From 0525681d7926f88777d185d2fae5260383fe12a0 Mon Sep 17 00:00:00 2001 From: Erik Amaru Ortiz Date: Thu, 2 Dec 2010 23:34:41 +0000 Subject: [PATCH] initial commit from rev. 632 --- LICENSE.txt | 661 + README.txt | 99 + gulliver/bin/gulliver | 64 + gulliver/bin/gulliver.php | 59 + gulliver/bin/tasks/pakeBase.php | 64 + gulliver/bin/tasks/pakeGulliver.php | 2519 ++ gulliver/bin/tasks/pakePropel.php | 492 + gulliver/bin/tasks/pakeTest.php | 123 + .../tasks/templates/authentication.php.tpl | 106 + gulliver/bin/tasks/templates/bm.jpg.tpl | Bin 0 -> 328 bytes gulliver/bin/tasks/templates/bsm.jpg.tpl | Bin 0 -> 292 bytes .../tasks/templates/class.pmFunctions.php.tpl | 26 + .../bin/tasks/templates/databases.php.tpl | 56 + gulliver/bin/tasks/templates/db.php.tpl | 16 + gulliver/bin/tasks/templates/dbInfo.php.tpl | 137 + gulliver/bin/tasks/templates/dbInfo.xml.tpl | 43 + gulliver/bin/tasks/templates/db_insert.sql | 152 + gulliver/bin/tasks/templates/defines.php.tpl | 42 + gulliver/bin/tasks/templates/green.html.tpl | 123 + gulliver/bin/tasks/templates/green.php.tpl | 35 + gulliver/bin/tasks/templates/httpd.conf.tpl | 30 + gulliver/bin/tasks/templates/index.html.tpl | 8 + gulliver/bin/tasks/templates/login.php.tpl | 66 + gulliver/bin/tasks/templates/login.xml.tpl | 20 + gulliver/bin/tasks/templates/mainmenu.php.tpl | 26 + gulliver/bin/tasks/templates/paths.php.tpl | 70 + .../tasks/templates/permissionsList.php.tpl | 27 + .../tasks/templates/permissionsList.xml.tpl | 26 + gulliver/bin/tasks/templates/pluginClass.tpl | 166 + gulliver/bin/tasks/templates/pluginDelete.tpl | 38 + .../bin/tasks/templates/pluginDeleteExec.tpl | 31 + .../tasks/templates/pluginDrawChart.php.tpl | 14 + gulliver/bin/tasks/templates/pluginEdit.tpl | 34 + gulliver/bin/tasks/templates/pluginList.tpl | 36 + .../bin/tasks/templates/pluginMainFile.tpl | 65 + gulliver/bin/tasks/templates/pluginMenu.tpl | 5 + .../tasks/templates/pluginMenuOnTransit.tpl | 5 + gulliver/bin/tasks/templates/pluginNew.tpl | 37 + .../templates/pluginOnTransitList.php.tpl | 35 + .../templates/pluginOnTransitList.xml.tpl | 85 + .../templates/pluginPaged-table.html.tpl | 75 + .../bin/tasks/templates/pluginPropel.ini.tpl | 46 + .../templates/pluginPropel.mysql.ini.tpl | 46 + .../bin/tasks/templates/pluginReport.xml.tpl | 26 + gulliver/bin/tasks/templates/pluginSave.tpl | 53 + .../bin/tasks/templates/pluginSchema.xml.tpl | 73 + gulliver/bin/tasks/templates/pluginStep.tpl | 8 + .../bin/tasks/templates/pluginWelcome.php.tpl | 57 + .../bin/tasks/templates/pluginXmlform.tpl | 23 + .../tasks/templates/pluginXmlformDelete.tpl | 23 + .../bin/tasks/templates/pluginXmlformEdit.tpl | 31 + .../bin/tasks/templates/pluginXmlformList.tpl | 23 + .../tasks/templates/pluginXmlformOptions.tpl | 8 + gulliver/bin/tasks/templates/propel.ini.tpl | 44 + .../tasks/templates/publish-treeview.php.tpl | 38 + gulliver/bin/tasks/templates/publish.php.tpl | 35 + .../bin/tasks/templates/rolesList.php.tpl | 27 + .../bin/tasks/templates/rolesList.xml.tpl | 30 + gulliver/bin/tasks/templates/schema.xml.tpl | 526 + .../bin/tasks/templates/showMessage.xml.tpl | 9 + .../bin/tasks/templates/skinPluginClass.tpl | 20 + .../tasks/templates/skinPluginMainClass.tpl | 72 + gulliver/bin/tasks/templates/style.css.tpl | 1116 + .../bin/tasks/templates/sysGeneric.php.tpl | 388 + gulliver/bin/tasks/templates/sysLogin.php.tpl | 17 + gulliver/bin/tasks/templates/sysLogin.xml.tpl | 22 + gulliver/bin/tasks/templates/unitTest.tpl | 58 + .../bin/tasks/templates/users.menu.php.tpl | 16 + .../bin/tasks/templates/usersList.php.tpl | 30 + .../bin/tasks/templates/usersList.xml.tpl | 30 + gulliver/bin/tasks/templates/welcome.php.tpl | 55 + gulliver/bin/tasks/templates/welcome.xml.tpl | 21 + gulliver/bin/tasks/templates/xmlform.html.tpl | 161 + gulliver/includes/inc.ajax.php | 111 + gulliver/js/common/core/common.js | 1887 ++ gulliver/js/common/core/effects.js | 244 + .../js/common/core/images/default_logo.gif | Bin 0 -> 1685 bytes gulliver/js/common/core/webResource.js | 238 + gulliver/js/common/tree/tree.js | 67 + gulliver/js/dveditor/core/dveditor.js | 129 + .../core/toolbars/complete3lines.html | 39 + .../dveditor/core/toolbars/complete3lines.png | Bin 0 -> 8141 bytes .../dveditor/core/toolbars/smallToolBar.html | 16 + .../dveditor/core/toolbars/smallToolBar.png | Bin 0 -> 4676 bytes .../dveditor/core/toolbars/toolbar2lines.html | 39 + .../dveditor/core/toolbars/toolbar2lines.png | Bin 0 -> 7896 bytes gulliver/js/ext/draw2d.js | 6367 ++++ gulliver/js/ext/ext-all.js | 11 + gulliver/js/ext/ext-base.js | 7 + gulliver/js/ext/moocanvas.js | 873 + gulliver/js/ext/mootools.js | 2409 ++ gulliver/js/ext/ux/ux-all.js | 14 + gulliver/js/ext/wz_jsgraphics.js | 937 + gulliver/js/form/core/form.js | 2097 ++ gulliver/js/form/core/pagedTable.js | 243 + gulliver/js/grid/core/grid.js | 902 + gulliver/js/highlight/core/AUTHORS.en.txt | 19 + gulliver/js/highlight/core/AUTHORS.ru.txt | 19 + gulliver/js/highlight/core/LICENSE | 24 + gulliver/js/highlight/core/export.html | 88 + gulliver/js/highlight/core/highlight.js | 429 + gulliver/js/highlight/core/languages/1c.js | 84 + .../js/highlight/core/languages/axapta.js | 52 + .../js/highlight/core/languages/dynamic.js | 319 + .../js/highlight/core/languages/javascript.js | 38 + gulliver/js/highlight/core/languages/rib.js | 30 + gulliver/js/highlight/core/languages/rsl.js | 46 + .../js/highlight/core/languages/smalltalk.js | 53 + gulliver/js/highlight/core/languages/sql.js | 50 + .../js/highlight/core/languages/static.js | 158 + .../js/highlight/core/languages/vbscript.js | 25 + gulliver/js/highlight/core/languages/www.js | 186 + gulliver/js/highlight/core/readme.eng.txt | 310 + gulliver/js/highlight/core/readme.rus.txt | 316 + gulliver/js/highlight/core/sample.css | 75 + gulliver/js/highlight/core/test.html | 620 + .../js/highlight/core/wp_highlight.js.php | 86 + gulliver/js/jquery/ajaxupload.3.6.js | 546 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_55_fbec88_40x100.png | Bin 0 -> 182 bytes .../images/ui-bg_glass_75_d0e5f5_1x400.png | Bin 0 -> 124 bytes .../images/ui-bg_glass_85_dfeffc_1x400.png | Bin 0 -> 123 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_gloss-wave_55_5c9ccc_500x100.png | Bin 0 -> 3457 bytes .../ui-bg_inset-hard_100_f5f8f9_1x100.png | Bin 0 -> 104 bytes .../ui-bg_inset-hard_100_fcfdfd_1x100.png | Bin 0 -> 88 bytes .../images/ui-icons_217bc0_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_469bdd_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_6da8d5_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_d8e7f3_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_f9bd01_256x240.png | Bin 0 -> 4369 bytes .../css/redmond/jquery-ui-1.7.2.custom.css | 406 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 144 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 151 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 5355 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../css/smoothness/jquery-ui-1.7.2.custom.css | 406 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 0 -> 125 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 0 -> 3762 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 0 -> 129 bytes .../images/ui-icons_222222_256x240.png | 2 + .../images/ui-icons_228ef1_256x240.png | 2 + .../images/ui-icons_ef8c08_256x240.png | 2 + .../images/ui-icons_ffd27a_256x240.png | 2 + .../images/ui-icons_ffffff_256x240.png | 2 + .../ui-lightness/jquery-ui-1.7.2.custom.css | 407 + gulliver/js/jquery/jquery-1.3.2.min.js | 19 + .../js/jquery/jquery-ui-1.7.2.custom.min.js | 298 + gulliver/js/jquery/jquery.layout-latest.js | 3712 +++ gulliver/js/json/core/json.js | 148 + .../core/data/maborak.module.rss.feeds.json | 1 + .../maborak/core/images/app.slide/Play_on.png | Bin 0 -> 50850 bytes .../js/maborak/core/images/app.slide/back.png | Bin 0 -> 45603 bytes .../core/images/app.slide/back_dark.png | Bin 0 -> 25888 bytes .../maborak/core/images/app.slide/back_on.png | Bin 0 -> 49634 bytes .../core/images/app.slide/back_on_dark.png | Bin 0 -> 27786 bytes .../images/app.slide/background_bottom.gif | Bin 0 -> 2394 bytes .../images/app.slide/background_bottom.png | Bin 0 -> 2393 bytes .../app.slide/background_bottom_dark.png | Bin 0 -> 29025 bytes .../maborak/core/images/app.slide/close.gif | Bin 0 -> 612 bytes .../js/maborak/core/images/app.slide/next.png | Bin 0 -> 2192 bytes .../core/images/app.slide/next_dark.png | Bin 0 -> 25623 bytes .../maborak/core/images/app.slide/next_on.png | Bin 0 -> 45934 bytes .../core/images/app.slide/next_on_dark.png | Bin 0 -> 27629 bytes .../maborak/core/images/app.slide/pause.png | Bin 0 -> 2301 bytes .../core/images/app.slide/pause_dark.png | Bin 0 -> 27202 bytes .../core/images/app.slide/pause_on.png | Bin 0 -> 2292 bytes .../core/images/app.slide/pause_on_dark.png | Bin 0 -> 26246 bytes .../core/images/app.slide/play_dark.png | Bin 0 -> 27941 bytes .../core/images/app.slide/play_on_dark.png | Bin 0 -> 28737 bytes gulliver/js/maborak/core/images/arrowB.gif | Bin 0 -> 13123 bytes gulliver/js/maborak/core/images/failed.png | Bin 0 -> 886 bytes gulliver/js/maborak/core/images/fbc.blue.png | Bin 0 -> 1242 bytes gulliver/js/maborak/core/images/fbc.png | Bin 0 -> 174 bytes gulliver/js/maborak/core/images/fbl.blue.png | Bin 0 -> 1343 bytes gulliver/js/maborak/core/images/fbl.png | Bin 0 -> 309 bytes gulliver/js/maborak/core/images/fbr.blue.png | Bin 0 -> 1358 bytes gulliver/js/maborak/core/images/fbr.png | Bin 0 -> 319 bytes gulliver/js/maborak/core/images/ftc.png | Bin 0 -> 621 bytes gulliver/js/maborak/core/images/ftl.blue.gif | Bin 0 -> 64 bytes gulliver/js/maborak/core/images/ftl.png | Bin 0 -> 219 bytes gulliver/js/maborak/core/images/ftlL.png | Bin 0 -> 289 bytes gulliver/js/maborak/core/images/ftr.blue.gif | Bin 0 -> 64 bytes gulliver/js/maborak/core/images/ftr.png | Bin 0 -> 216 bytes gulliver/js/maborak/core/images/ftrL.png | Bin 0 -> 1641 bytes gulliver/js/maborak/core/images/grid.png | Bin 0 -> 25591 bytes .../maborak/core/images/grid.title.gray.gif | Bin 0 -> 79 bytes .../maborak/core/images/grid.title.green.gif | Bin 0 -> 105 bytes .../core/images/grid.title.greenLight.gif | Bin 0 -> 158 bytes .../maborak/core/images/grid.title.orange.gif | Bin 0 -> 157 bytes .../maborak/core/images/grid.title.violet.gif | Bin 0 -> 158 bytes .../maborak/core/images/grid.titlebar.bg1.gif | Bin 0 -> 90 bytes .../maborak/core/images/grid.titlebar.bg1.png | Bin 0 -> 278 bytes gulliver/js/maborak/core/images/icons.gif | Bin 0 -> 11530 bytes gulliver/js/maborak/core/images/info.png | Bin 0 -> 1918 bytes .../js/maborak/core/images/input_back.gif | Bin 0 -> 44 bytes gulliver/js/maborak/core/images/loader_B.gif | Bin 0 -> 3236 bytes .../js/maborak/core/images/loader_B_blank.gif | Bin 0 -> 4178 bytes gulliver/js/maborak/core/images/maximizar.gif | Bin 0 -> 214 bytes .../js/maborak/core/images/maximizar1.gif | Bin 0 -> 200 bytes .../module.grid/page-first-disabled.gif | Bin 0 -> 925 bytes .../core/images/module.grid/page-first.gif | Bin 0 -> 925 bytes .../images/module.grid/page-last-disabled.gif | Bin 0 -> 923 bytes .../core/images/module.grid/page-last.gif | Bin 0 -> 923 bytes .../images/module.grid/page-next-disabled.gif | Bin 0 -> 875 bytes .../core/images/module.grid/page-next.gif | Bin 0 -> 875 bytes .../images/module.grid/page-prev-disabled.gif | Bin 0 -> 879 bytes .../core/images/module.grid/page-prev.gif | Bin 0 -> 879 bytes gulliver/js/maborak/core/images/nc.gif | Bin 0 -> 302 bytes gulliver/js/maborak/core/images/nr.gif | Bin 0 -> 297 bytes gulliver/js/maborak/core/images/nr.png | Bin 0 -> 474 bytes gulliver/js/maborak/core/images/ok.png | Bin 0 -> 866 bytes .../core/images/panel.bg.title.1x20.gif | Bin 0 -> 98 bytes .../core/images/panel.bg.title.1x23.gif | Bin 0 -> 100 bytes .../core/images/panel.bg.title.1x29.gif | Bin 0 -> 154 bytes .../js/maborak/core/images/panel.bg.title.gif | Bin 0 -> 147 bytes .../js/maborak/core/images/panel.bg.title.png | Bin 0 -> 21171 bytes .../core/images/panel.close.static.gif | Bin 0 -> 554 bytes .../core/images/panel.resize.11x11.png | Bin 0 -> 259 bytes .../core/images/panel.tabSelected.1x25.gif | Bin 0 -> 13123 bytes .../core/images/panel.tabSelected.1x3.gif | Bin 0 -> 49 bytes gulliver/js/maborak/core/images/question.png | Bin 0 -> 1435 bytes .../js/maborak/core/images/roll.static.gif | Bin 0 -> 200 bytes .../js/maborak/core/images/separator.down.gif | Bin 0 -> 82 bytes .../js/maborak/core/images/separator.up.gif | Bin 0 -> 81 bytes .../js/maborak/core/images/separatorTable.gif | Bin 0 -> 45 bytes .../images/silverBackgroundMenuSelected.jpg | Bin 0 -> 329 bytes .../core/images/silverBackgroundSubMenu.jpg | Bin 0 -> 13150 bytes .../images/silverBackgroundTableTitle.jpg | Bin 0 -> 296 bytes gulliver/js/maborak/core/images/star.gif | Bin 0 -> 1120 bytes gulliver/js/maborak/core/images/star_s.gif | Bin 0 -> 513 bytes gulliver/js/maborak/core/images/star_u.gif | Bin 0 -> 250 bytes .../js/maborak/core/images/tabs_li_bg.gif | Bin 0 -> 2349 bytes gulliver/js/maborak/core/images/warning.png | Bin 0 -> 2376 bytes gulliver/js/maborak/core/maborak.js | 2062 ++ gulliver/js/maborak/core/maborak.loader.js | 2 + gulliver/js/maborak/core/module.abbr.js | 10 + gulliver/js/maborak/core/module.app.js | 1828 + gulliver/js/maborak/core/module.boxi.js | 134 + gulliver/js/maborak/core/module.dashboard.js | 286 + gulliver/js/maborak/core/module.dom.js | 255 + gulliver/js/maborak/core/module.drag.js | 425 + gulliver/js/maborak/core/module.drop.js | 180 + gulliver/js/maborak/core/module.dynaform.js | 1143 + gulliver/js/maborak/core/module.fx.js | 306 + gulliver/js/maborak/core/module.grid.js | 1189 + gulliver/js/maborak/core/module.panel.js | 1784 + gulliver/js/maborak/core/module.rpc.js | 248 + gulliver/js/maborak/core/module.rss.js | 732 + gulliver/js/maborak/core/module.samples.js | 262 + gulliver/js/maborak/core/module.services.js | 234 + gulliver/js/maborak/core/module.slider.js | 205 + gulliver/js/maborak/core/module.validator.js | 163 + gulliver/js/maborak/core/module.xmlform.js | 224 + .../js/maborak/core/server/class.json.php | 806 + .../js/maborak/core/server/maborak.loader.php | 23 + .../core/server/maborak.module.rss.php | 94 + .../core/server/maborak.module.services.php | 26 + gulliver/js/maborak/core/server/proxy.js.php | 56 + .../core/server/services/service.comments.php | 33 + .../core/server/services/service.rate.php | 62 + .../js/maborak/core/stylesheet/default.css | 1618 + gulliver/js/maborak/core/stylesheet/tiny.css | 209 + gulliver/js/maborak/core/xml2array.js | 105 + gulliver/js/maborak/samples/1.html | 5 + gulliver/js/maborak/samples/2.html | 1 + gulliver/js/maborak/samples/ajax.tutorial.txt | 60 + gulliver/js/maborak/samples/bench.html | 54 + gulliver/js/maborak/samples/csshover.htc | 115 + .../js/maborak/samples/data.grid.backup.txt | 76 + gulliver/js/maborak/samples/doc.css.txt | 1 + gulliver/js/maborak/samples/dynaform.html | 191 + gulliver/js/maborak/samples/dynaform.tpl | 16 + gulliver/js/maborak/samples/empty.tpl | 1 + gulliver/js/maborak/samples/empty.xml | 3 + gulliver/js/maborak/samples/ex.app.php | 156 + gulliver/js/maborak/samples/ex.core.php | 128 + gulliver/js/maborak/samples/ex.grid.php | 80 + gulliver/js/maborak/samples/ex.panel.php | 171 + gulliver/js/maborak/samples/ex.rpc.php | 55 + gulliver/js/maborak/samples/fd1.php | 30 + gulliver/js/maborak/samples/fd2.php | 19 + gulliver/js/maborak/samples/file.swf | Bin 0 -> 65821 bytes gulliver/js/maborak/samples/g.xml | 1176 + .../js/maborak/samples/grid.files/paises.grid | 1 + .../js/maborak/samples/grid.files/sample.grid | 1 + gulliver/js/maborak/samples/grid.json | 39 + .../maborak/samples/grid.json.data.load.php | 25 + .../maborak/samples/grid.json.data.save.php | 9 + gulliver/js/maborak/samples/grid.txt | 1 + gulliver/js/maborak/samples/hard.tpl | 544 + gulliver/js/maborak/samples/hard.xml | 111 + gulliver/js/maborak/samples/index.php | 377 + gulliver/js/maborak/samples/leimnud.html | 47 + .../samples/leimnud.module.mail.sender.php | 93 + gulliver/js/maborak/samples/link.php | 6 + gulliver/js/maborak/samples/link2.php | 6 + gulliver/js/maborak/samples/links.html | 22 + gulliver/js/maborak/samples/maborak.html | 49 + .../js/maborak/samples/maborak.module.rss.php | 13 + gulliver/js/maborak/samples/menu.html | 131 + .../js/maborak/samples/module.rss.proxy.php | 8 + gulliver/js/maborak/samples/mootools.svn.js | 7102 ++++ gulliver/js/maborak/samples/myInfo.xml | 72 + gulliver/js/maborak/samples/nc.gif | Bin 0 -> 302 bytes gulliver/js/maborak/samples/nr.gif | Bin 0 -> 297 bytes gulliver/js/maborak/samples/nr.png | Bin 0 -> 474 bytes gulliver/js/maborak/samples/order.php | 35 + gulliver/js/maborak/samples/pagina1.html | 3 + gulliver/js/maborak/samples/pagina2.html | 6 + gulliver/js/maborak/samples/pm.xml | 5 + gulliver/js/maborak/samples/post.php | 6 + gulliver/js/maborak/samples/processmap.html | 35 + gulliver/js/maborak/samples/processmap2.html | 33 + gulliver/js/maborak/samples/report.html | 142 + gulliver/js/maborak/samples/rss.html | 41 + gulliver/js/maborak/samples/rss.xml | 95 + gulliver/js/maborak/samples/rss2.xml | 35 + gulliver/js/maborak/samples/s.html | 94 + gulliver/js/maborak/samples/sample.php | 3 + gulliver/js/maborak/samples/sampleGrids.php | 377 + gulliver/js/maborak/samples/services.html | 53 + gulliver/js/maborak/samples/sl.html | 265 + gulliver/js/maborak/samples/sl.php | 3 + gulliver/js/maborak/samples/slide.php | 130 + gulliver/js/maborak/samples/style.css | 1336 + gulliver/js/maborak/samples/style.panel.css | 444 + gulliver/js/maborak/samples/xmlform.html | 23 + gulliver/js/md5/core/md5.js | 248 + gulliver/js/thirdparty/krumo/krumo.js | 37 + gulliver/js/widgets/calendar/pmcalendar.js | 755 + .../widgets/js-calendar/css/border-radius.css | 82 + .../js-calendar/css/gold/brushed-steel.jpg | Bin 0 -> 17096 bytes .../widgets/js-calendar/css/gold/coolbg.png | Bin 0 -> 493 bytes .../js/widgets/js-calendar/css/gold/gold.css | 78 + .../js/widgets/js-calendar/css/gold/gold.jpg | Bin 0 -> 9521 bytes .../js-calendar/css/img/cool-bg-hard-inv.png | Bin 0 -> 257 bytes .../js-calendar/css/img/cool-bg-hard.png | Bin 0 -> 265 bytes .../js-calendar/css/img/cool-bg-inv.png | Bin 0 -> 222 bytes .../widgets/js-calendar/css/img/cool-bg.png | Bin 0 -> 232 bytes .../widgets/js-calendar/css/img/drop-down.gif | Bin 0 -> 68 bytes .../widgets/js-calendar/css/img/drop-up.gif | Bin 0 -> 68 bytes .../js-calendar/css/img/nav-left-x2.gif | Bin 0 -> 76 bytes .../widgets/js-calendar/css/img/nav-left.gif | Bin 0 -> 66 bytes .../js-calendar/css/img/nav-right-x2.gif | Bin 0 -> 75 bytes .../widgets/js-calendar/css/img/nav-right.gif | Bin 0 -> 64 bytes .../widgets/js-calendar/css/img/time-down.png | Bin 0 -> 226 bytes .../widgets/js-calendar/css/img/time-up.png | Bin 0 -> 226 bytes .../js/widgets/js-calendar/css/jscal2.css | 350 + .../widgets/js-calendar/css/matrix/matrix.css | 116 + .../js-calendar/css/matrix/nav-left-x2.gif | Bin 0 -> 97 bytes .../js-calendar/css/matrix/nav-left.gif | Bin 0 -> 87 bytes .../js-calendar/css/matrix/nav-right-x2.gif | Bin 0 -> 96 bytes .../js-calendar/css/matrix/nav-right.gif | Bin 0 -> 85 bytes .../js-calendar/css/reduce-spacing.css | 31 + .../js/widgets/js-calendar/css/shadow-b.png | Bin 0 -> 208 bytes .../js-calendar/css/steel/brushed-steel.jpg | Bin 0 -> 3431 bytes .../js-calendar/css/steel/brushed-steel.png | Bin 0 -> 20213 bytes .../widgets/js-calendar/css/steel/coolbg.png | Bin 0 -> 493 bytes .../widgets/js-calendar/css/steel/steel.css | 61 + .../widgets/js-calendar/css/steel/steel.jpg | Bin 0 -> 9924 bytes .../widgets/js-calendar/css/win2k/win2k.css | 66 + .../js/widgets/js-calendar/js-calendar.js | 11 + gulliver/js/widgets/js-calendar/lang/ca.js | 61 + gulliver/js/widgets/js-calendar/lang/cn.js | 61 + gulliver/js/widgets/js-calendar/lang/cz.js | 61 + gulliver/js/widgets/js-calendar/lang/de.js | 61 + gulliver/js/widgets/js-calendar/lang/en.js | 61 + gulliver/js/widgets/js-calendar/lang/es.js | 61 + gulliver/js/widgets/js-calendar/lang/fr.js | 61 + gulliver/js/widgets/js-calendar/lang/it.js | 61 + gulliver/js/widgets/js-calendar/lang/jp.js | 61 + gulliver/js/widgets/js-calendar/lang/nl.js | 61 + gulliver/js/widgets/js-calendar/lang/pl.js | 64 + gulliver/js/widgets/js-calendar/lang/pt.js | 61 + gulliver/js/widgets/js-calendar/lang/ro.js | 61 + gulliver/js/widgets/js-calendar/lang/ru.js | 61 + gulliver/js/widgets/js-calendar/lang/sv.js | 61 + gulliver/js/widgets/jscalendar/calendar.js | 2012 ++ .../js/widgets/jscalendar/lang/calendar-af.js | 39 + .../js/widgets/jscalendar/lang/calendar-al.js | 101 + .../js/widgets/jscalendar/lang/calendar-bg.js | 124 + .../jscalendar/lang/calendar-big5-utf8.js | 123 + .../widgets/jscalendar/lang/calendar-big5.js | 123 + .../js/widgets/jscalendar/lang/calendar-br.js | 108 + .../js/widgets/jscalendar/lang/calendar-ca.js | 123 + .../jscalendar/lang/calendar-cs-utf8.js | 65 + .../jscalendar/lang/calendar-cs-win.js | 65 + .../js/widgets/jscalendar/lang/calendar-da.js | 123 + .../js/widgets/jscalendar/lang/calendar-de.js | 124 + .../js/widgets/jscalendar/lang/calendar-du.js | 45 + .../js/widgets/jscalendar/lang/calendar-el.js | 89 + .../js/widgets/jscalendar/lang/calendar-en.js | 129 + .../js/widgets/jscalendar/lang/calendar-es.js | 131 + .../js/widgets/jscalendar/lang/calendar-fi.js | 98 + .../js/widgets/jscalendar/lang/calendar-fr.js | 125 + .../jscalendar/lang/calendar-he-utf8.js | 123 + .../jscalendar/lang/calendar-hr-utf8.js | 49 + .../js/widgets/jscalendar/lang/calendar-hr.js | Bin 0 -> 3088 bytes .../js/widgets/jscalendar/lang/calendar-hu.js | 124 + .../js/widgets/jscalendar/lang/calendar-it.js | 124 + .../js/widgets/jscalendar/lang/calendar-jp.js | 45 + .../jscalendar/lang/calendar-ko-utf8.js | 120 + .../js/widgets/jscalendar/lang/calendar-ko.js | 120 + .../jscalendar/lang/calendar-lt-utf8.js | 114 + .../js/widgets/jscalendar/lang/calendar-lt.js | 114 + .../js/widgets/jscalendar/lang/calendar-lv.js | 123 + .../js/widgets/jscalendar/lang/calendar-nl.js | 73 + .../js/widgets/jscalendar/lang/calendar-no.js | 114 + .../jscalendar/lang/calendar-pl-utf8.js | 93 + .../js/widgets/jscalendar/lang/calendar-pl.js | 56 + .../js/widgets/jscalendar/lang/calendar-pt.js | 123 + .../js/widgets/jscalendar/lang/calendar-ro.js | 66 + .../js/widgets/jscalendar/lang/calendar-ru.js | 123 + .../jscalendar/lang/calendar-ru_win_.js | 123 + .../js/widgets/jscalendar/lang/calendar-si.js | 94 + .../js/widgets/jscalendar/lang/calendar-sk.js | 99 + .../js/widgets/jscalendar/lang/calendar-sp.js | 110 + .../js/widgets/jscalendar/lang/calendar-sv.js | 93 + .../js/widgets/jscalendar/lang/calendar-tr.js | 58 + .../js/widgets/jscalendar/lang/calendar-zh.js | 119 + .../js/widgets/jscalendar/lang/cn_utf8.js | 123 + .../widgets/suggest/bsn.AutoSuggest_2.1.3.js | 774 + .../suggest/bsn.AutoSuggest_2.1.3_comp.js | 1 + gulliver/js/widgets/suggest/css/._.DS_Store | Bin 0 -> 70 bytes .../suggest/css/autosuggest_inquisitor.css | 177 + .../suggest/css/img_inquisitor/._.DS_Store | Bin 0 -> 70 bytes .../css/img_inquisitor/._as_pointer.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._hl_corner_bl.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._hl_corner_br.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._hl_corner_tl.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._hl_corner_tr.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._ul_corner_bl.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._ul_corner_br.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._ul_corner_tl.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/._ul_corner_tr.gif | Bin 0 -> 70 bytes .../css/img_inquisitor/_source/._.DS_Store | Bin 0 -> 70 bytes .../img_inquisitor/_source/._as_pointer.png | Bin 0 -> 109504 bytes .../img_inquisitor/_source/._li_corner.png | Bin 0 -> 110294 bytes .../img_inquisitor/_source/._ul_corner.png | Bin 0 -> 109622 bytes .../css/img_inquisitor/_source/as_pointer.png | Bin 0 -> 27142 bytes .../css/img_inquisitor/_source/li_corner.png | Bin 0 -> 28442 bytes .../css/img_inquisitor/_source/ul_corner.png | Bin 0 -> 27649 bytes .../suggest/css/img_inquisitor/as_pointer.gif | Bin 0 -> 66 bytes .../css/img_inquisitor/hl_corner_bl.gif | Bin 0 -> 73 bytes .../css/img_inquisitor/hl_corner_br.gif | Bin 0 -> 73 bytes .../css/img_inquisitor/hl_corner_tl.gif | Bin 0 -> 73 bytes .../css/img_inquisitor/hl_corner_tr.gif | Bin 0 -> 73 bytes .../css/img_inquisitor/ul_corner_bl.gif | Bin 0 -> 49 bytes .../css/img_inquisitor/ul_corner_br.gif | Bin 0 -> 49 bytes .../css/img_inquisitor/ul_corner_tl.gif | Bin 0 -> 50 bytes .../css/img_inquisitor/ul_corner_tr.gif | Bin 0 -> 50 bytes .../widgets/suggest/server/widget.suggest.php | 284 + gulliver/js/widgets/tooltip/pmtooltip.js | 89 + gulliver/methods/controls/Calendar-32x32.png | Bin 0 -> 2103 bytes gulliver/methods/controls/TrashIcon.jpg | Bin 0 -> 15143 bytes gulliver/methods/controls/cal.gif | Bin 0 -> 127 bytes gulliver/methods/controls/calendar.php | 173 + gulliver/methods/controls/next.gif | Bin 0 -> 214 bytes gulliver/methods/controls/next_year.gif | Bin 0 -> 256 bytes gulliver/methods/controls/pixel.gif | Bin 0 -> 67 bytes gulliver/methods/controls/prev.gif | Bin 0 -> 212 bytes gulliver/methods/controls/prev_year.gif | Bin 0 -> 259 bytes gulliver/methods/decorator.php | 23 + gulliver/methods/defaultAjax.php | 204 + gulliver/methods/defaultAjaxDynaform.php | 27 + gulliver/methods/errors/error.php | 33 + gulliver/methods/errors/error400.php | 33 + gulliver/methods/errors/error401.php | 39 + gulliver/methods/errors/error403.php | 35 + gulliver/methods/errors/error404.php | 61 + gulliver/methods/errors/error503.php | 35 + gulliver/methods/errors/error701.php | 32 + gulliver/methods/errors/error702.php | 33 + gulliver/methods/errors/error703.php | 33 + gulliver/methods/errors/error704.php | 33 + gulliver/methods/errors/header.php | 30 + gulliver/methods/errors/style.css | 78 + gulliver/methods/genericAjax.php | 147 + gulliver/methods/pagedTableAjax.php | 104 + gulliver/methods/propelTableAjax.php | 136 + gulliver/methods/streamFile.php | 36 + gulliver/system/VERSION | 1 + gulliver/system/class.database_base.php | 154 + gulliver/system/class.database_mssql.php | 710 + gulliver/system/class.database_mysql.php | 707 + gulliver/system/class.dbMaintenance.php | 678 + gulliver/system/class.dbconnection.php | 278 + gulliver/system/class.dbrecordset.php | 151 + gulliver/system/class.dbsession.php | 181 + gulliver/system/class.dbtable.php | 415 + gulliver/system/class.dvEditor.php | 76 + gulliver/system/class.dynaformhandler.php | 579 + gulliver/system/class.error.php | 102 + gulliver/system/class.fckEditor.php | 47 + gulliver/system/class.filterForm.php | 46 + gulliver/system/class.form.php | 520 + gulliver/system/class.functionTest.php | 55 + gulliver/system/class.g.php | 3114 ++ gulliver/system/class.headPublisher.php | 540 + gulliver/system/class.helper.php | 98 + gulliver/system/class.htmlArea.php | 61 + gulliver/system/class.i18n_po.php | 386 + gulliver/system/class.mailer.php | 270 + gulliver/system/class.menu.php | 378 + gulliver/system/class.objectTemplate.php | 63 + gulliver/system/class.pagedTable.php | 986 + gulliver/system/class.publisher.php | 664 + gulliver/system/class.rbac.php | 940 + gulliver/system/class.table.php | 1343 + gulliver/system/class.templatePower.php | 764 + gulliver/system/class.testTools.php | 181 + gulliver/system/class.tree.php | 148 + gulliver/system/class.unitTest.php | 65 + gulliver/system/class.webResource.php | 125 + gulliver/system/class.xmlDocument.php | 363 + gulliver/system/class.xmlMenu.php | 94 + gulliver/system/class.xmlform.php | 4250 +++ gulliver/system/class.xmlformExtension.php | 147 + gulliver/system/class.ymlDomain.php | 294 + gulliver/system/class.ymlTestCases.php | 270 + gulliver/templates/menu.html | 19 + gulliver/templates/submenu.html | 19 + gulliver/templates/xmlform.html | 97 + gulliver/thirdparty/codepress/codepress.css | 21 + gulliver/thirdparty/codepress/codepress.html | 35 + gulliver/thirdparty/codepress/codepress.js | 153 + .../thirdparty/codepress/engines/gecko.js | 293 + .../thirdparty/codepress/engines/khtml.js | 0 gulliver/thirdparty/codepress/engines/msie.js | 304 + .../thirdparty/codepress/engines/older.js | 0 .../thirdparty/codepress/engines/opera.js | 260 + .../codepress/images/line-numbers.png | Bin 0 -> 16556 bytes gulliver/thirdparty/codepress/index.html | 443 + .../thirdparty/codepress/languages/asp.css | 71 + .../thirdparty/codepress/languages/asp.js | 117 + .../thirdparty/codepress/languages/autoit.css | 13 + .../thirdparty/codepress/languages/autoit.js | 32 + .../thirdparty/codepress/languages/csharp.css | 9 + .../thirdparty/codepress/languages/csharp.js | 25 + .../thirdparty/codepress/languages/css.css | 10 + .../thirdparty/codepress/languages/css.js | 23 + .../codepress/languages/generic.css | 9 + .../thirdparty/codepress/languages/generic.js | 25 + .../thirdparty/codepress/languages/html.css | 13 + .../thirdparty/codepress/languages/html.js | 59 + .../thirdparty/codepress/languages/java.css | 7 + .../thirdparty/codepress/languages/java.js | 24 + .../codepress/languages/javascript.css | 8 + .../codepress/languages/javascript.js | 30 + .../thirdparty/codepress/languages/perl.css | 11 + .../thirdparty/codepress/languages/perl.js | 27 + .../thirdparty/codepress/languages/php.css | 12 + .../thirdparty/codepress/languages/php.js | 61 + .../thirdparty/codepress/languages/ruby.css | 10 + .../thirdparty/codepress/languages/ruby.js | 26 + .../thirdparty/codepress/languages/sql.css | 10 + .../thirdparty/codepress/languages/sql.js | 30 + .../thirdparty/codepress/languages/text.css | 5 + .../thirdparty/codepress/languages/text.js | 9 + .../codepress/languages/vbscript.css | 71 + .../codepress/languages/vbscript.js | 117 + .../codepress/languages/xmlform.css | 13 + .../thirdparty/codepress/languages/xmlform.js | 65 + .../thirdparty/codepress/languages/xsl.css | 15 + .../thirdparty/codepress/languages/xsl.js | 103 + gulliver/thirdparty/codepress/license.txt | 458 + .../thirdparty/creole/CallableStatement.php | 135 + gulliver/thirdparty/creole/Connection.php | 220 + gulliver/thirdparty/creole/Creole.php | 376 + gulliver/thirdparty/creole/CreoleTypes.php | 187 + gulliver/thirdparty/creole/IdGenerator.php | 57 + .../thirdparty/creole/PreparedStatement.php | 253 + gulliver/thirdparty/creole/ResultSet.php | 380 + .../thirdparty/creole/ResultSetIterator.php | 113 + gulliver/thirdparty/creole/SQLException.php | 105 + gulliver/thirdparty/creole/Statement.php | 147 + .../creole/common/ConnectionCommon.php | 258 + .../creole/common/PreparedStatementCommon.php | 641 + .../creole/common/ResultSetCommon.php | 462 + .../creole/common/StatementCommon.php | 289 + .../creole/contrib/DBArrayConnection.php | 551 + .../creole/contrib/DebugConnection.php | 269 + .../drivers/mssql/MSSQLCallableStatement.php | 478 + .../creole/drivers/mssql/MSSQLConnection.php | 283 + .../creole/drivers/mssql/MSSQLIdGenerator.php | 62 + .../drivers/mssql/MSSQLPreparedStatement.php | 99 + .../creole/drivers/mssql/MSSQLResultSet.php | 170 + .../creole/drivers/mssql/MSSQLStatement.php | 72 + .../creole/drivers/mssql/MSSQLTypes.php | 94 + .../mssql/metadata/MSSQLDatabaseInfo.php | 69 + .../drivers/mssql/metadata/MSSQLTableInfo.php | 183 + .../creole/drivers/mysql/MySQLConnection.php | 290 + .../creole/drivers/mysql/MySQLIdGenerator.php | 75 + .../drivers/mysql/MySQLPreparedStatement.php | 44 + .../creole/drivers/mysql/MySQLResultSet.php | 165 + .../creole/drivers/mysql/MySQLStatement.php | 36 + .../creole/drivers/mysql/MySQLTypes.php | 102 + .../mysql/metadata/MySQLDatabaseInfo.php | 66 + .../drivers/mysql/metadata/MySQLTableInfo.php | 252 + .../drivers/mysqli/MySQLiConnection.php | 293 + .../drivers/mysqli/MySQLiIdGenerator.php | 96 + .../mysqli/MySQLiPreparedStatement.php | 42 + .../creole/drivers/mysqli/MySQLiResultSet.php | 173 + .../creole/drivers/mysqli/MySQLiStatement.php | 33 + .../mysqli/metadata/MySQLiDatabaseInfo.php | 61 + .../mysqli/metadata/MySQLiTableInfo.php | 155 + .../drivers/odbc/ODBCCachedResultSet.php | 218 + .../creole/drivers/odbc/ODBCConnection.php | 362 + .../creole/drivers/odbc/ODBCIdGenerator.php | 118 + .../drivers/odbc/ODBCPreparedStatement.php | 246 + .../creole/drivers/odbc/ODBCResultSet.php | 209 + .../drivers/odbc/ODBCResultSetCommon.php | 188 + .../creole/drivers/odbc/ODBCStatement.php | 64 + .../creole/drivers/odbc/ODBCTypes.php | 189 + .../thirdparty/creole/drivers/odbc/README | 90 + .../drivers/odbc/adapters/CodeBaseAdapter.php | 73 + .../drivers/odbc/adapters/MySQLAdapter.php | 78 + .../drivers/odbc/adapters/ODBCAdapter.php | 115 + .../odbc/metadata/ODBCDatabaseInfo.php | 66 + .../drivers/odbc/metadata/ODBCTableInfo.php | 141 + .../creole/drivers/oracle/OCI8Connection.php | 398 + .../creole/drivers/oracle/OCI8IdGenerator.php | 65 + .../drivers/oracle/OCI8PreparedStatement.php | 424 + .../creole/drivers/oracle/OCI8ResultSet.php | 131 + .../creole/drivers/oracle/OCI8Statement.php | 34 + .../creole/drivers/oracle/OCI8Types.php | 90 + .../oracle/metadata/OCI8DatabaseInfo.php | 90 + .../drivers/oracle/metadata/OCI8TableInfo.php | 273 + .../creole/drivers/pgsql/PgSQLConnection.php | 260 + .../creole/drivers/pgsql/PgSQLIdGenerator.php | 84 + .../drivers/pgsql/PgSQLPreparedStatement.php | 157 + .../creole/drivers/pgsql/PgSQLResultSet.php | 205 + .../drivers/pgsql/PgSQLResultSetIterator.php | 109 + .../creole/drivers/pgsql/PgSQLStatement.php | 34 + .../creole/drivers/pgsql/PgSQLTypes.php | 101 + .../pgsql/metadata/PgSQLDatabaseInfo.php | 115 + .../drivers/pgsql/metadata/PgSQLTableInfo.php | 423 + .../drivers/sqlite/SQLiteConnection.php | 245 + .../drivers/sqlite/SQLiteIdGenerator.php | 60 + .../sqlite/SQLitePreparedStatement.php | 61 + .../creole/drivers/sqlite/SQLiteResultSet.php | 120 + .../sqlite/SQLiteResultSetIterator.php | 88 + .../creole/drivers/sqlite/SQLiteStatement.php | 34 + .../creole/drivers/sqlite/SQLiteTypes.php | 108 + .../sqlite/metadata/SQLiteDatabaseInfo.php | 64 + .../sqlite/metadata/SQLiteTableInfo.php | 137 + .../thirdparty/creole/metadata/ColumnInfo.php | 232 + .../creole/metadata/DatabaseInfo.php | 207 + .../creole/metadata/ForeignKeyInfo.php | 103 + .../thirdparty/creole/metadata/IndexInfo.php | 84 + .../creole/metadata/PrimaryKeyInfo.php | 91 + .../thirdparty/creole/metadata/TableInfo.php | 305 + gulliver/thirdparty/creole/util/Blob.php | 62 + gulliver/thirdparty/creole/util/Clob.php | 112 + gulliver/thirdparty/creole/util/Lob.php | 243 + .../creole/util/sql/SQLStatementExtractor.php | 164 + gulliver/thirdparty/geshi/contrib/aliased.php | 124 + gulliver/thirdparty/geshi/contrib/cssgen.php | 456 + gulliver/thirdparty/geshi/contrib/cssgen2.php | 59 + gulliver/thirdparty/geshi/contrib/example.php | 217 + .../thirdparty/geshi/contrib/langcheck.php | 766 + gulliver/thirdparty/geshi/geshi.php | 4656 +++ gulliver/thirdparty/geshi/geshi/bash.php | 327 + .../thirdparty/geshi/geshi/javascript.php | 150 + gulliver/thirdparty/geshi/geshi/jquery.php | 238 + gulliver/thirdparty/geshi/geshi/php.php | 1114 + gulliver/thirdparty/geshi/geshi/xml.php | 157 + gulliver/thirdparty/html2ps_pdf/.htaccess | 1 + .../thirdparty/html2ps_pdf/autofix.url.php | 77 + .../html2ps_pdf/background.image.php | 234 + .../html2ps_pdf/background.position.php | 88 + .../html2ps_pdf/box.block.inline.php | 159 + gulliver/thirdparty/html2ps_pdf/box.block.php | 465 + gulliver/thirdparty/html2ps_pdf/box.body.php | 38 + gulliver/thirdparty/html2ps_pdf/box.br.php | 201 + .../thirdparty/html2ps_pdf/box.button.php | 149 + .../html2ps_pdf/box.button.reset.php | 36 + .../html2ps_pdf/box.button.submit.php | 91 + .../html2ps_pdf/box.checkbutton.php | 230 + .../thirdparty/html2ps_pdf/box.container.php | 1103 + .../html2ps_pdf/box.field.pageno.php | 81 + .../html2ps_pdf/box.field.pages.php | 89 + gulliver/thirdparty/html2ps_pdf/box.form.php | 40 + gulliver/thirdparty/html2ps_pdf/box.frame.php | 304 + .../html2ps_pdf/box.generic.formatted.php | 1039 + .../html2ps_pdf/box.generic.inline.php | 112 + .../thirdparty/html2ps_pdf/box.generic.php | 454 + .../thirdparty/html2ps_pdf/box.iframe.php | 76 + gulliver/thirdparty/html2ps_pdf/box.img.php | 347 + .../html2ps_pdf/box.inline.control.php | 69 + .../thirdparty/html2ps_pdf/box.inline.php | 498 + .../html2ps_pdf/box.inline.simple.php | 48 + .../thirdparty/html2ps_pdf/box.input.img.php | 128 + .../html2ps_pdf/box.input.password.php | 66 + .../thirdparty/html2ps_pdf/box.input.text.php | 103 + .../html2ps_pdf/box.input.textarea.php | 74 + .../thirdparty/html2ps_pdf/box.legend.php | 57 + .../thirdparty/html2ps_pdf/box.list-item.php | 224 + .../html2ps_pdf/box.note-call.class.php | 199 + gulliver/thirdparty/html2ps_pdf/box.null.php | 36 + .../html2ps_pdf/box.page.margin.class.php | 476 + gulliver/thirdparty/html2ps_pdf/box.page.php | 49 + gulliver/thirdparty/html2ps_pdf/box.php | 569 + .../html2ps_pdf/box.radiobutton.php | 139 + .../thirdparty/html2ps_pdf/box.select.php | 128 + .../html2ps_pdf/box.table.cell.fake.php | 73 + .../thirdparty/html2ps_pdf/box.table.cell.php | 322 + gulliver/thirdparty/html2ps_pdf/box.table.php | 1341 + .../thirdparty/html2ps_pdf/box.table.row.php | 220 + .../html2ps_pdf/box.table.section.php | 55 + gulliver/thirdparty/html2ps_pdf/box.text.php | 653 + .../html2ps_pdf/box.text.string.php | 60 + .../html2ps_pdf/box.utils.text-align.inc.php | 103 + .../thirdparty/html2ps_pdf/box.whitespace.php | 121 + .../html2ps_pdf/classes/include.php | 39 + .../classes/org/active-link/doc/DocHTML.php | 242 + .../classes/org/active-link/doc/Method.php | 83 + .../classes/org/active-link/doc/PHPClass.php | 196 + .../org/active-link/net/HTTPClient.php | 173 + .../org/active-link/net/HTTPServer.php | 50 + .../classes/org/active-link/net/Socket.php | 162 + .../classes/org/active-link/sys/File.php | 153 + .../classes/org/active-link/xml/Branch.php | 42 + .../classes/org/active-link/xml/Leaf.php | 70 + .../classes/org/active-link/xml/RSS.php | 108 + .../classes/org/active-link/xml/Tag.php | 422 + .../classes/org/active-link/xml/Tree.php | 94 + .../classes/org/active-link/xml/XML.php | 580 + .../classes/org/active-link/xml/XMLBranch.php | 71 + .../org/active-link/xml/XMLDocument.php | 174 + .../classes/org/active-link/xml/XMLLeaf.php | 73 + .../org/active-link/xml/XMLRPCClient.php | 120 + .../classes/org/active-link/xml/XPath.php | 46 + .../thirdparty/html2ps_pdf/config.inc.php | 156 + .../thirdparty/html2ps_pdf/config.parse.php | 170 + .../html2ps_pdf/content_type.class.php | 27 + .../html2ps_pdf/converter.class.php | 58 + .../css.background.attachment.inc.php | 35 + .../html2ps_pdf/css.background.color.inc.php | 62 + .../html2ps_pdf/css.background.image.inc.php | 41 + .../html2ps_pdf/css.background.inc.php | 64 + .../css.background.position.inc.php | 108 + .../html2ps_pdf/css.background.repeat.inc.php | 43 + .../css.border.bottom.color.inc.php | 35 + .../html2ps_pdf/css.border.bottom.inc.php | 23 + .../css.border.bottom.style.inc.php | 34 + .../css.border.bottom.width.inc.php | 40 + .../html2ps_pdf/css.border.collapse.inc.php | 31 + .../html2ps_pdf/css.border.color.inc.php | 92 + .../thirdparty/html2ps_pdf/css.border.inc.php | 151 + .../html2ps_pdf/css.border.left.color.inc.php | 34 + .../html2ps_pdf/css.border.left.inc.php | 23 + .../html2ps_pdf/css.border.left.style.inc.php | 34 + .../html2ps_pdf/css.border.left.width.inc.php | 40 + .../css.border.right.color.inc.php | 34 + .../html2ps_pdf/css.border.right.inc.php | 23 + .../css.border.right.style.inc.php | 34 + .../css.border.right.width.inc.php | 40 + .../html2ps_pdf/css.border.style.inc.php | 115 + .../html2ps_pdf/css.border.top.color.inc.php | 34 + .../html2ps_pdf/css.border.top.inc.php | 23 + .../html2ps_pdf/css.border.top.style.inc.php | 34 + .../html2ps_pdf/css.border.top.width.inc.php | 40 + .../html2ps_pdf/css.border.width.inc.php | 104 + .../thirdparty/html2ps_pdf/css.bottom.inc.php | 56 + .../html2ps_pdf/css.cache.class.php | 47 + .../thirdparty/html2ps_pdf/css.clear.inc.php | 35 + .../thirdparty/html2ps_pdf/css.color.inc.php | 32 + .../thirdparty/html2ps_pdf/css.colors.inc.php | 234 + .../html2ps_pdf/css.constants.inc.php | 184 + .../html2ps_pdf/css.content.inc.php | 96 + .../html2ps_pdf/css.counter.collection.php | 24 + .../thirdparty/html2ps_pdf/css.counter.php | 33 + .../html2ps_pdf/css.direction.inc.php | 30 + .../html2ps_pdf/css.display.inc.php | 46 + .../thirdparty/html2ps_pdf/css.float.inc.php | 32 + .../html2ps_pdf/css.font-family.inc.php | 50 + .../html2ps_pdf/css.font-size.inc.php | 63 + .../html2ps_pdf/css.font-style.inc.php | 32 + .../html2ps_pdf/css.font-weight.inc.php | 40 + .../thirdparty/html2ps_pdf/css.font.inc.php | 186 + .../thirdparty/html2ps_pdf/css.frame.inc.php | 5 + .../thirdparty/html2ps_pdf/css.height.inc.php | 46 + .../css.html2ps.html.content.inc.php | 41 + .../css.html2ps.pseudoelements.inc.php | 32 + gulliver/thirdparty/html2ps_pdf/css.inc.php | 151 + .../thirdparty/html2ps_pdf/css.left.inc.php | 35 + .../html2ps_pdf/css.letter-spacing.inc.php | 42 + .../html2ps_pdf/css.line-height.inc.php | 65 + .../html2ps_pdf/css.list-style-image.inc.php | 45 + .../css.list-style-position.inc.php | 32 + .../html2ps_pdf/css.list-style-type.inc.php | 87 + .../html2ps_pdf/css.list-style.inc.php | 43 + .../thirdparty/html2ps_pdf/css.margin.inc.php | 130 + .../html2ps_pdf/css.max-height.inc.php | 57 + .../html2ps_pdf/css.min-height.inc.php | 54 + .../html2ps_pdf/css.min-width.inc.php | 26 + .../html2ps_pdf/css.orphans.inc.php | 27 + .../html2ps_pdf/css.overflow.inc.php | 33 + .../html2ps_pdf/css.padding.inc.php | 132 + .../html2ps_pdf/css.page-break-after.inc.php | 16 + .../html2ps_pdf/css.page-break-before.inc.php | 16 + .../html2ps_pdf/css.page-break-inside.inc.php | 16 + .../html2ps_pdf/css.page-break.inc.php | 25 + .../thirdparty/html2ps_pdf/css.page.inc.php | 28 + .../thirdparty/html2ps_pdf/css.parse.inc.php | 236 + .../html2ps_pdf/css.parse.media.inc.php | 16 + .../html2ps_pdf/css.parse.properties.php | 87 + .../html2ps_pdf/css.position.inc.php | 40 + .../html2ps_pdf/css.property.collection.php | 119 + .../html2ps_pdf/css.property.declaration.php | 67 + .../css.property.handler.class.php | 101 + .../css.property.stringset.class.php | 34 + .../html2ps_pdf/css.property.sub.class.php | 80 + .../css.property.sub.field.class.php | 23 + .../html2ps_pdf/css.pseudo.add.margin.inc.php | 2 + .../html2ps_pdf/css.pseudo.align.inc.php | 70 + .../css.pseudo.cellpadding.inc.php | 28 + .../css.pseudo.cellspacing.inc.php | 28 + .../css.pseudo.form.action.inc.php | 23 + .../css.pseudo.form.radiogroup.inc.php | 27 + .../css.pseudo.link.destination.inc.php | 27 + .../css.pseudo.link.target.inc.php | 39 + .../css.pseudo.listcounter.inc.php | 20 + .../html2ps_pdf/css.pseudo.localalign.inc.php | 26 + .../html2ps_pdf/css.pseudo.nowrap.inc.php | 22 + .../css.pseudo.table.border.inc.php | 57 + .../thirdparty/html2ps_pdf/css.right.inc.php | 35 + .../thirdparty/html2ps_pdf/css.rules.inc.php | 79 + .../html2ps_pdf/css.rules.page.inc.php | 394 + .../html2ps_pdf/css.ruleset.class.php | 327 + .../html2ps_pdf/css.selectors.inc.php | 224 + .../html2ps_pdf/css.state.class.php | 184 + .../html2ps_pdf/css.table-layout.inc.php | 30 + .../html2ps_pdf/css.text-align.inc.php | 49 + .../html2ps_pdf/css.text-decoration.inc.php | 52 + .../html2ps_pdf/css.text-indent.inc.php | 38 + .../html2ps_pdf/css.text-transform.inc.php | 35 + .../thirdparty/html2ps_pdf/css.top.inc.php | 35 + .../thirdparty/html2ps_pdf/css.utils.inc.php | 139 + .../html2ps_pdf/css.vertical-align.inc.php | 171 + .../html2ps_pdf/css.visibility.inc.php | 31 + .../html2ps_pdf/css.white-space.inc.php | 36 + .../thirdparty/html2ps_pdf/css.widows.inc.php | 25 + .../thirdparty/html2ps_pdf/css.width.inc.php | 80 + .../html2ps_pdf/css.word-spacing.inc.php | 42 + .../html2ps_pdf/css.z-index.inc.php | 29 + gulliver/thirdparty/html2ps_pdf/default.css | 528 + .../thirdparty/html2ps_pdf/demo/.htaccess | 1 + .../html2ps_pdf/demo/generic.param.php | 46 + .../thirdparty/html2ps_pdf/demo/html2ps.php | 230 + .../thirdparty/html2ps_pdf/demo/htmltopdf.php | 230 + .../thirdparty/html2ps_pdf/demo/index.php | 500 + .../thirdparty/html2ps_pdf/demo/phpinfo.php | 5 + .../html2ps_pdf/demo/systemcheck.footer.tpl | 5 + .../html2ps_pdf/demo/systemcheck.header.tpl | 69 + .../html2ps_pdf/demo/systemcheck.php | 679 + gulliver/thirdparty/html2ps_pdf/demo/test.php | 97 + .../html2ps_pdf/destination._http.class.php | 24 + .../destination._interface.class.php | 19 + .../html2ps_pdf/destination.browser.class.php | 11 + .../destination.download.class.php | 16 + .../html2ps_pdf/destination.file.class.php | 10 + .../html2ps_pdf/dispatcher.class.php | 37 + .../html2ps_pdf/doc.anchor.class.php | 59 + .../html2ps_pdf/dom.activelink.inc.php | 126 + .../thirdparty/html2ps_pdf/dom.php5.inc.php | 94 + .../html2ps_pdf/encoding.cp1251.inc.php | 261 + .../html2ps_pdf/encoding.cp866.inc.php | 262 + .../html2ps_pdf/encoding.dingbats.inc.php | 210 + .../html2ps_pdf/encoding.entities.inc.php | 289 + .../html2ps_pdf/encoding.glyphs.inc.php | 4060 +++ .../thirdparty/html2ps_pdf/encoding.inc.php | 69 + .../html2ps_pdf/encoding.iso-8859-1.inc.php | 261 + .../html2ps_pdf/encoding.iso-8859-10.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-11.inc.php | 254 + .../html2ps_pdf/encoding.iso-8859-13.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-14.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-15.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-2.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-3.inc.php | 255 + .../html2ps_pdf/encoding.iso-8859-4.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-5.inc.php | 262 + .../html2ps_pdf/encoding.iso-8859-6.inc.php | 152 + .../html2ps_pdf/encoding.iso-8859-7.inc.php | 259 + .../html2ps_pdf/encoding.iso-8859-8.inc.php | 160 + .../html2ps_pdf/encoding.iso-8859-9.inc.php | 262 + .../html2ps_pdf/encoding.koi8-r.inc.php | 262 + .../html2ps_pdf/encoding.symbol.inc.php | 200 + .../html2ps_pdf/encoding.windows-1250.inc.php | 262 + .../html2ps_pdf/encoding.windows-1251.inc.php | 261 + .../html2ps_pdf/encoding.windows-1252.inc.php | 257 + gulliver/thirdparty/html2ps_pdf/error.php | 9 + gulliver/thirdparty/html2ps_pdf/favicon.ico | 1 + .../html2ps_pdf/fetched_data._html.class.php | 15 + .../fetched_data._interface.class.php | 15 + .../html2ps_pdf/fetched_data.file.class.php | 35 + .../html2ps_pdf/fetched_data.url.class.php | 59 + .../html2ps_pdf/fetcher._interface.class.php | 27 + .../html2ps_pdf/fetcher.local.class.php | 22 + .../html2ps_pdf/fetcher.memory.class.php | 34 + .../html2ps_pdf/fetcher.url.class.php | 460 + .../html2ps_pdf/fetcher.url.curl.class.php | 106 + .../filter.data._interface.class.php | 7 + .../html2ps_pdf/filter.data.doctype.class.php | 55 + .../filter.data.encoding.class.php | 35 + .../filter.data.html2xhtml.class.php | 14 + .../html2ps_pdf/filter.data.ucs2.class.php | 11 + .../html2ps_pdf/filter.data.utf8.class.php | 12 + .../filter.data.xhtml2xhtml.class.php | 8 + .../filter.output._interface.class.php | 11 + .../html2ps_pdf/filter.output.gzip.class.php | 20 + .../filter.output.ps2pdf.class.php | 51 + .../filter.post._interface.class.php | 7 + .../filter.post.positioned.class.php | 29 + .../filter.post.postponed.class.php | 29 + .../filter.pre._interface.class.php | 7 + .../html2ps_pdf/filter.pre.fields.class.php | 63 + .../filter.pre.footnotes.class.php | 38 + .../html2ps_pdf/filter.pre.headfoot.class.php | 33 + .../filter.pre.height-constraint.class.php | 49 + .../html2ps_pdf/flow_context.class.inc.php | 361 + .../html2ps_pdf/flow_viewport.class.inc.php | 33 + .../thirdparty/html2ps_pdf/font.class.php | 219 + .../html2ps_pdf/font.constants.inc.php | 11 + .../html2ps_pdf/font.resolver.class.php | 152 + .../html2ps_pdf/font_factory.class.php | 62 + .../thirdparty/html2ps_pdf/fonts/arial.afm | 2640 ++ .../thirdparty/html2ps_pdf/fonts/arial.ttf | Bin 0 -> 367112 bytes .../thirdparty/html2ps_pdf/fonts/arialbd.afm | 2640 ++ .../thirdparty/html2ps_pdf/fonts/arialbd.ttf | Bin 0 -> 352224 bytes .../thirdparty/html2ps_pdf/fonts/arialbi.afm | 1834 ++ .../thirdparty/html2ps_pdf/fonts/arialbi.ttf | Bin 0 -> 226748 bytes .../thirdparty/html2ps_pdf/fonts/ariali.afm | 1871 ++ .../thirdparty/html2ps_pdf/fonts/ariali.ttf | Bin 0 -> 207808 bytes .../thirdparty/html2ps_pdf/fonts/cour.afm | 1372 + .../thirdparty/html2ps_pdf/fonts/cour.ttf | Bin 0 -> 303296 bytes .../thirdparty/html2ps_pdf/fonts/courbd.afm | 1372 + .../thirdparty/html2ps_pdf/fonts/courbd.ttf | Bin 0 -> 312920 bytes .../thirdparty/html2ps_pdf/fonts/courbi.afm | 994 + .../thirdparty/html2ps_pdf/fonts/courbi.ttf | Bin 0 -> 236148 bytes .../thirdparty/html2ps_pdf/fonts/couri.afm | 997 + .../thirdparty/html2ps_pdf/fonts/couri.ttf | Bin 0 -> 245032 bytes .../thirdparty/html2ps_pdf/fonts/georgia.ttf | Bin 0 -> 155068 bytes .../thirdparty/html2ps_pdf/fonts/georgiab.ttf | Bin 0 -> 141032 bytes .../thirdparty/html2ps_pdf/fonts/georgiai.ttf | Bin 0 -> 157388 bytes .../thirdparty/html2ps_pdf/fonts/georgiaz.ttf | Bin 0 -> 159736 bytes .../html2ps_pdf/fonts/print_glyphs.ps | 129 + .../thirdparty/html2ps_pdf/fonts/symbol.afm | 278 + .../thirdparty/html2ps_pdf/fonts/symbol.ttf | Bin 0 -> 69464 bytes .../thirdparty/html2ps_pdf/fonts/times.afm | 2599 ++ .../thirdparty/html2ps_pdf/fonts/times.ttf | Bin 0 -> 409280 bytes .../thirdparty/html2ps_pdf/fonts/timesbd.afm | 2597 ++ .../thirdparty/html2ps_pdf/fonts/timesbd.ttf | Bin 0 -> 398372 bytes .../thirdparty/html2ps_pdf/fonts/timesbi.afm | 1843 ++ .../thirdparty/html2ps_pdf/fonts/timesbi.ttf | Bin 0 -> 239692 bytes .../thirdparty/html2ps_pdf/fonts/timesi.afm | 1819 + .../thirdparty/html2ps_pdf/fonts/timesi.ttf | Bin 0 -> 248368 bytes .../thirdparty/html2ps_pdf/fonts/verdana.ttf | Bin 0 -> 171792 bytes .../thirdparty/html2ps_pdf/fonts/verdanab.ttf | Bin 0 -> 137616 bytes .../thirdparty/html2ps_pdf/fonts/verdanai.ttf | Bin 0 -> 155076 bytes .../thirdparty/html2ps_pdf/fonts/verdanaz.ttf | Bin 0 -> 154800 bytes .../html2ps_pdf/fpdf/font/makefont/cp1250.map | 251 + .../html2ps_pdf/fpdf/font/makefont/cp1251.map | 255 + .../html2ps_pdf/fpdf/font/makefont/cp1252.map | 251 + .../html2ps_pdf/fpdf/font/makefont/cp1253.map | 239 + .../html2ps_pdf/fpdf/font/makefont/cp1254.map | 249 + .../html2ps_pdf/fpdf/font/makefont/cp1255.map | 233 + .../html2ps_pdf/fpdf/font/makefont/cp1257.map | 244 + .../html2ps_pdf/fpdf/font/makefont/cp1258.map | 247 + .../html2ps_pdf/fpdf/font/makefont/cp874.map | 225 + .../fpdf/font/makefont/iso-8859-1.map | 256 + .../fpdf/font/makefont/iso-8859-11.map | 248 + .../fpdf/font/makefont/iso-8859-15.map | 256 + .../fpdf/font/makefont/iso-8859-16.map | 256 + .../fpdf/font/makefont/iso-8859-2.map | 256 + .../fpdf/font/makefont/iso-8859-4.map | 256 + .../fpdf/font/makefont/iso-8859-5.map | 256 + .../fpdf/font/makefont/iso-8859-7.map | 250 + .../fpdf/font/makefont/iso-8859-9.map | 256 + .../html2ps_pdf/fpdf/font/makefont/koi8-r.map | 256 + .../html2ps_pdf/fpdf/font/makefont/koi8-u.map | 256 + .../fpdf/font/makefont/makefont.php | 416 + .../html2ps_pdf/fpdf/font/makefont/symbol.map | 189 + gulliver/thirdparty/html2ps_pdf/fpdf/fpdf.php | 3212 ++ .../thirdparty/html2ps_pdf/globals.inc.php | 5 + gulliver/thirdparty/html2ps_pdf/globals.php | 7 + gulliver/thirdparty/html2ps_pdf/height.php | 230 + .../help/UML/Custom_fetcher_session.png | Bin 0 -> 6704 bytes .../html2ps_pdf/help/UML/Data_filters.PNG | Bin 0 -> 4242 bytes .../html2ps_pdf/help/UML/Destinations.PNG | Bin 0 -> 5669 bytes .../html2ps_pdf/help/UML/Fetchers.PNG | Bin 0 -> 4082 bytes .../html2ps_pdf/help/UML/Layout_engines.PNG | Bin 0 -> 2005 bytes .../help/UML/Multiple_fetcher_session.PNG | Bin 0 -> 10663 bytes .../html2ps_pdf/help/UML/Output_drivers.PNG | Bin 0 -> 4728 bytes .../html2ps_pdf/help/UML/Output_filters.PNG | Bin 0 -> 3512 bytes .../html2ps_pdf/help/UML/Parsers.PNG | Bin 0 -> 1671 bytes .../html2ps_pdf/help/UML/Post_filters.PNG | Bin 0 -> 1008 bytes .../html2ps_pdf/help/UML/Pre_filters.PNG | Bin 0 -> 3578 bytes .../UML/Simple_custom_fetcher_session.png | Bin 0 -> 8277 bytes .../help/UML/Simple_fetcher_session.PNG | Bin 0 -> 6995 bytes gulliver/thirdparty/html2ps_pdf/help/api.html | 409 + .../html2ps_pdf/help/api_events.html | 95 + .../html2ps_pdf/help/api_fetchers.html | 70 + .../html2ps_pdf/help/api_samples.html | 139 + .../thirdparty/html2ps_pdf/help/calling.html | 281 + .../help/compatibility.css.2.1.html | 654 + .../html2ps_pdf/help/compatibility.css.3.html | 86 + .../html2ps_pdf/help/configuration.html | 255 + .../thirdparty/html2ps_pdf/help/css/help.css | 127 + .../html2ps_pdf/help/directives.html | 68 + gulliver/thirdparty/html2ps_pdf/help/faq.html | 397 + .../thirdparty/html2ps_pdf/help/forms.html | 215 + .../html2ps_pdf/help/howto_afm.html | 19 + .../html2ps_pdf/help/howto_fonts.html | 141 + .../thirdparty/html2ps_pdf/help/index.html | 33 + .../thirdparty/html2ps_pdf/help/install.html | 31 + .../thirdparty/html2ps_pdf/help/misc.html | 1 + .../html2ps_pdf/help/requirements.html | 90 + .../html2ps_pdf/help/samples/headfoot.html | 5 + .../thirdparty/html2ps_pdf/html.attrs.inc.php | 819 + .../thirdparty/html2ps_pdf/html2ps.config | 187 + .../html2ps_pdf/html2ps.config.recommended | 187 + .../thirdparty/html2ps_pdf/image.class.php | 135 + gulliver/thirdparty/html2ps_pdf/index.php | 10 + .../inline.content.builder.factory.php | 34 + .../inline.content.builder.normal.php | 52 + .../inline.content.builder.nowrap.php | 22 + .../html2ps_pdf/inline.content.builder.php | 43 + .../inline.content.builder.pre.line.php | 35 + .../inline.content.builder.pre.php | 30 + .../inline.content.builder.pre.wrap.php | 39 + .../html2ps_pdf/layout._interface.class.php | 7 + .../html2ps_pdf/layout.default.class.php | 93 + .../html2ps_pdf/layout.page.breaks.php | 574 + .../html2ps_pdf/layout.vertical.php | 43 + .../html2ps_pdf/list-style.image.php | 22 + .../html2ps_pdf/manager.encoding.php | 247 + .../html2ps_pdf/media.layout.inc.php | 107 + .../thirdparty/html2ps_pdf/observer.class.php | 9 + gulliver/thirdparty/html2ps_pdf/ot.class.php | 892 + .../thirdparty/html2ps_pdf/out/readme.txt | 1 + .../html2ps_pdf/output._generic.class.php | 326 + .../html2ps_pdf/output._generic.pdf.class.php | 26 + .../html2ps_pdf/output._generic.ps.class.php | 37 + .../html2ps_pdf/output._interface.class.php | 73 + .../html2ps_pdf/output.fastps.class.php | 404 + .../html2ps_pdf/output.fastps.l2.class.php | 109 + .../html2ps_pdf/output.fpdf.class.php | 425 + .../html2ps_pdf/output.pcl.class.php | 291 + .../html2ps_pdf/output.pdflib.1.6.class.php | 225 + .../html2ps_pdf/output.pdflib.class.php | 437 + .../html2ps_pdf/output.pdflib.old.class.php | 40 + .../html2ps_pdf/output.png.class.php | 530 + .../html2ps_pdf/parser._interface.class.php | 7 + .../html2ps_pdf/parser.xhtml.class.php | 85 + gulliver/thirdparty/html2ps_pdf/path.php | 176 + .../thirdparty/html2ps_pdf/path.point.php | 17 + .../thirdparty/html2ps_pdf/path.rectangle.php | 35 + .../html2ps_pdf/pdf.fpdf.makefont.php | 512 + gulliver/thirdparty/html2ps_pdf/pdf.fpdf.php | 2688 ++ .../thirdparty/html2ps_pdf/pipeline.class.php | 1130 + .../html2ps_pdf/pipeline.factory.class.php | 32 + .../html2ps_pdf/postscript/array.ps | 284 + .../postscript/background.image.ps | 152 + .../html2ps_pdf/postscript/background.ps | 58 + .../html2ps_pdf/postscript/border.ps | 291 + .../postscript/box.block.inline.ps | 57 + .../html2ps_pdf/postscript/box.block.ps | 255 + .../html2ps_pdf/postscript/box.break.ps | 93 + .../html2ps_pdf/postscript/box.button.ps | 143 + .../html2ps_pdf/postscript/box.checkbutton.ps | 117 + .../html2ps_pdf/postscript/box.container.ps | 1023 + .../html2ps_pdf/postscript/box.frame.ps | 236 + .../postscript/box.generic.inline.ps | 86 + .../html2ps_pdf/postscript/box.generic.ps | 1273 + .../html2ps_pdf/postscript/box.iframe.ps | 4 + .../html2ps_pdf/postscript/box.image.ps | 199 + .../html2ps_pdf/postscript/box.inline.ps | 357 + .../postscript/box.inline.whitespace.ps | 76 + .../html2ps_pdf/postscript/box.input.check.ps | 63 + .../html2ps_pdf/postscript/box.input.radio.ps | 50 + .../html2ps_pdf/postscript/box.input.text.ps | 76 + .../html2ps_pdf/postscript/box.list-item.ps | 246 + .../thirdparty/html2ps_pdf/postscript/box.ps | 2 + .../html2ps_pdf/postscript/box.radiobutton.ps | 97 + .../html2ps_pdf/postscript/box.select.ps | 101 + .../html2ps_pdf/postscript/box.span.ps | 2 + .../postscript/box.table.cell.fake.ps | 15 + .../html2ps_pdf/postscript/box.table.cell.ps | 166 + .../html2ps_pdf/postscript/box.table.ps | 1272 + .../html2ps_pdf/postscript/box.table.row.ps | 165 + .../html2ps_pdf/postscript/box.text.ps | 379 + .../html2ps_pdf/postscript/box.whitespace.ps | 74 + .../html2ps_pdf/postscript/cellspan.ps | 21 + .../html2ps_pdf/postscript/class.ps | 35 + .../html2ps_pdf/postscript/color.ps | 29 + .../postscript/containing_block.ps | 4 + .../html2ps_pdf/postscript/context.ps | 472 + .../postscript/encoding.dingbats.ps | 104 + .../postscript/encoding.iso-8859-10.ps | 259 + .../postscript/encoding.iso-8859-11.ps | 259 + .../postscript/encoding.iso-8859-13.ps | 259 + .../postscript/encoding.iso-8859-14.ps | 259 + .../postscript/encoding.iso-8859-15.ps | 259 + .../postscript/encoding.iso-8859-2.ps | 2 + .../postscript/encoding.iso-8859-3.ps | 259 + .../postscript/encoding.iso-8859-4.ps | 259 + .../postscript/encoding.iso-8859-5.ps | 259 + .../postscript/encoding.iso-8859-7.ps | 259 + .../postscript/encoding.iso-8859-9.ps | 259 + .../html2ps_pdf/postscript/encoding.koi8-r.ps | 259 + .../html2ps_pdf/postscript/encoding.symbol.ps | 122 + .../postscript/encoding.windows-1250.ps | 259 + .../postscript/encoding.windows-1251.ps | 258 + .../postscript/encoding.windows-1252.ps | 259 + .../html2ps_pdf/postscript/fastps.footer.ps | 3 + .../html2ps_pdf/postscript/fastps.header.ps | 381 + .../html2ps_pdf/postscript/flow.block.ps | 96 + .../html2ps_pdf/postscript/flow.box.ps | 53 + .../html2ps_pdf/postscript/flow.float.ps | 36 + .../postscript/flow.inline.block.ps | 57 + .../html2ps_pdf/postscript/flow.inline.ps | 116 + .../html2ps_pdf/postscript/flow.legend.ps | 49 + .../html2ps_pdf/postscript/flow.table.ps | 163 + .../html2ps_pdf/postscript/flow_viewport.ps | 35 + .../thirdparty/html2ps_pdf/postscript/font.ps | 71 + .../html2ps_pdf/postscript/footer.ps | 154 + .../html2ps_pdf/postscript/geometry.ps | 27 + .../html2ps_pdf/postscript/header.ps | 665 + .../html2ps_pdf/postscript/height.ps | 231 + .../html2ps_pdf/postscript/image.ps | 338 + .../thirdparty/html2ps_pdf/postscript/init.ps | 11 + .../html2ps_pdf/postscript/position.ps | 4 + .../html2ps_pdf/postscript/predicates.ps | 28 + .../html2ps_pdf/postscript/table.ps | 1256 + .../html2ps_pdf/postscript/table.row.ps | 20 + .../html2ps_pdf/postscript/text-align.ps | 95 + .../html2ps_pdf/postscript/vertical-align.ps | 93 + .../html2ps_pdf/postscript/viewport.ps | 171 + .../html2ps_pdf/postscript/width.ps | 61 + .../html2ps_pdf/ps.image.encoder.inc.php | 2 + .../ps.image.encoder.simple.inc.php | 216 + .../ps.image.encoder.stream.inc.php | 51 + .../ps.l2.image.encoder.stream.inc.php | 43 + .../ps.l3.image.encoder.stream.inc.php | 250 + .../thirdparty/html2ps_pdf/ps.unicode.inc.php | 47 + .../thirdparty/html2ps_pdf/ps.utils.inc.php | 12 + .../html2ps_pdf/ps.whitespace.inc.php | 4 + .../html2ps_pdf/render.queue.class.php | 19 + .../render.stacking.context.class.php | 28 + .../render.stacking.level.class.php | 19 + .../html2ps_pdf/samples/out/readme.txt | 1 + .../html2ps_pdf/samples/sample.batch.php | 160 + .../samples/sample.form.handler.php | 8 + .../samples/sample.pipeline.custom.php | 38 + .../samples/sample.pipeline.default.php | 35 + .../samples/sample.simplest.from.file.php | 94 + .../samples/sample.simplest.from.memory.php | 112 + .../html2ps_pdf/samples/sample.simplest.php | 95 + .../strategy.link.rendering.normal.php | 30 + .../strategy.position.absolute.php | 84 + .../strategy.table.layout.auto.php | 252 + .../strategy.table.layout.fixed.php | 18 + .../strategy.width.absolute.positioned.php | 166 + .../strategy.width.max.natural.php | 87 + .../html2ps_pdf/strategy.width.max.php | 79 + .../html2ps_pdf/strategy.width.min.nowrap.php | 52 + .../html2ps_pdf/strategy.width.min.php | 79 + .../thirdparty/html2ps_pdf/stubs._.inc.php | 7 + .../html2ps_pdf/stubs.common.inc.php | 24 + .../stubs.file_get_contents.inc.php | 12 + .../stubs.file_put_contents.inc.php | 9 + .../html2ps_pdf/stubs.is_executable.inc.php | 7 + .../stubs.memory_get_usage.inc.php | 28 + .../thirdparty/html2ps_pdf/tag.body.inc.php | 3 + .../thirdparty/html2ps_pdf/tag.font.inc.php | 3 + .../thirdparty/html2ps_pdf/tag.frame.inc.php | 111 + .../thirdparty/html2ps_pdf/tag.img.inc.php | 4 + .../thirdparty/html2ps_pdf/tag.input.inc.php | 6 + .../thirdparty/html2ps_pdf/tag.select.inc.php | 4 + .../thirdparty/html2ps_pdf/tag.span.inc.php | 3 + .../thirdparty/html2ps_pdf/tag.table.inc.php | 4 + .../thirdparty/html2ps_pdf/tag.td.inc.php | 4 + .../thirdparty/html2ps_pdf/tag.utils.inc.php | 3 + .../thirdparty/html2ps_pdf/temp/readme.txt | 1 + .../html2ps_pdf/templates/cannot_parse.html | 56 + .../templates/error._connection.tpl | 16 + .../html2ps_pdf/templates/error._footer.tpl | 2 + .../html2ps_pdf/templates/error._header.tpl | 40 + .../html2ps_pdf/templates/error._http.tpl | 7 + .../templates/error._missing_afm.tpl | 47 + .../templates/error._no_fetchers.tpl | 6 + .../templates/error._redirects.tpl | 3 + .../html2ps_pdf/templates/error_exec.tpl | 70 + .../html2ps_pdf/templates/missing_exec.html | 64 + .../html2ps_pdf/templates/missing_gs.html | 94 + .../html2ps_pdf/templates/missing_pdflib.html | 85 + .../templates/missing_url_fopen.html | 58 + .../html2ps_pdf/tree.navigation.inc.php | 49 + .../html2ps_pdf/treebuilder.class.php | 48 + .../thirdparty/html2ps_pdf/utils_array.php | 74 + .../thirdparty/html2ps_pdf/utils_graphic.php | 51 + .../thirdparty/html2ps_pdf/utils_number.php | 19 + .../thirdparty/html2ps_pdf/utils_text.php | 8 + .../thirdparty/html2ps_pdf/utils_units.php | 82 + gulliver/thirdparty/html2ps_pdf/utils_url.php | 71 + .../html2ps_pdf/value.background.php | 162 + .../html2ps_pdf/value.border.class.php | 174 + .../html2ps_pdf/value.border.color.class.php | 24 + .../html2ps_pdf/value.border.edge.class.php | 314 + .../html2ps_pdf/value.border.style.class.php | 24 + .../html2ps_pdf/value.border.width.class.php | 24 + .../thirdparty/html2ps_pdf/value.bottom.php | 16 + .../thirdparty/html2ps_pdf/value.color.php | 50 + .../html2ps_pdf/value.content.item.php | 256 + .../thirdparty/html2ps_pdf/value.content.php | 63 + .../html2ps_pdf/value.font.class.php | 65 + .../html2ps_pdf/value.generic.length.php | 117 + .../html2ps_pdf/value.generic.percentage.php | 86 + .../thirdparty/html2ps_pdf/value.generic.php | 17 + .../thirdparty/html2ps_pdf/value.height.php | 16 + .../thirdparty/html2ps_pdf/value.left.php | 16 + .../html2ps_pdf/value.line-height.class.php | 53 + .../html2ps_pdf/value.list-style.class.php | 51 + .../html2ps_pdf/value.margin.class.php | 127 + .../html2ps_pdf/value.max-height.php | 16 + .../html2ps_pdf/value.min-height.php | 16 + .../html2ps_pdf/value.padding.class.php | 130 + .../thirdparty/html2ps_pdf/value.right.php | 16 + .../html2ps_pdf/value.text-indent.class.php | 39 + gulliver/thirdparty/html2ps_pdf/value.top.php | 16 + .../html2ps_pdf/width.constraint.php | 51 + gulliver/thirdparty/html2ps_pdf/width.php | 118 + .../html2ps_pdf/xhtml.autoclose.inc.php | 74 + .../html2ps_pdf/xhtml.comments.inc.php | 9 + .../html2ps_pdf/xhtml.deflist.inc.php | 25 + .../html2ps_pdf/xhtml.entities.inc.php | 79 + .../html2ps_pdf/xhtml.lists.inc.php | 30 + .../thirdparty/html2ps_pdf/xhtml.p.inc.php | 38 + .../html2ps_pdf/xhtml.script.inc.php | 8 + .../html2ps_pdf/xhtml.selects.inc.php | 22 + .../html2ps_pdf/xhtml.style.inc.php | 42 + .../html2ps_pdf/xhtml.tables.inc.php | 108 + .../html2ps_pdf/xhtml.utils.inc.php | 483 + .../html2ps_pdf/xml.validation.inc.php | 11 + gulliver/thirdparty/htmlarea/editor.js | 1124 + gulliver/thirdparty/htmlarea/example.html | 160 + gulliver/thirdparty/htmlarea/images/Thumbs.db | Bin 0 -> 28160 bytes .../thirdparty/htmlarea/images/ed_about.gif | Bin 0 -> 87 bytes .../htmlarea/images/ed_align_center.gif | Bin 0 -> 69 bytes .../htmlarea/images/ed_align_left.gif | Bin 0 -> 69 bytes .../htmlarea/images/ed_align_right.gif | Bin 0 -> 68 bytes .../thirdparty/htmlarea/images/ed_blank.gif | Bin 0 -> 56 bytes .../thirdparty/htmlarea/images/ed_charmap.gif | Bin 0 -> 143 bytes .../htmlarea/images/ed_color_bg.gif | Bin 0 -> 181 bytes .../htmlarea/images/ed_color_fg.gif | Bin 0 -> 171 bytes .../thirdparty/htmlarea/images/ed_copy.gif | Bin 0 -> 110 bytes .../thirdparty/htmlarea/images/ed_custom.gif | Bin 0 -> 67 bytes .../thirdparty/htmlarea/images/ed_cut.gif | Bin 0 -> 91 bytes .../thirdparty/htmlarea/images/ed_delete.gif | Bin 0 -> 90 bytes .../htmlarea/images/ed_format_bold.gif | Bin 0 -> 74 bytes .../htmlarea/images/ed_format_italic.gif | Bin 0 -> 77 bytes .../htmlarea/images/ed_format_strike.gif | Bin 0 -> 78 bytes .../htmlarea/images/ed_format_sub.gif | Bin 0 -> 78 bytes .../htmlarea/images/ed_format_sup.gif | Bin 0 -> 77 bytes .../htmlarea/images/ed_format_underline.gif | Bin 0 -> 85 bytes .../thirdparty/htmlarea/images/ed_help.gif | Bin 0 -> 70 bytes gulliver/thirdparty/htmlarea/images/ed_hr.gif | Bin 0 -> 70 bytes .../thirdparty/htmlarea/images/ed_html.gif | Bin 0 -> 75 bytes .../thirdparty/htmlarea/images/ed_image.gif | Bin 0 -> 148 bytes .../htmlarea/images/ed_indent_less.gif | Bin 0 -> 87 bytes .../htmlarea/images/ed_indent_more.gif | Bin 0 -> 87 bytes .../thirdparty/htmlarea/images/ed_link.gif | Bin 0 -> 97 bytes .../htmlarea/images/ed_list_bullet.gif | Bin 0 -> 80 bytes .../htmlarea/images/ed_list_num.gif | Bin 0 -> 82 bytes .../thirdparty/htmlarea/images/ed_redo.gif | Bin 0 -> 80 bytes .../thirdparty/htmlarea/images/ed_undo.gif | Bin 0 -> 81 bytes .../htmlarea/images/fullscreen_maximize.gif | Bin 0 -> 97 bytes .../htmlarea/images/fullscreen_minimize.gif | Bin 0 -> 97 bytes .../htmlarea/images/insert_table.gif | Bin 0 -> 121 bytes gulliver/thirdparty/htmlarea/license.txt | 13 + .../thirdparty/htmlarea/popups/about.html | 15 + .../thirdparty/htmlarea/popups/blank.html | 2 + .../thirdparty/htmlarea/popups/custom2.html | 35 + .../htmlarea/popups/editor_help.html | 16 + .../htmlarea/popups/fullscreen.html | 131 + .../htmlarea/popups/insert_image.html | 206 + .../htmlarea/popups/insert_table.html | 170 + .../htmlarea/popups/select_color.html | 343 + gulliver/thirdparty/htmlarea/readme.html | 760 + gulliver/thirdparty/jsmin/jsmin.php | 292 + gulliver/thirdparty/krumo/INSTALL | 32 + gulliver/thirdparty/krumo/LICENSE | 504 + gulliver/thirdparty/krumo/README | 103 + gulliver/thirdparty/krumo/TODO | 24 + gulliver/thirdparty/krumo/VERSION | 1 + gulliver/thirdparty/krumo/class.krumo.php | 1302 + .../krumo/docs/Krumo/_class.krumo.php.html | 267 + .../krumo/docs/Krumo/_class_krumo_php.html | 269 + .../thirdparty/krumo/docs/Krumo/krumo.html | 900 + gulliver/thirdparty/krumo/docs/blank.html | 13 + .../krumo/docs/classtrees_Krumo.html | 23 + .../thirdparty/krumo/docs/elementindex.html | 392 + .../krumo/docs/elementindex_Krumo.html | 389 + gulliver/thirdparty/krumo/docs/errors.html | 15 + gulliver/thirdparty/krumo/docs/index.html | 24 + gulliver/thirdparty/krumo/docs/li_Krumo.html | 155 + .../thirdparty/krumo/docs/media/banner.css | 32 + .../krumo/docs/media/images/AbstractClass.png | Bin 0 -> 620 bytes .../docs/media/images/AbstractClass_logo.png | Bin 0 -> 1232 bytes .../docs/media/images/AbstractMethod.png | Bin 0 -> 696 bytes .../media/images/AbstractPrivateClass.png | Bin 0 -> 848 bytes .../images/AbstractPrivateClass_logo.png | Bin 0 -> 1615 bytes .../media/images/AbstractPrivateMethod.png | Bin 0 -> 874 bytes .../krumo/docs/media/images/Class.png | Bin 0 -> 570 bytes .../krumo/docs/media/images/Class_logo.png | Bin 0 -> 1600 bytes .../krumo/docs/media/images/Constant.png | Bin 0 -> 752 bytes .../krumo/docs/media/images/Constructor.png | Bin 0 -> 865 bytes .../krumo/docs/media/images/Destructor.png | Bin 0 -> 956 bytes .../krumo/docs/media/images/Function.png | Bin 0 -> 596 bytes .../krumo/docs/media/images/Global.png | Bin 0 -> 712 bytes .../thirdparty/krumo/docs/media/images/I.png | Bin 0 -> 148 bytes .../krumo/docs/media/images/Index.png | Bin 0 -> 584 bytes .../krumo/docs/media/images/Interface.PNG | Bin 0 -> 1083 bytes .../docs/media/images/Interface_logo.png | Bin 0 -> 1600 bytes .../thirdparty/krumo/docs/media/images/L.png | Bin 0 -> 153 bytes .../krumo/docs/media/images/Lminus.png | Bin 0 -> 219 bytes .../krumo/docs/media/images/Lplus.png | Bin 0 -> 224 bytes .../krumo/docs/media/images/Method.png | Bin 0 -> 661 bytes .../krumo/docs/media/images/Page.png | Bin 0 -> 592 bytes .../krumo/docs/media/images/Page_logo.png | Bin 0 -> 1369 bytes .../krumo/docs/media/images/PrivateClass.png | Bin 0 -> 790 bytes .../docs/media/images/PrivateClass_logo.png | Bin 0 -> 1836 bytes .../krumo/docs/media/images/PrivateMethod.png | Bin 0 -> 918 bytes .../docs/media/images/PrivateVariable.png | Bin 0 -> 772 bytes .../krumo/docs/media/images/StaticMethod.png | Bin 0 -> 661 bytes .../docs/media/images/StaticVariable.png | Bin 0 -> 688 bytes .../thirdparty/krumo/docs/media/images/T.png | Bin 0 -> 152 bytes .../krumo/docs/media/images/Tminus.png | Bin 0 -> 207 bytes .../krumo/docs/media/images/Tplus.png | Bin 0 -> 222 bytes .../krumo/docs/media/images/Variable.png | Bin 0 -> 688 bytes .../krumo/docs/media/images/blank.png | Bin 0 -> 144 bytes .../krumo/docs/media/images/class_folder.png | Bin 0 -> 633 bytes .../krumo/docs/media/images/empty.png | Bin 0 -> 90 bytes .../krumo/docs/media/images/file.png | Bin 0 -> 462 bytes .../krumo/docs/media/images/folder.png | Bin 0 -> 492 bytes .../docs/media/images/function_folder.png | Bin 0 -> 605 bytes .../krumo/docs/media/images/minus.gif | Bin 0 -> 54 bytes .../krumo/docs/media/images/next_button.png | Bin 0 -> 657 bytes .../media/images/next_button_disabled.png | Bin 0 -> 543 bytes .../krumo/docs/media/images/package.png | Bin 0 -> 668 bytes .../docs/media/images/package_folder.png | Bin 0 -> 564 bytes .../krumo/docs/media/images/plus.gif | Bin 0 -> 56 bytes .../docs/media/images/previous_button.png | Bin 0 -> 644 bytes .../media/images/previous_button_disabled.png | Bin 0 -> 541 bytes .../docs/media/images/private_class_logo.png | Bin 0 -> 1836 bytes .../krumo/docs/media/images/tutorial.png | Bin 0 -> 431 bytes .../docs/media/images/tutorial_folder.png | Bin 0 -> 572 bytes .../krumo/docs/media/images/up_button.png | Bin 0 -> 668 bytes .../krumo/docs/media/lib/classTree.js | 454 + .../krumo/docs/media/stylesheet.css | 181 + gulliver/thirdparty/krumo/docs/packages.html | 40 + .../thirdparty/krumo/docs/ric_INSTALL.html | 49 + .../thirdparty/krumo/docs/ric_LICENSE.html | 522 + .../thirdparty/krumo/docs/ric_README.html | 121 + gulliver/thirdparty/krumo/docs/ric_TODO.html | 41 + .../thirdparty/krumo/docs/ric_VERSION.html | 18 + gulliver/thirdparty/krumo/krumo.ini | 20 + gulliver/thirdparty/krumo/krumo.js | 37 + gulliver/thirdparty/krumo/skins/blue/bg.gif | Bin 0 -> 141 bytes gulliver/thirdparty/krumo/skins/blue/skin.css | 158 + .../thirdparty/krumo/skins/default/bg.gif | Bin 0 -> 141 bytes .../thirdparty/krumo/skins/default/skin.css | 158 + gulliver/thirdparty/krumo/skins/green/bg.gif | Bin 0 -> 141 bytes .../thirdparty/krumo/skins/green/skin.css | 158 + gulliver/thirdparty/krumo/skins/orange/bg.gif | Bin 0 -> 141 bytes .../thirdparty/krumo/skins/orange/skin.css | 158 + .../krumo/skins/schablon.com/collapsed.gif | Bin 0 -> 102 bytes .../krumo/skins/schablon.com/dotted.gif | Bin 0 -> 91 bytes .../krumo/skins/schablon.com/empty.gif | Bin 0 -> 101 bytes .../krumo/skins/schablon.com/expanded.gif | Bin 0 -> 99 bytes .../krumo/skins/schablon.com/skin.css | 166 + gulliver/thirdparty/libchart/COPYING | 674 + gulliver/thirdparty/libchart/ChangeLog | 41 + gulliver/thirdparty/libchart/README | 46 + .../thirdparty/libchart/classes/libchart.php | 42 + .../libchart/classes/model/DataSet.php | 28 + .../libchart/classes/model/Point.php | 59 + .../libchart/classes/model/XYDataSet.php | 56 + .../classes/model/XYSeriesDataSet.php | 76 + .../libchart/classes/view/axis/Axis.php | 130 + .../libchart/classes/view/axis/Bound.php | 146 + .../libchart/classes/view/caption/Caption.php | 112 + .../libchart/classes/view/chart/BarChart.php | 174 + .../libchart/classes/view/chart/Chart.php | 102 + .../classes/view/chart/HorizontalBarChart.php | 213 + .../libchart/classes/view/chart/LineChart.php | 201 + .../libchart/classes/view/chart/PieChart.php | 253 + .../classes/view/chart/VerticalBarChart.php | 213 + .../libchart/classes/view/color/Color.php | 99 + .../libchart/classes/view/color/ColorSet.php | 83 + .../libchart/classes/view/color/Palette.php | 110 + .../libchart/classes/view/plot/Plot.php | 415 + .../classes/view/primitive/Padding.php | 68 + .../classes/view/primitive/Primitive.php | 70 + .../classes/view/primitive/Rectangle.php | 76 + .../libchart/classes/view/text/Text.php | 129 + .../fonts/DejaVuSansCondensed-Bold.ttf | Bin 0 -> 62716 bytes .../libchart/fonts/DejaVuSansCondensed.ttf | Bin 0 -> 73144 bytes .../thirdparty/libchart/images/PoweredBy.png | Bin 0 -> 1608 bytes gulliver/thirdparty/lime/Spyc.class.php | 1014 + gulliver/thirdparty/lime/lime.php | 980 + gulliver/thirdparty/lime/yaml.class.php | 93 + gulliver/thirdparty/pake/pakeApp.class.php | 458 + gulliver/thirdparty/pake/pakeColor.class.php | 72 + .../thirdparty/pake/pakeException.class.php | 91 + .../thirdparty/pake/pakeFileTask.class.php | 64 + gulliver/thirdparty/pake/pakeFinder.class.php | 538 + gulliver/thirdparty/pake/pakeFunction.php | 429 + gulliver/thirdparty/pake/pakeGetopt.class.php | 274 + .../thirdparty/pake/pakeGlobToRegex.class.php | 139 + .../pake/pakeNumberCompare.class.php | 120 + gulliver/thirdparty/pake/pakeTask.class.php | 310 + gulliver/thirdparty/pake/pakeYaml.class.php | 890 + .../pake/tasks/pakePearTask.class.php | 27 + .../pake/tasks/pakePhingTask.class.php | 72 + .../pake/tasks/pakeSimpletestTask.class.php | 112 + gulliver/thirdparty/pear/Archive/Tar.php | 1304 + gulliver/thirdparty/pear/Archive/Zip.php | 3606 ++ .../thirdparty/pear/Benchmark/Iterate.php | 167 + .../thirdparty/pear/Benchmark/Profiler.php | 447 + gulliver/thirdparty/pear/Benchmark/Timer.php | 321 + gulliver/thirdparty/pear/CMD.php | 285 + gulliver/thirdparty/pear/CODING_STANDARDS | 8 + gulliver/thirdparty/pear/Console/Getopt.php | 251 + gulliver/thirdparty/pear/DB.php | 1114 + gulliver/thirdparty/pear/DB/common.php | 2042 ++ gulliver/thirdparty/pear/DB/dbase.php | 225 + gulliver/thirdparty/pear/DB/fbsql.php | 655 + gulliver/thirdparty/pear/DB/ibase.php | 784 + gulliver/thirdparty/pear/DB/ifx.php | 579 + gulliver/thirdparty/pear/DB/msql.php | 242 + gulliver/thirdparty/pear/DB/mssql.php | 738 + gulliver/thirdparty/pear/DB/mysql.php | 916 + gulliver/thirdparty/pear/DB/mysqli.php | 960 + gulliver/thirdparty/pear/DB/oci8.php | 899 + gulliver/thirdparty/pear/DB/odbc.php | 585 + gulliver/thirdparty/pear/DB/pgsql.php | 847 + gulliver/thirdparty/pear/DB/sqlite.php | 695 + gulliver/thirdparty/pear/DB/storage.php | 495 + gulliver/thirdparty/pear/DB/sybase.php | 835 + gulliver/thirdparty/pear/HTTP/HTTP.php | 343 + gulliver/thirdparty/pear/HTTP/Request.php | 1191 + .../thirdparty/pear/HTTP/WebDAV/Server.php | 2000 ++ .../pear/HTTP/WebDAV/Server/Filesystem.php | 755 + .../HTTP/WebDAV/Tools/_parse_lockinfo.php | 237 + .../HTTP/WebDAV/Tools/_parse_propfind.php | 178 + .../HTTP/WebDAV/Tools/_parse_proppatch.php | 214 + gulliver/thirdparty/pear/Log.php | 832 + gulliver/thirdparty/pear/Log/composite.php | 231 + gulliver/thirdparty/pear/Log/console.php | 208 + gulliver/thirdparty/pear/Log/daemon.php | 230 + gulliver/thirdparty/pear/Log/display.php | 141 + gulliver/thirdparty/pear/Log/error_log.php | 127 + gulliver/thirdparty/pear/Log/file.php | 322 + gulliver/thirdparty/pear/Log/firebug.php | 214 + gulliver/thirdparty/pear/Log/mail.php | 257 + gulliver/thirdparty/pear/Log/mcal.php | 170 + gulliver/thirdparty/pear/Log/mdb2.php | 358 + gulliver/thirdparty/pear/Log/null.php | 91 + gulliver/thirdparty/pear/Log/observer.php | 129 + gulliver/thirdparty/pear/Log/sql.php | 294 + gulliver/thirdparty/pear/Log/sqlite.php | 225 + gulliver/thirdparty/pear/Log/syslog.php | 179 + gulliver/thirdparty/pear/Log/win.php | 269 + gulliver/thirdparty/pear/Net/CheckIP.php | 80 + gulliver/thirdparty/pear/Net/Curl.php | 876 + gulliver/thirdparty/pear/Net/DIME.php | 629 + gulliver/thirdparty/pear/Net/FTP.php | 2332 ++ gulliver/thirdparty/pear/Net/FTP/Observer.php | 101 + gulliver/thirdparty/pear/Net/FTP/Socket.php | 783 + gulliver/thirdparty/pear/Net/IDNA.php | 101 + gulliver/thirdparty/pear/Net/IDNA/php4.php | 3011 ++ gulliver/thirdparty/pear/Net/IDNA/php5.php | 3233 ++ gulliver/thirdparty/pear/Net/IPv4.php | 458 + gulliver/thirdparty/pear/Net/IPv6.php | 218 + gulliver/thirdparty/pear/Net/JSON.php | 806 + gulliver/thirdparty/pear/Net/LDAP.php | 1065 + gulliver/thirdparty/pear/Net/LDAP/Entry.php | 524 + gulliver/thirdparty/pear/Net/LDAP/RootDSE.php | 192 + gulliver/thirdparty/pear/Net/LDAP/Schema.php | 355 + gulliver/thirdparty/pear/Net/LDAP/Search.php | 245 + gulliver/thirdparty/pear/Net/LDAP/Util.php | 132 + gulliver/thirdparty/pear/Net/LDAP/fg.php | 38 + gulliver/thirdparty/pear/Net/POP3.php | 1226 + gulliver/thirdparty/pear/Net/SMTP.php | 1082 + gulliver/thirdparty/pear/Net/Socket.php | 576 + gulliver/thirdparty/pear/Net/URL.php | 485 + gulliver/thirdparty/pear/Net/URL2.php | 813 + .../thirdparty/pear/Net/UserAgent/Detect.php | 967 + .../pear/Net/UserAgent/Detect/APC.php | 114 + gulliver/thirdparty/pear/Numbers/Words.php | 145 + .../thirdparty/pear/Numbers/Words/lang.bg.php | 505 + .../thirdparty/pear/Numbers/Words/lang.de.php | 318 + .../thirdparty/pear/Numbers/Words/lang.ee.php | 349 + .../pear/Numbers/Words/lang.en_100.php | 307 + .../pear/Numbers/Words/lang.en_GB.php | 308 + .../pear/Numbers/Words/lang.en_US.php | 509 + .../thirdparty/pear/Numbers/Words/lang.es.php | 343 + .../pear/Numbers/Words/lang.es_AR.php | 470 + .../thirdparty/pear/Numbers/Words/lang.fr.php | 439 + .../thirdparty/pear/Numbers/Words/lang.id.php | 277 + .../pear/Numbers/Words/lang.it_IT.php | 348 + .../thirdparty/pear/Numbers/Words/lang.lt.php | 310 + .../thirdparty/pear/Numbers/Words/lang.pl.php | 513 + .../pear/Numbers/Words/lang.pt_BR.php | 241 + .../thirdparty/pear/Numbers/Words/lang.ru.php | 616 + .../thirdparty/pear/Numbers/Words/lang.sv.php | 310 + gulliver/thirdparty/pear/OLE/OLE.php | 410 + gulliver/thirdparty/pear/OLE/PPS.php | 219 + gulliver/thirdparty/pear/OLE/PPS/File.php | 114 + gulliver/thirdparty/pear/OLE/PPS/Root.php | 519 + gulliver/thirdparty/pear/OS/Guess.php | 265 + gulliver/thirdparty/pear/PEAR.php | 1056 + gulliver/thirdparty/pear/PEAR/Autoloader.php | 186 + gulliver/thirdparty/pear/PEAR/Builder.php | 383 + gulliver/thirdparty/pear/PEAR/Command.php | 322 + .../thirdparty/pear/PEAR/Command/Auth.php | 155 + .../thirdparty/pear/PEAR/Command/Build.php | 89 + .../thirdparty/pear/PEAR/Command/Common.php | 249 + .../thirdparty/pear/PEAR/Command/Config.php | 225 + .../thirdparty/pear/PEAR/Command/Install.php | 302 + .../thirdparty/pear/PEAR/Command/Mirror.php | 99 + .../thirdparty/pear/PEAR/Command/Package.php | 660 + .../thirdparty/pear/PEAR/Command/Registry.php | 319 + .../thirdparty/pear/PEAR/Command/Remote.php | 407 + gulliver/thirdparty/pear/PEAR/Common.php | 1674 + gulliver/thirdparty/pear/PEAR/Config.php | 1139 + gulliver/thirdparty/pear/PEAR/Dependency.php | 356 + .../thirdparty/pear/PEAR/Frontend/CLI.php | 487 + gulliver/thirdparty/pear/PEAR/Installer.php | 874 + gulliver/thirdparty/pear/PEAR/Packager.php | 176 + gulliver/thirdparty/pear/PEAR/Registry.php | 690 + gulliver/thirdparty/pear/PEAR/Remote.php | 367 + gulliver/thirdparty/pear/README | 18 + gulliver/thirdparty/pear/SOAP/Base.php | 1116 + gulliver/thirdparty/pear/SOAP/Client.php | 855 + gulliver/thirdparty/pear/SOAP/Disco.php | 383 + gulliver/thirdparty/pear/SOAP/Fault.php | 127 + .../pear/SOAP/Interop/config.php.dist | 4 + .../thirdparty/pear/SOAP/Interop/index.php | 94 + .../pear/SOAP/Interop/interop_Round2Base.php | 155 + .../SOAP/Interop/interop_Round2GroupB.php | 99 + .../SOAP/Interop/interop_Round2GroupC.php | 35 + .../SOAP/Interop/interop_Round3GroupD.php | 82 + .../pear/SOAP/Interop/interop_client.php | 805 + .../SOAP/Interop/interop_client_results.php | 75 + .../pear/SOAP/Interop/interop_client_run.php | 177 + .../pear/SOAP/Interop/interop_database.sql | 76 + .../pear/SOAP/Interop/interop_test.php | 137 + .../SOAP/Interop/interop_test_functions.php | 90 + .../pear/SOAP/Interop/params_Round2Base.php | 230 + .../pear/SOAP/Interop/params_Round2GroupB.php | 72 + .../pear/SOAP/Interop/params_Round2GroupC.php | 235 + .../pear/SOAP/Interop/params_Round3GroupD.php | 121 + .../pear/SOAP/Interop/params_classes.php | 162 + .../pear/SOAP/Interop/params_values.php | 173 + .../thirdparty/pear/SOAP/Interop/readme.txt | 23 + .../Interop/registrationAndNotification.php | 473 + .../pear/SOAP/Interop/server_Round2Base.php | 51 + .../pear/SOAP/Interop/server_Round2GroupB.php | 55 + .../pear/SOAP/Interop/server_Round2GroupC.php | 33 + .../pear/SOAP/Interop/server_Round3GroupD.php | 49 + .../Interop/server_Round3GroupDCompound1.php | 72 + .../Interop/server_Round3GroupDCompound2.php | 70 + .../Interop/server_Round3GroupDDocLit.php | 98 + .../server_Round3GroupDDocLitParams.php | 96 + .../Interop/server_Round3GroupDEmptySA.php | 38 + .../Interop/server_Round3GroupDImport1.php | 64 + .../Interop/server_Round3GroupDImport2.php | 81 + .../Interop/server_Round3GroupDImport3.php | 101 + .../Interop/server_Round3GroupDRpcEnc.php | 79 + .../Interop/wsdl/InteropTestDocLit.wsdl.php | 136 + .../wsdl/InteropTestDocLitParameters.wsdl.php | 176 + .../wsdl/InteropTestExtensibility.wsdl.php | 74 + .../InteropTestExtensibilityRequired.wsdl.php | 75 + .../Interop/wsdl/InteropTestList.wsdl.php | 62 + .../Interop/wsdl/InteropTestRpcEnc.wsdl.php | 127 + .../Interop/wsdl/InteropTestheaders.wsdl.php | 72 + .../pear/SOAP/Interop/wsdl/compound1.wsdl.php | 86 + .../pear/SOAP/Interop/wsdl/compound2.wsdl.php | 67 + .../SOAP/Interop/wsdl/echoheadersvc.wsdl.php | 18 + .../pear/SOAP/Interop/wsdl/emptysa.wsdl.php | 39 + .../pear/SOAP/Interop/wsdl/import1.wsdl.php | 28 + .../pear/SOAP/Interop/wsdl/import2.wsdl.php | 28 + .../pear/SOAP/Interop/wsdl/import3.wsdl.php | 77 + .../SOAP/Interop/wsdl/imported/import1B.wsdl | 20 + .../SOAP/Interop/wsdl/imported/import2B.wsdl | 22 + .../SOAP/Interop/wsdl/imported/import2B.xsd | 12 + .../pear/SOAP/Interop/wsdl/interop.wsdl.php | 19 + .../pear/SOAP/Interop/wsdl/interopB.wsdl.php | 15 + gulliver/thirdparty/pear/SOAP/Parser.php | 504 + gulliver/thirdparty/pear/SOAP/Server.php | 816 + .../thirdparty/pear/SOAP/Server/Email.php | 198 + .../pear/SOAP/Server/Email_Gateway.php | 138 + gulliver/thirdparty/pear/SOAP/Server/TCP.php | 106 + gulliver/thirdparty/pear/SOAP/Transport.php | 151 + .../thirdparty/pear/SOAP/Transport/HTTP.php | 620 + .../thirdparty/pear/SOAP/Transport/SMTP.php | 206 + .../thirdparty/pear/SOAP/Transport/TCP.php | 153 + .../thirdparty/pear/SOAP/Type/dateTime.php | 243 + .../thirdparty/pear/SOAP/Type/duration.php | 165 + .../thirdparty/pear/SOAP/Type/hexBinary.php | 45 + gulliver/thirdparty/pear/SOAP/Value.php | 238 + gulliver/thirdparty/pear/SOAP/WSDL.php | 2280 ++ .../thirdparty/pear/SOAP/tools/genproxy.php | 21 + .../pear/Spreadsheet/Excel/Writer.php | 104 + .../pear/Spreadsheet/Excel/Writer.php.bk | 104 + .../Spreadsheet/Excel/Writer/BIFFwriter.php | 241 + .../pear/Spreadsheet/Excel/Writer/Format.php | 1035 + .../pear/Spreadsheet/Excel/Writer/Parser.php | 1760 + .../Spreadsheet/Excel/Writer/Validator.php | 225 + .../Spreadsheet/Excel/Writer/Workbook.php | 1545 + .../Spreadsheet/Excel/Writer/Worksheet.php | 3495 ++ .../thirdparty/pear/Spreadsheet/package.xml | 61 + gulliver/thirdparty/pear/System.php | 540 + gulliver/thirdparty/pear/UDDI.php | 720 + gulliver/thirdparty/pear/XML/Parser.php | 684 + gulliver/thirdparty/pear/catalog | 1 + .../thirdparty/pear/class.nusoap_base.php | 905 + gulliver/thirdparty/pear/class.soap_fault.php | 86 + .../thirdparty/pear/class.soap_parser.php | 599 + .../thirdparty/pear/class.soap_server.php | 1038 + .../pear/class.soap_transport_http.php | 1038 + gulliver/thirdparty/pear/class.soap_val.php | 107 + gulliver/thirdparty/pear/class.soapclient.php | 859 + gulliver/thirdparty/pear/class.wsdl.php | 1727 + gulliver/thirdparty/pear/class.wsdlcache.php | 184 + gulliver/thirdparty/pear/class.xmlschema.php | 906 + gulliver/thirdparty/pear/install-pear.php | 109 + gulliver/thirdparty/pear/install-pear.txt | 11 + gulliver/thirdparty/pear/json/class.json.php | 806 + gulliver/thirdparty/pear/nusoap.colosa.php | 7249 ++++ gulliver/thirdparty/pear/nusoap.php | 7246 ++++ gulliver/thirdparty/pear/nusoapmime.php | 478 + .../thirdparty/pear/package-Archive_Tar.xml | 60 + .../pear/package-Console_Getopt.xml | 63 + gulliver/thirdparty/pear/package-PEAR.xml | 342 + gulliver/thirdparty/pear/package.dtd | 109 + gulliver/thirdparty/pear/template.spec | 44 + gulliver/thirdparty/phing/BuildEvent.php | 205 + gulliver/thirdparty/phing/BuildException.php | 100 + gulliver/thirdparty/phing/BuildListener.php | 91 + .../thirdparty/phing/IntrospectionHelper.php | 542 + gulliver/thirdparty/phing/Phing.php | 1161 + gulliver/thirdparty/phing/Project.php | 966 + .../thirdparty/phing/ProjectComponent.php | 72 + .../thirdparty/phing/RuntimeConfigurable.php | 118 + gulliver/thirdparty/phing/Target.php | 317 + gulliver/thirdparty/phing/Task.php | 266 + gulliver/thirdparty/phing/TaskAdapter.php | 84 + gulliver/thirdparty/phing/TaskContainer.php | 42 + gulliver/thirdparty/phing/UnknownElement.php | 211 + .../phing/filters/BaseFilterReader.php | 157 + .../phing/filters/BaseParamFilterReader.php | 69 + .../phing/filters/ChainableReader.php | 42 + .../phing/filters/ExpandProperties.php | 82 + .../thirdparty/phing/filters/HeadFilter.php | 161 + .../thirdparty/phing/filters/LineContains.php | 258 + .../phing/filters/LineContainsRegexp.php | 179 + .../thirdparty/phing/filters/PrefixLines.php | 142 + .../phing/filters/ReplaceRegexp.php | 129 + .../phing/filters/ReplaceTokens.php | 415 + .../phing/filters/StripLineBreaks.php | 148 + .../phing/filters/StripLineComments.php | 205 + .../phing/filters/StripPhpComments.php | 190 + .../thirdparty/phing/filters/TabToSpaces.php | 144 + .../thirdparty/phing/filters/TailFilter.php | 157 + .../thirdparty/phing/filters/TidyFilter.php | 162 + .../phing/filters/TranslateGettext.php | 285 + .../thirdparty/phing/filters/XsltFilter.php | 317 + .../phing/filters/util/ChainReaderHelper.php | 184 + .../phing/filters/util/IniFileTokenReader.php | 96 + .../phing/input/DefaultInputHandler.php | 82 + .../thirdparty/phing/input/InputHandler.php | 45 + .../thirdparty/phing/input/InputRequest.php | 107 + .../input/MultipleChoiceInputRequest.php | 58 + .../phing/input/PropertyFileInputHandler.php | 129 + .../phing/input/YesNoInputRequest.php | 47 + gulliver/thirdparty/phing/lib/Capsule.php | 266 + gulliver/thirdparty/phing/lib/Zip.php | 3588 ++ .../phing/listener/AnsiColorLogger.php | 231 + .../thirdparty/phing/listener/BuildLogger.php | 42 + .../phing/listener/DefaultLogger.php | 233 + .../phing/listener/NoBannerLogger.php | 61 + .../thirdparty/phing/listener/PearLogger.php | 246 + .../thirdparty/phing/listener/XmlLogger.php | 265 + .../phing/listener/defaults.properties | 43 + .../phing/mappers/FileNameMapper.php | 59 + .../phing/mappers/FlattenMapper.php | 55 + .../thirdparty/phing/mappers/GlobMapper.php | 113 + .../phing/mappers/IdentityMapper.php | 54 + .../thirdparty/phing/mappers/MergeMapper.php | 69 + .../thirdparty/phing/mappers/RegexpMapper.php | 97 + .../phing/parser/AbstractHandler.php | 98 + .../phing/parser/AbstractSAXParser.php | 140 + .../phing/parser/DataTypeHandler.php | 144 + .../phing/parser/ExpatParseException.php | 31 + .../thirdparty/phing/parser/ExpatParser.php | 140 + gulliver/thirdparty/phing/parser/Location.php | 72 + .../phing/parser/NestedElementHandler.php | 186 + .../phing/parser/ProjectConfigurator.php | 246 + .../phing/parser/ProjectHandler.php | 146 + .../thirdparty/phing/parser/RootHandler.php | 82 + .../thirdparty/phing/parser/TargetHandler.php | 149 + .../thirdparty/phing/parser/TaskHandler.php | 234 + .../phing/system/io/BufferedReader.php | 170 + .../phing/system/io/BufferedWriter.php | 72 + .../phing/system/io/ConsoleReader.php | 84 + .../thirdparty/phing/system/io/FileReader.php | 179 + .../thirdparty/phing/system/io/FileSystem.php | 657 + .../thirdparty/phing/system/io/FileWriter.php | 139 + .../phing/system/io/FilterReader.php | 72 + .../phing/system/io/IOException.php | 28 + .../thirdparty/phing/system/io/PhingFile.php | 866 + .../thirdparty/phing/system/io/Reader.php | 88 + .../phing/system/io/StringReader.php | 73 + .../phing/system/io/TokenReader.php | 51 + .../phing/system/io/UnixFileSystem.php | 266 + .../phing/system/io/Win32FileSystem.php | 477 + .../phing/system/io/WinNTFileSystem.php | 35 + .../thirdparty/phing/system/io/Writer.php | 48 + .../phing/system/lang/Character.php | 49 + .../phing/system/lang/EventObject.php | 52 + .../system/lang/FileNotFoundException.php | 27 + .../system/lang/NullPointerException.php | 27 + .../phing/system/lang/SecurityException.php | 27 + .../thirdparty/phing/system/util/Message.php | 9 + .../phing/system/util/Properties.php | 270 + .../thirdparty/phing/system/util/Register.php | 115 + .../thirdparty/phing/system/util/Timer.php | 96 + .../phing/tasks/defaults.properties | 72 + .../phing/tasks/ext/CapsuleTask.php | 478 + .../phing/tasks/ext/CreoleSQLExecTask.php | 556 + .../thirdparty/phing/tasks/ext/CreoleTask.php | 242 + .../phing/tasks/ext/ExtractBaseTask.php | 183 + .../thirdparty/phing/tasks/ext/MailTask.php | 77 + .../phing/tasks/ext/PackageAsPathTask.php | 65 + .../phing/tasks/ext/PearPackageTask.php | 421 + .../phing/tasks/ext/PhpLintTask.php | 82 + .../thirdparty/phing/tasks/ext/SmartyTask.php | 610 + .../thirdparty/phing/tasks/ext/TarTask.php | 425 + .../thirdparty/phing/tasks/ext/UntarTask.php | 90 + .../thirdparty/phing/tasks/ext/UnzipTask.php | 68 + .../phing/tasks/ext/XmlLintTask.php | 116 + .../phing/tasks/ext/ZendCodeAnalyzerTask.php | 163 + .../thirdparty/phing/tasks/ext/ZipTask.php | 176 + .../tasks/ext/coverage/CoverageMerger.php | 127 + .../tasks/ext/coverage/CoverageMergerTask.php | 92 + .../tasks/ext/coverage/CoverageReportTask.php | 407 + .../coverage/CoverageReportTransformer.php | 121 + .../tasks/ext/coverage/CoverageSetupTask.php | 163 + .../tasks/ext/ioncube/IoncubeComment.php | 44 + .../tasks/ext/ioncube/IoncubeEncoderTask.php | 336 + .../tasks/ext/ioncube/IoncubeLicenseTask.php | 144 + .../phing/tasks/ext/pearpackage/Fileset.php | 231 + .../tasks/ext/phpdoc/PHPDocumentorTask.php | 191 + .../phing/tasks/ext/phpunit2/BatchTest.php | 171 + .../tasks/ext/phpunit2/FormatterElement.php | 120 + .../tasks/ext/phpunit2/PHPUnit2ReportTask.php | 187 + .../ext/phpunit2/PHPUnit2ResultFormatter.php | 158 + .../phing/tasks/ext/phpunit2/PHPUnit2Task.php | 239 + .../tasks/ext/phpunit2/PHPUnit2TestRunner.php | 107 + .../phing/tasks/ext/phpunit2/PHPUnit2Util.php | 121 + .../phpunit2/PlainPHPUnit2ResultFormatter.php | 117 + .../SummaryPHPUnit2ResultFormatter.php | 58 + .../phpunit2/XMLPHPUnit2ResultFormatter.php | 117 + .../SimpleTestCountResultFormatter.php | 52 + .../simpletest/SimpleTestFormatterElement.php | 62 + .../SimpleTestPlainResultFormatter.php | 95 + .../simpletest/SimpleTestResultFormatter.php | 162 + .../SimpleTestSummaryResultFormatter.php | 54 + .../tasks/ext/simpletest/SimpleTestTask.php | 238 + .../phing/tasks/ext/svn/SvnBaseTask.php | 180 + .../phing/tasks/ext/svn/SvnExportTask.php | 68 + .../tasks/ext/svn/SvnLastRevisionTask.php | 75 + .../phing/tasks/system/AdhocTask.php | 88 + .../phing/tasks/system/AdhocTaskdefTask.php | 90 + .../phing/tasks/system/AdhocTypedefTask.php | 71 + .../phing/tasks/system/AppendTask.php | 240 + .../phing/tasks/system/AvailableTask.php | 132 + .../phing/tasks/system/ChmodTask.php | 177 + .../phing/tasks/system/ConditionTask.php | 74 + .../phing/tasks/system/CopyTask.php | 401 + .../phing/tasks/system/CvsPassTask.php | 173 + .../thirdparty/phing/tasks/system/CvsTask.php | 540 + .../phing/tasks/system/DeleteTask.php | 277 + .../phing/tasks/system/EchoTask.php | 107 + .../phing/tasks/system/ExecTask.php | 248 + .../phing/tasks/system/ExitTask.php | 118 + .../phing/tasks/system/ForeachTask.php | 138 + .../thirdparty/phing/tasks/system/IfTask.php | 224 + .../phing/tasks/system/IncludePathTask.php | 115 + .../phing/tasks/system/InputTask.php | 146 + .../phing/tasks/system/MatchingTask.php | 361 + .../phing/tasks/system/MkdirTask.php | 64 + .../phing/tasks/system/MoveTask.php | 197 + .../phing/tasks/system/PhingCallTask.php | 139 + .../phing/tasks/system/PhingTask.php | 618 + .../phing/tasks/system/PhpEvalTask.php | 169 + .../phing/tasks/system/PropertyPromptTask.php | 201 + .../phing/tasks/system/PropertyTask.php | 438 + .../phing/tasks/system/ReflexiveTask.php | 155 + .../phing/tasks/system/ResolvePathTask.php | 122 + .../phing/tasks/system/SequentialTask.php | 57 + .../phing/tasks/system/TaskdefTask.php | 127 + .../phing/tasks/system/TouchTask.php | 170 + .../phing/tasks/system/TstampTask.php | 168 + .../phing/tasks/system/TypedefTask.php | 125 + .../phing/tasks/system/UpToDateTask.php | 217 + .../phing/tasks/system/WarnTask.php | 35 + .../phing/tasks/system/XsltTask.php | 81 + .../tasks/system/condition/AndCondition.php | 46 + .../tasks/system/condition/Condition.php | 39 + .../tasks/system/condition/ConditionBase.php | 195 + .../system/condition/ContainsCondition.php | 76 + .../system/condition/EqualsCondition.php | 78 + .../system/condition/IsFalseCondition.php | 60 + .../tasks/system/condition/IsSetCondition.php | 53 + .../system/condition/IsTrueCondition.php | 59 + .../tasks/system/condition/NotCondition.php | 48 + .../tasks/system/condition/OrCondition.php | 46 + .../tasks/system/condition/OsCondition.php | 63 + .../condition/ReferenceExistsCondition.php | 52 + .../phing/types/AbstractFileSet.php | 570 + .../thirdparty/phing/types/Commandline.php | 467 + gulliver/thirdparty/phing/types/DataType.php | 182 + .../thirdparty/phing/types/Description.php | 53 + gulliver/thirdparty/phing/types/DirSet.php | 49 + gulliver/thirdparty/phing/types/FileList.php | 223 + gulliver/thirdparty/phing/types/FileSet.php | 56 + .../thirdparty/phing/types/FilterChain.php | 164 + gulliver/thirdparty/phing/types/Mapper.php | 207 + gulliver/thirdparty/phing/types/Parameter.php | 99 + .../phing/types/Parameterizable.php | 32 + gulliver/thirdparty/phing/types/Path.php | 456 + .../thirdparty/phing/types/PatternSet.php | 449 + .../phing/types/PhingFilterReader.php | 136 + gulliver/thirdparty/phing/types/Reference.php | 56 + .../phing/types/RegularExpression.php | 105 + .../thirdparty/phing/types/TokenReader.php | 66 + .../thirdparty/phing/types/TokenSource.php | 157 + .../phing/types/defaults.properties | 13 + .../phing/types/selectors/AndSelector.php | 67 + .../types/selectors/BaseExtendSelector.php | 62 + .../phing/types/selectors/BaseSelector.php | 84 + .../types/selectors/BaseSelectorContainer.php | 270 + .../selectors/ContainsRegexpSelector.php | 164 + .../types/selectors/ContainsSelector.php | 151 + .../phing/types/selectors/DateSelector.php | 214 + .../phing/types/selectors/DependSelector.php | 151 + .../phing/types/selectors/DepthSelector.php | 158 + .../types/selectors/ExtendFileSelector.php | 43 + .../phing/types/selectors/ExtendSelector.php | 127 + .../phing/types/selectors/FileSelector.php | 47 + .../types/selectors/FilenameSelector.php | 157 + .../types/selectors/MajoritySelector.php | 92 + .../phing/types/selectors/NoneSelector.php | 71 + .../phing/types/selectors/NotSelector.php | 59 + .../phing/types/selectors/OrSelector.php | 72 + .../phing/types/selectors/PresentSelector.php | 154 + .../phing/types/selectors/SelectSelector.php | 124 + .../types/selectors/SelectorContainer.php | 141 + .../phing/types/selectors/SelectorScanner.php | 55 + .../phing/types/selectors/SelectorUtils.php | 440 + .../phing/types/selectors/SizeSelector.php | 228 + .../phing/types/selectors/TypeSelector.php | 113 + .../phing/util/DirectoryScanner.php | 710 + .../phing/util/ExtendedFileStream.php | 133 + gulliver/thirdparty/phing/util/FileUtils.php | 294 + gulliver/thirdparty/phing/util/LogWriter.php | 96 + .../thirdparty/phing/util/PathTokenizer.php | 245 + .../phing/util/SourceFileScanner.php | 159 + .../thirdparty/phing/util/StringHelper.php | 209 + .../phing/util/regexp/PregEngine.php | 105 + .../thirdparty/phing/util/regexp/Regexp.php | 168 + .../phing/util/regexp/RegexpEngine.php | 74 + .../thirdparty/phpmailer/class.phpmailer.php | 1508 + gulliver/thirdparty/phpmailer/class.smtp.php | 1045 + .../phpmailer/language/phpmailer.lang-br.php | 21 + .../phpmailer/language/phpmailer.lang-ca.php | 22 + .../phpmailer/language/phpmailer.lang-cz.php | 24 + .../phpmailer/language/phpmailer.lang-de.php | 23 + .../phpmailer/language/phpmailer.lang-dk.php | 24 + .../phpmailer/language/phpmailer.lang-en.php | 23 + .../phpmailer/language/phpmailer.lang-es.php | 23 + .../phpmailer/language/phpmailer.lang-fi.php | 23 + .../phpmailer/language/phpmailer.lang-fo.php | 25 + .../phpmailer/language/phpmailer.lang-fr.php | 24 + .../phpmailer/language/phpmailer.lang-hu.php | 23 + .../phpmailer/language/phpmailer.lang-it.php | 28 + .../phpmailer/language/phpmailer.lang-ja.php | 25 + .../phpmailer/language/phpmailer.lang-nl.php | 23 + .../phpmailer/language/phpmailer.lang-no.php | 23 + .../phpmailer/language/phpmailer.lang-pl.php | 24 + .../phpmailer/language/phpmailer.lang-ro.php | 23 + .../phpmailer/language/phpmailer.lang-ru.php | 23 + .../phpmailer/language/phpmailer.lang-se.php | 24 + .../phpmailer/language/phpmailer.lang-tr.php | 25 + .../thirdparty/propel-generator/CHANGELOG | 150 + gulliver/thirdparty/propel-generator/INSTALL | 176 + gulliver/thirdparty/propel-generator/LICENSE | 506 + .../propel-generator/bin/propel-gen | 67 + .../propel-generator/bin/propel-gen.bat | 47 + .../propel-generator/build-propel.xml | 566 + .../propel-generator/build.properties-sample | 190 + .../thirdparty/propel-generator/build.xml | 177 + .../propel-generator/build.xml-local | 124 + .../classes/propel/engine/EngineException.php | 33 + .../engine/builder/DataModelBuilder.php | 221 + .../propel/engine/builder/om/ClassTools.php | 107 + .../propel/engine/builder/om/OMBuilder.php | 409 + .../engine/builder/om/ObjectBuilder.php | 148 + .../propel/engine/builder/om/PeerBuilder.php | 269 + .../om/php5/PHP5BasicObjectBuilder.php | 1414 + .../builder/om/php5/PHP5BasicPeerBuilder.php | 1478 + .../om/php5/PHP5ComplexObjectBuilder.php | 1273 + .../om/php5/PHP5ComplexPeerBuilder.php | 866 + .../om/php5/PHP5ExtensionNodeBuilder.php | 124 + .../om/php5/PHP5ExtensionNodePeerBuilder.php | 127 + .../om/php5/PHP5ExtensionObjectBuilder.php | 123 + .../om/php5/PHP5ExtensionPeerBuilder.php | 127 + .../builder/om/php5/PHP5InterfaceBuilder.php | 119 + .../builder/om/php5/PHP5MapBuilderBuilder.php | 300 + .../om/php5/PHP5MultiExtendObjectBuilder.php | 209 + .../builder/om/php5/PHP5NodeBuilder.php | 1115 + .../builder/om/php5/PHP5NodePeerBuilder.php | 774 + .../propel/engine/builder/sql/DDLBuilder.php | 130 + .../engine/builder/sql/DataSQLBuilder.php | 215 + .../builder/sql/mssql/MssqlDDLBuilder.php | 186 + .../builder/sql/mssql/MssqlDataSQLBuilder.php | 48 + .../builder/sql/mysql/MysqlDDLBuilder.php | 306 + .../builder/sql/mysql/MysqlDataSQLBuilder.php | 33 + .../builder/sql/mysqli/MysqliDDLBuilder.php | 33 + .../sql/mysqli/MysqliDataSQLBuilder.php | 33 + .../builder/sql/oracle/OracleDDLBuilder.php | 177 + .../sql/oracle/OracleDataSQLBuilder.php | 34 + .../builder/sql/pgsql/PgsqlDDLBuilder.php | 248 + .../builder/sql/pgsql/PgsqlDataSQLBuilder.php | 60 + .../builder/sql/sqlite/SqliteDDLBuilder.php | 126 + .../sql/sqlite/SqliteDataSQLBuilder.php | 47 + .../propel/engine/database/model/AppData.php | 206 + .../propel/engine/database/model/Column.php | 921 + .../model/ConstraintNameGenerator.php | 84 + .../propel/engine/database/model/Database.php | 463 + .../propel/engine/database/model/Domain.php | 313 + .../engine/database/model/ForeignKey.php | 278 + .../propel/engine/database/model/IDMethod.php | 46 + .../database/model/IdMethodParameter.php | 125 + .../propel/engine/database/model/Index.php | 276 + .../engine/database/model/Inheritance.php | 164 + .../engine/database/model/NameFactory.php | 116 + .../engine/database/model/NameGenerator.php | 72 + .../database/model/PhpNameGenerator.php | 131 + .../engine/database/model/PropelTypes.php | 290 + .../propel/engine/database/model/Rule.php | 203 + .../propel/engine/database/model/Table.php | 1154 + .../propel/engine/database/model/Unique.php | 69 + .../engine/database/model/Validator.php | 186 + .../engine/database/model/XMLElement.php | 141 + .../database/transform/XmlToAppData.php | 420 + .../engine/database/transform/XmlToData.php | 189 + .../engine/platform/DefaultPlatform.php | 169 + .../propel/engine/platform/MssqlPlatform.php | 122 + .../propel/engine/platform/MysqlPlatform.php | 105 + .../propel/engine/platform/MysqliPlatform.php | 58 + .../propel/engine/platform/OraclePlatform.php | 89 + .../propel/engine/platform/PgsqlPlatform.php | 114 + .../propel/engine/platform/Platform.php | 128 + .../propel/engine/platform/SqlitePlatform.php | 92 + .../phing/AbstractPropelDataModelTask.php | 635 + .../phing/PropelCreoleTransformTask.php | 777 + .../propel/phing/PropelDataDTDTask.php | 80 + .../propel/phing/PropelDataDumpTask.php | 383 + .../propel/phing/PropelDataModelTask.php | 131 + .../propel/phing/PropelDataSQLTask.php | 219 + .../propel/phing/PropelGraphvizTask.php | 177 + .../classes/propel/phing/PropelOMTask.php | 212 + .../classes/propel/phing/PropelOldOMTask.php | 236 + .../classes/propel/phing/PropelOldSQLTask.php | 287 + .../classes/propel/phing/PropelSQLExec.php | 681 + .../classes/propel/phing/PropelSQLTask.php | 258 + .../propel-generator/default.properties | 219 + .../pear/BuildPropelGenPEARPackageTask.php | 268 + .../pear/build-pear-package.xml | 146 + .../propel-generator/pear/build.properties | 5 + .../propel-generator/pear/pear-build.xml | 114 + .../propel-generator/pear/pear-propel-gen | 21 + .../propel-generator/pear/pear-propel-gen.bat | 24 + .../resources/dtd/database.dtd | 164 + .../resources/xsd/custom_datatypes.xsd | 8 + .../resources/xsd/database.xsd | 346 + .../resources/xsl/database.xsl | 226 + .../propel-generator/templates/README | 5 + .../templates/conf/Control.tpl | 30 + .../propel-generator/templates/conf/xml.tpl | 83 + .../templates/data/dtd/dataset.tpl | 13 + .../templates/data/dtd/table.tpl | 6 + .../templates/data/dump/bottom.tpl | 1 + .../templates/data/dump/row.tpl | 2 + .../templates/data/dump/top.tpl | 3 + .../templates/om/php4/ExtensionNode.tpl | 35 + .../templates/om/php4/ExtensionNodePeer.tpl | 35 + .../templates/om/php4/ExtensionObject.tpl | 36 + .../templates/om/php4/ExtensionPeer.tpl | 36 + .../templates/om/php4/Interface.tpl | 30 + .../templates/om/php4/MapBuilder.tpl | 135 + .../templates/om/php4/MultiExtendObject.tpl | 63 + .../templates/om/php4/Node.tpl | 871 + .../templates/om/php4/NodePeer.tpl | 563 + .../templates/om/php4/Object.tpl | 1938 ++ .../templates/om/php4/Peer.tpl | 1780 + .../templates/om/php5/ExtensionNode.tpl | 35 + .../templates/om/php5/ExtensionNodePeer.tpl | 35 + .../templates/om/php5/ExtensionObject.tpl | 49 + .../templates/om/php5/ExtensionPeer.tpl | 37 + .../templates/om/php5/Interface.tpl | 33 + .../templates/om/php5/MapBuilder.tpl | 135 + .../templates/om/php5/MultiExtendObject.tpl | 60 + .../templates/om/php5/Node.tpl | 801 + .../templates/om/php5/NodePeer.tpl | 522 + .../templates/om/php5/Object.tpl | 1841 ++ .../templates/om/php5/Peer.tpl | 1501 + .../templates/sql/base/mssql/columns.tpl | 20 + .../templates/sql/base/mssql/drop.tpl | 42 + .../templates/sql/base/mssql/foreignkey.tpl | 17 + .../templates/sql/base/mssql/index.tpl | 4 + .../templates/sql/base/mssql/primarykey.tpl | 3 + .../templates/sql/base/mssql/table.tpl | 38 + .../templates/sql/base/mssql/tablefk.tpl | 11 + .../templates/sql/base/mssql/unique.tpl | 3 + .../templates/sql/base/mysql/columns.tpl | 29 + .../templates/sql/base/mysql/database-end.tpl | 5 + .../sql/base/mysql/database-start.tpl | 4 + .../templates/sql/base/mysql/drop.tpl | 1 + .../templates/sql/base/mysql/foreignkey.tpl | 86 + .../templates/sql/base/mysql/index.tpl | 10 + .../templates/sql/base/mysql/primarykey.tpl | 7 + .../templates/sql/base/mysql/table.tpl | 45 + .../templates/sql/base/mysql/tablefk.tpl | 1 + .../templates/sql/base/mysql/unique.tpl | 12 + .../templates/sql/base/oracle/columns.tpl | 19 + .../templates/sql/base/oracle/drop.tpl | 4 + .../templates/sql/base/oracle/foreignkey.tpl | 16 + .../templates/sql/base/oracle/index.tpl | 3 + .../templates/sql/base/oracle/primarykey.tpl | 19 + .../templates/sql/base/oracle/sequence.tpl | 3 + .../templates/sql/base/oracle/table.tpl | 26 + .../templates/sql/base/oracle/tablefk.tpl | 5 + .../templates/sql/base/oracle/unique.tpl | 3 + .../templates/sql/base/pgsql/columns.tpl | 13 + .../templates/sql/base/pgsql/drop.tpl | 4 + .../templates/sql/base/pgsql/foreignkey.tpl | 20 + .../templates/sql/base/pgsql/index.tpl | 3 + .../templates/sql/base/pgsql/primarykey.tpl | 3 + .../templates/sql/base/pgsql/sequence.tpl | 3 + .../templates/sql/base/pgsql/table.tpl | 55 + .../templates/sql/base/pgsql/tablefk.tpl | 14 + .../templates/sql/base/pgsql/unique.tpl | 3 + .../templates/sql/base/sqlite/columns.tpl | 13 + .../templates/sql/base/sqlite/drop.tpl | 1 + .../templates/sql/base/sqlite/foreignkey.tpl | 4 + .../templates/sql/base/sqlite/index.tpl | 3 + .../templates/sql/base/sqlite/table.tpl | 33 + .../templates/sql/base/sqlite/tablefk.tpl | 1 + .../templates/sql/base/sqlite/unique.tpl | 3 + .../templates/sql/db-init/Control.tpl | 13 + .../templates/sql/db-init/mssql/unix.tpl | 6 + .../templates/sql/db-init/mssql/windows.tpl | 1 + .../templates/sql/db-init/mysql/createdb.tpl | 4 + .../templates/sql/db-init/oracle/createdb.tpl | 4 + .../templates/sql/db-init/pgsql/createdb.tpl | 4 + .../templates/sql/load/mssql/row.tpl | 14 + .../templates/sql/load/mssql/val.tpl | 9 + .../templates/sql/load/mysql/row.tpl | 14 + .../templates/sql/load/mysql/val.tpl | 7 + .../templates/sql/load/oracle/row.tpl | 14 + .../templates/sql/load/oracle/val.tpl | 9 + .../templates/sql/load/pgsql/row.tpl | 14 + .../templates/sql/load/pgsql/val.tpl | 11 + .../templates/sql/load/sqlite/row.tpl | 14 + .../templates/sql/load/sqlite/val.tpl | 4 + gulliver/thirdparty/propel/Propel.php | 600 + .../thirdparty/propel/PropelException.php | 61 + .../thirdparty/propel/adapter/DBAdapter.php | 185 + .../thirdparty/propel/adapter/DBArray.php | 114 + .../thirdparty/propel/adapter/DBMSSQL.php | 36 + .../thirdparty/propel/adapter/DBMySQL.php | 133 + .../thirdparty/propel/adapter/DBMySQLi.php | 34 + gulliver/thirdparty/propel/adapter/DBNone.php | 131 + .../thirdparty/propel/adapter/DBOracle.php | 123 + .../thirdparty/propel/adapter/DBPostgres.php | 117 + .../thirdparty/propel/adapter/DBSQLite.php | 124 + .../thirdparty/propel/adapter/DBSybase.php | 133 + .../thirdparty/propel/logger/BasicLogger.php | 103 + .../propel/logger/MojaviLogAdapter.php | 173 + gulliver/thirdparty/propel/map/ColumnMap.php | 344 + .../thirdparty/propel/map/DatabaseMap.php | 127 + gulliver/thirdparty/propel/map/MapBuilder.php | 75 + gulliver/thirdparty/propel/map/TableMap.php | 429 + .../thirdparty/propel/map/ValidatorMap.php | 109 + gulliver/thirdparty/propel/om/BaseObject.php | 187 + gulliver/thirdparty/propel/om/Persistent.php | 118 + .../propel/om/PreOrderNodeIterator.php | 90 + gulliver/thirdparty/propel/util/BasePeer.php | 1001 + gulliver/thirdparty/propel/util/Criteria.php | 1922 ++ gulliver/thirdparty/propel/util/PeerInfo.php | 188 + .../thirdparty/propel/util/PropelPager.php | 543 + .../thirdparty/propel/util/Transaction.php | 160 + .../propel/validator/BasicValidator.php | 46 + .../propel/validator/MatchValidator.php | 81 + .../propel/validator/MaxLengthValidator.php | 52 + .../propel/validator/MaxValueValidator.php | 56 + .../propel/validator/MinLengthValidator.php | 49 + .../propel/validator/MinValueValidator.php | 56 + .../propel/validator/NotMatchValidator.php | 79 + .../propel/validator/RequiredValidator.php | 51 + .../propel/validator/UniqueValidator.php | 66 + .../propel/validator/ValidValuesValidator.php | 46 + .../propel/validator/ValidationFailed.php | 126 + gulliver/thirdparty/smarty/BUGS | 7 + gulliver/thirdparty/smarty/COPYING.lib | 458 + gulliver/thirdparty/smarty/ChangeLog | 8667 +++++ gulliver/thirdparty/smarty/FAQ | 284 + gulliver/thirdparty/smarty/INSTALL | 29 + gulliver/thirdparty/smarty/NEWS | 1013 + gulliver/thirdparty/smarty/QUICK_START | 103 + gulliver/thirdparty/smarty/README | 80 + gulliver/thirdparty/smarty/RELEASE_NOTES | 428 + gulliver/thirdparty/smarty/TODO | 10 + .../thirdparty/smarty/demo/configs/test.conf | 5 + gulliver/thirdparty/smarty/demo/index.php | 25 + .../smarty/demo/templates/footer.tpl | 2 + .../smarty/demo/templates/header.tpl | 6 + .../smarty/demo/templates/index.tpl | 81 + .../smarty/libs/Config_File.class.php | 389 + .../thirdparty/smarty/libs/Smarty.class.php | 1944 ++ .../smarty/libs/Smarty_Compiler.class.php | 2327 ++ gulliver/thirdparty/smarty/libs/debug.tpl | 157 + .../core.assemble_plugin_filepath.php | 67 + .../core.assign_smarty_interface.php | 43 + .../internals/core.create_dir_structure.php | 79 + .../internals/core.display_debug_console.php | 61 + .../libs/internals/core.get_include_path.php | 44 + .../libs/internals/core.get_microtime.php | 23 + .../libs/internals/core.get_php_resource.php | 80 + .../smarty/libs/internals/core.is_secure.php | 59 + .../smarty/libs/internals/core.is_trusted.php | 47 + .../libs/internals/core.load_plugins.php | 125 + .../internals/core.load_resource_plugin.php | 74 + .../internals/core.process_cached_inserts.php | 71 + .../core.process_compiled_include.php | 37 + .../libs/internals/core.read_cache_file.php | 101 + .../smarty/libs/internals/core.rm_auto.php | 71 + .../smarty/libs/internals/core.rmdir.php | 54 + .../internals/core.run_insert_handler.php | 71 + .../internals/core.smarty_include_php.php | 50 + .../libs/internals/core.write_cache_file.php | 96 + .../internals/core.write_compiled_include.php | 91 + .../core.write_compiled_resource.php | 35 + .../smarty/libs/internals/core.write_file.php | 54 + .../smarty/libs/plugins/block.textformat.php | 103 + .../smarty/libs/plugins/compiler.assign.php | 40 + .../plugins/function.assign_debug_info.php | 40 + .../libs/plugins/function.config_load.php | 142 + .../smarty/libs/plugins/function.counter.php | 80 + .../smarty/libs/plugins/function.cycle.php | 102 + .../smarty/libs/plugins/function.debug.php | 35 + .../smarty/libs/plugins/function.eval.php | 49 + .../smarty/libs/plugins/function.fetch.php | 221 + .../libs/plugins/function.html_checkboxes.php | 143 + .../libs/plugins/function.html_image.php | 142 + .../libs/plugins/function.html_options.php | 122 + .../libs/plugins/function.html_radios.php | 156 + .../plugins/function.html_select_date.php | 331 + .../plugins/function.html_select_time.php | 194 + .../libs/plugins/function.html_table.php | 177 + .../smarty/libs/plugins/function.mailto.php | 165 + .../smarty/libs/plugins/function.math.php | 84 + .../smarty/libs/plugins/function.popup.php | 119 + .../libs/plugins/function.popup_init.php | 40 + .../libs/plugins/modifier.capitalize.php | 43 + .../smarty/libs/plugins/modifier.cat.php | 33 + .../plugins/modifier.count_characters.php | 32 + .../plugins/modifier.count_paragraphs.php | 29 + .../libs/plugins/modifier.count_sentences.php | 29 + .../libs/plugins/modifier.count_words.php | 33 + .../libs/plugins/modifier.date_format.php | 58 + .../libs/plugins/modifier.debug_print_var.php | 90 + .../smarty/libs/plugins/modifier.default.php | 32 + .../smarty/libs/plugins/modifier.escape.php | 93 + .../smarty/libs/plugins/modifier.indent.php | 28 + .../smarty/libs/plugins/modifier.lower.php | 26 + .../smarty/libs/plugins/modifier.nl2br.php | 35 + .../libs/plugins/modifier.regex_replace.php | 35 + .../smarty/libs/plugins/modifier.replace.php | 30 + .../smarty/libs/plugins/modifier.spacify.php | 30 + .../libs/plugins/modifier.string_format.php | 29 + .../smarty/libs/plugins/modifier.strip.php | 33 + .../libs/plugins/modifier.strip_tags.php | 32 + .../smarty/libs/plugins/modifier.truncate.php | 50 + .../smarty/libs/plugins/modifier.upper.php | 26 + .../smarty/libs/plugins/modifier.wordwrap.php | 29 + .../plugins/outputfilter.trimwhitespace.php | 75 + .../plugins/shared.escape_special_chars.php | 31 + .../libs/plugins/shared.make_timestamp.php | 46 + .../thirdparty/smarty/misc/smarty_icon.README | 6 + .../thirdparty/smarty/misc/smarty_icon.gif | Bin 0 -> 1102 bytes gulliver/thirdparty/smarty/unit_test/README | 32 + .../thirdparty/smarty/unit_test/config.php | 5 + .../configs/globals_double_quotes.conf | 1 + .../configs/globals_single_quotes.conf | 1 + .../smarty/unit_test/smarty_unit_test.php | 10 + .../smarty/unit_test/smarty_unit_test_gui.php | 10 + .../smarty/unit_test/templates/assign_var.tpl | 1 + .../smarty/unit_test/templates/constant.tpl | 1 + .../smarty/unit_test/templates/index.tpl | 1 + .../smarty/unit_test/templates/parse_math.tpl | 12 + .../unit_test/templates/parse_obj_meth.tpl | 8 + .../smarty/unit_test/test_cases.php | 450 + processmaker | 12 + .../classes/model/AuthenticationSource.php | 129 + .../model/AuthenticationSourcePeer.php | 23 + rbac/engine/classes/model/Permissions.php | 86 + rbac/engine/classes/model/PermissionsPeer.php | 46 + rbac/engine/classes/model/RbacUsers.php | 209 + rbac/engine/classes/model/RbacUsersPeer.php | 46 + rbac/engine/classes/model/Roles.php | 544 + rbac/engine/classes/model/RolesPeer.php | 46 + .../engine/classes/model/RolesPermissions.php | 61 + .../classes/model/RolesPermissionsPeer.php | 46 + rbac/engine/classes/model/Systems.php | 121 + rbac/engine/classes/model/SystemsPeer.php | 46 + rbac/engine/classes/model/UsersRoles.php | 110 + rbac/engine/classes/model/UsersRolesPeer.php | 46 + .../map/AuthenticationSourceMapBuilder.php | 97 + .../model/map/PermissionsMapBuilder.php | 81 + .../classes/model/map/RbacUsersMapBuilder.php | 97 + .../classes/model/map/RolesMapBuilder.php | 83 + .../model/map/RolesPermissionsMapBuilder.php | 73 + .../classes/model/map/SystemsMapBuilder.php | 79 + .../model/map/UsersRolesMapBuilder.php | 73 + .../model/om/BaseAuthenticationSource.php | 1193 + .../model/om/BaseAuthenticationSourcePeer.php | 630 + .../classes/model/om/BasePermissions.php | 813 + .../classes/model/om/BasePermissionsPeer.php | 590 + .../engine/classes/model/om/BaseRbacUsers.php | 1259 + .../classes/model/om/BaseRbacUsersPeer.php | 630 + rbac/engine/classes/model/om/BaseRoles.php | 866 + .../engine/classes/model/om/BaseRolesPeer.php | 595 + .../classes/model/om/BaseRolesPermissions.php | 569 + .../model/om/BaseRolesPermissionsPeer.php | 561 + rbac/engine/classes/model/om/BaseSystems.php | 760 + .../classes/model/om/BaseSystemsPeer.php | 585 + .../classes/model/om/BaseUsersRoles.php | 569 + .../classes/model/om/BaseUsersRolesPeer.php | 561 + rbac/engine/classes/plugins/class.ldap.php | 218 + rbac/engine/config/databases.php | 61 + rbac/engine/config/defines.php | 61 + rbac/engine/config/environments.php | 45 + rbac/engine/config/paths.php | 84 + rbac/engine/config/propel.ini | 44 + rbac/engine/config/propel.mssql.ini | 44 + rbac/engine/config/propel.mysql.ini | 44 + rbac/engine/config/propel.oracle.ini | 44 + rbac/engine/config/propel.pgsql.ini | 44 + rbac/engine/config/properties.ini | 2 + rbac/engine/config/schema-transformed.xml | 2 + rbac/engine/config/schema.xml | 658 + rbac/engine/content/languages/labels.xml | 172 + rbac/engine/content/languages/menus.xml | 64 + rbac/engine/content/messages.en | 18 + rbac/engine/content/messages.es | 18 + rbac/engine/content/messages.po | 18 + rbac/engine/content/rbac/myApp.cnt | 26 + rbac/engine/data/mssql/schema.sql | 247 + rbac/engine/data/mssql/sqldb.map | 2 + rbac/engine/data/mysql/create-db.sql | 2 + rbac/engine/data/mysql/insert.sql | 6 + rbac/engine/data/mysql/schema.sql | 134 + rbac/engine/data/mysql/sqldb.map | 2 + rbac/engine/data/oracle/create-db.sql | 4 + rbac/engine/data/oracle/schema.sql | 127 + rbac/engine/data/oracle/sqldb.map | 2 + rbac/engine/data/pgsql/create-db.sql | 2 + rbac/engine/data/pgsql/sqldb.map | 2 + rbac/engine/db/dbmodule_processmaker.php | 29 + rbac/engine/includes/inc.JSForms.php | 122 + rbac/engine/includes/inc.ajax.php | 91 + rbac/engine/includes/inc.application.php | 118 + rbac/engine/includes/inc.dynaForms.php | 224 + rbac/engine/menus/backApp.php | 42 + rbac/engine/menus/cancel.php | 47 + rbac/engine/menus/rbac.appEdit.php | 64 + rbac/engine/menus/rbac.appView.php | 57 + rbac/engine/menus/rbac.application.php | 34 + rbac/engine/menus/rbac.authSource.php | 33 + rbac/engine/menus/rbac.authentication.php | 33 + rbac/engine/menus/rbac.login.php | 54 + rbac/engine/menus/rbac.permission.php | 48 + rbac/engine/menus/rbac.php | 66 + rbac/engine/menus/rbac.role.php | 65 + rbac/engine/menus/rbac.user.php | 52 + rbac/engine/menus/rbac.userEdit.php | 69 + rbac/engine/menus/rbac.userView.php | 85 + rbac/engine/methods/controls/buscador.php | 50 + rbac/engine/methods/controls/buscador2.php | 38 + rbac/engine/methods/controls/calendar.js | 162 + rbac/engine/methods/controls/calendar.php | 183 + rbac/engine/methods/controls/img/cal.gif | Bin 0 -> 127 bytes rbac/engine/methods/controls/img/logo.gif | Bin 0 -> 660 bytes rbac/engine/methods/controls/img/next.gif | Bin 0 -> 214 bytes .../engine/methods/controls/img/next_year.gif | Bin 0 -> 256 bytes rbac/engine/methods/controls/img/pixel.gif | Bin 0 -> 67 bytes rbac/engine/methods/controls/img/prev.gif | Bin 0 -> 212 bytes .../engine/methods/controls/img/prev_year.gif | Bin 0 -> 259 bytes rbac/engine/methods/controls/img/tc.gif | Bin 0 -> 8301 bytes rbac/engine/methods/login/dbInfo.php | 88 + rbac/engine/methods/login/enumerate.php | 131 + rbac/engine/methods/login/login.php | 55 + rbac/engine/methods/login/loginAjax.php | 82 + rbac/engine/methods/login/noViewPage.php | 37 + rbac/engine/methods/login/showDBFiles.php | 34 + rbac/engine/methods/login/verify-login.php | 85 + rbac/engine/methods/rbac/appDel.php | 36 + rbac/engine/methods/rbac/appEdit.php | 46 + rbac/engine/methods/rbac/appEdit2.php | 50 + rbac/engine/methods/rbac/appList.php | 64 + rbac/engine/methods/rbac/appNew.php | 38 + rbac/engine/methods/rbac/appNew2.php | 49 + rbac/engine/methods/rbac/appView.php | 38 + rbac/engine/methods/rbac/authAddUser.php | 49 + rbac/engine/methods/rbac/authAjax.php | 219 + rbac/engine/methods/rbac/authDel.php | 31 + rbac/engine/methods/rbac/authEdit.php | 46 + rbac/engine/methods/rbac/authEdit2.php | 45 + rbac/engine/methods/rbac/authNew.php | 45 + rbac/engine/methods/rbac/authNew2.php | 47 + rbac/engine/methods/rbac/authTest.php | 133 + .../methods/rbac/authenticationList.php | 33 + rbac/engine/methods/rbac/dbInfo.php | 91 + rbac/engine/methods/rbac/loadAuthSource.php | 27 + rbac/engine/methods/rbac/loadPermView.php | 28 + rbac/engine/methods/rbac/loadRoleProp.php | 35 + rbac/engine/methods/rbac/loadRoleProp2.php | 40 + rbac/engine/methods/rbac/loadRoleView.php | 28 + rbac/engine/methods/rbac/loadUser.php | 27 + rbac/engine/methods/rbac/loadUserRole.php | 29 + rbac/engine/methods/rbac/message.php | 31 + rbac/engine/methods/rbac/permDel.php | 38 + rbac/engine/methods/rbac/permEdit.php | 48 + rbac/engine/methods/rbac/permEdit2.php | 48 + rbac/engine/methods/rbac/permList.php | 40 + rbac/engine/methods/rbac/permNew.php | 56 + rbac/engine/methods/rbac/permNew2.php | 48 + rbac/engine/methods/rbac/roleDel.php | 38 + rbac/engine/methods/rbac/roleEdit.php | 52 + rbac/engine/methods/rbac/roleEdit2.php | 47 + rbac/engine/methods/rbac/roleList.php | 38 + rbac/engine/methods/rbac/roleNew.php | 63 + rbac/engine/methods/rbac/roleNew2.php | 49 + rbac/engine/methods/rbac/roleProp.php | 56 + rbac/engine/methods/rbac/showFieldAjax.php | 206 + rbac/engine/methods/rbac/userAssignRole.php | 70 + rbac/engine/methods/rbac/userAssignRole2.php | 37 + rbac/engine/methods/rbac/userChangeLdap.php | 51 + rbac/engine/methods/rbac/userChangeLdap2.php | 44 + rbac/engine/methods/rbac/userChangePwd.php | 41 + rbac/engine/methods/rbac/userChangePwd2.php | 43 + rbac/engine/methods/rbac/userEdit.php | 155 + rbac/engine/methods/rbac/userEdit2.php | 98 + rbac/engine/methods/rbac/userList.php | 44 + rbac/engine/methods/rbac/userNew.php | 33 + rbac/engine/methods/rbac/userNew2.php | 75 + rbac/engine/methods/rbac/userNew3.php | 33 + rbac/engine/methods/rbac/userNew4.php | 56 + rbac/engine/methods/rbac/userRoleDel.php | 38 + rbac/engine/methods/rbac/userRoleProp.php | 57 + rbac/engine/methods/rbac/userTestLdap.php | 55 + rbac/engine/methods/rbac/userTestLdap2.php | 62 + rbac/engine/methods/rbac/userView.php | 47 + rbac/engine/methods/rbac/userViewRole.php | 52 + rbac/engine/pre_processor.php | 201 + rbac/engine/skins/blank.html | 21 + rbac/engine/skins/blank.php | 46 + rbac/engine/skins/index.html | 408 + rbac/engine/skins/styles.html | 53 + rbac/engine/skins/styles.php | 46 + rbac/engine/skins/stylesSimple.html | 188 + rbac/engine/skins/wf.php | 170 + rbac/engine/skins/wf5.php | 45 + rbac/engine/tables/rbac.applications.list.php | 82 + .../tables/rbac.authentication.list.php | 42 + rbac/engine/tables/rbac.permissions.list.php | 68 + rbac/engine/tables/rbac.roles.list.php | 71 + rbac/engine/tables/rbac.users.list.php | 78 + rbac/engine/tables/rbac.users.role.php | 89 + rbac/engine/templates/authListUsers.html | 71 + rbac/engine/templates/filterform.html | 111 + rbac/engine/templates/formFilter.html | 113 + rbac/engine/templates/grid.html | 107 + rbac/engine/templates/login/showDBFiles.php | 113 + rbac/engine/templates/paged-table.html | 58 + rbac/engine/templates/paged-table.php | 221 + rbac/engine/templates/popupMenu.html | 33 + rbac/engine/templates/publish.php | 53 + .../templates/testAuthenticationSource.html | 17 + .../templates/testAuthenticationSource.php | 251 + .../templates/testAuthenticationUser.php | 66 + rbac/engine/templates/toolbar.html | 21 + rbac/engine/templates/treePerm.php | 170 + rbac/engine/templates/treePermRole.php | 173 + rbac/engine/templates/treeRole.php | 172 + rbac/engine/templates/xmlform.html | 123 + rbac/engine/templates/xmlmenu.html | 77 + rbac/engine/xmlform/login.html | 33 + rbac/engine/xmlform/login/login.es | 39 + rbac/engine/xmlform/login/login.xml | 19 + rbac/engine/xmlform/login/noViewPage.xml | 19 + rbac/engine/xmlform/login/nologin.xml | 28 + rbac/engine/xmlform/rbac/appEdit.xml | 58 + rbac/engine/xmlform/rbac/appMenu.xml | 16 + rbac/engine/xmlform/rbac/appNew.es | 72 + rbac/engine/xmlform/rbac/appNew.xml | 41 + .../engine/xmlform/rbac/applicationsList.html | 18 + rbac/engine/xmlform/rbac/applicationsList.xml | 39 + .../xmlform/rbac/applicationsListCriteria.xml | 28 + rbac/engine/xmlform/rbac/authAddUser.es | 21 + rbac/engine/xmlform/rbac/authAddUser.html | 22 + rbac/engine/xmlform/rbac/authAddUser.xml | 125 + rbac/engine/xmlform/rbac/authNew.es | 103 + rbac/engine/xmlform/rbac/authNew.xml | 81 + .../xmlform/rbac/authenticationList.xml | 27 + .../xmlform/rbac/authenticationsList.es | 44 + .../xmlform/rbac/authenticationsList.xml | 27 + rbac/engine/xmlform/rbac/dbInfo.es | 98 + rbac/engine/xmlform/rbac/dbInfo.xml | 79 + .../xmlform/rbac/noMoreRolesAvailable.xml | 18 + rbac/engine/xmlform/rbac/permEdit.xml | 38 + rbac/engine/xmlform/rbac/permNew.xml | 47 + rbac/engine/xmlform/rbac/roleEdit.es | 56 + rbac/engine/xmlform/rbac/roleEdit.xml | 35 + rbac/engine/xmlform/rbac/roleNew.xml | 52 + rbac/engine/xmlform/rbac/userAssignRole.en | 57 + rbac/engine/xmlform/rbac/userAssignRole.es | 57 + rbac/engine/xmlform/rbac/userAssignRole.xml | 35 + rbac/engine/xmlform/rbac/userAssignRole3.xml | 45 + rbac/engine/xmlform/rbac/userChangeLdap.xml | 53 + rbac/engine/xmlform/rbac/userChangePwd.xml | 28 + rbac/engine/xmlform/rbac/userEdit.es | 98 + rbac/engine/xmlform/rbac/userEdit.xml | 77 + rbac/engine/xmlform/rbac/userNew.es | 53 + rbac/engine/xmlform/rbac/userNew.xml | 33 + rbac/engine/xmlform/rbac/userNewPwd.xml | 28 + rbac/engine/xmlform/rbac/userTestLdap.xml | 26 + rbac/engine/xmlform/rbac/userView.xml | 73 + rbac/engine/xmlform/rbac/usersList.xml | 41 + rbac/engine/xmlform/rbac/usersListFilter.xml | 52 + rbac/engine/xmlform/rbac/usersListMenu.xml | 16 + rbac/engine/xmlform/rbac/usersRolesList.xml | 26 + rbac/public_html/errors/error.php | 10 + rbac/public_html/errors/error400.php | 9 + rbac/public_html/errors/error401.php | 15 + rbac/public_html/errors/error403.php | 11 + rbac/public_html/errors/error404.php | 21 + rbac/public_html/errors/error503.php | 11 + rbac/public_html/errors/error701.php | 9 + rbac/public_html/errors/error702.php | 9 + rbac/public_html/errors/error703.php | 9 + rbac/public_html/errors/error704.php | 9 + rbac/public_html/errors/estilo.css | 78 + rbac/public_html/errors/header.php | 29 + rbac/public_html/errors/library/logo.gif | Bin 0 -> 3342 bytes rbac/public_html/images/arrow_order_asc.gif | Bin 0 -> 842 bytes rbac/public_html/images/arrow_order_desc.gif | Bin 0 -> 835 bytes rbac/public_html/images/browse.gif | Bin 0 -> 908 bytes rbac/public_html/images/btnGreen.gif | Bin 0 -> 875 bytes rbac/public_html/images/btnRed.gif | Bin 0 -> 875 bytes rbac/public_html/images/btnYellow.gif | Bin 0 -> 879 bytes rbac/public_html/images/calendar/cal.gif | Bin 0 -> 127 bytes rbac/public_html/images/calendar/logo.gif | Bin 0 -> 660 bytes rbac/public_html/images/calendar/next.gif | Bin 0 -> 214 bytes .../public_html/images/calendar/next_year.gif | Bin 0 -> 256 bytes rbac/public_html/images/calendar/pixel.gif | Bin 0 -> 67 bytes rbac/public_html/images/calendar/prev.gif | Bin 0 -> 212 bytes .../public_html/images/calendar/prev_year.gif | Bin 0 -> 259 bytes rbac/public_html/images/calendar/tc.gif | Bin 0 -> 8301 bytes rbac/public_html/images/date.gif | Bin 0 -> 94 bytes rbac/public_html/images/doc.gif | Bin 0 -> 653 bytes rbac/public_html/images/edit.gif | Bin 0 -> 115 bytes rbac/public_html/images/form.gif | Bin 0 -> 990 bytes rbac/public_html/images/ftv2doc.gif | Bin 0 -> 895 bytes rbac/public_html/images/ftv2lastnode.gif | Bin 0 -> 142 bytes rbac/public_html/images/ftv2mlastnode.gif | Bin 0 -> 125 bytes rbac/public_html/images/ftv2mnode.gif | Bin 0 -> 97 bytes rbac/public_html/images/ftv2node.gif | Bin 0 -> 147 bytes rbac/public_html/images/ftv2pnode.gif | Bin 0 -> 878 bytes rbac/public_html/images/ftv2vertline.gif | Bin 0 -> 140 bytes rbac/public_html/images/minus.gif | Bin 0 -> 868 bytes rbac/public_html/images/plus.gif | Bin 0 -> 878 bytes rbac/public_html/images/trash.gif | Bin 0 -> 872 bytes rbac/public_html/index.html | 8 + rbac/public_html/skins/JSForms.js | 496 + rbac/public_html/skins/ajax.js | 128 + .../public_html/skins/styles/simple/style.css | 326 + rbac/public_html/skins/valida.js | 1108 + rbac/public_html/skins/wf/arrow.gif | Bin 0 -> 113 bytes rbac/public_html/skins/wf/arrow2.gif | Bin 0 -> 67 bytes rbac/public_html/skins/wf/general.css | 190 + rbac/public_html/skins/wf/generalPrinter.css | 61 + rbac/public_html/skins/wf/help_big.gif | Bin 0 -> 303 bytes rbac/public_html/skins/wf/help_small.gif | Bin 0 -> 146 bytes rbac/public_html/skins/wf/menuShadow.gif | Bin 0 -> 75 bytes rbac/public_html/skins/wf/spacer.gif | Bin 0 -> 49 bytes rbac/public_html/skins/wf/tab.gif | Bin 0 -> 85 bytes rbac/public_html/skins/wf/topBackgr.jpg | Bin 0 -> 1405 bytes rbac/public_html/skins/wf5/style.css | 120 + rbac/public_html/sysGeneric.php | 91 + rbac/public_html/sysUnnamed.php | 33 + rbac/public_html/xmlform/login/login.js | 12 + rbac/public_html/xmlform/rbac/appNew.js | 15 + rbac/public_html/xmlform/rbac/authAddUser.js | 12 + rbac/public_html/xmlform/rbac/authNew.js | 30 + rbac/public_html/xmlform/rbac/dbInfo.js | 9 + rbac/public_html/xmlform/rbac/roleEdit.js | 18 + .../xmlform/rbac/userAssignRole.js | 19 + rbac/public_html/xmlform/rbac/userEdit.js | 32 + rbac/public_html/xmlform/rbac/userNew.js | 21 + workflow/engine/bin/commands.php | 59 + workflow/engine/bin/commands/cmdDrafts.php | 90 + workflow/engine/bin/commands/cmdSchema.php | 49 + workflow/engine/bin/cron.php | 81 + workflow/engine/bin/cron_single.php | 362 + workflow/engine/classes/class.ArrayPeer.php | 830 + workflow/engine/classes/class.BasePeer.php | 667 + workflow/engine/classes/class.Installer.php | 577 + workflow/engine/classes/class.archive.php | 713 + workflow/engine/classes/class.calendar.php | 231 + workflow/engine/classes/class.case.php | 5163 +++ .../engine/classes/class.configuration.php | 423 + workflow/engine/classes/class.dashboards.php | 177 + workflow/engine/classes/class.dates.php | 478 + .../engine/classes/class.dbConnections.php | 399 + workflow/engine/classes/class.derivation.php | 970 + .../engine/classes/class.dynaFormField.php | 202 + .../engine/classes/class.dynaformEditor.php | 923 + workflow/engine/classes/class.groupUser.php | 84 + workflow/engine/classes/class.groups.php | 366 + workflow/engine/classes/class.insert.php | 102 + .../engine/classes/class.javaBridgePM.php | 175 + workflow/engine/classes/class.jrml.php | 221 + workflow/engine/classes/class.languages.php | 350 + workflow/engine/classes/class.net.php | 505 + workflow/engine/classes/class.package.php | 266 + workflow/engine/classes/class.plugin.php | 519 + .../engine/classes/class.pluginRegistry.php | 921 + workflow/engine/classes/class.pmFunctions.php | 1742 + workflow/engine/classes/class.pmScript.php | 632 + workflow/engine/classes/class.popupMenu.php | 100 + workflow/engine/classes/class.processMap.php | 4009 +++ workflow/engine/classes/class.processes.php | 3286 ++ workflow/engine/classes/class.propelTable.php | 783 + .../engine/classes/class.replacementLogo.php | 101 + workflow/engine/classes/class.report.php | 1022 + .../engine/classes/class.reportTables.php | 588 + .../classes/class.serverConfiguration.php | 404 + workflow/engine/classes/class.sessions.php | 274 + workflow/engine/classes/class.smtp.php | 302 + .../engine/classes/class.smtp.rfc-821.php | 1035 + workflow/engine/classes/class.spool.php | 432 + workflow/engine/classes/class.system.php | 521 + workflow/engine/classes/class.tasks.php | 652 + workflow/engine/classes/class.toolBar.php | 159 + .../engine/classes/class.triggerLibrary.php | 160 + workflow/engine/classes/class.webdav.php | 992 + workflow/engine/classes/class.wsBase.php | 2029 ++ workflow/engine/classes/class.wsResponse.php | 177 + workflow/engine/classes/class.wsTools.php | 370 + workflow/engine/classes/class.xmlDb.php | 629 + .../engine/classes/class.xmlfield_Image.php | 43 + .../engine/classes/class.xmlfield_InputPM.php | 463 + .../engine/classes/model/AdditionalTables.php | 1123 + .../classes/model/AdditionalTablesPeer.php | 23 + .../engine/classes/model/AppCacheView.php | 1188 + .../engine/classes/model/AppCacheViewPeer.php | 23 + workflow/engine/classes/model/AppDelay.php | 118 + .../engine/classes/model/AppDelayPeer.php | 23 + .../engine/classes/model/AppDelegation.php | 415 + .../classes/model/AppDelegationPeer.php | 46 + workflow/engine/classes/model/AppDocument.php | 574 + .../engine/classes/model/AppDocumentPeer.php | 46 + workflow/engine/classes/model/AppEvent.php | 307 + .../engine/classes/model/AppEventPeer.php | 23 + workflow/engine/classes/model/AppFolder.php | 424 + .../engine/classes/model/AppFolderPeer.php | 23 + workflow/engine/classes/model/AppHistory.php | 199 + .../engine/classes/model/AppHistoryPeer.php | 23 + workflow/engine/classes/model/AppMessage.php | 120 + .../engine/classes/model/AppMessagePeer.php | 46 + workflow/engine/classes/model/AppOwner.php | 42 + .../engine/classes/model/AppOwnerPeer.php | 46 + workflow/engine/classes/model/AppSpool.php | 19 + .../engine/classes/model/AppSpoolPeer.php | 23 + workflow/engine/classes/model/AppThread.php | 121 + .../engine/classes/model/AppThreadPeer.php | 46 + workflow/engine/classes/model/Application.php | 533 + .../engine/classes/model/ApplicationPeer.php | 46 + .../classes/model/CalendarAssignments.php | 19 + .../classes/model/CalendarAssignmentsPeer.php | 23 + .../classes/model/CalendarBusinessHours.php | 107 + .../model/CalendarBusinessHoursPeer.php | 23 + .../classes/model/CalendarDefinition.php | 328 + .../classes/model/CalendarDefinitionPeer.php | 23 + .../engine/classes/model/CalendarHolidays.php | 111 + .../classes/model/CalendarHolidaysPeer.php | 23 + .../engine/classes/model/CaseScheduler.php | 873 + .../classes/model/CaseSchedulerPeer.php | 23 + workflow/engine/classes/model/CaseTracker.php | 121 + .../classes/model/CaseTrackerObject.php | 169 + .../classes/model/CaseTrackerObjectPeer.php | 23 + .../engine/classes/model/CaseTrackerPeer.php | 23 + .../engine/classes/model/Configuration.php | 145 + .../classes/model/ConfigurationPeer.php | 46 + workflow/engine/classes/model/Content.php | 299 + workflow/engine/classes/model/ContentPeer.php | 46 + workflow/engine/classes/model/DbSource.php | 195 + .../engine/classes/model/DbSourcePeer.php | 23 + workflow/engine/classes/model/Department.php | 558 + .../engine/classes/model/DepartmentPeer.php | 46 + .../engine/classes/model/DimTimeComplete.php | 19 + .../classes/model/DimTimeCompletePeer.php | 23 + .../engine/classes/model/DimTimeDelegate.php | 19 + .../classes/model/DimTimeDelegatePeer.php | 23 + workflow/engine/classes/model/Dynaform.php | 469 + .../engine/classes/model/DynaformPeer.php | 46 + workflow/engine/classes/model/Event.php | 743 + workflow/engine/classes/model/EventPeer.php | 23 + .../engine/classes/model/FieldCondition.php | 345 + .../classes/model/FieldConditionPeer.php | 23 + workflow/engine/classes/model/Fields.php | 119 + workflow/engine/classes/model/FieldsPeer.php | 23 + workflow/engine/classes/model/GroupUser.php | 102 + .../engine/classes/model/GroupUserPeer.php | 46 + workflow/engine/classes/model/Groupwf.php | 263 + workflow/engine/classes/model/GroupwfPeer.php | 46 + workflow/engine/classes/model/Holiday.php | 42 + workflow/engine/classes/model/HolidayPeer.php | 46 + .../engine/classes/model/InputDocument.php | 317 + .../classes/model/InputDocumentPeer.php | 46 + workflow/engine/classes/model/IsoCountry.php | 62 + .../engine/classes/model/IsoCountryPeer.php | 46 + workflow/engine/classes/model/IsoLocation.php | 67 + .../engine/classes/model/IsoLocationPeer.php | 46 + .../engine/classes/model/IsoSubdivision.php | 42 + .../classes/model/IsoSubdivisionPeer.php | 46 + workflow/engine/classes/model/Language.php | 120 + .../engine/classes/model/LanguagePeer.php | 46 + workflow/engine/classes/model/Lexico.php | 42 + workflow/engine/classes/model/LexicoPeer.php | 46 + .../classes/model/LogCasesScheduler.php | 74 + .../classes/model/LogCasesSchedulerPeer.php | 23 + workflow/engine/classes/model/LoginLog.php | 109 + .../engine/classes/model/LoginLogPeer.php | 23 + .../engine/classes/model/ObjectPermission.php | 135 + .../classes/model/ObjectPermissionPeer.php | 23 + .../engine/classes/model/OutputDocument.php | 795 + .../classes/model/OutputDocumentPeer.php | 46 + workflow/engine/classes/model/Process.php | 610 + .../engine/classes/model/ProcessCategory.php | 57 + .../classes/model/ProcessCategoryPeer.php | 23 + .../engine/classes/model/ProcessOwner.php | 42 + .../engine/classes/model/ProcessOwnerPeer.php | 46 + workflow/engine/classes/model/ProcessPeer.php | 46 + workflow/engine/classes/model/ProcessUser.php | 96 + .../engine/classes/model/ProcessUserPeer.php | 23 + workflow/engine/classes/model/ReportTable.php | 219 + .../engine/classes/model/ReportTablePeer.php | 23 + workflow/engine/classes/model/ReportVar.php | 158 + .../engine/classes/model/ReportVarPeer.php | 23 + workflow/engine/classes/model/Route.php | 181 + workflow/engine/classes/model/RoutePeer.php | 46 + workflow/engine/classes/model/Session.php | 19 + workflow/engine/classes/model/SessionPeer.php | 23 + workflow/engine/classes/model/ShadowTable.php | 87 + .../engine/classes/model/ShadowTablePeer.php | 23 + workflow/engine/classes/model/Stage.php | 196 + workflow/engine/classes/model/StagePeer.php | 23 + workflow/engine/classes/model/Step.php | 402 + workflow/engine/classes/model/StepPeer.php | 46 + .../engine/classes/model/StepSupervisor.php | 226 + .../classes/model/StepSupervisorPeer.php | 23 + workflow/engine/classes/model/StepTrigger.php | 324 + .../engine/classes/model/StepTriggerPeer.php | 46 + .../engine/classes/model/SubApplication.php | 94 + .../classes/model/SubApplicationPeer.php | 23 + workflow/engine/classes/model/SubProcess.php | 162 + .../engine/classes/model/SubProcessPeer.php | 23 + .../classes/model/SwimlanesElements.php | 235 + .../classes/model/SwimlanesElementsPeer.php | 46 + workflow/engine/classes/model/Task.php | 562 + workflow/engine/classes/model/TaskPeer.php | 46 + workflow/engine/classes/model/TaskUser.php | 132 + .../engine/classes/model/TaskUserPeer.php | 46 + workflow/engine/classes/model/Translation.php | 365 + .../engine/classes/model/TranslationPeer.php | 46 + workflow/engine/classes/model/Triggers.php | 330 + .../engine/classes/model/TriggersPeer.php | 46 + workflow/engine/classes/model/Users.php | 229 + workflow/engine/classes/model/UsersPeer.php | 46 + .../engine/classes/model/UsersProperties.php | 271 + .../classes/model/UsersPropertiesPeer.php | 23 + .../model/map/AdditionalTablesMapBuilder.php | 93 + .../model/map/AppCacheViewMapBuilder.php | 129 + .../classes/model/map/AppDelayMapBuilder.php | 97 + .../model/map/AppDelegationMapBuilder.php | 119 + .../model/map/AppDocumentMapBuilder.php | 127 + .../classes/model/map/AppEventMapBuilder.php | 83 + .../classes/model/map/AppFolderMapBuilder.php | 79 + .../model/map/AppHistoryMapBuilder.php | 87 + .../model/map/AppMessageMapBuilder.php | 101 + .../classes/model/map/AppOwnerMapBuilder.php | 75 + .../classes/model/map/AppSpoolMapBuilder.php | 79 + .../classes/model/map/AppThreadMapBuilder.php | 81 + .../model/map/ApplicationMapBuilder.php | 103 + .../map/CalendarAssignmentsMapBuilder.php | 75 + .../map/CalendarBusinessHoursMapBuilder.php | 79 + .../map/CalendarDefinitionMapBuilder.php | 85 + .../model/map/CalendarHolidaysMapBuilder.php | 77 + .../model/map/CaseSchedulerMapBuilder.php | 119 + .../model/map/CaseTrackerMapBuilder.php | 93 + .../model/map/CaseTrackerObjectMapBuilder.php | 83 + .../model/map/ConfigurationMapBuilder.php | 81 + .../classes/model/map/ContentMapBuilder.php | 83 + .../classes/model/map/DbSourceMapBuilder.php | 87 + .../model/map/DepartmentMapBuilder.php | 83 + .../model/map/DimTimeCompleteMapBuilder.php | 85 + .../model/map/DimTimeDelegateMapBuilder.php | 85 + .../classes/model/map/DynaformMapBuilder.php | 79 + .../classes/model/map/EventMapBuilder.php | 99 + .../model/map/FieldConditionMapBuilder.php | 85 + .../classes/model/map/FieldsMapBuilder.php | 93 + .../classes/model/map/GroupUserMapBuilder.php | 81 + .../classes/model/map/GroupwfMapBuilder.php | 77 + .../classes/model/map/HolidayMapBuilder.php | 75 + .../model/map/InputDocumentMapBuilder.php | 105 + .../model/map/IsoCountryMapBuilder.php | 75 + .../model/map/IsoLocationMapBuilder.php | 79 + .../model/map/IsoSubdivisionMapBuilder.php | 75 + .../classes/model/map/LanguageMapBuilder.php | 91 + .../classes/model/map/LexicoMapBuilder.php | 77 + .../model/map/LogCasesSchedulerMapBuilder.php | 89 + .../classes/model/map/LoginLogMapBuilder.php | 85 + .../model/map/ObjectPermissionMapBuilder.php | 131 + .../model/map/OutputDocumentMapBuilder.php | 111 + .../model/map/ProcessCategoryMapBuilder.php | 77 + .../classes/model/map/ProcessMapBuilder.php | 123 + .../model/map/ProcessOwnerMapBuilder.php | 73 + .../model/map/ProcessUserMapBuilder.php | 93 + .../model/map/ReportTableMapBuilder.php | 109 + .../classes/model/map/ReportVarMapBuilder.php | 95 + .../classes/model/map/RouteMapBuilder.php | 119 + .../classes/model/map/SessionMapBuilder.php | 83 + .../model/map/ShadowTableMapBuilder.php | 83 + .../classes/model/map/StageMapBuilder.php | 79 + .../classes/model/map/StepMapBuilder.php | 87 + .../model/map/StepSupervisorMapBuilder.php | 81 + .../model/map/StepTriggerMapBuilder.php | 83 + .../model/map/SubApplicationMapBuilder.php | 89 + .../model/map/SubProcessMapBuilder.php | 99 + .../model/map/SwimlanesElementsMapBuilder.php | 91 + .../classes/model/map/TaskMapBuilder.php | 175 + .../classes/model/map/TaskUserMapBuilder.php | 93 + .../model/map/TranslationMapBuilder.php | 93 + .../classes/model/map/TriggersMapBuilder.php | 83 + .../classes/model/map/UsersMapBuilder.php | 123 + .../model/map/UsersPropertiesMapBuilder.php | 77 + workflow/engine/classes/model/om/.directory | 4 + .../classes/model/om/BaseAdditionalTables.php | 1087 + .../model/om/BaseAdditionalTablesPeer.php | 620 + .../classes/model/om/BaseAppCacheView.php | 2183 ++ .../classes/model/om/BaseAppCacheViewPeer.php | 701 + .../engine/classes/model/om/BaseAppDelay.php | 1259 + .../classes/model/om/BaseAppDelayPeer.php | 630 + .../classes/model/om/BaseAppDelegation.php | 1693 + .../model/om/BaseAppDelegationPeer.php | 670 + .../classes/model/om/BaseAppDocument.php | 1249 + .../classes/model/om/BaseAppDocumentPeer.php | 645 + .../engine/classes/model/om/BaseAppEvent.php | 883 + .../classes/model/om/BaseAppEventPeer.php | 593 + .../engine/classes/model/om/BaseAppFolder.php | 760 + .../classes/model/om/BaseAppFolderPeer.php | 585 + .../classes/model/om/BaseAppHistory.php | 953 + .../classes/model/om/BaseAppHistoryPeer.php | 567 + .../classes/model/om/BaseAppMessage.php | 1343 + .../classes/model/om/BaseAppMessagePeer.php | 640 + .../engine/classes/model/om/BaseAppOwner.php | 627 + .../classes/model/om/BaseAppOwnerPeer.php | 573 + .../engine/classes/model/om/BaseAppSpool.php | 716 + .../classes/model/om/BaseAppSpoolPeer.php | 585 + .../engine/classes/model/om/BaseAppThread.php | 728 + .../classes/model/om/BaseAppThreadPeer.php | 579 + .../classes/model/om/BaseApplication.php | 1387 + .../classes/model/om/BaseApplicationPeer.php | 643 + .../model/om/BaseCalendarAssignments.php | 610 + .../model/om/BaseCalendarAssignmentsPeer.php | 575 + .../model/om/BaseCalendarBusinessHours.php | 685 + .../om/BaseCalendarBusinessHoursPeer.php | 588 + .../model/om/BaseCalendarDefinition.php | 866 + .../model/om/BaseCalendarDefinitionPeer.php | 598 + .../classes/model/om/BaseCalendarHolidays.php | 719 + .../model/om/BaseCalendarHolidaysPeer.php | 571 + .../classes/model/om/BaseCaseScheduler.php | 1886 ++ .../model/om/BaseCaseSchedulerPeer.php | 685 + .../classes/model/om/BaseCaseTracker.php | 663 + .../model/om/BaseCaseTrackerObject.php | 769 + .../model/om/BaseCaseTrackerObjectPeer.php | 593 + .../classes/model/om/BaseCaseTrackerPeer.php | 592 + .../classes/model/om/BaseConfiguration.php | 796 + .../model/om/BaseConfigurationPeer.php | 602 + .../engine/classes/model/om/BaseContent.php | 738 + .../classes/model/om/BaseContentPeer.php | 593 + .../engine/classes/model/om/BaseDbSource.php | 928 + .../classes/model/om/BaseDbSourcePeer.php | 605 + .../classes/model/om/BaseDepartment.php | 822 + .../classes/model/om/BaseDepartmentPeer.php | 595 + .../classes/model/om/BaseDimTimeComplete.php | 875 + .../model/om/BaseDimTimeCompletePeer.php | 600 + .../classes/model/om/BaseDimTimeDelegate.php | 875 + .../model/om/BaseDimTimeDelegatePeer.php | 600 + .../engine/classes/model/om/BaseDynaform.php | 663 + .../classes/model/om/BaseDynaformPeer.php | 583 + .../engine/classes/model/om/BaseEvent.php | 1234 + .../engine/classes/model/om/BaseEventPeer.php | 635 + .../classes/model/om/BaseFieldCondition.php | 875 + .../model/om/BaseFieldConditionPeer.php | 600 + .../engine/classes/model/om/BaseFields.php | 1087 + .../classes/model/om/BaseFieldsPeer.php | 620 + .../engine/classes/model/om/BaseGroupUser.php | 569 + .../classes/model/om/BaseGroupUserPeer.php | 567 + .../engine/classes/model/om/BaseGroupwf.php | 557 + .../classes/model/om/BaseGroupwfPeer.php | 573 + .../engine/classes/model/om/BaseHoliday.php | 612 + .../classes/model/om/BaseHolidayPeer.php | 577 + .../classes/model/om/BaseInputDocument.php | 875 + .../model/om/BaseInputDocumentPeer.php | 615 + .../classes/model/om/BaseIsoCountry.php | 610 + .../classes/model/om/BaseIsoCountryPeer.php | 575 + .../classes/model/om/BaseIsoLocation.php | 728 + .../classes/model/om/BaseIsoLocationPeer.php | 576 + .../classes/model/om/BaseIsoSubdivision.php | 622 + .../model/om/BaseIsoSubdivisionPeer.php | 566 + .../engine/classes/model/om/BaseLanguage.php | 822 + .../classes/model/om/BaseLanguagePeer.php | 601 + .../engine/classes/model/om/BaseLexico.php | 675 + .../classes/model/om/BaseLexicoPeer.php | 571 + .../model/om/BaseLogCasesScheduler.php | 1003 + .../model/om/BaseLogCasesSchedulerPeer.php | 610 + .../engine/classes/model/om/BaseLoginLog.php | 919 + .../classes/model/om/BaseLoginLogPeer.php | 600 + .../classes/model/om/BaseObjectPermission.php | 1034 + .../model/om/BaseObjectPermissionPeer.php | 645 + .../classes/model/om/BaseOutputDocument.php | 1246 + .../model/om/BaseOutputDocumentPeer.php | 647 + .../engine/classes/model/om/BaseProcess.php | 1708 + .../classes/model/om/BaseProcessCategory.php | 663 + .../model/om/BaseProcessCategoryPeer.php | 580 + .../classes/model/om/BaseProcessOwner.php | 569 + .../classes/model/om/BaseProcessOwnerPeer.php | 561 + .../classes/model/om/BaseProcessPeer.php | 687 + .../classes/model/om/BaseProcessUser.php | 663 + .../classes/model/om/BaseProcessUserPeer.php | 592 + .../classes/model/om/BaseReportTable.php | 897 + .../classes/model/om/BaseReportTablePeer.php | 618 + .../engine/classes/model/om/BaseReportVar.php | 716 + .../classes/model/om/BaseReportVarPeer.php | 597 + .../engine/classes/model/om/BaseRoute.php | 1140 + .../engine/classes/model/om/BaseRoutePeer.php | 649 + .../engine/classes/model/om/BaseSession.php | 822 + .../classes/model/om/BaseSessionPeer.php | 595 + .../classes/model/om/BaseShadowTable.php | 844 + .../classes/model/om/BaseShadowTablePeer.php | 595 + .../engine/classes/model/om/BaseStage.php | 716 + .../engine/classes/model/om/BaseStagePeer.php | 585 + workflow/engine/classes/model/om/BaseStep.php | 875 + .../engine/classes/model/om/BaseStepPeer.php | 603 + .../classes/model/om/BaseStepSupervisor.php | 716 + .../model/om/BaseStepSupervisorPeer.php | 588 + .../classes/model/om/BaseStepTrigger.php | 791 + .../classes/model/om/BaseStepTriggerPeer.php | 598 + .../classes/model/om/BaseSubApplication.php | 994 + .../model/om/BaseSubApplicationPeer.php | 613 + .../classes/model/om/BaseSubProcess.php | 1087 + .../classes/model/om/BaseSubProcessPeer.php | 629 + .../model/om/BaseSwimlanesElements.php | 716 + .../model/om/BaseSwimlanesElementsPeer.php | 594 + workflow/engine/classes/model/om/BaseTask.php | 2241 ++ .../engine/classes/model/om/BaseTaskPeer.php | 787 + .../engine/classes/model/om/BaseTaskUser.php | 685 + .../classes/model/om/BaseTaskUserPeer.php | 597 + .../classes/model/om/BaseTranslation.php | 680 + .../classes/model/om/BaseTranslationPeer.php | 590 + .../engine/classes/model/om/BaseTriggers.php | 716 + .../classes/model/om/BaseTriggersPeer.php | 588 + .../engine/classes/model/om/BaseUsers.php | 1864 ++ .../engine/classes/model/om/BaseUsersPeer.php | 688 + .../classes/model/om/BaseUsersProperties.php | 685 + .../model/om/BaseUsersPropertiesPeer.php | 580 + .../triggers/class.pmSugarFunctions.php | 345 + .../triggers/class.pmTalendFunctions.php | 67 + workflow/engine/config/databases.php | 84 + workflow/engine/config/environments.php | 45 + workflow/engine/config/paths.php | 141 + workflow/engine/config/propel.ini | 44 + workflow/engine/config/propel.mssql.ini | 44 + workflow/engine/config/propel.mysql.ini | 44 + workflow/engine/config/propel.oracle.ini | 44 + workflow/engine/config/propel.pgsql.ini | 45 + workflow/engine/config/properties.ini | 2 + workflow/engine/config/rbac.ini | 44 + workflow/engine/config/schema.xml | 7753 +++++ workflow/engine/content/languages/en.js | 3 + .../translations/english/processmaker.en.po | 27441 ++++++++++++++++ .../translations/pmos-translations.meta | 1 + workflow/engine/data/mssql/schema.sql | 1409 + workflow/engine/data/mssql/sqldb.map | 2 + workflow/engine/data/mysql/create-db.sql | 2 + workflow/engine/data/mysql/insert.sql | 9 + workflow/engine/data/mysql/schema.sql | 1294 + workflow/engine/data/mysql/sqldb.map | 2 + workflow/engine/data/oracle/create-db.sql | 4 + workflow/engine/data/oracle/schema.sql | 769 + workflow/engine/data/oracle/sqldb.map | 2 + workflow/engine/data/pgsql/create-db.sql | 2 + workflow/engine/data/pgsql/sqldb.map | 2 + workflow/engine/gulliver-win.bat | 9 + workflow/engine/includes/inc.JSForms.php | 122 + workflow/engine/includes/inc.application.php | 118 + workflow/engine/includes/inc.dynaForms.php | 224 + .../engine/js/appFolder/core/appFolderList.js | 297 + workflow/engine/js/cases/core/cases.js | 72 + workflow/engine/js/cases/core/cases_Step.js | 1031 + workflow/engine/js/cases/reassignByUser.js | 140 + workflow/engine/js/controls/varsAjax.js | 31 + .../engine/js/dashboard/core/dashboard.js | 61 + workflow/engine/js/dbConnections/main.js | 497 + workflow/engine/js/departments/departments.js | 65 + .../js/dynaformEditor/core/dynaformEditor.js | 567 + .../dynaforms_conditionalShowHide.js | 695 + .../js/dynaforms/dynaforms_fieldsHandler.js | 151 + workflow/engine/js/events/events.js | 254 + workflow/engine/js/groups/groups.js | 64 + workflow/engine/js/processes/main.js | 37 + .../engine/js/processmap/core/images/-1.gif | Bin 0 -> 668 bytes .../engine/js/processmap/core/images/-1b.gif | Bin 0 -> 1061 bytes .../engine/js/processmap/core/images/-1bb.jpg | Bin 0 -> 828 bytes .../engine/js/processmap/core/images/-2.gif | Bin 0 -> 796 bytes .../engine/js/processmap/core/images/0.gif | Bin 0 -> 909 bytes .../engine/js/processmap/core/images/0t.gif | Bin 0 -> 13154 bytes .../engine/js/processmap/core/images/1.gif | Bin 0 -> 378 bytes .../engine/js/processmap/core/images/1t.gif | Bin 0 -> 742 bytes .../engine/js/processmap/core/images/2.gif | Bin 0 -> 187 bytes .../engine/js/processmap/core/images/2t.gif | Bin 0 -> 13385 bytes .../engine/js/processmap/core/images/3.gif | Bin 0 -> 90 bytes .../engine/js/processmap/core/images/3t.gif | Bin 0 -> 13456 bytes .../engine/js/processmap/core/images/4.gif | Bin 0 -> 189 bytes .../engine/js/processmap/core/images/4t.gif | Bin 0 -> 13545 bytes .../engine/js/processmap/core/images/5.gif | Bin 0 -> 85 bytes .../engine/js/processmap/core/images/5t.gif | Bin 0 -> 374 bytes .../engine/js/processmap/core/images/6.gif | Bin 0 -> 1057 bytes .../engine/js/processmap/core/images/7.gif | Bin 0 -> 616 bytes .../js/processmap/core/images/arrowB.gif | Bin 0 -> 13123 bytes .../js/processmap/core/images/bg_pm.gif | Bin 0 -> 13253 bytes .../js/processmap/core/images/bg_pm.png | Bin 0 -> 47393 bytes .../js/processmap/core/images/bg_task.gif | Bin 0 -> 550 bytes .../js/processmap/core/images/bg_task2.gif | Bin 0 -> 13952 bytes .../js/processmap/core/images/cancel.gif | Bin 0 -> 612 bytes .../js/processmap/core/images/inicio.gif | Bin 0 -> 722 bytes .../js/processmap/core/images/loader_B.gif | Bin 0 -> 4178 bytes .../engine/js/processmap/core/images/mail.gif | Bin 0 -> 597 bytes .../js/processmap/core/images/parar.gif | Bin 0 -> 383 bytes .../js/processmap/core/images/proceso.gif | Bin 0 -> 364 bytes .../js/processmap/core/images/puntito.gif | Bin 0 -> 994 bytes .../engine/js/processmap/core/processUser.js | 23 + .../js/processmap/core/processes_Map.js | 211 + .../engine/js/processmap/core/processmap.js | 2592 ++ workflow/engine/js/reports/reports.js | 42 + workflow/engine/js/setup/pluginList.js | 45 + workflow/engine/js/setup/upgrade_System.js | 25 + .../engine/js/stagesmap/core/stagesmap.js | 508 + workflow/engine/js/tracker/tracker.js | 89 + workflow/engine/menus/admin.php | 28 + workflow/engine/menus/appFolder.php | 5 + workflow/engine/menus/backApp.php | 42 + workflow/engine/menus/cancel.php | 47 + workflow/engine/menus/caseOptions.php | 49 + workflow/engine/menus/caseTracker.php | 76 + workflow/engine/menus/cases.php | 77 + workflow/engine/menus/process.php | 28 + workflow/engine/menus/processes.php | 52 + workflow/engine/menus/processmaker.php | 60 + workflow/engine/menus/rbac.appEdit.php | 64 + workflow/engine/menus/rbac.appView.php | 57 + workflow/engine/menus/rbac.application.php | 34 + workflow/engine/menus/rbac.authSource.php | 33 + workflow/engine/menus/rbac.authentication.php | 33 + workflow/engine/menus/rbac.permission.php | 48 + workflow/engine/menus/rbac.php | 66 + workflow/engine/menus/rbac.role.php | 65 + workflow/engine/menus/rbac.user.php | 52 + workflow/engine/menus/rbac.userEdit.php | 69 + workflow/engine/menus/rbac.userView.php | 85 + workflow/engine/menus/setup.php | 61 + workflow/engine/menus/tools.php | 29 + workflow/engine/menus/toolsTranslations.php | 31 + workflow/engine/menus/users.php | 46 + workflow/engine/menus/wf.login.php | 57 + .../additionalTables/additionalTablesAjax.php | 275 + .../additionalTables/additionalTablesData.php | 67 + .../additionalTablesDataDelete.php | 40 + .../additionalTablesDataEdit.php | 46 + .../additionalTablesDataImport.php | 63 + .../additionalTablesDataImportForm.php | 43 + .../additionalTablesDataNew.php | 43 + .../additionalTablesDelete.php | 42 + .../additionalTablesDoImport.php | 203 + .../additionalTables/additionalTablesEdit.php | 109 + .../additionalTables/additionalTablesList.php | 47 + .../additionalTables/additionalTablesNew.php | 39 + .../additionalTables/additionalTablesSave.php | 198 + .../additionalTablesSaveData.php | 34 + .../additionalTablesToImport.php | 59 + .../additionalTablesUpdateData.php | 32 + .../methods/additionalTables/doExport.php | 37 + .../methods/appFolder/appFolderAjax.php | 305 + .../methods/appFolder/appFolderDelete.php | 38 + .../methods/appFolder/appFolderDeleteExec.php | 25 + .../methods/appFolder/appFolderEdit.php | 30 + .../methods/appFolder/appFolderList.php | 59 + .../engine/methods/appFolder/appFolderNew.php | 23 + .../methods/appFolder/appFolderSave.php | 53 + .../appFolder/appFolderSaveDocument.php | 165 + .../methods/authSources/authSources_Ajax.php | 102 + .../authSources/authSources_Delete.php | 32 + .../methods/authSources/authSources_Edit.php | 69 + .../authSources/authSources_ImportUsers.php | 73 + .../methods/authSources/authSources_List.php | 40 + .../methods/authSources/authSources_New.php | 51 + .../methods/authSources/authSources_Save.php | 65 + .../authSources/authSources_SearchUsers.php | 39 + .../authSources/authSources_SelectType.php | 53 + workflow/engine/methods/cases/casesDemo.php | 169 + .../engine/methods/cases/casesListExtJs.php | 762 + .../engine/methods/cases/casesMenuLoader.php | 205 + .../engine/methods/cases/casesStartPage.php | 11 + .../methods/cases/casesStartPage_Ajax.php | 268 + .../methods/cases/casesToRevisePanelExtJs.php | 15 + .../cases/casesToReviseTreeContent.php | 102 + workflow/engine/methods/cases/cases_Ajax.php | 839 + .../methods/cases/cases_CatchExecute.php | 68 + .../methods/cases/cases_CatchSelfService.php | 104 + .../engine/methods/cases/cases_Delete.php | 60 + .../methods/cases/cases_DeleteDocument.php | 63 + .../engine/methods/cases/cases_Derivate.php | 159 + workflow/engine/methods/cases/cases_List.php | 187 + workflow/engine/methods/cases/cases_New.php | 162 + .../engine/methods/cases/cases_NextStep.php | 32 + workflow/engine/methods/cases/cases_Open.php | 166 + .../methods/cases/cases_OpenToRevise.php | 79 + .../engine/methods/cases/cases_PrintView.php | 113 + .../engine/methods/cases/cases_Reassign.php | 121 + .../methods/cases/cases_ReassignByUser.php | 166 + .../methods/cases/cases_Reassign_save.php | 79 + .../engine/methods/cases/cases_Redirect.php | 41 + .../engine/methods/cases/cases_Resume.php | 108 + workflow/engine/methods/cases/cases_Save.php | 76 + .../engine/methods/cases/cases_SaveData.php | 233 + .../cases/cases_SaveDataSupervisor.php | 52 + .../methods/cases/cases_SaveDocument.php | 287 + .../cases/cases_SchedulerGetPlugins.php | 71 + .../cases/cases_SchedulerGetProcesses.php | 38 + .../methods/cases/cases_SchedulerGetTasks.php | 25 + .../cases/cases_SchedulerValidateUser.php | 73 + .../cases/cases_Scheduler_ChangeStatus.php | 56 + .../methods/cases/cases_Scheduler_Delete.php | 53 + .../methods/cases/cases_Scheduler_Edit.php | 138 + .../methods/cases/cases_Scheduler_List.php | 171 + .../methods/cases/cases_Scheduler_Log.php | 70 + .../cases/cases_Scheduler_Log_Detail.php | 94 + .../methods/cases/cases_Scheduler_New.php | 101 + .../methods/cases/cases_Scheduler_Save.php | 238 + .../methods/cases/cases_Scheduler_Update.php | 273 + .../methods/cases/cases_ShowDocument.php | 65 + .../cases/cases_ShowOutputDocument.php | 53 + .../cases_ShowToReviseOutputDocument.php | 66 + workflow/engine/methods/cases/cases_Step.php | 875 + .../methods/cases/cases_StepToRevise.php | 184 + .../cases/cases_StepToReviseInputs.php | 199 + .../cases/cases_StepToReviseOutputs.php | 130 + .../cases/cases_SupervisorSaveDocument.php | 86 + .../cases/cases_ToReviseInputDocView.php | 82 + .../cases/cases_ToReviseOutputDocView.php | 143 + .../methods/cases/cases_UsersReassign.php | 75 + .../methods/cases/cases_advancedSearch.php | 85 + .../methods/cases/cases_generatePMTable.php | 110 + .../engine/methods/cases/cases_toRevise.php | 29 + .../engine/methods/cases/debug_triggers.php | 72 + workflow/engine/methods/cases/debug_vars.php | 97 + workflow/engine/methods/cases/index.php | 29 + workflow/engine/methods/cases/main.php | 34 + workflow/engine/methods/cases/main_init.php | 63 + .../engine/methods/cases/proxyCasesList.php | 600 + .../engine/methods/cases/proxyProcessList.php | 67 + .../methods/cases/proxyReassignCasesList.php | 143 + .../methods/cases/proxyReassignUsersList.php | 77 + .../cases/proxySaveReassignCasesList.php | 131 + workflow/engine/methods/controls/buscador.php | 50 + .../engine/methods/controls/buscador2.php | 38 + workflow/engine/methods/controls/calendar.js | 162 + workflow/engine/methods/controls/calendar.php | 185 + workflow/engine/methods/controls/img/cal.gif | Bin 0 -> 127 bytes workflow/engine/methods/controls/img/logo.gif | Bin 0 -> 660 bytes workflow/engine/methods/controls/img/next.gif | Bin 0 -> 214 bytes .../engine/methods/controls/img/next_year.gif | Bin 0 -> 256 bytes .../engine/methods/controls/img/pixel.gif | Bin 0 -> 67 bytes workflow/engine/methods/controls/img/prev.gif | Bin 0 -> 212 bytes .../engine/methods/controls/img/prev_year.gif | Bin 0 -> 259 bytes workflow/engine/methods/controls/img/tc.gif | Bin 0 -> 8301 bytes workflow/engine/methods/controls/varsAjax.php | 162 + .../methods/controls/varsAjaxByType.php | 109 + .../engine/methods/dashboard/dashboard.php | 76 + .../methods/dashboard/dashboardAjax.php | 168 + .../methods/dbConnections/dbConnections.php | 77 + .../dbConnections/dbConnectionsAjax.php | 290 + .../dbConnections/genericDbConnections.php | 20 + .../dbConnections/rootDbConnections.php | 21 + .../methods/departments/departments.php | 362 + .../departments/departments_AddManager.php | 61 + .../departments/departments_AddUser.php | 56 + .../methods/departments/departments_Ajax.php | 114 + .../departments/departments_Delete.php | 58 + .../methods/departments/departments_Edit.php | 64 + .../methods/departments/departments_List.php | 53 + .../methods/departments/departments_New.php | 65 + .../methods/departments/departments_Save.php | 42 + .../methods/departments/subdep_Delete.php | 44 + .../methods/departments/subdep_Edit.php | 71 + .../methods/departments/subdep_Save.php | 68 + .../methods/dynaforms/conditionalShowHide.php | 96 + .../dynaforms/conditionalShowHide_Ajax.php | 205 + .../engine/methods/dynaforms/datemask.php | 41 + .../methods/dynaforms/dynaform_Fields.php | 60 + .../methods/dynaforms/dynaforms_Ajax.php | 229 + .../dynaforms/dynaforms_AssignVariables.php | 28 + .../methods/dynaforms/dynaforms_ChoseType.php | 9 + .../methods/dynaforms/dynaforms_Delete.php | 84 + .../methods/dynaforms/dynaforms_Edit.php | 74 + .../methods/dynaforms/dynaforms_Editor.php | 85 + .../dynaforms/dynaforms_FlatEditor.php | 240 + .../methods/dynaforms/dynaforms_List.php | 46 + .../methods/dynaforms/dynaforms_NewPlugin.php | 67 + .../dynaforms/dynaforms_PagedTableAjax.php | 125 + .../methods/dynaforms/dynaforms_Preview.php | 66 + .../methods/dynaforms/dynaforms_Save.php | 82 + .../dynaforms/dynaforms_SaveProperties.php | 55 + .../methods/dynaforms/dynaforms_Save_as.php | 109 + .../methods/dynaforms/dynaforms_Saveas.php | 44 + .../dynaforms/dynaforms_ToolbarAjax.php | 34 + .../dynaforms_checkDependentFields.php | 134 + .../methods/dynaforms/fieldsGetterAjax.php | 110 + .../methods/dynaforms/fieldsHandler.php | 32 + .../methods/dynaforms/fieldsHandlerAjax.php | 113 + .../methods/dynaforms/fieldsHandlerViewer.php | 36 + .../engine/methods/dynaforms/fields_Ajax.php | 110 + .../methods/dynaforms/fields_Delete.php | 64 + .../engine/methods/dynaforms/fields_Edit.php | 182 + .../engine/methods/dynaforms/fields_List.php | 55 + .../engine/methods/dynaforms/fields_Order.php | 99 + .../engine/methods/dynaforms/fields_Save.php | 196 + workflow/engine/methods/dynaforms/test.php | 58 + workflow/engine/methods/events/eventsAjax.php | 112 + .../engine/methods/events/eventsCompleted.php | 38 + .../engine/methods/events/eventsDelete.php | 35 + workflow/engine/methods/events/eventsEdit.php | 79 + .../methods/events/eventsEditAction.php | 249 + workflow/engine/methods/events/eventsNew.php | 68 + .../engine/methods/events/eventsNewAction.php | 83 + .../engine/methods/events/eventsPending.php | 38 + workflow/engine/methods/events/eventsSave.php | 77 + .../methods/events/eventsSetupGraph.php | 211 + .../engine/methods/events/triggersSave.php | 40 + workflow/engine/methods/groups/groups.php | 188 + .../engine/methods/groups/groups_AddUser.php | 57 + .../engine/methods/groups/groups_Ajax.php | 97 + .../engine/methods/groups/groups_Delete.php | 64 + .../engine/methods/groups/groups_Edit.php | 70 + .../engine/methods/groups/groups_List.php | 55 + .../engine/methods/groups/groups_Save.php | 69 + .../methods/groups/groups_SaveAddUser.php | 29 + .../methods/inputdocs/inputdocs_Delete.php | 91 + .../methods/inputdocs/inputdocs_Edit.php | 58 + .../methods/inputdocs/inputdocs_List.php | 43 + .../methods/inputdocs/inputdocs_Save.php | 99 + .../methods/install/autoinstallPlugins.php | 82 + .../methods/install/autoinstallProcesses.php | 58 + .../methods/install/heartbeatStatus.php | 24 + workflow/engine/methods/install/install.js | 676 + workflow/engine/methods/install/install.php | 203 + .../engine/methods/install/installServer.php | 295 + workflow/engine/methods/install/newSite.php | 96 + workflow/engine/methods/install/r.php | 8 + .../engine/methods/login/authentication.php | 263 + .../engine/methods/login/changePassword.php | 86 + workflow/engine/methods/login/dbInfo.php | 126 + workflow/engine/methods/login/index.php | 28 + workflow/engine/methods/login/login.php | 148 + workflow/engine/methods/login/login_Ajax.php | 50 + workflow/engine/methods/login/noViewPage.php | 36 + workflow/engine/methods/login/sysLogin.php | 162 + .../engine/methods/login/sysLoginVerify.php | 31 + .../methods/messages/messages_Delete.php | 40 + .../engine/methods/messages/messages_Edit.php | 43 + .../engine/methods/messages/messages_List.php | 47 + .../engine/methods/messages/messages_Save.php | 39 + .../methods/outputdocs/downloadFile.php | 15 + .../methods/outputdocs/outputdocs_Ajax.php | 39 + .../methods/outputdocs/outputdocs_Delete.php | 62 + .../methods/outputdocs/outputdocs_Edit.php | 103 + .../methods/outputdocs/outputdocs_List.php | 45 + .../methods/outputdocs/outputdocs_New.php | 82 + .../outputdocs/outputdocs_Properties.php | 82 + .../methods/outputdocs/outputdocs_Save.php | 110 + .../engine/methods/outputdocs/uploadFile.php | 32 + .../engine/methods/patterns/patterns_Ajax.php | 123 + .../processCategory/processCategoryAjax.php | 47 + .../processCategory/processCategoryDelete.php | 41 + .../processCategoryDeleteExec.php | 46 + .../processCategory/processCategoryEdit.php | 35 + .../processCategory/processCategoryList.php | 40 + .../processCategory/processCategoryNew.php | 27 + .../processCategory/processCategorySave.php | 59 + .../engine/methods/processes/clases_Test.php | 163 + .../engine/methods/processes/downloadPML.php | 72 + .../processes/downloadPML_ImportExisting.php | 100 + workflow/engine/methods/processes/index.php | 28 + workflow/engine/methods/processes/main.php | 58 + .../engine/methods/processes/mainAjax.php | 19 + .../engine/methods/processes/mainInit.php | 44 + .../methods/processes/process_DeleteCases.php | 68 + .../methods/processes/processesList.php | 51 + .../methods/processes/processes_Ajax.php | 473 + .../processes/processes_ChangeStatus.php | 48 + .../methods/processes/processes_Delete.php | 62 + .../processes_DeleteObjectPermission.php | 54 + .../processes/processes_DownloadFile.php | 37 + .../methods/processes/processes_Export.php | 54 + .../methods/processes/processes_GetFile.php | 15 + .../methods/processes/processes_Import.php | 65 + .../processes/processes_ImportExisting.php | 132 + .../processes/processes_ImportFile.php | 112 + .../methods/processes/processes_Library.php | 138 + .../methods/processes/processes_List.php | 73 + .../methods/processes/processes_Map.php | 92 + .../methods/processes/processes_New.php | 63 + .../methods/processes/processes_Save.php | 90 + .../processes_SaveEditObjectPermission.php | 84 + .../processes_SaveObjectPermission.php | 83 + .../processes/processes_UploadFiles.php | 18 + .../processes/processes_UploadFilesForm.php | 56 + .../methods/processes/processes_User.php | 59 + .../processes_availableProcessesUser.php | 55 + .../processes/processes_checkProperties.php | 90 + .../methods/processes/processes_doUpload.php | 29 + .../processes/processes_subProcessSave.php | 102 + .../processes/processes_webEntryGenerate.php | 150 + .../processes/processes_webEntryValidate.php | 96 + .../methods/processes/webEntry_Val_Assig.php | 32 + .../reportTables/reportTables_Ajax.php | 41 + .../reportTables/reportTables_Delete.php | 29 + .../reportTables/reportTables_Edit.php | 72 + .../reportTables/reportTables_Save.php | 94 + .../engine/methods/reports/reportsList.php | 144 + .../methods/reports/reports_Dashboard.php | 62 + .../methods/reports/reports_Description.php | 70 + .../methods/reports/reports_Duration.php | 98 + .../engine/methods/reports/reports_View.php | 278 + workflow/engine/methods/roles/roles_Ajax.php | 226 + workflow/engine/methods/roles/roles_List.php | 77 + .../engine/methods/services/ColosaSchema.xsd | 821 + .../methods/services/cases_StartExternal.php | 66 + workflow/engine/methods/services/demoSoap.php | 258 + .../methods/services/login_getStarted.php | 37 + workflow/engine/methods/services/pmos.wsdl | 733 + workflow/engine/methods/services/pmos2.wsdl | 1192 + .../services/processHeartBeat_Ajax.php | 213 + workflow/engine/methods/services/soap.php | 449 + workflow/engine/methods/services/soap2.php | 821 + workflow/engine/methods/services/upload.php | 126 + workflow/engine/methods/services/webdav.php | 51 + workflow/engine/methods/services/wsdl.php | 14 + workflow/engine/methods/services/wsdl2.php | 15 + workflow/engine/methods/services/wso2.php | 104 + workflow/engine/methods/services/xpdl.php | 184 + .../engine/methods/setup/appCacheViewAjax.php | 218 + .../engine/methods/setup/appCacheViewConf.php | 31 + workflow/engine/methods/setup/appearance.php | 45 + .../engine/methods/setup/calendarDelete.php | 20 + .../engine/methods/setup/calendarEdit.php | 58 + .../engine/methods/setup/calendarList.php | 57 + .../engine/methods/setup/calendarSave.php | 54 + .../engine/methods/setup/clearCompiled.php | 44 + .../engine/methods/setup/connectionDB.php | 32 + .../engine/methods/setup/connectionWS.php | 32 + .../engine/methods/setup/customFunctions.php | 33 + workflow/engine/methods/setup/debug.php | 40 + .../engine/methods/setup/emailSystemCron.php | 43 + .../engine/methods/setup/emailSystemSpool.php | 68 + .../engine/methods/setup/emailSystemTest.php | 55 + workflow/engine/methods/setup/emails.php | 74 + workflow/engine/methods/setup/emails_Ajax.php | 347 + workflow/engine/methods/setup/emails_Save.php | 46 + .../methods/setup/environmentSettings.php | 30 + .../methods/setup/environmentSettingsAjax.php | 56 + workflow/engine/methods/setup/holiday.php | 35 + workflow/engine/methods/setup/holidayNew.php | 36 + workflow/engine/methods/setup/index.php | 28 + workflow/engine/methods/setup/jasper.php | 139 + workflow/engine/methods/setup/language.php | 58 + .../engine/methods/setup/language_Ajax.php | 170 + workflow/engine/methods/setup/languages.php | 39 + .../engine/methods/setup/languages_Delete.php | 73 + .../engine/methods/setup/languages_Export.php | 288 + .../engine/methods/setup/languages_Import.php | 85 + .../methods/setup/languages_ImportForm.php | 66 + workflow/engine/methods/setup/location.php | 162 + workflow/engine/methods/setup/logo_Delete.php | 51 + workflow/engine/methods/setup/main.php | 40 + workflow/engine/methods/setup/mainAjax.php | 64 + workflow/engine/methods/setup/main_init.php | 71 + .../engine/methods/setup/pluginsChange.php | 62 + .../engine/methods/setup/pluginsImport.php | 78 + .../methods/setup/pluginsImportFile.php | 143 + workflow/engine/methods/setup/pluginsList.php | 125 + workflow/engine/methods/setup/pluginsMain.php | 41 + .../engine/methods/setup/pluginsRemove.php | 102 + .../engine/methods/setup/pluginsSetup.php | 58 + .../engine/methods/setup/pluginsSetupSave.php | 48 + .../methods/setup/processHeartBeatConfig.php | 61 + .../methods/setup/processHeartBeatSave.php | 35 + .../engine/methods/setup/replacementLogo.php | 84 + workflow/engine/methods/setup/setup.js | 73 + workflow/engine/methods/setup/setup.php | 87 + workflow/engine/methods/setup/setupAjax.php | 41 + .../setup/setupSchemas/app_cache_view.sql | 38 + .../setupSchemas/app_cache_view_insert.sql | 50 + .../triggerAppDelegationInsert.sql | 110 + .../triggerAppDelegationUpdate.sql | 75 + .../setupSchemas/triggerApplicationDelete.sql | 4 + .../setupSchemas/triggerApplicationUpdate.sql | 16 + .../engine/methods/setup/showLogoFile.php | 44 + workflow/engine/methods/setup/skinsExport.php | 191 + workflow/engine/methods/setup/skinsList.php | 121 + workflow/engine/methods/setup/skinsNew.php | 58 + workflow/engine/methods/setup/skinsSave.php | 102 + workflow/engine/methods/setup/upgrade.php | 81 + .../engine/methods/setup/upgrade_RBAC.php | 42 + .../engine/methods/setup/upgrade_System.php | 110 + .../methods/setup/upgrade_SystemAjax.php | 389 + workflow/engine/methods/setup/uplogo.php | 117 + workflow/engine/methods/setup/webServices.php | 161 + .../engine/methods/setup/webServicesAjax.php | 1238 + .../engine/methods/setup/webServicesList.php | 36 + .../engine/methods/setup/webServicesSetup.php | 63 + .../methods/setup/webServicesSetupSave.php | 22 + workflow/engine/methods/setup/weekend.php | 93 + workflow/engine/methods/setup/weekendAjax.php | 70 + workflow/engine/methods/setup/workPeriod.js | 20 + workflow/engine/methods/setup/workPeriod.php | 49 + .../engine/methods/setup/workPeriodGraph.php | 102 + .../engine/methods/setup/workPeriodSave.php | 43 + .../engine/methods/steps/conditions_Edit.php | 50 + .../engine/methods/steps/conditions_Save.php | 49 + workflow/engine/methods/steps/steps_Ajax.php | 182 + .../engine/methods/steps/steps_Delete.php | 51 + workflow/engine/methods/steps/steps_Down.php | 50 + workflow/engine/methods/steps/steps_New.php | 49 + workflow/engine/methods/steps/steps_Save.php | 54 + .../methods/steps/steps_SupervisorAjax.php | 70 + workflow/engine/methods/steps/steps_Up.php | 50 + workflow/engine/methods/tasks/tasks_Ajax.php | 88 + workflow/engine/methods/tools/dvServices.php | 83 + workflow/engine/methods/tools/index.php | 29 + .../methods/tools/methodsPermissions.php | 31 + .../methods/tools/methodsPermissions_Ajax.php | 287 + .../engine/methods/tools/translations.php | 45 + .../engine/methods/tools/translationsAdd.php | 38 + .../engine/methods/tools/translationsAjax.php | 217 + .../methods/tools/translationsDelete.php | 43 + .../engine/methods/tools/translationsEdit.php | 60 + .../engine/methods/tools/translationsSave.php | 36 + .../methods/tools/updateTranslation.php | 43 + .../engine/methods/tracker/authentication.php | 130 + workflow/engine/methods/tracker/login.php | 45 + .../engine/methods/tracker/tracker_Ajax.php | 427 + .../tracker/tracker_ConditionsEdit.php | 54 + .../tracker/tracker_ConditionsSave.php | 52 + .../methods/tracker/tracker_DynaDocs.php | 61 + .../methods/tracker/tracker_History.php | 55 + .../methods/tracker/tracker_Messages.php | 56 + .../methods/tracker/tracker_MessagesView.php | 45 + .../engine/methods/tracker/tracker_No.php | 45 + .../engine/methods/tracker/tracker_Save.php | 11 + .../engine/methods/tracker/tracker_Show.php | 89 + .../methods/tracker/tracker_ShowDocument.php | 47 + .../tracker/tracker_ShowOutputDocument.php | 57 + .../methods/tracker/tracker_ViewMap.php | 123 + .../methods/triggers/triggersProperties.php | 44 + .../engine/methods/triggers/triggersTree.php | 43 + .../engine/methods/triggers/triggers_Ajax.php | 88 + .../triggers/triggers_CreateWizard.php | 92 + .../methods/triggers/triggers_Delete.php | 43 + .../engine/methods/triggers/triggers_Edit.php | 73 + .../methods/triggers/triggers_EditCustom.php | 40 + .../methods/triggers/triggers_EditWizard.php | 95 + .../engine/methods/triggers/triggers_Save.php | 81 + .../methods/triggers/triggers_WizardSave.php | 95 + .../triggers/triggers_WizardUpdate.php | 100 + workflow/engine/methods/users/index.php | 28 + workflow/engine/methods/users/myInfo.php | 178 + workflow/engine/methods/users/myInfo_Ajax.php | 32 + workflow/engine/methods/users/myInfo_Edit.php | 168 + workflow/engine/methods/users/myInfo_Save.php | 171 + workflow/engine/methods/users/users_Ajax.php | 158 + .../engine/methods/users/users_AuthSource.php | 39 + .../methods/users/users_AuthSourceSave.php | 46 + .../engine/methods/users/users_Delete.php | 73 + .../methods/users/users_DeleteAssign.php | 49 + .../methods/users/users_DeleteReassign.php | 164 + .../methods/users/users_DeleteReassignEnd.php | 90 + workflow/engine/methods/users/users_Edit.php | 144 + .../engine/methods/users/users_Groups.php | 55 + workflow/engine/methods/users/users_List.php | 80 + workflow/engine/methods/users/users_New.php | 102 + .../engine/methods/users/users_Reassign.php | 49 + .../methods/users/users_ReassignCases.php | 119 + workflow/engine/methods/users/users_Save.php | 286 + workflow/engine/methods/users/users_View.php | 81 + .../engine/methods/users/users_ViewPhoto.php | 100 + .../engine/methods/users/users_ViewResume.php | 106 + workflow/engine/plugins/charts.php | 35 + .../engine/plugins/charts/class.charts.php | 106 + .../engine/plugins/charts/config/setup.conf | 1 + .../engine/plugins/charts/genericCharts.php | 60 + workflow/engine/plugins/charts/setupPage.xml | 20 + workflow/engine/plugins/openFlash.php | 36 + .../engine/plugins/openFlash/chart-data.php | 14 + workflow/engine/plugins/openFlash/chart.php | 11 + .../plugins/openFlash/class.openFlash.php | 428 + .../plugins/openFlash/open-flash-chart.php | 1769 + .../openFlash/open_flash_chart_object.php | 109 + .../public_html/open-flash-chart.swf | Bin 0 -> 64600 bytes .../openFlash/public_html/swfobject.js | 233 + .../engine/plugins/openFlash/setupPage.xml | 20 + workflow/engine/plugins/pmosCommunity.php | 36 + .../plugins/pmosCommunity/chart-data.php | 14 + .../engine/plugins/pmosCommunity/chart.php | 11 + .../pmosCommunity/class.pmosCommunity.php | 477 + .../pmosCommunity/config/databases.php | 9 + .../plugins/pmosCommunity/config/setup.conf | 1 + .../plugins/pmosCommunity/drawChart.php | 14 + .../pmosCommunity/open-flash-chart.php | 1769 + .../pmosCommunity/open_flash_chart_object.php | 109 + .../public_html/open-flash-chart.swf | Bin 0 -> 64600 bytes .../pmosCommunity/public_html/swfobject.js | 233 + .../plugins/pmosCommunity/setupPage.xml | 20 + workflow/engine/plugins/processTemplate.php | 69 + .../processTemplate/class.processTemplate.php | 195 + workflow/engine/skins/blank.html | 30 + workflow/engine/skins/blank.php | 47 + workflow/engine/skins/extJs.html | 10 + workflow/engine/skins/extJs.php | 60 + workflow/engine/skins/extJsInitLoad.html | 68 + workflow/engine/skins/green-submenu.html | 49 + workflow/engine/skins/green-submenu.php | 95 + workflow/engine/skins/green.html | 79 + workflow/engine/skins/green.php | 135 + workflow/engine/skins/iphone.html | 102 + workflow/engine/skins/iphone.php | 61 + workflow/engine/skins/raw.html | 16 + workflow/engine/skins/raw.php | 24 + workflow/engine/skins/rtl.cnf | 1 + workflow/engine/skins/rtl.html | 72 + workflow/engine/skins/rtl.php | 91 + workflow/engine/skins/tracker.html | 64 + workflow/engine/skins/tracker.php | 75 + .../templates/additionalTables/Table.tpl | 19 + .../templates/additionalTables/TablePeer.tpl | 23 + .../additionalTables/map/TableMapBuilder.tpl | 78 + .../additionalTables/om/BaseTable.tpl | 530 + .../additionalTables/om/BaseTablePeer.tpl | 584 + .../additionalTables/paged-table.html | 222 + .../additionalTables/paged-table2.html | 137 + .../appFolder/appFolderFileList.html | 1 + .../templates/appFolder/appFolderTree.php | 118 + workflow/engine/templates/authListUsers.html | 71 + .../engine/templates/cases/casesDemo.html | 562 + workflow/engine/templates/cases/casesList.js | 1543 + .../templates/cases/casesListExtJs.html | 4 + .../templates/cases/casesStartPage.html | 47 + .../engine/templates/cases/casesStartPage.js | 1278 + .../templates/cases/casesToRevisePanel.html | 2 + .../templates/cases/casesToRevisePanel.js | 42 + .../templates/cases/cases_ActionsTree.php | 103 + .../cases/cases_DynaformHistory.html | 116 + .../templates/cases/cases_DynaformHistory.php | 167 + .../templates/cases/cases_InformationTree.php | 91 + .../engine/templates/cases/cases_KTTree.php | 36 + .../engine/templates/cases/cases_Leyends.html | 8 + .../engine/templates/cases/cases_Load.php | 28 + .../templates/cases/cases_NewCategory.html | 77 + .../templates/cases/cases_NewCategory.php | 34 + .../templates/cases/cases_PrintViewTitle.html | 9 + .../templates/cases/cases_Reassign.html | 58 + .../cases/cases_ScreenDerivation.html | 164 + .../engine/templates/cases/cases_Step.html | 1 + .../templates/cases/cases_StepsTree.php | 241 + .../cases/cases_UsersReassignCases.html | 41 + .../engine/templates/cases/cases_title.html | 5 + .../engine/templates/cases/cases_toRevise.php | 151 + .../templates/cases/cases_toReviseIn.html | 1 + .../cases/css/extjs-extend/xtheme-gray.css | 386 + workflow/engine/templates/cases/main.html | 7 + workflow/engine/templates/cases/main.js | 701 + .../templates/cases/missRequiredFields.php | 82 + .../cases/paged-table-inputDocuments.html | 186 + .../cases/paged-table-reassigByUser.html | 157 + .../cases/paged-table-reassigByUser2.html | 158 + .../templates/cases/paged-table-reassign.html | 164 + .../engine/templates/cases/reassignList.js | 77 + .../engine/templates/cases/showDebugFrame.php | 261 + .../templates/cases/showDebugFrameBreaker.php | 4 + .../templates/cases/showDebugFrameLoader.php | 12 + workflow/engine/templates/cases/showStep.html | 2 + .../engine/templates/dashboard/frontend.html | 35 + .../templates/dbConnections/dbConnections.php | 113 + .../departments/departments_Tree.html | 91 + .../departments/departments_Tree.php | 101 + .../departments/departments_userList.html | 1 + .../templates/departments/paged-table.html | 201 + .../templates/departments/paged-table2.html | 138 + .../templates/departments/paged-table3.html | 201 + workflow/engine/templates/dummyTemplate.html | 1 + .../templates/dynaforms/fieldsHandler.php | 218 + .../dynaforms/fieldsHandlerViewer.php | 112 + .../engine/templates/events/sendMessage.tpl | 21 + workflow/engine/templates/filterform.html | 129 + workflow/engine/templates/form.html | 152 + workflow/engine/templates/grid.html | 113 + workflow/engine/templates/grid_preview.html | 114 + workflow/engine/templates/grid_view.html | 108 + .../engine/templates/groups/groups_Tree.php | 97 + .../templates/groups/groups_usersList.html | 1 + .../engine/templates/groups/paged-table.html | 201 + .../engine/templates/groups/paged-table2.html | 138 + workflow/engine/templates/image.php | 35 + .../engine/templates/javaBridgePM/classic.xml | 104 + .../engine/templates/javaBridgePM/out.jrxml | 262 + workflow/engine/templates/login/init.js | 14 + .../engine/templates/login/showDBFiles.php | 113 + .../engine/templates/mails/alert_message.html | 16 + .../engine/templates/outputdocs/editJrxml.php | 5 + .../engine/templates/outputdocs/htmlEditor.js | 164 + .../methods/packCreator_Delete.php | 39 + .../packCreator/methods/packCreator_Edit.php | 42 + .../packCreator/methods/packCreator_List.php | 46 + .../packCreator/methods/packCreator_Save.php | 38 + .../packCreator/xmlforms/packCreator_Edit.xml | 24 + .../packCreator/xmlforms/packCreator_List.xml | 37 + .../xmlforms/packCreator_Options.xml | 36 + workflow/engine/templates/paged-table.html | 143 + workflow/engine/templates/popupMenu.html | 49 + workflow/engine/templates/processes/main.html | 2 + workflow/engine/templates/processes/main.js | 476 + .../engine/templates/processes/mainLoad.php | 42 + .../templates/processes/processes_Map.html | 2 + .../templates/processes/processes_Upload.php | 141 + .../engine/templates/processes/webentry.tpl | 43 + .../templates/processes/webentryPost.tpl | 80 + workflow/engine/templates/publish-raw.php | 60 + .../engine/templates/publish-treeview.php | 74 + .../engine/templates/publish-twocolumns.php | 81 + workflow/engine/templates/publish.php | 100 + workflow/engine/templates/publishBlank.php | 105 + .../roles/roles_AssignPermissions.php | 79 + .../templates/roles/roles_AssignRole.php | 80 + .../engine/templates/roles/roles_Tree.php | 86 + .../templates/roles/roles_permissionsTree.php | 85 + .../templates/services/login_getStarted.html | 66 + .../templates/setup/appCacheViewConf.html | 5 + .../templates/setup/appCacheViewConf.js | 219 + .../templates/setup/clearCompiledResult.php | 16 + .../setup/css/extjs-extend/xtheme-gray.css | 148 + .../templates/setup/environmentSettings.js | 310 + .../engine/templates/setup/languages.html | 3 + workflow/engine/templates/setup/languages.js | 381 + .../templates/setup/mailConnectiontest.php | 104 + workflow/engine/templates/setup/main.html | 24 + workflow/engine/templates/setup/main.js | 97 + workflow/engine/templates/setup/main_Load.php | 25 + .../engine/templates/setup/pluginsMain.js | 316 + workflow/engine/templates/setup/tools.html | 76 + workflow/engine/templates/setup/uplogo.html | 36 + workflow/engine/templates/setup/uplogo.php | 127 + .../templates/setup/webServicesTree.php | 133 + .../engine/templates/steps/triggers_Tree.php | 116 + .../templates/testAuthenticationSource.html | 17 + .../templates/testAuthenticationUser.php | 66 + workflow/engine/templates/toolbar.html | 32 + .../templates/tools/methodsPermissions.php | 144 + .../engine/templates/tracker/stages_Map.html | 2 + workflow/engine/templates/tree.html | 127 + .../templates/triggers/triggersTree.php | 77 + .../triggers/triggers_CreateWizard.html | 171 + .../triggers/triggers_CreateWizard.php | 134 + .../triggers/triggers_EditWizard.html | 178 + .../triggers/triggers_EditWizard.php | 139 + .../templates/users/users_AssignGroup.php | 86 + .../templates/users/users_DeleteReassign.html | 42 + .../templates/users/users_ReassignCases.html | 42 + .../engine/templates/users/users_Tree.php | 88 + workflow/engine/templates/xmlform.html | 177 + workflow/engine/templates/xmlformScript.html | 69 + .../engine/templates/xmlform_preview.html | 175 + workflow/engine/templates/xmlmenu.html | 117 + workflow/engine/templates/xmlmenuDyn.html | 117 + workflow/engine/test/bootstrap/functional.php | 52 + .../test/bootstrap/gulliverConstants.php | 103 + workflow/engine/test/bootstrap/unit.php | 71 + .../engine/test/fixtures/appDelegation.yml | 40 + workflow/engine/test/fixtures/appDocument.yml | 100 + workflow/engine/test/fixtures/application.yml | 10 + .../engine/test/fixtures/applicationInput.yml | 75 + .../engine/test/fixtures/configuration.yml | 47 + workflow/engine/test/fixtures/content.yml | 71 + workflow/engine/test/fixtures/departments.txt | 34 + workflow/engine/test/fixtures/derivation.yml | 28 + workflow/engine/test/fixtures/domain.yml | 34 + workflow/engine/test/fixtures/es.yml | 59 + workflow/engine/test/fixtures/firstname.txt | 501 + workflow/engine/test/fixtures/fixtures.yml | 29 + workflow/engine/test/fixtures/groupUser.yml | 36 + workflow/engine/test/fixtures/groups.txt | 32 + .../engine/test/fixtures/inputDocument.yml | 88 + workflow/engine/test/fixtures/lastname.txt | 222 + .../engine/test/fixtures/outputDocument.yml | 84 + workflow/engine/test/fixtures/processMap.yml | 494 + workflow/engine/test/fixtures/route.yml | 112 + workflow/engine/test/fixtures/step.yml | 35 + workflow/engine/test/fixtures/stepTrigger.yml | 43 + .../test/fixtures/swimlanesElements.yml | 84 + workflow/engine/test/fixtures/task.yml | 32 + workflow/engine/test/fixtures/taskUser.yml | 44 + workflow/engine/test/fixtures/trigger.yml | 32 + workflow/engine/test/fixtures/user.yml | 34 + .../unit/gulliver/classDBConnectionTest.php | 74 + .../unit/gulliver/classDBRecordsetTest.php | 66 + .../test/unit/gulliver/classDBSessionTest.php | 67 + .../test/unit/gulliver/classDBTableTest.php | 71 + .../unit/gulliver/classDatabase_baseTest.php | 59 + .../unit/gulliver/classDatabase_mysqlTest.php | 65 + .../test/unit/gulliver/classDvEditorTest.php | 49 + .../gulliver/classDynaformhandlerTest.php | 44 + .../test/unit/gulliver/classErrorTest.php | 79 + .../test/unit/gulliver/classFckEditorTest.php | 44 + .../unit/gulliver/classFilterFormTest.php | 49 + .../test/unit/gulliver/classFormTest.php | 59 + .../engine/test/unit/gulliver/classGTest.php | 274 + .../unit/gulliver/classHeadPublisherTest.php | 73 + .../test/unit/gulliver/classHtmlAreaTest.php | 60 + .../test/unit/gulliver/classMailerTest.php | 67 + .../test/unit/gulliver/classMenuTest.php | 72 + .../unit/gulliver/classObjectTemplateTest.php | 58 + .../unit/gulliver/classPagedTableTest.php | 44 + .../test/unit/gulliver/classPublisherTest.php | 63 + .../test/unit/gulliver/classRbacTest.php | 66 + .../test/unit/gulliver/classTableTest.php | 81 + .../unit/gulliver/classTemplatePowerTest.php | 77 + .../test/unit/gulliver/classTestToolsTest.php | 42 + .../test/unit/gulliver/classTreeTest.php | 67 + .../unit/gulliver/classWebResourceTest.php | 48 + .../unit/gulliver/classXmlDocumentTest.php | 74 + .../test/unit/gulliver/classXmlMenuTest.php | 65 + .../gulliver/classXmlformExtensionTest.php | 49 + .../test/unit/gulliver/classXmlformTest.php | 46 + .../processmaker/classAppDelegationTest.php | 92 + .../processmaker/classAppDocumentTest.php | 153 + .../processmaker/classApplicationTest.php | 217 + .../unit/processmaker/classArchiveTest.php | 167 + .../processmaker/classArrayBasePeerTest.php | 229 + .../unit/processmaker/classBasePeerTest.php | 183 + .../test/unit/processmaker/classCasesTest.php | 638 + .../processmaker/classConfigurationTest.php | 135 + .../unit/processmaker/classContentTest.php | 149 + .../unit/processmaker/classDashboardsTest.php | 96 + .../test/unit/processmaker/classDatesTest.php | 207 + .../processmaker/classDbConnectionsTest.php | 151 + .../unit/processmaker/classDerivationTest.php | 149 + .../processmaker/classDynaFormFieldTest.php | 82 + .../unit/processmaker/classDynaformTest.php | 120 + .../test/unit/processmaker/classESMTPTest.php | 242 + .../test/unit/processmaker/classGroupTest.php | 77 + .../unit/processmaker/classGroupUserTest.php | 98 + .../unit/processmaker/classGroupsTest.php | 175 + .../processmaker/classInputDocumentTest.php | 148 + .../unit/processmaker/classInsertTest.php | 72 + .../unit/processmaker/classInstallerTest.php | 178 + .../processmaker/classJavaBridgePMTest.php | 73 + .../test/unit/processmaker/classJrmlTest.php | 113 + .../unit/processmaker/classLanguagesTest.php | 56 + .../unit/processmaker/classMenuDetailTest.php | 57 + .../test/unit/processmaker/classNetTest.php | 161 + .../processmaker/classOutputDocumentTest.php | 160 + .../unit/processmaker/classPackageTest.php | 113 + .../processmaker/classPluginDetailTest.php | 57 + .../unit/processmaker/classPmScriptTest.php | 89 + .../unit/processmaker/classPopupMenuTest.php | 55 + .../classProcessMakerWebDavTest.php | 465 + .../unit/processmaker/classProcessMapTest.php | 587 + .../unit/processmaker/classProcessTest.php | 247 + .../unit/processmaker/classProcessesTest.php | 985 + .../processmaker/classPropelTableTest.php | 112 + .../processmaker/classReportTablesTest.php | 112 + .../unit/processmaker/classReportTest.php | 162 + .../test/unit/processmaker/classRouteTest.php | 136 + .../unit/processmaker/classSessionsTest.php | 65 + .../test/unit/processmaker/classSmtpTest.php | 153 + .../unit/processmaker/classSpoolRunTest.php | 160 + .../test/unit/processmaker/classStepTest.php | 132 + .../processmaker/classStepTriggerTest.php | 137 + .../classSwimlanesElementsTest.php | 142 + .../test/unit/processmaker/classTaskTest.php | 132 + .../unit/processmaker/classTaskUserTest.php | 98 + .../unit/processmaker/classToolBarTest.php | 60 + .../processmaker/classTranslationTest.php | 55 + .../unit/processmaker/classTriggerTest.php | 129 + .../test/unit/processmaker/classUserTest.php | 132 + .../unit/processmaker/classWsBaseTest.php | 233 + .../unit/processmaker/classWsResponseTest.php | 73 + .../test/unit/processmaker/classXmlDbTest.php | 64 + .../classXmlForm_Field_ImageTest.php | 209 + .../classXmlForm_Field_TextPMTest.php | 210 + .../test/unit/ws/EvaluationDerivationTest.php | 182 + .../engine/test/unit/ws/OtherMethodsTest.php | 83 + .../test/unit/ws/ParallelDerivation2Test.php | 206 + .../test/unit/ws/ParallelDerivationTest.php | 172 + .../test/unit/ws/ProcessWithSubprocess.php | 108 + .../test/unit/ws/SelectionDerivationTest.php | 152 + .../test/unit/ws/SequentialDerivationTest.php | 156 + .../engine/test/unit/ws/SubprocessTest.php | 166 + .../engine/test/unit/ws/basicMethodsTest.php | 512 + .../engine/test/unit/ws/bugRelease09Test.php | 346 + .../engine/test/unit/ws/reportsToTest.php | 260 + workflow/engine/test/unit/ws/wsClient.php | 674 + .../engine/test/unit/ws/wsConfig.php.example | 9 + .../additionalTables/additionalTablesData.xml | 20 + .../additionalTablesDataImportForm.html | 40 + .../additionalTablesDataImportForm.xml | 31 + .../additionalTablesEdit.html | 69 + .../additionalTables/additionalTablesEdit.xml | 426 + .../additionalTablesExportList.xml | 32 + .../additionalTablesFields.xml | 32 + .../additionalTablesFields2.xml | 36 + .../additionalTables/additionalTablesList.xml | 20 + .../additionalTables/additionalTablesNew.html | 74 + .../additionalTables/additionalTablesNew.xml | 475 + .../additionalTablesOptions.xml | 119 + .../additionalTablesTitle.xml | 8 + .../additionalTablesToImport.html | 40 + .../additionalTablesToImport.xml | 44 + .../xmlform/additionalTables/doExport.xml | 19 + .../engine/xmlform/appFolder/appFolder.xml | 32 + .../xmlform/appFolder/appFolderDelete.xml | 21 + .../appFolder/appFolderDocsListOptions.xml | 30 + .../appFolderDocsListSearchOptions.xml | 22 + .../appFolder/appFolderDocumentInfo.xml | 27 + .../appFolder/appFolderDocumentList.xml | 61 + .../appFolder/appFolderDocumentListHeader.xml | 18 + .../appFolderDocumentListHistory.xml | 43 + .../appFolder/appFolderDocumentListSearch.xml | 54 + .../xmlform/appFolder/appFolderEdit.html | 45 + .../xmlform/appFolder/appFolderEdit.xml | 43 + .../xmlform/appFolder/appFolderList.xml | 25 + .../xmlform/appFolder/appFolderOptions.xml | 8 + .../xmlform/authSources/authSources_List.xml | 28 + .../authSources/authSources_Options.xml | 23 + .../authSources/authSources_SearchUsers.html | 39 + .../authSources/authSources_SearchUsers.xml | 82 + .../authSources/authSources_SelectType.html | 32 + .../authSources/authSources_SelectType.xml | 31 + .../engine/xmlform/authSources/ldapEdit.html | 103 + .../engine/xmlform/authSources/ldapEdit.xml | 116 + .../xmlform/authSources/ldapSearchResults.xml | 20 + workflow/engine/xmlform/cases/casesDemo.xml | 19 + .../xmlform/cases/cases_AllDynaformsList.xml | 13 + .../xmlform/cases/cases_AllInputdocsList.xml | 47 + .../xmlform/cases/cases_AllOutputdocsList.xml | 38 + .../cases/cases_AttachInputDocument1.xml | 73 + .../cases/cases_AttachInputDocument2.xml | 69 + .../cases/cases_AttachInputDocument3.xml | 80 + .../cases_AttachInputDocumentGeneral.html | 53 + .../cases_AttachInputDocumentGeneral.xml | 63 + .../cases/cases_AttachInputDocumentInfo.xml | 14 + .../cases/cases_CannotInitiateCase.xml | 12 + .../xmlform/cases/cases_CatchSelfService.html | 76 + .../xmlform/cases/cases_CatchSelfService.xml | 63 + .../xmlform/cases/cases_DynaformHistory.xml | 19 + .../xmlform/cases/cases_InputdocsList.xml | 51 + .../cases/cases_InputdocsListHistory.xml | 46 + .../cases/cases_InputdocsListOptions.xml | 20 + .../cases/cases_InputdocsListToRevise.xml | 25 + workflow/engine/xmlform/cases/cases_List.xml | 58 + .../engine/xmlform/cases/cases_ListAll.xml | 72 + .../xmlform/cases/cases_ListAllDelete.xml | 73 + .../xmlform/cases/cases_ListAll_Reassign.xml | 79 + .../xmlform/cases/cases_ListCancelled.xml | 71 + .../xmlform/cases/cases_ListCompleted.xml | 87 + .../engine/xmlform/cases/cases_ListDraft.xml | 61 + .../engine/xmlform/cases/cases_ListOnHold.xml | 74 + .../xmlform/cases/cases_ListSelfService.xml | 87 + .../engine/xmlform/cases/cases_ListSent.xml | 73 + .../xmlform/cases/cases_ListStarted.xml | 73 + .../xmlform/cases/cases_ListToRevise.xml | 94 + .../engine/xmlform/cases/cases_ListTodo.xml | 63 + .../xmlform/cases/cases_ListTodoNew.xml | 68 + .../engine/xmlform/cases/cases_Messages.xml | 34 + .../xmlform/cases/cases_MessagesView.xml | 27 + workflow/engine/xmlform/cases/cases_New.html | 39 + workflow/engine/xmlform/cases/cases_New.xml | 22 + .../xmlform/cases/cases_NewRadioGroup.html | 32 + .../xmlform/cases/cases_NewRadioGroup.xml | 27 + .../engine/xmlform/cases/cases_Options.xml | 135 + .../xmlform/cases/cases_OptionsSent.xml | 211 + .../xmlform/cases/cases_OptionsToDo.xml | 190 + .../cases/cases_OutputdocsListToRevise.xml | 21 + .../cases/cases_ProcessInformation.xml | 21 + .../engine/xmlform/cases/cases_Reassign.xml | 26 + .../xmlform/cases/cases_ReassignBy.html | 34 + .../engine/xmlform/cases/cases_ReassignBy.xml | 76 + .../xmlform/cases/cases_ReassignShowInfo.xml | 19 + .../xmlform/cases/cases_ReassignUsers.xml | 7 + .../engine/xmlform/cases/cases_Resume.xml | 81 + .../xmlform/cases/cases_Scheduler_Edit.html | 251 + .../xmlform/cases/cases_Scheduler_Edit.xml | 836 + .../xmlform/cases/cases_Scheduler_List.xml | 37 + .../xmlform/cases/cases_Scheduler_Log.xml | 39 + .../cases/cases_Scheduler_Log_Detail.xml | 42 + .../xmlform/cases/cases_Scheduler_New.html | 236 + .../xmlform/cases/cases_Scheduler_New.xml | 735 + .../cases/cases_Scheduler_NewOptions.xml | 6 + .../xmlform/cases/cases_Scheduler_Options.xml | 48 + .../xmlform/cases/cases_TaskDetails.xml | 28 + .../xmlform/cases/cases_TaskInformation.xml | 29 + .../cases/cases_ToReassignByUserList.xml | 46 + .../cases/cases_ToReassignByUserList2.xml | 39 + .../cases/cases_ToReviseInputdocsList.xml | 42 + .../cases_ToReviseInputdocsListOptions.xml | 21 + .../xmlform/cases/cases_TransferHistory.xml | 46 + .../xmlform/cases/cases_UnpauseDateInput.html | 40 + .../xmlform/cases/cases_UnpauseDateInput.xml | 20 + .../cases/cases_ViewAnyInputDocument.xml | 32 + .../cases/cases_ViewAnyInputDocument1.xml | 56 + .../cases/cases_ViewAnyInputDocument2.xml | 52 + .../cases/cases_ViewAnyInputDocument3.xml | 60 + .../cases/cases_ViewAnyOutputDocument.xml | 36 + .../cases/cases_ViewInputDocument1.xml | 65 + .../cases/cases_ViewInputDocument2.xml | 61 + .../cases/cases_ViewInputDocument3.xml | 69 + .../cases/cases_ViewInputDocumentToRevise.xml | 59 + .../cases/cases_ViewOutputDocument1.xml | 48 + .../cases/cases_ViewOutputDocument2.xml | 44 + .../cases/cases_ViewOutputDocument3.xml | 44 + .../cases_ViewOutputDocumentToRevise.xml | 34 + .../xmlform/cases/cases_advancedSearch.xml | 73 + .../cases/cases_advancedSearchFilter.html | 56 + .../cases/cases_advancedSearchFilter.xml | 51 + .../dashboard_AvailableDashboards.html | 33 + .../dashboard_AvailableDashboards.xml | 28 + .../dashboard_NoAvailableDashboards.xml | 11 + .../xmlform/dbConnections/dbConnections.xml | 34 + .../dbConnections/dbConnections_Edit.html | 77 + .../dbConnections/dbConnections_Edit.xml | 69 + .../dbConnections/dbConnections_New.html | 75 + .../dbConnections/dbConnections_New.xml | 66 + .../dbConnections/dbConnections_Options.xml | 10 + .../departments_AddUnAssignedUsers.xml | 43 + .../departments_AvailableUsers.xml | 25 + .../xmlform/departments/departments_Edit.html | 54 + .../xmlform/departments/departments_Edit.xml | 88 + .../xmlform/departments/departments_New.html | 41 + .../xmlform/departments/departments_New.xml | 94 + .../departments/departments_Options.xml | 12 + .../departments/departments_SubNew.html | 47 + .../departments/departments_SubNew.xml | 81 + .../departments/departments_UsersList.xml | 26 + .../engine/xmlform/dynaforms/datemask.xml | 37 + .../xmlform/dynaforms/dynaform_Fields.xml | 22 + .../dynaforms/dynaforms_AssignVariables.html | 49 + .../dynaforms/dynaforms_AssignVariables.xml | 131 + .../dynaforms_AssignVariablesGrid.xml | 13 + ...dynaforms_AvailableSupervisorDynaforms.xml | 27 + .../dynaforms/dynaforms_ChoseType.html | 39 + .../xmlform/dynaforms/dynaforms_ChoseType.xml | 52 + .../dynaforms_ConditionalShowHide.html | 149 + .../dynaforms_ConditionalShowHide.xml | 132 + .../dynaforms_ConditionalShowHideList.xml | 36 + .../dynaforms_ConditionalShowHideOptions.xml | 12 + .../dynaforms_ConditionalShowHideTest.html | 26 + .../dynaforms_ConditionalShowHideTest.xml | 17 + .../dynaforms_ConditionalShowHideTestGrid.xml | 13 + .../xmlform/dynaforms/dynaforms_Edit.html | 63 + .../xmlform/dynaforms/dynaforms_Edit.xml | 143 + .../xmlform/dynaforms/dynaforms_Editor.html | 28 + .../xmlform/dynaforms/dynaforms_Editor.xml | 258 + .../dynaforms/dynaforms_HtmlEditor.html | 35 + .../dynaforms/dynaforms_HtmlEditor.xml | 80 + .../xmlform/dynaforms/dynaforms_JSEditor.xml | 47 + .../xmlform/dynaforms/dynaforms_List.xml | 34 + .../xmlform/dynaforms/dynaforms_Options.xml | 151 + .../dynaforms/dynaforms_Properties.xml | 198 + .../xmlform/dynaforms/dynaforms_Saveas.html | 47 + .../xmlform/dynaforms/dynaforms_Saveas.xml | 51 + .../xmlform/dynaforms/dynaforms_ShortList.xml | 34 + .../dynaforms/dynaforms_Supervisor.xml | 31 + .../dynaforms/dynaforms_SupervisorOptions.xml | 80 + .../xmlform/dynaforms/dynaforms_Toolbar.xml | 20 + .../xmlform/dynaforms/dynaforms_WebEntry.xml | 226 + .../dynaforms/dynaforms_WebEntryList.xml | 15 + .../dynaforms/dynaforms_WebEntryOptions.xml | 78 + .../xmlform/dynaforms/dynaforms_XmlEditor.xml | 24 + .../xmlform/dynaforms/dynaforms_vars.html | 27 + .../xmlform/dynaforms/dynaforms_vars.xml | 10 + .../xmlform/dynaforms/fields/_options.xml | 9 + .../xmlform/dynaforms/fields/button.html | 58 + .../xmlform/dynaforms/fields/button.xml | 47 + .../xmlform/dynaforms/fields/checkbox.html | 90 + .../xmlform/dynaforms/fields/checkbox.xml | 74 + .../xmlform/dynaforms/fields/checkgroup.html | 93 + .../xmlform/dynaforms/fields/checkgroup.xml | 82 + .../xmlform/dynaforms/fields/currency.html | 136 + .../xmlform/dynaforms/fields/currency.xml | 134 + .../engine/xmlform/dynaforms/fields/date.html | 149 + .../engine/xmlform/dynaforms/fields/date.xml | 230 + .../xmlform/dynaforms/fields/dropdown.html | 111 + .../xmlform/dynaforms/fields/dropdown.xml | 123 + .../engine/xmlform/dynaforms/fields/file.html | 71 + .../engine/xmlform/dynaforms/fields/file.xml | 66 + .../engine/xmlform/dynaforms/fields/grid.html | 61 + .../engine/xmlform/dynaforms/fields/grid.xml | 51 + .../xmlform/dynaforms/fields/hidden.html | 71 + .../xmlform/dynaforms/fields/hidden.xml | 64 + .../xmlform/dynaforms/fields/javascript.html | 55 + .../xmlform/dynaforms/fields/javascript.xml | 42 + .../engine/xmlform/dynaforms/fields/link.html | 78 + .../engine/xmlform/dynaforms/fields/link.xml | 85 + .../xmlform/dynaforms/fields/listbox.html | 100 + .../xmlform/dynaforms/fields/listbox.xml | 90 + .../xmlform/dynaforms/fields/password.html | 90 + .../xmlform/dynaforms/fields/password.xml | 77 + .../xmlform/dynaforms/fields/percentage.html | 130 + .../xmlform/dynaforms/fields/percentage.xml | 125 + .../xmlform/dynaforms/fields/radiogroup.html | 95 + .../xmlform/dynaforms/fields/radiogroup.xml | 85 + .../dynaforms/fields/radiogroupview.xml | 38 + .../xmlform/dynaforms/fields/reset.html | 51 + .../engine/xmlform/dynaforms/fields/reset.xml | 43 + .../xmlform/dynaforms/fields/submit.html | 55 + .../xmlform/dynaforms/fields/submit.xml | 47 + .../xmlform/dynaforms/fields/subtitle.html | 60 + .../xmlform/dynaforms/fields/subtitle.xml | 52 + .../xmlform/dynaforms/fields/suggest.html | 141 + .../xmlform/dynaforms/fields/suggest.xml | 285 + .../engine/xmlform/dynaforms/fields/text.html | 139 + .../engine/xmlform/dynaforms/fields/text.xml | 177 + .../xmlform/dynaforms/fields/textarea.html | 107 + .../xmlform/dynaforms/fields/textarea.xml | 88 + .../xmlform/dynaforms/fields/title.html | 62 + .../engine/xmlform/dynaforms/fields/title.xml | 52 + .../xmlform/dynaforms/fields/yesno.html | 77 + .../engine/xmlform/dynaforms/fields/yesno.xml | 67 + .../engine/xmlform/dynaforms/fields_Edit.xml | 24 + .../engine/xmlform/dynaforms/fields_List.xml | 29 + .../xmlform/dynaforms/fields_Options.xml | 51 + .../xmlform/dynaforms/fields_ShortList.xml | 21 + .../xmlform/dynaforms/fields_Toolbar.xml | 104 + .../xmlform/dynaforms/fields_ToolbarGrid.xml | 56 + .../engine/xmlform/events/appEventsList.xml | 30 + .../xmlform/events/appEventsListCompleted.xml | 30 + .../engine/xmlform/events/dynavarsList.xml | 11 + .../engine/xmlform/events/eventsEdit.html | 100 + workflow/engine/xmlform/events/eventsEdit.xml | 176 + .../xmlform/events/eventsEditAction.html | 150 + .../xmlform/events/eventsEditAction.xml | 154 + workflow/engine/xmlform/events/eventsNew.html | 100 + workflow/engine/xmlform/events/eventsNew.xml | 178 + .../engine/xmlform/events/eventsOptions.xml | 157 + .../engine/xmlform/events/eventsShortList.xml | 28 + .../engine/xmlform/events/groupmailList.xml | 12 + .../engine/xmlform/events/usermailList.xml | 16 + .../engine/xmlform/groups/groups_AddUser.xml | 19 + .../xmlform/groups/groups_AvailableUsers.xml | 25 + .../engine/xmlform/groups/groups_Edit.html | 46 + .../engine/xmlform/groups/groups_Edit.xml | 91 + .../engine/xmlform/groups/groups_List.xml | 23 + .../engine/xmlform/groups/groups_Options.xml | 13 + .../engine/xmlform/groups/groups_Search.xml | 25 + .../xmlform/groups/groups_SelectUsers.xml | 8 + .../xmlform/groups/groups_UsersList.xml | 21 + .../xmlform/groups/groups_UsersListTitle.xml | 10 + .../xmlform/groups/groups_userSearch.xml | 9 + .../xmlform/gulliver/dynaforms_Options.xml | 20 + .../gulliver/dynaforms_OptionsPrint.xml | 20 + .../xmlform/gulliver/pagedTable_Options.xml | 9 + .../xmlform/gulliver/pagedTable_PopupMenu.xml | 22 + .../inputdocs_AvailableSupervisorInputs.xml | 27 + .../xmlform/inputdocs/inputdocs_Edit.html | 68 + .../xmlform/inputdocs/inputdocs_Edit.xml | 122 + .../xmlform/inputdocs/inputdocs_List.xml | 36 + .../xmlform/inputdocs/inputdocs_Options.xml | 55 + .../xmlform/inputdocs/inputdocs_ShortList.xml | 29 + .../inputdocs/inputdocs_Supervisor.xml | 31 + .../inputdocs/inputdocs_SupervisorOptions.xml | 76 + .../engine/xmlform/login/changePassword.xml | 75 + workflow/engine/xmlform/login/dbInfo.xml | 43 + workflow/engine/xmlform/login/login.xml | 127 + workflow/engine/xmlform/login/newSite.xml | 167 + workflow/engine/xmlform/login/noViewPage.xml | 16 + workflow/engine/xmlform/login/nologin.xml | 22 + workflow/engine/xmlform/login/showInfo.xml | 9 + .../engine/xmlform/login/showInfoUpdate.xml | 29 + workflow/engine/xmlform/login/showMessage.xml | 9 + workflow/engine/xmlform/login/sysLogin.xml | 53 + .../engine/xmlform/login/sysLoginNoWS.xml | 52 + .../engine/xmlform/messages/messages_Edit.xml | 19 + .../engine/xmlform/messages/messages_List.xml | 28 + .../xmlform/messages/messages_Options.xml | 34 + .../xmlform/messages/messages_ShortList.xml | 21 + .../outputdocs/outputdocsDynaformList.xml | 23 + .../outputdocs/outputdocsUploadFile.xml | 36 + .../xmlform/outputdocs/outputdocs_Edit.html | 39 + .../xmlform/outputdocs/outputdocs_Edit.xml | 135 + .../xmlform/outputdocs/outputdocs_List.xml | 27 + .../xmlform/outputdocs/outputdocs_New.xml | 109 + .../xmlform/outputdocs/outputdocs_Options.xml | 103 + .../outputdocs/outputdocs_Properties.html | 106 + .../outputdocs/outputdocs_Properties.xml | 176 + .../outputdocs/outputdocs_ShortList.xml | 35 + .../xmlform/patterns/patterns_Current.html | 62 + .../xmlform/patterns/patterns_Current.xml | 241 + .../xmlform/patterns/patterns_Evaluate.html | 49 + .../xmlform/patterns/patterns_Evaluate.xml | 266 + .../patterns/patterns_GridEvaluateType.xml | 14 + .../patterns_GridParallelByEvaluationType.xml | 13 + .../patterns/patterns_GridParallelType.xml | 9 + .../patterns/patterns_GridSelectType.xml | 14 + .../xmlform/patterns/patterns_Parallel.html | 49 + .../xmlform/patterns/patterns_Parallel.xml | 212 + .../patterns_ParallelByEvaluation.html | 50 + .../patterns_ParallelByEvaluation.xml | 268 + .../patterns/patterns_ParallelJoin.xml | 200 + .../xmlform/patterns/patterns_Select.html | 51 + .../xmlform/patterns/patterns_Select.xml | 216 + .../xmlform/patterns/patterns_Sequential.html | 50 + .../xmlform/patterns/patterns_Sequential.xml | 207 + .../processCategory/processCategory.xml | 33 + .../processCategoryDelete.html | 39 + .../processCategory/processCategoryDelete.xml | 31 + .../processCategory/processCategoryEdit.html | 48 + .../processCategory/processCategoryEdit.xml | 56 + .../processCategory/processCategoryList.xml | 25 + .../processCategoryOptions.xml | 8 + .../engine/xmlform/processes/objectpmView.xml | 136 + .../processes/processes_Assignuser.xml | 74 + .../processes/processes_DeleteCases.xml | 32 + .../processes/processes_DirectoriesList.xml | 6 + .../processes_DirectoriesOptions.xml | 86 + .../xmlform/processes/processes_Edit.html | 58 + .../xmlform/processes/processes_Edit.xml | 70 + .../processes_EditObjectPermission.xml | 130 + .../xmlform/processes/processes_Export.xml | 35 + .../xmlform/processes/processes_FileEdit.html | 40 + .../xmlform/processes/processes_FileEdit.xml | 31 + .../processes_FileEditCreateEmpty.html | 29 + .../processes_FileEditCreateEmpty.xml | 9 + .../xmlform/processes/processes_FilesList.xml | 17 + .../processes/processes_FilesOptions.xml | 150 + .../xmlform/processes/processes_Import.html | 36 + .../xmlform/processes/processes_Import.xml | 38 + .../processes/processes_ImportExisting.html | 43 + .../processes/processes_ImportExisting.xml | 44 + .../processes/processes_ImportSucessful.xml | 37 + .../xmlform/processes/processes_List.xml | 23 + .../processes/processes_ListPublic.xml | 43 + .../xmlform/processes/processes_New.xml | 51 + .../processes_NewObjectPermission.html | 85 + .../processes_NewObjectPermission.xml | 245 + .../processes/processes_NewOptions.xml | 6 + .../processes/processes_NewSimple.html | 46 + .../xmlform/processes/processes_NewSimple.xml | 79 + .../processes_ObjectsPermissionsList.xml | 37 + .../processes_ObjectsPermissionsOptions.xml | 125 + .../xmlform/processes/processes_Options.xml | 57 + .../processes/processes_Properties.xml | 46 + .../xmlform/processes/processes_Search.xml | 20 + .../processes/processes_UploadFilesForm.xml | 67 + .../xmlform/processes/processes_User.xml | 20 + .../processes/processes_ValidatingGroups.xml | 39 + .../xmlform/processes/processes_View.xml | 20 + .../processes/processes_ViewOptions.xml | 6 + .../processes_availableProcessesUser.xml | 17 + .../processes/processes_subProcess.html | 76 + .../processes/processes_subProcess.xml | 173 + .../processes/processes_subProcess_In.xml | 12 + .../processes/processes_subProcess_Out.xml | 12 + .../processes/processes_viewreassignCase.xml | 25 + .../engine/xmlform/processes/registerPML.html | 35 + .../engine/xmlform/processes/registerPML.xml | 28 + .../reportTables/reportTables_Edit.html | 59 + .../reportTables/reportTables_Edit.xml | 94 + .../reportTables/reportTables_Options.xml | 101 + .../reportTables/reportTables_ShortList.xml | 27 + workflow/engine/xmlform/reports/report1.xml | 33 + .../engine/xmlform/reports/report1_back.xml | 8 + .../xmlform/reports/report1_dashboard.xml | 26 + .../xmlform/reports/report1_search.html | 27 + .../engine/xmlform/reports/report1_search.xml | 21 + workflow/engine/xmlform/reports/report2.xml | 28 + .../xmlform/reports/report2_dashboard.xml | 26 + workflow/engine/xmlform/reports/report3.xml | 28 + .../xmlform/reports/report3_dashboard.xml | 26 + workflow/engine/xmlform/reports/report4.xml | 28 + .../xmlform/reports/report4_dashboard.xml | 26 + workflow/engine/xmlform/reports/report5.xml | 28 + .../xmlform/reports/report5_dashboard.xml | 26 + .../engine/xmlform/reports/report_filter.xml | 50 + .../engine/xmlform/reports/reportsList.xml | 18 + .../xmlform/reports/reports_Description.xml | 24 + .../reports/reports_Description_search.xml | 26 + .../engine/xmlform/reports/rpt_filters.xml | 16 + workflow/engine/xmlform/roles/roles_Edit.html | 46 + workflow/engine/xmlform/roles/roles_Edit.xml | 38 + workflow/engine/xmlform/roles/roles_List.xml | 36 + workflow/engine/xmlform/roles/roles_New.html | 43 + workflow/engine/xmlform/roles/roles_New.xml | 36 + .../engine/xmlform/roles/roles_Options.xml | 345 + .../engine/xmlform/setup/calendarEdit.html | 67 + .../engine/xmlform/setup/calendarEdit.xml | 371 + .../setup/calendarEdit_BusinessHours.xml | 15 + .../xmlform/setup/calendarEdit_Holidays.xml | 12 + .../engine/xmlform/setup/calendarList.xml | 29 + .../xmlform/setup/calendarList_Options.xml | 8 + .../engine/xmlform/setup/emailSetupTest.xml | 36 + workflow/engine/xmlform/setup/emails.html | 92 + workflow/engine/xmlform/setup/emails.xml | 639 + .../engine/xmlform/setup/emails_Sended.xml | 14 + .../engine/xmlform/setup/emails_TestForm.xml | 68 + workflow/engine/xmlform/setup/holiday.xml | 19 + workflow/engine/xmlform/setup/holidayList.xml | 20 + .../engine/xmlform/setup/holidayListMenu.xml | 6 + workflow/engine/xmlform/setup/language.xml | 16 + .../engine/xmlform/setup/language_table.xml | 16 + workflow/engine/xmlform/setup/languages.xml | 12 + .../xmlform/setup/languages_ImportForm.html | 34 + .../xmlform/setup/languages_ImportForm.xml | 34 + .../xmlform/setup/languages_Options.xml | 42 + workflow/engine/xmlform/setup/location.html | 52 + workflow/engine/xmlform/setup/location.xml | 34 + workflow/engine/xmlform/setup/logo_Option.xml | 33 + workflow/engine/xmlform/setup/mail.xml | 41 + workflow/engine/xmlform/setup/mailTest.xml | 14 + workflow/engine/xmlform/setup/noProcesses.xml | 8 + .../engine/xmlform/setup/pluginImport.html | 37 + .../engine/xmlform/setup/pluginImport.xml | 41 + workflow/engine/xmlform/setup/pluginList.xml | 38 + .../xmlform/setup/plugin_ListOptions.xml | 6 + .../xmlform/setup/processHeartBeatConfig.html | 44 + .../xmlform/setup/processHeartBeatConfig.xml | 30 + workflow/engine/xmlform/setup/showMessage.xml | 9 + workflow/engine/xmlform/setup/skinsList.xml | 24 + .../engine/xmlform/setup/skinsListOptions.xml | 8 + workflow/engine/xmlform/setup/skinsNew.html | 43 + workflow/engine/xmlform/setup/skinsNew.xml | 45 + workflow/engine/xmlform/setup/upgrade.xml | 47 + workflow/engine/xmlform/setup/uplogo.xml | 36 + workflow/engine/xmlform/setup/uplogoList.xml | 27 + .../xmlform/setup/webServicesDetails.xml | 28 + .../xmlform/setup/webServicesSetup.html | 48 + .../engine/xmlform/setup/webServicesSetup.xml | 42 + workflow/engine/xmlform/setup/weekend.xml | 31 + workflow/engine/xmlform/setup/workPeriod.xml | 59 + .../xmlform/setup/wsAssignUserToGroup.xml | 26 + workflow/engine/xmlform/setup/wsCaseList.xml | 15 + .../engine/xmlform/setup/wsCreateUser.xml | 42 + .../engine/xmlform/setup/wsDerivateCase.xml | 25 + workflow/engine/xmlform/setup/wsGroupList.xml | 15 + .../xmlform/setup/wsInputDocumentList.xml | 20 + .../setup/wsInputDocumentProcessList.xml | 20 + workflow/engine/xmlform/setup/wsLogin.xml | 43 + workflow/engine/xmlform/setup/wsMessage.xml | 8 + workflow/engine/xmlform/setup/wsNewCase.xml | 27 + .../xmlform/setup/wsNewCaseImpersonate.xml | 27 + .../xmlform/setup/wsOutputDocumentList.xml | 21 + .../engine/xmlform/setup/wsProcessList.xml | 15 + .../engine/xmlform/setup/wsReassignCase.xml | 35 + .../engine/xmlform/setup/wsRemoveDocument.xml | 20 + workflow/engine/xmlform/setup/wsRoleList.xml | 15 + workflow/engine/xmlform/setup/wsSendFiles.xml | 52 + .../engine/xmlform/setup/wsSendMessage.xml | 44 + .../engine/xmlform/setup/wsSendVariables.xml | 36 + .../engine/xmlform/setup/wsShowResult.xml | 15 + workflow/engine/xmlform/setup/wsTaskCase.xml | 20 + workflow/engine/xmlform/setup/wsTaskList.xml | 15 + .../engine/xmlform/setup/wsTriggerList.xml | 15 + workflow/engine/xmlform/setup/wsUserList.xml | 15 + .../engine/xmlform/setup/wsVariablesGrid.xml | 9 + workflow/engine/xmlform/setup/wsrCaseList.xml | 20 + .../engine/xmlform/setup/wsrGroupList.xml | 12 + .../xmlform/setup/wsrInputDocumentList.xml | 30 + .../setup/wsrInputDocumentProcessList.xml | 18 + .../xmlform/setup/wsrOutputDocumentList.xml | 30 + .../engine/xmlform/setup/wsrProcessList.xml | 13 + workflow/engine/xmlform/setup/wsrRoleList.xml | 12 + workflow/engine/xmlform/setup/wsrTaskCase.xml | 12 + workflow/engine/xmlform/setup/wsrTaskList.xml | 12 + .../engine/xmlform/setup/wsrTriggerList.xml | 16 + workflow/engine/xmlform/setup/wsrUserList.xml | 12 + .../engine/xmlform/steps/conditions_Edit.xml | 74 + .../engine/xmlform/steps/conditions_List.xml | 32 + .../xmlform/steps/conditions_Options.xml | 23 + workflow/engine/xmlform/steps/steps_List.xml | 40 + .../engine/xmlform/steps/steps_Options.xml | 75 + .../xmlform/steps/steps_availableBB.xml | 24 + .../xmlform/steps/triggersAfter_List.xml | 22 + .../xmlform/steps/triggersAfter_Options.xml | 13 + .../xmlform/steps/triggersBefore_List.xml | 22 + .../xmlform/steps/triggersBefore_Options.xml | 13 + .../xmlform/steps/triggersCondition_Edit.xml | 85 + .../engine/xmlform/steps/triggers_Assign.xml | 99 + .../xmlform/steps/triggers_NoAssign.xml | 12 + .../xmlform/tasks/tasks_AssignmentRules.xml | 139 + .../engine/xmlform/tasks/tasks_Definition.xml | 115 + .../engine/xmlform/tasks/tasks_Labels.xml | 91 + .../xmlform/tasks/tasks_Notifications.xml | 110 + workflow/engine/xmlform/tasks/tasks_Owner.xml | 12 + .../xmlform/tasks/tasks_Permissions.xml | 46 + .../xmlform/tasks/tasks_TimingControl.xml | 44 + .../engine/xmlform/tools/translationAdd.xml | 25 + .../engine/xmlform/tools/translationsList.xml | 33 + .../xmlform/tools/updateTranslation.xml | 29 + workflow/engine/xmlform/tracker/login.xml | 18 + .../tracker_AvailableCaseTrackerObjects.xml | 18 + .../tracker/tracker_AvailableStageTasks.xml | 14 + .../tracker/tracker_ConditionsEdit.xml | 74 + .../tracker/tracker_Configuration.html | 38 + .../xmlform/tracker/tracker_Configuration.xml | 96 + .../xmlform/tracker/tracker_DynaDocs.xml | 18 + .../xmlform/tracker/tracker_Inputdocs.xml | 20 + .../xmlform/tracker/tracker_Messages.xml | 27 + .../xmlform/tracker/tracker_MessagesView.xml | 32 + .../engine/xmlform/tracker/tracker_No.xml | 10 + .../xmlform/tracker/tracker_Outputdocs.xml | 18 + .../xmlform/tracker/tracker_StageEdit.xml | 32 + .../xmlform/tracker/tracker_StageTasks.xml | 12 + .../xmlform/tracker/tracker_TasksOptions.xml | 75 + .../tracker/tracker_TransferHistory.xml | 35 + .../tracker/tracker_ViewAnyInputDocument.xml | 24 + .../tracker/tracker_ViewAnyInputDocument1.xml | 47 + .../tracker/tracker_ViewAnyInputDocument2.xml | 44 + .../tracker/tracker_ViewAnyInputDocument3.xml | 52 + .../tracker/tracker_ViewAnyOutputDocument.xml | 28 + .../engine/xmlform/tracker/tracker_back.xml | 9 + .../xmlform/tracker/tracker_objectsList.xml | 28 + .../tracker/tracker_objectsOptions.xml | 104 + workflow/engine/xmlform/triggers/dynavars.xml | 22 + .../xmlform/triggers/triggersCustom.html | 60 + .../xmlform/triggers/triggersCustom.xml | 90 + .../xmlform/triggers/triggersNarrowEdit.html | 45 + .../xmlform/triggers/triggersNarrowEdit.xml | 87 + .../xmlform/triggers/triggersProperties.html | 47 + .../xmlform/triggers/triggersProperties.xml | 87 + .../xmlform/triggers/triggers_Edit.html | 42 + .../engine/xmlform/triggers/triggers_Edit.xml | 80 + .../xmlform/triggers/triggers_Options.xml | 148 + .../xmlform/triggers/triggers_ShortList.xml | 31 + .../engine/xmlform/triggers/wizardOptions.xml | 10 + workflow/engine/xmlform/users/myInfo.html | 119 + workflow/engine/xmlform/users/myInfo.xml | 246 + workflow/engine/xmlform/users/myInfo2.html | 111 + workflow/engine/xmlform/users/myInfo2.xml | 220 + .../engine/xmlform/users/myInfoOptions.xml | 14 + .../xmlform/users/myInfoOptionsView.xml | 14 + workflow/engine/xmlform/users/myInfoView.html | 108 + workflow/engine/xmlform/users/myInfoView.xml | 153 + .../engine/xmlform/users/myInfoView2.html | 108 + workflow/engine/xmlform/users/myInfoView2.xml | 148 + .../xmlform/users/users_AuthSource.html | 42 + .../engine/xmlform/users/users_AuthSource.xml | 49 + .../xmlform/users/users_AvailableUsers.xml | 12 + .../xmlform/users/users_DeleteAssign.xml | 25 + workflow/engine/xmlform/users/users_Edit.xml | 259 + .../engine/xmlform/users/users_EditAdmin.xml | 225 + .../xmlform/users/users_EditOptions.xml | 16 + .../engine/xmlform/users/users_EditRT.html | 153 + .../engine/xmlform/users/users_EditRT.xml | 282 + workflow/engine/xmlform/users/users_List.xml | 39 + workflow/engine/xmlform/users/users_New.html | 146 + workflow/engine/xmlform/users/users_New.xml | 337 + .../engine/xmlform/users/users_NewOptions.xml | 6 + .../engine/xmlform/users/users_Options.xml | 208 + .../xmlform/users/users_ReassignCases.xml | 18 + .../users/users_ReassignSelectSubType.html | 41 + .../users/users_ReassignSelectSubType.xml | 51 + .../users/users_ReassignSelectType.html | 35 + .../users/users_ReassignSelectType.xml | 46 + .../xmlform/users/users_ReassignShowInfo.xml | 50 + .../engine/xmlform/users/users_Search.xml | 12 + .../engine/xmlform/users/users_Searchx.xml | 9 + .../engine/xmlform/users/users_ShortList.xml | 12 + .../engine/xmlform/users/users_ShortList2.xml | 12 + .../xmlform/users/users_ShortListAdhoc.xml | 12 + .../xmlform/users/users_ShortOptions.xml | 82 + .../xmlform/users/users_ShortOptions2.xml | 70 + .../xmlform/users/users_ShortOptionsAdhoc.xml | 74 + workflow/engine/xmlform/users/users_View.xml | 130 + .../xmlform/users/users_ViewOptions.xml | 17 + workflow/public_html/images/1.png | Bin 0 -> 1266 bytes workflow/public_html/images/2.png | Bin 0 -> 1256 bytes workflow/public_html/images/3.png | Bin 0 -> 1256 bytes workflow/public_html/images/4.png | Bin 0 -> 1256 bytes workflow/public_html/images/50px-Edit.png | Bin 0 -> 6443 bytes .../public_html/images/50px-Edit_over.png | Bin 0 -> 6323 bytes workflow/public_html/images/Openreg.gif | Bin 0 -> 200 bytes .../images/PowerdbyProcessMaker.png | Bin 0 -> 9388 bytes workflow/public_html/images/Refresh.png | Bin 0 -> 2598 bytes workflow/public_html/images/activate.png | Bin 0 -> 750 bytes workflow/public_html/images/activity.gif | Bin 0 -> 6610 bytes .../public_html/images/activityanimation.gif | Bin 0 -> 1952 bytes .../public_html/images/add-user-32x32.png | Bin 0 -> 2356 bytes workflow/public_html/images/add.png | Bin 0 -> 400 bytes workflow/public_html/images/addc.png | Bin 0 -> 716 bytes workflow/public_html/images/addtext.png | Bin 0 -> 371 bytes workflow/public_html/images/ajax-loader.gif | Bin 0 -> 847 bytes workflow/public_html/images/alert.gif | Bin 0 -> 1277 bytes workflow/public_html/images/alert_icon.gif | Bin 0 -> 496 bytes .../public_html/images/app-delete-32x32.png | Bin 0 -> 1646 bytes .../public_html/images/app-edit-32x32.png | Bin 0 -> 1430 bytes workflow/public_html/images/arrow-down.gif | Bin 0 -> 176 bytes workflow/public_html/images/arrow-up.gif | Bin 0 -> 155 bytes .../public_html/images/arrow_order_asc.gif | Bin 0 -> 842 bytes .../public_html/images/arrow_order_desc.gif | Bin 0 -> 835 bytes workflow/public_html/images/back-24x24.png | Bin 0 -> 1609 bytes workflow/public_html/images/bg_ctaTooltip.png | Bin 0 -> 3617 bytes .../public_html/images/blueBackgroundMenu.jpg | Bin 0 -> 376 bytes workflow/public_html/images/borderTask.gif | Bin 0 -> 156 bytes workflow/public_html/images/browse.gif | Bin 0 -> 908 bytes workflow/public_html/images/btnGreen.gif | Bin 0 -> 875 bytes workflow/public_html/images/btnRed.gif | Bin 0 -> 875 bytes workflow/public_html/images/btnYellow.gif | Bin 0 -> 879 bytes workflow/public_html/images/bulletButton.gif | Bin 0 -> 112 bytes .../public_html/images/bulletButtonDown.gif | Bin 0 -> 121 bytes .../public_html/images/bulletButtonLeft.gif | Bin 0 -> 129 bytes .../public_html/images/bulletButtonUp.gif | Bin 0 -> 132 bytes workflow/public_html/images/bulletSubMenu.jpg | Bin 0 -> 286 bytes .../public_html/images/buttonBackground.png | Bin 0 -> 1704 bytes workflow/public_html/images/calendar/cal.gif | Bin 0 -> 127 bytes .../images/calendar/calendar-close.gif | Bin 0 -> 829 bytes .../calendar/calendar-dropdown-down.gif | Bin 0 -> 820 bytes .../images/calendar/calendar-dropdown-up.gif | Bin 0 -> 820 bytes .../images/calendar/calendar-next-month.gif | Bin 0 -> 823 bytes .../images/calendar/calendar-next-year.gif | Bin 0 -> 829 bytes .../calendar/calendar-previous-month.gif | Bin 0 -> 821 bytes .../calendar/calendar-previous-year.gif | Bin 0 -> 830 bytes .../images/calendar/calendar_heading.png | Bin 0 -> 187 bytes workflow/public_html/images/calendar/next.gif | Bin 0 -> 214 bytes .../public_html/images/calendar/next_year.gif | Bin 0 -> 256 bytes .../public_html/images/calendar/pixel.gif | Bin 0 -> 67 bytes workflow/public_html/images/calendar/prev.gif | Bin 0 -> 212 bytes .../public_html/images/calendar/prev_year.gif | Bin 0 -> 259 bytes workflow/public_html/images/cases-admin.png | Bin 0 -> 675 bytes .../public_html/images/cases-cancelled.png | Bin 0 -> 785 bytes .../public_html/images/cases-completed1.png | Bin 0 -> 765 bytes .../public_html/images/cases-documents.png | Bin 0 -> 354 bytes workflow/public_html/images/cases-draft.png | Bin 0 -> 844 bytes workflow/public_html/images/cases-folders.png | Bin 0 -> 693 bytes workflow/public_html/images/cases-inbox.png | Bin 0 -> 580 bytes workflow/public_html/images/cases-outbox.png | Bin 0 -> 576 bytes workflow/public_html/images/cases-paused.png | Bin 0 -> 731 bytes .../public_html/images/cases-reassing.png | Bin 0 -> 809 bytes workflow/public_html/images/cases-search.png | Bin 0 -> 754 bytes .../public_html/images/cases-selfservice.png | Bin 0 -> 914 bytes .../public_html/images/cases_torevise.png | Bin 0 -> 746 bytes workflow/public_html/images/charts.swf | Bin 0 -> 81768 bytes workflow/public_html/images/checked.gif | Bin 0 -> 908 bytes workflow/public_html/images/cinco.gif | Bin 0 -> 677 bytes workflow/public_html/images/closereg.gif | Bin 0 -> 200 bytes workflow/public_html/images/cross.gif | Bin 0 -> 560 bytes workflow/public_html/images/cuatro.gif | Bin 0 -> 681 bytes workflow/public_html/images/date.gif | Bin 0 -> 94 bytes workflow/public_html/images/deactivate.png | Bin 0 -> 700 bytes workflow/public_html/images/delete-16x16.gif | Bin 0 -> 275 bytes workflow/public_html/images/delete-icon.jpg | Bin 0 -> 2316 bytes workflow/public_html/images/delete-icon.png | Bin 0 -> 1235 bytes .../public_html/images/delete-user-32x32.png | Bin 0 -> 2455 bytes workflow/public_html/images/delete.png | Bin 0 -> 248 bytes workflow/public_html/images/delete_rules.png | Bin 0 -> 363 bytes workflow/public_html/images/der.png | Bin 0 -> 1275 bytes workflow/public_html/images/dialog-cancel.png | Bin 0 -> 2207 bytes .../public_html/images/dialog-ok-apply.png | Bin 0 -> 1218 bytes workflow/public_html/images/doc.gif | Bin 0 -> 653 bytes .../public_html/images/document-revert.png | Bin 0 -> 1703 bytes .../public_html/images/document-review.png | Bin 0 -> 2000 bytes workflow/public_html/images/dos.gif | Bin 0 -> 677 bytes workflow/public_html/images/dynaforms.gif | Bin 0 -> 402 bytes .../public_html/images/dynamicForm/.directory | 5 + .../public_html/images/dynamicForm/button.gif | Bin 0 -> 395 bytes .../public_html/images/dynamicForm/button.jpg | Bin 0 -> 575 bytes .../images/dynamicForm/button_on.jpg | Bin 0 -> 937 bytes .../images/dynamicForm/check_group.gif | Bin 0 -> 377 bytes .../images/dynamicForm/check_group.jpg | Bin 0 -> 699 bytes .../images/dynamicForm/check_group_on.jpg | Bin 0 -> 946 bytes .../images/dynamicForm/checkbox.gif | Bin 0 -> 429 bytes .../images/dynamicForm/checkbox.jpg | Bin 0 -> 637 bytes .../images/dynamicForm/checkbox_on.jpg | Bin 0 -> 952 bytes .../images/dynamicForm/currency.gif | Bin 0 -> 446 bytes .../images/dynamicForm/currency.jpg | Bin 0 -> 791 bytes .../images/dynamicForm/currency_on.jpg | Bin 0 -> 1021 bytes .../public_html/images/dynamicForm/date.gif | Bin 0 -> 314 bytes .../public_html/images/dynamicForm/date.jpg | Bin 0 -> 776 bytes .../images/dynamicForm/date_on.jpg | Bin 0 -> 991 bytes .../images/dynamicForm/dropdown.gif | Bin 0 -> 405 bytes .../images/dynamicForm/dropdown.jpg | Bin 0 -> 637 bytes .../images/dynamicForm/dropdown_on.jpg | Bin 0 -> 923 bytes .../public_html/images/dynamicForm/grid.gif | Bin 0 -> 923 bytes .../public_html/images/dynamicForm/grid.jpg | Bin 0 -> 670 bytes .../images/dynamicForm/grid_on.jpg | Bin 0 -> 945 bytes .../public_html/images/dynamicForm/hidden.gif | Bin 0 -> 188 bytes .../public_html/images/dynamicForm/hidden.jpg | Bin 0 -> 596 bytes .../images/dynamicForm/hidden_on.jpg | Bin 0 -> 913 bytes .../public_html/images/dynamicForm/hover.gif | Bin 0 -> 560 bytes .../images/dynamicForm/javascript.gif | Bin 0 -> 157 bytes .../images/dynamicForm/javascript.jpg | Bin 0 -> 573 bytes .../images/dynamicForm/javascript_on.jpg | Bin 0 -> 970 bytes .../public_html/images/dynamicForm/link.gif | Bin 0 -> 650 bytes .../public_html/images/dynamicForm/link.jpg | Bin 0 -> 558 bytes .../images/dynamicForm/link_on.jpg | Bin 0 -> 907 bytes .../images/dynamicForm/list_box.gif | Bin 0 -> 420 bytes .../images/dynamicForm/list_box.jpg | Bin 0 -> 667 bytes .../images/dynamicForm/list_box_on.jpg | Bin 0 -> 890 bytes .../images/dynamicForm/password.gif | Bin 0 -> 192 bytes .../images/dynamicForm/password.jpg | Bin 0 -> 738 bytes .../images/dynamicForm/password_on.jpg | Bin 0 -> 1034 bytes .../images/dynamicForm/percentage.gif | Bin 0 -> 420 bytes .../images/dynamicForm/percentage.jpg | Bin 0 -> 780 bytes .../images/dynamicForm/percentage_on.jpg | Bin 0 -> 1024 bytes .../images/dynamicForm/radio_group.gif | Bin 0 -> 425 bytes .../images/dynamicForm/radio_group.jpg | Bin 0 -> 618 bytes .../images/dynamicForm/radio_group_on.jpg | Bin 0 -> 989 bytes .../public_html/images/dynamicForm/reset.gif | Bin 0 -> 383 bytes .../public_html/images/dynamicForm/reset.jpg | Bin 0 -> 544 bytes .../images/dynamicForm/reset_on.jpg | Bin 0 -> 890 bytes .../public_html/images/dynamicForm/save.gif | Bin 0 -> 998 bytes .../public_html/images/dynamicForm/save.jpg | Bin 0 -> 849 bytes .../images/dynamicForm/save_as.gif | Bin 0 -> 325 bytes .../images/dynamicForm/save_on.jpg | Bin 0 -> 1009 bytes .../images/dynamicForm/separator.jpg | Bin 0 -> 8763 bytes .../public_html/images/dynamicForm/submit.gif | Bin 0 -> 388 bytes .../public_html/images/dynamicForm/submit.jpg | Bin 0 -> 552 bytes .../images/dynamicForm/submit_on.jpg | Bin 0 -> 893 bytes .../images/dynamicForm/subtitle.gif | Bin 0 -> 257 bytes .../images/dynamicForm/subtitle.jpg | Bin 0 -> 625 bytes .../images/dynamicForm/subtitle_on.jpg | Bin 0 -> 1014 bytes .../images/dynamicForm/suggest.gif | Bin 0 -> 1144 bytes .../images/dynamicForm/suggest.jpg | Bin 0 -> 473 bytes .../public_html/images/dynamicForm/text.gif | Bin 0 -> 186 bytes .../public_html/images/dynamicForm/text.jpg | Bin 0 -> 698 bytes .../images/dynamicForm/text_on.jpg | Bin 0 -> 1001 bytes .../images/dynamicForm/textarea.gif | Bin 0 -> 1197 bytes .../images/dynamicForm/textarea.jpg | Bin 0 -> 619 bytes .../images/dynamicForm/textarea_on.jpg | Bin 0 -> 866 bytes .../public_html/images/dynamicForm/title.gif | Bin 0 -> 97 bytes .../public_html/images/dynamicForm/title.jpg | Bin 0 -> 579 bytes .../images/dynamicForm/title_on.jpg | Bin 0 -> 945 bytes .../images/dynamicForm/toolbar.buttonbg.gif | Bin 0 -> 829 bytes .../images/dynamicForm/upload_files.gif | Bin 0 -> 459 bytes .../images/dynamicForm/upload_files.jpg | Bin 0 -> 617 bytes .../images/dynamicForm/upload_files_on.jpg | Bin 0 -> 932 bytes .../public_html/images/dynamicForm/yes_no.gif | Bin 0 -> 686 bytes .../public_html/images/dynamicForm/yes_no.jpg | Bin 0 -> 668 bytes .../images/dynamicForm/yes_no_on.jpg | Bin 0 -> 955 bytes workflow/public_html/images/dynavars.png | Bin 0 -> 6289 bytes workflow/public_html/images/e-loader.gif | Bin 0 -> 7322 bytes workflow/public_html/images/e_Delete.png | Bin 0 -> 1131 bytes workflow/public_html/images/e_Edit.png | Bin 0 -> 3070 bytes .../public_html/images/edit-clear-list.png | Bin 0 -> 2093 bytes workflow/public_html/images/edit.gif | Bin 0 -> 681 bytes workflow/public_html/images/edit.png | Bin 0 -> 1975 bytes .../public_html/images/event_conditional.png | Bin 0 -> 1276 bytes workflow/public_html/images/event_message.png | Bin 0 -> 1575 bytes .../public_html/images/event_multiple.png | Bin 0 -> 1574 bytes workflow/public_html/images/events.gif | Bin 0 -> 1167 bytes workflow/public_html/images/export.png | Bin 0 -> 744 bytes .../public_html/images/expressinstall.swf | Bin 0 -> 4823 bytes workflow/public_html/images/favicon.ico | Bin 0 -> 1150 bytes workflow/public_html/images/file-archiver.png | Bin 0 -> 1718 bytes workflow/public_html/images/firstPage.gif | Bin 0 -> 384 bytes workflow/public_html/images/flags/ad.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/ae.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/af.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/ag.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/ai.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/al.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/am.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/an.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/ao.gif | Bin 0 -> 244 bytes workflow/public_html/images/flags/ar.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/as.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/at.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/au.gif | Bin 0 -> 378 bytes workflow/public_html/images/flags/aw.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/ax.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/az.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/ba.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/bb.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/bd.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/be.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/bf.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/bg.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/bh.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/bi.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/bj.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/bm.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/bn.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/bo.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/br.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/bs.gif | Bin 0 -> 351 bytes workflow/public_html/images/flags/bt.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/bv.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/bw.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/by.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/bz.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/ca.gif | Bin 0 -> 376 bytes .../public_html/images/flags/catalonia.gif | Bin 0 -> 238 bytes workflow/public_html/images/flags/cc.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/cd.gif | Bin 0 -> 243 bytes workflow/public_html/images/flags/cf.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/cg.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/ch.gif | Bin 0 -> 332 bytes workflow/public_html/images/flags/ci.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/ck.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/cl.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/cm.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/cn.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/co.gif | Bin 0 -> 353 bytes workflow/public_html/images/flags/cr.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/cs.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/cu.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/cv.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/cx.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/cy.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/cz.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/da.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/de.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/dj.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/dk.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/dm.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/do.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/dz.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/ec.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/ee.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/eg.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/eh.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/en.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/england.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/er.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/es.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/et.gif | Bin 0 -> 364 bytes .../images/flags/europeanunion.gif | Bin 0 -> 171 bytes workflow/public_html/images/flags/fam.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/fi.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/fj.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/fk.gif | Bin 0 -> 372 bytes workflow/public_html/images/flags/fm.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/fo.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/fr.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/ga.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/gb.gif | Bin 0 -> 260 bytes workflow/public_html/images/flags/gd.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/ge.gif | Bin 0 -> 379 bytes workflow/public_html/images/flags/gf.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/gh.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/gi.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/gl.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/gm.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/gn.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/gp.gif | Bin 0 -> 357 bytes workflow/public_html/images/flags/gq.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/gr.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/gs.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/gt.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/gu.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/gw.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/gy.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/he.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/hk.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/hm.gif | Bin 0 -> 378 bytes workflow/public_html/images/flags/hn.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/hr.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/ht.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/hu.gif | Bin 0 -> 357 bytes workflow/public_html/images/flags/id.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/ie.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/il.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/in.gif | Bin 0 -> 363 bytes .../images/flags/international.png | Bin 0 -> 816 bytes workflow/public_html/images/flags/io.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/iq.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/ir.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/is.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/it.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/iw.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/jm.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/jo.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/jp.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/ke.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/kg.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/kh.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/ki.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/km.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/kn.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/kp.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/kr.gif | Bin 0 -> 385 bytes workflow/public_html/images/flags/kw.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/ky.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/kz.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/la.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/lb.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/lc.gif | Bin 0 -> 259 bytes workflow/public_html/images/flags/li.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/lk.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/lr.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/ls.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/lt.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/lu.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/lv.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/ly.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/ma.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/mc.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/md.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/me.gif | Bin 0 -> 238 bytes workflow/public_html/images/flags/mg.gif | Bin 0 -> 372 bytes workflow/public_html/images/flags/mh.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/mk.gif | Bin 0 -> 382 bytes workflow/public_html/images/flags/ml.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/mm.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/mn.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/mo.gif | Bin 0 -> 378 bytes workflow/public_html/images/flags/mp.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/mq.gif | Bin 0 -> 379 bytes workflow/public_html/images/flags/mr.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/ms.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/mt.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/mu.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/mv.gif | Bin 0 -> 372 bytes workflow/public_html/images/flags/mw.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/mx.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/my.gif | Bin 0 -> 375 bytes workflow/public_html/images/flags/mz.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/na.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/nc.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/ne.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/nf.gif | Bin 0 -> 375 bytes workflow/public_html/images/flags/ng.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/ni.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/nl.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/no.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/np.gif | Bin 0 -> 302 bytes workflow/public_html/images/flags/nr.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/nu.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/nz.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/om.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/pa.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/pe.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/pf.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/pg.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/ph.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/pk.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/pl.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/pm.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/pn.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/pr.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/ps.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/pt.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/pw.gif | Bin 0 -> 374 bytes workflow/public_html/images/flags/py.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/qa.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/re.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/ro.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/rs.gif | Bin 0 -> 238 bytes workflow/public_html/images/flags/ru.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/rw.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/sa.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/sb.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/sc.gif | Bin 0 -> 357 bytes .../public_html/images/flags/scotland.gif | Bin 0 -> 378 bytes workflow/public_html/images/flags/sd.gif | Bin 0 -> 355 bytes workflow/public_html/images/flags/se.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/sg.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/sh.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/si.gif | Bin 0 -> 362 bytes workflow/public_html/images/flags/sj.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/sk.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/sl.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/sm.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/sn.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/so.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/sr.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/st.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/sv.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/sy.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/sz.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/tc.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/td.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/tf.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/tg.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/th.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/tj.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/tk.gif | Bin 0 -> 372 bytes workflow/public_html/images/flags/tl.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/tm.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/tn.gif | Bin 0 -> 375 bytes workflow/public_html/images/flags/to.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/tr.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/tt.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/tv.gif | Bin 0 -> 361 bytes workflow/public_html/images/flags/tw.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/tz.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/ua.gif | Bin 0 -> 360 bytes workflow/public_html/images/flags/ug.gif | Bin 0 -> 359 bytes workflow/public_html/images/flags/um.gif | Bin 0 -> 371 bytes workflow/public_html/images/flags/us.gif | Bin 0 -> 367 bytes workflow/public_html/images/flags/uy.gif | Bin 0 -> 373 bytes workflow/public_html/images/flags/uz.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/va.gif | Bin 0 -> 369 bytes workflow/public_html/images/flags/vc.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/ve.gif | Bin 0 -> 364 bytes workflow/public_html/images/flags/vg.gif | Bin 0 -> 368 bytes workflow/public_html/images/flags/vi.gif | Bin 0 -> 376 bytes workflow/public_html/images/flags/vn.gif | Bin 0 -> 370 bytes workflow/public_html/images/flags/vu.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/wales.gif | Bin 0 -> 372 bytes workflow/public_html/images/flags/wf.gif | Bin 0 -> 377 bytes workflow/public_html/images/flags/ws.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/ye.gif | Bin 0 -> 356 bytes workflow/public_html/images/flags/yt.gif | Bin 0 -> 382 bytes workflow/public_html/images/flags/za.gif | Bin 0 -> 363 bytes workflow/public_html/images/flags/zh-cn.gif | Bin 0 -> 366 bytes workflow/public_html/images/flags/zh-tw.gif | Bin 0 -> 365 bytes workflow/public_html/images/flags/zm.gif | Bin 0 -> 358 bytes workflow/public_html/images/flags/zw.gif | Bin 0 -> 365 bytes workflow/public_html/images/flecha.png | Bin 0 -> 1371 bytes workflow/public_html/images/flechav1A.png | Bin 0 -> 324 bytes workflow/public_html/images/flechv1V.png | Bin 0 -> 349 bytes workflow/public_html/images/folder.gif | Bin 0 -> 264 bytes workflow/public_html/images/folderV2.gif | Bin 0 -> 243 bytes workflow/public_html/images/fondo.jpg | Bin 0 -> 315 bytes workflow/public_html/images/fondo.png | Bin 0 -> 1249 bytes workflow/public_html/images/fondotask.png | Bin 0 -> 1795 bytes workflow/public_html/images/form.gif | Bin 0 -> 990 bytes workflow/public_html/images/ftv2blank.gif | Bin 0 -> 135 bytes workflow/public_html/images/ftv2doc.gif | Bin 0 -> 895 bytes workflow/public_html/images/ftv2lastnode.gif | Bin 0 -> 142 bytes workflow/public_html/images/ftv2mlastnode.gif | Bin 0 -> 125 bytes workflow/public_html/images/ftv2mnode.gif | Bin 0 -> 97 bytes workflow/public_html/images/ftv2node.gif | Bin 0 -> 147 bytes .../public_html/images/ftv2nodeSimple.gif | Bin 0 -> 93 bytes workflow/public_html/images/ftv2pnode.gif | Bin 0 -> 878 bytes workflow/public_html/images/ftv2vertline.gif | Bin 0 -> 140 bytes workflow/public_html/images/gear.png | Bin 0 -> 20152 bytes workflow/public_html/images/gears.gif | Bin 0 -> 34083 bytes workflow/public_html/images/get_started.png | Bin 0 -> 65258 bytes workflow/public_html/images/go-lt-off.gif | Bin 0 -> 246 bytes workflow/public_html/images/go-lt-on.gif | Bin 0 -> 247 bytes workflow/public_html/images/go-rt-off.gif | Bin 0 -> 246 bytes workflow/public_html/images/go-rt-on.gif | Bin 0 -> 246 bytes workflow/public_html/images/green-folder.png | Bin 0 -> 2473 bytes workflow/public_html/images/group_add.png | Bin 0 -> 936 bytes workflow/public_html/images/heartBeat.jpg | Bin 0 -> 1338 bytes workflow/public_html/images/help4.gif | Bin 0 -> 318 bytes workflow/public_html/images/help5.gif | Bin 0 -> 13259 bytes .../images/icon-arrows-arrow-left.png | Bin 0 -> 2064 bytes .../images/icon-arrows-arrow-right.png | Bin 0 -> 2078 bytes .../public_html/images/icon-authSources.png | Bin 0 -> 52220 bytes workflow/public_html/images/icon-calendar.png | Bin 0 -> 1218 bytes .../public_html/images/icon-cases-inbox.png | Bin 0 -> 3449 bytes .../public_html/images/icon-cases-outbox.png | Bin 0 -> 3364 bytes workflow/public_html/images/icon-config.png | Bin 0 -> 1491 bytes .../public_html/images/icon-departments.png | Bin 0 -> 50463 bytes .../images/icon-email-settings.png | Bin 0 -> 904 bytes workflow/public_html/images/icon-groups.png | Bin 0 -> 50839 bytes workflow/public_html/images/icon-language.png | Bin 0 -> 1574 bytes .../public_html/images/icon-languages.png | Bin 0 -> 717 bytes .../public_html/images/icon-logs-list.png | Bin 0 -> 319 bytes workflow/public_html/images/icon-plugins.png | Bin 0 -> 1763 bytes .../images/icon-pmappcacheview-rebuild.png | Bin 0 -> 703 bytes .../public_html/images/icon-pmcalendar.png | Bin 0 -> 945 bytes .../images/icon-pmcaselist-conf.png | Bin 0 -> 697 bytes .../images/icon-pmcaselist-setup.png | Bin 0 -> 760 bytes .../images/icon-pmcaseslist-conf.png | Bin 0 -> 760 bytes .../public_html/images/icon-pmclear-cache.png | Bin 0 -> 951 bytes .../public_html/images/icon-pmlogo-15x15.png | Bin 0 -> 957 bytes workflow/public_html/images/icon-pmlogo.png | Bin 0 -> 2809 bytes workflow/public_html/images/icon-pmlogs.png | Bin 0 -> 319 bytes .../public_html/images/icon-pmmail-conf.png | Bin 0 -> 658 bytes .../public_html/images/icon-pmmailconf.png | Bin 0 -> 1024 bytes .../public_html/images/icon-pmplugins.png | Bin 0 -> 893 bytes .../images/icon-pmprocess-category.png | Bin 0 -> 233 bytes workflow/public_html/images/icon-pmskins.png | Bin 0 -> 851 bytes workflow/public_html/images/icon-pmtables.png | Bin 0 -> 723 bytes .../public_html/images/icon-pmupgrade.png | Bin 0 -> 1076 bytes .../public_html/images/icon-pmwebservices.png | Bin 0 -> 1006 bytes .../public_html/images/icon-rebuild-clean.png | Bin 0 -> 2489 bytes workflow/public_html/images/icon-roles.png | Bin 0 -> 51610 bytes workflow/public_html/images/icon-skins.png | Bin 0 -> 1703 bytes .../images/icon-system-upgrade.png | Bin 0 -> 2588 bytes workflow/public_html/images/icon-tables.png | Bin 0 -> 1192 bytes workflow/public_html/images/icon-users.png | Bin 0 -> 51132 bytes .../public_html/images/icon-webservices.png | Bin 0 -> 2445 bytes workflow/public_html/images/icon.trigger.png | Bin 0 -> 2339 bytes workflow/public_html/images/iconoenlace.png | Bin 0 -> 2148 bytes .../images/icons_silk/calendar_x_button.png | Bin 0 -> 48177 bytes .../public_html/images/icons_silk/checked.png | Bin 0 -> 618 bytes .../images/icons_silk/search_x_button.png | Bin 0 -> 620 bytes .../public_html/images/icons_silk/sprite.css | 1145 + .../images/icons_silk/sprite_ie.css | 5 + .../images/icons_silk/sprites.gif.png | Bin 0 -> 66905 bytes .../public_html/images/icons_silk/sprites.png | Bin 0 -> 250061 bytes .../images/icons_silk/unchecked.png | Bin 0 -> 468 bytes workflow/public_html/images/import.gif | Bin 0 -> 969 bytes workflow/public_html/images/inf.png | Bin 0 -> 1275 bytes workflow/public_html/images/inputdocument.gif | Bin 0 -> 417 bytes workflow/public_html/images/izp.png | Bin 0 -> 1275 bytes workflow/public_html/images/kcmdf.png | Bin 0 -> 1414 bytes .../public_html/images/language-selected.png | Bin 0 -> 829 bytes workflow/public_html/images/lastPage.gif | Bin 0 -> 284 bytes workflow/public_html/images/linhori.png | Bin 0 -> 77 bytes workflow/public_html/images/linver.png | Bin 0 -> 84 bytes workflow/public_html/images/loader-gears.gif | Bin 0 -> 22004 bytes workflow/public_html/images/loading-gears.gif | Bin 0 -> 19386 bytes workflow/public_html/images/lock.png | Bin 0 -> 1052 bytes .../public_html/images/logo_processmaker.gif | Bin 0 -> 2130 bytes .../public_html/images/mail-mark-task.png | Bin 0 -> 1995 bytes .../public_html/images/mail-message-new.png | Bin 0 -> 1258 bytes workflow/public_html/images/mail-queue.png | Bin 0 -> 1740 bytes workflow/public_html/images/mail-send.png | Bin 0 -> 4267 bytes workflow/public_html/images/mail.gif | Bin 0 -> 277 bytes .../public_html/images/masterDetailMain.png | Bin 0 -> 410 bytes .../public_html/images/masterDetailOther.png | Bin 0 -> 2887 bytes workflow/public_html/images/minus.gif | Bin 0 -> 868 bytes workflow/public_html/images/newSkin/bf.jpg | Bin 0 -> 318 bytes workflow/public_html/images/newSkin/bm.jpg | Bin 0 -> 328 bytes workflow/public_html/images/newSkin/bsm.jpg | Bin 0 -> 292 bytes workflow/public_html/images/newSkin/bsms.jpg | Bin 0 -> 323 bytes .../public_html/images/newSkin/fbc.blue.png | Bin 0 -> 1242 bytes workflow/public_html/images/newSkin/fbc.png | Bin 0 -> 40655 bytes .../public_html/images/newSkin/fbl.blue.png | Bin 0 -> 1343 bytes workflow/public_html/images/newSkin/fbl.png | Bin 0 -> 41148 bytes .../public_html/images/newSkin/fbr.blue.png | Bin 0 -> 1358 bytes workflow/public_html/images/newSkin/fbr.png | Bin 0 -> 41152 bytes .../images/newSkin/frame.full.bottom.png | Bin 0 -> 578 bytes .../images/newSkin/frame.full.top.png | Bin 0 -> 240 bytes .../images/newSkin/frame.home.bottom.png | Bin 0 -> 557 bytes .../images/newSkin/frame.right.bottom.png | Bin 0 -> 43095 bytes .../images/newSkin/frame.right.top.gif | Bin 0 -> 197 bytes workflow/public_html/images/newSkin/ftc.png | Bin 0 -> 621 bytes .../public_html/images/newSkin/ftl.blue.gif | Bin 0 -> 64 bytes workflow/public_html/images/newSkin/ftl.png | Bin 0 -> 219 bytes workflow/public_html/images/newSkin/ftlL.png | Bin 0 -> 289 bytes .../public_html/images/newSkin/ftr.blue.gif | Bin 0 -> 64 bytes workflow/public_html/images/newSkin/ftr.png | Bin 0 -> 216 bytes workflow/public_html/images/newSkin/ftrL.png | Bin 0 -> 1641 bytes .../public_html/images/newSkin/input_back.gif | Bin 0 -> 44 bytes workflow/public_html/images/nextPage.gif | Bin 0 -> 277 bytes .../public_html/images/object_permission.gif | Bin 0 -> 1051 bytes workflow/public_html/images/ok.png | Bin 0 -> 23144 bytes workflow/public_html/images/onmouse.png | Bin 0 -> 43150 bytes workflow/public_html/images/onmouseSilver.jpg | Bin 0 -> 296 bytes workflow/public_html/images/options.png | Bin 0 -> 900 bytes .../public_html/images/outputdocument.gif | Bin 0 -> 416 bytes workflow/public_html/images/panel_title.jpg | Bin 0 -> 359 bytes workflow/public_html/images/panel_title2.jpg | Bin 0 -> 326 bytes workflow/public_html/images/pin-dn-off.gif | Bin 0 -> 251 bytes workflow/public_html/images/pin-dn-on.gif | Bin 0 -> 252 bytes workflow/public_html/images/pin-up-off.gif | Bin 0 -> 237 bytes workflow/public_html/images/pin-up-on.gif | Bin 0 -> 241 bytes workflow/public_html/images/plus-blue.png | Bin 0 -> 3287 bytes workflow/public_html/images/plus.gif | Bin 0 -> 878 bytes workflow/public_html/images/plus_red.gif | Bin 0 -> 106 bytes workflow/public_html/images/pm.gif | Bin 0 -> 1074 bytes workflow/public_html/images/pmdate.png | Bin 0 -> 2193 bytes workflow/public_html/images/pmdateicon.png | Bin 0 -> 3476 bytes workflow/public_html/images/pmdateiw.png | Bin 0 -> 2355 bytes workflow/public_html/images/pmdatetime.png | Bin 0 -> 2815 bytes workflow/public_html/images/pmdatetimeiw.png | Bin 0 -> 3034 bytes workflow/public_html/images/previousPage.gif | Bin 0 -> 271 bytes workflow/public_html/images/printer.png | Bin 0 -> 3255 bytes .../public_html/images/processmaker.logo.jpg | Bin 0 -> 15731 bytes .../images/processmap/contract.gif | Bin 0 -> 91 bytes workflow/public_html/images/properties.png | Bin 0 -> 42987 bytes workflow/public_html/images/reassing.png | Bin 0 -> 2242 bytes workflow/public_html/images/refresh.gif | Bin 0 -> 570 bytes workflow/public_html/images/report_tables.gif | Bin 0 -> 405 bytes workflow/public_html/images/resizable-e.gif | Bin 0 -> 65 bytes workflow/public_html/images/resizable.gif | Bin 0 -> 330 bytes .../public_html/images/resource-group.png | Bin 0 -> 1823 bytes workflow/public_html/images/reviewed.png | Bin 0 -> 1797 bytes workflow/public_html/images/rotate_cw.png | Bin 0 -> 1817 bytes .../public_html/images/rotate_cw_green.png | Bin 0 -> 1859 bytes workflow/public_html/images/row_down.png | Bin 0 -> 1164 bytes workflow/public_html/images/rules.png | Bin 0 -> 233 bytes .../public_html/images/run-build-file.png | Bin 0 -> 1649 bytes workflow/public_html/images/scheduler.png | Bin 0 -> 1059 bytes workflow/public_html/images/select-icon.png | Bin 0 -> 1350 bytes workflow/public_html/images/separator-v.gif | Bin 0 -> 67 bytes workflow/public_html/images/steps.png | Bin 0 -> 239 bytes workflow/public_html/images/styles/red/bm.jpg | Bin 0 -> 707 bytes .../public_html/images/styles/red/bsms.jpg | Bin 0 -> 1186 bytes workflow/public_html/images/subProcess.png | Bin 0 -> 988 bytes workflow/public_html/images/subp.png | Bin 0 -> 3441 bytes workflow/public_html/images/sup.png | Bin 0 -> 1275 bytes workflow/public_html/images/system-search.png | Bin 0 -> 2584 bytes workflow/public_html/images/task.gif | Bin 0 -> 979 bytes workflow/public_html/images/toadd.png | Bin 0 -> 50814 bytes workflow/public_html/images/tool.jpeg | Bin 0 -> 1024 bytes .../public_html/images/toolbarBackground.jpg | Bin 0 -> 3345 bytes workflow/public_html/images/tracker.gif | Bin 0 -> 1174 bytes workflow/public_html/images/trash.gif | Bin 0 -> 872 bytes workflow/public_html/images/tres.gif | Bin 0 -> 671 bytes workflow/public_html/images/trigger.gif | Bin 0 -> 310 bytes .../triggers/Google_Calendar_normal.png | Bin 0 -> 884 bytes .../images/triggers/TalendOpenStudio.gif | Bin 0 -> 1300 bytes .../images/triggers/icon_SugarCRM.gif | Bin 0 -> 850 bytes .../ui-bg_gloss-wave_55_5c9ccc_500x100.png | Bin 0 -> 3457 bytes workflow/public_html/images/unchecked.gif | Bin 0 -> 888 bytes workflow/public_html/images/unknown_icon.gif | Bin 0 -> 808 bytes workflow/public_html/images/unlock.png | Bin 0 -> 2036 bytes workflow/public_html/images/uno.gif | Bin 0 -> 445 bytes workflow/public_html/images/user-id-32x32.png | Bin 0 -> 2248 bytes workflow/public_html/images/user.gif | Bin 0 -> 3750 bytes workflow/public_html/images/users.png | Bin 0 -> 1145 bytes .../images/yellowBackgroundMenu.jpg | Bin 0 -> 349 bytes .../images/yellowBackgroundSubMenu.jpg | Bin 0 -> 339 bytes workflow/public_html/index.html | 8 + workflow/public_html/skins/JSForms.js | 496 + workflow/public_html/skins/ajax.js | 128 + .../public_html/skins/ext/ext-all-notheme.css | 5150 +++ workflow/public_html/skins/ext/ext-all.css | 6789 ++++ .../ext/images/default/box/corners-blue.gif | Bin 0 -> 1010 bytes .../skins/ext/images/default/box/corners.gif | Bin 0 -> 1005 bytes .../skins/ext/images/default/box/l-blue.gif | Bin 0 -> 810 bytes .../skins/ext/images/default/box/l.gif | Bin 0 -> 810 bytes .../skins/ext/images/default/box/r-blue.gif | Bin 0 -> 810 bytes .../skins/ext/images/default/box/r.gif | Bin 0 -> 810 bytes .../skins/ext/images/default/box/tb-blue.gif | Bin 0 -> 851 bytes .../skins/ext/images/default/box/tb.gif | Bin 0 -> 839 bytes .../skins/ext/images/default/button/arrow.gif | Bin 0 -> 828 bytes .../skins/ext/images/default/button/btn.gif | Bin 0 -> 4298 bytes .../skins/ext/images/default/button/btn2.gif | Bin 0 -> 8783 bytes .../ext/images/default/button/group-cs.gif | Bin 0 -> 2459 bytes .../ext/images/default/button/group-lr.gif | Bin 0 -> 861 bytes .../ext/images/default/button/group-tb.gif | Bin 0 -> 846 bytes .../default/button/s-arrow-b-noline.gif | Bin 0 -> 898 bytes .../ext/images/default/button/s-arrow-b.gif | Bin 0 -> 937 bytes .../ext/images/default/button/s-arrow-bo.gif | Bin 0 -> 139 bytes .../images/default/button/s-arrow-noline.gif | Bin 0 -> 863 bytes .../ext/images/default/button/s-arrow-o.gif | Bin 0 -> 937 bytes .../ext/images/default/button/s-arrow.gif | Bin 0 -> 937 bytes .../skins/ext/images/default/dd/drop-add.gif | Bin 0 -> 1001 bytes .../skins/ext/images/default/dd/drop-no.gif | Bin 0 -> 949 bytes .../skins/ext/images/default/dd/drop-yes.gif | Bin 0 -> 1016 bytes .../ext/images/default/editor/tb-sprite.gif | Bin 0 -> 2072 bytes .../ext/images/default/form/checkbox.gif | Bin 0 -> 2061 bytes .../ext/images/default/form/clear-trigger.gif | Bin 0 -> 1988 bytes .../ext/images/default/form/clear-trigger.psd | Bin 0 -> 11804 bytes .../ext/images/default/form/date-trigger.gif | Bin 0 -> 1603 bytes .../ext/images/default/form/date-trigger.psd | Bin 0 -> 12377 bytes .../images/default/form/error-tip-corners.gif | Bin 0 -> 4183 bytes .../ext/images/default/form/exclamation.gif | Bin 0 -> 996 bytes .../skins/ext/images/default/form/radio.gif | Bin 0 -> 1746 bytes .../images/default/form/search-trigger.gif | Bin 0 -> 2182 bytes .../images/default/form/search-trigger.psd | Bin 0 -> 15601 bytes .../skins/ext/images/default/form/text-bg.gif | Bin 0 -> 819 bytes .../images/default/form/trigger-square.gif | Bin 0 -> 1810 bytes .../images/default/form/trigger-square.psd | Bin 0 -> 36542 bytes .../ext/images/default/form/trigger-tpl.gif | Bin 0 -> 1487 bytes .../skins/ext/images/default/form/trigger.gif | Bin 0 -> 1816 bytes .../skins/ext/images/default/form/trigger.psd | Bin 0 -> 37599 bytes .../skins/ext/images/default/gradient-bg.gif | Bin 0 -> 1472 bytes .../images/default/grid/arrow-left-white.gif | Bin 0 -> 825 bytes .../images/default/grid/arrow-right-white.gif | Bin 0 -> 825 bytes .../images/default/grid/col-move-bottom.gif | Bin 0 -> 868 bytes .../ext/images/default/grid/col-move-top.gif | Bin 0 -> 869 bytes .../skins/ext/images/default/grid/columns.gif | Bin 0 -> 962 bytes .../skins/ext/images/default/grid/dirty.gif | Bin 0 -> 832 bytes .../skins/ext/images/default/grid/done.gif | Bin 0 -> 133 bytes .../skins/ext/images/default/grid/drop-no.gif | Bin 0 -> 947 bytes .../ext/images/default/grid/drop-yes.gif | Bin 0 -> 860 bytes .../ext/images/default/grid/footer-bg.gif | Bin 0 -> 834 bytes .../ext/images/default/grid/grid-blue-hd.gif | Bin 0 -> 829 bytes .../images/default/grid/grid-blue-split.gif | Bin 0 -> 817 bytes .../ext/images/default/grid/grid-hrow.gif | Bin 0 -> 855 bytes .../ext/images/default/grid/grid-loading.gif | Bin 0 -> 701 bytes .../ext/images/default/grid/grid-split.gif | Bin 0 -> 817 bytes .../ext/images/default/grid/grid-vista-hd.gif | Bin 0 -> 829 bytes .../ext/images/default/grid/grid3-hd-btn.gif | Bin 0 -> 1229 bytes .../images/default/grid/grid3-hrow-over.gif | Bin 0 -> 823 bytes .../ext/images/default/grid/grid3-hrow.gif | Bin 0 -> 836 bytes .../default/grid/grid3-special-col-bg.gif | Bin 0 -> 837 bytes .../default/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 843 bytes .../ext/images/default/grid/group-by.gif | Bin 0 -> 917 bytes .../images/default/grid/group-collapse.gif | Bin 0 -> 881 bytes .../default/grid/group-expand-sprite.gif | Bin 0 -> 955 bytes .../ext/images/default/grid/group-expand.gif | Bin 0 -> 884 bytes .../skins/ext/images/default/grid/hd-pop.gif | Bin 0 -> 839 bytes .../ext/images/default/grid/hmenu-asc.gif | Bin 0 -> 931 bytes .../ext/images/default/grid/hmenu-desc.gif | Bin 0 -> 930 bytes .../ext/images/default/grid/hmenu-lock.gif | Bin 0 -> 955 bytes .../ext/images/default/grid/hmenu-lock.png | Bin 0 -> 648 bytes .../ext/images/default/grid/hmenu-unlock.gif | Bin 0 -> 971 bytes .../ext/images/default/grid/hmenu-unlock.png | Bin 0 -> 697 bytes .../ext/images/default/grid/invalid_line.gif | Bin 0 -> 815 bytes .../skins/ext/images/default/grid/loading.gif | Bin 0 -> 771 bytes .../skins/ext/images/default/grid/mso-hd.gif | Bin 0 -> 875 bytes .../skins/ext/images/default/grid/nowait.gif | Bin 0 -> 884 bytes .../default/grid/page-first-disabled.gif | Bin 0 -> 925 bytes .../ext/images/default/grid/page-first.gif | Bin 0 -> 925 bytes .../default/grid/page-last-disabled.gif | Bin 0 -> 923 bytes .../ext/images/default/grid/page-last.gif | Bin 0 -> 923 bytes .../default/grid/page-next-disabled.gif | Bin 0 -> 875 bytes .../ext/images/default/grid/page-next.gif | Bin 0 -> 875 bytes .../default/grid/page-prev-disabled.gif | Bin 0 -> 879 bytes .../ext/images/default/grid/page-prev.gif | Bin 0 -> 879 bytes .../ext/images/default/grid/pick-button.gif | Bin 0 -> 1036 bytes .../skins/ext/images/default/grid/refresh.gif | Bin 0 -> 977 bytes .../images/default/grid/row-check-sprite.gif | Bin 0 -> 1083 bytes .../images/default/grid/row-expand-sprite.gif | Bin 0 -> 955 bytes .../ext/images/default/grid/row-over.gif | Bin 0 -> 823 bytes .../skins/ext/images/default/grid/row-sel.gif | Bin 0 -> 823 bytes .../skins/ext/images/default/grid/sort-hd.gif | Bin 0 -> 1473 bytes .../ext/images/default/grid/sort_asc.gif | Bin 0 -> 830 bytes .../ext/images/default/grid/sort_desc.gif | Bin 0 -> 833 bytes .../skins/ext/images/default/grid/wait.gif | Bin 0 -> 1100 bytes .../ext/images/default/layout/collapse.gif | Bin 0 -> 842 bytes .../ext/images/default/layout/expand.gif | Bin 0 -> 842 bytes .../ext/images/default/layout/gradient-bg.gif | Bin 0 -> 1472 bytes .../ext/images/default/layout/mini-bottom.gif | Bin 0 -> 856 bytes .../ext/images/default/layout/mini-left.gif | Bin 0 -> 871 bytes .../ext/images/default/layout/mini-right.gif | Bin 0 -> 872 bytes .../ext/images/default/layout/mini-top.gif | Bin 0 -> 856 bytes .../ext/images/default/layout/ns-collapse.gif | Bin 0 -> 842 bytes .../ext/images/default/layout/ns-expand.gif | Bin 0 -> 843 bytes .../ext/images/default/layout/panel-close.gif | Bin 0 -> 829 bytes .../images/default/layout/panel-title-bg.gif | Bin 0 -> 838 bytes .../default/layout/panel-title-light-bg.gif | Bin 0 -> 835 bytes .../skins/ext/images/default/layout/stick.gif | Bin 0 -> 874 bytes .../skins/ext/images/default/layout/stuck.gif | Bin 0 -> 92 bytes .../images/default/layout/tab-close-on.gif | Bin 0 -> 880 bytes .../ext/images/default/layout/tab-close.gif | Bin 0 -> 859 bytes .../skins/ext/images/default/menu/checked.gif | Bin 0 -> 959 bytes .../ext/images/default/menu/group-checked.gif | Bin 0 -> 891 bytes .../ext/images/default/menu/item-over.gif | Bin 0 -> 820 bytes .../ext/images/default/menu/menu-parent.gif | Bin 0 -> 854 bytes .../skins/ext/images/default/menu/menu.gif | Bin 0 -> 834 bytes .../ext/images/default/menu/unchecked.gif | Bin 0 -> 941 bytes .../images/default/panel/corners-sprite.gif | Bin 0 -> 1418 bytes .../ext/images/default/panel/left-right.gif | Bin 0 -> 815 bytes .../ext/images/default/panel/light-hd.gif | Bin 0 -> 827 bytes .../images/default/panel/tool-sprite-tpl.gif | Bin 0 -> 971 bytes .../ext/images/default/panel/tool-sprites.gif | Bin 0 -> 4392 bytes .../default/panel/tools-sprites-trans.gif | Bin 0 -> 2843 bytes .../ext/images/default/panel/top-bottom.gif | Bin 0 -> 875 bytes .../ext/images/default/panel/top-bottom.png | Bin 0 -> 218 bytes .../default/panel/white-corners-sprite.gif | Bin 0 -> 1366 bytes .../images/default/panel/white-left-right.gif | Bin 0 -> 815 bytes .../images/default/panel/white-top-bottom.gif | Bin 0 -> 872 bytes .../images/default/progress/progress-bg.gif | Bin 0 -> 834 bytes .../skins/ext/images/default/qtip/bg.gif | Bin 0 -> 1091 bytes .../skins/ext/images/default/qtip/close.gif | Bin 0 -> 972 bytes .../images/default/qtip/tip-anchor-sprite.gif | Bin 0 -> 951 bytes .../ext/images/default/qtip/tip-sprite.gif | Bin 0 -> 4271 bytes .../skins/ext/images/default/s.gif | Bin 0 -> 43 bytes .../skins/ext/images/default/shadow-c.png | Bin 0 -> 118 bytes .../skins/ext/images/default/shadow-lr.png | Bin 0 -> 135 bytes .../skins/ext/images/default/shadow.png | Bin 0 -> 311 bytes .../images/default/shared/blue-loading.gif | Bin 0 -> 3236 bytes .../ext/images/default/shared/calendar.gif | Bin 0 -> 979 bytes .../ext/images/default/shared/glass-bg.gif | Bin 0 -> 873 bytes .../ext/images/default/shared/hd-sprite.gif | Bin 0 -> 1099 bytes .../images/default/shared/large-loading.gif | Bin 0 -> 3236 bytes .../ext/images/default/shared/left-btn.gif | Bin 0 -> 870 bytes .../images/default/shared/loading-balls.gif | Bin 0 -> 2118 bytes .../ext/images/default/shared/right-btn.gif | Bin 0 -> 871 bytes .../ext/images/default/shared/warning.gif | Bin 0 -> 960 bytes .../images/default/sizer/e-handle-dark.gif | Bin 0 -> 1062 bytes .../ext/images/default/sizer/e-handle.gif | Bin 0 -> 1586 bytes .../images/default/sizer/ne-handle-dark.gif | Bin 0 -> 839 bytes .../ext/images/default/sizer/ne-handle.gif | Bin 0 -> 854 bytes .../images/default/sizer/nw-handle-dark.gif | Bin 0 -> 839 bytes .../ext/images/default/sizer/nw-handle.gif | Bin 0 -> 853 bytes .../images/default/sizer/s-handle-dark.gif | Bin 0 -> 1060 bytes .../ext/images/default/sizer/s-handle.gif | Bin 0 -> 1318 bytes .../images/default/sizer/se-handle-dark.gif | Bin 0 -> 838 bytes .../ext/images/default/sizer/se-handle.gif | Bin 0 -> 853 bytes .../skins/ext/images/default/sizer/square.gif | Bin 0 -> 864 bytes .../images/default/sizer/sw-handle-dark.gif | Bin 0 -> 839 bytes .../ext/images/default/sizer/sw-handle.gif | Bin 0 -> 855 bytes .../ext/images/default/slider/slider-bg.png | Bin 0 -> 300 bytes .../images/default/slider/slider-thumb.png | Bin 0 -> 933 bytes .../ext/images/default/slider/slider-v-bg.png | Bin 0 -> 288 bytes .../images/default/slider/slider-v-thumb.png | Bin 0 -> 883 bytes .../ext/images/default/tabs/scroll-left.gif | Bin 0 -> 1295 bytes .../ext/images/default/tabs/scroll-right.gif | Bin 0 -> 1300 bytes .../ext/images/default/tabs/scroller-bg.gif | Bin 0 -> 1100 bytes .../default/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 886 bytes .../tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 1386 bytes .../images/default/tabs/tab-btm-left-bg.gif | Bin 0 -> 1402 bytes .../default/tabs/tab-btm-over-left-bg.gif | Bin 0 -> 191 bytes .../default/tabs/tab-btm-over-right-bg.gif | Bin 0 -> 638 bytes .../images/default/tabs/tab-btm-right-bg.gif | Bin 0 -> 863 bytes .../ext/images/default/tabs/tab-close.gif | Bin 0 -> 896 bytes .../ext/images/default/tabs/tab-strip-bg.gif | Bin 0 -> 835 bytes .../ext/images/default/tabs/tab-strip-bg.png | Bin 0 -> 259 bytes .../images/default/tabs/tab-strip-btm-bg.gif | Bin 0 -> 826 bytes .../ext/images/default/tabs/tabs-sprite.gif | Bin 0 -> 2120 bytes .../skins/ext/images/default/toolbar/bg.gif | Bin 0 -> 904 bytes .../default/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../ext/images/default/toolbar/btn-arrow.gif | Bin 0 -> 919 bytes .../images/default/toolbar/btn-over-bg.gif | Bin 0 -> 837 bytes .../ext/images/default/toolbar/gray-bg.gif | Bin 0 -> 832 bytes .../skins/ext/images/default/toolbar/more.gif | Bin 0 -> 845 bytes .../ext/images/default/toolbar/tb-bg.gif | Bin 0 -> 862 bytes .../images/default/toolbar/tb-btn-sprite.gif | Bin 0 -> 1127 bytes .../default/toolbar/tb-xl-btn-sprite.gif | Bin 0 -> 1663 bytes .../ext/images/default/toolbar/tb-xl-sep.gif | Bin 0 -> 810 bytes .../skins/ext/images/default/tree/arrows.gif | Bin 0 -> 617 bytes .../ext/images/default/tree/drop-add.gif | Bin 0 -> 1001 bytes .../ext/images/default/tree/drop-between.gif | Bin 0 -> 907 bytes .../skins/ext/images/default/tree/drop-no.gif | Bin 0 -> 949 bytes .../ext/images/default/tree/drop-over.gif | Bin 0 -> 911 bytes .../ext/images/default/tree/drop-under.gif | Bin 0 -> 911 bytes .../ext/images/default/tree/drop-yes.gif | Bin 0 -> 1016 bytes .../default/tree/elbow-end-minus-nl.gif | Bin 0 -> 898 bytes .../images/default/tree/elbow-end-minus.gif | Bin 0 -> 905 bytes .../images/default/tree/elbow-end-plus-nl.gif | Bin 0 -> 900 bytes .../images/default/tree/elbow-end-plus.gif | Bin 0 -> 907 bytes .../ext/images/default/tree/elbow-end.gif | Bin 0 -> 844 bytes .../ext/images/default/tree/elbow-line.gif | Bin 0 -> 846 bytes .../images/default/tree/elbow-minus-nl.gif | Bin 0 -> 898 bytes .../ext/images/default/tree/elbow-minus.gif | Bin 0 -> 908 bytes .../ext/images/default/tree/elbow-plus-nl.gif | Bin 0 -> 900 bytes .../ext/images/default/tree/elbow-plus.gif | Bin 0 -> 910 bytes .../skins/ext/images/default/tree/elbow.gif | Bin 0 -> 850 bytes .../ext/images/default/tree/folder-open.gif | Bin 0 -> 956 bytes .../skins/ext/images/default/tree/folder.gif | Bin 0 -> 952 bytes .../skins/ext/images/default/tree/leaf.gif | Bin 0 -> 945 bytes .../skins/ext/images/default/tree/loading.gif | Bin 0 -> 771 bytes .../skins/ext/images/default/tree/s.gif | Bin 0 -> 43 bytes .../ext/images/default/window/icon-error.gif | Bin 0 -> 1669 bytes .../ext/images/default/window/icon-info.gif | Bin 0 -> 1586 bytes .../images/default/window/icon-question.gif | Bin 0 -> 1607 bytes .../images/default/window/icon-warning.gif | Bin 0 -> 1483 bytes .../images/default/window/left-corners.png | Bin 0 -> 200 bytes .../images/default/window/left-corners.psd | Bin 0 -> 15576 bytes .../ext/images/default/window/left-right.png | Bin 0 -> 152 bytes .../ext/images/default/window/left-right.psd | Bin 0 -> 24046 bytes .../images/default/window/right-corners.png | Bin 0 -> 256 bytes .../images/default/window/right-corners.psd | Bin 0 -> 15530 bytes .../ext/images/default/window/top-bottom.png | Bin 0 -> 180 bytes .../ext/images/default/window/top-bottom.psd | Bin 0 -> 32128 bytes .../ext/images/gray/button/btn-arrow.gif | Bin 0 -> 870 bytes .../ext/images/gray/button/btn-sprite.gif | Bin 0 -> 1222 bytes .../skins/ext/images/gray/button/btn.gif | Bin 0 -> 3319 bytes .../skins/ext/images/gray/button/group-cs.gif | Bin 0 -> 2459 bytes .../skins/ext/images/gray/button/group-lr.gif | Bin 0 -> 861 bytes .../skins/ext/images/gray/button/group-tb.gif | Bin 0 -> 846 bytes .../ext/images/gray/button/s-arrow-bo.gif | Bin 0 -> 123 bytes .../ext/images/gray/button/s-arrow-o.gif | Bin 0 -> 139 bytes .../ext/images/gray/form/clear-trigger.gif | Bin 0 -> 1425 bytes .../ext/images/gray/form/date-trigger.gif | Bin 0 -> 929 bytes .../ext/images/gray/form/search-trigger.gif | Bin 0 -> 2220 bytes .../ext/images/gray/form/trigger-square.gif | Bin 0 -> 1071 bytes .../skins/ext/images/gray/form/trigger.gif | Bin 0 -> 1080 bytes .../skins/ext/images/gray/gradient-bg.gif | Bin 0 -> 1472 bytes .../ext/images/gray/grid/col-move-bottom.gif | Bin 0 -> 177 bytes .../ext/images/gray/grid/col-move-top.gif | Bin 0 -> 178 bytes .../ext/images/gray/grid/grid3-hd-btn.gif | Bin 0 -> 482 bytes .../ext/images/gray/grid/grid3-hrow-over.gif | Bin 0 -> 56 bytes .../ext/images/gray/grid/grid3-hrow-over2.gif | Bin 0 -> 107 bytes .../skins/ext/images/gray/grid/grid3-hrow.gif | Bin 0 -> 836 bytes .../ext/images/gray/grid/grid3-hrow2.gif | Bin 0 -> 107 bytes .../images/gray/grid/grid3-special-col-bg.gif | Bin 0 -> 158 bytes .../gray/grid/grid3-special-col-bg2.gif | Bin 0 -> 158 bytes .../gray/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 158 bytes .../ext/images/gray/grid/group-collapse.gif | Bin 0 -> 136 bytes .../images/gray/grid/group-expand-sprite.gif | Bin 0 -> 196 bytes .../ext/images/gray/grid/group-expand.gif | Bin 0 -> 138 bytes .../skins/ext/images/gray/grid/page-first.gif | Bin 0 -> 327 bytes .../skins/ext/images/gray/grid/page-last.gif | Bin 0 -> 325 bytes .../skins/ext/images/gray/grid/page-next.gif | Bin 0 -> 183 bytes .../skins/ext/images/gray/grid/page-prev.gif | Bin 0 -> 186 bytes .../skins/ext/images/gray/grid/refresh.gif | Bin 0 -> 570 bytes .../images/gray/grid/row-expand-sprite.gif | Bin 0 -> 196 bytes .../skins/ext/images/gray/grid/sort_asc.gif | Bin 0 -> 59 bytes .../skins/ext/images/gray/grid/sort_desc.gif | Bin 0 -> 59 bytes .../ext/images/gray/menu/group-checked.gif | Bin 0 -> 295 bytes .../images/gray/menu/item-over-disabled.gif | Bin 0 -> 49 bytes .../skins/ext/images/gray/menu/item-over.gif | Bin 0 -> 850 bytes .../ext/images/gray/menu/menu-parent.gif | Bin 0 -> 165 bytes .../ext/images/gray/panel/corners-sprite.gif | Bin 0 -> 1402 bytes .../ext/images/gray/panel/left-right.gif | Bin 0 -> 815 bytes .../skins/ext/images/gray/panel/light-hd.gif | Bin 0 -> 827 bytes .../ext/images/gray/panel/tool-sprite-tpl.gif | Bin 0 -> 971 bytes .../ext/images/gray/panel/tool-sprites.gif | Bin 0 -> 4464 bytes .../images/gray/panel/tools-sprites-trans.gif | Bin 0 -> 1981 bytes .../ext/images/gray/panel/top-bottom.gif | Bin 0 -> 871 bytes .../ext/images/gray/panel/top-bottom.png | Bin 0 -> 218 bytes .../gray/panel/white-corners-sprite.gif | Bin 0 -> 1365 bytes .../images/gray/panel/white-left-right.gif | Bin 0 -> 815 bytes .../images/gray/panel/white-top-bottom.gif | Bin 0 -> 860 bytes .../ext/images/gray/progress/progress-bg.gif | Bin 0 -> 107 bytes .../skins/ext/images/gray/qtip/bg.gif | Bin 0 -> 1024 bytes .../skins/ext/images/gray/qtip/close.gif | Bin 0 -> 972 bytes .../images/gray/qtip/tip-anchor-sprite.gif | Bin 0 -> 164 bytes .../skins/ext/images/gray/qtip/tip-sprite.gif | Bin 0 -> 3241 bytes .../public_html/skins/ext/images/gray/s.gif | Bin 0 -> 43 bytes .../ext/images/gray/shared/hd-sprite.gif | Bin 0 -> 305 bytes .../skins/ext/images/gray/shared/left-btn.gif | Bin 0 -> 106 bytes .../ext/images/gray/shared/right-btn.gif | Bin 0 -> 107 bytes .../skins/ext/images/gray/sizer/e-handle.gif | Bin 0 -> 753 bytes .../skins/ext/images/gray/sizer/ne-handle.gif | Bin 0 -> 128 bytes .../skins/ext/images/gray/sizer/nw-handle.gif | Bin 0 -> 114 bytes .../skins/ext/images/gray/sizer/s-handle.gif | Bin 0 -> 494 bytes .../skins/ext/images/gray/sizer/se-handle.gif | Bin 0 -> 114 bytes .../skins/ext/images/gray/sizer/square.gif | Bin 0 -> 123 bytes .../skins/ext/images/gray/sizer/sw-handle.gif | Bin 0 -> 116 bytes .../ext/images/gray/slider/slider-thumb.png | Bin 0 -> 675 bytes .../ext/images/gray/slider/slider-v-thumb.png | Bin 0 -> 632 bytes .../ext/images/gray/tabs/scroll-left.gif | Bin 0 -> 1260 bytes .../ext/images/gray/tabs/scroll-right.gif | Bin 0 -> 1269 bytes .../ext/images/gray/tabs/scroller-bg.gif | Bin 0 -> 1090 bytes .../gray/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 881 bytes .../gray/tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 1383 bytes .../ext/images/gray/tabs/tab-btm-left-bg.gif | Bin 0 -> 1402 bytes .../images/gray/tabs/tab-btm-over-left-bg.gif | Bin 0 -> 189 bytes .../gray/tabs/tab-btm-over-right-bg.gif | Bin 0 -> 635 bytes .../ext/images/gray/tabs/tab-btm-right-bg.gif | Bin 0 -> 863 bytes .../skins/ext/images/gray/tabs/tab-close.gif | Bin 0 -> 896 bytes .../ext/images/gray/tabs/tab-strip-bg.gif | Bin 0 -> 835 bytes .../ext/images/gray/tabs/tab-strip-bg.png | Bin 0 -> 259 bytes .../ext/images/gray/tabs/tab-strip-btm-bg.gif | Bin 0 -> 826 bytes .../ext/images/gray/tabs/tabs-sprite.gif | Bin 0 -> 2109 bytes .../skins/ext/images/gray/toolbar/bg.gif | Bin 0 -> 854 bytes .../images/gray/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../ext/images/gray/toolbar/btn-arrow.gif | Bin 0 -> 919 bytes .../ext/images/gray/toolbar/btn-over-bg.gif | Bin 0 -> 837 bytes .../skins/ext/images/gray/toolbar/gray-bg.gif | Bin 0 -> 815 bytes .../skins/ext/images/gray/toolbar/more.gif | Bin 0 -> 67 bytes .../skins/ext/images/gray/toolbar/tb-bg.gif | Bin 0 -> 862 bytes .../ext/images/gray/toolbar/tb-btn-sprite.gif | Bin 0 -> 1021 bytes .../skins/ext/images/gray/tree/arrows.gif | Bin 0 -> 407 bytes .../images/gray/tree/elbow-end-minus-nl.gif | Bin 0 -> 149 bytes .../ext/images/gray/tree/elbow-end-minus.gif | Bin 0 -> 154 bytes .../images/gray/tree/elbow-end-plus-nl.gif | Bin 0 -> 151 bytes .../ext/images/gray/tree/elbow-end-plus.gif | Bin 0 -> 156 bytes .../ext/images/gray/window/icon-error.gif | Bin 0 -> 1669 bytes .../ext/images/gray/window/icon-info.gif | Bin 0 -> 1586 bytes .../ext/images/gray/window/icon-question.gif | Bin 0 -> 1607 bytes .../ext/images/gray/window/icon-warning.gif | Bin 0 -> 1483 bytes .../ext/images/gray/window/left-corners.png | Bin 0 -> 325 bytes .../images/gray/window/left-corners.pspimage | Bin 0 -> 4385 bytes .../ext/images/gray/window/left-right.png | Bin 0 -> 2815 bytes .../ext/images/gray/window/right-corners.png | Bin 0 -> 344 bytes .../ext/images/gray/window/top-bottom.png | Bin 0 -> 2860 bytes .../skins/ext/pmos-xtheme-gray.css | 215 + .../public_html/skins/ext/xtheme-blue.css | 1646 + .../public_html/skins/ext/xtheme-gray.css | 1654 + workflow/public_html/skins/green/iepngfix.htc | 68 + .../skins/green/images/bar_bg_bw.gif | Bin 0 -> 809 bytes .../public_html/skins/green/images/bf.jpg | Bin 0 -> 318 bytes .../public_html/skins/green/images/bm.jpg | Bin 0 -> 328 bytes .../public_html/skins/green/images/bsm.jpg | Bin 0 -> 292 bytes .../public_html/skins/green/images/bsms.jpg | Bin 0 -> 323 bytes .../skins/green/images/dark-pointer.gif | Bin 0 -> 49 bytes .../public_html/skins/green/images/error.gif | Bin 0 -> 561 bytes .../skins/green/images/fbc.blue.png | Bin 0 -> 1242 bytes .../public_html/skins/green/images/fbc.png | Bin 0 -> 40655 bytes .../skins/green/images/fbl.blue.png | Bin 0 -> 1343 bytes .../public_html/skins/green/images/fbl.png | Bin 0 -> 205 bytes .../skins/green/images/fbr.blue.png | Bin 0 -> 1358 bytes .../public_html/skins/green/images/fbr.png | Bin 0 -> 41152 bytes .../skins/green/images/frame.full.bottom.png | Bin 0 -> 578 bytes .../skins/green/images/frame.full.top.png | Bin 0 -> 240 bytes .../skins/green/images/frame.home.bottom.png | Bin 0 -> 557 bytes .../skins/green/images/frame.right.bottom.png | Bin 0 -> 43095 bytes .../skins/green/images/frame.right.top.gif | Bin 0 -> 197 bytes .../public_html/skins/green/images/ftc.png | Bin 0 -> 621 bytes .../skins/green/images/ftl.blue.gif | Bin 0 -> 64 bytes .../public_html/skins/green/images/ftl.png | Bin 0 -> 219 bytes .../public_html/skins/green/images/ftlL.png | Bin 0 -> 289 bytes .../skins/green/images/ftr.blue.gif | Bin 0 -> 64 bytes .../public_html/skins/green/images/ftr.png | Bin 0 -> 216 bytes .../public_html/skins/green/images/ftrL.png | Bin 0 -> 1641 bytes .../skins/green/images/input_back.gif | Bin 0 -> 44 bytes .../skins/green/images/message.png | Bin 0 -> 472 bytes .../skins/green/images/warning.png | Bin 0 -> 394 bytes .../public_html/skins/green/printstyle.css | 500 + workflow/public_html/skins/green/style.css | 3018 ++ .../public_html/skins/iphone/images/bf.jpg | Bin 0 -> 318 bytes .../public_html/skins/iphone/images/bm.jpg | Bin 0 -> 328 bytes .../public_html/skins/iphone/images/bsm.jpg | Bin 0 -> 292 bytes .../public_html/skins/iphone/images/bsms.jpg | Bin 0 -> 323 bytes .../skins/iphone/images/fbc.blue.png | Bin 0 -> 1242 bytes .../public_html/skins/iphone/images/fbc.png | Bin 0 -> 40655 bytes .../skins/iphone/images/fbl.blue.png | Bin 0 -> 1343 bytes .../public_html/skins/iphone/images/fbl.png | Bin 0 -> 41148 bytes .../skins/iphone/images/fbr.blue.png | Bin 0 -> 1358 bytes .../public_html/skins/iphone/images/fbr.png | Bin 0 -> 41152 bytes .../skins/iphone/images/frame.full.bottom.png | Bin 0 -> 578 bytes .../skins/iphone/images/frame.full.top.png | Bin 0 -> 240 bytes .../skins/iphone/images/frame.home.bottom.png | Bin 0 -> 557 bytes .../iphone/images/frame.right.bottom.png | Bin 0 -> 43095 bytes .../skins/iphone/images/frame.right.top.gif | Bin 0 -> 197 bytes .../public_html/skins/iphone/images/ftc.png | Bin 0 -> 621 bytes .../skins/iphone/images/ftl.blue.gif | Bin 0 -> 64 bytes .../public_html/skins/iphone/images/ftl.png | Bin 0 -> 219 bytes .../public_html/skins/iphone/images/ftlL.png | Bin 0 -> 289 bytes .../skins/iphone/images/ftr.blue.gif | Bin 0 -> 64 bytes .../public_html/skins/iphone/images/ftr.png | Bin 0 -> 216 bytes .../public_html/skins/iphone/images/ftrL.png | Bin 0 -> 1641 bytes .../skins/iphone/images/iPhoneArrow.png | Bin 0 -> 272 bytes .../skins/iphone/images/iPhoneToolbar.png | Bin 0 -> 2848 bytes .../skins/iphone/images/input_back.gif | Bin 0 -> 44 bytes workflow/public_html/skins/iphone/style.css | 1492 + workflow/public_html/skins/rtl/iepngfix.htc | 68 + .../skins/rtl/images/bar_bg_bw.gif | Bin 0 -> 809 bytes workflow/public_html/skins/rtl/images/bf.jpg | Bin 0 -> 318 bytes workflow/public_html/skins/rtl/images/bm.jpg | Bin 0 -> 328 bytes workflow/public_html/skins/rtl/images/bsm.jpg | Bin 0 -> 292 bytes .../public_html/skins/rtl/images/bsms.jpg | Bin 0 -> 323 bytes .../skins/rtl/images/dark-pointer.gif | Bin 0 -> 49 bytes .../public_html/skins/rtl/images/fbc.blue.png | Bin 0 -> 1242 bytes workflow/public_html/skins/rtl/images/fbc.png | Bin 0 -> 40655 bytes .../public_html/skins/rtl/images/fbl.blue.png | Bin 0 -> 1343 bytes workflow/public_html/skins/rtl/images/fbl.png | Bin 0 -> 205 bytes .../public_html/skins/rtl/images/fbr.blue.png | Bin 0 -> 1358 bytes workflow/public_html/skins/rtl/images/fbr.png | Bin 0 -> 41152 bytes .../skins/rtl/images/frame.full.bottom.png | Bin 0 -> 578 bytes .../skins/rtl/images/frame.full.top.png | Bin 0 -> 240 bytes .../skins/rtl/images/frame.home.bottom.png | Bin 0 -> 557 bytes .../skins/rtl/images/frame.right.bottom.png | Bin 0 -> 43095 bytes .../skins/rtl/images/frame.right.top.gif | Bin 0 -> 197 bytes workflow/public_html/skins/rtl/images/ftc.png | Bin 0 -> 621 bytes .../public_html/skins/rtl/images/ftl.blue.gif | Bin 0 -> 64 bytes workflow/public_html/skins/rtl/images/ftl.png | Bin 0 -> 219 bytes .../public_html/skins/rtl/images/ftlL.png | Bin 0 -> 289 bytes .../public_html/skins/rtl/images/ftr.blue.gif | Bin 0 -> 64 bytes workflow/public_html/skins/rtl/images/ftr.png | Bin 0 -> 216 bytes .../public_html/skins/rtl/images/ftrL.png | Bin 0 -> 1641 bytes .../skins/rtl/images/input_back.gif | Bin 0 -> 44 bytes workflow/public_html/skins/rtl/style.css | 2391 ++ workflow/public_html/skins/valida.js | 1108 + workflow/public_html/skins/workPeriod.js | 20 + workflow/public_html/sysGeneric.php | 530 + workflow/public_html/sysUnnamed.php | 33 + 5410 files changed, 864427 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100755 gulliver/bin/gulliver create mode 100644 gulliver/bin/gulliver.php create mode 100644 gulliver/bin/tasks/pakeBase.php create mode 100644 gulliver/bin/tasks/pakeGulliver.php create mode 100644 gulliver/bin/tasks/pakePropel.php create mode 100644 gulliver/bin/tasks/pakeTest.php create mode 100644 gulliver/bin/tasks/templates/authentication.php.tpl create mode 100644 gulliver/bin/tasks/templates/bm.jpg.tpl create mode 100644 gulliver/bin/tasks/templates/bsm.jpg.tpl create mode 100644 gulliver/bin/tasks/templates/class.pmFunctions.php.tpl create mode 100644 gulliver/bin/tasks/templates/databases.php.tpl create mode 100644 gulliver/bin/tasks/templates/db.php.tpl create mode 100755 gulliver/bin/tasks/templates/dbInfo.php.tpl create mode 100755 gulliver/bin/tasks/templates/dbInfo.xml.tpl create mode 100755 gulliver/bin/tasks/templates/db_insert.sql create mode 100644 gulliver/bin/tasks/templates/defines.php.tpl create mode 100644 gulliver/bin/tasks/templates/green.html.tpl create mode 100644 gulliver/bin/tasks/templates/green.php.tpl create mode 100644 gulliver/bin/tasks/templates/httpd.conf.tpl create mode 100644 gulliver/bin/tasks/templates/index.html.tpl create mode 100644 gulliver/bin/tasks/templates/login.php.tpl create mode 100644 gulliver/bin/tasks/templates/login.xml.tpl create mode 100755 gulliver/bin/tasks/templates/mainmenu.php.tpl create mode 100644 gulliver/bin/tasks/templates/paths.php.tpl create mode 100644 gulliver/bin/tasks/templates/permissionsList.php.tpl create mode 100644 gulliver/bin/tasks/templates/permissionsList.xml.tpl create mode 100644 gulliver/bin/tasks/templates/pluginClass.tpl create mode 100644 gulliver/bin/tasks/templates/pluginDelete.tpl create mode 100644 gulliver/bin/tasks/templates/pluginDeleteExec.tpl create mode 100755 gulliver/bin/tasks/templates/pluginDrawChart.php.tpl create mode 100644 gulliver/bin/tasks/templates/pluginEdit.tpl create mode 100644 gulliver/bin/tasks/templates/pluginList.tpl create mode 100644 gulliver/bin/tasks/templates/pluginMainFile.tpl create mode 100644 gulliver/bin/tasks/templates/pluginMenu.tpl create mode 100644 gulliver/bin/tasks/templates/pluginMenuOnTransit.tpl create mode 100644 gulliver/bin/tasks/templates/pluginNew.tpl create mode 100644 gulliver/bin/tasks/templates/pluginOnTransitList.php.tpl create mode 100644 gulliver/bin/tasks/templates/pluginOnTransitList.xml.tpl create mode 100644 gulliver/bin/tasks/templates/pluginPaged-table.html.tpl create mode 100644 gulliver/bin/tasks/templates/pluginPropel.ini.tpl create mode 100644 gulliver/bin/tasks/templates/pluginPropel.mysql.ini.tpl create mode 100755 gulliver/bin/tasks/templates/pluginReport.xml.tpl create mode 100644 gulliver/bin/tasks/templates/pluginSave.tpl create mode 100644 gulliver/bin/tasks/templates/pluginSchema.xml.tpl create mode 100644 gulliver/bin/tasks/templates/pluginStep.tpl create mode 100755 gulliver/bin/tasks/templates/pluginWelcome.php.tpl create mode 100644 gulliver/bin/tasks/templates/pluginXmlform.tpl create mode 100644 gulliver/bin/tasks/templates/pluginXmlformDelete.tpl create mode 100644 gulliver/bin/tasks/templates/pluginXmlformEdit.tpl create mode 100644 gulliver/bin/tasks/templates/pluginXmlformList.tpl create mode 100644 gulliver/bin/tasks/templates/pluginXmlformOptions.tpl create mode 100644 gulliver/bin/tasks/templates/propel.ini.tpl create mode 100644 gulliver/bin/tasks/templates/publish-treeview.php.tpl create mode 100644 gulliver/bin/tasks/templates/publish.php.tpl create mode 100644 gulliver/bin/tasks/templates/rolesList.php.tpl create mode 100644 gulliver/bin/tasks/templates/rolesList.xml.tpl create mode 100644 gulliver/bin/tasks/templates/schema.xml.tpl create mode 100644 gulliver/bin/tasks/templates/showMessage.xml.tpl create mode 100644 gulliver/bin/tasks/templates/skinPluginClass.tpl create mode 100644 gulliver/bin/tasks/templates/skinPluginMainClass.tpl create mode 100644 gulliver/bin/tasks/templates/style.css.tpl create mode 100644 gulliver/bin/tasks/templates/sysGeneric.php.tpl create mode 100644 gulliver/bin/tasks/templates/sysLogin.php.tpl create mode 100644 gulliver/bin/tasks/templates/sysLogin.xml.tpl create mode 100644 gulliver/bin/tasks/templates/unitTest.tpl create mode 100755 gulliver/bin/tasks/templates/users.menu.php.tpl create mode 100755 gulliver/bin/tasks/templates/usersList.php.tpl create mode 100755 gulliver/bin/tasks/templates/usersList.xml.tpl create mode 100644 gulliver/bin/tasks/templates/welcome.php.tpl create mode 100644 gulliver/bin/tasks/templates/welcome.xml.tpl create mode 100644 gulliver/bin/tasks/templates/xmlform.html.tpl create mode 100644 gulliver/includes/inc.ajax.php create mode 100755 gulliver/js/common/core/common.js create mode 100755 gulliver/js/common/core/effects.js create mode 100644 gulliver/js/common/core/images/default_logo.gif create mode 100644 gulliver/js/common/core/webResource.js create mode 100644 gulliver/js/common/tree/tree.js create mode 100644 gulliver/js/dveditor/core/dveditor.js create mode 100644 gulliver/js/dveditor/core/toolbars/complete3lines.html create mode 100644 gulliver/js/dveditor/core/toolbars/complete3lines.png create mode 100644 gulliver/js/dveditor/core/toolbars/smallToolBar.html create mode 100644 gulliver/js/dveditor/core/toolbars/smallToolBar.png create mode 100644 gulliver/js/dveditor/core/toolbars/toolbar2lines.html create mode 100644 gulliver/js/dveditor/core/toolbars/toolbar2lines.png create mode 100755 gulliver/js/ext/draw2d.js create mode 100755 gulliver/js/ext/ext-all.js create mode 100755 gulliver/js/ext/ext-base.js create mode 100755 gulliver/js/ext/moocanvas.js create mode 100755 gulliver/js/ext/mootools.js create mode 100755 gulliver/js/ext/ux/ux-all.js create mode 100755 gulliver/js/ext/wz_jsgraphics.js create mode 100644 gulliver/js/form/core/form.js create mode 100644 gulliver/js/form/core/pagedTable.js create mode 100644 gulliver/js/grid/core/grid.js create mode 100644 gulliver/js/highlight/core/AUTHORS.en.txt create mode 100644 gulliver/js/highlight/core/AUTHORS.ru.txt create mode 100644 gulliver/js/highlight/core/LICENSE create mode 100644 gulliver/js/highlight/core/export.html create mode 100644 gulliver/js/highlight/core/highlight.js create mode 100644 gulliver/js/highlight/core/languages/1c.js create mode 100644 gulliver/js/highlight/core/languages/axapta.js create mode 100644 gulliver/js/highlight/core/languages/dynamic.js create mode 100644 gulliver/js/highlight/core/languages/javascript.js create mode 100644 gulliver/js/highlight/core/languages/rib.js create mode 100644 gulliver/js/highlight/core/languages/rsl.js create mode 100644 gulliver/js/highlight/core/languages/smalltalk.js create mode 100644 gulliver/js/highlight/core/languages/sql.js create mode 100644 gulliver/js/highlight/core/languages/static.js create mode 100644 gulliver/js/highlight/core/languages/vbscript.js create mode 100644 gulliver/js/highlight/core/languages/www.js create mode 100644 gulliver/js/highlight/core/readme.eng.txt create mode 100644 gulliver/js/highlight/core/readme.rus.txt create mode 100644 gulliver/js/highlight/core/sample.css create mode 100644 gulliver/js/highlight/core/test.html create mode 100644 gulliver/js/highlight/core/wp_highlight.js.php create mode 100644 gulliver/js/jquery/ajaxupload.3.6.js create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png create mode 100755 gulliver/js/jquery/css/redmond/jquery-ui-1.7.2.custom.css create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-icons_222222_256x240.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-icons_454545_256x240.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-icons_888888_256x240.png create mode 100755 gulliver/js/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100755 gulliver/js/jquery/css/smoothness/jquery-ui-1.7.2.custom.css create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-icons_222222_256x240.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-icons_228ef1_256x240.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-icons_ef8c08_256x240.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-icons_ffd27a_256x240.png create mode 100755 gulliver/js/jquery/css/ui-lightness/images/ui-icons_ffffff_256x240.png create mode 100755 gulliver/js/jquery/css/ui-lightness/jquery-ui-1.7.2.custom.css create mode 100755 gulliver/js/jquery/jquery-1.3.2.min.js create mode 100755 gulliver/js/jquery/jquery-ui-1.7.2.custom.min.js create mode 100755 gulliver/js/jquery/jquery.layout-latest.js create mode 100755 gulliver/js/json/core/json.js create mode 100644 gulliver/js/maborak/core/data/maborak.module.rss.feeds.json create mode 100644 gulliver/js/maborak/core/images/app.slide/Play_on.png create mode 100755 gulliver/js/maborak/core/images/app.slide/back.png create mode 100755 gulliver/js/maborak/core/images/app.slide/back_dark.png create mode 100755 gulliver/js/maborak/core/images/app.slide/back_on.png create mode 100755 gulliver/js/maborak/core/images/app.slide/back_on_dark.png create mode 100644 gulliver/js/maborak/core/images/app.slide/background_bottom.gif create mode 100755 gulliver/js/maborak/core/images/app.slide/background_bottom.png create mode 100755 gulliver/js/maborak/core/images/app.slide/background_bottom_dark.png create mode 100644 gulliver/js/maborak/core/images/app.slide/close.gif create mode 100755 gulliver/js/maborak/core/images/app.slide/next.png create mode 100755 gulliver/js/maborak/core/images/app.slide/next_dark.png create mode 100755 gulliver/js/maborak/core/images/app.slide/next_on.png create mode 100755 gulliver/js/maborak/core/images/app.slide/next_on_dark.png create mode 100644 gulliver/js/maborak/core/images/app.slide/pause.png create mode 100755 gulliver/js/maborak/core/images/app.slide/pause_dark.png create mode 100644 gulliver/js/maborak/core/images/app.slide/pause_on.png create mode 100755 gulliver/js/maborak/core/images/app.slide/pause_on_dark.png create mode 100755 gulliver/js/maborak/core/images/app.slide/play_dark.png create mode 100755 gulliver/js/maborak/core/images/app.slide/play_on_dark.png create mode 100755 gulliver/js/maborak/core/images/arrowB.gif create mode 100644 gulliver/js/maborak/core/images/failed.png create mode 100755 gulliver/js/maborak/core/images/fbc.blue.png create mode 100755 gulliver/js/maborak/core/images/fbc.png create mode 100755 gulliver/js/maborak/core/images/fbl.blue.png create mode 100755 gulliver/js/maborak/core/images/fbl.png create mode 100755 gulliver/js/maborak/core/images/fbr.blue.png create mode 100755 gulliver/js/maborak/core/images/fbr.png create mode 100755 gulliver/js/maborak/core/images/ftc.png create mode 100755 gulliver/js/maborak/core/images/ftl.blue.gif create mode 100755 gulliver/js/maborak/core/images/ftl.png create mode 100755 gulliver/js/maborak/core/images/ftlL.png create mode 100755 gulliver/js/maborak/core/images/ftr.blue.gif create mode 100755 gulliver/js/maborak/core/images/ftr.png create mode 100755 gulliver/js/maborak/core/images/ftrL.png create mode 100644 gulliver/js/maborak/core/images/grid.png create mode 100644 gulliver/js/maborak/core/images/grid.title.gray.gif create mode 100644 gulliver/js/maborak/core/images/grid.title.green.gif create mode 100644 gulliver/js/maborak/core/images/grid.title.greenLight.gif create mode 100644 gulliver/js/maborak/core/images/grid.title.orange.gif create mode 100644 gulliver/js/maborak/core/images/grid.title.violet.gif create mode 100644 gulliver/js/maborak/core/images/grid.titlebar.bg1.gif create mode 100644 gulliver/js/maborak/core/images/grid.titlebar.bg1.png create mode 100644 gulliver/js/maborak/core/images/icons.gif create mode 100755 gulliver/js/maborak/core/images/info.png create mode 100755 gulliver/js/maborak/core/images/input_back.gif create mode 100755 gulliver/js/maborak/core/images/loader_B.gif create mode 100644 gulliver/js/maborak/core/images/loader_B_blank.gif create mode 100644 gulliver/js/maborak/core/images/maximizar.gif create mode 100644 gulliver/js/maborak/core/images/maximizar1.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-first-disabled.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-first.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-last-disabled.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-last.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-next-disabled.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-next.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-prev-disabled.gif create mode 100644 gulliver/js/maborak/core/images/module.grid/page-prev.gif create mode 100644 gulliver/js/maborak/core/images/nc.gif create mode 100644 gulliver/js/maborak/core/images/nr.gif create mode 100644 gulliver/js/maborak/core/images/nr.png create mode 100644 gulliver/js/maborak/core/images/ok.png create mode 100644 gulliver/js/maborak/core/images/panel.bg.title.1x20.gif create mode 100644 gulliver/js/maborak/core/images/panel.bg.title.1x23.gif create mode 100644 gulliver/js/maborak/core/images/panel.bg.title.1x29.gif create mode 100755 gulliver/js/maborak/core/images/panel.bg.title.gif create mode 100755 gulliver/js/maborak/core/images/panel.bg.title.png create mode 100755 gulliver/js/maborak/core/images/panel.close.static.gif create mode 100644 gulliver/js/maborak/core/images/panel.resize.11x11.png create mode 100644 gulliver/js/maborak/core/images/panel.tabSelected.1x25.gif create mode 100644 gulliver/js/maborak/core/images/panel.tabSelected.1x3.gif create mode 100755 gulliver/js/maborak/core/images/question.png create mode 100755 gulliver/js/maborak/core/images/roll.static.gif create mode 100644 gulliver/js/maborak/core/images/separator.down.gif create mode 100644 gulliver/js/maborak/core/images/separator.up.gif create mode 100644 gulliver/js/maborak/core/images/separatorTable.gif create mode 100644 gulliver/js/maborak/core/images/silverBackgroundMenuSelected.jpg create mode 100644 gulliver/js/maborak/core/images/silverBackgroundSubMenu.jpg create mode 100644 gulliver/js/maborak/core/images/silverBackgroundTableTitle.jpg create mode 100755 gulliver/js/maborak/core/images/star.gif create mode 100644 gulliver/js/maborak/core/images/star_s.gif create mode 100644 gulliver/js/maborak/core/images/star_u.gif create mode 100644 gulliver/js/maborak/core/images/tabs_li_bg.gif create mode 100755 gulliver/js/maborak/core/images/warning.png create mode 100644 gulliver/js/maborak/core/maborak.js create mode 100644 gulliver/js/maborak/core/maborak.loader.js create mode 100644 gulliver/js/maborak/core/module.abbr.js create mode 100755 gulliver/js/maborak/core/module.app.js create mode 100644 gulliver/js/maborak/core/module.boxi.js create mode 100755 gulliver/js/maborak/core/module.dashboard.js create mode 100644 gulliver/js/maborak/core/module.dom.js create mode 100755 gulliver/js/maborak/core/module.drag.js create mode 100755 gulliver/js/maborak/core/module.drop.js create mode 100644 gulliver/js/maborak/core/module.dynaform.js create mode 100644 gulliver/js/maborak/core/module.fx.js create mode 100644 gulliver/js/maborak/core/module.grid.js create mode 100644 gulliver/js/maborak/core/module.panel.js create mode 100644 gulliver/js/maborak/core/module.rpc.js create mode 100755 gulliver/js/maborak/core/module.rss.js create mode 100644 gulliver/js/maborak/core/module.samples.js create mode 100644 gulliver/js/maborak/core/module.services.js create mode 100644 gulliver/js/maborak/core/module.slider.js create mode 100644 gulliver/js/maborak/core/module.validator.js create mode 100644 gulliver/js/maborak/core/module.xmlform.js create mode 100644 gulliver/js/maborak/core/server/class.json.php create mode 100644 gulliver/js/maborak/core/server/maborak.loader.php create mode 100644 gulliver/js/maborak/core/server/maborak.module.rss.php create mode 100644 gulliver/js/maborak/core/server/maborak.module.services.php create mode 100644 gulliver/js/maborak/core/server/proxy.js.php create mode 100644 gulliver/js/maborak/core/server/services/service.comments.php create mode 100644 gulliver/js/maborak/core/server/services/service.rate.php create mode 100755 gulliver/js/maborak/core/stylesheet/default.css create mode 100644 gulliver/js/maborak/core/stylesheet/tiny.css create mode 100644 gulliver/js/maborak/core/xml2array.js create mode 100644 gulliver/js/maborak/samples/1.html create mode 100644 gulliver/js/maborak/samples/2.html create mode 100644 gulliver/js/maborak/samples/ajax.tutorial.txt create mode 100644 gulliver/js/maborak/samples/bench.html create mode 100644 gulliver/js/maborak/samples/csshover.htc create mode 100644 gulliver/js/maborak/samples/data.grid.backup.txt create mode 100644 gulliver/js/maborak/samples/doc.css.txt create mode 100644 gulliver/js/maborak/samples/dynaform.html create mode 100644 gulliver/js/maborak/samples/dynaform.tpl create mode 100644 gulliver/js/maborak/samples/empty.tpl create mode 100644 gulliver/js/maborak/samples/empty.xml create mode 100644 gulliver/js/maborak/samples/ex.app.php create mode 100644 gulliver/js/maborak/samples/ex.core.php create mode 100644 gulliver/js/maborak/samples/ex.grid.php create mode 100644 gulliver/js/maborak/samples/ex.panel.php create mode 100644 gulliver/js/maborak/samples/ex.rpc.php create mode 100644 gulliver/js/maborak/samples/fd1.php create mode 100644 gulliver/js/maborak/samples/fd2.php create mode 100644 gulliver/js/maborak/samples/file.swf create mode 100644 gulliver/js/maborak/samples/g.xml create mode 100644 gulliver/js/maborak/samples/grid.files/paises.grid create mode 100644 gulliver/js/maborak/samples/grid.files/sample.grid create mode 100644 gulliver/js/maborak/samples/grid.json create mode 100644 gulliver/js/maborak/samples/grid.json.data.load.php create mode 100644 gulliver/js/maborak/samples/grid.json.data.save.php create mode 100644 gulliver/js/maborak/samples/grid.txt create mode 100755 gulliver/js/maborak/samples/hard.tpl create mode 100755 gulliver/js/maborak/samples/hard.xml create mode 100644 gulliver/js/maborak/samples/index.php create mode 100644 gulliver/js/maborak/samples/leimnud.html create mode 100644 gulliver/js/maborak/samples/leimnud.module.mail.sender.php create mode 100644 gulliver/js/maborak/samples/link.php create mode 100644 gulliver/js/maborak/samples/link2.php create mode 100644 gulliver/js/maborak/samples/links.html create mode 100644 gulliver/js/maborak/samples/maborak.html create mode 100644 gulliver/js/maborak/samples/maborak.module.rss.php create mode 100644 gulliver/js/maborak/samples/menu.html create mode 100644 gulliver/js/maborak/samples/module.rss.proxy.php create mode 100644 gulliver/js/maborak/samples/mootools.svn.js create mode 100644 gulliver/js/maborak/samples/myInfo.xml create mode 100644 gulliver/js/maborak/samples/nc.gif create mode 100644 gulliver/js/maborak/samples/nr.gif create mode 100644 gulliver/js/maborak/samples/nr.png create mode 100644 gulliver/js/maborak/samples/order.php create mode 100644 gulliver/js/maborak/samples/pagina1.html create mode 100644 gulliver/js/maborak/samples/pagina2.html create mode 100644 gulliver/js/maborak/samples/pm.xml create mode 100644 gulliver/js/maborak/samples/post.php create mode 100644 gulliver/js/maborak/samples/processmap.html create mode 100644 gulliver/js/maborak/samples/processmap2.html create mode 100644 gulliver/js/maborak/samples/report.html create mode 100644 gulliver/js/maborak/samples/rss.html create mode 100644 gulliver/js/maborak/samples/rss.xml create mode 100644 gulliver/js/maborak/samples/rss2.xml create mode 100644 gulliver/js/maborak/samples/s.html create mode 100644 gulliver/js/maborak/samples/sample.php create mode 100644 gulliver/js/maborak/samples/sampleGrids.php create mode 100644 gulliver/js/maborak/samples/services.html create mode 100644 gulliver/js/maborak/samples/sl.html create mode 100644 gulliver/js/maborak/samples/sl.php create mode 100644 gulliver/js/maborak/samples/slide.php create mode 100644 gulliver/js/maborak/samples/style.css create mode 100644 gulliver/js/maborak/samples/style.panel.css create mode 100644 gulliver/js/maborak/samples/xmlform.html create mode 100755 gulliver/js/md5/core/md5.js create mode 100755 gulliver/js/thirdparty/krumo/krumo.js create mode 100755 gulliver/js/widgets/calendar/pmcalendar.js create mode 100755 gulliver/js/widgets/js-calendar/css/border-radius.css create mode 100755 gulliver/js/widgets/js-calendar/css/gold/brushed-steel.jpg create mode 100755 gulliver/js/widgets/js-calendar/css/gold/coolbg.png create mode 100755 gulliver/js/widgets/js-calendar/css/gold/gold.css create mode 100755 gulliver/js/widgets/js-calendar/css/gold/gold.jpg create mode 100755 gulliver/js/widgets/js-calendar/css/img/cool-bg-hard-inv.png create mode 100755 gulliver/js/widgets/js-calendar/css/img/cool-bg-hard.png create mode 100755 gulliver/js/widgets/js-calendar/css/img/cool-bg-inv.png create mode 100755 gulliver/js/widgets/js-calendar/css/img/cool-bg.png create mode 100755 gulliver/js/widgets/js-calendar/css/img/drop-down.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/drop-up.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/nav-left-x2.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/nav-left.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/nav-right-x2.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/nav-right.gif create mode 100755 gulliver/js/widgets/js-calendar/css/img/time-down.png create mode 100755 gulliver/js/widgets/js-calendar/css/img/time-up.png create mode 100755 gulliver/js/widgets/js-calendar/css/jscal2.css create mode 100755 gulliver/js/widgets/js-calendar/css/matrix/matrix.css create mode 100755 gulliver/js/widgets/js-calendar/css/matrix/nav-left-x2.gif create mode 100755 gulliver/js/widgets/js-calendar/css/matrix/nav-left.gif create mode 100755 gulliver/js/widgets/js-calendar/css/matrix/nav-right-x2.gif create mode 100755 gulliver/js/widgets/js-calendar/css/matrix/nav-right.gif create mode 100755 gulliver/js/widgets/js-calendar/css/reduce-spacing.css create mode 100755 gulliver/js/widgets/js-calendar/css/shadow-b.png create mode 100755 gulliver/js/widgets/js-calendar/css/steel/brushed-steel.jpg create mode 100755 gulliver/js/widgets/js-calendar/css/steel/brushed-steel.png create mode 100755 gulliver/js/widgets/js-calendar/css/steel/coolbg.png create mode 100755 gulliver/js/widgets/js-calendar/css/steel/steel.css create mode 100755 gulliver/js/widgets/js-calendar/css/steel/steel.jpg create mode 100755 gulliver/js/widgets/js-calendar/css/win2k/win2k.css create mode 100755 gulliver/js/widgets/js-calendar/js-calendar.js create mode 100755 gulliver/js/widgets/js-calendar/lang/ca.js create mode 100755 gulliver/js/widgets/js-calendar/lang/cn.js create mode 100755 gulliver/js/widgets/js-calendar/lang/cz.js create mode 100755 gulliver/js/widgets/js-calendar/lang/de.js create mode 100755 gulliver/js/widgets/js-calendar/lang/en.js create mode 100755 gulliver/js/widgets/js-calendar/lang/es.js create mode 100755 gulliver/js/widgets/js-calendar/lang/fr.js create mode 100755 gulliver/js/widgets/js-calendar/lang/it.js create mode 100755 gulliver/js/widgets/js-calendar/lang/jp.js create mode 100755 gulliver/js/widgets/js-calendar/lang/nl.js create mode 100755 gulliver/js/widgets/js-calendar/lang/pl.js create mode 100755 gulliver/js/widgets/js-calendar/lang/pt.js create mode 100755 gulliver/js/widgets/js-calendar/lang/ro.js create mode 100755 gulliver/js/widgets/js-calendar/lang/ru.js create mode 100755 gulliver/js/widgets/js-calendar/lang/sv.js create mode 100644 gulliver/js/widgets/jscalendar/calendar.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-af.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-al.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-bg.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-big5-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-big5.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-br.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ca.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-cs-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-cs-win.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-da.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-de.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-du.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-el.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-en.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-es.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-fi.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-fr.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-he-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-hr-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-hr.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-hu.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-it.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-jp.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ko-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ko.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-lt-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-lt.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-lv.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-nl.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-no.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-pl-utf8.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-pl.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-pt.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ro.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ru.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-ru_win_.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-si.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-sk.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-sp.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-sv.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-tr.js create mode 100644 gulliver/js/widgets/jscalendar/lang/calendar-zh.js create mode 100644 gulliver/js/widgets/jscalendar/lang/cn_utf8.js create mode 100644 gulliver/js/widgets/suggest/bsn.AutoSuggest_2.1.3.js create mode 100644 gulliver/js/widgets/suggest/bsn.AutoSuggest_2.1.3_comp.js create mode 100644 gulliver/js/widgets/suggest/css/._.DS_Store create mode 100644 gulliver/js/widgets/suggest/css/autosuggest_inquisitor.css create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._.DS_Store create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._as_pointer.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._hl_corner_bl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._hl_corner_br.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._hl_corner_tl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._hl_corner_tr.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._ul_corner_bl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._ul_corner_br.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._ul_corner_tl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/._ul_corner_tr.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/._.DS_Store create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/._as_pointer.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/._li_corner.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/._ul_corner.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/as_pointer.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/li_corner.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/_source/ul_corner.png create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/as_pointer.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/hl_corner_bl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/hl_corner_br.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/hl_corner_tl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/hl_corner_tr.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/ul_corner_bl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/ul_corner_br.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/ul_corner_tl.gif create mode 100644 gulliver/js/widgets/suggest/css/img_inquisitor/ul_corner_tr.gif create mode 100644 gulliver/js/widgets/suggest/server/widget.suggest.php create mode 100755 gulliver/js/widgets/tooltip/pmtooltip.js create mode 100644 gulliver/methods/controls/Calendar-32x32.png create mode 100644 gulliver/methods/controls/TrashIcon.jpg create mode 100644 gulliver/methods/controls/cal.gif create mode 100644 gulliver/methods/controls/calendar.php create mode 100644 gulliver/methods/controls/next.gif create mode 100644 gulliver/methods/controls/next_year.gif create mode 100644 gulliver/methods/controls/pixel.gif create mode 100644 gulliver/methods/controls/prev.gif create mode 100644 gulliver/methods/controls/prev_year.gif create mode 100644 gulliver/methods/decorator.php create mode 100644 gulliver/methods/defaultAjax.php create mode 100644 gulliver/methods/defaultAjaxDynaform.php create mode 100644 gulliver/methods/errors/error.php create mode 100644 gulliver/methods/errors/error400.php create mode 100644 gulliver/methods/errors/error401.php create mode 100644 gulliver/methods/errors/error403.php create mode 100644 gulliver/methods/errors/error404.php create mode 100644 gulliver/methods/errors/error503.php create mode 100644 gulliver/methods/errors/error701.php create mode 100644 gulliver/methods/errors/error702.php create mode 100644 gulliver/methods/errors/error703.php create mode 100644 gulliver/methods/errors/error704.php create mode 100644 gulliver/methods/errors/header.php create mode 100644 gulliver/methods/errors/style.css create mode 100644 gulliver/methods/genericAjax.php create mode 100644 gulliver/methods/pagedTableAjax.php create mode 100644 gulliver/methods/propelTableAjax.php create mode 100644 gulliver/methods/streamFile.php create mode 100644 gulliver/system/VERSION create mode 100644 gulliver/system/class.database_base.php create mode 100644 gulliver/system/class.database_mssql.php create mode 100644 gulliver/system/class.database_mysql.php create mode 100755 gulliver/system/class.dbMaintenance.php create mode 100644 gulliver/system/class.dbconnection.php create mode 100644 gulliver/system/class.dbrecordset.php create mode 100644 gulliver/system/class.dbsession.php create mode 100644 gulliver/system/class.dbtable.php create mode 100644 gulliver/system/class.dvEditor.php create mode 100755 gulliver/system/class.dynaformhandler.php create mode 100644 gulliver/system/class.error.php create mode 100644 gulliver/system/class.fckEditor.php create mode 100644 gulliver/system/class.filterForm.php create mode 100644 gulliver/system/class.form.php create mode 100644 gulliver/system/class.functionTest.php create mode 100644 gulliver/system/class.g.php create mode 100644 gulliver/system/class.headPublisher.php create mode 100644 gulliver/system/class.helper.php create mode 100644 gulliver/system/class.htmlArea.php create mode 100755 gulliver/system/class.i18n_po.php create mode 100644 gulliver/system/class.mailer.php create mode 100644 gulliver/system/class.menu.php create mode 100644 gulliver/system/class.objectTemplate.php create mode 100644 gulliver/system/class.pagedTable.php create mode 100644 gulliver/system/class.publisher.php create mode 100644 gulliver/system/class.rbac.php create mode 100644 gulliver/system/class.table.php create mode 100644 gulliver/system/class.templatePower.php create mode 100644 gulliver/system/class.testTools.php create mode 100644 gulliver/system/class.tree.php create mode 100644 gulliver/system/class.unitTest.php create mode 100644 gulliver/system/class.webResource.php create mode 100644 gulliver/system/class.xmlDocument.php create mode 100644 gulliver/system/class.xmlMenu.php create mode 100644 gulliver/system/class.xmlform.php create mode 100644 gulliver/system/class.xmlformExtension.php create mode 100644 gulliver/system/class.ymlDomain.php create mode 100644 gulliver/system/class.ymlTestCases.php create mode 100644 gulliver/templates/menu.html create mode 100644 gulliver/templates/submenu.html create mode 100644 gulliver/templates/xmlform.html create mode 100644 gulliver/thirdparty/codepress/codepress.css create mode 100644 gulliver/thirdparty/codepress/codepress.html create mode 100755 gulliver/thirdparty/codepress/codepress.js create mode 100644 gulliver/thirdparty/codepress/engines/gecko.js create mode 100644 gulliver/thirdparty/codepress/engines/khtml.js create mode 100644 gulliver/thirdparty/codepress/engines/msie.js create mode 100644 gulliver/thirdparty/codepress/engines/older.js create mode 100644 gulliver/thirdparty/codepress/engines/opera.js create mode 100644 gulliver/thirdparty/codepress/images/line-numbers.png create mode 100644 gulliver/thirdparty/codepress/index.html create mode 100644 gulliver/thirdparty/codepress/languages/asp.css create mode 100644 gulliver/thirdparty/codepress/languages/asp.js create mode 100644 gulliver/thirdparty/codepress/languages/autoit.css create mode 100644 gulliver/thirdparty/codepress/languages/autoit.js create mode 100644 gulliver/thirdparty/codepress/languages/csharp.css create mode 100644 gulliver/thirdparty/codepress/languages/csharp.js create mode 100644 gulliver/thirdparty/codepress/languages/css.css create mode 100644 gulliver/thirdparty/codepress/languages/css.js create mode 100644 gulliver/thirdparty/codepress/languages/generic.css create mode 100644 gulliver/thirdparty/codepress/languages/generic.js create mode 100644 gulliver/thirdparty/codepress/languages/html.css create mode 100644 gulliver/thirdparty/codepress/languages/html.js create mode 100644 gulliver/thirdparty/codepress/languages/java.css create mode 100644 gulliver/thirdparty/codepress/languages/java.js create mode 100644 gulliver/thirdparty/codepress/languages/javascript.css create mode 100644 gulliver/thirdparty/codepress/languages/javascript.js create mode 100644 gulliver/thirdparty/codepress/languages/perl.css create mode 100644 gulliver/thirdparty/codepress/languages/perl.js create mode 100644 gulliver/thirdparty/codepress/languages/php.css create mode 100644 gulliver/thirdparty/codepress/languages/php.js create mode 100644 gulliver/thirdparty/codepress/languages/ruby.css create mode 100644 gulliver/thirdparty/codepress/languages/ruby.js create mode 100644 gulliver/thirdparty/codepress/languages/sql.css create mode 100644 gulliver/thirdparty/codepress/languages/sql.js create mode 100644 gulliver/thirdparty/codepress/languages/text.css create mode 100644 gulliver/thirdparty/codepress/languages/text.js create mode 100644 gulliver/thirdparty/codepress/languages/vbscript.css create mode 100644 gulliver/thirdparty/codepress/languages/vbscript.js create mode 100644 gulliver/thirdparty/codepress/languages/xmlform.css create mode 100644 gulliver/thirdparty/codepress/languages/xmlform.js create mode 100644 gulliver/thirdparty/codepress/languages/xsl.css create mode 100644 gulliver/thirdparty/codepress/languages/xsl.js create mode 100644 gulliver/thirdparty/codepress/license.txt create mode 100644 gulliver/thirdparty/creole/CallableStatement.php create mode 100644 gulliver/thirdparty/creole/Connection.php create mode 100644 gulliver/thirdparty/creole/Creole.php create mode 100644 gulliver/thirdparty/creole/CreoleTypes.php create mode 100644 gulliver/thirdparty/creole/IdGenerator.php create mode 100644 gulliver/thirdparty/creole/PreparedStatement.php create mode 100644 gulliver/thirdparty/creole/ResultSet.php create mode 100644 gulliver/thirdparty/creole/ResultSetIterator.php create mode 100644 gulliver/thirdparty/creole/SQLException.php create mode 100644 gulliver/thirdparty/creole/Statement.php create mode 100644 gulliver/thirdparty/creole/common/ConnectionCommon.php create mode 100644 gulliver/thirdparty/creole/common/PreparedStatementCommon.php create mode 100644 gulliver/thirdparty/creole/common/ResultSetCommon.php create mode 100644 gulliver/thirdparty/creole/common/StatementCommon.php create mode 100644 gulliver/thirdparty/creole/contrib/DBArrayConnection.php create mode 100644 gulliver/thirdparty/creole/contrib/DebugConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLCallableStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLPreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/MSSQLTypes.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/metadata/MSSQLDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/mssql/metadata/MSSQLTableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLPreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/MySQLTypes.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/metadata/MySQLDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/mysql/metadata/MySQLTableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/MySQLiConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/MySQLiIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/MySQLiPreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/MySQLiResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/MySQLiStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/metadata/MySQLiDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/mysqli/metadata/MySQLiTableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCCachedResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCPreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCResultSetCommon.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/ODBCTypes.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/README create mode 100644 gulliver/thirdparty/creole/drivers/odbc/adapters/CodeBaseAdapter.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/adapters/MySQLAdapter.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/adapters/ODBCAdapter.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/odbc/metadata/ODBCTableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8Connection.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8IdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8PreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8ResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8Statement.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/OCI8Types.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/metadata/OCI8DatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/oracle/metadata/OCI8TableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLPreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLResultSetIterator.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/PgSQLTypes.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/pgsql/metadata/PgSQLTableInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteConnection.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteIdGenerator.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLitePreparedStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteResultSet.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteResultSetIterator.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteStatement.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/SQLiteTypes.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/metadata/SQLiteDatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/drivers/sqlite/metadata/SQLiteTableInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/ColumnInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/DatabaseInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/ForeignKeyInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/IndexInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/PrimaryKeyInfo.php create mode 100644 gulliver/thirdparty/creole/metadata/TableInfo.php create mode 100644 gulliver/thirdparty/creole/util/Blob.php create mode 100644 gulliver/thirdparty/creole/util/Clob.php create mode 100644 gulliver/thirdparty/creole/util/Lob.php create mode 100644 gulliver/thirdparty/creole/util/sql/SQLStatementExtractor.php create mode 100644 gulliver/thirdparty/geshi/contrib/aliased.php create mode 100644 gulliver/thirdparty/geshi/contrib/cssgen.php create mode 100644 gulliver/thirdparty/geshi/contrib/cssgen2.php create mode 100644 gulliver/thirdparty/geshi/contrib/example.php create mode 100644 gulliver/thirdparty/geshi/contrib/langcheck.php create mode 100644 gulliver/thirdparty/geshi/geshi.php create mode 100644 gulliver/thirdparty/geshi/geshi/bash.php create mode 100644 gulliver/thirdparty/geshi/geshi/javascript.php create mode 100644 gulliver/thirdparty/geshi/geshi/jquery.php create mode 100644 gulliver/thirdparty/geshi/geshi/php.php create mode 100644 gulliver/thirdparty/geshi/geshi/xml.php create mode 100644 gulliver/thirdparty/html2ps_pdf/.htaccess create mode 100644 gulliver/thirdparty/html2ps_pdf/autofix.url.php create mode 100644 gulliver/thirdparty/html2ps_pdf/background.image.php create mode 100644 gulliver/thirdparty/html2ps_pdf/background.position.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.block.inline.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.block.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.body.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.br.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.button.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.button.reset.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.button.submit.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.checkbutton.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.container.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.field.pageno.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.field.pages.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.form.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.frame.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.generic.formatted.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.generic.inline.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.generic.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.iframe.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.img.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.inline.control.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.inline.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.inline.simple.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.input.img.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.input.password.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.input.text.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.input.textarea.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.legend.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.list-item.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.note-call.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.null.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.page.margin.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.page.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.radiobutton.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.select.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.table.cell.fake.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.table.cell.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.table.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.table.row.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.table.section.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.text.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.text.string.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.utils.text-align.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/box.whitespace.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/include.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/doc/DocHTML.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/doc/Method.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/doc/PHPClass.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/net/HTTPClient.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/net/HTTPServer.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/net/Socket.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/sys/File.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/Branch.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/Leaf.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/RSS.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/Tag.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/Tree.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XML.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XMLBranch.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XMLDocument.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XMLLeaf.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XMLRPCClient.php create mode 100644 gulliver/thirdparty/html2ps_pdf/classes/org/active-link/xml/XPath.php create mode 100644 gulliver/thirdparty/html2ps_pdf/config.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/config.parse.php create mode 100644 gulliver/thirdparty/html2ps_pdf/content_type.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/converter.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.attachment.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.image.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.position.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.background.repeat.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.bottom.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.bottom.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.bottom.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.bottom.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.collapse.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.left.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.left.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.left.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.left.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.right.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.right.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.right.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.right.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.top.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.top.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.top.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.top.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.border.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.bottom.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.cache.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.clear.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.color.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.colors.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.constants.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.content.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.counter.collection.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.counter.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.direction.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.display.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.float.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.font-family.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.font-size.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.font-style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.font-weight.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.font.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.frame.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.height.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.html2ps.html.content.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.html2ps.pseudoelements.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.left.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.letter-spacing.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.line-height.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.list-style-image.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.list-style-position.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.list-style-type.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.list-style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.margin.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.max-height.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.min-height.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.min-width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.orphans.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.overflow.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.padding.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.page-break-after.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.page-break-before.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.page-break-inside.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.page-break.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.page.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.parse.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.parse.media.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.parse.properties.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.position.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.collection.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.declaration.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.handler.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.stringset.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.sub.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.property.sub.field.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.add.margin.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.align.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.cellpadding.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.cellspacing.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.form.action.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.form.radiogroup.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.link.destination.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.link.target.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.listcounter.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.localalign.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.nowrap.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.pseudo.table.border.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.right.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.rules.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.rules.page.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.ruleset.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.selectors.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.state.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.table-layout.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.text-align.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.text-decoration.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.text-indent.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.text-transform.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.top.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.utils.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.vertical-align.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.visibility.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.white-space.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.widows.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.width.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.word-spacing.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/css.z-index.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/default.css create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/.htaccess create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/generic.param.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/html2ps.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/htmltopdf.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/index.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/phpinfo.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/systemcheck.footer.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/systemcheck.header.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/systemcheck.php create mode 100644 gulliver/thirdparty/html2ps_pdf/demo/test.php create mode 100644 gulliver/thirdparty/html2ps_pdf/destination._http.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/destination._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/destination.browser.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/destination.download.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/destination.file.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/dispatcher.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/doc.anchor.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/dom.activelink.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/dom.php5.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.cp1251.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.cp866.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.dingbats.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.entities.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.glyphs.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-1.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-10.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-11.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-13.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-14.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-15.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-2.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-3.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-4.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-5.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-6.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-7.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-8.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.iso-8859-9.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.koi8-r.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.symbol.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.windows-1250.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.windows-1251.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/encoding.windows-1252.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/error.php create mode 100644 gulliver/thirdparty/html2ps_pdf/favicon.ico create mode 100644 gulliver/thirdparty/html2ps_pdf/fetched_data._html.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetched_data._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetched_data.file.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetched_data.url.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetcher._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetcher.local.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetcher.memory.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetcher.url.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fetcher.url.curl.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.doctype.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.encoding.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.html2xhtml.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.ucs2.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.utf8.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.data.xhtml2xhtml.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.output._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.output.gzip.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.output.ps2pdf.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.post._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.post.positioned.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.post.postponed.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.pre._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.pre.fields.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.pre.footnotes.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.pre.headfoot.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/filter.pre.height-constraint.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/flow_context.class.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/flow_viewport.class.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/font.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/font.constants.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/font.resolver.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/font_factory.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arial.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arial.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arialbd.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arialbd.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arialbi.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/arialbi.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/ariali.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/ariali.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/cour.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/cour.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/courbd.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/courbd.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/courbi.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/courbi.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/couri.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/couri.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/georgia.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/georgiab.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/georgiai.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/georgiaz.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/print_glyphs.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/symbol.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/symbol.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/times.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/times.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesbd.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesbd.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesbi.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesbi.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesi.afm create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/timesi.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/verdana.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/verdanab.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/verdanai.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fonts/verdanaz.ttf create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1250.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1251.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1252.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1253.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1254.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1255.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1257.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp1258.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/cp874.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-1.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-11.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-15.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-16.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-2.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-4.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-5.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-7.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/iso-8859-9.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/koi8-r.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/koi8-u.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/makefont.php create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/font/makefont/symbol.map create mode 100644 gulliver/thirdparty/html2ps_pdf/fpdf/fpdf.php create mode 100644 gulliver/thirdparty/html2ps_pdf/globals.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/globals.php create mode 100644 gulliver/thirdparty/html2ps_pdf/height.php create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Custom_fetcher_session.png create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Data_filters.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Destinations.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Fetchers.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Layout_engines.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Multiple_fetcher_session.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Output_drivers.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Output_filters.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Parsers.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Post_filters.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Pre_filters.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Simple_custom_fetcher_session.png create mode 100644 gulliver/thirdparty/html2ps_pdf/help/UML/Simple_fetcher_session.PNG create mode 100644 gulliver/thirdparty/html2ps_pdf/help/api.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/api_events.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/api_fetchers.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/api_samples.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/calling.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/compatibility.css.2.1.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/compatibility.css.3.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/configuration.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/css/help.css create mode 100644 gulliver/thirdparty/html2ps_pdf/help/directives.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/faq.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/forms.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/howto_afm.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/howto_fonts.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/index.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/install.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/misc.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/requirements.html create mode 100644 gulliver/thirdparty/html2ps_pdf/help/samples/headfoot.html create mode 100644 gulliver/thirdparty/html2ps_pdf/html.attrs.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/html2ps.config create mode 100644 gulliver/thirdparty/html2ps_pdf/html2ps.config.recommended create mode 100644 gulliver/thirdparty/html2ps_pdf/image.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/index.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.factory.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.normal.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.nowrap.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.pre.line.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.pre.php create mode 100644 gulliver/thirdparty/html2ps_pdf/inline.content.builder.pre.wrap.php create mode 100644 gulliver/thirdparty/html2ps_pdf/layout._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/layout.default.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/layout.page.breaks.php create mode 100644 gulliver/thirdparty/html2ps_pdf/layout.vertical.php create mode 100644 gulliver/thirdparty/html2ps_pdf/list-style.image.php create mode 100644 gulliver/thirdparty/html2ps_pdf/manager.encoding.php create mode 100644 gulliver/thirdparty/html2ps_pdf/media.layout.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/observer.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ot.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/out/readme.txt create mode 100644 gulliver/thirdparty/html2ps_pdf/output._generic.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output._generic.pdf.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output._generic.ps.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.fastps.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.fastps.l2.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.fpdf.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.pcl.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.pdflib.1.6.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.pdflib.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.pdflib.old.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/output.png.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/parser._interface.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/parser.xhtml.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/path.php create mode 100644 gulliver/thirdparty/html2ps_pdf/path.point.php create mode 100644 gulliver/thirdparty/html2ps_pdf/path.rectangle.php create mode 100644 gulliver/thirdparty/html2ps_pdf/pdf.fpdf.makefont.php create mode 100644 gulliver/thirdparty/html2ps_pdf/pdf.fpdf.php create mode 100644 gulliver/thirdparty/html2ps_pdf/pipeline.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/pipeline.factory.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/array.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/background.image.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/background.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/border.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.block.inline.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.block.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.break.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.button.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.checkbutton.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.container.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.frame.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.generic.inline.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.generic.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.iframe.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.image.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.inline.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.inline.whitespace.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.input.check.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.input.radio.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.input.text.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.list-item.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.radiobutton.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.select.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.span.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.table.cell.fake.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.table.cell.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.table.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.table.row.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.text.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/box.whitespace.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/cellspan.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/class.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/color.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/containing_block.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/context.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.dingbats.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-10.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-11.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-13.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-14.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-15.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-2.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-3.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-4.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-5.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-7.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.iso-8859-9.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.koi8-r.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.symbol.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.windows-1250.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.windows-1251.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/encoding.windows-1252.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/fastps.footer.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/fastps.header.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.block.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.box.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.float.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.inline.block.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.inline.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.legend.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow.table.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/flow_viewport.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/font.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/footer.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/geometry.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/header.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/height.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/image.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/init.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/position.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/predicates.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/table.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/table.row.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/text-align.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/vertical-align.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/viewport.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/postscript/width.ps create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.image.encoder.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.image.encoder.simple.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.image.encoder.stream.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.l2.image.encoder.stream.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.l3.image.encoder.stream.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.unicode.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.utils.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/ps.whitespace.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/render.queue.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/render.stacking.context.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/render.stacking.level.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/out/readme.txt create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.batch.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.form.handler.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.pipeline.custom.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.pipeline.default.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.simplest.from.file.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.simplest.from.memory.php create mode 100644 gulliver/thirdparty/html2ps_pdf/samples/sample.simplest.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.link.rendering.normal.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.position.absolute.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.table.layout.auto.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.table.layout.fixed.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.width.absolute.positioned.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.width.max.natural.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.width.max.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.width.min.nowrap.php create mode 100644 gulliver/thirdparty/html2ps_pdf/strategy.width.min.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs._.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs.common.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs.file_get_contents.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs.file_put_contents.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs.is_executable.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/stubs.memory_get_usage.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.body.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.font.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.frame.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.img.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.input.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.select.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.span.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.table.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.td.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/tag.utils.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/temp/readme.txt create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/cannot_parse.html create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._connection.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._footer.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._header.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._http.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._missing_afm.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._no_fetchers.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error._redirects.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/error_exec.tpl create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/missing_exec.html create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/missing_gs.html create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/missing_pdflib.html create mode 100644 gulliver/thirdparty/html2ps_pdf/templates/missing_url_fopen.html create mode 100644 gulliver/thirdparty/html2ps_pdf/tree.navigation.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/treebuilder.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_array.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_graphic.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_number.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_text.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_units.php create mode 100644 gulliver/thirdparty/html2ps_pdf/utils_url.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.background.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.border.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.border.color.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.border.edge.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.border.style.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.border.width.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.bottom.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.color.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.content.item.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.content.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.font.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.generic.length.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.generic.percentage.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.generic.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.height.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.left.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.line-height.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.list-style.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.margin.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.max-height.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.min-height.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.padding.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.right.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.text-indent.class.php create mode 100644 gulliver/thirdparty/html2ps_pdf/value.top.php create mode 100644 gulliver/thirdparty/html2ps_pdf/width.constraint.php create mode 100644 gulliver/thirdparty/html2ps_pdf/width.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.autoclose.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.comments.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.deflist.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.entities.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.lists.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.p.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.script.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.selects.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.style.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.tables.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xhtml.utils.inc.php create mode 100644 gulliver/thirdparty/html2ps_pdf/xml.validation.inc.php create mode 100644 gulliver/thirdparty/htmlarea/editor.js create mode 100644 gulliver/thirdparty/htmlarea/example.html create mode 100644 gulliver/thirdparty/htmlarea/images/Thumbs.db create mode 100644 gulliver/thirdparty/htmlarea/images/ed_about.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_align_center.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_align_left.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_align_right.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_blank.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_charmap.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_color_bg.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_color_fg.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_copy.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_custom.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_cut.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_delete.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_bold.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_italic.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_strike.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_sub.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_sup.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_format_underline.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_help.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_hr.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_html.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_image.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_indent_less.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_indent_more.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_link.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_list_bullet.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_list_num.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_redo.gif create mode 100644 gulliver/thirdparty/htmlarea/images/ed_undo.gif create mode 100644 gulliver/thirdparty/htmlarea/images/fullscreen_maximize.gif create mode 100644 gulliver/thirdparty/htmlarea/images/fullscreen_minimize.gif create mode 100644 gulliver/thirdparty/htmlarea/images/insert_table.gif create mode 100644 gulliver/thirdparty/htmlarea/license.txt create mode 100644 gulliver/thirdparty/htmlarea/popups/about.html create mode 100644 gulliver/thirdparty/htmlarea/popups/blank.html create mode 100644 gulliver/thirdparty/htmlarea/popups/custom2.html create mode 100644 gulliver/thirdparty/htmlarea/popups/editor_help.html create mode 100644 gulliver/thirdparty/htmlarea/popups/fullscreen.html create mode 100644 gulliver/thirdparty/htmlarea/popups/insert_image.html create mode 100644 gulliver/thirdparty/htmlarea/popups/insert_table.html create mode 100644 gulliver/thirdparty/htmlarea/popups/select_color.html create mode 100644 gulliver/thirdparty/htmlarea/readme.html create mode 100644 gulliver/thirdparty/jsmin/jsmin.php create mode 100644 gulliver/thirdparty/krumo/INSTALL create mode 100644 gulliver/thirdparty/krumo/LICENSE create mode 100644 gulliver/thirdparty/krumo/README create mode 100644 gulliver/thirdparty/krumo/TODO create mode 100644 gulliver/thirdparty/krumo/VERSION create mode 100644 gulliver/thirdparty/krumo/class.krumo.php create mode 100644 gulliver/thirdparty/krumo/docs/Krumo/_class.krumo.php.html create mode 100644 gulliver/thirdparty/krumo/docs/Krumo/_class_krumo_php.html create mode 100644 gulliver/thirdparty/krumo/docs/Krumo/krumo.html create mode 100644 gulliver/thirdparty/krumo/docs/blank.html create mode 100644 gulliver/thirdparty/krumo/docs/classtrees_Krumo.html create mode 100644 gulliver/thirdparty/krumo/docs/elementindex.html create mode 100644 gulliver/thirdparty/krumo/docs/elementindex_Krumo.html create mode 100644 gulliver/thirdparty/krumo/docs/errors.html create mode 100644 gulliver/thirdparty/krumo/docs/index.html create mode 100644 gulliver/thirdparty/krumo/docs/li_Krumo.html create mode 100644 gulliver/thirdparty/krumo/docs/media/banner.css create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractClass.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractClass_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractMethod.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateClass.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateClass_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateMethod.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Class.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Class_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Constant.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Constructor.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Destructor.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Function.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Global.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/I.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Index.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Interface.PNG create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Interface_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/L.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Lminus.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Lplus.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Method.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Page.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Page_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/PrivateClass.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/PrivateClass_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/PrivateMethod.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/PrivateVariable.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/StaticMethod.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/StaticVariable.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/T.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Tminus.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Tplus.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/Variable.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/blank.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/class_folder.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/empty.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/file.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/folder.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/function_folder.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/minus.gif create mode 100644 gulliver/thirdparty/krumo/docs/media/images/next_button.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/next_button_disabled.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/package.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/package_folder.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/plus.gif create mode 100644 gulliver/thirdparty/krumo/docs/media/images/previous_button.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/previous_button_disabled.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/private_class_logo.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/tutorial.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/tutorial_folder.png create mode 100644 gulliver/thirdparty/krumo/docs/media/images/up_button.png create mode 100644 gulliver/thirdparty/krumo/docs/media/lib/classTree.js create mode 100644 gulliver/thirdparty/krumo/docs/media/stylesheet.css create mode 100644 gulliver/thirdparty/krumo/docs/packages.html create mode 100644 gulliver/thirdparty/krumo/docs/ric_INSTALL.html create mode 100644 gulliver/thirdparty/krumo/docs/ric_LICENSE.html create mode 100644 gulliver/thirdparty/krumo/docs/ric_README.html create mode 100644 gulliver/thirdparty/krumo/docs/ric_TODO.html create mode 100644 gulliver/thirdparty/krumo/docs/ric_VERSION.html create mode 100644 gulliver/thirdparty/krumo/krumo.ini create mode 100644 gulliver/thirdparty/krumo/krumo.js create mode 100644 gulliver/thirdparty/krumo/skins/blue/bg.gif create mode 100644 gulliver/thirdparty/krumo/skins/blue/skin.css create mode 100644 gulliver/thirdparty/krumo/skins/default/bg.gif create mode 100644 gulliver/thirdparty/krumo/skins/default/skin.css create mode 100644 gulliver/thirdparty/krumo/skins/green/bg.gif create mode 100644 gulliver/thirdparty/krumo/skins/green/skin.css create mode 100644 gulliver/thirdparty/krumo/skins/orange/bg.gif create mode 100644 gulliver/thirdparty/krumo/skins/orange/skin.css create mode 100644 gulliver/thirdparty/krumo/skins/schablon.com/collapsed.gif create mode 100644 gulliver/thirdparty/krumo/skins/schablon.com/dotted.gif create mode 100644 gulliver/thirdparty/krumo/skins/schablon.com/empty.gif create mode 100644 gulliver/thirdparty/krumo/skins/schablon.com/expanded.gif create mode 100644 gulliver/thirdparty/krumo/skins/schablon.com/skin.css create mode 100644 gulliver/thirdparty/libchart/COPYING create mode 100644 gulliver/thirdparty/libchart/ChangeLog create mode 100644 gulliver/thirdparty/libchart/README create mode 100644 gulliver/thirdparty/libchart/classes/libchart.php create mode 100644 gulliver/thirdparty/libchart/classes/model/DataSet.php create mode 100644 gulliver/thirdparty/libchart/classes/model/Point.php create mode 100644 gulliver/thirdparty/libchart/classes/model/XYDataSet.php create mode 100644 gulliver/thirdparty/libchart/classes/model/XYSeriesDataSet.php create mode 100644 gulliver/thirdparty/libchart/classes/view/axis/Axis.php create mode 100644 gulliver/thirdparty/libchart/classes/view/axis/Bound.php create mode 100644 gulliver/thirdparty/libchart/classes/view/caption/Caption.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/BarChart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/Chart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/HorizontalBarChart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/LineChart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/PieChart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/chart/VerticalBarChart.php create mode 100644 gulliver/thirdparty/libchart/classes/view/color/Color.php create mode 100644 gulliver/thirdparty/libchart/classes/view/color/ColorSet.php create mode 100644 gulliver/thirdparty/libchart/classes/view/color/Palette.php create mode 100644 gulliver/thirdparty/libchart/classes/view/plot/Plot.php create mode 100644 gulliver/thirdparty/libchart/classes/view/primitive/Padding.php create mode 100644 gulliver/thirdparty/libchart/classes/view/primitive/Primitive.php create mode 100644 gulliver/thirdparty/libchart/classes/view/primitive/Rectangle.php create mode 100644 gulliver/thirdparty/libchart/classes/view/text/Text.php create mode 100644 gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed-Bold.ttf create mode 100644 gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed.ttf create mode 100644 gulliver/thirdparty/libchart/images/PoweredBy.png create mode 100644 gulliver/thirdparty/lime/Spyc.class.php create mode 100644 gulliver/thirdparty/lime/lime.php create mode 100644 gulliver/thirdparty/lime/yaml.class.php create mode 100644 gulliver/thirdparty/pake/pakeApp.class.php create mode 100644 gulliver/thirdparty/pake/pakeColor.class.php create mode 100644 gulliver/thirdparty/pake/pakeException.class.php create mode 100644 gulliver/thirdparty/pake/pakeFileTask.class.php create mode 100644 gulliver/thirdparty/pake/pakeFinder.class.php create mode 100644 gulliver/thirdparty/pake/pakeFunction.php create mode 100644 gulliver/thirdparty/pake/pakeGetopt.class.php create mode 100644 gulliver/thirdparty/pake/pakeGlobToRegex.class.php create mode 100644 gulliver/thirdparty/pake/pakeNumberCompare.class.php create mode 100644 gulliver/thirdparty/pake/pakeTask.class.php create mode 100644 gulliver/thirdparty/pake/pakeYaml.class.php create mode 100644 gulliver/thirdparty/pake/tasks/pakePearTask.class.php create mode 100644 gulliver/thirdparty/pake/tasks/pakePhingTask.class.php create mode 100644 gulliver/thirdparty/pake/tasks/pakeSimpletestTask.class.php create mode 100644 gulliver/thirdparty/pear/Archive/Tar.php create mode 100755 gulliver/thirdparty/pear/Archive/Zip.php create mode 100755 gulliver/thirdparty/pear/Benchmark/Iterate.php create mode 100755 gulliver/thirdparty/pear/Benchmark/Profiler.php create mode 100755 gulliver/thirdparty/pear/Benchmark/Timer.php create mode 100644 gulliver/thirdparty/pear/CMD.php create mode 100644 gulliver/thirdparty/pear/CODING_STANDARDS create mode 100644 gulliver/thirdparty/pear/Console/Getopt.php create mode 100644 gulliver/thirdparty/pear/DB.php create mode 100644 gulliver/thirdparty/pear/DB/common.php create mode 100644 gulliver/thirdparty/pear/DB/dbase.php create mode 100644 gulliver/thirdparty/pear/DB/fbsql.php create mode 100644 gulliver/thirdparty/pear/DB/ibase.php create mode 100644 gulliver/thirdparty/pear/DB/ifx.php create mode 100644 gulliver/thirdparty/pear/DB/msql.php create mode 100644 gulliver/thirdparty/pear/DB/mssql.php create mode 100644 gulliver/thirdparty/pear/DB/mysql.php create mode 100644 gulliver/thirdparty/pear/DB/mysqli.php create mode 100644 gulliver/thirdparty/pear/DB/oci8.php create mode 100644 gulliver/thirdparty/pear/DB/odbc.php create mode 100644 gulliver/thirdparty/pear/DB/pgsql.php create mode 100644 gulliver/thirdparty/pear/DB/sqlite.php create mode 100644 gulliver/thirdparty/pear/DB/storage.php create mode 100644 gulliver/thirdparty/pear/DB/sybase.php create mode 100644 gulliver/thirdparty/pear/HTTP/HTTP.php create mode 100644 gulliver/thirdparty/pear/HTTP/Request.php create mode 100644 gulliver/thirdparty/pear/HTTP/WebDAV/Server.php create mode 100644 gulliver/thirdparty/pear/HTTP/WebDAV/Server/Filesystem.php create mode 100644 gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_lockinfo.php create mode 100644 gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_propfind.php create mode 100644 gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_proppatch.php create mode 100644 gulliver/thirdparty/pear/Log.php create mode 100644 gulliver/thirdparty/pear/Log/composite.php create mode 100644 gulliver/thirdparty/pear/Log/console.php create mode 100644 gulliver/thirdparty/pear/Log/daemon.php create mode 100644 gulliver/thirdparty/pear/Log/display.php create mode 100644 gulliver/thirdparty/pear/Log/error_log.php create mode 100644 gulliver/thirdparty/pear/Log/file.php create mode 100644 gulliver/thirdparty/pear/Log/firebug.php create mode 100644 gulliver/thirdparty/pear/Log/mail.php create mode 100644 gulliver/thirdparty/pear/Log/mcal.php create mode 100644 gulliver/thirdparty/pear/Log/mdb2.php create mode 100644 gulliver/thirdparty/pear/Log/null.php create mode 100644 gulliver/thirdparty/pear/Log/observer.php create mode 100644 gulliver/thirdparty/pear/Log/sql.php create mode 100644 gulliver/thirdparty/pear/Log/sqlite.php create mode 100644 gulliver/thirdparty/pear/Log/syslog.php create mode 100644 gulliver/thirdparty/pear/Log/win.php create mode 100644 gulliver/thirdparty/pear/Net/CheckIP.php create mode 100644 gulliver/thirdparty/pear/Net/Curl.php create mode 100644 gulliver/thirdparty/pear/Net/DIME.php create mode 100644 gulliver/thirdparty/pear/Net/FTP.php create mode 100644 gulliver/thirdparty/pear/Net/FTP/Observer.php create mode 100644 gulliver/thirdparty/pear/Net/FTP/Socket.php create mode 100644 gulliver/thirdparty/pear/Net/IDNA.php create mode 100644 gulliver/thirdparty/pear/Net/IDNA/php4.php create mode 100644 gulliver/thirdparty/pear/Net/IDNA/php5.php create mode 100644 gulliver/thirdparty/pear/Net/IPv4.php create mode 100644 gulliver/thirdparty/pear/Net/IPv6.php create mode 100644 gulliver/thirdparty/pear/Net/JSON.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/Entry.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/RootDSE.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/Schema.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/Search.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/Util.php create mode 100644 gulliver/thirdparty/pear/Net/LDAP/fg.php create mode 100644 gulliver/thirdparty/pear/Net/POP3.php create mode 100644 gulliver/thirdparty/pear/Net/SMTP.php create mode 100644 gulliver/thirdparty/pear/Net/Socket.php create mode 100644 gulliver/thirdparty/pear/Net/URL.php create mode 100644 gulliver/thirdparty/pear/Net/URL2.php create mode 100644 gulliver/thirdparty/pear/Net/UserAgent/Detect.php create mode 100644 gulliver/thirdparty/pear/Net/UserAgent/Detect/APC.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.bg.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.de.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.ee.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.en_100.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.en_GB.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.en_US.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.es.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.es_AR.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.fr.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.id.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.it_IT.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.lt.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.pl.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.pt_BR.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.ru.php create mode 100644 gulliver/thirdparty/pear/Numbers/Words/lang.sv.php create mode 100644 gulliver/thirdparty/pear/OLE/OLE.php create mode 100644 gulliver/thirdparty/pear/OLE/PPS.php create mode 100644 gulliver/thirdparty/pear/OLE/PPS/File.php create mode 100644 gulliver/thirdparty/pear/OLE/PPS/Root.php create mode 100644 gulliver/thirdparty/pear/OS/Guess.php create mode 100644 gulliver/thirdparty/pear/PEAR.php create mode 100644 gulliver/thirdparty/pear/PEAR/Autoloader.php create mode 100644 gulliver/thirdparty/pear/PEAR/Builder.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Auth.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Build.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Common.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Config.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Install.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Mirror.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Package.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Registry.php create mode 100644 gulliver/thirdparty/pear/PEAR/Command/Remote.php create mode 100644 gulliver/thirdparty/pear/PEAR/Common.php create mode 100644 gulliver/thirdparty/pear/PEAR/Config.php create mode 100644 gulliver/thirdparty/pear/PEAR/Dependency.php create mode 100644 gulliver/thirdparty/pear/PEAR/Frontend/CLI.php create mode 100644 gulliver/thirdparty/pear/PEAR/Installer.php create mode 100644 gulliver/thirdparty/pear/PEAR/Packager.php create mode 100644 gulliver/thirdparty/pear/PEAR/Registry.php create mode 100644 gulliver/thirdparty/pear/PEAR/Remote.php create mode 100644 gulliver/thirdparty/pear/README create mode 100644 gulliver/thirdparty/pear/SOAP/Base.php create mode 100644 gulliver/thirdparty/pear/SOAP/Client.php create mode 100644 gulliver/thirdparty/pear/SOAP/Disco.php create mode 100644 gulliver/thirdparty/pear/SOAP/Fault.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/config.php.dist create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/index.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_Round2Base.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupB.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupC.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_Round3GroupD.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_client.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_client_results.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_client_run.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_database.sql create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_test.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/interop_test_functions.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_Round2Base.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupB.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupC.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_Round3GroupD.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_classes.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/params_values.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/readme.txt create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/registrationAndNotification.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round2Base.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupB.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupC.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupD.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound1.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound2.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLit.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLitParams.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDEmptySA.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport1.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport2.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport3.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDRpcEnc.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLit.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLitParameters.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibility.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibilityRequired.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestList.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestRpcEnc.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestheaders.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound1.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound2.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/echoheadersvc.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/emptysa.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/import1.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/import2.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/import3.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import1B.wsdl create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.wsdl create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.xsd create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/interop.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Interop/wsdl/interopB.wsdl.php create mode 100644 gulliver/thirdparty/pear/SOAP/Parser.php create mode 100644 gulliver/thirdparty/pear/SOAP/Server.php create mode 100644 gulliver/thirdparty/pear/SOAP/Server/Email.php create mode 100644 gulliver/thirdparty/pear/SOAP/Server/Email_Gateway.php create mode 100644 gulliver/thirdparty/pear/SOAP/Server/TCP.php create mode 100644 gulliver/thirdparty/pear/SOAP/Transport.php create mode 100644 gulliver/thirdparty/pear/SOAP/Transport/HTTP.php create mode 100644 gulliver/thirdparty/pear/SOAP/Transport/SMTP.php create mode 100644 gulliver/thirdparty/pear/SOAP/Transport/TCP.php create mode 100644 gulliver/thirdparty/pear/SOAP/Type/dateTime.php create mode 100644 gulliver/thirdparty/pear/SOAP/Type/duration.php create mode 100644 gulliver/thirdparty/pear/SOAP/Type/hexBinary.php create mode 100644 gulliver/thirdparty/pear/SOAP/Value.php create mode 100644 gulliver/thirdparty/pear/SOAP/WSDL.php create mode 100644 gulliver/thirdparty/pear/SOAP/tools/genproxy.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php.bk create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/BIFFwriter.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Format.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Parser.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Validator.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Workbook.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Worksheet.php create mode 100644 gulliver/thirdparty/pear/Spreadsheet/package.xml create mode 100644 gulliver/thirdparty/pear/System.php create mode 100644 gulliver/thirdparty/pear/UDDI.php create mode 100644 gulliver/thirdparty/pear/XML/Parser.php create mode 100644 gulliver/thirdparty/pear/catalog create mode 100644 gulliver/thirdparty/pear/class.nusoap_base.php create mode 100644 gulliver/thirdparty/pear/class.soap_fault.php create mode 100644 gulliver/thirdparty/pear/class.soap_parser.php create mode 100644 gulliver/thirdparty/pear/class.soap_server.php create mode 100644 gulliver/thirdparty/pear/class.soap_transport_http.php create mode 100644 gulliver/thirdparty/pear/class.soap_val.php create mode 100644 gulliver/thirdparty/pear/class.soapclient.php create mode 100644 gulliver/thirdparty/pear/class.wsdl.php create mode 100644 gulliver/thirdparty/pear/class.wsdlcache.php create mode 100644 gulliver/thirdparty/pear/class.xmlschema.php create mode 100644 gulliver/thirdparty/pear/install-pear.php create mode 100644 gulliver/thirdparty/pear/install-pear.txt create mode 100644 gulliver/thirdparty/pear/json/class.json.php create mode 100644 gulliver/thirdparty/pear/nusoap.colosa.php create mode 100644 gulliver/thirdparty/pear/nusoap.php create mode 100644 gulliver/thirdparty/pear/nusoapmime.php create mode 100644 gulliver/thirdparty/pear/package-Archive_Tar.xml create mode 100644 gulliver/thirdparty/pear/package-Console_Getopt.xml create mode 100644 gulliver/thirdparty/pear/package-PEAR.xml create mode 100644 gulliver/thirdparty/pear/package.dtd create mode 100644 gulliver/thirdparty/pear/template.spec create mode 100644 gulliver/thirdparty/phing/BuildEvent.php create mode 100644 gulliver/thirdparty/phing/BuildException.php create mode 100644 gulliver/thirdparty/phing/BuildListener.php create mode 100644 gulliver/thirdparty/phing/IntrospectionHelper.php create mode 100644 gulliver/thirdparty/phing/Phing.php create mode 100644 gulliver/thirdparty/phing/Project.php create mode 100644 gulliver/thirdparty/phing/ProjectComponent.php create mode 100644 gulliver/thirdparty/phing/RuntimeConfigurable.php create mode 100644 gulliver/thirdparty/phing/Target.php create mode 100644 gulliver/thirdparty/phing/Task.php create mode 100644 gulliver/thirdparty/phing/TaskAdapter.php create mode 100644 gulliver/thirdparty/phing/TaskContainer.php create mode 100644 gulliver/thirdparty/phing/UnknownElement.php create mode 100644 gulliver/thirdparty/phing/filters/BaseFilterReader.php create mode 100644 gulliver/thirdparty/phing/filters/BaseParamFilterReader.php create mode 100644 gulliver/thirdparty/phing/filters/ChainableReader.php create mode 100644 gulliver/thirdparty/phing/filters/ExpandProperties.php create mode 100644 gulliver/thirdparty/phing/filters/HeadFilter.php create mode 100644 gulliver/thirdparty/phing/filters/LineContains.php create mode 100644 gulliver/thirdparty/phing/filters/LineContainsRegexp.php create mode 100644 gulliver/thirdparty/phing/filters/PrefixLines.php create mode 100644 gulliver/thirdparty/phing/filters/ReplaceRegexp.php create mode 100644 gulliver/thirdparty/phing/filters/ReplaceTokens.php create mode 100644 gulliver/thirdparty/phing/filters/StripLineBreaks.php create mode 100644 gulliver/thirdparty/phing/filters/StripLineComments.php create mode 100644 gulliver/thirdparty/phing/filters/StripPhpComments.php create mode 100644 gulliver/thirdparty/phing/filters/TabToSpaces.php create mode 100644 gulliver/thirdparty/phing/filters/TailFilter.php create mode 100644 gulliver/thirdparty/phing/filters/TidyFilter.php create mode 100644 gulliver/thirdparty/phing/filters/TranslateGettext.php create mode 100644 gulliver/thirdparty/phing/filters/XsltFilter.php create mode 100644 gulliver/thirdparty/phing/filters/util/ChainReaderHelper.php create mode 100644 gulliver/thirdparty/phing/filters/util/IniFileTokenReader.php create mode 100644 gulliver/thirdparty/phing/input/DefaultInputHandler.php create mode 100644 gulliver/thirdparty/phing/input/InputHandler.php create mode 100644 gulliver/thirdparty/phing/input/InputRequest.php create mode 100644 gulliver/thirdparty/phing/input/MultipleChoiceInputRequest.php create mode 100644 gulliver/thirdparty/phing/input/PropertyFileInputHandler.php create mode 100644 gulliver/thirdparty/phing/input/YesNoInputRequest.php create mode 100644 gulliver/thirdparty/phing/lib/Capsule.php create mode 100644 gulliver/thirdparty/phing/lib/Zip.php create mode 100644 gulliver/thirdparty/phing/listener/AnsiColorLogger.php create mode 100644 gulliver/thirdparty/phing/listener/BuildLogger.php create mode 100644 gulliver/thirdparty/phing/listener/DefaultLogger.php create mode 100644 gulliver/thirdparty/phing/listener/NoBannerLogger.php create mode 100644 gulliver/thirdparty/phing/listener/PearLogger.php create mode 100644 gulliver/thirdparty/phing/listener/XmlLogger.php create mode 100644 gulliver/thirdparty/phing/listener/defaults.properties create mode 100644 gulliver/thirdparty/phing/mappers/FileNameMapper.php create mode 100644 gulliver/thirdparty/phing/mappers/FlattenMapper.php create mode 100644 gulliver/thirdparty/phing/mappers/GlobMapper.php create mode 100644 gulliver/thirdparty/phing/mappers/IdentityMapper.php create mode 100644 gulliver/thirdparty/phing/mappers/MergeMapper.php create mode 100644 gulliver/thirdparty/phing/mappers/RegexpMapper.php create mode 100644 gulliver/thirdparty/phing/parser/AbstractHandler.php create mode 100644 gulliver/thirdparty/phing/parser/AbstractSAXParser.php create mode 100644 gulliver/thirdparty/phing/parser/DataTypeHandler.php create mode 100644 gulliver/thirdparty/phing/parser/ExpatParseException.php create mode 100644 gulliver/thirdparty/phing/parser/ExpatParser.php create mode 100644 gulliver/thirdparty/phing/parser/Location.php create mode 100644 gulliver/thirdparty/phing/parser/NestedElementHandler.php create mode 100644 gulliver/thirdparty/phing/parser/ProjectConfigurator.php create mode 100644 gulliver/thirdparty/phing/parser/ProjectHandler.php create mode 100644 gulliver/thirdparty/phing/parser/RootHandler.php create mode 100644 gulliver/thirdparty/phing/parser/TargetHandler.php create mode 100644 gulliver/thirdparty/phing/parser/TaskHandler.php create mode 100644 gulliver/thirdparty/phing/system/io/BufferedReader.php create mode 100644 gulliver/thirdparty/phing/system/io/BufferedWriter.php create mode 100644 gulliver/thirdparty/phing/system/io/ConsoleReader.php create mode 100644 gulliver/thirdparty/phing/system/io/FileReader.php create mode 100644 gulliver/thirdparty/phing/system/io/FileSystem.php create mode 100644 gulliver/thirdparty/phing/system/io/FileWriter.php create mode 100644 gulliver/thirdparty/phing/system/io/FilterReader.php create mode 100644 gulliver/thirdparty/phing/system/io/IOException.php create mode 100644 gulliver/thirdparty/phing/system/io/PhingFile.php create mode 100644 gulliver/thirdparty/phing/system/io/Reader.php create mode 100644 gulliver/thirdparty/phing/system/io/StringReader.php create mode 100644 gulliver/thirdparty/phing/system/io/TokenReader.php create mode 100644 gulliver/thirdparty/phing/system/io/UnixFileSystem.php create mode 100644 gulliver/thirdparty/phing/system/io/Win32FileSystem.php create mode 100644 gulliver/thirdparty/phing/system/io/WinNTFileSystem.php create mode 100644 gulliver/thirdparty/phing/system/io/Writer.php create mode 100644 gulliver/thirdparty/phing/system/lang/Character.php create mode 100644 gulliver/thirdparty/phing/system/lang/EventObject.php create mode 100644 gulliver/thirdparty/phing/system/lang/FileNotFoundException.php create mode 100644 gulliver/thirdparty/phing/system/lang/NullPointerException.php create mode 100644 gulliver/thirdparty/phing/system/lang/SecurityException.php create mode 100644 gulliver/thirdparty/phing/system/util/Message.php create mode 100644 gulliver/thirdparty/phing/system/util/Properties.php create mode 100644 gulliver/thirdparty/phing/system/util/Register.php create mode 100644 gulliver/thirdparty/phing/system/util/Timer.php create mode 100644 gulliver/thirdparty/phing/tasks/defaults.properties create mode 100644 gulliver/thirdparty/phing/tasks/ext/CapsuleTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/CreoleSQLExecTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/CreoleTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ExtractBaseTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/MailTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/PackageAsPathTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/PearPackageTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/PhpLintTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/SmartyTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/TarTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/UntarTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/UnzipTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/XmlLintTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ZendCodeAnalyzerTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ZipTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMerger.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMergerTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTransformer.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/coverage/CoverageSetupTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeComment.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeEncoderTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeLicenseTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/pearpackage/Fileset.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpdoc/PHPDocumentorTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/BatchTest.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/FormatterElement.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Task.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Util.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/svn/SvnBaseTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/svn/SvnExportTask.php create mode 100644 gulliver/thirdparty/phing/tasks/ext/svn/SvnLastRevisionTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/AdhocTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/AdhocTaskdefTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/AdhocTypedefTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/AppendTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/AvailableTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ChmodTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ConditionTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/CopyTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/CvsPassTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/CvsTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/DeleteTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/EchoTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ExecTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ExitTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ForeachTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/IfTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/IncludePathTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/InputTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/MatchingTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/MkdirTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/MoveTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/PhingCallTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/PhingTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/PhpEvalTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/PropertyPromptTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/PropertyTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ReflexiveTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/ResolvePathTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/SequentialTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/TaskdefTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/TouchTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/TstampTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/TypedefTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/UpToDateTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/WarnTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/XsltTask.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/AndCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/Condition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/ConditionBase.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/ContainsCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/EqualsCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/IsFalseCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/IsSetCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/IsTrueCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/NotCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/OrCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/OsCondition.php create mode 100644 gulliver/thirdparty/phing/tasks/system/condition/ReferenceExistsCondition.php create mode 100644 gulliver/thirdparty/phing/types/AbstractFileSet.php create mode 100644 gulliver/thirdparty/phing/types/Commandline.php create mode 100644 gulliver/thirdparty/phing/types/DataType.php create mode 100644 gulliver/thirdparty/phing/types/Description.php create mode 100644 gulliver/thirdparty/phing/types/DirSet.php create mode 100644 gulliver/thirdparty/phing/types/FileList.php create mode 100644 gulliver/thirdparty/phing/types/FileSet.php create mode 100644 gulliver/thirdparty/phing/types/FilterChain.php create mode 100644 gulliver/thirdparty/phing/types/Mapper.php create mode 100644 gulliver/thirdparty/phing/types/Parameter.php create mode 100644 gulliver/thirdparty/phing/types/Parameterizable.php create mode 100644 gulliver/thirdparty/phing/types/Path.php create mode 100644 gulliver/thirdparty/phing/types/PatternSet.php create mode 100644 gulliver/thirdparty/phing/types/PhingFilterReader.php create mode 100644 gulliver/thirdparty/phing/types/Reference.php create mode 100644 gulliver/thirdparty/phing/types/RegularExpression.php create mode 100644 gulliver/thirdparty/phing/types/TokenReader.php create mode 100644 gulliver/thirdparty/phing/types/TokenSource.php create mode 100644 gulliver/thirdparty/phing/types/defaults.properties create mode 100644 gulliver/thirdparty/phing/types/selectors/AndSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/BaseExtendSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/BaseSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/BaseSelectorContainer.php create mode 100644 gulliver/thirdparty/phing/types/selectors/ContainsRegexpSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/ContainsSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/DateSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/DependSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/DepthSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/ExtendFileSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/ExtendSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/FileSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/FilenameSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/MajoritySelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/NoneSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/NotSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/OrSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/PresentSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/SelectSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/SelectorContainer.php create mode 100644 gulliver/thirdparty/phing/types/selectors/SelectorScanner.php create mode 100644 gulliver/thirdparty/phing/types/selectors/SelectorUtils.php create mode 100644 gulliver/thirdparty/phing/types/selectors/SizeSelector.php create mode 100644 gulliver/thirdparty/phing/types/selectors/TypeSelector.php create mode 100644 gulliver/thirdparty/phing/util/DirectoryScanner.php create mode 100644 gulliver/thirdparty/phing/util/ExtendedFileStream.php create mode 100644 gulliver/thirdparty/phing/util/FileUtils.php create mode 100644 gulliver/thirdparty/phing/util/LogWriter.php create mode 100644 gulliver/thirdparty/phing/util/PathTokenizer.php create mode 100644 gulliver/thirdparty/phing/util/SourceFileScanner.php create mode 100644 gulliver/thirdparty/phing/util/StringHelper.php create mode 100644 gulliver/thirdparty/phing/util/regexp/PregEngine.php create mode 100644 gulliver/thirdparty/phing/util/regexp/Regexp.php create mode 100644 gulliver/thirdparty/phing/util/regexp/RegexpEngine.php create mode 100644 gulliver/thirdparty/phpmailer/class.phpmailer.php create mode 100644 gulliver/thirdparty/phpmailer/class.smtp.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-br.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-ca.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-cz.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-de.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-dk.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-en.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-es.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-fi.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-fo.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-fr.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-hu.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-it.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-ja.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-nl.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-no.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-pl.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-ro.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-ru.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-se.php create mode 100644 gulliver/thirdparty/phpmailer/language/phpmailer.lang-tr.php create mode 100644 gulliver/thirdparty/propel-generator/CHANGELOG create mode 100644 gulliver/thirdparty/propel-generator/INSTALL create mode 100644 gulliver/thirdparty/propel-generator/LICENSE create mode 100755 gulliver/thirdparty/propel-generator/bin/propel-gen create mode 100644 gulliver/thirdparty/propel-generator/bin/propel-gen.bat create mode 100644 gulliver/thirdparty/propel-generator/build-propel.xml create mode 100644 gulliver/thirdparty/propel-generator/build.properties-sample create mode 100644 gulliver/thirdparty/propel-generator/build.xml create mode 100644 gulliver/thirdparty/propel-generator/build.xml-local create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/EngineException.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/DataModelBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ClassTools.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/OMBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexObjectBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexPeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/AppData.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Column.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Database.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Domain.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ForeignKey.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IDMethod.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Index.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Inheritance.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameFactory.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameGenerator.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PropelTypes.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Rule.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Table.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Unique.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Validator.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/XMLElement.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToData.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/DefaultPlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MssqlPlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqlPlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqliPlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/OraclePlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/Platform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/engine/platform/SqlitePlatform.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDTDTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDumpTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataModelTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataSQLTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelGraphvizTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOMTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldOMTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldSQLTask.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLExec.php create mode 100644 gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLTask.php create mode 100644 gulliver/thirdparty/propel-generator/default.properties create mode 100644 gulliver/thirdparty/propel-generator/pear/BuildPropelGenPEARPackageTask.php create mode 100644 gulliver/thirdparty/propel-generator/pear/build-pear-package.xml create mode 100644 gulliver/thirdparty/propel-generator/pear/build.properties create mode 100644 gulliver/thirdparty/propel-generator/pear/pear-build.xml create mode 100644 gulliver/thirdparty/propel-generator/pear/pear-propel-gen create mode 100644 gulliver/thirdparty/propel-generator/pear/pear-propel-gen.bat create mode 100644 gulliver/thirdparty/propel-generator/resources/dtd/database.dtd create mode 100644 gulliver/thirdparty/propel-generator/resources/xsd/custom_datatypes.xsd create mode 100644 gulliver/thirdparty/propel-generator/resources/xsd/database.xsd create mode 100644 gulliver/thirdparty/propel-generator/resources/xsl/database.xsl create mode 100644 gulliver/thirdparty/propel-generator/templates/README create mode 100644 gulliver/thirdparty/propel-generator/templates/conf/Control.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/conf/xml.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/data/dtd/dataset.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/data/dtd/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/data/dump/bottom.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/data/dump/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/data/dump/top.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNode.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNodePeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionObject.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionPeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/Interface.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/MapBuilder.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/MultiExtendObject.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/Node.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/NodePeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/Object.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php4/Peer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNode.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNodePeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionObject.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionPeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/Interface.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/MapBuilder.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/MultiExtendObject.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/Node.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/NodePeer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/Object.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/om/php5/Peer.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/columns.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/drop.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/foreignkey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/index.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/primarykey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/tablefk.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mssql/unique.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/columns.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/database-end.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/database-start.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/drop.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/foreignkey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/index.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/primarykey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/tablefk.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/mysql/unique.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/columns.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/drop.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/foreignkey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/index.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/primarykey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/sequence.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/tablefk.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/oracle/unique.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/columns.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/drop.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/foreignkey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/index.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/primarykey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/sequence.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/tablefk.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/unique.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/columns.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/drop.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/foreignkey.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/index.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/table.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/tablefk.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/unique.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/Control.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/unix.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/windows.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/mysql/createdb.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/oracle/createdb.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/db-init/pgsql/createdb.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/mssql/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/mssql/val.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/mysql/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/mysql/val.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/oracle/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/oracle/val.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/val.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/row.tpl create mode 100644 gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/val.tpl create mode 100644 gulliver/thirdparty/propel/Propel.php create mode 100644 gulliver/thirdparty/propel/PropelException.php create mode 100644 gulliver/thirdparty/propel/adapter/DBAdapter.php create mode 100644 gulliver/thirdparty/propel/adapter/DBArray.php create mode 100644 gulliver/thirdparty/propel/adapter/DBMSSQL.php create mode 100644 gulliver/thirdparty/propel/adapter/DBMySQL.php create mode 100644 gulliver/thirdparty/propel/adapter/DBMySQLi.php create mode 100644 gulliver/thirdparty/propel/adapter/DBNone.php create mode 100644 gulliver/thirdparty/propel/adapter/DBOracle.php create mode 100644 gulliver/thirdparty/propel/adapter/DBPostgres.php create mode 100644 gulliver/thirdparty/propel/adapter/DBSQLite.php create mode 100644 gulliver/thirdparty/propel/adapter/DBSybase.php create mode 100644 gulliver/thirdparty/propel/logger/BasicLogger.php create mode 100644 gulliver/thirdparty/propel/logger/MojaviLogAdapter.php create mode 100644 gulliver/thirdparty/propel/map/ColumnMap.php create mode 100644 gulliver/thirdparty/propel/map/DatabaseMap.php create mode 100644 gulliver/thirdparty/propel/map/MapBuilder.php create mode 100644 gulliver/thirdparty/propel/map/TableMap.php create mode 100644 gulliver/thirdparty/propel/map/ValidatorMap.php create mode 100644 gulliver/thirdparty/propel/om/BaseObject.php create mode 100644 gulliver/thirdparty/propel/om/Persistent.php create mode 100644 gulliver/thirdparty/propel/om/PreOrderNodeIterator.php create mode 100644 gulliver/thirdparty/propel/util/BasePeer.php create mode 100644 gulliver/thirdparty/propel/util/Criteria.php create mode 100644 gulliver/thirdparty/propel/util/PeerInfo.php create mode 100644 gulliver/thirdparty/propel/util/PropelPager.php create mode 100644 gulliver/thirdparty/propel/util/Transaction.php create mode 100644 gulliver/thirdparty/propel/validator/BasicValidator.php create mode 100644 gulliver/thirdparty/propel/validator/MatchValidator.php create mode 100644 gulliver/thirdparty/propel/validator/MaxLengthValidator.php create mode 100644 gulliver/thirdparty/propel/validator/MaxValueValidator.php create mode 100644 gulliver/thirdparty/propel/validator/MinLengthValidator.php create mode 100644 gulliver/thirdparty/propel/validator/MinValueValidator.php create mode 100644 gulliver/thirdparty/propel/validator/NotMatchValidator.php create mode 100644 gulliver/thirdparty/propel/validator/RequiredValidator.php create mode 100644 gulliver/thirdparty/propel/validator/UniqueValidator.php create mode 100644 gulliver/thirdparty/propel/validator/ValidValuesValidator.php create mode 100644 gulliver/thirdparty/propel/validator/ValidationFailed.php create mode 100644 gulliver/thirdparty/smarty/BUGS create mode 100644 gulliver/thirdparty/smarty/COPYING.lib create mode 100644 gulliver/thirdparty/smarty/ChangeLog create mode 100644 gulliver/thirdparty/smarty/FAQ create mode 100644 gulliver/thirdparty/smarty/INSTALL create mode 100644 gulliver/thirdparty/smarty/NEWS create mode 100644 gulliver/thirdparty/smarty/QUICK_START create mode 100644 gulliver/thirdparty/smarty/README create mode 100644 gulliver/thirdparty/smarty/RELEASE_NOTES create mode 100644 gulliver/thirdparty/smarty/TODO create mode 100644 gulliver/thirdparty/smarty/demo/configs/test.conf create mode 100644 gulliver/thirdparty/smarty/demo/index.php create mode 100644 gulliver/thirdparty/smarty/demo/templates/footer.tpl create mode 100644 gulliver/thirdparty/smarty/demo/templates/header.tpl create mode 100644 gulliver/thirdparty/smarty/demo/templates/index.tpl create mode 100644 gulliver/thirdparty/smarty/libs/Config_File.class.php create mode 100644 gulliver/thirdparty/smarty/libs/Smarty.class.php create mode 100644 gulliver/thirdparty/smarty/libs/Smarty_Compiler.class.php create mode 100644 gulliver/thirdparty/smarty/libs/debug.tpl create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.assemble_plugin_filepath.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.assign_smarty_interface.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.create_dir_structure.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.display_debug_console.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.get_include_path.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.get_microtime.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.get_php_resource.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.is_secure.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.is_trusted.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.load_plugins.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.load_resource_plugin.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.process_cached_inserts.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.process_compiled_include.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.read_cache_file.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.rm_auto.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.rmdir.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.run_insert_handler.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.smarty_include_php.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.write_cache_file.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.write_compiled_include.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.write_compiled_resource.php create mode 100644 gulliver/thirdparty/smarty/libs/internals/core.write_file.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/block.textformat.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/compiler.assign.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.assign_debug_info.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.config_load.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.counter.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.cycle.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.debug.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.eval.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.fetch.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_checkboxes.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_image.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_options.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_radios.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_select_date.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_select_time.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.html_table.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.mailto.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.math.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.popup.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/function.popup_init.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.capitalize.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.cat.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.count_characters.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.count_paragraphs.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.count_sentences.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.count_words.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.date_format.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.debug_print_var.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.default.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.escape.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.indent.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.lower.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.nl2br.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.regex_replace.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.replace.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.spacify.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.string_format.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.strip.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.strip_tags.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.truncate.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.upper.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/modifier.wordwrap.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/outputfilter.trimwhitespace.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/shared.escape_special_chars.php create mode 100644 gulliver/thirdparty/smarty/libs/plugins/shared.make_timestamp.php create mode 100644 gulliver/thirdparty/smarty/misc/smarty_icon.README create mode 100644 gulliver/thirdparty/smarty/misc/smarty_icon.gif create mode 100644 gulliver/thirdparty/smarty/unit_test/README create mode 100644 gulliver/thirdparty/smarty/unit_test/config.php create mode 100644 gulliver/thirdparty/smarty/unit_test/configs/globals_double_quotes.conf create mode 100644 gulliver/thirdparty/smarty/unit_test/configs/globals_single_quotes.conf create mode 100644 gulliver/thirdparty/smarty/unit_test/smarty_unit_test.php create mode 100644 gulliver/thirdparty/smarty/unit_test/smarty_unit_test_gui.php create mode 100644 gulliver/thirdparty/smarty/unit_test/templates/assign_var.tpl create mode 100644 gulliver/thirdparty/smarty/unit_test/templates/constant.tpl create mode 100644 gulliver/thirdparty/smarty/unit_test/templates/index.tpl create mode 100644 gulliver/thirdparty/smarty/unit_test/templates/parse_math.tpl create mode 100644 gulliver/thirdparty/smarty/unit_test/templates/parse_obj_meth.tpl create mode 100644 gulliver/thirdparty/smarty/unit_test/test_cases.php create mode 100644 processmaker create mode 100644 rbac/engine/classes/model/AuthenticationSource.php create mode 100644 rbac/engine/classes/model/AuthenticationSourcePeer.php create mode 100644 rbac/engine/classes/model/Permissions.php create mode 100644 rbac/engine/classes/model/PermissionsPeer.php create mode 100644 rbac/engine/classes/model/RbacUsers.php create mode 100644 rbac/engine/classes/model/RbacUsersPeer.php create mode 100644 rbac/engine/classes/model/Roles.php create mode 100644 rbac/engine/classes/model/RolesPeer.php create mode 100644 rbac/engine/classes/model/RolesPermissions.php create mode 100644 rbac/engine/classes/model/RolesPermissionsPeer.php create mode 100644 rbac/engine/classes/model/Systems.php create mode 100644 rbac/engine/classes/model/SystemsPeer.php create mode 100644 rbac/engine/classes/model/UsersRoles.php create mode 100644 rbac/engine/classes/model/UsersRolesPeer.php create mode 100644 rbac/engine/classes/model/map/AuthenticationSourceMapBuilder.php create mode 100644 rbac/engine/classes/model/map/PermissionsMapBuilder.php create mode 100644 rbac/engine/classes/model/map/RbacUsersMapBuilder.php create mode 100644 rbac/engine/classes/model/map/RolesMapBuilder.php create mode 100644 rbac/engine/classes/model/map/RolesPermissionsMapBuilder.php create mode 100644 rbac/engine/classes/model/map/SystemsMapBuilder.php create mode 100644 rbac/engine/classes/model/map/UsersRolesMapBuilder.php create mode 100644 rbac/engine/classes/model/om/BaseAuthenticationSource.php create mode 100644 rbac/engine/classes/model/om/BaseAuthenticationSourcePeer.php create mode 100644 rbac/engine/classes/model/om/BasePermissions.php create mode 100644 rbac/engine/classes/model/om/BasePermissionsPeer.php create mode 100644 rbac/engine/classes/model/om/BaseRbacUsers.php create mode 100644 rbac/engine/classes/model/om/BaseRbacUsersPeer.php create mode 100644 rbac/engine/classes/model/om/BaseRoles.php create mode 100644 rbac/engine/classes/model/om/BaseRolesPeer.php create mode 100644 rbac/engine/classes/model/om/BaseRolesPermissions.php create mode 100644 rbac/engine/classes/model/om/BaseRolesPermissionsPeer.php create mode 100644 rbac/engine/classes/model/om/BaseSystems.php create mode 100644 rbac/engine/classes/model/om/BaseSystemsPeer.php create mode 100644 rbac/engine/classes/model/om/BaseUsersRoles.php create mode 100644 rbac/engine/classes/model/om/BaseUsersRolesPeer.php create mode 100755 rbac/engine/classes/plugins/class.ldap.php create mode 100644 rbac/engine/config/databases.php create mode 100644 rbac/engine/config/defines.php create mode 100644 rbac/engine/config/environments.php create mode 100644 rbac/engine/config/paths.php create mode 100644 rbac/engine/config/propel.ini create mode 100644 rbac/engine/config/propel.mssql.ini create mode 100644 rbac/engine/config/propel.mysql.ini create mode 100644 rbac/engine/config/propel.oracle.ini create mode 100644 rbac/engine/config/propel.pgsql.ini create mode 100644 rbac/engine/config/properties.ini create mode 100644 rbac/engine/config/schema-transformed.xml create mode 100644 rbac/engine/config/schema.xml create mode 100644 rbac/engine/content/languages/labels.xml create mode 100644 rbac/engine/content/languages/menus.xml create mode 100644 rbac/engine/content/messages.en create mode 100644 rbac/engine/content/messages.es create mode 100644 rbac/engine/content/messages.po create mode 100644 rbac/engine/content/rbac/myApp.cnt create mode 100644 rbac/engine/data/mssql/schema.sql create mode 100644 rbac/engine/data/mssql/sqldb.map create mode 100644 rbac/engine/data/mysql/create-db.sql create mode 100755 rbac/engine/data/mysql/insert.sql create mode 100644 rbac/engine/data/mysql/schema.sql create mode 100644 rbac/engine/data/mysql/sqldb.map create mode 100644 rbac/engine/data/oracle/create-db.sql create mode 100644 rbac/engine/data/oracle/schema.sql create mode 100644 rbac/engine/data/oracle/sqldb.map create mode 100644 rbac/engine/data/pgsql/create-db.sql create mode 100644 rbac/engine/data/pgsql/sqldb.map create mode 100644 rbac/engine/db/dbmodule_processmaker.php create mode 100644 rbac/engine/includes/inc.JSForms.php create mode 100644 rbac/engine/includes/inc.ajax.php create mode 100644 rbac/engine/includes/inc.application.php create mode 100644 rbac/engine/includes/inc.dynaForms.php create mode 100644 rbac/engine/menus/backApp.php create mode 100644 rbac/engine/menus/cancel.php create mode 100644 rbac/engine/menus/rbac.appEdit.php create mode 100644 rbac/engine/menus/rbac.appView.php create mode 100644 rbac/engine/menus/rbac.application.php create mode 100644 rbac/engine/menus/rbac.authSource.php create mode 100644 rbac/engine/menus/rbac.authentication.php create mode 100644 rbac/engine/menus/rbac.login.php create mode 100644 rbac/engine/menus/rbac.permission.php create mode 100644 rbac/engine/menus/rbac.php create mode 100644 rbac/engine/menus/rbac.role.php create mode 100644 rbac/engine/menus/rbac.user.php create mode 100644 rbac/engine/menus/rbac.userEdit.php create mode 100644 rbac/engine/menus/rbac.userView.php create mode 100644 rbac/engine/methods/controls/buscador.php create mode 100644 rbac/engine/methods/controls/buscador2.php create mode 100644 rbac/engine/methods/controls/calendar.js create mode 100644 rbac/engine/methods/controls/calendar.php create mode 100644 rbac/engine/methods/controls/img/cal.gif create mode 100644 rbac/engine/methods/controls/img/logo.gif create mode 100644 rbac/engine/methods/controls/img/next.gif create mode 100644 rbac/engine/methods/controls/img/next_year.gif create mode 100644 rbac/engine/methods/controls/img/pixel.gif create mode 100644 rbac/engine/methods/controls/img/prev.gif create mode 100644 rbac/engine/methods/controls/img/prev_year.gif create mode 100644 rbac/engine/methods/controls/img/tc.gif create mode 100644 rbac/engine/methods/login/dbInfo.php create mode 100644 rbac/engine/methods/login/enumerate.php create mode 100644 rbac/engine/methods/login/login.php create mode 100644 rbac/engine/methods/login/loginAjax.php create mode 100644 rbac/engine/methods/login/noViewPage.php create mode 100644 rbac/engine/methods/login/showDBFiles.php create mode 100644 rbac/engine/methods/login/verify-login.php create mode 100644 rbac/engine/methods/rbac/appDel.php create mode 100644 rbac/engine/methods/rbac/appEdit.php create mode 100644 rbac/engine/methods/rbac/appEdit2.php create mode 100644 rbac/engine/methods/rbac/appList.php create mode 100644 rbac/engine/methods/rbac/appNew.php create mode 100644 rbac/engine/methods/rbac/appNew2.php create mode 100644 rbac/engine/methods/rbac/appView.php create mode 100644 rbac/engine/methods/rbac/authAddUser.php create mode 100644 rbac/engine/methods/rbac/authAjax.php create mode 100644 rbac/engine/methods/rbac/authDel.php create mode 100644 rbac/engine/methods/rbac/authEdit.php create mode 100644 rbac/engine/methods/rbac/authEdit2.php create mode 100644 rbac/engine/methods/rbac/authNew.php create mode 100644 rbac/engine/methods/rbac/authNew2.php create mode 100644 rbac/engine/methods/rbac/authTest.php create mode 100644 rbac/engine/methods/rbac/authenticationList.php create mode 100644 rbac/engine/methods/rbac/dbInfo.php create mode 100644 rbac/engine/methods/rbac/loadAuthSource.php create mode 100644 rbac/engine/methods/rbac/loadPermView.php create mode 100644 rbac/engine/methods/rbac/loadRoleProp.php create mode 100644 rbac/engine/methods/rbac/loadRoleProp2.php create mode 100644 rbac/engine/methods/rbac/loadRoleView.php create mode 100644 rbac/engine/methods/rbac/loadUser.php create mode 100644 rbac/engine/methods/rbac/loadUserRole.php create mode 100644 rbac/engine/methods/rbac/message.php create mode 100644 rbac/engine/methods/rbac/permDel.php create mode 100644 rbac/engine/methods/rbac/permEdit.php create mode 100644 rbac/engine/methods/rbac/permEdit2.php create mode 100644 rbac/engine/methods/rbac/permList.php create mode 100644 rbac/engine/methods/rbac/permNew.php create mode 100644 rbac/engine/methods/rbac/permNew2.php create mode 100644 rbac/engine/methods/rbac/roleDel.php create mode 100644 rbac/engine/methods/rbac/roleEdit.php create mode 100644 rbac/engine/methods/rbac/roleEdit2.php create mode 100644 rbac/engine/methods/rbac/roleList.php create mode 100644 rbac/engine/methods/rbac/roleNew.php create mode 100644 rbac/engine/methods/rbac/roleNew2.php create mode 100644 rbac/engine/methods/rbac/roleProp.php create mode 100644 rbac/engine/methods/rbac/showFieldAjax.php create mode 100644 rbac/engine/methods/rbac/userAssignRole.php create mode 100644 rbac/engine/methods/rbac/userAssignRole2.php create mode 100644 rbac/engine/methods/rbac/userChangeLdap.php create mode 100644 rbac/engine/methods/rbac/userChangeLdap2.php create mode 100644 rbac/engine/methods/rbac/userChangePwd.php create mode 100644 rbac/engine/methods/rbac/userChangePwd2.php create mode 100644 rbac/engine/methods/rbac/userEdit.php create mode 100644 rbac/engine/methods/rbac/userEdit2.php create mode 100644 rbac/engine/methods/rbac/userList.php create mode 100644 rbac/engine/methods/rbac/userNew.php create mode 100644 rbac/engine/methods/rbac/userNew2.php create mode 100644 rbac/engine/methods/rbac/userNew3.php create mode 100644 rbac/engine/methods/rbac/userNew4.php create mode 100644 rbac/engine/methods/rbac/userRoleDel.php create mode 100644 rbac/engine/methods/rbac/userRoleProp.php create mode 100644 rbac/engine/methods/rbac/userTestLdap.php create mode 100644 rbac/engine/methods/rbac/userTestLdap2.php create mode 100644 rbac/engine/methods/rbac/userView.php create mode 100644 rbac/engine/methods/rbac/userViewRole.php create mode 100644 rbac/engine/pre_processor.php create mode 100644 rbac/engine/skins/blank.html create mode 100644 rbac/engine/skins/blank.php create mode 100644 rbac/engine/skins/index.html create mode 100644 rbac/engine/skins/styles.html create mode 100644 rbac/engine/skins/styles.php create mode 100644 rbac/engine/skins/stylesSimple.html create mode 100644 rbac/engine/skins/wf.php create mode 100644 rbac/engine/skins/wf5.php create mode 100644 rbac/engine/tables/rbac.applications.list.php create mode 100644 rbac/engine/tables/rbac.authentication.list.php create mode 100644 rbac/engine/tables/rbac.permissions.list.php create mode 100644 rbac/engine/tables/rbac.roles.list.php create mode 100644 rbac/engine/tables/rbac.users.list.php create mode 100644 rbac/engine/tables/rbac.users.role.php create mode 100644 rbac/engine/templates/authListUsers.html create mode 100644 rbac/engine/templates/filterform.html create mode 100644 rbac/engine/templates/formFilter.html create mode 100644 rbac/engine/templates/grid.html create mode 100644 rbac/engine/templates/login/showDBFiles.php create mode 100644 rbac/engine/templates/paged-table.html create mode 100644 rbac/engine/templates/paged-table.php create mode 100644 rbac/engine/templates/popupMenu.html create mode 100644 rbac/engine/templates/publish.php create mode 100644 rbac/engine/templates/testAuthenticationSource.html create mode 100644 rbac/engine/templates/testAuthenticationSource.php create mode 100644 rbac/engine/templates/testAuthenticationUser.php create mode 100644 rbac/engine/templates/toolbar.html create mode 100644 rbac/engine/templates/treePerm.php create mode 100644 rbac/engine/templates/treePermRole.php create mode 100644 rbac/engine/templates/treeRole.php create mode 100644 rbac/engine/templates/xmlform.html create mode 100644 rbac/engine/templates/xmlmenu.html create mode 100644 rbac/engine/xmlform/login.html create mode 100644 rbac/engine/xmlform/login/login.es create mode 100644 rbac/engine/xmlform/login/login.xml create mode 100644 rbac/engine/xmlform/login/noViewPage.xml create mode 100644 rbac/engine/xmlform/login/nologin.xml create mode 100644 rbac/engine/xmlform/rbac/appEdit.xml create mode 100644 rbac/engine/xmlform/rbac/appMenu.xml create mode 100644 rbac/engine/xmlform/rbac/appNew.es create mode 100644 rbac/engine/xmlform/rbac/appNew.xml create mode 100644 rbac/engine/xmlform/rbac/applicationsList.html create mode 100644 rbac/engine/xmlform/rbac/applicationsList.xml create mode 100644 rbac/engine/xmlform/rbac/applicationsListCriteria.xml create mode 100644 rbac/engine/xmlform/rbac/authAddUser.es create mode 100644 rbac/engine/xmlform/rbac/authAddUser.html create mode 100644 rbac/engine/xmlform/rbac/authAddUser.xml create mode 100644 rbac/engine/xmlform/rbac/authNew.es create mode 100644 rbac/engine/xmlform/rbac/authNew.xml create mode 100644 rbac/engine/xmlform/rbac/authenticationList.xml create mode 100644 rbac/engine/xmlform/rbac/authenticationsList.es create mode 100644 rbac/engine/xmlform/rbac/authenticationsList.xml create mode 100644 rbac/engine/xmlform/rbac/dbInfo.es create mode 100644 rbac/engine/xmlform/rbac/dbInfo.xml create mode 100644 rbac/engine/xmlform/rbac/noMoreRolesAvailable.xml create mode 100644 rbac/engine/xmlform/rbac/permEdit.xml create mode 100644 rbac/engine/xmlform/rbac/permNew.xml create mode 100644 rbac/engine/xmlform/rbac/roleEdit.es create mode 100644 rbac/engine/xmlform/rbac/roleEdit.xml create mode 100644 rbac/engine/xmlform/rbac/roleNew.xml create mode 100644 rbac/engine/xmlform/rbac/userAssignRole.en create mode 100644 rbac/engine/xmlform/rbac/userAssignRole.es create mode 100644 rbac/engine/xmlform/rbac/userAssignRole.xml create mode 100644 rbac/engine/xmlform/rbac/userAssignRole3.xml create mode 100644 rbac/engine/xmlform/rbac/userChangeLdap.xml create mode 100644 rbac/engine/xmlform/rbac/userChangePwd.xml create mode 100644 rbac/engine/xmlform/rbac/userEdit.es create mode 100644 rbac/engine/xmlform/rbac/userEdit.xml create mode 100644 rbac/engine/xmlform/rbac/userNew.es create mode 100644 rbac/engine/xmlform/rbac/userNew.xml create mode 100644 rbac/engine/xmlform/rbac/userNewPwd.xml create mode 100644 rbac/engine/xmlform/rbac/userTestLdap.xml create mode 100644 rbac/engine/xmlform/rbac/userView.xml create mode 100644 rbac/engine/xmlform/rbac/usersList.xml create mode 100644 rbac/engine/xmlform/rbac/usersListFilter.xml create mode 100644 rbac/engine/xmlform/rbac/usersListMenu.xml create mode 100644 rbac/engine/xmlform/rbac/usersRolesList.xml create mode 100644 rbac/public_html/errors/error.php create mode 100644 rbac/public_html/errors/error400.php create mode 100644 rbac/public_html/errors/error401.php create mode 100644 rbac/public_html/errors/error403.php create mode 100644 rbac/public_html/errors/error404.php create mode 100644 rbac/public_html/errors/error503.php create mode 100644 rbac/public_html/errors/error701.php create mode 100644 rbac/public_html/errors/error702.php create mode 100644 rbac/public_html/errors/error703.php create mode 100644 rbac/public_html/errors/error704.php create mode 100644 rbac/public_html/errors/estilo.css create mode 100644 rbac/public_html/errors/header.php create mode 100644 rbac/public_html/errors/library/logo.gif create mode 100644 rbac/public_html/images/arrow_order_asc.gif create mode 100644 rbac/public_html/images/arrow_order_desc.gif create mode 100644 rbac/public_html/images/browse.gif create mode 100644 rbac/public_html/images/btnGreen.gif create mode 100644 rbac/public_html/images/btnRed.gif create mode 100644 rbac/public_html/images/btnYellow.gif create mode 100644 rbac/public_html/images/calendar/cal.gif create mode 100644 rbac/public_html/images/calendar/logo.gif create mode 100644 rbac/public_html/images/calendar/next.gif create mode 100644 rbac/public_html/images/calendar/next_year.gif create mode 100644 rbac/public_html/images/calendar/pixel.gif create mode 100644 rbac/public_html/images/calendar/prev.gif create mode 100644 rbac/public_html/images/calendar/prev_year.gif create mode 100644 rbac/public_html/images/calendar/tc.gif create mode 100644 rbac/public_html/images/date.gif create mode 100644 rbac/public_html/images/doc.gif create mode 100644 rbac/public_html/images/edit.gif create mode 100644 rbac/public_html/images/form.gif create mode 100644 rbac/public_html/images/ftv2doc.gif create mode 100644 rbac/public_html/images/ftv2lastnode.gif create mode 100644 rbac/public_html/images/ftv2mlastnode.gif create mode 100644 rbac/public_html/images/ftv2mnode.gif create mode 100644 rbac/public_html/images/ftv2node.gif create mode 100644 rbac/public_html/images/ftv2pnode.gif create mode 100644 rbac/public_html/images/ftv2vertline.gif create mode 100644 rbac/public_html/images/minus.gif create mode 100644 rbac/public_html/images/plus.gif create mode 100644 rbac/public_html/images/trash.gif create mode 100644 rbac/public_html/index.html create mode 100644 rbac/public_html/skins/JSForms.js create mode 100644 rbac/public_html/skins/ajax.js create mode 100644 rbac/public_html/skins/styles/simple/style.css create mode 100644 rbac/public_html/skins/valida.js create mode 100644 rbac/public_html/skins/wf/arrow.gif create mode 100644 rbac/public_html/skins/wf/arrow2.gif create mode 100644 rbac/public_html/skins/wf/general.css create mode 100644 rbac/public_html/skins/wf/generalPrinter.css create mode 100644 rbac/public_html/skins/wf/help_big.gif create mode 100644 rbac/public_html/skins/wf/help_small.gif create mode 100644 rbac/public_html/skins/wf/menuShadow.gif create mode 100644 rbac/public_html/skins/wf/spacer.gif create mode 100644 rbac/public_html/skins/wf/tab.gif create mode 100644 rbac/public_html/skins/wf/topBackgr.jpg create mode 100644 rbac/public_html/skins/wf5/style.css create mode 100644 rbac/public_html/sysGeneric.php create mode 100644 rbac/public_html/sysUnnamed.php create mode 100644 rbac/public_html/xmlform/login/login.js create mode 100644 rbac/public_html/xmlform/rbac/appNew.js create mode 100644 rbac/public_html/xmlform/rbac/authAddUser.js create mode 100644 rbac/public_html/xmlform/rbac/authNew.js create mode 100644 rbac/public_html/xmlform/rbac/dbInfo.js create mode 100644 rbac/public_html/xmlform/rbac/roleEdit.js create mode 100644 rbac/public_html/xmlform/rbac/userAssignRole.js create mode 100644 rbac/public_html/xmlform/rbac/userEdit.js create mode 100644 rbac/public_html/xmlform/rbac/userNew.js create mode 100644 workflow/engine/bin/commands.php create mode 100644 workflow/engine/bin/commands/cmdDrafts.php create mode 100644 workflow/engine/bin/commands/cmdSchema.php create mode 100755 workflow/engine/bin/cron.php create mode 100755 workflow/engine/bin/cron_single.php create mode 100644 workflow/engine/classes/class.ArrayPeer.php create mode 100644 workflow/engine/classes/class.BasePeer.php create mode 100755 workflow/engine/classes/class.Installer.php create mode 100644 workflow/engine/classes/class.archive.php create mode 100755 workflow/engine/classes/class.calendar.php create mode 100644 workflow/engine/classes/class.case.php create mode 100644 workflow/engine/classes/class.configuration.php create mode 100644 workflow/engine/classes/class.dashboards.php create mode 100755 workflow/engine/classes/class.dates.php create mode 100644 workflow/engine/classes/class.dbConnections.php create mode 100644 workflow/engine/classes/class.derivation.php create mode 100644 workflow/engine/classes/class.dynaFormField.php create mode 100755 workflow/engine/classes/class.dynaformEditor.php create mode 100644 workflow/engine/classes/class.groupUser.php create mode 100644 workflow/engine/classes/class.groups.php create mode 100755 workflow/engine/classes/class.insert.php create mode 100644 workflow/engine/classes/class.javaBridgePM.php create mode 100644 workflow/engine/classes/class.jrml.php create mode 100644 workflow/engine/classes/class.languages.php create mode 100644 workflow/engine/classes/class.net.php create mode 100755 workflow/engine/classes/class.package.php create mode 100644 workflow/engine/classes/class.plugin.php create mode 100644 workflow/engine/classes/class.pluginRegistry.php create mode 100644 workflow/engine/classes/class.pmFunctions.php create mode 100644 workflow/engine/classes/class.pmScript.php create mode 100644 workflow/engine/classes/class.popupMenu.php create mode 100644 workflow/engine/classes/class.processMap.php create mode 100644 workflow/engine/classes/class.processes.php create mode 100644 workflow/engine/classes/class.propelTable.php create mode 100755 workflow/engine/classes/class.replacementLogo.php create mode 100644 workflow/engine/classes/class.report.php create mode 100644 workflow/engine/classes/class.reportTables.php create mode 100644 workflow/engine/classes/class.serverConfiguration.php create mode 100644 workflow/engine/classes/class.sessions.php create mode 100755 workflow/engine/classes/class.smtp.php create mode 100644 workflow/engine/classes/class.smtp.rfc-821.php create mode 100755 workflow/engine/classes/class.spool.php create mode 100755 workflow/engine/classes/class.system.php create mode 100644 workflow/engine/classes/class.tasks.php create mode 100644 workflow/engine/classes/class.toolBar.php create mode 100644 workflow/engine/classes/class.triggerLibrary.php create mode 100644 workflow/engine/classes/class.webdav.php create mode 100644 workflow/engine/classes/class.wsBase.php create mode 100644 workflow/engine/classes/class.wsResponse.php create mode 100644 workflow/engine/classes/class.wsTools.php create mode 100644 workflow/engine/classes/class.xmlDb.php create mode 100644 workflow/engine/classes/class.xmlfield_Image.php create mode 100644 workflow/engine/classes/class.xmlfield_InputPM.php create mode 100644 workflow/engine/classes/model/AdditionalTables.php create mode 100644 workflow/engine/classes/model/AdditionalTablesPeer.php create mode 100644 workflow/engine/classes/model/AppCacheView.php create mode 100644 workflow/engine/classes/model/AppCacheViewPeer.php create mode 100644 workflow/engine/classes/model/AppDelay.php create mode 100644 workflow/engine/classes/model/AppDelayPeer.php create mode 100644 workflow/engine/classes/model/AppDelegation.php create mode 100644 workflow/engine/classes/model/AppDelegationPeer.php create mode 100644 workflow/engine/classes/model/AppDocument.php create mode 100644 workflow/engine/classes/model/AppDocumentPeer.php create mode 100644 workflow/engine/classes/model/AppEvent.php create mode 100644 workflow/engine/classes/model/AppEventPeer.php create mode 100644 workflow/engine/classes/model/AppFolder.php create mode 100644 workflow/engine/classes/model/AppFolderPeer.php create mode 100644 workflow/engine/classes/model/AppHistory.php create mode 100644 workflow/engine/classes/model/AppHistoryPeer.php create mode 100644 workflow/engine/classes/model/AppMessage.php create mode 100644 workflow/engine/classes/model/AppMessagePeer.php create mode 100644 workflow/engine/classes/model/AppOwner.php create mode 100644 workflow/engine/classes/model/AppOwnerPeer.php create mode 100644 workflow/engine/classes/model/AppSpool.php create mode 100644 workflow/engine/classes/model/AppSpoolPeer.php create mode 100644 workflow/engine/classes/model/AppThread.php create mode 100644 workflow/engine/classes/model/AppThreadPeer.php create mode 100644 workflow/engine/classes/model/Application.php create mode 100644 workflow/engine/classes/model/ApplicationPeer.php create mode 100755 workflow/engine/classes/model/CalendarAssignments.php create mode 100755 workflow/engine/classes/model/CalendarAssignmentsPeer.php create mode 100755 workflow/engine/classes/model/CalendarBusinessHours.php create mode 100755 workflow/engine/classes/model/CalendarBusinessHoursPeer.php create mode 100755 workflow/engine/classes/model/CalendarDefinition.php create mode 100755 workflow/engine/classes/model/CalendarDefinitionPeer.php create mode 100755 workflow/engine/classes/model/CalendarHolidays.php create mode 100755 workflow/engine/classes/model/CalendarHolidaysPeer.php create mode 100644 workflow/engine/classes/model/CaseScheduler.php create mode 100755 workflow/engine/classes/model/CaseSchedulerPeer.php create mode 100644 workflow/engine/classes/model/CaseTracker.php create mode 100644 workflow/engine/classes/model/CaseTrackerObject.php create mode 100644 workflow/engine/classes/model/CaseTrackerObjectPeer.php create mode 100644 workflow/engine/classes/model/CaseTrackerPeer.php create mode 100644 workflow/engine/classes/model/Configuration.php create mode 100644 workflow/engine/classes/model/ConfigurationPeer.php create mode 100644 workflow/engine/classes/model/Content.php create mode 100644 workflow/engine/classes/model/ContentPeer.php create mode 100644 workflow/engine/classes/model/DbSource.php create mode 100644 workflow/engine/classes/model/DbSourcePeer.php create mode 100644 workflow/engine/classes/model/Department.php create mode 100644 workflow/engine/classes/model/DepartmentPeer.php create mode 100644 workflow/engine/classes/model/DimTimeComplete.php create mode 100644 workflow/engine/classes/model/DimTimeCompletePeer.php create mode 100644 workflow/engine/classes/model/DimTimeDelegate.php create mode 100644 workflow/engine/classes/model/DimTimeDelegatePeer.php create mode 100644 workflow/engine/classes/model/Dynaform.php create mode 100644 workflow/engine/classes/model/DynaformPeer.php create mode 100644 workflow/engine/classes/model/Event.php create mode 100644 workflow/engine/classes/model/EventPeer.php create mode 100644 workflow/engine/classes/model/FieldCondition.php create mode 100644 workflow/engine/classes/model/FieldConditionPeer.php create mode 100644 workflow/engine/classes/model/Fields.php create mode 100644 workflow/engine/classes/model/FieldsPeer.php create mode 100644 workflow/engine/classes/model/GroupUser.php create mode 100644 workflow/engine/classes/model/GroupUserPeer.php create mode 100644 workflow/engine/classes/model/Groupwf.php create mode 100644 workflow/engine/classes/model/GroupwfPeer.php create mode 100644 workflow/engine/classes/model/Holiday.php create mode 100644 workflow/engine/classes/model/HolidayPeer.php create mode 100644 workflow/engine/classes/model/InputDocument.php create mode 100644 workflow/engine/classes/model/InputDocumentPeer.php create mode 100644 workflow/engine/classes/model/IsoCountry.php create mode 100644 workflow/engine/classes/model/IsoCountryPeer.php create mode 100644 workflow/engine/classes/model/IsoLocation.php create mode 100644 workflow/engine/classes/model/IsoLocationPeer.php create mode 100644 workflow/engine/classes/model/IsoSubdivision.php create mode 100644 workflow/engine/classes/model/IsoSubdivisionPeer.php create mode 100644 workflow/engine/classes/model/Language.php create mode 100644 workflow/engine/classes/model/LanguagePeer.php create mode 100644 workflow/engine/classes/model/Lexico.php create mode 100644 workflow/engine/classes/model/LexicoPeer.php create mode 100644 workflow/engine/classes/model/LogCasesScheduler.php create mode 100644 workflow/engine/classes/model/LogCasesSchedulerPeer.php create mode 100644 workflow/engine/classes/model/LoginLog.php create mode 100644 workflow/engine/classes/model/LoginLogPeer.php create mode 100644 workflow/engine/classes/model/ObjectPermission.php create mode 100644 workflow/engine/classes/model/ObjectPermissionPeer.php create mode 100644 workflow/engine/classes/model/OutputDocument.php create mode 100644 workflow/engine/classes/model/OutputDocumentPeer.php create mode 100644 workflow/engine/classes/model/Process.php create mode 100644 workflow/engine/classes/model/ProcessCategory.php create mode 100644 workflow/engine/classes/model/ProcessCategoryPeer.php create mode 100644 workflow/engine/classes/model/ProcessOwner.php create mode 100644 workflow/engine/classes/model/ProcessOwnerPeer.php create mode 100644 workflow/engine/classes/model/ProcessPeer.php create mode 100644 workflow/engine/classes/model/ProcessUser.php create mode 100644 workflow/engine/classes/model/ProcessUserPeer.php create mode 100644 workflow/engine/classes/model/ReportTable.php create mode 100644 workflow/engine/classes/model/ReportTablePeer.php create mode 100644 workflow/engine/classes/model/ReportVar.php create mode 100644 workflow/engine/classes/model/ReportVarPeer.php create mode 100644 workflow/engine/classes/model/Route.php create mode 100644 workflow/engine/classes/model/RoutePeer.php create mode 100644 workflow/engine/classes/model/Session.php create mode 100644 workflow/engine/classes/model/SessionPeer.php create mode 100644 workflow/engine/classes/model/ShadowTable.php create mode 100644 workflow/engine/classes/model/ShadowTablePeer.php create mode 100644 workflow/engine/classes/model/Stage.php create mode 100644 workflow/engine/classes/model/StagePeer.php create mode 100644 workflow/engine/classes/model/Step.php create mode 100644 workflow/engine/classes/model/StepPeer.php create mode 100644 workflow/engine/classes/model/StepSupervisor.php create mode 100644 workflow/engine/classes/model/StepSupervisorPeer.php create mode 100644 workflow/engine/classes/model/StepTrigger.php create mode 100644 workflow/engine/classes/model/StepTriggerPeer.php create mode 100644 workflow/engine/classes/model/SubApplication.php create mode 100644 workflow/engine/classes/model/SubApplicationPeer.php create mode 100644 workflow/engine/classes/model/SubProcess.php create mode 100644 workflow/engine/classes/model/SubProcessPeer.php create mode 100644 workflow/engine/classes/model/SwimlanesElements.php create mode 100644 workflow/engine/classes/model/SwimlanesElementsPeer.php create mode 100644 workflow/engine/classes/model/Task.php create mode 100644 workflow/engine/classes/model/TaskPeer.php create mode 100644 workflow/engine/classes/model/TaskUser.php create mode 100644 workflow/engine/classes/model/TaskUserPeer.php create mode 100644 workflow/engine/classes/model/Translation.php create mode 100644 workflow/engine/classes/model/TranslationPeer.php create mode 100644 workflow/engine/classes/model/Triggers.php create mode 100644 workflow/engine/classes/model/TriggersPeer.php create mode 100644 workflow/engine/classes/model/Users.php create mode 100644 workflow/engine/classes/model/UsersPeer.php create mode 100644 workflow/engine/classes/model/UsersProperties.php create mode 100644 workflow/engine/classes/model/UsersPropertiesPeer.php create mode 100644 workflow/engine/classes/model/map/AdditionalTablesMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppCacheViewMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppDelayMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppDelegationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppDocumentMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppEventMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppFolderMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppHistoryMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppMessageMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppOwnerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppSpoolMapBuilder.php create mode 100644 workflow/engine/classes/model/map/AppThreadMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ApplicationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CalendarAssignmentsMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CalendarBusinessHoursMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CalendarDefinitionMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CalendarHolidaysMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CaseSchedulerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CaseTrackerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/CaseTrackerObjectMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ConfigurationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ContentMapBuilder.php create mode 100644 workflow/engine/classes/model/map/DbSourceMapBuilder.php create mode 100644 workflow/engine/classes/model/map/DepartmentMapBuilder.php create mode 100644 workflow/engine/classes/model/map/DimTimeCompleteMapBuilder.php create mode 100644 workflow/engine/classes/model/map/DimTimeDelegateMapBuilder.php create mode 100644 workflow/engine/classes/model/map/DynaformMapBuilder.php create mode 100644 workflow/engine/classes/model/map/EventMapBuilder.php create mode 100644 workflow/engine/classes/model/map/FieldConditionMapBuilder.php create mode 100644 workflow/engine/classes/model/map/FieldsMapBuilder.php create mode 100644 workflow/engine/classes/model/map/GroupUserMapBuilder.php create mode 100644 workflow/engine/classes/model/map/GroupwfMapBuilder.php create mode 100644 workflow/engine/classes/model/map/HolidayMapBuilder.php create mode 100644 workflow/engine/classes/model/map/InputDocumentMapBuilder.php create mode 100644 workflow/engine/classes/model/map/IsoCountryMapBuilder.php create mode 100644 workflow/engine/classes/model/map/IsoLocationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/IsoSubdivisionMapBuilder.php create mode 100644 workflow/engine/classes/model/map/LanguageMapBuilder.php create mode 100644 workflow/engine/classes/model/map/LexicoMapBuilder.php create mode 100644 workflow/engine/classes/model/map/LogCasesSchedulerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/LoginLogMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ObjectPermissionMapBuilder.php create mode 100644 workflow/engine/classes/model/map/OutputDocumentMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ProcessCategoryMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ProcessMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ProcessOwnerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ProcessUserMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ReportTableMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ReportVarMapBuilder.php create mode 100644 workflow/engine/classes/model/map/RouteMapBuilder.php create mode 100644 workflow/engine/classes/model/map/SessionMapBuilder.php create mode 100644 workflow/engine/classes/model/map/ShadowTableMapBuilder.php create mode 100644 workflow/engine/classes/model/map/StageMapBuilder.php create mode 100644 workflow/engine/classes/model/map/StepMapBuilder.php create mode 100644 workflow/engine/classes/model/map/StepSupervisorMapBuilder.php create mode 100644 workflow/engine/classes/model/map/StepTriggerMapBuilder.php create mode 100644 workflow/engine/classes/model/map/SubApplicationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/SubProcessMapBuilder.php create mode 100644 workflow/engine/classes/model/map/SwimlanesElementsMapBuilder.php create mode 100644 workflow/engine/classes/model/map/TaskMapBuilder.php create mode 100644 workflow/engine/classes/model/map/TaskUserMapBuilder.php create mode 100644 workflow/engine/classes/model/map/TranslationMapBuilder.php create mode 100644 workflow/engine/classes/model/map/TriggersMapBuilder.php create mode 100644 workflow/engine/classes/model/map/UsersMapBuilder.php create mode 100644 workflow/engine/classes/model/map/UsersPropertiesMapBuilder.php create mode 100644 workflow/engine/classes/model/om/.directory create mode 100644 workflow/engine/classes/model/om/BaseAdditionalTables.php create mode 100644 workflow/engine/classes/model/om/BaseAdditionalTablesPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppCacheView.php create mode 100644 workflow/engine/classes/model/om/BaseAppCacheViewPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppDelay.php create mode 100644 workflow/engine/classes/model/om/BaseAppDelayPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppDelegation.php create mode 100644 workflow/engine/classes/model/om/BaseAppDelegationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppDocument.php create mode 100644 workflow/engine/classes/model/om/BaseAppDocumentPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppEvent.php create mode 100644 workflow/engine/classes/model/om/BaseAppEventPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppFolder.php create mode 100644 workflow/engine/classes/model/om/BaseAppFolderPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppHistory.php create mode 100644 workflow/engine/classes/model/om/BaseAppHistoryPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppMessage.php create mode 100644 workflow/engine/classes/model/om/BaseAppMessagePeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppOwner.php create mode 100644 workflow/engine/classes/model/om/BaseAppOwnerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppSpool.php create mode 100644 workflow/engine/classes/model/om/BaseAppSpoolPeer.php create mode 100644 workflow/engine/classes/model/om/BaseAppThread.php create mode 100644 workflow/engine/classes/model/om/BaseAppThreadPeer.php create mode 100644 workflow/engine/classes/model/om/BaseApplication.php create mode 100644 workflow/engine/classes/model/om/BaseApplicationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarAssignments.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarAssignmentsPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarBusinessHours.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarBusinessHoursPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarDefinition.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarDefinitionPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarHolidays.php create mode 100644 workflow/engine/classes/model/om/BaseCalendarHolidaysPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCaseScheduler.php create mode 100644 workflow/engine/classes/model/om/BaseCaseSchedulerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCaseTracker.php create mode 100644 workflow/engine/classes/model/om/BaseCaseTrackerObject.php create mode 100644 workflow/engine/classes/model/om/BaseCaseTrackerObjectPeer.php create mode 100644 workflow/engine/classes/model/om/BaseCaseTrackerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseConfiguration.php create mode 100644 workflow/engine/classes/model/om/BaseConfigurationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseContent.php create mode 100644 workflow/engine/classes/model/om/BaseContentPeer.php create mode 100644 workflow/engine/classes/model/om/BaseDbSource.php create mode 100644 workflow/engine/classes/model/om/BaseDbSourcePeer.php create mode 100644 workflow/engine/classes/model/om/BaseDepartment.php create mode 100644 workflow/engine/classes/model/om/BaseDepartmentPeer.php create mode 100644 workflow/engine/classes/model/om/BaseDimTimeComplete.php create mode 100644 workflow/engine/classes/model/om/BaseDimTimeCompletePeer.php create mode 100644 workflow/engine/classes/model/om/BaseDimTimeDelegate.php create mode 100644 workflow/engine/classes/model/om/BaseDimTimeDelegatePeer.php create mode 100644 workflow/engine/classes/model/om/BaseDynaform.php create mode 100644 workflow/engine/classes/model/om/BaseDynaformPeer.php create mode 100644 workflow/engine/classes/model/om/BaseEvent.php create mode 100644 workflow/engine/classes/model/om/BaseEventPeer.php create mode 100644 workflow/engine/classes/model/om/BaseFieldCondition.php create mode 100644 workflow/engine/classes/model/om/BaseFieldConditionPeer.php create mode 100644 workflow/engine/classes/model/om/BaseFields.php create mode 100644 workflow/engine/classes/model/om/BaseFieldsPeer.php create mode 100644 workflow/engine/classes/model/om/BaseGroupUser.php create mode 100644 workflow/engine/classes/model/om/BaseGroupUserPeer.php create mode 100644 workflow/engine/classes/model/om/BaseGroupwf.php create mode 100644 workflow/engine/classes/model/om/BaseGroupwfPeer.php create mode 100644 workflow/engine/classes/model/om/BaseHoliday.php create mode 100644 workflow/engine/classes/model/om/BaseHolidayPeer.php create mode 100644 workflow/engine/classes/model/om/BaseInputDocument.php create mode 100644 workflow/engine/classes/model/om/BaseInputDocumentPeer.php create mode 100644 workflow/engine/classes/model/om/BaseIsoCountry.php create mode 100644 workflow/engine/classes/model/om/BaseIsoCountryPeer.php create mode 100644 workflow/engine/classes/model/om/BaseIsoLocation.php create mode 100644 workflow/engine/classes/model/om/BaseIsoLocationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseIsoSubdivision.php create mode 100644 workflow/engine/classes/model/om/BaseIsoSubdivisionPeer.php create mode 100644 workflow/engine/classes/model/om/BaseLanguage.php create mode 100644 workflow/engine/classes/model/om/BaseLanguagePeer.php create mode 100644 workflow/engine/classes/model/om/BaseLexico.php create mode 100644 workflow/engine/classes/model/om/BaseLexicoPeer.php create mode 100644 workflow/engine/classes/model/om/BaseLogCasesScheduler.php create mode 100644 workflow/engine/classes/model/om/BaseLogCasesSchedulerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseLoginLog.php create mode 100644 workflow/engine/classes/model/om/BaseLoginLogPeer.php create mode 100644 workflow/engine/classes/model/om/BaseObjectPermission.php create mode 100644 workflow/engine/classes/model/om/BaseObjectPermissionPeer.php create mode 100644 workflow/engine/classes/model/om/BaseOutputDocument.php create mode 100644 workflow/engine/classes/model/om/BaseOutputDocumentPeer.php create mode 100644 workflow/engine/classes/model/om/BaseProcess.php create mode 100644 workflow/engine/classes/model/om/BaseProcessCategory.php create mode 100644 workflow/engine/classes/model/om/BaseProcessCategoryPeer.php create mode 100644 workflow/engine/classes/model/om/BaseProcessOwner.php create mode 100644 workflow/engine/classes/model/om/BaseProcessOwnerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseProcessPeer.php create mode 100644 workflow/engine/classes/model/om/BaseProcessUser.php create mode 100644 workflow/engine/classes/model/om/BaseProcessUserPeer.php create mode 100644 workflow/engine/classes/model/om/BaseReportTable.php create mode 100644 workflow/engine/classes/model/om/BaseReportTablePeer.php create mode 100644 workflow/engine/classes/model/om/BaseReportVar.php create mode 100644 workflow/engine/classes/model/om/BaseReportVarPeer.php create mode 100644 workflow/engine/classes/model/om/BaseRoute.php create mode 100644 workflow/engine/classes/model/om/BaseRoutePeer.php create mode 100644 workflow/engine/classes/model/om/BaseSession.php create mode 100644 workflow/engine/classes/model/om/BaseSessionPeer.php create mode 100644 workflow/engine/classes/model/om/BaseShadowTable.php create mode 100644 workflow/engine/classes/model/om/BaseShadowTablePeer.php create mode 100644 workflow/engine/classes/model/om/BaseStage.php create mode 100644 workflow/engine/classes/model/om/BaseStagePeer.php create mode 100644 workflow/engine/classes/model/om/BaseStep.php create mode 100644 workflow/engine/classes/model/om/BaseStepPeer.php create mode 100644 workflow/engine/classes/model/om/BaseStepSupervisor.php create mode 100644 workflow/engine/classes/model/om/BaseStepSupervisorPeer.php create mode 100644 workflow/engine/classes/model/om/BaseStepTrigger.php create mode 100644 workflow/engine/classes/model/om/BaseStepTriggerPeer.php create mode 100644 workflow/engine/classes/model/om/BaseSubApplication.php create mode 100644 workflow/engine/classes/model/om/BaseSubApplicationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseSubProcess.php create mode 100644 workflow/engine/classes/model/om/BaseSubProcessPeer.php create mode 100644 workflow/engine/classes/model/om/BaseSwimlanesElements.php create mode 100644 workflow/engine/classes/model/om/BaseSwimlanesElementsPeer.php create mode 100644 workflow/engine/classes/model/om/BaseTask.php create mode 100644 workflow/engine/classes/model/om/BaseTaskPeer.php create mode 100644 workflow/engine/classes/model/om/BaseTaskUser.php create mode 100644 workflow/engine/classes/model/om/BaseTaskUserPeer.php create mode 100644 workflow/engine/classes/model/om/BaseTranslation.php create mode 100644 workflow/engine/classes/model/om/BaseTranslationPeer.php create mode 100644 workflow/engine/classes/model/om/BaseTriggers.php create mode 100644 workflow/engine/classes/model/om/BaseTriggersPeer.php create mode 100644 workflow/engine/classes/model/om/BaseUsers.php create mode 100644 workflow/engine/classes/model/om/BaseUsersPeer.php create mode 100644 workflow/engine/classes/model/om/BaseUsersProperties.php create mode 100644 workflow/engine/classes/model/om/BaseUsersPropertiesPeer.php create mode 100644 workflow/engine/classes/triggers/class.pmSugarFunctions.php create mode 100644 workflow/engine/classes/triggers/class.pmTalendFunctions.php create mode 100644 workflow/engine/config/databases.php create mode 100644 workflow/engine/config/environments.php create mode 100644 workflow/engine/config/paths.php create mode 100644 workflow/engine/config/propel.ini create mode 100644 workflow/engine/config/propel.mssql.ini create mode 100644 workflow/engine/config/propel.mysql.ini create mode 100644 workflow/engine/config/propel.oracle.ini create mode 100644 workflow/engine/config/propel.pgsql.ini create mode 100644 workflow/engine/config/properties.ini create mode 100644 workflow/engine/config/rbac.ini create mode 100644 workflow/engine/config/schema.xml create mode 100644 workflow/engine/content/languages/en.js create mode 100644 workflow/engine/content/translations/english/processmaker.en.po create mode 100644 workflow/engine/content/translations/pmos-translations.meta create mode 100644 workflow/engine/data/mssql/schema.sql create mode 100644 workflow/engine/data/mssql/sqldb.map create mode 100644 workflow/engine/data/mysql/create-db.sql create mode 100755 workflow/engine/data/mysql/insert.sql create mode 100644 workflow/engine/data/mysql/schema.sql create mode 100644 workflow/engine/data/mysql/sqldb.map create mode 100644 workflow/engine/data/oracle/create-db.sql create mode 100644 workflow/engine/data/oracle/schema.sql create mode 100644 workflow/engine/data/oracle/sqldb.map create mode 100644 workflow/engine/data/pgsql/create-db.sql create mode 100644 workflow/engine/data/pgsql/sqldb.map create mode 100644 workflow/engine/gulliver-win.bat create mode 100644 workflow/engine/includes/inc.JSForms.php create mode 100644 workflow/engine/includes/inc.application.php create mode 100644 workflow/engine/includes/inc.dynaForms.php create mode 100755 workflow/engine/js/appFolder/core/appFolderList.js create mode 100644 workflow/engine/js/cases/core/cases.js create mode 100644 workflow/engine/js/cases/core/cases_Step.js create mode 100755 workflow/engine/js/cases/reassignByUser.js create mode 100644 workflow/engine/js/controls/varsAjax.js create mode 100644 workflow/engine/js/dashboard/core/dashboard.js create mode 100755 workflow/engine/js/dbConnections/main.js create mode 100644 workflow/engine/js/departments/departments.js create mode 100755 workflow/engine/js/dynaformEditor/core/dynaformEditor.js create mode 100755 workflow/engine/js/dynaforms/dynaforms_conditionalShowHide.js create mode 100755 workflow/engine/js/dynaforms/dynaforms_fieldsHandler.js create mode 100644 workflow/engine/js/events/events.js create mode 100755 workflow/engine/js/groups/groups.js create mode 100755 workflow/engine/js/processes/main.js create mode 100644 workflow/engine/js/processmap/core/images/-1.gif create mode 100755 workflow/engine/js/processmap/core/images/-1b.gif create mode 100644 workflow/engine/js/processmap/core/images/-1bb.jpg create mode 100644 workflow/engine/js/processmap/core/images/-2.gif create mode 100644 workflow/engine/js/processmap/core/images/0.gif create mode 100644 workflow/engine/js/processmap/core/images/0t.gif create mode 100644 workflow/engine/js/processmap/core/images/1.gif create mode 100644 workflow/engine/js/processmap/core/images/1t.gif create mode 100644 workflow/engine/js/processmap/core/images/2.gif create mode 100644 workflow/engine/js/processmap/core/images/2t.gif create mode 100644 workflow/engine/js/processmap/core/images/3.gif create mode 100644 workflow/engine/js/processmap/core/images/3t.gif create mode 100644 workflow/engine/js/processmap/core/images/4.gif create mode 100644 workflow/engine/js/processmap/core/images/4t.gif create mode 100644 workflow/engine/js/processmap/core/images/5.gif create mode 100644 workflow/engine/js/processmap/core/images/5t.gif create mode 100644 workflow/engine/js/processmap/core/images/6.gif create mode 100644 workflow/engine/js/processmap/core/images/7.gif create mode 100644 workflow/engine/js/processmap/core/images/arrowB.gif create mode 100644 workflow/engine/js/processmap/core/images/bg_pm.gif create mode 100644 workflow/engine/js/processmap/core/images/bg_pm.png create mode 100644 workflow/engine/js/processmap/core/images/bg_task.gif create mode 100644 workflow/engine/js/processmap/core/images/bg_task2.gif create mode 100644 workflow/engine/js/processmap/core/images/cancel.gif create mode 100644 workflow/engine/js/processmap/core/images/inicio.gif create mode 100644 workflow/engine/js/processmap/core/images/loader_B.gif create mode 100644 workflow/engine/js/processmap/core/images/mail.gif create mode 100644 workflow/engine/js/processmap/core/images/parar.gif create mode 100644 workflow/engine/js/processmap/core/images/proceso.gif create mode 100644 workflow/engine/js/processmap/core/images/puntito.gif create mode 100644 workflow/engine/js/processmap/core/processUser.js create mode 100644 workflow/engine/js/processmap/core/processes_Map.js create mode 100644 workflow/engine/js/processmap/core/processmap.js create mode 100644 workflow/engine/js/reports/reports.js create mode 100644 workflow/engine/js/setup/pluginList.js create mode 100644 workflow/engine/js/setup/upgrade_System.js create mode 100644 workflow/engine/js/stagesmap/core/stagesmap.js create mode 100644 workflow/engine/js/tracker/tracker.js create mode 100755 workflow/engine/menus/admin.php create mode 100644 workflow/engine/menus/appFolder.php create mode 100644 workflow/engine/menus/backApp.php create mode 100644 workflow/engine/menus/cancel.php create mode 100644 workflow/engine/menus/caseOptions.php create mode 100644 workflow/engine/menus/caseTracker.php create mode 100644 workflow/engine/menus/cases.php create mode 100644 workflow/engine/menus/process.php create mode 100644 workflow/engine/menus/processes.php create mode 100644 workflow/engine/menus/processmaker.php create mode 100644 workflow/engine/menus/rbac.appEdit.php create mode 100644 workflow/engine/menus/rbac.appView.php create mode 100644 workflow/engine/menus/rbac.application.php create mode 100644 workflow/engine/menus/rbac.authSource.php create mode 100644 workflow/engine/menus/rbac.authentication.php create mode 100644 workflow/engine/menus/rbac.permission.php create mode 100644 workflow/engine/menus/rbac.php create mode 100644 workflow/engine/menus/rbac.role.php create mode 100644 workflow/engine/menus/rbac.user.php create mode 100644 workflow/engine/menus/rbac.userEdit.php create mode 100644 workflow/engine/menus/rbac.userView.php create mode 100644 workflow/engine/menus/setup.php create mode 100644 workflow/engine/menus/tools.php create mode 100644 workflow/engine/menus/toolsTranslations.php create mode 100644 workflow/engine/menus/users.php create mode 100644 workflow/engine/menus/wf.login.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesAjax.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesData.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDataDelete.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDataEdit.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDataImport.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDataImportForm.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDataNew.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesDelete.php create mode 100755 workflow/engine/methods/additionalTables/additionalTablesDoImport.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesEdit.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesList.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesNew.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesSave.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesSaveData.php create mode 100755 workflow/engine/methods/additionalTables/additionalTablesToImport.php create mode 100644 workflow/engine/methods/additionalTables/additionalTablesUpdateData.php create mode 100755 workflow/engine/methods/additionalTables/doExport.php create mode 100755 workflow/engine/methods/appFolder/appFolderAjax.php create mode 100644 workflow/engine/methods/appFolder/appFolderDelete.php create mode 100644 workflow/engine/methods/appFolder/appFolderDeleteExec.php create mode 100644 workflow/engine/methods/appFolder/appFolderEdit.php create mode 100644 workflow/engine/methods/appFolder/appFolderList.php create mode 100644 workflow/engine/methods/appFolder/appFolderNew.php create mode 100644 workflow/engine/methods/appFolder/appFolderSave.php create mode 100755 workflow/engine/methods/appFolder/appFolderSaveDocument.php create mode 100644 workflow/engine/methods/authSources/authSources_Ajax.php create mode 100644 workflow/engine/methods/authSources/authSources_Delete.php create mode 100644 workflow/engine/methods/authSources/authSources_Edit.php create mode 100644 workflow/engine/methods/authSources/authSources_ImportUsers.php create mode 100644 workflow/engine/methods/authSources/authSources_List.php create mode 100644 workflow/engine/methods/authSources/authSources_New.php create mode 100644 workflow/engine/methods/authSources/authSources_Save.php create mode 100644 workflow/engine/methods/authSources/authSources_SearchUsers.php create mode 100644 workflow/engine/methods/authSources/authSources_SelectType.php create mode 100644 workflow/engine/methods/cases/casesDemo.php create mode 100755 workflow/engine/methods/cases/casesListExtJs.php create mode 100644 workflow/engine/methods/cases/casesMenuLoader.php create mode 100644 workflow/engine/methods/cases/casesStartPage.php create mode 100755 workflow/engine/methods/cases/casesStartPage_Ajax.php create mode 100644 workflow/engine/methods/cases/casesToRevisePanelExtJs.php create mode 100644 workflow/engine/methods/cases/casesToReviseTreeContent.php create mode 100644 workflow/engine/methods/cases/cases_Ajax.php create mode 100644 workflow/engine/methods/cases/cases_CatchExecute.php create mode 100644 workflow/engine/methods/cases/cases_CatchSelfService.php create mode 100644 workflow/engine/methods/cases/cases_Delete.php create mode 100644 workflow/engine/methods/cases/cases_DeleteDocument.php create mode 100644 workflow/engine/methods/cases/cases_Derivate.php create mode 100644 workflow/engine/methods/cases/cases_List.php create mode 100644 workflow/engine/methods/cases/cases_New.php create mode 100644 workflow/engine/methods/cases/cases_NextStep.php create mode 100644 workflow/engine/methods/cases/cases_Open.php create mode 100644 workflow/engine/methods/cases/cases_OpenToRevise.php create mode 100644 workflow/engine/methods/cases/cases_PrintView.php create mode 100644 workflow/engine/methods/cases/cases_Reassign.php create mode 100644 workflow/engine/methods/cases/cases_ReassignByUser.php create mode 100644 workflow/engine/methods/cases/cases_Reassign_save.php create mode 100644 workflow/engine/methods/cases/cases_Redirect.php create mode 100644 workflow/engine/methods/cases/cases_Resume.php create mode 100644 workflow/engine/methods/cases/cases_Save.php create mode 100644 workflow/engine/methods/cases/cases_SaveData.php create mode 100644 workflow/engine/methods/cases/cases_SaveDataSupervisor.php create mode 100644 workflow/engine/methods/cases/cases_SaveDocument.php create mode 100644 workflow/engine/methods/cases/cases_SchedulerGetPlugins.php create mode 100644 workflow/engine/methods/cases/cases_SchedulerGetProcesses.php create mode 100644 workflow/engine/methods/cases/cases_SchedulerGetTasks.php create mode 100644 workflow/engine/methods/cases/cases_SchedulerValidateUser.php create mode 100755 workflow/engine/methods/cases/cases_Scheduler_ChangeStatus.php create mode 100755 workflow/engine/methods/cases/cases_Scheduler_Delete.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_Edit.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_List.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_Log.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_Log_Detail.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_New.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_Save.php create mode 100644 workflow/engine/methods/cases/cases_Scheduler_Update.php create mode 100644 workflow/engine/methods/cases/cases_ShowDocument.php create mode 100644 workflow/engine/methods/cases/cases_ShowOutputDocument.php create mode 100644 workflow/engine/methods/cases/cases_ShowToReviseOutputDocument.php create mode 100644 workflow/engine/methods/cases/cases_Step.php create mode 100644 workflow/engine/methods/cases/cases_StepToRevise.php create mode 100644 workflow/engine/methods/cases/cases_StepToReviseInputs.php create mode 100644 workflow/engine/methods/cases/cases_StepToReviseOutputs.php create mode 100644 workflow/engine/methods/cases/cases_SupervisorSaveDocument.php create mode 100644 workflow/engine/methods/cases/cases_ToReviseInputDocView.php create mode 100644 workflow/engine/methods/cases/cases_ToReviseOutputDocView.php create mode 100644 workflow/engine/methods/cases/cases_UsersReassign.php create mode 100644 workflow/engine/methods/cases/cases_advancedSearch.php create mode 100644 workflow/engine/methods/cases/cases_generatePMTable.php create mode 100644 workflow/engine/methods/cases/cases_toRevise.php create mode 100755 workflow/engine/methods/cases/debug_triggers.php create mode 100755 workflow/engine/methods/cases/debug_vars.php create mode 100644 workflow/engine/methods/cases/index.php create mode 100755 workflow/engine/methods/cases/main.php create mode 100644 workflow/engine/methods/cases/main_init.php create mode 100755 workflow/engine/methods/cases/proxyCasesList.php create mode 100755 workflow/engine/methods/cases/proxyProcessList.php create mode 100644 workflow/engine/methods/cases/proxyReassignCasesList.php create mode 100644 workflow/engine/methods/cases/proxyReassignUsersList.php create mode 100644 workflow/engine/methods/cases/proxySaveReassignCasesList.php create mode 100644 workflow/engine/methods/controls/buscador.php create mode 100644 workflow/engine/methods/controls/buscador2.php create mode 100644 workflow/engine/methods/controls/calendar.js create mode 100644 workflow/engine/methods/controls/calendar.php create mode 100644 workflow/engine/methods/controls/img/cal.gif create mode 100644 workflow/engine/methods/controls/img/logo.gif create mode 100644 workflow/engine/methods/controls/img/next.gif create mode 100644 workflow/engine/methods/controls/img/next_year.gif create mode 100644 workflow/engine/methods/controls/img/pixel.gif create mode 100644 workflow/engine/methods/controls/img/prev.gif create mode 100644 workflow/engine/methods/controls/img/prev_year.gif create mode 100644 workflow/engine/methods/controls/img/tc.gif create mode 100644 workflow/engine/methods/controls/varsAjax.php create mode 100644 workflow/engine/methods/controls/varsAjaxByType.php create mode 100755 workflow/engine/methods/dashboard/dashboard.php create mode 100644 workflow/engine/methods/dashboard/dashboardAjax.php create mode 100644 workflow/engine/methods/dbConnections/dbConnections.php create mode 100644 workflow/engine/methods/dbConnections/dbConnectionsAjax.php create mode 100644 workflow/engine/methods/dbConnections/genericDbConnections.php create mode 100644 workflow/engine/methods/dbConnections/rootDbConnections.php create mode 100644 workflow/engine/methods/departments/departments.php create mode 100644 workflow/engine/methods/departments/departments_AddManager.php create mode 100644 workflow/engine/methods/departments/departments_AddUser.php create mode 100644 workflow/engine/methods/departments/departments_Ajax.php create mode 100644 workflow/engine/methods/departments/departments_Delete.php create mode 100644 workflow/engine/methods/departments/departments_Edit.php create mode 100644 workflow/engine/methods/departments/departments_List.php create mode 100644 workflow/engine/methods/departments/departments_New.php create mode 100644 workflow/engine/methods/departments/departments_Save.php create mode 100644 workflow/engine/methods/departments/subdep_Delete.php create mode 100644 workflow/engine/methods/departments/subdep_Edit.php create mode 100644 workflow/engine/methods/departments/subdep_Save.php create mode 100755 workflow/engine/methods/dynaforms/conditionalShowHide.php create mode 100755 workflow/engine/methods/dynaforms/conditionalShowHide_Ajax.php create mode 100755 workflow/engine/methods/dynaforms/datemask.php create mode 100644 workflow/engine/methods/dynaforms/dynaform_Fields.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Ajax.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_AssignVariables.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_ChoseType.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Delete.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Edit.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Editor.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_FlatEditor.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_List.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_NewPlugin.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_PagedTableAjax.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Preview.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Save.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_SaveProperties.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Save_as.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_Saveas.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_ToolbarAjax.php create mode 100644 workflow/engine/methods/dynaforms/dynaforms_checkDependentFields.php create mode 100644 workflow/engine/methods/dynaforms/fieldsGetterAjax.php create mode 100755 workflow/engine/methods/dynaforms/fieldsHandler.php create mode 100755 workflow/engine/methods/dynaforms/fieldsHandlerAjax.php create mode 100755 workflow/engine/methods/dynaforms/fieldsHandlerViewer.php create mode 100644 workflow/engine/methods/dynaforms/fields_Ajax.php create mode 100644 workflow/engine/methods/dynaforms/fields_Delete.php create mode 100644 workflow/engine/methods/dynaforms/fields_Edit.php create mode 100644 workflow/engine/methods/dynaforms/fields_List.php create mode 100644 workflow/engine/methods/dynaforms/fields_Order.php create mode 100644 workflow/engine/methods/dynaforms/fields_Save.php create mode 100644 workflow/engine/methods/dynaforms/test.php create mode 100644 workflow/engine/methods/events/eventsAjax.php create mode 100644 workflow/engine/methods/events/eventsCompleted.php create mode 100644 workflow/engine/methods/events/eventsDelete.php create mode 100644 workflow/engine/methods/events/eventsEdit.php create mode 100644 workflow/engine/methods/events/eventsEditAction.php create mode 100644 workflow/engine/methods/events/eventsNew.php create mode 100644 workflow/engine/methods/events/eventsNewAction.php create mode 100644 workflow/engine/methods/events/eventsPending.php create mode 100644 workflow/engine/methods/events/eventsSave.php create mode 100644 workflow/engine/methods/events/eventsSetupGraph.php create mode 100755 workflow/engine/methods/events/triggersSave.php create mode 100644 workflow/engine/methods/groups/groups.php create mode 100644 workflow/engine/methods/groups/groups_AddUser.php create mode 100644 workflow/engine/methods/groups/groups_Ajax.php create mode 100644 workflow/engine/methods/groups/groups_Delete.php create mode 100644 workflow/engine/methods/groups/groups_Edit.php create mode 100644 workflow/engine/methods/groups/groups_List.php create mode 100644 workflow/engine/methods/groups/groups_Save.php create mode 100644 workflow/engine/methods/groups/groups_SaveAddUser.php create mode 100644 workflow/engine/methods/inputdocs/inputdocs_Delete.php create mode 100644 workflow/engine/methods/inputdocs/inputdocs_Edit.php create mode 100644 workflow/engine/methods/inputdocs/inputdocs_List.php create mode 100644 workflow/engine/methods/inputdocs/inputdocs_Save.php create mode 100644 workflow/engine/methods/install/autoinstallPlugins.php create mode 100644 workflow/engine/methods/install/autoinstallProcesses.php create mode 100644 workflow/engine/methods/install/heartbeatStatus.php create mode 100644 workflow/engine/methods/install/install.js create mode 100644 workflow/engine/methods/install/install.php create mode 100644 workflow/engine/methods/install/installServer.php create mode 100644 workflow/engine/methods/install/newSite.php create mode 100644 workflow/engine/methods/install/r.php create mode 100644 workflow/engine/methods/login/authentication.php create mode 100644 workflow/engine/methods/login/changePassword.php create mode 100644 workflow/engine/methods/login/dbInfo.php create mode 100644 workflow/engine/methods/login/index.php create mode 100644 workflow/engine/methods/login/login.php create mode 100644 workflow/engine/methods/login/login_Ajax.php create mode 100644 workflow/engine/methods/login/noViewPage.php create mode 100644 workflow/engine/methods/login/sysLogin.php create mode 100644 workflow/engine/methods/login/sysLoginVerify.php create mode 100644 workflow/engine/methods/messages/messages_Delete.php create mode 100644 workflow/engine/methods/messages/messages_Edit.php create mode 100644 workflow/engine/methods/messages/messages_List.php create mode 100644 workflow/engine/methods/messages/messages_Save.php create mode 100644 workflow/engine/methods/outputdocs/downloadFile.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_Ajax.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_Delete.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_Edit.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_List.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_New.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_Properties.php create mode 100644 workflow/engine/methods/outputdocs/outputdocs_Save.php create mode 100644 workflow/engine/methods/outputdocs/uploadFile.php create mode 100644 workflow/engine/methods/patterns/patterns_Ajax.php create mode 100644 workflow/engine/methods/processCategory/processCategoryAjax.php create mode 100755 workflow/engine/methods/processCategory/processCategoryDelete.php create mode 100755 workflow/engine/methods/processCategory/processCategoryDeleteExec.php create mode 100755 workflow/engine/methods/processCategory/processCategoryEdit.php create mode 100755 workflow/engine/methods/processCategory/processCategoryList.php create mode 100755 workflow/engine/methods/processCategory/processCategoryNew.php create mode 100755 workflow/engine/methods/processCategory/processCategorySave.php create mode 100644 workflow/engine/methods/processes/clases_Test.php create mode 100644 workflow/engine/methods/processes/downloadPML.php create mode 100644 workflow/engine/methods/processes/downloadPML_ImportExisting.php create mode 100644 workflow/engine/methods/processes/index.php create mode 100755 workflow/engine/methods/processes/main.php create mode 100644 workflow/engine/methods/processes/mainAjax.php create mode 100755 workflow/engine/methods/processes/mainInit.php create mode 100644 workflow/engine/methods/processes/process_DeleteCases.php create mode 100644 workflow/engine/methods/processes/processesList.php create mode 100644 workflow/engine/methods/processes/processes_Ajax.php create mode 100644 workflow/engine/methods/processes/processes_ChangeStatus.php create mode 100644 workflow/engine/methods/processes/processes_Delete.php create mode 100644 workflow/engine/methods/processes/processes_DeleteObjectPermission.php create mode 100644 workflow/engine/methods/processes/processes_DownloadFile.php create mode 100644 workflow/engine/methods/processes/processes_Export.php create mode 100644 workflow/engine/methods/processes/processes_GetFile.php create mode 100644 workflow/engine/methods/processes/processes_Import.php create mode 100644 workflow/engine/methods/processes/processes_ImportExisting.php create mode 100644 workflow/engine/methods/processes/processes_ImportFile.php create mode 100755 workflow/engine/methods/processes/processes_Library.php create mode 100644 workflow/engine/methods/processes/processes_List.php create mode 100644 workflow/engine/methods/processes/processes_Map.php create mode 100644 workflow/engine/methods/processes/processes_New.php create mode 100644 workflow/engine/methods/processes/processes_Save.php create mode 100644 workflow/engine/methods/processes/processes_SaveEditObjectPermission.php create mode 100644 workflow/engine/methods/processes/processes_SaveObjectPermission.php create mode 100644 workflow/engine/methods/processes/processes_UploadFiles.php create mode 100644 workflow/engine/methods/processes/processes_UploadFilesForm.php create mode 100644 workflow/engine/methods/processes/processes_User.php create mode 100644 workflow/engine/methods/processes/processes_availableProcessesUser.php create mode 100755 workflow/engine/methods/processes/processes_checkProperties.php create mode 100644 workflow/engine/methods/processes/processes_doUpload.php create mode 100644 workflow/engine/methods/processes/processes_subProcessSave.php create mode 100644 workflow/engine/methods/processes/processes_webEntryGenerate.php create mode 100644 workflow/engine/methods/processes/processes_webEntryValidate.php create mode 100644 workflow/engine/methods/processes/webEntry_Val_Assig.php create mode 100644 workflow/engine/methods/reportTables/reportTables_Ajax.php create mode 100644 workflow/engine/methods/reportTables/reportTables_Delete.php create mode 100644 workflow/engine/methods/reportTables/reportTables_Edit.php create mode 100644 workflow/engine/methods/reportTables/reportTables_Save.php create mode 100644 workflow/engine/methods/reports/reportsList.php create mode 100644 workflow/engine/methods/reports/reports_Dashboard.php create mode 100644 workflow/engine/methods/reports/reports_Description.php create mode 100644 workflow/engine/methods/reports/reports_Duration.php create mode 100644 workflow/engine/methods/reports/reports_View.php create mode 100644 workflow/engine/methods/roles/roles_Ajax.php create mode 100644 workflow/engine/methods/roles/roles_List.php create mode 100644 workflow/engine/methods/services/ColosaSchema.xsd create mode 100644 workflow/engine/methods/services/cases_StartExternal.php create mode 100644 workflow/engine/methods/services/demoSoap.php create mode 100644 workflow/engine/methods/services/login_getStarted.php create mode 100644 workflow/engine/methods/services/pmos.wsdl create mode 100755 workflow/engine/methods/services/pmos2.wsdl create mode 100644 workflow/engine/methods/services/processHeartBeat_Ajax.php create mode 100644 workflow/engine/methods/services/soap.php create mode 100644 workflow/engine/methods/services/soap2.php create mode 100644 workflow/engine/methods/services/upload.php create mode 100644 workflow/engine/methods/services/webdav.php create mode 100644 workflow/engine/methods/services/wsdl.php create mode 100755 workflow/engine/methods/services/wsdl2.php create mode 100644 workflow/engine/methods/services/wso2.php create mode 100644 workflow/engine/methods/services/xpdl.php create mode 100755 workflow/engine/methods/setup/appCacheViewAjax.php create mode 100755 workflow/engine/methods/setup/appCacheViewConf.php create mode 100644 workflow/engine/methods/setup/appearance.php create mode 100644 workflow/engine/methods/setup/calendarDelete.php create mode 100644 workflow/engine/methods/setup/calendarEdit.php create mode 100644 workflow/engine/methods/setup/calendarList.php create mode 100644 workflow/engine/methods/setup/calendarSave.php create mode 100755 workflow/engine/methods/setup/clearCompiled.php create mode 100644 workflow/engine/methods/setup/connectionDB.php create mode 100644 workflow/engine/methods/setup/connectionWS.php create mode 100644 workflow/engine/methods/setup/customFunctions.php create mode 100644 workflow/engine/methods/setup/debug.php create mode 100755 workflow/engine/methods/setup/emailSystemCron.php create mode 100755 workflow/engine/methods/setup/emailSystemSpool.php create mode 100644 workflow/engine/methods/setup/emailSystemTest.php create mode 100644 workflow/engine/methods/setup/emails.php create mode 100644 workflow/engine/methods/setup/emails_Ajax.php create mode 100644 workflow/engine/methods/setup/emails_Save.php create mode 100755 workflow/engine/methods/setup/environmentSettings.php create mode 100755 workflow/engine/methods/setup/environmentSettingsAjax.php create mode 100644 workflow/engine/methods/setup/holiday.php create mode 100644 workflow/engine/methods/setup/holidayNew.php create mode 100644 workflow/engine/methods/setup/index.php create mode 100644 workflow/engine/methods/setup/jasper.php create mode 100644 workflow/engine/methods/setup/language.php create mode 100644 workflow/engine/methods/setup/language_Ajax.php create mode 100644 workflow/engine/methods/setup/languages.php create mode 100644 workflow/engine/methods/setup/languages_Delete.php create mode 100644 workflow/engine/methods/setup/languages_Export.php create mode 100644 workflow/engine/methods/setup/languages_Import.php create mode 100644 workflow/engine/methods/setup/languages_ImportForm.php create mode 100644 workflow/engine/methods/setup/location.php create mode 100644 workflow/engine/methods/setup/logo_Delete.php create mode 100755 workflow/engine/methods/setup/main.php create mode 100755 workflow/engine/methods/setup/mainAjax.php create mode 100755 workflow/engine/methods/setup/main_init.php create mode 100755 workflow/engine/methods/setup/pluginsChange.php create mode 100644 workflow/engine/methods/setup/pluginsImport.php create mode 100644 workflow/engine/methods/setup/pluginsImportFile.php create mode 100644 workflow/engine/methods/setup/pluginsList.php create mode 100755 workflow/engine/methods/setup/pluginsMain.php create mode 100644 workflow/engine/methods/setup/pluginsRemove.php create mode 100644 workflow/engine/methods/setup/pluginsSetup.php create mode 100644 workflow/engine/methods/setup/pluginsSetupSave.php create mode 100755 workflow/engine/methods/setup/processHeartBeatConfig.php create mode 100755 workflow/engine/methods/setup/processHeartBeatSave.php create mode 100755 workflow/engine/methods/setup/replacementLogo.php create mode 100644 workflow/engine/methods/setup/setup.js create mode 100644 workflow/engine/methods/setup/setup.php create mode 100644 workflow/engine/methods/setup/setupAjax.php create mode 100755 workflow/engine/methods/setup/setupSchemas/app_cache_view.sql create mode 100755 workflow/engine/methods/setup/setupSchemas/app_cache_view_insert.sql create mode 100755 workflow/engine/methods/setup/setupSchemas/triggerAppDelegationInsert.sql create mode 100755 workflow/engine/methods/setup/setupSchemas/triggerAppDelegationUpdate.sql create mode 100644 workflow/engine/methods/setup/setupSchemas/triggerApplicationDelete.sql create mode 100755 workflow/engine/methods/setup/setupSchemas/triggerApplicationUpdate.sql create mode 100644 workflow/engine/methods/setup/showLogoFile.php create mode 100755 workflow/engine/methods/setup/skinsExport.php create mode 100755 workflow/engine/methods/setup/skinsList.php create mode 100644 workflow/engine/methods/setup/skinsNew.php create mode 100644 workflow/engine/methods/setup/skinsSave.php create mode 100644 workflow/engine/methods/setup/upgrade.php create mode 100644 workflow/engine/methods/setup/upgrade_RBAC.php create mode 100644 workflow/engine/methods/setup/upgrade_System.php create mode 100644 workflow/engine/methods/setup/upgrade_SystemAjax.php create mode 100644 workflow/engine/methods/setup/uplogo.php create mode 100644 workflow/engine/methods/setup/webServices.php create mode 100644 workflow/engine/methods/setup/webServicesAjax.php create mode 100644 workflow/engine/methods/setup/webServicesList.php create mode 100644 workflow/engine/methods/setup/webServicesSetup.php create mode 100644 workflow/engine/methods/setup/webServicesSetupSave.php create mode 100644 workflow/engine/methods/setup/weekend.php create mode 100644 workflow/engine/methods/setup/weekendAjax.php create mode 100644 workflow/engine/methods/setup/workPeriod.js create mode 100644 workflow/engine/methods/setup/workPeriod.php create mode 100644 workflow/engine/methods/setup/workPeriodGraph.php create mode 100644 workflow/engine/methods/setup/workPeriodSave.php create mode 100644 workflow/engine/methods/steps/conditions_Edit.php create mode 100644 workflow/engine/methods/steps/conditions_Save.php create mode 100644 workflow/engine/methods/steps/steps_Ajax.php create mode 100644 workflow/engine/methods/steps/steps_Delete.php create mode 100644 workflow/engine/methods/steps/steps_Down.php create mode 100644 workflow/engine/methods/steps/steps_New.php create mode 100644 workflow/engine/methods/steps/steps_Save.php create mode 100644 workflow/engine/methods/steps/steps_SupervisorAjax.php create mode 100644 workflow/engine/methods/steps/steps_Up.php create mode 100644 workflow/engine/methods/tasks/tasks_Ajax.php create mode 100755 workflow/engine/methods/tools/dvServices.php create mode 100644 workflow/engine/methods/tools/index.php create mode 100644 workflow/engine/methods/tools/methodsPermissions.php create mode 100644 workflow/engine/methods/tools/methodsPermissions_Ajax.php create mode 100644 workflow/engine/methods/tools/translations.php create mode 100644 workflow/engine/methods/tools/translationsAdd.php create mode 100644 workflow/engine/methods/tools/translationsAjax.php create mode 100644 workflow/engine/methods/tools/translationsDelete.php create mode 100644 workflow/engine/methods/tools/translationsEdit.php create mode 100644 workflow/engine/methods/tools/translationsSave.php create mode 100644 workflow/engine/methods/tools/updateTranslation.php create mode 100644 workflow/engine/methods/tracker/authentication.php create mode 100644 workflow/engine/methods/tracker/login.php create mode 100644 workflow/engine/methods/tracker/tracker_Ajax.php create mode 100644 workflow/engine/methods/tracker/tracker_ConditionsEdit.php create mode 100644 workflow/engine/methods/tracker/tracker_ConditionsSave.php create mode 100644 workflow/engine/methods/tracker/tracker_DynaDocs.php create mode 100644 workflow/engine/methods/tracker/tracker_History.php create mode 100644 workflow/engine/methods/tracker/tracker_Messages.php create mode 100644 workflow/engine/methods/tracker/tracker_MessagesView.php create mode 100644 workflow/engine/methods/tracker/tracker_No.php create mode 100644 workflow/engine/methods/tracker/tracker_Save.php create mode 100644 workflow/engine/methods/tracker/tracker_Show.php create mode 100644 workflow/engine/methods/tracker/tracker_ShowDocument.php create mode 100644 workflow/engine/methods/tracker/tracker_ShowOutputDocument.php create mode 100644 workflow/engine/methods/tracker/tracker_ViewMap.php create mode 100644 workflow/engine/methods/triggers/triggersProperties.php create mode 100755 workflow/engine/methods/triggers/triggersTree.php create mode 100755 workflow/engine/methods/triggers/triggers_Ajax.php create mode 100755 workflow/engine/methods/triggers/triggers_CreateWizard.php create mode 100644 workflow/engine/methods/triggers/triggers_Delete.php create mode 100644 workflow/engine/methods/triggers/triggers_Edit.php create mode 100644 workflow/engine/methods/triggers/triggers_EditCustom.php create mode 100644 workflow/engine/methods/triggers/triggers_EditWizard.php create mode 100644 workflow/engine/methods/triggers/triggers_Save.php create mode 100755 workflow/engine/methods/triggers/triggers_WizardSave.php create mode 100644 workflow/engine/methods/triggers/triggers_WizardUpdate.php create mode 100644 workflow/engine/methods/users/index.php create mode 100644 workflow/engine/methods/users/myInfo.php create mode 100644 workflow/engine/methods/users/myInfo_Ajax.php create mode 100755 workflow/engine/methods/users/myInfo_Edit.php create mode 100644 workflow/engine/methods/users/myInfo_Save.php create mode 100644 workflow/engine/methods/users/users_Ajax.php create mode 100644 workflow/engine/methods/users/users_AuthSource.php create mode 100644 workflow/engine/methods/users/users_AuthSourceSave.php create mode 100644 workflow/engine/methods/users/users_Delete.php create mode 100644 workflow/engine/methods/users/users_DeleteAssign.php create mode 100644 workflow/engine/methods/users/users_DeleteReassign.php create mode 100644 workflow/engine/methods/users/users_DeleteReassignEnd.php create mode 100644 workflow/engine/methods/users/users_Edit.php create mode 100644 workflow/engine/methods/users/users_Groups.php create mode 100644 workflow/engine/methods/users/users_List.php create mode 100644 workflow/engine/methods/users/users_New.php create mode 100644 workflow/engine/methods/users/users_Reassign.php create mode 100644 workflow/engine/methods/users/users_ReassignCases.php create mode 100644 workflow/engine/methods/users/users_Save.php create mode 100644 workflow/engine/methods/users/users_View.php create mode 100644 workflow/engine/methods/users/users_ViewPhoto.php create mode 100644 workflow/engine/methods/users/users_ViewResume.php create mode 100644 workflow/engine/plugins/charts.php create mode 100644 workflow/engine/plugins/charts/class.charts.php create mode 100644 workflow/engine/plugins/charts/config/setup.conf create mode 100644 workflow/engine/plugins/charts/genericCharts.php create mode 100644 workflow/engine/plugins/charts/setupPage.xml create mode 100644 workflow/engine/plugins/openFlash.php create mode 100644 workflow/engine/plugins/openFlash/chart-data.php create mode 100644 workflow/engine/plugins/openFlash/chart.php create mode 100644 workflow/engine/plugins/openFlash/class.openFlash.php create mode 100644 workflow/engine/plugins/openFlash/open-flash-chart.php create mode 100644 workflow/engine/plugins/openFlash/open_flash_chart_object.php create mode 100644 workflow/engine/plugins/openFlash/public_html/open-flash-chart.swf create mode 100644 workflow/engine/plugins/openFlash/public_html/swfobject.js create mode 100644 workflow/engine/plugins/openFlash/setupPage.xml create mode 100644 workflow/engine/plugins/pmosCommunity.php create mode 100644 workflow/engine/plugins/pmosCommunity/chart-data.php create mode 100644 workflow/engine/plugins/pmosCommunity/chart.php create mode 100644 workflow/engine/plugins/pmosCommunity/class.pmosCommunity.php create mode 100644 workflow/engine/plugins/pmosCommunity/config/databases.php create mode 100644 workflow/engine/plugins/pmosCommunity/config/setup.conf create mode 100644 workflow/engine/plugins/pmosCommunity/drawChart.php create mode 100644 workflow/engine/plugins/pmosCommunity/open-flash-chart.php create mode 100644 workflow/engine/plugins/pmosCommunity/open_flash_chart_object.php create mode 100644 workflow/engine/plugins/pmosCommunity/public_html/open-flash-chart.swf create mode 100644 workflow/engine/plugins/pmosCommunity/public_html/swfobject.js create mode 100644 workflow/engine/plugins/pmosCommunity/setupPage.xml create mode 100644 workflow/engine/plugins/processTemplate.php create mode 100644 workflow/engine/plugins/processTemplate/class.processTemplate.php create mode 100644 workflow/engine/skins/blank.html create mode 100644 workflow/engine/skins/blank.php create mode 100755 workflow/engine/skins/extJs.html create mode 100755 workflow/engine/skins/extJs.php create mode 100644 workflow/engine/skins/extJsInitLoad.html create mode 100755 workflow/engine/skins/green-submenu.html create mode 100755 workflow/engine/skins/green-submenu.php create mode 100644 workflow/engine/skins/green.html create mode 100644 workflow/engine/skins/green.php create mode 100755 workflow/engine/skins/iphone.html create mode 100755 workflow/engine/skins/iphone.php create mode 100644 workflow/engine/skins/raw.html create mode 100644 workflow/engine/skins/raw.php create mode 100644 workflow/engine/skins/rtl.cnf create mode 100644 workflow/engine/skins/rtl.html create mode 100644 workflow/engine/skins/rtl.php create mode 100644 workflow/engine/skins/tracker.html create mode 100644 workflow/engine/skins/tracker.php create mode 100644 workflow/engine/templates/additionalTables/Table.tpl create mode 100644 workflow/engine/templates/additionalTables/TablePeer.tpl create mode 100644 workflow/engine/templates/additionalTables/map/TableMapBuilder.tpl create mode 100644 workflow/engine/templates/additionalTables/om/BaseTable.tpl create mode 100644 workflow/engine/templates/additionalTables/om/BaseTablePeer.tpl create mode 100755 workflow/engine/templates/additionalTables/paged-table.html create mode 100755 workflow/engine/templates/additionalTables/paged-table2.html create mode 100755 workflow/engine/templates/appFolder/appFolderFileList.html create mode 100755 workflow/engine/templates/appFolder/appFolderTree.php create mode 100644 workflow/engine/templates/authListUsers.html create mode 100644 workflow/engine/templates/cases/casesDemo.html create mode 100755 workflow/engine/templates/cases/casesList.js create mode 100755 workflow/engine/templates/cases/casesListExtJs.html create mode 100644 workflow/engine/templates/cases/casesStartPage.html create mode 100644 workflow/engine/templates/cases/casesStartPage.js create mode 100644 workflow/engine/templates/cases/casesToRevisePanel.html create mode 100644 workflow/engine/templates/cases/casesToRevisePanel.js create mode 100644 workflow/engine/templates/cases/cases_ActionsTree.php create mode 100644 workflow/engine/templates/cases/cases_DynaformHistory.html create mode 100644 workflow/engine/templates/cases/cases_DynaformHistory.php create mode 100644 workflow/engine/templates/cases/cases_InformationTree.php create mode 100644 workflow/engine/templates/cases/cases_KTTree.php create mode 100644 workflow/engine/templates/cases/cases_Leyends.html create mode 100755 workflow/engine/templates/cases/cases_Load.php create mode 100755 workflow/engine/templates/cases/cases_NewCategory.html create mode 100755 workflow/engine/templates/cases/cases_NewCategory.php create mode 100644 workflow/engine/templates/cases/cases_PrintViewTitle.html create mode 100644 workflow/engine/templates/cases/cases_Reassign.html create mode 100644 workflow/engine/templates/cases/cases_ScreenDerivation.html create mode 100644 workflow/engine/templates/cases/cases_Step.html create mode 100644 workflow/engine/templates/cases/cases_StepsTree.php create mode 100644 workflow/engine/templates/cases/cases_UsersReassignCases.html create mode 100644 workflow/engine/templates/cases/cases_title.html create mode 100644 workflow/engine/templates/cases/cases_toRevise.php create mode 100644 workflow/engine/templates/cases/cases_toReviseIn.html create mode 100755 workflow/engine/templates/cases/css/extjs-extend/xtheme-gray.css create mode 100755 workflow/engine/templates/cases/main.html create mode 100755 workflow/engine/templates/cases/main.js create mode 100644 workflow/engine/templates/cases/missRequiredFields.php create mode 100755 workflow/engine/templates/cases/paged-table-inputDocuments.html create mode 100755 workflow/engine/templates/cases/paged-table-reassigByUser.html create mode 100755 workflow/engine/templates/cases/paged-table-reassigByUser2.html create mode 100644 workflow/engine/templates/cases/paged-table-reassign.html create mode 100644 workflow/engine/templates/cases/reassignList.js create mode 100644 workflow/engine/templates/cases/showDebugFrame.php create mode 100644 workflow/engine/templates/cases/showDebugFrameBreaker.php create mode 100644 workflow/engine/templates/cases/showDebugFrameLoader.php create mode 100644 workflow/engine/templates/cases/showStep.html create mode 100755 workflow/engine/templates/dashboard/frontend.html create mode 100644 workflow/engine/templates/dbConnections/dbConnections.php create mode 100644 workflow/engine/templates/departments/departments_Tree.html create mode 100644 workflow/engine/templates/departments/departments_Tree.php create mode 100644 workflow/engine/templates/departments/departments_userList.html create mode 100644 workflow/engine/templates/departments/paged-table.html create mode 100644 workflow/engine/templates/departments/paged-table2.html create mode 100755 workflow/engine/templates/departments/paged-table3.html create mode 100755 workflow/engine/templates/dummyTemplate.html create mode 100755 workflow/engine/templates/dynaforms/fieldsHandler.php create mode 100755 workflow/engine/templates/dynaforms/fieldsHandlerViewer.php create mode 100644 workflow/engine/templates/events/sendMessage.tpl create mode 100644 workflow/engine/templates/filterform.html create mode 100644 workflow/engine/templates/form.html create mode 100644 workflow/engine/templates/grid.html create mode 100755 workflow/engine/templates/grid_preview.html create mode 100755 workflow/engine/templates/grid_view.html create mode 100644 workflow/engine/templates/groups/groups_Tree.php create mode 100644 workflow/engine/templates/groups/groups_usersList.html create mode 100755 workflow/engine/templates/groups/paged-table.html create mode 100755 workflow/engine/templates/groups/paged-table2.html create mode 100644 workflow/engine/templates/image.php create mode 100755 workflow/engine/templates/javaBridgePM/classic.xml create mode 100644 workflow/engine/templates/javaBridgePM/out.jrxml create mode 100644 workflow/engine/templates/login/init.js create mode 100644 workflow/engine/templates/login/showDBFiles.php create mode 100644 workflow/engine/templates/mails/alert_message.html create mode 100755 workflow/engine/templates/outputdocs/editJrxml.php create mode 100644 workflow/engine/templates/outputdocs/htmlEditor.js create mode 100644 workflow/engine/templates/packCreator/methods/packCreator_Delete.php create mode 100644 workflow/engine/templates/packCreator/methods/packCreator_Edit.php create mode 100644 workflow/engine/templates/packCreator/methods/packCreator_List.php create mode 100644 workflow/engine/templates/packCreator/methods/packCreator_Save.php create mode 100644 workflow/engine/templates/packCreator/xmlforms/packCreator_Edit.xml create mode 100644 workflow/engine/templates/packCreator/xmlforms/packCreator_List.xml create mode 100644 workflow/engine/templates/packCreator/xmlforms/packCreator_Options.xml create mode 100644 workflow/engine/templates/paged-table.html create mode 100644 workflow/engine/templates/popupMenu.html create mode 100755 workflow/engine/templates/processes/main.html create mode 100755 workflow/engine/templates/processes/main.js create mode 100755 workflow/engine/templates/processes/mainLoad.php create mode 100644 workflow/engine/templates/processes/processes_Map.html create mode 100644 workflow/engine/templates/processes/processes_Upload.php create mode 100644 workflow/engine/templates/processes/webentry.tpl create mode 100644 workflow/engine/templates/processes/webentryPost.tpl create mode 100644 workflow/engine/templates/publish-raw.php create mode 100644 workflow/engine/templates/publish-treeview.php create mode 100644 workflow/engine/templates/publish-twocolumns.php create mode 100644 workflow/engine/templates/publish.php create mode 100755 workflow/engine/templates/publishBlank.php create mode 100644 workflow/engine/templates/roles/roles_AssignPermissions.php create mode 100644 workflow/engine/templates/roles/roles_AssignRole.php create mode 100644 workflow/engine/templates/roles/roles_Tree.php create mode 100644 workflow/engine/templates/roles/roles_permissionsTree.php create mode 100644 workflow/engine/templates/services/login_getStarted.html create mode 100755 workflow/engine/templates/setup/appCacheViewConf.html create mode 100755 workflow/engine/templates/setup/appCacheViewConf.js create mode 100644 workflow/engine/templates/setup/clearCompiledResult.php create mode 100755 workflow/engine/templates/setup/css/extjs-extend/xtheme-gray.css create mode 100755 workflow/engine/templates/setup/environmentSettings.js create mode 100755 workflow/engine/templates/setup/languages.html create mode 100755 workflow/engine/templates/setup/languages.js create mode 100644 workflow/engine/templates/setup/mailConnectiontest.php create mode 100755 workflow/engine/templates/setup/main.html create mode 100755 workflow/engine/templates/setup/main.js create mode 100755 workflow/engine/templates/setup/main_Load.php create mode 100755 workflow/engine/templates/setup/pluginsMain.js create mode 100755 workflow/engine/templates/setup/tools.html create mode 100755 workflow/engine/templates/setup/uplogo.html create mode 100755 workflow/engine/templates/setup/uplogo.php create mode 100644 workflow/engine/templates/setup/webServicesTree.php create mode 100644 workflow/engine/templates/steps/triggers_Tree.php create mode 100644 workflow/engine/templates/testAuthenticationSource.html create mode 100644 workflow/engine/templates/testAuthenticationUser.php create mode 100644 workflow/engine/templates/toolbar.html create mode 100644 workflow/engine/templates/tools/methodsPermissions.php create mode 100644 workflow/engine/templates/tracker/stages_Map.html create mode 100644 workflow/engine/templates/tree.html create mode 100644 workflow/engine/templates/triggers/triggersTree.php create mode 100755 workflow/engine/templates/triggers/triggers_CreateWizard.html create mode 100755 workflow/engine/templates/triggers/triggers_CreateWizard.php create mode 100644 workflow/engine/templates/triggers/triggers_EditWizard.html create mode 100644 workflow/engine/templates/triggers/triggers_EditWizard.php create mode 100644 workflow/engine/templates/users/users_AssignGroup.php create mode 100644 workflow/engine/templates/users/users_DeleteReassign.html create mode 100644 workflow/engine/templates/users/users_ReassignCases.html create mode 100644 workflow/engine/templates/users/users_Tree.php create mode 100644 workflow/engine/templates/xmlform.html create mode 100644 workflow/engine/templates/xmlformScript.html create mode 100755 workflow/engine/templates/xmlform_preview.html create mode 100644 workflow/engine/templates/xmlmenu.html create mode 100644 workflow/engine/templates/xmlmenuDyn.html create mode 100644 workflow/engine/test/bootstrap/functional.php create mode 100644 workflow/engine/test/bootstrap/gulliverConstants.php create mode 100644 workflow/engine/test/bootstrap/unit.php create mode 100755 workflow/engine/test/fixtures/appDelegation.yml create mode 100644 workflow/engine/test/fixtures/appDocument.yml create mode 100644 workflow/engine/test/fixtures/application.yml create mode 100644 workflow/engine/test/fixtures/applicationInput.yml create mode 100755 workflow/engine/test/fixtures/configuration.yml create mode 100644 workflow/engine/test/fixtures/content.yml create mode 100644 workflow/engine/test/fixtures/departments.txt create mode 100644 workflow/engine/test/fixtures/derivation.yml create mode 100644 workflow/engine/test/fixtures/domain.yml create mode 100644 workflow/engine/test/fixtures/es.yml create mode 100644 workflow/engine/test/fixtures/firstname.txt create mode 100644 workflow/engine/test/fixtures/fixtures.yml create mode 100644 workflow/engine/test/fixtures/groupUser.yml create mode 100644 workflow/engine/test/fixtures/groups.txt create mode 100644 workflow/engine/test/fixtures/inputDocument.yml create mode 100644 workflow/engine/test/fixtures/lastname.txt create mode 100644 workflow/engine/test/fixtures/outputDocument.yml create mode 100644 workflow/engine/test/fixtures/processMap.yml create mode 100644 workflow/engine/test/fixtures/route.yml create mode 100755 workflow/engine/test/fixtures/step.yml create mode 100755 workflow/engine/test/fixtures/stepTrigger.yml create mode 100644 workflow/engine/test/fixtures/swimlanesElements.yml create mode 100755 workflow/engine/test/fixtures/task.yml create mode 100644 workflow/engine/test/fixtures/taskUser.yml create mode 100755 workflow/engine/test/fixtures/trigger.yml create mode 100755 workflow/engine/test/fixtures/user.yml create mode 100644 workflow/engine/test/unit/gulliver/classDBConnectionTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDBRecordsetTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDBSessionTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDBTableTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDatabase_baseTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDatabase_mysqlTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDvEditorTest.php create mode 100644 workflow/engine/test/unit/gulliver/classDynaformhandlerTest.php create mode 100644 workflow/engine/test/unit/gulliver/classErrorTest.php create mode 100644 workflow/engine/test/unit/gulliver/classFckEditorTest.php create mode 100644 workflow/engine/test/unit/gulliver/classFilterFormTest.php create mode 100644 workflow/engine/test/unit/gulliver/classFormTest.php create mode 100644 workflow/engine/test/unit/gulliver/classGTest.php create mode 100644 workflow/engine/test/unit/gulliver/classHeadPublisherTest.php create mode 100644 workflow/engine/test/unit/gulliver/classHtmlAreaTest.php create mode 100644 workflow/engine/test/unit/gulliver/classMailerTest.php create mode 100644 workflow/engine/test/unit/gulliver/classMenuTest.php create mode 100644 workflow/engine/test/unit/gulliver/classObjectTemplateTest.php create mode 100644 workflow/engine/test/unit/gulliver/classPagedTableTest.php create mode 100644 workflow/engine/test/unit/gulliver/classPublisherTest.php create mode 100644 workflow/engine/test/unit/gulliver/classRbacTest.php create mode 100644 workflow/engine/test/unit/gulliver/classTableTest.php create mode 100644 workflow/engine/test/unit/gulliver/classTemplatePowerTest.php create mode 100644 workflow/engine/test/unit/gulliver/classTestToolsTest.php create mode 100644 workflow/engine/test/unit/gulliver/classTreeTest.php create mode 100644 workflow/engine/test/unit/gulliver/classWebResourceTest.php create mode 100644 workflow/engine/test/unit/gulliver/classXmlDocumentTest.php create mode 100644 workflow/engine/test/unit/gulliver/classXmlMenuTest.php create mode 100644 workflow/engine/test/unit/gulliver/classXmlformExtensionTest.php create mode 100644 workflow/engine/test/unit/gulliver/classXmlformTest.php create mode 100644 workflow/engine/test/unit/processmaker/classAppDelegationTest.php create mode 100644 workflow/engine/test/unit/processmaker/classAppDocumentTest.php create mode 100644 workflow/engine/test/unit/processmaker/classApplicationTest.php create mode 100644 workflow/engine/test/unit/processmaker/classArchiveTest.php create mode 100644 workflow/engine/test/unit/processmaker/classArrayBasePeerTest.php create mode 100644 workflow/engine/test/unit/processmaker/classBasePeerTest.php create mode 100644 workflow/engine/test/unit/processmaker/classCasesTest.php create mode 100644 workflow/engine/test/unit/processmaker/classConfigurationTest.php create mode 100644 workflow/engine/test/unit/processmaker/classContentTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDashboardsTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDatesTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDbConnectionsTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDerivationTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDynaFormFieldTest.php create mode 100644 workflow/engine/test/unit/processmaker/classDynaformTest.php create mode 100644 workflow/engine/test/unit/processmaker/classESMTPTest.php create mode 100644 workflow/engine/test/unit/processmaker/classGroupTest.php create mode 100644 workflow/engine/test/unit/processmaker/classGroupUserTest.php create mode 100644 workflow/engine/test/unit/processmaker/classGroupsTest.php create mode 100644 workflow/engine/test/unit/processmaker/classInputDocumentTest.php create mode 100644 workflow/engine/test/unit/processmaker/classInsertTest.php create mode 100644 workflow/engine/test/unit/processmaker/classInstallerTest.php create mode 100644 workflow/engine/test/unit/processmaker/classJavaBridgePMTest.php create mode 100644 workflow/engine/test/unit/processmaker/classJrmlTest.php create mode 100644 workflow/engine/test/unit/processmaker/classLanguagesTest.php create mode 100644 workflow/engine/test/unit/processmaker/classMenuDetailTest.php create mode 100644 workflow/engine/test/unit/processmaker/classNetTest.php create mode 100644 workflow/engine/test/unit/processmaker/classOutputDocumentTest.php create mode 100644 workflow/engine/test/unit/processmaker/classPackageTest.php create mode 100644 workflow/engine/test/unit/processmaker/classPluginDetailTest.php create mode 100644 workflow/engine/test/unit/processmaker/classPmScriptTest.php create mode 100644 workflow/engine/test/unit/processmaker/classPopupMenuTest.php create mode 100644 workflow/engine/test/unit/processmaker/classProcessMakerWebDavTest.php create mode 100644 workflow/engine/test/unit/processmaker/classProcessMapTest.php create mode 100644 workflow/engine/test/unit/processmaker/classProcessTest.php create mode 100644 workflow/engine/test/unit/processmaker/classProcessesTest.php create mode 100644 workflow/engine/test/unit/processmaker/classPropelTableTest.php create mode 100644 workflow/engine/test/unit/processmaker/classReportTablesTest.php create mode 100644 workflow/engine/test/unit/processmaker/classReportTest.php create mode 100644 workflow/engine/test/unit/processmaker/classRouteTest.php create mode 100644 workflow/engine/test/unit/processmaker/classSessionsTest.php create mode 100644 workflow/engine/test/unit/processmaker/classSmtpTest.php create mode 100644 workflow/engine/test/unit/processmaker/classSpoolRunTest.php create mode 100755 workflow/engine/test/unit/processmaker/classStepTest.php create mode 100644 workflow/engine/test/unit/processmaker/classStepTriggerTest.php create mode 100644 workflow/engine/test/unit/processmaker/classSwimlanesElementsTest.php create mode 100644 workflow/engine/test/unit/processmaker/classTaskTest.php create mode 100644 workflow/engine/test/unit/processmaker/classTaskUserTest.php create mode 100644 workflow/engine/test/unit/processmaker/classToolBarTest.php create mode 100644 workflow/engine/test/unit/processmaker/classTranslationTest.php create mode 100644 workflow/engine/test/unit/processmaker/classTriggerTest.php create mode 100644 workflow/engine/test/unit/processmaker/classUserTest.php create mode 100644 workflow/engine/test/unit/processmaker/classWsBaseTest.php create mode 100644 workflow/engine/test/unit/processmaker/classWsResponseTest.php create mode 100644 workflow/engine/test/unit/processmaker/classXmlDbTest.php create mode 100644 workflow/engine/test/unit/processmaker/classXmlForm_Field_ImageTest.php create mode 100644 workflow/engine/test/unit/processmaker/classXmlForm_Field_TextPMTest.php create mode 100644 workflow/engine/test/unit/ws/EvaluationDerivationTest.php create mode 100644 workflow/engine/test/unit/ws/OtherMethodsTest.php create mode 100644 workflow/engine/test/unit/ws/ParallelDerivation2Test.php create mode 100644 workflow/engine/test/unit/ws/ParallelDerivationTest.php create mode 100644 workflow/engine/test/unit/ws/ProcessWithSubprocess.php create mode 100755 workflow/engine/test/unit/ws/SelectionDerivationTest.php create mode 100644 workflow/engine/test/unit/ws/SequentialDerivationTest.php create mode 100644 workflow/engine/test/unit/ws/SubprocessTest.php create mode 100644 workflow/engine/test/unit/ws/basicMethodsTest.php create mode 100644 workflow/engine/test/unit/ws/bugRelease09Test.php create mode 100755 workflow/engine/test/unit/ws/reportsToTest.php create mode 100644 workflow/engine/test/unit/ws/wsClient.php create mode 100644 workflow/engine/test/unit/ws/wsConfig.php.example create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesData.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.html create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesEdit.html create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesEdit.xml create mode 100755 workflow/engine/xmlform/additionalTables/additionalTablesExportList.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesFields.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesFields2.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesList.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesNew.html create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesNew.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesOptions.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesTitle.xml create mode 100644 workflow/engine/xmlform/additionalTables/additionalTablesToImport.html create mode 100755 workflow/engine/xmlform/additionalTables/additionalTablesToImport.xml create mode 100755 workflow/engine/xmlform/additionalTables/doExport.xml create mode 100644 workflow/engine/xmlform/appFolder/appFolder.xml create mode 100644 workflow/engine/xmlform/appFolder/appFolderDelete.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocsListOptions.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocsListSearchOptions.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocumentInfo.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocumentList.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocumentListHeader.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocumentListHistory.xml create mode 100755 workflow/engine/xmlform/appFolder/appFolderDocumentListSearch.xml create mode 100644 workflow/engine/xmlform/appFolder/appFolderEdit.html create mode 100644 workflow/engine/xmlform/appFolder/appFolderEdit.xml create mode 100644 workflow/engine/xmlform/appFolder/appFolderList.xml create mode 100644 workflow/engine/xmlform/appFolder/appFolderOptions.xml create mode 100644 workflow/engine/xmlform/authSources/authSources_List.xml create mode 100644 workflow/engine/xmlform/authSources/authSources_Options.xml create mode 100644 workflow/engine/xmlform/authSources/authSources_SearchUsers.html create mode 100644 workflow/engine/xmlform/authSources/authSources_SearchUsers.xml create mode 100644 workflow/engine/xmlform/authSources/authSources_SelectType.html create mode 100644 workflow/engine/xmlform/authSources/authSources_SelectType.xml create mode 100644 workflow/engine/xmlform/authSources/ldapEdit.html create mode 100644 workflow/engine/xmlform/authSources/ldapEdit.xml create mode 100644 workflow/engine/xmlform/authSources/ldapSearchResults.xml create mode 100644 workflow/engine/xmlform/cases/casesDemo.xml create mode 100644 workflow/engine/xmlform/cases/cases_AllDynaformsList.xml create mode 100644 workflow/engine/xmlform/cases/cases_AllInputdocsList.xml create mode 100644 workflow/engine/xmlform/cases/cases_AllOutputdocsList.xml create mode 100644 workflow/engine/xmlform/cases/cases_AttachInputDocument1.xml create mode 100644 workflow/engine/xmlform/cases/cases_AttachInputDocument2.xml create mode 100644 workflow/engine/xmlform/cases/cases_AttachInputDocument3.xml create mode 100644 workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.html create mode 100755 workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.xml create mode 100755 workflow/engine/xmlform/cases/cases_AttachInputDocumentInfo.xml create mode 100644 workflow/engine/xmlform/cases/cases_CannotInitiateCase.xml create mode 100644 workflow/engine/xmlform/cases/cases_CatchSelfService.html create mode 100644 workflow/engine/xmlform/cases/cases_CatchSelfService.xml create mode 100644 workflow/engine/xmlform/cases/cases_DynaformHistory.xml create mode 100644 workflow/engine/xmlform/cases/cases_InputdocsList.xml create mode 100644 workflow/engine/xmlform/cases/cases_InputdocsListHistory.xml create mode 100755 workflow/engine/xmlform/cases/cases_InputdocsListOptions.xml create mode 100644 workflow/engine/xmlform/cases/cases_InputdocsListToRevise.xml create mode 100644 workflow/engine/xmlform/cases/cases_List.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListAll.xml create mode 100644 workflow/engine/xmlform/cases/cases_ListAllDelete.xml create mode 100644 workflow/engine/xmlform/cases/cases_ListAll_Reassign.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListCancelled.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListCompleted.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListDraft.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListOnHold.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListSelfService.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListSent.xml create mode 100644 workflow/engine/xmlform/cases/cases_ListStarted.xml create mode 100644 workflow/engine/xmlform/cases/cases_ListToRevise.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListTodo.xml create mode 100755 workflow/engine/xmlform/cases/cases_ListTodoNew.xml create mode 100644 workflow/engine/xmlform/cases/cases_Messages.xml create mode 100644 workflow/engine/xmlform/cases/cases_MessagesView.xml create mode 100755 workflow/engine/xmlform/cases/cases_New.html create mode 100644 workflow/engine/xmlform/cases/cases_New.xml create mode 100755 workflow/engine/xmlform/cases/cases_NewRadioGroup.html create mode 100644 workflow/engine/xmlform/cases/cases_NewRadioGroup.xml create mode 100644 workflow/engine/xmlform/cases/cases_Options.xml create mode 100755 workflow/engine/xmlform/cases/cases_OptionsSent.xml create mode 100755 workflow/engine/xmlform/cases/cases_OptionsToDo.xml create mode 100644 workflow/engine/xmlform/cases/cases_OutputdocsListToRevise.xml create mode 100644 workflow/engine/xmlform/cases/cases_ProcessInformation.xml create mode 100644 workflow/engine/xmlform/cases/cases_Reassign.xml create mode 100755 workflow/engine/xmlform/cases/cases_ReassignBy.html create mode 100644 workflow/engine/xmlform/cases/cases_ReassignBy.xml create mode 100644 workflow/engine/xmlform/cases/cases_ReassignShowInfo.xml create mode 100644 workflow/engine/xmlform/cases/cases_ReassignUsers.xml create mode 100644 workflow/engine/xmlform/cases/cases_Resume.xml create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_Edit.html create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_Edit.xml create mode 100755 workflow/engine/xmlform/cases/cases_Scheduler_List.xml create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_Log.xml create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_Log_Detail.xml create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_New.html create mode 100644 workflow/engine/xmlform/cases/cases_Scheduler_New.xml create mode 100755 workflow/engine/xmlform/cases/cases_Scheduler_NewOptions.xml create mode 100755 workflow/engine/xmlform/cases/cases_Scheduler_Options.xml create mode 100644 workflow/engine/xmlform/cases/cases_TaskDetails.xml create mode 100644 workflow/engine/xmlform/cases/cases_TaskInformation.xml create mode 100755 workflow/engine/xmlform/cases/cases_ToReassignByUserList.xml create mode 100755 workflow/engine/xmlform/cases/cases_ToReassignByUserList2.xml create mode 100644 workflow/engine/xmlform/cases/cases_ToReviseInputdocsList.xml create mode 100644 workflow/engine/xmlform/cases/cases_ToReviseInputdocsListOptions.xml create mode 100755 workflow/engine/xmlform/cases/cases_TransferHistory.xml create mode 100755 workflow/engine/xmlform/cases/cases_UnpauseDateInput.html create mode 100644 workflow/engine/xmlform/cases/cases_UnpauseDateInput.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewAnyInputDocument.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewAnyInputDocument1.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewAnyInputDocument2.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewAnyInputDocument3.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewAnyOutputDocument.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewInputDocument1.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewInputDocument2.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewInputDocument3.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewInputDocumentToRevise.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewOutputDocument1.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewOutputDocument2.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewOutputDocument3.xml create mode 100644 workflow/engine/xmlform/cases/cases_ViewOutputDocumentToRevise.xml create mode 100644 workflow/engine/xmlform/cases/cases_advancedSearch.xml create mode 100644 workflow/engine/xmlform/cases/cases_advancedSearchFilter.html create mode 100644 workflow/engine/xmlform/cases/cases_advancedSearchFilter.xml create mode 100644 workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.html create mode 100644 workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.xml create mode 100644 workflow/engine/xmlform/dashboard/dashboard_NoAvailableDashboards.xml create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections.xml create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections_Edit.html create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections_Edit.xml create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections_New.html create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections_New.xml create mode 100644 workflow/engine/xmlform/dbConnections/dbConnections_Options.xml create mode 100755 workflow/engine/xmlform/departments/departments_AddUnAssignedUsers.xml create mode 100644 workflow/engine/xmlform/departments/departments_AvailableUsers.xml create mode 100644 workflow/engine/xmlform/departments/departments_Edit.html create mode 100644 workflow/engine/xmlform/departments/departments_Edit.xml create mode 100644 workflow/engine/xmlform/departments/departments_New.html create mode 100644 workflow/engine/xmlform/departments/departments_New.xml create mode 100644 workflow/engine/xmlform/departments/departments_Options.xml create mode 100644 workflow/engine/xmlform/departments/departments_SubNew.html create mode 100755 workflow/engine/xmlform/departments/departments_SubNew.xml create mode 100644 workflow/engine/xmlform/departments/departments_UsersList.xml create mode 100755 workflow/engine/xmlform/dynaforms/datemask.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaform_Fields.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_AssignVariablesGrid.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_AvailableSupervisorDynaforms.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.html create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideList.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideOptions.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.html create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTestGrid.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Edit.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Edit.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Editor.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Editor.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_JSEditor.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_List.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Options.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Properties.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Saveas.html create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Saveas.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_ShortList.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Supervisor.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_SupervisorOptions.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_Toolbar.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_WebEntry.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_WebEntryList.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_WebEntryOptions.xml create mode 100644 workflow/engine/xmlform/dynaforms/dynaforms_XmlEditor.xml create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_vars.html create mode 100755 workflow/engine/xmlform/dynaforms/dynaforms_vars.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/_options.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/button.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/button.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/checkbox.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/checkbox.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/checkgroup.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/checkgroup.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/currency.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/currency.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/date.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/date.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/dropdown.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/dropdown.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/file.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/file.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/grid.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/grid.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/hidden.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/hidden.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/javascript.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/javascript.xml create mode 100755 workflow/engine/xmlform/dynaforms/fields/link.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/link.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/listbox.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/listbox.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/password.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/password.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/percentage.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/percentage.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/radiogroup.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/radiogroup.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/radiogroupview.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/reset.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/reset.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/submit.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/submit.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/subtitle.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/subtitle.xml create mode 100755 workflow/engine/xmlform/dynaforms/fields/suggest.html create mode 100755 workflow/engine/xmlform/dynaforms/fields/suggest.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/text.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/text.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/textarea.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/textarea.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/title.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/title.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields/yesno.html create mode 100644 workflow/engine/xmlform/dynaforms/fields/yesno.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_Edit.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_List.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_Options.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_ShortList.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_Toolbar.xml create mode 100644 workflow/engine/xmlform/dynaforms/fields_ToolbarGrid.xml create mode 100644 workflow/engine/xmlform/events/appEventsList.xml create mode 100644 workflow/engine/xmlform/events/appEventsListCompleted.xml create mode 100755 workflow/engine/xmlform/events/dynavarsList.xml create mode 100644 workflow/engine/xmlform/events/eventsEdit.html create mode 100644 workflow/engine/xmlform/events/eventsEdit.xml create mode 100755 workflow/engine/xmlform/events/eventsEditAction.html create mode 100644 workflow/engine/xmlform/events/eventsEditAction.xml create mode 100644 workflow/engine/xmlform/events/eventsNew.html create mode 100644 workflow/engine/xmlform/events/eventsNew.xml create mode 100644 workflow/engine/xmlform/events/eventsOptions.xml create mode 100644 workflow/engine/xmlform/events/eventsShortList.xml create mode 100755 workflow/engine/xmlform/events/groupmailList.xml create mode 100755 workflow/engine/xmlform/events/usermailList.xml create mode 100644 workflow/engine/xmlform/groups/groups_AddUser.xml create mode 100644 workflow/engine/xmlform/groups/groups_AvailableUsers.xml create mode 100644 workflow/engine/xmlform/groups/groups_Edit.html create mode 100644 workflow/engine/xmlform/groups/groups_Edit.xml create mode 100644 workflow/engine/xmlform/groups/groups_List.xml create mode 100644 workflow/engine/xmlform/groups/groups_Options.xml create mode 100644 workflow/engine/xmlform/groups/groups_Search.xml create mode 100644 workflow/engine/xmlform/groups/groups_SelectUsers.xml create mode 100644 workflow/engine/xmlform/groups/groups_UsersList.xml create mode 100644 workflow/engine/xmlform/groups/groups_UsersListTitle.xml create mode 100644 workflow/engine/xmlform/groups/groups_userSearch.xml create mode 100644 workflow/engine/xmlform/gulliver/dynaforms_Options.xml create mode 100755 workflow/engine/xmlform/gulliver/dynaforms_OptionsPrint.xml create mode 100644 workflow/engine/xmlform/gulliver/pagedTable_Options.xml create mode 100644 workflow/engine/xmlform/gulliver/pagedTable_PopupMenu.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_AvailableSupervisorInputs.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_Edit.html create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_Edit.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_List.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_Options.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_ShortList.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_Supervisor.xml create mode 100644 workflow/engine/xmlform/inputdocs/inputdocs_SupervisorOptions.xml create mode 100644 workflow/engine/xmlform/login/changePassword.xml create mode 100644 workflow/engine/xmlform/login/dbInfo.xml create mode 100644 workflow/engine/xmlform/login/login.xml create mode 100644 workflow/engine/xmlform/login/newSite.xml create mode 100644 workflow/engine/xmlform/login/noViewPage.xml create mode 100644 workflow/engine/xmlform/login/nologin.xml create mode 100755 workflow/engine/xmlform/login/showInfo.xml create mode 100644 workflow/engine/xmlform/login/showInfoUpdate.xml create mode 100644 workflow/engine/xmlform/login/showMessage.xml create mode 100644 workflow/engine/xmlform/login/sysLogin.xml create mode 100644 workflow/engine/xmlform/login/sysLoginNoWS.xml create mode 100644 workflow/engine/xmlform/messages/messages_Edit.xml create mode 100644 workflow/engine/xmlform/messages/messages_List.xml create mode 100644 workflow/engine/xmlform/messages/messages_Options.xml create mode 100644 workflow/engine/xmlform/messages/messages_ShortList.xml create mode 100755 workflow/engine/xmlform/outputdocs/outputdocsDynaformList.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocsUploadFile.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_Edit.html create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_Edit.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_List.xml create mode 100755 workflow/engine/xmlform/outputdocs/outputdocs_New.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_Options.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_Properties.html create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_Properties.xml create mode 100644 workflow/engine/xmlform/outputdocs/outputdocs_ShortList.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_Current.html create mode 100644 workflow/engine/xmlform/patterns/patterns_Current.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_Evaluate.html create mode 100644 workflow/engine/xmlform/patterns/patterns_Evaluate.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_GridEvaluateType.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_GridParallelByEvaluationType.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_GridParallelType.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_GridSelectType.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_Parallel.html create mode 100644 workflow/engine/xmlform/patterns/patterns_Parallel.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.html create mode 100644 workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_ParallelJoin.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_Select.html create mode 100644 workflow/engine/xmlform/patterns/patterns_Select.xml create mode 100644 workflow/engine/xmlform/patterns/patterns_Sequential.html create mode 100644 workflow/engine/xmlform/patterns/patterns_Sequential.xml create mode 100755 workflow/engine/xmlform/processCategory/processCategory.xml create mode 100644 workflow/engine/xmlform/processCategory/processCategoryDelete.html create mode 100755 workflow/engine/xmlform/processCategory/processCategoryDelete.xml create mode 100644 workflow/engine/xmlform/processCategory/processCategoryEdit.html create mode 100755 workflow/engine/xmlform/processCategory/processCategoryEdit.xml create mode 100755 workflow/engine/xmlform/processCategory/processCategoryList.xml create mode 100755 workflow/engine/xmlform/processCategory/processCategoryOptions.xml create mode 100644 workflow/engine/xmlform/processes/objectpmView.xml create mode 100644 workflow/engine/xmlform/processes/processes_Assignuser.xml create mode 100644 workflow/engine/xmlform/processes/processes_DeleteCases.xml create mode 100644 workflow/engine/xmlform/processes/processes_DirectoriesList.xml create mode 100644 workflow/engine/xmlform/processes/processes_DirectoriesOptions.xml create mode 100644 workflow/engine/xmlform/processes/processes_Edit.html create mode 100644 workflow/engine/xmlform/processes/processes_Edit.xml create mode 100644 workflow/engine/xmlform/processes/processes_EditObjectPermission.xml create mode 100644 workflow/engine/xmlform/processes/processes_Export.xml create mode 100755 workflow/engine/xmlform/processes/processes_FileEdit.html create mode 100755 workflow/engine/xmlform/processes/processes_FileEdit.xml create mode 100755 workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.html create mode 100755 workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.xml create mode 100644 workflow/engine/xmlform/processes/processes_FilesList.xml create mode 100644 workflow/engine/xmlform/processes/processes_FilesOptions.xml create mode 100644 workflow/engine/xmlform/processes/processes_Import.html create mode 100644 workflow/engine/xmlform/processes/processes_Import.xml create mode 100644 workflow/engine/xmlform/processes/processes_ImportExisting.html create mode 100644 workflow/engine/xmlform/processes/processes_ImportExisting.xml create mode 100644 workflow/engine/xmlform/processes/processes_ImportSucessful.xml create mode 100644 workflow/engine/xmlform/processes/processes_List.xml create mode 100644 workflow/engine/xmlform/processes/processes_ListPublic.xml create mode 100644 workflow/engine/xmlform/processes/processes_New.xml create mode 100644 workflow/engine/xmlform/processes/processes_NewObjectPermission.html create mode 100644 workflow/engine/xmlform/processes/processes_NewObjectPermission.xml create mode 100644 workflow/engine/xmlform/processes/processes_NewOptions.xml create mode 100644 workflow/engine/xmlform/processes/processes_NewSimple.html create mode 100644 workflow/engine/xmlform/processes/processes_NewSimple.xml create mode 100644 workflow/engine/xmlform/processes/processes_ObjectsPermissionsList.xml create mode 100644 workflow/engine/xmlform/processes/processes_ObjectsPermissionsOptions.xml create mode 100644 workflow/engine/xmlform/processes/processes_Options.xml create mode 100644 workflow/engine/xmlform/processes/processes_Properties.xml create mode 100644 workflow/engine/xmlform/processes/processes_Search.xml create mode 100644 workflow/engine/xmlform/processes/processes_UploadFilesForm.xml create mode 100644 workflow/engine/xmlform/processes/processes_User.xml create mode 100644 workflow/engine/xmlform/processes/processes_ValidatingGroups.xml create mode 100644 workflow/engine/xmlform/processes/processes_View.xml create mode 100644 workflow/engine/xmlform/processes/processes_ViewOptions.xml create mode 100644 workflow/engine/xmlform/processes/processes_availableProcessesUser.xml create mode 100644 workflow/engine/xmlform/processes/processes_subProcess.html create mode 100644 workflow/engine/xmlform/processes/processes_subProcess.xml create mode 100644 workflow/engine/xmlform/processes/processes_subProcess_In.xml create mode 100644 workflow/engine/xmlform/processes/processes_subProcess_Out.xml create mode 100644 workflow/engine/xmlform/processes/processes_viewreassignCase.xml create mode 100644 workflow/engine/xmlform/processes/registerPML.html create mode 100644 workflow/engine/xmlform/processes/registerPML.xml create mode 100644 workflow/engine/xmlform/reportTables/reportTables_Edit.html create mode 100644 workflow/engine/xmlform/reportTables/reportTables_Edit.xml create mode 100644 workflow/engine/xmlform/reportTables/reportTables_Options.xml create mode 100644 workflow/engine/xmlform/reportTables/reportTables_ShortList.xml create mode 100644 workflow/engine/xmlform/reports/report1.xml create mode 100644 workflow/engine/xmlform/reports/report1_back.xml create mode 100644 workflow/engine/xmlform/reports/report1_dashboard.xml create mode 100644 workflow/engine/xmlform/reports/report1_search.html create mode 100644 workflow/engine/xmlform/reports/report1_search.xml create mode 100644 workflow/engine/xmlform/reports/report2.xml create mode 100644 workflow/engine/xmlform/reports/report2_dashboard.xml create mode 100644 workflow/engine/xmlform/reports/report3.xml create mode 100644 workflow/engine/xmlform/reports/report3_dashboard.xml create mode 100644 workflow/engine/xmlform/reports/report4.xml create mode 100644 workflow/engine/xmlform/reports/report4_dashboard.xml create mode 100644 workflow/engine/xmlform/reports/report5.xml create mode 100644 workflow/engine/xmlform/reports/report5_dashboard.xml create mode 100644 workflow/engine/xmlform/reports/report_filter.xml create mode 100644 workflow/engine/xmlform/reports/reportsList.xml create mode 100644 workflow/engine/xmlform/reports/reports_Description.xml create mode 100644 workflow/engine/xmlform/reports/reports_Description_search.xml create mode 100644 workflow/engine/xmlform/reports/rpt_filters.xml create mode 100644 workflow/engine/xmlform/roles/roles_Edit.html create mode 100644 workflow/engine/xmlform/roles/roles_Edit.xml create mode 100644 workflow/engine/xmlform/roles/roles_List.xml create mode 100644 workflow/engine/xmlform/roles/roles_New.html create mode 100644 workflow/engine/xmlform/roles/roles_New.xml create mode 100644 workflow/engine/xmlform/roles/roles_Options.xml create mode 100644 workflow/engine/xmlform/setup/calendarEdit.html create mode 100644 workflow/engine/xmlform/setup/calendarEdit.xml create mode 100644 workflow/engine/xmlform/setup/calendarEdit_BusinessHours.xml create mode 100644 workflow/engine/xmlform/setup/calendarEdit_Holidays.xml create mode 100644 workflow/engine/xmlform/setup/calendarList.xml create mode 100644 workflow/engine/xmlform/setup/calendarList_Options.xml create mode 100644 workflow/engine/xmlform/setup/emailSetupTest.xml create mode 100644 workflow/engine/xmlform/setup/emails.html create mode 100644 workflow/engine/xmlform/setup/emails.xml create mode 100644 workflow/engine/xmlform/setup/emails_Sended.xml create mode 100644 workflow/engine/xmlform/setup/emails_TestForm.xml create mode 100644 workflow/engine/xmlform/setup/holiday.xml create mode 100644 workflow/engine/xmlform/setup/holidayList.xml create mode 100644 workflow/engine/xmlform/setup/holidayListMenu.xml create mode 100644 workflow/engine/xmlform/setup/language.xml create mode 100644 workflow/engine/xmlform/setup/language_table.xml create mode 100644 workflow/engine/xmlform/setup/languages.xml create mode 100644 workflow/engine/xmlform/setup/languages_ImportForm.html create mode 100644 workflow/engine/xmlform/setup/languages_ImportForm.xml create mode 100644 workflow/engine/xmlform/setup/languages_Options.xml create mode 100644 workflow/engine/xmlform/setup/location.html create mode 100644 workflow/engine/xmlform/setup/location.xml create mode 100755 workflow/engine/xmlform/setup/logo_Option.xml create mode 100644 workflow/engine/xmlform/setup/mail.xml create mode 100644 workflow/engine/xmlform/setup/mailTest.xml create mode 100644 workflow/engine/xmlform/setup/noProcesses.xml create mode 100644 workflow/engine/xmlform/setup/pluginImport.html create mode 100644 workflow/engine/xmlform/setup/pluginImport.xml create mode 100644 workflow/engine/xmlform/setup/pluginList.xml create mode 100644 workflow/engine/xmlform/setup/plugin_ListOptions.xml create mode 100755 workflow/engine/xmlform/setup/processHeartBeatConfig.html create mode 100755 workflow/engine/xmlform/setup/processHeartBeatConfig.xml create mode 100755 workflow/engine/xmlform/setup/showMessage.xml create mode 100755 workflow/engine/xmlform/setup/skinsList.xml create mode 100755 workflow/engine/xmlform/setup/skinsListOptions.xml create mode 100644 workflow/engine/xmlform/setup/skinsNew.html create mode 100644 workflow/engine/xmlform/setup/skinsNew.xml create mode 100644 workflow/engine/xmlform/setup/upgrade.xml create mode 100755 workflow/engine/xmlform/setup/uplogo.xml create mode 100755 workflow/engine/xmlform/setup/uplogoList.xml create mode 100755 workflow/engine/xmlform/setup/webServicesDetails.xml create mode 100644 workflow/engine/xmlform/setup/webServicesSetup.html create mode 100644 workflow/engine/xmlform/setup/webServicesSetup.xml create mode 100644 workflow/engine/xmlform/setup/weekend.xml create mode 100644 workflow/engine/xmlform/setup/workPeriod.xml create mode 100644 workflow/engine/xmlform/setup/wsAssignUserToGroup.xml create mode 100644 workflow/engine/xmlform/setup/wsCaseList.xml create mode 100644 workflow/engine/xmlform/setup/wsCreateUser.xml create mode 100644 workflow/engine/xmlform/setup/wsDerivateCase.xml create mode 100644 workflow/engine/xmlform/setup/wsGroupList.xml create mode 100644 workflow/engine/xmlform/setup/wsInputDocumentList.xml create mode 100755 workflow/engine/xmlform/setup/wsInputDocumentProcessList.xml create mode 100644 workflow/engine/xmlform/setup/wsLogin.xml create mode 100644 workflow/engine/xmlform/setup/wsMessage.xml create mode 100644 workflow/engine/xmlform/setup/wsNewCase.xml create mode 100644 workflow/engine/xmlform/setup/wsNewCaseImpersonate.xml create mode 100644 workflow/engine/xmlform/setup/wsOutputDocumentList.xml create mode 100644 workflow/engine/xmlform/setup/wsProcessList.xml create mode 100644 workflow/engine/xmlform/setup/wsReassignCase.xml create mode 100755 workflow/engine/xmlform/setup/wsRemoveDocument.xml create mode 100644 workflow/engine/xmlform/setup/wsRoleList.xml create mode 100644 workflow/engine/xmlform/setup/wsSendFiles.xml create mode 100644 workflow/engine/xmlform/setup/wsSendMessage.xml create mode 100644 workflow/engine/xmlform/setup/wsSendVariables.xml create mode 100644 workflow/engine/xmlform/setup/wsShowResult.xml create mode 100644 workflow/engine/xmlform/setup/wsTaskCase.xml create mode 100644 workflow/engine/xmlform/setup/wsTaskList.xml create mode 100644 workflow/engine/xmlform/setup/wsTriggerList.xml create mode 100644 workflow/engine/xmlform/setup/wsUserList.xml create mode 100644 workflow/engine/xmlform/setup/wsVariablesGrid.xml create mode 100644 workflow/engine/xmlform/setup/wsrCaseList.xml create mode 100644 workflow/engine/xmlform/setup/wsrGroupList.xml create mode 100644 workflow/engine/xmlform/setup/wsrInputDocumentList.xml create mode 100755 workflow/engine/xmlform/setup/wsrInputDocumentProcessList.xml create mode 100644 workflow/engine/xmlform/setup/wsrOutputDocumentList.xml create mode 100644 workflow/engine/xmlform/setup/wsrProcessList.xml create mode 100644 workflow/engine/xmlform/setup/wsrRoleList.xml create mode 100644 workflow/engine/xmlform/setup/wsrTaskCase.xml create mode 100644 workflow/engine/xmlform/setup/wsrTaskList.xml create mode 100644 workflow/engine/xmlform/setup/wsrTriggerList.xml create mode 100644 workflow/engine/xmlform/setup/wsrUserList.xml create mode 100644 workflow/engine/xmlform/steps/conditions_Edit.xml create mode 100644 workflow/engine/xmlform/steps/conditions_List.xml create mode 100644 workflow/engine/xmlform/steps/conditions_Options.xml create mode 100644 workflow/engine/xmlform/steps/steps_List.xml create mode 100644 workflow/engine/xmlform/steps/steps_Options.xml create mode 100644 workflow/engine/xmlform/steps/steps_availableBB.xml create mode 100644 workflow/engine/xmlform/steps/triggersAfter_List.xml create mode 100644 workflow/engine/xmlform/steps/triggersAfter_Options.xml create mode 100644 workflow/engine/xmlform/steps/triggersBefore_List.xml create mode 100644 workflow/engine/xmlform/steps/triggersBefore_Options.xml create mode 100644 workflow/engine/xmlform/steps/triggersCondition_Edit.xml create mode 100644 workflow/engine/xmlform/steps/triggers_Assign.xml create mode 100644 workflow/engine/xmlform/steps/triggers_NoAssign.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_AssignmentRules.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_Definition.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_Labels.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_Notifications.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_Owner.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_Permissions.xml create mode 100644 workflow/engine/xmlform/tasks/tasks_TimingControl.xml create mode 100644 workflow/engine/xmlform/tools/translationAdd.xml create mode 100644 workflow/engine/xmlform/tools/translationsList.xml create mode 100644 workflow/engine/xmlform/tools/updateTranslation.xml create mode 100644 workflow/engine/xmlform/tracker/login.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_AvailableCaseTrackerObjects.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_AvailableStageTasks.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ConditionsEdit.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_Configuration.html create mode 100644 workflow/engine/xmlform/tracker/tracker_Configuration.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_DynaDocs.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_Inputdocs.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_Messages.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_MessagesView.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_No.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_Outputdocs.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_StageEdit.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_StageTasks.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_TasksOptions.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_TransferHistory.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument1.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument2.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument3.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_ViewAnyOutputDocument.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_back.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_objectsList.xml create mode 100644 workflow/engine/xmlform/tracker/tracker_objectsOptions.xml create mode 100755 workflow/engine/xmlform/triggers/dynavars.xml create mode 100644 workflow/engine/xmlform/triggers/triggersCustom.html create mode 100644 workflow/engine/xmlform/triggers/triggersCustom.xml create mode 100644 workflow/engine/xmlform/triggers/triggersNarrowEdit.html create mode 100644 workflow/engine/xmlform/triggers/triggersNarrowEdit.xml create mode 100644 workflow/engine/xmlform/triggers/triggersProperties.html create mode 100644 workflow/engine/xmlform/triggers/triggersProperties.xml create mode 100644 workflow/engine/xmlform/triggers/triggers_Edit.html create mode 100644 workflow/engine/xmlform/triggers/triggers_Edit.xml create mode 100644 workflow/engine/xmlform/triggers/triggers_Options.xml create mode 100644 workflow/engine/xmlform/triggers/triggers_ShortList.xml create mode 100755 workflow/engine/xmlform/triggers/wizardOptions.xml create mode 100644 workflow/engine/xmlform/users/myInfo.html create mode 100644 workflow/engine/xmlform/users/myInfo.xml create mode 100644 workflow/engine/xmlform/users/myInfo2.html create mode 100644 workflow/engine/xmlform/users/myInfo2.xml create mode 100644 workflow/engine/xmlform/users/myInfoOptions.xml create mode 100644 workflow/engine/xmlform/users/myInfoOptionsView.xml create mode 100644 workflow/engine/xmlform/users/myInfoView.html create mode 100644 workflow/engine/xmlform/users/myInfoView.xml create mode 100755 workflow/engine/xmlform/users/myInfoView2.html create mode 100755 workflow/engine/xmlform/users/myInfoView2.xml create mode 100644 workflow/engine/xmlform/users/users_AuthSource.html create mode 100644 workflow/engine/xmlform/users/users_AuthSource.xml create mode 100644 workflow/engine/xmlform/users/users_AvailableUsers.xml create mode 100644 workflow/engine/xmlform/users/users_DeleteAssign.xml create mode 100644 workflow/engine/xmlform/users/users_Edit.xml create mode 100644 workflow/engine/xmlform/users/users_EditAdmin.xml create mode 100644 workflow/engine/xmlform/users/users_EditOptions.xml create mode 100644 workflow/engine/xmlform/users/users_EditRT.html create mode 100755 workflow/engine/xmlform/users/users_EditRT.xml create mode 100644 workflow/engine/xmlform/users/users_List.xml create mode 100644 workflow/engine/xmlform/users/users_New.html create mode 100644 workflow/engine/xmlform/users/users_New.xml create mode 100644 workflow/engine/xmlform/users/users_NewOptions.xml create mode 100644 workflow/engine/xmlform/users/users_Options.xml create mode 100644 workflow/engine/xmlform/users/users_ReassignCases.xml create mode 100644 workflow/engine/xmlform/users/users_ReassignSelectSubType.html create mode 100644 workflow/engine/xmlform/users/users_ReassignSelectSubType.xml create mode 100644 workflow/engine/xmlform/users/users_ReassignSelectType.html create mode 100644 workflow/engine/xmlform/users/users_ReassignSelectType.xml create mode 100644 workflow/engine/xmlform/users/users_ReassignShowInfo.xml create mode 100644 workflow/engine/xmlform/users/users_Search.xml create mode 100644 workflow/engine/xmlform/users/users_Searchx.xml create mode 100644 workflow/engine/xmlform/users/users_ShortList.xml create mode 100644 workflow/engine/xmlform/users/users_ShortList2.xml create mode 100644 workflow/engine/xmlform/users/users_ShortListAdhoc.xml create mode 100644 workflow/engine/xmlform/users/users_ShortOptions.xml create mode 100644 workflow/engine/xmlform/users/users_ShortOptions2.xml create mode 100644 workflow/engine/xmlform/users/users_ShortOptionsAdhoc.xml create mode 100644 workflow/engine/xmlform/users/users_View.xml create mode 100644 workflow/engine/xmlform/users/users_ViewOptions.xml create mode 100755 workflow/public_html/images/1.png create mode 100755 workflow/public_html/images/2.png create mode 100755 workflow/public_html/images/3.png create mode 100755 workflow/public_html/images/4.png create mode 100644 workflow/public_html/images/50px-Edit.png create mode 100644 workflow/public_html/images/50px-Edit_over.png create mode 100644 workflow/public_html/images/Openreg.gif create mode 100644 workflow/public_html/images/PowerdbyProcessMaker.png create mode 100644 workflow/public_html/images/Refresh.png create mode 100644 workflow/public_html/images/activate.png create mode 100644 workflow/public_html/images/activity.gif create mode 100644 workflow/public_html/images/activityanimation.gif create mode 100644 workflow/public_html/images/add-user-32x32.png create mode 100755 workflow/public_html/images/add.png create mode 100644 workflow/public_html/images/addc.png create mode 100755 workflow/public_html/images/addtext.png create mode 100644 workflow/public_html/images/ajax-loader.gif create mode 100644 workflow/public_html/images/alert.gif create mode 100755 workflow/public_html/images/alert_icon.gif create mode 100644 workflow/public_html/images/app-delete-32x32.png create mode 100644 workflow/public_html/images/app-edit-32x32.png create mode 100644 workflow/public_html/images/arrow-down.gif create mode 100644 workflow/public_html/images/arrow-up.gif create mode 100644 workflow/public_html/images/arrow_order_asc.gif create mode 100644 workflow/public_html/images/arrow_order_desc.gif create mode 100644 workflow/public_html/images/back-24x24.png create mode 100755 workflow/public_html/images/bg_ctaTooltip.png create mode 100644 workflow/public_html/images/blueBackgroundMenu.jpg create mode 100644 workflow/public_html/images/borderTask.gif create mode 100644 workflow/public_html/images/browse.gif create mode 100644 workflow/public_html/images/btnGreen.gif create mode 100644 workflow/public_html/images/btnRed.gif create mode 100644 workflow/public_html/images/btnYellow.gif create mode 100644 workflow/public_html/images/bulletButton.gif create mode 100644 workflow/public_html/images/bulletButtonDown.gif create mode 100644 workflow/public_html/images/bulletButtonLeft.gif create mode 100644 workflow/public_html/images/bulletButtonUp.gif create mode 100644 workflow/public_html/images/bulletSubMenu.jpg create mode 100644 workflow/public_html/images/buttonBackground.png create mode 100644 workflow/public_html/images/calendar/cal.gif create mode 100755 workflow/public_html/images/calendar/calendar-close.gif create mode 100644 workflow/public_html/images/calendar/calendar-dropdown-down.gif create mode 100644 workflow/public_html/images/calendar/calendar-dropdown-up.gif create mode 100755 workflow/public_html/images/calendar/calendar-next-month.gif create mode 100755 workflow/public_html/images/calendar/calendar-next-year.gif create mode 100755 workflow/public_html/images/calendar/calendar-previous-month.gif create mode 100755 workflow/public_html/images/calendar/calendar-previous-year.gif create mode 100755 workflow/public_html/images/calendar/calendar_heading.png create mode 100644 workflow/public_html/images/calendar/next.gif create mode 100644 workflow/public_html/images/calendar/next_year.gif create mode 100644 workflow/public_html/images/calendar/pixel.gif create mode 100644 workflow/public_html/images/calendar/prev.gif create mode 100644 workflow/public_html/images/calendar/prev_year.gif create mode 100755 workflow/public_html/images/cases-admin.png create mode 100755 workflow/public_html/images/cases-cancelled.png create mode 100755 workflow/public_html/images/cases-completed1.png create mode 100755 workflow/public_html/images/cases-documents.png create mode 100755 workflow/public_html/images/cases-draft.png create mode 100755 workflow/public_html/images/cases-folders.png create mode 100755 workflow/public_html/images/cases-inbox.png create mode 100755 workflow/public_html/images/cases-outbox.png create mode 100755 workflow/public_html/images/cases-paused.png create mode 100755 workflow/public_html/images/cases-reassing.png create mode 100755 workflow/public_html/images/cases-search.png create mode 100755 workflow/public_html/images/cases-selfservice.png create mode 100755 workflow/public_html/images/cases_torevise.png create mode 100755 workflow/public_html/images/charts.swf create mode 100644 workflow/public_html/images/checked.gif create mode 100644 workflow/public_html/images/cinco.gif create mode 100644 workflow/public_html/images/closereg.gif create mode 100644 workflow/public_html/images/cross.gif create mode 100644 workflow/public_html/images/cuatro.gif create mode 100644 workflow/public_html/images/date.gif create mode 100644 workflow/public_html/images/deactivate.png create mode 100755 workflow/public_html/images/delete-16x16.gif create mode 100644 workflow/public_html/images/delete-icon.jpg create mode 100644 workflow/public_html/images/delete-icon.png create mode 100644 workflow/public_html/images/delete-user-32x32.png create mode 100755 workflow/public_html/images/delete.png create mode 100644 workflow/public_html/images/delete_rules.png create mode 100755 workflow/public_html/images/der.png create mode 100644 workflow/public_html/images/dialog-cancel.png create mode 100644 workflow/public_html/images/dialog-ok-apply.png create mode 100644 workflow/public_html/images/doc.gif create mode 100755 workflow/public_html/images/document-revert.png create mode 100644 workflow/public_html/images/document-review.png create mode 100644 workflow/public_html/images/dos.gif create mode 100644 workflow/public_html/images/dynaforms.gif create mode 100644 workflow/public_html/images/dynamicForm/.directory create mode 100644 workflow/public_html/images/dynamicForm/button.gif create mode 100644 workflow/public_html/images/dynamicForm/button.jpg create mode 100644 workflow/public_html/images/dynamicForm/button_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/check_group.gif create mode 100644 workflow/public_html/images/dynamicForm/check_group.jpg create mode 100644 workflow/public_html/images/dynamicForm/check_group_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/checkbox.gif create mode 100644 workflow/public_html/images/dynamicForm/checkbox.jpg create mode 100644 workflow/public_html/images/dynamicForm/checkbox_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/currency.gif create mode 100644 workflow/public_html/images/dynamicForm/currency.jpg create mode 100644 workflow/public_html/images/dynamicForm/currency_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/date.gif create mode 100644 workflow/public_html/images/dynamicForm/date.jpg create mode 100644 workflow/public_html/images/dynamicForm/date_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/dropdown.gif create mode 100644 workflow/public_html/images/dynamicForm/dropdown.jpg create mode 100644 workflow/public_html/images/dynamicForm/dropdown_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/grid.gif create mode 100644 workflow/public_html/images/dynamicForm/grid.jpg create mode 100644 workflow/public_html/images/dynamicForm/grid_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/hidden.gif create mode 100644 workflow/public_html/images/dynamicForm/hidden.jpg create mode 100644 workflow/public_html/images/dynamicForm/hidden_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/hover.gif create mode 100644 workflow/public_html/images/dynamicForm/javascript.gif create mode 100644 workflow/public_html/images/dynamicForm/javascript.jpg create mode 100644 workflow/public_html/images/dynamicForm/javascript_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/link.gif create mode 100644 workflow/public_html/images/dynamicForm/link.jpg create mode 100644 workflow/public_html/images/dynamicForm/link_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/list_box.gif create mode 100644 workflow/public_html/images/dynamicForm/list_box.jpg create mode 100644 workflow/public_html/images/dynamicForm/list_box_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/password.gif create mode 100644 workflow/public_html/images/dynamicForm/password.jpg create mode 100644 workflow/public_html/images/dynamicForm/password_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/percentage.gif create mode 100644 workflow/public_html/images/dynamicForm/percentage.jpg create mode 100644 workflow/public_html/images/dynamicForm/percentage_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/radio_group.gif create mode 100644 workflow/public_html/images/dynamicForm/radio_group.jpg create mode 100644 workflow/public_html/images/dynamicForm/radio_group_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/reset.gif create mode 100644 workflow/public_html/images/dynamicForm/reset.jpg create mode 100644 workflow/public_html/images/dynamicForm/reset_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/save.gif create mode 100644 workflow/public_html/images/dynamicForm/save.jpg create mode 100644 workflow/public_html/images/dynamicForm/save_as.gif create mode 100644 workflow/public_html/images/dynamicForm/save_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/separator.jpg create mode 100644 workflow/public_html/images/dynamicForm/submit.gif create mode 100644 workflow/public_html/images/dynamicForm/submit.jpg create mode 100644 workflow/public_html/images/dynamicForm/submit_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/subtitle.gif create mode 100644 workflow/public_html/images/dynamicForm/subtitle.jpg create mode 100644 workflow/public_html/images/dynamicForm/subtitle_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/suggest.gif create mode 100644 workflow/public_html/images/dynamicForm/suggest.jpg create mode 100644 workflow/public_html/images/dynamicForm/text.gif create mode 100644 workflow/public_html/images/dynamicForm/text.jpg create mode 100644 workflow/public_html/images/dynamicForm/text_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/textarea.gif create mode 100644 workflow/public_html/images/dynamicForm/textarea.jpg create mode 100644 workflow/public_html/images/dynamicForm/textarea_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/title.gif create mode 100644 workflow/public_html/images/dynamicForm/title.jpg create mode 100644 workflow/public_html/images/dynamicForm/title_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/toolbar.buttonbg.gif create mode 100644 workflow/public_html/images/dynamicForm/upload_files.gif create mode 100644 workflow/public_html/images/dynamicForm/upload_files.jpg create mode 100644 workflow/public_html/images/dynamicForm/upload_files_on.jpg create mode 100644 workflow/public_html/images/dynamicForm/yes_no.gif create mode 100644 workflow/public_html/images/dynamicForm/yes_no.jpg create mode 100644 workflow/public_html/images/dynamicForm/yes_no_on.jpg create mode 100644 workflow/public_html/images/dynavars.png create mode 100755 workflow/public_html/images/e-loader.gif create mode 100644 workflow/public_html/images/e_Delete.png create mode 100644 workflow/public_html/images/e_Edit.png create mode 100755 workflow/public_html/images/edit-clear-list.png create mode 100644 workflow/public_html/images/edit.gif create mode 100755 workflow/public_html/images/edit.png create mode 100644 workflow/public_html/images/event_conditional.png create mode 100644 workflow/public_html/images/event_message.png create mode 100644 workflow/public_html/images/event_multiple.png create mode 100644 workflow/public_html/images/events.gif create mode 100755 workflow/public_html/images/export.png create mode 100644 workflow/public_html/images/expressinstall.swf create mode 100644 workflow/public_html/images/favicon.ico create mode 100644 workflow/public_html/images/file-archiver.png create mode 100644 workflow/public_html/images/firstPage.gif create mode 100755 workflow/public_html/images/flags/ad.gif create mode 100755 workflow/public_html/images/flags/ae.gif create mode 100755 workflow/public_html/images/flags/af.gif create mode 100755 workflow/public_html/images/flags/ag.gif create mode 100755 workflow/public_html/images/flags/ai.gif create mode 100755 workflow/public_html/images/flags/al.gif create mode 100755 workflow/public_html/images/flags/am.gif create mode 100755 workflow/public_html/images/flags/an.gif create mode 100755 workflow/public_html/images/flags/ao.gif create mode 100755 workflow/public_html/images/flags/ar.gif create mode 100755 workflow/public_html/images/flags/as.gif create mode 100755 workflow/public_html/images/flags/at.gif create mode 100755 workflow/public_html/images/flags/au.gif create mode 100755 workflow/public_html/images/flags/aw.gif create mode 100755 workflow/public_html/images/flags/ax.gif create mode 100755 workflow/public_html/images/flags/az.gif create mode 100755 workflow/public_html/images/flags/ba.gif create mode 100755 workflow/public_html/images/flags/bb.gif create mode 100755 workflow/public_html/images/flags/bd.gif create mode 100755 workflow/public_html/images/flags/be.gif create mode 100755 workflow/public_html/images/flags/bf.gif create mode 100755 workflow/public_html/images/flags/bg.gif create mode 100755 workflow/public_html/images/flags/bh.gif create mode 100755 workflow/public_html/images/flags/bi.gif create mode 100755 workflow/public_html/images/flags/bj.gif create mode 100755 workflow/public_html/images/flags/bm.gif create mode 100755 workflow/public_html/images/flags/bn.gif create mode 100755 workflow/public_html/images/flags/bo.gif create mode 100755 workflow/public_html/images/flags/br.gif create mode 100755 workflow/public_html/images/flags/bs.gif create mode 100755 workflow/public_html/images/flags/bt.gif create mode 100755 workflow/public_html/images/flags/bv.gif create mode 100755 workflow/public_html/images/flags/bw.gif create mode 100755 workflow/public_html/images/flags/by.gif create mode 100755 workflow/public_html/images/flags/bz.gif create mode 100755 workflow/public_html/images/flags/ca.gif create mode 100755 workflow/public_html/images/flags/catalonia.gif create mode 100755 workflow/public_html/images/flags/cc.gif create mode 100755 workflow/public_html/images/flags/cd.gif create mode 100755 workflow/public_html/images/flags/cf.gif create mode 100755 workflow/public_html/images/flags/cg.gif create mode 100755 workflow/public_html/images/flags/ch.gif create mode 100755 workflow/public_html/images/flags/ci.gif create mode 100755 workflow/public_html/images/flags/ck.gif create mode 100755 workflow/public_html/images/flags/cl.gif create mode 100755 workflow/public_html/images/flags/cm.gif create mode 100755 workflow/public_html/images/flags/cn.gif create mode 100755 workflow/public_html/images/flags/co.gif create mode 100755 workflow/public_html/images/flags/cr.gif create mode 100755 workflow/public_html/images/flags/cs.gif create mode 100755 workflow/public_html/images/flags/cu.gif create mode 100755 workflow/public_html/images/flags/cv.gif create mode 100755 workflow/public_html/images/flags/cx.gif create mode 100755 workflow/public_html/images/flags/cy.gif create mode 100755 workflow/public_html/images/flags/cz.gif create mode 100755 workflow/public_html/images/flags/da.gif create mode 100755 workflow/public_html/images/flags/de.gif create mode 100755 workflow/public_html/images/flags/dj.gif create mode 100755 workflow/public_html/images/flags/dk.gif create mode 100755 workflow/public_html/images/flags/dm.gif create mode 100755 workflow/public_html/images/flags/do.gif create mode 100755 workflow/public_html/images/flags/dz.gif create mode 100755 workflow/public_html/images/flags/ec.gif create mode 100755 workflow/public_html/images/flags/ee.gif create mode 100755 workflow/public_html/images/flags/eg.gif create mode 100755 workflow/public_html/images/flags/eh.gif create mode 100755 workflow/public_html/images/flags/en.gif create mode 100755 workflow/public_html/images/flags/england.gif create mode 100755 workflow/public_html/images/flags/er.gif create mode 100755 workflow/public_html/images/flags/es.gif create mode 100755 workflow/public_html/images/flags/et.gif create mode 100755 workflow/public_html/images/flags/europeanunion.gif create mode 100755 workflow/public_html/images/flags/fam.gif create mode 100755 workflow/public_html/images/flags/fi.gif create mode 100755 workflow/public_html/images/flags/fj.gif create mode 100755 workflow/public_html/images/flags/fk.gif create mode 100755 workflow/public_html/images/flags/fm.gif create mode 100755 workflow/public_html/images/flags/fo.gif create mode 100755 workflow/public_html/images/flags/fr.gif create mode 100755 workflow/public_html/images/flags/ga.gif create mode 100755 workflow/public_html/images/flags/gb.gif create mode 100755 workflow/public_html/images/flags/gd.gif create mode 100755 workflow/public_html/images/flags/ge.gif create mode 100755 workflow/public_html/images/flags/gf.gif create mode 100755 workflow/public_html/images/flags/gh.gif create mode 100755 workflow/public_html/images/flags/gi.gif create mode 100755 workflow/public_html/images/flags/gl.gif create mode 100755 workflow/public_html/images/flags/gm.gif create mode 100755 workflow/public_html/images/flags/gn.gif create mode 100755 workflow/public_html/images/flags/gp.gif create mode 100755 workflow/public_html/images/flags/gq.gif create mode 100755 workflow/public_html/images/flags/gr.gif create mode 100755 workflow/public_html/images/flags/gs.gif create mode 100755 workflow/public_html/images/flags/gt.gif create mode 100755 workflow/public_html/images/flags/gu.gif create mode 100755 workflow/public_html/images/flags/gw.gif create mode 100755 workflow/public_html/images/flags/gy.gif create mode 100755 workflow/public_html/images/flags/he.gif create mode 100755 workflow/public_html/images/flags/hk.gif create mode 100755 workflow/public_html/images/flags/hm.gif create mode 100755 workflow/public_html/images/flags/hn.gif create mode 100755 workflow/public_html/images/flags/hr.gif create mode 100755 workflow/public_html/images/flags/ht.gif create mode 100755 workflow/public_html/images/flags/hu.gif create mode 100755 workflow/public_html/images/flags/id.gif create mode 100755 workflow/public_html/images/flags/ie.gif create mode 100755 workflow/public_html/images/flags/il.gif create mode 100755 workflow/public_html/images/flags/in.gif create mode 100755 workflow/public_html/images/flags/international.png create mode 100755 workflow/public_html/images/flags/io.gif create mode 100755 workflow/public_html/images/flags/iq.gif create mode 100755 workflow/public_html/images/flags/ir.gif create mode 100755 workflow/public_html/images/flags/is.gif create mode 100755 workflow/public_html/images/flags/it.gif create mode 100755 workflow/public_html/images/flags/iw.gif create mode 100755 workflow/public_html/images/flags/jm.gif create mode 100755 workflow/public_html/images/flags/jo.gif create mode 100755 workflow/public_html/images/flags/jp.gif create mode 100755 workflow/public_html/images/flags/ke.gif create mode 100755 workflow/public_html/images/flags/kg.gif create mode 100755 workflow/public_html/images/flags/kh.gif create mode 100755 workflow/public_html/images/flags/ki.gif create mode 100755 workflow/public_html/images/flags/km.gif create mode 100755 workflow/public_html/images/flags/kn.gif create mode 100755 workflow/public_html/images/flags/kp.gif create mode 100755 workflow/public_html/images/flags/kr.gif create mode 100755 workflow/public_html/images/flags/kw.gif create mode 100755 workflow/public_html/images/flags/ky.gif create mode 100755 workflow/public_html/images/flags/kz.gif create mode 100755 workflow/public_html/images/flags/la.gif create mode 100755 workflow/public_html/images/flags/lb.gif create mode 100755 workflow/public_html/images/flags/lc.gif create mode 100755 workflow/public_html/images/flags/li.gif create mode 100755 workflow/public_html/images/flags/lk.gif create mode 100755 workflow/public_html/images/flags/lr.gif create mode 100755 workflow/public_html/images/flags/ls.gif create mode 100755 workflow/public_html/images/flags/lt.gif create mode 100755 workflow/public_html/images/flags/lu.gif create mode 100755 workflow/public_html/images/flags/lv.gif create mode 100755 workflow/public_html/images/flags/ly.gif create mode 100755 workflow/public_html/images/flags/ma.gif create mode 100755 workflow/public_html/images/flags/mc.gif create mode 100755 workflow/public_html/images/flags/md.gif create mode 100755 workflow/public_html/images/flags/me.gif create mode 100755 workflow/public_html/images/flags/mg.gif create mode 100755 workflow/public_html/images/flags/mh.gif create mode 100755 workflow/public_html/images/flags/mk.gif create mode 100755 workflow/public_html/images/flags/ml.gif create mode 100755 workflow/public_html/images/flags/mm.gif create mode 100755 workflow/public_html/images/flags/mn.gif create mode 100755 workflow/public_html/images/flags/mo.gif create mode 100755 workflow/public_html/images/flags/mp.gif create mode 100755 workflow/public_html/images/flags/mq.gif create mode 100755 workflow/public_html/images/flags/mr.gif create mode 100755 workflow/public_html/images/flags/ms.gif create mode 100755 workflow/public_html/images/flags/mt.gif create mode 100755 workflow/public_html/images/flags/mu.gif create mode 100755 workflow/public_html/images/flags/mv.gif create mode 100755 workflow/public_html/images/flags/mw.gif create mode 100755 workflow/public_html/images/flags/mx.gif create mode 100755 workflow/public_html/images/flags/my.gif create mode 100755 workflow/public_html/images/flags/mz.gif create mode 100755 workflow/public_html/images/flags/na.gif create mode 100755 workflow/public_html/images/flags/nc.gif create mode 100755 workflow/public_html/images/flags/ne.gif create mode 100755 workflow/public_html/images/flags/nf.gif create mode 100755 workflow/public_html/images/flags/ng.gif create mode 100755 workflow/public_html/images/flags/ni.gif create mode 100755 workflow/public_html/images/flags/nl.gif create mode 100755 workflow/public_html/images/flags/no.gif create mode 100755 workflow/public_html/images/flags/np.gif create mode 100755 workflow/public_html/images/flags/nr.gif create mode 100755 workflow/public_html/images/flags/nu.gif create mode 100755 workflow/public_html/images/flags/nz.gif create mode 100755 workflow/public_html/images/flags/om.gif create mode 100755 workflow/public_html/images/flags/pa.gif create mode 100755 workflow/public_html/images/flags/pe.gif create mode 100755 workflow/public_html/images/flags/pf.gif create mode 100755 workflow/public_html/images/flags/pg.gif create mode 100755 workflow/public_html/images/flags/ph.gif create mode 100755 workflow/public_html/images/flags/pk.gif create mode 100755 workflow/public_html/images/flags/pl.gif create mode 100755 workflow/public_html/images/flags/pm.gif create mode 100755 workflow/public_html/images/flags/pn.gif create mode 100755 workflow/public_html/images/flags/pr.gif create mode 100755 workflow/public_html/images/flags/ps.gif create mode 100755 workflow/public_html/images/flags/pt.gif create mode 100755 workflow/public_html/images/flags/pw.gif create mode 100755 workflow/public_html/images/flags/py.gif create mode 100755 workflow/public_html/images/flags/qa.gif create mode 100755 workflow/public_html/images/flags/re.gif create mode 100755 workflow/public_html/images/flags/ro.gif create mode 100755 workflow/public_html/images/flags/rs.gif create mode 100755 workflow/public_html/images/flags/ru.gif create mode 100755 workflow/public_html/images/flags/rw.gif create mode 100755 workflow/public_html/images/flags/sa.gif create mode 100755 workflow/public_html/images/flags/sb.gif create mode 100755 workflow/public_html/images/flags/sc.gif create mode 100755 workflow/public_html/images/flags/scotland.gif create mode 100755 workflow/public_html/images/flags/sd.gif create mode 100755 workflow/public_html/images/flags/se.gif create mode 100755 workflow/public_html/images/flags/sg.gif create mode 100755 workflow/public_html/images/flags/sh.gif create mode 100755 workflow/public_html/images/flags/si.gif create mode 100755 workflow/public_html/images/flags/sj.gif create mode 100755 workflow/public_html/images/flags/sk.gif create mode 100755 workflow/public_html/images/flags/sl.gif create mode 100755 workflow/public_html/images/flags/sm.gif create mode 100755 workflow/public_html/images/flags/sn.gif create mode 100755 workflow/public_html/images/flags/so.gif create mode 100755 workflow/public_html/images/flags/sr.gif create mode 100755 workflow/public_html/images/flags/st.gif create mode 100755 workflow/public_html/images/flags/sv.gif create mode 100755 workflow/public_html/images/flags/sy.gif create mode 100755 workflow/public_html/images/flags/sz.gif create mode 100755 workflow/public_html/images/flags/tc.gif create mode 100755 workflow/public_html/images/flags/td.gif create mode 100755 workflow/public_html/images/flags/tf.gif create mode 100755 workflow/public_html/images/flags/tg.gif create mode 100755 workflow/public_html/images/flags/th.gif create mode 100755 workflow/public_html/images/flags/tj.gif create mode 100755 workflow/public_html/images/flags/tk.gif create mode 100755 workflow/public_html/images/flags/tl.gif create mode 100755 workflow/public_html/images/flags/tm.gif create mode 100755 workflow/public_html/images/flags/tn.gif create mode 100755 workflow/public_html/images/flags/to.gif create mode 100755 workflow/public_html/images/flags/tr.gif create mode 100755 workflow/public_html/images/flags/tt.gif create mode 100755 workflow/public_html/images/flags/tv.gif create mode 100755 workflow/public_html/images/flags/tw.gif create mode 100755 workflow/public_html/images/flags/tz.gif create mode 100755 workflow/public_html/images/flags/ua.gif create mode 100755 workflow/public_html/images/flags/ug.gif create mode 100755 workflow/public_html/images/flags/um.gif create mode 100755 workflow/public_html/images/flags/us.gif create mode 100755 workflow/public_html/images/flags/uy.gif create mode 100755 workflow/public_html/images/flags/uz.gif create mode 100755 workflow/public_html/images/flags/va.gif create mode 100755 workflow/public_html/images/flags/vc.gif create mode 100755 workflow/public_html/images/flags/ve.gif create mode 100755 workflow/public_html/images/flags/vg.gif create mode 100755 workflow/public_html/images/flags/vi.gif create mode 100755 workflow/public_html/images/flags/vn.gif create mode 100755 workflow/public_html/images/flags/vu.gif create mode 100755 workflow/public_html/images/flags/wales.gif create mode 100755 workflow/public_html/images/flags/wf.gif create mode 100755 workflow/public_html/images/flags/ws.gif create mode 100755 workflow/public_html/images/flags/ye.gif create mode 100755 workflow/public_html/images/flags/yt.gif create mode 100755 workflow/public_html/images/flags/za.gif create mode 100755 workflow/public_html/images/flags/zh-cn.gif create mode 100755 workflow/public_html/images/flags/zh-tw.gif create mode 100755 workflow/public_html/images/flags/zm.gif create mode 100755 workflow/public_html/images/flags/zw.gif create mode 100644 workflow/public_html/images/flecha.png create mode 100644 workflow/public_html/images/flechav1A.png create mode 100644 workflow/public_html/images/flechv1V.png create mode 100644 workflow/public_html/images/folder.gif create mode 100644 workflow/public_html/images/folderV2.gif create mode 100755 workflow/public_html/images/fondo.jpg create mode 100755 workflow/public_html/images/fondo.png create mode 100644 workflow/public_html/images/fondotask.png create mode 100644 workflow/public_html/images/form.gif create mode 100644 workflow/public_html/images/ftv2blank.gif create mode 100644 workflow/public_html/images/ftv2doc.gif create mode 100644 workflow/public_html/images/ftv2lastnode.gif create mode 100644 workflow/public_html/images/ftv2mlastnode.gif create mode 100644 workflow/public_html/images/ftv2mnode.gif create mode 100644 workflow/public_html/images/ftv2node.gif create mode 100644 workflow/public_html/images/ftv2nodeSimple.gif create mode 100644 workflow/public_html/images/ftv2pnode.gif create mode 100644 workflow/public_html/images/ftv2vertline.gif create mode 100755 workflow/public_html/images/gear.png create mode 100644 workflow/public_html/images/gears.gif create mode 100644 workflow/public_html/images/get_started.png create mode 100755 workflow/public_html/images/go-lt-off.gif create mode 100755 workflow/public_html/images/go-lt-on.gif create mode 100755 workflow/public_html/images/go-rt-off.gif create mode 100755 workflow/public_html/images/go-rt-on.gif create mode 100755 workflow/public_html/images/green-folder.png create mode 100644 workflow/public_html/images/group_add.png create mode 100755 workflow/public_html/images/heartBeat.jpg create mode 100755 workflow/public_html/images/help4.gif create mode 100644 workflow/public_html/images/help5.gif create mode 100755 workflow/public_html/images/icon-arrows-arrow-left.png create mode 100755 workflow/public_html/images/icon-arrows-arrow-right.png create mode 100644 workflow/public_html/images/icon-authSources.png create mode 100644 workflow/public_html/images/icon-calendar.png create mode 100755 workflow/public_html/images/icon-cases-inbox.png create mode 100755 workflow/public_html/images/icon-cases-outbox.png create mode 100755 workflow/public_html/images/icon-config.png create mode 100644 workflow/public_html/images/icon-departments.png create mode 100755 workflow/public_html/images/icon-email-settings.png create mode 100644 workflow/public_html/images/icon-groups.png create mode 100755 workflow/public_html/images/icon-language.png create mode 100755 workflow/public_html/images/icon-languages.png create mode 100644 workflow/public_html/images/icon-logs-list.png create mode 100755 workflow/public_html/images/icon-plugins.png create mode 100644 workflow/public_html/images/icon-pmappcacheview-rebuild.png create mode 100644 workflow/public_html/images/icon-pmcalendar.png create mode 100644 workflow/public_html/images/icon-pmcaselist-conf.png create mode 100644 workflow/public_html/images/icon-pmcaselist-setup.png create mode 100644 workflow/public_html/images/icon-pmcaseslist-conf.png create mode 100644 workflow/public_html/images/icon-pmclear-cache.png create mode 100644 workflow/public_html/images/icon-pmlogo-15x15.png create mode 100755 workflow/public_html/images/icon-pmlogo.png create mode 100755 workflow/public_html/images/icon-pmlogs.png create mode 100644 workflow/public_html/images/icon-pmmail-conf.png create mode 100644 workflow/public_html/images/icon-pmmailconf.png create mode 100644 workflow/public_html/images/icon-pmplugins.png create mode 100755 workflow/public_html/images/icon-pmprocess-category.png create mode 100644 workflow/public_html/images/icon-pmskins.png create mode 100644 workflow/public_html/images/icon-pmtables.png create mode 100644 workflow/public_html/images/icon-pmupgrade.png create mode 100644 workflow/public_html/images/icon-pmwebservices.png create mode 100755 workflow/public_html/images/icon-rebuild-clean.png create mode 100644 workflow/public_html/images/icon-roles.png create mode 100755 workflow/public_html/images/icon-skins.png create mode 100755 workflow/public_html/images/icon-system-upgrade.png create mode 100755 workflow/public_html/images/icon-tables.png create mode 100644 workflow/public_html/images/icon-users.png create mode 100755 workflow/public_html/images/icon-webservices.png create mode 100644 workflow/public_html/images/icon.trigger.png create mode 100644 workflow/public_html/images/iconoenlace.png create mode 100644 workflow/public_html/images/icons_silk/calendar_x_button.png create mode 100644 workflow/public_html/images/icons_silk/checked.png create mode 100644 workflow/public_html/images/icons_silk/search_x_button.png create mode 100644 workflow/public_html/images/icons_silk/sprite.css create mode 100644 workflow/public_html/images/icons_silk/sprite_ie.css create mode 100644 workflow/public_html/images/icons_silk/sprites.gif.png create mode 100644 workflow/public_html/images/icons_silk/sprites.png create mode 100644 workflow/public_html/images/icons_silk/unchecked.png create mode 100755 workflow/public_html/images/import.gif create mode 100755 workflow/public_html/images/inf.png create mode 100644 workflow/public_html/images/inputdocument.gif create mode 100755 workflow/public_html/images/izp.png create mode 100644 workflow/public_html/images/kcmdf.png create mode 100755 workflow/public_html/images/language-selected.png create mode 100644 workflow/public_html/images/lastPage.gif create mode 100755 workflow/public_html/images/linhori.png create mode 100755 workflow/public_html/images/linver.png create mode 100755 workflow/public_html/images/loader-gears.gif create mode 100644 workflow/public_html/images/loading-gears.gif create mode 100644 workflow/public_html/images/lock.png create mode 100755 workflow/public_html/images/logo_processmaker.gif create mode 100755 workflow/public_html/images/mail-mark-task.png create mode 100755 workflow/public_html/images/mail-message-new.png create mode 100755 workflow/public_html/images/mail-queue.png create mode 100755 workflow/public_html/images/mail-send.png create mode 100644 workflow/public_html/images/mail.gif create mode 100644 workflow/public_html/images/masterDetailMain.png create mode 100644 workflow/public_html/images/masterDetailOther.png create mode 100644 workflow/public_html/images/minus.gif create mode 100644 workflow/public_html/images/newSkin/bf.jpg create mode 100644 workflow/public_html/images/newSkin/bm.jpg create mode 100644 workflow/public_html/images/newSkin/bsm.jpg create mode 100644 workflow/public_html/images/newSkin/bsms.jpg create mode 100755 workflow/public_html/images/newSkin/fbc.blue.png create mode 100644 workflow/public_html/images/newSkin/fbc.png create mode 100755 workflow/public_html/images/newSkin/fbl.blue.png create mode 100644 workflow/public_html/images/newSkin/fbl.png create mode 100755 workflow/public_html/images/newSkin/fbr.blue.png create mode 100644 workflow/public_html/images/newSkin/fbr.png create mode 100644 workflow/public_html/images/newSkin/frame.full.bottom.png create mode 100644 workflow/public_html/images/newSkin/frame.full.top.png create mode 100644 workflow/public_html/images/newSkin/frame.home.bottom.png create mode 100644 workflow/public_html/images/newSkin/frame.right.bottom.png create mode 100644 workflow/public_html/images/newSkin/frame.right.top.gif create mode 100755 workflow/public_html/images/newSkin/ftc.png create mode 100755 workflow/public_html/images/newSkin/ftl.blue.gif create mode 100644 workflow/public_html/images/newSkin/ftl.png create mode 100755 workflow/public_html/images/newSkin/ftlL.png create mode 100755 workflow/public_html/images/newSkin/ftr.blue.gif create mode 100644 workflow/public_html/images/newSkin/ftr.png create mode 100755 workflow/public_html/images/newSkin/ftrL.png create mode 100644 workflow/public_html/images/newSkin/input_back.gif create mode 100644 workflow/public_html/images/nextPage.gif create mode 100644 workflow/public_html/images/object_permission.gif create mode 100644 workflow/public_html/images/ok.png create mode 100755 workflow/public_html/images/onmouse.png create mode 100644 workflow/public_html/images/onmouseSilver.jpg create mode 100644 workflow/public_html/images/options.png create mode 100644 workflow/public_html/images/outputdocument.gif create mode 100644 workflow/public_html/images/panel_title.jpg create mode 100644 workflow/public_html/images/panel_title2.jpg create mode 100755 workflow/public_html/images/pin-dn-off.gif create mode 100755 workflow/public_html/images/pin-dn-on.gif create mode 100755 workflow/public_html/images/pin-up-off.gif create mode 100755 workflow/public_html/images/pin-up-on.gif create mode 100755 workflow/public_html/images/plus-blue.png create mode 100644 workflow/public_html/images/plus.gif create mode 100644 workflow/public_html/images/plus_red.gif create mode 100644 workflow/public_html/images/pm.gif create mode 100644 workflow/public_html/images/pmdate.png create mode 100644 workflow/public_html/images/pmdateicon.png create mode 100755 workflow/public_html/images/pmdateiw.png create mode 100644 workflow/public_html/images/pmdatetime.png create mode 100755 workflow/public_html/images/pmdatetimeiw.png create mode 100644 workflow/public_html/images/previousPage.gif create mode 100644 workflow/public_html/images/printer.png create mode 100755 workflow/public_html/images/processmaker.logo.jpg create mode 100644 workflow/public_html/images/processmap/contract.gif create mode 100755 workflow/public_html/images/properties.png create mode 100644 workflow/public_html/images/reassing.png create mode 100755 workflow/public_html/images/refresh.gif create mode 100644 workflow/public_html/images/report_tables.gif create mode 100755 workflow/public_html/images/resizable-e.gif create mode 100755 workflow/public_html/images/resizable.gif create mode 100755 workflow/public_html/images/resource-group.png create mode 100644 workflow/public_html/images/reviewed.png create mode 100644 workflow/public_html/images/rotate_cw.png create mode 100644 workflow/public_html/images/rotate_cw_green.png create mode 100644 workflow/public_html/images/row_down.png create mode 100755 workflow/public_html/images/rules.png create mode 100755 workflow/public_html/images/run-build-file.png create mode 100644 workflow/public_html/images/scheduler.png create mode 100644 workflow/public_html/images/select-icon.png create mode 100755 workflow/public_html/images/separator-v.gif create mode 100755 workflow/public_html/images/steps.png create mode 100644 workflow/public_html/images/styles/red/bm.jpg create mode 100644 workflow/public_html/images/styles/red/bsms.jpg create mode 100644 workflow/public_html/images/subProcess.png create mode 100644 workflow/public_html/images/subp.png create mode 100755 workflow/public_html/images/sup.png create mode 100755 workflow/public_html/images/system-search.png create mode 100644 workflow/public_html/images/task.gif create mode 100644 workflow/public_html/images/toadd.png create mode 100644 workflow/public_html/images/tool.jpeg create mode 100644 workflow/public_html/images/toolbarBackground.jpg create mode 100644 workflow/public_html/images/tracker.gif create mode 100644 workflow/public_html/images/trash.gif create mode 100644 workflow/public_html/images/tres.gif create mode 100644 workflow/public_html/images/trigger.gif create mode 100755 workflow/public_html/images/triggers/Google_Calendar_normal.png create mode 100755 workflow/public_html/images/triggers/TalendOpenStudio.gif create mode 100755 workflow/public_html/images/triggers/icon_SugarCRM.gif create mode 100755 workflow/public_html/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png create mode 100644 workflow/public_html/images/unchecked.gif create mode 100644 workflow/public_html/images/unknown_icon.gif create mode 100644 workflow/public_html/images/unlock.png create mode 100644 workflow/public_html/images/uno.gif create mode 100644 workflow/public_html/images/user-id-32x32.png create mode 100644 workflow/public_html/images/user.gif create mode 100755 workflow/public_html/images/users.png create mode 100644 workflow/public_html/images/yellowBackgroundMenu.jpg create mode 100644 workflow/public_html/images/yellowBackgroundSubMenu.jpg create mode 100644 workflow/public_html/index.html create mode 100644 workflow/public_html/skins/JSForms.js create mode 100644 workflow/public_html/skins/ajax.js create mode 100755 workflow/public_html/skins/ext/ext-all-notheme.css create mode 100755 workflow/public_html/skins/ext/ext-all.css create mode 100755 workflow/public_html/skins/ext/images/default/box/corners-blue.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/corners.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/l-blue.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/l.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/r-blue.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/r.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/tb-blue.gif create mode 100755 workflow/public_html/skins/ext/images/default/box/tb.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/arrow.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/btn.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/btn2.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/group-cs.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/group-lr.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/group-tb.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow-b-noline.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow-b.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow-bo.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow-noline.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow-o.gif create mode 100755 workflow/public_html/skins/ext/images/default/button/s-arrow.gif create mode 100755 workflow/public_html/skins/ext/images/default/dd/drop-add.gif create mode 100755 workflow/public_html/skins/ext/images/default/dd/drop-no.gif create mode 100755 workflow/public_html/skins/ext/images/default/dd/drop-yes.gif create mode 100755 workflow/public_html/skins/ext/images/default/editor/tb-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/checkbox.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/clear-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/clear-trigger.psd create mode 100755 workflow/public_html/skins/ext/images/default/form/date-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/date-trigger.psd create mode 100755 workflow/public_html/skins/ext/images/default/form/error-tip-corners.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/exclamation.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/radio.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/search-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/search-trigger.psd create mode 100755 workflow/public_html/skins/ext/images/default/form/text-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/trigger-square.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/trigger-square.psd create mode 100755 workflow/public_html/skins/ext/images/default/form/trigger-tpl.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/trigger.gif create mode 100755 workflow/public_html/skins/ext/images/default/form/trigger.psd create mode 100755 workflow/public_html/skins/ext/images/default/gradient-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/arrow-left-white.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/arrow-right-white.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/col-move-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/col-move-top.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/columns.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/dirty.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/done.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/drop-no.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/drop-yes.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/footer-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-blue-hd.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-blue-split.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-hrow.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-loading.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-split.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid-vista-hd.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid3-hd-btn.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid3-hrow-over.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid3-hrow.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid3-special-col-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/grid3-special-col-sel-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/group-by.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/group-collapse.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/group-expand-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/group-expand.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hd-pop.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-asc.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-desc.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-lock.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-lock.png create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-unlock.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/hmenu-unlock.png create mode 100755 workflow/public_html/skins/ext/images/default/grid/invalid_line.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/loading.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/mso-hd.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/nowait.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-first-disabled.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-first.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-last-disabled.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-last.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-next-disabled.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-next.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-prev-disabled.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/page-prev.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/pick-button.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/refresh.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/row-check-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/row-expand-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/row-over.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/row-sel.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/sort-hd.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/sort_asc.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/sort_desc.gif create mode 100755 workflow/public_html/skins/ext/images/default/grid/wait.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/collapse.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/expand.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/gradient-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/mini-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/mini-left.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/mini-right.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/mini-top.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/ns-collapse.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/ns-expand.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/panel-close.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/panel-title-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/panel-title-light-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/stick.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/stuck.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/tab-close-on.gif create mode 100755 workflow/public_html/skins/ext/images/default/layout/tab-close.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/checked.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/group-checked.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/item-over.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/menu-parent.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/menu.gif create mode 100755 workflow/public_html/skins/ext/images/default/menu/unchecked.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/corners-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/left-right.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/light-hd.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/tool-sprite-tpl.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/tool-sprites.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/tools-sprites-trans.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/top-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/top-bottom.png create mode 100755 workflow/public_html/skins/ext/images/default/panel/white-corners-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/white-left-right.gif create mode 100755 workflow/public_html/skins/ext/images/default/panel/white-top-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/default/progress/progress-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/qtip/bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/qtip/close.gif create mode 100755 workflow/public_html/skins/ext/images/default/qtip/tip-anchor-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/qtip/tip-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/s.gif create mode 100755 workflow/public_html/skins/ext/images/default/shadow-c.png create mode 100755 workflow/public_html/skins/ext/images/default/shadow-lr.png create mode 100755 workflow/public_html/skins/ext/images/default/shadow.png create mode 100755 workflow/public_html/skins/ext/images/default/shared/blue-loading.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/calendar.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/glass-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/hd-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/large-loading.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/left-btn.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/loading-balls.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/right-btn.gif create mode 100755 workflow/public_html/skins/ext/images/default/shared/warning.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/e-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/e-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/ne-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/ne-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/nw-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/nw-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/s-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/s-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/se-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/se-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/square.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/sw-handle-dark.gif create mode 100755 workflow/public_html/skins/ext/images/default/sizer/sw-handle.gif create mode 100755 workflow/public_html/skins/ext/images/default/slider/slider-bg.png create mode 100755 workflow/public_html/skins/ext/images/default/slider/slider-thumb.png create mode 100755 workflow/public_html/skins/ext/images/default/slider/slider-v-bg.png create mode 100755 workflow/public_html/skins/ext/images/default/slider/slider-v-thumb.png create mode 100755 workflow/public_html/skins/ext/images/default/tabs/scroll-left.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/scroll-right.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/scroller-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-inactive-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-inactive-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-over-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-over-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-btm-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-close.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.png create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tab-strip-btm-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/tabs/tabs-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/btn-arrow-light.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/btn-arrow.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/btn-over-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/gray-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/more.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/tb-bg.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/tb-btn-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/tb-xl-btn-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/default/toolbar/tb-xl-sep.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/arrows.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-add.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-between.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-no.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-over.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-under.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/drop-yes.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-end-minus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-end-minus.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-end-plus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-end-plus.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-end.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-line.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-minus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-minus.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-plus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow-plus.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/elbow.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/folder-open.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/folder.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/leaf.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/loading.gif create mode 100755 workflow/public_html/skins/ext/images/default/tree/s.gif create mode 100755 workflow/public_html/skins/ext/images/default/window/icon-error.gif create mode 100755 workflow/public_html/skins/ext/images/default/window/icon-info.gif create mode 100755 workflow/public_html/skins/ext/images/default/window/icon-question.gif create mode 100755 workflow/public_html/skins/ext/images/default/window/icon-warning.gif create mode 100755 workflow/public_html/skins/ext/images/default/window/left-corners.png create mode 100755 workflow/public_html/skins/ext/images/default/window/left-corners.psd create mode 100755 workflow/public_html/skins/ext/images/default/window/left-right.png create mode 100755 workflow/public_html/skins/ext/images/default/window/left-right.psd create mode 100755 workflow/public_html/skins/ext/images/default/window/right-corners.png create mode 100755 workflow/public_html/skins/ext/images/default/window/right-corners.psd create mode 100755 workflow/public_html/skins/ext/images/default/window/top-bottom.png create mode 100755 workflow/public_html/skins/ext/images/default/window/top-bottom.psd create mode 100755 workflow/public_html/skins/ext/images/gray/button/btn-arrow.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/btn-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/btn.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/group-cs.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/group-lr.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/group-tb.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/s-arrow-bo.gif create mode 100755 workflow/public_html/skins/ext/images/gray/button/s-arrow-o.gif create mode 100755 workflow/public_html/skins/ext/images/gray/form/clear-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/gray/form/date-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/gray/form/search-trigger.gif create mode 100755 workflow/public_html/skins/ext/images/gray/form/trigger-square.gif create mode 100755 workflow/public_html/skins/ext/images/gray/form/trigger.gif create mode 100755 workflow/public_html/skins/ext/images/gray/gradient-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/col-move-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/col-move-top.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-hd-btn.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-hrow-over.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-hrow-over2.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-hrow.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-hrow2.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-bg2.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-sel-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/group-collapse.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/group-expand-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/group-expand.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/page-first.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/page-last.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/page-next.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/page-prev.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/refresh.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/row-expand-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/sort_asc.gif create mode 100755 workflow/public_html/skins/ext/images/gray/grid/sort_desc.gif create mode 100755 workflow/public_html/skins/ext/images/gray/menu/group-checked.gif create mode 100755 workflow/public_html/skins/ext/images/gray/menu/item-over-disabled.gif create mode 100755 workflow/public_html/skins/ext/images/gray/menu/item-over.gif create mode 100755 workflow/public_html/skins/ext/images/gray/menu/menu-parent.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/corners-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/left-right.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/light-hd.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/tool-sprite-tpl.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/tool-sprites.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/tools-sprites-trans.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/top-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/top-bottom.png create mode 100755 workflow/public_html/skins/ext/images/gray/panel/white-corners-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/white-left-right.gif create mode 100755 workflow/public_html/skins/ext/images/gray/panel/white-top-bottom.gif create mode 100755 workflow/public_html/skins/ext/images/gray/progress/progress-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/qtip/bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/qtip/close.gif create mode 100755 workflow/public_html/skins/ext/images/gray/qtip/tip-anchor-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/qtip/tip-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/s.gif create mode 100755 workflow/public_html/skins/ext/images/gray/shared/hd-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/shared/left-btn.gif create mode 100755 workflow/public_html/skins/ext/images/gray/shared/right-btn.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/e-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/ne-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/nw-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/s-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/se-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/square.gif create mode 100755 workflow/public_html/skins/ext/images/gray/sizer/sw-handle.gif create mode 100755 workflow/public_html/skins/ext/images/gray/slider/slider-thumb.png create mode 100755 workflow/public_html/skins/ext/images/gray/slider/slider-v-thumb.png create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/scroll-left.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/scroll-right.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/scroller-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-inactive-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-inactive-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-over-left-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-over-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-btm-right-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-close.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-strip-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-strip-bg.png create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tab-strip-btm-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tabs/tabs-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/btn-arrow-light.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/btn-arrow.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/btn-over-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/gray-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/more.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/tb-bg.gif create mode 100755 workflow/public_html/skins/ext/images/gray/toolbar/tb-btn-sprite.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tree/arrows.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tree/elbow-end-minus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tree/elbow-end-minus.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus-nl.gif create mode 100755 workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus.gif create mode 100755 workflow/public_html/skins/ext/images/gray/window/icon-error.gif create mode 100755 workflow/public_html/skins/ext/images/gray/window/icon-info.gif create mode 100755 workflow/public_html/skins/ext/images/gray/window/icon-question.gif create mode 100755 workflow/public_html/skins/ext/images/gray/window/icon-warning.gif create mode 100755 workflow/public_html/skins/ext/images/gray/window/left-corners.png create mode 100755 workflow/public_html/skins/ext/images/gray/window/left-corners.pspimage create mode 100755 workflow/public_html/skins/ext/images/gray/window/left-right.png create mode 100755 workflow/public_html/skins/ext/images/gray/window/right-corners.png create mode 100755 workflow/public_html/skins/ext/images/gray/window/top-bottom.png create mode 100644 workflow/public_html/skins/ext/pmos-xtheme-gray.css create mode 100755 workflow/public_html/skins/ext/xtheme-blue.css create mode 100755 workflow/public_html/skins/ext/xtheme-gray.css create mode 100644 workflow/public_html/skins/green/iepngfix.htc create mode 100755 workflow/public_html/skins/green/images/bar_bg_bw.gif create mode 100644 workflow/public_html/skins/green/images/bf.jpg create mode 100644 workflow/public_html/skins/green/images/bm.jpg create mode 100644 workflow/public_html/skins/green/images/bsm.jpg create mode 100644 workflow/public_html/skins/green/images/bsms.jpg create mode 100755 workflow/public_html/skins/green/images/dark-pointer.gif create mode 100644 workflow/public_html/skins/green/images/error.gif create mode 100644 workflow/public_html/skins/green/images/fbc.blue.png create mode 100644 workflow/public_html/skins/green/images/fbc.png create mode 100644 workflow/public_html/skins/green/images/fbl.blue.png create mode 100644 workflow/public_html/skins/green/images/fbl.png create mode 100644 workflow/public_html/skins/green/images/fbr.blue.png create mode 100644 workflow/public_html/skins/green/images/fbr.png create mode 100644 workflow/public_html/skins/green/images/frame.full.bottom.png create mode 100644 workflow/public_html/skins/green/images/frame.full.top.png create mode 100644 workflow/public_html/skins/green/images/frame.home.bottom.png create mode 100644 workflow/public_html/skins/green/images/frame.right.bottom.png create mode 100644 workflow/public_html/skins/green/images/frame.right.top.gif create mode 100644 workflow/public_html/skins/green/images/ftc.png create mode 100644 workflow/public_html/skins/green/images/ftl.blue.gif create mode 100644 workflow/public_html/skins/green/images/ftl.png create mode 100644 workflow/public_html/skins/green/images/ftlL.png create mode 100644 workflow/public_html/skins/green/images/ftr.blue.gif create mode 100644 workflow/public_html/skins/green/images/ftr.png create mode 100644 workflow/public_html/skins/green/images/ftrL.png create mode 100644 workflow/public_html/skins/green/images/input_back.gif create mode 100644 workflow/public_html/skins/green/images/message.png create mode 100644 workflow/public_html/skins/green/images/warning.png create mode 100644 workflow/public_html/skins/green/printstyle.css create mode 100644 workflow/public_html/skins/green/style.css create mode 100644 workflow/public_html/skins/iphone/images/bf.jpg create mode 100644 workflow/public_html/skins/iphone/images/bm.jpg create mode 100644 workflow/public_html/skins/iphone/images/bsm.jpg create mode 100644 workflow/public_html/skins/iphone/images/bsms.jpg create mode 100644 workflow/public_html/skins/iphone/images/fbc.blue.png create mode 100644 workflow/public_html/skins/iphone/images/fbc.png create mode 100644 workflow/public_html/skins/iphone/images/fbl.blue.png create mode 100644 workflow/public_html/skins/iphone/images/fbl.png create mode 100644 workflow/public_html/skins/iphone/images/fbr.blue.png create mode 100644 workflow/public_html/skins/iphone/images/fbr.png create mode 100644 workflow/public_html/skins/iphone/images/frame.full.bottom.png create mode 100644 workflow/public_html/skins/iphone/images/frame.full.top.png create mode 100644 workflow/public_html/skins/iphone/images/frame.home.bottom.png create mode 100644 workflow/public_html/skins/iphone/images/frame.right.bottom.png create mode 100644 workflow/public_html/skins/iphone/images/frame.right.top.gif create mode 100644 workflow/public_html/skins/iphone/images/ftc.png create mode 100644 workflow/public_html/skins/iphone/images/ftl.blue.gif create mode 100644 workflow/public_html/skins/iphone/images/ftl.png create mode 100644 workflow/public_html/skins/iphone/images/ftlL.png create mode 100644 workflow/public_html/skins/iphone/images/ftr.blue.gif create mode 100644 workflow/public_html/skins/iphone/images/ftr.png create mode 100644 workflow/public_html/skins/iphone/images/ftrL.png create mode 100644 workflow/public_html/skins/iphone/images/iPhoneArrow.png create mode 100644 workflow/public_html/skins/iphone/images/iPhoneToolbar.png create mode 100644 workflow/public_html/skins/iphone/images/input_back.gif create mode 100644 workflow/public_html/skins/iphone/style.css create mode 100644 workflow/public_html/skins/rtl/iepngfix.htc create mode 100644 workflow/public_html/skins/rtl/images/bar_bg_bw.gif create mode 100644 workflow/public_html/skins/rtl/images/bf.jpg create mode 100644 workflow/public_html/skins/rtl/images/bm.jpg create mode 100644 workflow/public_html/skins/rtl/images/bsm.jpg create mode 100644 workflow/public_html/skins/rtl/images/bsms.jpg create mode 100644 workflow/public_html/skins/rtl/images/dark-pointer.gif create mode 100644 workflow/public_html/skins/rtl/images/fbc.blue.png create mode 100644 workflow/public_html/skins/rtl/images/fbc.png create mode 100644 workflow/public_html/skins/rtl/images/fbl.blue.png create mode 100644 workflow/public_html/skins/rtl/images/fbl.png create mode 100644 workflow/public_html/skins/rtl/images/fbr.blue.png create mode 100644 workflow/public_html/skins/rtl/images/fbr.png create mode 100644 workflow/public_html/skins/rtl/images/frame.full.bottom.png create mode 100644 workflow/public_html/skins/rtl/images/frame.full.top.png create mode 100644 workflow/public_html/skins/rtl/images/frame.home.bottom.png create mode 100644 workflow/public_html/skins/rtl/images/frame.right.bottom.png create mode 100644 workflow/public_html/skins/rtl/images/frame.right.top.gif create mode 100644 workflow/public_html/skins/rtl/images/ftc.png create mode 100644 workflow/public_html/skins/rtl/images/ftl.blue.gif create mode 100644 workflow/public_html/skins/rtl/images/ftl.png create mode 100644 workflow/public_html/skins/rtl/images/ftlL.png create mode 100644 workflow/public_html/skins/rtl/images/ftr.blue.gif create mode 100644 workflow/public_html/skins/rtl/images/ftr.png create mode 100644 workflow/public_html/skins/rtl/images/ftrL.png create mode 100644 workflow/public_html/skins/rtl/images/input_back.gif create mode 100644 workflow/public_html/skins/rtl/style.css create mode 100644 workflow/public_html/skins/valida.js create mode 100644 workflow/public_html/skins/workPeriod.js create mode 100644 workflow/public_html/sysGeneric.php create mode 100644 workflow/public_html/sysUnnamed.php diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..6e88f9e18 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 000000000..ae23bfe51 --- /dev/null +++ b/README.txt @@ -0,0 +1,99 @@ +Id: README.txt,v XXX 2008/02/14 12:30:06 pcabero + +Overview +-------- +ProcessMaker is an open source workflow management software suite, which includes tools to +automate your workflow, design forms, create documents, assign roles and users, create routing rules, +and map an individual process quickly and easily. +It's relatively lightweight and doesn't require any kind of installation on the client computer. +This file describes the requirements and installation steps for the server. + +More information and licence +---------------------------- +ProcessMaker - Automate your Processes +Copyright (C) 2002 - 2008 Colosa Inc. + +Licensed under the terms of the GNU Affero General Public License version 3: +http://www.affero.org/oagpl.html + +For further information visit: +http://www.processmaker.com/ + +Requirements +------------ +- Linux +- Apache 2.2.3 or greater +- PHP 5.1.6 or greater +- MySQL 4.1.20 or greater + +If you have the RHEL or Centos Linux distribution, to install and run ProcessMaker, the feature SELinux +shoud be disabled. See How to disable SELINUX for additional instructions. +Likewise PHP should be configured with more than 30 MB in the parameter memory_limit. ProcessMaker +ideally uses 120 MB in this parameter. See How to change the PHP "memory_limit" parameter +for additional instructions. +Magic quotes in php.ini must be in Off + +Installation +------------ +1. Download ProcessMaker XXX from http://sourceforge.net/projects/processmaker/ and install it +2. Rename the file "/etc/httpd/conf.d/pmos.conf.rpm" as "/etc/httpd/conf.d/pmos.conf" +3. Ensure that the virtual server "your_processmaker_server" defined in the file + "/etc/httpd/conf.d/pmos.conf" coincides with your system configuration. + The name of this virtual server is only an example, you can change this name + according the domain defined in your network. +4. If you don't have the name of the virtual server defined in step 3, you should add this server to your host. + To do this, you need to edit the file + /etc/hosts + In this file you should add the following line: + your_ip_address your_processmaker_server +5. Finally restart the httpd service + +Configuration +------------- +1. Make sure that the "data" and "compiled" subdirectories are world writable (chmod 0777), + because the data of your workflows will be saved in the "data" subdirectory, and the subdirectory "compiled" + will store the compiled templates of ProccessMaker. +2. Open your browser and load the ProcessMaker site. + You should see the test page. If you don't see it, please check the installation steps. +3. On the test page, + - check your connection and paths + - enter your MySQL database account information, which should have privileges to create databases and users. +4. Click on the tab "Install" (in the upper right-hand corner) +5. After few seconds you will get the confirmation of your installation. If it was successful, click on the button + "Finish installation" and enjoy ProccessMaker. Otherwise, please visit our forums (http://forum.processmaker.com/) + to get support. +6. To login to ProcessMaker use these credentials: + user: admin + pass: admin + +How to disable SELinux +---------------------- +Since ProcessMaker is currently installed and running in the /opt directory, it is +necessary to disable the SELinux feature. +To disactivate the SELinux you need to edit the respective configuration file. +Usually you should find it in: +/etc/selinux/config + +In this file you will need to disable the following parameter: + SELINUX = disable + +After that you need to restart your computer, so this change will take effect. + +How to change the PHP "memory_limit" parameter +---------------------------------------------- +ProccesMaker needs minimum 31MB in the parameter "memory_limit" of PHP. This parameter defines +the maximum amount of memory a script may consume. +To change this value you need to edit the php.ini file. +Usually you should find it in + /etc/php.ini + +In this file you should put the new value (beetween 31 and 120): + memory_limit = 31MB; + +After that, restart the httpd service. + +Credits +------- +- ProcessMaker - Automate your Processes +Copyright (C) 2002-2008 Colosa +http://www.processmaker.com/ \ No newline at end of file diff --git a/gulliver/bin/gulliver b/gulliver/bin/gulliver new file mode 100755 index 000000000..2aca4ed46 --- /dev/null +++ b/gulliver/bin/gulliver @@ -0,0 +1,64 @@ +#!/usr/bin/php +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if (! PATH_THIRDPARTY ) { + die("You must launch gulliver command line with the gulliver script\n"); + } + + // set magic_quotes_runtime to off + ini_set('magic_quotes_runtime', 'Off'); + require_once( PATH_THIRDPARTY . 'pake' . PATH_SEP . 'pakeFunction.php'); + require_once( PATH_THIRDPARTY . 'pake' . PATH_SEP . 'pakeGetopt.class.php'); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + // trap -V before pake + if (in_array('-V', $argv) || in_array('--version', $argv)) + { + printf("Gulliver version %s\n", pakeColor::colorize(trim(file_get_contents( PATH_GULLIVER . 'VERSION')), 'INFO')); + exit(0); + } + + if (count($argv) <= 1) + { + $argv[] = '-T'; + } + + + // register tasks + $dir = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks'; + $tasks = pakeFinder::type('file')->name( 'pake*.php' )->in($dir); + + foreach ($tasks as $task) { + include_once($task); + } + + // run task + pakeApp::get_instance()->run(null, null, false); + + exit(0); diff --git a/gulliver/bin/tasks/pakeBase.php b/gulliver/bin/tasks/pakeBase.php new file mode 100644 index 000000000..0a7054186 --- /dev/null +++ b/gulliver/bin/tasks/pakeBase.php @@ -0,0 +1,64 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +pake_task('project_exists'); +pake_task('app_exists', 'project_exists'); +pake_task('module_exists', 'app_exists'); + +function run_project_exists($task, $args) +{ +// if (!file_exists('pre_processor.php')) +// { +// throw new Exception('you must be in a gulliver project directory'); +// } + +// pake_properties('config/properties.ini'); +} + +function run_app_exists($task, $args) +{ + if (!count($args)) + { + throw new Exception('you must provide your application name'); + } + + if (!is_dir(getcwd().'/apps/'.$args[0])) + { + throw new Exception('application "'.$args[0].'" does not exist'); + } +} + +function run_module_exists($task, $args) +{ + if (count($args) < 2) + { + throw new Exception('you must provide your module name'); + } + + if (!is_dir(getcwd().'/apps/'.$args[0].'/modules/'.$args[1])) + { + throw new Exception('module "'.$args[1].'" does not exist'); + } +} diff --git a/gulliver/bin/tasks/pakeGulliver.php b/gulliver/bin/tasks/pakeGulliver.php new file mode 100644 index 000000000..d130b380d --- /dev/null +++ b/gulliver/bin/tasks/pakeGulliver.php @@ -0,0 +1,2519 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +//dont work mb_internal_encoding('UTF-8'); + + +pake_desc('gulliver version'); +pake_task('version', 'project_exists'); + +pake_desc("create poedit file for system labels\n args: [ [ [verbose]]] "); +pake_task('create-poedit-file', 'project_exists'); + +pake_desc("generate a unit test file for an existing class\n args: "); +pake_task('generate-unit-test-class', 'project_exists'); + +//pake_desc('generate basic CRUD files for an existing class'); +//pake_task('generate-crud', 'project_exists'); + + +pake_desc("build new project \n args: "); +pake_task('new-project', 'project_exists'); + +pake_desc("build new plugin \n args: "); +pake_task('new-plugin', 'project_exists'); + +pake_desc("pack plugin in .tar file \n args: "); +pake_task('pack-plugin', 'project_exists'); + +pake_desc("generate basic CRUD files for an existing class\n args: "); +pake_task('propel-build-crud', 'project_exists'); + +pake_desc("backup a workspace\n args: [-c|--compress] [|]"); +pake_task('workspace-backup', 'project_exists'); + +pake_desc("restore a previously backed-up workspace\n args: [-o|--overwrite] "); +pake_task('workspace-restore', 'project_exists'); + +pake_desc("check standard code\n args: "); +pake_task('check-standard-code', 'project_exists' ); + +function run_version($task, $args) { + printf("Gulliver version %s\n", pakeColor::colorize(trim(file_get_contents(PATH_GULLIVER . 'VERSION')), 'INFO')); + exit(0); +} + +function isUTF8($str) { + if( $str === mb_convert_encoding(mb_convert_encoding($str, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ) { + return true; + } else { + return false; + } +} + +function strip_quotes($text) { + if( ! isUTF8($text) ) + $text = utf8_encode($text); + return str_replace('"', "", $text); +} +// function for the prompt data read in windows +function prompt_win($text) { + + print $text; + flush(); + ob_flush(); + $read = trim(fgets(STDIN)); + return $read; + +} + +function prompt($text) { + + if( ! (PHP_OS == "WINNT") ) { + printf("$text%s ", pakeColor::colorize(':', 'INFO')); + # 4092 max on win32 fopen + + + //$fp=fopen("php://stdin", "r"); + $fp = fopen("/dev/tty", "r"); + $in = fgets($fp, 4094); + fclose($fp); + + # strip newline + (PHP_OS == "WINNT") ? ($read = str_replace("\r\n", "", $in)) : ($read = str_replace("\n", "", $in)); + } else { + $read = prompt_win($text); + } + + return $read; +} + +function query_sql_file($file, $connection) { + $report = array ( + 'SQL_FILE' => $file, + 'errors' => array (), + 'querys' => 0 + ); + $content = @fread(@fopen($file, "rt"), @filesize($file)); + if( ! $content ) { + $report['errors'] = "Error reading SQL"; + return $report; + } + $ret = array (); + for( $i = 0; $i < strlen($content) - 1; $i ++ ) { + if( $content[$i] == ";" ) { + if( $content[$i + 1] == "\n" ) { + $ret[] = substr($content, 0, $i); + $content = substr($content, $i + 1); + $i = 0; + } + } + } + $report['querys'] = count($ret); + foreach( $ret as $qr ) { + $re = @mysql_query($qr, $connection); + if( ! $re ) { + $report['errors'][] = "Query error: " . mysql_error(); + } + } + return $report; +} + +function createPngLogo($filePng, $text) { + $im = imagecreatetruecolor(162, 50); + $orange = imagecolorallocate($im, 140, 120, 0); + $white = imagecolorallocate($im, 255, 255, 255); + $black = imagecolorallocate($im, 0, 0, 0); + $grey = imagecolorallocate($im, 100, 100, 100); + $yellow = imagecolorallocatealpha($im, 255, 255, 10, 95); + $red = imagecolorallocatealpha($im, 255, 10, 10, 95); + $blue = imagecolorallocatealpha($im, 10, 10, 255, 95); + $transparent = imagecolorallocatealpha($im, 0, 0, 0, 127); + + imagefill($im, 0, 0, $white); + imagestring($im, 4, 50, 14, $text, $orange); + + // drawing 3 overlapped circle + imagefilledellipse($im, 25, 20, 27, 25, $yellow); + imagefilledellipse($im, 15, 30, 27, 25, $red); + imagefilledellipse($im, 30, 30, 27, 25, $blue); + + imagefill($im, 0, 0, $transparent); + imagesavealpha($im, true); + imagepng($im, $filePng); + + $aux = explode(PATH_SEP, $filePng); + $auxName = $aux[count($aux) - 2] . PATH_SEP . $aux[count($aux) - 1]; + $iSize = filesize($filePng); + printf("saved %s bytes in file %s [%s]\n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($auxName, 'INFO'), pakeColor::colorize($aux[count($aux) - 1], 'INFO')); + +} + +function run_generate_unit_test_class($task, $args) { + //the class filename in the first argument + $class = $args[0]; + + //try to find the class in classes directory + $classFilename = PATH_CORE . 'classes' . PATH_SEP . 'class.' . $args[0] . '.php'; + if( file_exists($classFilename) ) + printf("class found in %s \n", pakeColor::colorize($classFilename, 'INFO')); + else { + printf("class %s not found \n", pakeColor::colorize($class, 'ERROR')); + exit(0); + } + + include ('test' . PATH_SEP . 'bootstrap' . PATH_SEP . 'unit.php'); + G::LoadThirdParty('smarty/libs', 'Smarty.class'); + G::LoadSystem('error'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('form'); + G::LoadClass('application'); + require_once ('propel/Propel.php'); + + require_once ($classFilename); + + $unitFilename = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . 'unitTest.tpl'; + + $smarty = new Smarty(); + + $smarty->template_dir = PATH_GULLIVER . 'bin' . PATH_SEP . 'tasks'; + $smarty->compile_dir = PATH_SMARTY_C; + $smarty->cache_dir = PATH_SMARTY_CACHE; + $smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + + printf("using unit file in %s \n", pakeColor::colorize($unitFilename, 'INFO')); + $smarty->assign('className', ucwords($class)); + $smarty->assign('classFile', $class); + + //get the method list + $reflect = new ReflectionClass($class); + $methods = array (); + $testItems = 0; + foreach( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach( $reflectmethod->getParameters() as $key => $row ) { + if( $params != '' ) + $params .= ', '; + $params .= '$' . $row->name; + } + $testItems ++; + $methods[$reflectmethod->getName()] = $params; + } + + $smarty->assign('methods', $methods); + $smarty->assign('testItems', (count($methods) * 2) + 3); + $smarty->assign('cantMethods', count($methods)); + // $smarty->assign('llave', '{' ); + + + // fetch smarty output + $content = $smarty->fetch($unitFilename); + + //saving the content in the output file + if( defined('MAIN_POFILE') && MAIN_POFILE != '' ) + $unitFilename = PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP . MAIN_POFILE . PATH_SEP . 'class' . ucwords($class) . 'Test.php'; + else + $unitFilename = PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP . 'class' . ucwords($class) . 'Test.php'; + printf("creating unit file in %s \n", pakeColor::colorize($unitFilename, 'INFO')); + $fp = fopen($unitFilename, 'w'); + fprintf($fp, $content); + fclose($fp); + + exit(0); +} + +function convertPhpName($f) { + $upper = true; + $res = ''; + for( $i = 0; $i < strlen($f); $i ++ ) { + $car = substr($f, $i, 1); + if( $car == '_' ) + $upper = true; + else { + if( $upper ) { + $res .= strtoupper($car); + $upper = false; + } else + $res .= strtolower($car); + } + } + return $res; +} + +function copyPluginFile($tplName, $fName, $class) { + $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $class . PATH_SEP . $class . PATH_SEP; + $pluginFilename = $pluginOutDirectory . $fName; + $fileTpl = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . $tplName . '.tpl'; + $content = file_get_contents($fileTpl); + $iSize = file_put_contents($pluginFilename, $content); + printf("saved %s bytes in file %s \n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($tplName, 'INFO')); +} + +function savePluginFile($fName, $tplName, $class, $tableName, $fields = null) { + $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $class . PATH_SEP; + + $pluginFilename = $pluginOutDirectory . $fName; + + $pluginTpl = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . $tplName . '.tpl'; + $template = new TemplatePower($pluginTpl); + $template->prepare(); + $template->assign('className', $class); + $template->assign('tableName', $tableName); + $template->assign('menuId', 'ID_' . strtoupper($class)); + + if( is_array($fields) ) { + foreach( $fields as $block => $data ) { + $template->gotoBlock("_ROOT"); + if( is_array($data) ) + foreach( $data as $rowId => $row ) { + $template->newBlock($block); + foreach( $row as $key => $val ) + $template->assign($key, $val); + } + else + $template->assign($block, $data); + } + } + + $content = $template->getOutputContent(); + $iSize = file_put_contents($pluginFilename, $content); + printf("saved %s bytes in file %s [%s]\n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($fName, 'INFO'), pakeColor::colorize($tplName, 'INFO')); +} + +function run_generate_crud($task, $args) { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + //the class filename in the first argument + if( ! isset($args[0]) ) { + printf("Error: %s\n", pakeColor::colorize('you must specify a valid classname ', 'ERROR')); + exit(0); + } + $class = $args[0]; + //second parameter is the table name, by default is the same classname in uppercase. + $tableName = isset($args[1]) ? $args[1] : strtoupper($class); + + //try to find the class in classes directory + $classFilename = PATH_CORE . 'classes' . PATH_SEP . 'model' . PATH_SEP . $args[0] . '.php'; + if( file_exists($classFilename) ) + printf("class found in %s \n", pakeColor::colorize($classFilename, 'INFO')); + else { + printf("class %s not found \n", pakeColor::colorize($class, 'ERROR')); + exit(0); + } + require_once ("propel/Propel.php"); + require_once ($classFilename); + G::LoadSystem('templatePower'); + + Propel::init(PATH_CORE . "config/databases.php"); + + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + $dirs = explode(PATH_SEP, PATH_HOME); + print_r($dirs); + $projectName = $dirs[count($dirs) - 1]; + + // if ( strlen ( trim( $projectName) ) == 0 ) { + // printf("Project name not found \n", pakeColor::colorize( $class, 'ERROR')); + // exit (0); + // } + + + // printf("using Project Name %s \n", pakeColor::colorize( $projectName, 'INFO')); + + + // $pluginDirectory = PATH_PLUGINS . $class; + // $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $class; + // + // G::verifyPath ( $pluginOutDirectory, true ); + // G::verifyPath ( $pluginOutDirectory. PATH_SEP . $class, $pluginDirectory ); + + + //G::verifyPath ( $pluginDirectory, true ); + + + // //main php file + // savePluginFile ( $class . '.php', 'pluginMainFile', $class, $tableName ); + + + //menu + savePluginFile($class . PATH_SEP . 'menu' . $class . '.php', 'pluginMenu', $class, $tableName); + + //default list + savePluginFile($class . PATH_SEP . $class . 'List.php', 'pluginList', $class, $tableName); + + //parse the schema file in order to get Table definition + $schemaFile = PATH_CORE . 'config' . PATH_SEP . 'schema.xml'; + $xmlContent = file_get_contents($schemaFile); + $s = simplexml_load_file($schemaFile); + + //default xmlform + //load the $fields array with fields data for an xmlform. + $fields = array (); + foreach( $s->table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + //print $column['name'] . ' ' .$column['type'] . ' ' .$column['size'] . ' ' .$column['required'] . ' ' .$column['primaryKey']; + //print "\n"; + $maxlength = $column['size']; + $size = ($maxlength > 60) ? 60 : $maxlength; + $type = $column['type']; + $field = array ( + 'name' => $column['name'], + 'type' => $type, + 'size' => $size, + 'maxlength' => $maxlength + ); + $fields['fields'][] = $field; + } + } + savePluginFile($class . PATH_SEP . $class . '.xml', 'pluginXmlform', $class, $tableName, $fields); + + die(); + //xmlform for list + //load the $fields array with fields data for PagedTable xml. + $fields = array (); + $primaryKey = ''; + foreach( $s->table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + //print $column['name'] . ' ' .$column['type'] . ' ' .$column['size'] . ' ' .$column['required'] . ' ' .$column['primaryKey']; + //print "\n"; + $size = ($column['size'] > 30) ? 30 : $column['size']; + $type = $column['type']; + if( $column['primaryKey'] ) + if( $primaryKey == '' ) + $primaryKey .= '@@' . $column['name']; + else + $primaryKey .= '|@@' . $column['name']; + + $field = array ( + 'name' => $column['name'], + 'type' => $type, + 'size' => $size + ); + $fields['fields'][] = $field; + } + } + $fields['primaryKey'] = $primaryKey; + savePluginFile($class . PATH_SEP . $class . 'List.xml', 'pluginXmlformList', $class, $tableName, $fields); + + //default edit + $fields = array (); + $index = 0; + $keylist = ''; + foreach( $s->table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + $name = $column['name']; + $phpName = convertPhpName($name); + $field = array ( + 'name' => $name, + 'phpName' => $phpName, + 'index' => $index ++ + ); + if( $column['primaryKey'] ) { + if( $keylist == '' ) + $keylist .= '$' . $phpName; + else + $keylist .= ', $' . $phpName; + $fields['keys'][] = $field; + //$index++; + } + $fields['fields'][] = $field; + $fields['fields2'][] = $field; + } + } + $fields['keylist'] = $keylist; + savePluginFile($class . PATH_SEP . $class . 'Edit.php', 'pluginEdit', $class, $tableName, $fields); + savePluginFile($class . PATH_SEP . $class . 'Save.php', 'pluginSave', $class, $tableName, $fields); + + if( ! PHP_OS == "WINNT" ) { + printf("creting symlinks %s \n", pakeColor::colorize($pluginDirectory, 'INFO')); + symlink($pluginOutDirectory . PATH_SEP . $class . '.php', PATH_PLUGINS . $class . '.php'); + symlink($pluginOutDirectory . PATH_SEP . $class, $pluginDirectory); + } + exit(0); +} + +function addTarFolder($tar, $pathBase, $pluginHome) { + $aux = explode(PATH_SEP, $pathBase); + //print $aux[count($aux) -2 ] . "\n"; + if( $aux[count($aux) - 2] == '.svn' ) + return; + + if( $handle = opendir($pathBase) ) { + while( false !== ($file = readdir($handle)) ) { + if( is_file($pathBase . $file) ) { + //print "file $file \n"; + $tar->addModify($pathBase . $file, '', $pluginHome); + } + if( is_dir($pathBase . $file) && $file != '..' && $file != '.' ) { + //print "dir $pathBase$file \n"; + addTarFolder($tar, $pathBase . $file . PATH_SEP, $pluginHome); + } + } + closedir($handle); + } +} + +function run_pack_plugin($task, $args) { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + //the plugin name in the first argument + if( ! isset($args[0]) ) { + printf("Error: %s\n", pakeColor::colorize('you must specify a valid name for the plugin', 'ERROR')); + exit(0); + } + $pluginName = $args[0]; + + require_once ("propel/Propel.php"); + G::LoadSystem('templatePower'); + + $pluginDirectory = PATH_PLUGINS . $pluginName; + $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName; + $pluginHome = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName; + + //verify if plugin exists, + $pluginClassFilename = PATH_PLUGINS . $pluginName . PATH_SEP . 'class.' . $pluginName . '.php'; + $pluginFilename = PATH_PLUGINS . $pluginName . '.php'; + if( ! is_file($pluginClassFilename) ) { + printf("The plugin %s does not exist in this file %s \n", pakeColor::colorize($pluginName, 'ERROR'), pakeColor::colorize($pluginClassFilename, 'INFO')); + die(); + } + G::LoadClass('plugin'); + require_once ($pluginFilename); + + $oPluginRegistry = & PMPluginRegistry::getSingleton(); + $pluginDetail = $oPluginRegistry->getPluginDetails($pluginName . '.php'); + $fileTar = $pluginHome . PATH_SEP . $pluginName . '-' . $pluginDetail->iVersion . '.tar'; + G::LoadThirdParty('pear/Archive', 'Tar'); + $tar = new Archive_Tar($fileTar); + $tar->_compress = false; + + $pathBase = $pluginHome . PATH_SEP . $pluginName . PATH_SEP; + $tar->createModify($pluginHome . PATH_SEP . $pluginName . '.php', '', $pluginHome); + addTarFolder($tar, $pathBase, $pluginHome); + $aFiles = $tar->listContent(); + + foreach( $aFiles as $key => $val ) { + printf(" %6d %s \n", $val['size'], pakeColor::colorize($val['filename'], 'INFO')); + } + printf("File created in %s \n", pakeColor::colorize($fileTar, 'INFO')); + $filesize = sprintf("%5.2f", filesize($fileTar) / 1024); + printf("Filesize %s Kb \n", pakeColor::colorize($filesize, 'INFO')); +} +function run_new_plugin($task, $args) { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + //the plugin name in the first argument + if( ! isset($args[0]) ) { + printf("Error: %s\n", pakeColor::colorize('you must specify a valid name for the plugin', 'ERROR')); + exit(0); + } + $pluginName = $args[0]; + + require_once ("propel/Propel.php"); + G::LoadSystem('templatePower'); + + Propel::init(PATH_CORE . "config/databases.php"); + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + $pluginDirectory = PATH_PLUGINS . $pluginName; + $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName; + $pluginHome = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName . PATH_SEP . $pluginName; + + //verify if plugin exists, and then ask for overwrite + $pluginClassFilename = PATH_PLUGINS . $pluginName . PATH_SEP . 'class.' . $pluginName . '.php'; + if( is_file($pluginClassFilename) ) { + printf("The plugin %s exists in this file %s \n", pakeColor::colorize($pluginName, 'ERROR'), pakeColor::colorize($pluginClassFilename, 'INFO')); + $overwrite = strtolower(prompt('Do you want to create a new plugin? [Y/n]')); + if( $overwrite == 'n' ) + die(); + } + + printf("creating plugin directory %s \n", pakeColor::colorize($pluginOutDirectory, 'INFO')); + + G::verifyPath($pluginOutDirectory, true); + G::verifyPath($pluginHome . PATH_SEP . 'classes', true); + G::verifyPath($pluginHome . PATH_SEP . 'public_html', true); + G::verifyPath($pluginHome . PATH_SEP . 'config', true); + G::verifyPath($pluginHome . PATH_SEP . 'data', true); + + //config + savePluginFile($pluginName . PATH_SEP . 'config' . PATH_SEP . 'schema.xml', 'pluginSchema.xml', $pluginName, $pluginName); + savePluginFile($pluginName . PATH_SEP . 'config' . PATH_SEP . 'propel.ini', 'pluginPropel.ini', $pluginName, $pluginName); + savePluginFile($pluginName . PATH_SEP . 'config' . PATH_SEP . 'propel.mysql.ini', 'pluginPropel.mysql.ini', $pluginName, $pluginName); + + //create a logo to use instead the Workspace logo + $changeLogo = strtolower(prompt('Change system logo [y/N]')); + + $fields = array (); + $fields['phpClassName'] = $pluginName; + if( $changeLogo == 'y' ) { + $filePng = $pluginHome . PATH_SEP . 'public_html' . PATH_SEP . $pluginName . '.png'; + createPngLogo($filePng, $pluginName); + $fields['changeLogo'][] = array ( + 'className' => $pluginName + ); + } + + //menu + + + $menu = strtolower(prompt('Create an example Page [Y/n]')); + + if( $menu == 'y' ) { + + $fields['menu'][] = array ( + 'className' => $pluginName + ); + savePluginFile($pluginName . PATH_SEP . 'menu' . $pluginName . '.php', 'pluginMenu', $pluginName, $pluginName, $fields); + savePluginFile($pluginName . PATH_SEP . $pluginName . 'List.php', 'pluginWelcome.php', $pluginName, $pluginName); + savePluginFile($pluginName . PATH_SEP . 'welcome.xml', 'welcome.xml', $pluginName, $pluginName); + } + + //RBAC features + $classNameUpperCase = strtoupper($pluginName); + //Create a new Permission a new role + $newPermission = strtolower(prompt("Create the Role 'PROCESSMAKER_$classNameUpperCase' and \n the Permission 'PM_$classNameUpperCase' [y/N]")); + if( $newPermission == 'y' ) { + $fields['createPermission'][] = array ( + 'className' => $classNameUpperCase + ); + } + + //Redirect + $redirect = strtolower(prompt("Create a Redirect Login for the Role 'PROCESSMAKER_$classNameUpperCase' [y/N]")); + if( $redirect == 'y' ) { + $fields['redirectLogin'][] = array ( + 'className' => $classNameUpperCase + ); + } + + $externalStep = strtolower(prompt('Create external step for Processmaker[y/N]')); + if( $externalStep == 'y' ) { + $fields['externalStep'][] = array ( + 'className' => $pluginName, + 'GUID' => G::generateUniqueID() + ); + savePluginFile($pluginName . PATH_SEP . 'step' . $pluginName . '.php', 'pluginStep', $pluginName, $pluginName); + } + + $onTransit = strtolower(prompt('Create an "On transit Page" [y/N]')); + if( $onTransit == 'y' ) { + $fields['ontransit'][] = array ( + 'className' => $pluginName + ); + savePluginFile($pluginName . PATH_SEP . 'menu' . $pluginName . 'OnTransit.php', 'pluginMenuOnTransit', $pluginName, $pluginName, $fields); + savePluginFile($pluginName . PATH_SEP . $pluginName . 'OnTransitList.php', 'pluginOnTransitList.php', $pluginName, $pluginName); + savePluginFile($pluginName . PATH_SEP . $pluginName . 'OnTransitList.xml', 'pluginOnTransitList.xml', $pluginName, $pluginName); + copyPluginFile('pluginPaged-table.html', 'paged-table.html', $pluginName); + } + + $dashboard = strtolower(prompt('Create an element for the Processmaker Dashboard [y/N]')); + if( $dashboard == 'y' ) { + $fields['dashboard'][] = array ( + 'className' => $pluginName + ); + savePluginFile($pluginName . PATH_SEP . 'drawChart.php', 'pluginDrawChart.php', $pluginName, $pluginName, $fields); + } + + $report = strtolower(prompt('Create a Report for Processmaker [y/N]')); + if( $report == 'y' ) { + $fields['report'][] = array ( + 'className' => $pluginName + ); + savePluginFile($pluginName . PATH_SEP . 'report.xml', 'pluginReport.xml', $pluginName, $pluginName, $fields); + } + + $report = strtolower(prompt('Create a PmFunction Class for extend Processmaker [y/N]')); + if( $report == 'y' ) { + $fields['PmFunction'][] = array ( + 'className' => $pluginName + ); + savePluginFile($pluginName . PATH_SEP . 'classes' . PATH_SEP . 'class.pmFunctions.php', 'class.pmFunctions.php', $pluginName, $pluginName, $fields); + } + + //main php file + savePluginFile($pluginName . '.php', 'pluginMainFile', $pluginName, $pluginName, $fields); + savePluginFile($pluginName . PATH_SEP . 'class.' . $pluginName . '.php', 'pluginClass', $pluginName, $pluginName, $fields); + + if( ! PHP_OS == "WINNT" ) { + printf("creating symlinks %s \n", pakeColor::colorize($pluginDirectory, 'INFO')); + symlink($pluginOutDirectory . PATH_SEP . $pluginName . '.php', PATH_PLUGINS . $pluginName . '.php'); + symlink($pluginOutDirectory . PATH_SEP . $pluginName, $pluginDirectory); + } + + exit(0); +} + +function run_create_poedit_file($task, $args) { + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + //the output language .po file + $lgOutId = isset($args[0]) ? $args[0] : 'en'; + $countryOutId = isset($args[1]) ? strtoupper($args[1]) : 'US'; + $verboseFlag = isset($args[2]) ? $args[2] == true : false; + + require_once ("propel/Propel.php"); + require_once ("classes/model/Translation.php"); + require_once ("classes/model/Language.php"); + require_once ("classes/model/IsoCountry.php"); + + Propel::init(PATH_CORE . "config/databases.php"); + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['propel']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + printf("checking Language table \n"); + $c = new Criteria(); + $c->add(LanguagePeer::LAN_ENABLED, "1"); + $c->addor(LanguagePeer::LAN_ENABLED, "0"); + + $languages = LanguagePeer::doSelect($c); + $langs = array (); + $lgIndex = 0; + $findLang = false; + $langDir = 'english'; + $langId = 'en'; + foreach( $languages as $rowid => $row ) { + $lgIndex ++; + $langs[$row->getLanId()] = $row->getLanName(); + if( $lgOutId != '' && $lgOutId == $row->getLanId() ) { + $findLang = true; + $langDir = strtolower($row->getLanName()); + $langId = $row->getLanId(); + } + } + printf("read %s entries from language table\n", pakeColor::colorize($lgIndex, 'INFO')); + + printf("checking iso_country table \n"); + $c = new Criteria(); + $c->add(IsoCountryPeer::IC_UID, NULL, Criteria::ISNOTNULL); + + $countries = IsoCountryPeer::doSelect($c); + $countryIndex = 0; + $findCountry = false; + $countryDir = 'UNITED STATES'; + $countryId = 'US'; + foreach( $countries as $rowid => $row ) { + $countryIndex ++; + if( $countryOutId != '' && $countryOutId == $row->getICUid() ) { + $findCountry = true; + $countryDir = strtoupper($row->getICName()); + $countryId = $row->getICUid(); + } + } + printf("read %s entries from iso_country table\n", pakeColor::colorize($countryIndex, 'INFO')); + + if( $findLang == false && $lgOutId != '' ) { + printf("%s \n", pakeColor::colorize("'$lgOutId' is not a valid language ", 'ERROR')); + die(); + } else { + printf("language: %s\n", pakeColor::colorize($langDir, 'INFO')); + } + + if( $findCountry == false && $countryOutId != '' ) { + printf("%s \n", pakeColor::colorize("'$countryOutId' is not a valid country ", 'ERROR')); + die(); + } else { + printf("country: [%s] %s\n", pakeColor::colorize($countryId, 'INFO'), pakeColor::colorize($countryDir, 'INFO')); + } + + if( $findCountry && $countryId != '' ) + $poeditOutFile = PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . $langDir . PATH_SEP . MAIN_POFILE . '.' . $langId . '_' . $countryId . '.po'; + else + $poeditOutFile = PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . $langDir . PATH_SEP . MAIN_POFILE . '.' . $langId . '.po'; + + printf("poedit file: %s\n", pakeColor::colorize($poeditOutFile, 'INFO')); + + $poeditOutPathInfo = pathinfo($poeditOutFile); + G::verifyPath($poeditOutPathInfo['dirname'], true); + $lf = "\n"; + $fp = fopen($poeditOutFile, 'w'); + fprintf($fp, "msgid \"\" \n"); + fprintf($fp, "msgstr \"\" \n"); + fprintf($fp, "\"Project-Id-Version: %s\\n\"\n", PO_SYSTEM_VERSION); + fprintf($fp, "\"POT-Creation-Date: \\n\"\n"); + fprintf($fp, "\"PO-Revision-Date: %s \\n\"\n", date('Y-m-d H:i+0100')); + fprintf($fp, "\"Last-Translator: Fernando Ontiveros\\n\"\n"); + fprintf($fp, "\"Language-Team: Colosa Developers Team \\n\"\n"); + fprintf($fp, "\"MIME-Version: 1.0 \\n\"\n"); + fprintf($fp, "\"Content-Type: text/plain; charset=utf-8 \\n\"\n"); + fprintf($fp, "\"Content-Transfer_Encoding: 8bit\\n\"\n"); + fprintf($fp, "\"X-Poedit-Language: %s\\n\"\n", ucwords($langDir)); + fprintf($fp, "\"X-Poedit-Country: %s\\n\"\n", $countryDir); + fprintf($fp, "\"X-Poedit-SourceCharset: utf-8\\n\"\n"); + + printf("checking translation table\n"); + + $c = new Criteria(); + $c->add(TranslationPeer::TRN_LANG, "en"); + + $translation = TranslationPeer::doSelect($c); + $trIndex = 0; + $trError = 0; + $langIdOut = $langId; //the output language, later we'll include the country too. + + + $arrayLabels = array (); + foreach( $translation as $rowid => $row ) { + $keyid = 'TRANSLATION/' . $row->getTrnCategory() . '/' . $row->getTrnId(); + if( trim($row->getTrnValue()) == '' ) { + printf("warning the key %s is empty.\n", pakeColor::colorize($keyid, 'ERROR')); + $trError ++; + } else { + $trans = TranslationPeer::retrieveByPK($row->getTrnCategory(), $row->getTrnId(), $langIdOut); + if( is_null($trans) ) { + $msgStr = $row->getTrnValue(); + } else { + $msgStr = $trans->getTrnValue(); + } + + $msgid = $row->getTrnValue(); + if( in_array($msgid, $arrayLabels) ) { + $newMsgid = '[' . $row->getTrnCategory() . '/' . $row->getTrnId() . '] ' . $msgid; + printf("duplicated key %s is renamed to %s.\n", pakeColor::colorize($msgid, 'ERROR'), pakeColor::colorize($newMsgid, 'INFO')); + $trError ++; + $msgid = $newMsgid; + } + + $arrayLabels[] = $msgid; + sort($arrayLabels); + + $trIndex ++; + fprintf($fp, "\n"); + fprintf($fp, "#: %s \n", $keyid); + //fprintf ( $fp, "#, php-format \n" ); + fprintf($fp, "# %s \n", strip_quotes($keyid)); + fprintf($fp, "msgid \"%s\" \n", strip_quotes($msgid)); + fprintf($fp, "msgstr \"%s\" \n", strip_quotes($msgStr)); + } + } + + printf("checking xmlform\n"); + printf("using directory %s \n", pakeColor::colorize(PATH_XMLFORM, 'INFO')); + + G::LoadThirdParty('pear/json', 'class.json'); + G::LoadThirdParty('smarty/libs', 'Smarty.class'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlformExtension'); + G::LoadSystem('form'); + + $langIdOut = $langId; //the output language, later we'll include the country too. + $exceptionFields = array ( + 'javascript', + 'hidden', + 'phpvariable', + 'private', + 'toolbar', + 'xmlmenu', + 'toolbutton', + 'cellmark', + 'grid' + ); + + $xmlfiles = pakeFinder::type('file')->name('*.xml')->in(PATH_XMLFORM); + $xmlIndex = 0; + $xmlError = 0; + $fieldsIndexTotal = 0; + $exceptIndexTotal = 0; + foreach( $xmlfiles as $xmlfileComplete ) { + $xmlIndex ++; + $xmlfile = str_replace(PATH_XMLFORM, '', $xmlfileComplete); + + //english version of dynaform + $form = new Form($xmlfile, '', 'en'); + $englishLabel = array (); + foreach( $form->fields as $nodeName => $node ) { + if( trim($node->label) != '' ) + $englishLabel[$node->name] = $node->label; + } + unset($form->fields); + unset($form->tree); + unset($form); + + //in this second pass, we are getting the target language labels + $form = new Form($xmlfile, '', $langIdOut); + $fieldsIndex = 0; + $exceptIndex = 0; + foreach( $form->fields as $nodeName => $node ) { + if( is_object($node) && isset($englishLabel[$node->name]) ) { + $msgid = trim($englishLabel[$node->name]); + $node->label = trim(str_replace(chr(10), '', $node->label)); + } else + $msgid = ''; + if( trim($msgid) != '' && ! in_array($node->type, $exceptionFields) ) { + //$msgid = $englishLabel [ $node->name ]; + $keyid = $xmlfile . '?' . $node->name; + if( in_array($msgid, $arrayLabels) ) { + $newMsgid = '[' . $keyid . '] ' . $msgid; + if( $verboseFlag ) + printf("duplicated key %s is renamed to %s.\n", pakeColor::colorize($msgid, 'ERROR'), pakeColor::colorize($newMsgid, 'INFO')); + $xmlError ++; + $msgid = $newMsgid; + } + + $arrayLabels[] = $msgid; + sort($arrayLabels); + + $comment1 = $xmlfile; + $comment2 = $node->type . ' - ' . $node->name; + fprintf($fp, "\n"); + fprintf($fp, "#: %s \n", $keyid); + // fprintf ( $fp, "#, php-format \n" ); + fprintf($fp, "# %s \n", strip_quotes($comment1)); + fprintf($fp, "# %s \n", strip_quotes($comment2)); + fprintf($fp, "msgid \"%s\" \n", strip_quotes($msgid)); + fprintf($fp, "msgstr \"%s\" \n", strip_quotes($node->label)); + //fprintf ( $fp, "msgstr \"%s\" \n", strip_quotes( utf8_encode( trim($node->label) ) )); + $fieldsIndex ++; + $fieldsIndexTotal ++; + } + + else { + if( is_object($node) && ! in_array($node->type, $exceptionFields) ) { + if( isset($node->value) && strpos($node->value, 'G::LoadTranslation') !== false ) { + $exceptIndex ++; + //print ($node->value); + } else { + printf("Error: xmlform %s has no english definition for %s [%s]\n", pakeColor::colorize($xmlfile, 'ERROR'), pakeColor::colorize($node->name, 'INFO'), pakeColor::colorize($node->type, 'INFO')); + $xmlError ++; + } + } else { + $exceptIndex ++; + if( $verboseFlag ) + printf("%s %s in %s\n", $node->type, pakeColor::colorize($node->name, 'INFO'), pakeColor::colorize($xmlfile, 'INFO')); + } + } + } + unset($form->fields); + unset($form->tree); + unset($form); + printf("xmlform: %s has %s fields and %s exceptions \n", pakeColor::colorize($xmlfile, 'INFO'), pakeColor::colorize($fieldsIndex, 'INFO'), pakeColor::colorize($exceptIndex, 'INFO')); + $exceptIndexTotal += $exceptIndex; + } + + fclose($fp); + printf("added %s entries from translation table\n", pakeColor::colorize($trIndex, 'INFO')); + printf("added %s entries from %s xmlforms \n", pakeColor::colorize($fieldsIndexTotal, 'INFO'), pakeColor::colorize($xmlIndex, 'INFO')); + + if( $trError > 0 ) { + printf("there are %s errors in tranlation table\n", pakeColor::colorize($trError, 'ERROR')); + } + if( $xmlError > 0 ) { + printf("there are %s errors and %s exceptions in xmlforms\n", pakeColor::colorize($xmlError, 'ERROR'), pakeColor::colorize($exceptIndexTotal, 'ERROR')); + } + + exit(0); + +//to do: leer los html templates +} + +function create_file_from_tpl($tplName, $newFilename, $fields = NULL) { + global $pathHome; + global $projectName; + + $httpdTpl = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . $tplName . '.tpl'; + if( substr($newFilename, 0, 1) == PATH_SEP ) + $httpFilename = $newFilename; + else + $httpFilename = $pathHome . PATH_SEP . $newFilename; + $template = new TemplatePower($httpdTpl); + $template->prepare(); + $template->assignGlobal('pathHome', $pathHome); + $template->assignGlobal('projectName', $projectName); + $template->assignGlobal('rbacProjectName', strtoupper($projectName)); + $template->assignGlobal('siglaProjectName', substr(strtoupper($projectName), 0, 3)); + $template->assignGlobal('propel.output.dir', '{propel.output.dir}'); + + if( is_array($fields) ) { + foreach( $fields as $block => $data ) { + $template->gotoBlock("_ROOT"); + if( is_array($data) ) + foreach( $data as $rowId => $row ) { + $template->newBlock($block); + foreach( $row as $key => $val ) { + if( is_array($val) ) { + // $template->newBlock( $key ); + foreach( $val as $key2 => $val2 ) { + if( is_array($val2) ) { + $template->newBlock($key); + foreach( $val2 as $key3 => $val3 ) + $template->assign($key3, $val3); + } + } + } else + $template->assign($key, $val); + } + } + else + $template->assign($block, $data); + } + } + + $content = $template->getOutputContent(); + $iSize = file_put_contents($httpFilename, $content); + printf("saved %s bytes in file %s \n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($tplName, 'INFO')); +} + +function copy_file_from_tpl($tplName, $newFilename) { + global $pathHome; + global $projectName; + $httpdTpl = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . $tplName . '.tpl'; + $httpFilename = $pathHome . PATH_SEP . $newFilename; + $content = file_get_contents($httpdTpl); + $iSize = file_put_contents($httpFilename, $content); + printf("saved %s bytes in file %s \n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($tplName, 'INFO')); +} + +function copy_file($newFilename) { + global $pathHome; + $httpdTpl = PATH_HOME . $newFilename; + $httpFilename = $pathHome . PATH_SEP . $newFilename; + $content = file_get_contents($httpdTpl); + $iSize = file_put_contents($httpFilename, $content); + printf("saved %s bytes in file %s \n", pakeColor::colorize($iSize, 'INFO'), pakeColor::colorize($newFilename, 'INFO')); +} + +function run_new_project($task, $args) { + global $pathHome; + global $projectName; + //the class filename in the first argument + $projectName = $args[0]; + + if( trim($projectName) == '' ) { + printf("Error: %s\n", pakeColor::colorize("you must specify a valid name for the project", 'ERROR')); + exit(0); + } + $createProject = strtolower(prompt("Do you want to create the project '$projectName' ? [Y/n]")); + if( $createProject == 'n' ) + die(); + + G::LoadSystem('templatePower'); + define('PATH_SHARED', PATH_SEP . 'shared' . PATH_SEP . $projectName . '_data' . PATH_SEP); + $pathHome = PATH_TRUNK . $projectName; + printf("creating project %s in %s\n", pakeColor::colorize($projectName, 'INFO'), pakeColor::colorize($pathHome, 'INFO')); + + define('G_ENVIRONMENT', G_DEV_ENV); + require_once ("propel/Propel.php"); + + //create project.conf for httpd conf + //$dbFile = PATH_TRUNK . $projectName . PATH_SEP . 'shared' . PATH_SEP . 'sites'. PATH_SEP . 'dev'. PATH_SEP . 'db.php'; + $dbFile = PATH_SEP . PATH_SHARED . 'sites' . PATH_SEP . $projectName . PATH_SEP . 'db.php'; + $dbn = "db_" . $projectName; + $dbrn = "rb_" . $projectName; + $dbnpass = substr(G::GenerateUniqueId(), 0, 8); + if( 1 || ! file_exists($dbFile) ) { + if( ! defined('HASH_INSTALLATION') ) { + printf("%s\n", pakeColor::colorize('HASH INSTALLATION is invalid or does not exist. Please check the paths_installed.php file', 'ERROR')); + exit(0); + } + $dbOpt = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + $connectionDatabase = mysql_connect($dbOpt[0], $dbOpt[1], $dbOpt[2]); + if( ! $connectionDatabase ) { + printf("%s\n", pakeColor::colorize('HASH INSTALLATION has invalid credentials. Please check the paths_installed.php file', 'ERROR')); + exit(0); + } + printf("creating database %s \n", pakeColor::colorize($dbn, 'INFO')); + $q = "CREATE DATABASE IF NOT EXISTS $dbn DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"; + $ac = @mysql_query($q, $connectionDatabase); + if( ! $ac ) { + printf("%s\n", pakeColor::colorize(mysql_error(), 'ERROR')); + exit(0); + } + printf("creating database %s \n", pakeColor::colorize($dbrn, 'INFO')); + $q = "CREATE DATABASE IF NOT EXISTS $dbrn DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"; + $ac = @mysql_query($q, $connectionDatabase); + if( ! $ac ) { + printf("%s\n", pakeColor::colorize(mysql_error(), 'ERROR')); + exit(0); + } + $q = "GRANT ALL PRIVILEGES ON `$dbn`.* TO $dbn@'localhost' IDENTIFIED BY '$dbnpass' WITH GRANT OPTION"; + $ac = @mysql_query($q, $connectionDatabase); + if( ! $ac ) { + printf("%s\n", pakeColor::colorize(mysql_error(), 'ERROR')); + exit(0); + } + $q = "GRANT ALL PRIVILEGES ON `$dbrn`.* TO $dbn@'localhost' IDENTIFIED BY '$dbnpass' WITH GRANT OPTION"; + $ac = @mysql_query($q, $connectionDatabase); + if( ! $ac ) { + printf("%s\n", pakeColor::colorize(mysql_error(), 'ERROR')); + exit(0); + } + $rbSql = PATH_RBAC_MYSQL_DATA . 'schema.sql'; + printf("executing %s \n", pakeColor::colorize($rbSql, 'INFO')); + mysql_select_db($dbrn, $connectionDatabase); + $qrs = query_sql_file($rbSql, $connectionDatabase); + + $q = "INSERT INTO `USERS` VALUES ('00000000000000000000000000000001','admin',md5('admin'),'Administrator','','admin@colosa.com','2020-01-01','2007-08-03 12:24:36','2008-02-13 07:24:07',1);"; + $ac = @mysql_query($q, $connectionDatabase); + $q = "INSERT INTO `USERS` VALUES ('00000000000000000000000000000002','operator',md5('operator'),'Operator','','operator@colosa.com','2020-01-01','2007-08-03 12:24:36','2008-02-13 07:24:07',1);"; + $ac = @mysql_query($q, $connectionDatabase); + + //database wf_ db_ + $dbInsertSql = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . 'db_insert.sql'; + printf("executing %s \n", pakeColor::colorize($dbInsertSql, 'INFO')); + mysql_select_db($dbn, $connectionDatabase); + $qrs = query_sql_file($dbInsertSql, $connectionDatabase); + + G::mk_dir(PATH_SHARED . 'sites' . PATH_SEP); + G::mk_dir(PATH_SHARED . 'sites' . PATH_SEP . $projectName); + + $dbFields['rootUser'] = $dbn; + $dbFields['rootPass'] = $dbnpass; + create_file_from_tpl('db.php', $dbFile, $dbFields); + } + + global $G_ENVIRONMENTS; + $G_ENVIRONMENTS['DEVELOPMENT']['dbfile'] = $dbFile; + //print_r ( $G_ENVIRONMENTS ); + + + Propel::init(PATH_CORE . "config/databases.php"); + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + $rbacProjectName = strtoupper($projectName); + + G::LoadSystem('rbac'); + $RBAC = RBAC::getSingleton(); + $RBAC->sSystem = $rbacProjectName; + $RBAC->initRBAC(); + $RBAC->createSystem($rbacProjectName); + $RBAC->createPermision(substr($rbacProjectName, 0, 3) . '_LOGIN'); + $RBAC->createPermision(substr($rbacProjectName, 0, 3) . '_ADMIN'); + $RBAC->createPermision(substr($rbacProjectName, 0, 3) . '_OPERATOR'); + $systemData = $RBAC->systemObj->LoadByCode($rbacProjectName); + $roleData['ROL_UID'] = G::GenerateUniqueId(); + $roleData['ROL_PARENT'] = ''; + $roleData['ROL_SYSTEM'] = $systemData['SYS_UID']; + $roleData['ROL_CODE'] = substr($rbacProjectName, 0, 3) . '_ADMIN'; + $roleData['ROL_CREATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_STATUS'] = '1'; + $RBAC->createRole($roleData); + + $roleData['ROL_UID'] = G::GenerateUniqueId(); + $roleData['ROL_PARENT'] = ''; + $roleData['ROL_SYSTEM'] = $systemData['SYS_UID']; + $roleData['ROL_CODE'] = substr($rbacProjectName, 0, 3) . '_OPERATOR'; + $roleData['ROL_CREATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_STATUS'] = '1'; + $RBAC->createRole($roleData); + $roleData = $RBAC->rolesObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_ADMIN'); + + //Assign permissions to ADMIN + $roleData = $RBAC->rolesObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_ADMIN'); + $permData = $RBAC->permissionsObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_LOGIN'); + $RBAC->assignPermissionToRole($roleData['ROL_UID'], $permData['PER_UID']); + $permData = $RBAC->permissionsObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_ADMIN'); + $RBAC->assignPermissionToRole($roleData['ROL_UID'], $permData['PER_UID']); + $userRoleData['ROL_UID'] = $roleData['ROL_UID']; + $userRoleData['USR_UID'] = '00000000000000000000000000000001'; + $RBAC->assignUserToRole($userRoleData); + + //Assign permissions to OPERATOR + $roleData = $RBAC->rolesObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_OPERATOR'); + $permData = $RBAC->permissionsObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_LOGIN'); + $RBAC->assignPermissionToRole($roleData['ROL_UID'], $permData['PER_UID']); + $permData = $RBAC->permissionsObj->LoadByCode(substr($rbacProjectName, 0, 3) . '_OPERATOR'); + $RBAC->assignPermissionToRole($roleData['ROL_UID'], $permData['PER_UID']); + + $userRoleData['ROL_UID'] = $roleData['ROL_UID']; + $userRoleData['USR_UID'] = '00000000000000000000000000000002'; + $RBAC->assignUserToRole($userRoleData); + + //create folder and structure + G::mk_dir($pathHome); + G::mk_dir($pathHome . PATH_SEP . 'public_html'); + G::mk_dir($pathHome . PATH_SEP . 'public_html' . PATH_SEP . 'images'); + G::mk_dir($pathHome . PATH_SEP . 'public_html' . PATH_SEP . 'skins'); + G::mk_dir($pathHome . PATH_SEP . 'public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green'); + G::mk_dir($pathHome . PATH_SEP . 'public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images'); + G::mk_dir($pathHome . PATH_SEP . 'engine'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'classes'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'classes' . PATH_SEP . 'model'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'map'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'config'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'content'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'content' . PATH_SEP . 'languages'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'content' . PATH_SEP . 'translations'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'data'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'data' . PATH_SEP . 'mysql'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'js'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'js' . PATH_SEP . 'labels'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'menus'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'methods'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'users'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'skins'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'templates'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'test'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'test' . PATH_SEP . 'bootstrap'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'test' . PATH_SEP . 'fixtures'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'test' . PATH_SEP . 'unit'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'xmlform'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'gulliver'); + G::mk_dir($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'users'); + + //create project.conf for httpd conf + create_file_from_tpl('httpd.conf', $projectName . '.conf'); + create_file_from_tpl('sysGeneric.php', 'public_html' . PATH_SEP . 'sysGeneric.php'); + copy_file_from_tpl('bm.jpg', 'public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'bm.jpg'); + copy_file_from_tpl('bsm.jpg', 'public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'bsm.jpg'); + create_file_from_tpl('index.html', 'public_html' . PATH_SEP . 'index.html'); + create_file_from_tpl('paths.php', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php'); + create_file_from_tpl('defines.php', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'defines.php'); + create_file_from_tpl('databases.php', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'); + $fields['dbName'] = 'mysql'; + create_file_from_tpl('propel.ini', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'propel.ini', $fields); + create_file_from_tpl('propel.ini', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'propel.mysql.ini', $fields); + + if( file_exists($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'schema.xml') ) { + $createSchema = strtolower(prompt("schema.xml exists!. Do you want to overwrite the schema.xml file? [y/N]")); + if( $createSchema == 'y' ) { + create_file_from_tpl('schema.xml', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'schema.xml'); + } + } else + create_file_from_tpl('schema.xml', 'engine' . PATH_SEP . 'config' . PATH_SEP . 'schema.xml'); + + create_file_from_tpl('sysLogin.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login' . PATH_SEP . 'sysLogin.php'); + create_file_from_tpl('login.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login' . PATH_SEP . 'login.php'); + create_file_from_tpl('authentication.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login' . PATH_SEP . 'authentication.php'); + create_file_from_tpl('welcome.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login' . PATH_SEP . 'welcome.php'); + create_file_from_tpl('dbInfo.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'login' . PATH_SEP . 'dbInfo.php'); + create_file_from_tpl('usersList.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'users' . PATH_SEP . 'usersList.php'); + create_file_from_tpl('rolesList.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'users' . PATH_SEP . 'rolesList.php'); + create_file_from_tpl('permissionsList.php', 'engine' . PATH_SEP . 'methods' . PATH_SEP . 'users' . PATH_SEP . 'permissionsList.php'); + create_file_from_tpl('sysLogin.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'sysLogin.xml'); + create_file_from_tpl('login.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'login.xml'); + create_file_from_tpl('showMessage.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'showMessage.xml'); + create_file_from_tpl('welcome.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'welcome.xml'); + copy_file_from_tpl('xmlform.html', 'engine' . PATH_SEP . 'templates' . PATH_SEP . 'xmlform.html'); + copy_file_from_tpl('publish.php', 'engine' . PATH_SEP . 'templates' . PATH_SEP . 'publish.php'); + copy_file_from_tpl('publish-treeview.php', 'engine' . PATH_SEP . 'templates' . PATH_SEP . 'publish-treeview.php'); + create_file_from_tpl('dbInfo.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'dbInfo.xml'); + create_file_from_tpl('usersList.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'users' . PATH_SEP . 'usersList.xml'); + create_file_from_tpl('rolesList.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'users' . PATH_SEP . 'rolesList.xml'); + create_file_from_tpl('permissionsList.xml', 'engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'users' . PATH_SEP . 'permissionsList.xml'); + create_file_from_tpl('mainmenu.php', 'engine' . PATH_SEP . 'menus' . PATH_SEP . $projectName . '.php'); + create_file_from_tpl('users.menu.php', 'engine' . PATH_SEP . 'menus' . PATH_SEP . 'users.php'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'style.css'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'bsms.jpg'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'ftl.png'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'ftr.png'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'fbl.png'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'fbr.png'); + copy_file('public_html' . PATH_SEP . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images' . PATH_SEP . 'fbc.png'); + copy_file('public_html' . PATH_SEP . 'images' . PATH_SEP . 'favicon.ico'); + copy_file('public_html' . PATH_SEP . 'images' . PATH_SEP . 'bulletButton.gif'); + copy_file('public_html' . PATH_SEP . 'images' . PATH_SEP . 'bulletSubMenu.jpg'); + copy_file('public_html' . PATH_SEP . 'images' . PATH_SEP . 'users.png'); + copy_file('public_html' . PATH_SEP . 'images' . PATH_SEP . 'trigger.gif'); + + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'green.html'); + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'green.php'); + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'blank.html'); + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'blank.php'); + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'raw.html'); + copy_file('engine' . PATH_SEP . 'skins' . PATH_SEP . 'raw.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.ArrayPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.BasePeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.configuration.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.plugin.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.pluginRegistry.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.popupMenu.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'class.propelTable.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'Application.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'ApplicationPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'Content.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'ContentPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'Configuration.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'ConfigurationPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseApplication.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseApplicationPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseContent.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseContentPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseConfiguration.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'om' . PATH_SEP . 'BaseConfigurationPeer.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'map' . PATH_SEP . 'ApplicationMapBuilder.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'map' . PATH_SEP . 'ContentMapBuilder.php'); + copy_file('engine' . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'map' . PATH_SEP . 'ConfigurationMapBuilder.php'); + copy_file('engine' . PATH_SEP . 'config' . PATH_SEP . 'environments.php'); + copy_file('engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'login' . PATH_SEP . 'login.xml'); + copy_file('engine' . PATH_SEP . 'xmlform' . PATH_SEP . 'gulliver' . PATH_SEP . 'pagedTable_PopupMenu.xml'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'popupMenu.html'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'paged-table.html'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'xmlmenu.html'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'filterform.html'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'tree.html'); + copy_file('engine' . PATH_SEP . 'templates' . PATH_SEP . 'dummyTemplate.html'); + + $filePng = $pathHome . PATH_SEP . 'public_html' . PATH_SEP . 'images' . PATH_SEP . 'processmaker.logo.jpg'; + createPngLogo($filePng, $projectName); + if( ! PHP_OS == "WINNT" ) { + printf("creating symlinks %s \n", pakeColor::colorize($pathHome . PATH_SEP . 'engine' . PATH_SEP . 'gulliver', 'INFO')); + symlink(PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'gulliver', $pathHome . PATH_SEP . 'engine' . PATH_SEP . 'gulliver'); + } + //create schema.xml with empty databases + + + exit(0); +} + +function fieldToLabel($field) { + $aux = substr($field, 4); + $res = $aux[0]; + for( $i = 1; $i < strlen($aux); $i ++ ) { + if( $aux[$i] == '_' ) { + $res .= " " . $aux[++ $i]; + } else + $res .= strtolower($aux[$i]); + } + return $res; +} + +function fieldToLabelOption($field) { + $aux = $field; + $res = $aux[0]; + for( $i = 1; $i < strlen($aux); $i ++ ) { + if( $aux[$i] == '_' ) { + $res .= " " . $aux[++ $i]; + } else + $res .= strtolower($aux[$i]); + } + return $res; +} +function run_propel_build_crud($task, $args) { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + printf("Arguments: %s\n", pakeColor::colorize('./gulliver propel-build-crud ', 'INFO')); + + //the class filename in the first argument + if( ! isset($args[0]) ) { + printf("Error: %s\n", pakeColor::colorize('you must specify a valid classname ', 'ERROR')); + exit(0); + } + $class = $args[0]; + $phpClass = $class; + $phpClass[0] = strtolower($phpClass[0]); + + $tableName = $class[0]; + for( $i = 1; $i < strlen($class); $i ++ ) { + if( $class[$i] >= 'a' ) + $tableName .= strtoupper($class[$i]); + else + $tableName .= "_" . $class[$i]; + } + + //second parameter is the table name, by default is the same classname in uppercase. + if( isset($args[1]) ) + $tableName = $args[1]; + + $pluginName = ''; + if( isset($args[2]) ) + $pluginName = $args[2]; + + //try to find the class in classes directory + $classFilename = PATH_CORE . 'classes' . PATH_SEP . 'model' . PATH_SEP . $args[0] . '.php'; + + //try to find in the plugis directory, assuming there are a class in the plugin + if( $pluginName != '' ) { + $classFilename = PATH_PLUGINS . $pluginName . PATH_SEP . 'classes' . PATH_SEP . 'model' . PATH_SEP . $args[0] . '.php'; + set_include_path(PATH_PLUGINS . $pluginName . PATH_SEPARATOR . get_include_path()); + printf("using plugin : %s\n", pakeColor::colorize($pluginName, 'ERROR')); + } + + if( file_exists($classFilename) ) + printf("class found in %s \n", pakeColor::colorize($classFilename, 'INFO')); + else { + printf("class %s not found \n", pakeColor::colorize($class, 'ERROR')); + exit(0); + } + printf("TableName : %s \n", pakeColor::colorize($tableName, 'INFO')); + + require_once ("propel/Propel.php"); + require_once ($classFilename); + G::LoadSystem('templatePower'); + + global $G_ENVIRONMENTS; + $aux = explode(PATH_SEP, PATH_HOME); + $projectName = $aux[count($aux) - 2]; + define('PATH_SHARED', PATH_SEP . 'shared' . PATH_SEP . $projectName . '_data' . PATH_SEP); + + $dbFile = PATH_SHARED . 'sites' . PATH_SEP . $projectName . PATH_SEP . 'db.php'; + if( ! file_exists($dbFile) ) { + $dbFile = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' . PATH_SEP . 'templates' . PATH_SEP . 'db.php.tpl'; + } + printf("searching db file in : %s \n", pakeColor::colorize($dbFile, 'INFO')); + + $G_ENVIRONMENTS['DEVELOPMENT']['dbfile'] = $dbFile; + Propel::init(PATH_CORE . "config/databases.php"); + + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + if( $pluginName != '' ) { + $xmlformPath = PATH_PLUGINS . $pluginName . PATH_SEP; + $methodsPath = PATH_PLUGINS . $pluginName . PATH_SEP . $phpClass . PATH_SEP; + $corePath = PATH_PLUGINS . $pluginName . PATH_SEP; + } else { + $xmlformPath = PATH_CORE . 'xmlform' . PATH_SEP . $phpClass . PATH_SEP; + $methodsPath = PATH_CORE . 'methods' . PATH_SEP . $phpClass . PATH_SEP; + $corePath = PATH_CORE; + } + G::mk_dir($xmlformPath); + G::mk_dir($methodsPath); + + $fields['className'] = $class; + $fields['phpClassName'] = $phpClass; + $fields['tableName'] = $tableName; + $fields['projectName'] = $projectName; + + //1. MENU + if( $pluginName == '' ) { + create_file_from_tpl('pluginMenu', PATH_CORE . 'menus' . PATH_SEP . $phpClass . ".php", $fields); + } + //else { + // create_file_from_tpl ( 'pluginMenu', $corePath. $phpClass. ".php", $fields ); + //} + + + //2. si existe menu welcome, aqade la opcion + if( $pluginName == '' ) { + if( ! file_exists(PATH_CORE . 'menus' . PATH_SEP . "welcome.php") ) { + $fp = fopen(PATH_CORE . 'menus' . PATH_SEP . "welcome.php", "w"); + fwrite($fp, "table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + $valuesOpt = NULL; + if( isset($table->validator) ) { + foreach( $table->validator as $kc => $validator ) { + if( $validator['column'] == $column['name'] ) { + foreach( $validator->rule as $kr => $rule ) { + if( $rule['name'] == 'validValues' ) + $valuesOpt = explode('|', $rule['value']); + } + } + } + } + // print "\033[1;34m "; print_r ( $values); + //print $column['name'] . ' ' .$column['type'] . ' ' .$column['size'] . ' ' .$column['required'] . ' ' .$column['primaryKey']; + //print_r ( $column); print "\n"; + $maxlength = isset($column['size']) ? $column['size'] : 25; + $size = ($maxlength > 60) ? 60 : $maxlength; + $values = NULL; + if( isset($valuesOpt) ) { + $type = 'dropdown'; + foreach( $valuesOpt as $key => $val ) { + $values[] = array ( + 'value' => $val, + 'label' => fieldToLabelOption($val) + ); + } + } else { + switch( $column['type'] ) { + case 'TIMESTAMP': + $type = 'date'; + break; + case 'LONGVARCHAR': + $type = 'textarea'; + break; + default: + $type = 'text'; + } + } + if( isset($column['label']) ) { + $label = $column['label']; + } else { + $label = fieldToLabel($column['name']); + } + $field = array ( + 'name' => $column['name'], + 'className' => $class, + 'type' => $type, + 'size' => $size, + 'maxlength' => $maxlength, + 'label' => $label, + 'values' => $values + ); + $fields['fields'][] = $field; + if( ! $column['primaryKey'] ) { + $fields['onlyFields'][] = $field; + } else { + $fields['keys'][] = $field; + } + } + } + $fields['className'] = $class; + $fields['phpClassName'] = $phpClass; + $fields['projectName'] = $projectName; + $fields['firstKey'] = $fields['keys'][0]['name']; + + $fields['phpFolderName'] = $phpClass; + if( $pluginName != '' ) { + $fields['plugin'][] = array ( + 'pluginName' => $pluginName + ); + $fields['phpFolderName'] = $pluginName; + } + create_file_from_tpl('pluginXmlform', $xmlformPath . $phpClass . ".xml", $fields); + create_file_from_tpl('pluginXmlformEdit', $xmlformPath . $phpClass . "Edit.xml", $fields); + create_file_from_tpl('pluginXmlformDelete', $xmlformPath . $phpClass . "Delete.xml", $fields); + create_file_from_tpl('pluginList', $methodsPath . $phpClass . "List.php", $fields); + + //xmlform for list + //load the $fields array with fields data for PagedTable xml. + $fields = array (); + $onlyFields = array (); + $primaryKey = ''; + foreach( $s->table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + //print $column['name'] . ' ' .$column['type'] . ' ' .$column['size'] . ' ' .$column['required'] . ' ' .$column['primaryKey']; + //print "\n"; + $size = ($column['size'] > 40) ? 40 * 3 : $column['size'] * 3; + $type = $column['type']; + $label = fieldToLabel($column['name']); + if( $column['primaryKey'] ) { + if( $primaryKey == '' ) + $primaryKey .= '@!' . $column['name']; + else + $primaryKey .= '|@!' . $column['name']; + + if( isset($column['label']) ) { + $label = $column['label']; + } else { + $label = fieldToLabel($column['name']); + } + } + + $field = array ( + 'name' => $column['name'], + 'type' => $type, + 'size' => $size, + 'label' => $label + ); + $fields['fields'][] = $field; + if( ! $column['primaryKey'] ) { + if( $column['type'] != 'LONGVARCHAR' ) + $fields['onlyFields'][] = $field; + } else { + $fields['keys'][] = $field; + } + } + } + $fields['primaryKey'] = $primaryKey; + $fields['className'] = $class; + $fields['phpClassName'] = $phpClass; + $fields['phpFolderName'] = $phpClass; + if( $pluginName != '' ) { + $fields['phpFolderName'] = $pluginName; + } + $fields['projectName'] = $projectName; + $fields['tableName'] = $tableName; + create_file_from_tpl('pluginXmlformList', $xmlformPath . $phpClass . "List.xml", $fields); + create_file_from_tpl('pluginXmlformOptions', $xmlformPath . $phpClass . "Options.xml", $fields); + + //default edit + $fields = array (); + $index = 0; + $keylist = ''; + foreach( $s->table as $key => $table ) { + if( $table['name'] == $tableName ) + foreach( $table->column as $kc => $column ) { + $name = $column['name']; + $phpName = convertPhpName($name); + $field = array ( + 'name' => $name, + 'phpName' => $phpName, + 'index' => $index ++ + ); + if( $column['primaryKey'] ) { + if( $keylist == '' ) + $keylist .= '$' . $phpName; + else + $keylist .= ', $' . $phpName; + $fields['keys'][] = $field; + } + $fields['fields'][] = $field; + if( ! $column['primaryKey'] ) { + $fields['onlyFields'][] = $field; + } + $fields['fields2'][] = $field; + } + } + $fields['keylist'] = $keylist; + $fields['phpClassName'] = $phpClass; + $fields['phpFolderName'] = $phpClass; + $fields['className'] = $class; + $fields['tableName'] = $tableName; + $fields['projectName'] = $projectName; + if( $pluginName != '' ) { + $fields['plugin'][] = array ( + 'pluginName' => $pluginName + ); + $fields['phpFolderName'] = $pluginName; + } + //savePluginFile ( $class . PATH_SEP . $class . 'Edit.php', 'pluginEdit', $class, $tableName, $fields ); + //savePluginFile ( $class . PATH_SEP . $class . 'Save.php', 'pluginSave', $class, $tableName, $fields ); + create_file_from_tpl('pluginEdit', $methodsPath . $phpClass . "Edit.php", $fields); + create_file_from_tpl('pluginSave', $methodsPath . $phpClass . "Save.php", $fields); + create_file_from_tpl('pluginNew', $methodsPath . $phpClass . "New.php", $fields); + create_file_from_tpl('pluginDelete', $methodsPath . $phpClass . "Delete.php", $fields); + create_file_from_tpl('pluginDeleteExec', $methodsPath . $phpClass . "DeleteExec.php", $fields); + + exit(0); +} + +//////////////////////////// backup and restore functions /////////////////////////////////// +function backupAddTarFolder($tar, $pathBase, $pluginHome) { + $empty = true; + print " " . str_replace($pluginHome, '', $pathBase) . "\n"; + if( $handle = opendir($pathBase) ) { + while( false !== ($file = readdir($handle)) ) { + if( is_file($pathBase . $file) ) { + $empty = false; + $tar->addModify(array($pathBase . $file), '', $pluginHome); + } + if( is_dir($pathBase . $file) && $file != '..' && $file != '.' ) { + //print "dir $pathBase$file \n"; + backupAddTarFolder($tar, $pathBase . $file . PATH_SEP, $pluginHome); + $empty = false; + } + } + closedir($handle); + } + if( $empty /*&& $pathBase . $file != $pluginHome */) { + $tar->addModify(array($pathBase . $file), '', $pluginHome); + } + +} + +function getSysInfo() { + if( file_exists(PATH_METHODS . 'login/version-pmos.php') ) { + include (PATH_METHODS . 'login/version-pmos.php'); + } else { + define('PM_VERSION', 'Development Version'); + } + + $ipe = explode(" ", $_SERVER['SSH_CONNECTION']); + + if( getenv('HTTP_CLIENT_IP') ) { + $ip = getenv('HTTP_CLIENT_IP'); + } elseif( getenv('HTTP_X_FORWARDED_FOR') ) { + $ip = getenv('HTTP_X_FORWARDED_FOR'); + } else { + $ip = getenv('REMOTE_ADDR'); + } + + $redhat = ''; + if( file_exists('/etc/redhat-release') ) { + $fnewsize = filesize('/etc/redhat-release'); + $fp = fopen('/etc/redhat-release', 'r'); + $redhat = trim(fread($fp, $fnewsize)); + fclose($fp); + } + $redhat .= " (" . PHP_OS . ")"; + + $Fields = array(); + + $Fields['SYSTEM'] = $redhat; + $Fields['PHP'] = phpversion(); + $Fields['PM_VERSION'] = PM_VERSION; + $Fields['SERVER_ADDR'] = lookup($ipe[2]); + $Fields['IP'] = lookup($ipe[0]); + + return $Fields; +} + +/* +** function get_infoOnPM +** information about workspace +*/ +function get_infoOnPM($workspace) { + $infoPM = array (); + + $Fields = getSysInfo(); + + $Fields['WORKSPACE_NAME'] = $workspace; + + if( defined("DB_HOST") ) { + G::LoadClass('net'); + G::LoadClass('dbConnections'); + $dbNetView = new NET(DB_HOST); + $dbNetView->loginDbServer(DB_USER, DB_PASS); + + $dbConns = new dbConnections(''); + $availdb = ''; + foreach( $dbConns->getDbServicesAvailables() as $key => $val ) { + if( $availdb != '' ) + $availdb .= ', '; + $availdb .= $val['name']; + } + try { + $sMySQLVersion = $dbNetView->getDbServerVersion('mysql'); + } catch( Exception $oException ) { + $sMySQLVersion = 'Unknown'; + } + + $Fields['DATABASE'] = $dbNetView->dbName(DB_ADAPTER) . ' (Version ' . $sMySQLVersion . ')'; + $Fields['DATABASE_SERVER'] = DB_HOST; + $Fields['DATABASE_NAME'] = DB_NAME; + $Fields['AVAILABLE_DB'] = $availdb; + } else { + $Fields['DATABASE'] = "Not defined"; + $Fields['DATABASE_SERVER'] = $info_db['adap']; + $Fields['DATABASE_NAME'] = "Not defined"; + $Fields['AVAILABLE_DB'] = "Not defined"; + } + + $info_db = get_DirDB($workspace); + + $Fields['MYSQL_DATA_DIR'] = $info_db['datadir']; + $Fields['PLUGINS_LIST'] = get_plugins(); + $Fields['DB_ADAPTER'] = $info_db['DB_ADAPTER']; + $Fields['DB_HOST'] = $info_db['DB_HOST']; + $Fields['DB_NAME'] = $info_db['DB_NAME']; + $Fields['DB_USER'] = $info_db['DB_USER']; + $Fields['DB_PASS'] = $info_db['DB_PASS']; + $Fields['DB_RBAC_HOST'] = $info_db['DB_RBAC_HOST']; + $Fields['DB_RBAC_NAME'] = $info_db['DB_RBAC_NAME']; + $Fields['DB_RBAC_USER'] = $info_db['DB_RBAC_USER']; + $Fields['DB_RBAC_PASS'] = $info_db['DB_RBAC_PASS']; + $Fields['DB_REPORT_HOST'] = $info_db['DB_REPORT_HOST']; + $Fields['DB_REPORT_NAME'] = $info_db['DB_REPORT_NAME']; + $Fields['DB_REPORT_USER'] = $info_db['DB_REPORT_USER']; + $Fields['DB_REPORT_PASS'] = $info_db['DB_REPORT_PASS']; + + $infoPM = $Fields; + + return $infoPM; + +} + +function printMetadata($fields) { + printf("%20s %s \n", 'Workspace Name', pakeColor::colorize($fields['WORKSPACE_NAME'], 'INFO')); + printf("%20s %s \n", 'System', pakeColor::colorize($fields['SYSTEM'], 'INFO')); + + printf("%20s %s \n", 'ProcessMaker Version', pakeColor::colorize($fields['PM_VERSION'], 'INFO')); + printf("%20s %s \n", 'PHP Version', pakeColor::colorize($fields['PHP'], 'INFO')); + printf("%20s %s \n", 'Server Address', pakeColor::colorize($fields['SERVER_ADDR'], 'INFO')); + printf("%20s %s \n", 'Client IP Address', pakeColor::colorize($fields['IP'], 'INFO')); + + printf("%20s %s \n", 'MySql Version', pakeColor::colorize($fields['DATABASE'], 'INFO')); + printf("%20s %s \n", 'MySql Data Directory', pakeColor::colorize($fields['MYSQL_DATA_DIR'], 'INFO')); + printf("%20s %s \n", 'Available Databases', pakeColor::colorize($fields['AVAILABLE_DB'], 'INFO')); + + printf("%20s %s \n", 'Plugins', pakeColor::colorize('', 'INFO')); + + foreach( $fields['PLUGINS_LIST'] as $k => $v ) { + printf("%20s %s \n", ' -', pakeColor::colorize($v, 'INFO')); + } + + $wfDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_USER'] . ':' . $fields['DB_PASS'] . '@' . $fields['DB_HOST'] . '/' . $fields['DB_NAME']; + $rbDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_RBAC_USER'] . ':' . $fields['DB_RBAC_PASS'] . '@' . $fields['DB_RBAC_HOST'] . '/' . $fields['DB_RBAC_NAME']; + $rpDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_REPORT_USER'] . ':' . $fields['DB_REPORT_PASS'] . '@' . $fields['DB_REPORT_HOST'] . '/' . $fields['DB_REPORT_NAME']; + printf("%20s %s \n", 'Workflow Database', pakeColor::colorize($wfDsn, 'INFO')); + printf("%20s %s \n", 'RBAC Database', pakeColor::colorize($rbDsn, 'INFO')); + printf("%20s %s \n", 'Report Database', pakeColor::colorize($rpDsn, 'INFO')); + +} +function get_plugins() { + $dir = PATH_PLUGINS; + $filesArray = array (); + + if( file_exists($dir) ) { + if( $handle = opendir($dir) ) { + while( false !== ($file = readdir($handle)) ) { + if( ($file != ".") && ($file != "..") && ($file != ".svn") ) { + if( ! strpos($file, ".php") ) { + $filesArray[] = $file; + } + } + } + closedir($handle); + } + } + sort($filesArray, SORT_STRING); + return $filesArray; +} + +function lookup($target) { + global $ntarget; + $msg = $target . ' => '; + if( eregi('[a-zA-Z]', $target) ) + $ntarget = gethostbyname($target); + else + $ntarget = gethostbyaddr($target); + $msg .= $ntarget; + return ($msg); +} + +function run_workspace_backup($task, $args) { + try { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + /* Look for -c and --compress in arguments */ + $compress = array_search('-c', $args); + if ($compress === false) + $compress = array_search('--compress', $args); + if ($compress !== false) { + unset($args[$compress]); + /* We need to reorder the args if we removed the compress switch */ + $args = array_values($args); + $compress = true; + } + + /* Look for -c and --compress in arguments */ + $overwrite = array_search('-o', $args); + if ($overwrite === false) + $overwrite = array_search('--overwrite', $args); + if ($overwrite !== false) { + unset($args[$overwrite]); + /* We need to reorder the args if we removed the compress switch */ + $args = array_values($args); + $overwrite = true; + } + + if (array_search('compress', $args)) { + echo pakeColor::colorize("Compress is no longer an option, check if this is what you want\n", 'ERROR'); + } + + if (count($args) > 2 || count($args) == 0) + throw (new Exception('wrong arguments specified')); + + $workspace = $args[0]; + + /* Use system gzip if not in Windows */ + if ($compress && strtolower(reset(explode(' ',php_uname('s')))) != "windows") { + /* Find the system gzip */ + exec("whereis -b gzip", $whereisGzip); + $gzipPaths = explode(' ', $whereisGzip[0]); + if (isset($gzipPaths[1])) + $gzipPath = $gzipPaths[1]; + if (isset($gzipPath)) + echo "Using system gzip in $gzipPath\n"; + } + + if (isset($args[1])) { + $fileTar = $args[1]; + /* Check if the second argument is an absolute filename. If it is, use + * it as the backup filename. Otherwise, use it as a filename relative + * to the backups directory. This makes migration from previous versions + * easier, which always expects a relative filename, while still accepting + * absolute filenames. + */ + if (dirname($fileTar) == '.') { + printf("Using %s as root. Use an absolute filename to change it.\n", pakeColor::colorize(PATH_TRUNK . 'backups', 'INFO')); + G::mk_dir(PATH_DATA . 'backups'); + $fileTar = PATH_DATA . 'backups' . PATH_SEP . $fileTar . '.tar'; + if ($compress) + $fileTar .= '.gz'; + } + printf("Backing up workspace %s to %s\n", pakeColor::colorize($workspace, 'INFO'), pakeColor::colorize($fileTar, 'INFO')); + if (!$overwrite && file_exists($fileTar)) { + $overwrite = strtolower(prompt('Backup file already exists, do you want to overwrite? [Y/n]')); + if( array_search(trim($overwrite), array("y", "")) === false ) + die(); + $overwrite = true; + } + } else { + G::mk_dir(PATH_DATA . 'backups'); + $fileBase = PATH_DATA . 'backups' . PATH_SEP . $workspace . '.tar'; + $fileTar = $fileBase; + if ($compress) + $fileTar .= '.gz'; + printf("Backing up workspace %s to %s\n", pakeColor::colorize($workspace, 'INFO'), pakeColor::colorize($fileTar, 'INFO')); + /* To avoid confusion, we remove both .tar and .tar.gz */ + if (!$overwrite && (file_exists($fileBase) || file_exists($fileBase.'.gz'))) { + $overwrite = strtolower(prompt('Backup file already exists, do you want to overwrite? [Y/n]')); + if( array_search(trim($overwrite), array("y", "")) === false ) + die(); + $overwrite = true; + } + if (file_exists($fileBase)) + unlink($fileBase); + if (file_exists($fileBase.".gz")) + unlink($fileBase.'.gz'); + } + + /* Remove the backup file before backing up. Previous versions didn't do + * this, so backup files would increase indefinetely as new data was + * appended to the tar file instead of replaced. + */ + if (file_exists($fileTar)) + unlink($fileTar); + + /* If using the system gzip, create the tar using a temporary filename */ + if (isset($gzipPath)) { + $gzipFinal = $fileTar; + $fileTar = tempnam(__FILE__, ''); + } + + $aSerializeData = get_infoOnPM($workspace); + + $dbFile = PATH_DB . $workspace . PATH_SEP . 'db.php'; + if( ! file_exists($dbFile) ) { + throw (new Exception("Invalid workspace, the db file does not exist, $dbFile")); + } + + $dbOpt = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + G::LoadSystem('dbMaintenance'); + $oDbMaintainer = new DataBaseMaintenance($dbOpt[0], $dbOpt[1], $dbOpt[2]); + try{ + $oDbMaintainer->connect("mysql"); + } catch(Exception $e){ + echo "Problems contacting the database with the administrator user\n"; + echo "The response was: {$e->getMessage()}\n"; + } + + require_once ($dbFile); + require_once ("propel/Propel.php"); + G::LoadSystem('templatePower'); + + Propel::init(PATH_CORE . "config/databases.php"); + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + printf("using DSN Connection %s \n", pakeColor::colorize($connectionDSN, 'INFO')); + + $con = Propel::getConnection('workflow'); + $sql = "show variables like 'datadir'"; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + if( ! is_array($row) ) + throw (new Exception("unable to execute query in database")); + $dataDir = $row['Value']; + if( $dataDir[count($dataDir) - 1] == '/' ) + $dataDir = substr($dataDir, count($dataDir) - 1); + + printf("MySQL data dir %s \n", pakeColor::colorize($dataDir, 'INFO')); + + $sql = "SELECT VERSION();"; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + $rs->next(); + $row = $rs->getRow(); + $mysqlVersion = $row[0]; + $aSerializeData['DATABASE'] = $mysqlVersion; + $fileMetadata = PATH_TRUNK . 'backups' . PATH_SEP . 'metadata.txt'; + $sMetadata = file_put_contents($fileMetadata, serialize($aSerializeData)); + + G::LoadThirdParty('pear/Archive', 'Tar'); + + $tar = new Archive_Tar($fileTar); + if (!isset($gzipPath)) + $tar->_compress = $compress; + + //new db restore rotines, by Erik on May 17th, 2010 + //set the temporal directory for all tables into wf, rb, and rp databases + $tmpDir = G::getSysTemDir() . PATH_SEP . 'pmDbBackup' . PATH_SEP; + //create the db maintenance temporal dir + G::mk_dir($tmpDir); + + /*** WORKFLOW DATABASE BACKUP ***/ + $dbSettings = getDataBaseConfiguration($configuration['datasources']['workflow']['connection']); + backupDB($dbOpt[0], $dbOpt[1], $dbOpt[2], $dbSettings['dbname'], $tmpDir); + printf("Copying folder: %s \n", pakeColor::colorize( $tmpDir, 'INFO')); + backupAddTarFolder( $tar, $tmpDir . $dbSettings['dbname'] . PATH_SEP, $tmpDir ); + + /*** RBAC DATABASE BACKUP ***/ + $dbSettings = getDataBaseConfiguration($configuration['datasources']['rbac']['connection']); + backupDB($dbOpt[0], $dbOpt[1], $dbOpt[2], $dbSettings['dbname'], $tmpDir); + printf("Copying folder: %s \n", pakeColor::colorize( $tmpDir, 'INFO')); + backupAddTarFolder( $tar, $tmpDir . $dbSettings['dbname'] . PATH_SEP, $tmpDir ); + + /*** RP DATABASE BACKUP ***/ + $dbSettings = getDataBaseConfiguration($configuration['datasources']['rp']['connection']); + backupDB($dbOpt[0], $dbOpt[1], $dbOpt[2], $dbSettings['dbname'], $tmpDir); + printf("Copying folder: %s \n", pakeColor::colorize( $tmpDir, 'INFO')); + backupAddTarFolder( $tar, $tmpDir . $dbSettings['dbname'] . PATH_SEP, $tmpDir ); + + + $pathSharedBase = PATH_DATA . 'sites' . PATH_SEP . $workspace . PATH_SEP; + printf("copying folder: %s \n", pakeColor::colorize($pathSharedBase, 'INFO')); + backupAddTarFolder($tar, $pathSharedBase, PATH_DATA . 'sites'); + + backupAddTarFolder($tar, $fileMetadata, dirname($fileMetadata)); + unlink($fileMetadata); + $aFiles = $tar->listContent(); + + $total = 0; + foreach( $aFiles as $key => $val ) { + // printf( " %6d %s \n", $val['size'], pakeColor::colorize( $val['filename'], 'INFO') ); + $total += $val['size']; + } + + /* If using system gzip, compress the temporary tar to the original + * filename. + */ + if (isset($gzipPath)) { + exec("gzip -c \"$fileTar\" > $gzipFinal", $output, $ret); + if ($ret != 0) { + /* The error message is in stderr, which should be displayed already */ + echo pakeColor::colorize("Error compressing backup", "ERROR") . "\n"; + die(1); + } + unlink($fileTar); + $fileTar = $gzipFinal; + } + + printMetadata($aSerializeData); + printf("%20s %s \n", 'Backup File', pakeColor::colorize($fileTar, 'INFO')); + printf("%20s %s \n", 'Files in Backup', pakeColor::colorize(count($aFiles), 'INFO')); + printf("%20s %s \n", 'Total Filesize', pakeColor::colorize(sprintf("%5.2f MB", $total / 1024 / 1024), 'INFO')); + printf("%20s %s \n", 'Backup Filesize', pakeColor::colorize(sprintf("%5.2f MB", filesize($fileTar) / 1024 / 1024), 'INFO')); + + } catch( Exception $e ) { + printf("Error: %s\n", pakeColor::colorize($e->getMessage(), 'ERROR')); + exit(0); + } +} + +function backupDB($host, $user, $passwd, $dbname, $tmpDir){ + $oDbMaintainer = new DataBaseMaintenance($host, $user, $passwd); + //stablishing connetion with host + $oDbMaintainer->connect($dbname); + //set temporal dir. for maintenance for oDbMaintainer object + $oDbMaintainer->setTempDir($tmpDir . $dbname . PATH_SEP); + //create the backup + $oDbMaintainer->backupDataBaseSchema($oDbMaintainer->getTempDir() . "$dbname.sql"); + $oDbMaintainer->backupSqlData(); +} + +/** + * Parse and get the database parameters from a dns connection + * dsn sample mysql://wf_os:w9j14dkf5v0m@localhost:3306/wf_os?encoding=utf8 + * + * @author Erik A. O. + */ +function getDataBaseConfiguration($dsn) { + $dsn = trim($dsn); + $tmp = explode(':', $dsn); + $tmp2 = str_replace('//', '', $tmp[1]); + $result["user"] = $tmp2; + $tmp2 = explode('@', $tmp[2]); + $result["passwd"] = $tmp2[0]; + $result["host"] = $tmp2[1]; + $tmp2 = explode('?', $tmp[3]); + $tmp2 = explode('/', $tmp2[0]); + $result["port"] = $tmp2[0]; + $result["dbname"] = $tmp2[1]; + + return $result; +} + +function run_workspace_restore($task, $args) { + try { + ini_set('display_errors', 'on'); + ini_set('error_reporting', E_ERROR); + + // the environment for poedit always is Development + define('G_ENVIRONMENT', G_DEV_ENV); + + $overwrite = array_search('-o', $args); + if ($overwrite === false) + $overwrite = array_search('--overwrite', $args); + if ($overwrite !== false) { + unset($args[$overwrite]); + $args = array_values($args); + $overwrite = true; + } + + if (count($args) < 1 || count($args) > 2) { + throw (new Exception('Wrong number of arguments specified')); + } + + /* Search for the backup file in several directories, choosing the first one + * that is found. + * 1) An absolute filename used as is. + * 2) A filename relative to the backups directory (eg. workflow.tar) + * 3) A workspace name (such as workflow) uncompressed backup + * 4) A workspace name compressed backup + * 5) A filename in the old backups directory (for legacy compatibiility) + */ + $backupFiles = array( + $args[0], + PATH_DATA . 'backups' . PATH_SEP . $args[0], + PATH_DATA . 'backups' . PATH_SEP . $args[0] . ".tar", + PATH_DATA . 'backups' . PATH_SEP . $args[0] . ".tar.gz", + PATH_OUTTRUNK . 'backups' . PATH_SEP . $args[0] + ); + + foreach ($backupFiles as $backupFile) { + if (file_exists($backupFile)) + break; + } + if (!file_exists($backupFile)) + throw(new Exception("Backup file not found.")); + + $targetWorkspaceName = isset($args[1]) ? $args[1] : NULL; + + printf("Using file %s \n", pakeColor::colorize($backupFile, 'INFO')); + + if( workspaceRestore($backupFile, $targetWorkspaceName, $overwrite) ) { + printf("Successfully restored from file %s \n", pakeColor::colorize($backupFile, 'INFO')); + } else { + throw (new Exception('There was an error in file descompression. ')); + } + } catch( Exception $e ) { + printf("Error: %s\n", pakeColor::colorize($e->getMessage(), 'ERROR')); + exit(0); + } +} + +function updateDBCallback($matches) { + global $updateDBCallbackData; + /* This function changes the values of defines while keeping their formatting + * intact. + * $matches will contain several groups: + * ((define('()2', ')1 ()3 (');)4 )0 + */ + $dbPrefix = array( + 'DB_NAME' => 'wf_', + 'DB_USER' => 'wf_', + 'DB_RBAC_NAME' => 'rb_', + 'DB_RBAC_USER' => 'rb_', + 'DB_REPORT_NAME' => 'rp_', + 'DB_REPORT_USER' => 'rp_'); + $key = $matches['key']; + $value = $matches['value']; + if (array_search($key,array('DB_HOST', 'DB_RBAC_HOST', 'DB_REPORT_HOST')) !== false) { + /* Change the database hostname for these keys */ + $value = $updateDBCallbackData['new_host']; + } else if (array_key_exists($key, $dbPrefix)) { + if ($updateDBCallbackData['change_workspace']) + /* Change the database name to the new workspace, following the standard + * of prefix (either wf_, rp_, rb_) and the workspace name. + */ + $value = $dbPrefix[$key].$updateDBCallbackData['target_workspace']; + } + $updateDBCallbackData['config'][$key] = $value; + return $matches[1].$value.$matches[4]; +} + +function updateDBfile($directory, $targetWorkspace, $dbNewHost, $changeWorkspace) { + if (count(explode(":", $dbNewHost)) < 2) + $dbNewHost .= ':3306'; + /* Workaround to send variables to updateDBCallback callback */ + $GLOBALS['updateDBCallbackData'] = array( + "new_host" => $dbNewHost, + "change_workspace" => $changeWorkspace, + "target_workspace" => $targetWorkspace, + "config" => array() + ); + global $updateDBCallbackData; + + $dbfile = $directory . PATH_SEP . 'db.php'; + if( file_exists($dbfile) ) { + $sDbFile = file_get_contents($dbfile); + /* Match all defines in the config file. Check updateDBCallback to know what + * keys are changed and what groups are matched. + * This regular expression will match any "define ('', '');" + * with any combination of whitespace between words. + */ + $sNewDbFile = preg_replace_callback("/( *define *\( *'(?P.*?)' *, *\n* *')(?P.*?)(' *\) *;.*)/", + updateDBCallback, + $sDbFile); + file_put_contents($dbfile, $sNewDbFile); + return $updateDBCallbackData['config']; + } +} + +function restoreDB($dbHost, $dbMaintainer, $dbOldName, $dbName, $dbUser, $dbPass, $tempDirectory, $overwrite) { + printf("Restoring database %s to %s\n", $dbOldName, pakeColor::colorize($dbName, 'INFO')); + + /* Check if the hostname is local (localhost or 127.0.0.1) */ + $islocal = (strcmp(substr($dbHost, 0, strlen('localhost')),'localhost')===0) || + (strcmp(substr($dbHost, 0, strlen('127.0.0.1')),'127.0.0.1')===0); + + $dbMaintainer->connect('mysql'); + + $result = $dbMaintainer->query("SELECT * FROM `user` WHERE user='$dbUser' AND password=PASSWORD('{$dbPass}')"); + if( ! isset($result[0]) ){ //the user doesn't exist + $dbHostPerm = $islocal ? "localhost":"%"; + $dbMaintainer->query("INSERT INTO user VALUES('$dbHostPerm','$dbUser',PASSWORD('{$dbPass}'),'Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);"); + } + $dbMaintainer->query("GRANT ALL PRIVILEGES ON `$dbUser`.* TO $dbName@'localhost' IDENTIFIED BY '{$dbPass}' WITH GRANT OPTION"); + + if( $overwrite ) { + $dbMaintainer->createDb($dbName, true); + } else { + $dbMaintainer->createDb($dbName); + } + + $dbMaintainer->connect($dbName); + $dbMaintainer->setTempDir($tempDirectory . PATH_SEP . $dbOldName . PATH_SEP); + $dbMaintainer->restoreFromSql($dbMaintainer->getTempDir() . $dbOldName . '.sql'); + $dbMaintainer->restoreAllData('sql'); +} + +function workspaceRestore($backupFilename, $targetWorkspace, $overwrite) { + + $tempDirectory = tempnam(__FILE__, ''); + if (file_exists($tempDirectory)) { + unlink($tempDirectory); + } + + if (file_exists($tempDirectory)) + G::rm_dir($tempDirectory); + G::mk_dir($tempDirectory); + + G::LoadThirdParty('pear/Archive', 'Tar'); + $tar = new Archive_Tar($backupFilename); + $res = $tar->extract($tempDirectory); + + $metadataFilename = $tempDirectory . PATH_SEP . 'metadata.txt'; + if (!file_exists($metadataFilename)) { + /* Look for legacy backups, where metadata was stored as a file with the + * workspace name, such as workflow.txt + * This means the backup filename must be the same as the metadata file. + */ + $info = pathinfo($backupFilename); + /* Check if it's a compressed backup, in which case we need to remove + * both the gz and the tar extensions. + */ + if ($info['extension'] == "gz") + $info = pathinfo(basename($backupFilename, '.' . $info['extension'])); + $wsNameFromTar = basename($backupFilename, '.' . $info['extension']); + $metadataFilename = $tempDirectory . PATH_SEP . $wsNameFromTar . '.txt'; + if (!file_exists($metadataFilename)) { + throw (new Exception("Metadata file was not found in backup")); + } + } + + $metadata = unserialize(file_get_contents($metadataFilename)); + + $backupWorkspace = $metadata['WORKSPACE_NAME']; + $changeWorkspace = (isset($targetWorkspace)); + if (!$changeWorkspace) { + $targetWorkspace = $backupWorkspace; + } else { + echo "Restoring from workspace: " . pakeColor::colorize($backupWorkspace, 'INFO') . "\n"; + } + echo "Restoring to workspace: ".pakeColor::colorize($targetWorkspace, 'INFO')."\n"; + + //moving the site files + $backupWorkspaceDir = $tempDirectory . PATH_SEP . $backupWorkspace; + $targetWorkspaceDir = PATH_DATA . 'sites' . PATH_SEP . $targetWorkspace; + + if (!$overwrite && file_exists($targetWorkspaceDir)) { + $overwrite = strtolower(prompt('Workspace already exists, do you want to overwrite? [Y/n]')); + if( array_search(trim($overwrite), array("y", "")) === false ) + die(); + $overwrite = true; + } + + printf("Moving files to %s \n", pakeColor::colorize($targetWorkspaceDir, 'INFO')); + + /* We already know we will be overwriting the new workspace if we reach this + * point, so remove the workspace directory if it exists. + */ + if (file_exists($targetWorkspaceDir)) + G::rm_dir($targetWorkspaceDir); + + if( ! rename($backupWorkspaceDir, $targetWorkspaceDir) ) { + throw (new Exception("There was an error moving from $backupWorkspaceDir to $targetWorkspaceDir")); + } + + $dbOpt = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + $dbHostname = $dbOpt[0]; + + /* TODO: Check if database exists after updateDBfile */ + $config = updateDBfile($targetWorkspaceDir, $targetWorkspace, $dbHostname, $changeWorkspace); + + G::LoadSystem('dbMaintenance'); + $oDbMaintainer = new DataBaseMaintenance($dbOpt[0], $dbOpt[1], $dbOpt[2]); + + $dbName = $config['DB_NAME']; + $dbUser = $config['DB_USER']; + $dbPass = $config['DB_PASS']; + restoreDB($dbHostname, $oDbMaintainer, $metadata['DB_NAME'], $dbName, $dbUser, $dbPass, $tempDirectory, $overwrite); + + $dbName = $config['DB_RBAC_NAME']; + $dbUser = $config['DB_RBAC_USER']; + $dbPass = $config['DB_RBAC_PASS']; + restoreDB($dbHostname, $oDbMaintainer, $metadata['DB_RBAC_NAME'], $dbName, $dbUser, $dbPass, $tempDirectory, $overwrite); + + $dbName = $config['DB_REPORT_NAME']; + $dbUser = $config['DB_REPORT_USER']; + $dbPass = $config['DB_REPORT_PASS']; + restoreDB($dbHostname, $oDbMaintainer, $metadata['DB_REPORT_NAME'], $dbName, $dbUser, $dbPass, $tempDirectory, $overwrite); + + echo "\n"; + + $wsInfo = getSysInfo(); + $wsInfo['WORKSPACE_NAME'] = $targetWorkspace; + $wsInfo = array_merge($wsInfo, $config); + + printInfoSites($metadata, $wsInfo); + + return true; +} + +function get_DirDB($workspace) { + + $dbFile = PATH_DB . $workspace . PATH_SEP . 'db.php'; + if( ! file_exists($dbFile) ) { + throw (new Exception("the db file does not exist, $dbFile")); + } + + require_once ($dbFile); + require_once ("propel/Propel.php"); + G::LoadSystem('templatePower'); + + Propel::init(PATH_CORE . "config/databases.php"); + $configuration = Propel::getConfiguration(); + $connectionDSN = $configuration['datasources']['workflow']['connection']; + + // printf("using DSN Connection %s \n", pakeColor::colorize( $connectionDSN, 'INFO')); + + + $con = Propel::getConnection('workflow'); + $sql = "show variables like 'datadir'"; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + if( ! is_array($row) ) + throw (new Exception("unable to execute query in database")); + $dataDir = $row['Value']; + if( $dataDir[count($dataDir) - 1] == '/' ) + $dataDir = substr($dataDir, count($dataDir) - 1); + + $info_db = array (); + $info_db['conx'] = $configuration['datasources']['workflow']['connection']; + $info_db['adap'] = $configuration['datasources']['workflow']['adapter']; + $info_db['datadir'] = $dataDir; + + $info_db['DB_ADAPTER'] = DB_ADAPTER; + $info_db['DB_HOST'] = DB_HOST; + $info_db['DB_NAME'] = DB_NAME; + $info_db['DB_USER'] = DB_USER; + $info_db['DB_PASS'] = DB_PASS; + $info_db['DB_RBAC_HOST'] = DB_RBAC_HOST; + $info_db['DB_RBAC_NAME'] = DB_RBAC_NAME; + $info_db['DB_RBAC_USER'] = DB_RBAC_USER; + $info_db['DB_RBAC_PASS'] = DB_RBAC_PASS; + $info_db['DB_REPORT_HOST'] = DB_REPORT_HOST; + $info_db['DB_REPORT_NAME'] = DB_REPORT_NAME; + $info_db['DB_REPORT_USER'] = DB_REPORT_USER; + $info_db['DB_REPORT_PASS'] = DB_REPORT_PASS; + + return $info_db; +} + +function printInfoSites($aSitebck, $aSiterestared) { + printf("%25s %s \n", 'Workspace Name Backup', pakeColor::colorize($aSitebck['WORKSPACE_NAME'], 'INFO')); + printf("%25s %s \n", 'Workspace Name Restored', pakeColor::colorize($aSiterestared['WORKSPACE_NAME'], 'INFO')); + + printf("%25s %s \n", 'System Backup', pakeColor::colorize($aSitebck['SYSTEM'], 'INFO')); + printf("%25s %s \n", 'System Restored', pakeColor::colorize($aSiterestared['SYSTEM'], 'INFO')); + + printf("%25s %s \n", 'PM Version Backup', pakeColor::colorize($aSitebck['PM_VERSION'], 'INFO')); + printf("%25s %s \n", 'PM Version Restored', pakeColor::colorize($aSiterestared['PM_VERSION'], 'INFO')); + + printf("%25s %s \n", 'PHP Version Backup', pakeColor::colorize($aSitebck['PHP'], 'INFO')); + printf("%25s %s \n", 'PHP Version Restored', pakeColor::colorize($aSiterestared['PHP'], 'INFO')); + + //printf( "%25s %s \n", 'Server Address', pakeColor::colorize( $aSitebck['SERVER_ADDR'], 'INFO') ); + //printf( "%25s %s \n", 'Client IP Address', pakeColor::colorize( $aSitebck['IP'], 'INFO') ); + + + //printf( "%25s %s \n", 'MySql Version', pakeColor::colorize( $aSitebck['DATABASE'], 'INFO') ); + //printf( "%25s %s \n", 'MySql Version', pakeColor::colorize( $aSiterestared['DATABASE'], 'INFO') ); + + + //printf( "%25s %s \n", 'MySql Data Directory', pakeColor::colorize( $aSitebck['MYSQL_DATA_DIR'], 'INFO') ); + //printf( "%25s %s \n", 'MySql Data Directory', pakeColor::colorize( $aSiterestared['MYSQL_DATA_DIR'], 'INFO') ); + + + //printf( "%25s %s \n", 'Available Databases', pakeColor::colorize( $aSitebck['AVAILABLE_DB'], 'INFO') ); + + + /*printf( "%20s %s \n", 'Plugins', pakeColor::colorize( '', 'INFO') ); + foreach ($aSitebck['PLUGINS_LIST'] as $k => $v){ + printf( "%20s %s \n", ' -', pakeColor::colorize( $v, 'INFO') ); + }*/ + + $wfDsn = $aSiterestared['DB_ADAPTER'] . '://' . $aSiterestared['DB_USER'] . ':' . $aSiterestared['DB_PASS'] . '@' . $aSiterestared['DB_HOST'] . '/' . $aSiterestared['DB_NAME']; + $rbDsn = $aSiterestared['DB_ADAPTER'] . '://' . $aSiterestared['DB_RBAC_USER'] . ':' . $aSiterestared['DB_RBAC_PASS'] . '@' . $aSiterestared['DB_RBAC_HOST'] . '/' . $aSiterestared['DB_RBAC_NAME']; + $rpDsn = $aSiterestared['DB_ADAPTER'] . '://' . $aSiterestared['DB_REPORT_USER'] . ':' . $aSiterestared['DB_REPORT_PASS'] . '@' . $aSiterestared['DB_REPORT_HOST'] . '/' . $aSiterestared['DB_REPORT_NAME']; + printf("%25s %s \n", 'Workflow Database', pakeColor::colorize($wfDsn, 'INFO')); + printf("%25s %s \n", 'RBAC Database', pakeColor::colorize($rbDsn, 'INFO')); + printf("%25s %s \n", 'Report Database', pakeColor::colorize($rpDsn, 'INFO')); + +} + +global $aFiles; + +function checkFileStandardCode ( $file ) { + global $aFiles; + + if ( strpos ($file, 'workflow/engine/classes/model/om/') !== false ) { + return; + } + if ( strpos ($file, 'workflow/engine/classes/model/map/') !== false ) { + return; + } + if ( substr ($file, -4 ) == '.gif' ) { + return; + } + + $rootFolder = str_replace ( PATH_TRUNK, '', $file ); + + $data = file_get_contents ( $file ); + + $bTabs = false; + if ( strpos( $data, "\t" ) !== false ) { + $bTabs = true; + } + + $bUtf8 = false; + if ( strpos( $data, "\xff" ) !== false || strpos( $data, "\x00" ) !== false ) { +//isUTF8 + $bUtf8 = true; + } + if ( filesize ( $file ) != strlen($data) ) { + $bUtf8 = true; + } + + $bDos = false; + if ( strpos( $data, "\x0D" ) !== false ) { + $bDos = true; + } + + if ( $bUtf8 || $bTabs || $bDos ) { + $aFiles[] = array ( 'file' => $rootFolder, 'tab' => $bTabs, 'utf' => $bUtf8, 'dos' => $bDos ); + + } +} + +function checkFolderStandardCode ( $folder, $bSubFolders ) { + global $aFiles; + $rootFolder = str_replace ( PATH_TRUNK, '', $folder ); + //printf("%s \n", pakeColor::colorize($rootFolder, 'INFO')); + if ($handle = opendir( $folder )) { + while ( false !== ($file = readdir($handle))) { + + if ( substr( $file, 0, 1 ) !== '.' ) { + if ( is_file ( $folder . '/' . $file ) ) { + checkFileStandardCode ( $folder . '/' . $file); + } + if ( is_dir( $folder . '/' . $file ) && $bSubFolders ) { + checkFolderStandardCode ( $folder . '/' . $file, $bSubFolders ); + } + } + } + } +} + +function run_check_standard_code ( $task, $options) { + global $aFiles; + $aFiles = array(); + if ( ! isset( $options[0]) ) { + $folder = PATH_TRUNK . 'classes'; + } + else + $folder = PATH_TRUNK . $options[0]; + + + if ( ! isset( $options[1]) ) { + $bSubFolders = false; + } + else + $bSubFolders = strtolower($options[1]) == 'true'; + + printf("checking folder %s\n", pakeColor::colorize($folder, 'INFO') ); + checkFolderStandardCode ( $folder , $bSubFolders); + sort($aFiles); + foreach ( $aFiles as $key => $val ) { + + printf("%s %s %s %s \n", pakeColor::colorize($val['tab'] ? 'tab' : ' ', 'INFO'), + pakeColor::colorize($val['utf'] ? 'utf' : ' ', 'INFO'), + pakeColor::colorize($val['dos'] ? 'dos' : ' ', 'INFO'), $val['file'] ); + } +} diff --git a/gulliver/bin/tasks/pakePropel.php b/gulliver/bin/tasks/pakePropel.php new file mode 100644 index 000000000..32abd3e8a --- /dev/null +++ b/gulliver/bin/tasks/pakePropel.php @@ -0,0 +1,492 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * This file is part of the symfony package. + * (c) 2004-2006 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +pake_desc('create classes for current model'); +pake_task('propel-build-model', 'project_exists'); + +pake_desc('create sql for current model'); +pake_task('propel-build-sql', 'project_exists'); + +pake_desc('create schema.xml from existing database'); +pake_task('propel-build-schema', 'project_exists'); + +//pake_desc('create schema.xml from schema.yml'); +//pake_task('propel-convert-yml-schema', 'project_exists'); + +//pake_desc('create schema.yml from schema.xml'); +//pake_task('propel-convert-xml-schema', 'project_exists'); + +//pake_desc('load data from fixtures directory'); +//pake_task('propel-load-data', 'project_exists'); + +pake_desc('dump data to fixtures directory'); +pake_task('propel-dump-data', 'project_exists'); + +pake_desc('create database for current model'); +pake_task('propel-build-db', 'project_exists'); + +pake_desc('insert sql for current model'); +pake_task('propel-insert-sql', 'project_exists'); + +//pake_desc('generate propel model and sql and initialize database'); +//pake_task('propel-build-all', 'project_exists'); + +//pake_desc('generate propel model and sql and initialize database, and load data'); +//pake_task('propel-build-all-load', 'propel-build-all'); + +function run_propel_convert_yml_schema($task, $args) +{ + _propel_convert_yml_schema(true); +} + +function run_propel_convert_xml_schema($task, $args) +{ + _propel_convert_xml_schema(true); +} + +function _propel_convert_yml_schema($check_schema = true, $prefix = '') +{ + $finder = pakeFinder::type('file')->name('*schema.yml'); + $dirs = array('config'); + if ($pluginDirs = glob(sfConfig::get('sf_root_dir').'/plugins/*/config')) + { + $dirs = array_merge($dirs, $pluginDirs); + } + $schemas = $finder->in($dirs); + if ($check_schema && !count($schemas)) + { + throw new Exception('You must create a schema.yml file.'); + } + + $db_schema = new sfPropelDatabaseSchema(); + foreach ($schemas as $schema) + { + $db_schema->loadYAML($schema); + + pake_echo_action('schema', 'converting "'.$schema.'"'.' to XML'); + + $localprefix = $prefix; + + // change prefix for plugins + if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match)) + { + $localprefix = $prefix.$match[1].'-'; + } + + // save converted xml files in original directories + $xml_file_name = str_replace('.yml', '.xml', basename($schema)); + + $file = str_replace(basename($schema), $localprefix.$xml_file_name, $schema); + pake_echo_action('schema', 'putting '.$file); + file_put_contents($file, $db_schema->asXML()); + } +} + +function _propel_convert_xml_schema($check_schema = true, $prefix = '') +{ + $finder = pakeFinder::type('file')->name('*schema.xml'); + + $schemas = array_merge($finder->in('config'), $finder->in(glob(sfConfig::get('sf_root_dir').'/plugins/*/config'))); + if ($check_schema && !count($schemas)) + { + throw new Exception('You must create a schema.xml file.'); + } + + $db_schema = new sfPropelDatabaseSchema(); + foreach ($schemas as $schema) + { + $db_schema->loadXML($schema); + + $localprefix = $prefix; + + // change prefix for plugins + if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match)) + { + $localprefix = $prefix.$match[1].'-'; + } + + // save converted xml files in original directories + $yml_file_name = str_replace('.xml', '.yml', basename($schema)); + + $file = str_replace(basename($schema), $prefix.$yml_file_name, $schema); + pake_echo_action('schema', 'putting '.$file); + file_put_contents($file, $db_schema->asYAML()); + } +} + +function _propel_copy_xml_schema_from_plugins($prefix = '') +{ + $schemas = pakeFinder::type('file')->name('*schema.xml')->in(glob(sfConfig::get('sf_root_dir').'/plugins/*/config')); + + foreach ($schemas as $schema) + { + // reset local prefix + $localprefix = ''; + + // change prefix for plugins + if (preg_match('#plugins[/\\\\]([^/\\\\]+)[/\\\\]#', $schema, $match)) + { + // if the plugin name is not in the schema filename, add it + if (!strstr(basename($schema), $match[1])) + { + $localprefix = $match[1].'-'; + } + } + + // if the prefix is not in the schema filename, add it + if (!strstr(basename($schema), $prefix)) + { + $localprefix = $prefix.$localprefix; + } + + pake_copy($schema, 'config'.DIRECTORY_SEPARATOR.$localprefix.basename($schema)); + if ('' === $localprefix) + { + pake_remove($schema, ''); + } + } +} + +function run_propel_build_all($task, $args) +{ + run_propel_build_model($task, $args); + run_propel_build_sql($task, $args); + run_propel_insert_sql($task, $args); +} + +function run_propel_build_all_load($task, $args) +{ + run_propel_build_all($task, $args); + run_propel_load_data($task, $args); +} + +function run_propel_build_model($task, $args) +{ + if ( isset ( $args[0] ) ) { + $propelIniFile = $args[0] . '.ini'; + if ( ! file_exists ( 'config' . PATH_SEP . $propelIniFile ) ) { + $path = explode ( '/', $args[0] ); + if ( count($path) > 2 ) + throw new Exception('the propel.ini must be in your config directory.'); + if ( count($path) == 1 ) + $path[1] = 'propel'; + + $propelIniFile = 'plugins' .PATH_SEP . $path[0] . PATH_SEP . 'config' . PATH_SEP . $path[1] . '.ini'; + + pake_echo_action('propel.ini', "using the file : $propelIniFile "); + _call_phing($task, 'om', false, $path[1] . '.ini' , PATH_PLUGINS . $path[0] . PATH_SEP ); + return; + } + + } + _call_phing($task, 'om'); +} + +function run_propel_build_sql($task, $args) +{ + if ( isset ( $args[1] ) ) { + $propelIniFile = $args[1] . '.ini'; + $alternateDir = ''; + if ( ! file_exists ( 'config' . PATH_SEP . $propelIniFile ) ) { + $path = explode ( '/', $args[1] ); + if ( count($path) > 2 ) + throw new Exception('the propel.ini must be in your config directory.'); + if ( count($path) == 1 ) + $path[1] = 'propel'; + + $propelIniFile = 'plugins' .PATH_SEP . $path[0] . PATH_SEP . 'config' . PATH_SEP . $path[1] . '.ini'; + if ( ! file_exists($propelIniFile) ) + throw new Exception("the propel.ini must be in your config directory. ($propelIniFile)"); + + pake_echo_action('propel.ini', "using the file : $propelIniFile "); + $alternateDir = PATH_PLUGINS . $path[0] . PATH_SEP; + //_call_phing($task, 'om', false, $path[1] . '.ini' , PATH_PLUGINS . $path[0] . PATH_SEP ); + //return; + } + + } + switch ( $args [0]) { + case 'mysql' : if ( $alternateDir != '' ) + _call_phing($task, 'sql', false, 'propel.mysql.ini', $alternateDir ); + else + _call_phing($task, 'sql', true, 'propel.mysql.ini' ); + break; + case 'mssql' : _call_phing($task, 'sql', true, 'propel.mssql.ini' ); + break; + case 'oracle' : _call_phing($task, 'sql', true, 'propel.oracle.ini' ); + break; + case 'pgsql' : _call_phing($task, 'sql', true, 'propel.pgsql.ini' ); + break; + default : + throw new Exception('specify database Adapter, valid values are: mysql, mssql, oracle, pgsql.'); + } + +} + +function run_propel_build_db($task, $args) +{ + switch ( $args [0]) { + case 'mysql' : _call_phing($task, 'create-db', true, 'propel.mysql.ini' ); + break; + case 'mssql' : _call_phing($task, 'create-db', true, 'propel.mssql.ini' ); + break; + case 'oracle' : _call_phing($task, 'create-db', true, 'propel.oracle.ini' ); + break; + case 'pgsql' : _call_phing($task, 'create-db', true, 'propel.pgsql.ini' ); + break; + default : + throw new Exception('specify database Adapter, valid values are: mysql, mssql, oracle, pgsql.'); + } + +} + +function run_propel_insert_sql($task, $args) +{ + switch ( $args [0]) { + case 'mysql' : //_call_phing($task, 'insert-sql', true, 'propel.mysql.ini' ); + $filename = 'config/propel.mysql.ini'; + $fd = fopen ($filename, "r"); + $contents = fread ($fd,filesize ($filename)); + fclose ($fd); + $delimiter = "\n"; + $splitcontents = explode($delimiter, $contents); + foreach ($splitcontents as $key => $line) + if ( strpos ( $line, 'database.url' ) > 0 ) { + $param = explode ( '/', $line ); + $database = $param [ count( $param) -1 ]; + pake_echo_action('propel-insert-sql', "using the database : $database "); + } + + //exec ( 'mysqldump --add-drop-table --compatible=mysql40 --compact --default-character-set=utf8 --no-create-info --complete-insert --extended-insert=false > data/mysql/insert.sql ' . $database ); + exec ( 'mysqldump --password=atopml2005 --compatible=mysql40 --compact --default-character-set=utf8 --no-create-info --complete-insert=false --extended-insert=true > data/mysql/insert.sql ' . $database ); + break; + case 'mssql' : _call_phing($task, 'insert-sql', true, 'propel.mssql.ini' ); + break; + case 'oracle' : _call_phing($task, 'insert-sql', true, 'propel.oracle.ini' ); + break; + case 'pgsql' : _call_phing($task, 'insert-sql', true, 'propel.pgsql.ini' ); + break; + default : + throw new Exception('specify database Adapter, valid values are: mysql, mssql, oracle, pgsql.'); + } +} + +function run_propel_build_schema($task, $args) +{ + $propelIniFile = 'propel.ini'; + if ( isset ( $args[0] ) ) { + + $propelIniFile = $args[0] . '.ini'; + if ( ! file_exists ( 'config' . PATH_SEP . $propelIniFile ) ) { + $path = explode ( '/', $args[0] ); + if ( count($path) > 2 ) + throw new Exception('the propel.ini must be in your config directory.'); + if ( count($path) == 1 ) + $path[1] = 'propel'; + + $propelIniFile = 'plugins' .PATH_SEP . $path[0] . PATH_SEP . 'config' . PATH_SEP . $path[1] . '.ini'; + + pake_echo_action('propel.ini', "using the file : $propelIniFile "); + _call_phing($task, 'creole', false, $path[1] . '.ini' , PATH_PLUGINS . $path[0] . PATH_SEP ); + + // fix database name + if (file_exists(PATH_PLUGINS . $path[0] . PATH_SEP . 'config/schema.xml')) + { + $schema = file_get_contents(PATH_PLUGINS . $path[0] . PATH_SEP . 'config/schema.xml'); + $schema = preg_replace('/initialize(); + + pake_echo_action('propel', sprintf('dumping data to "%s"', $filename)); + + $data = new sfPropelData(); + $data->dumpData($filename); +} + +/** + * Loads yml data from fixtures directory and inserts into database. + * + * @example symfony load-data frontend + * @example symfony load-data frontend dev fixtures append + * + * @todo replace delete argument with flag -d + * + * @param object $task + * @param array $args + */ +function run_propel_load_data($task, $args) +{ + if (!count($args)) + { + throw new Exception('You must provide the app.'); + } + + $app = $args[0]; + + if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app)) + { + throw new Exception('The app "'.$app.'" does not exist.'); + } + + if (count($args) > 1 && $args[count($args) - 1] == 'append') + { + array_pop($args); + $delete = false; + } + else + { + $delete = true; + } + + $env = empty($args[1]) ? 'dev' : $args[1]; + + // define constants + define('SF_ROOT_DIR', sfConfig::get('sf_root_dir')); + define('SF_APP', $app); + define('SF_ENVIRONMENT', $env); + define('SF_DEBUG', true); + + // get configuration + require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'; + + if (count($args) == 1) + { + if (!$pluginDirs = glob(sfConfig::get('sf_root_dir').'/plugins/*/data')) + { + $pluginDirs = array(); + } + $fixtures_dirs = pakeFinder::type('dir')->name('fixtures')->in(array_merge($pluginDirs, array(sfConfig::get('sf_data_dir')))); + } + else + { + $fixtures_dirs = array_slice($args, 1); + } + + $databaseManager = new sfDatabaseManager(); + $databaseManager->initialize(); + + $data = new sfPropelData(); + $data->setDeleteCurrentData($delete); + + foreach ($fixtures_dirs as $fixtures_dir) + { + if (!is_readable($fixtures_dir)) + { + continue; + } + + pake_echo_action('propel', sprintf('load data from "%s"', $fixtures_dir)); + $data->loadData($fixtures_dir); + } +} + +function _call_phing($task, $task_name, $check_schema = true, $propelIni = 'propel.ini' , $propelDirectory = '' ) +{ + $schemas = pakeFinder::type('file')->name('*schema.xml')->relative()->follow_link()->in('config'); + if ($check_schema && !$schemas) + { + throw new Exception('You must create a schema.yml or schema.xml file.'); + } + + // call phing targets + pake_import('Phing', false); + +// if (false === strpos('propel-generator', get_include_path())) +// { +// set_include_path( PATH_THIRDPARTY . 'propel-generator/classes' . PATH_SEPARATOR. get_include_path()); +// } +// set_include_path(sfConfig::get('sf_root_dir').PATH_SEPARATOR.get_include_path()); + + if ( $propelDirectory == '' ) + $options = array( + 'project.dir' => PATH_CORE . 'config', + 'build.properties' => $propelIni, + 'propel.output.dir' => PATH_CORE , + ); + else + $options = array( + 'project.dir' => $propelDirectory . 'config', + 'build.properties' => $propelIni, + 'propel.output.dir' => $propelDirectory , + ); + + pakePhingTask::call_phing($task, array($task_name), + PATH_THIRDPARTY . 'propel-generator/build.xml', $options); + + chdir( PATH_CORE ); +} diff --git a/gulliver/bin/tasks/pakeTest.php b/gulliver/bin/tasks/pakeTest.php new file mode 100644 index 000000000..b40412f82 --- /dev/null +++ b/gulliver/bin/tasks/pakeTest.php @@ -0,0 +1,123 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +pake_desc('launch unit tests'); +pake_task('test-unit', 'project_exists'); + +pake_desc('launch functional tests for an application'); +pake_task('test-functional', 'project_exists'); + +pake_desc('launch all tests'); +pake_task('test-all', 'project_exists'); + +function run_test_all($task, $args) +{ + require_once(sfConfig::get('sf_symfony_lib_dir').'/lime/lime.php'); + + $h = new lime_harness(new lime_output_color()); + $h->base_dir = sfConfig::get('sf_test_dir'); + + // register all tests + $finder = pakeFinder::type('file')->ignore_version_control()->follow_link()->name('*Test.php'); + $h->register($finder->in($h->base_dir)); + + $h->run(); +} + +function run_test_functional($task, $args) +{ + if (!count($args)) + { + throw new Exception('You must provide the app to test.'); + } + + $app = $args[0]; + + if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app)) + { + throw new Exception(sprintf('The app "%s" does not exist.', $app)); + } + + if (isset($args[1])) + { + foreach (array_splice($args, 1) as $path) + { + $files = pakeFinder::type('file')->ignore_version_control()->follow_link()->name(basename($path).'Test.php')->in(sfConfig::get('sf_test_dir').DIRECTORY_SEPARATOR.'functional'.DIRECTORY_SEPARATOR.$app.DIRECTORY_SEPARATOR.dirname($path)); + foreach ($files as $file) + { + include($file); + } + } + } + else + { + require_once(sfConfig::get('sf_symfony_lib_dir').'/lime/lime.php'); + + $h = new lime_harness(new lime_output_color()); + $h->base_dir = sfConfig::get('sf_test_dir').'/functional/'.$app; + + // register functional tests + $finder = pakeFinder::type('file')->ignore_version_control()->follow_link()->name('*Test.php'); + $h->register($finder->in($h->base_dir)); + + $h->run(); + } +} + +function run_test_unit($task, $args) +{ + $environment = isset ( $arg[1] ) ? $arg[1] : G_TEST_ENV; + printf("start test in %s environment\n", pakeColor::colorize( $environment, 'INFO')); + define ( 'G_ENVIRONMENT', $environment ); + + if (isset($args[0])) + { + foreach ($args as $path) + { + $pathUnit = PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP . dirname($path); + $files = pakeFinder::type('file')->ignore_version_control()->follow_link()->name(basename($path).'Test.php')->in( $pathUnit ); + foreach ($files as $file) + { + $fName = str_replace ( PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP , '', $file ); + printf("\ntesting %s \n", pakeColor::colorize( $fName, 'INFO')); + include($file); + } + } + } + else + { + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + $h = new lime_harness(new lime_output_color()); + $h->base_dir = $pathUnit = PATH_CORE . 'test' . PATH_SEP . 'unit'; +// $h->base_dir = $pathUnit = PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP . "processmaker"; + + // register unit tests + $finder = pakeFinder::type('file')->ignore_version_control()->follow_link()->name('*Test.php'); + $h->register($finder->in($h->base_dir)); + + $h->run(); + } +} diff --git a/gulliver/bin/tasks/templates/authentication.php.tpl b/gulliver/bin/tasks/templates/authentication.php.tpl new file mode 100644 index 000000000..750e775d1 --- /dev/null +++ b/gulliver/bin/tasks/templates/authentication.php.tpl @@ -0,0 +1,106 @@ +VerifyLogin( $usr , $pwd); + switch ($uid) { + //The user not exists + case -1: + G::SendTemporalMessage ('ID_USER_NOT_REGISTERED', "warning"); + break; + //The password is incorrect + case -2: + G::SendTemporalMessage ('ID_WRONG_PASS', "warning"); + break; + //The user is inactive + case -3: + G::SendTemporalMessage ('ID_USER_INACTIVE', "warning"); + //The Due date is finished + case -4: + G::SendTemporalMessage ('ID_USER_INACTIVE', "warning"); + break; + } + + if ($uid < 0 ) { + G::header ("location: login.html"); + die; + } + + $_SESSION['USER_LOGGED'] = $uid; + $_SESSION['USR_USERNAME'] = $usr; + + // Asign the uid of user to userloggedobj + $RBAC->loadUserRolePermission( $RBAC->sSystem, $uid ); + $res = $RBAC->userCanAccess("{siglaProjectName}_LOGIN"); + + + if ($res != 1 ) { + if ($res == -2) + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); + else + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_PAGE', "error"); + G::header ("location: login.html"); + die; + } + + if (isset($frm['USER_LANG'])) { + if ($frm['USER_LANG'] != '') { + $lang = $frm['USER_LANG']; + } + } + else { + if (defined('SYS_LANG')) { + $lang = SYS_LANG; + } + else { + $lang = 'en'; + } + } + + + $accessLogin = $RBAC->userCanAccess("{siglaProjectName}_LOGIN"); + + //administrator + if ( $accessLogin == 1) { + G::header('location: /sys' . SYS_TEMP . '/' . $lang . '/' . SYS_SKIN . '/' . 'login/welcome'); + die; + } + + //Operador + if ( $accessLogin == 1) { + G::header('location: /sys' . SYS_TEMP . '/' . $lang . '/' . SYS_SKIN . '/' . 'login/welcome'); + die; + } + + + throw ( new Exception ( "the user $usr has no role assigned ($res, $uid)" ) ); + +} +catch ( Exception $e ) { + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; +} \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/bm.jpg.tpl b/gulliver/bin/tasks/templates/bm.jpg.tpl new file mode 100644 index 0000000000000000000000000000000000000000..0a3e7cce1f1cafd61114e3f8b642def5938263fc GIT binary patch literal 328 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{1QZ$iO7X$SlbC{|JL9(5Vb4fQ=m}tRTR^$i&KuEWs+u$jm03Bo-Vx|&a$Ql_KgarTJV&DNPXA)!H=;Uucj#j?8>hBzQ U?ZWp;x_|Ke8)@gd=J@}c0J{A$$^ZZW literal 0 HcmV?d00001 diff --git a/gulliver/bin/tasks/templates/bsm.jpg.tpl b/gulliver/bin/tasks/templates/bsm.jpg.tpl new file mode 100644 index 0000000000000000000000000000000000000000..ee151c40f7ef7a2ee6d7ed21c31460aeb68c7202 GIT binary patch literal 292 zcma)$OA5j;6h&{$*EF?>X{EFs6vy3zf>6*+>Czmy2tNbeNlYCSKNAl;c$^3K-Ea;M z*j>NvK_VULfN;YGf-%OK;9N{aoJ0ws5~FpZwXx=fHM7iSGvj@pd*9S`-LxY^2$52z zCM~TktHKr4c>H$>M>vHFoDzqLBh-;_!eXe3cNmq?7xqg7^QiM5i^00jh!_{HFqFhU P)M15ts}4)D-iON*g`gze literal 0 HcmV?d00001 diff --git a/gulliver/bin/tasks/templates/class.pmFunctions.php.tpl b/gulliver/bin/tasks/templates/class.pmFunctions.php.tpl new file mode 100644 index 000000000..c789cc48a --- /dev/null +++ b/gulliver/bin/tasks/templates/class.pmFunctions.php.tpl @@ -0,0 +1,26 @@ + diff --git a/gulliver/bin/tasks/templates/db.php.tpl b/gulliver/bin/tasks/templates/db.php.tpl new file mode 100644 index 000000000..e91b9a23c --- /dev/null +++ b/gulliver/bin/tasks/templates/db.php.tpl @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/dbInfo.php.tpl b/gulliver/bin/tasks/templates/dbInfo.php.tpl new file mode 100755 index 000000000..077a9160b --- /dev/null +++ b/gulliver/bin/tasks/templates/dbInfo.php.tpl @@ -0,0 +1,137 @@ + '; + if( eregi('[a-zA-Z]', $target) ) + $ntarget = gethostbyname($target); + else + $ntarget = gethostbyaddr($target); + $msg .= $ntarget; + return($msg); +} + + function getDbServicesAvailables() + { + $servicesAvailables = Array(); + + $dbServices = Array( + 'mysql' => Array( + 'id' => 'mysql', + 'command' => 'mysql_connect', + 'name' => 'MySql' + ), + 'pgsql' => Array( + 'id' => 'pgsql', + 'command' => 'pg_connect', + 'name' => 'PostgreSQL' + ), + 'mssql' => Array( + 'id' => 'mssql', + 'command' => 'mssql_connect', + 'name' => 'Microsoft SQL Server'), + 'oracle'=> Array( + 'id' => 'oracle', + 'command' => 'oci_connect', + 'name' => 'Oracle' + ), + 'informix'=> Array( + 'id' => 'informix', + 'command' => 'ifx_connect', + 'name' => 'Informix' + ), + 'sqlite' => Array( + 'id' => 'sqlite', + 'command' => 'sqlite_open', + 'name' => 'SQLite' + ) + ); + + foreach($dbServices as $service) { + if(@function_exists($service['command'])){ + $servicesAvailables[] = $service; + } + } + return $servicesAvailables; + } + + function getDbServerVersion($driver) { + try{ + switch($driver) + { + case 'mysql': + if($link = @mysql_connect( DB_HOST, DB_USER, DB_PASS)){ + $v = @mysql_get_server_info(); + } else { + throw new Exception(@mysql_error($link)); + } + break; + } + return (isset($v))?$v:'none'; + } catch (Exception $e){ + return ($e->getMessage()); + } + } + + if (file_exists(PATH_METHODS . 'login/version-{projectName}.php')) + { + include('version-{projectName}.php'); + } + else { + define('PRG_VERSION', 'Development Version'); + } + + if (getenv('HTTP_CLIENT_IP')) { + $ip = getenv('HTTP_CLIENT_IP'); + } + elseif(getenv('HTTP_X_FORWARDED_FOR')) { + $ip = getenv('HTTP_X_FORWARDED_FOR'); + } else { + $ip = getenv('REMOTE_ADDR'); + } + + $redhat = ''; + if ( file_exists ( '/etc/redhat-release' ) ) { + $fnewsize = filesize( '/etc/redhat-release' ); + $fp = fopen( '/etc/redhat-release' , 'r' ); + $redhat = fread( $fp, $fnewsize ); + fclose( $fp ); + } + + $redhat .= " (" . PHP_OS . ")"; + + //$dbNetView = new NET(DB_HOST); + //$dbNetView->loginDbServer(DB_USER, DB_PASS); + + $availdb = ''; + foreach ( getDbServicesAvailables() as $key => $val ) { + if ( $availdb != '' ) $availdb .= ', '; + $availdb .= $val['name']; + } + + $Fields['SYSTEM'] = $redhat; + $Fields['DATABASE'] = 'MySql (Version ' . getDbServerVersion('mysql') .')'; + $Fields['DATABASE_SERVER'] = DB_HOST; + $Fields['DATABASE_NAME'] = DB_NAME; + $Fields['PHP'] = phpversion(); + $Fields['FLUID'] = PRG_VERSION; + $Fields['IP'] = lookup ($ip); + $Fields['ENVIRONMENT'] = SYS_SYS; + $Fields['SERVER_SOFTWARE'] = getenv('SERVER_SOFTWARE'); + $Fields['SERVER_NAME'] = getenv('SERVER_NAME'); + $Fields['AVAILABLE_DB'] = $availdb; + $Fields['SERVER_PROTOCOL'] = getenv('SERVER_PROTOCOL'); + $Fields['SERVER_PORT'] = getenv('SERVER_PORT'); + $Fields['REMOTE_HOST'] = getenv('REMOTE_HOST'); + $Fields['SERVER_ADDR'] = getenv('SERVER_ADDR'); + $Fields['HTTP_USER_AGENT'] = getenv('HTTP_USER_AGENT'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/dbInfo', '', $Fields); + G::RenderPage('publish', 'raw'); diff --git a/gulliver/bin/tasks/templates/dbInfo.xml.tpl b/gulliver/bin/tasks/templates/dbInfo.xml.tpl new file mode 100755 index 000000000..acb4df45e --- /dev/null +++ b/gulliver/bin/tasks/templates/dbInfo.xml.tpl @@ -0,0 +1,43 @@ + + + + System Information + + + {projectName} + + + Operating System + + + + Web Server + + + Server Name + + + Server IP Address + + + PHP version + + + Database + + + Database Server IP Address + + + Database Name + + + Available Databases + + + User's Browser + + + User's Ip Address + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/db_insert.sql b/gulliver/bin/tasks/templates/db_insert.sql new file mode 100755 index 000000000..892cfebc0 --- /dev/null +++ b/gulliver/bin/tasks/templates/db_insert.sql @@ -0,0 +1,152 @@ +CREATE TABLE `LANGUAGE` ( + `LAN_ID` varchar(4) NOT NULL default '', + `LAN_NAME` varchar(30) NOT NULL default '', + `LAN_NATIVE_NAME` varchar(30) NOT NULL default '', + `LAN_DIRECTION` char(1) NOT NULL default 'L', + `LAN_WEIGHT` int(11) NOT NULL default '0', + `LAN_ENABLED` char(1) NOT NULL default '1', + `LAN_CALENDAR` varchar(30) NOT NULL default 'GREGORIAN', + PRIMARY KEY (`LAN_ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `LANGUAGE` +-- + +INSERT INTO `LANGUAGE` (`LAN_ID`, `LAN_NAME`, `LAN_NATIVE_NAME`, `LAN_DIRECTION`, `LAN_WEIGHT`, `LAN_ENABLED`, `LAN_CALENDAR`) VALUES +('aa', 'Afar', '', 'L', 0, '0', 'GREGORIAN'), +('ab', 'Abkhazian', '', 'L', 1, '0', 'GREGORIAN'), +('af', 'Afrikaans', '', 'L', 2, '0', 'GREGORIAN'), +('am', 'Amharic', '', 'L', 3, '0', 'GREGORIAN'), +('ar', 'Arabic', '', 'L', 4, '0', 'GREGORIAN'), +('as', 'Assamese', '', 'L', 5, '0', 'GREGORIAN'), +('ay', 'Aymara', '', 'L', 6, '0', 'GREGORIAN'), +('az', 'Azerbaijani', '', 'L', 7, '0', 'GREGORIAN'), +('ba', 'Bashkir', '', 'L', 8, '0', 'GREGORIAN'), +('be', 'Byelorussian', '', 'L', 9, '0', 'GREGORIAN'), +('bg', 'Bulgarian', '', 'L', 10, '0', 'GREGORIAN'), +('bh', 'Bihari', '', 'L', 11, '0', 'GREGORIAN'), +('bi', 'Bislama', '', 'L', 12, '0', 'GREGORIAN'), +('bn', 'Bengali', '', 'L', 13, '0', 'GREGORIAN'), +('bo', 'Tibetan', '', 'L', 14, '0', 'GREGORIAN'), +('br', 'Breton', '', 'L', 15, '0', 'GREGORIAN'), +('ca', 'Catalan', '', 'L', 16, '0', 'GREGORIAN'), +('co', 'Corsican', '', 'L', 17, '0', 'GREGORIAN'), +('cs', 'Czech', '', 'L', 18, '0', 'GREGORIAN'), +('cy', 'Welsh', '', 'L', 19, '0', 'GREGORIAN'), +('da', 'Danish', '', 'L', 20, '0', 'GREGORIAN'), +('de', 'German', '', 'L', 21, '0', 'GREGORIAN'), +('dz', 'Bhutani', '', 'L', 22, '0', 'GREGORIAN'), +('el', 'Greek', '', 'L', 23, '0', 'GREGORIAN'), +('en', 'English', '', 'L', 24, '1', 'GREGORIAN'), +('eo', 'Esperanto', '', 'L', 25, '0', 'GREGORIAN'), +('es', 'Spanish', 'Español', 'L', 26, '0', 'GREGORIAN'), +('et', 'Estonian', '', 'L', 27, '0', 'GREGORIAN'), +('eu', 'Basque', '', 'L', 28, '0', 'GREGORIAN'), +('fa', 'Persian', '', 'R', 29, '0', 'PERSIAN'), +('fi', 'Finnish', '', 'L', 30, '0', 'GREGORIAN'), +('fj', 'Fiji', '', 'L', 31, '0', 'GREGORIAN'), +('fo', 'Faeroese', '', 'L', 32, '0', 'GREGORIAN'), +('fr', 'French', '', 'L', 33, '0', 'GREGORIAN'), +('fy', 'Frisian', '', 'L', 34, '0', 'GREGORIAN'), +('ga', 'Irish', '', 'L', 35, '0', 'GREGORIAN'), +('gd', 'Gaelic', '', 'L', 36, '0', 'GREGORIAN'), +('gl', 'Galician', '', 'L', 37, '0', 'GREGORIAN'), +('gn', 'Guarani', '', 'L', 38, '0', 'GREGORIAN'), +('gu', 'Gujarati', '', 'L', 39, '0', 'GREGORIAN'), +('ha', 'Hausa', '', 'L', 40, '0', 'GREGORIAN'), +('hi', 'Hindi', '', 'L', 41, '0', 'GREGORIAN'), +('hr', 'Croatian', '', 'L', 42, '0', 'GREGORIAN'), +('hu', 'Hungarian', '', 'L', 43, '0', 'GREGORIAN'), +('hy', 'Armenian', '', 'L', 44, '0', 'GREGORIAN'), +('ia', 'Interlingua', '', 'L', 45, '0', 'GREGORIAN'), +('ie', 'Interlingue', '', 'L', 46, '0', 'GREGORIAN'), +('ik', 'Inupiak', '', 'L', 47, '0', 'GREGORIAN'), +('in', 'Indonesian', '', 'L', 48, '0', 'GREGORIAN'), +('is', 'Icelandic', '', 'L', 49, '0', 'GREGORIAN'), +('it', 'Italian', '', 'L', 50, '0', 'GREGORIAN'), +('iw', 'Hebrew', '', 'L', 51, '0', 'GREGORIAN'), +('ja', 'Japanese', '', 'L', 52, '0', 'GREGORIAN'), +('ji', 'Yiddish', '', 'L', 53, '0', 'GREGORIAN'), +('jw', 'Javanese', '', 'L', 54, '0', 'GREGORIAN'), +('ka', 'Georgian', '', 'L', 55, '0', 'GREGORIAN'), +('kk', 'Kazakh', '', 'L', 56, '0', 'GREGORIAN'), +('kl', 'Greenlandic', '', 'L', 57, '0', 'GREGORIAN'), +('km', 'Cambodian', '', 'L', 58, '0', 'GREGORIAN'), +('kn', 'Kannada', '', 'L', 59, '0', 'GREGORIAN'), +('ko', 'Korean', '', 'L', 60, '0', 'GREGORIAN'), +('ks', 'Kashmiri', '', 'L', 61, '0', 'GREGORIAN'), +('ku', 'Kurdish', '', 'L', 62, '0', 'GREGORIAN'), +('ky', 'Kirghiz', '', 'L', 63, '0', 'GREGORIAN'), +('la', 'Latin', '', 'L', 64, '0', 'GREGORIAN'), +('ln', 'Lingala', '', 'L', 65, '0', 'GREGORIAN'), +('lo', 'Laothian', '', 'L', 66, '0', 'GREGORIAN'), +('lt', 'Lithuanian', '', 'L', 67, '0', 'GREGORIAN'), +('lv', 'Latvian', '', 'L', 68, '0', 'GREGORIAN'), +('mg', 'Malagasy', '', 'L', 69, '0', 'GREGORIAN'), +('mi', 'Maori', '', 'L', 70, '0', 'GREGORIAN'), +('mk', 'Macedonian', '', 'L', 71, '0', 'GREGORIAN'), +('ml', 'Malayalam', '', 'L', 72, '0', 'GREGORIAN'), +('mn', 'Mongolian', '', 'L', 73, '0', 'GREGORIAN'), +('mo', 'Moldavian', '', 'L', 74, '0', 'GREGORIAN'), +('mr', 'Marathi', '', 'L', 75, '0', 'GREGORIAN'), +('ms', 'Malay', '', 'L', 76, '0', 'GREGORIAN'), +('mt', 'Maltese', '', 'L', 77, '0', 'GREGORIAN'), +('my', 'Burmese', '', 'L', 78, '0', 'GREGORIAN'), +('na', 'Nauru', '', 'L', 79, '0', 'GREGORIAN'), +('ne', 'Nepali', '', 'L', 80, '0', 'GREGORIAN'), +('nl', 'Dutch', '', 'L', 81, '0', 'GREGORIAN'), +('no', 'Norwegian', '', 'L', 82, '0', 'GREGORIAN'), +('oc', 'Occitan', '', 'L', 83, '0', 'GREGORIAN'), +('om', 'Oromo', '', 'L', 84, '0', 'GREGORIAN'), +('or', 'Oriya', '', 'L', 85, '0', 'GREGORIAN'), +('pa', 'Punjabi', '', 'L', 86, '0', 'GREGORIAN'), +('pl', 'Polish', '', 'L', 87, '0', 'GREGORIAN'), +('ps', 'Pashto', '', 'L', 88, '0', 'GREGORIAN'), +('pt', 'Portuguese', '', 'L', 89, '0', 'GREGORIAN'), +('qu', 'Quechua', '', 'L', 90, '0', 'GREGORIAN'), +('rm', 'Rhaeto-Romance', '', 'L', 91, '0', 'GREGORIAN'), +('rn', 'Kirundi', '', 'L', 92, '0', 'GREGORIAN'), +('ro', 'Romanian', '', 'L', 93, '0', 'GREGORIAN'), +('ru', 'Russian', '', 'L', 94, '0', 'GREGORIAN'), +('rw', 'Kinyarwanda', '', 'L', 95, '0', 'GREGORIAN'), +('sa', 'Sanskrit', '', 'L', 96, '0', 'GREGORIAN'), +('sd', 'Sindhi', '', 'L', 97, '0', 'GREGORIAN'), +('sg', 'Sangro', '', 'L', 98, '0', 'GREGORIAN'), +('sh', 'Serbo-Croatian', '', 'L', 99, '0', 'GREGORIAN'), +('si', 'Singhalese', '', 'L', 100, '0', 'GREGORIAN'), +('sk', 'Slovak', '', 'L', 101, '0', 'GREGORIAN'), +('sl', 'Slovenian', '', 'L', 102, '0', 'GREGORIAN'), +('sm', 'Samoan', '', 'L', 103, '0', 'GREGORIAN'), +('sn', 'Shona', '', 'L', 104, '0', 'GREGORIAN'), +('so', 'Somali', '', 'L', 105, '0', 'GREGORIAN'), +('sq', 'Albanian', '', 'L', 106, '0', 'GREGORIAN'), +('sr', 'Serbian', '', 'L', 107, '0', 'GREGORIAN'), +('ss', 'Siswati', '', 'L', 108, '0', 'GREGORIAN'), +('st', 'Sesotho', '', 'L', 109, '0', 'GREGORIAN'), +('su', 'Sudanese', '', 'L', 110, '0', 'GREGORIAN'), +('sv', 'Swedish', '', 'L', 111, '0', 'GREGORIAN'), +('sw', 'Swahili', '', 'L', 112, '0', 'GREGORIAN'), +('ta', 'Tamil', '', 'L', 113, '0', 'GREGORIAN'), +('te', 'Tegulu', '', 'L', 114, '0', 'GREGORIAN'), +('tg', 'Tajik', '', 'L', 115, '0', 'GREGORIAN'), +('th', 'Thai', '', 'L', 116, '0', 'GREGORIAN'), +('ti', 'Tigrinya', '', 'L', 117, '0', 'GREGORIAN'), +('tk', 'Turkmen', '', 'L', 118, '0', 'GREGORIAN'), +('tl', 'Tagalog', '', 'L', 119, '0', 'GREGORIAN'), +('tn', 'Setswana', '', 'L', 120, '0', 'GREGORIAN'), +('to', 'Tonga', '', 'L', 121, '0', 'GREGORIAN'), +('tr', 'Turkish', '', 'L', 122, '0', 'GREGORIAN'), +('ts', 'Tsonga', '', 'L', 123, '0', 'GREGORIAN'), +('tt', 'Tatar', '', 'L', 124, '0', 'GREGORIAN'), +('tw', 'Twi', '', 'L', 125, '0', 'GREGORIAN'), +('uk', 'Ukrainian', '', 'L', 126, '0', 'GREGORIAN'), +('ur', 'Urdu', '', 'L', 127, '0', 'GREGORIAN'), +('uz', 'Uzbek', '', 'L', 128, '0', 'GREGORIAN'), +('vi', 'Vietnamese', '', 'L', 129, '0', 'GREGORIAN'), +('vo', 'Volapuk', '', 'L', 130, '0', 'GREGORIAN'), +('wo', 'Wolof', '', 'L', 131, '0', 'GREGORIAN'), +('xh', 'Xhosa', '', 'L', 132, '0', 'GREGORIAN'), +('yo', 'Yoruba', '', 'L', 133, '0', 'GREGORIAN'), +('zh', 'Chinese', '', 'L', 134, '0', 'GREGORIAN'), +('zu', 'Zulu', '', 'L', 135, '0', 'GREGORIAN'); diff --git a/gulliver/bin/tasks/templates/defines.php.tpl b/gulliver/bin/tasks/templates/defines.php.tpl new file mode 100644 index 000000000..eae726edc --- /dev/null +++ b/gulliver/bin/tasks/templates/defines.php.tpl @@ -0,0 +1,42 @@ +=")) { + date_default_timezone_set("America/La_Paz"); + } + else { + // you're not + } + diff --git a/gulliver/bin/tasks/templates/green.html.tpl b/gulliver/bin/tasks/templates/green.html.tpl new file mode 100644 index 000000000..bd5eca772 --- /dev/null +++ b/gulliver/bin/tasks/templates/green.html.tpl @@ -0,0 +1,123 @@ + + + {$username} + + + + {$header} + + + + + + + + + + + +
+ + + + + + + + + +
+
{php}if ((int)$_SESSION['USER_LOGGED'] != 0) {{/php}{php}echo G::LoadTranslation('ID_LOGOUT');{/php}{php}}{/php}    
+
+
+
+
+ + + + + + {php} + global $G_TMP_MENU_ALIGN; + {/php} + + + + + + + + +
+
+ + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') + { + G::LoadTemplate($G_TEMPLATE); + } + {/php} +
+
+ +
+ + + + + diff --git a/gulliver/bin/tasks/templates/green.php.tpl b/gulliver/bin/tasks/templates/green.php.tpl new file mode 100644 index 000000000..fc0698c48 --- /dev/null +++ b/gulliver/bin/tasks/templates/green.php.tpl @@ -0,0 +1,35 @@ +template_dir = PATH_SKINS; + $smarty->compile_dir = PATH_SMARTY_C; + $smarty->cache_dir = PATH_SMARTY_CACHE; + $smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + + global $G_ENABLE_BLANK_SKIN; + + if ( isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN ) { + $smarty->display('blank.html'); + } + else { + $oHeadPublisher =& headPublisher::getSingleton(); + if (isset($oHeadPublisher)) $header = $oHeadPublisher->printHeader(); + $smarty->assign('username', (isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : '') ); + $smarty->assign('header', $header ); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html' ); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html' ); + $smarty->display('green.html'); + } diff --git a/gulliver/bin/tasks/templates/httpd.conf.tpl b/gulliver/bin/tasks/templates/httpd.conf.tpl new file mode 100644 index 000000000..3d4b5e06b --- /dev/null +++ b/gulliver/bin/tasks/templates/httpd.conf.tpl @@ -0,0 +1,30 @@ +NameVirtualHost your_ip_address + +#{projectName} virtual host + + ServerName "your_{projectName}_server" + DocumentRoot {pathHome}/public_html + DirectoryIndex index.html index.php + + AddDefaultCharset UTF-8 + + AllowOverRide none + Options FollowSymlinks + Order allow,deny + Allow from all + + RewriteEngine on + RewriteRule ^.*/(.*)$ sysGeneric.php [NC,L] + + ExpiresActive On + ExpiresDefault "access plus 1 day" + ExpiresByType image/gif "access plus 1 day" + ExpiresByType image/png "access plus 1 day" + ExpiresByType image/jpg "access plus 1 day" + ExpiresByType text/css "access plus 1 day" + ExpiresByType text/javascript "access plus 1 day" + + AddOutputFilterByType DEFLATE text/html + + + diff --git a/gulliver/bin/tasks/templates/index.html.tpl b/gulliver/bin/tasks/templates/index.html.tpl new file mode 100644 index 000000000..667bbbc82 --- /dev/null +++ b/gulliver/bin/tasks/templates/index.html.tpl @@ -0,0 +1,8 @@ + + +Redirector + + + + + diff --git a/gulliver/bin/tasks/templates/login.php.tpl b/gulliver/bin/tasks/templates/login.php.tpl new file mode 100644 index 000000000..9beb75d8f --- /dev/null +++ b/gulliver/bin/tasks/templates/login.php.tpl @@ -0,0 +1,66 @@ + 0 ) +{ + $_SESSION['G_MESSAGE'] = $msg; +} +if (strlen($msgType) > 0 ) +{ + $_SESSION['G_MESSAGE_TYPE'] = $msgType; +} + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/login', '', '', SYS_URI.'login/authentication.php'); + +G::RenderPage( "publish" ); +?> + diff --git a/gulliver/bin/tasks/templates/login.xml.tpl b/gulliver/bin/tasks/templates/login.xml.tpl new file mode 100644 index 000000000..1991742a3 --- /dev/null +++ b/gulliver/bin/tasks/templates/login.xml.tpl @@ -0,0 +1,20 @@ + + + + <en>Login</en> + + + User + + + Password + + +SELECT LAN_ID, LAN_NAME FROM LANGUAGE WHERE LAN_ENABLED = "1" ORDER BY LAN_WEIGHT DESC + Language + + + Login + + + diff --git a/gulliver/bin/tasks/templates/mainmenu.php.tpl b/gulliver/bin/tasks/templates/mainmenu.php.tpl new file mode 100755 index 000000000..43e0cd8fb --- /dev/null +++ b/gulliver/bin/tasks/templates/mainmenu.php.tpl @@ -0,0 +1,26 @@ +AddIdRawOption('USERS', 'users/usersList'); +//$G_TMP_MENU->AddIdRawOption('REPORTS', 'login/welcome'); +$G_TMP_MENU->AddIdRawOption('WELCOME', 'login/welcome'); + +$G_TMP_MENU->Labels = array( + G::LoadTranslation('ID_USERS'), +// G::LoadTranslation('ID_REPORTS'), + G::LoadTranslation('ID_WELCOME') + +); + +/* + +if ($RBAC->userCanAccess('PM_USERS') != 1) +{ + $G_TMP_MENU->DisableOptionId('USERS'); +} +*/ \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/paths.php.tpl b/gulliver/bin/tasks/templates/paths.php.tpl new file mode 100644 index 000000000..b3c7b849b --- /dev/null +++ b/gulliver/bin/tasks/templates/paths.php.tpl @@ -0,0 +1,70 @@ +listAllPermissions( '{rbacProjectName}'); + $G_MAIN_MENU = '{projectName}'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'PERMISSIONS'; + + + $rs = RolesPeer::doSelectRs ( $oCriteria ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $rs->next(); + $row = $rs->getRow(); + } + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'users/permissionsList', $oCriteria); + + G::RenderPage('publish'); diff --git a/gulliver/bin/tasks/templates/permissionsList.xml.tpl b/gulliver/bin/tasks/templates/permissionsList.xml.tpl new file mode 100644 index 000000000..009d24ee0 --- /dev/null +++ b/gulliver/bin/tasks/templates/permissionsList.xml.tpl @@ -0,0 +1,26 @@ + + + + # + + + + Permission Name + + + + Create Date + + + + Update Date + + + + Status + + + + diff --git a/gulliver/bin/tasks/templates/pluginClass.tpl b/gulliver/bin/tasks/templates/pluginClass.tpl new file mode 100644 index 000000000..797dac413 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginClass.tpl @@ -0,0 +1,166 @@ + + //here we are defining the available charts, the dashboard setup will call this function to know the charts + function getAvailableCharts( ) { + return array ( + '{className}Chart', + ); + } + + function getChart( $chartName ) { + $prePath = '/sys' . SYS_SYS . '/' . SYS_LANG . '/blank/'; + $obj = new StdClass(); + switch ($chartName) { + case '{className}Chart': + $obj->title = '{className} Chart - Per Forum'; + break; + } + $obj->height = 220; + $obj->open->image = $prePath . '{className}/drawChart?chart=' . $chartName . "&u="; + return $obj; + } + + /* definition of all charts */ + /* that definition comes in two parts : + /* 1. the getXX () function to get the data from the databases + /* 2. the XX () function to draw the graph + */ + + /** chart {className} ***/ + function get{className}Chart ( ) { + $dataSet = array(); + $past1months = mktime(0, 0, 0, date("m") -1 , date("d"), date("Y")); + + $con = Propel::getConnection('workflow'); + $sql = "select CON_VALUE, COUNT(*) AS CANT from APPLICATION LEFT JOIN CONTENT ON ( CON_CATEGORY = 'PRO_TITLE' AND CON_ID = PRO_UID AND CON_LANG = 'en' ) GROUP BY CON_VALUE" ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + if ( strlen ( trim ($row['CON_VALUE']) ) > 0 ) { + $label[] = $row['CON_VALUE']; + $data[] = $row['CANT']; + } + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $aux = intval($max / 6 ) * 6 + 6; + $dataSet['max'] = $aux; + + return $dataSet; + } + + function {className}Chart( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + $dataSet = $this->get{className}Chart(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + } + + $chart->setDataSet($dataPostSet); + $chart->setTitle( " Posts by Week " ); + $chart->render(); + } + + + + + + + //here we are defining the available charts, the dashboard setup will call this function to know the charts + function getAvailableReports( ) { + return array ( + array ( 'uid'=>'{className}Report_1', 'title'=>'{className} Test Report (users)' ), + //array ( 'uid'=>'{className}Report_2', 'title'=>'{className} Test Report (groups)' ) + ); + } + + function getReport( $reportName ) { + $obj = new StdClass(); + switch ( $reportName ) { + case '{className}Report_1': + $obj->title = '{className} Test Report (users)'; + break; + case '{className}Report_2': + $obj->title = '{className} Test Report (users)'; + break; + default: + $obj->title = 'default ....'; + break; + } + return $obj; + } + + function {className}Report_1() { + global $G_PUBLISH; + require_once 'classes/model/Users.php'; + $sDelimiter = DBAdapter::getStringDelimiter(); + $aUsers = array(); + $aUsers[] = array('USR_UID' => 'char', + 'USR_NAME' => 'char', + 'USR_FIRSTNAME' => 'char', + 'USR_LASTNAME' => 'char', + 'USR_EMAIL' => 'char', + 'USR_ROLE' => 'char',); + + $con = Propel::getConnection('workflow'); + $sql = 'SELECT USR_UID,USR_USERNAME,USR_FIRSTNAME,USR_LASTNAME,USR_EMAIL,USR_ROLE FROM USERS'; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $aUsers[] = array('USR_UID' => $row['USR_UID'], + 'USR_NAME' => $row['USR_USERNAME'], + 'USR_FIRSTNAME' => $row['USR_FIRSTNAME'], + 'USR_LASTNAME' => $row['USR_LASTNAME'], + 'USR_EMAIL' => $row['USR_EMAIL'], + 'USR_ROLE' => $row['USR_ROLE']); + $rs->next(); + $row = $rs->getRow(); + } + + global $_DBArray; + $_DBArray['users'] = $aUsers; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('users'); + $oCriteria->addDescendingOrderByColumn('USR_USERNAME'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', '{className}/report', $oCriteria); + G::RenderPage('publish'); + return 1; + } + + + + } \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginDelete.tpl b/gulliver/bin/tasks/templates/pluginDelete.tpl new file mode 100644 index 000000000..9cd02264a --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginDelete.tpl @@ -0,0 +1,38 @@ + + ${phpName} = str_replace ( '"', '', $aux[$index++] ); + + + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = {className}Peer::retrieveByPK( {keylist} ); + + if ( ( is_object ( $tr ) && get_class ($tr) == '{className}' ) ) { + + $fields['{name}'] = $tr->get{phpName}(); + $fields['LABEL_{name}'] = $tr->get{phpName}(); + + } + else + $fields = array(); + + $G_MAIN_MENU = '{projectName}'; + $G_SUB_MENU = '{phpClassName}'; + $G_ID_MENU_SELECTED = '{menuId}'; + $G_ID_SUB_MENU_SELECTED = '{menuId}'; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', '{phpFolderName}/{phpClassName}Delete', '', $fields, '{phpClassName}DeleteExec' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginDeleteExec.tpl b/gulliver/bin/tasks/templates/pluginDeleteExec.tpl new file mode 100644 index 000000000..d68b55e34 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginDeleteExec.tpl @@ -0,0 +1,31 @@ + + ${phpName} = $form['{name}']; + + + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = {className}Peer::retrieveByPK( {keylist} ); + if ( ( is_object ( $tr ) && get_class ($tr) == '{className}' ) ) { + $tr->delete(); + } + + G::Header('location: {phpClassName}List'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginDrawChart.php.tpl b/gulliver/bin/tasks/templates/pluginDrawChart.php.tpl new file mode 100755 index 000000000..31c485ebb --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginDrawChart.php.tpl @@ -0,0 +1,14 @@ +{ $chartType }(); + die; + } + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginEdit.tpl b/gulliver/bin/tasks/templates/pluginEdit.tpl new file mode 100644 index 000000000..ae199b4df --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginEdit.tpl @@ -0,0 +1,34 @@ + + ${phpName} = str_replace ( '"', '', $aux[{index}] ); + + + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = {className}Peer::retrieveByPK( {keylist} ); + + if ( ( is_object ( $tr ) && get_class ($tr) == '{className}' ) ) { + + $fields['{name}'] = $tr->get{phpName}(); + + } + else + $fields = array(); + + $G_MAIN_MENU = '{projectName}'; + $G_SUB_MENU = '{phpClassName}'; + $G_ID_MENU_SELECTED = '{menuId}'; + $G_ID_SUB_MENU_SELECTED = '{menuId}'; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', '{phpFolderName}/{phpClassName}Edit', '', $fields, '{phpClassName}Save' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginList.tpl b/gulliver/bin/tasks/templates/pluginList.tpl new file mode 100644 index 000000000..c0cdef5a5 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginList.tpl @@ -0,0 +1,36 @@ + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + + $Criteria = new Criteria('workflow'); + $Criteria->clearSelectColumns ( ); + + + $Criteria->addSelectColumn ( {className}Peer::{name} ); + + + $Criteria->add ( {phpClassName}Peer::{firstKey}, "xx" , CRITERIA::NOT_EQUAL ); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', '{phpFolderName}/{phpClassName}List', $Criteria , array(),''); + G::RenderPage('publish'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } diff --git a/gulliver/bin/tasks/templates/pluginMainFile.tpl b/gulliver/bin/tasks/templates/pluginMainFile.tpl new file mode 100644 index 000000000..590af9cb9 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginMainFile.tpl @@ -0,0 +1,65 @@ +sFriendlyName = '{className} Plugin'; + $this->sDescription = 'Autogenerated plugin for class {className}'; + $this->sPluginFolder = '{className}'; + $this->sSetupPage = '{className}'; + $this->iVersion = 0.78; + //$this->iPMVersion = 2425; + $this->aWorkspaces = null; + //$this->aWorkspaces = array('os'); + return $res; + } + + function setup() { + + $this->setCompanyLogo ('/plugin/{className}/{className}.png'); + + + $this->registerMenu( 'setup', 'menu{className}.php'); + + + $this->registerMenu( 'processmaker', 'menu{className}OnTransit.php'); + + + $this->registerStep( '{GUID}', 'step{className}', '{className} external step' ); + + + $this->registerDashboard(); + + + $this->registerReport(); + + + $this->registerPmFunction(); + + + $this->redirectLogin( 'PROCESSMAKER_{className}', 'users/users_List' ); + + } + + function install() { + + $RBAC = RBAC::getSingleton() ; + $RBAC->initRBAC(); + $roleData = array(); + $roleData['ROL_UID'] = G::GenerateUniqueId(); + $roleData['ROL_PARENT'] = ''; + $roleData['ROL_SYSTEM'] = '00000000000000000000000000000002'; + $roleData['ROL_CODE'] = 'PROCESSMAKER_{className}'; + $roleData['ROL_CREATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $roleData['ROL_STATUS'] = '1'; + $RBAC->createRole ( $roleData ); + $RBAC->createPermision ('PM_{className}' ); + + } +} + +$oPluginRegistry =& PMPluginRegistry::getSingleton(); +$oPluginRegistry->registerPlugin('{className}', __FILE__); diff --git a/gulliver/bin/tasks/templates/pluginMenu.tpl b/gulliver/bin/tasks/templates/pluginMenu.tpl new file mode 100644 index 000000000..d0902fa95 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginMenu.tpl @@ -0,0 +1,5 @@ +AddIdRawOption('{menuId}', '{phpClassName}/{phpClassName}List', "{className}" ); + +?> \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginMenuOnTransit.tpl b/gulliver/bin/tasks/templates/pluginMenuOnTransit.tpl new file mode 100644 index 000000000..0a1079a58 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginMenuOnTransit.tpl @@ -0,0 +1,5 @@ +AddIdRawOption('{menuId}_ONTRANSIT', '{phpClassName}/{phpClassName}OnTransitList', "ON_TRANSIT" ); + +?> \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginNew.tpl b/gulliver/bin/tasks/templates/pluginNew.tpl new file mode 100644 index 000000000..6175cde29 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginNew.tpl @@ -0,0 +1,37 @@ + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + + + //if exists the row in the database propel will update it, otherwise will insert. +// $tr = {phpClassName}Peer::retrieveByPK( {keylist} ); +// if ( ( is_object ( $tr ) && get_class ($tr) == '{phpClassName}' ) ) { +// } +// else +// $fields = array(); +// $fields['ITM_UID'] = $ItmUid; + + + + $fields['{name}'] = G::GenerateUniqueID();; + + + + $fields['{name}'] = ''; + + + $G_MAIN_MENU = '{projectName}'; + $G_SUB_MENU = '{phpClassName}'; + $G_ID_MENU_SELECTED = '{menuId}'; + $G_ID_SUB_MENU_SELECTED = '{menuId}'; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', '{phpFolderName}/{phpClassName}Edit', '', $fields, '{phpClassName}Save' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginOnTransitList.php.tpl b/gulliver/bin/tasks/templates/pluginOnTransitList.php.tpl new file mode 100644 index 000000000..f093acfd5 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginOnTransitList.php.tpl @@ -0,0 +1,35 @@ +userCanAccess("PM_CASES"))!=1) return $RBAC_Response; + + /* Includes */ + G::LoadClass('case'); + G::LoadClass('configuration'); + + /* GET , POST & $_SESSION Vars */ + $conf = new Configurations(); + + $sTypeList = 'to_do'; + + $sUIDUserLogged = $_SESSION['USER_LOGGED']; + + /* Menues */ + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = '{className}/menu{className}'; + $G_ID_MENU_SELECTED = '{menuId}'; + $G_ID_SUB_MENU_SELECTED = '{menuId}'; + + $oCases = new Cases(); + list($Criteria,$xmlfile) = $oCases->getConditionCasesList( $sTypeList, $sUIDUserLogged); + $xmlfile = '{className}/{className}OnTransitList'; + /* Render page */ + + //require_once ( 'classes/class.extendGulliver.php' ); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'propeltable', '{className}/paged-table', '{className}/{className}OnTransitList', $Criteria ); + G::RenderPage( "publish" ); diff --git a/gulliver/bin/tasks/templates/pluginOnTransitList.xml.tpl b/gulliver/bin/tasks/templates/pluginOnTransitList.xml.tpl new file mode 100644 index 000000000..aeebda987 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginOnTransitList.xml.tpl @@ -0,0 +1,85 @@ + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + Sent by + + + + Due Date + + + + Last Modification + + + + Priority + + + + + + + + + + Start Date + + + + + + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + diff --git a/gulliver/bin/tasks/templates/pluginPaged-table.html.tpl b/gulliver/bin/tasks/templates/pluginPaged-table.html.tpl new file mode 100644 index 000000000..f7a0c2419 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginPaged-table.html.tpl @@ -0,0 +1,75 @@ + +
+
+
+ + + + +
+ + {title} + + + + +
{content}
+ + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + +
+ {header} +
  + {noRecordsFound}
  +
+ + + + + + + +
+ {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
+
+ +
+
+
+
+ \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginPropel.ini.tpl b/gulliver/bin/tasks/templates/pluginPropel.ini.tpl new file mode 100644 index 000000000..731546490 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginPropel.ini.tpl @@ -0,0 +1,46 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = {className} +propel.database = mysql +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/{className} + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/sql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false + diff --git a/gulliver/bin/tasks/templates/pluginPropel.mysql.ini.tpl b/gulliver/bin/tasks/templates/pluginPropel.mysql.ini.tpl new file mode 100644 index 000000000..3ca99ab16 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginPropel.mysql.ini.tpl @@ -0,0 +1,46 @@ +propel.targetPackage = model +propel.packageObjectModel = true +propel.project = {className} +propel.database = mysql +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/{className} + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/mysql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginReport.xml.tpl b/gulliver/bin/tasks/templates/pluginReport.xml.tpl new file mode 100755 index 000000000..5e7f5e46d --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginReport.xml.tpl @@ -0,0 +1,26 @@ + + + + + Uid + + + Name + + + First Name + + + + Last Name + + + + Email + + + + Role + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginSave.tpl b/gulliver/bin/tasks/templates/pluginSave.tpl new file mode 100644 index 000000000..49b04f787 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginSave.tpl @@ -0,0 +1,53 @@ + + ${phpName} = $form['{name}']; + + + + require_once ( PATH_PLUGINS . '{pluginName}' . PATH_SEP . 'class.{pluginName}.php'); + $pluginObj = new {pluginName}Class (); + + + require_once ( "classes/model/{className}.php" ); + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = {className}Peer::retrieveByPK( {keylist} ); + if ( ! ( is_object ( $tr ) && get_class ($tr) == '{className}' ) ) { + $tr = new {className}(); + } + + $tr->set{phpName}( ${phpName} ); + + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "
"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + //to do: uniform coderror structures for all classes + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + G::Header('location: {phpClassName}List'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginSchema.xml.tpl b/gulliver/bin/tasks/templates/pluginSchema.xml.tpl new file mode 100644 index 000000000..aae41bf43 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginSchema.xml.tpl @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/gulliver/bin/tasks/templates/pluginStep.tpl b/gulliver/bin/tasks/templates/pluginStep.tpl new file mode 100644 index 000000000..6da1aef1d --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginStep.tpl @@ -0,0 +1,8 @@ + 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); +$rows[] = array ( 'uid' => 11, 'name' => 'john', 'age' => 44, 'balance' => 123423 ); +$rows[] = array ( 'uid' => 22, 'name' => 'Amy', 'age' => 33, 'balance' => 23456 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Dan', 'age' => 22, 'balance' => 34567 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Mike', 'age' => 21, 'balance' => 4567 ); +$rows[] = array ( 'uid' => 44, 'name' => 'Paul', 'age' => 22, 'balance' => 567 ); +$rows[] = array ( 'uid' => 55, 'name' => 'Wil', 'age' => 23, 'balance' => 67 ); +$rows[] = array ( 'uid' => 66, 'name' => 'Ernest', 'age' => 24, 'balance' => 7 ); +$rows[] = array ( 'uid' => 77, 'name' => 'Albert', 'age' => 25, 'balance' => 84567 ); +$rows[] = array ( 'uid' => 88, 'name' => 'Sue', 'age' => 26, 'balance' => 94567 ); +$rows[] = array ( 'uid' => 99, 'name' => 'Freddy', 'age' => 22, 'balance' => 04567 ); + +$_DBArray['user'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; +//krumo ( $_DBArray ); + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('user'); + //$c->add ( 'user.age', 122 , Criteria::GREATER_EQUAL ); + //$c->add ( 'user.balance', 3456 , Criteria::GREATER_EQUAL ); + $c->addAscendingOrderByColumn ('name'); +/* + $rs = ArrayBasePeer::doSelectRs ( $c ); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $rs->next(); + $row = $rs->getRow(); + } +*/ + /* Render page */ + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'WELCOME'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = '{menuId}'; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'propeltable', 'paged-table', '{className}/welcome', $c ); + G::RenderPage( "publish" ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish'); +} diff --git a/gulliver/bin/tasks/templates/pluginXmlform.tpl b/gulliver/bin/tasks/templates/pluginXmlform.tpl new file mode 100644 index 000000000..713bba6a4 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginXmlform.tpl @@ -0,0 +1,23 @@ + + + + + {className} form + + + +<{name} type="{type}" size='{size}' maxlength='{maxlength}' > + {label} + + + + + + + + + + save + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginXmlformDelete.tpl b/gulliver/bin/tasks/templates/pluginXmlformDelete.tpl new file mode 100644 index 000000000..1f352dfee --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginXmlformDelete.tpl @@ -0,0 +1,23 @@ + + + + + Delete {className} + + + + + + {label} + + +<{name} type="hidden" colWidth='{size}' > + + + + + + delete + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginXmlformEdit.tpl b/gulliver/bin/tasks/templates/pluginXmlformEdit.tpl new file mode 100644 index 000000000..21aa7f225 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginXmlformEdit.tpl @@ -0,0 +1,31 @@ + + + + + {className} form + + + + +<{name} type="hidden" colWidth='{size}' > + {label} + + + + + +<{name} type="{type}" size='{size}' maxlength='{maxlength}' > + {label} + + + + + + + + + + save + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginXmlformList.tpl b/gulliver/bin/tasks/templates/pluginXmlformList.tpl new file mode 100644 index 000000000..d307b891c --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginXmlformList.tpl @@ -0,0 +1,23 @@ + + + + +<{name} type="text" colWidth='{size}' > + {label} + + + + + + Edit + + + + Delete + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/pluginXmlformOptions.tpl b/gulliver/bin/tasks/templates/pluginXmlformOptions.tpl new file mode 100644 index 000000000..afcf639e8 --- /dev/null +++ b/gulliver/bin/tasks/templates/pluginXmlformOptions.tpl @@ -0,0 +1,8 @@ + + + + <{phpClassName}New type="private" defaultValue="../{phpClassName}/{phpClassName}New"/> + + + + \ No newline at end of file diff --git a/gulliver/bin/tasks/templates/propel.ini.tpl b/gulliver/bin/tasks/templates/propel.ini.tpl new file mode 100644 index 000000000..286e5b927 --- /dev/null +++ b/gulliver/bin/tasks/templates/propel.ini.tpl @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = {dbName} +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/db_{projectName} + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/{dbName} +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/gulliver/bin/tasks/templates/publish-treeview.php.tpl b/gulliver/bin/tasks/templates/publish-treeview.php.tpl new file mode 100644 index 000000000..bcaf5c61d --- /dev/null +++ b/gulliver/bin/tasks/templates/publish-treeview.php.tpl @@ -0,0 +1,38 @@ + + +' . G::capitalize($_SESSION['G_MESSAGE_TYPE']) . ' : ' . $_SESSION['G_MESSAGE']); + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); + } + if( is_array( $G_PUBLISH->Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + print ""; + print ""; + print ""; + print ""; + } +?> +
"; + $G_PUBLISH->RenderContent( 0, false ); + print ""; + print ""; + for( $npcount = 1; $npcount < $nplim; $npcount++ ) { + print( "\n\n\n" ); + } + print "
\n" ); + $G_PUBLISH->RenderContent( $npcount, false ); + print( "
"; + print "
diff --git a/gulliver/bin/tasks/templates/publish.php.tpl b/gulliver/bin/tasks/templates/publish.php.tpl new file mode 100644 index 000000000..21d64dc0e --- /dev/null +++ b/gulliver/bin/tasks/templates/publish.php.tpl @@ -0,0 +1,35 @@ + + +'); + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); + } + if( is_array( $G_PUBLISH->Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + for( $npcount = 0; $npcount < $nplim; $npcount++ ) + { + print( "\n\n\n" ); + } + } +?> +
' . G::capitalize($_SESSION['G_MESSAGE_TYPE']) . ' : ' . $_SESSION['G_MESSAGE'] . '
\n" ); + if (isset($RBAC->userObj)) + $G_PUBLISH->RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + else + $G_PUBLISH->RenderContent( $npcount ); + print( "
diff --git a/gulliver/bin/tasks/templates/rolesList.php.tpl b/gulliver/bin/tasks/templates/rolesList.php.tpl new file mode 100644 index 000000000..d9dd1bba3 --- /dev/null +++ b/gulliver/bin/tasks/templates/rolesList.php.tpl @@ -0,0 +1,27 @@ +listAllRoles( '{rbacProjectName}'); + $G_MAIN_MENU = '{projectName}'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'ROLES'; + + /* + $rs = RolesPeer::doSelectRs ( $oCriteria ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $rs->next(); + $row = $rs->getRow(); + } + */ + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'users/rolesList', $oCriteria); + + G::RenderPage('publish'); diff --git a/gulliver/bin/tasks/templates/rolesList.xml.tpl b/gulliver/bin/tasks/templates/rolesList.xml.tpl new file mode 100644 index 000000000..00b9777c6 --- /dev/null +++ b/gulliver/bin/tasks/templates/rolesList.xml.tpl @@ -0,0 +1,30 @@ + + + + # + + + + System Name + + + + System Name + + + + Create Date + + + + Update Date + + + + Status + + + + diff --git a/gulliver/bin/tasks/templates/schema.xml.tpl b/gulliver/bin/tasks/templates/schema.xml.tpl new file mode 100644 index 000000000..f3670ae36 --- /dev/null +++ b/gulliver/bin/tasks/templates/schema.xml.tpl @@ -0,0 +1,526 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
diff --git a/gulliver/bin/tasks/templates/showMessage.xml.tpl b/gulliver/bin/tasks/templates/showMessage.xml.tpl new file mode 100644 index 000000000..1fba1e9f3 --- /dev/null +++ b/gulliver/bin/tasks/templates/showMessage.xml.tpl @@ -0,0 +1,9 @@ + + + + <en>Error</en> + + + + + diff --git a/gulliver/bin/tasks/templates/skinPluginClass.tpl b/gulliver/bin/tasks/templates/skinPluginClass.tpl new file mode 100644 index 000000000..43b4ab941 --- /dev/null +++ b/gulliver/bin/tasks/templates/skinPluginClass.tpl @@ -0,0 +1,20 @@ +sFriendlyName = "Plugin for skin {className} "; + $this->sDescription = "{description}"; + $this->sPluginFolder = "{className}"; + $this->sSetupPage = "{className}"; + $this->iVersion = {version}; + $this->iPMVersion = "{PMversion}"; + $this->aWorkspaces = null; + return $res; + } + + function install() { + //Nothing + } + + function setup() { + //Nothing + } + + function xcopy ( $pathSource, $pathTarget ) { + G::mk_dir ($pathTarget); + if ($handle = opendir( $pathSource )) { + while ( false !== ($file = readdir($handle))) { + if ( substr($file,0,1) != '.' && !is_dir ($file) ) { + $content = file_get_contents ( $pathSource . $file ); + $filename = $pathTarget . $file ; + file_put_contents ( $filename, $content ); + } + } + closedir($handle); + } + } + + function enable() { + $this->xcopy ( + PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'data' . PATH_SEP, + PATH_SKINS ); + + $this->xcopy ( + PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'data' . PATH_SEP . 'public_html'. PATH_SEP , + PATH_HTML . 'skins' . PATH_SEP . $this->sPluginFolder. PATH_SEP ); + + $this->xcopy ( + PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'data' . PATH_SEP . 'public_html'. PATH_SEP. 'images'. PATH_SEP , + PATH_HTML . 'skins' . PATH_SEP . $this->sPluginFolder. PATH_SEP . 'images'. PATH_SEP ); + } + + function disable() { + //delete from engine + $this->delete(PATH_SKINS . $this->sPluginFolder . '.php', true); + $this->delete(PATH_SKINS . $this->sPluginFolder . '.html', true); + $this->delete(PATH_SKINS . $this->sPluginFolder . '.cnf', true); + + //delete directory + G::rm_dir(PATH_HTML . 'skins' . PATH_SEP . $this->sPluginFolder ); + } + +} + +$oPluginRegistry =& PMPluginRegistry::getSingleton(); +$oPluginRegistry->registerPlugin('{className}', __FILE__); diff --git a/gulliver/bin/tasks/templates/style.css.tpl b/gulliver/bin/tasks/templates/style.css.tpl new file mode 100644 index 000000000..715fc5dfa --- /dev/null +++ b/gulliver/bin/tasks/templates/style.css.tpl @@ -0,0 +1,1116 @@ +* { behavior: url(/skin/green/iepngfix.htc) } +body +{ + margin :0px; + background-color:#ECECEC; + color :#808080; + font :normal 8pt sans-serif,Tahoma,MiscFixed; +} + +.Footer +{ + font :normal 8pt sans-serif,Tahoma,MiscFixed; + color :#000; + height :150px; + text-align :center; +} +.Footer .image +{ + /*background-image: url(/skins/green/images/bf.jpg); + background-repeat: repeat-x; + height:10px;*/ + +} +.Footer .content +{ + color :black; + padding :10px; +} +.Footer .content a +{ + color :#006699; + text-decoration :none; +} +.Footer .content a:hover +{ + color :orange; +} +.logout a +{ + font:bold 8pt Tahoma,sans-serif,MiscFixed; + color:#006699; + text-decoration:none; +} +.logout a:hover +{ + color:orange; +} +.temporalMessage +{ + color :red; + font :normal 8pt Tahoma,sans-serif,MiscFixed; + text-decoration:none; +} +.userGroupTitle +{ + color :black; + font :bold 8pt Tahoma,sans-serif,MiscFixed; + padding-left:10px; +} +.userGroupLink +{ + padding:0px; + padding-left:10px; + padding-bottom:10px; +} +.userGroupLink a +{ + color :#006699; + text-decoration:none; + font :bold 8pt Tahoma,sans-serif,MiscFixed; +} +.userGroupLink a:hover +{ + color :orange; +} +span.treePlusLink +{ + background-color:#E68B2C; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.treePlusLink:hover +{ + background-color:#EFC395; +} +span.XtreeMinus +{ + background-color:#006699; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.XtreeMinus:hover +{ + background-color:#EFC395; +} + +/* leimnud.app.menuRight CSS begin */ + +/* Processmaker CSS begin */ +.pm_separator___processmaker +{ + +} +.pm_separatorOn___processmaker +{ + +} +.pm_separatorOff___processmaker,.pm_separatorOn___processmaker +{ + height: 7px; + cursor:pointer; + text-align:center; + overflow:hidden; +} +.pm_separatorDOff___processmaker,.pm_separatorDOn___processmaker, .pm_separatorOver___processmaker, .pm_separatorOut___processmaker +{ + height:7px; + width:100%; + background-color:#C1D2EE; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + border-width:1px 0pt; + overflow:hidden; +} +.pm_separatorDOff___processmaker +{ + background:url(/js/maborak/core/images/separator.up.gif); + background-repeat:no-repeat; + background-position:50% 2; + +} +.pm_separatorDOn___processmaker +{ + background:url(/js/maborak/core/images/separator.down.gif); + background-repeat:no-repeat; + background-position:50% 50%; +} +.pm_separatorOver___processmaker +{ + background-color:#C1D2EE; +} +.pm_separatorOut___processmaker +{ + background-color:buttonface; +} + +/* Processmaker CSS end */ +/* processmap Theme.Task begin */ +/*theme firefox begin*/ +.processmap_task___firefox +{ + position : absolute; + height : 30; + width : 150; + background-color: #006699; + border : 1px solid #006699; + z-index : 10; + overflow : hidden; + cursor : move; +} +.processmap_task_label___firefox +{ + color:white; + text-align:center; + cursor:text; + padding-top:11; +} +.processmap_text___firefox +{ + position : absolute; + cursor : move; + background-color:red; +} +.processmap_title___firefox +{ + +} + /*theme firefox end*/ + + /*theme processmap begin*/ +.processmap_task___processmaker +{ + position : absolute; + height : 40; + height : 38; + width : 171; + width : 164; + z-index : 10; + overflow : hidden; + cursor : move; + /*background : url(/js/processmap/core/images/bg_task.gif); + background : url(/images/fondotask.png);*/ + //background-color:#006699; + //background-color:#6F6F6F; + background : url(/images/borderTask.gif); + background-color:#0576C4; + background-color:#006699; + vertical-align:middle; + display:table-cell; +} +.processmap_task_label___processmaker +{ + color:#FFF; + text-align:center; + /*position:absolute;*/ + margin:10; + vertical-align:middle; + cursor:move; +} +.processmap_text___processmaker +{ + position : absolute; + z-index : 10; + cursor : move; + font : bold 8pt Tahoma,MiscFixed; +} +.processmap_title___processmaker +{ + position :absolute; + cursor :move; + font :bold 13pt Tahoma,MiscFixed; +} + /*theme processmap end*/ +.processmap_toolbarItem___processmaker +{ + margin:0px; + border:1px solid #CEC6B5; + background:#EFEFEF url(/images/dynamicForm/toolbar.buttonbg.gif) repeat-x scroll 0%; +} +.processmap_toolbarItem___processmaker:hover +{ + margin:0px; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + /*border-width:1px 0pt;*/ + border:1px solid #316AC5; + background:#C1D2EE; + background-color: #C1D2EE; + + +} +/* processmap Theme.Task end */ + +/* processmap Theme.Panels begin */ +/* processmap Theme.Panels end */ + + +/* Theme leimnud.module.grid BEGIN */ + +/* Theme leimnud.module.grid END */ + + +/* Menues */ + + +TD.mainMenu { + background-image: url(/skins/green/images/bm.jpg); + background-repeat: repeat-x; + height: 25px; + left: 46px; + top: 72px; +} + +A.mainMenu { + font-family: Tahoma; + font-size: 11px; + color: #FFFFFF; + font-weight: bold; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} +A.mainMenu:hover { + color: #D3D3D3; + font-weight: bold; + text-decoration: none; +} + +TD.SelectedMenu{ + background-image: url(/skins/green/images/bsms.jpg); + background-repeat: repeat-x; + top: 72px; + height: 26px; +} +A.SelectedMenu { + vertical-align: middle; + font-family: Tahoma; + font-size: 11px; + font-weight: bold; + color: #000; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} + +.SelectedMenu:hover { + vertical-align: middle; + font-family: Tahoma; + font-size: 11px; + font-weight: bold; + color: #005791; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} + + +TD.subMenu { + background-image: url('/skins/green/images/bsm.jpg'); + background-repeat: repeat-x; + height: 25px; +} + +A.subMenu { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +A.subMenu:hover { + font-family: Tahoma; + font-size: 10px; + color: #092148; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +TD.selectedSubMenu { + background-image: url('/images/silverBackgroundSubMenu.jpg'); + background-repeat: repeat-x; + height: 26px; + left: 46px; + top: 98px; +} + +A.selectedSubMenu { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +A.selectedSubMenu:hover { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + + +/* Menues END */ + +/* Box Top Model BEGIN */ +.boxTop, .boxTopBlue +{ + height:9px; + padding-left:8px; + padding-right:8px; + position:relative; + overflow:hidden; +} +.boxTop div, .boxTopBlue div +{ + background-color:#FFF; +} +.boxTop div.a, .boxTop div.c, .boxTopBlue div.a, .boxTopBlue div.c +{ + position:absolute; + width:9px; + height:9px; +} +.boxTop div.a, .boxTopBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftl.png); + background-color:transparent; +} +.boxTop div.c, .boxTopBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftr.png); + background-color:transparent; +} +.boxTop div.b, .boxTopBlue div.b +{ + width:100%; + height:9px; + border-top:1px solid #DADADA; + background-color:#FFF; +} +/* Box Top Model END */ + +/* Box Top Model Blue BEGIN */ +.boxTopBlue div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); + background-color:transparent; +} +.boxTopBlue div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); + background-color:transparent; +} +.boxTopBlue div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} + +/* Box Top Model Blue END */ + +/* Box Bottom Model BEGIN */ +.boxBottom, .boxBottomBlue +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxBottom div.a, .boxBottom div.c, .boxBottomBlue div.a, .boxBottomBlue div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxBottom div.a, .boxBottomBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/fbl.png); + background-color:transparent; +} +.boxBottom div.c, .boxBottomBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/fbr.png); + background-color:transparent; +} +.boxBottom div.b, .boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.png) repeat-x; +} +/* Box Bottom Model END */ +/* Box Bottom Model Blue BEGIN */ +.boxBottomBlue div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); + background-color:transparent; +} +.boxBottomBlue div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); + background-color:transparent; +} +.boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.blue.png) repeat-x; +} +.boxContentBlue +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + padding-right:5px; + padding-left:5px; + background-color:#D0DEF0; +} +a.linkInBlue +{ + font:normal 8pt Tahoma,MiscFixed; + color:#006699; + text-decoration:none; +} + +a.linkInBlue:hover +{ + color:orange; +} +/* Box Bottom Model Blue END */ + +/* BoxPanel Bottom Model BEGIN */ +.boxTopPanel +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxTopPanel div.a, .boxTopPanel div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxTopPanel div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftlL.png); + background-color:transparent; +} +.boxTopPanel div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftrL.png); + background-color:transparent; +} +.boxTopPanel div.b +{ + width:100%; + height:16px; + background: transparent url(/skins/green/images/ftc.png) repeat-x; +} + +/* BoxPanel Bottom Model END */ + + + +/* XmlForm BEGIN */ + /* form BEGIN */ +form{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form table{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form.formDefault select +{ + font:normal 11px sans-serif,MiscFixed; + color:#000; +} +form.formDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; + line-height:180%; +} +form.formDefault td +{ + padding:2px; +} +form.formDefault .content +{ + background-color:#FFF; + border-left:1px solid #dadada; + border-right:1px solid #dadada; +} +form.formDefault input.FormField +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; +} +form.formDefault input.FormFieldInvalid +{ + border: 1px solid red; +} +form.formDefault input.FormFieldValid +{ + border: 1px solid green; +} +form.formDefault .FormLabel +{ + color:#808080; + text-align:right; + padding-right:10px; +} +form.formDefault .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; +} +form.formDefault textarea.FormTextArea +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + overflow:auto; +} +form.formDefault .FormTitle +{ + color:#000; + padding-left:5px; + font-weight:bold; + background-color:#E0EFE6; +} +form.formDefault .FormSubTitle +{ + background-color:#D1DEDF; + color:black; +} +form.formDefault .FormButton +{ + text-align:center; +} + +form.formDefault a +{ + text-decoration:none; + color:#006699; +} +form.formDefault a:hover +{ + color:orange; +} +form.formDefault td.withoutLabel, form.formDefault td.withoutLabel table td +{ + padding:0px; + height:8px; +} + + /* form END */ + /* formSearch BEGIN */ +form.formSearch input, input +{ + font-size:8pt; +} +form.formSearch a +{ + color:#006699; + text-decoration:none; +} +form.formSearch a:hover +{ + color:orange; +} +form.formSearch +{ + padding-top:5px; + padding-bottom:5px; +/* width:100%;*/ + padding-left:10px; + padding-right:10px; +/* padding-left:10%; + padding-right:10%;*/ +} +form.formSearch .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; + padding:10px; +} +form.formSearch input.FormField +{ + border: 1px solid #99BBE8; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + width:200px; +} +form.formSearch .FormLabel +{ + color:#000; + text-align:center; + padding-right:10px; + width:40%; +} +form.formSearch .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; + width:60%; +} + +form.formSearch .Record +{ + width:80%; +} + /* formSearch END */ + + + /* pagedTable BEGIN */ +.pagedTableDefault +{ + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + padding-left:5px; + padding-right:5px; +} +.pagedTableDefault, .pagedTableDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a +{ + color:#2078A8; + text-decoration:none; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a:hover +{ + color:orange; +} +.pagedTableDefault td +{ + padding:0px; +} +.pagedTableDefault .pagedTable td +{ + padding:5px; +} +.pagedTableDefault .pagedTable +{ + border:1px solid #DFDFDF; + border-collapse:collapse; + color:#27373F; +} +.pagedTableDefault .pagedTable .Row1 +{ + background-color:#FFF; +} +.pagedTableDefault .pagedTable .Row2 +{ + background-color:#EEE; +} +.pagedTableDefault .pagedTable .RowPointer +{ + background-color:#E0EAEF; +} +.pagedTableDefault .cellSelected1 +{ +font-weight:bold; +} +.pagedTableDefault .cellSelected2 +{ +font-weight:bold; +} +.pagedTableDefault .pagedTable a +{ + color:#FFF; +} +.pagedTableDefault .pagedTable a:hover +{ + color:orange; +} +.pagedTableDefault .pagedTable .pagedTableHeader +{ + border-bottom:0px solid #DFDFDF; + background-color:#E0E9EF; + background-color:#6F7F75; + color:#5B5B5B; + font-weight:bold; + background-image:url(/images/silverBackgroundTableTitle.jpg); + background-repeat:repeat-x; + height:26px; + padding:0px; + overflow:hidden; +} +.pagedTableDefault .pagedTable .pagedTableHeader a +{ + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; +} +.pagedTableDefault .pagedTable .pagedTableHeader a:hover +{ + color:orange; +} +.pagedTableDefault .pagedTable .RowLink +{ + background-color:#6F7F75; + text-align :center; +} +A.firstPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noFirstPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.previousPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noPreviousPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.nextPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noNextPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.lastPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noLastPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} + + /* pagedTable END */ + /* Grid BEGIN */ +div.pattern .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +div.pattern .FormTitle +{ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} + + +div.grid +{ + font:normal 11px sans-serif,MiscFixed; + padding-left:10px; + padding-right:10px; + margin-top:7px; +} + +div.grid .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} + +div.grid .tableGrid +{ + width:100%; +} +div.grid .tableGrid .vFormTitle +{ +/* color:#006699;*/ +} + /* Grid END */ + /* Tree BEGIN */ + +div.treeBase .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +.treeNode +{ + padding-bottom:10px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:#808080; +} +div.treeBase table td.a +{ + width:16px; + height:10px; +} +div.treeBase table td.b +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; + text-align:left; +} +/* TreeParent BEGIN */ +div.treeParent +{ + position:relative; +} +div.treeParent table +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; +} + +div.treeParent .treeMinus +{ + width:16px; + height:22px; + display:block; + position:relative; + background-image:url(/images/minus.gif); + background-repeat:no-repeat; + overflow:hidden; +} +div.treeParent .treePlus +{ + width:16px; + height:22px; + background-image:url(/images/plus.gif); + background-repeat:no-repeat; + display:block; +} +div.treeParent .treePointer +{ + width:1px; + height:22px; + display:block; +} +div.treeParent td.c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +div.treeParent td.d +{ + background-image:url(/images/ftv2node.gif); + background-repeat:repeat-y; +} +div.treeParent .treeNode +{ + padding:2px; + padding-bottom:1px; + font-weight:bold; +} + + + +div.treeParent .treeNode a, div.treeBase .treeNode a +{ + color:#006699; + font-weight:normal; + text-decoration:none; +} +div.treeParent .treeNode a:hover, div.treeBase .treeNode a:hover +{ + color:orange; +} +div.treeParent .FormField +{ + background-color:#FFF; + padding-bottom:10px; +} +div.treeParent .FormField a +{ + font-size:8pt !important; + color:red; +} +div.treeParent .FormTitle +{ +/* font:bold 8pt sans-serif,Tahoma,MiscFixed; + font:normal 11px sans-serif,MiscFixed;*/ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} +/* TreeParent END */ + +/* TreeChild BEGIN */ +div.treeChild td.b +{ + padding-right:10px; +} +div.treeChild td.a +{ + width:10px; + height:22px; + background:none; +} +div.treeChild .c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +/* TreeChild END */ + + +div.treeChild +{ + padding-left:1px; +} +div.treeParent .content .treeNode a.selected +{ + color:white; + background-color:#006699; +} + +/*div.treeParent div.treeParent .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); +} +div.treeParent div.treeParent .boxTop div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); +} +div.treeParent div.treeParent .boxBottom div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); +} +div.treeParent div.treeParent .boxBottom div.b +{ + background-image:url(/skins/green/images/fbc.blue.png); +} +div.treeParent div.treeParent .boxBottom div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); +}*/ + + + + +div.treeParent table +{ + +} +div.treeParent .subcontent +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} + /* Tree END */ +/* XmlForm END */ diff --git a/gulliver/bin/tasks/templates/sysGeneric.php.tpl b/gulliver/bin/tasks/templates/sysGeneric.php.tpl new file mode 100644 index 000000000..2b96a46c6 --- /dev/null +++ b/gulliver/bin/tasks/templates/sysGeneric.php.tpl @@ -0,0 +1,388 @@ +addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/maborak.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/core/common.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/core/webResource.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'dveditor/core/dveditor.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/tree/tree.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'json/core/json.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'form/core/form.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'form/core/pagedTable.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'grid/core/grid.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.panel.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.validator.js', true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.app.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.rpc.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.fx.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.drag.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.drop.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.dom.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.abbr.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.dashboard.js', true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'widgets/jscalendar/calendar.js' ); + +//************ defining Virtual URLs ****************/ + $virtualURITable = array(); + $virtualURITable['/plugin/(*)'] = 'plugin'; + $virtualURITable['/(sys*)/(*.js)'] = 'jsMethod'; + $virtualURITable['/js/(*)'] = PATH_GULLIVER_HOME . 'js/'; + $virtualURITable['/jscore/(*)'] = PATH_CORE . 'js/'; + //$virtualURITable['/fckeditor/(*)'] = PATH_THIRDPARTY . 'fckeditor/'; + $virtualURITable['/htmlarea/(*)'] = PATH_THIRDPARTY . 'htmlarea/'; + $virtualURITable['/sys[a-zA-Z][a-zA-Z0-9]{0,}()/'] = 'sysNamed'; + $virtualURITable['/(sys*)'] = FALSE; + $virtualURITable['/errors/(*)'] = PATH_GULLIVER_HOME . 'methods/errors/'; + $virtualURITable['/controls/(*)'] = PATH_GULLIVER_HOME . 'methods/controls/'; + $virtualURITable['/html2ps_pdf/(*)'] = PATH_THIRDPARTY . 'html2ps_pdf/'; + $virtualURITable['/Krumo/(*)'] = PATH_THIRDPARTY . 'krumo/'; + $virtualURITable['/codepress/(*)'] = PATH_THIRDPARTY . 'codepress/'; + + if(defined('PATH_C')) + { + $virtualURITable['/jsform/(*.js)'] = PATH_C . 'xmlform/'; + } + /*To sysUnnamed*/ + $virtualURITable['/[a-zA-Z][a-zA-Z0-9]{0,}()'] = 'sysUnnamed'; + $virtualURITable['/(*)'] = PATH_HTML; + +//************** verify if we need to redirect or stream the file ************** + if ( G::virtualURI($_SERVER['REQUEST_URI'], $virtualURITable , $realPath )) { + // review if the file requested belongs to public_html plugin + if ( substr ( $realPath, 0,6) == 'plugin' ) { + $paths = explode ( PATH_SEP, $realPath ); + $paths[0] = substr ( $paths[0],6); + if ( count($paths) == 2 ) { + $pathsQuery = explode('?', $paths[1]); + $pluginFilename = PATH_PLUGINS . $paths[0] . PATH_SEP . 'public_html'. PATH_SEP . $pathsQuery[0]; + if ( file_exists ( $pluginFilename ) ) { + G::streamFile ( $pluginFilename ); + } + } + die; + } + + switch ( $realPath ) { + case 'sysUnnamed' : + require_once('sysUnnamed.php'); die; + break; + case 'sysNamed' : + header('location : ' . $_SERVER['REQUEST_URI'] . 'en/green/login/login' ); + die; + break; + case 'jsMethod' : + G::parseURI ( getenv( "REQUEST_URI" ) ); + $filename = PATH_METHODS . SYS_COLLECTION . '/' . SYS_TARGET . '.js'; + G::streamFile ( $filename ); + die; + break; + default : + $realPath = explode('?', $realPath); + G::streamFile ( $realPath[0] ); + die; + } + } + +//************** verify if the URI is encrypted or not ************** + G::parseURI ( getenv( "REQUEST_URI" ) ); + + define( 'SYS_URI' , '/sys' . SYS_TEMP . '/' . SYS_LANG . '/' . SYS_SKIN . '/' ); + + require_once ( PATH_THIRDPARTY . 'krumo' . PATH_SEP . 'class.krumo.php' ); + +//***************** Call Gulliver Classes ************************** + + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + + G::LoadSystem('error'); + G::LoadSystem('dbconnection'); + G::LoadSystem('dbsession'); + G::LoadSystem('dbrecordset'); + G::LoadSystem('dbtable'); + G::LoadSystem('rbac' ); + G::LoadSystem('publisher'); + G::LoadSystem('templatePower'); + G::LoadSystem('headPublisher'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlformExtension'); + G::LoadSystem('form'); + G::LoadSystem('menu'); + G::LoadSystem("xmlMenu"); + G::LoadSystem('dvEditor'); + G::LoadSystem('table'); + G::LoadSystem('pagedTable'); + G::LoadSystem('tree'); + + $oHeadPublisher =& headPublisher::getSingleton(); + + //***************** database and workspace definition ************************ + //if SYS_TEMP exists, the URL has a workspace, now we need to verify if exists their db.php file + if ( defined('SYS_TEMP') && SYS_TEMP != '') + { + //this is the default, the workspace db.php file is in /shared/{projectName}/sites/SYS_SYS + if ( file_exists( PATH_DB . SYS_TEMP . '/db.php' ) ) { + require_once( PATH_DB . SYS_TEMP . '/db.php' ); + define ( 'SYS_SYS' , SYS_TEMP ); + } + else { + $sysParts = explode('-',SYS_TEMP); + //try to find the definition in the module-file + if ( count($sysParts) == 3) { + $fileName = 'dbmodule_'.$sysParts[1].'.php'; + $DB_INDEX = 0; + $DB_MODULE = array(); + + if ( !file_exists( PATH_DB . $fileName)) { + header ("location: errors/error701.php"); + die; + } + require_once ( PATH_DB . $fileName ); + $moduleName = $DB_MODULE[$DB_INDEX]['name']; + $modulePath = $DB_MODULE[$DB_INDEX]['path']; + $moduleType = $DB_MODULE[$DB_INDEX]['type']; + if ( !file_exists( $modulePath )) { + header ("location: /errors/error704.php"); die; + } + if ( $moduleType == 'single-file' ) { + $workspaceDB = $modulePath. 'db_'. $sysParts[2] . '.php'; + } + else { + $workspaceDB = $modulePath. $sysParts[2] . '/db.php'; + } + if ( !file_exists( $workspaceDB )) { + header ("location: /errors/error704.php"); die; + } + require_once( $workspaceDB ) ; + define ( 'SYS_SYS', $sysParts[2]); + } + else { + $aMessage['MESSAGE'] = G::LoadTranslation ('ID_NOT_WORKSPACE'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; + } + } + } + else { //when we are in global pages, outside any valid workspace + + + if ((SYS_TARGET==='sysLoginVerify') || (SYS_TARGET==='sysLogin') || (SYS_TARGET==='newSite')) { + $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . "/" . SYS_TARGET.'.php'; + require_once($phpFile); + die(); + } + else { + require_once( PATH_METHODS . "login/sysLogin.php" ) ; + die(); + } + } + +//***************** PM Paths DATA ************************** + define( 'PATH_DATA_SITE', PATH_DATA . 'sites/' . SYS_SYS . '/'); + define( 'PATH_DOCUMENT', PATH_DATA_SITE . 'files/' ); + define( 'PATH_DYNAFORM', PATH_DATA_SITE . 'xmlForms/' ); + define( 'PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE.'usersFiles'.PATH_SEP); + define( 'PATH_IMAGES_ENVIRONMENT_USERS', PATH_DATA_SITE.'usersPhotographies'.PATH_SEP); + + +//***************** Plugins ************************** + G::LoadClass('plugin'); +// //here we are loading all plugins registered +// //the singleton has a list of enabled plugins + +// $sSerializedFile = PATH_DATA_SITE . 'plugin.singleton'; +// $oPluginRegistry =& PMPluginRegistry::getSingleton(); +// if ( file_exists ($sSerializedFile) ) +// $oPluginRegistry->unSerializeInstance( file_get_contents ( $sSerializedFile ) ); +// +// $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + +//***************** create $G_ENVIRONMENTS dependent of SYS_SYS ************************** + + define ( 'G_ENVIRONMENT', G_DEV_ENV ); + $G_ENVIRONMENTS = array ( + G_PRO_ENV => array ( + 'dbfile' => PATH_DB . 'production' . PATH_SEP . 'db.php' , + 'cache' => 1, + 'debug' => 0, + ) , + G_DEV_ENV => array ( + 'dbfile' => PATH_DB . SYS_SYS . PATH_SEP . 'db.php', + 'datasource' => 'workflow', + 'cache' => 0, + 'debug' => 0, + ) , + G_TEST_ENV => array ( + 'dbfile' => PATH_DB . 'test' . PATH_SEP . 'db.php' , + 'cache' => 0, + 'debug' => 0, + ) + ); + + // setup propel definitions and logging + //try { + require_once ( "propel/Propel.php" ); + require_once ( "creole/Creole.php" ); + + if ( $G_ENVIRONMENTS[ G_ENVIRONMENT ]['debug'] ) { + require_once ( "Log.php" ); + + // register debug connection decorator driver + Creole::registerDriver('*', 'creole.contrib.DebugConnection'); + + // itialize Propel with converted config file + Propel::init( PATH_CORE . "config/databases.php" ); + + //log file for workflow database + $logFile = PATH_DATA . 'log' . PATH_SEP . 'workflow.log'; + $logger = Log::singleton('file', $logFile, 'wf ' . SYS_SYS, null, PEAR_LOG_INFO); + Propel::setLogger($logger); + $con = Propel::getConnection('workflow'); + if ($con instanceof DebugConnection) $con->setLogger($logger); + + //log file for rbac database + $logFile = PATH_DATA . 'log' . PATH_SEP . 'rbac.log'; + $logger = Log::singleton('file', $logFile, 'rbac ' . SYS_SYS, null, PEAR_LOG_INFO); + Propel::setLogger($logger); + $con = Propel::getConnection('rbac'); + if ($con instanceof DebugConnection) $con->setLogger($logger); + } + else + Propel::init( PATH_CORE . "config/databases.php" ); + + Creole::registerDriver('dbarray', 'creole.contrib.DBArrayConnection'); + + //***************** Session Initializations **************************/ + ini_alter( 'session.auto_start', '1' ); + ini_alter( 'register_globals', 'Off' ); + session_start(); + ob_start(); + + //********* Log Page Handler ************* + // logPage ( $URL , SYS_CURRENT_PARMS); + + //*********jump to php file in methods directory ************* +// if ( $oPluginRegistry->isRegisteredFolder( SYS_COLLECTION ) ) +// $phpFile = PATH_PLUGINS . SYS_COLLECTION . PATH_SEP . SYS_TARGET.'.php'; +// else + $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . PATH_SEP . SYS_TARGET.'.php'; + + //the index.php file, this new feature will allow automatically redirects to valid php file inside the methods directory + if ( SYS_TARGET == '' ) { + $phpFile = str_replace ( '.php', 'index.php', $phpFile ); + $phpFile = include ( $phpFile ); + } + if ( substr(SYS_COLLECTION , 0,8) === 'gulliver' ) { + $phpFile = PATH_GULLIVER_HOME . 'methods/' . substr( SYS_COLLECTION , 8) . SYS_TARGET.'.php'; + } + else { + if ( ! file_exists( $phpFile ) ) { + $_SESSION['phpFileNotFound'] = $phpFile; + header ("location: /errors/error404.php"); + die; + } + } + +// ***************** enable rbac ************************** + + $RBAC =& RBAC::getSingleton(); + $RBAC->sSystem = '{rbacProjectName}'; + +// ***************** Headers ************************** + if ( ! defined('EXECUTE_BY_CRON') ) { + header("Expires: Tue, 19 Jan 1999 04:30:00 GMT"); + header("Last-Modified: Tue, 19 Jan 1999 04:30:00 GMT"); + header('Cache-Control: no-cache, must-revalidate, post-check=0,pre-check=0 '); + header('P3P: CP="CAO PSA OUR"'); + + if(isset( $_SESSION['USER_LOGGED'] )) { + $RBAC->initRBAC(); + $RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] ); + } + else { + //This sentence is used when you lost the Session + if ( SYS_TARGET != 'authentication' and SYS_TARGET != 'login' + and SYS_TARGET != 'dbInfo' and SYS_TARGET != 'sysLoginVerify' + and SYS_TARGET != 'updateTranslation' and SYS_COLLECTION != 'services' ){ + header ("location: ".SYS_URI."login/login.php"); + die(); + } + } + + require_once( $phpFile ); + if ( defined('SKIP_HEADERS') ) { + header("Expires: " . gmdate("D, d M Y H:i:s", mktime( 0,0,0,date('m'),date('d'),date('Y') + 1) ) . " GMT"); + header('Cache-Control: public'); + header('Pragma: '); + } + ob_end_flush(); + } +/* + } + catch ( Exception $e ) { + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; + } +*/ diff --git a/gulliver/bin/tasks/templates/sysLogin.php.tpl b/gulliver/bin/tasks/templates/sysLogin.php.tpl new file mode 100644 index 000000000..8080f4473 --- /dev/null +++ b/gulliver/bin/tasks/templates/sysLogin.php.tpl @@ -0,0 +1,17 @@ +AddContent('xmlform', 'xmlform', 'login/sysLogin', '', '', 'sysLogin'); +G::RenderPage( "publish" ); +?> diff --git a/gulliver/bin/tasks/templates/sysLogin.xml.tpl b/gulliver/bin/tasks/templates/sysLogin.xml.tpl new file mode 100644 index 000000000..4d85b3958 --- /dev/null +++ b/gulliver/bin/tasks/templates/sysLogin.xml.tpl @@ -0,0 +1,22 @@ + + + + <en>Login</en> + + + + User + + + + Password + + + + Workspace + + + + Login + + diff --git a/gulliver/bin/tasks/templates/unitTest.tpl b/gulliver/bin/tasks/templates/unitTest.tpl new file mode 100644 index 000000000..6d781d0a9 --- /dev/null +++ b/gulliver/bin/tasks/templates/unitTest.tpl @@ -0,0 +1,58 @@ +getMethods() as $reflectmethod ) {literal} { {/literal} + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) {literal} { {/literal} + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , {$cantMethods}, "class $className have " . {$cantMethods} . ' methods.' ); + + {foreach from=$methods key=methodName item=parameters} + //checking method '{$methodName}' + $t->can_ok( $obj, '{$methodName}', '{$methodName}() is callable' ); + + //$result = $obj->{$methodName} ( {$parameters}); + //$t->isa_ok( $result, 'NULL', 'call to method {$methodName} '); + $t->todo( "call to method {$methodName} using {$parameters} "); + + +{/foreach} + + $t->todo ( 'review all pendings methods in this class'); diff --git a/gulliver/bin/tasks/templates/users.menu.php.tpl b/gulliver/bin/tasks/templates/users.menu.php.tpl new file mode 100755 index 000000000..1e0537058 --- /dev/null +++ b/gulliver/bin/tasks/templates/users.menu.php.tpl @@ -0,0 +1,16 @@ +AddIdRawOption('USERS', 'users/usersList'); + $G_TMP_MENU->AddIdRawOption('ROLES', 'users/rolesList'); + $G_TMP_MENU->AddIdRawOption('PERMISSIONS','users/permissionsList'); + + $G_TMP_MENU->Labels = array ( + G::LoadTranslation('ID_USERS_LIST'), + G::LoadTranslation('ID_ROLES'), + G::LoadTranslation('ID_PERMISSIONS') + ); diff --git a/gulliver/bin/tasks/templates/usersList.php.tpl b/gulliver/bin/tasks/templates/usersList.php.tpl new file mode 100755 index 000000000..09e4881f7 --- /dev/null +++ b/gulliver/bin/tasks/templates/usersList.php.tpl @@ -0,0 +1,30 @@ +createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $rows[] = array ( 'uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); + while ( is_array ( $row ) ) { + if ( is_array( $row) ) $rows[] = $row; + $rs->next(); + $row = $rs->getRow(); + } + + $_DBArray['user'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('user'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'users/usersList', $c ); + G::RenderPage('publish'); diff --git a/gulliver/bin/tasks/templates/usersList.xml.tpl b/gulliver/bin/tasks/templates/usersList.xml.tpl new file mode 100755 index 000000000..63e8a2ee9 --- /dev/null +++ b/gulliver/bin/tasks/templates/usersList.xml.tpl @@ -0,0 +1,30 @@ + + + + # + + + + username + + + + First Name + + + + Last Name + + + + Email + + + + Status + + + + diff --git a/gulliver/bin/tasks/templates/welcome.php.tpl b/gulliver/bin/tasks/templates/welcome.php.tpl new file mode 100644 index 000000000..7fdaa51f4 --- /dev/null +++ b/gulliver/bin/tasks/templates/welcome.php.tpl @@ -0,0 +1,55 @@ + 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); +$rows[] = array ( 'uid' => 11, 'name' => 'john', 'age' => 44, 'balance' => 123423 ); +$rows[] = array ( 'uid' => 22, 'name' => 'Amy', 'age' => 33, 'balance' => 23456 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Dan', 'age' => 22, 'balance' => 34567 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Mike', 'age' => 21, 'balance' => 4567 ); +$rows[] = array ( 'uid' => 44, 'name' => 'Paul', 'age' => 22, 'balance' => 567 ); +$rows[] = array ( 'uid' => 55, 'name' => 'Wil', 'age' => 23, 'balance' => 67 ); +$rows[] = array ( 'uid' => 66, 'name' => 'Ernest', 'age' => 24, 'balance' => 7 ); +$rows[] = array ( 'uid' => 77, 'name' => 'Albert', 'age' => 25, 'balance' => 84567 ); +$rows[] = array ( 'uid' => 88, 'name' => 'Sue', 'age' => 26, 'balance' => 94567 ); +$rows[] = array ( 'uid' => 99, 'name' => 'Freddy', 'age' => 22, 'balance' => 04567 ); + +$_DBArray['user'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; +//krumo ( $_DBArray ); + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('user'); + //$c->add ( 'user.age', 122 , Criteria::GREATER_EQUAL ); + //$c->add ( 'user.balance', 3456 , Criteria::GREATER_EQUAL ); + $c->addAscendingOrderByColumn ('name'); +/* + $rs = ArrayBasePeer::doSelectRs ( $c ); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $rs->next(); + $row = $rs->getRow(); + } +*/ + /* Render page */ + $G_MAIN_MENU = '{projectName}'; + $G_ID_MENU_SELECTED = 'WELCOME'; + $G_SUB_MENU = 'welcome'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'login/welcome', $c ); + G::RenderPage( "publish" ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish'); +} diff --git a/gulliver/bin/tasks/templates/welcome.xml.tpl b/gulliver/bin/tasks/templates/welcome.xml.tpl new file mode 100644 index 000000000..6eb088644 --- /dev/null +++ b/gulliver/bin/tasks/templates/welcome.xml.tpl @@ -0,0 +1,21 @@ + + + + # + + + + name + + + + Task + + + + balance + + + diff --git a/gulliver/bin/tasks/templates/xmlform.html.tpl b/gulliver/bin/tasks/templates/xmlform.html.tpl new file mode 100644 index 000000000..0b200370b --- /dev/null +++ b/gulliver/bin/tasks/templates/xmlform.html.tpl @@ -0,0 +1,161 @@ +{if $printTemplate} +{* this is the xmlform template *} +
+
+
+
+ + + + +
+ + {foreach from=$form->fields item=field} + {if ($field->type==='title')} + + + + {elseif ($field->type==='subtitle')} + + + + {elseif ($field->type==='button') || ($field->type==='submit') || ($field->type==='reset')} + + + + {elseif ($field->type==='grid')} + + + + {elseif ($field->type==='checkbox') && ($field->labelOnRight)} + + + + + {elseif ($field->type==='phpvariable')} + {elseif ($field->type==='private')} + {elseif ($field->type==='javascript')} + {elseif ($field->type==='hidden')} + + + + {elseif ($field->type==='')} + {elseif ($field->withoutLabel)} + + + + {elseif (isset($field->withoutValue) && $field->withoutValue)} + + + + {else} + + + + + {/if} + {/foreach} +
{$field->field}
+ {$field->field} + {if (isset($field->showHide) && $field->showHide)} + Hide + {/if} +
{$field->field}
{$field->field}
{$field->field}
{$field->field}
{$field->field}
{$field->label}
{if (isset($field->required)&&$field->required&&$field->mode==='edit')}* {/if}{$field->label}width y=$form->labelWidth}" *}>{$field->field}
+
+ {if $hasRequiredFields}
* {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
{/if} +
+
+
+{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +
+{/if} +{if $printJSFile} +{* TODO: include file='xmlformScript.html' *} +var form_{$form->id}; +var object_{$form->name}; +var i; +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('{$form->id}'),'{$form->id}'); + object_{$form->name} = form_{$form->id}; + var myForm=form_{$form->id}; + if (myForm.aElements===undefined) alert("{$form->name}"); + myForm.ajaxServer=ajaxServer; + + {if isset($form->ajaxSubmit) && ($form->ajaxSubmit)} + {literal} + var sub = new leimnud.module.app.submit({ + form : myForm.element,{/literal} + inProgress: {$form->in_progress}, + callback: {$form->callback} + {literal} + }); + sub.sendObj = false; + {/literal} + {/if} + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if (($field->type==='dropdown') || $field->type==='listbox')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='hidden')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='date')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} +{/if} +{if $printJavaScript} +leimnud.event.add(window,'load',function(){literal}{{/literal}loadForm_{$form->id}('{$form->ajaxServer}');{literal}}{/literal}); +{/if} diff --git a/gulliver/includes/inc.ajax.php b/gulliver/includes/inc.ajax.php new file mode 100644 index 000000000..84a828a0c --- /dev/null +++ b/gulliver/includes/inc.ajax.php @@ -0,0 +1,111 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + define ('AJAX_PAGE', 1); + + function get_ajax_value ( $varName ) { + $_result = NULL; + if(isset($_GET[ $varName ]) || isset($_POST[ $varName ])) { + $_result =(isset($_GET[ $varName ]))?urldecode($_GET[ $varName ]):$_POST[ $varName ]; + } + //linea comentada porque cuando llegaba un valor cero, se convertia en la cadena nula + //y eso provocaba muchos problemas.... + //$_result =(isset($_result) and !empty($_result)) ? $_result : ""; + $_result =(isset($_result) ) ? $_result : NULL; + return $_result; + } + + function urldecode_values($aVars) + { + foreach ($aVars as $sKey1 => $sValue1) + { + if (is_array($sValue1)) + { + foreach ($sValue1 as $sKey2 => $sValue2) + { + if (is_array($sValue2)) + { + foreach ($sValue2 as $sKey3 => $sValue3) + { + $aVars[$sKey1][$sKey2][$sKey3] = urldecode($sValue3); + } + } + else + { + $aVars[$sKey1][$sKey2] = urldecode($sValue2); + } + } + } + else + { + $aVars[$sKey1] = urldecode($sValue1); + } + } + return $aVars; + } + + function ajax_show_xmlform($sFilename, $aFields = array(), $sAction = '') { + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sFilename, '', $aFields, $sAction); + G::RenderPage('publish', 'blank'); + } + + function ajax_show_menu ( $menu ) { + if ( $menu == '' ) return; + global $G_OP_MENU; + $G_OP_MENU = new Menu; + $G_OP_MENU->Load( $menu ); + G::LoadTemplate( 'submenu' ); + } + + function ajax_show_template ( $file ) { + if ( $file == '' ) return; + G::LoadTemplate( $file ); + } + function ajax_show_image ( $file ) { + global $G_IMAGE_FILENAME; + global $G_IMAGE_PARTS; + + if ( $file == '' ) return; + + $G_IMAGE_FILENAME = $file; + //$G_IMAGE_PARTS = $Part['Data']; + + G::LoadTemplate( 'viewProcessMap' ); + } + + function ajax_show_table ( $dbc, $file , $template) { + global $G_CONTENT; + global $G_TABLE; + $G_CONTENT = new Content; + //global $G_TMP_TARGET; + if ( $file == '' || $template == '' ) return; + //$G_TMP_TARGET = $Part['Target']; + $G_TABLE = G::LoadRawTable( $file, $dbc, $Fields ); + G::LoadTemplate( $template ); + } + + function ajax_LoadJavaScript( $phpMethod, $phpFile ) { + print ' LoadPopJavaScript ( "/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/tools/loadJavaScript.html?method=' .$phpMethod . '&file=' . $phpFile . "\");\n"; + } diff --git a/gulliver/js/common/core/common.js b/gulliver/js/common/core/common.js new file mode 100755 index 000000000..5d96c1a85 --- /dev/null +++ b/gulliver/js/common/core/common.js @@ -0,0 +1,1887 @@ +/* PACKAGE : COMMON + */ + function get_xmlhttp() { + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } + if (!xmlhttp && typeof XMLHttpRequest!='undefined') { + xmlhttp = new XMLHttpRequest(); + } + return xmlhttp; + } + /* ajax_function + * Envia una solicitud GET a ajax_server con la variables "function" y las definidas en parameters. + * @author Julio Cesar Laura Avendano + * @version 1.0 + * @package ajax + * @param string ajax_server url de la pagina servidor + * @param string function funci�n solicitada en el lado del servidor + * @param string parameters variables pasadas por url. Ej. variable=valor&otravariable=suvalor + */ + function ajax_function(ajax_server, funcion, parameters, method) + { + var objetus; + objetus = get_xmlhttp(); + var response; + try + { + if (parameters) parameters = '&' + encodeURI(parameters); + if (!method ) method ="POST"; + data = "function=" + funcion + parameters; + questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?'; + var callServer; + callServer = new leimnud.module.rpc.xmlhttp({ + url : ajax_server, + async : false, + method : method, + args : data + }); + callServer.make(); + response = callServer.xmlhttp.responseText; + var scs = callServer.xmlhttp.responseText.extractScript(); + + scs.evalScript(); + delete callServer; + } catch(ss){ + alert("Error: "+ss.message+var_dump(ss)); + } + return response;//objetus.responseText; + } + /* ajax_message + * Envia una solicitud GET a ajax_server con la variables "function" y las definidas en parameters. + * @author Julio Cesar Laura Avendano + * @version 1.0 + * @package ajax + * @param string ajax_server url de la pagina servidor + * @param string function funci�n solicitada en el lado del servidor + * @param string parameters variables pasadas por url. Ej. variable=valor&otravariable=suvalor + */ + function ajax_message(ajax_server, funcion, parameters, method, callback) + { + var objetus; + objetus = get_xmlhttp(); + var response; + try + { + if (parameters) parameters = '&' + encodeURI(parameters); + if (!method ) method ="POST"; + data = "function=" + funcion + parameters; + questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?'; + objetus.open( method, ajax_server + ((method==='GET')? questionMark+data : '') , true ); + objetus.onreadystatechange=function() { + if ( objetus.readyState==4) + { + if( objetus.status==200) + { + if ( callback ) callback(objetus.responseText); + } + } + } + if (method==='POST') objetus.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + objetus.send(((method==='GET')? null : data)); + }catch(ss) + { + alert("error"+ss.message); + } + } + /* ajax_post + * Envia una solicitud GET/POST a ajax_server con los parametros definidos + * o los campos de un formulario + * @author Julio Cesar Laura Avendano + * @version 1.0 + * @package ajax + * @param string ajax_server url de la pagina servidor + * @param string function funci�n solicitada en el lado del servidor + * @param string parameters variables pasadas por url o formulario. + * @example: ajax_post('foo.com', document.form[0], "POST", callback ) + */ + function ajax_post(ajax_server, parameters, method, callback, asynchronous ) + { + var objetus; + objetus = get_xmlhttp(); + var response; + try + { + if (typeof(parameters)==='object') parameters = ajax_getForm(parameters); + if (!method ) method ="POST"; + if (typeof(asynchronous)==='undefined') asynchronous = false; + data = parameters; + questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?'; + if (method==='GET/POST') { + objetus.open( 'POST', ajax_server + ((data.length<1024)?(questionMark+data):''), asynchronous ); + } else { + objetus.open( method, ajax_server + ((method==='GET')? questionMark+data : '') , asynchronous ); + } + objetus.onreadystatechange=function() { + if ( objetus.readyState==4) + { + if( objetus.status==200) + { + if ( callback ) callback(objetus.responseText); + } + } + } + if ((method==='POST')||(method==='GET/POST')) objetus.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); + objetus.send(((method==='GET')? null : data)); + if (!asynchronous) + { + if ( callback ) callback(objetus.responseText); + return objetus.responseText; + } + }catch(ss) + { + alert("Error: "+ var_dump(ss)); + } + } + + /* + * Refactoring....................... + * Fixed by checkboxes binary values + * By Neyek + * Date March 27th, 2009 12:20:00 GMT-4 + */ + + function ajax_getForm( thisform ) { + var formdata=''; + + // Loop through form fields + for (var i=0; i < thisform.length; i++) { + if ( formdata!=='' ) formdata += '&'; + //Build Send String + if(thisform.elements[i].type == "text") { //Handle Textbox's + formdata += thisform.elements[i].name + "=" + encodeURIComponent(thisform.elements[i].value); + } else if(thisform.elements[i].type == "textarea") { //Handle textareas + formdata += thisform.elements[i].name + "=" + encodeURIComponent(thisform.elements[i].value); + } else if(thisform.elements[i].type == "checkbox") { //Handle checkbox's + formdata += thisform.elements[i].name + '=' + ((thisform.elements[i].checked)? '1': '0'); + } else if(thisform.elements[i].type == "radio") { //Handle Radio buttons + if(thisform.elements[i].checked==true){ + formdata += thisform.elements[i].name + "=" + thisform.elements[i].value; + } + } else if(thisform.elements[i].type == "select-multiple") { //Handle list box + for(var j=0; j= '0') && (sCharacter <= '9'))) + { + return false; + } + } + } + else + { + if (sCharacter == '.') + { + if (!bDot) + { + bDot = true; + } + else + { + return false; + } + } + else + { + if (!((sCharacter >= '0') && (sCharacter <= '9') && (sCharacter != '-') || (sCharacter == '+'))) + { + return false; + } + } + } + } + return true; +} + +function roundNumber(iNumber, iDecimals) + { + var iNumber = parseFloat(iNumber || 0); + var iDecimals = parseFloat(iDecimals || 2); + return Math.round(iNumber * Math.pow(10, iDecimals)) / Math.pow(10, iDecimals); +} + +function toMaskNumber(iNumber,dec) +{ + iNumber = fix(iNumber.toString(),dec || 2); + var t=iNumber.split("."); + var arrayResult=iNumber.replace(/\D/g,'').replace(/^0*/,'').split("").reverse(); + var final=""; + var aux=0; + var sep=0; + for(var i=0;i1 && aux>=3 && ((aux%3)==0)) + { + final=arrayResult[i]+","+final; + aux+=1; + sep+=1; + } + else + { + final=arrayResult[i]+final; + if(i>1) + { + aux+=1; + } + } + } + } + return final; +} + +function fix(val, dec) +{ + var a = val.split("."); + var r=""; + if(a.length==1) + { + r=a[0]+"."+creaZero(dec); + } + else + { + if(a[1].length<=dec) + { + r=a[0]+"."+a[1]+creaZero(dec-a[1].length); + } + else + { + r=a[0]+"."+a[1].substr(0,dec); + } + } + return r; +} + +function creaZero(cant) +{ + var a=""; + for(var i=0;i + */ +function getField( fieldName , formId ) +{ + if (formId) + { + var form = document.getElementById(formId); + if (!form) {form=document.getElementsByName(formId); + if (form) { + if (form.length > 0) { + form = form[0]; + } + } + } + if (form.length > 0) { + return form.elements[ 'form[' + fieldName + ']' ]; + } + else { + //return null; + return document.getElementById( 'form[' + fieldName + ']' ); + } + } + else + { + return document.getElementById( 'form[' + fieldName + ']' ); + } +} + +/* + * author + */ +function getElementByName( fieldName ) +{ + var elements = document.getElementsByName( fieldName ); + try{ + var x=0; + if (elements.length === 1) + return elements[0]; + else if (elements.length === 0) + return elements[0]; + else + return elements; + } catch (E) + {} +} + + +var myDialog; +function commonDialog ( type, title , text, buttons, values, callbackFn ) { + myDialog = new leimnud.module.panel(); + myDialog.options = { + size:{w:400,h:200}, + position:{center:true}, + title: title, + control: { close :false, roll :false, drag :true, resize :false }, + fx: { + //shadow :true, + blinkToFront:false, + opacity :true, + drag:false, + modal: true + }, + theme:"processmaker" + }; + + myDialog.make(); + switch (type) { + case 'question': + icon = 'question.gif'; + break + case 'warning': + icon = 'warning.gif'; + break + case 'error': + icon = 'error.gif'; + break + default: + icon = 'information.gif'; + break + } + + var contentStr = ''; + contentStr += "
"; + contentStr += ""; + contentStr += "
"; + contentStr += "" + text + "
"; + if ( buttons.custom && buttons.customText ) + contentStr += "   "; + if ( buttons.cancel ) + contentStr += "   "; + if ( buttons.yes ) + contentStr += "   "; + if ( buttons.no ) + contentStr += "   "; + contentStr += "
"; + + myDialog.addContent( contentStr ); + myDialog.values = values; + myDialog.dialogCallback = function ( dialogResult ) { + myDialog.remove( ); + if ( callbackFn ) + callbackFn ( dialogResult ); + } + +} +function var_dump(obj) +{ + var o,dump; + dump=''; + if (typeof(obj)=='object') { + for(o in obj) if (typeof(obj[o])!=='function') + { + dump+=o+'('+typeof(obj[o])+'):'+obj[o]+"\n"; + } + } + else + dump=obj; + return dump; +} + +/* + * @author David Callizaya + */ +var currentPopupWindow; +function popupWindow ( title , url, width, height, callbackFn , autoSizeWidth, autoSizeHeight,modal,showModalColor) { + modal = (modal===false)?false:true; + showModalColor = (showModalColor===false)?false:true; + var myPanel = new leimnud.module.panel(); + currentPopupWindow = myPanel; + myPanel.options = { + size:{w:width,h:height}, + position:{center:true}, + title: title, + theme: "processmaker", + control: { close :true, roll :false, drag :true, resize :false}, + fx: { + //shadow :true, + blinkToFront:true, + opacity :true, + drag:true, + modal: modal + //opacityModal:{static:'1'} + } + }; + if(showModalColor===true) + { + //Panel.setStyle={modal:{backgroundColor:"#ECF3F6"}}; + } + else + { + myPanel.styles.fx.opacityModal.Static='0'; + } + myPanel.make(); + myPanel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({url:url}); + r.callback=leimnud.closure({Function:function(rpc,myPanel){ + myPanel.addContent(rpc.xmlhttp.responseText); + var myScripts = myPanel.elements.content.getElementsByTagName('SCRIPT'); + for(var rr=0; rr'; + textfield.innerHTML = dataArray[0].firstChild.xml; + } + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + + +function refillDropdown( fldName, ajax_server, values , InitValue) +{ + + var objetus; + objetus = get_xmlhttp(); + objetus.open ("GET", ajax_server + "?" + values, false); + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + var dropdown = document.getElementById( 'form[' + fldName + ']' ); + + while ( dropdown.hasChildNodes() ) + dropdown.removeChild(dropdown.childNodes[0]); + + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { + var xmlDoc = objetus.responseXML; + + if ( xmlDoc ) { + var dropdown = document.getElementById( 'form[' + fldName + ']' ); + var dataArray = xmlDoc.getElementsByTagName('item'); + itemsNumber = dataArray.length; + + if(InitValue == true) itemsNumber = dataArray.length-1; + for (var i=0; i'; + } + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + + + +function iframe_get_xmlhttp() { + try { + xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (E) { + xmlhttp = false; + } + } + if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { + xmlhttp = new XMLHttpRequest(); + } + return xmlhttp; +} + +function iframe_ajax_init(ajax_server, div_container, values, callback) { + var objetus; + objetus = iframe_get_xmlhttp(); + objetus.open ('GET', ajax_server + '?' + values, true); + objetus.onreadystatechange = function() { + if ( objetus.readyState == 1 ) { + document.getElementById(div_container).style.display = ''; + document.getElementById(div_container).innerHTML = '...'; + } + else if (objetus.readyState==4) { + if (objetus.status==200) { + document.getElementById(div_container).innerHTML = objetus.responseText; + if (callback != '') + callback(); + } + else { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function iframe_ajax_init_2(ajax_server, div_container, values, callback) { + var objetus; + objetus = iframe_get_xmlhttp(); + objetus.open ('GET', ajax_server + '?' + values, true); + objetus.onreadystatechange = function() { + if ( objetus.readyState == 1 ) { + div_container.style.display = ''; + div_container.innerHTML = '...'; + } + else if (objetus.readyState==4) { + if (objetus.status==200) { + div_container.innerHTML = objetus.responseText; + if (callback != '') + callback(); + } + else { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function myEmptyCallback() { +} + +function disable (obj) { + obj.disabled = true; + return; +} + +function enable (obj) { + obj.disabled = false; + return; +} + +function disableById (id) { + obj = getField(id); + obj.disabled = true; + return; +} + +function enableById (id) { + obj = getField(id); + obj.disabled = false; + return; +} + +function visible (obj) { + if (obj.style) { + obj.style.visibility = 'visible'; + } + return; +} + +function hidden (obj) { + if (obj.style) { + obj.style.visibility = 'hidden'; + } + return; +} + +function visibleById (id) { + obj = getField(id); + obj.style.visibility = 'visible'; + return; +} + +function hiddenById (id) { + obj = getField(id); + obj.style.visibility = 'hidden'; + return; +} + +function hiddenRowById (id) { + row = 'DIV_'+ id +'.style.visibility = \'hidden\';'; + hiden = 'DIV_'+ id +'.style.display = \'none\';'; + eval(row); + eval(hiden); + return; +} +function visibleRowById (id) { + row = 'DIV_'+ id +'.style.visibility = \'visible\';'; + block = 'DIV_'+ id +'.style.display = \'block\';'; + eval(row); + eval(block); + return; +} + +function setFocus (obj) { + obj.focus(); + return; +} + +function setFocusById (id) { + obj = getField (id); + setFocus(obj); + return; +} + +function submitForm () { + document.webform.submit(); + return; +} + +function changeValue(id, newValue) { + obj = getField(id); + obj.value = newValue; + return ; +} + +function getValue(obj) { + return obj.value; +} + +function getValueById (id) { + obj = getField(id); + return obj.value; +} + +function removeCurrencySign (snumber) { + var aux = ''; + var num = new String (snumber); + var len = num.length; + var i = 0; + for (i=0; !(i>=len); i++) + if (num.charAt(i) != ',' && num.charAt(i) != '$' && num.charAt(i) != ' ') aux = aux + num.charAt(i); + return aux; + } + + function removePercentageSign (snumber) { + var aux = ''; + var num = new String (snumber); + var len = num.length; + var i = 0; + for (i=0; !(i>=len); i++) + if (num.charAt(i) != ',' && num.charAt(i) != '%' && num.charAt(i) != ' ') aux = aux + num.charAt(i); + return aux; + } + + function toReadOnly(obj) { + if (obj) { + obj.readOnly = 'readOnly'; + obj.style.background = '#CCCCCC'; + } + return; + } + + function toReadOnlyById(id) { + obj = getField(id); + if (obj) { + obj.readOnly = 'readOnly'; + obj.style.background = '#CCCCCC'; + } + return ; + } + +function getGridField(Grid, Row, Field) { + obj = document.getElementById('form[' + Grid + ']' + '[' + Row + ']' + '[' + Field + ']'); + return obj; +} + +function getGridValueById(Grid, Row, Field) { + obj = getGridField(Grid, Row, Field); + if (obj) + return obj.value; + else + return ''; +} + +function Number_Rows_Grid(Grid, Field) { + Number_Rows = 1; + if (getGridField(Grid, Number_Rows, Field)) { + Number_Rows = 0; + while (getGridField(Grid, (Number_Rows + 1), Field)) + Number_Rows++; + return Number_Rows; + } + else + return 0; +} + +function attachFunctionEventOnChange(Obj, TheFunction) { + Obj.oncustomize = TheFunction; +} + +function attachFunctionEventOnChangeById(Id, TheFunction) { + Obj = getField(Id); + Obj.oncustomize = TheFunction; +} + +function attachFunctionEventOnKeypress(Obj, TheFunction) { + Obj.attachEvent('onkeypress', TheFunction); +} + +function attachFunctionEventOnKeypressById(Id, TheFunction) { + Obj = getField(Id); + Obj.attachEvent('onkeypress', TheFunction); +} + +function unselectOptions ( field ) { +var radios = document.getElementById('form[' + field + ']'); + if (radios) { + var inputs = radios.getElementsByTagName ('input'); + if (inputs) { + for(var i = 0; i < inputs.length; ++i) { + inputs[i].checked = false; + } + } + } +} + +function validDate(TheField, Required) { + TheYear = getField(TheField + '][YEAR'); + TheMonth = getField(TheField + '][MONTH'); + TheDay = getField(TheField + '][DAY'); + if (!TheYear || !TheMonth || !TheDay) + return false; + if (Required) + if ((TheYear.value == 0) || (TheMonth.value == 0) || (TheDay.value == 0)) + return false; + if (TheMonth.value == 2) + if (TheDay.value > 29) + return false; + if ((TheMonth.value == 4) || (TheMonth.value == 6) || (TheMonth.value == 9) || (TheMonth.value == 11)) + if (TheDay.value > 30) + return false; + return true; +} + +/* @author David S. Callizaya S. + */ +function globalEval(scriptCode) { + if (scriptCode!=='') + if (window.execScript) + window.execScript( scriptCode, 'javascript' ); + else + window.setTimeout( scriptCode, 0 ); +} +function switchImage(oImg,url1,url2){ + if (oImg && (url2!=='')) { + oImg.src=(oImg.src.substr(oImg.src.length-url1.length,url1.length)===url1)? url2: url1; + } +} +function MM_preloadImages() { //v3.0 + var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array(); + var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i + * @return false + */ +function dynaformSetFocus(){ + /* looking for the inputs fields */ + var inputs = document.getElementsByTagName('input'); + if(inputs.length > 0){ + for(i in inputs){ + type = inputs[i].type; + if(type == "text" || type == "radio" || type == "checkbox" || type == "file" || type == "password"){ + try { + inputs[i].focus(); + } catch (e) { + //nothing + } + return false; + } + } + } else { + /* if there is no inputs fields, maybe it has a textarea field */ + var ta = document.getElementsByTagName('textarea'); + if(ta.length > 0){ + inputs[0].focus(); + return false; + } + } + return false; +} + +/** + * ********************************* Misc Functions by Neyek **************************************** + */ + +/** + * get the htmlentities from a string + * + * @Author Erik Amaru Ortiz + * @Param (string) string within the htmlentities to parse + * @Param (string) quote_style it can be (ENT_QUOTES or ENT_NOQUOTES) + * @Return (string) the parsed string with htmlentities at the string passed such as parameter + */ +function htmlentities (string, quote_style) { + + var hash_map = {}, symbol = '', tmp_str = '', entity = ''; + tmp_str = string.toString(); + + if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) { + return false; + } + hash_map["'"] = '''; + for (symbol in hash_map) { + entity = hash_map[symbol]; + tmp_str = tmp_str.split(symbol).join(entity); + } + + return tmp_str; +} + +function get_html_translation_table (table, quote_style) { + //example 1: get_html_translation_table('HTML_SPECIALCHARS'); + //returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'} + + var entities = {}, hash_map = {}, decimal = 0, symbol = ''; + var constMappingTable = {}, constMappingQuoteStyle = {}; + var useTable = {}, useQuoteStyle = {}; + + // Translate arguments + constMappingTable[0] = 'HTML_SPECIALCHARS'; + constMappingTable[1] = 'HTML_ENTITIES'; + constMappingQuoteStyle[0] = 'ENT_NOQUOTES'; + constMappingQuoteStyle[2] = 'ENT_COMPAT'; + constMappingQuoteStyle[3] = 'ENT_QUOTES'; + + useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS'; + useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT'; + + if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') { + throw new Error("Table: "+useTable+' not supported'); + // return false; + } + + entities['38'] = '&'; + if (useTable === 'HTML_ENTITIES') { + entities['160'] = ' '; + entities['161'] = '¡'; + entities['162'] = '¢'; + entities['163'] = '£'; + entities['164'] = '¤'; + entities['165'] = '¥'; + entities['166'] = '¦'; + entities['167'] = '§'; + entities['168'] = '¨'; + entities['169'] = '©'; + entities['170'] = 'ª'; + entities['171'] = '«'; + entities['172'] = '¬'; + entities['173'] = '­'; + entities['174'] = '®'; + entities['175'] = '¯'; + entities['176'] = '°'; + entities['177'] = '±'; + entities['178'] = '²'; + entities['179'] = '³'; + entities['180'] = '´'; + entities['181'] = 'µ'; + entities['182'] = '¶'; + entities['183'] = '·'; + entities['184'] = '¸'; + entities['185'] = '¹'; + entities['186'] = 'º'; + entities['187'] = '»'; + entities['188'] = '¼'; + entities['189'] = '½'; + entities['190'] = '¾'; + entities['191'] = '¿'; + entities['192'] = 'À'; + entities['193'] = 'Á'; + entities['194'] = 'Â'; + entities['195'] = 'Ã'; + entities['196'] = 'Ä'; + entities['197'] = 'Å'; + entities['198'] = 'Æ'; + entities['199'] = 'Ç'; + entities['200'] = 'È'; + entities['201'] = 'É'; + entities['202'] = 'Ê'; + entities['203'] = 'Ë'; + entities['204'] = 'Ì'; + entities['205'] = 'Í'; + entities['206'] = 'Î'; + entities['207'] = 'Ï'; + entities['208'] = 'Ð'; + entities['209'] = 'Ñ'; + entities['210'] = 'Ò'; + entities['211'] = 'Ó'; + entities['212'] = 'Ô'; + entities['213'] = 'Õ'; + entities['214'] = 'Ö'; + entities['215'] = '×'; + entities['216'] = 'Ø'; + entities['217'] = 'Ù'; + entities['218'] = 'Ú'; + entities['219'] = 'Û'; + entities['220'] = 'Ü'; + entities['221'] = 'Ý'; + entities['222'] = 'Þ'; + entities['223'] = 'ß'; + entities['224'] = 'à'; + entities['225'] = 'á'; + entities['226'] = 'â'; + entities['227'] = 'ã'; + entities['228'] = 'ä'; + entities['229'] = 'å'; + entities['230'] = 'æ'; + entities['231'] = 'ç'; + entities['232'] = 'è'; + entities['233'] = 'é'; + entities['234'] = 'ê'; + entities['235'] = 'ë'; + entities['236'] = 'ì'; + entities['237'] = 'í'; + entities['238'] = 'î'; + entities['239'] = 'ï'; + entities['240'] = 'ð'; + entities['241'] = 'ñ'; + entities['242'] = 'ò'; + entities['243'] = 'ó'; + entities['244'] = 'ô'; + entities['245'] = 'õ'; + entities['246'] = 'ö'; + entities['247'] = '÷'; + entities['248'] = 'ø'; + entities['249'] = 'ù'; + entities['250'] = 'ú'; + entities['251'] = 'û'; + entities['252'] = 'ü'; + entities['253'] = 'ý'; + entities['254'] = 'þ'; + entities['255'] = 'ÿ'; + } + + if (useQuoteStyle !== 'ENT_NOQUOTES') { + entities['34'] = '"'; + } + if (useQuoteStyle === 'ENT_QUOTES') { + entities['39'] = '''; + } + entities['60'] = '<'; + entities['62'] = '>'; + + + // ascii decimals to real symbols + for (decimal in entities) { + symbol = String.fromCharCode(decimal); + hash_map[symbol] = entities[decimal]; + } + + return hash_map; +} + +function stripslashes (str) { + return (str+'').replace(/\\(.?)/g, function (s, n1) { + switch (n1) { + case '\\': + return '\\'; + case '0': + return '\0'; + case '': + return ''; + default: + return n1; + } + }); +} + +function addslashes (str) { + return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\u0000/g, "\\0"); +} + +/** + * This function sets netsted properties to dom elements + * + * @Author Erik Amaru Ortiz + * @Param (object) dom element refered by ID + * @Param (array) nested array of properties strings + * @Param (string) value to set + * @Return + * + * Example: + * setNestedProperty(document, ['body','style','backgroundColor'], 'black'); + */ +function setNestedProperty(obj, propertyName, propertyValue){ + var oTarget = obj; + for (var i=0; i + * @Param + * @Return (objeect) {browser:sBrowser, version:sVersion} + */ +function getBrowserClient(){ + var aBrowFull = new Array("opera", "msie", "firefox", "opera", "safari"); + var sInfo = navigator.userAgent.toLowerCase(); + sBrowser = ""; + for (var i = 0; i < aBrowFull.length; i++){ + if ((sBrowser == "") && (sInfo.indexOf(aBrowFull[i]) != -1)){ + sBrowser = aBrowFull[i]; + sVersion = String(parseFloat(sInfo.substr(sInfo.indexOf(aBrowFull[i]) + aBrowFull[i].length + 1))); + return {name:sBrowser, browser:sBrowser, version:sVersion} + } + } + return false; +}; +var _BROWSER = getBrowserClient(); + +/** + * Create and send cookie + * + * @Author Erik Amaru Ortiz + * @Param (string) cookie name + * @Param (string) cookie value + * @Param (int) cookie number of days for expires + * @Return + */ +function createCookie(name, value, days){ + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } else var expires = ""; + document.cookie = name+"="+value+expires+"; path=/"; +} + +/** + * read a cookie + * + * @Author Erik Amaru Ortiz + * @Param cookie name + * @Return (string) cookie content + */ +function readCookie(name){ + var ca = document.cookie.split(';'); + var nameEQ = name + "="; + for(var i=0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; +} + +/** + * delete a cookie + * + * @Author Erik Amaru Ortiz + * @Param cookie name + * @Return + */ +function eraseCookie(name){ + createCookie(name, "", -1); +} + +/** + * highlightRow a html element (setting background) + * + * @Author Erik Amaru Ortiz + * @Param (object) html element + * @Param (string) some color in hexadecimal format + * @Return + */ +function highlightRow(o, color){ + o.style.background = color +} + +/** + * left and right delete the blank characteres (String prototype) + * + * Example: + * var str = String(" some_string_with_spaces "); + * str.trim(); //clean the blank characteres + * + * @Author Erik Amaru Ortiz + * @Param + * @Return + */ +String.prototype.trim = function() { + return this.replace(/^\s+|\s+get/g,""); +} + +function clearCalendar(id){ + document.getElementById(id).value=''; + document.getElementById(id+'[div]').innerHTML = ''; + setTimeout('enableCalendar()', 350); +} + +function lockCalendar(){ + G_CALENDAR_MEM_OFFSET = 'lock'; + + //G_CALENDAR_CURRENT_OBJ.hide(); +} + +function enableCalendar(){ + G_CALENDAR_MEM_OFFSET = 'enable'; +} + +function parseDateFromMask (inputArray, mask){ + /* inputArray is an associative array with properties + year, month, day, hour, minute */ + + /* format mask + * Y -> 2009 + * y -> 09 + * m -> 02 + * d -> 01 + * + * h -> 12 + * i -> 59 + * + * d/m/y -> 01/02/09 + * d/m/Y -> 01/02/2009 + * Y-m-d -> 2009-02-01 + * + * Y-m-d h:m -> 2009-02-01 12:59 + * + */ + + result = mask; + result = result.replace("Y", inputArray.year); + + year = new String(inputArray.year); + result = result.replace("y", year.substr(2,3)); + result = result.replace("m", inputArray.month); + result = result.replace("d", inputArray.day); + result = result.replace("h", inputArray.hour); + result = result.replace("i", inputArray.minute); + + return result; + +} + +Array.prototype.walk = function( funcionaplicada ) { + for(var i=0, parar=false; i + * @Param (string) function name + * @Param (int) time in seconds + * @Return + */ +function Timer(functionName, time) { + setTimeout(functionName, time*1000); +} + +function PMOS_TemporalMessage(timeToHide){ + fade('temporalMessageTD', 'inOut'); + if( typeof(timeToHide) != 'undefined' ) { + Timer( + function(){ + try{ + document.getElementById('temporalMessageTD').style.display = 'none'; + }catch(e){} + }, + timeToHide + ); + } +} + +/** + * fast messagesbox + * + * @Param msg (string) : your message + * @Param type (string): {alert|info|confirm} + * @Param type (string): xcallback, callback function name to execute after at user click on Accept + * @Author + */ + +function msgBox(msg, type, callbackAccept, callbackCancel){ + + //setting default type + type = typeof(type) != 'undefined'? type: 'info'; + + //setting up the callback action + acceptEv = typeof(callbackAccept) != 'undefined'? callbackAccept: false; + cancelEv = typeof(callbackCancel) != 'undefined'? callbackCancel: false; + + switch(type){ + case 'alert': + new leimnud.module.app.alert().make({ + label: msg, + width: 350, + action:function(){ + if( acceptEv ){ + setTimeout(acceptEv, 1); + } + }.extend(this) + }); + break; + case 'info': + new leimnud.module.app.info().make({ + label: msg, + width: 350, + action:function(){ + if( acceptEv ){ + setTimeout(acceptEv, 1); + } + }.extend(this) + }); + break; + case 'confirm': + if( cancelEv ){ + new leimnud.module.app.confirm().make({ + label: msg, + action: function(){ + if( acceptEv ){ + setTimeout(acceptEv, 0); + } + }.extend(this), + cancel: function(){ + setTimeout(cancelEv, 1); + }.extend(this) + }); + } else { + new leimnud.module.app.confirm().make({ + label: msg, + action: function(){ + if( acceptEv ){ + setTimeout(acceptEv, 1); + } + }.extend(this) + }); + } + break; + } + +} + + +function executeEvent(id, ev){ + switch(ev){ + case 'click': + document.getElementById(id).checked = true; + if(document.getElementById(id).onclick){ + try{ + document.getElementById(id).onclick(); + }catch(e){} + } + break; + } +} + +/* + * @By Erik + */ +function getClientWindowSize() { + var wSize = [0, 0]; + if (typeof window.innerWidth != 'undefined'){ + wSize = [ + window.innerWidth, + window.innerHeight + ]; + } else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0){ + wSize = [ + document.documentElement.clientWidth, + document.documentElement.clientHeight + ]; + } else { + wSize = [ + document.getElementsByTagName('body')[0].clientWidth, + document.getElementsByTagName('body')[0].clientHeight + ]; + } + return {width:wSize[0], height:wSize[1]}; +} + +function popUp(URL, width, height, left, top, resizable) { + window.open(URL, '', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=1,resizable='+resizable+',width='+width+',height='+height+',left = '+left+',top = '+top+''); +} + +/** + * Alias for tedious large definition for ajax object - By Erik A.O. + */ +function XHRequest(){ + return new leimnud.module.rpc.xmlhttp; +} + +function removeValue(id){ + if( document.getElementById('form['+id+']') ) + document.getElementById('form['+id+']').value = ''; + else if( document.getElementById(id) ) + document.getElementById(id).value = ''; +} + +function datePicker4(obj, id, mask, startDate, endDate, showTIme){ + + new Calendar({ + inputField: id, + dateFormat: mask, + trigger: id+"[btn]", + bottomBar: true, + min:startDate, + max:endDate, + animation: _BROWSER.name =='msie'? false: true, + showTime: showTIme, + opacity: 1, + onSelect: function() { this.hide(); }} + ); + + if( _BROWSER.name != 'msie' ) + obj.onmouseover = undefined; + +} + +function elementAttributesNS(e, ns) { + if (!this.__namespaceRegexps) + this.__namespaceRegexps = {}; + var regexp = this.__namespaceRegexps[ns]; + if (!regexp) { + this.__namespaceRegexps[ns] = regexp = + ns ? eval("/^" + ns + ":(.+)/") : /^([^:]*)$/; + } + var result = {}; + var atts = e.attributes; + var l = atts.length; + for (var i = 0; i < l; i++) { + var m = atts[i].name.match(regexp); + if (m) + result[m[1]] = atts[i].value; + } + return result; +} diff --git a/gulliver/js/common/core/effects.js b/gulliver/js/common/core/effects.js new file mode 100755 index 000000000..f667a55fc --- /dev/null +++ b/gulliver/js/common/core/effects.js @@ -0,0 +1,244 @@ +/** + * + * Effects + * + * @Author Erik A. Ortiz + * @Date Feb 11th, 2009 + */ + +/** + * fade effect + * + * i.e. fade('myDivId') + * or fade('myDivId', true) -> this for fadeIn and fadeOut in the self time + */ + +var TimeToFade = 1000.0; + +function fade(eid, inOut){ + + inOut = ( typeof(inOut) != 'undefined' )? true: false; + + var element = document.getElementById(eid); + if(element == null) + return; + + if(element.FadeState == null) + { + if(element.style.opacity == null + || element.style.opacity == '' + || element.style.opacity == '1') + { + element.FadeState = 2; + } + else + { + element.FadeState = -2; + } + } + + if(element.FadeState == 1 || element.FadeState == -1) + { + element.FadeState = element.FadeState == 1 ? -1 : 1; + element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft; + } + else + { + element.FadeState = element.FadeState == 2 ? -1 : 1; + element.FadeTimeLeft = TimeToFade; + if(inOut){ + setTimeout("animateFadeInOut(" + new Date().getTime() + ",'" + eid + "')", 33); + } + else + setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33); + } +} + + +function animateFade(lastTick, eid) +{ + var curTick = new Date().getTime(); + var elapsedTicks = curTick - lastTick; + + var element = document.getElementById(eid); + + if(element.FadeTimeLeft <= elapsedTicks) + { + element.style.opacity = element.FadeState == 1 ? '1' : '0'; + element.style.filter = 'alpha(opacity = ' + (element.FadeState == 1 ? '100' : '0') + ')'; + element.FadeState = element.FadeState == 1 ? 2 : -2; + + return; + } + + element.FadeTimeLeft -= elapsedTicks; + var newOpVal = element.FadeTimeLeft/TimeToFade; + if(element.FadeState == 1) + newOpVal = 1 - newOpVal; + + element.style.opacity = newOpVal; + element.style.filter = 'alpha(opacity = ' + (newOpVal*100) + ')'; + + setTimeout("animateFade(" + curTick + ",'" + eid + "')", 33); +} + + +function animateFadeInOut(lastTick, eid) +{ + var curTick = new Date().getTime(); + var elapsedTicks = curTick - lastTick; + + var element = document.getElementById(eid); + + if(element.FadeTimeLeft <= elapsedTicks) + { + element.style.opacity = element.FadeState == 1 ? '1' : '0'; + element.style.filter = 'alpha(opacity = ' + (element.FadeState == 1 ? '100' : '0') + ')'; + element.FadeState = element.FadeState == 1 ? 2 : -2; + + fade(eid); + return; + } + + element.FadeTimeLeft -= elapsedTicks; + var newOpVal = element.FadeTimeLeft/TimeToFade; + if(element.FadeState == 1) + newOpVal = 1 - newOpVal; + + element.style.opacity = newOpVal; + element.style.filter = 'alpha(opacity = ' + (newOpVal*100) + ')'; + + setTimeout("animateFadeInOut(" + curTick + ",'" + eid + "')", 33); +} + +/** + * Effect + * + * To fade backgroud or text + * + * @author Erik A. Ortiz + * + */ + +var Effect = function(element){ + this.max=255; + this.min=100; + this.incrementor=1; + + this.element=(typeof(element) != 'undefined')? element: "text"; //"text" o "background" + //---------------------------------------------- + + this.r=this.max; + this.g=this.max; + this.b=this.max; + + this.target = ''; + this.iTarget = ''; + + switch(this.element){ + case "text": + this.target="color"; + this.iTarget="this.max-"; + break; + case "background": + this.iTarget=""; + this.target="backgroundColor"; + break; + } + + this.setElement = function(e){ + this.element = e; + + switch(this.element){ + case "text": + this.target="color"; + this.iTarget="this.max-"; + break; + case "background": + this.iTarget=""; + this.target="backgroundColor"; + break; + } + } + + this.setMin = function(e){ + this.min = e; + } + + this.setMax = function(e){ + this.max = e; + } + + this.fadeIn = function (obj){ + variation = -1; + increment=variation*this.incrementor; + eval('obj.style.'+this.target+'="RGB("+('+this.iTarget+'this.r)+","+('+this.iTarget+'this.g)+","+('+this.iTarget+'this.b)+")"'); + this.r+=increment; + this.b+=increment; + this.g+=increment; + eso=obj; + elincrement=variation; + if(this.r>this.min && this.rthis.min && this.rthis.min && this.rGSt9PjITd&Hn!S{rvN3f}8*hGR4{G{rmWYny~^WSCX*EMrDWK@A)1- zX8<#10USv3_U-@x0000000000000I5ARvw;5C9iZlq`9+a4gSsZQpDVT-tKQF92gD zIt6jaq;lEPIUbOQu?ZL~Dz4<^Qiv43kqC24ZaPF02&JL}I1-|b>0;5y0dhy+JdL~e zXBQI-8HE%W6dD*7Y=AKcE=MIs4wW&LXH+A4CNGwHmJAvc6f1CUnE`1Q8%LO_nVE49 zqoWiViKH4D6K=jGr)LN!ua+ZizMPWDIVQg>XMC9v8n_rgcOw&tQpCico6G+CTnIaAks924jU(OL{ABqEQ$ypoMdxf`tW%@}7f0V8N9O5hmO{Y-?2B40A=m zku@U10tkyHKoyh}^csTx0}TFu?#V2;!SAJv<-=3lTh^oLehIGtOZV0+xeg zYLvIj0}O=JAqEg&q}YZPrW9XJ%W$HRgK;5bfr&Ff5#SnGuy6qewO~NZ2vBHX0gW+K zKngAd02za60b&5bH;TVgp&pY>Cgn;cQ;A&lxeu)x&li8(1MW#A(21}DJEvJ z!D+U<$pA&ViqXpd83mwo7#1RmlEEe?qyg9oauh&-8t4Fd2CD?HP=IETq4QZ}xN5K| z1?crD%LEB7Kp{RC3=n~o0a7OmKs~x8F9d0xkbpUcXaE=jp%{f}0Gnc}2TX1mJd|{4 zwvYe=Ji3|TQ(PKTL5vuQNiuqg;rFjL|K+Eb1_g*X&R`Jp21&6Hh+)j30>L2%4{f>G ztO(hTGQpN=u8YnBMCfe70KuRU9|bg$%v?Hcy~)Cd0bZf&U9SED1x6W>0ML?XFpMb* z)LX z07?;gny>-?ACpr?9iNc#W!ZuC@)8XktZrF4Y6=-^4ULj8(42e57$gy!Ort}@&nU?B zuZ}AR9oPkVt#HJ<6+ra@bBKoukaU2_0)_K;9JGrCvi!VuQcy;2=uM2&42-7KDh9}j zLlyyBp#tC=H(eoF02mmwb}^wD6u>6uSOC=UAQASFCnsYnLP~DJw!T$hTGN^dtg4YT z+0f*MIkbz(a6*-uB<(OZWPlQ7fZpOyeC@feu=gO21ivD@bFSI!^MFaQWmZC#gnI zvXYfnTxB9RDa&;vMQ)pr6}HAm%S7&?R16qnE!VTkY7jylhWI3@(o-{8?t(A(8D=E4 z6uzICZyXOm(toTt9!6{kC1WIGa8kpg&R{45(F + * Depend of common.js + */ +function WebResource(uri,parameters,method) +{ + var request; + request = get_xmlhttp(); + var response; + try + { + if (!method ) method ="POST"; + if (parameters != '') { + parameters += '&rand=' + Math.random(); + } + else { + parameters = 'rand=' + Math.random(); + } + data = parameters; + request.open( method, uri + ((method==='GET')?('?'+data): '') , false); + if (method==='POST') request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + request.send(((method==='GET')? null : data)); + var type=request.getResponseHeader('Content-Type'); + var reType=/\w+\/\w+/; + var maType=reType.exec(type); + type=maType?maType[0]:'';//type.split(String.fromCharCode(9)).join("").trim(); + }catch(ss) + { + alert("error"+ss.message); + } + switch(type) + { + case "text/json": + try + { + eval('response='+request.responseText+';'); + break; + } + catch (err) + { + } + G.alert(''); + return ; + break; + case "text/javascript": + if (window.execScript) + window.execScript( request.responseText ,'javascript'); + else + window.setTimeout( request.responseText, 0 ); + break; + case "text/html": + response=$dce('div'); + response.innerHTML=request.responseText; + break; + } + /*var r; + for(r in response) + { + eval('this.'+r+'=response[r];'); + }*/ + return response; +} +function __wrCall(uri,func,parameters) +{ + var param=[]; + for(var a=0;a=0; i=cadena.length-1) + { + if(cadena.charAt(i)==" ") + cadena=cadena.substr(0,i); + else + break; + } + return cadena.toString(); + } +} \ No newline at end of file diff --git a/gulliver/js/common/tree/tree.js b/gulliver/js/common/tree/tree.js new file mode 100644 index 000000000..6ae5bd077 --- /dev/null +++ b/gulliver/js/common/tree/tree.js @@ -0,0 +1,67 @@ +/* Manages a table of Tree type. + * @author David Callizaya + */ +function G_Tree() { + this.lastSelected = false; + this.lastSelectedClassName = 'treeNode'; + var me = this; + this.changeSign = function( element, newSign ){ + /*element must be the TR of the current node */ + var spans = element.cells[0].childNodes;//getElementsByTagName('SPAN'); + for(var r= 0 ; r=2)) return false; + //Now element is the TR of the current node. + return element.parentNode; + } + } + element = element.parentNode; + } + return false; + }; + this.contract=function( element ){ + if (!(element = this.getRowOf(element))) return; + var row = element.rowIndex; + if ( (row+1)>= element.parentNode.rows.length ) return; + element.parentNode.rows[row+1].style.display = 'none'; + this.changeSign( element , 'plus' ); + }; + +this.expand=function( element ){ + if (!(element = this.getRowOf(element))) return; + var row = element.rowIndex; + if ( (row+1)>= element.parentNode.rows.length ) return; + element.parentNode.rows[row+1].style.display = ''; + this.changeSign( element , 'minus' ); + }; + this.select=function( element ){ + if (!(element = this.getRowOf(element))) return; + if (me.lastSelected) { + if (me.lastSelected.cells[1]) me.lastSelected.cells[1].className=me.lastSelectedClassName; + } + me.lastSelected = element ; + //me.lastSelected.cells[1].style.filter='Light'; + //me.lastSelected.cells[1].filters['Light'].addAmbient(155,155,155,255); + me.lastSelectedClassName=me.lastSelected.cells[1].className; + me.lastSelected.cells[1].className="treeNodeSelected"; + }; + this.refresh=function( div , server ) { + div.innerHTML = ajax_function( server ,'','' ); + }; +}; +var tree = new G_Tree(); diff --git a/gulliver/js/dveditor/core/dveditor.js b/gulliver/js/dveditor/core/dveditor.js new file mode 100644 index 000000000..20a2770ab --- /dev/null +++ b/gulliver/js/dveditor/core/dveditor.js @@ -0,0 +1,129 @@ +function DVEditor(where,body,oHiddenInput,height,mode) +{ + var me=this; + var hiddenInput=oHiddenInput; + var iframe=$dce("iframe"); + //NOTE: className no funciona en FIREFOX + iframe.style.width="100%"; + iframe.style.height=height; + iframe.style.margin="0px"; + iframe.style.padding="0px"; + iframe.style.border="none"; + where.appendChild(iframe); + var head=document.childNodes[0].childNodes[0]; + var header=''; + if (iframe.contentWindow) + { + var doc=iframe.contentWindow.document; + } + else + { + var doc=iframe.contentDocument; + } + var _header=$dce("head");// head.cloneNode(true); + for(var i=0;i'+header+''+body+''); + doc.close(); + doc.designMode="on"; + if(mode=="edit"){ + doc.contentEditable=true; + }else{ + doc.contentEditable=false; + } + this.doc=doc; + me.insertHTML=function (html) + { + var cmd = 'inserthtml'; + var bool = false; + var value = html; + try + { + doc.execCommand(cmd,bool,value); + } catch (e) { + } + return false; + }; + me.command=function() + { + var cmd = this.getAttribute('name'); + var bool = false; + var value = this.getAttribute('cmdValue') || null; + if (value == 'promptUser') + value = prompt( + (typeof(G_STRINGS[this.getAttribute('promptText')])!=='undefined')? + G_STRINGS[this.getAttribute('promptText')]: + this.getAttribute('promptText') + ); + try + { + doc.execCommand(cmd,bool,value); + } catch (e) { + } + return false; + } + me.loadToolBar=function(uri) + { + var tb=WebResource(uri); + iframe.parentNode.insertBefore(tb,iframe); + me.setToolBar(tb); + } + me.setToolBar=function(toolbar) + { + var buttons=toolbar.getElementsByTagName('area'); + for(var b=0;b + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/gulliver/js/dveditor/core/toolbars/complete3lines.png b/gulliver/js/dveditor/core/toolbars/complete3lines.png new file mode 100644 index 0000000000000000000000000000000000000000..b71594ad53c55c487a43a0b587adc54c3b286cc0 GIT binary patch literal 8141 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 + + + + + + + + + + + + + \ No newline at end of file diff --git a/gulliver/js/dveditor/core/toolbars/smallToolBar.png b/gulliver/js/dveditor/core/toolbars/smallToolBar.png new file mode 100644 index 0000000000000000000000000000000000000000..8beb16eb336e76c2dd0f481ed7a24adcb8aed9b2 GIT binary patch literal 4676 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/dveditor/core/toolbars/toolbar2lines.html b/gulliver/js/dveditor/core/toolbars/toolbar2lines.html new file mode 100644 index 000000000..4172a9f69 --- /dev/null +++ b/gulliver/js/dveditor/core/toolbars/toolbar2lines.html @@ -0,0 +1,39 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/gulliver/js/dveditor/core/toolbars/toolbar2lines.png b/gulliver/js/dveditor/core/toolbars/toolbar2lines.png new file mode 100644 index 0000000000000000000000000000000000000000..28df773c8ed7b1fce1a958d723310f0f7bdf522e GIT binary patch literal 7896 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/ext/draw2d.js b/gulliver/js/ext/draw2d.js new file mode 100755 index 000000000..172b9d97b --- /dev/null +++ b/gulliver/js/ext/draw2d.js @@ -0,0 +1,6367 @@ + +/**This notice must be untouched at all times. +This is the COMPRESSED version of the Draw2D Library +WebSite: http://www.draw2d.org +Copyright: 2006 Andreas Herz. All rights reserved. +Created: 5.11.2006 by Andreas Herz (Web: http://www.freegroup.de ) +LICENSE: LGPL +**/ +Event=function(){ +this.type=null; +this.target=null; +this.relatedTarget=null; +this.cancelable=false; +this.timeStamp=null; +this.returnValue=true; +}; +Event.prototype.initEvent=function(sType,_3a0c){ +this.type=sType; +this.cancelable=_3a0c; +this.timeStamp=(new Date()).getTime(); +}; +Event.prototype.preventDefault=function(){ +if(this.cancelable){ +this.returnValue=false; +} +}; +Event.fireDOMEvent=function(_3a0d,_3a0e){ +if(document.createEvent){ +var evt=document.createEvent("Events"); +evt.initEvent(_3a0d,true,true); +_3a0e.dispatchEvent(evt); +}else{ +if(document.createEventObject){ +var evt=document.createEventObject(); +_3a0e.fireEvent("on"+_3a0d,evt); +} +} +}; +EventTarget=function(){ +this.eventhandlers=new Object(); +}; +EventTarget.prototype.addEventListener=function(sType,_3a11){ +if(typeof this.eventhandlers[sType]=="undefined"){ +this.eventhandlers[sType]=new Array; +} +this.eventhandlers[sType][this.eventhandlers[sType].length]=_3a11; +}; +EventTarget.prototype.dispatchEvent=function(_3a12){ +_3a12.target=this; +if(typeof this.eventhandlers[_3a12.type]!="undefined"){ +for(var i=0;i=0){ +return this.removeElementAt(index); +} +return null; +}; +ArrayList.prototype.insertElementAt=function(obj,index){ +if(this.size==this.capacity){ +this.resize(); +} +for(var i=this.getSize();i>index;i--){ +this.data[i]=this.data[i-1]; +} +this.data[index]=obj; +this.size++; +}; +ArrayList.prototype.removeElementAt=function(index){ +var _3dd3=this.data[index]; +for(var i=index;i<(this.getSize()-1);i++){ +this.data[i]=this.data[i+1]; +} +this.data[this.getSize()-1]=null; +this.size--; +return _3dd3; +}; +ArrayList.prototype.removeAllElements=function(){ +this.size=0; +for(var i=0;i=0&&_3de2>_3ddf){ +this.data[j+1]=this.data[j]; +j--; +if(j>=0){ +_3de1=this.data[j]; +_3de2=_3de1[f]; +} +} +this.data[j+1]=_3de0; +} +}; +ArrayList.prototype.clone=function(){ +var _3de3=new ArrayList(this.size); +for(var i=0;i"+_3dbe+""); +} +function openwindow(url,width,_3dc2){ +var left=(screen.width-width)/2; +var top=(screen.height-_3dc2)/2; +property="left="+left+", top="+top+", toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=1,alwaysRaised,width="+width+",height="+_3dc2; +return window.open(url,"_blank",property); +} +function dumpObject(obj){ +trace("----------------------------------------------------------------------------"); +trace("- Object dump"); +trace("----------------------------------------------------------------------------"); +for(var i in obj){ +try{ +if(typeof obj[i]!="function"){ +trace(i+" --> "+obj[i]); +} +} +catch(e){ +} +} +for(var i in obj){ +try{ +if(typeof obj[i]=="function"){ +trace(i+" --> "+obj[i]); +} +} +catch(e){ +} +} +trace("----------------------------------------------------------------------------"); +} +Drag=function(){ +}; +Drag.current=null; +Drag.currentTarget=null; +Drag.dragging=false; +Drag.isDragging=function(){ +return this.dragging; +}; +Drag.setCurrent=function(_326a){ +this.current=_326a; +this.dragging=true; +}; +Drag.getCurrent=function(){ +return this.current; +}; +Drag.clearCurrent=function(){ +this.current=null; +this.dragging=false; +}; +Draggable=function(_326b,_326c){ +EventTarget.call(this); +this.construct(_326b,_326c); +this.diffX=0; +this.diffY=0; +this.targets=new ArrayList(); +}; +Draggable.prototype=new EventTarget; +Draggable.prototype.construct=function(_326d,_326e){ +this.element=_326d; +this.constraints=_326e; +var oThis=this; +var _3270=function(){ +var _3271=new DragDropEvent(); +_3271.initDragDropEvent("dblclick",true); +oThis.dispatchEvent(_3271); +var _3272=arguments[0]||window.event; +_3272.cancelBubble=true; +_3272.returnValue=false; +}; +var _3273=function(){ +var _3274=arguments[0]||window.event; +var _3275=new DragDropEvent(); +var _3276=oThis.node.workflow.getAbsoluteX(); +var _3277=oThis.node.workflow.getAbsoluteY(); +var _3278=oThis.node.workflow.getScrollLeft(); +var _3279=oThis.node.workflow.getScrollTop(); +_3275.x=_3274.clientX-oThis.element.offsetLeft+_3278-_3276; +_3275.y=_3274.clientY-oThis.element.offsetTop+_3279-_3277; +if(_3274.button==2){ +_3275.initDragDropEvent("contextmenu",true); +oThis.dispatchEvent(_3275); +}else{ +_3275.initDragDropEvent("dragstart",true); +if(oThis.dispatchEvent(_3275)){ +oThis.diffX=_3274.clientX-oThis.element.offsetLeft; +oThis.diffY=_3274.clientY-oThis.element.offsetTop; +Drag.setCurrent(oThis); +if(oThis.isAttached==true){ +oThis.detachEventHandlers(); +} +oThis.attachEventHandlers(); +} +} +_3274.cancelBubble=true; +_3274.returnValue=false; +}; +var _327a=function(){ +if(Drag.getCurrent()==null){ +var _327b=arguments[0]||window.event; +if(Drag.currentHover!=null&&oThis!=Drag.currentHover){ +var _327c=new DragDropEvent(); +_327c.initDragDropEvent("mouseleave",false,oThis); +Drag.currentHover.dispatchEvent(_327c); +} +if(oThis!=null&&oThis!=Drag.currentHover){ +var _327c=new DragDropEvent(); +_327c.initDragDropEvent("mouseenter",false,oThis); +oThis.dispatchEvent(_327c); +} +Drag.currentHover=oThis; +}else{ +} +}; +if(this.element.addEventListener){ +this.element.addEventListener("mousemove",_327a,false); +this.element.addEventListener("mousedown",_3273,false); +this.element.addEventListener("dblclick",_3270,false); +}else{ +if(this.element.attachEvent){ +this.element.attachEvent("onmousemove",_327a); +this.element.attachEvent("onmousedown",_3273); +this.element.attachEvent("ondblclick",_3270); +}else{ +throw new Error("Drag not supported in this browser."); +} +} +}; +Draggable.prototype.attachEventHandlers=function(){ +var oThis=this; +oThis.isAttached=true; +this.tempMouseMove=function(){ +var _327e=arguments[0]||window.event; +var _327f=new Point(_327e.clientX-oThis.diffX,_327e.clientY-oThis.diffY); +if(oThis.node.getCanSnapToHelper()){ +_327f=oThis.node.getWorkflow().snapToHelper(oThis.node,_327f); +} +oThis.element.style.left=_327f.x+"px"; +oThis.element.style.top=_327f.y+"px"; +var _3280=oThis.node.workflow.getScrollLeft(); +var _3281=oThis.node.workflow.getScrollTop(); +var _3282=oThis.node.workflow.getAbsoluteX(); +var _3283=oThis.node.workflow.getAbsoluteY(); +var _3284=oThis.getDropTarget(_327e.clientX+_3280-_3282,_327e.clientY+_3281-_3283); +var _3285=oThis.getCompartment(_327e.clientX+_3280-_3282,_327e.clientY+_3281-_3283); +if(Drag.currentTarget!=null&&_3284!=Drag.currentTarget){ +var _3286=new DragDropEvent(); +_3286.initDragDropEvent("dragleave",false,oThis); +Drag.currentTarget.dispatchEvent(_3286); +} +if(_3284!=null&&_3284!=Drag.currentTarget){ +var _3286=new DragDropEvent(); +_3286.initDragDropEvent("dragenter",false,oThis); +_3284.dispatchEvent(_3286); +} +Drag.currentTarget=_3284; +if(Drag.currentCompartment!=null&&_3285!=Drag.currentCompartment){ +var _3286=new DragDropEvent(); +_3286.initDragDropEvent("figureleave",false,oThis); +Drag.currentCompartment.dispatchEvent(_3286); +} +if(_3285!=null&&_3285.node!=oThis.node&&_3285!=Drag.currentCompartment){ +var _3286=new DragDropEvent(); +_3286.initDragDropEvent("figureenter",false,oThis); +_3285.dispatchEvent(_3286); +} +Drag.currentCompartment=_3285; +var _3287=new DragDropEvent(); +_3287.initDragDropEvent("drag",false); +oThis.dispatchEvent(_3287); +}; +oThis.tempMouseUp=function(){ +oThis.detachEventHandlers(); +var _3288=arguments[0]||window.event; +var _3289=new DragDropEvent(); +_3289.initDragDropEvent("dragend",false); +oThis.dispatchEvent(_3289); +var _328a=oThis.node.workflow.getScrollLeft(); +var _328b=oThis.node.workflow.getScrollTop(); +var _328c=oThis.node.workflow.getAbsoluteX(); +var _328d=oThis.node.workflow.getAbsoluteY(); +var _328e=oThis.getDropTarget(_3288.clientX+_328a-_328c,_3288.clientY+_328b-_328d); +var _328f=oThis.getCompartment(_3288.clientX+_328a-_328c,_3288.clientY+_328b-_328d); +if(_328e!=null){ +var _3290=new DragDropEvent(); +_3290.initDragDropEvent("drop",false,oThis); +_328e.dispatchEvent(_3290); +} +if(_328f!=null&&_328f.node!=oThis.node){ +var _3290=new DragDropEvent(); +_3290.initDragDropEvent("figuredrop",false,oThis); +_328f.dispatchEvent(_3290); +} +if(Drag.currentTarget!=null){ +var _3290=new DragDropEvent(); +_3290.initDragDropEvent("dragleave",false,oThis); +Drag.currentTarget.dispatchEvent(_3290); +Drag.currentTarget=null; +} +Drag.currentCompartment=null; +Drag.clearCurrent(); +}; +if(document.body.addEventListener){ +document.body.addEventListener("mousemove",this.tempMouseMove,false); +document.body.addEventListener("mouseup",this.tempMouseUp,false); +}else{ +if(document.body.attachEvent){ +document.body.attachEvent("onmousemove",this.tempMouseMove); +document.body.attachEvent("onmouseup",this.tempMouseUp); +}else{ +throw new Error("Drag doesn't support this browser."); +} +} +}; +Draggable.prototype.detachEventHandlers=function(){ +this.isAttached=false; +if(document.body.removeEventListener){ +document.body.removeEventListener("mousemove",this.tempMouseMove,false); +document.body.removeEventListener("mouseup",this.tempMouseUp,false); +}else{ +if(document.body.detachEvent){ +document.body.detachEvent("onmousemove",this.tempMouseMove); +document.body.detachEvent("onmouseup",this.tempMouseUp); +}else{ +throw new Error("Drag doesn't support this browser."); +} +} +}; +Draggable.prototype.getDropTarget=function(x,y){ +for(var i=0;i255){ +red=255; +} +} +if(green<0){ +green=0; +}else{ +if(green>255){ +green=255; +} +} +if(blue<0){ +blue=0; +}else{ +if(blue>255){ +blue=255; +} +} +return new Color(red,green,blue); +}; +Color.prototype.lighter=function(_3f0f){ +var red=parseInt(Math.round(this.getRed()*(1+_3f0f))); +var green=parseInt(Math.round(this.getGreen()*(1+_3f0f))); +var blue=parseInt(Math.round(this.getBlue()*(1+_3f0f))); +if(red<0){ +red=0; +}else{ +if(red>255){ +red=255; +} +} +if(green<0){ +green=0; +}else{ +if(green>255){ +green=255; +} +} +if(blue<0){ +blue=0; +}else{ +if(blue>255){ +blue=255; +} +} +return new Color(red,green,blue); +}; +Point=function(x,y){ +this.x=x; +this.y=y; +}; +Point.prototype.type="Point"; +Point.prototype.getX=function(){ +return this.x; +}; +Point.prototype.getY=function(){ +return this.y; +}; +Point.prototype.getPosition=function(p){ +var dx=p.x-this.x; +var dy=p.y-this.y; +if(Math.abs(dx)>Math.abs(dy)){ +if(dx<0){ +return PositionConstants.WEST; +} +return PositionConstants.EAST; +} +if(dy<0){ +return PositionConstants.NORTH; +} +return PositionConstants.SOUTH; +}; +Point.prototype.equals=function(o){ +return this.x==o.x&&this.y==o.y; +}; +Point.prototype.getDistance=function(other){ +return Math.sqrt((this.x-other.x)*(this.x-other.x)+(this.y-other.y)*(this.y-other.y)); +}; +Point.prototype.getTranslated=function(other){ +return new Point(this.x+other.x,this.y+other.y); +}; +Dimension=function(x,y,w,h){ +Point.call(this,x,y); +this.w=w; +this.h=h; +}; +Dimension.prototype=new Point; +Dimension.prototype.type="Dimension"; +Dimension.prototype.translate=function(dx,dy){ +this.x+=dx; +this.y+=dy; +return this; +}; +Dimension.prototype.resize=function(dw,dh){ +this.w+=dw; +this.h+=dh; +return this; +}; +Dimension.prototype.setBounds=function(rect){ +this.x=rect.x; +this.y=rect.y; +this.w=rect.w; +this.h=rect.h; +return this; +}; +Dimension.prototype.isEmpty=function(){ +return this.w<=0||this.h<=0; +}; +Dimension.prototype.getWidth=function(){ +return this.w; +}; +Dimension.prototype.getHeight=function(){ +return this.h; +}; +Dimension.prototype.getRight=function(){ +return this.x+this.w; +}; +Dimension.prototype.getBottom=function(){ +return this.y+this.h; +}; +Dimension.prototype.getTopLeft=function(){ +return new Point(this.x,this.y); +}; +Dimension.prototype.getCenter=function(){ +return new Point(this.x+this.w/2,this.y+this.h/2); +}; +Dimension.prototype.getBottomRight=function(){ +return new Point(this.x+this.w,this.y+this.h); +}; +Dimension.prototype.equals=function(o){ +return this.x==o.x&&this.y==o.y&&this.w==o.w&&this.h==o.h; +}; +SnapToHelper=function(_3f1b){ +this.workflow=_3f1b; +}; +SnapToHelper.NORTH=1; +SnapToHelper.SOUTH=4; +SnapToHelper.WEST=8; +SnapToHelper.EAST=16; +SnapToHelper.NORTH_EAST=SnapToHelper.NORTH|SnapToHelper.EAST; +SnapToHelper.NORTH_WEST=SnapToHelper.NORTH|SnapToHelper.WEST; +SnapToHelper.SOUTH_EAST=SnapToHelper.SOUTH|SnapToHelper.EAST; +SnapToHelper.SOUTH_WEST=SnapToHelper.SOUTH|SnapToHelper.WEST; +SnapToHelper.NORTH_SOUTH=SnapToHelper.NORTH|SnapToHelper.SOUTH; +SnapToHelper.EAST_WEST=SnapToHelper.EAST|SnapToHelper.WEST; +SnapToHelper.NSEW=SnapToHelper.NORTH_SOUTH|SnapToHelper.EAST_WEST; +SnapToHelper.prototype.snapPoint=function(_3f1c,_3f1d,_3f1e){ +return _3f1d; +}; +SnapToHelper.prototype.snapRectangle=function(_3f1f,_3f20){ +return _3f1f; +}; +SnapToHelper.prototype.onSetDocumentDirty=function(){ +}; +SnapToGrid=function(_39d9){ +SnapToHelper.call(this,_39d9); +}; +SnapToGrid.prototype=new SnapToHelper; +SnapToGrid.prototype.snapPoint=function(_39da,_39db,_39dc){ +_39dc.x=this.workflow.gridWidthX*Math.floor(((_39db.x+this.workflow.gridWidthX/2)/this.workflow.gridWidthX)); +_39dc.y=this.workflow.gridWidthY*Math.floor(((_39db.y+this.workflow.gridWidthY/2)/this.workflow.gridWidthY)); +return 0; +}; +SnapToGrid.prototype.snapRectangle=function(_39dd,_39de){ +_39de.x=_39dd.x; +_39de.y=_39dd.y; +_39de.w=_39dd.w; +_39de.h=_39dd.h; +return 0; +}; +SnapToGeometryEntry=function(type,_39cd){ +this.type=type; +this.location=_39cd; +}; +SnapToGeometryEntry.prototype.getLocation=function(){ +return this.location; +}; +SnapToGeometryEntry.prototype.getType=function(){ +return this.type; +}; +SnapToGeometry=function(_40db){ +SnapToHelper.call(this,_40db); +}; +SnapToGeometry.prototype=new SnapToHelper; +SnapToGeometry.THRESHOLD=5; +SnapToGeometry.prototype.snapPoint=function(_40dc,_40dd,_40de){ +if(this.rows==null||this.cols==null){ +this.populateRowsAndCols(); +} +if((_40dc&SnapToHelper.EAST)!=0){ +var _40df=this.getCorrectionFor(this.cols,_40dd.getX()-1,1); +if(_40df!=SnapToGeometry.THRESHOLD){ +_40dc&=~SnapToHelper.EAST; +_40de.x+=_40df; +} +} +if((_40dc&SnapToHelper.WEST)!=0){ +var _40e0=this.getCorrectionFor(this.cols,_40dd.getX(),-1); +if(_40e0!=SnapToGeometry.THRESHOLD){ +_40dc&=~SnapToHelper.WEST; +_40de.x+=_40e0; +} +} +if((_40dc&SnapToHelper.SOUTH)!=0){ +var _40e1=this.getCorrectionFor(this.rows,_40dd.getY()-1,1); +if(_40e1!=SnapToGeometry.THRESHOLD){ +_40dc&=~SnapToHelper.SOUTH; +_40de.y+=_40e1; +} +} +if((_40dc&SnapToHelper.NORTH)!=0){ +var _40e2=this.getCorrectionFor(this.rows,_40dd.getY(),-1); +if(_40e2!=SnapToGeometry.THRESHOLD){ +_40dc&=~SnapToHelper.NORTH; +_40de.y+=_40e2; +} +} +return _40dc; +}; +SnapToGeometry.prototype.snapRectangle=function(_40e3,_40e4){ +var _40e5=_40e3.getTopLeft(); +var _40e6=_40e3.getBottomRight(); +var _40e7=this.snapPoint(SnapToHelper.NORTH_WEST,_40e3.getTopLeft(),_40e5); +_40e4.x=_40e5.x; +_40e4.y=_40e5.y; +var _40e8=this.snapPoint(SnapToHelper.SOUTH_EAST,_40e3.getBottomRight(),_40e6); +if(_40e7&SnapToHelper.WEST){ +_40e4.x=_40e6.x-_40e3.getWidth(); +} +if(_40e7&SnapToHelper.NORTH){ +_40e4.y=_40e6.y-_40e3.getHeight(); +} +return _40e7|_40e8; +}; +SnapToGeometry.prototype.populateRowsAndCols=function(){ +this.rows=new Array(); +this.cols=new Array(); +var _40e9=this.workflow.getDocument().getFigures(); +var index=0; +for(var i=0;i<_40e9.getSize();i++){ +var _40ec=_40e9.get(i); +if(_40ec!=this.workflow.getCurrentSelection()){ +var _40ed=_40ec.getBounds(); +this.cols[index*3]=new SnapToGeometryEntry(-1,_40ed.getX()); +this.rows[index*3]=new SnapToGeometryEntry(-1,_40ed.getY()); +this.cols[index*3+1]=new SnapToGeometryEntry(0,_40ed.x+(_40ed.getWidth()-1)/2); +this.rows[index*3+1]=new SnapToGeometryEntry(0,_40ed.y+(_40ed.getHeight()-1)/2); +this.cols[index*3+2]=new SnapToGeometryEntry(1,_40ed.getRight()-1); +this.rows[index*3+2]=new SnapToGeometryEntry(1,_40ed.getBottom()-1); +index++; +} +} +}; +SnapToGeometry.prototype.getCorrectionFor=function(_40ee,value,side){ +var _40f1=SnapToGeometry.THRESHOLD; +var _40f2=SnapToGeometry.THRESHOLD; +for(var i=0;i<_40ee.length;i++){ +var entry=_40ee[i]; +var _40f5; +if(entry.type==-1&&side!=0){ +_40f5=Math.abs(value-entry.location); +if(_40f5<_40f1){ +_40f1=_40f5; +_40f2=entry.location-value; +} +}else{ +if(entry.type==0&&side==0){ +_40f5=Math.abs(value-entry.location); +if(_40f5<_40f1){ +_40f1=_40f5; +_40f2=entry.location-value; +} +}else{ +if(entry.type==1&&side!=0){ +_40f5=Math.abs(value-entry.location); +if(_40f5<_40f1){ +_40f1=_40f5; +_40f2=entry.location-value; +} +} +} +} +} +return _40f2; +}; +SnapToGeometry.prototype.onSetDocumentDirty=function(){ +this.rows=null; +this.cols=null; +}; +Border=function(){ +this.color=null; +}; +Border.prototype.type="Border"; +Border.prototype.dispose=function(){ +this.color=null; +}; +Border.prototype.getHTMLStyle=function(){ +return ""; +}; +Border.prototype.setColor=function(c){ +this.color=c; +}; +Border.prototype.getColor=function(){ +return this.color; +}; +Border.prototype.refresh=function(){ +}; +LineBorder=function(width){ +Border.call(this); +this.width=1; +if(width){ +this.width=width; +} +this.figure=null; +}; +LineBorder.prototype=new Border; +LineBorder.prototype.type="LineBorder"; +LineBorder.prototype.dispose=function(){ +Border.prototype.dispose.call(this); +this.figure=null; +}; +LineBorder.prototype.setLineWidth=function(w){ +this.width=w; +if(this.figure!=null){ +this.figure.html.style.border=this.getHTMLStyle(); +} +}; +LineBorder.prototype.getHTMLStyle=function(){ +if(this.getColor()!=null){ +return this.width+"px solid "+this.getColor().getHTMLStyle(); +} +return this.width+"px solid black"; +}; +LineBorder.prototype.refresh=function(){ +this.setLineWidth(this.width); +}; +Figure=function(){ +this.construct(); +}; +Figure.prototype.type="Figure"; +Figure.ZOrderBaseIndex=100; +Figure.setZOrderBaseIndex=function(index){ +Figure.ZOrderBaseIndex=index; +}; +Figure.prototype.construct=function(){ +this.lastDragStartTime=0; +this.x=0; +this.y=0; +this.border=null; +this.setDimension(10,10); +this.id=this.generateUId(); +this.html=this.createHTMLElement(); +this.canvas=null; +this.workflow=null; +this.draggable=null; +this.parent=null; +this.isMoving=false; +this.canSnapToHelper=true; +this.snapToGridAnchor=new Point(0,0); +this.timer=-1; +this.setDeleteable(true); +this.setCanDrag(true); +this.setResizeable(true); +this.setSelectable(true); +this.properties=new Object(); +this.moveListener=new ArrayList(); +}; +Figure.prototype.dispose=function(){ +this.canvas=null; +this.workflow=null; +this.moveListener=null; +if(this.draggable!=null){ +this.draggable.removeEventListener("mouseenter",this.tmpMouseEnter); +this.draggable.removeEventListener("mouseleave",this.tmpMouseLeave); +this.draggable.removeEventListener("dragend",this.tmpDragend); +this.draggable.removeEventListener("dragstart",this.tmpDragstart); +this.draggable.removeEventListener("drag",this.tmpDrag); +this.draggable.removeEventListener("dblclick",this.tmpDoubleClick); +this.draggable.node=null; +} +this.draggable=null; +if(this.border!=null){ +this.border.dispose(); +} +this.border=null; +if(this.parent!=null){ +this.parent.removeChild(this); +} +}; +Figure.prototype.getProperties=function(){ +return this.properties; +}; +Figure.prototype.getProperty=function(key){ +return this.properties[key]; +}; +Figure.prototype.setProperty=function(key,value){ +this.properties[key]=value; +this.setDocumentDirty(); +}; +Figure.prototype.getId=function(){ +return this.id; +}; +Figure.prototype.setCanvas=function(_3deb){ +this.canvas=_3deb; +}; +Figure.prototype.getWorkflow=function(){ +return this.workflow; +}; +Figure.prototype.setWorkflow=function(_3dec){ +if(this.draggable==null){ +this.html.tabIndex="0"; +var oThis=this; +this.keyDown=function(event){ +event.cancelBubble=true; +event.returnValue=true; +oThis.onKeyDown(event.keyCode,event.ctrlKey); +}; +if(this.html.addEventListener){ +this.html.addEventListener("keydown",this.keyDown,false); +}else{ +if(this.html.attachEvent){ +this.html.attachEvent("onkeydown",this.keyDown); +} +} +this.draggable=new Draggable(this.html,Draggable.DRAG_X|Draggable.DRAG_Y); +this.draggable.node=this; +this.tmpContextMenu=function(_3def){ +oThis.onContextMenu(oThis.x+_3def.x,_3def.y+oThis.y); +}; +this.tmpMouseEnter=function(_3df0){ +oThis.onMouseEnter(); +}; +this.tmpMouseLeave=function(_3df1){ +oThis.onMouseLeave(); +}; +this.tmpDragend=function(_3df2){ +oThis.onDragend(); +}; +this.tmpDragstart=function(_3df3){ +var w=oThis.workflow; +w.showMenu(null); +if(oThis.workflow.toolPalette&&oThis.workflow.toolPalette.activeTool){ +_3df3.returnValue=false; +oThis.workflow.onMouseDown(oThis.x+_3df3.x,_3df3.y+oThis.y); +oThis.workflow.onMouseUp(oThis.x+_3df3.x,_3df3.y+oThis.y); +return; +} +_3df3.returnValue=oThis.onDragstart(_3df3.x,_3df3.y); +}; +this.tmpDrag=function(_3df5){ +oThis.onDrag(); +}; +this.tmpDoubleClick=function(_3df6){ +oThis.onDoubleClick(); +}; +this.draggable.addEventListener("contextmenu",this.tmpContextMenu); +this.draggable.addEventListener("mouseenter",this.tmpMouseEnter); +this.draggable.addEventListener("mouseleave",this.tmpMouseLeave); +this.draggable.addEventListener("dragend",this.tmpDragend); +this.draggable.addEventListener("dragstart",this.tmpDragstart); +this.draggable.addEventListener("drag",this.tmpDrag); +this.draggable.addEventListener("dblclick",this.tmpDoubleClick); +} +this.workflow=_3dec; +}; +Figure.prototype.createHTMLElement=function(){ +var item=document.createElement("div"); +item.id=this.id; +item.style.position="absolute"; +item.style.left=this.x+"px"; +item.style.top=this.y+"px"; +item.style.height=this.width+"px"; +item.style.width=this.height+"px"; +item.style.margin="0px"; +item.style.padding="0px"; +item.style.outline="none"; +item.style.zIndex=""+Figure.ZOrderBaseIndex; +return item; +}; +Figure.prototype.setParent=function(_3df8){ +this.parent=_3df8; +}; +Figure.prototype.getParent=function(){ +return this.parent; +}; +Figure.prototype.getZOrder=function(){ +return this.html.style.zIndex; +}; +Figure.prototype.setZOrder=function(index){ +this.html.style.zIndex=index; +}; +Figure.prototype.hasFixedPosition=function(){ +return false; +}; +Figure.prototype.getMinWidth=function(){ +return 5; +}; +Figure.prototype.getMinHeight=function(){ +return 5; +}; +Figure.prototype.getHTMLElement=function(){ +if(this.html==null){ +this.html=this.createHTMLElement(); +} +return this.html; +}; +Figure.prototype.paint=function(){ +}; +Figure.prototype.setBorder=function(_3dfa){ +if(this.border!=null){ +this.border.figure=null; +} +this.border=_3dfa; +this.border.figure=this; +this.border.refresh(); +this.setDocumentDirty(); +}; +Figure.prototype.onContextMenu=function(x,y){ +var menu=this.getContextMenu(); +if(menu!=null){ +this.workflow.showMenu(menu,x,y); +} +}; +Figure.prototype.getContextMenu=function(){ +return null; +}; +Figure.prototype.onDoubleClick=function(){ +}; +Figure.prototype.onMouseEnter=function(){ +}; +Figure.prototype.onMouseLeave=function(){ +}; +Figure.prototype.onDrag=function(){ +this.x=this.draggable.getLeft(); +this.y=this.draggable.getTop(); +if(this.isMoving==false){ +this.isMoving=true; +this.setAlpha(0.5); +} +this.fireMoveEvent(); +}; +Figure.prototype.onDragend=function(){ +if(this.getWorkflow().getEnableSmoothFigureHandling()==true){ +var _3dfe=this; +var _3dff=function(){ +if(_3dfe.alpha<1){ +_3dfe.setAlpha(Math.min(1,_3dfe.alpha+0.05)); +}else{ +window.clearInterval(_3dfe.timer); +_3dfe.timer=-1; +} +}; +if(_3dfe.timer>0){ +window.clearInterval(_3dfe.timer); +} +_3dfe.timer=window.setInterval(_3dff,20); +}else{ +this.setAlpha(1); +} +this.command.setPosition(this.x,this.y); +this.workflow.commandStack.execute(this.command); +this.command=null; +this.isMoving=false; +this.workflow.hideSnapToHelperLines(); +this.fireMoveEvent(); +}; +Figure.prototype.onDragstart=function(x,y){ +if(!this.canDrag){ +return false; +} +this.command=new CommandMove(this,this.x,this.y); +return true; +}; +Figure.prototype.setCanDrag=function(flag){ +this.canDrag=flag; +if(flag){ +this.html.style.cursor="move"; +}else{ +this.html.style.cursor=null; +} +}; +Figure.prototype.setAlpha=function(_3e03){ +if(this.alpha==_3e03){ +return; +} +try{ +this.html.style.MozOpacity=_3e03; +} +catch(exc){ +} +try{ +this.html.style.opacity=_3e03; +} +catch(exc){ +} +try{ +var _3e04=Math.round(_3e03*100); +if(_3e04>=99){ +this.html.style.filter=""; +}else{ +this.html.style.filter="alpha(opacity="+_3e04+")"; +} +} +catch(exc){ +} +this.alpha=_3e03; +}; +Figure.prototype.setDimension=function(w,h){ +this.width=Math.max(this.getMinWidth(),w); +this.height=Math.max(this.getMinHeight(),h); +if(this.html==null){ +return; +} +this.html.style.width=this.width+"px"; +this.html.style.height=this.height+"px"; +this.fireMoveEvent(); +if(this.workflow!=null&&this.workflow.getCurrentSelection()==this){ +this.workflow.showResizeHandles(this); +} +}; +Figure.prototype.setPosition=function(xPos,yPos){ +this.x=xPos; +this.y=yPos; +if(this.html==null){ +return; +} +this.html.style.left=this.x+"px"; +this.html.style.top=this.y+"px"; +this.fireMoveEvent(); +if(this.workflow!=null&&this.workflow.getCurrentSelection()==this){ +this.workflow.showResizeHandles(this); +} +}; +Figure.prototype.isResizeable=function(){ +return this.resizeable; +}; +Figure.prototype.setResizeable=function(flag){ +this.resizeable=flag; +}; +Figure.prototype.isSelectable=function(){ +return this.selectable; +}; +Figure.prototype.setSelectable=function(flag){ +this.selectable=flag; +}; +Figure.prototype.isStrechable=function(){ +return true; +}; +Figure.prototype.isDeleteable=function(){ +return this.deleteable; +}; +Figure.prototype.setDeleteable=function(flag){ +this.deleteable=flag; +}; +Figure.prototype.setCanSnapToHelper=function(flag){ +this.canSnapToHelper=flag; +}; +Figure.prototype.getCanSnapToHelper=function(){ +return this.canSnapToHelper; +}; +Figure.prototype.getSnapToGridAnchor=function(){ +return this.snapToGridAnchor; +}; +Figure.prototype.setSnapToGridAnchor=function(point){ +this.snapToGridAnchor=point; +}; +Figure.prototype.getBounds=function(){ +return new Dimension(this.getX(),this.getY(),this.getWidth(),this.getHeight()); +}; +Figure.prototype.getWidth=function(){ +return this.width; +}; +Figure.prototype.getHeight=function(){ +return this.height; +}; +Figure.prototype.getY=function(){ +return this.y; +}; +Figure.prototype.getX=function(){ +return this.x; +}; +Figure.prototype.getAbsoluteY=function(){ +return this.y; +}; +Figure.prototype.getAbsoluteX=function(){ +return this.x; +}; +Figure.prototype.onKeyDown=function(_3e0e,ctrl){ +if(_3e0e==46&&this.isDeleteable()==true){ +this.workflow.commandStack.execute(new CommandDelete(this)); +} +if(ctrl){ +this.workflow.onKeyDown(_3e0e,ctrl); +} +}; +Figure.prototype.getPosition=function(){ +return new Point(this.x,this.y); +}; +Figure.prototype.isOver=function(iX,iY){ +var x=this.getAbsoluteX(); +var y=this.getAbsoluteY(); +var iX2=x+this.width; +var iY2=y+this.height; +return (iX>=x&&iX<=iX2&&iY>=y&&iY<=iY2); +}; +Figure.prototype.attachMoveListener=function(_3e16){ +if(_3e16==null||this.moveListener==null){ +return; +} +this.moveListener.add(_3e16); +}; +Figure.prototype.detachMoveListener=function(_3e17){ +if(_3e17==null||this.moveListener==null){ +return; +} +this.moveListener.remove(_3e17); +}; +Figure.prototype.fireMoveEvent=function(){ +this.setDocumentDirty(); +var size=this.moveListener.getSize(); +for(var i=0;ih){ +Oval.prototype.setDimension.call(this,w,w); +}else{ +Oval.prototype.setDimension.call(this,h,h); +} +}; +Circle.prototype.isStrechable=function(){ +return false; +}; +Rectangle=function(width,_3e35){ +this.bgColor=null; +this.lineColor=new Color(0,0,0); +this.lineStroke=1; +Figure.call(this); +if(width&&_3e35){ +this.setDimension(width,_3e35); +} +}; +Rectangle.prototype=new Figure; +Rectangle.prototype.type="Rectangle"; +Rectangle.prototype.dispose=function(){ +Figure.prototype.dispose.call(this); +this.bgColor=null; +this.lineColor=null; +}; +Rectangle.prototype.createHTMLElement=function(){ +var item=Figure.prototype.createHTMLElement.call(this); +item.style.width="auto"; +item.style.height="auto"; +item.style.margin="0px"; +item.style.padding="0px"; +item.style.border=this.lineStroke+"px solid "+this.lineColor.getHTMLStyle(); +item.style.fontSize="1px"; +item.style.lineHeight="1px"; +item.innerHTML=" "; +if(this.bgColor!=null){ +item.style.backgroundColor=this.bgColor.getHTMLStyle(); +} +return item; +}; +Rectangle.prototype.setBackgroundColor=function(color){ +this.bgColor=color; +if(this.bgColor!=null){ +this.html.style.backgroundColor=this.bgColor.getHTMLStyle(); +}else{ +this.html.style.backgroundColor="transparent"; +} +}; +Rectangle.prototype.getBackgroundColor=function(){ +return this.bgColor; +}; +Rectangle.prototype.setColor=function(color){ +this.lineColor=color; +if(this.lineColor!=null){ +this.html.style.border=this.lineStroke+"px solid "+this.lineColor.getHTMLStyle(); +}else{ +this.html.style.border=this.lineStroke+"0px"; +} +}; +Rectangle.prototype.getColor=function(){ +return this.lineColor; +}; +Rectangle.prototype.getWidth=function(){ +return Figure.prototype.getWidth.call(this)+2*this.lineStroke; +}; +Rectangle.prototype.getHeight=function(){ +return Figure.prototype.getHeight.call(this)+2*this.lineStroke; +}; +Rectangle.prototype.setDimension=function(w,h){ +return Figure.prototype.setDimension.call(this,w-2*this.lineStroke,h-2*this.lineStroke); +}; +Rectangle.prototype.setLineWidth=function(w){ +var diff=w-this.lineStroke; +this.setDimension(this.getWidth()-2*diff,this.getHeight()-2*diff); +this.lineStroke=w; +var c="transparent"; +if(this.lineColor!=null){ +c=this.lineColor.getHTMLStyle(); +} +this.html.style.border=this.lineStroke+"px solid "+c; +}; +Rectangle.prototype.getLineWidth=function(){ +return this.lineStroke; +}; +ImageFigure=function(url){ +this.url=url; +Node.call(this); +this.setDimension(40,40); +}; +ImageFigure.prototype=new Node; +ImageFigure.prototype.type="Image"; +ImageFigure.prototype.createHTMLElement=function(){ +var item=Node.prototype.createHTMLElement.call(this); +item.style.width=this.width+"px"; +item.style.height=this.height+"px"; +item.style.margin="0px"; +item.style.padding="0px"; +item.style.border="0px"; +if(this.url!=null){ +item.style.backgroundImage="url("+this.url+")"; +}else{ +item.style.backgroundImage=""; +} +return item; +}; +ImageFigure.prototype.setColor=function(color){ +}; +ImageFigure.prototype.isResizeable=function(){ +return false; +}; +ImageFigure.prototype.setImage=function(url){ +this.url=url; +if(this.url!=null){ +this.html.style.backgroundImage="url("+this.url+")"; +}else{ +this.html.style.backgroundImage=""; +} +}; +Port=function(_41c2,_41c3){ +Corona=function(){ +}; +Corona.prototype=new Circle; +Corona.prototype.setAlpha=function(_41c4){ +Circle.prototype.setAlpha.call(this,Math.min(0.3,_41c4)); +}; +if(_41c2==null){ +this.currentUIRepresentation=new Circle(); +}else{ +this.currentUIRepresentation=_41c2; +} +if(_41c3==null){ +this.connectedUIRepresentation=new Circle(); +this.connectedUIRepresentation.setColor(null); +}else{ +this.connectedUIRepresentation=_41c3; +} +this.disconnectedUIRepresentation=this.currentUIRepresentation; +this.hideIfConnected=false; +this.uiRepresentationAdded=true; +this.parentNode=null; +this.originX=0; +this.originY=0; +this.coronaWidth=10; +this.corona=null; +Rectangle.call(this); +this.setDimension(8,8); +this.setBackgroundColor(new Color(100,180,100)); +this.setColor(new Color(90,150,90)); +Rectangle.prototype.setColor.call(this,null); +this.dropable=new DropTarget(this.html); +this.dropable.node=this; +this.dropable.addEventListener("dragenter",function(_41c5){ +_41c5.target.node.onDragEnter(_41c5.relatedTarget.node); +}); +this.dropable.addEventListener("dragleave",function(_41c6){ +_41c6.target.node.onDragLeave(_41c6.relatedTarget.node); +}); +this.dropable.addEventListener("drop",function(_41c7){ +_41c7.relatedTarget.node.onDrop(_41c7.target.node); +}); +}; +Port.prototype=new Rectangle; +Port.prototype.type="Port"; +Port.ZOrderBaseIndex=5000; +Port.setZOrderBaseIndex=function(index){ +Port.ZOrderBaseIndex=index; +}; +Port.prototype.setHideIfConnected=function(flag){ +this.hideIfConnected=flag; +}; +Port.prototype.dispose=function(){ +var size=this.moveListener.getSize(); +for(var i=0;i=x&&iX<=iX2&&iY>=y&&iY<=iY2); +}; +Port.prototype.showCorona=function(flag,_41ed){ +if(flag==true){ +this.corona=new Corona(); +this.corona.setAlpha(0.3); +this.corona.setBackgroundColor(new Color(0,125,125)); +this.corona.setColor(null); +this.corona.setDimension(this.getWidth()+(this.getCoronaWidth()*2),this.getWidth()+(this.getCoronaWidth()*2)); +this.parentNode.getWorkflow().addFigure(this.corona,this.getAbsoluteX()-this.getCoronaWidth()-this.getWidth()/2,this.getAbsoluteY()-this.getCoronaWidth()-this.getHeight()/2); +}else{ +if(flag==false&&this.corona!=null){ +this.parentNode.getWorkflow().removeFigure(this.corona); +this.corona=null; +} +} +}; +InputPort=function(_4067){ +Port.call(this,_4067); +}; +InputPort.prototype=new Port; +InputPort.prototype.type="InputPort"; +InputPort.prototype.onDrop=function(port){ +if(port.getMaxFanOut&&port.getMaxFanOut()<=port.getFanOut()){ +return; +} +if(this.parentNode.id==port.parentNode.id){ +}else{ +if(port instanceof OutputPort){ +var _4069=new CommandConnect(this.parentNode.workflow,port,this); +this.parentNode.workflow.getCommandStack().execute(_4069); +} +} +}; +InputPort.prototype.onDragEnter=function(port){ +if(port instanceof OutputPort){ +Port.prototype.onDragEnter.call(this,port); +}else{ +if(port instanceof LineStartResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getSource() instanceof InputPort){ +Port.prototype.onDragEnter.call(this,line.getSource()); +} +}else{ +if(port instanceof LineEndResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getTarget() instanceof InputPort){ +Port.prototype.onDragEnter.call(this,line.getTarget()); +} +} +} +} +}; +InputPort.prototype.onDragLeave=function(port){ +if(port instanceof OutputPort){ +Port.prototype.onDragLeave.call(this,port); +}else{ +if(port instanceof LineStartResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getSource() instanceof InputPort){ +Port.prototype.onDragLeave.call(this,line.getSource()); +} +}else{ +if(port instanceof LineEndResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getTarget() instanceof InputPort){ +Port.prototype.onDragLeave.call(this,line.getTarget()); +} +} +} +} +}; +OutputPort=function(_357f){ +Port.call(this,_357f); +this.maxFanOut=100; +}; +OutputPort.prototype=new Port; +OutputPort.prototype.type="OutputPort"; +OutputPort.prototype.onDrop=function(port){ +if(this.getMaxFanOut()<=this.getFanOut()){ +return; +} +if(this.parentNode.id==port.parentNode.id){ +}else{ +if(port instanceof InputPort){ +var _3581=new CommandConnect(this.parentNode.workflow,this,port); +this.parentNode.workflow.getCommandStack().execute(_3581); +} +} +}; +OutputPort.prototype.onDragEnter=function(port){ +if(this.getMaxFanOut()<=this.getFanOut()){ +return; +} +if(port instanceof InputPort){ +Port.prototype.onDragEnter.call(this,port); +}else{ +if(port instanceof LineStartResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getSource() instanceof OutputPort){ +Port.prototype.onDragEnter.call(this,line.getSource()); +} +}else{ +if(port instanceof LineEndResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getTarget() instanceof OutputPort){ +Port.prototype.onDragEnter.call(this,line.getTarget()); +} +} +} +} +}; +OutputPort.prototype.onDragLeave=function(port){ +if(port instanceof InputPort){ +Port.prototype.onDragLeave.call(this,port); +}else{ +if(port instanceof LineStartResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getSource() instanceof OutputPort){ +Port.prototype.onDragLeave.call(this,line.getSource()); +} +}else{ +if(port instanceof LineEndResizeHandle){ +var line=this.workflow.currentSelection; +if(line instanceof Connection&&line.getTarget() instanceof OutputPort){ +Port.prototype.onDragLeave.call(this,line.getTarget()); +} +} +} +} +}; +OutputPort.prototype.onDragstart=function(x,y){ +if(this.maxFanOut==-1){ +return true; +} +if(this.getMaxFanOut()<=this.getFanOut()){ +return false; +} +return true; +}; +OutputPort.prototype.setMaxFanOut=function(count){ +this.maxFanOut=count; +}; +OutputPort.prototype.getMaxFanOut=function(){ +return this.maxFanOut; +}; +OutputPort.prototype.getFanOut=function(){ +if(this.getParent().workflow==null){ +return 0; +} +var count=0; +var lines=this.getParent().workflow.getLines(); +var size=lines.getSize(); +for(var i=0;i=99){ +this.html.style.filter=""; +}else{ +this.html.style.filter="alpha(opacity="+_3ed5+")"; +} +} +catch(exc){ +} +this.alpha=_3ed4; +}; +Line.prototype.setStartPoint=function(x,y){ +this.startX=x; +this.startY=y; +if(this.graphics!=null){ +this.paint(); +} +this.setDocumentDirty(); +}; +Line.prototype.setEndPoint=function(x,y){ +this.endX=x; +this.endY=y; +if(this.graphics!=null){ +this.paint(); +} +this.setDocumentDirty(); +}; +Line.prototype.getStartX=function(){ +return this.startX; +}; +Line.prototype.getStartY=function(){ +return this.startY; +}; +Line.prototype.getStartPoint=function(){ +return new Point(this.startX,this.startY); +}; +Line.prototype.getEndX=function(){ +return this.endX; +}; +Line.prototype.getEndY=function(){ +return this.endY; +}; +Line.prototype.getEndPoint=function(){ +return new Point(this.endX,this.endY); +}; +Line.prototype.isSelectable=function(){ +return this.selectable; +}; +Line.prototype.setSelectable=function(flag){ +this.selectable=flag; +}; +Line.prototype.isDeleteable=function(){ +return this.deleteable; +}; +Line.prototype.setDeleteable=function(flag){ +this.deleteable=flag; +}; +Line.prototype.getLength=function(){ +return Math.sqrt((this.startX-this.endX)*(this.startX-this.endX)+(this.startY-this.endY)*(this.startY-this.endY)); +}; +Line.prototype.getAngle=function(){ +var _3edc=this.getLength(); +var angle=-(180/Math.PI)*Math.asin((this.startY-this.endY)/_3edc); +if(angle<0){ +if(this.endX0)&&((yDiff*yDiff)0)&&(toDir==DOWN))||((yDiff<0)&&(toDir==UP))){ +point=new Point(toPt.x,_3bad.y); +}else{ +if(_3bae==toDir){ +var pos=Math.min(_3bad.x,toPt.x)-this.MINDIST; +point=new Point(pos,_3bad.y); +}else{ +point=new Point(_3bad.x-(xDiff/2),_3bad.y); +} +} +} +if(yDiff>0){ +dir=UP; +}else{ +dir=DOWN; +} +} +}else{ +if(_3bae==RIGHT){ +if((xDiff<0)&&((yDiff*yDiff)0){ +point=new Point(_3bad.x+this.MINDIST,_3bad.y); +}else{ +if(((yDiff>0)&&(toDir==DOWN))||((yDiff<0)&&(toDir==UP))){ +point=new Point(toPt.x,_3bad.y); +}else{ +if(_3bae==toDir){ +var pos=Math.max(_3bad.x,toPt.x)+this.MINDIST; +point=new Point(pos,_3bad.y); +}else{ +point=new Point(_3bad.x-(xDiff/2),_3bad.y); +} +} +} +if(yDiff>0){ +dir=UP; +}else{ +dir=DOWN; +} +} +}else{ +if(_3bae==DOWN){ +if(((xDiff*xDiff)0){ +point=new Point(_3bad.x,_3bad.y+this.MINDIST); +}else{ +if(((xDiff>0)&&(toDir==RIGHT))||((xDiff<0)&&(toDir==LEFT))){ +point=new Point(_3bad.x,toPt.y); +}else{ +if(_3bae==toDir){ +var pos=Math.max(_3bad.y,toPt.y)+this.MINDIST; +point=new Point(_3bad.x,pos); +}else{ +point=new Point(_3bad.x,_3bad.y-(yDiff/2)); +} +} +} +if(xDiff>0){ +dir=LEFT; +}else{ +dir=RIGHT; +} +} +}else{ +if(_3bae==UP){ +if(((xDiff*xDiff)0)&&(toDir==DOWN)){ +point=toPt; +dir=toDir; +}else{ +if(yDiff<0){ +point=new Point(_3bad.x,_3bad.y-this.MINDIST); +}else{ +if(((xDiff>0)&&(toDir==RIGHT))||((xDiff<0)&&(toDir==LEFT))){ +point=new Point(_3bad.x,toPt.y); +}else{ +if(_3bae==toDir){ +var pos=Math.min(_3bad.y,toPt.y)-this.MINDIST; +point=new Point(_3bad.x,pos); +}else{ +point=new Point(_3bad.x,_3bad.y-(yDiff/2)); +} +} +} +if(xDiff>0){ +dir=LEFT; +}else{ +dir=RIGHT; +} +} +} +} +} +} +this._route(conn,point,dir,toPt,toDir); +conn.addPoint(_3bad); +}; +BezierConnectionRouter=function(_354a){ +if(!_354a){ +this.cheapRouter=new ManhattanConnectionRouter(); +}else{ +this.cheapRouter=null; +} +this.iteration=5; +}; +BezierConnectionRouter.prototype=new ConnectionRouter; +BezierConnectionRouter.prototype.type="BezierConnectionRouter"; +BezierConnectionRouter.prototype.drawBezier=function(_354b,_354c,t,iter){ +var n=_354b.length-1; +var q=new Array(); +var _3551=n+1; +for(var i=0;i<_3551;i++){ +q[i]=new Array(); +q[i][0]=_354b[i]; +} +for(var j=1;j<=n;j++){ +for(var i=0;i<=(n-j);i++){ +q[i][j]=new Point((1-t)*q[i][j-1].x+t*q[i+1][j-1].x,(1-t)*q[i][j-1].y+t*q[i+1][j-1].y); +} +} +var c1=new Array(); +var c2=new Array(); +for(var i=0;i=0){ +this.drawBezier(c1,_354c,t,--iter); +this.drawBezier(c2,_354c,t,--iter); +}else{ +for(var i=0;i0)&&((yDiff*yDiff)0)&&(toDir==DOWN))||((yDiff<0)&&(toDir==UP))){ +point=new Point(toPt.x,_355e.y); +}else{ +if(_355f==toDir){ +var pos=Math.min(_355e.x,toPt.x)-_3564; +point=new Point(pos,_355e.y); +}else{ +point=new Point(_355e.x-(xDiff/2),_355e.y); +} +} +} +if(yDiff>0){ +dir=UP; +}else{ +dir=DOWN; +} +} +}else{ +if(_355f==RIGHT){ +if((xDiff<0)&&((yDiff*yDiff)0){ +point=new Point(_355e.x+_3564,_355e.y); +}else{ +if(((yDiff>0)&&(toDir==DOWN))||((yDiff<0)&&(toDir==UP))){ +point=new Point(toPt.x,_355e.y); +}else{ +if(_355f==toDir){ +var pos=Math.max(_355e.x,toPt.x)+_3564; +point=new Point(pos,_355e.y); +}else{ +point=new Point(_355e.x-(xDiff/2),_355e.y); +} +} +} +if(yDiff>0){ +dir=UP; +}else{ +dir=DOWN; +} +} +}else{ +if(_355f==DOWN){ +if(((xDiff*xDiff)0){ +point=new Point(_355e.x,_355e.y+_3564); +}else{ +if(((xDiff>0)&&(toDir==RIGHT))||((xDiff<0)&&(toDir==LEFT))){ +point=new Point(_355e.x,toPt.y); +}else{ +if(_355f==toDir){ +var pos=Math.max(_355e.y,toPt.y)+_3564; +point=new Point(_355e.x,pos); +}else{ +point=new Point(_355e.x,_355e.y-(yDiff/2)); +} +} +} +if(xDiff>0){ +dir=LEFT; +}else{ +dir=RIGHT; +} +} +}else{ +if(_355f==UP){ +if(((xDiff*xDiff)0)&&(toDir==DOWN)){ +point=toPt; +dir=toDir; +}else{ +if(yDiff<0){ +point=new Point(_355e.x,_355e.y-_3564); +}else{ +if(((xDiff>0)&&(toDir==RIGHT))||((xDiff<0)&&(toDir==LEFT))){ +point=new Point(_355e.x,toPt.y); +}else{ +if(_355f==toDir){ +var pos=Math.min(_355e.y,toPt.y)-_3564; +point=new Point(_355e.x,pos); +}else{ +point=new Point(_355e.x,_355e.y-(yDiff/2)); +} +} +} +if(xDiff>0){ +dir=LEFT; +}else{ +dir=RIGHT; +} +} +} +} +} +} +this._route(_355c,conn,point,dir,toPt,toDir); +_355c.push(_355e); +}; +FanConnectionRouter=function(){ +}; +FanConnectionRouter.prototype=new NullConnectionRouter; +FanConnectionRouter.prototype.type="FanConnectionRouter"; +FanConnectionRouter.prototype.route=function(conn){ +var _40c7=conn.getStartPoint(); +var toPt=conn.getEndPoint(); +var lines=conn.getSource().getConnections(); +var _40ca=new ArrayList(); +var index=0; +for(var i=0;i1){ +this.routeCollision(conn,index); +}else{ +NullConnectionRouter.prototype.route.call(this,conn); +} +}; +FanConnectionRouter.prototype.routeNormal=function(conn){ +conn.addPoint(conn.getStartPoint()); +conn.addPoint(conn.getEndPoint()); +}; +FanConnectionRouter.prototype.routeCollision=function(conn,index){ +var start=conn.getStartPoint(); +var end=conn.getEndPoint(); +conn.addPoint(start); +var _40d3=10; +var _40d4=new Point((end.x+start.x)/2,(end.y+start.y)/2); +var _40d5=end.getPosition(start); +var ray; +if(_40d5==PositionConstants.SOUTH||_40d5==PositionConstants.EAST){ +ray=new Point(end.x-start.x,end.y-start.y); +}else{ +ray=new Point(start.x-end.x,start.y-end.y); +} +var _40d7=Math.sqrt(ray.x*ray.x+ray.y*ray.y); +var _40d8=_40d3*ray.x/_40d7; +var _40d9=_40d3*ray.y/_40d7; +var _40da; +if(index%2==0){ +_40da=new Point(_40d4.x+(index/2)*(-1*_40d9),_40d4.y+(index/2)*_40d8); +}else{ +_40da=new Point(_40d4.x+(index/2)*_40d9,_40d4.y+(index/2)*(-1*_40d8)); +} +conn.addPoint(_40da); +conn.addPoint(end); +}; +Graphics=function(_3a61,_3a62,_3a63){ +this.jsGraphics=_3a61; +this.xt=_3a63.x; +this.yt=_3a63.y; +this.radian=_3a62*Math.PI/180; +this.sinRadian=Math.sin(this.radian); +this.cosRadian=Math.cos(this.radian); +}; +Graphics.prototype.setStroke=function(x){ +this.jsGraphics.setStroke(x); +}; +Graphics.prototype.drawLine=function(x1,y1,x2,y2){ +var _x1=this.xt+x1*this.cosRadian-y1*this.sinRadian; +var _y1=this.yt+x1*this.sinRadian+y1*this.cosRadian; +var _x2=this.xt+x2*this.cosRadian-y2*this.sinRadian; +var _y2=this.yt+x2*this.sinRadian+y2*this.cosRadian; +this.jsGraphics.drawLine(_x1,_y1,_x2,_y2); +}; +Graphics.prototype.fillRect=function(x,y,w,h){ +var x1=this.xt+x*this.cosRadian-y*this.sinRadian; +var y1=this.yt+x*this.sinRadian+y*this.cosRadian; +var x2=this.xt+(x+w)*this.cosRadian-y*this.sinRadian; +var y2=this.yt+(x+w)*this.sinRadian+y*this.cosRadian; +var x3=this.xt+(x+w)*this.cosRadian-(y+h)*this.sinRadian; +var y3=this.yt+(x+w)*this.sinRadian+(y+h)*this.cosRadian; +var x4=this.xt+x*this.cosRadian-(y+h)*this.sinRadian; +var y4=this.yt+x*this.sinRadian+(y+h)*this.cosRadian; +this.jsGraphics.fillPolygon([x1,x2,x3,x4],[y1,y2,y3,y4]); +}; +Graphics.prototype.fillPolygon=function(_3a79,_3a7a){ +var rotX=new Array(); +var rotY=new Array(); +for(var i=0;i<_3a79.length;i++){ +rotX[i]=this.xt+_3a79[i]*this.cosRadian-_3a7a[i]*this.sinRadian; +rotY[i]=this.yt+_3a79[i]*this.sinRadian+_3a7a[i]*this.cosRadian; +} +this.jsGraphics.fillPolygon(rotX,rotY); +}; +Graphics.prototype.setColor=function(color){ +this.jsGraphics.setColor(color.getHTMLStyle()); +}; +Graphics.prototype.drawPolygon=function(_3a7f,_3a80){ +var rotX=new Array(); +var rotY=new Array(); +for(var i=0;i<_3a7f.length;i++){ +rotX[i]=this.xt+_3a7f[i]*this.cosRadian-_3a80[i]*this.sinRadian; +rotY[i]=this.yt+_3a7f[i]*this.sinRadian+_3a80[i]*this.cosRadian; +} +this.jsGraphics.drawPolygon(rotX,rotY); +}; +Connection=function(){ +Line.call(this); +this.sourcePort=null; +this.targetPort=null; +this.sourceDecorator=null; +this.targetDecorator=null; +this.sourceAnchor=new ConnectionAnchor(); +this.targetAnchor=new ConnectionAnchor(); +this.router=Connection.defaultRouter; +this.lineSegments=new ArrayList(); +this.children=new ArrayList(); +this.setColor(new Color(0,0,115)); +this.setLineWidth(1); +}; +Connection.prototype=new Line; +Connection.defaultRouter=new ManhattanConnectionRouter(); +Connection.setDefaultRouter=function(_2e24){ +Connection.defaultRouter=_2e24; +}; +Connection.prototype.disconnect=function(){ +if(this.sourcePort!=null){ +this.sourcePort.detachMoveListener(this); +this.fireSourcePortRouteEvent(); +} +if(this.targetPort!=null){ +this.targetPort.detachMoveListener(this); +this.fireTargetPortRouteEvent(); +} +}; +Connection.prototype.reconnect=function(){ +if(this.sourcePort!=null){ +this.sourcePort.attachMoveListener(this); +this.fireSourcePortRouteEvent(); +} +if(this.targetPort!=null){ +this.targetPort.attachMoveListener(this); +this.fireTargetPortRouteEvent(); +} +}; +Connection.prototype.isResizeable=function(){ +return true; +}; +Connection.prototype.addFigure=function(_2e25,_2e26){ +var entry=new Object(); +entry.figure=_2e25; +entry.locator=_2e26; +this.children.add(entry); +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.setSourceDecorator=function(_2e28){ +this.sourceDecorator=_2e28; +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.setTargetDecorator=function(_2e29){ +this.targetDecorator=_2e29; +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.setSourceAnchor=function(_2e2a){ +this.sourceAnchor=_2e2a; +this.sourceAnchor.setOwner(this.sourcePort); +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.setTargetAnchor=function(_2e2b){ +this.targetAnchor=_2e2b; +this.targetAnchor.setOwner(this.targetPort); +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.setRouter=function(_2e2c){ +if(_2e2c!=null){ +this.router=_2e2c; +}else{ +this.router=new NullConnectionRouter(); +} +if(this.graphics!=null){ +this.paint(); +} +}; +Connection.prototype.getRouter=function(){ +return this.router; +}; +Connection.prototype.paint=function(){ +for(var i=0;i0){ +window.clearInterval(_3e60.timer); +} +_3e60.timer=window.setInterval(_3e61,30); +} +_3e5c.setCanvas(this); +if(xPos&&yPos){ +_3e5c.setPosition(xPos,yPos); +} +if(_3e5c instanceof Line){ +this.canvasLines.add(_3e5c); +this.html.appendChild(_3e5c.getHTMLElement()); +}else{ +var obj=this.canvasLines.getFirstElement(); +if(obj==null){ +this.html.appendChild(_3e5c.getHTMLElement()); +}else{ +this.html.insertBefore(_3e5c.getHTMLElement(),obj.getHTMLElement()); +} +} +if(!_3e5f){ +_3e5c.paint(); +} +}; +Canvas.prototype.removeFigure=function(_3e63){ +if(this.enableSmoothFigureHandling==true){ +var oThis=this; +var _3e65=_3e63; +var _3e66=function(){ +if(_3e65.alpha>0){ +_3e65.setAlpha(Math.max(0,_3e65.alpha-0.05)); +}else{ +window.clearInterval(_3e65.timer); +_3e65.timer=-1; +oThis.html.removeChild(_3e65.html); +_3e65.setCanvas(null); +} +}; +if(_3e65.timer>0){ +window.clearInterval(_3e65.timer); +} +_3e65.timer=window.setInterval(_3e66,20); +}else{ +this.html.removeChild(_3e63.html); +_3e63.setCanvas(null); +} +if(_3e63 instanceof Line){ +this.canvasLines.remove(_3e63); +} +}; +Canvas.prototype.getEnableSmoothFigureHandling=function(){ +return this.enableSmoothFigureHandling; +}; +Canvas.prototype.setEnableSmoothFigureHandling=function(flag){ +this.enableSmoothFigureHandling=flag; +}; +Canvas.prototype.getWidth=function(){ +return parseInt(this.html.style.width); +}; +Canvas.prototype.getHeight=function(){ +return parseInt(this.html.style.height); +}; +Canvas.prototype.setBackgroundImage=function(_3e68,_3e69){ +if(_3e68!=null){ +if(_3e69){ +this.html.style.background="transparent url("+_3e68+") "; +}else{ +this.html.style.background="transparent url("+_3e68+") no-repeat"; +} +}else{ +this.html.style.background="transparent"; +} +}; +Canvas.prototype.getY=function(){ +return this.y; +}; +Canvas.prototype.getX=function(){ +return this.x; +}; +Canvas.prototype.getAbsoluteY=function(){ +var el=this.html; +var ot=el.offsetTop; +while((el=el.offsetParent)!=null){ +ot+=el.offsetTop; +} +return ot; +}; +Canvas.prototype.getAbsoluteX=function(){ +var el=this.html; +var ol=el.offsetLeft; +while((el=el.offsetParent)!=null){ +ol+=el.offsetLeft; +} +return ol; +}; +Canvas.prototype.getScrollLeft=function(){ +return this.scrollArea.scrollLeft; +}; +Canvas.prototype.getScrollTop=function(){ +return this.scrollArea.scrollTop; +}; +Workflow=function(id){ +if(!id){ +return; +} +this.gridWidthX=10; +this.gridWidthY=10; +this.snapToGridHelper=null; +this.verticalSnapToHelperLine=null; +this.horizontalSnapToHelperLine=null; +this.figures=new ArrayList(); +this.lines=new ArrayList(); +this.commonPorts=new ArrayList(); +this.dropTargets=new ArrayList(); +this.compartments=new ArrayList(); +this.selectionListeners=new ArrayList(); +this.dialogs=new ArrayList(); +this.toolPalette=null; +this.dragging=false; +this.tooltip=null; +this.draggingLine=null; +this.commandStack=new CommandStack(); +this.oldScrollPosLeft=0; +this.oldScrollPosTop=0; +this.currentSelection=null; +this.currentMenu=null; +this.connectionLine=new Line(); +this.resizeHandleStart=new LineStartResizeHandle(this); +this.resizeHandleEnd=new LineEndResizeHandle(this); +this.resizeHandle1=new ResizeHandle(this,1); +this.resizeHandle2=new ResizeHandle(this,2); +this.resizeHandle3=new ResizeHandle(this,3); +this.resizeHandle4=new ResizeHandle(this,4); +this.resizeHandle5=new ResizeHandle(this,5); +this.resizeHandle6=new ResizeHandle(this,6); +this.resizeHandle7=new ResizeHandle(this,7); +this.resizeHandle8=new ResizeHandle(this,8); +this.resizeHandleHalfWidth=parseInt(this.resizeHandle2.getWidth()/2); +Canvas.call(this,id); +this.setPanning(false); +if(this.html!=null){ +this.html.style.backgroundImage="url(grid_10.png)"; +oThis=this; +this.html.tabIndex="0"; +var _4116=function(){ +var _4117=arguments[0]||window.event; +var diffX=_4117.clientX; +var diffY=_4117.clientY; +var _411a=oThis.getScrollLeft(); +var _411b=oThis.getScrollTop(); +var _411c=oThis.getAbsoluteX(); +var _411d=oThis.getAbsoluteY(); +if(oThis.getBestFigure(diffX+_411a-_411c,diffY+_411b-_411d)!=null){ +return; +} +var line=oThis.getBestLine(diffX+_411a-_411c,diffY+_411b-_411d,null); +if(line!=null){ +line.onContextMenu(diffX+_411a-_411c,diffY+_411b-_411d); +}else{ +oThis.onContextMenu(diffX+_411a-_411c,diffY+_411b-_411d); +} +}; +this.html.oncontextmenu=function(){ +return false; +}; +var oThis=this; +var _4120=function(event){ +var ctrl=event.ctrlKey; +oThis.onKeyDown(event.keyCode,ctrl); +}; +var _4123=function(){ +var _4124=arguments[0]||window.event; +var diffX=_4124.clientX; +var diffY=_4124.clientY; +var _4127=oThis.getScrollLeft(); +var _4128=oThis.getScrollTop(); +var _4129=oThis.getAbsoluteX(); +var _412a=oThis.getAbsoluteY(); +oThis.onMouseDown(diffX+_4127-_4129,diffY+_4128-_412a); +}; +var _412b=function(){ +var _412c=arguments[0]||window.event; +if(oThis.currentMenu!=null){ +oThis.removeFigure(oThis.currentMenu); +oThis.currentMenu=null; +} +if(_412c.button==2){ +return; +} +var diffX=_412c.clientX; +var diffY=_412c.clientY; +var _412f=oThis.getScrollLeft(); +var _4130=oThis.getScrollTop(); +var _4131=oThis.getAbsoluteX(); +var _4132=oThis.getAbsoluteY(); +oThis.onMouseUp(diffX+_412f-_4131,diffY+_4130-_4132); +}; +var _4133=function(){ +var _4134=arguments[0]||window.event; +var diffX=_4134.clientX; +var diffY=_4134.clientY; +var _4137=oThis.getScrollLeft(); +var _4138=oThis.getScrollTop(); +var _4139=oThis.getAbsoluteX(); +var _413a=oThis.getAbsoluteY(); +oThis.currentMouseX=diffX+_4137-_4139; +oThis.currentMouseY=diffY+_4138-_413a; +var obj=oThis.getBestFigure(oThis.currentMouseX,oThis.currentMouseY); +if(Drag.currentHover!=null&&obj==null){ +var _413c=new DragDropEvent(); +_413c.initDragDropEvent("mouseleave",false,oThis); +Drag.currentHover.dispatchEvent(_413c); +}else{ +var diffX=_4134.clientX; +var diffY=_4134.clientY; +var _4137=oThis.getScrollLeft(); +var _4138=oThis.getScrollTop(); +var _4139=oThis.getAbsoluteX(); +var _413a=oThis.getAbsoluteY(); +oThis.onMouseMove(diffX+_4137-_4139,diffY+_4138-_413a); +} +if(obj==null){ +Drag.currentHover=null; +} +if(oThis.tooltip!=null){ +if(Math.abs(oThis.currentTooltipX-oThis.currentMouseX)>10||Math.abs(oThis.currentTooltipY-oThis.currentMouseY)>10){ +oThis.showTooltip(null); +} +} +}; +var _413d=function(_413e){ +var _413e=arguments[0]||window.event; +var diffX=_413e.clientX; +var diffY=_413e.clientY; +var _4141=oThis.getScrollLeft(); +var _4142=oThis.getScrollTop(); +var _4143=oThis.getAbsoluteX(); +var _4144=oThis.getAbsoluteY(); +var line=oThis.getBestLine(diffX+_4141-_4143,diffY+_4142-_4144,null); +if(line!=null){ +line.onDoubleClick(); +} +}; +if(this.html.addEventListener){ +this.html.addEventListener("contextmenu",_4116,false); +this.html.addEventListener("mousemove",_4133,false); +this.html.addEventListener("mouseup",_412b,false); +this.html.addEventListener("mousedown",_4123,false); +this.html.addEventListener("keydown",_4120,false); +this.html.addEventListener("dblclick",_413d,false); +}else{ +if(this.html.attachEvent){ +this.html.attachEvent("oncontextmenu",_4116); +this.html.attachEvent("onmousemove",_4133); +this.html.attachEvent("onmousedown",_4123); +this.html.attachEvent("onmouseup",_412b); +this.html.attachEvent("onkeydown",_4120); +this.html.attachEvent("ondblclick",_413d); +}else{ +throw new Error("Open-jACOB Draw2D not supported in this browser."); +} +} +} +}; +Workflow.prototype=new Canvas; +Workflow.prototype.type="Workflow"; +Workflow.COLOR_GREEN=new Color(0,255,0); +Workflow.prototype.onScroll=function(){ +var _4146=this.getScrollLeft(); +var _4147=this.getScrollTop(); +var _4148=_4146-this.oldScrollPosLeft; +var _4149=_4147-this.oldScrollPosTop; +for(var i=0;i=0){ +window.clearTimeout(this.tooltipTimer); +this.tooltipTimer=-1; +} +} +this.tooltip=_4156; +if(this.tooltip!=null){ +this.currentTooltipX=this.currentMouseX; +this.currentTooltipY=this.currentMouseY; +this.addFigure(this.tooltip,this.currentTooltipX+10,this.currentTooltipY+10); +var oThis=this; +var _4159=function(){ +oThis.tooltipTimer=-1; +oThis.showTooltip(null); +}; +if(_4157==true){ +this.tooltipTimer=window.setTimeout(_4159,5000); +} +} +}; +Workflow.prototype.showDialog=function(_415a,xPos,yPos){ +if(xPos){ +this.addFigure(_415a,xPos,yPos); +}else{ +this.addFigure(_415a,200,100); +} +this.dialogs.add(_415a); +}; +Workflow.prototype.showMenu=function(menu,xPos,yPos){ +if(this.menu!=null){ +this.html.removeChild(this.menu.getHTMLElement()); +this.menu.setWorkflow(); +} +this.menu=menu; +if(this.menu!=null){ +this.menu.setWorkflow(this); +this.menu.setPosition(xPos,yPos); +this.html.appendChild(this.menu.getHTMLElement()); +this.menu.paint(); +} +}; +Workflow.prototype.onContextMenu=function(x,y){ +var menu=this.getContextMenu(); +if(menu!=null){ +this.showMenu(menu,x,y); +} +}; +Workflow.prototype.getContextMenu=function(){ +return null; +}; +Workflow.prototype.setToolWindow=function(_4163,x,y){ +this.toolPalette=_4163; +if(y){ +this.addFigure(_4163,x,y); +}else{ +this.addFigure(_4163,20,20); +} +this.dialogs.add(_4163); +}; +Workflow.prototype.setSnapToGrid=function(flag){ +if(flag){ +this.snapToGridHelper=new SnapToGrid(this); +}else{ +this.snapToGridHelper=null; +} +}; +Workflow.prototype.setSnapToGeometry=function(flag){ +if(flag){ +this.snapToGeometryHelper=new SnapToGeometry(this); +}else{ +this.snapToGeometryHelper=null; +} +}; +Workflow.prototype.setGridWidth=function(dx,dy){ +this.gridWidthX=dx; +this.gridWidthY=dy; +}; +Workflow.prototype.addFigure=function(_416a,xPos,yPos){ +Canvas.prototype.addFigure.call(this,_416a,xPos,yPos,true); +_416a.setWorkflow(this); +var _416d=this; +if(_416a instanceof CompartmentFigure){ +this.compartments.add(_416a); +} +if(_416a instanceof Line){ +this.lines.add(_416a); +}else{ +this.figures.add(_416a); +_416a.draggable.addEventListener("dragend",function(_416e){ +}); +_416a.draggable.addEventListener("dragstart",function(_416f){ +var _4170=_416d.getFigure(_416f.target.element.id); +if(_4170==null){ +return; +} +if(_4170.isSelectable()==false){ +return; +} +_416d.showResizeHandles(_4170); +_416d.setCurrentSelection(_4170); +}); +_416a.draggable.addEventListener("drag",function(_4171){ +var _4172=_416d.getFigure(_4171.target.element.id); +if(_4172==null){ +return; +} +if(_4172.isSelectable()==false){ +return; +} +_416d.moveResizeHandles(_4172); +}); +} +_416a.paint(); +this.setDocumentDirty(); +}; +Workflow.prototype.removeFigure=function(_4173){ +Canvas.prototype.removeFigure.call(this,_4173); +this.figures.remove(_4173); +this.lines.remove(_4173); +this.dialogs.remove(_4173); +_4173.setWorkflow(null); +if(_4173 instanceof CompartmentFigure){ +this.compartments.remove(_4173); +} +if(_4173 instanceof Connection){ +_4173.disconnect(); +} +if(this.currentSelection==_4173){ +this.setCurrentSelection(null); +} +this.setDocumentDirty(); +}; +Workflow.prototype.moveFront=function(_4174){ +this.html.removeChild(_4174.getHTMLElement()); +this.html.appendChild(_4174.getHTMLElement()); +}; +Workflow.prototype.moveBack=function(_4175){ +this.html.removeChild(_4175.getHTMLElement()); +this.html.insertBefore(_4175.getHTMLElement(),this.html.firstChild); +}; +Workflow.prototype.getBestCompartmentFigure=function(x,y,_4178){ +var _4179=null; +for(var i=0;i=0&&a<=b){ +return (a); +}else{ +if(a>b){ +return (b); +}else{ +if(a<0){ +return ("-"+oo); +} +} +} +}; +ColorDialog.prototype.mouseDownH=function(e){ +this.slideHSV[0]=this.HSV[0]; +var oThis=this; +this.H.onmousemove=function(e){ +oThis.dragH(e); +}; +this.H.onmouseup=function(e){ +oThis.H.onmousemove=""; +oThis.H.onmouseup=""; +}; +this.dragH(e); +}; +ColorDialog.prototype.dragH=function(e){ +var y=this.XY(e,1)-this.getY()-40; +this.Hslide.style.top=(this.ckHSV(y,this.wH)-5)+"px"; +this.slideHSV[0]=this.mkHSV(359,this.wH,this.Hslide.style.top); +this.updateSV(); +this.showColor(this.commit()); +this.SV.style.backgroundColor="#"+this.hsv2hex(Array(this.HSV[0],100,100)); +}; +ColorDialog.prototype.mouseDownSV=function(o,e){ +this.slideHSV[0]=this.HSV[0]; +var oThis=this; +function reset(){ +oThis.SV.onmousemove=""; +oThis.SV.onmouseup=""; +oThis.SVslide.onmousemove=""; +oThis.SVslide.onmouseup=""; +} +this.SV.onmousemove=function(e){ +oThis.dragSV(e); +}; +this.SV.onmouseup=reset; +this.SVslide.onmousemove=function(e){ +oThis.dragSV(e); +}; +this.SVslide.onmouseup=reset; +this.dragSV(e); +}; +ColorDialog.prototype.dragSV=function(e){ +var x=this.XY(e,0)-this.getX()-1; +var y=this.XY(e,1)-this.getY()-20; +this.SVslide.style.left=this.ckHSV(x,this.wSV)+"px"; +this.SVslide.style.top=this.ckHSV(y,this.wSV)+"px"; +this.slideHSV[1]=this.mkHSV(100,this.wSV,this.SVslide.style.left); +this.slideHSV[2]=100-this.mkHSV(100,this.wSV,this.SVslide.style.top); +this.updateSV(); +}; +ColorDialog.prototype.commit=function(){ +var r="hsv"; +var z={}; +var j=""; +for(var i=0;i<=r.length-1;i++){ +j=r.substr(i,1); +z[i]=(j=="h")?this.maxValue[j]-this.mkHSV(this.maxValue[j],this.wH,this.Hslide.style.top):this.HSV[i]; +} +return (this.updateSV(this.hsv2hex(z))); +}; +ColorDialog.prototype.updateSV=function(v){ +this.HSV=v?this.hex2hsv(v):Array(this.slideHSV[0],this.slideHSV[1],this.slideHSV[2]); +if(!v){ +v=this.hsv2hex(Array(this.slideHSV[0],this.slideHSV[1],this.slideHSV[2])); +} +this.showColor(v); +return v; +}; +ColorDialog.prototype.loadSV=function(){ +var z=""; +for(var i=this.SVHeight;i>=0;i--){ +z+="

"; +} +this.Hmodel.innerHTML=z; +}; +ColorDialog.prototype.updateH=function(v){ +this.plugHEX.innerHTML=v; +this.HSV=this.hex2hsv(v); +this.SV.style.backgroundColor="#"+this.hsv2hex(Array(this.HSV[0],100,100)); +this.SVslide.style.top=(parseInt(this.wSV-this.wSV*(this.HSV[1]/100))+20)+"px"; +this.SVslide.style.left=(parseInt(this.wSV*(this.HSV[1]/100))+5)+"px"; +this.Hslide.style.top=(parseInt(this.wH*((this.maxValue["h"]-this.HSV[0])/this.maxValue["h"]))-7)+"px"; +}; +ColorDialog.prototype.toHex=function(v){ +v=Math.round(Math.min(Math.max(0,v),255)); +return ("0123456789ABCDEF".charAt((v-v%16)/16)+"0123456789ABCDEF".charAt(v%16)); +}; +ColorDialog.prototype.hex2rgb=function(r){ +return ({0:parseInt(r.substr(0,2),16),1:parseInt(r.substr(2,2),16),2:parseInt(r.substr(4,2),16)}); +}; +ColorDialog.prototype.rgb2hex=function(r){ +return (this.toHex(r[0])+this.toHex(r[1])+this.toHex(r[2])); +}; +ColorDialog.prototype.hsv2hex=function(h){ +return (this.rgb2hex(this.hsv2rgb(h))); +}; +ColorDialog.prototype.hex2hsv=function(v){ +return (this.rgb2hsv(this.hex2rgb(v))); +}; +ColorDialog.prototype.rgb2hsv=function(r){ +var max=Math.max(r[0],r[1],r[2]); +var delta=max-Math.min(r[0],r[1],r[2]); +var H; +var S; +var V; +if(max!=0){ +S=Math.round(delta/max*100); +if(r[0]==max){ +H=(r[1]-r[2])/delta; +}else{ +if(r[1]==max){ +H=2+(r[2]-r[0])/delta; +}else{ +if(r[2]==max){ +H=4+(r[0]-r[1])/delta; +} +} +} +var H=Math.min(Math.round(H*60),360); +if(H<0){ +H+=360; +} +} +return ({0:H?H:0,1:S?S:0,2:Math.round((max/255)*100)}); +}; +ColorDialog.prototype.hsv2rgb=function(r){ +var R; +var B; +var G; +var S=r[1]/100; +var V=r[2]/100; +var H=r[0]/360; +if(S>0){ +if(H>=1){ +H=0; +} +H=6*H; +F=H-Math.floor(H); +A=Math.round(255*V*(1-S)); +B=Math.round(255*V*(1-(S*F))); +C=Math.round(255*V*(1-(S*(1-F)))); +V=Math.round(255*V); +switch(Math.floor(H)){ +case 0: +R=V; +G=C; +B=A; +break; +case 1: +R=B; +G=V; +B=A; +break; +case 2: +R=A; +G=V; +B=C; +break; +case 3: +R=A; +G=B; +B=V; +break; +case 4: +R=C; +G=A; +B=V; +break; +case 5: +R=V; +G=A; +B=B; +break; +} +return ({0:R?R:0,1:G?G:0,2:B?B:0}); +}else{ +return ({0:(V=Math.round(V*255)),1:V,2:V}); +} +}; +LineColorDialog=function(_2e57){ +ColorDialog.call(this); +this.figure=_2e57; +var color=_2e57.getColor(); +this.updateH(this.rgb2hex(color.getRed(),color.getGreen(),color.getBlue())); +}; +LineColorDialog.prototype=new ColorDialog; +LineColorDialog.prototype.type="LineColorDialog"; +LineColorDialog.prototype.onOk=function(){ +var _2e59=this.workflow; +ColorDialog.prototype.onOk.call(this); +if(typeof this.figure.setColor=="function"){ +_2e59.getCommandStack().execute(new CommandSetColor(this.figure,this.getSelectedColor())); +if(_2e59.getCurrentSelection()==this.figure){ +_2e59.setCurrentSelection(this.figure); +} +} +}; +BackgroundColorDialog=function(_40a6){ +ColorDialog.call(this); +this.figure=_40a6; +var color=_40a6.getBackgroundColor(); +if(color!=null){ +this.updateH(this.rgb2hex(color.getRed(),color.getGreen(),color.getBlue())); +} +}; +BackgroundColorDialog.prototype=new ColorDialog; +BackgroundColorDialog.prototype.type="BackgroundColorDialog"; +BackgroundColorDialog.prototype.onOk=function(){ +var _40a8=this.workflow; +ColorDialog.prototype.onOk.call(this); +if(typeof this.figure.setBackgroundColor=="function"){ +_40a8.getCommandStack().execute(new CommandSetBackgroundColor(this.figure,this.getSelectedColor())); +if(_40a8.getCurrentSelection()==this.figure){ +_40a8.setCurrentSelection(this.figure); +} +} +}; +AnnotationDialog=function(_2e5e){ +this.figure=_2e5e; +Dialog.call(this); +this.setDimension(400,100); +}; +AnnotationDialog.prototype=new Dialog; +AnnotationDialog.prototype.type="AnnotationDialog"; +AnnotationDialog.prototype.createHTMLElement=function(){ +var item=Dialog.prototype.createHTMLElement.call(this); +var _2e60=document.createElement("form"); +_2e60.style.position="absolute"; +_2e60.style.left="10px"; +_2e60.style.top="30px"; +_2e60.style.width="375px"; +_2e60.style.font="normal 10px verdana"; +item.appendChild(_2e60); +this.label=document.createTextNode("Text"); +_2e60.appendChild(this.label); +this.input=document.createElement("input"); +this.input.style.border="1px solid gray"; +this.input.style.font="normal 10px verdana"; +this.input.type="text"; +var value=this.figure.getText(); +if(value){ +this.input.value=value; +}else{ +this.input.value=""; +} +this.input.style.width="100%"; +_2e60.appendChild(this.input); +this.input.focus(); +return item; +}; +AnnotationDialog.prototype.onOk=function(){ +this.workflow.getCommandStack().execute(new CommandSetText(this.figure,this.input.value)); +this.workflow.removeFigure(this); +}; +Command=function(label){ +this.label=label; +}; +Command.prototype.type="Command"; +Command.prototype.getLabel=function(){ +}; +Command.prototype.canExecute=function(){ +return true; +}; +Command.prototype.execute=function(){ +}; +Command.prototype.undo=function(){ +}; +Command.prototype.redo=function(){ +}; +CommandStack=function(){ +this.undostack=new Array(); +this.redostack=new Array(); +this.maxundo=50; +this.eventListeners=new ArrayList(); +}; +CommandStack.PRE_EXECUTE=1; +CommandStack.PRE_REDO=2; +CommandStack.PRE_UNDO=4; +CommandStack.POST_EXECUTE=8; +CommandStack.POST_REDO=16; +CommandStack.POST_UNDO=32; +CommandStack.POST_MASK=CommandStack.POST_EXECUTE|CommandStack.POST_UNDO|CommandStack.POST_REDO; +CommandStack.PRE_MASK=CommandStack.PRE_EXECUTE|CommandStack.PRE_UNDO|CommandStack.PRE_REDO; +CommandStack.prototype.type="CommandStack"; +CommandStack.prototype.setUndoLimit=function(count){ +this.maxundo=count; +}; +CommandStack.prototype.markSaveLocation=function(){ +this.undostack=new Array(); +this.redostack=new Array(); +}; +CommandStack.prototype.execute=function(_3f6c){ +if(_3f6c.canExecute()==false){ +return; +} +this.notifyListeners(_3f6c,CommandStack.PRE_EXECUTE); +this.undostack.push(_3f6c); +_3f6c.execute(); +this.redostack=new Array(); +if(this.undostack.length>this.maxundo){ +this.undostack=this.undostack.slice(this.undostack.length-this.maxundo); +} +this.notifyListeners(_3f6c,CommandStack.POST_EXECUTE); +}; +CommandStack.prototype.undo=function(){ +var _3f6d=this.undostack.pop(); +if(_3f6d){ +this.notifyListeners(_3f6d,CommandStack.PRE_UNDO); +this.redostack.push(_3f6d); +_3f6d.undo(); +this.notifyListeners(_3f6d,CommandStack.POST_UNDO); +} +}; +CommandStack.prototype.redo=function(){ +var _3f6e=this.redostack.pop(); +if(_3f6e){ +this.notifyListeners(_3f6e,CommandStack.PRE_REDO); +this.undostack.push(_3f6e); +_3f6e.redo(); +this.notifyListeners(_3f6e,CommandStack.POST_REDO); +} +}; +CommandStack.prototype.canRedo=function(){ +return this.redostack.length>0; +}; +CommandStack.prototype.canUndo=function(){ +return this.undostack.length>0; +}; +CommandStack.prototype.addCommandStackEventListener=function(_3f6f){ +this.eventListeners.add(_3f6f); +}; +CommandStack.prototype.removeCommandStackEventListener=function(_3f70){ +this.eventListeners.remove(_3f70); +}; +CommandStack.prototype.notifyListeners=function(_3f71,state){ +var event=new CommandStackEvent(_3f71,state); +var size=this.eventListeners.getSize(); +for(var i=0;i",i="",b=a+"",j=""+i,l=b+"",v=""+j;function h(A,C,B,D,z,x){var y=r.insertHtml(D,Ext.getDom(A),t(C));return B?Ext.get(y,true):y}function t(D){var z="",y,C,B,x,E;if(typeof D=="string"){z=D}else{if(Ext.isArray(D)){for(var A=0;A"}}}return z}function g(E,B,A,C){w.innerHTML=[B,A,C].join("");var x=-1,z=w,y;while(++x "'+C+'"'},insertBefore:function(x,z,y){return h(x,z,y,c)},insertAfter:function(x,z,y){return h(x,z,y,p,"nextSibling")},insertFirst:function(x,z,y){return h(x,z,y,n,"firstChild")},append:function(x,z,y){return h(x,z,y,q,"",true)},overwrite:function(x,z,y){x=Ext.getDom(x);x.innerHTML=t(z);return y?Ext.get(x.firstChild):x.firstChild},createHtml:t};return r}();Ext.apply(Ext.DomHelper,function(){var e,a="afterbegin",h="afterend",i="beforebegin",d="beforeend",b=/tag|children|cn|html$/i;function g(m,p,n,q,l,j){m=Ext.getDom(m);var k;if(e.useDom){k=c(p,null);if(j){m.appendChild(k)}else{(l=="firstChild"?m:m.parentNode).insertBefore(k,m[l]||m)}}else{k=Ext.DomHelper.insertHtml(q,m,Ext.DomHelper.createHtml(p))}return n?Ext.get(k,true):k}function c(j,r){var k,u=document,p,s,m,t;if(Ext.isArray(j)){k=u.createDocumentFragment();for(var q=0,n=j.length;q1){for(var g=0,b=c.length;g+~]\s?|\s|$)/,tagTokenRe=/^(#)?([\w-\*]+)/,nthRe=/(\d*)n\+?(\d*)/,nthRe2=/\D/,isIE=window.ActiveXObject?true:false,key=30803;eval("var batch = 30803;");function child(parent,index){var i=0,n=parent.firstChild;while(n){if(n.nodeType==1){if(++i==index){return n}}n=n.nextSibling}return null}function next(n){while((n=n.nextSibling)&&n.nodeType!=1){}return n}function prev(n){while((n=n.previousSibling)&&n.nodeType!=1){}return n}function children(parent){var n=parent.firstChild,nodeIndex=-1,nextNode;while(n){nextNode=n.nextSibling;if(n.nodeType==3&&!nonSpace.test(n.nodeValue)){parent.removeChild(n)}else{n.nodeIndex=++nodeIndex}n=nextNode}return this}function byClassName(nodeSet,cls){if(!cls){return nodeSet}var result=[],ri=-1;for(var i=0,ci;ci=nodeSet[i];i++){if((" "+ci.className+" ").indexOf(cls)!=-1){result[++ri]=ci}}return result}function attrValue(n,attr){if(!n.tagName&&typeof n.length!="undefined"){n=n[0]}if(!n){return null}if(attr=="for"){return n.htmlFor}if(attr=="class"||attr=="className"){return n.className}return n.getAttribute(attr)||n[attr]}function getNodes(ns,mode,tagName){var result=[],ri=-1,cs;if(!ns){return result}tagName=tagName||"*";if(typeof ns.getElementsByTagName!="undefined"){ns=[ns]}if(!mode){for(var i=0,ni;ni=ns[i];i++){cs=ni.getElementsByTagName(tagName);for(var j=0,ci;ci=cs[j];j++){result[++ri]=ci}}}else{if(mode=="/"||mode==">"){var utag=tagName.toUpperCase();for(var i=0,ni,cn;ni=ns[i];i++){cn=ni.childNodes;for(var j=0,cj;cj=cn[j];j++){if(cj.nodeName==utag||cj.nodeName==tagName||tagName=="*"){result[++ri]=cj}}}}else{if(mode=="+"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(n&&(n.nodeName==utag||n.nodeName==tagName||tagName=="*")){result[++ri]=n}}}else{if(mode=="~"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)){if(n.nodeName==utag||n.nodeName==tagName||tagName=="*"){result[++ri]=n}}}}}}}return result}function concat(a,b){if(b.slice){return a.concat(b)}for(var i=0,l=b.length;i1){return nodup(results)}return results},isXml:function(el){var docEl=(el?el.ownerDocument||el:0).documentElement;return docEl?docEl.nodeName!=="HTML":false},select:document.querySelectorAll?function(path,root,type){root=root||document;if(!Ext.DomQuery.isXml(root)){try{var cs=root.querySelectorAll(path);return Ext.toArray(cs)}catch(ex){}}return Ext.DomQuery.jsSelect.call(this,path,root,type)}:function(path,root,type){return Ext.DomQuery.jsSelect.call(this,path,root,type)},selectNode:function(path,root){return Ext.DomQuery.select(path,root)[0]},selectValue:function(path,root,defaultValue){path=path.replace(trimRe,"");if(!valueCache[path]){valueCache[path]=Ext.DomQuery.compile(path,"select")}var n=valueCache[path](root),v;n=n[0]?n[0]:n;if(typeof n.normalize=="function"){n.normalize()}v=(n&&n.firstChild?n.firstChild.nodeValue:null);return((v===null||v===undefined||v==="")?defaultValue:v)},selectNumber:function(path,root,defaultValue){var v=Ext.DomQuery.selectValue(path,root,defaultValue||0);return parseFloat(v)},is:function(el,ss){if(typeof el=="string"){el=document.getElementById(el)}var isArray=Ext.isArray(el),result=Ext.DomQuery.filter(isArray?el:[el],ss);return isArray?(result.length==el.length):(result.length>0)},filter:function(els,ss,nonMatches){ss=ss.replace(trimRe,"");if(!simpleCache[ss]){simpleCache[ss]=Ext.DomQuery.compile(ss,"simple")}var result=simpleCache[ss](els);return nonMatches?quickDiff(result,els):result},matchers:[{re:/^\.([\w-]+)/,select:'n = byClassName(n, " {1} ");'},{re:/^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,select:'n = byPseudo(n, "{1}", "{2}");'},{re:/^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,select:'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'},{re:/^#([\w-]+)/,select:'n = byId(n, "{1}");'},{re:/^@([\w-]+)/,select:'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'}],operators:{"=":function(a,v){return a==v},"!=":function(a,v){return a!=v},"^=":function(a,v){return a&&a.substr(0,v.length)==v},"$=":function(a,v){return a&&a.substr(a.length-v.length)==v},"*=":function(a,v){return a&&a.indexOf(v)!==-1},"%=":function(a,v){return(a%v)==0},"|=":function(a,v){return a&&(a==v||a.substr(0,v.length+1)==v+"-")},"~=":function(a,v){return a&&(" "+a+" ").indexOf(" "+v+" ")!=-1}},pseudos:{"first-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.previousSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"last-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"nth-child":function(c,a){var r=[],ri=-1,m=nthRe.exec(a=="even"&&"2n"||a=="odd"&&"2n+1"||!nthRe2.test(a)&&"n+"+a||a),f=(m[1]||1)-0,l=m[2]-0;for(var i=0,n;n=c[i];i++){var pn=n.parentNode;if(batch!=pn._batch){var j=0;for(var cn=pn.firstChild;cn;cn=cn.nextSibling){if(cn.nodeType==1){cn.nodeIndex=++j}}pn._batch=batch}if(f==1){if(l==0||n.nodeIndex==l){r[++ri]=n}}else{if((n.nodeIndex+l)%f==0){r[++ri]=n}}}return r},"only-child":function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(!prev(ci)&&!next(ci)){r[++ri]=ci}}return r},empty:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var cns=ci.childNodes,j=0,cn,empty=true;while(cn=cns[j]){++j;if(cn.nodeType==1||cn.nodeType==3){empty=false;break}}if(empty){r[++ri]=ci}}return r},contains:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if((ci.textContent||ci.innerText||"").indexOf(v)!=-1){r[++ri]=ci}}return r},nodeValue:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.firstChild&&ci.firstChild.nodeValue==v){r[++ri]=ci}}return r},checked:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.checked==true){r[++ri]=ci}}return r},not:function(c,ss){return Ext.DomQuery.filter(c,ss,true)},any:function(c,selectors){var ss=selectors.split("|"),r=[],ri=-1,s;for(var i=0,ci;ci=c[i];i++){for(var j=0;s=ss[j];j++){if(Ext.DomQuery.is(ci,s)){r[++ri]=ci;break}}}return r},odd:function(c){return this["nth-child"](c,"odd")},even:function(c){return this["nth-child"](c,"even")},nth:function(c,a){return c[a-1]||[]},first:function(c){return c[0]||[]},last:function(c){return c[c.length-1]||[]},has:function(c,ss){var s=Ext.DomQuery.select,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(s(ss,ci).length>0){r[++ri]=ci}}return r},next:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r},prev:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r}}}}();Ext.query=Ext.DomQuery.select;Ext.util.DelayedTask=function(d,c,a){var e=this,g,b=function(){clearInterval(g);g=null;d.apply(c,a||[])};e.delay=function(i,k,j,h){e.cancel();d=k||d;c=j||c;a=h||a;g=setInterval(b,i)};e.cancel=function(){if(g){clearInterval(g);g=null}}};(function(){var h=Ext.util,j=Ext.each,g=true,i=false;h.Observable=function(){var k=this,l=k.events;if(k.listeners){k.on(k.listeners);delete k.listeners}k.events=l||{}};h.Observable.prototype={filterOptRe:/^(?:scope|delay|buffer|single)$/,fireEvent:function(){var k=Array.prototype.slice.call(arguments,0),m=k[0].toLowerCase(),n=this,l=g,p=n.events[m],s,o,r;if(n.eventsSuspended===g){if(o=n.eventQueue){o.push(k)}}else{if(typeof p=="object"){if(p.bubble){if(p.fire.apply(p,k.slice(1))===i){return i}r=n.getBubbleTarget&&n.getBubbleTarget();if(r&&r.enableBubble){s=r.events[m];if(!s||typeof s!="object"||!s.bubble){r.enableBubble(m)}return r.fireEvent.apply(r,k)}}else{k.shift();l=p.fire.apply(p,k)}}}return l},addListener:function(m,q,s,l){var p=this,n,t,r,k;if(typeof m=="object"){l=m;for(n in l){t=l[n];if(!p.filterOptRe.test(n)){p.addListener(n,t.fn||t,t.scope||l.scope,t.fn?t:l)}}}else{m=m.toLowerCase();k=p.events[m]||g;if(typeof k=="boolean"){p.events[m]=k=new h.Event(p,m)}k.addListener(q,s,typeof l=="object"?l:{})}},removeListener:function(k,m,l){var n=this.events[k.toLowerCase()];if(typeof n=="object"){n.removeListener(m,l)}},purgeListeners:function(){var m=this.events,k,l;for(l in m){k=m[l];if(typeof k=="object"){k.clearListeners()}}},addEvents:function(n){var m=this;m.events=m.events||{};if(typeof n=="string"){var k=arguments,l=k.length;while(l--){m.events[k[l]]=m.events[k[l]]||g}}else{Ext.applyIf(m.events,n)}},hasListener:function(k){var l=this.events[k.toLowerCase()];return typeof l=="object"&&l.listeners.length>0},suspendEvents:function(k){this.eventsSuspended=g;if(k&&!this.eventQueue){this.eventQueue=[]}},resumeEvents:function(){var k=this,l=k.eventQueue||[];k.eventsSuspended=i;delete k.eventQueue;j(l,function(m){k.fireEvent.apply(k,m)})}};var d=h.Observable.prototype;d.on=d.addListener;d.un=d.removeListener;h.Observable.releaseCapture=function(k){k.fireEvent=d.fireEvent};function e(l,m,k){return function(){if(m.target==arguments[0]){l.apply(k,Array.prototype.slice.call(arguments,0))}}}function b(n,p,k,m){k.task=new h.DelayedTask();return function(){k.task.delay(p.buffer,n,m,Array.prototype.slice.call(arguments,0))}}function c(m,n,l,k){return function(){n.removeListener(l,k);return m.apply(k,arguments)}}function a(n,p,k,m){return function(){var l=new h.DelayedTask();if(!k.tasks){k.tasks=[]}k.tasks.push(l);l.delay(p.delay||10,n,m,Array.prototype.slice.call(arguments,0))}}h.Event=function(l,k){this.name=k;this.obj=l;this.listeners=[]};h.Event.prototype={addListener:function(o,n,m){var p=this,k;n=n||p.obj;if(!p.isListening(o,n)){k=p.createListener(o,n,m);if(p.firing){p.listeners=p.listeners.slice(0)}p.listeners.push(k)}},createListener:function(p,n,q){q=q||{},n=n||this.obj;var k={fn:p,scope:n,options:q},m=p;if(q.target){m=e(m,q,n)}if(q.delay){m=a(m,q,k,n)}if(q.single){m=c(m,this,p,n)}if(q.buffer){m=b(m,q,k,n)}k.fireFn=m;return k},findListener:function(o,n){var p=this.listeners,m=p.length,k;n=n||this.obj;while(m--){k=p[m];if(k){if(k.fn==o&&k.scope==n){return m}}}return -1},isListening:function(l,k){return this.findListener(l,k)!=-1},removeListener:function(r,q){var p,m,n,s=this,o=i;if((p=s.findListener(r,q))!=-1){if(s.firing){s.listeners=s.listeners.slice(0)}m=s.listeners[p];if(m.task){m.task.cancel();delete m.task}n=m.tasks&&m.tasks.length;if(n){while(n--){m.tasks[n].cancel()}delete m.tasks}s.listeners.splice(p,1);o=g}return o},clearListeners:function(){var n=this,k=n.listeners,m=k.length;while(m--){n.removeListener(k[m].fn,k[m].scope)}},fire:function(){var q=this,p=q.listeners,k=p.length,o=0,m;if(k>0){q.firing=g;var n=Array.prototype.slice.call(arguments,0);for(;o=525:!((Ext.isGecko&&!Ext.isWindows)||Ext.isOpera);return{doResizeEvent:function(){var l=a.getViewHeight(),k=a.getViewWidth();if(g!=l||h!=k){c.fire(h=k,g=l)}},onWindowResize:function(m,l,k){if(!c){c=new Ext.util.Event();j=new Ext.util.DelayedTask(this.doResizeEvent);Ext.EventManager.on(window,"resize",this.fireWindowResize,this)}c.addListener(m,l,k)},fireWindowResize:function(){if(c){j.delay(100)}},onTextResize:function(n,m,k){if(!e){e=new Ext.util.Event();var l=new Ext.Element(document.createElement("div"));l.dom.className="x-text-resize";l.dom.innerHTML="X";l.appendTo(document.body);b=l.dom.offsetHeight;setInterval(function(){if(l.dom.offsetHeight!=b){e.fire(b,b=l.dom.offsetHeight)}},this.textResizeInterval)}e.addListener(n,m,k)},removeResizeListener:function(l,k){if(c){c.removeListener(l,k)}},fireResize:function(){if(c){c.fire(a.getViewWidth(),a.getViewHeight())}},textResizeInterval:50,ieDeferSrc:false,useKeydown:d}}());Ext.EventManager.on=Ext.EventManager.addListener;Ext.apply(Ext.EventObjectImpl.prototype,{BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,RETURN:13,SHIFT:16,CTRL:17,CONTROL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGEUP:33,PAGE_DOWN:34,PAGEDOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,isNavKeyPress:function(){var b=this,a=this.normalizeKey(b.keyCode);return(a>=33&&a<=40)||a==b.RETURN||a==b.TAB||a==b.ESC},isSpecialKey:function(){var a=this.normalizeKey(this.keyCode);return(this.type=="keypress"&&this.ctrlKey)||this.isNavKeyPress()||(a==this.BACKSPACE)||(a>=16&&a<=20)||(a>=44&&a<=46)},getPoint:function(){return new Ext.lib.Point(this.xy[0],this.xy[1])},hasModifier:function(){return((this.ctrlKey||this.altKey)||this.shiftKey)}});(function(){var j=document;Ext.Element=function(o,p){var q=typeof o=="string"?j.getElementById(o):o,r;if(!q){return null}r=q.id;if(!p&&r&&Ext.elCache[r]){return Ext.elCache[r].el}this.dom=q;this.id=r||Ext.id(q)};var a=Ext.lib.Dom,g=Ext.DomHelper,m=Ext.lib.Event,e=Ext.lib.Anim,h=Ext.Element,b=Ext.elCache;h.prototype={set:function(t,q){var r=this.dom,p,s,q=(q!==false)&&!!r.setAttribute;for(p in t){if(t.hasOwnProperty(p)){s=t[p];if(p=="style"){g.applyStyles(r,s)}else{if(p=="cls"){r.className=s}else{if(q){r.setAttribute(p,s)}else{r[p]=s}}}}}return this},defaultUnit:"px",is:function(o){return Ext.DomQuery.is(this.dom,o)},focus:function(r,q){var o=this,q=q||o.dom;try{if(Number(r)){o.focus.defer(r,null,[null,q])}else{q.focus()}}catch(p){}return o},blur:function(){try{this.dom.blur()}catch(o){}return this},getValue:function(o){var p=this.dom.value;return o?parseInt(p,10):p},addListener:function(o,r,q,p){Ext.EventManager.on(this.dom,o,r,q||this,p);return this},removeListener:function(o,q,p){Ext.EventManager.removeListener(this.dom,o,q,p||this);return this},removeAllListeners:function(){Ext.EventManager.removeAll(this.dom);return this},purgeAllListeners:function(){Ext.EventManager.purgeElement(this,true);return this},addUnits:function(o){if(o===""||o=="auto"||o===undefined){o=o||""}else{if(!isNaN(o)||!k.test(o)){o=o+(this.defaultUnit||"px")}}return o},load:function(p,q,o){Ext.Ajax.request(Ext.apply({params:q,url:p.url||p,callback:o,el:this.dom,indicatorText:p.indicatorText||""},Ext.isObject(p)?p:{}));return this},isBorderBox:function(){return i[(this.dom.tagName||"").toLowerCase()]||Ext.isBorderBox},remove:function(){var o=this,p=o.dom;if(p){delete o.dom;Ext.removeNode(p)}},hover:function(p,o,r,q){var s=this;s.on("mouseenter",p,r||s.dom,q);s.on("mouseleave",o,r||s.dom,q);return s},contains:function(o){return !o?false:Ext.lib.Dom.isAncestor(this.dom,o.dom?o.dom:o)},getAttributeNS:function(p,o){return this.getAttribute(o,p)},getAttribute:Ext.isIE?function(o,q){var r=this.dom,p=typeof r[q+":"+o];if(["undefined","unknown"].indexOf(p)==-1){return r[q+":"+o]}return r[o]}:function(o,p){var q=this.dom;return q.getAttributeNS(p,o)||q.getAttribute(p+":"+o)||q.getAttribute(o)||q[o]},update:function(o){if(this.dom){this.dom.innerHTML=o}return this}};var n=h.prototype;h.addMethods=function(p){Ext.apply(n,p)};n.on=n.addListener;n.un=n.removeListener;n.autoBoxAdjust=true;var k=/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,d;h.get=function(p){var o,s,r;if(!p){return null}if(typeof p=="string"){if(!(s=j.getElementById(p))){return null}if(b[p]&&b[p].el){o=b[p].el;o.dom=s}else{o=h.addToCache(new h(s))}return o}else{if(p.tagName){if(!(r=p.id)){r=Ext.id(p)}if(b[r]&&b[r].el){o=b[r].el;o.dom=p}else{o=h.addToCache(new h(p))}return o}else{if(p instanceof h){if(p!=d){if(Ext.isIE&&(p.id==undefined||p.id=="")){p.dom=p.dom}else{p.dom=j.getElementById(p.id)||p.dom}}return p}else{if(p.isComposite){return p}else{if(Ext.isArray(p)){return h.select(p)}else{if(p==j){if(!d){var q=function(){};q.prototype=h.prototype;d=new q();d.dom=j}return d}}}}}}return null};h.addToCache=function(o,p){p=p||o.id;b[p]={el:o,data:{},events:{}};return o};h.data=function(p,o,q){p=h.get(p);if(!p){return null}var r=b[p.id].data;if(arguments.length==2){return r[o]}else{return(r[o]=q)}};function l(){if(!Ext.enableGarbageCollector){clearInterval(h.collectorThreadId)}else{var p,r,u,s;for(p in b){s=b[p];if(s.skipGC){continue}r=s.el;u=r.dom;if(!u||!u.parentNode||(!u.offsetParent&&!j.getElementById(p))){if(Ext.enableListenerCollection){Ext.EventManager.removeAll(u)}delete b[p]}}if(Ext.isIE){var q={};for(p in b){q[p]=b[p]}b=Ext.elCache=q}}}h.collectorThreadId=setInterval(l,30000);var c=function(){};c.prototype=h.prototype;h.Flyweight=function(o){this.dom=o};h.Flyweight.prototype=new c();h.Flyweight.prototype.isFlyweight=true;h._flyweights={};h.fly=function(q,o){var p=null;o=o||"_global";if(q=Ext.getDom(q)){(h._flyweights[o]=h._flyweights[o]||new h.Flyweight()).dom=q;p=h._flyweights[o]}return p};Ext.get=h.get;Ext.fly=h.fly;var i=Ext.isStrict?{select:1}:{input:1,select:1,textarea:1};if(Ext.isIE||Ext.isGecko){i.button=1}})();Ext.Element.addMethods({swallowEvent:function(a,b){var d=this;function c(g){g.stopPropagation();if(b){g.preventDefault()}}if(Ext.isArray(a)){Ext.each(a,function(g){d.on(g,c)});return d}d.on(a,c);return d},relayEvent:function(a,b){this.on(a,function(c){b.fireEvent(a,c)})},clean:function(b){var d=this,e=d.dom,g=e.firstChild,c=-1;if(Ext.Element.data(e,"isCleaned")&&b!==true){return d}while(g){var a=g.nextSibling;if(g.nodeType==3&&!/\S/.test(g.nodeValue)){e.removeChild(g)}else{g.nodeIndex=++c}g=a}Ext.Element.data(e,"isCleaned",true);return d},load:function(){var a=this.getUpdater();a.update.apply(a,arguments);return this},getUpdater:function(){return this.updateManager||(this.updateManager=new Ext.Updater(this))},update:function(html,loadScripts,callback){if(!this.dom){return this}html=html||"";if(loadScripts!==true){this.dom.innerHTML=html;if(typeof callback=="function"){callback()}return this}var id=Ext.id(),dom=this.dom;html+='';Ext.lib.Event.onAvailable(id,function(){var DOC=document,hd=DOC.getElementsByTagName("head")[0],re=/(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,srcRe=/\ssrc=([\'\"])(.*?)\1/i,typeRe=/\stype=([\'\"])(.*?)\1/i,match,attrs,srcMatch,typeMatch,el,s;while((match=re.exec(html))){attrs=match[1];srcMatch=attrs?attrs.match(srcRe):false;if(srcMatch&&srcMatch[2]){s=DOC.createElement("script");s.src=srcMatch[2];typeMatch=attrs.match(typeRe);if(typeMatch&&typeMatch[2]){s.type=typeMatch[2]}hd.appendChild(s)}else{if(match[2]&&match[2].length>0){if(window.execScript){window.execScript(match[2])}else{window.eval(match[2])}}}}el=DOC.getElementById(id);if(el){Ext.removeNode(el)}if(typeof callback=="function"){callback()}});dom.innerHTML=html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig,"");return this},removeAllListeners:function(){this.removeAnchor();Ext.EventManager.removeAll(this.dom);return this},createProxy:function(a,e,d){a=(typeof a=="object")?a:{tag:"div",cls:a};var c=this,b=e?Ext.DomHelper.append(e,a,true):Ext.DomHelper.insertBefore(c.dom,a,true);if(d&&c.setBox&&c.getBox){b.setBox(c.getBox())}return b}});Ext.Element.prototype.getUpdateManager=Ext.Element.prototype.getUpdater;Ext.Element.addMethods({getAnchorXY:function(e,l,q){e=(e||"tl").toLowerCase();q=q||{};var k=this,b=k.dom==document.body||k.dom==document,n=q.width||b?Ext.lib.Dom.getViewWidth():k.getWidth(),i=q.height||b?Ext.lib.Dom.getViewHeight():k.getHeight(),p,a=Math.round,c=k.getXY(),m=k.getScroll(),j=b?m.left:!l?c[0]:0,g=b?m.top:!l?c[1]:0,d={c:[a(n*0.5),a(i*0.5)],t:[a(n*0.5),0],l:[0,a(i*0.5)],r:[n,a(i*0.5)],b:[a(n*0.5),i],tl:[0,0],bl:[0,i],br:[n,i],tr:[n,0]};p=d[e];return[p[0]+j,p[1]+g]},anchorTo:function(b,h,c,a,k,l){var i=this,e=i.dom,j=!Ext.isEmpty(k),d=function(){Ext.fly(e).alignTo(b,h,c,a);Ext.callback(l,Ext.fly(e))},g=this.getAnchor();this.removeAnchor();Ext.apply(g,{fn:d,scroll:j});Ext.EventManager.onWindowResize(d,null);if(j){Ext.EventManager.on(window,"scroll",d,null,{buffer:!isNaN(k)?k:50})}d.call(i);return i},removeAnchor:function(){var b=this,a=this.getAnchor();if(a&&a.fn){Ext.EventManager.removeResizeListener(a.fn);if(a.scroll){Ext.EventManager.un(window,"scroll",a.fn)}delete a.fn}return b},getAnchor:function(){var b=Ext.Element.data,c=this.dom;if(!c){return}var a=b(c,"_anchor");if(!a){a=b(c,"_anchor",{})}return a},getAlignToXY:function(g,A,B){g=Ext.get(g);if(!g||!g.dom){throw"Element.alignToXY with an element that doesn't exist"}B=B||[0,0];A=(!A||A=="?"?"tl-bl?":(!/-/.test(A)&&A!==""?"tl-"+A:A||"tl-bl")).toLowerCase();var K=this,H=K.dom,M,L,n,l,s,F,v,t=Ext.lib.Dom.getViewWidth()-10,G=Ext.lib.Dom.getViewHeight()-10,b,i,j,k,u,z,N=document,J=N.documentElement,q=N.body,E=(J.scrollLeft||q.scrollLeft||0)+5,D=(J.scrollTop||q.scrollTop||0)+5,I=false,e="",a="",C=A.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!C){throw"Element.alignTo with an invalid alignment "+A}e=C[1];a=C[2];I=!!C[3];M=K.getAnchorXY(e,true);L=g.getAnchorXY(a,false);n=L[0]-M[0]+B[0];l=L[1]-M[1]+B[1];if(I){s=K.getWidth();F=K.getHeight();v=g.getRegion();b=e.charAt(0);i=e.charAt(e.length-1);j=a.charAt(0);k=a.charAt(a.length-1);u=((b=="t"&&j=="b")||(b=="b"&&j=="t"));z=((i=="r"&&k=="l")||(i=="l"&&k=="r"));if(n+s>t+E){n=z?v.left-s:t+E-s}if(nG+D){l=u?v.top-F:G+D-F}if(lA){o=A-p;l=true}if((n+B)>g){n=g-B;l=true}if(o "+g,this.dom);return h?i:a(i)},parent:function(g,h){return this.matchNode(d,d,g,h)},next:function(g,h){return this.matchNode(b,b,g,h)},prev:function(g,h){return this.matchNode(c,c,g,h)},first:function(g,h){return this.matchNode(b,"firstChild",g,h)},last:function(g,h){return this.matchNode(c,"lastChild",g,h)},matchNode:function(h,k,g,i){var j=this.dom[k];while(j){if(j.nodeType==1&&(!g||e.is(j,g))){return !i?a(j):j}j=j[h]}return null}}}());Ext.Element.addMethods({select:function(a,b){return Ext.Element.select(a,b,this.dom)}});Ext.Element.addMethods(function(){var c=Ext.getDom,a=Ext.get,b=Ext.DomHelper;return{appendChild:function(d){return a(d).appendTo(this)},appendTo:function(d){c(d).appendChild(this.dom);return this},insertBefore:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d);return this},insertAfter:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d.nextSibling);return this},insertFirst:function(e,d){e=e||{};if(e.nodeType||e.dom||typeof e=="string"){e=c(e);this.dom.insertBefore(e,this.dom.firstChild);return !d?a(e):e}else{return this.createChild(e,this.dom.firstChild,d)}},replace:function(d){d=a(d);this.insertBefore(d);d.remove();return this},replaceWith:function(d){var e=this;if(d.nodeType||d.dom||typeof d=="string"){d=c(d);e.dom.parentNode.insertBefore(d,e.dom)}else{d=b.insertBefore(e.dom,d)}delete Ext.elCache[e.id];Ext.removeNode(e.dom);e.id=Ext.id(e.dom=d);Ext.Element.addToCache(e.isFlyweight?new Ext.Element(e.dom):e);return e},createChild:function(e,d,g){e=e||{tag:"div"};return d?b.insertBefore(d,e,g!==true):b[!this.dom.firstChild?"overwrite":"append"](this.dom,e,g!==true)},wrap:function(d,e){var g=b.insertBefore(this.dom,d||{tag:"div"},!e);g.dom?g.dom.appendChild(this.dom):g.appendChild(this.dom);return g},insertHtml:function(e,g,d){var h=b.insertHtml(e,this.dom,g);return d?Ext.get(h):h}}}());Ext.apply(Ext.Element.prototype,function(){var c=Ext.getDom,a=Ext.get,b=Ext.DomHelper;return{insertSibling:function(i,g,h){var j=this,e,d=(g||"before").toLowerCase()=="after",k;if(Ext.isArray(i)){k=j;Ext.each(i,function(l){e=Ext.fly(k,"_internal").insertSibling(l,g,h);if(d){k=e}});return e}i=i||{};if(i.nodeType||i.dom){e=j.dom.parentNode.insertBefore(c(i),d?j.dom.nextSibling:j.dom);if(!h){e=a(e)}}else{if(d&&!j.dom.nextSibling){e=b.append(j.dom.parentNode,i,!h)}else{e=b[d?"insertAfter":"insertBefore"](j.dom,i,!h)}}return e}}}());Ext.Element.addMethods(function(){var i={},z=/(-[a-z])/gi,c={},t=document.defaultView,w=Ext.isIE?"styleFloat":"cssFloat",E=/alpha\(opacity=(.*)\)/i,m=/^\s+|\s+$/g,v=/\s+/,b=/\w/g,C=Ext.Element,e="padding",d="margin",A="border",u="-left",r="-right",y="-top",p="-bottom",k="-width",s=Math,B="hidden",g="isClipped",l="overflow",o="overflow-x",n="overflow-y",D="originalClip",j={l:A+u+k,r:A+r+k,t:A+y+k,b:A+p+k},h={l:e+u,r:e+r,t:e+y,b:e+p},a={l:d+u,r:d+r,t:d+y,b:d+p},F=Ext.Element.data;function q(G,H){return H.charAt(1).toUpperCase()}function x(G){return i[G]||(i[G]=G=="float"?w:G.replace(z,q))}return{adjustWidth:function(G){var H=this;var I=(typeof G=="number");if(I&&H.autoBoxAdjust&&!H.isBorderBox()){G-=(H.getBorderWidth("lr")+H.getPadding("lr"))}return(I&&G<0)?0:G},adjustHeight:function(G){var H=this;var I=(typeof G=="number");if(I&&H.autoBoxAdjust&&!H.isBorderBox()){G-=(H.getBorderWidth("tb")+H.getPadding("tb"))}return(I&&G<0)?0:G},addClass:function(K){var L=this,J,G,I,H=[];if(!Ext.isArray(K)){if(typeof K=="string"&&!this.hasClass(K)){L.dom.className+=" "+K}}else{for(J=0,G=K.length;J5?I.toLowerCase():H)},setStyle:function(K,J){var H,I,G;if(typeof K!="object"){H={};H[K]=J;K=H}for(I in K){J=K[I];I=="opacity"?this.setOpacity(J):this.dom.style[x(I)]=J}return this},setOpacity:function(H,G){var K=this,I=K.dom.style;if(!G||!K.anim){if(Ext.isIE){var J=H<1?"alpha(opacity="+H*100+")":"",L=I.filter.replace(E,"").replace(m,"");I.zoom=1;I.filter=L+(L.length>0?" ":"")+J}else{I.opacity=H}}else{K.anim({opacity:{to:H}},K.preanim(arguments,1),null,0.35,"easeIn")}return K},clearOpacity:function(){var G=this.dom.style;if(Ext.isIE){if(!Ext.isEmpty(G.filter)){G.filter=G.filter.replace(E,"").replace(m,"")}}else{G.opacity=G["-moz-opacity"]=G["-khtml-opacity"]=""}return this},getHeight:function(I){var H=this,K=H.dom,J=Ext.isIE&&H.isStyle("display","none"),G=s.max(K.offsetHeight,J?0:K.clientHeight)||0;G=!I?G:G-H.getBorderWidth("tb")-H.getPadding("tb");return G<0?0:G},getWidth:function(H){var I=this,K=I.dom,J=Ext.isIE&&I.isStyle("display","none"),G=s.max(K.offsetWidth,J?0:K.clientWidth)||0;G=!H?G:G-I.getBorderWidth("lr")-I.getPadding("lr");return G<0?0:G},setWidth:function(H,G){var I=this;H=I.adjustWidth(H);!G||!I.anim?I.dom.style.width=I.addUnits(H):I.anim({width:{to:H}},I.preanim(arguments,1));return I},setHeight:function(G,H){var I=this;G=I.adjustHeight(G);!H||!I.anim?I.dom.style.height=I.addUnits(G):I.anim({height:{to:G}},I.preanim(arguments,1));return I},getBorderWidth:function(G){return this.addStyles(G,j)},getPadding:function(G){return this.addStyles(G,h)},clip:function(){var G=this,H=G.dom;if(!F(H,g)){F(H,g,true);F(H,D,{o:G.getStyle(l),x:G.getStyle(o),y:G.getStyle(n)});G.setStyle(l,B);G.setStyle(o,B);G.setStyle(n,B)}return G},unclip:function(){var G=this,I=G.dom;if(F(I,g)){F(I,g,false);var H=F(I,D);if(H.o){G.setStyle(l,H.o)}if(H.x){G.setStyle(o,H.x)}if(H.y){G.setStyle(n,H.y)}}return G},addStyles:function(N,M){var K=0,L=N.match(b),J,I,H,G=L.length;for(H=0;H"+String.format(Ext.Element.boxMarkup,c)+""));Ext.DomQuery.selectNode("."+c+"-mc",d.dom).appendChild(this.dom);return d},setSize:function(e,c,d){var g=this;if(typeof e=="object"){c=e.height;e=e.width}e=g.adjustWidth(e);c=g.adjustHeight(c);if(!d||!g.anim){g.dom.style.width=g.addUnits(e);g.dom.style.height=g.addUnits(c)}else{g.anim({width:{to:e},height:{to:c}},g.preanim(arguments,2))}return g},getComputedHeight:function(){var d=this,c=Math.max(d.dom.offsetHeight,d.dom.clientHeight);if(!c){c=parseFloat(d.getStyle("height"))||0;if(!d.isBorderBox()){c+=d.getFrameWidth("tb")}}return c},getComputedWidth:function(){var c=Math.max(this.dom.offsetWidth,this.dom.clientWidth);if(!c){c=parseFloat(this.getStyle("width"))||0;if(!this.isBorderBox()){c+=this.getFrameWidth("lr")}}return c},getFrameWidth:function(d,c){return c&&this.isBorderBox()?0:(this.getPadding(d)+this.getBorderWidth(d))},addClassOnOver:function(c){this.hover(function(){Ext.fly(this,a).addClass(c)},function(){Ext.fly(this,a).removeClass(c)});return this},addClassOnFocus:function(c){this.on("focus",function(){Ext.fly(this,a).addClass(c)},this.dom);this.on("blur",function(){Ext.fly(this,a).removeClass(c)},this.dom);return this},addClassOnClick:function(c){var d=this.dom;this.on("mousedown",function(){Ext.fly(d,a).addClass(c);var g=Ext.getDoc(),e=function(){Ext.fly(d,a).removeClass(c);g.removeListener("mouseup",e)};g.on("mouseup",e)});return this},getViewSize:function(){var g=document,h=this.dom,c=(h==g||h==g.body);if(c){var e=Ext.lib.Dom;return{width:e.getViewWidth(),height:e.getViewHeight()}}else{return{width:h.clientWidth,height:h.clientHeight}}},getStyleSize:function(){var j=this,c,i,l=document,m=this.dom,e=(m==l||m==l.body),g=m.style;if(e){var k=Ext.lib.Dom;return{width:k.getViewWidth(),height:k.getViewHeight()}}if(g.width&&g.width!="auto"){c=parseFloat(g.width);if(j.isBorderBox()){c-=j.getFrameWidth("lr")}}if(g.height&&g.height!="auto"){i=parseFloat(g.height);if(j.isBorderBox()){i-=j.getFrameWidth("tb")}}return{width:c||j.getWidth(true),height:i||j.getHeight(true)}},getSize:function(c){return{width:this.getWidth(c),height:this.getHeight(c)}},repaint:function(){var c=this.dom;this.addClass("x-repaint");setTimeout(function(){Ext.fly(c).removeClass("x-repaint")},1);return this},unselectable:function(){this.dom.unselectable="on";return this.swallowEvent("selectstart",true).applyStyles("-moz-user-select:none;-khtml-user-select:none;").addClass("x-unselectable")},getMargins:function(d){var e=this,c,g={t:"top",l:"left",r:"right",b:"bottom"},h={};if(!d){for(c in e.margins){h[g[c]]=parseFloat(e.getStyle(e.margins[c]))||0}return h}else{return e.addStyles.call(e,d,e.margins)}}}}());(function(){var a=Ext.lib.Dom,b="left",g="right",d="top",i="bottom",h="position",c="static",e="relative",j="auto",k="z-index";Ext.Element.addMethods({getX:function(){return a.getX(this.dom)},getY:function(){return a.getY(this.dom)},getXY:function(){return a.getXY(this.dom)},getOffsetsTo:function(l){var n=this.getXY(),m=Ext.fly(l,"_internal").getXY();return[n[0]-m[0],n[1]-m[1]]},setX:function(l,m){return this.setXY([l,this.getY()],this.animTest(arguments,m,1))},setY:function(m,l){return this.setXY([this.getX(),m],this.animTest(arguments,l,1))},setLeft:function(l){this.setStyle(b,this.addUnits(l));return this},setTop:function(l){this.setStyle(d,this.addUnits(l));return this},setRight:function(l){this.setStyle(g,this.addUnits(l));return this},setBottom:function(l){this.setStyle(i,this.addUnits(l));return this},setXY:function(n,l){var m=this;if(!l||!m.anim){a.setXY(m.dom,n)}else{m.anim({points:{to:n}},m.preanim(arguments,1),"motion")}return m},setLocation:function(l,n,m){return this.setXY([l,n],this.animTest(arguments,m,2))},moveTo:function(l,n,m){return this.setXY([l,n],this.animTest(arguments,m,2))},getLeft:function(l){return !l?this.getX():parseInt(this.getStyle(b),10)||0},getRight:function(l){var m=this;return !l?m.getX()+m.getWidth():(m.getLeft(true)+m.getWidth())||0},getTop:function(l){return !l?this.getY():parseInt(this.getStyle(d),10)||0},getBottom:function(l){var m=this;return !l?m.getY()+m.getHeight():(m.getTop(true)+m.getHeight())||0},position:function(p,o,l,n){var m=this;if(!p&&m.isStyle(h,c)){m.setStyle(h,e)}else{if(p){m.setStyle(h,p)}}if(o){m.setStyle(k,o)}if(l||n){m.setXY([l||false,n||false])}},clearPositioning:function(l){l=l||"";this.setStyle({left:l,right:l,top:l,bottom:l,"z-index":"",position:c});return this},getPositioning:function(){var m=this.getStyle(b);var n=this.getStyle(d);return{position:this.getStyle(h),left:m,right:m?"":this.getStyle(g),top:n,bottom:n?"":this.getStyle(i),"z-index":this.getStyle(k)}},setPositioning:function(l){var n=this,m=n.dom.style;n.setStyle(l);if(l.right==j){m.right=""}if(l.bottom==j){m.bottom=""}return n},translatePoints:function(m,u){u=isNaN(m[1])?u:m[1];m=isNaN(m[0])?m:m[0];var q=this,r=q.isStyle(h,e),s=q.getXY(),n=parseInt(q.getStyle(b),10),p=parseInt(q.getStyle(d),10);n=!isNaN(n)?n:(r?0:q.dom.offsetLeft);p=!isNaN(p)?p:(r?0:q.dom.offsetTop);return{left:(m-s[0]+n),top:(u-s[1]+p)}},animTest:function(m,l,n){return !!l&&this.preanim?this.preanim(m,n):false}})})();Ext.Element.addMethods({setBox:function(e,g,b){var d=this,a=e.width,c=e.height;if((g&&!d.autoBoxAdjust)&&!d.isBorderBox()){a-=(d.getBorderWidth("lr")+d.getPadding("lr"));c-=(d.getBorderWidth("tb")+d.getPadding("tb"))}d.setBounds(e.x,e.y,a,c,d.animTest.call(d,arguments,b,2));return d},getBox:function(j,p){var m=this,v,e,o,d=m.getBorderWidth,q=m.getPadding,g,a,u,n;if(!p){v=m.getXY()}else{e=parseInt(m.getStyle("left"),10)||0;o=parseInt(m.getStyle("top"),10)||0;v=[e,o]}var c=m.dom,s=c.offsetWidth,i=c.offsetHeight,k;if(!j){k={x:v[0],y:v[1],0:v[0],1:v[1],width:s,height:i}}else{g=d.call(m,"l")+q.call(m,"l");a=d.call(m,"r")+q.call(m,"r");u=d.call(m,"t")+q.call(m,"t");n=d.call(m,"b")+q.call(m,"b");k={x:v[0]+g,y:v[1]+u,0:v[0]+g,1:v[1]+u,width:s-(g+a),height:i-(u+n)}}k.right=k.x+k.width;k.bottom=k.y+k.height;return k},move:function(j,b,c){var g=this,m=g.getXY(),k=m[0],i=m[1],d=[k-b,i],l=[k+b,i],h=[k,i-b],a=[k,i+b],e={l:d,left:d,r:l,right:l,t:h,top:h,up:h,b:a,bottom:a,down:a};j=j.toLowerCase();g.moveTo(e[j][0],e[j][1],g.animTest.call(g,arguments,c,2))},setLeftTop:function(d,c){var b=this,a=b.dom.style;a.left=b.addUnits(d);a.top=b.addUnits(c);return b},getRegion:function(){return Ext.lib.Dom.getRegion(this.dom)},setBounds:function(b,g,d,a,c){var e=this;if(!c||!e.anim){e.setSize(d,a);e.setLocation(b,g)}else{e.anim({points:{to:[b,g]},width:{to:e.adjustWidth(d)},height:{to:e.adjustHeight(a)}},e.preanim(arguments,4),"motion")}return e},setRegion:function(b,a){return this.setBounds(b.left,b.top,b.right-b.left,b.bottom-b.top,this.animTest.call(this,arguments,a,1))}});Ext.Element.addMethods({isScrollable:function(){var a=this.dom;return a.scrollHeight>a.clientHeight||a.scrollWidth>a.clientWidth},scrollTo:function(a,b){this.dom["scroll"+(/top/i.test(a)?"Top":"Left")]=b;return this},getScroll:function(){var i=this.dom,h=document,a=h.body,c=h.documentElement,b,g,e;if(i==h||i==a){if(Ext.isIE&&Ext.isStrict){b=c.scrollLeft;g=c.scrollTop}else{b=window.pageXOffset;g=window.pageYOffset}e={left:b||(a?a.scrollLeft:0),top:g||(a?a.scrollTop:0)}}else{e={left:i.scrollLeft,top:i.scrollTop}}return e}});Ext.Element.addMethods({scrollTo:function(b,d,a){var e=/top/i.test(b),c=this,g=c.dom,h;if(!a||!c.anim){h="scroll"+(e?"Top":"Left"),g[h]=d}else{h="scroll"+(e?"Left":"Top"),c.anim({scroll:{to:e?[g[h],d]:[d,g[h]]}},c.preanim(arguments,2),"scroll")}return c},scrollIntoView:function(e,i){var p=Ext.getDom(e)||Ext.getBody().dom,h=this.dom,g=this.getOffsetsTo(p),k=g[0]+p.scrollLeft,u=g[1]+p.scrollTop,q=u+h.offsetHeight,d=k+h.offsetWidth,a=p.clientHeight,m=parseInt(p.scrollTop,10),s=parseInt(p.scrollLeft,10),j=m+a,n=s+p.clientWidth;if(h.offsetHeight>a||uj){p.scrollTop=q-a}}p.scrollTop=p.scrollTop;if(i!==false){if(h.offsetWidth>p.clientWidth||kn){p.scrollLeft=d-p.clientWidth}}p.scrollLeft=p.scrollLeft}return this},scrollChildIntoView:function(b,a){Ext.fly(b,"_scrollChildIntoView").scrollIntoView(this,a)},scroll:function(m,b,d){if(!this.isScrollable()){return}var e=this.dom,g=e.scrollLeft,p=e.scrollTop,n=e.scrollWidth,k=e.scrollHeight,i=e.clientWidth,a=e.clientHeight,c=false,o,j={l:Math.min(g+b,n-i),r:o=Math.max(g-b,0),t:Math.max(p-b,0),b:Math.min(p+b,k-a)};j.d=j.b;j.u=j.t;m=m.substr(0,1);if((o=j[m])>-1){c=true;this.scrollTo(m=="l"||m=="r"?"left":"top",o,this.preanim(arguments,2))}return c}});Ext.Element.VISIBILITY=1;Ext.Element.DISPLAY=2;Ext.Element.addMethods(function(){var h="visibility",d="display",b="hidden",k="offsets",j="none",a="originalDisplay",c="visibilityMode",e=Ext.Element.DISPLAY,g=Ext.Element.data,i=function(n){var m=g(n,a);if(m===undefined){g(n,a,m="")}return m},l=function(o){var n=g(o,c);if(n===undefined){g(o,c,n=1)}return n};return{originalDisplay:"",visibilityMode:1,setVisibilityMode:function(m){g(this.dom,c,m);return this},animate:function(n,p,o,q,m){this.anim(n,{duration:p,callback:o,easing:q},m);return this},anim:function(p,q,n,s,o,m){n=n||"run";q=q||{};var r=this,t=Ext.lib.Anim[n](r.dom,p,(q.duration||s)||0.35,(q.easing||o)||"easeOut",function(){if(m){m.call(r)}if(q.callback){q.callback.call(q.scope||r,r,q)}},r);q.anim=t;return t},preanim:function(m,n){return !m[n]?false:(typeof m[n]=="object"?m[n]:{duration:m[n+1],callback:m[n+2],easing:m[n+3]})},isVisible:function(){return !this.isStyle(h,b)&&!this.isStyle(d,j)},setVisible:function(r,o){var p=this,n,m,s,q=p.dom;if(typeof o=="string"){n=o==d;m=o==h;s=o==k;o=false}else{n=l(this.dom)==e;m=!n}if(!o||!p.anim){if(n){p.setDisplayed(r)}else{if(s){if(!r){p.hideModeStyles={position:p.getStyle("position"),top:p.getStyle("top"),left:p.getStyle("left")};p.applyStyles({position:"absolute",top:"-10000px",left:"-10000px"})}else{p.applyStyles(p.hideModeStyles||{position:"",top:"",left:""})}}else{p.fixDisplay();q.style.visibility=r?"visible":b}}}else{if(r){p.setOpacity(0.01);p.setVisible(true)}p.anim({opacity:{to:(r?1:0)}},p.preanim(arguments,1),null,0.35,"easeIn",function(){if(!r){q.style[n?d:h]=(n)?j:b;Ext.fly(q).setOpacity(1)}})}return p},toggle:function(m){var n=this;n.setVisible(!n.isVisible(),n.preanim(arguments,0));return n},setDisplayed:function(m){if(typeof m=="boolean"){m=m?i(this.dom):j}this.setStyle(d,m);return this},fixDisplay:function(){var m=this;if(m.isStyle(d,j)){m.setStyle(h,b);m.setStyle(d,i(this.dom));if(m.isStyle(d,j)){m.setStyle(d,"block")}}},hide:function(m){if(typeof m=="string"){this.setVisible(false,m);return this}this.setVisible(false,this.preanim(arguments,0));return this},show:function(m){if(typeof m=="string"){this.setVisible(true,m);return this}this.setVisible(true,this.preanim(arguments,0));return this}}}());Ext.Element.addMethods(function(){var d="visibility",b="display",a="hidden",h="none",c="x-masked",g="x-masked-relative",e=Ext.Element.data;return{isVisible:function(i){var j=!this.isStyle(d,a)&&!this.isStyle(b,h),k=this.dom.parentNode;if(i!==true||!j){return j}while(k&&!/^body/i.test(k.tagName)){if(!Ext.fly(k,"_isVisible").isVisible()){return false}k=k.parentNode}return true},isDisplayed:function(){return !this.isStyle(b,h)},enableDisplayMode:function(i){this.setVisibilityMode(Ext.Element.DISPLAY);if(!Ext.isEmpty(i)){e(this.dom,"originalDisplay",i)}return this},mask:function(j,n){var p=this,l=p.dom,o=Ext.DomHelper,m="ext-el-mask-msg",i,q;if(!/^body/i.test(l.tagName)&&p.getStyle("position")=="static"){p.addClass(g)}if((i=e(l,"maskMsg"))){i.remove()}if((i=e(l,"mask"))){i.remove()}q=o.append(l,{cls:"ext-el-mask"},true);e(l,"mask",q);p.addClass(c);q.setDisplayed(true);if(typeof j=="string"){var k=o.append(l,{cls:m,cn:{tag:"div"}},true);e(l,"maskMsg",k);k.dom.className=n?m+" "+n:m;k.dom.firstChild.innerHTML=j;k.setDisplayed(true);k.center(p)}if(Ext.isIE&&!(Ext.isIE7&&Ext.isStrict)&&p.getStyle("height")=="auto"){q.setSize(undefined,p.getHeight())}return q},unmask:function(){var k=this,l=k.dom,i=e(l,"mask"),j=e(l,"maskMsg");if(i){if(j){j.remove();e(l,"maskMsg",undefined)}i.remove();e(l,"mask",undefined)}k.removeClass([c,g])},isMasked:function(){var i=e(this.dom,"mask");return i&&i.isVisible()},createShim:function(){var i=document.createElement("iframe"),j;i.frameBorder="0";i.className="ext-shim";i.src=Ext.SSL_SECURE_URL;j=Ext.get(this.dom.parentNode.insertBefore(i,this.dom));j.autoBoxAdjust=false;return j}}}());Ext.Element.addMethods({addKeyListener:function(b,d,c){var a;if(typeof b!="object"||Ext.isArray(b)){a={key:b,fn:d,scope:c}}else{a={key:b.key,shift:b.shift,ctrl:b.ctrl,alt:b.alt,fn:d,scope:c}}return new Ext.KeyMap(this,a)},addKeyMap:function(a){return new Ext.KeyMap(this,a)}});(function(){var y=null,A=undefined,k=true,t=false,j="setX",h="setY",a="setXY",n="left",l="bottom",s="top",m="right",q="height",g="width",i="points",w="hidden",z="absolute",u="visible",e="motion",o="position",r="easeOut",d=new Ext.Element.Flyweight(),v={},x=function(B){return B||{}},p=function(B){d.dom=B;d.id=Ext.id(B);return d},c=function(B){if(!v[B]){v[B]=[]}return v[B]},b=function(C,B){v[C]=B};Ext.enableFx=k;Ext.Fx={switchStatements:function(C,D,B){return D.apply(this,B[C])},slideIn:function(H,E){E=x(E);var J=this,G=J.dom,M=G.style,O,B,L,D,C,M,I,N,K,F;H=H||"t";J.queueFx(E,function(){O=p(G).getXY();p(G).fixDisplay();B=p(G).getFxRestore();L={x:O[0],y:O[1],0:O[0],1:O[1],width:G.offsetWidth,height:G.offsetHeight};L.right=L.x+L.width;L.bottom=L.y+L.height;p(G).setWidth(L.width).setHeight(L.height);D=p(G).fxWrap(B.pos,E,w);M.visibility=u;M.position=z;function P(){p(G).fxUnwrap(D,B.pos,E);M.width=B.width;M.height=B.height;p(G).afterFx(E)}N={to:[L.x,L.y]};K={to:L.width};F={to:L.height};function Q(U,R,V,S,X,Z,ac,ab,aa,W,T){var Y={};p(U).setWidth(V).setHeight(S);if(p(U)[X]){p(U)[X](Z)}R[ac]=R[ab]="0";if(aa){Y.width=aa}if(W){Y.height=W}if(T){Y.points=T}return Y}I=p(G).switchStatements(H.toLowerCase(),Q,{t:[D,M,L.width,0,y,y,n,l,y,F,y],l:[D,M,0,L.height,y,y,m,s,K,y,y],r:[D,M,L.width,L.height,j,L.right,n,s,y,y,N],b:[D,M,L.width,L.height,h,L.bottom,n,s,y,F,N],tl:[D,M,0,0,y,y,m,l,K,F,N],bl:[D,M,0,0,h,L.y+L.height,m,s,K,F,N],br:[D,M,0,0,a,[L.right,L.bottom],n,s,K,F,N],tr:[D,M,0,0,j,L.x+L.width,n,l,K,F,N]});M.visibility=u;p(D).show();arguments.callee.anim=p(D).fxanim(I,E,e,0.5,r,P)});return J},slideOut:function(F,D){D=x(D);var H=this,E=H.dom,K=E.style,L=H.getXY(),C,B,I,J,G={to:0};F=F||"t";H.queueFx(D,function(){B=p(E).getFxRestore();I={x:L[0],y:L[1],0:L[0],1:L[1],width:E.offsetWidth,height:E.offsetHeight};I.right=I.x+I.width;I.bottom=I.y+I.height;p(E).setWidth(I.width).setHeight(I.height);C=p(E).fxWrap(B.pos,D,u);K.visibility=u;K.position=z;p(C).setWidth(I.width).setHeight(I.height);function M(){D.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).fxUnwrap(C,B.pos,D);K.width=B.width;K.height=B.height;p(E).afterFx(D)}function N(O,W,U,X,S,V,R,T,Q){var P={};O[W]=O[U]="0";P[X]=S;if(V){P[V]=R}if(T){P[T]=Q}return P}J=p(E).switchStatements(F.toLowerCase(),N,{t:[K,n,l,q,G],l:[K,m,s,g,G],r:[K,n,s,g,G,i,{to:[I.right,I.y]}],b:[K,n,s,q,G,i,{to:[I.x,I.bottom]}],tl:[K,m,l,g,G,q,G],bl:[K,m,s,g,G,q,G,i,{to:[I.x,I.bottom]}],br:[K,n,s,g,G,q,G,i,{to:[I.x+I.width,I.bottom]}],tr:[K,n,l,g,G,q,G,i,{to:[I.right,I.y]}]});arguments.callee.anim=p(C).fxanim(J,D,e,0.5,r,M)});return H},puff:function(H){H=x(H);var F=this,G=F.dom,C=G.style,D,B,E;F.queueFx(H,function(){D=p(G).getWidth();B=p(G).getHeight();p(G).clearOpacity();p(G).show();E=p(G).getFxRestore();function I(){H.useDisplay?p(G).setDisplayed(t):p(G).hide();p(G).clearOpacity();p(G).setPositioning(E.pos);C.width=E.width;C.height=E.height;C.fontSize="";p(G).afterFx(H)}arguments.callee.anim=p(G).fxanim({width:{to:p(G).adjustWidth(D*2)},height:{to:p(G).adjustHeight(B*2)},points:{by:[-D*0.5,-B*0.5]},opacity:{to:0},fontSize:{to:200,unit:"%"}},H,e,0.5,r,I)});return F},switchOff:function(F){F=x(F);var D=this,E=D.dom,B=E.style,C;D.queueFx(F,function(){p(E).clearOpacity();p(E).clip();C=p(E).getFxRestore();function G(){F.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).clearOpacity();p(E).setPositioning(C.pos);B.width=C.width;B.height=C.height;p(E).afterFx(F)}p(E).fxanim({opacity:{to:0.3}},y,y,0.1,y,function(){p(E).clearOpacity();(function(){p(E).fxanim({height:{to:1},points:{by:[0,p(E).getHeight()*0.5]}},F,e,0.3,"easeIn",G)}).defer(100)})});return D},highlight:function(D,H){H=x(H);var F=this,G=F.dom,B=H.attr||"backgroundColor",C={},E;F.queueFx(H,function(){p(G).clearOpacity();p(G).show();function I(){G.style[B]=E;p(G).afterFx(H)}E=G.style[B];C[B]={from:D||"ffff9c",to:H.endColor||p(G).getColor(B)||"ffffff"};arguments.callee.anim=p(G).fxanim(C,H,"color",1,"easeIn",I)});return F},frame:function(B,E,H){H=x(H);var D=this,G=D.dom,C,F;D.queueFx(H,function(){B=B||"#C3DAF9";if(B.length==6){B="#"+B}E=E||1;p(G).show();var L=p(G).getXY(),J={x:L[0],y:L[1],0:L[0],1:L[1],width:G.offsetWidth,height:G.offsetHeight},I=function(){C=p(document.body||document.documentElement).createChild({style:{position:z,"z-index":35000,border:"0px solid "+B}});return C.queueFx({},K)};arguments.callee.anim={isAnimated:true,stop:function(){E=0;C.stopFx()}};function K(){var M=Ext.isBorderBox?2:1;F=C.anim({top:{from:J.y,to:J.y-20},left:{from:J.x,to:J.x-20},borderWidth:{from:0,to:10},opacity:{from:1,to:0},height:{from:J.height,to:J.height+20*M},width:{from:J.width,to:J.width+20*M}},{duration:H.duration||1,callback:function(){C.remove();--E>0?I():p(G).afterFx(H)}});arguments.callee.anim={isAnimated:true,stop:function(){F.stop()}}}I()});return D},pause:function(D){var C=this.dom,B;this.queueFx({},function(){B=setTimeout(function(){p(C).afterFx({})},D*1000);arguments.callee.anim={isAnimated:true,stop:function(){clearTimeout(B);p(C).afterFx({})}}});return this},fadeIn:function(D){D=x(D);var B=this,C=B.dom,E=D.endOpacity||1;B.queueFx(D,function(){p(C).setOpacity(0);p(C).fixDisplay();C.style.visibility=u;arguments.callee.anim=p(C).fxanim({opacity:{to:E}},D,y,0.5,r,function(){if(E==1){p(C).clearOpacity()}p(C).afterFx(D)})});return B},fadeOut:function(E){E=x(E);var C=this,D=C.dom,B=D.style,F=E.endOpacity||0;C.queueFx(E,function(){arguments.callee.anim=p(D).fxanim({opacity:{to:F}},E,y,0.5,r,function(){if(F==0){Ext.Element.data(D,"visibilityMode")==Ext.Element.DISPLAY||E.useDisplay?B.display="none":B.visibility=w;p(D).clearOpacity()}p(D).afterFx(E)})});return C},scale:function(B,C,D){this.shift(Ext.apply({},D,{width:B,height:C}));return this},shift:function(D){D=x(D);var C=this.dom,B={};this.queueFx(D,function(){for(var E in D){if(D[E]!=A){B[E]={to:D[E]}}}B.width?B.width.to=p(C).adjustWidth(D.width):B;B.height?B.height.to=p(C).adjustWidth(D.height):B;if(B.x||B.y||B.xy){B.points=B.xy||{to:[B.x?B.x.to:p(C).getX(),B.y?B.y.to:p(C).getY()]}}arguments.callee.anim=p(C).fxanim(B,D,e,0.35,r,function(){p(C).afterFx(D)})});return this},ghost:function(E,C){C=x(C);var G=this,D=G.dom,J=D.style,H={opacity:{to:0},points:{}},K=H.points,B,I,F;E=E||"b";G.queueFx(C,function(){B=p(D).getFxRestore();I=p(D).getWidth();F=p(D).getHeight();function L(){C.useDisplay?p(D).setDisplayed(t):p(D).hide();p(D).clearOpacity();p(D).setPositioning(B.pos);J.width=B.width;J.height=B.height;p(D).afterFx(C)}K.by=p(D).switchStatements(E.toLowerCase(),function(N,M){return[N,M]},{t:[0,-F],l:[-I,0],r:[I,0],b:[0,F],tl:[-I,-F],bl:[-I,F],br:[I,F],tr:[I,-F]});arguments.callee.anim=p(D).fxanim(H,C,e,0.5,r,L)});return G},syncFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:k,stopFx:t});return B},sequenceFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:t,stopFx:t});return B},nextFx:function(){var B=c(this.dom.id)[0];if(B){B.call(this)}},hasActiveFx:function(){return c(this.dom.id)[0]},stopFx:function(B){var C=this,E=C.dom.id;if(C.hasActiveFx()){var D=c(E)[0];if(D&&D.anim){if(D.anim.isAnimated){b(E,[D]);D.anim.stop(B!==undefined?B:k)}else{b(E,[])}}}return C},beforeFx:function(B){if(this.hasActiveFx()&&!B.concurrent){if(B.stopFx){this.stopFx();return k}return t}return k},hasFxBlock:function(){var B=c(this.dom.id);return B&&B[0]&&B[0].block},queueFx:function(E,B){var C=p(this.dom);if(!C.hasFxBlock()){Ext.applyIf(E,C.fxDefaults);if(!E.concurrent){var D=C.beforeFx(E);B.block=E.block;c(C.dom.id).push(B);if(D){C.nextFx()}}else{B.call(C)}}return C},fxWrap:function(H,F,D){var E=this.dom,C,B;if(!F.wrap||!(C=Ext.getDom(F.wrap))){if(F.fixPosition){B=p(E).getXY()}var G=document.createElement("div");G.style.visibility=D;C=E.parentNode.insertBefore(G,E);p(C).setPositioning(H);if(p(C).isStyle(o,"static")){p(C).position("relative")}p(E).clearPositioning("auto");p(C).clip();C.appendChild(E);if(B){p(C).setXY(B)}}return C},fxUnwrap:function(C,F,E){var D=this.dom;p(D).clearPositioning();p(D).setPositioning(F);if(!E.wrap){var B=p(C).dom.parentNode;B.insertBefore(D,C);p(C).remove()}},getFxRestore:function(){var B=this.dom.style;return{pos:this.getPositioning(),width:B.width,height:B.height}},afterFx:function(C){var B=this.dom,D=B.id;if(C.afterStyle){p(B).setStyle(C.afterStyle)}if(C.afterCls){p(B).addClass(C.afterCls)}if(C.remove==k){p(B).remove()}if(C.callback){C.callback.call(C.scope,p(B))}if(!C.concurrent){c(D).shift();p(B).nextFx()}},fxanim:function(E,F,C,G,D,B){C=C||"run";F=F||{};var H=Ext.lib.Anim[C](this.dom,E,(F.duration||G)||0.35,(F.easing||D)||r,B,this);F.anim=H;return H}};Ext.Fx.resize=Ext.Fx.scale;Ext.Element.addMethods(Ext.Fx)})();Ext.CompositeElementLite=function(b,a){this.elements=[];this.add(b,a);this.el=new Ext.Element.Flyweight()};Ext.CompositeElementLite.prototype={isComposite:true,getElement:function(a){var b=this.el;b.dom=a;b.id=a.id;return b},transformElement:function(a){return Ext.getDom(a)},getCount:function(){return this.elements.length},add:function(d,b){var e=this,g=e.elements;if(!d){return this}if(typeof d=="string"){d=Ext.Element.selectorFunction(d,b)}else{if(d.isComposite){d=d.elements}else{if(!Ext.isIterable(d)){d=[d]}}}for(var c=0,a=d.length;c-1){c=Ext.getDom(c);if(a){g=this.elements[b];g.parentNode.insertBefore(c,g);Ext.removeNode(g)}this.elements.splice(b,1,c)}return this},clear:function(){this.elements=[]}};Ext.CompositeElementLite.prototype.on=Ext.CompositeElementLite.prototype.addListener;(function(){var c,b=Ext.Element.prototype,a=Ext.CompositeElementLite.prototype;for(c in b){if(Ext.isFunction(b[c])){(function(d){a[d]=a[d]||function(){return this.invoke(d,arguments)}}).call(a,c)}}})();if(Ext.DomQuery){Ext.Element.selectorFunction=Ext.DomQuery.select}Ext.Element.select=function(a,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;Ext.apply(Ext.CompositeElementLite.prototype,{addElements:function(c,a){if(!c){return this}if(typeof c=="string"){c=Ext.Element.selectorFunction(c,a)}var b=this.elements;Ext.each(c,function(d){b.push(Ext.get(d))});return this},first:function(){return this.item(0)},last:function(){return this.item(this.getCount()-1)},contains:function(a){return this.indexOf(a)!=-1},removeElement:function(d,e){var c=this,a=this.elements,b;Ext.each(d,function(g){if((b=(a[g]||a[g=c.indexOf(g)]))){if(e){if(b.dom){b.remove()}else{Ext.removeNode(b)}}a.splice(g,1)}});return this}});Ext.CompositeElement=Ext.extend(Ext.CompositeElementLite,{constructor:function(b,a){this.elements=[];this.add(b,a)},getElement:function(a){return a},transformElement:function(a){return Ext.get(a)}});Ext.Element.select=function(a,d,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return(d===true)?new Ext.CompositeElement(c):new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;(function(){var b="beforerequest",e="requestcomplete",d="requestexception",h=undefined,c="load",i="POST",a="GET",g=window;Ext.data.Connection=function(j){Ext.apply(this,j);this.addEvents(b,e,d);Ext.data.Connection.superclass.constructor.call(this)};Ext.extend(Ext.data.Connection,Ext.util.Observable,{timeout:30000,autoAbort:false,disableCaching:true,disableCachingParam:"_dc",request:function(n){var s=this;if(s.fireEvent(b,s,n)){if(n.el){if(!Ext.isEmpty(n.indicatorText)){s.indicatorText='
'+n.indicatorText+"
"}if(s.indicatorText){Ext.getDom(n.el).innerHTML=s.indicatorText}n.success=(Ext.isFunction(n.success)?n.success:function(){}).createInterceptor(function(o){Ext.getDom(n.el).innerHTML=o.responseText})}var l=n.params,k=n.url||s.url,j,q={success:s.handleResponse,failure:s.handleFailure,scope:s,argument:{options:n},timeout:n.timeout||s.timeout},m,t;if(Ext.isFunction(l)){l=l.call(n.scope||g,n)}l=Ext.urlEncode(s.extraParams,Ext.isObject(l)?Ext.urlEncode(l):l);if(Ext.isFunction(k)){k=k.call(n.scope||g,n)}if((m=Ext.getDom(n.form))){k=k||m.action;if(n.isUpload||/multipart\/form-data/i.test(m.getAttribute("enctype"))){return s.doFormUpload.call(s,n,l,k)}t=Ext.lib.Ajax.serializeForm(m);l=l?(l+"&"+t):t}j=n.method||s.method||((l||n.xmlData||n.jsonData)?i:a);if(j===a&&(s.disableCaching&&n.disableCaching!==false)||n.disableCaching===true){var r=n.disableCachingParam||s.disableCachingParam;k=Ext.urlAppend(k,r+"="+(new Date().getTime()))}n.headers=Ext.apply(n.headers||{},s.defaultHeaders||{});if(n.autoAbort===true||s.autoAbort){s.abort()}if((j==a||n.xmlData||n.jsonData)&&l){k=Ext.urlAppend(k,l);l=""}return(s.transId=Ext.lib.Ajax.request(j,k,q,l,n))}else{return n.callback?n.callback.apply(n.scope,[n,h,h]):null}},isLoading:function(j){return j?Ext.lib.Ajax.isCallInProgress(j):!!this.transId},abort:function(j){if(j||this.isLoading()){Ext.lib.Ajax.abort(j||this.transId)}},handleResponse:function(j){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(e,this,j,k);if(k.success){k.success.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,true,j)}},handleFailure:function(j,l){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(d,this,j,k,l);if(k.failure){k.failure.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,false,j)}},doFormUpload:function(q,j,k){var l=Ext.id(),v=document,r=v.createElement("iframe"),m=Ext.getDom(q.form),u=[],t,p="multipart/form-data",n={target:m.target,method:m.method,encoding:m.encoding,enctype:m.enctype,action:m.action};Ext.fly(r).set({id:l,name:l,cls:"x-hidden",src:Ext.SSL_SECURE_URL});v.body.appendChild(r);if(Ext.isIE){document.frames[l].name=l}Ext.fly(m).set({target:l,method:i,enctype:p,encoding:p,action:k||n.action});Ext.iterate(Ext.urlDecode(j,false),function(w,o){t=v.createElement("input");Ext.fly(t).set({type:"hidden",value:o,name:w});m.appendChild(t);u.push(t)});function s(){var x=this,w={responseText:"",responseXML:null,argument:q.argument},A,z;try{A=r.contentWindow.document||r.contentDocument||g.frames[l].document;if(A){if(A.body){if(/textarea/i.test((z=A.body.firstChild||{}).tagName)){w.responseText=z.value}else{w.responseText=A.body.innerHTML}}w.responseXML=A.XMLDocument||A}}catch(y){}Ext.EventManager.removeListener(r,c,s,x);x.fireEvent(e,x,w,q);function o(D,C,B){if(Ext.isFunction(D)){D.apply(C,B)}}o(q.success,q.scope,[w,q]);o(q.callback,q.scope,[q,true,w]);if(!x.debugUploads){setTimeout(function(){Ext.removeNode(r)},100)}}Ext.EventManager.on(r,c,s,this);m.submit();Ext.fly(m).set(n);Ext.each(u,function(o){Ext.removeNode(o)})}})})();Ext.Ajax=new Ext.data.Connection({autoAbort:false,serializeForm:function(a){return Ext.lib.Ajax.serializeForm(a)}});Ext.UpdateManager=Ext.Updater=Ext.extend(Ext.util.Observable,function(){var b="beforeupdate",d="update",c="failure";function a(h){var i=this;i.transaction=null;if(h.argument.form&&h.argument.reset){try{h.argument.form.reset()}catch(j){}}if(i.loadScripts){i.renderer.render(i.el,h,i,g.createDelegate(i,[h]))}else{i.renderer.render(i.el,h,i);g.call(i,h)}}function g(h,i,j){this.fireEvent(i||d,this.el,h);if(Ext.isFunction(h.argument.callback)){h.argument.callback.call(h.argument.scope,this.el,Ext.isEmpty(j)?true:false,h,h.argument.options)}}function e(h){g.call(this,h,c,!!(this.transaction=null))}return{constructor:function(i,h){var j=this;i=Ext.get(i);if(!h&&i.updateManager){return i.updateManager}j.el=i;j.defaultUrl=null;j.addEvents(b,d,c);Ext.apply(j,Ext.Updater.defaults);j.transaction=null;j.refreshDelegate=j.refresh.createDelegate(j);j.updateDelegate=j.update.createDelegate(j);j.formUpdateDelegate=(j.formUpdate||function(){}).createDelegate(j);j.renderer=j.renderer||j.getDefaultRenderer();Ext.Updater.superclass.constructor.call(j)},setRenderer:function(h){this.renderer=h},getRenderer:function(){return this.renderer},getDefaultRenderer:function(){return new Ext.Updater.BasicRenderer()},setDefaultUrl:function(h){this.defaultUrl=h},getEl:function(){return this.el},update:function(i,n,p,l){var k=this,h,j;if(k.fireEvent(b,k.el,i,n)!==false){if(Ext.isObject(i)){h=i;i=h.url;n=n||h.params;p=p||h.callback;l=l||h.discardUrl;j=h.scope;if(!Ext.isEmpty(h.nocache)){k.disableCaching=h.nocache}if(!Ext.isEmpty(h.text)){k.indicatorText='
'+h.text+"
"}if(!Ext.isEmpty(h.scripts)){k.loadScripts=h.scripts}if(!Ext.isEmpty(h.timeout)){k.timeout=h.timeout}}k.showLoading();if(!l){k.defaultUrl=i}if(Ext.isFunction(i)){i=i.call(k)}var m=Ext.apply({},{url:i,params:(Ext.isFunction(n)&&j)?n.createDelegate(j):n,success:a,failure:e,scope:k,callback:undefined,timeout:(k.timeout*1000),disableCaching:k.disableCaching,argument:{options:h,url:i,form:null,callback:p,scope:j||window,params:n}},h);k.transaction=Ext.Ajax.request(m)}},formUpdate:function(k,h,j,l){var i=this;if(i.fireEvent(b,i.el,k,h)!==false){if(Ext.isFunction(h)){h=h.call(i)}k=Ext.getDom(k);i.transaction=Ext.Ajax.request({form:k,url:h,success:a,failure:e,scope:i,timeout:(i.timeout*1000),argument:{url:h,form:k,callback:l,reset:j}});i.showLoading.defer(1,i)}},startAutoRefresh:function(i,j,l,m,h){var k=this;if(h){k.update(j||k.defaultUrl,l,m,true)}if(k.autoRefreshProcId){clearInterval(k.autoRefreshProcId)}k.autoRefreshProcId=setInterval(k.update.createDelegate(k,[j||k.defaultUrl,l,m,true]),i*1000)},stopAutoRefresh:function(){if(this.autoRefreshProcId){clearInterval(this.autoRefreshProcId);delete this.autoRefreshProcId}},isAutoRefreshing:function(){return !!this.autoRefreshProcId},showLoading:function(){if(this.showLoadIndicator){this.el.dom.innerHTML=this.indicatorText}},abort:function(){if(this.transaction){Ext.Ajax.abort(this.transaction)}},isUpdating:function(){return this.transaction?Ext.Ajax.isLoading(this.transaction):false},refresh:function(h){if(this.defaultUrl){this.update(this.defaultUrl,null,h,true)}}}}());Ext.Updater.defaults={timeout:30,disableCaching:false,showLoadIndicator:true,indicatorText:'
Loading...
',loadScripts:false,sslBlankUrl:Ext.SSL_SECURE_URL};Ext.Updater.updateElement=function(d,c,e,b){var a=Ext.get(d).getUpdater();Ext.apply(a,b);a.update(c,e,b?b.callback:null)};Ext.Updater.BasicRenderer=function(){};Ext.Updater.BasicRenderer.prototype={render:function(c,a,b,d){c.update(a.responseText,b.loadScripts,d)}};(function(){Date.useStrict=false;function b(d){var c=Array.prototype.slice.call(arguments,1);return d.replace(/\{(\d+)\}/g,function(e,g){return c[g]})}Date.formatCodeToRegex=function(d,c){var e=Date.parseCodes[d];if(e){e=typeof e=="function"?e():e;Date.parseCodes[d]=e}return e?Ext.applyIf({c:e.c?b(e.c,c||"{0}"):e.c},e):{g:0,c:null,s:Ext.escapeRe(d)}};var a=Date.formatCodeToRegex;Ext.apply(Date,{parseFunctions:{"M$":function(d,c){var e=new RegExp("\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/");var g=(d||"").match(e);return g?new Date(((g[1]||"")+g[2])*1):null}},parseRegexes:[],formatFunctions:{"M$":function(){return"\\/Date("+this.getTime()+")\\/"}},y2kYear:50,MILLI:"ms",SECOND:"s",MINUTE:"mi",HOUR:"h",DAY:"d",MONTH:"mo",YEAR:"y",defaults:{},dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNumbers:{Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11},getShortMonthName:function(c){return Date.monthNames[c].substring(0,3)},getShortDayName:function(c){return Date.dayNames[c].substring(0,3)},getMonthNumber:function(c){return Date.monthNumbers[c.substring(0,1).toUpperCase()+c.substring(1,3).toLowerCase()]},formatCodes:{d:"String.leftPad(this.getDate(), 2, '0')",D:"Date.getShortDayName(this.getDay())",j:"this.getDate()",l:"Date.dayNames[this.getDay()]",N:"(this.getDay() ? this.getDay() : 7)",S:"this.getSuffix()",w:"this.getDay()",z:"this.getDayOfYear()",W:"String.leftPad(this.getWeekOfYear(), 2, '0')",F:"Date.monthNames[this.getMonth()]",m:"String.leftPad(this.getMonth() + 1, 2, '0')",M:"Date.getShortMonthName(this.getMonth())",n:"(this.getMonth() + 1)",t:"this.getDaysInMonth()",L:"(this.isLeapYear() ? 1 : 0)",o:"(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",Y:"this.getFullYear()",y:"('' + this.getFullYear()).substring(2, 4)",a:"(this.getHours() < 12 ? 'am' : 'pm')",A:"(this.getHours() < 12 ? 'AM' : 'PM')",g:"((this.getHours() % 12) ? this.getHours() % 12 : 12)",G:"this.getHours()",h:"String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",H:"String.leftPad(this.getHours(), 2, '0')",i:"String.leftPad(this.getMinutes(), 2, '0')",s:"String.leftPad(this.getSeconds(), 2, '0')",u:"String.leftPad(this.getMilliseconds(), 3, '0')",O:"this.getGMTOffset()",P:"this.getGMTOffset(true)",T:"this.getTimezone()",Z:"(this.getTimezoneOffset() * -60)",c:function(){for(var k="Y-m-dTH:i:sP",h=[],g=0,d=k.length;g= 0 && y >= 0){","v = new Date(y, 0, 1, h, i, s, ms);","v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);","}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){","v = null;","}else{","v = new Date(y, m, d, h, i, s, ms);","}","}","}","if(v){","if(zz != null){","v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);","}else if(o){","v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));","}","}","return v;"].join("\n");return function(m){var e=Date.parseRegexes.length,n=1,g=[],l=[],k=false,d="";for(var j=0;j Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"},a:{g:1,c:"if (results[{0}] == 'am') {\nif (!h || h == 12) { h = 0; }\n} else { if (!h || h < 12) { h = (h || 0) + 12; }}",s:"(am|pm)"},A:{g:1,c:"if (results[{0}] == 'AM') {\nif (!h || h == 12) { h = 0; }\n} else { if (!h || h < 12) { h = (h || 0) + 12; }}",s:"(AM|PM)"},g:function(){return a("G")},G:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{1,2})"},h:function(){return a("H")},H:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},i:{g:1,c:"i = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},s:{g:1,c:"s = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},u:{g:1,c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",s:"(\\d+)"},O:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),","mn = o.substring(3,5) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{4})"},P:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),","mn = o.substring(4,6) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{2}:\\d{2})"},T:{g:0,c:null,s:"[A-Z]{1,4}"},Z:{g:1,c:"zz = results[{0}] * 1;\nzz = (-43200 <= zz && zz <= 50400)? zz : null;\n",s:"([+-]?\\d{1,5})"},c:function(){var e=[],c=[a("Y",1),a("m",2),a("d",3),a("h",4),a("i",5),a("s",6),{c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},{c:["if(results[8]) {","if(results[8] == 'Z'){","zz = 0;","}else if (results[8].indexOf(':') > -1){",a("P",8).c,"}else{",a("O",8).c,"}","}"].join("\n")}];for(var g=0,d=c.length;g0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+(a?":":"")+String.leftPad(Math.abs(this.getTimezoneOffset()%60),2,"0")},getDayOfYear:function(){var b=0,e=this.clone(),a=this.getMonth(),c;for(c=0,e.setDate(1),e.setMonth(0);c28){a=Math.min(a,this.getFirstDateOfMonth().add("mo",c).getLastDateOfMonth().getDate())}e.setDate(a);e.setMonth(this.getMonth()+c);break;case Date.YEAR:e.setFullYear(this.getFullYear()+c);break}return e},between:function(c,a){var b=this.getTime();return c.getTime()<=b&&b<=a.getTime()}});Date.prototype.format=Date.prototype.dateFormat;if(Ext.isSafari&&(navigator.userAgent.match(/WebKit\/(\d+)/)[1]||NaN)<420){Ext.apply(Date.prototype,{_xMonth:Date.prototype.setMonth,_xDate:Date.prototype.setDate,setMonth:function(a){if(a<=-1){var d=Math.ceil(-a),c=Math.ceil(d/12),b=(d%12)?12-d%12:0;this.setFullYear(this.getFullYear()-c);return this._xMonth(b)}else{return this._xMonth(a)}},setDate:function(a){return this.setTime(this.getTime()-(this.getDate()-a)*86400000)}})}Ext.util.MixedCollection=function(b,a){this.items=[];this.map={};this.keys=[];this.length=0;this.addEvents("clear","add","replace","remove","sort");this.allowFunctions=b===true;if(a){this.getKey=a}Ext.util.MixedCollection.superclass.constructor.call(this)};Ext.extend(Ext.util.MixedCollection,Ext.util.Observable,{allowFunctions:false,add:function(b,c){if(arguments.length==1){c=arguments[0];b=this.getKey(c)}if(typeof b!="undefined"&&b!==null){var a=this.map[b];if(typeof a!="undefined"){return this.replace(b,c)}this.map[b]=c}this.length++;this.items.push(c);this.keys.push(b);this.fireEvent("add",this.length-1,c,b);return c},getKey:function(a){return a.id},replace:function(c,d){if(arguments.length==1){d=arguments[0];c=this.getKey(d)}var a=this.map[c];if(typeof c=="undefined"||c===null||typeof a=="undefined"){return this.add(c,d)}var b=this.indexOfKey(c);this.items[b]=d;this.map[c]=d;this.fireEvent("replace",c,a,d);return d},addAll:function(e){if(arguments.length>1||Ext.isArray(e)){var b=arguments.length>1?arguments:e;for(var d=0,a=b.length;d=this.length){return this.add(b,c)}this.length++;this.items.splice(a,0,c);if(typeof b!="undefined"&&b!==null){this.map[b]=c}this.keys.splice(a,0,b);this.fireEvent("add",a,c,b);return c},remove:function(a){return this.removeAt(this.indexOf(a))},removeAt:function(a){if(a=0){this.length--;var c=this.items[a];this.items.splice(a,1);var b=this.keys[a];if(typeof b!="undefined"){delete this.map[b]}this.keys.splice(a,1);this.fireEvent("remove",c,b);return c}return false},removeKey:function(a){return this.removeAt(this.indexOfKey(a))},getCount:function(){return this.length},indexOf:function(a){return this.items.indexOf(a)},indexOfKey:function(a){return this.keys.indexOf(a)},item:function(b){var a=this.map[b],c=a!==undefined?a:(typeof b=="number")?this.items[b]:undefined;return typeof c!="function"||this.allowFunctions?c:null},itemAt:function(a){return this.items[a]},key:function(a){return this.map[a]},contains:function(a){return this.indexOf(a)!=-1},containsKey:function(a){return typeof this.map[a]!="undefined"},clear:function(){this.length=0;this.items=[];this.keys=[];this.map={};this.fireEvent("clear")},first:function(){return this.items[0]},last:function(){return this.items[this.length-1]},_sort:function(k,a,j){var d,e,b=String(a).toUpperCase()=="DESC"?-1:1,h=[],l=this.keys,g=this.items;j=j||function(i,c){return i-c};for(d=0,e=g.length;de?1:(g=a;c--){d[d.length]=b[c]}}return d},filter:function(c,b,d,a){if(Ext.isEmpty(b,false)){return this.clone()}b=this.createValueMatcher(b,d,a);return this.filterBy(function(e){return e&&b.test(e[c])})},filterBy:function(g,e){var h=new Ext.util.MixedCollection();h.getKey=this.getKey;var b=this.keys,d=this.items;for(var c=0,a=d.length;c]+>/gi,stripScriptsRe=/(?:)((\n|\r|.)*?)(?:<\/script>)/ig,nl2brRe=/\r?\n/g;return{ellipsis:function(value,len,word){if(value&&value.length>len){if(word){var vs=value.substr(0,len-2),index=Math.max(vs.lastIndexOf(" "),vs.lastIndexOf("."),vs.lastIndexOf("!"),vs.lastIndexOf("?"));if(index==-1||index<(len-15)){return value.substr(0,len-3)+"..."}else{return vs.substr(0,index)+"..."}}else{return value.substr(0,len-3)+"..."}}return value},undef:function(value){return value!==undefined?value:""},defaultValue:function(value,defaultValue){return value!==undefined&&value!==""?value:defaultValue},htmlEncode:function(value){return !value?value:String(value).replace(/&/g,"&").replace(/>/g,">").replace(/").replace(/</g,"<").replace(/"/g,'"').replace(/&/g,"&")},trim:function(value){return String(value).replace(trimRe,"")},substr:function(value,start,length){return String(value).substr(start,length)},lowercase:function(value){return String(value).toLowerCase()},uppercase:function(value){return String(value).toUpperCase()},capitalize:function(value){return !value?value:value.charAt(0).toUpperCase()+value.substr(1).toLowerCase()},call:function(value,fn){if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);args.unshift(value);return eval(fn).apply(window,args)}else{return eval(fn).call(window,value)}},usMoney:function(v){v=(Math.round((v-0)*100))/100;v=(v==Math.floor(v))?v+".00":((v*10==Math.floor(v*10))?v+"0":v);v=String(v);var ps=v.split("."),whole=ps[0],sub=ps[1]?"."+ps[1]:".00",r=/(\d+)(\d{3})/;while(r.test(whole)){whole=whole.replace(r,"$1,$2")}v=whole+sub;if(v.charAt(0)=="-"){return"-$"+v.substr(1)}return"$"+v},date:function(v,format){if(!v){return""}if(!Ext.isDate(v)){v=new Date(Date.parse(v))}return v.dateFormat(format||"m/d/Y")},dateRenderer:function(format){return function(v){return Ext.util.Format.date(v,format)}},stripTags:function(v){return !v?v:String(v).replace(stripTagsRE,"")},stripScripts:function(v){return !v?v:String(v).replace(stripScriptsRe,"")},fileSize:function(size){if(size<1024){return size+" bytes"}else{if(size<1048576){return(Math.round(((size*10)/1024))/10)+" KB"}else{return(Math.round(((size*10)/1048576))/10)+" MB"}}},math:function(){var fns={};return function(v,a){if(!fns[a]){fns[a]=new Function("v","return v "+a+";")}return fns[a](v)}}(),round:function(value,precision){var result=Number(value);if(typeof precision=="number"){precision=Math.pow(10,precision);result=Math.round(value*precision)/precision}return result},number:function(v,format){if(!format){return v}v=Ext.num(v,NaN);if(isNaN(v)){return""}var comma=",",dec=".",i18n=false,neg=v<0;v=Math.abs(v);if(format.substr(format.length-2)=="/i"){format=format.substr(0,format.length-2);i18n=true;comma=".";dec=","}var hasComma=format.indexOf(comma)!=-1,psplit=(i18n?format.replace(/[^\d\,]/g,""):format.replace(/[^\d\.]/g,"")).split(dec);if(1")}}}();Ext.XTemplate=function(){Ext.XTemplate.superclass.constructor.apply(this,arguments);var y=this,j=y.html,q=/]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,d=/^]*?for="(.*?)"/,v=/^]*?if="(.*?)"/,x=/^]*?exec="(.*?)"/,r,p=0,k=[],o="values",w="parent",l="xindex",n="xcount",e="return ",c="with(values){ ";j=["",j,""].join("");while((r=j.match(q))){var b=r[0].match(d),a=r[0].match(v),A=r[0].match(x),g=null,h=null,t=null,z=b&&b[1]?b[1]:"";if(a){g=a&&a[1]?a[1]:null;if(g){h=new Function(o,w,l,n,c+e+(Ext.util.Format.htmlDecode(g))+"; }")}}if(A){g=A&&A[1]?A[1]:null;if(g){t=new Function(o,w,l,n,c+(Ext.util.Format.htmlDecode(g))+"; }")}}if(z){switch(z){case".":z=new Function(o,w,c+e+o+"; }");break;case"..":z=new Function(o,w,c+e+w+"; }");break;default:z=new Function(o,w,c+e+z+"; }")}}k.push({id:p,target:z,exec:t,test:h,body:r[1]||""});j=j.replace(r[0],"{xtpl"+p+"}");++p}for(var u=k.length-1;u>=0;--u){y.compileTpl(k[u])}y.master=k[k.length-1];y.tpls=k};Ext.extend(Ext.XTemplate,Ext.Template,{re:/\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,codeRe:/\{\[((?:\\\]|.|\n)*?)\]\}/g,applySubTemplate:function(a,k,j,d,c){var h=this,g,m=h.tpls[a],l,b=[];if((m.test&&!m.test.call(h,k,j,d,c))||(m.exec&&m.exec.call(h,k,j,d,c))){return""}l=m.target?m.target.call(h,k,j):k;g=l.length;j=m.target?k:j;if(m.target&&Ext.isArray(l)){for(var e=0,g=l.length;e=0;--g){d[k[g].selectorText.toLowerCase()]=k[g]}}catch(i){}},getRules:function(h){if(d===null||h){d={};var k=c.styleSheets;for(var j=0,g=k.length;j=37&&a<=40){b.stopEvent()}},destroy:function(){this.disable()},enable:function(){if(this.disabled){if(Ext.isSafari2){this.el.on("keyup",this.stopKeyUp,this)}this.el.on(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=false}},disable:function(){if(!this.disabled){if(Ext.isSafari2){this.el.un("keyup",this.stopKeyUp,this)}this.el.un(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=true}},setDisabled:function(a){this[a?"disable":"enable"]()},isKeydown:function(){return this.forceKeyDown||Ext.EventManager.useKeydown}};Ext.KeyMap=function(c,b,a){this.el=Ext.get(c);this.eventName=a||"keydown";this.bindings=[];if(b){this.addBinding(b)}this.enable()};Ext.KeyMap.prototype={stopEvent:false,addBinding:function(b){if(Ext.isArray(b)){Ext.each(b,function(j){this.addBinding(j)},this);return}var k=b.key,g=b.fn||b.handler,l=b.scope;if(b.stopEvent){this.stopEvent=b.stopEvent}if(typeof k=="string"){var h=[];var e=k.toUpperCase();for(var c=0,d=e.length;c2)?a[2]:null;var h=(i>3)?a[3]:"/";var d=(i>4)?a[4]:null;var g=(i>5)?a[5]:false;document.cookie=c+"="+escape(e)+((b===null)?"":("; expires="+b.toGMTString()))+((h===null)?"":("; path="+h))+((d===null)?"":("; domain="+d))+((g===true)?"; secure":"")},get:function(d){var b=d+"=";var g=b.length;var a=document.cookie.length;var e=0;var c=0;while(e0){return this.ownerCt.items.itemAt(a-1)}}return null},getBubbleTarget:function(){return this.ownerCt}});Ext.reg("component",Ext.Component);Ext.Action=Ext.extend(Object,{constructor:function(a){this.initialConfig=a;this.itemId=a.itemId=(a.itemId||a.id||Ext.id());this.items=[]},isAction:true,setText:function(a){this.initialConfig.text=a;this.callEach("setText",[a])},getText:function(){return this.initialConfig.text},setIconClass:function(a){this.initialConfig.iconCls=a;this.callEach("setIconClass",[a])},getIconClass:function(){return this.initialConfig.iconCls},setDisabled:function(a){this.initialConfig.disabled=a;this.callEach("setDisabled",[a])},enable:function(){this.setDisabled(false)},disable:function(){this.setDisabled(true)},isDisabled:function(){return this.initialConfig.disabled},setHidden:function(a){this.initialConfig.hidden=a;this.callEach("setVisible",[!a])},show:function(){this.setHidden(false)},hide:function(){this.setHidden(true)},isHidden:function(){return this.initialConfig.hidden},setHandler:function(b,a){this.initialConfig.handler=b;this.initialConfig.scope=a;this.callEach("setHandler",[b,a])},each:function(b,a){Ext.each(this.items,b,a)},callEach:function(e,b){var d=this.items;for(var c=0,a=d.length;cj+o.left){k=j-l-c;g=true}if((i+e)>d+o.top){i=d-e-c;g=true}if(k=m){i=m-e-5}}n=[k,i];this.storeXY(n);a.setXY.call(this,n);this.sync()}}return this},isVisible:function(){return this.visible},showAction:function(){this.visible=true;if(this.useDisplay===true){this.setDisplayed("")}else{if(this.lastXY){a.setXY.call(this,this.lastXY)}else{if(this.lastLT){a.setLeftTop.call(this,this.lastLT[0],this.lastLT[1])}}}},hideAction:function(){this.visible=false;if(this.useDisplay===true){this.setDisplayed(false)}else{this.setLeftTop(-10000,-10000)}},setVisible:function(i,h,k,l,j){if(i){this.showAction()}if(h&&i){var g=function(){this.sync(true);if(l){l()}}.createDelegate(this);a.setVisible.call(this,true,true,k,g,j)}else{if(!i){this.hideUnders(true)}var g=l;if(h){g=function(){this.hideAction();if(l){l()}}.createDelegate(this)}a.setVisible.call(this,i,h,k,g,j);if(i){this.sync(true)}else{if(!h){this.hideAction()}}}return this},storeXY:function(c){delete this.lastLT;this.lastXY=c},storeLeftTop:function(d,c){delete this.lastXY;this.lastLT=[d,c]},beforeFx:function(){this.beforeAction();return Ext.Layer.superclass.beforeFx.apply(this,arguments)},afterFx:function(){Ext.Layer.superclass.afterFx.apply(this,arguments);this.sync(this.isVisible())},beforeAction:function(){if(!this.updating&&this.shadow){this.shadow.hide()}},setLeft:function(c){this.storeLeftTop(c,this.getTop(true));a.setLeft.apply(this,arguments);this.sync();return this},setTop:function(c){this.storeLeftTop(this.getLeft(true),c);a.setTop.apply(this,arguments);this.sync();return this},setLeftTop:function(d,c){this.storeLeftTop(d,c);a.setLeftTop.apply(this,arguments);this.sync();return this},setXY:function(j,h,k,l,i){this.fixDisplay();this.beforeAction();this.storeXY(j);var g=this.createCB(l);a.setXY.call(this,j,h,k,g,i);if(!h){g()}return this},createCB:function(e){var d=this;return function(){d.constrainXY();d.sync(true);if(e){e()}}},setX:function(g,h,j,k,i){this.setXY([g,this.getY()],h,j,k,i);return this},setY:function(k,g,i,j,h){this.setXY([this.getX(),k],g,i,j,h);return this},setSize:function(j,k,i,m,n,l){this.beforeAction();var g=this.createCB(n);a.setSize.call(this,j,k,i,m,g,l);if(!i){g()}return this},setWidth:function(i,h,k,l,j){this.beforeAction();var g=this.createCB(l);a.setWidth.call(this,i,h,k,g,j);if(!h){g()}return this},setHeight:function(j,i,l,m,k){this.beforeAction();var g=this.createCB(m);a.setHeight.call(this,j,i,l,g,k);if(!i){g()}return this},setBounds:function(o,m,p,i,n,k,l,j){this.beforeAction();var g=this.createCB(l);if(!n){this.storeXY([o,m]);a.setXY.call(this,[o,m]);a.setSize.call(this,p,i,n,k,g,j);g()}else{a.setBounds.call(this,o,m,p,i,n,k,g,j)}return this},setZIndex:function(c){this.zindex=c;this.setStyle("z-index",c+2);if(this.shadow){this.shadow.setZIndex(c+1)}if(this.shim){this.shim.setStyle("z-index",c)}return this}})})();Ext.Shadow=function(d){Ext.apply(this,d);if(typeof this.mode!="string"){this.mode=this.defaultMode}var e=this.offset,c={h:0};var b=Math.floor(this.offset/2);switch(this.mode.toLowerCase()){case"drop":c.w=0;c.l=c.t=e;c.t-=1;if(Ext.isIE){c.l-=this.offset+b;c.t-=this.offset+b;c.w-=b;c.h-=b;c.t+=1}break;case"sides":c.w=(e*2);c.l=-e;c.t=e-1;if(Ext.isIE){c.l-=(this.offset-b);c.t-=this.offset+b;c.l+=1;c.w-=(this.offset-b)*2;c.w-=b+1;c.h-=1}break;case"frame":c.w=c.h=(e*2);c.l=c.t=-e;c.t+=1;c.h-=2;if(Ext.isIE){c.l-=(this.offset-b);c.t-=(this.offset-b);c.l+=1;c.w-=(this.offset+b+1);c.h-=(this.offset+b);c.h+=1}break}this.adjusts=c};Ext.Shadow.prototype={offset:4,defaultMode:"drop",show:function(a){a=Ext.get(a);if(!this.el){this.el=Ext.Shadow.Pool.pull();if(this.el.dom.nextSibling!=a.dom){this.el.insertBefore(a)}}this.el.setStyle("z-index",this.zIndex||parseInt(a.getStyle("z-index"),10)-1);if(Ext.isIE){this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")"}this.realign(a.getLeft(true),a.getTop(true),a.getWidth(),a.getHeight());this.el.dom.style.display="block"},isVisible:function(){return this.el?true:false},realign:function(b,r,q,g){if(!this.el){return}var n=this.adjusts,k=this.el.dom,u=k.style;var i=0;u.left=(b+n.l)+"px";u.top=(r+n.t)+"px";var p=(q+n.w),e=(g+n.h),j=p+"px",o=e+"px";if(u.width!=j||u.height!=o){u.width=j;u.height=o;if(!Ext.isIE){var m=k.childNodes;var c=Math.max(0,(p-12))+"px";m[0].childNodes[1].style.width=c;m[1].childNodes[1].style.width=c;m[2].childNodes[1].style.width=c;m[1].style.height=Math.max(0,(e-12))+"px"}}},hide:function(){if(this.el){this.el.dom.style.display="none";Ext.Shadow.Pool.push(this.el);delete this.el}},setZIndex:function(a){this.zIndex=a;if(this.el){this.el.setStyle("z-index",a)}}};Ext.Shadow.Pool=function(){var b=[];var a=Ext.isIE?'
':'
';return{pull:function(){var c=b.shift();if(!c){c=Ext.get(Ext.DomHelper.insertHtml("beforeBegin",document.body.firstChild,a));c.autoBoxAdjust=false}return c},push:function(c){b.push(c)}}}();Ext.BoxComponent=Ext.extend(Ext.Component,{initComponent:function(){Ext.BoxComponent.superclass.initComponent.call(this);this.addEvents("resize","move")},boxReady:false,deferHeight:false,setSize:function(b,d){if(typeof b=="object"){d=b.height;b=b.width}if(Ext.isDefined(b)&&Ext.isDefined(this.boxMinWidth)&&(bthis.boxMaxWidth)){b=this.boxMaxWidth}if(Ext.isDefined(d)&&Ext.isDefined(this.boxMaxHeight)&&(d>this.boxMaxHeight)){d=this.boxMaxHeight}if(!this.boxReady){this.width=b;this.height=d;return this}if(this.cacheSizes!==false&&this.lastSize&&this.lastSize.width==b&&this.lastSize.height==d){return this}this.lastSize={width:b,height:d};var c=this.adjustSize(b,d),g=c.width,a=c.height,e;if(g!==undefined||a!==undefined){e=this.getResizeEl();if(!this.deferHeight&&g!==undefined&&a!==undefined){e.setSize(g,a)}else{if(!this.deferHeight&&a!==undefined){e.setHeight(a)}else{if(g!==undefined){e.setWidth(g)}}}this.onResize(g,a,b,d);this.fireEvent("resize",this,g,a,b,d)}return this},setWidth:function(a){return this.setSize(a)},setHeight:function(a){return this.setSize(undefined,a)},getSize:function(){return this.getResizeEl().getSize()},getWidth:function(){return this.getResizeEl().getWidth()},getHeight:function(){return this.getResizeEl().getHeight()},getOuterSize:function(){var a=this.getResizeEl();return{width:a.getWidth()+a.getMargins("lr"),height:a.getHeight()+a.getMargins("tb")}},getPosition:function(a){var b=this.getPositionEl();if(a===true){return[b.getLeft(true),b.getTop(true)]}return this.xy||b.getXY()},getBox:function(a){var c=this.getPosition(a);var b=this.getSize();b.x=c[0];b.y=c[1];return b},updateBox:function(a){this.setSize(a.width,a.height);this.setPagePosition(a.x,a.y);return this},getResizeEl:function(){return this.resizeEl||this.el},setAutoScroll:function(a){if(this.rendered){this.getContentTarget().setOverflow(a?"auto":"")}this.autoScroll=a;return this},setPosition:function(a,g){if(a&&typeof a[1]=="number"){g=a[1];a=a[0]}this.x=a;this.y=g;if(!this.boxReady){return this}var b=this.adjustPosition(a,g);var e=b.x,d=b.y;var c=this.getPositionEl();if(e!==undefined||d!==undefined){if(e!==undefined&&d!==undefined){c.setLeftTop(e,d)}else{if(e!==undefined){c.setLeft(e)}else{if(d!==undefined){c.setTop(d)}}}this.onPosition(e,d);this.fireEvent("move",this,e,d)}return this},setPagePosition:function(a,c){if(a&&typeof a[1]=="number"){c=a[1];a=a[0]}this.pageX=a;this.pageY=c;if(!this.boxReady){return}if(a===undefined||c===undefined){return}var b=this.getPositionEl().translatePoints(a,c);this.setPosition(b.left,b.top);return this},afterRender:function(){Ext.BoxComponent.superclass.afterRender.call(this);if(this.resizeEl){this.resizeEl=Ext.get(this.resizeEl)}if(this.positionEl){this.positionEl=Ext.get(this.positionEl)}this.boxReady=true;Ext.isDefined(this.autoScroll)&&this.setAutoScroll(this.autoScroll);this.setSize(this.width,this.height);if(this.x||this.y){this.setPosition(this.x,this.y)}else{if(this.pageX||this.pageY){this.setPagePosition(this.pageX,this.pageY)}}},syncSize:function(){delete this.lastSize;this.setSize(this.autoWidth?undefined:this.getResizeEl().getWidth(),this.autoHeight?undefined:this.getResizeEl().getHeight());return this},onResize:function(d,b,a,c){},onPosition:function(a,b){},adjustSize:function(a,b){if(this.autoWidth){a="auto"}if(this.autoHeight){b="auto"}return{width:a,height:b}},adjustPosition:function(a,b){return{x:a,y:b}}});Ext.reg("box",Ext.BoxComponent);Ext.Spacer=Ext.extend(Ext.BoxComponent,{autoEl:"div"});Ext.reg("spacer",Ext.Spacer);Ext.SplitBar=function(c,e,b,d,a){this.el=Ext.get(c,true);this.el.dom.unselectable="on";this.resizingEl=Ext.get(e,true);this.orientation=b||Ext.SplitBar.HORIZONTAL;this.minSize=0;this.maxSize=2000;this.animate=false;this.useShim=false;this.shim=null;if(!a){this.proxy=Ext.SplitBar.createProxy(this.orientation)}else{this.proxy=Ext.get(a).dom}this.dd=new Ext.dd.DDProxy(this.el.dom.id,"XSplitBars",{dragElId:this.proxy.id});this.dd.b4StartDrag=this.onStartProxyDrag.createDelegate(this);this.dd.endDrag=this.onEndProxyDrag.createDelegate(this);this.dragSpecs={};this.adapter=new Ext.SplitBar.BasicLayoutAdapter();this.adapter.init(this);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.placement=d||(this.el.getX()>this.resizingEl.getX()?Ext.SplitBar.LEFT:Ext.SplitBar.RIGHT);this.el.addClass("x-splitbar-h")}else{this.placement=d||(this.el.getY()>this.resizingEl.getY()?Ext.SplitBar.TOP:Ext.SplitBar.BOTTOM);this.el.addClass("x-splitbar-v")}this.addEvents("resize","moved","beforeresize","beforeapply");Ext.SplitBar.superclass.constructor.call(this)};Ext.extend(Ext.SplitBar,Ext.util.Observable,{onStartProxyDrag:function(a,e){this.fireEvent("beforeresize",this);this.overlay=Ext.DomHelper.append(document.body,{cls:"x-drag-overlay",html:" "},true);this.overlay.unselectable();this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();Ext.get(this.proxy).setDisplayed("block");var c=this.adapter.getElementSize(this);this.activeMinSize=this.getMinimumSize();this.activeMaxSize=this.getMaximumSize();var d=c-this.activeMinSize;var b=Math.max(this.activeMaxSize-c,0);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.dd.resetConstraints();this.dd.setXConstraint(this.placement==Ext.SplitBar.LEFT?d:b,this.placement==Ext.SplitBar.LEFT?b:d,this.tickSize);this.dd.setYConstraint(0,0)}else{this.dd.resetConstraints();this.dd.setXConstraint(0,0);this.dd.setYConstraint(this.placement==Ext.SplitBar.TOP?d:b,this.placement==Ext.SplitBar.TOP?b:d,this.tickSize)}this.dragSpecs.startSize=c;this.dragSpecs.startPoint=[a,e];Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd,a,e)},onEndProxyDrag:function(c){Ext.get(this.proxy).setDisplayed(false);var b=Ext.lib.Event.getXY(c);if(this.overlay){Ext.destroy(this.overlay);delete this.overlay}var a;if(this.orientation==Ext.SplitBar.HORIZONTAL){a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.LEFT?b[0]-this.dragSpecs.startPoint[0]:this.dragSpecs.startPoint[0]-b[0])}else{a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.TOP?b[1]-this.dragSpecs.startPoint[1]:this.dragSpecs.startPoint[1]-b[1])}a=Math.min(Math.max(a,this.activeMinSize),this.activeMaxSize);if(a!=this.dragSpecs.startSize){if(this.fireEvent("beforeapply",this,a)!==false){this.adapter.setElementSize(this,a);this.fireEvent("moved",this,a);this.fireEvent("resize",this,a)}}},getAdapter:function(){return this.adapter},setAdapter:function(a){this.adapter=a;this.adapter.init(this)},getMinimumSize:function(){return this.minSize},setMinimumSize:function(a){this.minSize=a},getMaximumSize:function(){return this.maxSize},setMaximumSize:function(a){this.maxSize=a},setCurrentSize:function(b){var a=this.animate;this.animate=false;this.adapter.setElementSize(this,b);this.animate=a},destroy:function(a){Ext.destroy(this.shim,Ext.get(this.proxy));this.dd.unreg();if(a){this.el.remove()}this.purgeListeners()}});Ext.SplitBar.createProxy=function(b){var c=new Ext.Element(document.createElement("div"));document.body.appendChild(c.dom);c.unselectable();var a="x-splitbar-proxy";c.addClass(a+" "+(b==Ext.SplitBar.HORIZONTAL?a+"-h":a+"-v"));return c.dom};Ext.SplitBar.BasicLayoutAdapter=function(){};Ext.SplitBar.BasicLayoutAdapter.prototype={init:function(a){},getElementSize:function(a){if(a.orientation==Ext.SplitBar.HORIZONTAL){return a.resizingEl.getWidth()}else{return a.resizingEl.getHeight()}},setElementSize:function(b,a,c){if(b.orientation==Ext.SplitBar.HORIZONTAL){if(!b.animate){b.resizingEl.setWidth(a);if(c){c(b,a)}}else{b.resizingEl.setWidth(a,true,0.1,c,"easeOut")}}else{if(!b.animate){b.resizingEl.setHeight(a);if(c){c(b,a)}}else{b.resizingEl.setHeight(a,true,0.1,c,"easeOut")}}}};Ext.SplitBar.AbsoluteLayoutAdapter=function(a){this.basic=new Ext.SplitBar.BasicLayoutAdapter();this.container=Ext.get(a)};Ext.SplitBar.AbsoluteLayoutAdapter.prototype={init:function(a){this.basic.init(a)},getElementSize:function(a){return this.basic.getElementSize(a)},setElementSize:function(b,a,c){this.basic.setElementSize(b,a,this.moveSplitter.createDelegate(this,[b]))},moveSplitter:function(a){var b=Ext.SplitBar;switch(a.placement){case b.LEFT:a.el.setX(a.resizingEl.getRight());break;case b.RIGHT:a.el.setStyle("right",(this.container.getWidth()-a.resizingEl.getLeft())+"px");break;case b.TOP:a.el.setY(a.resizingEl.getBottom());break;case b.BOTTOM:a.el.setY(a.resizingEl.getTop()-a.el.getHeight());break}}};Ext.SplitBar.VERTICAL=1;Ext.SplitBar.HORIZONTAL=2;Ext.SplitBar.LEFT=1;Ext.SplitBar.RIGHT=2;Ext.SplitBar.TOP=3;Ext.SplitBar.BOTTOM=4;Ext.Container=Ext.extend(Ext.BoxComponent,{bufferResize:50,autoDestroy:true,forceLayout:false,defaultType:"panel",resizeEvent:"resize",bubbleEvents:["add","remove"],initComponent:function(){Ext.Container.superclass.initComponent.call(this);this.addEvents("afterlayout","beforeadd","beforeremove","add","remove");var a=this.items;if(a){delete this.items;this.add(a)}},initItems:function(){if(!this.items){this.items=new Ext.util.MixedCollection(false,this.getComponentId);this.getLayout()}},setLayout:function(a){if(this.layout&&this.layout!=a){this.layout.setContainer(null)}this.layout=a;this.initItems();a.setContainer(this)},afterRender:function(){Ext.Container.superclass.afterRender.call(this);if(!this.layout){this.layout="auto"}if(Ext.isObject(this.layout)&&!this.layout.layout){this.layoutConfig=this.layout;this.layout=this.layoutConfig.type}if(Ext.isString(this.layout)){this.layout=new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig)}this.setLayout(this.layout);if(this.activeItem!==undefined){var a=this.activeItem;delete this.activeItem;this.layout.setActiveItem(a)}if(!this.ownerCt){this.doLayout(false,true)}if(this.monitorResize===true){Ext.EventManager.onWindowResize(this.doLayout,this,[false])}},getLayoutTarget:function(){return this.el},getComponentId:function(a){return a.getItemId()},add:function(b){this.initItems();var e=arguments.length>1;if(e||Ext.isArray(b)){var a=[];Ext.each(e?arguments:b,function(h){a.push(this.add(h))},this);return a}var g=this.lookupComponent(this.applyDefaults(b));var d=this.items.length;if(this.fireEvent("beforeadd",this,g,d)!==false&&this.onBeforeAdd(g)!==false){this.items.add(g);g.onAdded(this,d);this.onAdd(g);this.fireEvent("add",this,g,d)}return g},onAdd:function(a){},onAdded:function(a,b){this.ownerCt=a;this.initRef();this.cascade(function(d){d.initRef()});this.fireEvent("added",this,a,b)},insert:function(h,g){this.initItems();var e=arguments,d=e.length;if(d>2){var b=[];for(var j=d-1;j>=1;--j){b.push(this.insert(h,e[j]))}return b}var k=this.lookupComponent(this.applyDefaults(g));h=Math.min(h,this.items.length);if(this.fireEvent("beforeadd",this,k,h)!==false&&this.onBeforeAdd(k)!==false){if(k.ownerCt==this){this.items.remove(k)}this.items.insert(h,k);k.onAdded(this,h);this.onAdd(k);this.fireEvent("add",this,k,h)}return k},applyDefaults:function(b){var a=this.defaults;if(a){if(Ext.isFunction(a)){a=a.call(this,b)}if(Ext.isString(b)){b=Ext.ComponentMgr.get(b);Ext.apply(b,a)}else{if(!b.events){Ext.applyIf(b,a)}else{Ext.apply(b,a)}}}return b},onBeforeAdd:function(a){if(a.ownerCt){a.ownerCt.remove(a,false)}if(this.hideBorders===true){a.border=(a.border===true)}},remove:function(a,b){this.initItems();var d=this.getComponent(a);if(d&&this.fireEvent("beforeremove",this,d)!==false){this.doRemove(d,b);this.fireEvent("remove",this,d)}return d},onRemove:function(a){},doRemove:function(e,d){var b=this.layout,a=b&&this.rendered;if(a){b.onRemove(e)}this.items.remove(e);e.onRemoved();this.onRemove(e);if(d===true||(d!==false&&this.autoDestroy)){e.destroy()}if(a){b.afterRemove(e)}},removeAll:function(c){this.initItems();var e,g=[],b=[];this.items.each(function(h){g.push(h)});for(var d=0,a=g.length;d','','
','
',"");a.disableFormats=true;return a.compile()})(),destroy:function(){if(this.resizeTask&&this.resizeTask.cancel){this.resizeTask.cancel()}if(!Ext.isEmpty(this.targetCls)){var a=this.container.getLayoutTarget();if(a){a.removeClass(this.targetCls)}}}});Ext.layout.AutoLayout=Ext.extend(Ext.layout.ContainerLayout,{type:"auto",monitorResize:true,onLayout:function(d,g){Ext.layout.AutoLayout.superclass.onLayout.call(this,d,g);var e=this.getRenderedItems(d),a=e.length,b,h;for(b=0;b0){b.setSize(a)}}});Ext.Container.LAYOUTS.fit=Ext.layout.FitLayout;Ext.layout.CardLayout=Ext.extend(Ext.layout.FitLayout,{deferredRender:false,layoutOnCardChange:false,renderHidden:true,type:"card",setActiveItem:function(d){var a=this.activeItem,b=this.container;d=b.getComponent(d);if(d&&a!=d){if(a){a.hide();if(a.hidden!==true){return false}a.fireEvent("deactivate",a)}var c=d.doLayout&&(this.layoutOnCardChange||!d.rendered);this.activeItem=d;delete d.deferLayout;d.show();this.layout();if(c){d.doLayout()}d.fireEvent("activate",d)}},renderAll:function(a,b){if(this.deferredRender){this.renderItem(this.activeItem,undefined,b)}else{Ext.layout.CardLayout.superclass.renderAll.call(this,a,b)}}});Ext.Container.LAYOUTS.card=Ext.layout.CardLayout;Ext.layout.AnchorLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"anchor",defaultAnchor:"100%",parseAnchorRE:/^(r|right|b|bottom)$/i,getLayoutTargetSize:function(){var a=this.container.getLayoutTarget();if(!a){return{}}return a.getStyleSize()},onLayout:function(m,p){Ext.layout.AnchorLayout.superclass.onLayout.call(this,m,p);var v=this.getLayoutTargetSize();var t=v.width,l=v.height;if(t<20&&l<20){return}var d,r;if(m.anchorSize){if(typeof m.anchorSize=="number"){d=m.anchorSize}else{d=m.anchorSize.width;r=m.anchorSize.height}}else{d=m.initialConfig.width;r=m.initialConfig.height}var o=this.getRenderedItems(m),n=o.length,j,q,s,g,b,e,u,k=[];for(j=0;j ');b.disableFormats=true;b.compile();Ext.layout.BorderLayout.Region.prototype.toolTemplate=b}this.collapsedEl=this.targetEl.createChild({cls:"x-layout-collapsed x-layout-collapsed-"+this.position,id:this.panel.id+"-xcollapsed"});this.collapsedEl.enableDisplayMode("block");if(this.collapseMode=="mini"){this.collapsedEl.addClass("x-layout-cmini-"+this.position);this.miniCollapsedEl=this.collapsedEl.createChild({cls:"x-layout-mini x-layout-mini-"+this.position,html:" "});this.miniCollapsedEl.addClassOnOver("x-layout-mini-over");this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this.onExpandClick,this,{stopEvent:true})}else{if(this.collapsible!==false&&!this.hideCollapseTool){var a=this.toolTemplate.append(this.collapsedEl.dom,{id:"expand-"+this.position},true);a.addClassOnOver("x-tool-expand-"+this.position+"-over");a.on("click",this.onExpandClick,this,{stopEvent:true})}if(this.floatable!==false||this.titleCollapse){this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this[this.floatable?"collapseClick":"onExpandClick"],this)}}}return this.collapsedEl},onExpandClick:function(a){if(this.isSlid){this.panel.expand(false)}else{this.panel.expand()}},onCollapseClick:function(a){this.panel.collapse()},beforeCollapse:function(c,a){this.lastAnim=a;if(this.splitEl){this.splitEl.hide()}this.getCollapsedEl().show();var b=this.panel.getEl();this.originalZIndex=b.getStyle("z-index");b.setStyle("z-index",100);this.isCollapsed=true;this.layout.layout()},onCollapse:function(a){this.panel.el.setStyle("z-index",1);if(this.lastAnim===false||this.panel.animCollapse===false){this.getCollapsedEl().dom.style.visibility="visible"}else{this.getCollapsedEl().slideIn(this.panel.slideAnchor,{duration:0.2})}this.state.collapsed=true;this.panel.saveState()},beforeExpand:function(a){if(this.isSlid){this.afterSlideIn()}var b=this.getCollapsedEl();this.el.show();if(this.position=="east"||this.position=="west"){this.panel.setSize(undefined,b.getHeight())}else{this.panel.setSize(b.getWidth(),undefined)}b.hide();b.dom.style.visibility="hidden";this.panel.el.setStyle("z-index",this.floatingZIndex)},onExpand:function(){this.isCollapsed=false;if(this.splitEl){this.splitEl.show()}this.layout.layout();this.panel.el.setStyle("z-index",this.originalZIndex);this.state.collapsed=false;this.panel.saveState()},collapseClick:function(a){if(this.isSlid){a.stopPropagation();this.slideIn()}else{a.stopPropagation();this.slideOut()}},onHide:function(){if(this.isCollapsed){this.getCollapsedEl().hide()}else{if(this.splitEl){this.splitEl.hide()}}},onShow:function(){if(this.isCollapsed){this.getCollapsedEl().show()}else{if(this.splitEl){this.splitEl.show()}}},isVisible:function(){return !this.panel.hidden},getMargins:function(){return this.isCollapsed&&this.cmargins?this.cmargins:this.margins},getSize:function(){return this.isCollapsed?this.getCollapsedEl().getSize():this.panel.getSize()},setPanel:function(a){this.panel=a},getMinWidth:function(){return this.minWidth},getMinHeight:function(){return this.minHeight},applyLayoutCollapsed:function(a){var b=this.getCollapsedEl();b.setLeftTop(a.x,a.y);b.setSize(a.width,a.height)},applyLayout:function(a){if(this.isCollapsed){this.applyLayoutCollapsed(a)}else{this.panel.setPosition(a.x,a.y);this.panel.setSize(a.width,a.height)}},beforeSlide:function(){this.panel.beforeEffect()},afterSlide:function(){this.panel.afterEffect()},initAutoHide:function(){if(this.autoHide!==false){if(!this.autoHideHd){this.autoHideSlideTask=new Ext.util.DelayedTask(this.slideIn,this);this.autoHideHd={mouseout:function(a){if(!a.within(this.el,true)){this.autoHideSlideTask.delay(500)}},mouseover:function(a){this.autoHideSlideTask.cancel()},scope:this}}this.el.on(this.autoHideHd);this.collapsedEl.on(this.autoHideHd)}},clearAutoHide:function(){if(this.autoHide!==false){this.el.un("mouseout",this.autoHideHd.mouseout);this.el.un("mouseover",this.autoHideHd.mouseover);this.collapsedEl.un("mouseout",this.autoHideHd.mouseout);this.collapsedEl.un("mouseover",this.autoHideHd.mouseover)}},clearMonitor:function(){Ext.getDoc().un("click",this.slideInIf,this)},slideOut:function(){if(this.isSlid||this.el.hasActiveFx()){return}this.isSlid=true;var b=this.panel.tools,c,a;if(b&&b.toggle){b.toggle.hide()}this.el.show();a=this.panel.collapsed;this.panel.collapsed=false;if(this.position=="east"||this.position=="west"){c=this.panel.deferHeight;this.panel.deferHeight=false;this.panel.setSize(undefined,this.collapsedEl.getHeight());this.panel.deferHeight=c}else{this.panel.setSize(this.collapsedEl.getWidth(),undefined)}this.panel.collapsed=a;this.restoreLT=[this.el.dom.style.left,this.el.dom.style.top];this.el.alignTo(this.collapsedEl,this.getCollapseAnchor());this.el.setStyle("z-index",this.floatingZIndex+2);this.panel.el.replaceClass("x-panel-collapsed","x-panel-floating");if(this.animFloat!==false){this.beforeSlide();this.el.slideIn(this.getSlideAnchor(),{callback:function(){this.afterSlide();this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)},scope:this,block:true})}else{this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)}},afterSlideIn:function(){this.clearAutoHide();this.isSlid=false;this.clearMonitor();this.el.setStyle("z-index","");this.panel.el.replaceClass("x-panel-floating","x-panel-collapsed");this.el.dom.style.left=this.restoreLT[0];this.el.dom.style.top=this.restoreLT[1];var a=this.panel.tools;if(a&&a.toggle){a.toggle.show()}},slideIn:function(a){if(!this.isSlid||this.el.hasActiveFx()){Ext.callback(a);return}this.isSlid=false;if(this.animFloat!==false){this.beforeSlide();this.el.slideOut(this.getSlideAnchor(),{callback:function(){this.el.hide();this.afterSlide();this.afterSlideIn();Ext.callback(a)},scope:this,block:true})}else{this.el.hide();this.afterSlideIn()}},slideInIf:function(a){if(!a.within(this.el)){this.slideIn()}},anchors:{west:"left",east:"right",north:"top",south:"bottom"},sanchors:{west:"l",east:"r",north:"t",south:"b"},canchors:{west:"tl-tr",east:"tr-tl",north:"tl-bl",south:"bl-tl"},getAnchor:function(){return this.anchors[this.position]},getCollapseAnchor:function(){return this.canchors[this.position]},getSlideAnchor:function(){return this.sanchors[this.position]},getAlignAdj:function(){var a=this.cmargins;switch(this.position){case"west":return[0,0];break;case"east":return[0,0];break;case"north":return[0,0];break;case"south":return[0,0];break}},getExpandAdj:function(){var b=this.collapsedEl,a=this.cmargins;switch(this.position){case"west":return[-(a.right+b.getWidth()+a.left),0];break;case"east":return[a.right+b.getWidth()+a.left,0];break;case"north":return[0,-(a.top+a.bottom+b.getHeight())];break;case"south":return[0,a.top+a.bottom+b.getHeight()];break}},destroy:function(){if(this.autoHideSlideTask&&this.autoHideSlideTask.cancel){this.autoHideSlideTask.cancel()}Ext.destroy(this.miniCollapsedEl,this.collapsedEl)}};Ext.layout.BorderLayout.SplitRegion=function(b,a,c){Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this,b,a,c);this.applyLayout=this.applyFns[c]};Ext.extend(Ext.layout.BorderLayout.SplitRegion,Ext.layout.BorderLayout.Region,{splitTip:"Drag to resize.",collapsibleSplitTip:"Drag to resize. Double click to hide.",useSplitTips:false,splitSettings:{north:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.TOP,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},south:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.BOTTOM,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},east:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.RIGHT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"},west:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.LEFT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"}},applyFns:{west:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;this.panel.setPosition(c.x,c.y);var a=d.offsetWidth;b.left=(c.x+c.width-a)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},east:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetWidth;this.panel.setPosition(c.x+a,c.y);b.left=(c.x)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},north:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y);b.left=(c.x)+"px";b.top=(c.y+c.height-a)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)},south:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y+a);b.left=(c.x)+"px";b.top=(c.y)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)}},render:function(a,c){Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this,a,c);var d=this.position;this.splitEl=a.createChild({cls:"x-layout-split x-layout-split-"+d,html:" ",id:this.panel.id+"-xsplit"});if(this.collapseMode=="mini"){this.miniSplitEl=this.splitEl.createChild({cls:"x-layout-mini x-layout-mini-"+d,html:" "});this.miniSplitEl.addClassOnOver("x-layout-mini-over");this.miniSplitEl.on("click",this.onCollapseClick,this,{stopEvent:true})}var b=this.splitSettings[d];this.split=new Ext.SplitBar(this.splitEl.dom,c.el,b.orientation);this.split.tickSize=this.tickSize;this.split.placement=b.placement;this.split.getMaximumSize=this[b.maxFn].createDelegate(this);this.split.minSize=this.minSize||this[b.minProp];this.split.on("beforeapply",this.onSplitMove,this);this.split.useShim=this.useShim===true;this.maxSize=this.maxSize||this[b.maxProp];if(c.hidden){this.splitEl.hide()}if(this.useSplitTips){this.splitEl.dom.title=this.collapsible?this.collapsibleSplitTip:this.splitTip}if(this.collapsible){this.splitEl.on("dblclick",this.onCollapseClick,this)}},getSize:function(){if(this.isCollapsed){return this.collapsedEl.getSize()}var a=this.panel.getSize();if(this.position=="north"||this.position=="south"){a.height+=this.splitEl.dom.offsetHeight}else{a.width+=this.splitEl.dom.offsetWidth}return a},getHMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getWidth()+a.el.getWidth())-a.getMinWidth())},getVMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getHeight()+a.el.getHeight())-a.getMinHeight())},onSplitMove:function(b,a){var c=this.panel.getSize();this.lastSplitSize=a;if(this.position=="north"||this.position=="south"){this.panel.setSize(c.width,a);this.state.height=a}else{this.panel.setSize(a,c.height);this.state.width=a}this.layout.layout();this.panel.saveState();return false},getSplitBar:function(){return this.split},destroy:function(){Ext.destroy(this.miniSplitEl,this.split,this.splitEl);Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.border=Ext.layout.BorderLayout;Ext.layout.FormLayout=Ext.extend(Ext.layout.AnchorLayout,{labelSeparator:":",trackLabels:false,type:"form",onRemove:function(d){Ext.layout.FormLayout.superclass.onRemove.call(this,d);if(this.trackLabels){d.un("show",this.onFieldShow,this);d.un("hide",this.onFieldHide,this)}var b=d.getPositionEl(),a=d.getItemCt&&d.getItemCt();if(d.rendered&&a){if(b&&b.dom){b.insertAfter(a)}Ext.destroy(a);Ext.destroyMembers(d,"label","itemCt");if(d.customItemCt){Ext.destroyMembers(d,"getItemCt","customItemCt")}}},setContainer:function(a){Ext.layout.FormLayout.superclass.setContainer.call(this,a);if(a.labelAlign){a.addClass("x-form-label-"+a.labelAlign)}if(a.hideLabels){Ext.apply(this,{labelStyle:"display:none",elementStyle:"padding-left:0;",labelAdjust:0})}else{this.labelSeparator=a.labelSeparator||this.labelSeparator;a.labelWidth=a.labelWidth||100;if(Ext.isNumber(a.labelWidth)){var b=Ext.isNumber(a.labelPad)?a.labelPad:5;Ext.apply(this,{labelAdjust:a.labelWidth+b,labelStyle:"width:"+a.labelWidth+"px;",elementStyle:"padding-left:"+(a.labelWidth+b)+"px"})}if(a.labelAlign=="top"){Ext.apply(this,{labelStyle:"width:auto;",labelAdjust:0,elementStyle:"padding-left:0;"})}}},isHide:function(a){return a.hideLabel||this.container.hideLabels},onFieldShow:function(a){a.getItemCt().removeClass("x-hide-"+a.hideMode);if(a.isComposite){a.doLayout()}},onFieldHide:function(a){a.getItemCt().addClass("x-hide-"+a.hideMode)},getLabelStyle:function(e){var b="",c=[this.labelStyle,e];for(var d=0,a=c.length;d=b)||(this.cells[c]&&this.cells[c][a])){if(b&&a>=b){c++;a=0}else{a++}}return[a,c]},renderItem:function(e,a,d){if(!this.table){this.table=d.createChild(Ext.apply({tag:"table",cls:"x-table-layout",cellspacing:0,cn:{tag:"tbody"}},this.tableAttrs),null,true)}if(e&&!e.rendered){e.render(this.getNextCell(e));this.configureItem(e,a)}else{if(e&&!this.isValidParent(e,d)){var b=this.getNextCell(e);b.insertBefore(e.getPositionEl().dom,null);e.container=Ext.get(b);this.configureItem(e,a)}}},isValidParent:function(b,a){return b.getPositionEl().up("table",5).dom.parentNode===(a.dom||a)}});Ext.Container.LAYOUTS.table=Ext.layout.TableLayout;Ext.layout.AbsoluteLayout=Ext.extend(Ext.layout.AnchorLayout,{extraCls:"x-abs-layout-item",type:"absolute",onLayout:function(a,b){b.position();this.paddingLeft=b.getPadding("l");this.paddingTop=b.getPadding("t");Ext.layout.AbsoluteLayout.superclass.onLayout.call(this,a,b)},adjustWidthAnchor:function(b,a){return b?b-a.getPosition(true)[0]+this.paddingLeft:b},adjustHeightAnchor:function(b,a){return b?b-a.getPosition(true)[1]+this.paddingTop:b}});Ext.Container.LAYOUTS.absolute=Ext.layout.AbsoluteLayout;Ext.layout.BoxLayout=Ext.extend(Ext.layout.ContainerLayout,{defaultMargins:{left:0,top:0,right:0,bottom:0},padding:"0",pack:"start",monitorResize:true,type:"box",scrollOffset:0,extraCls:"x-box-item",targetCls:"x-box-layout-ct",innerCls:"x-box-inner",constructor:function(a){Ext.layout.BoxLayout.superclass.constructor.call(this,a);if(Ext.isString(this.defaultMargins)){this.defaultMargins=this.parseMargins(this.defaultMargins)}},onLayout:function(a,d){Ext.layout.BoxLayout.superclass.onLayout.call(this,a,d);var b=this.getVisibleItems(a),c=this.getLayoutTargetSize();this.layoutTargetLastSize=c;this.childBoxCache=this.calculateChildBoxes(b,c);this.updateInnerCtSize(c,this.childBoxCache);this.updateChildBoxes(this.childBoxCache.boxes);this.handleTargetOverflow(c,a,d)},updateChildBoxes:function(c){for(var b=0,e=c.length;b0){s.left=p+G+(r/2)}}y+=s.height+t.bottom}return{boxes:j,meta:{maxWidth:E}}}});Ext.Container.LAYOUTS.vbox=Ext.layout.VBoxLayout;Ext.layout.HBoxLayout=Ext.extend(Ext.layout.BoxLayout,{align:"top",type:"hbox",updateInnerCtSize:function(b,d){var a=b.width,c=d.meta.maxHeight+this.padding.top+this.padding.bottom;if(this.align=="stretch"){c=b.height}else{if(this.align=="middle"){c=Math.max(b.height,c)}}this.innerCt.setSize(a||undefined,c||undefined)},calculateChildBoxes:function(z,e){var n=z.length,x=this.padding,C=x.top,r=x.left,s=C+x.bottom,a=r+x.right,B=e.width-this.scrollOffset,y=e.height,h=Math.max(0,y-s),o=this.pack=="start",p=this.pack=="center",q=this.pack=="end",I=0,A=0,D=0,m=[],l,d,g,c,w,F,E,v,H,j,t;for(E=0;E0){v.top=C+j+(u/2)}}r+=v.width+w.right}return{boxes:m,meta:{maxHeight:A}}}});Ext.Container.LAYOUTS.hbox=Ext.layout.HBoxLayout;Ext.layout.ToolbarLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"toolbar",triggerWidth:18,noItemsMenuText:'
(None)
',lastOverflow:false,tableHTML:['',"","",'",'","","","
','',"",'',"","
","
','',"","","","","","","
",'',"",'',"","
","
",'',"",'',"","
","
","
"].join(""),onLayout:function(e,j){if(!this.leftTr){var h=e.buttonAlign=="center"?"center":"left";j.addClass("x-toolbar-layout-ct");j.insertHtml("beforeEnd",String.format(this.tableHTML,h));this.leftTr=j.child("tr.x-toolbar-left-row",true);this.rightTr=j.child("tr.x-toolbar-right-row",true);this.extrasTr=j.child("tr.x-toolbar-extras-row",true);if(this.hiddenItem==undefined){this.hiddenItems=[]}}var k=e.buttonAlign=="right"?this.rightTr:this.leftTr,l=e.items.items,d=0;for(var b=0,g=l.length,m;b=0&&(d=e[a]);a--){if(!d.firstChild){b.removeChild(d)}}},insertCell:function(e,b,a){var d=document.createElement("td");d.className="x-toolbar-cell";b.insertBefore(d,b.childNodes[a]||null);return d},hideItem:function(a){this.hiddenItems.push(a);a.xtbHidden=true;a.xtbWidth=a.getPositionEl().dom.parentNode.offsetWidth;a.hide()},unhideItem:function(a){a.show();a.xtbHidden=false;this.hiddenItems.remove(a)},getItemWidth:function(a){return a.hidden?(a.xtbWidth||0):a.getPositionEl().dom.parentNode.offsetWidth},fitToSize:function(k){if(this.container.enableOverflow===false){return}var b=k.dom.clientWidth,j=k.dom.firstChild.offsetWidth,m=b-this.triggerWidth,a=this.lastWidth||0,c=this.hiddenItems,e=c.length!=0,n=b>=a;this.lastWidth=b;if(j>b||(e&&n)){var l=this.container.items.items,h=l.length,d=0,o;for(var g=0;gm){if(!(o.hidden||o.xtbHidden)){this.hideItem(o)}}else{if(o.xtbHidden){this.unhideItem(o)}}}}}e=c.length!=0;if(e){this.initMore();if(!this.lastOverflow){this.container.fireEvent("overflowchange",this.container,true);this.lastOverflow=true}}else{if(this.more){this.clearMenu();this.more.destroy();delete this.more;if(this.lastOverflow){this.container.fireEvent("overflowchange",this.container,false);this.lastOverflow=false}}}},createMenuConfig:function(c,a){var b=Ext.apply({},c.initialConfig),d=c.toggleGroup;Ext.copyTo(b,c,["iconCls","icon","itemId","disabled","handler","scope","menu"]);Ext.apply(b,{text:c.overflowText||c.text,hideOnClick:a});if(d||c.enableToggle){Ext.apply(b,{group:d,checked:c.pressed,listeners:{checkchange:function(g,e){c.toggle(e)}}})}delete b.ownerCt;delete b.xtype;delete b.id;return b},addComponentToMenu:function(b,a){if(a instanceof Ext.Toolbar.Separator){b.add("-")}else{if(Ext.isFunction(a.isXType)){if(a.isXType("splitbutton")){b.add(this.createMenuConfig(a,true))}else{if(a.isXType("button")){b.add(this.createMenuConfig(a,!a.menu))}else{if(a.isXType("buttongroup")){a.items.each(function(c){this.addComponentToMenu(b,c)},this)}}}}}},clearMenu:function(){var a=this.moreMenu;if(a&&a.items){a.items.each(function(b){delete b.menu})}},beforeMoreShow:function(h){var b=this.container.items.items,a=b.length,g,e;var c=function(j,i){return j.isXType("buttongroup")&&!(i instanceof Ext.Toolbar.Separator)};this.clearMenu();h.removeAll();for(var d=0;d','','',"","")}if(g&&!g.rendered){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}var d=this.getItemArgs(g);g.render(g.positionEl=b?this.itemTpl.insertBefore(b,d,true):this.itemTpl.append(e,d,true));g.positionEl.menuItemId=g.getItemId();if(!d.isMenuItem&&d.needsIcon){g.positionEl.addClass("x-menu-list-item-indent")}this.configureItem(g,b)}else{if(g&&!this.isValidParent(g,e)){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}e.dom.insertBefore(g.getActionEl().dom,b||null)}}},getItemArgs:function(b){var a=b instanceof Ext.menu.Item;return{isMenuItem:a,needsIcon:!a&&(b.icon||b.iconCls),icon:b.icon||Ext.BLANK_IMAGE_URL,iconCls:"x-menu-item-icon "+(b.iconCls||""),itemId:"x-menu-el-"+b.id,itemCls:"x-menu-list-item "}},isValidParent:function(b,a){return b.el.up("li.x-menu-list-item",5).dom.parentNode===(a.dom||a)},onLayout:function(a,b){Ext.layout.MenuLayout.superclass.onLayout.call(this,a,b);this.doAutoSize()},doAutoSize:function(){var c=this.container,a=c.width;if(c.floating){if(a){c.setWidth(a)}else{if(Ext.isIE){c.setWidth(Ext.isStrict&&(Ext.isIE7||Ext.isIE8)?"auto":c.minWidth);var d=c.getEl(),b=d.dom.offsetWidth;c.setWidth(c.getLayoutTarget().getWidth()+d.getFrameWidth("lr"))}}}}});Ext.Container.LAYOUTS.menu=Ext.layout.MenuLayout;Ext.Viewport=Ext.extend(Ext.Container,{initComponent:function(){Ext.Viewport.superclass.initComponent.call(this);document.getElementsByTagName("html")[0].className+=" x-viewport";this.el=Ext.getBody();this.el.setHeight=Ext.emptyFn;this.el.setWidth=Ext.emptyFn;this.el.setSize=Ext.emptyFn;this.el.dom.scroll="no";this.allowDomMove=false;this.autoWidth=true;this.autoHeight=true;Ext.EventManager.onWindowResize(this.fireResize,this);this.renderTo=this.el},fireResize:function(a,b){this.fireEvent("resize",this,a,b,a,b)}});Ext.reg("viewport",Ext.Viewport);Ext.Panel=Ext.extend(Ext.Container,{baseCls:"x-panel",collapsedCls:"x-panel-collapsed",maskDisabled:true,animCollapse:Ext.enableFx,headerAsText:true,buttonAlign:"right",collapsed:false,collapseFirst:true,minButtonWidth:75,elements:"body",preventBodyReset:false,padding:undefined,resizeEvent:"bodyresize",toolTarget:"header",collapseEl:"bwrap",slideAnchor:"t",disabledClass:"",deferHeight:true,expandDefaults:{duration:0.25},collapseDefaults:{duration:0.25},initComponent:function(){Ext.Panel.superclass.initComponent.call(this);this.addEvents("bodyresize","titlechange","iconchange","collapse","expand","beforecollapse","beforeexpand","beforeclose","close","activate","deactivate");if(this.unstyled){this.baseCls="x-plain"}this.toolbars=[];if(this.tbar){this.elements+=",tbar";this.topToolbar=this.createToolbar(this.tbar);this.tbar=null}if(this.bbar){this.elements+=",bbar";this.bottomToolbar=this.createToolbar(this.bbar);this.bbar=null}if(this.header===true){this.elements+=",header";this.header=null}else{if(this.headerCfg||(this.title&&this.header!==false)){this.elements+=",header"}}if(this.footerCfg||this.footer===true){this.elements+=",footer";this.footer=null}if(this.buttons){this.fbar=this.buttons;this.buttons=null}if(this.fbar){this.createFbar(this.fbar)}if(this.autoLoad){this.on("render",this.doAutoLoad,this,{delay:10})}},createFbar:function(b){var a=this.minButtonWidth;this.elements+=",footer";this.fbar=this.createToolbar(b,{buttonAlign:this.buttonAlign,toolbarCls:"x-panel-fbar",enableOverflow:false,defaults:function(d){return{minWidth:d.minWidth||a}}});this.fbar.items.each(function(d){d.minWidth=d.minWidth||this.minButtonWidth},this);this.buttons=this.fbar.items.items},createToolbar:function(b,c){var a;if(Ext.isArray(b)){b={items:b}}a=b.events?Ext.apply(b,c):this.createComponent(Ext.apply({},b,c),"toolbar");this.toolbars.push(a);return a},createElement:function(a,c){if(this[a]){c.appendChild(this[a].dom);return}if(a==="bwrap"||this.elements.indexOf(a)!=-1){if(this[a+"Cfg"]){this[a]=Ext.fly(c).createChild(this[a+"Cfg"])}else{var b=document.createElement("div");b.className=this[a+"Cls"];this[a]=Ext.get(c.appendChild(b))}if(this[a+"CssClass"]){this[a].addClass(this[a+"CssClass"])}if(this[a+"Style"]){this[a].applyStyles(this[a+"Style"])}}},onRender:function(g,e){Ext.Panel.superclass.onRender.call(this,g,e);this.createClasses();var a=this.el,h=a.dom,k,i;if(this.collapsible&&!this.hideCollapseTool){this.tools=this.tools?this.tools.slice(0):[];this.tools[this.collapseFirst?"unshift":"push"]({id:"toggle",handler:this.toggleCollapse,scope:this})}if(this.tools){i=this.tools;this.elements+=(this.header!==false)?",header":""}this.tools={};a.addClass(this.baseCls);if(h.firstChild){this.header=a.down("."+this.headerCls);this.bwrap=a.down("."+this.bwrapCls);var j=this.bwrap?this.bwrap:a;this.tbar=j.down("."+this.tbarCls);this.body=j.down("."+this.bodyCls);this.bbar=j.down("."+this.bbarCls);this.footer=j.down("."+this.footerCls);this.fromMarkup=true}if(this.preventBodyReset===true){a.addClass("x-panel-reset")}if(this.cls){a.addClass(this.cls)}if(this.buttons){this.elements+=",footer"}if(this.frame){a.insertHtml("afterBegin",String.format(Ext.Element.boxMarkup,this.baseCls));this.createElement("header",h.firstChild.firstChild.firstChild);this.createElement("bwrap",h);k=this.bwrap.dom;var c=h.childNodes[1],b=h.childNodes[2];k.appendChild(c);k.appendChild(b);var l=k.firstChild.firstChild.firstChild;this.createElement("tbar",l);this.createElement("body",l);this.createElement("bbar",l);this.createElement("footer",k.lastChild.firstChild.firstChild);if(!this.footer){this.bwrap.dom.lastChild.className+=" x-panel-nofooter"}this.ft=Ext.get(this.bwrap.dom.lastChild);this.mc=Ext.get(l)}else{this.createElement("header",h);this.createElement("bwrap",h);k=this.bwrap.dom;this.createElement("tbar",k);this.createElement("body",k);this.createElement("bbar",k);this.createElement("footer",k);if(!this.header){this.body.addClass(this.bodyCls+"-noheader");if(this.tbar){this.tbar.addClass(this.tbarCls+"-noheader")}}}if(Ext.isDefined(this.padding)){this.body.setStyle("padding",this.body.addUnits(this.padding))}if(this.border===false){this.el.addClass(this.baseCls+"-noborder");this.body.addClass(this.bodyCls+"-noborder");if(this.header){this.header.addClass(this.headerCls+"-noborder")}if(this.footer){this.footer.addClass(this.footerCls+"-noborder")}if(this.tbar){this.tbar.addClass(this.tbarCls+"-noborder")}if(this.bbar){this.bbar.addClass(this.bbarCls+"-noborder")}}if(this.bodyBorder===false){this.body.addClass(this.bodyCls+"-noborder")}this.bwrap.enableDisplayMode("block");if(this.header){this.header.unselectable();if(this.headerAsText){this.header.dom.innerHTML=''+this.header.dom.innerHTML+"";if(this.iconCls){this.setIconClass(this.iconCls)}}}if(this.floating){this.makeFloating(this.floating)}if(this.collapsible&&this.titleCollapse&&this.header){this.mon(this.header,"click",this.toggleCollapse,this);this.header.setStyle("cursor","pointer")}if(i){this.addTool.apply(this,i)}if(this.fbar){this.footer.addClass("x-panel-btns");this.fbar.ownerCt=this;this.fbar.render(this.footer);this.footer.createChild({cls:"x-clear"})}if(this.tbar&&this.topToolbar){this.topToolbar.ownerCt=this;this.topToolbar.render(this.tbar)}if(this.bbar&&this.bottomToolbar){this.bottomToolbar.ownerCt=this;this.bottomToolbar.render(this.bbar)}},setIconClass:function(b){var a=this.iconCls;this.iconCls=b;if(this.rendered&&this.header){if(this.frame){this.header.addClass("x-panel-icon");this.header.replaceClass(a,this.iconCls)}else{var e=this.header,c=e.child("img.x-panel-inline-icon");if(c){Ext.fly(c).replaceClass(a,this.iconCls)}else{var d=e.child("span."+this.headerTextCls);if(d){Ext.DomHelper.insertBefore(d.dom,{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-panel-inline-icon "+this.iconCls})}}}}this.fireEvent("iconchange",this,b,a)},makeFloating:function(a){this.floating=true;this.el=new Ext.Layer(Ext.apply({},a,{shadow:Ext.isDefined(this.shadow)?this.shadow:"sides",shadowOffset:this.shadowOffset,constrain:false,shim:this.shim===false?false:undefined}),this.el)},getTopToolbar:function(){return this.topToolbar},getBottomToolbar:function(){return this.bottomToolbar},getFooterToolbar:function(){return this.fbar},addButton:function(a,c,b){if(!this.fbar){this.createFbar([])}if(c){if(Ext.isString(a)){a={text:a}}a=Ext.apply({handler:c,scope:b},a)}return this.fbar.add(a)},addTool:function(){if(!this.rendered){if(!this.tools){this.tools=[]}Ext.each(arguments,function(a){this.tools.push(a)},this);return}if(!this[this.toolTarget]){return}if(!this.toolTemplate){var h=new Ext.Template('
 
');h.disableFormats=true;h.compile();Ext.Panel.prototype.toolTemplate=h}for(var g=0,d=arguments,c=d.length;g0){Ext.each(this.toolbars,function(c){c.doLayout(undefined,a)});this.syncHeight()}},syncHeight:function(){var b=this.toolbarHeight,c=this.body,a=this.lastSize.height,d;if(this.autoHeight||!Ext.isDefined(a)||a=="auto"){return}if(b!=this.getToolbarHeight()){b=Math.max(0,a-this.getFrameHeight());c.setHeight(b);d=c.getSize();this.toolbarHeight=this.getToolbarHeight();this.onBodyResize(d.width,d.height)}},onShow:function(){if(this.floating){return this.el.show()}Ext.Panel.superclass.onShow.call(this)},onHide:function(){if(this.floating){return this.el.hide()}Ext.Panel.superclass.onHide.call(this)},createToolHandler:function(c,a,d,b){return function(g){c.removeClass(d);if(a.stopEvent!==false){g.stopEvent()}if(a.handler){a.handler.call(a.scope||c,g,c,b,a)}}},afterRender:function(){if(this.floating&&!this.hidden){this.el.show()}if(this.title){this.setTitle(this.title)}Ext.Panel.superclass.afterRender.call(this);if(this.collapsed){this.collapsed=false;this.collapse(false)}this.initEvents()},getKeyMap:function(){if(!this.keyMap){this.keyMap=new Ext.KeyMap(this.el,this.keys)}return this.keyMap},initEvents:function(){if(this.keys){this.getKeyMap()}if(this.draggable){this.initDraggable()}if(this.toolbars.length>0){Ext.each(this.toolbars,function(a){a.doLayout();a.on({scope:this,afterlayout:this.syncHeight,remove:this.syncHeight})},this);this.syncHeight()}},initDraggable:function(){this.dd=new Ext.Panel.DD(this,Ext.isBoolean(this.draggable)?null:this.draggable)},beforeEffect:function(a){if(this.floating){this.el.beforeAction()}if(a!==false){this.el.addClass("x-panel-animated")}},afterEffect:function(a){this.syncShadow();this.el.removeClass("x-panel-animated")},createEffect:function(c,b,d){var e={scope:d,block:true};if(c===true){e.callback=b;return e}else{if(!c.callback){e.callback=b}else{e.callback=function(){b.call(d);Ext.callback(c.callback,c.scope)}}}return Ext.applyIf(e,c)},collapse:function(b){if(this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforecollapse",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.beforeEffect(a);this.onCollapse(a,b);return this},onCollapse:function(a,b){if(a){this[this.collapseEl].slideOut(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterCollapse,this),this.collapseDefaults))}else{this[this.collapseEl].hide(this.hideMode);this.afterCollapse(false)}},afterCollapse:function(a){this.collapsed=true;this.el.addClass(this.collapsedCls);if(a!==false){this[this.collapseEl].hide(this.hideMode)}this.afterEffect(a);this.cascade(function(b){if(b.lastSize){b.lastSize={width:undefined,height:undefined}}});this.fireEvent("collapse",this)},expand:function(b){if(!this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforeexpand",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.el.removeClass(this.collapsedCls);this.beforeEffect(a);this.onExpand(a,b);return this},onExpand:function(a,b){if(a){this[this.collapseEl].slideIn(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterExpand,this),this.expandDefaults))}else{this[this.collapseEl].show(this.hideMode);this.afterExpand(false)}},afterExpand:function(a){this.collapsed=false;if(a!==false){this[this.collapseEl].show(this.hideMode)}this.afterEffect(a);if(this.deferLayout){delete this.deferLayout;this.doLayout(true)}this.fireEvent("expand",this)},toggleCollapse:function(a){this[this.collapsed?"expand":"collapse"](a);return this},onDisable:function(){if(this.rendered&&this.maskDisabled){this.el.mask()}Ext.Panel.superclass.onDisable.call(this)},onEnable:function(){if(this.rendered&&this.maskDisabled){this.el.unmask()}Ext.Panel.superclass.onEnable.call(this)},onResize:function(g,d,c,e){var a=g,b=d;if(Ext.isDefined(a)||Ext.isDefined(b)){if(!this.collapsed){if(Ext.isNumber(a)){this.body.setWidth(a=this.adjustBodyWidth(a-this.getFrameWidth()))}else{if(a=="auto"){a=this.body.setWidth("auto").dom.offsetWidth}else{a=this.body.dom.offsetWidth}}if(this.tbar){this.tbar.setWidth(a);if(this.topToolbar){this.topToolbar.setSize(a)}}if(this.bbar){this.bbar.setWidth(a);if(this.bottomToolbar){this.bottomToolbar.setSize(a);if(Ext.isIE){this.bbar.setStyle("position","static");this.bbar.setStyle("position","")}}}if(this.footer){this.footer.setWidth(a);if(this.fbar){this.fbar.setSize(Ext.isIE?(a-this.footer.getFrameWidth("lr")):"auto")}}if(Ext.isNumber(b)){b=Math.max(0,b-this.getFrameHeight());this.body.setHeight(b)}else{if(b=="auto"){this.body.setHeight(b)}}if(this.disabled&&this.el._mask){this.el._mask.setSize(this.el.dom.clientWidth,this.el.getHeight())}}else{this.queuedBodySize={width:a,height:b};if(!this.queuedExpand&&this.allowQueuedExpand!==false){this.queuedExpand=true;this.on("expand",function(){delete this.queuedExpand;this.onResize(this.queuedBodySize.width,this.queuedBodySize.height)},this,{single:true})}}this.onBodyResize(a,b)}this.syncShadow();Ext.Panel.superclass.onResize.call(this,g,d,c,e)},onBodyResize:function(a,b){this.fireEvent("bodyresize",this,a,b)},getToolbarHeight:function(){var a=0;if(this.rendered){Ext.each(this.toolbars,function(b){a+=b.getHeight()},this)}return a},adjustBodyHeight:function(a){return a},adjustBodyWidth:function(a){return a},onPosition:function(){this.syncShadow()},getFrameWidth:function(){var b=this.el.getFrameWidth("lr")+this.bwrap.getFrameWidth("lr");if(this.frame){var a=this.bwrap.dom.firstChild;b+=(Ext.fly(a).getFrameWidth("l")+Ext.fly(a.firstChild).getFrameWidth("r"));b+=this.mc.getFrameWidth("lr")}return b},getFrameHeight:function(){var a=Math.max(0,this.getHeight()-this.body.getHeight());if(isNaN(a)){a=0}return a},getInnerWidth:function(){return this.getSize().width-this.getFrameWidth()},getInnerHeight:function(){return this.body.getHeight()},syncShadow:function(){if(this.floating){this.el.sync(true)}},getLayoutTarget:function(){return this.body},getContentTarget:function(){return this.body},setTitle:function(b,a){this.title=b;if(this.header&&this.headerAsText){this.header.child("span").update(b)}if(a){this.setIconClass(a)}this.fireEvent("titlechange",this,b);return this},getUpdater:function(){return this.body.getUpdater()},load:function(){var a=this.body.getUpdater();a.update.apply(a,arguments);return this},beforeDestroy:function(){Ext.Panel.superclass.beforeDestroy.call(this);if(this.header){this.header.removeAllListeners()}if(this.tools){for(var a in this.tools){Ext.destroy(this.tools[a])}}if(this.toolbars.length>0){Ext.each(this.toolbars,function(b){b.un("afterlayout",this.syncHeight,this);b.un("remove",this.syncHeight,this)},this)}if(Ext.isArray(this.buttons)){while(this.buttons.length){Ext.destroy(this.buttons[0])}}if(this.rendered){Ext.destroy(this.ft,this.header,this.footer,this.tbar,this.bbar,this.body,this.mc,this.bwrap,this.dd);if(this.fbar){Ext.destroy(this.fbar,this.fbar.el)}}Ext.destroy(this.toolbars)},createClasses:function(){this.headerCls=this.baseCls+"-header";this.headerTextCls=this.baseCls+"-header-text";this.bwrapCls=this.baseCls+"-bwrap";this.tbarCls=this.baseCls+"-tbar";this.bodyCls=this.baseCls+"-body";this.bbarCls=this.baseCls+"-bbar";this.footerCls=this.baseCls+"-footer"},createGhost:function(a,e,b){var d=document.createElement("div");d.className="x-panel-ghost "+(a?a:"");if(this.header){d.appendChild(this.el.dom.firstChild.cloneNode(true))}Ext.fly(d.appendChild(document.createElement("ul"))).setHeight(this.bwrap.getHeight());d.style.width=this.el.dom.offsetWidth+"px";if(!b){this.container.dom.appendChild(d)}else{Ext.getDom(b).appendChild(d)}if(e!==false&&this.el.useShim!==false){var c=new Ext.Layer({shadow:false,useDisplay:true,constrain:false},d);c.show();return c}else{return new Ext.Element(d)}},doAutoLoad:function(){var a=this.body.getUpdater();if(this.renderer){a.setRenderer(this.renderer)}a.update(Ext.isObject(this.autoLoad)?this.autoLoad:{url:this.autoLoad})},getTool:function(a){return this.tools[a]}});Ext.reg("panel",Ext.Panel);Ext.Editor=function(b,a){if(b.field){this.field=Ext.create(b.field,"textfield");a=Ext.apply({},b);delete a.field}else{this.field=b}Ext.Editor.superclass.constructor.call(this,a)};Ext.extend(Ext.Editor,Ext.Component,{allowBlur:true,value:"",alignment:"c-c?",offsets:[0,0],shadow:"frame",constrain:false,swallowKeys:true,completeOnEnter:true,cancelOnEsc:true,updateEl:false,initComponent:function(){Ext.Editor.superclass.initComponent.call(this);this.addEvents("beforestartedit","startedit","beforecomplete","complete","canceledit","specialkey")},onRender:function(b,a){this.el=new Ext.Layer({shadow:this.shadow,cls:"x-editor",parentEl:b,shim:this.shim,shadowOffset:this.shadowOffset||4,id:this.id,constrain:this.constrain});if(this.zIndex){this.el.setZIndex(this.zIndex)}this.el.setStyle("overflow",Ext.isGecko?"auto":"hidden");if(this.field.msgTarget!="title"){this.field.msgTarget="qtip"}this.field.inEditor=true;this.mon(this.field,{scope:this,blur:this.onBlur,specialkey:this.onSpecialKey});if(this.field.grow){this.mon(this.field,"autosize",this.el.sync,this.el,{delay:1})}this.field.render(this.el).show();this.field.getEl().dom.name="";if(this.swallowKeys){this.field.el.swallowEvent(["keypress","keydown"])}},onSpecialKey:function(g,d){var b=d.getKey(),a=this.completeOnEnter&&b==d.ENTER,c=this.cancelOnEsc&&b==d.ESC;if(a||c){d.stopEvent();if(a){this.completeEdit()}else{this.cancelEdit()}if(g.triggerBlur){g.triggerBlur()}}this.fireEvent("specialkey",g,d)},startEdit:function(b,c){if(this.editing){this.completeEdit()}this.boundEl=Ext.get(b);var a=c!==undefined?c:this.boundEl.dom.innerHTML;if(!this.rendered){this.render(this.parentEl||document.body)}if(this.fireEvent("beforestartedit",this,this.boundEl,a)!==false){this.startValue=a;this.field.reset();this.field.setValue(a);this.realign(true);this.editing=true;this.show()}},doAutoSize:function(){if(this.autoSize){var b=this.boundEl.getSize(),a=this.field.getSize();switch(this.autoSize){case"width":this.setSize(b.width,a.height);break;case"height":this.setSize(a.width,b.height);break;case"none":this.setSize(a.width,a.height);break;default:this.setSize(b.width,b.height)}}},setSize:function(a,b){delete this.field.lastSize;this.field.setSize(a,b);if(this.el){if(Ext.isGecko2||Ext.isOpera){this.el.setSize(a,b)}this.el.sync()}},realign:function(a){if(a===true){this.doAutoSize()}this.el.alignTo(this.boundEl,this.alignment,this.offsets)},completeEdit:function(a){if(!this.editing){return}if(this.field.assertValue){this.field.assertValue()}var b=this.getValue();if(!this.field.isValid()){if(this.revertInvalid!==false){this.cancelEdit(a)}return}if(String(b)===String(this.startValue)&&this.ignoreNoChange){this.hideEdit(a);return}if(this.fireEvent("beforecomplete",this,b,this.startValue)!==false){b=this.getValue();if(this.updateEl&&this.boundEl){this.boundEl.update(b)}this.hideEdit(a);this.fireEvent("complete",this,b,this.startValue)}},onShow:function(){this.el.show();if(this.hideEl!==false){this.boundEl.hide()}this.field.show().focus(false,true);this.fireEvent("startedit",this.boundEl,this.startValue)},cancelEdit:function(a){if(this.editing){var b=this.getValue();this.setValue(this.startValue);this.hideEdit(a);this.fireEvent("canceledit",this,b,this.startValue)}},hideEdit:function(a){if(a!==true){this.editing=false;this.hide()}},onBlur:function(){if(this.allowBlur===true&&this.editing&&this.selectSameEditor!==true){this.completeEdit()}},onHide:function(){if(this.editing){this.completeEdit();return}this.field.blur();if(this.field.collapse){this.field.collapse()}this.el.hide();if(this.hideEl!==false){this.boundEl.show()}},setValue:function(a){this.field.setValue(a)},getValue:function(){return this.field.getValue()},beforeDestroy:function(){Ext.destroyMembers(this,"field");delete this.parentEl;delete this.boundEl}});Ext.reg("editor",Ext.Editor);Ext.ColorPalette=Ext.extend(Ext.Component,{itemCls:"x-color-palette",value:null,clickEvent:"click",ctype:"Ext.ColorPalette",allowReselect:false,colors:["000000","993300","333300","003300","003366","000080","333399","333333","800000","FF6600","808000","008000","008080","0000FF","666699","808080","FF0000","FF9900","99CC00","339966","33CCCC","3366FF","800080","969696","FF00FF","FFCC00","FFFF00","00FF00","00FFFF","00CCFF","993366","C0C0C0","FF99CC","FFCC99","FFFF99","CCFFCC","CCFFFF","99CCFF","CC99FF","FFFFFF"],initComponent:function(){Ext.ColorPalette.superclass.initComponent.call(this);this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope,true)}},onRender:function(b,a){this.autoEl={tag:"div",cls:this.itemCls};Ext.ColorPalette.superclass.onRender.call(this,b,a);var c=this.tpl||new Ext.XTemplate(' ');c.overwrite(this.el,this.colors);this.mon(this.el,this.clickEvent,this.handleClick,this,{delegate:"a"});if(this.clickEvent!="click"){this.mon(this.el,"click",Ext.emptyFn,this,{delegate:"a",preventDefault:true})}},afterRender:function(){Ext.ColorPalette.superclass.afterRender.call(this);if(this.value){var a=this.value;this.value=null;this.select(a,true)}},handleClick:function(b,a){b.preventDefault();if(!this.disabled){var d=a.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];this.select(d.toUpperCase())}},select:function(b,a){b=b.replace("#","");if(b!=this.value||this.allowReselect){var c=this.el;if(this.value){c.child("a.color-"+this.value).removeClass("x-color-palette-sel")}c.child("a.color-"+b).addClass("x-color-palette-sel");this.value=b;if(a!==true){this.fireEvent("select",this,b)}}}});Ext.reg("colorpalette",Ext.ColorPalette);Ext.DatePicker=Ext.extend(Ext.BoxComponent,{todayText:"Today",okText:" OK ",cancelText:"Cancel",todayTip:"{0} (Spacebar)",minText:"This date is before the minimum date",maxText:"This date is after the maximum date",format:"m/d/y",disabledDaysText:"Disabled",disabledDatesText:"Disabled",monthNames:Date.monthNames,dayNames:Date.dayNames,nextText:"Next Month (Control+Right)",prevText:"Previous Month (Control+Left)",monthYearText:"Choose a month (Control+Up/Down to move years)",startDay:0,showToday:true,focusOnSelect:true,initHour:12,initComponent:function(){Ext.DatePicker.superclass.initComponent.call(this);this.value=this.value?this.value.clearTime(true):new Date().clearTime();this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope||this)}this.initDisabledDays()},initDisabledDays:function(){if(!this.disabledDatesRE&&this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){if(Ext.isArray(a)){this.disabledDates=a;this.disabledDatesRE=null}else{this.disabledDatesRE=a}this.initDisabledDays();this.update(this.value,true)},setDisabledDays:function(a){this.disabledDays=a;this.update(this.value,true)},setMinDate:function(a){this.minDate=a;this.update(this.value,true)},setMaxDate:function(a){this.maxDate=a;this.update(this.value,true)},setValue:function(a){this.value=a.clearTime(true);this.update(this.value)},getValue:function(){return this.value},focus:function(){this.update(this.activeDate)},onEnable:function(a){Ext.DatePicker.superclass.onEnable.call(this);this.doDisabled(false);this.update(a?this.value:this.activeDate);if(Ext.isIE){this.el.repaint()}},onDisable:function(){Ext.DatePicker.superclass.onDisable.call(this);this.doDisabled(true);if(Ext.isIE&&!Ext.isIE8){Ext.each([].concat(this.textNodes,this.el.query("th span")),function(a){Ext.fly(a).repaint()})}},doDisabled:function(a){this.keyNav.setDisabled(a);this.prevRepeater.setDisabled(a);this.nextRepeater.setDisabled(a);if(this.showToday){this.todayKeyListener.setDisabled(a);this.todayBtn.setDisabled(a)}},onRender:function(e,b){var a=['','','",this.showToday?'':"",'
  
'],c=this.dayNames,h;for(h=0;h<7;h++){var k=this.startDay+h;if(k>6){k=k-7}a.push("")}a[a.length]="";for(h=0;h<42;h++){if(h%7===0&&h!==0){a[a.length]=""}a[a.length]=''}a.push("
",c[k].substr(0,1),"
');var j=document.createElement("div");j.className="x-date-picker";j.innerHTML=a.join("");e.dom.insertBefore(j,b);this.el=Ext.get(j);this.eventEl=Ext.get(j.firstChild);this.prevRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"),{handler:this.showPrevMonth,scope:this,preventDefault:true,stopDefault:true});this.nextRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"),{handler:this.showNextMonth,scope:this,preventDefault:true,stopDefault:true});this.monthPicker=this.el.down("div.x-date-mp");this.monthPicker.enableDisplayMode("block");this.keyNav=new Ext.KeyNav(this.eventEl,{left:function(d){if(d.ctrlKey){this.showPrevMonth()}else{this.update(this.activeDate.add("d",-1))}},right:function(d){if(d.ctrlKey){this.showNextMonth()}else{this.update(this.activeDate.add("d",1))}},up:function(d){if(d.ctrlKey){this.showNextYear()}else{this.update(this.activeDate.add("d",-7))}},down:function(d){if(d.ctrlKey){this.showPrevYear()}else{this.update(this.activeDate.add("d",7))}},pageUp:function(d){this.showNextMonth()},pageDown:function(d){this.showPrevMonth()},enter:function(d){d.stopPropagation();return true},scope:this});this.el.unselectable();this.cells=this.el.select("table.x-date-inner tbody td");this.textNodes=this.el.query("table.x-date-inner tbody span");this.mbtn=new Ext.Button({text:" ",tooltip:this.monthYearText,renderTo:this.el.child("td.x-date-middle",true)});this.mbtn.el.child("em").addClass("x-btn-arrow");if(this.showToday){this.todayKeyListener=this.eventEl.addKeyListener(Ext.EventObject.SPACE,this.selectToday,this);var g=(new Date()).dateFormat(this.format);this.todayBtn=new Ext.Button({renderTo:this.el.child("td.x-date-bottom",true),text:String.format(this.todayText,g),tooltip:String.format(this.todayTip,g),handler:this.selectToday,scope:this})}this.mon(this.eventEl,"mousewheel",this.handleMouseWheel,this);this.mon(this.eventEl,"click",this.handleDateClick,this,{delegate:"a.x-date-date"});this.mon(this.mbtn,"click",this.showMonthPicker,this);this.onEnable(true)},createMonthPicker:function(){if(!this.monthPicker.dom.firstChild){var a=[''];for(var b=0;b<6;b++){a.push('",'",b===0?'':'')}a.push('","
',Date.getShortMonthName(b),"',Date.getShortMonthName(b+6),"
");this.monthPicker.update(a.join(""));this.mon(this.monthPicker,"click",this.onMonthClick,this);this.mon(this.monthPicker,"dblclick",this.onMonthDblClick,this);this.mpMonths=this.monthPicker.select("td.x-date-mp-month");this.mpYears=this.monthPicker.select("td.x-date-mp-year");this.mpMonths.each(function(c,d,e){e+=1;if((e%2)===0){c.dom.xmonth=5+Math.round(e*0.5)}else{c.dom.xmonth=Math.round((e-1)*0.5)}})}},showMonthPicker:function(){if(!this.disabled){this.createMonthPicker();var a=this.el.getSize();this.monthPicker.setSize(a);this.monthPicker.child("table").setSize(a);this.mpSelMonth=(this.activeDate||this.value).getMonth();this.updateMPMonth(this.mpSelMonth);this.mpSelYear=(this.activeDate||this.value).getFullYear();this.updateMPYear(this.mpSelYear);this.monthPicker.slideIn("t",{duration:0.2})}},updateMPYear:function(e){this.mpyear=e;var c=this.mpYears.elements;for(var b=1;b<=10;b++){var d=c[b-1],a;if((b%2)===0){a=e+Math.round(b*0.5);d.firstChild.innerHTML=a;d.xyear=a}else{a=e-(5-Math.round(b*0.5));d.firstChild.innerHTML=a;d.xyear=a}this.mpYears.item(b-1)[a==this.mpSelYear?"addClass":"removeClass"]("x-date-mp-sel")}},updateMPMonth:function(a){this.mpMonths.each(function(b,c,d){b[b.dom.xmonth==a?"addClass":"removeClass"]("x-date-mp-sel")})},selectMPMonth:function(a){},onMonthClick:function(g,b){g.stopEvent();var c=new Ext.Element(b),a;if(c.is("button.x-date-mp-cancel")){this.hideMonthPicker()}else{if(c.is("button.x-date-mp-ok")){var h=new Date(this.mpSelYear,this.mpSelMonth,(this.activeDate||this.value).getDate());if(h.getMonth()!=this.mpSelMonth){h=new Date(this.mpSelYear,this.mpSelMonth,1).getLastDateOfMonth()}this.update(h);this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-month",2))){this.mpMonths.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelMonth=a.dom.xmonth}else{if((a=c.up("td.x-date-mp-year",2))){this.mpYears.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelYear=a.dom.xyear}else{if(c.is("a.x-date-mp-prev")){this.updateMPYear(this.mpyear-10)}else{if(c.is("a.x-date-mp-next")){this.updateMPYear(this.mpyear+10)}}}}}}},onMonthDblClick:function(d,b){d.stopEvent();var c=new Ext.Element(b),a;if((a=c.up("td.x-date-mp-month",2))){this.update(new Date(this.mpSelYear,a.dom.xmonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-year",2))){this.update(new Date(a.dom.xyear,this.mpSelMonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}}},hideMonthPicker:function(a){if(this.monthPicker){if(a===true){this.monthPicker.hide()}else{this.monthPicker.slideOut("t",{duration:0.2})}}},showPrevMonth:function(a){this.update(this.activeDate.add("mo",-1))},showNextMonth:function(a){this.update(this.activeDate.add("mo",1))},showPrevYear:function(){this.update(this.activeDate.add("y",-1))},showNextYear:function(){this.update(this.activeDate.add("y",1))},handleMouseWheel:function(a){a.stopEvent();if(!this.disabled){var b=a.getWheelDelta();if(b>0){this.showPrevMonth()}else{if(b<0){this.showNextMonth()}}}},handleDateClick:function(b,a){b.stopEvent();if(!this.disabled&&a.dateValue&&!Ext.fly(a.parentNode).hasClass("x-date-disabled")){this.cancelFocus=this.focusOnSelect===false;this.setValue(new Date(a.dateValue));delete this.cancelFocus;this.fireEvent("select",this,this.value)}},selectToday:function(){if(this.todayBtn&&!this.todayBtn.disabled){this.setValue(new Date().clearTime());this.fireEvent("select",this,this.value)}},update:function(G,A){if(this.rendered){var a=this.activeDate,p=this.isVisible();this.activeDate=G;if(!A&&a&&this.el){var o=G.getTime();if(a.getMonth()==G.getMonth()&&a.getFullYear()==G.getFullYear()){this.cells.removeClass("x-date-selected");this.cells.each(function(d){if(d.dom.firstChild.dateValue==o){d.addClass("x-date-selected");if(p&&!this.cancelFocus){Ext.fly(d.dom.firstChild).focus(50)}return false}},this);return}}var k=G.getDaysInMonth(),q=G.getFirstDateOfMonth(),g=q.getDay()-this.startDay;if(g<0){g+=7}k+=g;var B=G.add("mo",-1),h=B.getDaysInMonth()-g,e=this.cells.elements,r=this.textNodes,D=(new Date(B.getFullYear(),B.getMonth(),h,this.initHour)),C=new Date().clearTime().getTime(),v=G.clearTime(true).getTime(),u=this.minDate?this.minDate.clearTime(true):Number.NEGATIVE_INFINITY,y=this.maxDate?this.maxDate.clearTime(true):Number.POSITIVE_INFINITY,F=this.disabledDatesRE,s=this.disabledDatesText,I=this.disabledDays?this.disabledDays.join(""):false,E=this.disabledDaysText,z=this.format;if(this.showToday){var m=new Date().clearTime(),c=(my||(F&&z&&F.test(m.dateFormat(z)))||(I&&I.indexOf(m.getDay())!=-1));if(!this.disabled){this.todayBtn.setDisabled(c);this.todayKeyListener[c?"disable":"enable"]()}}var l=function(J,d){d.title="";var i=D.clearTime(true).getTime();d.firstChild.dateValue=i;if(i==C){d.className+=" x-date-today";d.title=J.todayText}if(i==v){d.className+=" x-date-selected";if(p){Ext.fly(d.firstChild).focus(50)}}if(iy){d.className=" x-date-disabled";d.title=J.maxText;return}if(I){if(I.indexOf(D.getDay())!=-1){d.title=E;d.className=" x-date-disabled"}}if(F&&z){var w=D.dateFormat(z);if(F.test(w)){d.title=s.replace("%0",w);d.className=" x-date-disabled"}}};var x=0;for(;x=a.value){d=a.value}}c.setValue(b,d,false);c.fireEvent("drag",c,g,this)},getNewValue:function(){var a=this.slider,b=a.innerEl.translatePoints(this.tracker.getXY());return Ext.util.Format.round(a.reverseValue(b.left),a.decimalPrecision)},onDragEnd:function(c){var a=this.slider,b=this.value;this.el.removeClass("x-slider-thumb-drag");this.dragging=false;a.fireEvent("dragend",a,c);if(this.dragStartValue!=b){a.fireEvent("changecomplete",a,b,this)}}});Ext.slider.MultiSlider=Ext.extend(Ext.BoxComponent,{vertical:false,minValue:0,maxValue:100,decimalPrecision:0,keyIncrement:1,increment:0,clickRange:[5,15],clickToChange:true,animate:true,dragging:false,constrainThumbs:true,topThumbZIndex:10000,initComponent:function(){if(!Ext.isDefined(this.value)){this.value=this.minValue}this.thumbs=[];Ext.slider.MultiSlider.superclass.initComponent.call(this);this.keyIncrement=Math.max(this.increment,this.keyIncrement);this.addEvents("beforechange","change","changecomplete","dragstart","drag","dragend");if(this.values==undefined||Ext.isEmpty(this.values)){this.values=[0]}var a=this.values;for(var b=0;bthis.clickRange[0]&&c.top=c){d+=c}else{if(a*2<-c){d-=c}}}return d.constrain(this.minValue,this.maxValue)},afterRender:function(){Ext.slider.MultiSlider.superclass.afterRender.apply(this,arguments);for(var c=0;ce?e:c.value}this.syncThumb()},setValue:function(d,c,b,g){var a=this.thumbs[d],e=a.el;c=this.normalizeValue(c);if(c!==a.value&&this.fireEvent("beforechange",this,c,a.value,a)!==false){a.value=c;if(this.rendered){this.moveThumb(d,this.translateValue(c),b!==false);this.fireEvent("change",this,c,a);if(g){this.fireEvent("changecomplete",this,c,a)}}}},translateValue:function(a){var b=this.getRatio();return(a*b)-(this.minValue*b)-this.halfThumb},reverseValue:function(b){var a=this.getRatio();return(b+(this.minValue*a))/a},moveThumb:function(d,c,b){var a=this.thumbs[d].el;if(!b||this.animate===false){a.setLeft(c)}else{a.shift({left:c,stopFx:true,duration:0.35})}},focus:function(){this.focusEl.focus(10)},onResize:function(c,e){var b=this.thumbs,a=b.length,d=0;for(;dthis.clickRange[0]&&c.left','
','
','
',"
 
","
","
",'
',"
 
","
","
","");this.el=a?c.insertBefore(a,{cls:this.baseCls},true):c.append(d,{cls:this.baseCls},true);if(this.id){this.el.dom.id=this.id}var b=this.el.dom.firstChild;this.progressBar=Ext.get(b.firstChild);if(this.textEl){this.textEl=Ext.get(this.textEl);delete this.textTopEl}else{this.textTopEl=Ext.get(this.progressBar.dom.firstChild);var e=Ext.get(b.childNodes[1]);this.textTopEl.setStyle("z-index",99).addClass("x-hidden");this.textEl=new Ext.CompositeElement([this.textTopEl.dom.firstChild,e.dom.firstChild]);this.textEl.setWidth(b.offsetWidth)}this.progressBar.setHeight(b.offsetHeight)},afterRender:function(){Ext.ProgressBar.superclass.afterRender.call(this);if(this.value){this.updateProgress(this.value,this.text)}else{this.updateText(this.text)}},updateProgress:function(c,d,b){this.value=c||0;if(d){this.updateText(d)}if(this.rendered&&!this.isDestroyed){var a=Math.floor(c*this.el.dom.firstChild.offsetWidth);this.progressBar.setWidth(a,b===true||(b!==false&&this.animate));if(this.textTopEl){this.textTopEl.removeClass("x-hidden").setWidth(a)}}this.fireEvent("update",this,c,d);return this},wait:function(b){if(!this.waitTimer){var a=this;b=b||{};this.updateText(b.text);this.waitTimer=Ext.TaskMgr.start({run:function(c){var d=b.increment||10;c-=1;this.updateProgress(((((c+d)%d)+1)*(100/d))*0.01,null,b.animate)},interval:b.interval||1000,duration:b.duration,onStop:function(){if(b.fn){b.fn.apply(b.scope||this)}this.reset()},scope:a})}return this},isWaiting:function(){return this.waitTimer!==null},updateText:function(a){this.text=a||" ";if(this.rendered){this.textEl.update(this.text)}return this},syncProgressBar:function(){if(this.value){this.updateProgress(this.value,this.text)}return this},setSize:function(a,c){Ext.ProgressBar.superclass.setSize.call(this,a,c);if(this.textTopEl){var b=this.el.dom.firstChild;this.textEl.setSize(b.offsetWidth,b.offsetHeight)}this.syncProgressBar();return this},reset:function(a){this.updateProgress(0);if(this.textTopEl){this.textTopEl.addClass("x-hidden")}this.clearTimer();if(a===true){this.hide()}return this},clearTimer:function(){if(this.waitTimer){this.waitTimer.onStop=null;Ext.TaskMgr.stop(this.waitTimer);this.waitTimer=null}},onDestroy:function(){this.clearTimer();if(this.rendered){if(this.textEl.isComposite){this.textEl.clear()}Ext.destroyMembers(this,"textEl","progressBar","textTopEl")}Ext.ProgressBar.superclass.onDestroy.call(this)}});Ext.reg("progress",Ext.ProgressBar);(function(){var a=Ext.EventManager;var b=Ext.lib.Dom;Ext.dd.DragDrop=function(e,c,d){if(e){this.init(e,c,d)}};Ext.dd.DragDrop.prototype={id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true},moveOnly:false,unlock:function(){this.locked=false},isTarget:true,padding:null,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,b4StartDrag:function(c,d){},startDrag:function(c,d){},b4Drag:function(c){},onDrag:function(c){},onDragEnter:function(c,d){},b4DragOver:function(c){},onDragOver:function(c,d){},b4DragOut:function(c){},onDragOut:function(c,d){},b4DragDrop:function(c){},onDragDrop:function(c,d){},onInvalidDrop:function(c){},b4EndDrag:function(c){},endDrag:function(c){},b4MouseDown:function(c){},onMouseDown:function(c){},onMouseUp:function(c){},onAvailable:function(){},defaultPadding:{left:0,right:0,top:0,bottom:0},constrainTo:function(j,h,o){if(Ext.isNumber(h)){h={left:h,right:h,top:h,bottom:h}}h=h||this.defaultPadding;var l=Ext.get(this.getEl()).getBox(),d=Ext.get(j),n=d.getScroll(),k,e=d.dom;if(e==document.body){k={x:n.left,y:n.top,width:Ext.lib.Dom.getViewWidth(),height:Ext.lib.Dom.getViewHeight()}}else{var m=d.getXY();k={x:m[0],y:m[1],width:e.clientWidth,height:e.clientHeight}}var i=l.y-k.y,g=l.x-k.x;this.resetConstraints();this.setXConstraint(g-(h.left||0),k.width-g-l.width-(h.right||0),this.xTickSize);this.setYConstraint(i-(h.top||0),k.height-i-l.height-(h.bottom||0),this.yTickSize)},getEl:function(){if(!this._domRef){this._domRef=Ext.getDom(this.id)}return this._domRef},getDragEl:function(){return Ext.getDom(this.dragElId)},init:function(e,c,d){this.initTarget(e,c,d);a.on(this.id,"mousedown",this.handleMouseDown,this)},initTarget:function(e,c,d){this.config=d||{};this.DDM=Ext.dd.DDM;this.groups={};if(typeof e!=="string"){e=Ext.id(e)}this.id=e;this.addToGroup((c)?c:"default");this.handleElId=e;this.setDragElId(e);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();this.handleOnAvailable()},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false)},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable()},setPadding:function(e,c,g,d){if(!c&&0!==c){this.padding=[e,e,e,e]}else{if(!g&&0!==g){this.padding=[e,c,e,c]}else{this.padding=[e,c,g,d]}}},setInitPosition:function(g,e){var h=this.getEl();if(!this.DDM.verifyEl(h)){return}var d=g||0;var c=e||0;var i=b.getXY(h);this.initPageX=i[0]-d;this.initPageY=i[1]-c;this.lastPageX=i[0];this.lastPageY=i[1];this.setStartPosition(i)},setStartPosition:function(d){var c=d||b.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=c[0];this.startPageY=c[1]},addToGroup:function(c){this.groups[c]=true;this.DDM.regDragDrop(this,c)},removeFromGroup:function(c){if(this.groups[c]){delete this.groups[c]}this.DDM.removeDDFromGroup(this,c)},setDragElId:function(c){this.dragElId=c},setHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.handleElId=c;this.DDM.regHandle(this.id,c)},setOuterHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}a.on(c,"mousedown",this.handleMouseDown,this);this.setHandleElId(c);this.hasOuterHandles=true},unreg:function(){a.un(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this)},destroy:function(){this.unreg()},isLocked:function(){return(this.DDM.isLocked()||this.locked)},handleMouseDown:function(g,d){if(this.primaryButtonOnly&&g.button!=0){return}if(this.isLocked()){return}this.DDM.refreshCache(this.groups);var c=new Ext.lib.Point(Ext.lib.Event.getPageX(g),Ext.lib.Event.getPageY(g));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(c,this)){}else{if(this.clickValidator(g)){this.setStartPosition();this.b4MouseDown(g);this.onMouseDown(g);this.DDM.handleMouseDown(g,this);this.DDM.stopEvent(g)}else{}}},clickValidator:function(d){var c=d.getTarget();return(this.isValidHandleChild(c)&&(this.id==this.handleElId||this.DDM.handleWasClicked(c,this.id)))},addInvalidHandleType:function(c){var d=c.toUpperCase();this.invalidHandleTypes[d]=d},addInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.invalidHandleIds[c]=c},addInvalidHandleClass:function(c){this.invalidHandleClasses.push(c)},removeInvalidHandleType:function(c){var d=c.toUpperCase();delete this.invalidHandleTypes[d]},removeInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}delete this.invalidHandleIds[c]},removeInvalidHandleClass:function(d){for(var e=0,c=this.invalidHandleClasses.length;e=this.minX;d=d-c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}for(d=this.initPageX;d<=this.maxX;d=d+c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}this.xTicks.sort(this.DDM.numericSort)},setYTicks:function(g,c){this.yTicks=[];this.yTickSize=c;var e={};for(var d=this.initPageY;d>=this.minY;d=d-c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}for(d=this.initPageY;d<=this.maxY;d=d+c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}this.yTicks.sort(this.DDM.numericSort)},setXConstraint:function(e,d,c){this.leftConstraint=e;this.rightConstraint=d;this.minX=this.initPageX-e;this.maxX=this.initPageX+d;if(c){this.setXTicks(this.initPageX,c)}this.constrainX=true},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks()},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0},setYConstraint:function(c,e,d){this.topConstraint=c;this.bottomConstraint=e;this.minY=this.initPageY-c;this.maxY=this.initPageY+e;if(d){this.setYTicks(this.initPageY,d)}this.constrainY=true},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var d=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var c=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(d,c)}else{this.setInitPosition()}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize)}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize)}},getTick:function(k,g){if(!g){return k}else{if(g[0]>=k){return g[0]}else{for(var d=0,c=g.length;d=k){var j=k-g[d];var h=g[e]-k;return(h>j)?g[d]:g[e]}}return g[g.length-1]}}},toString:function(){return("DragDrop "+this.id)}}})();if(!Ext.dd.DragDropMgr){Ext.dd.DragDropMgr=function(){var a=Ext.EventManager;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,init:function(){this.initialized=true},POINT:0,INTERSECT:1,mode:0,_execOnAll:function(d,c){for(var e in this.ids){for(var b in this.ids[e]){var g=this.ids[e][b];if(!this.isTypeOfDD(g)){continue}g[d].apply(g,c)}}},_onLoad:function(){this.init();a.on(document,"mouseup",this.handleMouseUp,this,true);a.on(document,"mousemove",this.handleMouseMove,this,true);a.on(window,"unload",this._onUnload,this,true);a.on(window,"resize",this._onResize,this,true)},_onResize:function(b){this._execOnAll("resetConstraints",[])},lock:function(){this.locked=true},unlock:function(){this.locked=false},isLocked:function(){return this.locked},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:350,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,regDragDrop:function(c,b){if(!this.initialized){this.init()}if(!this.ids[b]){this.ids[b]={}}this.ids[b][c.id]=c},removeDDFromGroup:function(d,b){if(!this.ids[b]){this.ids[b]={}}var c=this.ids[b];if(c&&c[d.id]){delete c[d.id]}},_remove:function(c){for(var b in c.groups){if(b&&this.ids[b]&&this.ids[b][c.id]){delete this.ids[b][c.id]}}delete this.handleIds[c.id]},regHandle:function(c,b){if(!this.handleIds[c]){this.handleIds[c]={}}this.handleIds[c][b]=b},isDragDrop:function(b){return(this.getDDById(b))?true:false},getRelated:function(h,c){var g=[];for(var e in h.groups){for(var d in this.ids[e]){var b=this.ids[e][d];if(!this.isTypeOfDD(b)){continue}if(!c||b.isTarget){g[g.length]=b}}}return g},isLegalTarget:function(g,e){var c=this.getRelated(g,true);for(var d=0,b=c.length;dthis.clickPixelThresh||b>this.clickPixelThresh){this.startDrag(this.startX,this.startY)}}if(this.dragThreshMet){this.dragCurrent.b4Drag(d);this.dragCurrent.onDrag(d);if(!this.dragCurrent.moveOnly){this.fireEvents(d,false)}}this.stopEvent(d);return true},fireEvents:function(n,o){var q=this.dragCurrent;if(!q||q.isLocked()){return}var r=n.getPoint();var b=[];var g=[];var l=[];var j=[];var d=[];for(var h in this.dragOvers){var c=this.dragOvers[h];if(!this.isTypeOfDD(c)){continue}if(!this.isOverTarget(r,c,this.mode)){g.push(c)}b[h]=true;delete this.dragOvers[h]}for(var p in q.groups){if("string"!=typeof p){continue}for(h in this.ids[p]){var k=this.ids[p][h];if(!this.isTypeOfDD(k)){continue}if(k.isTarget&&!k.isLocked()&&((k!=q)||(q.ignoreSelf===false))){if(this.isOverTarget(r,k,this.mode)){if(o){j.push(k)}else{if(!b[k.id]){d.push(k)}else{l.push(k)}this.dragOvers[k.id]=k}}}}}if(this.mode){if(g.length){q.b4DragOut(n,g);q.onDragOut(n,g)}if(d.length){q.onDragEnter(n,d)}if(l.length){q.b4DragOver(n,l);q.onDragOver(n,l)}if(j.length){q.b4DragDrop(n,j);q.onDragDrop(n,j)}}else{var m=0;for(h=0,m=g.length;h2000){}else{setTimeout(b._addListeners,10);if(document&&document.body){b._timeoutCount+=1}}}},handleWasClicked:function(b,d){if(this.isHandle(d,b.id)){return true}else{var c=b.parentNode;while(c){if(this.isHandle(d,c.id)){return true}else{c=c.parentNode}}}return false}}}();Ext.dd.DDM=Ext.dd.DragDropMgr;Ext.dd.DDM._addListeners()}Ext.dd.DD=function(c,a,b){if(c){this.init(c,a,b)}};Ext.extend(Ext.dd.DD,Ext.dd.DragDrop,{scroll:true,autoOffset:function(c,b){var a=c-this.startPageX;var d=b-this.startPageY;this.setDelta(a,d)},setDelta:function(b,a){this.deltaX=b;this.deltaY=a},setDragElPos:function(c,b){var a=this.getDragEl();this.alignElWithMouse(a,c,b)},alignElWithMouse:function(c,h,g){var e=this.getTargetCoord(h,g);var b=c.dom?c:Ext.fly(c,"_dd");if(!this.deltaSetXY){var i=[e.x,e.y];b.setXY(i);var d=b.getLeft(true);var a=b.getTop(true);this.deltaSetXY=[d-e.x,a-e.y]}else{b.setLeftTop(e.x+this.deltaSetXY[0],e.y+this.deltaSetXY[1])}this.cachePosition(e.x,e.y);this.autoScroll(e.x,e.y,c.offsetHeight,c.offsetWidth);return e},cachePosition:function(b,a){if(b){this.lastPageX=b;this.lastPageY=a}else{var c=Ext.lib.Dom.getXY(this.getEl());this.lastPageX=c[0];this.lastPageY=c[1]}},autoScroll:function(l,k,e,m){if(this.scroll){var n=Ext.lib.Dom.getViewHeight();var b=Ext.lib.Dom.getViewWidth();var p=this.DDM.getScrollTop();var d=this.DDM.getScrollLeft();var j=e+k;var o=m+l;var i=(n+p-k-this.deltaY);var g=(b+d-l-this.deltaX);var c=40;var a=(document.all)?80:30;if(j>n&&i0&&k-pb&&g0&&l-dthis.maxX){a=this.maxX}}if(this.constrainY){if(dthis.maxY){d=this.maxY}}a=this.getTick(a,this.xTicks);d=this.getTick(d,this.yTicks);return{x:a,y:d}},applyConfig:function(){Ext.dd.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false)},b4MouseDown:function(a){this.autoOffset(a.getPageX(),a.getPageY())},b4Drag:function(a){this.setDragElPos(a.getPageX(),a.getPageY())},toString:function(){return("DD "+this.id)}});Ext.dd.DDProxy=function(c,a,b){if(c){this.init(c,a,b);this.initFrame()}};Ext.dd.DDProxy.dragElId="ygddfdiv";Ext.extend(Ext.dd.DDProxy,Ext.dd.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var b=this;var a=document.body;if(!a||!a.firstChild){setTimeout(function(){b.createFrame()},50);return}var d=this.getDragEl();if(!d){d=document.createElement("div");d.id=this.dragElId;var c=d.style;c.position="absolute";c.visibility="hidden";c.cursor="move";c.border="2px solid #aaa";c.zIndex=999;a.insertBefore(d,a.firstChild)}},initFrame:function(){this.createFrame()},applyConfig:function(){Ext.dd.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||Ext.dd.DDProxy.dragElId)},showFrame:function(e,d){var c=this.getEl();var a=this.getDragEl();var b=a.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(b.width,10)/2),Math.round(parseInt(b.height,10)/2))}this.setDragElPos(e,d);Ext.fly(a).show()},_resizeProxy:function(){if(this.resizeFrame){var a=this.getEl();Ext.fly(this.getDragEl()).setSize(a.offsetWidth,a.offsetHeight)}},b4MouseDown:function(b){var a=b.getPageX();var c=b.getPageY();this.autoOffset(a,c);this.setDragElPos(a,c)},b4StartDrag:function(a,b){this.showFrame(a,b)},b4EndDrag:function(a){Ext.fly(this.getDragEl()).hide()},endDrag:function(c){var b=this.getEl();var a=this.getDragEl();a.style.visibility="";this.beforeMove();b.style.visibility="hidden";Ext.dd.DDM.moveToEl(b,a);a.style.visibility="hidden";b.style.visibility="";this.afterDrag()},beforeMove:function(){},afterDrag:function(){},toString:function(){return("DDProxy "+this.id)}});Ext.dd.DDTarget=function(c,a,b){if(c){this.initTarget(c,a,b)}};Ext.extend(Ext.dd.DDTarget,Ext.dd.DragDrop,{getDragEl:Ext.emptyFn,isValidHandleChild:Ext.emptyFn,startDrag:Ext.emptyFn,endDrag:Ext.emptyFn,onDrag:Ext.emptyFn,onDragDrop:Ext.emptyFn,onDragEnter:Ext.emptyFn,onDragOut:Ext.emptyFn,onDragOver:Ext.emptyFn,onInvalidDrop:Ext.emptyFn,onMouseDown:Ext.emptyFn,onMouseUp:Ext.emptyFn,setXConstraint:Ext.emptyFn,setYConstraint:Ext.emptyFn,resetConstraints:Ext.emptyFn,clearConstraints:Ext.emptyFn,clearTicks:Ext.emptyFn,setInitPosition:Ext.emptyFn,setDragElId:Ext.emptyFn,setHandleElId:Ext.emptyFn,setOuterHandleElId:Ext.emptyFn,addInvalidHandleClass:Ext.emptyFn,addInvalidHandleId:Ext.emptyFn,addInvalidHandleType:Ext.emptyFn,removeInvalidHandleClass:Ext.emptyFn,removeInvalidHandleId:Ext.emptyFn,removeInvalidHandleType:Ext.emptyFn,toString:function(){return("DDTarget "+this.id)}});Ext.dd.DragTracker=Ext.extend(Ext.util.Observable,{active:false,tolerance:5,autoStart:false,constructor:function(a){Ext.apply(this,a);this.addEvents("mousedown","mouseup","mousemove","dragstart","dragend","drag");this.dragRegion=new Ext.lib.Region(0,0,0,0);if(this.el){this.initEl(this.el)}Ext.dd.DragTracker.superclass.constructor.call(this,a)},initEl:function(a){this.el=Ext.get(a);a.on("mousedown",this.onMouseDown,this,this.delegate?{delegate:this.delegate}:undefined)},destroy:function(){this.el.un("mousedown",this.onMouseDown,this)},onMouseDown:function(c,b){if(this.fireEvent("mousedown",this,c)!==false&&this.onBeforeStart(c)!==false){this.startXY=this.lastXY=c.getXY();this.dragTarget=this.delegate?b:this.el.dom;if(this.preventDefault!==false){c.preventDefault()}var a=Ext.getDoc();a.on("mouseup",this.onMouseUp,this);a.on("mousemove",this.onMouseMove,this);a.on("selectstart",this.stopSelect,this);if(this.autoStart){this.timer=this.triggerStart.defer(this.autoStart===true?1000:this.autoStart,this)}}},onMouseMove:function(d,c){if(this.active&&Ext.isIE&&!d.browserEvent.button){d.preventDefault();this.onMouseUp(d);return}d.preventDefault();var b=d.getXY(),a=this.startXY;this.lastXY=b;if(!this.active){if(Math.abs(a[0]-b[0])>this.tolerance||Math.abs(a[1]-b[1])>this.tolerance){this.triggerStart()}else{return}}this.fireEvent("mousemove",this,d);this.onDrag(d);this.fireEvent("drag",this,d)},onMouseUp:function(c){var b=Ext.getDoc();b.un("mousemove",this.onMouseMove,this);b.un("mouseup",this.onMouseUp,this);b.un("selectstart",this.stopSelect,this);c.preventDefault();this.clearStart();var a=this.active;this.active=false;delete this.elRegion;this.fireEvent("mouseup",this,c);if(a){this.onEnd(c);this.fireEvent("dragend",this,c)}},triggerStart:function(a){this.clearStart();this.active=true;this.onStart(this.startXY);this.fireEvent("dragstart",this,this.startXY)},clearStart:function(){if(this.timer){clearTimeout(this.timer);delete this.timer}},stopSelect:function(a){a.stopEvent();return false},onBeforeStart:function(a){},onStart:function(a){},onDrag:function(a){},onEnd:function(a){},getDragTarget:function(){return this.dragTarget},getDragCt:function(){return this.el},getXY:function(a){return a?this.constrainModes[a].call(this,this.lastXY):this.lastXY},getOffset:function(c){var b=this.getXY(c);var a=this.startXY;return[a[0]-b[0],a[1]-b[1]]},constrainModes:{point:function(b){if(!this.elRegion){this.elRegion=this.getDragCt().getRegion()}var a=this.dragRegion;a.left=b[0];a.top=b[1];a.right=b[0];a.bottom=b[1];a.constrainTo(this.elRegion);return[a.left,a.top]}}});Ext.dd.ScrollManager=function(){var c=Ext.dd.DragDropMgr;var e={};var b=null;var i={};var h=function(l){b=null;a()};var j=function(){if(c.dragCurrent){c.refreshCache(c.dragCurrent.groups)}};var d=function(){if(c.dragCurrent){var l=Ext.dd.ScrollManager;var m=i.el.ddScrollConfig?i.el.ddScrollConfig.increment:l.increment;if(!l.animate){if(i.el.scroll(i.dir,m)){j()}}else{i.el.scroll(i.dir,m,true,l.animDuration,j)}}};var a=function(){if(i.id){clearInterval(i.id)}i.id=0;i.el=null;i.dir=""};var g=function(m,l){a();i.el=m;i.dir=l;var n=(m.ddScrollConfig&&m.ddScrollConfig.frequency)?m.ddScrollConfig.frequency:Ext.dd.ScrollManager.frequency;i.id=setInterval(d,n)};var k=function(o,q){if(q||!c.dragCurrent){return}var s=Ext.dd.ScrollManager;if(!b||b!=c.dragCurrent){b=c.dragCurrent;s.refreshCache()}var t=Ext.lib.Event.getXY(o);var u=new Ext.lib.Point(t[0],t[1]);for(var m in e){var n=e[m],l=n._region;var p=n.ddScrollConfig?n.ddScrollConfig:s;if(l&&l.contains(u)&&n.isScrollable()){if(l.bottom-u.y<=p.vthresh){if(i.el!=n){g(n,"down")}return}else{if(l.right-u.x<=p.hthresh){if(i.el!=n){g(n,"left")}return}else{if(u.y-l.top<=p.vthresh){if(i.el!=n){g(n,"up")}return}else{if(u.x-l.left<=p.hthresh){if(i.el!=n){g(n,"right")}return}}}}}}a()};c.fireEvents=c.fireEvents.createSequence(k,c);c.stopDrag=c.stopDrag.createSequence(h,c);return{register:function(n){if(Ext.isArray(n)){for(var m=0,l=n.length;m]+>/gi,asText:function(a){return String(a).replace(this.stripTagsRE,"")},asUCText:function(a){return String(a).toUpperCase().replace(this.stripTagsRE,"")},asUCString:function(a){return String(a).toUpperCase()},asDate:function(a){if(!a){return 0}if(Ext.isDate(a)){return a.getTime()}return Date.parse(String(a))},asFloat:function(a){var b=parseFloat(String(a).replace(/,/g,""));return isNaN(b)?0:b},asInt:function(a){var b=parseInt(String(a).replace(/,/g,""),10);return isNaN(b)?0:b}};Ext.data.Record=function(a,b){this.id=(b||b===0)?b:Ext.data.Record.id(this);this.data=a||{}};Ext.data.Record.create=function(e){var c=Ext.extend(Ext.data.Record,{});var d=c.prototype;d.fields=new Ext.util.MixedCollection(false,function(g){return g.name});for(var b=0,a=e.length;b-1){a.join(null);this.data.removeAt(b)}if(this.pruneModifiedRecords){this.modified.remove(a)}if(this.snapshot){this.snapshot.remove(a)}if(b>-1){this.fireEvent("remove",this,a,b)}},removeAt:function(a){this.remove(this.getAt(a))},removeAll:function(b){var a=[];this.each(function(c){a.push(c)});this.clearData();if(this.snapshot){this.snapshot.clear()}if(this.pruneModifiedRecords){this.modified=[]}if(b!==true){this.fireEvent("clear",this,a)}},onClear:function(b,a){Ext.each(a,function(d,c){this.destroyRecord(this,d,c)},this)},insert:function(c,b){b=[].concat(b);for(var d=0,a=b.length;d=0;d--){if(b[d].phantom===true){var a=b.splice(d,1).shift();if(a.isValid()){g.push(a)}}else{if(!b[d].isValid()){b.splice(d,1)}}}if(g.length){h.push(["create",g])}if(b.length){h.push(["update",b])}}j=h.length;if(j){e=++this.batchCounter;for(var d=0;d=0;b--){this.modified.splice(this.modified.indexOf(a[b]),1)}}else{this.modified.splice(this.modified.indexOf(a),1)}},reMap:function(b){if(Ext.isArray(b)){for(var d=0,a=b.length;d=0;c--){this.insert(b[c].lastIndex,b[c])}}},handleException:function(a){Ext.handleError(a)},reload:function(a){this.load(Ext.applyIf(a||{},this.lastOptions))},loadRecords:function(h,b,g){if(this.isDestroyed===true){return}if(!h||g===false){if(g!==false){this.fireEvent("load",this,[],b)}if(b.callback){b.callback.call(b.scope||this,[],b,false,h)}return}var e=h.records,d=h.totalRecords||e.length;if(!b||b.add!==true){if(this.pruneModifiedRecords){this.modified=[]}for(var c=0,a=e.length;c1){for(var p=1,o=c.length;ph?1:(i=0;b--){if(Ext.isArray(c)){this.realize(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.realize(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(!this.isData(c)){throw new Ext.data.DataReader.Error("realize",a)}a.phantom=false;a._phid=a.id;a.id=this.getId(c);a.data=c;a.commit()}},update:function(a,c){if(Ext.isArray(a)){for(var b=a.length-1;b>=0;b--){if(Ext.isArray(c)){this.update(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.update(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(this.isData(c)){a.data=Ext.apply(a.data,c)}a.commit()}},extractData:function(k,a){var j=(this instanceof Ext.data.JsonReader)?"json":"node";var c=[];if(this.isData(k)&&!(this instanceof Ext.data.XmlReader)){k=[k]}var h=this.recordType.prototype.fields,o=h.items,m=h.length,c=[];if(a===true){var l=this.recordType;for(var e=0;e=0){return new Function("obj","return obj"+(b>0?".":"")+c)}return function(d){return d[c]}}}(),extractValues:function(h,d,a){var g,c={};for(var e=0;e<\u003fxml version="{version}" encoding="{encoding}"\u003f><{documentRoot}><{name}>{value}<{root}><{parent.record}><{name}>{value}',render:function(b,c,a){c=this.toArray(c);b.xmlData=this.tpl.applyTemplate({version:this.xmlVersion,encoding:this.xmlEncoding,documentRoot:(c.length>0||this.forceDocumentRoot===true)?this.documentRoot:false,record:this.meta.record,root:this.root,baseParams:c,records:(Ext.isArray(a[0]))?a:[a]})},createRecord:function(a){return this.toArray(this.toHash(a))},updateRecord:function(a){return this.toArray(this.toHash(a))},destroyRecord:function(b){var a={};a[this.meta.idProperty]=b.id;return this.toArray(a)}});Ext.data.XmlReader=function(a,b){a=a||{};Ext.applyIf(a,{idProperty:a.idProperty||a.idPath||a.id,successProperty:a.successProperty||a.success});Ext.data.XmlReader.superclass.constructor.call(this,a,b||a.fields)};Ext.extend(Ext.data.XmlReader,Ext.data.DataReader,{read:function(a){var b=a.responseXML;if(!b){throw {message:"XmlReader.read: XML Document not available"}}return this.readRecords(b)},readRecords:function(d){this.xmlData=d;var a=d.documentElement||d,c=Ext.DomQuery,g=0,e=true;if(this.meta.totalProperty){g=this.getTotal(a,0)}if(this.meta.successProperty){e=this.getSuccess(a)}var b=this.extractData(c.select(this.meta.record,a),true);return{success:e,records:b,totalRecords:g||b.length}},readResponse:function(e,a){var d=Ext.DomQuery,g=a.responseXML;var b=new Ext.data.Response({action:e,success:this.getSuccess(g),message:this.getMessage(g),data:this.extractData(d.select(this.meta.record,g)||d.select(this.meta.root,g),false),raw:g});if(Ext.isEmpty(b.success)){throw new Ext.data.DataReader.Error("successProperty-response",this.meta.successProperty)}if(e===Ext.data.Api.actions.create){var c=Ext.isDefined(b.data);if(c&&Ext.isEmpty(b.data)){throw new Ext.data.JsonReader.Error("root-empty",this.meta.root)}else{if(!c){throw new Ext.data.JsonReader.Error("root-undefined-response",this.meta.root)}}}return b},getSuccess:function(){return true},buildExtractors:function(){if(this.ef){return}var l=this.meta,h=this.recordType,e=h.prototype.fields,k=e.items,j=e.length;if(l.totalProperty){this.getTotal=this.createAccessor(l.totalProperty)}if(l.successProperty){this.getSuccess=this.createAccessor(l.successProperty)}if(l.messageProperty){this.getMessage=this.createAccessor(l.messageProperty)}this.getRoot=function(g){return(!Ext.isEmpty(g[this.meta.record]))?g[this.meta.record]:g[this.meta.root]};if(l.idPath||l.idProperty){var d=this.createAccessor(l.idPath||l.idProperty);this.getId=function(g){var i=d(g)||g.id;return(i===undefined||i==="")?null:i}}else{this.getId=function(){return null}}var c=[];for(var b=0;b0&&sorters[0].field==this.groupField){sorters.shift()}this.groupField=d;this.groupDir=c;this.applyGroupField();var b=function(){this.fireEvent("groupchange",this,this.getGroupState())};if(this.groupOnSort){this.sort(d,c);b.call(this);return}if(this.remoteGroup){this.on("load",b,this,{single:true});this.reload()}else{this.sort(sorters);b.call(this)}},sort:function(h,c){if(this.remoteSort){return Ext.data.GroupingStore.superclass.sort.call(this,h,c)}var g=[];if(Ext.isArray(arguments[0])){g=arguments[0]}else{if(h==undefined){g=this.sortInfo?[this.sortInfo]:[]}else{var e=this.fields.get(h);if(!e){return false}var b=e.name,a=this.sortInfo||null,d=this.sortToggle?this.sortToggle[b]:null;if(!c){if(a&&a.field==b){c=(this.sortToggle[b]||"ASC").toggle("ASC","DESC")}else{c=e.sortDir}}this.sortToggle[b]=c;this.sortInfo={field:b,direction:c};g=[this.sortInfo]}}if(this.groupField){g.unshift({direction:this.groupDir,field:this.groupField})}return this.multiSort.call(this,g,c)},applyGroupField:function(){if(this.remoteGroup){if(!this.baseParams){this.baseParams={}}Ext.apply(this.baseParams,{groupBy:this.groupField,groupDir:this.groupDir});var a=this.lastOptions;if(a&&a.params){a.params.groupDir=this.groupDir;delete a.params.groupBy}}},applyGrouping:function(a){if(this.groupField!==false){this.groupBy(this.groupField,true,this.groupDir);return true}else{if(a===true){this.fireEvent("datachanged",this)}return false}},getGroupState:function(){return this.groupOnSort&&this.groupField!==false?(this.sortInfo?this.sortInfo.field:undefined):this.groupField}});Ext.reg("groupingstore",Ext.data.GroupingStore);Ext.data.DirectProxy=function(a){Ext.apply(this,a);if(typeof this.paramOrder=="string"){this.paramOrder=this.paramOrder.split(/[\s,|]/)}Ext.data.DirectProxy.superclass.constructor.call(this,a)};Ext.extend(Ext.data.DirectProxy,Ext.data.DataProxy,{paramOrder:undefined,paramsAsHash:true,directFn:undefined,doRequest:function(b,c,a,e,k,l,n){var j=[],h=this.api[b]||this.directFn;switch(b){case Ext.data.Api.actions.create:j.push(a.jsonData);break;case Ext.data.Api.actions.read:if(h.directCfg.method.len>0){if(this.paramOrder){for(var d=0,g=this.paramOrder.length;d1){for(var d=0,b=c.length;d0){this.doSend(a==1?this.callBuffer[0]:this.callBuffer);this.callBuffer=[]}},queueTransaction:function(a){if(a.form){this.processForm(a);return}this.callBuffer.push(a);if(this.enableBuffer){if(!this.callTask){this.callTask=new Ext.util.DelayedTask(this.combineAndSend,this)}this.callTask.delay(Ext.isNumber(this.enableBuffer)?this.enableBuffer:10)}else{this.combineAndSend()}},doCall:function(i,a,b){var h=null,e=b[a.len],g=b[a.len+1];if(a.len!==0){h=b.slice(0,a.len)}var d=new Ext.Direct.Transaction({provider:this,args:b,action:i,method:a.name,data:h,cb:g&&Ext.isFunction(e)?e.createDelegate(g):e});if(this.fireEvent("beforecall",this,d)!==false){Ext.Direct.addTransaction(d);this.queueTransaction(d);this.fireEvent("call",this,d)}},doForm:function(j,b,g,i,e){var d=new Ext.Direct.Transaction({provider:this,action:j,method:b.name,args:[g,i,e],cb:e&&Ext.isFunction(i)?i.createDelegate(e):i,isForm:true});if(this.fireEvent("beforecall",this,d)!==false){Ext.Direct.addTransaction(d);var a=String(g.getAttribute("enctype")).toLowerCase()=="multipart/form-data",h={extTID:d.tid,extAction:j,extMethod:b.name,extType:"rpc",extUpload:String(a)};Ext.apply(d,{form:Ext.getDom(g),isUpload:a,params:i&&Ext.isObject(i.params)?Ext.apply(h,i.params):h});this.fireEvent("call",this,d);this.processForm(d)}},processForm:function(a){Ext.Ajax.request({url:this.url,params:a.params,callback:this.onData,scope:this,form:a.form,isUpload:a.isUpload,ts:a})},createMethod:function(d,a){var b;if(!a.formHandler){b=function(){this.doCall(d,a,Array.prototype.slice.call(arguments,0))}.createDelegate(this)}else{b=function(e,g,c){this.doForm(d,a,e,g,c)}.createDelegate(this)}b.directCfg={action:d,method:a};return b},getTransaction:function(a){return a&&a.tid?Ext.Direct.getTransaction(a.tid):null},doCallback:function(c,g){var d=g.status?"success":"failure";if(c&&c.cb){var b=c.cb,a=Ext.isDefined(g.result)?g.result:g.data;if(Ext.isFunction(b)){b(a,g)}else{Ext.callback(b[d],b.scope,[a,g]);Ext.callback(b.callback,b.scope,[a,g])}}}});Ext.Direct.PROVIDERS.remoting=Ext.direct.RemotingProvider;Ext.Resizable=Ext.extend(Ext.util.Observable,{constructor:function(d,e){this.el=Ext.get(d);if(e&&e.wrap){e.resizeChild=this.el;this.el=this.el.wrap(typeof e.wrap=="object"?e.wrap:{cls:"xresizable-wrap"});this.el.id=this.el.dom.id=e.resizeChild.id+"-rzwrap";this.el.setStyle("overflow","hidden");this.el.setPositioning(e.resizeChild.getPositioning());e.resizeChild.clearPositioning();if(!e.width||!e.height){var g=e.resizeChild.getSize();this.el.setSize(g.width,g.height)}if(e.pinned&&!e.adjustments){e.adjustments="auto"}}this.proxy=this.el.createProxy({tag:"div",cls:"x-resizable-proxy",id:this.el.id+"-rzproxy"},Ext.getBody());this.proxy.unselectable();this.proxy.enableDisplayMode("block");Ext.apply(this,e);if(this.pinned){this.disableTrackOver=true;this.el.addClass("x-resizable-pinned")}var k=this.el.getStyle("position");if(k!="absolute"&&k!="fixed"){this.el.setStyle("position","relative")}if(!this.handles){this.handles="s,e,se";if(this.multiDirectional){this.handles+=",n,w"}}if(this.handles=="all"){this.handles="n s e w ne nw se sw"}var o=this.handles.split(/\s*?[,;]\s*?| /);var c=Ext.Resizable.positions;for(var j=0,l=o.length;j0){if(a>(e/2)){d=c+(e-a)}else{d=c-a}}return Math.max(b,d)},resizeElement:function(){var a=this.proxy.getBox();if(this.updateBox){this.el.setBox(a,false,this.animate,this.duration,null,this.easing)}else{this.el.setSize(a.width,a.height,this.animate,this.duration,null,this.easing)}this.updateChildSize();if(!this.dynamic){this.proxy.hide()}if(this.draggable&&this.constrainTo){this.dd.resetConstraints();this.dd.constrainTo(this.constrainTo)}return a},constrain:function(b,c,a,d){if(b-cd){c=b-d}}return c},onMouseMove:function(z){if(this.enabled&&this.activeHandle){try{if(this.resizeRegion&&!this.resizeRegion.contains(z.getPoint())){return}var t=this.curSize||this.startBox,l=this.startBox.x,k=this.startBox.y,c=l,b=k,m=t.width,u=t.height,d=m,o=u,n=this.minWidth,A=this.minHeight,s=this.maxWidth,D=this.maxHeight,i=this.widthIncrement,a=this.heightIncrement,B=z.getXY(),r=-(this.startPoint[0]-Math.max(this.minX,B[0])),p=-(this.startPoint[1]-Math.max(this.minY,B[1])),j=this.activeHandle.position,E,g;switch(j){case"east":m+=r;m=Math.min(Math.max(n,m),s);break;case"south":u+=p;u=Math.min(Math.max(A,u),D);break;case"southeast":m+=r;u+=p;m=Math.min(Math.max(n,m),s);u=Math.min(Math.max(A,u),D);break;case"north":p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"west":r=this.constrain(m,r,n,s);l+=r;m-=r;break;case"northeast":m+=r;m=Math.min(Math.max(n,m),s);p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"northwest":r=this.constrain(m,r,n,s);p=this.constrain(u,p,A,D);k+=p;u-=p;l+=r;m-=r;break;case"southwest":r=this.constrain(m,r,n,s);u+=p;u=Math.min(Math.max(A,u),D);l+=r;m-=r;break}var q=this.snap(m,i,n);var C=this.snap(u,a,A);if(q!=m||C!=u){switch(j){case"northeast":k-=C-u;break;case"north":k-=C-u;break;case"southwest":l-=q-m;break;case"west":l-=q-m;break;case"northwest":l-=q-m;k-=C-u;break}m=q;u=C}if(this.preserveRatio){switch(j){case"southeast":case"east":u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);break;case"south":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"northeast":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"north":E=m;m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);l+=(E-m)/2;break;case"southwest":u=o*(m/d);u=Math.min(Math.max(A,u),D);E=m;m=d*(u/o);l+=E-m;break;case"west":g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);k+=(g-u)/2;E=m;m=d*(u/o);l+=E-m;break;case"northwest":E=m;g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);k+=g-u;l+=E-m;break}}this.proxy.setBounds(l,k,m,u);if(this.dynamic){this.resizeElement()}}catch(v){}}},handleOver:function(){if(this.enabled){this.el.addClass("x-resizable-over")}},handleOut:function(){if(!this.resizing){this.el.removeClass("x-resizable-over")}},getEl:function(){return this.el},getResizeChild:function(){return this.resizeChild},destroy:function(b){Ext.destroy(this.dd,this.overlay,this.proxy);this.overlay=null;this.proxy=null;var c=Ext.Resizable.positions;for(var a in c){if(typeof c[a]!="function"&&this[c[a]]){this[c[a]].destroy()}}if(b){this.el.update("");Ext.destroy(this.el);this.el=null}this.purgeListeners()},syncHandleHeight:function(){var a=this.el.getHeight(true);if(this.west){this.west.el.setHeight(a)}if(this.east){this.east.el.setHeight(a)}}});Ext.Resizable.positions={n:"north",s:"south",e:"east",w:"west",se:"southeast",sw:"southwest",nw:"northwest",ne:"northeast"};Ext.Resizable.Handle=Ext.extend(Object,{constructor:function(d,g,c,e,a){if(!this.tpl){var b=Ext.DomHelper.createTemplate({tag:"div",cls:"x-resizable-handle x-resizable-handle-{0}"});b.compile();Ext.Resizable.Handle.prototype.tpl=b}this.position=g;this.rz=d;this.el=this.tpl.append(d.el.dom,[this.position],true);this.el.unselectable();if(e){this.el.setOpacity(0)}if(!Ext.isEmpty(a)){this.el.addClass(a)}this.el.on("mousedown",this.onMouseDown,this);if(!c){this.el.on({scope:this,mouseover:this.onMouseOver,mouseout:this.onMouseOut})}},afterResize:function(a){},onMouseDown:function(a){this.rz.onMouseDown(this,a)},onMouseOver:function(a){this.rz.handleOver(this,a)},onMouseOut:function(a){this.rz.handleOut(this,a)},destroy:function(){Ext.destroy(this.el);this.el=null}});Ext.Window=Ext.extend(Ext.Panel,{baseCls:"x-window",resizable:true,draggable:true,closable:true,closeAction:"close",constrain:false,constrainHeader:false,plain:false,minimizable:false,maximizable:false,minHeight:100,minWidth:200,expandOnShow:true,collapsible:false,initHidden:undefined,hidden:true,elements:"header,body",frame:true,floating:true,initComponent:function(){this.initTools();Ext.Window.superclass.initComponent.call(this);this.addEvents("resize","maximize","minimize","restore");if(Ext.isDefined(this.initHidden)){this.hidden=this.initHidden}if(this.hidden===false){this.hidden=true;this.show()}},getState:function(){return Ext.apply(Ext.Window.superclass.getState.call(this)||{},this.getBox(true))},onRender:function(b,a){Ext.Window.superclass.onRender.call(this,b,a);if(this.plain){this.el.addClass("x-window-plain")}this.focusEl=this.el.createChild({tag:"a",href:"#",cls:"x-dlg-focus",tabIndex:"-1",html:" "});this.focusEl.swallowEvent("click",true);this.proxy=this.el.createProxy("x-window-proxy");this.proxy.enableDisplayMode("block");if(this.modal){this.mask=this.container.createChild({cls:"ext-el-mask"},this.el.dom);this.mask.enableDisplayMode("block");this.mask.hide();this.mon(this.mask,"click",this.focus,this)}if(this.maximizable){this.mon(this.header,"dblclick",this.toggleMaximize,this)}},initEvents:function(){Ext.Window.superclass.initEvents.call(this);if(this.animateTarget){this.setAnimateTarget(this.animateTarget)}if(this.resizable){this.resizer=new Ext.Resizable(this.el,{minWidth:this.minWidth,minHeight:this.minHeight,handles:this.resizeHandles||"all",pinned:true,resizeElement:this.resizerAction,handleCls:"x-window-handle"});this.resizer.window=this;this.mon(this.resizer,"beforeresize",this.beforeResize,this)}if(this.draggable){this.header.addClass("x-window-draggable")}this.mon(this.el,"mousedown",this.toFront,this);this.manager=this.manager||Ext.WindowMgr;this.manager.register(this);if(this.maximized){this.maximized=false;this.maximize()}if(this.closable){var a=this.getKeyMap();a.on(27,this.onEsc,this);a.disable()}},initDraggable:function(){this.dd=new Ext.Window.DD(this)},onEsc:function(a,b){b.stopEvent();this[this.closeAction]()},beforeDestroy:function(){if(this.rendered){this.hide();this.clearAnchor();Ext.destroy(this.focusEl,this.resizer,this.dd,this.proxy,this.mask)}Ext.Window.superclass.beforeDestroy.call(this)},onDestroy:function(){if(this.manager){this.manager.unregister(this)}Ext.Window.superclass.onDestroy.call(this)},initTools:function(){if(this.minimizable){this.addTool({id:"minimize",handler:this.minimize.createDelegate(this,[])})}if(this.maximizable){this.addTool({id:"maximize",handler:this.maximize.createDelegate(this,[])});this.addTool({id:"restore",handler:this.restore.createDelegate(this,[]),hidden:true})}if(this.closable){this.addTool({id:"close",handler:this[this.closeAction].createDelegate(this,[])})}},resizerAction:function(){var a=this.proxy.getBox();this.proxy.hide();this.window.handleResize(a);return a},beforeResize:function(){this.resizer.minHeight=Math.max(this.minHeight,this.getFrameHeight()+40);this.resizer.minWidth=Math.max(this.minWidth,this.getFrameWidth()+40);this.resizeBox=this.el.getBox()},updateHandles:function(){if(Ext.isIE&&this.resizer){this.resizer.syncHandleHeight();this.el.repaint()}},handleResize:function(b){var a=this.resizeBox;if(a.x!=b.x||a.y!=b.y){this.updateBox(b)}else{this.setSize(b);if(Ext.isIE6&&Ext.isStrict){this.doLayout()}}this.focus();this.updateHandles();this.saveState()},focus:function(){var e=this.focusEl,a=this.defaultButton,c=typeof a,d,b;if(Ext.isDefined(a)){if(Ext.isNumber(a)&&this.fbar){e=this.fbar.items.get(a)}else{if(Ext.isString(a)){e=Ext.getCmp(a)}else{e=a}}d=e.getEl();b=Ext.getDom(this.container);if(d&&b){if(!Ext.lib.Region.getRegion(b).contains(Ext.lib.Region.getRegion(d.dom))){return}}}e=e||this.focusEl;e.focus.defer(10,e)},setAnimateTarget:function(a){a=Ext.get(a);this.animateTarget=a},beforeShow:function(){delete this.el.lastXY;delete this.el.lastLT;if(this.x===undefined||this.y===undefined){var a=this.el.getAlignToXY(this.container,"c-c");var b=this.el.translatePoints(a[0],a[1]);this.x=this.x===undefined?b.left:this.x;this.y=this.y===undefined?b.top:this.y}this.el.setLeftTop(this.x,this.y);if(this.expandOnShow){this.expand(false)}if(this.modal){Ext.getBody().addClass("x-body-masked");this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.mask.show()}},show:function(c,a,b){if(!this.rendered){this.render(Ext.getBody())}if(this.hidden===false){this.toFront();return this}if(this.fireEvent("beforeshow",this)===false){return this}if(a){this.on("show",a,b,{single:true})}this.hidden=false;if(Ext.isDefined(c)){this.setAnimateTarget(c)}this.beforeShow();if(this.animateTarget){this.animShow()}else{this.afterShow()}return this},afterShow:function(b){if(this.isDestroyed){return false}this.proxy.hide();this.el.setStyle("display","block");this.el.show();if(this.maximized){this.fitContainer()}if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.onWindowResize(this.onWindowResize,this)}this.doConstrain();this.doLayout();if(this.keyMap){this.keyMap.enable()}this.toFront();this.updateHandles();if(b&&(Ext.isIE||Ext.isWebKit)){var a=this.getSize();this.onResize(a.width,a.height)}this.onShow();this.fireEvent("show",this)},animShow:function(){this.proxy.show();this.proxy.setBox(this.animateTarget.getBox());this.proxy.setOpacity(0);var a=this.getBox();this.el.setStyle("display","none");this.proxy.shift(Ext.apply(a,{callback:this.afterShow.createDelegate(this,[true],false),scope:this,easing:"easeNone",duration:0.25,opacity:0.5}))},hide:function(c,a,b){if(this.hidden||this.fireEvent("beforehide",this)===false){return this}if(a){this.on("hide",a,b,{single:true})}this.hidden=true;if(c!==undefined){this.setAnimateTarget(c)}if(this.modal){this.mask.hide();Ext.getBody().removeClass("x-body-masked")}if(this.animateTarget){this.animHide()}else{this.el.hide();this.afterHide()}return this},afterHide:function(){this.proxy.hide();if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.removeResizeListener(this.onWindowResize,this)}if(this.keyMap){this.keyMap.disable()}this.onHide();this.fireEvent("hide",this)},animHide:function(){this.proxy.setOpacity(0.5);this.proxy.show();var a=this.getBox(false);this.proxy.setBox(a);this.el.hide();this.proxy.shift(Ext.apply(this.animateTarget.getBox(),{callback:this.afterHide,scope:this,duration:0.25,easing:"easeNone",opacity:0}))},onShow:Ext.emptyFn,onHide:Ext.emptyFn,onWindowResize:function(){if(this.maximized){this.fitContainer()}if(this.modal){this.mask.setSize("100%","100%");var a=this.mask.dom.offsetHeight;this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true))}this.doConstrain()},doConstrain:function(){if(this.constrain||this.constrainHeader){var b;if(this.constrain){b={right:this.el.shadowOffset,left:this.el.shadowOffset,bottom:this.el.shadowOffset}}else{var a=this.getSize();b={right:-(a.width-100),bottom:-(a.height-25)}}var c=this.el.getConstrainToXY(this.container,true,b);if(c){this.setPosition(c[0],c[1])}}},ghost:function(a){var c=this.createGhost(a);var b=this.getBox(true);c.setLeftTop(b.x,b.y);c.setWidth(b.width);this.el.hide();this.activeGhost=c;return c},unghost:function(b,a){if(!this.activeGhost){return}if(b!==false){this.el.show();this.focus.defer(10,this);if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}}if(a!==false){this.setPosition(this.activeGhost.getLeft(true),this.activeGhost.getTop(true))}this.activeGhost.hide();this.activeGhost.remove();delete this.activeGhost},minimize:function(){this.fireEvent("minimize",this);return this},close:function(){if(this.fireEvent("beforeclose",this)!==false){if(this.hidden){this.doClose()}else{this.hide(null,this.doClose,this)}}},doClose:function(){this.fireEvent("close",this);this.destroy()},maximize:function(){if(!this.maximized){this.expand(false);this.restoreSize=this.getSize();this.restorePos=this.getPosition(true);if(this.maximizable){this.tools.maximize.hide();this.tools.restore.show()}this.maximized=true;this.el.disableShadow();if(this.dd){this.dd.lock()}if(this.collapsible){this.tools.toggle.hide()}this.el.addClass("x-window-maximized");this.container.addClass("x-window-maximized-ct");this.setPosition(0,0);this.fitContainer();this.fireEvent("maximize",this)}return this},restore:function(){if(this.maximized){var a=this.tools;this.el.removeClass("x-window-maximized");if(a.restore){a.restore.hide()}if(a.maximize){a.maximize.show()}this.setPosition(this.restorePos[0],this.restorePos[1]);this.setSize(this.restoreSize.width,this.restoreSize.height);delete this.restorePos;delete this.restoreSize;this.maximized=false;this.el.enableShadow(true);if(this.dd){this.dd.unlock()}if(this.collapsible&&a.toggle){a.toggle.show()}this.container.removeClass("x-window-maximized-ct");this.doConstrain();this.fireEvent("restore",this)}return this},toggleMaximize:function(){return this[this.maximized?"restore":"maximize"]()},fitContainer:function(){var a=this.container.getViewSize(false);this.setSize(a.width,a.height)},setZIndex:function(a){if(this.modal){this.mask.setStyle("z-index",a)}this.el.setZIndex(++a);a+=5;if(this.resizer){this.resizer.proxy.setStyle("z-index",++a)}this.lastZIndex=a},alignTo:function(b,a,c){var d=this.el.getAlignToXY(b,a,c);this.setPagePosition(d[0],d[1]);return this},anchorTo:function(c,e,d,b){this.clearAnchor();this.anchorTarget={el:c,alignment:e,offsets:d};Ext.EventManager.onWindowResize(this.doAnchor,this);var a=typeof b;if(a!="undefined"){Ext.EventManager.on(window,"scroll",this.doAnchor,this,{buffer:a=="number"?b:50})}return this.doAnchor()},doAnchor:function(){var a=this.anchorTarget;this.alignTo(a.el,a.alignment,a.offsets);return this},clearAnchor:function(){if(this.anchorTarget){Ext.EventManager.removeResizeListener(this.doAnchor,this);Ext.EventManager.un(window,"scroll",this.doAnchor,this);delete this.anchorTarget}return this},toFront:function(a){if(this.manager.bringToFront(this)){if(!a||!a.getTarget().focus){this.focus()}}return this},setActive:function(a){if(a){if(!this.maximized){this.el.enableShadow(true)}this.fireEvent("activate",this)}else{this.el.disableShadow();this.fireEvent("deactivate",this)}},toBack:function(){this.manager.sendToBack(this);return this},center:function(){var a=this.el.getAlignToXY(this.container,"c-c");this.setPagePosition(a[0],a[1]);return this}});Ext.reg("window",Ext.Window);Ext.Window.DD=function(a){this.win=a;Ext.Window.DD.superclass.constructor.call(this,a.el.id,"WindowDD-"+a.id);this.setHandleElId(a.header.id);this.scroll=false};Ext.extend(Ext.Window.DD,Ext.dd.DD,{moveOnly:true,headerOffsets:[100,25],startDrag:function(){var a=this.win;this.proxy=a.ghost();if(a.constrain!==false){var c=a.el.shadowOffset;this.constrainTo(a.container,{right:c,left:c,bottom:c})}else{if(a.constrainHeader!==false){var b=this.proxy.getSize();this.constrainTo(a.container,{right:-(b.width-this.headerOffsets[0]),bottom:-(b.height-this.headerOffsets[1])})}}},b4Drag:Ext.emptyFn,onDrag:function(a){this.alignElWithMouse(this.proxy,a.getPageX(),a.getPageY())},endDrag:function(a){this.win.unghost();this.win.saveState()}});Ext.WindowGroup=function(){var g={};var d=[];var e=null;var c=function(j,i){return(!j._lastAccess||j._lastAccess0){l.sort(c);var k=l[0].manager.zseed;for(var m=0;m=0;--j){if(!d[j].hidden){b(d[j]);return}}b(null)};return{zseed:9000,register:function(i){if(i.manager){i.manager.unregister(i)}i.manager=this;g[i.id]=i;d.push(i);i.on("hide",a)},unregister:function(i){delete i.manager;delete g[i.id];i.un("hide",a);d.remove(i)},get:function(i){return typeof i=="object"?i:g[i]},bringToFront:function(i){i=this.get(i);if(i!=e){i._lastAccess=new Date().getTime();h();return true}return false},sendToBack:function(i){i=this.get(i);i._lastAccess=-(new Date().getTime());h();return i},hideAll:function(){for(var i in g){if(g[i]&&typeof g[i]!="function"&&g[i].isVisible()){g[i].hide()}}},getActive:function(){return e},getBy:function(l,k){var m=[];for(var j=d.length-1;j>=0;--j){var n=d[j];if(l.call(k||n,n)!==false){m.push(n)}}return m},each:function(j,i){for(var k in g){if(g[k]&&typeof g[k]!="function"){if(j.call(i||g[k],g[k])===false){return}}}}}};Ext.WindowMgr=new Ext.WindowGroup();Ext.MessageBox=function(){var u,b,q,t,h,l,s,a,n,p,j,g,r,v,o,i="",d="",m=["ok","yes","no","cancel"];var c=function(x){r[x].blur();if(u.isVisible()){u.hide();w();Ext.callback(b.fn,b.scope||window,[x,v.dom.value,b],1)}};var w=function(){if(b&&b.cls){u.el.removeClass(b.cls)}n.reset()};var e=function(z,x,y){if(b&&b.closable!==false){u.hide();w()}if(y){y.stopEvent()}};var k=function(x){var z=0,y;if(!x){Ext.each(m,function(A){r[A].hide()});return z}u.footer.dom.style.display="";Ext.iterate(r,function(A,B){y=x[A];if(y){B.show();B.setText(Ext.isString(y)?y:Ext.MessageBox.buttonText[A]);z+=B.getEl().getWidth()+15}else{B.hide()}});return z};return{getDialog:function(x){if(!u){var z=[];r={};Ext.each(m,function(A){z.push(r[A]=new Ext.Button({text:this.buttonText[A],handler:c.createCallback(A),hideMode:"offsets"}))},this);u=new Ext.Window({autoCreate:true,title:x,resizable:false,constrain:true,constrainHeader:true,minimizable:false,maximizable:false,stateful:false,modal:true,shim:true,buttonAlign:"center",width:400,height:100,minHeight:80,plain:true,footer:true,closable:true,close:function(){if(b&&b.buttons&&b.buttons.no&&!b.buttons.cancel){c("no")}else{c("cancel")}},fbar:new Ext.Toolbar({items:z,enableOverflow:false})});u.render(document.body);u.getEl().addClass("x-window-dlg");q=u.mask;h=u.body.createChild({html:'

'});j=Ext.get(h.dom.firstChild);var y=h.dom.childNodes[1];l=Ext.get(y.firstChild);s=Ext.get(y.childNodes[2].firstChild);s.enableDisplayMode();s.addKeyListener([10,13],function(){if(u.isVisible()&&b&&b.buttons){if(b.buttons.ok){c("ok")}else{if(b.buttons.yes){c("yes")}}}});a=Ext.get(y.childNodes[2].childNodes[1]);a.enableDisplayMode();n=new Ext.ProgressBar({renderTo:h});h.createChild({cls:"x-clear"})}return u},updateText:function(A){if(!u.isVisible()&&!b.width){u.setSize(this.maxWidth,100)}l.update(A||" ");var y=d!=""?(j.getWidth()+j.getMargins("lr")):0,C=l.getWidth()+l.getMargins("lr"),z=u.getFrameWidth("lr"),B=u.body.getFrameWidth("lr"),x;if(Ext.isIE&&y>0){y+=3}x=Math.max(Math.min(b.width||y+C+z+B,b.maxWidth||this.maxWidth),Math.max(b.minWidth||this.minWidth,o||0));if(b.prompt===true){v.setWidth(x-y-z-B)}if(b.progress===true||b.wait===true){n.setSize(x-y-z-B)}if(Ext.isIE&&x==o){x+=4}u.setSize(x,"auto").center();return this},updateProgress:function(y,x,z){n.updateProgress(y,x);if(z){this.updateText(z)}return this},isVisible:function(){return u&&u.isVisible()},hide:function(){var x=u?u.activeGhost:null;if(this.isVisible()||x){u.hide();w();if(x){u.unghost(false,false)}}return this},show:function(A){if(this.isVisible()){this.hide()}b=A;var B=this.getDialog(b.title||" ");B.setTitle(b.title||" ");var x=(b.closable!==false&&b.progress!==true&&b.wait!==true);B.tools.close.setDisplayed(x);v=s;b.prompt=b.prompt||(b.multiline?true:false);if(b.prompt){if(b.multiline){s.hide();a.show();a.setHeight(Ext.isNumber(b.multiline)?b.multiline:this.defaultTextHeight);v=a}else{s.show();a.hide()}}else{s.hide();a.hide()}v.dom.value=b.value||"";if(b.prompt){B.focusEl=v}else{var z=b.buttons;var y=null;if(z&&z.ok){y=r.ok}else{if(z&&z.yes){y=r.yes}}if(y){B.focusEl=y}}if(b.iconCls){B.setIconClass(b.iconCls)}this.setIcon(Ext.isDefined(b.icon)?b.icon:i);o=k(b.buttons);n.setVisible(b.progress===true||b.wait===true);this.updateProgress(0,b.progressText);this.updateText(b.msg);if(b.cls){B.el.addClass(b.cls)}B.proxyDrag=b.proxyDrag===true;B.modal=b.modal!==false;B.mask=b.modal!==false?q:false;if(!B.isVisible()){document.body.appendChild(u.el.dom);B.setAnimateTarget(b.animEl);B.on("show",function(){if(x===true){B.keyMap.enable()}else{B.keyMap.disable()}},this,{single:true});B.show(b.animEl)}if(b.wait===true){n.wait(b.waitConfig)}return this},setIcon:function(x){if(!u){i=x;return}i=undefined;if(x&&x!=""){j.removeClass("x-hidden");j.replaceClass(d,x);h.addClass("x-dlg-icon");d=x}else{j.replaceClass(d,"x-hidden");h.removeClass("x-dlg-icon");d=""}return this},progress:function(z,y,x){this.show({title:z,msg:y,buttons:false,progress:true,closable:false,minWidth:this.minProgressWidth,progressText:x});return this},wait:function(z,y,x){this.show({title:y,msg:z,buttons:false,closable:false,wait:true,modal:true,minWidth:this.minProgressWidth,waitConfig:x});return this},alert:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.OK,fn:y,scope:x,minWidth:this.minWidth});return this},confirm:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.YESNO,fn:y,scope:x,icon:this.QUESTION,minWidth:this.minWidth});return this},prompt:function(C,B,z,y,x,A){this.show({title:C,msg:B,buttons:this.OKCANCEL,fn:z,minWidth:this.minPromptWidth,scope:y,prompt:true,multiline:x,value:A});return this},OK:{ok:true},CANCEL:{cancel:true},OKCANCEL:{ok:true,cancel:true},YESNO:{yes:true,no:true},YESNOCANCEL:{yes:true,no:true,cancel:true},INFO:"ext-mb-info",WARNING:"ext-mb-warning",QUESTION:"ext-mb-question",ERROR:"ext-mb-error",defaultTextHeight:75,maxWidth:600,minWidth:100,minProgressWidth:250,minPromptWidth:250,buttonText:{ok:"OK",cancel:"Cancel",yes:"Yes",no:"No"}}}();Ext.Msg=Ext.MessageBox;Ext.dd.PanelProxy=function(a,b){this.panel=a;this.id=this.panel.id+"-ddproxy";Ext.apply(this,b)};Ext.dd.PanelProxy.prototype={insertProxy:true,setStatus:Ext.emptyFn,reset:Ext.emptyFn,update:Ext.emptyFn,stop:Ext.emptyFn,sync:Ext.emptyFn,getEl:function(){return this.ghost},getGhost:function(){return this.ghost},getProxy:function(){return this.proxy},hide:function(){if(this.ghost){if(this.proxy){this.proxy.remove();delete this.proxy}this.panel.el.dom.style.display="";this.ghost.remove();delete this.ghost}},show:function(){if(!this.ghost){this.ghost=this.panel.createGhost(undefined,undefined,Ext.getBody());this.ghost.setXY(this.panel.el.getXY());if(this.insertProxy){this.proxy=this.panel.el.insertSibling({cls:"x-panel-dd-spacer"});this.proxy.setSize(this.panel.getSize())}this.panel.el.dom.style.display="none"}},repair:function(b,c,a){this.hide();if(typeof c=="function"){c.call(a||this)}},moveProxy:function(a,b){if(this.proxy){a.insertBefore(this.proxy.dom,b)}}};Ext.Panel.DD=function(b,a){this.panel=b;this.dragData={panel:b};this.proxy=new Ext.dd.PanelProxy(b,a);Ext.Panel.DD.superclass.constructor.call(this,b.el,a);var c=b.header;if(c){this.setHandleElId(c.id)}(c?c:this.panel.body).setStyle("cursor","move");this.scroll=false};Ext.extend(Ext.Panel.DD,Ext.dd.DragSource,{showFrame:Ext.emptyFn,startDrag:Ext.emptyFn,b4StartDrag:function(a,b){this.proxy.show()},b4MouseDown:function(b){var a=b.getPageX();var c=b.getPageY();this.autoOffset(a,c)},onInitDrag:function(a,b){this.onStartDrag(a,b);return true},createFrame:Ext.emptyFn,getDragEl:function(a){return this.proxy.ghost.dom},endDrag:function(a){this.proxy.hide();this.panel.saveState()},autoOffset:function(a,b){a-=this.startPageX;b-=this.startPageY;this.setDelta(a,b)}});Ext.state.Provider=function(){this.addEvents("statechange");this.state={};Ext.state.Provider.superclass.constructor.call(this)};Ext.extend(Ext.state.Provider,Ext.util.Observable,{get:function(b,a){return typeof this.state[b]=="undefined"?a:this.state[b]},clear:function(a){delete this.state[a];this.fireEvent("statechange",this,a,null)},set:function(a,b){this.state[a]=b;this.fireEvent("statechange",this,a,b)},decodeValue:function(b){var e=/^(a|n|d|b|s|o)\:(.*)$/;var g=e.exec(unescape(b));if(!g||!g[1]){return}var d=g[1];var a=g[2];switch(d){case"n":return parseFloat(a);case"d":return new Date(Date.parse(a));case"b":return(a=="1");case"a":var c=[];if(a!=""){Ext.each(a.split("^"),function(h){c.push(this.decodeValue(h))},this)}return c;case"o":var c={};if(a!=""){Ext.each(a.split("^"),function(i){var h=i.split("=");c[h[0]]=this.decodeValue(h[1])},this)}return c;default:return a}},encodeValue:function(c){var b;if(typeof c=="number"){b="n:"+c}else{if(typeof c=="boolean"){b="b:"+(c?"1":"0")}else{if(Ext.isDate(c)){b="d:"+c.toGMTString()}else{if(Ext.isArray(c)){var g="";for(var e=0,a=c.length;e-1){var e=this.isSelected(b);var c=this.all.elements[b];var d=this.bufferRender([a],b)[0];this.all.replaceElement(b,d,true);if(e){this.selected.replaceElement(c,d);this.all.item(b).addClass(this.selectedClass)}this.updateIndexes(b,b)}},onAdd:function(g,d,e){if(this.all.getCount()===0){this.refresh();return}var c=this.bufferRender(d,e),h,b=this.all.elements;if(e0){if(!b){this.selected.removeClass(this.selectedClass)}this.selected.clear();this.last=false;if(!a){this.fireEvent("selectionchange",this,this.selected.elements)}}},isSelected:function(a){return this.selected.contains(this.getNode(a))},deselect:function(a){if(this.isSelected(a)){a=this.getNode(a);this.selected.removeElement(a);if(this.last==a.viewIndex){this.last=false}Ext.fly(a).removeClass(this.selectedClass);this.fireEvent("selectionchange",this,this.selected.elements)}},select:function(d,g,b){if(Ext.isArray(d)){if(!g){this.clearSelections(true)}for(var c=0,a=d.length;c=a&&d[c];c--){b.push(d[c])}}return b},indexOf:function(a){a=this.getNode(a);if(Ext.isNumber(a.viewIndex)){return a.viewIndex}return this.all.indexOf(a)},onBeforeLoad:function(){if(this.loadingText){this.clearSelections(false,true);this.getTemplateTarget().update('
'+this.loadingText+"
");this.all.clear()}},onDestroy:function(){this.all.clear();this.selected.clear();Ext.DataView.superclass.onDestroy.call(this);this.bindStore(null)}});Ext.DataView.prototype.setStore=Ext.DataView.prototype.bindStore;Ext.reg("dataview",Ext.DataView);Ext.list.ListView=Ext.extend(Ext.DataView,{itemSelector:"dl",selectedClass:"x-list-selected",overClass:"x-list-over",scrollOffset:undefined,columnResize:true,columnSort:true,maxWidth:Ext.isIE?99:100,initComponent:function(){if(this.columnResize){this.colResizer=new Ext.list.ColumnResizer(this.colResizer);this.colResizer.init(this)}if(this.columnSort){this.colSorter=new Ext.list.Sorter(this.columnSort);this.colSorter.init(this)}if(!this.internalTpl){this.internalTpl=new Ext.XTemplate('
','','
',"{header}","
","
",'
',"
",'
',"
")}if(!this.tpl){this.tpl=new Ext.XTemplate('',"
",'','
',' class="{cls}">',"{[values.tpl.apply(parent)]}","
","
",'
',"
","
")}var l=this.columns,h=0,k=0,m=l.length,b=[];for(var g=0;g10)){e.style.width=a+"px";g.style.width=a+"px"}else{e.style.width=b+"px";g.style.width=b+"px";setTimeout(function(){if((c.offsetWidth-c.clientWidth)>10){e.style.width=a+"px";g.style.width=a+"px"}},10)}}if(Ext.isNumber(d)){c.style.height=(d-g.parentNode.offsetHeight)+"px"}},updateIndexes:function(){Ext.list.ListView.superclass.updateIndexes.apply(this,arguments);this.verifyInternalSize()},findHeaderIndex:function(e){e=e.dom||e;var a=e.parentNode,d=a.parentNode.childNodes;for(var b=0,g;g=d[b];b++){if(g==a){return b}}return -1},setHdWidths:function(){var c=this.innerHd.dom.getElementsByTagName("div");for(var b=0,d=this.columns,a=d.length;b','','{text}',"");d.disableFormats=true;d.compile();Ext.TabPanel.prototype.itemTpl=d}this.items.each(this.initTab,this)},afterRender:function(){Ext.TabPanel.superclass.afterRender.call(this);if(this.autoTabs){this.readTabs(false)}if(this.activeTab!==undefined){var a=Ext.isObject(this.activeTab)?this.activeTab:this.items.get(this.activeTab);delete this.activeTab;this.setActiveTab(a)}},initEvents:function(){Ext.TabPanel.superclass.initEvents.call(this);this.mon(this.strip,{scope:this,mousedown:this.onStripMouseDown,contextmenu:this.onStripContextMenu});if(this.enableTabScroll){this.mon(this.strip,"mousewheel",this.onWheel,this)}},findTargets:function(c){var b=null,a=c.getTarget("li:not(.x-tab-edge)",this.strip);if(a){b=this.getComponent(a.id.split(this.idDelimiter)[1]);if(b.disabled){return{close:null,item:null,el:null}}}return{close:c.getTarget(".x-tab-strip-close",this.strip),item:b,el:a}},onStripMouseDown:function(b){if(b.button!==0){return}b.preventDefault();var a=this.findTargets(b);if(a.close){if(a.item.fireEvent("beforeclose",a.item)!==false){a.item.fireEvent("close",a.item);this.remove(a.item)}return}if(a.item&&a.item!=this.activeTab){this.setActiveTab(a.item)}},onStripContextMenu:function(b){b.preventDefault();var a=this.findTargets(b);if(a.item){this.fireEvent("contextmenu",this,a.item,b)}},readTabs:function(d){if(d===true){this.items.each(function(h){this.remove(h)},this)}var c=this.el.query(this.autoTabSelector);for(var b=0,a=c.length;b0){this.setActiveTab(0)}else{this.setActiveTab(null)}}}if(!this.destroying){this.delegateUpdates()}},onBeforeShowItem:function(a){if(a!=this.activeTab){this.setActiveTab(a);return false}},onItemDisabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).addClass("x-item-disabled")}this.stack.remove(b)},onItemEnabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).removeClass("x-item-disabled")}},onItemTitleChanged:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).child("span.x-tab-strip-text",true).innerHTML=b.title}},onItemIconChanged:function(d,a,c){var b=this.getTabEl(d);if(b){b=Ext.get(b);b.child("span.x-tab-strip-text").replaceClass(c,a);b[Ext.isEmpty(a)?"removeClass":"addClass"]("x-tab-with-icon")}},getTabEl:function(a){var b=this.getComponent(a);return b?b.tabEl:null},onResize:function(){Ext.TabPanel.superclass.onResize.apply(this,arguments);this.delegateUpdates()},beginUpdate:function(){this.suspendUpdates=true},endUpdate:function(){this.suspendUpdates=false;this.delegateUpdates()},hideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="none";this.delegateUpdates()}this.stack.remove(b)},unhideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="";this.delegateUpdates()}},delegateUpdates:function(){if(this.suspendUpdates){return}if(this.resizeTabs&&this.rendered){this.autoSizeTabs()}if(this.enableTabScroll&&this.rendered){this.autoScrollTabs()}},autoSizeTabs:function(){var h=this.items.length,b=this.tabPosition!="bottom"?"header":"footer",c=this[b].dom.offsetWidth,a=this[b].dom.clientWidth;if(!this.resizeTabs||h<1||!a){return}var k=Math.max(Math.min(Math.floor((a-4)/h)-this.tabMargin,this.tabWidth),this.minTabWidth);this.lastTabWidth=k;var m=this.strip.query("li:not(.x-tab-edge)");for(var e=0,j=m.length;e20?c:20);if(!this.scrolling){if(!this.scrollLeft){this.createScrollers()}else{this.scrollLeft.show();this.scrollRight.show()}}this.scrolling=true;if(i>(a-c)){e.scrollLeft=a-c}else{this.scrollToTab(this.activeTab,false)}this.updateScrollButtons()}},createScrollers:function(){this.pos.addClass("x-tab-scrolling-"+this.tabPosition);var c=this.stripWrap.dom.offsetHeight;var a=this.pos.insertFirst({cls:"x-tab-scroller-left"});a.setHeight(c);a.addClassOnOver("x-tab-scroller-left-over");this.leftRepeater=new Ext.util.ClickRepeater(a,{interval:this.scrollRepeatInterval,handler:this.onScrollLeft,scope:this});this.scrollLeft=a;var b=this.pos.insertFirst({cls:"x-tab-scroller-right"});b.setHeight(c);b.addClassOnOver("x-tab-scroller-right-over");this.rightRepeater=new Ext.util.ClickRepeater(b,{interval:this.scrollRepeatInterval,handler:this.onScrollRight,scope:this});this.scrollRight=b},getScrollWidth:function(){return this.edge.getOffsetsTo(this.stripWrap)[0]+this.getScrollPos()},getScrollPos:function(){return parseInt(this.stripWrap.dom.scrollLeft,10)||0},getScrollArea:function(){return parseInt(this.stripWrap.dom.clientWidth,10)||0},getScrollAnim:function(){return{duration:this.scrollDuration,callback:this.updateScrollButtons,scope:this}},getScrollIncrement:function(){return this.scrollIncrement||(this.resizeTabs?this.lastTabWidth+2:100)},scrollToTab:function(e,a){if(!e){return}var c=this.getTabEl(e),h=this.getScrollPos(),d=this.getScrollArea(),g=Ext.fly(c).getOffsetsTo(this.stripWrap)[0]+h,b=g+c.offsetWidth;if(g(h+d)){this.scrollTo(b-d,a)}}},scrollTo:function(b,a){this.stripWrap.scrollTo("left",b,a?this.getScrollAnim():false);if(!a){this.updateScrollButtons()}},onWheel:function(g){var h=g.getWheelDelta()*this.wheelIncrement*-1;g.stopEvent();var i=this.getScrollPos(),c=i+h,a=this.getScrollWidth()-this.getScrollArea();var b=Math.max(0,Math.min(a,c));if(b!=i){this.scrollTo(b,false)}},onScrollRight:function(){var a=this.getScrollWidth()-this.getScrollArea(),c=this.getScrollPos(),b=Math.min(a,c+this.getScrollIncrement());if(b!=c){this.scrollTo(b,this.animScroll)}},onScrollLeft:function(){var b=this.getScrollPos(),a=Math.max(0,b-this.getScrollIncrement());if(a!=b){this.scrollTo(a,this.animScroll)}},updateScrollButtons:function(){var a=this.getScrollPos();this.scrollLeft[a===0?"addClass":"removeClass"]("x-tab-scroller-left-disabled");this.scrollRight[a>=(this.getScrollWidth()-this.getScrollArea())?"addClass":"removeClass"]("x-tab-scroller-right-disabled")},beforeDestroy:function(){Ext.destroy(this.leftRepeater,this.rightRepeater);this.deleteMembers("strip","edge","scrollLeft","scrollRight","stripWrap");this.activeTab=null;Ext.TabPanel.superclass.beforeDestroy.apply(this)}});Ext.reg("tabpanel",Ext.TabPanel);Ext.TabPanel.prototype.activate=Ext.TabPanel.prototype.setActiveTab;Ext.TabPanel.AccessStack=function(){var a=[];return{add:function(b){a.push(b);if(a.length>10){a.shift()}},remove:function(e){var d=[];for(var c=0,b=a.length;c','  ','  ','  ',"");Ext.Button.buttonTemplate.compile()}this.template=Ext.Button.buttonTemplate}var b,d=this.getTemplateArgs();if(a){b=this.template.insertBefore(a,d,true)}else{b=this.template.append(c,d,true)}this.btnEl=b.child(this.buttonSelector);this.mon(this.btnEl,{scope:this,focus:this.onFocus,blur:this.onBlur});this.initButtonEl(b,this.btnEl);Ext.ButtonToggleMgr.register(this)},initButtonEl:function(b,c){this.el=b;this.setIcon(this.icon);this.setText(this.text);this.setIconClass(this.iconCls);if(Ext.isDefined(this.tabIndex)){c.dom.tabIndex=this.tabIndex}if(this.tooltip){this.setTooltip(this.tooltip,true)}if(this.handleMouseEvents){this.mon(b,{scope:this,mouseover:this.onMouseOver,mousedown:this.onMouseDown})}if(this.menu){this.mon(this.menu,{scope:this,show:this.onMenuShow,hide:this.onMenuHide})}if(this.repeat){var a=new Ext.util.ClickRepeater(b,Ext.isObject(this.repeat)?this.repeat:{});this.mon(a,"click",this.onClick,this)}this.mon(b,this.clickEvent,this.onClick,this)},afterRender:function(){Ext.Button.superclass.afterRender.call(this);this.useSetClass=true;this.setButtonClass();this.doc=Ext.getDoc();this.doAutoWidth()},setIconClass:function(a){this.iconCls=a;if(this.el){this.btnEl.dom.className="";this.btnEl.addClass(["x-btn-text",a||""]);this.setButtonClass()}return this},setTooltip:function(b,a){if(this.rendered){if(!a){this.clearTip()}if(Ext.isObject(b)){Ext.QuickTips.register(Ext.apply({target:this.btnEl.id},b));this.tooltip=b}else{this.btnEl.dom[this.tooltipType]=b}}else{this.tooltip=b}return this},clearTip:function(){if(Ext.isObject(this.tooltip)){Ext.QuickTips.unregister(this.btnEl)}},beforeDestroy:function(){if(this.rendered){this.clearTip()}if(this.menu&&this.destroyMenu!==false){Ext.destroy(this.menu)}Ext.destroy(this.repeater)},onDestroy:function(){if(this.rendered){this.doc.un("mouseover",this.monitorMouseOver,this);this.doc.un("mouseup",this.onMouseUp,this);delete this.doc;delete this.btnEl;Ext.ButtonToggleMgr.unregister(this)}Ext.Button.superclass.onDestroy.call(this)},doAutoWidth:function(){if(this.autoWidth!==false&&this.el&&this.text&&this.width===undefined){this.el.setWidth("auto");if(Ext.isIE7&&Ext.isStrict){var a=this.btnEl;if(a&&a.getWidth()>20){a.clip();a.setWidth(Ext.util.TextMetrics.measure(a,this.text).width+a.getFrameWidth("lr"))}}if(this.minWidth){if(this.el.getWidth()a}else{return c.getPageY()>this.btnEl.getRegion().bottom}},onClick:function(b,a){b.preventDefault();if(!this.disabled){if(this.isClickOnArrow(b)){if(this.menu&&!this.menu.isVisible()&&!this.ignoreNextClick){this.showMenu()}this.fireEvent("arrowclick",this,b);if(this.arrowHandler){this.arrowHandler.call(this.scope||this,this,b)}}else{if(this.enableToggle){this.toggle()}this.fireEvent("click",this,b);if(this.handler){this.handler.call(this.scope||this,this,b)}}}},isMenuTriggerOver:function(a){return this.menu&&a.target.tagName==this.arrowSelector},isMenuTriggerOut:function(b,a){return this.menu&&b.target.tagName!=this.arrowSelector}});Ext.reg("splitbutton",Ext.SplitButton);Ext.CycleButton=Ext.extend(Ext.SplitButton,{getItemText:function(a){if(a&&this.showText===true){var b="";if(this.prependText){b+=this.prependText}b+=a.text;return b}return undefined},setActiveItem:function(c,a){if(!Ext.isObject(c)){c=this.menu.getComponent(c)}if(c){if(!this.rendered){this.text=this.getItemText(c);this.iconCls=c.iconCls}else{var b=this.getItemText(c);if(b){this.setText(b)}this.setIconClass(c.iconCls)}this.activeItem=c;if(!c.checked){c.setChecked(true,false)}if(this.forceIcon){this.setIconClass(this.forceIcon)}if(!a){this.fireEvent("change",this,c)}}},getActiveItem:function(){return this.activeItem},initComponent:function(){this.addEvents("change");if(this.changeHandler){this.on("change",this.changeHandler,this.scope||this);delete this.changeHandler}this.itemCount=this.items.length;this.menu={cls:"x-cycle-menu",items:[]};var a=0;Ext.each(this.items,function(c,b){Ext.apply(c,{group:c.group||this.id,itemIndex:b,checkHandler:this.checkHandler,scope:this,checked:c.checked||false});this.menu.items.push(c);if(c.checked){a=b}},this);Ext.CycleButton.superclass.initComponent.call(this);this.on("click",this.toggleSelected,this);this.setActiveItem(a,true)},checkHandler:function(a,b){if(b){this.setActiveItem(a)}},toggleSelected:function(){var a=this.menu;a.render();if(!a.hasLayout){a.doLayout()}var d,b;for(var c=1;c"){b=new a.Fill()}else{b=new a.TextItem(b)}}}this.applyDefaults(b)}else{if(b.isFormField||b.render){b=this.createComponent(b)}else{if(b.tag){b=new a.Item({autoEl:b})}else{if(b.tagName){b=new a.Item({el:b})}else{if(Ext.isObject(b)){b=b.xtype?this.createComponent(b):this.constructButton(b)}}}}}return b},applyDefaults:function(e){if(!Ext.isString(e)){e=Ext.Toolbar.superclass.applyDefaults.call(this,e);var b=this.internalDefaults;if(e.events){Ext.applyIf(e.initialConfig,b);Ext.apply(e,b)}else{Ext.applyIf(e,b)}}return e},addSeparator:function(){return this.add(new a.Separator())},addSpacer:function(){return this.add(new a.Spacer())},addFill:function(){this.add(new a.Fill())},addElement:function(b){return this.addItem(new a.Item({el:b}))},addItem:function(b){return this.add.apply(this,arguments)},addButton:function(c){if(Ext.isArray(c)){var e=[];for(var d=0,b=c.length;d");this.items.push(this.displayItem=new a.TextItem({}))}Ext.PagingToolbar.superclass.initComponent.call(this);this.addEvents("change","beforechange");this.on("afterlayout",this.onFirstLayout,this,{single:true});this.cursor=0;this.bindStore(this.store,true)},onFirstLayout:function(){if(this.dsLoaded){this.onLoad.apply(this,this.dsLoaded)}},updateInfo:function(){if(this.displayItem){var b=this.store.getCount();var c=b==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+b,this.store.getTotalCount());this.displayItem.setText(c)}},onLoad:function(b,e,j){if(!this.rendered){this.dsLoaded=[b,e,j];return}var g=this.getParams();this.cursor=(j.params&&j.params[g.start])?j.params[g.start]:0;var i=this.getPageData(),c=i.activePage,h=i.pages;this.afterTextItem.setText(String.format(this.afterPageText,i.pages));this.inputItem.setValue(c);this.first.setDisabled(c==1);this.prev.setDisabled(c==1);this.next.setDisabled(c==h);this.last.setDisabled(c==h);this.refresh.enable();this.updateInfo();this.fireEvent("change",this,i)},getPageData:function(){var b=this.store.getTotalCount();return{total:b,activePage:Math.ceil((this.cursor+this.pageSize)/this.pageSize),pages:b=1&g<=j.pages){i.setValue(g)}}}}}},getParams:function(){return this.paramNames||this.store.paramNames},beforeLoad:function(){if(this.rendered&&this.refresh){this.refresh.disable()}},doLoad:function(d){var c={},b=this.getParams();c[b.start]=d;c[b.limit]=this.pageSize;if(this.fireEvent("beforechange",this,c)!==false){this.store.load({params:c})}},moveFirst:function(){this.doLoad(0)},movePrevious:function(){this.doLoad(Math.max(0,this.cursor-this.pageSize))},moveNext:function(){this.doLoad(this.cursor+this.pageSize)},moveLast:function(){var c=this.store.getTotalCount(),b=c%this.pageSize;this.doLoad(b?(c-b):c-this.pageSize)},doRefresh:function(){this.doLoad(this.cursor)},bindStore:function(c,d){var b;if(!d&&this.store){if(c!==this.store&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.beforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.onLoadError,this)}if(!c){this.store=null}}if(c){c=Ext.StoreMgr.lookup(c);c.on({scope:this,beforeload:this.beforeLoad,load:this.onLoad,exception:this.onLoadError});b=true}this.store=c;if(b){this.onLoad(c,null,{})}},unbind:function(b){this.bindStore(null)},bind:function(b){this.bindStore(b)},onDestroy:function(){this.bindStore(null);Ext.PagingToolbar.superclass.onDestroy.call(this)}})})();Ext.reg("paging",Ext.PagingToolbar);Ext.History=(function(){var e,c;var k=false;var d;function g(){var l=top.location.href,m=l.indexOf("#");return m>=0?l.substr(m+1):null}function a(){c.value=d}function h(l){d=l;Ext.History.fireEvent("change",l)}function i(m){var l=['
',Ext.util.Format.htmlEncode(m),"
"].join("");try{var o=e.contentWindow.document;o.open();o.write(l);o.close();return true}catch(n){return false}}function b(){if(!e.contentWindow||!e.contentWindow.document){setTimeout(b,10);return}var o=e.contentWindow.document;var m=o.getElementById("state");var l=m?m.innerText:null;var n=g();setInterval(function(){o=e.contentWindow.document;m=o.getElementById("state");var q=m?m.innerText:null;var p=g();if(q!==l){l=q;h(l);top.location.hash=l;n=l;a()}else{if(p!==n){n=p;i(p)}}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}function j(){d=c.value?c.value:g();if(Ext.isIE){b()}else{var l=g();setInterval(function(){var m=g();if(m!==l){l=m;h(l);a()}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}}return{fieldId:"x-history-field",iframeId:"x-history-frame",events:{},init:function(m,l){if(k){Ext.callback(m,l,[this]);return}if(!Ext.isReady){Ext.onReady(function(){Ext.History.init(m,l)});return}c=Ext.getDom(Ext.History.fieldId);if(Ext.isIE){e=Ext.getDom(Ext.History.iframeId)}this.addEvents("ready","change");if(m){this.on("ready",m,l,{single:true})}j()},add:function(l,m){if(m!==false){if(this.getToken()==l){return true}}if(Ext.isIE){return i(l)}else{top.location.hash=l;return true}},back:function(){history.go(-1)},forward:function(){history.go(1)},getToken:function(){return k?d:g()}}})();Ext.apply(Ext.History,new Ext.util.Observable());Ext.Tip=Ext.extend(Ext.Panel,{minWidth:40,maxWidth:300,shadow:"sides",defaultAlign:"tl-bl?",autoRender:true,quickShowInterval:250,frame:true,hidden:true,baseCls:"x-tip",floating:{shadow:true,shim:true,useDisplay:true,constrain:false},autoHeight:true,closeAction:"hide",initComponent:function(){Ext.Tip.superclass.initComponent.call(this);if(this.closable&&!this.title){this.elements+=",header"}},afterRender:function(){Ext.Tip.superclass.afterRender.call(this);if(this.closable){this.addTool({id:"close",handler:this[this.closeAction],scope:this})}},showAt:function(a){Ext.Tip.superclass.show.call(this);if(this.measureWidth!==false&&(!this.initialConfig||typeof this.initialConfig.width!="number")){this.doAutoWidth()}if(this.constrainPosition){a=this.el.adjustForConstraints(a)}this.setPagePosition(a[0],a[1])},doAutoWidth:function(a){a=a||0;var b=this.body.getTextWidth();if(this.title){b=Math.max(b,this.header.child("span").getTextWidth(this.title))}b+=this.getFrameWidth()+(this.closable?20:0)+this.body.getPadding("lr")+a;this.setWidth(b.constrain(this.minWidth,this.maxWidth));if(Ext.isIE7&&!this.repainted){this.el.repaint();this.repainted=true}},showBy:function(a,b){if(!this.rendered){this.render(Ext.getBody())}this.showAt(this.el.getAlignToXY(a,b||this.defaultAlign))},initDraggable:function(){this.dd=new Ext.Tip.DD(this,typeof this.draggable=="boolean"?null:this.draggable);this.header.addClass("x-tip-draggable")}});Ext.reg("tip",Ext.Tip);Ext.Tip.DD=function(b,a){Ext.apply(this,a);this.tip=b;Ext.Tip.DD.superclass.constructor.call(this,b.el.id,"WindowDD-"+b.id);this.setHandleElId(b.header.id);this.scroll=false};Ext.extend(Ext.Tip.DD,Ext.dd.DD,{moveOnly:true,scroll:false,headerOffsets:[100,25],startDrag:function(){this.tip.el.disableShadow()},endDrag:function(a){this.tip.el.enableShadow(true)}});Ext.ToolTip=Ext.extend(Ext.Tip,{showDelay:500,hideDelay:200,dismissDelay:5000,trackMouse:false,anchorToTarget:true,anchorOffset:0,targetCounter:0,constrainPosition:false,initComponent:function(){Ext.ToolTip.superclass.initComponent.call(this);this.lastActive=new Date();this.initTarget(this.target);this.origAnchor=this.anchor},onRender:function(b,a){Ext.ToolTip.superclass.onRender.call(this,b,a);this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl=this.el.createChild({cls:"x-tip-anchor "+this.anchorCls})},afterRender:function(){Ext.ToolTip.superclass.afterRender.call(this);this.anchorEl.setStyle("z-index",this.el.getZIndex()+1)},initTarget:function(c){var a;if((a=Ext.get(c))){if(this.target){var b=Ext.get(this.target);this.mun(b,"mouseover",this.onTargetOver,this);this.mun(b,"mouseout",this.onTargetOut,this);this.mun(b,"mousemove",this.onMouseMove,this)}this.mon(a,{mouseover:this.onTargetOver,mouseout:this.onTargetOut,mousemove:this.onMouseMove,scope:this});this.target=a}if(this.anchor){this.anchorTarget=this.target}},onMouseMove:function(b){var a=this.delegate?b.getTarget(this.delegate):this.triggerElement=true;if(a){this.targetXY=b.getXY();if(a===this.triggerElement){if(!this.hidden&&this.trackMouse){this.setPagePosition(this.getTargetXY())}}else{this.hide();this.lastActive=new Date(0);this.onTargetOver(b)}}else{if(!this.closable&&this.isVisible()){this.hide()}}},getTargetXY:function(){if(this.delegate){this.anchorTarget=this.triggerElement}if(this.anchor){this.targetCounter++;var c=this.getOffsets(),l=(this.anchorToTarget&&!this.trackMouse)?this.el.getAlignToXY(this.anchorTarget,this.getAnchorAlign()):this.targetXY,a=Ext.lib.Dom.getViewWidth()-5,h=Ext.lib.Dom.getViewHeight()-5,i=document.documentElement,e=document.body,k=(i.scrollLeft||e.scrollLeft||0)+5,j=(i.scrollTop||e.scrollTop||0)+5,b=[l[0]+c[0],l[1]+c[1]],g=this.getSize();this.anchorEl.removeClass(this.anchorCls);if(this.targetCounter<2){if(b[0]a){if(this.anchorToTarget){this.defaultAlign="r-l";if(this.mouseOffset){this.mouseOffset[0]*=-1}}this.anchor="right";return this.getTargetXY()}if(b[1]h){if(this.anchorToTarget){this.defaultAlign="b-t";if(this.mouseOffset){this.mouseOffset[1]*=-1}}this.anchor="bottom";return this.getTargetXY()}}this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl.addClass(this.anchorCls);this.targetCounter=0;return b}else{var d=this.getMouseOffset();return[this.targetXY[0]+d[0],this.targetXY[1]+d[1]]}},getMouseOffset:function(){var a=this.anchor?[0,0]:[15,18];if(this.mouseOffset){a[0]+=this.mouseOffset[0];a[1]+=this.mouseOffset[1]}return a},getAnchorPosition:function(){if(this.anchor){this.tipAnchor=this.anchor.charAt(0)}else{var a=this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!a){throw"AnchorTip.defaultAlign is invalid"}this.tipAnchor=a[1].charAt(0)}switch(this.tipAnchor){case"t":return"top";case"b":return"bottom";case"r":return"right"}return"left"},getAnchorAlign:function(){switch(this.anchor){case"top":return"tl-bl";case"left":return"tl-tr";case"right":return"tr-tl";default:return"bl-tl"}},getOffsets:function(){var b,a=this.getAnchorPosition().charAt(0);if(this.anchorToTarget&&!this.trackMouse){switch(a){case"t":b=[0,9];break;case"b":b=[0,-13];break;case"r":b=[-13,0];break;default:b=[9,0];break}}else{switch(a){case"t":b=[-15-this.anchorOffset,30];break;case"b":b=[-19-this.anchorOffset,-13-this.el.dom.offsetHeight];break;case"r":b=[-15-this.el.dom.offsetWidth,-13-this.anchorOffset];break;default:b=[25,-13-this.anchorOffset];break}}var c=this.getMouseOffset();b[0]+=c[0];b[1]+=c[1];return b},onTargetOver:function(b){if(this.disabled||b.within(this.target.dom,true)){return}var a=b.getTarget(this.delegate);if(a){this.triggerElement=a;this.clearTimer("hide");this.targetXY=b.getXY();this.delayShow()}},delayShow:function(){if(this.hidden&&!this.showTimer){if(this.lastActive.getElapsed()=c){d=c-b-5}}return{x:a,y:d}},beforeDestroy:function(){this.clearTimers();Ext.destroy(this.anchorEl);delete this.anchorEl;delete this.target;delete this.anchorTarget;delete this.triggerElement;Ext.ToolTip.superclass.beforeDestroy.call(this)},onDestroy:function(){Ext.getDoc().un("mousedown",this.onDocMouseDown,this);Ext.ToolTip.superclass.onDestroy.call(this)}});Ext.reg("tooltip",Ext.ToolTip);Ext.QuickTip=Ext.extend(Ext.ToolTip,{interceptTitles:false,tagConfig:{namespace:"ext",attribute:"qtip",width:"qwidth",target:"target",title:"qtitle",hide:"hide",cls:"qclass",align:"qalign",anchor:"anchor"},initComponent:function(){this.target=this.target||Ext.getDoc();this.targets=this.targets||{};Ext.QuickTip.superclass.initComponent.call(this)},register:function(e){var h=Ext.isArray(e)?e:arguments;for(var g=0,a=h.length;g1){var d=function(i,h){if(i&&h){var j=h.findChild(a,b);if(j){j.select();if(g){g(true,j)}}else{if(g){g(false,j)}}}else{if(g){g(false,j)}}};this.expandPath(c.join(this.pathSeparator),a,d)}else{this.root.select();if(g){g(true,this.root)}}},getTreeEl:function(){return this.body},onRender:function(b,a){Ext.tree.TreePanel.superclass.onRender.call(this,b,a);this.el.addClass("x-tree");this.innerCt=this.body.createChild({tag:"ul",cls:"x-tree-root-ct "+(this.useArrows?"x-tree-arrows":this.lines?"x-tree-lines":"x-tree-no-lines")})},initEvents:function(){Ext.tree.TreePanel.superclass.initEvents.call(this);if(this.containerScroll){Ext.dd.ScrollManager.register(this.body)}if((this.enableDD||this.enableDrop)&&!this.dropZone){this.dropZone=new Ext.tree.TreeDropZone(this,this.dropConfig||{ddGroup:this.ddGroup||"TreeDD",appendOnly:this.ddAppendOnly===true})}if((this.enableDD||this.enableDrag)&&!this.dragZone){this.dragZone=new Ext.tree.TreeDragZone(this,this.dragConfig||{ddGroup:this.ddGroup||"TreeDD",scroll:this.ddScroll})}this.getSelectionModel().init(this)},afterRender:function(){Ext.tree.TreePanel.superclass.afterRender.call(this);this.renderRoot()},beforeDestroy:function(){if(this.rendered){Ext.dd.ScrollManager.unregister(this.body);Ext.destroy(this.dropZone,this.dragZone)}this.destroyRoot();Ext.destroy(this.loader);this.nodeHash=this.root=this.loader=null;Ext.tree.TreePanel.superclass.beforeDestroy.call(this)},destroyRoot:function(){if(this.root&&this.root.destroy){this.root.destroy(true)}}});Ext.tree.TreePanel.nodeTypes={};Ext.reg("treepanel",Ext.tree.TreePanel);Ext.tree.TreeEventModel=function(a){this.tree=a;this.tree.on("render",this.initEvents,this)};Ext.tree.TreeEventModel.prototype={initEvents:function(){var a=this.tree;if(a.trackMouseOver!==false){a.mon(a.innerCt,{scope:this,mouseover:this.delegateOver,mouseout:this.delegateOut})}a.mon(a.getTreeEl(),{scope:this,click:this.delegateClick,dblclick:this.delegateDblClick,contextmenu:this.delegateContextMenu})},getNode:function(b){var a;if(a=b.getTarget(".x-tree-node-el",10)){var c=Ext.fly(a,"_treeEvents").getAttribute("tree-node-id","ext");if(c){return this.tree.getNodeById(c)}}return null},getNodeTarget:function(b){var a=b.getTarget(".x-tree-node-icon",1);if(!a){a=b.getTarget(".x-tree-node-el",6)}return a},delegateOut:function(b,a){if(!this.beforeEvent(b)){return}if(b.getTarget(".x-tree-ec-icon",1)){var c=this.getNode(b);this.onIconOut(b,c);if(c==this.lastEcOver){delete this.lastEcOver}}if((a=this.getNodeTarget(b))&&!b.within(a,true)){this.onNodeOut(b,this.getNode(b))}},delegateOver:function(b,a){if(!this.beforeEvent(b)){return}if(Ext.isGecko&&!this.trackingDoc){Ext.getBody().on("mouseover",this.trackExit,this);this.trackingDoc=true}if(this.lastEcOver){this.onIconOut(b,this.lastEcOver);delete this.lastEcOver}if(b.getTarget(".x-tree-ec-icon",1)){this.lastEcOver=this.getNode(b);this.onIconOver(b,this.lastEcOver)}if(a=this.getNodeTarget(b)){this.onNodeOver(b,this.getNode(b))}},trackExit:function(a){if(this.lastOverNode){if(this.lastOverNode.ui&&!a.within(this.lastOverNode.ui.getEl())){this.onNodeOut(a,this.lastOverNode)}delete this.lastOverNode;Ext.getBody().un("mouseover",this.trackExit,this);this.trackingDoc=false}},delegateClick:function(b,a){if(this.beforeEvent(b)){if(b.getTarget("input[type=checkbox]",1)){this.onCheckboxClick(b,this.getNode(b))}else{if(b.getTarget(".x-tree-ec-icon",1)){this.onIconClick(b,this.getNode(b))}else{if(this.getNodeTarget(b)){this.onNodeClick(b,this.getNode(b))}}}}else{this.checkContainerEvent(b,"click")}},delegateDblClick:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeDblClick(b,this.getNode(b))}}else{this.checkContainerEvent(b,"dblclick")}},delegateContextMenu:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeContextMenu(b,this.getNode(b))}}else{this.checkContainerEvent(b,"contextmenu")}},checkContainerEvent:function(b,a){if(this.disabled){b.stopEvent();return false}this.onContainerEvent(b,a)},onContainerEvent:function(b,a){this.tree.fireEvent("container"+a,this.tree,b)},onNodeClick:function(b,a){a.ui.onClick(b)},onNodeOver:function(b,a){this.lastOverNode=a;a.ui.onOver(b)},onNodeOut:function(b,a){a.ui.onOut(b)},onIconOver:function(b,a){a.ui.addClass("x-tree-ec-over")},onIconOut:function(b,a){a.ui.removeClass("x-tree-ec-over")},onIconClick:function(b,a){a.ui.ecClick(b)},onCheckboxClick:function(b,a){a.ui.onCheckChange(b)},onNodeDblClick:function(b,a){a.ui.onDblClick(b)},onNodeContextMenu:function(b,a){a.ui.onContextMenu(b)},beforeEvent:function(b){var a=this.getNode(b);if(this.disabled||!a||!a.ui){b.stopEvent();return false}return true},disable:function(){this.disabled=true},enable:function(){this.disabled=false}};Ext.tree.DefaultSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNode=null;this.addEvents("selectionchange","beforeselect");Ext.apply(this,a);Ext.tree.DefaultSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){this.select(a)},select:function(c,a){if(!Ext.fly(c.ui.wrap).isVisible()&&a){return a.call(this,c)}var b=this.selNode;if(c==b){c.ui.onSelectedChange(true)}else{if(this.fireEvent("beforeselect",this,c,b)!==false){if(b&&b.ui){b.ui.onSelectedChange(false)}this.selNode=c;c.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,c,b)}}return c},unselect:function(b,a){if(this.selNode==b){this.clearSelections(a)}},clearSelections:function(a){var b=this.selNode;if(b){b.ui.onSelectedChange(false);this.selNode=null;if(a!==true){this.fireEvent("selectionchange",this,null)}}return b},getSelectedNode:function(){return this.selNode},isSelected:function(a){return this.selNode==a},selectPrevious:function(a){if(!(a=a||this.selNode||this.lastSelNode)){return null}var c=a.previousSibling;if(c){if(!c.isExpanded()||c.childNodes.length<1){return this.select(c,this.selectPrevious)}else{var b=c.lastChild;while(b&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()&&b.childNodes.length>0){b=b.lastChild}return this.select(b,this.selectPrevious)}}else{if(a.parentNode&&(this.tree.rootVisible||!a.parentNode.isRoot)){return this.select(a.parentNode,this.selectPrevious)}}return null},selectNext:function(b){if(!(b=b||this.selNode||this.lastSelNode)){return null}if(b.firstChild&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()){return this.select(b.firstChild,this.selectNext)}else{if(b.nextSibling){return this.select(b.nextSibling,this.selectNext)}else{if(b.parentNode){var a=null;b.parentNode.bubble(function(){if(this.nextSibling){a=this.getOwnerTree().selModel.select(this.nextSibling,this.selectNext);return false}});return a}}}return null},onKeyDown:function(c){var b=this.selNode||this.lastSelNode;var d=this;if(!b){return}var a=c.getKey();switch(a){case c.DOWN:c.stopEvent();this.selectNext();break;case c.UP:c.stopEvent();this.selectPrevious();break;case c.RIGHT:c.preventDefault();if(b.hasChildNodes()){if(!b.isExpanded()){b.expand()}else{if(b.firstChild){this.select(b.firstChild,c)}}}break;case c.LEFT:c.preventDefault();if(b.hasChildNodes()&&b.isExpanded()){b.collapse()}else{if(b.parentNode&&(this.tree.rootVisible||b.parentNode!=this.tree.getRootNode())){this.select(b.parentNode,c)}}break}}});Ext.tree.MultiSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNodes=[];this.selMap={};this.addEvents("selectionchange");Ext.apply(this,a);Ext.tree.MultiSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){if(b.ctrlKey&&this.isSelected(a)){this.unselect(a)}else{this.select(a,b,b.ctrlKey)}},select:function(a,c,b){if(b!==true){this.clearSelections(true)}if(this.isSelected(a)){this.lastSelNode=a;return a}this.selNodes.push(a);this.selMap[a.id]=a;this.lastSelNode=a;a.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,this.selNodes);return a},unselect:function(b){if(this.selMap[b.id]){b.ui.onSelectedChange(false);var c=this.selNodes;var a=c.indexOf(b);if(a!=-1){this.selNodes.splice(a,1)}delete this.selMap[b.id];this.fireEvent("selectionchange",this,this.selNodes)}},clearSelections:function(b){var d=this.selNodes;if(d.length>0){for(var c=0,a=d.length;c0},isExpandable:function(){return this.attributes.expandable||this.hasChildNodes()},appendChild:function(e){var g=false;if(Ext.isArray(e)){g=e}else{if(arguments.length>1){g=arguments}}if(g){for(var d=0,a=g.length;d0){var g=d?function(){e.apply(d,arguments)}:e;c.sort(g);for(var b=0;b
','',this.indentMarkup,"",'','',g?('':"/>")):"",'',e.text,"
",'',""].join("");if(l!==true&&e.nextSibling&&(b=e.nextSibling.ui.getEl())){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",b,d)}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",j,d)}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1];var i=this.elNode.childNodes;this.indentNode=i[0];this.ecNode=i[1];this.iconNode=i[2];var h=3;if(g){this.checkbox=i[3];this.checkbox.defaultChecked=this.checkbox.checked;h++}this.anchor=i[h];this.textNode=i[h].firstChild},getAnchor:function(){return this.anchor},getTextEl:function(){return this.textNode},getIconEl:function(){return this.iconNode},isChecked:function(){return this.checkbox?this.checkbox.checked:false},updateExpandIcon:function(){if(this.rendered){var g=this.node,d,c,a=g.isLast()?"x-tree-elbow-end":"x-tree-elbow",e=g.hasChildNodes();if(e||g.attributes.expandable){if(g.expanded){a+="-minus";d="x-tree-node-collapsed";c="x-tree-node-expanded"}else{a+="-plus";d="x-tree-node-expanded";c="x-tree-node-collapsed"}if(this.wasLeaf){this.removeClass("x-tree-node-leaf");this.wasLeaf=false}if(this.c1!=d||this.c2!=c){Ext.fly(this.elNode).replaceClass(d,c);this.c1=d;this.c2=c}}else{if(!this.wasLeaf){Ext.fly(this.elNode).replaceClass("x-tree-node-expanded","x-tree-node-collapsed");delete this.c1;delete this.c2;this.wasLeaf=true}}var b="x-tree-ec-icon "+a;if(this.ecc!=b){this.ecNode.className=b;this.ecc=b}}},onIdChange:function(a){if(this.rendered){this.elNode.setAttribute("ext:tree-node-id",a)}},getChildIndent:function(){if(!this.childIndent){var a=[],b=this.node;while(b){if(!b.isRoot||(b.isRoot&&b.ownerTree.rootVisible)){if(!b.isLast()){a.unshift('')}else{a.unshift('')}}b=b.parentNode}this.childIndent=a.join("")}return this.childIndent},renderIndent:function(){if(this.rendered){var a="",b=this.node.parentNode;if(b){a=b.ui.getChildIndent()}if(this.indentMarkup!=a){this.indentNode.innerHTML=a;this.indentMarkup=a}this.updateExpandIcon()}},destroy:function(){if(this.elNode){Ext.dd.Registry.unregister(this.elNode.id)}Ext.each(["textnode","anchor","checkbox","indentNode","ecNode","iconNode","elNode","ctNode","wrap","holder"],function(a){if(this[a]){Ext.fly(this[a]).remove();delete this[a]}},this);delete this.node}};Ext.tree.RootTreeNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{render:function(){if(!this.rendered){var a=this.node.ownerTree.innerCt.dom;this.node.expanded=true;a.innerHTML='
';this.wrap=this.ctNode=a.firstChild}},collapse:Ext.emptyFn,expand:Ext.emptyFn});Ext.tree.TreeLoader=function(a){this.baseParams={};Ext.apply(this,a);this.addEvents("beforeload","load","loadexception");Ext.tree.TreeLoader.superclass.constructor.call(this);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}};Ext.extend(Ext.tree.TreeLoader,Ext.util.Observable,{uiProviders:{},clearOnLoad:true,paramOrder:undefined,paramsAsHash:false,nodeParameter:"node",directFn:undefined,load:function(b,c,a){if(this.clearOnLoad){while(b.firstChild){b.removeChild(b.firstChild)}}if(this.doPreload(b)){this.runCallback(c,a||b,[b])}else{if(this.directFn||this.dataUrl||this.url){this.requestData(b,c,a||b)}}},doPreload:function(d){if(d.attributes.children){if(d.childNodes.length<1){var c=d.attributes.children;d.beginUpdate();for(var b=0,a=c.length;b-1){c=[]}for(var d=0,a=b.length;dl){return e?-1:+1}else{return 0}}}};Ext.tree.TreeSorter.prototype={doSort:function(a){a.sort(this.sortFn)},compareNodes:function(b,a){return(b.text.toUpperCase()>a.text.toUpperCase()?1:-1)},updateSort:function(a,b){if(b.childrenRendered){this.doSort.defer(1,this,[b])}},updateSortParent:function(a){var b=a.parentNode;if(b&&b.childrenRendered){this.doSort.defer(1,this,[b])}}};if(Ext.dd.DropZone){Ext.tree.TreeDropZone=function(a,b){this.allowParentInsert=b.allowParentInsert||false;this.allowContainerDrop=b.allowContainerDrop||false;this.appendOnly=b.appendOnly||false;Ext.tree.TreeDropZone.superclass.constructor.call(this,a.getTreeEl(),b);this.tree=a;this.dragOverData={};this.lastInsertClass="x-tree-no-status"};Ext.extend(Ext.tree.TreeDropZone,Ext.dd.DropZone,{ddGroup:"TreeDD",expandDelay:1000,expandNode:function(a){if(a.hasChildNodes()&&!a.isExpanded()){a.expand(false,null,this.triggerCacheRefresh.createDelegate(this))}},queueExpand:function(a){this.expandProcId=this.expandNode.defer(this.expandDelay,this,[a])},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId);this.expandProcId=false}},isValidDropPoint:function(a,k,i,d,c){if(!a||!c){return false}var g=a.node;var h=c.node;if(!(g&&g.isTarget&&k)){return false}if(k=="append"&&g.allowChildren===false){return false}if((k=="above"||k=="below")&&(g.parentNode&&g.parentNode.allowChildren===false)){return false}if(h&&(g==h||h.contains(g))){return false}var b=this.dragOverData;b.tree=this.tree;b.target=g;b.data=c;b.point=k;b.source=i;b.rawEvent=d;b.dropNode=h;b.cancel=false;var j=this.tree.fireEvent("nodedragover",b);return b.cancel===false&&j!==false},getDropPoint:function(h,g,l){var m=g.node;if(m.isRoot){return m.allowChildren!==false?"append":false}var c=g.ddel;var o=Ext.lib.Dom.getY(c),j=o+c.offsetHeight;var i=Ext.lib.Event.getPageY(h);var k=m.allowChildren===false||m.isLeaf();if(this.appendOnly||m.parentNode.allowChildren===false){return k?false:"append"}var d=false;if(!this.allowParentInsert){d=m.hasChildNodes()&&m.isExpanded()}var a=(j-o)/(k?2:3);if(i>=o&&i<(o+a)){return"above"}else{if(!d&&(k||i>=j-a&&i<=j)){return"below"}else{return"append"}}},onNodeEnter:function(d,a,c,b){this.cancelExpand()},onContainerOver:function(a,c,b){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,c,b)){return this.dropAllowed}return this.dropNotAllowed},onNodeOver:function(b,i,h,g){var k=this.getDropPoint(h,b,i);var c=b.node;if(!this.expandProcId&&k=="append"&&c.hasChildNodes()&&!b.node.isExpanded()){this.queueExpand(c)}else{if(k!="append"){this.cancelExpand()}}var d=this.dropNotAllowed;if(this.isValidDropPoint(b,k,i,h,g)){if(k){var a=b.ddel;var j;if(k=="above"){d=b.node.isFirst()?"x-tree-drop-ok-above":"x-tree-drop-ok-between";j="x-tree-drag-insert-above"}else{if(k=="below"){d=b.node.isLast()?"x-tree-drop-ok-below":"x-tree-drop-ok-between";j="x-tree-drag-insert-below"}else{d="x-tree-drop-ok-append";j="x-tree-drag-append"}}if(this.lastInsertClass!=j){Ext.fly(a).replaceClass(this.lastInsertClass,j);this.lastInsertClass=j}}}return d},onNodeOut:function(d,a,c,b){this.cancelExpand();this.removeDropIndicators(d)},onNodeDrop:function(i,b,h,d){var a=this.getDropPoint(h,i,b);var g=i.node;g.ui.startDrop();if(!this.isValidDropPoint(i,a,b,h,d)){g.ui.endDrop();return false}var c=d.node||(b.getTreeNode?b.getTreeNode(d,g,a,h):null);return this.processDrop(g,d,a,b,h,c)},onContainerDrop:function(a,g,c){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,g,c)){var d=this.tree.getRootNode();d.ui.startDrop();var b=c.node||(a.getTreeNode?a.getTreeNode(c,d,"append",g):null);return this.processDrop(d,c,"append",a,g,b)}return false},processDrop:function(j,h,b,a,i,d){var g={tree:this.tree,target:j,data:h,point:b,source:a,rawEvent:i,dropNode:d,cancel:!d,dropStatus:false};var c=this.tree.fireEvent("beforenodedrop",g);if(c===false||g.cancel===true||!g.dropNode){j.ui.endDrop();return g.dropStatus}j=g.target;if(b=="append"&&!j.isExpanded()){j.expand(false,null,function(){this.completeDrop(g)}.createDelegate(this))}else{this.completeDrop(g)}return true},completeDrop:function(h){var d=h.dropNode,e=h.point,c=h.target;if(!Ext.isArray(d)){d=[d]}var g;for(var b=0,a=d.length;bd.offsetLeft){e.scrollLeft=d.offsetLeft}var a=Math.min(this.maxWidth,(e.clientWidth>20?e.clientWidth:e.offsetWidth)-Math.max(0,d.offsetLeft-e.scrollLeft)-5);this.setSize(a,"")},triggerEdit:function(a,c){this.completeEdit();if(a.attributes.editable!==false){this.editNode=a;if(this.tree.autoScroll){Ext.fly(a.ui.getEl()).scrollIntoView(this.tree.body)}var b=a.text||"";if(!Ext.isGecko&&Ext.isEmpty(a.text)){a.setText(" ")}this.autoEditTimer=this.startEdit.defer(this.editDelay,this,[a.ui.textNode,b]);return false}},bindScroll:function(){this.tree.getTreeEl().on("scroll",this.cancelEdit,this)},beforeNodeClick:function(a,b){clearTimeout(this.autoEditTimer);if(this.tree.getSelectionModel().isSelected(a)){b.stopEvent();return this.triggerEdit(a)}},onNodeDblClick:function(a,b){clearTimeout(this.autoEditTimer)},updateNode:function(a,b){this.tree.getTreeEl().un("scroll",this.cancelEdit,this);this.editNode.setText(b)},onHide:function(){Ext.tree.TreeEditor.superclass.onHide.call(this);if(this.editNode){this.editNode.ui.focus.defer(50,this.editNode.ui)}},onSpecialKey:function(c,b){var a=b.getKey();if(a==b.ESC){b.stopEvent();this.cancelEdit()}else{if(a==b.ENTER&&!b.hasModifier()){b.stopEvent();this.completeEdit()}}},onDestroy:function(){clearTimeout(this.autoEditTimer);Ext.tree.TreeEditor.superclass.onDestroy.call(this);var a=this.tree;a.un("beforeclick",this.beforeNodeClick,this);a.un("dblclick",this.onNodeDblClick,this)}}); +/* SWFObject v2.2 + is released under the MIT License +*/ +var swfobject=function(){var E="undefined",s="object",T="Shockwave Flash",X="ShockwaveFlash.ShockwaveFlash",r="application/x-shockwave-flash",S="SWFObjectExprInst",y="onreadystatechange",P=window,k=document,u=navigator,U=false,V=[i],p=[],O=[],J=[],m,R,F,C,K=false,a=false,o,H,n=true,N=function(){var ab=typeof k.getElementById!=E&&typeof k.getElementsByTagName!=E&&typeof k.createElement!=E,ai=u.userAgent.toLowerCase(),Z=u.platform.toLowerCase(),af=Z?/win/.test(Z):/win/.test(ai),ad=Z?/mac/.test(Z):/mac/.test(ai),ag=/webkit/.test(ai)?parseFloat(ai.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,Y=!+"\v1",ah=[0,0,0],ac=null;if(typeof u.plugins!=E&&typeof u.plugins[T]==s){ac=u.plugins[T].description;if(ac&&!(typeof u.mimeTypes!=E&&u.mimeTypes[r]&&!u.mimeTypes[r].enabledPlugin)){U=true;Y=false;ac=ac.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ah[0]=parseInt(ac.replace(/^(.*)\..*$/,"$1"),10);ah[1]=parseInt(ac.replace(/^.*\.(.*)\s.*$/,"$1"),10);ah[2]=/[a-zA-Z]/.test(ac)?parseInt(ac.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof P.ActiveXObject!=E){try{var ae=new ActiveXObject(X);if(ae){ac=ae.GetVariable("$version");if(ac){Y=true;ac=ac.split(" ")[1].split(",");ah=[parseInt(ac[0],10),parseInt(ac[1],10),parseInt(ac[2],10)]}}}catch(aa){}}}return{w3:ab,pv:ah,wk:ag,ie:Y,win:af,mac:ad}}(),l=function(){if(!N.w3){return}if((typeof k.readyState!=E&&k.readyState=="complete")||(typeof k.readyState==E&&(k.getElementsByTagName("body")[0]||k.body))){g()}if(!K){if(typeof k.addEventListener!=E){k.addEventListener("DOMContentLoaded",g,false)}if(N.ie&&N.win){k.attachEvent(y,function(){if(k.readyState=="complete"){k.detachEvent(y,arguments.callee);g()}});if(P==top){(function(){if(K){return}try{k.documentElement.doScroll("left")}catch(Y){setTimeout(arguments.callee,0);return}g()})()}}if(N.wk){(function(){if(K){return}if(!/loaded|complete/.test(k.readyState)){setTimeout(arguments.callee,0);return}g()})()}t(g)}}();function g(){if(K){return}try{var aa=k.getElementsByTagName("body")[0].appendChild(D("span"));aa.parentNode.removeChild(aa)}catch(ab){return}K=true;var Y=V.length;for(var Z=0;Z0){for(var ag=0;ag0){var af=c(Z);if(af){if(G(p[ag].swfVersion)&&!(N.wk&&N.wk<312)){x(Z,true);if(ac){ab.success=true;ab.ref=A(Z);ac(ab)}}else{if(p[ag].expressInstall&&B()){var aj={};aj.data=p[ag].expressInstall;aj.width=af.getAttribute("width")||"0";aj.height=af.getAttribute("height")||"0";if(af.getAttribute("class")){aj.styleclass=af.getAttribute("class")}if(af.getAttribute("align")){aj.align=af.getAttribute("align")}var ai={};var Y=af.getElementsByTagName("param");var ad=Y.length;for(var ae=0;ae'}}ab.outerHTML='"+ag+"";O[O.length]=aj.id;Y=c(aj.id)}else{var aa=D(s);aa.setAttribute("type",r);for(var ad in aj){if(aj[ad]!=Object.prototype[ad]){if(ad.toLowerCase()=="styleclass"){aa.setAttribute("class",aj[ad])}else{if(ad.toLowerCase()!="classid"){aa.setAttribute(ad,aj[ad])}}}}for(var ac in ah){if(ah[ac]!=Object.prototype[ac]&&ac.toLowerCase()!="movie"){e(aa,ac,ah[ac])}}ab.parentNode.replaceChild(aa,ab);Y=aa}}return Y}function e(aa,Y,Z){var ab=D("param");ab.setAttribute("name",Y);ab.setAttribute("value",Z);aa.appendChild(ab)}function z(Z){var Y=c(Z);if(Y&&Y.nodeName=="OBJECT"){if(N.ie&&N.win){Y.style.display="none";(function(){if(Y.readyState==4){b(Z)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.removeChild(Y)}}}function b(aa){var Z=c(aa);if(Z){for(var Y in Z){if(typeof Z[Y]=="function"){Z[Y]=null}}Z.parentNode.removeChild(Z)}}function c(aa){var Y=null;try{Y=k.getElementById(aa)}catch(Z){}return Y}function D(Y){return k.createElement(Y)}function j(aa,Y,Z){aa.attachEvent(Y,Z);J[J.length]=[aa,Y,Z]}function G(aa){var Z=N.pv,Y=aa.split(".");Y[0]=parseInt(Y[0],10);Y[1]=parseInt(Y[1],10)||0;Y[2]=parseInt(Y[2],10)||0;return(Z[0]>Y[0]||(Z[0]==Y[0]&&Z[1]>Y[1])||(Z[0]==Y[0]&&Z[1]==Y[1]&&Z[2]>=Y[2]))?true:false}function w(ad,Z,ae,ac){if(N.ie&&N.mac){return}var ab=k.getElementsByTagName("head")[0];if(!ab){return}var Y=(ae&&typeof ae=="string")?ae:"screen";if(ac){o=null;H=null}if(!o||H!=Y){var aa=D("style");aa.setAttribute("type","text/css");aa.setAttribute("media",Y);o=ab.appendChild(aa);if(N.ie&&N.win&&typeof k.styleSheets!=E&&k.styleSheets.length>0){o=k.styleSheets[k.styleSheets.length-1]}H=Y}if(N.ie&&N.win){if(o&&typeof o.addRule==s){o.addRule(ad,Z)}}else{if(o&&typeof k.createTextNode!=E){o.appendChild(k.createTextNode(ad+" {"+Z+"}"))}}}function x(aa,Y){if(!n){return}var Z=Y?"visible":"hidden";if(K&&c(aa)){c(aa).style.visibility=Z}else{w("#"+aa,"visibility:"+Z)}}function M(Z){var aa=/[\\\"<>\.;]/;var Y=aa.exec(Z)!=null;return Y&&typeof encodeURIComponent!=E?encodeURIComponent(Z):Z}var d=function(){if(N.ie&&N.win){window.attachEvent("onunload",function(){var ad=J.length;for(var ac=0;ac0){for(h=0;h-1&&e.position=="left"){e.position="bottom"}return e},onDestroy:function(){Ext.chart.CartesianChart.superclass.onDestroy.call(this);Ext.each(this.labelFn,function(a){this.removeFnProxy(a)},this)}});Ext.reg("cartesianchart",Ext.chart.CartesianChart);Ext.chart.LineChart=Ext.extend(Ext.chart.CartesianChart,{type:"line"});Ext.reg("linechart",Ext.chart.LineChart);Ext.chart.ColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"column"});Ext.reg("columnchart",Ext.chart.ColumnChart);Ext.chart.StackedColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackcolumn"});Ext.reg("stackedcolumnchart",Ext.chart.StackedColumnChart);Ext.chart.BarChart=Ext.extend(Ext.chart.CartesianChart,{type:"bar"});Ext.reg("barchart",Ext.chart.BarChart);Ext.chart.StackedBarChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackbar"});Ext.reg("stackedbarchart",Ext.chart.StackedBarChart);Ext.chart.Axis=function(a){Ext.apply(this,a)};Ext.chart.Axis.prototype={type:null,orientation:"horizontal",reverse:false,labelFunction:null,hideOverlappingLabels:true,labelSpacing:2};Ext.chart.NumericAxis=Ext.extend(Ext.chart.Axis,{type:"numeric",minimum:NaN,maximum:NaN,majorUnit:NaN,minorUnit:NaN,snapToUnits:true,alwaysShowZero:true,scale:"linear",roundMajorUnit:true,calculateByLabelSize:true,position:"left",adjustMaximumByMajorUnit:true,adjustMinimumByMajorUnit:true});Ext.chart.TimeAxis=Ext.extend(Ext.chart.Axis,{type:"time",minimum:null,maximum:null,majorUnit:NaN,majorTimeUnit:null,minorUnit:NaN,minorTimeUnit:null,snapToUnits:true,stackingEnabled:false,calculateByLabelSize:true});Ext.chart.CategoryAxis=Ext.extend(Ext.chart.Axis,{type:"category",categoryNames:null,calculateCategoryCount:false});Ext.chart.Series=function(a){Ext.apply(this,a)};Ext.chart.Series.prototype={type:null,displayName:null};Ext.chart.CartesianSeries=Ext.extend(Ext.chart.Series,{xField:null,yField:null,showInLegend:true,axis:"primary"});Ext.chart.ColumnSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"column"});Ext.chart.LineSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"line"});Ext.chart.BarSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"bar"});Ext.chart.PieSeries=Ext.extend(Ext.chart.Series,{type:"pie",dataField:null,categoryField:null});Ext.menu.Menu=Ext.extend(Ext.Container,{minWidth:120,shadow:"sides",subMenuAlign:"tl-tr?",defaultAlign:"tl-bl?",allowOtherMenus:false,ignoreParentClicks:false,enableScrolling:true,maxHeight:null,scrollIncrement:24,showSeparator:true,defaultOffsets:[0,0],plain:false,floating:true,zIndex:15000,hidden:true,layout:"menu",hideMode:"offsets",scrollerHeight:8,autoLayout:true,defaultType:"menuitem",bufferResize:false,initComponent:function(){if(Ext.isArray(this.initialConfig)){Ext.apply(this,{items:this.initialConfig})}this.addEvents("click","mouseover","mouseout","itemclick");Ext.menu.MenuMgr.register(this);if(this.floating){Ext.EventManager.onWindowResize(this.hide,this)}else{if(this.initialConfig.hidden!==false){this.hidden=false}this.internalDefaults={hideOnClick:false}}Ext.menu.Menu.superclass.initComponent.call(this);if(this.autoLayout){var a=this.doLayout.createDelegate(this,[]);this.on({add:a,remove:a})}},getLayoutTarget:function(){return this.ul},onRender:function(b,a){if(!b){b=Ext.getBody()}var c={id:this.getId(),cls:"x-menu "+((this.floating)?"x-menu-floating x-layer ":"")+(this.cls||"")+(this.plain?" x-menu-plain":"")+(this.showSeparator?"":" x-menu-nosep"),style:this.style,cn:[{tag:"a",cls:"x-menu-focus",href:"#",onclick:"return false;",tabIndex:"-1"},{tag:"ul",cls:"x-menu-list"}]};if(this.floating){this.el=new Ext.Layer({shadow:this.shadow,dh:c,constrain:false,parentEl:b,zindex:this.zIndex})}else{this.el=b.createChild(c)}Ext.menu.Menu.superclass.onRender.call(this,b,a);if(!this.keyNav){this.keyNav=new Ext.menu.MenuNav(this)}this.focusEl=this.el.child("a.x-menu-focus");this.ul=this.el.child("ul.x-menu-list");this.mon(this.ul,{scope:this,click:this.onClick,mouseover:this.onMouseOver,mouseout:this.onMouseOut});if(this.enableScrolling){this.mon(this.el,{scope:this,delegate:".x-menu-scroller",click:this.onScroll,mouseover:this.deactivateActive})}},findTargetItem:function(b){var a=b.getTarget(".x-menu-list-item",this.ul,true);if(a&&a.menuItemId){return this.items.get(a.menuItemId)}},onClick:function(b){var a=this.findTargetItem(b);if(a){if(a.isFormField){this.setActiveItem(a)}else{if(a instanceof Ext.menu.BaseItem){if(a.menu&&this.ignoreParentClicks){a.expandMenu();b.preventDefault()}else{if(a.onClick){a.onClick(b);this.fireEvent("click",this,a,b)}}}}}},setActiveItem:function(a,b){if(a!=this.activeItem){this.deactivateActive();if((this.activeItem=a).isFormField){a.focus()}else{a.activate(b)}}else{if(b){a.expandMenu()}}},deactivateActive:function(){var b=this.activeItem;if(b){if(b.isFormField){if(b.collapse){b.collapse()}}else{b.deactivate()}delete this.activeItem}},tryActivate:function(g,e){var b=this.items;for(var c=g,a=b.length;c>=0&&c=a.scrollHeight){this.onScrollerOut(null,b)}},onScrollerIn:function(d,b){var a=this.ul.dom,c=Ext.fly(b).is(".x-menu-scroller-top");if(c?a.scrollTop>0:a.scrollTop+this.activeMaxc){b=c;a=i-h}else{if(bb&&b>0){this.activeMax=b-this.scrollerHeight*2-this.el.getFrameWidth("tb")-Ext.num(this.el.shadowOffset,0);this.ul.setHeight(this.activeMax);this.createScrollers();this.el.select(".x-menu-scroller").setDisplayed("")}else{this.ul.setHeight(d);this.el.select(".x-menu-scroller").setDisplayed("none")}this.ul.dom.scrollTop=0;return a},createScrollers:function(){if(!this.scroller){this.scroller={pos:0,top:this.el.insertFirst({tag:"div",cls:"x-menu-scroller x-menu-scroller-top",html:" "}),bottom:this.el.createChild({tag:"div",cls:"x-menu-scroller x-menu-scroller-bottom",html:" "})};this.scroller.top.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.topRepeater=new Ext.util.ClickRepeater(this.scroller.top,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.top],false)}});this.scroller.bottom.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.bottomRepeater=new Ext.util.ClickRepeater(this.scroller.bottom,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.bottom],false)}})}},onLayout:function(){if(this.isVisible()){if(this.enableScrolling){this.constrainScroll(this.el.getTop())}if(this.floating){this.el.sync()}}},focus:function(){if(!this.hidden){this.doFocus.defer(50,this)}},doFocus:function(){if(!this.hidden){this.focusEl.focus()}},hide:function(a){if(!this.isDestroyed){this.deepHide=a;Ext.menu.Menu.superclass.hide.call(this);delete this.deepHide}},onHide:function(){Ext.menu.Menu.superclass.onHide.call(this);this.deactivateActive();if(this.el&&this.floating){this.el.hide()}var a=this.parentMenu;if(this.deepHide===true&&a){if(a.floating){a.hide(true)}else{a.deactivateActive()}}},lookupComponent:function(a){if(Ext.isString(a)){a=(a=="separator"||a=="-")?new Ext.menu.Separator():new Ext.menu.TextItem(a);this.applyDefaults(a)}else{if(Ext.isObject(a)){a=this.getMenuItem(a)}else{if(a.tagName||a.el){a=new Ext.BoxComponent({el:a})}}}return a},applyDefaults:function(b){if(!Ext.isString(b)){b=Ext.menu.Menu.superclass.applyDefaults.call(this,b);var a=this.internalDefaults;if(a){if(b.events){Ext.applyIf(b.initialConfig,a);Ext.apply(b,a)}else{Ext.applyIf(b,a)}}}return b},getMenuItem:function(a){if(!a.isXType){if(!a.xtype&&Ext.isBoolean(a.checked)){return new Ext.menu.CheckItem(a)}return Ext.create(a,this.defaultType)}return a},addSeparator:function(){return this.add(new Ext.menu.Separator())},addElement:function(a){return this.add(new Ext.menu.BaseItem({el:a}))},addItem:function(a){return this.add(a)},addMenuItem:function(a){return this.add(this.getMenuItem(a))},addText:function(a){return this.add(new Ext.menu.TextItem(a))},onDestroy:function(){Ext.EventManager.removeResizeListener(this.hide,this);var a=this.parentMenu;if(a&&a.activeChild==this){delete a.activeChild}delete this.parentMenu;Ext.menu.Menu.superclass.onDestroy.call(this);Ext.menu.MenuMgr.unregister(this);if(this.keyNav){this.keyNav.disable()}var b=this.scroller;if(b){Ext.destroy(b.topRepeater,b.bottomRepeater,b.top,b.bottom)}Ext.destroy(this.el,this.focusEl,this.ul)}});Ext.reg("menu",Ext.menu.Menu);Ext.menu.MenuNav=Ext.extend(Ext.KeyNav,function(){function a(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)-1,-1)){c.tryActivate(c.items.length-1,-1)}}function b(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)+1,1)){c.tryActivate(0,1)}}return{constructor:function(c){Ext.menu.MenuNav.superclass.constructor.call(this,c.el);this.scope=this.menu=c},doRelay:function(g,d){var c=g.getKey();if(this.menu.activeItem&&this.menu.activeItem.isFormField&&c!=g.TAB){return false}if(!this.menu.activeItem&&g.isNavKeyPress()&&c!=g.SPACE&&c!=g.RETURN){this.menu.tryActivate(0,1);return false}return d.call(this.scope||this,g,this.menu)},tab:function(d,c){d.stopEvent();if(d.shiftKey){a(d,c)}else{b(d,c)}},up:a,down:b,right:function(d,c){if(c.activeItem){c.activeItem.expandMenu(true)}},left:function(d,c){c.hide();if(c.parentMenu&&c.parentMenu.activeItem){c.parentMenu.activeItem.activate()}},enter:function(d,c){if(c.activeItem){d.stopPropagation();c.activeItem.onClick(d);c.fireEvent("click",this,c.activeItem);return true}}}}());Ext.menu.MenuMgr=function(){var g,d,c={},a=false,l=new Date();function n(){g={};d=new Ext.util.MixedCollection();Ext.getDoc().addKeyListener(27,function(){if(d.length>0){i()}})}function i(){if(d&&d.length>0){var o=d.clone();o.each(function(p){p.hide()});return true}return false}function e(o){d.remove(o);if(d.length<1){Ext.getDoc().un("mousedown",m);a=false}}function k(o){var p=d.last();l=new Date();d.add(o);if(!a){Ext.getDoc().on("mousedown",m);a=true}if(o.parentMenu){o.getEl().setZIndex(parseInt(o.parentMenu.getEl().getStyle("z-index"),10)+3);o.parentMenu.activeChild=o}else{if(p&&!p.isDestroyed&&p.isVisible()){o.getEl().setZIndex(parseInt(p.getEl().getStyle("z-index"),10)+3)}}}function b(o){if(o.activeChild){o.activeChild.hide()}if(o.autoHideTimer){clearTimeout(o.autoHideTimer);delete o.autoHideTimer}}function h(o){var p=o.parentMenu;if(!p&&!o.allowOtherMenus){i()}else{if(p&&p.activeChild){p.activeChild.hide()}}}function m(o){if(l.getElapsed()>50&&d.length>0&&!o.getTarget(".x-menu")){i()}}function j(p,s){if(s){var r=c[p.group];for(var q=0,o=r.length;q',' target="{hrefTarget}"',"",">",'','{text}',"")}var c=this.getTemplateArgs();this.el=b?this.itemTpl.insertBefore(b,c,true):this.itemTpl.append(d,c,true);this.iconEl=this.el.child("img.x-menu-item-icon");this.textEl=this.el.child(".x-menu-item-text");if(!this.href){this.mon(this.el,"click",Ext.emptyFn,null,{preventDefault:true})}Ext.menu.Item.superclass.onRender.call(this,d,b)},getTemplateArgs:function(){return{id:this.id,cls:this.itemCls+(this.menu?" x-menu-item-arrow":"")+(this.cls?" "+this.cls:""),href:this.href||"#",hrefTarget:this.hrefTarget,icon:this.icon||Ext.BLANK_IMAGE_URL,iconCls:this.iconCls||"",text:this.itemText||this.text||" "}},setText:function(a){this.text=a||" ";if(this.rendered){this.textEl.update(this.text);this.parentMenu.layout.doAutoSize()}},setIconClass:function(a){var b=this.iconCls;this.iconCls=a;if(this.rendered){this.iconEl.replaceClass(b,this.iconCls)}},beforeDestroy:function(){if(this.menu){delete this.menu.ownerCt;this.menu.destroy()}Ext.menu.Item.superclass.beforeDestroy.call(this)},handleClick:function(a){if(!this.href){a.stopEvent()}Ext.menu.Item.superclass.handleClick.apply(this,arguments)},activate:function(a){if(Ext.menu.Item.superclass.activate.apply(this,arguments)){this.focus();if(a){this.expandMenu()}}return true},shouldDeactivate:function(a){if(Ext.menu.Item.superclass.shouldDeactivate.call(this,a)){if(this.menu&&this.menu.isVisible()){return !this.menu.getEl().getRegion().contains(a.getPoint())}return true}return false},deactivate:function(){Ext.menu.Item.superclass.deactivate.apply(this,arguments);this.hideMenu()},expandMenu:function(a){if(!this.disabled&&this.menu){clearTimeout(this.hideTimer);delete this.hideTimer;if(!this.menu.isVisible()&&!this.showTimer){this.showTimer=this.deferExpand.defer(this.showDelay,this,[a])}else{if(this.menu.isVisible()&&a){this.menu.tryActivate(0,1)}}}},deferExpand:function(a){delete this.showTimer;this.menu.show(this.container,this.parentMenu.subMenuAlign||"tl-tr?",this.parentMenu);if(a){this.menu.tryActivate(0,1)}},hideMenu:function(){clearTimeout(this.showTimer);delete this.showTimer;if(!this.hideTimer&&this.menu&&this.menu.isVisible()){this.hideTimer=this.deferHide.defer(this.hideDelay,this)}},deferHide:function(){delete this.hideTimer;if(this.menu.over){this.parentMenu.setActiveItem(this,false)}else{this.menu.hide()}}});Ext.reg("menuitem",Ext.menu.Item);Ext.menu.CheckItem=Ext.extend(Ext.menu.Item,{itemCls:"x-menu-item x-menu-check-item",groupClass:"x-menu-group-item",checked:false,ctype:"Ext.menu.CheckItem",initComponent:function(){Ext.menu.CheckItem.superclass.initComponent.call(this);this.addEvents("beforecheckchange","checkchange");if(this.checkHandler){this.on("checkchange",this.checkHandler,this.scope)}Ext.menu.MenuMgr.registerCheckable(this)},onRender:function(a){Ext.menu.CheckItem.superclass.onRender.apply(this,arguments);if(this.group){this.el.addClass(this.groupClass)}if(this.checked){this.checked=false;this.setChecked(true,true)}},destroy:function(){Ext.menu.MenuMgr.unregisterCheckable(this);Ext.menu.CheckItem.superclass.destroy.apply(this,arguments)},setChecked:function(b,a){var c=a===true;if(this.checked!=b&&(c||this.fireEvent("beforecheckchange",this,b)!==false)){if(this.container){this.container[b?"addClass":"removeClass"]("x-menu-item-checked")}this.checked=b;if(!c){this.fireEvent("checkchange",this,b)}}},handleClick:function(a){if(!this.disabled&&!(this.checked&&this.group)){this.setChecked(!this.checked)}Ext.menu.CheckItem.superclass.handleClick.apply(this,arguments)}});Ext.reg("menucheckitem",Ext.menu.CheckItem);Ext.menu.DateMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,pickerId:null,cls:"x-date-menu",initComponent:function(){this.on("beforeshow",this.onBeforeShow,this);if(this.strict=(Ext.isIE7&&Ext.isStrict)){this.on("show",this.onShow,this,{single:true,delay:20})}Ext.apply(this,{plain:true,showSeparator:false,items:this.picker=new Ext.DatePicker(Ext.applyIf({internalRender:this.strict||!Ext.isIE,ctCls:"x-menu-date-item",id:this.pickerId},this.initialConfig))});this.picker.purgeListeners();Ext.menu.DateMenu.superclass.initComponent.call(this);this.relayEvents(this.picker,["select"]);this.on("show",this.picker.focus,this.picker);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}},onBeforeShow:function(){if(this.picker){this.picker.hideMonthPicker(true)}},onShow:function(){var a=this.picker.getEl();a.setWidth(a.getWidth())}});Ext.reg("datemenu",Ext.menu.DateMenu);Ext.menu.ColorMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,cls:"x-color-menu",paletteId:null,initComponent:function(){Ext.apply(this,{plain:true,showSeparator:false,items:this.palette=new Ext.ColorPalette(Ext.applyIf({id:this.paletteId},this.initialConfig))});this.palette.purgeListeners();Ext.menu.ColorMenu.superclass.initComponent.call(this);this.relayEvents(this.palette,["select"]);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}}});Ext.reg("colormenu",Ext.menu.ColorMenu);Ext.form.Field=Ext.extend(Ext.BoxComponent,{invalidClass:"x-form-invalid",invalidText:"The value in this field is invalid",focusClass:"x-form-focus",validationEvent:"keyup",validateOnBlur:true,validationDelay:250,defaultAutoCreate:{tag:"input",type:"text",size:"20",autocomplete:"off"},fieldClass:"x-form-field",msgTarget:"qtip",msgFx:"normal",readOnly:false,disabled:false,submitValue:true,isFormField:true,msgDisplay:"",hasFocus:false,initComponent:function(){Ext.form.Field.superclass.initComponent.call(this);this.addEvents("focus","blur","specialkey","change","invalid","valid")},getName:function(){return this.rendered&&this.el.dom.name?this.el.dom.name:this.name||this.id||""},onRender:function(c,a){if(!this.el){var b=this.getAutoCreate();if(!b.name){b.name=this.name||this.id}if(this.inputType){b.type=this.inputType}this.autoEl=b}Ext.form.Field.superclass.onRender.call(this,c,a);if(this.submitValue===false){this.el.dom.removeAttribute("name")}var d=this.el.dom.type;if(d){if(d=="password"){d="text"}this.el.addClass("x-form-"+d)}if(this.readOnly){this.setReadOnly(true)}if(this.tabIndex!==undefined){this.el.dom.setAttribute("tabIndex",this.tabIndex)}this.el.addClass([this.fieldClass,this.cls])},getItemCt:function(){return this.itemCt},initValue:function(){if(this.value!==undefined){this.setValue(this.value)}else{if(!Ext.isEmpty(this.el.dom.value)&&this.el.dom.value!=this.emptyText){this.setValue(this.el.dom.value)}}this.originalValue=this.getValue()},isDirty:function(){if(this.disabled||!this.rendered){return false}return String(this.getValue())!==String(this.originalValue)},setReadOnly:function(a){if(this.rendered){this.el.dom.readOnly=a}this.readOnly=a},afterRender:function(){Ext.form.Field.superclass.afterRender.call(this);this.initEvents();this.initValue()},fireKey:function(a){if(a.isSpecialKey()){this.fireEvent("specialkey",this,a)}},reset:function(){this.setValue(this.originalValue);this.clearInvalid()},initEvents:function(){this.mon(this.el,Ext.EventManager.useKeydown?"keydown":"keypress",this.fireKey,this);this.mon(this.el,"focus",this.onFocus,this);this.mon(this.el,"blur",this.onBlur,this,this.inEditor?{buffer:10}:null)},preFocus:Ext.emptyFn,onFocus:function(){this.preFocus();if(this.focusClass){this.el.addClass(this.focusClass)}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this)}},beforeBlur:Ext.emptyFn,onBlur:function(){this.beforeBlur();if(this.focusClass){this.el.removeClass(this.focusClass)}this.hasFocus=false;if(this.validationEvent!==false&&(this.validateOnBlur||this.validationEvent=="blur")){this.validate()}var a=this.getValue();if(String(a)!==String(this.startValue)){this.fireEvent("change",this,a,this.startValue)}this.fireEvent("blur",this);this.postBlur()},postBlur:Ext.emptyFn,isValid:function(a){if(this.disabled){return true}var c=this.preventMark;this.preventMark=a===true;var b=this.validateValue(this.processValue(this.getRawValue()));this.preventMark=c;return b},validate:function(){if(this.disabled||this.validateValue(this.processValue(this.getRawValue()))){this.clearInvalid();return true}return false},processValue:function(a){return a},validateValue:function(b){var a=this.getErrors(b)[0];if(a==undefined){return true}else{this.markInvalid(a);return false}},getErrors:function(){return[]},getActiveError:function(){return this.activeError||""},markInvalid:function(c){if(this.rendered&&!this.preventMark){c=c||this.invalidText;var a=this.getMessageHandler();if(a){a.mark(this,c)}else{if(this.msgTarget){this.el.addClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML=c;b.style.display=this.msgDisplay}}}}this.setActiveError(c)},clearInvalid:function(){if(this.rendered&&!this.preventMark){this.el.removeClass(this.invalidClass);var a=this.getMessageHandler();if(a){a.clear(this)}else{if(this.msgTarget){this.el.removeClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML="";b.style.display="none"}}}}this.unsetActiveError()},setActiveError:function(b,a){this.activeError=b;if(a!==true){this.fireEvent("invalid",this,b)}},unsetActiveError:function(a){delete this.activeError;if(a!==true){this.fireEvent("valid",this)}},getMessageHandler:function(){return Ext.form.MessageTargets[this.msgTarget]},getErrorCt:function(){return this.el.findParent(".x-form-element",5,true)||this.el.findParent(".x-form-field-wrap",5,true)},alignErrorEl:function(){this.errorEl.setWidth(this.getErrorCt().getWidth(true)-20)},alignErrorIcon:function(){this.errorIcon.alignTo(this.el,"tl-tr",[2,0])},getRawValue:function(){var a=this.rendered?this.el.getValue():Ext.value(this.value,"");if(a===this.emptyText){a=""}return a},getValue:function(){if(!this.rendered){return this.value}var a=this.el.getValue();if(a===this.emptyText||a===undefined){a=""}return a},setRawValue:function(a){return this.rendered?(this.el.dom.value=(Ext.isEmpty(a)?"":a)):""},setValue:function(a){this.value=a;if(this.rendered){this.el.dom.value=(Ext.isEmpty(a)?"":a);this.validate()}return this},append:function(a){this.setValue([this.getValue(),a].join(""))}});Ext.form.MessageTargets={qtip:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.qtip=b;a.el.dom.qclass="x-form-invalid-tip";if(Ext.QuickTips){Ext.QuickTips.enable()}},clear:function(a){a.el.removeClass(a.invalidClass);a.el.dom.qtip=""}},title:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.title=b},clear:function(a){a.el.dom.title=""}},under:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorEl){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorEl=a.createChild({cls:"x-form-invalid-msg"});b.on("resize",b.alignErrorEl,b);b.on("destroy",function(){Ext.destroy(this.errorEl)},b)}b.alignErrorEl();b.errorEl.update(c);Ext.form.Field.msgFx[b.msgFx].show(b.errorEl,b)},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorEl){Ext.form.Field.msgFx[a.msgFx].hide(a.errorEl,a)}else{a.el.dom.title=""}}},side:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorIcon){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorIcon=a.createChild({cls:"x-form-invalid-icon"});if(b.ownerCt){b.ownerCt.on("afterlayout",b.alignErrorIcon,b);b.ownerCt.on("expand",b.alignErrorIcon,b)}b.on("resize",b.alignErrorIcon,b);b.on("destroy",function(){Ext.destroy(this.errorIcon)},b)}b.alignErrorIcon();b.errorIcon.dom.qtip=c;b.errorIcon.dom.qclass="x-form-invalid-tip";b.errorIcon.show()},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorIcon){a.errorIcon.dom.qtip="";a.errorIcon.hide()}else{a.el.dom.title=""}}}};Ext.form.Field.msgFx={normal:{show:function(a,b){a.setDisplayed("block")},hide:function(a,b){a.setDisplayed(false).update("")}},slide:{show:function(a,b){a.slideIn("t",{stopFx:true})},hide:function(a,b){a.slideOut("t",{stopFx:true,useDisplay:true})}},slideRight:{show:function(a,b){a.fixDisplay();a.alignTo(b.el,"tl-tr");a.slideIn("l",{stopFx:true})},hide:function(a,b){a.slideOut("l",{stopFx:true,useDisplay:true})}}};Ext.reg("field",Ext.form.Field);Ext.form.TextField=Ext.extend(Ext.form.Field,{grow:false,growMin:30,growMax:800,vtype:null,maskRe:null,disableKeyFilter:false,allowBlank:true,minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",selectOnFocus:false,blankText:"This field is required",validator:null,regex:null,regexText:"",emptyText:null,emptyClass:"x-form-empty-field",initComponent:function(){Ext.form.TextField.superclass.initComponent.call(this);this.addEvents("autosize","keydown","keyup","keypress")},initEvents:function(){Ext.form.TextField.superclass.initEvents.call(this);if(this.validationEvent=="keyup"){this.validationTask=new Ext.util.DelayedTask(this.validate,this);this.mon(this.el,"keyup",this.filterValidation,this)}else{if(this.validationEvent!==false&&this.validationEvent!="blur"){this.mon(this.el,this.validationEvent,this.validate,this,{buffer:this.validationDelay})}}if(this.selectOnFocus||this.emptyText){this.mon(this.el,"mousedown",this.onMouseDown,this);if(this.emptyText){this.applyEmptyText()}}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Ext.form.VTypes[this.vtype+"Mask"]))){this.mon(this.el,"keypress",this.filterKeys,this)}if(this.grow){this.mon(this.el,"keyup",this.onKeyUpBuffered,this,{buffer:50});this.mon(this.el,"click",this.autoSize,this)}if(this.enableKeyEvents){this.mon(this.el,{scope:this,keyup:this.onKeyUp,keydown:this.onKeyDown,keypress:this.onKeyPress})}},onMouseDown:function(a){if(!this.hasFocus){this.mon(this.el,"mouseup",Ext.emptyFn,this,{single:true,preventDefault:true})}},processValue:function(a){if(this.stripCharsRe){var b=a.replace(this.stripCharsRe,"");if(b!==a){this.setRawValue(b);return b}}return a},filterValidation:function(a){if(!a.isNavKeyPress()){this.validationTask.delay(this.validationDelay)}},onDisable:function(){Ext.form.TextField.superclass.onDisable.call(this);if(Ext.isIE){this.el.dom.unselectable="on"}},onEnable:function(){Ext.form.TextField.superclass.onEnable.call(this);if(Ext.isIE){this.el.dom.unselectable=""}},onKeyUpBuffered:function(a){if(this.doAutoSize(a)){this.autoSize()}},doAutoSize:function(a){return !a.isNavKeyPress()},onKeyUp:function(a){this.fireEvent("keyup",this,a)},onKeyDown:function(a){this.fireEvent("keydown",this,a)},onKeyPress:function(a){this.fireEvent("keypress",this,a)},reset:function(){Ext.form.TextField.superclass.reset.call(this);this.applyEmptyText()},applyEmptyText:function(){if(this.rendered&&this.emptyText&&this.getRawValue().length<1&&!this.hasFocus){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass)}},preFocus:function(){var a=this.el;if(this.emptyText){if(a.dom.value==this.emptyText){this.setRawValue("")}a.removeClass(this.emptyClass)}if(this.selectOnFocus){a.dom.select()}},postBlur:function(){this.applyEmptyText()},filterKeys:function(b){if(b.ctrlKey){return}var a=b.getKey();if(Ext.isGecko&&(b.isNavKeyPress()||a==b.BACKSPACE||(a==b.DELETE&&b.button==-1))){return}var c=String.fromCharCode(b.getCharCode());if(!Ext.isGecko&&b.isSpecialKey()&&!c){return}if(!this.maskRe.test(c)){b.stopEvent()}},setValue:function(a){if(this.emptyText&&this.el&&!Ext.isEmpty(a)){this.el.removeClass(this.emptyClass)}Ext.form.TextField.superclass.setValue.apply(this,arguments);this.applyEmptyText();this.autoSize();return this},getErrors:function(a){var d=Ext.form.TextField.superclass.getErrors.apply(this,arguments);a=a||this.processValue(this.getRawValue());if(Ext.isFunction(this.validator)){var c=this.validator(a);if(c!==true){d.push(c)}}if(a.length<1||a===this.emptyText){if(this.allowBlank){return d}else{d.push(this.blankText)}}if(!this.allowBlank&&(a.length<1||a===this.emptyText)){d.push(this.blankText)}if(a.lengththis.maxLength){d.push(String.format(this.maxLengthText,this.maxLength))}if(this.vtype){var b=Ext.form.VTypes;if(!b[this.vtype](a,this)){d.push(this.vtypeText||b[this.vtype+"Text"])}}if(this.regex&&!this.regex.test(a)){d.push(this.regexText)}return d},selectText:function(h,a){var c=this.getRawValue();var e=false;if(c.length>0){h=h===undefined?0:h;a=a===undefined?c.length:a;var g=this.el.dom;if(g.setSelectionRange){g.setSelectionRange(h,a)}else{if(g.createTextRange){var b=g.createTextRange();b.moveStart("character",h);b.moveEnd("character",a-c.length);b.select()}}e=Ext.isGecko||Ext.isOpera}else{e=true}if(e){this.focus()}},autoSize:function(){if(!this.grow||!this.rendered){return}if(!this.metrics){this.metrics=Ext.util.TextMetrics.createInstance(this.el)}var c=this.el;var b=c.dom.value;var e=document.createElement("div");e.appendChild(document.createTextNode(b));b=e.innerHTML;Ext.removeNode(e);e=null;b+=" ";var a=Math.min(this.growMax,Math.max(this.metrics.getWidth(b)+10,this.growMin));this.el.setWidth(a);this.fireEvent("autosize",this,a)},onDestroy:function(){if(this.validationTask){this.validationTask.cancel();this.validationTask=null}Ext.form.TextField.superclass.onDestroy.call(this)}});Ext.reg("textfield",Ext.form.TextField);Ext.form.TriggerField=Ext.extend(Ext.form.TextField,{defaultAutoCreate:{tag:"input",type:"text",size:"16",autocomplete:"off"},hideTrigger:false,editable:true,readOnly:false,wrapFocusClass:"x-trigger-wrap-focus",autoSize:Ext.emptyFn,monitorTab:true,deferHeight:true,mimicing:false,actionMode:"wrap",defaultTriggerWidth:17,onResize:function(a,c){Ext.form.TriggerField.superclass.onResize.call(this,a,c);var b=this.getTriggerWidth();if(Ext.isNumber(a)){this.el.setWidth(a-b)}this.wrap.setWidth(this.el.getWidth()+b)},getTriggerWidth:function(){var a=this.trigger.getWidth();if(!this.hideTrigger&&!this.readOnly&&a===0){a=this.defaultTriggerWidth}return a},alignErrorIcon:function(){if(this.wrap){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}},onRender:function(b,a){this.doc=Ext.isIE?Ext.getBody():Ext.getDoc();Ext.form.TriggerField.superclass.onRender.call(this,b,a);this.wrap=this.el.wrap({cls:"x-form-field-wrap x-form-field-trigger-wrap"});this.trigger=this.wrap.createChild(this.triggerConfig||{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});this.initTrigger();if(!this.width){this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())}this.resizeEl=this.positionEl=this.wrap},getWidth:function(){return(this.el.getWidth()+this.trigger.getWidth())},updateEditState:function(){if(this.rendered){if(this.readOnly){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this);this.trigger.setDisplayed(false)}else{if(!this.editable){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mon(this.el,"click",this.onTriggerClick,this)}else{this.el.dom.readOnly=false;this.el.removeClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this)}this.trigger.setDisplayed(!this.hideTrigger)}this.onResize(this.width||this.wrap.getWidth())}},setHideTrigger:function(a){if(a!=this.hideTrigger){this.hideTrigger=a;this.updateEditState()}},setEditable:function(a){if(a!=this.editable){this.editable=a;this.updateEditState()}},setReadOnly:function(a){if(a!=this.readOnly){this.readOnly=a;this.updateEditState()}},afterRender:function(){Ext.form.TriggerField.superclass.afterRender.call(this);this.updateEditState()},initTrigger:function(){this.mon(this.trigger,"click",this.onTriggerClick,this,{preventDefault:true});this.trigger.addClassOnOver("x-form-trigger-over");this.trigger.addClassOnClick("x-form-trigger-click")},onDestroy:function(){Ext.destroy(this.trigger,this.wrap);if(this.mimicing){this.doc.un("mousedown",this.mimicBlur,this)}delete this.doc;Ext.form.TriggerField.superclass.onDestroy.call(this)},onFocus:function(){Ext.form.TriggerField.superclass.onFocus.call(this);if(!this.mimicing){this.wrap.addClass(this.wrapFocusClass);this.mimicing=true;this.doc.on("mousedown",this.mimicBlur,this,{delay:10});if(this.monitorTab){this.on("specialkey",this.checkTab,this)}}},checkTab:function(a,b){if(b.getKey()==b.TAB){this.triggerBlur()}},onBlur:Ext.emptyFn,mimicBlur:function(a){if(!this.isDestroyed&&!this.wrap.contains(a.target)&&this.validateBlur(a)){this.triggerBlur()}},triggerBlur:function(){this.mimicing=false;this.doc.un("mousedown",this.mimicBlur,this);if(this.monitorTab&&this.el){this.un("specialkey",this.checkTab,this)}Ext.form.TriggerField.superclass.onBlur.call(this);if(this.wrap){this.wrap.removeClass(this.wrapFocusClass)}},beforeBlur:Ext.emptyFn,validateBlur:function(a){return true},onTriggerClick:Ext.emptyFn});Ext.form.TwinTriggerField=Ext.extend(Ext.form.TriggerField,{initComponent:function(){Ext.form.TwinTriggerField.superclass.initComponent.call(this);this.triggerConfig={tag:"span",cls:"x-form-twin-triggers",cn:[{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.trigger1Class},{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.trigger2Class}]}},getTrigger:function(a){return this.triggers[a]},initTrigger:function(){var a=this.trigger.select(".x-form-trigger",true);var b=this;a.each(function(d,g,c){var e="Trigger"+(c+1);d.hide=function(){var h=b.wrap.getWidth();this.dom.style.display="none";b.el.setWidth(h-b.trigger.getWidth());this["hidden"+e]=true};d.show=function(){var h=b.wrap.getWidth();this.dom.style.display="";b.el.setWidth(h-b.trigger.getWidth());this["hidden"+e]=false};if(this["hide"+e]){d.dom.style.display="none";this["hidden"+e]=true}this.mon(d,"click",this["on"+e+"Click"],this,{preventDefault:true});d.addClassOnOver("x-form-trigger-over");d.addClassOnClick("x-form-trigger-click")},this);this.triggers=a.elements},getTriggerWidth:function(){var a=0;Ext.each(this.triggers,function(d,c){var e="Trigger"+(c+1),b=d.getWidth();if(b===0&&!this["hidden"+e]){a+=this.defaultTriggerWidth}else{a+=b}},this);return a},onDestroy:function(){Ext.destroy(this.triggers);Ext.form.TwinTriggerField.superclass.onDestroy.call(this)},onTrigger1Click:Ext.emptyFn,onTrigger2Click:Ext.emptyFn});Ext.reg("trigger",Ext.form.TriggerField);Ext.form.TextArea=Ext.extend(Ext.form.TextField,{growMin:60,growMax:1000,growAppend:" \n ",enterIsSpecial:false,preventScrollbars:false,onRender:function(b,a){if(!this.el){this.defaultAutoCreate={tag:"textarea",style:"width:100px;height:60px;",autocomplete:"off"}}Ext.form.TextArea.superclass.onRender.call(this,b,a);if(this.grow){this.textSizeEl=Ext.DomHelper.append(document.body,{tag:"pre",cls:"x-form-grow-sizer"});if(this.preventScrollbars){this.el.setStyle("overflow","hidden")}this.el.setHeight(this.growMin)}},onDestroy:function(){Ext.removeNode(this.textSizeEl);Ext.form.TextArea.superclass.onDestroy.call(this)},fireKey:function(a){if(a.isSpecialKey()&&(this.enterIsSpecial||(a.getKey()!=a.ENTER||a.hasModifier()))){this.fireEvent("specialkey",this,a)}},doAutoSize:function(a){return !a.isNavKeyPress()||a.getKey()==a.ENTER},autoSize:function(){if(!this.grow||!this.textSizeEl){return}var c=this.el,a=Ext.util.Format.htmlEncode(c.dom.value),d=this.textSizeEl,b;Ext.fly(d).setWidth(this.el.getWidth());if(a.length<1){a="  "}else{a+=this.growAppend;if(Ext.isIE){a=a.replace(/\n/g," 
")}}d.innerHTML=a;b=Math.min(this.growMax,Math.max(d.offsetHeight,this.growMin));if(b!=this.lastHeight){this.lastHeight=b;this.el.setHeight(b);this.fireEvent("autosize",this,b)}}});Ext.reg("textarea",Ext.form.TextArea);Ext.form.NumberField=Ext.extend(Ext.form.TextField,{fieldClass:"x-form-field x-form-num-field",allowDecimals:true,decimalSeparator:".",decimalPrecision:2,allowNegative:true,minValue:Number.NEGATIVE_INFINITY,maxValue:Number.MAX_VALUE,minText:"The minimum value for this field is {0}",maxText:"The maximum value for this field is {0}",nanText:"{0} is not a valid number",baseChars:"0123456789",initEvents:function(){var a=this.baseChars+"";if(this.allowDecimals){a+=this.decimalSeparator}if(this.allowNegative){a+="-"}this.maskRe=new RegExp("["+Ext.escapeRe(a)+"]");Ext.form.NumberField.superclass.initEvents.call(this)},getErrors:function(b){var c=Ext.form.NumberField.superclass.getErrors.apply(this,arguments);b=b||this.processValue(this.getRawValue());if(b.length<1){return c}b=String(b).replace(this.decimalSeparator,".");if(isNaN(b)){c.push(String.format(this.nanText,b))}var a=this.parseValue(b);if(athis.maxValue){c.push(String.format(this.maxText,this.maxValue))}return c},getValue:function(){return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)))},setValue:function(a){a=Ext.isNumber(a)?a:parseFloat(String(a).replace(this.decimalSeparator,"."));a=isNaN(a)?"":String(a).replace(".",this.decimalSeparator);return Ext.form.NumberField.superclass.setValue.call(this,a)},setMinValue:function(a){this.minValue=Ext.num(a,Number.NEGATIVE_INFINITY)},setMaxValue:function(a){this.maxValue=Ext.num(a,Number.MAX_VALUE)},parseValue:function(a){a=parseFloat(String(a).replace(this.decimalSeparator,"."));return isNaN(a)?"":a},fixPrecision:function(b){var a=isNaN(b);if(!this.allowDecimals||this.decimalPrecision==-1||a||!b){return a?"":b}return parseFloat(parseFloat(b).toFixed(this.decimalPrecision))},beforeBlur:function(){var a=this.parseValue(this.getRawValue());if(!Ext.isEmpty(a)){this.setValue(this.fixPrecision(a))}}});Ext.reg("numberfield",Ext.form.NumberField);Ext.form.DateField=Ext.extend(Ext.form.TriggerField,{format:"m/d/Y",altFormats:"m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",disabledDaysText:"Disabled",disabledDatesText:"Disabled",minText:"The date in this field must be equal to or after {0}",maxText:"The date in this field must be equal to or before {0}",invalidText:"{0} is not a valid date - it must be in the format {1}",triggerClass:"x-form-date-trigger",showToday:true,defaultAutoCreate:{tag:"input",type:"text",size:"10",autocomplete:"off"},initTime:"12",initTimeFormat:"H",safeParse:function(b,c){if(/[gGhH]/.test(c.replace(/(\\.)/g,""))){return Date.parseDate(b,c)}else{var a=Date.parseDate(b+" "+this.initTime,c+" "+this.initTimeFormat);if(a){return a.clearTime()}}},initComponent:function(){Ext.form.DateField.superclass.initComponent.call(this);this.addEvents("select");if(Ext.isString(this.minValue)){this.minValue=this.parseDate(this.minValue)}if(Ext.isString(this.maxValue)){this.maxValue=this.parseDate(this.maxValue)}this.disabledDatesRE=null;this.initDisabledDays()},initEvents:function(){Ext.form.DateField.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{down:function(a){this.onTriggerClick()},scope:this,forceKeyDown:true})},initDisabledDays:function(){if(this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){this.disabledDates=a;this.initDisabledDays();if(this.menu){this.menu.picker.setDisabledDates(this.disabledDatesRE)}},setDisabledDays:function(a){this.disabledDays=a;if(this.menu){this.menu.picker.setDisabledDays(a)}},setMinValue:function(a){this.minValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMinDate(this.minValue)}},setMaxValue:function(a){this.maxValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMaxDate(this.maxValue)}},getErrors:function(e){var h=Ext.form.DateField.superclass.getErrors.apply(this,arguments);e=this.formatDate(e||this.processValue(this.getRawValue()));if(e.length<1){return h}var c=e;e=this.parseDate(e);if(!e){h.push(String.format(this.invalidText,c,this.format));return h}var g=e.getTime();if(this.minValue&&gthis.maxValue.getTime()){h.push(String.format(this.maxText,this.formatDate(this.maxValue)))}if(this.disabledDays){var a=e.getDay();for(var b=0;b
{'+this.displayField+"}
"}this.view=new Ext.DataView({applyTo:this.innerList,tpl:this.tpl,singleSelect:true,selectedClass:this.selectedClass,itemSelector:this.itemSelector||"."+a+"-item",emptyText:this.listEmptyText,deferEmptyText:false});this.mon(this.view,{containerclick:this.onViewClick,click:this.onViewClick,scope:this});this.bindStore(this.store,true);if(this.resizable){this.resizer=new Ext.Resizable(this.list,{pinned:true,handles:"se"});this.mon(this.resizer,"resize",function(i,e,g){this.maxHeight=g-this.handleHeight-this.list.getFrameWidth("tb")-this.assetHeight;this.listWidth=e;this.innerList.setWidth(e-this.list.getFrameWidth("lr"));this.restrictHeight()},this);this[this.pageSize?"footer":"innerList"].setStyle("margin-bottom",this.handleHeight+"px")}}},getListParent:function(){return document.body},getStore:function(){return this.store},bindStore:function(a,b){if(this.store&&!b){if(this.store!==a&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.collapse,this)}if(!a){this.store=null;if(this.view){this.view.bindStore(null)}if(this.pageTb){this.pageTb.bindStore(null)}}}if(a){if(!b){this.lastQuery=null;if(this.pageTb){this.pageTb.bindStore(a)}}this.store=Ext.StoreMgr.lookup(a);this.store.on({scope:this,beforeload:this.onBeforeLoad,load:this.onLoad,exception:this.collapse});if(this.view){this.view.bindStore(a)}}},reset:function(){Ext.form.ComboBox.superclass.reset.call(this);if(this.clearFilterOnReset&&this.mode=="local"){this.store.clearFilter()}},initEvents:function(){Ext.form.ComboBox.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{up:function(a){this.inKeyMode=true;this.selectPrev()},down:function(a){if(!this.isExpanded()){this.onTriggerClick()}else{this.inKeyMode=true;this.selectNext()}},enter:function(a){this.onViewClick()},esc:function(a){this.collapse()},tab:function(a){if(this.forceSelection===true){this.collapse()}else{this.onViewClick(false)}return true},scope:this,doRelay:function(c,b,a){if(a=="down"||this.scope.isExpanded()){var d=Ext.KeyNav.prototype.doRelay.apply(this,arguments);if(!Ext.isIE&&Ext.EventManager.useKeydown){this.scope.fireKey(c)}return d}return true},forceKeyDown:true,defaultEventAction:"stopEvent"});this.queryDelay=Math.max(this.queryDelay||10,this.mode=="local"?10:250);this.dqTask=new Ext.util.DelayedTask(this.initQuery,this);if(this.typeAhead){this.taTask=new Ext.util.DelayedTask(this.onTypeAhead,this)}if(!this.enableKeyEvents){this.mon(this.el,"keyup",this.onKeyUp,this)}},onDestroy:function(){if(this.dqTask){this.dqTask.cancel();this.dqTask=null}this.bindStore(null);Ext.destroy(this.resizer,this.view,this.pageTb,this.list);Ext.destroyMembers(this,"hiddenField");Ext.form.ComboBox.superclass.onDestroy.call(this)},fireKey:function(a){if(!this.isExpanded()){Ext.form.ComboBox.superclass.fireKey.call(this,a)}},onResize:function(a,b){Ext.form.ComboBox.superclass.onResize.apply(this,arguments);if(!isNaN(a)&&this.isVisible()&&this.list){this.doResize(a)}else{this.bufferSize=a}},doResize:function(a){if(!Ext.isDefined(this.listWidth)){var b=Math.max(a,this.minListWidth);this.list.setWidth(b);this.innerList.setWidth(b-this.list.getFrameWidth("lr"))}},onEnable:function(){Ext.form.ComboBox.superclass.onEnable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=false}},onDisable:function(){Ext.form.ComboBox.superclass.onDisable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=true}},onBeforeLoad:function(){if(!this.hasFocus){return}this.innerList.update(this.loadingText?'
'+this.loadingText+"
":"");this.restrictHeight();this.selectedIndex=-1},onLoad:function(){if(!this.hasFocus){return}if(this.store.getCount()>0||this.listEmptyText){this.expand();this.restrictHeight();if(this.lastQuery==this.allQuery){if(this.editable){this.el.dom.select()}if(this.autoSelect!==false&&!this.selectByValue(this.value,true)){this.select(0,true)}}else{if(this.autoSelect!==false){this.selectNext()}if(this.typeAhead&&this.lastKey!=Ext.EventObject.BACKSPACE&&this.lastKey!=Ext.EventObject.DELETE){this.taTask.delay(this.typeAheadDelay)}}}else{this.collapse()}},onTypeAhead:function(){if(this.store.getCount()>0){var b=this.store.getAt(0);var c=b.data[this.displayField];var a=c.length;var d=this.getRawValue().length;if(d!=a){this.setRawValue(c);this.selectText(d,c.length)}}},assertValue:function(){var b=this.getRawValue(),a=this.findRecord(this.displayField,b);if(!a&&this.forceSelection){if(b.length>0&&b!=this.emptyText){this.el.dom.value=Ext.value(this.lastSelectionText,"");this.applyEmptyText()}else{this.clearValue()}}else{if(a){if(b==a.get(this.displayField)&&this.value==a.get(this.valueField)){return}b=a.get(this.valueField||this.displayField)}this.setValue(b)}},onSelect:function(a,b){if(this.fireEvent("beforeselect",this,a,b)!==false){this.setValue(a.data[this.valueField||this.displayField]);this.collapse();this.fireEvent("select",this,a,b)}},getName:function(){var a=this.hiddenField;return a&&a.name?a.name:this.hiddenName||Ext.form.ComboBox.superclass.getName.call(this)},getValue:function(){if(this.valueField){return Ext.isDefined(this.value)?this.value:""}else{return Ext.form.ComboBox.superclass.getValue.call(this)}},clearValue:function(){if(this.hiddenField){this.hiddenField.value=""}this.setRawValue("");this.lastSelectionText="";this.applyEmptyText();this.value=""},setValue:function(a){var c=a;if(this.valueField){var b=this.findRecord(this.valueField,a);if(b){c=b.data[this.displayField]}else{if(Ext.isDefined(this.valueNotFoundText)){c=this.valueNotFoundText}}}this.lastSelectionText=c;if(this.hiddenField){this.hiddenField.value=Ext.value(a,"")}Ext.form.ComboBox.superclass.setValue.call(this,c);this.value=a;return this},findRecord:function(c,b){var a;if(this.store.getCount()>0){this.store.each(function(d){if(d.data[c]==b){a=d;return false}})}return a},onViewMove:function(b,a){this.inKeyMode=false},onViewOver:function(d,b){if(this.inKeyMode){return}var c=this.view.findItemFromChild(b);if(c){var a=this.view.indexOf(c);this.select(a,false)}},onViewClick:function(b){var a=this.view.getSelectedIndexes()[0],c=this.store,d=c.getAt(a);if(d){this.onSelect(d,a)}else{this.collapse()}if(b!==false){this.el.focus()}},restrictHeight:function(){this.innerList.dom.style.height="";var b=this.innerList.dom,e=this.list.getFrameWidth("tb")+(this.resizable?this.handleHeight:0)+this.assetHeight,c=Math.max(b.clientHeight,b.offsetHeight,b.scrollHeight),a=this.getPosition()[1]-Ext.getBody().getScroll().top,g=Ext.lib.Dom.getViewHeight()-a-this.getSize().height,d=Math.max(a,g,this.minHeight||0)-this.list.shadowOffset-e-5;c=Math.min(c,d,this.maxHeight);this.innerList.setHeight(c);this.list.beginUpdate();this.list.setHeight(c+e);this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));this.list.endUpdate()},isExpanded:function(){return this.list&&this.list.isVisible()},selectByValue:function(a,c){if(!Ext.isEmpty(a,true)){var b=this.findRecord(this.valueField||this.displayField,a);if(b){this.select(this.store.indexOf(b),c);return true}}return false},select:function(a,c){this.selectedIndex=a;this.view.select(a);if(c!==false){var b=this.view.getNode(a);if(b){this.innerList.scrollChildIntoView(b,false)}}},selectNext:function(){var a=this.store.getCount();if(a>0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex!==0){this.select(this.selectedIndex-1)}}}},onKeyUp:function(b){var a=b.getKey();if(this.editable!==false&&this.readOnly!==true&&(a==b.BACKSPACE||!b.isSpecialKey())){this.lastKey=a;this.dqTask.delay(this.queryDelay)}Ext.form.ComboBox.superclass.onKeyUp.call(this,b)},validateBlur:function(){return !this.list||!this.list.isVisible()},initQuery:function(){this.doQuery(this.getRawValue())},beforeBlur:function(){this.assertValue()},postBlur:function(){Ext.form.ComboBox.superclass.postBlur.call(this);this.collapse();this.inKeyMode=false},doQuery:function(c,b){c=Ext.isEmpty(c)?"":c;var a={query:c,forceAll:b,combo:this,cancel:false};if(this.fireEvent("beforequery",a)===false||a.cancel){return false}c=a.query;b=a.forceAll;if(b===true||(c.length>=this.minChars)){if(this.lastQuery!==c){this.lastQuery=c;if(this.mode=="local"){this.selectedIndex=-1;if(b){this.store.clearFilter()}else{this.store.filter(this.displayField,c)}this.onLoad()}else{this.store.baseParams[this.queryParam]=c;this.store.load({params:this.getParams(c)});this.expand()}}else{this.selectedIndex=-1;this.onLoad()}}},getParams:function(a){var b={};if(this.pageSize){b.start=0;b.limit=this.pageSize}return b},collapse:function(){if(!this.isExpanded()){return}this.list.hide();Ext.getDoc().un("mousewheel",this.collapseIf,this);Ext.getDoc().un("mousedown",this.collapseIf,this);this.fireEvent("collapse",this)},collapseIf:function(a){if(!this.isDestroyed&&!a.within(this.wrap)&&!a.within(this.list)){this.collapse()}},expand:function(){if(this.isExpanded()||!this.hasFocus){return}if(this.title||this.pageSize){this.assetHeight=0;if(this.title){this.assetHeight+=this.header.getHeight()}if(this.pageSize){this.assetHeight+=this.footer.getHeight()}}if(this.bufferSize){this.doResize(this.bufferSize);delete this.bufferSize}this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));var b=Ext.getDom(this.getListParent()||Ext.getBody()),a=parseInt(Ext.fly(b).getStyle("z-index"),10);if(!a){a=this.getParentZIndex()}if(a){this.list.setZIndex(a+5)}this.list.show();if(Ext.isGecko2){this.innerList.setOverflow("auto")}this.mon(Ext.getDoc(),{scope:this,mousewheel:this.collapseIf,mousedown:this.collapseIf});this.fireEvent("expand",this)},onTriggerClick:function(){if(this.readOnly||this.disabled){return}if(this.isExpanded()){this.collapse();this.el.focus()}else{this.onFocus({});if(this.triggerAction=="all"){this.doQuery(this.allQuery,true)}else{this.doQuery(this.getRawValue())}this.el.focus()}}});Ext.reg("combo",Ext.form.ComboBox);Ext.form.Checkbox=Ext.extend(Ext.form.Field,{focusClass:undefined,fieldClass:"x-form-field",checked:false,boxLabel:" ",defaultAutoCreate:{tag:"input",type:"checkbox",autocomplete:"off"},actionMode:"wrap",initComponent:function(){Ext.form.Checkbox.superclass.initComponent.call(this);this.addEvents("check")},onResize:function(){Ext.form.Checkbox.superclass.onResize.apply(this,arguments);if(!this.boxLabel&&!this.fieldLabel){this.el.alignTo(this.wrap,"c-c")}},initEvents:function(){Ext.form.Checkbox.superclass.initEvents.call(this);this.mon(this.el,{scope:this,click:this.onClick,change:this.onClick})},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,onRender:function(b,a){Ext.form.Checkbox.superclass.onRender.call(this,b,a);if(this.inputValue!==undefined){this.el.dom.value=this.inputValue}this.wrap=this.el.wrap({cls:"x-form-check-wrap"});if(this.boxLabel){this.wrap.createChild({tag:"label",htmlFor:this.el.id,cls:"x-form-cb-label",html:this.boxLabel})}if(this.checked){this.setValue(true)}else{this.checked=this.el.dom.checked}if(Ext.isIE){this.wrap.repaint()}this.resizeEl=this.positionEl=this.wrap},onDestroy:function(){Ext.destroy(this.wrap);Ext.form.Checkbox.superclass.onDestroy.call(this)},initValue:function(){this.originalValue=this.getValue()},getValue:function(){if(this.rendered){return this.el.dom.checked}return this.checked},onClick:function(){if(this.el.dom.checked!=this.checked){this.setValue(this.el.dom.checked)}},setValue:function(a){var b=this.checked;this.checked=(a===true||a==="true"||a=="1"||String(a).toLowerCase()=="on");if(this.rendered){this.el.dom.checked=this.checked;this.el.dom.defaultChecked=this.checked}if(b!=this.checked){this.fireEvent("check",this,this.checked);if(this.handler){this.handler.call(this.scope||this,this,this.checked)}}return this}});Ext.reg("checkbox",Ext.form.Checkbox);Ext.form.CheckboxGroup=Ext.extend(Ext.form.Field,{columns:"auto",vertical:false,allowBlank:true,blankText:"You must select at least one item in this group",defaultType:"checkbox",groupCls:"x-form-check-group",initComponent:function(){this.addEvents("change");this.on("change",this.validate,this);Ext.form.CheckboxGroup.superclass.initComponent.call(this)},onRender:function(j,g){if(!this.el){var p={autoEl:{id:this.id},cls:this.groupCls,layout:"column",renderTo:j,bufferResize:false};var a={xtype:"container",defaultType:this.defaultType,layout:"form",defaults:{hideLabel:true,anchor:"100%"}};if(this.items[0].items){Ext.apply(p,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,m=this.items.length;e0&&e%r==0){o++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}n[o].items.push(this.items[e])}}else{for(var e=0,m=this.items.length;e-1){b.setValue(true)}})},getBox:function(b){var a=null;this.eachItem(function(c){if(b==c||c.dataIndex==b||c.id==b||c.getName()==b){a=c;return false}});return a},getValue:function(){var a=[];this.eachItem(function(b){if(b.checked){a.push(b)}});return a},eachItem:function(b,a){if(this.items&&this.items.each){this.items.each(b,a||this)}},getRawValue:Ext.emptyFn,setRawValue:Ext.emptyFn});Ext.reg("checkboxgroup",Ext.form.CheckboxGroup);Ext.form.CompositeField=Ext.extend(Ext.form.Field,{defaultMargins:"0 5 0 0",skipLastItemMargin:true,isComposite:true,combineErrors:true,initComponent:function(){var e=[],a=this.items,d;for(var c=0,b=a.length;c")},sortErrors:function(){var a=this.items;this.fieldErrors.sort("ASC",function(g,d){var c=function(b){return function(i){return i.getName()==b}};var h=a.findIndexBy(c(g.field)),e=a.findIndexBy(c(d.field));return h1){var a=this.getBox(c);if(a){a.setValue(b);if(a.checked){this.eachItem(function(d){if(d!==a){d.setValue(false)}})}}}else{this.setValueForItem(c)}},setValueForItem:function(a){a=String(a).split(",")[0];this.eachItem(function(b){b.setValue(a==b.inputValue)})},fireChecked:function(){if(!this.checkTask){this.checkTask=new Ext.util.DelayedTask(this.bufferChecked,this)}this.checkTask.delay(10)},bufferChecked:function(){var a=null;this.eachItem(function(b){if(b.checked){a=b;return false}});this.fireEvent("change",this,a)},onDestroy:function(){if(this.checkTask){this.checkTask.cancel();this.checkTask=null}Ext.form.RadioGroup.superclass.onDestroy.call(this)}});Ext.reg("radiogroup",Ext.form.RadioGroup);Ext.form.Hidden=Ext.extend(Ext.form.Field,{inputType:"hidden",onRender:function(){Ext.form.Hidden.superclass.onRender.apply(this,arguments)},initEvents:function(){this.originalValue=this.getValue()},setSize:Ext.emptyFn,setWidth:Ext.emptyFn,setHeight:Ext.emptyFn,setPosition:Ext.emptyFn,setPagePosition:Ext.emptyFn,markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn});Ext.reg("hidden",Ext.form.Hidden);Ext.form.BasicForm=Ext.extend(Ext.util.Observable,{constructor:function(b,a){Ext.apply(this,a);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}this.items=new Ext.util.MixedCollection(false,function(c){return c.getItemId()});this.addEvents("beforeaction","actionfailed","actioncomplete");if(b){this.initEl(b)}Ext.form.BasicForm.superclass.constructor.call(this)},timeout:30,paramOrder:undefined,paramsAsHash:false,waitTitle:"Please Wait...",activeAction:null,trackResetOnLoad:false,initEl:function(a){this.el=Ext.get(a);this.id=this.el.id||Ext.id();if(!this.standardSubmit){this.el.on("submit",this.onSubmit,this)}this.el.addClass("x-form")},getEl:function(){return this.el},onSubmit:function(a){a.stopEvent()},destroy:function(a){if(a!==true){this.items.each(function(b){Ext.destroy(b)});Ext.destroy(this.el)}this.items.clear();this.purgeListeners()},isValid:function(){var a=true;this.items.each(function(b){if(!b.validate()){a=false}});return a},isDirty:function(){var a=false;this.items.each(function(b){if(b.isDirty()){a=true;return false}});return a},doAction:function(b,a){if(Ext.isString(b)){b=new Ext.form.Action.ACTION_TYPES[b](this,a)}if(this.fireEvent("beforeaction",this,b)!==false){this.beforeAction(b);b.run.defer(100,b)}return this},submit:function(b){b=b||{};if(this.standardSubmit){var a=b.clientValidation===false||this.isValid();if(a){var c=this.el.dom;if(this.url&&Ext.isEmpty(c.action)){c.action=this.url}c.submit()}return a}var d=String.format("{0}submit",this.api?"direct":"");this.doAction(d,b);return this},load:function(a){var b=String.format("{0}load",this.api?"direct":"");this.doAction(b,a);return this},updateRecord:function(b){b.beginEdit();var a=b.fields;a.each(function(c){var d=this.findField(c.name);if(d){b.set(c.name,d.getValue())}},this);b.endEdit();return this},loadRecord:function(a){this.setValues(a.data);return this},beforeAction:function(a){this.items.each(function(c){if(c.isFormField&&c.syncValue){c.syncValue()}});var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.mask(b.waitMsg,"x-mask-loading")}else{if(this.waitMsgTarget){this.waitMsgTarget=Ext.get(this.waitMsgTarget);this.waitMsgTarget.mask(b.waitMsg,"x-mask-loading")}else{Ext.MessageBox.wait(b.waitMsg,b.waitTitle||this.waitTitle)}}}},afterAction:function(a,c){this.activeAction=null;var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.unmask()}else{if(this.waitMsgTarget){this.waitMsgTarget.unmask()}else{Ext.MessageBox.updateProgress(1);Ext.MessageBox.hide()}}}if(c){if(b.reset){this.reset()}Ext.callback(b.success,b.scope,[this,a]);this.fireEvent("actioncomplete",this,a)}else{Ext.callback(b.failure,b.scope,[this,a]);this.fireEvent("actionfailed",this,a)}},findField:function(c){var b=this.items.get(c);if(!Ext.isObject(b)){var a=function(d){if(d.isFormField){if(d.dataIndex==c||d.id==c||d.getName()==c){b=d;return false}else{if(d.isComposite&&d.rendered){return d.items.each(a)}}}};this.items.each(a)}return b||null},markInvalid:function(h){if(Ext.isArray(h)){for(var c=0,a=h.length;c':">"),c,"")}return d.join("")},createToolbar:function(e){var c=[];var a=Ext.QuickTips&&Ext.QuickTips.isEnabled();function d(j,h,i){return{itemId:j,cls:"x-btn-icon",iconCls:"x-edit-"+j,enableToggle:h!==false,scope:e,handler:i||e.relayBtnCmd,clickEvent:"mousedown",tooltip:a?e.buttonTips[j]||undefined:undefined,overflowText:e.buttonTips[j].title||undefined,tabIndex:-1}}if(this.enableFont&&!Ext.isSafari2){var g=new Ext.Toolbar.Item({autoEl:{tag:"select",cls:"x-font-select",html:this.createFontOptions()}});c.push(g,"-")}if(this.enableFormat){c.push(d("bold"),d("italic"),d("underline"))}if(this.enableFontSize){c.push("-",d("increasefontsize",false,this.adjustFont),d("decreasefontsize",false,this.adjustFont))}if(this.enableColors){c.push("-",{itemId:"forecolor",cls:"x-btn-icon",iconCls:"x-edit-forecolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.forecolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({allowReselect:true,focus:Ext.emptyFn,value:"000000",plain:true,listeners:{scope:this,select:function(i,h){this.execCmd("forecolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}},clickEvent:"mousedown"})},{itemId:"backcolor",cls:"x-btn-icon",iconCls:"x-edit-backcolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.backcolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({focus:Ext.emptyFn,value:"FFFFFF",plain:true,allowReselect:true,listeners:{scope:this,select:function(i,h){if(Ext.isGecko){this.execCmd("useCSS",false);this.execCmd("hilitecolor",h);this.execCmd("useCSS",true);this.deferFocus()}else{this.execCmd(Ext.isOpera?"hilitecolor":"backcolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}}},clickEvent:"mousedown"})})}if(this.enableAlignments){c.push("-",d("justifyleft"),d("justifycenter"),d("justifyright"))}if(!Ext.isSafari2){if(this.enableLinks){c.push("-",d("createlink",false,this.createLink))}if(this.enableLists){c.push("-",d("insertorderedlist"),d("insertunorderedlist"))}if(this.enableSourceEdit){c.push("-",d("sourceedit",true,function(h){this.toggleSourceEdit(!this.sourceEditMode)}))}}var b=new Ext.Toolbar({renderTo:this.wrap.dom.firstChild,items:c});if(g){this.fontSelect=g.el;this.mon(this.fontSelect,"change",function(){var h=this.fontSelect.dom.value;this.relayCmd("fontname",h);this.deferFocus()},this)}this.mon(b.el,"click",function(h){h.preventDefault()});this.tb=b;this.tb.doLayout()},onDisable:function(){this.wrap.mask();Ext.form.HtmlEditor.superclass.onDisable.call(this)},onEnable:function(){this.wrap.unmask();Ext.form.HtmlEditor.superclass.onEnable.call(this)},setReadOnly:function(b){Ext.form.HtmlEditor.superclass.setReadOnly.call(this,b);if(this.initialized){if(Ext.isIE){this.getEditorBody().contentEditable=!b}else{this.setDesignMode(!b)}var a=this.getEditorBody();if(a){a.style.cursor=this.readOnly?"default":"text"}this.disableItems(b)}},getDocMarkup:function(){var a=Ext.fly(this.iframe).getHeight()-this.iframePad*2;return String.format('',this.iframePad,a)},getEditorBody:function(){var a=this.getDoc();return a.body||a.documentElement},getDoc:function(){return Ext.isIE?this.getWin().document:(this.iframe.contentDocument||this.getWin().document)},getWin:function(){return Ext.isIE?this.iframe.contentWindow:window.frames[this.iframe.name]},onRender:function(b,a){Ext.form.HtmlEditor.superclass.onRender.call(this,b,a);this.el.dom.style.border="0 none";this.el.dom.setAttribute("tabIndex",-1);this.el.addClass("x-hidden");if(Ext.isIE){this.el.applyStyles("margin-top:-1px;margin-bottom:-1px;")}this.wrap=this.el.wrap({cls:"x-html-editor-wrap",cn:{cls:"x-html-editor-tb"}});this.createToolbar(this);this.disableItems(true);this.tb.doLayout();this.createIFrame();if(!this.width){var c=this.el.getSize();this.setSize(c.width,this.height||c.height)}this.resizeEl=this.positionEl=this.wrap},createIFrame:function(){var a=document.createElement("iframe");a.name=Ext.id();a.frameBorder="0";a.style.overflow="auto";this.wrap.dom.appendChild(a);this.iframe=a;this.monitorTask=Ext.TaskMgr.start({run:this.checkDesignMode,scope:this,interval:100})},initFrame:function(){Ext.TaskMgr.stop(this.monitorTask);var b=this.getDoc();this.win=this.getWin();b.open();b.write(this.getDocMarkup());b.close();var a={run:function(){var c=this.getDoc();if(c.body||c.readyState=="complete"){Ext.TaskMgr.stop(a);this.setDesignMode(true);this.initEditor.defer(10,this)}},interval:10,duration:10000,scope:this};Ext.TaskMgr.start(a)},checkDesignMode:function(){if(this.wrap&&this.wrap.dom.offsetWidth){var a=this.getDoc();if(!a){return}if(!a.editorInitialized||this.getDesignMode()!="on"){this.initFrame()}}},setDesignMode:function(b){var a;if(a=this.getDoc()){if(this.readOnly){b=false}a.designMode=(/on|true/i).test(String(b).toLowerCase())?"on":"off"}},getDesignMode:function(){var a=this.getDoc();if(!a){return""}return String(a.designMode).toLowerCase()},disableItems:function(a){if(this.fontSelect){this.fontSelect.dom.disabled=a}this.tb.items.each(function(b){if(b.getItemId()!="sourceedit"){b.setDisabled(a)}})},onResize:function(b,c){Ext.form.HtmlEditor.superclass.onResize.apply(this,arguments);if(this.el&&this.iframe){if(Ext.isNumber(b)){var e=b-this.wrap.getFrameWidth("lr");this.el.setWidth(e);this.tb.setWidth(e);this.iframe.style.width=Math.max(e,0)+"px"}if(Ext.isNumber(c)){var a=c-this.wrap.getFrameWidth("tb")-this.tb.el.getHeight();this.el.setHeight(a);this.iframe.style.height=Math.max(a,0)+"px";var d=this.getEditorBody();if(d){d.style.height=Math.max((a-(this.iframePad*2)),0)+"px"}}}},toggleSourceEdit:function(c){var e,b,a;if(c===undefined){c=!this.sourceEditMode}this.sourceEditMode=c===true;var d=this.tb.getComponent("sourceedit");if(d.pressed!==this.sourceEditMode){d.toggle(this.sourceEditMode);if(!d.xtbHidden){return}}if(this.sourceEditMode){a=this.getSize();e=Ext.get(this.iframe).getHeight();this.disableItems(true);this.syncValue();this.iframe.className="x-hidden";this.el.removeClass("x-hidden");this.el.dom.removeAttribute("tabIndex");this.el.focus();this.el.dom.style.height=e+"px"}else{b=parseInt(this.el.dom.style.height,10);if(this.initialized){this.disableItems(this.readOnly)}this.pushValue();this.iframe.className="";this.el.addClass("x-hidden");this.el.dom.setAttribute("tabIndex",-1);this.deferFocus();this.setSize(a);this.iframe.style.height=b+"px"}this.fireEvent("editmodechange",this,this.sourceEditMode)},createLink:function(){var a=prompt(this.createLinkText,this.defaultLinkValue);if(a&&a!="http://"){this.relayCmd("createlink",a)}},initEvents:function(){this.originalValue=this.getValue()},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,setValue:function(a){Ext.form.HtmlEditor.superclass.setValue.call(this,a);this.pushValue();return this},cleanHtml:function(a){a=String(a);if(Ext.isWebKit){a=a.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,"")}if(a.charCodeAt(0)==this.defaultValue.replace(/\D/g,"")){a=a.substring(1)}return a},syncValue:function(){if(this.initialized){var d=this.getEditorBody();var c=d.innerHTML;if(Ext.isWebKit){var b=d.getAttribute("style");var a=b.match(/text-align:(.*?);/i);if(a&&a[1]){c='
'+c+"
"}}c=this.cleanHtml(c);if(this.fireEvent("beforesync",this,c)!==false){this.el.dom.value=c;this.fireEvent("sync",this,c)}}},getValue:function(){this[this.sourceEditMode?"pushValue":"syncValue"]();return Ext.form.HtmlEditor.superclass.getValue.call(this)},pushValue:function(){if(this.initialized){var a=this.el.dom.value;if(!this.activated&&a.length<1){a=this.defaultValue}if(this.fireEvent("beforepush",this,a)!==false){this.getEditorBody().innerHTML=a;if(Ext.isGecko){this.setDesignMode(false);this.setDesignMode(true)}this.fireEvent("push",this,a)}}},deferFocus:function(){this.focus.defer(10,this)},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus()}else{this.el.focus()}},initEditor:function(){try{var c=this.getEditorBody(),a=this.el.getStyles("font-size","font-family","background-image","background-repeat","background-color","color"),g,b;a["background-attachment"]="fixed";c.bgProperties="fixed";Ext.DomHelper.applyStyles(c,a);g=this.getDoc();if(g){try{Ext.EventManager.removeAll(g)}catch(d){}}b=this.onEditorEvent.createDelegate(this);Ext.EventManager.on(g,{mousedown:b,dblclick:b,click:b,keyup:b,buffer:100});if(Ext.isGecko){Ext.EventManager.on(g,"keypress",this.applyCommand,this)}if(Ext.isIE||Ext.isWebKit||Ext.isOpera){Ext.EventManager.on(g,"keydown",this.fixKeys,this)}g.editorInitialized=true;this.initialized=true;this.pushValue();this.setReadOnly(this.readOnly);this.fireEvent("initialize",this)}catch(d){}},onDestroy:function(){if(this.monitorTask){Ext.TaskMgr.stop(this.monitorTask)}if(this.rendered){Ext.destroy(this.tb);var b=this.getDoc();if(b){try{Ext.EventManager.removeAll(b);for(var c in b){delete b[c]}}catch(a){}}if(this.wrap){this.wrap.dom.innerHTML="";this.wrap.remove()}}if(this.el){this.el.removeAllListeners();this.el.remove()}this.purgeListeners()},onFirstFocus:function(){this.activated=true;this.disableItems(this.readOnly);if(Ext.isGecko){this.win.focus();var a=this.win.getSelection();if(!a.focusNode||a.focusNode.nodeType!=3){var b=a.getRangeAt(0);b.selectNodeContents(this.getEditorBody());b.collapse(true);this.deferFocus()}try{this.execCmd("useCSS",true);this.execCmd("styleWithCSS",false)}catch(c){}}this.fireEvent("activate",this)},adjustFont:function(b){var d=b.getItemId()=="increasefontsize"?1:-1,c=this.getDoc(),a=parseInt(c.queryCommandValue("FontSize")||2,10);if((Ext.isSafari&&!Ext.isSafari2)||Ext.isChrome||Ext.isAir){if(a<=10){a=1+d}else{if(a<=13){a=2+d}else{if(a<=16){a=3+d}else{if(a<=18){a=4+d}else{if(a<=24){a=5+d}else{a=6+d}}}}}a=a.constrain(1,6)}else{if(Ext.isSafari){d*=2}a=Math.max(1,a+d)+(Ext.isSafari?"px":0)}this.execCmd("FontSize",a)},onEditorEvent:function(a){this.updateToolbar()},updateToolbar:function(){if(this.readOnly){return}if(!this.activated){this.onFirstFocus();return}var b=this.tb.items.map,c=this.getDoc();if(this.enableFont&&!Ext.isSafari2){var a=(c.queryCommandValue("FontName")||this.defaultFont).toLowerCase();if(a!=this.fontSelect.dom.value){this.fontSelect.dom.value=a}}if(this.enableFormat){b.bold.toggle(c.queryCommandState("bold"));b.italic.toggle(c.queryCommandState("italic"));b.underline.toggle(c.queryCommandState("underline"))}if(this.enableAlignments){b.justifyleft.toggle(c.queryCommandState("justifyleft"));b.justifycenter.toggle(c.queryCommandState("justifycenter"));b.justifyright.toggle(c.queryCommandState("justifyright"))}if(!Ext.isSafari2&&this.enableLists){b.insertorderedlist.toggle(c.queryCommandState("insertorderedlist"));b.insertunorderedlist.toggle(c.queryCommandState("insertunorderedlist"))}Ext.menu.MenuMgr.hideAll();this.syncValue()},relayBtnCmd:function(a){this.relayCmd(a.getItemId())},relayCmd:function(b,a){(function(){this.focus();this.execCmd(b,a);this.updateToolbar()}).defer(10,this)},execCmd:function(b,a){var c=this.getDoc();c.execCommand(b,false,a===undefined?null:a);this.syncValue()},applyCommand:function(b){if(b.ctrlKey){var d=b.getCharCode(),a;if(d>0){d=String.fromCharCode(d);switch(d){case"b":a="bold";break;case"i":a="italic";break;case"u":a="underline";break}if(a){this.win.focus();this.execCmd(a);this.deferFocus();b.preventDefault()}}}},insertAtCursor:function(c){if(!this.activated){return}if(Ext.isIE){this.win.focus();var b=this.getDoc(),a=b.selection.createRange();if(a){a.pasteHTML(c);this.syncValue();this.deferFocus()}}else{this.win.focus();this.execCmd("InsertHTML",c);this.deferFocus()}},fixKeys:function(){if(Ext.isIE){return function(g){var a=g.getKey(),d=this.getDoc(),b;if(a==g.TAB){g.stopEvent();b=d.selection.createRange();if(b){b.collapse(true);b.pasteHTML("    ");this.deferFocus()}}else{if(a==g.ENTER){b=d.selection.createRange();if(b){var c=b.parentElement();if(!c||c.tagName.toLowerCase()!="li"){g.stopEvent();b.pasteHTML("
");b.collapse(false);b.select()}}}}}}else{if(Ext.isOpera){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.win.focus();this.execCmd("InsertHTML","    ");this.deferFocus()}}}else{if(Ext.isWebKit){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.execCmd("InsertText","\t");this.deferFocus()}else{if(a==b.ENTER){b.stopEvent();this.execCmd("InsertHtml","

");this.deferFocus()}}}}}}}(),getToolbar:function(){return this.tb},buttonTips:{bold:{title:"Bold (Ctrl+B)",text:"Make the selected text bold.",cls:"x-html-editor-tip"},italic:{title:"Italic (Ctrl+I)",text:"Make the selected text italic.",cls:"x-html-editor-tip"},underline:{title:"Underline (Ctrl+U)",text:"Underline the selected text.",cls:"x-html-editor-tip"},increasefontsize:{title:"Grow Text",text:"Increase the font size.",cls:"x-html-editor-tip"},decreasefontsize:{title:"Shrink Text",text:"Decrease the font size.",cls:"x-html-editor-tip"},backcolor:{title:"Text Highlight Color",text:"Change the background color of the selected text.",cls:"x-html-editor-tip"},forecolor:{title:"Font Color",text:"Change the color of the selected text.",cls:"x-html-editor-tip"},justifyleft:{title:"Align Text Left",text:"Align text to the left.",cls:"x-html-editor-tip"},justifycenter:{title:"Center Text",text:"Center text in the editor.",cls:"x-html-editor-tip"},justifyright:{title:"Align Text Right",text:"Align text to the right.",cls:"x-html-editor-tip"},insertunorderedlist:{title:"Bullet List",text:"Start a bulleted list.",cls:"x-html-editor-tip"},insertorderedlist:{title:"Numbered List",text:"Start a numbered list.",cls:"x-html-editor-tip"},createlink:{title:"Hyperlink",text:"Make the selected text a hyperlink.",cls:"x-html-editor-tip"},sourceedit:{title:"Source Edit",text:"Switch to source editing mode.",cls:"x-html-editor-tip"}}});Ext.reg("htmleditor",Ext.form.HtmlEditor);Ext.form.TimeField=Ext.extend(Ext.form.ComboBox,{minValue:undefined,maxValue:undefined,minText:"The time in this field must be equal to or after {0}",maxText:"The time in this field must be equal to or before {0}",invalidText:"{0} is not a valid time",format:"g:i A",altFormats:"g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",increment:15,mode:"local",triggerAction:"all",typeAhead:false,initDate:"1/1/2008",initDateFormat:"j/n/Y",initComponent:function(){if(Ext.isDefined(this.minValue)){this.setMinValue(this.minValue,true)}if(Ext.isDefined(this.maxValue)){this.setMaxValue(this.maxValue,true)}if(!this.store){this.generateStore(true)}Ext.form.TimeField.superclass.initComponent.call(this)},setMinValue:function(b,a){this.setLimit(b,true,a);return this},setMaxValue:function(b,a){this.setLimit(b,false,a);return this},generateStore:function(b){var c=this.minValue||new Date(this.initDate).clearTime(),a=this.maxValue||new Date(this.initDate).clearTime().add("mi",(24*60)-1),d=[];while(c<=a){d.push(c.dateFormat(this.format));c=c.add("mi",this.increment)}this.bindStore(d,b)},setLimit:function(b,g,a){var e;if(Ext.isString(b)){e=this.parseDate(b)}else{if(Ext.isDate(b)){e=b}}if(e){var c=new Date(this.initDate).clearTime();c.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds());this[g?"minValue":"maxValue"]=c;if(!a){this.generateStore()}}},getValue:function(){var a=Ext.form.TimeField.superclass.getValue.call(this);return this.formatDate(this.parseDate(a))||""},setValue:function(a){return Ext.form.TimeField.superclass.setValue.call(this,this.formatDate(this.parseDate(a)))},validateValue:Ext.form.DateField.prototype.validateValue,formatDate:Ext.form.DateField.prototype.formatDate,parseDate:function(h){if(!h||Ext.isDate(h)){return h}var j=this.initDate+" ",g=this.initDateFormat+" ",b=Date.parseDate(j+h,g+this.format),c=this.altFormats;if(!b&&c){if(!this.altFormatsArray){this.altFormatsArray=c.split("|")}for(var e=0,d=this.altFormatsArray,a=d.length;e=0){if(!d){c=g-1}d=false;while(c>=0){if(e.call(j||this,k,c,i)===true){return[k,c]}c--}k--}}else{if(c>=g){k++;d=false}while(k','
','
{header}
','
{body}
',"
",'
 
','
 
',"")}if(!c.header){c.header=new Ext.Template('','{cells}',"
")}if(!c.hcell){c.hcell=new Ext.Template('
',this.grid.enableHdMenu?'':"",'{value}',"
")}if(!c.body){c.body=new Ext.Template("{rows}")}if(!c.row){c.row=new Ext.Template('
',"{cells}",(this.enableRowBody?'':""),"
{body}
")}if(!c.cell){c.cell=new Ext.Template('','
{value}
',"")}for(var a in c){var b=c[a];if(b&&Ext.isFunction(b.compile)&&!b.compiled){b.disableFormats=true;b.compile()}}this.templates=c;this.colRe=new RegExp("x-grid3-td-([^\\s]+)","")},fly:function(a){if(!this._flyweight){this._flyweight=new Ext.Element.Flyweight(document.body)}this._flyweight.dom=a;return this._flyweight},getEditorParent:function(){return this.scroller.dom},initElements:function(){var c=Ext.Element;var b=this.grid.getGridEl().dom.firstChild;var a=b.childNodes;this.el=new c(b);this.mainWrap=new c(a[0]);this.mainHd=new c(this.mainWrap.dom.firstChild);if(this.grid.hideHeaders){this.mainHd.setDisplayed(false)}this.innerHd=this.mainHd.dom.firstChild;this.scroller=new c(this.mainWrap.dom.childNodes[1]);if(this.forceFit){this.scroller.setStyle("overflow-x","hidden")}this.mainBody=new c(this.scroller.dom.firstChild);this.focusEl=new c(this.scroller.dom.childNodes[1]);this.focusEl.swallowEvent("click",true);this.resizeMarker=new c(a[1]);this.resizeProxy=new c(a[2])},getRows:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},findCell:function(a){if(!a){return false}return this.fly(a).findParent(this.cellSelector,this.cellSelectorDepth)},findCellIndex:function(c,b){var a=this.findCell(c);if(a&&(!b||this.fly(a).hasClass(b))){return this.getCellIndex(a)}return false},getCellIndex:function(b){if(b){var a=b.className.match(this.colRe);if(a&&a[1]){return this.cm.getIndexById(a[1])}}return false},findHeaderCell:function(b){var a=this.findCell(b);return a&&this.fly(a).hasClass(this.hdCls)?a:null},findHeaderIndex:function(a){return this.findCellIndex(a,this.hdCls)},findRow:function(a){if(!a){return false}return this.fly(a).findParent(this.rowSelector,this.rowSelectorDepth)},findRowIndex:function(a){var b=this.findRow(a);return b?b.rowIndex:false},findRowBody:function(a){if(!a){return false}return this.fly(a).findParent(this.rowBodySelector,this.rowBodySelectorDepth)},getRow:function(a){return this.getRows()[a]},getCell:function(b,a){return this.getRow(b).getElementsByTagName("td")[a]},getHeaderCell:function(a){return this.mainHd.dom.getElementsByTagName("td")[a]},addRowClass:function(c,a){var b=this.getRow(c);if(b){this.fly(b).addClass(a)}},removeRowClass:function(c,a){var b=this.getRow(c);if(b){this.fly(b).removeClass(a)}},removeRow:function(a){Ext.removeNode(this.getRow(a));this.syncFocusEl(a)},removeRows:function(c,a){var b=this.mainBody.dom;for(var d=c;d<=a;d++){Ext.removeNode(b.childNodes[c])}this.syncFocusEl(c)},getScrollState:function(){var a=this.scroller.dom;return{left:a.scrollLeft,top:a.scrollTop}},restoreScroll:function(a){var b=this.scroller.dom;b.scrollLeft=a.left;b.scrollTop=a.top},scrollToTop:function(){this.scroller.dom.scrollTop=0;this.scroller.dom.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.scroller.dom;this.grid.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.scroller.dom;this.innerHd.scrollLeft=a.scrollLeft;this.innerHd.scrollLeft=a.scrollLeft},updateSortIcon:function(b,a){var d=this.sortClasses;var c=this.mainHd.select("td").removeClass(d);c.item(b).addClass(d[a=="DESC"?1:0])},updateAllColumnWidths:function(){var d=this.getTotalWidth(),l=this.cm.getColumnCount(),g=[],e,b;for(b=0;b=this.ds.getCount()){return null}d=(d!==undefined?d:0);var c=this.getRow(h),a=this.cm,e=a.getColumnCount(),b;if(!(g===false&&d===0)){while(dm){n.scrollTop=q-a}}if(e!==false){var l=parseInt(h.offsetLeft,10);var j=l+h.offsetWidth;var i=parseInt(n.scrollLeft,10);var b=i+n.clientWidth;if(lb){n.scrollLeft=j-n.clientWidth}}}return this.getResolvedXY(r)},insertRows:function(a,i,e,h){var d=a.getCount()-1;if(!h&&i===0&&e>=d){this.fireEvent("beforerowsinserted",this,i,e);this.refresh();this.fireEvent("rowsinserted",this,i,e)}else{if(!h){this.fireEvent("beforerowsinserted",this,i,e)}var b=this.renderRows(i,e),g=this.getRow(i);if(g){if(i===0){Ext.fly(this.getRow(0)).removeClass(this.firstRowCls)}Ext.DomHelper.insertHtml("beforeBegin",g,b)}else{var c=this.getRow(d-1);if(c){Ext.fly(c).removeClass(this.lastRowCls)}Ext.DomHelper.insertHtml("beforeEnd",this.mainBody.dom,b)}if(!h){this.fireEvent("rowsinserted",this,i,e);this.processRows(i)}else{if(i===0||i>=d){Ext.fly(this.getRow(i)).addClass(i===0?this.firstRowCls:this.lastRowCls)}}}this.syncFocusEl(i)},deleteRows:function(a,c,b){if(a.getRowCount()<1){this.refresh()}else{this.fireEvent("beforerowsdeleted",this,c,b);this.removeRows(c,b);this.processRows(c);this.fireEvent("rowsdeleted",this,c,b)}},getColumnStyle:function(a,c){var b=!c?(this.cm.config[a].css||""):"";b+="width:"+this.getColumnWidth(a)+";";if(this.cm.isHidden(a)){b+="display:none;"}var d=this.cm.config[a].align;if(d){b+="text-align:"+d+";"}return b},getColumnWidth:function(b){var a=this.cm.getColumnWidth(b);if(Ext.isNumber(a)){return(Ext.isBorderBox||(Ext.isWebKit&&!Ext.isSafari2)?a:(a-this.borderWidth>0?a-this.borderWidth:0))+"px"}return a},getTotalWidth:function(){return this.cm.getTotalWidth()+"px"},fitColumns:function(d,h,j){var q=this.cm,k;var l=q.getTotalWidth(false);var a=this.grid.getGridEl().getWidth(true)-this.getScrollOffset();if(a<20){return}var e=a-l;if(e===0){return false}var m=q.getColumnCount(true);var s=m-(Ext.isNumber(j)?1:0);if(s===0){s=1;j=undefined}var r=q.getColumnCount();var o=[];var n=0;var c=0;var p;for(k=0;ka){var g=s!=m?j:n;q.setColumnWidth(g,Math.max(1,q.getColumnWidth(g)-(l-a)),true)}if(d!==true){this.updateAllColumnWidths()}return true},autoExpand:function(b){var i=this.grid,a=this.cm;if(!this.userResized&&i.autoExpandColumn){var d=a.getTotalWidth(false);var j=this.grid.getGridEl().getWidth(true)-this.getScrollOffset();if(d!=j){var h=a.getIndexById(i.autoExpandColumn);var e=a.getColumnWidth(h);var c=Math.min(Math.max(((j-d)+e),i.autoExpandMin),i.autoExpandMax);if(c!=e){a.setColumnWidth(h,c,true);if(b!==true){this.updateColumnWidth(h,c)}}}}},getColumnData:function(){var d=[],a=this.cm,e=a.getColumnCount();for(var c=0;c'+this.emptyText+"")}},updateHeaderSortState:function(){var b=this.ds.getSortState();if(!b){return}if(!this.sortState||(this.sortState.field!=b.field||this.sortState.direction!=b.direction)){this.grid.fireEvent("sortchange",this.grid,b)}this.sortState=b;var c=this.cm.findColumnIndex(b.field);if(c!=-1){var a=b.direction;this.updateSortIcon(c,a)}},clearHeaderSortState:function(){if(!this.sortState){return}this.grid.fireEvent("sortchange",this.grid,null);this.mainHd.select("td").removeClass(this.sortClasses);delete this.sortState},destroy:function(){if(this.scrollToTopTask&&this.scrollToTopTask.cancel){this.scrollToTopTask.cancel()}if(this.colMenu){Ext.menu.MenuMgr.unregister(this.colMenu);this.colMenu.destroy();delete this.colMenu}if(this.hmenu){Ext.menu.MenuMgr.unregister(this.hmenu);this.hmenu.destroy();delete this.hmenu}this.initData(null,null);this.purgeListeners();Ext.fly(this.innerHd).un("click",this.handleHdDown,this);if(this.grid.enableColumnMove){Ext.destroy(this.columnDrag.el,this.columnDrag.proxy.ghost,this.columnDrag.proxy.el,this.columnDrop.el,this.columnDrop.proxyTop,this.columnDrop.proxyBottom,this.columnDrag.dragData.ddel,this.columnDrag.dragData.header);if(this.columnDrag.proxy.anim){Ext.destroy(this.columnDrag.proxy.anim)}delete this.columnDrag.proxy.ghost;delete this.columnDrag.dragData.ddel;delete this.columnDrag.dragData.header;this.columnDrag.destroy();delete Ext.dd.DDM.locationCache[this.columnDrag.id];delete this.columnDrag._domRef;delete this.columnDrop.proxyTop;delete this.columnDrop.proxyBottom;this.columnDrop.destroy();delete Ext.dd.DDM.locationCache["gridHeader"+this.grid.getGridEl().id];delete this.columnDrop._domRef;delete Ext.dd.DDM.ids[this.columnDrop.ddGroup]}if(this.splitZone){this.splitZone.destroy();delete this.splitZone._domRef;delete Ext.dd.DDM.ids["gridSplitters"+this.grid.getGridEl().id]}Ext.fly(this.innerHd).removeAllListeners();Ext.removeNode(this.innerHd);delete this.innerHd;Ext.destroy(this.el,this.mainWrap,this.mainHd,this.scroller,this.mainBody,this.focusEl,this.resizeMarker,this.resizeProxy,this.activeHdBtn,this.dragZone,this.splitZone,this._flyweight);delete this.grid.container;if(this.dragZone){this.dragZone.destroy()}Ext.dd.DDM.currentTarget=null;delete Ext.dd.DDM.locationCache[this.grid.getGridEl().id];Ext.EventManager.removeResizeListener(this.onWindowResize,this)},onDenyColumnHide:function(){},render:function(){if(this.autoFill){var a=this.grid.ownerCt;if(a&&a.getLayout()){a.on("afterlayout",function(){this.fitColumns(true,true);this.updateHeaders()},this,{single:true})}else{this.fitColumns(true,true)}}else{if(this.forceFit){this.fitColumns(true,false)}else{if(this.grid.autoExpandColumn){this.autoExpand(true)}}}this.renderUI()},initData:function(b,a){if(this.ds){this.ds.un("load",this.onLoad,this);this.ds.un("datachanged",this.onDataChange,this);this.ds.un("add",this.onAdd,this);this.ds.un("remove",this.onRemove,this);this.ds.un("update",this.onUpdate,this);this.ds.un("clear",this.onClear,this);if(this.ds!==b&&this.ds.autoDestroy){this.ds.destroy()}}if(b){b.on({scope:this,load:this.onLoad,datachanged:this.onDataChange,add:this.onAdd,remove:this.onRemove,update:this.onUpdate,clear:this.onClear})}this.ds=b;if(this.cm){this.cm.un("configchange",this.onColConfigChange,this);this.cm.un("widthchange",this.onColWidthChange,this);this.cm.un("headerchange",this.onHeaderChange,this);this.cm.un("hiddenchange",this.onHiddenChange,this);this.cm.un("columnmoved",this.onColumnMove,this)}if(a){delete this.lastViewWidth;a.on({scope:this,configchange:this.onColConfigChange,widthchange:this.onColWidthChange,headerchange:this.onHeaderChange,hiddenchange:this.onHiddenChange,columnmoved:this.onColumnMove})}this.cm=a},onDataChange:function(){this.refresh();this.updateHeaderSortState();this.syncFocusEl(0)},onClear:function(){this.refresh();this.syncFocusEl(0)},onUpdate:function(b,a){this.refreshRow(a)},onAdd:function(c,a,b){this.insertRows(c,b,b+(a.length-1))},onRemove:function(d,a,b,c){if(c!==true){this.fireEvent("beforerowremoved",this,b,a)}this.removeRow(b);if(c!==true){this.processRows(b);this.applyEmptyText();this.fireEvent("rowremoved",this,b,a)}},onLoad:function(){if(Ext.isGecko){if(!this.scrollToTopTask){this.scrollToTopTask=new Ext.util.DelayedTask(this.scrollToTop,this)}this.scrollToTopTask.delay(1)}else{this.scrollToTop()}},onColWidthChange:function(a,b,c){this.updateColumnWidth(b,c)},onHeaderChange:function(a,b,c){this.updateHeaders()},onHiddenChange:function(a,b,c){this.updateColumnHidden(b,c)},onColumnMove:function(a,d,b){this.indexMap=null;var c=this.getScrollState();this.refresh(true);this.restoreScroll(c);this.afterMove(b);this.grid.fireEvent("columnmove",d,b)},onColConfigChange:function(){delete this.lastViewWidth;this.indexMap=null;this.refresh(true)},initUI:function(a){a.on("headerclick",this.onHeaderClick,this)},initEvents:function(){},onHeaderClick:function(b,a){if(this.headersDisabled||!this.cm.isSortable(a)){return}b.stopEditing(true);b.store.sort(this.cm.getDataIndex(a))},onRowOver:function(b,a){var c;if((c=this.findRowIndex(a))!==false){this.addRowClass(c,"x-grid3-row-over")}},onRowOut:function(b,a){var c;if((c=this.findRowIndex(a))!==false&&!b.within(this.getRow(c),true)){this.removeRowClass(c,"x-grid3-row-over")}},handleWheel:function(a){a.stopPropagation()},onRowSelect:function(a){this.addRowClass(a,this.selectedRowClass)},onRowDeselect:function(a){this.removeRowClass(a,this.selectedRowClass)},onCellSelect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).addClass("x-grid3-cell-selected")}},onCellDeselect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).removeClass("x-grid3-cell-selected")}},onColumnSplitterMoved:function(c,b){this.userResized=true;var a=this.grid.colModel;a.setColumnWidth(c,b,true);if(this.forceFit){this.fitColumns(true,false,c);this.updateAllColumnWidths()}else{this.updateColumnWidth(c,b);this.syncHeaderScroll()}this.grid.fireEvent("columnresize",c,b)},handleHdMenuClick:function(c){var b=this.hdCtxIndex,a=this.cm,d=this.ds,e=c.getItemId();switch(e){case"asc":d.sort(a.getDataIndex(b),"ASC");break;case"desc":d.sort(a.getDataIndex(b),"DESC");break;default:b=a.getIndexById(e.substr(4));if(b!=-1){if(c.checked&&a.getColumnsBy(this.isHideableColumn,this).length<=1){this.onDenyColumnHide();return false}a.setHidden(b,c.checked)}}return true},isHideableColumn:function(a){return !a.hidden},beforeColMenuShow:function(){var a=this.cm,c=a.getColumnCount();this.colMenu.removeAll();for(var b=0;b=0&&this.config[a].resizable!==false&&this.config[a].fixed!==true},setHidden:function(a,b){var d=this.config[a];if(d.hidden!==b){d.hidden=b;this.totalWidth=null;this.fireEvent("hiddenchange",this,a,b)}},setEditor:function(a,b){this.config[a].setEditor(b)},destroy:function(){var d;for(var b=0,a=this.config.length;b0},isSelected:function(a){var b=Ext.isNumber(a)?this.grid.store.getAt(a):a;return(b&&this.selections.key(b.id)?true:false)},isIdSelected:function(a){return(this.selections.key(a)?true:false)},handleMouseDown:function(d,i,h){if(h.button!==0||this.isLocked()){return}var a=this.grid.getView();if(h.shiftKey&&!this.singleSelect&&this.last!==false){var c=this.last;this.selectRange(c,i,h.ctrlKey);this.last=c;a.focusRow(i)}else{var b=this.isSelected(i);if(h.ctrlKey&&b){this.deselectRow(i)}else{if(!b||this.getCount()>1){this.selectRow(i,h.ctrlKey||h.shiftKey);a.focusRow(i)}}}},selectRows:function(c,d){if(!d){this.clearSelections()}for(var b=0,a=c.length;b=a;c--){this.selectRow(c,true)}}},deselectRange:function(c,b,a){if(this.isLocked()){return}for(var d=c;d<=b;d++){this.deselectRow(d,a)}},selectRow:function(b,d,a){if(this.isLocked()||(b<0||b>=this.grid.store.getCount())||(d&&this.isSelected(b))){return}var c=this.grid.store.getAt(b);if(c&&this.fireEvent("beforerowselect",this,b,d,c)!==false){if(!d||this.singleSelect){this.clearSelections()}this.selections.add(c);this.last=this.lastActive=b;if(!a){this.grid.getView().onRowSelect(b)}this.fireEvent("rowselect",this,b,c);this.fireEvent("selectionchange",this)}},deselectRow:function(b,a){if(this.isLocked()){return}if(this.last==b){this.last=false}if(this.lastActive==b){this.lastActive=false}var c=this.grid.store.getAt(b);if(c){this.selections.remove(c);if(!a){this.grid.getView().onRowDeselect(b)}this.fireEvent("rowdeselect",this,b,c);this.fireEvent("selectionchange",this)}},restoreLast:function(){if(this._last){this.last=this._last}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)},onEditorKey:function(n,l){var d=l.getKey(),h,i=this.grid,o=i.lastEdit,j=i.activeEditor,p,o,a,m;var b=l.shiftKey;if(d==l.TAB){l.stopEvent();j.completeEdit();if(b){h=i.walkCells(j.row,j.col-1,-1,this.acceptsNav,this)}else{h=i.walkCells(j.row,j.col+1,1,this.acceptsNav,this)}}else{if(d==l.ENTER){if(this.moveEditorOnEnter!==false){if(b){h=i.walkCells(o.row-1,o.col,-1,this.acceptsNav,this)}else{h=i.walkCells(o.row+1,o.col,1,this.acceptsNav,this)}}}}if(h){a=h[0];m=h[1];if(o.row!=a){this.selectRow(a)}if(i.isEditor&&i.editing){p=i.activeEditor;if(p&&p.field.triggerBlur){p.field.triggerBlur()}}i.startEditing(a,m)}},destroy:function(){if(this.rowNav){this.rowNav.disable();this.rowNav=null}Ext.grid.RowSelectionModel.superclass.destroy.call(this)}});Ext.grid.Column=Ext.extend(Object,{isColumn:true,constructor:function(b){Ext.apply(this,b);if(Ext.isString(this.renderer)){this.renderer=Ext.util.Format[this.renderer]}else{if(Ext.isObject(this.renderer)){this.scope=this.renderer.scope;this.renderer=this.renderer.fn}}if(!this.scope){this.scope=this}var a=this.editor;delete this.editor;this.setEditor(a)},renderer:function(a){if(Ext.isString(a)&&a.length<1){return" "}return a},getEditor:function(a){return this.editable!==false?this.editor:null},setEditor:function(b){var a=this.editor;if(a){if(a.gridEditor){a.gridEditor.destroy();delete a.gridEditor}else{a.destroy()}}this.editor=null;if(b){if(!b.isXType){b=Ext.create(b,"textfield")}this.editor=b}},getCellEditor:function(b){var a=this.getEditor(b);if(a){if(!a.startEdit){if(!a.gridEditor){a.gridEditor=new Ext.grid.GridEditor(a)}a=a.gridEditor}}return a}});Ext.grid.BooleanColumn=Ext.extend(Ext.grid.Column,{trueText:"true",falseText:"false",undefinedText:" ",constructor:function(a){Ext.grid.BooleanColumn.superclass.constructor.call(this,a);var c=this.trueText,d=this.falseText,b=this.undefinedText;this.renderer=function(e){if(e===undefined){return b}if(!e||e==="false"){return d}return c}}});Ext.grid.NumberColumn=Ext.extend(Ext.grid.Column,{format:"0,000.00",constructor:function(a){Ext.grid.NumberColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.numberRenderer(this.format)}});Ext.grid.DateColumn=Ext.extend(Ext.grid.Column,{format:"m/d/Y",constructor:function(a){Ext.grid.DateColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.dateRenderer(this.format)}});Ext.grid.TemplateColumn=Ext.extend(Ext.grid.Column,{constructor:function(a){Ext.grid.TemplateColumn.superclass.constructor.call(this,a);var b=(!Ext.isPrimitive(this.tpl)&&this.tpl.compile)?this.tpl:new Ext.XTemplate(this.tpl);this.renderer=function(d,e,c){return b.apply(c.data)};this.tpl=b}});Ext.grid.Column.types={gridcolumn:Ext.grid.Column,booleancolumn:Ext.grid.BooleanColumn,numbercolumn:Ext.grid.NumberColumn,datecolumn:Ext.grid.DateColumn,templatecolumn:Ext.grid.TemplateColumn};Ext.grid.RowNumberer=Ext.extend(Object,{header:"",width:23,sortable:false,constructor:function(a){Ext.apply(this,a);if(this.rowspan){this.renderer=this.renderer.createDelegate(this)}},fixed:true,hideable:false,menuDisabled:true,dataIndex:"",id:"numberer",rowspan:undefined,renderer:function(b,c,a,d){if(this.rowspan){c.cellAttr='rowspan="'+this.rowspan+'"'}return d+1}});Ext.grid.CheckboxSelectionModel=Ext.extend(Ext.grid.RowSelectionModel,{header:'
 
',width:20,sortable:false,menuDisabled:true,fixed:true,hideable:false,dataIndex:"",id:"checker",constructor:function(){Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this,arguments);if(this.checkOnly){this.handleMouseDown=Ext.emptyFn}},initEvents:function(){Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);this.grid.on("render",function(){var a=this.grid.getView();a.mainBody.on("mousedown",this.onMouseDown,this);Ext.fly(a.innerHd).on("mousedown",this.onHdMouseDown,this)},this)},handleMouseDown:function(){Ext.grid.CheckboxSelectionModel.superclass.handleMouseDown.apply(this,arguments);this.mouseHandled=true},onMouseDown:function(c,b){if(c.button===0&&b.className=="x-grid3-row-checker"){c.stopEvent();var d=c.getTarget(".x-grid3-row");if(!this.mouseHandled&&d){var a=d.rowIndex;if(this.isSelected(a)){this.deselectRow(a)}else{this.selectRow(a,true);this.grid.getView().focusRow(a)}}}this.mouseHandled=false},onHdMouseDown:function(c,a){if(a.className=="x-grid3-hd-checker"){c.stopEvent();var b=Ext.fly(a.parentNode);var d=b.hasClass("x-grid3-hd-checker-on");if(d){b.removeClass("x-grid3-hd-checker-on");this.clearSelections()}else{b.addClass("x-grid3-hd-checker-on");this.selectAll()}}},renderer:function(b,c,a){return'
 
'}});Ext.grid.CellSelectionModel=Ext.extend(Ext.grid.AbstractSelectionModel,{constructor:function(a){Ext.apply(this,a);this.selection=null;this.addEvents("beforecellselect","cellselect","selectionchange");Ext.grid.CellSelectionModel.superclass.constructor.call(this)},initEvents:function(){this.grid.on("cellmousedown",this.handleMouseDown,this);this.grid.on(Ext.EventManager.useKeydown?"keydown":"keypress",this.handleKeyDown,this);this.grid.getView().on({scope:this,refresh:this.onViewChange,rowupdated:this.onRowUpdated,beforerowremoved:this.clearSelections,beforerowsinserted:this.clearSelections});if(this.grid.isEditor){this.grid.on("beforeedit",this.beforeEdit,this)}},beforeEdit:function(a){this.select(a.row,a.column,false,true,a.record)},onRowUpdated:function(a,b,c){if(this.selection&&this.selection.record==c){a.onCellSelect(b,this.selection.cell[1])}},onViewChange:function(){this.clearSelections(true)},getSelectedCell:function(){return this.selection?this.selection.cell:null},clearSelections:function(b){var a=this.selection;if(a){if(b!==true){this.grid.view.onCellDeselect(a.cell[0],a.cell[1])}this.selection=null;this.fireEvent("selectionchange",this,null)}},hasSelection:function(){return this.selection?true:false},handleMouseDown:function(b,d,a,c){if(c.button!==0||this.isLocked()){return}this.select(d,a)},select:function(g,c,b,e,d){if(this.fireEvent("beforecellselect",this,g,c)!==false){this.clearSelections();d=d||this.grid.store.getAt(g);this.selection={record:d,cell:[g,c]};if(!b){var a=this.grid.getView();a.onCellSelect(g,c);if(e!==true){a.focusCell(g,c)}}this.fireEvent("cellselect",this,g,c);this.fireEvent("selectionchange",this,this.selection)}},isSelectable:function(c,b,a){return !a.isHidden(b)},onEditorKey:function(b,a){if(a.getKey()==a.TAB){this.handleKeyDown(a)}},handleKeyDown:function(j){if(!j.isNavKeyPress()){return}var d=j.getKey(),i=this.grid,p=this.selection,b=this,m=function(g,c,e){return i.walkCells(g,c,e,i.isEditor&&i.editing?b.acceptsNav:b.isSelectable,b)},o,h,a,l,n;switch(d){case j.ESC:case j.PAGE_UP:case j.PAGE_DOWN:break;default:j.stopEvent();break}if(!p){o=m(0,0,1);if(o){this.select(o[0],o[1])}return}o=p.cell;a=o[0];l=o[1];switch(d){case j.TAB:if(j.shiftKey){h=m(a,l-1,-1)}else{h=m(a,l+1,1)}break;case j.DOWN:h=m(a+1,l,1);break;case j.UP:h=m(a-1,l,-1);break;case j.RIGHT:h=m(a,l+1,1);break;case j.LEFT:h=m(a,l-1,-1);break;case j.ENTER:if(i.isEditor&&!i.editing){i.startEditing(a,l);return}break}if(h){a=h[0];l=h[1];this.select(a,l);if(i.isEditor&&i.editing){n=i.activeEditor;if(n&&n.field.triggerBlur){n.field.triggerBlur()}i.startEditing(a,l)}}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)}});Ext.grid.EditorGridPanel=Ext.extend(Ext.grid.GridPanel,{clicksToEdit:2,forceValidation:false,isEditor:true,detectEdit:false,autoEncode:false,trackMouseOver:false,initComponent:function(){Ext.grid.EditorGridPanel.superclass.initComponent.call(this);if(!this.selModel){this.selModel=new Ext.grid.CellSelectionModel()}this.activeEditor=null;this.addEvents("beforeedit","afteredit","validateedit")},initEvents:function(){Ext.grid.EditorGridPanel.superclass.initEvents.call(this);this.getGridEl().on("mousewheel",this.stopEditing.createDelegate(this,[true]),this);this.on("columnresize",this.stopEditing,this,[true]);if(this.clicksToEdit==1){this.on("cellclick",this.onCellDblClick,this)}else{var a=this.getView();if(this.clicksToEdit=="auto"&&a.mainBody){a.mainBody.on("mousedown",this.onAutoEditClick,this)}this.on("celldblclick",this.onCellDblClick,this)}},onResize:function(){Ext.grid.EditorGridPanel.superclass.onResize.apply(this,arguments);var a=this.activeEditor;if(this.editing&&a){a.realign(true)}},onCellDblClick:function(b,c,a){this.startEditing(c,a)},onAutoEditClick:function(c,b){if(c.button!==0){return}var g=this.view.findRowIndex(b),a=this.view.findCellIndex(b);if(g!==false&&a!==false){this.stopEditing();if(this.selModel.getSelectedCell){var d=this.selModel.getSelectedCell();if(d&&d[0]===g&&d[1]===a){this.startEditing(g,a)}}else{if(this.selModel.isSelected(g)){this.startEditing(g,a)}}}},onEditComplete:function(b,d,a){this.editing=false;this.lastActiveEditor=this.activeEditor;this.activeEditor=null;var c=b.record,h=this.colModel.getDataIndex(b.col);d=this.postEditValue(d,a,c,h);if(this.forceValidation===true||String(d)!==String(a)){var g={grid:this,record:c,field:h,originalValue:a,value:d,row:b.row,column:b.col,cancel:false};if(this.fireEvent("validateedit",g)!==false&&!g.cancel&&String(d)!==String(a)){c.set(h,g.value);delete g.cancel;this.fireEvent("afteredit",g)}}this.view.focusCell(b.row,b.col)},startEditing:function(i,c){this.stopEditing();if(this.colModel.isCellEditable(c,i)){this.view.ensureVisible(i,c,true);var d=this.store.getAt(i),h=this.colModel.getDataIndex(c),g={grid:this,record:d,field:h,value:d.data[h],row:i,column:c,cancel:false};if(this.fireEvent("beforeedit",g)!==false&&!g.cancel){this.editing=true;var b=this.colModel.getCellEditor(c,i);if(!b){return}if(!b.rendered){b.parentEl=this.view.getEditorParent(b);b.on({scope:this,render:{fn:function(e){e.field.focus(false,true)},single:true,scope:this},specialkey:function(k,j){this.getSelectionModel().onEditorKey(k,j)},complete:this.onEditComplete,canceledit:this.stopEditing.createDelegate(this,[true])})}Ext.apply(b,{row:i,col:c,record:d});this.lastEdit={row:i,col:c};this.activeEditor=b;b.selectSameEditor=(this.activeEditor==this.lastActiveEditor);var a=this.preEditValue(d,h);b.startEdit(this.view.getCell(i,c).firstChild,Ext.isDefined(a)?a:"");(function(){delete b.selectSameEditor}).defer(50)}}},preEditValue:function(a,c){var b=a.data[c];return this.autoEncode&&Ext.isString(b)?Ext.util.Format.htmlDecode(b):b},postEditValue:function(c,a,b,d){return this.autoEncode&&Ext.isString(c)?Ext.util.Format.htmlEncode(c):c},stopEditing:function(b){if(this.editing){var a=this.lastActiveEditor=this.activeEditor;if(a){a[b===true?"cancelEdit":"completeEdit"]();this.view.focusCell(a.row,a.col)}this.activeEditor=null}this.editing=false}});Ext.reg("editorgrid",Ext.grid.EditorGridPanel);Ext.grid.GridEditor=function(b,a){Ext.grid.GridEditor.superclass.constructor.call(this,b,a);b.monitorTab=false};Ext.extend(Ext.grid.GridEditor,Ext.Editor,{alignment:"tl-tl",autoSize:"width",hideEl:false,cls:"x-small-editor x-grid-editor",shim:false,shadow:false});Ext.grid.PropertyRecord=Ext.data.Record.create([{name:"name",type:"string"},"value"]);Ext.grid.PropertyStore=Ext.extend(Ext.util.Observable,{constructor:function(a,b){this.grid=a;this.store=new Ext.data.Store({recordType:Ext.grid.PropertyRecord});this.store.on("update",this.onUpdate,this);if(b){this.setSource(b)}Ext.grid.PropertyStore.superclass.constructor.call(this)},setSource:function(c){this.source=c;this.store.removeAll();var b=[];for(var a in c){if(this.isEditableValue(c[a])){b.push(new Ext.grid.PropertyRecord({name:a,value:c[a]},a))}}this.store.loadRecords({records:b},{},true)},onUpdate:function(e,a,d){if(d==Ext.data.Record.EDIT){var b=a.data.value;var c=a.modified.value;if(this.grid.fireEvent("beforepropertychange",this.source,a.id,b,c)!==false){this.source[a.id]=b;a.commit();this.grid.fireEvent("propertychange",this.source,a.id,b,c)}else{a.reject()}}},getProperty:function(a){return this.store.getAt(a)},isEditableValue:function(a){return Ext.isPrimitive(a)||Ext.isDate(a)},setValue:function(d,c,a){var b=this.getRec(d);if(b){b.set("value",c);this.source[d]=c}else{if(a){this.source[d]=c;b=new Ext.grid.PropertyRecord({name:d,value:c},d);this.store.add(b)}}},remove:function(b){var a=this.getRec(b);if(a){this.store.remove(a);delete this.source[b]}},getRec:function(a){return this.store.getById(a)},getSource:function(){return this.source}});Ext.grid.PropertyColumnModel=Ext.extend(Ext.grid.ColumnModel,{nameText:"Name",valueText:"Value",dateFormat:"m/j/Y",trueText:"true",falseText:"false",constructor:function(c,b){var d=Ext.grid,e=Ext.form;this.grid=c;d.PropertyColumnModel.superclass.constructor.call(this,[{header:this.nameText,width:50,sortable:true,dataIndex:"name",id:"name",menuDisabled:true},{header:this.valueText,width:50,resizable:false,dataIndex:"value",id:"value",menuDisabled:true}]);this.store=b;var a=new e.Field({autoCreate:{tag:"select",children:[{tag:"option",value:"true",html:this.trueText},{tag:"option",value:"false",html:this.falseText}]},getValue:function(){return this.el.dom.value=="true"}});this.editors={date:new d.GridEditor(new e.DateField({selectOnFocus:true})),string:new d.GridEditor(new e.TextField({selectOnFocus:true})),number:new d.GridEditor(new e.NumberField({selectOnFocus:true,style:"text-align:left;"})),"boolean":new d.GridEditor(a,{autoSize:"both"})};this.renderCellDelegate=this.renderCell.createDelegate(this);this.renderPropDelegate=this.renderProp.createDelegate(this)},renderDate:function(a){return a.dateFormat(this.dateFormat)},renderBool:function(a){return this[a?"trueText":"falseText"]},isCellEditable:function(a,b){return a==1},getRenderer:function(a){return a==1?this.renderCellDelegate:this.renderPropDelegate},renderProp:function(a){return this.getPropertyName(a)},renderCell:function(d,b,c){var a=this.grid.customRenderers[c.get("name")];if(a){return a.apply(this,arguments)}var e=d;if(Ext.isDate(d)){e=this.renderDate(d)}else{if(typeof d=="boolean"){e=this.renderBool(d)}}return Ext.util.Format.htmlEncode(e)},getPropertyName:function(b){var a=this.grid.propertyNames;return a&&a[b]?a[b]:b},getCellEditor:function(a,e){var b=this.store.getProperty(e),d=b.data.name,c=b.data.value;if(this.grid.customEditors[d]){return this.grid.customEditors[d]}if(Ext.isDate(c)){return this.editors.date}else{if(typeof c=="number"){return this.editors.number}else{if(typeof c=="boolean"){return this.editors["boolean"]}else{return this.editors.string}}}},destroy:function(){Ext.grid.PropertyColumnModel.superclass.destroy.call(this);for(var a in this.editors){Ext.destroy(this.editors[a])}}});Ext.grid.PropertyGrid=Ext.extend(Ext.grid.EditorGridPanel,{enableColumnMove:false,stripeRows:false,trackMouseOver:false,clicksToEdit:1,enableHdMenu:false,viewConfig:{forceFit:true},initComponent:function(){this.customRenderers=this.customRenderers||{};this.customEditors=this.customEditors||{};this.lastEditRow=null;var b=new Ext.grid.PropertyStore(this);this.propStore=b;var a=new Ext.grid.PropertyColumnModel(this,b);b.store.sort("name","ASC");this.addEvents("beforepropertychange","propertychange");this.cm=a;this.ds=b.store;Ext.grid.PropertyGrid.superclass.initComponent.call(this);this.mon(this.selModel,"beforecellselect",function(e,d,c){if(c===0){this.startEditing.defer(200,this,[d,1]);return false}},this)},onRender:function(){Ext.grid.PropertyGrid.superclass.onRender.apply(this,arguments);this.getGridEl().addClass("x-props-grid")},afterRender:function(){Ext.grid.PropertyGrid.superclass.afterRender.apply(this,arguments);if(this.source){this.setSource(this.source)}},setSource:function(a){this.propStore.setSource(a)},getSource:function(){return this.propStore.getSource()},setProperty:function(c,b,a){this.propStore.setValue(c,b,a)},removeProperty:function(a){this.propStore.remove(a)}});Ext.reg("propertygrid",Ext.grid.PropertyGrid);Ext.grid.GroupingView=Ext.extend(Ext.grid.GridView,{groupByText:"Group By This Field",showGroupsText:"Show in Groups",hideGroupedColumn:false,showGroupName:true,startCollapsed:false,enableGrouping:true,enableGroupingMenu:true,enableNoGroups:true,emptyGroupText:"(None)",ignoreAdd:false,groupTextTpl:"{text}",groupMode:"value",initTemplates:function(){Ext.grid.GroupingView.superclass.initTemplates.call(this);this.state={};var a=this.grid.getSelectionModel();a.on(a.selectRow?"beforerowselect":"beforecellselect",this.onBeforeRowSelect,this);if(!this.startGroup){this.startGroup=new Ext.XTemplate('
','
',this.groupTextTpl,"
",'
')}this.startGroup.compile();if(!this.endGroup){this.endGroup="
"}},findGroup:function(a){return Ext.fly(a).up(".x-grid-group",this.mainBody.dom)},getGroups:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},onAdd:function(d,a,b){if(this.canGroup()&&!this.ignoreAdd){var c=this.getScrollState();this.fireEvent("beforerowsinserted",d,b,b+(a.length-1));this.refresh();this.restoreScroll(c);this.fireEvent("rowsinserted",d,b,b+(a.length-1))}else{if(!this.canGroup()){Ext.grid.GroupingView.superclass.onAdd.apply(this,arguments)}}},onRemove:function(e,a,b,d){Ext.grid.GroupingView.superclass.onRemove.apply(this,arguments);var c=document.getElementById(a._groupId);if(c&&c.childNodes[1].childNodes.length<1){Ext.removeNode(c)}this.applyEmptyText()},refreshRow:function(a){if(this.ds.getCount()==1){this.refresh()}else{this.isUpdating=true;Ext.grid.GroupingView.superclass.refreshRow.apply(this,arguments);this.isUpdating=false}},beforeMenuShow:function(){var c,a=this.hmenu.items,b=this.cm.config[this.hdCtxIndex].groupable===false;if((c=a.get("groupBy"))){c.setDisabled(b)}if((c=a.get("showGroups"))){c.setDisabled(b);c.setChecked(this.enableGrouping,true)}},renderUI:function(){Ext.grid.GroupingView.superclass.renderUI.call(this);this.mainBody.on("mousedown",this.interceptMouse,this);if(this.enableGroupingMenu&&this.hmenu){this.hmenu.add("-",{itemId:"groupBy",text:this.groupByText,handler:this.onGroupByClick,scope:this,iconCls:"x-group-by-icon"});if(this.enableNoGroups){this.hmenu.add({itemId:"showGroups",text:this.showGroupsText,checked:true,checkHandler:this.onShowGroupsClick,scope:this})}this.hmenu.on("beforeshow",this.beforeMenuShow,this)}},processEvent:function(b,h){Ext.grid.GroupingView.superclass.processEvent.call(this,b,h);var g=h.getTarget(".x-grid-group-hd",this.mainBody);if(g){var d=this.getGroupField(),c=this.getPrefix(d),a=g.id.substring(c.length);a=a.substr(0,a.length-3);if(a){this.grid.fireEvent("group"+b,this.grid,d,a,h)}}},onGroupByClick:function(){this.enableGrouping=true;this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));this.grid.fireEvent("groupchange",this,this.grid.store.getGroupState());this.beforeMenuShow();this.refresh()},onShowGroupsClick:function(a,b){this.enableGrouping=b;if(b){this.onGroupByClick()}else{this.grid.store.clearGrouping();this.grid.fireEvent("groupchange",this,null)}},toggleRowIndex:function(c,a){if(!this.canGroup()){return}var b=this.getRow(c);if(b){this.toggleGroup(this.findGroup(b),a)}},toggleGroup:function(c,b){var a=Ext.get(c);b=Ext.isDefined(b)?b:a.hasClass("x-grid-group-collapsed");if(this.state[a.id]!==b){this.grid.stopEditing(true);this.state[a.id]=b;a[b?"removeClass":"addClass"]("x-grid-group-collapsed")}},toggleAllGroups:function(c){var b=this.getGroups();for(var d=0,a=b.length;d0){return setTimeout(d,c)}d();return 0}});Ext.applyIf(String,{format:function(b){var a=Ext.toArray(arguments,1);return b.replace(/\{(\d+)\}/g,function(c,d){return a[d]})}});Ext.applyIf(Array.prototype,{indexOf:function(b,c){var a=this.length;c=c||0;c+=(c<0)?a:0;for(;c
'),g=h.child("div",true);var e=g.offsetWidth;h.setStyle("overflow",(Ext.isWebKit||Ext.isGecko)?"auto":"scroll");var d=g.offsetWidth;h.remove();b=e-d+2}return b},combine:function(){var f=arguments,e=f.length,h=[];for(var g=0;gg?1:-1};Ext.each(d,function(g){f=e(f,g)==1?f:g});return f},mean:function(d){return d.length>0?Ext.sum(d)/d.length:undefined},sum:function(d){var e=0;Ext.each(d,function(f){e+=f});return e},partition:function(d,e){var f=[[],[]];Ext.each(d,function(h,j,g){f[(e&&e(h,j,g))||(!e&&h)?0:1].push(h)});return f},invoke:function(d,e){var g=[],f=Array.prototype.slice.call(arguments,2);Ext.each(d,function(h,j){if(h&&typeof h[e]=="function"){g.push(h[e].apply(h,f))}else{g.push(undefined)}});return g},pluck:function(d,f){var e=[];Ext.each(d,function(g){e.push(g[f])});return e},zip:function(){var m=Ext.partition(arguments,function(i){return typeof i!="function"}),h=m[0],l=m[1][0],d=Ext.max(Ext.pluck(h,"length")),g=[];for(var k=0;k0){for(var p=0;p0);if(!C){C=true;for(K=0;K=0){z=s.substr(0,y).toLowerCase();if(s.charAt(y+1)==" "){++y}A[z]=s.substr(y+1)}})}catch(x){}return{tId:q.tId,status:r?204:u.status,statusText:r?"No Content":u.statusText,getResponseHeader:function(s){return A[s.toLowerCase()]},getAllResponseHeaders:function(){return v},responseText:u.responseText,responseXML:u.responseXML,argument:w}}function n(q){if(q.tId){k.conn[q.tId]=null}q.conn=null;q=null}function f(v,w,r,q){if(!w){n(v);return}var t,s;try{if(v.conn.status!==undefined&&v.conn.status!=0){t=v.conn.status}else{t=13030}}catch(u){t=13030}if((t>=200&&t<300)||(Ext.isIE&&t==1223)){s=o(v,w.argument);if(w.success){if(!w.scope){w.success(s)}else{w.success.apply(w.scope,[s])}}}else{switch(t){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:s=e(v.tId,w.argument,(r?r:false),q);if(w.failure){if(!w.scope){w.failure(s)}else{w.failure.apply(w.scope,[s])}}break;default:s=o(v,w.argument);if(w.failure){if(!w.scope){w.failure(s)}else{w.failure.apply(w.scope,[s])}}}}n(v);s=null}function m(s,v){v=v||{};var q=s.conn,u=s.tId,r=k.poll,t=v.timeout||null;if(t){k.conn[u]=q;k.timeout[u]=setTimeout(function(){k.abort(s,v,true)},t)}r[u]=setInterval(function(){if(q&&q.readyState==4){clearInterval(r[u]);r[u]=null;if(t){clearTimeout(k.timeout[u]);k.timeout[u]=null}f(s,v)}},k.pollInterval)}function i(u,r,t,q){var s=l()||null;if(s){s.conn.open(u,r,true);if(k.useDefaultXhrHeader){j("X-Requested-With",k.defaultXhrHeader)}if(q&&k.useDefaultHeader&&(!k.headers||!k.headers[d])){j(d,k.defaultPostHeader)}if(k.defaultHeaders||k.headers){h(s)}m(s,t);s.conn.send(q||null)}return s}function l(){var r;try{if(r=p(k.transactionId)){k.transactionId++}}catch(q){}finally{return r}}function p(t){var q;try{q=new XMLHttpRequest()}catch(s){for(var r=0;r=d.left&&e.right<=d.right&&e.top>=d.top&&e.bottom<=d.bottom)},getArea:function(){var d=this;return((d.bottom-d.top)*(d.right-d.left))},intersect:function(i){var h=this,f=Math.max(h.top,i.top),g=Math.min(h.right,i.right),d=Math.min(h.bottom,i.bottom),e=Math.max(h.left,i.left);if(d>=f&&g>=e){return new Ext.lib.Region(f,g,d,e)}},union:function(i){var h=this,f=Math.min(h.top,i.top),g=Math.max(h.right,i.right),d=Math.max(h.bottom,i.bottom),e=Math.min(h.left,i.left);return new Ext.lib.Region(f,g,d,e)},constrainTo:function(e){var d=this;d.top=d.top.constrain(e.top,e.bottom);d.bottom=d.bottom.constrain(e.top,e.bottom);d.left=d.left.constrain(e.left,e.right);d.right=d.right.constrain(e.left,e.right);return d},adjust:function(f,e,d,h){var g=this;g.top+=f;g.left+=e;g.right+=h;g.bottom+=d;return g}};Ext.lib.Region.getRegion=function(g){var i=Ext.lib.Dom.getXY(g),f=i[1],h=i[0]+g.offsetWidth,d=i[1]+g.offsetHeight,e=i[0];return new Ext.lib.Region(f,h,d,e)};Ext.lib.Point=function(d,f){if(Ext.isArray(d)){f=d[1];d=d[0]}var e=this;e.x=e.right=e.left=e[0]=d;e.y=e.top=e.bottom=e[1]=f};Ext.lib.Point.prototype=new Ext.lib.Region();(function(){var g=Ext.lib,i=/width|height|opacity|padding/i,f=/^((width|height)|(top|left))$/,d=/width|height|top$|bottom$|left$|right$/i,h=/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,j=function(k){return typeof k!=="undefined"},e=function(){return new Date()};g.Anim={motion:function(n,l,o,p,k,m){return this.run(n,l,o,p,k,m,Ext.lib.Motion)},run:function(o,l,q,r,k,n,m){m=m||Ext.lib.AnimBase;if(typeof r=="string"){r=Ext.lib.Easing[r]}var p=new m(o,l,q,r);p.animateX(function(){if(Ext.isFunction(k)){k.call(n)}});return p}};g.AnimBase=function(l,k,m,n){if(l){this.init(l,k,m,n)}};g.AnimBase.prototype={doMethod:function(k,n,l){var m=this;return m.method(m.curFrame,n,l-n,m.totalFrames)},setAttr:function(k,m,l){if(i.test(k)&&m<0){m=0}Ext.fly(this.el,"_anim").setStyle(k,m+l)},getAttr:function(k){var m=Ext.fly(this.el),n=m.getStyle(k),l=f.exec(k)||[];if(n!=="auto"&&!h.test(n)){return parseFloat(n)}return(!!(l[2])||(m.getStyle("position")=="absolute"&&!!(l[3])))?m.dom["offset"+l[0].charAt(0).toUpperCase()+l[0].substr(1)]:0},getDefaultUnit:function(k){return d.test(k)?"px":""},animateX:function(n,k){var l=this,m=function(){l.onComplete.removeListener(m);if(Ext.isFunction(n)){n.call(k||l,l)}};l.onComplete.addListener(m,l);l.animate()},setRunAttr:function(p){var r=this,s=this.attributes[p],t=s.to,q=s.by,u=s.from,v=s.unit,l=(this.runAttrs[p]={}),m;if(!j(t)&&!j(q)){return false}var k=j(u)?u:r.getAttr(p);if(j(t)){m=t}else{if(j(q)){if(Ext.isArray(k)){m=[];for(var n=0,o=k.length;n0&&isFinite(w)){if(r.curFrame+w>=v){w=v-(u+1)}r.curFrame+=w}}};g.Bezier=new function(){this.getPosition=function(p,o){var r=p.length,m=[],q=1-o,l,k;for(l=0;l0&&!Ext.isArray(t[0])){t=[t]}else{}Ext.fly(q,"_anim").position();B.setXY(q,j(y)?y:B.getXY(q));p=x.getAttr("points");if(j(z)){r=k.call(x,z,p);for(s=0,u=t.length;s0){o=o.concat(t)}o[o.length]=r}else{n.setRunAttr.call(this,v)}}});var k=function(o,q){var p=g.Dom.getXY(this.el);return[o[0]-p[0]+q[0],o[1]-p[1]+q[1]]}})()})();(function(){var d=Math.abs,i=Math.PI,h=Math.asin,g=Math.pow,e=Math.sin,f=Ext.lib;Ext.apply(f.Easing,{easeBoth:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k+j:-m/2*((--k)*(k-2)-1)+j},easeInStrong:function(k,j,m,l){return m*(k/=l)*k*k*k+j},easeOutStrong:function(k,j,m,l){return -m*((k=k/l-1)*k*k*k-1)+j},easeBothStrong:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k*k*k+j:-m/2*((k-=2)*k*k*k-2)+j},elasticIn:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return -(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j},elasticOut:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return k*g(2,-10*l)*e((l*o-m)*(2*i)/n)+q+j},elasticBoth:function(l,j,q,o,k,n){if(l==0||(l/=o/2)==2){return l==0?j:j+q}n=n||(o*(0.3*1.5));var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return l<1?-0.5*(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j:k*g(2,-10*(l-=1))*e((l*o-m)*(2*i)/n)*0.5+q+j},backIn:function(k,j,n,m,l){l=l||1.70158;return n*(k/=m)*k*((l+1)*k-l)+j},backOut:function(k,j,n,m,l){if(!l){l=1.70158}return n*((k=k/m-1)*k*((l+1)*k+l)+1)+j},backBoth:function(k,j,n,m,l){l=l||1.70158;return((k/=m/2)<1)?n/2*(k*k*(((l*=(1.525))+1)*k-l))+j:n/2*((k-=2)*k*(((l*=(1.525))+1)*k+l)+2)+j},bounceIn:function(k,j,m,l){return m-f.Easing.bounceOut(l-k,0,m,l)+j},bounceOut:function(k,j,m,l){if((k/=l)<(1/2.75)){return m*(7.5625*k*k)+j}else{if(k<(2/2.75)){return m*(7.5625*(k-=(1.5/2.75))*k+0.75)+j}else{if(k<(2.5/2.75)){return m*(7.5625*(k-=(2.25/2.75))*k+0.9375)+j}}}return m*(7.5625*(k-=(2.625/2.75))*k+0.984375)+j},bounceBoth:function(k,j,m,l){return(k, MIT Style License. +/* +Script: Canvas.js + Contains the class. + +Dependencies: + MooTools, + Element, and its dependencies + +Author: + Olmo Maldonado, + +Credits: + Lightly based from Ralph Sommerer's work: + Moderately based from excanvas: + Great thanks to Inviz, , for his optimizing help. + +License: + MIT License, +*/ + +/* +Class: Canvas + Creates the element and extends the element with getContext if not defined. + +Arguments: + id - The ID of the canvas element + props - Optional properties for the canvas element, which also gets passed to the new Element + +Example: + > var cv = new Canvas('cv'); + > var ctx = cv.getContext('2d'); + > + > $(document.body).adopt(cv); +*/ +var MooCanvas = new Class({ + + initialize: function(id, props) { + var el; + if($type(id) == 'string') { + props = $merge({width: 300, height: 150}, props, {'id': id}); + el = new Element('canvas', props); + if(!el.getContext) { + if(!CanvasRenderingContext2D.cssFixed) { + document.createStyleSheet().cssText = + 'canvas{display:inline-block;overflow:hidden;text-align:left;cursor:default;}' + + 'v\\:*{behavior:url(#default#VML)}' + + 'o\\:*{behavior:url(#default#VML)}'; + CanvasRenderingContext2D.cssFixed = true; + } + + el.set({ + styles: { + width: props.width, + height: props.height, + display: 'inline-block', + overflow: 'hidden' + }, + + getContext: function() { + this.context = this.context || new CanvasRenderingContext2D(el); + return this.context; + } + }); + + } + } + + return el; + } + +}); + +/* +Class: CanvasRenderingContext2D + Context2D class with all the Context methods specified by the WHATWG, + +Arguments: + el - Element requesting the context2D +*/ +var CanvasRenderingContext2D = new Class({ + + initialize: function(el) { + this.parent = el; + this.fragment = document.createDocumentFragment(); + this.element = new Element('div', { + styles: { + width: el.clientWidth || el.width, + height: el.clientHeight || el.height, + overflow: 'hidden', + position: 'absolute' + } + }); + this.fragment.appendChild(this.element); + + this.m = [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + this.rot = 0; + this.state = []; + this.path = []; + this.delay = 30; + this.max = 10; + this.i = 0; + + // from excanvas, subpixel rendering. + this.Z = 10; + this.Z2 = this.Z / 2; + this.arcScaleX = 1; + this.arcScaleY = 1; + this.currentX = 0; + this.currentY = 0; + + + this.miterLimit = this.Z * 1; + }, + + lineWidth: 1, + strokeStyle: '#000', + fillStyle: '#fff', + globalAlpha: 1, + globalCompositeOperation: 'source-over', + lineCap: 'butt', + lineJoin: 'miter', + shadowBlur: 0, + shadowColor: '#000', + shadowOffsetX: 0, + shadowOffsetY: 0 + +}); + +/* +Script: Path.js + +Dependencies: + Canvas.js + +Author: + Olmo Maldonado, + +Credits: + Lightly based from Ralph Sommerer's work: + Moderately based from excanvas: + Great thanks to Inviz, , for his optimizing help. + +License: + MIT License, +*/ + +CanvasRenderingContext2D.implement({ + + /* + A path has a list of zero or more subpaths. + Each subpath consists of a list of one or more points, + connected by straight or curved lines, and a flag indicating whether + the subpath is closed or not. A closed subpath is one where the + last point of the subpath is connected to the first point of + the subpath by a straight line. Subpaths with fewer than two + points are ignored when painting the path. + */ + + /* + Property: + Empties the list of subpaths so that the context once again has zero + subpaths. + */ + beginPath: function() { + this.path = []; + this.moved = false; + }, + + /* + Property: + Creates a new subpath with the specified point as its first + (and only) point. + */ + moveTo: function(x, y) { + this.path.push('m', this.coord(x, y)); + this.currentX = x; + this.currentY = y; + this.moved = true; + }, + + /* + Property: + Does nothing if the context has no subpaths. + Otherwise, marks the last subpath as closed, create a new + subpath whose first point is the same as the previous + subpath's first point, and finally add this new subpath to the + path. + */ + closePath: function() { + this.path.push('x'); + }, + + /* + Property: + Method must do nothing if the context has no subpaths. Otherwise, + it must connect the last point in the subpath to the given point + (x, y) using a straight line, and must then add the given point + (x, y) to the subpath. + */ + lineTo: function(x, y) { + this.path.push((this.moved ? 'l' : ','), this.coord(x, y)); + this.currentX = x; + this.currentY = y; + this.moved = false; + }, + + /* + Property: + Method must do nothing if the context has no subpaths. Otherwise, + it must connect the last point in the subpath to the given point + (x, y) using a straight line, and must then add the given point + (x, y) to the subpath. + */ + quadraticCurveTo: function(cpx, cpy, x, y) { + var cx = 2 * cpx, + cy = 2 * cpy; + + this.bezierCurveTo( + (cx + this.currentX) / 3, + (cy + this.currentY) / 3, + (cx + x) / 3, + (cy + y) / 3, + x, + y + ); + }, + + /* + Property: + Method must do nothing if the context has no subpaths. Otherwise, + it must connect the last point in the subpath to the given point + (x, y) using a bezier curve with control points (cp1x, cp1y) and + (cp2x, cp2y). Then, it must add the point (x, y) to the subpath. + */ + bezierCurveTo: function(cp0x, cp0y, cp1x, cp1y, x, y) { + this.path.push(' c ', + this.coord(cp0x, cp0y), ",", + this.coord(cp1x, cp1y), ",", + this.coord(x, y) + ); + + this.currentX = x; + this.currentY = y; + }, + + /* + Property: + Method must do nothing if the context has no subpaths. If the context + does have a subpath, then the behaviour depends on the arguments and + the last point in the subpath. + + Let the point (x0, y0) be the last point in the subpath. Let The Arc + be the shortest arc given by circumference of the circle that has one + point tangent to the line defined by the points (x0, y0) and (x1, y1), + another point tangent to the line defined by the points (x1, y1) and + (x2, y2), and that has radius radius. The points at which this circle + touches these two lines are called the start and end tangent points + respectively. + + If the point (x2, y2) is on the line defined by the points (x0, y0) + and (x1, y1) then the method must do nothing, as no arc would satisfy + the above constraints. + + Otherwise, the method must connect the point (x0, y0) to the start + tangent point by a straight line, then connect the start tangent point + to the end tangent point by The Arc, and finally add the start and end + tangent points to the subpath. + + Negative or zero values for radius must cause the implementation to + raise an INDEX_SIZE_ERR exception. + */ + arcTo: function(x, y, w, h) { + + }, + + /* + Property: + Method draws an arc. If the context has any subpaths, then the method + must add a straight line from the last point in the subpath to the + start point of the arc. In any case, it must draw the arc between the + start point of the arc and the end point of the arc, and add the start + and end points of the arc to the subpath. The arc and its start and + end points are defined as follows: + + Consider a circle that has its origin at (x, y) and that has radius + radius. The points at startAngle and endAngle along the circle's + circumference, measured in radians clockwise from the positive x-axis, + are the start and end points respectively. The arc is the path along + the circumference of this circle from the start point to the end point, + going anti-clockwise if the anticlockwise argument is true, and + clockwise otherwise. + + Negative or zero values for radius must cause the implementation to + raise an INDEX_SIZE_ERR exception. + */ + arc: function(x, y, rad, a0, a1, cw) { + if(this.rot === 0) rad *= this.Z; + + var x0 = Math.cos(a0) * rad, + y0 = Math.sin(a0) * rad, + x1 = Math.cos(a1) * rad, + y1 = Math.sin(a1) * rad; + + if (this.rot !== 0) { + var da = Math.PI / 24; + this.lineTo(x0 + x, y0 + y); + if(cw) { + if (a0 < a1) a0 += 2 * Math.PI; + while(a0 - da > a1) this.lineTo(x + Math.cos(a0 -= da) * rad, y + Math.sin(a0) * rad); + } else { + if (a1 < a0) a1 += 2 * Math.PI; + while(a0 + da < a1) this.lineTo(x + Math.cos(a0 += da) * rad, y + Math.sin(a0) * rad); + } + this.lineTo(x1 + x, y1 + y); + return; + } + + if (x0 == x1 && !cw) x0 += 0.125; + + var c = this.getCoords(x, y); + this.path.push(cw ? 'at ' : 'wa ', + Math.round(c.x - this.arcScaleX * rad) + ',' + Math.round(c.y - this.arcScaleY * rad), ' ', + Math.round(c.x + this.arcScaleX * rad) + ',' + Math.round(c.y + this.arcScaleY * rad), ' ', + this.coord(x0 + x - this.Z2, y0 + y - this.Z2), ' ', + this.coord(x1 + x - this.Z2, y1 + y - this.Z2) + ); + }, + + /* + Property: + method must create a new subpath containing just the four points + (x, y), (x+w, y), (x+w, y+h), (x, y+h), with those four points + connected by straight lines, and must then mark the subpath as + closed. It must then create a new subpath with the point (x, y) + as the only point in the subpath. + + Negative values for w and h must cause the implementation to raise + an INDEX_SIZE_ERR exception. + */ + rect: function(x, y, w, h) { + this.moveTo(x, y); + this.lineTo(x + w, y); + this.lineTo(x + w, y + h); + this.lineTo(x, y + h); + this.closePath(); + }, + + /* + Property: + Method must fill each subpath of the current path in turn, using + fillStyle, and using the non-zero winding number rule. Open subpaths + must be implicitly closed when being filled (without affecting the + actual subpaths). + */ + fill: function() { + this.stroke(true); + }, + + + /* + Property: + Method must stroke each subpath of the current path in turn, using + the strokeStyle, lineWidth, lineJoin, and (if appropriate) miterLimit + attributes. + + Paths, when filled or stroked, must be painted without affecting the + current path, and must be subject to transformations, shadow effects, + global alpha, clipping paths, and global composition operators. + + The transformation is applied to the path when it is drawn, not when + the path is constructed. Thus, a single path can be constructed and + then drawn according to different transformations without recreating + the path. + */ + + stroke: function(fill) { + if(!this.path.length) return; + var a, color; + if (fill) { + a = [1000, '']; + } else { + color = this.processColor(this.strokeStyle); + a = [10, + '']; + } + this.element.insertAdjacentHTML('beforeEnd', + '' + + a[1] + + '' + ); + + this.parent.appendChild(this.fragment); + + if(fill && this.fillStyle.img) this.element.getLast().fill.alignshape = false; // not sure why this has to be called explicitly + + this.path = []; + }, + + /* + Property: + Method must create a new clipping path by calculating the intersection + of the current clipping path and the area described by the current path + (after applying the current transformation), using the non-zero winding + number rule. Open subpaths must be implicitly closed when computing the + clipping path, without affecting the actual subpaths. + + When the context is created, the initial clipping path is the rectangle + with the top left corner at (0,0) and the width and height of the + coordinate space. + */ + clip: function() { + + }, + + /* + Property: + Method must return true if the point given by the x and y coordinates + passed to the method, when treated as coordinates in the canvas' + coordinate space unaffected by the current transformation, is within + the area of the canvas that is inside the current path; and must + return false otherwise. + */ + isPointInPath: function(x, y) { + + }, + + processColor: function(col) { //path + var a = this.globalAlpha; + if (col.substr(0, 3) == 'rgb') { + if (col.charAt(3) == "a") { + a*= col.match(/([\d.]*)\)$/)[1]; + } + + col = col.rgbToHex(); + } + return { + color: col, + opacity: a + }; + }, + + /* + If a gradient has no stops defined, then the gradient must be treated as a + solid transparent black. Gradients are, naturally, only painted where the + stroking or filling effect requires that they be drawn. + */ + processColorObject: function(obj) { + var ret = '', col; + if(obj.addColorStop) { + ret += ((obj.r0) ? ( + 'type="gradientradial" ' + + 'focusposition="0.2, 0.2" ' + + 'focussize="0.2, 0.2" ' + ) : ( + 'type="gradient" ' + + 'focus="0" ' + + 'angle="' + (180 + (180 * obj.angle(obj.x0, obj.y0, obj.x1, obj.y1) / Math.PI)) + '" ' + )) + + 'color="' + obj.col0.color + '" ' + + 'opacity="' + obj.col0.opacity * 100 + '%" ' + + 'color2="' + obj.col1.color + '" ' + + 'o:opacity2="' + obj.col1.opacity * 100 + '%" ' + + 'colors="'; + if(obj.stops) { + for (var i = 0, l = obj.stops.length; i < l; i++) { + ret += Math.round(100 * obj.stops[i][0]) + '% ' + obj.stops[i][1]; + } + } + ret += + '" '; + } else if(obj.img) { //pattern + ret += + 'type="tile" ' + + 'src="' + obj.img.src + '" '; + } else { + col = this.processColor(obj); + ret += + 'color="' + col.color + '" ' + + 'opacity="' + col.opacity + '" '; + } + + return ret; + }, + + getCoords: function(x, y) { + var m = this.m; + return { + x: this.Z * (x * m[0][0] + y * m[1][0] + m[2][0]) - this.Z2, + y: this.Z * (x * m[0][1] + y * m[1][1] + m[2][1]) - this.Z2 + }; + }, + + coord: function(x, y) { + var m = this.m; + return [ + Math.round(this.Z * (x * m[0][0] + y * m[1][0] + m[2][0]) - this.Z2), ',', + Math.round(this.Z * (x * m[0][1] + y * m[1][1] + m[2][1]) - this.Z2) + ].join(''); + } +}); +/* +Script: Rects.js + +Dependencies: + Canvas.js, Path.js + +Author: + Olmo Maldonado, + +Credits: + Lightly based from Ralph Sommerer's work: + Moderately based from excanvas: + Great thanks to Inviz, , for his optimizing help. + +License: + MIT License, +*/ + +CanvasRenderingContext2D.implement({ + + /* + Property: clearRect + Clears the pixels in the specified rectangle. + If height or width are zero has no effect. + + If no arguments, clears all of the canvas + + Currently, clearRect clears all of the canvas. + */ + clearRect: function(x, y, w, h) { + //if((x <= 0) && (y <= 0) && ( x + w >= this.element.width) && (y + h >= this.element.height)){ + this.element.innerHTML = ''; + //} else { + // var f0 = this.fillStyle; + // this.fillStyle = '#fff'; + // this.fillRect(x, y, w, h); + // this.fillStyle = f0; + //} + }, + + /* + Property: fillRect + Paints the specified rectangle using fillStyle. + If height or width are zero, this method has no effect. + */ + fillRect: function(x, y, w, h) { + this.rect(x, y, w, h); + this.fill(); + }, + + /* + Draws a rectangular outline of the specified size. + If width or height are zero: ?? + */ + strokeRect: function(x, y, w, h) { + this.rect(x, y, w, h); + this.stroke(); + } + +}); +/* +Script: Transform.js + +Dependencies: + Canvas.js + +Author: + Olmo Maldonado, + +Credits: + Lightly based from Ralph Sommerer's work: + Moderately based from excanvas: + Great thanks to Inviz, , for his optimizing help. + +License: + MIT License, +*/ + +CanvasRenderingContext2D.implement({ + /* + The transformation matrix is applied to all drawing operations prior + to their being rendered. It is also applied when creating the clip region. + * The transformations must be performed in reverse order. For instance, + if a scale transformation that doubles the width is applied, followed + by a rotation transformation that rotates drawing operations by a + quarter turn, and a rectangle twice as wide as it is tall is then + drawn on the canvas, the actual result will be a square. + */ + + /* + Property: scale + Method must add the scaling transformation described by the arguments + to the transformation matrix. The x argument represents the scale factor + in the horizontal direction and the y argument represents the scale + factor in the vertical direction. The factors are multiples. + */ + scale: function(x, y) { + this.arcScaleX *= x; + this.arcScaleY *= y; + + this.matMult([ + [x, 0, 0], + [0, y, 0], + [0, 0, 1] + ]); + }, + + /* + Property: rotate + Method must add the rotation transformation described by the argument + to the transformation matrix. The angle argument represents a clockwise + rotation angle expressed in radians. + */ + rotate: function(ang) { + this.rot += ang; + var c = Math.cos(ang), + s = Math.sin(ang); + + this.matMult([ + [ c, s, 0], + [-s, c, 0], + [ 0, 0, 1] + ]); + }, + + /* + Property: translate + Method must add the translation transformation described by the arguments + to the transformation matrix. The x argument represents the translation + distance in the horizontal direction and the y argument represents the + translation distance in the vertical direction. The arguments are in + coordinate space units. + */ + translate: function(x, y) { + this.matMult([ + [1, 0, 0], + [0, 1, 0], + [x, y, 1] + ]); + }, + + /* + Property: transform + Method must multiply the current transformation matrix with the matrix described + by the inputs. + */ + transform: function(m11, m12, m21, m22, dx, dy) { + this.matMult([ + [m11, m21, dx], + [m12, m22, dy], + [ 0, 0, 1] + ]); + }, + + /* + Property: setTransform + Method must reset the current transform to the identity matrix, and then invoke + the transform method with the same arguments. + */ + setTransform: function(m11, m12, m21, m22, dx, dy) { + this.m = [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + + this.transform(m11, m12, m21, m22, dx, dy); + }, + + /* + Property: matMult + Method to multiply 3x3 matrice. Currently takes input and multiplies against + the transform matrix and saves the result to the transform matrix. + + This is an optimized multiplication method. Will only multiply if the input + value is not zero. Thus, minimizing multiplications and additions. + */ + matMult: function(b) { + var m = this.m, + o = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ]; + + for(var i = 0; i < 3; i++) { + if(b[0][i] !== 0) this.sum(o[0], this.mult(b[0][i], m[i])); + if(b[1][i] !== 0) this.sum(o[1], this.mult(b[1][i], m[i])); + if(b[2][i] !== 0) this.sum(o[2], this.mult(b[2][i], m[i])); + } + + this.m = [o[0], o[1], o[2]]; + }, + + mult: function(x, y) { + return [x * y[0], x * y[1], x * y[2]]; + }, + + sum: function(o, v) { + o[0] += v[0]; + o[1] += v[1]; + o[2] += v[2]; + } +}); +/* +Script: Image.js + +Dependencies: + Canvas.js + +Author: + Olmo Maldonado, + +Credits: + Lightly based from Ralph Sommerer's work: + Moderately based from excanvas: + Great thanks to Inviz, , for his optimizing help. + +License: + MIT License, +*/ + +CanvasRenderingContext2D.implement({ + /* + Property: drawImage + This method is overloaded with three variants: drawImage(image, dx, dy), + drawImage(image, dx, dy, dw, dh), and drawImage(image, sx, sy, sw, sh, + dx, dy, dw, dh). (Actually it is overloaded with six; each of those three + can take either an HTMLImageElement or an HTMLCanvasElement for the image + argument.) If not specified, the dw and dh arguments default to the values + of sw and sh, interpreted such that one CSS pixel in the image is treated + as one unit in the canvas coordinate space. If the sx, sy, sw, and sh + arguments are omitted, they default to 0, 0, the image's intrinsic width + in image pixels, and the image's intrinsic height in image pixels, + respectively. + + If the image is of the wrong type, the implementation must raise a + TYPE_MISMATCH_ERR exception. If one of the sy, sw, sw, and sh arguments + is outside the size of the image, or if one of the dw and dh arguments + is negative, the implementation must raise an INDEX_SIZE_ERR exception. + + The specified region of the image specified by the source rectangle + (sx, sy, sw, sh) must be painted on the region of the canvas specified + by the destination rectangle (dx, dy, dw, dh). + + Images are painted without affecting the current path, and are subject to + transformations, shadow effects, global alpha, clipping paths, and global + composition operators. + */ + drawImage: function (image, var_args) { + var args = arguments, + length = args.length, + off = (length == 9) ? 4 : 0; + + if(!((length + '').test(/3|5|9/))) throw 'Wrong number of arguments'; + + var w0 = image.runtimeStyle.width, + h0 = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + var w = image.width, + h = image.height; + image.runtimeStyle.width = w0; + image.runtimeStyle.height = h0; + + var sx = 0, + sy = 0, + sw = w, + sh = h, + dx = args[1 + off], + dy = args[2 + off], + dw = args[3 + off] || w, + dh = args[4 + off] || h; + + if (length == 9) { + sx = args[1]; + sy = args[2]; + sw = args[3]; + sh = args[4]; + } + + var d = this.getCoords(dx, dy), + vmlStr = + '' + ); + + this.parent.appendChild(this.fragment); + }, + + drawImageFromRect: Function.empty, + + /* + Property: getImageData + Method must return an ImageData object representing the underlying + pixel data for the area of the canvas denoted by the rectangle which + has one corner at the (sx, sy) coordinate, and that has width sw and + height sh. Pixels outside the canvas must be returned as transparent + black. + */ + getImageData: function(sx, sy, sw, sh) { + + }, + + /* + Property: putImageData + Method must take the given ImageData structure, and draw it at the + specified location dx,dy in the canvas coordinate space, mapping each + pixel represented by the ImageData structure into one device pixel. + */ + putImageData: function(image, dx, dy) { + + }, + + getCoords: function(x, y) { + var m = this.m; + return { + x: this.Z * (x * m[0][0] + y * m[1][0] + m[2][0]) - this.Z2, + y: this.Z * (x * m[0][1] + y * m[1][1] + m[2][1]) - this.Z2 + }; + } + +}); diff --git a/gulliver/js/ext/mootools.js b/gulliver/js/ext/mootools.js new file mode 100755 index 000000000..348113a30 --- /dev/null +++ b/gulliver/js/ext/mootools.js @@ -0,0 +1,2409 @@ +/* +Script: Core.js + Mootools - My Object Oriented javascript. + +License: + MIT-style license. + +MooTools Copyright: + copyright (c) 2007 Valerio Proietti, + +MooTools Credits: + - Class is slightly based on Base.js (c) 2006 Dean Edwards, License + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license + - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. +*/ + +var MooTools = { + version: '1.11' +}; + +/* Section: Core Functions */ + +/* +Function: $defined + Returns true if the passed in value/object is defined, that means is not null or undefined. + +Arguments: + obj - object to inspect +*/ + +function $defined(obj){ + return (obj != undefined); +}; + +/* +Function: $type + Returns the type of object that matches the element passed in. + +Arguments: + obj - the object to inspect. + +Example: + >var myString = 'hello'; + >$type(myString); //returns "string" + +Returns: + 'element' - if obj is a DOM element node + 'textnode' - if obj is a DOM text node + 'whitespace' - if obj is a DOM whitespace node + 'arguments' - if obj is an arguments object + 'object' - if obj is an object + 'string' - if obj is a string + 'number' - if obj is a number + 'boolean' - if obj is a boolean + 'function' - if obj is a function + 'regexp' - if obj is a regular expression + 'class' - if obj is a Class. (created with new Class, or the extend of another class). + 'collection' - if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc. + false - (boolean) if the object is not defined or none of the above. +*/ + +function $type(obj){ + if (!$defined(obj)) return false; + if (obj.htmlElement) return 'element'; + var type = typeof obj; + if (type == 'object' && obj.nodeName){ + switch(obj.nodeType){ + case 1: return 'element'; + case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; + } + } + if (type == 'object' || type == 'function'){ + switch(obj.constructor){ + case Array: return 'array'; + case RegExp: return 'regexp'; + case Class: return 'class'; + } + if (typeof obj.length == 'number'){ + if (obj.item) return 'collection'; + if (obj.callee) return 'arguments'; + } + } + return type; +}; + +/* +Function: $merge + merges a number of objects recursively without referencing them or their sub-objects. + +Arguments: + any number of objects. + +Example: + >var mergedObj = $merge(obj1, obj2, obj3); + >//obj1, obj2, and obj3 are unaltered +*/ + +function $merge(){ + var mix = {}; + for (var i = 0; i < arguments.length; i++){ + for (var property in arguments[i]){ + var ap = arguments[i][property]; + var mp = mix[property]; + if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap); + else mix[property] = ap; + } + } + return mix; +}; + +/* +Function: $extend + Copies all the properties from the second passed object to the first passed Object. + If you do myWhatever.extend = $extend the first parameter will become myWhatever, and your extend function will only need one parameter. + +Example: + (start code) + var firstOb = { + 'name': 'John', + 'lastName': 'Doe' + }; + var secondOb = { + 'age': '20', + 'sex': 'male', + 'lastName': 'Dorian' + }; + $extend(firstOb, secondOb); + //firstOb will become: + { + 'name': 'John', + 'lastName': 'Dorian', + 'age': '20', + 'sex': 'male' + }; + (end) + +Returns: + The first object, extended. +*/ + +var $extend = function(){ + var args = arguments; + if (!args[1]) args = [this, args[0]]; + for (var property in args[1]) args[0][property] = args[1][property]; + return args[0]; +}; + +/* +Function: $native + Will add a .extend method to the objects passed as a parameter, but the property passed in will be copied to the object's prototype only if non previously existent. + Its handy if you dont want the .extend method of an object to overwrite existing methods. + Used automatically in MooTools to implement Array/String/Function/Number methods to browser that dont support them whitout manual checking. + +Arguments: + a number of classes/native javascript objects + +*/ + +var $native = function(){ + for (var i = 0, l = arguments.length; i < l; i++){ + arguments[i].extend = function(props){ + for (var prop in props){ + if (!this.prototype[prop]) this.prototype[prop] = props[prop]; + if (!this[prop]) this[prop] = $native.generic(prop); + } + }; + } +}; + +$native.generic = function(prop){ + return function(bind){ + return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1)); + }; +}; + +$native(Function, Array, String, Number); + +/* +Function: $chk + Returns true if the passed in value/object exists or is 0, otherwise returns false. + Useful to accept zeroes. + +Arguments: + obj - object to inspect +*/ + +function $chk(obj){ + return !!(obj || obj === 0); +}; + +/* +Function: $pick + Returns the first object if defined, otherwise returns the second. + +Arguments: + obj - object to test + picked - the default to return + +Example: + (start code) + function say(msg){ + alert($pick(msg, 'no meessage supplied')); + } + (end) +*/ + +function $pick(obj, picked){ + return $defined(obj) ? obj : picked; +}; + +/* +Function: $random + Returns a random integer number between the two passed in values. + +Arguments: + min - integer, the minimum value (inclusive). + max - integer, the maximum value (inclusive). + +Returns: + a random integer between min and max. +*/ + +function $random(min, max){ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +/* +Function: $time + Returns the current timestamp + +Returns: + a timestamp integer. +*/ + +function $time(){ + return new Date().getTime(); +}; + +/* +Function: $clear + clears a timeout or an Interval. + +Returns: + null + +Arguments: + timer - the setInterval or setTimeout to clear. + +Example: + >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. + >myTimer = $clear(myTimer); //nevermind + +See also: + , +*/ + +function $clear(timer){ + clearTimeout(timer); + clearInterval(timer); + return null; +}; + +/* +Class: Abstract + Abstract class, to be used as singleton. Will add .extend to any object + +Arguments: + an object + +Returns: + the object with an .extend property, equivalent to <$extend>. +*/ + +var Abstract = function(obj){ + obj = obj || {}; + obj.extend = $extend; + return obj; +}; + +//window, document + +var Window = new Abstract(window); +var Document = new Abstract(document); +document.head = document.getElementsByTagName('head')[0]; + +/* +Class: window + Some properties are attached to the window object by the browser detection. + +Note: + browser detection is entirely object-based. We dont sniff. + +Properties: + window.ie - will be set to true if the current browser is internet explorer (any). + window.ie6 - will be set to true if the current browser is internet explorer 6. + window.ie7 - will be set to true if the current browser is internet explorer 7. + window.gecko - will be set to true if the current browser is Mozilla/Gecko. + window.webkit - will be set to true if the current browser is Safari/Konqueror. + window.webkit419 - will be set to true if the current browser is Safari2 / webkit till version 419. + window.webkit420 - will be set to true if the current browser is Safari3 (Webkit SVN Build) / webkit over version 419. + window.opera - is set to true by opera itself. +*/ + +window.xpath = !!(document.evaluate); +if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; +else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true; +else if (document.getBoxObjectFor != null) window.gecko = true; + +/*compatibility*/ + +window.khtml = window.webkit; + +Object.extend = $extend; + +/*end compatibility*/ + +//htmlelement + +if (typeof HTMLElement == 'undefined'){ + var HTMLElement = function(){}; + if (window.webkit) document.createElement("iframe"); //fixes safari + HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {}; +} +HTMLElement.prototype.htmlElement = function(){}; + +//enables background image cache for internet explorer 6 + +if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){}; + +/* +Script: Class.js + Contains the Class Function, aims to ease the creation of reusable Classes. + +License: + MIT-style license. +*/ + +/* +Class: Class + The base class object of the framework. + Creates a new class, its initialize method will fire upon class instantiation. + Initialize wont fire on instantiation when you pass *null*. + +Arguments: + properties - the collection of properties that apply to the class. + +Example: + (start code) + var Cat = new Class({ + initialize: function(name){ + this.name = name; + } + }); + var myCat = new Cat('Micia'); + alert(myCat.name); //alerts 'Micia' + (end) +*/ + +var Class = function(properties){ + var klass = function(){ + return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this; + }; + $extend(klass, this); + klass.prototype = properties; + klass.constructor = Class; + return klass; +}; + +/* +Property: empty + Returns an empty function +*/ + +Class.empty = function(){}; + +Class.prototype = { + + /* + Property: extend + Returns the copy of the Class extended with the passed in properties. + + Arguments: + properties - the properties to add to the base class in this new Class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + var Cat = Animal.extend({ + initialize: function(name, age){ + this.parent(age); //will call the previous initialize; + this.name = name; + } + }); + var myCat = new Cat('Micia', 20); + alert(myCat.name); //alerts 'Micia' + alert(myCat.age); //alerts 20 + (end) + */ + + extend: function(properties){ + var proto = new this(null); + for (var property in properties){ + var pp = proto[property]; + proto[property] = Class.Merge(pp, properties[property]); + } + return new Class(proto); + }, + + /* + Property: implement + Implements the passed in properties to the base Class prototypes, altering the base class, unlike . + + Arguments: + properties - the properties to add to the base class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + Animal.implement({ + setName: function(name){ + this.name = name + } + }); + var myAnimal = new Animal(20); + myAnimal.setName('Micia'); + alert(myAnimal.name); //alerts 'Micia' + (end) + */ + + implement: function(){ + for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]); + } + +}; + +//internal + +Class.Merge = function(previous, current){ + if (previous && previous != current){ + var type = $type(current); + if (type != $type(previous)) return current; + switch(type){ + case 'function': + var merged = function(){ + this.parent = arguments.callee.parent; + return current.apply(this, arguments); + }; + merged.parent = previous; + return merged; + case 'object': return $merge(previous, current); + } + } + return current; +}; + +/* +Script: Array.js + Contains Array prototypes, <$A>, <$each> + +License: + MIT-style license. +*/ + +/* +Class: Array + A collection of The Array Object prototype methods. +*/ + +//custom methods + +Array.extend({ + + /* + Property: forEach + Iterates through an array; This method is only available for browsers without native *forEach* support. + For more info see + + *forEach* executes the provided function (callback) once for each element present in the array. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >['apple','banana','lemon'].each(function(item, index){ + > alert(index + " = " + item); //alerts "0 = apple" etc. + >}, bindObj); //optional second arg for binding, not used here + */ + + forEach: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this); + }, + + /* + Property: filter + This method is provided only for browsers without native *filter* support. + For more info see + + *filter* calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var biggerThanTwenty = [10,3,25,100].filter(function(item, index){ + > return item > 20; + >}); + >//biggerThanTwenty = [25,100] + */ + + filter: function(fn, bind){ + var results = []; + for (var i = 0, j = this.length; i < j; i++){ + if (fn.call(bind, this[i], i, this)) results.push(this[i]); + } + return results; + }, + + /* + Property: map + This method is provided only for browsers without native *map* support. + For more info see + + *map* calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var timesTwo = [1,2,3].map(function(item, index){ + > return item*2; + >}); + >//timesTwo = [2,4,6]; + */ + + map: function(fn, bind){ + var results = []; + for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this); + return results; + }, + + /* + Property: every + This method is provided only for browsers without native *every* support. + For more info see + + *every* executes the provided callback function once for each element present in the array until it finds one where callback returns a false value. If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var areAllBigEnough = [10,4,25,100].every(function(item, index){ + > return item > 20; + >}); + >//areAllBigEnough = false + */ + + every: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++){ + if (!fn.call(bind, this[i], i, this)) return false; + } + return true; + }, + + /* + Property: some + This method is provided only for browsers without native *some* support. + For more info see + + *some* executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var isAnyBigEnough = [10,4,25,100].some(function(item, index){ + > return item > 20; + >}); + >//isAnyBigEnough = true + */ + + some: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++){ + if (fn.call(bind, this[i], i, this)) return true; + } + return false; + }, + + /* + Property: indexOf + This method is provided only for browsers without native *indexOf* support. + For more info see + + *indexOf* compares a search element to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator). + + Arguments: + item - any type of object; element to locate in the array + from - integer; optional; the index of the array at which to begin the search (defaults to 0) + + Example: + >['apple','lemon','banana'].indexOf('lemon'); //returns 1 + >['apple','lemon'].indexOf('banana'); //returns -1 + */ + + indexOf: function(item, from){ + var len = this.length; + for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ + if (this[i] === item) return i; + } + return -1; + }, + + /* + Property: each + Same as . + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - optional, the object that the "this" of the function will refer to. + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.each(function(animal){ + > document.write(animal) + >}); + */ + + /* + Property: copy + returns a copy of the array. + + Returns: + a new array which is a copy of the current one. + + Arguments: + start - integer; optional; the index where to start the copy, default is 0. If negative, it is taken as the offset from the end of the array. + length - integer; optional; the number of elements to copy. By default, copies all elements from start to the end of the array. + + Example: + >var letters = ["a","b","c"]; + >var copy = letters.copy(); // ["a","b","c"] (new instance) + */ + + copy: function(start, length){ + start = start || 0; + if (start < 0) start = this.length + start; + length = length || (this.length - start); + var newArray = []; + for (var i = 0; i < length; i++) newArray[i] = this[start++]; + return newArray; + }, + + /* + Property: remove + Removes all occurrences of an item from the array. + + Arguments: + item - the item to remove + + Returns: + the Array with all occurrences of the item removed. + + Example: + >["1","2","3","2"].remove("2") // ["1","3"]; + */ + + remove: function(item){ + var i = 0; + var len = this.length; + while (i < len){ + if (this[i] === item){ + this.splice(i, 1); + len--; + } else { + i++; + } + } + return this; + }, + + /* + Property: contains + Tests an array for the presence of an item. + + Arguments: + item - the item to search for in the array. + from - integer; optional; the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array. + + Returns: + true - the item was found + false - it wasn't + + Example: + >["a","b","c"].contains("a"); // true + >["a","b","c"].contains("d"); // false + */ + + contains: function(item, from){ + return this.indexOf(item, from) != -1; + }, + + /* + Property: associate + Creates an object with key-value pairs based on the array of keywords passed in + and the current content of the array. + + Arguments: + keys - the array of keywords. + + Example: + (start code) + var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; + var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; + var Speeches = Animals.associate(Speech); + //Speeches['Miao'] is now Cat. + //Speeches['Bau'] is now Dog. + //... + (end) + */ + + associate: function(keys){ + var obj = {}, length = Math.min(this.length, keys.length); + for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; + return obj; + }, + + /* + Property: extend + Extends an array with another one. + + Arguments: + array - the array to extend ours with + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.extend(['Lizard']); + >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; + */ + + extend: function(array){ + for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); + return this; + }, + + /* + Property: merge + merges an array in another array, without duplicates. (case- and type-sensitive) + + Arguments: + array - the array to merge from. + + Example: + >['Cat','Dog'].merge(['Dog','Coala']); //returns ['Cat','Dog','Coala'] + */ + + merge: function(array){ + for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); + return this; + }, + + /* + Property: include + includes the passed in element in the array, only if its not already present. (case- and type-sensitive) + + Arguments: + item - item to add to the array (if not present) + + Example: + >['Cat','Dog'].include('Dog'); //returns ['Cat','Dog'] + >['Cat','Dog'].include('Coala'); //returns ['Cat','Dog','Coala'] + */ + + include: function(item){ + if (!this.contains(item)) this.push(item); + return this; + }, + + /* + Property: getRandom + returns a random item in the Array + */ + + getRandom: function(){ + return this[$random(0, this.length - 1)] || null; + }, + + /* + Property: getLast + returns the last item in the Array + */ + + getLast: function(){ + return this[this.length - 1] || null; + } + +}); + +//copies + +Array.prototype.each = Array.prototype.forEach; +Array.each = Array.forEach; + +/* Section: Utility Functions */ + +/* +Function: $A() + Same as , but as function. + Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. + +Example: + (start code) + function myFunction(){ + $A(arguments).each(argument, function(){ + alert(argument); + }); + }; + //the above will alert all the arguments passed to the function myFunction. + (end) +*/ + +function $A(array){ + return Array.copy(array); +}; + +/* +Function: $each + Use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, arguments of a function, or an object. + +Arguments: + iterable - an iterable element or an objct. + function - function to apply to the iterable. + bind - optional, the 'this' of the function will refer to this object. + +Function argument: + The function argument will be passed the following arguments. + + item - the current item in the iterator being procesed + index - integer; the index of the item, or key in case of an object. + +Examples: + (start code) + $each(['Sun','Mon','Tue'], function(day, index){ + alert('name:' + day + ', index: ' + index); + }); + //alerts "name: Sun, index: 0", "name: Mon, index: 1", etc. + //over an object + $each({first: "Sunday", second: "Monday", third: "Tuesday"}, function(value, key){ + alert("the " + key + " day of the week is " + value); + }); + //alerts "the first day of the week is Sunday", + //"the second day of the week is Monday", etc. + (end) +*/ + +function $each(iterable, fn, bind){ + if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){ + Array.forEach(iterable, fn, bind); + } else { + for (var name in iterable) fn.call(bind || iterable, iterable[name], name); + } +}; + +/*compatibility*/ + +Array.prototype.test = Array.prototype.contains; + +/*end compatibility*/ + +/* +Script: String.js + Contains String prototypes. + +License: + MIT-style license. +*/ + +/* +Class: String + A collection of The String Object prototype methods. +*/ + +String.extend({ + + /* + Property: test + Tests a string with a regular expression. + + Arguments: + regex - a string or regular expression object, the regular expression you want to match the string with + params - optional, if first parameter is a string, any parameters you want to pass to the regex ('g' has no effect) + + Returns: + true if a match for the regular expression is found in the string, false if not. + See + + Example: + >"I like cookies".test("cookie"); // returns true + >"I like cookies".test("COOKIE", "i") // ignore case, returns true + >"I like cookies".test("cake"); // returns false + */ + + test: function(regex, params){ + return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this); + }, + + /* + Property: toInt + parses a string to an integer. + + Returns: + either an int or "NaN" if the string is not a number. + + Example: + >var value = "10px".toInt(); // value is 10 + */ + + toInt: function(){ + return parseInt(this, 10); + }, + + /* + Property: toFloat + parses a string to an float. + + Returns: + either a float or "NaN" if the string is not a number. + + Example: + >var value = "10.848".toFloat(); // value is 10.848 + */ + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: camelCase + Converts a hiphenated string to a camelcase string. + + Example: + >"I-like-cookies".camelCase(); //"ILikeCookies" + + Returns: + the camel cased string + */ + + camelCase: function(){ + return this.replace(/-\D/g, function(match){ + return match.charAt(1).toUpperCase(); + }); + }, + + /* + Property: hyphenate + Converts a camelCased string to a hyphen-ated string. + + Example: + >"ILikeCookies".hyphenate(); //"I-like-cookies" + */ + + hyphenate: function(){ + return this.replace(/\w[A-Z]/g, function(match){ + return (match.charAt(0) + '-' + match.charAt(1).toLowerCase()); + }); + }, + + /* + Property: capitalize + Converts the first letter in each word of a string to Uppercase. + + Example: + >"i like cookies".capitalize(); //"I Like Cookies" + + Returns: + the capitalized string + */ + + capitalize: function(){ + return this.replace(/\b[a-z]/g, function(match){ + return match.toUpperCase(); + }); + }, + + /* + Property: trim + Trims the leading and trailing spaces off a string. + + Example: + >" i like cookies ".trim() //"i like cookies" + + Returns: + the trimmed string + */ + + trim: function(){ + return this.replace(/^\s+|\s+$/g, ''); + }, + + /* + Property: clean + trims () a string AND removes all the double spaces in a string. + + Returns: + the cleaned string + + Example: + >" i like cookies \n\n".clean() //"i like cookies" + */ + + clean: function(){ + return this.replace(/\s{2,}/g, ' ').trim(); + }, + + /* + Property: rgbToHex + Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255,255,255)" or "rgba(255,255,255,1)"; + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['FF','33','00'] as output instead of "#FF3300" + + Returns: + hex string or array. returns "transparent" if the output is set as string and the fourth value of rgba in input string is 0. + + Example: + >"rgb(17,34,51)".rgbToHex(); //"#112233" + >"rgba(17,34,51,0)".rgbToHex(); //"transparent" + >"rgb(17,34,51)".rgbToHex(true); //['11','22','33'] + */ + + rgbToHex: function(array){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? rgb.rgbToHex(array) : false; + }, + + /* + Property: hexToRgb + Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); + + Arguments: + array - boolean value, defaults to false. Use true if you want the array [255,255,255] as output instead of "rgb(255,255,255)"; + + Returns: + rgb string or array. + + Example: + >"#112233".hexToRgb(); //"rgb(17,34,51)" + >"#112233".hexToRgb(true); //[17,34,51] + */ + + hexToRgb: function(array){ + var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); + return (hex) ? hex.slice(1).hexToRgb(array) : false; + }, + + /* + Property: contains + checks if the passed in string is contained in the String. also accepts an optional second parameter, to check if the string is contained in a list of separated values. + + Example: + >'a b c'.contains('c', ' '); //true + >'a bc'.contains('bc'); //true + >'a bc'.contains('b', ' '); //false + */ + + contains: function(string, s){ + return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1; + }, + + /* + Property: escapeRegExp + Returns string with escaped regular expression characters + + Example: + >var search = 'animals.sheeps[1]'.escapeRegExp(); // search is now 'animals\.sheeps\[1\]' + + Returns: + Escaped string + */ + + escapeRegExp: function(){ + return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); + } + +}); + +Array.extend({ + + /* + Property: rgbToHex + see , but as an array method. + */ + + rgbToHex: function(array){ + if (this.length < 3) return false; + if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (this[i] - 0).toString(16); + hex.push((bit.length == 1) ? '0' + bit : bit); + } + return array ? hex : '#' + hex.join(''); + }, + + /* + Property: hexToRgb + same as , but as an array method. + */ + + hexToRgb: function(array){ + if (this.length != 3) return false; + var rgb = []; + for (var i = 0; i < 3; i++){ + rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16)); + } + return array ? rgb : 'rgb(' + rgb.join(',') + ')'; + } + +}); + +/* +Script: Function.js + Contains Function prototypes and utility functions . + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Function + A collection of The Function Object prototype methods. +*/ + +Function.extend({ + + /* + Property: create + Main function to create closures. + + Returns: + a function. + + Arguments: + options - An Options object. + + Options: + bind - The object that the "this" of the function will refer to. Default is the current function. + event - If set to true, the function will act as an event listener and receive an event as first argument. + If set to a class name, the function will receive a new instance of this class (with the event passed as argument's constructor) as first argument. + Default is false. + arguments - A single argument or array of arguments that will be passed to the function when called. + + If both the event and arguments options are set, the event is passed as first argument and the arguments array will follow. + + Default is no custom arguments, the function will receive the standard arguments when called. + + delay - Numeric value: if set, the returned function will delay the actual execution by this amount of milliseconds and return a timer handle when called. + Default is no delay. + periodical - Numeric value: if set, the returned function will periodically perform the actual execution with this specified interval and return a timer handle when called. + Default is no periodical execution. + attempt - If set to true, the returned function will try to execute and return either the results or false on error. Default is false. + */ + + create: function(options){ + var fn = this; + options = $merge({ + 'bind': fn, + 'event': false, + 'arguments': null, + 'delay': false, + 'periodical': false, + 'attempt': false + }, options); + if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments]; + return function(event){ + var args; + if (options.event){ + event = event || window.event; + args = [(options.event === true) ? event : new options.event(event)]; + if (options.arguments) args.extend(options.arguments); + } + else args = options.arguments || arguments; + var returns = function(){ + return fn.apply($pick(options.bind, fn), args); + }; + if (options.delay) return setTimeout(returns, options.delay); + if (options.periodical) return setInterval(returns, options.periodical); + if (options.attempt) try {return returns();} catch(err){return false;}; + return returns(); + }; + }, + + /* + Property: pass + Shortcut to create closures with arguments and bind. + + Returns: + a function. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.pass([arg1, arg2], myElement); + */ + + pass: function(args, bind){ + return this.create({'arguments': args, 'bind': bind}); + }, + + /* + Property: attempt + Tries to execute the function, returns either the result of the function or false on error. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.attempt([arg1, arg2], myElement); + */ + + attempt: function(args, bind){ + return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); + }, + + /* + Property: bind + method to easily create closures with "this" altered. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function. + + Example: + >function myFunction(){ + > this.setStyle('color', 'red'); + > // note that 'this' here refers to myFunction, not an element + > // we'll need to bind this function to the element we want to alter + >}; + >var myBoundFunction = myFunction.bind(myElement); + >myBoundFunction(); // this will make the element myElement red. + */ + + bind: function(bind, args){ + return this.create({'bind': bind, 'arguments': args}); + }, + + /* + Property: bindAsEventListener + cross browser method to pass event firer + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindAsEventListener(myElement); + */ + + bindAsEventListener: function(bind, args){ + return this.create({'bind': bind, 'event': true, 'arguments': args}); + }, + + /* + Property: delay + Delays the execution of a function by a specified duration. + + Arguments: + delay - the duration to wait in milliseconds. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Example: + >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it + >(function(){alert('one second later...')}).delay(1000); //wait a second and alert + */ + + delay: function(delay, bind, args){ + return this.create({'delay': delay, 'bind': bind, 'arguments': args})(); + }, + + /* + Property: periodical + Executes a function in the specified intervals of time + + Arguments: + interval - the duration of the intervals between executions. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + */ + + periodical: function(interval, bind, args){ + return this.create({'periodical': interval, 'bind': bind, 'arguments': args})(); + } + +}); + +/* +Script: Number.js + Contains the Number prototypes. + +License: + MIT-style license. +*/ + +/* +Class: Number + A collection of The Number Object prototype methods. +*/ + +Number.extend({ + + /* + Property: toInt + Returns this number; useful because toInt must work on both Strings and Numbers. + */ + + toInt: function(){ + return parseInt(this); + }, + + /* + Property: toFloat + Returns this number as a float; useful because toFloat must work on both Strings and Numbers. + */ + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: limit + Limits the number. + + Arguments: + min - number, minimum value + max - number, maximum value + + Returns: + the number in the given limits. + + Example: + >(12).limit(2, 6.5) // returns 6.5 + >(-4).limit(2, 6.5) // returns 2 + >(4.3).limit(2, 6.5) // returns 4.3 + */ + + limit: function(min, max){ + return Math.min(max, Math.max(min, this)); + }, + + /* + Property: round + Returns the number rounded to specified precision. + + Arguments: + precision - integer, number of digits after the decimal point. Can also be negative or zero (default). + + Example: + >12.45.round() // returns 12 + >12.45.round(1) // returns 12.5 + >12.45.round(-1) // returns 10 + + Returns: + The rounded number. + */ + + round: function(precision){ + precision = Math.pow(10, precision || 0); + return Math.round(this * precision) / precision; + }, + + /* + Property: times + Executes a passed in function the specified number of times + + Arguments: + function - the function to be executed on each iteration of the loop + + Example: + >(4).times(alert); + */ + + times: function(fn){ + for (var i = 0; i < this; i++) fn(i); + } + +}); + +/* +Script: Element.js + Contains useful Element prototypes, to be used with the dollar function <$>. + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +var Element = new Class({ + + /* + Property: initialize + Creates a new element of the type passed in. + + Arguments: + el - string; the tag name for the element you wish to create. you can also pass in an element reference, in which case it will be extended. + props - object; the properties you want to add to your element. + Accepts the same keys as , but also allows events and styles + + Props: + the key styles will be used as setStyles, the key events will be used as addEvents. any other key is used as setProperty. + + Example: + (start code) + new Element('a', { + 'styles': { + 'display': 'block', + 'border': '1px solid black' + }, + 'events': { + 'click': function(){ + //aaa + }, + 'mousedown': function(){ + //aaa + } + }, + 'class': 'myClassSuperClass', + 'href': 'http://mad4milk.net' + }); + + (end) + */ + + initialize: function(el, props){ + if ($type(el) == 'string'){ + if (window.ie && props && (props.name || props.type)){ + var name = (props.name) ? ' name="' + props.name + '"' : ''; + var type = (props.type) ? ' type="' + props.type + '"' : ''; + delete props.name; + delete props.type; + el = '<' + el + name + type + '>'; + } + el = document.createElement(el); + } + el = $(el); + return (!props || !el) ? el : el.set(props); + } + +}); + +/* +Class: Elements + - Every dom function such as <$$>, or in general every function that returns a collection of nodes in mootools, returns them as an Elements class. + - The purpose of the Elements class is to allow methods to work also on array. + - Elements is also an Array, so it accepts all the methods. + - Every node of the Elements instance is already extended with <$>. + +Example: + >$$('myselector').each(function(el){ + > //... + >}); + + some iterations here, $$('myselector') is also an array. + + >$$('myselector').setStyle('color', 'red'); + every element returned by $$('myselector') also accepts methods, in this example every element will be made red. +*/ + +var Elements = new Class({ + + initialize: function(elements){ + return (elements) ? $extend(elements, this) : this; + } + +}); + +Elements.extend = function(props){ + for (var prop in props){ + this.prototype[prop] = props[prop]; + this[prop] = $native.generic(prop); + } +}; + +/* +Section: Utility Functions + +Function: $ + returns the element passed in with all the Element prototypes applied. + +Arguments: + el - a reference to an actual element or a string representing the id of an element + +Example: + >$('myElement') // gets a DOM element by id with all the Element prototypes applied. + >var div = document.getElementById('myElement'); + >$(div) //returns an Element also with all the mootools extentions applied. + + You'll use this when you aren't sure if a variable is an actual element or an id, as + well as just shorthand for document.getElementById(). + +Returns: + a DOM element or false (if no id was found). + +Note: + you need to call $ on an element only once to get all the prototypes. + But its no harm to call it multiple times, as it will detect if it has been already extended. +*/ + +function $(el){ + if (!el) return null; + if (el.htmlElement) return Garbage.collect(el); + if ([window, document].contains(el)) return el; + var type = $type(el); + if (type == 'string'){ + el = document.getElementById(el); + type = (el) ? 'element' : false; + } + if (type != 'element') return null; + if (el.htmlElement) return Garbage.collect(el); + if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el; + $extend(el, Element.prototype); + el.htmlElement = function(){}; + return Garbage.collect(el); +}; + +/* +Function: $$ + Selects, and extends DOM elements. Elements arrays returned with $$ will also accept all the methods. + The return type of element methods run through $$ is always an array. If the return array is only made by elements, + $$ will be applied automatically. + +Arguments: + HTML Collections, arrays of elements, arrays of strings as element ids, elements, strings as selectors. + Any number of the above as arguments are accepted. + +Note: + if you load , $$ will also accept CSS Selectors, otherwise the only selectors supported are tag names. + +Example: + >$$('a') //an array of all anchor tags on the page + >$$('a', 'b') //an array of all anchor and bold tags on the page + >$$('#myElement') //array containing only the element with id = myElement. (only with ) + >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" + >//within the DOM element with id "myElement" (only with ) + >$$(myelement, myelement2, 'a', ['myid', myid2, 'myid3'], document.getElementsByTagName('div')) //an array containing: + >// the element referenced as myelement if existing, + >// the element referenced as myelement2 if existing, + >// all the elements with a as tag in the page, + >// the element with id = myid if existing + >// the element with id = myid2 if existing + >// the element with id = myid3 if existing + >// all the elements with div as tag in the page + +Returns: + array - array of all the dom elements matched, extended with <$>. Returns as . +*/ + +document.getElementsBySelector = document.getElementsByTagName; + +function $$(){ + var elements = []; + for (var i = 0, j = arguments.length; i < j; i++){ + var selector = arguments[i]; + switch($type(selector)){ + case 'element': elements.push(selector); + case 'boolean': break; + case false: break; + case 'string': selector = document.getElementsBySelector(selector, true); + default: elements.extend(selector); + } + } + return $$.unique(elements); +}; + +$$.unique = function(array){ + var elements = []; + for (var i = 0, l = array.length; i < l; i++){ + if (array[i].$included) continue; + var element = $(array[i]); + if (element && !element.$included){ + element.$included = true; + elements.push(element); + } + } + for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null; + return new Elements(elements); +}; + +Elements.Multi = function(property){ + return function(){ + var args = arguments; + var items = []; + var elements = true; + for (var i = 0, j = this.length, returns; i < j; i++){ + returns = this[i][property].apply(this[i], args); + if ($type(returns) != 'element') elements = false; + items.push(returns); + }; + return (elements) ? $$.unique(items) : items; + }; +}; + +Element.extend = function(properties){ + for (var property in properties){ + HTMLElement.prototype[property] = properties[property]; + Element.prototype[property] = properties[property]; + Element[property] = $native.generic(property); + var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property; + Elements.prototype[elementsProperty] = Elements.Multi(property); + } +}; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: set + you can set events, styles and properties with this shortcut. same as calling new Element. + */ + + set: function(props){ + for (var prop in props){ + var val = props[prop]; + switch(prop){ + case 'styles': this.setStyles(val); break; + case 'events': if (this.addEvents) this.addEvents(val); break; + case 'properties': this.setProperties(val); break; + default: this.setProperty(prop, val); + } + } + return this; + }, + + inject: function(el, where){ + el = $(el); + switch(where){ + case 'before': el.parentNode.insertBefore(this, el); break; + case 'after': + var next = el.getNext(); + if (!next) el.parentNode.appendChild(this); + else el.parentNode.insertBefore(this, next); + break; + case 'top': + var first = el.firstChild; + if (first){ + el.insertBefore(this, first); + break; + } + default: el.appendChild(this); + } + return this; + }, + + /* + Property: injectBefore + Inserts the Element before the passed element. + + Arguments: + el - an element reference or the id of the element to be injected in. + + Example: + >html: + >
+ >
+ >js: + >$('mySecondElement').injectBefore('myElement'); + >resulting html: + >
+ >
+ */ + + injectBefore: function(el){ + return this.inject(el, 'before'); + }, + + /* + Property: injectAfter + Same as , but inserts the element after. + */ + + injectAfter: function(el){ + return this.inject(el, 'after'); + }, + + /* + Property: injectInside + Same as , but inserts the element inside. + */ + + injectInside: function(el){ + return this.inject(el, 'bottom'); + }, + + /* + Property: injectTop + Same as , but inserts the element inside, at the top. + */ + + injectTop: function(el){ + return this.inject(el, 'top'); + }, + + /* + Property: adopt + Inserts the passed elements inside the Element. + + Arguments: + accepts elements references, element ids as string, selectors ($$('stuff')) / array of elements, array of ids as strings and collections. + */ + + adopt: function(){ + var elements = []; + $each(arguments, function(argument){ + elements = elements.concat(argument); + }); + $$(elements).inject(this); + return this; + }, + + /* + Property: remove + Removes the Element from the DOM. + + Example: + >$('myElement').remove() //bye bye + */ + + remove: function(){ + return this.parentNode.removeChild(this); + }, + + /* + Property: clone + Clones the Element and returns the cloned one. + + Arguments: + contents - boolean, when true the Element is cloned with childNodes, default true + + Returns: + the cloned element + + Example: + >var clone = $('myElement').clone().injectAfter('myElement'); + >//clones the Element and append the clone after the Element. + */ + + clone: function(contents){ + var el = $(this.cloneNode(contents !== false)); + if (!el.$events) return el; + el.$events = {}; + for (var type in this.$events) el.$events[type] = { + 'keys': $A(this.$events[type].keys), + 'values': $A(this.$events[type].values) + }; + return el.removeEvents(); + }, + + /* + Property: replaceWith + Replaces the Element with an element passed. + + Arguments: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Returns: + the passed in element + + Example: + >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. + */ + + replaceWith: function(el){ + el = $(el); + this.parentNode.replaceChild(el, this); + return el; + }, + + /* + Property: appendText + Appends text node to a DOM element. + + Arguments: + text - the text to append. + + Example: + >
hey
+ >$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" + */ + + appendText: function(text){ + this.appendChild(document.createTextNode(text)); + return this; + }, + + /* + Property: hasClass + Tests the Element to see if it has the passed in className. + + Returns: + true - the Element has the class + false - it doesn't + + Arguments: + className - string; the class name to test. + + Example: + >
+ >$('myElement').hasClass('testClass'); //returns true + */ + + hasClass: function(className){ + return this.className.contains(className, ' '); + }, + + /* + Property: addClass + Adds the passed in class to the Element, if the element doesnt already have it. + + Arguments: + className - string; the class name to add + + Example: + >
+ >$('myElement').addClass('newClass'); //
+ */ + + addClass: function(className){ + if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); + return this; + }, + + /* + Property: removeClass + Works like , but removes the class from the element. + */ + + removeClass: function(className){ + this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean(); + return this; + }, + + /* + Property: toggleClass + Adds or removes the passed in class name to the element, depending on if it's present or not. + + Arguments: + className - the class to add or remove + + Example: + >
+ >$('myElement').toggleClass('myClass'); + >
+ >$('myElement').toggleClass('myClass'); + >
+ */ + + toggleClass: function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + /* + Property: setStyle + Sets a css property to the Element. + + Arguments: + property - the property to set + value - the value to which to set it; for numeric values that require "px" you can pass an integer + + Example: + >$('myElement').setStyle('width', '300px'); //the width is now 300px + >$('myElement').setStyle('width', 300); //the width is now 300px + */ + + setStyle: function(property, value){ + switch(property){ + case 'opacity': return this.setOpacity(parseFloat(value)); + case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat'; + } + property = property.camelCase(); + switch($type(value)){ + case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break; + case 'array': value = 'rgb(' + value.join(',') + ')'; + } + this.style[property] = value; + return this; + }, + + /* + Property: setStyles + Applies a collection of styles to the Element. + + Arguments: + source - an object or string containing all the styles to apply. When its a string it overrides old style. + + Examples: + >$('myElement').setStyles({ + > border: '1px solid #000', + > width: 300, + > height: 400 + >}); + + OR + + >$('myElement').setStyles('border: 1px solid #000; width: 300px; height: 400px;'); + */ + + setStyles: function(source){ + switch($type(source)){ + case 'object': Element.setMany(this, 'setStyle', source); break; + case 'string': this.style.cssText = source; + } + return this; + }, + + /* + Property: setOpacity + Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity > 0. + + Arguments: + opacity - float; Accepts values from 0 to 1. + + Example: + >$('myElement').setOpacity(0.5) //make it 50% transparent + */ + + setOpacity: function(opacity){ + if (opacity == 0){ + if (this.style.visibility != "hidden") this.style.visibility = "hidden"; + } else { + if (this.style.visibility != "visible") this.style.visibility = "visible"; + } + if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; + if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")"; + this.style.opacity = this.$tmp.opacity = opacity; + return this; + }, + + /* + Property: getStyle + Returns the style of the Element given the property passed in. + + Arguments: + property - the css style property you want to retrieve + + Example: + >$('myElement').getStyle('width'); //returns "400px" + >//but you can also use + >$('myElement').getStyle('width').toInt(); //returns 400 + + Returns: + the style as a string + */ + + getStyle: function(property){ + property = property.camelCase(); + var result = this.style[property]; + if (!$chk(result)){ + if (property == 'opacity') return this.$tmp.opacity; + result = []; + for (var style in Element.Styles){ + if (property == style){ + Element.Styles[style].each(function(s){ + var style = this.getStyle(s); + result.push(parseInt(style) ? style : '0px'); + }, this); + if (property == 'border'){ + var every = result.every(function(bit){ + return (bit == result[0]); + }); + return (every) ? result[0] : false; + } + return result.join(' '); + } + } + if (property.contains('border')){ + if (Element.Styles.border.contains(property)){ + return ['Width', 'Style', 'Color'].map(function(p){ + return this.getStyle(property + p); + }, this).join(' '); + } else if (Element.borderShort.contains(property)){ + return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){ + return this.getStyle('border' + p + property.replace('border', '')); + }, this).join(' '); + } + } + if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); + else if (this.currentStyle) result = this.currentStyle[property]; + } + if (window.ie) result = Element.fixStyle(property, result, this); + if (result && property.test(/color/i) && result.contains('rgb')){ + return result.split('rgb').splice(1,4).map(function(color){ + return color.rgbToHex(); + }).join(' '); + } + return result; + }, + + /* + Property: getStyles + Returns an object of styles of the Element for each argument passed in. + Arguments: + properties - strings; any number of style properties + Example: + >$('myElement').getStyles('width','height','padding'); + >//returns an object like: + >{width: "10px", height: "10px", padding: "10px 0px 10px 0px"} + */ + + getStyles: function(){ + return Element.getMany(this, 'getStyle', arguments); + }, + + walk: function(brother, start){ + brother += 'Sibling'; + var el = (start) ? this[start] : this[brother]; + while (el && $type(el) != 'element') el = el[brother]; + return $(el); + }, + + /* + Property: getPrevious + Returns the previousSibling of the Element, excluding text nodes. + + Example: + >$('myElement').getPrevious(); //get the previous DOM element from myElement + + Returns: + the sibling element or undefined if none found. + */ + + getPrevious: function(){ + return this.walk('previous'); + }, + + /* + Property: getNext + Works as Element.getPrevious, but tries to find the nextSibling. + */ + + getNext: function(){ + return this.walk('next'); + }, + + /* + Property: getFirst + Works as , but tries to find the firstChild. + */ + + getFirst: function(){ + return this.walk('next', 'firstChild'); + }, + + /* + Property: getLast + Works as , but tries to find the lastChild. + */ + + getLast: function(){ + return this.walk('previous', 'lastChild'); + }, + + /* + Property: getParent + returns the $(element.parentNode) + */ + + getParent: function(){ + return $(this.parentNode); + }, + + /* + Property: getChildren + returns all the $(element.childNodes), excluding text nodes. Returns as . + */ + + getChildren: function(){ + return $$(this.childNodes); + }, + + /* + Property: hasChild + returns true if the passed in element is a child of the $(element). + */ + + hasChild: function(el){ + return !!$A(this.getElementsByTagName('*')).contains(el); + }, + + /* + Property: getProperty + Gets the an attribute of the Element. + + Arguments: + property - string; the attribute to retrieve + + Example: + >$('myImage').getProperty('src') // returns whatever.gif + + Returns: + the value, or an empty string + */ + + getProperty: function(property){ + var index = Element.Properties[property]; + if (index) return this[index]; + var flag = Element.PropertiesIFlag[property] || 0; + if (!window.ie || flag) return this.getAttribute(property, flag); + var node = this.attributes[property]; + return (node) ? node.nodeValue : null; + }, + + /* + Property: removeProperty + Removes an attribute from the Element + + Arguments: + property - string; the attribute to remove + */ + + removeProperty: function(property){ + var index = Element.Properties[property]; + if (index) this[index] = ''; + else this.removeAttribute(property); + return this; + }, + + /* + Property: getProperties + same as , but for properties + */ + + getProperties: function(){ + return Element.getMany(this, 'getProperty', arguments); + }, + + /* + Property: setProperty + Sets an attribute for the Element. + + Arguments: + property - string; the property to assign the value passed in + value - the value to assign to the property passed in + + Example: + >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source + */ + + setProperty: function(property, value){ + var index = Element.Properties[property]; + if (index) this[index] = value; + else this.setAttribute(property, value); + return this; + }, + + /* + Property: setProperties + Sets numerous attributes for the Element. + + Arguments: + source - an object with key/value pairs. + + Example: + (start code) + $('myElement').setProperties({ + src: 'whatever.gif', + alt: 'whatever dude' + }); + whatever dude + (end) + */ + + setProperties: function(source){ + return Element.setMany(this, 'setProperty', source); + }, + + /* + Property: setHTML + Sets the innerHTML of the Element. + + Arguments: + html - string; the new innerHTML for the element. + + Example: + >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML + */ + + setHTML: function(){ + this.innerHTML = $A(arguments).join(''); + return this; + }, + + /* + Property: setText + Sets the inner text of the Element. + + Arguments: + text - string; the new text content for the element. + + Example: + >$('myElement').setText('some text') //the text of myElement is now = 'some text' + */ + + setText: function(text){ + var tag = this.getTag(); + if (['style', 'script'].contains(tag)){ + if (window.ie){ + if (tag == 'style') this.styleSheet.cssText = text; + else if (tag == 'script') this.setProperty('text', text); + return this; + } else { + this.removeChild(this.firstChild); + return this.appendText(text); + } + } + this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text; + return this; + }, + + /* + Property: getText + Gets the inner text of the Element. + */ + + getText: function(){ + var tag = this.getTag(); + if (['style', 'script'].contains(tag)){ + if (window.ie){ + if (tag == 'style') return this.styleSheet.cssText; + else if (tag == 'script') return this.getProperty('text'); + } else { + return this.innerHTML; + } + } + return ($pick(this.innerText, this.textContent)); + }, + + /* + Property: getTag + Returns the tagName of the element in lower case. + + Example: + >$('myImage').getTag() // returns 'img' + + Returns: + The tag name in lower case + */ + + getTag: function(){ + return this.tagName.toLowerCase(); + }, + + /* + Property: empty + Empties an element of all its children. + + Example: + >$('myDiv').empty() // empties the Div and returns it + + Returns: + The element. + */ + + empty: function(){ + Garbage.trash(this.getElementsByTagName('*')); + return this.setHTML(''); + } + +}); + +Element.fixStyle = function(property, result, element){ + if ($chk(parseInt(result))) return result; + if (['height', 'width'].contains(property)){ + var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom']; + var size = 0; + values.each(function(value){ + size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt(); + }); + return element['offset' + property.capitalize()] - size + 'px'; + } else if (property.test(/border(.+)Width|margin|padding/)){ + return '0px'; + } + return result; +}; + +Element.Styles = {'border': [], 'padding': [], 'margin': []}; +['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ + for (var style in Element.Styles) Element.Styles[style].push(style + direction); +}); + +Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor']; + +Element.getMany = function(el, method, keys){ + var result = {}; + $each(keys, function(key){ + result[key] = el[method](key); + }); + return result; +}; + +Element.setMany = function(el, method, pairs){ + for (var key in pairs) el[method](key, pairs[key]); + return el; +}; + +Element.Properties = new Abstract({ + 'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan', + 'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength', + 'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value', + 'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected' +}); +Element.PropertiesIFlag = { + 'href': 2, 'src': 2 +}; + +Element.Methods = { + Listeners: { + addListener: function(type, fn){ + if (this.addEventListener) this.addEventListener(type, fn, false); + else this.attachEvent('on' + type, fn); + return this; + }, + + removeListener: function(type, fn){ + if (this.removeEventListener) this.removeEventListener(type, fn, false); + else this.detachEvent('on' + type, fn); + return this; + } + } +}; + +window.extend(Element.Methods.Listeners); +document.extend(Element.Methods.Listeners); +Element.extend(Element.Methods.Listeners); + +var Garbage = { + + elements: [], + + collect: function(el){ + if (!el.$tmp){ + Garbage.elements.push(el); + el.$tmp = {'opacity': 1}; + } + return el; + }, + + trash: function(elements){ + for (var i = 0, j = elements.length, el; i < j; i++){ + if (!(el = elements[i]) || !el.$tmp) continue; + if (el.$events) el.fireEvent('trash').removeEvents(); + for (var p in el.$tmp) el.$tmp[p] = null; + for (var d in Element.prototype) el[d] = null; + Garbage.elements[Garbage.elements.indexOf(el)] = null; + el.htmlElement = el.$tmp = el = null; + } + Garbage.elements.remove(null); + }, + + empty: function(){ + Garbage.collect(window); + Garbage.collect(document); + Garbage.trash(Garbage.elements); + } + +}; + +window.addListener('beforeunload', function(){ + window.addListener('unload', Garbage.empty); + if (window.ie) window.addListener('unload', CollectGarbage); +}); \ No newline at end of file diff --git a/gulliver/js/ext/ux/ux-all.js b/gulliver/js/ext/ux/ux-all.js new file mode 100755 index 000000000..4ce04c142 --- /dev/null +++ b/gulliver/js/ext/ux/ux-all.js @@ -0,0 +1,14 @@ +/* + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +Ext.ns("Ext.ux.grid");Ext.ux.grid.BufferView=Ext.extend(Ext.grid.GridView,{rowHeight:19,borderHeight:2,scrollDelay:100,cacheSize:20,cleanDelay:500,initTemplates:function(){Ext.ux.grid.BufferView.superclass.initTemplates.call(this);var a=this.templates;a.rowHolder=new Ext.Template('
');a.rowHolder.disableFormats=true;a.rowHolder.compile();a.rowBody=new Ext.Template('',"{cells}",(this.enableRowBody?'':""),"
{body}
");a.rowBody.disableFormats=true;a.rowBody.compile()},getStyleRowHeight:function(){return Ext.isBorderBox?(this.rowHeight+this.borderHeight):this.rowHeight},getCalculatedRowHeight:function(){return this.rowHeight+this.borderHeight},getVisibleRowCount:function(){var b=this.getCalculatedRowHeight(),a=this.scroller.dom.clientHeight;return(a<1)?0:Math.ceil(a/b)},getVisibleRows:function(){var a=this.getVisibleRowCount(),b=this.scroller.dom.scrollTop,c=(b===0?0:Math.floor(b/this.getCalculatedRowHeight())-1);return{first:Math.max(c,0),last:Math.min(c+a+2,this.ds.getCount()-1)}},doRender:function(g,k,u,a,s,A,l){var b=this.templates,f=b.cell,h=b.row,x=b.rowBody,n=s-1,t=this.getStyleRowHeight(),z=this.getVisibleRows(),d="width:"+this.getTotalWidth()+";height:"+t+"px;",D=[],w,E,v={},m={tstyle:d},q;for(var y=0,C=k.length;y=z.first&&o<=z.last;if(e){for(var B=0;B0},syncScroll:function(){Ext.ux.grid.BufferView.superclass.syncScroll.apply(this,arguments);this.update()},update:function(){if(this.scrollDelay){if(!this.renderTask){this.renderTask=new Ext.util.DelayedTask(this.doUpdate,this)}this.renderTask.delay(this.scrollDelay)}else{this.doUpdate()}},onRemove:function(d,a,b,c){Ext.ux.grid.BufferView.superclass.onRemove.apply(this,arguments);if(c!==true){this.update()}},doUpdate:function(){if(this.getVisibleRowCount()>0){var f=this.grid,b=f.colModel,h=f.store,e=this.getColumnData(),a=this.getVisibleRows(),j;for(var d=a.first;d<=a.last;d++){if(!this.isRowRendered(d)&&(j=this.getRow(d))){var c=this.doRender(e,[h.getAt(d)],h,d,b.getColumnCount(),f.stripeRows,true);j.innerHTML=c}}this.clean()}},clean:function(){if(!this.cleanTask){this.cleanTask=new Ext.util.DelayedTask(this.doClean,this)}this.cleanTask.delay(this.cleanDelay)},doClean:function(){if(this.getVisibleRowCount()>0){var b=this.getVisibleRows();b.first-=this.cacheSize;b.last+=this.cacheSize;var c=0,d=this.getRows();if(b.first<=0){c=b.last+1}for(var a=this.ds.getCount();cb.last)&&d[c].innerHTML){d[c].innerHTML=""}}}},removeTask:function(b){var a=this[b];if(a&&a.cancel){a.cancel();this[b]=null}},destroy:function(){this.removeTask("cleanTask");this.removeTask("renderTask");Ext.ux.grid.BufferView.superclass.destroy.call(this)},layout:function(){Ext.ux.grid.BufferView.superclass.layout.call(this);this.update()}});Ext.ns("Ext.ux.layout");Ext.ux.layout.CenterLayout=Ext.extend(Ext.layout.FitLayout,{setItemSize:function(b,a){this.container.addClass("ux-layout-center");b.addClass("ux-layout-center-item");if(b&&a.height>0){if(b.width){a.width=b.width}b.setSize(a)}}});Ext.Container.LAYOUTS["ux.center"]=Ext.ux.layout.CenterLayout;Ext.ns("Ext.ux.grid");Ext.ux.grid.CheckColumn=function(a){Ext.apply(this,a);if(!this.id){this.id=Ext.id()}this.renderer=this.renderer.createDelegate(this)};Ext.ux.grid.CheckColumn.prototype={init:function(a){this.grid=a;this.grid.on("render",function(){var b=this.grid.getView();b.mainBody.on("mousedown",this.onMouseDown,this)},this)},onMouseDown:function(d,c){if(Ext.fly(c).hasClass(this.createId())){d.stopEvent();var b=this.grid.getView().findRowIndex(c);var a=this.grid.store.getAt(b);a.set(this.dataIndex,!a.data[this.dataIndex])}},renderer:function(b,c,a){c.css+=" x-grid3-check-col-td";return String.format('
 
',b?"-on":"",this.createId())},createId:function(){return"x-grid3-cc-"+this.id}};Ext.preg("checkcolumn",Ext.ux.grid.CheckColumn);Ext.grid.CheckColumn=Ext.ux.grid.CheckColumn;Ext.ns("Ext.ux.grid");Ext.ux.grid.ColumnHeaderGroup=Ext.extend(Ext.util.Observable,{constructor:function(a){this.config=a},init:function(a){Ext.applyIf(a.colModel,this.config);Ext.apply(a.getView(),this.viewConfig)},viewConfig:{initTemplates:function(){this.constructor.prototype.initTemplates.apply(this,arguments);var a=this.templates||{};if(!a.gcell){a.gcell=new Ext.XTemplate('','
',this.grid.enableHdMenu?'':"","{value}
")}this.templates=a;this.hrowRe=new RegExp("ux-grid-hd-group-row-(\\d+)","")},renderHeaders:function(){var h=this.templates,d=[],l=this.cm,p=l.rows,j="width:"+this.getTotalWidth()+";";for(var o=0,k=p.length;o=f&&e=0;c.setChecked(n,true)}q.checked=!q.checked}return true},beforeColMenuShow:function(){var h=this.cm,j=this.cm.rows;this.colMenu.removeAll();for(var d=0,m=h.getColumnCount();d=p&&d=m&&x.oldIndex=m&&x.oldIndex+x.colspan-1=m&&x.newIndex table"),e=this.getTotalWidth(),k=this.cm.rows;for(var j=0;j=c&&b=b&&c=b.col&&p<=b.col+b.colspan){return false}var j=Ext.ux.grid.ColumnHeaderGroup.prototype.getGroupSpan.call(this.view,q-1,k);if(pj.col+j.colspan){return false}return{r:a,px:m,pt:s,row:q,oldIndex:k,newIndex:p,colspan:b.colspan}}});Ext.ns("Ext.ux.tree");Ext.ux.tree.ColumnTree=Ext.extend(Ext.tree.TreePanel,{lines:false,borderWidth:Ext.isBorderBox?0:2,cls:"x-column-tree",onRender:function(){Ext.tree.ColumnTree.superclass.onRender.apply(this,arguments);this.headers=this.header.createChild({cls:"x-tree-headers"});var f=this.columns,g;var b=0;var d=19;for(var e=0,a=f.length;e
','"];for(var e=1,g=l.length;e','
',(j.renderer?j.renderer(m[j.dataIndex],d,m):m[j.dataIndex]),"
","
")}b.push('
','',"");if(o!==true&&d.nextSibling&&d.nextSibling.ui.getEl()){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",d.nextSibling.ui.getEl(),b.join(""))}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",h,b.join(""))}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1];var f=this.elNode.firstChild.childNodes;this.indentNode=f[0];this.ecNode=f[1];this.iconNode=f[2];this.anchor=f[3];this.textNode=f[3].firstChild}});Ext.tree.ColumnNodeUI=Ext.ux.tree.ColumnNodeUI;Ext.DataView.LabelEditor=Ext.extend(Ext.Editor,{alignment:"tl-tl",hideEl:false,cls:"x-small-editor",shim:false,completeOnEnter:true,cancelOnEsc:true,labelSelector:"span.x-editable",constructor:function(a,b){Ext.DataView.LabelEditor.superclass.constructor.call(this,b||new Ext.form.TextField({allowBlank:false,growMin:90,growMax:240,grow:true,selectOnFocus:true}),a)},init:function(a){this.view=a;a.on("render",this.initEditor,this);this.on("complete",this.onSave,this)},initEditor:function(){this.view.on({scope:this,containerclick:this.doBlur,click:this.doBlur});this.view.getEl().on("mousedown",this.onMouseDown,this,{delegate:this.labelSelector})},doBlur:function(){if(this.editing){this.field.blur()}},onMouseDown:function(d,c){if(!d.ctrlKey&&!d.shiftKey){var b=this.view.findItemFromChild(c);d.stopEvent();var a=this.view.store.getAt(this.view.indexOf(b));this.startEdit(c,a.data[this.dataIndex]);this.activeRecord=a}else{d.preventDefault()}},onSave:function(a,b){this.activeRecord.set(this.dataIndex,b)}});Ext.DataView.DragSelector=function(f){f=f||{};var j,h,l;var d,k,m=new Ext.lib.Region(0,0,0,0);var b=f.dragSafe===true;this.init=function(q){j=q;j.on("render",p)};function n(){d=[];j.all.each(function(q){d[d.length]=q.getRegion()});k=j.el.getRegion()}function e(){return false}function g(q){return !b||q.target==j.el.dom}function o(q){j.on("containerclick",e,j,{single:true});if(!h){h=j.el.createChild({cls:"x-view-selector"})}else{if(h.dom.parentNode!==j.el.dom){j.el.dom.appendChild(h.dom)}h.setDisplayed("block")}n();j.clearSelections()}function c(z){var A=l.startXY;var E=l.getXY();var C=Math.min(A[0],E[0]);var B=Math.min(A[1],E[1]);var D=Math.abs(A[0]-E[0]);var u=Math.abs(A[1]-E[1]);m.left=C;m.top=B;m.right=C+D;m.bottom=B+u;m.constrainTo(k);h.setRegion(m);for(var t=0,v=d.length;t
Level "+accuracy+" Accuracy (8 = Exact Match, 1 = Vague Match)")}else{point=new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);if(typeof this.setCenter.marker==="object"&&typeof point==="object"){this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true,this.setCenter.listeners)}}}}}});Ext.reg("gmappanel",Ext.ux.GMapPanel);Ext.namespace("Ext.ux.grid");Ext.ux.grid.GridFilters=Ext.extend(Ext.util.Observable,{autoReload:true,filterCls:"ux-filtered-column",local:false,menuFilterText:"Filters",paramPrefix:"filter",showMenu:true,stateId:undefined,updateBuffer:500,constructor:function(a){a=a||{};this.deferredUpdate=new Ext.util.DelayedTask(this.reload,this);this.filters=new Ext.util.MixedCollection();this.filters.getKey=function(b){return b?b.dataIndex:null};this.addFilters(a.filters);delete a.filters;Ext.apply(this,a)},init:function(a){if(a instanceof Ext.grid.GridPanel){this.grid=a;this.bindStore(this.grid.getStore(),true);if(this.filters.getCount()==0){this.addFilters(this.grid.getColumnModel())}this.grid.filters=this;this.grid.addEvents({filterupdate:true});a.on({scope:this,beforestaterestore:this.applyState,beforestatesave:this.saveState,beforedestroy:this.destroy,reconfigure:this.onReconfigure});if(a.rendered){this.onRender()}else{a.on({scope:this,single:true,render:this.onRender})}}else{if(a instanceof Ext.PagingToolbar){this.toolbar=a}}},applyState:function(b,d){var a,c;this.applyingState=true;this.clearFilters();if(d.filters){for(a in d.filters){c=this.filters.get(a);if(c){c.setValue(d.filters[a]);c.setActive(true)}}}this.deferredUpdate.cancel();if(this.local){this.reload()}delete this.applyingState;delete d.filters},saveState:function(a,c){var b={};this.filters.each(function(d){if(d.active){b[d.dataIndex]=d.getValue()}});return(c.filters=b)},onRender:function(){this.grid.getView().on("refresh",this.onRefresh,this);this.createMenu()},destroy:function(){this.removeAll();this.purgeListeners();if(this.filterMenu){Ext.menu.MenuMgr.unregister(this.filterMenu);this.filterMenu.destroy();this.filterMenu=this.menu.menu=null}},removeAll:function(){if(this.filters){Ext.destroy.apply(Ext,this.filters.items);this.filters.clear()}},bindStore:function(a,b){if(!b&&this.store){if(this.local){a.un("load",this.onLoad,this)}else{a.un("beforeload",this.onBeforeLoad,this)}}if(a){if(this.local){a.on("load",this.onLoad,this)}else{a.on("beforeload",this.onBeforeLoad,this)}}this.store=a},onReconfigure:function(){this.bindStore(this.grid.getStore());this.store.clearFilter();this.removeAll();this.addFilters(this.grid.getColumnModel());this.updateColumnHeadings()},createMenu:function(){var a=this.grid.getView(),b=a.hmenu;if(this.showMenu&&b){this.sep=b.addSeparator();this.filterMenu=new Ext.menu.Menu({id:this.grid.id+"-filters-menu"});this.menu=b.add({checked:false,itemId:"filters",text:this.menuFilterText,menu:this.filterMenu});this.menu.on({scope:this,checkchange:this.onCheckChange,beforecheckchange:this.onBeforeCheck});b.on("beforeshow",this.onMenu,this)}this.updateColumnHeadings()},getMenuFilter:function(){var a=this.grid.getView();if(!a||a.hdCtxIndex===undefined){return null}return this.filters.get(a.cm.config[a.hdCtxIndex].dataIndex)},onMenu:function(b){var a=this.getMenuFilter();if(a){this.menu.menu=a.menu;this.menu.setChecked(a.active,false);this.menu.setDisabled(a.disabled===true)}this.menu.setVisible(a!==undefined);this.sep.setVisible(a!==undefined)},onCheckChange:function(a,b){this.getMenuFilter().setActive(b)},onBeforeCheck:function(a,b){return !b||this.getMenuFilter().isActivatable()},onStateChange:function(b,a){if(b==="serialize"){return}if(a==this.getMenuFilter()){this.menu.setChecked(a.active,false)}if((this.autoReload||this.local)&&!this.applyingState){this.deferredUpdate.delay(this.updateBuffer)}this.updateColumnHeadings();if(!this.applyingState){this.grid.saveState()}this.grid.fireEvent("filterupdate",this,a)},onBeforeLoad:function(a,b){b.params=b.params||{};this.cleanParams(b.params);var c=this.buildQuery(this.getFilterData());Ext.apply(b.params,c)},onLoad:function(a,b){a.filterBy(this.getRecordFilter())},onRefresh:function(){this.updateColumnHeadings()},updateColumnHeadings:function(){var b=this.grid.getView(),c,a,d;if(b.mainHd){for(c=0,a=b.cm.config.length;c0){a[this.paramPrefix]=Ext.util.JSON.encode(d)}}return a},cleanParams:function(c){if(this.encode){delete c[this.paramPrefix]}else{var b,a;b=new RegExp("^"+this.paramPrefix+"[[0-9]+]");for(a in c){if(b.test(a)){delete c[a]}}}},getFilterClass:function(a){switch(a){case"auto":a="string";break;case"int":case"float":a="numeric";break}return Ext.ux.grid.filter[a.substr(0,1).toUpperCase()+a.substr(1)+"Filter"]}});Ext.preg("gridfilters",Ext.ux.grid.GridFilters);Ext.namespace("Ext.ux.grid.filter");Ext.ux.grid.filter.Filter=Ext.extend(Ext.util.Observable,{active:false,dataIndex:null,menu:null,updateBuffer:500,constructor:function(a){Ext.apply(this,a);this.addEvents("activate","deactivate","serialize","update");Ext.ux.grid.filter.Filter.superclass.constructor.call(this);this.menu=new Ext.menu.Menu();this.init(a);if(a&&a.value){this.setValue(a.value);this.setActive(a.active!==false,true);delete a.value}},destroy:function(){if(this.menu){this.menu.destroy()}this.purgeListeners()},init:Ext.emptyFn,getValue:Ext.emptyFn,setValue:Ext.emptyFn,isActivatable:function(){return true},getSerialArgs:Ext.emptyFn,validateRecord:function(){return true},serialize:function(){var a=this.getSerialArgs();this.fireEvent("serialize",a,this);return a},fireUpdate:function(){if(this.active){this.fireEvent("update",this)}this.setActive(this.isActivatable())},setActive:function(b,a){if(this.active!=b){this.active=b;if(a!==true){this.fireEvent(b?"activate":"deactivate",this)}}}});Ext.ux.grid.filter.BooleanFilter=Ext.extend(Ext.ux.grid.filter.Filter,{defaultValue:false,yesText:"Yes",noText:"No",init:function(a){var c=Ext.id();this.options=[new Ext.menu.CheckItem({text:this.yesText,group:c,checked:this.defaultValue===true}),new Ext.menu.CheckItem({text:this.noText,group:c,checked:this.defaultValue===false})];this.menu.add(this.options[0],this.options[1]);for(var b=0;bd){a.after.setChecked(false,true)}}}this.fireEvent("update",this)},getValue:function(){var b,a={};for(b in this.fields){if(this.fields[b].checked){a[b]=this.fields[b].menu.picker.getValue()}}return a},setValue:function(c,b){var a;for(a in this.fields){if(c[a]){this.fields[a].menu.picker.setValue(c[a]);this.fields[a].setChecked(true)}else{if(!b){this.fields[a].setChecked(false)}}}this.fireEvent("update",this)},isActivatable:function(){var a;for(a in this.fields){if(this.fields[a].checked){return true}}return false},getSerialArgs:function(){var a=[];for(var b in this.fields){if(this.fields[b].checked){a.push({type:"date",comparison:this.compareMap[b],value:this.getFieldValue(b).format(this.dateFormat)})}}return a},getFieldValue:function(a){return this.fields[a].menu.picker.getValue()},getPicker:function(a){return this.fields[a].menu.picker},validateRecord:function(a){var b,d,c=a.get(this.dataIndex);if(!Ext.isDate(c)){return false}c=c.clearTime(true).getTime();for(b in this.fields){if(this.fields[b].checked){d=this.getFieldValue(b).clearTime(true).getTime();if(b=="before"&&d<=c){return false}if(b=="after"&&d>=c){return false}if(b=="on"&&d!=c){return false}}}return true}});Ext.ux.grid.filter.ListFilter=Ext.extend(Ext.ux.grid.filter.Filter,{phpMode:false,init:function(a){this.dt=new Ext.util.DelayedTask(this.fireUpdate,this);if(this.menu){this.menu.destroy()}this.menu=new Ext.ux.menu.ListMenu(a);this.menu.on("checkchange",this.onCheckChange,this)},getValue:function(){return this.menu.getSelected()},setValue:function(a){this.menu.setSelected(a);this.fireEvent("update",this)},isActivatable:function(){return this.getValue().length>0},getSerialArgs:function(){var a={type:"list",value:this.phpMode?this.getValue().join(","):this.getValue()};return a},onCheckChange:function(){this.dt.delay(this.updateBuffer)},validateRecord:function(a){return this.getValue().indexOf(a.get(this.dataIndex))>-1}});Ext.ux.grid.filter.NumericFilter=Ext.extend(Ext.ux.grid.filter.Filter,{fieldCls:Ext.form.NumberField,iconCls:{gt:"ux-rangemenu-gt",lt:"ux-rangemenu-lt",eq:"ux-rangemenu-eq"},menuItemCfgs:{emptyText:"Enter Filter Text...",selectOnFocus:true,width:125},menuItems:["lt","gt","-","eq"],init:function(a){if(this.menu){this.menu.destroy()}this.menu=new Ext.ux.menu.RangeMenu(Ext.apply(a,{fieldCfg:this.fieldCfg||{},fieldCls:this.fieldCls,fields:this.fields||{},iconCls:this.iconCls,menuItemCfgs:this.menuItemCfgs,menuItems:this.menuItems,updateBuffer:this.updateBuffer}));this.menu.on("update",this.fireUpdate,this)},getValue:function(){return this.menu.getValue()},setValue:function(a){this.menu.setValue(a)},isActivatable:function(){var a=this.getValue();for(key in a){if(a[key]!==undefined){return true}}return false},getSerialArgs:function(){var c,b=[],a=this.menu.getValue();for(c in a){b.push({type:"numeric",comparison:c,value:a[c]})}return b},validateRecord:function(a){var c=a.get(this.dataIndex),b=this.getValue();if(b.eq!==undefined&&c!=b.eq){return false}if(b.lt!==undefined&&c>=b.lt){return false}if(b.gt!==undefined&&c<=b.gt){return false}return true}});Ext.ux.grid.filter.StringFilter=Ext.extend(Ext.ux.grid.filter.Filter,{iconCls:"ux-gridfilter-text-icon",emptyText:"Enter Filter Text...",selectOnFocus:true,width:125,init:function(a){Ext.applyIf(a,{enableKeyEvents:true,iconCls:this.iconCls,listeners:{scope:this,keyup:this.onInputKeyUp}});this.inputItem=new Ext.form.TextField(a);this.menu.add(this.inputItem);this.updateTask=new Ext.util.DelayedTask(this.fireUpdate,this)},getValue:function(){return this.inputItem.getValue()},setValue:function(a){this.inputItem.setValue(a);this.fireEvent("update",this)},isActivatable:function(){return this.inputItem.getValue().length>0},getSerialArgs:function(){return{type:"string",value:this.getValue()}},validateRecord:function(a){var b=a.get(this.dataIndex);if(typeof b!="string"){return(this.getValue().length===0)}return b.toLowerCase().indexOf(this.getValue().toLowerCase())>-1},onInputKeyUp:function(c,b){var a=b.getKey();if(a==b.RETURN&&c.isValid()){b.stopEvent();this.menu.hide(true);return}this.updateTask.delay(this.updateBuffer)}});Ext.namespace("Ext.ux.menu");Ext.ux.menu.ListMenu=Ext.extend(Ext.menu.Menu,{labelField:"text",loadingText:"Loading...",loadOnShow:true,single:false,constructor:function(b){this.selected=[];this.addEvents("checkchange");Ext.ux.menu.ListMenu.superclass.constructor.call(this,b=b||{});if(!b.store&&b.options){var c=[];for(var d=0,a=b.options.length;d-1,hideOnClick:false});f.itemId=b[d].id;f.on("checkchange",this.checkChange,this);this.add(f)}this.loaded=true;if(g){this.show()}this.fireEvent("load",this,b)},getSelected:function(){return this.selected},setSelected:function(a){a=this.selected=[].concat(a);if(this.loaded){this.items.each(function(d){d.setChecked(false,true);for(var c=0,b=a.length;c0){a[b]=c.getValue()}}return a},setValue:function(b){var a;for(a in this.fields){this.fields[a].setValue(b[a]!==undefined?b[a]:"")}this.fireEvent("update",this)},onInputKeyUp:function(c,b){var a=b.getKey();if(a==b.RETURN&&c.isValid()){b.stopEvent();this.hide(true);return}if(c==this.fields.eq){if(this.fields.gt){this.fields.gt.setValue(null)}if(this.fields.lt){this.fields.lt.setValue(null)}}else{this.fields.eq.setValue(null)}this.updateTask.delay(this.updateBuffer)}}); +/* + * Ext JS Library 3.2.0 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +Ext.ns("Ext.ux.grid");Ext.ux.grid.GroupSummary=Ext.extend(Ext.util.Observable,{constructor:function(a){Ext.apply(this,a);Ext.ux.grid.GroupSummary.superclass.constructor.call(this)},init:function(b){this.grid=b;var a=this.view=b.getView();a.doGroupEnd=this.doGroupEnd.createDelegate(this);a.afterMethod("onColumnWidthUpdated",this.doWidth,this);a.afterMethod("onAllColumnWidthsUpdated",this.doAllWidths,this);a.afterMethod("onColumnHiddenUpdated",this.doHidden,this);a.afterMethod("onUpdate",this.doUpdate,this);a.afterMethod("onRemove",this.doRemove,this);if(!this.rowTpl){this.rowTpl=new Ext.Template('
','',"{cells}","
");this.rowTpl.disableFormats=true}this.rowTpl.compile();if(!this.cellTpl){this.cellTpl=new Ext.Template('','
{value}
',"");this.cellTpl.disableFormats=true}this.cellTpl.compile()},toggleSummaries:function(b){var a=this.grid.getGridEl();if(a){if(b===undefined){b=a.hasClass("x-grid-hide-summary")}a[b?"removeClass":"addClass"]("x-grid-hide-summary")}},renderSummary:function(d,h){h=h||this.view.getColumnData();var j=this.grid.getColumnModel().config,e=[],k,a={},b,l=h.length-1;for(var f=0,g=h.length;f",this.renderSummary({data:e},b),"")},doWidth:function(e,b,d){if(!this.isGrouped()){return}var c=this.view.getGroups(),a=c.length,f=0,g;for(;f'+d+""}}});Ext.grid.GroupSummary=Ext.ux.grid.GroupSummary;Ext.ux.grid.GroupSummary.Calculations={sum:function(b,a,c){return b+(a.data[c]||0)},count:function(b,a,d,c){return c[d+"count"]?++c[d+"count"]:(c[d+"count"]=1)},max:function(c,b,e,d){var c=b.data[e];var a=d[e+"max"]===undefined?(d[e+"max"]=c):d[e+"max"];return c>a?(d[e+"max"]=c):a},min:function(b,a,e,d){var b=a.data[e];var c=d[e+"min"]===undefined?(d[e+"min"]=b):d[e+"min"];return b','{text}',"");c.disableFormats=true;c.compile();Ext.ux.GroupTab.prototype.itemTpl=c}this.items.each(this.initTab,this)},afterRender:function(){Ext.ux.GroupTab.superclass.afterRender.call(this);if(this.activeTab!==undefined){var a=(typeof this.activeTab=="object")?this.activeTab:this.items.get(this.activeTab);delete this.activeTab;this.setActiveTab(a)}},initTab:function(c,a){var d=this.strip.dom.childNodes[a];var e=Ext.TabPanel.prototype.getTemplateArgs.call(this,c);if(c===this.mainItem){c.tabEl=this.groupEl;e.cls+=" x-grouptabs-main-item"}var b=d?this.itemTpl.insertBefore(d,e):this.itemTpl.append(this.strip,e);c.tabEl=c.tabEl||b;c.on("disable",this.onItemDisabled,this);c.on("enable",this.onItemEnabled,this);c.on("titlechange",this.onItemTitleChanged,this);c.on("iconchange",this.onItemIconChanged,this);c.on("beforeshow",this.onBeforeShowItem,this)},setMainItem:function(a){a=this.getComponent(a);if(!a||this.fireEvent("changemainitem",this,a,this.mainItem)===false){return}this.mainItem=a},getMainItem:function(){return this.mainItem||null},onBeforeShowItem:function(a){if(a!=this.activeTab){this.setActiveTab(a);return false}},onAdd:function(a,c,b){if(this.rendered){this.initTab.call(this,c,b)}},onRemove:function(c,b){Ext.destroy(Ext.get(this.getTabEl(b)));this.stack.remove(b);b.un("disable",this.onItemDisabled,this);b.un("enable",this.onItemEnabled,this);b.un("titlechange",this.onItemTitleChanged,this);b.un("iconchange",this.onItemIconChanged,this);b.un("beforeshow",this.onBeforeShowItem,this);if(b==this.activeTab){var a=this.stack.next();if(a){this.setActiveTab(a)}else{if(this.items.getCount()>0){this.setActiveTab(0)}else{this.activeTab=null}}}},onBeforeAdd:function(b){var a=b.events?(this.items.containsKey(b.getItemId())?b:null):this.items.get(b);if(a){this.setActiveTab(b);return false}Ext.TabPanel.superclass.onBeforeAdd.apply(this,arguments);var c=b.elements;b.elements=c?c.replace(",header",""):c;b.border=(b.border===true)},onItemDisabled:Ext.TabPanel.prototype.onItemDisabled,onItemEnabled:Ext.TabPanel.prototype.onItemEnabled,onItemTitleChanged:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).child("a.x-grouptabs-text",true).innerHTML=b.title}},onItemIconChanged:function(d,a,c){var b=this.getTabEl(d);if(b){Ext.fly(b).child("a.x-grouptabs-text").replaceClass(c,a)}},beforeDestroy:function(){Ext.TabPanel.prototype.beforeDestroy.call(this);this.tooltip.destroy()}});Ext.reg("grouptab",Ext.ux.GroupTab);Ext.ns("Ext.ux");Ext.ux.GroupTabPanel=Ext.extend(Ext.TabPanel,{tabPosition:"left",alternateColor:false,alternateCls:"x-grouptabs-panel-alt",defaultType:"grouptab",deferredRender:false,activeGroup:null,initComponent:function(){Ext.ux.GroupTabPanel.superclass.initComponent.call(this);this.addEvents("beforegroupchange","groupchange");this.elements="body,header";this.stripTarget="header";this.tabPosition=this.tabPosition=="right"?"right":"left";this.addClass("x-grouptabs-panel");if(this.tabStyle&&this.tabStyle!=""){this.addClass("x-grouptabs-panel-"+this.tabStyle)}if(this.alternateColor){this.addClass(this.alternateCls)}this.on("beforeadd",function(b,c,a){this.initGroup(c,a)});this.items.each(function(a){a.on("tabchange",function(b){this.fireEvent("tabchange",this,b.activeTab)},this)},this)},initEvents:function(){this.mon(this.strip,"mousedown",this.onStripMouseDown,this)},onRender:function(c,a){Ext.TabPanel.superclass.onRender.call(this,c,a);if(this.plain){var f=this.tabPosition=="top"?"header":"footer";this[f].addClass("x-tab-panel-"+f+"-plain")}var b=this[this.stripTarget];this.stripWrap=b.createChild({cls:"x-tab-strip-wrap ",cn:{tag:"ul",cls:"x-grouptabs-strip x-grouptabs-tab-strip-"+this.tabPosition}});var e=(this.tabPosition=="bottom"?this.stripWrap:null);this.strip=new Ext.Element(this.stripWrap.dom.firstChild);this.header.addClass("x-grouptabs-panel-header");this.bwrap.addClass("x-grouptabs-bwrap");this.body.addClass("x-tab-panel-body-"+this.tabPosition+" x-grouptabs-panel-body");if(!this.groupTpl){var d=new Ext.Template('
  • ','','',"{text}","
  • ");d.disableFormats=true;d.compile();Ext.ux.GroupTabPanel.prototype.groupTpl=d}this.items.each(this.initGroup,this)},afterRender:function(){Ext.ux.GroupTabPanel.superclass.afterRender.call(this);this.tabJoint=Ext.fly(this.body.dom.parentNode).createChild({cls:"x-tab-joint"});this.addClass("x-tab-panel-"+this.tabPosition);this.header.setWidth(this.tabWidth);if(this.activeGroup!==undefined){var a=(typeof this.activeGroup=="object")?this.activeGroup:this.items.get(this.activeGroup);delete this.activeGroup;this.setActiveGroup(a);a.setActiveTab(a.getMainItem())}},getGroupEl:Ext.TabPanel.prototype.getTabEl,findTargets:function(c){var b=null,a=c.getTarget("li",this.strip);if(a){b=this.findById(a.id.split(this.idDelimiter)[1]);if(b.disabled){return{expand:null,item:null,el:null}}}return{expand:c.getTarget(".x-grouptabs-expand",this.strip),isGroup:!c.getTarget("ul.x-grouptabs-sub",this.strip),item:b,el:a}},onStripMouseDown:function(b){if(b.button!=0){return}b.preventDefault();var a=this.findTargets(b);if(a.expand){this.toggleGroup(a.el)}else{if(a.item){if(a.isGroup){a.item.setActiveTab(a.item.getMainItem())}else{a.item.ownerCt.setActiveTab(a.item)}}}},expandGroup:function(a){if(a.isXType){a=this.getGroupEl(a)}Ext.fly(a).addClass("x-grouptabs-expanded");this.syncTabJoint()},toggleGroup:function(a){if(a.isXType){a=this.getGroupEl(a)}Ext.fly(a).toggleClass("x-grouptabs-expanded");this.syncTabJoint()},collapseGroup:function(a){if(a.isXType){a=this.getGroupEl(a)}Ext.fly(a).removeClass("x-grouptabs-expanded");this.syncTabJoint()},syncTabJoint:function(b){if(!this.tabJoint){return}b=b||this.getGroupEl(this.activeGroup);if(b){this.tabJoint.setHeight(Ext.fly(b).getHeight()-2);var a=Ext.isGecko2?0:1;if(this.tabPosition=="left"){this.tabJoint.alignTo(b,"tl-tr",[-2,a])}else{this.tabJoint.alignTo(b,"tr-tl",[1,a])}}else{this.tabJoint.hide()}},getActiveTab:function(){if(!this.activeGroup){return null}return this.activeGroup.getTabEl(this.activeGroup.activeTab)||null},onResize:function(){Ext.ux.GroupTabPanel.superclass.onResize.apply(this,arguments);this.syncTabJoint()},createCorner:function(a,b){return Ext.fly(a).createChild({cls:"x-grouptabs-corner x-grouptabs-corner-"+b})},initGroup:function(f,b){var d=this.strip.dom.childNodes[b],e=this.getTemplateArgs(f);if(b===0){e.cls+=" x-tab-first"}e.cls+=" x-grouptabs-main";e.text=f.getMainItem().title;var c=d?this.groupTpl.insertBefore(d,e):this.groupTpl.append(this.strip,e),a=this.createCorner(c,"top-"+this.tabPosition),g=this.createCorner(c,"bottom-"+this.tabPosition);f.tabEl=c;if(f.expanded){this.expandGroup(c)}if(Ext.isIE6||(Ext.isIE&&!Ext.isStrict)){g.setLeft("-10px");g.setBottom("-5px");a.setLeft("-10px");a.setTop("-5px")}this.mon(f,{scope:this,changemainitem:this.onGroupChangeMainItem,beforetabchange:this.onGroupBeforeTabChange})},setActiveGroup:function(b){b=this.getComponent(b);if(!b){return false}if(!this.rendered){this.activeGroup=b;return true}if(this.activeGroup!=b&&this.fireEvent("beforegroupchange",this,b,this.activeGroup)!==false){if(this.activeGroup){this.activeGroup.activeTab=null;var a=this.getGroupEl(this.activeGroup);if(a){Ext.fly(a).removeClass("x-grouptabs-strip-active")}}var c=this.getGroupEl(b);Ext.fly(c).addClass("x-grouptabs-strip-active");this.activeGroup=b;this.stack.add(b);this.layout.setActiveItem(b);this.syncTabJoint(c);this.fireEvent("groupchange",this,b);return true}return false},onGroupBeforeTabChange:function(a,c,b){if(a!==this.activeGroup||c!==b){this.strip.select(".x-grouptabs-sub > li.x-grouptabs-strip-active",true).removeClass("x-grouptabs-strip-active")}this.expandGroup(this.getGroupEl(a));if(a!==this.activeGroup){return this.setActiveGroup(a)}},getFrameHeight:function(){var a=this.el.getFrameWidth("tb");a+=(this.tbar?this.tbar.getHeight():0)+(this.bbar?this.bbar.getHeight():0);return a},adjustBodyWidth:function(a){return a-this.tabWidth}});Ext.reg("grouptabpanel",Ext.ux.GroupTabPanel);Ext.ux.form.ItemSelector=Ext.extend(Ext.form.Field,{hideNavIcons:false,imagePath:"",iconUp:"up2.gif",iconDown:"down2.gif",iconLeft:"left2.gif",iconRight:"right2.gif",iconTop:"top2.gif",iconBottom:"bottom2.gif",drawUpIcon:true,drawDownIcon:true,drawLeftIcon:true,drawRightIcon:true,drawTopIcon:true,drawBotIcon:true,delimiter:",",bodyStyle:null,border:false,defaultAutoCreate:{tag:"div"},multiselects:null,initComponent:function(){Ext.ux.form.ItemSelector.superclass.initComponent.call(this);this.addEvents({rowdblclick:true,change:true})},onRender:function(d,a){Ext.ux.form.ItemSelector.superclass.onRender.call(this,d,a);var h=[{legend:"Available",draggable:true,droppable:true,width:100,height:100},{legend:"Selected",droppable:true,draggable:true,width:100,height:100}];this.fromMultiselect=new Ext.ux.form.MultiSelect(Ext.applyIf(this.multiselects[0],h[0]));this.fromMultiselect.on("dblclick",this.onRowDblClick,this);this.toMultiselect=new Ext.ux.form.MultiSelect(Ext.applyIf(this.multiselects[1],h[1]));this.toMultiselect.on("dblclick",this.onRowDblClick,this);var g=new Ext.Panel({bodyStyle:this.bodyStyle,border:this.border,layout:"table",layoutConfig:{columns:3}});g.add(this.fromMultiselect);var c=new Ext.Panel({header:false});g.add(c);g.add(this.toMultiselect);g.render(this.el);c.el.down("."+c.bwrapCls).remove();if(this.imagePath!=""&&this.imagePath.charAt(this.imagePath.length-1)!="/"){this.imagePath+="/"}this.iconUp=this.imagePath+(this.iconUp||"up2.gif");this.iconDown=this.imagePath+(this.iconDown||"down2.gif");this.iconLeft=this.imagePath+(this.iconLeft||"left2.gif");this.iconRight=this.imagePath+(this.iconRight||"right2.gif");this.iconTop=this.imagePath+(this.iconTop||"top2.gif");this.iconBottom=this.imagePath+(this.iconBottom||"bottom2.gif");var f=c.getEl();this.toTopIcon=f.createChild({tag:"img",src:this.iconTop,style:{cursor:"pointer",margin:"2px"}});f.createChild({tag:"br"});this.upIcon=f.createChild({tag:"img",src:this.iconUp,style:{cursor:"pointer",margin:"2px"}});f.createChild({tag:"br"});this.addIcon=f.createChild({tag:"img",src:this.iconRight,style:{cursor:"pointer",margin:"2px"}});f.createChild({tag:"br"});this.removeIcon=f.createChild({tag:"img",src:this.iconLeft,style:{cursor:"pointer",margin:"2px"}});f.createChild({tag:"br"});this.downIcon=f.createChild({tag:"img",src:this.iconDown,style:{cursor:"pointer",margin:"2px"}});f.createChild({tag:"br"});this.toBottomIcon=f.createChild({tag:"img",src:this.iconBottom,style:{cursor:"pointer",margin:"2px"}});this.toTopIcon.on("click",this.toTop,this);this.upIcon.on("click",this.up,this);this.downIcon.on("click",this.down,this);this.toBottomIcon.on("click",this.toBottom,this);this.addIcon.on("click",this.fromTo,this);this.removeIcon.on("click",this.toFrom,this);if(!this.drawUpIcon||this.hideNavIcons){this.upIcon.dom.style.display="none"}if(!this.drawDownIcon||this.hideNavIcons){this.downIcon.dom.style.display="none"}if(!this.drawLeftIcon||this.hideNavIcons){this.addIcon.dom.style.display="none"}if(!this.drawRightIcon||this.hideNavIcons){this.removeIcon.dom.style.display="none"}if(!this.drawTopIcon||this.hideNavIcons){this.toTopIcon.dom.style.display="none"}if(!this.drawBotIcon||this.hideNavIcons){this.toBottomIcon.dom.style.display="none"}var b=g.body.first();this.el.setWidth(g.body.first().getWidth());g.body.removeClass();this.hiddenName=this.name;var e={tag:"input",type:"hidden",value:"",name:this.name};this.hiddenField=this.el.createChild(e)},doLayout:function(){if(this.rendered){this.fromMultiselect.fs.doLayout();this.toMultiselect.fs.doLayout()}},afterRender:function(){Ext.ux.form.ItemSelector.superclass.afterRender.call(this);this.toStore=this.toMultiselect.store;this.toStore.on("add",this.valueChanged,this);this.toStore.on("remove",this.valueChanged,this);this.toStore.on("load",this.valueChanged,this);this.valueChanged(this.toStore)},toTop:function(){var c=this.toMultiselect.view.getSelectedIndexes();var a=[];if(c.length>0){c.sort();for(var b=0;b-1;b--){record=a[b];this.toMultiselect.view.store.remove(record);this.toMultiselect.view.store.insert(0,record);c.push(((a.length-1)-b))}}this.toMultiselect.view.refresh();this.toMultiselect.view.select(c)},toBottom:function(){var c=this.toMultiselect.view.getSelectedIndexes();var a=[];if(c.length>0){c.sort();for(var b=0;b0){for(var b=0;b=0){this.toMultiselect.view.store.remove(a);this.toMultiselect.view.store.insert(c[b]-1,a);d.push(c[b]-1)}}this.toMultiselect.view.refresh();this.toMultiselect.view.select(d)}},down:function(){var a=null;var c=this.toMultiselect.view.getSelectedIndexes();c.sort();c.reverse();var d=[];if(c.length>0){for(var b=0;b0){for(var d=0;d0){for(var c=0;c','
    ','
    {lockedHeader}
    ','
    {lockedBody}
    ',"
    ",'
    ','
    {header}
    ','
    {body}
    ',"
    ",'
     
    ','
     
    ',"")}this.templates=a;Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this)},getEditorParent:function(a){return this.el.dom},initElements:function(){var c=Ext.Element,b=this.grid.getGridEl().dom.firstChild,a=b.childNodes;this.el=new c(b);this.lockedWrap=new c(a[0]);this.lockedHd=new c(this.lockedWrap.dom.firstChild);this.lockedInnerHd=this.lockedHd.dom.firstChild;this.lockedScroller=new c(this.lockedWrap.dom.childNodes[1]);this.lockedBody=new c(this.lockedScroller.dom.firstChild);this.mainWrap=new c(a[1]);this.mainHd=new c(this.mainWrap.dom.firstChild);if(this.grid.hideHeaders){this.lockedHd.setDisplayed(false);this.mainHd.setDisplayed(false)}this.innerHd=this.mainHd.dom.firstChild;this.scroller=new c(this.mainWrap.dom.childNodes[1]);if(this.forceFit){this.scroller.setStyle("overflow-x","hidden")}this.mainBody=new c(this.scroller.dom.firstChild);this.focusEl=new c(this.scroller.dom.childNodes[1]);this.resizeMarker=new c(a[2]);this.resizeProxy=new c(a[3]);this.focusEl.swallowEvent("click",true)},getLockedRows:function(){return this.hasRows()?this.lockedBody.dom.childNodes:[]},getLockedRow:function(a){return this.getLockedRows()[a]},getCell:function(c,a){var b=this.cm.getLockedCount();if(af){a.setHeight(h)}else{if(f>h){b.setHeight(f)}}}}if(k===0){Ext.fly(m[0]).addClass(this.firstRowCls);Ext.fly(e[0]).addClass(this.firstRowCls)}Ext.fly(m[m.length-1]).addClass(this.lastRowCls);Ext.fly(e[e.length-1]).addClass(this.lastRowCls)},afterRender:function(){if(!this.ds||!this.cm){return}var a=this.renderRows()||[" "," "];this.mainBody.dom.innerHTML=a[0];this.lockedBody.dom.innerHTML=a[1];this.processRows(0,true);if(this.deferEmptyText!==true){this.applyEmptyText()}},renderUI:function(){var d=this.renderHeaders();var a=this.templates.body.apply({rows:" "});var b=this.templates.master.apply({body:a,header:d[0],ostyle:"width:"+this.getOffsetWidth()+";",bstyle:"width:"+this.getTotalWidth()+";",lockedBody:a,lockedHeader:d[1],lstyle:"width:"+this.getLockedWidth()+";"});var c=this.grid;c.getGridEl().dom.innerHTML=b;this.initElements();Ext.fly(this.innerHd).on("click",this.handleHdDown,this);Ext.fly(this.lockedInnerHd).on("click",this.handleHdDown,this);this.mainHd.on({scope:this,mouseover:this.handleHdOver,mouseout:this.handleHdOut,mousemove:this.handleHdMove});this.lockedHd.on({scope:this,mouseover:this.handleHdOver,mouseout:this.handleHdOut,mousemove:this.handleHdMove});this.scroller.on("scroll",this.syncScroll,this);if(c.enableColumnResize!==false){this.splitZone=new Ext.grid.GridView.SplitDragZone(c,this.mainHd.dom);this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom))}if(c.enableColumnMove){this.columnDrag=new Ext.grid.GridView.ColumnDragZone(c,this.innerHd);this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));this.columnDrop=new Ext.grid.HeaderDropZone(c,this.mainHd.dom)}if(c.enableHdMenu!==false){this.hmenu=new Ext.menu.Menu({id:c.id+"-hctx"});this.hmenu.add({itemId:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},{itemId:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"});if(this.grid.enableColLock!==false){this.hmenu.add("-",{itemId:"lock",text:this.lockText,cls:"xg-hmenu-lock"},{itemId:"unlock",text:this.unlockText,cls:"xg-hmenu-unlock"})}if(c.enableColumnHide!==false){this.colMenu=new Ext.menu.Menu({id:c.id+"-hcols-menu"});this.colMenu.on({scope:this,beforeshow:this.beforeColMenuShow,itemclick:this.handleHdMenuClick});this.hmenu.add("-",{itemId:"columns",hideOnClick:false,text:this.columnsText,menu:this.colMenu,iconCls:"x-cols-icon"})}this.hmenu.on("itemclick",this.handleHdMenuClick,this)}if(c.trackMouseOver){this.mainBody.on({scope:this,mouseover:this.onRowOver,mouseout:this.onRowOut});this.lockedBody.on({scope:this,mouseover:this.onRowOver,mouseout:this.onRowOut})}if(c.enableDragDrop||c.enableDrag){this.dragZone=new Ext.grid.GridDragZone(c,{ddGroup:c.ddGroup||"GridDD"})}this.updateHeaderSortState()},layout:function(){if(!this.mainBody){return}var d=this.grid;var h=d.getGridEl();var a=h.getSize(true);var b=a.width;if(!d.hideHeaders&&(b<20||a.height<20)){return}this.syncHeaderHeight();if(d.autoHeight){this.scroller.dom.style.overflow="visible";this.lockedScroller.dom.style.overflow="visible";if(Ext.isWebKit){this.scroller.dom.style.position="static";this.lockedScroller.dom.style.position="static"}}else{this.el.setSize(a.width,a.height);var f=this.mainHd.getHeight();var e=a.height-(f)}this.updateLockedWidth();if(this.forceFit){if(this.lastViewWidth!=b){this.fitColumns(false,false);this.lastViewWidth=b}}else{this.autoExpand();this.syncHeaderScroll()}this.onLayout(b,e)},getOffsetWidth:function(){return(this.cm.getTotalWidth()-this.cm.getTotalLockedWidth()+this.getScrollOffset())+"px"},renderHeaders:function(){var h=this.cm,f=this.templates,d=f.hcell,b=[],g=[],a={},e=h.getColumnCount(),j=e-1;for(var c=0;c=c){this.refresh()}else{if(!f){this.fireEvent("beforerowsinserted",this,g,d)}var b=this.renderRows(g,d),e=this.getRow(g);if(e){if(g===0){this.removeRowClass(0,this.firstRowCls)}Ext.DomHelper.insertHtml("beforeBegin",e,b[0]);e=this.getLockedRow(g);Ext.DomHelper.insertHtml("beforeBegin",e,b[1])}else{this.removeRowClass(c-1,this.lastRowCls);Ext.DomHelper.insertHtml("beforeEnd",this.mainBody.dom,b[0]);Ext.DomHelper.insertHtml("beforeEnd",this.lockedBody.dom,b[1])}if(!f){this.fireEvent("rowsinserted",this,g,d);this.processRows(g)}else{if(g===0||g>=c){this.addRowClass(g,g===0?this.firstRowCls:this.lastRowCls)}}}this.syncFocusEl(g)},getColumnStyle:function(a,c){var b=!c?this.cm.config[a].cellStyle||this.cm.config[a].css||"":this.cm.config[a].headerStyle||"";b+="width:"+this.getColumnWidth(a)+";";if(this.cm.isHidden(a)){b+="display:none;"}var d=this.cm.config[a].align;if(d){b+="text-align:"+d+";"}return b},getLockedWidth:function(){return this.cm.getTotalLockedWidth()+"px"},getTotalWidth:function(){return(this.cm.getTotalWidth()-this.cm.getTotalLockedWidth())+"px"},getColumnData:function(){var d=[],a=this.cm,e=a.getColumnCount();for(var c=0;cc?b:c)+"px";this.innerHd.firstChild.firstChild.style.height=a;this.lockedInnerHd.firstChild.firstChild.style.height=a},updateLockedWidth:function(){var g=this.cm.getTotalLockedWidth(),a=this.cm.getTotalWidth()-g,c=this.grid.getGridEl().getSize(true),b=Ext.isBorderBox?0:this.lockedBorderWidth,d=Ext.isBorderBox?0:this.rowBorderWidth,e=(c.width-g-b-d)+"px",f=this.getScrollOffset();if(!this.grid.autoHeight){var h=(c.height-this.mainHd.getHeight())+"px";this.lockedScroller.dom.style.height=h;this.scroller.dom.style.height=h}this.lockedWrap.dom.style.width=(g+d)+"px";this.scroller.dom.style.width=e;this.mainWrap.dom.style.left=(g+b+d)+"px";if(this.innerHd){this.lockedInnerHd.firstChild.style.width=g+"px";this.lockedInnerHd.firstChild.firstChild.style.width=g+"px";this.innerHd.style.width=e;this.innerHd.firstChild.style.width=(a+d+f)+"px";this.innerHd.firstChild.firstChild.style.width=a+"px"}if(this.mainBody){this.lockedBody.dom.style.width=(g+d)+"px";this.mainBody.dom.style.width=(a+d)+"px"}}});Ext.ux.grid.LockingColumnModel=Ext.extend(Ext.grid.ColumnModel,{isLocked:function(a){return this.config[a].locked===true},setLocked:function(b,c,a){if(this.isLocked(b)==c){return}this.config[b].locked=c;if(!a){this.fireEvent("columnlockchange",this,b,c)}},getTotalLockedWidth:function(){var b=0;for(var c=0,a=this.config.length;cc&&!a&&b){this.setLocked(d,true,true)}}Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this,arguments)}});Ext.ns("Ext.ux.form");Ext.ux.form.MultiSelect=Ext.extend(Ext.form.Field,{ddReorder:false,appendOnly:false,width:100,height:100,displayField:0,valueField:1,allowBlank:true,minSelections:0,maxSelections:Number.MAX_VALUE,blankText:Ext.form.TextField.prototype.blankText,minSelectionsText:"Minimum {0} item(s) required",maxSelectionsText:"Maximum {0} item(s) allowed",delimiter:",",defaultAutoCreate:{tag:"div"},initComponent:function(){Ext.ux.form.MultiSelect.superclass.initComponent.call(this);if(Ext.isArray(this.store)){if(Ext.isArray(this.store[0])){this.store=new Ext.data.ArrayStore({fields:["value","text"],data:this.store});this.valueField="value"}else{this.store=new Ext.data.ArrayStore({fields:["text"],data:this.store,expandData:true});this.valueField="text"}this.displayField="text"}else{this.store=Ext.StoreMgr.lookup(this.store)}this.addEvents({dblclick:true,click:true,change:true,drop:true})},onRender:function(c,b){Ext.ux.form.MultiSelect.superclass.onRender.call(this,c,b);var a=this.fs=new Ext.form.FieldSet({renderTo:this.el,title:this.legend,height:this.height,width:this.width,style:"padding:0;",tbar:this.tbar});a.body.addClass("ux-mselect");this.view=new Ext.ListView({multiSelect:true,store:this.store,columns:[{header:"Value",width:1,dataIndex:this.displayField}],hideHeaders:true});a.add(this.view);this.view.on("click",this.onViewClick,this);this.view.on("beforeclick",this.onViewBeforeClick,this);this.view.on("dblclick",this.onViewDblClick,this);this.hiddenName=this.name||Ext.id();var d={tag:"input",type:"hidden",value:"",name:this.hiddenName};this.hiddenField=this.el.createChild(d);this.hiddenField.dom.disabled=this.hiddenName!=this.name;a.doLayout()},afterRender:function(){Ext.ux.form.MultiSelect.superclass.afterRender.call(this);if(this.ddReorder&&!this.dragGroup&&!this.dropGroup){this.dragGroup=this.dropGroup="MultiselectDD-"+Ext.id()}if(this.draggable||this.dragGroup){this.dragZone=new Ext.ux.form.MultiSelect.DragZone(this,{ddGroup:this.dragGroup})}if(this.droppable||this.dropGroup){this.dropZone=new Ext.ux.form.MultiSelect.DropZone(this,{ddGroup:this.dropGroup})}},onViewClick:function(c,a,b,d){this.fireEvent("change",this,this.getValue(),this.hiddenField.dom.value);this.hiddenField.dom.value=this.getValue();this.fireEvent("click",this,d);this.validate()},onViewBeforeClick:function(c,a,b,d){if(this.disabled||this.readOnly){return false}},onViewDblClick:function(c,a,b,d){return this.fireEvent("dblclick",c,a,b,d)},getValue:function(a){var d=[];var c=this.view.getSelectedIndexes();if(c.length==0){return""}for(var b=0;bthis.maxSelections){this.markInvalid(String.format(this.maxSelectionsText,this.maxSelections));return false}return true},disable:function(){this.disabled=true;this.hiddenField.dom.disabled=true;this.fs.disable()},enable:function(){this.disabled=false;this.hiddenField.dom.disabled=false;this.fs.enable()},destroy:function(){Ext.destroy(this.fs,this.dragZone,this.dropZone);Ext.ux.form.MultiSelect.superclass.destroy.call(this)}});Ext.reg("multiselect",Ext.ux.form.MultiSelect);Ext.ux.Multiselect=Ext.ux.form.MultiSelect;Ext.ux.form.MultiSelect.DragZone=function(d,c){this.ms=d;this.view=d.view;var b=c.ddGroup||"MultiselectDD";var a;if(Ext.isArray(b)){a=b.shift()}else{a=b;b=null}Ext.ux.form.MultiSelect.DragZone.superclass.constructor.call(this,this.ms.fs.body,{containerScroll:true,ddGroup:a});this.setDraggable(b)};Ext.extend(Ext.ux.form.MultiSelect.DragZone,Ext.dd.DragZone,{onInitDrag:function(a,c){var b=Ext.get(this.dragData.ddel.cloneNode(true));this.proxy.update(b.dom);b.setWidth(b.child("em").getWidth());this.onStartDrag(a,c);return true},collectSelection:function(b){b.repairXY=Ext.fly(this.view.getSelectedNodes()[0]).getXY();var a=0;this.view.store.each(function(d){if(this.view.isSelected(a)){var e=this.view.getNode(a);var c=e.cloneNode(true);c.id=Ext.id();b.ddel.appendChild(c);b.records.push(this.view.store.getAt(a));b.viewNodes.push(e)}a++},this)},onEndDrag:function(a,b){var c=Ext.get(this.dragData.ddel);if(c&&c.hasClass("multi-proxy")){c.remove()}},getDragData:function(d){var c=this.view.findItemFromChild(d.getTarget());if(c){if(!this.view.isSelected(c)&&!d.ctrlKey&&!d.shiftKey){this.view.select(c);this.ms.setValue(this.ms.getValue())}if(this.view.getSelectionCount()==0||d.ctrlKey||d.shiftKey){return false}var b={sourceView:this.view,viewNodes:[],records:[]};if(this.view.getSelectionCount()==1){var a=this.view.getSelectedIndexes()[0];var f=this.view.getNode(a);b.viewNodes.push(b.ddel=f);b.records.push(this.view.store.getAt(a));b.repairXY=Ext.fly(f).getXY()}else{b.ddel=document.createElement("div");b.ddel.className="multi-proxy";this.collectSelection(b)}return b}return false},getRepairXY:function(a){return this.dragData.repairXY},setDraggable:function(a){if(!a){return}if(Ext.isArray(a)){Ext.each(a,this.setDraggable,this);return}this.addToGroup(a)}});Ext.ux.form.MultiSelect.DropZone=function(d,c){this.ms=d;this.view=d.view;var b=c.ddGroup||"MultiselectDD";var a;if(Ext.isArray(b)){a=b.shift()}else{a=b;b=null}Ext.ux.form.MultiSelect.DropZone.superclass.constructor.call(this,this.ms.fs.body,{containerScroll:true,ddGroup:a});this.setDroppable(b)};Ext.extend(Ext.ux.form.MultiSelect.DropZone,Ext.dd.DropZone,{getTargetFromEvent:function(b){var a=b.getTarget();return a},getDropPoint:function(g,k,d){if(k==this.ms.fs.body.dom){return"below"}var f=Ext.lib.Dom.getY(k),a=f+k.offsetHeight;var j=f+(a-f)/2;var h=Ext.lib.Event.getPageY(g);if(h<=j){return"above"}else{return"below"}},isValidDropPoint:function(b,e,a){if(!a.viewNodes||(a.viewNodes.length!=1)){return true}var c=a.viewNodes[0];if(c==e){return false}if((b=="below")&&(e.nextSibling==c)){return false}if((b=="above")&&(e.previousSibling==c)){return false}return true},onNodeEnter:function(d,a,c,b){return false},onNodeOver:function(h,a,g,d){var b=this.dropNotAllowed;var f=this.getDropPoint(g,h,a);if(this.isValidDropPoint(f,h,d)){if(this.ms.appendOnly){return"x-tree-drop-ok-below"}if(f){var c;if(f=="above"){b=h.previousSibling?"x-tree-drop-ok-between":"x-tree-drop-ok-above";c="x-view-drag-insert-above"}else{b=h.nextSibling?"x-tree-drop-ok-between":"x-tree-drop-ok-below";c="x-view-drag-insert-below"}if(this.lastInsertClass!=c){Ext.fly(h).replaceClass(this.lastInsertClass,c);this.lastInsertClass=c}}}return b},onNodeOut:function(d,a,c,b){this.removeDropIndicators(d)},onNodeDrop:function(b,j,h,f){if(this.ms.fireEvent("drop",this,b,j,h,f)===false){return false}var k=this.getDropPoint(h,b,j);if(b!=this.ms.fs.body.dom){b=this.view.findItemFromChild(b)}if(this.ms.appendOnly){insertAt=this.view.store.getCount()}else{insertAt=b==this.ms.fs.body.dom?this.view.store.getCount()-1:this.view.indexOf(b);if(k=="below"){insertAt++}}var c=false;if(f.sourceView==this.view){if(k=="below"){if(f.viewNodes[0]==b){f.viewNodes.shift()}}else{if(f.viewNodes[f.viewNodes.length-1]==b){f.viewNodes.pop()}}if(!f.viewNodes.length){return false}if(insertAt>this.view.store.indexOf(f.records[0])){c="down";insertAt--}}for(var g=0;ge?1:(nf[1]){l=true;break}}}j=(l&&r?j:v.items.getCount())+(k?-1:0);var g=this.createEvent(w,u,x,d,v,j);if(a.fireEvent("validatedrop",g)!==false&&a.fireEvent("beforedragover",g)!==false){o.getProxy().setWidth("auto");if(r){o.moveProxy(r.el.dom.parentNode,l?r.el.dom:null)}else{o.moveProxy(v.el.dom,null)}this.lastPos={c:v,col:d,p:k||(l&&r)?j:false};this.scrollPos=a.body.getScroll();a.fireEvent("dragover",g);return g.status}else{return g.status}},notifyOut:function(){delete this.grid},notifyDrop:function(m,h,g){delete this.grid;if(!this.lastPos){return}var k=this.lastPos.c,f=this.lastPos.col,l=this.lastPos.p,a=m.panel,b=this.createEvent(m,h,g,f,k,l!==false?l:k.items.getCount());if(this.portal.fireEvent("validatedrop",b)!==false&&this.portal.fireEvent("beforedrop",b)!==false){m.proxy.getProxy().remove();a.el.dom.parentNode.removeChild(m.panel.el.dom);if(l!==false){k.insert(l,a)}else{k.add(a)}k.doLayout();this.portal.fireEvent("drop",b);var n=this.scrollPos.top;if(n){var j=this.portal.body.dom;setTimeout(function(){j.scrollTop=n},10)}}delete this.lastPos},getGrid:function(){var a=this.portal.bwrap.getBox();a.columnX=[];this.portal.items.each(function(b){a.columnX.push({x:b.el.getX(),w:b.el.getWidth()})});return a},unreg:function(){Ext.dd.ScrollManager.unregister(this.portal.body);Ext.ux.Portal.DropZone.superclass.unreg.call(this)}});Ext.ux.PortalColumn=Ext.extend(Ext.Container,{layout:"anchor",defaultType:"portlet",cls:"x-portal-column"});Ext.reg("portalcolumn",Ext.ux.PortalColumn);Ext.ux.Portlet=Ext.extend(Ext.Panel,{anchor:"100%",frame:true,collapsible:true,draggable:true,cls:"x-portlet"});Ext.reg("portlet",Ext.ux.Portlet);Ext.ux.ProgressBarPager=Ext.extend(Object,{progBarWidth:225,defaultText:"Loading...",defaultAnimCfg:{duration:1,easing:"bounceOut"},constructor:function(a){if(a){Ext.apply(this,a)}},init:function(a){if(a.displayInfo){this.parent=a;var b=a.items.indexOf(a.displayItem);a.remove(a.displayItem,true);this.progressBar=new Ext.ProgressBar({text:this.defaultText,width:this.progBarWidth,animate:this.defaultAnimCfg});a.displayItem=this.progressBar;a.add(a.displayItem);a.doLayout();Ext.apply(a,this.parentOverrides);this.progressBar.on("render",function(c){c.mon(c.getEl().applyStyles("cursor:pointer"),"click",this.handleProgressBarClick,this)},this,{single:true})}},handleProgressBarClick:function(j){var d=this.parent,c=d.displayItem,f=this.progressBar.getBox(),h=j.getXY(),b=h[0]-f.x,a=Math.ceil(d.store.getTotalCount()/d.pageSize),g=Math.ceil(b/(c.width/a));d.changePage(g)},parentOverrides:{updateInfo:function(){if(this.displayItem){var b=this.store.getCount(),a=this.getPageData(),d=this.readPage(a),e=b==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+b,this.store.getTotalCount());d=a.activePage;var c=d/a.pages;this.displayItem.updateProgress(c,e,this.animate||this.defaultAnimConfig)}}}});Ext.preg("progressbarpager",Ext.ux.ProgressBarPager);Ext.ns("Ext.ux.grid");Ext.ux.grid.RowEditor=Ext.extend(Ext.Panel,{floating:true,shadow:false,layout:"hbox",cls:"x-small-editor",buttonAlign:"center",baseCls:"x-row-editor",elements:"header,footer,body",frameWidth:5,buttonPad:3,clicksToEdit:"auto",monitorValid:true,focusDelay:250,errorSummary:true,saveText:"Save",cancelText:"Cancel",commitChangesText:"You need to commit or cancel your changes",errorText:"Errors",defaults:{normalWidth:true},initComponent:function(){Ext.ux.grid.RowEditor.superclass.initComponent.call(this);this.addEvents("beforeedit","canceledit","validateedit","afteredit")},init:function(a){this.grid=a;this.ownerCt=a;if(this.clicksToEdit===2){a.on("rowdblclick",this.onRowDblClick,this)}else{a.on("rowclick",this.onRowClick,this);if(Ext.isIE){a.on("rowdblclick",this.onRowDblClick,this)}}a.getStore().on("remove",function(){this.stopEditing(false)},this);a.on({scope:this,keydown:this.onGridKey,columnresize:this.verifyLayout,columnmove:this.refreshFields,reconfigure:this.refreshFields,beforedestroy:this.beforedestroy,destroy:this.destroy,bodyscroll:{buffer:250,fn:this.positionButtons}});a.getColumnModel().on("hiddenchange",this.verifyLayout,this,{delay:1});a.getView().on("refresh",this.stopEditing.createDelegate(this,[]))},beforedestroy:function(){this.stopMonitoring();this.grid.getStore().un("remove",this.onStoreRemove,this);this.stopEditing(false);Ext.destroy(this.btns,this.tooltip)},refreshFields:function(){this.initFields();this.verifyLayout()},isDirty:function(){var a;this.items.each(function(b){if(String(this.values[b.id])!==String(b.getValue())){a=true;return false}},this);return a},startEditing:function(k,p){if(this.editing&&this.isDirty()){this.showTooltip(this.commitChangesText);return}if(Ext.isObject(k)){k=this.grid.getStore().indexOf(k)}if(this.fireEvent("beforeedit",this,k)!==false){this.editing=true;var e=this.grid,l=e.getView(),o=l.getRow(k),c=e.store.getAt(k);this.record=c;this.rowIndex=k;this.values={};if(!this.rendered){this.render(l.getEditorParent())}var m=Ext.fly(o).getWidth();this.setSize(m);if(!this.initialized){this.initFields()}var n=e.getColumnModel(),d=this.items.items,j,a;for(var b=0,h=n.getColumnCount();b=h){d=b;break}}}return d},startMonitoring:function(){if(!this.bound&&this.monitorValid){this.bound=true;Ext.TaskMgr.start({run:this.bindHandler,interval:this.monitorPoll||200,scope:this})}},stopMonitoring:function(){this.bound=false;if(this.tooltip){this.tooltip.hide()}},isValid:function(){var a=true;this.items.each(function(b){if(!b.isValid(true)){a=false;return false}});return a},bindHandler:function(){if(!this.bound){return false}var a=this.isValid();if(!a&&this.errorSummary){this.showTooltip(this.getErrorText().join(""))}this.btns.saveBtn.setDisabled(!a);this.fireEvent("validation",this,a)},lastVisibleColumn:function(){var a=this.items.getCount()-1,b;for(;a>=0;a--){b=this.items.items[a];if(!b.hidden){return b}}},showTooltip:function(f){var c=this.tooltip;if(!c){c=this.tooltip=new Ext.ToolTip({maxWidth:600,cls:"errorTip",width:300,title:this.errorText,autoHide:false,anchor:"left",anchorToTarget:true,mouseOffset:[40,0]})}var b=this.grid.getView(),e=parseInt(this.el.dom.style.top,10),a=b.scroller.dom.scrollTop,d=this.el.getHeight();if(e+d>=a){c.initTarget(this.lastVisibleColumn().getEl());if(!c.rendered){c.show();c.hide()}c.body.update(f);c.doAutoWidth(20);c.show()}else{if(c.rendered){c.hide()}}},getErrorText:function(){var a=["
      "];this.items.each(function(b){if(!b.isValid(true)){a.push("
    • ",b.getActiveError(),"
    • ")}});a.push("
    ");return a}});Ext.preg("roweditor",Ext.ux.grid.RowEditor);Ext.ns("Ext.ux.grid");Ext.ux.grid.RowExpander=Ext.extend(Ext.util.Observable,{expandOnEnter:true,expandOnDblClick:true,header:"",width:20,sortable:false,fixed:true,hideable:false,menuDisabled:true,dataIndex:"",id:"expander",lazyRender:true,enableCaching:true,constructor:function(a){Ext.apply(this,a);this.addEvents({beforeexpand:true,expand:true,beforecollapse:true,collapse:true});Ext.ux.grid.RowExpander.superclass.constructor.call(this);if(this.tpl){if(typeof this.tpl=="string"){this.tpl=new Ext.Template(this.tpl)}this.tpl.compile()}this.state={};this.bodyContent={}},getRowClass:function(a,e,d,c){d.cols=d.cols-1;var b=this.bodyContent[a.id];if(!b&&!this.lazyRender){b=this.getBodyContent(a,e)}if(b){d.body=b}return this.state[a.id]?"x-grid3-row-expanded":"x-grid3-row-collapsed"},init:function(b){this.grid=b;var a=b.getView();a.getRowClass=this.getRowClass.createDelegate(this);a.enableRowBody=true;b.on("render",this.onRender,this);b.on("destroy",this.onDestroy,this)},onRender:function(){var a=this.grid;var b=a.getView().mainBody;b.on("mousedown",this.onMouseDown,this,{delegate:".x-grid3-row-expander"});if(this.expandOnEnter){this.keyNav=new Ext.KeyNav(this.grid.getGridEl(),{enter:this.onEnter,scope:this})}if(this.expandOnDblClick){a.on("rowdblclick",this.onRowDblClick,this)}},onDestroy:function(){if(this.keyNav){this.keyNav.disable();delete this.keyNav}var a=this.grid.getView().mainBody;if(a){a.un("mousedown",this.onMouseDown,this)}},onRowDblClick:function(a,b,c){this.toggleRow(b)},onEnter:function(h){var f=this.grid;var j=f.getSelectionModel();var b=j.getSelections();for(var c=0,a=b.length;c '},beforeExpand:function(b,a,c){if(this.fireEvent("beforeexpand",this,b,a,c)!==false){if(this.tpl&&this.lazyRender){a.innerHTML=this.getBodyContent(b,c)}return true}else{return false}},toggleRow:function(a){if(typeof a=="number"){a=this.grid.view.getRow(a)}this[Ext.fly(a).hasClass("x-grid3-row-collapsed")?"expandRow":"collapseRow"](a)},expandRow:function(c){if(typeof c=="number"){c=this.grid.view.getRow(c)}var b=this.grid.store.getAt(c.rowIndex);var a=Ext.DomQuery.selectNode("tr:nth(2) div.x-grid3-row-body",c);if(this.beforeExpand(b,a,c.rowIndex)){this.state[b.id]=true;Ext.fly(c).replaceClass("x-grid3-row-collapsed","x-grid3-row-expanded");this.fireEvent("expand",this,b,a,c.rowIndex)}},collapseRow:function(c){if(typeof c=="number"){c=this.grid.view.getRow(c)}var b=this.grid.store.getAt(c.rowIndex);var a=Ext.fly(c).child("tr:nth(1) div.x-grid3-row-body",true);if(this.fireEvent("beforecollapse",this,b,a,c.rowIndex)!==false){this.state[b.id]=false;Ext.fly(c).replaceClass("x-grid3-row-expanded","x-grid3-row-collapsed");this.fireEvent("collapse",this,b,a,c.rowIndex)}}});Ext.preg("rowexpander",Ext.ux.grid.RowExpander);Ext.grid.RowExpander=Ext.ux.grid.RowExpander;Ext.ns("Ext.ux.layout");Ext.ux.layout.RowLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"row",allowContainerRemove:false,isValidParent:function(b,a){return this.innerCt&&b.getPositionEl().dom.parentNode==this.innerCt.dom},getLayoutTargetSize:function(){var b=this.container.getLayoutTarget(),a;if(b){a=b.getViewSize();if(Ext.isIE&&Ext.isStrict&&a.height==0){a=b.getStyleSize()}a.width-=b.getPadding("lr");a.height-=b.getPadding("tb")}return a},renderAll:function(a,b){if(!this.innerCt){this.innerCt=b.createChild({cls:"x-column-inner"});this.innerCt.createChild({cls:"x-clear"})}Ext.layout.ColumnLayout.superclass.renderAll.call(this,a,this.innerCt)},onLayout:function(g,k){var c=g.items.items,j=c.length,a,b,d,n=[];this.renderAll(g,k);var o=this.getLayoutTargetSize();if(o.width<1&&o.height<1){return}var e=o.height,f=e;this.innerCt.setSize({height:e});for(d=0;d{0}
    of {1}",d.value,d.slider.maxValue)}}),listeners:{changecomplete:function(e,d){b.changePage(d)}}});b.insert(a+1,c);b.on({change:function(d,e){c.setMaxValue(e.pages);c.setValue(e.activePage)}})}});Ext.ns("Ext.ux.form");Ext.ux.form.SpinnerField=Ext.extend(Ext.form.NumberField,{actionMode:"wrap",deferHeight:true,autoSize:Ext.emptyFn,onBlur:Ext.emptyFn,adjustSize:Ext.BoxComponent.prototype.adjustSize,constructor:function(c){var b=Ext.copyTo({},c,"incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass");var d=this.spinner=new Ext.ux.Spinner(b);var a=c.plugins?(Ext.isArray(c.plugins)?c.plugins.push(d):[c.plugins,d]):d;Ext.ux.form.SpinnerField.superclass.constructor.call(this,Ext.apply(c,{plugins:a}))},getResizeEl:function(){return this.wrap},getPositionEl:function(){return this.wrap},alignErrorIcon:function(){if(this.wrap){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}},validateBlur:function(){return true}});Ext.reg("spinnerfield",Ext.ux.form.SpinnerField);Ext.form.SpinnerField=Ext.ux.form.SpinnerField;Ext.ux.Spinner=Ext.extend(Ext.util.Observable,{incrementValue:1,alternateIncrementValue:5,triggerClass:"x-form-spinner-trigger",splitterClass:"x-form-spinner-splitter",alternateKey:Ext.EventObject.shiftKey,defaultValue:0,accelerate:false,constructor:function(a){Ext.ux.Spinner.superclass.constructor.call(this,a);Ext.apply(this,a);this.mimicing=false},init:function(a){this.field=a;a.afterMethod("onRender",this.doRender,this);a.afterMethod("onEnable",this.doEnable,this);a.afterMethod("onDisable",this.doDisable,this);a.afterMethod("afterRender",this.doAfterRender,this);a.afterMethod("onResize",this.doResize,this);a.afterMethod("onFocus",this.doFocus,this);a.beforeMethod("onDestroy",this.doDestroy,this)},doRender:function(b,a){var c=this.el=this.field.getEl();var d=this.field;if(!d.wrap){d.wrap=this.wrap=c.wrap({cls:"x-form-field-wrap"})}else{this.wrap=d.wrap.addClass("x-form-field-wrap")}this.trigger=this.wrap.createChild({tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});if(!d.width){this.wrap.setWidth(c.getWidth()+this.trigger.getWidth())}this.splitter=this.wrap.createChild({tag:"div",cls:this.splitterClass,style:"width:13px; height:2px;"});this.splitter.setRight((Ext.isIE)?1:2).setTop(10).show();this.proxy=this.trigger.createProxy("",this.splitter,true);this.proxy.addClass("x-form-spinner-proxy");this.proxy.setStyle("left","0px");this.proxy.setSize(14,1);this.proxy.hide();this.dd=new Ext.dd.DDProxy(this.splitter.dom.id,"SpinnerDrag",{dragElId:this.proxy.id});this.initTrigger();this.initSpinner()},doAfterRender:function(){var a;if(Ext.isIE&&this.el.getY()!=(a=this.trigger.getY())){this.el.position();this.el.setY(a)}},doEnable:function(){if(this.wrap){this.wrap.removeClass(this.field.disabledClass)}},doDisable:function(){if(this.wrap){this.wrap.addClass(this.field.disabledClass);this.el.removeClass(this.field.disabledClass)}},doResize:function(a,b){if(typeof a=="number"){this.el.setWidth(a-this.trigger.getWidth())}this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())},doFocus:function(){if(!this.mimicing){this.wrap.addClass("x-trigger-wrap-focus");this.mimicing=true;Ext.get(Ext.isIE?document.body:document).on("mousedown",this.mimicBlur,this,{delay:10});this.el.on("keydown",this.checkTab,this)}},checkTab:function(a){if(a.getKey()==a.TAB){this.triggerBlur()}},mimicBlur:function(a){if(!this.wrap.contains(a.target)&&this.field.validateBlur(a)){this.triggerBlur()}},triggerBlur:function(){this.mimicing=false;Ext.get(Ext.isIE?document.body:document).un("mousedown",this.mimicBlur,this);this.el.un("keydown",this.checkTab,this);this.field.beforeBlur();this.wrap.removeClass("x-trigger-wrap-focus");this.field.onBlur.call(this.field)},initTrigger:function(){this.trigger.addClassOnOver("x-form-trigger-over");this.trigger.addClassOnClick("x-form-trigger-click")},initSpinner:function(){this.field.addEvents({spin:true,spinup:true,spindown:true});this.keyNav=new Ext.KeyNav(this.el,{up:function(a){a.preventDefault();this.onSpinUp()},down:function(a){a.preventDefault();this.onSpinDown()},pageUp:function(a){a.preventDefault();this.onSpinUpAlternate()},pageDown:function(a){a.preventDefault();this.onSpinDownAlternate()},scope:this});this.repeater=new Ext.util.ClickRepeater(this.trigger,{accelerate:this.accelerate});this.field.mon(this.repeater,"click",this.onTriggerClick,this,{preventDefault:true});this.field.mon(this.trigger,{mouseover:this.onMouseOver,mouseout:this.onMouseOut,mousemove:this.onMouseMove,mousedown:this.onMouseDown,mouseup:this.onMouseUp,scope:this,preventDefault:true});this.field.mon(this.wrap,"mousewheel",this.handleMouseWheel,this);this.dd.setXConstraint(0,0,10);this.dd.setYConstraint(1500,1500,10);this.dd.endDrag=this.endDrag.createDelegate(this);this.dd.startDrag=this.startDrag.createDelegate(this);this.dd.onDrag=this.onDrag.createDelegate(this)},onMouseOver:function(){if(this.disabled){return}var a=this.getMiddle();this.tmpHoverClass=(Ext.EventObject.getPageY()a)&&this.tmpHoverClass=="x-form-spinner-overup")||((Ext.EventObject.getPageY()0){this.onSpinUp();a.stopEvent()}else{if(b<0){this.onSpinDown();a.stopEvent()}}},startDrag:function(){this.proxy.show();this._previousY=Ext.fly(this.dd.getDragEl()).getTop()},endDrag:function(){this.proxy.hide()},onDrag:function(){if(this.disabled){return}var b=Ext.fly(this.dd.getDragEl()).getTop();var a="";if(this._previousY>b){a="Up"}if(this._previousYthis.field.maxValue){a=this.field.maxValue}return this.fixPrecision(a)},fixPrecision:function(b){var a=isNaN(b);if(!this.field.allowDecimals||this.field.decimalPrecision==-1||a||!b){return a?"":b}return parseFloat(parseFloat(b).toFixed(this.field.decimalPrecision))},doDestroy:function(){if(this.trigger){this.trigger.remove()}if(this.wrap){this.wrap.remove();delete this.field.wrap}if(this.splitter){this.splitter.remove()}if(this.dd){this.dd.unreg();this.dd=null}if(this.proxy){this.proxy.remove()}if(this.repeater){this.repeater.purgeListeners()}}});Ext.form.Spinner=Ext.ux.Spinner;Ext.ux.Spotlight=function(a){Ext.apply(this,a)};Ext.ux.Spotlight.prototype={active:false,animate:true,duration:0.25,easing:"easeNone",animated:false,createElements:function(){var a=Ext.getBody();this.right=a.createChild({cls:"x-spotlight"});this.left=a.createChild({cls:"x-spotlight"});this.top=a.createChild({cls:"x-spotlight"});this.bottom=a.createChild({cls:"x-spotlight"});this.all=new Ext.CompositeElement([this.right,this.left,this.top,this.bottom])},show:function(b,c,a){if(this.animated){this.show.defer(50,this,[b,c,a]);return}this.el=Ext.get(b);if(!this.right){this.createElements()}if(!this.active){this.all.setDisplayed("");this.applyBounds(true,false);this.active=true;Ext.EventManager.onWindowResize(this.syncSize,this);this.applyBounds(false,this.animate,false,c,a)}else{this.applyBounds(false,false,false,c,a)}},hide:function(b,a){if(this.animated){this.hide.defer(50,this,[b,a]);return}Ext.EventManager.removeResizeListener(this.syncSize,this);this.applyBounds(true,this.animate,true,b,a)},doHide:function(){this.active=false;this.all.setDisplayed(false)},syncSize:function(){this.applyBounds(false,false)},applyBounds:function(e,d,k,j,l){var h=this.el.getRegion();var a=Ext.lib.Dom.getViewWidth(true);var g=Ext.lib.Dom.getViewHeight(true);var f=0,b=false;if(d){b={callback:function(){f++;if(f==4){this.animated=false;if(k){this.doHide()}Ext.callback(j,l,[this])}},scope:this,duration:this.duration,easing:this.easing};this.animated=true}this.right.setBounds(h.right,e?g:h.top,a-h.right,e?0:(g-h.top),b);this.left.setBounds(0,0,h.left,e?0:h.bottom,b);this.top.setBounds(e?a:h.left,0,e?0:a-h.left,h.top,b);this.bottom.setBounds(0,h.bottom,e?0:h.right,g-h.bottom,b);if(!d){if(k){this.doHide()}if(j){Ext.callback(j,l,[this])}}},destroy:function(){this.doHide();Ext.destroy(this.right,this.left,this.top,this.bottom);delete this.el;delete this.all}};Ext.Spotlight=Ext.ux.Spotlight;Ext.ux.StatusBar=Ext.extend(Ext.Toolbar,{cls:"x-statusbar",busyIconCls:"x-status-busy",busyText:"Loading...",autoClear:5000,emptyText:" ",activeThreadId:0,initComponent:function(){if(this.statusAlign=="right"){this.cls+=" x-status-right"}Ext.ux.StatusBar.superclass.initComponent.call(this)},afterRender:function(){Ext.ux.StatusBar.superclass.afterRender.call(this);var a=this.statusAlign=="right";this.currIconCls=this.iconCls||this.defaultIconCls;this.statusEl=new Ext.Toolbar.TextItem({cls:"x-status-text "+(this.currIconCls||""),text:this.text||this.defaultText||""});if(a){this.add("->");this.add(this.statusEl)}else{this.insert(0,this.statusEl);this.insert(1,"->")}this.doLayout()},setStatus:function(d){d=d||{};if(typeof d=="string"){d={text:d}}if(d.text!==undefined){this.setText(d.text)}if(d.iconCls!==undefined){this.setIcon(d.iconCls)}if(d.clear){var e=d.clear,b=this.autoClear,a={useDefaults:true,anim:true};if(typeof e=="object"){e=Ext.applyIf(e,a);if(e.wait){b=e.wait}}else{if(typeof e=="number"){b=e;e=a}else{if(typeof e=="boolean"){e=a}}}e.threadId=this.activeThreadId;this.clearStatus.defer(b,this,[e])}return this},clearStatus:function(c){c=c||{};if(c.threadId&&c.threadId!==this.activeThreadId){return this}var b=c.useDefaults?this.defaultText:this.emptyText,a=c.useDefaults?(this.defaultIconCls?this.defaultIconCls:""):"";if(c.anim){this.statusEl.el.fadeOut({remove:false,useDisplay:true,scope:this,callback:function(){this.setStatus({text:b,iconCls:a});this.statusEl.el.show()}})}else{this.statusEl.hide();this.setStatus({text:b,iconCls:a});this.statusEl.show()}return this},setText:function(a){this.activeThreadId++;this.text=a||"";if(this.rendered){this.statusEl.setText(this.text)}return this},getText:function(){return this.text},setIcon:function(a){this.activeThreadId++;a=a||"";if(this.rendered){if(this.currIconCls){this.statusEl.removeClass(this.currIconCls);this.currIconCls=null}if(a.length>0){this.statusEl.addClass(a);this.currIconCls=a}}else{this.currIconCls=a}return this},showBusy:function(a){if(typeof a=="string"){a={text:a}}a=Ext.applyIf(a||{},{text:this.busyText,iconCls:this.busyIconCls});return this.setStatus(a)}});Ext.reg("statusbar",Ext.ux.StatusBar);Ext.ux.TabCloseMenu=Ext.extend(Object,{closeTabText:"Close Tab",closeOtherTabsText:"Close Other Tabs",showCloseAll:true,closeAllTabsText:"Close All Tabs",constructor:function(a){Ext.apply(this,a||{})},init:function(a){this.tabs=a;a.on({scope:this,contextmenu:this.onContextMenu,destroy:this.destroy})},destroy:function(){Ext.destroy(this.menu);delete this.menu;delete this.tabs;delete this.active},onContextMenu:function(b,c,g){this.active=c;var a=this.createMenu(),d=true,h=true,f=a.getComponent("closeall");a.getComponent("close").setDisabled(!c.closable);b.items.each(function(){if(this.closable){d=false;if(this!=c){h=false;return false}}});a.getComponent("closeothers").setDisabled(h);if(f){f.setDisabled(d)}g.stopEvent();a.showAt(g.getPoint())},createMenu:function(){if(!this.menu){var a=[{itemId:"close",text:this.closeTabText,scope:this,handler:this.onClose}];if(this.showCloseAll){a.push("-")}a.push({itemId:"closeothers",text:this.closeOtherTabsText,scope:this,handler:this.onCloseOthers});if(this.showCloseAll){a.push({itemId:"closeall",text:this.closeAllTabsText,scope:this,handler:this.onCloseAll})}this.menu=new Ext.menu.Menu({items:a})}return this.menu},onClose:function(){this.tabs.remove(this.active)},onCloseOthers:function(){this.doClose(true)},onCloseAll:function(){this.doClose(false)},doClose:function(b){var a=[];this.tabs.items.each(function(c){if(c.closable){if(!b||c!=this.active){a.push(c)}}},this);Ext.each(a,function(c){this.tabs.remove(c)},this)}});Ext.preg("tabclosemenu",Ext.ux.TabCloseMenu);Ext.ns("Ext.ux.grid");Ext.ux.grid.TableGrid=function(p,f){f=f||{};Ext.apply(this,f);var c=f.fields||[],a=f.columns||[];p=Ext.get(p);var k=p.insertSibling();var l=[],m=[];var e=p.query("thead th");for(var g=0,j;j=e[g];g++){var o=j.innerHTML;var b="tcol-"+g;l.push(Ext.applyIf(c[g]||{},{name:b,mapping:"td:nth("+(g+1)+")/@innerHTML"}));m.push(Ext.applyIf(a[g]||{},{header:o,dataIndex:b,width:j.offsetWidth,tooltip:j.title,sortable:true}))}var d=new Ext.data.Store({reader:new Ext.data.XmlReader({record:"tbody tr"},l)});d.loadData(p.dom);var n=new Ext.grid.ColumnModel(m);if(f.width||f.height){k.setSize(f.width||"auto",f.height||"auto")}else{k.setWidth(p.getWidth())}if(f.remove!==false){p.remove()}Ext.applyIf(this,{ds:d,cm:n,sm:new Ext.grid.RowSelectionModel(),autoHeight:true,autoWidth:false});Ext.ux.grid.TableGrid.superclass.constructor.call(this,k,{})};Ext.extend(Ext.ux.grid.TableGrid,Ext.grid.GridPanel);Ext.grid.TableGrid=Ext.ux.grid.TableGrid;Ext.ns("Ext.ux");Ext.ux.TabScrollerMenu=Ext.extend(Object,{pageSize:10,maxText:15,menuPrefixText:"Items",constructor:function(a){a=a||{};Ext.apply(this,a)},init:function(b){Ext.apply(b,this.parentOverrides);b.tabScrollerMenu=this;var a=this;b.on({render:{scope:b,single:true,fn:function(){var c=b.createScrollers.createSequence(a.createPanelsMenu,this);b.createScrollers=c}}})},createPanelsMenu:function(){var c=this.stripWrap.dom.offsetHeight;var b=this.header.dom.firstChild;Ext.fly(b).applyStyles({right:"18px"});var a=Ext.get(this.strip.dom.parentNode);a.applyStyles({"margin-right":"36px"});var d=this.header.insertFirst({cls:"x-tab-tabmenu-right"});d.setHeight(c);d.addClassOnOver("x-tab-tabmenu-over");d.on("click",this.showTabsMenu,this);this.scrollLeft.show=this.scrollLeft.show.createSequence(function(){d.show()});this.scrollLeft.hide=this.scrollLeft.hide.createSequence(function(){d.hide()})},getPageSize:function(){return this.pageSize},setPageSize:function(a){this.pageSize=a},getMaxText:function(){return this.maxText},setMaxText:function(a){this.maxText=a},getMenuPrefixText:function(){return this.menuPrefixText},setMenuPrefixText:function(a){this.menuPrefixText=a},parentOverrides:{showTabsMenu:function(c){if(this.tabsMenu){this.tabsMenu.destroy();this.un("destroy",this.tabsMenu.destroy,this.tabsMenu);this.tabsMenu=null}this.tabsMenu=new Ext.menu.Menu();this.on("destroy",this.tabsMenu.destroy,this.tabsMenu);this.generateTabMenuItems();var b=Ext.get(c.getTarget());var a=b.getXY();a[1]+=24;this.tabsMenu.showAt(a)},generateTabMenuItems:function(){var a=this.getActiveTab();var l=this.items.getCount();var g=this.tabScrollerMenu.getPageSize();if(l>g){var d=Math.floor(l/g);var j=l%g;for(var e=0;e0){var c=d*g;b=[];for(var e=c;e0){var e=this.parseXml(f);if(typeof e=="string"){c.attributes.innerText=e}else{c.appendChild(e)}}a.push(c)}else{if(f.nodeType==this.XML_NODE_TEXT){var d=f.nodeValue.trim();if(d.length>0){return a=d}}}},this);return a},createNode:function(b){var a={tagName:b.tagName};Ext.each(b.attributes,function(c){a[c.nodeName]=c.nodeValue});this.processAttributes(a);return Ext.ux.tree.XmlTreeLoader.superclass.createNode.call(this,a)},processAttributes:Ext.emptyFn});Ext.ux.XmlTreeLoader=Ext.ux.tree.XmlTreeLoader;Ext.ux.ValidationStatus=Ext.extend(Ext.Component,{errorIconCls:"x-status-error",errorListCls:"x-status-error-list",validIconCls:"x-status-valid",showText:"The form has errors (click for details...)",hideText:"Click again to hide the error list",submitText:"Saving...",init:function(a){a.on("render",function(){this.statusBar=a;this.monitor=true;this.errors=new Ext.util.MixedCollection();this.listAlign=(a.statusAlign=="right"?"br-tr?":"bl-tl?");if(this.form){this.form=Ext.getCmp(this.form).getForm();this.startMonitoring();this.form.on("beforeaction",function(d,c){if(c.type=="submit"){this.monitor=false}},this);var b=function(){this.monitor=true};this.form.on("actioncomplete",b,this);this.form.on("actionfailed",b,this)}},this,{single:true});a.on({scope:this,afterlayout:{single:true,fn:function(){a.statusEl.getEl().on("click",this.onStatusClick,this,{buffer:200})}},beforedestroy:{single:true,fn:this.onDestroy}})},startMonitoring:function(){this.form.items.each(function(a){a.on("invalid",this.onFieldValidation,this);a.on("valid",this.onFieldValidation,this)},this)},stopMonitoring:function(){this.form.items.each(function(a){a.un("invalid",this.onFieldValidation,this);a.un("valid",this.onFieldValidation,this)},this)},onDestroy:function(){this.stopMonitoring();this.statusBar.statusEl.un("click",this.onStatusClick,this);Ext.ux.ValidationStatus.superclass.onDestroy.call(this)},onFieldValidation:function(a,b){if(!this.monitor){return false}if(b){this.errors.add(a.id,{field:a,msg:b})}else{this.errors.removeKey(a.id)}this.updateErrorList();if(this.errors.getCount()>0){if(this.statusBar.getText()!=this.showText){this.statusBar.setStatus({text:this.showText,iconCls:this.errorIconCls})}}else{this.statusBar.clearStatus().setIcon(this.validIconCls)}},updateErrorList:function(){if(this.errors.getCount()>0){var a="
      ";this.errors.each(function(b){a+=('
    • '+b.msg+"
    • ")},this);this.getMsgEl().update(a+"
    ")}else{this.getMsgEl().update("")}},getMsgEl:function(){if(!this.msgEl){this.msgEl=Ext.DomHelper.append(Ext.getBody(),{cls:this.errorListCls+" x-hide-offsets"},true);this.msgEl.on("click",function(b){var a=b.getTarget("li",10,true);if(a){Ext.getCmp(a.id.split("x-err-")[1]).focus();this.hideErrors()}},this,{stopEvent:true})}return this.msgEl},showErrors:function(){this.updateErrorList();this.getMsgEl().alignTo(this.statusBar.getEl(),this.listAlign).slideIn("b",{duration:0.3,easing:"easeOut"});this.statusBar.setText(this.hideText);this.form.getEl().on("click",this.hideErrors,this,{single:true})},hideErrors:function(){var a=this.getMsgEl();if(a.isVisible()){a.slideOut("b",{duration:0.2,easing:"easeIn"});this.statusBar.setText(this.showText)}this.form.getEl().un("click",this.hideErrors,this)},onStatusClick:function(){if(this.getMsgEl().isVisible()){this.hideErrors()}else{if(this.errors.getCount()>0){this.showErrors()}}}});(function(){Ext.override(Ext.list.Column,{init:function(){var b=Ext.data.Types,a=this.sortType;if(this.type){if(Ext.isString(this.type)){this.type=Ext.data.Types[this.type.toUpperCase()]||b.AUTO}}else{this.type=b.AUTO}if(Ext.isString(a)){this.sortType=Ext.data.SortTypes[a]}else{if(Ext.isEmpty(a)){this.sortType=this.type.sortType}}}});Ext.tree.Column=Ext.extend(Ext.list.Column,{});Ext.tree.NumberColumn=Ext.extend(Ext.list.NumberColumn,{});Ext.tree.DateColumn=Ext.extend(Ext.list.DateColumn,{});Ext.tree.BooleanColumn=Ext.extend(Ext.list.BooleanColumn,{});Ext.reg("tgcolumn",Ext.tree.Column);Ext.reg("tgnumbercolumn",Ext.tree.NumberColumn);Ext.reg("tgdatecolumn",Ext.tree.DateColumn);Ext.reg("tgbooleancolumn",Ext.tree.BooleanColumn)})();Ext.ux.tree.TreeGridNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:true,renderElements:function(d,l,h,m){var o=d.getOwnerTree(),k=o.columns,j=k[0],e,b,g;this.indentMarkup=d.parentNode?d.parentNode.ui.getChildIndent():"";b=['','','','',this.indentMarkup,"",'','','",'',(j.tpl?j.tpl.apply(l):l[j.dataIndex]||j.text),"",""];for(e=1,g=k.length;e','
    ",(j.tpl?j.tpl.apply(l):l[j.dataIndex]),"
    ","")}b.push('','');for(e=0,g=k.length;e')}b.push("");if(m!==true&&d.nextSibling&&d.nextSibling.ui.getEl()){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",d.nextSibling.ui.getEl(),b.join(""))}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",h,b.join(""))}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1].firstChild.firstChild;var f=this.elNode.firstChild.childNodes;this.indentNode=f[0];this.ecNode=f[1];this.iconNode=f[2];this.anchor=f[3];this.textNode=f[3].firstChild},animExpand:function(a){this.ctNode.style.display="";Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this,a)}});Ext.ux.tree.TreeGridRootNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:true,render:function(){if(!this.rendered){this.wrap=this.ctNode=this.node.ownerTree.innerCt.dom;this.node.expanded=true}if(Ext.isWebKit){var a=this.ctNode;a.style.tableLayout=null;(function(){a.style.tableLayout="fixed"}).defer(1)}},destroy:function(){if(this.elNode){Ext.dd.Registry.unregister(this.elNode.id)}delete this.node},collapse:Ext.emptyFn,expand:Ext.emptyFn});Ext.tree.ColumnResizer=Ext.extend(Ext.util.Observable,{minWidth:14,constructor:function(a){Ext.apply(this,a);Ext.tree.ColumnResizer.superclass.constructor.call(this)},init:function(a){this.tree=a;a.on("render",this.initEvents,this)},initEvents:function(a){a.mon(a.innerHd,"mousemove",this.handleHdMove,this);this.tracker=new Ext.dd.DragTracker({onBeforeStart:this.onBeforeStart.createDelegate(this),onStart:this.onStart.createDelegate(this),onDrag:this.onDrag.createDelegate(this),onEnd:this.onEnd.createDelegate(this),tolerance:3,autoStart:300});this.tracker.initEl(a.innerHd);a.on("beforedestroy",this.tracker.destroy,this.tracker)},handleHdMove:function(f,k){var g=5,j=f.getPageX(),d=f.getTarget(".x-treegrid-hd",3,true);if(d){var b=d.getRegion(),l=d.dom.style,c=d.dom.parentNode;if(j-b.left<=g&&d.dom!==c.firstChild){var a=d.dom.previousSibling;while(a&&Ext.fly(a).hasClass("x-treegrid-hd-hidden")){a=a.previousSibling}if(a){this.activeHd=Ext.get(a);l.cursor=Ext.isWebKit?"e-resize":"col-resize"}}else{if(b.right-j<=g){var h=d.dom;while(h&&Ext.fly(h).hasClass("x-treegrid-hd-hidden")){h=h.previousSibling}if(h){this.activeHd=Ext.get(h);l.cursor=Ext.isWebKit?"w-resize":"col-resize"}}else{delete this.activeHd;l.cursor=""}}}},onBeforeStart:function(a){this.dragHd=this.activeHd;return !!this.dragHd},onStart:function(b){this.tree.headersDisabled=true;this.proxy=this.tree.body.createChild({cls:"x-treegrid-resizer"});this.proxy.setHeight(this.tree.body.getHeight());var a=this.tracker.getXY()[0];this.hdX=this.dragHd.getX();this.hdIndex=this.tree.findHeaderIndex(this.dragHd);this.proxy.setX(this.hdX);this.proxy.setWidth(a-this.hdX);this.maxWidth=this.tree.outerCt.getWidth()-this.tree.innerBody.translatePoints(this.hdX).left},onDrag:function(b){var a=this.tracker.getXY()[0];this.proxy.setWidth((a-this.hdX).constrain(this.minWidth,this.maxWidth))},onEnd:function(c){var b=this.proxy.getWidth(),a=this.tree;this.proxy.remove();delete this.dragHd;a.columns[this.hdIndex].width=b;a.updateColumnWidths();setTimeout(function(){a.headersDisabled=false},100)}});Ext.ns("Ext.ux.tree");Ext.ux.tree.TreeGridSorter=Ext.extend(Ext.tree.TreeSorter,{sortClasses:["sort-asc","sort-desc"],sortAscText:"Sort Ascending",sortDescText:"Sort Descending",constructor:function(a,b){if(!Ext.isObject(b)){b={property:a.columns[0].dataIndex||"text",folderSort:true}}Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this,arguments);this.tree=a;a.on("headerclick",this.onHeaderClick,this);a.ddAppendOnly=true;me=this;this.defaultSortFn=function(k,j){var f=me.dir&&me.dir.toLowerCase()=="desc";var c=me.property||"text";var e=me.sortType;var g=me.folderSort;var h=me.caseSensitive===true;var d=me.leafAttr||"leaf";if(g){if(k.attributes[d]&&!j.attributes[d]){return 1}if(!k.attributes[d]&&j.attributes[d]){return -1}}var m=e?e(k):(h?k.attributes[c]:k.attributes[c].toUpperCase());var l=e?e(j):(h?j.attributes[c]:j.attributes[c].toUpperCase());if(ml){return f?-1:+1}else{return 0}}};a.on("afterrender",this.onAfterTreeRender,this,{single:true});a.on("headermenuclick",this.onHeaderMenuClick,this)},onAfterTreeRender:function(){if(this.tree.hmenu){this.tree.hmenu.insert(0,{itemId:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},{itemId:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"})}this.updateSortIcon(0,"asc")},onHeaderMenuClick:function(d,b,a){if(b==="asc"||b==="desc"){this.onHeaderClick(d,null,a);return false}},onHeaderClick:function(e,b,a){if(e&&!this.tree.headersDisabled){var d=this;d.property=e.dataIndex;d.dir=e.dir=(e.dir==="desc"?"asc":"desc");d.sortType=e.sortType;d.caseSensitive===Ext.isBoolean(e.caseSensitive)?e.caseSensitive:this.caseSensitive;d.sortFn=e.sortFn||this.defaultSortFn;this.tree.root.cascade(function(c){if(!c.isLeaf()){d.updateSort(d.tree,c)}});this.updateSortIcon(a,e.dir)}},updateSortIcon:function(b,a){var d=this.sortClasses;var c=this.tree.innerHd.select("td").removeClass(d);c.item(b).addClass(d[a=="desc"?1:0])}});Ext.ux.tree.TreeGridLoader=Ext.extend(Ext.tree.TreeLoader,{createNode:function(a){if(!a.uiProvider){a.uiProvider=Ext.ux.tree.TreeGridNodeUI}return Ext.tree.TreeLoader.prototype.createNode.call(this,a)}});Ext.ux.tree.TreeGrid=Ext.extend(Ext.tree.TreePanel,{rootVisible:false,useArrows:true,lines:false,borderWidth:Ext.isBorderBox?0:2,cls:"x-treegrid",columnResize:true,enableSort:true,reserveScrollOffset:true,enableHdMenu:true,columnsText:"Columns",initComponent:function(){if(!this.root){this.root=new Ext.tree.AsyncTreeNode({text:"Root"})}var a=this.loader;if(!a){a=new Ext.ux.tree.TreeGridLoader({dataUrl:this.dataUrl,requestMethod:this.requestMethod,store:this.store})}else{if(Ext.isObject(a)&&!a.load){a=new Ext.ux.tree.TreeGridLoader(a)}else{if(a){a.createNode=function(c){if(!c.uiProvider){c.uiProvider=Ext.ux.tree.TreeGridNodeUI}return Ext.tree.TreeLoader.prototype.createNode.call(this,c)}}}}this.loader=a;Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);this.initColumns();if(this.enableSort){this.treeGridSorter=new Ext.ux.tree.TreeGridSorter(this,this.enableSort)}if(this.columnResize){this.colResizer=new Ext.tree.ColumnResizer(this.columnResize);this.colResizer.init(this)}var b=this.columns;if(!this.internalTpl){this.internalTpl=new Ext.XTemplate('
    ','
    ','
    ','','','','","","
    ','
    ',this.enableHdMenu?'':"",'{header}',"
    ","
    ","
    ","
    ",'
    ','
    ',"
    ")}if(!this.colgroupTpl){this.colgroupTpl=new Ext.XTemplate('')}},initColumns:function(){var e=this.columns,a=e.length,d=[],b,f;for(b=0;b10)){this.setScrollOffset(a)}else{var d=this;setTimeout(function(){d.setScrollOffset(e.offsetWidth-e.clientWidth>10?a:0)},10)}}},updateColumnWidths:function(){var k=this.columns,m=k.length,a=this.outerCt.query("colgroup"),l=a.length,h,e,d,b;for(d=0;d0&&this.columns[a]){this.setColumnVisible(a,!b.checked)}}return true},setColumnVisible:function(a,b){this.columns[a].hidden=!b;this.updateColumnWidths()},scrollToTop:function(){this.innerBody.dom.scrollTop=0;this.innerBody.dom.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.innerBody.dom;this.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerBody.dom;this.innerHd.dom.scrollLeft=a.scrollLeft;this.innerHd.dom.scrollLeft=a.scrollLeft},registerNode:function(a){Ext.ux.tree.TreeGrid.superclass.registerNode.call(this,a);if(!a.uiProvider&&!a.isRoot&&!a.ui.isTreeGridNodeUI){a.ui=new Ext.ux.tree.TreeGridNodeUI(a)}}});Ext.reg("treegrid",Ext.ux.tree.TreeGrid); \ No newline at end of file diff --git a/gulliver/js/ext/wz_jsgraphics.js b/gulliver/js/ext/wz_jsgraphics.js new file mode 100755 index 000000000..2d55388d6 --- /dev/null +++ b/gulliver/js/ext/wz_jsgraphics.js @@ -0,0 +1,937 @@ +/* This notice must be untouched at all times. + +wz_jsgraphics.js v. 2.36 +The latest version is available at +http://www.walterzorn.com +or http://www.devira.com +or http://www.walterzorn.de + +Copyright (c) 2002-2004 Walter Zorn. All rights reserved. +Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com ) +Last modified: 21. 6. 2006 + +Performance optimizations for Internet Explorer +by Thomas Frank and John Holdsworth. +fillPolygon method implemented by Matthieu Haller. + +High Performance JavaScript Graphics Library. +Provides methods +- to draw lines, rectangles, ellipses, polygons + with specifiable line thickness, +- to fill rectangles and ellipses +- to draw text. +NOTE: Operations, functions and branching have rather been optimized +to efficiency and speed than to shortness of source code. + +LICENSE: LGPL + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License (LGPL) as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, +or see http://www.gnu.org/copyleft/lesser.html +*/ + + +var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz, +jg_n4 = (document.layers && typeof document.classes != "undefined"); + + +function chkDHTM(x, i) +{ + x = document.body || null; + jg_ie = x && typeof x.insertAdjacentHTML != "undefined"; + jg_dom = (x && !jg_ie && + typeof x.appendChild != "undefined" && + typeof document.createRange != "undefined" && + typeof (i = document.createRange()).setStartBefore != "undefined" && + typeof i.createContextualFragment != "undefined"); + jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined"; + jg_fast = jg_ie && document.all && !window.opera; + jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined"; +} + + +function pntDoc() +{ + this.wnd.document.write(jg_fast? this.htmRpc() : this.htm); + this.htm = ''; +} + + +function pntCnvDom() +{ + var x = this.wnd.document.createRange(); + x.setStartBefore(this.cnv); + x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm); + if(this.cnv) this.cnv.appendChild(x); + this.htm = ''; +} + + +function pntCnvIe() +{ + if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm); + this.htm = ''; +} + + +function pntCnvIhtm() +{ + if(this.cnv) this.cnv.innerHTML += this.htm; + this.htm = ''; +} + + +function pntCnv() +{ + this.htm = ''; +} + + +function mkDiv(x, y, w, h) +{ + this.htm += '
    <\/div>'; +} + + +function mkDivIe(x, y, w, h) +{ + this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';'; +} + + +function mkDivPrt(x, y, w, h) +{ + this.htm += '
    <\/div>'; +} + + +function mkLyr(x, y, w, h) +{ + this.htm += '<\/layer>\n'; +} + + +var regex = /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g; +function htmRpc() +{ + return this.htm.replace( + regex, + '
    \n'); +} + + +function htmPrtRpc() +{ + return this.htm.replace( + regex, + '
    \n'); +} + + +function mkLin(x1, y1, x2, y2) +{ + if (x1 > x2) + { + var _x2 = x2; + var _y2 = y2; + x2 = x1; + y2 = y1; + x1 = _x2; + y1 = _y2; + } + var dx = x2-x1, dy = Math.abs(y2-y1), + x = x1, y = y1, + yIncr = (y1 > y2)? -1 : 1; + + if (dx >= dy) + { + var pr = dy<<1, + pru = pr - (dx<<1), + p = pr-dx, + ox = x; + while ((dx--) > 0) + { + ++x; + if (p > 0) + { + this.mkDiv(ox, y, x-ox, 1); + y += yIncr; + p += pru; + ox = x; + } + else p += pr; + } + this.mkDiv(ox, y, x2-ox+1, 1); + } + + else + { + var pr = dx<<1, + pru = pr - (dy<<1), + p = pr-dy, + oy = y; + if (y2 <= y1) + { + while ((dy--) > 0) + { + if (p > 0) + { + this.mkDiv(x++, y, 1, oy-y+1); + y += yIncr; + p += pru; + oy = y; + } + else + { + y += yIncr; + p += pr; + } + } + this.mkDiv(x2, y2, 1, oy-y2+1); + } + else + { + while ((dy--) > 0) + { + y += yIncr; + if (p > 0) + { + this.mkDiv(x++, oy, 1, y-oy); + p += pru; + oy = y; + } + else p += pr; + } + this.mkDiv(x2, oy, 1, y2-oy+1); + } + } +} + + +function mkLin2D(x1, y1, x2, y2) +{ + if (x1 > x2) + { + var _x2 = x2; + var _y2 = y2; + x2 = x1; + y2 = y1; + x1 = _x2; + y1 = _y2; + } + var dx = x2-x1, dy = Math.abs(y2-y1), + x = x1, y = y1, + yIncr = (y1 > y2)? -1 : 1; + + var s = this.stroke; + if (dx >= dy) + { + if (dx > 0 && s-3 > 0) + { + var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx; + _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1; + } + else var _s = s; + var ad = Math.ceil(s/2); + + var pr = dy<<1, + pru = pr - (dx<<1), + p = pr-dx, + ox = x; + while ((dx--) > 0) + { + ++x; + if (p > 0) + { + this.mkDiv(ox, y, x-ox+ad, _s); + y += yIncr; + p += pru; + ox = x; + } + else p += pr; + } + this.mkDiv(ox, y, x2-ox+ad+1, _s); + } + + else + { + if (s-3 > 0) + { + var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy; + _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1; + } + else var _s = s; + var ad = Math.round(s/2); + + var pr = dx<<1, + pru = pr - (dy<<1), + p = pr-dy, + oy = y; + if (y2 <= y1) + { + ++ad; + while ((dy--) > 0) + { + if (p > 0) + { + this.mkDiv(x++, y, _s, oy-y+ad); + y += yIncr; + p += pru; + oy = y; + } + else + { + y += yIncr; + p += pr; + } + } + this.mkDiv(x2, y2, _s, oy-y2+ad); + } + else + { + while ((dy--) > 0) + { + y += yIncr; + if (p > 0) + { + this.mkDiv(x++, oy, _s, y-oy+ad); + p += pru; + oy = y; + } + else p += pr; + } + this.mkDiv(x2, oy, _s, y2-oy+ad+1); + } + } +} + + +function mkLinDott(x1, y1, x2, y2) +{ + if (x1 > x2) + { + var _x2 = x2; + var _y2 = y2; + x2 = x1; + y2 = y1; + x1 = _x2; + y1 = _y2; + } + var dx = x2-x1, dy = Math.abs(y2-y1), + x = x1, y = y1, + yIncr = (y1 > y2)? -1 : 1, + drw = true; + if (dx >= dy) + { + var pr = dy<<1, + pru = pr - (dx<<1), + p = pr-dx; + while ((dx--) > 0) + { + if (drw) this.mkDiv(x, y, 1, 1); + drw = !drw; + if (p > 0) + { + y += yIncr; + p += pru; + } + else p += pr; + ++x; + } + if (drw) this.mkDiv(x, y, 1, 1); + } + + else + { + var pr = dx<<1, + pru = pr - (dy<<1), + p = pr-dy; + while ((dy--) > 0) + { + if (drw) this.mkDiv(x, y, 1, 1); + drw = !drw; + y += yIncr; + if (p > 0) + { + ++x; + p += pru; + } + else p += pr; + } + if (drw) this.mkDiv(x, y, 1, 1); + } +} + + +function mkOv(left, top, width, height) +{ + var a = width>>1, b = height>>1, + wod = width&1, hod = (height&1)+1, + cx = left+a, cy = top+b, + x = 0, y = b, + ox = 0, oy = b, + aa = (a*a)<<1, bb = (b*b)<<1, + st = (aa>>1)*(1-(b<<1)) + bb, + tt = (bb>>1) - aa*((b<<1)-1), + w, h; + while (y > 0) + { + if (st < 0) + { + st += bb*((x<<1)+3); + tt += (bb<<1)*(++x); + } + else if (tt < 0) + { + st += bb*((x<<1)+3) - (aa<<1)*(y-1); + tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); + w = x-ox; + h = oy-y; + if (w&2 && h&2) + { + this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1); + this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1); + } + else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h); + ox = x; + oy = y; + } + else + { + tt -= aa*((y<<1)-3); + st -= (aa<<1)*(--y); + } + } + this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod); + this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod); +} + + +function mkOv2D(left, top, width, height) +{ + var s = this.stroke; + width += s-1; + height += s-1; + var a = width>>1, b = height>>1, + wod = width&1, hod = (height&1)+1, + cx = left+a, cy = top+b, + x = 0, y = b, + aa = (a*a)<<1, bb = (b*b)<<1, + st = (aa>>1)*(1-(b<<1)) + bb, + tt = (bb>>1) - aa*((b<<1)-1); + + if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0)) + { + var ox = 0, oy = b, + w, h, + pxl, pxr, pxt, pxb, pxw; + while (y > 0) + { + if (st < 0) + { + st += bb*((x<<1)+3); + tt += (bb<<1)*(++x); + } + else if (tt < 0) + { + st += bb*((x<<1)+3) - (aa<<1)*(y-1); + tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); + w = x-ox; + h = oy-y; + + if (w-1) + { + pxw = w+1+(s&1); + h = s; + } + else if (h-1) + { + pxw = s; + h += 1+(s&1); + } + else pxw = h = s; + this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h); + ox = x; + oy = y; + } + else + { + tt -= aa*((y<<1)-3); + st -= (aa<<1)*(--y); + } + } + this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod); + this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod); + } + + else + { + var _a = (width-((s-1)<<1))>>1, + _b = (height-((s-1)<<1))>>1, + _x = 0, _y = _b, + _aa = (_a*_a)<<1, _bb = (_b*_b)<<1, + _st = (_aa>>1)*(1-(_b<<1)) + _bb, + _tt = (_bb>>1) - _aa*((_b<<1)-1), + + pxl = new Array(), + pxt = new Array(), + _pxb = new Array(); + pxl[0] = 0; + pxt[0] = b; + _pxb[0] = _b-1; + while (y > 0) + { + if (st < 0) + { + st += bb*((x<<1)+3); + tt += (bb<<1)*(++x); + pxl[pxl.length] = x; + pxt[pxt.length] = y; + } + else if (tt < 0) + { + st += bb*((x<<1)+3) - (aa<<1)*(y-1); + tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); + pxl[pxl.length] = x; + pxt[pxt.length] = y; + } + else + { + tt -= aa*((y<<1)-3); + st -= (aa<<1)*(--y); + } + + if (_y > 0) + { + if (_st < 0) + { + _st += _bb*((_x<<1)+3); + _tt += (_bb<<1)*(++_x); + _pxb[_pxb.length] = _y-1; + } + else if (_tt < 0) + { + _st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1); + _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3); + _pxb[_pxb.length] = _y-1; + } + else + { + _tt -= _aa*((_y<<1)-3); + _st -= (_aa<<1)*(--_y); + _pxb[_pxb.length-1]--; + } + } + } + + var ox = 0, oy = b, + _oy = _pxb[0], + l = pxl.length, + w, h; + for (var i = 0; i < l; i++) + { + if (typeof _pxb[i] != "undefined") + { + if (_pxb[i] < _oy || pxt[i] < oy) + { + x = pxl[i]; + this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy); + ox = x; + oy = pxt[i]; + _oy = _pxb[i]; + } + } + else + { + x = pxl[i]; + this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod); + this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod); + ox = x; + oy = pxt[i]; + } + } + this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod); + this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod); + } +} + + +function mkOvDott(left, top, width, height) +{ + var a = width>>1, b = height>>1, + wod = width&1, hod = height&1, + cx = left+a, cy = top+b, + x = 0, y = b, + aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1, + st = (aa2>>1)*(1-(b<<1)) + bb, + tt = (bb>>1) - aa2*((b<<1)-1), + drw = true; + while (y > 0) + { + if (st < 0) + { + st += bb*((x<<1)+3); + tt += (bb<<1)*(++x); + } + else if (tt < 0) + { + st += bb*((x<<1)+3) - aa4*(y-1); + tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3); + } + else + { + tt -= aa2*((y<<1)-3); + st -= aa4*(--y); + } + if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1); + drw = !drw; + } +} + + +function mkRect(x, y, w, h) +{ + var s = this.stroke; + this.mkDiv(x, y, w, s); + this.mkDiv(x+w, y, s, h); + this.mkDiv(x, y+h, w+s, s); + this.mkDiv(x, y+s, s, h-s); +} + + +function mkRectDott(x, y, w, h) +{ + this.drawLine(x, y, x+w, y); + this.drawLine(x+w, y, x+w, y+h); + this.drawLine(x, y+h, x+w, y+h); + this.drawLine(x, y, x, y+h); +} + + +function jsgFont() +{ + this.PLAIN = 'font-weight:normal;'; + this.BOLD = 'font-weight:bold;'; + this.ITALIC = 'font-style:italic;'; + this.ITALIC_BOLD = this.ITALIC + this.BOLD; + this.BOLD_ITALIC = this.ITALIC_BOLD; +} +var Font = new jsgFont(); + + +function jsgStroke() +{ + this.DOTTED = -1; +} +var Stroke = new jsgStroke(); + + +function jsGraphics(id, wnd) +{ + this.setColor = new Function('arg', 'this.color = arg.toLowerCase();'); + + this.setStroke = function(x) + { + this.stroke = x; + if (!(x+1)) + { + this.drawLine = mkLinDott; + this.mkOv = mkOvDott; + this.drawRect = mkRectDott; + } + else if (x-1 > 0) + { + this.drawLine = mkLin2D; + this.mkOv = mkOv2D; + this.drawRect = mkRect; + } + else + { + this.drawLine = mkLin; + this.mkOv = mkOv; + this.drawRect = mkRect; + } + }; + + + this.setPrintable = function(arg) + { + this.printable = arg; + if (jg_fast) + { + this.mkDiv = mkDivIe; + this.htmRpc = arg? htmPrtRpc : htmRpc; + } + else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv; + }; + + + this.setFont = function(fam, sz, sty) + { + this.ftFam = fam; + this.ftSz = sz; + this.ftSty = sty || Font.PLAIN; + }; + + + this.drawPolyline = this.drawPolyLine = function(x, y, s) + { + for (var i=0 ; i>1, b = (h -= 1)>>1, + wod = (w&1)+1, hod = (h&1)+1, + cx = left+a, cy = top+b, + x = 0, y = b, + ox = 0, oy = b, + aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1, + st = (aa2>>1)*(1-(b<<1)) + bb, + tt = (bb>>1) - aa2*((b<<1)-1), + pxl, dw, dh; + if (w+1) while (y > 0) + { + if (st < 0) + { + st += bb*((x<<1)+3); + tt += (bb<<1)*(++x); + } + else if (tt < 0) + { + st += bb*((x<<1)+3) - aa4*(y-1); + pxl = cx-x; + dw = (x<<1)+wod; + tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3); + dh = oy-y; + this.mkDiv(pxl, cy-oy, dw, dh); + this.mkDiv(pxl, cy+y+hod, dw, dh); + ox = x; + oy = y; + } + else + { + tt -= aa2*((y<<1)-3); + st -= aa4*(--y); + } + } + this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod); + }; + + +/* fillPolygon method, implemented by Matthieu Haller. +This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib. +C source of GD 1.8.4 found at http://www.boutell.com/gd/ + +THANKS to Kirsten Schulz for the polygon fixes! + +The intersection finding technique of this code could be improved +by remembering the previous intertersection, and by using the slope. +That could help to adjust intersections to produce a nice +interior_extrema. */ + this.fillPolygon = function(array_x, array_y) + { + var i; + var y; + var miny, maxy; + var x1, y1; + var x2, y2; + var ind1, ind2; + var ints; + + var n = array_x.length; + + if (!n) return; + + + miny = array_y[0]; + maxy = array_y[0]; + for (i = 1; i < n; i++) + { + if (array_y[i] < miny) + miny = array_y[i]; + + if (array_y[i] > maxy) + maxy = array_y[i]; + } + for (y = miny; y <= maxy; y++) + { + var polyInts = new Array(); + ints = 0; + for (i = 0; i < n; i++) + { + if (!i) + { + ind1 = n-1; + ind2 = 0; + } + else + { + ind1 = i-1; + ind2 = i; + } + y1 = array_y[ind1]; + y2 = array_y[ind2]; + if (y1 < y2) + { + x1 = array_x[ind1]; + x2 = array_x[ind2]; + } + else if (y1 > y2) + { + y2 = array_y[ind1]; + y1 = array_y[ind2]; + x2 = array_x[ind1]; + x1 = array_x[ind2]; + } + else continue; + + // modified 11. 2. 2004 Walter Zorn + if ((y >= y1) && (y < y2)) + polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1); + + else if ((y == maxy) && (y > y1) && (y <= y2)) + polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1); + } + polyInts.sort(integer_compare); + for (i = 0; i < ints; i+=2) + this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1); + } + }; + + + this.drawString = function(txt, x, y) + { + this.htm += '
    '+ + txt + + '<\/div>'; + }; + + +/* drawStringRect() added by Rick Blommers. +Allows to specify the size of the text rectangle and to align the +text both horizontally (e.g. right) and vertically within that rectangle */ + this.drawStringRect = function(txt, x, y, width,height, halign) + { + this.ftSz = '11px'; + this.htm += '
    '+ + txt + + '<\/div>'; + }; + + + this.drawImage = function(imgSrc, x, y, w, h, a) + { + this.htm += '
    '+ + ''+ + '<\/div>'; + }; + + + this.clear = function() + { + this.htm = ""; + if (this.cnv) this.cnv.innerHTML = this.defhtm; + }; + + + this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h) + { + this.mkDiv(xr+cx, yt+cy, w, h); + this.mkDiv(xr+cx, yb+cy, w, h); + this.mkDiv(xl+cx, yb+cy, w, h); + this.mkDiv(xl+cx, yt+cy, w, h); + }; + + this.setStroke(1); + this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN); + this.color = '#000000'; + this.htm = ''; + this.wnd = wnd || window; + + if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM(); + if (typeof id != 'string' || !id) this.paint = pntDoc; + else + { + this.cnv = document.all? (this.wnd.document.all[id] || null) + : document.getElementById? (this.wnd.document.getElementById(id) || null) + : null; + this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : ''; + this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv; + } + + this.setPrintable(false); +} + + + +function integer_compare(x,y) +{ + return (x < y) ? -1 : ((x > y)*1); +} + diff --git a/gulliver/js/form/core/form.js b/gulliver/js/form/core/form.js new file mode 100644 index 000000000..f14ab059c --- /dev/null +++ b/gulliver/js/form/core/form.js @@ -0,0 +1,2097 @@ +/* PACKAGE : GULLIVER FORMS + */ + +function G_Form ( element, id ) +{ + var me=this; + this.info = { + name:'G_Fom', + version :'1.0' + }; + /*this.module=RESERVED*/ + this.formula=''; + this.element=element; + if (!element) return; + this.id=id; + this.aElements=[]; + this.ajaxServer=''; + this.getElementIdByName = function (name) { + if (name=='') return -1; + var j; + for(j=0;j=0) return me.aElements[i]; else return null; + } + this.hideGroup = function( group, parentLevel ){ + if (typeof(parentLevel)==='undefined') parentLevel = 1; + for( var r=0 ; r < me.aElements.length ; r++ ) { + if ((typeof(me.aElements[r].group)!=='undefined') && (me.aElements[r].group == group )) + me.aElements[r].hide(parentLevel); + } + } + this.showGroup = function( group, parentLevel ){ + if (typeof(parentLevel)==='undefined') parentLevel = 1; + for( var r=0 ; r < me.aElements.length ; r++ ) { + if ((typeof(me.aElements[r].group)!=='undefined') && (me.aElements[r].group == group )) + me.aElements[r].show(parentLevel); + } + } + this.verifyRequiredFields=function(){ + var valid=true; + for(var i=0;i -1) { + dependentFields = dependentFields.split(','); + } + else { + dependentFields = dependentFields.split('|'); + } + for(i=0;i=0) { + me.dependentFields[i] = me.form.getElementByName(dependentFields[i]); + me.dependentFields[i].addDependencie(me); + } + } + } + this.addDependencie = function (field) { + var exists = false; + for (i=0;i -1) { + var aAux = oAux.name.split(']['); + grid = aAux[0]; + row = aAux[1]; + eval("var oAux2 = {" + aAux[2] + ":'" + oAux.value() + "'}"); + fields = fields.concat(oAux2); + } + else { + fields = fields.concat(me.dependentFields[i].dependentOf); + } + } + } + } + var callServer; + callServer = new leimnud.module.rpc.xmlhttp({ + url : me.form.ajaxServer, + async : false, + method : "POST", + args : "function=reloadField&" + 'form='+encodeURIComponent(me.form.id)+'&fields='+encodeURIComponent(fields.toJSONString())+(grid!=''?'&grid='+grid:'')+(row>0?'&row='+row:'') + }); + callServer.make(); + var response = callServer.xmlhttp.responseText; + //Validate the response + if (response.substr(0,1)==='[') { + var newcont; + eval('newcont=' + response + ';'); + if (grid == '') { + for(var i=0;i0?'&row='+row:'') + }); + checkCallServer.make(); + + var dependentList = eval(checkCallServer.xmlhttp.responseText); + var field ; + var oAuxJs; + for ( index in dependentList ){ + field = 'form[grid]['+ row +']['+dependentList[index]+']'; + // alert(field); + oAuxJs = document.getElementById(field); + // alert (oAuxJs.value); + if ( oAuxJs!=null ){ + if (oAuxJs.value!="") { + if ( oAuxJs.fireEvent ) { + oAuxJs.fireEvent("onchange"); + } else { + var evObj = document.createEvent( 'HTMLEvents' ); + evObj.initEvent( 'change', true, true ); + oAuxJs.dispatchEvent(evObj); + } + } + } + } + } + return true; + } + this.setValue = function(newValue) { + me.element.value = newValue; + } + this.setContent = function(newContent) { + + } + + this.setAttributes = function (attributes) { + for(var a in attributes) { + if(a=='formula' && attributes[a]){ + //here we called a this function if it has a formula + sumaformu(this.element,attributes[a],attributes['mask']); + } + + switch (typeof(attributes[a])) { + case 'string': + case 'int': + case 'boolean': + if (a != 'strTo') { + switch (true) { + case typeof(me[a])==='undefined': + case typeof(me[a])==='object': + case typeof(me[a])==='function': + case a==='isObject': + case a==='isArray': + break; + default: + me[a] = attributes[a]; + } + } + else { + me[a] = attributes[a]; + } + } + + } + } + this.value=function() { + return me.element.value; + } + this.toJSONString=function() { + return '{'+me.name+':'+me.element.value.toJSONString()+'}'; + } + this.highLight=function(){ + try{ + G.highLight(me.element); + if (G.autoFirstField) { + me.element.focus(); + G.autoFirstField=false; + setTimeout("G.autoFirstField=true;",1000); + } + } catch (e){ + } + } +} + +function G_DropDown( form, element, name ) +{ + var me=this; + this.parent = G_Field; + this.parent( form, element, name ); + this.setContent=function(content) { + var dd=me.element; + while(dd.options.length>0) dd.remove(0); + for(var o=0;o 57) && (keyCode != 8 && keyCode != 0 && keyCode != 46)) return false; + if((keyCode===118 || keyCode===86) && event.ctrlKey) return false; + if (event.ctrlKey) return true; + if (event.altKey) return true; + if (event.shiftKey) return true; + } //alert(keyCode +" \n"+event.ctrlKey); + if ((keyCode===0) ) if (event.keyCode===46) return true; else return true; + if ( (keyCode===8)) return true; + if (me.mask ==='') { + if (me.validate == 'NodeName') { + if (me.getCursorPos() == 0) { + if ((keyCode >= 48) && (keyCode <= 57)) { + return false; + } + } + var k=new leimnud.module.validator({ + valid :['Field'], + key :event, + lang :(typeof(me.language)!=='undefined')?me.language:"en" + }); + return k.result(); + } + else { + switch(me.validate){ + case "Int": + if ((keyCode > 47) && (keyCode < 58) || ( keyCode == 118 && event.ctrlKey)|| (keyCode == 120 && event.ctrlKey)) { + return true; + }else{ + return false; + } + break; + case "Alpha": + if (keyCode==8) return true; + patron =/[A-Za-z\s]/; + te = String.fromCharCode(keyCode); + return patron.test(te); + break; + default: + var k=new leimnud.module.validator({ + valid :[me.validate], + key :event, + lang :(typeof(me.language)!=='undefined')?me.language:"en" + }); + return k.result(); + break; + } + } + } else { + //return true; + if (doubleChange) { + doubleChange=false; + return false; + } + if(navigator.appName!='Microsoft Internet Explorer') + var sel = me.getSelectionRange(); + else + var sel = me.getCursorP(me.element); + + var myValue = String.fromCharCode(keyCode); + var startPos=sel.selectionStart; + var endPos=sel.selectionEnd; + var myField = me.element; + var newValue = myField.value + if (keyCode===8) { + if (startPos>0) + newValue = myField.value.substring(0, startPos + ((startPos==endPos)?-1:0) ) + + myField.value.substring(endPos, myField.value.length); + } else { + newValue = myField.value.substring(0, startPos) + + myValue + + myField.value.substring(endPos, myField.value.length); + } + var Esperado = newValue; + startPos++; +//alert( newValue.result +'\n'+ me.mask +'\n'+ startPos ); + var newValue2=G.cleanMask( newValue, me.mask, startPos ); +//alert( newValue2.result +'\n'+ me.mask +'\n'+ startPos ); + newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor ); +//alert( newValue2.result +'\n'+ newValue2.cursor +'\n'+ newValue2.cursor ); + me.element.value=newValue2.result; + me.setSelectionRange(newValue2.cursor, newValue2.cursor); +//alert( me.element.value +'\n'+ me.mask +'\n'+ newValue2.cursor ); + + if (me.element.fireEvent) { + me.element.fireEvent("onchange"); + } else { + var evObj = document.createEvent('HTMLEvents'); + evObj.initEvent( 'change', true, true ); + me.element.dispatchEvent(evObj); + } + + return false; + } + } + +function replaceAll( text, busca, reemplaza ){ + while (text.toString().indexOf(busca) != -1) + text = text.toString().replace(busca,reemplaza); + return text; +} + + this.putFormatNumber =function (evt) { + if((typeof(evt)==="undefined" || evt===0) && me.mask!='' ){ + var numberSet=me.element.value.split('.'); + if(numberSet.length >=2)return; + + maskD = me.mask.split(';'); + maskL = (maskD.length >1)?maskD[1]:maskD[0]; + maskWithoutC =replaceAll(maskL,",",""); + //maskWithoutC =replaceAll(maskWithoutC,".",""); + //maskWithoutC =replaceAll(maskWithoutC,"#",""); + maskWithoutC =replaceAll(maskWithoutC,"%",""); + maskWithoutC =replaceAll(maskWithoutC," ",""); + maskWithoutPto=replaceAll(maskWithoutC,".",""); + + maskElemnts = maskWithoutC.split('.'); + maskpartInt = maskElemnts[0].split(''); + //in here is the int part maskpartInt + //numberwc = me.element.value.replaceAll(".","").replaceAll(",",""); + numberwc = replaceAll(me.element.value,",", ""); + numberwc = replaceAll(numberwc,".", ""); + onlynumber = replaceAll(numberwc,".", ""); + onlynumber = replaceAll(numberwc," ", ""); + onlynumber = replaceAll(numberwc,"%", ""); + if(onlynumber=='') return false; + cd = parseInt(Math.log(onlynumber)/Math.LN10+1); + var auxnumber = onlynumber; + var cdaux=0; + while(auxnumber > 0){ + cdaux++; + auxnumber =parseInt(auxnumber / 10); + } + cd=cdaux; + /* + ///we added this slice of code to complete with zeros a number if is needed + var cdnum = cdaux; + while(cdnum < maskWithoutPto.length){ + onlynumber=parseInt(onlynumber)*10; + cdnum++; + } + var numberFormat=''; + var r=maskL.length -1 ; + while(r >= 0){ + var slicemask=maskL.substr(r,1); + switch(slicemask){ + case '#': + lastdig = onlynumber % 10; + numberFormat = lastdig.toString() + numberFormat; + onlynumber = parseInt(onlynumber / 10); + break; + default: + numberFormat = slicemask + numberFormat; + break; + } + r--; + } + me.element.value = numberFormat; + ///////// end the slice code ... complete with zeros + return; + */ + if(cd < maskpartInt.length && cd >= 4 && cd !=3){ + var newnamber=''; + var cc=1; + while (onlynumber >0){ + lastdigito = onlynumber % 10; + if (cc%3==0 && cd != cc){ + newnamber = ','+lastdigito.toString() + newnamber; + } else { + newnamber = lastdigito.toString() + newnamber; + } + onlynumber =parseInt(onlynumber / 10); + cc++; + } + me.element.value = newnamber; + } + } + } + + this.preValidateChange=function(event) { //alert(event.keyCode); + me.putFormatNumber(event); + /* if(cd < maskpartInt.length && cd >= 4 && cd !=3){ + var newnamber=''; + var cc=1; + while (onlynumber >0){ + lastdigito = onlynumber % 10; + + if (cc%3==0 && cd != cc){ + newnamber = ','+lastdigito.toString() + newnamber; + } else { + newnamber = lastdigito.toString() + newnamber; + } + + onlynumber =parseInt(onlynumber / 10); + cc++; + } + me.element.value = newnamber; + } + }//end me.mask + }*/ + if(me.element.readOnly) return true; + if (me.mask ==='') return true; + if (event.keyCode===46) { + var sel=me.getSelectionRange(); + var startPos = sel.selectionStart; + var endPos = sel.selectionEnd; + var myField = me.element; + var newValue = myField.value + if (startPos0) { + newValue = myField.value.substring(0, startPos-1) + + myField.value.substring(endPos, myField.value.length); + newValue2=G.cleanMask( newValue, me.mask, startPos ); + newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor ); + me.element.value=newValue2.result; + me.setSelectionRange(startPos-1, startPos-1); + } + }else{ + var sel=me.getSelectionRange(); + //var sel = me.getCursorP(me.element); + var startPos = sel.selectionStart; + var endPos = sel.selectionEnd; + var myField = me.element; + var newValue = myField.value; + if (startPos>0) { + //newValue = myField.value.substring(0, startPos-1) + newValue = myField.value.substring(0, startPos); + //+ myField.value.substring(endPos, myField.value.length); + + myField.value.substring(endPos+1, myField.value.length); + newValue2=G.cleanMask( newValue, me.mask, startPos ); + newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor ); + //me.element.value=newValue2.result; ///it was commented because it is putting a incomplete number + //me.setSelectionRange(startPos-1, startPos-1); + me.setSelectionRange(startPos, startPos); + } + } + return false; + } + me.prev=me.element.value; + return true; + } + this.execFormula=function(event) { + + //alert(me.formula); return; + + if( me.formula != ''){ + + leimnud.event.add(getField('faa'),'keypress',function(){ + alert(getField('faa').value); + }); + } + return false; + + } + this.validateChange=function(event) { + if (me.mask ==='') return true; + var sel=me.getSelectionRange(); + var newValue2=G.cleanMask( me.element.value, me.mask, sel.selectionStart ); + newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor); + me.element.value = newValue2.result; + me.setSelectionRange(newValue2.cursor, newValue2.cursor); + return true; + } + + this.value=function() + { + return me.element.value; + } + + this.getCursorPos = function () { + var textElement=me.element; + if (!document.selection) return textElement.selectionStart; + //save off the current value to restore it later, + var sOldText = textElement.value; + + //create a range object and save off it's text + var objRange = document.selection.createRange(); + var sOldRange = objRange.text; + + //set this string to a small string that will not normally be encountered + var sWeirdString = '#%~'; + + //insert the weirdstring where the cursor is at + objRange.text = sOldRange + sWeirdString; + objRange.moveStart('character', (0 - sOldRange.length - sWeirdString.length)); + + //save off the new string with the weirdstring in it + var sNewText = textElement.value; + + //set the actual text value back to how it was + objRange.text = sOldRange; + + //look through the new string we saved off and find the location of + //the weirdstring that was inserted and return that value + for (i=0; i <= sNewText.length; i++) { + var sTemp = sNewText.substring(i, i + sWeirdString.length); + if (sTemp == sWeirdString) { + var cursorPos = (i - sOldRange.length); + return cursorPos; + } + } + } + this.setSelectionRange = function(selectionStart, selectionEnd) { + var input=me.element; + if (input.createTextRange) { + var range = input.createTextRange(); + range.collapse(true); + range.moveEnd('character', selectionEnd); + range.moveStart('character', selectionStart); + range.select(); + } + else if (input.setSelectionRange) { + input.focus(); + input.setSelectionRange(selectionStart, selectionEnd); + } + } + this.getSelectionRange = function() { + if (document.selection) { + var textElement=me.element; + var sOldText = textElement.value; + var objRange = document.selection.createRange(); + var sOldRange = objRange.text; + var sWeirdString = '#%~'; + objRange.text = sOldRange + sWeirdString; + objRange.moveStart('character', (0 - sOldRange.length - sWeirdString.length)); + var sNewText = textElement.value; + objRange.text = sOldRange; + for (i=0; i <= sNewText.length; i++) { + var sTemp = sNewText.substring(i, i + sWeirdString.length); + if (sTemp == sWeirdString) { + var cursorPos = (i - sOldRange.length); + return { + selectionStart: cursorPos, + selectionEnd: cursorPos+sOldRange.length + }; + } + } + } else { + var sel={ + selectionStart: 0, + selectionEnd: 0 + }; + sel.selectionStart = me.element.selectionStart; + sel.selectionEnd = me.element.selectionEnd; + return sel; + } + } + + this.getCursorP =function (field) { + if (document.selection) { + field.focus(); + var oSel = document.selection.createRange(); + oSel.moveStart('character', -field.value.length); + field.selectionEnd = oSel.text.length; + oSel.setEndPoint('EndToStart', document.selection.createRange() ); + field.selectionStart = oSel.text.length; + } + return { selectionStart: field.selectionStart, selectionEnd: field.selectionEnd }; + } + + + + if (!element) return; + if (!window.event) + this.element.onkeypress = this.validateKey; + else + leimnud.event.add(this.element,'keypress',this.validateKey); + leimnud.event.add(this.element,'change',this.updateDepententFields); + + + + this.element.onblur=function(event) + { + var evt = event || window.event; + var keyPressed = evt.which || evt.keyCode; + me.putFormatNumber(keyPressed); + ////////////////////////////////////////// + /* + if(this.validate == 'Int'|| this.validate == 'Real'){ + alert(this.formula); + symOp=typeOperation(this.formula); + if(this.formula){ + operations=this.formula.split(symOp); + + var resdo=iniAcum(symOp); + for (var i=0;i=0;r--) num+= num0.substr(r,1); + return num; + } + function __toMask(num, mask, cursor) + { + var inv=false; + if (mask.substr(0,1)==='_') { + mask=mask.substr(1); + inv=true; + } + var re; + if (inv) { + mask=invertir(mask); + num=invertir(num); + } + var minAdd=-1; + var minLoss=-1; + var newCursorPosition=cursor; + var betterOut=""; + for(var r0=0;r0< mask.length; r0++) { + var out=""; + var j=0; + var loss=0; + var add=0; + loss=0; + add=0; + var cursorPosition=cursor; + var i=-1; + var dayPosition=0; + var mounthPosition=0; + var dayAnalized =''; + var mounthAnalized =''; + var blocks={}; + for(var r=0;r< r0 ;r++) { + var e=false; + var m=mask.substr(r,1); + __parseMask(); + } + i=0; + for(r=r0;r< mask.length;r++) { + j++; + if (j>200) break; + e=num.substr(i,1); + e=(e==='')?false:e; + m=mask.substr(r,1); + __parseMask(); + } + var io=num.length - i; + io=(io<0)?0:io; + loss+=io; + loss=loss+add/1000; + //var_dump($loss); + if (loss===0) { + betterOut=out; + minLoss=0; + newCursorPosition=cursorPosition; + break; + } + if ((minLoss===-1)||(loss< minLoss)) { + minLoss=loss; + betterOut=out; + newCursorPosition=cursorPosition; + } + //echo('min:');var_dump($minLoss); + } + // var_dump($minLoss); + out=betterOut; + if (inv) { + out=invertir(out); + mask=invertir(mask); + } + return { + 'result':out, + 'cursor':newCursorPosition, + 'value':minLoss, + 'mask':mask + }; + function searchBlock( where , what ) + { + for(var r=0; r < where.length ; r++ ) { + if (where[r].key === what) return where[r]; + } + } + function __parseMask() + { + var ok=true; + switch(false) { + case m==='d': + dayAnalized=''; + break; + case m==='m': + mounthAnalized=''; + break; + default: + } + if ( e!==false ) { + if (typeof(blocks[m])==='undefined') blocks[m] = e; else blocks[m] += e; + } + switch(m) { + case '0': + if (e===false) { + out+='0'; + add++; + break; + } + case 'y': + case '#': + if (e===false) { + out+=''; + break; + } + //Use direct comparition to increse speed of processing + if ((e==='0')||(e==='1')||(e==='2')||(e==='3')||(e==='4')||(e==='5')||(e==='6')||(e==='7')||(e==='8')||(e==='9')||(e==='-')) { + out+=e; + i++; + } else { + //loss + loss++; + i++; + r--; + } + break; + case '(': + if (e===false) { + out+=''; + break; + } + out+=m; + if (i3) ok=false + //dayPosition=(dayPosition+1) | 1; + if (ok) dayAnalized = dayAnalized + e; + if ((ok) && (parseInt(dayAnalized)>31)) ok = false; + if (ok) { + out+=e; + i++; + + } else { + //loss + loss++; + i++; + r--; + } + break; + case 'm': + if (e===false) { + out+=''; + break; + } + if ((e==='0')||(e==='1')||(e==='2')||(e==='3')||(e==='4')||(e==='5')||(e==='6')||(e==='7')||(e==='8')||(e==='9')) ok=true; else ok=false; + if (ok) mounthAnalized = mounthAnalized + e; + if ((ok) && (parseInt(mounthAnalized)>12)) ok=false; + if (ok) { + out+=e; + i++; + } else { + //loss + loss++; + i++; + r--; + } + break; + + default: + if (e===false) { + out+=''; + break; + } + if (e===m) { + out+=e; + i++; + }else { + + //if (m==='.') alert(i.toString() +'.'+ cursor.toString()); + out+=m; + /////here was krlos + add++; + if (i0) { + r=others.length; + others[r] = mask.substr(0,1); + mask= mask.split(others[r]).join(''); + num = num.split(others[r]).join(''); + cursor -= a.split(others[r]).length-1;//alert(cursor) + } + return { + 'result':num, + 'cursor':cursor + }; + } + this.getId=function(element){ + var re=/(\[(\w+)\])+/; + var res=re.exec(element.id); + return res?res[2]:element.id; + } + this.getObject=function(element){ + var objId=G.getId(element); + switch (element.tagName){ + case 'FORM': + return eval('form_'+objId); + break; + default: + if (element.form) { + var formId=G.getId(element.form); + return eval('form_'+objId+'.getElementByName("'+objId+'")'); + } + } + } + + /*BLINK EFECT*/ + this.blinked=[]; + this.blinkedt0=[]; + this.autoFirstField=true; + this.pi=Math.atan(1)*4; + this.highLight = function(element){ + var newdiv = $dce('div'); + newdiv.style.position="absolute"; + newdiv.style.display="inline"; + newdiv.style.height=element.clientHeight+2; + newdiv.style.width=element.clientWidth+2; + newdiv.style.background = "#FF5555"; + element.style.backgroundColor='#FFCACA'; + element.parentNode.insertBefore(newdiv,element); + G.doBlinkEfect(newdiv,1000); + } + this.setOpacity=function(e,o){ + e.style.filter='alpha'; + if (e.filters) { + e.filters['alpha'].opacity=o*100; + } else { + e.style.opacity=o; + } + } + this.doBlinkEfect=function(div,T){ + var f=1/T; + var j=G.blinked.length; + G.blinked[j]=div; + G.blinkedt0[j]=(new Date()).getTime(); + for(var i=1;i<=20;i++){ + setTimeout("G.setOpacity(G.blinked["+j+"],0.3-0.3*Math.cos(2*G.pi*((new Date()).getTime()-G.blinkedt0["+j+"])*"+f+"));",T/20*i); + } + setTimeout("G.blinked["+j+"].parentNode.removeChild(G.blinked["+j+"]);G.blinked["+j+"]=null;",T/20*i); + } + var alertPanel; + this.alert=function(html, title , width, height, autoSize, modal, showModalColor, runScripts) + { + html='
    '+html+'
    '; + width = (width)?width:300; + height = (height)?height:200; + autoSize = (showModalColor===false)?false:true; + modal = (modal===false)?false:true; + showModalColor = (showModalColor===true)?true:false; + var alertPanel = new leimnud.module.panel(); + alertPanel.options = { + size:{ + w:width, + h:height + }, + position:{ + center:true + }, + title: title, + theme: "processmaker", + control: { + close :true, + roll :false, + drag :true, + resize :true + }, + fx: { + blinkToFront:true, + opacity :true, + drag:true, + modal: modal + } + }; + if(showModalColor===false) + { + alertPanel.styles.fx.opacityModal.Static='0'; + } + alertPanel.make(); + alertPanel.addContent(html); + if(runScripts) + { + var myScripts=alertPanel.elements.content.getElementsByTagName('SCRIPT'); + var sMyScripts=[]; + for(var rr=0; rr:'+obj[o]+"
    \n"; + } + else + dump=obj; + debugDiv = document.getElementById('debug'); + if (debugDiv) debugDiv.innerHTML=dump; + return dump; + } +} +var oDebug = new G_Debugger(); + +/* PACKAGE : date field + */ +var datePickerPanel; + +function showDatePicker(ev, formId, idName, value, min, max ) { + var coor = leimnud.dom.mouse(ev); + var coorx = ( coor.x - 50 ); + var coory = ( coor.y - 40 ); + datePickerPanel=new leimnud.module.panel(); + datePickerPanel.options={ + size:{ + w:275, + h:240 + }, + position:{ + x:coorx, + y:coory + }, + title:"Date Picker", + theme:"panel", + control:{ + close:true, + drag:true + }, + fx:{ + modal:true + } + }; + + datePickerPanel.setStyle={ + containerWindow:{ + borderWidth:0 + } + }; + datePickerPanel.make(); + datePickerPanel.idName = idName; + datePickerPanel.formId = formId; + + var sUrl = "/controls/calendar.php?v="+value+"&d="+value+"&min="+min+"&max="+max; + var r = new leimnud.module.rpc.xmlhttp({ + url: sUrl + }); + r.callback=leimnud.closure({ + Function:function(rpc){ + datePickerPanel.addContent(rpc.xmlhttp.responseText); + }, + args:r + }) + r.make(); + +} + +function moveDatePicker( n_datetime ) { + var dtmin_value = document.getElementById ( 'dtmin_value' ); + var dtmax_value = document.getElementById ( 'dtmax_value' ); + + var sUrl = "/controls/calendar.php?d="+n_datetime + '&min='+dtmin_value.value + '&max='+dtmax_value.value; + var r = new leimnud.module.rpc.xmlhttp({ + url:sUrl + }); + r.callback=leimnud.closure({ + Function:function(rpc){ + datePickerPanel.clearContent(); + datePickerPanel.addContent(rpc.xmlhttp.responseText); + }, + args:r + }) + r.make(); +} + +function selectDate( day ) { + var obj = document.getElementById ( 'span['+datePickerPanel.formId+'][' + datePickerPanel.idName + ']' ); + getField(datePickerPanel.idName, datePickerPanel.formId ).value = day; + obj.innerHTML = day; + datePickerPanel.remove(); +} + +function set_datetime(n_datetime, b_close) { + moveDatePicker(n_datetime); +} + +/* Functions for show and hide rows of a simple xmlform. + * @author David Callizaya + */ +function getRow( name ){ + try{ + var element = null; + if (typeof(name)==='string'){ + element = getField(name); + /** Set to hide/show of objects "checkgroup" and "radiogroup" + @author: Hector Cortez + */ + if(element == null){ + aElements = document.getElementsByName('form['+ name +'][]'); + if( aElements.length == 0) + aElements = document.getElementsByName('form['+ name +']'); + if( aElements.length ){ + element = aElements[aElements.length-1]; + } else + element = null; + } + } + if( element != null){ + while ( element.tagName !== 'TR' ) { + element=element.parentNode; + } + return element; + } else { + return null; + } + } catch(e){ + alert(e); + } + +} +var getRowById=getRow; + +function hideRow( element ){ //neyek + var row=getRow(element); + if (row) row.style.display='none'; + removeRequiredById(element); + delete row; +} + +var hideRowById=hideRow; +function showRow( element ){ + var row=getRow(element); + requiredFields = []; + sRequiredFields = document.getElementById('DynaformRequiredFields').value.replace(/%27/gi, '"'); + + fields = new String(sRequiredFields); + fields = stripslashes(fields); + requiredFieldsList = eval(fields); + + for(i=0; i 0 ){ + sRequiredFields = sRequiredFields.replace(/%27/gi, '"'); + } + + aRequiredFields = eval(sRequiredFields); + + var sMessage = ''; + var invalid_fields = Array(); + + for (var i = 0; i < aRequiredFields.length; i++) { + aRequiredFields[i].label=(aRequiredFields[i].label=='')?aRequiredFields[i].name:aRequiredFields[i].label; + if (!notValidateThisFields.inArray(aRequiredFields[i].name)) { + switch(aRequiredFields[i].type) { + case 'suggest': + var vtext1 = new input(getField(aRequiredFields[i].name+'_suggest')); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext1.failed(); + } else { + vtext1.passed(); + } + break; + case 'text': + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + break; + + case 'dropdown': + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + break; + + case 'textarea': + + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + + break; + + case 'password': + var vpass = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vpass.failed(); + } else { + vpass.passed(); + } + break; + + case 'currency': + var vcurr = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vcurr.failed(); + } else { + vcurr.passed(); + } + break; + + case 'percentage': + var vper = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vper.failed(); + } else { + vper.passed(); + } + break; + + case 'yesno': + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + break; + + case 'date': + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + break; + + case 'file': + var vtext = new input(getField(aRequiredFields[i].name)); + if(getField(aRequiredFields[i].name).value==''){ + invalid_fields.push(aRequiredFields[i].label); + vtext.failed(); + } else { + vtext.passed(); + } + break; + + case 'listbox': + var oAux = getField(aRequiredFields[i].name); + var bOneSelected = false; + for (var j = 0; j < oAux.options.length; j++) { + if (oAux.options[j].selected) { + bOneSelected = true; + j = oAux.options.length; + } + } + if(bOneSelected == false) + invalid_fields.push(aRequiredFields[i].label); + break; + + case 'radiogroup': + var x=aRequiredFields[i].name; + var oAux = document.getElementsByName('form['+ x +']'); + var bOneChecked = false; + for (var k = 0; k < oAux.length; k++) { + var r = oAux[k]; + if (r.checked) { + bOneChecked = true; + k = oAux.length; + } + } + + if(bOneChecked == false) + invalid_fields.push(aRequiredFields[i].label); + + break; + + case 'checkgroup': + var bOneChecked = false; + var aAux = document.getElementsByName('form[' + aRequiredFields[i].name + '][]'); + for (var k = 0; k < aAux.length; k++) { + if (aAux[k].checked) { + bOneChecked = true; + k = aAux.length; + } + } + if(!bOneChecked) { + invalid_fields.push(aRequiredFields[i].label); + } + break; + } + } + } + // call added by gustavo - cruz, gustavo-at-colosa.com validate grid forms + invalid_fields = validateGridForms(invalid_fields); + + if (invalid_fields.length > 0) { + //alert(G_STRINGS.ID_REQUIRED_FIELDS + ": \n\n" + sMessage); + + for(j=0; j 0)? ', ': ''; + sMessage += invalid_fields[j]; + } + + new leimnud.module.app.alert().make({ + label:G_STRINGS.ID_REQUIRED_FIELDS + ":

    [ " + sMessage + " ]", + width:450, + height:140 + (parseInt(invalid_fields.length/10)*10) + }); + return false; + } + else { + return true; + } +}; + +var getObject = function(sObject) { + var i; + var oAux = null; + var iLength = __aObjects__.length; + for (i = 0; i < iLength; i++) { + oAux = __aObjects__[i].getElementByName(sObject); + if (oAux) { + return oAux; + } + } + return oAux; +}; + +var saveAndRefreshForm = function(oObject) { + if (oObject) { + oObject.form.action += '&_REFRESH_=1'; + oObject.form.submit(); + } + else { + var oAux = window.document.getElementsByTagName('form'); + if (oAux.length > 0) { + oAux[0].action += '&_REFRESH_=1'; + oAux[0].submit(); + } + } +}; + +/** + * @function saveForm + * @author gustavo cruz gustavo[at]colosa[dot]com + * @param oObject is a reference to the object which is attached to the event, + * for example can be a save button, or anything else. + * @return This function only makes an ajax post to the form action + * @desc saveForm takes a object reference as a parameter, from that extracts + * the form and the form action references, then executes an Ajax request + * that post the form data to the action url, so the form is never + * refreshed or submited, at least not in the traditional sense. + **/ + +var saveForm = function(oObject) { + if (oObject) { + ajax_post(oObject.form.action,oObject.form,'POST'); + } + else { + var oAux = window.document.getElementsByTagName('form'); + if (oAux.length > 0) { + ajax_post(oAux[0].action,oAux[0],'POST'); + } + } +}; + +/** + * @function validateUrl + * @author gustavo cruz gustavo[at]colosa[dot]com + * @param url is the url to be validated. + * @return true/false. + * @desc takes a url as parameter and check returning a boolean if it's valid or not. + **/ + +var validateURL = function (url){ + var regexp = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/; + if (regexp.test(url)){ + return true; + } + else + { + return false; + } +} + +/** + * @function saveAndRedirectForm + * @author gustavo cruz gustavo[at]colosa[dot]com + * @param oObject is a reference to the object which is attached to the event, + * for example can be a save button, or anything else. + * @param oLocation is the url of tha redirect location. + * @return This function only makes a non refresh save a redirection action. + * @desc saveAndRedirectForm takes a object reference as a parameter, and + * then invoques the saveForm() function, so after the form data is saved, + * validates the url passed as parameter, if it's valid then redirects + * the browser to the oLocation url. + **/ + +var saveAndRedirectForm = function(oObject, oLocation) { + saveForm(oObject); + if (validateURL(oLocation)){ + document.location.href = oLocation; + } +}; + + +var removeRequiredById = function(sFieldName) { + if (!notValidateThisFields.inArray(sFieldName)) { + notValidateThisFields.push(sFieldName); + var oAux = document.getElementById('__notValidateThisFields__'); + if (oAux) { + oAux.value = notValidateThisFields.toJSONString(); + } + } +}; + +var enableRequiredById = function(sFieldName) { + if (notValidateThisFields.inArray(sFieldName)) { + var i; + var aAux = []; + for(i = 0; i < notValidateThisFields.length; i++) { + if(notValidateThisFields[i] != sFieldName) { + aAux.push(notValidateThisFields[i]); + } + } + notValidateThisFields = aAux; + var oAux = document.getElementById('__notValidateThisFields__'); + if (oAux) { + oAux.value = notValidateThisFields.toJSONString(); + } + } +}; + + +function dynaformVerifyFieldName(){ + pme_validating = true; + setTimeout('verifyFieldName1();',0); + return true; +} + +function verifyFieldName1(){ + var newFieldName=fieldName.value; + var validatedFieldName=getField("PME_VALIDATE_NAME",fieldForm).value; + var dField = new input(getField('PME_XMLNODE_NAME')); + + var valid=(newFieldName!=='')&&(((newFieldName!==savedFieldName)&&(validatedFieldName===''))||((newFieldName===savedFieldName))); + if (valid){ + dField.passed(); + getField("PME_ACCEPT",fieldForm).disabled=false; + }else{ + getField("PME_ACCEPT",fieldForm).disabled=true; + dField.failed(); + new leimnud.module.app.alert().make({ + label: G_STRINGS.DYNAFIELD_ALREADY_EXIST + }); + dField.focus(); + } + pme_validating=false; + return valid; +} + +/* +function sumElem(s,ans,fs){ + var sm=0; + for(var j=0;j 1) { + maskDecimal=maskDecimal[1].split("."); + } else { + maskDecimal=mask.split("."); + } + numDecimal=maskDecimal[1].length; + + ans.value=numb.toFixed(numDecimal); + return; + var nnum='',i=0,j=0; + //we get the number of digits + cnumb=numb.toString(); + cd = parseInt(Math.log(numb)/Math.LN10+1); + //now we're runing the mask and cd + fnb=cnumb.split("."); + maskp=mask.split(";"); + mask = (maskp.length > 1)? maskp[1]:mask; + while(i < numb.toString().length && j < mask.length){ + //alert(cnumb.charAt(i)+' ** '+mask.charAt(i)); + switch(mask.charAt(j)){ + case '#': + if(cnumb.charAt(i)!='.') { + nnum+=cnumb.charAt(i).toString(); + i++; + } + break; + + case '.': + nnum+=mask.charAt(j).toString(); + i=cd+1; + cd=i +4; + break + + default: + //alert(mask.charAt(i)); + nnum+=mask.charAt(j).toString(); + break; + } + + j++; + } + + ans.value=nnum; + +} + +function showRowsById(aFields){ + + for(i=0; i 0) { + + if (aObjects[0]) { + aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].name = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a'); + if (aObjects) { + if (aObjects[0]) { + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + } + } + break; + case 'select': + aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('select'); + if (aObjects) { + var oAux = document.createElement(aObjects[0].tagName); + oAux.name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + oAux.setAttribute("required", aObjects[0].getAttribute("required")); + oAux.id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + for ( var j = 0; j < aObjects[0].options.length; j++) { + var oOption = document.createElement('OPTION'); + oOption.value = aObjects[0].options[j].value; + oOption.text = aObjects[0].options[j].text; + oAux.options.add(oOption); + } + aObjects[0].parentNode.replaceChild(oAux, aObjects[0]); + /** + * note added by gustavo cruz gustavo-at-colosa-dot-com + * the piece of code below has been comented in revision 2123 + * i have tested it and seems to work well, please check this. + * aObjects[0].name.replace(/\[1\]/g, '\[' + + * (this.oGrid.rows.length - 2) + '\]'); + * aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, + * '\[' + (this.oGrid.rows.length - 2) + '\]'); + * aObjects[0].selectedIndex = 0; + */ + } + break; + case 'textarea': + aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('textarea'); + if (aObjects) { + aObjects[0].name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].value = ''; + } + break; + + case 'a': + aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a'); + if (aObjects) { + aObjects[0].name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].value = ''; + } + break; + + default: + oNewRow.getElementsByTagName('td')[i].innerHTML = ' '; + break; + } + aObjects = null; + } + } + } + if (this.aFields.length > 0) { + this.setFields(this.aFields, this.oGrid.rows.length - 2); + } + if (this.aFunctions.length > 0) { + this.assignFunctions(this.aFunctions, 'change', this.oGrid.rows.length - 2); + } + if (this.aFormulas.length > 0) { + this.assignFormulas(this.aFormulas, 'change', this.oGrid.rows.length - 2); + } + if (this.onaddrow) { + this.onaddrow(this.oGrid.rows.length - 2); + } + }; + this.deleteGridRow = function(sRow) { + var i, iRow, iRowAux, oAux, ooAux; + if (this.oGrid.rows.length == 3) { + new leimnud.module.app.alert().make( { + label : G_STRINGS.ID_MSG_NODELETE_GRID_ITEM + }); + return false; + } + new leimnud.module.app.confirm().make( { + label : G_STRINGS.ID_MSG_DELETE_GRID_ITEM, + action : function() { + //this.aElements = []; + sRow = sRow.replace('[', ''); + sRow = sRow.replace(']', ''); + iRow = Number(sRow); + + /* + * delete the respective session row grid variables from + * Dynaform - by Nyeke 0) { + + if (aObjects[0]) { + aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].name = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + aObjects = oCell1.getElementsByTagName('a'); + if (aObjects) { + if (aObjects[0]) { + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + } + } + + break; + case '= 0; j--) { aObjects1[0].options[j] = + * null; } + */ + aObjects1[0].options.length = 0; + for ( var j = 0; j < aObjects2[0].options.length; j++) { + var optn = $dce("OPTION"); + optn.text = aObjects2[0].options[j].text; + optn.value = aObjects2[0].options[j].value; + aObjects1[0].options[j] = optn; + } + aObjects1[0].value = vValue; + } + break; + case ' 0) { + this.unsetFields(); + }*/ + //this slice of code was added to fill the grid after to delete some row + this.aElements = []; + for (var k=1;k<= this.oGrid.rows.length-2;k++){ + for (var i = 0; i < this.aFields.length; i++) { + var j = k; + switch (this.aFields[i].sType) { + case 'text': + this.aElements.push(new G_Text(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName)); + this.aElements[this.aElements.length - 1].validate = this.aFields[i].oProperties.validate; + break; + case 'currency': + this.aElements.push(new G_Currency(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['+ this.aFields[i].sFieldName)); + break; + case 'percentage': + this.aElements.push(new G_Percentage(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j+ '][' + this.aFields[i].sFieldName)); + break; + case 'dropdown': + this.aElements.push(new G_DropDown(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['+ this.aFields[i].sFieldName)); + break; + } + j++; + } + } + + if (this.aFunctions.length > 0) { + + for (i = 0; i < this.aFunctions.length; i++) { + oAux = document.getElementById('form[' + this.sGridName + '][1][' + this.aFunctions[i].sFieldName + ']'); + if (oAux) { + switch (this.aFunctions[i].sFunction) { + case 'sum': + this.sum(false, oAux); + /* + aaAux=oAux.name.split(']['); + sNamef=aaAux[2].replace(']', ''); + var sumaSol = 0; + this.aElements.length; + var j=1;k=0; + for ( var i = 0; i < this.aElements.length; i++) { + nnName= this.aElements[i].name.split(']['); + if (nnName[2] == sNamef && j <= (this.oGrid.rows.length-2)){ + ooAux=this.getElementByName(j, nnName[2]); + + if(ooAux!=null){ + + sumaSol += parseFloat(G.cleanMask(ooAux.value() || 0, ooAux.mask).result.replace(/,/g, '')) + } + j++; + } + } + sumaSol = sumaSol.toFixed(2); + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + sNamef + ']'); + oAux.value = sumaSol; + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + sNamef + ']'); + oAux.innerHTML = sumaSol;//return; + */ + break; + case 'avg': + this.avg(false, oAux); + break; + } + } + } + } + if (this.ondeleterow) { + this.ondeleterow(); + } + + }.extend(this) + }); + }; + this.assignFunctions = function(aFields, sEvent, iRow) { + iRow = iRow || 1; + var i, j, oAux; + for (i = 0; i < aFields.length; i++) { + j = iRow; + while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + aFields[i].sFieldName + ']')) { + switch (aFields[i].sFunction) { + case 'sum': + leimnud.event.add(oAux, sEvent, { + method : this.sum, + instance : this, + event : true + }); + break; + case 'avg': + leimnud.event.add(oAux, sEvent, { + method : this.avg, + instance : this, + event : true + }); + break; + default: + leimnud.event.add(oAux, sEvent, { + method : aFields[i].sFunction, + instance : this, + event : true + }); + break; + } + j++; + } + } + }; + this.setFunctions = function(aFunctions) { + this.aFunctions = aFunctions; + this.assignFunctions(this.aFunctions, 'change'); + }; + this.sum = function(oEvent, oDOM) { + oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement); + var i, aAux, oAux, fTotal, sMask, nnName; + aAux = oDOM.name.split(']['); + i = 1; + fTotal = 0; + aAux[2] = aAux[2].replace(']', ''); + + var j=1; + for ( var k = 0; k < this.aElements.length; k++) { + nnName= this.aElements[k].name.split(']['); + if (aAux[2] == nnName[2] && j <= (this.oGrid.rows.length-2)){ + oAux=this.getElementByName(j, nnName[2]); + if(oAux!=null){ + fTotal += parseFloat(G.cleanMask(oAux.value() || 0, oAux.mask).result.replace(/,/g, '')) + } + j++; + } + } + /* + while (oAux = this.getElementByName(i, aAux[2])) { + fTotal += parseFloat(G.cleanMask(oAux.value() || 0, oAux.mask).result.replace(/,/g, '')); + sMask = oAux.mask; + i++; + }*/ + fTotal = fTotal.toFixed(2); + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']'); + oAux.value = fTotal; + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']'); + // oAux.innerHTML = G.toMask(fTotal, sMask).result; + oAux.innerHTML = fTotal; + }; + this.avg = function(oEvent, oDOM) { + oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement); + var i, aAux, oAux, fTotal, sMask; + aAux = oDOM.name.split(']['); + i = 1; + fTotal = 0; + aAux[2] = aAux[2].replace(']', ''); + while (oAux = this.getElementByName(i, aAux[2])) { + fTotal += parseFloat(G.cleanMask(oAux.value() || 0, oAux.mask).result.replace(/,/g, '')); + sMask = oAux.mask; + i++; + } + i--; + if (fTotal > 0) { + fTotal = (fTotal / i).toFixed(2); + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']'); + oAux.value = fTotal; + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']'); + // oAux.innerHTML = G.toMask((fTotal / i), sMask).result; + oAux.innerHTML = fTotal; + } else { + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']'); + oAux.value = 0; + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']'); + // oAux.innerHTML = G.toMask(0, sMask).result; + oAux.innerHTML = 0; + } + }; + this.assignFormulas = function(aFields, sEvent, iRow) { + iRow = iRow || 1; + var i, j, oAux; + for (i = 0; i < aFields.length; i++) { + j = iRow; + while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + aFields[i].sDependentOf + ']')) { + leimnud.event.add(oAux, sEvent, { + method : this.evaluateFormula, + instance : this, + args : [ oAux, aFields[i] ], + event : true + }); + j++; + } + } + }; + this.setFormulas = function(aFormulas) { + this.aFormulas = aFormulas; + this.assignFormulas(this.aFormulas, 'change'); + }; + this.evaluateFormula = function(oEvent, oDOM, oField) { + oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement); + var aAux, sAux, i, oAux; + var oContinue = true; + aAux = oDOM.name.split(']['); + sAux = oField.sFormula.replace(/\+|\-|\*|\/|\(|\)|\[|\]|\{|\}|\%|\$/g, ' '); + sAux = sAux.replace(/^\s+|\s+$/g, ''); + sAux = sAux.replace(/ /g, ' '); + sAux = sAux.replace(/ /g, ' '); + sAux = sAux.replace(/ /g, ' '); + sAux = sAux.replace(/ /g, ' '); + sAux = sAux.replace(/ /g, ' '); + aFields = sAux.split(' '); + aFields = aFields.unique(); + sAux = oField.sFormula; + for (i = 0; i < aFields.length; i++) { + if (!isNumber(aFields[i])) { + oAux = this.getElementByName(aAux[1], aFields[i]); + sAux = sAux.replace(new RegExp(aFields[i], "g"), "parseFloat(G.cleanMask(this.getElementByName(" + aAux[1] + ", '" + aFields[i] + "').value() || 0, '" + (oAux.sMask ? oAux.sMask : '') + + "').result.replace(/,/g, ''))"); + eval("if (!document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + aFields[i] + "]')) { oContinue = false; }"); + } + } + eval("if (!document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + "]')) { oContinue = false; }"); + if (oContinue) { + //we're selecting the mask to put in the field with the formula + for (i = 0; i < this.aFields.length; i++) { + if(oField.sFieldName==this.aFields[i].sFieldName) { + maskformula =this.aFields[i].oProperties.mask; + } + } + if(maskformula!=''){ + maskDecimal=maskformula.split(";"); + if(maskDecimal.length > 1) { + maskDecimal=maskDecimal[1].split("."); + } else { + maskDecimal=maskformula.split("."); + } + maskToPut=maskDecimal[1].length; + }else{ + maskToPut=0; + } + eval("document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + "]').value = (" + sAux + ').toFixed('+maskToPut+');'); + //eval("document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + "]').value = (" + sAux + ').toFixed(2);'); + if (this.aFunctions.length > 0) { + for (i = 0; i < this.aFunctions.length; i++) { + oAux = document.getElementById('form[' + this.sGridName + '][' + aAux[1] + '][' + this.aFunctions[i].sFieldName + ']'); + if (oAux) { + if (oAux.name == aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + ']') { + switch (this.aFunctions[i].sFunction) { + case 'sum': + this.sum(false, oAux); + break; + case 'avg': + this.avg(false, oAux); + break; + } + if (oAux.fireEvent) { + oAux.fireEvent('onchange'); + } else { + var evObj = document.createEvent('HTMLEvents'); + evObj.initEvent('change', true, true); + oAux.dispatchEvent(evObj); + } + } + } + } + } + } else { + new leimnud.module.app.alert().make( { + label : "Check your formula!\n\n" + oField.sFormula + }); + } + }; + + /*add*/ + this.deleteGridRownomsg = function(sRow) { + var i, iRow, iRowAux, oAux, ooAux; + + + //action : function() { + //this.aElements = []; + sRow = sRow.replace('[', ''); + sRow = sRow.replace(']', ''); + iRow = Number(sRow); + + /* + * delete the respective session row grid variables from + * Dynaform - by Nyeke 0) { + + if (aObjects[0]) { + aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + aObjects[0].name = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]'); + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + aObjects = oCell1.getElementsByTagName('a'); + if (aObjects) { + if (aObjects[0]) { + if (aObjects[0].onclick) { + sAux = new String(aObjects[0].onclick); + eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';'); + } + } + } + } + //oCell1.innerHTML= aux.innerHTM; + break; + case '= 0; j--) { aObjects1[0].options[j] = + * null; } + */ + aObjects1[0].options.length = 0; + for ( var j = 0; j < aObjects2[0].options.length; j++) { + var optn = $dce("OPTION"); + optn.text = aObjects2[0].options[j].text; + optn.value = aObjects2[0].options[j].value; + aObjects1[0].options[j] = optn; + } + aObjects1[0].value = vValue; + } + break; + case ' 0) { + this.unsetFields(); + }*/ + //this slice of code was added to fill the grid after to delete some row + this.aElements = []; + for (var k=1;k<= this.oGrid.rows.length-2;k++){ + for (var i = 0; i < this.aFields.length; i++) { + var j = k; + switch (this.aFields[i].sType) { + case 'text': + this.aElements.push(new G_Text(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName)); + this.aElements[this.aElements.length - 1].validate = this.aFields[i].oProperties.validate; + break; + case 'currency': + this.aElements.push(new G_Currency(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['+ this.aFields[i].sFieldName)); + break; + case 'percentage': + this.aElements.push(new G_Percentage(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j+ '][' + this.aFields[i].sFieldName)); + break; + case 'dropdown': + this.aElements.push(new G_DropDown(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['+ this.aFields[i].sFieldName)); + break; + } + j++; + } + } + + if (this.aFunctions.length > 0) { + + for (i = 0; i < this.aFunctions.length; i++) { + oAux = document.getElementById('form[' + this.sGridName + '][1][' + this.aFunctions[i].sFieldName + ']'); + if (oAux) { + switch (this.aFunctions[i].sFunction) { + case 'sum': + this.sum(false, oAux); + /* + aaAux=oAux.name.split(']['); + sNamef=aaAux[2].replace(']', ''); + var sumaSol = 0; + this.aElements.length; + var j=1;k=0; + for ( var i = 0; i < this.aElements.length; i++) { + nnName= this.aElements[i].name.split(']['); + if (nnName[2] == sNamef && j <= (this.oGrid.rows.length-2)){ + ooAux=this.getElementByName(j, nnName[2]); + + if(ooAux!=null){ + + sumaSol += parseFloat(G.cleanMask(ooAux.value() || 0, ooAux.mask).result.replace(/,/g, '')) + } + j++; + } + } + sumaSol = sumaSol.toFixed(2); + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + sNamef + ']'); + oAux.value = sumaSol; + oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + sNamef + ']'); + oAux.innerHTML = sumaSol;//return; + */ + break; + case 'avg': + this.avg(false, oAux); + break; + } + } + } + } + if (this.ondeleterow) { + this.ondeleterow(); + } + + //}.extend(this) + + }; + /*add end*/ +}; + +/** + * Delete the respective session row grid variables from Dynaform + * + * @Param grid + * [object: grid] + * @Param sRow + * [integer: row index] + * @author Erik Amaru Ortiz + */ +function deleteRowOnDybaform(grid, sRow) { + var oRPC = new leimnud.module.rpc.xmlhttp( { + url : '../gulliver/genericAjax', + args : 'request=deleteGridRowOnDynaform&gridname=' + grid.sGridName + '&rowpos=' + sRow + }); + oRPC.callback = function(rpc) { + if(oPanel) + oPanel.loader.hide(); + scs = rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + /** + * We verify if the debug panel is open, if it is-> update its content + */ + if ( typeof(oDebuggerPanel) != 'undefined' && oDebuggerPanel != null) { + oDebuggerPanel.clearContent(); + oDebuggerPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp( { + url : 'cases_Ajax', + args : 'action=showdebug' + }); + oRPC.callback = function(rpc) { + oDebuggerPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + oDebuggerPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + }.extend(this); + oRPC.make(); +} diff --git a/gulliver/js/highlight/core/AUTHORS.en.txt b/gulliver/js/highlight/core/AUTHORS.en.txt new file mode 100644 index 000000000..4c5a3c295 --- /dev/null +++ b/gulliver/js/highlight/core/AUTHORS.en.txt @@ -0,0 +1,19 @@ +Syntax highlighting with language autodetection. + +URL: http://softwaremaniacs.org/soft/highlight/en/ + +Original author and current maintainer: +Ivan Sagalaev + +Contributors: + +- Peter Leonov +- Victor Karamzin +- Vsevolod Solovyov +- Anton Kovalyov +- Nikita Ledyaev +- Konstantin Evdokimenko +- Dmitri Roudakov +- Yuri Ivanov +- Vladimir Ermakov +- Vladimir Gubarkov \ No newline at end of file diff --git a/gulliver/js/highlight/core/AUTHORS.ru.txt b/gulliver/js/highlight/core/AUTHORS.ru.txt new file mode 100644 index 000000000..ad39a904c --- /dev/null +++ b/gulliver/js/highlight/core/AUTHORS.ru.txt @@ -0,0 +1,19 @@ +ПодÑветка ÑинтакÑиÑа Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸ÐµÐ¼ Ñзыка. + +URL: http://softwaremaniacs.org/soft/highlight/ + +Первоначальный автор и ведущий проекта: +Иван Сагалаев + +ВнеÑли Ñвой вклад: + +- Петр Леонов +- Виктор Карамзин +- Ð’Ñеволод Соловьёв +- Ðнтон Ковалёв +- Ðикита ЛедÑев +- КонÑтантин Евдокименко +- Дмитрий Рудаков +- Юрий Иванов +- Владимир Ермаков +- Владимир Губарьков \ No newline at end of file diff --git a/gulliver/js/highlight/core/LICENSE b/gulliver/js/highlight/core/LICENSE new file mode 100644 index 000000000..e452d954c --- /dev/null +++ b/gulliver/js/highlight/core/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2006, Ivan Sagalaev +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of highlight.js nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/gulliver/js/highlight/core/export.html b/gulliver/js/highlight/core/export.html new file mode 100644 index 000000000..a2f3a782d --- /dev/null +++ b/gulliver/js/highlight/core/export.html @@ -0,0 +1,88 @@ + + + + + + + + Highlited code export + + + + + + + + + + + + + + + + +
    Write a code snippetGet HTML to paste anywhere (for actual styles and colors see sample.css)
    + + + + + +
    +
    +
    + Export script: Vladimir Gubarkov
    + Highlighting: highlight.js +
    + + \ No newline at end of file diff --git a/gulliver/js/highlight/core/highlight.js b/gulliver/js/highlight/core/highlight.js new file mode 100644 index 000000000..a873b64cd --- /dev/null +++ b/gulliver/js/highlight/core/highlight.js @@ -0,0 +1,429 @@ +/* +Syntax highlighting with language autodetection. +http://softwaremaniacs.org/soft/highlight/ +*/ + +var DEFAULT_LANGUAGES = ['python', 'ruby', 'perl', 'php', 'css', 'xml', 'html', 'django', 'javascript', 'java', 'cpp', 'sql', 'smalltalk']; +var ALL_LANGUAGES = (DEFAULT_LANGUAGES.join(',') + ',' + ['1c', 'axapta', 'delphi', 'rib', 'rsl', 'vbscript'].join(',')).split(','); +var LANGUAGE_GROUPS = { + 'xml': 'www', + 'html': 'www', + 'css': 'www', + 'django': 'www', + 'python': 'dynamic', + 'perl': 'dynamic', + 'php': 'dynamic', + 'ruby': 'dynamic', + 'cpp': 'static', + 'java': 'static', + 'delphi': 'static' +} + +var IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*'; +var UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*'; +var NUMBER_RE = '\\b\\d+(\\.\\d+)?'; +var C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)'; + +// Common modes +var APOS_STRING_MODE = { + className: 'string', + begin: '\'', end: '\'', + illegal: '\\n', + contains: ['escape'], + relevance: 0 +} +var QUOTE_STRING_MODE = { + className: 'string', + begin: '"', end: '"', + illegal: '\\n', + contains: ['escape'], + relevance: 0 +} +var BACKSLASH_ESCAPE = { + className: 'escape', + begin: '\\\\.', end: '^', + relevance: 0 +} +var C_LINE_COMMENT_MODE = { + className: 'comment', + begin: '//', end: '$', + relevance: 0 +} +var C_BLOCK_COMMENT_MODE = { + className: 'comment', + begin: '/\\*', end: '\\*/' +} +var HASH_COMMENT_MODE = { + className: 'comment', + begin: '#', end: '$' +} +var C_NUMBER_MODE = { + className: 'number', + begin: C_NUMBER_RE, end: '^', + relevance: 0 +} + +var LANGUAGES = {} +var selected_languages = {}; + +function Highlighter(language_name, value) { + function subMode(lexem) { + if (!modes[modes.length - 1].contains) + return null; + for (var i in modes[modes.length - 1].contains) { + var className = modes[modes.length - 1].contains[i]; + for (var key in language.modes) + if (language.modes[key].className == className && language.modes[key].beginRe.test(lexem)) + return language.modes[key]; + }//for + return null; + }//subMode + + function endOfMode(mode_index, lexem) { + if (modes[mode_index].end && modes[mode_index].endRe.test(lexem)) + return 1; + if (modes[mode_index].endsWithParent) { + var level = endOfMode(mode_index - 1, lexem); + return level ? level + 1 : 0; + }//if + return 0; + }//endOfMode + + function isIllegal(lexem) { + if (!modes[modes.length - 1].illegalRe) + return false; + return modes[modes.length - 1].illegalRe.test(lexem); + }//isIllegal + + function eatModeChunk(value, index) { + if (!modes[modes.length - 1].terminators) { + var terminators = []; + + if (modes[modes.length - 1].contains) + for (var key in language.modes) { + if (contains(modes[modes.length - 1].contains, language.modes[key].className) && + !contains(terminators, language.modes[key].begin)) + terminators[terminators.length] = language.modes[key].begin; + }//for + + var mode_index = modes.length - 1; + do { + if (modes[mode_index].end && !contains(terminators, modes[mode_index].end)) + terminators[terminators.length] = modes[mode_index].end; + mode_index--; + } while (modes[mode_index + 1].endsWithParent); + + if (modes[modes.length - 1].illegal) + if (!contains(terminators, modes[modes.length - 1].illegal)) + terminators[terminators.length] = modes[modes.length - 1].illegal; + + var terminator_re = '(' + terminators[0]; + for (var i = 0; i < terminators.length; i++) + terminator_re += '|' + terminators[i]; + terminator_re += ')'; + modes[modes.length - 1].terminators = langRe(language, terminator_re); + }//if + value = value.substr(index); + var match = modes[modes.length - 1].terminators.exec(value); + if (!match) + return [value, '', true]; + if (match.index == 0) + return ['', match[0], false]; + else + return [value.substr(0, match.index), match[0], false]; + }//eatModeChunk + + function escape(value) { + return value.replace(/&/gm, '&').replace(//gm, '>'); + }//escape + + function keywordMatch(mode, match) { + var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0] + for (var className in mode.keywordGroups) { + var value = mode.keywordGroups[className].hasOwnProperty(match_str); + if (value) + return [className, value]; + }//for + return false; + }//keywordMatch + + function processKeywords(buffer) { + var mode = modes[modes.length - 1]; + if (!mode.keywords || !mode.lexems) + return escape(buffer); + if (!mode.lexemsRe) { + var lexems = []; + for (var key in mode.lexems) + if (!contains(lexems, mode.lexems[key])) + lexems[lexems.length] = mode.lexems[key]; + var lexems_re = '(' + lexems[0]; + for (var i = 1; i < lexems.length; i++) + lexems_re += '|' + lexems[i]; + lexems_re += ')'; + mode.lexemsRe = langRe(language, lexems_re, true); + }//if + var result = ''; + var last_index = 0; + mode.lexemsRe.lastIndex = 0; + var match = mode.lexemsRe.exec(buffer); + while (match) { + result += escape(buffer.substr(last_index, match.index - last_index)); + keyword_match = keywordMatch(mode, match); + if (keyword_match) { + keyword_count += keyword_match[1]; + result += '' + escape(match[0]) + ''; + } else { + result += escape(match[0]); + }//if + last_index = mode.lexemsRe.lastIndex; + match = mode.lexemsRe.exec(buffer); + }//while + result += escape(buffer.substr(last_index, buffer.length - last_index)); + return result; + }//processKeywords + + function processModeInfo(buffer, lexem, end) { + if (end) { + result += processKeywords(modes[modes.length - 1].buffer + buffer); + return; + }//if + if (isIllegal(lexem)) + throw 'Illegal'; + var new_mode = subMode(lexem); + if (new_mode) { + modes[modes.length - 1].buffer += buffer; + result += processKeywords(modes[modes.length - 1].buffer); + if (new_mode.excludeBegin) { + result += lexem + ''; + new_mode.buffer = ''; + } else { + result += ''; + new_mode.buffer = lexem; + }//if + modes[modes.length] = new_mode; + relevance += modes[modes.length - 1].relevance != undefined ? modes[modes.length - 1].relevance : 1; + return; + }//if + var end_level = endOfMode(modes.length - 1, lexem); + if (end_level) { + modes[modes.length - 1].buffer += buffer; + if (modes[modes.length - 1].excludeEnd) { + result += processKeywords(modes[modes.length - 1].buffer) + '' + lexem; + } else { + result += processKeywords(modes[modes.length - 1].buffer + lexem) + ''; + } + while (end_level > 1) { + result += ''; + end_level--; + modes.length--; + }//while + modes.length--; + modes[modes.length - 1].buffer = ''; + return; + }//if + }//processModeInfo + + function highlight(value) { + var index = 0; + language.defaultMode.buffer = ''; + do { + var mode_info = eatModeChunk(value, index); + processModeInfo(mode_info[0], mode_info[1], mode_info[2]); + index += mode_info[0].length + mode_info[1].length; + } while (!mode_info[2]); + if(modes.length > 1) + throw 'Illegal'; + }//highlight + + this.language_name = language_name; + var language = LANGUAGES[language_name]; + var modes = [language.defaultMode]; + var relevance = 0; + var keyword_count = 0; + var result = ''; + try { + highlight(value); + this.relevance = relevance; + this.keyword_count = keyword_count; + this.result = result; + } catch (e) { + if (e == 'Illegal') { + this.relevance = 0; + this.keyword_count = 0; + this.result = escape(value); + } else { + throw e; + }//if + }//try +}//Highlighter + +function contains(array, item) { + if (!array) + return false; + for (var key in array) + if (array[key] == item) + return true; + return false; +}//contains + +function blockText(block) { + var result = ''; + for (var i = 0; i < block.childNodes.length; i++) + if (block.childNodes[i].nodeType == 3) + result += block.childNodes[i].nodeValue; + else if (block.childNodes[i].nodeName == 'BR') + result += '\n'; + else + throw 'Complex markup'; + return result; +}//blockText + +function initHighlight(block) { + if (block.className.search(/\bno\-highlight\b/) != -1) + return; + try { + blockText(block); + } catch (e) { + if (e == 'Complex markup') + return; + }//try + var classes = block.className.split(/\s+/); + for (var i = 0; i < classes.length; i++) { + if (LANGUAGES[classes[i]]) { + highlightLanguage(block, classes[i]); + return; + }//if + }//for + highlightAuto(block); +}//initHighlight + +function highlightLanguage(block, language) { + var highlight = new Highlighter(language, blockText(block)); + // See these 4 lines? This is IE's notion of "block.innerHTML = result". Love this browser :-/ + var container = $dce('div'); + container.innerHTML = '
    ' + highlight.result + '
    '; + var environment = block.parentNode.parentNode; + environment.replaceChild(container.firstChild, block.parentNode); +}//highlightLanguage + +function highlightAuto(block) { + var result = null; + var language = ''; + var max_relevance = 2; + var relevance = 0; + var block_text = blockText(block); + for (var key in selected_languages) { + var highlight = new Highlighter(key, block_text); + relevance = highlight.keyword_count + highlight.relevance; + if (relevance > max_relevance) { + max_relevance = relevance; + result = highlight; + }//if + }//for + + if(result) { + // See these 4 lines? This is IE's notion of "block.innerHTML = result". Love this browser :-/ + var container = $dce('div'); + container.innerHTML = '
    ' + result.result + '
    '; + var environment = block.parentNode.parentNode; + environment.replaceChild(container.firstChild, block.parentNode); + }//if +}//highlightAuto + +function langRe(language, value, global) { + var mode = 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : ''); + return new RegExp(value, mode); +}//re + +function compileRes() { + for (var i in LANGUAGES) { + var language = LANGUAGES[i]; + for (var key in language.modes) { + if (language.modes[key].begin) + language.modes[key].beginRe = langRe(language, '^' + language.modes[key].begin); + if (language.modes[key].end) + language.modes[key].endRe = langRe(language, '^' + language.modes[key].end); + if (language.modes[key].illegal) + language.modes[key].illegalRe = langRe(language, '^(?:' + language.modes[key].illegal + ')'); + language.defaultMode.illegalRe = langRe(language, '^(?:' + language.defaultMode.illegal + ')'); + }//for + }//for +}//compileRes + +function compileKeywords() { + + function compileModeKeywords(mode) { + if (!mode.keywordGroups) { + for (var key in mode.keywords) { + if (mode.keywords[key] instanceof Object) + mode.keywordGroups = mode.keywords; + else + mode.keywordGroups = {'keyword': mode.keywords}; + break; + }//for + }//if + }//compileModeKeywords + + for (var i in LANGUAGES) { + var language = LANGUAGES[i]; + compileModeKeywords(language.defaultMode); + for (var key in language.modes) { + compileModeKeywords(language.modes[key]); + }//for + }//for +}//compileKeywords + +function initHighlighting() { + if (initHighlighting.called) + return; + initHighlighting.called = true; + compileRes(); + compileKeywords(); + if (arguments.length) { + for (var i = 0; i < arguments.length; i++) { + if (LANGUAGES[arguments[i]]) { + selected_languages[arguments[i]] = LANGUAGES[arguments[i]]; + }//if + }//for + } else + selected_languages = LANGUAGES; + var pres = document.getElementsByTagName('pre'); + for (var i = 0; i < pres.length; i++) { + if (pres[i].firstChild && pres[i].firstChild.nodeName == 'CODE') + initHighlight(pres[i].firstChild); + }//for +}//initHighlighting + +function injectScripts(languages) { + var scripts = document.getElementsByTagName('SCRIPT'); + for (var i=0; i < scripts.length; i++) { + if (scripts[i].src.match(/highlight\.js(\?.+)?$/)) { + var path = scripts[i].src.replace(/highlight\.js(\?.+)?$/, ''); + break; + }//if + }//for + if (languages.length == 0) { + languages = DEFAULT_LANGUAGES; + }//if + var injected = {} + for (var i=0; i < languages.length; i++) { + var filename = LANGUAGE_GROUPS[languages[i]] ? LANGUAGE_GROUPS[languages[i]] : languages[i]; + if (!injected[filename]) { + document.write(''); + injected[filename] = true; + }//if + }//for +}//injectScripts + +function initHighlightingOnLoad() { + var original_arguments = arguments; + injectScripts(arguments); + var handler = function(){initHighlighting.apply(null, original_arguments)}; + if (window.addEventListener) { + window.addEventListener('DOMContentLoaded', handler, false); + window.addEventListener('load', handler, false); + } else if (window.attachEvent) + window.attachEvent('onload', handler); + else + window.onload = handler; +}//initHighlightingOnLoad \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/1c.js b/gulliver/js/highlight/core/languages/1c.js new file mode 100644 index 000000000..a57dc03b1 --- /dev/null +++ b/gulliver/js/highlight/core/languages/1c.js @@ -0,0 +1,84 @@ +var IDENT_RE_RU = '[a-zA-Zа-ÑÐ-Я][a-zA-Z0-9_а-ÑÐ-Я]*'; +var NUMBER_RE = '\\b\\d+(\\.\\d+)?'; + +var OneS_KEYWORDS = {'процедура':1,'функциÑ':1,'ÑкÑпорт':1,'перем':1,'конецфункции':1,'конецпроцедуры':1,'еÑли':1,'тогда':1,'иначе':1,'иначееÑли':1,'конецеÑли':1,'попытка':1,'иÑключение':1,'конецпопытки':1,'ложь':1,'иÑтина':1,'неопределено':1,'и':1,'или':1,'не':1,'null':1,'длÑ':1,'каждого':1,'из':1,'по':1,'цикл':1,'конеццикла':1}; + +LANGUAGES['1c'] = { + defaultMode: { + lexems: [IDENT_RE_RU], + contains: ['comment', 'string', 'function', 'preprocessor', 'number'], + keywords: OneS_KEYWORDS + }, + case_insensitive: true, + modes: [ + C_LINE_COMMENT_MODE, + { + className: 'string', + begin: '"', end: '"', + contains: ['dquote'], + relevance: 0 + }, + { + className: 'string', + begin: '"', end: '$', + contains: ['dquote'] + }, + { + className: 'string', + begin: '\\|', end: '$', + contains: ['dquote'] + }, + { + className: 'string', + begin: '\\|', end: '"', + contains: ['dquote'] + }, + { + className: 'dquote', + begin: '""', end: '^' + }, + { + className: 'number', + begin: NUMBER_RE, end: '^', + relevance: 0 + }, + { + className: 'title', + lexems: [IDENT_RE_RU], + begin: IDENT_RE_RU, end: '^' + }, + { + className: 'params', + begin: '\\(', end: '\\)', + lexems: [IDENT_RE_RU], + keywords: {'знач':1}, + contains: ['string'] + }, + { + className: 'function', + begin: '(процедура|функциÑ)', end: '$', + lexems: [IDENT_RE_RU], + keywords: {'процедура': 1, 'ÑкÑпорт':1, 'функциÑ': 1}, + contains: ['title','tail','comment'], + relevance: 0 + }, + { + className: 'tail', + begin: '^', endsWithParent: true, + lexems: [IDENT_RE_RU], + contains: ['params', 'export'] + }, + { + className: 'export', + begin: 'ÑкÑпорт', endsWithParent: true, + lexems: [IDENT_RE_RU], + keywords: {'ÑкÑпорт': 1}, + contains: ['comment'] + }, + { + className: 'preprocessor', + begin: '#', end: '$', + lexems: [IDENT_RE_RU] + } + ] +};//1c \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/axapta.js b/gulliver/js/highlight/core/languages/axapta.js new file mode 100644 index 000000000..32ab1f30d --- /dev/null +++ b/gulliver/js/highlight/core/languages/axapta.js @@ -0,0 +1,52 @@ +/* + +Axapta definition (Ñ) Dmitri Roudakov + +*/ +LANGUAGES.axapta = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + contains: ['comment', 'string', 'class', 'number', 'preprocessor'], + keywords: {'false': 1, 'int': 1, 'abstract': 1, 'private': 1, 'char': 1, 'interface': 1, 'boolean': 1, 'static': 1, 'null': 1, 'if': 1, 'for': 1, 'true': 1, 'while': 1, 'long': 1, 'throw': 1, 'finally': 1, 'protected': 1, 'extends': 1, 'final': 1, 'implements': 1, 'return': 1, 'void': 1, 'enum': 1, 'else': 1, 'break': 1, 'new': 1, 'catch': 1, 'byte': 1, 'super': 1, 'class': 1, 'case': 1, 'short': 1, 'default': 1, 'double': 1, 'public': 1, 'try': 1, 'this': 1, 'switch': 1, 'continue': 1, + 'reverse':1, 'firstfast':1,'firstonly':1,'forupdate':1,'nofetch':1, 'sum':1, 'avg':1, 'minof':1, 'maxof':1, 'count':1, 'order':1, 'group':1, 'by':1, 'asc':1, 'desc':1, 'index':1, 'hint':1, 'like':1, + 'dispaly':1, 'edit':1, 'client':1, 'server':1, 'ttsbegin':1, 'ttscommit':1, + 'str':1, 'real':1, 'date':1, 'container':1, 'anytype':1, 'common':1, 'div':1,'mod':1 + } + }, + modes: [ + { + className: 'class', + lexems: [UNDERSCORE_IDENT_RE], + begin: '(class |interface )', end: '{', + illegal: ':', + keywords: {'class': 1, 'interface': 1}, + contains: ['inheritance', 'title'] + }, + { + className: 'inheritance', + begin: '(implements|extends)', end: '^', + lexems: [IDENT_RE], + keywords: {'extends': 1, 'implements': 1}, + relevance: 10 + }, + { + className: 'title', + begin: UNDERSCORE_IDENT_RE, end: '^' + }, + { + className: 'params', + begin: '\\(', end: '\\)', + contains: ['string', 'annotation'] + }, + C_NUMBER_MODE, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + C_LINE_COMMENT_MODE, + C_BLOCK_COMMENT_MODE, + { + className: 'preprocessor', + begin: '#', end: '$' + } + ] +};//axapta \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/dynamic.js b/gulliver/js/highlight/core/languages/dynamic.js new file mode 100644 index 000000000..9bf5013dc --- /dev/null +++ b/gulliver/js/highlight/core/languages/dynamic.js @@ -0,0 +1,319 @@ +LANGUAGES.python = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + illegal: '()', + contains: ['comment', 'string', 'function', 'class', 'number', 'decorator'], + keywords: {'and': 1, 'elif': 1, 'is': 1, 'global': 1, 'as': 1, 'in': 1, 'if': 1, 'from': 1, 'raise': 1, 'for': 1, 'except': 1, 'finally': 1, 'print': 1, 'import': 1, 'pass': 1, 'None': 1, 'return': 1, 'exec': 1, 'else': 1, 'break': 1, 'not': 1, 'with': 1, 'class': 1, 'assert': 1, 'yield': 1, 'try': 1, 'while': 1, 'continue': 1, 'del': 1, 'or': 1, 'def': 1, 'lambda': 1} + }, + modes: [ + { + className: 'function', + lexems: [UNDERSCORE_IDENT_RE], + begin: '\\bdef ', end: ':', + illegal: '$', + keywords: {'def': 1}, + contains: ['title', 'params'], + relevance: 10 + }, + { + className: 'class', + lexems: [UNDERSCORE_IDENT_RE], + begin: '\\bclass ', end: ':', + illegal: '[${]', + keywords: {'class': 1}, + contains: ['title', 'params',], + relevance: 10 + }, + { + className: 'title', + begin: UNDERSCORE_IDENT_RE, end: '^' + }, + { + className: 'params', + begin: '\\(', end: '\\)', + contains: ['string'] + }, + HASH_COMMENT_MODE, + C_NUMBER_MODE, + { + className: 'string', + begin: '\'\'\'', end: '\'\'\'', + relevance: 10 + }, + { + className: 'string', + begin: '"""', end: '"""', + relevance: 10 + }, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + { + className: 'string', + begin: 'r\'', end: '\'', + relevance: 10 + }, + { + className: 'string', + begin: 'r"', end: '"', + relevance: 10 + }, + { + className: 'string', + begin: 'u\'', end: '(^|[^\\\\])\'', + relevance: 10 + }, + { + className: 'string', + begin: 'u"', end: '(^|[^\\\\])"', + relevance: 10 + }, + { + className: 'string', + begin: 'ur\'', end: '\'', + relevance: 10 + }, + { + className: 'string', + begin: 'ur"', end: '"', + relevance: 10 + }, + { + className: 'decorator', + begin: '@', end: '$' + } + ] +};//python + + +/* + +Perl definition (Ñ) Peter Leonov +Test you perl code here: http://wiki.cmsbuilder.ru/Highlite_test + +*/ + +var PERL_NUMBER_RE = '(\\b0[0-7]+)|(\\b0x[0-9a-fA-F]+)|(\\b[1-9]\\d*(\\.\\d+)?)|0\\b'; +var PERL_KEYWORDS = {'getpwent': 1, 'getservent': 1, 'quotemeta': 1, 'msgrcv': 1, 'scalar': 1, 'kill': 1, 'dbmclose': 1, 'undef': 1, 'lc': 1, 'ma': 1, 'syswrite': 1, 'tr': 1, 'send': 1, 'umask': 1, 'sysopen': 1, 'shmwrite': 1, 'vec': 1, 'qx': 1, 'utime': 1, 'local': 1, 'oct': 1, 'semctl': 1, 'localtime': 1, 'readpipe': 1, 'do': 1, 'return': 1, 'format': 1, 'read': 1, 'sprintf': 1, 'dbmopen': 1, 'pop': 1, 'getpgrp': 1, 'not': 1, 'getpwnam': 1, 'rewinddir': 1, 'qq': 1, 'fileno': 1, 'qw': 1, 'endprotoent': 1, 'wait': 1, 'sethostent': 1, 'bless': 1, 's': 1, 'opendir': 1, 'continue': 1, 'each': 1, 'sleep': 1, 'endgrent': 1, 'shutdown': 1, 'dump': 1, 'chomp': 1, 'connect': 1, 'getsockname': 1, 'die': 1, 'socketpair': 1, 'close': 1, 'flock': 1, 'exists': 1, 'index': 1, 'shmget': 1, 'sub': 1, 'for': 1, 'endpwent': 1, 'redo': 1, 'lstat': 1, 'msgctl': 1, 'setpgrp': 1, 'abs': 1, 'exit': 1, 'select': 1, 'print': 1, 'ref': 1, 'gethostbyaddr': 1, 'unshift': 1, 'fcntl': 1, 'syscall': 1, 'goto': 1, 'getnetbyaddr': 1, 'join': 1, 'gmtime': 1, 'symlink': 1, 'semget': 1, 'splice': 1, 'x': 1, 'getpeername': 1, 'recv': 1, 'log': 1, 'setsockopt': 1, 'cos': 1, 'last': 1, 'reverse': 1, 'gethostbyname': 1, 'getgrnam': 1, 'study': 1, 'formline': 1, 'endhostent': 1, 'times': 1, 'chop': 1, 'length': 1, 'gethostent': 1, 'getnetent': 1, 'pack': 1, 'getprotoent': 1, 'getservbyname': 1, 'rand': 1, 'mkdir': 1, 'pos': 1, 'chmod': 1, 'y': 1, 'substr': 1, 'endnetent': 1, 'printf': 1, 'next': 1, 'open': 1, 'msgsnd': 1, 'readdir': 1, 'use': 1, 'unlink': 1, 'getsockopt': 1, 'getpriority': 1, 'rindex': 1, 'wantarray': 1, 'hex': 1, 'system': 1, 'getservbyport': 1, 'endservent': 1, 'int': 1, 'chr': 1, 'untie': 1, 'rmdir': 1, 'prototype': 1, 'tell': 1, 'listen': 1, 'fork': 1, 'shmread': 1, 'ucfirst': 1, 'setprotoent': 1, 'else': 1, 'sysseek': 1, 'link': 1, 'getgrgid': 1, 'shmctl': 1, 'waitpid': 1, 'unpack': 1, 'getnetbyname': 1, 'reset': 1, 'chdir': 1, 'grep': 1, 'split': 1, 'require': 1, 'caller': 1, 'lcfirst': 1, 'until': 1, 'warn': 1, 'while': 1, 'values': 1, 'shift': 1, 'telldir': 1, 'getpwuid': 1, 'my': 1, 'getprotobynumber': 1, 'delete': 1, 'and': 1, 'sort': 1, 'uc': 1, 'defined': 1, 'srand': 1, 'accept': 1, 'package': 1, 'seekdir': 1, 'getprotobyname': 1, 'semop': 1, 'our': 1, 'rename': 1, 'seek': 1, 'if': 1, 'q': 1, 'chroot': 1, 'sysread': 1, 'setpwent': 1, 'no': 1, 'crypt': 1, 'getc': 1, 'chown': 1, 'sqrt': 1, 'write': 1, 'setnetent': 1, 'setpriority': 1, 'foreach': 1, 'tie': 1, 'sin': 1, 'msgget': 1, 'map': 1, 'stat': 1, 'getlogin': 1, 'unless': 1, 'elsif': 1, 'truncate': 1, 'exec': 1, 'keys': 1, 'glob': 1, 'tied': 1, 'closedir': 1, 'ioctl': 1, 'socket': 1, 'readlink': 1, 'eval': 1, 'xor': 1, 'readline': 1, 'binmode': 1, 'setservent': 1, 'eof': 1, 'ord': 1, 'bind': 1, 'alarm': 1, 'pipe': 1, 'atan2': 1, 'getgrent': 1, 'exp': 1, 'time': 1, 'push': 1, 'setgrent': 1, 'gt': 1, 'lt': 1, 'or': 1, 'ne': 1, 'm': 1}; + +LANGUAGES.perl = { + defaultMode: { + lexems: [IDENT_RE], + contains: ['comment', 'string', 'number', 'regexp', 'sub', 'variable', 'operator', 'pod', 'identifier'], + keywords: PERL_KEYWORDS + }, + modes: [ + + // variables + { + className: 'variable', + begin: '\\$\\d', end: '^', + relevance: 5 + }, + { + className: 'variable', + begin: '[\\$\\%\\@\\*](\\^\\w\\b|#\\w+|[^\\s\\w{]|{\\w+}|\\w+)', end: '^' + }, + + // numbers and strings + { + className: 'number', + begin: PERL_NUMBER_RE, end: '^', + relevance: 0 + }, + { + className: 'string', + begin: 'q[qwxr]?\\(', end: '[^\\\\]\\)', + relevance: 10 + }, + { + className: 'string', + begin: 'qw\\s+q', end: 'q', + relevance: 10 + }, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + { + className: 'string', + begin: '`', end: '`', + contains: ['escape'] + }, + + // regexps + { + className: 'regexp', + begin: '(s|tr|y)(/.*?[^\\\\]/|//)(.*?[^\\\\]/|/)[a-z]*', end: '^', + relevance: 10 + }, + { + className: 'regexp', + begin: '(m|qr)?//[cgimosxe]*', end: '^', + relevance: 0 // allows empty "//" which is a common comment delimiter in other languages + }, + { + className: 'regexp', + begin: '(m|qr)?/.*?[^\\\\/]/[cgimosxe]*', end: '^' + }, + + // bareword context + { + className: 'string', + begin: '{\\w+}', end: '^', + relevance: 0 + }, + { + className: 'string', + begin: '\-?\\w+\\s*\\=\\>', end: '^', + relevance: 5 + }, + + // subroutines + { + className: 'sub', + begin: '\\bsub\\b', end: '(\\s*\\(.*?\\))?[;{]', + lexems: [IDENT_RE], + keywords: {'sub':1}, + contains: ['identifier'], + relevance: 10 + }, + + // operators + { + className: 'operator', + begin: '-\\w\\b', end: '^' + }, + + // comments + HASH_COMMENT_MODE, + + // pod + { + className: 'pod', + begin: '\\=\\w', end: '\\=cut' + }, + + // identifiers + { + className: 'identifier', + begin: '\\b[a-zA-Z]\\w*\\b', end: '^', + lexems: [IDENT_RE], + keywords: PERL_KEYWORDS, + relevance: 0 + } + ] +};//perl + + +/* + +PHP5 definition (Ñ) Victor Karamzin + +*/ +PHP5_KEYWORDS = {'and': 1, 'include_once': 1, 'list': 1, 'abstract': 1, 'global': 1, 'private': 1, 'echo': 1, 'interface': 1, 'as': 1, 'static': 1, 'endswitch': 1, 'array': 1, 'null': 1, 'if': 1, 'endwhile': 1, 'or': 1, 'const': 1, 'for': 1, 'endforeach': 1, 'self': 1, 'var': 1, 'while': 1, 'isset': 1, 'public': 1, 'protected': 1, 'exit': 1, 'foreach': 1, 'throw': 1, 'elseif': 1, 'extends': 1, 'include': 1, '__FILE__': 1, 'empty': 1, 'require_once': 1, 'function': 1, 'do': 1, 'xor': 1, 'return': 1, 'implements': 1, 'parent': 1, 'clone': 1, 'use': 1, '__CLASS__': 1, '__LINE__': 1, 'else': 1, 'break': 1, 'print': 1, 'eval': 1, 'new': 1, 'catch': 1, '__METHOD__': 1, 'class': 1, 'case': 1, 'exception': 1, 'php_user_filter': 1, 'default': 1, 'die': 1, 'require': 1, '__FUNCTION__': 1, 'enddeclare': 1, 'final': 1, 'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'endfor': 1, 'endif': 1, 'declare': 1, 'unset': 1}; + +PHP_IDENTIFIER_RE = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'; + +LANGUAGES.php = { + defaultMode: { + lexems: [IDENT_RE], + contains: ['comment', 'number', 'string', 'variable'], + keywords: PHP5_KEYWORDS + }, + case_insensitive: true, + modes: [ + C_LINE_COMMENT_MODE, + HASH_COMMENT_MODE, + { + className: 'comment', + begin: '/\\*', end: '\\*/', + contains: ['phpdoc'] + }, + { + className: 'phpdoc', + begin: '\\s@[A-Za-z]+', end: '^', + relevance: 10 + }, + C_NUMBER_MODE, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + { + className: 'variable', + begin: '\\$' + PHP_IDENTIFIER_RE, end: '^' + }, + ] +};//php + + +/* + +Ruby definition (Ñ) Anton Kovalyov + +*/ +LANGUAGES.ruby = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + contains: ['comment', 'string', 'class', 'function', 'symbol'], + keywords: {'and': 1, 'false': 1, 'then': 1, 'defined': 1, 'module': 1, 'in': 1, 'return': 1, 'redo': 1, 'if': 1, 'BEGIN': 1, 'retry': 1, 'end': 1, 'for': 1, 'true': 1, 'self': 1, 'when': 1, 'next': 1, 'until': 1, 'do': 1, 'begin': 1, 'unless': 1, 'END': 1, 'rescue': 1, 'nil': 1, 'else': 1, 'break': 1, 'undef': 1, 'not': 1, 'super': 1, 'class': 1, 'case': 1, 'require': 1, 'yield': 1, 'alias': 1, 'while': 1, 'ensure': 1, 'elsif': 1, 'or': 1, 'def': 1} + }, + modes: [ + HASH_COMMENT_MODE, + { + className: 'comment', + begin: '^\\=begin', end: '^\\=end', + relevance: 10 + }, + { + className: 'string', + begin: '\'', end: '(^|[^\\\\])\'', + contains: ['subst'], + relevance: 0 + }, + { + className: 'string', + begin: '"', end: '(^|[^\\\\])"', + contains: ['subst'], + relevance: 0 + }, + { + className: 'subst', + begin: '#\\{', end: '\}', + contains: ['string'], + relevance: 10 + }, + { + className: 'function', + lexems: [IDENT_RE], + begin: '\\bdef ', end: '$', + illegal: '[{\\:]', + keywords: {'def': 1}, + contains: ['title', 'comment'], + relevance: 10 + }, + { + className: 'class', + lexems: [IDENT_RE], + begin: '\\bclass ', end: '$', + illegal: '[{\\:]', + contains: ['title', 'comment'], + keywords: {'class': 1} + }, + { + className: 'symbol', + begin: ':' + UNDERSCORE_IDENT_RE, end: '^' + }, + { + className: 'title', + begin: IDENT_RE + "\\s*<\\s*" + IDENT_RE, end: '^' + }, + { + className: 'title', + begin: 'self.' + IDENT_RE, end: '^' + }, + { + className: 'title', + begin: IDENT_RE, end: '^' + } + ] +};//ruby \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/javascript.js b/gulliver/js/highlight/core/languages/javascript.js new file mode 100644 index 000000000..fd14d6f8e --- /dev/null +++ b/gulliver/js/highlight/core/languages/javascript.js @@ -0,0 +1,38 @@ +LANGUAGES.javascript = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + contains: ['string', 'comment', 'number', 'regexp', 'function'], + keywords: { + 'keyword': {'in': 1, 'if': 1, 'for': 1, 'while': 1, 'finally': 1, 'var': 1, 'new': 1, 'function': 1, 'do': 1, 'return': 1, 'void': 1, 'else': 1, 'break': 1, 'catch': 1, 'instanceof': 1, 'with': 1, 'throw': 1, 'case': 1, 'default': 1, 'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'typeof': 1, 'delete': 1}, + 'literal': {'true': 1, 'false': 1, 'null': 1} + } + }, + modes: [ + C_LINE_COMMENT_MODE, + C_BLOCK_COMMENT_MODE, + C_NUMBER_MODE, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + { + className: 'regexp', + begin: '/.*?[^\\\\/]/[gim]*', end: '^' + }, + { + className: 'function', + begin: 'function ', end: '{', + lexems: [UNDERSCORE_IDENT_RE], + keywords: {'function': 1}, + contains: ['title', 'params'] + }, + { + className: 'title', + begin: UNDERSCORE_IDENT_RE, end: '^' + }, + { + className: 'params', + begin: '\\(', end: '\\)', + contains: ['string', 'comment'] + } + ] +};//javascript \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/rib.js b/gulliver/js/highlight/core/languages/rib.js new file mode 100644 index 000000000..618bca490 --- /dev/null +++ b/gulliver/js/highlight/core/languages/rib.js @@ -0,0 +1,30 @@ +/* + +RenderMan Interface Bytestream (c) Konstantin Evdokimenko + +*/ + +LANGUAGES.rib = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + illegal: ' + +*/ + +LANGUAGES.rsl = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + illegal: ' + +*/ + +var SMALLTALK_KEYWORDS = {'self': 1, 'super': 1, 'nil': 1, 'true': 1, 'false': 1, 'thisContext': 1}; // only 6 +var VAR_IDENT_RE = '[a-z][a-zA-Z0-9_]*'; + +LANGUAGES.smalltalk = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + contains: ['comment', 'string', 'class', 'method', + 'number', 'symbol', 'char', 'localvars', 'array'], + keywords: SMALLTALK_KEYWORDS + }, + modes: [ + { + className: 'class', + begin: '\\b[A-Z][A-Za-z0-9_]*', end: '^', + relevance: 0 + }, + { + className: 'symbol', + begin: '#' + UNDERSCORE_IDENT_RE, end: '^' + }, + C_NUMBER_MODE, + APOS_STRING_MODE, + { + className: 'comment', + begin: '"', end: '"', + relevance: 0 + }, + { + className: 'method', + begin: VAR_IDENT_RE+':', end:'^' + }, + { + className: 'char', + begin: '\\$.{1}', end: '^' + }, + { + className: 'localvars', + begin: '\\|\\s*(('+VAR_IDENT_RE+')\\s*)+\\|', end: '^', + relevance: 10 + }, + { + className: 'array', + begin: '\\#\\(', end: '\\)', + contains: ['string', 'char', 'number', 'symbol'] + } + ] +};//smalltalk \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/sql.js b/gulliver/js/highlight/core/languages/sql.js new file mode 100644 index 000000000..585ef259d --- /dev/null +++ b/gulliver/js/highlight/core/languages/sql.js @@ -0,0 +1,50 @@ +SQL_KEYWORDS = {'all': 1, 'partial': 1, 'global': 1, 'month': 1, 'current_timestamp': 1, 'using': 1, 'go': 1, 'revoke': 1, 'smallint': 1, 'indicator': 1, 'end-exec': 1, 'disconnect': 1, 'zone': 1, 'with': 1, 'character': 1, 'assertion': 1, 'to': 1, 'add': 1, 'current_user': 1, 'usage': 1, 'input': 1, 'local': 1, 'alter': 1, 'match': 1, 'collate': 1, 'real': 1, 'then': 1, 'rollback': 1, 'get': 1, 'read': 1, 'timestamp': 1, 'session_user': 1, 'not': 1, 'integer': 1, 'bit': 1, 'unique': 1, 'day': 1, 'minute': 1, 'desc': 1, 'insert': 1, 'execute': 1, 'like': 1, 'level': 1, 'decimal': 1, 'drop': 1, 'continue': 1, 'isolation': 1, 'found': 1, 'where': 1, 'constraints': 1, 'domain': 1, 'right': 1, 'national': 1, 'some': 1, 'module': 1, 'transaction': 1, 'relative': 1, 'second': 1, 'connect': 1, 'escape': 1, 'close': 1, 'system_user': 1, 'for': 1, 'deferred': 1, 'section': 1, 'cast': 1, 'current': 1, 'sqlstate': 1, 'allocate': 1, 'intersect': 1, 'deallocate': 1, 'numeric': 1, 'public': 1, 'preserve': 1, 'full': 1, 'goto': 1, 'initially': 1, 'asc': 1, 'no': 1, 'key': 1, 'output': 1, 'collation': 1, 'group': 1, 'by': 1, 'union': 1, 'session': 1, 'both': 1, 'last': 1, 'language': 1, 'constraint': 1, 'column': 1, 'of': 1, 'space': 1, 'foreign': 1, 'deferrable': 1, 'prior': 1, 'connection': 1, 'unknown': 1, 'action': 1, 'commit': 1, 'view': 1, 'or': 1, 'first': 1, 'into': 1, 'float': 1, 'year': 1, 'primary': 1, 'cascaded': 1, 'except': 1, 'restrict': 1, 'set': 1, 'references': 1, 'names': 1, 'table': 1, 'outer': 1, 'open': 1, 'select': 1, 'size': 1, 'are': 1, 'rows': 1, 'from': 1, 'prepare': 1, 'distinct': 1, 'leading': 1, 'create': 1, 'only': 1, 'next': 1, 'inner': 1, 'authorization': 1, 'schema': 1, 'corresponding': 1, 'option': 1, 'declare': 1, 'precision': 1, 'immediate': 1, 'else': 1, 'timezone_minute': 1, 'external': 1, 'varying': 1, 'translation': 1, 'true': 1, 'case': 1, 'exception': 1, 'join': 1, 'hour': 1, 'default': 1, 'double': 1, 'scroll': 1, 'value': 1, 'cursor': 1, 'descriptor': 1, 'values': 1, 'dec': 1, 'fetch': 1, 'procedure': 1, 'delete': 1, 'and': 1, 'false': 1, 'int': 1, 'is': 1, 'describe': 1, 'char': 1, 'as': 1, 'at': 1, 'in': 1, 'varchar': 1, 'null': 1, 'trailing': 1, 'any': 1, 'absolute': 1, 'current_time': 1, 'end': 1, 'grant': 1, 'privileges': 1, 'when': 1, 'cross': 1, 'check': 1, 'write': 1, 'current_date': 1, 'pad': 1, 'begin': 1, 'temporary': 1, 'exec': 1, 'time': 1, 'update': 1, 'catalog': 1, 'user': 1, 'sql': 1, 'date': 1, 'on': 1, 'identity': 1, 'timezone_hour': 1, 'natural': 1, 'whenever': 1, 'interval': 1, 'work': 1, 'order': 1, 'cascade': 1, 'diagnostics': 1, 'nchar': 1, 'having': 1, 'left': 1}; + +LANGUAGES.sql = +{ + case_insensitive: true, + defaultMode: + { + lexems: [IDENT_RE], + contains: ['string', 'number', 'comment'], + keywords: { + 'keyword': SQL_KEYWORDS, + 'aggregate': {'count': 1, 'sum': 1, 'min': 1, 'max': 1, 'avg': 1} + } + }, + + modes: [ + C_NUMBER_MODE, + C_BLOCK_COMMENT_MODE, + { + className: 'comment', + begin: '--', end: '$' + }, + { + className: 'string', + begin: '\'', end: '\'', + contains: ['escape', 'squote'], + relevance: 0 + }, + { + className: 'squote', + begin: '\'\'', end: '^' + }, + { + className: 'string', + begin: '"', end: '"', + contains: [ 'escape', 'dquote'], + relevance: 0 + }, + { + className: 'dquote', + begin: '""', end: '^' + }, + { + className: 'string', + begin: '`', end: '`', + contains: ['escape'] + }, + BACKSLASH_ESCAPE + ] +};//sql diff --git a/gulliver/js/highlight/core/languages/static.js b/gulliver/js/highlight/core/languages/static.js new file mode 100644 index 000000000..4f9b10e30 --- /dev/null +++ b/gulliver/js/highlight/core/languages/static.js @@ -0,0 +1,158 @@ +LANGUAGES.cpp = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + illegal: ' + +*/ +LANGUAGES.java = { + defaultMode: { + lexems: [UNDERSCORE_IDENT_RE], + contains: ['comment', 'string', 'class', 'number', 'javadoc', 'annotation'], + keywords: {'false': 1, 'synchronized': 1, 'int': 1, 'abstract': 1, 'float': 1, 'private': 1, 'char': 1, 'interface': 1, 'boolean': 1, 'static': 1, 'null': 1, 'if': 1, 'const': 1, 'for': 1, 'true': 1, 'while': 1, 'long': 1, 'throw': 1, 'strictfp': 1, 'finally': 1, 'protected': 1, 'extends': 1, 'import': 1, 'native': 1, 'final': 1, 'implements': 1, 'return': 1, 'void': 1, 'enum': 1, 'else': 1, 'break': 1, 'transient': 1, 'new': 1, 'catch': 1, 'instanceof': 1, 'byte': 1, 'super': 1, 'class': 1, 'volatile': 1, 'case': 1, 'assert': 1, 'short': 1, 'package': 1, 'default': 1, 'double': 1, 'public': 1, 'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'throws': 1} + }, + modes: [ + { + className: 'class', + lexems: [UNDERSCORE_IDENT_RE], + begin: '(class |interface )', end: '{', + illegal: ':', + keywords: {'class': 1, 'interface': 1}, + contains: ['inheritance', 'title'] + }, + { + className: 'inheritance', + begin: '(implements|extends)', end: '^', + lexems: [IDENT_RE], + keywords: {'extends': 1, 'implements': 1}, + relevance: 10 + }, + { + className: 'title', + begin: UNDERSCORE_IDENT_RE, end: '^' + }, + { + className: 'params', + begin: '\\(', end: '\\)', + contains: ['string', 'annotation'] + }, + C_NUMBER_MODE, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + C_LINE_COMMENT_MODE, + { + className: 'javadoc', + begin: '/\\*\\*', end: '\\*/', + relevance: 10 + }, + C_BLOCK_COMMENT_MODE, + { + className: 'annotation', + begin: '@[A-Za-z]+', end: '^' + } + ] +};//java + + +var DELPHI_KEYWORDS = {'and': 1, 'safecall': 1, 'cdecl': 1, 'then': 1, 'string': 1, 'exports': 1, 'library': 1, 'not': 1, 'pascal': 1, 'set': 1, 'virtual': 1, 'file': 1, 'in': 1, 'array': 1, 'label': 1, 'packed': 1, 'end.': 1, 'index': 1, 'while': 1, 'const': 1, 'raise': 1, 'for': 1, 'to': 1, 'implementation': 1, 'with': 1, 'except': 1, 'overload': 1, 'destructor': 1, 'downto': 1, 'finally': 1, 'program': 1, 'exit': 1, 'unit': 1, 'inherited': 1, 'override': 1, 'if': 1, 'type': 1, 'until': 1, 'function': 1, 'do': 1, 'begin': 1, 'repeat': 1, 'goto': 1, 'nil': 1, 'far': 1, 'initialization': 1, 'object': 1, 'else': 1, 'var': 1, 'uses': 1, 'external': 1, 'resourcestring': 1, 'interface': 1, 'end': 1, 'finalization': 1, 'class': 1, 'asm': 1, 'mod': 1, 'case': 1, 'on': 1, 'shr': 1, 'shl': 1, 'of': 1, 'register': 1, 'xorwrite': 1, 'threadvar': 1, 'try': 1, 'record': 1, 'near': 1, 'stored': 1, 'constructor': 1, 'stdcall': 1, 'inline': 1, 'div': 1, 'out': 1, 'or': 1, 'procedure': 1}; +var DELPHI_CLASS_KEYWORDS = {'safecall': 1, 'stdcall': 1, 'pascal': 1, 'stored': 1, 'const': 1, 'implementation': 1, 'finalization': 1, 'except': 1, 'to': 1, 'finally': 1, 'program': 1, 'inherited': 1, 'override': 1, 'then': 1, 'exports': 1, 'string': 1, 'read': 1, 'not': 1, 'mod': 1, 'shr': 1, 'try': 1, 'div': 1, 'shl': 1, 'set': 1, 'library': 1, 'message': 1, 'packed': 1, 'index': 1, 'for': 1, 'near': 1, 'overload': 1, 'label': 1, 'downto': 1, 'exit': 1, 'public': 1, 'goto': 1, 'interface': 1, 'asm': 1, 'on': 1, 'of': 1, 'constructor': 1, 'or': 1, 'private': 1, 'array': 1, 'unit': 1, 'raise': 1, 'destructor': 1, 'var': 1, 'type': 1, 'until': 1, 'function': 1, 'else': 1, 'external': 1, 'with': 1, 'case': 1, 'default': 1, 'record': 1, 'while': 1, 'protected': 1, 'property': 1, 'procedure': 1, 'published': 1, 'and': 1, 'cdecl': 1, 'do': 1, 'threadvar': 1, 'file': 1, 'in': 1, 'if': 1, 'end': 1, 'virtual': 1, 'write': 1, 'far': 1, 'out': 1, 'begin': 1, 'repeat': 1, 'nil': 1, 'initialization': 1, 'object': 1, 'uses': 1, 'resourcestring': 1, 'class': 1, 'register': 1, 'xorwrite': 1, 'inline': 1}; + +LANGUAGES.delphi = { + defaultMode: { + lexems: [IDENT_RE], + illegal: '("|\\$[G-Zg-z]|\\/\\*| + +*/ +LANGUAGES.vbscript = { + defaultMode: { + lexems: [IDENT_RE], + contains: ['string', 'comment', 'number', 'built_in'], + keywords: { + 'keyword': {'call' : 1,'class' : 1,'const' : 1,'dim' : 1,'do' : 1,'loop' : 1,'erase' : 1,'execute' : 1,'executeglobal' : 1,'exit' : 1,'for' : 1,'each' : 1,'next' : 1,'function' : 1,'if' : 1,'then' : 1,'else' : 1,'on' : 1, 'error' : 1,'option' : 1, 'explicit' : 1,'private' : 1,'property' : 1,'let' : 1,'get' : 1,'public' : 1,'randomize' : 1,'redim' : 1,'rem' : 1,'select' : 1,'case' : 1,'set' : 1,'stop' : 1,'sub' : 1,'while' : 1,'wend' : 1,'with' : 1, 'end' : 1, 'to' : 1}, + 'built_in': {'lcase': 1, 'month': 1, 'vartype': 1, 'instrrev': 1, 'ubound': 1, 'setlocale': 1, 'getobject': 1, 'rgb': 1, 'getref': 1, 'string': 1, 'weekdayname': 1, 'rnd': 1, 'dateadd': 1, 'monthname': 1, 'now': 1, 'day': 1, 'minute': 1, 'isarray': 1, 'cbool': 1, 'round': 1, 'formatcurrency': 1, 'conversions': 1, 'csng': 1, 'timevalue': 1, 'second': 1, 'year': 1, 'space': 1, 'abs': 1, 'clng': 1, 'timeserial': 1, 'fixs': 1, 'len': 1, 'asc': 1, 'isempty': 1, 'maths': 1, 'dateserial': 1, 'atn': 1, 'timer': 1, 'isobject': 1, 'filter': 1, 'weekday': 1, 'datevalue': 1, 'ccur': 1, 'isdate': 1, 'instr': 1, 'datediff': 1, 'formatdatetime': 1, 'replace': 1, 'isnull': 1, 'right': 1, 'sgn': 1, 'array': 1, 'snumeric': 1, 'log': 1, 'cdbl': 1, 'hex': 1, 'chr': 1, 'lbound': 1, 'msgbox': 1, 'ucase': 1, 'getlocale': 1, 'cos': 1, 'cdate': 1, 'cbyte': 1, 'rtrim': 1, 'join': 1, 'hour': 1, 'oct': 1, 'typename': 1, 'trim': 1, 'strcomp': 1, 'int': 1, 'createobject': 1, 'loadpicture': 1, 'tan': 1, 'formatnumber': 1, 'mid': 1, 'scriptenginebuildversion': 1, 'scriptengine': 1, 'split': 1, 'scriptengineminorversion': 1, 'cint': 1, 'sin': 1, 'datepart': 1, 'ltrim': 1, 'sqr': 1, 'scriptenginemajorversion': 1, 'time': 1, 'derived': 1, 'eval': 1, 'date': 1, 'formatpercent': 1, 'exp': 1, 'inputbox': 1, 'left': 1} + } + }, + case_insensitive: true, + modes: [ + QUOTE_STRING_MODE, + BACKSLASH_ESCAPE, + { + className: 'comment', + begin: '\'', end: '$' + }, + C_NUMBER_MODE + ] +};//vbscript \ No newline at end of file diff --git a/gulliver/js/highlight/core/languages/www.js b/gulliver/js/highlight/core/languages/www.js new file mode 100644 index 000000000..b88f7c05e --- /dev/null +++ b/gulliver/js/highlight/core/languages/www.js @@ -0,0 +1,186 @@ +var XML_COMMENT = { + className: 'comment', + begin: '' +}; +var XML_ATTR = { + className: 'attribute', + begin: ' [a-zA-Z]+=', end: '^', + contains: ['value'] +}; +var XML_VALUE = { + className: 'value', + begin: '"', end: '"' +}; + +LANGUAGES.xml = { + defaultMode: { + contains: ['pi', 'comment', 'cdata', 'tag'] + }, + case_insensitive: true, + modes: [ + { + className: 'pi', + begin: '<\\?', end: '\\?>', + relevance: 10 + }, + XML_COMMENT, + { + className: 'cdata', + begin: '<\\!\\[CDATA\\[', end: '\\]\\]>' + }, + { + className: 'tag', + begin: '', + contains: ['title', 'tag_internal'], + relevance: 1.5 + }, + { + className: 'title', + begin: '[A-Za-z]+', end: '^', + relevance: 0 + }, + { + className: 'tag_internal', + begin: '^', endsWithParent: true, + contains: ['attribute'], + relevance: 0, + illegal: '[\\+\\.]' + }, + XML_ATTR, + XML_VALUE + ] +};//xml + +var HTML_TAGS = {'code': 1, 'kbd': 1, 'font': 1, 'noscript': 1, 'style': 1, 'img': 1, 'title': 1, 'menu': 1, 'tt': 1, 'tr': 1, 'param': 1, 'li': 1, 'tfoot': 1, 'th': 1, 'input': 1, 'td': 1, 'dl': 1, 'blockquote': 1, 'fieldset': 1, 'big': 1, 'dd': 1, 'abbr': 1, 'optgroup': 1, 'dt': 1, 'button': 1, 'isindex': 1, 'p': 1, 'small': 1, 'div': 1, 'dir': 1, 'em': 1, 'frame': 1, 'meta': 1, 'sub': 1, 'bdo': 1, 'label': 1, 'acronym': 1, 'sup': 1, 'body': 1, 'xml': 1, 'basefont': 1, 'base': 1, 'br': 1, 'address': 1, 'strong': 1, 'legend': 1, 'ol': 1, 'script': 1, 'caption': 1, 's': 1, 'col': 1, 'h2': 1, 'h3': 1, 'h1': 1, 'h6': 1, 'h4': 1, 'h5': 1, 'table': 1, 'select': 1, 'noframes': 1, 'span': 1, 'area': 1, 'dfn': 1, 'strike': 1, 'cite': 1, 'thead': 1, 'head': 1, 'option': 1, 'form': 1, 'hr': 1, 'var': 1, 'link': 1, 'b': 1, 'colgroup': 1, 'ul': 1, 'applet': 1, 'del': 1, 'iframe': 1, 'pre': 1, 'frameset': 1, 'ins': 1, 'tbody': 1, 'html': 1, 'samp': 1, 'map': 1, 'object': 1, 'a': 1, 'xmlns': 1, 'center': 1, 'textarea': 1, 'i': 1, 'q': 1, 'u': 1}; +var HTML_DOCTYPE = { + className: 'doctype', + begin: '', + relevance: 10 +}; +var HTML_ATTR = { + className: 'attribute', + begin: ' [a-zA-Z]+', end: '^' +}; +var HTML_VALUE = { + className: 'value', + begin: '[a-zA-Z0-9]+', end: '^' +}; + +LANGUAGES.html = { + defaultMode: { + contains: ['tag', 'comment', 'doctype'] + }, + case_insensitive: true, + modes: [ + XML_COMMENT, + HTML_DOCTYPE, + { + className: 'tag', + lexems: [IDENT_RE], + keywords: HTML_TAGS, + begin: '<[A-Za-z/]', end: '>', + contains: ['attribute'], + illegal: '[\\+\\.]' + }, + XML_ATTR, + HTML_ATTR, + XML_VALUE, + HTML_VALUE + ] +};//html + +LANGUAGES.css = { + defaultMode: { + contains: ['id', 'class', 'attr_selector', 'rules', 'comment'], + keywords: HTML_TAGS, + lexems: [IDENT_RE], + illegal: '=' + }, + case_insensitive: true, + modes: [ + { + className: 'id', + begin: '\\#[A-Za-z0-9_-]+', end: '^' + }, + { + className: 'class', + begin: '\\.[A-Za-z0-9_-]+', end: '^', + relevance: 0 + }, + { + className: 'attr_selector', + begin: '\\[', end: '\\]', + illegal: '$' + }, + { + className: 'rules', + begin: '{', end: '}', + lexems: ['[A-Za-z-]+'], + keywords: {'play-during': 1, 'counter-reset': 1, 'counter-increment': 1, 'min-height': 1, 'quotes': 1, 'border-top': 1, 'pitch': 1, 'font': 1, 'pause': 1, 'list-style-image': 1, 'border-width': 1, 'cue': 1, 'outline-width': 1, 'border-left': 1, 'elevation': 1, 'richness': 1, 'speech-rate': 1, 'border-bottom': 1, 'border-spacing': 1, 'background': 1, 'list-style-type': 1, 'text-align': 1, 'page-break-inside': 1, 'orphans': 1, 'page-break-before': 1, 'text-transform': 1, 'line-height': 1, 'padding-left': 1, 'font-size': 1, 'right': 1, 'word-spacing': 1, 'padding-top': 1, 'outline-style': 1, 'bottom': 1, 'content': 1, 'border-right-style': 1, 'padding-right': 1, 'border-left-style': 1, 'voice-family': 1, 'background-color': 1, 'border-bottom-color': 1, 'outline-color': 1, 'unicode-bidi': 1, 'max-width': 1, 'font-family': 1, 'caption-side': 1, 'border-right-width': 1, 'pause-before': 1, 'border-top-style': 1, 'color': 1, 'border-collapse': 1, 'border-bottom-width': 1, 'float': 1, 'height': 1, 'max-height': 1, 'margin-right': 1, 'border-top-width': 1, 'speak': 1, 'speak-header': 1, 'top': 1, 'cue-before': 1, 'min-width': 1, 'width': 1, 'font-variant': 1, 'border-top-color': 1, 'background-position': 1, 'empty-cells': 1, 'direction': 1, 'border-right': 1, 'visibility': 1, 'padding': 1, 'border-style': 1, 'background-attachment': 1, 'overflow': 1, 'border-bottom-style': 1, 'cursor': 1, 'margin': 1, 'display': 1, 'border-left-width': 1, 'letter-spacing': 1, 'vertical-align': 1, 'clip': 1, 'border-color': 1, 'list-style': 1, 'padding-bottom': 1, 'pause-after': 1, 'speak-numeral': 1, 'margin-left': 1, 'widows': 1, 'border': 1, 'font-style': 1, 'border-left-color': 1, 'pitch-range': 1, 'background-repeat': 1, 'table-layout': 1, 'margin-bottom': 1, 'speak-punctuation': 1, 'font-weight': 1, 'border-right-color': 1, 'page-break-after': 1, 'position': 1, 'white-space': 1, 'text-indent': 1, 'background-image': 1, 'volume': 1, 'stress': 1, 'outline': 1, 'clear': 1, 'z-index': 1, 'text-decoration': 1, 'margin-top': 1, 'azimuth': 1, 'cue-after': 1, 'left': 1, 'list-style-position': 1}, + contains: ['comment', 'value'] + }, + C_BLOCK_COMMENT_MODE, + { + className: 'value', + begin: ':', end: ';', endsWithParent: true, + excludeBegin: true, excludeEnd: true + } + ] +};//css + +LANGUAGES.django = { + defaultMode: { + contains: ['tag', 'comment', 'doctype', 'template_comment', 'template_tag', 'variable'] + }, + case_insensitive: true, + modes: [ + XML_COMMENT, + HTML_DOCTYPE, + { + className: 'tag', + lexems: [IDENT_RE], + keywords: HTML_TAGS, + begin: '<[A-Za-z/]', end: '>', + contains: ['attribute', 'template_comment', 'template_tag', 'variable'] + }, + XML_ATTR, + HTML_ATTR, + { + className: 'value', + begin: '"', end: '"', + contains: ['template_comment', 'template_tag', 'variable'] + }, + HTML_VALUE, + { + className: 'template_comment', + begin: '\\{\\%\\s*comment\\s*\\%\\}', end: '\\{\\%\\s*endcomment\\s*\\%\\}' + }, + { + className: 'template_comment', + begin: '\\{#', end: '#\\}' + }, + { + className: 'template_tag', + begin: '\\{\\%', end: '\\%\\}', + lexems: [IDENT_RE], + keywords: {'comment': 1, 'endcomment': 1, 'load': 1, 'templatetag': 1, 'ifchanged': 1, 'endifchanged': 1, 'if': 1, 'endif': 1, 'firstof': 1, 'for': 1, 'endfor': 1, 'in': 1, 'ifnotequal': 1, 'endifnotequal': 1, 'widthratio': 1, 'extends': 1, 'include': 1, 'spaceless': 1, 'endspaceless': 1, 'regroup': 1, 'by': 1, 'as': 1, 'ifequal': 1, 'endifequal': 1, 'ssi': 1, 'now': 1, 'with': 1, 'cycle': 1, 'url': 1, 'filter': 1, 'endfilter': 1, 'debug': 1, 'block': 1, 'endblock': 1, 'else': 1}, + contains: ['filter'] + }, + { + className: 'variable', + begin: '\\{\\{', end: '\\}\\}', + contains: ['filter'] + }, + { + className: 'filter', + begin: '\\|[A-Za-z]+\\:?', end: '^', excludeEnd: true, + lexems: [IDENT_RE], + keywords: {'truncatewords': 1, 'removetags': 1, 'linebreaksbr': 1, 'yesno': 1, 'get_digit': 1, 'timesince': 1, 'random': 1, 'striptags': 1, 'filesizeformat': 1, 'escape': 1, 'linebreaks': 1, 'length_is': 1, 'ljust': 1, 'rjust': 1, 'cut': 1, 'urlize': 1, 'fix_ampersands': 1, 'title': 1, 'floatformat': 1, 'capfirst': 1, 'pprint': 1, 'divisibleby': 1, 'add': 1, 'make_list': 1, 'unordered_list': 1, 'urlencode': 1, 'timeuntil': 1, 'urlizetrunc': 1, 'wordcount': 1, 'stringformat': 1, 'linenumbers': 1, 'slice': 1, 'date': 1, 'dictsort': 1, 'dictsortreversed': 1, 'default_if_none': 1, 'pluralize': 1, 'lower': 1, 'join': 1, 'center': 1, 'default': 1, 'truncatewords_html': 1, 'upper': 1, 'length': 1, 'phone2numeric': 1, 'wordwrap': 1, 'time': 1, 'addslashes': 1, 'slugify': 1, 'first': 1}, + contains: ['argument'] + }, + { + className: 'argument', + begin: '"', end: '"' + } + ] +};//django \ No newline at end of file diff --git a/gulliver/js/highlight/core/readme.eng.txt b/gulliver/js/highlight/core/readme.eng.txt new file mode 100644 index 000000000..96590bc96 --- /dev/null +++ b/gulliver/js/highlight/core/readme.eng.txt @@ -0,0 +1,310 @@ +# Highlight.js + +Highlight.js highlights syntax in code examples on blogs, forums and +in fact on any web pages. It's very easy to use because it works +automatically: finds blocks of code, detects a language, highlights it. + +Autodetection can be fine tuned when it fails by itself (see "Heuristics"). + +## Installation and usage + +The script is installed by linking to a single file and making a single +initialization call: + + + + +Autodetection can work a bit slow if it includes too many languages and code +blocks are large. To speed up highlighting in this case you can pass to the +initialization function only those languages that you actually use on your pages: + + + +When called this way highlight.js will dynamically load appropriate language +files and thus will also weigh less than with the default set that includes all +languages implemented. + +Then the script looks in your page for fragments `
    ...
    ` +that are used traditionally to mark up code examples. Their content is +marked up by logical pieces with defined class names. The classes are +used to actually style the code elements: + + .comment { + color: gray; + } + + .keyword { + font-weight: bold; + } + + .python .string { + color: blue; + } + + .html .atribute .value { + color: green; + } + +You can use included sample.css as a starting point for you own style. + +A full list of available classes is below ("Languages"). + +### WordPress plugin + +Generally installing highlight.js in a [WordPress][wp] blog is no different +than for any other web page. However it can also be installed as a plugin. +This is useful if your blog is located on a shared hosting and you don't +have a permission to edit template and style files. Or it may be more convenient +to you this way. + +To install the plugin copy the whole directory with highlight.js to the +WordPress plugins directory. After this you can activate and deactivate it +from the Plugins panel. There is also a page "highlight.js" under the Options +menu where you can set a list of languages and style rules. Insanely convenient :-) + +[wp]: http://wordpress.org/ + + +## Export + +File export.html contains a little program that shows and allows to copy and paste +an HTML code generated by the highlighter for any code snippet. This can be useful +in situations when one can't use the script itself on a site. + + +## Languages + +This is a full list of available classes corresponding to languages' +syntactic structures. + +Python: + + keyword keyword + number number + string string (of any type) + comment comment + decorator @-decorator for functions + function function header "def some_name(...):" + class class header "class SomeName(...):" + title name of a function or a class inside a header + params everything inside parentheses in a function's or class' header + +Ruby: + + keyword keyword + string string + subst in-string substitution (#{...}) + comment comment + function function header "def some_name(...):" + class class header "class SomeName(...):" + title name of a function or a class inside a header + symbol symbol + +Perl: + + keyword keyword + comment comment + number number + string string + regexp regular expression + sub subroutine header (from "sub" till "{") + variable variable starting with "$", "%", "@" + operator operator + pod plain old doc + +PHP: + + keyword keyword + number number + string string (of any type) + comment comment + phpdoc phpdoc params in comments + variable variable starting with "$" + +XML: + + tag any tag from "<" till ">" + comment comment + pi processing instruction () + cdata CDATA section + attribute attribute + value attribute's value + +HTML: + + keyword HTML tag + tag any tag from "<" till ">" + comment comment + doctype declaration + attribute tag's attribute with or without value + value attribute's value + +CSS: + + keyword HTML tag when in selectors, CSS keyword when in rules + id #some_name in selectors + class .some_name in selectors + attr_selector attribute selector (square brackets in a[href^=http://]) + comment comment + rules everything from "{" till "}" + value property's value inside a rule, from ":" till ";" or + till the end of rule block + +Django: + + keyword HTML tag in HTML, default tags and default filters in templates + tag any tag from "<" till ">" + comment comment + doctype declaration + attribute tag's attribute with or withou value + value attribute's value + template_tag template tag {% .. %} + variable template variable {{ .. }} + template_comment template comment, both {# .. #} and {% comment %} + filter filter from "|" till the next filter or the end of tag + argument filter argument + +Javascript: + + keyword keyword + comment comment + number number + literal special literal: "true", "false" and "null" + string string + regexp regular expression + function header of a function + title name of a function inside a header + params everything inside parentheses in a function's header + +VBScript: + + keyword keyword + number number + string string + comment comment + built_in built-in function + +Delphi: + + keyword keyword + comment comment (of any type) + number number + string string + function header of a function, procedure, constructor and destructor + title name of a function, procedure, constructor or destructor + inside a header + params everything inside parentheses in a function's header + class class' body from "= class" till "end;" + +Java: + + keyword keyword + number number + string string + comment commment + annotaion annotation + javadoc javadoc comment + class class header from "class" till "{" + title class name inside a header + params everything in parentheses inside a class header + inheritance keywords "extends" and "implements" inside class header + +C++: + + keyword keyword + number number + string string and character + comment comment + preprocessor preprocessor directive + +RenderMan (RSL): + + keyword keyword + number number + string string + comment comment + preprocessor preprocessor directive + shader sahder keywords + shading shading keywords + built_in built-in function + +RenderMan (RIB): + + keyword keyword + number number + string string + comment comment + commands command + +SQL: + + keyword keyword (mostly SQL'92 and SQL'99) + number number + string string (of any type: "..", '..', `..`) + comment comment + aggregate aggregate function + +Smalltalk: + + keyword keyword + number number + string string + comment commment + symbol symbol + array array + class name of a class + char char + localvars block of local variables + +Axapta: + + keyword keyword + number number + string string + comment commment + class class header from "class" till "{" + title class name inside a header + params everything in parentheses inside a class header + inheritance keywords "extends" and "implements" inside class header + preprocessor preprocessor directive + +1C: + + keyword keyword + number number + string string + comment commment + function header of function or procudure + title function name inside a header + params everything in parentheses inside a function header + preprocessor preprocessor directive + +## Heuristics + +Autodetection of a code's language is done with a simple heuristics: +the program tries to highlight a fragment with all available languages and +counts all syntactic structures that it finds along the way. The language +with greatest count wins. + +This means that in short fragments the probability of an error is high +(and it really happens sometimes). In this cases you can set the fragment's +language explicitly by assigning a class to the `` element: + +
    ...
    + +To disable highlighting of a fragment altogether use "no-highlight" class: + +
    ...
    + +## Contacts + +Version: 3.5 +URL: http://softwaremaniacs.org/soft/highlight/en/ +Author: Ivan Sagalaev (Maniac@SoftwareManiacs.Org) + +For the license terms see LICENSE files. +For the list of contributors see AUTHORS.en.txt file. diff --git a/gulliver/js/highlight/core/readme.rus.txt b/gulliver/js/highlight/core/readme.rus.txt new file mode 100644 index 000000000..d458c787f --- /dev/null +++ b/gulliver/js/highlight/core/readme.rus.txt @@ -0,0 +1,316 @@ +# Highlight.js + +Highlight.js нужен Ð´Ð»Ñ Ð¿Ð¾Ð´Ñветки ÑинтакÑиÑа в примерах кода в блогах, +форумах и вообще на любых веб-Ñтраницах. ПользоватьÑÑ Ð¸Ð¼ очень проÑто, +потому что работает он автоматичеÑки: Ñам находит блоки кода, Ñам +определÑет Ñзык, Ñам подÑвечивает. + +Ðвтоопределением Ñзыка можно управлÑть, когда оно не ÑправлÑетÑÑ Ñамо (Ñм. +дальше "ЭвриÑтика"). + +## Подключение и иÑпользование + +Скрипт подключаетÑÑ Ð¾Ð´Ð½Ð¸Ð¼ файлом и одним вызовом инициализирующей +функции: + + + + +ÐвтоматичеÑкое определение Ñзыков может работать довольно медленно, когда +в него включено много Ñзыков, а фрагменты кода обширны. Чтобы уÑкорить +процеÑÑ, можно перечиÑлить в вызове инициализирующей функции только те +Ñзыки, которые иÑпользуютÑÑ Ð² текÑте: + + + +При вызов таким образом highlight.js динамичеÑки подгружает ÑоответÑтвующие +Ñзыковые файлы и таким образом веÑит меньше, чем Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð¼ по умолчанию, +который включает вÑе реализованные Ñзыки. + +Дальше Ñкрипт ищет на Ñтранице конÑтрукции `
    ...
    `, +которые традиционно иÑпользуютÑÑ Ð´Ð»Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ ÐºÐ¾Ð´Ð°, и код в них +размечаетÑÑ Ð½Ð° куÑки, помеченные разными значениÑми клаÑÑов. КлаÑÑам +Ñтим затем надо задать в ÑтилÑÑ… нужные цвета например так: + + .comment { + color: gray; + } + + .keyword { + font-weight: bold; + } + + .python .string { + color: blue; + } + + .html .atribute .value { + color: green; + } + +Можно иÑпользовать sample.css из комплекта как Ñтартовую точку Ð´Ð»Ñ ÑобÑтвенного +ÑтилÑ. + +Полный ÑпиÑок клаÑÑов Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… Ñзыков приведен ниже ("Языки"). + +### Плагин к WordPress + +Вообще, подключение highlight.js к блогу на [WordPress][wp] ничем не отличаетÑÑ +от Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÐºÑƒÐ´Ð°-либо еще. Однако он может быть подключен к блогу и как плагин. +Это удобно, еÑли блог находитÑÑ Ð½Ð° общеÑтвенном Ñервере, где вы не можете +Ñвободно редактировать файлы, или проÑто еÑли вы привыкли пользоватьÑÑ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð°Ð¼Ð¸. + +Ð”Ð»Ñ ÑƒÑтановки плагина надо Ñкопировать вÑÑŽ директорию Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ highlight.js в +директорию плагинов WordPress. ПоÑле Ñтого в панели плагинов его можно +будет включать и отключать. Ð’ меню Options также добавлÑетÑÑ Ñтраничка +highlight.js, где можно наÑтраивать ÑпиÑок Ñзыков и CSS-Ñтили. Удобно до Ð¾Ð´ÑƒÑ€ÐµÐ½Ð¸Ñ :-). + +[wp]: http://wordpress.org/ + + +## ЭкÑпорт + +Ð’ файле export.html находитÑÑ Ð½ÐµÐ±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼ÐºÐ°, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°ÐµÑ‚ и дает +Ñкопировать непоÑредÑтвенно HTML-код подÑветки Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ заданного фрагмента кода. +Это может понадобитÑÑ Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€ на Ñайте, на котором Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ñам Ñкрипт +highlight.js. + + +## Языки + +Ð’ ÑпиÑке приведены вÑе Ñзыки, которые знает библиотека Ñ ÐºÐ»Ð°ÑÑами, +ÑоответÑтвующими различным ÑинтакÑичеÑким чаÑÑ‚Ñм. + +Python: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока (любого типа) + comment комментарий + decorator @-декоратор функции + function заголовок функции "def some_name(...):" + class заголовок клаÑÑа "class SomeName(...):" + title название функции или клаÑÑа внутри заголовка + params вÑе, что в Ñкобках внутри заголовка функции или клаÑÑа + +Ruby: + + keyword ключевое Ñлово Ñзыка + string Ñтрока + subst внутриÑÑ‚Ñ€Ð¾ÐºÐ¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ñтановка (#{...}) + comment комментарий + function заголовок функции "def ..." + class заголовок клаÑÑа "class ..." + title название функции или клаÑÑа внутри заголовка + symbol Ñимвол + +Perl: + + keyword ключевое Ñлово Ñзыка + comment комментарий + number чиÑло + string Ñтрока + regexp регулÑрное выражение + sub заголовок процедуры (от "sub" до "{") + variable переменнаÑ, начинающаÑÑÑ Ñ "$", "%", "@" + operator оператор + pod Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ (plain old doc) + +PHP: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока (любого типа) + comment комментарий + phpdoc параметры phpdoc в комментарии + variable переменнаÑ, начинающаÑÑÑ Ñ "$" + +XML: + + tag любой открывающий или закрывающий тег от "<" до ">" + comment комментарий + pi инÑтрукции обработки () + cdata раздел CDATA + attribute атрибут + value значение атрибута + +HTML: + + keyword тег Ñзыка HTML + tag любой открывающий или закрывающий тег от "<" до ">" + comment комментарий + doctype объÑвление + attribute атрибут внутри тега Ñо значением или без + value значение атрибута + +CSS: + + keyword тег Ñзыка HTML в Ñелекторах или ÑвойÑтво CSS в правилах + id #some_name в Ñелекторах + class .some_name в Ñелекторах + attr_selector Ñелектор атрибутов (квадатные Ñкобоки в a[href^=http://]) + comment комментарий + rules вÑе от "{" до "}" + value значение ÑвойÑтва внутри правила, вÑе от ":" до ";" или + до конца блока правил + +Django: + + keyword тег HTML в HTML, вÑтроенные шаблонные теги и фильтры в шаблонах + tag любой открывающий или закрывающий тег от "<" до ">" + comment комментарий + doctype объÑвление + attribute атрибут внутри тега Ñо значением или без + value значение атрибута + template_tag шаблонный тег {% .. %} + variable ÑˆÐ°Ð±Ð»Ð¾Ð½Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ {{ .. }} + template_comment шаблонный комментарий, и {# .. #}, и {% comment %} + filter фильтр от "|" до Ñледующего фильтра или до конца тега + argument аргумент фильтра + +Javascript: + + keyword ключевое Ñлово Ñзыка + comment комментарий + number чиÑло + literal Ñпециальное Ñлово: "true", "false" и "null" + string Ñтрока + regexp регулÑрное выражение + function заголовок функции + title название функции внутри заголовка + params вÑе, что в Ñкобках внутри заголовка функции + +VBScript: + + keyword ключевое Ñлово Ñзыка + comment комментарий + number чиÑло + string Ñтрока + built_in вÑÑ‚Ñ€Ð¾ÐµÐ½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + +Delphi: + + keyword ключевое Ñлово Ñзыка + comment комментарий (любого типа) + number чиÑло + string Ñтрока + function заголовок функции, процедуры, конÑтруктора или деÑтруктора + title название функции, процедуры, конÑтруктора или деÑтруктора + внутри заголовка + params вÑе, что в Ñкобках внутри заголовка функций + class тело клаÑÑа от "= class" до "end;" + +Java: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока + comment комментарий + annotaion Ð°Ð½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ + javadoc javadoc-комментарии + class заголовок клаÑÑа от "class" до "{" + title название клаÑÑа внутри заголовка + params вÑе, что в Ñкобках внутри заголовка клаÑÑа + inheritance Ñлова "extends" и "implements" внутри заголовка клаÑÑа + +C++: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока и одиночный Ñимвол + comment комментарий + preprocessor директива препроцеÑÑора + +RenderMan (RSL): + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока + comment комментарий + preprocessor директива препроцеÑÑора + shader ключевое Ñлово шейдеров + shading ключевое Ñлово затенений + built_in вÑÑ‚Ñ€Ð¾ÐµÐ½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + +RenderMan (RIB): + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока + comment комментарий + commands команда + +SQL: + + keyword ключевое Ñлово (в оÑновном из SQL'92 и SQL'99) + number чиÑло + string Ñтрока (любого типа: "..", '..', `..`) + comment комментарий + aggregate Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + +Smalltalk: + + keyword ключевое Ñлово + number чиÑло + string Ñтрока + comment комментарий + symbol Ñимвол + array маÑÑив + class Ð¸Ð¼Ñ ÐºÐ»Ð°ÑÑа + char буква + localvars блок локальных переменных + +Axapta: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока + comment комментарий + class заголовок клаÑÑа от "class" до "{" + title название клаÑÑа внутри заголовка + params вÑе, что в Ñкобках внутри заголовка клаÑÑа + inheritance Ñлова "extends" и "implements" внутри заголовка клаÑÑа + preprocessor директива препроцеÑÑора + +1С: + + keyword ключевое Ñлово Ñзыка + number чиÑло + string Ñтрока + comment комментарий + function заголовок функции или процедуры + title название функции внутри заголовка + params вÑе, что в Ñкобках внутри заголовка функции + preprocessor директива препроцеÑÑора + + +## ЭвриÑтика + +Определение Ñзыка, на котором напиÑан фрагмент, делаетÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ +довольно проÑтой ÑвриÑтики: программа пытаетÑÑ Ñ€Ð°Ñцветить фрагмент вÑеми +Ñзыками подрÑд, и Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзыка Ñчитает количеÑтво подошедших +ÑинтакÑичеÑки конÑтрукций и ключевых Ñлов. Ð”Ð»Ñ ÐºÐ°ÐºÐ¾Ð³Ð¾ Ñзыка нашлоÑÑŒ больше, +тот и выбираетÑÑ. + +Это означает, что в коротких фрагментах выÑока вероÑтноÑть ошибки, что +периодичеÑки и ÑлучаетÑÑ. Чтобы указать Ñзык фрагмента Ñвно, надо напиÑать +его название в виде клаÑÑа к Ñлементу ``: + +
    ...
    + +Чтобы запретить раÑцветку фрагмента вообще, иÑпользуетÑÑ ÐºÐ»Ð°ÑÑ "no-highlight": + +
    ...
    + +## Координаты + +ВерÑиÑ: 3.5 +URL: http://softwaremaniacs.org/soft/highlight/ +Ðвтор: Иван Сагалаев (Maniac@SoftwareManiacs.Org) + +Лицензионное Ñоглашение читайте в файле LICENSE. +СпиÑок Ñоавторов читайте в файле AUTHORS.ru.txt \ No newline at end of file diff --git a/gulliver/js/highlight/core/sample.css b/gulliver/js/highlight/core/sample.css new file mode 100644 index 000000000..fac0df5ff --- /dev/null +++ b/gulliver/js/highlight/core/sample.css @@ -0,0 +1,75 @@ +/* +You can use this file as is or as a starting point for you own styling +*/ + +pre code[class]:after { + content: 'highlight: ' attr(class); + display: block; text-align: right; + font-size: smaller; + color: #CCC; background: white; + border-top: solid 1px; + padding-top: 0.5em; +} + +pre code { + display: block; + background: #F0F0F0; +} + +pre code, +.ruby .subst { + color: black; +} + +.string, +.function .title, +.class .title, +.tag .attribute .value, +.css .rules .value, +.preprocessor, +.ruby .symbol, +.built_in, +.sql .aggregate, +.django .template_tag, +.django .variable, +.smalltalk .class { + color: #800; +} + +.comment, +.java .annotation, +.template_comment { + color: #888; +} + +.number, +.regexp, +.javascript .literal, +.smalltalk .symbol, +.smalltalk .char { + color: #080; +} + +.javadoc, +.ruby .string, +.python .decorator, +.django .filter .argument, +.smalltalk .localvars, +.smalltalk .array, +.css .attr_selector, +.xml .pi { + color: #88F; +} + +.keyword, +.css .id, +.phpdoc, +.function .title, +.class .title, +.vbscript .built_in, +.sql .aggregate, +.rsl .built_in, +.smalltalk .class, +.xml .tag .title { + font-weight: bold; +} \ No newline at end of file diff --git a/gulliver/js/highlight/core/test.html b/gulliver/js/highlight/core/test.html new file mode 100644 index 000000000..c1256f8a5 --- /dev/null +++ b/gulliver/js/highlight/core/test.html @@ -0,0 +1,620 @@ + + + Highlight + + + + + + + + +

    Some Python code: + +

    @requires_authorization
    +def somefunc(param1, param2):
    +  '''A docstring'''
    +  if param1 > param2: # interesting
    +    print 'Gre\'ater'
    +    print ''
    +  return param2 - param1 + 1
    +  
    +class SomeClass:
    pass +
    + +

    Short sample of Ruby: + +

    # Ruby support for highlight.js
    +  
    +class CategoriesController < ApplicationController
    +  layout "core"
    +
    +  before_filter :login_required
    +  before_filter :xhr_required, :only => [:create, :update]
    +  before_filter :admin_privileges_required, :except => [:show]
    +
    +=begin
    +  This method creates a category. Very difficult to understand, huh?
    +=end
    +
    +  def create
    +    @category = Category.create(params[:category])
    +    flash[:notice] = "Category #{@category + "..."} was successfully created"
    +  end
    +end
    +
    + +

    A bit of Perl: + +

    # loads object
    +sub load
    +{
    +  my $c = shift;
    +  my $id = shift;
    +  
    +  my $flds = $c->db_load($id,@_) || do { Carp::carp "Can`t load (class: $c, id: $id): '$!'"; return undef };
    +  
    +  my $o = $c->_perl_new();
    +  
    +  $id12 = $id;
    +  $o->{'ID'} = $id12 + 123;
    +  
    +  $o->{'PAPA'} = $flds->{'PAPA'};
    +  #$o->{'SHCUT'} = $flds->{'SHCUT'};
    +  
    +  my $p = $o->props;
    +  
    +  #if($o->{'SHCUT'})
    +  #{
    +  #  $flds = $o->db_load($o->{'SHCUT'},@_);
    +  #}
    +  
    +  my $vt;
    +  for my $key (keys %$p)
    +  {
    +    if(${$vt.'::property'})
    +    {
    +      $o->{$key . '_real'} = $flds->{$key};
    +      tie $o->{$key}, 'CMSBuilder::Property', $o, $key;
    +    }
    +    else
    +    {
    +      $o->{$key} = $flds->{$key};
    +    }
    +  }
    +  
    +  $o->save if delete $o->{'_save_after_load'};
    +  
    +  return $o;
    +}
    +
    + +

    A chunk of PHP: + +

    require_once 'Zend.php';
    +require_once 'Zend/Uri/Exception.php';
    +require_once 'Zend/Uri/Http.php';
    +
    +/**
    + * Zend_Uri_Mailto
    + */
    +require_once 'Zend/Uri/Mailto.php';
    +
    +
    +/**
    + * @category   Zend
    + * @package    Zend_Uri
    + * @copyright  Copyright (c) 2006 Zend Technologies USA Inc. (http://www.zend.com)
    + * @license    http://framework.zend.com/license/new-bsd     New BSD License
    + */
    +abstract class Zend_Uri
    +{
    +
    +
    +	/**
    +	 * Scheme of this URI (http, ftp, etc.)
    +	 * @var string
    +	 */
    +	protected $_scheme = "";
    +
    +
    +    /**
    +     * Return a string representation of this URI.
    +     *
    +     * @see     getUri()
    +     * @return  string
    +     */
    +    public function __toString()
    +    {
    +        return $this->getUri();
    +    }
    +
    +
    +    static public function check($uri)
    +    {
    +        try {
    +            $uri = self::factory($uri);
    +        } catch (Exception $e) {
    +            return false;
    +        }
    +
    +        return $uri->valid();
    +    }
    +
    +
    +    /**
    +     * Create a new Zend_Uri object for a URI.  If building a new URI, then $uri should contain
    +     * only the scheme (http, ftp, etc).  Otherwise, supply $uri with the complete URI.
    +     *
    +     * @param string $uri
    +     * @throws Zend_Uri_Exception
    +     * @return Zend_Uri
    +     */
    +    static public function factory($uri = 'http')
    +    {
    +        /**
    +         * Separate the scheme from the scheme-specific parts
    +         * @link http://www.faqs.org/rfcs/rfc2396.html
    +         */
    +        $uri = explode(':', $uri, 2);
    +        $scheme = strtolower($uri[0]);
    +        $schemeSpecific = isset($uri[1]) ? $uri[1] : '';
    +
    +        if (!strlen($scheme)) {
    +            throw new Zend_Uri_Exception('An empty string was supplied for the scheme');
    +        }
    +
    +        // Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
    +        if (!ctype_alnum($scheme)) {
    +            throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
    +        }
    +}
    +
    + +

    A custom XML document: + +

    <?xml version="1.0"?>
    +<response value="ok">
    +  <text>Ok</text>
    +  <comment/>
    +  <description><![CDATA[ 
    +  CDATA is <not> magical. 
    +  ]]></description>
    +</response>
    +
    + +

    Some HTML code: + +

    <head>
    +  <title>Title</title>
    +<body>
    +  <p class="something">Something</p>
    +  <p class=something>Something</p>
    +  <!-- comment -->
    +  <p class>Something</p>
    +  <p class="something" title="p">Something</p>
    +</body>
    +
    + +

    HTML with Django templates: + +

    {% if articles|length %}
    +{% for article in articles %}
    +
    +{# Striped table #}
    +<tr class="{% cycle odd,even %}">
    +  <td>{{ article|default:"Hi... "|escape }}</td>
    +  <td>{{ article.date|date:"d.m.Y" }}</td>
    +</tr>
    +  
    +{% endfor %}
    +{% endif %}
    +
    +{% comment %}
    +Comments may be long and
    +multiline.
    +{% endcomment %}
    +
    + +

    Some CSS code: + +

    body, 
    +html {
    +  font: Tahoma, Arial, san-serif;
    +}
    +
    +#content {
    +  width: 100%; /* комментарий */
    +  height: 100%
    +}
    +
    +p[lang=ru] {
    +  color: red;
    +}
    +
    + +

    Javascript here too (right from the source, mind you): + +

    function initHighlight(block) {
    +  if (block.className.search(/\bno\-highlight\b/) != -1)
    +    return false;
    +  try {
    +    blockText(block);
    +  } catch (e) {
    +    if (e == 'Complex markup')
    +      return;
    +  }//try
    +  var classes = block.className.split(/\s+/);
    +  for (var i = 0; i < classes.length; i++) {
    +    if (LANGUAGES[classes[i]]) {
    +      highlightLanguage(block, classes[i]);
    +      return;
    +    }//if
    +  }//for
    +  highlightAuto(block);
    +}//initHighlight
    + +

    VBScript + +

    ' creating configuration storage and initializing with default values
    +Set cfg = CreateObject("Scripting.Dictionary")
    +cfg.add "dest", ""
    +cfg.add "dest_gz", ""
    +cfg.add "gzip_exe", ""
    +cfg.add "perl_exe", ""
    +cfg.add "uncompressed_postfix", ""
    +
    +' reading ini file
    +for i = 0 to ubound(ini_strings)
    +    s = trim(ini_strings(i))
    +
    +    ' skipping empty strings and comments
    +    if mid(s, 1, 1) <> "#" and len(s) > 0 then 
    +      ' obtaining key and value
    +      parts = split(s, "=", -1, 1)
    +
    +      if ubound(parts)+1 = 2 then
    +        parts(0) = trim(parts(0))
    +        parts(1) = trim(parts(1))
    +
    +        ' reading configuration and filenames
    +        select case lcase(parts(0))
    +          case "dest"                 cfg.item("dest") = parts(1)
    +          case "dest_gz"              cfg.item("dest_gz") = parts(1)
    +          case "gzip_exe"             cfg.item("gzip_exe") = parts(1)
    +          case "perl_exe"             cfg.item("perl_exe") = parts(1)
    +          case "uncompressed_postfix" cfg.item("uncompressed_postfix") = parts(1)
    +          case "f"
    +                    options = split(parts(1), "|", -1, 1)
    +                    if ubound(options)+1 = 2 then
    +                      ' 0: filename,  1: options
    +                      ff.add trim(options(0)), trim(options(1))
    +                    end if
    +        end select
    +      end if
    +    end if
    +next
    + +

    Delphi code + +

    TList=Class(TObject) 
    +Private
    +  Some: String;
    +Public
    +  Procedure Inside;
    +End;{TList}
    +
    +Procedure CopyFile(InFileName,var OutFileName:String);
    +Const
    +  BufSize=4096; (* Huh? *)
    +Var
    +  InFile,OutFile:TStream;
    +  Buffer:Array[1..BufSize] Of Byte;
    +  ReadBufSize:Integer;
    +Begin
    +  InFile:=Nil;
    +  OutFile:=Nil;
    +  Try
    +    InFile:=TFileStream.Create(InFileName,fmOpenRead);
    +    OutFile:=TFileStream.Create(OutFileName,fmCreate);
    +    Repeat
    +      ReadBufSize:=InFile.Read(Buffer,BufSize);
    +      OutFile.Write(Buffer,ReadBufSize);
    +    Until ReadBufSize<>BufSize;
    +    Log('File '''+InFileName+''' copied'#13#10);
    +  Finally
    +    InFile.Free;
    +    OutFile.Free;
    +  End;{Try}
    +End;{CopyFile}
    +
    + +

    From Java world: + +

    package l2f.gameserver.model;
    +
    +import java.util.ArrayList;
    +
    +/**
    + * Mother class of all character objects of the world (PC, NPC...)<BR><BR>
    + *
    + */
    +public abstract class L2Character extends L2Object
    +{
    +	protected static final Logger _log = Logger.getLogger(L2Character.class.getName());
    +
    +	public static final Short ABNORMAL_EFFECT_BLEEDING = 0x0001; // not sure
    +	public static final Short ABNORMAL_EFFECT_POISON = 0x0002;
    +
    +	/**
    +	 * Cancel the AI.<BR><BR>
    +	 */
    +	public void detachAI()
    +	{
    +		_ai = null;
    +		//jbf = null;
    +		if (1 > 5)
    +		{
    +			return;
    +		}
    +	}
    +
    +	public void moveTo(int x, int y, int z)
    +	{
    +		moveTo(x, y, z, 0);
    +	}
    +
    +	/** Task of AI notification */
    +	@SuppressWarnings( { "nls", "unqualified-field-access", "boxing" })
    +	public class NotifyAITask implements Runnable
    +	{
    +		private final CtrlEvent _evt;
    +
    +		public NotifyAITask(CtrlEvent evt)
    +		{
    +			this._evt = evt;
    +		}
    +
    +		public void run()
    +		{
    +			try
    +			{
    +				getAI().notifyEvent(_evt, null, null);
    +			}
    +			catch (Throwable t)
    +			{
    +				_log.warning("Exception " + t);
    +				t.printStackTrace();
    +			}
    +		}
    +	}
    +
    +	private static final int HP_REGEN_FLAG = 1;
    +	private static final int MP_REGEN_FLAG = 2;
    +	private static final int CP_REGEN_FLAG = 4;
    +
    +	/** The table containing the List of all stacked effect in progress for each Stack group Identifier */
    +	private ConcurrentHashMap<String, Short> _stackedEffects = null;
    +}
    +
    + +

    C++: + +

    #include <iostream>
    +
    +int main(int argc, char *argv[]) {
    +  
    +  /* An annoying "Hello World" example */
    +  for (unsigned i = 0; i < 0xFFFF; i++)
    +    cout << "Hello, World!" << endl;
    +  
    +  char c = '\n'; // just a test 
    +  char *s = "\\\\"; // another test
    +}
    +
    + +

    Bet you didn't expect to see a highlighted RenderMan (both RenderMan +Shading Language and RenderMan Interface Bytestream):

    + +
    #define TEST_DEFINE 3.14
    +/*	plastic surface shader
    + *
    + * 	Pixie is:
    + * 	(c) Copyright 1999-2003 Okan Arikan. All rights reserved.
    + */
    +
    +surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1;
    +                 color specularcolor = 1;) {
    +	normal Nf = faceforward (normalize(N),I);
    +	Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,-normalize(I),roughness);
    +	Oi = Os;
    +	Ci *= Oi;
    +}
    +
    + +
    FrameBegin 0
    +Display "Scene" "framebuffer" "rgb"
    +Option "searchpath" "shader" "+&:/home/kew"
    +Option "trace" "int maxdepth" [4]
    +Attribute "visibility" "trace" [1]
    +Attribute "irradiance" "maxerror" [0.1]
    +Attribute "visibility" "transmission" "opaque"
    +Format 640 480 1.0
    +ShadingRate 2
    +PixelFilter "catmull-rom" 1 1
    +PixelSamples 4 4
    +Projection "perspective" "fov" 49.5502811377
    +Scale 1 1 -1
    +ConcatTransform [-0.105581186712 -0.336664259434 0.935686826706 0.0
    +
    +		      0.994097530842 -0.0121211335063 0.107810914516 0.0
    +
    +          -0.0249544940889 0.941546678543 0.335956931114 0.0
    +
    +          0.103667020798 -1.30126297474 -6.22769546509 1.0]
    +
    +WorldBegin
    +
    +ReadArchive "/home/qewerty/blends/my/instances/Lamp.002_Light/instance.rib"
    +Surface "plastic"
    +ReadArchive "/home/qewerty/blends/my/instances/Cube.004_Mesh/instance.rib"
    +# ReadArchive "/home/qewerty/blends/my/instances/Sphere.010_Mesh/instance.rib"
    +# ReadArchive "/home/qewerty/blends/my/instances/Sphere.009_Mesh/instance.rib"
    +ReadArchive "/home/qewerty/blends/my/instances/Sphere.006_Mesh/instance.rib"
    +
    +WorldEnd
    +FrameEnd
    +
    + +

    SQL: + +

    BEGIN;
    +CREATE TABLE "cicero_topic" (
    +    "id" serial NOT NULL PRIMARY KEY,
    +    "forum_id" integer NOT NULL,
    +    "subject" varchar(255) NOT NULL,
    +    "created" timestamp with time zone NOT NULL
    +);
    +ALTER TABLE "cicero_topic" 
    +ADD CONSTRAINT forum_id_refs_id_4be56999 
    +FOREIGN KEY ("forum_id") 
    +REFERENCES "cicero_forum" ("id") 
    +DEFERRABLE INITIALLY DEFERRED;
    +
    +-- Initials
    +insert into "cicero_forum" ("slug", "name", "group", "ordering") values ('test', 'ТеÑÑ‚''овый форум', 'ТеÑÑ‚', 0);
    +
    +-- Indices
    +CREATE INDEX "cicero_topic_forum_id" ON "cicero_topic" ("forum_id");
    +
    +-- Test
    +select count(*) from cicero_forum;
    +
    +COMMIT;
    +
    + +

    Good old classic SmallTalk: + +

    Object>>method: num
    +    "comment 123"
    +    | var1 var2 |
    +    (1 to: num) do: [:i | |var| ^i].
    +    Klass with: var1.
    +    Klass new.
    +    arr := #('123' 123.345 #hello Transcript var $@).
    +    arr := #().
    +    var2 = arr at: 3.
    +    ^ self abc
    +
    +heapExample
    +    "HeapTest new heapExample"
    +    "Create a sorted collection of numbers, remove the elements
    +    sequentially and add new objects randomly.
    +    Note: This is the kind of benchmark a heap is designed for."
    +    | n rnd array time sorted |
    +    n := 5000.
    +    "# of elements to sort"
    +    rnd := Random new.
    +    array := (1 to: n)
    +                collect: [:i | rnd next].
    +    "First, the heap version"
    +    time := Time
    +                millisecondsToRun: [sorted := Heap withAll: array.
    +    1
    +        to: n
    +        do: [:i |
    +            sorted removeFirst.
    +            sorted add: rnd next]].
    +    Transcript cr; show: 'Time for Heap: ' , time printString , ' msecs'.
    +    "The quicksort version"
    +    time := Time
    +                millisecondsToRun: [sorted := SortedCollection withAll: array.
    +    1
    +        to: n
    +        do: [:i |
    +            sorted removeFirst.
    +            sorted add: rnd next]].
    +    Transcript cr; show: 'Time for SortedCollection: ' , time printString , ' msecs'
    +
    + +

    Axapta: + +

    class ExchRateLoadBatch extends RunBaseBatch
    +{
    +    ExchRateLoad rbc;
    +    container currencies;
    +    boolean actual;
    +    boolean overwrite;
    +    date beg;
    +    date end;
    +
    +    #define.CurrentVersion(5)
    +
    +    #localmacro.CurrentList
    +        currencies,
    +        actual,
    +        beg,
    +        end
    +    #endmacro
    +}
    +
    +public boolean unpack(container packedClass)
    +{
    +    container       base;
    +    boolean         ret;
    +    Integer         version    = runbase::getVersion(packedClass);
    +
    +    switch (version)
    +    {
    +        case #CurrentVersion:
    +            [version, #CurrentList] = packedClass;
    +            return true;
    +        default:
    +            return false;
    +    }
    +    return ret;
    +}
    +
    + +

    And this is a russian enterpise system "1С": + +

    
    +#ЕÑли Клиент Тогда
    +Перем СимвольныйКодКаталога = "лÑ-лÑ-лÑ"; //комментарий
    +Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¡Ð¾Ð¾Ð±Ñ‰Ð¸Ñ‚ÑŒ(Знач ТекÑтСообщениÑ, ТекÑтСообщениÑ2) ЭкÑпорт //комментарий к функции
    +	x=ТекÑтСообщениÑ+ТекÑтСообщениÑ2+"
    +	|Ñтрока1
    +	|Ñтрока2
    +	|Ñтрока3";
    +КонецФункции
    +#КонецЕÑли
    +
    +////////////////////////////////////////////////////////////////////////////////
    +// ОБРÐБОТЧИКИ СОБЫТИЙ
    +// 
    +
    +// Процедура ПриÐачалеРаботыСиÑтемы
    +// 
    +Процедура ПриÐачалеРаботыСиÑтемы()
    +
    +	Обработки.Помощник.ПолучитьФорму("Форма").Открыть();
    +
    +КонецПроцедуры
    +
    + +
    + +

    Explicit Python highlight: + +

    for x in [1, 2, 3]:
    +  count(x)
    +
    + +

    Disabled highlighting: + +

    <div id="contents">
    +  <p>Hello, World!
    +</div>
    +
    \ No newline at end of file diff --git a/gulliver/js/highlight/core/wp_highlight.js.php b/gulliver/js/highlight/core/wp_highlight.js.php new file mode 100644 index 000000000..ca91abcb9 --- /dev/null +++ b/gulliver/js/highlight/core/wp_highlight.js.php @@ -0,0 +1,86 @@ + $language) { + $languages[$i] = '\'' . trim($language) . '\''; + } + $languages_str = implode(', ', $languages); + } + ?> + + + + +

    Options updated.

    +
    +
    +

    highlight.js options

    + +
    +

    +

    List here languages that you want to highlight on your blog like this: php, html, css. Empty string means "all known languages". For the list + of supported languages refer to highlight.js homepage.

    +
    + +
    +

    +

    Let's you place the script in a convenient place

    +
    + +
    +

    +

    +

    Normally styling of code snippets goes into site's main CSS files. But you can + write it here if you can't access site's CSS or just like it this way.

    +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/gulliver/js/jquery/ajaxupload.3.6.js b/gulliver/js/jquery/ajaxupload.3.6.js new file mode 100644 index 000000000..673218176 --- /dev/null +++ b/gulliver/js/jquery/ajaxupload.3.6.js @@ -0,0 +1,546 @@ +/** + * Ajax upload + * Project page - http://valums.com/ajax-upload/ + * Copyright (c) 2008 Andris Valums, http://valums.com + * Licensed under the MIT license (http://valums.com/mit-license/) + * Version 3.5 (23.06.2009) + */ + +/** + * Changes from the previous version: + * 1. Added better JSON handling that allows to use 'application/javascript' as a response + * 2. Added demo for usage with jQuery UI dialog + * 3. Fixed IE "mixed content" issue when used with secure connections + * + * For the full changelog please visit: + * http://valums.com/ajax-upload-changelog/ + */ + +(function(){ + +var d = document, w = window; + +/** + * Get element by id + */ +function get(element){ + if (typeof element == "string") + element = d.getElementById(element); + return element; +} + +/** + * Attaches event to a dom element + */ +function addEvent(el, type, fn){ + if (w.addEventListener){ + el.addEventListener(type, fn, false); + } else if (w.attachEvent){ + var f = function(){ + fn.call(el, w.event); + }; + el.attachEvent('on' + type, f) + } +} + + +/** + * Creates and returns element from html chunk + */ +var toElement = function(){ + var div = d.createElement('div'); + return function(html){ + div.innerHTML = html; + var el = div.childNodes[0]; + div.removeChild(el); + return el; + } +}(); + +function hasClass(ele,cls){ + return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')); +} +function addClass(ele,cls) { + if (!hasClass(ele,cls)) ele.className += " "+cls; +} +function removeClass(ele,cls) { + var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)'); + ele.className=ele.className.replace(reg,' '); +} + +// getOffset function copied from jQuery lib (http://jquery.com/) +if (document.documentElement["getBoundingClientRect"]){ + // Get Offset using getBoundingClientRect + // http://ejohn.org/blog/getboundingclientrect-is-awesome/ + var getOffset = function(el){ + var box = el.getBoundingClientRect(), + doc = el.ownerDocument, + body = doc.body, + docElem = doc.documentElement, + + // for ie + clientTop = docElem.clientTop || body.clientTop || 0, + clientLeft = docElem.clientLeft || body.clientLeft || 0, + + // In Internet Explorer 7 getBoundingClientRect property is treated as physical, + // while others are logical. Make all logical, like in IE8. + + + zoom = 1; + if (body.getBoundingClientRect) { + var bound = body.getBoundingClientRect(); + zoom = (bound.right - bound.left)/body.clientWidth; + } + if (zoom > 1){ + clientTop = 0; + clientLeft = 0; + } + var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop, + left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft; + + return { + top: top, + left: left + }; + } + +} else { + // Get offset adding all offsets + var getOffset = function(el){ + if (w.jQuery){ + return jQuery(el).offset(); + } + + var top = 0, left = 0; + do { + top += el.offsetTop || 0; + left += el.offsetLeft || 0; + } + while (el = el.offsetParent); + + return { + left: left, + top: top + }; + } +} + +function getBox(el){ + var left, right, top, bottom; + var offset = getOffset(el); + left = offset.left; + top = offset.top; + + right = left + el.offsetWidth; + bottom = top + el.offsetHeight; + + return { + left: left, + right: right, + top: top, + bottom: bottom + }; +} + +/** + * Crossbrowser mouse coordinates + */ +function getMouseCoords(e){ + // pageX/Y is not supported in IE + // http://www.quirksmode.org/dom/w3c_cssom.html + if (!e.pageX && e.clientX){ + // In Internet Explorer 7 some properties (mouse coordinates) are treated as physical, + // while others are logical (offset). + var zoom = 1; + var body = document.body; + + if (body.getBoundingClientRect) { + var bound = body.getBoundingClientRect(); + zoom = (bound.right - bound.left)/body.clientWidth; + } + + return { + x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft, + y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop + }; + } + + return { + x: e.pageX, + y: e.pageY + }; + +} +/** + * Function generates unique id + */ +var getUID = function(){ + var id = 0; + return function(){ + return 'ValumsAjaxUpload' + id++; + } +}(); + +function fileFromPath(file){ + return file.replace(/.*(\/|\\)/, ""); +} + +function getExt(file){ + return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : ''; +} + +// Please use AjaxUpload , Ajax_upload will be removed in the next version +Ajax_upload = AjaxUpload = function(button, options){ + if (button.jquery){ + // jquery object was passed + button = button[0]; + } else if (typeof button == "string" && /^#.*/.test(button)){ + button = button.slice(1); + } + button = get(button); + + this._input = null; + this._button = button; + this._disabled = false; + this._submitting = false; + // Variable changes to true if the button was clicked + // 3 seconds ago (requred to fix Safari on Mac error) + this._justClicked = false; + this._parentDialog = d.body; + + if (window.jQuery && jQuery.ui && jQuery.ui.dialog){ + var parentDialog = jQuery(this._button).parents('.ui-dialog'); + if (parentDialog.length){ + this._parentDialog = parentDialog[0]; + } + } + + this._settings = { + // Location of the server-side upload script + action: 'upload.php', + // File upload name + name: 'userfile', + // Additional data to send + data: {}, + // Submit file as soon as it's selected + autoSubmit: true, + // The type of data that you're expecting back from the server. + // Html and xml are detected automatically. + // Only useful when you are using json data as a response. + // Set to "json" in that case. + responseType: false, + // When user selects a file, useful with autoSubmit disabled + onChange: function(file, extension){}, + // Callback to fire before file is uploaded + // You can return false to cancel upload + onSubmit: function(file, extension){}, + // Fired when file upload is completed + // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! + onComplete: function(file, response) {} + }; + + // Merge the users options with our defaults + for (var i in options) { + this._settings[i] = options[i]; + } + + this._createInput(); + this._rerouteClicks(); +} + +// assigning methods to our class +AjaxUpload.prototype = { + setData : function(data){ + this._settings.data = data; + }, + disable : function(){ + this._disabled = true; + }, + enable : function(){ + this._disabled = false; + }, + // removes ajaxupload + destroy : function(){ + if(this._input){ + if(this._input.parentNode){ + this._input.parentNode.removeChild(this._input); + } + this._input = null; + } + }, + /** + * Creates invisible file input above the button + */ + _createInput : function(){ + var self = this; + var input = d.createElement("input"); + input.setAttribute('type', 'file'); + input.setAttribute('name', this._settings.name); + var styles = { + 'position' : 'absolute' + ,'margin': '-5px 0 0 -175px' + ,'padding': 0 + ,'width': '220px' + ,'height': '30px' + ,'fontSize': '14px' + ,'opacity': 0 + ,'cursor': 'pointer' + ,'display' : 'none' + ,'zIndex' : 2147483583 //Max zIndex supported by Opera 9.0-9.2x + // Strange, I expected 2147483647 + }; + for (var i in styles){ + input.style[i] = styles[i]; + } + + // Make sure that element opacity exists + // (IE uses filter instead) + if ( ! (input.style.opacity === "0")){ + input.style.filter = "alpha(opacity=0)"; + } + + this._parentDialog.appendChild(input); + + addEvent(input, 'change', function(){ + // get filename from input + var file = fileFromPath(this.value); + if(self._settings.onChange.call(self, file, getExt(file)) == false ){ + return; + } + // Submit form when value is changed + if (self._settings.autoSubmit){ + self.submit(); + } + }); + + // Fixing problem with Safari + // The problem is that if you leave input before the file select dialog opens + // it does not upload the file. + // As dialog opens slowly (it is a sheet dialog which takes some time to open) + // there is some time while you can leave the button. + // So we should not change display to none immediately + addEvent(input, 'click', function(){ + self.justClicked = true; + setTimeout(function(){ + // we will wait 3 seconds for dialog to open + self.justClicked = false; + }, 3000); + }); + + this._input = input; + }, + _rerouteClicks : function (){ + var self = this; + + // IE displays 'access denied' error when using this method + // other browsers just ignore click() + // addEvent(this._button, 'click', function(e){ + // self._input.click(); + // }); + + var box, dialogOffset = {top:0, left:0}, over = false; + addEvent(self._button, 'mouseover', function(e){ + if (!self._input || over) return; + over = true; + box = getBox(self._button); + + if (self._parentDialog != d.body){ + dialogOffset = getOffset(self._parentDialog); + } + }); + + + // we can't use mouseout on the button, + // because invisible input is over it + addEvent(document, 'mousemove', function(e){ + var input = self._input; + if (!input || !over) return; + + if (self._disabled){ + removeClass(self._button, 'hover'); + input.style.display = 'none'; + return; + } + + var c = getMouseCoords(e); + + if ((c.x >= box.left) && (c.x <= box.right) && + (c.y >= box.top) && (c.y <= box.bottom)){ + input.style.top = c.y - dialogOffset.top + 'px'; + input.style.left = c.x - dialogOffset.left + 'px'; + input.style.display = 'block'; + addClass(self._button, 'hover'); + } else { + // mouse left the button + over = false; + if (!self.justClicked){ + input.style.display = 'none'; + } + removeClass(self._button, 'hover'); + } + }); + + }, + /** + * Creates iframe with unique name + */ + _createIframe : function(){ + // unique name + // We cannot use getTime, because it sometimes return + // same value in safari :( + var id = getUID(); + + // Remove ie6 "This page contains both secure and nonsecure items" prompt + // http://tinyurl.com/77w9wh + var iframe = toElement('':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?" ":"")}if(secondary||!changeYear){html+=''+drawYear+""}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?" ":"")+monthHtml}html+="
    ";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&datemaxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/* + * jQuery UI Progressbar 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * ui.core.js + */ +(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('
    ').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(bthis._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);;/* + * jQuery UI Effects 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f
    ');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h
    ").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/* + * jQuery UI Effects Fold 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * effects.core.js + */ +(function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1],10)/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);;/* + * jQuery UI Effects Highlight 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * effects.core.js + */ +(function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/* + * jQuery UI Effects Pulsate 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * effects.core.js + */ +(function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c
    ').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file diff --git a/gulliver/js/jquery/jquery.layout-latest.js b/gulliver/js/jquery/jquery.layout-latest.js new file mode 100755 index 000000000..65d6e0fd5 --- /dev/null +++ b/gulliver/js/jquery/jquery.layout-latest.js @@ -0,0 +1,3712 @@ +/* + * jquery.layout 1.3.0 - Release Candidate 26 + * + * Copyright (c) 2010 + * Fabrizio Balliano (http://www.fabrizioballiano.net) + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * Docs: http://layout.jquery-dev.net/documentation.html + * Tips: http://layout.jquery-dev.net/tips.html + * Help: http://groups.google.com/group/jquery-ui-layout + * + * $Date: 2010-02-27 18:00:00 -1800 (Sat, 27 Feb 2010) $ + * $Rev: 3026 $ + * + * NOTE: For best code readability, view this with a fixed-width font and tabs equal to 4-chars + */ +;(function ($) { + +$.fn.layout = function (opts) { + +/* + * ########################### + * WIDGET CONFIG & OPTIONS + * ########################### + */ + + // LANGUAGE CUSTOMIZATION - will be *externally customizable* in next version + var lang = { + Pane: "Pane" + , Open: "Open" // eg: "Open Pane" + , Close: "Close" + , Resize: "Resize" + , Slide: "Slide Open" + , Pin: "Pin" + , Unpin: "Un-Pin" + , selector: "selector" + , msgNoRoom: "Not enough room to show this pane." + , errContainerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist." + , errCenterPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element." + , errContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!" + , errButton: "Error Adding Button \n\nInvalid " + }; + + // DEFAULT OPTIONS - CHANGE IF DESIRED + var options = { + name: "" // Not required, but useful for buttons and used for the state-cookie + , scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) + , resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event + , resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky + , resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized + , onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific + , onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific + , onload: null // CALLBACK when Layout inits - after options initialized, but before elements + , onunload: null // CALLBACK when Layout is destroyed OR onWindowUnload + , autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them + , zIndex: null // the PANE zIndex - resizers and masks will be +1 + // PANE SETTINGS + , defaults: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // border-Pane - default: 'ui-layout-pane' + , resizerClass: "ui-layout-resizer" // Resizer Bar - default: 'ui-layout-resizer' + , togglerClass: "ui-layout-toggler" // Toggler Button - default: 'ui-layout-toggler' + , buttonClass: "ui-layout-button" // CUSTOM Buttons - default: 'ui-layout-button-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerTip_open: lang.Close // Toggler tool-tip (title) + , togglerTip_closed: lang.Open // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , noSelectionWhileDragging: true // set $(document).disableSelection to avoid selecting text while dragging the resizer + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskIframesOnResize: true // true = all iframes OR = iframe-selector(s) - adds masking-div during resizing/dragging + , resizeWhileDragging: false // true = LIVE Resizing as resizer is dragged + , resizeContentWhileDragging: false // true = re-measure header/footer heights as resizer is dragged + // TIPS & MESSAGES - also see lang object + , noRoomToOpenTip: lang.msgNoRoom + , resizerTip: lang.Resize // Resizer tool-tip (title) + , sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseover + , slideTrigger_close: "mouseout" // click, mouseout + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , trackMouseWhenSliding: false // true = check isMouseOver to avoid premature slide-closed + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open & fxSss_close options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + // CALLBACKS + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsWhileDragging: true // true = trigger onresize callback REPEATEDLY if resizeWhileDragging==true + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS to be ***MANUALLY*** Resized + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + } + , north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode OR a character + } + , south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } + , east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } + , west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } + , center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } + + // STATE MANAGMENT + , useStateCookie: false // Enable cookie-based state-management - can fine-tune with cookie.autoLoad/autoSave + , cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , autoSave: true // Save a state cookie when page exits? + , autoLoad: true // Load the state cookie when Layout inits? + // Cookie Options + , domain: "" + , path: "" + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + // List of options to save in the cookie - must be pane-specific + , keys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" + } + }; + + + // PREDEFINED EFFECTS / DEFAULTS + var effects = { // LIST *PREDEFINED EFFECTS* HERE, even if effect has no settings + slide: { + all: { duration: "fast" } // eg: duration: 1000, easing: "easeOutBounce" + , north: { direction: "up" } + , south: { direction: "down" } + , east: { direction: "right"} + , west: { direction: "left" } + } + , drop: { + all: { duration: "slow" } // eg: duration: 1000, easing: "easeOutQuint" + , north: { direction: "up" } + , south: { direction: "down" } + , east: { direction: "right"} + , west: { direction: "left" } + } + , scale: { + all: { duration: "fast" } + } + }; + + + // DYNAMIC DATA - IS READ-ONLY EXTERNALLY! + var state = { + // generate unique ID to use for event.namespace so can unbind only events added by 'this layout' + id: "layout"+ new Date().getTime() // code uses alias: sID + , initialized: false + , container: {} // init all keys + , north: {} + , south: {} + , east: {} + , west: {} + , center: {} + , cookie: {} // State Managment data storage + }; + + + // INTERNAL CONFIG DATA - DO NOT CHANGE THIS! + var _c = { + allPanes: "north,south,west,east,center" + , borderPanes: "north,south,west,east" + , altSide: { + north: "south" + , south: "north" + , east: "west" + , west: "east" + } + // CSS used in multiple places + , hidden: { visibility: "hidden" } + , visible: { visibility: "visible" } + // layout element settings + , zIndex: { // set z-index values here + pane_normal: 1 // normal z-index for panes + , resizer_normal: 2 // normal z-index for resizer-bars + , iframe_mask: 2 // overlay div used to mask pane(s) during resizing + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } + , resizers: { + cssReq: { + position: "absolute" + , padding: 0 + , margin: 0 + , fontSize: "1px" + , textAlign: "left" // to counter-act "center" alignment! + , overflow: "hidden" // prevent toggler-button from overflowing + // SEE c.zIndex.resizer_normal + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + background: "#DDD" + , border: "none" + } + } + , togglers: { + cssReq: { + position: "absolute" + , display: "block" + , padding: 0 + , margin: 0 + , overflow: "hidden" + , textAlign: "center" + , fontSize: "1px" + , cursor: "pointer" + , zIndex: 1 + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + background: "#AAA" + } + } + , content: { + cssReq: { + position: "relative" /* contain floated or positioned elements */ + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + overflow: "auto" + , padding: "10px" + } + , cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div + overflow: "hidden" + , padding: 0 + } + } + , panes: { // defaults for ALL panes - overridden by 'per-pane settings' below + cssReq: { + position: "absolute" + , margin: 0 + // SEE c.zIndex.pane_normal + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + padding: "10px" + , background: "#FFF" + , border: "1px solid #BBB" + , overflow: "auto" + } + } + , north: { + side: "Top" + , sizeType: "Height" + , dir: "horz" + , cssReq: { + top: 0 + , bottom: "auto" + , left: 0 + , right: 0 + , width: "auto" + // height: DYNAMIC + } + , pins: [] // array of 'pin buttons' to be auto-updated on open/close (classNames) + } + , south: { + side: "Bottom" + , sizeType: "Height" + , dir: "horz" + , cssReq: { + top: "auto" + , bottom: 0 + , left: 0 + , right: 0 + , width: "auto" + // height: DYNAMIC + } + , pins: [] + } + , east: { + side: "Right" + , sizeType: "Width" + , dir: "vert" + , cssReq: { + left: "auto" + , right: 0 + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + // width: DYNAMIC + } + , pins: [] + } + , west: { + side: "Left" + , sizeType: "Width" + , dir: "vert" + , cssReq: { + left: 0 + , right: "auto" + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + // width: DYNAMIC + } + , pins: [] + } + , center: { + dir: "center" + , cssReq: { + left: "auto" // DYNAMIC + , right: "auto" // DYNAMIC + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + , width: "auto" + } + } + // internal tracking + , timers: {} + }; + + +/* + * ########################### + * INTERNAL HELPER FUNCTIONS + * ########################### + */ + + /** + * min / max + * + * Aliases for Math methods to simplify coding + */ + var min = function (x,y) { return Math.min(x,y); }; + var max = function (x,y) { return Math.max(x,y); }; + + /** + * _transformData + * + * Processes the options passed in and transforms them into the format used by layout() + * Missing keys are added, and converts the data if passed in 'flat-format' (no sub-keys) + * In flat-format, pane-specific-settings are prefixed like: north__optName (2-underscores) + * To update effects, options MUST use nested-keys format, with an effects key ??? + * + * @callers initOptions() + * @params JSON d Data/options passed by user - may be a single level or nested levels + * @returns JSON Creates a data struture that perfectly matches 'options', ready to be imported + */ + var _transformData = function (d) { + var json = { cookie:{}, defaults:{fxSettings:{}}, north:{fxSettings:{}}, south:{fxSettings:{}}, east:{fxSettings:{}}, west:{fxSettings:{}}, center:{fxSettings:{}} }; + d = d || {}; + if (d.effects || d.cookie || d.defaults || d.north || d.south || d.west || d.east || d.center) + json = $.extend( true, json, d ); // already in json format - add to base keys + else + // convert 'flat' to 'nest-keys' format - also handles 'empty' user-options + $.each( d, function (key,val) { + a = key.split("__"); + if (!a[1] || json[a[0]]) // check for invalid keys + json[ a[1] ? a[0] : "defaults" ][ a[1] ? a[1] : a[0] ] = val; + }); + return json; + }; + + /** + * _queue + * + * Set an INTERNAL callback to avoid simultaneous animation + * Runs only if needed and only if all callbacks are not 'already set' + * Called by open() and close() when isLayoutBusy=true + * + * @param String action Either 'open' or 'close' + * @param String pane A valid border-pane name, eg 'west' + * @param Boolean param Extra param for callback (optional) + */ + var _queue = function (action, pane, param) { + var tried = []; + + // if isLayoutBusy, then some pane must be 'moving' + $.each(_c.borderPanes.split(","), function (i, p) { + if (_c[p].isMoving) { + bindCallback(p); // TRY to bind a callback + return false; // BREAK + } + }); + + // if pane does NOT have a callback, then add one, else follow the callback chain... + function bindCallback (p) { + var c = _c[p]; + if (!c.doCallback) { + c.doCallback = true; + c.callback = action +","+ pane +","+ (param ? 1 : 0); + } + else { // try to 'chain' this callback + tried.push(p); + var cbPane = c.callback.split(",")[1]; // 2nd param of callback is 'pane' + // ensure callback target NOT 'itself' and NOT 'target pane' and NOT already tried (avoid loop) + if (cbPane != p && cbPane != pane && !$.inArray(p, tried)) + bindCallback(cbPane); // RECURSE + } + } + }; + + /** + * _dequeue + * + * RUN the INTERNAL callback for this pane - if one exists + * + * @param String action Either 'open' or 'close' + * @param String pane A valid border-pane name, eg 'west' + * @param Boolean param Extra param for callback (optional) + */ + var _dequeue = function (pane) { + var c = _c[pane]; + + // RESET flow-control flags + _c.isLayoutBusy = false; + delete c.isMoving; + if (!c.doCallback || !c.callback) return; + + c.doCallback = false; // RESET logic flag + + // EXECUTE the callback + var + cb = c.callback.split(",") + , param = (cb[2] > 0 ? true : false) + ; + if (cb[0] == "open") + open( cb[1], param ); + else if (cb[0] == "close") + close( cb[1], param ); + + if (!c.doCallback) c.callback = null; // RESET - unless callback above enabled it again! + }; + + /** + * _execCallback + * + * Executes a Callback function after a trigger event, like resize, open or close + * + * @param String pane This is passed only so we can pass the 'pane object' to the callback + * @param String v_fn Accepts a function name, OR a comma-delimited array: [0]=function name, [1]=argument + */ + var _execCallback = function (pane, v_fn) { + if (!v_fn) return; + var fn; + try { + if (typeof v_fn == "function") + fn = v_fn; + else if (typeof v_fn != "string") + return; + else if (v_fn.match(/,/)) { + // function name cannot contain a comma, so must be a function name AND a 'name' parameter + var + args = v_fn.split(",") + , fn = eval(args[0]) + ; + if (typeof fn=="function" && args.length > 1) + return fn(args[1]); // pass the argument parsed from 'list' + } + else // just the name of an external function? + fn = eval(v_fn); + + if (typeof fn=="function") { + if (pane && $Ps[pane]) + // pass data: pane-name, pane-element, pane-state (copy), pane-options, and layout-name + return fn( pane, $Ps[pane], $.extend({},state[pane]), options[pane], options.name ); + else // must be a layout/container callback - pass suitable info + return fn( Instance, $.extend({},state), options, options.name ); + } + } + catch (ex) {} + }; + + /** + * _showInvisibly + * + * Returns hash container 'display' and 'visibility' + * + * @TODO: SEE $.swap() - swaps CSS, runs callback, resets CSS + */ + var _showInvisibly = function ($E, force) { + if (!$E) return {}; + if (!$E.jquery) $E = $($E); + var CSS = { + display: $E.css('display') + , visibility: $E.css('visibility') + }; + if (force || CSS.display == "none") { // only if not *already hidden* + $E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured + return CSS; + } + else return {}; + }; + + /** + * _fixIframe + * + * cure iframe display issues in IE & other browsers + */ + var _fixIframe = function (pane) { + if (state.browser.mozilla) return; // skip FireFox - it auto-refreshes iframes onShow + var $P = $Ps[pane]; + // if the 'pane' is an iframe, do it + if (state[pane].tagName == "IFRAME") + $P.css(_c.hidden).css(_c.visible); + else // ditto for any iframes INSIDE the pane + $P.find('IFRAME').css(_c.hidden).css(_c.visible); + }; + + /** + * _cssNum + * + * Returns the 'current CSS numeric value' for an element - returns 0 if property does not exist + * + * @callers Called by many methods + * @param jQuery $Elem Must pass a jQuery object - first element is processed + * @param String property The name of the CSS property, eg: top, width, etc. + * @returns Variant Usually is used to get an integer value for position (top, left) or size (height, width) + */ + var _cssNum = function ($E, prop) { + if (!$E.jquery) $E = $($E); + var CSS = _showInvisibly($E); + var val = parseInt($.curCSS($E[0], prop, true), 10) || 0; + $E.css( CSS ); // RESET + return val; + }; + + var _borderWidth = function (E, side) { + if (E.jquery) E = E[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.curCSS(E, b+"Style", true) == "none" ? 0 : (parseInt($.curCSS(E, b+"Width", true), 10) || 0); + }; + + /** + * cssW / cssH / cssSize / cssMinDims + * + * Contains logic to check boxModel & browser, and return the correct width/height for the current browser/doctype + * + * @callers initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param Variant el Can accept a 'pane' (east, west, etc) OR a DOM object OR a jQuery object + * @param Integer outerWidth/outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @returns Integer Returns the innerWidth/Height of the elem by subtracting padding and borders + * + * @TODO May need additional logic for other browser/doctype variations? Maybe use more jQuery methods? + */ + var cssW = function (el, outerWidth) { + var + str = typeof el == "string" + , $E = str ? $Ps[el] : $(el) + ; + if (isNaN(outerWidth)) // not specified + outerWidth = str ? getPaneSize(el) : $E.outerWidth(); + + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + if (!state.browser.boxModel) return outerWidth; + + // strip border and padding from outerWidth to get CSS Width + var W = outerWidth + - _borderWidth($E, "Left") + - _borderWidth($E, "Right") + - _cssNum($E, "paddingLeft") + - _cssNum($E, "paddingRight") + ; + + return W > 0 ? W : 0; + }; + + var cssH = function (el, outerHeight) { + var + str = typeof el == "string" + , $E = str ? $Ps[el] : $(el) + ; + if (isNaN(outerHeight)) // not specified + outerHeight = str ? getPaneSize(el) : $E.outerHeight(); + + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + if (!state.browser.boxModel) return outerHeight; + + // strip border and padding from outerHeight to get CSS Height + var H = outerHeight + - _borderWidth($E, "Top") + - _borderWidth($E, "Bottom") + - _cssNum($E, "paddingTop") + - _cssNum($E, "paddingBottom") + ; + + return H > 0 ? H : 0; + }; + + var cssSize = function (pane, outerSize) { + if (_c[pane].dir=="horz") // pane = north or south + return cssH(pane, outerSize); + else // pane = east or west + return cssW(pane, outerSize); + }; + + var cssMinDims = function (pane) { + // minWidth/Height means CSS width/height = 1px + var + dir = _c[pane].dir + , d = { + minWidth: 1001 - cssW(pane, 1000) + , minHeight: 1001 - cssH(pane, 1000) + } + ; + if (dir == "horz") d.minSize = d.minHeight; + if (dir == "vert") d.minSize = d.minWidth; + return d; + }; + + // TODO: see if these methods can be made more useful... + // TODO: *maybe* return cssW/H from these so caller can use this info + + var setOuterWidth = function (el, outerWidth, autoHide) { + var $E = el, w; + if (typeof el == "string") $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + w = cssW($E, outerWidth); + $E.css({ width: w }); + if (w > 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!state.browser.mozilla) // FireFox refreshes iframes - IE doesn't + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + }; + + var setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el; + if (typeof el == "string") $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!state.browser.mozilla) // FireFox refreshes iframes - IE doesn't + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + }; + + var setOuterSize = function (el, outerSize, autoHide) { + if (_c[pane].dir=="horz") // pane = north or south + setOuterHeight(el, outerSize, autoHide); + else // pane = east or west + setOuterWidth(el, outerSize, autoHide); + }; + + + /** + * _parseSize + * + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + * @returns Integer + */ + var _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (typeof size=='string' && size.match(/%/)) + size = parseInt(size) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size,10); + else if (size > 0) { // percentage, eg: .25 + var o = options, avail; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + return Math.floor(avail * size); + } + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var + $P = $Ps[pane] + , dim = (dir == "horz" ? "height" : "width") + , vis = _showInvisibly($P) // show pane invisibly if hidden + , s = $P.css(dim); // SAVE current size + ; + $P.css(dim, "auto"); + size = (dim == "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, s).css(vis); // RESET size & visibility + return size; + } + }; + + /** + * getPaneSize + * + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @returns Integer Returns EITHER Width for east/west panes OR Height for north/south panes - adjusted for boxModel & browser + */ + var getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir == "horz") + return $P.outerHeight() + oSp; + else // dir == "vert" + return $P.outerWidth() + oSp; + }; + + /** + * setSizeLimits + * + * Calculate min/max pane dimensions and limits for resizing + */ + var setSizeLimits = function (pane, slide) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , side = c.side.toLowerCase() + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.altSide[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.insetTop + , left = sC.insetLeft + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + }; + + /** + * calcNewCenterPaneDims + * + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @returns JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ + var calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + with (d) { // NOTE: sC = state.container + // calc center-pane's outer dimensions + width = sC.innerWidth - left - right; // outerWidth + height = sC.innerHeight - bottom - top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + top += sC.insetTop; + bottom += sC.insetBottom; + left += sC.insetLeft; + right += sC.insetRight; + } + + return d; + }; + + + /** + * getElemDims + * + * Returns data for setting size of an element (container or a pane). + * + * @callers _create(), onWindowResize() for container, plus others for pane + * @returns JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ + var getElemDims = function ($E) { + var + d = {} // dimensions hash + , x = d.css = {} // CSS hash + , i = {} // TEMP insets + , b, p // TEMP border, padding + , off = $E.offset() + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { + b = x["border" + e] = _borderWidth($E, e); + p = x["padding"+ e] = _cssNum($E, "padding"+e); + i[e] = b + p; // total offset of content from outer side + d["inset"+ e] = p; + /* WRONG ??? + // if BOX MODEL, then 'position' = PADDING (ignore borderWidth) + if ($E == $Container) + d["inset"+ e] = (state.browser.boxModel ? p : 0); + */ + }); + + d.offsetWidth = $E.innerWidth(true); // true=include Padding + d.offsetHeight = $E.innerHeight(true); + d.outerWidth = $E.outerWidth(); + d.outerHeight = $E.outerHeight(); + d.innerWidth = d.outerWidth - i.Left - i.Right; + d.innerHeight = d.outerHeight - i.Top - i.Bottom; + + // TESTING + x.width = $E.width(); + x.height = $E.height(); + + return d; + }; + + var getElemCSS = function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p == "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + }; + + + var setTimer = function (name, fn, ms) { + clearTimer(name); // clear previous timer if exists + _c.timers[name] = setTimeout(fn, ms); + }; + + var clearTimer = function (name) { + if (_c.timers[name]) { + clearTimeout(_c.timers[name]); + delete _c.timers[name]; + } + }; + + var isTimerRunning = function (name) { + return !!_c.timers[name]; + } + + var getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state == _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + }; + var addHover = function (evt, el) { + var e = el || this; + $(e).addClass( getHoverClasses(e) ); + //if (evt && $(e).data("layoutRole") == "toggler") evt.stopPropagation(); + }; + var removeHover = function (evt, el) { + var e = el || this; + $(e).removeClass( getHoverClasses(e, true) ); + }; + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * _create + * + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @callers none - triggered onInit + * @returns An object pointer to the instance created + */ + var _create = function () { + // initialize config/options + initOptions(); + var o = options; + + // onload will CANCEL resizing if returns false + if (false === _execCallback(null, o.onload)) return false; + + // a center pane is required, so make sure it exists + if (!getPane('center').length) { + alert( lang.errCenterPaneMissing ); + return null; + } + + // update options with saved state, if option enabled + if (o.useStateCookie && o.cookie.autoLoad) + loadCookie(); // Update options from state-cookie + + // set environment - can update code here if $.browser is phased out + state.browser = { + mozilla: $.browser.mozilla + , msie: $.browser.msie + , isIE6: $.browser.msie && $.browser.version == 6 + , boxModel: $.support.boxModel + //, version: $.browser.version - not used + }; + + // initialize all layout elements + initContainer(); // set CSS as needed and init state.container dimensions + initPanes(); // size & position all panes - calls initHandles() + //initHandles(); // create and position all resize bars & togglers buttons + initResizable(); // activate resizing on all panes where resizable=true + sizeContent("all"); // AFTER panes & handles have been initialized, size 'content' divs + + if (o.scrollToBookmarkOnLoad) + with (self.location) if (hash) replace( hash ); // scrollTo Bookmark + + // search for and bind custom-buttons + if (o.autoBindCustomButtons) initButtons(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + // track mouse position so we can use it anytime we need it + initMouseTracking(); + + // bind resizeAll() for 'this layout instance' to window.resize event + if (o.resizeWithWindow && !$Container.data("layoutRole")) // skip if 'nested' inside a pane + $(window).bind("resize."+ sID, windowResize); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + state.initialized = true; + }; + + var windowResize = function () { + var delay = Number(options.resizeWithWindowDelay) || 100; // there MUST be some delay! + if (delay > 0) { + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + clearTimer("winResize"); // if already running + setTimer("winResize", function(){ clearTimer("winResize"); clearTimer("winResizeRepeater"); resizeAll(); }, delay); + // ALSO set fixed-delay timer, if not already running + if (!_c.timers["winResizeRepeater"]) setWindowResizeRepeater(); + } + }; + + var setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + setTimer("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + }; + + var unload = function () { + var o = options; + state.cookie = getState(); // save state in case onunload has custom state-management + if (o.useStateCookie && o.cookie.autoSave) saveCookie(); + + _execCallback(null, o.onunload); + }; + + /** + * initMouseTracking / trackMouse / isMouseOver + * + * Bound to document.mousemove - updates window.mouseCoords.X/Y + * + * TODO: use ui.isOver(y, x, top, left, height, width) + */ + var initMouseTracking = function () { + if (!window.mouseCoords) { // only need 1 mouse tracker! + window.mouseCoords = { X: 0, Y: 0 }; // init + $(document).bind("mousemove."+ sID, trackMouse); + } + }; + var trackMouse = function (evt) { + var m = window.mouseCoords; + m.X = evt.pageX; + m.Y = evt.pageY; + }; + var isMouseOver = function (el) { + var $E = (typeof el == "string" && $Ps[el]) ? $Ps[el] : $(el); + if (!$E.length) return false; + var + _ = this + , d = $E.offset() + , T = d.top + , L = d.left + , R = L + $E.outerWidth() + , B = T + $E.outerHeight() + , m = window.mouseCoords + ; + return ((m.X >= L && m.X <= R) && (m.Y >= T && m.Y <= B)); + }; + + + /** + * initContainer + * + * Validate and initialize container CSS and events + * + * @callers _create() + */ + var initContainer = function () { + sC.tagName = $Container.attr("tagName"); + var + isFullPage = (sC.tagName == "BODY") + , $C = $Container // alias + , props = "position,margin,padding,border" + , CSS = {} + ; + sC.ref = sC.tagName + ($C.selector || "").split(".slice")[0]; + + // the layoutContainer key is used to store the unique layoutID + $C + .data("layoutContainer", sID) // unique identifier for internal use + .data("layoutName", options.name) // add user's layout-name - even if blank! + ; + + // SAVE original container CSS for use in destroy() + if (!$C.data("layoutCSS")) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (isFullPage) { + CSS = $.extend( getElemCSS($C, props), { + height: $C.css("height") + , overflow: $C.css("overflow") + , overflowX: $C.css("overflowX") + , overflowY: $C.css("overflowY") + }); + // ALSO SAVE CSS + var $H = $("html"); + $H.data("layoutCSS", { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + }); + } + else // handle props normally for non-body elements + CSS = getElemCSS($C, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY"); + + $C.data("layoutCSS", CSS); + } + + try { // format html/body if this is a full page layout + if (isFullPage) { + $("html").css({ + height: "100%" + , overflow: "hidden" + , overflowX: "hidden" + , overflowY: "hidden" + }); + $("body").css({ + position: "relative" + , height: "100%" + , overflow: "hidden" + , overflowX: "hidden" + , overflowY: "hidden" + , margin: 0 + , padding: 0 // TODO: test whether body-padding could be handled? + , border: "none" // a body-border creates problems because it cannot be measured! + }); + } + else { // set required CSS for overflow and position + var + CSS = { overflow: "hidden" } // make sure container will not 'scroll' + , p = $C.css("position") + , h = $C.css("height") + ; + // if this is a NESTED layout, then container/outer-pane ALREADY has position and height + if (!$C.data("layoutRole")) { + if (!p || !p.match(/fixed|absolute|relative/)) + CSS.position = "relative"; // container MUST have a 'position' + /* + if (!h || h=="auto") + CSS.height = "100%"; // container MUST have a 'height' + */ + } + $C.css( CSS ); + if ($C.is(":visible") && $C.innerHeight() < 2) + alert( lang.errContainerHeight.replace(/CONTAINER/, sC.ref) ); + } + } catch (ex) {} + + // set current layout-container dimensions + $.extend(state.container, getElemDims( $C )); + }; + + /** + * initHotkeys + * + * Bind layout hotkeys - if options enabled + * + * @callers _create() + */ + var initHotkeys = function () { + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(_c.borderPanes.split(","), function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + }; + + /** + * initOptions + * + * Build final OPTIONS data + * + * @callers _create() + */ + var initOptions = function () { + // simplify logic by making sure passed 'opts' var has basic keys + opts = _transformData( opts ); + + // TODO: create a compatibility add-on for new UI widget that will transform old option syntax + var newOpts = { + applyDefaultStyles: "applyDemoStyles" + }; + renameOpts(opts.defaults); + $.each(_c.allPanes.split(","), function (i, pane) { + renameOpts(opts[pane]); + }); + + // update default effects, if case user passed key + if (opts.effects) { + $.extend( effects, opts.effects ); + delete opts.effects; + } + $.extend( options.cookie, opts.cookie ); + + // see if any 'global options' were specified + var globals = "name,zIndex,scrollToBookmarkOnLoad,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,"+ + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons,useStateCookie"; + $.each(globals.split(","), function (i, key) { + if (opts[key] !== undefined) + options[key] = opts[key]; + else if (opts.defaults[key] !== undefined) { + options[key] = opts.defaults[key]; + delete opts.defaults[key]; + } + }); + + // remove any 'defaults' that MUST be set 'per-pane' + $.each("paneSelector,resizerCursor,customHotkey".split(","), + function (i, key) { delete opts.defaults[key]; } // is OK if key does not exist + ); + + // now update options.defaults + $.extend( true, options.defaults, opts.defaults ); + + // merge config for 'center-pane' - border-panes handled in the loop below + _c.center = $.extend( true, {}, _c.panes, _c.center ); + // update config.zIndex values if zIndex option specified + var z = options.zIndex; + if (z === 0 || z > 0) { + _c.zIndex.pane_normal = z; + _c.zIndex.resizer_normal = z+1; + _c.zIndex.iframe_mask = z+1; + } + + // merge options for 'center-pane' - border-panes handled in the loop below + $.extend( options.center, opts.center ); + // Most 'default options' do not apply to 'center', so add only those that DO + var o_Center = $.extend( true, {}, options.defaults, opts.defaults, options.center ); // TEMP data + $.each("paneClass,contentSelector,applyDemoStyles,showOverflowOnHover,triggerEventsOnLoad".split(","), + function (i, key) { options.center[key] = o_Center[key]; } + ); + + var o, defs = options.defaults; + + // create a COMPLETE set of options for EACH border-pane + $.each(_c.borderPanes.split(","), function (i, pane) { + + // apply 'pane-defaults' to CONFIG.[PANE] + _c[pane] = $.extend( true, {}, _c.panes, _c[pane] ); + + // apply 'pane-defaults' + user-options to OPTIONS.PANE + o = options[pane] = $.extend( true, {}, options.defaults, options[pane], opts.defaults, opts[pane] ); + + // make sure we have base-classes + if (!o.paneClass) o.paneClass = "ui-layout-pane"; + if (!o.resizerClass) o.resizerClass = "ui-layout-resizer"; + if (!o.togglerClass) o.togglerClass = "ui-layout-toggler"; + + // create FINAL fx options for each pane, ie: options.PANE.fxName/fxSpeed/fxSettings[_open|_close] + $.each(["_open","_close",""], function (i,n) { + var + sName = "fxName"+n + , sSpeed = "fxSpeed"+n + , sSettings = "fxSettings"+n + ; + // recalculate fxName according to specificity rules + o[sName] = + opts[pane][sName] // opts.west.fxName_open + || opts[pane].fxName // opts.west.fxName + || opts.defaults[sName] // opts.defaults.fxName_open + || opts.defaults.fxName // opts.defaults.fxName + || o[sName] // options.west.fxName_open + || o.fxName // options.west.fxName + || defs[sName] // options.defaults.fxName_open + || defs.fxName // options.defaults.fxName + || "none" + ; + // validate fxName to be sure is a valid effect + var fxName = o[sName]; + if (fxName == "none" || !$.effects || !$.effects[fxName] || (!effects[fxName] && !o[sSettings] && !o.fxSettings)) + fxName = o[sName] = "none"; // effect not loaded, OR undefined FX AND fxSettings not passed + // set vars for effects subkeys to simplify logic + var + fx = effects[fxName] || {} // effects.slide + , fx_all = fx.all || {} // effects.slide.all + , fx_pane = fx[pane] || {} // effects.slide.west + ; + // RECREATE the fxSettings[_open|_close] keys using specificity rules + o[sSettings] = $.extend( + {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , defs.fxSettings || {} // options.defaults.fxSettings + , defs[sSettings] || {} // options.defaults.fxSettings_open + , o.fxSettings // options.west.fxSettings + , o[sSettings] // options.west.fxSettings_open + , opts.defaults.fxSettings // opts.defaults.fxSettings + , opts.defaults[sSettings] || {} // opts.defaults.fxSettings_open + , opts[pane].fxSettings // opts.west.fxSettings + , opts[pane][sSettings] || {} // opts.west.fxSettings_open + ); + // recalculate fxSpeed according to specificity rules + o[sSpeed] = + opts[pane][sSpeed] // opts.west.fxSpeed_open + || opts[pane].fxSpeed // opts.west.fxSpeed (pane-default) + || opts.defaults[sSpeed] // opts.defaults.fxSpeed_open + || opts.defaults.fxSpeed // opts.defaults.fxSpeed + || o[sSpeed] // options.west.fxSpeed_open + || o[sSettings].duration // options.west.fxSettings_open.duration + || o.fxSpeed // options.west.fxSpeed + || o.fxSettings.duration // options.west.fxSettings.duration + || defs.fxSpeed // options.defaults.fxSpeed + || defs.fxSettings.duration// options.defaults.fxSettings.duration + || fx_pane.duration // effects.slide.west.duration + || fx_all.duration // effects.slide.all.duration + || "normal" // DEFAULT + ; + }); + + }); + + function renameOpts (O) { + for (var key in newOpts) { + if (O[key] != undefined) { + O[newOpts[key]] = O[key]; + delete O[key]; + } + } + } + }; + + /** + * initPanes + * + * Initialize module objects, styling, size and position for all panes + * + * @callers _create() + */ + var getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $Container.find(sel).eq(0); + else { // class or other selector + var $P = $Container.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $Container.children("form:first").children(sel).eq(0); + } + }; + var initPanes = function () { + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes.split(","), function (idx, pane) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , fx = s.fx + , dir = c.dir + , spacing = o.spacing_open || 0 + , isCenter = (pane == "center") + , CSS = {} + , $P, $C + , size, minSize, maxSize + ; + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return true; // SKIP to next + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", getElemCSS($P, props)); + } + + // add basic classes & attributes + $P + .data("layoutName", options.name) // add user's layout-name - even if blank! + .data("layoutRole", "pane") + .data("layoutEdge", pane) + .css(c.cssReq).css("zIndex", _c.zIndex.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + + // see if this pane has a 'scrolling-content element' + if (o.contentSelector) { + $C = $Cs[pane] = $P.find(o.contentSelector).eq(0); // match 1-element only + if (!$C.length) + $Cs[pane] = false; + else { + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + s.content = {}; // init content state + // sizeContent() is called later + } + } + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as it's 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + } + + // init pane-logic vars + s.tagName = $P.attr("tagName"); + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + if (!isCenter) { + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + } + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.insetTop; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "south": CSS.bottom = sC.insetBottom; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "west": CSS.left = sC.insetLeft; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.insetRight; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + + if (dir == "horz") // north or south pane + CSS.height = max(1, cssH(pane, size)); + else if (dir == "vert") // east or west pane + CSS.width = max(1, cssW(pane, size)); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // NOW make the pane visible - in case was initially hidden + $P.css({ visibility: "visible", display: "block" }); + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + // ELSE setAsOpen() - called later by initHandles() + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + }); + + /* + * init the pane-handles NOW in case we have to hide or close the pane below + */ + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes.split(","), function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // trigger onResize callbacks for all panes with triggerEventsOnLoad = true + $.each(_c.allPanes.split(","), function (i, pane) { + o = options[pane]; + if ($Ps[pane] && o.triggerEventsOnLoad && state[pane].isVisible) // pane is OPEN + _execCallback(pane, o.onresize_end || o.onresize); // call onresize + }); + + if ($Container.innerHeight() < 2) + alert( lang.errContainerHeight.replace(/CONTAINER/, sC.ref) ); + }; + + /** + * initHandles + * + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @callers _create() + */ + var initHandles = function (panes) { + if (!panes || panes == "all") panes = _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes.split(","), function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , rClass = o.resizerClass + , tClass = o.togglerClass + , side = c.side.toLowerCase() + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + // INIT RESIZER BAR + , $R = $Rs[pane] = $("
    ") + // INIT TOGGLER BUTTON + , $T = (o.closable ? $Ts[pane] = $("
    ") : false) + ; + + if (s.isVisible && o.resizable) + ; // handled by initResizable + else if (!s.isVisible && o.slidable) + $R.attr("title", o.sliderTip).css("cursor", o.sliderCursor); + + $R + // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-resizer" : "")) + .data("layoutRole", "resizer") + .data("layoutEdge", pane) + .css(_c.resizers.cssReq).css("zIndex", _c.zIndex.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .appendTo($Container) // append DIV to container + .hover( addHover, removeHover ) + ; + + if ($T) { + $T + // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-toggler" : "")) + .data("layoutRole", "toggler") + .data("layoutEdge", pane) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .appendTo($R) // append SPAN to resizer DIV + .click(function(evt){ toggle(pane); evt.stopPropagation(); }) + .hover( addHover, removeHover ) + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $(""+ o.togglerContent_open +"") + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + .hover( addHover, removeHover ) + ; + if (o.togglerContent_closed) // ui-layout-closed + $(""+ o.togglerContent_closed +"") + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + .hover( addHover, removeHover ) + ; + } + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles("all"); + }; + + /** + * initButtons + * + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @callers _create() + */ + var initButtons = function () { + var pre = "ui-layout-button-", name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each(_c.borderPanes.split(","), function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name == options.name) { + if (action.substr("-slide") > 0) + bindButton(this, action.split("-")[0], pane, true) + else + bindButton(this, action, pane); + } + }); + }); + }); + }; + + /** + * initResizable + * + * Add resize-bars to all panes that specify it in options + * + * @dependancies $.fn.resizable - will skip if not found + * @callers _create() + */ + var initResizable = function (panes) { + var + draggingAvailable = (typeof $.fn.draggable == "function") + , $Frames, side // set in start() + ; + if (!panes || panes == "all") panes = _c.borderPanes; + + $.each(panes.split(","), function (idx, pane) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , side = (c.dir=="horz" ? "top" : "left") + , r, live // set in start because may change + ; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R + .attr("title", o.resizerTip) + .css("cursor", o.resizerCursor) // n-resize, s-resize, etc + ; + + $R.draggable({ + containment: $Container[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 100 + , distance: 1 + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: _c.zIndex.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.resizeWhileDragging; + + // onresize_start callback - will CANCEL hide if returns false + // TODO: CONFIRM that dragging can be cancelled like this??? + if (false === _execCallback(pane, o.onresize_start)) return false; + + _c.isLayoutBusy = true; // used by sizePane() logic during a liveResize + s.isResizing = true; // prevent pane from closing while resizing + clearTimer(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // MASK PANES WITH IFRAMES OR OTHER TROUBLESOME ELEMENTS + $Frames = $(o.maskIframesOnResize === true ? "iframe" : o.maskIframesOnResize).filter(":visible"); + var id, i=0; // ID incrementer - used when 'resizing' masks during dynamic resizing + $Frames.each(function() { + id = "ui-layout-mask-"+ (++i); + $(this).data("layoutMaskID", id); // tag iframe with corresponding maskID + $('
    ') + .css({ + background: "#fff" + , opacity: "0.001" + , zIndex: _c.zIndex.iframe_mask + , position: "absolute" + , width: this.offsetWidth+"px" + , height: this.offsetHeight+"px" + }) + .css($(this).position()) // top & left -- changed from offset() + .appendTo(this.parentNode) // put mask-div INSIDE pane to avoid zIndex issues + ; + }); + + // DISABLE TEXT SELECTION - particularly for WebKit browsers, Safari & Chrome + if (o.noSelectionWhileDragging) $(document).disableSelection(); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", _c.zIndex.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass ); // at dragging-limit + window.defaultStatus = "Panel has reached its "+ (limit>0 ? "maximum" : "minimum") +" size"; + } + else { + ui.helper.removeClass( helperLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + if (live) resizePanes(e, ui, pane); + } + + , stop: function (e, ui) { + // RE-ENABLE TEXT SELECTION + if (o.noSelectionWhileDragging) $(document).enableSelection(); + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass +" "+ helperLimitClass ); // remove drag classes from Resizer + s.isResizing = false; + _c.isLayoutBusy = false; // set BEFORE resizePanes so other logic can pick it up + resizePanes(e, ui, pane, true); // true = resizingDone + } + + }); + + /** + * resizePanes + * + * Sub-routine called from stop() and optionally drag() + */ + var resizePanes = function (e, ui, pane, resizingDone) { + var + dragPos = ui.position + , c = _c[pane] + , resizerPos, newSize + , i = 0 // ID incrementer + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.offsetHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.offsetWidth - dragPos.left - o.spacing_open; break; + }; + + // remove container margin from resizer position to get the pane size + newSize = resizerPos - sC["inset"+ c.side]; + manualSizePane(pane, newSize); + + if (resizingDone) { + // Remove OR Resize MASK(S) created in drag.start + $("div.ui-layout-mask").each(function() { this.parentNode.removeChild(this); }); + //$("div.ui-layout-mask").remove(); // TODO: Is this less efficient? + } + else + $Frames.each(function() { + $("#"+ $(this).data("layoutMaskID")) // get corresponding mask by ID + .css($(this).position()) // update top & left + .css({ // update width & height + width: this.offsetWidth +"px" + , height: this.offsetHeight+"px" + }) + ; + }); + } + }); + }; + + + /** + * destroy + * + * Destroy this layout and reset all elements + */ + var destroy = function () { + // UNBIND layout events and remove global object + $(window).unbind("."+ sID); + $(document).unbind("."+ sID); + window[ sID ] = null; + + var + isFullPage = (sC.tagName == "BODY") + // create list of ALL pane-classes that need to be removed + , root = o.paneClass // default="ui-layout-pane" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , generic = [ root, root+_open, root+_closed, root+_sliding ] // generic classes + , $P, pRoot, pClasses // loop vars + ; + // loop all panes to remove layout classes, attributes and bindings + $.each(_c.allPanes.split(","), function (i, pane) { + $P = $Ps[pane]; + if (!$P) return true; // no pane - SKIP + + // REMOVE pane's resizer and toggler elements + if (pane != "center") { + $Ts[pane].remove(); + $Rs[pane].remove(); + } + + pRoot = root+"-"+pane; // eg: "ui-layout-pane-west" + pClasses = []; // reset + pClasses.push( pRoot ); + pClasses.push( pRoot+_open ); + pClasses.push( pRoot+_closed ); + pClasses.push( pRoot+_sliding ); + + $.merge(pClasses, generic); // ADD generic classes + $.merge(pClasses, getHoverClasses($P, true)); // ADD hover-classes + + $P + .removeClass( pClasses.join(" ") ) // remove ALL pane-classes + .removeData("layoutRole") + .removeData("layoutEdge") + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + .unbind("mouseenter") + .unbind("mouseleave") + ; + + // do NOT reset CSS if this pane is STILL the container of a nested layout! + // the nested layout will reset its 'container' when/if it is destroyed + if (!$P.data("layoutContainer")) + $P.css( $P.data("layoutCSS") ); + }); + + // reset layout-container + $Container.removeData("layoutContainer"); + + // do NOT reset container CSS if is a 'pane' in an outer-layout - ie, THIS layout is 'nested' + if (!$Container.data("layoutEdge")) + $Container.css( $Container.data("layoutCSS") ); // RESET CSS + // for full-page layouts, must also reset the CSS + if (isFullPage) + $("html").css( $("html").data("layoutCSS") ); // RESET CSS + + // trigger state-management and onunload callback + unload(); + + var n = options.name; // layout-name + if (n && window[n]) window[n] = null; // clear window object, if exists + }; + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + + /** + * hide / show + * + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param String pane The pane being hidden, ie: north, south, east, or west + */ + var hide = function (pane, noAnimation) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _execCallback(pane, o.onhide_start)) return; + + s.isSliding = false; // just in case + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + $P.hide(); // no animation when loading page + sizeMidPanes(_c[pane].dir == "horz" ? "all" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _execCallback(pane, o.onhide_end || o.onhide); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + }; + + var show = function (pane, openPane, noAnimation, noAlert) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _execCallback(pane, o.onshow_start)) return; + + s.isSliding = false; // just in case + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + }; + + + var slideOpen = function (evt_or_pane) { + var + type = typeof evt_or_pane + , pane = (type == "string" ? evt_or_pane : $(this).data("layoutEdge")) + ; + // prevent event from triggering on NEW resizer binding created below + if (type == "object") { evt_or_pane.stopImmediatePropagation(); } + + if (state[pane].isClosed) + open(pane, true); // true = slide - ie, called from here! + else // skip 'open' if already open! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + }; + + var slideClosed = function (evt_or_pane) { + var + $E = (typeof evt_or_pane == "string" ? $Ps[evt_or_pane] : $(this)) + , pane= $E.data("layoutEdge") + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + ; + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close == "click") + close_NOW(); // close immediately onClick + else if (o.trackMouseWhenSliding && isMouseOver(pane)) + clearTimer(pane+"_closeSlider"); // browser glitch - mouse is REALLY 'over' the pane + else // trigger = mouseout - use a delay + setTimer(pane+"_closeSlider", close_NOW, 300); // .3 sec delay + + // SUBROUTINE for timed close + function close_NOW (e) { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events + else + close(pane); // close will handle unbinding + } + }; + + + /** + * toggle + * + * Toggles a pane open/closed by calling either open or close + * + * @param String pane The pane being toggled, ie: north, south, east, or west + */ + var toggle = function (pane, slide) { + if (typeof pane !="string") + pane = $(this).data("layoutEdge"); // bound to $R.dblclick + var s = state[pane]; + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + }; + + /** + * close + * + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param String pane The pane being closed, ie: north, south, east, or west + */ + var close = function (pane, force, noAnimation, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none") + // transfer logic vars to temp vars + , isShowing = s.isShowing + , isHiding = s.isHiding + , wasSliding = s.isSliding + ; + // now clear the logic vars + delete s.isShowing; + delete s.isHiding; + + if (!$P || !o.closable) return; // invalid request // (!o.resizable && !o.closable) ??? + else if (!force && s.isClosed && !isShowing) return; // already closed + + if (_c.isLayoutBusy) { // layout is 'busy' - probably with an animation + _queue("close", pane, force); // set a callback for this action, if possible + return; // ABORT + } + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + if (state.initialized && !isShowing && false === _execCallback(pane, o.onclose_start)) return; + + // SET flow-control flags + _c[pane].isMoving = true; + _c.isLayoutBusy = true; + + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else if (state.initialized) // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir == "horz" ? "all" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + if (state.initialized) setAsClosed(pane); // during init, setAsClosed will be called LATER by initHandles + + // ANIMATE 'CLOSE' - if no animation, then was ALREADY shown above + if (doFX) { + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + close_2(); + }); + } + else { + $P.hide(); // just hide pane NOW + close_2(); + }; + + // SUBROUTINE + function close_2 () { + if (s.isClosed) { // make sure pane was not 'reopened' before animation finished! + + bindStartSlidingEvent(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.altSide[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing && !wasSliding) _execCallback(pane, o.onclose_end || o.onclose); + // onhide OR onshow callback + if (isShowing) _execCallback(pane, o.onshow_end || o.onshow); + if (isHiding) _execCallback(pane, o.onhide_end || o.onhide); + } + } + // execute internal flow-control callback + _dequeue(pane); + } + }; + + var setAsClosed = function (pane) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC[inset]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .unbind("dblclick."+ sID) + ; + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent? + if (o.resizable && typeof $.fn.draggable == "function") + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.togglerTip_closed) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles("all"); + } + }; + + /** + * open + * + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param String pane The pane being opened, ie: north, south, east, or west + */ + var open = function (pane, slide, noAnimation, noAlert) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , doFX = !noAnimation && s.isClosed && (o.fxName_open != "none") + // transfer logic var to temp var + , isShowing = s.isShowing + ; + // now clear the logic var + delete s.isShowing; + + if (!$P || (!o.resizable && !o.closable)) return; // invalid request + else if (s.isVisible && !s.isSliding) return; // already open + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !isShowing) { + show(pane, true); + return; + } + + if (_c.isLayoutBusy) { // layout is 'busy' - probably with an animation + _queue("open", pane, slide); // set a callback for this action, if possible + return; // ABORT + } + + // onopen_start callback - will CANCEL hide if returns false + if (false === _execCallback(pane, o.onopen_start)) return; + + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); // update pane-state + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.noRoomToOpenTip) alert(o.noRoomToOpenTip); + return; // ABORT + } + + // SET flow-control flags + _c[pane].isMoving = true; + _c.isLayoutBusy = true; + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvent(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + open_2(); // continue + }); + } + else {// no animation + $P.show(); // just show pane and... + open_2(); // continue + }; + + // SUBROUTINE + function open_2 () { + if (s.isVisible) { // make sure pane was not closed or hidden before animation finished! + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) // resize all panes adjacent to this one + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "all", false); // false = NOT skipCallback + else if (o.slideTrigger_close == "mouseout" && isTimerRunning(pane+"_closeSlider")) { + if (o.trackMouseWhenSliding && isMouseOver(pane)) // handle Chrome browser glitch... + clearTimer(pane+"_closeSlider"); // prevent premature close + } + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + } + + // internal flow-control callback + _dequeue(pane); + }; + + }; + + var setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC[inset] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + if (o.resizerDblClickToggle) + $R.bind("dblclick", toggle ); + removeHover( 0, $R ); // remove hover classes + if (o.resizable && typeof $.fn.draggable == "function") + $R + .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.resizerTip) + ; + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.togglerTip_open) // may be blank + ; + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles("all"); + // resize content every time pane opens - to be sure + sizeContent(pane); + } + + // update pane-state dimensions + $.extend(s, getElemDims($P)); + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _execCallback(pane, o.onopen_end || o.onopen); + // onshow callback - TODO: should this be here? + if (s.isShowing) _execCallback(pane, o.onshow_end || o.onshow); + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) _execCallback(pane, o.onresize_end || o.onresize); // if (state.initialized) + } + }; + + + /** + * lockPaneForFX + * + * Must set left/top on East/South panes so animation will work properly + * + * @param String pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param Boolean doLock true = set left/top, false = remove + */ + var lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane]; + if (doLock) { + $P.css({ zIndex: _c.zIndex.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + $P.css({ zIndex: (state[pane].isSliding ? _c.zIndex.pane_sliding : _c.zIndex.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + else if (pane=="east") + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + var o = options[pane]; + if (state.browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + }; + + + /** + * bindStartSlidingEvent + * + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @callers open(), close() + * @param String pane The pane to enable/disable, 'north', 'south', etc. + * @param Boolean enable Enable or Disable sliding? + */ + var bindStartSlidingEvent = function (pane, enable) { + var + o = options[pane] + , $R = $Rs[pane] + , trigger = o.slideTrigger_open + ; + if (!$R || !o.slidable) return; + + // make sure we have a valid event + if (trigger != "click" && trigger != "dblclick" && trigger != "mouseover") + trigger = o.slideTrigger_open = "click"; + + $R + // add or remove trigger event + [enable ? "bind" : "unbind"](trigger, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", (enable ? o.sliderCursor : "default")) + .attr("title", (enable ? o.sliderTip : "")) + ; + }; + + /** + * bindStopSlidingEvents + * + * Add or remove 'mouseout' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvent for code to control 'slide open' + * + * @callers slideOpen(), slideClosed() + * @param String pane The pane to process, 'north', 'south', etc. + * @param Boolean enable Enable or Disable events? + */ + var bindStopSlidingEvents = function (pane, enable) { + var + o = options[pane] + , s = state[pane] + , trigger = o.slideTrigger_close + , action = (enable ? "bind" : "unbind") // can't make 'unbind' work! - see disabled code below + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + + s.isSliding = enable; // logic + clearTimer(pane+"_closeSlider"); // just in case + + // raise z-index when sliding + $P.css({ zIndex: (enable ? _c.zIndex.pane_sliding : _c.zIndex.pane_normal) }); + $R.css({ zIndex: (enable ? _c.zIndex.pane_sliding : _c.zIndex.resizer_normal) }); + + // make sure we have a valid event + if (trigger != "mouseout" && trigger != "click") + trigger = o.slideTrigger_close = "mouseout"; + + // remove 'slideOpen' trigger event from resizer + if (enable) bindStartSlidingEvent(pane, false); + + // add/remove slide triggers + $R[action](trigger, slideClosed); // base event on resize + // need extra events for mouseout + if (trigger == "mouseout") { + // also close on pane.mouseout + $P[action]("mouseout."+ sID, slideClosed); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseover", cancelMouseOut); + $P[action]("mouseover."+ sID, cancelMouseOut); + } + + if (!enable) + clearTimer(pane+"_closeSlider"); + else if (trigger == "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", (enable ? o.sliderCursor : "default")); + $R.attr("title", (enable ? o.togglerTip_open : "")); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseout timer clearing + function cancelMouseOut (evt) { + clearTimer(pane+"_closeSlider"); + evt.stopPropagation(); + } + }; + + + /** + * makePaneFit + * + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + */ + var makePaneFit = function (pane, isOpening, skipCallback) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir=="vert" + , hasRoom = false + ; + + // special handling for center pane + if (pane == "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the center-pane + hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + $P.show(); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + $P.hide(); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane == "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback); + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback); + else if ($R && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var + side = c.side.toLowerCase() + , pos = s.size + sC["inset"+ c.side] + ; + if (_cssNum($R, side) != pos) $R.css( side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + }; + + + /** + * sizePane / manualSizePane + * + * sizePane is called only by internal methods whenever a pane needs to be resized + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param String pane The pane being resized + * @param Integer size The *desired* new size for this pane - will be validated + * @param Boolean skipCallback Should the onresize callback be run? + */ + var manualSizePane = function (pane, size, skipCallback) { + // ANY call to sizePane will disabled autoResize + var + o = options[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = o.resizeWhileDragging && !_c.isLayoutBusy // && !o.triggerEventsWhileDragging + ; + o.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, forceResize); + } + var sizePane = function (pane, size, skipCallback, force) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , skipResizeWhileDragging = _c.isLayoutBusy && !o.triggerEventsWhileDragging + , oldSize + ; + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size == oldSize) return; + s.size = size; + + // resize the pane, and make sure its visible + $P.css( _c[pane].sizeType.toLowerCase(), max(1, cssSize(pane, size)) ); + + // update pane-state dimensions + $.extend(s, getElemDims($P)); + + // reposition the resizer-bar + if ($R && $P.is(":visible")) $R.css( side, size + sC[inset] ); + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsWhileDragging + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "all" : "center", skipResizeWhileDragging, force); + sizeHandles("all"); + } + + sizeContent(pane); + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) + _execCallback(pane, o.onresize_end || o.onresize); + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.altSide[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + }; + + /** + * sizeMidPanes + * + * @callers initPanes(), sizePane(), resizeAll(), open(), close(), hide() + */ + var sizeMidPanes = function (panes, skipCallback, force) { + if (!panes || panes == "all") panes = "east,west,center"; + + $.each(panes.split(","), function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + , d = calcNewCenterPaneDims() + ; + // update pane-state dimensions + $.extend(s, getElemDims($P)); + + if (pane == "center") { + if (!force && s.isVisible && d.width == s.outerWidth && d.height == s.outerHeight) + return true; // SKIP - pane already the correct size + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: d.width + , maxHeight: d.height + }); + CSS = d; + // convert OUTER width/height to CSS width/height + CSS.width = cssW(pane, d.width); + CSS.height = cssH(pane, d.height); + hasRoom = CSS.width > 0 && CSS.height > 0; + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + $.extend(s, getElemDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && d.height == s.outerHeight) + return true; // SKIP - pane already the correct size + CSS.top = d.top; + CSS.bottom = d.bottom; + CSS.height = cssH(pane, d.height); + s.maxHeight = max(0, CSS.height); + hasRoom = (s.maxHeight > 0); + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + $P.css(CSS); // apply the CSS to pane + if (pane == "center") $.extend(s, getElemDims($P)); // set new dimensions + if (s.noRoom) makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (state.initialized) sizeContent(pane); + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + */ + if (pane == "center") { // finished processing midPanes + var b = state.browser; + var fix = b.isIE6 || (b.msie && !b.boxModel); + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized && s.isVisible) + _execCallback(pane, o.onresize_end || o.onresize); + }); + }; + + + /** + * resizeAll + * + * @callers window.onresize(), callbacks or custom code + */ + var resizeAll = function () { + var + oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + $.extend( state.container, getElemDims( $Container ) ); // UPDATE container dimensions + if (!sC.outerHeight) return; // cannot size layout when 'container' is hidden or collapsed + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _execCallback(null, options.onresizeall_start)) return false; + + var + // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , o, s, dir + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + s = state[pane]; + o = options[pane]; + dir = _c[pane].dir; + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true); // true - skipCallback + else { + setSizeLimits(pane); + makePaneFit(pane, false, true); // true - skipCallback + } + }); + + sizeMidPanes("all", true); // true - skipCallback + sizeHandles("all"); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + o = options; // reuse alias + $.each(_c.allPanes.split(","), function (i, pane) { + if (state[pane].isVisible) // undefined for non-existent panes + _execCallback(pane, o[pane].onresize_end || o[pane].onresize); // callback - if exists + }); + + _execCallback(null, o.onresizeall_end || o.onresizeall); // onresizeall callback, if exists + }; + + + /** + * sizeContent + * + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + */ + var sizeContent = function (panes) { + if (!panes || panes == "all") panes = _c.allPanes; + $.each(panes.split(","), function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content + ; + if ($P && $C && $P.is(":visible")) { // if No Content OR Pane not visible, then skip + var eC = $C[0]; + function setOffsets () { + $.swap( $C[0], { height: "auto", display: "block", visibility: "hidden" }, function(){ + m.above = eC.offsetTop; + m.below = $P.innerHeight() - eC.offsetTop - eC.offsetHeight; + }); + }; + // defer remeasuring offsets while live-resizing + if (o.resizeContentWhileDragging || !s.isResizing || m.above == undefined) + // let pane size-to-fit (invisibly), then measure the Content offset from top & bottom + $.swap( $P[0], { position: "relative", height: "auto", visibility: "hidden" }, setOffsets ); + // resize the Content element to fit actual pane-size - will autoHide if not enough room + setOuterHeight($C, $P.innerHeight() - m.above - m.below, true); // true=autoHide + } + }); + }; + + + /** + * sizeHandles + * + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @callers initHandles(), open(), close(), resizeAll() + */ + var sizeHandles = function (panes) { + if (!panes || panes == "all") panes = _c.borderPanes; + + $.each(panes.split(","), function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , offset + , CSS = {} + ; + + if (spacing == 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir == "horz") { // north/south + paneLen = $P.outerWidth(); // s.outerWidth || + s.resizerLength = paneLen; + $R.css({ + width: max(1, cssW($R, paneLen)) // account for borders & padding + , height: max(0, cssH($R, spacing)) // ditto + , left: _cssNum($P, "left") + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: max(1, cssH($R, paneLen)) // account for borders & padding + , width: max(0, cssW($R, spacing)) // ditto + , top: sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane? + //, top: _cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen == 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen == "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (typeof togAlign == "string") { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = Math.floor((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir == "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: max(0, width) // account for borders & padding + , height: max(1, cssH($T, spacing)) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", Math.floor((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: max(0, height) // account for borders & padding + , width: max(1, cssW($T, spacing)) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", Math.floor((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && o.initHidden) { + $R.hide(); + if ($T) $T.hide(); + } + }); + }; + + + /** + * swapPanes + * + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + */ + var swapPanes = function (pane1, pane2) { + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // pane1 does not exist anymore + if (!$Ps[pane1] && $Rs[pane1]) { + $Rs[pane1].remove(); + $Rs[pane1] = $Ts[pane1] = false; + } + + // pane2 does not exist anymore + if (!$Ps[pane2] && $Rs[pane2]) { + $Rs[pane2].remove(); + $Rs[pane2] = $Ts[pane2] = false; + } + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend({}, state[n]) + , options: $.extend({}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + , side = c.side.toLowerCase() + , inset = "inset"+ c.side + // save pane-options that should be retained + , s = $.extend({}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k] = o[k]; + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data("layoutEdge", pane) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend({}, oPane.options, fx); + state[pane] = $.extend({}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp("pane-"+ oldPane, "g"); + P.className = P.className.replace(re, "pane-"+ pane); + + if (!$Rs[pane]) { + initHandles(pane); // create the required resizer & toggler + initResizable(pane); + } + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true); // true = skipCallback + } + else // move the resizer here + $Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane, true); // true = skipCallback + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + }; + + + /** + * keyDown + * + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @callers document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes.split(","), function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code == (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * allowOverflow / resetOverflow + * + * Change/reset a pane's overflow setting & zIndex to allow popups/drop-downs to work + * + * @param element elem Optional - can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (typeof el == "string") + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents.each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or it's closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (_c.zIndex.pane_normal + 1) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && ofX != "visible" && ofX != "auto") { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && ofY != "visible" && ofY != "auto") { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes.split(","), function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + + function resetOverflow (el) { + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (typeof el == "string") + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents.each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", _c.zIndex.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + + + /** + * getBtn + * + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin + * - ui-layout-pane-button-toggle + * - ui-layout-pane-button-open + * - ui-layout-pane-button-close + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .toggle-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + * @returns If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise 'false' + */ + function getBtn(selector, pane, action) { + var $E = $(selector); + if (!$E.length) // element not found + alert(lang.errButton + lang.selector +": "+ selector); + else if (_c.borderPanes.indexOf(pane) == -1) // invalid 'pane' sepecified + alert(lang.errButton + lang.Pane.toLowerCase() +": "+ pane); + else { // VALID + var btn = options[pane].buttonClass +"-"+ action; + $E + .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", options.name) // add layout identifier - even if blank! + ; + return $E; + } + return false; // INVALID + }; + + + /** + * bindButton + * + * NEW syntax for binding layout-buttons - will eventually replace addToggleBtn, addOpenBtn, etc. + * + */ + function bindButton (selector, action, pane) { + switch (action.toLowerCase()) { + case "toggle": addToggleBtn(selector, pane); break; + case "open": addOpenBtn(selector, pane); break; + case "close": addCloseBtn(selector, pane); break; + case "pin": addPinBtn(selector, pane); break; + case "toggle-slide": addToggleBtn(selector, pane, true); break; + case "open-slide": addOpenBtn(selector, pane, true); break; + } + }; + + /** + * addToggleBtn + * + * Add a custom Toggler button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .toggle-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addToggleBtn (selector, pane, slide) { + var $E = getBtn(selector, pane, "toggle"); + if ($E) + $E.click(function (evt) { + toggle(pane, !!slide); + evt.stopPropagation(); + }); + }; + + /** + * addOpenBtn + * + * Add a custom Open button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .open-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addOpenBtn (selector, pane, slide) { + var $E = getBtn(selector, pane, "open"); + if ($E) + $E + .attr("title", lang.Open) + .click(function (evt) { + open(pane, !!slide); + evt.stopPropagation(); + }) + ; + }; + + /** + * addCloseBtn + * + * Add a custom Close button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .close-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addCloseBtn (selector, pane) { + var $E = getBtn(selector, pane, "close"); + if ($E) + $E + .attr("title", lang.Close) + .click(function (evt) { + close(pane); + evt.stopPropagation(); + }) + ; + }; + + /** + * addPinBtn + * + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .ui-layout-pin" + * @param String pane Name of the pane the pin is for: 'north', 'south', etc. + */ + function addPinBtn (selector, pane) { + var $E = getBtn(selector, pane, "pin"); + if ($E) { + var s = state[pane]; + $E.click(function (evt) { + setPinState($(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) open( pane ); // change from sliding to open + else close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + setPinState ($E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + _c[pane].pins.push( selector ); // just save the selector string + } + }; + + /** + * syncPinBtns + * + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @callers open(), close() + * @params pane These are the params returned to callbacks by layout() + * @params doPin True means set the pin 'down', False means 'up' + */ + function syncPinBtns (pane, doPin) { + $.each(_c[pane].pins, function (i, selector) { + setPinState($(selector), pane, doPin); + }); + }; + + /** + * setPinState + * + * Change the class of the pin button to make it look 'up' or 'down' + * + * @callers addPinBtn(), syncPinBtns() + * @param Element $Pin The pin-span element in a jQuery wrapper + * @param Boolean doPin True = set the pin 'down', False = set it 'up' + * @param String pinClass The root classname for pins - will add '-up' or '-down' suffix + */ + function setPinState ($Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin == (updown=="down")) return; // already in correct state + var + pin = options[pane].buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? lang.Unpin : lang.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + }; + + + /* + * LAYOUT STATE MANAGEMENT + * + * @example .layout({ cookie: { name: "myLayout", keys: "west.isClosed,east.isClosed" } }) + * @example .layout({ cookie__name: "myLayout", cookie__keys: "west.isClosed,east.isClosed" }) + * @example myLayout.getState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.deleteCookie(); + * @example myLayout.loadCookie(); + * @example var hSaved = myLayout.state.cookie; + */ + + function isCookiesEnabled () { + // TODO: is the cookieEnabled property common enough to be useful??? + return (navigator.cookieEnabled != 0); + }; + + /* + * getCookie + * + * Read & return data from the cookie - as JSON + */ + function getCookie (opts) { + var + o = $.extend( {}, options.cookie, opts || {} ) + , name = o.name || options.name || "Layout" + , c = document.cookie + , cs = c ? c.split(';') : [] + , pair // loop var + ; + for (var i=0, n=cs.length; i < n; i++) { + pair = $.trim(cs[i]).split('='); // name=value pair + if (pair[0] == name) // found the layout cookie + // convert cookie string back to a hash + return decodeJSON( decodeURIComponent(pair[1]) ); + } + return ""; + }; + + /* + * saveCookie + * + * Get the current layout state and save it to a cookie + */ + function saveCookie (keys, opts) { + var + o = $.extend( {}, options.cookie, opts || {} ) + , name = o.name || options.name || "Layout" + , params = '' + , date = '' + , clear = false + ; + if (o.expires.toUTCString) + date = o.expires; + else if (typeof o.expires == 'number') { + date = new Date(); + if (o.expires > 0) + date.setDate(date.getDate() + o.expires); + else { + date.setYear(1970); + clear = true; + } + } + if (date) params += ';expires='+ date.toUTCString(); + if (o.path) params += ';path='+ o.path; + if (o.domain) params += ';domain='+ o.domain; + if (o.secure) params += ';secure'; + + if (clear) { + state.cookie = {}; // clear data + document.cookie = name +'='+ params; // expire the cookie + } + else { + state.cookie = getState(keys || o.keys); // read current panes-state + document.cookie = name +'='+ encodeURIComponent( encodeJSON(state.cookie) ) + params; // write cookie + } + + return $.extend({}, state.cookie); // return COPY of state.cookie + }; + + /* + * deleteCookie + * + * Remove the state cookie + */ + function deleteCookie () { + saveCookie('', { expires: -1 }); + }; + + /* + * loadCookie + * + * Get data from the cookie and USE IT to loadState + */ + function loadCookie (opts) { + var o = getCookie(opts); // READ the cookie + if (o) { + state.cookie = $.extend({}, o); // SET state.cookie + loadState(o); // LOAD the retrieved state + } + return o; + }; + + /* + * loadState + * + * Update layout options from the cookie, if one exists + */ + function loadState (opts) { + $.extend( true, options, opts ); // update layout options + }; + + /* + * getState + * + * Get the *current layout state* and return it as a hash + */ + function getState (keys) { + var + data = {} + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , pair, pane, key, val + ; + if (!keys) keys = options.cookie.keys; // if called by user + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0,n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if (_c.allPanes.indexOf(pane) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + return data; + }; + + /* + * encodeJSON + * + * Stringify a JSON hash so can save in a cookie or db-field + */ + function encodeJSON (JSON) { + return parse( JSON ); + function parse (h) { + var D=[], i=0, k, v, t; // k = key, v = value + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = '"'+ k +'":'+ v; + } + return "{"+ D.join(",") +"}"; + }; + }; + + /* + * decodeJSON + * + * Convert stringified JSON back to a hash object + */ + function decodeJSON (str) { + try { return window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + }; + + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $Container = $(this).eq(0); // FIRST matching Container element + if (!$Container.length) { + alert( lang.errContainerMissing ); + return null; + }; + // return Instance if layout has already been initialized + if ($Container.data("layoutContainer")) + return $.extend( {}, window[ $Container.data("layoutContainer") ] ); + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create the border layout NOW + _create(); + + // return object pointers to expose data & option Properties, and primary action Methods + var Instance = { + options: options // property - options hash + , state: state // property - dimensions hash + , container: $Container // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , open: open // method - ditto + , close: close // method - ditto + , hide: hide // method - ditto + , show: show // method - ditto + , resizeContent: sizeContent // method - ditto - DEPRICATED - "resize" is inconsistent + , sizeContent: sizeContent // method - pass a 'pane' + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + , resizeAll: resizeAll // method - no parameters + , destroy: destroy // method - no parameters + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , bindButton: bindButton // utility - pass element selector, 'action' and 'pane' (E, "toggle", "west") + , addToggleBtn: addToggleBtn // utility - pass element selector and 'pane' (E, "west") + , addOpenBtn: addOpenBtn // utility - ditto + , addCloseBtn: addCloseBtn // utility - ditto + , addPinBtn: addPinBtn // utility - ditto + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + , encodeJSON: encodeJSON // method - pass a JSON object + , decodeJSON: decodeJSON // method - pass a string of encoded JSON + , getState: getState // method - returns hash of current layout-state + , getCookie: getCookie // method - update options from cookie - returns hash of cookie data + , saveCookie: saveCookie // method - optionally pass keys-list and cookie-options (hash) + , deleteCookie: deleteCookie // method + , loadCookie: loadCookie // method - update options from cookie - returns hash of cookie data + , loadState: loadState // method - pass a hash of state to use to update options + , cssWidth: cssW // utility - pass element and target outerWidth + , cssHeight: cssH // utility - ditto + , isMouseOver: isMouseOver // utility - pass any element OR 'pane' - returns true or false + }; + + // create a global instance pointer + window[ sID ] = Instance; + + // return the Instance object + return Instance; + +} +})( jQuery ); \ No newline at end of file diff --git a/gulliver/js/json/core/json.js b/gulliver/js/json/core/json.js new file mode 100755 index 000000000..c99aab684 --- /dev/null +++ b/gulliver/js/json/core/json.js @@ -0,0 +1,148 @@ +/* PACKAGE : json.js 2007-03-21 + */ +if (!Object.prototype.toJSONString) { + Array.prototype.toJSONString = function () { + var a = ['['], + b, + i, + l = this.length, + v; + function p(s) { + if (b) { + a.push(','); + } + a.push(s); + b = true; + } + for (i = 0; i < l; i += 1) { + v = this[i]; + switch (typeof v) { + case 'undefined': + case 'function': + case 'unknown': + break; + case 'object': + if (v) { + if (typeof v.toJSONString === 'function') { + p(v.toJSONString()); + } + } else { + p("null"); + } + break; + default: + p(v.toJSONString()); + } + } + a.push(']'); + return a.join(''); + }; + Boolean.prototype.toJSONString = function () { + return String(this); + }; + Date.prototype.toJSONString = function () { + function f(n) { + return n < 10 ? '0' + n : n; + } + return '"' + this.getFullYear() + '-' + + f(this.getMonth() + 1) + '-' + + f(this.getDate()) + 'T' + + f(this.getHours()) + ':' + + f(this.getMinutes()) + ':' + + f(this.getSeconds()) + '"'; + }; + Number.prototype.toJSONString = function () { + return isFinite(this) ? String(this) : "null"; + }; + Object.prototype.toJSONString = function () { + var a = ['{'], + b, + k, + v; + function p(s) { + if (b) { + a.push(','); + } + a.push(k.toJSONString(), ':', s); + b = true; + } + for (k in this) { + if (this.hasOwnProperty(k)) { + v = this[k]; + switch (typeof v) { + case 'undefined': + case 'function': + case 'unknown': + break; + case 'object': + if (v) { + if (typeof v.toJSONString === 'function') { + p(v.toJSONString()); + } + } else { + p("null"); + } + break; + default: + p(v.toJSONString()); + } + } + } + a.push('}'); + return a.join(''); + }; + + (function (s) { + var m = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; + s.parseJSON = function (filter) { + try { + if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/. + test(this)) { + var j = eval('(' + this + ')'); + if (typeof filter === 'function') { + + function walk(k, v) { + if (v && typeof v === 'object') { + for (var i in v) { + if (v.hasOwnProperty(i)) { + v[i] = walk(i, v[i]); + } + } + } + return filter(k, v); + } + + j = walk('', j); + } + return j; + } + } catch (e) { + } + throw new SyntaxError("parseJSON"); + }; + + s.toJSONString = function () { + if (/["\\\x00-\x1f]/.test(this)) { + return '"' + this.replace(/([\x00-\x1f\\"])/g, function(a, b) { + var c = m[b]; + if (c) { + return c; + } + c = b.charCodeAt(); + return '\\u00' + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }) + '"'; + } + return '"' + this + '"'; + }; + })(String.prototype); +} diff --git a/gulliver/js/maborak/core/data/maborak.module.rss.feeds.json b/gulliver/js/maborak/core/data/maborak.module.rss.feeds.json new file mode 100644 index 000000000..651db6822 --- /dev/null +++ b/gulliver/js/maborak/core/data/maborak.module.rss.feeds.json @@ -0,0 +1 @@ +[{"url":"http:\/\/www.maborak.net\/feeds\/rss","title":"http:\/\/www.maborak.net\/feeds\/rss","proxy":true,"hash":"35c15980f21f450222f2d070dcbab670"},{"url":"http:\/\/www.maborak.net\/feeds\/rss","title":"http:\/\/www.maborak.net\/feeds\/rss","proxy":true,"hash":"35c15980f21f450222f2d070dcbab670"},{"url":"http:\/\/www.maborak.net\/feeds\/rss","title":"http:\/\/www.maborak.net\/feeds\/rss","proxy":true,"hash":"35c15980f21f450222f2d070dcbab670"}] \ No newline at end of file diff --git a/gulliver/js/maborak/core/images/app.slide/Play_on.png b/gulliver/js/maborak/core/images/app.slide/Play_on.png new file mode 100644 index 0000000000000000000000000000000000000000..30be4321cb23507bafa822e493aa1f1eaad00034 GIT binary patch literal 50850 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%0A2~ixmaJ>qN;#|0 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/back.png b/gulliver/js/maborak/core/images/app.slide/back.png new file mode 100755 index 0000000000000000000000000000000000000000..da375294a873e0652b8c9be8f2cf1f88f48dcf5a GIT binary patch literal 45603 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 La0_y*#jILoQEIeWi)P6y4zdi9>HyV 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/back_on.png b/gulliver/js/maborak/core/images/app.slide/back_on.png new file mode 100755 index 0000000000000000000000000000000000000000..74e143428d75171b78efe1b279834ac08b6cd7a7 GIT binary patch literal 49634 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 Z$abIAbr-^NZ2vnlXJ_SP$=kj!?q6SQeDMGP literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/back_on_dark.png b/gulliver/js/maborak/core/images/app.slide/back_on_dark.png new file mode 100755 index 0000000000000000000000000000000000000000..813c836c59a5b4903c2f5e56c4ab7bb897ad4d67 GIT binary patch literal 27786 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/background_bottom.gif b/gulliver/js/maborak/core/images/app.slide/background_bottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..642a1a9929a524508f8fd871a5ca3349d70b91ca GIT binary patch literal 2394 zcmd7Pi#yW`1Hkd0ncG5GV-)sb4M)xEvHhKhBkm6r?X|T&0M&vrRjxnN`m3z@+p2UgL|Ou|I#s`UOR|nc^)0sJm`_% ziNM}f3?k`zgdPtou)gABZEX$w^D@|i$|wMC0P=6z-%kLAeY|Q+Y~1ts1mcUtq~w&; zmude?&&bTm&dJToFCe`tECP#5O3TVCD#=yVHMMp14HRl4t*N<%-uk+Y(caPdhS}BK z)BCospT*{Ic>{wqz4sr6M?Q{@efm89W#a3%N&eLI%=g*3`Gv)$Wx8QR>uiPNnqvqB?Tl4Z*mIJHs z3Zv!6m)5Z5Zvzba>LfGvz%e&RCPbse1*wQ~i~!VOC9Xwo9c>VGUcrn_s$k z*wxPVEs_2s^1t78cKnnGXShXI-*oQ&l!}%oi{22FjSQfsd_0;p1UwU*#&_YBZ5H@= zEj=PXYEMRrQqrxTGa3)4wfeWo+Xr$)7AAO=`) zCe?9W>!PPkI`Q($%SY~)rJ|wN4fj)>H>IWN?oMX2nVw!Qzo=S5!P#uz@Wt62T)f#_ z?!D~$b9n(3Rde}%-9UFiXrGx0$%^t~h7>thHUIK~Jinsw@#yDyFz!g;LNU>pQ-0u# zFMpvl&B=VREYmA+u{_tWda;5OzO-1GXK27Amt_Z5SD~ZryQ*qimX^qHq_B$I(3Wpb zZk?-Mu5aI5S}s4MNM%xbj|2&*EaMtMBhO}8KpS$h_|Y_C;~G@g;$+cN{VDv*64d?o zCv|kPSJ2Aqg^HS$Ho0Hff=g#Kx>Ki}-N$E7aj1zV#n$!xr z45hl=-D=KAYL~&z4dH&TmaU_(PcK5S){jU?Zh*UG@<-UFm9^^}Bweu1wdzNTc&El5 zSo5^z^)B#W3xcp-7;A^tYpeNi<2~A>ZsP+o2el51`u&7>#Pixi@kej}I`OD)#E<4N zxU&8l)H~_nW)~W#zxi1yV^{nowEu);;?dX%G0e!}!evOb+Ib?&d_q z>aOIy?G$4lZj2Av+ghk>*xMG+SNDDj`%iW#&1CSPGVAjV`+GZ*)%|@y85HHZpHJ78 zk%OW^h$f3EZ!aXMC4*2CbQjD=7^B4lGrC(NKQzYF>Y|K_cO1M; z_}nVFSlJ)lqcbjyx8qGglfdr7>9v5P9YHk#-D{|`Mnq#vG;*YVox4OpDUSNo%)MI)ite``UrUYTl^$)5 zfc#R%Pmx2S4&Fi$zG|odNd-O4Msj9|M`)tL&ITp5cSW^9PjZTW+d zGKb+H!OvclH4^%kFnm@3~e)n`+R0ODyQ3{x$7@ZAJ@e28(=J-`e8rKtQMLu{G^WJBR z531IY0YlDEYScz4LZu3Q*ghtG6DMz`HRpJ(tsBzIFSkmm!un%|^T#(T>;|gbA~?f^ z+- z0Kryfim4$3D2oG6KGDpxsj&mKezx4tgHf9_@V_@<=kNgRGQv$A1R&>x{a)Wtz?HjV!1%Ab{@&Yd5M)xm`qI<%%es;UhDb&}M9p2&J}*ZI>F0jiY?E{dQ$l3&aIdz;qMzz2woA`?}oa0JxDeD2PkU# zxWg9P-HoCUjeux)Z*jZ_8?#*ykYoJQ9GogGw?|i2SAfJ>5%DUX_H#CjtpQN~gq(R_ zgPJ?OIdqU#C_#SGWqv5WpFsfsBg{*YA8v_uYbw!H@e*JVMO&H7aP2FL5P1mT@PDW1 BjdB10 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/background_bottom.png b/gulliver/js/maborak/core/images/app.slide/background_bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..063e18513f7394b30b8429fc9c004954761f4c02 GIT binary patch literal 2393 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/close.gif b/gulliver/js/maborak/core/images/app.slide/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..b6cfdf9a8b925e55ebaab8cf2d9a41caada6471a GIT binary patch literal 612 zcmZ?wbhEHb6l4%&c*Xz%WoN#pRyOax_uf4zzi7jGD|^RTm*3z1{D0Nq^KzQ{&CSi7 zH~vQ#*ROr@|I&y5cAowpzWq3S;kt;le9zAF{Sziu*VInB{lDSr{}XTjXXF)f@$%2U z_kZGr_d71#|Mutq=G*Vn($e&;>?bT;zhv9~w5I-so!6d!{!xD6Z+=1Hm7BM%g5%5D z`#ZXOw>|&A|JDB`5C0by7CJdOO}P3!tFGhi&;Kc9_4Q57S+(s&n=YNWb~n4YIGl)EW(q{19fSpU*fJK=7gF&0j9~o^fS&Nbx*ZZ3nN{S0<#jGfB zgdGmF3bz3_8+9?#B9RDqR4|3AR z)TFFl9oaAe?%Mw%lj}#d^Zs%2%la|x{Q0N`3XoV6DQzN?>xS@0s@47Ct27=UTq!CZ6QxIk@@%g0R6}V@?ayG z-tao*9tnbrpQzI7$Ayno^82q2RrejM>T`Wo**%=^+u*D&_75HK>8^mxJIk|s%uaV%pKM)q{I}q=lED2XriUBt z(yP6aN>--TE=#}Tv-g7ezN$6JmFtsk+Q$``#}>19=a}GyOQO%4MCQ^%Gt2^$sM`+B z_uDteRY7%@&EiNYY|*vx$L64Y8AO0@AcY1jC`cqyC{j}^D(-5mwRJ#ing;!kcGm~F z2k><$%r+oAf{9?CEgS(Rp(8>p45ce2G78s4DMJKNC;^3` z;bN&X4T2yVBo;c;w%PeGd}MBDgxD({M+4)1`GWW;fuoS-!lQDP96*+!1Oh1~(NZ}_ z=}eo9$pLeX8>T^%5F*N%=Bh~s1^f6zZWxY2wsfYAfWfwfZ0+eR2bQCQy)_hw5YT2s z3b7m@7J~sUEDqZN9H5v1}M-c+U`4|?>(=OjrjH3z+kCH=ffo!gZ`3`6%>kJ=t zM+lUs(ZhzxuwmHpHLBQg81^A=@wK4$=suWGEQ))VZpUXZIN)G0rs!{hrs!N)Bg9+6 zOscL~(|i8^5=h12z-*}+Eu_@%%CyNs9Q>;F+ zGMc~6VjVTTI^EFe)js{3()_H{>se2VDqu-$;^Mk_6oL&RP%?enA0-&n?z$URM7UpI2B= zz4+Xg4G*pJs4LW`Qno)*6=&>EsY^T+UK%FQZFSFNAFJlx=E!aA4=jrBPv~B`;4bHO z>9@$Wzt=8MW$-dhM5a5L!FKvr@vy3f3b*#lVuPJ_Ve{w2RSz1YBeJxClb7eN_8TzU zg`|ced*gUdc7As<@=|iN?Bk*xpSSr9{kc+ic9LtE4u1H-{tmT;wZTT2k?YZgSX^Aw zi)XhsSQ~KnxZxdTFO7%7U-X;gjoB`~C2%!+-IMpl(P!o6^n0EMdwc5AS6OE!#4II$ zFU$XGmy@Z}uk^2-jgMbyDOub3vLwyQRT%NKx+(UIea#NrWqO$1xzZ|LXGo~xz|%iI qlcx%sQ!Gb+I+ED8l-VCTKDV8IV#zOOY?DCODBd2v?gg86CH?~jRg((< literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/next_dark.png b/gulliver/js/maborak/core/images/app.slide/next_dark.png new file mode 100755 index 0000000000000000000000000000000000000000..31549d6731794de5a92c9a98f92e4bb594b99ee7 GIT binary patch literal 25623 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/next_on.png b/gulliver/js/maborak/core/images/app.slide/next_on.png new file mode 100755 index 0000000000000000000000000000000000000000..b6ceba57ab4f1cfa7a0617648af5a25c215d2513 GIT binary patch literal 45934 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/pause.png b/gulliver/js/maborak/core/images/app.slide/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..52cfe882b10950c47861d23a37070eb43717be16 GIT binary patch literal 2301 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 C)VWpw literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/pause_on_dark.png b/gulliver/js/maborak/core/images/app.slide/pause_on_dark.png new file mode 100755 index 0000000000000000000000000000000000000000..611cbd63d7f97a732f3eb3ceccdb68d6bf469e70 GIT binary patch literal 26246 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 Wc3g7G{b_%#PdzQ8$K{$1@BRmRU-^>& literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/play_dark.png b/gulliver/js/maborak/core/images/app.slide/play_dark.png new file mode 100755 index 0000000000000000000000000000000000000000..f68fede5ad6e55ee4a4bd12f5632f0be0f5f2346 GIT binary patch literal 27941 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

    a% z(JU&mS%iVJ6CI+WqGnB-c&wyuB_t%oxz2Kq_;U33_nW=CP|eXhK0UR;qUQmkit_Sv zx693Xv4(wr|Ei`lh`Y?z=|8+(QB@UgF1#sll2`Qj6g_{vi!~q~6@u53>`U#dXn4NzUab;T`Nk{S)#k-cHcsVS z{l*k+J}WnIL;rRu`M)&XUiWdn6TbpZmZgQSTeo|qAKHn_peMTHnl2IfkKyn)3x0&! bB@zWsPf@_49naXmz4jMsuT;yFt;7EZAifP( literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/app.slide/play_on_dark.png b/gulliver/js/maborak/core/images/app.slide/play_on_dark.png new file mode 100755 index 0000000000000000000000000000000000000000..472c71f3603415352c789d9582380c5f6ec4ef01 GIT binary patch literal 28737 zcmcG!Wmp`~x-W_(xP(A};6Z}BJHegc?(Xg|KoZ>DAvnR^Ex~p0!QI_;n7QP?)?WMU z^WokP=bn11yQt zuA(w(NUzBc$t>)(jqD_??fS}x|M!BWE2AcRCE~hCXt{~Gm>auUJ35f5S=*b#u(B|- za4@rQ_d4(X)lc=8L)Fp3&C}S$97e&|)Wy->+|1gTOw!uL+|$v;)|E^_i;Rthg(K9X z0{Chc>#u;8f;^w8qdk+cnWKq0lb5{{jDWD0ld-9-xf_{@xuvy(AUPQs89AA?nIO3) zrvi(DlbE@cwX~0mxvGz%nyHViDX$s1un>xX7vHO}y}6q)nU}qtgDanxAo)K!`CjXP z$;{+r|FF2(3X*^MYm7`w;VYS#ql-Bi2NNr!DGNIX83z{=8#fy-Hx~n$s<9iHtg!#KaUS<|HW;Qm)R}My3ZwEJHFGdGfihn8jFFoSsuBI;5PX7S>SFf>&qr00RIr(2h z|4IKIoUzk?3^};|8@yK-nZ1mim|2-vnE#{sRZ!rS$oJ3GIl8DhI@$^SYxw^?En=$d z0)Hj{2h)FB{cm}5abq`gp}%-Ava&F;aH#!7g_DnkOXq)){}Xl|vYJR-0Rw|D>*S)L>6LY==WB-}fe*Ft@URU1sppMDIXN%- zEAX9Zza%sePC{koYf@OB)J`037*57~1TGS65Y6X6s|G5O@GXiwAp$iH@;UMF_(&W> zSg43HwtSLaKSIl!%Js3ewfa!c$yKq%^|KRG2giW!^JfbSOON}r$Zkx8Jd7hBA0N0N z5jipzulLm;5T3HL`!+5t9iT*HfBHZqGo*V zp1M3tgRvL%GcjKDz27C?SdKi;6{@})z?@n&$a%sE@+d=@~XVlbF#i~x!SZvNa}iC+-q!CRQJeP&mvvo zqPhW#<>Af$$j}vA<`?A$Aboh0X3x$Ec+sc!KxjTeg{*wM5!QBd$)7rK%+Tk}Yi}sO z4AP9g4NAQCsMIol3V@y+lohPwylqy%L}F{ zvs|4XY4cXQ`5zPNvp>dm`f8l7I~f^HxsCuNoZ!V{?-(}afic%M!jg!`#n$-^} zW8T>kzD`6;57sU%fQv%T+65IN0sLl7}FX?J?0V`S)z zKE}uhcwKCed`{^S@ElAv+-)#Gy*3nRxU_4!^>V^{`!!VXCxV^#%VNsbW;YUf$q>2j zN&KQZIoFFuTvWFo9nlW8jjUM2lVg|`JMk`Rt*Bt8f=g;xY~qXFK| zCxMNZP9!_0u#oyAlGnAh>j2`j@XCVQMac|@JpitgT`Hk~gv?rA5rvF0e={F0D?e6I zSvQdxp0YCKf^ycRT{lyvWWZ{d7`VppHr9bL&f8n>7bZ?cY z)qm*)%gZs~TO-p9UP>{lZ70{jHbb&Wc=K1B!E6YZuq}3`z8`*C|9W7Aot2H@g!%PY zWLqOb^R_SVD)j)e@UT41@FB)aq=~!pdZy21Qw@y$5Uvl!-rjnxg_X`hs7j|B8djk4 z*~raJn4le37DmCRJ{YajfcJv#c9aQv&_us;y@zCYGvruG(W!gZ=gplBk*EcRO&(jB z38iH}?{iCD1~sMM)5W1yf|}t2c2XT%J4i6w3fqf`2iZhHTIytfsEtxTLN*GIPIrpb+L=)|nw*xHNP{pFQG<{laqka<`Vn5aq45ZT6Xptf zvbGv&B(F>xic>d2s%y<)lgQkx&uxbTFGKGNm6sXkEF=~n^~sdBU~bvb`g#`Yt+@p59r=dcGP z&0f*5^530Bsm376=uBYV{a72<3#i#Z>5>0d2sV6Wx#-HC(7hzFjFaWl8`B=%gKsDZ za5QI|ly69a8b9FS;OPNOR)6+0tI+MF@)}j~5v#WLw7^uMzSBb@Rl9+tg^OMl|Q}3C7X%-_fQyub9i%xr|_0 z31rOTZ&VF`;Xl4435 zOOQ3^?Foax^U}y+9Z-{)y{?v}?QKORpVmeouk|;t*Z)zXEo9GwfuW zdaiIaeOB^hO4(j;o-TRb?69iTX1`9d`Q|B9rbahRtY21M*f$}ETV1P2v^rp+|$pfj2uLBph& zDxNGGa0U3ZWEy5(TY|586O{p{Uf18LOCB4K$4h+c!5OtiJ!#e%ah@I_#-WX#4q#RvQhhx|Up zEpo2~4s>wkh%FVxSN08TE|}5Ru-ewjynjpR8az)4J2=q9cZ}}JBY+i3y>;=1C?~KN zd(1MCG%v|ZC^P(c=gn7Fik43hE5r>`*o~@7l#o^WKr94ew85i9b(SwIdDgAvlTkW9 ze_1clad0X`I%v!wi2}=moVY$-C4KDH_|!>FM*Lnin=l;aCLYEO!D#PiNU#6QGRYhG>}bVO6|G39aoqDj zT*JDK$rX!R<2^X#-s`%x_l}OnUmQuWWWF3f|vkAH{d1hTdBcak-C;JAdgMpz>di0a;LEZ zuHF=*DwxA?=g8J}bUk`2^de#;?j;NBaC1#G)V)km8#LkSs8o~)z=$&1dsq`MG28*V zE!|~OJ48dxC?Rb87nmeZ?Z}wwUuj&d6)vf)<=32dHV*7+1g`_AvV9u) zoanxqdf0Nurz?6kx+q`}D$FA3b4moj8IpvRMix}I8=0@8Ovf^cP*|twQSF%YnafAdihw_MQEU))sJ=Cc+$ zxA0+1CWVGDIcwqRtT(f%PUB`szmD{H&uW77R?;Q^N1LOc*?(RP3G|)<;qhHyh8-%u z=08@&l=n_;%Z5}U|9C48Al?eK)kgZ+2q&W1Qf*}G0utJJ=L09E6nKD)!)x&%m1RpW zYt=80X;tiqxF^V);jGQh3OLM<+iBoZU_I4~c={L;!d_EE23+pZ_&%)Dlkoq&_ zANSG@lgd~#CvaDj`Ml2MyqK-O4KzMSa+x-T4dWPF;+mfmc;Nc%+cf2uc@2F>V$y}J z+INF*hKbpAIiiATq;0|Ic09@!z*-S5@e-eL$>`oQ2-BDet?9UyMs-H!$<|_R&u$CS z>yd$9+5^>28tdeLpqFw|2Z^=B^Xvvr6#r?$%Ehw!9B45vvYt9`qN`QFX-q}fhOD8h zI{gQRSyaGGn6ZVuBA77Ra}e&7RVp(nsb+bzfG|8T=`L`usR>`G$|&rNtL#wH>jMQ1 zqu1Q~pPy4CD}IG3T;Qv~H^Pa{mf4aw*?)#xpq#XKHksXu^{LwpzzIU1wO4Ubvmwzb z-&|#u&;*OHSduS&Art_)FjfBKk`|v=O>{7ADJft!!^0wP=vW(WZaDUnTbgdQo3Z4^ zZ`V3)O&f4=Cm1atBoFg!%sCqVT_zTnd8*!-tk~K$J!$Y^**<+L<*EpM$zfCs(VSt0 zR0i3stW&k4&I7L*tvEG?ck#BLbS5#P)yM^5o{ItxEA|&liNVKiCVXA!+YnLl;y*T~ zqxzo2CGZU^l%-?F#Q6tCLbH-P7Z9x#((7jq?+@kAV|Zy#S>mX@f$|`D#j;Zt#sM(< zAJ^M7P4D`-Hl-lT%x#1}vk|u3`&J3%}kMwWy&Uf(N0;64?jmY=~w6lTrQ@E zoIepNL1ups>4o+l{F?pfZlqYP!8oqdSU9xI*RB{bEG5`r9KIM@#ijp9bJxc*-&&`= z|4>ykN3l>v_|U}-9Ng2gj@Vc&Hi)^3V(hZ zQf~rQM6KGHx8|3R?8Gs3%R71(P27*f*iaqm+3oTUJH*}g!!4wwXSS-B1Nn$?^6ML6 zQ7kl!&V&yo5(l1Ib;ejI26fRVXfVDq*pIqbtElWyRoEi?sCg~Bn`JvvTkQKrb#|3t ztg!BZb2~hW+HVAyhk;6q`c7?zTW?|}h0?!tS4viRa5OJFYl;kHgu1HmXJ~7bc%NvH z@drJp;#Ao2p}1nlwVrMh5||lZ7wT3lS=INW!)mmwv~cfcDb9JgwjSeIYUDT9#8`p& zR*ir1t$LsGRK}WG9UI7WPR~tc161nVn%}Og_lk3LlO1)9juVVeJHSEZ4l%p()1P=@ zn46F)=NB`VH@YG|eqTaYJ6P3x*WC7oC)Jv<8PhV7OA-4UCOs15yD0YZ4!_4hT+^-F z!XBfuTLxo)BT%S-c45nnx%GRvVZEZ;t$psg`J?h2=^+)uneC~U_M?~ z$&jV!U_R49+UuXZ9P~9N$vflxZ2 zBv=%?2)_=9`YlV=%Ea^GIp3{L{qZ5|EZ%S6N7lTn3uc_=dsu6OwVnqwDh|llRX-zy zkSk8RExr5Igle;^ipO;RTf7n%AKE zQ3h9W#?OzZt&K!eX>;$*NfeyNelmqDFRYI|GulJ)Pa)k5@}I=l#nG)A(T}A>=kX-b zB@{kpe7n|&;42*FYv;Mt?GNt}^I0MJ>c28vnmEim>9jj!ofcC$eb8=Yc2H?len+P! z-_zGOE3z5!d9k<#)IS4`ryVgRx)os4 z-{?e6CFVA+`O-X>o~7600xLiTSm#rv=Tl6AK87*kXdU_H`nPr0vR|8|`E}!)41l~H z`&nK4^B*HS5SfMv0#rAOqWhmLCv*g^6;DRA){FGp8X79eea^L8C3x{rJ^EkjsqR6? zOsSr!%lGqqot&R2*nSb^PDoT#wgfcoKzurPuh*`g*K|sn2YyJ?UDEgzb^MF|;bINt zY3*oQ*Dzvj2^&$_5W8DFI+0ldIxFZr|Ip{-|M98|?YZk@IyE=4i)ea247JrOd(@QM zai?_Vyb7d*d|py`Uc&U!K$Xo;L=V2@Zxb^pKEUu!uQSLk>Hto60q4`_06!I67XMUe ztO@J71az*AcsZK;J63MnDUFcTH(Z{}9oJ-dG?CkP=8Sp+cV+uYq&Y{T7Vwod1xoO} zYA3&zM&|(L zEiqMhSHeqK9-f!uN;SrMzS}bAq{HZ`So9xRlYM95_I6Ajy#CY7-p&&Pu;;Yl!rfc?5XWF zTJ;x(LOD|y`;Wrqs}<=5TiV^b8L7M|lVCilyYi!*QU}7l(tCj8B$*#F;t83ovkXUP z&dK(hMCkN%4u?`E?6F0HyIadN>|t!E_nTnam|@B~`mm-6!p-9OSB4xn@(ZsoDwf~2S~pwtU@UmBmm~=X?+O6VLHb) z{%$V2#+=k4b#oOW=zwZoh}#+gjV$|*fv zWPU*bWY8BmB;&&~br(d_$bz|h)p9xvy{{0LZ~)c)~{g6P{ zrj7TV2wfV*jSCW=7pCTtaZRD3;dC<@MBZQDk9%Hj#PgHuf@}=p&00O`WP&;Hm@29I zm@qtbNxVUx(M1u%AU@K% z^}$%gTt0b+%EjLSjM*cMmr;=N9EYI-{TzlSW!x4QfO?ggOu9V8$$)9aP?Zv=32;L; zjQfFSA`Y7CPS73YEpR2HZOmt~EZRdg&FDrVZg`VMmCp*Ay_1Mei)Vr&2x1XJhoxGF zo@r-sDY)=ZqgVHq@M4eQ;PmH(lHUQv^pi;nz!0D~P>h%rc&EHv;zef30M19}@VtiTU0<+;_atJ8>NIK4CbybxT$6 zA7I88IJ(9f{B`o)_r@pYjJGYP;CzInGpEEi=j{IAA1`fkx=sas1eIQuolhNmx9uPL z$)j1H*-XYeI z6l29tIzyEq?>6vNOm0#MSMOr()WZPa`#$&36jqIn70*TDw~h@-9-qduqYON2p$C5| z&l#bUqk3>-0#ykQ0fkzwez7$qB87pi03E3%o3m=cnG(MfRC8ZpoYNHJ<4S<*HqX)^ zP~kaW8!9?jCSSdrd;cTFSPjqqx5D8fh0iK|?s~1z@?={xhcCHi_fy!ZlI~2_?p+Cq zC)lY{sgt$mxevcr&zZvEW<--&81GpZGxzS)w02rKHvG+uAQ_#-hTclP$nnLBT?cL>1s~Z>7 z0!Ha}f2=S+t}j{}DVtAiU1|n+%Z%!Dx8Zc&sz2Hsck4_)qCITRX;5q@}zL8UC+&(j}mZbq~6uwM(!n?(Mung z*YLC2{#4%*@ll+@l+-}~-o}R-A1^XSfTb;LbzgWv+Br9w=4o~+ET+3Itz@_`GhpbR z=~uuG=FV3H%bnsKCxkDRZnITc4=PdKf2fqvV5ZpSAp zSXDbi`N4RTgqI+l_bO4;RD``J6;${1h7Zk*KF|Fj4V&~>?K@a_4NNK#Mk#lbdjhdZ z@7#vY6o#PDG;AMjauDyN3&ojf-;0;$FMcy`Wk(UU!s)wuO zah1@OdmKR-TfP$oNNn3A>U~Wi8ctBRpe76*Sfk%eG#I<5o@{s-KAgLq>D32+8?Xek zF`sK!jh=6jUcXI$pi1GUz5c=rT`OH-j#xaAELubN7^Q4qJWpOFAw>MKVfeeg?_o!G zdR#8TwqxaD%#%_UQlddfbPi>-EwDLuoq~?nv|P96|w%goeFdZTGQw@a$L9|WQ+?Nkbu(+)gUN)*_x(Xi16n`e{spZ*ew_9 zH%L|Jf9Nh;eSnIE?~ROH7Mp@ullyci}mKOKYx70xV*&a zYaMqDQmSDKV4a7rNY51y0&U{cr^)Lb)euQk7A5+&Jf5J!DL2BgQl^w|oFU0I0GYdy ze3Fh_10VUK)XOZDdfa=M9~sRTB}Lw;=jbf_M`5V`L~+@hL4L6o1A1D~7_5?twQiEn zpY@i6gW7*gVWS>|4-FBx?*v^ITt;Ys9i@aJ{zU+=>a4vg-(@m`@*JX|$vxr$;i_-- zXn19K6y8W%FR7Eb=WOuTER5c@dozyld|r5^nEpc4Qbv->hQ2~X-pWoboB*-R#&qW5 zZ>qHu%>|eNI{BE6bezjcTz-{FOX?I|+8NKq4dhgEe~MSFR}yMU`vM!_K-~H!NLlnQ zTVY8jcA~-qbp8sgX zvzHg^`b12l{20C^g6Agr^!X%F{p#3la?b4lNPlJ6Bw#-^m+$T{lwS$zMLb%Ke#XO$ zlIc8KMQ%@+IvdK`QV^KNneNzRz7ek-^?b>hJa?e`Q?eOA?W81K&FT>J4DrVKo;#ou zW%58w?l;)L7k%s(e0M&X)umr-mlQzyyv@Os3cuRNIAl1&0SDG(Vf6<)uKJtZ$t06N!8VC&j8JrTI9a?|8g}*~h zHMhFkpZOjGDM*uW*|5%O-s1anIF~Q(Pq#RILtjdyb3Js4p21k<5mQY2+{}m zRjfeNY5Ak)B=mL0ot zJ?o5j&`Zn9Y7pUcx@YzNUWGu^fdz-$u35FQ8*2ek@S1qvrw0SrhN}k$E;$xOB-$3A zqN8zY4vU0{(|%mVB|in47p8&t!j@2e@F~)2U;T`)OSY)~wNMd&C$(HMGa|9Fs(;le zDA2Aq3O{F%0ba+pYJfp->BVBkr%vJJXqupaTG9Q`xs1tQy|K@^F@BjP^Q1(b^8x>f zh9S-8RA`AjcL#kx7CqNQm*LU$ATjCe(Ekekbb7bl=tA&QcN}TAg6j%uT}64POZAFW z+mw(t!+q}|7U|RPl4O@$jj_vSDXuuVCYIYFuoZ$nTkc7gfj*`uCb0T?#WHBS{xK~; z77m;qOI^2rHl+hp+VwTq85+hj`C=)jT3nF$u#^?66uR%VNH}Be;Rdk(T{3fRTl(8g zJXXF$;55)MXUiP$$&<7W5( zyaX)ZF<*F?DcSbKV_Wy-Yi%PT%{H0y#Qas4DE6=eTXE3>lK{;G1)y9vfRo;~Y67l$ zDS_~h!}8iWxVarHoTJo&%rYs-KS$8C67~R{IGlzVJIM`X!G0C(NoXWh4bs-%mxL;B z819!Fhva5P5`z-ov@W99Hd>$+CUK4?@HDr{O+6{a|C*m^R;9+=r6zT{JeCXfD^A!m z8*ZPMm*9?cP2sr1Ekx+Fm73whJ@Pdnwl=^FXS>4tCO_?qtIZZoox9i=)zB$#o^tFH~( zw4Z{-e=+A_K9Ng_#1(#^%}Fe79V>|@g2^X}4noaMi2^VO`n^w`l%bPu0T3inl?r_E z(Vv(22+JhbDJ#StPG?_(Eqq^?ge2(|?nhAaOa7W|<9A(-hsxAEO$6*`Z4wtH?Rp;P zQKc$mBw5Cb(>_M2EW9Ax&mU-wwZHX>SS-?O5K*cegIOlz1S7{5m}kiOJ+RXe)C@kJ zUle8!-7QZ3sC%;>F_S>OLQ^X{epSIk%X$rm&!}RN)@QM$Hl6R{=B23j5z~O++1yr4 zcx2Si0Y+)WPXh)iC8K`}#litYWhd><1fR4nrzyE60{2H8u-wl@meDEuh(f6U93461TM=dhnw-7FmLZn_tUzTkIqYz&@VHMy?Do zd4KyINTY1RFe1D5_9{wN|C`d6qIu;$wnd@k$cj4u6v9^X$O;x0*~N-+8fmHaH3jdGI%XfqBF&Hu2q@$2+Ed>ctLac#7)cg&c^MFmD6tftkkR>$p~GvF zEcE0U-nAd5b!nT}Tjrb~vNupD#lXxo*aI`a!+QAvh`+xLyCc(yNt`it!2h;5y2qdR zx|=&?ZkcK*>6RXJn)W-9Vyq@MrH~i8ymP(}VluD z;`G1Rb5YViIf-srggzWPd4!~5brVetO$q@d8+o(FC!d6P1plBRmI&POkXIx47px!1 zS`zOo4XS0ANU4El4wc7Tw{{P$5Se|qOUQcCNJ)7$K^Lf}CT%<5KM(!0Oiskx*Bf{( zu5E#}ot_<$pqXqjI)^Lx4>2Et`wC2loZJNRr}sjEJvTxt-Utrkp3e(y^|X$>+RwS) zavvhLV5%qK|NJP>Z;Q%#htwW=aDI{(wR(O5S=*eNyM?%Y>n@c#7}&Xi0jOtD&*5S( zu`pzpFfNhbV%s12%H*w(2R`FTf1yTRZAD&zh9XU$Ony7%UD?HO6<_|NvZ*6TiFeg_ z8L)fJ+6wHj{xeK)7I%j3`Lo_`<971^nVd_2?~egK$?sDup{&y>G4^jhVQaX0AwO=M z9*FflVuNAMs?bYzO3(+z0G~jXUSp0EBI}}7{GJyfC3;VXQFtzWyO*QbDoLglAKZHW z$1b|qxeZ6tL;rvrVaW|P3KE#w$hp`b5=Jz+>Go|dJ1fB?MoF=De#X=*tf+~wa1ng7 zV-0v={7L}6MT58m$$oA({o&8nOSycD&~^Bn2hV+hJa~@?>k1FbRl2*Oe$4|<*rqSx zpJsj8er#TwNt$tI5pR`;e8$F~;-bW3CNkOVX%Jg)c(e^A;<_MSM*rxj6gD$0y*)VI5Wx2s>su! z-A+853ct}3(ces?GaysK$a-|WJM&W#vDF93imjfv!qQq@e&?c0+>{|t5+1^n z88EV9wP!*>`oNUIdx@AGD(!})&Q@R)9fcmbJ+O8 zPp~wOfa?}aWn+S2=S21sR7#hExe=UadR+!1Q$Kmf`e8JLcBI)@@q<20^nDs?XX&@Z zFJ~sNn_>e59|T7cg0NenF3Vu3+EZ*sC?w&b$5OGp=V*h%o)LLF?21eLkaWjw3q=M=lwTie0LMb?Oe0 z1wusRs-SXGhBGOgn|D22^n*n$d(tDbh)12)Xo7{1vD!q|-QFq}#L!dMU4eXV^ImTDBQj6$sH4;inlSV#i`^HXf!$d$tI%jwrjZ}@aRoeg8KCmkzd~W zAWGJ2qq2sR50rdimMk1KvPu^r8&^@0c(u{hWcRthB`^AEh30d4M6HntB6mN%E%pzx zqTn<=ta=t8$IjredAtQf8e5Mb61;Y1++x>yX>a(*yA_R%oFx(cHG zoJ1|eAA-f1XOPT8PJ=V5YNoP$+k|B9{`ueQcYHRZZf5Oinqo@boFMKDx`6?zq2m!bg+G} zve+a;N9l#@dzjSqph&l%n`EJQQ>-h$%k#QSov~{(r=xm?2f`)xq^e97+2`=HC&&L* zgCl9w`^ES5!~7V3y5vyX%xoMnaWTQZIq|xbWZTl)rluycL^M}yhVWpdTtp~% z3pp>w9zKM)&m9w=ECqRxEvs6;?Im6wr%1VzHAd!jp4(AwZ1cwuW-6nK@mdCV z+E17ay85%oZHz}XRFQo6g`V)sAi4UaX}@M`btzl5MHKsRS^5xndW&IM^+l8}9*X7C zQ%JMO%Y1_hTouuSic^Vp8Uf;04OxasMG{kjzp1Boqv7f zVJY?)zwR9uUd@PCtKw;eT6fzvf>moEtkW7?Fhr#?of_u zi$2(-u;*qWJ~lfk zdeL2mlJAVF%|zwu1*c7zTNS%$4XgKgiOKU~_S}F2yP`w6cP zPS;}Jwy8*YERU0-x)oi?FR%VB>kR%?x;Xu-oItYo3^;HrQdF|%4tUiwp8U6MSERV| zw{2FWjr9+G&ixv()s~ZM+(%bAtbNVjG)htD_;h-T*LIvyjL)*NHArT^g0ormFspHI zk14x;e%ZQMb>63a&22!(5iv(m>-ZF5_R*#@I~>)mah^#gyJ~*9_E-I!PrH=NBg$ZXMCO0U_2nU zYaPb+n!T~$AtrfuU8}A2Z5tuD>ck{#Y=2$&qoIBPP|0RuUrxyzAnEAqgAQ$my*%Po zYI@4Dbj6a#xs)hEg8XSC-S8YkHLb)*X2RiG&yA_7x_1`*opru#0++MwAHjeKvINt` zaL))2vBKdlkSZHL7o0!TaX~_r5Wn_84tyC7%p}{96)pI^(xCyW!;1_x=Qnk)=T6&S zkD|UF8`W1FMfuM1ZtU0kloAWAkk9M`%4hp2=|*nGHys~PS{a_t6=v@ygUmy+v(42K zwP|#_VEVtfz{AE6u1Yur24l^O68>cEZ8|{nI(zCTHcOUEC#I3I{!&~JT=C1o^1kwh zlKBXIM}#MRXmmXOtJw|`)5PnE z+5pYA|D)ry{}z5dNt+!Vzs!RssVYq%^NE%+x-bqWK~hE9AuiMN`V3WiSi72d*^51A z?kKbn>3u#-+|#2geu(jZvX@L(02H!(J{U_1C2prykMT|2TztIP>~-v}HtdF!-7j@n zzG(86q4hoobpW^SE>a+^?M*Rrj?@8FQkv+#LICi>{G2T03~CqfbaMz=cU4CiW%fwB|X5N5u|00{UI#C59# zWo%7Ci{oW85#CpW4B@1MAa-~+wi8ss&DcwDyM%WqJBDmm57h@dK-L}6fJU@<*TxU` z+B<`s8$w-tAwn=Crh=>|i^I?gh|;6yIog5ujzK^YUqk@x?rhAMsectc3*kF0W!xzS}W9OLh+A2rDY81kR=FuaG#@*jKcJC0e(-W}g)>nE($9|wpu9l|r6 zl+&hfIywi4rGUE=h5grsL9r^CvsO$(q7Lb0LHnD(n(Cfpf(3-SE%gNN0zaB| zlQ#KZ)+=;HqIP}==mqy$T3XH=fj8!n4=@IQ?7yx-7)1?^uWb!2g~zUbR!a(J71WoL zL6cWO9xQ%-3o(;~3ju?7sw|Y<1y!J3p4j=L}dxhZ5Z%(-0f(;K5 znt6qx#N}VdR;oEy+x1R$JGZ_4))wLLd-reqqIt4sfvXR>mM}Zd-J>J5^1eI5|KP%c zwvTVPVawjtvmYYVkg)v#mrJ<3GJyBsvqMlm`~YY8JsUiT_W;&Yg>0kx2~^QSP5gpl z`$zVQc?3)}VG8;ETuuVZ=GR#q%@QdDicf?@s~cSZ|sU>9IF z03j|DHnsk-y{Is=do&IB{khpjjy^MM*D-+H{OU=7X?rBcDD(G`0S&v)*cI^Zz#S#` zcd^|vJy-kFx<|uVra*cK=v{AhD0-JIw?35FZpM^Q*XTuQ>F#mT!M_uvA)Ab8z9WDX+Pj{%b5)(cHA+&BdyPc$oQNHKXs+W#w(rO z`*__)`L=#u82t1cY~Jd_1o;JSf5`^V;LY}vPgPHy76#m)x302+aptdgeqTyif}p3q z^wY8M%?SY@61!(l0oWHof2q~ZlO@T4(l~=BTGHF>pr#Wa8Dgg$sqSPjYW23<2~5R& z)`ai4@8a;f`OrD)bB0uMKs+nk;ox#*HPE@bB;DHG-U2T*QK*}#dk(VdUr{xFe3exN z$T2?ouNkY!&~3;=c){q*oFcqle<|2~B!D$K255@P45fHkU)-yN zF7CApHO(wa+Crn2$(xPe*p4R~Rf8%wmB7 ztldv*%zlS`P6FQQ`d@fCnu9<-{cb;j%Y4kGXnpFX`&!*Z72xq$ z0x2+Py;nz5;#Q(L^y8<0R0SSN-GDj#gcmGMNgJS(_f2%dgDx?t_nH788_=;|5t6c) zJM#KAP=)Y9K>)KD>bbr(4;Xj-EyTfkN=&3e(*ep`&} z@kujo8&6V96t&P+f|kfuN(aV-a>cXq3xP?&#**_*O!k$hS2*g4$vtgi_wiYa;fS1H za%{ZE1RmMi3hRE%oI(fJJ6k04TysXY!OZg~&c|Hd)N5j4IfEF9wn9KS?-j6C`MkDD zy9y-P%9C;&fQ6|jybIvx6OuDAb=cZ%Q-Y+Ml_u!lHHs`;2;2HHV1{^|H{eqk8=zHVWf)ydW0Retf1o&n$%18g+Sz7yF4|t zpzd0};))M*M_j*-YsIF*B0K%cQap;8{Jd|FfbUP|6af*1pWWFfF+_u3nmW3b|%B<3+H)&S1ZuaG5di`rTGci-mhIN>-Xl$Z&q+=FZN!3)hVcEriVb1#)9vx@J}@`HZ;S7~ zY=6tOr~=0P;r=&N`S39U!tMu!yzI`DDE-sT=J$BDyAEXP@_)YLKd<37e{=IJB{}=t zkdvIFblVNbH3g}|&znU@<#|TSP=X-)ny0~ELa0y*Z|K*d+S$WT)TO!+VvrhXnI&WH zr9TMrH1?qa9H3z_4?PUX?g$!#966S%YIvRy`Dpl0F>QTko)jtt1PN%kc(jQKjeHWm z|Dc}z@)!pkUH=F@XT@vjha3nzQQV&G6hV?-{E4@Enid2hlDcHCLj;6W+$b+aieBd_ zrZZhMGtr;Mw;GrSn9c5Yg5@3Qb@log?@EYm+s}8<&F(Y+A zfKoyUy#j_MQTDQAp}xyeD8hlJNM3fGxv{o=G)2S$z*nR&z|zzb9VPRJAB~R zsoD5iN<{{DC%SvC;Ft4SSCI|EB_J-+$&$J~!vmQL$V&P3a|F8CxZ<;WwXCPU%>C9# z>4B)FT|@)f_M}$--rAHVw?m0kV8}i>vJP!zwKhqnp53r4(w3xIX;qA;;ogi$5=BmL zgndki%42%ARX!fq!_(p};t4uj&9mzc_ndcdUbiGp9QZ9y+|s;I$kqY-g}aIypmyz8 z@P39(JS$?V(++eyaHrA+L~^)E)_IvhQv+>QLNmT6fAF^;Rx_eln-j6MOPaJHy}o%0 zsFVp&_6d|JW&8DV*^=I2On3O{M`d4@tVqhf zH8vk%3$H<264U-sudq1c$}}Kp<*FzFgr;w#y6d}VgEe;_Q=tz3+cwX2wZA>ddlhoU zJIhkK)Q~%9PMEqOGM#!i)>q`&I#il)X2Zz_7_;QN$;4(BGf&>os9X7^W3K5Lm|^{ z$TF@^-jg>%Z7S?nVS23 z)jqTQxP@qhq46T0P7NK#kHzgI7m=Dlc7t6T@! z(~vd)v+YGMS}a&b>&-GGIBM%yD%0~WwQSy(7F)1fHUe>Pem?vxN&_$dG`zb!N>`cc zP5hrDAyjGOp;NR7S?}C=`m1LeIS86&@RAg(WN1?D6=fXpkjK63$hqBJ<2~EZ zk%ClBV=Q)Nl0uU}Ti5YaE438__)bG23s?d-LpH7f8#Tr)ybniiXNw%#eF^;jx!re7 z(0GZoJE>)fNy*}laZVJo&@SAUf}#t;k9H$lO;3JFr${^G2j~gQ+H{jbRhn;4{dDJE zMk+?{^fj)WGB!B@VN%Y=_+DT2uw+@(zr#_oaeNa%N(l0evW~WJzY*r(j6O`0*4v>Z z)c2n7RQ(>SXyiC3JFJshO=8pN9H5CwMa!;Q0#)vhn0WvY1G|66qFNLcuX6fi1llQE zs($dzU_?K6ifFE^ znPahI1TSB@Y>e?Q0#}}P;%)a8kKx^mE^p`P_1ld2tjNDVmc{O4xXQL!wi;^LGeWg@ zXz{Fl+RVAQ)@Ut!@2EwrmJkL;rmc#Vd8n{Cx zrgA@ER@3LAW_Xk#?%+7IyUdmRZqAO971)=Qe}}OS(krS7&fSl+-fko=$d8jq%=zk? z3k_=rVM4QLZhw-xpNx_lnA23BqX}+5KfvS#bTm$HK;q4+hql ztnE)Sc*4N)w_(}4bzeAD0lJXU>Ypp@Z4@g?KrfXM4;omN3?09@@niMNKx#As1Gm** zW8Oaz2L8x{V0)WS3C|s_M#`+j`yI9k&6^9mAU^{J3wB44@dMOjg|$Dz>Yf%iAi!Iw z5g;+KAv;a&%%3yOCB41w$cp+jbE@&zRhFP3%%WGy!gllS_2hAV!&DdJDD@`4++Z#C6WMJ8CQRUXEI5J;g$ zZSNJ08)anpwxVHKIQN5}jr_8FCwDRmg#vpeJvHm7w`8M6zz!en2Thxvj^@h;fc2YL zlZ${_zndc0J};g)Nh z9Z-i-Vu9mbT490zhh~;FUXphcHqoz6TkX5h1P2!$&f*`miB~U zC}K_RUOg2Tt*h41Hv%a06_Sb^qlVCaYho&K@a_4)FR)xfz;Igo5X@dni#F&o7R@i! zc1%XBU5+wpO~9`#;pL8KE%IdQKNl67@RHJy2t5J2t0h2@&HMF9`2~*FNP@KD zpz*49Sz9WjeP;V-<6)N{-Sr$6;Jx(@t5tCm;GbP@uZUePJhU(*CY6oG0d(EdcGB8m(^_+9g zur5R!lqa#|#EQ5SzS6_P(&9`9F`c;#u(=3uSmi#8(C32y=x;2|o>a)EnX;w8a`-ak z{)DTNRkZ67q3LZwMcIKFBl0j}Xux->E z8i5l}2&#&}nrui4=x?rV&UBVWM?Oa;j3}1DvVE1iy{LTtBx@Xe1n9OFe6-uB3kM=j zP`15oNcDI^LN(3trS^ZK=6_Cd|Kf=~!t#a4u^G}~YG({Lt^BAB);o^!yx{0(bQJzt zE5z^TZnUD46_CcRQ2;losayd<9x-w&J3*zNhpxrVnSmO;^ z9DGPTMxm;|9)WyX-%uz(mOomDzd0~s&@a(H=LUI^_y%3Ia*XlZS7UVzS~)E!pB$c< zi~ag1I+t-ax83_)bPVwWwt6zE?#ZV&yAmn_4=nho(68lwQa^013y80Vjy|*2z z`*U~KG#gI|lsF=^VeK|R6%retg7Yk%H6nnANkb90AL5EMf6QA)P4veEXac^rGlZA6 zKWUlY-G=fVMN_CFDk_Rm>0@+?ubV2LY4vY_zSNM>~~NdqPgy#ybk$?%Iy^ z;LxJ|8m@eRN;Xz+SCG(Y$E@na1nUcqkky*Y$fX;RYYQQ91JrG0Mj!e2Je%33_9zqU zd{L_nK?RaI6ucH;k0^?Oj0cJ4Q&Riqkcy+-_MscRso2u_g)rcF!Qq11Y^K(1coJRe zU-voRihF%S1KW7%iB7`*E5!Y#^xqWX=DhPk%W<8y|3CI<-fAlyJ8QgrG*j(zoWpWH z_~T0T;Dc**D5;`!v&WMEz9>infj~v0y&or_;%h`QjYt=_0OppE1z+Vg94?4PBoc#S z2180jET?2F+d<*ss?&6Dr?TRZMk0}9ABU7jXcy8vNr)v{ww9Jw%q&9?qfa4J>O*K} zNWx_5G0#Zbvz(A26<9417V=bJT>HDViPnJpY_sNBZOfE8#)q*347~LbO(z=XgPLjm(D7@g^1GxlY5VM;919 zKCZ&p?A++J7%(9yQY;q5Di2XVgxzV-y~m=WQztJuu86q)rAX{*CQTh{Ck$u#ZEc+R z#_m+VI6`A`58I-Y`IC80v~nogy&n%PGp-M+m+f9m`Bp(rk=^$>sw;R3lHFW20N2eB z+;FB-@#KiezI}}em!U1CEthQH6ZOr?*#TNnjcGemh7Tz+l5lrNoYFyJ_8cn?Tfane z*XR*HxHjz2eqD2$T=^f8DlpHS-53tub(KAtN=IMGta=eGINa_{B>Vx?9fj9vm#hBC z>3=yKkvvX|_7Q{Q^igC(@2lmxhdA$>gR0y50=c>3aIL+Ekm7 zl#g}qp}c&jS8-O` zN*0sp>_BU{O1R1uDG)MLH&AO?JcGMD(?H|Cmp4X9rRlqB=|@wwyJ-TTBkIS{mAp0q z@UbGT--bKJtBshK8F}hB!lLBxUW2g%;$Wa^OpBWU(+C66Ds#6?|?Y)ERnsw&`fLAHx5aLH>tT+CNdh@ZVli)&GhnW`ezD)WLZS z42uTa5gs$E zjl|HRUFRaO$lbYm3UP?A0jIz#i6Tfs89@g+2_)s|PC|r{-v664BH>?#*#Eb3tfPJI zq`c8=_Ldt1!-c^AVsF_Py#dDmw?_WIYti@N?J8j9jT136CGm>_?>~I#x|W(+o!Zye zH~mQb;(MX~Tq>)-uMf|sYycis*Fq3+d%7R2mQNjWtQGjM)dIBzufEk|>^az|xYx*3 z#b3xqR2>c@A{ogwh?rI%NDA zJEznOX|H?p@oBfNdAC@I+z7MSDhtb-UO7;LOQbhQ54zL_LJsr|HO{@?Qi-_O@!F{8 z;A&8+P)2N^Nfi~=#5@r~ZCv$!-I)Lp?GYE>sGu)(jV$8OlTSllu3gc!j(d&kA||A3K3)FdgwH+0?6?Y+h{yZ3vwcCpuA85Q zMCYQo)m&N3aPlhN=M5Q->bGC`%-v^GHi%_uEY>}>_7h+_22*ckFInDf33M?km0ng{ zZ0dfJd=4kE6(!AW@TFC)wcXoZ z+-?sz>+#5PH5iKxy;P50E;kc!oOeIPa3-zSCY{+EXn<)c`V(+BBl%(ua5)DIoIg};Lku<)l2=@4h*s_%$+E> zMF|ZYOZZ#LG7T9YSlr@$^_?rDvA8Zql)ZnCiJU1#KM!=f*Uc)>=VSXX6NHW7n+xfV zj~r=fk|`a!p}^&3*}dOaE*e$62>N>QA`OEt?h})o*V+WHc zv;UcB&n}7LTNCu^AIm0f@0=*|Bjb8;aXve_sTx#XdCVMrPqrfNqh3lC>z8qM@ocH{ zF?3aEj?0X;-Q%2#Wj+kWR8`0jX(bGD`W8FS) zo^WbPqyIW+q(kI*Rp0u^CpaYrViiKs=BC(m`fg2(1_O3!3uadRe7OZG!>&y3+8Vv2 zzelpQx}`w(tt{_4+YBcqx2K;Z@9=4Mas1tseh%j z#A~lFw>uh6GoPPlIF!+i@(;OaC4Avz`sonu=;Z&iu{Nsc=2&OZqRbKR*x3a7f$+k8qr}z%I6wXpsqKX3(<7 zf5K)xcWqSBIj5tgqf(#OzDSkNf8?v#styH_e~*TGRW+LO?l! z!|)be7ghM4;j)W!=uw}|)eB$jhk8rd%riPfqJzguFNicG9!wTiL^ZU`THIJDy%?gTscP* z$IIK+FgUg3jQ^XwJ69TYl;o-BXjvV0;RJoAGqsF@6{VWmmdW=b`FPn9nfcbeZ=2ew@OqpC+9w-QCW-I&&@IMfnF(Xows$u~8AV zaO+mkwOgvhOZAUpWu|d9!3*w7QP;Jj6KA*&Z*2fSC#aGKZ zsCW1PVbFOIo!1of6rw{iddK$O@Q{wnS3pI@J3l5lRx`U27IS9oiH2oTR!_)3g}=G8 zPpd@64qJSA_)nd2)~h|f9OZwt*e`Vlx+&*~6bgzrnc4AIyF+Deb6fl-3gFhg*AJ?7 zPn&MD90$c9{I=ElGtWx33GdSS7T>z)Wf}=;w_&n!gX=_F`&1F*AgX%%Fxyp%(i-^ z614$^({$7tUE%1N->GPseA&yQw6A2sv{b}3%JR^#LM@uWqN6+He{LkGdy{SoOKT+< zcVo@S(`lA3Y=7x=#x`5C0{wPK{tY)m5zj;KL*v%Cv{-J=KLw!aPilHj- zL2SD90{8sZpKa}?Jy)%xi{gPYV}T|A`Zk#;P@Qnf0v%Q_pu9_W`J*W{Wca`l(!$S7S?&+rfNvMh- z9XBogPh}iYizD=Q2CD*tUX zMb0YO4<|28a_T=h;$dM3$^pH30FAo(@|1af-`|T~F^7YJR{ia8+Lqb0EvI@|cN4VQ zeqc-VC}%d-xC6#BE8;!y@t0%En8n++h_m!5mHEz;fEXz(8Mw#5TDi|miV3c(v8KMV z)vSH6@?>~ytsQpw_T@7_^HCR%Q%Xsp=^lBAt~;7UuIsQ33) zJo&9F(MO%*`7t-?3Lj8b3N1z$Gh{dg_~WXBWR znb+$qpCWpEN&;cSa4w>|?l+3{qyz94B%~z&5rNVnow_M^tDDRTvYx+R&*dm`RS7$D z{mV(_3nMM|AEub6APTi%Ra8`4)bKUf_%Ys`!N2E_{ps&&h8sd0=rUuM)r(9=8hkAf zr{`Ck51DYrb(pcSD@-;){)c^_LdI!%HxFNXQ(>>9x0kQa!o2BOb4zckrsJ4#S5YA9 zB$i{kLS`#sX8lI=Ktzlic<)ADV%N7A!&95Hx9--Q8F>9O`$5-3gIA{avtn4$bOzQ^ zg(E|Kn7}3u2X1#8TiG)jH4%Z|L z_Dho3&Q4rQeup;ef(gMUcKGjyV$meg`~;bneGe%Q4RI~UPw{7RJFa1im6&P;u&h5v z+OZx+yl#x|6~D`ERr_84reODI3*Js^`C6zIc*LesxOO1?nYQm2zfx5qufbxp+9~5| zynOj>d^%ILIbLYMfbNA@stZr|@PWTD%+0VfkpKWOxt|)PGVLP0F~bZ$e{J<>=O`xc z;mL?j-I{GKm}w=dCm$>|2MRn~&dBS4jeMQf;0u&4gDm-bAWWMhM8Q)41nsij-)Cui(5Er0gBnX;Du?tQQW;kOUO@Y5p5iSbhm%vh7l-4gej_(P#v3t$+w9tx{<7mm za$SX0#Lt-Btdx;iB$W$_kn?6VmPF(OmaoQ!FH-0rw4{La<7g(Y48%=+LzSupaYO}h z{&82rFiuR~4AB60$*l-+vF_1*AZIlRwW{(Wzf+Fv{u5nD0e;OFPQYA`u4)FjFrrz2 zVo}*Gz2vz`HxuU7ox0QGZis%X9}x$xXL`NR6cO%P;I28!vXuQ!0){E`$#KcH^oJ2T zSl=)C6DAl1oShfXwF zXyNf0j;o_PUri74CXh%tX%<#n(MWAm!YegE3-Jh-)l!Ea{d@OuH$3_!mS9YZ-@cow z%>kDD{MbP`>sOjM89bswHVPrz;rNrEZweBnYY#T611bPD!JtG z9?)sPyM5P^RT~)Pd46AnG$ky>+MyEwnzf!#L8%{lX)oG64MYZ!xr`BKhi(L)?bV_?Lna~aM$5-9?xsM}gnYX2`QLi^sUJGT7`SZ{+?jIrc zIL|+N{dZ+@r(L3ihhq$p`p2bvXOE7cOItminDketY2XhXHWQ%QY+BpW`O7ht5ZxpO z(wHnpwnj6I?r|KKnrooN005pohP*96IV-Vh^jQBbetqJ(0QiN5davgBM_=tmUmQnJ zHwR2BewUBdnYgQjf~+*oWlr9+IzRV%{rTJhnf8N(R%v|Ry=puUVoi%#!(ZLa-2@|p z-mJ!mzhp9dJvgfEqd1;&xmjHrP0hHgFq!W#28f_{f8}Rfvbu0{H3!veY--1yN^1P3 z-HL6G&qJKktW>!eRGetQfRsDjVZAGlz-0mTiy8M~7wflnSsZiv2AkOy`mfvzBA%HA+dWca9tE z$^#wQQ5G_D?eo#w9qoh2zp>v>!x@Gc%{%VMF+Pm%{IV$L&qm~uV<7XW#0t17FL}{R zV9P?Nt|_zWr3>8y`tH%u`FMPYLblOWk(3RypB4k#Izo!Xv<}53p1tDB$M&5v-sc(g z+9A0bix@#Y%426VI%cRg5?)} zeK?FAc0=!AFu^lBN3$LcrnfVthK7d3L+l|vAC47`<}e=lGMx=odaRo`62)FdM&|KX zlP?9qVP$~gu$P{mlCY|(J;n(fH^wP{=gn^=Hlk<;Di&N&PyoS%wm9Z~jac??Jd1k)v=Qx%>+A7W(w#pz3|NA6{1|p)3k?lbGW_%!iY~9LR6gHG=Hp^! z%pIn`iSmz{V0&aNDh?2bQi^ClHDA*Qh&5#+dl(xV=ZYJApSa5o3mIJYcjP~_?5~n^ z@`dUZvZTG1AsLr>Lfp-|pglD?iHAuK{@UL5dLY)8&wNkkl5XBpi6%QJ*Sm+*_p0OM zGvr(acxGhlCfd0pws&>Q?2_)=-c@$Oq3^&34zti=y%*7DPrpgUTW8kmI^59YAS9qq z{g#1QC2H6D;ydPMhslRiCIWBnDP(tT;3VHY{DzeKF#e&;bN0R*zY(9q45LRMsJL6m|MCe zJ$U}rWNCl3S4cZ1&+ayo>wVFLXU&YXL#1^A1Ol}EP(jz}cUel3ZsAW#OV3r?e2CHl zSSp@p`YqSDfqQuE!c&OW@LYpmfQk_7D-&YtB5z8ssikGd5aB(euk0%zgG|!5#)qcj zpC3;~#jp4ayzg!d+rQ@Q?EDuOeo6PI8mn#H!)tLjlWr!h{K_*`j}7hLHh9nD6RDQp zBljT(G<6W*fDGyB?G4ARvuDZz^eio{tgND#vzw6)=@nY+y2&}u;J{PNCRgI!bL>D=L-5@Sf|8GyaL410s^D{T-pFOgI9fJz~m zxs+MnE&I~nZ!nUl`nxG;gI`2soqm+m^17dGzByye&TQQ{X~oE;KI$J}8v!bFROhe?Q(p)ia=V-V){@flI z%<*l^!(MJOnAn#pX4mK+=dUt^M$;jW z8|QZ1e0`zIOB{*ufS8kn<>ePx6dcjj)m4v1L}?jI^NR7lw~V5rpGv^W!_#5BuwUtT z66N%hiS2{I(4`vbpygkuqqIbUyNj*?0Rg?ZhBVZ!Y&t9{tFD#*<2DBK=l$vY=W|w9 ze*gacAtgo3;38cGx}2(;+ifrDs;R5v1Fg=&7*yH1=-TzIsHnSvuFU3ll=McI{r$K9 zNSy}d0_OC$N}vDt6$K7Lw~*4f!9 z4!G59&Rcd?QlgAk%+yePG3Csla;k~+^l&*{v9>7oHW<)b1=EX z^I12oY6m2~+;mGFV^nEwX~|FI5LT0ummib+`25njgiS0q#!p_e-obDp;;aV$`R$zI zw$6D=e?}QGF|jAj(1s_*#vt>}qoYtgJ-u&PQ(JRl53MnjRA{j=G5w?RL(t~8I6-suDtl};ozS?=|ahR-Xblzxw$iN5a?@J znG|w<-Y(DXGAz7~F{XFtS9iBAl1y%u$u>Gi=W`U5+_Vw_LD1*5F1k4A5Q-&`(#SJ& v34%-TO7>ZH;p6uDu7+_SUg9;4kHUEUJ@Qe?K_L0xR*Zq}(}&Rej<5a)h-{;v literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/arrowB.gif b/gulliver/js/maborak/core/images/arrowB.gif new file mode 100755 index 0000000000000000000000000000000000000000..df4833955daf3c2ce6ae2ab53694d63261683a73 GIT binary patch literal 13123 zcmeI3SC|u37=~vN#a%?Pcby$9sGCelcEgNGR?NDvXb{;5h;?@6Bs(UV8E0lqc5SGj zqBOf$u=m~zD%gAP1r>Y8uGqqvO-L3l;Q24O`{&7%oSb?8Q{MC4o-rNmqhz(7sb{7! z43nN;DwP^bL#HGsux+ZR(%)!n(N?uA@z^esG0YgZY~dn~HS`!axj88$?F8vI#`Za+ zvu}J#>&t4g&b7uHqD7^cxAVkP*C#?vEx*el_IPp2=q%*LJ|65D-RcMpslE*rN=TeKpuP;PR-UwUBi%coTn>m* zN)nW?q%_Nw@&Qn#Jj(kb28ijm?(b=}{$I0~{i>~n`NAkqG5~@x zU8oCW00d*YP#4Gm2*z}wE|38bjOjvMAOj#6(}lV~20$>T3w41EfM84)>H--6!I&=8 z1u_7FF$Xx=n}h5wCu+pzW?sqZ@&KO%P&6v?9-*6eEiXp4?lSSy?5Vv`>i+Mc>T3kUwQeZ z7hib(xo4kw`l%J-&iynRC;e`)9_`v=5-Fwg7cinl%?YG@}%gs04c*FJAU3<;d zS6z9<-+#1oD`uCKRP zIJU=gonvgv%;&O48{L^S(X}r1s3VU!{IEl(9x`R}q=QqP6Azkj;P~VL`;Y4wJEncV zw#2@p_i2sCqKqPsinKI`Ly{=)!9deqd+srE_uY2gWdzsA?!42EJ8Zw*w%csI)s|aq zzS*Y3H`#dDMnfCwHypCT`h(XSRL3xl%LmsDVd|JBdOL<*lBs8yLBnRv?OnWN>4KRZ LlV-RhnY~v4M2bn? literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/failed.png b/gulliver/js/maborak/core/images/failed.png new file mode 100644 index 0000000000000000000000000000000000000000..9f9ea214069b3babde23df888e3f5b788c8be59a GIT binary patch literal 886 zcmV-+1Bv{JP)Q@^KztbD zgFXrF!6yeI_~e_=7vGA?Hn*~Zblo3XWlnK5xvep2{x!C_$<4j@`{UbIJ@E?I{NfQ;h)NfwUm52c3tsS#ql)sk*5X9?fC z3#Q%NlY3&lhG)`QqLkXj!p04A$If?RyY^|q=|FZo01AW=H2<9Snh)k4OV|Boul4k| z|M75UD~&`ZdOrIiqiyH|)pZ!D0Z=0d(RSci1$fI<@L~@2U#A`~+wD(|6`n1ynRGUy zI6t2l|7ctv7@@|{+ejYXkKph|xJ<&#ZiYFQfmg0Uv^{8W;$E>VdUbu8I>H}SJ;_7S zt=kz3YDj#z8_$0J5qCa6j(@IPgI%sbi$&3MWE^^5AB^m1K#v9vj1l!7EqiXl9~|iC zl`?|;Z$U7M>a9tPj_ts$c2p%`_@9o=IICl{%)*=KUupcd;wYFlskfMuLBuA}LhiKH$TwH{RL=pY^ zE6DT^@;}`}>HH=1Dh;x`8?90S2J!Gxa<3+Zpf9CZwU(ZjrDMaMoyBUg2szk?=lAbp z?eh2N)x$8(o<=>NhdcKGkr+qb@vC*t8*D5TY!{nr?++Q~sPQmQmaIHzW-~%Vn-Dti zG5Cp3u?7zN>U9h}oQIWY$;p!Y!@TQF5CHfx9ve^U#>ByB?*>|LqqAiM{+0|>vKv}$ z1?Jo%WR~)cV@cPzDoe$WTJ~n;8c=n-|aDtc*+lwAZG{%D0FbJD2Em9 zsL67t_SdR^VcKp_c9g3Ax9uY_GZ3QWFjM5zyQcQRV2BxUM$uscg|>8lZ+KHHTu%Jq zIQMKRD*z-}|B}5CgC;23$bs!0DH9T)1b_m(66f(%V+kJylPlhP)wjU=%)0iy@$WOtIT$?hz(Q?f0B zQhLyfh#-g;dn<@|>9x>+e}#9?TD*F3Hc6ATh@Lv^{Q7wBec!wp_SIVX?zDJK6a-8)fjKjV)jeEpYm591%e=+M15lEbMie8#@TX>RY-$% z5XHixP3jn|I23mXZ3XuaZOG?Sl;Z0|ChvLdkxoYjSth6mHWJNPHIN8MvfzWMxfe~h;o~FUqQ5Z^~2Vt#@ z)UT&jS_3&kF-Xd4!cz1kNY2YzN=v8aZ-EM8;2!dTmI9ih@If>56#sZJy(VQvKAY5T z80-0!K~BEQNSloL285kXNABn{p-rf!(`l$^P}33|kqEXuhQfpw-0X{->f~`?QO9Qv z@j#@D>ST*$Bq>TXY=grgf0)P%2Ig@aVTgRF$_gARbE3(EMvh{{2(1#*&YrstkgMos z#5@BUWgYQx9x+kc~{3{4%-$3O$R2_qxM zjOn=^o#|Zse}>uC&@X?BwtLrNTM)Ogi#--_&(yP?*_P2D)I}`oxTuMt?=?+03jVXc ze%1V0@Mj5!@A9WPUzX+bNg?@D}pe4Rdk*l!>3$EC@h!r JUzRp@{{ShsJqZ8+ literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/fbc.png b/gulliver/js/maborak/core/images/fbc.png new file mode 100755 index 0000000000000000000000000000000000000000..76fdcffacf8f45ea298300a9b6792d1196c40d9e GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^96-#^!3HF6a`hPlDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#1}l@efPCNQn;t+RYfl%)5Q)plfBygfU(aUK(Amf! zA;c9i&#tyBoKcyXxmh4iSVBUg&RO(P$cO0@IHzbP980%9BVHj2w0u9;&8*IMO+aH9 NJYD@<);T3K0RSQOGWh@i literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/fbl.blue.png b/gulliver/js/maborak/core/images/fbl.blue.png new file mode 100755 index 0000000000000000000000000000000000000000..6dd9228cd668f78f5de6356f5afe8720f0d84ce0 GIT binary patch literal 1343 zcmcIkO=uHA7+r0RX=p7~DOM224OWG0Hrb>}vm_~P(%Ptrr3n~&%4B!ahGc)(otkZ_ zh+08w6+I|Y1bYz_#7i&gMT)JU2eCKBv*1zjphcn1CTaSE=&8f({CvFkzHiJ(-BYJS^#o_Oz( z;6B`&#z`fIOHe~px2R+h=*w%Uq-X{G^xVM&(P=R;>G&yLP$VZbAx=Y5sbH6(LZN^# z$fDuA9HIdLG{}n~`bvi45=vVyb+?y znmk#XVU`AE2rh)^NTxoPaXm{D5=0$iVR) zKk1~Ha-+jGG6yv=#}7vPsyWFnM2}#s@+?~_m7FDyQ_+T5cOVd8T^!4C3_&pZn2e#p z$hy5EvZ@nBx}fD%oL6LE>cXrtibFJQCaSgS;hffPRo3lvu{C8v43Z!p z(GbLnmQs{rc++)&NYWEDnHxZBS=aa|3NZ?selTt~!?{zOiznUf8(PP&fHu+NikQ!h z{hi+7tC_ zr#f#4_n-e-yr839mZ9zKGc)1ej#%kVCOr0Ir^LWaCSy#fQ&xt_=E%Aee|g_rH+J*Q zgXQVB;$-@f++g4P>Z7Oh@@J%QGUMITI@1sf`OZIMmRDA~>g;yA@A@rf{>svU=})^Y z7Ry8{tUoq$abdasU3Yr22wp6HXnb90nL6C*pcmS$F2_7{XE)7O>#1}l>|uXcd8<3pg(Ax{^_5R22vJ4#<)tB+zf3jg5`1 z&AFZL?}JB=qK=+Fe_l~XC+FOuLr$UI5(_2H!rYA}nF z`)tb+x!HDirv3TEn{Py1kg7Op00i_>zopr0EO*% AlmGw# literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/fbr.blue.png b/gulliver/js/maborak/core/images/fbr.blue.png new file mode 100755 index 0000000000000000000000000000000000000000..2dcc39d873686539fa55544acfed3fd7e24e0daa GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDVAa<&kznEsNqQI0P;BtJR*x3 z7`Q%wFr(8NlNmrki4xa{lHmNblJdl&R0hYC{G?O`x6Go{^8BLgV*kzZen4{sL24p= zeXNr6bM+EIO7tpn3m9zdD+&^mvr|hHl2X$%^K6wA6cm&cGE;1o!cBb*d<&dYGcrA@ zic*8C{6dnevXd=Slkzt6Dft8V=m8nq_l75IHH0{3mDVb@N*t8p285%&fBPoJvx6ua$1X93& zLmlKNG;u-!mXZt)uY%H|9B{OxBzopr0Kye literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/fbr.png b/gulliver/js/maborak/core/images/fbr.png new file mode 100755 index 0000000000000000000000000000000000000000..2e542cca8d23260fc6625ac6907c94aa611e738c GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#1}l@efcb8>!c9P-GoCJvAr`0iPVwbyG7xCpFXgvj zyXu=g4fg6ESaNP`DB(9;7rC>6dxNH9ZQd%wB`aKBd#lae^741utz~YLI99A$HRB^Y zYkNd?xuat2^@-1avayClPSZ{hTQhlCW?$wkJ;u6wom<0P1J_JeiQHjr9vFMwe&wF` zzk_dY`>k_&TcM0R!_ET?pZRURnAjb^+G_JSIi6*Xy+JyQ5la@wgeBzy@;-9L_hlM- z3|$VSGBM1*$ndQq;QO5&%CnVx&ve>M-S;}BB=^l`Q@wpxPdnwGyeixFEHgeC=r0CO LS3j3^P6{XE)7O>#IuElTi%$HnB^3+|jK4fx977}|8Q(Js{9^1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z76M_$OLy!300kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!ywE43U_c{OA9FduE9hr1aOgeV# z*o`X&1_vc}h!}vt9LwTo_KF8uqOHYVvrSZDuwvH>cp}_A9cToDr>mdKI;Vst0OX54 AZ~y=R literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/ftlL.png b/gulliver/js/maborak/core/images/ftlL.png new file mode 100755 index 0000000000000000000000000000000000000000..14b43f8c749408a9c048000cf6b4a34d885f3f47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#IuElDyYcUtF5*C;b)GJcAr`0iPT0tM$UwmLzkQ-+ zuQpo(TSNov9%kVUj;~De5}4UGsZNpI(`@hE>#W-Z z*4_KPx%gc}uL48n?XvknyZRrmh;H7VAknrwjEOgTe~DWM4fHw1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z`T)X=PHRkN00kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!6M843U_cY*YN~Og)>{XE)7O>#IuElThZXzmI8_D))^DCJjv*F;jIUWmelY@-fG|bi zKM>$E0Av9(J_SHId52@3&B(4~z&w3}gvAx+!RUWP?CbFg`XKCdPnl z5y%&Wf(zMT7#n05%s^x|NFD_KGXeq3B9JBcf(vF4SSLs`9{dlg2&4uSLU4-+SpwCE z;cA#=AcH{|<`@tSE`SZaoTeeKDs;W8)6KiT}gnm|0JsKD_|92qs7i`s~@W6F|O!Co>?2>fqmdKI;Vst0Lvns AXaE2J literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/grid.png b/gulliver/js/maborak/core/images/grid.png new file mode 100644 index 0000000000000000000000000000000000000000..ea2f7e31b6cfe81b817344163552577447c1a085 GIT binary patch literal 25591 zcmdqIbx<5#^Dhn|gb*M^a8C#!1c%_3Kmx&oI|O%kT_SjJw*`W`yM+*37I#>Dk!5jN z|M5KESL)V%>sR&G{pZ%58aeYh-92;q^z?L3??!x5kt2CP^8g12heZD4dvzR~JGwYH zxE%NI-6D(!2BB_27LO0Q9vaS8 z9^R&ImN?3$=5Ef8mKL_AOtQ9amfp^8_U=r|x=egLJa59hDnPdk6n`c_h3H z2ca`z1wpD)8Pqu0uU^`;mfUo3BuX|8s8Wkp5D4GI#L zs|>}$=KZ^&IFVFr`8&X)2_|FnMrnnw$)`K|z6KJ7A<@0n zlo3BYPcFMwuQIy)Ny6iahKN$o^Nd38^+OcC`({_G4-HgN@%Zqj)|0uKi6p4W1#!sq??F^T)0`2xmyji06n{KE8kV z&X>1Lk8TgO@^L|p0@byP)6ox1oSX3O=zpe_;LBb6}ug!A#(|LbswOD zN=A9tT5lSLN>-83KZ1h`p1J7XyyPT}3*eDrPLx|-oN zRDZ@lXphM}H1CeypbRdTG@;cq!o)b{YrYLdo)0kUR|$6}}PGm~>bja6V-#OSeM??}?JSyF|EjbawL~#|Ln8cMUioJ~TEBpB_FD-r8m6x}0 zj=1!zscYn5I90&_zbLfqU_6)c-^$z}_{S_irswvpOo`YoH_tu;P=+0yRHWM>@Gm=rXi?u&rke2`g&2uaF zeMkwYv*V5f+sK_7hq|a+_w>=xURoBhHjKG#-@V=bj~2E9{yZEUhEI<6ni{tb&B(xg zSvIBL>SY8AI5B;+x1+?)-mbi9n6Rp2H1kztLVugf{nsfPRc>FHKD(PKGORu!rIhjl z{E~DyVq9=n5qg_DiGv&d+>$_6k0f{U?Uq<^w7@oI6$I~Nq@EJ;=^fv-5eVYC3?YyT-vOw*yjAv)Zfbr=*TlPR$syc)~mpUM2nHM~*% z8!TQhy@_e^RB)B~TLMGY%(F>7v(Hb+emfY2F7m~zIfwu7GZ`b|53@M9YKHv>1xt~?w4-;11f^7hHzYD_eUzrj~_rzp3* zYnuP;%LL3@H)d=~xZqm2fZnVuV$~h?p^0vN*NPU)egwBuWmuqXzrR4-oRvIN9$C`Ad}UB@gBD zr9+DMj|vXMs-=U7vR>isN<6gUJ;zy=Bkm8?yF2h{S>K9~Y(VHuLFDKAjs=fGV}(Nv zf+xiusB}jBCSk;^%`#$l;Xvva8xIBb=Q2aZ@Tv~` zo?%3(UvS`Yd*-`WepdEoUq3wciVAuBIZ~OMY#n#K%%7oG2`YEaTW&@(f+UPQww8e$ z?67h3{ou@gH^9RYn!QU7<9yyXjefxC7sb>&{v7O1Y4D~is^A;Bi+$UUD?fZMtT(fP zSJ1gonbomHMVR8bZHxWmgaylh7c!iSHUushhzM6;6z+l*PQofp{`&euqZH&uGA_mjJBn}H;Ufo9}~}dlFB(vYt8VMuDtz zO~Zg^TBr?t@NvP==_9Kb52ac|5|lrCWor{0 z_KackAW1Br+$I0iAvS;2+$J&MiC1QYC-dXDDcF-R%Dxj@Vi}KSHRaUb8Vd}FKsS(_q69%0OZD#a{4u3 zEgC-LH0n+9{*h3l?9O)X$Rmp@O+#nqVnaIHS5=XHMWgp+;PJ{P4#P5pmc*+=;ZFuN z+toVMMWe(X6oKg6&k}!U_o$5;exk-BN{sIf9|+FWupUMx)n2OdkkRpxpG9+)9|)@u z+N8@rI_y<=KiLxyC%b(T5Sw#cdp_eEl8@9+G+(lKK|^!Tq7BBU&KYXEuxs)J2zQhm z$_(iblopTT5Lz#q`zR_R$J0>YC^_OZ7U}#l|4%sWhD~t*!r?~x`avpP)@#X!7F)xN z)ITyT`KV~+4?GljtYykl$}~CI&a^G({4YuJdj!r*ZS1bN_Rl@p%zJc8+d* z+BymjCC+#u)5ezJ$HzsrH0kH&2l3;CoKz7h0;bviiY>iRf0yO-z*sT#BN;J=?r(AI z>7M$;(=J>eNR3`m|77Mj{T{lc)87tq{PR7}p+Xu4a8n|oE^<n=cxY& zIf3b3GrxH+4_Ov(G?WTQtS|-@8E`!@icOHQeYN`FTlCoT>4C^UX+H|6)4x9sH`(;2 zh>G9ij0kHOX@l|!SAtyb$k~LA=9-*6PHfsWKN1!rdj$5NLCu+n!CTwqN-*uVW65HylM%b=Bj@b=R ztUX(@euGa`0b}u=a8&5GwWW(z`7UPaQ4flC4fsGo6{!a?3$_80b#1BN#6QpB;*4s` zwL}d5Y7z7?m*v^n|E`?MR<@unDF3=?0-%P&HpWtj2>2!^N!%5Tr@r}wi-CdJ@*W$d z%5Q5{+rHXB4s6Sjai=;9T$NaYdour>}~_GzmbI*(cCRmWz&>d#AV7RV=C0<{$g3rU>xXp3V%Ui_k4G_%||4moeBUcREhxujMMH65r!+ zPGwc5eJ>D?jv|EVr-1M;vhmTTYs&Bz&1a z9;>}zUKAL>uPS}17A8Ma%Azm(^H5Fk&o6fUIaluGSbWRgj;*W?y9EC9?NNO1@%ug~{F^yx7>aW3huclr@!B@p*(S%&$#7LV zc0IbpJ2hAl_8r_|Zr}8Qk$M~X5wPnkb~h!g+le!*Ox=SrN)k47~!n|0b5@s zePhnb*W+FQ3X2#A)a9V)4+uSETPraO^a8^A`ie=NS(Td2=t-YJ1T(+un?LRMdLH7}*b9v5Oe^3>MBsYh>yX%t4Jp!unbqrB z@la2-HEMYl3>+2(Igc6h9IqOcwFGZCN?2&&NRi{jyrTtOsC;lBM`t%mJxSogWqX-)-%ZAtJ3qvc7vttpW<&P$#Yi{WDwr+F zev}W!XFF#4r=c>r_UgRDv^W9HaPd1Ny?z%?;clavk-&<@>ZU?f^pdh;QsH)nHKHgv zZ<}PmU5it3Xj*9Q4-L6pzIPj<+$mo$(BxF#CSRRyS(cXgD+ir2eKQB0+}t3Qt)B2y zHwWDSgOmCr{nt+Tv+F8404+NgDfMrp0dJ|LY!E@f*9DGJzxaS`SN2vFChl&c5-9E( zD749}=%sdX9K*_LTeSiqgFDNw#R%&+k74Q}n~YC=_`&AW%Vp+`{Ki#mJNvXN)>=#< zT#nm=<5|nTI3XA-hsVm#cdwv`~`<<``x1Zb6i5-=&!Ti2Op`mTkny5b|n4Hgd&!R%s+Rg80PuaYRQI z`|eY#D_&iN-Kn)X8H&fKRhVaW@p9)vOOYJY@nnO=g}La-bw(FCZA_H!AFLg8>9%&+GZVq6j_R26rG?BeA*LVmtZ2yYS8#D)RWB?22S9YX|7-M9od| z8UhBbeh{oyGO{5i^W@P`@9TvJ&thRwif7*z&KX%@4Fr}8Zo!1u5HhcBusiLjVp3<$ zEC08Q*aeNYj!~1O(y4-#(4Rd;uiMUuuZ)Dh`TIC2b$ic$bypr#v#sA7euhJ_kt5)uN_?F2c6qe1boj3xH$?53m43O zz0b^ur{unDJUb5V1_`jjSL7Pv5R@tw3l9cL&+I=LM>~dY66wO!4Mw}aF)sfRTPYUn z*y7aJ#_HPU6(}FR?Z2R?OQ_8#UV4LkBx*y*6D8y5wANlM@cX3^2LA=GI;KZogd52+ zL%}Ra$tJrOH^WtmUMTQQP0u)eV@N+zEe@K|t=-nwRCk#7V0q$+AH(oSqpMV;ZFdg@ z%&*MIw~xVm7xv@a++$C`vkMxV7ElGi#8*pv+jjR=MMgth~clR@jrTl>u)Xjgj zj`>spiMzHz63XqL7GkI7MveHdA>%84V=Dsg0O`@r@pL4s9j;VQJvjK`ypj?BC1iZY zYHUV810bzL-!E;ZWOVK^Hk~7(N-Ll`FCGZ-(f_IHZ4<+Q%x(tXk+T<&1LMY2LH1_p z&}?oOum5ToxqC>+RqyU)g?{#irw%_X|5)}si7B0@E6v>NN>dx(J)yZ; zIm3ZXCGMr1>y{K#O-jce%l$=j#0vW%xK@((#7k$!|G7?1VETD2OISAb046E$^Vx50{YTTpsx}vDu5KuYo%-9rs^eYE9S~h6TRD*fE z-`$5~PGAN|QQM)~#l+|RDZ_~N&cLX(r0Yt_D{G5=)R9ero;)+-i#Kj?weo?}wBHJs zlbb1DR0VPMA1W^>wRE*frbL_TJ#j*LZ0VA&xAD3l$X5Z(R~V)1u5W%oxhouJ&tX!t z5v{HPM|s2zXZ2I${<4RWxN)Xin`Lkil>)6@c>;MP&Fnq;=_hR=aPtF&$HMnIi<(99eTFPUtJY%=UVzI!mP++zdaf(vOqe=e2r&7p(1mNyak~Ui z%i}HYbU!!jE)ZJ%)y>jqK{6i9RS%9cDdQRiLf@-)MXYpwg!PkbcRdvF!(%a?&gALp zxbJmBIp>Y&J=`C{P+)u}6jScjySG`^*0&^fv0{ErJwJxy*imB)r=K7D=PY0%3p!fb zs}$Pj&87SrdoHh66E2X1*WmQ|FLUc@9X>*3TW5Y?UfXtgi64rBxiV|M277_Em%@ak zz>a4$)FqU(^qG-FqPwNBONKX!O)<-V8`nw=2BJo|=FS9PECsYK0fDHIdPw ztMBZ6A5!JJvir5-y>{mHFd(rhpUW^QrSL(*#X1f2@J(I8o09hQ$o_`GH68h%qKo=U zh{5zPpX&`jVLeogckP|)E8a;e zY)PQVkE_W8{JHt>C0$?DtM`E=k@9-ZIaspOqpfSzE_C9L=2%3k5=e>&x3-`nDE7sx zQU6VIwkIEeUQ%CV5h7+Q3NiPOsrl_#H-*bh>#{0>NLg&QrH!GY9B= z-(cw@R!N0&Gn}wu6-!8#9%CtIcV7ne3ZKzl(85WaTW7_=^D?_iTlxjtPa~yMujLuv zMtFNTS_D35dmf8lJ6iskz-D}K*Kpg6TvI8adTbmfURfIWG0V{UxhqQeo@KIhL^J&Q}Ti^=j6&1 z92xzv^ab7zY4RgpXT^KnvHgIwyH*1ub)VY)u$P=mCOyAU+^T#BR28?8GU*$p6N@4wpV7B#?Y8=H?#kO5)V)YEC!eq4-aDoVj0= zH+uq>k#8HoP_8F1WWM~yW+uB)IU5#E@kM@Xm?AniH=q{ZAa1^>b?+~H{*g|XY%9gc^6aeEk=z@M6gc!r_6>GPbFx1 zZam(gl5N(`Ck2ep61>0b8lu^ z{9IrnZT_Gm94Xx9C)ReFwB}3U`r}Z}ZG4haS26E+_;nQVa}#-%gTeU#;Izot3(070 zABJg~5*};j4E`1+BY4c=Fv0JP4Tk#TmPUx?R9r!$^_qY^_av(!i^XZi<|E361Fy$d z@@r^II!i+R8zU9?NCzB=e{u5e3_695B2X}?@@Huzu~s^`0B@SBIUclUusISz^sC03 z;}oUE+bekA;$jn8+Go6Yoxapp>ydq{jF6Y(&0z0GEBajXhg4cWXapoyBuDFwtHZB( z#jya9-mFA&K;cBBCgGN3-l2=^s;%a{8S1pMVVhjl+P(g4pl|o^tDJfteB6e%jZ8~( z$l6C%gjsTHIGD!HLaJsFZo}edVgJ*)wnA`FyN3l*6;{6PP57n0aO{C{WxnpFc&lZ# zhvGP$35wE{rj+k|zRgxT!qKn58{@#&37g8f+Fqx*5i@0k~4d?m@rqAO#Yx{RCVRKZQ$;!ja5M#;P-cG%BYbT zUQ6~*DO;0C@mg8+yb5Ctf$46;)Jhbq~KMq5qn%Ox1(znZp>{0y9e-kcym0KU>)(4I&j zT`)T1{FxTnD(f7Htunkdt}df;$2F3SN!W-g#`t?#371lP4ADh)6N}ex02Qv-G?%3J5CcmXx)JO`a?R`a)d;E7 zU>yPWp;D%dfQ%bqKF ztlyFtm04%gRcReMP}nZG?e~u1JM=xL__ijOsF;kFK27STy}{p{qI|cf9xFeYNt*Xw zO^Ww7e2}}~7NyyspciTRAm_O9GoQj~QtfH;Uda~&4~tuvx+O#ocE1_t?H&4grH=$0 z^bCB^m``#-NF+xs+v19ueCiY0^~?2PE{cUk);;VT7HMH;YFFROoN}QS;pOL_h8pX) zr~BBvxbevOTBuznvI)%kZn8VqJG@Rz{FhYVRELb;Qmnsb9@7Hjr*Er_#Cl)3aS8X_ z?a81ENS~2FBvm4p;+3QNUT>Ei522nd*q9+xn(8f_jNtr2>LVF^_O@d^Wkr}JQYB-9Vhg#q&S?(z@Fx~$!Q zNIH7RhI&Ww^N)2z{}Zi`Oh+4+zkX}KCA7J5NhAwc0K7}3qx;Q55cZ0EZ~xjv`g{Q# zK)8B(PG12#4Yn0GsSdwlmu|vEU*p;n6Bx|=Y_Gs|JTi~1i}qghi&+-5-YtX-I2fcWX`0O(Y1E4X*C%a^%+CZnkML3SyrNT7^rdi*BtP96 z{yk$=?--T1D6be}b+g|1$>0kX#q{+2(w27-TyJKwxg;Elk#zN%f73~k;=$}Z#<7iOTm+>JZzGFGdB-j zI!=CU6ym(wLH?kX19_}Gb2ahBGBi8eQZrHSl|dIy-#a%v+!)%`4^F`$kLRRmb9sB4 z_K1C8h(3CYWW{v)S8}%Ritd*NE81 zYc8hfqREf8@56N@q!lBhbJ0;D_yaXJR=mY&2K%K!%sQ^EPaN7L@bda;69TJL@6ux8 z9BL4(y3X=-Frgt)6a1bfqJ(5xv9DU9{$C}$<+YFK?_W)^E*`FbtXYb)aAr=J9q7L6 zpA%Ohf@WSA_+e4$`>sX~`}Dsb%A>7^y_*gG&9Zo@w|Y_iw_c71|9fHoJIAeFCe=uS zdB}df{iAx{>_p(j$)$RoVWP%Fr@-Q+dqySZ5MY3w$2K9Vv5uD}*yV$6O!F)N?OcvU zfVHug-T(IxT%Tjx7Q*1`K1H2d3BP4 zX>D(cnRR9bRLSX(_)7+%7UpIZFfgnG0CBND4|WE3p;2c$BLKwDE6T>|Gq%^<<2zK4 zcono^)e@+7$r+yLm2F_FZ!%kJ3Q`!)#&Ci~Uhq;C%h{Sl94EqOCI!*N43eeK zV;m?i?8jN8nx8J+*`d9HZkzC(-Bj;wgLt>40gc4*?v3QvdfNj6>yllfp^`Ym<`TTn z#UX43MiuUTOuXm2Z44;qWSU=U;y{n;4uSn}_K?Xy&)x}lWjOPEf|k*tCZn*Sm~#q4%tgH^sJAFa`6b$Wf4P@(+kT%p8x)6l zAvJCU$5Vzl7yK}cMGtmyEOQ@$mkLwQni)6MmfsG8g9I7frPu-^#yMJ(!wWs5gthuZz}u#MJT7QCTl$8xD?la%)tx962$p<1 zfYiE$lQj?T#dtvt6r~K_1r|ziqP?$8X!#j#S zcTRnFmHgI<7#OrLy*$K!t)I*dpqVIf$!=>yiK}30^KQnbz|(r=t|+2TazHPt*V@{8 z`T(^)N4WQJ;5%gH*9E7v@!`3>iM7<|S#GtgR91d{ITJQ{b>537AYdV8f_4EQF;M)m z`%^z`*&5;wZQkM@uwh(?Kb0pL@IbEwQO^6vpFt2##>IhOnvV5%Z%EsG-vbX*&q2`U zbAi3^eJn(G2vCUC@jAIEELNqbWjlI~tTpEuryKFoTTfi*BO=B^^v{k1g4SD2Shzv> z9OD-N7sKF@p;q7Vn%f@kiJ^TlZl6%fxs7r6OO(m}y=D<9EPeT>(Uod})po-pgU&7A zfVIUtRK1YPKheV3GoaO*9BZ6yWcSE$t&;z?)ZcpHA%;+ytlRT<{epx_HY9A_+{vL` zUg@X2@!O^;AG*0?@+})RKzV~Q)WB>J1&CL%Va)=*#P$tCgt~tH)2N-e8k0Q^L+MNb zPoy0FTpP=5C4(P(*;iI9bTU`1-zvir83$v-Ht>t{8_yFg(>AsKwm+$`aDbZwdR{i$ zDY9o~?KlITTb?1rxweLZpEG+7j9>Bljh=z7_Bnim^TiBku>5LUg6Y#;d}v{d}%(E3q#Z2A&~9EL;7!Fr}z= zbT(?5a^|+ASv`4F0JtD&UFAiQ&7E)eoXT0xV~_mVr(*G%69DrJ4oGitT(m@>+-fIu zNw&Wv&KSYQc$xjB3F;?L@3Jk|os1%?-cp3(RLo_K`;YlA4uLHPkBN{Oa>;;rUcUW- z<;rT1YjttDt*4_EWon{iH&^#8W;L*)YV7bVt11X+3jODd)npiWHgspQp9tM(c)3>e z9z%EMDzALULm&_6JEhjX#sgvlshaY3vS@VS5bvYDruZeVQ7Q0F4Y>5=`uz#^ODtS} zIq`(kl{-ZWTz@LjeIWjLWHhMhM`jo^8oan$iCx@nmu#9|l(onHSbpw`x$&#Pb*t=F z+jAxq>Hp(a#Bmc2t1NaJ(=!mGJ1TbG6~$!(yd`bn{5)UGxgZpUdgVV(TMMqv)R;Od zUPZLOt^VD(1HQ~r+&&gz+=HR!a=V9G5&@E=qB%}I{QKmP2POtslh=SlM~@nFM`*8% zEFz|jf(2)@_Zf| zBMuzG&N_0FNhbzgJ)O6L*J4G37;}n7rWf;#aUF7PN&B220yHAk^`(?RodHl#v!NK- zvXmFbDJJ!({R)yGXgTUu2%bcDpKFnvAIP~+1(ULvGkog}G%zCA`5=oJ({e}}Na8cm;L*rHeJdt}0+c&~ZWI?p#|>mhgPDCb4mj-`*@XsjeIylLtsMU@I+9z_aTc zZph6dK^msVOaQYy)II2nS-m;d`qv}>51;ryo{^`6>(3{O)F9HkjF{JR3^#MS zw^tO0Pu3oR-4u1PX^rlDfX&)h;KDOVTa3aXw3(t!I4R}_tK?>a?%U0jj)&uF6-YHS zjamNslIulG_L;X&1QFEink}*W5Y}QctQe3S8}Btv$+Wh@3yGOk?ht%rf8R34l9O*B z^B5rj&k;#Ir+QmVLZ3Io{25(#TQ}i+BHqD*Np!Q^6I^sTew}o(ra~*qc{91?#Mg)+*zWOUL*Nn)>r_-H;{8*KB4n5ZnGxg!e;^clsFs*m9UFyq3VC8z71ff-jU$&+{fYlJ2&XF`Z^%ZUHa`X<%N90|KA$zQMbUpcIQ7!{SW9# zCedt2`H=*Y{0ax>;rzeHk?`d|Q2*D^{{-T6Y{Vh-;ZI$e9{!0CenhbOo^H^1|3GrS z-CF)F2!zqCwzIQtw|(^F{=_$6YHH7C9xCE{-~M@6mqH;f4|gD-96-RP=ye%n)4i|) z$MWX72dlOZkHqi?U@_>O>0;HtyZHj(XFFgJS63kNO6<5s$nx$5QciXT*#Jxis$O>A z5uC(SU71{}A-s}{66cS=@N6T^vx@DzMl_wqg(FqgM;-o>E_RS|ze6bFjy>43wZYk+ zA%oNxzYJ6DYk3)i%#i|MuKo8or_eX2Ti2aFp=~AHMDImA8TR?#V}LKu!aG_iEz6BR zQqEuc9^~3GbF0eHU-+S-L1owh@L#z@5bS{{(p}kd@{CzI3B<3L!z^*lhioTS11{gs z8~{(G7eyTZFfeqN_&}3=F5D3KL9#%OaPS`OWD$g*%L=FU&6KvG0Esa`psWW3lbPv1E$*{28C8!s4YcFpXaHhbDcDEu^+{^ z8e0M^W+0s?C1-X6!#>WdVtV`b<82a)D;+@C@fhM&;3_)yKoI7-ihj|>TrcG}A(*l+ zJzY9xOF4LaH6V4SgxaAV6RLW)#Sc|AQ45^N!S%d6K5(W6(`7KE?;9W_fQ6(U_JxB{ z$Q$Kf*!ceAXRLwTc$fWQ7Ht!5eDEQY0U1OX_PDMDC7N1#vEN4jPcsn}zD`{QjGa06 zNVI%s7v?;F6WF&5{B6GTr%)GU;rhkjObc_cNS-t2nil)Jbi8V>Wz+HaS$Tg`x%KPu zvNJ|4L%(K}0lY!(-OilEQ{!TGH_ua)f8(K&_RcH{LkQ6-lw!kbOIA)Lo`;UJAsFx> zK5-!dS$KN;6;ogO$=j_NYylTrS%!VSwkyWwyIP3pGv|%z*AkEOiGJ1pK7V#TjQMk< zNs(MXtyhTGDCK5#W{trPGh{qP>SU$5&kc8K(=9r|XD(moXfHCtbm7c9WD?j>*})Yw zpbQUGo&ZQ?H^`$YUzfcI>hs0_SZ=748ua%KkE>3F<^QlDy$}GdHg?BQ1Ftj*im$rK z51iL&lDw+}G^{AAkSjgYIY|KaoVk6r`sQ&lYRU%as4VUdMSX*qs1FJ9aA9cRdXtSi zTvcP7$hYoL3z7KO-Se%DTjC9~X&w|VACxo4=%<#Uvd;|r%SI0nF&%$swfdh{K*8C~ca27;;M_N&N7%h#5WfXPY^Yq+ zT3TdKJv(~v;y6G~Cnz};Ht$Vc&R2dYc4p-#{%#;P9vo>6g_`UGAP$e=h~g1S-wAXK zXbJ=D+pIs6sLrncu9ZG}N$<-q0c4`ZCL3G`nj9fpm$3XsT4<9I81$I#q6}-lW`wQY z1sGxH>;6afnjJPchEp>>i@~ZguRRnwx z!q_AJXC&7(QkPY8SU+z2%$0e`ZSf2cRw8;lK2RlRY^R;-%XkPJh)a!<-0|Ge@vXF| z7_O+Qp0e+dT+&0N=NvYTz76X!DLBc;N;L%{q<{i~fZ~!!xILL`*%SMY}P43OZV#v)a6J&_HQ-DsOru9o7WAnp{L=M>_ zbV$&;N|nF~!YL zNK530;{o`Uf8S)bOLlsfm*vXN9q);K17rolr~2@rT*-0cD55(CY=i~ZN?D6tazLEG zQ=NEA&fdapMpgAw^U0WM5ZDZGjU9w-Ng)PQwf8$D;4S)#CgN=rl%Bqxa2Gr^9Wv(GtOIYT_@tAZJaFE7$li)U~)^}qN3WY zaZOL1L(c!tcVP$M7i4egSgj?YxyxXS;kavl;TNHoB|z1X%-&cSXD%tW1kXzx_fX%= zudTXnnZOV?W`m4I73xwLQ;ly%(dG0ah~gx$qU+&+^PXQaKh^1E8i}Lg7SUe$mX}ul zIL64h-L^rcjdX3NMTh>~RXcOTwNK1pQu+R!_+2~ju*aWEC>@b2QFOg1L4G&rgTw@h zAIn?_*cHwuV}3fThuip}?>1p{O>d|g_EncdbLO#o62Br(=mdlko&~&a@D6FH|COxn0&~Ys4d+j=|pRzT?a6@mw@3dHm|8ykdm$3;rKuh zwA(;#=k6(--n%3#2R6`lhkp5D%b#=eoAX5{-HHai#eA~K2=I7({@XC-hHqzvUd&eW zWsdi2@VGZ3tT{bV^xn+9w&H;S>-oy2L=B8;-WGxTD0Iy(cJ-j`m_^zG=@rq%s1n*fT61$^Y<->teSoRx&Doay&lw^%&Rr zopCIr1|}vUr=C|Ym4&nK1+A{7m=hDfrnvC^+RWrk5&J>~#!Cxn2$v8A7k+|iZ;|5y zJ#+HK8wQxfUzVe~5BL?!eV@vdwoq|X!r!Fi)42_>*-A8GUULVG#~8;Mji|M%Ol0%A z#>lnak1q6<>}~bmN!}n5mo2+IKaU>o(Z=Ms)$w&YEv`8@V;7!%pbC{U zawsV^t>^{X5q;N$IS>3G+B`UJQtm{@?mvm~#P&)+tIxX+R@`#yGp}9861zt0jU*+p zBNmf^RP3EMD9{c~fKo@u<>vY&&lR?v7lrvNM1_SopqnEtgPSj^;4#*sAyxBjr%jRB zz|T7K*BtyKs#{X!o$RL-0{sGn`?KK&m~ zao|Jmq7E)}EWhh$U^3|z5WwnH=6T}%Lc2Dh!igqv(re@FRh?U1+iz@3l|alfUukE! zhL}!E)G*fmhY3h=5|ngaDJ;!Ru-cPt1K;}qn$2ZQWsMR!@RkB7icR^5p83$8wBd`V zKm*=3kuICp{{eMYk%tw-wGr#SoBiYj?dG>m?Co+&j0S`En6NYfUGkZ0RWA%{gv_Uu zh~4KSxNwM-p0*U!4z#?wZVd-kmY=DkUo|i6_l|6=5o%+=mcv*2nsj-G-`}hv8IMf? z7C$R3`3Tk$(Ckj9dRL%bz>V}}YFq4`98K5nRT?P3JQlAV^AMc0FP_ zadq7Cq1zh-2OA7@&WnA!4yna{c98m~*Zk*8?yr2})gMN0z2u3&{H-a@3FO{du88$%;*rQQ9IxBPoe+u)+{z}bl5-`h4gxx>-cvOusy3R<1 zM4&GXpC9RrjIJ5&oL3BEP^w~Ge5`M~pj&T)JmhG{QKD_-s4|HE&Z_5^Va$OLt|M<0 z`Chu35%`l%HlsF#mJg{>6|>`K1S<5)nQ~{$M#m2=&+||88F@h{;$dYgt3KXSz>8JU zrBul!-^klp&pRaze_{9Y(7W@tN_)rb-zjbu?7z-u{{zEqio2-FwdzXMXByS~=-lZo z&6MWd==*9jIl1qb<$HIGiHU<&gD>biMb5_fZyeUed-*x59aQY>Z8M5uSKa^uHB4;5 zQ&Td{3Qf%Y*+O+L-A4f-vre#aQR;ZSopeeU}2ylwy~GsZwd3=Qh#$|cWjFO z=9u3~|N9cOto(ly2&pp8>MS*1fJOZ^{}v5F$^R|EnNsy{(Z|N)e-mJF7#9Z%1L5bl z3HohnjQUq&8u`O`DfNGW{_2zJ1nvF5Ob)09IKjHo8eM|H|F9F9~WyaZZZgnJ>oWNM`WHig4qj`)D_tN+M(yKudgwO zhxQ5~;BR#dsY=Kv`z9J%Ijc@WJLl)_SOfy$9yH=v%%C;LsnrGW^%YsTjjgLIFR(}? zl3T&E!cQt6Yl{S}W78!iC4-i5+;JWAtJr^d^>~KN#@~>Scj{$$jtbW|AnH9;sHda~ zbUsNA^D4L(MC#aTVYAu@8C- zXXXyW=Ntw_Iht8|v>)3wyKXP{uqhLcJvur%i3tz%DY_m|Vh((l$<#5mnRO+H0&3Hb z2z8{!8(#-XCfZH`+v+$WbT@mL9NS$iR4fpvq;OLM)jfJSpgH{MnjfvX#$0^?E}^%^ zR-Gs?GS0yr9x^dlZlhU`B_ii;q(a8hocAGcr{JSn)2l;h=0#_K5LGleTrvYKH4t~9 zmBKP2R(|{>_Gcw3miyH4su8FH;NIJkk7-=IwmMgv`-bxKA3PPGwix~Y+PUtiCYNph zAsq=tq)9J=3J3^>UX^x0X$l-#5CjxNO6V;hC^mv92c!l?K z$-OY1z9#n*>rr2D>~~U_hX@j_H-BpAE>w_uh<3l!qqM1ax-46d zOqg2_P8^pkG)0Q-JnDOBv5I_2D4W5HK*m%L(vH5$)%It2h+^%PTtP`8N@67e?CDfL!hsAhTDu?4%3_OuXBtWveKC`Dqb5WOyXNo zyuK!G{&sI9s`e9JVeMc@folM}rW=HjnbMqpWyHg#fzJ4?7F%if;9;YtTGJu&ZwvDG zRcUuih4p_u#jC6c#3aGpCRN~RXzePyb_!^Di2ZjnLTQ!zhRI&rE5(S!uml zIK5eZW=b0(&sOIMkzUfTMczm?#-naM>No#qceTKfH}6{0uJM{uPh|iWS!ay(v>S)= zc0f~dItI452$I;5Mn8_8GFAHy8Ae!BjPGul({Ewr_xua{@M@K?Q3WJ1b_Y_03b9Z^ zA$|m>hvC~Nk#+XNgdS+qE`&6`78E|EF}_6#bDj>~8Q-0*BAoPM*N_Bc@d^JpHXo~5 zG#Y?U(-}qZjl2Ibx)bcrcuW6Y!f9$S92eA>O+FeAU(ol$Zn!5*%8ilMP}jAwlp-I0!YcSYE}{tmxb;GK>9z_f{_129rN zp<1%%euWR>K+jN>;njv>@VVw_qxJ(KXgqIXgpWxHvAmXQ*pFDV>=AAp5n$^&8@m@% zAgyK(x1|PnM52JJL^pjM*E<@LHN-usoVW|7CE|#%lZL)sdhWSVFsNXeRi47CUuWY5 zOasNb&M;SwoYh$D#(@2yT$yHvoP4lOQ!VLMMGE%cH_!%hd*G~2Rl9Q(iYPT0Z zJ7Q94s2rBz;!&8#O=mL)$}gJJBf?VW*_54W&Cs%n?u>@OQPt)>k7@0*3I-9hH90zG zetdzL4wb7kfN~et>wWGU<%v^#-XYJ~gm5ZE!RQ}NnM!5S$=MuLB%}2%aZxJ{T;x&T zguV3JH{*T|?i4rWy7ry?(E^IipD?xEie*5HZ-h#+8DusnH#E7M0CML*hX6Lvrd96Q zc{UycD1DLK%GDw8=KLx)dg(hmo68L*SHX8*si=Z+BQCZQy?)K=Uu?O zN}d2$;($e!#OF;Ps7+StaK;sazt7Oql|0%B#P{yG4UQ+DSQ2Y;D#HapU3-+LNfLFn z)K@!PEPOoPG<`K0urhqcn&6=CKzesMu35)FU~y4;?-R2pI^@jpCcixf8bSz@=m*tk z#QI&B=wH!}KQJ`x#801QcrCnw9c)rcFIqc>&a{>lomB=Bx zHBG+BP#F0}H?D*(^E*g1S%NW~Ooh70q%fO3=IIEkL;tOkLa7r{E+C_K=QdXE7v8;2 zPbEWN(J*DA2kQ$c1V&`fBl_?0#mCint-|`7`Ekp7mPa1Gap4FHKY|7u!K&r)#_*so zWS2B+X3@o&nxWX|OzEnj+JRp=lCIFn3vk_d?_Oz>=m>VX{r0jvr&=r1PdwaYw@zn; zhP2F2JNz3bNOI*A8%>%qP9U~%<2fJj#S1q(ti~5uomzz{(3n$i?v_SqZ@JI10Ly-oZCTIG|$!P#n;23^$oc*18ZI`^0?-q-3^-Q?hs=CsOm7O~H zWDmj+8CcGxAAuyZF0Byr1Eb{Vsf0pGuJn0YPC?bjLhEoz-)LK|T@1}k`06(Dao`xvZ*STpT z5KSB|m5MLZp*OPPH0v41BgGBom%r|p!XTu^Rjp>ec83A>C87}%L2JUSQ)qj#o_mvq z4E$Fe==#ZRKcnR)VggNbXq-98;N)36<>HH|rRrm~#g9t!57&EoJ*@;}eWwaZjhnGj z{c@LMNNGq$?dG2XO9&E6%F!@xanrIKNzA43dX^?HSfdG+B{GoSH`@kb^(bj7D0m9< z)HLqKYK3reoQEJNl=H8{>+k!lWu29PNH^P)U^#As&!#S4Oke-FlJW0O48@Y zynmGRW0Tm$dzY)7;qLD_E9iQ34{r<@w46hw)k1G0H1S3+&b~4{B->>{Sa#0#=TWBR zq}Hc%DU)_5hWQc}w@$zCeRKs)D27Dz-O0T9lg?<%<@U!+1uN>H^KCvZ3Mu?qJfgK` zwp^vIMN(JU?tDApMz6ZB9+c`(n{LwLpy30ao622D^b(DHyQEH8zOhKo^sy2uSk+gD zRZ-pE$X;7bTGk+w4`jqCIGLdVJSYBJxE-a*pgjjRczN2qtBku%nj7=^o5yO->Lv0P zNBRK8>k@N+&{7b2d3zo2558QOu58;@QbR6BjIjjxY4{YaZykNpRy<;OKgG*&R3UZ> zVr6?q9{Q6dAMnToZ$nYUMUY1cbjPu{8nu`r+IXGjs8 z!GiuVFbLNdNl=m$@U8=YZL#EQt#_AYEfB_}!pUKK$XNK7Ej+nBa`=gOxYwSu;qe}O zQIvdn?s=AQ%;nyEl;s^N8{Itd3h%55veg<~Vrrk+F03DY)Ikg02b)kXWU~y?-ZU&! z4#U!F>hyXs^h4X$$xC73NA8xZv04cAySw*nzG}8a)LGI6?7T4>kqdQ9z0rBOl%izj z(h>QMU0N!_+~l^kuS$G550v=ah)A%UWt-U;+0>}rb5=h(C+Z_L< zVJ`TT3-ns*u&bm;qU6wA%eG!Gj5NXEU4#(|nTW$FoCqjEJjT7QVTDg zLlN0&``$kSTePi8dUdY{h){sg6OunE<1jy`=;<(4Bu3=OS4i6`?@_+-OUH$(xce(g zHjb-hOK+%>;mC=lrP-gtD>bI$Q((Kk*o9GMy<11@v;Z^(_UuMcsL-P`=2e|5=iI^% zdweXqnvkRovk4n!mB6;zqEfr=4S}PSsR-lda`q{H_wF}e9qNbfJZ}u9C;y~U$&Yc1 z-~(d=_5ix#eJXsoZ)KS!@rjLE#f_y~gZo(BsT;v_;m=`Lc3+?IvJ8+=cxrOXArt-{ zdhMfoi}+lb#e}dsp|cWtn0@>Bl!{blCWDF29kay<{5pd1RLR@0&hwDy4N}qvVgqHS z2zzT@y!h{e{cU<4O-;nYXV*vP#(U?a<0FokV`{w|cWRL7W%fH0rIIgm=d9g31}P{> zsVxE#W=rFEjr0R&(!1d*FL$})Z#v?g#A)`=)1yx1kaU=}zDoQ0y8v6XE>T9cB(XEH zu6d5USt!cQR#;|ST)EF|l zpXWpfRavdbMN^J93~?}9_K23W4ky_-0o)n!0V{wZxUKTrJl%0KXYyj^and~_btvwIvrA?jVrf?h6E|Cpk9Zauq=uRS(gWo?M(UHUOvBY zajM*%=}BhZC8Y#36MjYK?nkbao2%cOO3+oOJcY*JTrNy*<3^zQpK6T}K8BKTe zm*g9*Hw~VcYQGPsLy-ZjAo7Lydr-nn>4EPVbU4n$(+@k`m*nqDn^N|#U%_rEzPe$Rn@;?`r?%@#?8+b_W^f=^2Id9M@C zkU(RB-LCWC-FqbzuHyH1+?9B*EldZoQn84`1T%B#h^E$1b;4JH1?Fz$EpJ8q*q42A zZpmG+6)CpPpVEP+S7~}`Xg~MmS^8n&*cT|X)^gtR;cYH${~Z)wApNOS{r&@q2dbj# z4sWAqQk#W$a=?@o+&gq%`kQth7;(5zypsDQvr+1K@#8gH{S9Ojss2Njy3f&B#jGC( ze7}+QJ)@RNa%EL%jh0)aoQ)SRJdaACEH%gQb{mj)A$L{yCfYgSnZWcUh!PKhh{$|V z&68^4?+EV$zI@$i*GQ3z-NT#?wCI#=vXq+^&$p+;C8l9Mhl`16&E@?cCR90nB=Zpq zUJnLL>w*Q~V~_#T1>2QL>IbXIoS#wDTgyGF3z@~ex;KdwOAxmJyHfU?4PN`>GaTpo zqQ<_BufdGh!g)498s}F)82(geK1ER)vrENNQgiqM9{$s`N!0~@S?@)mh@d$F*$6FM z8~0?YJ6-CI9Q!z*rwnBZ^=2M%1#eLdk6!Xqg}2Hq@v_kEk@rAO%Hql;1=*fw96(;f zt>fHWYWExiQXjOI0!Y4rI&Q+9;x@^JhwJ2JLbbeIN&Verpv&TO@PRW;hZ~B(&sGtz zYd(KB4g(} zj!Ex81W4a5-@4IgRes^Hu=~Sfa~2-Ew-n|i)F5fdUnWwZ?trekr4S+*8b;Lf&R({X zSzFvZKT!x0(@Tp}%U*Klczo0NDz7N4AvS_B;Oe3*%)tHS zJp0dGd)jER2VLR|<&<(CKba~|Ll!(eL9mon!CGeEL8$-QBAa`9&@N%mRV>4Y2GhGc zFg00P{OUNEXs0kobD|wGH$(mKu|7yeGJMB1Ds?Bf<&+(m{Sc6!!GyuyA~VCMLr&;c z;5&ipfVVMnj<%{!%#sGpi1c%!k&koid@yn8u}h06l*Zg-$rGASTrPK274F{P%b;rA za#5*EJ}VMzpSw7A*%bGV@_ITdt_Q)n&Ur$_dp4-3GRj+zCbf~zZtsf%+qe@st4E)= znkgPETrE+YvC(nku_Z2p@27DbkjH>=`J^tb+&#!{t<8@g}Cs~oy% z%-P=d8Hb*-7!T0*iuuxasFIIwhLu*M>%!Bi&W<3}7>V27EdPN3EjczxI=dv>m4aAS!Z`t?HASVc0aae?tdcrilfC4e82-jXg;3ncG2aCzpcC=m#Ry%R{=fE3W3lnmnZo?}*r zt-0a%R8>0E81+Bc4&K8B6W6;<3%?Z%R+_jf`ok<#8Ine|EEuPwSFNWHPD!8fD8(A< zwq@fP7~Q+@9~hzC)OGkc^x1N_=p#zA=$=6h54rDg7wS|bQN+aS*GALrhakaZ^@3j_ zV^#R-N|}gmLu1>nM10LhjfS13sI&nFwPM9{(3}_pU|i;Kj}kk7_KyI+e~a_`fA+D5 zj3Cj;Qe14bCw8E!gWL%@jt?Qw#b%?L zKoAU(j->`nQk-7@-mfrOiQ}2GfS}kvWWt95fW_RB+?_aCjjZR-N_g?V6#eJMf0g_N zlpuJ_+8s*=M7&dMIRiYWmjoi-H~*FS3xxkiOqe(gN7gF<0Phchy!y+#snnR@pVr(! M=l0DaZHFiS1yfI>s{jB1 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/grid.title.gray.gif b/gulliver/js/maborak/core/images/grid.title.gray.gif new file mode 100644 index 0000000000000000000000000000000000000000..57bf0477c06cd7d3819d35719c79f734a670a18b GIT binary patch literal 79 zcmZ?wbhEHbWMt@OSj52a{rmUl&!0bj{P_O;`?qi3zJC4srAwDiojRrXlZ8cu;Xi{8 j0}z1JGBAs9Y?S$Q{Df1dti|iIyZ^gWruz+epkG^iz7 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/grid.title.green.gif b/gulliver/js/maborak/core/images/grid.title.green.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf64b899e9ef6abfc2cdabf74a8cc8ba98e16e77 GIT binary patch literal 105 zcmZ?wbhEHbWMt@O*v!D-IjhuVVxCKXu5(|GQ*X9Yca~#UhC^q%LwlNiTdI9aicNh2 w0}@dD$-*MS@Si~kBnC2rfkjN9#glob_sg|?-@`TfQZnadtXh{N#mHa{09aHWZ2$lO literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/grid.title.greenLight.gif b/gulliver/js/maborak/core/images/grid.title.greenLight.gif new file mode 100644 index 0000000000000000000000000000000000000000..08f6d3a3d5e4adc7d91d2dd685348811b979d8bc GIT binary patch literal 158 zcmZ?wbhEHbWMt@OIKsei<>BpP*UullcJ9d4vxl#qIe6vtfy<}%Upl$(;)%T%j_*2u zbjR7l+s_=@cKYC!(+4)6+P~@Kz75CsEI+i3fjFS}lZ8cu;Xi{8NIA$(23BbWfgZ+0 dq2r3KZyp{|!n1*C+m87yo~4?Ef{<|5kkU=08_6glYt literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/grid.titlebar.bg1.gif b/gulliver/js/maborak/core/images/grid.titlebar.bg1.gif new file mode 100644 index 0000000000000000000000000000000000000000..919a84fecb202d92ad12713680df5dcef5bd7905 GIT binary patch literal 90 zcmZ?wbhEHb)b|Ns9#0~jd&WML6u_|KpN;(^pM pFw1M~vihfYLbG%4w3lahi%YomrZ6};3=*#Y$WwN}P*Q6H7Al^Atidb5j`%jr0vI^$pBtKVkI)s!#=~2+mI{ zDNig)W$;Z*F3QhMP037DaLX)8Ezd8?E>`f3P%ttuFljGaa~`N6)zif>q+-s~3mdr( zDDbdc@U|2X|NsB<9~SpOLs>8G)^Ao8X33vUv_@ziRqV1%H)Rj@+TJ#kk>O7N(H_HB zyoxNm9$5ux`S&#q# literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/icons.gif b/gulliver/js/maborak/core/images/icons.gif new file mode 100644 index 0000000000000000000000000000000000000000..01b1b22c06451494591d06cc84c9d993225daf11 GIT binary patch literal 11530 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 Ef~C2d^#A|> literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/input_back.gif b/gulliver/js/maborak/core/images/input_back.gif new file mode 100755 index 0000000000000000000000000000000000000000..d9d4a35491a4383c6a7aa91cf2064308ee254a4f GIT binary patch literal 44 tcmZ?wbhEHbWM*JyXkcLY|NsAo4<8hNvM_*v4u}BBFfcLq@JBLO0{|Yv3V;9r literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/loader_B.gif b/gulliver/js/maborak/core/images/loader_B.gif new file mode 100755 index 0000000000000000000000000000000000000000..b36b555b4ff04f841bb2101514d8f95bcf7358f4 GIT binary patch literal 3236 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/loader_B_blank.gif b/gulliver/js/maborak/core/images/loader_B_blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0e6e9760bc04861cc4771e327f22ed7962e0858 GIT binary patch literal 4178 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 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/maximizar.gif b/gulliver/js/maborak/core/images/maximizar.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f27c677acad32f2d1a043161cc6dfe146f1bf21 GIT binary patch literal 214 zcmZ?wbhEHb)A_J-@kuv zZEgMk|Nnja_AOhsEH^Lj%$YM)RaMWQKRt>2-uPFqs+>Eq6#OUBKOil xhXOuvZic3iS|?r(Zt(_PW-b<{lR+7~xdpm^JnT6AUX0_ZpumiOOpJ;Q)&SFzR8;@~ literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/maximizar1.gif b/gulliver/js/maborak/core/images/maximizar1.gif new file mode 100644 index 0000000000000000000000000000000000000000..30bc5ecaba251c5d2d0e55b8a1b8cd4167a8665d GIT binary patch literal 200 zcmZ?wbhEHbgPhY%v@z$+dw{PFR zd-v{x2M-uV!Dt8!L;Mq+#E6<8x|aFW_O4e+3))3Q*|Q=94?bWMk!6jGP<+(r$fM>Xwqe7gmNr&4?FkK$jz>EMMFb>zJ~*Z~ zvMU=|C?p6pu`gocw@ENKkig96%Ptk5a9{xwcPOV4M}k2k%Q{v@i4+D0okN>5F7xql HFjxZs_zi%( literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/module.grid/page-first.gif b/gulliver/js/maborak/core/images/module.grid/page-first.gif new file mode 100644 index 0000000000000000000000000000000000000000..d84f41a91fca3a0ccc1107a78ffbf7b62c527afb GIT binary patch literal 925 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!N5_)V9X)ov0=f%X7nX_llo;Ppa!i5VLFJ8Q4$&%&Em#6pV(z;0OW5pDfG_ z46F<~Am@Pc1OrC}12>0^$A$$5o7t@;-Y_UNJMxKf6&W}lT+k*Y$eyJjc<@21kdg?` z9)m}X2f37ODg+`IICZeGskVGL@ZdlLlaQT?!H)&bz6?zAIR*(A8e5nhSgkHN9C*OQ m>dC5ipkT8?(+Va*AAy7q4&fY(0%9#)p=)k#W@Tbxum%8@3U^Ha literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/module.grid/page-last.gif b/gulliver/js/maborak/core/images/module.grid/page-last.gif new file mode 100644 index 0000000000000000000000000000000000000000..3df5c2ba50b143fca7d168d5acbcc4404b903ee8 GIT binary patch literal 923 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!N5_$V9X)ov0=f%X7)sh7DeV(M==$yO&0_YC2+|IvM<}Q z@ZbVY8B+}&lf=VK2L;XIwg}8jWa;H%bG(qjsCck}M+|z`(?y z1M&eVPcU$JFtBpScx+g3u$hC^!6V}XBXb*zY)A!1phGj4Fjq*7gQ62lFOR54M?r!E kLmQ{U6cz@-#wJD`MJWvdVWq}d0_-7oPHt8|*uY>70KTb0MF0Q* literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/module.grid/page-next.gif b/gulliver/js/maborak/core/images/module.grid/page-next.gif new file mode 100644 index 0000000000000000000000000000000000000000..960163530132545abe690cb8e49c5fef0f923344 GIT binary patch literal 875 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!NB3cV9X)ov0=f%W)9;69vKr@Ionu*A5?G{Hgn3DYJ|un wK6d5q<#D`_!KiqUp-ntt3Jb$U#ts%8MWY1*!jGC}2?&SWIk{Q=U;~3S0KQg&YXATM literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/module.grid/page-prev-disabled.gif b/gulliver/js/maborak/core/images/module.grid/page-prev-disabled.gif new file mode 100644 index 0000000000000000000000000000000000000000..37154d62406ddc064dba311b95f554e49ad38003 GIT binary patch literal 879 zcmZ?wbhEHb6krfwXlGzZPfyRu$tfx-s;H=_udjFb@6g=b+}hgO*4EbD-QC;U+t=4O zY0{+0lPAxdIdk5;dGqJbU$}7L;>C-XELpN*#fp_HSMJ!cW9QDDr%#{0ef##^yLTBz z!Dt8!oe)s`$->OQz{;Qlaxy4SFmU)VaC69bY*=uxnSOV literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/module.grid/page-prev.gif b/gulliver/js/maborak/core/images/module.grid/page-prev.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb70cf8f6a3b7f524bbeb3656d875a823b27fd7c GIT binary patch literal 879 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!NB3eV9X)ov0=f%W)AK)kBA8^Y;DZmPc|?ZI=9Q{X*oQZ zkbJD2lgIqQijPiCj2*mD6%7sx9yN0CvxS^laG;@KrlbJNftid9=jS`{vav8&0{~Hw Bh1385 literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/nc.gif b/gulliver/js/maborak/core/images/nc.gif new file mode 100644 index 0000000000000000000000000000000000000000..44ef04f457e6e4a44ea8b2f649997db16212354a GIT binary patch literal 302 zcmZ?wbhEHb zwChiwzuUa^MMlozqbI&tdDP5ZaC=_Mqo}BbA3lEFx##Vf^FP|7u9>=4PAtE1&LCK0`{ZC`USDU+5MFp+hu;qD>&$1JzzqSNjTd?@n?VO;2FOngY~BZ^PH-0SX*n_VK+47`lMY=_PP*j~zOXULVTYPlV@UXq ynLYx&KFt$mSV&B0Jid8?hlkR!F2;=JC@5*iZW9!dd@4Aua>m33AC literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/nr.gif b/gulliver/js/maborak/core/images/nr.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb650024ed177c54dd42d25122eca6471161fae0 GIT binary patch literal 297 zcmZ?wbhEHb zwChiwzuUa^MMlozqbI&tdDP5ZaC=_Mqo}BbA3lEFx##Vf^FP|7u9>=4PAtE1&LCK0`{ZC`USDU+5MFp+hu;qD>&$1JzzqSNjTd?@n?VO;2FOngY;Fgp2E0h%=|9wYqC-T@L&91yBry;0pN3S;Q#;t literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/nr.png b/gulliver/js/maborak/core/images/nr.png new file mode 100644 index 0000000000000000000000000000000000000000..287e68f7117e1ae4977ab8bd4ac33ea79b4c1b29 GIT binary patch literal 474 zcmV<00VV#4P)Mfvv6dg@h5lqW0j>o>} zTV1a;6m=1V00GhNE-FH>lG?zPvNn^BKZ~*G{`>5FtXwIBuMA#6;dzRu6QAsPo~F?X z)^|2>r3|>PD?tb@E*{YZFgc5QvG^}Vgag+Hd8WoEN$u~xx&T^fLZLc*rSUz3?3H^6V{0v= zBYTCzqnr(QF57TqA@s$Cwf0xJSZwe8F@IAIv}Mxq%YQq+edJDomhU3KC%FQ)xIQv+ QT>t<807*qoM6N<$fbB zG9?kGvzGm4-ms5KP2k5N?XdgfgP?N>#60i*diN309zuyyZ#YK!<7Y;uC&q@3;0)wI zgHGtt?6|D7{)(4d>)-of{3-AKasxmD@N(sK19jn}nRiCVOUF<`qnGsQB>|eya0YT5 z&DTUZJ#=iPxi-qP!#7xHv?O02efi78)PUd_c_}X72azIJfjU8%|6n&?)(S2BTQ$svD|3uT9FddH=|3 zSi;1LG+wQp_f#>yJ)Jm!BW-8!zV;T3KdwlE8VU-mlmS9kVC7@u2 z816o+H~T+Do8D!~lli^S4~K%bKRY^^mFr2LTfqkDl1|kUqy#9XVVe;-)n@5x&pp@* zzGCgclH`wrfbs0jsMEJQclM_%BRv4_UcRGVowwum%9r C`z*Hr literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/panel.bg.title.1x23.gif b/gulliver/js/maborak/core/images/panel.bg.title.1x23.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f7aa594c3bee57302fa817bf95e8bc1ca1a1095 GIT binary patch literal 100 zcmV-q0Gt0uNk%w1VF3Ua0J8u9W@UiR(Av1U%B-u!qoTd;@AG_om)+jv#l_M8|Nr*( z_`SW&v$n?6*Wl*n=fuO+A^8LV2LS&7EC2ui0096O000CL5InUA8H|aAP-ur!D2aj? G5db@w6fish literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/panel.bg.title.1x29.gif b/gulliver/js/maborak/core/images/panel.bg.title.1x29.gif new file mode 100644 index 0000000000000000000000000000000000000000..7e33d6c3cc6b6b7a2bbe2ae2783f918c4fb79ad1 GIT binary patch literal 154 zcmZ?wbhEHbWMq(KIKse?mR5KA?2Rqkj;~pLWXa-vuU@~ubMNW@|Nr;wJzHKr>B#Xb z-@pI7aOuvI$B#dJ{BrfiL!cA`DM0Zj3nM#&0D}%l6Ua^mR&fOf8Ga{$!wPFS7HKek QmhgS3bNZr!CkKNy0C9*l5&!@I literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/panel.bg.title.gif b/gulliver/js/maborak/core/images/panel.bg.title.gif new file mode 100755 index 0000000000000000000000000000000000000000..4f29de61f12a7650ca1f5408b9984eff630a5499 GIT binary patch literal 147 zcmZ?wbhEHb6krfw*v!DNc+sA-=WjiI{&x4?vzxabfB*i=oqJD@9KX7H)!{2w@Bjb* z|JCbH2M%9gfC0syEG!}n{~2^Z0w6OOSR4vYdcIb&cFbC37Cf@^v}8`3iK- wGbi7#I44u{{(pNzfrk#8(1|5QGYu@}Us&Pjur_LaQ&ZXLw^jS^a4=W{0JF(NrT_o{ literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/panel.bg.title.png b/gulliver/js/maborak/core/images/panel.bg.title.png new file mode 100755 index 0000000000000000000000000000000000000000..179e2be0886f94f3be64c1632325a5c3f99a96dc GIT binary patch literal 21171 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 G-v0q}$W0Rf literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/panel.tabSelected.1x3.gif b/gulliver/js/maborak/core/images/panel.tabSelected.1x3.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec327a6602f2ba93802402038e1ae93fcf62b488 GIT binary patch literal 49 vcmZ?wbhEHbWMp7wn8*ME|NsBDjOhWAia%Kx8Gyn%AW@J!0~6B}ZU$=rQC$m( literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/question.png b/gulliver/js/maborak/core/images/question.png new file mode 100755 index 0000000000000000000000000000000000000000..8e6762fa49bc5ad9aebdd8dd8cb479efa4c65bdb GIT binary patch literal 1435 zcmV;M1!Ve(P)WSr}sySlK{e6gCQL>B_4ew59I{c)r`)3w=Sm&2W;F@AkW2@9%fc z`F-bpm$kUK2y1C~=W2s_E^9Rn zAaEiMN6<6E!^8P;aj_5)5e_^a&tsiNqXDf}2WqtjY&M$?r|MZOR_SU)RwRJnr35@7 zA)b#8F)`6WWlNzL2dQ)zj7Fm#e|}Y1@P1{;1Q7fjMx2wHnjAE+x5;Fq6cLlj_($=f z!pxuv5O6-9m$P%{4hRbi^SF0sOab5javp9DNSV3V4KeU;`Wuvc8!1bB`#&&0um7vG z%7dp@WFw%{gP;Dxq{=|m*t1c zjs@I?Zo#FbB>R99>*<$L;KUlmS0NI`xaZY0=6+56CBLP>fIukRhQj5S6%-Z;SLy>f zL~!H}tC@i&vgOGHj|>H}&6_vj?um$sk59tfh_ICRQNbAi%R)^y54v0 zDm=8n)Rx8a7)hxGf>_Y&^>5+Nqv-cN2pq3G#piN4iK|8LEwr}IZsxiyFB>>)HU+wz zfLmvRH~|a{-WCW&DI0wV*d0z$baZIjjqC)nE8;Nnviux)W&3jsI7NWvEqNB0EjCCJ zC2zy~14wLvAz-%J!D@GeM4;wk6YP0y7kpBX1H8!fz$VeNmk7`~pjR(amjuUVcan*9 z=q84M&E}BH#*`ruAVNG`co6tekrc2i{cO)Hc)k0~7CYQij;nlj!FOMODmPgj+No(x zP~ha@>APQsjj_9|AVV(ZAcfF-_JL2^dXgcr&{Qa?6gu z?gRNSIisNf2npB7_DO$xXD=ux)zIJDb&^!iZzHNX{f+#-&T!(y*}4^@C(56o+wZ)= z2=&da2+E?|x9$MbnmPFCw~H{R)m0DPyryz*LBA)WhU$uv9_h%fAAfHMNPwh1a(x6d z_d;@#->6+eHNzLjt6+L|cIa~Lsc&&=&Yk{%Z^Iq?O85&4&W@yKHa%OOzYiiFTgTiZ z^(2Cu!UIUdRC8j+XR=|Bw#Zes=FJ{lE{g$l%)9tbtWVWF%y1E z;A$~Tt(E{zVV!#iWpJ&#A4cRVa5`)f-ORlohB_K0blTMqbtv^Eg75#&D`9kef|(#vV7Dg2+{kZgc1`Xym0%k_nFBe-# z1Q47Yxz816rTeNHd%&3s%^>dR(ND{zSqM)0w;~v@pa{_5R}Sudo&UV>X=eV`hyo;i z!_eB*2L^*tHKQ0VlHF(-q=jXF;8HH%1#WP1irTs*k(#@!oWgc%p{^ZvtJq@Dwe*Sq ztfPDR1peRpD8GzEiwn+^Hj9aOqqm=uxk;zFZnv7}G1?(_6^J9S{!x6I`SbzYR#7;3 ppGb+QoDUoA1AUtP-}avX0{})OV?7k1tv literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/separatorTable.gif b/gulliver/js/maborak/core/images/separatorTable.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5724af182e40d409e340e8ec98d81a377d8ea52 GIT binary patch literal 45 xcmZ?wbhEHbWMmLvXkcKNIdkU!|Nj+#vM{hS{AbW%00NK<0~1S2KPM}LH2@%)3dH~b literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/silverBackgroundMenuSelected.jpg b/gulliver/js/maborak/core/images/silverBackgroundMenuSelected.jpg new file mode 100644 index 0000000000000000000000000000000000000000..530884228c9c354a344e6ae80f474e9f24f4d97c GIT binary patch literal 329 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{bod$iO7X$SlbC{|JLP0|PT712SM{VPywO$OtenF|wjaF$=Sc2ZcV%7eRgy+gi5z!Xz+gxy77$fLsEtGwHAtVl1J#W zPtZ-DqKiaTU!c2QHth?v>J!j05H4wy>MXK5M_`Y~|2b#o^S_@^|W8#tKhzFV>Dp^rUCfP+%(^>WtCm|L6 zY?Qa_4fXkcdD4?T6{N}L`u%>QpH7%|Q%>b_IXS7wiV|mvc<^8%<-fInA0jx|ZU!GE2-ev}(zwnq%5k)9e(-+b_3l+BfZX zPb?j!^Dh4d(X8t%pYCf8ExJ77sZ?B1s;Nh6CZi^^ujcZ{qATeYv)*c)UX#9)Qg?Eb z^f}QaJukZ;=D>`oyL-Aa|36@Leag!^u{)#BQrBhLpiP2q%3q$}UMt31D5CM=F-G#V71VCbR7vcgD0Ey9EhzmpjBt~~3E)W5b z7~O@qKmiEnh5e|FS^8ti;WpB>~FekUcud%a$tm-qR2KhOTb z6`o%Sh5~_LAP^ElqYy%?VIjO4ibU4eBay9WG`b~C!!5!s^L!{6+6ad?HrIr;&4p!e zkDs=;-2uCfVwyf43@?bVOg2f-!wFoXTP}(SwD|J_Qb)>ml}T@-}tsV{Q4LB CV)H-% literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/silverBackgroundTableTitle.jpg b/gulliver/js/maborak/core/images/silverBackgroundTableTitle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8357f9b56c7bd7e1d51991563663d0a6639ba9d GIT binary patch literal 296 zcma)%O$x#=5Jtb)B&}&`6Ou}4yKv*KcW@z;>aD~xcoPrc!UG6y{MmSun7AldH$E5` z-oQ6A?&e-l+iuf=cv{i|?uj)xrIb<57@u-qX~KDuN+D7qq>>+$oaHK?Nn@-vrm5?? zSqy{_631~Svr?(DDs)i|!+#rhf=*CEMnq$xNu-H8V;)Y$7cB94xE^=?^1^WF?cUwrCuk=) literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/star.gif b/gulliver/js/maborak/core/images/star.gif new file mode 100755 index 0000000000000000000000000000000000000000..32633e30d43c43e8b412b7d47a80e2bd40c9a052 GIT binary patch literal 1120 zcmcJM{WIHl0DwOdny;5OK}77ZWYMi!dPHkp)=YF+5;fwbtgUU->6O~9Gwsb?Z;OaT zN=`_IzHE0fF)yvD)ltWqdRsQMF)`83d%P?Z^_B$re7F7)dwzcI`Q>4AKMV;?^8jbS z0sz~hlW>2=FgvFk9=583_kR5x9lW)mitj~JkPo|51*ZeYl@xnFt{jylT{Y=Eok0^FKb`u$KldBbnp_Kird%M z!qpzLiUr61liT4|I{cln*A~0DuweN)0dDJeTcV+91CD(KO?TlAAI@Z$Os2K9wVl#X zbW(v%<(U+baOIQz&IEJa$GeZOSq)ENUpUmo!L4j)S%UjUxZ43uayTJIwc&815zb~= z4PDUu_ul9|xIP3|A46j$8U+3is1{or97qR#uj8+u036CE3JQdUBC(i#v#3PK=Fk{q zsg#TmE7*!6JYK-y+!3)!w*@3zZ8Z^35_0Hx@-M}bQo2$|qIc2}n!JFG!y`U)#vKN& zmfhFVNF3-cAHGL=BEVyYD{zHRk%kgBeM*d5P|#`8e-?|{6|_f1BT~+`m@_NIufOWg zZw%Im3vms$NUo5gN3P5KkSasEvRT5mjV6kEaYu>^!oKl5Tb#nZawMUFc->{5X5*H8 zF+%0+qlyu5mM*Z295RK|tjs>EDsUhpZ#>Vnb(9?NKVRV)x-iFNIL#5g$Z2V6Kz=)? zXf$vIJiyU>-)l*oNq4iqh|cBAyhRn^k`TKLoq^@#ZpX)Bo0w$8E>U-)6^X7|7yVY6 z%p(AT9Qb&L=m^JH4*AdG6R%cvCTMLW-n`sT?^kaV$tRu5Iv&=vN?x={d1T&gUWaoa z@kCSLkL_-@UG-l2_)e}XqNNt8xiK!zONmh_zAfo&$w)BQOWlGk7Gsqd1#&gyhA)2Q zpu^=WH$6hXAjZ(*w(5?G4Ae9&H)G#lMf&#G;ks$TFr~db2xCyWxYTRpe>zw42#WkY zv#i@OvbS4F)87DU+`NYFm}E$u#@Yw?P}7MFC+z?eb1=cl-p4Z)xJEF_1euqvRXYf^ zHS4S{jC%^dM;`J4U}3ZRYLbs12mpr}^}JcDp5cjol_C6qv5mmM}ObfxAR zyG5(A2>My!h`*=Jl&r|DT!p z?|Sj=8#jMnUGwM0vVV8m@87%k@7|2Z4<0^w^!V?CUC*CA`}^p~-zR(jJ~{XL)vMR9 zUjKV{`2G9$|2~}k`~K;_4|hL*`t;@Vm+#-d|NH*w-_IBSetiD-@9TfuK=Gfbb5Uwy zNotBhd1gt5LP$ocg1e`00D}$#5P&?%!1nLJ>;jKHC;N^rDbfh;4cWA`ou^`C~SxJ-*eR*r#|lBA@86!QcQ zJtu>yTJ3IrCFXjvY%DCSi&*)ERNPc6j3UjY*cY>MZsO$LDrc^2kfRyMwRsEYVjdn* zQ{^=-hR5{g(B$DOb1{C@33qFx^|QfK^SiH(Ei#bp4`D+`Q_lO4pOc%@6bN z@d^J@jQ`|nAer}Kv%`i5ZPGGHKAjg^71~72qgpmJJapr14f=NHhrl5=ZoZW{7j^`u zbM**0yL5O=d=xXyD>&?KK;nxNf?}Fp8$NvRU&=RC$?Pagtn-!?7ZsPN{zk2=t{rk_KK7IN8 z<@@*V|B-;=KT+qR)Wnk16ovB4k_?5Aj8p}8Pu~Cr9R?r(8Op#iZNf><)qBe`&%AVU zTUavJ$l#e%(s4!66Ir@VTAZD_#_bM@jm=3rPS!9Pb}1a-;o(_)QmIgafvGk0U_x|A ztM#!kEw0ZjfhQXU%v81RHTG@h*rU&Bt(oxR$$JS86*fdEv tCUz^9Npj4AY&8l@EXu62gBEkMEDqveHCQIRcD=D{$=0+TJGBKFtO0CcZFK+u literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/core/images/tabs_li_bg.gif b/gulliver/js/maborak/core/images/tabs_li_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..79be4504b84e363840fd8bb111f30adb7d1a6213 GIT binary patch literal 2349 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 uA>nH3%0FV7c}h70U +* Version : 0.6 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +var maborak = function(){ + this.info={ + version :"0.3", + name :"maborak", + file :"maborak.js" + }, + /** + * Make this Class + * @param options = Object{Options.for.class} || {}; + * @access = Public; + */ + this.make=function(options) + { + this.protoCore(); + this.module={ + debug:function(flag){ + this.flag = flag || false; + this.log=function(v) + { + if(typeof console!='undefined' && this.flag===true) + { + console.log(v || ''); + } + }; + return this; + } + }.expand(this); + this.options={ + thisIsNotPM:false + }.concat(options || {}); + this.report = new this.bitacora(); + this.loadMethods([this.checkBrowser],this); + this.event = this.factory(this.mantis,true); + this.tools = this.factory(this.extended.tools,true); + this.file = this.factory(this.fileCore,true); + this.dom = this.factory(this.extended.D0M,true); + this.iphone = this.factory(this.iphoneBrowser,true); + this.cookie = this.factory(this.extended.cookie,true); + this.Package = new this.PackageCore(this,this.file.db); + + this.report.add("Class loaded."); + this.info.base=this.tools.baseJS(this.info.file); + this.info.images=this.info.base+"images/"; + this.path_root=this.tools.path_root(this.info.base)+"/"; + + if(this.options.modules){ + this.Package.Load(this.options.modules,{Instance:this,Type:"module"}); + } + if(this.options.files){ + this.Package.Load(this.options.files,{Type:"file"}); + } + this.exec(this.fix.memoryLeak); + + /* create Stylesheet BEGIN */ + var st =$dce('link'); + st.rel ='stylesheet'; + st.type ='text/css'; + st.href =this.info.base+'stylesheet/default.css'; + this.dom.capture("tag.head 0").appendChild(st); + /* create Stylesheet END */ + this.expand(this); + return this; + }; + this.factory=function(Class,create) + { + var cl = (typeof Class==="function")?Class:function(){}; + cl.prototype.parent = this; + if(create===true) + { + //return new cl().expand(); + return new cl(); + } + else + { + return cl; + } + }, + this.Class=function() + { + var Vc = function(){}; + return new Vc(); + }, + /** + * @class Manage Patterns Design + */ + this.pattern={ + observer:function(event) + { + this.event = event; + this.g="aaa"; + this.db = []; + this.register=function(launch,Class) + { + this.event = event; + this.Class = Class; + this.launch = launch; + if(this.verify()) + { + return this.write(); + } + return true; + }; + this.verify=function() + { + return (typeof this.launch==="function")?true:false; + }; + this.write=function() + { + var cap = { + //update:this.parent.closure({instance:this,method:this.update}), + //unregister:this.parent.closure({instance:this,method:this.unregister,args:this.db.length}) + update:this.update, + unregister:this.unregister.args(this.db.length) + }; + this.db.push(this.launch); + if(this.Class) + { + this.Class.observer = cap; + } + delete this.event; + delete this.Class; + delete this.launch; + return this.db.length-1; + }; + this.update=function() + { + var ln = this.db.length; + for(i=0;i 0 ) { range = range % l; } + else { i = range; range = l + range % l; } + return this[ Math.floor( range * Math.random() - i ) ]; + }; + /** + * Map array elements + * @param {Function} fun + * @return Function + */ + Array.prototype.map = function(fun) + { + if(typeof fun!=="function"){return false;} + var i = 0, l = this.length; + for(i=0;i]+>/gi, ''); + }; + /** + * Convert special characters to HTML entities + * @return String + */ + String.prototype.escapeHTML = function() + { + var div = $dce('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }; + /** + * Convert special HTML entities back to characters + * @return String + */ + String.prototype.unescapeHTML = function() + { + var div = $dce('div'); + div.innerHTML = this.trim(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }; + /** + * Search and Replace + * @return String + */ + String.prototype.sReplace = function(search,replace) + { + search = search || ""; + replace= replace || ""; + var re = new RegExp(search,"g"); + return this.replace(re,replace); + }; + /** + * Camelize String (text-align -> textAlign) + * @return String + */ + String.prototype.camelize = function () + { + var oStringList = this.split("-"); + if (oStringList.length == 1) { + return oStringList[0]; + } + var camelizedString = this.indexOf("-")===0 ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) : oStringList[0]; + for (var i = 1, len = oStringList.length; i < len; i++) + { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + return camelizedString; + }; + /** + * Convert String to Array + * @return Array + */ + String.prototype.toArray = function() + { + return this.split(""); + }; + /** + * extract script fragment + * @return String + */ + String.prototype.extractScript = function() + { + var matchAll = new RegExp(tagScript, 'img'); + return (this.match(matchAll) || []); + }; + /** + * Eval script fragment + * @return String + */ + String.prototype.evalScript = function() + { + return (this.match(new RegExp(tagScript, 'img')) || []).evalScript(); + }; + /** + * strip script fragment + * @return String + */ + String.prototype.stripScript = function() + { + return this.replace(new RegExp(tagScript, 'img'), ''); + }; + /** + * XMLSerializer Crossbrowser + */ + if((typeof XMLSerializer)==='undefined') + { + window.XMLSerializer = function() { + this.toString=function() + { + return "[object XMLSerializer]"; + }; + this.serializeToString=function(xml){ + return xml.xml || xml.outerHTML || "Error XMLSerializer"; + }; + }; + } + }; + /** + * Load methods + * @param methods = Array[Method || Array[Method,[Argument1,Argument2,...],return]]; + * @param instance= Class; + * @example: + * this.loadMethods([ + * this.proto, + * [this.checkBrowser,['argument1',More...,12]] + * ],this); + * @access = Public; + */ + this.loadMethods = function(methods,instance) + { + var _return_ = []; + var tmp; + for(var i=0;i=0)?true:false), + isNS:((userAgent.indexOf('Netscape6/')>=0)?true:false), + isFF:((userAgent.indexOf('Firefox')>=0)?true:false), + isSF:((userAgent.indexOf('Safari')>=0)?true:false), + isGK:((userAgent.indexOf('Gecko')>=0)?true:false), + isIphone:((userAgent.indexOf('iPhone')>=0)?true:false), + isOP:((userAgent.indexOf('Opera')>=0)?true:false) + }; + this.browser.isIE=(this.browser.isOP)?false:this.browser.isIE; + var checkFor=["MSIE","Netscape/6","Firefox","Safari","Gecko","Opera","iPhone"]; + for(var i=0;i 0) + { + if(this.db[0] && this.db[0].isObject===true) + { + this.remove(this.db[0]._object_,this.db[0]._event_,this.db[0]._function_,this.db[0]._bumble_); + } + this.db.splice(0,1); + } + }; + /** + * Add new Event; + * @param _object_ = DOMelement; + * @param _event_ = event [load,focus,etc]; + * @param _function_ = Function || Object{method,instance,[arguments[Array],event[Boolean],argument_is_array[Boolean]]} || Function[virtual]; + * @param _bumble_ = true || false; + * @example: + * + * 1) Callback simple: + * this.event.add(Input,"unload",FunctionX); + * + * 2) Callback is Object + * this.event.add(Input,"click",{ + * method : this.other, + * instance: this + * }); + * 3) Callback is Object & Advanced options + * this.event.add(Input,"click",{ + * method : this.other, + * instance: this + * arguments:[989898,767676], //Arguments to Function Callback + * event :true // es| Expandir evento como argumento + * }); + * 4) Callback to Virtual Instance + * this.event.add(Input,"click",leimnud.closure({ + * method:this.changes, + * instance:this, + * arguments:98989898 + * })); + * 5) Callback to Virtual Function + * this.event.add(Input,"click",leimnud.closure({ + * Function:foo, + * arguments:[bla,99] + * })); + */ + this.add=function(_object_,_event_,_function_,_bumble_) + { + _function_=(_function_.isObject)?this.parent.closure(_function_):_function_; + _object_ = this.parent.dom.element(_object_); + if (_object_.addEventListener) + { + _object_.addEventListener(_event_,_function_,((_bumble_===true)?true:false)); + } + else if(_object_.attachEvent) + { + _object_.attachEvent("on"+_event_,_function_); + } + else + { + this.report("Event registration not supported"); + } + var event = { + _object_ :_object_, + _event_ :_event_, + _function_ :_function_, + _bumble_ :((_bumble_===true)?true:false) + }; + this.db.push(event); + return (this.db.length-1); + }; + /** + * Remove Event; + * @param {DOM Object} _object_ = DOMelement; + * @param {event} _event_ = event [load,focus,etc]; + * @param {Function} _function_ = Function || Object{method,instance,[arguments[Array],event[Boolean],argument_is_array[Boolean]]} || Function[virtual]; + * @param {Boolean} _bumble_ = true || false; + * @example: + * Add new Event Examples. + */ + this.remove=function(_object_,_event_,_function_,_bumble_,uidInDB) + { + _function_=(_function_.isObject)?this.parent.closure(_function_):_function_; + _object_ = this.parent.dom.element(_object_); + if (_object_.removeEventListener) + { + _object_.removeEventListener(_event_,_function_,((_bumble_===true)?true:false)); + } + else if(_object_.detachEvent) + { + _object_.detachEvent("on"+_event_,_function_); + } + if(uidInDB) + { + if(uidInDB==(this.db.length-1)) + { + this.db.pop(); + } + else + { + this.db[uidInDB]=null; + } + } + }; + /** + * es| Remover evento basado en Uid + */ + this.removeFromUid=function(uid) + { + if(this.db[uid]) + { + var e = this.db[uid]; + this.remove(e._object_,e._event_,e._function_,e._bumble_,uid); + } + }; + /** + * Flush Collection events from DB + * @param {Array} arrayEventsInDB Array of Events. + */ + this.flushCollection=function(arrayEventsInDB) + { + var l=arrayEventsInDB.length; + for(i=0;i 0; i--) + { + this.name = this.toLoad[this.toLoad.length - i]; + if (!this.isset()) { + tl.push(this.name); + this.write(false); + } + } + //alert(this.parent.options.thisIsNotPM); + if (tl.length > 0) { + var script = $dce("script"); + this.parent.dom.capture("tag.head 0").appendChild(script); + script.src = (this.parent.options.inGulliver===true)?this.path+'maborak.loader.js':this.path + 'server/maborak.loader.php?load=' + tl.join(','); +// script.src = this.path + 'maborak.loader.js'; +// alert(script.src) + script.type = "text/javascript"; + script.charset = this.parent.charset; + if (this.type == "module") { + this.write(script); + } + } + } + else + { + for (var i = this.toLoad.length; i > 0; i--) + { + this.name = this.toLoad[this.toLoad.length - i]; + if (!this.isset()) { + //if (this.options.noWrite === false && this.type!='module') + //{ + this.src = this.source(); + var script = $dce("script"); + this.parent.dom.capture("tag.head 0").appendChild(script); + //script.src = this.src+"?d="+Math.random(); + script.src = this.src; + script.type = "text/javascript"; + script.charset = this.parent.charset; + //} + if (this.type == "module") { + this.write(script); + } + } + } + } + delete this.Class; + delete this.file; + delete this.info; + delete this.path; + delete this.toLoad; + delete this.type; + delete this.src; + return true; + }; + /** + * es| Obtener la ruta del archivo,modulo a cargar + * + * @access = Private; + */ + this.source=function() + { + if(this.type=="module") + { + return this.path+"module."+this.name+".js"; + } + else if(this.type=="file") + { + var nroute= (this.options.Absolute===true)?this.path:this.path+this.name+"/core/"+this.name+".js"; + return nroute; + } + return false; + }; + /** + * Probe conditions + * + * @access = Private; + */ + this.check = function() + { + if(!this.db || !this.options.Type){ + return false; + } + this.type = this.options.Type.toLowerCase(); + if(this.type=="file") + { + this.path = this.options.Path || this.parent.path_root; + return true; + } + else if(this.type=="module") + { + this.Class=(this.options.Instance)?this.options.Instance:((this.options.Class)?this.options.Class.prototype:false); + if(this.Class===false || !this.Class.info){return false;} + if(!this.Class.module) + { + this.Class.module={}; + } + this.path = this.options.Path || this.Class.info.base || false; + return (this.path===false)?false:true; + } + else + { + return false; + } + }; + /** + * Prevent duplicate + * + * @access = Private; + */ + this.isset = function() + { + if(this.type=="module") + { + for(var i=this.db.length;i>0;i--) + { + if(this.db[this.db.length-i].name==this.Class.info.name) + { + this.file=this.db[this.db.length-i]; + break; + } + } + if(!this.file) + { + this.db.push({ + name:this.Class.info.name, + Class:this.Class, + _Package_:[] + }); + this.file=this.db[this.db.length-1]; + } + for(i=this.file._Package_.length;i>0;i--) + { + var nm=this.file._Package_[this.file._Package_.length-i]; + if(nm.name==this.name && nm.type==this.type) + { + return true; + } + } + this.Class.module[this.name]=true; + return false; + } + else if(this.type=="file") + { + return false; + } + return false; + }; + this.write = function(script,option) + { + this.file._Package_.push({ + type :this.type, + loaded :false, + name :this.name, + script :script, + onLoad :this.options.onLoad || false + }); + }; + this.Public = function(Package) + { + if(!Package || !Package.info || !Package.info.Class || !Package.info.Name || !Package.info.Type || !Package.content){return false;} + for(var i=this.db.length;i>0;i--) + { + if(this.db[this.db.length-i].name==Package.info.Class) + { + this._file_=this.db[this.db.length-i]; + break; + } + } + if(!this._file_) + { + return false; + } + else + { + this.tmpPgk=this._file_.Class.module[Package.info.Name]; + if(this.tmpPgk===true) + { + if(typeof Package.content=="function") + { + Package.content.prototype.parent=this._file_.Class; + } + else if(typeof Package.content=="object") + { + Package.content.setParent(this._file_.Class); + //alert(Package.content+":"+this._file_.Class) + } + this._file_.Class.module[Package.info.Name]=Package.content; + for(i=this._file_._Package_.length;i>0;i--) + { + var nm=this._file_._Package_[this._file_._Package_.length-i]; + if(nm.name==Package.info.Name && nm.type==Package.info.Type) + { + nm.loaded=true; + if(!this.parent.browser.isIE) + { + this.parent.dom.remove(nm.script); + } + delete nm.script; + if(nm.onLoad) + { + nm.onLoad(); + } + break; + } + } + delete this._file_; + } + } + return true; + }; + }; + this.fileCore =function() + { + this.db = []; + }; + this.extended={ + cookie:function() + { + this.set = function(name, value, days, path, domain, secure) + { + var expires = -1; + if(typeof days == "number" && days >= 0) { + var d = new Date(); + d.setTime(d.getTime()+(days*24*60*60*1000)); + expires = d.toGMTString(); + } + value = escape(value); + document.cookie = name + "=" + value + ";" + + (expires != -1 ? " expires=" + expires + ";" : "") + + (path ? "path=" + path : "") + + (domain ? "; domain=" + domain : "") + + (secure ? "; secure" : ""); + }; + this.get = function(name) + { + var idx = document.cookie.lastIndexOf(name+'='); + if(idx == -1) { return null; } + var value = document.cookie.substring(idx+name.length+1); + var end = value.indexOf(';'); + if(end == -1) { end = value.length; } + value = value.substring(0, end); + value = unescape(value); + return value; + }; + this.del = function(name) + { + this.set(name, "-",0); + }; + }, + tools:function() + { + this.baseURL =function() + { + return window.location; + }; + this.path_root =function(jsPath) + { + if(this.parent.browser.isIE) + { + //alert(jsPath) + return jsPath+"../.."; + } + else + { + var a = jsPath.split("/"); + a.pop(); + a.pop(); + a.pop(); + return a.join("/"); + } + }; + this.baseJS =function(js) + { + var Isrc="",script = document.getElementsByTagName('script'); + for (var i=script.length-1; i>=0; i--){ + if (script[i].src && (script[i].src.indexOf(js) != -1)) + { + Isrc = script[i].src; + Isrc = Isrc.substring(0, Isrc.lastIndexOf('/')); + this.parent.info.domBaseJS=script[i]; + break; + } + } + return Isrc+"/"; + }; + this.head=function() + { + return document.getElementsByTagName("HTML")[0].getElementsByTagName("HEAD")[0]; + }; + this.createUID=function() + { + return Math.random(); + }; + this.expand(this); + }, + /** + * @class Manage DOM elements + * @param {Object} parent Leimnud instance + */ + D0M:function() + { + this.get_html=function() + { + return document.getElementsByTagName('html')[0]; + }; + this.get_doc=function(){ + var doc = window.document; + return (!doc.compatMode || doc.compatMode == 'CSS1Compat')?this.get_html():doc.body; + }; + /** + * Capture DOM object from (String || DOM element) + * @param {string || object} element String.id || DOM object + * @return DOM object + */ + this.element=function(element) + {//return document.getElementById(element); +// return (!element)?false:((typeof element=="object")?element:(($(element))?$(element):false)); + return (!element)?false:((typeof element=="object")?element:((document.getElementById(element))?document.getElementById(element):false)); + }; + /** + * Remove Elements + * @param {DOM || Array.DOM} DOM Elements + */ + this.remove=function(DOM){ + DOM = (DOM.isArray || (DOM.isObject && !DOM.appendChild))?DOM:[DOM]; + for(var i in DOM) + { + if(DOM.propertyIsEnumerable(i)) + { + if(DOM[i].isObject && !DOM[i].appendChild) + { + this.remove(DOM[i]); + } + else + { + var element=this.element(DOM[i]); + if(element && element.parentNode) + { + element.parentNode.removeChild(element); + } + } + } + } + return true; + }; + /** + * Automate DOM || HTMLCollection => ArrayDOMCollection + * @param {string || DOM} DOM DOM || HTMLCollection + * @param {Array} style ArrayDOMCollection + */ + this.automateDOMToCollection = function(DOM) + { + return ((!DOM.isArray && (DOM.isObject || (this.parent.browser.isIE && !DOM.isObject))) || DOM.isArray)?DOM:[DOM]; + }; + /** + * Apply styles to DOM object + * @param {string || DOM} DOM String.id || DOM object + * @param {object} style es| Objeto con valores de estilo + */ + this.setStyle = function(DOM,styles) + { + DOM = (DOM.isArray)?DOM:[DOM]; + var sizeInPixel=["width","height","left","top","right","bottom", + "margin","marginLeft","marginRight","marginTop","marginBottom","marginLeftWidth","marginRightWidth","marginTopWidth","marginBottomWidth", + "padding","paddingLeft","paddingRight","paddingTop","paddingBottom","paddingLeftWidth","paddingRightWidth","paddingTopWidth","paddingBottomWidth", + "borderLeftWidth","borderRightWidth","borderTopWidth","borderBopttomWidth" + ]; + for(var j=0;jr.x2))?p2.x:r.x2; + r.y2=(!r.y2 || (p2.y>r.y2))?p2.y:r.y2; + } + return r; + }; + /** + * DOM elements, Fix positions if out of range + * @param {DOM || Array[DOM]} DOM Elements + * @param {Object} range Current range + */ + this.positionRangeFix = function(DOM,range) + { + DOM = (DOM.isArray)?DOM:[DOM]; + var r={}; + for(var i=0;i-1){ + return false; + } + } + var script = $dce("script"); + this.capture("tag.head 0").appendChild(script); + script.src = file; + script.type = "text/javascript"; + script.charset = this.parent.charset; + return true; + }; + this.getPageScroll=function() + { + return [window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop]; + }; + this.getPageSize = function() + { + var xScroll, yScroll; + if (window.innerHeight && window.scrollMaxY) { + xScroll = window.innerWidth + window.scrollMaxX; + yScroll = window.innerHeight + window.scrollMaxY; + } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac + xScroll = document.body.scrollWidth; + yScroll = document.body.scrollHeight; + } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari + xScroll = document.body.offsetWidth; + yScroll = document.body.offsetHeight; + } + + var windowWidth, windowHeight; + + if (self.innerHeight) { // all except Explorer + if(document.documentElement.clientWidth){ + windowWidth = document.documentElement.clientWidth; + } else { + windowWidth = self.innerWidth; + } + windowHeight = self.innerHeight; + } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode + windowWidth = document.documentElement.clientWidth; + windowHeight = document.documentElement.clientHeight; + //alert(windowHeight); + } else if (document.body) { // other Explorers + windowWidth = document.body.clientWidth; + windowHeight = document.body.clientHeight; + } + + // for small pages with total height less then height of the viewport + if(yScroll < windowHeight){ + pageHeight = windowHeight; + } else { + pageHeight = yScroll; + } + + // for small pages with total width less then width of the viewport + if(xScroll < windowWidth){ + pageWidth = xScroll; + } else { + pageWidth = windowWidth; + } + return [pageWidth,pageHeight]; + }; + this.serializer = this.parent.factory(function(DOM,obj) + { + /** + * Serialize form Element + * @param {FormElement} form + * @return {String} serialized + */ + this.DOM = DOM; + this.inObject = (obj===true)?true:false; + this.serialized = (this.inObject)?{}:""; + this.parse=function() + { + + }; + this.rake = function(val) + { + if(!val){return val;} + if(typeof val==="object") + { + this.serialized.concat(val); + } + else + { + this.serialized+=val; + } + return true; + }; + this.form = function() + { + var form = this.DOM; + var serializeds = []; + serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("input"),this.inObject).input()); + serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("select"),this.inObject).select()); + serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("textarea"),this.inObject).textarea()); + for (var i=0;ithis.options.x1)?true:false), + t:((this.options.y2this.options.y1)?true:false) + }; + return d; + }; + this.createLines=function() + { + return (this.direction.t)?5:3; + }; + this.kase=function() + { + var kase; + if(this.options.y2>this.options.y1 && this.options.x2this.options.y2 && this.options.x2<=this.options.x1) + { + kase=2; + } + else if(this.options.y2>this.options.y1 && this.options.x2>this.options.x1) + { + kase=3; + } + else if(this.options.y1>this.options.y2 && this.options.x2>this.options.x1) + { + kase=4; + } + else if(this.options.y2>this.options.y1 && this.options.x1 === this.options.x2) + { + kase=1; + } + //alert(kase) + //window.status=kase; + return kase; + }; + this.paint=function() + { + this.rootSize=this.options.indexRootSize || 15; + this.rootLastSize=this.options.indexRootLastSize || 15; + this.codo=[]; + var height0=((this.options.y2-this.options.y1)/2); + this.codo[0]={x:this.options.x1,y:(this.options.y1+height0)}; + this.codo[1]={x:this.options.x2,y:this.codo[0].y}; + if(this.kase()==1) + { + this.parent.dom.setStyle(this.elements[0],{ + height:height0, + top:this.options.y1, + left:this.codo[0].x + }); + this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[0].x-this.codo[1].x, + top:this.codo[1].y, + left:this.codo[1].x + }); + this.parent.dom.setStyle(this.elements[2],{ + top:this.codo[1].y, + left:this.codo[1].x, + height:height0 + }); + + } + else if(this.kase()==3) + { + this.parent.dom.setStyle(this.elements[0],{ + height:height0, + top:this.options.y1, + left:this.codo[0].x + }); + this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[1].x-this.codo[0].x, + top:this.codo[0].y, + left:this.codo[0].x + }); + this.parent.dom.setStyle(this.elements[2],{ + top:this.codo[1].y, + left:this.codo[1].x, + height:height0 + }); + } + else if (this.kase()==2) + { + this.codo[0]={x:this.options.x1,y:(this.options.y1+this.rootSize+1)}; + this.codo[3]={x:this.options.x2,y:(this.options.y2-this.rootLastSize)}; + //this.codo[2]={x:this.codo[3].x-((this.options.elements[1].offsetWidth/2)+this.rootSize),y:this.codo[3].y}; + //this.codo[1]={x:this.codo[2].x,y:this.codo[0].y}; + this.codo[2]={x:this.codo[0].x+((this.options.elements[0].offsetWidth/2)+this.rootSize),y:this.codo[3].y}; + this.codo[1]={x:this.codo[2].x,y:this.codo[0].y}; + this.parent.dom.setStyle(this.elements[0],{ + height:(this.codo[0].y-this.options.y1)+1, + top:this.options.y1, + left:this.options.x1 + }); + this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[1].x-this.codo[0].x, + top:this.codo[0].y, + left:this.codo[0].x + }); + /*this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[0].x-this.codo[1].x, + top:this.codo[1].y, + left:this.codo[1].x + });*/ + this.parent.dom.setStyle(this.elements[2],{ + top:this.codo[2].y, + left:this.codo[2].x, + height:this.codo[1].y-this.codo[2].y + }); + this.parent.dom.setStyle(this.elements[3],{ + top:this.codo[3].y, + left:this.codo[3].x, + width:this.codo[2].x-this.codo[3].x + }); + /*this.parent.dom.setStyle(this.elements[3],{ + top:this.codo[2].y, + left:this.codo[2].x, + width:this.codo[3].x-this.codo[2].x + });*/ + this.parent.dom.setStyle(this.elements[4],{ + top:this.codo[3].y, + left:this.codo[3].x, + height:this.options.y2-this.codo[3].y + }); + } + else if (this.kase()==4) + { + this.codo[0]={x:this.options.x1,y:(this.options.y1+this.rootSize)}; + this.codo[3]={x:this.options.x2,y:(this.options.y2-this.rootLastSize)}; + //this.codo[2]={x:this.codo[3].x+((this.options.elements[1].offsetWidth/2)+this.rootSize),y:this.codo[3].y}; + //this.codo[1]={x:this.codo[2].x,y:this.codo[0].y}; + this.codo[2]={x:this.codo[0].x-((this.options.elements[0].offsetWidth/2)+this.rootSize),y:this.codo[3].y}; + this.codo[1]={x:this.codo[2].x,y:this.codo[0].y}; + this.parent.dom.setStyle(this.elements[0],{ + height:this.codo[0].y-this.options.y1, + top:this.options.y1, + left:this.options.x1 + }); + this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[0].x-this.codo[1].x, + top:this.codo[1].y, + left:this.codo[1].x + }); + /*this.parent.dom.setStyle(this.elements[1],{ + width:this.codo[1].x-this.codo[0].x, + top:this.codo[0].y, + left:this.codo[0].x + });*/ + this.parent.dom.setStyle(this.elements[2],{ + top:this.codo[2].y, + left:this.codo[2].x, + height:this.codo[1].y-this.codo[2].y + }); + this.parent.dom.setStyle(this.elements[3],{ + top:this.codo[2].y, + left:this.codo[2].x, + width:this.codo[3].x-this.codo[2].x + }); + /*this.parent.dom.setStyle(this.elements[3],{ + top:this.codo[3].y, + left:this.codo[3].x, + width:this.codo[2].x-this.codo[3].x + });*/ + this.parent.dom.setStyle(this.elements[4],{ + top:this.codo[3].y, + left:this.codo[3].x, + height:this.options.y2-this.codo[3].y + }); + } + var im = this.elements[5]; + //alert(this.elements[5]) + this.parent.dom.setStyle(im,{ + top:this.options.y2-7, + left:this.options.x2-4 + }); + }; + this.update=function() + { + if(this.changed()) + { + //alert(9) + this.options.concat(this.coords()); + if(this.kase()%2===0) + { + this.elements[3].style.visibility="visible"; + this.elements[4].style.visibility="visible"; + } + else + { + this.elements[3].style.visibility="hidden"; + this.elements[4].style.visibility="hidden"; + } + this.paint(); + } + }; + this.expand(this); + }, + menuRight:function(options){ + this.elements = {}; + this.make=function(options) + { + this.options = { + bubble:true, + theme :"firefox" + }.concat(options || {}); + if(!this.validate()){return false;} + if(this.options.auto_event){return false;} + this.parent.event.add(this.options.targetRemove || this.options.target,"click",this.updateObservers); + //this.parent.event.add(this.options.target,"click",this.parent.closure({instance:this,method:this.updateObservers,event:true})); + //this.parent.event.add(document.body,"click",this.parent.closure({instance:this,method:this.remove})); + //this.parent.event.add(this.options.target,"contextmenu",function(){return false;}); + //this.options.target.oncontextmenu=this.parent.closure({instance:this,method:this.menu,event:true}); + this.options.target.oncontextmenu=this.menu; + }; + this.menu=function(evt) + { + this.evt = evt || this.options.auto_event || false; + this.updateObservers(); + this.parent.dom.bubble(false,this.evt); + //this.remove(); + this.maked=true; + this.cursor = (this.options.auto_event)?this.options.auto_position:this.parent.dom.mouse(this.evt); + this.positionTarget = this.parent.dom.position(this.options.target); + this.elements.shadow = $dce("div"); + this.elements.shadow.className = "app_menuRight_shadow___"+this.options.theme; + this.elements.container = $dce("div"); + this.elements.container.className = "app_menuRight_container___"+this.options.theme; + this.parent.dom.setStyle(this.elements.container,{ + width:this.options.width || 150, + left:this.cursor.x-5, + top:this.cursor.y-5 + }); + this.parent.dom.capture("tag.body 0").appendChild(this.elements.shadow); + this.parseOptionsMenu(); + this.parent.dom.capture("tag.body 0").appendChild(this.elements.container); + this.parent.dom.setStyle(this.elements.shadow,{ + width : this.elements.container.clientWidth, + height : this.elements.container.clientHeight, + left : this.cursor.x-((this.parent.browser.isIE)?1:3), + top : this.cursor.y-((this.parent.browser.isIE)?1:3) + }); + this.parent.dom.nullContextMenu([this.elements.container]); + return false; + }; + this.parseOptionsMenu=function() + { + var ii=0; + for(var i=0;ithis.options.images.length-1)?0:index; + index = (index<0)?this.options.images.length-1:index; + this.current = index; + this.setLoad(); + var image = new Image(); + image.onload=this.show.args(image); + image.src=this.options.images[index]; + if(this.options.counter) + { + this.domCounter.innerHTML=""+(index+1)+" de "+(this.options.images.length-1)+""; + } + }; + this.show=function(evt,image) + { + image = arguments[1] || arguments[0]; + if(this.options.resize) + { + this.panel.resize({w:image.width+10,h:image.height+50}); + this.panel.center(); + } + this.image.src=image.src; + this.unsetLoad(); + if(this.inPlay) + { + setTimeout(this.control.next,5000); + } + }; + this.setLoad=function() + { + this.image.style.display="none"; + this.panel.elements.content.style.borderWidth=1; + this.panel.loader.show(); + }; + this.unsetLoad=function() + { + this.panel.elements.content.style.borderWidth=0; + this.panel.loader.hide(); + this.image.style.display=""; + }; + this.buttons=function() + { + var target = this.panel.elements.statusBar; + var end = $dce("div"); + this.parent.dom.setStyle(end,{ + right :5 + }); + var next = $dce("div"); + this.parent.dom.setStyle(next,{ + right :parseInt(end.style.right,10)+20 + }); + var play = $dce("div"); + this.parent.dom.setStyle(play,{ + right :parseInt(next.style.right,10)+20 + }); + var prev = $dce("div"); + this.parent.dom.setStyle(prev,{ + right :parseInt(play.style.right,10)+20 + }); + var begin = $dce("div"); + this.parent.dom.setStyle(begin,{ + right :parseInt(prev.style.right,10)+20 + }); + var title; + this.domTitle = title = $dce("div"); + var counter; + this.domCounter = counter= $dce("div"); + target.appendChild(end); + target.appendChild(next); + target.appendChild(play); + target.appendChild(prev); + target.appendChild(begin); + target.appendChild(title); + target.appendChild(counter); + this.parent.dom.setStyle([end,next,play,prev,begin,title,counter],{ + position:"absolute", + backgroundColor:"#006699", + top :3, + width :15, + height :15, + overflow:"hidden" + }); + this.parent.dom.setStyle([title,counter],{ + left :5, + backgroundColor:"white", + color :"black", + font :"normal 8pt Tahoma,MiscFixed" + }); + this.parent.dom.setStyle(counter,{ + left :"auto", + right :parseInt(begin.style.right,10)+30, + width :60 + }); + begin.onmouseup = this.control.first; + play.onmouseup = this.control.play; + prev.onmouseup = this.control.previous; + next.onmouseup = this.control.next; + end.onmouseup = this.control.last; + }; + this.control={ + play:function() + { + if(!this.inPlay) + { + this.control.next(); + } + this.inPlay=!this.inPlay; + }, + next:function(){ + this.load(this.current+1); + }, + previous:function(){ + this.load(this.current-1); + }, + first:function() + { + this.load(0); + }, + last:function() + { + this.load(this.options.images.length-1); + } + }.expand(this); + this.expand(this); + }, + slide:function() + { + + + this.inPlay = false; + this.last = false; + this.elements = {}; + this.stopped = false; + this.inM = 0; + this.make=function(options) + { + this.options = { + initIn : 0, + counter : true, + playTimeOut:3, + tactil : false, + target : document.body, + resize : true, + size : {w:522,h:363}, + position: {x:0,y:30,centerX:true}, + skin_images:this.parent.info.base+"images/app.slide/", + images:[] + }.concat(options || {}); + //510 - 310 + //90 - 65 + //alert(this.parent.info.base) + this.options.thumbnail = { + show:4, + size:{w:90,h:55}, + images:[] + }.concat(options.thumbnail || {}); + //alert(this.options.target) + this.windowImage(); + this.toolbarImage(); + this.image=$dce("img"); + this.panel.elements.content.appendChild(this.image); + this.load(this.options.initIn); + this.current=this.options.initIn; + //this.control.play(); + }; + this.windowImage=function() + { + this.panel = new this.parent.module.panel(); + //alert(this.options.target) + this.panel.options={ + size :this.options.size, + position :this.options.position, + target :this.options.target, + statusBar :false, + titleBar :false, + limit :true, + control :{drag:false,close:false}, + fx :{shadow:false,modal:true,opacity:true,rolled:false,rollWidth:150} + }; + this.panel.events={ + remove:function(){ + var el=[ + + this.domNext, + this.domPlay, + this.domPrev, + this.buttonNext, + this.domCounter, + this.domTitle, + this.domClose, + this.toolbar, + this.footer + ]; + if(this.options.banner) + { + el.push(this.banner); + } + new this.parent.module.fx.fade().make({ + duration:200, + end :0, + dom :el, + onFinish :function(el){ + this.parent.dom.remove(el); + }.extend(this,el) + }); + }.extend(this) + }; + this.panel.setStyle={ + content:{ + overflow : "hidden", + textAlign : "center", + verticalAlign: "center", + margin:10, + marginBottom:40, + border:"1px solid #fff" + }, + containerWindow:{ + border:"0px solid black", + backgroundColor:"transparent" + }, + modal:{ + backgroundColor:"black" + }, + shadow:{ + backgroundColor:"black" + }, + frontend:{ + background:"", + backgroundColor:"#ECECEC" + }, + backend:{ + backgroundColor:"transparent" + }, + titleBar:{ + background:"transparent" + }, + title:{ + textAlign : "left", + color : "white" + } + }; + this.panel.styles.fx.opacityModal.Static=90; + this.panel.make(); + if(this.options.tactil) + { + this.panel.elements.modal.onmouseup=this.panel.remove; + } + }; + this.toolbarImage=function() + { + this.toolbar = $dce("div"); + var div = $dce("div"); + var thu = this.options.thumbnail; + var g = this.options.thumbnail.images.length; + var h = 4-(g % 4); + var j = (h===4)?0:h; + var tw = ((thu.show*thu.size.w)+(thu.show*(4))); + //alert(tw) + this.toolbar.appendChild(div); + this.toolbar.scrollLeft=0; + this.options.target.appendChild(this.toolbar); + this.parent.dom.setStyle(this.toolbar,{ + position :"absolute", + border :"1px solid #666", + width :tw+((this.parent.browser.isIE)?4:0), + height :thu.size.h+((this.parent.browser.isIE)?8:4), + padding :1, + //backgroundColor:"#DFF2FD", + backgroundColor:"#000", + overflow :"hidden", + zIndex :this.panel.elements.containerWindow.style.zIndex+1 + }); + this.parent.dom.opacity(this.toolbar,80); + var w = (thu.size.w*(thu.images.length+j))+(4*(thu.images.length+j)); + //alert(w) + this.parent.dom.setStyle(div,{ + border :"0px solid blue", + overflow :"hidden", + width :w + }); + this.elements.thumbs=[]; + for(var i=0;ithis.options.images.length-1 || index<0) + { + if(this.inPlay) + { + this.control.play(); + } + return false; + } + //alert(55); + //index = (index>this.options.images.length-1)?0:index; + //index = (index<0)?this.options.images.length-1:index; + this.current = index; + //alert(this.current) + this.setLoad(); + this.domCounter.innerHTML="Foto "+(index+1)+" de "+this.options.images.length+""; + this.domTitle.innerHTML=" "+this.options.thumbnail.images[index].title || "Untitled"+"/b> "; + if(this.last!==false) + { + this.parent.dom.setStyle(this.elements.thumbs[this.last],{ + borderWidth:0, + margin:2 + }); + this.parent.dom.opacity(this.elements.thumbs[this.last],50); + } + this.parent.dom.setStyle(this.elements.thumbs[index],{ + border:"2px solid orange", + margin:0 + }); + this.parent.dom.opacity(this.elements.thumbs[index],100); + this.last=index; + var image = new Image(); + image.onload=this.show.args(image); + /*image.onload=function(){ + setTimeout(this.show.args(image),5000); + }.extend(this);*/ + image.src=this.options.images[index]; + this.panel.addContentTitle(this.options.thumbnail.images[this.current].title || ""); + }; + this.show=function(evt,image) + { + image = arguments[1] || arguments[0]; + if(this.options.resize) + { + this.panel.resize({w:image.width+10,h:image.height+50}); + this.panel.center(); + } + this.image.src=image.src; + this.unsetLoad(); + //alert(this.inPlay); + if(this.inPlay) + { + //alert(444); + setTimeout(this.control.next,this.options.playTimeOut*1000); + } + }; + this.setLoad=function() + { + this.image.style.display="none"; + this.parent.dom.opacity(this.image,0); + this.panel.loader.show(); + }; + this.unsetLoad=function() + { + //this.panel.elements.content.style.borderWidth=0; + this.panel.loader.hide(); + this.image.style.display=""; + new this.parent.module.fx.fade().make({ + duration :500, + end :1, + dom :this.image, + onFinish :function(){ + + }.extend(this) + }); + this.image.style.display=""; + }; + this.buttons=function() + { + var target = this.options.target; + this.footer = $dce("div"); + target.appendChild(this.footer); + this.buttonNext = $dce("div"); + var rr = this.panel.elements.containerWindow; + this.parent.dom.setStyle(this.footer,{ + position : "absolute", + background :"url("+this.options.skin_images+"background_bottom_dark.png) no-repeat", + width :524, + height :56, + top :this.panel.options.position.y+rr.offsetHeight, + left :this.panel.options.position.x, + zIndex :this.panel.elements.containerWindow.style.zIndex + }); + //alert(this.panel.options.position.y+rr.offsetHeight) + this.buttonPrevious = $dce("div"); + this.parent.dom.setStyle([this.buttonNext,this.buttonPrevious],{ + position : "absolute", + backgroundColor:"#006699", + width : 20, + cursor : "pointer", + height : this.toolbar.clientHeight, + zIndex : this.panel.elements.containerWindow.style.zIndex + }); + /*var play = $dce("div"); + this.parent.dom.setStyle(play,{ + right :parseInt(next.style.right,10)+20 + });*/ + //target.appendChild(this.buttonNext); + this.buttonNext.onmouseup=this.control.right; + this.buttonPrevious.onmouseup=this.control.left; + //target.appendChild(this.buttonPrevious); + + + + + /*var end = $dce("div"); + this.parent.dom.setStyle(end,{ + right :5 + }); + var begin = $dce("div"); + this.parent.dom.setStyle(begin,{ + right :parseInt(prev.style.right,10)+20 + });*/ + this.domNext = $dce("img"); + this.domNext.src = this.options.skin_images+"next_dark.png"; + this.domNext.onmouseover = function() + { + this.domNext.src = this.options.skin_images+"next_on_dark.png"; + }.extend(this); + this.domNext.onmouseout = function() + { + this.domNext.src = this.options.skin_images+"next_dark.png"; + }.extend(this); + this.parent.dom.setStyle(this.domNext,{ + position : "absolute", + //background:"url("+this.options.skin_images+"next.png)", + cursor :"pointer", + width :30, + height :56, + top :this.panel.options.position.y+rr.offsetHeight+1, + left :this.panel.options.position.x+295, + zIndex :this.panel.elements.containerWindow.style.zIndex+1 + }); + this.domPlay = $dce("img"); + this.control.setPlay(); + this.parent.dom.setStyle(this.domPlay,{ + position : "absolute", + //background:"url("+this.options.skin_images+"play.png)", + cursor :"pointer", + width :46, + height :56, + top :this.panel.options.position.y+rr.offsetHeight+1, + left :this.panel.options.position.x+239, + zIndex :this.panel.elements.containerWindow.style.zIndex+1 + }); + this.domPrev = $dce("img"); + this.domPrev.src = this.options.skin_images+"back_dark.png"; + this.domPrev.onmouseover = function() + { + this.domPrev.src = this.options.skin_images+"back_on_dark.png"; + }.extend(this); + this.domPrev.onmouseout = function() + { + this.domPrev.src = this.options.skin_images+"back_dark.png"; + }.extend(this); + this.parent.dom.setStyle(this.domPrev,{ + position : "absolute", + //background:"url("+this.options.skin_images+"back.png)", + cursor :"pointer", + width :30, + height :56, + top :this.panel.options.position.y+rr.offsetHeight+1, + left :this.panel.options.position.x+200, + zIndex :this.panel.elements.containerWindow.style.zIndex+1 + }); + + var counter; + this.domCounter = counter= $dce("div"); + this.domTitle = $dce("div"); + this.domClose = $dce("img"); + this.domClose.src=this.options.skin_images+"close.gif"; + this.parent.dom.setStyle(this.domClose,{ + cursor : "pointer" + }); + this.domClose.onmousedown=this.panel.remove; + + //target.appendChild(end); + target.appendChild(this.domNext); + target.appendChild(this.domPlay); + target.appendChild(this.domPrev); + //target.appendChild(begin); + //target.appendChild(title); + target.appendChild(this.domCounter); + target.appendChild(this.domTitle); + target.appendChild(this.domClose); + //counter.innerHTML="1 [b]/[/b] 12" + this.parent.dom.setStyle([counter,this.domTitle,this.domClose],{ + position:"absolute", + font :"normal 8pt Tahoma,MiscFixed", + //top :3, + //width :15, + //height :15, + color :"black", + overflow:"hidden", + zIndex : this.panel.elements.containerWindow.style.zIndex+1 + }); + /*this.parent.dom.setStyle(counter,{ + left :5, + backgroundColor:"white", + color :"black", + font :"normal 8pt Tahoma,MiscFixed", + left :20, + width :60 + });*/ + //begin.onmouseup = this.control.first; + this.domPlay.onmouseup = this.control.play; + this.domPrev.onmouseup = this.control.previous; + this.domNext.onmouseup = this.control.next; + //end.onmouseup = this.control.last; + if(this.options.banner) + { + this.banner=$dce("img"); + this.banner.src=this.options.banner; + this.options.target.appendChild(this.banner); + } + }; + this.control={ + setPlay:function() + { + this.domPlay.src = this.options.skin_images+"play_dark.png"; + this.domPlay.onmouseover = function() + { + this.domPlay.src = this.options.skin_images+"play_on_dark.png"; + }.extend(this); + this.domPlay.onmouseout = function() + { + this.domPlay.src = this.options.skin_images+"play_dark.png"; + }.extend(this); + }, + setPause:function() + { + this.domPlay.src = this.options.skin_images+"pause_dark.png"; + this.domPlay.onmouseover = function() + { + this.domPlay.src = this.options.skin_images+"pause_on_dark.png"; + }.extend(this); + this.domPlay.onmouseout = function() + { + this.domPlay.src = this.options.skin_images+"pause_dark.png"; + }.extend(this); + }, + play:function() + { + if(!this.inPlay) + { + this.control.setPause(); + this.stopped=false; + this.inPlay=!this.inPlay; + this.control.next(); + } + else + { + this.control.setPlay(); + this.stopped=true; + this.inPlay=!this.inPlay; + } + //alert(!this.inPlay) + //this.inPlay=!this.inPlay; + //alert("=> "+this.inPlay); + }, + next:function(){ + //alert("in NExt: "+this.inPlay) + if(this.Null===true){return false;} + if(this.stopped===false) + { + var t = this.current+1; + if(t%4===0) + { + this.control.right(); + } + else + { + this.load(t); + } + } + else + { + this.stopped=false; + } + }, + previous:function(){ + if(this.Null===true){return false;} + var t = this.current; + if(t%4===0) + { + this.control.left(); + } + else + { + this.load(this.current-1); + } + }, + left:function() + { + //this.toolbar.scrollLeft=this.toolbar.scrollLeft-((this.options.thumbnail.size.w*4)+4); + //this.toolbar.scrollLeft=this.toolbar.scrollLeft-((this.options.thumbnail.size.w*4)+(4*4)); + this.Null=true; + new this.parent.module.fx.algorithm().make({ + transition :"sineInOut", + duration :1000, + begin :this.toolbar.scrollLeft, + end :this.toolbar.scrollLeft-((this.options.thumbnail.size.w*4)+(4*4)), + onTransition:function(fx){ + this.toolbar.scrollLeft=fx.result; + }.extend(this), + onFinish :function(fx){ + this.toolbar.scrollLeft=fx.options.end; + this.load(this.current-1); + this.Null=false; + }.extend(this) + }); + //this.toolbar.scrollLeft=this.toolbar.scrollLeft-25; + }, + right:function() + { + //this.toolbar.scrollLeft=this.toolbar.scrollLeft+(this.options.thumbnail.size.w+4); + //this.toolbar.scrollLeft=this.toolbar.scrollLeft+((this.options.thumbnail.size.w*4)+(4*4)); + this.Null=true; + //alert(this.options.thumbnail.images.length / 4); + new this.parent.module.fx.algorithm().make({ + transition :"sineInOut", + duration :1000, + begin :this.toolbar.scrollLeft, + end :this.toolbar.scrollLeft+((this.options.thumbnail.size.w*4)+(4*4)), + onTransition :function(fx){ + this.toolbar.scrollLeft=fx.result; + }.extend(this), + onFinish :function(fx){ + this.toolbar.scrollLeft=fx.options.end; + var t = this.current+1; + this.load(t); + this.Null=false; + }.extend(this) + }); + //this.toolbar.scrollLeft=this.toolbar.scrollLeft+25; + } + }.expand(this); + this.expand(this); + }, + box:function() + { + this.panel = new this.parent.module.panel(); + this.panel.options={ + size:{w:300,h:200}, + title :"Prueba panel", + headerBar:true, + titleBar:false, + elementToDrag:"backend", + position:{x:5,y:5,center:true}, + fx:{shadow:false,modal:true,opacity:false} + }; + this.panel.setStyle={ + containerWindow:{ + border:"0px solid red" + }, + frontend:{ + backgroundColor:"transparent" + }, + content:{ + margin:0, + border:"0px solid red", + borderLeft:"1px solid #DADADA", + borderRight:"1px solid #DADADA", + backgroundColor:"white" + }, + headerBar:{ + display:'' + //height:16, + //border:"1px solid red" + }, + statusBar:{ + } + }; + this.panel.styles.fx.opacityModal.Static=0; + this.panel.make(); + this.panel.elements.headerBar.className="boxTopPanel"; + this.panel.elements.headerBar.innerHTML="

    "; + + this.panel.elements.statusBar.className="boxBottom"; + this.panel.elements.statusBar.innerHTML="
    "; + return this.panel; + }, + confirm:function() + { + this.make=function(options) + { + var lb = (typeof G_STRINGS!=='undefined') ? G_STRINGS:{}; + var label={ + accept:lb.ACCEPT || "Aceptar", + cancel:lb.CANCEL || "Cancelar" + }; + this.panel = new this.parent.module.panel(); + this.options = { + action:function(){} + }.concat(options || {}); + this.panel.options={ + statusBarButtons:[ + {value:label.accept}, + {value:label.cancel} + ], + position:{center:true}, + size:{ + w:(typeof(options.width) != 'undefined')? options.width: 350, + h: (typeof(options.height) != 'undefined')? options.height: 100 + }, + control:{ + close :true, + resize :false + }, + fx:{ + modal:true + } + }; + //alert(this.parent.info.path_images) + this.panel.setStyle={ + content:{ + padding:10, + paddingBottom:2, + textAlign:"left", + paddingLeft:50, + background:"url("+this.parent.info.images+"question.png)", + backgroundRepeat:"no-repeat", + backgroundPosition:"10 50%", + backgroundColor:"transparent", + borderWidth:0 + } + }; + this.panel.make(); + this.panel.addContent(this.options.label || ""); + this.panel.fixContent(); + this.panel.elements.statusBarButtons[0].onmouseup=function() + { + this.options.action(); + this.panel.remove(); + return false; + }.extend(this); + this.panel.elements.statusBarButtons[1].onmouseup=function() + { + if(this.options.cancel) + { + this.options.cancel(); + } + this.panel.remove(); + return false; + }.extend(this); + this.panel.events = { + remove: function() { + }.extend(this) + }; + }; + }, + alert:function() + { + this.make=function(options) + { + var lb = (typeof G_STRINGS!=='undefined')?G_STRINGS:{}; + var label={ + accept:lb.ACCEPT || "Aceptar" + }; + this.panel = new this.parent.module.panel(); + this.options = { + action:function(){}, + target:document.body + }.concat(options || {}); + this.panel.options={ + statusBarButtons:[ + {value:label.accept} + ], + target:this.options.target, + position:{center:true}, + size:{ + w:(typeof(options.width) != 'undefined')? options.width: 300, + h: (typeof(options.height) != 'undefined')? options.height: 110 + }, + control:{ + close :true, + resize :false + }, + fx:{ + modal:true + } + }; + this.panel.setStyle={ + content:{ + padding:10, + paddingBottom:2, + textAlign:"left", + paddingLeft:65, + background:"url("+this.parent.info.images+"warning.png)", + backgroundRepeat:"no-repeat", + backgroundPosition:"10 50%", + backgroundColor:"transparent", + borderWidth:0 + } + }; + this.panel.make(); + this.panel.addContent(this.options.label || ""); + this.panel.fixContent(); + this.panel.elements.statusBarButtons[0].onmouseup=function() + { + this.options.action(); + this.panel.remove(); + return false; + }.extend(this); + return this; + }; + }, + info:function() + { + this.make=function(options) + { + var lb = (typeof G_STRINGS!=='undefined')?G_STRINGS:{}; + var label={ + accept:lb.ACCEPT || "Aceptar" + }; + this.panel = new this.parent.module.panel(); + this.options = { + action:function(){}, + target:document.body + }.concat(options || {}); + this.panel.options={ + statusBarButtons:[ + {value:label.accept} + ], + target:this.options.target, + position:{center:true}, + size:{ + w:(typeof(options.width) != 'undefined')? options.width: 300, + h: (typeof(options.height) != 'undefined')? options.height: 110 + }, + control:{ + close :true, + resize :false + }, + fx:{ + modal:true + } + }; + this.panel.setStyle={ + content:{ + padding:10, + paddingBottom:2, + textAlign:"left", + paddingLeft:65, + background:"url("+this.parent.info.images+"info.png)", + backgroundRepeat:"no-repeat", + backgroundPosition:"10 50%", + backgroundColor:"transparent", + borderWidth:0 + } + }; + this.panel.make(); + this.panel.addContent(this.options.label || ""); + this.panel.fixContent(); + this.panel.elements.statusBarButtons[0].onmouseup=function() + { + this.options.action(); + this.panel.remove(); + return false; + }.extend(this); + return this; + }; + }, + prompt:function() + { + this.make=function(options) + { + var lb = (typeof G_STRINGS!=='undefined')?G_STRINGS:{}; + var label={ + accept :lb.ACCEPT || "Aceptar", + cancel :lb.CANCEL || "Cancelar" + }; + this.panel = new this.parent.module.panel(); + this.options = { + action :function(){}, + value :"" + }.concat(options || {}); + this.panel.options={ + statusBarButtons:[ + {value:label.accept}, + {value:label.cancel} + ], + position:{center:true}, + size:{w:300,h:110}, + control:{ + close :true, + resize :false + }, + fx:{ + modal:true + } + }; + this.panel.setStyle={ + content:{ + padding:10, + paddingBottom:2, + textAlign:"left", + paddingLeft:50, + background:"url("+this.parent.info.images+"question.png)", + backgroundRepeat:"no-repeat", + backgroundPosition:"10 50%", + backgroundColor:"transparent", + borderWidth:0 + } + }; + this.panel.events={remove:this.functionOnFALSE}; + this.panel.make(); + this.panel.addContent(this.options.label || ""); + this.panel.addContent("
    "); + this.input = $dce("input"); + this.input.type="text" + this.parent.dom.setStyle(this.input,{ + font:"normal 8pt Tahoma,MiscFixed", + color:"#000", + width:"100%", + marginTop:3, + backgroundColor:"white", + border:"1px solid #919B9C" + }); + this.panel.addContent(this.input); + this.input.value=this.options.value; + this.input.focus(); + this.input.onkeyup=function(evt) + { + //alert(searchText) + var evt = (window.event)?window.event:evt; + var key = (evt.which)?evt.which:evt.keyCode; + if(key==13) + { + this.functionOnTRUE(); + } + else if(key==27) + { + this.functionOnFALSE(); + } + //this.renderSearched(); + }.extend(this); + + this.panel.fixContent(); + this.panel.elements.statusBarButtons[0].onmouseup=this.functionOnTRUE; + this.panel.elements.statusBarButtons[1].onmouseup=this.functionOnFALSE; + return this; + }; + this.functionOnTRUE=function() + { + this.action=true; + this.options.action(this.input.value); + this.panel.remove(); + return false; + }; + this.functionOnFALSE=function() + { + if(this.options.cancel && this.action!==true) + { + this.options.cancel(); + } + this.panel.remove(); + return false; + }; + this.expand(this); + }, + radioEvents:function() + { + this.makes=[]; + this.add=function(param) + { + var radio=this.parent.module.dom.radioByValue({ + name:param.name, + value:param.value} + ); + var idName=param.name+param.value; + param.activated=false; + radio.id=idName; + + /*leimnud.event.add(radio,"click",leimnud.aplication.event.launch); + + leimnud.aplication.event.dispatcher( + { + name:idName,no t + _function:this.engine, + arguments:{inst:this,options:param,radio:radio} + });*/ + + radio.onclick=this.engine.args({options:param,radio:radio}); + + if(param.make){this.makes[this.makes.length]=idName;} + }; + this.engine=function(param) + { + /*var inst=param.arguments.inst; + + this.conditions(param.arguments.radio,param.arguments.options.event,true,false); + + if(param.arguments.options.revert) + { + var rv=param.arguments.options.revert.split(","); + for(var i=0;i +* Version : 0.2 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +/** +* @class drag +*/ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.dashboard.js", + Name :"dashboard", + Type :"module", + Version :"0.1" + }, + content :function(){ + this.elements = {}; + this.make=function(options) + { + this.options = { + drag:true, + panel:[], + data:[] + }.concat(options || {}); + this.drop = new this.parent.module.drop(); + this.drop.make(); + + var width = this.options.target.offsetWidth-50; + this.columns = this.options.data.length; + this.widthColumn = (width/this.columns); + this.elements.column=[]; + this.elements.table = $dce('table'); + $(this.elements.table).setStyle({ + width:width, + borderCollapse:'collapse' + }) + this.elements.tr = this.elements.table.insertRow(-1); + this.options.target.append(this.elements.table); + this.matriz = []; + for(var i=0;i +* Version : 0.2 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +/** +* @class drag +*/ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.drag.js", + Name :"drag", + Type :"module", + Version :"0.1" + }, + content :function(options){ + this.options = { + limitbox:false + }.concat(options || {}); + this.loaded = false; + this.eventHandlers=[]; + this.cursor = "move"; + this.uid = this.parent.tools.createUID(); + this.make=function() + { + //alert(this.options.elements.isArray); + //this.options.elements=(this.options.elements && !this.options.elements.length)?[this.options.elements]:this.options.elements + this.options.elements=this.set(); + this.options.fx = { + type:"simple", + target:document.body + }.concat(this.options.fx || {}); + this.events =this.events || {}; + //alert(this.options.elements.length); + var elements=(this.options.elements || []).length; + this.flagEvents=[]; + var oThis = this; + for(var i=0;ithis.options.limitbox.clientWidth)){rG.l=false;} + if((tT<0 || this.options.limit==="y") || (this.options.limitbox && (tT+element.clientHeight)>this.options.limitbox.clientHeight)){rG.t=false;} + this.currentX = tL; + this.currentY = tT; + //var tL=parseInt(this.elementStart.x+(cursor.x-this.cursorStart.x),10); + //var tT=parseInt(this.elementStart.y+(cursor.y-this.cursorStart.y),10); + if(rG.l || !this.options.limit) + { + this.parent.dom.setStyle(element,{ + left:tL + }); + } + if(rG.t || !this.options.limit) + { + this.parent.dom.setStyle(element,{ + top:tT + }); + } + } + else if(this.type=="group") + { + for(var i=0;i +* Version : 0.2 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +/** +* @class drop +*/ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.drop.js", + Name :"drop", + Type :"module", + Version :"0.1" + }, + content :function(options){ + this.options = options || {}; + this.elements = []; + this.selected = false; + this.selID = false; + this.lastSelected= false; + this.make=function(options) + { + return this; + }; + this.register = function(data) + { + var ev = data.events || {}; + data.events = ev; + this.elements.push(data); + return (this.elements.length-1); + }; + this.unregister = function(index) + { + this.elements[index]=null; + }; + this.generateIndex=function() + { + return this.elements.length; + }; + this.capture = function(drag,StopOnAbsolute) + { + this.drag = drag.currentElementDrag; + //window.status=this.drag; + var position = this.parent.dom.position(this.drag,false,StopOnAbsolute || false); + position={ + x:position.x+(this.drag.clientWidth/2), + y:position.y+(this.drag.clientHeight/2) + }; + this.selected = false; + //console.info(position); + for(var i=0;i pt.x1 && position.x < pt.x2 && position.y > pt.y1 && position.y < pt.y2) + { + this.selected = i; + break; + } + } + } + if(this.selected===false) + { + if(this.selID!==false) + { + this.out(this.selID); + } + } + else + { + if(this.selID!==false && this.selID!==this.selected) + { + this.out(this.selID); + } + this.over(this.selected); + } + this.lastSelected = (this.selected===false)?this.lastSelected:this.selected; + //window.status=this.selected; + //return (inTarget===false)?false:this.elements[inTarget].value;*/ + }; + this.setArrayPositions=function(StopOnAbsolute) + { + this.arrayPositions=[]; + for(var i=0;i= pt.x1 && this.position.x <= pt.x2 && this.position.y >= pt.y1 && this.position.y <= pt.y2) + { + this.selected = i; + break; + } + } + this.lastSelected = (this.selected===false)?this.lastSelected:this.selected; + //window.status=this.selected; + if(this.selected===false) + { + if(this.selID!==false) + { + this.out(this.selID); + } + } + else + { + if(this.selID!==false && this.selID!==this.selected) + { + this.out(this.selID); + } + this.over(this.selected); + } + //return (inTarget===false)?false:this.elements[inTarget].value;*/ + }; + this.over=function(uid) + { + this.selID = uid; + if(this.elements[uid]!==null) + { + return this.launchEvents(this.elements[uid].events.over); + } + + }; + this.out=function(uid) + { + this.selID=false; + if(this.elements[uid]!==null) + { + return this.launchEvents(this.elements[uid].events.out); + } + }; + this.launchEvents=function(event) + { + if(event && event.isArray===true) + { + for(var i=0;i + +* + +4.- arrastrar soltar NO. right click Elementos. + + +i: .xml, .tpl + +o: .xml, .tpl, .html + + + + + +*/ +var $a='0123456789ABCDEF'; +var $b=function() +{ + $g = $a.split(''); + return $g.random()+$g.random()+$g.random()+$g.random()+$g.random()+$g.random(); +}; +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.dynaform.js", + Name :"dynaform", + Type :"module", + Version :"0.1" + }, + content :function() + { + this.tmp = {}; + this.make=function(options) + { + this.options = { + template :'default.tpl', + sectionName:'section', + target :document.body, + points :{}, + dom :{}, + drop :{}, + drag :{}, + menu :{}, + debug :false, + editor :{showed:false}, + observers:{}, + panel :{}, + tmp :{}, + style:{ + section:"#B3B3BF", + new_section:{border:'1px solid green',margin:4,minHeight:20}, + add_section:{position:'relative',border:'1px solid #B3B3BF',margin:4,minHeight:20} + } + }.concat(options || {}); + this.db=[]; + this.debug = new this.parent.module.debug(this.options.debug || false); + this.options.observers['menu'] = new this.parent.pattern.observer(); + this.options.target.setStyle({ + textAlign:'center' + }); + this.options.target.append( + table =new DOM('table',{align:'center'},{width:'99%'}) + ); + var tr = table.insertRow(-1); + $(tr).append( + new DOM('td').append( + new DOM('div',{className:'boxTop'}).append( + new DOM('div',{className:'a'}), + new DOM('div',{className:'b'}), + new DOM('div',{className:'c'}) + ), + new DOM('div',{className:'boxContentNormal',id:"bcn"},{minHeight:this.options.target.clientHeight-70,paddingBottom:20}).append( + this.options.dom.body = new DOM('div',{id:'root'},{border:'1px solid '+this.options.style.section,padding:5,minHeight:(this.options.target.clientHeight-80)}) + ), + new DOM('div',{className:'boxBottom'}).append( + new DOM('div',{className:'a'}), + new DOM('div',{className:'b'}), + new DOM('div',{className:'c'}) + ) + ) + ); +// this.options.dom.body = this.options.target; +/* this.options.target.append( + this.options.dom.body = new DOM('div') + );*/ +// this.options.dom.header = new DOM('div'); +/* this.setStyles(); + this.dynas=[]; + for(var i=0;i<12;i++) + { + var d; + this.options.dom.header.append( + d = new DOM('input',{type:'button',value:i},{backgroundColor:'#'+$b(),width:30,margin:2,border:'1px solid red'}) + ); + this.dynas.push(d); + }*/ + this.load({ + template:this.options.template, + xmlform:this.options.xmlform + }); + this.buttons_set(); + return this; + }; + this.buttons_set=function() + { + //alert(this.options.buttons.xml); + this.options.buttons.xml.onmouseup=function() + { + this.show_editor('xml'); + //alert(this.options.window.editor) + }.extend(this); + this.options.buttons.template.onmouseup=function() + { + this.show_editor('template'); + }.extend(this); + }; + this.show_editor=function(b) + { + //alert(this.options.editor.selected+":"+b); + this.options.window.textarea.value=''; + if(this.options.editor.showed===true && this.options.editor.selected==b) + { + if(b=='xml') + { + //this.options.buttons.template.disabled=false; + //this.options.buttons.xml.disabled=true; + this.options.buttons.xml.className="dbo"; + this.options.buttons.xml.dv='0'; + this.options.buttons.template.dv='0'; + this.options.buttons.template.className="dbs"; + } + else + { + //this.options.buttons.template.disabled=true; + //this.options.buttons.xml.disabled=false; + this.options.buttons.xml.dv='0'; + this.options.buttons.template.dv='0'; + this.options.buttons.xml.className="dbs"; + this.options.buttons.template.className="dbo"; + } + this.options.window.editor.move({y:this.options.sizes.pi}); + this.options.editor.showed=false; + this.options.editor.selected=b; + } + else + { + if(b=='xml') + { + //this.options.buttons.template.disabled=false; + //this.options.buttons.xml.disabled=true; + this.options.window.textarea.value=this.xmlform.serialize().sReplace('><','>\n<'); + + this.options.buttons.xml.dv='1'; + this.options.buttons.template.dv='0'; + this.options.buttons.xml.className="dbo"; + this.options.buttons.template.className="dbs"; + } + else + { + this.options.window.textarea.value='b'; + //this.options.buttons.template.disabled=true; + //this.options.buttons.xml.disabled=false; + this.options.buttons.xml.dv='0'; + this.options.buttons.template.dv='1'; + this.options.buttons.xml.className="dbs"; + this.options.buttons.template.className="dbo"; + } + this.options.window.editor.move({y:this.options.sizes.pv,onFinish:function(){this.options.window.textarea.focus();}.extend(this)}); + this.options.editor.showed=true; + this.options.editor.selected=b; + } + }; + this.setStyles=function() + { +/* this.options.dom.actions.setStyle({ + border:'1px solid red', + position:'absolute', + width:200, + height:400 + }); + this.options.dom.header.setStyle({ + border:'1px solid red', + position:'relative', + top:100, + left:250, + width:300, + height:100 + });*/ + this.options.dom.body.setStyle({ + border:'1px solid red', + position:'relative', + top:0, + left:250, + width:600, + height:400 + }); + }; + this.load=function(options) + { + options = { + template:"empty.tpl", + xmlform:"empty.xml" + }.concat(options || {}); + var r = new this.parent.module.rpc.xmlhttp({ + url:options.template + }); + r.callback=function(rpc){ + this.xmlform = new this.parent.module.xmlform(); + this.xmlform.make({ + file :options.xmlform, + target :this.options.target_info, + debug :this.options.debug, + onload :function(){ + this.editor(); + this.xmlform.tag_edit(this.xmlform.show_dyna(),'dyna_root'); + this.parse_elements(); + }.extend(this) + }); + this.build({ + template:rpc.xmlhttp.responseText + }); + }.extend(this); + r.make(); + }; + this.editor=function() + { + var e =$dce("div",{innerHTML:"asd"},{height:100,width:1212,backgroundColor:"red",position:'absolute',zIndex:123123,top:0}); + document.body.appendChild(e); + }; + this.build=function(o) + { + this.options.dom.body.innerHTML=o.template; + //this.options.dom.body.append(this.options.dom.header); + var t = this.tplFirstChild(); + this.tplSetPoints({ + html:t + }); + + this.tplSetDropables(); + + + + this.menu_root = new this.parent.module.app.menuRight(); + this.options.observers['menu'].register(this.menu_root.remove,this.menu_root); + this.menu_root.make({ + target:this.options.dom.body, + width:201, + theme:'light', + menu:[ + {text:'New Dynaform',launch:function(){}}, + {text:'New Section',launch:this.add_section.args(this.options.dom.body)}, + {text:'Save Dynaform',launch:function(){}}, + {separator:true}, + {text:'Edit XML',launch:function(){this.show_editor('xml');}.extend(this)}, + {text:'Edit Template',launch:function(){this.show_editor('template');}.extend(this)} + ] + }); + }; + this.tplFirstChild=function() + { + //return this.options.dom.body.firstChild; + return this.options.dom.body; + }; + this.tplSetPoints=function(o) + { + var t = o.html; + var c = t.childNodes.length || 0; + //alert(o.html.childNodes) + for(var i=0;i0) + { + this.tplSetPoints({ + html:e + }); + } + } + }; + this.isPoint=function(e) + { + if(e[this.options.sectionName]){ + return e[this.options.sectionName]; + } + if(e.attributes) + { + for(var i=0;i0)?true:false; + //return "Element_"+(new Date().getTime()); + }; + this.unique_name=function() + { + return "Element_"+(new Date().getTime()); + }; + this.menu={ + /** + * Menu para Grupos (points) + */ + group:function(dom) + { + var menu = new this.parent.module.app.menuRight(); + menu.make({ + target:dom, + width:150, + theme:'light', + //menu:this.group.elements.concat( + menu:[ + {text:'Add element',launch:function(evt,g){ + //alert(evt+":"+g) + this.options.panel.add=new this.parent.module.panel(); + this.options.panel.add.options={ + title:"Add element", + size:{w:400,h:350}, + position:{center:true}, + statusBarButtons:[ + {value:'Create'}, + {value:'Cancel'} + ], + fx:{modal:true} + }; + this.options.panel.add.make(); + var a = { + textAlign:'right', + font:'normal 8pt Tahoma,sans-serif' + }; + var b = { + textAlign:'left', + font:'normal 8pt Tahoma,sans-serif' + }; + this.options.panel.add.addContent( + new DOM('table',{align:'center',cellPadding:2},{width:'100%',margin:0}).append( + new DOM('tbody').append( + new DOM('tr').append( + new DOM('td',{},{width:'30%'}).append( + new DOM('div',{innerHTML:'Type:'},a) + ), + new DOM('td',{},{width:'70%'}).append( + new DOM('div',{},b).append( + this.tmp.t = this.dynaform_dom_types() + ) + ) + ), + new DOM('tr').append( + new DOM('td').append( + new DOM('div',{innerHTML:'Name:'},a) + ), + new DOM('td').append( + new DOM('div',{},b).append( + this.tmp.n = new input({label:this.unique_name()},{},{style:{width:'70%'}}) + ) + ) + ), + new DOM('tr').append( + new DOM('td').append( + new DOM('div',{innerHTML:'NodeValue:'},a) + ), + new DOM('td').append( + new DOM('div',{},b).append( + this.tmp.v = new input({},{},{style:{width:'70%'}}) + ) + ) + ), + new DOM('tr').append( + new DOM('td',{colSpan:2}).append( + new DOM('div',{},a).append( + new DOM('fieldset',{},{border:'1px solid #B3B3BF'}).append( + new DOM('legend',{innerHTML:'Properties'}), + this.tmp.p = new DOM('div').append(this.dynaform_dom_properties()) + ) + ) + ) + ) + ) + ) + ); + this.tmp.g = window.event?evt:g; + this.options.panel.add.elements.statusBarButtons[0].onmouseup=function() + { + if(this.tmp.n.value.trim()=='' || !this.tmp.n.value.isAlphaUS() || this.isset_tagName(this.tmp.n.value)) + { + this.tmp.n.failed(); + return false; + } + else + { + this.tmp.n.passed(); + var a = {}; + for(var i=0;i this.drop.arrayPositions[uid].y2) + { + this.setImageAddRow(uid,true); + } + }*/ + }.extend(this,c) + } + }); + } + } + this.options.drop.elements.setArrayPositions(true); + }; + this.setImageAddRow=function(drop_uid,last) + { + this.imageAddRow.setStyle({ + position:"absolute", + zIndex :100, + top:((last)?this.options.drop.elements.arrayPositions[drop_uid].y2:this.options.drop.elements.arrayPositions[drop_uid].y1)-7, + left:this.options.drop.elements.arrayPositions[drop_uid].x1-3 + }); + }; + this.drag_elements_group_onfinish=function(db_uid) + { + var drag = this.options.drag.phantom; + var drop = this.options.drop.groups; + if(drag.moved) + { + this.inDragProcess=false; + this.phantom_static.remove(); + delete this.phantom_static; + if(drop.selected!==false) + { + var t = drop.elements[drop.selected].value; + //console.log(this.xmlform.db[db_uid]) + var c = this.xmlform.tag_attributes_to_object(this.xmlform.db[db_uid]).concat({ + group:t + }); + var m = c['nodeName']; + //console.log(c.group) + ////this.add_element(m,true,{group:c.group,type:"other"}); + //this.add_element(m,true,{group:t,type:"other"}); + this.add_element(m,true,c); + this.remove_element(db_uid); + } + else + { + + } + + } + else + { + this.inDragProcess=false; + this.phantom_static.remove(); + delete this.phantom_static; + + } + }; + this.drag_elements_onfinish=function(db_uid) + { + this.imageAddRow.remove(); + delete this.imageAddRow; + + var insertRowIn,begin; + + var drag = this.options.drag.phantom; + var drop = this.options.drop.elements; + + if(drag.moved) + { + if(drop.selected===false) + { + var uid=drop.arrayPositions.length-1; + if((drop.position.y > drop.arrayPositions[uid].y2)/* && this.lastSelected===uid*/) + { + insertRowIn = uid; + begin = false; + } + else + { + insertRowIn = 0; + begin = true; + } + } + else + { + insertRowIn = drop.selected; + begin = true; + } + var t = this.db[drop.elements[insertRowIn].value]; +// t.parentNode.insertBefore(new DOM('input').replace(this.db[db_uid])); + var n = t.before(new DOM('div')).replace(this.db[db_uid]); + drag.flush(); + new this.parent.module.fx.move().make({ + duration:((drag.moved)?500:0), + //end :{x:this.drop.arrayPositions[insertRowIn].x1,y:this.drop.arrayPositions[insertRowIn].y1}, + end :this.parent.dom.position(n,false,true), + dom :this.phantom_static, + onFinish :function() + { + new this.parent.module.fx.fade().make({ + duration:500, + end :0, + dom :this.phantom_static, + onFinish :function(){ + this.inDragProcess=false; + this.phantom_static.remove(); + delete this.phantom_static; + }.extend(this) + }); + }.extend(this) + }); + + + //var newRow=this.db[insertRowIn]; + //newRow.parentNode.replaceChild(domRow,newRow); + //alert(movedUID+":"+this.options.data.rows[movedUID].info.rowIndex+":"+domRow.rowIndex) + //alert(domRow.rowIndex) + } + else + { + /*insertRowIn = drag.currentElementDrag.db_uid-1; + begin = true;*/ + this.inDragProcess=false; + this.phantom_static.remove(); + delete this.phantom_static; + } + + }; + /* Contar elementos en grupo */ + + /* Devuelve el Key actual de un objeto dentro del grupo */ + this.key_in_group=function(db_uid) + { + var a = this.db[db_uid]; + var j=0; + for(var i=0;ilimit)?limit:this.options.paginator.limit; + lpp = (((page)==this.options.paginator.pages)?(total-((page-1)*forp)):forp); + var inicio = this.options.paginator.limit*(this.options.paginator.page-1); + inicio = (inicio<0)?0:inicio; + var fin = inicio+lpp; + //alert(inicio+":"+fin); + for(var i=inicio;ithis.options.paginator.pages)?this.options.paginator.pages:pagTo); + this.pDC.value = pagTo; + if(pagTo!==this.options.paginator.page || force===true) + { + this.options.paginator.page=pagTo; + this.clear(); + this.renderData(); + } + if(pagTo===1) + { + this.pDf.className="app_grid_pDfDisabled___"+this.options.theme; + this.pDp.className="app_grid_pDpDisabled___"+this.options.theme; + } + else + { + this.pDf.className="app_grid_pDf___"+this.options.theme; + this.pDp.className="app_grid_pDp___"+this.options.theme; + } + if(pagTo===this.options.paginator.pages) + { + this.pDn.className="app_grid_pDnDisabled___"+this.options.theme; + this.pDl.className="app_grid_pDlDisabled___"+this.options.theme; + } + else + { + this.pDn.className="app_grid_pDn___"+this.options.theme; + this.pDl.className="app_grid_pDl___"+this.options.theme; + } + return false; + }; + this.renderSearched=function(evt,stext) + { + //alert(345345) + this.dataToRender = []; + var text = this.searchText.value; + //var r = this.options.data.rows; + var r = this.options.data.rows; + var rw = this.elements.table.rows; + var c = this.options.data.column; + for(var i=0;i bComp) {return order2} + return 0; + }.args(data.order)); + var sortedIndex = []; + for(var i=0;iSearch in:

    "); + var fs = $dce("fieldset"); + this.parent.dom.setStyle(fs,{ + fontWeight :"bold", + //border :"1px solid #99BBE8", + //height :"100%", + color :"#000" + }); + var lg = $dce("legend"); + lg.innerHTML="Search in:"; + fs.appendChild(lg); + options.addContent(fs); + + var dr = this.options.data.column; + var se = []; + var cn = $dce("div"); + this.parent.dom.setStyle(cn,{ + fontWeight :"normal", + textAlign :"right", + //backgroundColor :"#D0DEF0", + //border :"1px solid #99BBE8", + color :"#000" + }); + fs.appendChild(cn); + for(var i=0;i0;i--) + { + //alert(this.elements.table.rows[i]) + this.parent.dom.remove(this.elements.table.rows[i]); + } + }; + this.searchables=function() + { + var dr = this.options.data.column; + var se = []; + for(var i=0;i this.dropToCell.arrayPositions[uid].y2)) + { + insertCellIn= uid; + begin = false; + } + else + { + insertCellIn= 0; + begin = true; + } + } + else + { + insertCellIn= this.dropToCell.selected; + begin = true; + } + //var newRow=this.elements.table.insertRow((begin)?insertRowIn+1:-1); + var row0 = this.elements.table.rows[0]; + var insI = (begin)?insertCellIn+1:row0.length-1; + //console.info("Nuevo en: "+insI); + //alert(insI) + var newCell = row0.insertCell(insI); + newCell.parentNode.replaceChild(domCell,newCell); + //console.info("Nuevo cellIndex: "+domCell.cellIndex+":"+newCell.cellIndex); + for(var i=1;i this.drop.arrayPositions[uid].y2)/* && this.lastSelected===uid*/) + { + insertRowIn = uid; + begin = false; + } + else + { + insertRowIn = 0; + begin = true; + } + } + else + { + insertRowIn = this.drop.selected; + begin = true; + } + var newRow=this.elements.table.insertRow((begin)?insertRowIn+1:-1); + newRow.parentNode.replaceChild(domRow,newRow); + //alert(movedUID+":"+this.options.data.rows[movedUID].info.rowIndex+":"+domRow.rowIndex) + this.options.data.rows[movedUID].info.rowIndex=domRow.rowIndex; + //alert(domRow.rowIndex) + } + else + { + insertRowIn = domRow.rowIndex-1; + begin = true; + } + this.parent.dom.remove([this.phantomRowStatic,this.imageAddRow]); + //window.status=insertRowIn+":"+begin; + this.drag.flush(); + //this.parent.dom.remove([this.phantomRow,this.phantomRowStatic,this.imageAddRow]); + new this.parent.module.fx.move().make({ + duration:((this.drag.moved)?500:0), + //end :{x:this.drop.arrayPositions[insertRowIn].x1,y:this.drop.arrayPositions[insertRowIn].y1}, + end :this.parent.dom.position(domRow,false,true), + dom :this.phantomRow, + onFinish :function(insertRowIn,begin,domRow) + { + new this.parent.module.fx.fade().make({ + duration:500, + end :0, + dom :this.phantomRow, + onFinish :function(){ + this.parent.dom.remove(this.phantomRow); + this.inDragProcess=false; + }.extend(this) + }); + }.extend(this,insertRowIn,begin,domRow) + }); + //alert("insertRowIn="+insertRowIn+":begin="+begin+":movedUID="+movedUID+":domRow="+domRow); + //alert(this.drop.arrayPositions[insertRowIn].y1); + }.extend(this,row,domRow) + }; + this.drag.make(); + this.drag.onInit(event,0); + this.imageAddRow = $dce("img"); + this.imageAddRow.src=this.parent.info.images+"nr.gif"; + this.setImageAddRow(domRow.rowIndex-1); + this.options.target.appendChild(this.imageAddRow); + //this.elements.table.rows[1]=this.elements.table.rows[3]; + /*var uidMm = this.parent.event.add(this.options.target,"mousemove",function(evt) + { + evt = window.event || evt; + var m = this.parent.dom.mouse(evt); + window.status = "x="+m.x+": y="+m.y; + }.extend(this)); + this.parent.event.removeFromUid(uidMm);*/ + //alert(uidMm) + /*var tableCloned = this.elements.table.cloneNode(false); + this.parent.dom.setStyle(tableCloned,{ + //border : "1px dashed red" + }); + //alert(this.elements.table.clientWidth) + this.phantomRow.appendChild(tableCloned); + var headCloned = this.elements.table.rows[0].cloneNode(true) + var rowCloned = domRow.cloneNode(true); + this.parent.dom.opacity(headCloned,0); + for(var k=0;k this.dropToCell.arrayPositions[uid].y2) + { + this.setImageAddCell(uid,true); + } + } + }.extend(this,i) + } + }); + //} + } + this.dropToCell.setArrayPositions(true); + }; + this.registerRowsToDrop=function(inRow) + { + for(var i=1;i this.drop.arrayPositions[uid].y2) + { + this.setImageAddRow(uid,true); + } + } + }.extend(this,i) + } + }); + //} + } + this.drop.setArrayPositions(true); + }; + /** + * {Dom} a Source + * {Dom} b Destiny + */ + this.fixColumnsWidth=function(a,b) + { + var h=0; + for(var i=0;i0) + { + this.resize({ + //w:this.options.size.w, + h:this.options.size.h+diff + }); + this.options.size = originalSize; + this.originalContent= originalContentSize; + } + else if(this.elements.content.clientHeight>originalContentSize.h) + { + this.resize({ + //w:this.options.size.w, + h:this.options.size.h + }); + if(rcr!==true) + { + // this.fixContent(true); + } + } + }; + /** + * Make Events + */ + this.makeEvents=function() + { + this.events.init =(this.events.init)?((this.events.init.isArray)?this.events.init:[this.events.init]):[]; + this.events.move =(this.events.move)?((this.events.move.isArray)?this.events.move:[this.events.move]):[]; + this.events.finish =(this.events.finish)?((this.events.finish.isArray)?this.events.finish:[this.events.finish]):[]; + }; + this.makeControls=function() + { + this.controls=[]; + /** Close */ + if(this.options.control.close) + { + this.elements.close = $dce("div"); + this.elements.close.className="panel_close___"+this.getTheme("close"); + this.parent.exec(this.styles.close,false,false,this); + this.controls.push(this.elements.close); + this.elements.titleBar.appendChild(this.elements.close); + } + /** Rollup/Rolldown */ + if(this.options.control.roll) + { + this.elements.roll = $dce("div"); + this.elements.roll.className="panel_roll___"+this.getTheme("roll"); + this.styles.roll(); + this.controls.push(this.elements.roll); + this.elements.titleBar.appendChild(this.elements.roll); + this.elements.title.ondblclick=this.roll; + } + if(this.options.control.setup) + { + this.elements.setup = $dce("div"); + this.elements.setup.className="panel_roll___"+this.getTheme("roll"); + this.styles.setup(); + this.controls.push(this.elements.setup); + this.elements.titleBar.appendChild(this.elements.setup); + } + + /** + * Drag window + */ + if(this.options.control.drag) + { + var etd = this.elements[this.options.elementToDrag]; + this.parent.dom.setStyle(this.elements.title,{cursor:this.options.cursorToDrag}); + this.drag=new this.parent.module.drag({ + link:{ + elements:[etd], + ref:((this.options.fx.shadow===true)?[this.elements.containerWindow,this.elements.shadow]:[this.elements.containerWindow]) + }, + limit:this.options.limit || false + }); + this.drag.events={ + init :this.events.init, + move :this.events.move, + finish :this.events.finish.concat(function(pan){ + pan.options.position.x=parseInt(pan.elements.containerWindow.style.left,10); + pan.options.position.y=parseInt(pan.elements.containerWindow.style.top,10); + }.extend(this.drag,this)) + }; + this.drag.cursor=this.options.cursorToDrag; + this.drag.make(); + } + /** + * Resize window + */ + if(this.options.control.resize) + { + this.parent.dom.setStyle(this.elements.resize,{cursor:"nw-resize"}); + this.resizeDrag=new this.parent.module.drag({ + link:{ + elements:[this.elements.resize], + ref:[] + }, + noCursorMove:true + }); + this.resizeDrag.cursor="nw-resize"; + this.resizeDrag.events={ + init :function(panel) + { + this.panelBeginSize=panel.options.size; + }.extend(this.resizeDrag,this), + move :function(panel){ + var np={ + x:this.currentCursorPosition.x-this.cursorStart.x, + y:this.currentCursorPosition.y-this.cursorStart.y + }; + panel.resize({ + w:this.panelBeginSize.w+np.x, + h:this.panelBeginSize.h+np.y + }); + }.extend(this.resizeDrag,this) + }; + this.resizeDrag.make(); + } + else + { + this.parent.dom.setStyle(this.elements.resize,{background:"transparent"}); + } + }; + this.makeTab=function(dynamic) + { + if(this.loading===true){return false;} + var thm = this.tab.display==="vertical"?"":"H"; + var tb =this.elements.tabOptions[this.tabSelected]; + tb.className="panel_tabOptionSelected"+thm+"___"+this.getTheme("tabOptionSelected"); + //tb.onmouseover = this.styles.tabCSS.sover.args(tb); + //tb.onmouseout = this.styles.tabCSS.sout.args(tb); + tb.onmouseover = function(o,j){ + o = window.event?o:j; + o.a.className=o.b; + }.args({a:tb,b:"panel_tabOptionSelectedOver"+thm+"___"+this.getTheme("tabOptionSelectedOver")}); + tb.onmouseout = function(o,j){ + o = window.event?o:j; + o.a.className=o.b; + }.args({a:tb,b:"panel_tabOptionSelected"+thm+"___"+this.getTheme("tabOptionSelected")}); + var tc = (typeof this.tab.options[this.tabSelected].content); + if(!dynamic) + { + /*this.parent.dom.setStyle(tb,this.styles.tabCSS.sel.concat({ + width :parseInt(this.parent.dom.getStyle(tb,"width"),10)-((!this.parent.browser.isIE)?3:0), + borderLeftWidth :4 + }));*/ + if(this.tab.display==="vertical") + { + var hj = (parseInt(this.parent.dom.getStyle(tb,"width"),10)-((!this.parent.browser.isIE)?3:0)); + this.parent.dom.setStyle(tb,{ + width :hj, + borderLeftWidth :4 + }); + } + else + { + this.parent.dom.setStyle(tb,{ + //height :parseInt(this.parent.dom.getStyle(tb,"height"),10)-((!this.parent.browser.isIE)?3:0), + //borderTopWidth :4, + //paddingTop :5 + }); + } + } + tb.onmouseup=function(){return false;}; + if(this.tabLastSelected!==false) + { + var tls =this.elements.tabOptions[this.tabLastSelected]; + tls.className="panel_tabOption"+thm+"___"+this.getTheme("tabOption"); + //tls.onmouseover = this.styles.tabCSS.over.args(tls); + tls.onmouseover = function(o,j){ + o = window.event?o:j; + o.a.className=o.b; + }.args({a:tls,b:"panel_tabOptionOver"+thm+"___"+this.getTheme("tabOptionOver")}); + //tls.onmouseout = this.styles.tabCSS.out.args(tls); + tls.onmouseout = function(o,j){ + o = window.event?o:j; + o.a.className=o.b; + }.args({a:tls,b:"panel_tabOption"+thm+"___"+this.getTheme("tabOption")}); + tls.onmouseup=function(event,tabID){ + if(this.tab.manualDisabled){return false;} + this.tabSelected=(this.parent.browser.isIE)?event:tabID; + this.makeTab(); + //this.resize(); + return false; + }.extend(this,this.tabLastSelected); + + /*this.parent.dom.setStyle(tls,this.styles.tabCSS.def.concat({ + width :parseInt(this.parent.dom.getStyle(tb,"width"),10)+((!this.parent.browser.isIE)?3:0), + borderLeftWidth :1 + }));*/ + + if(this.tab.display==="vertical") + { + this.parent.dom.setStyle(tls,{ + width :parseInt(this.parent.dom.getStyle(tb,"width"),10)+((!this.parent.browser.isIE)?3:0), + borderLeftWidth :1 + }); + } + else + { + this.parent.dom.setStyle(tls,{ + //height :parseInt(this.parent.dom.getStyle(tb,"height"),10)+((!this.parent.browser.isIE)?3:0), + //borderTopWidth :1, + //paddingTop :10 + }); + } + this.parent.dom.setStyle(tls,this.setStyle.tabOption || {}); + } + this.parent.dom.setStyle(tb,this.setStyle.tabOptionSelected || {}); + if(!this.tab.options[this.tabSelected].noClear) + { + this.clearContent(); + } + this.addContent(this.tab.options[this.tabSelected].content); + + this.tabLastSelected=this.tabSelected; + return true; + }; + this.selectTab=function(tab) + { + if(tab>=this.elements.tabOptions.length){return false;} + if(this.tabSelected===tab){ + this.tabLastSelected=false; + } + this.tabSelected = tab; + this.makeTab((this.tabLastSelected===false)?true:false); + return true; + }; + this.shadowReIndex=function() + { + this.parent.dom.setStyle(this.elements.shadow,{ + zIndex :this.zIndex-2 + }); + }; + this.reIndexElements=function() + { + + }; + this.controlPosition=function() + { + var cl=this.controls.length+1; + return ((3*cl)+(this.controlSize.w*this.controls.length)); + }; + this.makeTmpDB=function() + { + if(!this.parent.tmp.panel) + { + this.parent.tmp.panel={}; + this.parent.tmp.panel.zIndex=100; + } + }; + this.makezIndex=function() + { + this.parent.tmp.panel.zIndex+=this.stepZindex; + return this.parent.tmp.panel.zIndex; + }; + this.target=function() + { + return (this.options.target)?this.options.target:this.parent.dom.capture("tag.body 0"); + }; + /** + * + * @return {Int} h Height border,padding of Top/Bottom Panel + * + */ + this.spaceOutPanel=function() + { + var brdr={ + x:(parseInt(this.parent.dom.getStyle(this.elements.content,"marginLeft") || 0,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"marginRight") || 0,10)), + y:(parseInt(this.parent.dom.getStyle(this.elements.content,"marginTop") || 0,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"marginBottom") || 0,10)) + }; + var pddn={ + x:(parseInt(this.parent.dom.getStyle(this.elements.content,"paddingLeft") || 0,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"paddingRight") || 0,10)), + y:(parseInt(this.parent.dom.getStyle(this.elements.content,"paddingTop") || 0,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"paddingBottom") || 0,10)) + }; + var bbb={ + x:(parseInt(this.parent.dom.getStyle(this.elements.content,"borderLeftWidth") || 1,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"borderRightWidth") || 1,10)), + y:(parseInt(this.parent.dom.getStyle(this.elements.content,"borderTopWidth") || 1,10)+parseInt(this.parent.dom.getStyle(this.elements.content,"borderBottomWidth") || 1,10)) + }; + //alert(brdr.y+((this.parent.browser.isIE)?-1:pddn.y+1)+2) + return { + //x:brdr.x+((this.parent.browser.isIE)?0:pddn.x)+bbb.x, + x:brdr.x+pddn.x+bbb.x, + //y:brdr.y+((this.parent.browser.isIE)?-1:pddn.y+1)+bbb.y + y:brdr.y+pddn.y+bbb.y + }; + }; + this.roll=function() + { + if(this.rolling){return false;} + if(this.inroll===true) + { + this.rolling=true; + this.inroll=false; + this.parent.dom.setStyle(this.elements.containerWindow,{ + overflow:"hidden", + //height :this.options.size.h, + width :this.lastWidth + }); + this.parent.dom.setStyle([this.elements.content,this.elements.statusBar],{ + display:"block" + }); + new this.parent.module.fx.algorithm().make({ + transition :"sineOut", + duration :1000, + begin :this.elements.containerWindow.offsetHeight, + end :this.options.size.h, + onTransition :function(fx){ + this.parent.dom.setStyle([this.elements.containerWindow],{ + height:fx.result + }); + if(this.options.fx.shadow) + { + this.styles.shadow(); + } + + }.extend(this), + onFinish :function(fx){ + this.parent.dom.setStyle([this.elements.containerWindow],{ + height:this.options.size.h + }); + if(this.options.fx.shadow) + { + this.styles.shadow(); + } + this.parent.dom.setStyle(this.elements.frontend,{ + width:"auto" + }); + this.rolling=false; + return (this.events.roll || function(){})(); + }.extend(this) + }); + } + else + { + this.rolling=true; + this.inroll=true; + //alert(this.parent.dom.getStyle(this.elements.titleBar,"height")+":"+this.elements.titleBar.clientHeight) + this.lastWidth=this.options.size.w || this.elements.containerWindow.offsetWidth; + this.parent.dom.setStyle(this.elements.containerWindow,{ + overflow:"hidden", + //height :this.elements.titleBar.clientHeight, + width :this.options.fx.rollWidth || this.lastWidth + }); + new this.parent.module.fx.algorithm().make({ + transition :"sineOut", + duration :1000, + begin :this.elements.containerWindow.offsetHeight, + end :this.elements.titleBar.offsetHeight, + onTransition :function(fx){ + this.parent.dom.setStyle([this.elements.containerWindow],{ + height:fx.result + }); + if(this.options.fx.shadow) + { + this.styles.shadow(); + } + + }.extend(this), + onFinish :function(fx){ + this.parent.dom.setStyle([this.elements.containerWindow],{ + height:this.elements.titleBar.clientHeight + }); + this.parent.dom.setStyle([this.elements.content,this.elements.statusBar],{ + display:"none" + }); + if(this.options.fx.shadow) + { + this.styles.shadow(); + } + this.parent.dom.setStyle(this.elements.frontend,{ + width:"100%" + }); + this.rolling=false; + return (this.events.roll || function(){})(); + }.extend(this) + }); + } + }; + this.remove=function() + { + //alert(this.parent.dom.getOpacity(this.elements.shadow)) + if(this.inRemove===true){return false;}else{this.inRemove=true;} + var e = []; + if(this.options.fx.fadeOut===true) + { + e.push(this.elements.containerWindow); + //e.push(this.elements.shadow); + //e.push(this.elements.modal); + } + if(this.options.fx.shadow) + { + e.push(this.elements.shadow); + } + if(this.options.fx.modal) + { + e.push(this.elements.modal); + } + if(this.events.remove) + { + this.events.remove=(this.events.remove.isArray)?this.events.remove:[this.events.remove]; + for(var i=0;i
    "); + } + + } + else + { + this.addContent(new DOM('iframe',{ + src:options.url + },{ + border:"0px solid red", + height:"100%", + width:"100%" + })); + } + return true; + }; + this.clearContent=function() + { + this.elements.content.innerHTML=""; + return true; + }; + this.addContentTitle=function(content) + { + if(typeof content=="string") + { + this.elements.title.innerHTML=content; + return true; + } + else if(typeof content=="object") + { + this.elements.title.appendChild(content); + return true; + } + return false; + }, + this.addContentStatus=function(content) + { + if(typeof content=="string") + { + this.elements.status.innerHTML+=content; + } + else if(typeof content=="object") + { + this.elements.status.appendChild(content); + } + if(!this.showing.status){ + this.status.show(); + } + return true; + }; + this.clearContentStatus=function() + { + this.elements.status.innerHTML=""; + return true; + }; + this.fx={ + setOpacity:function() + { + //alert(this.styles.fx.opacityPanel.Static/100) + this.parent.dom.setStyle(this.elements.containerWindow,{ + opacity:this.styles.fx.opacityPanel.Move/100, + filter:"alpha(opacity="+this.styles.fx.opacityPanel.Move+")" + }); + if(this.options.fx.shadow===true){ + this.parent.dom.setStyle(this.elements.shadow,{ + opacity:this.styles.fx.opacityShadow.Move/100, + filter:"alpha(opacity="+this.styles.fx.opacityShadow.Move+")" + }); + } + }, + unsetOpacity:function() + { + this.parent.dom.setStyle(this.elements.containerWindow,{ + opacity:this.styles.fx.opacityPanel.Static/100, + filter:"alpha(opacity="+this.styles.fx.opacityPanel.Static+")" + }); + if(this.options.fx.shadow===true){ + this.parent.dom.setStyle(this.elements.shadow,{ + opacity:this.styles.fx.opacityShadow.Static/100, + filter:"alpha(opacity="+this.styles.fx.opacityShadow.Static+")" + }); + } + } + }.expand(this); + this.styles={ + containerWindow:function() + { + this.options.size.w = this.options.size.w || 200; + this.options.size.h = this.options.size.h || 200; + if(this.options.intoDOM) + { + var center = { + x:(((this.target().offsetWidth/2)+this.target().scrollLeft)-(this.options.size.w/2)), + y:(((this.target().offsetHeight/2)+this.target().scrollTop)-(this.options.size.h/2)) + }; + } + else + { + var scroll = this.parent.dom.getPageScroll(); + this.parent.dom.get_doc() + var center = { + x:((((this.parent.dom.get_doc().clientWidth)/2)+scroll[0])-(this.options.size.w/2)), + y:((((this.parent.dom.get_doc().clientHeight)/2)+scroll[1])-(this.options.size.h/2)) + }; + } + if(this.options.position.center===true) + { + this.options.position.x = center.x; + this.options.position.y = center.y; + } + else if(this.options.position.centerX===true || this.options.position.centerY===true) + { + this.options.position.x = ((this.options.position.centerX===true)?center.x:(this.options.position.x || 0)); + this.options.position.y = ((this.options.position.centerY===true)?center.y:(this.options.position.y || 0)); + } + else + { + this.options.position.x = this.options.position.x || 0; + this.options.position.y = this.options.position.y || 0; + } + + if(this.options.strict_position) + { + this.options.position.x = (this.options.position.x<0)?0:this.options.position.x; + this.options.position.y = (this.options.position.y<0)?0:this.options.position.y; + } + + + this.zIndex = this.options.zIndex || this.makezIndex(); + this.parent.dom.setStyle(this.elements.containerWindow,{ + width : this.options.size.w, + height : this.options.size.h, + //border:"1px solid #A3A2BC", + position :"absolute", + left : this.options.position.x, + top : this.options.position.y, + opacity : this.styles.fx.opacityPanel.Static/100, + filter : "alpha(opacity="+this.styles.fx.opacityPanel.Static+")", + zIndex : this.zIndex + }); + this.parent.dom.setStyle(this.elements.containerWindow,this.setStyle.containerWindow || {}); + }, + frontend:function() + { + this.parent.dom.setStyle(this.elements.frontend,{ + width:(this.parent.browser.isIE)?"auto":"100%" + //height:"100%", + //position:"absolute", + //backgroundColor:"#FFFFFF", + //zIndex:2, + //overflow:"hidden", + //top:0, + //left:0 + }); + this.parent.dom.setStyle(this.elements.frontend,this.setStyle.frontend || {}); + + }, + backend:function() + { + this.parent.dom.setStyle(this.elements.backend,{ + //width:"100%", + //height:"100%", + //position:"absolute", + //overflow:"hidden", + //zIndex:1, + //top:0, + //left:0 + }); + this.parent.dom.setStyle(this.elements.backend,this.setStyle.backend || {}); + + }, + loader:function() + { + this.parent.dom.setStyle(this.elements.loader,{ + //display:"none", + background:"url('"+this.parent.path_root+"maborak/core/images/loader_B.gif')", + backgroundRepeat:"no-repeat", + width:32, + height:32, + position:"absolute", + display:"none" + }); + this.parent.dom.setStyle(this.elements.loader,this.setStyle.loader || {}); + }, + iframe:function() + { + this.parent.dom.setStyle(this.elements.iframe,{ + //width:"100%", + //height:"100%", + //position:"absolute", + //overflow:"hidden", + //zIndex:1, + //top:0, + //left:0 + }); + this.parent.dom.setStyle(this.elements.iframe,this.setStyle.iframe || {}); + + }, + titleBar:function() + { + this.parent.dom.setStyle(this.elements.titleBar,{ + //position:"relative", + display:((!this.options.titleBar)?"none":"") + //overflow:"hidden" + //background:"url("+this.parent.info.base+"images/panel.bg.title.gif)", + //backgroundColor:"white", + //backgroundRepeat:"repeat-x" + //borderBottom:"1px solid #DBE0E5" + + }); + this.parent.dom.setStyle(this.elements.titleBar,this.setStyle.titleBar || {}); + }, + title:function() + { + this.parent.dom.setStyle(this.elements.title,{ + //textAlign:"center", + //width:"100%", + //height:"100%", + //color:"black", + //font:"normal 8pt Tahoma,MiscFixed", + //fontWeight:"bold", + //paddingLeft:5, + //paddingTop:3, + //zIndex:1 + }); + this.parent.dom.setStyle(this.elements.title,this.setStyle.title || {}); + }, + roll:function() + { + this.parent.dom.setStyle(this.elements.roll,{ + //position:"absolute", + //top:3, + //font:"normal 0pt tahoma", + //padding:0, + right:this.controlPosition(), + height:this.controlSize.h, + width:this.controlSize.w + //border:"1px solid #006699", + //zIndex:2 + }); + this.parent.dom.setStyle(this.elements.roll,this.setStyle.roll || {}); + this.parent.event.add(this.elements.roll,"mouseup",this.roll,false); + }, + setup:function() + { + this.parent.dom.setStyle(this.elements.setup,{ + //position:"absolute", + //top:3, + //font:"normal 0pt tahoma", + //padding:0, + right:this.controlPosition(), + height:this.controlSize.h, + width:this.controlSize.w + //border:"1px solid #006699", + //zIndex:2 + }); + this.parent.dom.setStyle(this.elements.setup,this.setStyle.setup || {}); + this.parent.event.add(this.elements.setup,"mouseup",(this.options.setup && typeof this.options.setup=='function')?this.options.setup:function(){return false;},false); + }, + close:function() + { + this.parent.dom.setStyle(this.elements.close,{ + //font :"normal 0pt tahoma", + //padding :0, + //position:"absolute", + height :this.controlSize.h, + //top :3, + right :this.controlPosition(), + width :this.controlSize.w + //background:"url("+this.parent.info.base+"images/panel.close.static.gif)" + //cursor :"hand", + //zIndex :2 + }); + this.parent.dom.setStyle(this.elements.close,this.setStyle.close || {}); + /*this.elements.close.onmouseover=this.parent.closure({ + method:function(){ + this.parent.dom.setStyle(this.elements.close,{ + background:"url("+this.parent.info.base+"images/panel.close.over.gif)", + cursor:"pointer" + }); + }, + instance:this + }); + this.elements.close.onmouseout=this.parent.closure({ + method:function(){ + this.parent.dom.setStyle(this.elements.close,{ + background:"url("+this.parent.info.base+"images/panel.close.static.gif)", + cursor :"pointer" + }); + }, + instance:this + });*/ + /*this.elements.close.onmouseup=this.parent.closure({ + method:this.remove, + instance:this + });*/ + this.parent.event.add(this.elements.close,"mouseup",this.remove,false); + }, + headerBar:function() + { + this.parent.dom.setStyle(this.elements.headerBar,{ + //position:"relative", + display:((!this.options.headerBar)?"none":"block") + //overflow:"hidden" + //background:"url("+this.parent.info.base+"images/panel.bg.title.gif)", + //backgroundColor:"white", + //backgroundRepeat:"repeat-x" + //borderBottom:"1px solid #DBE0E5" + + }); + this.parent.dom.setStyle(this.elements.headerBar,this.setStyle.headerBar || {}); + }, + shadow:function() + { + //alert((parseInt(this.parent.dom.getStyle(this.elements.containerWindow,"top"),10)+2)+":"+(parseInt(this.parent.dom.getStyle(this.elements.containerWindow,"left"),10)+2)) + //alert(parseInt(this.parent.dom.getStyle(this.elements.containerWindow,"top"),10)+2) + this.parent.dom.setStyle(this.elements.shadow,{ + width :this.elements.containerWindow.offsetWidth, + height :this.elements.containerWindow.offsetHeight, + //position:"absolute", + top :(parseInt(this.parent.dom.getStyle(this.elements.containerWindow,"top"),10)+2), + left :(parseInt(this.parent.dom.getStyle(this.elements.containerWindow,"left"),10)+2), + //backgroundColor:"#CCCCCC", + opacity :this.styles.fx.opacityShadow.Static/100, + filter :"alpha(opacity="+this.styles.fx.opacityShadow.Static+")", + zIndex :this.zIndex-2 + }); + this.parent.dom.setStyle(this.elements.shadow,this.setStyle.shadow || {}); + }, + modal:function() + { + //if(this.parent.browser.isIE) + //{ + //var h = (this.parent.browser.isIE)?this.target().scrollHeight:this.target().scrollHeight; + //var ps = this.parent.dom.getPageSize(); + //var ps = this.parent.dom.getPageSize(); + //alert(this.parent.dom.get_doc()); + //alert(window.document.compatMode+":"+window.document.html+":"+window.document.body+":"+this.parent.dom.get_doc()+":"); + //alert(this.parent.dom.getDoc()+":"+this.parent.dom.getDoc().scrollHeight) + var ps = [this.parent.dom.get_doc().scrollWidth,this.parent.dom.get_doc().scrollHeight]; + //alert(ps[1]); + //alert(this.target().scrollHeight) + this.parent.dom.setStyle(this.elements.modal,{ + height :ps[1], + width :ps[0], + position:"absolute", + zIndex :this.zIndex-3 + }); + /*} + else + { + this.parent.dom.setStyle(this.elements.modal,{ + height :"100%", + width :"100%", + //position:"fixed", + zIndex :this.zIndex-3 + }); + }*/ + if(this.options.fx.fadeIn===true) + { + new this.parent.module.fx.fade().make({ + duration :1000, + end :this.styles.fx.opacityModal.Static/100, + dom :this.elements.modal + }); + } + else + { + this.parent.dom.opacity(this.elements.modal,this.styles.fx.opacityModal.Static); + } + + this.parent.dom.setStyle(this.elements.modal,this.setStyle.modal || {}); + }, + tab:function() + { + + this.tab = { + display :"horizontal", + initIn :20, + step :5, + optHeight:20, + widthFixed:true, + optWidth:this.tab.width-4 + }.concat(this.tab); + var thm = this.tab.display==="vertical"?"":"H"; + var heightContent = this.options.size.h-(this.elements.titleBar.offsetHeight+this.elements.statusBar.offsetHeight); + //alert(this.elements.headerBar.offsetHeight+":"+this.elements.headerBar.clientHeight) + var beginTop = this.elements.titleBar.offsetHeight+this.elements.headerBar.offsetHeight; + var beginLeft = 4; + var space = this.spaceOutPanel(); + this.tab.width = (this.tab.display==="vertical")?((this.tab.options)?((this.tab.width)?this.tab.width:80):0):4; + this.parent.dom.setStyle(this.elements.tab,this.setStyle.tab || {}); + if(this.tab.options) + { + this.parent.dom.setStyle(this.elements.tab,{ + height :((this.tab.display==="vertical")?heightContent:this.tab.optHeight+4), + //border :"1px solid red", + width :((this.tab.display==="vertical")?this.tab.width:this.options.size.w-8), + top :beginTop, + left :((this.tab.display==="vertical")?0:4) + }); + + this.tabSelected = false; + this.tabLastSelected = false; + /*this.tab.initIn = this.tab.initIn || 20; + this.tab.step = (typeof this.tab.step=="number")?this.tab.step:5; + this.tab.optHeight = this.tab.optHeight || 25; + this.tab.optWidth = (this.tab.optWidth || (this.tab.width -4));*/ + this.tab.diffWidthBugPadding = ((this.parent.browser.isIE)?0:20); + this.elements.tabOptions=[]; + var lastBul = 0; + for(var i=0;i +* Version : 0.2 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +/** +* @class rpc +*/ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.rpc.js", + Name :"rpc", + Type :"module", + Version :"0.1" + }, + content :{ + /* + * @class xmlhttp + * @param {Object} options Options + * @param {String} options.url Url to Open + * @param {String} options.method Method + * @param {String} options.arguments Arguments [Optional,Default=""] + * @param {String} options.async Asynchronous? [Optional,Default=true] + * + * @param {Function | Object | Virtual function} Instance.callback Callback for this process + * @example: + * var process = new leimnud.module.rpc.xmlhttp({ + * url :"g.xml", + * method :"POST", + * arguments :"u=iuiu" + * }); + * process.callback=functionCallback; + * + * || + * + * process.callback=leimnud.closure({method:Myinstance.callback,instance:MyInstance,arguments:[process,"demo",99]}); + * + * || + * + * process.callback={Function:myFunction,arguments:[process,"demo"]}; + * process.make(); + * + */ + xmlhttp:function(options) + { + this.options=options || {}; + this.headers=[]; + this.core = function() + { + try{ + var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch(e) + { + try + { + var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch(e) + { + var xmlhttp = false; + } + } + return (!xmlhttp && typeof XMLHttpRequest!='undefined')? + new XMLHttpRequest():xmlhttp || new function(){}; + }; + /* + * Make this process + */ + this.make=function() + { + this.xmlhttp = this.core(); + this.url = this.options.url || false; + if(!this.options.url || !this.xmlhttp){return false;} + this.method = (this.options.method || "POST").toUpperCase(); + this.args = this.options.args || ""; + this.async = (this.options.async===false)?false:true; + if(this.method=="POST"){this.header("Content-Type","application/x-www-form-urlencoded");} + this.open(); + return true; + }; + + /* + * + * Open this.options.url request + * + */ + this.open=function() + { + this.url = ((this.url.substr(this.url.length-1,1)!=="?" && this.method==="GET")?this.url+"?":this.url); + this.url = ((this.method=="GET")?(this.url+this.args):this.url); + this.xmlhttp.open(this.method,this.url+((this.options.nocache)?"&rand_rpc="+Math.random():""),this.async); + this.applyHeaders(); + this.xmlhttp.send((this.method=="GET")?null:this.args); + //this.xmlhttp.onreadystatechange=this.parent.closure({method:this.changes,instance:this,args:98989898}); + this.xmlhttp.onreadystatechange=this.changes; + }; + /* + * + * Method for this.xmlhttp.onreadystatechange + * + */ + this.changes=function(g) + { + if (this.xmlhttp.readyState==4) + { + if(this.callback) + { + //this.callback=(this.callback.isObject)?this.parent.closure(this.callback):this.callback; + this.callback.args(this)(); + } + } + }; + /* + * + * Apply headers + * + */ + this.applyHeaders=function() + { + for(var i=0;i65000) + { + this.interval = clearInterval(this.interval); + var rt; + try{ + rt = window[this.tmp].data.parseJSON(); + } + catch(e) + { + rt = ""; + } + if(this.options.debug===true && console.info) + { + console.info(rt) + } + /* Create XML BEGIN */ + var myDocument; + if(document.implementation.createDocument) + { + var parser = new DOMParser(); + try{ + window.lk = myDocument = parser.parseFromString(rt || "empty", "text/xml"); + }catch(e) + { + myDocument = parser.parseFromString("empty", "text/xml"); + } + } else if (window.ActiveXObject){ + myDocument = new ActiveXObject("Microsoft.XMLDOM"); + myDocument.async="false"; + try{ + myDocument.loadXML(rt || "empty"); + } + catch(e) + { + myDocument.loadXML("empty"); + } + } + /* Create XML END */ + this.json ={ + responseText:rt, + responseXML:myDocument + }; + if(this.parent.browser.isIE) + { + window[this.tmp]=null; + } + else + { + delete window[this.tmp]; + } + this.script.parentNode.removeChild(this.script); + if(this.callback) + { + this.callback.args(this)(); + } + } + }; + this.expand(this); + return this; + } + } +}); diff --git a/gulliver/js/maborak/core/module.rss.js b/gulliver/js/maborak/core/module.rss.js new file mode 100755 index 000000000..8ef9a5af2 --- /dev/null +++ b/gulliver/js/maborak/core/module.rss.js @@ -0,0 +1,732 @@ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.rss.js", + Name :"rss", + Type :"module", + Version :"0.2" + }, + content :function(){ + this.make=function(options) + { + options = options || {}; + this.modes = ["remote","local"]; + this.options = { + mode:(this.modes.inArray((options.mode || "remote"))?options.mode:"local") + }; + this.options = (this.options.mode=="remote" || options.openFeed)?{ + rpc :"json", + mode :"remote", + fileJson:this.parent.info.base+"data/maborak.module.rss.feeds.json", + proxy :this.parent.info.base+"server/maborak.module.rss.php" + }:{ + mode :"local", + rpc :"xmlhttp", + proxy :"server/maborak.module.rss.php", + fileJson :"data/maborak.module.rss.feeds.json" + }.concat(this.options); + this.options = this.options.concat({ + fromObject:false, + theme :"gray", + multiple :true, + Default :0, + target :document.body, + toolbar :true, + saveDataIn:"json", /*Support: cookie,json*/ + cookieFeed:"maborak.module.rss.feeds", + width :250, + inline :false, + title :"Rss Reader", + feed :[] + }).concat(options || {}).concat({ + multiple :((this.options.openFeed)?false:true) + }); + this.options.target=this.setTarget(); + this.driverRPC = ["xmlhttp","json"]; + this.options.rpc = (this.driverRPC.inArray(this.options.rpc))?this.options.rpc:"xmlhttp"; + this.elements={ + interface:{}, + rootItems:[], + items:[] + }; + var tg = new DOM('div',{ + className:"module_rss_container___"+this.options.theme + },{width:this.options.width}); + this.options.feed = (!this.options.feed.isArray)?[this.options.feed]:this.options.feed; + $(this.options.target).append(tg); + this.options.target = tg; + if(this.options.saveDataIn=="cookie") + { + this.options.feed = this.options.feed.concat((this.parent.cookie.get(this.options.cookieFeed) || "[]").parseJSON()); + return this.beforeLoad(); + } + else if(this.options.saveDataIn=="json") + { + this.message("Loading feeds......"); + if(this.options.openFeed) + { + this.options.feed = [ + {url:this.options.openFeed,proxy:true} + ]; + this.clearMessage(); + return this.beforeLoad(); + } + else + { + var r = new this.parent.module.rpc[this.options.rpc]({ + method :"GET", +// debug :true, + url :this.options.fileJson + }); + r.callback=function(rpc) + { + try{ + var ed = rpc[this.options.rpc].responseText.parseJSON(); + var f = ed.feeds || []; + } + catch(e) + { + var ed = {category:["General"],feeds:[]}; + var f = ed.feeds; + } + this.categoryArray=(ed.category && ed.category.isArray && ed.category.length>0)?ed.category:["General"]; + this.options.feed = this.options.feed.concat(f || []); + this.clearMessage(); + return this.beforeLoad(); + }.extend(this); + r.make(); + } + } + }; + this.setTarget=function() + { + if(this.options.inline===true) + { + var rnd ="rss_"+new Date().getTime(); + document.write("
    "); + return $(rnd); + } + else + { + return this.options.target; + } + }; + this.beforeLoad=function() + { + if(this.options.fromObject) + { + this.show(this.options.fromObject); + } + else + { + this.renderHeader(); + this.load(this.options.Default); + } + return true; + }; + this.reload=function() + { + this.load(this.current); + return false; + }; + this.load=function(feedIndex) + { + this.lock(); + this.clear(); + if(this.options.feed.length===0){ + this.message("No se registraron Feeds."); + return false; + } + this.clearMessage(); + this.message("Loading...."); + this.current = feedIndex; + var feed= this.options.feed[feedIndex]; + var url = (this.options.mode=="local" && feed.proxy===true)?this.options.proxy || feed.url:feed.url; + var rpc = new this.parent.module.rpc[this.options.rpc]({ + url : url, + method : ((this.options.mode=="local")?"POST":"GET"), + args : ((feed.proxy && this.options.mode==='local')?"action=proxy&url="+encodeURIComponent(feed.url):"") + }); + rpc.callback = function(rpc) + { + this.clearMessage(); + this.feedArray = this.feedXmlToObject(rpc[this.options.rpc].responseXML); + this.renderItems(this.feedArray); + this.unlock(); + }.extend(this); + rpc.make(); + }; + this.feedXmlToObject=function(DOMDocument) + { + var p = DOMDocument; + var atom = this.tag(p,'feed',0); + var rss = this.tag(p,'rss',0); + var rdf = this.tag(p,'RDF',0); + this.type = ((rss || rdf) && !atom)?"rss":((atom && !rss)?"atom":"error"); + var channel = (this.type=='atom')?atom:this.tag(rss,'channel',0); + var f = { + title : (this.tag(channel,'title',0,true) || '').escapeHTML(), + description : (this.tag(channel,'description',0,true) || '').stripScript(), + language : (this.tag(channel,'language',0,true) || 'en').escapeHTML(), + generator : (this.tag(channel,'generator',0,true) || 'text').escapeHTML(), + lastBuildDate : this.tag(channel,'lastBuildDate',0,true) || new Date(), + author : (this.tag(channel,'author',0,true) || '').escapeHTML(), + email : (this.tag(channel,'email',0,true) || '').escapeHTML(), + item : [] + }; + var items = this.tag((rdf)?rdf:channel,(this.type=='rss')?'item':'entry'); + for(var i=0;iPublished date:
    "+feedItem.pubDate}), + description = new DOM('div',{className:"module_rss_itemDescription___"+this.options.theme,innerHTML:feedItem.description || "
    "}), + hr = new DOM('hr' ,{className:"module_rss_itemHr___"+this.options.theme}), + content = new DOM('div',{className:"module_rss_itemContent___"+this.options.theme,innerHTML:feedItem.content || "
    "}), + link = new DOM('div',{className:"module_rss_itemLink___"+this.options.theme}).append( + new button("Save").disable(), + new button("Read",function(evt,button,i){ + var ln = (this.parent.browser.isIE)?button:i; + var link = this.feedArray.item[ln].link; + window.open(link); + }.extend(this,i),false,{title:"Read more"}), + new button("Send",this.send.args(i)) + ) + ); + var header,title,buttons,item; + this.options.target.appendChild(item = new DOM('div',{ + className:"module_rss_item___"+this.options.theme+" "+(((i+1)==Obj.item.length)?"module_rss_itemLast___"+this.options.theme:"") + }).append( + header = new DOM('div',{ + className:"module_rss_itemHeader___"+this.options.theme, + title :"Published date: "+feedItem.pubDate, + onmouseover:function(){ + this.className=this.className+" module_rss_itemOver"; + }, + onmouseout:function() + { + this.className=this.className.split(" ")[0]; + } + }).append( + title = new DOM('div',{ + className:"module_rss_itemTitle___"+this.options.theme+((feedItem.readed)?" module_rss_itemReaded___"+this.options.theme:""), + innerHTML:(i+1)+".- "+feedItem.title + }), + buttons = new DOM('div',{className:"module_rss_itemButtons___"+this.options.theme}).append( + ) + ), + container + ) + ); + //console.info((itemPubDate.clientHeight)+":"+(content.clientHeight)+":"+(description.clientHeight)+":"+(link.clientHeight)); + var contentHeight = ((itemPubDate.clientHeight)+(description.clientHeight)+(hr.clientHeight)+(content.clientHeight)+(link.clientHeight)); + this.parent.dom.setStyle(container,{ + display:"none", + overflow:((contentHeight>3)?"auto":"hidden") + }); + contentHeight = (contentHeight>300)?300:contentHeight; + header.onmouseup=function(evt,data) + { + data = (this.parent.browser.isIE)?evt:data; + return this.show(data.index); + }.extend(this,{index:i}); + this.elements.rootItems.push(item); + this.elements.items.push({ + title :title, + container :container, + height :contentHeight + }); + } + }; + this.show=function(item) + { + if(this.inprogress){return false;} + this.inprogress=true; + data = this.elements.items[item]; + var title = data.title; + var container = data.container; + var visible = (container.style.display=="none")?false:true; + if(!visible) + { + container.setStyle({ + height:1, + display:"" + }); + this.setReaded(item); + title.setStyle({fontWeight:"bold"}); + new this.parent.module.fx.algorithm().make({ + duration : 500, + begin : container.clientHeight, + transition : "sineInOut", + end : data.height, + onTransition: function(fx){ + this.parent.dom.setStyle(container,{ + height:fx.result + }); + }.extend(this), + onFinish:function(fx) + { + this.parent.dom.setStyle(container,{ + height:fx.end + }); + this.inprogress=false; + }.extend(this) + }); + } + else + { + new this.parent.module.fx.algorithm().make({ + duration : 500, + begin : container.clientHeight, + transition : "sineOut", + end : 4, + onTransition: function(fx){ + this.parent.dom.setStyle(container,{ + height:fx.result + }); + }.extend(this), + onFinish:function(fx) + { + this.parent.dom.setStyle(container,{ + height:fx.end, + display:"none" + }); + this.parent.dom.setStyle(title,{ + fontWeight:"normal" + }); + this.inprogress=false; + }.extend(this) + }); + + } + return false; + }; + this.lock=function() + { + if(this.options.multiple) + { + this.elements.feedSelector.disabled=true; + } + if(this.options.toolbar) + { + this.elements.interface.details.disable(); + this.elements.interface.reload.disable(); + } + }; + this.unlock=function() + { + if(this.options.multiple) + { + this.elements.feedSelector.disabled=false; + } + if(this.options.toolbar) + { + this.elements.interface.details.enable(); + this.elements.interface.reload.enable(); + } + }; + this.showDetails=function() + { + var myPanel=new leimnud.module.panel(); + myPanel.options={ + size:{w:300,h:370}, + position:{x:0,y:0,center:true}, + title:"", + theme:"processmaker", + control:{ + resize:false + }, + fx:{ + modal:true, + opacity:false + }, + statusBar:false + }; + myPanel.setStyle={ + content:{padding:2,background:"transparent",borderWidth:0} + }; + myPanel.make(); + + var gridCity = new leimnud.module.grid(); + gridCity.make({ + target :myPanel.elements.content, + theme :"gray", + search :false, + title :"Feed: "+(this.options.feed[this.current].title || this.options.feed[this.current].url), + noPaginator:true, + data :{ + column:[ + { + title:"Properties", + type:"text", + width:"40%", + style:{ + fontWeight:"bold" + }, + styleValues:{ + textAlign:"right", + border:"1px solid #AAA" + } + }, + { + title : "Value", + type : "text", + style:{ + fontWeight:"bold" + },styleValues:{ + border:"1px solid #AAA" + }, + width : "60%" + } + ], + rows:[ + { + data:[{value:"Items"},{value:this.feedArray.item.length}] + }, + {data:[{value:"Title"},{value:this.feedArray.title || ""}]}, + {data:[{value:"Description"},{value:this.feedArray.description || ""}]}, + {data:[{value:"Author"},{value:this.feedArray.author || ""}]}, + {data:[{value:"Email"},{value:this.feedArray.email || ""}]}, + {data:[{value:"Language"},{value:this.feedArray.language || ""}]}, + {data:[{value:"Generator"},{value:this.feedArray.generator || ""}]}, + {data:[{value:"Last update"},{value:this.feedArray.lastUpdate || ""}]}, + {data:[{value:"Feed url"},{value:"URL" || ""}]} + ] + } + }); + }; + this.addFeed=function(obj) + { + var index = this.options.feed.length; + if(this.options.saveDataIn=="cookie") + { + var added = (this.parent.cookie.get(this.options.cookieFeed) || "[]").parseJSON(); + added.push(obj); + this.parent.cookie.set(this.options.cookieFeed,added.toJSONString()); + } + else if(this.options.saveDataIn=="json") + { + this.elements.interface.add.disable(); + var ojs = encodeURIComponent(obj.toJSONString()); + //console.info(ojs); + var r = new this.parent.module.rpc[this.options.rpc]({ + method :"POST", + url :this.options.proxy, + args :"action=add&data="+ojs + }); + r.callback=function(rpc){ + try + { + var result = rpc[this.options.rpc].responseText.parseJSON(); + } + catch(e) + { + var result = {ok:"Error read/write json"}; + } + if(result.ok!=="ok") + { + new this.parent.module.app.alert().make({label:""+this.options.fileJson+"
    "+result}); + } + this.elements.interface.add.enable(); + }.extend(this); + r.make(); + } + this.options.feed.push(obj); + var fls = this.elements.feedSelector.options; + fls[fls.length] = new Option((fls.length+1)+".- "+(obj.title),index,true); +/* this.elements.feedSelector.append( + new Option(obj.title,index,true) + );*/ + this.load(index); + }; + this.send=function(evt,b,index) + { + index = (this.parent.browser.isIE)?b:index; + new this.parent.module.app.prompt().make({ + label:"Email address:", + action:function(value) + { + var f = this.feedArray.item[index]; + var c = f.content || ""+f.description || ""; + var l = f.link; + var ft= this.feedArray.title; + var r = new this.parent.module.rpc[this.options.rpc]({ + url :this.options.proxy, + method :((this.options.mode=="remote")?"GET":"POST"), + args :"action=sendmail&to="+value.trim()+"&subject="+encodeURIComponent(f.title)+"&content="+encodeURIComponent(c)+"&link="+encodeURIComponent(l)+"&feed="+encodeURIComponent(ft) + }); + r.callback=function(){ + /*new this.parent.module.app.alert().make({label:"Success"});*/ + }.extend(this); + r.make(); + }.extend(this) + }); + }; + this.open=function() + { + var myPanel=new leimnud.module.panel(); + myPanel.options={ + size:{w:330,h:155}, + position:{x:0,y:0,center:true}, + title:"Add New feed", + theme:"processmaker", + statusBarButtons:[ + {value:"Test Feed"}, + {value:"Add Feed"}, + {value:"Reset"}, + {value:"Cancel"} + ], + control:{ + resize:false + }, + fx:{ + modal:true, + opacity:false + }, + statusBar:true + }; + myPanel.setStyle={ + content:{padding:10,background:"transparent",borderWidth:0,overflow:"hidden"} + }; + myPanel.make(); + var table = $dce("table"); + myPanel.addContent(table); + table.className="app_grid_table___"+this.options.theme; + var url,title,probe; + $(table).append( + new DOM('tbody').append( + new DOM('tr').append( + new DOM('td',{innerHTML:"Url:"},{width:"25%",textAlign:"right"}), + new DOM('td',false,{width:"75%",padding:1}).append( + url = new input(false,{width:"100%"}) + ) + ), + new DOM('tr').append( + new DOM('td',{innerHTML:"Title:"},{textAlign:"right"}), + new DOM('td',false,{padding:1}).append( + title = new input(false,{width:"100%"}) + ) + ), + new DOM('tr').append( + new DOM('td',{innerHTML:"Category:"},{textAlign:"right"}), + new DOM('td',false,{padding:1}).append( + category = new this.parent.module.dom.select({ + data :this.categoryArray.toSelect().concat([{value:"new",text:"--- New category ---"}]), + properties:{onchange:function(){ + //alert(category.options[category.selectedIndex].value) + if(category.selected().value==="new") + { + new leimnud.module.app.prompt().make({ + label:"Category name:", + action:function(val) + { + //category.clear(); + this.categoryArray.push(val); + category.addOption({ + text :val, + value :this.categoryArray.length, + key :(category.options.length-1), + selected:true + }); + }.extend(this), + cancel:function() + { + category.selectedIndex=0; + } + }); + } + else + { + + } + }.extend(this)}, + style:{marginLeft:2} + }) + ) + ), + new DOM('tr').append( + probe = new DOM('td',{innerHTML:"",colSpan:2},{textAlign:"center",padding:1}) + ) + ) + ); + var but0 = myPanel.elements.statusBarButtons[0]; + var but1 = myPanel.elements.statusBarButtons[1]; + var but2 = myPanel.elements.statusBarButtons[2]; + url.focus(); + myPanel.elements.statusBarButtons[3].onmouseup=myPanel.remove; + but1.disable(); + but0.onmouseup=function() + { + var t = encodeURIComponent(url.value.trim()); + if(!t){return false;} + but0.disable(); + var rpc = new this.parent.module.rpc[this.options.rpc]({ + url : ((this.options.mode==='local')?this.options.proxy:url.value.trim()), +// debug : true, + method : ((this.options.mode==='local')?"POST":"GET"), + args : ((this.options.mode==='local')?"action=proxy&url="+encodeURIComponent(url.value.trim()):"") + }); + probe.innerHTML="Loading feed............."; + rpc.callback = function(rpc) + { + probe.innerHTML="Validating............."; + var xml = rpc[this.options.rpc].responseXML; + var atom = this.tag(xml,'feed',0); + var rss = this.tag(xml,'rss',0); + var rdf = this.tag(xml,'RDF',0); + but0.enable(); + if(atom || rss || rdf) + { + url.disable(); + title.disable(); + but0.disable(); + var tp = (rss)?"RSS":((rdf)?"RDF":"ATOM"); + probe.innerHTML="Feed "+tp+" valid"; + but1.enable(); + } + else + { + but1.disable(); + probe.innerHTML="Feed invalid"; + } + }.extend(this); + rpc.make(); + return false; + }.extend(this); + but1.onmouseup=function() + { + var u = url.value.trim(); + var t = title.value.trim() || u; + this.addFeed({ + url :u, + title :t, + proxy :true + }); + myPanel.remove(); + return false; + }.extend(this); + but2.onmouseup=function() + { + title.enable(); + url.enable(); + but0.enable(); + but1.disable(); + return false; + }.extend(this); + return false; + }; + this.tag=function(DOM,tag,node,value) + { + try + { + var o = DOM.getElementsByTagName(tag); + return (typeof node==='number')?((value)?o[node].firstChild.nodeValue:o[node]):o; + } + catch(e) + { + return false; + } + }; + this.expand(this); + } +}); diff --git a/gulliver/js/maborak/core/module.samples.js b/gulliver/js/maborak/core/module.samples.js new file mode 100644 index 000000000..1a0413bd4 --- /dev/null +++ b/gulliver/js/maborak/core/module.samples.js @@ -0,0 +1,262 @@ +var t,j,l,k,g,dAd,drop,myPanel,myPanel2,explain,panel=[],arg=[],wilDebug; +var samp = function() +{ + explain = { + core:{ + content:function(){ + myPanel.command(myPanel.loader.show); + var r = new leimnud.module.rpc.xmlhttp({url:"ex.core.php"}); + r.callback=leimnud.closure({Function:function(rpc){ + myPanel.command(myPanel.loader.hide); + myPanel.addContent(rpc.xmlhttp.responseText); + },args:r}) + r.make(); + }, + samples:{ + + } + }, + rpc:{ + content:function() + { + myPanel.command(myPanel.loader.show); + var r = new leimnud.module.rpc.xmlhttp({url:"ex.rpc.php"}); + r.callback=leimnud.closure({Function:function(rpc){ + myPanel.command(myPanel.loader.hide); + var scs=rpc.xmlhttp.responseText.extractScript(); + myPanel.addContent(rpc.xmlhttp.responseText.stripScript()); + scs.evalScript(); + },args:r}) + r.make(); + }, + samples:{ + + } + }, + panel:{ + content:function(){ + myPanel.command(myPanel.loader.show); + var r = new leimnud.module.rpc.xmlhttp({url:"ex.panel.php"}); + r.callback=leimnud.closure({Function:function(rpc){ + myPanel.command(myPanel.loader.hide); + /*var tg = new RegExp('(?:)((\n|\r|.)*?)(?:<\/pre>)', 'img'); + rpc.xmlhttp.responseText.match(tg).length);*/ + myPanel.addContent(rpc.xmlhttp.responseText); + /*[1,2,3].map(leimnud.closure({Function:function(kk){ + alert(3333+":"+kk) + }}));*/ + },args:r}) + r.make(); + + }, + samples:{ + panel1:function() + { + panel[0]=new leimnud.module.panel(); + panel[0].options={ + control:{roll:true} + }; + panel[0].make(); + panel[0].addContent("Hola mundo"); + }, + panel2:function() + { + panel[1]=new leimnud.module.panel(); + panel[1].options={ + size:{w:200,h:100}, + position:{x:50,y:50}, + title:"Panel 2", + theme:"processmaker_fixed", + control:{ + close:true + }, + fx:{ + shadow:false + } + }; + panel[1].make(); + panel[1].addContent("Hola mundo"); + }, + panel3:function() + { + panel[2]=new leimnud.module.panel(); + panel[2].options={ + size:{w:400,h:100}, + position:{x:50,y:50,center:true}, + title:"Panel 2", + theme:"processmaker_fixed", + control:{ + close:true, + drag:false + }, + fx:{ + modal:true + } + }; + panel[2].setStyle={ + modal:{ + backgroundColor:"black" + }, + shadow:{ + backgroundColor:"black" + }}; + panel[2].make(); + panel[2].addContent("Hola mundo"); + } + } + }, + grid:{ + content:function() + { + myPanel.loader.show(); + window.r = new leimnud.module.rpc.xmlhttp({ + url : "grid.json.data.load.php", + method : "post", + args : "action=loadSimpleGrid" + }); + r.callback=function(rpc,panel){ + window.grid = new leimnud.module.grid(); + grid.make({ + paginator :{ + limit : 5, + page : 1 + }, + server :"grid.json.data.load.php", + target :panel.elements.content, + theme :"gray", + title :"Discografía - Data grid", + search :true, + data :rpc.xmlhttp.responseText.parseJSON() + }); + var dv = $dce("div"); + myPanel.addContent(dv); + var r = new leimnud.module.rpc.xmlhttp({url:"ex.grid.php"}); + r.callback=function(rpc){ + panel.loader.hide(); + dv.innerHTML=rpc.xmlhttp.responseText; + }; + r.make(); + }.args(myPanel); + r.make(); + } + }, + app:{ + content:function() + { + myPanel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({url:"ex.app.php"}); + r.callback=leimnud.closure({Function:function(rpc){ + myPanel.loader.hide(); + //return; + myPanel.addContent(rpc.xmlhttp.responseText); + explain.app.samples.menu1(); + new leimnud.module.app.iframe("content_to_iframe"); + var sub = new leimnud.module.app.submit({ + form : document.forms['algun_formulario'] + }); + sub.callback = function(){ + alert(sub.rpc.xmlhttp.responseText) + }; + },args:r}) + r.make(); + }, + samples:{ + menu1:function() + { + var menuObserver=leimnud.factory(leimnud.pattern.observer,true); + leimnud.event.add(document.body,"click",leimnud.closure({instance:menuObserver,method:menuObserver.update})); + var menu = new leimnud.module.app.menuRight(); + menu.make({ + target:"menu1", + menu:[ + {text:"Option 1",launch:function(){alert("option 1")}}, + {text:"Option 2",launch:function(){alert("option 2")}}, + {text:"Option 3",launch:function(){alert("option 3")}} + ] + }); + menuObserver.register(leimnud.closure({instance:menu,method:menu.remove}),menu); + } + } + } + }; + myPanel=new leimnud.module.panel(); + var bod=leimnud.dom.capture("tag.body 0"); + myPanel.options={ + size:{w:bod.clientWidth-50,h:bod.clientHeight-50}, + position:{x:270,y:50,center:true}, + title:"Tutorial de maborak.js", + theme:"processmaker", + control:{ + //resize:true, + //drag:false, + //close:true, + roll:true + }, + statusBar:true + }; + myPanel.setStyle={ + content:{ + padding:15, + font:"normal 11px sans-serif, MiscFixed" + } + //modal:{backgroundColor:"black"}, + //shadow:{backgroundColor:"black"}, + //containerWindow:{border:"1px solid #666"} + }; + myPanel.styles.fx.opacityModal.Static=80 + myPanel.tab={ + width :110, + optWidth:100, + step :(leimnud.browser.isIE?-1:5), + options:[{ + title :"Core", + content :explain.core.content + },{ + title :"Paneles", + content :explain.panel.content + },{ + title :"Ajax / Rpc", + content :explain.rpc.content + },{ + title :"Drag & Drop", + content :"fgfgf" + },{ + title :"Data grid", + content :explain.grid.content + },{ + title :"Aplicaciones", + content :explain.app.content, + selected:true + }] + }; + myPanel.make(); + /*wilDebug = new leimnud.module.panel(); + wilDebug.options={ + size:{w:300,h:300}, + position:{x:5,y:5}, + control:{ + roll:true + }, + fx:{ + shadow:false, + fadeIn:true + } + }; + wilDebug.events={ + remove:function() + { + + } + }; + wilDebug.make();*/ +}; +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.samples.js", + Name :"samples", + Type :"module", + Version :"0.1" + }, + content :samp +}); diff --git a/gulliver/js/maborak/core/module.services.js b/gulliver/js/maborak/core/module.services.js new file mode 100644 index 000000000..d041485ee --- /dev/null +++ b/gulliver/js/maborak/core/module.services.js @@ -0,0 +1,234 @@ +/*************************************************************************** +* module.dashboard.js +* ------------------------ +* Copyleft : (c) 2007 maborak.com +* Version : 0.2 +* +***************************************************************************/ + +/*************************************************************************** +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +***************************************************************************/ +/** +* @class services +*/ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.services.js", + Name :"services", + Type :"module", + Version :"0.1" + }, + content :{ + provider:function(provider){ + this.provider=provider; + this.Execute=function(options,callback) + { + this.options = { + service:"test", + action :"test", + data:{ + id:1, + uid:1 + } + }.concat(options || {}); + this.callback = callback || function(){}; + var rpc = new this.parent.module.rpc['json']({ + url : this.provider, + method : 'POST', + args : "data="+this.options.toJSONString() + }); + rpc.callback = function(rpc) + { + this.callback(rpc['json'].responseText); + }.extend(this); + rpc.make(); + return this; + }; + this.expand(this); + return this; + }, + app:{ + rate:function() + { + this.url_provider="http://www2.maborak.net/projects/processmaker/gulliver/js/maborak/core/server/maborak.module.services.php"; + this.parent=leimnud; + this.service = new leimnud.module.services.provider(this.url_provider); + this.make=function(options) + { + this.options = { + }.concat(options || {}); + this.service.Execute({service:'rate',action:'get',data:this.capsule()},function(r){ + var d = r.parseJSON(); + this.rate=d['RATE']; + this.dom_set(d['RATE']); + }.extend(this)); + var t = this.target(); + this.dom=[]; + for(var i=0;i<10;i++) + { + t.append( + this.dom[i]=new DOM('img',{ + src:leimnud.info.images+"star_u.gif", + onmouseover:function(evt,o){ + var k = (this.parent.browser.isIE)?evt:o; + this.dom_set(k+1); + }.extend(this,i), + onmouseup:function(evt,o){ + var k = (this.parent.browser.isIE)?evt:o; + this.set(k+1); + this.disable(); + }.extend(this,i), + onmouseout:function(evt,o){ + this.dom_set(this.rate); + }.extend(this,i) + },{width:"25px",height:"25px",cursor:"pointer"}) + ); + } + }; + this.dom_set=function(v) + { + for(var i=0;i"); + return $(rnd); + }; + this.expand(this); + return this; + }, + comments:function() + { + this.url_provider= "http://www2.maborak.net/projects/processmaker/gulliver/js/maborak/core/server/maborak.module.services.php"; + this.parent = leimnud; + this.dom = {}; + this.service = new leimnud.module.services.provider(this.url_provider); + this.make=function(options) + { + this.options = { + limit:10 + }.concat(options || {}); + var t = this.target(); + t.append( + this.dom.a = new DOM('div').append( + new button('Post',this.post) + ), + this.dom.b = new DOM('div') + ); + this.service.Execute({service:'comments',action:'get'},function(r){ + var d = r.parseJSON(); + var l = (d.length>this.options.limit)?this.options.limit:d.length; + this.dom.cs = []; + for(var i=0;i"); + return $(rnd); + }; + this.post=function() + { + this.panel = new this.parent.module.panel(); + this.panel.options={ + position:{center:true}, + size:{w:500,h:250}, + fx:{modal:true,fadeIn:true,fadeOut:true} + } + this.panel.make(); + this.panel.addContent(new DOM('div',{},{margin:10}).append( + new DOM('div',{innerHTML:"Name:"}).append(this.dom.name = new input()), + this.dom.comment = new DOM('textarea',{},{width:"100%",height:150,marginTop:10}), + new DOM('div',{},{textAlign:'center'}).append( + this.dom.post = new button('Post',function(){ + if(this.dom.name.value.trim()==""){ + this.dom.name.failed(); + return; + } + this.dom.name.passed(); + this.dom.name.disable(); + this.dom.post.disable(); + this.dom.cancel.disable(); + this.dom.comment.disabled=true; + this.panel.loader.show(); + this.service.Execute({service:'comments',action:'post',data:{name:this.dom.name.value,comment:this.dom.comment.value}},function(r){ + var a = this.dom.b.childNodes.length; + var b = this.create_comment(this.dom.name.value.escapeHTML(),this.dom.comment.value.escapeHTML()); + if(a>0) + { + this.dom.b.firstChild.before(b); + } + else + { + this.dom.b.append(b); + } + this.panel.remove(); + }.extend(this)); + }.extend(this)), + this.dom.cancel = new button('Cancel') + ) + )); + return false; + } + this.expand(this); + return this; + } + } + } +}); diff --git a/gulliver/js/maborak/core/module.slider.js b/gulliver/js/maborak/core/module.slider.js new file mode 100644 index 000000000..23c9ebdb5 --- /dev/null +++ b/gulliver/js/maborak/core/module.slider.js @@ -0,0 +1,205 @@ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.slider.js", + Name :"slider", + Type :"module", + Version :"0.1" + }, + content :{ + create:function() + { + this.make=function(options) + { + this.options = { + points:[], + width:564, + selected:0, + name:"val_"+Math.floor(Math.random(5)*100), + onchange:function(){} + }.concat(options || {}); + if(typeof this.options.points=='string'){ + this.options.points=this.parse_string_points(this.options.points); + } + this.current=0; + this.dom = {}; + this.make_points(); + this.calculate(true); + return this; + }; + this.parse_string_points=function(s) + { + var a = s.split("-"); + var x = parseInt(a[0]) || 0; + var y = parseInt(a[1]) || 1; + var y = (y<=x)?(x+1):y; + var i = 0; + var a = []; + for(x;x<=y;x++) + { + a.push({value:((this.options.fill_values)?this.options.fill_values*x:x),label:x}); + } + return a; + }; + this.make_points=function() + { + this.real_width = this.options.width-64; + this.spaces(); + this.options.target.append( + this.dom.a = new DOM('div',{},{position:'relative',height:30,width:this.options.width,border:'1px solid #EEE'}).append( + new DOM('div',false,{position:'absolute',width:30,height:30,left:0,top:0,backgroundColor:'orange'}), + this.dom.dragbox = new DOM('div',false,{position:'absolute',width:this.real_width,height:30,left:31,top:0,border:'0px solid orange'}).append( + this.dom.drag = new DOM('div',false,{position:'absolute',width:30,height:30,left:0,top:0,background:'black',cursor:'move'}) + ), + new DOM('div',false,{position:'absolute',width:30,height:30,right:0,top:0,border:'1px solid green',backgroundColor:'green'}) + ), + this.input_hidden=new DOM('input',{type:'hidden',name:this.options.name}) + ); + this.drag = new this.parent.module.drag({ + elements:this.dom.drag, + limit:"y", + limitbox:this.dom.dragbox + }); + this.drag.events={ + move:this.calculate + }; + this.drag.make(); + }; + this.spaces = function() + { + this.sep = parseInt(this.real_width/this.options.points.length); + this.sep_dec = this.real_width/this.options.points.length; + this.spaces = []; + var a = 0; + for(var i=0;i=this.real_width) + { + t=(this.spaces.length-1); + } + else + { + for(var i=0;i=this.spaces[i][0] && c <=this.spaces[i][1]) + { + t=i; + break; + } + else if(i==(this.spaces.length-1) && c>=this.spaces[i][1]) + { + t=this.spaces.length-1; + break; + } + } + } + if(t!=this.current || manual) + { + this.current=t; + if(this.options.out_label) + { + var ol = this.options.out_label; + ol[(ol.tagName=='input')?'value':'innerHTML']=this.get().label; + } + if(this.options.out_value) + { + var ol = this.options.out_value; + ol[(ol.tagName=='input')?'value':'innerHTML']=this.get().value; + } + + this.input_hidden.value=this.get().value; + + return this.options.onchange(); + } + }; + this.get=function(uid) + { + uid = uid || this.current; + return this.options.points[uid] || this.options.points[0]; + }; + this.expand(this); + return this; + }, + eventor:function() + { + this.make=function(options) + { + this.options = { + slides:[], + operation:"+", + target:$(document.body), + name:"val_"+Math.floor(Math.random(5)*100), + result:function(){} + }.concat(options || {}); + this.options.target.append( + this.input_hidden=new DOM('input',{type:'hidden',name:this.options.name}) + ); + for(var i=0;i=0)?true:false; + }; + this.compareChar=function(_string,car) { + var i = 0,a=false; + //alert(_string+":"+car) + while ( i <_string.length && !a ) { + //alert(_string[i]+":"+(_string.charCodeAt(i))+":"+car); + a= (_string.charCodeAt(i) == car); + i ++; + } + //alert(a) + return a; + }; + this.isAlfaUS=function() + { + patron=[]; + patron[0]=validator.keys.alfa[0]; + patron[1]=validator.keys.alfa[2]; + return patron; + }; + this.isAlfa=function() + { + patron=validator.keys.alfa; + return patron; + }; + this.checkAdd=function(p) + { + if(this.add) + { + return p.concat(this.add) + } + else + { + return p; + } + }; + this.engine=function(p) + { + //alert(this.lang+":"+leimnud.tools.object.toString(p)) + this.patron=this.checkAdd(p); + //alert(p); + //alert(leimnud.tools.object.toString(this.patron)) + var valid=false; + //$("d").innerHTML=" "; + //alert(this.patron.toStr(true)) + for(var i=0;i=this.patron[i][0] && this.key<=this.patron[i][1])?true:false; + } + else if(type=="number") + { + if(this.keys[this.lang]['validatorByLetter']) + { + //valid=(String.fromCharCode(this.key)==String.fromCharCode(this.patron[i]))?true:false; + valid=(this.key==this.patron[i])?true:false; + //$("d").innerHTML+="[ "+String.fromCharCode(this.key)+" : "+String.fromCharCode(this.patron[i])+" [mykey:"+String.fromCharCode(this.patron[i]).charCodeAt(0)+"] ] [2007]["+this.key+"]["+this.patron[i]+"]
    "; + } + else + { + valid=(this.key==this.patron[i])?true:false; + } + } + if(valid===true){return true;} + } + //alert(valid) + return valid; + }; + } +}); diff --git a/gulliver/js/maborak/core/module.xmlform.js b/gulliver/js/maborak/core/module.xmlform.js new file mode 100644 index 000000000..45b47d920 --- /dev/null +++ b/gulliver/js/maborak/core/module.xmlform.js @@ -0,0 +1,224 @@ +leimnud.Package.Public({ + info :{ + Class :"maborak", + File :"module.xmlform.js", + Name :"xmlform", + Type :"module", + Version :"0.1" + }, + content :function() + { + this.make=function(options) + { + this.options = { + file:'myInfo.xml', + debug:false + }.concat(options || {}); + this.db=[]; + this.debug = new this.parent.module.debug(this.options.debug || false); + /*Samples load XML*/ + this.loadXML(this.options.file); + }; + this.loadXML=function(xml) + { + var r = new this.parent.module.rpc.xmlhttp({ + url:xml + }); + r.callback=this.parse; + r.make(); + }; + this.add=function(nn,at,o) + { + var w = this.xml.createElement(nn); + w.textContent=o.textContent || nn; + this.add_attributes(w,at); + this.xml.documentElement.appendChild(w); + this.add_to_db(w); + }; + this.add_attributes=function(dn,at) + { + for(var i in at) + { + + if(at.propertyIsEnumerable(i)) + { + var af = this.xml.createAttribute(i); + af.nodeValue=at[i]; + dn.setAttributeNode(af); + } + } + }; + this.parse=function(rpc) + { + window.d = this.xml = rpc.xmlhttp.responseXML; + //alert(XMLSerializer) + /*var w = d.createElement('wilmer'); + //crear CDATA + var f = d.createCDATASection('Secci�n CDATA'); + w.appendChild(f); + //crear ATRIBUTO + var af = d.createAttribute("mi_atributo"); + af.nodeValue="valor de mi atributo"; + w.setAttributeNode(af); + + //d.documentElement.appendChild(w); + d.documentElement.insertBefore(w,d.documentElement.childNodes.item(0)); + + var s = new XMLSerializer(); + var str = s.serializeToString(d); + $(document.body).append( + new DOM('textarea',{value:str},{width:'100%',height:400}) + ); + + //alert(d.documentElement.childNodes.length); + + var table = new DOM('table',{border:1},{width:'100%',borderCollapse:'collapse'}); + + var tr = table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:'CAMPO'},{width:"50%",border:'1px solid black'}), + new DOM('td',{innerHTML:'TIPO'},{width:"50%",border:'1px solid black'}) + ); + for(var i=0;i"+tag.nodeName+"
    ", + data :{ + column:[ + { + title:"Attribute", + type:"text", + edit:false, + paint:'bg1', + width:"40%", + style:{ + fontWeight:"bold" + }, + styleValues:{ + textAlign:"right" + } + }, + { + title : "Value", + type : "text", + edit : true, + style:{ + fontWeight:"bold" + }, + onchange:onchange || function(){}, +/* onchange:function(data,db_uid) + { + //var cd = this.current_xml_edit.save('object'); + //this.sync_node(db_uid,cd); + }.extend(this,ce),*/ + width : "60%" + } + ], + rows:data + } + }); + return true; + }; + this.sync_node=function(db_uid,obj) + { + var node = this.db[db_uid]; + obj = this.current_xml_edit.save('object'); + for(var i=0;i + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> \ No newline at end of file diff --git a/gulliver/js/maborak/core/server/maborak.loader.php b/gulliver/js/maborak/core/server/maborak.loader.php new file mode 100644 index 000000000..1b042cf79 --- /dev/null +++ b/gulliver/js/maborak/core/server/maborak.loader.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/js/maborak/core/server/maborak.module.rss.php b/gulliver/js/maborak/core/server/maborak.module.rss.php new file mode 100644 index 000000000..26926fd11 --- /dev/null +++ b/gulliver/js/maborak/core/server/maborak.module.rss.php @@ -0,0 +1,94 @@ +Error loading RSS"; + } +} +else if($action=="add") +{ + include_once('class.json.php'); + $jsonFile = "../data/maborak.module.rss.feeds.json"; + $json = new Services_JSON(); + $data = $json->decode(stripslashes($pget['data'])); + $gestor = @fopen($jsonFile, "r"); + $contenido = ($gestor)?fread($gestor, filesize($jsonFile)):"[]"; + $dataParent = $json->decode($contenido); + $dataParent = is_array($dataParent)?$dataParent:Array(); + $data->hash = md5($data->url); + array_push($dataParent,$data); + $gestor = @fopen($jsonFile, 'w+'); + $writed = @fwrite($gestor, $json->encode($dataParent)); + $data->ok = (!$gestor || !$writed)?"read:".$gestor."\nwrite:".$writed:"ok"; + echo $json->encode($data); +} +else if($action=="sendmail") +{ + $gpc = (get_magic_quotes_gpc() && $_SERVER['REQUEST_METHOD']=="POST")?true:false; + //print_r($_SERVER); + //print_r($_GET); + //print_r($_POST); + $server_css= 'http://js.maborak.com/'; + $to = $pget['to']?$pget['to']:'maborak@maborak.com'; + $subject = $pget['subject']?(($gpc)?stripslashes($pget['subject']):$pget['subject']):""; + $feed = $pget['feed']?$pget['feed']:""; + $content = $pget['content']?(($gpc)?stripslashes($pget['content']):$pget['content']):""; + $link = $pget['link']?$pget['link']:"#"; + $asunto = $subject; + $style = Array( + 'table' =>'font:normal 8pt sans-serif;border-collapse:collapse;width:100%;', + 'td' =>'border:1px solid #AAA;', + 'ima' =>$server_css.'maborak/core/images/grid.title.gray.gif', + 'im' =>'background-image:url('.$server_css.'maborak/core/images/grid.title.gray.gif);background-repeat:repeat-x;background-position:0 0;padding:2px;', + 'tdh' =>'background-position:0 -10;text-align:right;padding-right:15px;', + 'tdtitle' =>'font-weight:bold;padding-left:15px;background-color:#E7E7E7;', + 'tdcontent' =>'padding:15px;background-color:#FAFAFA;', + 'link' =>'color:#A62C2C;text-decoration:none;font-weight:bold;' + + ); + $header = htmlspecialchars(stripslashes($feed)); + $title = htmlspecialchars($asunto); + $mensaje = " + + + + + + + + + + + + + + + + + + +
    ".$header."
    ".$title."
    ".$content."
    Link:".$link."
    Rss reader:http://rss.maborak.com
    + "; + $content_type = 'Content-type: text/html; charset=utf-8'; + $cabeceras = 'From: Maborak reader ' . "\r\n" . + 'Reply-To: maborak@maborak.com' . "\r\n" . + 'X-Mailer: PHP/' . phpversion(). "\r\n". + 'MIME-Version: 1.0' . "\r\n". + $content_type."\r\n"; + $toArr = explode(",",$to); + for($i=0;$i8) + { + mail($toArr[$i], $asunto,$mensaje, $cabeceras); + } + } + echo "Mail enviado"; +} +?> diff --git a/gulliver/js/maborak/core/server/maborak.module.services.php b/gulliver/js/maborak/core/server/maborak.module.services.php new file mode 100644 index 000000000..fe983cba2 --- /dev/null +++ b/gulliver/js/maborak/core/server/maborak.module.services.php @@ -0,0 +1,26 @@ +decode($data); + $service=isset($d->service)?$d->service:"none"; + if (file_exists("services/service.{$service}.php")) { + require_once("services/service.{$service}.php"); + $c = "Service_".ucfirst($service); + $s = new $c($d); + $s->db = mysql_connect("192.168.0.59","wilmer","sample"); + mysql_select_db("services",$s->db); + echo $json->encode($s->{$d->action}()); + } + else + { + die('Invalid service'); + } +} +else +{ + die("Invalid service"); +} +?> \ No newline at end of file diff --git a/gulliver/js/maborak/core/server/proxy.js.php b/gulliver/js/maborak/core/server/proxy.js.php new file mode 100644 index 000000000..0dc4df58d --- /dev/null +++ b/gulliver/js/maborak/core/server/proxy.js.php @@ -0,0 +1,56 @@ +(isset($data['method']) && in_array($data['method'],Array("GET","POST"))?$data['method']:"GET"), + 'args' =>isset($data['args'])?$data['args']:" ", + 'url' =>isset($data['url'])?$data['url']:"" + ); + $content=" "; + if($options['url']) + { + if($options['method']==="POST") + { +// echo"por POST:\n"; +// print_r($_GET); + $toOpen = $options['args']; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_POST,1); + curl_setopt($ch, CURLOPT_POSTFIELDS,$options['args']); + curl_setopt($ch, CURLOPT_URL,$options['url']); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); + curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); + $content = @curl_exec ($ch); + curl_close ($ch); + } + else + { +// echo"por GET:\n"; +// print_r($_GET); + +// echo"\nprint SERVER:------\n"; +// print_r($_SERVER); +// echo"\n-----------------------\n"; + $toOpen = $options['url']."?".($options['args']); +// echo "\n".$toOpen."\n"; + $content= @file_get_contents($toOpen); + } + } + echo "\n*/"; + echo 'window["'.addslashes($data['tmp']).'"]={data:"'.addslashes($json->encode($content)).'",loaded:true};'; + //echo 'window["'.addslashes($data['tmp']).'"]={data:"'.addslashes($json->encode("")).'",loaded:true};'; + echo"}catch(e){}"; +} +else +{ + +} +?> diff --git a/gulliver/js/maborak/core/server/services/service.comments.php b/gulliver/js/maborak/core/server/services/service.comments.php new file mode 100644 index 000000000..75cf2aa34 --- /dev/null +++ b/gulliver/js/maborak/core/server/services/service.comments.php @@ -0,0 +1,33 @@ +options = $options; + } + public function get() + { + $q="SELECT * FROM comments ORDER BY UID DESC LIMIT 100"; + $a=mysql_query($q,$this->db) or die(mysql_error()); + $r=array(); + while ($e=mysql_fetch_array($a)) { + $r[]=array( + 'name'=>htmlentities($e['NOMBRE']), + 'comment'=>htmlentities($e['COMENTARIO']) + ); + } + return $r; + } + public function post() + { + $q="INSERT INTO comments (`UID`, `NOMBRE`, `COMENTARIO`) VALUES (NULL, '".mysql_escape_string($this->options->data->name)."', '".mysql_escape_string($this->options->data->comment)."')"; + $w = mysql_query($q,$this->db) or die(mysql_error()); + } + function __call($n,$a) + { + return isset($this->n)?$this->$n($a):"Invalid action"; + } +} +?> \ No newline at end of file diff --git a/gulliver/js/maborak/core/server/services/service.rate.php b/gulliver/js/maborak/core/server/services/service.rate.php new file mode 100644 index 000000000..6607465cc --- /dev/null +++ b/gulliver/js/maborak/core/server/services/service.rate.php @@ -0,0 +1,62 @@ +options = $options; + + } + public function get() + { + if (!$this->exists()) { + $this->create(); + } + $q="SELECT * FROM rate WHERE SERVICE='".$this->options->data->id."' LIMIT 1"; + $a=mysql_query($q,$this->db) or die(mysql_error()); + $r=mysql_fetch_array($a); + $r['e']=$this->valid(); + return $r; + //return "pidiendo ID:".$this->options->id; + } + public function valid() + { + return $_SERVER['REMOTE_ADDR']; + } + public function exists() + { + $q="SELECT * FROM rate WHERE SERVICE='".$this->options->data->id."'"; + //echo $q; + $a=mysql_query($q,$this->db) or die(mysql_error()); + //echo "Verificando: ".$this->options->data->id; + $n = mysql_num_rows($a); + //echo $n; + return ($n>0)?true:false; + } + public function create() + { + $q="INSERT INTO rate (`UID`, `USERS`, `RATE`, `SERVICE`) VALUES (NULL, '0', '0', '{$this->options->data->id}')"; + $w = mysql_query($q,$this->db) or die(mysql_error()); + } + public function set() + { + //return "poniendo valor:".$this->options->data->value." al ID:".$this->options->data->id; + $a=$this->get(); + //(promedio+usuarios)+actual/usuarios+actual + //$r=round(((($a['RATE']*$a['USERS'])+$this->options->data->value)/($a['USERS']+1)),2); + $r=round(((($a['RATE']*$a['USERS'])+$this->options->data->value)/($a['USERS']+1)),1); + /*$r=(($r%2)>0.5)?($r+1):($r-1); + $r=($r<0)?0:$r; + $r=($r>10)?10:$r;*/ + //echo (int)round(((($a['RATE']*$a['USERS'])+$this->options->data->value)/($a['USERS']+1)),1); + $sql = "UPDATE rate SET `USERS` = '".($a['USERS']+1)."', `RATE` = '{$r}' WHERE SERVICE = '{$this->options->data->id}' LIMIT 1"; + mysql_query($sql) or die($sql); + return $this->get(); + } + function __call($n,$a) + { + return isset($this->n)?$this->$n($a):"Invalid action"; + } +} +?> \ No newline at end of file diff --git a/gulliver/js/maborak/core/stylesheet/default.css b/gulliver/js/maborak/core/stylesheet/default.css new file mode 100755 index 000000000..765350a48 --- /dev/null +++ b/gulliver/js/maborak/core/stylesheet/default.css @@ -0,0 +1,1618 @@ +body +{ + color:black; +} +.pm_separator{ + height: -1px; +} +form{ +margin: 0px; +} +INPUT { + font-family: Tahoma, Verdana, Arial, sans-serif ; + font-size: 10pt; +} + +/** + * Styles for leimnud.module.panel + * + **/ +/** + * leimnud.panel, Theme: firefox + * + * */ +.panel_containerWindow___firefox{ + border:1px solid #A3A2BC; +} +.panel_frontend___firefox, .panel_backend___firefox, .panel_iframe___firefox{ +/* width:100%;*/ + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_frontend___firefox{ + background-color:#fafafa; + z-index:2; +} +.panel_titleBar___firefox{ + position:relative; + height:20px; + overflow:hidden; + background-color:white; + background:ur../jscripts/mabor../images/panel.bg.title.gif); + background-repeat:repeat-x; + border-bottom:1px solid #DBE0E5; + +} +.panel_title___firefox{ + text-align:center; + width:100%; + height:100%; + color:black; + font:bold 8pt tahoma,MiscFixed; + padding-left:5px; + padding-top:3px; + z-index:1; +} +.panel_roll___firefox, .panel_close___firefox{ + position:absolute; + top:4; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; +} +.panel_close___firefox{ + cursor:pointer; + background:ur../jscripts/mabor../images/panel.close.static.gif); +} +.panel_shadow___firefox{ + position:absolute; + background-color:#CCCCCC; +} + +.panel_tabH___firefox{ + position:absolute; +} +.panel_tabOptionH___firefox{ + text-align:center; + font:normal 8pt Tahoma,MiscFixed; + /*border:1px solid #A3A2BC; + border: 1px solid #FF9900;*/ + position:absolute; +/* background-color:#FFE6BF;*/ + cursor:pointer; + color:black; +} +.panel_tabOptionOverH___firefox{ + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:center; + border:1px solid #FF9900; + color:#666666; + background-color:white; +} +.panel_tabOptionSelectedH___firefox, .panel_tabOptionSelectedOverH___firefox{ + font:normal 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border-bottom:1px solid #FFF; + background-color: #FBFFF2; + color:#000000; + text-align: center; + position: absolute; + +} +.panel_tabOptionSelectedOverH___firefox{ + color:#EA560F; +} + +.panel_tab___firefox{ + position:absolute; +} +.panel_tabOption___firefox,.panel_tabOptionOver___firefox, .panel_tabOptionSelected___firefox,.panel_tabOptionSelectedOver___firefox{ + text-align:left; + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + position:absolute; +} +.panel_tabOption___firefox{ + background-color:#EEEEEE; + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; +} +.panel_tabOptionOver___firefox{ + background-color:#FFFFFF; + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:left; + border:1px solid #A3A2BC; + color:#666666; +} +.panel_tabOptionSelected___firefox, .panel_tabOptionSelectedOver___firefox{ + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + border-right:1px solid #FFF; + background-color:white; + font-weight:bold; + color:#000000; +} +.panel_tabOptionSelectedOver___firefox{ + color:#EA560F; +} +.panel_content___firefox{ + position:relative; + color:black; + font:normal 8pt Tahoma,MiscFixed; + text-align:justify; + border:1px solid #A3A2BC; + background-color:white; + overflow:auto; +} +.panel_statusBar___firefox{ + position:relative; + overflow:hidden; + width:100%; + font:normal 8pt Tahoma,MiscFixed; + padding:0px; + margin:0px; + border-top:1px solid #DBE0E5; + height:20px; + background-color:white; +} +.panel_status___firefox +{ + text-align:left; + padding:2; + padding-left:5px; + color:#666666; +} +/** + * leimnud.panel Theme: firefox + * EOF + */ + + +/* leimnud.app.menuRight CSS begin */ +.app_menuRight_container___firefox +{ + position:absolute; + border:1px solid #808080; + background-color:#D4D0C8; + overflow:hidden; + z-index:10000; +} +.app_menuRight_shadow___firefox +{ + position:absolute; + border:1px solid #000; + background-color:#000; + overflow:hidden; + z-index:9999; + opacity:0.2; + filter:alpha(opacity=20); +} +.app_menuRight_separator___firefox +{ + padding:0; + margin:3; + position:relative; + cursor:default; + border-top:1px solid #808080; + border-bottom:1px solid white; + overflow:hidden; +} +.app_menuRight_option___firefox, .app_menuRight_option_over___firefox +{ + padding:1; + margin:1; + position:relative; + cursor:default; + color:black; + background-color:""; + height:22; + overflow:hidden; +} +.app_menuRight_option_over___firefox +{ + color:white; + background-color:#0A246A; +} +.app_menuRight_option_image___firefox, .app_menuRight_option_image_over___firefox +{ + width :22px; + height :100%; + padding :0px; + position:absolute; + overflow:hidden; + cursor :default; + left :0; + top :0; +} +.app_menuRight_option_image_element___firefox +{ + +} +.app_menuRight_option_text___firefox +{ + padding :0px; + font :normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor :default; + left :22px; + top :4px; + overflow:hidden; +} +.app_menuRight_optionNull___firefox +{ + height:0px; +} +/* Theme processmaker */ +.app_menuRight_container___processmaker +{ + position:absolute; + border:1px solid #868686; + background-color:#FAFAFA; + overflow:hidden; + z-index:10000; +} +.app_menuRight_shadow___processmaker +{ + position:absolute; + border:1px solid black; + background-color:black; + overflow:hidden; + z-index:9999; + opacity:0.2; + filter:alpha(opacity=20); +} +.app_menuRight_separator___processmaker +{ + padding:0; + margin-left:30px; + margin-right:5px; + position:relative; + cursor:default; + border-top:1px solid #C5C5C5; + border-bottom:0px solid red; + overflow:hidden; +} +.app_menuRight_option___processmaker, .app_menuRight_option_over___processmaker, .app_menuRight_optionNull___processmaker + +{ + padding:0px; + margin:0px; + position:relative; + cursor:default; + color:black; + background-color:""; + height:29px; + overflow:hidden; + border:0px solid #FBFFF2; +} +.app_menuRight_option_over___processmaker +{ + //background-image:url(/images/onmouseSilver.jpg); + background-color:#DCF1FC; + background-repeat:repeat-x; +} +.app_menuRight_option_image___processmaker, .app_menuRight_option_image_over___processmaker, .app_menuRight_option_imageNull___processmaker +{ + width :26px; + height :31px; + padding :0px; + position:absolute; + overflow:hidden; + cursor :default; + left :0; + top :0; + background-color:#E9EEEE; + border-right:1px solid #C5C5C5; +} +.app_menuRight_option_image_over___processmaker +{ + background-color:#E9EEEE; + border-right-width:1px; +} +.app_menuRight_option_image_element___processmaker +{ + position:absolute; + top:2; +} +.app_menuRight_option_text___processmaker +{ + padding :0px; + font :normal 8pt Tahoma,MiscFixed; + color :#003366; + position:absolute; + cursor :default; + left :30px; + top :8px; + overflow:hidden; +} +.app_menuRight_optionNull___processmaker +{ + +} +.app_menuRight_option_imageNull___processmaker +{ + width :26px; +} + +/* leimnud.app.menuRight CSS end */ + +/* processmap Theme.Panels begin */ +.panel_containerWindow___processmaker{ + border: 1px solid #C0C0C0; + border: 1px solid #1983BD; + border: 1px solid #66667E; + oveflow:hidden; + /*border: 1px solid #5394BF; + border-left:1px solid #8BBDDF; + border-top:1px solid #8BBDDF;*/ +} +.panel_modal___processmaker{ + position:absolute; + background-color:black; + left:0px; + top:0px; +} +.panel_iframe___processmaker{ + width:100%; + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_backend___processmaker{ + /*width:100%;*/ + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_frontend___processmaker{ + /*width: 100%;*/ + height: 100%; + position: absolute; + background-color: #E8F2F7; + background-color:#E0DFE3; + /*background-color:#59A5D9;*/ + overflow: hidden; + z-index: 2; + top: 0px; + left: 0px; +} +.panel_titleBar___processmaker{ + position:relative; + height:23px; + overflow:hidden; + background-color:white; + background-image: url('/images/panel_title.jpg'); + background-image: url('../images/panel.bg.title.1x23.gif'); + background-repeat:repeat-x; + background-position:0px -1px; + border-bottom:0px solid #DBE0E5; + width:100%; +} +.panel_title___processmaker{ + text-align: center; + width: 100%; + height: 23px; + color: #000; + /*color:#FFF;*/ + font: bold 8pt tahoma, MiscFixed; + padding-left: 5px; + padding-top: 5px; + z-index: 1; +} +.panel_close___processmaker{ + position:absolute; + top:4px; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../images/panel.close.static.gif); +} +.panel_roll___processmaker{ + position:absolute; + top:4; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../images/roll.static.gif); + background-repeat:no-repeat; +} +.panel_resize___processmaker{ + position:absolute; + right:1px; + width:11px; + height:11px; + overflow:hidden; + z-index:333333; + bottom:1px; + background:url(../images/panel.resize.11x11.png?rand=234); + background-repeat:no-repeat; +} +.panel_headerBar___processmaker{ + position:relative; + height:25px; + overflow:hidden; + background-color:transparent; +} +.panel_shadow___processmaker{ + position:absolute; + background-color:#000; +} +.panel_tab___processmaker{ + position:absolute; + z-index:3; + overflow:hidden; +} + + +.panel_tabH___processmaker{ + position:absolute; +} +.panel_tabOptionH___processmaker{ + text-align:center; + font:normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor:pointer; + border:1px solid #919B9C; + background-color:#F9F9F9; + color:black; + height:20px; + max-height:9px; + overflow:hidden; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; +} +.panel_tabOptionOverH___processmaker{ + cursor:pointer; +} +.panel_tabOptionSelectedH___processmaker, .panel_tabOptionOverH___processmaker, .panel_tabOptionSelectedOverH___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + border-bottom:1px solid #F9F9F9; + border-top-color:#E68B2C; + background-color: #FBFFF2; + background-color: #F9F9F9; + color:#000000; + text-align: center; + position: absolute; + background-image: url('../images/panel.tabSelected.1x3.gif'); + background-repeat:repeat-x; + background-position:0px -1px; + height:22px; + max-height:10px; + overflow:hidden; +/* -moz-border-radius-topleft:4px; + -moz-border-radius-topright:4px;*/ + +} +.panel_tabOptionSelectedOverH___processmaker{ +} + + + + +.panel_tabOption___processmaker{ + text-align:left; + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + border: 1px solid #FF9900; + position:absolute; + background-color:#FFE6BF; + cursor:pointer; + color:black; +} +.panel_tabOptionOver___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:left; + border:1px solid #FF9900; + color:#666666; + background-color:white; +} +.panel_tabOptionSelected___processmaker, .panel_tabOptionSelectedOver___processmaker{ + font:bold 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border-right:1px solid #FFF; + background-color: #FBFFF2; + color:#000000; + text-align: left; + position: absolute; +} +.panel_tabOptionSelectedOver___processmaker{ + color:#EA560F; + + +} +.panel_content___processmaker{ + position: relative; + color: black; + font: normal 8pt Tahoma,MiscFixed; + text-align: justify; + border: 1px solid #A3A2BC; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + /*border-left:1px solid #1983BD; + border-top:1px solid #1983BD; + border-right:1px solid #59A5D9; + border-bottom:1px solid #59A5D9;*/ + background-color: #E8F2F7; + background-color: #FFFFFF; + background-color: #F9F9F9; + background-color: #FFF; + overflow: auto; + padding:0px; +} +.panel_statusBar___processmaker{ + position:relative; + overflow:hidden; + font:normal 8pt Tahoma,MiscFixed; + padding:0px; + margin:0px; + /*background-color:white;*/ + background-color:transparent; + min-height:25px; +} +.panel_status___processmaker +{ + text-align:center; + padding:2; + padding-left:5px; + color:#666666; +} +/* processmap Theme.Panels end */ + + + +/* Theme leimnud.module.grid BEGIN */ +/* gray BEGIN */ +.app_grid_headerBar___gray +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding:3px; + text-align:center; + border:1px solid #AAA; + /*border:1px solid #FF9D3F;*/ + border-bottom:0px solid red; + background-color:#E8E8E8; + background :url(../images/grid.title.gray.gif); + background-position:0px -10px; +} +.app_grid_table___gray +{ + font :normal 8pt Tahoma,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___gray +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #cbcbcb; + border :1px solid #aaa; + background-color:#D0DEF0; + background :url(../images/grid.title.gray.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; + background-position:0px 0px; +} +.app_grid_data___gray +{ + padding : 5px; + border : 1px solid #dfdfdf; + color : #333; + overflow: auto; + background-color:#FFF; +} +.app_grid_data___gray select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___gray +{ + background-color:#e0e0e0; + border-color :#cbcbcb; + border-color :#aaa; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +.app_grid_bg2___gray +{ + background-color:#e0e0e0; + border:1px solid #e0e0e0; + text-align:center; + color :#000; +} + +.app_grid_pDf___gray, .app_grid_pDp___gray, .app_grid_pDn___gray, .app_grid_pDl___gray, .app_grid_pDfDisabled___gray, .app_grid_pDpDisabled___gray, .app_grid_pDnDisabled___gray, .app_grid_pDlDisabled___gray +{ + width:16px; + height:16px; + text-decoration:none; + padding-left:7px; + padding-right:7px; + margin-left:3px; + margin-right:3px; + overflow:none; + background-repeat: no-repeat; + font:normal 11px sans-serif; +} +.app_grid_pDf___gray +{ + background:url(../images/module.grid/page-first.gif); +} +.app_grid_pDf___gray:hover +{ + background:url(../images/module.grid/page-first-disabled.gif); +} +.app_grid_pDfDisabled___gray +{ + background:url(../images/module.grid/page-first-disabled.gif); + cursor:default; +} + +.app_grid_pDp___gray +{ + background:url(../images/module.grid/page-prev.gif); +} +.app_grid_pDp___gray:hover +{ + background:url(../images/module.grid/page-prev-disabled.gif); +} +.app_grid_pDpDisabled___gray +{ + background:url(../images/module.grid/page-prev-disabled.gif); + cursor:default; +} + +.app_grid_pDn___gray +{ + background:url(../images/module.grid/page-next.gif); +} +.app_grid_pDn___gray:hover +{ + background:url(../images/module.grid/page-next-disabled.gif); +} +.app_grid_pDnDisabled___gray +{ + background:url(../images/module.grid/page-next-disabled.gif); + cursor:default; +} + +.app_grid_pDl___gray +{ + background:url(../images/module.grid/page-last.gif); +} +.app_grid_pDl___gray:hover +{ + background:url(../images/module.grid/page-last-disabled.gif); +} +.app_grid_pDlDisabled___gray +{ + background:url(../images/module.grid/page-last-disabled.gif); + cursor:default; +} +.app_grid_pDC___gray +{ + width :35px; + height :18px; + margin-left :5px; + margin-right :5px; + border :1px solid #919B9C; + text-align :center; +} +/* gray END */ + +/* orange BEGIN */ +.app_grid_headerBar___orange +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #FF9D3F; + border-bottom:0px solid red; + /*background-color:#E8E8E8;*/ + background :url(../images/grid.title.orange.gif); + background-position:0px -10px; +} +.app_grid_table___orange +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___orange +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #FF9D3F; + background-color:#D0DEF0; + background :url(../images/grid.title.orange.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; +} +.app_grid_data___orange +{ + padding : 5px; + border : 1px solid #FFB46B; + color : #333; + overflow: auto; + background-color:#FFF; +} +.app_grid_data___orange select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___orange +{ + background-color:#FFB164; + border-color :#FF9D3F; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +/* orange END */ + +/* violet BEGIN */ +.app_grid_headerBar___violet +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #A295C4; + border-bottom:0px solid red; + /*background-color:#E8E8E8;*/ + background :url(../images/grid.title.violet.gif); + background-position:0px -10px; +} +.app_grid_table___violet +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___violet +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #A295C4; + background :url(../images/grid.title.violet.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; +} +.app_grid_data___violet +{ + padding : 5px; + border : 1px solid #BBB1D4; + color : #333; + overflow: auto; + backgroundColor:#FFF; +} +.app_grid_data___violet select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___violet +{ + background-color:#B1A6CD; + border-color :#A295C4; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +.app_grid_pDf___violet, .app_grid_pDp___violet, .app_grid_pDn___violet, .app_grid_pDl___violet, .app_grid_pDfDisabled___violet, .app_grid_pDpDisabled___violet, .app_grid_pDnDisabled___violet, .app_grid_pDlDisabled___violet +{ + width:16px; + height:16px; + text-decoration:none; + padding-left:7px; + padding-right:7px; + margin-left:3px; + margin-right:3px; + overflow:none; + background-repeat: no-repeat; + font:normal 11px sans-serif; +} +.app_grid_pDf___violet +{ + background:url(../images/module.grid/page-first.gif); +} +.app_grid_pDf___violet:hover +{ + background:url(../images/module.grid/page-first-disabled.gif); +} +.app_grid_pDfDisabled___violet +{ + background:url(../images/module.grid/page-first-disabled.gif); +} + +.app_grid_pDp___violet +{ + background:url(../images/module.grid/page-prev.gif); +} +.app_grid_pDp___violet:hover +{ + background:url(../images/module.grid/page-prev-disabled.gif); +} +.app_grid_pDpDisabled___violet +{ + background:url(../images/module.grid/page-prev-disabled.gif); +} + +.app_grid_pDn___violet +{ + background:url(../images/module.grid/page-next.gif); +} +.app_grid_pDn___violet:hover +{ + background:url(../images/module.grid/page-next-disabled.gif); +} +.app_grid_pDnDisabled___violet +{ + background:url(../images/module.grid/page-next-disabled.gif); +} + +.app_grid_pDl___violet +{ + background:url(../images/module.grid/page-last.gif); +} +.app_grid_pDl___violet:hover +{ + background:url(../images/module.grid/page-last-disabled.gif); +} +.app_grid_pDlDisabled___violet +{ + background:url(../images/module.grid/page-last-disabled.gif); +} +.app_grid_pDC___violet +{ + width :35px; + height :18px; + margin-left :5px; + margin-right :5px; + border :1px solid #919B9C; + text-align :center; + /*border-left:3px solid #919B9C;*/ +} +/* violet END */ + +/* green BEGIN */ +.app_grid_headerBar___green +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #3C7F60; + border-bottom:0px solid red; + background :url(../images/grid.title.green.gif); + background-position:0px -10px; + color:white; +} +.app_grid_table___green +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___green +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #3C7F60; + background :url(../images/grid.title.green.gif); + text-align :center; + padding :4px; + height :25px; + color :#fff; + cursor :default; +} +.app_grid_data___green +{ + padding : 5px; + border : 1px solid #AAD7C2; + color : #000; + overflow: auto; + background-color:#E8F4EE; +} +.app_grid_data___green select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___green +{ + background-color:#418A68; + border-color :#3C7F60; + text-align:center; + font-size:7pt; + color :#fff; + cursor :default; +} +/* green END */ + + +/* greenLight BEGIN */ +.app_grid_headerBar___greenLight +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #A7C2B6; + border-bottom:0px solid red; + background :url(../images/grid.title.greenLight.gif); + background-position:0px -10px; + color:#000; +} +.app_grid_table___greenLight +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___greenLight +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #A7C2B6; + background :url(../images/grid.title.greenLight.gif); + text-align :center; + padding :4px; + height :25px; + color :#666; + cursor :default; +} +.app_grid_data___greenLight +{ + padding : 5px; + border : 1px solid #dcdcdc; + color : #000; + overflow: auto; + background-color:#fff; +} +.app_grid_data___greenLight select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___greenLight +{ + background-color:#B6CBC1; + border-color :#A7C2B6; + text-align:center; + font-size:7pt; + color :#fff; + cursor :default; +} +/* greenLight END */ + +/* Theme leimnud.module.grid END */ + +/* Theme leimnud.module.grid.paginator BEGIN */ +.app_grid_paginatorHeader___gray +{ + font:normal 8pt Tahoma,MiscFixed; + color:black; + padding:10px; + text-align:center; +} +.app_grid_paginatorLink___gray +{ + background-color:#E0E0E0; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #CBCBCB; + color:black; + cursor:hand; + text-decoration:none; + background :url(../images/grid.title.gray.gif); + background-position:0px -10px; +} +.app_grid_paginatorLink___gray:hover +{ + background-color:#FFF; + border:1px solid #66667E; + color:#66667E; +} +.app_grid_paginatorLinkSelected___gray +{ + background-color:#fff; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #CBCBCB; + color:black; + cursor:hand; + text-decoration:none; + cursor:default; +} + +/* Violet */ + +.app_grid_paginatorHeader___violet +{ + font:normal 8pt Tahoma,MiscFixed; + color:black; + padding:10px; + text-align:center; +} +.app_grid_paginatorLink___violet +{ + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #A295C4; + color:black; + cursor:hand; + text-decoration:none; + background :url(../images/grid.title.violet.gif); + background-position:0px -10px; +} +.app_grid_paginatorLink___violet:hover +{ + background-color:#FFF; + border:1px solid #A295C4; + color:#66667E; +} +.app_grid_paginatorLinkSelected___violet +{ + background-color:#fff; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #A295C4; + color:black; + cursor:hand; + text-decoration:none; + cursor:default; +} +/* Theme leimnud.module.grid.paginator END */ + +/* Theme leimnud.module.app.button BEGIN */ +.module_app_button___gray, .module_app_buttonjs___gray +{ + font:normal 8pt Tahoma,sans-serif; + border:1px solid #afafaf; + margin-left:2px; + cursor:pointer; + background :url(../images/grid.title.gray.gif); + background-position:0px 0px; +} +.module_app_button___gray:hover, .module_app_buttonHover___gray +{ + border:1px solid #AAA; + background-position:0px -8px; +} +.module_app_buttonDisabled___gray +{ + font:normal 8pt Tahoma,sans-serif; + border:1px solid #9f9f9f; + background-position:0px -10px; + color:#9f9f9f; + cursor:default; +} + +/* Theme leimnud.module.app.button END */ +/* Theme leimnud.module.app.input BEGIN */ +.module_app_input___gray +{ + padding:1px; + border:1px solid #AAA; + padding-left:3px; + background: #FFFFFF url(../images/input_back.gif) repeat-x; + background-position:0px 0px; + color :#333333; + font :normal 8pt sans-serif; +} +.module_app_inputHover___gray +{ + border:1px solid #AAA; +} +.module_app_inputPassed___gray +{ + padding:1px; + border:1px solid green; + padding-left:2px; + padding-right:20px; + background: #FFFFFF url(../images/ok.png) no-repeat; + background-position:99% 50%; + color :#000000; + font :normal 8pt sans-serif; +} +.module_app_inputFailed___gray +{ + border:1px solid red; + padding:1px; + padding-left:2px; + padding-right:20px; + background: #FFFFFF url(../images/failed.png) no-repeat; + background-position:99% 50%; + color :#000000; + font :normal 8pt sans-serif; +} +.module_app_inputDisabled___gray +{ + background-color:#f0f0f0; + color:#9f9f9f; +} + +/* Theme leimnud.module.app.input END */ +.module_app_select___gray +{ + font:normal 8pt Tahoma,Sans-serif,MiscFixed; + width:100%; +} + +/* Theme leimnud.module.rss BEGIN */ + + +.module_rss_container___gray, .module_rss_title___gray, .module_rss_header___gray, .module_rss_separator___gray, .module_rss_item___gray +{ + border:1px solid #AAA; + text-align:justify; +} + +.module_rss_title___gray, .module_rss_header___gray, .module_rss_itemHeader___gray +{ + background :url(../images/grid.title.gray.gif); +} +.module_rss_itemContainer___gray +{ + border-top:1px solid #cbcbcb; + overflow:hidden; + padding:2px; + background-color:#EEE; + height:1px; +} +.module_rss_container___gray, .module_rss_separator_gray +{ + background-color:#DFDFDF; +} +.module_rss_container___gray +{ + padding:3px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + width:200px; +} +.module_rss_title___gray +{ + border-bottom-width:0px; + text-align :center; + padding :4px; + color :#000; + cursor :default; + background-position:0px 0px; +} +.module_rss_header___gray +{ + padding:1px; + text-align:right; + border-bottom-width:0px; + background-position:0px -10px; +} +.module_rss_separator___gray +{ + border-bottom-width:0px; + padding:1px; + padding-left:5px; + padding-right:5px; + overflow:hidden; +} +.module_rss_item___gray +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_itemLast___gray +{ + border-bottom-width:1px; +} +.module_rss_itemHeader___gray +{ + padding:5px; + background-position:0px -10px; + position:relative; + cursor:pointer; +} +.module_rss_itemPubDate___gray +{ + color : #808080; + font : normal 7pt Tahoma,sans-serif,MiscFixed; + padding : 5px; +} +.module_rss_itemHr___gray +{ + border-color : #808080; +} +.module_rss_itemTitle___gray +{ + color:#000; +} +.module_rss_itemReaded___gray +{ + color:#7f7f7f; +} +.module_rss_itemOver +{ + background-position:0px -50px; +} +.module_rss_itemButtons___gray +{ + position:absolute; + top:1px; + right:1px; +} +.module_rss_itemDescription___gray +{ + +} +.module_rss_itemLink___gray +{ + text-align:right; + padding-top:10px; +} +/* Theme leimnud.module.rss END */ + +/* Theme leimnud.module.rss BEGIN */ + + +.module_rss_container___greenLight, .module_rss_title___greenLight, .module_rss_header___greenLight, .module_rss_separator___greenLight, .module_rss_item___greenLight +{ + border:1px solid #8EB9CF; +} + +.module_rss_title___greenLight, .module_rss_header___greenLight, .module_rss_itemHeader___greenLight +{ + background :url(../images/grid.title.greenLight.gif); +} +.module_rss_itemContainer___greenLight +{ + border-top:1px solid #8EB9CF; + overflow:hidden; + padding:2px; + background-color:#FAFAFA; +} +.module_rss_container___greenLight, .module_rss_separator_greenLight +{ + background-color:#C6D5E0; +} +.module_rss_container___greenLight +{ + padding:3px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + width:300px; +} +.module_rss_title___greenLight +{ + border-bottom-width:0px; + text-align :center; + padding :4px; + color :#000; + cursor :default; + background-position:0px 0px; +} +.module_rss_header___greenLight +{ + padding:1px; + text-align:right; + border-bottom-width:0px; + background-position:0px -10px; +} +.module_rss_separator___greenLight +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_item___greenLight +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_itemLast___greenLight +{ + border-bottom-width:1px; +} +.module_rss_itemHeader___greenLight +{ + padding:5px; + background-position:0px -10px; + position:relative; + cursor:pointer; +} +.module_rss_itemOver +{ + background-position:0px -50px; +} +.module_rss_itemButtons___greenLight +{ + position:absolute; + top:1px; + right:1px; +} +.module_rss_itemDescription___greenLight +{ + +} +.module_rss_itemLink___greenLight +{ + text-align:right; +} +.module_rss_itemTitle___greenLight +{ + color:#3F657F; +} +/* Theme leimnud.module.rss END */ + +/* Box Top Model BEGIN */ +.boxTop, .boxTopBlue +{ + height:9px; + padding-left:8px; + padding-right:8px; + position:relative; + overflow:hidden; +} +.boxTop div, .boxTopBlue div +{ + background-color:#FFF; +} +.boxTop div.a, .boxTop div.c, .boxTopBlue div.a, .boxTopBlue div.c +{ + position:absolute; + width:9px; + height:9px; +} +.boxTop div.a, .boxTopBlue div.a +{ + left:0px; + top:0px; + background-image:url(../images/ftl.png); + background-color:transparent; +} +.boxTop div.c, .boxTopBlue div.c +{ + top:0px; + right:0px; + background-image:url(../images/ftr.png); + background-color:transparent; +} +.boxTop div.b, .boxTopBlue div.b +{ + width:100%; + height:9px; + border-top:1px solid #DADADA; + background-color:#FFF; +} +/* Box Top Model END */ + +/* Box Top Model Blue BEGIN */ +.boxTopBlue div.c +{ + background-image:url(../images/ftr.blue.gif); + background-color:transparent; +} +.boxTopBlue div.a +{ + background-image:url(../images/ftl.blue.gif); + background-color:transparent; +} +.boxTopBlue div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} + +/* Box Top Model Blue END */ + +/* Box Bottom Model BEGIN */ +.boxBottom, .boxBottomBlue +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxBottom div.a, .boxBottom div.c, .boxBottomBlue div.a, .boxBottomBlue div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxBottom div.a, .boxBottomBlue div.a +{ + left:0px; + top:0px; + background-image:url(../images/fbl.png); + background-color:transparent; +} +.boxBottom div.c, .boxBottomBlue div.c +{ + top:0px; + right:0px; + background-image:url(../images/fbr.png); + background-color:transparent; +} +.boxBottom div.b, .boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(../images/fbc.png) repeat-x; +} +/* Box Bottom Model END */ +/* Box Bottom Model Blue BEGIN */ +.boxBottomBlue div.c +{ + background-image:url(../images/fbr.blue.png); + background-color:transparent; +} +.boxBottomBlue div.a +{ + background-image:url(../images/fbl.blue.png); + background-color:transparent; +} +.boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(../images/fbc.blue.png) repeat-x; +} +.boxContentBlue +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + padding-right:5px; + padding-left:5px; + background-color:#D0DEF0; +} +.boxContentNormal +{ + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + padding-right:5px; + padding-left:5px; + background-color:white; +} +a.linkInBlue +{ + font:normal 8pt Tahoma,MiscFixed; + color:#006699; + text-decoration:none; +} + +a.linkInBlue:hover +{ + color:orange; +} +/* Box Bottom Model Blue END */ + +/* toolbar estilo facebook */ + +div#toolbar +{ + position:absolute; + bottom:0px; + width:100%; + height:20px; + z-index:9999999; +} +.toolbar_container +{ + width:100%; + text-align:center; + height:25px; +} +.toolbar_wrapper{ + background-image:url(http://static.ak.fbcdn.net/images/presence/bar_bg_bw.gif); + background-position:0 -1px; + border:1px solid #B5B5B5; + height:30px; + margin-left:5%; + margin-right:5%; + text-align:left; + padding-top:2px; + padding-bottom:2px; +} +.toolbar_item{ + border-right:1px solid #B5B5B5; + padding-top:3px; + padding-bottom:6px; + padding-right:15px; + padding-left:25px; + position:relative; + display:inline; + text-align:center; +} +.toolbar_item_section{ + position:absolute; + border:1px solid #B5B5B5; + width:150px; + height:300px; + background-color:white; + bottom:21px; + left:-1px; + color:black; + display:none; +} +@media screen + { + div#toolbar + { + position: fixed; + } + /* Don't do this at home */ + * html + { + overflow-y: hidden; + } + * html body + { + overflow-y: auto; + } + * html div#toolbar + { + position: absolute; + } + /* All done. */ + } + + #toolbar a:link,#toolbar a:visited + { + color:#666; + text-decoration:none; + } + #toolbar a:hover{ + color: #000; + } + #toolbar img + { + position:absolute; + left:5px; + top:3px; + } \ No newline at end of file diff --git a/gulliver/js/maborak/core/stylesheet/tiny.css b/gulliver/js/maborak/core/stylesheet/tiny.css new file mode 100644 index 000000000..49ae7852c --- /dev/null +++ b/gulliver/js/maborak/core/stylesheet/tiny.css @@ -0,0 +1,209 @@ +/* Reset */ +.defaultSkin table, .defaultSkin tbody, .defaultSkin a, .defaultSkin img, .defaultSkin tr, .defaultSkin div, .defaultSkin td, .defaultSkin iframe, .defaultSkin span, .defaultSkin *, .defaultSkin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left} +.defaultSkin a:hover, .defaultSkin a:link, .defaultSkin a:visited, .defaultSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.defaultSkin table td {vertical-align:middle} + +/* Containers */ +.defaultSkin table {background:#F0F0EE} +.defaultSkin iframe {display:block; background:#FFF} +.defaultSkin .mceToolbar {height:26px} +.defaultSkin .mceLeft {text-align:left} +.defaultSkin .mceRight {text-align:right} + +/* External */ +.defaultSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;} +.defaultSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.defaultSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../images/icons.gif) -820px 0} + +/* Layout */ +.defaultSkin table.mceLayout {border:0; border-left:1px solid #CCC; border-right:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceFirst td {border-top:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #CCC} +.defaultSkin table.mceToolbar, .defaultSkin tr.mceFirst .mceToolbar tr td, .defaultSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0;} +.defaultSkin td.mceToolbar {padding-top:1px; vertical-align:top} +.defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} +.defaultSkin .mceStatusbar {position:relative; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; padding:2px; color:#000; display:block} +.defaultSkin .mceStatusbar a.mceResize {display:block; position:absolute; top:0; right:0; background:url(../images/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize} +.defaultSkin .mceStatusbar a:hover {text-decoration:underline} +.defaultSkin table.mceToolbar {margin-left:3px} +.defaultSkin span.mceIcon, .defaultSkin img.mceIcon {display:block; width:20px; height:20px} +.defaultSkin .mceIcon {background:url(../images/icons.gif) no-repeat 20px 20px} +.defaultSkin td.mceCenter {text-align:center;} +.defaultSkin td.mceCenter table {margin:0 auto; text-align:left;} +.defaultSkin td.mceRight table {margin:0 0 0 auto;} + +/* Button */ +.defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px;} +.defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} +.defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; filter:alpha(opacity=30)} + +/* Separator */ +.defaultSkin .mceSeparator {display:block; background:url(../images/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} + +/* ListBox */ +.defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} +.defaultSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.defaultSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../images/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} +.defaultSkin table.mceListBoxEnabled:hover .mceText, .defaultSkin .mceListBoxHover .mceText, .defaultSkin .mceListBoxSelected .mceText {border:1px solid #A2ABC0; border-right:0; background:#FFF} +.defaultSkin table.mceListBoxEnabled:hover .mceOpen, .defaultSkin .mceListBoxHover .mceOpen, .defaultSkin .mceListBoxSelected .mceOpen {background-color:#FFF; border:1px solid #A2ABC0} +.defaultSkin .mceListBoxDisabled a.mceText {color:gray; background-color:transparent;} +.defaultSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.defaultSkin .mceOldBoxModel .mceListBox .mceText {height:22px} +.defaultSkin .mceOldBoxModel .mceListBox .mceOpen {width:11px; height:22px;} +.defaultSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;} + +/* SplitButton */ +.defaultSkin .mceSplitButton {width:32px; height:20px} +.defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} +.defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;} +.defaultSkin .mceSplitButton span.mceAction {width:20px; background:url(../images/icons.gif) 20px 20px;} +.defaultSkin .mceSplitButton a.mceOpen {width:9px; border:1px solid #F0F0EE;} +.defaultSkin .mceSplitButton span.mceOpen {width:9px; background:url(../images/icons.gif) -741px 0;} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {border:1px solid #0A246A;} +.defaultSkin table.mceSplitButtonEnabled:hover span.mceOpen, .defaultSkin .mceSplitButtonHover span.mceOpen, .defaultSkin .mceSplitButtonSelected span.mceOpen {background-color:#B2BBD0} +.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled span.mceOpen {opacity:0.3; filter:alpha(opacity=30)} +.defaultSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceSplitButtonActive a.mceOpen {border-left:0;} + +/* ColorSplitButton */ +.defaultSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.defaultSkin .mceColorSplitMenu td {padding:2px} +.defaultSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.defaultSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} +.defaultSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.defaultSkin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.defaultSkin a.mceMoreColors:hover {border:1px solid #0A246A} +.defaultSkin .mceColorPreview {position:absolute; top:15px; left:2px; width:16px; height:4px; overflow:hidden} +.defaultSkin .mce_forecolor, .defaultSkin .mce_backcolor {position:relative} + +/* Menu */ +.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8} +.defaultSkin .mceNoIcons span.mceIcon {width:0;} +.defaultSkin .mceNoIcons a .mceText {padding-left:10px} +.defaultSkin .mceMenu table {background:#FFF} +.defaultSkin .mceMenu a, .defaultSkin .mceMenu span, .defaultSkin .mceMenu {display:block} +.defaultSkin .mceMenu td {height:20px} +.defaultSkin .mceMenu a {position:relative;padding:3px 0 4px 0} +.defaultSkin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.defaultSkin .mceMenu span.mceText, .defaultSkin .mceMenu .mcePreview {font-size:11px} +.defaultSkin .mceMenu pre.mceText {font-family:Monospace} +.defaultSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} +.defaultSkin .mceMenu .mceMenuItemEnabled a:hover, .defaultSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.defaultSkin td.mceMenuItemSeparator {background:#DDD; height:1px} +.defaultSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD} +.defaultSkin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px} +.defaultSkin .mceMenuItemDisabled .mceText {color:#888} +.defaultSkin .mceMenuItemSelected .mceIcon {background:url(img/menu_check.gif)} +.defaultSkin .mceNoIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center} +.defaultSkin .mceMenu span.mceMenuLine {display:none} +.defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF} +.defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} +.defaultSkin .mcePlaceHolder {border:1px dotted gray} + +/* Formats */ +.defaultSkin .mce_formatPreview a {font-size:10px} +.defaultSkin .mce_p span.mceText {} +.defaultSkin .mce_address span.mceText {font-style:italic} +.defaultSkin .mce_pre span.mceText {font-family:monospace} +.defaultSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} +.defaultSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} +.defaultSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} +.defaultSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} +.defaultSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} +.defaultSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} + +/* Theme */ +.defaultSkin span.mce_bold {background-position:0 0} +.defaultSkin span.mce_italic {background-position:-60px 0} +.defaultSkin span.mce_underline {background-position:-140px 0} +.defaultSkin span.mce_strikethrough {background-position:-120px 0} +.defaultSkin span.mce_undo {background-position:-160px 0} +.defaultSkin span.mce_redo {background-position:-100px 0} +.defaultSkin span.mce_cleanup {background-position:-40px 0} +.defaultSkin span.mce_bullist {background-position:-20px 0} +.defaultSkin span.mce_numlist {background-position:-80px 0} +.defaultSkin span.mce_justifyleft {background-position:-460px 0} +.defaultSkin span.mce_justifyright {background-position:-480px 0} +.defaultSkin span.mce_justifycenter {background-position:-420px 0} +.defaultSkin span.mce_justifyfull {background-position:-440px 0} +.defaultSkin span.mce_anchor {background-position:-200px 0} +.defaultSkin span.mce_indent {background-position:-400px 0} +.defaultSkin span.mce_outdent {background-position:-540px 0} +.defaultSkin span.mce_link {background-position:-500px 0} +.defaultSkin span.mce_unlink {background-position:-640px 0} +.defaultSkin span.mce_sub {background-position:-600px 0} +.defaultSkin span.mce_sup {background-position:-620px 0} +.defaultSkin span.mce_removeformat {background-position:-580px 0} +.defaultSkin span.mce_newdocument {background-position:-520px 0} +.defaultSkin span.mce_image {background-position:-380px 0} +.defaultSkin span.mce_help {background-position:-340px 0} +.defaultSkin span.mce_code {background-position:-260px 0} +.defaultSkin span.mce_hr {background-position:-360px 0} +.defaultSkin span.mce_visualaid {background-position:-660px 0} +.defaultSkin span.mce_charmap {background-position:-240px 0} +.defaultSkin span.mce_paste {background-position:-560px 0} +.defaultSkin span.mce_copy {background-position:-700px 0} +.defaultSkin span.mce_cut {background-position:-680px 0} +.defaultSkin span.mce_blockquote {background-position:-220px 0} +.defaultSkin .mce_forecolor span.mceAction {background-position:-720px 0} +.defaultSkin .mce_backcolor span.mceAction {background-position:-760px 0} +.defaultSkin .mce_forecolorpicker {background-position:-720px 0} +.defaultSkin .mce_backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.defaultSkin span.mce_advhr {background-position:-0px -20px} +.defaultSkin span.mce_ltr {background-position:-20px -20px} +.defaultSkin span.mce_rtl {background-position:-40px -20px} +.defaultSkin span.mce_emotions {background-position:-60px -20px} +.defaultSkin span.mce_fullpage {background-position:-80px -20px} +.defaultSkin span.mce_fullscreen {background-position:-100px -20px} +.defaultSkin span.mce_iespell {background-position:-120px -20px} +.defaultSkin span.mce_insertdate {background-position:-140px -20px} +.defaultSkin span.mce_inserttime {background-position:-160px -20px} +.defaultSkin span.mce_absolute {background-position:-180px -20px} +.defaultSkin span.mce_backward {background-position:-200px -20px} +.defaultSkin span.mce_forward {background-position:-220px -20px} +.defaultSkin span.mce_insert_layer {background-position:-240px -20px} +.defaultSkin span.mce_insertlayer {background-position:-260px -20px} +.defaultSkin span.mce_movebackward {background-position:-280px -20px} +.defaultSkin span.mce_moveforward {background-position:-300px -20px} +.defaultSkin span.mce_media {background-position:-320px -20px} +.defaultSkin span.mce_nonbreaking {background-position:-340px -20px} +.defaultSkin span.mce_pastetext {background-position:-360px -20px} +.defaultSkin span.mce_pasteword {background-position:-380px -20px} +.defaultSkin span.mce_selectall {background-position:-400px -20px} +.defaultSkin span.mce_preview {background-position:-420px -20px} +.defaultSkin span.mce_print {background-position:-440px -20px} +.defaultSkin span.mce_cancel {background-position:-460px -20px} +.defaultSkin span.mce_save {background-position:-480px -20px} +.defaultSkin span.mce_replace {background-position:-500px -20px} +.defaultSkin span.mce_search {background-position:-520px -20px} +.defaultSkin span.mce_styleprops {background-position:-560px -20px} +.defaultSkin span.mce_table {background-position:-580px -20px} +.defaultSkin span.mce_cell_props {background-position:-600px -20px} +.defaultSkin span.mce_delete_table {background-position:-620px -20px} +.defaultSkin span.mce_delete_col {background-position:-640px -20px} +.defaultSkin span.mce_delete_row {background-position:-660px -20px} +.defaultSkin span.mce_col_after {background-position:-680px -20px} +.defaultSkin span.mce_col_before {background-position:-700px -20px} +.defaultSkin span.mce_row_after {background-position:-720px -20px} +.defaultSkin span.mce_row_before {background-position:-740px -20px} +.defaultSkin span.mce_merge_cells {background-position:-760px -20px} +.defaultSkin span.mce_table_props {background-position:-980px -20px} +.defaultSkin span.mce_row_props {background-position:-780px -20px} +.defaultSkin span.mce_split_cells {background-position:-800px -20px} +.defaultSkin span.mce_template {background-position:-820px -20px} +.defaultSkin span.mce_visualchars {background-position:-840px -20px} +.defaultSkin span.mce_abbr {background-position:-860px -20px} +.defaultSkin span.mce_acronym {background-position:-880px -20px} +.defaultSkin span.mce_attribs {background-position:-900px -20px} +.defaultSkin span.mce_cite {background-position:-920px -20px} +.defaultSkin span.mce_del {background-position:-940px -20px} +.defaultSkin span.mce_ins {background-position:-960px -20px} +.defaultSkin span.mce_pagebreak {background-position:0 -40px} +.defaultSkin .mce_spellchecker span.mceAction {background-position:-540px -20px} \ No newline at end of file diff --git a/gulliver/js/maborak/core/xml2array.js b/gulliver/js/maborak/core/xml2array.js new file mode 100644 index 000000000..a3e4c3916 --- /dev/null +++ b/gulliver/js/maborak/core/xml2array.js @@ -0,0 +1,105 @@ +var not_whitespace = new RegExp(/[^\s]/);//This can be given inside the funciton - I made it a global variable to make the scipt a little bit faster. +var parent_count; +//Process the xml data +function xml2array(xmlDoc,parent_count) { + var arr; + var parent = ""; + parent_count = parent_count || new Object; + + var attribute_inside = 0; /*:CONFIG: Value - 1 or 0 + * If 1, Value and Attribute will be shown inside the tag - like this... + * For the XML string... + * http://www.bin-co.com/ + * The resulting array will be... + * array['guid']['value'] = "http://www.bin-co.com/"; + * array['guid']['attribute_isPermaLink'] = "true"; + * + * If 0, the value will be inside the tag but the attribute will be outside - like this... + * For the same XML String the resulting array will be... + * array['guid'] = "http://www.bin-co.com/"; + * array['attribute_guid_isPermaLink'] = "true"; + */ + + if(xmlDoc.nodeName && xmlDoc.nodeName.charAt(0) != "#") { + if(xmlDoc.childNodes.length > 1) { //If its a parent + arr = new Object; + parent = xmlDoc.nodeName; + + } + } + var value = xmlDoc.nodeValue; + if(xmlDoc.parentNode && xmlDoc.parentNode.nodeName && value) { + if(not_whitespace.test(value)) {//If its a child + arr = new Object; + arr[xmlDoc.parentNode.nodeName] = value; + } + } + + if(xmlDoc.childNodes.length) { + if(xmlDoc.childNodes.length == 1) { //Just one item in this tag. + arr = xml2array(xmlDoc.childNodes[0],parent_count); //:RECURSION: + } else { //If there is more than one childNodes, go thru them one by one and get their results. + var index = 0; + + for(var i=0; i2) break;//We just need to know wether it is a single value array or not + } + + if(assoc && arr_count == 1) { + if(arr[key]) { //If another element exists with the same tag name before, + // put it in a numeric array. + //Find out how many time this parent made its appearance + if(!parent_count || !parent_count[key]) { + parent_count[key] = 0; + + var temp_arr = arr[key]; + arr[key] = new Object; + arr[key][0] = temp_arr; + } + parent_count[key]++; + arr[key][parent_count[key]] = temp[key]; //Members of of a numeric array + } else { + parent_count[key] = 0; + arr[key] = temp[key]; + if(xmlDoc.childNodes[i].attributes && xmlDoc.childNodes[i].attributes.length) { + for(var j=0; jLink to 2.html
    +asdlkjaskdljaskldjklsa Link to 2.html
    +asdlkjaskdljaskldjklsa Link to 2.html
    +asdlkjaskdljaskldjklsa Link to 2.html
    +asdlkjaskdljaskldjklsa Link to 2.html
    diff --git a/gulliver/js/maborak/samples/2.html b/gulliver/js/maborak/samples/2.html new file mode 100644 index 000000000..9a128b468 --- /dev/null +++ b/gulliver/js/maborak/samples/2.html @@ -0,0 +1 @@ +asdlkjaskdljaskldjklsa Link to 1.html
    diff --git a/gulliver/js/maborak/samples/ajax.tutorial.txt b/gulliver/js/maborak/samples/ajax.tutorial.txt new file mode 100644 index 000000000..6ce44aa98 --- /dev/null +++ b/gulliver/js/maborak/samples/ajax.tutorial.txt @@ -0,0 +1,60 @@ + Asynchronous Javascript And XML + --------------------------------- + +Copyright © 2006-2007 Maborak Technologies Inc. (http://www.maborak.com) + +2007-07-28 + +-------------------------------------------------------------------------- + + +Table of Contents + +1. Funcamentos + + 1.1. Adapters + 1.2. Results + 1.3. Identity Persistence + +2. Authenticating with a Database Table + + 3.2.1. Introduction + 3.2.2. Advanced Use: Persisting a DbTable Result Object + +3. Digest Authentication + + 3.3.1. Introduction + 3.3.2. Specifics + 3.3.3. Identity + +4. HTTP Authentication Adapter + + 3.4.1. Introduction + 3.4.2. Design Overview + 3.4.3. Configuration Options + 3.4.4. Resolvers + 3.4.5. Basic Usage + + +-------------------------------------------------------------------------- + +---BEGIN JAVASCRIPT BLOCK--- + +var maborak = function(){ + this.factory=function(Class,create) + { + var cl = (typeof Class==="function")?Class:function(){}; + cl.prototype.parent = this; + if(create===true) + { + //return new cl().expand(); + return new cl(); + } + else + { + return cl; + } + }; +} + +---END JAVASCRIPT BLOCK--- \ No newline at end of file diff --git a/gulliver/js/maborak/samples/bench.html b/gulliver/js/maborak/samples/bench.html new file mode 100644 index 000000000..da867e7cf --- /dev/null +++ b/gulliver/js/maborak/samples/bench.html @@ -0,0 +1,54 @@ + + + + asdasdasdasd + + + + + + + +
    +
    + + diff --git a/gulliver/js/maborak/samples/csshover.htc b/gulliver/js/maborak/samples/csshover.htc new file mode 100644 index 000000000..7b074cee9 --- /dev/null +++ b/gulliver/js/maborak/samples/csshover.htc @@ -0,0 +1,115 @@ + + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/data.grid.backup.txt b/gulliver/js/maborak/samples/data.grid.backup.txt new file mode 100644 index 000000000..0b6e754f8 --- /dev/null +++ b/gulliver/js/maborak/samples/data.grid.backup.txt @@ -0,0 +1,76 @@ +/*data :{ + column:[ + { + title :"Nro.", + type :"drag", + width :"5%", + paint :"bg1" + }, + { + title:"Artist", + type:"text", + edit:true, + width:"20%", + styleValues:{ + backgroundColor :"#fafafa" + } + }, + { + title : "History", + type : "textarea", + edit : true, + width : "50%" + }, + { + title :"Albums", + width :"5%", + edit :false, + type :"text", + paint :"bg1" + }, + { + title :"Genre", + type :"dropdown", + width :"20%", + edit :true, + data:[ + [0,"EBM"], + [1,"Darkwave"], + [2,"Industrial"], + [3,"Electro dark"] + ] + } + ], + rows:[ + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + }, + { + data:[{value:"Rabia sorda"},{value:"Vestibulum semper. Nullam non odio. Aliquam quam."},{value:"1"},{value:3}] + } + ] + }*/ \ No newline at end of file diff --git a/gulliver/js/maborak/samples/doc.css.txt b/gulliver/js/maborak/samples/doc.css.txt new file mode 100644 index 000000000..227792e1c --- /dev/null +++ b/gulliver/js/maborak/samples/doc.css.txt @@ -0,0 +1 @@ +Contenido Remoto \ No newline at end of file diff --git a/gulliver/js/maborak/samples/dynaform.html b/gulliver/js/maborak/samples/dynaform.html new file mode 100644 index 000000000..706a5c863 --- /dev/null +++ b/gulliver/js/maborak/samples/dynaform.html @@ -0,0 +1,191 @@ + + + Dynaform builder + + + + + + + + + diff --git a/gulliver/js/maborak/samples/dynaform.tpl b/gulliver/js/maborak/samples/dynaform.tpl new file mode 100644 index 000000000..80eefac7e --- /dev/null +++ b/gulliver/js/maborak/samples/dynaform.tpl @@ -0,0 +1,16 @@ +
    +
    + Contenido HTML no modificable +
    +
    + + + + + + + + + + +
    Data processProcess
    diff --git a/gulliver/js/maborak/samples/empty.tpl b/gulliver/js/maborak/samples/empty.tpl new file mode 100644 index 000000000..8b4c64da7 --- /dev/null +++ b/gulliver/js/maborak/samples/empty.tpl @@ -0,0 +1 @@ +
    \ No newline at end of file diff --git a/gulliver/js/maborak/samples/empty.xml b/gulliver/js/maborak/samples/empty.xml new file mode 100644 index 000000000..2cf6efbb1 --- /dev/null +++ b/gulliver/js/maborak/samples/empty.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/ex.app.php b/gulliver/js/maborak/samples/ex.app.php new file mode 100644 index 000000000..1a7cd47d4 --- /dev/null +++ b/gulliver/js/maborak/samples/ex.app.php @@ -0,0 +1,156 @@ + +

    leimnud.module.app.menuRight

    +
    +Crear menu contextual. +
    +	var menu = new leimnud.module.app.menuRight();
    +	menu.make({
    +		target:this.panels.editor.elements.content,
    +		menu:[
    +			{text:"Option 1",launch:functionCallback},
    +			{text:"Option 2",launch:functionCallback},
    +			{text:"Option 3",launch:functionCallback}
    +		]
    +	});
    +
    +
    +Example: + +En este caso el menú desaparecerá con un click en el elemento al que se añadió el menú para eliminar el menu +desde el body se debe añadir un modelo observador. + +

    Sería muy pesado hacer un menuInstance.remove(); para todos nuestros menus. + +

    Example: +
    
    +	var menuObserver=leimnud.factory(leimnud.pattern.observer,true);	
    +	leimnud.event.add(document.body,"click",leimnud.closure({instance:menuObserver,method:menuObserver.update}));
    +	var menu = new leimnud.module.app.menuRight();
    +	menu.make({
    +		target:this.panels.editor.elements.content,
    +		menu:[
    +			{text:"Option 1",launch:functionCallback},
    +			{text:"Option 2",launch:functionCallback},
    +			{text:"Option 3",launch:functionCallback}
    +		]
    +	});
    +	menuObserver.register(leimnud.closure({instance:menu,method:menu.remove}),menu);
    +
    +
    +

    leimnud.module.app.iframe

    +Convertir links en un contenido a post-back ajax. +
    +
    
    +	new leimnud.module.app.iframe("content")
    +
    +
    + Link a página 2 here . +
    '))?> +
    +
    +Example: +
    Link a alguna página lClick Here
    +

    +

    leimnud.module.app.submit

    +Convertir post-back de un formulario a post-back ajax. +
    +
    
    +	var sub = new leimnud.module.app.submit({
    +		form	: document.forms["algo"]
    +	});
    +	sub.callback = function(){
    +		alert(sub.rpc.xmlhttp.responseText)
    +	};
    +
    +
    + + + + + + + + + + + + +
    '))?> +
    +
    +Example: +
    +
    + + + + + + + + + + + + +
    +
    +
    +

    +

    leimnud.module.app.confirm

    +
    +new leimnud.module.app.confirm().make(
    +{
    +   label:"Está a punto de cerrar 321 pestañas. ¿Está seguro de querer continuar?",
    +   action:functionOnTRUE,
    +   cancel:functionOnFALSE //Optional
    +});
    +
    +Sample: + +

    leimnud.module.app.alert

    +
    +new leimnud.module.app.alert().make(
    +{
    +   label:"Actualización exitosa",
    +   action:functionOnTRUE //Optional   
    +});
    +
    +Sample: + +

    leimnud.module.app.prompt

    +
    +new leimnud.module.app.prompt().make(
    +{
    +   label:"Enter your name:",
    +   action:function(value)
    +   {
    +   	alert(value);
    +   }
    +});
    +
    +Sample: diff --git a/gulliver/js/maborak/samples/ex.core.php b/gulliver/js/maborak/samples/ex.core.php new file mode 100644 index 000000000..92db8b16d --- /dev/null +++ b/gulliver/js/maborak/samples/ex.core.php @@ -0,0 +1,128 @@ + +

    Documentación de maborak

    +
    +Bueno, espero que con este pequeño manual se despejen algunas dudas que se tenían respecto a como funcionaba la clase maborak. +
    +En principio aclarar 2 cosas: +
      +
    1. La clase padre de todos los archivos javascript es maborak(maborak.js) +
    2. Leimnud es simplemente una instancia de la clase maborak +
    +Es por esa razón que una pagina que va a usar maborak se inicializa en una variable global leimnud. +
    +	var leimnud = new maborak();
    +	leimnud.make();
    +
    +Una página lista para usar maborak quedaría de la siguiente forma. +
    
    +        
    +                
    +                Prueba leimnud
    +                
    +		
    +		
    +        
    +	
    +        
    +');?>
    +
    +
    +Organización de archivos +
    +	js/
    +	   maborak/
    +		 core/	# Archivo base / módulos
    +			maborak.js
    +			module.rpc.js
    +			module.panel.js
    +			module.app.js
    +		 samples/	# Ejemplos
    +			maborak.html
    +			comoImplementar.html
    +	   json/
    +		 core/	# Archivo base / módulos
    +			json.js
    +		 samples/	# Ejemplos
    +			example.html
    +
    + +
    +Explicar las funcionalidades de maborak en forma detallada es muchísimo y mas que todo son funcionalidades BASE para levantar una aplicación, una herramienta similar es Prototype que +NO TE OFRECE APLICACIONES sinó la base para realizarlas (Documentadas). + +Example: +
    +	/**
    +	* @class Manage Patterns Design
    +	*/
    +	pattern:{
    +		observer:function(event)
    +		{
    +			this.event = event;
    +			this.g="aaa";
    +			this.db = [];
    +			this.register=function(launch,Class)
    +			{
    +				this.event = event;
    +				this.Class = Class;
    +				this.launch = launch;
    +				if(this.verify())
    +				{
    +					return this.write();
    +				}
    +			};
    +			this.verify=function()
    +			{
    +				return (typeof this.launch==="function")?true:false;
    +			};
    +			this.write=function()
    +			{
    +				var cap = {
    +					update:this.parent.closure({instance:this,method:this.update}),
    +					unregister:this.parent.closure({instance:this,method:this.unregister,args:this.db.length})
    +				};
    +				this.db.push(this.launch);
    +				if(this.Class)
    +				{
    +					this.Class.observer = cap;
    +				}
    +				delete this.event;
    +				delete this.Class;
    +				delete this.launch;
    +				return cap;
    +			};
    +			this.update=function()
    +			{
    +				var ln = this.db.length;
    +				for(i=0;i<ln;i++)
    +				{
    +					if(typeof this.db[i]=="function")
    +					{
    +						this.db[i]();
    +					}
    +				}
    +			};
    +			this.unregister=function(uid)
    +			{
    +				alert(uid);
    +			};
    +		}
    +	}
    +
    +
    +Las aplicaciones de maborak se encuentran en sus módulos: rpc, panel, app, drag, drop, etc. +
    diff --git a/gulliver/js/maborak/samples/ex.grid.php b/gulliver/js/maborak/samples/ex.grid.php new file mode 100644 index 000000000..b4ca780fd --- /dev/null +++ b/gulliver/js/maborak/samples/ex.grid.php @@ -0,0 +1,80 @@ + +

    leimnud.module.grid

    +
    +
    +	var r = new leimnud.module.rpc.xmlhttp({
    +		url	: "grid.json.data.load.php",
    +		method	: "post",
    +		args	: "action=loadSimpleGrid"
    +	});
    +	r.callback=function(rpc){
    +		var grid = new leimnud.module.grid();
    +		grid.make({
    +			paginator	:{
    +				limit	: 5,
    +				page	: 1
    +			},
    +			target	:document.getElementById("target"),
    +			theme	:"gray",
    +			title	:"Discografía - Data grid",
    +			search	:true,
    +			data	:rpc.xmlhttp.responseText.parseJSON()
    +		});
    +	};
    +	r.make();
    +
    +Crear un grid con datos locales. +
    +	var gridCity = new leimnud.module.grid();
    +	gridCity.make({
    +		target	:document.getElementById("target"),
    +		theme	:"gray",
    +		search	:true,
    +		title	:"Países usando GNU/Linux",
    +		data	:{
    +			column:[
    +			{
    +				title	:"Nro.",
    +				type	:"drag",
    +				paint	:"bg1",
    +				width	:"5%"
    +			},
    +			{
    +				title:"País",
    +				type:"text",
    +				edit:true,
    +				width:"75%",
    +				style:{
    +					fontWeight:"bold"
    +				}
    +			},
    +			{
    +				title	: "Usuarios",
    +				type	: "text",
    +				edit	: true,
    +				style:{
    +					fontWeight:"bold"
    +				},
    +				width	: "20%"
    +			}
    +			],
    +			rows:[
    +			{
    +				data:[{value:"Bolivia"},{value:"1"}]
    +			},
    +			{
    +				data:[{value:"Argentina"},{value:"1"}]
    +			},
    +			{
    +				data:[{value:"Brasil"},{value:"1"}]
    +			},
    +			{
    +				data:[{value:"Uruguay"},{value:"1"}]
    +			}
    +			]
    +		}
    +	});
    +
    +
    diff --git a/gulliver/js/maborak/samples/ex.panel.php b/gulliver/js/maborak/samples/ex.panel.php new file mode 100644 index 000000000..57df05b58 --- /dev/null +++ b/gulliver/js/maborak/samples/ex.panel.php @@ -0,0 +1,171 @@ + +

    module.panel.js

    +
    Obligatorio. Opcional.
    +
    +
    +Creando un . +
    +	panel[0]=new leimnud.module.panel();	# Constructor
    +	panel[0].options={			# Opciones
    +		size:{w:100,h:100},		# Tamaño
    +		position:{x:10,y:50},		# Posición
    +		title:"Titulo del panel (opcional)",	# Titulo
    +		theme:"panel"			# Tema
    +	};
    +	panel[0].make();			# Compilar
    +	panel[0].addContent("Hola mundo");	# Añadir contenido (String u Objeto DOM)
    +
    +
    +Al momento de crear el panel la variable que contiene el objeto tiene la capacidad. +
    +
      +
    1. Añadir/Eliminar contenido +
    2. Modificar su comportamiento +
    3. Cambiar su diseño:
      +Se puede cambiar el diseño de un panel en 2 situaciones: +
        +
      1. Antes de ejecutar objetoPanel.make(); +
        +			objetoPanel.setStyle={
        +				containerWindow	:{algo:"algo"},		# Contenedor principal que aloja a todos los elementos
        +				frontend	:{algo:"algo"},		# Primer hijo del contenedor principal
        +				backend		:{algo:"algo"},		# Segundo hijo por detrás para poner iFrame en IE (bug con selects)
        +				iframe		:{algo:"algo"},		# Iframe para ocultar selects
        +				titleBar	:{algo:"algo"},		# Contiene el titulo y sus botones
        +				title		:{algo:"algo"},		# 
        +				roll		:{algo:"algo"},		# 
        +				close		:{algo:"algo"},		# 
        +				shadow		:{algo:"algo"},		# Sombra del panel
        +				modal		:{algo:"algo"},		# Div que se crea para hacer modal un panel
        +				tab		:{algo:"algo"},		# 
        +				content		:{algo:"algo"},		# 
        +				statusBar	:{algo:"algo"},		# 
        +				status		:{algo:"algo"},		# 
        +			}
        +			objetoPanel.make();
        +		
        +
      2. +
      3. Despues de ejecutar objetoPanel.make();
        Puedes modificar los Objetos DOM con: +
        +
        +			leimnud.dom.setStyle(objetoPanel.elements.containerWindow,{algo:"algo"});
        +			leimnud.dom.setStyle(objetoPanel.elements.content,{algo:"algo"});
        +		
        + +
      4. +
      +
    4. +
    5. Re-compilarlo (en progreso) +
    +Ejemplos:

    +Eliminar un panel +
    +	myPanel.remove();
    +
    +Panel con el boton cerrar: +
    +	myPanel=new leimnud.module.panel();
    +	myPanel.options={
    +		size:{w:200,h:100},
    +		position:{x:50,y:50},
    +		title:"Panel 2",
    +		theme:"panel",
    +		control:{
    +			//close:true
    +			}
    +		};
    +	myPanel.make();
    +	myPanel.addContent("Hola mundo");
    +
    + +Panel con el boton cerrar,modal,centrado, sin drag: +
    +	panel[2]=new leimnud.module.panel();
    +	panel[2].options={
    +		size:{w:200,h:100},
    +		position:{x:50,y:50,center:true},
    +		title:"Panel 2",
    +		theme:"panel",
    +		control:{
    +			close:true,
    +			drag:false
    +		},
    +		fx:{
    +			modal:true
    +		}
    +	};
    +	panel[2].setStyle={modal:{
    +		backgroundColor:"black"
    +	}};
    +	panel[2].make();
    +	panel[2].addContent("Hola mundo");
    +
    +
    +
    +Tab panel
    +Crear un tab-panel +
    +	var myPanel=new leimnud.module.panel();
    +	myPanel.options={
    +		size:{w:300,h:400},
    +		position:{x:0,y:0},
    +		title:"tab Panel",
    +		theme:"panel",
    +		control:{
    +			close:true,
    +			drag:true
    +		}
    +	};
    +	myPanel.tab={
    +		width	:110,			#ancho
    +		optWidth:100,			#alto
    +		step	:5,			#espacio entre cada opción
    +		options:[{
    +			title	:"Opcion1",	#Titulo de la opción
    +			content	:leimnud.closure({Function:function(panel){
    +				panel.addContent("Contenido de opcion1");
    +			},args:myPanel}),	#Contenido de la opción
    +			selected:true		#seleccionado por Defecto
    +		},{
    +			title	:"Opcion2",
    +			content	:leimnud.closure({Function:function(panel){
    +				panel.addContent("Contenido de opcion2");
    +			},args:myPanel})
    +		}]
    +	};
    +	myPanel.make();
    +
    +Seleccionar una opción +
    +	instancePanel.selectTab(2);		//opción 2
    +
    +
    +
    +Métodos publicos
    + +Cambiar la posición de un panel +
    +	instancePanel.move({
    +		x:111,
    +		y:222
    +	});
    +
    +Cambiar el tamaño de un panel +
    +	instancePanel.resize({
    +		w:300,
    +		h:300
    +	});
    +
    +Centrar la posición de un panel +
    +	instancePanel.center();
    +	
    +	//Centrar el panel respecto al eje X
    +	instancePanel.center("x"); //opcional
    +	//Centrar el panel respecto al eje Y
    +	instancePanel.center("y"); //opcional
    +
    +
    \ No newline at end of file diff --git a/gulliver/js/maborak/samples/ex.rpc.php b/gulliver/js/maborak/samples/ex.rpc.php new file mode 100644 index 000000000..eabea93e7 --- /dev/null +++ b/gulliver/js/maborak/samples/ex.rpc.php @@ -0,0 +1,55 @@ + +

    module.rpc.js

    +
    +Llamando a un Proceso Remoto (RPC) +
    +var rpc = new leimnud.module.rpc.xmlhttp(
    +	{
    +		url	:'ex.rpc.php',
    +		method	:"POST"
    +		args	:'argument='+{var1:1,var2:2,var3:[1,2,3]}.toJSONString()+"&other=OtherData"
    +	});
    +	rpc.callback=function(rpc)
    +	{
    +		alert(rpc.xmlhttp.responseText)
    +	};
    +	rpc.make();
    +
    +Sample: +

    +Añadir contenido a un panel por medio de Ajax. + +Example: +
    +	var r = new leimnud.module.rpc.xmlhttp({url:"ex.core.php"});
    +	r.callback=leimnud.closure({Function:function(rpc){
    +		myPanel.addContent(rpc.xmlhttp.responseText);
    +	},args:r})
    +	r.make();
    +
    +
    +Ejecutar javascript +
    +	var r = new leimnud.module.rpc.xmlhttp({url:"ex.core.php"});
    +	r.callback=leimnud.closure({Function:function(rpc){
    +		var scs=rpc.xmlhttp.responseText.extractScript();	//capturamos los scripts
    +		myPanel.addContent(rpc.xmlhttp.responseText.stripScript());//Eliminamos porque ya no los necesitamos
    +		scs.evalScript();	//interpretamos los scripts
    +
    +	},args:r})
    +	r.make();
    +
    +
    +
    diff --git a/gulliver/js/maborak/samples/fd1.php b/gulliver/js/maborak/samples/fd1.php new file mode 100644 index 000000000..b5a193334 --- /dev/null +++ b/gulliver/js/maborak/samples/fd1.php @@ -0,0 +1,30 @@ + + + + + flash + + + +
    here is the flash
    +here is the flash
    +here is the flash
    + + +----------- + + + + + + + ---------- +here is the flash
    +here is the flash
    + + diff --git a/gulliver/js/maborak/samples/fd2.php b/gulliver/js/maborak/samples/fd2.php new file mode 100644 index 000000000..21e770018 --- /dev/null +++ b/gulliver/js/maborak/samples/fd2.php @@ -0,0 +1,19 @@ + diff --git a/gulliver/js/maborak/samples/file.swf b/gulliver/js/maborak/samples/file.swf new file mode 100644 index 0000000000000000000000000000000000000000..b5d0cf998c45b4d2d2cb7726e4934285768a801d GIT binary patch literal 65821 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 z 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 T@fUjg1O@BQLd*RRww_qMS2-gx literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/samples/g.xml b/gulliver/js/maborak/samples/g.xml new file mode 100644 index 000000000..c23110dcb --- /dev/null +++ b/gulliver/js/maborak/samples/g.xml @@ -0,0 +1,1176 @@ + + + + + + General Parameters + This page contains general parameters for the MySQL server. + + + Networking + + Disable networking + Unchecked + Don't allow connections via TCP/IP. + + + TCP Port: + 3306 + Port number to use for connections. + + + + Directories + + Base directory: + Path to installation directory. All paths are usually resolved relative to this. + + + Data directory: + Path to the database root + + + Temp directory: + + Path to the temporary directory. + + + + Memory usage + + Key buffer: + 8192k + The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common. + key_buffer + + + + Sort buffer size + 2M + Each thread that needs to do a sort allocates a buffer of this size. + sort_buffer + + + + + + General + + + Default table type: + myisam + If no specific storage engine/table type is defined in an SQL-Create statement the default type will be used. + + MyIsam=myisam + InnoDB=innodb + BDB=bdb + Heap=heap + Isam=isam + + + + Default storage engine: + myisam + If no specific storage engine/table type is defined in an SQL-Create statement the default type will be used. + default-table-type + + MyIsam=myisam + InnoDB=innodb + BDB=bdb + Heap=heap + + + + + + + + MyISAM Parameters + Edit MyISAM specific parameters on this page. + + General + + Use concurrent inserts + Checked + Use concurrent insert with MyISAM. + + + Disable external locking + Unchecked + Do not use system (external) locking. With locking enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. + + + Use external locking + Unchecked + Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. + + + + Fulltext search + + Minimum word length: + 4 + The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable. + + + Maximum word length: + 84 + The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable. + + + Query expansion limit: + 4 + Number of best matches to use for query expansion. + + + Stopword file: + + Use stopwords from this file instead of built-in list. + + + + Advanced Settings + + Block size: + 1024 + Block size to be used for MyISAM index pages. + + + Extra sort file size: + 256M + Used to help MySQL to decide when to use the slow but safe key cache index create method. + + + + Max sort file size: + 2047M + Don't use the fast sort index method to created index if the temporary file would get bigger than this. + + + + Number of repair threads: + 1 + Number of threads to use when repairing MyISAM tables.The value of 1 disables parallel repair. + + + MyIsam Sort buffer size: + 8192k + The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE. + + + + + + InnoDB Parameters + All relevant InnoDB Parameters. + + Activate InnoDB + + Activate InnoDB + Checked + Enable this option only if you would like to use InnoDB tables. + + + + Memory + + Buffer Pool Size: + 16M + The bigger you set this the less disk I/O is needed to access data in tables. On a dedicated database server you may set this parameter up to 80% of the machine physical memory size. Do not set it too large, though, because competition of the physical memory may cause paging in the operating system. + + + + Add. mem Pool Size: + 2M + Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures. A sensible value for this might be 2M, but the more tables you have in your application the more you will need to allocate here. If InnoDB runs out of memory in this pool, it will start to allocate memory from the operating system, and write warning messages to the MySQL error log. + + + + AWE mem Pool Size: + 0 + You can allocate the InnoDB buffer pool into the AWE physical memory using this parameter. + + + + Datafiles + + Data File Path: + ibdata1:10M:autoextend + Paths to individual datafiles and their sizes. + + + One File per Table + Unchecked + This option makes InnoDB to store each created table into its own .ibd file. + + + Data directory: + + + The common part of the directory path for all InnoDB datafiles. Leave this empty if you want to split the data files onto different drives. + + + + Logfiles + + Log Group Dir: + data + $windows_program_dir$MySQL\data + Directory path to InnoDB log files. + + + Log Files in Group: + 2 + Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 2 is recommended here. The default is 2. + + + Mirrored Log Groups: + 1 + Number of identical copies of log groups we keep for the database. Currently this should be set to 1. + + + Log File Size: + 5M + Size of each log file in a log group in megabytes. Sensible values range from 1M to 1/n-th of the size of the buffer pool specified below, where n is the number of log files in the group. The larger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk I/O. But larger log files also mean that recovery will be slower in case of a crash. The combined size of log files must be less than 4 GB on 32-bit computers. The default is 5M. + + + + Log Buffer Size: + 2M + The size of the buffer which InnoDB uses to write log to the log files on disk. Sensible values range from 1M to 8M. A big log buffer allows large transactions to run without a need to write the log to disk until the transaction commit. Thus, if you have big transactions, making the log buffer big will save disk I/O. + + + + Flush Log at: + 0 + 1 + Specifies when log files are flushed to disk. + + Write to Log and flush every second=0 + Transaction commit flushes logs=1 + Write Log at commit, flush every second=2 + + + + Flush Method: + fdatasync + Method used for flushing the log files to disk. + + fdatasync (safe, recommended)=fdatasync + O_DSYNC (faster, but relies on OS/drv/hdw)=O_DSYNC + nosync (not for production systems)=nosync + + + + Log archive + 0 + This value should currently be disabled. + + InnoDB log archive disabled=0 + InnoDB log archive enabled=1 + + + + Log Archive Dir: + data + $windows_program_dir$MySQL\data + Directory path where log archives should be stored. + + + + Various + + Lock Wait Timeout: + 2 + Timeout in seconds InnoDB transaction may wait for a lock before being rolled back. InnoDB automatically detects transaction deadlocks in its own lock table and rolls back the transaction. If you use the LOCK TABLES command, or other transaction-safe storage engines than InnoDB in the same transaction, then a deadlock may arise which InnoDB cannot notice. In cases like this the timeout is useful to resolve the situation. + + + Open Files: + 300 + This is relevant only if you use multiple tablespaces in InnoDB. This specifies the maximum how many .ibd files InnoDB can keep open at one time. The minimum value for this is 10. The default is 300. + + + File IO Threads: + 4 + Number of file I/O threads in InnoDB. Normally, this should be 4, but on Windows disk I/O may benefit from a larger number. + + + Thread concurrency + 8 + Helps in performance tuning in heavily concurrent environments. + + + Force recovery + 0 + Helps to save your data in case the disk image of the database becomes corrupt. + + + Fast shutdown + Checked + Speeds up server shutdown process. + + + Max Dirty Pages + 90 + Percentage of dirty pages allowed in bufferpool + + + + + Performance + You can configure performance and caching related options here. + + Query cache + + Query cache limit + 1M + Don't cache results that are bigger than this. + + + + Minimal size of result unit + 4096k + minimal size of unit in wich space for results is allocated (last unit will be trimed after writing all result data + + + + Cache Size + 0 + The memory allocated to store results from old queries. + + + + Cache type + 1 + Query cache type to use. + + Don't cache or retrieve results=0 + Cache all queries except SELECT SQL_NO_CACHE=1 + Cache only SELECT SQL_CACHE queries=2 + + + + + + Log files + You can configure all log files options here. + + Activate Logging + + Binary Logfile Name: + + Enter a name for the binary log. Otherwise a default name will be used. + + + Query Logfile Name: + + Enter a name for the query log file. Otherwise a default name will be used. + + + Error Logfile Name: + + Enter a name for the error log file. Otherwise a default name will be used. + + + Slow Queries Log: + + Enter a name for the slow query log. Otherwise a default name will be used. + + + Update Logfile Name: + + Enter a name for the update log file. Otherwise a default name will be used. + + + Isam Logfile Name: + + Enter a name for the isam logfile. Otherwise a default name will be used. + + + + Binlog Options + + Log updates for these databases only + Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned. + + + Ignore updates for these databases + Tells the master that updates to the given database should not be logged to the binary log. + + + Filename of the index for binary logfiles + File that holds the names for last binary log files. + + + Maximum binary log size + 1024M + Binary log will be rotated automatically when the size exceeds this value. Will also apply to relay logs if max_relay_log_size is 0. The minimum value for this variable is 4096. + + + + + Slow query log options + + Long query time + 2 + Log all queries that have taken more than long_query_time seconds to execute to file. + + + + Advanced log options + + Log only in short format + Unchecked + Don't log extra information to update and slow-query logs. + + + Log queries that don't use indexes + Unchecked + Log queries that are executed without benefit of any index. + + + Log warnings + Unchecked + Log some not critical warnings to the log file. + + + Expire log days + 0 + Logs will be rotated after expire-log-days days + + + + + Replication + All replication options + + General + + Server Id + 0 + Uniquely identifies the server instance in the community of replication partners. + + + + Master + + Show Slave authentication Info + Unchecked + Show user and password in SHOW SLAVE HOSTS + + + + General slave + + Do not start slave automaticaly + Unchecked + If set, slave is not autostarted. + + + Use compression + Unchecked + Use compression on master/slave protocol. + + + Log slave updates + Unchecked + Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves. + + + Temporary Directory + The location where the slave should put its temporary files when replicating a LOAD DATA INFILE command. + + + Skip the following errors: + Tells the slave thread to continue replication when a query returns an error from the provided list. + + + Initial commands + Command(s) that are executed when a slave connects to this master + + + Initial replication role + Set the replication role + + + Slave timeout + 3600 + Number of seconds to wait for more data from a master/slave connection before aborting the read + + + + Slave replication objects + + Replicate these databases: + Tells the slave thread to restrict replication to the specified database. To specify more than one database,use the directive multiple times, once for each database.Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.% + + + Replicate these tables: + Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db. + + + Replicate wild these tables: + Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. Tospecify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar + + + Ignore DBs: + Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore,use the directive multiple times, once for each database. This option will not work if you use cross databaseupdates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.% + + + Ignore tables: + Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db. + + + Wild ignore tables: + Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar. + + + Rewrite DB names: + Updates to a database with a different name than the original. Example:replicate-rewrite-db=master_db_name->slave_db_name. + + + + Slave Identification + + Report Host: + Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts. + + + Report User: + This username will be displayed in the output of "SHOW SLAVE HOSTS". + + + Report Password: + This password will be displayed in the output of "SHOW SLAVE HOSTS". + + + Report Port + 3306 + Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset. + + + + Relay Log + + Relay log filename: + The location and name to use for relay logs. + + + Relay log index filename: + The location and name to use for the file that keeps a list of the last relay logs. + + + Relay log info filename: + The location and name of the file that remembers where the SQL replication thread is in the relay logs. + + + Purge relay logs + Unchecked + 0 = do not purge relay logs. 1 = purge them as soon as they are no more needed. + + + Maximum size for all relay logs together: + 0 + Maximum space to use for all relay logs. + + + Maximum relay log size + 0 + If non-zero: relay log will be rotated automatically when the size exceeds this value; if zero (the default): when the size exceeds max_binlog_size. 0 expected, the minimum value for this variable is 4096. + + + + Slave default connection values + + Master hostname: + Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file. + + + Master Username: + The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read. + + + Master password: + The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read. + + + Master port + 3306 + The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read. + + + Master connect retry + 60 + The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost. + + + Master retry count + 86400 + The number of tries the slave will make to connect to the master before giving up. + + + Master info file name: + The location and name of the file that remembers the master and where the I/O replication thread is in the master's binlogs. + + + Master ssl + Unchecked + Enable the slave to connect to the master using SSL. + + + Master SSL Key: + Master SSL keyfile name. Only applies if you have enabled master-ssl. + + + Master SSL Certificate filename: + Master SSL certificate file name. Only applies if you have enabled master-ssl + + + Master SSL CA filename: + Master SSL CA file. Only applies if you have enabled master-ssl. + + + Master SSL CA-path: + Master SSL CA path. Only applies if you have enabled master-ssl. + + + Master SSL Cipher: + Master SSL cipher. Only applies if you have enabled master-ssl. + + + + + Networking + All network settings + + General + + Socket file name: + /tmp/mysql.sock + mysql + Name of the socket file to use. + + + + Data / Memory size + + Max. packet size: + 1M + Max packetlength to send/receive from to server. + + + + Net buffer length + 16 + Buffer length for TCP/IP and socket communication. + + + + + Timeout Settings + + Connection timeout + 0 + The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake' + + + Interactive timeout + 28800 + The number of seconds the server waits for activity on an interactive connection before closing it. + + + Read timeout + 30 + Number of seconds to wait for more data from a connection before aborting the read + + + Write timeout + 60 + Number of seconds to wait for a block to be written to a connection before aborting the writ + + + Wait timeout + 28800 + The number of seconds the server waits for activity on a connection before closing it + + + + Advanced + + Max Connections: + 100 + The number of simultaneous clients allowed. + + + Max Conn per User: + 0 + The maximum number of active connections for a single user (0 = no limit). + + + Retry count: + 10 + If a read on a communication port is interrupted, retry this many times before giving up. + + + Max Conn Errors: + 10 + If there is more than this number of interrupted connections from a host this host will be blocked from further connections. + + + + Naming + + Disable caching of host-names + Unchecked + Don't cache host names. + + + Disable name resolving + Unchecked + Don't resolve hostnames. All hostnames are IP's or 'localhost'. + + + + + Security + This page contains general parameters for the MySQL server. + + Security + + Safe User Create + Unchecked + Don't allow new user creation by the user who has no write privileges to the mysql.user table. + + + Disable grant tables + Unchecked + Start without grant tables. This gives all users FULL ACCESS to all tables! + + + Make all tables read-only + Unchecked + Make all tables read-only, with the exception of replication (slave) threads and users with the SUPER privilege. + + + Deactivate show database + Unchecked + Don't allow 'SHOW DATABASE' commands + + + Use old passwords + Unchecked + Use old password encryption method (needed for 4.0 and older clients). + + + Secure authentication + Unchecked + Disallow authentication for accounts that have old (pre-4.1) passwords. + + + Enable load data local infile + Unchecked + Enable/disable LOAD DATA LOCAL INFILE + + + + + Advanced + You will find all advanced settings here. + + Localization + + Language: + Client error messages in given language. May be given as a full path. + + + Def. Char Set: + Set the default character set. + + + Default Collation: + Set the default collation. + + + Charsets directory: + + Path to the character-sets directory. + + + + General + + Print stack trace + Unchecked + Print a symbolic stack trace on failure. + + + Flush tables + Unchecked + Flush tables to disk between SQL commands. + + + Flush time + 0 + A dedicated thread is created to flush all tables at the given interval. + + + Set up for GDB + Unchecked + Set up signals usable for debugging + + + Low prioriy updates + Unchecked + INSERT/DELETE/UPDATE has lower priority than selects. + + + Memory lock + Unchecked + Lock mysqld in memory.(=Don't swap.) + + + Old rpl compat + Unchecked + Use old LOAD DATA format in the binary log (don't save data in file). + + + Disable stack trace + Unchecked + Don't print a stack trace on failure + + + Default week format: + The default week format used by WEEK() functions. + + + Open files limit + 0 + If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files. + + + Maximum error count + 64 + Max number of errors/warnings to store for a statement. + + + + Thread specific settings + + Deactivate thread priority + Unchecked + Don't give threads different priorities. + + + Thread concurrency + 10 + Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time + + + Thread cache size + 0 + How many threads we should keep in a cache for reuse. + + + Thread stack size + 192k + The stack size for each thread. + + + + Slow launch time + 2 + If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented. + + + + Insert delayed settings + + Insert delayed Timeout + 300 + How long a INSERT DELAYED thread should wait for INSERT statements before terminating. + + + Insert delayed Limit + 100 + After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing. + + + Insert delayed queue size + 1k + What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again. + + + + Maximum Threads + 20 + Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used. + + + + Various + + Max join size + 4095M + Joins that are probably going to read more than max_join_size records return an error + + + + Maximum binlog cache size: + 4095M + Can be used to restrict the total size used to cache a multi-transaction query. + + + + Query alloc block size: + 8k + Allocation block size for query parsing and execution + + + + Query prealloc size + 8k + Persistent buffer for query parsing and execution + + + + Read buffer size + 128k + Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value. + + + + Read rnd buffer size + 256k + When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer. + record_buffer + + + + Range alloc block size + 2k + Allocation block size for storing ranges during optimization + + + + Preload buffer size + 32k + The size of the buffer that is allocated when preloading + indexes + + + + Table cache: + 64 + The number of open tables for all threads. + + + Temporary table size + 32M + If an in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM table. + + + + Transaction alloc block size + 8k + Allocation block size for transactions to be stored in binary log + + + + Transaction prealloc size + 4k + Persistent buffer for transactions to be stored in binary log + + + + Max write lock count + 4294967295 + After this many write locks, allow some read locks to run in between + + + Bulk insert buffer size + 8M + Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread! + + + + Max heap table size + 16M + Don't allow creation of heap tables bigger than this. + + + + Max length for sort data + 1k + Max number of bytes in sorted records. + + + + Max seeks for key + 4294967295 + Limit assumed max number of seeks when looking up rows based on a key + + + Max sort length + 1k + The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored). + + + + Max temporary tables: + 32 + Maximum number of temporary tables a client can keep open at a time. + + + Join buffer size: + 128k + The size of the buffer that is used for full joins. + + + + Key cache block size + 1k + The default size of key cache blocks + + + + Key cache division limit + 100 + The minimum percentage of warm blocks in key cache + + + Key cache division age treshold + 300 + This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache + + + Back log size + 50 + The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time. + + + Binlog cache size + 32k + The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance. + + + + Group concat max len + 1k + The maximum length of the result of function group_concat. + + + + Delay key write: + Type of DELAY_KEY_WRITE. + + + Make table names case insensitive + 1 + If set to 0, table and db names are stored with the lettercase specified during creation and comparisons are case sensitive. If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. If set to 2, names are stored as specified during creation but are compared case-insensitively (Only works on case-insensitive filesystems, starting from MySQL 4.1.8). + + 0- Store as Created, Case Sensitive=0 + 1- Store in Lowercase, Case Insensitive=1 + 2- Store as Created, Case Insensitive=2 + + + + Enable symbolic link support + Unchecked + N/A + + + Run as User: + Run mysqld daemon as user. + + + SQL Mode: + Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT,ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION. + + + Use pool for temporary files + Unchecked + Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file. + + + Default transaction isolation level: + REPEATABLE-READ + Default transaction isolation level + + READ-UNCOMMITTED=READ-UNCOMMITTED + READ-COMMITTED=READ-COMMITTED + REPEATABLE-READ=REPEATABLE-READ + SERIALIZABLE=SERIALIZABLE + + + + Use ANSI SQL + Unchecked + Use ANSI SQL syntax instead of MySQL syntax. + + + Big Tables + Unchecked + Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors). + + + Bind to IP: + IP address to bind to. + + + Write core file + Unchecked + Write core on errors. + + + Chroot: + Chroot mysqld daemon during startup. + + + Init connect: + Command(s) that are executed for each new connection + + + Use new routines + Unchecked + Use very new possible 'unsafe' functions. + + + Pid filename: + Pid file used by safe_mysqld. + + + + + + diff --git a/gulliver/js/maborak/samples/grid.files/paises.grid b/gulliver/js/maborak/samples/grid.files/paises.grid new file mode 100644 index 000000000..9ddfe4514 --- /dev/null +++ b/gulliver/js/maborak/samples/grid.files/paises.grid @@ -0,0 +1 @@ +{"column":[{"title":"Nro.","type":"drag","paint":"bg1","width":"5%","searchable":true},{"title":"País","type":"text","edit":true,"width":"75%","style":{"fontWeight":"bold"},"searchable":true},{"title":"Usuarios","type":"text","edit":true,"style":{"fontWeight":"bold"},"width":"20%","searchable":true}],"rows":[{"info":{"rowIndex":1},"data":[{"value":"Bolivia"},{"value":"1"}]},{"info":{"rowIndex":2},"data":[{"value":"Argentina"},{"value":"1"}]},{"info":{"rowIndex":3},"data":[{"value":"Brasil"},{"value":"1"}]},{"info":{"rowIndex":4},"data":[{"value":"Uruguay"},{"value":"1"}]},{"info":{"rowIndex":5},"data":[{"value":"Ecuador"},{"value":"1"}]},{"info":{"rowIndex":6},"data":[{"value":"Paraguay"},{"value":"1"}]},{"info":{"rowIndex":7},"data":[{"value":"Chile"},{"value":0}]}]} \ No newline at end of file diff --git a/gulliver/js/maborak/samples/grid.files/sample.grid b/gulliver/js/maborak/samples/grid.files/sample.grid new file mode 100644 index 000000000..fac068807 --- /dev/null +++ b/gulliver/js/maborak/samples/grid.files/sample.grid @@ -0,0 +1 @@ +{"column":[{"title":"Nro.","type":"drag","width":"5%","paint":"bg1","searchable":true},{"title":"Artist","type":"text","edit":true,"width":"20%","styleValues":{"backgroundColor":"#fafafa"},"searchable":true},{"title":"History","type":"textarea","edit":true,"width":"50%","searchable":true},{"title":"Albums","width":"5%","edit":false,"type":"text","searchable":true,"paint":"bg1"},{"title":"Genre","type":"dropdown","width":"20%","edit":true,"data":[[0,"EBM"],[1,"Darkwave"],[2,"Industrial"],[3,"Electro dark"],[4,"Otro"]],"searchable":true}],"rows":[]}]} \ No newline at end of file diff --git a/gulliver/js/maborak/samples/grid.json b/gulliver/js/maborak/samples/grid.json new file mode 100644 index 000000000..99c7712d0 --- /dev/null +++ b/gulliver/js/maborak/samples/grid.json @@ -0,0 +1,39 @@ +{"column":[{"title":"Nro.","type":"drag","width":"5%","paint":"bg1","searchable":true},{"title":"Artist","type":"text","edit":true,"width":"20%","styleValues":{"backgroundColor":"#fafafa"},"searchable":true},{"title":"History","type":"textarea","edit":true,"width":"50%","searchable":true},{"title":"Albums","width":"5%","edit":false,"type":"text","searchable":true,"paint":"bg1"},{"title":"Genre","type":"dropdown","width":"20%","edit":true,"data":[[0,"EBM"],[1,"Darkwave"],[2,"Industrial"],[3,"Electro dark"],[4,"Otro"]],"searchable":true}], +"rows":[ +{"info":{"rowIndex":1},"data":[{"value":"[SITD]"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":0},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, +{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]}, + + + + + +{"info":{"rowIndex":3},"data":[{"value":"A Industrya"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"6"},{"value":0}]},{"info":{"rowIndex":4},"data":[{"value":"Rabia sA Split Second"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"
    Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam. Vestibulum semper. Nullam non odio. Aliquam quam.
    "},{"value":"1"},{"value":1}]}]} diff --git a/gulliver/js/maborak/samples/grid.json.data.load.php b/gulliver/js/maborak/samples/grid.json.data.load.php new file mode 100644 index 000000000..c22b7b849 --- /dev/null +++ b/gulliver/js/maborak/samples/grid.json.data.load.php @@ -0,0 +1,25 @@ + diff --git a/gulliver/js/maborak/samples/grid.json.data.save.php b/gulliver/js/maborak/samples/grid.json.data.save.php new file mode 100644 index 000000000..a82ef0743 --- /dev/null +++ b/gulliver/js/maborak/samples/grid.json.data.save.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/grid.txt b/gulliver/js/maborak/samples/grid.txt new file mode 100644 index 000000000..5bc8c240a --- /dev/null +++ b/gulliver/js/maborak/samples/grid.txt @@ -0,0 +1 @@ +{"column":[{"title":"Nro.","type":"drag","width":"5%","paint":"bg1","searchable":true},{"title":"Artist","type":"text","edit":true,"width":"20%","styleValues":{"backgroundColor":"#fafafa"},"searchable":true},{"title":"History","type":"textarea","edit":true,"width":"50%","searchable":true},{"title":"Albums","width":"5%","edit":false,"type":"text","searchable":true,"paint":"bg1"},{"title":"Genre","type":"dropdown","width":"20%","edit":true,"data":[[0,"EBM"],[1,"Darkwave"],[2,"Industrial"],[3,"Electro dark"],[4,"Otro"]],"searchable":true}],"rows":[{"info":{"rowIndex":1},"data":[{"value":"[SITD]"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":0},{"value":0}]},{"info":{"rowIndex":2},"data":[{"value":"3rd And The Mortal"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":3},"data":[{"value":"A Industrya"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"6"},{"value":0}]},{"info":{"rowIndex":4},"data":[{"value":"Rabia sA Split Second"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":5},"data":[{"value":"Absurd Minds"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":0}]},{"info":{"rowIndex":6},"data":[{"value":"Abuse"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":7},"data":[{"value":"Adam"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":3}]},{"info":{"rowIndex":8},"data":[{"value":"Aenima"},{"value":"asdasdasdasd"},{"value":"1"},{"value":4}]},{"info":{"rowIndex":9},"data":[{"value":"Aesma daeva"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":10},"data":[{"value":"After forever \"blabla\""},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":4}]},{"info":{"rowIndex":11},"data":[{"value":"Agonoize"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":12},"data":[{"value":"Aire'n terre"},{"value":"Vestibulum semper. Nullam non odio. Aliquam quam."},{"value":"1"},{"value":1}]},{"info":{"rowIndex":13},"data":[{"value":"Akoma"},{"value":"tttt"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"dfgdfgdfg"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample"},{"value":"1"},{"value":1}]},{"info":{"rowIndex":14},"data":[{"value":"Alien sex fiend"},{"value":"Data sample Ultimo"},{"value":"1"},{"value":1}]}]} \ No newline at end of file diff --git a/gulliver/js/maborak/samples/hard.tpl b/gulliver/js/maborak/samples/hard.tpl new file mode 100755 index 000000000..b0a38e02e --- /dev/null +++ b/gulliver/js/maborak/samples/hard.tpl @@ -0,0 +1,544 @@ +
    +
    +
    +
    + + + +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.FR_TIT1}
    {$form.FR_ST1}
    {$FR_NOMB}{$FR_PATE}{$FR_MATE}
    {$form.FR_NOMB}{$form.FR_PATE}{$form.FR_MATE}
    {$FR_FNAC}{$FR_ORIG}{$FR_NDOC}
    {$form.FR_LNAC} {$form.FR_FNAC}{$form.FR_ORIG}{$form.FR_NDOC} {$form.FR_DEPT}{$form.FR_PAIS}
    {$FR_TELE} {$FR_CELU}{$FR_CORR}{$FR_SEXO}
    {$form.FR_TELE}{$form.FR_CELU}{$form.FR_CORR}{$form.FR_SEXO}
    {$form.FR_ST2}
    + + + + + + + + + + + +
    {$form.CH_BACHI}{$form.CH_INDUS}{$form.CH_COMER}
    {$form.CH_MADUR}{$form.CH_SOCIA}{$form.CH_DIVER}
    {$form.FR_ST3}
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Año
    Curso
    Colegio
    Tipo
    Ciudad
    Provincia
    {$form.ANIO12}
    4to de Secundaria
    +
    {$form.TIPO12}
    {$form.CIUDAD12}

    {$form.PROVINCIA12}

    {$form.ANIO11}
    3ro de Secundaria
    {$form.TIPO11}
    {$form.CIUDAD11}

    {$form.PROVINCIA11}

    {$form.ANIO10}
    2do de Secundaria
    {$form.TIPO10}
    {$form.CIUDAD10}

    {$form.PROVINCIA10}

    {$form.ANIO9}
    1ro de Secundaria
    {$form.TIPO9}
    {$form.CIUDAD9}

    {$form.PROVINCIA9}

    {$form.ANIO8}
    8vo de Primaria
    {$form.TIPO8}
    {$form.CIUDAD8}

    {$form.PROVINCIA8}

    {$form.ANIO7}
    7mo de Primaria
    {$form.TIPO7}
    {$form.CIUDAD7}

    {$form.PROVINCIA7}

    {$form.ANIO6}
    6to de Primaria
    {$form.TIPO6}
    {$form.CIUDAD6}

    {$form.PROVINCIA6}

    {$form.ANIO5}
    5to de Primaria
    {$form.TIPO5}
    {$form.CIUDAD5}

    {$form.PROVINCIA5}

    {$form.ANIO4}
    4to de Primaria
    {$form.TIPO4}
    {$form.CIUDAD4}

    {$form.PROVINCIA4}

    {$form.ANIO3}
    3ro de Primaria
    {$form.TIPO3}
    {$form.CIUDAD3}

    {$form.PROVINCIA3}

    {$form.ANIO2}
    2do de Primaria
    {$form.TIPO2}
    {$form.CIUDAD2}

    {$form.PROVINCIA2}

    {$form.ANIO1}
    1ro de Primaria
    {$form.TIPO1}
    {$form.CIUDAD1}

    {$form.PROVINCIA1}

    + +{literal} + +{/literal} +

    {$form.FR_SUBMIT}

    +
    diff --git a/gulliver/js/maborak/samples/hard.xml b/gulliver/js/maborak/samples/hard.xml new file mode 100755 index 000000000..d9f929bd2 --- /dev/null +++ b/gulliver/js/maborak/samples/hard.xml @@ -0,0 +1,111 @@ + + +FORMULARIO DE SOLICITUD DE TRAMITE DIPLOMA DE BACHILLER +DATOS GENERALES DEL INTERESADO +Nombres +Apellido Paterno +Apellido Materno + +Lugar y Fecha de Nacimiento + Nacionalidad +Numero de Doc. de Identidad +Telefono +Celular +Correo Electronico + Sexo + +INFORMACION PARA LA EMISION DEL DIPLOMA +Humanidades +Industrial +Comercial +Madurez y Suficiencia (CEMA) +Sociales y Cs. Naturales +Diversificado (ISEC La Paz) +COLEGIOS DE PROCEDENCIA + + +Departamento + + + + + + + + + + + +select IC_UID, IC_NAME from ISO_COUNTRY Pais + +ANIO12 +ANIO11 +ANIO10 +ANIO9 +ANIO8 +ANIO7 +ANIO6 +ANIO5 +ANIO4 +ANIO3 +ANIO2 +ANIO1 + + + + +4to de Secundaria +3ro de Secundaria +2do de Secundaria +1ro de Secundaria +8vo de Primaria +7mo de Primaria +6mo de Primaria +5to de Primaria +4to de Primaria +3ro de Primaria +2do de Primaria +1ro de Primaria + +TIPO12 +TIPO11 +TIPO10 +TIPO9 +TIPO8 +TIPO7 +TIPO6 +TIPO5 +TIPO4 +TIPO3 +TIPO2 +TIPO1 + +CIUDAD12 +CIUDAD11 +CIUDAD10 +CIUDAD9 +CIUDAD8 +CIUDAD7 +CIUDAD6 +CIUDAD5 +CIUDAD4 +CIUDAD3 +CIUDAD2 +CIUDAD1 + + +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 +PROVINCIA12 + +Enviar + diff --git a/gulliver/js/maborak/samples/index.php b/gulliver/js/maborak/samples/index.php new file mode 100644 index 000000000..b79e7824e --- /dev/null +++ b/gulliver/js/maborak/samples/index.php @@ -0,0 +1,377 @@ +'; +?> + + + + + Web samples + + + + + + + + + + diff --git a/gulliver/js/maborak/samples/leimnud.html b/gulliver/js/maborak/samples/leimnud.html new file mode 100644 index 000000000..f2fa401f2 --- /dev/null +++ b/gulliver/js/maborak/samples/leimnud.html @@ -0,0 +1,47 @@ + + + + Prueba leimnud + + + + + + + diff --git a/gulliver/js/maborak/samples/leimnud.module.mail.sender.php b/gulliver/js/maborak/samples/leimnud.module.mail.sender.php new file mode 100644 index 000000000..d48e66842 --- /dev/null +++ b/gulliver/js/maborak/samples/leimnud.module.mail.sender.php @@ -0,0 +1,93 @@ + + .lrss_table{ + font:normal 8pt sans-serif; + border-collapse:collapse; + width:100%; + } + .lrss_table td{ + border:1px solid #AAA; + } + .lrss_tdTitle, .lrss_tdHeader, .lrss_link, .lrss_link2 + { + background:transparent url(".$server_css."maborak/core/images/grid.title.gray.gif) repeat-x; + background-position:0 0; + padding:2px; + } + .lrss_tdTitle + { + font-weight:bold; + padding-left:15px; + } + .lrss_tdHeader + { + background-position:0 -10; + text-align:right; + } + .lrss_tdContent + { + background-color:#EEE; + padding:15px; + } + .lrss_link, .lrss_link2 + { + padding:5px; + background-position:0 -10; + } + .lrss_link + { + text-align:right; + } + .lrss_link2 + { + color:#666; + font-weight:bold; + } + .lrss_link2 a:link + { + color:#A62C2C; + text-decoration:none; + } + .lrss_link2 a:hover + { + color:#999; + text-decoration:underline; + } + + + + + + + + + + + + + + + + +
    Maborak Feed Reader ( http://rss.maborak.com )
    Feed sender
    + asdasd
    + asdasd
    + asdasd
    + asdasd
    + asdasd
    +
    http://asas.com
    + "; +$content_type = 'Content-type: text/html; charset=utf-8'; +$cabeceras = 'From: maborak@maborak.com' . "\r\n" . + 'Reply-To: maborak@maborak.com' . "\r\n" . + 'X-Mailer: PHP/' . phpversion(). "\r\n". + 'MIME-Version: 1.0' . "\r\n". + $content_type."\r\n"; +mail($para, $asunto, $mensaje, $cabeceras); +header($content_type); +echo $mensaje; +?> diff --git a/gulliver/js/maborak/samples/link.php b/gulliver/js/maborak/samples/link.php new file mode 100644 index 000000000..b225186a9 --- /dev/null +++ b/gulliver/js/maborak/samples/link.php @@ -0,0 +1,6 @@ + +

    +Página 1 link a Página 2
    \ No newline at end of file diff --git a/gulliver/js/maborak/samples/link2.php b/gulliver/js/maborak/samples/link2.php new file mode 100644 index 000000000..6e5463538 --- /dev/null +++ b/gulliver/js/maborak/samples/link2.php @@ -0,0 +1,6 @@ + +

    +Página 2 link a Página 1
    \ No newline at end of file diff --git a/gulliver/js/maborak/samples/links.html b/gulliver/js/maborak/samples/links.html new file mode 100644 index 000000000..74cb5307b --- /dev/null +++ b/gulliver/js/maborak/samples/links.html @@ -0,0 +1,22 @@ + + + Links + + + + + bla bla bla Link to page 1.html
    + bla bla bla Link to page 2.html
    + bla bla bla Link to page 2 con Ancho, Alto y color de fondo y opacidad.html
    + bla bla bla Link with title y tamaño personalizado.html
    + + diff --git a/gulliver/js/maborak/samples/maborak.html b/gulliver/js/maborak/samples/maborak.html new file mode 100644 index 000000000..2946b6071 --- /dev/null +++ b/gulliver/js/maborak/samples/maborak.html @@ -0,0 +1,49 @@ + + + + Prueba leimnud + + + + + + + + + diff --git a/gulliver/js/maborak/samples/maborak.module.rss.php b/gulliver/js/maborak/samples/maborak.module.rss.php new file mode 100644 index 000000000..07345521d --- /dev/null +++ b/gulliver/js/maborak/samples/maborak.module.rss.php @@ -0,0 +1,13 @@ +Error loading RSS"; + } +} +?> diff --git a/gulliver/js/maborak/samples/menu.html b/gulliver/js/maborak/samples/menu.html new file mode 100644 index 000000000..c039ba4c1 --- /dev/null +++ b/gulliver/js/maborak/samples/menu.html @@ -0,0 +1,131 @@ + + + + + + + + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/module.rss.proxy.php b/gulliver/js/maborak/samples/module.rss.proxy.php new file mode 100644 index 000000000..a7e2179c4 --- /dev/null +++ b/gulliver/js/maborak/samples/module.rss.proxy.php @@ -0,0 +1,8 @@ + diff --git a/gulliver/js/maborak/samples/mootools.svn.js b/gulliver/js/maborak/samples/mootools.svn.js new file mode 100644 index 000000000..986426c55 --- /dev/null +++ b/gulliver/js/maborak/samples/mootools.svn.js @@ -0,0 +1,7102 @@ +/* +Script: Core.js + Mootools - My Object Oriented javascript. + +License: + MIT-style license. + +MooTools Copyright: + copyright (c) 2007 Valerio Proietti, + +MooTools Credits: + - Class is slightly based on Base.js (c) 2006 Dean Edwards, License + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license + - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. +*/ + +var MooTools = { + version: '1.11' +}; + +/* Section: Core Functions */ + +/* +Function: $defined + Returns true if the passed in value/object is defined, that means is not null or undefined. + +Arguments: + obj - object to inspect +*/ + +function $defined(obj){ + return (obj != undefined); +}; + +/* +Function: $type + Returns the type of object that matches the element passed in. + +Arguments: + obj - the object to inspect. + +Example: + >var myString = 'hello'; + >$type(myString); //returns "string" + +Returns: + 'element' - if obj is a DOM element node + 'textnode' - if obj is a DOM text node + 'whitespace' - if obj is a DOM whitespace node + 'arguments' - if obj is an arguments object + 'object' - if obj is an object + 'string' - if obj is a string + 'number' - if obj is a number + 'boolean' - if obj is a boolean + 'function' - if obj is a function + 'regexp' - if obj is a regular expression + 'class' - if obj is a Class. (created with new Class, or the extend of another class). + 'collection' - if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc. + false - (boolean) if the object is not defined or none of the above. +*/ + +function $type(obj){ + if (!$defined(obj)) return false; + if (obj.htmlElement) return 'element'; + var type = typeof obj; + if (type == 'object' && obj.nodeName){ + switch(obj.nodeType){ + case 1: return 'element'; + case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; + } + } + if (type == 'object' || type == 'function'){ + switch(obj.constructor){ + case Array: return 'array'; + case RegExp: return 'regexp'; + case Class: return 'class'; + } + if (typeof obj.length == 'number'){ + if (obj.item) return 'collection'; + if (obj.callee) return 'arguments'; + } + } + return type; +}; + +/* +Function: $merge + merges a number of objects recursively without referencing them or their sub-objects. + +Arguments: + any number of objects. + +Example: + >var mergedObj = $merge(obj1, obj2, obj3); + >//obj1, obj2, and obj3 are unaltered +*/ + +function $merge(){ + var mix = {}; + for (var i = 0; i < arguments.length; i++){ + for (var property in arguments[i]){ + var ap = arguments[i][property]; + var mp = mix[property]; + if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap); + else mix[property] = ap; + } + } + return mix; +}; + +/* +Function: $extend + Copies all the properties from the second passed object to the first passed Object. + If you do myWhatever.extend = $extend the first parameter will become myWhatever, and your extend function will only need one parameter. + +Example: + (start code) + var firstOb = { + 'name': 'John', + 'lastName': 'Doe' + }; + var secondOb = { + 'age': '20', + 'sex': 'male', + 'lastName': 'Dorian' + }; + $extend(firstOb, secondOb); + //firstOb will become: + { + 'name': 'John', + 'lastName': 'Dorian', + 'age': '20', + 'sex': 'male' + }; + (end) + +Returns: + The first object, extended. +*/ + +var $extend = function(){ + var args = arguments; + if (!args[1]) args = [this, args[0]]; + for (var property in args[1]) args[0][property] = args[1][property]; + return args[0]; +}; + +/* +Function: $native + Will add a .extend method to the objects passed as a parameter, but the property passed in will be copied to the object's prototype only if non previously existent. + Its handy if you dont want the .extend method of an object to overwrite existing methods. + Used automatically in MooTools to implement Array/String/Function/Number methods to browser that dont support them whitout manual checking. + +Arguments: + a number of classes/native javascript objects + +*/ + +var $native = function(){ + for (var i = 0, l = arguments.length; i < l; i++){ + arguments[i].extend = function(props){ + for (var prop in props){ + if (!this.prototype[prop]) this.prototype[prop] = props[prop]; + if (!this[prop]) this[prop] = $native.generic(prop); + } + }; + } +}; + +$native.generic = function(prop){ + return function(bind){ + return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1)); + }; +}; + +$native(Function, Array, String, Number); + +/* +Function: $chk + Returns true if the passed in value/object exists or is 0, otherwise returns false. + Useful to accept zeroes. + +Arguments: + obj - object to inspect +*/ + +function $chk(obj){ + return !!(obj || obj === 0); +}; + +/* +Function: $pick + Returns the first object if defined, otherwise returns the second. + +Arguments: + obj - object to test + picked - the default to return + +Example: + (start code) + function say(msg){ + alert($pick(msg, 'no meessage supplied')); + } + (end) +*/ + +function $pick(obj, picked){ + return $defined(obj) ? obj : picked; +}; + +/* +Function: $random + Returns a random integer number between the two passed in values. + +Arguments: + min - integer, the minimum value (inclusive). + max - integer, the maximum value (inclusive). + +Returns: + a random integer between min and max. +*/ + +function $random(min, max){ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +/* +Function: $time + Returns the current timestamp + +Returns: + a timestamp integer. +*/ + +function $time(){ + return new Date().getTime(); +}; + +/* +Function: $clear + clears a timeout or an Interval. + +Returns: + null + +Arguments: + timer - the setInterval or setTimeout to clear. + +Example: + >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. + >myTimer = $clear(myTimer); //nevermind + +See also: + , +*/ + +function $clear(timer){ + clearTimeout(timer); + clearInterval(timer); + return null; +}; + +/* +Class: Abstract + Abstract class, to be used as singleton. Will add .extend to any object + +Arguments: + an object + +Returns: + the object with an .extend property, equivalent to <$extend>. +*/ + +var Abstract = function(obj){ + obj = obj || {}; + obj.extend = $extend; + return obj; +}; + +//window, document + +var Window = new Abstract(window); +var Document = new Abstract(document); +document.head = document.getElementsByTagName('head')[0]; + +/* +Class: window + Some properties are attached to the window object by the browser detection. + +Note: + browser detection is entirely object-based. We dont sniff. + +Properties: + window.ie - will be set to true if the current browser is internet explorer (any). + window.ie6 - will be set to true if the current browser is internet explorer 6. + window.ie7 - will be set to true if the current browser is internet explorer 7. + window.gecko - will be set to true if the current browser is Mozilla/Gecko. + window.webkit - will be set to true if the current browser is Safari/Konqueror. + window.webkit419 - will be set to true if the current browser is Safari2 / webkit till version 419. + window.webkit420 - will be set to true if the current browser is Safari3 (Webkit SVN Build) / webkit over version 419. + window.opera - is set to true by opera itself. +*/ + +window.xpath = !!(document.evaluate); +if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; +else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true; +else if (document.getBoxObjectFor != null) window.gecko = true; + +/*compatibility*/ + +window.khtml = window.webkit; + +Object.extend = $extend; + +/*end compatibility*/ + +//htmlelement + +if (typeof HTMLElement == 'undefined'){ + var HTMLElement = function(){}; + if (window.webkit) $dce("iframe"); //fixes safari + HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {}; +} +HTMLElement.prototype.htmlElement = function(){}; + +//enables background image cache for internet explorer 6 + +if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch(e){}; + +/* +Script: Class.js + Contains the Class Function, aims to ease the creation of reusable Classes. + +License: + MIT-style license. +*/ + +/* +Class: Class + The base class object of the framework. + Creates a new class, its initialize method will fire upon class instantiation. + Initialize wont fire on instantiation when you pass *null*. + +Arguments: + properties - the collection of properties that apply to the class. + +Example: + (start code) + var Cat = new Class({ + initialize: function(name){ + this.name = name; + } + }); + var myCat = new Cat('Micia'); + alert(myCat.name); //alerts 'Micia' + (end) +*/ + +var Class = function(properties){ + var klass = function(){ + return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this; + }; + $extend(klass, this); + klass.prototype = properties; + klass.constructor = Class; + return klass; +}; + +/* +Property: empty + Returns an empty function +*/ + +Class.empty = function(){}; + +Class.prototype = { + + /* + Property: extend + Returns the copy of the Class extended with the passed in properties. + + Arguments: + properties - the properties to add to the base class in this new Class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + var Cat = Animal.extend({ + initialize: function(name, age){ + this.parent(age); //will call the previous initialize; + this.name = name; + } + }); + var myCat = new Cat('Micia', 20); + alert(myCat.name); //alerts 'Micia' + alert(myCat.age); //alerts 20 + (end) + */ + + extend: function(properties){ + var proto = new this(null); + for (var property in properties){ + var pp = proto[property]; + proto[property] = Class.Merge(pp, properties[property]); + } + return new Class(proto); + }, + + /* + Property: implement + Implements the passed in properties to the base Class prototypes, altering the base class, unlike . + + Arguments: + properties - the properties to add to the base class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + Animal.implement({ + setName: function(name){ + this.name = name + } + }); + var myAnimal = new Animal(20); + myAnimal.setName('Micia'); + alert(myAnimal.name); //alerts 'Micia' + (end) + */ + + implement: function(){ + for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]); + } + +}; + +//internal + +Class.Merge = function(previous, current){ + if (previous && previous != current){ + var type = $type(current); + if (type != $type(previous)) return current; + switch(type){ + case 'function': + var merged = function(){ + this.parent = arguments.callee.parent; + return current.apply(this, arguments); + }; + merged.parent = previous; + return merged; + case 'object': return $merge(previous, current); + } + } + return current; +}; + +/* +Script: Class.Extras.js + Contains common implementations for custom classes. In Mootools is implemented in , and and many more. + +License: + MIT-style license. +*/ + +/* +Class: Chain + An "Utility" Class. Its methods can be implemented with into any . + Currently implemented in , and . In for example, is used to execute a list of function, one after another, once the effect is completed. + The functions will not be fired all togheter, but one every completion, to create custom complex animations. + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity'); + + myFx.start(1,0).chain(function(){ + myFx.start(0,1); + }).chain(function(){ + myFx.start(1,0); + }).chain(function(){ + myFx.start(0,1); + }); + //the element will appear and disappear three times + (end) +*/ + +var Chain = new Class({ + + /* + Property: chain + adds a function to the Chain instance stack. + + Arguments: + fn - the function to append. + */ + + chain: function(fn){ + this.chains = this.chains || []; + this.chains.push(fn); + return this; + }, + + /* + Property: callChain + Executes the first function of the Chain instance stack, then removes it. The first function will then become the second. + */ + + callChain: function(){ + if (this.chains && this.chains.length) this.chains.shift().delay(10, this); + }, + + /* + Property: clearChain + Clears the stack of a Chain instance. + */ + + clearChain: function(){ + this.chains = []; + } + +}); + +/* +Class: Events + An "Utility" Class. Its methods can be implemented with into any . + In Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel. + Events in a Class that implements can be either added as an option, or with addEvent. Never with .options.onEventName. + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){ + alert('the effect is completed'); + }).addEvent('onComplete', function(){ + alert('I told you the effect is completed'); + }); + + myFx.start(0,1); + //upon completion it will display the 2 alerts, in order. + (end) + +Implementing: + This class can be implemented into other classes to add the functionality to them. + Goes well with the class. + +Example: + (start code) + var Widget = new Class({ + initialize: function(){}, + finish: function(){ + this.fireEvent('onComplete'); + } + }); + Widget.implement(new Events); + //later... + var myWidget = new Widget(); + myWidget.addEvent('onComplete', myfunction); + (end) +*/ + +var Events = new Class({ + + /* + Property: addEvent + adds an event to the stack of events of the Class instance. + + Arguments: + type - string; the event name (e.g. 'onComplete') + fn - function to execute + */ + + addEvent: function(type, fn){ + if (fn != Class.empty){ + this.$events = this.$events || {}; + this.$events[type] = this.$events[type] || []; + this.$events[type].include(fn); + } + return this; + }, + + /* + Property: fireEvent + fires all events of the specified type in the Class instance. + + Arguments: + type - string; the event name (e.g. 'onComplete') + args - array or single object; arguments to pass to the function; if more than one argument, must be an array + delay - (integer) delay (in ms) to wait to execute the event + + Example: + (start code) + var Widget = new Class({ + initialize: function(arg1, arg2){ + ... + this.fireEvent("onInitialize", [arg1, arg2], 50); + } + }); + Widget.implement(new Events); + (end) + */ + + fireEvent: function(type, args, delay){ + if (this.$events && this.$events[type]){ + this.$events[type].each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + } + return this; + }, + + /* + Property: removeEvent + removes an event from the stack of events of the Class instance. + + Arguments: + type - string; the event name (e.g. 'onComplete') + fn - function that was added + */ + + removeEvent: function(type, fn){ + if (this.$events && this.$events[type]) this.$events[type].remove(fn); + return this; + } + +}); + +/* +Class: Options + An "Utility" Class. Its methods can be implemented with into any . + Used to automate the options settings, also adding Class when the option begins with on. + + Example: + (start code) + var Widget = new Class({ + options: { + color: '#fff', + size: { + width: 100 + height: 100 + } + }, + initialize: function(options){ + this.setOptions(options); + } + }); + Widget.implement(new Options); + //later... + var myWidget = new Widget({ + color: '#f00', + size: { + width: 200 + } + }); + //myWidget.options = {color: #f00, size: {width: 200, height: 100}} + (end) +*/ + +var Options = new Class({ + + /* + Property: setOptions + sets this.options + + Arguments: + defaults - object; the default set of options + options - object; the user entered options. can be empty too. + + Note: + if your Class has implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event. + */ + + setOptions: function(){ + this.options = $merge.apply(null, [this.options].extend(arguments)); + if (this.addEvent){ + for (var option in this.options){ + if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]); + } + } + return this; + } + +}); + +/* +Script: Array.js + Contains Array prototypes, <$A>, <$each> + +License: + MIT-style license. +*/ + +/* +Class: Array + A collection of The Array Object prototype methods. +*/ + +//custom methods + +Array.extend({ + + /* + Property: forEach + Iterates through an array; This method is only available for browsers without native *forEach* support. + For more info see + + *forEach* executes the provided function (callback) once for each element present in the array. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >['apple','banana','lemon'].each(function(item, index){ + > alert(index + " = " + item); //alerts "0 = apple" etc. + >}, bindObj); //optional second arg for binding, not used here + */ + + forEach: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this); + }, + + /* + Property: filter + This method is provided only for browsers without native *filter* support. + For more info see + + *filter* calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var biggerThanTwenty = [10,3,25,100].filter(function(item, index){ + > return item > 20; + >}); + >//biggerThanTwenty = [25,100] + */ + + filter: function(fn, bind){ + var results = []; + for (var i = 0, j = this.length; i < j; i++){ + if (fn.call(bind, this[i], i, this)) results.push(this[i]); + } + return results; + }, + + /* + Property: map + This method is provided only for browsers without native *map* support. + For more info see + + *map* calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var timesTwo = [1,2,3].map(function(item, index){ + > return item*2; + >}); + >//timesTwo = [2,4,6]; + */ + + map: function(fn, bind){ + var results = []; + for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this); + return results; + }, + + /* + Property: every + This method is provided only for browsers without native *every* support. + For more info see + + *every* executes the provided callback function once for each element present in the array until it finds one where callback returns a false value. If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var areAllBigEnough = [10,4,25,100].every(function(item, index){ + > return item > 20; + >}); + >//areAllBigEnough = false + */ + + every: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++){ + if (!fn.call(bind, this[i], i, this)) return false; + } + return true; + }, + + /* + Property: some + This method is provided only for browsers without native *some* support. + For more info see + + *some* executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - the object to bind "this" to (see ) + + Example: + >var isAnyBigEnough = [10,4,25,100].some(function(item, index){ + > return item > 20; + >}); + >//isAnyBigEnough = true + */ + + some: function(fn, bind){ + for (var i = 0, j = this.length; i < j; i++){ + if (fn.call(bind, this[i], i, this)) return true; + } + return false; + }, + + /* + Property: indexOf + This method is provided only for browsers without native *indexOf* support. + For more info see + + *indexOf* compares a search element to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator). + + Arguments: + item - any type of object; element to locate in the array + from - integer; optional; the index of the array at which to begin the search (defaults to 0) + + Example: + >['apple','lemon','banana'].indexOf('lemon'); //returns 1 + >['apple','lemon'].indexOf('banana'); //returns -1 + */ + + indexOf: function(item, from){ + var len = this.length; + for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ + if (this[i] === item) return i; + } + return -1; + }, + + /* + Property: each + Same as . + + Arguments: + fn - function to execute with each item in the array; passed the item and the index of that item in the array + bind - optional, the object that the "this" of the function will refer to. + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.each(function(animal){ + > document.write(animal) + >}); + */ + + /* + Property: copy + returns a copy of the array. + + Returns: + a new array which is a copy of the current one. + + Arguments: + start - integer; optional; the index where to start the copy, default is 0. If negative, it is taken as the offset from the end of the array. + length - integer; optional; the number of elements to copy. By default, copies all elements from start to the end of the array. + + Example: + >var letters = ["a","b","c"]; + >var copy = letters.copy(); // ["a","b","c"] (new instance) + */ + + copy: function(start, length){ + start = start || 0; + if (start < 0) start = this.length + start; + length = length || (this.length - start); + var newArray = []; + for (var i = 0; i < length; i++) newArray[i] = this[start++]; + return newArray; + }, + + /* + Property: remove + Removes all occurrences of an item from the array. + + Arguments: + item - the item to remove + + Returns: + the Array with all occurrences of the item removed. + + Example: + >["1","2","3","2"].remove("2") // ["1","3"]; + */ + + remove: function(item){ + var i = 0; + var len = this.length; + while (i < len){ + if (this[i] === item){ + this.splice(i, 1); + len--; + } else { + i++; + } + } + return this; + }, + + /* + Property: contains + Tests an array for the presence of an item. + + Arguments: + item - the item to search for in the array. + from - integer; optional; the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array. + + Returns: + true - the item was found + false - it wasn't + + Example: + >["a","b","c"].contains("a"); // true + >["a","b","c"].contains("d"); // false + */ + + contains: function(item, from){ + return this.indexOf(item, from) != -1; + }, + + /* + Property: associate + Creates an object with key-value pairs based on the array of keywords passed in + and the current content of the array. + + Arguments: + keys - the array of keywords. + + Example: + (start code) + var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; + var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; + var Speeches = Animals.associate(Speech); + //Speeches['Miao'] is now Cat. + //Speeches['Bau'] is now Dog. + //... + (end) + */ + + associate: function(keys){ + var obj = {}, length = Math.min(this.length, keys.length); + for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; + return obj; + }, + + /* + Property: extend + Extends an array with another one. + + Arguments: + array - the array to extend ours with + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.extend(['Lizard']); + >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; + */ + + extend: function(array){ + for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); + return this; + }, + + /* + Property: merge + merges an array in another array, without duplicates. (case- and type-sensitive) + + Arguments: + array - the array to merge from. + + Example: + >['Cat','Dog'].merge(['Dog','Coala']); //returns ['Cat','Dog','Coala'] + */ + + merge: function(array){ + for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); + return this; + }, + + /* + Property: include + includes the passed in element in the array, only if its not already present. (case- and type-sensitive) + + Arguments: + item - item to add to the array (if not present) + + Example: + >['Cat','Dog'].include('Dog'); //returns ['Cat','Dog'] + >['Cat','Dog'].include('Coala'); //returns ['Cat','Dog','Coala'] + */ + + include: function(item){ + if (!this.contains(item)) this.push(item); + return this; + }, + + /* + Property: getRandom + returns a random item in the Array + */ + + getRandom: function(){ + return this[$random(0, this.length - 1)] || null; + }, + + /* + Property: getLast + returns the last item in the Array + */ + + getLast: function(){ + return this[this.length - 1] || null; + } + +}); + +//copies + +Array.prototype.each = Array.prototype.forEach; +Array.each = Array.forEach; + +/* Section: Utility Functions */ + +/* +Function: $A() + Same as , but as function. + Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. + +Example: + (start code) + function myFunction(){ + $A(arguments).each(argument, function(){ + alert(argument); + }); + }; + //the above will alert all the arguments passed to the function myFunction. + (end) +*/ + +function $A(array){ + return Array.copy(array); +}; + +/* +Function: $each + Use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, arguments of a function, or an object. + +Arguments: + iterable - an iterable element or an objct. + function - function to apply to the iterable. + bind - optional, the 'this' of the function will refer to this object. + +Function argument: + The function argument will be passed the following arguments. + + item - the current item in the iterator being procesed + index - integer; the index of the item, or key in case of an object. + +Examples: + (start code) + $each(['Sun','Mon','Tue'], function(day, index){ + alert('name:' + day + ', index: ' + index); + }); + //alerts "name: Sun, index: 0", "name: Mon, index: 1", etc. + //over an object + $each({first: "Sunday", second: "Monday", third: "Tuesday"}, function(value, key){ + alert("the " + key + " day of the week is " + value); + }); + //alerts "the first day of the week is Sunday", + //"the second day of the week is Monday", etc. + (end) +*/ + +function $each(iterable, fn, bind){ + if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object'){ + Array.forEach(iterable, fn, bind); + } else { + for (var name in iterable) fn.call(bind || iterable, iterable[name], name); + } +}; + +/*compatibility*/ + +Array.prototype.test = Array.prototype.contains; + +/*end compatibility*/ + +/* +Script: String.js + Contains String prototypes. + +License: + MIT-style license. +*/ + +/* +Class: String + A collection of The String Object prototype methods. +*/ + +String.extend({ + + /* + Property: test + Tests a string with a regular expression. + + Arguments: + regex - a string or regular expression object, the regular expression you want to match the string with + params - optional, if first parameter is a string, any parameters you want to pass to the regex ('g' has no effect) + + Returns: + true if a match for the regular expression is found in the string, false if not. + See + + Example: + >"I like cookies".test("cookie"); // returns true + >"I like cookies".test("COOKIE", "i") // ignore case, returns true + >"I like cookies".test("cake"); // returns false + */ + + test: function(regex, params){ + return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this); + }, + + /* + Property: toInt + parses a string to an integer. + + Returns: + either an int or "NaN" if the string is not a number. + + Example: + >var value = "10px".toInt(); // value is 10 + */ + + toInt: function(){ + return parseInt(this, 10); + }, + + /* + Property: toFloat + parses a string to an float. + + Returns: + either a float or "NaN" if the string is not a number. + + Example: + >var value = "10.848".toFloat(); // value is 10.848 + */ + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: camelCase + Converts a hiphenated string to a camelcase string. + + Example: + >"I-like-cookies".camelCase(); //"ILikeCookies" + + Returns: + the camel cased string + */ + + camelCase: function(){ + return this.replace(/-\D/g, function(match){ + return match.charAt(1).toUpperCase(); + }); + }, + + /* + Property: hyphenate + Converts a camelCased string to a hyphen-ated string. + + Example: + >"ILikeCookies".hyphenate(); //"I-like-cookies" + */ + + hyphenate: function(){ + return this.replace(/\w[A-Z]/g, function(match){ + return (match.charAt(0) + '-' + match.charAt(1).toLowerCase()); + }); + }, + + /* + Property: capitalize + Converts the first letter in each word of a string to Uppercase. + + Example: + >"i like cookies".capitalize(); //"I Like Cookies" + + Returns: + the capitalized string + */ + + capitalize: function(){ + return this.replace(/\b[a-z]/g, function(match){ + return match.toUpperCase(); + }); + }, + + /* + Property: trim + Trims the leading and trailing spaces off a string. + + Example: + >" i like cookies ".trim() //"i like cookies" + + Returns: + the trimmed string + */ + + trim: function(){ + return this.replace(/^\s+|\s+$/g, ''); + }, + + /* + Property: clean + trims () a string AND removes all the double spaces in a string. + + Returns: + the cleaned string + + Example: + >" i like cookies \n\n".clean() //"i like cookies" + */ + + clean: function(){ + return this.replace(/\s{2,}/g, ' ').trim(); + }, + + /* + Property: rgbToHex + Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255,255,255)" or "rgba(255,255,255,1)"; + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['FF','33','00'] as output instead of "#FF3300" + + Returns: + hex string or array. returns "transparent" if the output is set as string and the fourth value of rgba in input string is 0. + + Example: + >"rgb(17,34,51)".rgbToHex(); //"#112233" + >"rgba(17,34,51,0)".rgbToHex(); //"transparent" + >"rgb(17,34,51)".rgbToHex(true); //['11','22','33'] + */ + + rgbToHex: function(array){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? rgb.rgbToHex(array) : false; + }, + + /* + Property: hexToRgb + Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); + + Arguments: + array - boolean value, defaults to false. Use true if you want the array [255,255,255] as output instead of "rgb(255,255,255)"; + + Returns: + rgb string or array. + + Example: + >"#112233".hexToRgb(); //"rgb(17,34,51)" + >"#112233".hexToRgb(true); //[17,34,51] + */ + + hexToRgb: function(array){ + var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); + return (hex) ? hex.slice(1).hexToRgb(array) : false; + }, + + /* + Property: contains + checks if the passed in string is contained in the String. also accepts an optional second parameter, to check if the string is contained in a list of separated values. + + Example: + >'a b c'.contains('c', ' '); //true + >'a bc'.contains('bc'); //true + >'a bc'.contains('b', ' '); //false + */ + + contains: function(string, s){ + return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1; + }, + + /* + Property: escapeRegExp + Returns string with escaped regular expression characters + + Example: + >var search = 'animals.sheeps[1]'.escapeRegExp(); // search is now 'animals\.sheeps\[1\]' + + Returns: + Escaped string + */ + + escapeRegExp: function(){ + return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); + } + +}); + +Array.extend({ + + /* + Property: rgbToHex + see , but as an array method. + */ + + rgbToHex: function(array){ + if (this.length < 3) return false; + if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (this[i] - 0).toString(16); + hex.push((bit.length == 1) ? '0' + bit : bit); + } + return array ? hex : '#' + hex.join(''); + }, + + /* + Property: hexToRgb + same as , but as an array method. + */ + + hexToRgb: function(array){ + if (this.length != 3) return false; + var rgb = []; + for (var i = 0; i < 3; i++){ + rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16)); + } + return array ? rgb : 'rgb(' + rgb.join(',') + ')'; + } + +}); + +/* +Script: Function.js + Contains Function prototypes and utility functions . + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Function + A collection of The Function Object prototype methods. +*/ + +Function.extend({ + + /* + Property: create + Main function to create closures. + + Returns: + a function. + + Arguments: + options - An Options object. + + Options: + bind - The object that the "this" of the function will refer to. Default is the current function. + event - If set to true, the function will act as an event listener and receive an event as first argument. + If set to a class name, the function will receive a new instance of this class (with the event passed as argument's constructor) as first argument. + Default is false. + arguments - A single argument or array of arguments that will be passed to the function when called. + + If both the event and arguments options are set, the event is passed as first argument and the arguments array will follow. + + Default is no custom arguments, the function will receive the standard arguments when called. + + delay - Numeric value: if set, the returned function will delay the actual execution by this amount of milliseconds and return a timer handle when called. + Default is no delay. + periodical - Numeric value: if set, the returned function will periodically perform the actual execution with this specified interval and return a timer handle when called. + Default is no periodical execution. + attempt - If set to true, the returned function will try to execute and return either the results or false on error. Default is false. + */ + + create: function(options){ + var fn = this; + options = $merge({ + 'bind': fn, + 'event': false, + 'arguments': null, + 'delay': false, + 'periodical': false, + 'attempt': false + }, options); + if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments]; + return function(event){ + var args; + if (options.event){ + event = event || window.event; + args = [(options.event === true) ? event : new options.event(event)]; + if (options.arguments) args.extend(options.arguments); + } + else args = options.arguments || arguments; + var returns = function(){ + return fn.apply($pick(options.bind, fn), args); + }; + if (options.delay) return setTimeout(returns, options.delay); + if (options.periodical) return setInterval(returns, options.periodical); + if (options.attempt) try {return returns();} catch(err){return false;}; + return returns(); + }; + }, + + /* + Property: pass + Shortcut to create closures with arguments and bind. + + Returns: + a function. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.pass([arg1, arg2], myElement); + */ + + pass: function(args, bind){ + return this.create({'arguments': args, 'bind': bind}); + }, + + /* + Property: attempt + Tries to execute the function, returns either the result of the function or false on error. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.attempt([arg1, arg2], myElement); + */ + + attempt: function(args, bind){ + return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); + }, + + /* + Property: bind + method to easily create closures with "this" altered. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function. + + Example: + >function myFunction(){ + > this.setStyle('color', 'red'); + > // note that 'this' here refers to myFunction, not an element + > // we'll need to bind this function to the element we want to alter + >}; + >var myBoundFunction = myFunction.bind(myElement); + >myBoundFunction(); // this will make the element myElement red. + */ + + bind: function(bind, args){ + return this.create({'bind': bind, 'arguments': args}); + }, + + /* + Property: bindAsEventListener + cross browser method to pass event firer + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindAsEventListener(myElement); + */ + + bindAsEventListener: function(bind, args){ + return this.create({'bind': bind, 'event': true, 'arguments': args}); + }, + + /* + Property: delay + Delays the execution of a function by a specified duration. + + Arguments: + delay - the duration to wait in milliseconds. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Example: + >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it + >(function(){alert('one second later...')}).delay(1000); //wait a second and alert + */ + + delay: function(delay, bind, args){ + return this.create({'delay': delay, 'bind': bind, 'arguments': args})(); + }, + + /* + Property: periodical + Executes a function in the specified intervals of time + + Arguments: + interval - the duration of the intervals between executions. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + */ + + periodical: function(interval, bind, args){ + return this.create({'periodical': interval, 'bind': bind, 'arguments': args})(); + } + +}); + +/* +Script: Number.js + Contains the Number prototypes. + +License: + MIT-style license. +*/ + +/* +Class: Number + A collection of The Number Object prototype methods. +*/ + +Number.extend({ + + /* + Property: toInt + Returns this number; useful because toInt must work on both Strings and Numbers. + */ + + toInt: function(){ + return parseInt(this); + }, + + /* + Property: toFloat + Returns this number as a float; useful because toFloat must work on both Strings and Numbers. + */ + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: limit + Limits the number. + + Arguments: + min - number, minimum value + max - number, maximum value + + Returns: + the number in the given limits. + + Example: + >(12).limit(2, 6.5) // returns 6.5 + >(-4).limit(2, 6.5) // returns 2 + >(4.3).limit(2, 6.5) // returns 4.3 + */ + + limit: function(min, max){ + return Math.min(max, Math.max(min, this)); + }, + + /* + Property: round + Returns the number rounded to specified precision. + + Arguments: + precision - integer, number of digits after the decimal point. Can also be negative or zero (default). + + Example: + >12.45.round() // returns 12 + >12.45.round(1) // returns 12.5 + >12.45.round(-1) // returns 10 + + Returns: + The rounded number. + */ + + round: function(precision){ + precision = Math.pow(10, precision || 0); + return Math.round(this * precision) / precision; + }, + + /* + Property: times + Executes a passed in function the specified number of times + + Arguments: + function - the function to be executed on each iteration of the loop + + Example: + >(4).times(alert); + */ + + times: function(fn){ + for (var i = 0; i < this; i++) fn(i); + } + +}); + +/* +Script: Element.js + Contains useful Element prototypes, to be used with the dollar function <$>. + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +var Element = new Class({ + + /* + Property: initialize + Creates a new element of the type passed in. + + Arguments: + el - string; the tag name for the element you wish to create. you can also pass in an element reference, in which case it will be extended. + props - object; the properties you want to add to your element. + Accepts the same keys as , but also allows events and styles + + Props: + the key styles will be used as setStyles, the key events will be used as addEvents. any other key is used as setProperty. + + Example: + (start code) + new Element('a', { + 'styles': { + 'display': 'block', + 'border': '1px solid black' + }, + 'events': { + 'click': function(){ + //aaa + }, + 'mousedown': function(){ + //aaa + } + }, + 'class': 'myClassSuperClass', + 'href': 'http://mad4milk.net' + }); + + (end) + */ + + initialize: function(el, props){ + if ($type(el) == 'string'){ + if (window.ie && props && (props.name || props.type)){ + var name = (props.name) ? ' name="' + props.name + '"' : ''; + var type = (props.type) ? ' type="' + props.type + '"' : ''; + delete props.name; + delete props.type; + el = '<' + el + name + type + '>'; + } + el = $dce(el); + } + el = $(el); + return (!props || !el) ? el : el.set(props); + } + +}); + +/* +Class: Elements + - Every dom function such as <$$>, or in general every function that returns a collection of nodes in mootools, returns them as an Elements class. + - The purpose of the Elements class is to allow methods to work also on array. + - Elements is also an Array, so it accepts all the methods. + - Every node of the Elements instance is already extended with <$>. + +Example: + >$$('myselector').each(function(el){ + > //... + >}); + + some iterations here, $$('myselector') is also an array. + + >$$('myselector').setStyle('color', 'red'); + every element returned by $$('myselector') also accepts methods, in this example every element will be made red. +*/ + +var Elements = new Class({ + + initialize: function(elements){ + return (elements) ? $extend(elements, this) : this; + } + +}); + +Elements.extend = function(props){ + for (var prop in props){ + this.prototype[prop] = props[prop]; + this[prop] = $native.generic(prop); + } +}; + +/* +Section: Utility Functions + +Function: $ + returns the element passed in with all the Element prototypes applied. + +Arguments: + el - a reference to an actual element or a string representing the id of an element + +Example: + >$('myElement') // gets a DOM element by id with all the Element prototypes applied. + >var div = $('myElement'); + >$(div) //returns an Element also with all the mootools extentions applied. + + You'll use this when you aren't sure if a variable is an actual element or an id, as + well as just shorthand for $(). + +Returns: + a DOM element or false (if no id was found). + +Note: + you need to call $ on an element only once to get all the prototypes. + But its no harm to call it multiple times, as it will detect if it has been already extended. +*/ + +function $(el){ + if (!el) return null; + if (el.htmlElement) return Garbage.collect(el); + if ([window, document].contains(el)) return el; + var type = $type(el); + if (type == 'string'){ + el = $(el); + type = (el) ? 'element' : false; + } + if (type != 'element') return null; + if (el.htmlElement) return Garbage.collect(el); + if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el; + $extend(el, Element.prototype); + el.htmlElement = function(){}; + return Garbage.collect(el); +}; + +/* +Function: $$ + Selects, and extends DOM elements. Elements arrays returned with $$ will also accept all the methods. + The return type of element methods run through $$ is always an array. If the return array is only made by elements, + $$ will be applied automatically. + +Arguments: + HTML Collections, arrays of elements, arrays of strings as element ids, elements, strings as selectors. + Any number of the above as arguments are accepted. + +Note: + if you load , $$ will also accept CSS Selectors, otherwise the only selectors supported are tag names. + +Example: + >$$('a') //an array of all anchor tags on the page + >$$('a', 'b') //an array of all anchor and bold tags on the page + >$$('#myElement') //array containing only the element with id = myElement. (only with ) + >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" + >//within the DOM element with id "myElement" (only with ) + >$$(myelement, myelement2, 'a', ['myid', myid2, 'myid3'], document.getElementsByTagName('div')) //an array containing: + >// the element referenced as myelement if existing, + >// the element referenced as myelement2 if existing, + >// all the elements with a as tag in the page, + >// the element with id = myid if existing + >// the element with id = myid2 if existing + >// the element with id = myid3 if existing + >// all the elements with div as tag in the page + +Returns: + array - array of all the dom elements matched, extended with <$>. Returns as . +*/ + +document.getElementsBySelector = document.getElementsByTagName; + +function $$(){ + var elements = []; + for (var i = 0, j = arguments.length; i < j; i++){ + var selector = arguments[i]; + switch($type(selector)){ + case 'element': elements.push(selector); + case 'boolean': break; + case false: break; + case 'string': selector = document.getElementsBySelector(selector, true); + default: elements.extend(selector); + } + } + return $$.unique(elements); +}; + +$$.unique = function(array){ + var elements = []; + for (var i = 0, l = array.length; i < l; i++){ + if (array[i].$included) continue; + var element = $(array[i]); + if (element && !element.$included){ + element.$included = true; + elements.push(element); + } + } + for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null; + return new Elements(elements); +}; + +Elements.Multi = function(property){ + return function(){ + var args = arguments; + var items = []; + var elements = true; + for (var i = 0, j = this.length, returns; i < j; i++){ + returns = this[i][property].apply(this[i], args); + if ($type(returns) != 'element') elements = false; + items.push(returns); + }; + return (elements) ? $$.unique(items) : items; + }; +}; + +Element.extend = function(properties){ + for (var property in properties){ + HTMLElement.prototype[property] = properties[property]; + Element.prototype[property] = properties[property]; + Element[property] = $native.generic(property); + var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property; + Elements.prototype[elementsProperty] = Elements.Multi(property); + } +}; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: set + you can set events, styles and properties with this shortcut. same as calling new Element. + */ + + set: function(props){ + for (var prop in props){ + var val = props[prop]; + switch(prop){ + case 'styles': this.setStyles(val); break; + case 'events': if (this.addEvents) this.addEvents(val); break; + case 'properties': this.setProperties(val); break; + default: this.setProperty(prop, val); + } + } + return this; + }, + + inject: function(el, where){ + el = $(el); + switch(where){ + case 'before': el.parentNode.insertBefore(this, el); break; + case 'after': + var next = el.getNext(); + if (!next) el.parentNode.appendChild(this); + else el.parentNode.insertBefore(this, next); + break; + case 'top': + var first = el.firstChild; + if (first){ + el.insertBefore(this, first); + break; + } + default: el.appendChild(this); + } + return this; + }, + + /* + Property: injectBefore + Inserts the Element before the passed element. + + Arguments: + el - an element reference or the id of the element to be injected in. + + Example: + >html: + >
    + >
    + >js: + >$('mySecondElement').injectBefore('myElement'); + >resulting html: + >
    + >
    + */ + + injectBefore: function(el){ + return this.inject(el, 'before'); + }, + + /* + Property: injectAfter + Same as , but inserts the element after. + */ + + injectAfter: function(el){ + return this.inject(el, 'after'); + }, + + /* + Property: injectInside + Same as , but inserts the element inside. + */ + + injectInside: function(el){ + return this.inject(el, 'bottom'); + }, + + /* + Property: injectTop + Same as , but inserts the element inside, at the top. + */ + + injectTop: function(el){ + return this.inject(el, 'top'); + }, + + /* + Property: adopt + Inserts the passed elements inside the Element. + + Arguments: + accepts elements references, element ids as string, selectors ($$('stuff')) / array of elements, array of ids as strings and collections. + */ + + adopt: function(){ + var elements = []; + $each(arguments, function(argument){ + elements = elements.concat(argument); + }); + $$(elements).inject(this); + return this; + }, + + /* + Property: remove + Removes the Element from the DOM. + + Example: + >$('myElement').remove() //bye bye + */ + + remove: function(){ + return this.parentNode.removeChild(this); + }, + + /* + Property: clone + Clones the Element and returns the cloned one. + + Arguments: + contents - boolean, when true the Element is cloned with childNodes, default true + + Returns: + the cloned element + + Example: + >var clone = $('myElement').clone().injectAfter('myElement'); + >//clones the Element and append the clone after the Element. + */ + + clone: function(contents){ + var el = $(this.cloneNode(contents !== false)); + if (!el.$events) return el; + el.$events = {}; + for (var type in this.$events) el.$events[type] = { + 'keys': $A(this.$events[type].keys), + 'values': $A(this.$events[type].values) + }; + return el.removeEvents(); + }, + + /* + Property: replaceWith + Replaces the Element with an element passed. + + Arguments: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Returns: + the passed in element + + Example: + >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. + */ + + replaceWith: function(el){ + el = $(el); + this.parentNode.replaceChild(el, this); + return el; + }, + + /* + Property: appendText + Appends text node to a DOM element. + + Arguments: + text - the text to append. + + Example: + >
    hey
    + >$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" + */ + + appendText: function(text){ + this.appendChild(document.createTextNode(text)); + return this; + }, + + /* + Property: hasClass + Tests the Element to see if it has the passed in className. + + Returns: + true - the Element has the class + false - it doesn't + + Arguments: + className - string; the class name to test. + + Example: + >
    + >$('myElement').hasClass('testClass'); //returns true + */ + + hasClass: function(className){ + return this.className.contains(className, ' '); + }, + + /* + Property: addClass + Adds the passed in class to the Element, if the element doesnt already have it. + + Arguments: + className - string; the class name to add + + Example: + >
    + >$('myElement').addClass('newClass'); //
    + */ + + addClass: function(className){ + if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); + return this; + }, + + /* + Property: removeClass + Works like , but removes the class from the element. + */ + + removeClass: function(className){ + this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean(); + return this; + }, + + /* + Property: toggleClass + Adds or removes the passed in class name to the element, depending on if it's present or not. + + Arguments: + className - the class to add or remove + + Example: + >
    + >$('myElement').toggleClass('myClass'); + >
    + >$('myElement').toggleClass('myClass'); + >
    + */ + + toggleClass: function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + /* + Property: setStyle + Sets a css property to the Element. + + Arguments: + property - the property to set + value - the value to which to set it; for numeric values that require "px" you can pass an integer + + Example: + >$('myElement').setStyle('width', '300px'); //the width is now 300px + >$('myElement').setStyle('width', 300); //the width is now 300px + */ + + setStyle: function(property, value){ + switch(property){ + case 'opacity': return this.setOpacity(parseFloat(value)); + case 'float': property = (window.ie) ? 'styleFloat' : 'cssFloat'; + } + property = property.camelCase(); + switch($type(value)){ + case 'number': if (!['zIndex', 'zoom'].contains(property)) value += 'px'; break; + case 'array': value = 'rgb(' + value.join(',') + ')'; + } + this.style[property] = value; + return this; + }, + + /* + Property: setStyles + Applies a collection of styles to the Element. + + Arguments: + source - an object or string containing all the styles to apply. When its a string it overrides old style. + + Examples: + >$('myElement').setStyles({ + > border: '1px solid #000', + > width: 300, + > height: 400 + >}); + + OR + + >$('myElement').setStyles('border: 1px solid #000; width: 300px; height: 400px;'); + */ + + setStyles: function(source){ + switch($type(source)){ + case 'object': Element.setMany(this, 'setStyle', source); break; + case 'string': this.style.cssText = source; + } + return this; + }, + + /* + Property: setOpacity + Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity > 0. + + Arguments: + opacity - float; Accepts values from 0 to 1. + + Example: + >$('myElement').setOpacity(0.5) //make it 50% transparent + */ + + setOpacity: function(opacity){ + if (opacity == 0){ + if (this.style.visibility != "hidden") this.style.visibility = "hidden"; + } else { + if (this.style.visibility != "visible") this.style.visibility = "visible"; + } + if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; + if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")"; + this.style.opacity = this.$tmp.opacity = opacity; + return this; + }, + + /* + Property: getStyle + Returns the style of the Element given the property passed in. + + Arguments: + property - the css style property you want to retrieve + + Example: + >$('myElement').getStyle('width'); //returns "400px" + >//but you can also use + >$('myElement').getStyle('width').toInt(); //returns 400 + + Returns: + the style as a string + */ + + getStyle: function(property){ + property = property.camelCase(); + var result = this.style[property]; + if (!$chk(result)){ + if (property == 'opacity') return this.$tmp.opacity; + result = []; + for (var style in Element.Styles){ + if (property == style){ + Element.Styles[style].each(function(s){ + var style = this.getStyle(s); + result.push(parseInt(style) ? style : '0px'); + }, this); + if (property == 'border'){ + var every = result.every(function(bit){ + return (bit == result[0]); + }); + return (every) ? result[0] : false; + } + return result.join(' '); + } + } + if (property.contains('border')){ + if (Element.Styles.border.contains(property)){ + return ['Width', 'Style', 'Color'].map(function(p){ + return this.getStyle(property + p); + }, this).join(' '); + } else if (Element.borderShort.contains(property)){ + return ['Top', 'Right', 'Bottom', 'Left'].map(function(p){ + return this.getStyle('border' + p + property.replace('border', '')); + }, this).join(' '); + } + } + if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); + else if (this.currentStyle) result = this.currentStyle[property]; + } + if (window.ie) result = Element.fixStyle(property, result, this); + if (result && property.test(/color/i) && result.contains('rgb')){ + return result.split('rgb').splice(1,4).map(function(color){ + return color.rgbToHex(); + }).join(' '); + } + return result; + }, + + /* + Property: getStyles + Returns an object of styles of the Element for each argument passed in. + Arguments: + properties - strings; any number of style properties + Example: + >$('myElement').getStyles('width','height','padding'); + >//returns an object like: + >{width: "10px", height: "10px", padding: "10px 0px 10px 0px"} + */ + + getStyles: function(){ + return Element.getMany(this, 'getStyle', arguments); + }, + + walk: function(brother, start){ + brother += 'Sibling'; + var el = (start) ? this[start] : this[brother]; + while (el && $type(el) != 'element') el = el[brother]; + return $(el); + }, + + /* + Property: getPrevious + Returns the previousSibling of the Element, excluding text nodes. + + Example: + >$('myElement').getPrevious(); //get the previous DOM element from myElement + + Returns: + the sibling element or undefined if none found. + */ + + getPrevious: function(){ + return this.walk('previous'); + }, + + /* + Property: getNext + Works as Element.getPrevious, but tries to find the nextSibling. + */ + + getNext: function(){ + return this.walk('next'); + }, + + /* + Property: getFirst + Works as , but tries to find the firstChild. + */ + + getFirst: function(){ + return this.walk('next', 'firstChild'); + }, + + /* + Property: getLast + Works as , but tries to find the lastChild. + */ + + getLast: function(){ + return this.walk('previous', 'lastChild'); + }, + + /* + Property: getParent + returns the $(element.parentNode) + */ + + getParent: function(){ + return $(this.parentNode); + }, + + /* + Property: getChildren + returns all the $(element.childNodes), excluding text nodes. Returns as . + */ + + getChildren: function(){ + return $$(this.childNodes); + }, + + /* + Property: hasChild + returns true if the passed in element is a child of the $(element). + */ + + hasChild: function(el){ + return !!$A(this.getElementsByTagName('*')).contains(el); + }, + + /* + Property: getProperty + Gets the an attribute of the Element. + + Arguments: + property - string; the attribute to retrieve + + Example: + >$('myImage').getProperty('src') // returns whatever.gif + + Returns: + the value, or an empty string + */ + + getProperty: function(property){ + var index = Element.Properties[property]; + if (index) return this[index]; + var flag = Element.PropertiesIFlag[property] || 0; + if (!window.ie || flag) return this.getAttribute(property, flag); + var node = this.attributes[property]; + return (node) ? node.nodeValue : null; + }, + + /* + Property: removeProperty + Removes an attribute from the Element + + Arguments: + property - string; the attribute to remove + */ + + removeProperty: function(property){ + var index = Element.Properties[property]; + if (index) this[index] = ''; + else this.removeAttribute(property); + return this; + }, + + /* + Property: getProperties + same as , but for properties + */ + + getProperties: function(){ + return Element.getMany(this, 'getProperty', arguments); + }, + + /* + Property: setProperty + Sets an attribute for the Element. + + Arguments: + property - string; the property to assign the value passed in + value - the value to assign to the property passed in + + Example: + >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source + */ + + setProperty: function(property, value){ + var index = Element.Properties[property]; + if (index) this[index] = value; + else this.setAttribute(property, value); + return this; + }, + + /* + Property: setProperties + Sets numerous attributes for the Element. + + Arguments: + source - an object with key/value pairs. + + Example: + (start code) + $('myElement').setProperties({ + src: 'whatever.gif', + alt: 'whatever dude' + }); + whatever dude + (end) + */ + + setProperties: function(source){ + return Element.setMany(this, 'setProperty', source); + }, + + /* + Property: setHTML + Sets the innerHTML of the Element. + + Arguments: + html - string; the new innerHTML for the element. + + Example: + >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML + */ + + setHTML: function(){ + this.innerHTML = $A(arguments).join(''); + return this; + }, + + /* + Property: setText + Sets the inner text of the Element. + + Arguments: + text - string; the new text content for the element. + + Example: + >$('myElement').setText('some text') //the text of myElement is now = 'some text' + */ + + setText: function(text){ + var tag = this.getTag(); + if (['style', 'script'].contains(tag)){ + if (window.ie){ + if (tag == 'style') this.styleSheet.cssText = text; + else if (tag == 'script') this.setProperty('text', text); + return this; + } else { + this.removeChild(this.firstChild); + return this.appendText(text); + } + } + this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text; + return this; + }, + + /* + Property: getText + Gets the inner text of the Element. + */ + + getText: function(){ + var tag = this.getTag(); + if (['style', 'script'].contains(tag)){ + if (window.ie){ + if (tag == 'style') return this.styleSheet.cssText; + else if (tag == 'script') return this.getProperty('text'); + } else { + return this.innerHTML; + } + } + return ($pick(this.innerText, this.textContent)); + }, + + /* + Property: getTag + Returns the tagName of the element in lower case. + + Example: + >$('myImage').getTag() // returns 'img' + + Returns: + The tag name in lower case + */ + + getTag: function(){ + return this.tagName.toLowerCase(); + }, + + /* + Property: empty + Empties an element of all its children. + + Example: + >$('myDiv').empty() // empties the Div and returns it + + Returns: + The element. + */ + + empty: function(){ + Garbage.trash(this.getElementsByTagName('*')); + return this.setHTML(''); + } + +}); + +Element.fixStyle = function(property, result, element){ + if ($chk(parseInt(result))) return result; + if (['height', 'width'].contains(property)){ + var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom']; + var size = 0; + values.each(function(value){ + size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt(); + }); + return element['offset' + property.capitalize()] - size + 'px'; + } else if (property.test(/border(.+)Width|margin|padding/)){ + return '0px'; + } + return result; +}; + +Element.Styles = {'border': [], 'padding': [], 'margin': []}; +['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ + for (var style in Element.Styles) Element.Styles[style].push(style + direction); +}); + +Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor']; + +Element.getMany = function(el, method, keys){ + var result = {}; + $each(keys, function(key){ + result[key] = el[method](key); + }); + return result; +}; + +Element.setMany = function(el, method, pairs){ + for (var key in pairs) el[method](key, pairs[key]); + return el; +}; + +Element.Properties = new Abstract({ + 'class': 'className', 'for': 'htmlFor', 'colspan': 'colSpan', 'rowspan': 'rowSpan', + 'accesskey': 'accessKey', 'tabindex': 'tabIndex', 'maxlength': 'maxLength', + 'readonly': 'readOnly', 'frameborder': 'frameBorder', 'value': 'value', + 'disabled': 'disabled', 'checked': 'checked', 'multiple': 'multiple', 'selected': 'selected' +}); +Element.PropertiesIFlag = { + 'href': 2, 'src': 2 +}; + +Element.Methods = { + Listeners: { + addListener: function(type, fn){ + if (this.addEventListener) this.addEventListener(type, fn, false); + else this.attachEvent('on' + type, fn); + return this; + }, + + removeListener: function(type, fn){ + if (this.removeEventListener) this.removeEventListener(type, fn, false); + else this.detachEvent('on' + type, fn); + return this; + } + } +}; + +window.extend(Element.Methods.Listeners); +document.extend(Element.Methods.Listeners); +Element.extend(Element.Methods.Listeners); + +var Garbage = { + + elements: [], + + collect: function(el){ + if (!el.$tmp){ + Garbage.elements.push(el); + el.$tmp = {'opacity': 1}; + } + return el; + }, + + trash: function(elements){ + for (var i = 0, j = elements.length, el; i < j; i++){ + if (!(el = elements[i]) || !el.$tmp) continue; + if (el.$events) el.fireEvent('trash').removeEvents(); + for (var p in el.$tmp) el.$tmp[p] = null; + for (var d in Element.prototype) el[d] = null; + Garbage.elements[Garbage.elements.indexOf(el)] = null; + el.htmlElement = el.$tmp = el = null; + } + Garbage.elements.remove(null); + }, + + empty: function(){ + Garbage.collect(window); + Garbage.collect(document); + Garbage.trash(Garbage.elements); + } + +}; + +window.addListener('beforeunload', function(){ + window.addListener('unload', Garbage.empty); + if (window.ie) window.addListener('unload', CollectGarbage); +}); + +/* +Script: Element.Event.js + Contains the Event Class, Element methods to deal with Element events, custom Events, and the Function prototype bindWithEvent. + +License: + MIT-style license. +*/ + +/* +Class: Event + Cross browser methods to manage events. + +Arguments: + event - the event + +Properties: + shift - true if the user pressed the shift + control - true if the user pressed the control + alt - true if the user pressed the alt + meta - true if the user pressed the meta key + wheel - the amount of third button scrolling + code - the keycode of the key pressed + page.x - the x position of the mouse, relative to the full window + page.y - the y position of the mouse, relative to the full window + client.x - the x position of the mouse, relative to the viewport + client.y - the y position of the mouse, relative to the viewport + key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys. + target - the event target + relatedTarget - the event related target + +Example: + (start code) + $('myLink').onkeydown = function(event){ + var event = new Event(event); + //event is now the Event class. + alert(event.key); //returns the lowercase letter pressed + alert(event.shift); //returns true if the key pressed is shift + if (event.key == 's' && event.control) alert('document saved'); + }; + (end) +*/ + +var Event = new Class({ + + initialize: function(event){ + if (event && event.$extended) return event; + this.$extended = true; + event = event || window.event; + this.event = event; + this.type = event.type; + this.target = event.target || event.srcElement; + if (this.target.nodeType == 3) this.target = this.target.parentNode; + this.shift = event.shiftKey; + this.control = event.ctrlKey; + this.alt = event.altKey; + this.meta = event.metaKey; + if (['DOMMouseScroll', 'mousewheel'].contains(this.type)){ + this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; + } else if (this.type.contains('key')){ + this.code = event.which || event.keyCode; + for (var name in Event.keys){ + if (Event.keys[name] == this.code){ + this.key = name; + break; + } + } + if (this.type == 'keydown'){ + var fKey = this.code - 111; + if (fKey > 0 && fKey < 13) this.key = 'f' + fKey; + } + this.key = this.key || String.fromCharCode(this.code).toLowerCase(); + } else if (this.type.test(/(click|mouse|menu)/)){ + this.page = { + 'x': event.pageX || event.clientX + document.documentElement.scrollLeft, + 'y': event.pageY || event.clientY + document.documentElement.scrollTop + }; + this.client = { + 'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX, + 'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY + }; + this.rightClick = (event.which == 3) || (event.button == 2); + switch(this.type){ + case 'mouseover': this.relatedTarget = event.relatedTarget || event.fromElement; break; + case 'mouseout': this.relatedTarget = event.relatedTarget || event.toElement; + } + this.fixRelatedTarget(); + } + return this; + }, + + /* + Property: stop + cross browser method to stop an event + */ + + stop: function(){ + return this.stopPropagation().preventDefault(); + }, + + /* + Property: stopPropagation + cross browser method to stop the propagation of an event + */ + + stopPropagation: function(){ + if (this.event.stopPropagation) this.event.stopPropagation(); + else this.event.cancelBubble = true; + return this; + }, + + /* + Property: preventDefault + cross browser method to prevent the default action of the event + */ + + preventDefault: function(){ + if (this.event.preventDefault) this.event.preventDefault(); + else this.event.returnValue = false; + return this; + } + +}); + +Event.fix = { + + relatedTarget: function(){ + if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode; + }, + + relatedTargetGecko: function(){ + try {Event.fix.relatedTarget.call(this);} catch(e){this.relatedTarget = this.target;} + } + +}; + +Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget; + +/* +Property: keys + you can add additional Event keys codes this way: + +Example: + (start code) + Event.keys.whatever = 80; + $(myelement).addEvent(keydown, function(event){ + event = new Event(event); + if (event.key == 'whatever') console.log(whatever key clicked). + }); + (end) +*/ + +Event.keys = new Abstract({ + 'enter': 13, + 'up': 38, + 'down': 40, + 'left': 37, + 'right': 39, + 'esc': 27, + 'space': 32, + 'backspace': 8, + 'tab': 9, + 'delete': 46 +}); + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.Methods.Events = { + + /* + Property: addEvent + Attaches an event listener to a DOM element. + + Arguments: + type - the event to monitor ('click', 'load', etc) without the prefix 'on'. + fn - the function to execute + + Example: + >$('myElement').addEvent('click', function(){alert('clicked!')}); + */ + + addEvent: function(type, fn){ + this.$events = this.$events || {}; + this.$events[type] = this.$events[type] || {'keys': [], 'values': []}; + if (this.$events[type].keys.contains(fn)) return this; + this.$events[type].keys.push(fn); + var realType = type; + var custom = Element.Events[type]; + if (custom){ + if (custom.add) custom.add.call(this, fn); + if (custom.map) fn = custom.map; + if (custom.type) realType = custom.type; + } + if (!this.addEventListener) fn = fn.create({'bind': this, 'event': true}); + this.$events[type].values.push(fn); + return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this; + }, + + /* + Property: removeEvent + Works as Element.addEvent, but instead removes the previously added event listener. + */ + + removeEvent: function(type, fn){ + if (!this.$events || !this.$events[type]) return this; + var pos = this.$events[type].keys.indexOf(fn); + if (pos == -1) return this; + var key = this.$events[type].keys.splice(pos,1)[0]; + var value = this.$events[type].values.splice(pos,1)[0]; + var custom = Element.Events[type]; + if (custom){ + if (custom.remove) custom.remove.call(this, fn); + if (custom.type) type = custom.type; + } + return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this; + }, + + /* + Property: addEvents + As , but accepts an object and add multiple events at once. + */ + + addEvents: function(source){ + return Element.setMany(this, 'addEvent', source); + }, + + /* + Property: removeEvents + removes all events of a certain type from an element. if no argument is passed in, removes all events. + + Arguments: + type - string; the event name (e.g. 'click') + */ + + removeEvents: function(type){ + if (!this.$events) return this; + if (!type){ + for (var evType in this.$events) this.removeEvents(evType); + this.$events = null; + } else if (this.$events[type]){ + this.$events[type].keys.each(function(fn){ + this.removeEvent(type, fn); + }, this); + this.$events[type] = null; + } + return this; + }, + + /* + Property: fireEvent + executes all events of the specified type present in the element. + + Arguments: + type - string; the event name (e.g. 'click') + args - array or single object; arguments to pass to the function; if more than one argument, must be an array + delay - (integer) delay (in ms) to wait to execute the event + */ + + fireEvent: function(type, args, delay){ + if (this.$events && this.$events[type]){ + this.$events[type].keys.each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + } + return this; + }, + + /* + Property: cloneEvents + Clones all events from an element to this element. + + Arguments: + from - element, copy all events from this element + type - optional, copies only events of this type + */ + + cloneEvents: function(from, type){ + if (!from.$events) return this; + if (!type){ + for (var evType in from.$events) this.cloneEvents(from, evType); + } else if (from.$events[type]){ + from.$events[type].keys.each(function(fn){ + this.addEvent(type, fn); + }, this); + } + return this; + } + +}; + +window.extend(Element.Methods.Events); +document.extend(Element.Methods.Events); +Element.extend(Element.Methods.Events); + +/* Section: Custom Events */ + +Element.Events = new Abstract({ + + /* + Event: mouseenter + In addition to the standard javascript events (load, mouseover, mouseout, click, etc.) contains two custom events + this event fires when the mouse enters the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseover) + + + Example: + >$(myElement).addEvent('mouseenter', myFunction); + */ + + 'mouseenter': { + type: 'mouseover', + map: function(event){ + event = new Event(event); + if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event); + } + }, + + /* + Event: mouseleave + this event fires when the mouse exits the area of the dom element; will not be fired again if the mouse crosses over children of the element (unlike mouseout) + + + Example: + >$(myElement).addEvent('mouseleave', myFunction); + */ + + 'mouseleave': { + type: 'mouseout', + map: function(event){ + event = new Event(event); + if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event); + } + }, + + 'mousewheel': { + type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel' + } + +}); + +Element.NativeEvents = [ + 'click', 'dblclick', 'mouseup', 'mousedown', //mouse buttons + 'mousewheel', 'DOMMouseScroll', //mouse wheel + 'mouseover', 'mouseout', 'mousemove', //mouse movement + 'keydown', 'keypress', 'keyup', //keys + 'load', 'unload', 'beforeunload', 'resize', 'move', //window + 'focus', 'blur', 'change', 'submit', 'reset', 'select', //forms elements + 'error', 'abort', 'contextmenu', 'scroll' //misc +]; + +/* +Class: Function + A collection of The Function Object prototype methods. +*/ + +Function.extend({ + + /* + Property: bindWithEvent + automatically passes MooTools Event Class. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, an argument to pass to the function; if more than one argument, it must be an array of arguments. + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.client.x) //returns the coordinates of the mouse.. + >}; + >myElement.addEvent('click', myFunction.bindWithEvent(myElement)); + */ + + bindWithEvent: function(bind, args){ + return this.create({'bind': bind, 'arguments': args, 'event': Event}); + } + +}); + + +/* +Script: Element.Filters.js + add Filters capability to . + +License: + MIT-style license. +*/ + +/* +Class: Elements + A collection of methods to be used with <$$> elements collections. +*/ + +Elements.extend({ + + /* + Property: filterByTag + Filters the collection by a specified tag name. + Returns a new Elements collection, while the original remains untouched. + */ + + filterByTag: function(tag){ + return new Elements(this.filter(function(el){ + return (Element.getTag(el) == tag); + })); + }, + + /* + Property: filterByClass + Filters the collection by a specified class name. + Returns a new Elements collection, while the original remains untouched. + */ + + filterByClass: function(className, nocash){ + var elements = this.filter(function(el){ + return (el.className && el.className.contains(className, ' ')); + }); + return (nocash) ? elements : new Elements(elements); + }, + + /* + Property: filterById + Filters the collection by a specified ID. + Returns a new Elements collection, while the original remains untouched. + */ + + filterById: function(id, nocash){ + var elements = this.filter(function(el){ + return (el.id == id); + }); + return (nocash) ? elements : new Elements(elements); + }, + + /* + Property: filterByAttribute + Filters the collection by a specified attribute. + Returns a new Elements collection, while the original remains untouched. + + Arguments: + name - the attribute name. + operator - optional, the attribute operator. + value - optional, the attribute value, only valid if the operator is specified. + */ + + filterByAttribute: function(name, operator, value, nocash){ + var elements = this.filter(function(el){ + var current = Element.getProperty(el, name); + if (!current) return false; + if (!operator) return true; + switch(operator){ + case '=': return (current == value); + case '*=': return (current.contains(value)); + case '^=': return (current.substr(0, value.length) == value); + case '$=': return (current.substr(current.length - value.length) == value); + case '!=': return (current != value); + case '~=': return current.contains(value, ' '); + } + return false; + }); + return (nocash) ? elements : new Elements(elements); + } + +}); + +/* +Script: Element.Selectors.js + Css Query related functions and extensions + +License: + MIT-style license. +*/ + +/* Section: Utility Functions */ + +/* +Function: $E + Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. + Returns as . + +Arguments: + selector - string; the css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Example: + >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' + +Returns: + a DOM element - the first element that matches the selector +*/ + +function $E(selector, filter){ + return ($(filter) || document).getElement(selector); +}; + +/* +Function: $ES + Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. + See Also: for an alternate syntax. + Returns as . + +Returns: + an array of dom elements that match the selector within the filter + +Arguments: + selector - string; css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Examples: + >$ES("a") //gets all the anchor tags; synonymous with $$("a") + >$ES('a','myElement') //get all the anchor tags within $('myElement') +*/ + +function $ES(selector, filter){ + return ($(filter) || document).getElementsBySelector(selector); +}; + +$$.shared = { + + 'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/, + + 'xpath': { + + getParam: function(items, context, param, i){ + var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]]; + if (param[2]) temp.push('[@id="', param[2], '"]'); + if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]'); + if (param[4]){ + if (param[5] && param[6]){ + switch(param[5]){ + case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break; + case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break; + case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break; + case '=': temp.push('[@', param[4], '="', param[6], '"]'); break; + case '!=': temp.push('[@', param[4], '!="', param[6], '"]'); + } + } else { + temp.push('[@', param[4], ']'); + } + } + items.push(temp.join('')); + return items; + }, + + getItems: function(items, context, nocash){ + var elements = []; + var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i)); + return (nocash) ? elements : new Elements(elements.map($)); + } + + }, + + 'normal': { + + getParam: function(items, context, param, i){ + if (i == 0){ + if (param[2]){ + var el = context.getElementById(param[2]); + if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false; + items = [el]; + } else { + items = $A(context.getElementsByTagName(param[1])); + } + } else { + items = $$.shared.getElementsByTagName(items, param[1]); + if (param[2]) items = Elements.filterById(items, param[2], true); + } + if (param[3]) items = Elements.filterByClass(items, param[3], true); + if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true); + return items; + }, + + getItems: function(items, context, nocash){ + return (nocash) ? items : $$.unique(items); + } + + }, + + resolver: function(prefix){ + return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false; + }, + + getElementsByTagName: function(context, tagName){ + var found = []; + for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName)); + return found; + } + +}; + +$$.shared.method = (window.xpath) ? 'xpath' : 'normal'; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.Methods.Dom = { + + /* + Property: getElements + Gets all the elements within an element that match the given (single) selector. + Returns as . + + Arguments: + selector - string; the css selector to match + + Examples: + >$('myElement').getElements('a'); // get all anchors within myElement + >$('myElement').getElements('input[name=dialog]') //get all input tags with name 'dialog' + >$('myElement').getElements('input[name$=log]') //get all input tags with names ending with 'log' + + Notes: + Supports these operators in attribute selectors: + + - = : is equal to + - ^= : starts-with + - $= : ends-with + - != : is not equal to + + Xpath is used automatically for compliant browsers. + */ + + getElements: function(selector, nocash){ + var items = []; + selector = selector.trim().split(' '); + for (var i = 0, j = selector.length; i < j; i++){ + var sel = selector[i]; + var param = sel.match($$.shared.regexp); + if (!param) break; + param[1] = param[1] || '*'; + var temp = $$.shared[$$.shared.method].getParam(items, this, param, i); + if (!temp) break; + items = temp; + } + return $$.shared[$$.shared.method].getItems(items, this, nocash); + }, + + /* + Property: getElement + Same as , but returns only the first. Alternate syntax for <$E>, where filter is the Element. + Returns as . + + Arguments: + selector - string; css selector + */ + + getElement: function(selector){ + return $(this.getElements(selector, true)[0] || false); + }, + + /* + Property: getElementsBySelector + Same as , but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. + Returns as . + + Arguments: + selector - string; css selector + */ + + getElementsBySelector: function(selector, nocash){ + var elements = []; + selector = selector.split(','); + for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true)); + return (nocash) ? elements : $$.unique(elements); + } + +}; + +Element.extend({ + + /* + Property: getElementById + Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. + + Arguments: + id - string; the id of the element to find. + */ + + getElementById: function(id){ + var el = $(id); + if (!el) return false; + for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ + if (!parent) return false; + } + return el; + }/*compatibility*/, + + getElementsByClassName: function(className){ + return this.getElements('.' + className); + } + + /*end compatibility*/ + +}); + +document.extend(Element.Methods.Dom); +Element.extend(Element.Methods.Dom); + +/* +Script: Element.Form.js + Contains Element prototypes to deal with Forms and their elements. + +License: + MIT-style license. +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: getValue + Returns the value of the Element, if its tag is textarea, select or input. getValue called on a multiple select will return an array. + */ + + getValue: function(){ + switch(this.getTag()){ + case 'select': + var values = []; + $each(this.options, function(option){ + if (option.selected) values.push($pick(option.value, option.text)); + }); + return (this.multiple) ? values : values[0]; + case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break; + case 'textarea': return this.value; + } + return false; + }, + + getFormElements: function(){ + return $$(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea')); + }, + + /* + Property: toQueryString + Reads the children inputs of the Element and generates a query string, based on their values. Used internally in + + Example: + (start code) +
    + + +
    + + + (end) + + Returns: + email=bob@bob.com&zipCode=90210 + */ + + toQueryString: function(){ + var queryString = []; + this.getFormElements().each(function(el){ + var name = el.name; + var value = el.getValue(); + if (value === false || !name || el.disabled) return; + var qs = function(val){ + queryString.push(name + '=' + encodeURIComponent(val)); + }; + if ($type(value) == 'array') value.each(qs); + else qs(value); + }); + return queryString.join('&'); + } + +}); + +/* +Script: Element.Dimensions.js + Contains Element prototypes to deal with Element size and position in space. + +Note: + The functions in this script require n XHTML doctype. + +License: + MIT-style license. +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: scrollTo + Scrolls the element to the specified coordinated (if the element has an overflow) + + Arguments: + x - the x coordinate + y - the y coordinate + + Example: + >$('myElement').scrollTo(0, 100) + */ + + scrollTo: function(x, y){ + this.scrollLeft = x; + this.scrollTop = y; + }, + + /* + Property: getSize + Return an Object representing the size/scroll values of the element. + + Example: + (start code) + $('myElement').getSize(); + (end) + + Returns: + (start code) + { + 'scroll': {'x': 100, 'y': 100}, + 'size': {'x': 200, 'y': 400}, + 'scrollSize': {'x': 300, 'y': 500} + } + (end) + */ + + getSize: function(){ + return { + 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, + 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, + 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} + }; + }, + + /* + Property: getPosition + Returns the real offsets of the element. + + Arguments: + overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars + + Example: + >$('element').getPosition(); + + Returns: + >{x: 100, y:500}; + */ + + getPosition: function(overflown){ + overflown = overflown || []; + var el = this, left = 0, top = 0; + do { + left += el.offsetLeft || 0; + top += el.offsetTop || 0; + el = el.offsetParent; + } while (el); + overflown.each(function(element){ + left -= element.scrollLeft || 0; + top -= element.scrollTop || 0; + }); + return {'x': left, 'y': top}; + }, + + /* + Property: getTop + Returns the distance from the top of the window to the Element. + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + */ + + getTop: function(overflown){ + return this.getPosition(overflown).y; + }, + + /* + Property: getLeft + Returns the distance from the left of the window to the Element. + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + */ + + getLeft: function(overflown){ + return this.getPosition(overflown).x; + }, + + /* + Property: getCoordinates + Returns an object with width, height, left, right, top, and bottom, representing the values of the Element + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + + Example: + (start code) + var myValues = $('myElement').getCoordinates(); + (end) + + Returns: + (start code) + { + width: 200, + height: 300, + left: 100, + top: 50, + right: 300, + bottom: 350 + } + (end) + */ + + getCoordinates: function(overflown){ + var position = this.getPosition(overflown); + var obj = { + 'width': this.offsetWidth, + 'height': this.offsetHeight, + 'left': position.x, + 'top': position.y + }; + obj.right = obj.left + obj.width; + obj.bottom = obj.top + obj.height; + return obj; + } + +}); + +/* +Script: Window.DomReady.js + Contains the custom event domready, for window. + +License: + MIT-style license. +*/ + +/* Section: Custom Events */ + +/* +Event: domready + executes a function when the dom tree is loaded, without waiting for images. Only works when called from window. + +Credits: + (c) Dean Edwards/Matthias Miller/John Resig, remastered for MooTools. + +Arguments: + fn - the function to execute when the DOM is ready + +Example: + > window.addEvent('domready', function(){ + > alert('the dom is ready'); + > }); +*/ + +Element.Events.domready = { + + add: function(fn){ + if (window.loaded){ + fn.call(this); + return; + } + var domReady = function(){ + if (window.loaded) return; + window.loaded = true; + window.timer = $clear(window.timer); + this.fireEvent('domready'); + }.bind(this); + if (document.readyState && window.webkit){ + window.timer = function(){ + if (['loaded','complete'].contains(document.readyState)) domReady(); + }.periodical(50); + } else if (document.readyState && window.ie){ + if (!$('ie_ready')){ + var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)'; + document.write(' + (end) + */ + + send: function(options){ + return new Ajax(this.getProperty('action'), $merge({data: this.toQueryString()}, options, {method: 'post'})).request(); + } + +}); + +/* +Script: Cookie.js + A cookie reader/creator + +Credits: + based on the functions by Peter-Paul Koch (http://quirksmode.org) +*/ + +/* +Class: Cookie + Class for creating, getting, and removing cookies. +*/ + +var Cookie = new Abstract({ + + options: { + domain: false, + path: false, + duration: false, + secure: false + }, + + /* + Property: set + Sets a cookie in the browser. + + Arguments: + key - the key (name) for the cookie + value - the value to set, cannot contain semicolons + options - an object representing the Cookie options. See Options below. Default values are stored in Cookie.options. + + Options: + domain - the domain the Cookie belongs to. If you want to share the cookie with pages located on a different domain, you have to set this value. Defaults to the current domain. + path - the path the Cookie belongs to. If you want to share the cookie with pages located in a different path, you have to set this value, for example to "/" to share the cookie with all pages on the domain. Defaults to the current path. + duration - the duration of the Cookie before it expires, in days. + If set to false or 0, the cookie will be a session cookie that expires when the browser is closed. This is default. + secure - Stored cookie information can be accessed only from a secure environment. + + Returns: + An object with the options, the key and the value. You can give it as first parameter to Cookie.remove. + + Example: + >Cookie.set('username', 'Harald'); // session cookie (duration is false), or ... + >Cookie.set('username', 'JackBauer', {duration: 1}); // save this for 1 day + + */ + + set: function(key, value, options){ + options = $merge(this.options, options); + value = encodeURIComponent(value); + if (options.domain) value += '; domain=' + options.domain; + if (options.path) value += '; path=' + options.path; + if (options.duration){ + var date = new Date(); + date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000); + value += '; expires=' + date.toGMTString(); + } + if (options.secure) value += '; secure'; + document.cookie = key + '=' + value; + return $extend(options, {'key': key, 'value': value}); + }, + + /* + Property: get + Gets the value of a cookie. + + Arguments: + key - the name of the cookie you wish to retrieve. + + Returns: + The cookie string value, or false if not found. + + Example: + >Cookie.get("username") //returns JackBauer + */ + + get: function(key){ + var value = document.cookie.match('(?:^|;)\\s*' + key.escapeRegExp() + '=([^;]*)'); + return value ? decodeURIComponent(value[1]) : false; + }, + + /* + Property: remove + Removes a cookie from the browser. + + Arguments: + cookie - the name of the cookie to remove or a previous cookie (for domains) + options - optional. you can also pass the domain and path here. Same as options in + + Examples: + >Cookie.remove('username') //bye-bye JackBauer, cya in 24 hours + > + >var myCookie = Cookie.set('username', 'Aaron', {domain: 'mootools.net'}); // Cookie.set returns an object with all values need to remove the cookie + >Cookie.remove(myCookie); + */ + + remove: function(cookie, options){ + if ($type(cookie) == 'object') this.set(cookie.key, '', $merge(cookie, {duration: -1})); + else this.set(cookie, '', $merge(options, {duration: -1})); + } + +}); + +/* +Script: Json.js + Simple Json parser and Stringyfier, See: + +License: + MIT-style license. +*/ + +/* +Class: Json + Simple Json parser and Stringyfier, See: +*/ + +var Json = { + + /* + Property: toString + Converts an object to a string, to be passed in server-side scripts as a parameter. Although its not normal usage for this class, this method can also be used to convert functions and arrays to strings. + + Arguments: + obj - the object to convert to string + + Returns: + A json string + + Example: + (start code) + Json.toString({apple: 'red', lemon: 'yellow'}); '{"apple":"red","lemon":"yellow"}' + (end) + */ + + toString: function(obj){ + switch($type(obj)){ + case 'string': + return '"' + obj.replace(/(["\\])/g, '\\$1') + '"'; + case 'array': + return '[' + obj.map(Json.toString).join(',') + ']'; + case 'object': + var string = []; + for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property])); + return '{' + string.join(',') + '}'; + case 'number': + if (isFinite(obj)) break; + case false: + return 'null'; + } + return String(obj); + }, + + /* + Property: evaluate + converts a json string to an javascript Object. + + Arguments: + str - the string to evaluate. if its not a string, it returns false. + secure - optionally, performs syntax check on json string. Defaults to false. + + Credits: + Json test regexp is by Douglas Crockford . + + Example: + >var myObject = Json.evaluate('{"apple":"red","lemon":"yellow"}'); + >//myObject will become {apple: 'red', lemon: 'yellow'} + */ + + evaluate: function(str, secure){ + return (($type(str) != 'string') || (secure && !str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/))) ? null : eval('(' + str + ')'); + } + +}; + +/* +Script: Json.Remote.js + Contains . + +License: + MIT-style license. +*/ + +/* +Class: Json.Remote + Wrapped XHR with automated sending and receiving of Javascript Objects in Json Format. + Inherits methods, properties, options and events from . + +Arguments: + url - the url you want to send your object to. + options - see options + +Example: + this code will send user information based on name/last name + (start code) + var jSonRequest = new Json.Remote("http://site.com/tellMeAge.php", {onComplete: function(person){ + alert(person.age); //is 25 years + alert(person.height); //is 170 cm + alert(person.weight); //is 120 kg + }}).send({'name': 'John', 'lastName': 'Doe'}); + (end) +*/ + +Json.Remote = XHR.extend({ + + initialize: function(url, options){ + this.url = url; + this.addEvent('onSuccess', this.onComplete); + this.parent(options); + this.setHeader('X-Request', 'JSON'); + }, + + send: function(obj){ + return this.parent(this.url, 'json=' + Json.toString(obj)); + }, + + onComplete: function(){ + this.fireEvent('onComplete', [Json.evaluate(this.response.text, this.options.secure)]); + } + +}); + +/* +Script: Assets.js + provides dynamic loading for images, css and javascript files. + +License: + MIT-style license. +*/ + +var Asset = new Abstract({ + + /* + Property: javascript + Injects a javascript file in the page. + + Arguments: + source - the path of the javascript file + properties - some additional attributes you might want to add to the script element + + Example: + > new Asset.javascript('/scripts/myScript.js', {id: 'myScript'}); + */ + + javascript: function(source, properties){ + properties = $merge({ + 'onload': Class.empty + }, properties); + var script = new Element('script', {'src': source}).addEvents({ + 'load': properties.onload, + 'readystatechange': function(){ + if (this.readyState == 'complete') this.fireEvent('load'); + } + }); + delete properties.onload; + return script.setProperties(properties).inject(document.head); + }, + + /* + Property: css + Injects a css file in the page. + + Arguments: + source - the path of the css file + properties - some additional attributes you might want to add to the link element + + Example: + > new Asset.css('/css/myStyle.css', {id: 'myStyle', title: 'myStyle'}); + */ + + css: function(source, properties){ + return new Element('link', $merge({ + 'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source + }, properties)).inject(document.head); + }, + + /* + Property: image + Preloads an image and returns the img element. does not inject it to the page. + + Arguments: + source - the path of the image file + properties - some additional attributes you might want to add to the img element + + Example: + > new Asset.image('/images/myImage.png', {id: 'myImage', title: 'myImage', onload: myFunction}); + + Returns: + the img element. you can inject it anywhere you want with // + */ + + image: function(source, properties){ + properties = $merge({ + 'onload': Class.empty, + 'onabort': Class.empty, + 'onerror': Class.empty + }, properties); + var image = new Image(); + image.src = source; + var element = new Element('img', {'src': source}); + ['load', 'abort', 'error'].each(function(type){ + var event = properties['on' + type]; + delete properties['on' + type]; + element.addEvent(type, function(){ + this.removeEvent(type, arguments.callee); + event.call(this); + }); + }); + if (image.width && image.height) element.fireEvent('load', element, 1); + return element.setProperties(properties); + }, + + /* + Property: images + Preloads an array of images (as strings) and returns an array of img elements. does not inject them to the page. + + Arguments: + sources - array, the paths of the image files + options - object, see below + + Options: + onComplete - a function to execute when all image files are loaded in the browser's cache + onProgress - a function to execute when one image file is loaded in the browser's cache + + Example: + (start code) + new Asset.images(['/images/myImage.png', '/images/myImage2.gif'], { + onComplete: function(){ + alert('all images loaded!'); + } + }); + (end) + + Returns: + the img elements as $$. you can inject them anywhere you want with // + */ + + images: function(sources, options){ + options = $merge({ + onComplete: Class.empty, + onProgress: Class.empty + }, options); + if (!sources.push) sources = [sources]; + var images = []; + var counter = 0; + sources.each(function(source){ + var img = new Asset.image(source, { + 'onload': function(){ + options.onProgress.call(this, counter); + counter++; + if (counter == sources.length) options.onComplete(); + } + }); + images.push(img); + }); + return new Elements(images); + } + +}); + +/* +Script: Hash.js + Contains the class Hash. + +License: + MIT-style license. +*/ + +/* +Class: Hash + It wraps an object that it uses internally as a map. The user must use set(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. null/undefined values are allowed. + +Note: + Each hash instance has the length property. + +Arguments: + obj - an object to convert into a Hash instance. + +Example: + (start code) + var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'}); + hash.remove('b'); // b is removed. + hash.set('c', 'hello'); + hash.get('c'); // returns 'hello' + hash.length // returns 2 (a and c) + (end) +*/ + +var Hash = new Class({ + + length: 0, + + initialize: function(object){ + this.obj = object || {}; + this.setLength(); + }, + + /* + Property: get + Retrieves a value from the hash. + + Arguments: + key - The key + + Returns: + The value + */ + + get: function(key){ + return (this.hasKey(key)) ? this.obj[key] : null; + }, + + /* + Property: hasKey + Check the presence of a specified key-value pair in the hash. + + Arguments: + key - The key + + Returns: + True if the Hash contains a value for the specified key, otherwise false + */ + + hasKey: function(key){ + return (key in this.obj); + }, + + /* + Property: set + Adds a key-value pair to the hash or replaces a previous value associated with the key. + + Arguments: + key - The key + value - The value + */ + + set: function(key, value){ + if (!this.hasKey(key)) this.length++; + this.obj[key] = value; + return this; + }, + + setLength: function(){ + this.length = 0; + for (var p in this.obj) this.length++; + return this; + }, + + /* + Property: remove + Removes a key-value pair from the hash. + + Arguments: + key - The key + */ + + remove: function(key){ + if (this.hasKey(key)){ + delete this.obj[key]; + this.length--; + } + return this; + }, + + /* + Property: each + Calls a function for each key-value pair. The first argument passed to the function will be the value, the second one will be the key, like $each. + + Arguments: + fn - The function to call for each key-value pair + bind - Optional, the object that will be referred to as "this" in the function + */ + + each: function(fn, bind){ + $each(this.obj, fn, bind); + }, + + /* + Property: extend + Extends the current hash with an object containing key-value pairs. Values for duplicate keys will be replaced by the new ones. + + Arguments: + obj - An object containing key-value pairs + */ + + extend: function(obj){ + $extend(this.obj, obj); + return this.setLength(); + }, + + /* + Property: merge + Merges the current hash with multiple objects. + */ + + merge: function(){ + this.obj = $merge.apply(null, [this.obj].extend(arguments)); + return this.setLength(); + }, + + /* + Property: empty + Empties all hash values properties and values. + */ + + empty: function(){ + this.obj = {}; + this.length = 0; + return this; + }, + + /* + Property: keys + Returns an array containing all the keys, in the same order as the values returned by . + + Returns: + An array containing all the keys of the hash + */ + + keys: function(){ + var keys = []; + for (var property in this.obj) keys.push(property); + return keys; + }, + + /* + Property: values + Returns an array containing all the values, in the same order as the keys returned by . + + Returns: + An array containing all the values of the hash + */ + + values: function(){ + var values = []; + for (var property in this.obj) values.push(this.obj[property]); + return values; + } + +}); + +/* Section: Utility Functions */ + +/* +Function: $H + Shortcut to create a Hash from an Object. +*/ + +function $H(obj){ + return new Hash(obj); +}; + +/* +Script: Hash.Cookie.js + Stores and loads an Hash as a cookie using Json format. +*/ + +/* +Class: Hash.Cookie + Inherits all the methods from , additional methods are save and load. + Hash json string has a limit of 4kb (4096byte), so be careful with your Hash size. + Creating a new instance automatically loads the data from the Cookie into the Hash. + If the Hash is emptied, the cookie is also removed. + +Arguments: + name - the key (name) for the cookie + options - options are identical to and are simply passed along to it. + In addition, it has the autoSave option, to save the cookie at every operation. defaults to true. + +Example: + (start code) + var fruits = new Hash.Cookie('myCookieName', {duration: 3600}); + fruits.extend({ + 'lemon': 'yellow', + 'apple': 'red' + }); + fruits.set('melon', 'green'); + fruits.get('lemon'); // yellow + + // ... on another page ... values load automatically + + var fruits = new Hash.Cookie('myCookieName', {duration: 365}); + fruits.get('melon'); // green + + fruits.erase(); // delete cookie + (end) +*/ + +Hash.Cookie = Hash.extend({ + + initialize: function(name, options){ + this.name = name; + this.options = $extend({'autoSave': true}, options || {}); + this.load(); + }, + + /* + Property: save + Saves the Hash to the cookie. If the hash is empty, removes the cookie. + + Returns: + Returns false when the JSON string cookie is too long (4kb), otherwise true. + + Example: + (start code) + var login = new Hash.Cookie('userstatus', {autoSave: false}); + + login.extend({ + 'username': 'John', + 'credentials': [4, 7, 9] + }); + login.set('last_message', 'User logged in!'); + + login.save(); // finally save the Hash + (end) + */ + + save: function(){ + if (this.length == 0){ + Cookie.remove(this.name, this.options); + return true; + } + var str = Json.toString(this.obj); + if (str.length > 4096) return false; //cookie would be truncated! + Cookie.set(this.name, str, this.options); + return true; + }, + + /* + Property: load + Loads the cookie and assigns it to the Hash. + */ + + load: function(){ + this.obj = Json.evaluate(Cookie.get(this.name), true) || {}; + this.setLength(); + } + +}); + +Hash.Cookie.Methods = {}; +['extend', 'set', 'merge', 'empty', 'remove'].each(function(method){ + Hash.Cookie.Methods[method] = function(){ + Hash.prototype[method].apply(this, arguments); + if (this.options.autoSave) this.save(); + return this; + }; +}); +Hash.Cookie.implement(Hash.Cookie.Methods); + +/* +Script: Color.js + Contains the Color class. + +License: + MIT-style license. +*/ + +/* +Class: Color + Creates a new Color Object, which is an array with some color specific methods. +Arguments: + color - the hex, the RGB array or the HSB array of the color to create. For HSB colors, you need to specify the second argument. + type - a string representing the type of the color to create. needs to be specified if you intend to create the color with HSB values, or an array of HEX values. Can be 'rgb', 'hsb' or 'hex'. + +Example: + (start code) + var black = new Color('#000'); + var purple = new Color([255,0,255]); + // mix black with white and purple, each time at 10% of the new color + var darkpurple = black.mix('#fff', purple, 10); + $('myDiv').setStyle('background-color', darkpurple); + (end) +*/ + +var Color = new Class({ + + initialize: function(color, type){ + type = type || (color.push ? 'rgb' : 'hex'); + var rgb, hsb; + switch(type){ + case 'rgb': + rgb = color; + hsb = rgb.rgbToHsb(); + break; + case 'hsb': + rgb = color.hsbToRgb(); + hsb = color; + break; + default: + rgb = color.hexToRgb(true); + hsb = rgb.rgbToHsb(); + } + rgb.hsb = hsb; + rgb.hex = rgb.rgbToHex(); + return $extend(rgb, Color.prototype); + }, + + /* + Property: mix + Mixes two or more colors with the Color. + + Arguments: + color - a color to mix. you can use as arguments how many colors as you want to mix with the original one. + alpha - if you use a number as the last argument, it will be threated as the amount of the color to mix. + */ + + mix: function(){ + var colors = $A(arguments); + var alpha = ($type(colors[colors.length - 1]) == 'number') ? colors.pop() : 50; + var rgb = this.copy(); + colors.each(function(color){ + color = new Color(color); + for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); + }); + return new Color(rgb, 'rgb'); + }, + + /* + Property: invert + Inverts the Color. + */ + + invert: function(){ + return new Color(this.map(function(value){ + return 255 - value; + })); + }, + + /* + Property: setHue + Modifies the hue of the Color, and returns a new one. + + Arguments: + value - the hue to set + */ + + setHue: function(value){ + return new Color([value, this.hsb[1], this.hsb[2]], 'hsb'); + }, + + /* + Property: setSaturation + Changes the saturation of the Color, and returns a new one. + + Arguments: + percent - the percentage of the saturation to set + */ + + setSaturation: function(percent){ + return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb'); + }, + + /* + Property: setBrightness + Changes the brightness of the Color, and returns a new one. + + Arguments: + percent - the percentage of the brightness to set + */ + + setBrightness: function(percent){ + return new Color([this.hsb[0], this.hsb[1], percent], 'hsb'); + } + +}); + +/* Section: Utility Functions */ + +/* +Function: $RGB + Shortcut to create a new color, based on red, green, blue values. + +Arguments: + r - (integer) red value (0-255) + g - (integer) green value (0-255) + b - (integer) blue value (0-255) + +*/ + +function $RGB(r, g, b){ + return new Color([r, g, b], 'rgb'); +}; + +/* +Function: $HSB + Shortcut to create a new color, based on hue, saturation, brightness values. + +Arguments: + h - (integer) hue value (0-100) + s - (integer) saturation value (0-100) + b - (integer) brightness value (0-100) +*/ + +function $HSB(h, s, b){ + return new Color([h, s, b], 'hsb'); +}; + +/* +Class: Array + A collection of The Array Object prototype methods. +*/ + +Array.extend({ + + /* + Property: rgbToHsb + Converts a RGB array to an HSB array. + + Returns: + the HSB array. + */ + + rgbToHsb: function(){ + var red = this[0], green = this[1], blue = this[2]; + var hue, saturation, brightness; + var max = Math.max(red, green, blue), min = Math.min(red, green, blue); + var delta = max - min; + brightness = max / 255; + saturation = (max != 0) ? delta / max : 0; + if (saturation == 0){ + hue = 0; + } else { + var rr = (max - red) / delta; + var gr = (max - green) / delta; + var br = (max - blue) / delta; + if (red == max) hue = br - gr; + else if (green == max) hue = 2 + rr - br; + else hue = 4 + gr - rr; + hue /= 6; + if (hue < 0) hue++; + } + return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)]; + }, + + /* + Property: hsbToRgb + Converts an HSB array to an RGB array. + + Returns: + the RGB array. + */ + + hsbToRgb: function(){ + var br = Math.round(this[2] / 100 * 255); + if (this[1] == 0){ + return [br, br, br]; + } else { + var hue = this[0] % 360; + var f = hue % 60; + var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255); + var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255); + var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255); + switch(Math.floor(hue / 60)){ + case 0: return [br, t, p]; + case 1: return [q, br, p]; + case 2: return [p, br, t]; + case 3: return [p, q, br]; + case 4: return [t, p, br]; + case 5: return [br, p, q]; + } + } + return false; + } + +}); + +/* +Script: Scroller.js + Contains the . + +License: + MIT-style license. +*/ + +/* +Class: Scroller + The Scroller is a class to scroll any element with an overflow (including the window) when the mouse cursor reaches certain buondaries of that element. + You must call its start method to start listening to mouse movements. + +Note: + The Scroller requires an XHTML doctype. + +Arguments: + element - required, the element to scroll. + options - optional, see options below, and options. + +Options: + area - integer, the necessary boundaries to make the element scroll. + velocity - integer, velocity ratio, the modifier for the window scrolling speed. + +Events: + onChange - optionally, when the mouse reaches some boundaries, you can choose to alter some other values, instead of the scrolling offsets. + Automatically passes as parameters x and y values. +*/ + +var Scroller = new Class({ + + options: { + area: 20, + velocity: 1, + onChange: function(x, y){ + this.element.scrollTo(x, y); + } + }, + + initialize: function(element, options){ + this.setOptions(options); + this.element = $(element); + this.mousemover = ([window, document].contains(element)) ? $(document.body) : this.element; + }, + + /* + Property: start + The scroller starts listening to mouse movements. + */ + + start: function(){ + this.coord = this.getCoords.bindWithEvent(this); + this.mousemover.addListener('mousemove', this.coord); + }, + + /* + Property: stop + The scroller stops listening to mouse movements. + */ + + stop: function(){ + this.mousemover.removeListener('mousemove', this.coord); + this.timer = $clear(this.timer); + }, + + getCoords: function(event){ + this.page = (this.element == window) ? event.client : event.page; + if (!this.timer) this.timer = this.scroll.periodical(50, this); + }, + + scroll: function(){ + var el = this.element.getSize(); + var pos = this.element.getPosition(); + + var change = {'x': 0, 'y': 0}; + for (var z in this.page){ + if (this.page[z] < (this.options.area + pos[z]) && el.scroll[z] != 0) + change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity; + else if (this.page[z] + this.options.area > (el.size[z] + pos[z]) && el.scroll[z] + el.size[z] != el.scrollSize[z]) + change[z] = (this.page[z] - el.size[z] + this.options.area - pos[z]) * this.options.velocity; + } + if (change.y || change.x) this.fireEvent('onChange', [el.scroll.x + change.x, el.scroll.y + change.y]); + } + +}); + +Scroller.implement(new Events, new Options); + +/* +Script: Slider.js + Contains + +License: + MIT-style license. +*/ + +/* +Class: Slider + Creates a slider with two elements: a knob and a container. Returns the values. + +Note: + The Slider requires an XHTML doctype. + +Arguments: + element - the knob container + knob - the handle + options - see Options below + +Options: + steps - the number of steps for your slider. + mode - either 'horizontal' or 'vertical'. defaults to horizontal. + offset - relative offset for knob position. default to 0. + +Events: + onChange - a function to fire when the value changes. + onComplete - a function to fire when you're done dragging. + onTick - optionally, you can alter the onTick behavior, for example displaying an effect of the knob moving to the desired position. + Passes as parameter the new position. +*/ + +var Slider = new Class({ + + options: { + onChange: Class.empty, + onComplete: Class.empty, + onTick: function(pos){ + this.knob.setStyle(this.p, pos); + }, + mode: 'horizontal', + steps: 100, + offset: 0 + }, + + initialize: function(el, knob, options){ + this.element = $(el); + this.knob = $(knob); + this.setOptions(options); + this.previousChange = -1; + this.previousEnd = -1; + this.step = -1; + this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this)); + var mod, offset; + switch(this.options.mode){ + case 'horizontal': + this.z = 'x'; + this.p = 'left'; + mod = {'x': 'left', 'y': false}; + offset = 'offsetWidth'; + break; + case 'vertical': + this.z = 'y'; + this.p = 'top'; + mod = {'x': false, 'y': 'top'}; + offset = 'offsetHeight'; + } + this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2); + this.half = this.knob[offset]/2; + this.getPos = this.element['get' + this.p.capitalize()].bind(this.element); + this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset); + var lim = {}; + lim[this.z] = [- this.options.offset, this.max - this.options.offset]; + this.drag = new Drag.Base(this.knob, { + limit: lim, + modifiers: mod, + snap: 0, + onStart: function(){ + this.draggedKnob(); + }.bind(this), + onDrag: function(){ + this.draggedKnob(); + }.bind(this), + onComplete: function(){ + this.draggedKnob(); + this.end(); + }.bind(this) + }); + if (this.options.initialize) this.options.initialize.call(this); + }, + + /* + Property: set + The slider will get the step you pass. + + Arguments: + step - one integer + */ + + set: function(step){ + this.step = step.limit(0, this.options.steps); + this.checkStep(); + this.end(); + this.fireEvent('onTick', this.toPosition(this.step)); + return this; + }, + + clickedElement: function(event){ + var position = event.page[this.z] - this.getPos() - this.half; + position = position.limit(-this.options.offset, this.max -this.options.offset); + this.step = this.toStep(position); + this.checkStep(); + this.end(); + this.fireEvent('onTick', position); + }, + + draggedKnob: function(){ + this.step = this.toStep(this.drag.value.now[this.z]); + this.checkStep(); + }, + + checkStep: function(){ + if (this.previousChange != this.step){ + this.previousChange = this.step; + this.fireEvent('onChange', this.step); + } + }, + + end: function(){ + if (this.previousEnd !== this.step){ + this.previousEnd = this.step; + this.fireEvent('onComplete', this.step + ''); + } + }, + + toStep: function(position){ + return Math.round((position + this.options.offset) / this.max * this.options.steps); + }, + + toPosition: function(step){ + return this.max * step / this.options.steps; + } + +}); + +Slider.implement(new Events); +Slider.implement(new Options); + +/* +Script: SmoothScroll.js + Contains + +License: + MIT-style license. +*/ + +/* +Class: SmoothScroll + Auto targets all the anchors in a page and display a smooth scrolling effect upon clicking them. + Inherits methods, properties, options and events from . + +Note: + SmoothScroll requires an XHTML doctype. + +Arguments: + options - the Fx.Scroll options (see: ) plus links, a collection of elements you want your smoothscroll on. Defaults to document.links. + +Example: + >new SmoothScroll(); +*/ + +var SmoothScroll = Fx.Scroll.extend({ + + initialize: function(options){ + this.parent(window, options); + this.links = (this.options.links) ? $$(this.options.links) : $$(document.links); + var location = window.location.href.match(/^[^#]*/)[0] + '#'; + this.links.each(function(link){ + if (link.href.indexOf(location) != 0) return; + var anchor = link.href.substr(location.length); + if (anchor && $(anchor)) this.useLink(link, anchor); + }, this); + if (!window.webkit419) this.addEvent('onComplete', function(){ + window.location.hash = this.anchor; + }); + }, + + useLink: function(link, anchor){ + link.addEvent('click', function(event){ + this.anchor = anchor; + this.toElement(anchor); + event.stop(); + }.bindWithEvent(this)); + } + +}); + +/* +Script: Sortables.js + Contains Class. + +License: + MIT-style license. +*/ + +/* +Class: Sortables + Creates an interface for and drop, resorting of a list. + +Note: + The Sortables require an XHTML doctype. + +Arguments: + list - required, the list that will become sortable. + options - an Object, see options below. + +Options: + handles - a collection of elements to be used for drag handles. defaults to the elements. + +Events: + onStart - function executed when the item starts dragging + onComplete - function executed when the item ends dragging +*/ + +var Sortables = new Class({ + + options: { + handles: false, + onStart: Class.empty, + onComplete: Class.empty, + ghost: true, + snap: 3, + onDragStart: function(element, ghost){ + ghost.setStyle('opacity', 0.7); + element.setStyle('opacity', 0.7); + }, + onDragComplete: function(element, ghost){ + element.setStyle('opacity', 1); + ghost.remove(); + this.trash.remove(); + } + }, + + initialize: function(list, options){ + this.setOptions(options); + this.list = $(list); + this.elements = this.list.getChildren(); + this.handles = (this.options.handles) ? $$(this.options.handles) : this.elements; + this.bound = { + 'start': [], + 'moveGhost': this.moveGhost.bindWithEvent(this) + }; + for (var i = 0, l = this.handles.length; i < l; i++){ + this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]); + } + this.attach(); + if (this.options.initialize) this.options.initialize.call(this); + this.bound.move = this.move.bindWithEvent(this); + this.bound.end = this.end.bind(this); + }, + + attach: function(){ + this.handles.each(function(handle, i){ + handle.addEvent('mousedown', this.bound.start[i]); + }, this); + }, + + detach: function(){ + this.handles.each(function(handle, i){ + handle.removeEvent('mousedown', this.bound.start[i]); + }, this); + }, + + start: function(event, el){ + this.active = el; + this.coordinates = this.list.getCoordinates(); + if (this.options.ghost){ + var position = el.getPosition(); + this.offset = event.page.y - position.y; + this.trash = new Element('div').inject(document.body); + this.ghost = el.clone().inject(this.trash).setStyles({ + 'position': 'absolute', + 'left': position.x, + 'top': event.page.y - this.offset + }); + document.addListener('mousemove', this.bound.moveGhost); + this.fireEvent('onDragStart', [el, this.ghost]); + } + document.addListener('mousemove', this.bound.move); + document.addListener('mouseup', this.bound.end); + this.fireEvent('onStart', el); + event.stop(); + }, + + moveGhost: function(event){ + var value = event.page.y - this.offset; + value = value.limit(this.coordinates.top, this.coordinates.bottom - this.ghost.offsetHeight); + this.ghost.setStyle('top', value); + event.stop(); + }, + + move: function(event){ + var now = event.page.y; + this.previous = this.previous || now; + var up = ((this.previous - now) > 0); + var prev = this.active.getPrevious(); + var next = this.active.getNext(); + if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev); + if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next); + this.previous = now; + }, + + serialize: function(converter){ + return this.list.getChildren().map(converter || function(el){ + return this.elements.indexOf(el); + }, this); + }, + + end: function(){ + this.previous = null; + document.removeListener('mousemove', this.bound.move); + document.removeListener('mouseup', this.bound.end); + if (this.options.ghost){ + document.removeListener('mousemove', this.bound.moveGhost); + this.fireEvent('onDragComplete', [this.active, this.ghost]); + } + this.fireEvent('onComplete', this.active); + } + +}); + +Sortables.implement(new Events, new Options); + +/* +Script: Tips.js + Tooltips, BubbleTips, whatever they are, they will appear on mouseover + +License: + MIT-style license. + +Credits: + The idea behind Tips.js is based on Bubble Tooltips () by Alessandro Fulcitiniti +*/ + +/* +Class: Tips + Display a tip on any element with a title and/or href. + +Note: + Tips requires an XHTML doctype. + +Arguments: + elements - a collection of elements to apply the tooltips to on mouseover. + options - an object. See options Below. + +Options: + maxTitleChars - the maximum number of characters to display in the title of the tip. defaults to 30. + showDelay - the delay the onShow method is called. (defaults to 100 ms) + hideDelay - the delay the onHide method is called. (defaults to 100 ms) + + className - the prefix for your tooltip classNames. defaults to 'tool'. + + the whole tooltip will have as classname: tool-tip + + the title will have as classname: tool-title + + the text will have as classname: tool-text + + offsets - the distance of your tooltip from the mouse. an Object with x/y properties. + fixed - if set to true, the toolTip will not follow the mouse. + +Events: + onShow - optionally you can alter the default onShow behaviour with this option (like displaying a fade in effect); + onHide - optionally you can alter the default onHide behaviour with this option (like displaying a fade out effect); + +Example: + (start code) + + + (end) + +Note: + The title of the element will always be used as the tooltip body. If you put :: on your title, the text before :: will become the tooltip title. +*/ + +var Tips = new Class({ + + options: { + onShow: function(tip){ + tip.setStyle('visibility', 'visible'); + }, + onHide: function(tip){ + tip.setStyle('visibility', 'hidden'); + }, + maxTitleChars: 30, + showDelay: 100, + hideDelay: 100, + className: 'tool', + offsets: {'x': 16, 'y': 16}, + fixed: false + }, + + initialize: function(elements, options){ + this.setOptions(options); + this.toolTip = new Element('div', { + 'class': this.options.className + '-tip', + 'styles': { + 'position': 'absolute', + 'top': '0', + 'left': '0', + 'visibility': 'hidden' + } + }).inject(document.body); + this.wrapper = new Element('div').inject(this.toolTip); + $$(elements).each(this.build, this); + if (this.options.initialize) this.options.initialize.call(this); + }, + + build: function(el){ + el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false); + if (el.title){ + var dual = el.title.split('::'); + if (dual.length > 1){ + el.$tmp.myTitle = dual[0].trim(); + el.$tmp.myText = dual[1].trim(); + } else { + el.$tmp.myText = el.title; + } + el.removeAttribute('title'); + } else { + el.$tmp.myText = false; + } + if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "…"; + el.addEvent('mouseenter', function(event){ + this.start(el); + if (!this.options.fixed) this.locate(event); + else this.position(el); + }.bind(this)); + if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this)); + var end = this.end.bind(this); + el.addEvent('mouseleave', end); + el.addEvent('trash', end); + }, + + start: function(el){ + this.wrapper.empty(); + if (el.$tmp.myTitle){ + this.title = new Element('span').inject(new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)).setHTML(el.$tmp.myTitle); + } + if (el.$tmp.myText){ + this.text = new Element('span').inject(new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)).setHTML(el.$tmp.myText); + } + $clear(this.timer); + this.timer = this.show.delay(this.options.showDelay, this); + }, + + end: function(event){ + $clear(this.timer); + this.timer = this.hide.delay(this.options.hideDelay, this); + }, + + position: function(element){ + var pos = element.getPosition(); + this.toolTip.setStyles({ + 'left': pos.x + this.options.offsets.x, + 'top': pos.y + this.options.offsets.y + }); + }, + + locate: function(event){ + var win = {'x': window.getWidth(), 'y': window.getHeight()}; + var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()}; + var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight}; + var prop = {'x': 'left', 'y': 'top'}; + for (var z in prop){ + var pos = event.page[z] + this.options.offsets[z]; + if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z]; + this.toolTip.setStyle(prop[z], pos); + }; + }, + + show: function(){ + if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this); + this.fireEvent('onShow', [this.toolTip]); + }, + + hide: function(){ + this.fireEvent('onHide', [this.toolTip]); + } + +}); + +Tips.implement(new Events, new Options); + +/* +Script: Group.js + For Grouping Classes or Elements Events. The Event added to the Group will fire when all of the events of the items of the group are fired. + +License: + MIT-style license. +*/ + +/* +Class: Group + An "Utility" Class. + +Arguments: + List of Class instances + +Example: + (start code) + xhr1 = new Ajax('data.js', {evalScript: true}); + xhr2 = new Ajax('abstraction.js', {evalScript: true}); + xhr3 = new Ajax('template.js', {evalScript: true}); + + var group = new Group(xhr1, xhr2, xhr3); + group.addEvent('onComplete', function(){ + alert('All Scripts loaded'); + }); + + xhr1.request(); + xhr2.request(); + xhr3.request(); + (end) + +*/ + +var Group = new Class({ + + initialize: function(){ + this.instances = $A(arguments); + this.events = {}; + this.checker = {}; + }, + + /* + Property: addEvent + adds an event to the stack of events of the Class instances. + + Arguments: + type - string; the event name (e.g. 'onComplete') + fn - function to execute when all instances fired this event + */ + + addEvent: function(type, fn){ + this.checker[type] = this.checker[type] || {}; + this.events[type] = this.events[type] || []; + if (this.events[type].contains(fn)) return false; + else this.events[type].push(fn); + this.instances.each(function(instance, i){ + instance.addEvent(type, this.check.bind(this, [type, instance, i])); + }, this); + return this; + }, + + check: function(type, instance, i){ + this.checker[type][i] = true; + var every = this.instances.every(function(current, j){ + return this.checker[type][j] || false; + }, this); + if (!every) return; + this.checker[type] = {}; + this.events[type].each(function(event){ + event.call(this, this.instances, instance); + }, this); + } + +}); + +/* +Script: Accordion.js + Contains + +License: + MIT-style license. +*/ + +/* +Class: Accordion + The Accordion class creates a group of elements that are toggled when their handles are clicked. When one elements toggles in, the others toggles back. + Inherits methods, properties, options and events from . + +Note: + The Accordion requires an XHTML doctype. + +Arguments: + togglers - required, a collection of elements, the elements handlers that will be clickable. + elements - required, a collection of elements the transitions will be applied to. + options - optional, see options below, and options and events. + +Options: + show - integer, the Index of the element to show at start. + display - integer, the Index of the element to show at start (with a transition). defaults to 0. + fixedHeight - integer, if you want the elements to have a fixed height. defaults to false. + fixedWidth - integer, if you want the elements to have a fixed width. defaults to false. + height - boolean, will add a height transition to the accordion if true. defaults to true. + opacity - boolean, will add an opacity transition to the accordion if true. defaults to true. + width - boolean, will add a width transition to the accordion if true. defaults to false, css mastery is required to make this work! + alwaysHide - boolean, will allow to hide all elements if true, instead of always keeping one element shown. defaults to false. + +Events: + onActive - function to execute when an element starts to show + onBackground - function to execute when an element starts to hide +*/ + +var Accordion = Fx.Elements.extend({ + + options: { + onActive: Class.empty, + onBackground: Class.empty, + display: 0, + show: false, + height: true, + width: false, + opacity: true, + fixedHeight: false, + fixedWidth: false, + wait: false, + alwaysHide: false + }, + + initialize: function(){ + var options, togglers, elements, container; + $each(arguments, function(argument, i){ + switch($type(argument)){ + case 'object': options = argument; break; + case 'element': container = $(argument); break; + default: + var temp = $$(argument); + if (!togglers) togglers = temp; + else elements = temp; + } + }); + this.togglers = togglers || []; + this.elements = elements || []; + this.container = $(container); + this.setOptions(options); + this.previous = -1; + if (this.options.alwaysHide) this.options.wait = true; + if ($chk(this.options.show)){ + this.options.display = false; + this.previous = this.options.show; + } + if (this.options.start){ + this.options.display = false; + this.options.show = false; + } + this.effects = {}; + if (this.options.opacity) this.effects.opacity = 'fullOpacity'; + if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth'; + if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight'; + for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]); + this.elements.each(function(el, i){ + if (this.options.show === i){ + this.fireEvent('onActive', [this.togglers[i], el]); + } else { + for (var fx in this.effects) el.setStyle(fx, 0); + } + }, this); + this.parent(this.elements); + if ($chk(this.options.display)) this.display(this.options.display); + }, + + /* + Property: addSection + Dynamically adds a new section into the accordion at the specified position. + + Arguments: + toggler - (dom element) the element that toggles the accordion section open. + element - (dom element) the element that stretches open when the toggler is clicked. + pos - (integer) the index where these objects are to be inserted within the accordion. + */ + + addSection: function(toggler, element, pos){ + toggler = $(toggler); + element = $(element); + var test = this.togglers.contains(toggler); + var len = this.togglers.length; + this.togglers.include(toggler); + this.elements.include(element); + if (len && (!test || pos)){ + pos = $pick(pos, len - 1); + toggler.injectBefore(this.togglers[pos]); + element.injectAfter(toggler); + } else if (this.container && !test){ + toggler.inject(this.container); + element.inject(this.container); + } + var idx = this.togglers.indexOf(toggler); + toggler.addEvent('click', this.display.bind(this, idx)); + if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'}); + if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'}); + element.fullOpacity = 1; + if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth; + if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight; + element.setStyle('overflow', 'hidden'); + if (!test){ + for (var fx in this.effects) element.setStyle(fx, 0); + } + return this; + }, + + /* + Property: display + Shows a specific section and hides all others. Useful when triggering an accordion from outside. + + Arguments: + index - integer, the index of the item to show, or the actual element to show. + */ + + display: function(index){ + index = ($type(index) == 'element') ? this.elements.indexOf(index) : index; + if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this; + this.previous = index; + var obj = {}; + this.elements.each(function(el, i){ + obj[i] = {}; + var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0)); + this.fireEvent(hide ? 'onBackground' : 'onActive', [this.togglers[i], el]); + for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]]; + }, this); + return this.start(obj); + }, + + showThisHideOpen: function(index){return this.display(index);} + +}); + +Fx.Accordion = Accordion; \ No newline at end of file diff --git a/gulliver/js/maborak/samples/myInfo.xml b/gulliver/js/maborak/samples/myInfo.xml new file mode 100644 index 000000000..34e1238e3 --- /dev/null +++ b/gulliver/js/maborak/samples/myInfo.xml @@ -0,0 +1,72 @@ + + +
    + + + + + + + Personal Information + + + + First Name + + + Last Name + + + User ID + + + Zip Code + + + + + + + + SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + + Country + + + + + + + + + +SELECT IS_UID, IS_NAME FROM ISO_SUBDIVISION WHERE IC_UID = "@#USR_COUNTRY" ORDER BY IS_NAME + State or Region + + + + Save + + + + + + + + + + + + alert('javascript'); + +Valor de Campo Wilmer +Valor de Campo Otro + +Texto 1 +Texto 2 +Texto 3 +Texto 4 +Proceso1 +Proceso2 +Proceso3 + diff --git a/gulliver/js/maborak/samples/nc.gif b/gulliver/js/maborak/samples/nc.gif new file mode 100644 index 0000000000000000000000000000000000000000..44ef04f457e6e4a44ea8b2f649997db16212354a GIT binary patch literal 302 zcmZ?wbhEHb zwChiwzuUa^MMlozqbI&tdDP5ZaC=_Mqo}BbA3lEFx##Vf^FP|7u9>=4PAtE1&LCK0`{ZC`USDU+5MFp+hu;qD>&$1JzzqSNjTd?@n?VO;2FOngY~BZ^PH-0SX*n_VK+47`lMY=_PP*j~zOXULVTYPlV@UXq ynLYx&KFt$mSV&B0Jid8?hlkR!F2;=JC@5*iZW9!dd@4Aua>m33AC literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/samples/nr.gif b/gulliver/js/maborak/samples/nr.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb650024ed177c54dd42d25122eca6471161fae0 GIT binary patch literal 297 zcmZ?wbhEHb zwChiwzuUa^MMlozqbI&tdDP5ZaC=_Mqo}BbA3lEFx##Vf^FP|7u9>=4PAtE1&LCK0`{ZC`USDU+5MFp+hu;qD>&$1JzzqSNjTd?@n?VO;2FOngY;Fgp2E0h%=|9wYqC-T@L&91yBry;0pN3S;Q#;t literal 0 HcmV?d00001 diff --git a/gulliver/js/maborak/samples/nr.png b/gulliver/js/maborak/samples/nr.png new file mode 100644 index 0000000000000000000000000000000000000000..287e68f7117e1ae4977ab8bd4ac33ea79b4c1b29 GIT binary patch literal 474 zcmV<00VV#4P)Mfvv6dg@h5lqW0j>o>} zTV1a;6m=1V00GhNE-FH>lG?zPvNn^BKZ~*G{`>5FtXwIBuMA#6;dzRu6QAsPo~F?X z)^|2>r3|>PD?tb@E*{YZFgc5QvG^}Vgag+Hd8WoEN$u~xx&T^fLZLc*rSUz3?3H^6V{0v= zBYTCzqnr(QF57TqA@s$Cwf0xJSZwe8F@IAIv}Mxq%YQq+edJDomhU3KC%FQ)xIQv+ QT>t<807*qoM6N<$f + + + order + + + + + + + + + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/pagina1.html b/gulliver/js/maborak/samples/pagina1.html new file mode 100644 index 000000000..60cc4458e --- /dev/null +++ b/gulliver/js/maborak/samples/pagina1.html @@ -0,0 +1,3 @@ +
    + +
    diff --git a/gulliver/js/maborak/samples/pagina2.html b/gulliver/js/maborak/samples/pagina2.html new file mode 100644 index 000000000..dd6a59b0d --- /dev/null +++ b/gulliver/js/maborak/samples/pagina2.html @@ -0,0 +1,6 @@ + + + + + asdasdasd + diff --git a/gulliver/js/maborak/samples/pm.xml b/gulliver/js/maborak/samples/pm.xml new file mode 100644 index 000000000..42a522bc5 --- /dev/null +++ b/gulliver/js/maborak/samples/pm.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/gulliver/js/maborak/samples/post.php b/gulliver/js/maborak/samples/post.php new file mode 100644 index 000000000..3c2123f22 --- /dev/null +++ b/gulliver/js/maborak/samples/post.php @@ -0,0 +1,6 @@ + diff --git a/gulliver/js/maborak/samples/processmap.html b/gulliver/js/maborak/samples/processmap.html new file mode 100644 index 000000000..ad27b6831 --- /dev/null +++ b/gulliver/js/maborak/samples/processmap.html @@ -0,0 +1,35 @@ + + + + Prueba processmap + + + + + + + + + diff --git a/gulliver/js/maborak/samples/processmap2.html b/gulliver/js/maborak/samples/processmap2.html new file mode 100644 index 000000000..726244a44 --- /dev/null +++ b/gulliver/js/maborak/samples/processmap2.html @@ -0,0 +1,33 @@ + + + + Prueba processmap + + + + + + + + + diff --git a/gulliver/js/maborak/samples/report.html b/gulliver/js/maborak/samples/report.html new file mode 100644 index 000000000..7e9c573e2 --- /dev/null +++ b/gulliver/js/maborak/samples/report.html @@ -0,0 +1,142 @@ + + + + Prueba leimnud + + + + + + + + + diff --git a/gulliver/js/maborak/samples/rss.html b/gulliver/js/maborak/samples/rss.html new file mode 100644 index 000000000..79b9c8d4f --- /dev/null +++ b/gulliver/js/maborak/samples/rss.html @@ -0,0 +1,41 @@ + + + + RSS Reader - BETA + + + + + + + + diff --git a/gulliver/js/maborak/samples/rss.xml b/gulliver/js/maborak/samples/rss.xml new file mode 100644 index 000000000..2d8e84d8b --- /dev/null +++ b/gulliver/js/maborak/samples/rss.xml @@ -0,0 +1,95 @@ + + + +Feed 19 + +NA +en +NA +Wed, 19 Apr 2006 16:26:12 -0800 +text +http://blogs.law.harvard.edu/tech/rss + + +<![CDATA[Arti<u>cle<u> 1 <i>from</i> feed 19]]> +data/feed19/article_1.html +sdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkh +Wed, 19 Apr 2006 16:26:12 -0800 + + + +Article 2 from feed 19 +data/feed19/article_2.html +Wed, 18 Apr 2006 16:26:12 -0800 + + + +Article 3 from feed 19 +data/feed19/article_3.html +Wed, 17 Apr 2006 16:26:12 -0800 + + + +Article 4 from feed 19 +data/feed19/article_4.html +ssdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkh +Wed, 16 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 + + + + + + + + + + diff --git a/gulliver/js/maborak/samples/rss2.xml b/gulliver/js/maborak/samples/rss2.xml new file mode 100644 index 000000000..973cfeb83 --- /dev/null +++ b/gulliver/js/maborak/samples/rss2.xml @@ -0,0 +1,35 @@ + + + +Feed 19 + +NA +en +NA +Wed, 19 Apr 2006 16:26:12 -0800 +text +http://blogs.law.harvard.edu/tech/rss + + +Article 1 from feed 19 +data/feed19/article_1.html +alert(5656)fsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkh]]> +Wed, 19 Apr 2006 16:26:12 -0800 + + + +Article 4 from feed 19 +data/feed19/article_4.html +ssdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkh +Wed, 16 Apr 2006 16:26:12 -0800 + + + +Article 5 from feed 19 +data/feed19/article_5.html +Wed, 15 Apr 2006 16:26:12 -0800 +sssdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hddfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhsdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkhdfsdfsdfsdf slkjdf kl sjdfkjs klsk jklsj kljskljskld jfklsjd kjsd fkhsdfj khsd jhjksd hjks hdfjkh + + + + diff --git a/gulliver/js/maborak/samples/s.html b/gulliver/js/maborak/samples/s.html new file mode 100644 index 000000000..ee06e5fc4 --- /dev/null +++ b/gulliver/js/maborak/samples/s.html @@ -0,0 +1,94 @@ + + + + Prueba leimnud + + + + + + + +
    + + + + + + + + + + + + +
    + + diff --git a/gulliver/js/maborak/samples/sample.php b/gulliver/js/maborak/samples/sample.php new file mode 100644 index 000000000..7cb71ca49 --- /dev/null +++ b/gulliver/js/maborak/samples/sample.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/gulliver/js/maborak/samples/sampleGrids.php b/gulliver/js/maborak/samples/sampleGrids.php new file mode 100644 index 000000000..f9bfdcce6 --- /dev/null +++ b/gulliver/js/maborak/samples/sampleGrids.php @@ -0,0 +1,377 @@ +'; +?> + + + + + Web samples + + + + + + + + + + diff --git a/gulliver/js/maborak/samples/services.html b/gulliver/js/maborak/samples/services.html new file mode 100644 index 000000000..778d050e7 --- /dev/null +++ b/gulliver/js/maborak/samples/services.html @@ -0,0 +1,53 @@ + + + Dynaform builder + + + + + + + Rate para el product bla:
    + +
    + Rate para el product bla:
    + +
    + Rate para el product bla:
    + +
    + Rate para el product bla:
    + +
    + +
    +Un comment System remoto ID por ejemplo "testeo" +
    +
    + +
    +Un comment System remoto ID por ejemplo "testeo_perucho" +
    +
    + + + diff --git a/gulliver/js/maborak/samples/sl.html b/gulliver/js/maborak/samples/sl.html new file mode 100644 index 000000000..81ee50b24 --- /dev/null +++ b/gulliver/js/maborak/samples/sl.html @@ -0,0 +1,265 @@ + + + Dynaform builder + + + + + + +
    +			Size: 
    +			Price: $ 
    +			
    + OS: + Price: $ +
    + Days: +
    + + TOTAL COST: $ + +------------------------------------------------------------------------------------ + + +This is important. A common page to load sliders + + + + +<html> + <head> + <title>Dynaform builder</title> +<script type="text/javascript" src="../core/maborak.js"></script> +<script type="text/javascript"> + var leimnud = new maborak().make({ + modules :"dom,abbr,drag,fx,slider" + }); +</script> +<script type="text/javascript"> + leimnud.event.add(window,"load",function(){ + + //SLIDER CODE + + }); +</script> +</head> +<body> +</body> +</html> + + +------------------------------------------------------------------------------------ + +Slider to Size: + + Small : 100 $ + Medium: 200 $ + Big : 300 $ + -------------- + label | price + +In slider code add. + + + + var size = new leimnud.module.slider.create(); + size.make({ + name : "size", // Name for your slider, this is important but .. this is the input containing the value of size to send. + selected:2, // Value selected by default... 2 is Big (0=Small,1=Medium,2=Big) + points:[ + {value:100,label:"Small"}, + {value:200,label:"Medium"}, + {value:300,label:"Big"} + ], + target:$('size'), // Target to Slider, an DIV with id "size" (for example) + out_label:$('size_label'), // Target to render current Label , an DIV or SPAN with id "size_label" (for example) + out_value:$('size_price') // Target to render current Price , an DIV or SPAN with id "size_price" (for example) + }); + + + The html: + + Size : <span id="size_label"></span> + Price: $ <span id="size_price"></span> + <div id="size"> </div> + + +------------------------------------------------------------------------------------ + + +Days: + 1 to 31 days (for example) + +In slider code add. + + var days = new leimnud.module.slider.create(); + days.make({ + name : "days", // Name for your slider, this is important but .. this is the input containing the value of size to send. + selected:1, // Value Day 2 selected... why?... in the system [1=0,2=1,etc] if the days are... "0-31" [0=0,1=1,etc] + points:"1-31", // change to "1-365" ... if neeeded. + fill_value:5, //By default "value === label" 2 days == 2 $ , but if U need apply a price to days. Set value per day HERE!. (example 1 day == 5 $) + target:$('days'), // Target to Slider, an DIV with id "size" (for example) + out_label:$('days_label'), // Target to render current Label , an DIV or SPAN with id "size_label" (for example) + out_value:$('days_price') // Target to render current Price , an DIV or SPAN with id "size_price" (for example) + }); + + + The html: + + Days : <span id="days_label"></span> + Price: $ <span id="days_price"></span> + <div id="days"> </div> + + +if you only need 5 days you can use the last metod and add it one value everyday + + + + +----------------------------------------------------------------------------------------- + + +TOTAL PRICES: + + + After you maked Sliders... is easy calculate the total prices. + + var total = new leimnud.module.slider.eventor(); + total.make({ + name:"total_cart", //Name + slides:[days,size], //Sliders to sume + operation:"+", + target:$('total'), + out_value:$('total_price') + }); + + The html: + + <div id="total"> </div> + Total Price: $ <span id="total"></span> + +------------------------------------------------------------------------------------------ + + +ALL IN ONE: + +
    + Size : + Price: $ +
    + + Days : + Price: $ +
    +
    + Total Price: $ + + +
    +
    + + + diff --git a/gulliver/js/maborak/samples/sl.php b/gulliver/js/maborak/samples/sl.php new file mode 100644 index 000000000..4aee7ffbb --- /dev/null +++ b/gulliver/js/maborak/samples/sl.php @@ -0,0 +1,3 @@ + diff --git a/gulliver/js/maborak/samples/slide.php b/gulliver/js/maborak/samples/slide.php new file mode 100644 index 000000000..a62900c15 --- /dev/null +++ b/gulliver/js/maborak/samples/slide.php @@ -0,0 +1,130 @@ + + + + drag + + + + + + + +
    + + + + diff --git a/gulliver/js/maborak/samples/style.css b/gulliver/js/maborak/samples/style.css new file mode 100644 index 000000000..435eca42d --- /dev/null +++ b/gulliver/js/maborak/samples/style.css @@ -0,0 +1,1336 @@ +body +{ + color:black; +} +.pm_separator{ + height: -1px; +} +form{ +margin: 0px; +} +INPUT { + font-family: Tahoma, Verdana, Arial, sans-serif ; + font-size: 10pt; +} + +/** + * Styles for leimnud.module.panel + * + **/ +/** + * leimnud.panel, Theme: firefox + * + * */ +.panel_containerWindow___firefox{ + border:1px solid #A3A2BC; +} +.panel_frontend___firefox, .panel_backend___firefox, .panel_iframe___firefox{ +/* width:100%;*/ + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_frontend___firefox{ + background-color:#fafafa; + z-index:2; +} +.panel_titleBar___firefox{ + position:relative; + height:20px; + overflow:hidden; + background-color:white; + background:url(/core/jscripts/maborak/core/images/panel.bg.title.gif); + background-repeat:repeat-x; + border-bottom:1px solid #DBE0E5; + +} +.panel_title___firefox{ + text-align:center; + width:100%; + height:100%; + color:black; + font:bold 8pt tahoma,MiscFixed; + padding-left:5px; + padding-top:3px; + z-index:1; +} +.panel_roll___firefox, .panel_close___firefox{ + position:absolute; + top:4; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; +} +.panel_close___firefox{ + cursor:pointer; + background:url(/core/jscripts/maborak/core/images/panel.close.static.gif); +} +.panel_shadow___firefox{ + position:absolute; + background-color:#CCCCCC; +} + +.panel_tabH___firefox{ + position:absolute; +} +.panel_tabOptionH___firefox{ + text-align:center; + font:normal 8pt Tahoma,MiscFixed; + /*border:1px solid #A3A2BC; + border: 1px solid #FF9900;*/ + position:absolute; +/* background-color:#FFE6BF;*/ + cursor:pointer; + color:black; +} +.panel_tabOptionOverH___firefox{ + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:center; + border:1px solid #FF9900; + color:#666666; + background-color:white; +} +.panel_tabOptionSelectedH___firefox, .panel_tabOptionSelectedOverH___firefox{ + font:normal 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border-bottom:1px solid #FFF; + background-color: #FBFFF2; + color:#000000; + text-align: center; + position: absolute; + +} +.panel_tabOptionSelectedOverH___firefox{ + color:#EA560F; +} + +.panel_tab___firefox{ + position:absolute; +} +.panel_tabOption___firefox,.panel_tabOptionOver___firefox, .panel_tabOptionSelected___firefox,.panel_tabOptionSelectedOver___firefox{ + text-align:left; + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + position:absolute; +} +.panel_tabOption___firefox{ + background-color:#EEEEEE; + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; +} +.panel_tabOptionOver___firefox{ + background-color:#FFFFFF; + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:left; + border:1px solid #A3A2BC; + color:#666666; +} +.panel_tabOptionSelected___firefox, .panel_tabOptionSelectedOver___firefox{ + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + border-right:1px solid #FFF; + background-color:white; + font-weight:bold; + color:#000000; +} +.panel_tabOptionSelectedOver___firefox{ + color:#EA560F; +} +.panel_content___firefox{ + position:relative; + color:black; + font:normal 8pt Tahoma,MiscFixed; + text-align:justify; + border:1px solid #A3A2BC; + background-color:white; + overflow:auto; +} +.panel_statusBar___firefox{ + position:relative; + overflow:hidden; + width:100%; + font:normal 8pt Tahoma,MiscFixed; + padding:0px; + margin:0px; + border-top:1px solid #DBE0E5; + height:20px; + background-color:white; +} +.panel_status___firefox +{ + text-align:left; + padding:2; + padding-left:5px; + color:#666666; +} +/** + * leimnud.panel Theme: firefox + * EOF + */ + + +/* leimnud.app.menuRight CSS begin */ +.app_menuRight_container___firefox +{ + position:absolute; + border:1px solid #808080; + background-color:#D4D0C8; + overflow:hidden; + z-index:10000; +} +.app_menuRight_shadow___firefox +{ + position:absolute; + border:1px solid #000; + background-color:#000; + overflow:hidden; + z-index:9999; + opacity:0.2; + filter:alpha(opacity=20); +} +.app_menuRight_separator___firefox +{ + padding:0; + margin:3; + position:relative; + cursor:default; + border-top:1px solid #808080; + border-bottom:1px solid white; + overflow:hidden; +} +.app_menuRight_option___firefox, .app_menuRight_option_over___firefox +{ + padding:1; + margin:1; + position:relative; + cursor:default; + color:black; + background-color:""; + height:22; + overflow:hidden; +} +.app_menuRight_option_over___firefox +{ + color:white; + background-color:#0A246A; +} +.app_menuRight_option_image___firefox, .app_menuRight_option_image_over___firefox +{ + width :22; + height :100%; + padding :0; + position:absolute; + overflow:hidden; + cursor :default; + left :0; + top :0; +} +.app_menuRight_option_image_element___firefox +{ + +} +.app_menuRight_option_text___firefox +{ + padding :0; + font :normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor :default; + left :22; + top :4; + overflow:hidden; +} +/* Theme processmaker */ +.app_menuRight_container___processmaker +{ + position:absolute; + border:1px solid #868686; + background-color:#FAFAFA; + overflow:hidden; + z-index:10000; +} +.app_menuRight_shadow___processmaker +{ + position:absolute; + border:1px solid black; + background-color:black; + overflow:hidden; + z-index:9999; + opacity:0.2; + filter:alpha(opacity=20); +} +.app_menuRight_separator___processmaker +{ + padding:0; + margin-left:30px; + margin-right:5px; + position:relative; + cursor:default; + border-top:1px solid #C5C5C5; + border-bottom:0px solid red; + overflow:hidden; +} +.app_menuRight_option___processmaker, .app_menuRight_option_over___processmaker, .app_menuRight_optionNull___processmaker + +{ + padding:0; + margin:0; + position:relative; + cursor:default; + color:black; + background-color:""; + height:29; + overflow:hidden; + border:0px solid #FBFFF2; +} +.app_menuRight_option_over___processmaker +{ + //background-image:url(/images/onmouseSilver.jpg); + background-color:#DCF1FC; + background-repeat:repeat-x; +} +.app_menuRight_option_image___processmaker, .app_menuRight_option_image_over___processmaker, .app_menuRight_option_imageNull___processmaker +{ + width :26; + height :31; + padding :0; + position:absolute; + overflow:hidden; + cursor :default; + left :0; + top :0; + background-color:#E9EEEE; + border-right:1px solid #C5C5C5; +} +.app_menuRight_option_image_over___processmaker +{ + background-color:#E9EEEE; + border-right-width:1px; +} +.app_menuRight_option_image_element___processmaker +{ + position:absolute; + top:2; +} +.app_menuRight_option_text___processmaker +{ + padding :0; + font :normal 8pt Tahoma,MiscFixed; + color :#003366; + position:absolute; + cursor :default; + left :30; + top :8; + overflow:hidden; +} +.app_menuRight_optionNull___processmaker +{ + +} +.app_menuRight_option_imageNull___processmaker +{ + width :26px; +} + +/* leimnud.app.menuRight CSS end */ + +/* processmap Theme.Panels begin */ +.panel_containerWindow___processmaker{ + border: 1px solid #C0C0C0; + border: 1px solid #1983BD; + border: 1px solid #66667E; + oveflow:hidden; + /*border: 1px solid #5394BF; + border-left:1px solid #8BBDDF; + border-top:1px solid #8BBDDF;*/ +} +.panel_modal___processmaker{ + position:absolute; + background-color:black; + left:0px; + top:0px; +} +.panel_iframe___processmaker{ + width:100%; + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_backend___processmaker{ + /*width:100%;*/ + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_frontend___processmaker{ + width: 100%; + height: 100%; + position: absolute; + background-color: #E8F2F7; + background-color:#E0DFE3; + /*background-color:#59A5D9;*/ + overflow: hidden; + z-index: 2; + top: 0px; + left: 0px; +} +.panel_titleBar___processmaker{ + position:relative; + height:23px; + overflow:hidden; + background-color:white; + background-image: url('/images/panel_title.jpg'); + background-image: url('../core/images/panel.bg.title.1x23.gif'); + background-repeat:repeat-x; + background-position:0 -1; + border-bottom:0px solid #DBE0E5; +} +.panel_title___processmaker{ + text-align: center; + width: 100%; + height: 23px; + color: #000; + /*color:#FFF;*/ + font: bold 8pt tahoma, MiscFixed; + padding-left: 5px; + padding-top: 5px; + z-index: 1; +} +.panel_close___processmaker{ + position:absolute; + top:4; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../core/images/panel.close.static.gif); +} +.panel_roll___processmaker{ + position:absolute; + top:4; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../core/images/roll.static.gif); + background-repeat:no-repeat; +} +.panel_resize___processmaker{ + position:absolute; + right:1px; + width:11px; + height:11px; + overflow:hidden; + z-index:333333; + bottom:1px; + background:url(../core/images/panel.resize.11x11.png?rand=234); + background-repeat:no-repeat; +} +.panel_headerBar___processmaker{ + position:relative; + height:25px; + overflow:hidden; + background-color:transparent; +} +.panel_shadow___processmaker{ + position:absolute; + background-color:#000; +} +.panel_tab___processmaker{ + position:absolute; + z-index:3; + overflow:hidden; +} + + +.panel_tabH___processmaker{ + position:absolute; +} +.panel_tabOptionH___processmaker{ + text-align:center; + font:normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor:pointer; + border:1px solid #919B9C; + background-color:#F9F9F9; + color:black; + height:20px; + max-height:9px; + overflow:hidden; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; +} +.panel_tabOptionOverH___processmaker{ + cursor:pointer; +} +.panel_tabOptionSelectedH___processmaker, .panel_tabOptionOverH___processmaker, .panel_tabOptionSelectedOverH___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + border-bottom:1px solid #F9F9F9; + border-top-color:#E68B2C; + background-color: #FBFFF2; + background-color: #F9F9F9; + color:#000000; + text-align: center; + position: absolute; + background-image: url('../core/images/panel.tabSelected.1x3.gif'); + background-repeat:repeat-x; + background-position:0 -1; + height:22px; + max-height:10px; + overflow:hidden; +/* -moz-border-radius-topleft:4px; + -moz-border-radius-topright:4px;*/ + +} +.panel_tabOptionSelectedOverH___processmaker{ +} + + + + +.panel_tabOption___processmaker{ + text-align:left; + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + border: 1px solid #FF9900; + position:absolute; + background-color:#FFE6BF; + cursor:pointer; + color:black; +} +.panel_tabOptionOver___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:left; + border:1px solid #FF9900; + color:#666666; + background-color:white; +} +.panel_tabOptionSelected___processmaker, .panel_tabOptionSelectedOver___processmaker{ + font:bold 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border-right:1px solid #FFF; + background-color: #FBFFF2; + color:#000000; + text-align: left; + position: absolute; +} +.panel_tabOptionSelectedOver___processmaker{ + color:#EA560F; + + +} +.panel_content___processmaker{ + position: relative; + color: black; + font: normal 8pt Tahoma,MiscFixed; + text-align: justify; + border: 1px solid #A3A2BC; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + /*border-left:1px solid #1983BD; + border-top:1px solid #1983BD; + border-right:1px solid #59A5D9; + border-bottom:1px solid #59A5D9;*/ + background-color: #E8F2F7; + background-color: #FFFFFF; + background-color: #F9F9F9; + overflow: auto; + padding:0px; +} +.panel_statusBar___processmaker{ + position:relative; + overflow:hidden; + font:normal 8pt Tahoma,MiscFixed; + padding:0px; + margin:0px; + /*background-color:white;*/ + background-color:transparent; +} +.panel_status___processmaker +{ + text-align:center; + padding:2; + padding-left:5px; + color:#666666; +} +/* processmap Theme.Panels end */ + + + +/* Theme leimnud.module.grid BEGIN */ +/* gray BEGIN */ +.app_grid_headerBar___gray +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding:3px; + text-align:center; + border:1px solid #AAA; + /*border:1px solid #FF9D3F;*/ + border-bottom:0px solid red; + background-color:#E8E8E8; + background :url(../core/images/grid.title.gray.gif); + background-position:0 -10; +} +.app_grid_table___gray +{ + font :normal 8pt Tahoma,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___gray +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #cbcbcb; + border :1px solid #aaa; + background-color:#D0DEF0; + background :url(../core/images/grid.title.gray.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; + background-position:0 0; +} +.app_grid_data___gray +{ + padding : 5px; + border : 1px solid #dfdfdf; + color : #333; + overflow: auto; + background-color:#FFF; +} +.app_grid_data___gray select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___gray +{ + background-color:#e0e0e0; + border-color :#cbcbcb; + border-color :#aaa; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +.app_grid_bg2___gray +{ + background-color:#e0e0e0; + border:1px solid #e0e0e0; + text-align:center; + color :#000; +} + +.app_grid_pDf___gray, .app_grid_pDp___gray, .app_grid_pDn___gray, .app_grid_pDl___gray, .app_grid_pDfDisabled___gray, .app_grid_pDpDisabled___gray, .app_grid_pDnDisabled___gray, .app_grid_pDlDisabled___gray +{ + width:16px; + height:16px; + text-decoration:none; + padding-left:7px; + padding-right:7px; + margin-left:3px; + margin-right:3px; + overflow:none; + background-repeat: no-repeat; + font:normal 11px sans-serif; +} +.app_grid_pDf___gray +{ + background:url(../core/images/module.grid/page-first.gif); +} +.app_grid_pDf___gray:hover +{ + background:url(../core/images/module.grid/page-first-disabled.gif); +} +.app_grid_pDfDisabled___gray +{ + background:url(../core/images/module.grid/page-first-disabled.gif); + cursor:default; +} + +.app_grid_pDp___gray +{ + background:url(../core/images/module.grid/page-prev.gif); +} +.app_grid_pDp___gray:hover +{ + background:url(../core/images/module.grid/page-prev-disabled.gif); +} +.app_grid_pDpDisabled___gray +{ + background:url(../core/images/module.grid/page-prev-disabled.gif); + cursor:default; +} + +.app_grid_pDn___gray +{ + background:url(../core/images/module.grid/page-next.gif); +} +.app_grid_pDn___gray:hover +{ + background:url(../core/images/module.grid/page-next-disabled.gif); +} +.app_grid_pDnDisabled___gray +{ + background:url(../core/images/module.grid/page-next-disabled.gif); + cursor:default; +} + +.app_grid_pDl___gray +{ + background:url(../core/images/module.grid/page-last.gif); +} +.app_grid_pDl___gray:hover +{ + background:url(../core/images/module.grid/page-last-disabled.gif); +} +.app_grid_pDlDisabled___gray +{ + background:url(../core/images/module.grid/page-last-disabled.gif); + cursor:default; +} +.app_grid_pDC___gray +{ + width :35px; + height :18px; + margin-left :5px; + margin-right :5px; + border :1px solid #919B9C; + text-align :center; +} +/* gray END */ + +/* orange BEGIN */ +.app_grid_headerBar___orange +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #FF9D3F; + border-bottom:0px solid red; + /*background-color:#E8E8E8;*/ + background :url(../core/images/grid.title.orange.gif); + background-position:0 -10; +} +.app_grid_table___orange +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___orange +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #FF9D3F; + background-color:#D0DEF0; + background :url(../core/images/grid.title.orange.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; +} +.app_grid_data___orange +{ + padding : 5px; + border : 1px solid #FFB46B; + color : #333; + overflow: auto; + background-color:#FFF; +} +.app_grid_data___orange select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___orange +{ + background-color:#FFB164; + border-color :#FF9D3F; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +/* orange END */ + +/* violet BEGIN */ +.app_grid_headerBar___violet +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #A295C4; + border-bottom:0px solid red; + /*background-color:#E8E8E8;*/ + background :url(../core/images/grid.title.violet.gif); + background-position:0 -10; +} +.app_grid_table___violet +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___violet +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #A295C4; + background :url(../core/images/grid.title.violet.gif); + text-align :center; + padding :4px; + height :25px; + color :#000; + cursor :default; +} +.app_grid_data___violet +{ + padding : 5px; + border : 1px solid #BBB1D4; + color : #333; + overflow: auto; + backgroundColor:#FFF; +} +.app_grid_data___violet select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___violet +{ + background-color:#B1A6CD; + border-color :#A295C4; + text-align:center; + font-size:7pt; + color :#000; + cursor :default; +} +.app_grid_pDf___violet, .app_grid_pDp___violet, .app_grid_pDn___violet, .app_grid_pDl___violet, .app_grid_pDfDisabled___violet, .app_grid_pDpDisabled___violet, .app_grid_pDnDisabled___violet, .app_grid_pDlDisabled___violet +{ + width:16px; + height:16px; + text-decoration:none; + padding-left:7px; + padding-right:7px; + margin-left:3px; + margin-right:3px; + overflow:none; + background-repeat: no-repeat; + font:normal 11px sans-serif; +} +.app_grid_pDf___violet +{ + background:url(../core/images/module.grid/page-first.gif); +} +.app_grid_pDf___violet:hover +{ + background:url(../core/images/module.grid/page-first-disabled.gif); +} +.app_grid_pDfDisabled___violet +{ + background:url(../core/images/module.grid/page-first-disabled.gif); +} + +.app_grid_pDp___violet +{ + background:url(../core/images/module.grid/page-prev.gif); +} +.app_grid_pDp___violet:hover +{ + background:url(../core/images/module.grid/page-prev-disabled.gif); +} +.app_grid_pDpDisabled___violet +{ + background:url(../core/images/module.grid/page-prev-disabled.gif); +} + +.app_grid_pDn___violet +{ + background:url(../core/images/module.grid/page-next.gif); +} +.app_grid_pDn___violet:hover +{ + background:url(../core/images/module.grid/page-next-disabled.gif); +} +.app_grid_pDnDisabled___violet +{ + background:url(../core/images/module.grid/page-next-disabled.gif); +} + +.app_grid_pDl___violet +{ + background:url(../core/images/module.grid/page-last.gif); +} +.app_grid_pDl___violet:hover +{ + background:url(../core/images/module.grid/page-last-disabled.gif); +} +.app_grid_pDlDisabled___violet +{ + background:url(../core/images/module.grid/page-last-disabled.gif); +} +.app_grid_pDC___violet +{ + width :35px; + height :18px; + margin-left :5px; + margin-right :5px; + border :1px solid #919B9C; + text-align :center; + /*border-left:3px solid #919B9C;*/ +} +/* violet END */ + +/* green BEGIN */ +.app_grid_headerBar___green +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #3C7F60; + border-bottom:0px solid red; + background :url(../core/images/grid.title.green.gif); + background-position:0 -10; + color:white; +} +.app_grid_table___green +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___green +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #3C7F60; + background :url(../core/images/grid.title.green.gif); + text-align :center; + padding :4px; + height :25px; + color :#fff; + cursor :default; +} +.app_grid_data___green +{ + padding : 5px; + border : 1px solid #AAD7C2; + color : #000; + overflow: auto; + background-color:#E8F4EE; +} +.app_grid_data___green select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___green +{ + background-color:#418A68; + border-color :#3C7F60; + text-align:center; + font-size:7pt; + color :#fff; + cursor :default; +} +/* green END */ + + +/* greenLight BEGIN */ +.app_grid_headerBar___greenLight +{ + height:17px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + padding-top:3; + padding-bottom:1; + text-align:center; + border:1px solid #A7C2B6; + border-bottom:0px solid red; + background :url(../core/images/grid.title.greenLight.gif); + background-position:0 -10; + color:#000; +} +.app_grid_table___greenLight +{ + font :normal 11px arial,tahoma,helvetica,sans-serif; + width :100%; + border-collapse:collapse; + margin :0px; +} +.app_grid_title___greenLight +{ + font:normal 8pt tahoma,helvetica,sans-serif; + border :1px solid #A7C2B6; + background :url(../core/images/grid.title.greenLight.gif); + text-align :center; + padding :4px; + height :25px; + color :#666; + cursor :default; +} +.app_grid_data___greenLight +{ + padding : 5px; + border : 1px solid #dcdcdc; + color : #000; + overflow: auto; + background-color:#fff; +} +.app_grid_data___greenLight select +{ + font:normal 8pt Tahoma,MiscFixed; + width:100%; +} +.app_grid_bg1___greenLight +{ + background-color:#B6CBC1; + border-color :#A7C2B6; + text-align:center; + font-size:7pt; + color :#fff; + cursor :default; +} +/* greenLight END */ + +/* Theme leimnud.module.grid END */ + +/* Theme leimnud.module.grid.paginator BEGIN */ +.app_grid_paginatorHeader___gray +{ + font:normal 8pt Tahoma,MiscFixed; + color:black; + padding:10px; + text-align:center; +} +.app_grid_paginatorLink___gray +{ + background-color:#E0E0E0; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #CBCBCB; + color:black; + cursor:hand; + text-decoration:none; + background :url(../core/images/grid.title.gray.gif); + background-position:0 -10; +} +.app_grid_paginatorLink___gray:hover +{ + background-color:#FFF; + border:1px solid #66667E; + color:#66667E; +} +.app_grid_paginatorLinkSelected___gray +{ + background-color:#fff; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #CBCBCB; + color:black; + cursor:hand; + text-decoration:none; + cursor:default; +} + +/* Violet */ + +.app_grid_paginatorHeader___violet +{ + font:normal 8pt Tahoma,MiscFixed; + color:black; + padding:10px; + text-align:center; +} +.app_grid_paginatorLink___violet +{ + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #A295C4; + color:black; + cursor:hand; + text-decoration:none; + background :url(../core/images/grid.title.violet.gif); + background-position:0 -10; +} +.app_grid_paginatorLink___violet:hover +{ + background-color:#FFF; + border:1px solid #A295C4; + color:#66667E; +} +.app_grid_paginatorLinkSelected___violet +{ + background-color:#fff; + padding-left:3px; + padding-right:3px; + margin:2px; + border:1px solid #A295C4; + color:black; + cursor:hand; + text-decoration:none; + cursor:default; +} +/* Theme leimnud.module.grid.paginator END */ + +/* Theme leimnud.module.app.button BEGIN */ +.module_app_button___gray +{ + font:normal 8pt Tahoma,sans-serif; + border:1px solid #afafaf; + margin-left:2px; + color:black; + cursor:pointer; + background :url(../core/images/grid.title.gray.gif); + background-position:0 0; +} +.module_app_buttonHover___gray +{ + border:1px solid #AAA; + background-position:0 -8; +} +.module_app_buttonDisabled___gray +{ + font:normal 8pt Tahoma,sans-serif; + border:1px solid #9f9f9f; + background-position:0 -10; + color:#9f9f9f; + cursor:default; +} + +/* Theme leimnud.module.app.button END */ +/* Theme leimnud.module.app.input BEGIN */ +.module_app_input___gray +{ + border:1px solid #AAA; + margin-left:2px; + background: #FFFFFF url(../core/images/input_back.gif) repeat-x; + background-position:0 0; + color :#333333; + font :normal 8pt sans-serif; +} +.module_app_inputHover___gray +{ + border:1px solid #AAA; +} +.module_app_inputDisabled___gray +{ + border:1px solid #9f9f9f; + color:#9f9f9f; +} + +/* Theme leimnud.module.app.input END */ + + + +/* Theme leimnud.module.rss BEGIN */ + + +.module_rss_container___gray, .module_rss_title___gray, .module_rss_header___gray, .module_rss_separator___gray, .module_rss_item___gray +{ + border:1px solid #AAA; +} + +.module_rss_title___gray, .module_rss_header___gray, .module_rss_itemHeader___gray +{ + background :url(../core/images/grid.title.gray.gif); +} +.module_rss_itemContainer___gray +{ + border-top:1px solid #cbcbcb; + overflow:hidden; + padding:2px; + background-color:#EEE; +} +.module_rss_container___gray, .module_rss_separator_gray +{ + background-color:#DFDFDF; +} +.module_rss_container___gray +{ + padding:3px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + width:200px; +} +.module_rss_title___gray +{ + border-bottom-width:0px; + text-align :center; + padding :4px; + color :#000; + cursor :default; + background-position:0 0; +} +.module_rss_header___gray +{ + padding:1px; + text-align:right; + border-bottom-width:0px; + background-position:0 -10; +} +.module_rss_separator___gray +{ + border-bottom-width:0px; + padding:1px; + padding-left:5px; + padding-right:5px; + overflow:hidden; +} +.module_rss_item___gray +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_itemLast___gray +{ + border-bottom-width:1px; +} +.module_rss_itemHeader___gray +{ + padding:5px; + background-position:0 -10; + position:relative; + cursor:pointer; +} +.module_rss_itemOver +{ + background-position:0 -50; +} +.module_rss_itemButtons___gray +{ + position:absolute; + top:1px; + right:1px; +} +.module_rss_itemDescription___gray +{ + +} +.module_rss_itemLink___gray +{ + text-align:right; + padding-top:10px; +} +/* Theme leimnud.module.rss END */ + +/* Theme leimnud.module.rss BEGIN */ + + +.module_rss_container___greenLight, .module_rss_title___greenLight, .module_rss_header___greenLight, .module_rss_separator___greenLight, .module_rss_item___greenLight +{ + border:1px solid #8EB9CF; +} + +.module_rss_title___greenLight, .module_rss_header___greenLight, .module_rss_itemHeader___greenLight +{ + background :url(../core/images/grid.title.greenLight.gif); +} +.module_rss_itemContainer___greenLight +{ + border-top:1px solid #8EB9CF; + overflow:hidden; + padding:2px; + background-color:#FAFAFA; +} +.module_rss_container___greenLight, .module_rss_separator_greenLight +{ + background-color:#C6D5E0; +} +.module_rss_container___greenLight +{ + padding:3px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + width:300px; +} +.module_rss_title___greenLight +{ + border-bottom-width:0px; + text-align :center; + padding :4px; + color :#000; + cursor :default; + background-position:0 0; +} +.module_rss_header___greenLight +{ + padding:1px; + text-align:right; + border-bottom-width:0px; + background-position:0 -10; +} +.module_rss_separator___greenLight +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_item___greenLight +{ + border-bottom-width:0px; + overflow:hidden; +} +.module_rss_itemLast___greenLight +{ + border-bottom-width:1px; +} +.module_rss_itemHeader___greenLight +{ + padding:5px; + background-position:0 -10; + position:relative; + cursor:pointer; +} +.module_rss_itemOver +{ + background-position:0 -50; +} +.module_rss_itemButtons___greenLight +{ + position:absolute; + top:1px; + right:1px; +} +.module_rss_itemDescription___greenLight +{ + +} +.module_rss_itemLink___greenLight +{ + text-align:right; +} +.module_rss_itemTitle___greenLight +{ + color:#3F657F; +} +/* Theme leimnud.module.rss END */ diff --git a/gulliver/js/maborak/samples/style.panel.css b/gulliver/js/maborak/samples/style.panel.css new file mode 100644 index 000000000..e219ebb63 --- /dev/null +++ b/gulliver/js/maborak/samples/style.panel.css @@ -0,0 +1,444 @@ +/* Theme processmaker */ +.app_menuRight_container___processmaker +{ + position:absolute; + border:1px solid #28427E; + background-color:#FBFFF2; + overflow:hidden; + z-index:10000; +} +.app_menuRight_shadow___processmaker +{ + position:absolute; + border:1px solid black; + background-color:black; + overflow:hidden; + z-index:9999; + opacity:0.2; + filter:alpha(opacity=20); +} +.app_menuRight_separator___processmaker +{ + padding:0; + margin:0; + position:relative; + cursor:default; + border-top:1px solid #28437E; + border-bottom:1px solid white; + overflow:hidden; +} +.app_menuRight_option___processmaker, .app_menuRight_option_over___processmaker +{ + padding:0; + margin:0; + position:relative; + cursor:default; + color:black; + background-color:""; + height:29; + overflow:hidden; + border:0px solid #FBFFF2; +} +.app_menuRight_option_over___processmaker +{ + //background-image:url(/images/onmouseSilver.jpg); + background-color:#D6D6D6; + background-repeat:repeat-x; +} +.app_menuRight_option_image___processmaker, .app_menuRight_option_image_over___processmaker +{ + width :26; + height :31; + padding :0; + position:absolute; + overflow:hidden; + cursor :default; + left :0; + top :0; + background-color:#D6D6D6; + border-right:1px solid #C3C0BB; +} +.app_menuRight_option_image_over___processmaker +{ + background:transparent; + border-right:0px solid white; +} +.app_menuRight_option_image_element___processmaker +{ + position:absolute; + top:2; +} +.app_menuRight_option_text___processmaker +{ + padding :0; + font :normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor :default; + left :30; + top :8; + overflow:hidden; +} + +/* leimnud.app.menuRight CSS end */ + +/* Processmaker CSS begin */ +.pm_separator___processmaker +{ + +} +.pm_separatorOn___processmaker +{ + +} +.pm_separatorOff___processmaker,.pm_separatorOn___processmaker +{ + height: 7px; + cursor:pointer; + text-align:center; + overflow:hidden; +} +.pm_separatorDOff___processmaker,.pm_separatorDOn___processmaker, .pm_separatorOver___processmaker, .pm_separatorOut___processmaker +{ + height:7px; + width:100%; + background-color:#C1D2EE; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + border-width:1px 0pt; + overflow:hidden; +} +.pm_separatorDOff___processmaker +{ + background:url(../core/images/separator.up.gif); + background-repeat:no-repeat; + background-position:50% 2; + +} +.pm_separatorDOn___processmaker +{ + background:url(../core/images/separator.down.gif); + background-repeat:no-repeat; + background-position:50% 50%; +} +.pm_separatorOver___processmaker +{ + background-color:#C1D2EE; +} +.pm_separatorOut___processmaker +{ + background-color:buttonface; +} + +/* Processmaker CSS end */ +/* processmap Theme.Task begin */ +/*theme firefox begin*/ +.processmap_task___firefox +{ + position : absolute; + height : 30; + width : 150; + background-color: #006699; + border : 1px solid #006699; + z-index : 10; + overflow : hidden; + cursor : move; +} +.processmap_task_label___firefox +{ + color:white; + text-align:center; + cursor:text; + padding-top:11; +} +.processmap_text___firefox +{ + position : absolute; + cursor : move; + background-color:red; +} +.processmap_title___firefox +{ + +} + /*theme firefox end*/ + + /*theme processmap begin*/ +.processmap_task___processmaker +{ + position : absolute; + height : 40; + height : 38; + width : 171; + width : 164; + z-index : 10; + overflow : hidden; + cursor : move; + /*background : url(/core/jscripts/processmap/core/images/bg_task.gif); + background : url(/images/fondotask.png);*/ + //background-color:#006699; + //background-color:#6F6F6F; + background : url(/images/borderTask.gif); + background-color:#0576C4; + vertical-align:middle; + display:table-cell; +} +.processmap_task_label___processmaker +{ + color:#FFF; + text-align:center; + /*position:absolute;*/ + margin:10; + vertical-align:middle; + cursor:move; +} +.processmap_text___processmaker +{ + position : absolute; + z-index : 10; + cursor : move; + font : bold 8pt Tahoma,MiscFixed; +} +.processmap_title___processmaker +{ + position :absolute; + cursor :move; + font :bold 13pt Tahoma,MiscFixed; +} + /*theme processmap end*/ +/* processmap Theme.Task end */ + +/* processmap Theme.Panels begin */ +.panel_containerWindow___processmaker{ + border: 1px solid #C0C0C0; + border: 1px solid #1983BD; + border: 1px solid #66667E; + oveflow:hidden; + /*border: 1px solid #5394BF; + border-left:1px solid #8BBDDF; + border-top:1px solid #8BBDDF;*/ +} +.panel_iframe___processmaker{ + width:100%; + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_backend___processmaker{ + width:100%; + height:100%; + position:absolute; + background-color:white; + overflow:hidden; + z-index:1; + top:0px; + left:0px; +} +.panel_frontend___processmaker{ + /*width: 100%;*/ + height: 100%; + position: absolute; + background-color: #E8F2F7; + background-color:#E0DFE3; + /*background-color:#59A5D9;*/ + overflow: hidden; + padding:0px; + margin:0px; + z-index: 2; + top: 0px; + left: 0px; +} +.panel_titleBar___processmaker{ + position:relative; + height:23px; + overflow:hidden; + background-color:white; + background-image: url('/images/panel_title.jpg'); + background-image: url('../core/images/panel.bg.title.1x23.gif'); + background-repeat:repeat-x; + background-position:0 -1; + border-bottom:0px solid #DBE0E5; +} +.panel_title___processmaker{ + text-align: center; + /*width: 100%;*/ + height: 23px; + color: #000; + /*color:#FFF;*/ + font: bold 8pt tahoma, MiscFixed; + padding-left: 5px; + padding-top: 5px; + z-index: 1; +} +.panel_close___processmaker{ + position:absolute; + top:4px; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../core/images/panel.close.static.gif); +} +.panel_roll___processmaker{ + position:absolute; + top:4px; + font:normal 0pt tahoma; + padding:0px; + border:0px solid red; + z-index:2; + cursor:pointer; + background:url(../core/images/roll.static.gif); + background-repeat:no-repeat; +} +.panel_resize___processmaker{ + position:absolute; + right:1px; + bottom:1px; + width:11px; + height:11px; + overflow:hidden; + background:url(../core/images/panel.resize.11x11.png?rand=234); + background-repeat:no-repeat; +} +. +.panel_headerBar___processmaker{ + position:relative; + height:25px; + overflow:hidden; + background-color:transparent; +} +.panel_shadow___processmaker{ + position:absolute; + background-color:#c0c0c0; +} +.panel_tab___processmaker{ + position:absolute; + z-index:3; + overflow:hidden; +} + + +.panel_tabH___processmaker{ + position:absolute; +} +.panel_tabOptionH___processmaker{ + text-align:center; + font:normal 8pt Tahoma,MiscFixed; + position:absolute; + cursor:pointer; + border:1px solid #919B9C; + background-color:#F9F9F9; + color:black; + height:20px; + max-height:9px; + overflow:hidden; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; +} +.panel_tabOptionOverH___processmaker{ + cursor:pointer; +} +.panel_tabOptionSelectedH___processmaker, .panel_tabOptionOverH___processmaker, .panel_tabOptionSelectedOverH___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + border-bottom:1px solid #F9F9F9; + border-top-color:#E68B2C; + background-color: #FBFFF2; + background-color: #F9F9F9; + color:#000000; + text-align: center; + position: absolute; + background-image: url('../core/images/panel.tabSelected.1x3.gif'); + background-repeat:repeat-x; + background-position:0 -1; + height:22px; + max-height:10px; + overflow:hidden; +/* -moz-border-radius-topleft:4px; + -moz-border-radius-topright:4px;*/ + +} +.panel_tabOptionSelectedOverH___processmaker{ +} + + + + +.panel_tabOption___processmaker{ + text-align:left; + font:normal 8pt Tahoma,MiscFixed; + border:1px solid #A3A2BC; + border: 1px solid #FF9900; + position:absolute; + background-color:#FFE6BF; + cursor:pointer; + color:black; +} +.panel_tabOptionOver___processmaker{ + font:normal 8pt Tahoma,MiscFixed; + cursor:pointer; + text-align:left; + border:1px solid #FF9900; + color:#666666; + background-color:white; +} +.panel_tabOptionSelected___processmaker, .panel_tabOptionSelectedOver___processmaker{ + font:bold 8pt Tahoma,MiscFixed; + border: 1px solid #FF9900; + border-right:1px solid #FFF; + background-color: #FBFFF2; + color:#000000; + text-align: left; + position: absolute; + +} +.panel_tabOptionSelectedOver___processmaker{ + color:#EA560F; + + +} +.panel_content___processmaker{ + position: relative; + color: black; + font: normal 8pt Tahoma,MiscFixed; + text-align: justify; + border: 1px solid #A3A2BC; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + /*border-left:1px solid #1983BD; + border-top:1px solid #1983BD; + border-right:1px solid #59A5D9; + border-bottom:1px solid #59A5D9;*/ + background-color: #E8F2F7; + background-color: #FFFFFF; + background-color: #F9F9F9; + overflow: auto; + padding:0px; + margin:0px; +} +.panel_statusBar___processmaker{ + position:relative; + overflow:hidden; + width:100%; + font:normal 8pt Tahoma,MiscFixed; + padding:0px; + margin:0px; + height:20px; + /*background-color:white;*/ + background-color:transparent; +} +.panel_status___processmaker +{ + text-align:center; + padding:2; + padding-left:5px; + color:#666666; + height:100%; +} +/* processmap Theme.Panels end */ \ No newline at end of file diff --git a/gulliver/js/maborak/samples/xmlform.html b/gulliver/js/maborak/samples/xmlform.html new file mode 100644 index 000000000..547388c36 --- /dev/null +++ b/gulliver/js/maborak/samples/xmlform.html @@ -0,0 +1,23 @@ + + + + + + + + +
    + + diff --git a/gulliver/js/md5/core/md5.js b/gulliver/js/md5/core/md5.js new file mode 100755 index 000000000..9a21d8683 --- /dev/null +++ b/gulliver/js/md5/core/md5.js @@ -0,0 +1,248 @@ +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +var hex_md5 = md5 = function(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} +function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} +function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} +function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } +function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } +function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Calculate the HMAC-MD5, of a key and some data + */ +function core_hmac_md5(key, data) +{ + var bkey = str2binl(key); + if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str) +{ + var bin = new Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} diff --git a/gulliver/js/thirdparty/krumo/krumo.js b/gulliver/js/thirdparty/krumo/krumo.js new file mode 100755 index 000000000..035fe44c0 --- /dev/null +++ b/gulliver/js/thirdparty/krumo/krumo.js @@ -0,0 +1,37 @@ +/** JavaScript routines for Krumo +* @version $Id: krumo.js 22 2007-12-02 07:38:18Z Mrasnika $ +* @link http://sourceforge.net/projects/krumo +*/ + +function krumo() {} +krumo.reclass = function(el, className) { + if (el.className.indexOf(className) < 0) { + el.className += (' ' + className); + } +} +krumo.unclass = function(el, className) { + if (el.className.indexOf(className) > -1) { + el.className = el.className.replace(className, ''); + } +} +krumo.toggle = function(el) { + var ul = el.parentNode.getElementsByTagName('ul'); + for (var i=0; i + * @Date Oct 5th, 2009 La Paz - Bolivia + */ + +var G_CALENDAR_CURRENT_OBJ = null; +var G_CALENDAR_MEM_OFFSET; + +var NeyekCalendar = function(t, editable){ + + this.target = (typeof(t) != 'undefined')? t: null; + this.editable = (typeof(editable) != 'undefined')? "1": "0"; + + this.calendarObjForForm = null; + this.oCalendar = null; + + this.lang = null; + this.mask = null; + this.showTime = false; + this.e = null; + + this.__init__ = function(initialDate, enableTime){ + + var dayClickCallbackParams = Array(this.target, this.mask, this.editable); + + this.calendarObjForForm = new DHTMLSuite.calendar({ + minuteDropDownInterval :10, + numberOfRowsInHourDropDown :5, + callbackFunctionOnDayClick : {"func": 'getDateFromCalendar', "params": dayClickCallbackParams}, + isDragable :true, + displayTimeBar :this.showTime + }); + + //this.calendarObjForForm.setCallbackFunctionOnClose('myOtherFunction'); + + this.oCalendar = new DHTMLSuite.calendarModel({ + initialYear :initialDate.year, + initialMonth :initialDate.month, + initialDay :initialDate.day + }); + + } + + this.picker = function(initialDate, mask, lang, beforeDate, afterDate, showTime, e){ + + if(G_CALENDAR_CURRENT_OBJ != null) return false; + + if(G_CALENDAR_MEM_OFFSET == 'lock') return false; + + if ( typeof(mask) != 'undefined') { + this.mask = mask; + } else { + this.mask = 'Y-m-d h:i'; + } + //alert('->'+this.mask); + if ( typeof(lang) != 'undefined') { + this.lang = lang; + } else { + this.lang = 'en'; + } + + if ( typeof(showTime) != 'undefined') { + if (showTime) { + this.showTime = true; + } else { + this.showTime = false; + } + } else { + this.showTime = false; + } + + this.__init__(initialDate); + + if ( typeof(e) != 'undefined') { + this.calendarObjForForm.e = e; + } + + if ( typeof(beforeDate) != 'undefined' && beforeDate != '') { + /* before date from it will be set such as invalid*/ + this.oCalendar.addInvalidDateRange(false,{ + year : beforeDate.year, + month : beforeDate.month, + day : beforeDate.day + }); + } + + + if ( typeof(beforeDate) != 'undefined' && beforeDate != '') { + /* after date from it will be set such as invalid*/ + this.oCalendar.addInvalidDateRange({ + year : afterDate.year, + month : afterDate.month, + day : afterDate.day + },false); + } + + /* languaje set */ + this.oCalendar.setLanguageCode(this.lang); + + this.calendarObjForForm.setCalendarModelReference(this.oCalendar); + + eInput = this.$(this.target); + eDiv = this.$(this.target+'[div]'); + + // Position the calendar right below the form input + if(this.editable === "1"){ + this.calendarObjForForm.setCalendarPositionByHTMLElement(eInput, 0, eInput.offsetHeight+2); + } else { + this.calendarObjForForm.setCalendarPositionByHTMLElement(eDiv, 0, eDiv.offsetHeight+2); + } + // Specify that the calendar should set it's initial date from the value of the input field. + submask = this.mask; + + if (submask.search(/Y/) != -1 ) { + submask = submask.replace("Y", 'yyyy'); + } else { + submask = submask.replace("y", 'yy'); + } + submask = submask.replace("m", 'mm'); + submask = submask.replace("d", 'dd'); + submask = submask.replace("h", 'hh'); + submask = submask.replace("i", 'ii'); + + this.calendarObjForForm.setInitialDateFromInput(eInput, submask); + + // Adding a reference to this element so that I can pick it up in the getDateFromCalendar below(myInput is a unique key) + if(this.editable === "1"){ + this.calendarObjForForm.addHtmlElementReference(this.target, eInput); + } else { + this.calendarObjForForm.addHtmlElementReference(this.target+'[div]', eDiv); + } + + if(this.calendarObjForForm.isVisible()){ + this.calendarObjForForm.hide(); + + }else{ + // This line resets the view back to the inital display, i.e. it displays the inital month and not the month it displayed the last time it was open. + this.calendarObjForForm.resetViewDisplayedMonth(); + this.calendarObjForForm.display(); + } + + G_CALENDAR_CURRENT_OBJ = this.calendarObjForForm; + return false; + } + + this.getDateFromCalendar = function(inputArray){ + // Get back reference to form field. + var references = this.calendarObjForForm.getHtmlElementReferences(); + references.myDate.value = this.parseDateFromMask(inputArray, this.mask); //inputArray.year + '-' + inputArray.month + '-' + inputArray.day + ' ' + inputArray.hour + ':' + inputArray.minute; + this.calendarObjForForm.hide(); + return false; + } + + this.parseDateFromMask = function(inputArray, mask){ + /* inputArray is an associative array with properties + year, month, day, hour, minute */ + + /* format mask + * Y -> 2009 + * y -> 09 + * m -> 02 + * d -> 01 + * + * h -> 12 + * i -> 59 + * + * d/m/y -> 01/02/09 + * d/m/Y -> 01/02/2009 + * Y-m-d -> 2009-02-01 + * + * Y-m-d h:m -> 2009-02-01 12:59 + * + */ + + result = mask; + result = result.replace("Y", inputArray.year); + + year = new String(inputArray.year); + result = result.replace("y", year.substr(2,3)); + result = result.replace("m", inputArray.month); + result = result.replace("d", inputArray.day); + result = result.replace("h", inputArray.hour); + result = result.replace("i", inputArray.minute); + + return result; + + } + + this.$ = function(id){ + return document.getElementById(id); + } +} + +function getDateFromCalendar(inputArray, targetId, mask, editable){ + + sClear = ''; + + result = mask; + result = result.replace("Y", inputArray.year); + + year = new String(inputArray.year); + result = result.replace("y", year.substr(2,3)); + result = result.replace("m", inputArray.month); + result = result.replace("d", inputArray.day); + result = result.replace("h", inputArray.hour); + result = result.replace("i", inputArray.minute); + + document.getElementById(targetId).value = result; + if(editable !== "1"){ + document.getElementById(targetId+'[div]').innerHTML = ' '+document.getElementById(targetId).value + ' ' + sClear; + } + G_CALENDAR_CURRENT_OBJ.hide(); + + if (document.getElementById(targetId).onchange){ + try{ + document.getElementById(targetId).onchange(); + }catch(e){} + } + + G_CALENDAR_CURRENT_OBJ = null; +} + + + + + + + + +/*e2*/ +if(!window.DHTMLSuite)var DHTMLSuite=new Object();if(!String.trim)String.prototype.trim=function(){return this.replace(/^\s+|\s+$/,'')};var DHTMLSuite_funcs=new Object();if(!window.DHTML_SUITE_THEME)var DHTML_SUITE_THEME='blue';if(!window.DHTML_SUITE_THEME_FOLDER)var DHTML_SUITE_THEME_FOLDER='../themes/';if(!window.DHTML_SUITE_JS_FOLDER)var DHTML_SUITE_JS_FOLDER='../js/separateFiles/';var DHTMLSuite=new Object();var standardObjectsCreated=false;DHTMLSuite.eventEls=new Array();var widgetDep=new Object();widgetDep['formValidator']=['dhtmlSuite-formUtil.js'];widgetDep['paneSplitter']=['dhtmlSuite-paneSplitter.js','dhtmlSuite-paneSplitterModel.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['menuBar']=['dhtmlSuite-menuBar.js','dhtmlSuite-menuItem.js','dhtmlSuite-menuModel.js'];widgetDep['windowWidget']=['dhtmlSuite-windowWidget.js','dhtmlSuite-resize.js','dhtmlSuite-dragDropSimple.js','ajax.js','dhtmlSuite-dynamicContent.js'];widgetDep['colorWidget']=['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js'];widgetDep['colorSlider']=['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js','dhtmlSuite-slider.js'];widgetDep['colorPalette']=['dhtmlSuite-colorWidgets.js','dhtmlSuite-colorUtil.js'];widgetDep['calendar']=['dhtmlSuite-calendar.js','dhtmlSuite-dragDropSimple.js'];widgetDep['dragDropTree']=['dhtmlSuite-dragDropTree.js'];widgetDep['slider']=['dhtmlSuite-slider.js'];widgetDep['dragDrop']=['dhtmlSuite-dragDrop.js'];widgetDep['imageEnlarger']=['dhtmlSuite-imageEnlarger.js','dhtmlSuite-dragDropSimple.js'];widgetDep['imageSelection']=['dhtmlSuite-imageSelection.js'];widgetDep['floatingGallery']=['dhtmlSuite-floatingGallery.js','dhtmlSuite-mediaModel.js'];widgetDep['contextMenu']=['dhtmlSuite-contextMenu.js','dhtmlSuite-menuBar.js','dhtmlSuite-menuItem.js','dhtmlSuite-menuModel.js'];widgetDep['dynamicContent']=['dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['textEdit']=['dhtmlSuite-textEdit.js','dhtmlSuite-textEditModel.js','dhtmlSuite-listModel.js'];widgetDep['listModel']=['dhtmlSuite-listModel.js'];widgetDep['resize']=['dhtmlSuite-resize.js'];widgetDep['dragDropSimple']=['dhtmlSuite-dragDropSimple.js'];widgetDep['dynamicTooltip']=['dhtmlSuite-dynamicTooltip.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['modalMessage']=['dhtmlSuite-modalMessage.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['tableWidget']=['dhtmlSuite-tableWidget.js','ajax.js'];widgetDep['progressBar']=['dhtmlSuite-progressBar.js'];widgetDep['tabView']=['dhtmlSuite-tabView.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['infoPanel']=['dhtmlSuite-infoPanel.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['form']=['dhtmlSuite-formUtil.js','dhtmlSuite-dynamicContent.js','ajax.js'];widgetDep['autoComplete']=['dhtmlSuite-autoComplete.js','ajax.js'];widgetDep['chainedSelect']=['dhtmlSuite-chainedSelect.js','ajax.js'];var depCache=new Object();DHTMLSuite.include=function(widget){if(!widgetDep[widget]){alert('Cannot find the files for widget '+widget+'. Please verify that the name is correct');return} +var files=widgetDep[widget];for(var no=0;no');document.write('');depCache[files[no]]=true}}} +DHTMLSuite.discardElement=function(element){element=DHTMLSuite.commonObj.getEl(element);var gBin=document.getElementById('IELeakGBin');if(!gBin){gBin=document.createElement('DIV');gBin.id='IELeakGBin';gBin.style.display='none';document.body.appendChild(gBin)} +gBin.appendChild(element);gBin.innerHTML=''} +DHTMLSuite.createStandardObjects=function(){DHTMLSuite.clientInfoObj=new DHTMLSuite.clientInfo();DHTMLSuite.clientInfoObj.init();if(!DHTMLSuite.configObj){DHTMLSuite.configObj=new DHTMLSuite.config();DHTMLSuite.configObj.init()} +DHTMLSuite.commonObj=new DHTMLSuite.common();DHTMLSuite.variableStorage=new DHTMLSuite.globalVariableStorage();;DHTMLSuite.commonObj.init();DHTMLSuite.domQueryObj=new DHTMLSuite.domQuery();DHTMLSuite.commonObj.addEvent(window,'unload',function(){DHTMLSuite.commonObj.__clearMemoryGarbage()});standardObjectsCreated=true} +DHTMLSuite.config=function(){var imagePath;var cssPath;var defaultCssPath;var defaultImagePath} +DHTMLSuite.config.prototype={init:function(){this.imagePath=DHTML_SUITE_THEME_FOLDER+DHTML_SUITE_THEME+'/images/';this.cssPath=DHTML_SUITE_THEME_FOLDER+DHTML_SUITE_THEME+'/css/';this.defaultCssPath=this.cssPath;this.defaultImagePath=this.imagePath},setCssPath:function(newCssPath){this.cssPath=newCssPath},resetCssPath:function(){this.cssPath=this.defaultCssPath},resetImagePath:function(){this.imagePath=this.defaultImagePath},setImagePath:function(newImagePath){this.imagePath=newImagePath}} +DHTMLSuite.globalVariableStorage=function(){var menuBar_highlightedItems;this.menuBar_highlightedItems=new Array();var arrayDSObjects;var arrayOfDhtmlSuiteObjects;this.arrayDSObjects=new Array();this.arrayOfDhtmlSuiteObjects=this.arrayDSObjects;var ajaxObjects;this.ajaxObjects=new Array()} +DHTMLSuite.globalVariableStorage.prototype={} +DHTMLSuite.common=function(){var loadedCSSFiles;var cssCacheStatus;var eventEls;var isOkToSelect;this.okToSelect=true;this.cssCacheStatus=true;this.eventEls=new Array()} +DHTMLSuite.common.prototype={init:function(){this.loadedCSSFiles=new Array()},loadCSS:function(cssFile,prefixConfigPath){if(!prefixConfigPath&&prefixConfigPath!==false)prefixConfigPath=true;if(!this.loadedCSSFiles[cssFile]){this.loadedCSSFiles[cssFile]=true;var lt=document.createElement('LINK');if(!this.cssCacheStatus){if(cssFile.indexOf('?')>=0)cssFile=cssFile+'&';else cssFile=cssFile+'?';cssFile=cssFile+'rand='+Math.random()} +if(prefixConfigPath){lt.href=DHTMLSuite.configObj.cssPath+cssFile}else{lt.href=cssFile} +lt.rel='stylesheet';lt.media='screen';lt.type='text/css';document.getElementsByTagName('HEAD')[0].appendChild(lt)}},__setTextSelOk:function(okToSelect){this.okToSelect=okToSelect},__isTextSelOk:function(){return this.okToSelect},setCssCacheStatus:function(cssCacheStatus){this.cssCacheStatus=cssCacheStatus},getEl:function(elRef){if(typeof elRef=='string'){if(document.getElementById(elRef))return document.getElementById(elRef);if(document.forms[elRef])return document.forms[elRef];if(document[elRef])return document[elRef];if(window[elRef])return window[elRef]} +return elRef},isArray:function(el){if(el.constructor.toString().indexOf("Array")!=-1)return true;return false},getStyle:function(el,property){el=this.getEl(el);if(document.defaultView&&document.defaultView.getComputedStyle){var retVal=null;var comp=document.defaultView.getComputedStyle(el,'');if(comp){retVal=comp[property]} +return el.style[property]||retVal} +if(document.documentElement.currentStyle&&DHTMLSuite.clientInfoObj.isMSIE){var retVal=null;if(el.currentStyle)value=el.currentStyle[property];return(el.style[property]||retVal)} +return el.style[property]}, + +getLeftPos:function(el){ + if(document.getBoxObjectFor){ + if(el.tagName!='INPUT'&&el.tagName!='SELECT'&&el.tagName!='TEXTAREA') + return document.getBoxObjectFor(el).x + } + var returnValue=el.offsetLeft; + while((el=el.offsetParent)!=null){ + if(el.tagName!='HTML'){ + returnValue+= el.offsetLeft; + if(document.all)returnValue+=el.clientLeft + } + } + return returnValue +}, + +getTopPos:function(el){ + if(document.getBoxObjectFor){ + if(el.tagName!='INPUT'&&el.tagName!='SELECT'&&el.tagName!='TEXTAREA') + return document.getBoxObjectFor(el).y + } + var returnValue=el.offsetTop; + while((el=el.offsetParent)!=null){ + if(el.tagName!='HTML'){ + returnValue+=(el.offsetTop-el.scrollTop); + if(document.all)returnValue+=el.clientTop + } + } + return returnValue +}, + +sgetCookie:function(name){var start=document.cookie.indexOf(name+"=");var len=start+name.length+1;if((!start)&&(name!=document.cookie.substring(0,name.length)))return null;if(start==-1)return null;var end=document.cookie.indexOf(";",len);if(end==-1)end=document.cookie.length;return unescape(document.cookie.substring(len,end))},setCookie:function(name,value,expires,path,domain,secure){expires=expires*60*60*24*1000;var today=new Date();var expires_date=new Date(today.getTime()+(expires));var cookieString=name+"="+escape(value)+ +((expires)?";expires="+expires_date.toGMTString():"")+ +((path)?";path="+path:"")+ +((domain)?";domain="+domain:"")+ +((secure)?";secure":"");document.cookie=cookieString},deleteCookie:function(name,path,domain){if(this.getCookie(name))document.cookie=name+"="+ +((path)?";path="+path:"")+ +((domain)?";domain="+domain:"")+ +";expires=Thu,01-Jan-1970 00:00:01 GMT"},cancelEvent:function(){return false},addEvent:function(obj,type,fn,suffix){if(!suffix)suffix='';if(obj.attachEvent){if(typeof DHTMLSuite_funcs[type+fn+suffix]!='function'){DHTMLSuite_funcs[type+fn+suffix]=function(){fn.apply(window.event.srcElement)};obj.attachEvent('on'+type,DHTMLSuite_funcs[type+fn+suffix])} +obj=null} else {obj.addEventListener(type,fn,false)} +this.__addEventEl(obj)},removeEvent:function(obj,type,fn,suffix){if(obj.detachEvent){obj.detachEvent('on'+type,DHTMLSuite_funcs[type+fn+suffix]);DHTMLSuite_funcs[type+fn+suffix]=null;obj=null} else {obj.removeEventListener(type,fn,false)}},__clearMemoryGarbage:function(){if(!DHTMLSuite.clientInfoObj.isMSIE)return;for(var no=0;no';img.outerHTML=html},__evaluateJs:function(obj){obj=this.getEl(obj);var scriptTags=obj.getElementsByTagName('SCRIPT');var string='';var jsCode='';for(var no=0;no=0)?true:false;this.isFirefox=(this.browser.toLowerCase().indexOf('firefox')>=0)?true:false;this.isMSIE=(this.browser.toLowerCase().indexOf('msie')>=0)?true:false;this.isOldMSIE=(this.browser.toLowerCase().match(/msie\s[0-6]/gi))?true:false;this.isSafari=(this.browser.toLowerCase().indexOf('safari')>=0)?true:false;this.navigatorVersion=navigator.appVersion.replace(/.*?MSIE\s(\d\.\d).*/g,'$1')/1;this.isOldMSIE=(this.isMSIE&&this.navigatorVersion<7)?true:false},getBrowserWidth:function(){if(self.innerWidth)return self.innerWidth;return document.documentElement.offsetWidth},getBrowserHeight:function(){if(self.innerHeight)return self.innerHeight;return document.documentElement.offsetHeight}} +DHTMLSuite.domQuery=function(){document.getElementsByClassName=this.getElementsByClassName;document.getElementsByAttribute=this.getElementsByAttribute} +DHTMLSuite.domQuery.prototype={} + + +/*e1*/ +/* + * Adapted By @Neyek + * + **/ + +if(!window.DHTMLSuite)var DHTMLSuite=new Object();DHTMLSuite.calendarLanguageModel=function(languageCode){var monthArray;var monthArrayShort;var dayArray;var weekString;var todayString;var todayIsString;var timeString;this.monthArray=new Array();this.monthArrayShort=new Array();this.dayArray=new Array();if(!languageCode)languageCode='en';this.languageCode=languageCode;this.__setCalendarProperties()} + +DHTMLSuite.calendarLanguageModel.prototype={ +__setCalendarProperties:function(){ +switch(this.languageCode){ +case "fi": +this.monthArray =['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu','Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu']; +this.monthArrayShort=['Tam','Hel','Maa','Huh','Tou','Kes','Hei','Elo','Syy','Lok','Mar','Jou']; +this.dayArray=['Maa','Tii','Kes','Tor','Per','Lau','Sun']; +this.weekString='Viikko'; +this.todayIsString='Tänään on'; +this.todayString='Tänään'; +this.timeString='Kello'; +break; +case "ge": +this.monthArray=['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']; +this.monthArrayShort=['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez']; +this.dayArray=['Mon','Die','Mit','Don','Fre','Sam','Son']; +this.weekString='Woche'; +this.todayIsString='Heute'; +this.todayString='Heute'; +this.timeString=''; +break; +case "no": +this.monthArray=['Januar','Februar','Mars','April','Mai','Juni','Juli','August','September','Oktober','November','Desember']; +this.monthArrayShort=['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Des']; +this.dayArray=['Man','Tir','Ons','Tor','Fre','Lør','Søn']; +this.weekString='Uke'; +this.todayIsString='Dagen i dag er'; +this.todayString='I dag'; +this.timeString='Tid'; +break; +case "nl": +this.monthArray=['Januari','Februari','Maart','April','Mei','Juni','Juli','Augustus','September','Oktober','November','December']; +this.monthArrayShort=['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Aug','Sep','Okt','Nov','Dec']; +this.dayArray=['Ma','Di','Wo','Do','Vr','Za','Zo']; +this.weekString='Week'; +this.todayIsString='Vandaag'; +this.todayString='Vandaag'; +this.timeString=''; +break; +case "es": +this.monthArray=['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre']; +this.monthArrayShort =['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic']; +this.dayArray=['Lun','Mar','Mie','Jue','Vie','Sab','Dom']; +this.weekString='Semana'; +this.todayIsString='Hoy es'; +this.todayString='Hoy'; +this.timeString=''; +break; +case "pt-br": +this.monthArray=['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro']; +this.monthArrayShort=['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']; +this.dayArray=['Seg','Ter','Qua','Qui','Sex','Sáb','Dom']; +this.weekString='Sem.'; +this.todayIsString='Hoje é'; +this.todayString='Hoje'; +this.timeString=''; +break; +case "fr": +this.monthArray=['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre']; +this.monthArrayShort=['Jan','Fev','Mar','Avr','Mai','Jun','Jul','Aou','Sep','Oct','Nov','Dec']; +this.dayArray=['Lun','Mar','Mer','Jeu','Ven','Sam','Dim']; +this.weekString='Sem'; +this.todayIsString="Aujourd'hui"; +this.todayString='Aujourd'; +this.timeString=''; +break; +case "da": +this.monthArray=['januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december']; +this.monthArrayShort=['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec']; +this.dayArray=['man','tirs','ons','tors','fre','lør','søn']; +this.weekString='Uge'; +this.todayIsString='I dag er den'; +this.todayString='I dag'; +this.timeString='Tid'; +break; +case "it": +this.monthArray=['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre']; +this.monthArrayShort=['Gen','Feb','Mar','Apr','Mag','Giu','Lugl','Ago','Set','Ott','Nov','Dic']; +this.dayArray=['Lun','Mar','Mer','Gio','Ven','Sab','Dom']; +this.weekString='Sett'; +this.todayIsString='Oggi èil'; +this.todayString='Oggi èil'; +this.timeString=''; +break; +case "sv": +this.monthArray=['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December']; +this.monthArrayShort=['Jan','Feb','Mar','Apr','Maj','Jun','Jul','Aug','Sep','Okt','Nov','Dec']; +this.dayArray=['Mån','Tis','Ons','Tor','Fre','Lör','Sön']; +this.weekString='Vecka'; +this.todayIsString='Idag är det den'; +this.todayString='Idag är det den'; +this.timeString=''; +break; + +default: +this.monthArray=['January','February','March','April','May','June','July','August','September','October','November','December']; +this.monthArrayShort=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; +this.dayArray=['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; +this.weekString='Week'; +this.todayIsString=''; +this.todayString='Today'; +this.timeString='Time'; +break}}} +DHTMLSuite.calendarModel=function(inputArray){var initialDay;var initialMonth;var initialYear;var initialHour;var initialMinute;var displayedDay;var displayedMonth;var displayedYear;var displayedMinute;var displayedHour;var languageCode;var languageModel;var invalidDateRange;var weekStartsOnMonday;this.weekStartsOnMonday=true;this.languageCode='en';this.invalidDateRange=new Array();this.__createDefaultModel(inputArray)} +DHTMLSuite.calendarModel.prototype= +{setCallbackFunctionOnMonthChange:function(functionName){this.callbackFunctionOnMonthChange=functionName},addInvalidDateRange:function(fromDateAsArray,toDateAsArray){var index=this.invalidDateRange.length;this.invalidDateRange[index]=new Object();if(fromDateAsArray){fromDateAsArray.day=fromDateAsArray.day+'';fromDateAsArray.month=fromDateAsArray.month+'';fromDateAsArray.year=fromDateAsArray.year+'';if(!fromDateAsArray.month)fromDateAsArray.month=fromDateAsArray.month='1';if(!fromDateAsArray.day)fromDateAsArray.day=fromDateAsArray.day='1';if(fromDateAsArray.day.length==1)fromDateAsArray.day='0'+fromDateAsArray.day;if(fromDateAsArray.month.length==1)fromDateAsArray.month='0'+fromDateAsArray.month;this.invalidDateRange[index].fromDate=fromDateAsArray.year+fromDateAsArray.month+fromDateAsArray.day}else{this.invalidDateRange[index].fromDate=false} +if(toDateAsArray){toDateAsArray.day=toDateAsArray.day+'';toDateAsArray.month=toDateAsArray.month+'';toDateAsArray.year=toDateAsArray.year+'';if(!toDateAsArray.month)toDateAsArray.month=toDateAsArray.month='1';if(!toDateAsArray.day)toDateAsArray.day=toDateAsArray.day='1';if(toDateAsArray.day.length==1)toDateAsArray.day='0'+toDateAsArray.day;if(toDateAsArray.month.length==1)toDateAsArray.month='0'+toDateAsArray.month;this.invalidDateRange[index].toDate=toDateAsArray.year+toDateAsArray.month+toDateAsArray.day}else{this.invalidDateRange[index].toDate=false}},isDateWithinValidRange:function(inputDate){if(this.invalidDateRange.length==0)return true;var month=inputDate.month+'';if(month.length==1)month='0'+month;var day=inputDate.day+'';if(day.length==1)day='0'+day;var dateToCheck=inputDate.year+month+day;for(var no=0;no=dateToCheck)return false;if(!this.invalidDateRange[no].toDate&&this.invalidDateRange[no].fromDate<=dateToCheck)return false;if(this.invalidDateRange[no].fromDate<=dateToCheck&&this.invalidDateRange[no].toDate>=dateToCheck)return false} +return true},setInitialDateFromInput:function(inputReference,format){if(inputReference.value.length>0){if(!format.match(/^[0-9]*?$/gi)){var items=inputReference.value.split(/[^0-9]/gi);var positionArray=new Object();positionArray.m=format.indexOf('mm');if(positionArray.m==-1)positionArray.m=format.indexOf('m');positionArray.d=format.indexOf('dd');if(positionArray.d==-1)positionArray.d=format.indexOf('d');positionArray.y=format.indexOf('yyyy');positionArray.h=format.indexOf('hh');positionArray.i=format.indexOf('ii');this.initialHour='00';this.initialMinute='00';var elements=['y','m','d','h','i'];var properties=['initialYear','initialMonth','initialDay','initialHour','initialMinute'];var propertyLength=[4,2,2,2,2];for(var i=0;i=0){this[properties[i]]=inputReference.value.substr(positionArray[elements[i]],propertyLength[i])/1}}}else{var monthPos=format.indexOf('mm');this.initialMonth=inputReference.value.substr(monthPos,2)/1;var yearPos=format.indexOf('yyyy');this.initialYear=inputReference.value.substr(yearPos,4);var dayPos=format.indexOf('dd');tmpDay=inputReference.value.substr(dayPos,2);this.initialDay=tmpDay;var hourPos=format.indexOf('hh');if(hourPos>=0){tmpHour=inputReference.value.substr(hourPos,2);this.initialHour=tmpHour}else{this.initialHour='00'} +var minutePos=format.indexOf('ii');if(minutePos>=0){tmpMinute=inputReference.value.substr(minutePos,2);this.initialMinute=tmpMinute}else{this.initialMinute='00'}}} +this.__setDisplayedDateToInitialData()},__setDisplayedDateToInitialData:function(){this.displayedYear=this.initialYear;this.displayedMonth=this.initialMonth;this.displayedDay=this.initialDay;this.displayedHour=this.initialHour;this.displayedMinute=this.initialMinute},__calendarSortItems:function(a,b){return a/1-b/1},setWeekStartsOnMonday:function(weekStartsOnMonday){this.weekStartsOnMonday=weekStartsOnMonday},setLanguageCode:function(languageCode){this.languageModel=new DHTMLSuite.calendarLanguageModel(languageCode)},__isLeapYear:function(inputYear){if(inputYear%400==0||(inputYear%4==0&&inputYear%100!=0))return true;return false},getWeekStartsOnMonday:function(){return this.weekStartsOnMonday},__createDefaultModel:function(inputArray){var d=new Date();this.initialYear=d.getFullYear();this.initialMonth=d.getMonth()+1;this.initialDay=d.getDate();this.initialHour=d.getHours();if(inputArray){if(inputArray.initialYear)this.initialYear=inputArray.initialYear;if(inputArray.initialMonth)this.initialMonth=inputArray.initialMonth;if(inputArray.initialDay)this.initialDay=inputArray.initialDay;if(inputArray.initialHour)this.initialHour=inputArray.initialHour;if(inputArray.initialMinute)this.initialMinute=inputArray.initialMinute;if(inputArray.languageCode)this.languageCode=inputArray.languageCode} +this.displayedYear=this.initialYear;this.displayedMonth=this.initialMonth;this.displayedDay=this.initialDay;this.displayedHour=this.initialHour;this.displayedMinute=this.initialMinute;this.languageModel=new DHTMLSuite.calendarLanguageModel()},__getDisplayedDay:function(){return this.displayedDay},__getDisplayedHourWithLeadingZeros:function(){var retVal=this.__getDisplayedHour()+'';if(retVal.length==1)retVal='0'+retVal;return retVal},__getDisplayedMinuteWithLeadingZeros:function(){var retVal=this.__getDisplayedMinute()+'';if(retVal.length==1)retVal='0'+retVal;return retVal},__getDisplayedDayWithLeadingZeros:function(){var retVal=this.__getDisplayedDay()+'';if(retVal.length==1)retVal='0'+retVal;return retVal},__getDisplayedMonthNumberWithLeadingZeros:function(){var retVal=this.__getDisplayedMonthNumber()+'';if(retVal.length==1)retVal='0'+retVal;return retVal},__getDisplayedYear:function(){return this.displayedYear},__getDisplayedHour:function(){if(!this.displayedHour)this.displayedHour=0;return this.displayedHour},__getDisplayedMinute:function(){if(!this.displayedMinute)this.displayedMinute=0;return this.displayedMinute},__getDisplayedMonthNumber:function(){return this.displayedMonth},__getInitialDay:function(){return this.initialDay},__getInitialYear:function(){return this.initialYear},__getInitialMonthNumber:function(){return this.initialMonth},__getMonthNameByMonthNumber:function(monthNumber){return this.languageModel.monthArray[monthNumber-1]},__moveOneYearBack:function(){this.displayedYear--},__moveOneYearForward:function(){this.displayedYear++},__moveOneMonthBack:function(){this.displayedMonth--;if(this.displayedMonth<1){this.displayedMonth=12;this.displayedYear--}},__moveOneMonthForward:function(){this.displayedMonth++;if(this.displayedMonth>12){this.displayedMonth=1;this.displayedYear++}},__setDisplayedYear:function(year){var success=year!=this.displayedYear;this.displayedYear=year;return success +},__setDisplayedMonth:function(month){var success=month!=this.displayedMonth;this.displayedMonth=month;return success},__setDisplayedDay:function(day){this.displayedDay=day},__setDisplayedHour:function(hour){this.displayedHour=hour/1},__setDisplayedMinute:function(minute){this.displayedMinute=minute/1},__getPreviousYearAndMonthAsArray:function(){var month=this.displayedMonth-1;var year=this.displayedYear;if(month==0){month=12;year=year-1} +var retArray=[year,month];return retArray},__getNumberOfDaysInCurrentDisplayedMonth:function(){return this.__getNumberOfDaysInAMonthByMonthAndYear(this.displayedYear,this.displayedMonth)},__getNumberOfDaysInAMonthByMonthAndYear:function(year,month){var daysInMonthArray=[31,28,31,30,31,30,31,31,30,31,30,31];var daysInMonth=daysInMonthArray[month-1];if(daysInMonth==28){if(this.__isLeapYear(year))daysInMonth=29} +return daysInMonth/1},__getStringWeek:function(){return this.languageModel.weekString},__getDaysMondayToSunday:function(){return this.languageModel.dayArray},__getDaysSundayToSaturday:function(){var retArray=this.languageModel.dayArray.concat();var lastDay=new Array(retArray[retArray.length-1]);retArray.pop();return lastDay.concat(retArray)},__getWeekNumberFromDayMonthAndYear:function(year,month,day){day=day/1;year=year/1;month=month/1;if(!this.weekStartsOnMonday)return this.__getWeekNumberFromDayMonthAndYear_S(year,month,day);var a=Math.floor((14-(month))/12);var y=year+4800-a;var m=(month)+(12*a)-3;var jd=day+Math.floor(((153*m)+2)/5)+ +(365*y)+Math.floor(y/4)- Math.floor(y/100)+ +Math.floor(y/400)- 32045;var d4=(jd+31741-(jd%7))%146097%36524%1461;var L=Math.floor(d4/1460);var d1=((d4-L)%365)+L;NumberOfWeek=Math.floor(d1/7)+1;return NumberOfWeek},__getWeekNumberFromDayMonthAndYear_S:function(year,month,day){month--;now=Date.UTC(year,month,day+1,0,0,0);var firstDay=new Date();firstDay.setYear(year);firstDay.setMonth(0);firstDay.setDate(1);then=Date.UTC(year,0,1,0,0,0);var Compensation=firstDay.getDay();if(Compensation > 3)Compensation-= 4;else Compensation+= 3;NumberOfWeek= Math.round((((now-then)/86400000)+Compensation)/7);return NumberOfWeek},__getDayNumberFirstDayInYear:function(year){var d=new Date();d.setFullYear(year);d.setDate(1);d.setMonth(0);return d.getDay()},__getRemainingDaysInPreviousMonthAsArray:function(){var d=new Date();d.setFullYear(this.displayedYear);d.setDate(1);d.setMonth(this.displayedMonth-1);var dayStartOfMonth=d.getDay();if(this.weekStartsOnMonday){if(dayStartOfMonth==0)dayStartOfMonth=7;dayStartOfMonth--} +var previousMonthArray=this.__getPreviousYearAndMonthAsArray();var daysInPreviousMonth=this.__getNumberOfDaysInAMonthByMonthAndYear(previousMonthArray[0],previousMonthArray[1]);var returnArray=new Array();for(var no=0;no';divNext.onmouseover=function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoverUpAndDownArrowsInDropDownMinutes(e)} ;divNext.onmouseout =function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoutUpAndDownArrowsInDropDownMinutes(e)} ;DHTMLSuite.commonObj.__addEventEl(divNext);this.divElMinuteDropdown.appendChild(divNext);if(60/this.minuteDropDownInterval< this.numberOfRowsInMinuteDropDown){divPrevious.style.display='none';divNext.style.display='none'}},__populateMinutesInsideDropDownMinutes:function(){var ind=this.objectIndex;this.divElMinuteDropdownParent.innerHTML='';if(60/this.minuteDropDownInterval< this.numberOfRowsInMinuteDropDown){startMinute=0}else{var startMinute=Math.max(0,(this.calendarModelReference.__getDisplayedMinute()-Math.round(this.numberOfRowsInMinuteDropDown/2)));startMinute+=(this.minuteDropDownOffsetInMinute*this.minuteDropDownInterval) +if(startMinute<0){startMinute+=this.minuteDropDownInterval;this.minuteDropDownOffsetInMinute++} +if(startMinute+(this.numberOfRowsInMinuteDropDown*this.minuteDropDownInterval)>60){/*start minute in drop down+number of records shown*interval larger than 60-> adjust it*/ +startMinute-=this.minuteDropDownInterval;this.minuteDropDownOffsetInMinute--}} +for(var no=startMinute;no';div.onmouseover=function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoverUpAndDownArrowsInDropDownHours(e)} ;div.onmouseout =function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoutUpAndDownArrowsInDropDownHours(e)} ;DHTMLSuite.commonObj.__addEventEl(div);this.divElHourDropdown.appendChild(div)},__populateHoursInsideDropDownHours:function(){var ind=this.objectIndex;this.divElHourDropdownParentHours.innerHTML='';var startHour=Math.max(0,(this.calendarModelReference.__getDisplayedHour()-Math.round(this.numberOfRowsInHourDropDown/2)));startHour=Math.min(14,startHour);if((startHour+this.hourDropDownOffsetInHour+this.numberOfRowsInHourDropDown)>24){this.hourDropDownOffsetInHour=(24-startHour-this.numberOfRowsInHourDropDown)} +if((startHour+this.hourDropDownOffsetInHour)<0){this.hourDropDownOffsetInHour=startHour*-1} +startHour+=this.hourDropDownOffsetInHour;if(startHour<0)startHour=0;if(startHour>(24-this.numberOfRowsInHourDropDown))startHour=(24-this.numberOfRowsInHourDropDown);for(var no=startHour;no';div.onmouseover=function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoverUpAndDownArrowsInDropDownYears(e)} ;div.onmouseout =function(e){DHTMLSuite.variableStorage.arrayDSObjects[ind].__mouseoutUpAndDownArrowsInDropDownYears(e)} ;DHTMLSuite.commonObj.__addEventEl(div);this.divElYearDropdown.appendChild(div)},__populateYearsInsideDropDownYears:function(divElementToPopulate){var ind=this.objectIndex;this.divElYearDropdownParentYears.innerHTML='';var startYear=this.calendarModelReference.__getDisplayedYear()-5+this.yearDropDownOffsetInYear;for(var no=startYear;no=0||src.className.indexOf('HourAndMinute')>=0){if(DHTMLSuite.commonObj.isObjectClicked(this.divElement,e))return} +this.__showHideDropDownBoxMonth('none');this.__showHideDropDownBoxYear('none');this.__showHideDropDownBoxHour('none');this.__showHideDropDownBoxMinute('none')},__showHideDropDownBoxMonth:function(forcedDisplayAttribute){if(!forcedDisplayAttribute){this.__showHideDropDownBoxYear('none');this.__showHideDropDownBoxHour('none')} +if(forcedDisplayAttribute){this.divElMonthDropdown.style.display=forcedDisplayAttribute}else{this.divElMonthDropdown.style.display=(this.divElMonthDropdown.style.display=='block'?'none':'block')} +this.__populateDropDownMonths();this.__positionDropDownMonths()},__showHideDropDownBoxYear:function(forcedDisplayAttribute){if(!forcedDisplayAttribute){this.__showHideDropDownBoxMonth('none');this.__showHideDropDownBoxHour('none');this.__showHideDropDownBoxMinute('none')} +if(forcedDisplayAttribute){this.divElYearDropdown.style.display=forcedDisplayAttribute}else{this.divElYearDropdown.style.display=(this.divElYearDropdown.style.display=='block'?'none':'block')} +if(this.divElYearDropdown.style.display=='none'){this.yearDropDownOffsetInYear=0}else{this.__populateDropDownYears()} +this.__positionDropDownYears()},__showHideDropDownBoxHour:function(forcedDisplayAttribute){if(!forcedDisplayAttribute){this.__showHideDropDownBoxYear('none');this.__showHideDropDownBoxMonth('none');this.__showHideDropDownBoxMinute('none')} +if(forcedDisplayAttribute){this.divElHourDropdown.style.display=forcedDisplayAttribute}else{this.divElHourDropdown.style.display=(this.divElHourDropdown.style.display=='block'?'none':'block')} +if(this.divElHourDropdown.style.display=='none'){this.hourDropDownOffsetInHour=0}else{this.__populateDropDownHours()} +this.__positionDropDownHours()},__showHideDropDownBoxMinute:function(forcedDisplayAttribute){if(!forcedDisplayAttribute){this.__showHideDropDownBoxYear('none');this.__showHideDropDownBoxMonth('none');this.__showHideDropDownBoxHour('none')} +if(forcedDisplayAttribute){this.divElMinuteDropdown.style.display=forcedDisplayAttribute}else{this.divElMinuteDropdown.style.display=(this.divElMinuteDropdown.style.display=='block'?'none':'block')} +if(this.divElMinuteDropdown.style.display=='none'){this.minuteDropDownOffsetInMinute=0}else{this.__populateDropDownMinutes()} +this.__positionDropDownMinutes()},__createMainHtmlEls:function(){this.divElement=document.createElement('DIV');this.divElement.className='DHTMLSuite_calendar';this.divElContent=document.createElement('DIV');this.divElement.appendChild(this.divElContent);this.divElContent.className='DHTMLSuite_calendarContent';if(this.targetReference)this.targetReference.appendChild(this.divElement);else document.body.appendChild(this.divElement);if(this.isDragable){try{this.referenceToDragDropObject=new DHTMLSuite.dragDropSimple({elementReference: this.divElement })}catch(e){alert('Include DHTMLSuite-dragDropSimple.js for the drag feature')}} +if(DHTMLSuite.clientInfoObj.isMSIE&&DHTMLSuite.clientInfoObj.navigatorVersion<8){this.iframeEl=document.createElement(''; + + // src="' +_editor_url+ 'popups/blank.html" + + // + // Switch to TEXTEDIT mode + // + + if (mode == "textedit" || editor_obj.tagName.toLowerCase() == 'iframe') { + config.mode = "textedit"; + var editdoc = editor_obj.contentWindow.document; + var contents = editdoc.body.createTextRange().htmlText; + editor_obj.outerHTML = TextEdit; + editor_obj = document.getElementById("_" +objname + "_editor"); + editor_obj.value = contents; + editor_event(objname); + + editor_updateToolbar(objname, "disable"); // disable toolbar items + + // set event handlers + editor_obj.onkeydown = function() { editor_event(objname); } + editor_obj.onkeypress = function() { editor_event(objname); } + editor_obj.onkeyup = function() { editor_event(objname); } + editor_obj.onmouseup = function() { editor_event(objname); } + editor_obj.ondrop = function() { editor_event(objname, 100); } // these events fire before they occur + editor_obj.oncut = function() { editor_event(objname, 100); } + editor_obj.onpaste = function() { editor_event(objname, 100); } + editor_obj.onblur = function() { editor_event(objname, -1); } + + editor_updateOutput(objname); + editor_focus(editor_obj); + } + + // + // Switch to WYSIWYG mode + // + + else { + config.mode = "wysiwyg"; + var contents = editor_obj.value; + if (mode == 'init') { contents = document.getElementById(objname).value; } // on init use original textarea content + + // create editor + editor_obj.outerHTML = RichEdit; + editor_obj = document.getElementById("_" +objname + "_editor"); + + // get iframe document object + + // create editor contents (and default styles for editor) + var html = ""; + html += '\n'; + if (config.stylesheet) { + html += '\n'; + } + html += '\n' + + '\n' + + '' + + contents + + '\n' + + '\n'; + + // write to editor window + if (editor_obj.contentWindow) + var editdoc = editor_obj.contentWindow.document; + else + var editdoc = editor_obj.contentDocument; + + editdoc.open(); + editdoc.write(html); + editdoc.close(); + + editor_updateToolbar(objname, "enable"); // enable toolbar items + + // store objname under editdoc + editdoc.objname = objname; + + // set event handlers + editdoc.onkeydown = function() { editor_event(objname); } + editdoc.onkeypress = function() { editor_event(objname); } + editdoc.onkeyup = function() { editor_event(objname); } + editdoc.onmouseup = function() { editor_event(objname); } + editdoc.body.ondrop = function() { editor_event(objname, 100); } // these events fire before they occur + editdoc.body.oncut = function() { editor_event(objname, 100); } + editdoc.body.onpaste = function() { editor_event(objname, 100); } + editdoc.body.onblur = function() { editor_event(objname, -1); } + + // bring focus to editor + if (mode != 'init') { // don't focus on page load, only on mode switch + editor_focus(editor_obj); + } + + } + + // Call update UI + if (mode != 'init') { // don't update UI on page load, only on mode switch + editor_event(objname); + } + +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_focus + Description : bring focus to the editor + Usage : editor_focus(editor_obj); + Arguments : editor_obj - editor object +\* ---------------------------------------------------------------------- */ + +function editor_focus(editor_obj) { + + // check editor mode + if (editor_obj.tagName.toLowerCase() == 'textarea') { // textarea + var myfunc = function() { editor_obj.focus(); }; + setTimeout(myfunc,100); // doesn't work all the time without delay + } + + else { // wysiwyg + var editdoc = editor_obj.contentWindow.document; // get iframe editor document object + var editorRange = editdoc.body.createTextRange(); // editor range + var curRange = editdoc.selection.createRange(); // selection range + + if (curRange.length == null && // make sure it's not a controlRange + !editorRange.inRange(curRange)) { // is selection in editor range + editorRange.collapse(); // move to start of range + editorRange.select(); // select + curRange = editorRange; + } + } + +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_about + Description : display "about this editor" popup +\* ---------------------------------------------------------------------- */ + +function editor_about(objname) { + showModalDialog(_editor_url + "popups/about.html", window, "resizable: yes; help: no; status: no; scroll: no; "); +} + +/* ---------------------------------------------------------------------- *\ + Function : _dec_to_rgb + Description : convert dec color value to rgb hex + Usage : var hex = _dec_to_rgb('65535'); // returns FFFF00 + Arguments : value - dec value +\* ---------------------------------------------------------------------- */ + +function _dec_to_rgb(value) { + var hex_string = ""; + for (var hexpair = 0; hexpair < 3; hexpair++) { + var myByte = value & 0xFF; // get low byte + value >>= 8; // drop low byte + var nybble2 = myByte & 0x0F; // get low nybble (4 bits) + var nybble1 = (myByte >> 4) & 0x0F; // get high nybble + hex_string += nybble1.toString(16); // convert nybble to hex + hex_string += nybble2.toString(16); // convert nybble to hex + } + return hex_string.toUpperCase(); +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_insertHTML + Description : insert string at current cursor position in editor. If + two strings are specifed, surround selected text with them. + Usage : editor_insertHTML(objname, str1, [str2], reqSelection) + Arguments : objname - ID of textarea + str1 - HTML or text to insert + str2 - HTML or text to insert (optional argument) + reqSelection - (1 or 0) give error if no text selected +\* ---------------------------------------------------------------------- */ + +function editor_insertHTML(objname, str1,str2, reqSel) { + var config = document.getElementById(objname).config; + var editor_obj = document.getElementById("_" +objname + "_editor"); // editor object + if (str1 == null) { str1 = ''; } + if (str2 == null) { str2 = ''; } + + // for non-wysiwyg capable browsers just add to end of textbox + if (document.getElementById(objname) && editor_obj == null) { + document.getElementById(objname).focus(); + document.getElementById(objname).value = document.getElementById(objname).value + str1 + str2; + return; + } + + // error checking + if (editor_obj == null) { return alert("Unable to insert HTML. Invalid object name '" +objname+ "'."); } + + editor_focus(editor_obj); + + var tagname = editor_obj.tagName.toLowerCase(); + var sRange; + + // insertHTML for wysiwyg iframe + if (tagname == 'iframe') { + var editdoc = editor_obj.contentWindow.document; + sRange = editdoc.selection.createRange(); + var sHtml = sRange.htmlText; + + // check for control ranges + if (sRange.length) { return alert("Unable to insert HTML. Try highlighting content instead of selecting it."); } + + // insert HTML + var oldHandler = window.onerror; + window.onerror = function() { alert("Unable to insert HTML for current selection."); return true; } // partial table selections cause errors + if (sHtml.length) { // if content selected + if (str2) { sRange.pasteHTML(str1 +sHtml+ str2) } // surround + else { sRange.pasteHTML(str1); } // overwrite + } else { // if insertion point only + if (reqSel) { return alert("Unable to insert HTML. You must select something first."); } + sRange.pasteHTML(str1 + str2); // insert strings + } + window.onerror = oldHandler; + } + + // insertHTML for plaintext textarea + else if (tagname == 'textarea') { + editor_obj.focus(); + sRange = document.selection.createRange(); + var sText = sRange.text; + + // insert HTML + if (sText.length) { // if content selected + if (str2) { sRange.text = str1 +sText+ str2; } // surround + else { sRange.text = str1; } // overwrite + } else { // if insertion point only + if (reqSel) { return alert("Unable to insert HTML. You must select something first."); } + sRange.text = str1 + str2; // insert strings + } + } + else { alert("Unable to insert HTML. Unknown object tag type '" +tagname+ "'."); } + + // move to end of new content + sRange.collapse(false); // move to end of range + sRange.select(); // re-select + +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_getHTML + Description : return HTML contents of editor (in either wywisyg or html mode) + Usage : var myHTML = editor_getHTML('objname'); +\* ---------------------------------------------------------------------- */ + +function editor_getHTML(objname) { + var editor_obj = document.getElementById("_" +objname + "_editor"); + var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea'); + + if (isTextarea) { return editor_obj.value; } + else { return editor_obj.contentWindow.document.body.innerHTML; } +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_setHTML + Description : set HTML contents of editor (in either wywisyg or html mode) + Usage : editor_setHTML('objname',"html here"); +\* ---------------------------------------------------------------------- */ + +function editor_setHTML(objname, html) { + var editor_obj = document.getElementById("_" +objname + "_editor"); + var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea'); + + if (isTextarea) { editor_obj.value = html; } + else { editor_obj.contentWindow.document.body.innerHTML = html; } +} + +/* ---------------------------------------------------------------------- *\ + Function : editor_appendHTML + Description : append HTML contents to editor (in either wywisyg or html mode) + Usage : editor_appendHTML('objname',"html here"); +\* ---------------------------------------------------------------------- */ + +function editor_appendHTML(objname, html) { + var editor_obj = document.getElementById("_" +objname + "_editor"); + var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea'); + + if (isTextarea) { editor_obj.value += html; } + else { editor_obj.contentWindow.document.body.innerHTML += html; } +} + +/* ---------------------------------------------------------------- */ + +function _isMouseOver(obj,event) { // determine if mouse is over object + var mouseX = event.clientX; + var mouseY = event.clientY; + + var objTop = obj.offsetTop; + var objBottom = obj.offsetTop + obj.offsetHeight; + var objLeft = obj.offsetLeft; + var objRight = obj.offsetLeft + obj.offsetWidth; + + if (mouseX >= objLeft && mouseX <= objRight && + mouseY >= objTop && mouseY <= objBottom) { return true; } + + return false; +} + +/* ---------------------------------------------------------------- */ + +function editor_cMenu_generate(editorWin,objname) { + var parentWin = window; + editorWin.event.returnValue = false; // cancel default context menu + + // define content menu options + var cMenuOptions = [ // menu name, shortcut displayed, javascript code + ['Cut', 'Ctrl-X', function() {}], + ['Copy', 'Ctrl-C', function() {}], + ['Paste', 'Ctrl-C', function() {}], + ['Delete', 'DEL', function() {}], + ['---', null, null], + ['Select All', 'Ctrl-A', function() {}], + ['Clear All', '', function() {}], + ['---', null, null], + ['About this editor...', '', function() { + alert("about this editor"); + }]]; + editor_cMenu.options = cMenuOptions; // save options + + // generate context menu + var cMenuHeader = '' + + ''; + + for(var menuIdx=0;menuIdx'; + if (menuKey) { cMenuList += ' ' +menuName+ '' +menuKey+ ''; } + else { cMenuList += ' ' +menuName+ ''; } + cMenuList += ''; + } + } + + var cMenuHTML = cMenuHeader + cMenuList + cMenuFooter; + + + document.getElementById('_'+objname+'_cMenu').outerHTML = cMenuHTML; + + editor_cMenu_setPosition(parentWin, editorWin, objname); + + parentWin['_'+objname+'_cMenu'].style.visibility = 'visible'; + parentWin['_'+objname+'_cMenu'].focus(); + +} + +/* ---------------------------------------------------------------- */ + +function editor_cMenu_setPosition(parentWin, editorWin, objname) { // set object position that won't overlap window edge + var event = editorWin.event; + var cMenuObj = parentWin['_'+objname+'_cMenu']; + var mouseX = event.clientX + parentWin.document.getElementById('_'+objname+'_editor').offsetLeft; + var mouseY = event.clientY + parentWin.document.getElementById('_'+objname+'_editor').offsetTop; + var cMenuH = cMenuObj.offsetHeight; + var cMenuW = cMenuObj.offsetWidth; + var pageH = document.body.clientHeight + document.body.scrollTop; + var pageW = document.body.clientWidth + document.body.scrollLeft; + + // set horzontal position + if (mouseX + 5 + cMenuW > pageW) { var left = mouseX - cMenuW - 5; } // too far right + else { var left = mouseX + 5; } + + // set vertical position + if (mouseY + 5 + cMenuH > pageH) { var top = mouseY - cMenuH + 5; } // too far down + else { var top = mouseY + 5; } + + cMenuObj.style.top = top; + cMenuObj.style.left = left; + +} + +/* ---------------------------------------------------------------- */ + +function editor_cMenu(obj,menuIdx,objname) { + var action = event.type; + if (action == "mouseover" && !obj.disabled && obj.tagName.toLowerCase() == 'tr') { + obj.className = 'cMenuOver'; + for (var i=0; i < obj.cells.length; i++) { obj.cells[i].className = 'cMenuOver'; } + } + else if (action == "mouseout" && !obj.disabled && obj.tagName.toLowerCase() == 'tr') { + obj.className = 'cMenu'; + for (var i=0; i < obj.cells.length; i++) { obj.cells[i].className = 'cMenu'; } + } + else if (action == "click" && !obj.disabled) { + document.getElementById('_'+objname+'_cMenu').style.visibility = "hidden"; + var menucode = editor_cMenu.options[menuIdx][2]; + menucode(); + } + else if (action == "blur") { + if (!_isMouseOver(obj,event)) { obj.style.visibility = 'hidden'; } + else { + if (obj.style.visibility != "hidden") { obj.focus(); } + } + } + else { alert("editor_cMenu, unknown action: " + action); } +} + +/* ---------------------------------------------------------------------- */ +/* -- For FireFox Compatibility -- */ +function insertAfterEnd(oElement,oNewNode) +{ + oElement.parentNode.insertBefore(oNewNode,oElement.nextSibling); +} +function insertHTMLAfterEnd(oElement,html) +{ + var auxDiv=$dce('div'); + auxDiv.innerHTML=html; + for(var i=auxDiv.childNodes.length-1;i>=0;i--) + { + insertAfterEnd(oElement,auxDiv.childNodes[i]); + } +} +/**/ \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/example.html b/gulliver/thirdparty/htmlarea/example.html new file mode 100644 index 000000000..62f7ac129 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/example.html @@ -0,0 +1,160 @@ +htmlArea Example + + + + + + + + + + + + +
    + +
    +htmlArea v2.03
    +A free WYSIWYG editor replacement for <textarea> fields.
    from your friends at interactivetools.com
    +
    +
    + + +

    Sample textarea follows:

    + +
    + +Example "InsertHTML" links:   +Highlight selected text - +Insert Smiley +getHTML +setHTML + + + + +


    +

    Another textarea follows: (This one has many more configuration defined in the source code)

    + + +
    + + + +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/images/Thumbs.db b/gulliver/thirdparty/htmlarea/images/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..5e7f17f4ce2a154544f7f475bd9d2d417527de80 GIT binary patch literal 28160 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 hSk)jwl6Ig^Vf(rF0`-oe`>4S#n9{y%?kSqlIF literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_about.gif b/gulliver/thirdparty/htmlarea/images/ed_about.gif new file mode 100644 index 0000000000000000000000000000000000000000..d476271df6a260d9578aab6974996897471df67f GIT binary patch literal 87 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3`}}G{hbHi^8198_|00A6#cF` lBjTB^jAX;4S<}+4r>*(1=<}Pl3Y)gd{6-FcTQ5ciYXD1{9fbe@ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_align_center.gif b/gulliver/thirdparty/htmlarea/images/ed_align_center.gif new file mode 100644 index 0000000000000000000000000000000000000000..09669101af58e41d62320feda80968bd01604ef5 GIT binary patch literal 69 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3`{aT{VPwuWn47pbEL=X(w)s` TE9Fmgh(vb1IJM15{)-0I$ZZ;m*F FH30ie6G8w0 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_charmap.gif b/gulliver/thirdparty/htmlarea/images/ed_charmap.gif new file mode 100644 index 0000000000000000000000000000000000000000..b0dc889d7ec47ddc8325ec6f935c6d2134aa8d5a GIT binary patch literal 143 zcmZ?wbhEHb6k-r!Sj52a|Ns932M#neH2h~^XaGV6APo{!{K>*9!obd;1LOi#3NbJ+ zhg9skb5F@mym{*8wu9>z95~9`BwEuWP_>km;l;&$%ec9Z1&O&j>}PUPQ8yM%o48=Y s4(o3()BOA{wb<6ex4ECeE)-m4I_g!0K^|S9RL6T literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_color_bg.gif b/gulliver/thirdparty/htmlarea/images/ed_color_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6ff05d0d327a2b17c7ca68a431d5a6eb686123f GIT binary patch literal 181 zcmZ?wbhEHb6k-r!*v!E29|S;DOG`_2bu~i^14A{#e;}U$2tWi_8pMGB#h)y!A`ILN zIv_5{3Mo5V0m2r2x(p4x9SV*PDhX98 z2?Y)!66Hd3a;u~ROtuCmSR07&_)l8Bl~-V2tAVD~j9vCEEprN1tk!0(ObW2SqZt%p MrrgphBFJD30Hv`#4gdfE literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_color_fg.gif b/gulliver/thirdparty/htmlarea/images/ed_color_fg.gif new file mode 100644 index 0000000000000000000000000000000000000000..90e5123c48fe301ba17723c6eec02fa7de5c1019 GIT binary patch literal 171 zcmZ?wbhEHb6k-r!*v!E2|33(~w6s)LS2MIQFjO=A2a5qk89*{15*aA|WMLIy;9}4L z34+XEV2KDg>8b5&k*$6Ci2U*jS<9~Joy%6U@)gMJzE^O^c>({Hr29;<4dIoXECwo* zj4p661UNPZC={^;9BA;`5XI)cA*ex0;T&`Gt!TkHf=pW*&x$m^U%MwxkdeU}01{R< A5C8xG literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_copy.gif b/gulliver/thirdparty/htmlarea/images/ed_copy.gif new file mode 100644 index 0000000000000000000000000000000000000000..f598fa21a92f19b05acd611d0a51a9cfa1d67a16 GIT binary patch literal 110 zcmZ?wbhEHb6k-r!n8?8J|Nnmmh6V;OL-8jIs|W)#gAR}jloeuNV6vanzw)#i|82nq zP3r7hLr&adeY7GcEP*kJ$?nBUrL6$`WC)1^_(Q6o3E# literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_cut.gif b/gulliver/thirdparty/htmlarea/images/ed_cut.gif new file mode 100644 index 0000000000000000000000000000000000000000..92972fc26e0e8e2af305e7726f1e5f95403677d3 GIT binary patch literal 91 zcmZ?wbhEHb6k-r!n8*MG4M6<=|9>E<_>+ZIgn@}c2gnA>3NbJ+=}hTgd0P6r)SOE$ qg{c+0&&A{>yijytnBvB@CG_+6*WnT<@hHbV^#)h00*KNSpWb4 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_format_italic.gif b/gulliver/thirdparty/htmlarea/images/ed_format_italic.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8e1cb0b9ad5b9c821accc34e71fac2fa25e5fb7 GIT binary patch literal 77 zcmZ?wbhEHb6k-r!n8?7;($Z30UCqG2@c;jR#h)y!A`Hw7IzTQ^R)~RtNp4R6%F}Q8 fduJH;aptTjV>|0Arx7vzgQH05ws+j_tPIuwOhgw$ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_format_strike.gif b/gulliver/thirdparty/htmlarea/images/ed_format_strike.gif new file mode 100644 index 0000000000000000000000000000000000000000..48853615a455cd2954333642d5eabaa8da794ed0 GIT binary patch literal 78 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3{0v${VPwu%bhhW8 cfJo)3X+LbEy_6PjFFPI5_O1814E<_>+ZIgn@}c2gnA>3NbJ+$xrEDdHU^pCj%j_ c$hUK)K2Hy2SfH3vnYGet+B@#!zKjgk0O8seEC2ui literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_format_sup.gif b/gulliver/thirdparty/htmlarea/images/ed_format_sup.gif new file mode 100644 index 0000000000000000000000000000000000000000..8e66b99d081f1d446f340e152d5ce0e80108c2cb GIT binary patch literal 77 zcmZ?wbhEHb6k-r!n8?7;zyJdO|NjS)ia%LcMHrYEbU;ENc?KrADg7%?=Q7B23tjxR ap;d?FabnzxiH|Cp<{#Vkj(a;RgEaup{}(d= literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_format_underline.gif b/gulliver/thirdparty/htmlarea/images/ed_format_underline.gif new file mode 100644 index 0000000000000000000000000000000000000000..b05384eaf8a4a83d984ea134556b6930f171243c GIT binary patch literal 85 zcmZ?wbhEHb6k-r!n8?6TU0uzpd}VTOrB76tGFyMfqCnbE{Ye25SJ^r5U6E literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_help.gif b/gulliver/thirdparty/htmlarea/images/ed_help.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d66154aa81083c39eee89390a526f8a6fff9ef0 GIT binary patch literal 70 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3{0{;{VPwu$ Zzj)4;*6z)A3x4y5J@T0LY^4Z;H2|{E7KQ)- literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_html.gif b/gulliver/thirdparty/htmlarea/images/ed_html.gif new file mode 100644 index 0000000000000000000000000000000000000000..380de29dfa18c80c3f8b5f980ebe0350b01b48b9 GIT binary patch literal 75 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3`|Nr{VPwuv%P9R1{T-JOxa8UXv@7wiB4 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_image.gif b/gulliver/thirdparty/htmlarea/images/ed_image.gif new file mode 100644 index 0000000000000000000000000000000000000000..a715019b96d2dbfec155e15edf3d31365f0397b8 GIT binary patch literal 148 zcmZ?wbhEHb6k-r!Sj52a|33&ffB*wS0}z71|Ns9Lf3mQOFt9V|fcPM_49t-gyYBo8 zkaS$Vw5`)<$NPkB9Le_y$85_)Y$u>=K*kJyOHPSwKgRH literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_indent_less.gif b/gulliver/thirdparty/htmlarea/images/ed_indent_less.gif new file mode 100644 index 0000000000000000000000000000000000000000..6054d617daa94f7f4be08d430c0b74ec7ee8ba1b GIT binary patch literal 87 zcmZ?wbhEHb6k-r!n8*MGEkOML|9>E<_>+ZIgn@}c2P6!VXJFEp(!Wyj_4=lq&0Za> k4%_55$lgt9NDFIo+rEOSJLz7<(bIQs{Mz+BfRVu(0M%F=(f|Me literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_indent_more.gif b/gulliver/thirdparty/htmlarea/images/ed_indent_more.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5dd55dcd821d5b5e7cbc18a6ab218f68f564d23 GIT binary patch literal 87 zcmZ?wbhEHb6k-r!n8*MGEkOML|9>E<_>+ZIgn@}c2P6!VXJFEp(!Wyj_4=lq&0Za> k4%?JANZw6pNGoe_-`=vQHSJ!-(bIQs?Aq}?fRVu(0NqI)B>(^b literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_link.gif b/gulliver/thirdparty/htmlarea/images/ed_link.gif new file mode 100644 index 0000000000000000000000000000000000000000..0482da3f5a4318c83915f5fc85055fd11db935f6 GIT binary patch literal 97 zcmZ?wbhEHb6k-r!n8?8J|NsAnh6V;OL-8jIs|W)#gAR}jloeuNU^1H1zw-23{>L1P x!jiKsL>huCADD5(w{c0Zt$3Cm@YHAdO{E<_>+ZIgn@}c2P6!VXJAsC(!cUF+x;udYB#Dc d_U!q+rB=}`>q7go2QPb5%35Ce6tgl|0{}l$8V3LX literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_list_num.gif b/gulliver/thirdparty/htmlarea/images/ed_list_num.gif new file mode 100644 index 0000000000000000000000000000000000000000..ae4e03b074c4ceccdbcac1dfcdf12a93a996e6a6 GIT binary patch literal 82 zcmZ?wbhEHb6k-r!n8*MGEkOML|9>E<_>+ZIgn@}c2P6!VXJAsE(!cUF$KC_R3!`SM fl@wLqsO2k-otfbw)wOC(*sSFeo3=$TFjxZsKmr&W literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_redo.gif b/gulliver/thirdparty/htmlarea/images/ed_redo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b5ebbd927fe65b22d79a1eec6bf518431496eee GIT binary patch literal 80 zcmZ?wbhEHb6k-r!n8?7;(9i%R{{R2az`&sRlZ91;fr&u}$Og&^F)%PGPU&BH`t5s% h8H`>g{=T!j-{?-cl$cyJQ=Q%69ry81KKof2tO0y-8B72G literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/ed_undo.gif b/gulliver/thirdparty/htmlarea/images/ed_undo.gif new file mode 100644 index 0000000000000000000000000000000000000000..05f041e9f9ee5a53ef2df798cc768fac3c5867e7 GIT binary patch literal 81 zcmZ?wbhEHb6k-r!n8?7;(9i%R{{R2az`&sRlZ91;fr&u}$Og&^F)%PGP3d2G`YnGl iw@HI2pKI9LH!V%jMF(n{u=YqnWKohJ1+3zII literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/fullscreen_minimize.gif b/gulliver/thirdparty/htmlarea/images/fullscreen_minimize.gif new file mode 100644 index 0000000000000000000000000000000000000000..b12c3f737fa30a748c383614808905671ba3ce9e GIT binary patch literal 97 zcmZ?wbhEHb6k-r!XkY+=|Ns9h{$yblVPIs?0r5dH3``b1{VO@%?q}*KzIu5{W#7}P w+=yjUZ@5hp-nnd5NomiCU5mawmEoQ1na%ytLYuWf-6XQ-NbHlD8Vn590MQa71^@s6 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/images/insert_table.gif b/gulliver/thirdparty/htmlarea/images/insert_table.gif new file mode 100644 index 0000000000000000000000000000000000000000..4ce3ff49c72e689943a7851b3ccd3c490276b869 GIT binary patch literal 121 zcmZ?wbhEHb6k-r!Sj52a|Ns9pXU;Gf&tw3zfg}Vd{$yblVPIj<0dYZU8JO)ncHQ|m zp~rKzY*xqF>f@8tiyknrICQOg89DDQ*Xq=S`xgIB)$BR$5T)k6=Wm2Zc-pZiSG$f} PO10{YSbrmjiNP8Go=7f( literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/htmlarea/license.txt b/gulliver/thirdparty/htmlarea/license.txt new file mode 100644 index 000000000..f5d26fae1 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/license.txt @@ -0,0 +1,13 @@ +htmlArea License (based on BSD license) +Copyright (c) 2002, interactivetools.com, inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3) Neither the name of interactivetools.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/gulliver/thirdparty/htmlarea/popups/about.html b/gulliver/thirdparty/htmlarea/popups/about.html new file mode 100644 index 000000000..6511174f8 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/about.html @@ -0,0 +1,15 @@ + +About + + +htmlArea v2.03
    +A free WYSIWYG editor replacement for <textarea> fields.
    + +

    For full source code and docs, visit:
    +
    http://www.interactivetools.com/products/htmlarea/

    + +

    Copyright (c) 2002 interactivetools.com, inc. All Rights Reserved.
    + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/blank.html b/gulliver/thirdparty/htmlarea/popups/blank.html new file mode 100644 index 000000000..5b1b16d1f --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/blank.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/custom2.html b/gulliver/thirdparty/htmlarea/popups/custom2.html new file mode 100644 index 000000000..04314a05b --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/custom2.html @@ -0,0 +1,35 @@ + + + Select Phrase + + + + +

    +
    + + + + + +
    +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/editor_help.html b/gulliver/thirdparty/htmlarea/popups/editor_help.html new file mode 100644 index 000000000..b4553697d --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/editor_help.html @@ -0,0 +1,16 @@ + + + Editor Help + + + + +

    Editor Help

    + +Todo... + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/fullscreen.html b/gulliver/thirdparty/htmlarea/popups/fullscreen.html new file mode 100644 index 000000000..0e133aeb3 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/fullscreen.html @@ -0,0 +1,131 @@ + +Fullscreen Editor + + + + + + +
    + +
    + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/insert_image.html b/gulliver/thirdparty/htmlarea/popups/insert_image.html new file mode 100644 index 000000000..3edcd3eb7 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/insert_image.html @@ -0,0 +1,206 @@ + + + + + + + +Insert Image + + + + + +
    Image URL:
    + + +
    Alternate Text:
    + + +
    +Layout +
    + +
    +Spacing +
    + +
    Alignment:
    + + +
    Horizontal:
    + + +
    Border Thickness:
    + + +
    Vertical:
    + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/insert_table.html b/gulliver/thirdparty/htmlarea/popups/insert_table.html new file mode 100644 index 000000000..88b70eb06 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/insert_table.html @@ -0,0 +1,170 @@ + +Insert Table + + + + + + + + + + + + + + + + + +
    Rows:  
    Cols: Width:   + + +
    + + +
    +Layout + + + + + + + + + + +
    Alignment: + +
    Border Thickness:
    +
    + + +
    +Spacing + + + + + + + + + + +
    Cell Spacing:
    Cell Padding:
    +
    + + +
    +
    + +
    + + + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/popups/select_color.html b/gulliver/thirdparty/htmlarea/popups/select_color.html new file mode 100644 index 000000000..8c4f5f134 --- /dev/null +++ b/gulliver/thirdparty/htmlarea/popups/select_color.html @@ -0,0 +1,343 @@ + + +Select Color + + + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/htmlarea/readme.html b/gulliver/thirdparty/htmlarea/readme.html new file mode 100644 index 000000000..ca2d2a8cc --- /dev/null +++ b/gulliver/thirdparty/htmlarea/readme.html @@ -0,0 +1,760 @@ +htmlArea Help + + + + + + + + +
    +htmlArea v2.03
    +Turn any <textarea> into a WYSIWYG editor, a free script
    from your friends at interactivetools.com
    +
    +
    + + + +

    Introduction

    + +What is htmlArea?
    +Is it really free? What's the catch?
    +What are the browser requirements?
    +Can I see an example of what it looks like?
    +Where can I find out more info, download the latest version, and talk to other htmlArea users?
    + +

    Installation / Setup

    + +How do I add htmlArea to my web page?
    +I want to change the editor settings, how do I do that?
    +How can I change what controls are displayed on the toolbar?
    +How can I change what fonts are in the font list?
    +How can I change what sizes are in the font size?
    +How can I change what styles are in the font style (CSS) list?
    +How can I specify an external stylesheet for my styles?
    + +

    Frequently Asked Questions

    + +What the project goals for htmlArea?
    +This editor is pretty neat, so how does it actually work?
    +You don't happen to have one of these for (Netscape, Mozilla, Opera, Mac IE, etc) do you?
    +Why doesn't htmlArea output XHTML instead of regular HTML? Can you make it do that?
    +I'd like to be able to upload images from my hard drive, can you add that feature?
    +I'd like to <insert idea here>, can you add that feature?
    +Can I change the toolbar/button colors?
    +I love htmlArea, is there anything I can do to help the project?
    +Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?
    + + +

    Known Bugs & Issues

    + +Undo/Redo doesn't work
    +Relative paths are converted to absolute paths
    +HTML header info (eg: <head>, <body>, etc) doesn't get preserved
    +Some tags (eg: noframes, noscript, etc) doesn't get preserved
    +htmlArea doesn't work when multiple textareas that have the same name
    +Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?
    + +

    Change Log

    + +View Change Log
    + + + +

    + + + +

    Introduction back to top

    +
    + + +

    What is htmlArea?
    +
    htmlArea is a free WYSIWYG (what you see is what you get) editor replacement for <textarea> fields. By adding a few +simple lines of JavaScript to your web page you can replace a regular textarea with a rich text +editor that let your users do the following: +

      +
    • Format text to be bold, italicized, or underlined.
    • +
    • Change the face, size, style and colour.
    • +
    • Left, centre, or right-justify paragraphs.
    • +
    • Make bulleted or numbered lists.
    • +
    • Indent or un-indent paragraphs.
    • +
    • Insert a horizontal line.
    • +
    • Insert hyperlinks and images.
    • +
    • View the raw HTML source of what they're editing.
    • +
    • and much more...
    • +
    + +

    Some of the interesting features of htmlArea that set's it apart from other web based WYSIWYG editors are as follows: + +

      +
    • It's lightweight, fast loading and can transform a regular textarea into a rich-text editor with a single line of JavaScript.
    • +
    • It's 100% backwards compatible with older or non-supported browsers (they get the original textarea field).
    • +
    • It's free and can be incorporated into any free or commercial program.
    • +
    • It works with any programming language (ASP, PHP, Perl, Java, etc).
    • +
    • It's written in simple JavaScript and can be easily viewed, modified or extended.
    • +
    • It remembers entered content when a user navigates away and then hits "back" in their browser.
    • +
    • Since it replaces existing textareas it doesn't require a lot of code to add it to your pages (just one line).
    • +
    • Did we mention it was free? : )
    • +
    + + +

    + + +

    Is it really free? What's the catch?
    +
    Yes! It's really free. You can use it, modify it, distribute it with your software, +or do just about anything you like with it. +

    + + + +

    What are the browser requirements?
    +
    htmlArea requires Internet Explorer 5.5 or better on Windows to run. This is because it +makes use of some advanced features of IE5.5 that aren't available in other browsers yet. +It is backwards compatible with other browsers, though. They will get a regular textarea +field instead of a WYSIWYG editor.

    + + + +

    Can I see an example of what it looks like?
    +
    Sure, make sure you're using IE5.5 or better on windows and see below. + +

    Here is a regular <textarea> field.
    + + +

    And here is a <textarea> transformed with htmlArea (with a single line of JavaScript code).

    + + + + +

    + + +

    Where can I find out more info, download the latest version, and talk to other htmlArea users?
    +
    You can find out more about htmlArea and download the latest version on the +htmlArea homepage +and you can talk to other htmlArea users and post any comments or suggestions you have in the +htmlArea forum. + +
    + + + +

    Installation / Setup back to top

    +
    + + +

    How do I add htmlArea to my web page?
    +
    It's easy, first you need to upload the htmlArea files to your website. Just follow these steps: + +

      +
    1. Download the latest version from the htmlArea homepage.
    2. +
    3. Unzip the files onto your local computer (making sure to maintain the directory structure contained in the zip).
    4. +
    5. Create a new folder on your website called /htmlarea/ (make sure it's NOT inside the cgi-bin).
    6. +
    7. Transfer all the htmlArea files from your local computer into the /htmlarea/ folder on your website.
    8. +
    9. Open the example page /htmlarea/example.html with your browser to make sure everything works.
    10. +

    + +Once htmlArea is on your website all you need to do is add some JavaScript to any pages that you want to +add WYSIWYG editors to. Here's how to do that. + +

      +
    1. Open the page you want to add a WYSIWYG editor to. Add the following to the top of +the page in the <head></head> of the HTML document. +
      +<script language="Javascript1.2"><!-- // load htmlarea
      +_editor_url = "";                     // URL to htmlarea files
      +var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]);
      +if (navigator.userAgent.indexOf('Mac')        >= 0) { win_ie_ver = 0; }
      +if (navigator.userAgent.indexOf('Windows CE') >= 0) { win_ie_ver = 0; }
      +if (navigator.userAgent.indexOf('Opera')      >= 0) { win_ie_ver = 0; }
      +if (win_ie_ver >= 5.5) {
      +  document.write('<scr' + 'ipt src="' +_editor_url+ 'editor.js"');
      +  document.write(' language="Javascript1.2"></scr' + 'ipt>');  
      +} else { document.write('<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>'); }
      +// --></script> +
      +If you've installed htmlArea anywhere other than /htmlarea/ then be sure to change _editor_url to point to +your htmlarea directory (ending with a forward slash "/").
    2. + +

    3. For each <textarea> that you want to change, add the following code to the page. +
      +<script language="JavaScript1.2" defer>
      +editor_generate('fieldname');
      +</script>
      +
      +Be sure to change "fieldname" to be the name (not id) of the textarea you want to change.
    4. + +

    5. And you're done, open your page in your browser and see if it worked. If you run into +any problems, keep trying and feel free to visit the +htmlArea forum.
    6. +

    + + +

    I want to change the editor settings, how do I do that?
    +
    While it's true that all you need is one line of JavaScript to create an htmlArea WYSIWYG editor +you can also specify more config settings in the code to control how the editor works and looks. Here's an +example of some of the available settings: +
    +<script language="JavaScript1.2" defer>
    +var config = new Object(); // create new config object

    + +config.width = "90%";
    +config.height = "200px";
    +config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';
    +config.debug = 0;

    + +// Add additional editor config settings here...

    + +editor_generate('fieldname',config);
    +</script>
    +
    +See below for even more configuration options that can be added. All of these settings will use +default values in editor.js if you don't specify them yourself. +

    + + + + +
    Widthspecifies the width of the editor (in pixels or as a percentage).
    Heightspecifies the height of the editor (in pixels or as a percentage).
    bodyStylespecifies CSS style of the editor window including color, default font face, and size. Note, the default font information isn't saved, it just controls how text is displayed if no other font formatting has been applied.
    debugif set to 1, displays a debug field with the actual contents of the editor (in raw html) which is updated as your type.
    +

    + + +

    How can I change what controls are displayed on the toolbar?
    +
    You can add a config.toolbar config setting to control exactly what's shown on the toolbar. +Here's an example. +
    +config.toolbar = [
    +   ['fontname'],
    +   ['fontsize'],
    +   ['fontstyle'],
    +   ['linebreak'],
    +   ['bold','italic','underline','separator'],
    +   ['strikethrough','subscript','superscript','separator'],
    +   ['justifyleft','justifycenter','justifyright','separator'],
    +   ['OrderedList','UnOrderedList','Outdent','Indent','separator'],
    +   ['forecolor','backcolor','separator'],
    +//['custom1','custom2','custom3','separator'],
    +   ['HorizontalRule','Createlink','InsertImage','htmlmode','separator'],
    +   ['about','help']
    +]; +
    +The square brackets control how the buttons are "grouped" together. You can either erase +or comment out (by adding // to the beginning of the line) buttons or button groups you don't +want displayed. Most of the buttons do pretty much just what you'd expect, but here's a few +odd ones for reference. +

    + + + +
    linebreakadds a linebreak to the toolbar, all buttons after this are on the next line.
    separatoradds a vertical separator between buttons, helps to visually group buttons together
    customNthese are custom buttons that can be defined by JavaScript programmers who want to extend htmlArea.
    +

    + + +

    How can I change what fonts are in the font list?
    +
    There is a config.fontnames setting that lets you control this. See below. +
    +config.fontnames = {
    +   "Arial":           "arial, helvetica, sans-serif",
    +   "Courier New":     "courier new, courier, mono",
    +   "Georgia":         "Georgia, Times New Roman, Times, Serif",
    +   "Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",
    +   "Times New Roman": "times new roman, times, serif",
    +   "Verdana":         "Verdana, Arial, Helvetica, sans-serif",
    +   "impact":          "impact",
    +   "WingDings":       "WingDings"
    +};
    +
    +The name on the left is what is displayed to the user. The list of fonts on the right is what is +actually put into the font tag in the code.

    + + +

    How can I change what sizes are in the font size?
    +
    There is a config.fontsizes setting that lets you control this. See below. +
    +config.fontsizes = {
    +   "1 (8 pt)":  "1",
    +   "2 (10 pt)": "2",
    +   "3 (12 pt)": "3",
    +   "4 (14 pt)": "4",
    +   "5 (18 pt)": "5",
    +   "6 (24 pt)": "6",
    +   "7 (36 pt)": "7"
    + };
    +
    +The value on the right is what the user sees, the value on the left is the actual font size used. +

    + + +

    How can I change what styles are in the font style (CSS) list?
    +
    As you can probably guess, there's a config.fontstyles setting for this. Now remember, the +styles defined here control how the text looks in the editor. These styles ALSO have to be defined +on any page where you display content created with the editor. htmlArea will save the class name +with the content but nothing else. It's up to you to define the class style in your pages. +
    + +config.fontstyles = [{
    +   name: "headline",
    +   className: "headline",
    +   classStyle: "font-family: arial; font-size: 28px;"
    + },{
    +   name: "red text",
    +   className: "saletext2",
    +   classStyle: ""
    +}];
    +
    +The "name" is what's displayed to users, "className" is the name of the CSS class to use, and +classStyle defines the attributes of the style in the editor. If you leave classStyle blank +you have to be sure to also specify an external stylesheet with all the style information (and +matching classNames!). See the next question on how to do that. +

    + + + + +

    How can I specify an external stylesheet for my styles?
    +
    You can specify a stylesheet to avoid entering the class style data for each class name. +You STILL have to specify which classNames you want to have available though, see the previous +question for information on that. +
    +config.stylesheet = "/style.css";
    +
    +

    + +
    + + + +

    Frequently Asked Questions back to top

    +
    + + +

    What are the project goals for htmlArea?
    +
    When we originally started the htmlArea project we had some pretty specific +goals in mind for how it would work and what issues were important to us. Those +goals still lead the direction of development today and are listed below in order +of priority. + +
      +

    1. Compatibility
    2. +
      htmlArea has to always be backwards compatible with older and unsupported browsers. This +ensures that even if a user with an older and unsupported browser can't use htmlArea, they'll always be able to, at a minimum, +enter text in a plain textarea like they would have done before. + +htmlArea should also be compatible with as many programming languages as possible by being +completely DHTML and JavaScript based. + +
      + +

    3. Ease of Use
    4. +
      htmlArea needs to be easy for developers to +integrate into their applications and customize, easy for programmers to extend +and modify, and easy for end users to "use". That's why you only have to add a +single line of JavaScript for each textarea you want to convert, and why all the +code is stored in a single, easy to follow JavaScript file. That's why htmlArea +can be used with almost any programming language (ASP, PHP, Perl, Java, etc), +and that the toolbar is streamlined, customizable by developers, and follows the +conventions of common word processing programs.
      + +

    5. Lightweight
    6. +
      htmlArea needs to be fast loading, allow the user to perform word processing functions at a +reasonable speed, and not put a lot of strain on a user's browser. To these ends we've +managed to keep the main editor program in a single file of only 40k and we've written the editor +in such a way that it has a minimal impact on the resources of the browser it is running in. +In addition, where we make use of popup windows to perform additional functions we try to put as +much code as possible in the popup window so it doesn't increase the size of the base editor.
      + +
    + +

    + + + +

    This editor is pretty neat, so how does it actually work?
    +
    htmlArea is based on the MSHTML Editing Platform +in Internet Explorer 5.5+ on windows. Basically, Internet Explorer includes some functionality to make sections of a +webpage editable by defining a "contentEditable" attribute or "designMode" property. It also provides some built in +commands +for performing common web editing operations (bold, italic, center, insert image, etc). + +

    htmlArea builds on the features provided by Internet Explorer and adds its own user definable toolbar, +an easy method to include a WYSIWYG editor in a web page (replacing textareas), an easy way to save user +changes, as well as a number of custom web editing commands of its own. + +

    How htmlArea actually works is it replaces a textarea with an (user definable) toolbar, an iframe that +has the "contentEditable" attribute set to true, and a hidden field with the same name as your original +textarea that gets updated automatically when you modify content in the editor. + +

    The user can enter or modify text as well as use keyboard shortcuts and toolbar buttons to perform operations +on the content. A lot of the editor commands are built into IE and called via +the execCommand +method, but htmlArea also includes other custom commands and functions written in JavaScript and stored in +the editor.js file or the popup windows (in the /popups/ folder). + + +

    + + +

    You don't happen to have one of these for (Netscape, Mozilla, Opera, Mac IE, etc) do you?
    +
    No. None of these other browsers (including IE for Mac) support "contentEditable" or a way to make +existing content in the page editable. It might be possible to emulate this in JavaScript, but it would +be a lot of work. Other problems include displaying or emulating the flashing | bar cursor you see when +editing. The cross-platform Mozilla browser has some bug entries related to adding contentEditable +functionality, and perhaps in the future it may be possible to create something for that browser. +

    Although it's a long shot, you might want to send a friendly letter to Microsoft to encourage them to +make the "contentEditable" functionality work on IE for the Macintosh. Once they implement it, we can offer it. + + +

    + + +

    Why doesn't htmlArea output XHTML instead of regular HTML? Can you make it do that?
    +
    The HTML output by htmlArea is generated by the built in functionality of Internet Explorer. +For that reason, there is no easy way to have it output XHTML. If we were going to do it, the way +to do so would be to parse the HTML after it's output by IE and convert it to XHTML. That's something +we hope to do at some point. + +

    + + +

    I'd like to be able to upload images from my hard drive, can you add that feature?
    +
    No. We want htmlArea to be compatible with as many programming languages as possible. Because it's +written in client side JavaScript, it should work with any programming language. If we start adding +language specific features htmlArea won't be as useful to as many people. That said, there's a lot of +free "file upload" scripts available, and htmlArea does include a function called editor_insertHTML()\ +for inserting text or HTML tags. If you want to write your own program for doing this it should be +that hard. Alternatively, you might check in the forum to see if someone already has. +

    + + +

    I'd like to <insert idea here>, can you add that feature?
    +
    Maybe, maybe not. If it's a good feature and it fits in with the goals of our project we'll +likely consider it. The best thing to do is post your suggestions to the +forum. At the very least +we'll try to give you some suggestions and point you in the right direction. At best you might +find somebody else has already implemented the feature you were hoping for. + + +

    + + +

    Can I change the toolbar/button colors?
    +
    Yes, just search for "buttonface" and "buttonhighlight" in editor.js and change those to whatever colors +you like. If you haven't heard of those colors before, it's because they're special windows colors +that match whatever color scheme the user has selected for their desktop. For example, if someone +has changed their desktop color scheme to "lilac", the WYSIWYG editor toolbar and buttons will match that +theme. Try it, it's really neat.

    + + +

    I love htmlArea, is there anything I can do to help the project?
    +
    The number one thing you can do to help is also the easiest thing to do; give us a link on your website. +The more people who can find out about htmlArea the better it will be. + +

    The next best thing you can do is participate in our +forum and post a message or two to +help other htmlArea users (or learn something new yourself). + +

    Lastly, any code improvements you want to share would certainly be welcome as well.

    + + +

    Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?
    +
    This is a bug/feature of Internet Explorer. htmlArea dynamically updates the content of your page to replace +a textarea with the WYSIWYG editor. In Internet Explorer, when you update the content of a page after it has loaded +and insert an image it will load the image from the server EVEN if has the image in it's cache. This means if you have 10 +htmlareas on the same page the "bold" toolbar button will be loaded 10 times. + +

    One workaround for this is to move all your editor_generate() scripts to the bottom of the page, combine them +into one script tag, and remove the "defer" attribute from that script tag. This will cause them all to run just +as the page is finishing loading and the cached images WILL be used. Meaning, the browser will only need to load each +image once. + + +

    + + + +

    Known Bugs and Issues back to top

    +
    + + +

    Undo/Redo doesn't work
    +
    We update a hidden field every time you make a change in the editor so the hidden field will be +submitted when you submit the form. The way undo/redo works in Internet Explorer it seems to reset +the undo buffer every time you use JavaScript to set the value of a form element or otherwise make +changes to the page. Because of this the built in undo/redo functionality of the browser doesn't +work. We hope to implement our own undo/redo functionality at a future point.

    + + +

    Relative paths are converted to absolute paths
    +
    Internet Explorer has a tendency to convert relative paths into absolute paths. We've seen some +implementations of WYSIWYG editors that maintain relative paths "better" than others but certain operations +(such as dragging and dropping, etc) still convert relative paths to absolute paths. We hope to find a +workaround for this in a future version. +

    + + +

    HTML header info (eg: <head>, <body>, etc) doesn't get preserved
    +
    This is due to Internet Explorer and the way the editor works. The editor already has a +HTML header of its own so inserting another one confuses the browser and the content gets thrown +away. The best solution is to have another plain text textarea field for HTML header information.

    + + +

    Some tags (eg: noframes, noscript, etc) doesn't get preserved
    +
    This is a result of how Internet Explorer works. It seems to discard certain tags that it +doesn't need to display. Because htmlArea reads the content back from the browser it cannot +preserve content the browser has "thrown away".

    + + +

    htmlArea doesn't work with multiple textareas that have the same name
    +
    If you have two or more textareas with the same name on the same page and you try +to convert one or more of them into a WYSIWYG editor htmlArea won't work. This is because htmlArea +looks up the textareas by name in the entire page, not just inside a specific form. There's currently +no workaround for this. We hope to resolve it in a future release.

    + + +

    Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?
    +
    This is a bug/feature of Internet Explorer. Even if you get unsecure warnings your form contents should +still be submitted securely. + +

    htmlArea uses an <iframe> to contain the editor and because the contents of the iframe isn't being +loaded off a secure site, Internet Explorer thinks the iframe is unsecure. The problem is, the iframe doesn't +load anything off any site, it's blank, it doesn't even have a src attribute. We just create an empty iframe +and then use javascript to update it. We hope to have this fixed in a future release. + +

    Note: There's a clever workaround for this problem posted in the forum here. +The only issue with it is that can cause the back button to not work as intended (it goes back in the iframe first). + +

    + + + +
    + +

    Change Log back to top

    +
    + + + + + + + + + +

    Version 2.03 (Released: December 17, 2002)
    + +

      +
    • new license - switched to "BSD style" software license. The "About this editor" button is no longer required. +
    • readme updates - minor updates, spelling, and grammer fixes. +
    + +

    + + + + +

    Version 2.02a (Released: December 5, 2002)
    + +

      +
    • fixed error in readme.html example code under "How do I add htmlArea to my web page?". +
    + +

    + + + + + +

    Version 2.02 (Released: December 5, 2002)
      + +

      Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)
      + +
    • fix nested script tag error (thanks to Phil Revill) + +

      New Features
      +
    • added 'replaceNextlines' config option to replace nextlines with spaces on output +
    • added 'plaintextInput' config option to replace nextlines with <br> tags on input +
    + +

    + + + + + +

    Version 2.01 (Released: December 3, 2002)
      + +

      Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)
      + +
    • fixed "function not found" error for non IE5.5+ browsers (thanks to slowhand) +
    • popup editor - fixed javascript error caused during launch of popup (thanks to slowhand and Chlorel) +
    • popup editor - fixed toolbar 'linebreak' error (thanks to fbridge9 and RekiM) + +

      Documentation Updates
      +
    • Add two new questions to readme.html +
        +
      • Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?
        +
      • Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?
        +
      + +

      + + + +

      Version 2.00 (official release) (Released: November 25, 2002)
        + +

        New Javascript Functions
        +
      • editor_getHTML(objname) - return HTML content of editor +
      • editor_setHTML(objname) - set HTML content of editor +
      • editor_appendHTML(objname) - add HTML content to editor + +

        New Features
        +
      • Popup "fullscreen" editor now has minimize and maximize buttons (switched from ModalDialog to popup window) + +

        Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)
        +
      • "Create Table" popup now creates tables with the correct number of cols and rows (thanks to Corey) +
      • Clicking on images no longer causes error when you have "CSS style pulldown" enabled (thanks to Virrdo) +
      • Fixed bug that prevented external stylesheets from working properly (thanks to slowhand) +
      • fixed javascript errors in Mozilla 1.0 (thanks to slowhand) +
      • moved browser detection code to editor page to prevent javascript errors from older browsers and prevent the editor from being loaded unless it's needed. +
      • submitting empty htmlarea now submits nothing "" instead of "<p>&nbsp;</p>" +
      • Popup "fullscreen" editor no longer generates error on "<>" html mode change + +

      + + + +

      Version 2.00 (beta2) (Released: October 16, 2002)
        + +

        New Docs
        +
      • created new readme.html with install instructions, faq, and lots of information + +

        New Features
        +
      • added support for stylesheets +
      • get enlarge/shrink window working +
      • get context menu working (still disabled by default, needs more code for functionality) +
      • allow user to change ANY option in internal config from calling page +
      • added _editor_filterOutput function that's called on form submit +
      • added insert table button + +

        Bug Fixes / Optimizations
        +
      • organized associated files into directories +
      • fixed bug that caused htmlarea to sometimes not display last entered content when user pressed back in their browser. +
      • moved about window into a separate file to reduce size of editor + +

      + + +

      Version 2.00 (beta1) (Released: August 19, 2002)
        + +

        visual changes
        +
      • added mouseover/mouseoff events and style for toolbar ui buttons +
      • update toolbar to take up less space and be smaller +
      • display point sizes beside HTML font sizes (eg: 7 (36px) +
      • change "about this editor" icon to an "i" +
      • created a help popup (content still needs to be written). +
      • added version number to about page. + +

        code changes
        +
      • added "defer" to script tag to prevent editor from being created until page loads +
      • simplified header that needs to be added to pages that contain editor +
      • generated script include tag using _editor_url so users don't have to enter URL twice +
      • moved CSS for editor toolbar buttons into editor.js +
      • switched to using object to pass configuration arguments to editor_generate +
      • general code improvements, optimizations and re-organization +
      • added hooks for keypress events for future use + +

        new features
        +
      • added pulldown for CSS style classnames +
      • added many many more config options including: +
      • ability to select which toolbar elements you want displayed +
      • ability to specify the order of toolbar elements +
      • ability to specify fonts, sizes, and CSS styles for pulldowns +
      • ability to set default font and style used in editor window +
      • debug flag that lets you see the source of the WYSIWYG field at all times +
      • add more sample code and comments showing how to add custom buttons + +

        bug fixes
        +
      • fixed error caused when height/width were manually specified (reported by jpeto, thanks!) +
      • "about this editor" window now works when in textedit mode +

      + + + + +

      Version 1.05 (Released: August 28, 2002)
        +
      • - Added support for textareas with underscores ("_") in their names.
      • +

      + + + +

      Version 1.04 (Released: August 27, 2002)
        +
      • Even more speed improvements (WYSIWYG editor is now much faster on older computers).
      • +
      • General code improvements and optimizations.
      • +

      + + + +

      Version 1.03 (Released: August 26, 2002)
        +
      • Beta release only
      • +

      + + + +

      Version 1.02 (Released: August 21, 2002)
        +
      • added editor_insertHTML() function. Developers can now easily add buttons that insert HTML or surround selected text with HTML.
      • +
      • removed unneeded debug code and comments to reduce editor.js file size (and load time).
      • +

      + + + +

      Version 1.01 (Released: August 20, 2002)
        +
      • optimized code to improve speed (WYSIWYG editor is now much faster)
      • +
      • added addition event handlers to update UI on mouse events.
      • +

      + + + +

      Version 1.00 (Released: August 19, 2002)
        +
      • Initial Release
      • +

      + + + +
    + +


    + \ No newline at end of file diff --git a/gulliver/thirdparty/jsmin/jsmin.php b/gulliver/thirdparty/jsmin/jsmin.php new file mode 100644 index 000000000..2e01ce467 --- /dev/null +++ b/gulliver/thirdparty/jsmin/jsmin.php @@ -0,0 +1,292 @@ + + * @copyright 2002 Douglas Crockford (jsmin.c) + * @copyright 2008 Ryan Grove (PHP port) + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 1.1.1 (2008-03-02) + * @link http://code.google.com/p/jsmin-php/ + */ + +class JSMin { + const ORD_LF = 10; + const ORD_SPACE = 32; + + protected $a = ''; + protected $b = ''; + protected $input = ''; + protected $inputIndex = 0; + protected $inputLength = 0; + protected $lookAhead = null; + protected $output = ''; + + // -- Public Static Methods -------------------------------------------------- + + public static function minify($js) { + $jsmin = new JSMin($js); + return $jsmin->min(); + } + + // -- Public Instance Methods ------------------------------------------------ + + public function __construct($input) { + $this->input = str_replace("\r\n", "\n", $input); +// $this->input = str_replace("\n", "", $this->input); + $this->inputLength = strlen($this->input); + } + + // -- Protected Instance Methods --------------------------------------------- + + protected function action($d) { + switch($d) { + case 1: + $this->output .= $this->a; + + case 2: + $this->a = $this->b; + + if ($this->a === "'" || $this->a === '"') { + for (;;) { + $this->output .= $this->a; + $this->a = $this->get(); + + if ($this->a === $this->b) { + break; + } + + if (ord($this->a) <= self::ORD_LF) { + throw new JSMinException('Unterminated string literal.'); + } + + if ($this->a === '\\') { + $this->output .= $this->a; + $this->a = $this->get(); + } + } + } + + case 3: + $this->b = $this->next(); + + if ($this->b === '/' && ( + $this->a === '(' || $this->a === ',' || $this->a === '=' || + $this->a === ':' || $this->a === '[' || $this->a === '!' || + $this->a === '&' || $this->a === '|' || $this->a === '?')) { + + $this->output .= $this->a . $this->b; + + for (;;) { + $this->a = $this->get(); + + if ($this->a === '/') { + break; + } elseif ($this->a === '\\') { + $this->output .= $this->a; + $this->a = $this->get(); + } elseif (ord($this->a) <= self::ORD_LF) { + throw new JSMinException('Unterminated regular expression '. + 'literal.'); + } + + $this->output .= $this->a; + } + + $this->b = $this->next(); + } + } + } + + protected function get() { + $c = $this->lookAhead; + $this->lookAhead = null; + + if ($c === null) { + if ($this->inputIndex < $this->inputLength) { + $c = $this->input[$this->inputIndex]; + $this->inputIndex += 1; + } else { + $c = null; + } + } + + if ($c === "\r") { + return "\n"; + } + + if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) { + return $c; + } + + return ' '; + } + + protected function isAlphaNum($c) { + return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1; + } + + protected function min() { + $this->a = "\n"; + $this->action(3); + + while ($this->a !== null) { + switch ($this->a) { + case ' ': + if ($this->isAlphaNum($this->b)) { + $this->action(1); + } else { + $this->action(2); + } + break; + + case "\n": + switch ($this->b) { + case '{': + case '[': + case '(': + case '+': + case '-': + $this->action(1); + break; + + case ' ': + $this->action(3); + break; + + default: + if ($this->isAlphaNum($this->b)) { + $this->action(1); + } + else { + $this->action(2); + } + } + break; + + default: + switch ($this->b) { + case ' ': + if ($this->isAlphaNum($this->a)) { + $this->action(1); + break; + } + + $this->action(3); + break; + + case "\n": + switch ($this->a) { + case '}': + case ']': + case ')': + case '+': + case '-': + case '"': + case "'": + $this->action(1); + break; + + default: + if ($this->isAlphaNum($this->a)) { + $this->action(1); + } + else { + $this->action(3); + } + } + break; + + default: + $this->action(1); + break; + } + } + } + + return $this->output; + } + + protected function next() { + $c = $this->get(); + + if ($c === '/') { + switch($this->peek()) { + case '/': + for (;;) { + $c = $this->get(); + + if (ord($c) <= self::ORD_LF) { + return $c; + } + } + + case '*': + $this->get(); + + for (;;) { + switch($this->get()) { + case '*': + if ($this->peek() === '/') { + $this->get(); + return ' '; + } + break; + + case null: + throw new JSMinException('Unterminated comment.'); + } + } + + default: + return $c; + } + } + + return $c; + } + + protected function peek() { + $this->lookAhead = $this->get(); + return $this->lookAhead; + } +} + +// -- Exceptions --------------------------------------------------------------- +class JSMinException extends Exception {} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/INSTALL b/gulliver/thirdparty/krumo/INSTALL new file mode 100644 index 000000000..e6117c854 --- /dev/null +++ b/gulliver/thirdparty/krumo/INSTALL @@ -0,0 +1,32 @@ +------------------------------------------------------------------------------ + + SETUP: How to install Krumo ? + +------------------------------------------------------------------------------ + +In order to use Krumo you have to put it on your (development) server, and +include it in your script. You can put it somewhere in the INCLUDE_PATH, or +specify the full path to the "class.krumo.php" file. + +You have to modify the "krumo.ini" file too. It is the configuration file for +Krumo. The first option is choosing a skin: + + [skin] + selected = "orange" + +The value for this setting has to be the name of one of the sub-folders from the +"Krumo/skins/" folder. If the value provided for the skin results in not finding +the skin, the `default` skin will be used instead. + +The second option is used to set the correct web path to the folder where Krumo +is installed. This is used in order to make the images from Krumo's CSS skins +web-accessible. + + [css] + url = "http://www.example.com/Krumo/" + +So far those two are the only configuration options. + +All the CSS files ("skin.css") from the "Krumo/skins/" sub-folders must have the +proper permissions in order to be readable from Krumo. Same applies for +"krumo.ini" and "krumo.js" files. \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/LICENSE b/gulliver/thirdparty/krumo/LICENSE new file mode 100644 index 000000000..03851a338 --- /dev/null +++ b/gulliver/thirdparty/krumo/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/gulliver/thirdparty/krumo/README b/gulliver/thirdparty/krumo/README new file mode 100644 index 000000000..93914098b --- /dev/null +++ b/gulliver/thirdparty/krumo/README @@ -0,0 +1,103 @@ +============================================================================= + + Krumo + version 0.2.1a + +============================================================================= + +You probably got this package from... +http://www.sourceforge.net/projects/krumo/ + +If there is no licence agreement with this package please download +a version from the location above. You must read and accept that +licence to use this software. The file is titled simply LICENSE. + +OVERVIEW +------------------------------------------------------------------------------ +To put it simply, Krumo is a replacement for print_r() and var_dump(). By +definition Krumo is a debugging tool (for PHP5), which displays structured +information about any PHP variable. + +A lot of developers use print_r() and var_dump() in the means of debugging +tools. Although they were intended to present human readble information about a +variable, we can all agree that in general they are not. Krumo is an +alternative: it does the same job, but it presents the information beautified +using CSS and DHTML. + +EXAMPLES +------------------------------------------------------------------------------ +Here's a basic example, which will return a report on the array variable passed +as argument to it: + + krumo(array('a1'=> 'A1', 3, 'red')); + +You can dump simultaneously more then one variable - here's another example: + + krumo($_SERVER, $_REQUEST); + +You probably saw from the examples above that some of the nodes are expandable, +so if you want to inspect the nested information, click on them and they will +expand; if you do not need that information shown simply click again on it to +collapse it. Here's an example to test this: + + $x1->x2->x3->x4->x5->x6->x7->x8->x9 = 'X10'; + krumo($x1); + +The krumo() is the only standalone function from the package, and this is +because basic dumps about variables (like print_r() or var_dump()) are the most +common tasks such functionality is used for. The rest of the functionality can +be called using static calls to the Krumo class. Here are several more examples: + + // print a debug backgrace + krumo::backtrace(); + + // print all the included(or required) files + krumo::includes(); + + // print all the included functions + krumo::functions(); + + // print all the declared classes + krumo::classes(); + + // print all the defined constants + krumo::defines(); + + ... and so on, etc. + +A full PHPDocumenter API documentation exists both in this package and at the +project's website. + +INSTALL +------------------------------------------------------------------------------ +Read the INSTALL file. + +DOCUMENTATION +------------------------------------------------------------------------------ +As I said, a full PHPDocumenter API documentation can be found both in this +package and at the project's website. + +SKINS +------------------------------------------------------------------------------ +There are several skins pre-installed with this package, but if you wish you can +create skins of your own. The skins are simply CSS files that are prepended to +the result that Krumo prints. If you want to use images in your CSS (for +background, list-style, etc), you have to put "%URL%" in front of the image URL +in order hook it up to the skin folder and make the image web-accessible. + +Here's an example: + + ul.krumo-first {background: url(%url%bg.gif);} + +TODO +------------------------------------------------------------------------------ +You can find the list of stuff that is going to be added to this project in the +TODO file from this very package. + +CONTRIBUTION +----------------------------------------------------------------------------- +If you download and use and possibly even extend this tool, please let us know. +Any feedback, even bad, is always welcome and your suggestions are going to be +considered for our next release. Please use our SourceForge page for that: + + http://www.sourceforge.net/projects/krumo/ diff --git a/gulliver/thirdparty/krumo/TODO b/gulliver/thirdparty/krumo/TODO new file mode 100644 index 000000000..d1de49fab --- /dev/null +++ b/gulliver/thirdparty/krumo/TODO @@ -0,0 +1,24 @@ +****************************************************************************** + + Krumo: TODO + +****************************************************************************** + +BUGS +---------------- + - watch the SourceForge.net Bug Tracker + +Features: PHP +---------------- + - Try to detect anonymous (lambda) functions + - Try to detect whether an array is indexed or associated + - Add var_export support for arrays and objects + - Add JSON support for arrays and objects + +Features: GUI +---------------- + - Nicer and friendlier skin(s) + - Add top-level links for collapsing and expanding the whole tree + - Add object & array -level links for collapsing and expanding all the + nested nodes + - Print all parent classes for the rendered objects \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/VERSION b/gulliver/thirdparty/krumo/VERSION new file mode 100644 index 000000000..8d940129e --- /dev/null +++ b/gulliver/thirdparty/krumo/VERSION @@ -0,0 +1 @@ +0.2.1a \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/class.krumo.php b/gulliver/thirdparty/krumo/class.krumo.php new file mode 100644 index 000000000..1d9ec62c7 --- /dev/null +++ b/gulliver/thirdparty/krumo/class.krumo.php @@ -0,0 +1,1302 @@ + +* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License Version 2.1 +* +* @package Krumo +* @version $Id: class.krumo.php 22 2007-12-02 07:38:18Z Mrasnika $ +*/ + +////////////////////////////////////////////////////////////////////////////// + +/** +* backward compatibility: the DIR_SEP constant isn't used anymore +*/ +if(!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); + } +/** +* backward compatibility: the PATH_SEPARATOR constant is availble since 4.3.0RC2 +*/ +if (!defined('PATH_SEPARATOR')) { + define('PATH_SEPARATOR', OS_WINDOWS ? ';' : ':'); + } + +// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +/** +* Set the KRUMO_DIR constant up with the absolute path to Krumo files. If it is +* not defined, include_path will be used. Set KRUMO_DIR only if any other module +* or application has not already set it up. +*/ +if (!defined('KRUMO_DIR')) { + define('KRUMO_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); + } + +/** +* This constant sets the maximum strings of strings that will be shown +* as they are. Longer strings will be truncated with this length, and +* their `full form` will be shown in a child node. +*/ +if (!defined('KRUMO_TRUNCATE_LENGTH')) { + define('KRUMO_TRUNCATE_LENGTH', 50); + } + +////////////////////////////////////////////////////////////////////////////// + +/** +* Krumo API +* +* This class stores the Krumo API for rendering and +* displaying the structured information it is reporting +* +* @package Krumo +*/ +Class krumo { + + public static $show_details; + + /** + * Return Krumo version + * + * @return string + * @access public + * @static + */ + Public Static Function version() { + return '0.2.1a'; + } + + // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + /** + * Prints a debug backtrace + * + * @access public + * @static + */ + Public Static Function backtrace() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + return krumo::dump(debug_backtrace()); + } + + /** + * Prints a list of all currently declared classes. + * + * @access public + * @static + */ + Public Static Function classes() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all currently declared classes. +
    + +
    +This is a list of all currently declared interfaces. +
    + +
    +This is a list of all currently included (or required) files. +
    + +
    +This is a list of all currently declared functions. +
    + +
    +This is a list of all currently declared constants (defines). +
    + +
    +This is a list of all currently loaded PHP extensions. +
    + +
    +This is a list of all HTTP request headers. +
    + php.ini
    + * + * @access public + * @static + */ + Public Static Function phpini() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + if (!readable(get_cfg_var('cfg_file_path'))) { + return false; + } + + // render it + // + ?> +
    +This is a list of the configuration settings read from . +
    + +
    +This is a list of all your configuration settings. +
    + include_path
    option. + * + * @access public + * @static + */ + Public Static Function path() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of the specified directories under your include_path option. +
    + $_REQUEST
    array. + * + * @access public + * @static + */ + Public Static Function request() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_REQUEST array. +
    + $_GET array. + * + * @access public + * @static + */ + Public Static Function get() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_GET array. +
    + $_POST array. + * + * @access public + * @static + */ + Public Static Function post() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_POST array. +
    + $_SERVER array. + * + * @access public + * @static + */ + Public Static Function server() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_SERVER array. +
    + $_COOKIE array. + * + * @access public + * @static + */ + Public Static Function cookie() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_COOKIE array. +
    + $_ENV array. + * + * @access public + * @static + */ + Public Static Function env() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_ENV array. +
    + $_SESSION array. + * + * @access public + * @static + */ + Public Static Function session() { + + // disabled ? + // + if (!krumo::_debug()) { + return false; + } + + // render it + // + ?> +
    +This is a list of all the values from the $_SESSION array. +
    + +
    +This is a list of all the values from the INI file. +
    + 1) { + $_ = func_get_args(); + foreach($_ as $d) { + krumo::dump($d); + } + return; + } + + // the css ? + // + krumo::_css(); + + // find caller + // + $_ = debug_backtrace(); + while($d = array_pop($_)) { + if ((strToLower($d['function']) == 'krumo') || (strToLower(@$d['class']) == 'krumo')) { + break; + } + } + + // the content + // + ?> +
    + +
    +$bee){ + if (is_object($bee)) { + unset($hive[$i]->$_recursion_marker); + } else { + unset($hive[$i][$_recursion_marker]); + } + } + } + + // PHP 4.x.x array reference bug... + // + if (is_array($data) && version_compare(PHP_VERSION, "5", "<")) { + unset($GLOBALS[krumo::_marker()]); + } + } + + // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + /** + * Returns values from Krumo's configuration + * + * @param string $group + * @param string $name + * @param mixed $fallback + * @return mixed + * + * @access private + * @static + */ + Private Static Function _config($group, $name, $fallback=null) { + + static $_config = array(); + + // not loaded ? + // + if (empty($_config)) { + $_config = (array) @parse_ini_file( + KRUMO_DIR . 'krumo.ini', + true); + } + + // exists ? + // + return (isset($_config[$group][$name])) + ? $_config[$group][$name] + : $fallback; + } + + // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + /** + * Print the skin (CSS) + * + * @return boolean + * @access private + * @static + */ + Private Static Function _css() { + + static $_css = false; + + // already set ? + // + if ($_css) { + return true; + } + + $css = ''; + $skin = krumo::_config('skin', 'selected', 'default'); + + // custom selected skin ? + // + $_ = KRUMO_DIR . "skins/{$skin}/skin.css"; + if ($fp = @fopen($_, 'r', 1)) { + $css = fread($fp, filesize($_)); + fclose($fp); + } + + // defautl skin ? + // + if (!$css && ($skin != 'default')) { + $skin = 'default'; + $_ = KRUMO_DIR . "skins/default/skin.css"; + $css = join('', @file($_)); + } + + // print ? + // + if ($_css = $css != '') { + + // fix the urls + // + $css_url = krumo::_config('css', 'url') . "skins/{$skin}/"; + $css = preg_replace('~%url%~Uis', $css_url, $css); + + // the CSS + // + ?> + + + +
  • +
    + + + (NULL) +
    +
  • +$_recursion_marker++) + : @($bee[$_recursion_marker]++); + + $_[0][] =& $bee; + } + + // return all bees + // + return $_[0]; + } + + // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + /** + * Render a dump for the properties of an array or objeect + * + * @param mixed &$data + * @access private + * @static + */ + Private Static Function _vars(&$data) { + + $_is_object = is_object($data); + + // test for references in order to + // prevent endless recursion loops + // + $_recursion_marker = krumo::_marker(); + $_r = ($_is_object) + ? @$data->$_recursion_marker + : @$data[$_recursion_marker] ; + $_r = (integer) $_r; + + // recursion detected + // + if ($_r > 0) { + return krumo::_recursion(); + } + + // stain it + // + krumo::_hive($data); + + // render it + // + ?> + + + + +
  • + +
    0) {?> onClick="krumo.toggle(this);" + onMouseOver="krumo.over(this);" + onMouseOut="krumo.out(this);"> + + + (Array, ) + + + + | + (Callback) + ::(); + + +
    + + +
  • + +
  • + +
    0) {?> onClick="krumo.toggle(this);" + onMouseOver="krumo.over(this);" + onMouseOut="krumo.out(this);"> + + + (Object) + +
    + + +
  • + +
  • + +
    + + + (Resource) + +
    + +
  • + +
  • + +
    + + + (Boolean) + +
    + +
  • + +
  • + +
    + + + (Integer) + +
    + +
  • + +
  • + +
    + + + (Float) + +
    + +
  • + KRUMO_TRUNCATE_LENGTH) { + $_ = substr($data, 0, KRUMO_TRUNCATE_LENGTH - 3) . '...'; + $_extra = true; + } +?> +
  • + +
    onClick="krumo.toggle(this);" + onMouseOver="krumo.over(this);" + onMouseOut="krumo.out(this);"> + + + (String, + characters ) + + + + | + (Callback) + (); + + +
    + + + + +
  • + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/Krumo/_class.krumo.php.html b/gulliver/thirdparty/krumo/docs/Krumo/_class.krumo.php.html new file mode 100644 index 000000000..05ac34528 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/Krumo/_class.krumo.php.html @@ -0,0 +1,267 @@ + + + + + + Docs for page class.krumo.php + + + + + +
    +

    File/class.krumo.php

    + + +
    +
    Description
    + +
    + +

    Krumo: Structured information display solution

    +

    Krumo is a debugging tool (PHP5 only), which displays structured information about any PHP variable. It is a nice replacement for print_r() or var_dump() which are used by a lot of PHP developers.

    + + +
    +
    + + +
    +
    Classes
    + +
    + + + + + + + + + +
    ClassDescription
    +  class + krumo + + Krumo API +
    +
    +
    + + + +
    +
    Constants
    + +
    + +
    + +
    + + + DIR_SEP = DIRECTORY_SEPARATOR + (line 22) + +
    + + +

    backward compatibility: the DIR_SEP constant isn't used anymore

    + + +
    + +
    + +
    + + + KRUMO_DIR = dirname(__FILE__).DIRECTORY_SEPARATOR + (line 39) + +
    + + +

    Set the KRUMO_DIR constant up with the absolute path to Krumo files. If it is not defined, include_path will be used. Set KRUMO_DIR only if any other module or application has not already set it up.

    + + +
    + +
    + +
    + + + KRUMO_TRUNCATE_LENGTH = 50 + (line 48) + +
    + + +

    This constant sets the maximum strings of strings that will be shown as they are. Longer strings will be truncated with this length, and their `full form` will be shown in a child node.

    + + +
    + +
    + +
    + + + PATH_SEPARATOR = OS_WINDOWS?';':':' + (line 28) + +
    + + +

    backward compatibility: the PATH_SEPARATOR constant is availble since 4.3.0RC2

    + + +
    +
    +
    + + + +
    +
    Functions
    + +
    + +
    + +
    + + krumo (line 1295) +
    + + +

    Alias of krumo::dump()

    + +
    + void + + krumo + + ([mixed $data,... = ]) +
    + +
      +
    • + mixed + $data,...
    • +
    + + +
    +
    +
    + +

    + Documentation generated on Sun, 02 Dec 2007 09:43:24 +0200 by phpDocumentor 1.4.0a2 +

    +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/Krumo/_class_krumo_php.html b/gulliver/thirdparty/krumo/docs/Krumo/_class_krumo_php.html new file mode 100644 index 000000000..ffbee47e0 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/Krumo/_class_krumo_php.html @@ -0,0 +1,269 @@ + + + + + + Docs for page class.krumo.php + + + + + +
    +

    File/class.krumo.php

    + + +
    +
    Description
    + +
    + +

    Krumo: Structured information display solution

    +

    Krumo is a debugging tool (PHP4/PHP5), which displays structured information about any PHP variable. It is a nice replacement for print_r() or var_dump() which are used by a lot of PHP developers.

    + + +
    +
    + + +
    +
    Classes
    + +
    + + + + + + + + + +
    ClassDescription
    +  class + krumo + + Krumo API +
    +
    +
    + + + +
    +
    Constants
    + +
    + +
    + +
    + + + DIR_SEP = DIRECTORY_SEPARATOR + (line 22) + +
    + + +

    backward compatibility: the DIR_SEP constant isn't used anymore

    + + +
    + +
    + +
    + + + KRUMO_DIR = dirname(__FILE__).DIRECTORY_SEPARATOR + (line 39) + +
    + + +

    Set the KRUMO_DIR constant up with the absolute path to Krumo files. If it is not defined, include_path will be used. Set KRUMO_DIR only if any other module or application has not already set it up.

    + + +
    + +
    + +
    + + + KRUMO_TRUNCATE_LENGTH = 50 + (line 48) + +
    + + +

    This constant sets the maximum strings of strings that will be shown as they are. Longer strings will be truncated with this length, and their `full form` will be shown in a child node.

    + + +
    + +
    + +
    + + + PATH_SEPARATOR = OS_WINDOWS?';':':' + (line 28) + +
    + + +

    backward compatibility: the PATH_SEPARATOR constant is availble since 4.3.0RC2

    + + +
    +
    +
    + + + +
    +
    Functions
    + +
    + +
    + +
    + + krumo (line 1296) +
    + + +

    Alias of krumo::dump()

    + +
    + void + + krumo + + ([mixed $data,... + = ]) +
    + +
      +
    • + mixed + $data,... +
    • +
    + + +
    +
    +
    + +

    + Documentation generated on Sat, 16 Jun 2007 09:50:08 +0300 by phpDocumentor 1.3.0RC4 +

    +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/Krumo/krumo.html b/gulliver/thirdparty/krumo/docs/Krumo/krumo.html new file mode 100644 index 000000000..ce4d33b89 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/Krumo/krumo.html @@ -0,0 +1,900 @@ + + + + + + Docs For Class krumo + + + + + +
    +

     Class krumo

    + + +
    +
    Description
    + +
    + +

    Krumo API

    +

    This class stores the Krumo API for rendering and displaying the structured information it is reporting

    +

    + Located in /class.krumo.php (line 61) +

    + + +
    
    +	
    +			
    +
    + + + + + +
    +
    Method Summary
    + +
    +
    + +
    +  + static void + backtrace + () +
    + +
    +  + static void + classes + () +
    + +
    +  + static void + conf + () +
    + +
    +  + static void + cookie + () +
    + +
    +  + static void + defines + () +
    + +
    +  + static boolean + disable + () +
    + +
    +  + static void + dump + ( $data, mixed $data,...) +
    + +
    +  + static boolean + enable + () +
    + +
    +  + static void + env + () +
    + +
    +  + static void + extensions + () +
    + +
    +  + static void + functions + () +
    + +
    +  + static void + get + () +
    + +
    +  + static void + headers + () +
    + +
    +  + static void + includes + () +
    + +
    +  + static void + ini + (string $ini_file) +
    + +
    +  + static void + interfaces + () +
    + +
    +  + static void + path + () +
    + +
    +  + static void + phpini + () +
    + +
    +  + static void + post + () +
    + +
    +  + static void + request + () +
    + +
    +  + static void + server + () +
    + +
    +  + static void + session + () +
    + +
    +  + static string + version + () +
    +
    +
    +
    + + + +
    +
    Methods
    + +
    + + +
    + +
    + + static backtrace (line 82) +
    + + +

    Prints a debug backtrace

    +
      +
    • access: public
    • +
    + +
    + static void + + backtrace + + () +
    + + + +
    + +
    + +
    + + static classes (line 101) +
    + + +

    Prints a list of all currently declared classes.

    +
      +
    • access: public
    • +
    + +
    + static void + + classes + + () +
    + + + +
    + +
    + +
    + + static conf (line 297) +
    + + +

    Prints a list of all your configuration settings.

    +
      +
    • access: public
    • +
    + +
    + static void + + conf + + () +
    + + + +
    + +
    + +
    + + static cookie (line 441) +
    + + +

    Prints a list of all the values from the $_COOKIE array.

    +
      +
    • access: public
    • +
    + +
    + static void + + cookie + + () +
    + + + +
    + +
    + +
    + + static defines (line 197) +
    + + +

    Prints a list of all currently declared constants.

    +
      +
    • access: public
    • +
    + +
    + static void + + defines + + () +
    + + + +
    + +
    + +
    + + static disable (line 747) +
    + + +

    Disable Krumo

    +
      +
    • access: public
    • +
    + +
    + static boolean + + disable + + () +
    + + + +
    + +
    + +
    + + static dump (line 548) +
    + + +

    Dump information about a variable

    +
      +
    • access: public
    • +
    + +
    + static void + + dump + + ( $data, mixed $data,...) +
    + +
      +
    • + mixed + $data,...
    • +
    • + + $data
    • +
    + + +
    + +
    + +
    + + static enable (line 736) +
    + + +

    Enable Krumo

    +
      +
    • access: public
    • +
    + +
    + static boolean + + enable + + () +
    + + + +
    + +
    + +
    + + static env (line 465) +
    + + +

    Prints a list of all the values from the $_ENV array.

    +
      +
    • access: public
    • +
    + +
    + static void + + env + + () +
    + + + +
    + +
    + +
    + + static extensions (line 221) +
    + + +

    Prints a list of all currently loaded PHP extensions.

    +
      +
    • access: public
    • +
    + +
    + static void + + extensions + + () +
    + + + +
    + +
    + +
    + + static functions (line 173) +
    + + +

    Prints a list of all currently declared functions.

    +
      +
    • access: public
    • +
    + +
    + static void + + functions + + () +
    + + + +
    + +
    + +
    + + static get (line 369) +
    + + +

    Prints a list of all the values from the $_GET array.

    +
      +
    • access: public
    • +
    + +
    + static void + + get + + () +
    + + + +
    + +
    + +
    + + static headers (line 245) +
    + + +

    Prints a list of all HTTP request headers.

    +
      +
    • access: public
    • +
    + +
    + static void + + headers + + () +
    + + + +
    + +
    + +
    + + static includes (line 149) +
    + + +

    Prints a list of all currently included (or required) files.

    +
      +
    • access: public
    • +
    + +
    + static void + + includes + + () +
    + + + +
    + +
    + +
    + + static ini (line 515) +
    + + +

    Prints a list of all the values from an INI file.

    +
      +
    • access: public
    • +
    + +
    + static void + + ini + + (string $ini_file) +
    + +
      +
    • + string + $ini_file
    • +
    + + +
    + +
    + +
    + + static interfaces (line 125) +
    + + +

    Prints a list of all currently declared interfaces (PHP5 only).

    +
      +
    • access: public
    • +
    + +
    + static void + + interfaces + + () +
    + + + +
    + +
    + +
    + + static path (line 321) +
    + + +

    Prints a list of the specified directories under your include_path option.

    +
      +
    • access: public
    • +
    + +
    + static void + + path + + () +
    + + + +
    + +
    + +
    + + static phpini (line 269) +
    + + +

    Prints a list of the configuration settings read from php.ini

    +
      +
    • access: public
    • +
    + +
    + static void + + phpini + + () +
    + + + +
    + +
    + +
    + + static post (line 393) +
    + + +

    Prints a list of all the values from the $_POST array.

    +
      +
    • access: public
    • +
    + +
    + static void + + post + + () +
    + + + +
    + +
    + +
    + + static request (line 345) +
    + + +

    Prints a list of all the values from the $_REQUEST array.

    +
      +
    • access: public
    • +
    + +
    + static void + + request + + () +
    + + + +
    + +
    + +
    + + static server (line 417) +
    + + +

    Prints a list of all the values from the $_SERVER array.

    +
      +
    • access: public
    • +
    + +
    + static void + + server + + () +
    + + + +
    + +
    + +
    + + static session (line 489) +
    + + +

    Prints a list of all the values from the $_SESSION array.

    +
      +
    • access: public
    • +
    + +
    + static void + + session + + () +
    + + + +
    + +
    + +
    + + static version (line 70) +
    + + +

    Return Krumo version

    +
      +
    • access: public
    • +
    + +
    + static string + + version + + () +
    + + + +
    + +
    +
    + + +

    + Documentation generated on Sun, 02 Dec 2007 09:43:24 +0200 by phpDocumentor 1.4.0a2 +

    +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/blank.html b/gulliver/thirdparty/krumo/docs/blank.html new file mode 100644 index 000000000..98c96360e --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/blank.html @@ -0,0 +1,13 @@ + + + Krumo + + + + +

    Krumo

    +Welcome to Krumo!
    +
    +This documentation was generated by phpDocumentor v1.4.0a2
    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/classtrees_Krumo.html b/gulliver/thirdparty/krumo/docs/classtrees_Krumo.html new file mode 100644 index 000000000..8123084b9 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/classtrees_Krumo.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +

    + +

    +

    Root class krumo

    + + +

    + Documentation generated on Sun, 02 Dec 2007 09:43:24 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/elementindex.html b/gulliver/thirdparty/krumo/docs/elementindex.html new file mode 100644 index 000000000..dd757db70 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/elementindex.html @@ -0,0 +1,392 @@ + + + + + + + + + + +

    Full index

    +

    Package indexes

    + +
    +
    + b + c + d + e + f + g + h + i + k + p + r + s + v +
    + + +
    +
    b
    + +
    +
    +
    +
    + Method + backtrace +
    +
    +
    krumo::backtrace() in class.krumo.php
    +
    Prints a debug backtrace
    +
    +
    + +
    +
    c
    + +
    +
    +
    +
    + Method + classes +
    +
    +
    krumo::classes() in class.krumo.php
    +
    Prints a list of all currently declared classes.
    +
    +
    + Page + class.krumo.php +
    +
    +
    class.krumo.php in class.krumo.php
    +
    +
    + Method + conf +
    +
    +
    krumo::conf() in class.krumo.php
    +
    Prints a list of all your configuration settings.
    +
    +
    + Method + cookie +
    +
    +
    krumo::cookie() in class.krumo.php
    +
    Prints a list of all the values from the $_COOKIE array.
    +
    +
    + +
    +
    d
    + +
    +
    +
    +
    + Method + defines +
    +
    +
    krumo::defines() in class.krumo.php
    +
    Prints a list of all currently declared constants.
    +
    +
    + Constant + DIR_SEP +
    +
    +
    DIR_SEP in class.krumo.php
    +
    backward compatibility: the DIR_SEP constant isn't used anymore
    +
    +
    + Method + disable +
    +
    +
    krumo::disable() in class.krumo.php
    +
    Disable Krumo
    +
    +
    + Method + dump +
    +
    +
    krumo::dump() in class.krumo.php
    +
    Dump information about a variable
    +
    +
    + +
    +
    e
    + +
    +
    +
    +
    + Method + enable +
    +
    +
    krumo::enable() in class.krumo.php
    +
    Enable Krumo
    +
    +
    + Method + env +
    +
    +
    krumo::env() in class.krumo.php
    +
    Prints a list of all the values from the $_ENV array.
    +
    +
    + Method + extensions +
    +
    +
    krumo::extensions() in class.krumo.php
    +
    Prints a list of all currently loaded PHP extensions.
    +
    +
    + +
    +
    f
    + +
    +
    +
    +
    + Method + functions +
    +
    +
    krumo::functions() in class.krumo.php
    +
    Prints a list of all currently declared functions.
    +
    +
    + +
    +
    g
    + +
    +
    +
    +
    + Method + get +
    +
    +
    krumo::get() in class.krumo.php
    +
    Prints a list of all the values from the $_GET array.
    +
    +
    + +
    +
    h
    + +
    +
    +
    +
    + Method + headers +
    +
    +
    krumo::headers() in class.krumo.php
    +
    Prints a list of all HTTP request headers.
    +
    +
    + +
    +
    i
    + +
    +
    +
    +
    + Method + includes +
    +
    +
    krumo::includes() in class.krumo.php
    +
    Prints a list of all currently included (or required) files.
    +
    +
    + Method + ini +
    +
    +
    krumo::ini() in class.krumo.php
    +
    Prints a list of all the values from an INI file.
    +
    +
    + Method + interfaces +
    +
    +
    krumo::interfaces() in class.krumo.php
    +
    Prints a list of all currently declared interfaces (PHP5 only).
    +
    +
    + +
    +
    k
    + +
    +
    +
    +
    + Function + krumo +
    +
    +
    krumo() in class.krumo.php
    +
    Alias of krumo::dump()
    +
    +
    + Class + krumo +
    +
    +
    krumo in class.krumo.php
    +
    Krumo API
    +
    +
    + Constant + KRUMO_DIR +
    +
    +
    KRUMO_DIR in class.krumo.php
    +
    Set the KRUMO_DIR constant up with the absolute path to Krumo files. If it is not defined, include_path will be used. Set KRUMO_DIR only if any other module or application has not already set it up.
    +
    +
    + Constant + KRUMO_TRUNCATE_LENGTH +
    +
    +
    KRUMO_TRUNCATE_LENGTH in class.krumo.php
    +
    This constant sets the maximum strings of strings that will be shown as they are. Longer strings will be truncated with this length, and their `full form` will be shown in a child node.
    +
    +
    + +
    +
    p
    + +
    +
    +
    +
    + Method + path +
    +
    +
    krumo::path() in class.krumo.php
    +
    Prints a list of the specified directories under your include_path option.
    +
    +
    + Constant + PATH_SEPARATOR +
    +
    +
    PATH_SEPARATOR in class.krumo.php
    +
    backward compatibility: the PATH_SEPARATOR constant is availble since 4.3.0RC2
    +
    +
    + Method + phpini +
    +
    +
    krumo::phpini() in class.krumo.php
    +
    Prints a list of the configuration settings read from php.ini
    +
    +
    + Method + post +
    +
    +
    krumo::post() in class.krumo.php
    +
    Prints a list of all the values from the $_POST array.
    +
    +
    + +
    +
    r
    + +
    +
    +
    +
    + Method + request +
    +
    +
    krumo::request() in class.krumo.php
    +
    Prints a list of all the values from the $_REQUEST array.
    +
    +
    + +
    +
    s
    + +
    +
    +
    +
    + Method + server +
    +
    +
    krumo::server() in class.krumo.php
    +
    Prints a list of all the values from the $_SERVER array.
    +
    +
    + Method + session +
    +
    +
    krumo::session() in class.krumo.php
    +
    Prints a list of all the values from the $_SESSION array.
    +
    +
    + +
    +
    v
    + +
    +
    +
    +
    + Method + version +
    +
    +
    krumo::version() in class.krumo.php
    +
    Return Krumo version
    +
    +
    + +
    + b + c + d + e + f + g + h + i + k + p + r + s + v +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/elementindex_Krumo.html b/gulliver/thirdparty/krumo/docs/elementindex_Krumo.html new file mode 100644 index 000000000..529c1801a --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/elementindex_Krumo.html @@ -0,0 +1,389 @@ + + + + + + + + + + +

    [Krumo] element index

    +All elements +
    +
    + b + c + d + e + f + g + h + i + k + p + r + s + v +
    + + +
    +
    b
    + +
    +
    +
    +
    + Method + backtrace +
    +
    +
    krumo::backtrace() in class.krumo.php
    +
    Prints a debug backtrace
    +
    +
    + +
    +
    c
    + +
    +
    +
    +
    + Method + classes +
    +
    +
    krumo::classes() in class.krumo.php
    +
    Prints a list of all currently declared classes.
    +
    +
    + Page + class.krumo.php +
    +
    +
    class.krumo.php in class.krumo.php
    +
    +
    + Method + conf +
    +
    +
    krumo::conf() in class.krumo.php
    +
    Prints a list of all your configuration settings.
    +
    +
    + Method + cookie +
    +
    +
    krumo::cookie() in class.krumo.php
    +
    Prints a list of all the values from the $_COOKIE array.
    +
    +
    + +
    +
    d
    + +
    +
    +
    +
    + Method + defines +
    +
    +
    krumo::defines() in class.krumo.php
    +
    Prints a list of all currently declared constants.
    +
    +
    + Constant + DIR_SEP +
    +
    +
    DIR_SEP in class.krumo.php
    +
    backward compatibility: the DIR_SEP constant isn't used anymore
    +
    +
    + Method + disable +
    +
    +
    krumo::disable() in class.krumo.php
    +
    Disable Krumo
    +
    +
    + Method + dump +
    +
    +
    krumo::dump() in class.krumo.php
    +
    Dump information about a variable
    +
    +
    + +
    +
    e
    + +
    +
    +
    +
    + Method + enable +
    +
    +
    krumo::enable() in class.krumo.php
    +
    Enable Krumo
    +
    +
    + Method + env +
    +
    +
    krumo::env() in class.krumo.php
    +
    Prints a list of all the values from the $_ENV array.
    +
    +
    + Method + extensions +
    +
    +
    krumo::extensions() in class.krumo.php
    +
    Prints a list of all currently loaded PHP extensions.
    +
    +
    + +
    +
    f
    + +
    +
    +
    +
    + Method + functions +
    +
    +
    krumo::functions() in class.krumo.php
    +
    Prints a list of all currently declared functions.
    +
    +
    + +
    +
    g
    + +
    +
    +
    +
    + Method + get +
    +
    +
    krumo::get() in class.krumo.php
    +
    Prints a list of all the values from the $_GET array.
    +
    +
    + +
    +
    h
    + +
    +
    +
    +
    + Method + headers +
    +
    +
    krumo::headers() in class.krumo.php
    +
    Prints a list of all HTTP request headers.
    +
    +
    + +
    +
    i
    + +
    +
    +
    +
    + Method + includes +
    +
    +
    krumo::includes() in class.krumo.php
    +
    Prints a list of all currently included (or required) files.
    +
    +
    + Method + ini +
    +
    +
    krumo::ini() in class.krumo.php
    +
    Prints a list of all the values from an INI file.
    +
    +
    + Method + interfaces +
    +
    +
    krumo::interfaces() in class.krumo.php
    +
    Prints a list of all currently declared interfaces (PHP5 only).
    +
    +
    + +
    +
    k
    + +
    +
    +
    +
    + Function + krumo +
    +
    +
    krumo() in class.krumo.php
    +
    Alias of krumo::dump()
    +
    +
    + Class + krumo +
    +
    +
    krumo in class.krumo.php
    +
    Krumo API
    +
    +
    + Constant + KRUMO_DIR +
    +
    +
    KRUMO_DIR in class.krumo.php
    +
    Set the KRUMO_DIR constant up with the absolute path to Krumo files. If it is not defined, include_path will be used. Set KRUMO_DIR only if any other module or application has not already set it up.
    +
    +
    + Constant + KRUMO_TRUNCATE_LENGTH +
    +
    +
    KRUMO_TRUNCATE_LENGTH in class.krumo.php
    +
    This constant sets the maximum strings of strings that will be shown as they are. Longer strings will be truncated with this length, and their `full form` will be shown in a child node.
    +
    +
    + +
    +
    p
    + +
    +
    +
    +
    + Method + path +
    +
    +
    krumo::path() in class.krumo.php
    +
    Prints a list of the specified directories under your include_path option.
    +
    +
    + Constant + PATH_SEPARATOR +
    +
    +
    PATH_SEPARATOR in class.krumo.php
    +
    backward compatibility: the PATH_SEPARATOR constant is availble since 4.3.0RC2
    +
    +
    + Method + phpini +
    +
    +
    krumo::phpini() in class.krumo.php
    +
    Prints a list of the configuration settings read from php.ini
    +
    +
    + Method + post +
    +
    +
    krumo::post() in class.krumo.php
    +
    Prints a list of all the values from the $_POST array.
    +
    +
    + +
    +
    r
    + +
    +
    +
    +
    + Method + request +
    +
    +
    krumo::request() in class.krumo.php
    +
    Prints a list of all the values from the $_REQUEST array.
    +
    +
    + +
    +
    s
    + +
    +
    +
    +
    + Method + server +
    +
    +
    krumo::server() in class.krumo.php
    +
    Prints a list of all the values from the $_SERVER array.
    +
    +
    + Method + session +
    +
    +
    krumo::session() in class.krumo.php
    +
    Prints a list of all the values from the $_SESSION array.
    +
    +
    + +
    +
    v
    + +
    +
    +
    +
    + Method + version +
    +
    +
    krumo::version() in class.krumo.php
    +
    Return Krumo version
    +
    +
    + +
    + b + c + d + e + f + g + h + i + k + p + r + s + v +
    + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/errors.html b/gulliver/thirdparty/krumo/docs/errors.html new file mode 100644 index 000000000..cf21fd427 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/errors.html @@ -0,0 +1,15 @@ + + + + + + phpDocumentor Parser Errors and Warnings + + + + Post-parsing
    +

    + Documentation generated on Sun, 02 Dec 2007 09:43:25 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/index.html b/gulliver/thirdparty/krumo/docs/index.html new file mode 100644 index 000000000..6787e62f0 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/index.html @@ -0,0 +1,24 @@ + + + + + + Krumo + + + + + + + + + + + <H2>Frame Alert</H2> + <P>This document is designed to be viewed using the frames feature. + If you see this message, you are using a non-frame-capable web client.</P> + + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/li_Krumo.html b/gulliver/thirdparty/krumo/docs/li_Krumo.html new file mode 100644 index 000000000..f353e8db6 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/li_Krumo.html @@ -0,0 +1,155 @@ + + + + + + + + + + + + +

    Krumo

    +
    + +
    +

    + Generated by + phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/media/banner.css b/gulliver/thirdparty/krumo/docs/media/banner.css new file mode 100644 index 000000000..1b7fa8a24 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/media/banner.css @@ -0,0 +1,32 @@ +body +{ + background-color: #EEEEEE; + margin: 0px; + padding: 0px; +} + +/* Banner (top bar) classes */ + +.banner { } + +.banner-menu +{ + clear: both; + padding: .5em; + border-top: 2px solid #AAAAAA; +} + +.banner-title +{ + text-align: right; + font-size: 20pt; + font-weight: bold; + margin: .2em; +} + +.package-selector +{ + background-color: #DDDDDD; + border: 1px solid #AAAAAA; + color: #000090; +} diff --git a/gulliver/thirdparty/krumo/docs/media/images/AbstractClass.png b/gulliver/thirdparty/krumo/docs/media/images/AbstractClass.png new file mode 100644 index 0000000000000000000000000000000000000000..afa9d1d9261500c57ec37cff1de8cf43b31dbf25 GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZSaHJ|V9E z|NjRvPcK>oB;jC!uy7wgKahK+w)SFm^_jG^eUXv70s?k;dvAAg+Gb<3&cI-?g2GG& zh8_lnGzNx)iHU~;0{$Bt?{jhjD)_IizRSYmznt6_Lqnj-|B{khH8nS=tN#}e_{zt( zR#EXk2ggfJ&eakUK)aWTi~nF?_`tyMoPps!1H*L&hBwx{7GaqsHK2b=zCZk2F6c8jl1JVN5*@+%rr7PI}^11C*oaK4^xC05VCJK_3< zud|-<{@_}WT(>@P3->I)OHK!WY*;^8{ZU{D!{pbT`vks!nK+ee*>;`t+%u+Jea(8o vR5x-}=mldp!DT+b`?hi(nsMPiM;)`hf`a|hX9_^KGcb6%`njxgN@xNA_;dCz literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/AbstractClass_logo.png b/gulliver/thirdparty/krumo/docs/media/images/AbstractClass_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8f65c390e37b548578390c0bdbe4a4bc469c4d19 GIT binary patch literal 1232 zcmb`F`%jZ+6vq#W@U{$S1TZXV4viCPx3q`=k`4L zo1#BJx0H}AAicqQU>vV%^^<9m|tWsIx<8LP>5;)!-8{5Ba8xawKa^8)JAwolYrP3xG ze;gi;N)W-psLCUuuq7;v;PILTf-XM)dx3ypvzvl~UU4|4;9xV4hpH34zB3F)V?aO$ zn|+nbCFt}9e}9{g&n%sOWyOknOy(?=N>C`M!zl`-mcbw}tb)O4@%Ek}kw)FzM%>+P z&dw7gQYD>^Hi$-;0kAkbTLCIOJjMZr0D1sUQ>kWvt0dArfEIuTfD>f$DGaLt_zu7T zPzaEN77pxLob%;x2CG}`xIIwL@5%qsVT}twSp0*)++a!sc%Q?K z`N@jCeTp+nwyR|s`Xqf{xt8ToY?#m#I3M+++}?TZyynf|!6(h%ZXB5YwRD&DpE->+ zQa?!d&ipfd^zwzIKtBJ~qLA$Mj4wHSb~mtdtP52mbBN=vTM#>mfmycxM}yu)6Bg^4@lw*?MFu3*Llv~ zTq;{9ldCeY*UL|oCB+&|W}C3XvTUffR~(q#WAaNg-nYFVl1oFwjfcGkWO1Lan7mWj zTHAk$B{{PsrhD+|_&Dv{Dq|lMERc7*{?yjm*&4fucG~As73P}JZF+xm+H<2#y7rxG zW9=q?%ZBwC`JJPAZS{(h+4A?WNris0W9rS3rW|*EzKH2={VP|ERZ$+~<|y91p2^}Q nm5>e}t(H)$%7m@A#{7td(X}C*54y81qwfI{akQvb7@z$w+j=f( literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/AbstractMethod.png b/gulliver/thirdparty/krumo/docs/media/images/AbstractMethod.png new file mode 100644 index 0000000000000000000000000000000000000000..605ccbe58e04d8f1462227f08369ef6d8e5d4fe0 GIT binary patch literal 696 zcmV;p0!RIcP){TiMy!!e(Yf-7_V#G2iUr zLy?{{R5VTt!-qRXx-)@b&OX;WKp!2|aT>;Q#=c z001J6D>1||Q0X(T002sRN{?O-R{#J232;bRa{vGf5&!@T5&_cPe*6Fc02XvbSad^j zWnpw_Z*Cw|X>DZyFf=bPGA}SQ*^*j90000WbVXQnQ*UN;cVTj608L?Ia&K*AWNBd_ zMrm?ocW-iQb0AGvyOAm+0002PNklfMHT-Bv8QIEs=+ZPf$A`E>2c0)H#Sj$PWnk1p@>G(zLXgfTkY(YJ2o$Mf2{EX7&_@CL4Lsu zf=WupE-s;IY31eR9Y|p2?lbS+y#t0XRlwut?cae`au#?*7Bet#3xP1>rMq>1fPxAo zt`Q}{`DrEPiAAXlzKO|2`MIennTZN+nMJAP`9;~q3ceA$Cu*qx)rx`CIv1rTmSpDV zDTHL^rZO0q=o=X68yMf56y*d|@zK-8F{EOS?)lqMO%4*R4`(`@EDFELx7ssVZORd| zq%5HzwQYvlS2%cGPXFHD@~{05-~Gi~FPw_9ndsyAvUly>(4LD`8%wTUDBXMa-M%{6 zPZCGZ>%ZQD?T}l&!`s7tUKsOr`-?Wu<;}Q-LQ_10v>q37%ry4uIK**v&qDxa`a*R3vrciLZ8L}yD) oC>0QH(U@~sMxOVvCC6j?c~N@r8XNCh0zJ>*>FVdQ&MBb@0EQ=S+yDRo literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateClass_logo.png b/gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateClass_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4e68f570dcb38ee67756ce2231bb5c38e77cce71 GIT binary patch literal 1615 zcmd5)X;Twc6n!ia!lFSW4Jkrc1`LPY$1sj(#lRGf?-K4OF)W1MOFm{ z#7YHOM1d45sY*y?RaT*Ff-H@QqJv;$S_hSqKJ6F#4|-7%db^6N%JBAT-(9*4o%q znVVM{8z&gwu}%jHt3R3eeo)zwv3Rdtk> zHkX%IR8+_c3#BLl`T3*C$>o`ujcI8r9xppPdr&AWJ9+Y=SiH#R_r%1&N)#a> zLp)xoP^jW?x*{TSg~HD8@MMu_J|N&;P>>Mv3@w(yNtt`_4MTNcqLq} z%GI^Y$LAr10vpK)47}svp&}CHWHOh_eLy0K*z8s^S%t^Hv9+Bb5@VQ58Hse=#f8OU z!IlG<%q?^C0ynn}bMx!Y&f#=AmrftS zz{0{8=0u^Owi_rERBYA2Al=^ngo6W*NbJU9H<8F%9BxBfdvV7O=!jBFYZ-~mv9x@x zsR@ORv9^X@%xG!71fbr~a2|np3MB<#5&&q>5CDxxWG?{FDLDW|y1G&TngOW$U}y!L z4IC~XfGhw62!t2_EEWrG`q&@}0J;|r4?^#yB9<>37+4Ughj_fi#GHz2*JLti8^rv7 zu=W9PsQxe5o@p5i8$iZ+2Ey)icfJp`vH6pmki>~-0U~xRPm~y%5D9!j!xLhUM@H~N zaUT4H$i&!$Xd%ugKz7d73jRgE|LdL*87kt(3UD0$@kl^$b|5%85QsCyT&R@#EjpFV zNxB$0{_dMGCPphR1jGN@&Te?$F)~u1_bJ2p$i%={-+*sD-;Or!G|aRk{(Pj}Kd}0H zUF|6ogUq)Y;t|lhxz(~t`eQ_RUoq1-eLFT?AP8E>XkA)fHggqi^htaeb*$=!t4&v9 zqXdHJ6|UE%Zb#CMmiE)kj0RV6b=%tA)%tp^#^=wTC2c+JUMy1oOuKh7@94hZJCoCG zXxaS2yJN@J#J33U`c+%lKU?M&7D~KdDwWEKxzE31HT2^+xj+0k>P|X8pxN^#{*0l; zJtxPg-}2sdI`*|*oC&-#etYRjR+M_H)cIG6TS0l{{gE&BmCtq~sCpA%t$SPejT1KZ zhgY7Xi)In=GWoXzL>tiaEgkbHwlbdGz1?uS;}g9r9hTrqerW-%FO1@shEpP|okxi= zPM5cWANffS>kbM9sa+||;ebojEN0yA9yek&f^IImjYjiE#g2W+w}g5r{lcI0tMbXg zn)g@NIfMqbGFiEQJ-TD7%ey9VJ;gYDC9Ao8C1ZwKf{tkXg^MxlZFwOFr^!}`w~YQU zd1uJz%3r<80}oBt)q-)m&*Rf}D)wh9&K|(^9IVw$da;MNxX>Y)R&c|pBRwc!j(BVG z1gV@=8A+_ZCz$E2gI1@w{L*m@r+H)9vC7|V^Qd`Hj&)~W1WkS8@5e~OE~BI%6gwn= zr*W1_Ms>6Hs`1daQJXsTMk+A3=fdt{i_4foPsd6$>Q%`uT3s3z34l|D0EF>7@e!`_b&3NDRW2J ly0$Y=SuS5{3YHYFR9bNnjKnZ6dJUX%K&SaqC6tg;{{UJF@sa=l literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateMethod.png b/gulliver/thirdparty/krumo/docs/media/images/AbstractPrivateMethod.png new file mode 100644 index 0000000000000000000000000000000000000000..41cc9f021734b6f99a723a687827190f2ae645e2 GIT binary patch literal 874 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J8+1AIbU z|Ns9Flwsj#1(FdZp_~dll^g2aJA$}1LE7U51%YJBiZnqBFdculhYlSI zePQDH(Aed!@#@v9{V!U0T+*|>Vq|mPaK+-qHfL>(<z;@U}mwJ#*$v?ZZY|dku|t z>TYOnx7uW^y4kR+tIJ@Wf$1uBpzT)k?NpbUwl>yHs;P72AM0gsJN85x|f1nsNASyQ)C^V z5(o6cX?uI1gPQ_$zUt}*MFj!9qne@NAL##8Sy?4sMa%1B#506*U(#MpQkI2X< zc`N_t;!<)|IwT?j3`C$$JEf(8o_)r^aG!xeU0r=914Ae{#Jqy9S^>kcyd=mkm_blU z$=KK>G&D3VtsLmpnX6WvIdc~R-hlxyN~jN}hd;CiI)SsmBeIx*fm;ZK886+f`vVjd zD{+k|aV|AI6tkVJh3R1!8b9vC_gtf zB{NaMEwd=KJijQrSiv`9_e3ofpxV=(E{-7;bCLzbgr`rKFk#BGq?87R>nEOk>FJpx zR5!!H#V1TpU<$_pmPbOx#d~EhvfQbWT_nhq+3L!8?pK_VPC(<7l;G z*2$BHZrL7j2|sUR5%A_P)N-TQ+}Y|GrRdK zV81Pn)+>0zGnMUCiP|Spqc&^AG^y;y-0mPhgGJ5$HDs$bXTdY0@m-PJEq%`?TdG9A z`7w;w(EZ*psMAWc}ikt!qr000(rMObu0a%Ew3 zX>V>IRB3Hx05CK!FfuPNGue__LI3~&s7XXYRCt_C%4rvYKmdi|(V{3Sky0s2sVw0{ z3ns_0{QqBM)L8Df_c<4+W|ZRbuE?ptT;0z>z23f%IS}<{hVT1%ezB)pU1LBR7z?!4 zdf1$>0)?RM<32r|FI3$jzfkuMegO9fmRSW?+;gd{A6?vpl~i!EaT78927Y{aY)A+t zD;|Uj0{6%|rRRA`LWdbZAQrk%Pf@@U0ViwJZw&^h9P>Z*1$ZnRgm9bKlmGw#07*qo IM6N<$g0d3*MgRZ+ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Class_logo.png b/gulliver/thirdparty/krumo/docs/media/images/Class_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6f223c479a6c6fefab504deb84ab824d2e744713 GIT binary patch literal 1600 zcmd5*`!|$%9DdQB9VXJcrO7tT6s8%5m)$T$<9->p85y@dE{&RXZA?TG%_2nB{k}w+ z>>y&K8JEf>)@4JEu#A%^x8$DGyKmbsyZ^yH=X@^b^L>8!JkR-jlN{|WrKJu_0RSLv zZDr;RS2P?)5fX5&yJ6f47l|;kH4TA4Ow2fl06^Tq(T-*gK@j``L!Zj}+HeO}zBX0; zizS_}vsy(-{E4`_@#vbdi+5fGm5%u5_tDdPtzuhX8qOmN&M4C`MSV{xS#?0cPBr16I(qS$$iDTJrh_s?O!p#8Hcm?#qi{w{Bl~rNTh%>k zux{n)ub}uDC~68~PeK9XP|o0n-x!qAyY4;;IgdbbU2Fb*kj)U}I`FAP@Yeb{ME(1wR2$S zCnkTzwDp5^%MQJH%Za}Qw(J@Sb}rN|#d2rO_**uOn}$u>PW5Z&eqR6^w@vF-EowJR z?ytf7pRC>Vy0c(Xy#ZElT5*>`i$x}PS71@3%2n|0Ix}zDrR23?#T;0%YIu7FmT6El z2Nu24DVZbXi)=HebP7bUa4>sWJ4d9GHAl=E1#c}<6Gn-tBHfgEozyY>%|Y;&c|yW4 zku#~q8L_(3kLUF3#=OE^@6x?8LyQ_DL=9+0x1A2}#zl7MT$&`ZUJ%&*xUeUhY#|}I zSN$R%Hj~6`#Raq+3+8G3+=%z@#4@=!KOxb#LH%4E&aW2hTXDiu02{99&efzpfNj@w zsn?)ZV`*i_sYO_)-;O(09;Z}d95XSL46I%8F`F_qo10kk0*qOr$PC`va_ndpbYvy|{2GJehB@IiF4o$aZ>K{XIGb8+#H_!n;6$gipr{DZ!g z{{X(k{~?NKvs$nq$xth|FaSV)_a(%J{)*XyhiJArolOn#XGi$37y!k`j};QcILGus zTQFISh!9pl7@9&C{EEZET*WV3Qx?OA%?t@f)0jaFfT*WU)YT?}FEiZ9@ONZdo1LLu zF7opRBrE~}wa)fRZUyglRb^$GxSn2Pg91AFWDunfuj18GhDIRNFt3KCaO!XG6XR&1 z28*aehm}!<>IiA_!AaB^KQ(Cz%0e>k6#30Eu? zFVRRBHaEw|$2T?#1h?9*(e0eWnYQm1Hr1B!cKi1WHPMl!yyD`-M9a|7P&O+nm`UBf zx#`hy(nM;f-efI&Ys=m~Cg$M5y1IM!ni-dtGv`C5w7MQkIj2kLO^;6v4}(M!NmW%J zqg~58a-sbR!Ac6xD=uAAR*p0`XIvs=o+nJC@!AI@u?L*fb6sg?her$|Pd^gJMy6kX zyY5=9aetfR0c3@|$s=BsOcoC~V2u4xFqbA7rlWwKMHLuT_IuR@E0N<;1(y5jqdklr zA18PT(&hJAnw&ypeXE(*jBty~<~W1~;xeKKN4`lJ4URwYtcit4vd9TpEPUi`Ko+~! znxf<=Hu;%f(yED6tR88cY6$)$k_sYx5+paB)@w47v$fpK_KbB9<-0uWWx$V$Y(nJvu4LwpP~GnArV?p7r+FCdX3sF>*+w zM8ps6Vm(S|1s-pS4xBiFG!w(f$;lxV0eSz9%%(EsBY==fcwRHDvGW Fe*-2SG_e2x literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Constant.png b/gulliver/thirdparty/krumo/docs/media/images/Constant.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c6f28b3591824c0732239096324984401092e5 GIT binary patch literal 752 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 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Index.png b/gulliver/thirdparty/krumo/docs/media/images/Index.png new file mode 100644 index 0000000000000000000000000000000000000000..6558ec393a6e0b35fb7776a52b4ca9c10da0d5c3 GIT binary patch literal 584 zcmV-O0=NB%P)sGc1s$KlTB|5tUFl&jIZ$KRg6;GCqm5-wl6(B`4Q;1)J+i=@-=`2U5V zz0~Rd#@X$9lDq;jjf$eZgrL)or^gjMgq*e3yWRhls?|-6=3oE-010qNS#tmY3h)2` z3h)6!tTdPa001C#MObuGZ)S9NVRB^vO<`klZ*65{X<;BnX>w(EZ*psMAWc}ikt!qr z000(rMObu0a%Ew3X>V>IRB3Hx05CK!FfuPNGue__LI3~&s!2paRCt^{$?Fn1@%ouFXELYW(Fj^6Z(U`)_51(-|7XseY25!>(WA}p^8eefzIoSOHBLL@ zu5c=u23 zg#EgG*R(4R8Bcv1+IdSoXt7!L5tEf~j@@~uVBhR|_Md6WYSZ+C#*073PQ0UAdtN0gNKbwkHzugYdUHQk=cz1X!nX~(+V z_vf=O_Fb>Npdzh8PLU=1Pe4dSL)YuZgf>gNH%uxGi_eHC{A4Kd*st(Y%3;N2oyz=} znqKw`%X@Y1uQTv0S!*U^fJH$hN@BTe&;g&?!xjVTG>^jPxS@?+*er933 sa(UjQ<*PC{8=_;sg?l=%aQ~mEp5P)i@yk~|9Z;Bfy85}Sb4q9e05`Dm_y7O^ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Interface_logo.png b/gulliver/thirdparty/krumo/docs/media/images/Interface_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6f223c479a6c6fefab504deb84ab824d2e744713 GIT binary patch literal 1600 zcmd5*`!|$%9DdQB9VXJcrO7tT6s8%5m)$T$<9->p85y@dE{&RXZA?TG%_2nB{k}w+ z>>y&K8JEf>)@4JEu#A%^x8$DGyKmbsyZ^yH=X@^b^L>8!JkR-jlN{|WrKJu_0RSLv zZDr;RS2P?)5fX5&yJ6f47l|;kH4TA4Ow2fl06^Tq(T-*gK@j``L!Zj}+HeO}zBX0; zizS_}vsy(-{E4`_@#vbdi+5fGm5%u5_tDdPtzuhX8qOmN&M4C`MSV{xS#?0cPBr16I(qS$$iDTJrh_s?O!p#8Hcm?#qi{w{Bl~rNTh%>k zux{n)ub}uDC~68~PeK9XP|o0n-x!qAyY4;;IgdbbU2Fb*kj)U}I`FAP@Yeb{ME(1wR2$S zCnkTzwDp5^%MQJH%Za}Qw(J@Sb}rN|#d2rO_**uOn}$u>PW5Z&eqR6^w@vF-EowJR z?ytf7pRC>Vy0c(Xy#ZElT5*>`i$x}PS71@3%2n|0Ix}zDrR23?#T;0%YIu7FmT6El z2Nu24DVZbXi)=HebP7bUa4>sWJ4d9GHAl=E1#c}<6Gn-tBHfgEozyY>%|Y;&c|yW4 zku#~q8L_(3kLUF3#=OE^@6x?8LyQ_DL=9+0x1A2}#zl7MT$&`ZUJ%&*xUeUhY#|}I zSN$R%Hj~6`#Raq+3+8G3+=%z@#4@=!KOxb#LH%4E&aW2hTXDiu02{99&efzpfNj@w zsn?)ZV`*i_sYO_)-;O(09;Z}d95XSL46I%8F`F_qo10kk0*qOr$PC`va_ndpbYvy|{2GJehB@IiF4o$aZ>K{XIGb8+#H_!n;6$gipr{DZ!g z{{X(k{~?NKvs$nq$xth|FaSV)_a(%J{)*XyhiJArolOn#XGi$37y!k`j};QcILGus zTQFISh!9pl7@9&C{EEZET*WV3Qx?OA%?t@f)0jaFfT*WU)YT?}FEiZ9@ONZdo1LLu zF7opRBrE~}wa)fRZUyglRb^$GxSn2Pg91AFWDunfuj18GhDIRNFt3KCaO!XG6XR&1 z28*aehm}!<>IiA_!AaB^KQ(Cz%0e>k6#30Eu? zFVRRBHaEw|$2T?#1h?9*(e0eWnYQm1Hr1B!cKi1WHPMl!yyD`-M9a|7P&O+nm`UBf zx#`hy(nM;f-efI&Ys=m~Cg$M5y1IM!ni-dtGv`C5w7MQkIj2kLO^;6v4}(M!NmW%J zqg~58a-sbR!Ac6xD=uAAR*p0`XIvs=o+nJC@!AI@u?L*fb6sg?her$|Pd^gJMy6kX zyY5=9aetfR0c3@|$s=BsOcoC~V2u4xFqbA7rlWwKMHLuT_IuR@E0N<;1(y5jqdklr zA18PT(&hJAnw&ypeXE(*jBty~<~W1~;xeKKN4`lJ4URwYtcit4vd9TpEPUi`Ko+~! znxf<=Hu;%f(yED6tR88cY6$)$k_sYx5+paB)@w47v$fpK_KbB9<-0uWWx$V$Y(nJvu4LwpP~GnArV?p7r+FCdX3sF>*+w zM8ps6Vm(S|1s-pS4xBiFG!w(f$;lxV0eSz9%%(EsBY==fcwRHDvGW Fe*-2SG_e2x literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/L.png b/gulliver/thirdparty/krumo/docs/media/images/L.png new file mode 100644 index 0000000000000000000000000000000000000000..eb334edaeac52e2f473ffd92a49b025fb6148ec3 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv*$P6UUaa~gcQtTz3zOL*Scz79Am98pQqyvRG z3p^r=85p=efH0%e8j~47LAC&&5ZCE_)&Kwh7Y~}?0Tf{>3Gxg6&+v4+fftY`;pyTS tQgJK!NBsYWhyUvpj=8p5Ib^(%U@*zon(m*SoDEdN;OXk;vd$@?2>{+EE2IDb literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Lminus.png b/gulliver/thirdparty/krumo/docs/media/images/Lminus.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c43c0aa3bebb499e86eb744b1e47b9a9445ba7 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv*!VDzYUPT51DfSXiUsv`EJiLsmQh${X`~(Vd z7I;J!Gca&{0AWU_H6}BFf(8LTA+A9B|NsBf`>KHqVn8Lk#c`lIrjj7P;QtIyw;Ol? zc?O;?jv*Ddk_A|pTm=*lC~zFVdQ&MBb@0OtiQr2qf` literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Lplus.png b/gulliver/thirdparty/krumo/docs/media/images/Lplus.png new file mode 100644 index 0000000000000000000000000000000000000000..848ec2fc3bbaab6345864c303684ff8a86559cfb GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv*!VDzYUPT51DfSXiUsv`EJiLtR`ZJfMMF533 z3p^r=85p=efH0%e8j~47L4yFF5LY1m|NsB#ebqn)F`$y&;y6$pQ%R6t@PCG<+YP*c zJX22>$B>F!$pS1)t^$e&6gZd#)XV}^6#`leL>0XheB5$;*x1}$U0qr4a0#d>%paztiFSddoE z=FO+Zs9v~B@b&OYf=WY?JVJfcJk32QO)AOb$urFVKXE`Ry)jqsH71)XJB8YEt>{GE zGvwvuGqv|cy!A6?%sp|-T8&j?o?bnP-A{*1r^4t+dqpBkBPV|V>IRB3Hx05CK!FfuPNGue__LI3~& zAaq4obW?9;ba!ELWdKcKV{&h8Wn^h#AVz6&Wp{6KYjYq?Si6xbBme*ayGcYrRCt_Y z&;kMn2M1Xdeh6R)4Ab%Sw6|x9hYPq^SqVCeF?quTBwVb*o#mC81mFUy;m%?#?D`xC z0cWuYe|IAv4`YZxESp$_l#sZsh-s)UL?ALUMqSb?I@nP<)JGU7U}h%a#vI_K=%}q7 zq~RmZ$N<)8;N{4}qYx4zCu$87;NdY>VCC|)P=g6*o7-s0FmMCSfC?zsMKS0(@xufx vP5c-vI3ex;lft~dN-&p#Ny9iND4!ny)Wjn48}#yJ00000NkvXXu0mjf>`)kw literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Page.png b/gulliver/thirdparty/krumo/docs/media/images/Page.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe7986ee2e78f7079d6de1a13ef29bff125f7a8 GIT binary patch literal 592 zcmV-W0wTQkb(FJYg{r&I=J@>oPidBsr@_|i|DM0#0xyTVySs>p zi0u&l@7S9O=i(&oFz-*}d|5-wk#ve_0k zZi}ST)an1e-~WcE$O18qgrL(EJcN#?$DzRBm8#XK#^imQz1B}9Gynhq32;bRa{vGe z@Bjb`@Bu=sG?)MY03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22; zDkJ~^02XvbSad^jWnpw_Z*Cw|X>DZyFf=bPGA}SQ*^*j900025Nkl8X^a6$`;}MU&lC(fZYGN)*U*T&WTYe`t|6?P&^gvL>{}6e8nl zLI{`JKlCFG|LqoMkSE{iD56H;IN0Sraje`6bqbr=>+Ac4L(v&iSUtNMDLgY2KvhT^ eCV+sH1<((?kR=WgbuC-~0000)GO-L0AERF6v)dP%qbhFs5=j^@`6F?l_(@;?;SYFPR0 zI9jbQwZey3=y8ba9+c^JAk$@k`bNJ*XM8mL<6q0r!V+YD551g+rvHRYW=KB^jl71Q zyjUEXf%<=gv{N57&;Ray_CaNWG~<7$j7xBl@^MHtX718|yz^v1Gcq;sXrgWOL-%8| zeAujcX!zyfo16VFq#9G>J(EnWtL=RyR-0NB6V)oy zRmEie9Z=A1gd35_HMMe(FE?E78WVI3@nv91+wgViUAV!rpFqJ)Wl_to!seceCS_?; zZ;4o$E4k0B*A>>Q@@^>L31o}zmDNbO)e5c<%)AP+E5P*1yXjXRr0_e>m1)_fP3L*4 zq>@`n#eK};ri8-Yv`eDs;=aU7t-G*r(;{fc=?O5OKSe$`R3j_d*nP9?x%J(%fQEH%67mU3Hek2mE8BI_V-TD<8{d?o6-ef!PG`p%c&+4{j^aUgcH zPg_HSd3If0jjtfvXN7{Bm9@0` z{!FFF(*y6@p7PEXiOALIn)UNaUZG?FMfe@usLHF4iAJOOeEx9SoR_ols++f6a=J|s z5ggQNwU#-2UgKh&U;x$U?l6kKlg`fF$Kh~T&%}(*P&e;MzM$e1iDYH5)s7SzdNQ)O zW|LFc9?jNAIaVEr_>4^{Y;|6Zw5lrHumeb(iS9?J(ExtAVJMHD8w=kA5FA7#v<61y F{sZ~k(bNC{ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/PrivateClass.png b/gulliver/thirdparty/krumo/docs/media/images/PrivateClass.png new file mode 100644 index 0000000000000000000000000000000000000000..470e6d5684f29e52abb36ee6036a4d0b717f92e4 GIT binary patch literal 790 zcmV+x1L^#UP)WmEhNm^6>N2zOCt|Fuvb2MPgIr%?-{0R%gxJKy#3oLoEQio1TB$RW z>}rOS@9*z3X3RRU*Z=?jNYVd(pWkzHbE2lGGqCn7nbbf>Stx6=M8@%WtGpvWd{9$d zW@ctxl-^f`)gwrPNl|4eO^Yjd!Y3yuC{eAu(Bd|2#VxYmFkYoDiPgf`>UMyN)z#HS z%>A{^=P{-CPSgKgi`geqs99WJM7{YbYtFRD+-aQPBu9}dn9Ep?+$&_jF0SJ+!SP*W zX)~JcM@?QQa<)}jTP=IfF8)Ib00009a7bBm000XT000XT0n*)m`~Uy|Aaq4obW?9; zba!ELWdKcKV{&h8Wn^h#AVz6&Wp{6KYjYq?Si6xbBme*a7IZ~ebVG7wVRUJ4ZXi@? zZDjy3G%qkRFEBINl3GFl008buL_t(|oMUj)Q(}VxtyFm#HwHbAypTdL(6@<=mvd%N zQkP73cXv}CPB4cExH8Hr zR9dNMl-WZB*f~Ua3V1C`?H#MY0*R^toKm_>URD+2h7KTs7*P=&Pi7Gj&r(CfOje+P zFt?7JoTp{7PL{MZM8L#S&O(+`PDicC$POfs3ly+qPy-6^M{5QG1%xD+<>aCiZ7tPU z^H~Lf0(?n|mdsYno>sEH;pIUBhYhhT*-1^kj&-m>@4F3035e9 Ui&^Ep{Qv*}07*qoM6N<$f)e~=1ONa4 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/PrivateClass_logo.png b/gulliver/thirdparty/krumo/docs/media/images/PrivateClass_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..590e00640baeca2f541347cc1c5067c255030bba GIT binary patch literal 1836 zcmdT^`&Sa!7N)T^!|2#(lU~J2d<$xV*reb%if{uGAB2xcCr~6EBoS~N3`R%8oA1Z9 zjI?x2^HGvbVw2{xv>MSY!8DVxe2kTOO|w!{=Jd;~yVm^+?p|x3z1KPWoOQnaedlBa z1?)G}hv`Eg5JNJFKm!r}(V==^BvfbjfuJYElj%?>bo^=HBn0wFeULw$sMG1d%HLKu zxBzkwfr3JzfTUsI<@w&3l8(u&mT`$j!bTAk>Lj{8{G)6;Xhe<^xY#~9JI zx3?b|Ud!owO;hVQDqYy%2IZmdeCu=a(B{wGi%O+3M75INIh1s3f~0znAN+9Y`W*B2 zYFSHH*zMJT-gTef-zyY~$j*1CuC)_;*9A8gz*V^|uYx-Nq_)2&cB}^f_O_;`#Wz=Dmm0WGd_5vmZPn;Z@Y$?s-xl010-LVn-j7_WpUmV?gQ z#@BnsDCw;D-Mk{e0y63*g(>ik5-}JIM`rWR*c|KVbAjP(z>W_i1`*!8_i(%|;{uGC z=1*tRXf#K<;z00WJ9@QwgxE5?z#+KKmR3oohFArc09Du>_{D}=45RaiWSTAcoE0S( z@N0$7w#FA*`D6m3Ej=?Wu_-VQ{;qw(T^K2l4WQn_MPTm22Kq5Uga8S_V6a;oN&P@u zQzBZxL5Q(6h7b}0@Ff42os>5;w6y`Ds8kaR|6@St|4;V1Z*vQP`#GOQZH!5*#rSH(*E!w%R>-W{9c69(j2#gn5S*Pqeeq^v zzkL7CbksY8FY>ZH_y6!U8jYr2bRG(APR1>F*_YGqtw{Yg0`Hk*&pV0b&!3yS)ld!| zn-f5urNP6I+p~<`D6nDn7fewiT>32o*H`kl6t(#{?$F=*N%E5432(0YCHDnRmtM{%F+ZC$WQDv++M6`c7mUI8vfQsyf=ACU$>$DI+n##uKp{O$Xh-}+|U_|mnTX|Q;*F+<{u+T@*V3jZ|K z&~S*U?dR?=dYp2%b8#zklwvgU3(HA5ZJ*GQU#Pd#ydxV9O*j5)xBk^zxanB&!TRJbl+-sIOMSY7+S!-!q6vOvO6U|hJ<$tucw(e2>IopzU zf2Q#2*c**a=_FsApXeEHs+lu9>UQWW!OhK72-@dJnVPY@2A%?hObj3>@XYkT0K34m Aj{pDw literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/PrivateMethod.png b/gulliver/thirdparty/krumo/docs/media/images/PrivateMethod.png new file mode 100644 index 0000000000000000000000000000000000000000..d01f2b314b973da7318cdb98a71a326f383e5864 GIT binary patch literal 918 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vk7#J8E0(?ST z|NsBrx}lMUpA{(2slZdYq28zK9FXna5yY)2U{iVAD08bu#A0RNsVOVc1TDmPHTipb zdQ55!GnYS0Uh*_%;nVQBj{~OMck8;@+}kAODC6$#?$PP#(BP7mmKGHirRd(Fy|8-qYX6HC z9+&iNuNW;|w!-GTq4$nAHfL?^c7FHT`aNmOeB(356Bn%kIv{R`xBWrwnKNf)W>PYjD}zLwkAT3uZo(G~1G(Z;{#vR6}oNlA%PpSD}U zF^_6j=PGB;3=*#Y$WwN}P*Q6H7Al^Atid zb5j`%O!N(m^bL$}PKt5@s!#x_2+mI{DNig)W$;Z*F3QhMP037DaLX)8Ezd8?E>`f3 z*ga881*rD2r;B4q#hhdTK`}8wQQ_$c$qh{j*4F9e`#W^>b~G%TwQJr~Z#{D#1vl?l z|LazJX0WSGSg|%ebAsU9Bi!N!<-8wzw);;`Y~fl`b(`(zvrGw95l%-IFCTC1&!2ls zzwGV0^wWWiW15+nU*5!-t};9e3k&TQp8P2% zX10&@>Zv(AJSVl5iLPpE{gyxy^(5I^ sFWFixmIS`k36rN!*Izp!t?eTtSH52M{Yh~%f!<^AboFyt=akR{02;ETy8r+H literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/PrivateVariable.png b/gulliver/thirdparty/krumo/docs/media/images/PrivateVariable.png new file mode 100644 index 0000000000000000000000000000000000000000..d76b21d4e9e8656a68989f007945ab14507ae23c GIT binary patch literal 772 zcmV+f1N;1mP)%f|KD9dx9b1xbjG4eNtEH2jam85a{u&(X=GITZxLbNk_B|L=MK=xa7(sn)kg@8o`zfK1-9S*@a5ux7 zfmfd7&Z|n=(z?t5000SaNLh0L01EH`01EH{Laa2H0000WbVXQnQ*UN;cVTj608L?I za&K*AWNBd_Mrm?ocW-iQb0AGvyOAm+0000MbVXQnLvm$dbZKvHAXI5>WdJZVFEBDM zFf-YbT0#H-0Od(UK~#90W8e{Sh>wpK_v7H<0s#g#e~U6rcWa$YHYh)|I4&;C+*d}O z2f|lomMalTR8dirW#a+!op`m(q>74+J*{+kKztWlvm~$d^mHFbLpC7aKvFO=TL8$- z(9YH4VPIntQ#1*-Nlnd2bB@(uW8hJbF68FUi^)(>aJDaCV_;(~R6mrqkrNJ-9N zW6+HbC{^VT@L*JM&I(uJVNf@UHVOzZ($7!fbQ1-dZx^5&WvUzCEm6)Q&B_DjGcf1| zBm@>j=z`qG8lcY2t!~7v&IWNmtEDgym~unB%LM?}VJts-{;Z7v0000paztiFSddoE z=FO+Zs9v~B@b&OYf=WY?JVJfcJk32QO)AOb$urFVKXE`Ry)jqsH71)XJB8YEt>{GE zGvwvuGqv|cy!A6?%sp|-T8&j?o?bnP-A{*1r^4t+dqpBkBPV|V>IRB3Hx05CK!FfuPNGue__LI3~& zAaq4obW?9;ba!ELWdKcKV{&h8Wn^h#AVz6&Wp{6KYjYq?Si6xbBme*ayGcYrRCt_Y z&;kMn2M1Xdeh6R)4Ab%Sw6|x9hYPq^SqVCeF?quTBwVb*o#mC81mFUy;m%?#?D`xC z0cWuYe|IAv4`YZxESp$_l#sZsh-s)UL?ALUMqSb?I@nP<)JGU7U}h%a#vI_K=%}q7 zq~RmZ$N<)8;N{4}qYx4zCu$87;NdY>VCC|)P=g6*o7-s0FmMCSfC?zsMKS0(@xufx vP5c-vI3ex;lft~dN-&p#Ny9iND4!ny)Wjn48}#yJ00000NkvXXu0mjf>`)kw literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/StaticVariable.png b/gulliver/thirdparty/krumo/docs/media/images/StaticVariable.png new file mode 100644 index 0000000000000000000000000000000000000000..8e820193cf930c4147eba542a1b50626933d1f42 GIT binary patch literal 688 zcmV;h0#E&kP)ugtEVnh;=iW%reFK|K(=fyleQ_jJUz6HFV9ct*geON>7>N>(GgmfJ|kL+1=gU z^~Y`c%U_K>y!eySuyp^oG^8 zOJ%3#Pt*VAzglvk(fQzS|Kx&gliM$y+%{plJI?=wq~ZVfjLxV|_|0oEwD7g7kJ`IY z``=&x-kSgDYyawSp@vA;vQq!uhw#*m-@tNLp5*`PleCyn|MHYq)&I_`O8L%mFH&Tq z00009a7bBm000W`000W`0Ya=am;e9(Aaq4obW?9;ba!ELWdKcKV{&h8Wn^h#AVz6& zWp{6KYjYq?Si6xbBme*a7IZ~ebVG7wVRUJ4ZXi@?ZDjy3G%qkRFEBINl3GFl007WQ zL_t(|oMT{NQ!(J+;Bd9(Wn%#W1{OIVrx+F&;*6wS&87O>I`iFMG>&~Wn?kpl^s3aTqPC~9aZgzBhqu>l3V zEJEUe@?l}Z!7lo83@mJN_9niTy1Jpl!gdkiKmisO)({&oUzpiX1}q>a${hye3fnpI z39x|#*m&f1fLvyFNkfn=ASHU{Ea4lA_OTmCm4hW!rK?49w W#UB-s5zQI^0000H> zJR*x37`Q%wFr(8NlNmrkwg8_H*Xe!L|Ns9N51QZs6k#d}@(cdY@N~O@7mz3J>Eakt raVz;p{QriB|LYZwxwcz9n9R-~pRXx?mgVYJpb`d8S3j3^P6#nkpi;(?AirP+hi5m^fE-m% z7srr_TgeFwOpI(f46|1#2yiGY`Di?KiU>FVdQ I&MBb@06e2A@c;k- literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Tplus.png b/gulliver/thirdparty/krumo/docs/media/images/Tplus.png new file mode 100644 index 0000000000000000000000000000000000000000..2c8d8f4fd38259b2ef70fc63fad505fb0a0f55a4 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv*!VDzYUPT51DfSXiUsv`EJiLtRLI=-jc>;wv z3p^r=85p=efH0%e8j~47L4yFF5LY1m|NsB#ebqn)F`$y&;y6$pQ%R6t@PCG<+YP*c zJY!E6$B>F!$pS1)t^$e&6gZd#)XV}^6#`leL>0XheB5$;*x1}$U0qr4a0#d>%86hy4NT6+w`tp00i_>zopr0L}p{>Hq)$ literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/Variable.png b/gulliver/thirdparty/krumo/docs/media/images/Variable.png new file mode 100644 index 0000000000000000000000000000000000000000..8e820193cf930c4147eba542a1b50626933d1f42 GIT binary patch literal 688 zcmV;h0#E&kP)ugtEVnh;=iW%reFK|K(=fyleQ_jJUz6HFV9ct*geON>7>N>(GgmfJ|kL+1=gU z^~Y`c%U_K>y!eySuyp^oG^8 zOJ%3#Pt*VAzglvk(fQzS|Kx&gliM$y+%{plJI?=wq~ZVfjLxV|_|0oEwD7g7kJ`IY z``=&x-kSgDYyawSp@vA;vQq!uhw#*m-@tNLp5*`PleCyn|MHYq)&I_`O8L%mFH&Tq z00009a7bBm000W`000W`0Ya=am;e9(Aaq4obW?9;ba!ELWdKcKV{&h8Wn^h#AVz6& zWp{6KYjYq?Si6xbBme*a7IZ~ebVG7wVRUJ4ZXi@?ZDjy3G%qkRFEBINl3GFl007WQ zL_t(|oMT{NQ!(J+;Bd9(Wn%#W1{OIVrx+F&;*6wS&87O>I`iFMG>&~Wn?kpl^s3aTqPC~9aZgzBhqu>l3V zEJEUe@?l}Z!7lo83@mJN_9niTy1Jpl!gdkiKmisO)({&oUzpiX1}q>a${hye3fnpI z39x|#*m&f1fLvyFNkfn=ASHU{Ea4lA_OTmCm4hW!rK?49w W#UB-s5zQI^0000(x0NIF%{nuT>i_6Z|J+03z&LVrQvdj0nPvbd zPMvIEmeZ?!4s&x# z#i%Uo#W*vP>T-Bh-n}vA&qc6+7`mT2TL1t632;bRa{vGe@Bjb`@Bu=sG?)MY03dWl zSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22;DkJ~^02XvbSad^jWnpw_ zZ*Cw|X>DZyFf=bPGA}SQ*^*j90002ANklU5Ub z)J&2>v72qTTu7E`nx@t2xdQKkZtdZYg4lY+yP)e911YGU#WzGE3Im~vZA6xzk`9>4 zNL8_RMr5ZhnC39*aq{=8RR=h(7tdcVhw%9H0)imQWkC?GbCM*z2n^6y_rKc*n=K%t TSg55|Cs*qzIWRJ6ld^s^>bP0l+XkKHvAUX literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/file.png b/gulliver/thirdparty/krumo/docs/media/images/file.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb2427f8afe94b50835b0a6fb2f7fc4b6624bb9 GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+o!2~3GGZMc6DV-A6h!W?b)Wnj^{5*w_%-mFl zkkV8IBTEIZ#5@Hf0|O%FdgViBVQqh^b}u-UUD* z&H|6fVg?4j!ywFfJby(BP>?0v(btiIVPik{pF~y$21Zp+7srr_TgiX^|F>tp*udH$ zEiL_V#ftUo-3uDh%uP)G{Qt|SZB_7q!9$E~2FI`q8Re^|Ns4w54;**JyG{r3reJX3bz{Zf3vmrZqg`n}6P+S5*tz>i^H* z#2~u%W)Z8#mr%xxhMwd+SvmjaL%%Odb!ew<(5(2Ban^6jjOpAT8-5&KS>(Rw-29d% zNdZfFap?uEMT+k<(v+DOT$Z%I^ZS1lw?N{?lj=*DIus0-A5UO#>EQ|b(2vWFmuh=~9H|IVo^qIey?Dz1hsy_{P4Pvu|$000SaNLh0L01EH`01EH{Laa2H0000W zbVXQnQ*UN;cVTj608L?Ia&K*AWNBd_Mrm?ocW-iQb0AGvyOAm+0000MbVXQnLvm$d zbZKvHAXI5>WdJZVFEBDMFf-YbT0#H-0F6mRK~#90WyotAfiM_=;n!)RO))lyYKg9G zDu)jI|9{59Wq7{b4-9^S|1r5?yt?|k_gEL_vSjsQJ~o|}aLiJr)OMPgdUXK!BBdrI ziX117J(mLBNUinDT$y2+3p0|WwfAs4W|lcJ!*ci>ABPQvf>`e66oz{@WlRWx5Nh&6 i1*3pkRRDgc|J5D1CKP}NM>^*K0000|Jy16 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/function_folder.png b/gulliver/thirdparty/krumo/docs/media/images/function_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..8b3d6e3b12902fd6de044496082464dbc7639d42 GIT binary patch literal 605 zcmV-j0;2tiP)|{;@VQH zutK?#8|2oVPNX5otuVc-H2>T~`qMo_z!(4RRPW0<*~LTu^jkBj5P!Tt|K&_$wm39v z5ILL=BqI z!r&0NoVJJLDxgp-+TMLq>XzlVuBikpI}FsMP+>!akcx{yaKxWv;lIWQI-(jqRCU$Q00000NkvXXu0mjfHW&%O literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/minus.gif b/gulliver/thirdparty/krumo/docs/media/images/minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..f502662bccc750fa7163df74d83beb34041d8509 GIT binary patch literal 54 zcmZ?wbhEHb>%!0InVFe0X3Tk++2-cv|NsBJy}eg}(|db+t*x!g)adv3 z_j7Y|rn=z0$>ZMM-tX`4KW@&Ajg7^{#b#z^wY9a6sobTdrOeFC+TiVjgM-%A*0aLm zTwGj+qT6qh*h+WM*WK!7W@ee0nXJF&WQx{%o7>so?BwU}l&#?3;^@xa?}MP(t-ap6 zEIdd6000SaNLh0L01m?d01m?e$8V@)0000MbVXQnLvm$dbZKvHAXI5>WdJZVFEKJN zFf-)xbMgQH03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22;DkJ~^ z0ZK_kK~#90g_GNIgCGzd~1b@PXAis>##hF-Lcwks_T5{Gt1=G+~a%dFwQCnQZU3J+k?=iHfkBIVqw%X0=b%mMM4MWsfC|3Za zJLI<3MRLMm2C;EFN?uzwL|DX3a6V)!kcPBr r4(}qx0<9ZuvwaL3$t_-E{1p8KSMoIIFM}#&00000NkvXXu0mjfmFG8p literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/next_button_disabled.png b/gulliver/thirdparty/krumo/docs/media/images/next_button_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..4a11780fc0ec50dd27cdb6a52f863c511e32b61a GIT binary patch literal 543 zcmV+)0^t3LP)D z03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22;DkJ~^02XvbSad^j zWnpw_Z*Cw|X>DZyFf=bQGA}SQTlLsPeLfOt#LNVQ}_yWVA&J!XM&=yzgAag0bSrwNq7QKuW}AeCmE|^Nojv;1W49t( zJ^R_7npd}q|9AEYBEEOSPL(b=(wtUnF~5x!^#c9rjMvp>dVHd>fI6h^x!+-x^4?w{ zA}`WpEJtxdM>gE74H3rQb1zDxCZhMp#IYTl92jdPHrzr4kKJTmn+Eji>=$zWWK{du hHd63A_=WQ``UAH88gT1vi|haZ002ovPDHLkV1oT`@4^58 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/package.png b/gulliver/thirdparty/krumo/docs/media/images/package.png new file mode 100644 index 0000000000000000000000000000000000000000..b04cf566d4ac41fa95f87664cf65325cc51e8a64 GIT binary patch literal 668 zcmV;N0%QG&P)t@djQ|x-^8(p z?4%BxbRnvSIo8(J;;cKFW&rs3_^P0a=H}+Wz`&@4HsP26zocrIZ4l3l0QR&iRXPBo zdnn+jGIdY@nPvdLr+C=OsEk?wl583Es}SUx0Hl8}w3Siws0*g0p<_e<_q#u(c^k{N zhsBHlt8)OYia^7{zq@__-VIW3na%FdKa%*!SO<22;DkJ~^02XvbSad^jWnpw_ zZ*Cw|X>DZyFf=bPGA}SQ*^*j90002jNklc}6)3g8( z2ru$H580mZyrWAbSccU12f~7K5mUsGBX6FN7o9)y4In#v$>W9q0000@uL8oa~j{sfyu2e|KUjW+DCy{0JN1+^UXT2cmT$oA=$Mq|M6Jhn+c_M3;+0E zbx;8R*gvs`8movsnPvdrmjLt9Kjg6{xsNKVeGbg7FZ<$8{qAY-)kDUkCzNLg*TZiA z)ja?7TfLMa+qE&-lK}C{I^?=9yq74~zG|$36Zh6a^rZm*+(ZBWW~z4x;hqqmcOiRJ z0IiEc|K?4LUIG8;Po#Y-wvr&V>IRB3Hx05CK!FfuPNGue__LI3~&Aaq4obW?9;ba!ELWdKcKV{&h8 zWn^h#AVz6&Wp{6KYjYq?Si6xbBme*aqDe$SRCt_K&07n zYC8yeE(c9}CP^I;-Xj?!ixGY5~lHzpft}vlT9I`brT10000%q?FnVFe0X3Vv2q^)rKP2vv)}0J@jq_P*4*ihjg4kzX1%?=#l^*vtlzDzt>WeD%*@Qz*49dQ&}@*_ zgM)*ny5P~$Sz@EU>hb z00009a7bBm000id000id0mpBsWB>pF7IZ~ebVG7wVRUJ4ZXi@?ZDjy3G%qnSFEBIY z@^kV4001C#MObuGZ)S9NVRB^vO<`klZ*65{X<;BnX>w(EZ*psMAWc}ikt!qr00BTr zL_t(|oOP4!R>L3+K%uvC@aN(<}}S| z_cY8cJz7aQY#zo&M2jq~x36itf~8liMJ`!c@Asvy$I6;i&)Dnru()HiB+edazpMKd zEoJN8-)<(BGm@V>Kss~sJD&cma7A&3Rf z-i?ioW@cust*yny#e;)`TwGjcW@ee0nN!N#@Bjb+32;bRa{vGi!vFvd!vV){sAK>D z03dWlSaefwW^{L9a%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22;DkJ~^02XvbSad^j zWnpw_Z*Cw|X>DZyFf=bQGA}SQx z*6k)+-YhrkG_XnH4KgoalbW`Y#C%zLMG(A8#WIe0Sdy)s;aR#>iI`s&ukbi9->Bn; zl^kv0>?j`lHcTk$X~oOxj`mj&)#BNTkGP5zKdfml{jyB_s;gQ~-J%yw(;cg&WqD+e z@4Tv&%scxQ+Swu0bZj8*=8QhlX_YI61C}V0RhrpeSIKn$X;_d%y$~5a%u?9ODEgSKg~J500000NkvXXu0mjffsXN< literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/private_class_logo.png b/gulliver/thirdparty/krumo/docs/media/images/private_class_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..590e00640baeca2f541347cc1c5067c255030bba GIT binary patch literal 1836 zcmdT^`&Sa!7N)T^!|2#(lU~J2d<$xV*reb%if{uGAB2xcCr~6EBoS~N3`R%8oA1Z9 zjI?x2^HGvbVw2{xv>MSY!8DVxe2kTOO|w!{=Jd;~yVm^+?p|x3z1KPWoOQnaedlBa z1?)G}hv`Eg5JNJFKm!r}(V==^BvfbjfuJYElj%?>bo^=HBn0wFeULw$sMG1d%HLKu zxBzkwfr3JzfTUsI<@w&3l8(u&mT`$j!bTAk>Lj{8{G)6;Xhe<^xY#~9JI zx3?b|Ud!owO;hVQDqYy%2IZmdeCu=a(B{wGi%O+3M75INIh1s3f~0znAN+9Y`W*B2 zYFSHH*zMJT-gTef-zyY~$j*1CuC)_;*9A8gz*V^|uYx-Nq_)2&cB}^f_O_;`#Wz=Dmm0WGd_5vmZPn;Z@Y$?s-xl010-LVn-j7_WpUmV?gQ z#@BnsDCw;D-Mk{e0y63*g(>ik5-}JIM`rWR*c|KVbAjP(z>W_i1`*!8_i(%|;{uGC z=1*tRXf#K<;z00WJ9@QwgxE5?z#+KKmR3oohFArc09Du>_{D}=45RaiWSTAcoE0S( z@N0$7w#FA*`D6m3Ej=?Wu_-VQ{;qw(T^K2l4WQn_MPTm22Kq5Uga8S_V6a;oN&P@u zQzBZxL5Q(6h7b}0@Ff42os>5;w6y`Ds8kaR|6@St|4;V1Z*vQP`#GOQZH!5*#rSH(*E!w%R>-W{9c69(j2#gn5S*Pqeeq^v zzkL7CbksY8FY>ZH_y6!U8jYr2bRG(APR1>F*_YGqtw{Yg0`Hk*&pV0b&!3yS)ld!| zn-f5urNP6I+p~<`D6nDn7fewiT>32o*H`kl6t(#{?$F=*N%E5432(0YCHDnRmtM{%F+ZC$WQDv++M6`c7mUI8vfQsyf=ACU$>$DI+n##uKp{O$Xh-}+|U_|mnTX|Q;*F+<{u+T@*V3jZ|K z&~S*U?dR?=dYp2%b8#zklwvgU3(HA5ZJ*GQU#Pd#ydxV9O*j5)xBk^zxanB&!TRJbl+-sIOMSY7+S!-!q6vOvO6U|hJ<$tucw(e2>IopzU zf2Q#2*c**a=_FsApXeEHs+lu9>UQWW!OhK72-@dJnVPY@2A%?hObj3>@XYkT0K34m Aj{pDw literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/tutorial.png b/gulliver/thirdparty/krumo/docs/media/images/tutorial.png new file mode 100644 index 0000000000000000000000000000000000000000..bc19737521daf3fdf8ba84693a6c1db275587a5c GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfZXr^pAgre zprHL{KJDGRx2LCv!T8Mo|NkA*ZeG25wYa$W-Me?omMzQgdGzervomMTq@|^;S+i#5 z%$Y4ME$=`5xp(j0`I}#l9z7Zv8M$@qR-kNkbv01-`}gk!y^mPGos9)r!CBxDS#iRWF{)OWfrBD=NDxcEBHq2o~We) zR4WEj>s*wYSdy8arx22vo62BdqHkafM2UK~>Od6>JzX3_D(1wVzsPr3frB+*)nX0d z)r+?ozWcww_=ZWek(`gs#BPRvqA|;NeJ*kO*ruqfcq}a9c#C3L?KpBF@G1}eAg_> R{R!w;22WQ%mvv4FO#oMzwKo6& literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/tutorial_folder.png b/gulliver/thirdparty/krumo/docs/media/images/tutorial_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..2a468b2a06fa3424ba94773373637d424f91f7e0 GIT binary patch literal 572 zcmV-C0>k}@P)>~W@cuiqoe=KGyn8k-rnBK%*_ATKmXxKdU|^Q=uf|NmyHcL<7#inXPLp`VEqaE{#o000SaNLh0L01FZT01FZU z(%pXi0000MbVXQnLvm$dbZKvHAXI5>WdJZVFEBDMFf-YbT0#H-03dWlSaefwW^{L9 za%BKbVPkS{ZDnL>VIW3na%FdKa%*!SO<22;DkJ~^0HH}lK~#90Rm|HGfj|I&;Z-?S zTE~>lvDmU9)2vA$a-s45?_+lx7yird;s>}vSUUa%B5*H?0lB_-jxz$}S+Eu>Tci^} zf*_zRSBAc7nwO;j`bo#VVd?HJ70@Hv7$8pt&R;?fo08O0cTlDBo5&$ zS2)D&L_ip-Xv-c3iad`)mSr0V%M{(b3i`Z5_cW1MYXWTY*ZT`cP91=4{NC>X0000< KMNUMnLSTaQ$PWMj literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/docs/media/images/up_button.png b/gulliver/thirdparty/krumo/docs/media/images/up_button.png new file mode 100644 index 0000000000000000000000000000000000000000..ff36c59356d1d67cf8c4d12cef7b5aff7bf4dbc1 GIT binary patch literal 668 zcmV;N0%QG&P)%Pk4nVFe0X3Tq=+TY{p|NsA1fYZIby?c9mt*x!i*Xj57 z_j7Y|p0wcB-0AP{?>}zNjg5_FW@fduwWXz{lda&z#l@+-;@;%(Zjsl_%*=y>gJX); zOLx%L*4A8HT!y3E-rnA{#N%dWW|^6pp||AZ=k2Gu;O6G$tG?unrQUFp*;j$nOL)=N z-H!7B000SaNLh0L01m?d01m?e$8V@)0000WbVXQnQ*UN;cVTj608L?Ia&K*AWNBd_ zMrm?ocW-iQb0AGvyOAm+0000MbVXQnLvm$dbZKvHAXI5>WdJZVFEKJNFf-)xbMgQH z0aZyvK~#90eUl4s!XOZUanyCl+N~BSZdg%F=FV*U|Nm|WGzj(aC4Hp#g}ZVbsUwYZ z&Rzjil!QBIZEnCM*G;mFfhMO*Sgs&ijd4EZ4F>=mqdHh2`yC0Klf6aD**dot!!VqZ z1kM^tYtrbhSZY~S)mve)l_6jX>4Z|XyI6o$PsyzG!CTd_u;_}+68;72Gqbc*E#XaG z{1KHkUhfaBA749OLuPS0vpzyLTx|WwI-s@b{QWyw?8=I(yrMOhmdva(hL@P@CDfl= z3@+A)(FIx?d>#r*+a&qgfBjDR2CScBhYVBOmN=QV;cFbnb7;T&7X-qIrqsl*m$}d$CKcW835(Ow@m?{E zuz;N49J94VK$=2) { + this.childNodes[this.childNodes.length -2]._last = false; + } + while (root.parentNode) { root = root.parentNode; } + if (root.rendered) { + if (this.childNodes.length >= 2) { + document.getElementById(this.childNodes[this.childNodes.length -2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tIcon); + if (this.childNodes[this.childNodes.length -2].folder) { + this.childNodes[this.childNodes.length -2].plusIcon = webFXTreeConfig.tPlusIcon; + this.childNodes[this.childNodes.length -2].minusIcon = webFXTreeConfig.tMinusIcon; + } + this.childNodes[this.childNodes.length -2]._last = false; + } + this._last = true; + var foo = this; + while (foo.parentNode) { + for (var i = 0; i < foo.parentNode.childNodes.length; i++) { + if (foo.id == foo.parentNode.childNodes[i].id) { break; } + } + if (++i == foo.parentNode.childNodes.length) { foo.parentNode._last = true; } + else { foo.parentNode._last = false; } + foo = foo.parentNode; + } + document.getElementById(this.id + '-cont').insertAdjacentHTML("beforeEnd", node.toString()); + if ((!this.folder) && (!this.openIcon)) { + this.icon = webFXTreeConfig.folderIcon; + this.openIcon = webFXTreeConfig.openFolderIcon; + } + this.folder = true; + this.indent(); + this.expand(); + } + return node; +} + +WebFXTreeAbstractNode.prototype.toggle = function() { + if (this.folder) { + if (this.open) { this.collapse(); } + else { this.expand(); } + } +} + +WebFXTreeAbstractNode.prototype.select = function() { + document.getElementById(this.id + '-anchor').focus(); +} + +WebFXTreeAbstractNode.prototype.focus = function() { + webFXTreeHandler.selected = this; + if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.openIcon; } + document.getElementById(this.id + '-anchor').style.backgroundColor = 'highlight'; + document.getElementById(this.id + '-anchor').style.color = 'highlighttext'; + document.getElementById(this.id + '-anchor').focus(); +} + +WebFXTreeAbstractNode.prototype.blur = function() { + if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.icon; } + document.getElementById(this.id + '-anchor').style.backgroundColor = 'transparent'; + document.getElementById(this.id + '-anchor').style.color = 'menutext'; +} + +WebFXTreeAbstractNode.prototype.doExpand = function() { + if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.openIcon; } + if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'block'; } + this.open = true; + webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1'); +} + +WebFXTreeAbstractNode.prototype.doCollapse = function() { + if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.icon; } + if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'none'; } + this.open = false; + webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0'); +} + +WebFXTreeAbstractNode.prototype.expandAll = function() { + this.expandChildren(); + if ((this.folder) && (!this.open)) { this.expand(); } +} + +WebFXTreeAbstractNode.prototype.expandChildren = function() { + for (var i = 0; i < this.childNodes.length; i++) { + this.childNodes[i].expandAll(); +} } + +WebFXTreeAbstractNode.prototype.collapseAll = function() { + if ((this.folder) && (this.open)) { this.collapse(); } + this.collapseChildren(); +} + +WebFXTreeAbstractNode.prototype.collapseChildren = function() { + for (var i = 0; i < this.childNodes.length; i++) { + this.childNodes[i].collapseAll(); +} } + +WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level) { + /* + * Since we only want to modify items one level below ourself, + * and since the rightmost indentation position is occupied by + * the plus icon we set this to -2 + */ + if (lvl == null) { lvl = -2; } + var state = 0; + for (var i = this.childNodes.length - 1; i >= 0 ; i--) { + state = this.childNodes[i].indent(lvl + 1, del, last, level); + if (state) { return; } + } + if (del) { + if (level >= this._level) { + if (this.folder) { + document.getElementById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon; + this.plusIcon = webFXTreeConfig.lPlusIcon; + this.minusIcon = webFXTreeConfig.lMinusIcon; + } + else { document.getElementById(this.id + '-plus').src = webFXTreeConfig.lIcon; } + return 1; + } + } + var foo = document.getElementById(this.id + '-indent-' + lvl); + if (foo) { + if ((del) && (last)) { foo._last = true; } + if (foo._last) { foo.src = webFXTreeConfig.blankIcon; } + else { foo.src = webFXTreeConfig.iIcon; } + } + return 0; +} + +/* + * WebFXTree class + */ + +function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) { + this.base = WebFXTreeAbstractNode; + this.base(sText, sAction); + this.icon = sIcon || webFXTreeConfig.rootIcon; + this.openIcon = sOpenIcon || webFXTreeConfig.openRootIcon; + /* Defaults to open */ + this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true; + this.folder = true; + this.rendered = false; + if (!webFXTreeHandler.behavior) { webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior; } + this.targetWindow = 'right'; +} + +WebFXTree.prototype = new WebFXTreeAbstractNode; + +WebFXTree.prototype.setBehavior = function (sBehavior) { + webFXTreeHandler.behavior = sBehavior; +}; + +WebFXTree.prototype.getBehavior = function (sBehavior) { + return webFXTreeHandler.behavior; +}; + +WebFXTree.prototype.getSelected = function() { + if (webFXTreeHandler.selected) { return webFXTreeHandler.selected; } + else { return null; } +} + +WebFXTree.prototype.remove = function() { } + +WebFXTree.prototype.expand = function() { + this.doExpand(); +} + +WebFXTree.prototype.collapse = function() { + this.focus(); + this.doCollapse(); +} + +WebFXTree.prototype.getFirst = function() { + return null; +} + +WebFXTree.prototype.getLast = function() { + return null; +} + +WebFXTree.prototype.getNextSibling = function() { + return null; +} + +WebFXTree.prototype.getPreviousSibling = function() { + return null; +} + +WebFXTree.prototype.keydown = function(key) { + if (key == 39) { this.expand(); return false; } + if (key == 37) { this.collapse(); return false; } + if ((key == 40) && (this.open)) { this.childNodes[0].select(); return false; } + return true; +} + +WebFXTree.prototype.toString = function() { + var str = "
    "; + str += "" + this.text + "
    "; + str += "
    "; + for (var i = 0; i < this.childNodes.length; i++) { + str += this.childNodes[i].toString(i, this.childNodes.length); + } + str += "
    "; + this.rendered = true; + return str; +}; + +/* + * WebFXTreeItem class + */ + +function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) { + this.base = WebFXTreeAbstractNode; + this.base(sText, sAction); + /* Defaults to close */ + this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false; + if (eParent) { eParent.add(this); } + if (sIcon) { this.icon = sIcon; } + if (sOpenIcon) { this.openIcon = sOpenIcon; } +} + +WebFXTreeItem.prototype = new WebFXTreeAbstractNode; + +WebFXTreeItem.prototype.remove = function() { + var parentNode = this.parentNode; + var prevSibling = this.getPreviousSibling(true); + var nextSibling = this.getNextSibling(true); + var folder = this.parentNode.folder; + var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true; + this.getPreviousSibling().focus(); + this._remove(); + if (parentNode.childNodes.length == 0) { + parentNode.folder = false; + parentNode.open = false; + } + if (last) { + if (parentNode.id == prevSibling.id) { + document.getElementById(parentNode.id + '-icon').src = webFXTreeConfig.fileIcon; + } + else { } + } + if ((!prevSibling.parentNode) || (prevSibling.parentNode != parentNode)) { + parentNode.indent(null, true, last, this._level); + } + if (document.getElementById(prevSibling.id + '-plus')) { + if (nextSibling) { + if ((parentNode == prevSibling) && (parentNode.getNextSibling)) { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.tIcon; } + else if (nextSibling.parentNode != prevSibling) { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.lIcon; } + } + else { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.lIcon; } + } +} + +WebFXTreeItem.prototype._remove = function() { + for (var i = this.childNodes.length - 1; i >= 0; i--) { + this.childNodes[i]._remove(); + } + for (var i = 0; i < this.parentNode.childNodes.length; i++) { + if (this.id == this.parentNode.childNodes[i].id) { + for (var j = i; j < this.parentNode.childNodes.length; j++) { + this.parentNode.childNodes[i] = this.parentNode.childNodes[i+1] + } + this.parentNode.childNodes.length = this.parentNode.childNodes.length - 1; + if (i + 1 == this.parentNode.childNodes.length) { this.parentNode._last = true; } + } + } + webFXTreeHandler.all[this.id] = null; + if (document.getElementById(this.id)) { + document.getElementById(this.id).innerHTML = ""; + document.getElementById(this.id).removeNode(); + } +} + +WebFXTreeItem.prototype.expand = function() { + this.doExpand(); + document.getElementById(this.id + '-plus').src = this.minusIcon; +} + +WebFXTreeItem.prototype.collapse = function() { + this.focus(); + this.doCollapse(); + document.getElementById(this.id + '-plus').src = this.plusIcon; +} + +WebFXTreeItem.prototype.getFirst = function() { + return this.childNodes[0]; +} + +WebFXTreeItem.prototype.getLast = function() { + if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); } + else { return this.childNodes[this.childNodes.length - 1]; } +} + +WebFXTreeItem.prototype.getNextSibling = function() { + for (var i = 0; i < this.parentNode.childNodes.length; i++) { + if (this == this.parentNode.childNodes[i]) { break; } + } + if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); } + else { return this.parentNode.childNodes[i]; } +} + +WebFXTreeItem.prototype.getPreviousSibling = function(b) { + for (var i = 0; i < this.parentNode.childNodes.length; i++) { + if (this == this.parentNode.childNodes[i]) { break; } + } + if (i == 0) { return this.parentNode; } + else { + if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); } + else { return this.parentNode.childNodes[i]; } +} } + +WebFXTreeItem.prototype.keydown = function(key) { + if ((key == 39) && (this.folder)) { + if (!this.open) { this.expand(); return false; } + else { this.getFirst().select(); return false; } + } + else if (key == 37) { + if (this.open) { this.collapse(); return false; } + else { this.parentNode.select(); return false; } + } + else if (key == 40) { + if (this.open) { this.getFirst().select(); return false; } + else { + var sib = this.getNextSibling(); + if (sib) { sib.select(); return false; } + } } + else if (key == 38) { this.getPreviousSibling().select(); return false; } + return true; +} + +WebFXTreeItem.prototype.toString = function (nItem, nItemCount) { + var foo = this.parentNode; + var indent = ''; + if (nItem + 1 == nItemCount) { this.parentNode._last = true; } + var i = 0; + while (foo.parentNode) { + foo = foo.parentNode; + indent = "" + indent; + i++; + } + this._level = i; + if (this.childNodes.length) { this.folder = 1; } + else { this.open = false; } + if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) { + if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; } + if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; } + } + else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; } + var label = this.text; + label = label.replace('<', '<'); + label = label.replace('>', '>'); + var str = "
    "; + str += indent; + str += "" + str += "" + label + "
    "; + str += "
    "; + for (var i = 0; i < this.childNodes.length; i++) { + str += this.childNodes[i].toString(i,this.childNodes.length); + } + str += "
    "; + this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon); + this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon); + return str; +} \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/media/stylesheet.css b/gulliver/thirdparty/krumo/docs/media/stylesheet.css new file mode 100644 index 000000000..498826ae1 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/media/stylesheet.css @@ -0,0 +1,181 @@ +a { color: #000090; text-decoration: none; } +a:hover, a:active, a:focus { color: highlighttext; background-color: highlight; text-decoration: none; } + +body { background : #FFFFFF; } +body, table { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; } + +a img { border: 0px; } + +/* Page layout/boxes */ + +.info-box { } +.info-box-title { margin: 1em 0em 0em 0em; font-weight: normal; font-size: 14pt; color: #999999; border-bottom: 2px solid #999999; } +.info-box-body { border: 1px solid #999999; padding: .5em; } +.nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; } + +.oddrow { background-color: #F8F8F8; border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em} +.evenrow { border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em} + +.page-body { max-width: 800px; margin: auto; } +.tree { } + +/* Index formatting classes */ + +.index-item-body { margin-top: .5em; margin-bottom: .5em} +.index-item-description { margin-top: .25em } +.index-item-details { font-weight: normal; font-style: italic; font-size: 8pt } +.index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em} +.index-letter-title { font-size: 12pt; font-weight: bold } +.index-letter-menu { text-align: center; margin: 1em } +.index-letter { font-size: 12pt } + +/* Docbook classes */ + +.description {} +.short-description { font-weight: bold; color: #666666; } +.tags { padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; } +.parameters { padding-left: 0em; margin-left: 3em; color: #014fbe; list-style-type: square; } +.redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; } +.package { font-weight: bold; } +.package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black } +.sub-package { font-weight: bold; } +.tutorial { border-width: thin; border-color: #0066ff; } +.tutorial-nav-box { width: 100%; border: 1px solid #999999; background-color: #F8F8F8; } + +/* Generic formatting */ + +.field { font-weight: bold; } +.detail { font-size: 8pt; } +.notes { font-style: italic; font-size: 8pt; } +.separator { background-color: #999999; height: 2px; } +.warning { color: #FF6600; } +.disabled { font-style: italic; color: #999999; } + +/* Code elements */ + +.line-number { } + +.class-table { width: 100%; } +.class-table-header { border-bottom: 1px dotted #666666; text-align: left} +.class-name { color: #0000AA; font-weight: bold; } + +.method-summary { color: #009000; padding-left: 1em; font-size: 8pt; } +.method-header { } +.method-definition { margin-bottom: .2em } +.method-title { color: #009000; font-weight: bold; } +.method-name { font-weight: bold; } +.method-signature { font-size: 85%; color: #666666; margin: .5em 0em } +.method-result { font-style: italic; } + +.var-summary { padding-left: 1em; font-size: 8pt; } +.var-header { } +.var-title { color: #014fbe; margin-bottom: .3em } +.var-type { font-style: italic; } +.var-name { font-weight: bold; } +.var-default {} +.var-description { font-weight: normal; color: #000000; } + +.include-title { color: #014fbe;} +.include-type { font-style: italic; } +.include-name { font-weight: bold; } + +.const-title { color: #FF6600; } +.const-name { font-weight: bold; } + +/* Syntax highlighting */ + +.src-code { font-family: 'Courier New', Courier, monospace; font-weight: normal; } +.src-line { font-family: 'Courier New', Courier, monospace; font-weight: normal; } + +.src-code a:link { padding: 1px; text-decoration: underline; color: #0000DD; } +.src-code a:visited { text-decoration: underline; color: #0000DD; } +.src-code a:active { background-color: #FFFF66; color: #008000; } +.src-code a:hover { background-color: #FFFF66; text-decoration: overline underline; color: #008000; } + +.src-comm { color: #666666; } +.src-id { color: #FF6600; font-style: italic; } +.src-inc { color: #0000AA; font-weight: bold; } +.src-key { color: #0000AA; font-weight: bold; } +.src-num { color: #CC0000; } +.src-str { color: #CC0000; } +.src-sym { } +.src-var { } + +.src-php { font-weight: bold; } + +.src-doc { color: #666666; } +.src-doc-close-template { color: #666666 } +.src-doc-coretag { color: #008000; } +.src-doc-inlinetag {} +.src-doc-internal {} +.src-doc-tag { color: #0080CC; } +.src-doc-template { color: #666666 } +.src-doc-type { font-style: italic; color: #444444 } +.src-doc-var { color: #444444 } + +.tute-tag { color: #009999 } +.tute-attribute-name { color: #0000FF } +.tute-attribute-value { color: #0099FF } +.tute-entity { font-weight: bold; } +.tute-comment { font-style: italic } +.tute-inline-tag { color: #636311; font-weight: bold } + +/* tutorial */ + +.authors { } +.author { font-style: italic; font-weight: bold } +.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal } +.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; } +.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap; } +.release-info { font-size: 85%; font-style: italic; margin: 1em 0em } +.ref-title-box { } +.ref-title { } +.ref-purpose { font-style: italic; color: #666666 } +.ref-synopsis { } +.title { font-weight: bold; border-bottom: 1px solid #999999; color: #999999; } +.cmd-synopsis { margin: 1em 0em } +.cmd-title { font-weight: bold } +.toc { margin-left: 2em; padding-left: 0em } + +/*------------------------------------------------------------------------------ + webfx-tree +------------------------------------------------------------------------------*/ + +.webfx-tree-container { + margin: 0px; + padding: 0px; + white-space: nowrap; + font: icon; +} + +.webfx-tree-item { + padding: 0px; + margin: 0px; + color: black; + white-space: nowrap; + font: icon; +} + +.webfx-tree-item a { + margin-left: 3px; + padding: 1px 2px 1px 2px; + color: black; + text-decoration: none; +} + +.webfx-tree-item a:hover, .webfx-tree-item a:active { + color: highlighttext; + background: highlight; + text-decoration: none +} + +.webfx-tree-item img { + vertical-align: middle; + border: 0px; +} + +.webfx-tree-icon { + width: 16px; + height: 16px; +} + diff --git a/gulliver/thirdparty/krumo/docs/packages.html b/gulliver/thirdparty/krumo/docs/packages.html new file mode 100644 index 000000000..a4852e3d0 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/packages.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/ric_INSTALL.html b/gulliver/thirdparty/krumo/docs/ric_INSTALL.html new file mode 100644 index 000000000..8851703f1 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/ric_INSTALL.html @@ -0,0 +1,49 @@ + + + + + + + + + +

    INSTALL

    +
    +------------------------------------------------------------------------------
    +
    +                     SETUP: How to install Krumo ?
    +
    +------------------------------------------------------------------------------
    +
    +In order to use Krumo you have to put it on your (development) server, and 
    +include it in your script. You can put it somewhere in the INCLUDE_PATH, or 
    +specify the full path to the "class.krumo.php" file.
    +
    +You have to modify the "krumo.ini" file too. It is the configuration file for 
    +Krumo. The first option is choosing a skin:
    +
    + [skin]
    + selected = "orange"
    +
    +The value for this setting has to be the name of one of the sub-folders from the 
    +"Krumo/skins/" folder. If the value provided for the skin results in not finding 
    +the skin, the `default` skin will be used instead.
    +
    +The second option is used to set the correct web path to the folder where Krumo 
    +is installed. This is used in order to make the images from Krumo's CSS skins 
    +web-accessible.
    +
    + [css]
    + url = "http://www.example.com/Krumo/"
    +
    +So far those two are the only configuration options.
    +
    +All the CSS files ("skin.css") from the "Krumo/skins/" sub-folders must have the 
    +proper permissions in order to be readable from Krumo. Same applies for 
    +"krumo.ini" and "krumo.js" files.
    +
    +

    + Documentation generated on Sun, 02 Dec 2007 09:43:22 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/ric_LICENSE.html b/gulliver/thirdparty/krumo/docs/ric_LICENSE.html new file mode 100644 index 000000000..aa2cad1e9 --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/ric_LICENSE.html @@ -0,0 +1,522 @@ + + + + + + + + + +

    LICENSE

    +
    +		  GNU LESSER GENERAL PUBLIC LICENSE
    +		       Version 2.1, February 1999
    +
    + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    +     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    + Everyone is permitted to copy and distribute verbatim copies
    + of this license document, but changing it is not allowed.
    +
    +[This is the first released version of the Lesser GPL.  It also counts
    + as the successor of the GNU Library Public License, version 2, hence
    + the version number 2.1.]
    +
    +			    Preamble
    +
    +  The licenses for most software are designed to take away your
    +freedom to share and change it.  By contrast, the GNU General Public
    +Licenses are intended to guarantee your freedom to share and change
    +free software--to make sure the software is free for all its users.
    +
    +  This license, the Lesser General Public License, applies to some
    +specially designated software packages--typically libraries--of the
    +Free Software Foundation and other authors who decide to use it.  You
    +can use it too, but we suggest you first think carefully about whether
    +this license or the ordinary General Public License is the better
    +strategy to use in any particular case, based on the explanations below.
    +
    +  When we speak of free software, we are referring to freedom of use,
    +not price.  Our General Public Licenses are designed to make sure that
    +you have the freedom to distribute copies of free software (and charge
    +for this service if you wish); that you receive source code or can get
    +it if you want it; that you can change the software and use pieces of
    +it in new free programs; and that you are informed that you can do
    +these things.
    +
    +  To protect your rights, we need to make restrictions that forbid
    +distributors to deny you these rights or to ask you to surrender these
    +rights.  These restrictions translate to certain responsibilities for
    +you if you distribute copies of the library or if you modify it.
    +
    +  For example, if you distribute copies of the library, whether gratis
    +or for a fee, you must give the recipients all the rights that we gave
    +you.  You must make sure that they, too, receive or can get the source
    +code.  If you link other code with the library, you must provide
    +complete object files to the recipients, so that they can relink them
    +with the library after making changes to the library and recompiling
    +it.  And you must show them these terms so they know their rights.
    +
    +  We protect your rights with a two-step method: (1) we copyright the
    +library, and (2) we offer you this license, which gives you legal
    +permission to copy, distribute and/or modify the library.
    +
    +  To protect each distributor, we want to make it very clear that
    +there is no warranty for the free library.  Also, if the library is
    +modified by someone else and passed on, the recipients should know
    +that what they have is not the original version, so that the original
    +author's reputation will not be affected by problems that might be
    +introduced by others.
    +
    +  Finally, software patents pose a constant threat to the existence of
    +any free program.  We wish to make sure that a company cannot
    +effectively restrict the users of a free program by obtaining a
    +restrictive license from a patent holder.  Therefore, we insist that
    +any patent license obtained for a version of the library must be
    +consistent with the full freedom of use specified in this license.
    +
    +  Most GNU software, including some libraries, is covered by the
    +ordinary GNU General Public License.  This license, the GNU Lesser
    +General Public License, applies to certain designated libraries, and
    +is quite different from the ordinary General Public License.  We use
    +this license for certain libraries in order to permit linking those
    +libraries into non-free programs.
    +
    +  When a program is linked with a library, whether statically or using
    +a shared library, the combination of the two is legally speaking a
    +combined work, a derivative of the original library.  The ordinary
    +General Public License therefore permits such linking only if the
    +entire combination fits its criteria of freedom.  The Lesser General
    +Public License permits more lax criteria for linking other code with
    +the library.
    +
    +  We call this license the "Lesser" General Public License because it
    +does Less to protect the user's freedom than the ordinary General
    +Public License.  It also provides other free software developers Less
    +of an advantage over competing non-free programs.  These disadvantages
    +are the reason we use the ordinary General Public License for many
    +libraries.  However, the Lesser license provides advantages in certain
    +special circumstances.
    +
    +  For example, on rare occasions, there may be a special need to
    +encourage the widest possible use of a certain library, so that it becomes
    +a de-facto standard.  To achieve this, non-free programs must be
    +allowed to use the library.  A more frequent case is that a free
    +library does the same job as widely used non-free libraries.  In this
    +case, there is little to gain by limiting the free library to free
    +software only, so we use the Lesser General Public License.
    +
    +  In other cases, permission to use a particular library in non-free
    +programs enables a greater number of people to use a large body of
    +free software.  For example, permission to use the GNU C Library in
    +non-free programs enables many more people to use the whole GNU
    +operating system, as well as its variant, the GNU/Linux operating
    +system.
    +
    +  Although the Lesser General Public License is Less protective of the
    +users' freedom, it does ensure that the user of a program that is
    +linked with the Library has the freedom and the wherewithal to run
    +that program using a modified version of the Library.
    +
    +  The precise terms and conditions for copying, distribution and
    +modification follow.  Pay close attention to the difference between a
    +"work based on the library" and a "work that uses the library".  The
    +former contains code derived from the library, whereas the latter must
    +be combined with the library in order to run.
    +
    +		  GNU LESSER GENERAL PUBLIC LICENSE
    +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    +
    +  0. This License Agreement applies to any software library or other
    +program which contains a notice placed by the copyright holder or
    +other authorized party saying it may be distributed under the terms of
    +this Lesser General Public License (also called "this License").
    +Each licensee is addressed as "you".
    +
    +  A "library" means a collection of software functions and/or data
    +prepared so as to be conveniently linked with application programs
    +(which use some of those functions and data) to form executables.
    +
    +  The "Library", below, refers to any such software library or work
    +which has been distributed under these terms.  A "work based on the
    +Library" means either the Library or any derivative work under
    +copyright law: that is to say, a work containing the Library or a
    +portion of it, either verbatim or with modifications and/or translated
    +straightforwardly into another language.  (Hereinafter, translation is
    +included without limitation in the term "modification".)
    +
    +  "Source code" for a work means the preferred form of the work for
    +making modifications to it.  For a library, complete source code means
    +all the source code for all modules it contains, plus any associated
    +interface definition files, plus the scripts used to control compilation
    +and installation of the library.
    +
    +  Activities other than copying, distribution and modification are not
    +covered by this License; they are outside its scope.  The act of
    +running a program using the Library is not restricted, and output from
    +such a program is covered only if its contents constitute a work based
    +on the Library (independent of the use of the Library in a tool for
    +writing it).  Whether that is true depends on what the Library does
    +and what the program that uses the Library does.
    +  
    +  1. You may copy and distribute verbatim copies of the Library's
    +complete source code as you receive it, in any medium, provided that
    +you conspicuously and appropriately publish on each copy an
    +appropriate copyright notice and disclaimer of warranty; keep intact
    +all the notices that refer to this License and to the absence of any
    +warranty; and distribute a copy of this License along with the
    +Library.
    +
    +  You may charge a fee for the physical act of transferring a copy,
    +and you may at your option offer warranty protection in exchange for a
    +fee.
    +
    +  2. You may modify your copy or copies of the Library or any portion
    +of it, thus forming a work based on the Library, and copy and
    +distribute such modifications or work under the terms of Section 1
    +above, provided that you also meet all of these conditions:
    +
    +    a) The modified work must itself be a software library.
    +
    +    b) You must cause the files modified to carry prominent notices
    +    stating that you changed the files and the date of any change.
    +
    +    c) You must cause the whole of the work to be licensed at no
    +    charge to all third parties under the terms of this License.
    +
    +    d) If a facility in the modified Library refers to a function or a
    +    table of data to be supplied by an application program that uses
    +    the facility, other than as an argument passed when the facility
    +    is invoked, then you must make a good faith effort to ensure that,
    +    in the event an application does not supply such function or
    +    table, the facility still operates, and performs whatever part of
    +    its purpose remains meaningful.
    +
    +    (For example, a function in a library to compute square roots has
    +    a purpose that is entirely well-defined independent of the
    +    application.  Therefore, Subsection 2d requires that any
    +    application-supplied function or table used by this function must
    +    be optional: if the application does not supply it, the square
    +    root function must still compute square roots.)
    +
    +These requirements apply to the modified work as a whole.  If
    +identifiable sections of that work are not derived from the Library,
    +and can be reasonably considered independent and separate works in
    +themselves, then this License, and its terms, do not apply to those
    +sections when you distribute them as separate works.  But when you
    +distribute the same sections as part of a whole which is a work based
    +on the Library, the distribution of the whole must be on the terms of
    +this License, whose permissions for other licensees extend to the
    +entire whole, and thus to each and every part regardless of who wrote
    +it.
    +
    +Thus, it is not the intent of this section to claim rights or contest
    +your rights to work written entirely by you; rather, the intent is to
    +exercise the right to control the distribution of derivative or
    +collective works based on the Library.
    +
    +In addition, mere aggregation of another work not based on the Library
    +with the Library (or with a work based on the Library) on a volume of
    +a storage or distribution medium does not bring the other work under
    +the scope of this License.
    +
    +  3. You may opt to apply the terms of the ordinary GNU General Public
    +License instead of this License to a given copy of the Library.  To do
    +this, you must alter all the notices that refer to this License, so
    +that they refer to the ordinary GNU General Public License, version 2,
    +instead of to this License.  (If a newer version than version 2 of the
    +ordinary GNU General Public License has appeared, then you can specify
    +that version instead if you wish.)  Do not make any other change in
    +these notices.
    +
    +  Once this change is made in a given copy, it is irreversible for
    +that copy, so the ordinary GNU General Public License applies to all
    +subsequent copies and derivative works made from that copy.
    +
    +  This option is useful when you wish to copy part of the code of
    +the Library into a program that is not a library.
    +
    +  4. You may copy and distribute the Library (or a portion or
    +derivative of it, under Section 2) in object code or executable form
    +under the terms of Sections 1 and 2 above provided that you accompany
    +it with the complete corresponding machine-readable source code, which
    +must be distributed under the terms of Sections 1 and 2 above on a
    +medium customarily used for software interchange.
    +
    +  If distribution of object code is made by offering access to copy
    +from a designated place, then offering equivalent access to copy the
    +source code from the same place satisfies the requirement to
    +distribute the source code, even though third parties are not
    +compelled to copy the source along with the object code.
    +
    +  5. A program that contains no derivative of any portion of the
    +Library, but is designed to work with the Library by being compiled or
    +linked with it, is called a "work that uses the Library".  Such a
    +work, in isolation, is not a derivative work of the Library, and
    +therefore falls outside the scope of this License.
    +
    +  However, linking a "work that uses the Library" with the Library
    +creates an executable that is a derivative of the Library (because it
    +contains portions of the Library), rather than a "work that uses the
    +library".  The executable is therefore covered by this License.
    +Section 6 states terms for distribution of such executables.
    +
    +  When a "work that uses the Library" uses material from a header file
    +that is part of the Library, the object code for the work may be a
    +derivative work of the Library even though the source code is not.
    +Whether this is true is especially significant if the work can be
    +linked without the Library, or if the work is itself a library.  The
    +threshold for this to be true is not precisely defined by law.
    +
    +  If such an object file uses only numerical parameters, data
    +structure layouts and accessors, and small macros and small inline
    +functions (ten lines or less in length), then the use of the object
    +file is unrestricted, regardless of whether it is legally a derivative
    +work.  (Executables containing this object code plus portions of the
    +Library will still fall under Section 6.)
    +
    +  Otherwise, if the work is a derivative of the Library, you may
    +distribute the object code for the work under the terms of Section 6.
    +Any executables containing that work also fall under Section 6,
    +whether or not they are linked directly with the Library itself.
    +
    +  6. As an exception to the Sections above, you may also combine or
    +link a "work that uses the Library" with the Library to produce a
    +work containing portions of the Library, and distribute that work
    +under terms of your choice, provided that the terms permit
    +modification of the work for the customer's own use and reverse
    +engineering for debugging such modifications.
    +
    +  You must give prominent notice with each copy of the work that the
    +Library is used in it and that the Library and its use are covered by
    +this License.  You must supply a copy of this License.  If the work
    +during execution displays copyright notices, you must include the
    +copyright notice for the Library among them, as well as a reference
    +directing the user to the copy of this License.  Also, you must do one
    +of these things:
    +
    +    a) Accompany the work with the complete corresponding
    +    machine-readable source code for the Library including whatever
    +    changes were used in the work (which must be distributed under
    +    Sections 1 and 2 above); and, if the work is an executable linked
    +    with the Library, with the complete machine-readable "work that
    +    uses the Library", as object code and/or source code, so that the
    +    user can modify the Library and then relink to produce a modified
    +    executable containing the modified Library.  (It is understood
    +    that the user who changes the contents of definitions files in the
    +    Library will not necessarily be able to recompile the application
    +    to use the modified definitions.)
    +
    +    b) Use a suitable shared library mechanism for linking with the
    +    Library.  A suitable mechanism is one that (1) uses at run time a
    +    copy of the library already present on the user's computer system,
    +    rather than copying library functions into the executable, and (2)
    +    will operate properly with a modified version of the library, if
    +    the user installs one, as long as the modified version is
    +    interface-compatible with the version that the work was made with.
    +
    +    c) Accompany the work with a written offer, valid for at
    +    least three years, to give the same user the materials
    +    specified in Subsection 6a, above, for a charge no more
    +    than the cost of performing this distribution.
    +
    +    d) If distribution of the work is made by offering access to copy
    +    from a designated place, offer equivalent access to copy the above
    +    specified materials from the same place.
    +
    +    e) Verify that the user has already received a copy of these
    +    materials or that you have already sent this user a copy.
    +
    +  For an executable, the required form of the "work that uses the
    +Library" must include any data and utility programs needed for
    +reproducing the executable from it.  However, as a special exception,
    +the materials to be distributed need not include anything that is
    +normally distributed (in either source or binary form) with the major
    +components (compiler, kernel, and so on) of the operating system on
    +which the executable runs, unless that component itself accompanies
    +the executable.
    +
    +  It may happen that this requirement contradicts the license
    +restrictions of other proprietary libraries that do not normally
    +accompany the operating system.  Such a contradiction means you cannot
    +use both them and the Library together in an executable that you
    +distribute.
    +
    +  7. You may place library facilities that are a work based on the
    +Library side-by-side in a single library together with other library
    +facilities not covered by this License, and distribute such a combined
    +library, provided that the separate distribution of the work based on
    +the Library and of the other library facilities is otherwise
    +permitted, and provided that you do these two things:
    +
    +    a) Accompany the combined library with a copy of the same work
    +    based on the Library, uncombined with any other library
    +    facilities.  This must be distributed under the terms of the
    +    Sections above.
    +
    +    b) Give prominent notice with the combined library of the fact
    +    that part of it is a work based on the Library, and explaining
    +    where to find the accompanying uncombined form of the same work.
    +
    +  8. You may not copy, modify, sublicense, link with, or distribute
    +the Library except as expressly provided under this License.  Any
    +attempt otherwise to copy, modify, sublicense, link with, or
    +distribute the Library is void, and will automatically terminate your
    +rights under this License.  However, parties who have received copies,
    +or rights, from you under this License will not have their licenses
    +terminated so long as such parties remain in full compliance.
    +
    +  9. You are not required to accept this License, since you have not
    +signed it.  However, nothing else grants you permission to modify or
    +distribute the Library or its derivative works.  These actions are
    +prohibited by law if you do not accept this License.  Therefore, by
    +modifying or distributing the Library (or any work based on the
    +Library), you indicate your acceptance of this License to do so, and
    +all its terms and conditions for copying, distributing or modifying
    +the Library or works based on it.
    +
    +  10. Each time you redistribute the Library (or any work based on the
    +Library), the recipient automatically receives a license from the
    +original licensor to copy, distribute, link with or modify the Library
    +subject to these terms and conditions.  You may not impose any further
    +restrictions on the recipients' exercise of the rights granted herein.
    +You are not responsible for enforcing compliance by third parties with
    +this License.
    +
    +  11. If, as a consequence of a court judgment or allegation of patent
    +infringement or for any other reason (not limited to patent issues),
    +conditions are imposed on you (whether by court order, agreement or
    +otherwise) that contradict the conditions of this License, they do not
    +excuse you from the conditions of this License.  If you cannot
    +distribute so as to satisfy simultaneously your obligations under this
    +License and any other pertinent obligations, then as a consequence you
    +may not distribute the Library at all.  For example, if a patent
    +license would not permit royalty-free redistribution of the Library by
    +all those who receive copies directly or indirectly through you, then
    +the only way you could satisfy both it and this License would be to
    +refrain entirely from distribution of the Library.
    +
    +If any portion of this section is held invalid or unenforceable under any
    +particular circumstance, the balance of the section is intended to apply,
    +and the section as a whole is intended to apply in other circumstances.
    +
    +It is not the purpose of this section to induce you to infringe any
    +patents or other property right claims or to contest validity of any
    +such claims; this section has the sole purpose of protecting the
    +integrity of the free software distribution system which is
    +implemented by public license practices.  Many people have made
    +generous contributions to the wide range of software distributed
    +through that system in reliance on consistent application of that
    +system; it is up to the author/donor to decide if he or she is willing
    +to distribute software through any other system and a licensee cannot
    +impose that choice.
    +
    +This section is intended to make thoroughly clear what is believed to
    +be a consequence of the rest of this License.
    +
    +  12. If the distribution and/or use of the Library is restricted in
    +certain countries either by patents or by copyrighted interfaces, the
    +original copyright holder who places the Library under this License may add
    +an explicit geographical distribution limitation excluding those countries,
    +so that distribution is permitted only in or among countries not thus
    +excluded.  In such case, this License incorporates the limitation as if
    +written in the body of this License.
    +
    +  13. The Free Software Foundation may publish revised and/or new
    +versions of the Lesser General Public License from time to time.
    +Such new versions will be similar in spirit to the present version,
    +but may differ in detail to address new problems or concerns.
    +
    +Each version is given a distinguishing version number.  If the Library
    +specifies a version number of this License which applies to it and
    +"any later version", you have the option of following the terms and
    +conditions either of that version or of any later version published by
    +the Free Software Foundation.  If the Library does not specify a
    +license version number, you may choose any version ever published by
    +the Free Software Foundation.
    +
    +  14. If you wish to incorporate parts of the Library into other free
    +programs whose distribution conditions are incompatible with these,
    +write to the author to ask for permission.  For software which is
    +copyrighted by the Free Software Foundation, write to the Free
    +Software Foundation; we sometimes make exceptions for this.  Our
    +decision will be guided by the two goals of preserving the free status
    +of all derivatives of our free software and of promoting the sharing
    +and reuse of software generally.
    +
    +			    NO WARRANTY
    +
    +  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
    +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
    +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
    +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
    +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
    +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    +PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
    +LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
    +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    +
    +  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
    +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
    +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
    +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
    +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
    +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
    +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
    +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
    +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    +DAMAGES.
    +
    +		     END OF TERMS AND CONDITIONS
    +
    +           How to Apply These Terms to Your New Libraries
    +
    +  If you develop a new library, and you want it to be of the greatest
    +possible use to the public, we recommend making it free software that
    +everyone can redistribute and change.  You can do so by permitting
    +redistribution under these terms (or, alternatively, under the terms of the
    +ordinary General Public License).
    +
    +  To apply these terms, attach the following notices to the library.  It is
    +safest to attach them to the start of each source file to most effectively
    +convey the exclusion of warranty; and each file should have at least the
    +"copyright" line and a pointer to where the full notice is found.
    +
    +    <one line to give the library's name and a brief idea of what it does.>
    +    Copyright (C) <year>  <name of author>
    +
    +    This library is free software; you can redistribute it and/or
    +    modify it under the terms of the GNU Lesser General Public
    +    License as published by the Free Software Foundation; either
    +    version 2.1 of the License, or (at your option) any later version.
    +
    +    This library is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +    Lesser General Public License for more details.
    +
    +    You should have received a copy of the GNU Lesser General Public
    +    License along with this library; if not, write to the Free Software
    +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    +
    +Also add information on how to contact you by electronic and paper mail.
    +
    +You should also get your employer (if you work as a programmer) or your
    +school, if any, to sign a "copyright disclaimer" for the library, if
    +necessary.  Here is a sample; alter the names:
    +
    +  Yoyodyne, Inc., hereby disclaims all copyright interest in the
    +  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
    +
    +  <signature of Ty Coon>, 1 April 1990
    +  Ty Coon, President of Vice
    +
    +That's all there is to it!
    +
    +
    +
    +
    +

    + Documentation generated on Sun, 02 Dec 2007 09:43:23 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/ric_README.html b/gulliver/thirdparty/krumo/docs/ric_README.html new file mode 100644 index 000000000..559d3c24c --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/ric_README.html @@ -0,0 +1,121 @@ + + + + + + + + + +

    README

    +
    +=============================================================================
    +
    +                               Krumo
    +                            version 0.1a
    +
    +=============================================================================
    +
    +You probably got this package from...
    +http://www.sourceforge.net/projects/krumo/
    +
    +If there is no licence agreement with this package please download
    +a version from the location above. You must read and accept that
    +licence to use this software. The file is titled simply LICENSE.
    +
    +OVERVIEW
    +------------------------------------------------------------------------------
    +To put it simply, Krumo is a replacement for print_r() and var_dump(). By 
    +definition Krumo is a debugging tool (PHP4/PHP5), which displays structured 
    +information about any PHP variable.
    +
    +A lot of developers use print_r() and var_dump() in the means of debugging 
    +tools. Although they were intended to present human readble information about a 
    +variable, we can all agree that in general they are not. Krumo is an 
    +alternative: it does the same job, but it presents the information beautified 
    +using CSS and DHTML. 
    +
    +EXAMPLES
    +------------------------------------------------------------------------------
    +Here's a basic example, which will return a report on the array variable passed 
    +as argument to it:
    +
    + krumo(array('a1'=> 'A1', 3, 'red'));
    +
    +You can dump simultaneously more then one variable - here's another example:
    +
    + krumo($_SERVER, $_REQUEST);
    +
    +You probably saw from the examples above that some of the nodes are expandable, 
    +so if you want to inspect the nested information, click on them and they will 
    +expand; if you do not need that information shown simply click again on it to 
    +collapse it. Here's an example to test this:
    +
    + $x1->x2->x3->x4->x5->x6->x7->x8->x9 = 'X10';
    + krumo($x1);
    +
    +The krumo() is the only standalone function from the package, and this is 
    +because basic dumps about variables (like print_r() or var_dump()) are the most 
    +common tasks such functionality is used for. The rest of the functionality can 
    +be called using static calls to the Krumo class. Here are several more examples:
    +
    + // print a debug backgrace
    + krumo::backtrace();
    +
    + // print all the included(or required) files
    + krumo::includes();
    + 
    + // print all the included functions
    + krumo::functions();
    + 
    + // print all the declared classes
    + krumo::classes();
    + 
    + // print all the defined constants
    + krumo::defines();
    +
    + ... and so on, etc.
    +
    +A full PHPDocumenter API documentation exists both in this package and at the 
    +project's website.
    +
    +INSTALL
    +------------------------------------------------------------------------------
    +Read the INSTALL file.
    +
    +DOCUMENTATION
    +------------------------------------------------------------------------------
    +As I said, a full PHPDocumenter API documentation can be found both in this
    +package and at the project's website.
    +
    +SKINS
    +------------------------------------------------------------------------------
    +There are several skins pre-installed with this package, but if you wish you can 
    +create skins of your own. The skins are simply CSS files that are prepended to 
    +the result that Krumo prints. If you want to use images in your CSS (for 
    +background, list-style, etc), you have to put "%URL%" in front of the image URL 
    +in order hook it up to the skin folder and make the image web-accessible.
    +
    +Here's an example:
    +
    + ul.krumo-first {background: url(%url%bg.gif);}
    +
    +TODO
    +------------------------------------------------------------------------------
    +You can find the list of stuff that is going to be added to this project in the 
    +TODO file from this very package.
    +
    +CONTRIBUTION
    +-----------------------------------------------------------------------------
    +If you download and use and possibly even extend this tool, please let us know. 
    +Any feedback, even bad, is always welcome and your suggestions are going to be 
    +considered for our next release. Please use our SourceForge page for that:
    + 
    + http://www.sourceforge.net/projects/krumo/
    +
    +
    +

    + Documentation generated on Sat, 16 Jun 2007 09:50:08 +0300 by phpDocumentor 1.3.0RC4 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/ric_TODO.html b/gulliver/thirdparty/krumo/docs/ric_TODO.html new file mode 100644 index 000000000..82b751e8b --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/ric_TODO.html @@ -0,0 +1,41 @@ + + + + + + + + + +

    TODO

    +
    +******************************************************************************
    +
    +                                 Krumo: TODO
    +
    +******************************************************************************
    +
    +BUGS
    +----------------
    + - watch the SourceForge.net Bug Tracker
    +
    +Features: PHP
    +----------------
    + - Try to detect anonymous (lambda) functions
    + - Try to detect whether an array is indexed or associated
    + - Add var_export support for arrays and objects
    + - Add JSON support for arrays and objects
    + 
    +Features: GUI
    +----------------
    + - Nicer and friendlier skin(s)
    + - Add top-level links for collapsing and expanding the whole tree
    + - Add object & array -level links for collapsing and expanding all the
    + 	nested nodes
    + - Print all parent classes for the rendered objects
    +
    +

    + Documentation generated on Sun, 02 Dec 2007 09:43:23 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/docs/ric_VERSION.html b/gulliver/thirdparty/krumo/docs/ric_VERSION.html new file mode 100644 index 000000000..45904040e --- /dev/null +++ b/gulliver/thirdparty/krumo/docs/ric_VERSION.html @@ -0,0 +1,18 @@ + + + + + + + + + +

    VERSION

    +
    +0.2.1a
    +
    +

    + Documentation generated on Sun, 02 Dec 2007 09:43:23 +0200 by phpDocumentor 1.4.0a2 +

    + + \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/krumo.ini b/gulliver/thirdparty/krumo/krumo.ini new file mode 100644 index 000000000..2ccfc128c --- /dev/null +++ b/gulliver/thirdparty/krumo/krumo.ini @@ -0,0 +1,20 @@ +; +; KRUMO CONFIGURATION FILE +; + +[skin] +selected = "schablon.com" +; +; Change the above value to set the CSS skin used to render +; Krumo layout. If the skin is not found, then the "default" one +; is going to be used. +; + +[css] +url = "/Krumo/" +; +; This value is used to set the URL path to +; where the Krumo folder is. This is required in +; order to have web access to Krumo's CSS and +; image files. +; \ No newline at end of file diff --git a/gulliver/thirdparty/krumo/krumo.js b/gulliver/thirdparty/krumo/krumo.js new file mode 100644 index 000000000..035fe44c0 --- /dev/null +++ b/gulliver/thirdparty/krumo/krumo.js @@ -0,0 +1,37 @@ +/** JavaScript routines for Krumo +* @version $Id: krumo.js 22 2007-12-02 07:38:18Z Mrasnika $ +* @link http://sourceforge.net/projects/krumo +*/ + +function krumo() {} +krumo.reclass = function(el, className) { + if (el.className.indexOf(className) < 0) { + el.className += (' ' + className); + } +} +krumo.unclass = function(el, className) { + if (el.className.indexOf(className) > -1) { + el.className = el.className.replace(className, ''); + } +} +krumo.toggle = function(el) { + var ul = el.parentNode.getElementsByTagName('ul'); + for (var i=0; i{>MNZQ2fcl2vVs7B0y#^uvi&zD85|tBkOeW z{Wy-k_?HtGb*{^ry-)kirXt__^KIW(_0Qik-@s$b&#uFZg-*tp6`p)i%vBt +*/ + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +ul.krumo-node { + margin: 0px; + padding: 0px; + } +ul.krumo-node ul { + margin-left: 20px; + } +* html ul.krumo-node ul { + margin-left: 24px; + } +div.krumo-root { + border: solid 1px black; + margin: 1em 0em; + } +ul.krumo-first { + font: normal 12px arial; + border: solid 2px white; + border-top-width:1px; + background: url(%url%bg.gif); + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-child { + display:block; + list-style: none; + padding: 0px; + margin: 0px; + overflow:hidden; + } +div.krumo-element { + cursor:default; + + line-height: 24px; + display:block; + + clear:both; + white-space:nowrap; + + border-top: solid 1px white; + background: #BFDFFF; + padding-left: 10px; + } +* html div.krumo-element { + padding-bottom: 3px; + } +a.krumo-name { + color:navy; + font: bold 13px Arial; + } +a.krumo-name big { + font: bold 20pt Georgia; + line-height: 14px; + position:relative; + top:2px; + left:-2px; + } +* html a.krumo-name big { + font: bold 19pt Georgia; + top: 5px; + left: 0px; + line-height: 9px; + height: 12px; + padding: 0px; + margin: 0px; + } +div.krumo-expand { + background: #AAD5FF; + cursor:pointer; + } +div.krumo-hover { + background: #FFBE7D; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-preview { + font: normal 13px courier new; + padding: 5px 5px 14px 5px; + background: white; + border-top: 0px; + overflow:auto; + } +* html div.krumo-preview { + padding-top: 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-footnote { + background:white; + padding: 2px 5px; + list-style:none; + border-top: solid 1px #bebebe; + margin-top:2px; + cursor:default; + } +* html li.krumo-footnote { + line-height: 13px; + } +div.krumo-version { + float:right; + } +li.krumo-footnote h6 { + font: bold 11px verdana; + margin: 0px; + padding: 0px; + color:navy; + display:inline; + } +* html li.krumo-footnote h6 { + margin-right: 3px; + } +li.krumo-footnote a { + font: bold 10px arial; + color: #434343; + text-decoration:none; + } +li.krumo-footnote a:hover { + color:black; + } + +li.krumo-footnote span.krumo-call { + font:normal 11px verdana; + position: relative; + top: 1px; + } +li.krumo-footnote span.krumo-call code { + font-weight:bold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-title { + font: normal 11px verdana ; + position:relative; + top:9px; + cursor:default; + line-height:2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +strong.krumo-array-length, +strong.krumo-string-length { + font-weight: normal; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ diff --git a/gulliver/thirdparty/krumo/skins/default/bg.gif b/gulliver/thirdparty/krumo/skins/default/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..fee4763e77bb256fa39a512338ff9dbd05385ec8 GIT binary patch literal 141 zcmZ?wbhEHbjAGzq*v!E2|NsBfr%yk5@`Qmnp!k!85u{QFM1ag-V6igbP<*-ON7m`$ z`*9q7@h>MX>RgvKd!P23O+~)<=i9!o>Yu-7zJbSv literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/skins/default/skin.css b/gulliver/thirdparty/krumo/skins/default/skin.css new file mode 100644 index 000000000..4c14dbd51 --- /dev/null +++ b/gulliver/thirdparty/krumo/skins/default/skin.css @@ -0,0 +1,158 @@ +/** +* Krumo Default Skin +* +* @version $Id: skin.css 6 2007-06-16 06:37:27Z mrasnika $ +* @author Kaloyan K. Tsvetkov +*/ + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +ul.krumo-node { + margin: 0px; + padding: 0px; + } +ul.krumo-node ul { + margin-left: 20px; + } +* html ul.krumo-node ul { + margin-left: 24px; + } +div.krumo-root { + border: solid 1px black; + margin: 1em 0em; + } +ul.krumo-first { + font: normal 12px arial; + border: solid 2px white; + border-top-width:1px; + background: url(%url%bg.gif); + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-child { + display:block; + list-style: none; + padding: 0px; + margin: 0px; + overflow:hidden; + } +div.krumo-element { + cursor:default; + + line-height: 24px; + display:block; + + clear:both; + white-space:nowrap; + + border-top: solid 1px white; + background: #E8E8E8; + padding-left: 10px; + } +* html div.krumo-element { + padding-bottom: 3px; + } +a.krumo-name { + color:#2C5858; + font: bold 13px Arial; + } +a.krumo-name big { + font: bold 20pt Georgia; + line-height: 14px; + position:relative; + top:2px; + left:-2px; + } +* html a.krumo-name big { + font: bold 19pt Georgia; + top: 5px; + left: 0px; + line-height: 9px; + height: 12px; + padding: 0px; + margin: 0px; + } +div.krumo-expand { + background: #CCCCCC; + cursor:pointer; + } +div.krumo-hover { + background: #B7DBDB; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-preview { + font: normal 13px courier new; + padding: 5px 5px 14px 5px; + background: white; + border-top: 0px; + overflow:auto; + } +* html div.krumo-preview { + padding-top: 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-footnote { + background:white; + padding: 2px 5px; + list-style:none; + border-top: solid 1px #bebebe; + margin-top:2px; + cursor:default; + } +* html li.krumo-footnote { + line-height: 13px; + } +div.krumo-version { + float:right; + } +li.krumo-footnote h6 { + font: bold 11px verdana; + margin: 0px; + padding: 0px; + color:#366D6D; + display:inline; + } +* html li.krumo-footnote h6 { + margin-right: 3px; + } +li.krumo-footnote a { + font: bold 10px arial; + color: #434343; + text-decoration:none; + } +li.krumo-footnote a:hover { + color:black; + } + +li.krumo-footnote span.krumo-call { + font:normal 11px verdana; + position: relative; + top: 1px; + } +li.krumo-footnote span.krumo-call code { + font-weight:bold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-title { + font: normal 11px verdana ; + position:relative; + top:9px; + cursor:default; + line-height:2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +strong.krumo-array-length, +strong.krumo-string-length { + font-weight: normal; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ diff --git a/gulliver/thirdparty/krumo/skins/green/bg.gif b/gulliver/thirdparty/krumo/skins/green/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..aa4e75ec1636ec9332fe79436b641ac71b89604c GIT binary patch literal 141 zcmZ?wbhEHbjAGzq*v!E2|Nno6GzNx^3`7FOpDc_Zr8*!2WCjC^RX~fv%QZi;P8Z*g z +*/ + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +ul.krumo-node { + margin: 0px; + padding: 0px; + } +ul.krumo-node ul { + margin-left: 20px; + } +* html ul.krumo-node ul { + margin-left: 24px; + } +div.krumo-root { + border: solid 1px black; + margin: 1em 0em; + } +ul.krumo-first { + font: normal 12px arial; + border: solid 2px white; + border-top-width:1px; + background: url(%url%bg.gif); + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-child { + display:block; + list-style: none; + padding: 0px; + margin: 0px; + overflow:hidden; + } +div.krumo-element { + cursor:default; + + line-height: 24px; + display:block; + + clear:both; + white-space:nowrap; + + border-top: solid 1px white; + background: #D7F4CA; + padding-left: 10px; + } +* html div.krumo-element { + padding-bottom: 3px; + } +a.krumo-name { + color:#004000; + font: bold 13px Arial; + } +a.krumo-name big { + font: bold 20pt Georgia; + line-height: 14px; + position:relative; + top:2px; + left:-2px; + } +* html a.krumo-name big { + font: bold 19pt Georgia; + top: 5px; + left: 0px; + line-height: 9px; + height: 12px; + padding: 0px; + margin: 0px; + } +div.krumo-expand { + background: #C0EEAC; + cursor:pointer; + } +div.krumo-hover { + background: gold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-preview { + font: normal 13px courier new; + padding: 5px 5px 14px 5px; + background: white; + border-top: 0px; + overflow:auto; + } +* html div.krumo-preview { + padding-top: 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-footnote { + background:white; + padding: 2px 5px; + list-style:none; + border-top: solid 1px #bebebe; + margin-top:2px; + cursor:default; + } +* html li.krumo-footnote { + line-height: 13px; + } +div.krumo-version { + float:right; + } +li.krumo-footnote h6 { + font: bold 11px verdana; + margin: 0px; + padding: 0px; + color:#008040; + display:inline; + } +* html li.krumo-footnote h6 { + margin-right: 3px; + } +li.krumo-footnote a { + font: bold 10px arial; + color: #434343; + text-decoration:none; + } +li.krumo-footnote a:hover { + color:black; + } + +li.krumo-footnote span.krumo-call { + font:normal 11px verdana; + position: relative; + top: 1px; + } +li.krumo-footnote span.krumo-call code { + font-weight:bold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-title { + font: normal 11px verdana ; + position:relative; + top:9px; + cursor:default; + line-height:2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +strong.krumo-array-length, +strong.krumo-string-length { + font-weight: normal; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ diff --git a/gulliver/thirdparty/krumo/skins/orange/bg.gif b/gulliver/thirdparty/krumo/skins/orange/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..3c71bc9209545a1cca8caed84caac180ac84ce36 GIT binary patch literal 141 zcmZ?wbhEHbjAGzq*v!E29|-m{{J+OQBvAax!U$5T10q0XFtAt!v?#n>^CRnY@%=cC zzWA3D7j>@7n!Qi^&88yX`}1wzSM|@|GvB~t%g?UEi-k_cm=&IUQOs2wwKUwDg~1vC DGv+E? literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/skins/orange/skin.css b/gulliver/thirdparty/krumo/skins/orange/skin.css new file mode 100644 index 000000000..779ad08e3 --- /dev/null +++ b/gulliver/thirdparty/krumo/skins/orange/skin.css @@ -0,0 +1,158 @@ +/** +* Krumo "Orange" Skin +* +* @version $Id: skin.css 6 2007-06-16 06:37:27Z mrasnika $ +* @author Kaloyan K. Tsvetkov +*/ + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +ul.krumo-node { + margin: 0px; + padding: 0px; + } +ul.krumo-node ul { + margin-left: 20px; + } +* html ul.krumo-node ul { + margin-left: 24px; + } +div.krumo-root { + border: solid 1px black; + margin: 1em 0em; + } +ul.krumo-first { + font: normal 12px arial; + border: solid 2px white; + border-top-width:1px; + background: url(%url%bg.gif); + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-child { + display:block; + list-style: none; + padding: 0px; + margin: 0px; + overflow:hidden; + } +div.krumo-element { + cursor:default; + + line-height: 24px; + display:block; + + clear:both; + white-space:nowrap; + + border-top: solid 1px white; + background: #FCEBA9; + padding-left: 10px; + } +* html div.krumo-element { + padding-bottom: 3px; + } +a.krumo-name { + color:#404000; + font: bold 13px Arial; + } +a.krumo-name big { + font: bold 20pt Georgia; + line-height: 14px; + position:relative; + top:2px; + left:-2px; + } +* html a.krumo-name big { + font: bold 19pt Georgia; + top: 5px; + left: 0px; + line-height: 9px; + height: 12px; + padding: 0px; + margin: 0px; + } +div.krumo-expand { + background: #FADB61; + cursor:pointer; + } +div.krumo-hover { + background: #FF8A4B; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-preview { + font: normal 13px courier new; + padding: 5px 5px 14px 5px; + background: white; + border-top: 0px; + overflow:auto; + } +* html div.krumo-preview { + padding-top: 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-footnote { + background:white; + padding: 2px 5px; + list-style:none; + border-top: solid 1px #bebebe; + margin-top:2px; + cursor:default; + } +* html li.krumo-footnote { + line-height: 13px; + } +div.krumo-version { + float:right; + } +li.krumo-footnote h6 { + font: bold 11px verdana; + margin: 0px; + padding: 0px; + color:#E87400; + display:inline; + } +* html li.krumo-footnote h6 { + margin-right: 3px; + } +li.krumo-footnote a { + font: bold 10px arial; + color: #434343; + text-decoration:none; + } +li.krumo-footnote a:hover { + color:black; + } + +li.krumo-footnote span.krumo-call { + font:normal 11px verdana; + position: relative; + top: 1px; + } +li.krumo-footnote span.krumo-call code { + font-weight:bold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-title { + font: normal 11px verdana ; + position:relative; + top:9px; + cursor:default; + line-height:2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +strong.krumo-array-length, +strong.krumo-string-length { + font-weight: normal; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ diff --git a/gulliver/thirdparty/krumo/skins/schablon.com/collapsed.gif b/gulliver/thirdparty/krumo/skins/schablon.com/collapsed.gif new file mode 100644 index 0000000000000000000000000000000000000000..c1a4e7d5f7254b0cde1c912aad7a114305432b14 GIT binary patch literal 102 zcmZ?wbhEHb- NC>7Z>oy~>88UTeX5|sb| literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/krumo/skins/schablon.com/dotted.gif b/gulliver/thirdparty/krumo/skins/schablon.com/dotted.gif new file mode 100644 index 0000000000000000000000000000000000000000..e009cf1ead6fdd6bf974f4173b9bc2d30ee2675e GIT binary patch literal 91 zcmZ?wbhEHb +*/ + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +ul.krumo-node { + margin: 0px; + padding: 0px; + background-color: white; + } +ul.krumo-node ul { + margin-left: 20px; + } +* html ul.krumo-node ul { + margin-left: 24px; + } +div.krumo-root { + border: solid 1px black; + margin: 1em 0em; + text-align: left; + } +ul.krumo-first { + font: normal 11px tahoma, verdana; + border: solid 1px white; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-child { + display:block; + list-style: none; + padding: 0px; + margin: 0px; + overflow:hidden; + } +div.krumo-element { + cursor:default; + display:block; + clear:both; + white-space:nowrap; + + background-color: white; + background-image: url(%url%empty.gif); + background-repeat: no-repeat; + background-position: 6px 5px; + padding: 2px 0px 3px 20px; + } +* html div.krumo-element { + padding-bottom: 3px; + line-height: 13px; + } +div.krumo-expand { + background-image: url(%url%collapsed.gif); + cursor:pointer; + } +div.krumo-hover { + background-color: #BFDFFF; + } +div.krumo-opened { + background-image: url(%url%expanded.gif); + } +a.krumo-name { + color:navy; + font: bold 13px courier new; + line-height:12px; + } +a.krumo-name big { + font: bold 16pt Georgia; + line-height: 10px; + position:relative; + top:2px; + left:-2px; + } +* html a.krumo-name big { + font: bold 15pt Georgia; + float:left; + top: -5px; + left: 0px; + padding: 0px; + margin: 0px; + } +em.krumo-type { + font-style:normal; + margin: 0px 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-preview { + font: normal 13px courier new; + padding: 5px ; + background: lightyellow; + border: solid 1px #808000; + overflow:auto; + margin: 5px 1em 1em 0px; + } +* html div.krumo-preview { + padding-top: 2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +li.krumo-footnote { + background: white url(%url%dotted.gif) repeat-x; + padding: 4px 5px 3px 5px; + list-style:none; + cursor:default; + } +* html li.krumo-footnote { + line-height: 13px; + } +div.krumo-version { + float:right; + } +li.krumo-footnote h6 { + font: bold 11px verdana; + margin: 0px; + padding: 0px; + color:navy; + display:inline; + } +* html li.krumo-footnote h6 { + margin-right: 3px; + } +li.krumo-footnote a { + font: bold 10px arial; + color: #434343; + text-decoration:none; + } +li.krumo-footnote a:hover { + color:black; + } + + +li.krumo-footnote span.krumo-call { + font:normal 11px tahoma, verdana; + position: relative; + top: 1px; + } +li.krumo-footnote span.krumo-call code { + font-weight:bold; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +div.krumo-title { + font: normal 11px tahoma, verdana; + position:relative; + top:9px; + cursor:default; + line-height:2px; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ + +strong.krumo-array-length, +strong.krumo-string-length { + font-weight: normal; + color: #000099; + } + +/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ diff --git a/gulliver/thirdparty/libchart/COPYING b/gulliver/thirdparty/libchart/COPYING new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/gulliver/thirdparty/libchart/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/gulliver/thirdparty/libchart/ChangeLog b/gulliver/thirdparty/libchart/ChangeLog new file mode 100644 index 000000000..78e4be8a7 --- /dev/null +++ b/gulliver/thirdparty/libchart/ChangeLog @@ -0,0 +1,41 @@ +Libchart ChangeLog +================== +(C) 2005-2007 Jean-Marc Trémeaux + + +VERSION 1.2: (2007-08-13) +========== + LICENSE: + * Change of license to GPL v3 + + FEATURES: + * Multiple line charts + * Multiple vertical and horizontal bar charts + * Customizable layout (plot) + + REFACTORING: + * Support for PHP4 is deprecated, as PHP 4 has reached its end of life. + * Use of PHP5 OO constructs + * Use of setLowerBound(null) if you want to revert to the old behaviour. + + BUGFIXES: + * Removed undefined IMG_ARC_FILL constant + * Added missing default parameter in HorizontalChart::render() + * Fixed decimal values in Bar Charts + * Typo in default logo + * Crashed when no point was defined + * Crashed when all values were set to 0 + +Version 1.0: (2005-09-30) +========== + INITIAL RELEASE + diff --git a/gulliver/thirdparty/libchart/README b/gulliver/thirdparty/libchart/README new file mode 100644 index 000000000..a2e70c82d --- /dev/null +++ b/gulliver/thirdparty/libchart/README @@ -0,0 +1,46 @@ + + Libchart - Simple PHP chart drawing library +============================================= + +Libchart is a free chart creation PHP library, that is easy to use. + +-------------------------------------------------------------------------------- + + + Features +========== + + * Bar charts (horizontal or vertical). + * Pie charts. + * Compatibility with PHP 5. + +-------------------------------------------------------------------------------- + + + Dependencies +============== + + * PHP 5, compiled with: + * GD 2+ + * FreeType 2+ + +-------------------------------------------------------------------------------- + + + Installation +============== + +In order to use Libchart, unpack the archive in you project directory and +include libchart.php. Please have a look at the demo files for more information. +You need to chmod 777 the "generated" directory in order to generate the demos. +There is also a tutorial available at the project homepage. + + +-------------------------------------------------------------------------------- + + + Contact info +============== + +WWW: http://naku.dohcrew.com/libchart/ +MAIL: jm.tremeaux at gmail dot com diff --git a/gulliver/thirdparty/libchart/classes/libchart.php b/gulliver/thirdparty/libchart/classes/libchart.php new file mode 100644 index 000000000..bcf3a8452 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/libchart.php @@ -0,0 +1,42 @@ +. + * + */ + + require_once 'model/Point.php'; + require_once 'model/DataSet.php'; + require_once 'model/XYDataSet.php'; + require_once 'model/XYSeriesDataSet.php'; + + require_once 'view/primitive/Padding.php'; + require_once 'view/primitive/Rectangle.php'; + require_once 'view/primitive/Primitive.php'; + require_once 'view/text/Text.php'; + require_once 'view/color/Color.php'; + require_once 'view/color/ColorSet.php'; + require_once 'view/color/Palette.php'; + require_once 'view/axis/Bound.php'; + require_once 'view/axis/Axis.php'; + require_once 'view/plot/Plot.php'; + require_once 'view/caption/Caption.php'; + require_once 'view/chart/Chart.php'; + require_once 'view/chart/BarChart.php'; + require_once 'view/chart/VerticalBarChart.php'; + require_once 'view/chart/HorizontalBarChart.php'; + require_once 'view/chart/LineChart.php'; + require_once 'view/chart/PieChart.php'; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/model/DataSet.php b/gulliver/thirdparty/libchart/classes/model/DataSet.php new file mode 100644 index 000000000..eaa6e0cd8 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/model/DataSet.php @@ -0,0 +1,28 @@ +. + * + */ + + /** + * Superclass of all data sets. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 10 may 2007 + */ + abstract class DataSet { + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/model/Point.php b/gulliver/thirdparty/libchart/classes/model/Point.php new file mode 100644 index 000000000..13ea383f5 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/model/Point.php @@ -0,0 +1,59 @@ +. + * + */ + + /** + * Point of coordinates (X,Y). + * The value of X isn't really of interest, but X is used as a label to display on the horizontal axis. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class Point { + private $x; + private $y; + + /** + * Creates a new sampling point of coordinates (x, y) + * + * @param integer x coordinate (label) + * @param integer y coordinate (value) + */ + public function Point($x, $y) { + $this->x = $x; + $this->y = $y; + } + + /** + * Gets the x coordinate (label). + * + * @return integer x coordinate (label) + */ + public function getX() { + return $this->x; + } + + /** + * Gets the y coordinate (value). + * + * @return integer y coordinate (value) + */ + public function getY() { + return $this->y; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/model/XYDataSet.php b/gulliver/thirdparty/libchart/classes/model/XYDataSet.php new file mode 100644 index 000000000..8e50eaa64 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/model/XYDataSet.php @@ -0,0 +1,56 @@ +. + * + */ + + /** + * Set of data in the form of (x, y) items. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 10 may 2007 + */ + class XYDataSet extends DataSet { + private $pointList; + + /** + * Constructor of XYDataSet. + * + */ + public function XYDataSet() { + $this->pointList = array(); + } + + /** + * Add a new point to the dataset. + * + * @param Point Point to add to the dataset + */ + + public function addPoint($point) { + array_push($this->pointList, $point); + } + + /** + * Getter of pointList. + * + * @return List of points. + */ + public function getPointList() { + return $this->pointList; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/model/XYSeriesDataSet.php b/gulliver/thirdparty/libchart/classes/model/XYSeriesDataSet.php new file mode 100644 index 000000000..80b721d73 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/model/XYSeriesDataSet.php @@ -0,0 +1,76 @@ +. + * + */ + + /** + * This dataset comprises several series of points and is used to plot multiple lines charts. + * Each serie is a XYDataSet. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 20 july 2007 + */ + class XYSeriesDataSet extends DataSet { + /** + * List of titles + */ + private $titleList; + + /** + * List of XYDataSet. + */ + private $serieList; + + /** + * Constructor of XYSeriesDataSet. + * + */ + public function XYSeriesDataSet() { + $this->titleList = array(); + $this->serieList = array(); + } + + /** + * Add a new serie to the dataset. + * + * @param string Title (label) of the serie. + * @param XYDataSet Serie of points to add + */ + public function addSerie($title, $serie) { + array_push($this->titleList, $title); + array_push($this->serieList, $serie); + } + + /** + * Getter of titleList. + * + * @return List of titles. + */ + public function getTitleList() { + return $this->titleList; + } + + /** + * Getter of serieList. + * + * @return List of series. + */ + public function getSerieList() { + return $this->serieList; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/axis/Axis.php b/gulliver/thirdparty/libchart/classes/view/axis/Axis.php new file mode 100644 index 000000000..617da73d5 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/axis/Axis.php @@ -0,0 +1,130 @@ +. + * + */ + + /** + * Automatic axis boundaries and ticks calibration + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class Axis { + private $min; + private $max; + private $guide; + private $delta; + private $magnitude; + private $displayMin; + private $displayMax; + private $tics; + + /** + * Creates a new axis formatter. + * + * @param integer minimum value on the axis + * @param integer maximum value on the axis + */ + public function Axis($min, $max) { + $this->min = $min; + $this->max = $max; + + $this->guide = 10; + } + + /** + * Computes value between two ticks. + */ + public function quantizeTics() { + // Approximate number of decades, in [1..10[ + $norm = $this->delta / $this->magnitude; + + // Approximate number of tics per decade + $posns = $this->guide / $norm; + + if ($posns > 20) { + $tics = 0.05; // e.g. 0, .05, .10, ... + } else if ($posns > 10) { + $tics = 0.2; // e.g. 0, .1, .2, ... + } else if ($posns > 5) { + $tics = 0.4; // e.g. 0, 0.2, 0.4, ... + } else if ($posns > 3) { + $tics = 0.5; // e.g. 0, 0.5, 1, ... + } else if ($posns > 2) { + $tics = 1; // e.g. 0, 1, 2, ... + } else if ($posns > 0.25) { + $tics = 2; // e.g. 0, 2, 4, 6 + } else { + $tics = ceil($norm); + } + + $this->tics = $tics * $this->magnitude; + } + + /** + * Computes automatic boundaries on the axis + */ + public function computeBoundaries() { + // Range + $this->delta = abs($this->max - $this->min); + + // Check for null distribution + if ($this->delta == 0) + $this->delta = 1; + + // Order of magnitude of range + $this->magnitude = pow(10, floor(log10($this->delta))); + + $this->quantizeTics(); + + $this->displayMin = floor($this->min / $this->tics) * $this->tics; + $this->displayMax = ceil($this->max / $this->tics) * $this->tics; + $this->displayDelta = $this->displayMax - $this->displayMin; + + // Check for null distribution + if ($this->displayDelta == 0) { + $this->displayDelta = 1; + } + } + + /** + * Get the lower boundary on the axis3 + * + * @return integer lower boundary on the axis + */ + public function getLowerBoundary() { + return $this->displayMin; + } + + /** + * Get the upper boundary on the axis3 + * + * @return integer upper boundary on the axis + */ + public function getUpperBoundary() { + return $this->displayMax; + } + + /** + * Get the value between two ticks3 + * + * @return integer value between two ticks + */ + public function getTics() { + return $this->tics; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/axis/Bound.php b/gulliver/thirdparty/libchart/classes/view/axis/Bound.php new file mode 100644 index 000000000..b5fd5919b --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/axis/Bound.php @@ -0,0 +1,146 @@ +. + * + */ + + /** + * Object representing the bounds of a dataset (its minimal and maximal values) on its vertical axis. + * The bounds are automatically calculated from a XYDataSet or XYSeriesDataSet. + * Default (calculated) bounds can be overriden using the setLowerBound() and setUpperBound() methods. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 25 july 2007 + */ + class Bound { + /** + * Manually set lower bound, overrides the value calculated by computeBound(). + */ + private $lowerBound = null; + + /** + * Manually set upper bound, overrides the value calculated by computeBound(). + */ + private $upperBound = null; + + /** + * Computed min bound. + */ + private $yMinValue = null; + + /** + * Computed max bound. + */ + private $yMaxValue = null; + + /** + * Compute the boundaries on the axis. + * + * @param dataSet The data set + */ + public function computeBound($dataSet) { + // Check if the data set is empty + $dataSetEmpty = true; + $serieList = null; + if ($dataSet instanceof XYDataSet) { + $pointList = $dataSet->getPointList(); + $dataSetEmpty = count($pointList) == 0; + + if (!$dataSetEmpty) { + // Process it as a serie + $serieList = array(); + array_push($serieList, $dataSet); + } + } else if ($dataSet instanceof XYSeriesDataSet) { + $serieList = $dataSet->getSerieList(); + if (count($serieList) > 0) { + $serie = current($serieList); + $dataSetEmpty = count($serie) == 0; + } + } else { + die("Error: unknown dataset type"); + } + + // If the dataset is empty, default some bounds + $yMin = 0; + $yMax = 1; + if (!$dataSetEmpty) { + // Compute lower and upper bound on the value axis + unset($yMin); + unset($yMax); + + foreach ($serieList as $serie) { + foreach ($serie->getPointList() as $point) { + $y = $point->getY(); + + if (!isset($yMin)) { + $yMin = $y; + $yMax = $y; + } else { + if ($y < $yMin) { + $yMin = $y; + } + + if ($y > $yMax) { + $yMax = $y; + } + } + } + } + } + + $this->yMinValue = isset($this->lowerBound) ? $this->lowerBound : $yMin; + $this->yMaxValue = isset($this->upperBound) ? $this->upperBound : $yMax; + } + + /** + * Getter of yMinValue. + * + * @return min bound + */ + public function getYMinValue() { + return $this->yMinValue; + } + + /** + * Getter of yMaxValue. + * + * @return max bound + */ + public function getYMaxValue() { + return $this->yMaxValue; + } + + /** + * Set manually the lower boundary value (overrides the automatic formatting). + * Typical usage is to set the bars starting from zero. + * + * @param double lower boundary value + */ + public function setLowerBound($lowerBound) { + $this->lowerBound = $lowerBound; + } + + /** + * Set manually the upper boundary value (overrides the automatic formatting). + * + * @param double upper boundary value + */ + public function setUpperBound($upperBound) { + $this->upperBound = $upperBound; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/caption/Caption.php b/gulliver/thirdparty/libchart/classes/view/caption/Caption.php new file mode 100644 index 000000000..a491f9b7d --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/caption/Caption.php @@ -0,0 +1,112 @@ +. + * + */ + + /** + * Caption. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 30 july 2007 + */ + class Caption { + protected $labelBoxWidth; + protected $labelBoxHeight; + + // Plot + protected $plot; + + // Label list + protected $labelList; + + // Color set + protected $colorSet; + + /** + * Constructor of Caption + */ + public function Caption() { + $this->labelBoxWidth = 15; + $this->labelBoxHeight = 15; + } + + /** + * Render the caption. + */ + public function render() { + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + $primitive = $this->plot->getPrimitive(); + + // Get the caption area + $captionArea = $this->plot->getCaptionArea(); + + // Get the pie color set + $colorSet = $this->colorSet; + $colorSet->reset(); + + $i = 0; + foreach ($this->labelList as $label) { + // Get the next color + $color = $colorSet->currentColor(); + $colorSet->next(); + + $boxX1 = $captionArea->x1; + $boxX2 = $boxX1 + $this->labelBoxWidth; + $boxY1 = $captionArea->y1 + 5 + $i * ($this->labelBoxHeight + 5); + $boxY2 = $boxY1 + $this->labelBoxHeight; + + $primitive->outlinedBox($boxX1, $boxY1, $boxX2, $boxY2, $palette->axisColor[0], $palette->axisColor[1]); + imagefilledrectangle($img, $boxX1 + 2, $boxY1 + 2, $boxX2 - 2, $boxY2 - 2, $color->getColor($img)); + + $text->printText($img, $boxX2 + 5, $boxY1 + $this->labelBoxHeight / 2, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->VERTICAL_CENTER_ALIGN); + + $i++; + } + } + + /** + * Sets the plot. + * + * @param Plot The plot + */ + public function setPlot($plot) { + $this->plot = $plot; + } + + /** + * Sets the label list. + * + * @param Array label list + */ + public function setLabelList($labelList) { + $this->labelList = $labelList; + } + + + /** + * Sets the color set. + * + * @param Array Color set + */ + public function setColorSet($colorSet) { + $this->colorSet = $colorSet; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/chart/BarChart.php b/gulliver/thirdparty/libchart/classes/view/chart/BarChart.php new file mode 100644 index 000000000..76755fb32 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/BarChart.php @@ -0,0 +1,174 @@ +. + * + */ + + /** + * Base abstract class for rendering both horizontal and vertical bar charts. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + abstract class BarChart extends Chart { + protected $bound; + protected $axis; + protected $hasSeveralSerie; + + /** + * Creates a new bar chart. + * + * @param integer width of the image + * @param integer height of the image + */ + protected function BarChart($width, $height) { + parent::Chart($width, $height); + + // Initialize the bounds + $this->bound = new Bound(); + $this->bound->setLowerBound(0); + } + + /** + * Compute the axis. + */ + protected function computeAxis() { + $this->axis = new Axis($this->bound->getYMinValue(), $this->bound->getYMaxValue()); + $this->axis->computeBoundaries(); + } + + /** + * Create the image. + */ + protected function createImage() { + parent::createImage(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + $primitive = $this->plot->getPrimitive(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Aqua-like background + for ($i = $graphArea->y1; $i < $graphArea->y2; $i++) { + $color = $palette->aquaColor[($i + 3) % 4]; + $primitive->line($graphArea->x1, $i, $graphArea->x2, $i, $color); + } + + // Axis + imagerectangle($img, $graphArea->x1 - 1, $graphArea->y1, $graphArea->x1, $graphArea->y2, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $graphArea->x1 - 1, $graphArea->y2, $graphArea->x2, $graphArea->y2 + 1, $palette->axisColor[0]->getColor($img)); + } + + /** + * Returns true if the data set has some data. + * @param minNumberOfPoint Minimum number of points (1 for bars, 2 for lines). + * + * @return true if data set empty + */ + protected function isEmptyDataSet($minNumberOfPoint) { + if ($this->dataSet instanceof XYDataSet) { + $pointList = $this->dataSet->getPointList(); + $pointCount = count($pointList); + return $pointCount < $minNumberOfPoint; + } else if ($this->dataSet instanceof XYSeriesDataSet) { + $serieList = $this->dataSet->getSerieList(); + reset($serieList); + if (count($serieList) > 0) { + $serie = current($serieList); + $pointList = $serie->getPointList(); + $pointCount = count($pointList); + return $pointCount < $minNumberOfPoint; + } + } else { + die("Error: unknown dataset type"); + } + } + + /** + * Checks the data model before rendering the graph. + */ + protected function checkDataModel() { + // Check if a dataset was defined + if (!$this->dataSet) { + die("Error: No dataset defined."); + } + + // Bar charts accept both XYDataSet and XYSeriesDataSet + if ($this->dataSet instanceof XYDataSet) { + // The dataset contains only one serie + $this->hasSeveralSerie = false; + } else if ($this->dataSet instanceof XYSeriesDataSet) { + // Check if each series has the same number of points + unset($lastPointCount); + $serieList = $this->dataSet->getSerieList(); + for ($i = 0; $i < count($serieList); $i++) { + $serie = $serieList[$i]; + $pointCount = count($serie->getPointList()); + if (isset($lastPointCount) && $pointCount != $lastPointCount) { + die("Error: serie <" . $i . "> doesn't have the same number of points as last serie (last one: <" . $lastPointCount. ">, this one: <" . $pointCount. ">)."); + } + $lastPointCount = $pointCount; + } + + // The dataset contains several series + $this->hasSeveralSerie = true; + } else { + die("Error: Bar chart accept only XYDataSet and XYSeriesDataSet"); + } + } + + /** + * Return the data as a series list (for consistency). + * + * @return List of series + */ + protected function getDataAsSerieList() { + // Get the data as a series list + $serieList = null; + if ($this->dataSet instanceof XYSeriesDataSet) { + $serieList = $this->dataSet->getSerieList(); + } else if ($this->dataSet instanceof XYDataSet) { + $serieList = array(); + array_push($serieList, $this->dataSet); + } + + return $serieList; + } + + /** + * Return the first serie of the list, or the dataSet itself if there is no serie. + * + * @return XYDataSet + */ + protected function getFirstSerieOfList() { + $pointList = null; + if ($this->dataSet instanceof XYSeriesDataSet) { + // For a series dataset, print the legend from the first serie + $serieList = $this->dataSet->getSerieList(); + reset($serieList); + $serie = current($serieList); + $pointList = $serie->getPointList(); + } else if ($this->dataSet instanceof XYDataSet) { + $pointList = $this->dataSet->getPointList(); + } + + return $pointList; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/chart/Chart.php b/gulliver/thirdparty/libchart/classes/view/chart/Chart.php new file mode 100644 index 000000000..68c7ab7e3 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/Chart.php @@ -0,0 +1,102 @@ +. + * + */ + + /*! \mainpage Libchart + * + * This is the reference API, automatically compiled by Doxygen. + * You can find here information that is not covered by the tutorial. + * + */ + + /** + * Base chart class. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + abstract class Chart { + /** + * The data set. + */ + protected $dataSet; + + /** + * Plot (holds graphical attributes). + */ + protected $plot; + + /** + * Abstract constructor of Chart. + * + * @param integer width of the image + * @param integer height of the image + */ + protected function Chart($width, $height) { + // Creates the plot + $this->plot = new Plot($width, $height); + $this->plot->setTitle("Untitled chart"); + $this->plot->setLogoFileName(dirname(__FILE__) . "/../../../images/PoweredBy.png"); + } + + /** + * Checks the data model before rendering the graph. + */ + protected function checkDataModel() { + // Check if a dataset was defined + if (!$this->dataSet) { + die("Error: No dataset defined."); + } + + // Maybe no points are defined, but that's ok. This will yield and empty graph with default boundaries. + } + + /** + * Create the image. + */ + protected function createImage() { + $this->plot->createImage(); + } + + /** + * Sets the data set. + * + * @param DataSet The data set + */ + public function setDataSet($dataSet) { + $this->dataSet = $dataSet; + } + + /** + * Return the plot. + * + * @return plot + */ + public function getPlot() { + return $this->plot; + } + + /** + * Sets the title. + * + * @param string New title + */ + public function setTitle($title) { + $this->plot->setTitle($title); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/chart/HorizontalBarChart.php b/gulliver/thirdparty/libchart/classes/view/chart/HorizontalBarChart.php new file mode 100644 index 000000000..a95128eb6 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/HorizontalBarChart.php @@ -0,0 +1,213 @@ +. + * + */ + + /** + * Horizontal bar chart + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class HorizontalBarChart extends BarChart { + /** + * Ratio of empty space beside the bars. + */ + private $emptyToFullRatio; + + /** + * Creates a new horizontal bar chart. + * + * @param integer width of the image + * @param integer height of the image + */ + public function HorizontalBarChart($width = 600, $height = 250) { + parent::BarChart($width, $height); + + $this->emptyToFullRatio = 1 / 5; + //$this->plot->setGraphPadding(new Padding(5, 30, 30, 50)); + $this->plot->setGraphPadding(new Padding(-20, 5, 30, 60)); + } + + /** + * Computes the layout. + */ + protected function computeLayout() { + if ($this->hasSeveralSerie) { + $this->plot->setHasCaption(true); + } + $this->plot->computeLayout(); + } + + /** + * Print the axis. + */ + protected function printAxis() { + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + $stepValue = $this->axis->getTics(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Horizontal axis + for ($value = $minValue; $value <= $maxValue; $value += $stepValue) { + $x = $graphArea->x1 + ($value - $minValue) * ($graphArea->x2 - $graphArea->x1) / ($this->axis->displayDelta); + + imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img)); + + $text->printText($img, $x, $graphArea->y2 + 5, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN); + } + + // Get first serie of a list + $pointList = $this->getFirstSerieOfList(); + + // Vertical Axis + $pointCount = count($pointList); + reset($pointList); + $rowHeight = ($graphArea->y2 - $graphArea->y1) / $pointCount; + reset($pointList); + for ($i = 0; $i <= $pointCount; $i++) { + $y = $graphArea->y2 - $i * $rowHeight; + + imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img)); + + if ($i < $pointCount) { + $point = current($pointList); + next($pointList); + + $label = $point->getX(); + + $text->printText($img, $graphArea->x1 - 5, $y - $rowHeight / 2, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN); + } + } + } + + /** + * Print the bars. + */ + protected function printBar() { + // Get the data as a list of series for consistency + $serieList = $this->getDataAsSerieList(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + $stepValue = $this->axis->getTics(); + + $barColorSet = $palette->barColorSet; + $barColorSet->reset(); + + $serieCount = count($serieList); + for ($j = 0; $j < $serieCount; $j++) { + $serie = $serieList[$j]; + $pointList = $serie->getPointList(); + $pointCount = count($pointList); + reset($pointList); + + // Get the next color + $color = $barColorSet->currentColor(); + $shadowColor = $barColorSet->currentShadowColor(); + $barColorSet->next(); + + $rowHeight = ($graphArea->y2 - $graphArea->y1) / $pointCount; + for ($i = 0; $i < $pointCount; $i++) { + $y = $graphArea->y2 - $i * $rowHeight; + + $point = current($pointList); + next($pointList); + + $value = $point->getY(); + + $xmax = $graphArea->x1 + ($value - $minValue) * ($graphArea->x2 - $graphArea->x1) / ($this->axis->displayDelta); + + // Bar dimensions + $yWithMargin = $y - $rowHeight * $this->emptyToFullRatio; + $rowWidthWithMargin = $rowHeight * (1 - $this->emptyToFullRatio * 2); + $barWidth = $rowWidthWithMargin / $serieCount; + $barOffset = $barWidth * $j; + $y1 = $yWithMargin - $barWidth - $barOffset; + $y2 = $yWithMargin - $barOffset - 1; + + // Text + $text->printText($img, $xmax + 5, $y2 - $barWidth / 2, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->VERTICAL_CENTER_ALIGN); + + imagefilledrectangle($img, $graphArea->x1 + 1, $y1, $xmax, $y2, $shadowColor->getColor($img)); + imagefilledrectangle($img, $graphArea->x1 + 2, $y1 + 1, $xmax - 4, $y2, $color->getColor($img)); + } + } + } + + /** + * Renders the caption. + */ + protected function printCaption() { + // Get the list of labels + $labelList = $this->dataSet->getTitleList(); + + // Create the caption + $caption = new Caption(); + $caption->setPlot($this->plot); + $caption->setLabelList($labelList); + + $palette = $this->plot->getPalette(); + $barColorSet = $palette->barColorSet; + $caption->setColorSet($barColorSet); + + // Render the caption + $caption->render(); + } + + /** + * Render the chart image. + * + * @param string name of the file to render the image to (optional) + */ + public function render($fileName = null) { + // Check the data model + $this->checkDataModel(); + + $this->bound->computeBound($this->dataSet); + $this->computeAxis(); + $this->computeLayout(); + $this->createImage(); + //$this->plot->printLogo(); + if (!$this->isEmptyDataSet(1)) { + $this->printAxis(); + $this->printBar(); + if ($this->hasSeveralSerie) { + $this->printCaption(); + } + } + + $this->plot->render($fileName); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/chart/LineChart.php b/gulliver/thirdparty/libchart/classes/view/chart/LineChart.php new file mode 100644 index 000000000..a1c211579 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/LineChart.php @@ -0,0 +1,201 @@ +. + * + */ + + /** + * Line chart. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class LineChart extends BarChart { + /** + * Creates a new line chart. + * Line charts allow for XYDataSet and XYSeriesDataSet in order to plot several lines. + * + * @param integer width of the image + * @param integer height of the image + */ + public function LineChart($width = 600, $height = 250) { + parent::BarChart($width, $height); + + //$this->plot->setGraphPadding(new Padding(5, 30, 50, 50)); + $this->plot->setGraphPadding(new Padding(-10, 5, 50, 40)); + } + + /** + * Computes the layout. + */ + protected function computeLayout() { + if ($this->hasSeveralSerie) { + $this->plot->setHasCaption(true); + } + $this->plot->computeLayout(); + } + + /** + * Print the axis. + */ + protected function printAxis() { + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + $stepValue = $this->axis->getTics(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Vertical axis + for ($value = $minValue; $value <= $maxValue; $value += $stepValue) { + $y = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta); + + imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img)); + + $text->printText($img, $graphArea->x1 - 5, $y, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN); + } + + // Get first serie of a list + $pointList = $this->getFirstSerieOfList(); + + // Horizontal Axis + $pointCount = count($pointList); + reset($pointList); + $columnWidth = ($graphArea->x2 - $graphArea->x1) / ($pointCount - 1); + + for ($i = 0; $i < $pointCount; $i++) { + $x = $graphArea->x1 + $i * $columnWidth; + + imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img)); + + $point = current($pointList); + next($pointList); + + $label = $point->getX(); + + $text->printDiagonal($img, $x - 5, $graphArea->y2 + 10, $this->plot->getTextColor(), $label); + } + } + + /** + * Print the lines. + */ + protected function printLine() { + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + + // Get the data as a list of series for consistency + $serieList = $this->getDataAsSerieList(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + $primitive = $this->plot->getPrimitive(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + $lineColorSet = $palette->lineColorSet; + $lineColorSet->reset(); + for ($j = 0; $j < count($serieList); $j++) { + $serie = $serieList[$j]; + $pointList = $serie->getPointList(); + $pointCount = count($pointList); + reset($pointList); + + $columnWidth = ($graphArea->x2 - $graphArea->x1) / ($pointCount - 1); + + $lineColor = $lineColorSet->currentColor(); + $lineColorShadow = $lineColorSet->currentShadowColor(); + $lineColorSet->next(); + $x1 = null; + $y1 = null; + for ($i = 0; $i < $pointCount; $i++) { + $x2 = $graphArea->x1 + $i * $columnWidth; + + $point = current($pointList); + next($pointList); + + $value = $point->getY(); + + $y2 = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta); + + // Draw line + if ($x1) { + $primitive->line($x1, $y1, $x2, $y2, $lineColor, 4); + $primitive->line($x1, $y1 - 1, $x2, $y2 - 1, $lineColorShadow, 2); + } + + $x1 = $x2; + $y1 = $y2; + } + } + } + + /** + * Renders the caption. + */ + protected function printCaption() { + // Get the list of labels + $labelList = $this->dataSet->getTitleList(); + + // Create the caption + $caption = new Caption(); + $caption->setPlot($this->plot); + $caption->setLabelList($labelList); + + $palette = $this->plot->getPalette(); + $lineColorSet = $palette->lineColorSet; + $caption->setColorSet($lineColorSet); + + // Render the caption + $caption->render(); + } + + /** + * Render the chart image. + * + * @param string name of the file to render the image to (optional) + */ + public function render($fileName = null) { + // Check the data model + $this->checkDataModel(); + + $this->bound->computeBound($this->dataSet); + $this->computeAxis(); + $this->computeLayout(); + $this->createImage(); + //$this->plot->printLogo(); + //$this->plot->printTitle(); + if (!$this->isEmptyDataSet(2)) { + $this->printAxis(); + $this->printLine(); + if ($this->hasSeveralSerie) { + $this->printCaption(); + } + } + + $this->plot->render($fileName); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/chart/PieChart.php b/gulliver/thirdparty/libchart/classes/view/chart/PieChart.php new file mode 100644 index 000000000..33938394c --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/PieChart.php @@ -0,0 +1,253 @@ +. + * + */ + + /** + * Pie chart. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class PieChart extends Chart { + protected $pieCenterX; + protected $pieCenterY; + + /** + * Constructor of a pie chart. + * + * @param integer width of the image + * @param integer height of the image + */ + public function PieChart($width = 600, $height = 250) { + parent::Chart($width, $height); + $this->plot->setGraphPadding(new Padding( -30, 1, 1, 1 )); + } + + /** + * Computes the layout. + */ + protected function computeLayout() { + $this->plot->setHasCaption(true); + $this->plot->computeLayout(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Compute the coordinates of the pie + $this->pieCenterX = $graphArea->x1 + ($graphArea->x2 - $graphArea->x1) / 2; + $this->pieCenterY = $graphArea->y1 + ($graphArea->y2 - $graphArea->y1) / 2; + + $this->pieWidth = round(($graphArea->x2 - $graphArea->x1) * 4 / 5); + $this->pieHeight = round(($graphArea->y2 - $graphArea->y1) * 3.7 / 5); + $this->pieDepth = round($this->pieWidth * 0.05); + } + + /** + * Compare two sampling point values, order from biggest to lowest value. + * + * @param double first value + * @param double second value + * @return integer result of the comparison + */ + protected function sortPie($v1, $v2) { + return $v1[0] == $v2[0] ? 0 : + $v1[0] > $v2[0] ? -1 : + 1; + } + + /** + * Compute pie values in percentage and sort them. + */ + protected function computePercent() { + $this->total = 0; + $this->percent = array(); + + $pointList = $this->dataSet->getPointList(); + foreach ($pointList as $point) { + $this->total += $point->getY(); + } + + foreach ($pointList as $point) { + $percent = $this->total == 0 ? 0 : 100 * $point->getY() / $this->total; + + array_push($this->percent, array($percent, $point)); + } + + usort($this->percent, array("PieChart", "sortPie")); + } + + /** + * Creates the pie chart image. + */ + protected function createImage() { + parent::createImage(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $primitive = $this->plot->getPrimitive(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Legend box + $primitive->outlinedBox($graphArea->x1, $graphArea->y1, $graphArea->x2, $graphArea->y2, $palette->axisColor[0], $palette->axisColor[1]); + + // Aqua-like background + for ($i = $graphArea->y1 + 2; $i < $graphArea->y2 - 1; $i++) { + $color = $palette->aquaColor[($i + 3) % 4]; + $primitive->line($graphArea->x1 + 2, $i, $graphArea->x2 - 2, $i, $color); + } + } + + /** + * Renders the caption. + */ + protected function printCaption() { + // Create a list of labels + $labelList = array(); + foreach($this->percent as $percent) { + list($percent, $point) = $percent; + $label = $point->getX(); + + array_push($labelList, $label); + } + + // Create the caption + $caption = new Caption(); + $caption->setPlot($this->plot); + $caption->setLabelList($labelList); + + $palette = $this->plot->getPalette(); + $pieColorSet = $palette->pieColorSet; + $caption->setColorSet($pieColorSet); + + // Render the caption + $caption->render(); + } + + /** + * Draw a 2D disc. + * + * @param integer center coordinate (y) + * @param array colors for each portion + * @param bitfield drawing mode + */ + protected function drawDisc($cy, $colorArray, $mode) { + // Get graphical obects + $img = $this->plot->getImg(); + + $i = 0; + $angle1 = 0; + $percentTotal = 0; + + foreach ($this->percent as $a) { + list ($percent, $point) = $a; + + $color = $colorArray[$i % count($colorArray)]; + + $percentTotal += $percent; + $angle2 = $percentTotal * 360 / 100; + + imagefilledarc($img, $this->pieCenterX, $cy, $this->pieWidth, $this->pieHeight, $angle1, $angle2, $color->getColor($img), $mode); + + $angle1 = $angle2; + + $i++; + } + } + + /** + * Print the percentage text. + */ + protected function drawPercent() { + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + $primitive = $this->plot->getPrimitive(); + + $angle1 = 0; + $percentTotal = 0; + + foreach ($this->percent as $a) { + list ($percent, $point) = $a; + + // If value is null, don't print percentage + if ($percent <= 0) { + continue; + } + + $percentTotal += $percent; + $angle2 = $percentTotal * 2 * M_PI / 100; + + $angle = $angle1 + ($angle2 - $angle1) / 2; + $label = number_format($percent) . "%"; + + $x = cos($angle) * ($this->pieWidth + 35) / 2 + $this->pieCenterX; + $y = sin($angle) * ($this->pieHeight + 35) / 2 + $this->pieCenterY; + + $text->printText($img, $x, $y, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN | $text->VERTICAL_CENTER_ALIGN); + + $angle1 = $angle2; + } + } + + /** + * Print the pie chart. + */ + protected function printPie() { + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + $primitive = $this->plot->getPrimitive(); + + // Get the pie color set + $pieColorSet = $palette->pieColorSet; + $pieColorSet->reset(); + + // Silhouette + for ($cy = $this->pieCenterY + $this->pieDepth / 2; $cy >= $this->pieCenterY - $this->pieDepth / 2; $cy--) { + $this->drawDisc($cy, $palette->pieColorSet->shadowColorList, IMG_ARC_EDGED); + } + + // Top + $this->drawDisc($this->pieCenterY - $this->pieDepth / 2, $palette->pieColorSet->colorList, IMG_ARC_PIE); + + // Top Outline + $this->drawPercent(); + } + + /** + * Render the chart image. + * + * @param string name of the file to render the image to (optional) + */ + public function render($fileName = null) { + $this->computePercent(); + $this->computeLayout(); + $this->createImage(); + //$this->plot->printLogo(); + //$this->plot->printTitle(); + $this->printPie(); + $this->printCaption(); + + $this->plot->render($fileName); + } + } +?> diff --git a/gulliver/thirdparty/libchart/classes/view/chart/VerticalBarChart.php b/gulliver/thirdparty/libchart/classes/view/chart/VerticalBarChart.php new file mode 100644 index 000000000..7c5090e9f --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/chart/VerticalBarChart.php @@ -0,0 +1,213 @@ +. + * + */ + + /** + * Chart composed of vertical bars. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class VerticalBarChart extends BarChart { + /** + * Ratio of empty space beside the bars. + */ + private $emptyToFullRatio; + + /** + * Creates a new vertical bar chart + * + * @param integer width of the image + * @param integer height of the image + */ + public function VerticalBarChart($width = 600, $height = 250) { + parent::BarChart($width, $height); + + $this->emptyToFullRatio = 1 / 4; + $this->plot->setGraphPadding(new Padding(-10, 5, 70, 45)); + } + + /** + * Computes the layout. + */ + protected function computeLayout() { + if ($this->hasSeveralSerie) { + $this->plot->setHasCaption(true); + } + $this->plot->computeLayout(); + } + + /** + * Print the horizontal and veritcal axis. + */ + protected function printAxis() { + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + $stepValue = $this->axis->getTics(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + // Vertical axis + for ($value = $minValue; $value <= $maxValue; $value += $stepValue) { + $y = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta); + + imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img)); + + $text->printText($img, $graphArea->x1 - 5, $y, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN); + } + + // Get first serie of a list + $pointList = $this->getFirstSerieOfList(); + + // Horizontal Axis + $pointCount = count($pointList); + reset($pointList); + $columnWidth = ($graphArea->x2 - $graphArea->x1) / $pointCount; + for ($i = 0; $i <= $pointCount; $i++) { + $x = $graphArea->x1 + $i * $columnWidth; + + imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img)); + imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img)); + + if ($i < $pointCount) { + $point = current($pointList); + next($pointList); + + $label = $point->getX(); + + $text->printDiagonal($img, $x + $columnWidth * 1 / 3, $graphArea->y2 + 10, $this->plot->getTextColor(), $label); + } + } + } + + /** + * Print the bars. + */ + protected function printBar() { + // Get the data as a list of series for consistency + $serieList = $this->getDataAsSerieList(); + + // Get graphical obects + $img = $this->plot->getImg(); + $palette = $this->plot->getPalette(); + $text = $this->plot->getText(); + + // Get the graph area + $graphArea = $this->plot->getGraphArea(); + + $barColorSet = $palette->barColorSet; + $barColorSet->reset(); + + $minValue = $this->axis->getLowerBoundary(); + $maxValue = $this->axis->getUpperBoundary(); + $stepValue = $this->axis->getTics(); + + $serieCount = count($serieList); + for ($j = 0; $j < $serieCount; $j++) { + $serie = $serieList[$j]; + $pointList = $serie->getPointList(); + $pointCount = count($pointList); + reset($pointList); + + // Get the next color + $color = $barColorSet->currentColor(); + $shadowColor = $barColorSet->currentShadowColor(); + $barColorSet->next(); + + $columnWidth = ($graphArea->x2 - $graphArea->x1) / $pointCount; + for ($i = 0; $i < $pointCount; $i++) { + $x = $graphArea->x1 + $i * $columnWidth; + + $point = current($pointList); + next($pointList); + + $value = $point->getY(); + + $ymin = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta); + + // Bar dimensions + $xWithMargin = $x + $columnWidth * $this->emptyToFullRatio; + $columnWidthWithMargin = $columnWidth * (1 - $this->emptyToFullRatio * 2); + $barWidth = $columnWidthWithMargin / $serieCount; + $barOffset = $barWidth * $j; + $x1 = $xWithMargin + $barOffset; + $x2 = $xWithMargin + $barWidth + $barOffset - 1; + + // Text + $text->printText($img, $x1 + $barWidth / 2 , $ymin - 5, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN | $text->VERTICAL_BOTTOM_ALIGN); + + // Vertical bar + imagefilledrectangle($img, $x1, $ymin, $x2, $graphArea->y2 - 1, $shadowColor->getColor($img)); + imagefilledrectangle($img, $x1 + 1, $ymin + 1, $x2 - 4, $graphArea->y2 - 1, $color->getColor($img)); + } + } + } + + /** + * Renders the caption. + */ + protected function printCaption() { + // Get the list of labels + $labelList = $this->dataSet->getTitleList(); + + // Create the caption + $caption = new Caption(); + $caption->setPlot($this->plot); + $caption->setLabelList($labelList); + + $palette = $this->plot->getPalette(); + $barColorSet = $palette->barColorSet; + $caption->setColorSet($barColorSet); + + // Render the caption + $caption->render(); + } + + /** + * Render the chart image. + * + * @param string name of the file to render the image to (optional) + */ + public function render($fileName = null) { + // Check the data model + $this->checkDataModel(); + + $this->bound->computeBound($this->dataSet); + $this->computeAxis(); + $this->computeLayout(); + $this->createImage(); + //$this->plot->printLogo(); + //$this->plot->printTitle(); + if (!$this->isEmptyDataSet(1)) { + $this->printAxis(); + $this->printBar(); + if ($this->hasSeveralSerie) { + $this->printCaption(); + } + } + + $this->plot->render($fileName); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/color/Color.php b/gulliver/thirdparty/libchart/classes/view/color/Color.php new file mode 100644 index 000000000..f42d51c4b --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/color/Color.php @@ -0,0 +1,99 @@ +. + * + */ + + /** + * Color. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class Color { + private $red; + private $green; + private $blue; + private $alpha; + private $gdColor; + + /** + * Creates a new color + * + * @param integer red [0..255] + * @param integer green [0..255] + * @param integer blue [0..255] + * @param integer alpha [0..255] + */ + public function Color($red, $green, $blue, $alpha = 0) { + $this->red = (int) $red; + $this->green = (int) $green; + $this->blue = (int) $blue; + $this->alpha = (int) round($alpha * 127.0 / 255); + + $this->gdColor = null; + } + + /** + * Get GD color. + * + * @param $img GD image resource + */ + public function getColor($img) { + // Checks if color has already been allocated + if (!$this->gdColor) { + if ($this->alpha == 0 || !function_exists('imagecolorallocatealpha')) { + $this->gdColor = imagecolorallocate($img, $this->red, $this->green, $this->blue); + } else { + $this->gdColor = imagecolorallocatealpha($img, $this->red, $this->green, $this->blue, $this->alpha); + } + } + + // Returns GD color + return $this->gdColor; + } + + /** + * Clip a color component in the interval [0..255] + * + * @param integer Component + * @return Clipped component + */ + public function clip($component) { + if ($component < 0) { + $component = 0; + } else if ($component > 255) { + $component = 255; + } + + return $component; + } + + /** + * Return a new color, which is a shadow of this one. + * + * @param double Multiplication factor + * @return Shadow color + */ + public function getShadowColor($shadowFactor) { + $red = $this->clip($this->red * $shadowFactor); + $green = $this->clip($this->green * $shadowFactor); + $blue = $this->clip($this->blue * $shadowFactor); + $shadowColor = new Color($red, $green, $blue); + + return $shadowColor; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/color/ColorSet.php b/gulliver/thirdparty/libchart/classes/view/color/ColorSet.php new file mode 100644 index 000000000..fbfcef33a --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/color/ColorSet.php @@ -0,0 +1,83 @@ +. + * + */ + + /** + * A set of colors, used for drawing series of data. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 26 july 2007 + */ + class ColorSet { + public $colorList; + public $shadowColorList; + + /** + * ColorSet constructor. + * + * @param $shadowFactor Shadow factor + * @param $colorArray Colors as an array + */ + public function ColorSet($colorList, $shadowFactor) { + $this->colorList = $colorList; + $this->shadowColorList = array(); + + // Generate the shadow color set + foreach ($colorList as $color) { + $shadowColor = $color->getShadowColor($shadowFactor); + + array_push($this->shadowColorList, $shadowColor); + } + } + + /** + * Reset the iterator over the collections of colors. + */ + public function reset() { + reset($this->colorList); + reset($this->shadowColorList); + } + + /** + * Iterate over the colors and shadow colors. When we go after the last one, loop over (TODO). + * + */ + public function next() { + next($this->colorList); + next($this->shadowColorList); + } + + /** + * Returns the current color. + * + * @return Current color + */ + public function currentColor() { + return current($this->colorList); + } + + /** + * Returns the current shadow color. + * + * @return Current shadow color + */ + public function currentShadowColor() { + return current($this->shadowColorList); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/color/Palette.php b/gulliver/thirdparty/libchart/classes/view/color/Palette.php new file mode 100644 index 000000000..56bbce8c2 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/color/Palette.php @@ -0,0 +1,110 @@ +. + * + */ + + /** + * Color palette shared by all chart types. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 25 july 2007 + */ + class Palette { + public $red; + public $axisColor; + public $aquaColor; + + public $barColorSet; + public $lineColorSet; + public $pieColorSet; + + /** + * Palette constructor. + */ + public function Palette() { + $this->red = new Color(255, 0, 0); + + // Colors for the horizontal and vertical axis + $this->axisColor = array( + new Color(201, 201, 201), + new Color(158, 158, 158) + ); + + // Colors for the background + $this->aquaColor = array( + new Color(242, 242, 242), + new Color(231, 231, 231), + new Color(239, 239, 239), + new Color(253, 253, 253) + ); + + // Colors for the bars + $this->barColorSet = new ColorSet(array( + new Color(42, 71, 181), + new Color(243, 198, 118), + new Color(128, 63, 35), + new Color(128, 63, 35), + new Color(195, 45, 28), + new Color(224, 198, 165), + new Color(239, 238, 218), + new Color(40, 72, 59), + new Color(71, 112, 132), + new Color(167, 192, 199), + new Color(218, 233, 202) + ), 0.75); + + // Colors for the lines + $this->lineColorSet = new ColorSet(array( + new Color(172, 172, 210), + new Color(2, 78, 0), + new Color(148, 170, 36), + new Color(233, 191, 49), + new Color(240, 127, 41), + new Color(243, 63, 34), + new Color(190, 71, 47), + new Color(135, 81, 60), + new Color(128, 78, 162), + new Color(121, 75, 255), + new Color(142, 165, 250), + new Color(162, 254, 239), + new Color(137, 240, 166), + new Color(104, 221, 71), + new Color(98, 174, 35), + new Color(93, 129, 1) + ), 0.75); + + // Colors for the pie + $this->pieColorSet = new ColorSet(array( + new Color(2, 78, 0), + new Color(148, 170, 36), + new Color(233, 191, 49), + new Color(240, 127, 41), + new Color(243, 63, 34), + new Color(190, 71, 47), + new Color(135, 81, 60), + new Color(128, 78, 162), + new Color(121, 75, 255), + new Color(142, 165, 250), + new Color(162, 254, 239), + new Color(137, 240, 166), + new Color(104, 221, 71), + new Color(98, 174, 35), + new Color(93, 129, 1) + ), 0.7); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/plot/Plot.php b/gulliver/thirdparty/libchart/classes/view/plot/Plot.php new file mode 100644 index 000000000..068060a10 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/plot/Plot.php @@ -0,0 +1,415 @@ +. + * + */ + + /** + * The plot holds graphical attributes, and is responsible for computing the layout of the graph. + * The layout is quite simple right now, with 4 areas laid out like that: + * (of course this is subject to change in the future). + * + * output area------------------------------------------------| + * | (outer padding) | + * | image area--------------------------------------------| | + * | | (title padding) | | + * | | title area----------------------------------------| | | + * | | |-------------------------------------------------| | | + * | | | | + * | | (graph padding) (caption padding) | | + * | | graph area----------------| caption area---------| | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * | | |-------------------------| |--------------------| | | + * | | | | + * | |-----------------------------------------------------| | + * | | + * |----------------------------------------------------------| + * + * All area dimensions are known in advance , and the optional logo is drawn in absolute coordinates. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * Created on 27 july 2007 + */ + class Plot { + // Style properties + protected $title; + protected $logoFileName; + + // Outer area, whose dimension is the same as the PNG returned + protected $outputArea; + + // Outer padding surrounding the whole image, everything outside is blank + protected $outerPadding; + + // Coordinates of the area inside the outer padding + protected $imageArea; + + // Fixed title height in pixels + protected $titleHeight; + + // Padding of the title area + protected $titlePadding; + + // Coordinates of the title area + protected $titleArea; + + // True if the plot has a caption + protected $hasCaption; + + // Ratio of graph/caption in width + protected $graphCaptionRatio; + + // Padding of the graph area + protected $graphPadding; + + // Coordinates of the graph area + protected $graphArea; + + // Padding of the caption area + protected $captionPadding; + + // Coordinates of the caption area + protected $captionArea; + + /** + * Text writer. + */ + protected $text; + + /** + * Color palette. + */ + protected $palette; + + /** + * GD image + */ + protected $img; + + /** + * Drawing primitives + */ + protected $primitive; + + protected $backGroundColor; + protected $textColor; + + /** + * Constructor of Plot. + * + * @param integer width of the image + * @param integer height of the image + */ + public function Plot($width, $height) { + $this->width = $width; + $this->height = $height; + + $this->text = new Text(); + $this->palette = new Palette(); + + // Default layout + $this->outputArea = new Rectangle(0, 0, $width - 1, $height - 1); + $this->outerPadding = new Padding(5); + $this->titleHeight = 26; + $this->titlePadding = new Padding(5); + $this->hasCaption = false; + $this->graphCaptionRatio = 0.50; + $this->graphPadding = new Padding(50); + $this->captionPadding = new Padding(15); + } + + /** + * Compute the area inside the outer padding (outside is white). + */ + private function computeImageArea() { + $this->imageArea = $this->outputArea->getPaddedRectangle($this->outerPadding); + } + + /** + * Compute the title area. + */ + private function computeTitleArea() { + $titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom; + $titleArea = new Rectangle( + $this->imageArea->x1, + $this->imageArea->y1, + $this->imageArea->x2, + $titleUnpaddedBottom - 1 + ); + $this->titleArea = $titleArea->getPaddedRectangle($this->titlePadding); + } + + /** + * Compute the graph area. + */ + private function computeGraphArea() { + $titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom; + $graphArea = null; + if ($this->hasCaption) { + $graphUnpaddedRight = $this->imageArea->x1 + ($this->imageArea->x2 - $this->imageArea->x1) * $this->graphCaptionRatio + + $this->graphPadding->left + $this->graphPadding->right; + $graphArea = new Rectangle( + $this->imageArea->x1, + $titleUnpaddedBottom, + $graphUnpaddedRight - 1, + $this->imageArea->y2 + ); + } else { + $graphArea = new Rectangle( + $this->imageArea->x1, + $titleUnpaddedBottom, + $this->imageArea->x2, + $this->imageArea->y2 + ); + } + $this->graphArea = $graphArea->getPaddedRectangle($this->graphPadding); + } + + /** + * Compute the caption area. + */ + private function computeCaptionArea() { + $graphUnpaddedRight = $this->imageArea->x1 + ($this->imageArea->x2 - $this->imageArea->x1) * $this->graphCaptionRatio + + $this->graphPadding->left + $this->graphPadding->right; + $titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom; + $captionArea = new Rectangle( + $graphUnpaddedRight, + $titleUnpaddedBottom, + $this->imageArea->x2, + $this->imageArea->y2 + ); + $this->captionArea = $captionArea->getPaddedRectangle($this->captionPadding); + } + + /** + * Compute the layout of all areas of the graph. + */ + public function computeLayout() { + $this->computeImageArea(); + $this->computeTitleArea(); + $this->computeGraphArea(); + if ($this->hasCaption) { + $this->computeCaptionArea(); + } + } + + /** + * Creates and initialize the image. + */ + public function createImage() { + $this->img = imagecreatetruecolor($this->width, $this->height); + + $this->primitive = new Primitive($this->img); + + $this->backGroundColor = new Color(255, 255, 255); + $this->textColor = new Color(0, 0, 0); + + // White background + imagefilledrectangle($this->img, 0, 0, $this->width - 1, $this->height - 1, $this->backGroundColor->getColor($this->img)); + + //imagerectangle($this->img, $this->imageArea->x1, $this->imageArea->y1, $this->imageArea->x2, $this->imageArea->y2, $this->palette->red->getColor($this->img)); + } + + /** + * Print the title to the image. + */ + public function printTitle() { + $yCenter = $this->titleArea->y1 + ($this->titleArea->y2 - $this->titleArea->y1) / 2; + $this->text->printCentered($this->img, $yCenter, $this->textColor, $this->title, $this->text->fontCondensedBold); + } + + /** + * Print the logo image to the image. + */ + public function printLogo() { + @$logoImage = imageCreateFromPNG($this->logoFileName); + + if ($logoImage) { + imagecopymerge($this->img, $logoImage, 2 * $this->outerPadding->left, $this->outerPadding->top, 0, 0, imagesx($logoImage), imagesy($logoImage), 100); + } + } + + /** + * Renders to a file or to standard output. + * + * @param fileName File name (optional) + */ + public function render($fileName) { + if (isset($fileName)) { + imagepng($this->img, $fileName); + } else { + imagepng($this->img); + } + } + + /** + * Sets the title. + * + * @param string New title + */ + public function setTitle($title) { + $this->title = $title; + } + + /** + * Sets the logo image file name. + * + * @param string New logo image file name + */ + public function setLogoFileName($logoFileName) { + $this->logoFileName = $logoFileName; + } + + /** + * Return the GD image. + * + * @return GD Image + */ + public function getImg() { + return $this->img; + } + + /** + * Return the palette. + * + * @return palette + */ + public function getPalette() { + return $this->palette; + } + + /** + * Return the text. + * + * @return text + */ + public function getText() { + return $this->text; + } + + /** + * Return the primitive. + * + * @return primitive + */ + public function getPrimitive() { + return $this->primitive; + } + + /** + * Return the outer padding. + * + * @param integer Outer padding value in pixels + */ + public function getOuterPadding() { + return $outerPadding; + } + + /** + * Set the outer padding. + * + * @param integer Outer padding value in pixels + */ + public function setOuterPadding($outerPadding) { + $this->outerPadding = $outerPadding; + } + + /** + * Return the title height. + * + * @param integer title height + */ + public function setTitleHeight($titleHeight) { + $this->titleHeight = $titleHeight; + } + + /** + * Return the title padding. + * + * @param integer title padding + */ + public function setTitlePadding($titlePadding) { + $this->titlePadding = $titlePadding; + } + + /** + * Return the graph padding. + * + * @param integer graph padding + */ + public function setGraphPadding($graphPadding) { + $this->graphPadding = $graphPadding; + } + + /** + * Set if the graph has a caption. + * + * @param boolean graph has a caption + */ + public function setHasCaption($hasCaption) { + $this->hasCaption = $hasCaption; + } + + /** + * Set the caption padding. + * + * @param integer caption padding + */ + public function setCaptionPadding($captionPadding) { + $this->captionPadding = $captionPadding; + } + + /** + * Set the graph/caption ratio. + * + * @param integer caption padding + */ + public function setGraphCaptionRatio($graphCaptionRatio) { + $this->graphCaptionRatio = $graphCaptionRatio; + } + + /** + * Return the graph area. + * + * @return graph area + */ + public function getGraphArea() { + return $this->graphArea; + } + + /** + * Return the caption area. + * + * @return caption area + */ + public function getCaptionArea() { + return $this->captionArea; + } + + /** + * Return the text color. + * + * @return text color + */ + public function getTextColor() { + return $this->textColor; + } + } +?> diff --git a/gulliver/thirdparty/libchart/classes/view/primitive/Padding.php b/gulliver/thirdparty/libchart/classes/view/primitive/Padding.php new file mode 100644 index 000000000..e222f77cc --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/primitive/Padding.php @@ -0,0 +1,68 @@ +. + * + */ + + /** + * A padding. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * @Created on 27 july 2007 + */ + class Padding { + /** + * Top padding + */ + public $top; + + /** + * Right padding + */ + public $right; + + /** + * Bottom padding + */ + public $bottom; + + /** + * Left padding + */ + public $left; + + /** + * Creates a new padding. + * + * @param integer Top padding + * @param integer Right padding + * @param integer Bottom padding + * @param integer Left padding + */ + public function Padding($top, $right = null, $bottom = null, $left = null) { + $this->top = $top; + if ($right == null) { + $this->right = $top; + $this->bottom = $top; + $this->left = $top; + } else { + $this->right = $right; + $this->bottom = $bottom; + $this->left = $left; + } + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/primitive/Primitive.php b/gulliver/thirdparty/libchart/classes/view/primitive/Primitive.php new file mode 100644 index 000000000..7a2d55649 --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/primitive/Primitive.php @@ -0,0 +1,70 @@ +. + * + */ + + /** + * Graphic primitives, extends GD with chart related primitives. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class Primitive { + private $img; + + /** + * Creates a new primitive object + * + * @param resource GD image resource + */ + public function Primitive($img) { + $this->img = $img; + } + + /** + * Draws a straight line. + * + * @param integer line start (X) + * @param integer line start (Y) + * @param integer line end (X) + * @param integer line end (Y) + * @param Color line color + */ + public function line($x1, $y1, $x2, $y2, $color, $width = 1) { + imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), 4, $color->getColor($this->img)); + // imageline($this->img, $x1, $y1, $x2, $y2, $color->getColor($this->img)); + } + + /** + * Draw a filled gray box with thick borders and darker corners. + * + * @param integer top left coordinate (x) + * @param integer top left coordinate (y) + * @param integer bottom right coordinate (x) + * @param integer bottom right coordinate (y) + * @param Color edge color + * @param Color corner color + */ + public function outlinedBox($x1, $y1, $x2, $y2, $color0, $color1) { + imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $color0->getColor($this->img)); + imagerectangle($this->img, $x1, $y1, $x1 + 1, $y1 + 1, $color1->getColor($this->img)); + imagerectangle($this->img, $x2 - 1, $y1, $x2, $y1 + 1, $color1->getColor($this->img)); + imagerectangle($this->img, $x1, $y2 - 1, $x1 + 1, $y2, $color1->getColor($this->img)); + imagerectangle($this->img, $x2 - 1, $y2 - 1, $x2, $y2, $color1->getColor($this->img)); + } + + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/primitive/Rectangle.php b/gulliver/thirdparty/libchart/classes/view/primitive/Rectangle.php new file mode 100644 index 000000000..eb28dc0ca --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/primitive/Rectangle.php @@ -0,0 +1,76 @@ +. + * + */ + + /** + * A rectangle identified by the top-left and the bottom-right corners. + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + * @Created on 27 july 2007 + */ + class Rectangle { + /** + * Top left X + */ + public $x1; + + /** + * Top left Y + */ + public $y1; + + /** + * Bottom right X + */ + public $x2; + + /** + * Bottom right Y + */ + public $y2; + + /** + * Creates a new rectangle + * + * @param resource GD image resource + */ + public function Rectangle($x1, $y1, $x2, $y2) { + $this->x1 = $x1; + $this->y1 = $y1; + $this->x2 = $x2; + $this->y2 = $y2; + } + + /** + * Apply a padding and returns the resulting rectangle. + * + * @return Resulting rectangle + */ + public function getPaddedRectangle($padding) { + $rectangle = new Rectangle( + $this->x1 + $padding->left, + $this->y1 + $padding->top, + $this->x2 - $padding->right, + $this->y2 - $padding->bottom + ); + + //echo "(" . $this->x1 . "," . $this->y1 . ") (" . $this->x2 . "," . $this->y2 . ")
    "; + return $rectangle; + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/classes/view/text/Text.php b/gulliver/thirdparty/libchart/classes/view/text/Text.php new file mode 100644 index 000000000..da75c2fdc --- /dev/null +++ b/gulliver/thirdparty/libchart/classes/view/text/Text.php @@ -0,0 +1,129 @@ +. + * + */ + + /** + * Text drawing helper + * + * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com) + */ + class Text { + public $HORIZONTAL_LEFT_ALIGN = 1; + public $HORIZONTAL_CENTER_ALIGN = 2; + public $HORIZONTAL_RIGHT_ALIGN = 4; + public $VERTICAL_TOP_ALIGN = 8; + public $VERTICAL_CENTER_ALIGN = 16; + public $VERTICAL_BOTTOM_ALIGN = 32; + + /** + * Creates a new text drawing helper. + */ + public function Text() { + $baseDir = dirname(__FILE__) . "/../../../"; + + // Free low-res fonts based on Bitstream Vera + $this->fontCondensed = $baseDir . "fonts/DejaVuSansCondensed.ttf"; + $this->fontCondensedBold = $baseDir . "fonts/DejaVuSansCondensed-Bold.ttf"; + } + + /** + * Print text. + * + * @param Image GD image + * @param integer text coordinate (x) + * @param integer text coordinate (y) + * @param Color text color + * @param string text value + * @param string font file name + * @param bitfield text alignment + */ + public function printText($img, $px, $py, $color, $text, $fontFileName, $align = 0) { + if (!($align & $this->HORIZONTAL_CENTER_ALIGN) && !($align & $this->HORIZONTAL_RIGHT_ALIGN)) { + $align |= $this->HORIZONTAL_LEFT_ALIGN; + } + + if (!($align & $this->VERTICAL_CENTER_ALIGN) && !($align & $this->VERTICAL_BOTTOM_ALIGN)) { + $align |= $this->VERTICAL_TOP_ALIGN; + } + + $fontSize = 8; + $lineSpacing = 1; + + list ($llx, $lly, $lrx, $lry, $urx, $ury, $ulx, $uly) = imageftbbox($fontSize, 0, $fontFileName, $text, array("linespacing" => $lineSpacing)); + + $textWidth = $lrx - $llx; + $textHeight = $lry - $ury; + + $angle = 0; + + if ($align & $this->HORIZONTAL_CENTER_ALIGN) { + $px -= $textWidth / 2; + } + + if ($align & $this->HORIZONTAL_RIGHT_ALIGN) { + $px -= $textWidth; + } + + if ($align & $this->VERTICAL_CENTER_ALIGN) { + $py += $textHeight / 2; + } + + if ($align & $this->VERTICAL_TOP_ALIGN) { + $py += $textHeight; + } + + imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img), $fontFileName, $text); + } + + /** + * Print text centered horizontally on the image. + * + * @param Image GD image + * @param integer text coordinate (y) + * @param Color text color + * @param string text value + * @param string font file name + */ + public function printCentered($img, $py, $color, $text, $fontFileName) { + $this->printText($img, imagesx($img) / 2, $py, $color, $text, $fontFileName, $this->HORIZONTAL_CENTER_ALIGN | $this->VERTICAL_CENTER_ALIGN); + } + + /** + * Print text in diagonal. + * + * @param Image GD image + * @param integer text coordinate (x) + * @param integer text coordinate (y) + * @param Color text color + * @param string text value + */ + public function printDiagonal($img, $px, $py, $color, $text) { + $fontSize = 8; + $fontFileName = $this->fontCondensed; + + $lineSpacing = 1; + + list ($lx, $ly, $rx, $ry) = imageftbbox($fontSize, 0, $fontFileName, $text, array("linespacing" => $lineSpacing)); + $textWidth = $rx - $lx; + + $angle = -30; + + imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img), $fontFileName, $text); + } + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed-Bold.ttf b/gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6f4e42ecee285c78e382a287a5ef36b077cdfbb1 GIT binary patch literal 62716 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 literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed.ttf b/gulliver/thirdparty/libchart/fonts/DejaVuSansCondensed.ttf new file mode 100644 index 0000000000000000000000000000000000000000..12af35728fd1fc8a6aa16fd9f1f51b9dc9634c43 GIT binary patch literal 73144 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 Zr9Sl^pZxzo-p@%9{g7EJx%^u0{{;fX5Rm`? literal 0 HcmV?d00001 diff --git a/gulliver/thirdparty/libchart/images/PoweredBy.png b/gulliver/thirdparty/libchart/images/PoweredBy.png new file mode 100644 index 0000000000000000000000000000000000000000..6c5290c879c7fc6b8cfc0549ac2e3343d1eb2e2a GIT binary patch literal 1608 zcmV-O2DkZ%P)WFU8GbZ8({Xk{QrNlj4iWF>9@00pc`L_t(o!`)bKOjB1B zKd-O+6Rp(%)+`7`Yl#og_6a5}8ga^$7&S{)7ZS=Cw3}rN%LpM;F{o^$aq0rj$e3|1 z6*HzHIu;!eP~tw|f~BEU_}7Pbg3`<5BAKoFNU;do5z9BydEr=M$b zUJn3bRu*6wh7fx8>{)DVti$1$=aj}Udh;yZx6CO^3yaE`{r6aZEk3H(lzi2AyDQ+e z+U<5Om)qRjOp+u?lC7<+0I+@gcDLJo;J|_N=g-@0w!*@~k&%&%j0~AfcJACcdRI!N z^2UuDEW2K>7mLLjjfVA7PoKVi z{rat2w<;?u*-M%gg7TBsXv+^R-Qmktzx+Dzh2ebRh0AySg@Dm<9QSxUZnvAu;B>LQ``2HZQED&*%wXz(m^B=nayUC$s`hq z06;F6U%Ys6!-fq!9?x#KM@B|QMMXV)_z)qa*XsoW0nG&fVAPoF-u*=%C5nB~Uxy~@xloDgF&a$(U-}|$&-_le$)l@iNK3Ycx-NkqVn_e zRVo!plK!0t81~Wuc|E>e7jpSiR#s-QSfo;^--n`ma`Yu);4XxSs<8n+Q*%)zf(P7+WaR|Gs)CUb4}D&AmHbb$Cym-P&-hwc*%@dFlQ>J1i{h)f%R~y!3OM_}p#$<~9k#p!gdA~L5I z1%lPP0_YJ~I;(~u2%@vI)8%rNmX-p5(P$hS8w&~wLI|nV>VbiQ(a}++_@yf)zdC|| zdIXH4zg)k2$9e!5ce?URYCC>9fn-5AUl*JGm{{Q#>Pg3(9N4Slai8TGFfwTGYf*OtSp&KR!~qN z5{c^T>!)rzDJh8|#k>�Df%md0%_-_rZINB{(cX5VLWmAQI=`sj|cma?_VC3Hv|) zHKL{Eo~h>R+s2;W@v$MmFdkp9QA%ju-IXE{2JpXN0m@(L7zfUZ9pQuk0000 + * @link http://spyc.sourceforge.net/ + * @copyright Copyright 2005-2006 Chris Wanstrath + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + +/** + * A node, used by Spyc for parsing YAML. + * @package Spyc + */ +class YAMLNode +{ + public $parent; + public $id; + public $data; + public $indent; + public $children = false; + + static protected $lastNodeId = 0; + + /** + * The constructor assigns the node a unique ID. + * + * @return void + */ + public function __construct() + { + $this->id = ++self::$lastNodeId; + } +} + +/** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * + * $parser = new Spyc; + * $array = $parser->load($file); + * + * @package Spyc + */ +class Spyc +{ + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * + * $array = Spyc::YAMLLoad('lucky.yml'); + * print_r($array); + * + * + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public static function YAMLLoad($input) + { + $spyc = new Spyc(); + + return $spyc->load($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public static function YAMLDump($array, $indent = false, $wordwrap = false) + { + $spyc = new Spyc(); + + return $spyc->dump($array, $indent, $wordwrap); + } + + /** + * Load YAML into a PHP array from an instantiated object + * + * The load method, when supplied with a YAML stream (string or file path), + * will do its best to convert the YAML into a PHP array. Pretty simple. + * Usage: + * + * $parser = new Spyc; + * $array = $parser->load('lucky.yml'); + * print_r($array); + * + * + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public function load($input) + { + // See what type of input we're talking about + // If it's not a file, assume it's a string + if (!empty($input) && (strpos($input, "\n") === false) && file_exists($input)) + { + $file = $input; + $yaml = file($input); + } + else + { + $file = null; + $yaml = explode("\n", $input); + } + + // Initiate some objects and values + $base = new YAMLNode(); + $base->indent = 0; + $this->_lastIndent = 0; + $this->_lastNode = $base->id; + $this->_inBlock = false; + $this->_isInline = false; + + foreach ($yaml as $linenum => $line) + { + $ifchk = trim($line); + + // If the line starts with a tab (instead of a space), throw a fit. + if (preg_match('/^ *(\t) *+(\w+)/', $line)) + { + $error = sprintf('ERROR: %sLine %d in your input YAML begins with a tab. YAML only recognizes spaces. Please reformat.', ($file ? "File $file " : ''), $linenum + 1); + + throw new Exception($error); + } + + if ($this->_inBlock === false && empty($ifchk)) + { + continue; + } + else if ($this->_inBlock == true && empty($ifchk)) + { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] .= "\n"; + } + else if ($ifchk{0} != '#' && substr($ifchk, 0, 3) != '---') + { + // Create a new node and get its indent + $node = new YAMLNode(); + $node->indent = $this->_getIndent($line); + + // Check where the node lies in the hierarchy + if ($this->_lastIndent == $node->indent) + { + // If we're in a block, add the text to the parent's data + if ($this->_inBlock === true) + { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; + } + else + { + // The current node's parent is the same as the previous node's + if (isset($this->_allNodes[$this->_lastNode])) + { + $node->parent = $this->_allNodes[$this->_lastNode]->parent; + } + } + } + else if ($this->_lastIndent < $node->indent) + { + if ($this->_inBlock === true) + { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= substr($line, $this->_lastIndent).$this->_blockEnd; + } + else if ($this->_inBlock === false) + { + // The current node's parent is the previous node + $node->parent = $this->_lastNode; + + // If the value of the last node's data was > or | we need to + // start blocking i.e. taking in all lines as a text value until + // we drop our indent. + $parent =& $this->_allNodes[$node->parent]; + $this->_allNodes[$node->parent]->children = true; + if (is_array($parent->data)) + { + $chk = $parent->data[key($parent->data)]; + if ($chk === '>') + { + $this->_inBlock = true; + $this->_blockEnd = ' '; + $parent->data[key($parent->data)] = str_replace('>', '', $parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line).' '; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } + else if ($chk === '|') + { + $this->_inBlock = true; + $this->_blockEnd = "\n"; + $parent->data[key($parent->data)] = str_replace('|', '', $parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line)."\n"; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } + } + } + } + else if ($this->_lastIndent > $node->indent) + { + // Any block we had going is dead now + if ($this->_inBlock === true) + { + $this->_inBlock = false; + if ($this->_blockEnd = "\n") + { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] = trim($last->data[key($last->data)]); + } + } + + // We don't know the parent of the node so we have to find it + // foreach ($this->_allNodes as $n) { + foreach ($this->_indentSort[$node->indent] as $n) + { + if ($n->indent == $node->indent) + { + $node->parent = $n->parent; + } + } + } + + if ($this->_inBlock === false) + { + // Set these properties with information from our current node + $this->_lastIndent = $node->indent; + // Set the last node + $this->_lastNode = $node->id; + // Parse the YAML line and return its data + $node->data = $this->_parseLine($line); + // Add the node to the master list + $this->_allNodes[$node->id] = $node; + // Add a reference to the node in an indent array + $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; + // Add a reference to the node in a References array if this node + // has a YAML reference in it. + if ( + ((is_array($node->data)) && + isset($node->data[key($node->data)]) && + (!is_array($node->data[key($node->data)]))) + && + ((preg_match('/^&([^ ]+)/', $node->data[key($node->data)])) + || + (preg_match('/^\*([^ ]+)/', $node->data[key($node->data)]))) + ) + { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } + else if ( + ((is_array($node->data)) && + isset($node->data[key($node->data)]) && + (is_array($node->data[key($node->data)]))) + ) + { + // Incomplete reference making code. Ugly, needs cleaned up. + foreach ($node->data[key($node->data)] as $d) + { + if (!is_array($d) && ((preg_match('/^&([^ ]+)/', $d)) || (preg_match('/^\*([^ ]+)/', $d)))) + { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } + } + } + } + } + } + unset($node); + + // Here we travel through node-space and pick out references (& and *) + $this->_linkReferences(); + + // Build the PHP array out of node-space + $trunk = $this->_buildArray(); + + return $trunk; + } + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array, $indent = false, $wordwrap = false) + { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) + { + $this->_dumpIndent = 2; + } + else + { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) + { + $this->_dumpWordWrap = 40; + } + else + { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + foreach ($array as $key => $value) + { + $string .= $this->_yamlize($key, $value, 0); + } + + return $string; + } + + protected $_haveRefs; + protected $_allNodes; + protected $_lastIndent; + protected $_lastNode; + protected $_inBlock; + protected $_isInline; + protected $_dumpIndent; + protected $_dumpWordWrap; + + /** + * Attempts to convert a key / value array item to YAML + * + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + protected function _yamlize($key, $value, $indent) + { + if (is_array($value)) + { + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key, null, $indent); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value, $indent); + } + else if (!is_array($value)) + { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key, $value, $indent); + } + + return $string; + } + + /** + * Attempts to convert an array to YAML + * + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + protected function _yamlizeArray($array, $indent) + { + if (is_array($array)) + { + $string = ''; + foreach ($array as $key => $value) + { + $string .= $this->_yamlize($key, $value, $indent); + } + + return $string; + } + else + { + return false; + } + } + + /** + * Returns YAML from a key and a value + * + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + protected function _dumpNode($key, $value, $indent) + { + if (is_object($value)) + { + if (method_exists($value, '__toString')) + { + $value = (string) $value; + } + else + { + $ref = new ReflectionObject($value); + $value = $ref->getName(); + } + } + + // do some folding here, for blocks + if (strpos($value,"\n")) + { + $value = $this->_doLiteralBlock($value, $indent); + } + else + { + $value = $this->_doFolding($value, $indent); + } + + $spaces = str_repeat(' ', $indent); + + if (is_int($key)) + { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } + else + { + // It's mapped + $string = $spaces.$key.': '.$value."\n"; + } + + return $string; + } + + /** + * Creates a literal block for dumping + * + * @return string + * @param $value + * @param $indent int The value of the indent + */ + protected function _doLiteralBlock($value, $indent) + { + $exploded = explode("\n", $value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ', $indent); + foreach ($exploded as $line) + { + $newValue .= "\n".$spaces.trim($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * + * @return string + * @param $value The string you wish to fold + */ + protected function _doFolding($value, $indent) + { + // Don't do anything if wordwrap is set to 0 + if ($this->_dumpWordWrap === 0) + { + return $value; + } + + if (strlen($value) > $this->_dumpWordWrap) + { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ', $indent); + $wrapped = wordwrap($value, $this->_dumpWordWrap, "\n$indent"); + $value = ">\n".$indent.$wrapped; + } + + return $value; + } + + /* Methods used in loading */ + + /** + * Finds and returns the indentation of a YAML line + * + * @return int + * @param string $line A line from the YAML file + */ + protected function _getIndent($line) + { + preg_match('/^\s{1,}/', $line, $match); + if (!empty($match[0])) + { + $indent = substr_count($match[0], ' '); + } + else + { + $indent = 0; + } + + return $indent; + } + + /** + * Parses YAML code and returns an array for a node + * + * @return array + * @param string $line A line from the YAML file + */ + protected function _parseLine($line) + { + $line = trim($line); + + $array = array(); + + if (preg_match('/^-(.*):$/', $line)) + { + // It's a mapped sequence + $key = trim(substr(substr($line,1), 0, -1)); + $array[$key] = ''; + } + else if ($line[0] == '-' && substr($line, 0, 3) != '---') + { + // It's a list item but not a new stream + if (strlen($line) > 1) + { + $value = trim(substr($line, 1)); + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + $array[] = $value; + } + else + { + $array[] = array(); + } + } + else if (preg_match('/^(.+):/', $line, $key)) + { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (preg_match('/^(["\'](.*)["\'](\s)*:)/', $line, $matches)) + { + $value = trim(str_replace($matches[1], '', $line)); + $key = $matches[2]; + } + else + { + // Do some guesswork as to the key and the value + $explode = explode(':', $line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':', $explode)); + } + + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if (empty($key)) + { + $array[] = $value; + } + else + { + $array[$key] = $value; + } + } + + return $array; + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * + * @param string $value + * @return mixed + */ + protected function _toType($value) + { + $value = trim($value); + if ($value && !('"' == $value[0] || "'" == $value[0])) + { + $value = preg_replace('/\s*#(.+)$/', '', $value); + } + + if (preg_match('/^("(.*)"|\'(.*)\')/', $value, $matches)) + { + $value = (string) preg_replace('/(\'\'|\\\\\')/', "'", end($matches)); + $value = preg_replace('/\\\\"/', '"', $value); + } + else if (preg_match('/^\\[\s*\\]$/', $value, $matches)) + { + $value = array(); + } + else if (preg_match('/^{}$/', $value, $matches)) + { + $value = array(); + } + else if (preg_match('/^\\[(.+)\\]$/', $value, $matches)) + { + // Inline Sequence + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $value = array(); + foreach ($explode as $v) + { + $value[] = $this->_toType($v); + } + } + else if (strpos($value,': ') !== false && !preg_match('/^{(.+)/', $value)) + { + // It's a map + $array = explode(': ', $value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ', $array)); + $value = $this->_toType($value); + $value = array($key => $value); + } + else if (preg_match("/{(.+)}$/", $value, $matches)) + { + // Inline Mapping + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $array = array(); + foreach ($explode as $v) + { + $array = $array + $this->_toType($v); + } + $value = $array; + } + else if (strtolower($value) == 'null' or $value == '' or $value == '~') + { + $value = null; + } + else if (ctype_digit($value)) + { + $value = (int) $value; + } + else if (in_array(strtolower($value), array('true', 'on', '+', 'yes', 'y'))) + { + $value = true; + } + else if (in_array(strtolower($value), array('false', 'off', '-', 'no', 'n'))) + { + $value = false; + } + else if (is_numeric($value)) + { + $value = (float) $value; + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * + * @return array + */ + protected function _inlineEscape($inline) + { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex, $inline, $strings)) + { + foreach ($strings[0] as $string) + { + $saved_strings[] = $string; + } + $inline = preg_replace($regex, 'YAMLString', $inline); + } + unset($regex); + + // Check for sequences + if (preg_match_all('/\[(.+)\]/U', $inline, $seqs)) + { + $inline = preg_replace('/\[(.+)\]/U', 'YAMLSeq', $inline); + $seqs = $seqs[0]; + } + + // Check for mappings + if (preg_match_all('/{(.+)}/U', $inline, $maps)) + { + $inline = preg_replace('/{(.+)}/U', 'YAMLMap', $inline); + $maps = $maps[0]; + } + + $explode = explode(', ', $inline); + + // Re-add the strings + if (!empty($saved_strings)) + { + $i = 0; + foreach ($explode as $key => $value) + { + if (false !== strpos($value,'YAMLString')) + { + $explode[$key] = str_replace('YAMLString', $saved_strings[$i], $value); + ++$i; + } + } + } + + // Re-add the sequences + if (!empty($seqs)) + { + $i = 0; + foreach ($explode as $key => $value) + { + if (strpos($value,'YAMLSeq') !== false) + { + $explode[$key] = str_replace('YAMLSeq', $seqs[$i], $value); + ++$i; + } + } + } + + // Re-add the mappings + if (!empty($maps)) + { + $i = 0; + foreach ($explode as $key => $value) + { + if (strpos($value,'YAMLMap') !== false) + { + $explode[$key] = str_replace('YAMLMap', $maps[$i], $value); + ++$i; + } + } + } + + return $explode; + } + + /** + * Builds the PHP array from all the YAML nodes we've gathered + * + * @return array + */ + protected function _buildArray() + { + $trunk = array(); + + if (!isset($this->_indentSort[0])) + { + return $trunk; + } + + foreach ($this->_indentSort[0] as $n) + { + if (empty($n->parent)) + { + $this->_nodeArrayizeData($n); + // Check for references and copy the needed data to complete them. + $this->_makeReferences($n); + // Merge our data with the big array we're building + $trunk = $this->_array_kmerge($trunk, $n->data); + } + } + + return $trunk; + } + + /** + * Traverses node-space and sets references (& and *) accordingly + * + * @return bool + */ + protected function _linkReferences() + { + if (is_array($this->_haveRefs)) + { + foreach ($this->_haveRefs as $node) + { + if (!empty($node->data)) + { + $key = key($node->data); + // If it's an array, don't check. + if (is_array($node->data[$key])) + { + foreach ($node->data[$key] as $k => $v) + { + $this->_linkRef($node, $key, $k, $v); + } + } + else + { + $this->_linkRef($node, $key); + } + } + } + } + + return true; + } + + function _linkRef(&$n, $key, $k = null, $v = null) + { + if (empty($k) && empty($v)) + { + // Look for &refs + if (preg_match('/^&([^ ]+)/', $n->data[$key], $matches)) + { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0], 1); + $this->_allNodes[$n->id]->data[$key] = substr($n->data[$key], strlen($matches[0]) + 1); + // Look for *refs + } + else if (preg_match('/^\*([^ ]+)/', $n->data[$key], $matches)) + { + $ref = substr($matches[0], 1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } + } + else if (!empty($k) && !empty($v)) + { + if (preg_match('/^&([^ ]+)/', $v, $matches)) + { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0], 1); + $this->_allNodes[$n->id]->data[$key][$k] = substr($v, strlen($matches[0]) + 1); + // Look for *refs + } + else if (preg_match('/^\*([^ ]+)/', $v, $matches)) + { + $ref = substr($matches[0], 1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } + } + } + + /** + * Finds the children of a node and aids in the building of the PHP array + * + * @param int $nid The id of the node whose children we're gathering + * @return array + */ + protected function _gatherChildren($nid) + { + $return = array(); + $node =& $this->_allNodes[$nid]; + foreach ($this->_allNodes as $z) + { + if ($z->parent == $node->id) + { + // We found a child + $this->_nodeArrayizeData($z); + // Check for references + $this->_makeReferences($z); + // Merge with the big array we're returning + // The big array being all the data of the children of our parent node + $return = $this->_array_kmerge($return, $z->data); + } + } + + return $return; + } + + /** + * Turns a node's data and its children's data into a PHP array + * + * + * @param array $node The node which you want to arrayize + * @return boolean + */ + protected function _nodeArrayizeData(&$node) + { + if (is_array($node->data) && $node->children == true) + { + // This node has children, so we need to find them + $childs = $this->_gatherChildren($node->id); + // We've gathered all our children's data and are ready to use it + $key = key($node->data); + $key = empty($key) ? 0 : $key; + // If it's an array, add to it of course + if (is_array($node->data[$key])) + { + $node->data[$key] = $this->_array_kmerge($node->data[$key], $childs); + } + else + { + $node->data[$key] = $childs; + } + } + else if (!is_array($node->data) && $node->children == true) + { + // Same as above, find the children of this node + $childs = $this->_gatherChildren($node->id); + $node->data = array(); + $node->data[] = $childs; + } + + // We edited $node by reference, so just return true + return true; + } + + /** + * Traverses node-space and copies references to / from this object. + * + * @param object $z A node whose references we wish to make real + * @return bool + */ + protected function _makeReferences(&$z) + { + // It is a reference + if (isset($z->ref)) + { + $key = key($z->data); + // Copy the data to this object for easy retrieval later + $this->ref[$z->ref] =& $z->data[$key]; + // It has a reference + } + else if (isset($z->refKey)) + { + if (isset($this->ref[$z->refKey])) + { + $key = key($z->data); + // Copy the data from this object to make the node a real reference + $z->data[$key] =& $this->ref[$z->refKey]; + } + } + + return true; + } + + /** + * Merges arrays and maintains numeric keys. + * + * An ever-so-slightly modified version of the array_kmerge() function posted + * to php.net by mail at nospam dot iaindooley dot com on 2004-04-08. + * + * http://us3.php.net/manual/en/function.array-merge.php#41394 + * + * @param array $arr1 + * @param array $arr2 + * @return array + */ + protected function _array_kmerge($arr1, $arr2) + { + if (!is_array($arr1)) + { + $arr1 = array(); + } + if (!is_array($arr2)) + { + $arr2 = array(); + } + + $keys = array_merge(array_keys($arr1), array_keys($arr2)); + $vals = array_merge(array_values($arr1), array_values($arr2)); + $ret = array(); + foreach ($keys as $key) + { + list($unused, $val) = each($vals); + if (isset($ret[$key]) && is_int($key)) + { + $ret[] = $val; + } + else + { + $ret[$key] = $val; + } + } + + return $ret; + } +} diff --git a/gulliver/thirdparty/lime/lime.php b/gulliver/thirdparty/lime/lime.php new file mode 100644 index 000000000..456dd2564 --- /dev/null +++ b/gulliver/thirdparty/lime/lime.php @@ -0,0 +1,980 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Unit test library. + * + * @package lime + * @author Fabien Potencier + * @version SVN: $Id: lime.php 4259 2007-06-19 07:24:40Z fabien $ + */ + +class lime_test +{ + public $plan = null; + public $test_nb = 0; + public $failed = 0; + public $passed = 0; + public $skipped = 0; + public $output = null; + + function __construct($plan = null, $output_instance = null) + { + $this->plan = $plan; + $this->output = $output_instance ? $output_instance : new lime_output(); + + null !== $this->plan and $this->output->echoln(sprintf("1..%d", $this->plan)); + } + + function __destruct() + { + $total = $this->passed + $this->failed + $this->skipped; + + null === $this->plan and $this->plan = $total and $this->output->echoln(sprintf("1..%d", $this->plan)); + + if ($total > $this->plan) + { + $this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $this->plan, $total - $this->plan)); + } + elseif ($total < $this->plan) + { + $this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $this->plan, $total)); + } + + if ($this->failed) + { + $this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $this->failed, $this->plan)); + } + else if ($total == $this->plan) + { + $this->output->green_bar(" Looks like everything went fine."); + } + + flush(); + } + + function ok($exp, $message = '') + { + if ($result = (boolean) $exp) + { + ++$this->passed; + } + else + { + ++$this->failed; + } + $this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', ++$this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : '')); + + if (!$result) + { + $traces = debug_backtrace(); + if ($_SERVER['PHP_SELF']) + { + $i = strstr($traces[0]['file'], $_SERVER['PHP_SELF']) ? 0 : (isset($traces[1]['file']) ? 1 : 0); + } + else + { + $i = 0; + } + $this->output->diag(sprintf(' Failed test (%s at line %d)', str_replace(getcwd(), '.', $traces[$i]['file']), $traces[$i]['line'])); + } + + return $result; + } + + function is($exp1, $exp2, $message = '') + { + if (is_object($exp1) || is_object($exp2)) + { + $value = $exp1 === $exp2; + } + else + { + $value = $exp1 == $exp2; + } + + if (!$result = $this->ok($value, $message)) + { + $this->output->diag(sprintf(" got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" expected: %s", str_replace("\n", '', var_export($exp2, true)))); + } + + return $result; + } + + function isnt($exp1, $exp2, $message = '') + { + if (!$result = $this->ok($exp1 != $exp2, $message)) + { + $this->output->diag(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), ' ne', sprintf(" %s", str_replace("\n", '', var_export($exp2, true)))); + } + + return $result; + } + + function like($exp, $regex, $message = '') + { + if (!$result = $this->ok(preg_match($regex, $exp), $message)) + { + $this->output->diag(sprintf(" '%s'", $exp), sprintf(" doesn't match '%s'", $regex)); + } + + return $result; + } + + function unlike($exp, $regex, $message = '') + { + if (!$result = $this->ok(!preg_match($regex, $exp), $message)) + { + $this->output->diag(sprintf(" '%s'", $exp), sprintf(" matches '%s'", $regex)); + } + + return $result; + } + + function cmp_ok($exp1, $op, $exp2, $message = '') + { + eval(sprintf("\$result = \$exp1 $op \$exp2;")); + if (!$this->ok($result, $message)) + { + $this->output->diag(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" %s", $op), sprintf(" %s", str_replace("\n", '', var_export($exp2, true)))); + } + + return $result; + } + + function can_ok($object, $methods, $message = '') + { + $result = true; + $failed_messages = array(); + foreach ((array) $methods as $method) + { + if (!method_exists($object, $method)) + { + $failed_messages[] = sprintf(" method '%s' does not exist", $method); + $result = false; + } + } + + !$this->ok($result, $message); + + !$result and $this->output->diag($failed_messages); + + return $result; + } + + function isa_ok($var, $class, $message = '') + { + $type = is_object($var) ? get_class($var) : gettype($var); + if (!$result = $this->ok($type == $class, $message)) + { + $this->output->diag(sprintf(" isa_ok isn't a '%s' it's a '%s'", $class, $type)); + } + + return $result; + } + + function is_deeply($exp1, $exp2, $message = '') + { + if (!$result = $this->ok($this->test_is_deeply($exp1, $exp2), $message)) + { + $this->output->diag(sprintf(" got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" expected: %s", str_replace("\n", '', var_export($exp2, true)))); + } + + return $result; + } + + function pass($message = '') + { + return $this->ok(true, $message); + } + + function fail($message = '') + { + return $this->ok(false, $message); + } + + function diag($message) + { + $this->output->diag($message); + } + + function skip($message = '', $nb_tests = 1) + { + for ($i = 0; $i < $nb_tests; $i++) + { + ++$this->skipped and --$this->passed; + $this->pass(sprintf("# SKIP%s", $message ? ' '.$message : '')); + } + } + + function todo($message = '') + { + ++$this->skipped and --$this->passed; + $this->pass(sprintf("# TODO%s", $message ? ' '.$message : '')); + } + + function include_ok($file, $message = '') + { + if (!$result = $this->ok((@include($file)) == 1, $message)) + { + $this->output->diag(sprintf(" Tried to include '%s'", $file)); + } + + return $result; + } + + private function test_is_deeply($var1, $var2) + { + if (gettype($var1) != gettype($var2)) + { + return false; + } + + if (is_array($var1)) + { + ksort($var1); + ksort($var2); + if (array_diff(array_keys($var1), array_keys($var2))) + { + return false; + } + $is_equal = true; + foreach ($var1 as $key => $value) + { + $is_equal = $this->test_is_deeply($var1[$key], $var2[$key]); + if ($is_equal === false) + { + break; + } + } + + return $is_equal; + } + else + { + return $var1 === $var2; + } + } + + function comment($message) + { + $this->output->comment($message); + } + + static function get_temp_directory() + { + if ('\\' == DIRECTORY_SEPARATOR) + { + foreach (array('TEMP', 'TMP', 'windir') as $dir) + { + if ($var = isset($_ENV[$dir]) ? $_ENV[$dir] : getenv($dir)) + { + return $var; + } + } + + return getenv('SystemRoot').'\temp'; + } + + if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) + { + return $var; + } + + return '/tmp'; + } +} + +class lime_output +{ + function diag() + { + $messages = func_get_args(); + foreach ($messages as $message) + { + array_map(array($this, 'comment'), (array) $message); + } + } + + function comment($message) + { + echo "# $message\n"; + } + + function echoln($message) + { + echo "$message\n"; + } + + function green_bar($message) + { + echo "$message\n"; + } + + function red_bar($message) + { + echo "$message\n"; + } +} + +class lime_output_color extends lime_output +{ + public $colorizer = null; + + function __construct() + { + $this->colorizer = new lime_colorizer(); + } + + function diag() + { + $messages = func_get_args(); + foreach ($messages as $message) + { + echo $this->colorizer->colorize('# '.join("\n# ", (array) $message), 'COMMENT')."\n"; + } + } + + function comment($message) + { + echo $this->colorizer->colorize(sprintf('# %s', $message), 'COMMENT')."\n"; + } + + function echoln($message, $colorizer_parameter = null) + { + $message = preg_replace('/(?:^|\.)((?:not ok|dubious) *\d*)\b/e', '$this->colorizer->colorize(\'$1\', \'ERROR\')', $message); + $message = preg_replace('/(?:^|\.)(ok *\d*)\b/e', '$this->colorizer->colorize(\'$1\', \'INFO\')', $message); + $message = preg_replace('/"(.+?)"/e', '$this->colorizer->colorize(\'$1\', \'PARAMETER\')', $message); + $message = preg_replace('/(\->|\:\:)?([a-zA-Z0-9_]+?)\(\)/e', '$this->colorizer->colorize(\'$1$2()\', \'PARAMETER\')', $message); + + echo ($colorizer_parameter ? $this->colorizer->colorize($message, $colorizer_parameter) : $message)."\n"; + } + + function green_bar($message) + { + echo $this->colorizer->colorize($message.str_repeat(' ', 71 - min(71, strlen($message))), 'GREEN_BAR')."\n"; + } + + function red_bar($message) + { + echo $this->colorizer->colorize($message.str_repeat(' ', 71 - min(71, strlen($message))), 'RED_BAR')."\n"; + } +} + +class lime_colorizer +{ + static public $styles = array(); + + static function style($name, $options = array()) + { + self::$styles[$name] = $options; + } + + static function colorize($text = '', $parameters = array()) + { + // disable colors if not supported (windows or non tty console) + if (DIRECTORY_SEPARATOR == '\\' || !function_exists('posix_isatty') || !@posix_isatty(STDOUT)) + { + return $text; + } + + static $options = array('bold' => 1, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, 'conceal' => 8); + static $foreground = array('black' => 30, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37); + static $background = array('black' => 40, 'red' => 41, 'green' => 42, 'yellow' => 43, 'blue' => 44, 'magenta' => 45, 'cyan' => 46, 'white' => 47); + + !is_array($parameters) && isset(self::$styles[$parameters]) and $parameters = self::$styles[$parameters]; + + $codes = array(); + isset($parameters['fg']) and $codes[] = $foreground[$parameters['fg']]; + isset($parameters['bg']) and $codes[] = $background[$parameters['bg']]; + foreach ($options as $option => $value) + { + isset($parameters[$option]) && $parameters[$option] and $codes[] = $value; + } + + return "\033[".implode(';', $codes).'m'.$text."\033[0m"; + } +} + +lime_colorizer::style('ERROR', array('bg' => 'red', 'fg' => 'white', 'bold' => true)); +lime_colorizer::style('INFO', array('fg' => 'green', 'bold' => true)); +lime_colorizer::style('PARAMETER', array('fg' => 'cyan')); +lime_colorizer::style('COMMENT', array('fg' => 'yellow')); + +lime_colorizer::style('GREEN_BAR', array('fg' => 'white', 'bg' => 'green', 'bold' => true)); +lime_colorizer::style('RED_BAR', array('fg' => 'white', 'bg' => 'red', 'bold' => true)); + +class lime_harness extends lime_registration +{ + public $php_cli = ''; + public $stats = array(); + public $output = null; + + function __construct($output_instance, $php_cli = null) + { + if (getenv('PHP_PATH')) + { + $this->php_cli = getenv('PHP_PATH'); + + if (!is_executable($this->php_cli)) + { + throw new Exception('The defined PHP_PATH environment variable is not a valid PHP executable.'); + } + } + + $this->php_cli = null === $php_cli ? PHP_BINDIR.DIRECTORY_SEPARATOR.'php' : $php_cli; + + if (!is_executable($this->php_cli)) + { + $this->php_cli = $this->find_php_cli(); + } + + $this->output = $output_instance ? $output_instance : new lime_output(); + } + + protected function find_php_cli() + { + $path = getenv('PATH') ? getenv('PATH') : getenv('Path'); + $exe_suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array(''); + foreach (array('php5', 'php') as $php_cli) + { + foreach ($exe_suffixes as $suffix) + { + foreach (explode(PATH_SEPARATOR, $path) as $dir) + { + $file = $dir.DIRECTORY_SEPARATOR.$php_cli.$suffix; + if (is_executable($file)) + { + return $file; + } + } + } + } + + throw new Exception("Unable to find PHP executable."); + } + + function run() + { + if (!count($this->files)) + { + throw new Exception('You must register some test files before running them!'); + } + + // sort the files to be able to predict the order + sort($this->files); + + $this->stats =array( + '_failed_files' => array(), + '_failed_tests' => 0, + '_nb_tests' => 0, + ); + + foreach ($this->files as $file) + { + $this->stats[$file] = array( + 'plan' => null, + 'nb_tests' => 0, + 'failed' => array(), + 'passed' => array(), + ); + $this->current_file = $file; + $this->current_test = 0; + $relative_file = $this->get_relative_file($file); + + //$fName = str_replace ( PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP , '', $file ); + //printf("\ntesting %s \n", pakeColor::colorize( $file, 'INFO')); + ob_start(array($this, 'process_test_output')); + passthru(sprintf('%s -d html_errors=off -d open_basedir= -q "%s" 2>&1', $this->php_cli, $file), $return); + ob_end_clean(); + + if ($return > 0) + { + $this->stats[$file]['status'] = 'dubious'; + $this->stats[$file]['status_code'] = $return; + } + else + { + $delta = $this->stats[$file]['plan'] - $this->stats[$file]['nb_tests']; + if ($delta > 0) + { + $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->colorizer->colorize(sprintf('# Looks like you planned %d tests but only ran %d.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests']), 'COMMENT'))); + $this->stats[$file]['status'] = 'dubious'; + $this->stats[$file]['status_code'] = 255; + $this->stats['_nb_tests'] += $delta; + for ($i = 1; $i <= $delta; $i++) + { + $this->stats[$file]['failed'][] = $this->stats[$file]['nb_tests'] + $i; + } + } + else if ($delta < 0) + { + $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->colorizer->colorize(sprintf('# Looks like you planned %s test but ran %s extra.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'] - $this->stats[$file]['plan']), 'COMMENT'))); + $this->stats[$file]['status'] = 'dubious'; + $this->stats[$file]['status_code'] = 255; + for ($i = 1; $i <= -$delta; $i++) + { + $this->stats[$file]['failed'][] = $this->stats[$file]['plan'] + $i; + } + } + else + { + $this->stats[$file]['status_code'] = 0; + $this->stats[$file]['status'] = $this->stats[$file]['failed'] ? 'not ok' : 'ok'; + } + } + + $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->stats[$file]['status'])); + if (($nb = count($this->stats[$file]['failed'])) || $return > 0) + { + if ($nb) + { + $this->output->echoln(sprintf(" Failed tests: %s", implode(', ', $this->stats[$file]['failed']))); + } + $this->stats['_failed_files'][] = $file; + $this->stats['_failed_tests'] += $nb; + } + + if ('dubious' == $this->stats[$file]['status']) + { + $this->output->echoln(sprintf(' Test returned status %s', $this->stats[$file]['status_code'])); + } + } + + if (count($this->stats['_failed_files'])) + { + $format = "%-30s %4s %5s %5s %s"; + $this->output->echoln(sprintf($format, 'Failed Test', 'Stat', 'Total', 'Fail', 'List of Failed')); + $this->output->echoln("------------------------------------------------------------------"); + foreach ($this->stats as $file => $file_stat) + { + if (!in_array($file, $this->stats['_failed_files'])) continue; + + $relative_file = $this->get_relative_file($file); + $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $file_stat['status_code'], count($file_stat['failed']) + count($file_stat['passed']), count($file_stat['failed']), implode(' ', $file_stat['failed']))); + } + + $this->output->red_bar(sprintf('Failed %d/%d test scripts, %.2f%% okay. %d/%d subtests failed, %.2f%% okay.', + $nb_failed_files = count($this->stats['_failed_files']), + $nb_files = count($this->files), + ($nb_files - $nb_failed_files) * 100 / $nb_files, + $nb_failed_tests = $this->stats['_failed_tests'], + $nb_tests = $this->stats['_nb_tests'], + $nb_tests > 0 ? ($nb_tests - $nb_failed_tests) * 100 / $nb_tests : 0 + )); + } + else + { + $this->output->green_bar(' All tests successful.'); + $this->output->green_bar(sprintf(' Files=%d, Tests=%d', count($this->files), $this->stats['_nb_tests'])); + } + + return $this->stats['_failed_tests'] ? false : true; + } + + private function process_test_output($lines) + { + foreach (explode("\n", $lines) as $text) + { + if (false !== strpos($text, 'not ok ')) + { + ++$this->current_test; + $test_number = (int) substr($text, 7); + $this->stats[$this->current_file]['failed'][] = $test_number; + + ++$this->stats[$this->current_file]['nb_tests']; + ++$this->stats['_nb_tests']; + } + else if (false !== strpos($text, 'ok ')) + { + ++$this->stats[$this->current_file]['nb_tests']; + ++$this->stats['_nb_tests']; + } + else if (preg_match('/^1\.\.(\d+)/', $text, $match)) + { + $this->stats[$this->current_file]['plan'] = $match[1]; + } + } + + return; + } +} + +class lime_coverage extends lime_registration +{ + public $files = array(); + public $extension = '.php'; + public $base_dir = ''; + public $harness = null; + public $verbose = false; + + function __construct($harness) + { + $this->harness = $harness; + } + + function run() + { + if (!function_exists('xdebug_start_code_coverage')) + { + throw new Exception('You must install and enable xdebug before using lime coverage.'); + } + + if (!ini_get('xdebug.extended_info')) + { + throw new Exception('You must set xdebug.extended_info to 1 in your php.ini to use lime coverage.'); + } + + if (!count($this->harness->files)) + { + throw new Exception('You must register some test files before running coverage!'); + } + + if (!count($this->files)) + { + throw new Exception('You must register some files to cover!'); + } + + $coverage = array(); + $tmp_file = lime_test::get_temp_directory().DIRECTORY_SEPARATOR.'test.php'; + foreach ($this->harness->files as $file) + { + $tmp = <<'.serialize(xdebug_get_code_coverage()).''; +EOF; + file_put_contents($tmp_file, $tmp); + ob_start(); + passthru(sprintf('%s -d html_errors=off -d open_basedir= -q "%s" 2>&1', $this->harness->php_cli, $tmp_file), $return); + $retval = ob_get_clean(); + if (0 == $return) + { + if (false === $cov = unserialize(substr($retval, strpos($retval, '') + 9, strpos($retval, '') - 9))) + { + throw new Exception(sprintf('Unable to unserialize coverage for file "%s"', $file)); + } + + foreach ($cov as $file => $lines) + { + if (!isset($coverage[$file])) + { + $coverage[$file] = array(); + } + + foreach ($lines as $line => $count) + { + if (!isset($coverage[$file][$line])) + { + $coverage[$file][$line] = 0; + } + $coverage[$file][$line] = $coverage[$file][$line] + $count; + } + } + } + } + unlink($tmp_file); + + ksort($coverage); + $total_php_lines = 0; + $total_covered_lines = 0; + foreach ($this->files as $file) + { + $cov = isset($coverage[$file]) ? $coverage[$file] : array(); + + list($cov, $php_lines) = $this->compute(file_get_contents($file), $cov); + + $output = $this->harness->output; + $percent = count($php_lines) ? count($cov) * 100 / count($php_lines) : 100; + + $total_php_lines += count($php_lines); + $total_covered_lines += count($cov); + + $relative_file = $this->get_relative_file($file); + $output->echoln(sprintf("%-70s %3.0f%%", substr($relative_file, -min(70, strlen($relative_file))), $percent), $percent == 100 ? 'INFO' : ($percent > 90 ? 'PARAMETER' : ($percent < 20 ? 'ERROR' : ''))); + if ($this->verbose && $percent != 100) + { + $output->comment(sprintf("missing: %s", $this->format_range(array_keys(array_diff_key($php_lines, $cov))))); + } + } + + $output->echoln(sprintf("TOTAL COVERAGE: %3.0f%%", $total_covered_lines * 100 / $total_php_lines)); + } + + static function get_php_lines($content) + { + if (is_file($content)) + { + $content = file_get_contents($content); + } + + $tokens = token_get_all($content); + $php_lines = array(); + $current_line = 1; + $in_class = false; + $in_function = false; + $in_function_declaration = false; + $end_of_current_expr = true; + $open_braces = 0; + foreach ($tokens as $token) + { + if (is_string($token)) + { + switch ($token) + { + case '=': + if (false === $in_class || (false !== $in_function && !$in_function_declaration)) + { + $php_lines[$current_line] = true; + } + break; + case '{': + ++$open_braces; + $in_function_declaration = false; + break; + case ';': + $in_function_declaration = false; + $end_of_current_expr = true; + break; + case '}': + $end_of_current_expr = true; + --$open_braces; + if ($open_braces == $in_class) + { + $in_class = false; + } + if ($open_braces == $in_function) + { + $in_function = false; + } + break; + } + + continue; + } + + list($id, $text) = $token; + + switch ($id) + { + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + ++$open_braces; + break; + case T_WHITESPACE: + case T_OPEN_TAG: + case T_CLOSE_TAG: + $end_of_current_expr = true; + $current_line += count(explode("\n", $text)) - 1; + break; + case T_COMMENT: + case T_DOC_COMMENT: + $current_line += count(explode("\n", $text)) - 1; + break; + case T_CLASS: + $in_class = $open_braces; + break; + case T_FUNCTION: + $in_function = $open_braces; + $in_function_declaration = true; + break; + case T_AND_EQUAL: + case T_CASE: + case T_CATCH: + case T_CLONE: + case T_CONCAT_EQUAL: + case T_CONTINUE: + case T_DEC: + case T_DECLARE: + case T_DEFAULT: + case T_DIV_EQUAL: + case T_DO: + case T_ECHO: + case T_ELSEIF: + case T_EMPTY: + case T_ENDDECLARE: + case T_ENDFOR: + case T_ENDFOREACH: + case T_ENDIF: + case T_ENDSWITCH: + case T_ENDWHILE: + case T_EVAL: + case T_EXIT: + case T_FOR: + case T_FOREACH: + case T_GLOBAL: + case T_IF: + case T_INC: + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_INSTANCEOF: + case T_ISSET: + case T_IS_EQUAL: + case T_IS_GREATER_OR_EQUAL: + case T_IS_IDENTICAL: + case T_IS_NOT_EQUAL: + case T_IS_NOT_IDENTICAL: + case T_IS_SMALLER_OR_EQUAL: + case T_LIST: + case T_LOGICAL_AND: + case T_LOGICAL_OR: + case T_LOGICAL_XOR: + case T_MINUS_EQUAL: + case T_MOD_EQUAL: + case T_MUL_EQUAL: + case T_NEW: + case T_OBJECT_OPERATOR: + case T_OR_EQUAL: + case T_PLUS_EQUAL: + case T_PRINT: + case T_REQUIRE: + case T_REQUIRE_ONCE: + case T_RETURN: + case T_SL: + case T_SL_EQUAL: + case T_SR: + case T_SR_EQUAL: + case T_THROW: + case T_TRY: + case T_UNSET: + case T_UNSET_CAST: + case T_USE: + case T_WHILE: + case T_XOR_EQUAL: + $php_lines[$current_line] = true; + $end_of_current_expr = false; + break; + default: + if (false === $end_of_current_expr) + { + $php_lines[$current_line] = true; + } + //print "$current_line: ".token_name($id)."\n"; + } + } + + return $php_lines; + } + + function compute($content, $cov) + { + $php_lines = self::get_php_lines($content); + + // we remove from $cov non php lines + foreach (array_diff_key($cov, $php_lines) as $line => $tmp) + { + unset($cov[$line]); + } + + return array($cov, $php_lines); + } + + function format_range($lines) + { + sort($lines); + $formatted = ''; + $first = -1; + $last = -1; + foreach ($lines as $line) + { + if ($last + 1 != $line) + { + if ($first != -1) + { + $formatted .= $first == $last ? "$first " : "[$first - $last] "; + } + $first = $line; + $last = $line; + } + else + { + $last = $line; + } + } + if ($first != -1) + { + $formatted .= $first == $last ? "$first " : "[$first - $last] "; + } + + return $formatted; + } +} + +class lime_registration +{ + public $files = array(); + public $extension = '.php'; + public $base_dir = ''; + + function register($files_or_directories) + { + foreach ((array) $files_or_directories as $f_or_d) + { + if (is_file($f_or_d)) + { + $this->files[] = realpath($f_or_d); + } + elseif (is_dir($f_or_d)) + { + $this->register_dir($f_or_d); + } + else + { + throw new Exception(sprintf('The file or directory "%s" does not exist.', $f_or_d)); + } + } + } + + function register_glob($glob) + { + if ($dirs = glob($glob)) + { + foreach ($dirs as $file) + { + $this->files[] = realpath($file); + } + } + } + + function register_dir($directory) + { + if (!is_dir($directory)) + { + throw new Exception(sprintf('The directory "%s" does not exist.', $directory)); + } + + $files = array(); + + $current_dir = opendir($directory); + while ($entry = readdir($current_dir)) + { + if ($entry == '.' || $entry == '..') continue; + + if (is_dir($entry)) + { + $this->register_dir($entry); + } + elseif (preg_match('#'.$this->extension.'$#', $entry)) + { + $files[] = realpath($directory.DIRECTORY_SEPARATOR.$entry); + } + } + + $this->files = array_merge($this->files, $files); + } + + protected function get_relative_file($file) + { + return str_replace(DIRECTORY_SEPARATOR, '/', str_replace(array(realpath($this->base_dir).DIRECTORY_SEPARATOR, $this->extension), '', $file)); + } +} diff --git a/gulliver/thirdparty/lime/yaml.class.php b/gulliver/thirdparty/lime/yaml.class.php new file mode 100644 index 000000000..e170220ca --- /dev/null +++ b/gulliver/thirdparty/lime/yaml.class.php @@ -0,0 +1,93 @@ + + * $array = sfYAML::Load('config.yml'); + * print_r($array); + *
    + * + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public static function load($input) + { + $input = self::getIncludeContents($input); + + // if an array is returned by the config file assume it's in plain php form else in yaml + if (is_array($input)) + { + return $input; + } + + // syck is prefered over spyc + if (function_exists('syck_load')) + { + $retval = syck_load($input); + + return is_array($retval) ? $retval : array(); + } + else + { + require_once(dirname(__FILE__).'/Spyc.class.php'); + + $spyc = new Spyc(); + + return $spyc->load($input); + } + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. + * + * @return string + * @param array $array PHP array + */ + public static function dump($array) + { + require_once(dirname(__FILE__).'/Spyc.class.php'); + + $spyc = new Spyc(); + + return $spyc->dump($array); + } + + protected static function getIncludeContents($input) + { + // if input is a file, process it + if (strpos($input, "\n") === false && is_file($input)) + { + ob_start(); + $retval = include($input); + $contents = ob_get_clean(); + + // if an array is returned by the config file assume it's in plain php form else in yaml + return is_array($retval) ? $retval : $contents; + } + + // else return original input + return $input; + } +} + +/** + * Wraps echo to automatically provide a newline + */ +function echoln($string) +{ + echo $string."\n"; +} diff --git a/gulliver/thirdparty/pake/pakeApp.class.php b/gulliver/thirdparty/pake/pakeApp.class.php new file mode 100644 index 000000000..bcf53d1fc --- /dev/null +++ b/gulliver/thirdparty/pake/pakeApp.class.php @@ -0,0 +1,458 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeApp.class.php 4623 2007-07-16 12:34:38Z fabien $ + */ + +/** + * + * main pake class. + * + * This class is a singleton. + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeApp.class.php 4623 2007-07-16 12:34:38Z fabien $ + */ +class pakeApp +{ + const VERSION = '1.1.DEV'; + + private static $MAX_LINE_SIZE = 65; + private static $PROPERTIES = array(); + private static $PAKEFILES = array('pakefile', 'Pakefile', 'pakefile.php', 'Pakefile.php'); + private static $PLUGINDIRS = array(); + private static $OPTIONS = array( + array('--dry-run', '-n', pakeGetopt::NO_ARGUMENT, "Do a dry run without executing actions."), + array('--help', '-H', pakeGetopt::NO_ARGUMENT, "Display this help message."), + array('--libdir', '-I', pakeGetopt::REQUIRED_ARGUMENT, "Include LIBDIR in the search path for required modules."), + array('--nosearch', '-N', pakeGetopt::NO_ARGUMENT, "Do not search parent directories for the pakefile."), + array('--prereqs', '-P', pakeGetopt::NO_ARGUMENT, "Display the tasks and dependencies, then exit."), + array('--quiet', '-q', pakeGetopt::NO_ARGUMENT, "Do not log messages to standard output."), + array('--pakefile', '-f', pakeGetopt::REQUIRED_ARGUMENT, "Use FILE as the pakefile."), + array('--require', '-r', pakeGetopt::REQUIRED_ARGUMENT, "Require MODULE before executing pakefile."), + array('--tasks', '-T', pakeGetopt::NO_ARGUMENT, "Display the tasks and dependencies, then exit."), + array('--trace', '-t', pakeGetopt::NO_ARGUMENT, "Turn on invoke/execute tracing, enable full backtrace."), + array('--usage', '-h', pakeGetopt::NO_ARGUMENT, "Display usage."), + array('--verbose', '-v', pakeGetopt::NO_ARGUMENT, "Log message to standard output (default)."), + array('--version', '-V', pakeGetopt::NO_ARGUMENT, "Display the program version."), + ); + + private $opt = null; + private $nosearch = false; + private $trace = false; + private $verbose = true; + private $dryrun = false; + private $nowrite = false; + private $show_tasks = false; + private $show_prereqs = false; + private $pakefile = ''; + private static $instance = null; + + private function __construct() + { + self::$PLUGINDIRS[] = dirname(__FILE__).'/tasks'; + } + + public static function get_plugin_dirs() + { + return self::$PLUGINDIRS; + } + + public function get_properties() + { + return self::$PROPERTIES; + } + + public function set_properties($properties) + { + self::$PROPERTIES = $properties; + } + + public static function get_instance() + { + if (!self::$instance) self::$instance = new pakeApp(); + + return self::$instance; + } + + public function get_verbose() + { + return $this->verbose; + } + + public function get_trace() + { + return $this->trace; + } + + public function get_dryrun() + { + return $this->dryrun; + } + + public function run($pakefile = null, $options = null, $load_pakefile = true) + { + if ($pakefile) + { + pakeApp::$PAKEFILES = array($pakefile); + } + + $this->handle_options($options); + if ($load_pakefile) + { + $this->load_pakefile(); + } + + if ($this->show_tasks) + { + $this->display_tasks_and_comments(); + } + else if ($this->show_prereqs) + { + $this->display_prerequisites(); + } + else + { + $args = $this->opt->get_arguments(); + $task = array_shift($args); + + $options = array(); + for ($i = 0, $max = count($args); $i < $max; $i++) + { + if (0 === strpos($args[$i], '--')) + { + if (false !== $pos = strpos($args[$i], '=')) + { + $key = substr($args[$i], 2, $pos - 2); + $value = substr($args[$i], $pos + 1); + } + else + { + $key = substr($args[$i], 2); + $value = true; + } + if ('[]' == substr($key, -2)) + { + if (!isset($options[$key])) + { + $options[$key] = array(); + } + $options[$key][] = $value; + } + else + { + $options[$key] = $value; + } + unset($args[$i]); + } + } + $args = array_values($args); + + $abbrev_options = $this->abbrev(array_keys(pakeTask::get_tasks())); + $task = pakeTask::get_full_task_name($task); + if (!$task) + { + $task = 'default'; + } + + if (!array_key_exists($task, $abbrev_options)) + { + throw new pakeException(sprintf('Task "%s" is not defined.', $task)); + } + else if (count($abbrev_options[$task]) > 1) + { + throw new pakeException(sprintf('Task "%s" is ambiguous (%s).', $task, implode(', ', $abbrev_options[$task]))); + } + else + { + return pakeTask::get($abbrev_options[$task][0])->invoke($args, $options); + } + } + } + + // Read and handle the command line options. + public function handle_options($options = null) + { + $this->opt = new pakeGetopt(pakeApp::$OPTIONS); + $this->opt->parse($options); + foreach ($this->opt->get_options() as $opt => $value) + { + $this->do_option($opt, $value); + } + } + + // True if one of the files in RAKEFILES is in the current directory. + // If a match is found, it is copied into @pakefile. + public function have_pakefile() + { + foreach (pakeApp::$PAKEFILES as $file) + { + if (file_exists($file)) + { + $this->pakefile = $file; + return true; + } + } + + return false; + } + + public function load_pakefile() + { + $here = getcwd(); + while (!$this->have_pakefile()) + { + chdir('..'); + if (getcwd() == $here || $this->nosearch) + { + throw new pakeException(sprintf('No pakefile found (looking for: %s)', join(', ', pakeApp::$PAKEFILES))."\n"); + } + + $here = getcwd(); + } + + require_once($this->pakefile); + } + + // Do the option defined by +opt+ and +value+. + public function do_option($opt, $value) + { + switch ($opt) + { + case 'dry-run': + $this->verbose = true; + $this->nowrite = true; + $this->dryrun = true; + $this->trace = true; + break; + case 'help': + $this->help(); + exit(); + case 'libdir': + set_include_path($value.PATH_SEPARATOR.get_include_path()); + break; + case 'nosearch': + $this->nosearch = true; + break; + case 'prereqs': + $this->show_prereqs = true; + break; + case 'quiet': + $this->verbose = false; + break; + case 'pakefile': + pakeApp::$PAKEFILES = array($value); + break; + case 'require': + require $value; + break; + case 'tasks': + $this->show_tasks = true; + break; + case 'trace': + $this->trace = true; + $this->verbose = true; + break; + case 'usage': + $this->usage(); + exit(); + case 'verbose': + $this->verbose = true; + break; + case 'version': + echo sprintf('pake version %s', pakeColor::colorize(pakeApp::VERSION, 'INFO'))."\n"; + exit(); + default: + throw new pakeException(sprintf("Unknown option: %s", $opt)); + } + } + + // Display the program usage line. + public function usage() + { + echo "pake [-f pakefile] {options} targets...\n".pakeColor::colorize("Try pake -H for more information", 'INFO')."\n"; + } + + // Display the rake command line help. + public function help() + { + $this->usage(); + echo "\n"; + echo "available options:"; + echo "\n"; + + foreach (pakeApp::$OPTIONS as $option) + { + list($long, $short, $mode, $comment) = $option; + if ($mode == pakeGetopt::REQUIRED_ARGUMENT) + { + if (preg_match('/\b([A-Z]{2,})\b/', $comment, $match)) + $long .= '='.$match[1]; + } + printf(" %-20s (%s)\n", pakeColor::colorize($long, 'INFO'), pakeColor::colorize($short, 'INFO')); + printf(" %s\n", $comment); + } + } + + // Display the tasks and dependencies. + public function display_tasks_and_comments() + { + $width = 0; + $tasks = pakeTask::get_tasks(); + foreach ($tasks as $name => $task) + { + $w = strlen(pakeTask::get_mini_task_name($name)); + if ($w > $width) $width = $w; + } + $width += strlen(pakeColor::colorize(' ', 'INFO')); + + echo "available pake tasks:\n"; + + // display tasks + $has_alias = false; + ksort($tasks); + foreach ($tasks as $name => $task) + { + if ($task->get_alias()) + { + $has_alias = true; + } + + if (!$task->get_alias() && $task->get_comment()) + { + $mini_name = pakeTask::get_mini_task_name($name); + printf(' %-'.$width.'s > %s'."\n", pakeColor::colorize($mini_name, 'INFO'), $task->get_comment().($mini_name != $name ? ' ['.$name.']' : '')); + } + } + + if ($has_alias) + { + print("\ntask aliases:\n"); + + // display aliases + foreach ($tasks as $name => $task) + { + if ($task->get_alias()) + { + $mini_name = pakeTask::get_mini_task_name($name); + printf(' %-'.$width.'s = pake %s'."\n", pakeColor::colorize(pakeTask::get_mini_task_name($name), 'INFO'), $task->get_alias().($mini_name != $name ? ' ['.$name.']' : '')); + } + } + } + } + + // Display the tasks and prerequisites + public function display_prerequisites() + { + foreach (pakeTask::get_tasks() as $name => $task) + { + echo "pake ".pakeTask::get_mini_task_name($name)."\n"; + foreach ($task->get_prerequisites() as $prerequisite) + { + echo " $prerequisite\n"; + } + } + } + + public static function get_files_from_argument($arg, $target_dir = '', $relative = false) + { + $files = array(); + if (is_array($arg)) + { + $files = $arg; + } + else if (is_string($arg)) + { + $files[] = $arg; + } + else if ($arg instanceof pakeFinder) + { + $files = $arg->in($target_dir); + } + else + { + throw new pakeException('Wrong argument type (must be a list, a string or a pakeFinder object).'); + } + + if ($relative && $target_dir) + { + $files = preg_replace('/^'.preg_quote(realpath($target_dir), '/').'/', '', $files); + + // remove leading / + $files = array_map(create_function('$f', 'return 0 === strpos($f, DIRECTORY_SEPARATOR) ? substr($f, 1) : $f;'), $files); + } + + return $files; + } + + public static function excerpt($text, $size = null) + { + if (!$size) + { + $size = self::$MAX_LINE_SIZE; + } + + if (strlen($text) < $size) + { + return $text; + } + + $subsize = floor(($size - 3) / 2); + + return substr($text, 0, $subsize).pakeColor::colorize('...', 'INFO').substr($text, -$subsize); + } + + /* see perl Text::Abbrev module */ + private function abbrev($options) + { + $abbrevs = array(); + $table = array(); + + foreach ($options as $option) + { + $option = pakeTask::get_mini_task_name($option); + + for ($len = (strlen($option)) - 1; $len > 0; --$len) + { + $abbrev = substr($option, 0, $len); + if (!array_key_exists($abbrev, $table)) + $table[$abbrev] = 1; + else + ++$table[$abbrev]; + + $seen = $table[$abbrev]; + if ($seen == 1) + { + // we're the first word so far to have this abbreviation. + $abbrevs[$abbrev] = array($option); + } + else if ($seen == 2) + { + // we're the second word to have this abbreviation, so we can't use it. + //unset($abbrevs[$abbrev]); + $abbrevs[$abbrev][] = $option; + } + else + { + // we're the third word to have this abbreviation, so skip to the next word. + continue; + } + } + } + + // Non-abbreviations always get entered, even if they aren't unique + foreach ($options as $option) + { + $abbrevs[$option] = array($option); + } + + return $abbrevs; + } +} diff --git a/gulliver/thirdparty/pake/pakeColor.class.php b/gulliver/thirdparty/pake/pakeColor.class.php new file mode 100644 index 000000000..026fb104d --- /dev/null +++ b/gulliver/thirdparty/pake/pakeColor.class.php @@ -0,0 +1,72 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeColor.class.php 2990 2006-12-09 11:10:59Z fabien $ + */ + +/** + * + * main pake class. + * + * This class is a singleton. + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeColor.class.php 2990 2006-12-09 11:10:59Z fabien $ + */ +class pakeColor +{ + static public $styles = array(); + + static function style($name, $options = array()) + { + self::$styles[$name] = $options; + } + + static function colorize($text = '', $parameters = array(), $stream = STDOUT) + { + // disable colors if not supported (windows or non tty console) + if (DIRECTORY_SEPARATOR == '\\' || !function_exists('posix_isatty') || !@posix_isatty($stream)) + { + return $text; + } + + static $options = array('bold' => 1, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, 'conceal' => 8); + static $foreground = array('black' => 30, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37); + static $background = array('black' => 40, 'red' => 41, 'green' => 42, 'yellow' => 43, 'blue' => 44, 'magenta' => 45, 'cyan' => 46, 'white' => 47); + + if (!is_array($parameters) && isset(self::$styles[$parameters])) + { + $parameters = self::$styles[$parameters]; + } + + $codes = array(); + if (isset($parameters['fg'])) + { + $codes[] = $foreground[$parameters['fg']]; + } + if (isset($parameters['bg'])) + { + $codes[] = $background[$parameters['bg']]; + } + foreach ($options as $option => $value) + { + if (isset($parameters[$option]) && $parameters[$option]) + { + $codes[] = $value; + } + } + + return "\033[".implode(';', $codes).'m'.$text."\033[0m"; + } +} + +pakeColor::style('ERROR', array('bg' => 'red', 'fg' => 'white', 'bold' => true)); +pakeColor::style('INFO', array('fg' => 'green', 'bold' => true)); +pakeColor::style('COMMENT', array('fg' => 'yellow')); diff --git a/gulliver/thirdparty/pake/pakeException.class.php b/gulliver/thirdparty/pake/pakeException.class.php new file mode 100644 index 000000000..86b72ec1a --- /dev/null +++ b/gulliver/thirdparty/pake/pakeException.class.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * pakeException is the base class for all pake related exceptions and + * provides an additional method for printing up a detailed view of an + * exception. + * + * @package pake + * @author Fabien Potencier + * @version SVN: $Id: pakeException.class.php 2795 2006-11-23 19:51:21Z fabien $ + */ +class pakeException extends Exception +{ + public static function strlen($string) + { + return function_exists('mb_strlen') ? mb_strlen($string) : strlen($string); + } + + function render($e) + { + $title = ' ['.get_class($e).'] '; + $len = self::strlen($title); + $lines = array(); + foreach (explode("\n", $e->getMessage()) as $line) + { + $lines[] = ' '.$line.' '; + $len = max(self::strlen($line) + 4, $len); + } + $messages = array( + str_repeat(' ', $len), + $title.str_repeat(' ', $len - self::strlen($title)), + ); + + foreach ($lines as $line) + { + $messages[] = $line.str_repeat(' ', $len - self::strlen($line)); + } + + $messages[] = str_repeat(' ', $len); + + fwrite(STDERR, "\n"); + foreach ($messages as $message) + { + fwrite(STDERR, pakeColor::colorize($message, 'ERROR', STDERR)."\n"); + } + fwrite(STDERR, "\n"); + + $pake = pakeApp::get_instance(); + + if ($pake->get_trace()) + { + fwrite(STDERR, "exception trace:\n"); + + $trace = $this->trace($e); + for ($i = 0, $count = count($trace); $i < $count; $i++) + { + $class = (isset($trace[$i]['class']) ? $trace[$i]['class'] : ''); + $type = (isset($trace[$i]['type']) ? $trace[$i]['type'] : ''); + $function = $trace[$i]['function']; + $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; + $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; + + fwrite(STDERR, sprintf(" %s%s%s at %s:%s\n", $class, $type, $function, pakeColor::colorize($file, 'INFO', STDERR), pakeColor::colorize($line, 'INFO', STDERR))); + } + } + + fwrite(STDERR, "\n"); + } + + function trace($exception) + { + // exception related properties + $trace = $exception->getTrace(); + array_unshift($trace, array( + 'function' => '', + 'file' => ($exception->getFile() != null) ? $exception->getFile() : 'n/a', + 'line' => ($exception->getLine() != null) ? $exception->getLine() : 'n/a', + 'args' => array(), + )); + + return $trace; + } +} diff --git a/gulliver/thirdparty/pake/pakeFileTask.class.php b/gulliver/thirdparty/pake/pakeFileTask.class.php new file mode 100644 index 000000000..9bc1848c6 --- /dev/null +++ b/gulliver/thirdparty/pake/pakeFileTask.class.php @@ -0,0 +1,64 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeFileTask.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +/** + * + * . + * + * . + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeFileTask.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ +class pakeFileTask extends pakeTask +{ + public function is_needed() + { + if (!file_exists($this->get_name())) return true; + $latest_prereq = 0; + foreach ($this->prerequisites as $prerequisite) + { + $t = pakeTask::get($prerequisite)->timestamp(); + if ($t > $latest_prereq) + { + $latest_prereq = $t; + } + } + + if ($latest_prereq == 0) + { + return false; + } + + return ($this->timestamp() < $latest_prereq); + } + + public function timestamp() + { + if (!file_exists($this->get_name())) + { + throw new pakeException(sprintf('File "%s" does not exist!', $this->get_name())); + } + + $stats = stat($this->get_name()); + + return $stats['mtime']; + } + + public static function define_task($name, $deps = null) + { + $task = pakeTask::lookup($name, 'pakeFileTask'); + $task->add_comment(); + $task->enhance($deps); + } +} diff --git a/gulliver/thirdparty/pake/pakeFinder.class.php b/gulliver/thirdparty/pake/pakeFinder.class.php new file mode 100644 index 000000000..b0ddddf0b --- /dev/null +++ b/gulliver/thirdparty/pake/pakeFinder.class.php @@ -0,0 +1,538 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $ + */ + +require_once dirname(__FILE__).'/pakeGlobToRegex.class.php'; +require_once dirname(__FILE__).'/pakeNumberCompare.class.php'; + +if (class_exists('pakeFinder')) +{ + return; +} + +/** + * + * Allow to build rules to find files and directories. + * + * All rules may be invoked several times, except for ->in() method. + * Some rules are cumulative (->name() for example) whereas others are destructive + * (most recent value is used, ->maxdepth() method for example). + * + * All methods return the current pakeFinder object to allow easy chaining: + * + * $files = pakeFinder::type('file')->name('*.php')->in(.); + * + * Interface loosely based on perl File::Find::Rule module. + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $ + */ +class pakeFinder +{ + private $type = 'file'; + private $names = array(); + private $prunes = array(); + private $discards = array(); + private $execs = array(); + private $mindepth = 0; + private $sizes = array(); + private $maxdepth = 1000000; + private $relative = false; + private $follow_link = false; + private $search_dir = ''; + + /** + * Sets maximum directory depth. + * + * Finder will descend at most $level levels of directories below the starting point. + * + * @param integer level + * @return object current pakeFinder object + */ + public function maxdepth($level) + { + $this->maxdepth = $level; + + return $this; + } + + /** + * Sets minimum directory depth. + * + * Finder will start applying tests at level $level. + * + * @param integer level + * @return object current pakeFinder object + */ + public function mindepth($level) + { + $this->mindepth = $level; + + return $this; + } + + public function get_type() + { + return $this->type; + } + + /** + * Sets the type of elements to returns. + * + * @param string directory or file or any (for both file and directory) + * @return object new pakeFinder object + */ + public static function type($name) + { + $finder = new pakeFinder(); + + if (strtolower(substr($name, 0, 3)) == 'dir') + { + $finder->type = 'directory'; + } + else if (strtolower($name) == 'any') + { + $finder->type = 'any'; + } + else + { + $finder->type = 'file'; + } + + return $finder; + } + + /* + * glob, patterns (must be //) or strings + */ + private function to_regex($str) + { + if ($str[0] == '/' && $str[strlen($str) - 1] == '/') + { + return $str; + } + else + { + return pakeGlobToRegex::glob_to_regex($str); + } + } + + private function args_to_array($arg_list, $not = false) + { + $list = array(); + + for ($i = 0; $i < count($arg_list); $i++) + { + if (is_array($arg_list[$i])) + { + foreach ($arg_list[$i] as $arg) + { + $list[] = array($not, $this->to_regex($arg)); + } + } + else + { + $list[] = array($not, $this->to_regex($arg_list[$i])); + } + } + + return $list; + } + + /** + * Adds rules that files must match. + * + * You can use patterns (delimited with / sign), globs or simple strings. + * + * $finder->name('*.php') + * $finder->name('/\.php$/') // same as above + * $finder->name('test.php') + * + * @param list a list of patterns, globs or strings + * @return object current pakeFinder object + */ + public function name() + { + $args = func_get_args(); + $this->names = array_merge($this->names, $this->args_to_array($args)); + + return $this; + } + + /** + * Adds rules that files must not match. + * + * @see ->name() + * @param list a list of patterns, globs or strings + * @return object current pakeFinder object + */ + public function not_name() + { + $args = func_get_args(); + $this->names = array_merge($this->names, $this->args_to_array($args, true)); + + return $this; + } + + /** + * Adds tests for file sizes. + * + * $finder->size('> 10K'); + * $finder->size('<= 1Ki'); + * $finder->size(4); + * + * @param list a list of comparison strings + * @return object current pakeFinder object + */ + public function size() + { + $args = func_get_args(); + for ($i = 0; $i < count($args); $i++) + { + $this->sizes[] = new pakeNumberCompare($args[$i]); + } + + return $this; + } + + /** + * Traverses no further. + * + * @param list a list of patterns, globs to match + * @return object current pakeFinder object + */ + public function prune() + { + $args = func_get_args(); + $this->prunes = array_merge($this->prunes, $this->args_to_array($args)); + + return $this; + } + + /** + * Discards elements that matches. + * + * @param list a list of patterns, globs to match + * @return object current pakeFinder object + */ + public function discard() + { + $args = func_get_args(); + $this->discards = array_merge($this->discards, $this->args_to_array($args)); + + return $this; + } + + /** + * Ignores version control directories. + * + * Currently supports subversion, CVS, DARCS, Gnu Arch, Monotone, Bazaar-NG + * + * @return object current pakeFinder object + */ + public function ignore_version_control() + { + $ignores = array('.svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr'); + + return $this->discard($ignores)->prune($ignores); + } + + /** + * Executes function or method for each element. + * + * Element match if functino or method returns true. + * + * $finder->exec('myfunction'); + * $finder->exec(array($object, 'mymethod')); + * + * @param mixed function or method to call + * @return object current pakeFinder object + */ + public function exec() + { + $args = func_get_args(); + for ($i = 0; $i < count($args); $i++) + { + if (is_array($args[$i]) && !method_exists($args[$i][0], $args[$i][1])) + { + throw new pakeException(sprintf("Method %s does not exist for object %s.", $args[$i][1], $args[$i][0])); + } + else if (!is_array($args[$i]) && !function_exists($args[$i])) + { + throw new pakeException(sprintf("Function %s does not exist.", $args[$i])); + } + + $this->execs[] = $args[$i]; + } + + return $this; + } + + /** + * Returns relative paths for all files and directories. + * + * @return object current pakeFinder object + */ + public function relative() + { + $this->relative = true; + + return $this; + } + + /** + * Symlink following. + * + * @return object current sfFinder object + */ + public function follow_link() + { + $this->follow_link = true; + + return $this; + } + + /** + * Searches files and directories which match defined rules. + * + * @return array list of files and directories + */ + public function in() + { + $files = array(); + $here_dir = getcwd(); + $numargs = func_num_args(); + $arg_list = func_get_args(); + + // first argument is an array? + if ($numargs == 1 && is_array($arg_list[0])) + { + $arg_list = $arg_list[0]; + $numargs = count($arg_list); + } + + $dirs = array(); + for ($i = 0; $i < $numargs; $i++) + { + if ($argDirs = glob($arg_list[$i])) + { + $dirs = array_merge($dirs, $argDirs); + } + } + + foreach ($dirs as $dir) + { + $real_dir = realpath($dir); + + // absolute path? + if (!self::isPathAbsolute($real_dir)) + { + $dir = $here_dir.DIRECTORY_SEPARATOR.$real_dir; + } + else + { + $dir = $real_dir; + } + + if (!is_dir($real_dir)) + { + continue; + } + + $this->search_dir = $dir; + + if ($this->relative) + { + $files = array_merge($files, str_replace($dir.DIRECTORY_SEPARATOR, '', $this->search_in($dir))); + } + else + { + $files = array_merge($files, $this->search_in($dir)); + } + } + + return array_unique($files); + } + + private function search_in($dir, $depth = 0) + { + if ($depth > $this->maxdepth) + { + return array(); + } + + if (is_link($dir) && !$this->follow_link) + { + return array(); + } + + $files = array(); + + if (is_dir($dir)) + { + $current_dir = opendir($dir); + while (false !== $entryname = readdir($current_dir)) + { + if ($entryname == '.' || $entryname == '..') continue; + + $current_entry = $dir.DIRECTORY_SEPARATOR.$entryname; + if (is_link($current_entry) && !$this->follow_link) + { + continue; + } + + if (is_dir($current_entry)) + { + if (($this->type == 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->exec_ok($dir, $entryname)) + { + $files[] = realpath($current_entry); + } + + if (!$this->is_pruned($dir, $entryname)) + { + $files = array_merge($files, $this->search_in($current_entry, $depth + 1)); + } + } + else + { + if (($this->type != 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->size_ok($dir, $entryname) && $this->exec_ok($dir, $entryname)) + { + $files[] = realpath($current_entry); + } + } + } + closedir($current_dir); + } + + return $files; + } + + private function match_names($dir, $entry) + { + if (!count($this->names)) return true; + + // we must match one "not_name" rules to be ko + $one_not_name_rule = false; + foreach ($this->names as $args) + { + list($not, $regex) = $args; + if ($not) + { + $one_not_name_rule = true; + if (preg_match($regex, $entry)) + { + return false; + } + } + } + + $one_name_rule = false; + // we must match one "name" rules to be ok + foreach ($this->names as $args) + { + list($not, $regex) = $args; + if (!$not) + { + $one_name_rule = true; + if (preg_match($regex, $entry)) + { + return true; + } + } + } + + if ($one_not_name_rule && $one_name_rule) + { + return false; + } + else if ($one_not_name_rule) + { + return true; + } + else if ($one_name_rule) + { + return false; + } + else + { + return true; + } + } + + private function size_ok($dir, $entry) + { + if (!count($this->sizes)) return true; + + if (!is_file($dir.DIRECTORY_SEPARATOR.$entry)) return true; + + $filesize = filesize($dir.DIRECTORY_SEPARATOR.$entry); + foreach ($this->sizes as $number_compare) + { + if (!$number_compare->test($filesize)) return false; + } + + return true; + } + + private function is_pruned($dir, $entry) + { + if (!count($this->prunes)) return false; + + foreach ($this->prunes as $args) + { + $regex = $args[1]; + if (preg_match($regex, $entry)) return true; + } + + return false; + } + + private function is_discarded($dir, $entry) + { + if (!count($this->discards)) return false; + + foreach ($this->discards as $args) + { + $regex = $args[1]; + if (preg_match($regex, $entry)) return true; + } + + return false; + } + + private function exec_ok($dir, $entry) + { + if (!count($this->execs)) return true; + + foreach ($this->execs as $exec) + { + if (!call_user_func_array($exec, array($dir, $entry))) return false; + } + + return true; + } + + public static function isPathAbsolute($path) + { + if ($path{0} == '/' || $path{0} == '\\' || + (strlen($path) > 3 && ctype_alpha($path{0}) && + $path{1} == ':' && + ($path{2} == '\\' || $path{2} == '/') + ) + ) + { + return true; + } + + return false; + } +} diff --git a/gulliver/thirdparty/pake/pakeFunction.php b/gulliver/thirdparty/pake/pakeFunction.php new file mode 100644 index 000000000..40f36d33e --- /dev/null +++ b/gulliver/thirdparty/pake/pakeFunction.php @@ -0,0 +1,429 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeFunction.php 3263 2007-01-13 14:20:52Z fabien $ + */ + +require_once dirname(__FILE__).'/pakeException.class.php'; +require_once dirname(__FILE__).'/pakeYaml.class.php'; +require_once dirname(__FILE__).'/pakeGetopt.class.php'; +require_once dirname(__FILE__).'/pakeFinder.class.php'; +require_once dirname(__FILE__).'/pakeTask.class.php'; +require_once dirname(__FILE__).'/pakeFileTask.class.php'; +require_once dirname(__FILE__).'/pakeColor.class.php'; +require_once dirname(__FILE__).'/pakeApp.class.php'; + +function pake_import($name, $import_default_tasks = true) +{ + $class_name = 'pake'.ucfirst(strtolower($name)).'Task'; + + if (!class_exists($class_name)) + { + // plugin available? + $plugin_path = ''; + foreach (pakeApp::get_plugin_dirs() as $dir) + { + if (file_exists($dir.DIRECTORY_SEPARATOR.$class_name.'.class.php')) + { + $plugin_path = $dir.DIRECTORY_SEPARATOR.$class_name.'.class.php'; + break; + } + } + + if ($plugin_path) + { + require_once $plugin_path; + } + else + { + throw new pakeException(sprintf('Plugin "%s" does not exist.', $name)); + } + } + + if ($import_default_tasks && is_callable($class_name, 'import_default_tasks')) + { + call_user_func(array($class_name, 'import_default_tasks')); + } +} + +function pake_task($name) +{ + $args = func_get_args(); + array_shift($args); + pakeTask::define_task($name, $args); + + return $name; +} + +function pake_alias($alias, $name) +{ + pakeTask::define_alias($alias, $name); + + return $alias; +} + +function pake_desc($comment) +{ + pakeTask::define_comment($comment); +} + +function pake_properties($property_file) +{ + $file = $property_file; + if (!pakeFinder::isPathAbsolute($file)) + { + $file = getcwd().DIRECTORY_SEPARATOR.$property_file; + } + + if (file_exists($file)) + { + pakeApp::get_instance()->set_properties(parse_ini_file($file, true)); + } + else + { + throw new pakeException('Properties file does not exist.'); + } +} + +function pake_file($name) +{ + $args = func_get_args(); + array_shift($args); + pakeFileTask::define_task($name, $args); + + return $name; +} + +function pake_mkdirs($path, $mode = 0777) +{ + if (is_dir($path)) + { + return true; + } + + pake_echo_action('dir+', $path); + + return @mkdir($path, $mode, true); +} + +/* + override => boolean +*/ +function pake_copy($origin_file, $target_file, $options = array()) +{ + if (!array_key_exists('override', $options)) + { + $options['override'] = false; + } + + // we create target_dir if needed + if (!is_dir(dirname($target_file))) + { + pake_mkdirs(dirname($target_file)); + } + + $most_recent = false; + if (file_exists($target_file)) + { + $stat_target = stat($target_file); + $stat_origin = stat($origin_file); + $most_recent = ($stat_origin['mtime'] > $stat_target['mtime']) ? true : false; + } + + if ($options['override'] || !file_exists($target_file) || $most_recent) + { + pake_echo_action('file+', $target_file); + copy($origin_file, $target_file); + } +} + +function pake_rename($origin, $target, $options = array()) +{ + // we check that target does not exist + if (is_readable($target)) + { + throw new pakeException(sprintf('Cannot rename because the target "%" already exist.', $target)); + } + + pake_echo_action('rename', $origin.' > '.$target); + rename($origin, $target); +} + +function pake_mirror($arg, $origin_dir, $target_dir, $options = array()) +{ + $files = pakeApp::get_files_from_argument($arg, $origin_dir, true); + + foreach ($files as $file) + { + if (is_dir($origin_dir.DIRECTORY_SEPARATOR.$file)) + { + pake_mkdirs($target_dir.DIRECTORY_SEPARATOR.$file); + } + else if (is_file($origin_dir.DIRECTORY_SEPARATOR.$file)) + { + pake_copy($origin_dir.DIRECTORY_SEPARATOR.$file, $target_dir.DIRECTORY_SEPARATOR.$file, $options); + } + else if (is_link($origin_dir.DIRECTORY_SEPARATOR.$file)) + { + pake_symlink($origin_dir.DIRECTORY_SEPARATOR.$file, $target_dir.DIRECTORY_SEPARATOR.$file); + } + else + { + throw new pakeException(sprintf('Unable to determine "%s" type', $file)); + } + } +} + +function pake_remove($arg, $target_dir) +{ + $files = array_reverse(pakeApp::get_files_from_argument($arg, $target_dir)); + + foreach ($files as $file) + { + if (is_dir($file) && !is_link($file)) + { + pake_echo_action('dir-', $file); + + rmdir($file); + } + else + { + pake_echo_action(is_link($file) ? 'link-' : 'file-', $file); + + unlink($file); + } + } +} + +function pake_touch($arg, $target_dir) +{ + $files = pakeApp::get_files_from_argument($arg, $target_dir); + + foreach ($files as $file) + { + pake_echo_action('file+', $file); + + touch($file); + } +} + +function pake_replace_tokens($arg, $target_dir, $begin_token, $end_token, $tokens) +{ + $files = pakeApp::get_files_from_argument($arg, $target_dir, true); + + foreach ($files as $file) + { + $replaced = false; + $content = file_get_contents($target_dir.DIRECTORY_SEPARATOR.$file); + foreach ($tokens as $key => $value) + { + $content = str_replace($begin_token.$key.$end_token, $value, $content, $count); + if ($count) $replaced = true; + } + + pake_echo_action('tokens', $target_dir.DIRECTORY_SEPARATOR.$file); + + file_put_contents($target_dir.DIRECTORY_SEPARATOR.$file, $content); + } +} + +function pake_symlink($origin_dir, $target_dir, $copy_on_windows = false) +{ + if (!function_exists('symlink') && $copy_on_windows) + { + $finder = pakeFinder::type('any')->ignore_version_control(); + pake_mirror($finder, $origin_dir, $target_dir); + return; + } + + $ok = false; + if (is_link($target_dir)) + { + if (readlink($target_dir) != $origin_dir) + { + unlink($target_dir); + } + else + { + $ok = true; + } + } + + if (!$ok) + { + pake_echo_action('link+', $target_dir); + symlink($origin_dir, $target_dir); + } +} + +function pake_chmod($arg, $target_dir, $mode, $umask = 0000) +{ + $current_umask = umask(); + umask($umask); + + $files = pakeApp::get_files_from_argument($arg, $target_dir, true); + + foreach ($files as $file) + { + pake_echo_action(sprintf('chmod %o', $mode), $target_dir.DIRECTORY_SEPARATOR.$file); + chmod($target_dir.DIRECTORY_SEPARATOR.$file, $mode); + } + + umask($current_umask); +} + +function pake_sh($cmd) +{ + $verbose = pakeApp::get_instance()->get_verbose(); + pake_echo_action('exec ', $cmd); + + ob_start(); + passthru($cmd.' 2>&1', $return); + $content = ob_get_contents(); + ob_end_clean(); + + if ($return > 0) + { + throw new pakeException(sprintf('Problem executing command %s', $verbose ? "\n".$content : '')); + } + + return $content; +} + +function pake_strip_php_comments($arg) +{ + /* T_ML_COMMENT does not exist in PHP 5. + * The following three lines define it in order to + * preserve backwards compatibility. + * + * The next two lines define the PHP 5-only T_DOC_COMMENT, + * which we will mask as T_ML_COMMENT for PHP 4. + */ + if (!defined('T_ML_COMMENT')) + { + define('T_ML_COMMENT', T_COMMENT); + } + else + { + if (!defined('T_DOC_COMMENT')) define('T_DOC_COMMENT', T_ML_COMMENT); + } + + $files = pakeApp::get_files_from_argument($arg); + + foreach ($files as $file) + { + if (!is_file($file)) continue; + + $source = file_get_contents($file); + $output = ''; + + $tokens = token_get_all($source); + foreach ($tokens as $token) + { + if (is_string($token)) + { + // simple 1-character token + $output .= $token; + } + else + { + // token array + list($id, $text) = $token; + switch ($id) + { + case T_COMMENT: + case T_ML_COMMENT: // we've defined this + case T_DOC_COMMENT: // and this + // no action on comments + break; + default: + // anything else -> output "as is" + $output .= $text; + break; + } + } + } + + file_put_contents($file, $output); + } +} + +function pake_format_action($section, $text, $size = null) +{ + if (pakeApp::get_instance()->get_verbose()) + { + $width = 9 + strlen(pakeColor::colorize('', 'INFO')); + return sprintf('>> %-'.$width.'s %s', pakeColor::colorize($section, 'INFO'), pakeApp::excerpt($text, $size))."\n"; + } +} + +function pake_echo_action($section, $text) +{ + echo pake_format_action($section, $text); +} + +function pake_excerpt($text) +{ + if (pakeApp::get_instance()->get_verbose()) + { + echo pakeApp::excerpt($text)."\n"; + } +} + +function pake_echo($text) +{ + if (pakeApp::get_instance()->get_verbose()) + { + echo $text."\n"; + } +} + +function pake_echo_comment($text) +{ + if (pakeApp::get_instance()->get_verbose()) + { + echo sprintf(pakeColor::colorize(' # %s', 'COMMENT'), $text)."\n"; + } +} + +// register our default exception handler +function pake_exception_default_handler($exception) +{ + $e = new pakeException(); + $e->render($exception); + exit(1); +} +set_exception_handler('pake_exception_default_handler'); + +// fix php behavior if using cgi php +// from http://www.sitepoint.com/article/php-command-line-1/3 +if (false !== strpos(PHP_SAPI, 'cgi')) +{ + // handle output buffering + @ob_end_flush(); + ob_implicit_flush(true); + + // PHP ini settings + set_time_limit(0); + ini_set('track_errors', true); + ini_set('html_errors', false); + ini_set('magic_quotes_runtime', false); + + // define stream constants + define('STDIN', fopen('php://stdin', 'r')); + define('STDOUT', fopen('php://stdout', 'w')); + define('STDERR', fopen('php://stderr', 'w')); + + // change directory + if (isset($_SERVER['PWD'])) + { + chdir($_SERVER['PWD']); + } + + // close the streams on script termination + register_shutdown_function(create_function('', 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;')); +} diff --git a/gulliver/thirdparty/pake/pakeGetopt.class.php b/gulliver/thirdparty/pake/pakeGetopt.class.php new file mode 100644 index 000000000..9ceb8ced3 --- /dev/null +++ b/gulliver/thirdparty/pake/pakeGetopt.class.php @@ -0,0 +1,274 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeGetopt.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +if (class_exists('pakeGetopt')) +{ + return; +} + +/** + * + * Console options parsing class. + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeGetopt.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ +class pakeGetopt +{ + const NO_ARGUMENT = 0; + const REQUIRED_ARGUMENT = 1; + const OPTIONAL_ARGUMENT = 2; + private $short_options = array(); + private $long_options = array(); + private $args = ''; + private $options = array(); + private $arguments = array(); + + public function __construct($options) + { + $this->args = ''; + foreach ($options as $option) + { + if (!$option[0]) + { + throw new pakeException(sprintf("pakeGetopt: You must define a long option name! for option %s (%s).", $option[1], $option[3])); + } + + $this->add_option($option[0], $option[1], $option[2], $option[3]); + } + } + + public function add_option($long_opt, $short_opt, $mode = self::NO_ARGUMENT, $comment = '') + { + if ($long_opt{0} == '-' && $long_opt{1} == '-') + { + $long_opt = substr($long_opt, 2); + } + + if ($short_opt) + { + if ($short_opt{0} == '-') + { + $short_opt = substr($short_opt, 1); + } + $this->short_options[$short_opt] = array('mode' => $mode, 'comment' => $comment, 'name' => $long_opt); + } + + $this->long_options[$long_opt] = array('mode' => $mode, 'comment' => $comment, 'name' => $long_opt); + } + + public function parse($args = null) + { + if (is_string($args)) + { + // hack to split arguments with spaces : --test="with some spaces" + $args = preg_replace('/(\'|")(.+?)\\1/e', "str_replace(' ', '=PLACEHOLDER=', '\\2')", $args); + $args = preg_split('/\s+/', $args); + $args = str_replace('=PLACEHOLDER=', ' ', $args); + } + else if (!$args) + { + $args = $this->read_php_argv(); + + // we strip command line program + if (isset($args[0]) && $args[0]{0} != '-') + { + array_shift($args); + } + } + + $this->args = $args; + + $this->options = array(); + $this->arguments = array(); + + while ($arg = array_shift($this->args)) + { + /* '--' stop options parsing. */ + if ($arg == '--') + { + $this->arguments = array_merge($this->arguments, $this->args); + break; + } + + if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$this->long_options)) + { + $this->arguments = array_merge($this->arguments, array($arg), $this->args); + break; + } + elseif (strlen($arg) > 1 && $arg{1} == '-') + { + $this->parse_long_option(substr($arg, 2)); + } + else + { + $this->parse_short_option(substr($arg, 1)); + } + } + } + + public function has_option($option) + { + return (array_key_exists($option, $this->options) ? true : false); + } + + public function get_option($option) + { + // is it a long option? + if (array_key_exists($option, $this->long_options) && $this->long_options[$option]['mode'] != self::NO_ARGUMENT) + { + return (array_key_exists($option, $this->options) ? $this->options[$option] : ''); + } + else + { + throw new pakeException('pakeGetopt: You cannot get a value for a NO_ARGUMENT option.'); + } + } + + public function get_options() + { + return $this->options; + } + + public function get_arguments() + { + return $this->arguments; + } + + private function parse_short_option($arg) + { + for ($i = 0; $i < strlen($arg); $i++) + { + $opt = $arg{$i}; + $opt_arg = true; + + /* option exists? */ + if (!array_key_exists($opt, $this->short_options)) + { + throw new pakeException(sprintf("pakeGetopt: unrecognized option -%s.", $opt)); + } + + /* required or optional argument? */ + if ($this->short_options[$opt]['mode'] == self::REQUIRED_ARGUMENT) + { + if ($i + 1 < strlen($arg)) + { + $this->options[$this->short_options[$opt]['name']] = substr($arg, $i + 1); + break; + } + else + { + // take next element as argument (if it doesn't start with a -) + if (count($this->args) && $this->args[0]{0} != '-') + { + $this->options[$this->short_options[$opt]['name']] = array_shift($this->args); + break; + } + else + { + throw new pakeException(sprintf("pakeGetopt: option -%s requires an argument", $opt)); + } + } + } + else if ($this->short_options[$opt]['mode'] == self::OPTIONAL_ARGUMENT) + { + if (substr($arg, $i + 1) != '') + { + $this->options[$this->short_options[$opt]['name']] = substr($arg, $i + 1); + } + else + { + // take next element as argument (if it doesn't start with a -) + if (count($this->args) && $this->args[0]{0} != '-') + { + $this->options[$this->short_options[$opt]['name']] = array_shift($this->args); + } + else + { + $this->options[$this->short_options[$opt]['name']] = true; + } + } + + break; + } + + $this->options[$this->short_options[$opt]['name']] = $opt_arg; + } + } + + private function parse_long_option($arg) + { + @list($opt, $opt_arg) = explode('=', $arg); + + if (!$opt_arg) + { + $opt_arg = true; + } + + /* option exists? */ + if (!array_key_exists($opt, $this->long_options)) + { + throw new pakeException(sprintf("pakeGetopt: unrecognized option --%s.", $opt)); + } + + /* required or optional argument? */ + if ($this->long_options[$opt]['mode'] == self::REQUIRED_ARGUMENT) + { + if ($opt_arg) + { + $this->options[$this->long_options[$opt]['name']] = $opt_arg; + return; + } + else + { + throw new pakeException(sprintf("pakeGetopt: option --%s requires an argument.", $opt)); + } + } + else if ($this->long_options[$opt]['mode'] == self::OPTIONAL_ARGUMENT) + { + $this->options[$this->long_options[$opt]['name']] = $opt_arg; + return; + } + else + { + $this->options[$this->long_options[$opt]['name']] = true; + } + } + + /** + * Function from PEAR::Console_Getopt. + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @access public + * @return mixed the $argv PHP array + */ + private function read_php_argv() + { + global $argv; + if (!is_array($argv)) + { + if (!@is_array($_SERVER['argv'])) + { + if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) + { + throw new pakeException("pakeGetopt: Could not read cmd args (register_argc_argv=Off?)."); + } + + return $GLOBALS['HTTP_SERVER_VARS']['argv']; + } + return $_SERVER['argv']; + } + return $argv; + } +} diff --git a/gulliver/thirdparty/pake/pakeGlobToRegex.class.php b/gulliver/thirdparty/pake/pakeGlobToRegex.class.php new file mode 100644 index 000000000..f30ca35b6 --- /dev/null +++ b/gulliver/thirdparty/pake/pakeGlobToRegex.class.php @@ -0,0 +1,139 @@ + php port + * @author Richard Clamp perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeGlobToRegex.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +if (class_exists('pakeGlobToRegex')) +{ + return; +} + +/** + * + * Match globbing patterns against text. + * + * if match_glob("foo.*", "foo.bar") echo "matched\n"; + * + * // prints foo.bar and foo.baz + * $regex = glob_to_regex("foo.*"); + * for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t) + * { + * if (/$regex/) echo "matched: $car\n"; + * } + * + * pakeGlobToRegex implements glob(3) style matching that can be used to match + * against text, rather than fetching names from a filesystem. + * + * based on perl Text::Glob module. + * + * @package pake + * @author Fabien Potencier php port + * @author Richard Clamp perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeGlobToRegex.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ +class pakeGlobToRegex +{ + private static $strict_leading_dot = true; + private static $strict_wildcard_slash = true; + + public static function setStrictLeadingDot($boolean) + { + self::$strict_leading_dot = $boolean; + } + + public static function setStrictWildcardSlash($boolean) + { + self::$strict_wildcard_slash = $boolean; + } + + /** + * Returns a compiled regex which is the equiavlent of the globbing pattern. + * + * @param string glob pattern + * @return string regex + */ + public static function glob_to_regex($glob) + { + $first_byte = true; + $escaping = false; + $in_curlies = 0; + $regex = ''; + for ($i = 0; $i < strlen($glob); $i++) + { + $car = $glob[$i]; + if ($first_byte) + { + if (self::$strict_leading_dot && $car != '.') + { + $regex .= '(?=[^\.])'; + } + + $first_byte = false; + } + + if ($car == '/') + { + $first_byte = true; + } + + if ($car == '.' || $car == '(' || $car == ')' || $car == '|' || $car == '+' || $car == '^' || $car == '$') + { + $regex .= "\\$car"; + } + else if ($car == '*') + { + $regex .= ($escaping ? "\\*" : (self::$strict_wildcard_slash ? "[^/]*" : ".*")); + } + else if ($car == '?') + { + $regex .= ($escaping ? "\\?" : (self::$strict_wildcard_slash ? "[^/]" : ".")); + } + else if ($car == '{') + { + $regex .= ($escaping ? "\\{" : "("); + if (!$escaping) ++$in_curlies; + } + else if ($car == '}' && $in_curlies) + { + $regex .= ($escaping ? "}" : ")"); + if (!$escaping) --$in_curlies; + } + else if ($car == ',' && $in_curlies) + { + $regex .= ($escaping ? "," : "|"); + } + else if ($car == "\\") + { + if ($escaping) + { + $regex .= "\\\\"; + $escaping = false; + } + else + { + $escaping = true; + } + + continue; + } + else + { + $regex .= $car; + $escaping = false; + } + $escaping = false; + } + + return "#^$regex$#"; + } +} diff --git a/gulliver/thirdparty/pake/pakeNumberCompare.class.php b/gulliver/thirdparty/pake/pakeNumberCompare.class.php new file mode 100644 index 000000000..a954650bf --- /dev/null +++ b/gulliver/thirdparty/pake/pakeNumberCompare.class.php @@ -0,0 +1,120 @@ + php port + * @author Richard Clamp perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeNumberCompare.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +if (class_exists('pakeNumberCompare')) +{ + return; +} + +/** + * + * Numeric comparisons. + * + * sfNumberCompare compiles a simple comparison to an anonymous + * subroutine, which you can call with a value to be tested again. + + * Now this would be very pointless, if sfNumberCompare didn't understand + * magnitudes. + + * The target value may use magnitudes of kilobytes (C, C), + * megabytes (C, C), or gigabytes (C, C). Those suffixed + * with an C use the appropriate 2**n version in accordance with the + * IEC standard: http://physics.nist.gov/cuu/Units/binary.html + * + * based on perl Number::Compare module. + * + * @package pake + * @author Fabien Potencier php port + * @author Richard Clamp perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * @see http://physics.nist.gov/cuu/Units/binary.html + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeNumberCompare.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ +class pakeNumberCompare +{ + private $test = ''; + + public function __construct($test) + { + $this->test = $test; + } + + public function test($number) + { + if (!preg_match('{^([<>]=?)?(.*?)([kmg]i?)?$}i', $this->test, $matches)) + { + throw new pakeException(sprintf('Don\'t understand "%s" as a test.', $this->test)); + } + + $target = array_key_exists(2, $matches) ? $matches[2] : ''; + $magnitude = array_key_exists(3, $matches) ? $matches[3] : ''; + if (strtolower($magnitude) == 'k') $target *= 1000; + if (strtolower($magnitude) == 'ki') $target *= 1024; + if (strtolower($magnitude) == 'm') $target *= 1000000; + if (strtolower($magnitude) == 'mi') $target *= 1024*1024; + if (strtolower($magnitude) == 'g') $target *= 1000000000; + if (strtolower($magnitude) == 'gi') $target *= 1024*1024*1024; + + $comparison = array_key_exists(1, $matches) ? $matches[1] : '=='; + if ($comparison == '==' || $comparison == '') + { + return ($number == $target); + } + else if ($comparison == '>') + { + return ($number > $target); + } + else if ($comparison == '>=') + { + return ($number >= $target); + } + else if ($comparison == '<') + { + return ($number < $target); + } + else if ($comparison == '<=') + { + return ($number <= $target); + } + + return false; + } +} + +/* +=head1 SYNOPSIS + + Number::Compare->new(">1Ki")->test(1025); # is 1025 > 1024 + + my $c = Number::Compare->new(">1M"); + $c->(1_200_000); # slightly terser invocation + +=head1 DESCRIPTION + + +=head1 METHODS + +=head2 ->new( $test ) + +Returns a new object that compares the specified test. + +=head2 ->test( $value ) + +A longhanded version of $compare->( $value ). Predates blessed +subroutine reference implementation. + +=head2 ->parse_to_perl( $test ) + +Returns a perl code fragment equivalent to the test. +*/ diff --git a/gulliver/thirdparty/pake/pakeTask.class.php b/gulliver/thirdparty/pake/pakeTask.class.php new file mode 100644 index 000000000..a85d7d6e1 --- /dev/null +++ b/gulliver/thirdparty/pake/pakeTask.class.php @@ -0,0 +1,310 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeTask.class.php 4358 2007-06-25 10:04:03Z fabien $ + */ + +/** + * + * . + * + * . + * + * @package pake + * @author Fabien Potencier + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeTask.class.php 4358 2007-06-25 10:04:03Z fabien $ + */ +class pakeTask +{ + protected static $TASKS = array(); + protected static $ALIAS = array(); + protected static $last_comment = ''; + protected $prerequisites = array(); + protected $name = ''; + protected $comment = ''; + protected $already_invoked = false; + protected $trace = null; + protected $verbose = null; + protected $dryrun = null; + protected $alias = ''; + + public function __construct($task_name) + { + $this->name = $task_name; + $this->comment = ''; + $this->prerequisites = array(); + $this->already_invoked = false; + $pake = pakeApp::get_instance(); + $this->trace = $pake->get_trace(); + $this->dryrun = $pake->get_dryrun(); + $this->verbose = $pake->get_verbose(); + } + + public function is_verbose() + { + return $this->verbose; + } + + public function enhance($deps = null) + { + if (!$deps) return; + + if (is_array($deps)) + { + $this->prerequisites = array_merge($this->prerequisites, $deps); + } + else + { + $this->prerequisites[] = $deps; + } + } + + public static function get_tasks() + { + $tasks = pakeTask::$TASKS; + // we merge tasks and aliases + foreach (pakeTask::$ALIAS as $alias => $name) + { + if (!array_key_exists($name, $tasks)) + { + throw new pakeException(sprintf('Task "%s" cannot be cloned to "%s" because it does not exist.', $name, $alias)); + } + + $alias_task = clone $tasks[$name]; + $alias_task->alias = $name; + $alias_task->name = $alias; + $tasks[$alias] = $alias_task; + } + + return $tasks; + } + + public function get_property($name, $section = null) + { + $properties = pakeApp::get_instance()->get_properties(); + + if ($section) + { + if (!array_key_exists($section, $properties) || !array_key_exists($name, $properties[$section])) + { + throw new pakeException(sprintf('Property "%s/%s" does not exist.', $section, $name)); + } + else + { + return $properties[$section][$name]; + } + } + else + { + if (!array_key_exists($name, $properties)) + { + throw new pakeException(sprintf('Property "%s" does not exist.', $name)); + } + else + { + return $properties[$name]; + } + } + } + + public function get_alias() + { + return $this->alias; + } + + public function get_prerequisites() + { + return $this->prerequisites; + } + + public function get_name() + { + return $this->name; + } + + public function get_comment() + { + return $this->comment; + } + + // Format the trace flags for display. + private function format_trace_flags() + { + $flags = array(); + if (!$this->already_invoked) + { + $flags[] = 'first_time'; + } + if (!$this->is_needed()) + { + $flags[] = 'not_needed'; + } + + return (count($flags)) ? '('.join(', ', $flags).')' : ''; + } + + public function invoke($args, $options) + { + if ($this->trace) + { + pake_echo_action('invoke', $this->name.' '.$this->format_trace_flags()); + } + + // return if already invoked + if ($this->already_invoked) return; + $this->already_invoked = true; + + // run prerequisites + $tasks = self::get_tasks(); + foreach ($this->prerequisites as $prerequisite) + { + $real_prerequisite = self::get_full_task_name($prerequisite); + if (array_key_exists($real_prerequisite, $tasks)) + { + $tasks[$real_prerequisite]->invoke($args, $options); + } + else + { + throw new pakeException(sprintf('Prerequisite "%s" does not exist.', $prerequisite)); + } + } + + // only run if needed + if ($this->is_needed()) + { + return $this->execute($args, $options); + } + } + + public function execute($args, $options) + { + if ($this->dryrun) + { + pake_echo_action('execute', '(dry run) '.$this->name); + return; + } + + if ($this->trace) + { + pake_echo_action('execute', $this->name); + } + + // action to run + $function = ($this->get_alias() ? $this->get_alias() : $this->get_name()); + if ($pos = strpos($function, '::')) + { + $function = array(substr($function, 0, $pos), preg_replace('/\-/', '_', 'run_'.strtolower(substr($function, $pos + 2)))); + if (!is_callable($function)) + { + throw new pakeException(sprintf('Task "%s" is defined but with no action defined.', $function[1])); + } + } + else + { + $function = preg_replace('/\-/', '_', 'run_'.strtolower($function)); + if (!function_exists($function)) + { + throw new pakeException(sprintf('Task "%s" is defined but with no action defined.', $this->name)); + } + } + + // execute action + return call_user_func_array($function, array($this, $args, $options)); + } + + public function is_needed() + { + return true; + } + + public function timestamp() + { + $max = 0; + foreach ($this->prerequisites as $prerequisite) + { + $t = pakeTask::get($prerequisite)->timestamp(); + if ($t > $max) $max = $t; + } + + return ($max ? $max : time()); + } + + public static function define_task($name, $deps = null) + { + $task = pakeTask::lookup($name, 'pakeTask'); + $task->add_comment(); + $task->enhance($deps); + } + + public static function define_alias($alias, $name) + { + self::$ALIAS[$alias] = $name; + } + + public static function lookup($task_name, $class = 'pakeTask') + { + $tasks = self::get_tasks(); + $task_name = self::get_full_task_name($task_name); + if (!array_key_exists($task_name, $tasks)) + { + pakeTask::$TASKS[$task_name] = new $class($task_name); + } + + return pakeTask::$TASKS[$task_name]; + } + + public static function get($task_name) + { + $tasks = self::get_tasks(); + $task_name = self::get_full_task_name($task_name); + if (!array_key_exists($task_name, $tasks)) + { + throw new pakeException(sprintf('Task "%s" is not defined.', $task_name)); + } + + return $tasks[$task_name]; + } + + public static function get_full_task_name($task_name) + { + foreach (self::get_tasks() as $task) + { + $mini_task_name = self::get_mini_task_name($task->get_name()); + if ($mini_task_name == $task_name) + { + return $task->get_name(); + } + } + + return $task_name; + } + + public static function get_mini_task_name($task_name) + { + $is_method_task = strpos($task_name, '::'); + return ($is_method_task ? substr($task_name, $is_method_task + 2) : $task_name); + } + + public static function define_comment($comment) + { + pakeTask::$last_comment = $comment; + } + + public function add_comment() + { + if (!pakeTask::$last_comment) return; + if ($this->comment) + { + $this->comment .= ' / '; + } + + $this->comment .= pakeTask::$last_comment; + pakeTask::$last_comment = ''; + } +} diff --git a/gulliver/thirdparty/pake/pakeYaml.class.php b/gulliver/thirdparty/pake/pakeYaml.class.php new file mode 100644 index 000000000..55c4fa30b --- /dev/null +++ b/gulliver/thirdparty/pake/pakeYaml.class.php @@ -0,0 +1,890 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeYaml.class.php 2978 2006-12-08 19:15:44Z fabien $ + */ + + class pakeYaml + { + public static function load($input) + { + // syck is prefered over spyc + if (function_exists('syck_load')) { + if (!empty($input) && is_readable($input)) + { + $input = file_get_contents($input); + } + + return syck_load($input); + } + else + { + $spyc = new pakeSpyc(); + + return $spyc->load($input); + } + } + + public static function dump($array) + { + $spyc = new pakeSpyc(); + + return $spyc->dump($array); + } + } + + /** + * Spyc -- A Simple PHP YAML Class + * @version 0.2.2 -- 2006-01-29 + * @author Chris Wanstrath + * @link http://spyc.sourceforge.net/ + * @copyright Copyright 2005-2006 Chris Wanstrath + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + + /** + * A node, used by Spyc for parsing YAML. + * @package Spyc + */ + class pakeYAMLNode { + /**#@+ + * @access public + * @var string + */ + public $parent; + public $id; + /**#@+*/ + /** + * @access public + * @var mixed + */ + public $data; + /** + * @access public + * @var int + */ + public $indent; + /** + * @access public + * @var bool + */ + public $children = false; + + /** + * The constructor assigns the node a unique ID. + * @access public + * @return void + */ + public function pakeYAMLNode() { + $this->id = uniqid(''); + } + } + + /** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * + * $parser = new Spyc; + * $array = $parser->load($file); + * + * @package Spyc + */ + class pakeSpyc { + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * + * $array = Spyc::YAMLLoad('lucky.yml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public function YAMLLoad($input) { + $spyc = new pakeSpyc; + return $spyc->load($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function YAMLDump($array,$indent = false,$wordwrap = false) { + $spyc = new pakeSpyc; + return $spyc->dump($array,$indent,$wordwrap); + } + + /** + * Load YAML into a PHP array from an instantiated object + * + * The load method, when supplied with a YAML stream (string or file path), + * will do its best to convert the YAML into a PHP array. Pretty simple. + * Usage: + * + * $parser = new Spyc; + * $array = $parser->load('lucky.yml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public function load($input) { + // See what type of input we're talking about + // If it's not a file, assume it's a string + if (!empty($input) && (strpos($input, "\n") === false) + && file_exists($input)) { + $yaml = file($input); + } else { + $yaml = explode("\n",$input); + } + // Initiate some objects and values + $base = new pakeYAMLNode; + $base->indent = 0; + $this->_lastIndent = 0; + $this->_lastNode = $base->id; + $this->_inBlock = false; + $this->_isInline = false; + + foreach ($yaml as $linenum => $line) { + $ifchk = trim($line); + + // If the line starts with a tab (instead of a space), throw a fit. + if (preg_match('/^(\t)+(\w+)/', $line)) { + $err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'. + ' with a tab. YAML only recognizes spaces. Please reformat.'; + throw new Exception($err); + } + + if ($this->_inBlock === false && empty($ifchk)) { + continue; + } elseif ($this->_inBlock == true && empty($ifchk)) { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] .= "\n"; + } elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') { + // Create a new node and get its indent + $node = new pakeYAMLNode; + $node->indent = $this->_getIndent($line); + + // Check where the node lies in the hierarchy + if ($this->_lastIndent == $node->indent) { + // If we're in a block, add the text to the parent's data + if ($this->_inBlock === true) { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; + } else { + // The current node's parent is the same as the previous node's + if (isset($this->_allNodes[$this->_lastNode])) { + $node->parent = $this->_allNodes[$this->_lastNode]->parent; + } + } + } elseif ($this->_lastIndent < $node->indent) { + if ($this->_inBlock === true) { + $parent =& $this->_allNodes[$this->_lastNode]; + $parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; + } elseif ($this->_inBlock === false) { + // The current node's parent is the previous node + $node->parent = $this->_lastNode; + + // If the value of the last node's data was > or | we need to + // start blocking i.e. taking in all lines as a text value until + // we drop our indent. + $parent =& $this->_allNodes[$node->parent]; + $this->_allNodes[$node->parent]->children = true; + if (is_array($parent->data)) { + $chk = $parent->data[key($parent->data)]; + if ($chk === '>') { + $this->_inBlock = true; + $this->_blockEnd = ' '; + $parent->data[key($parent->data)] = + str_replace('>','',$parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line).' '; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } elseif ($chk === '|') { + $this->_inBlock = true; + $this->_blockEnd = "\n"; + $parent->data[key($parent->data)] = + str_replace('|','',$parent->data[key($parent->data)]); + $parent->data[key($parent->data)] .= trim($line)."\n"; + $this->_allNodes[$node->parent]->children = false; + $this->_lastIndent = $node->indent; + } + } + } + } elseif ($this->_lastIndent > $node->indent) { + // Any block we had going is dead now + if ($this->_inBlock === true) { + $this->_inBlock = false; + if ($this->_blockEnd = "\n") { + $last =& $this->_allNodes[$this->_lastNode]; + $last->data[key($last->data)] = + trim($last->data[key($last->data)]); + } + } + + // We don't know the parent of the node so we have to find it + // foreach ($this->_allNodes as $n) { + foreach ($this->_indentSort[$node->indent] as $n) { + if ($n->indent == $node->indent) { + $node->parent = $n->parent; + } + } + } + + if ($this->_inBlock === false) { + // Set these properties with information from our current node + $this->_lastIndent = $node->indent; + // Set the last node + $this->_lastNode = $node->id; + // Parse the YAML line and return its data + $node->data = $this->_parseLine($line); + // Add the node to the master list + $this->_allNodes[$node->id] = $node; + // Add a reference to the node in an indent array + $this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; + // Add a reference to the node in a References array if this node + // has a YAML reference in it. + if ( + ( (is_array($node->data)) && + isset($node->data[key($node->data)]) && + (!is_array($node->data[key($node->data)])) ) + && + ( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)])) + || + (preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) ) + ) { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } elseif ( + ( (is_array($node->data)) && + isset($node->data[key($node->data)]) && + (is_array($node->data[key($node->data)])) ) + ) { + // Incomplete reference making code. Ugly, needs cleaned up. + foreach ($node->data[key($node->data)] as $d) { + if ( !is_array($d) && + ( (preg_match('/^&([^ ]+)/',$d)) + || + (preg_match('/^\*([^ ]+)/',$d)) ) + ) { + $this->_haveRefs[] =& $this->_allNodes[$node->id]; + } + } + } + } + } + } + unset($node); + + // Here we travel through node-space and pick out references (& and *) + $this->_linkReferences(); + + // Build the PHP array out of node-space + $trunk = $this->_buildArray(); + return $trunk; + } + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array,$indent = false,$wordwrap = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key,$value,0); + } + return $string; + } + + /**** Private Properties ****/ + + /**#@+ + * @access private + * @var mixed + */ + private $_haveRefs; + private $_allNodes; + private $_lastIndent; + private $_lastNode; + private $_inBlock; + private $_isInline; + private $_dumpIndent; + private $_dumpWordWrap; + /**#@+*/ + + /**** Private Methods ****/ + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _yamlize($key,$value,$indent) { + if (is_array($value)) { + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key,NULL,$indent); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key,$value,$indent); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + private function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key,$value,$indent); + } + return $string; + } else { + return false; + } + } + + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _dumpNode($key,$value,$indent) { + // do some folding here, for blocks + if (strpos($value,"\n")) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + } + + $spaces = str_repeat(' ',$indent); + + if (is_int($key)) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + // It's mapped + $string = $spaces.$key.': '.$value."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + private function _doLiteralBlock($value,$indent) { + $exploded = explode("\n",$value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $newValue .= "\n" . $spaces . trim($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + private function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + if ($this->_dumpWordWrap === 0) { + return $value; + } + + if (strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } + return $value; + } + + /* Methods used in loading */ + + /** + * Finds and returns the indentation of a YAML line + * @access private + * @return int + * @param string $line A line from the YAML file + */ + private function _getIndent($line) { + preg_match('/^\s{1,}/',$line,$match); + if (!empty($match[0])) { + $indent = substr_count($match[0],' '); + } else { + $indent = 0; + } + return $indent; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + private function _parseLine($line) { + $line = trim($line); + + $array = array(); + + if (preg_match('/^-(.*):$/',$line)) { + // It's a mapped sequence + $key = trim(substr(substr($line,1),0,-1)); + $array[$key] = ''; + } elseif ($line[0] == '-' && substr($line,0,3) != '---') { + // It's a list item but not a new stream + if (strlen($line) > 1) { + $value = trim(substr($line,1)); + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + $array[] = $value; + } else { + $array[] = array(); + } + } elseif (preg_match('/^(.+):/',$line,$key)) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(':',$line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':',$explode)); + } + + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if (empty($key)) { + $array[] = $value; + } else { + $array[$key] = $value; + } + } + return $array; + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + private function _toType($value) { + if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) { + $value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches)); + $value = preg_replace('/\\\\"/','"',$value); + } elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) { + // Inline Sequence + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + } elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) { + // It's a map + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + $value = array($key => $value); + } elseif (preg_match("/{(.+)}$/",$value,$matches)) { + // Inline Mapping + + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($matches[1]); + + // Propogate value array + $array = array(); + foreach ($explode as $v) { + $array = $array + $this->_toType($v); + } + $value = $array; + } elseif (strtolower($value) == 'null' or $value == '' or $value == '~') { + $value = NULL; + } elseif (ctype_digit($value)) { + $value = (int)$value; + } elseif (in_array(strtolower($value), + array('true', 'on', '+', 'yes', 'y'))) { + $value = TRUE; + } elseif (in_array(strtolower($value), + array('false', 'off', '-', 'no', 'n'))) { + $value = FALSE; + } elseif (is_numeric($value)) { + $value = (float)$value; + } else { + // Just a normal string, right? + $value = trim(preg_replace('/#(.+)$/','',$value)); + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + private function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $strings = $strings[2]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + // Check for sequences + if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) { + $inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline); + $seqs = $seqs[0]; + } + + // Check for mappings + if (preg_match_all('/{(.+)}/U',$inline,$maps)) { + $inline = preg_replace('/{(.+)}/U','YAMLMap',$inline); + $maps = $maps[0]; + } + + $explode = explode(', ',$inline); + + // Re-add the strings + if (!empty($strings)) { + $i = 0; + foreach ($explode as $key => $value) { + if ($value == 'YAMLString') { + $explode[$key] = $strings[$i]; + ++$i; + } + } + } + + // Re-add the sequences + if (!empty($seqs)) { + $i = 0; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value); + ++$i; + } + } + } + + // Re-add the mappings + if (!empty($maps)) { + $i = 0; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + $explode[$key] = str_replace('YAMLMap',$maps[$i],$value); + ++$i; + } + } + } + + return $explode; + } + + /** + * Builds the PHP array from all the YAML nodes we've gathered + * @access private + * @return array + */ + private function _buildArray() { + $trunk = array(); + + if (!isset($this->_indentSort[0])) { + return $trunk; + } + + foreach ($this->_indentSort[0] as $n) { + if (empty($n->parent)) { + $this->_nodeArrayizeData($n); + // Check for references and copy the needed data to complete them. + $this->_makeReferences($n); + // Merge our data with the big array we're building + $trunk = $this->_array_kmerge($trunk,$n->data); + } + } + + return $trunk; + } + + /** + * Traverses node-space and sets references (& and *) accordingly + * @access private + * @return bool + */ + private function _linkReferences() { + if (is_array($this->_haveRefs)) { + foreach ($this->_haveRefs as $node) { + if (!empty($node->data)) { + $key = key($node->data); + // If it's an array, don't check. + if (is_array($node->data[$key])) { + foreach ($node->data[$key] as $k => $v) { + $this->_linkRef($node,$key,$k,$v); + } + } else { + $this->_linkRef($node,$key); + } + } + } + } + return true; + } + + function _linkRef(&$n,$key,$k = NULL,$v = NULL) { + if (empty($k) && empty($v)) { + // Look for &refs + if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0],1); + $this->_allNodes[$n->id]->data[$key] = + substr($n->data[$key],strlen($matches[0])+1); + // Look for *refs + } elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) { + $ref = substr($matches[0],1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } + } elseif (!empty($k) && !empty($v)) { + if (preg_match('/^&([^ ]+)/',$v,$matches)) { + // Flag the node so we know it's a reference + $this->_allNodes[$n->id]->ref = substr($matches[0],1); + $this->_allNodes[$n->id]->data[$key][$k] = + substr($v,strlen($matches[0])+1); + // Look for *refs + } elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) { + $ref = substr($matches[0],1); + // Flag the node as having a reference + $this->_allNodes[$n->id]->refKey = $ref; + } + } + } + + /** + * Finds the children of a node and aids in the building of the PHP array + * @access private + * @param int $nid The id of the node whose children we're gathering + * @return array + */ + private function _gatherChildren($nid) { + $return = array(); + $node =& $this->_allNodes[$nid]; + foreach ($this->_allNodes as $z) { + if ($z->parent == $node->id) { + // We found a child + $this->_nodeArrayizeData($z); + // Check for references + $this->_makeReferences($z); + // Merge with the big array we're returning + // The big array being all the data of the children of our parent node + $return = $this->_array_kmerge($return,$z->data); + } + } + return $return; + } + + /** + * Turns a node's data and its children's data into a PHP array + * + * @access private + * @param array $node The node which you want to arrayize + * @return boolean + */ + private function _nodeArrayizeData(&$node) { + if (is_array($node->data) && $node->children == true) { + // This node has children, so we need to find them + $childs = $this->_gatherChildren($node->id); + // We've gathered all our children's data and are ready to use it + $key = key($node->data); + $key = empty($key) ? 0 : $key; + // If it's an array, add to it of course + if (is_array($node->data[$key])) { + $node->data[$key] = $this->_array_kmerge($node->data[$key],$childs); + } else { + $node->data[$key] = $childs; + } + } elseif (!is_array($node->data) && $node->children == true) { + // Same as above, find the children of this node + $childs = $this->_gatherChildren($node->id); + $node->data = array(); + $node->data[] = $childs; + } + + // We edited $node by reference, so just return true + return true; + } + + /** + * Traverses node-space and copies references to / from this object. + * @access private + * @param object $z A node whose references we wish to make real + * @return bool + */ + private function _makeReferences(&$z) { + // It is a reference + if (isset($z->ref)) { + $key = key($z->data); + // Copy the data to this object for easy retrieval later + $this->ref[$z->ref] =& $z->data[$key]; + // It has a reference + } elseif (isset($z->refKey)) { + if (isset($this->ref[$z->refKey])) { + $key = key($z->data); + // Copy the data from this object to make the node a real reference + $z->data[$key] =& $this->ref[$z->refKey]; + } + } + return true; + } + + + /** + * Merges arrays and maintains numeric keys. + * + * An ever-so-slightly modified version of the array_kmerge() function posted + * to php.net by mail at nospam dot iaindooley dot com on 2004-04-08. + * + * http://us3.php.net/manual/en/function.array-merge.php#41394 + * + * @access private + * @param array $arr1 + * @param array $arr2 + * @return array + */ + private function _array_kmerge($arr1,$arr2) { + if(!is_array($arr1)) + $arr1 = array(); + + if(!is_array($arr2)) + $arr2 = array(); + + $keys1 = array_keys($arr1); + $keys2 = array_keys($arr2); + $keys = array_merge($keys1,$keys2); + $vals1 = array_values($arr1); + $vals2 = array_values($arr2); + $vals = array_merge($vals1,$vals2); + $ret = array(); + + foreach($keys as $key) { + list($unused,$val) = each($vals); + // This is the good part! If a key already exists, but it's part of a + // sequence (an int), just keep addin numbers until we find a fresh one. + if (isset($ret[$key]) and is_int($key)) { + while (array_key_exists($key, $ret)) { + $key++; + } + } + $ret[$key] = $val; + } + + return $ret; + } + } diff --git a/gulliver/thirdparty/pake/tasks/pakePearTask.class.php b/gulliver/thirdparty/pake/tasks/pakePearTask.class.php new file mode 100644 index 000000000..d82d3dc91 --- /dev/null +++ b/gulliver/thirdparty/pake/tasks/pakePearTask.class.php @@ -0,0 +1,27 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakePearTask.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +class pakePearTask +{ + public static function import_default_tasks() + { + pake_desc('create a PEAR package'); + pake_task('pakePearTask::pear'); + } + + public static function run_pear($task, $args) + { + $results = pake_sh('pear package'); + if ($task->is_verbose()) + { + echo $results; + } + } +} diff --git a/gulliver/thirdparty/pake/tasks/pakePhingTask.class.php b/gulliver/thirdparty/pake/tasks/pakePhingTask.class.php new file mode 100644 index 000000000..b25bc39c0 --- /dev/null +++ b/gulliver/thirdparty/pake/tasks/pakePhingTask.class.php @@ -0,0 +1,72 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakePhingTask.class.php 4977 2007-09-05 09:14:45Z noel $ + */ + +include_once 'phing/Phing.php'; +if (!class_exists('Phing')) +{ + throw new pakeException('You must install Phing to use this task. (pear install http://phing.info/pear/phing-current.tgz)'); +} + +class pakePhingTask +{ + public static function import_default_tasks() + { + } + + public static function call_phing($task, $target, $build_file = '', $options = array()) + { + $args = array(); + foreach ($options as $key => $value) + { + $args[] = "-D$key=$value"; + } + + if ($build_file) + { + $args[] = '-f'; + $args[] = realpath($build_file); + } + + if (!$task->is_verbose()) + { + $args[] = '-q'; + } + + if (is_array($target)) + { + $args = array_merge($args, $target); + } + else + { + $args[] = $target; + } + + if (DIRECTORY_SEPARATOR != '\\' && (function_exists('posix_isatty') && @posix_isatty(STDOUT))) + { + $args[] = '-logger'; + $args[] = 'phing.listener.AnsiColorLogger'; + } + + Phing::startup(); + Phing::setProperty('phing.home', getenv('PHING_HOME')); + + $m = new pakePhing(); + $m->execute($args); + $m->runBuild(); + } +} + +class pakePhing extends Phing +{ + function getPhingVersion() + { + return 'pakePhing'; + } +} diff --git a/gulliver/thirdparty/pake/tasks/pakeSimpletestTask.class.php b/gulliver/thirdparty/pake/tasks/pakeSimpletestTask.class.php new file mode 100644 index 000000000..a1abe00e1 --- /dev/null +++ b/gulliver/thirdparty/pake/tasks/pakeSimpletestTask.class.php @@ -0,0 +1,112 @@ + + * @copyright 2004-2005 Fabien Potencier + * @license see the LICENSE file included in the distribution + * @version SVN: $Id: pakeSimpletestTask.class.php 1791 2006-08-23 21:17:06Z fabien $ + */ + +class pakeSimpletestTask +{ + public static function import_default_tasks() + { + pake_desc('launch project test suite'); + pake_task('pakeSimpletestTask::test'); + } + + public static function call_simpletest($task, $type = 'text', $dirs = array()) + { + // remove E_STRICT because simpletest is not E_STRICT compatible + $old_error_reporting = ini_get('error_reporting'); + if ($old_error_reporting & E_STRICT) + { + error_reporting($old_error_reporting ^ E_STRICT); + } + + set_include_path('test'.PATH_SEPARATOR.'lib'.PATH_SEPARATOR.'classes'.PATH_SEPARATOR.get_include_path()); + + include_once('simpletest/unit_tester.php'); + include_once('simpletest/web_tester.php'); + if (!class_exists('GroupTest')) + { + throw new pakeException('You must install SimpleTest to use this task.'); + } + + require_once('simpletest/reporter.php'); + require_once('simpletest/mock_objects.php'); + + $base_test_dir = 'test'; + $test_dirs = array(); + + // run tests only in these subdirectories + if ($dirs) + { + foreach ($dirs as $dir) + { + $test_dirs[] = $base_test_dir.DIRECTORY_SEPARATOR.$dir; + } + } + else + { + $test_dirs[] = $base_test_dir; + } + + $test = new GroupTest('Test suite in ('.implode(', ', $test_dirs).')'); + $files = pakeFinder::type('file')->name('*Test.php')->in($test_dirs); + foreach ($files as $file) + { + $test->addTestFile($file); + } + + if (count($files)) + { + ob_start(); + if ($type == 'html') + { + $result = $test->run(new HtmlReporter()); + } + else if ($type == 'xml') + { + $result = $test->run(new XmlReporter()); + } + else + { + $result = $test->run(new TextReporter()); + } + $content = ob_get_contents(); + ob_end_clean(); + + if ($task->is_verbose()) + { + echo $content; + } + } + else + { + throw new pakeException('No test to run.'); + } + + error_reporting($old_error_reporting); + } + + public static function run_test($task, $args) + { + $types = array('text', 'html', 'xml'); + $type = 'text'; + if (array_key_exists(0, $args) && in_array($args[0], $types)) + { + $type = $args[0]; + array_shift($args); + } + + $dirs = array(); + if (is_array($args) && array_key_exists(0, $args)) + { + $dirs[] = $args[0]; + } + + self::call_simpletest($task, $type, $dirs); + } +} diff --git a/gulliver/thirdparty/pear/Archive/Tar.php b/gulliver/thirdparty/pear/Archive/Tar.php new file mode 100644 index 000000000..952092bac --- /dev/null +++ b/gulliver/thirdparty/pear/Archive/Tar.php @@ -0,0 +1,1304 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Tar.php,v 1.15 2003/01/07 15:04:42 vblavet Exp $ + +require_once 'PEAR.php'; + +/** +* Creates a (compressed) Tar archive +* +* @author Vincent Blavet +* @version $Revision: 1.15 $ +* @package Archive +*/ +class Archive_Tar extends PEAR +{ + /** + * @var string Name of the Tar + */ + var $_tarname=''; + + /** + * @var boolean if true, the Tar file will be gzipped + */ + var $_compress=false; + + /** + * @var file descriptor + */ + var $_file=0; + + /** + * @var string Local Tar name of a remote Tar (http:// or ftp://) + */ + var $_temp_tarname=''; + + // {{{ constructor + /** + * Archive_Tar Class constructor. This flavour of the constructor only + * declare a new Archive_Tar object, identifying it by the name of the + * tar file. + * If the compress argument is set the tar will be read or created as a + * gzip compressed TAR file. + * + * @param string $p_tarname The name of the tar archive to create + * @param boolean $p_compress if true, the archive will be gezip(ped) + * @access public + */ + function Archive_Tar($p_tarname, $p_compress = null) + { + $this->PEAR(); + if ($p_compress === null) { + if (@file_exists($p_tarname)) { + if ($fp = @fopen($p_tarname, "r")) { + // look for gzip magic cookie + $data = fread($fp, 2); + if ($data == "\37\213") { + $p_compress = true; + } + } + } else { + // probably a remote file or some file accessible + // through a stream interface + if (substr($p_tarname, -2) == 'gz') { + $p_compress = true; + } + } + } + $this->_tarname = $p_tarname; + if ($p_compress) { // assert zlib extension support + $extname = 'zlib'; + if (!extension_loaded($extname)) { + if (OS_WINDOWS) { + @dl("php_$extname.dll"); + } else { + @dl("$extname.so"); + } + } + if (!extension_loaded($extname)) { + die("The extension '$extname' couldn't be found.\n". + "Please make sure your version of PHP was built". + "with '$extname' support.\n"); + return false; + } + } + $this->_compress = (bool)$p_compress; + } + // }}} + + // {{{ destructor + function _Archive_Tar() + { + $this->_close(); + // ----- Look for a local copy to delete + if ($this->_temp_tarname != '') + @unlink($this->_temp_tarname); + $this->_PEAR(); + } + // }}} + + // {{{ create() + /** + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If a file with the same name exist and is writable, it is replaced + * by the new tar. + * The method return false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * For each directory added in the archive, the files and + * sub-directories are also added. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a single + * string with names separated by a single blank space. + * @return true on success, false on error. + * @see createModify() + * @access public + */ + function create($p_filelist) + { + return $this->createModify($p_filelist, '', ''); + } + // }}} + + // {{{ add() + /** + * This method add the files / directories that are listed in $p_filelist in + * the archive. If the archive does not exist it is created. + * The method return false and a PEAR error text. + * The files and directories listed are only added at the end of the archive, + * even if a file with the same name is already archived. + * See also createModify() method for more details. + * + * @param array $p_filelist An array of filenames and directory names, or a single + * string with names separated by a single blank space. + * @return true on success, false on error. + * @see createModify() + * @access public + */ + function add($p_filelist) + { + return $this->addModify($p_filelist, '', ''); + } + // }}} + + // {{{ extract() + function extract($p_path='') + { + return $this->extractModify($p_path, ''); + } + // }}} + + // {{{ listContent() + function listContent() + { + $v_list_detail = array(); + + if ($this->_openRead()) { + if (!$this->_extractList('', $v_list_detail, "list", '', '')) { + unset($v_list_detail); + $v_list_detail = 0; + } + $this->_close(); + } + + return $v_list_detail; + } + // }}} + + // {{{ createModify() + /** + * This method creates the archive file and add the files / directories + * that are listed in $p_filelist. + * If the file already exists and is writable, it is replaced by the + * new tar. It is a create and not an add. If the file exists and is + * read-only or is a directory it is not replaced. The method return + * false and a PEAR error text. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * See also addModify() method for file adding properties. + * + * @param array $p_filelist An array of filenames and directory names, or a single + * string with names separated by a single blank space. + * @param string $p_add_dir A string which contains a path to be added to the + * memorized path of each element in the list. + * @param string $p_remove_dir A string which contains a path to be removed from + * the memorized path of each element in the list, when + * relevant. + * @return boolean true on success, false on error. + * @access public + * @see addModify() + */ + function createModify($p_filelist, $p_add_dir, $p_remove_dir='') + { + $v_result = true; + + if (!$this->_openWrite()) + return false; + + if ($p_filelist != '') { + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_cleanFile(); + $this->_error('Invalid file list'); + return false; + } + + $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir); + } + + if ($v_result) { + $this->_writeFooter(); + $this->_close(); + } else + $this->_cleanFile(); + + return $v_result; + } + // }}} + + // {{{ addModify() + /** + * This method add the files / directories listed in $p_filelist at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * The $p_filelist parameter can be an array of string, each string + * representing a filename or a directory name with their path if + * needed. It can also be a single string with names separated by a + * single blank. + * The path indicated in $p_remove_dir will be removed from the + * memorized path of each file / directory listed when this path + * exists. By default nothing is removed (empty path '') + * The path indicated in $p_add_dir will be added at the beginning of + * the memorized path of each file / directory listed. However it can + * be set to empty ''. The adding of a path is done after the removing + * of path. + * The path add/remove ability enables the user to prepare an archive + * for extraction in a different path than the origin files are. + * If a file/dir is already in the archive it will only be added at the + * end of the archive. There is no update of the existing archived + * file/dir. However while extracting the archive, the last file will + * replace the first one. This results in a none optimization of the + * archive size. + * If a file/dir does not exist the file/dir is ignored. However an + * error text is send to PEAR error. + * If a file/dir is not readable the file/dir is ignored. However an + * error text is send to PEAR error. + * + * @param array $p_filelist An array of filenames and directory names, or a single + * string with names separated by a single blank space. + * @param string $p_add_dir A string which contains a path to be added to the + * memorized path of each element in the list. + * @param string $p_remove_dir A string which contains a path to be removed from + * the memorized path of each element in the list, when + * relevant. + * @return true on success, false on error. + * @access public + */ + function addModify($p_filelist, $p_add_dir, $p_remove_dir='') + { + $v_result = true; + + if (!@is_file($this->_tarname)) + $v_result = $this->createModify($p_filelist, $p_add_dir, $p_remove_dir); + else { + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_error('Invalid file list'); + return false; + } + + $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); + } + + return $v_result; + } + // }}} + + // {{{ extractModify() + /** + * This method extract all the content of the archive in the directory + * indicated by $p_path. When relevant the memorized path of the + * files/dir can be modified by removing the $p_remove_path path at the + * beginning of the file/dir path. + * While extracting a file, if the directory path does not exists it is + * created. + * While extracting a file, if the file already exists it is replaced + * without looking for last modification date. + * While extracting a file, if the file already exists and is write + * protected, the extraction is aborted. + * While extracting a file, if a directory with the same name already + * exists, the extraction is aborted. + * While extracting a directory, if a file with the same name already + * exists, the extraction is aborted. + * While extracting a file/directory if the destination directory exist + * and is write protected, or does not exist but can not be created, + * the extraction is aborted. + * If after extraction an extracted file does not show the correct + * stored file size, the extraction is aborted. + * When the extraction is aborted, a PEAR error text is set and false + * is returned. However the result can be a partial extraction that may + * need to be manually cleaned. + * + * @param string $p_path The path of the directory where the files/dir need to by + * extracted. + * @param string $p_remove_path Part of the memorized path that can be removed if + * present at the beginning of the file/dir path. + * @return boolean true on success, false on error. + * @access public + * @see extractList() + */ + function extractModify($p_path, $p_remove_path) + { + $v_result = true; + $v_list_detail = array(); + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList($p_path, $v_list_detail, "complete", 0, $p_remove_path); + $this->_close(); + } + + return $v_result; + } + // }}} + + // {{{ extractList() + /** + * This method extract from the archive only the files indicated in the + * $p_filelist. These files are extracted in the current directory or + * in the directory indicated by the optional $p_path parameter. + * If indicated the $p_remove_path can be used in the same way as it is + * used in extractModify() method. + * @param array $p_filelist An array of filenames and directory names, or a single + * string with names separated by a single blank space. + * @param string $p_path The path of the directory where the files/dir need to by + * extracted. + * @param string $p_remove_path Part of the memorized path that can be removed if + * present at the beginning of the file/dir path. + * @return true on success, false on error. + * @access public + * @see extractModify() + */ + function extractList($p_filelist, $p_path='', $p_remove_path='') + { + $v_result = true; + $v_list_detail = array(); + + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_error('Invalid string list'); + return false; + } + + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList($p_path, $v_list_detail, "partial", $v_list, $p_remove_path); + $this->_close(); + } + + return $v_result; + } + // }}} + + // {{{ _error() + function _error($p_message) + { + // ----- To be completed + $this->raiseError($p_message); + } + // }}} + + // {{{ _warning() + function _warning($p_message) + { + // ----- To be completed + $this->raiseError($p_message); + } + // }}} + + // {{{ _openWrite() + function _openWrite() + { + if ($this->_compress) + $this->_file = @gzopen($this->_tarname, "w"); + else + $this->_file = @fopen($this->_tarname, "w"); + + if ($this->_file == 0) { + $this->_error('Unable to open in write mode \''.$this->_tarname.'\''); + return false; + } + + return true; + } + // }}} + + // {{{ _openRead() + function _openRead() + { + if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { + + // ----- Look if a local copy need to be done + if ($this->_temp_tarname == '') { + $this->_temp_tarname = uniqid('tar').'.tmp'; + if (!$v_file_from = @fopen($this->_tarname, 'rb')) { + $this->_error('Unable to open in read mode \''.$this->_tarname.'\''); + $this->_temp_tarname = ''; + return false; + } + if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { + $this->_error('Unable to open in write mode \''.$this->_temp_tarname.'\''); + $this->_temp_tarname = ''; + return false; + } + while ($v_data = @fread($v_file_from, 1024)) + @fwrite($v_file_to, $v_data); + @fclose($v_file_from); + @fclose($v_file_to); + } + + // ----- File to open if the local copy + $v_filename = $this->_temp_tarname; + + } else + // ----- File to open if the normal Tar file + $v_filename = $this->_tarname; + + if ($this->_compress) + $this->_file = @gzopen($v_filename, "rb"); + else + $this->_file = @fopen($v_filename, "rb"); + + if ($this->_file == 0) { + $this->_error('Unable to open in read mode \''.$v_filename.'\''); + return false; + } + + return true; + } + // }}} + + // {{{ _openReadWrite() + function _openReadWrite() + { + if ($this->_compress) + $this->_file = @gzopen($this->_tarname, "r+b"); + else + $this->_file = @fopen($this->_tarname, "r+b"); + + if ($this->_file == 0) { + $this->_error('Unable to open in read/write mode \''.$this->_tarname.'\''); + return false; + } + + return true; + } + // }}} + + // {{{ _close() + function _close() + { + if (isset($this->_file)) { + if ($this->_compress) + @gzclose($this->_file); + else + @fclose($this->_file); + + $this->_file = 0; + } + + // ----- Look if a local copy need to be erase + // Note that it might be interesting to keep the url for a time : ToDo + if ($this->_temp_tarname != '') { + @unlink($this->_temp_tarname); + $this->_temp_tarname = ''; + } + + return true; + } + // }}} + + // {{{ _cleanFile() + function _cleanFile() + { + $this->_close(); + + // ----- Look for a local copy + if ($this->_temp_tarname != '') { + // ----- Remove the local copy but not the remote tarname + @unlink($this->_temp_tarname); + $this->_temp_tarname = ''; + } else { + // ----- Remove the local tarname file + @unlink($this->_tarname); + } + $this->_tarname = ''; + + return true; + } + // }}} + + // {{{ _writeFooter() + function _writeFooter() + { + if ($this->_file) { + // ----- Write the last 0 filled block for end of archive + $v_binary_data = pack("a512", ''); + if ($this->_compress) + @gzputs($this->_file, $v_binary_data); + else + @fputs($this->_file, $v_binary_data); + } + return true; + } + // }}} + + // {{{ _addList() + function _addList($p_list, $p_add_dir, $p_remove_dir) + { + $v_result=true; + $v_header = array(); + + // ----- Remove potential windows directory separator + $p_add_dir = $this->_translateWinPath($p_add_dir); + $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); + + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if (sizeof($p_list) == 0) + return true; + + for ($j=0; ($j_tarname) + continue; + + if ($v_filename == '') + continue; + + if (!file_exists($v_filename)) { + $this->_warning("File '$v_filename' does not exist"); + continue; + } + + // ----- Add the file or directory header + if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) + return false; + + if (@is_dir($v_filename)) { + if (!($p_hdir = opendir($v_filename))) { + $this->_warning("Directory '$v_filename' can not be read"); + continue; + } + $p_hitem = readdir($p_hdir); // '.' directory + $p_hitem = readdir($p_hdir); // '..' directory + while (false !== ($p_hitem = readdir($p_hdir))) { + if ($v_filename != ".") + $p_temp_list[0] = $v_filename.'/'.$p_hitem; + else + $p_temp_list[0] = $p_hitem; + + $v_result = $this->_addList($p_temp_list, $p_add_dir, $p_remove_dir); + } + + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; + } + // }}} + + // {{{ _addFile() + function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir) + { + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } + + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false);; + $v_stored_filename = $p_filename; + if (strcmp($p_filename, $p_remove_dir) == 0) { + return true; + } + if ($p_remove_dir != '') { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= '/'; + + if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + $v_stored_filename = $this->_translateWinPath($v_stored_filename); + if ($p_add_dir != '') { + if (substr($p_add_dir, -1) == '/') + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir.'/'.$v_stored_filename; + } + + $v_stored_filename = $this->_pathReduction($v_stored_filename); + + if (is_file($p_filename)) { + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_warning("Unable to open file '$p_filename' in binary read mode"); + return true; + } + + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; + + while (($v_buffer = fread($v_file, 512)) != '') { + $v_binary_data = pack("a512", "$v_buffer"); + if ($this->_compress) + @gzputs($this->_file, $v_binary_data); + else + @fputs($this->_file, $v_binary_data); + } + + fclose($v_file); + + } else { + // ----- Only header for dir + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; + } + + return true; + } + // }}} + + // {{{ _writeHeader() + function _writeHeader($p_filename, $p_stored_filename) + { + if ($p_stored_filename == '') + $p_stored_filename = $p_filename; + $v_reduce_filename = $this->_pathReduction($p_stored_filename); + + if (strlen($v_reduce_filename) > 99) { + if (!$this->_writeLongHeader($p_stored_filename)) + return false; + } + + $v_info = stat($p_filename); + $v_uid = sprintf("%6s ", DecOct($v_info[4])); + $v_gid = sprintf("%6s ", DecOct($v_info[5])); + $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); + + $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename))); + + if (@is_dir($p_filename)) { + $v_typeflag = "5"; + $v_size = sprintf("%11s ", DecOct(0)); + } else { + $v_typeflag = ''; + clearstatcache(); + $v_size = sprintf("%11s ", DecOct(filesize($p_filename))); + } + + $v_linkname = ''; + + $v_magic = ''; + + $v_version = ''; + + $v_uname = ''; + + $v_gname = ''; + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); + $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, ''); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i=0; $i<148; $i++) + $v_checksum += ord(substr($v_binary_data_first,$i,1)); + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i=148; $i<156; $i++) + $v_checksum += ord(' '); + // ..... Last part of the header + for ($i=156, $j=0; $i<512; $i++, $j++) + $v_checksum += ord(substr($v_binary_data_last,$j,1)); + + // ----- Write the first 148 bytes of the header in the archive + if ($this->_compress) + @gzputs($this->_file, $v_binary_data_first, 148); + else + @fputs($this->_file, $v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + if ($this->_compress) + @gzputs($this->_file, $v_binary_data, 8); + else + @fputs($this->_file, $v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + if ($this->_compress) + @gzputs($this->_file, $v_binary_data_last, 356); + else + @fputs($this->_file, $v_binary_data_last, 356); + + return true; + } + // }}} + + // {{{ _writeLongHeader() + function _writeLongHeader($p_filename) + { + $v_size = sprintf("%11s ", DecOct(strlen($p_filename))); + + $v_typeflag = 'L'; + + $v_linkname = ''; + + $v_magic = ''; + + $v_version = ''; + + $v_uname = ''; + + $v_gname = ''; + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack("a100a8a8a8a12A12", '././@LongLink', 0, 0, 0, $v_size, 0); + $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, ''); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i=0; $i<148; $i++) + $v_checksum += ord(substr($v_binary_data_first,$i,1)); + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i=148; $i<156; $i++) + $v_checksum += ord(' '); + // ..... Last part of the header + for ($i=156, $j=0; $i<512; $i++, $j++) + $v_checksum += ord(substr($v_binary_data_last,$j,1)); + + // ----- Write the first 148 bytes of the header in the archive + if ($this->_compress) + @gzputs($this->_file, $v_binary_data_first, 148); + else + @fputs($this->_file, $v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + if ($this->_compress) + @gzputs($this->_file, $v_binary_data, 8); + else + @fputs($this->_file, $v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + if ($this->_compress) + @gzputs($this->_file, $v_binary_data_last, 356); + else + @fputs($this->_file, $v_binary_data_last, 356); + + // ----- Write the filename as content of the block + $i=0; + while (($v_buffer = substr($p_filename, (($i++)*512), 512)) != '') { + $v_binary_data = pack("a512", "$v_buffer"); + if ($this->_compress) + @gzputs($this->_file, $v_binary_data); + else + @fputs($this->_file, $v_binary_data); + } + + return true; + } + // }}} + + // {{{ _readHeader() + function _readHeader($v_binary_data, &$v_header) + { + if (strlen($v_binary_data)==0) { + $v_header['filename'] = ''; + return true; + } + + if (strlen($v_binary_data) != 512) { + $v_header['filename'] = ''; + $this->_error('Invalid block size : '.strlen($v_binary_data)); + return false; + } + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i=0; $i<148; $i++) + $v_checksum+=ord(substr($v_binary_data,$i,1)); + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i=148; $i<156; $i++) + $v_checksum += ord(' '); + // ..... Last part of the header + for ($i=156; $i<512; $i++) + $v_checksum+=ord(substr($v_binary_data,$i,1)); + + $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data); + + // ----- Extract the checksum + $v_header['checksum'] = OctDec(trim($v_data['checksum'])); + if ($v_header['checksum'] != $v_checksum) { + $v_header['filename'] = ''; + + // ----- Look for last block (empty block) + if (($v_checksum == 256) && ($v_header['checksum'] == 0)) + return true; + + $this->_error('Invalid checksum : '.$v_checksum.' calculated, '.$v_header['checksum'].' expected'); + return false; + } + + // ----- Extract the properties + $v_header['filename'] = trim($v_data['filename']); + $v_header['mode'] = OctDec(trim($v_data['mode'])); + $v_header['uid'] = OctDec(trim($v_data['uid'])); + $v_header['gid'] = OctDec(trim($v_data['gid'])); + $v_header['size'] = OctDec(trim($v_data['size'])); + $v_header['mtime'] = OctDec(trim($v_data['mtime'])); + if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { + $v_header['size'] = 0; + } + /* ----- All these fields are removed form the header because they do not carry interesting info + $v_header[link] = trim($v_data[link]); + $v_header[magic] = trim($v_data[magic]); + $v_header[version] = trim($v_data[version]); + $v_header[uname] = trim($v_data[uname]); + $v_header[gname] = trim($v_data[gname]); + $v_header[devmajor] = trim($v_data[devmajor]); + $v_header[devminor] = trim($v_data[devminor]); + */ + + return true; + } + // }}} + + // {{{ _readLongHeader() + function _readLongHeader(&$v_header) + { + $v_filename = ''; + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + if ($this->_compress) + $v_content = @gzread($this->_file, 512); + else + $v_content = @fread($this->_file, 512); + $v_filename .= $v_content; + } + if (($v_header['size'] % 512) != 0) { + if ($this->_compress) + $v_content = @gzread($this->_file, 512); + else + $v_content = @fread($this->_file, 512); + $v_filename .= $v_content; + } + + // ----- Read the next header + if ($this->_compress) + $v_binary_data = @gzread($this->_file, 512); + else + $v_binary_data = @fread($this->_file, 512); + + if (!$this->_readHeader($v_binary_data, $v_header)) + return false; + + $v_header['filename'] = $v_filename; + + return true; + } + // }}} + + // {{{ _extractList() + function _extractList($p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path) + { + $v_result=true; + $v_nb = 0; + $v_extract_all = true; + $v_listing = false; + + $p_path = $this->_translateWinPath($p_path, false); + if ($p_path == '' || (substr($p_path, 0, 1) != '/' && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) { + $p_path = "./".$p_path; + } + $p_remove_path = $this->_translateWinPath($p_remove_path); + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) + $p_remove_path .= '/'; + $p_remove_path_size = strlen($p_remove_path); + + switch ($p_mode) { + case "complete" : + $v_extract_all = TRUE; + $v_listing = FALSE; + break; + case "partial" : + $v_extract_all = FALSE; + $v_listing = FALSE; + break; + case "list" : + $v_extract_all = FALSE; + $v_listing = TRUE; + break; + default : + $this->_error('Invalid extract mode ('.$p_mode.')'); + return false; + } + + clearstatcache(); + + While (!($v_end_of_file = ($this->_compress?@gzeof($this->_file):@feof($this->_file)))) + { + $v_extract_file = FALSE; + $v_extraction_stopped = 0; + + if ($this->_compress) + $v_binary_data = @gzread($this->_file, 512); + else + $v_binary_data = @fread($this->_file, 512); + + if (!$this->_readHeader($v_binary_data, $v_header)) + return false; + + if ($v_header['filename'] == '') + continue; + + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) + return false; + } + + if ((!$v_extract_all) && (is_array($p_file_list))) { + // ----- By default no unzip if the file is not found + $v_extract_file = false; + + for ($i=0; $i strlen($p_file_list[$i])) && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) == $p_file_list[$i])) { + $v_extract_file = TRUE; + break; + } + } + + // ----- It is a file, so compare the file names + elseif ($p_file_list[$i] == $v_header['filename']) { + $v_extract_file = TRUE; + break; + } + } + } else { + $v_extract_file = TRUE; + } + + // ----- Look if this file need to be extracted + if (($v_extract_file) && (!$v_listing)) + { + if (($p_remove_path != '') + && (substr($v_header['filename'], 0, $p_remove_path_size) == $p_remove_path)) + $v_header['filename'] = substr($v_header['filename'], $p_remove_path_size); + if (($p_path != './') && ($p_path != '/')) { + while (substr($p_path, -1) == '/') + $p_path = substr($p_path, 0, strlen($p_path)-1); + + if (substr($v_header['filename'], 0, 1) == '/') + $v_header['filename'] = $p_path.$v_header['filename']; + else + $v_header['filename'] = $p_path.'/'.$v_header['filename']; + } + if (file_exists($v_header['filename'])) { + if ((@is_dir($v_header['filename'])) && ($v_header['typeflag'] == '')) { + $this->_error('File '.$v_header['filename'].' already exists as a directory'); + return false; + } + if ((is_file($v_header['filename'])) && ($v_header['typeflag'] == "5")) { + $this->_error('Directory '.$v_header['filename'].' already exists as a file'); + return false; + } + if (!is_writeable($v_header['filename'])) { + $this->_error('File '.$v_header['filename'].' already exists and is write protected'); + return false; + } + if (filemtime($v_header['filename']) > $v_header['mtime']) { + // To be completed : An error or silent no replace ? + } + } + + // ----- Check the directory availability and create it if necessary + elseif (($v_result = $this->_dirCheck(($v_header['typeflag'] == "5"?$v_header['filename']:dirname($v_header['filename'])))) != 1) { + $this->_error('Unable to create path for '.$v_header['filename']); + print "AB \n"; + + print $this->_dirCheck(($v_header['typeflag'] == "5"?$v_header['filename']:dirname($v_header['filename']))); + print "\nAB \n"; die; +die; + return 'Unable to create path for '.$v_header['filename']; //false; + } + + if ($v_extract_file) { + if ($v_header['typeflag'] == "5") { + if (!@file_exists($v_header['filename'])) { + if (!@mkdir($v_header['filename'], 0777)) { + $this->_error('Unable to create directory {'.$v_header['filename'].'}'); + return false; + } + } + } else { + if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { + $this->_error('Error while opening {'.$v_header['filename'].'} in write binary mode'); + return false; + } else { + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + if ($this->_compress) + $v_content = @gzread($this->_file, 512); + else + $v_content = @fread($this->_file, 512); + fwrite($v_dest_file, $v_content, 512); + } + if (($v_header['size'] % 512) != 0) { + if ($this->_compress) + $v_content = @gzread($this->_file, 512); + else + $v_content = @fread($this->_file, 512); + fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); + } + + @fclose($v_dest_file); + + // ----- Change the file mode, mtime + @touch($v_header['filename'], $v_header['mtime']); + // To be completed + //chmod($v_header[filename], DecOct($v_header[mode])); + } + + // ----- Check the file size + clearstatcache(); + if (filesize($v_header['filename']) != $v_header['size']) { + $this->_error('Extracted file '.$v_header['filename'].' does not have the correct file size \''.filesize($v_filename).'\' ('.$v_header['size'].' expected). Archive may be corrupted.'); + return false; + } + } + } else { + // ----- Jump to next file + if ($this->_compress) + @gzseek($this->_file, @gztell($this->_file)+(ceil(($v_header['size']/512))*512)); + else + @fseek($this->_file, @ftell($this->_file)+(ceil(($v_header['size']/512))*512)); + } + } else { + // ----- Jump to next file + if ($this->_compress) + @gzseek($this->_file, @gztell($this->_file)+(ceil(($v_header['size']/512))*512)); + else + @fseek($this->_file, @ftell($this->_file)+(ceil(($v_header['size']/512))*512)); + } + + if ($this->_compress) + $v_end_of_file = @gzeof($this->_file); + else + $v_end_of_file = @feof($this->_file); + + if ($v_listing || $v_extract_file || $v_extraction_stopped) { + // ----- Log extracted files + if (($v_file_dir = dirname($v_header['filename'])) == $v_header['filename']) + $v_file_dir = ''; + if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) + $v_file_dir = '/'; + + $p_list_detail[$v_nb++] = $v_header; + } + } + + return true; + } + // }}} + + // {{{ _append() + function _append($p_filelist, $p_add_dir='', $p_remove_dir='') + { + if ($this->_compress) { + $this->_close(); + + if (!@rename($this->_tarname, $this->_tarname.".tmp")) { + $this->_error('Error while renaming \''.$this->_tarname.'\' to temporary file \''.$this->_tarname.'.tmp\''); + return false; + } + + if (($v_temp_tar = @gzopen($this->_tarname.".tmp", "rb")) == 0) { + $this->_error('Unable to open file \''.$this->_tarname.'.tmp\' in binary read mode'); + @rename($this->_tarname.".tmp", $this->_tarname); + return false; + } + + if (!$this->_openWrite()) { + @rename($this->_tarname.".tmp", $this->_tarname); + return false; + } + + $v_buffer = @gzread($v_temp_tar, 512); + + // ----- Read the following blocks but not the last one + if (!@gzeof($v_temp_tar)) { + do{ + $v_binary_data = pack("a512", "$v_buffer"); + @gzputs($this->_file, $v_binary_data); + $v_buffer = @gzread($v_temp_tar, 512); + + } while (!@gzeof($v_temp_tar)); + } + + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) + $this->_writeFooter(); + + $this->_close(); + @gzclose($v_temp_tar); + + if (!@unlink($this->_tarname.".tmp")) { + $this->_error('Error while deleting temporary file \''.$this->_tarname.'.tmp\''); + } + + return true; + } + + // ----- For not compressed tar, just add files before the last 512 bytes block + if (!$this->_openReadWrite()) + return false; + + clearstatcache(); + $v_size = filesize($this->_tarname); + fseek($this->_file, $v_size-512); + + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) + $this->_writeFooter(); + + $this->_close(); + + return true; + } + // }}} + + // {{{ _dirCheck() + + /** + * Check if a directory exists and create it (including parent + * dirs) if not. + * + * @param string $p_dir directory to check + * + * @return bool TRUE if the directory exists or was created + */ + function _dirCheck($p_dir) + { + if ((@is_dir($p_dir)) || ($p_dir == '')) + return true; + + $p_parent_dir = dirname($p_dir); + if (($p_parent_dir != $p_dir) && + ($p_parent_dir != '') && + (!$this->_dirCheck($p_parent_dir))) + return false; + + if (!is_dir($p_dir) && !@mkdir($p_dir, 0777)) { + $this->_error("Unable to create directory '$p_dir'"); + return false; + } + + return true; + } + + // }}} + + // {{{ _pathReduction() + + /** + * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", and + * remove double slashes. + * + * @param string $p_dir path to reduce + * + * @return string reduced path + * + * @access private + * + */ + function _pathReduction($p_dir) + { + $v_result = ''; + + // ----- Look for not empty path + if ($p_dir != '') { + // ----- Explode path by directory names + $v_list = explode('/', $p_dir); + + // ----- Study directories from last to first + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + // ----- Ignore it and ignore the $i-1 + $i--; + } + else if (($v_list[$i] == '') && ($i!=(sizeof($v_list)-1)) && ($i!=0)) { + // ----- Ignore only the double '//' in path, + // but not the first and last / + } else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?'/'.$v_result:''); + } + } + } + $v_result = strtr($v_result, '\\', '/'); + return $v_result; + } + + // }}} + + // {{{ _translateWinPath() + function _translateWinPath($p_path, $p_remove_disk_letter=true) + { + if (OS_WINDOWS) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // }}} + +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Archive/Zip.php b/gulliver/thirdparty/pear/Archive/Zip.php new file mode 100755 index 000000000..11c5c8ba1 --- /dev/null +++ b/gulliver/thirdparty/pear/Archive/Zip.php @@ -0,0 +1,3606 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Zip.php,v 1.2 2005/11/21 06:51:57 vblavet Exp $ + + require_once 'PEAR.php'; + + // ----- Constants + define( 'ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048 ); + + // ----- File list separator + define( 'ARCHIVE_ZIP_SEPARATOR', ',' ); + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', 'C:/Temp/' ); + define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '' ); + + // ----- Error codes + define( 'ARCHIVE_ZIP_ERR_NO_ERROR', 0 ); + define( 'ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'ARCHIVE_ZIP_ERR_MISSING_FILE', -4 ); + define( 'ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_ZIP', -6 ); + define( 'ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9 ); + define( 'ARCHIVE_ZIP_ERR_BAD_FORMAT', -10 ); + define( 'ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16 ); + + // ----- Warning codes + define( 'ARCHIVE_ZIP_WARN_NO_WARNING', 0 ); + define( 'ARCHIVE_ZIP_WARN_FILE_EXIST', 1 ); + + // ----- Methods parameters + define( 'ARCHIVE_ZIP_PARAM_PATH', 'path' ); + define( 'ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path' ); + define( 'ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path' ); + define( 'ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path' ); + define( 'ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod' ); + define( 'ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string' ); + define( 'ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression' ); + define( 'ARCHIVE_ZIP_PARAM_BY_NAME', 'by_name' ); + define( 'ARCHIVE_ZIP_PARAM_BY_INDEX', 'by_index' ); + define( 'ARCHIVE_ZIP_PARAM_BY_EREG', 'by_ereg' ); + define( 'ARCHIVE_ZIP_PARAM_BY_PREG', 'by_preg' ); + + define( 'ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract' ); + define( 'ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract' ); + define( 'ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add' ); + define( 'ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add' ); + + + +/** +* Class for manipulating zip archive files +* +* A class which provided common methods to manipulate ZIP formatted +* archive files. +* It provides creation, extraction, deletion and add features. +* +* @author Vincent Blavet +* @version $Revision: 1.2 $ +* @package Archive_Zip +* @category Archive +*/ +class Archive_Zip +{ + /** + * The filename of the zip archive. + * + * @var string Name of the Zip file + */ + var $_zipname=''; + + /** + * File descriptor of the opened Zip file. + * + * @var int Internal zip file descriptor + */ + var $_zip_fd=0; + + /** + * @var int last error code + */ + var $_error_code=1; + + /** + * @var string Last error description + */ + var $_error_string=''; + + // {{{ constructor + /** + * Archive_Zip Class constructor. This flavour of the constructor only + * declare a new Archive_Zip object, identifying it by the name of the + * zip file. + * + * @param string $p_zipname The name of the zip archive to create + * @access public + */ + function Archive_Zip($p_zipname) + { + + // ----- Check the zlib + if (!extension_loaded('zlib')) { + PEAR::loadExtension('zlib'); + } + if (!extension_loaded('zlib')) { + die("The extension 'zlib' couldn't be found.\n". + "Please make sure your version of PHP was built ". + "with 'zlib' support.\n"); + return false; + } + + // ----- Set the attributes + $this->_zipname = $p_zipname; + $this->_zip_fd = 0; + + return; + } + // }}} + + // {{{ create() + /** + * This method creates a Zip Archive with the filename set with + * the constructor. + * The files and directories indicated in $p_filelist + * are added in the archive. + * When a directory is in the list, the directory and its content is added + * in the archive. + * The methods takes a variable list of parameters in $p_params. + * The supported parameters for this method are : + * 'add_path' : Add a path to the archived files. + * 'remove_path' : Remove the specified 'root' path of the archived files. + * 'remove_all_path' : Remove all the path of the archived files. + * 'no_compression' : The archived files will not be compressed. + * + * @access public + * @param mixed $p_filelist The list of the files or folders to add. + * It can be a string with filenames separated + * by a comma, or an array of filenames. + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * an error code on error + */ + function create($p_filelist, $p_params=0) + { + $this->_errorReset(); + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array('no_compression' => false, + 'add_path' => "", + 'remove_path' => "", + 'remove_all_path' => false)) != 1) { + return 0; + } + + // ----- Look if the $p_filelist is really an array + $p_result_list = array(); + if (is_array($p_filelist)) { + $v_result = $this->_create($p_filelist, $p_result_list, $p_params); + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list with the elements from the string + $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist); + + $v_result = $this->_create($v_list, $p_result_list, $p_params); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Invalid variable type p_filelist'); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + if ($v_result != 1) { + return 0; + } + + return $p_result_list; + } + // }}} + + // {{{ add() + /** + * This method add files or directory in an existing Zip Archive. + * If the Zip Archive does not exist it is created. + * The files and directories to add are indicated in $p_filelist. + * When a directory is in the list, the directory and its content is added + * in the archive. + * The methods takes a variable list of parameters in $p_params. + * The supported parameters for this method are : + * 'add_path' : Add a path to the archived files. + * 'remove_path' : Remove the specified 'root' path of the archived files. + * 'remove_all_path' : Remove all the path of the archived files. + * 'no_compression' : The archived files will not be compressed. + * 'callback_pre_add' : A callback function that will be called before + * each entry archiving. + * 'callback_post_add' : A callback function that will be called after + * each entry archiving. + * + * @access public + * @param mixed $p_filelist The list of the files or folders to add. + * It can be a string with filenames separated + * by a comma, or an array of filenames. + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function add($p_filelist, $p_params=0) + { + $this->_errorReset(); + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array ('no_compression' => false, + 'add_path' => '', + 'remove_path' => '', + 'remove_all_path' => false, + 'callback_pre_add' => '', + 'callback_post_add' => '')) != 1) { + return 0; + } + + // ----- Look if the $p_filelist is really an array + $p_result_list = array(); + if (is_array($p_filelist)) { + // ----- Call the create fct + $v_result = $this->_add($p_filelist, $p_result_list, $p_params); + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list with the elements from the string + $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist); + + // ----- Call the create fct + $v_result = $this->_add($v_list, $p_result_list, $p_params); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "add() : Invalid variable type p_filelist"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + if ($v_result != 1) { + return 0; + } + + // ----- Return the result list + return $p_result_list; + } + // }}} + + // {{{ listContent() + /** + * This method gives the names and properties of the files and directories + * which are present in the zip archive. + * The properties of each entries in the list are : + * filename : Name of the file. + * For create() or add() it's the filename given by the user. + * For an extract() it's the filename of the extracted file. + * stored_filename : Name of the file / directory stored in the archive. + * size : Size of the stored file. + * compressed_size : Size of the file's data compressed in the archive + * (without the zip headers overhead) + * mtime : Last known modification date of the file (UNIX timestamp) + * comment : Comment associated with the file + * folder : true | false (indicates if the entry is a folder) + * index : index of the file in the archive (-1 when not available) + * status : status of the action on the entry (depending of the action) : + * Values are : + * ok : OK ! + * filtered : the file/dir was not extracted (filtered by user) + * already_a_directory : the file can't be extracted because a + * directory with the same name already + * exists + * write_protected : the file can't be extracted because a file + * with the same name already exists and is + * write protected + * newer_exist : the file was not extracted because a newer + * file already exists + * path_creation_fail : the file is not extracted because the + * folder does not exists and can't be + * created + * write_error : the file was not extracted because there was a + * error while writing the file + * read_error : the file was not extracted because there was a + * error while reading the file + * invalid_header : the file was not extracted because of an + * archive format error (bad file header) + * Note that each time a method can continue operating when there + * is an error on a single file, the error is only logged in the file status. + * + * @access public + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function listContent() + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + $v_list = array(); + if ($this->_list($v_list) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + // {{{ extract() + /** + * This method extract the files and folders which are in the zip archive. + * It can extract all the archive or a part of the archive by using filter + * feature (extract by name, by index, by ereg, by preg). The extraction + * can occur in the current path or an other path. + * All the advanced features are activated by the use of variable + * parameters. + * The return value is an array of entry descriptions which gives + * information on extracted files (See listContent()). + * The method may return a success value (an array) even if some files + * are not correctly extracted (see the file status in listContent()). + * The supported variable parameters for this method are : + * 'add_path' : Path where the files and directories are to be extracted + * 'remove_path' : First part ('root' part) of the memorized path + * (if similar) to remove while extracting. + * 'remove_all_path' : Remove all the memorized path while extracting. + * 'extract_as_string' : + * 'set_chmod' : After the extraction of the file the indicated mode + * will be set. + * 'by_name' : It can be a string with file/dir names separated by ',', + * or an array of file/dir names to extract from the archive. + * 'by_index' : A string with range of indexes separated by ',', + * (sample "1,3-5,12"). + * 'by_ereg' : A regular expression (ereg) that must match the extracted + * filename. + * 'by_preg' : A regular expression (preg) that must match the extracted + * filename. + * 'callback_pre_extract' : A callback function that will be called before + * each entry extraction. + * 'callback_post_extract' : A callback function that will be called after + * each entry extraction. + * + * @access public + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function extract($p_params=0) + { + + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array ('extract_as_string' => false, + 'add_path' => '', + 'remove_path' => '', + 'remove_all_path' => false, + 'callback_pre_extract' => '', + 'callback_post_extract' => '', + 'set_chmod' => 0, + 'by_name' => '', + 'by_index' => '', + 'by_ereg' => '', + 'by_preg' => '') ) != 1) { + return 0; + } + + // ----- Call the extracting fct + $v_list = array(); + if ($this->_extractByRule($v_list, $p_params) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + + // {{{ delete() + /** + * This methods delete archive entries in the zip archive. + * Notice that at least one filtering rule (set by the variable parameter + * list) must be set. + * Also notice that if you delete a folder entry, only the folder entry + * is deleted, not all the files bellonging to this folder. + * The supported variable parameters for this method are : + * 'by_name' : It can be a string with file/dir names separated by ',', + * or an array of file/dir names to delete from the archive. + * 'by_index' : A string with range of indexes separated by ',', + * (sample "1,3-5,12"). + * 'by_ereg' : A regular expression (ereg) that must match the extracted + * filename. + * 'by_preg' : A regular expression (preg) that must match the extracted + * filename. + * + * @access public + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function delete($p_params) + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Set default values + if ($this->_check_parameters($p_params, + array ('by_name' => '', + 'by_index' => '', + 'by_ereg' => '', + 'by_preg' => '') ) != 1) { + return 0; + } + + // ----- Check that at least one rule is set + if ( ($p_params['by_name'] == '') + && ($p_params['by_index'] == '') + && ($p_params['by_ereg'] == '') + && ($p_params['by_preg'] == '')) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'At least one filtering rule must' + .' be set as parameter'); + return 0; + } + + // ----- Call the delete fct + $v_list = array(); + if ($this->_deleteByRule($v_list, $p_params) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + // {{{ properties() + /** + * This method gives the global properties of the archive. + * The properties are : + * nb : Number of files in the archive + * comment : Comment associated with the archive file + * status : not_exist, ok + * + * @access public + * @param mixed $p_params {Description} + * @return mixed An array with the global properties or 0 on error. + */ + function properties() + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->_zipname)) { + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive \''.$this->_zipname + .'\' in binary read mode'); + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) { + return 0; + } + + $this->_closeFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + return $v_prop; + } + // }}} + + + // {{{ duplicate() + /** + * This method creates an archive by copying the content of an other one. + * If the archive already exist, it is replaced by the new one without + * any warning. + * + * @access public + * @param mixed $p_archive It can be a valid Archive_Zip object or + * the filename of a valid zip archive. + * @return integer 1 on success, 0 on failure. + */ + function duplicate($p_archive) + { + $this->_errorReset(); + + // ----- Look if the $p_archive is a Archive_Zip object + if ( (is_object($p_archive)) + && (strtolower(get_class($p_archive)) == 'archive_zip')) { + $v_result = $this->_duplicate($p_archive->_zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) { + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "No file with filename '".$p_archive."'"); + $v_result = ARCHIVE_ZIP_ERR_MISSING_FILE; + } + else { + $v_result = $this->_duplicate($p_archive); + } + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "Invalid variable type p_archive_to_add"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + return $v_result; + } + // }}} + + // {{{ merge() + /** + * This method merge a valid zip archive at the end of the + * archive identified by the Archive_Zip object. + * If the archive ($this) does not exist, the merge becomes a duplicate. + * If the archive to add does not exist, the merge is a success. + * + * @access public + * @param mixed $p_archive_to_add It can be a valid Archive_Zip object or + * the filename of a valid zip archive. + * @return integer 1 on success, 0 on failure. + */ + function merge($p_archive_to_add) + { + $v_result = 1; + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a Archive_Zip object + if ( (is_object($p_archive_to_add)) + && (strtolower(get_class($p_archive_to_add)) == 'archive_zip')) { + $v_result = $this->_merge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) { + // ----- Create a temporary archive + $v_object_archive = new Archive_Zip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->_merge($v_object_archive); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "Invalid variable type p_archive_to_add"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + return $v_result; + } + // }}} + + // {{{ errorCode() + /** + * Method that gives the lastest error code. + * + * @access public + * @return integer The error code value. + */ + function errorCode() + { + return($this->_error_code); + } + // }}} + + // {{{ errorName() + /** + * This method gives the latest error code name. + * + * @access public + * @param boolean $p_with_code If true, gives the name and the int value. + * @return string The error name. + */ + function errorName($p_with_code=false) + { + $v_const_list = get_defined_constants(); + + // ----- Extract error constants from all const. + for (reset($v_const_list); + list($v_key, $v_value) = each($v_const_list);) { + if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_')) + =='ARCHIVE_ZIP_ERR_') { + $v_error_list[$v_key] = $v_value; + } + } + + // ----- Search the name form the code value + $v_key=array_search($this->_error_code, $v_error_list, true); + if ($v_key!=false) { + $v_value = $v_key; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->_error_code.')'); + } + else { + return($v_value); + } + } + // }}} + + // {{{ errorInfo() + /** + * This method returns the description associated with the latest error. + * + * @access public + * @param boolean $p_full If set to true gives the description with the + * error code, the name and the description. + * If set to false gives only the description + * and the error code. + * @return string The error description. + */ + function errorInfo($p_full=false) + { + if ($p_full) { + return($this->errorName(true)." : ".$this->_error_string); + } + else { + return($this->_error_string." [code ".$this->_error_code."]"); + } + } + // }}} + + +// ----------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// ----------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _checkFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_checkFormat() + * + * { Description } + * + * @param integer $p_level + */ + function _checkFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the error handler + $this->_errorReset(); + + // ----- Look if the file exits + if (!is_file($this->_zipname)) { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "Missing archive file '".$this->_zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->_zipname)) { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + "Unable to read archive '".$this->_zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _create() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_create() + * + * { Description } + * + */ + function _create($p_list, &$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + $p_add_dir = $p_params['add_path']; + $p_remove_dir = $p_params['remove_path']; + $p_remove_all_dir = $p_params['remove_all_path']; + + // ----- Open the file in write mode + if (($v_result = $this->_openFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->_addList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params); + + // ----- Close + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _add() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_add() + * + * { Description } + * + */ + function _add($p_list, &$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + $p_add_dir = $p_params['add_path']; + $p_remove_dir = $p_params['remove_path']; + $p_remove_all_dir = $p_params['remove_all_path']; + + // ----- Look if the archive exists or is empty and need to be created + if ((!is_file($this->_zipname)) || (filesize($this->_zipname) == 0)) { + $v_result = $this->_create($p_list, $p_result_list, $p_params); + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open temporary file \'' + .$v_zip_temp_name.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to + // use the following methods on the temporary fil and not the real archive + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->_addFileList($p_list, $v_header_list, + $p_add_dir, $p_remove_dir, + $p_remove_all_dir, $p_params)) != 1) + { + fclose($v_zip_temp_fd); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->_zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->_zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i_writeCentralFileHeader($v_header_list[$i]))!=1) { + fclose($v_zip_temp_fd); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($this->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_count + +$v_central_dir['entries'], + $v_size, $v_offset, + $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _openFd() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_openFd() + * + * { Description } + * + */ + function _openFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->_zip_fd != 0) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Zip file \''.$this->_zipname.'\' already open'); + return Archive_Zip::errorCode(); + } + + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive \''.$this->_zipname + .'\' in '.$p_mode.' mode'); + return Archive_Zip::errorCode(); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _closeFd() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_closeFd() + * + * { Description } + * + */ + function _closeFd() + { + $v_result=1; + + if ($this->_zip_fd != 0) + @fclose($this->_zip_fd); + $this->_zip_fd = 0; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addList() + * + * { Description } + * + */ + function _addList($p_list, &$p_result_list, + $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->_addFileList($p_list, $v_header_list, + $p_add_dir, $p_remove_dir, + $p_remove_all_dir, $p_params)) != 1) { + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->_zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $i_writeCentralFileHeader($v_header_list[$i])) != 1) { + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($this->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_count, $v_size, $v_offset, + $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addFileList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to + // run the lib in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addFileList() + * + * { Description } + * + */ + function _addFileList($p_list, &$p_result_list, + $p_add_dir, $p_remove_dir, $p_remove_all_dir, + &$p_params) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($j_tool_TranslateWinPath($p_list[$j], false); + + // ----- Skip empty file names + if ($p_filename == "") + { + continue; + } + + // ----- Check the filename + if (!file_exists($p_filename)) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "File '$p_filename' does not exists"); + return Archive_Zip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all pathnre move + if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) { + // ----- Add the file + if (($v_result = $this->_addFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1) + { + // ----- Return status + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + + // ----- Look for directory + if (is_dir($p_filename)) + { + + // ----- Look for path + if ($p_filename != ".") + $v_path = $p_filename."/"; + else + $v_path = ""; + + // ----- Read the directory for files and sub-directories + $p_hdir = opendir($p_filename); + $p_hitem = readdir($p_hdir); // '.' directory + $p_hitem = readdir($p_hdir); // '..' directory + while ($p_hitem = readdir($p_hdir)) + { + + // ----- Look for a file + if (is_file($v_path.$p_hitem)) + { + + // ----- Add the file + if (($v_result = $this->_addFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1) + { + // ----- Return status + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + + // ----- Recursive call to _addFileList() + else + { + + // ----- Need an array as parameter + $p_temp_list[0] = $v_path.$p_hitem; + $v_result = $this->_addFileList($p_temp_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params); + + // ----- Update the number of elements of the list + $v_nb = sizeof($p_result_list); + } + } + + // ----- Free memory for the recursive loop + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addFile() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addFile() + * + * { Description } + * + */ + function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params) + { + $v_result=1; + + if ($p_filename == "") + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") + { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) + { + if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) + $p_remove_dir = "./".$p_remove_dir; + if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) + $p_remove_dir = substr($p_remove_dir, 2); + } + + $v_compare = $this->_tool_PathInclusion($p_remove_dir, $p_filename); + if ($v_compare > 0) +// if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + { + + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + } + } + // ----- Look for path to add + if ($p_add_dir != "") + { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = $this->_tool_PathReduction($v_stored_filename); + + + /* filename length moved after call-back in release 1.3 + // ----- Check the path length + if (strlen($v_stored_filename) > 0xFF) + { + // ----- Error log + $this->_errorLog(-5, "Stored file name is too long (max. 255) : '$v_stored_filename'"); + + // ----- Return + return Archive_Zip::errorCode(); + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['mtime'] = filemtime($p_filename); + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['size'] = filesize($p_filename); + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['comment_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010); + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; + $p_header['stored_filename'] = $v_stored_filename; + $p_header['extra'] = ''; + $p_header['comment'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for pre-add callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD])) + && ($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_ADD].'(ARCHIVE_ZIP_PARAM_PRE_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = $this->_tool_PathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if (is_file($p_filename)) + { + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return Archive_Zip::errorCode(); + } + + if ($p_params['no_compression']) { + // ----- Read the file content + $v_content_compressed = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = crc32($v_content_compressed); + } + else { + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = crc32($v_content); + + // ----- Compress the file + $v_content_compressed = gzdeflate($v_content); + } + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content_compressed); + $p_header['compression'] = 8; + + // ----- Call the header generation + if (($v_result = $this->_writeFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed content + $v_binary_data = pack('a'.$p_header['compressed_size'], $v_content_compressed); + @fwrite($this->_zip_fd, $v_binary_data, $p_header['compressed_size']); + + // ----- Close the file + @fclose($v_file); + } + + // ----- Look for a directory + else + { + // ----- Set the file properties + $p_header['filename'] .= '/'; + $p_header['filename_len']++; + $p_header['size'] = 0; + $p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->_writeFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for pre-add callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_ADD])) + && ($p_params[ARCHIVE_ZIP_PARAM_POST_ADD] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_ADD].'(ARCHIVE_ZIP_PARAM_POST_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeFileHeader() + * + * { Description } + * + */ + function _writeFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->_zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->_zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeCentralFileHeader() + * + * { Description } + * + */ + function _writeCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->_zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->_zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeCentralHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeCentralHeader() + * + * { Description } + * + */ + function _writeCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->_zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->_zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _list() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_list() + * + * { Description } + * + */ + function _list(&$p_list) + { + $v_result=1; + + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->_zipname.'\' in binary read mode'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_central_dir['offset'])) + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) + { + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->_convertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _convertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_convertHeader2FileInfo() + * + * { Description } + * + */ + function _convertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $p_info['filename'] = $p_header['filename']; + $p_info['stored_filename'] = $p_header['stored_filename']; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractByRule() + * + * { Description } + * + */ + function _extractByRule(&$p_file_list, &$p_params) + { + $v_result=1; + + $p_path = $p_params['add_path']; + $p_remove_path = $p_params['remove_path']; + $p_remove_all_path = $p_params['remove_all_path']; + + // ----- Check the path + if (($p_path == "") + || ((substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->_openFd('rb')) != 1) + { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + // ----- Read next Central dir entry + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_pos_entry)) { + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + + return Archive_Zip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) { + $this->_closeFd(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->_zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; + ($j strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) { + + if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) { + + if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->_closeFd(); + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_params[ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING]) { + + // ----- Extracting the file + if (($v_result = $this->_extractFileAsString($v_header, $v_string)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + } + else { + // ----- Extracting the file + if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + } + } + } + + // ----- Close the zip file + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractFile() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractFile() + * + * { Description } + * + */ + function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->_readFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + // TBC + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + //if (strcmp($p_remove_path, $p_entry['filename'])==0) + if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') + { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Look for pre-extract callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT])) + && ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT].'(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Return + //return $v_result; + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Return + //return $v_result; + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + + // ----- Change the file status + $p_entry['status'] = "newer_exist"; + + // ----- Return + //return $v_result; + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->_dirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) + { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by ARCHIVE_ZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + } + else + { + // ----- Trace + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->_zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD])) + && ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) { + + // ----- Change the mode of the file + chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]); + } + + } + } + + // ----- Look for post-extract callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT])) + && ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT].'(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);'); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractFileAsString() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractFileAsString() + * + * { Description } + * + */ + function _extractFileAsString(&$p_entry, &$p_string) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->_readFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + // TBC + + // ----- Trace + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) + { + // ----- Trace + + // ----- Reading the file + $p_string = fread($this->_zip_fd, $p_entry['compressed_size']); + } + else + { + // ----- Trace + + // ----- Reading the file + $v_data = fread($this->_zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $p_string = gzinflate($v_data); + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readFileHeader() + * + * { Description } + * + */ + function _readFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->_zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Other informations + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readCentralFileHeader() + * + * { Description } + * + */ + function _readCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->_zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') + { + $p_header['external'] = 0x41FF0010; + } + + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readEndCentralDir() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readEndCentralDir() + * + * { Description } + * + */ + function _readEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->_zipname); + @fseek($this->_zip_fd, $v_size); + if (@ftell($this->_zip_fd) != $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to go to the end of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries + // (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->_zip_fd, $v_size-22); + if (($v_pos = @ftell($this->_zip_fd)) != ($v_size-22)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to seek back to the middle of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->_zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->_zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->_zip_fd) != ($v_size-$v_maximum_size)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to seek back to the middle of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->_zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) { + // ----- Read a byte + $v_byte = @fread($this->_zip_fd, 1); + + // ----- Add the byte + $v_bytes = ($v_bytes << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Unable to find End of Central Dir Record signature"); + return Archive_Zip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->_zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Invalid End of Central Dir Record size : " + .strlen($v_binary_data)); + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Fail to find the right signature"); + return Archive_Zip::errorCode(); + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) + $p_central_dir['comment'] = fread($this->_zip_fd, $v_data['comment_size']); + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _deleteByRule() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_deleteByRule() + * + * { Description } + * + */ + function _deleteByRule(&$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_pos_entry)) { + // ----- Clean + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + return Archive_Zip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + $v_result + = $this->_readCentralFileHeader($v_header_list[$v_nb_extracted]); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + + return $v_result; + } + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; + ($j strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] + == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) { + + if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], + $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) { + + if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], + $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; + ($j=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) + && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for deletion + if ($v_found) { + unset($v_header_list[$v_nb_extracted]); + } + else { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-') + .'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new Archive_Zip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->_openFd('wb')) != 1) { + $this->_closeFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i_zip_fd); + if (@fseek($this->_zip_fd, $v_header_list[$i]['offset'])) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + return Archive_Zip::errorCode(); + } + + // ----- Read the file header + if (($v_result = $this->_readFileHeader($v_header_list[$i])) != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Write the file header + $v_result = $v_temp_zip->_writeFileHeader($v_header_list[$i]); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Read/write the data block + $v_result = $this->_tool_CopyBlock($this->_zip_fd, + $v_temp_zip->_zip_fd, + $v_header_list[$i]['compressed_size']); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->_zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $i_writeCentralFileHeader($v_header_list[$i]); + if ($v_result != 1) { + // ----- Clean + $v_temp_zip->_closeFd(); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->_convertHeader2FileInfo($v_header_list[$i], + $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + $v_result = $v_temp_zip->_writeCentralHeader(sizeof($v_header_list), + $v_size, $v_offset, + $v_comment); + if ($v_result != 1) { + // ----- Clean + unset($v_header_list); + $v_temp_zip->_closeFd(); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Close + $v_temp_zip->_closeFd(); + $this->_closeFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _dirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_dirCheck() + * + * { Description } + * + * @param [type] $p_is_dir + */ + function _dirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) { + // ----- Look for parent directory + if ($p_parent_dir != "") { + if (($v_result = $this->_dirCheck($p_parent_dir)) != 1) { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL, + "Unable to create directory '$p_dir'"); + return Archive_Zip::errorCode(); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _merge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_merge() + * + * { Description } + * + */ + function _merge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->_zipname)) { + // ----- Nothing to merge, so merge is a success + return 1; + } + + // ----- Look if the archive exists + if (!is_file($this->_zipname)) { + // ----- Do a duplicate + $v_result = $this->_duplicate($p_archive_to_add->_zipname); + + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->_openFd('rb')) != 1) { + $this->_closeFd(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + $v_result = $p_archive_to_add->_readEndCentralDir($v_central_dir_to_add); + if ($v_result != 1) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->_zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open temporary file \'' + .$v_zip_temp_name.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Zip file comment + // TBC : I should merge the two comments + $v_comment = ''; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_central_dir['entries'] + +$v_central_dir_to_add['entries'], + $v_size, $v_offset, + $v_comment)) != 1) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + @fclose($v_zip_temp_fd); + $this->_zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _duplicate() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_duplicate() + * + * { Description } + * + */ + function _duplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('wb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { + $this->_closeFd(); + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive file \'' + .$p_archive_filename.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->_zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + return $v_result; + } + // --------------------------------------------------------------------------- + + /** + * Archive_Zip::_check_parameters() + * + * { Description } + * + * @param integer $p_error_code + * @param string $p_error_string + */ + function _check_parameters(&$p_params, $p_default) + { + + // ----- Check that param is an array + if (!is_array($p_params)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Unsupported parameter, waiting for an array'); + return Archive_Zip::errorCode(); + } + + // ----- Check that all the params are valid + for (reset($p_params); list($v_key, $v_value) = each($p_params); ) { + if (!isset($p_default[$v_key])) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Unsupported parameter with key \''.$v_key.'\''); + + return Archive_Zip::errorCode(); + } + } + + // ----- Set the default values + for (reset($p_default); list($v_key, $v_value) = each($p_default); ) { + if (!isset($p_params[$v_key])) { + $p_params[$v_key] = $p_default[$v_key]; + } + } + + // ----- Check specific parameters + $v_callback_list = array ('callback_pre_add','callback_post_add', + 'callback_pre_extract','callback_post_extract'); + for ($i=0; $i_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE, + "Callback '".$p_params[$v_key] + ."()' is not an existing function for " + ."parameter '".$v_key."'"); + return Archive_Zip::errorCode(); + } + } + } + + return(1); + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _errorLog() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_errorLog() + * + * { Description } + * + * @param integer $p_error_code + * @param string $p_error_string + */ + function _errorLog($p_error_code=0, $p_error_string='') + { + $this->_error_code = $p_error_code; + $this->_error_string = $p_error_string; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _errorReset() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_errorReset() + * + * { Description } + * + */ + function _errorReset() + { + $this->_error_code = 1; + $this->_error_string = ''; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_PathReduction() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * _tool_PathReduction() + * + * { Description } + * + */ + function _tool_PathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") + { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + for ($i=sizeof($v_list)-1; $i>=0; $i--) + { + // ----- Look for current path + if ($v_list[$i] == ".") + { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") + { + // ----- Ignore it and ignore the $i-1 + $i--; + } + else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0)) + { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + else + { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_PathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // --------------------------------------------------------------------------- + /** + * _tool_PathInclusion() + * + * { Description } + * + */ + function _tool_PathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if ( ($v_list_dir[$i] != $v_list_path[$j]) + && ($v_list_dir[$i] != '') + && ( $v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_CopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // --------------------------------------------------------------------------- + /** + * _tool_CopyBlock() + * + * { Description } + * + * @param integer $p_mode + */ + function _tool_CopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_Rename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // --------------------------------------------------------------------------- + /** + * _tool_Rename() + * + * { Description } + * + */ + function _tool_Rename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_TranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // --------------------------------------------------------------------------- + /** + * _tool_TranslateWinPath() + * + * { Description } + * + * @param [type] $p_remove_disk_letter + */ + function _tool_TranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if ( ($p_remove_disk_letter) + && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // --------------------------------------------------------------------------- + + } + // End of class + +?> diff --git a/gulliver/thirdparty/pear/Benchmark/Iterate.php b/gulliver/thirdparty/pear/Benchmark/Iterate.php new file mode 100755 index 000000000..159b43416 --- /dev/null +++ b/gulliver/thirdparty/pear/Benchmark/Iterate.php @@ -0,0 +1,167 @@ +. | +// +------------------------------------------------------------------------+ +// | This source file is subject to the New BSD license, That is bundled | +// | with this package in the file LICENSE, and is available through | +// | the world-wide-web at | +// | http://www.opensource.org/licenses/bsd-license.php | +// | If you did not receive a copy of the new BSDlicense and are unable | +// | to obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +------------------------------------------------------------------------+ +// +// $Id: Iterate.php,v 1.1 2007/05/24 05:17:56 anant Exp $ +// + +require_once 'Benchmark/Timer.php'; + +/** + * Provides timing and profiling information. + * + * Example 1 + * + * + * '; + * } + * + * $benchmark->run(100, 'foo', 'test'); + * $result = $benchmark->get(); + * ?> + * + * + * Example 2 + * + * + * '; + * } + * } + * + * $benchmark->run(100, 'myclass::foo', 'test'); + * $result = $benchmark->get(); + * ?> + * + * + * Example 3 + * + * + * '; + * } + * } + * + * $o = new MyClass(); + * + * $benchmark->run(100, 'o->foo', 'test'); + * $result = $benchmark->get(); + * ?> + * + * + * @author Sebastian Bergmann + * @copyright Copyright © 2002-2005 Sebastian Bergmann + * @license http://www.php.net/license/3_0.txt The PHP License, Version 3.0 + * @category Benchmarking + * @package Benchmark + */ +class Benchmark_Iterate extends Benchmark_Timer { + /** + * Benchmarks a function or method. + * + * @access public + */ + function run() { + $arguments = func_get_args(); + $iterations = array_shift($arguments); + $function_name = array_shift($arguments); + + if (strstr($function_name, '::')) { + $function_name = explode('::', $function_name); + $objectmethod = $function_name[1]; + } + + if (strstr($function_name, '->')) { + $function_name = explode('->', $function_name); + $objectname = $function_name[0]; + + $object = $GLOBALS[$objectname]; + $objectmethod = $function_name[1]; + + for ($i = 1; $i <= $iterations; $i++) { + $this->setMarker('start_' . $i); + call_user_func_array(array($object, $function_name[1]), $arguments); + $this->setMarker('end_' . $i); + } + + return(0); + } + + for ($i = 1; $i <= $iterations; $i++) { + $this->setMarker('start_' . $i); + call_user_func_array($function_name, $arguments); + $this->setMarker('end_' . $i); + } + } + + /** + * Returns benchmark result. + * + * $result[x ] = execution time of iteration x + * $result['mean' ] = mean execution time + * $result['iterations'] = number of iterations + * + * @return array + * @access public + */ + function get($simple_output = false) { + $result = array(); + $total = 0; + + $iterations = count($this->markers)/2; + + for ($i = 1; $i <= $iterations; $i++) { + $time = $this->timeElapsed('start_'.$i , 'end_'.$i); + + if (extension_loaded('bcmath')) { + $total = bcadd($total, $time, 6); + } else { + $total = $total + $time; + } + + if (!$simple_output) { + $result[$i] = $time; + } + } + + if (extension_loaded('bcmath')) { + $result['mean'] = bcdiv($total, $iterations, 6); + } else { + $result['mean'] = $total / $iterations; + } + + $result['iterations'] = $iterations; + + return $result; + } +} diff --git a/gulliver/thirdparty/pear/Benchmark/Profiler.php b/gulliver/thirdparty/pear/Benchmark/Profiler.php new file mode 100755 index 000000000..a91b34477 --- /dev/null +++ b/gulliver/thirdparty/pear/Benchmark/Profiler.php @@ -0,0 +1,447 @@ +. | +// +----------------------------------------------------------------------+ +// | This source file is subject to the New BSD license, That is bundled | +// | with this package in the file LICENSE, and is available through | +// | the world-wide-web at | +// | http://www.opensource.org/licenses/bsd-license.php | +// | If you did not receive a copy of the new BSDlicense and are unable | +// | to obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// +// $Id: Profiler.php,v 1.2 2007/05/24 05:23:20 anant Exp $ +// + +require_once 'PEAR.php'; + +/** + * Provides timing and profiling information. + * + * Example 1: Automatic profiling start, stop, and output. + * + * + * enterSection('myFunction'); + * //do something + * $profiler->leaveSection('myFunction'); + * return; + * } + * + * //do something + * myFunction(); + * //do more + * ?> + * + * + * Example 2: Manual profiling start, stop, and output. + * + * + * enterSection('myFunction'); + * //do something + * $profiler->leaveSection('myFunction'); + * return; + * } + * + * $profiler->start(); + * //do something + * myFunction(); + * //do more + * $profiler->stop(); + * $profiler->display(); + * ?> + * + * + * @author Matthias Englert + * @copyright Copyright © 2002-2005 Matthias Englert + * @license http://www.php.net/license/3_0.txt The PHP License, Version 3.0 + * @category Benchmarking + * @package Benchmark + * @since 1.2.0 + */ +class Benchmark_Profiler extends PEAR { + /** + * Contains the total ex. time of each section + * + * @var array + * @access private + */ + var $_sections = array(); + + /** + * Calling stack + * + * @var array + * @access private + */ + var $_stack = array(); + + /** + * Notes how often a section was entered + * + * @var array + * @access private + */ + var $_numberOfCalls = array(); + + /** + * Notes for each section how much time is spend in sub-sections + * + * @var array + * @access private + */ + var $_subSectionsTime = array(); + + /** + * Notes for each section how often it calls which section + * + * @var array + * @access private + */ + var $_calls = array(); + + /** + * Notes for each section how often it was called by which section + * + * @var array + * @access private + */ + var $_callers = array(); + + /** + * Auto-starts and stops profiler + * + * @var boolean + * @access private + */ + var $_auto = FALSE; + + /** + * Max marker name length for non-html output + * + * @var integer + * @access private + */ + var $_maxStringLength = 0; + + /** + * Constructor, starts profiling recording + * + * @access public + */ + function Benchmark_Profiler($auto = FALSE) { + $this->_auto = $auto; + + if ($this->_auto) { + $this->start(); + } + + $this->PEAR(); + } + + /** + * Close method, stop profiling recording and display output. + * + * @access public + */ + function close() { + if (isset($this->_auto) && $this->_auto) { + $this->stop(); + $this->display(); + } + } + + /** + * Returns profiling informations for a given section. + * + * @param string $section + * @return array + * @access public + */ + function getSectionInformations($section = 'Global') { + if (isset($this->_sections[$section])) { + $calls = array(); + + if (isset($this->_calls[$section])) { + $calls = $this->_calls[$section]; + } + + $callers = array(); + + if (isset($this->_callers[$section])) { + $callers = $this->_callers[$section]; + } + + $informations = array(); + + $informations['time'] = $this->_sections[$section]; + if (isset($this->_sections['Global'])) { + $informations['percentage'] = number_format(100 * $this->_sections[$section] / $this->_sections['Global'], 2, '.', ''); + } else { + $informations['percentage'] = 'N/A'; + } + $informations['calls'] = $calls; + $informations['num_calls'] = $this->_numberOfCalls[$section]; + $informations['callers'] = $callers; + + if (isset($this->_subSectionsTime[$section])) { + $informations['netto_time'] = $this->_sections[$section] - $this->_subSectionsTime[$section]; + } else { + $informations['netto_time'] = $this->_sections[$section]; + } + + return $informations; + } else { + $this->raiseError("The section '$section' does not exists.\n", NULL, PEAR_ERROR_TRIGGER, E_USER_WARNING); + } + } + + /** + * Returns profiling informations for all sections. + * + * @return array + * @access public + */ + function getAllSectionsInformations() { + $informations = array(); + + foreach($this->_sections as $section => $time) { + $informations[$section] = $this->getSectionInformations($section); + } + + return $informations; + } + + /** + * Returns formatted profiling information. + * + * @param string output format (auto, plain or html), default auto + * @see display() + * @access private + */ + function _getOutput($format) { + + /* Quickly find out the maximun length: Ineffecient, but will do for now! */ + $informations = $this->getAllSectionsInformations(); + $names = array_keys($informations); + + $maxLength = 0; + foreach ($names as $name) + { + if ($maxLength < strlen($name)) { + $maxLength = strlen($name); + } + } + $this->_maxStringLength = $maxLength; + + if ($format == 'auto') { + if (function_exists('version_compare') && + version_compare(phpversion(), '4.1', 'ge')) { + $format = isset($_SERVER['SERVER_PROTOCOL']) ? 'html' : 'plain'; + } else { + global $HTTP_SERVER_VARS; + $format = isset($HTTP_SERVER_VARS['SERVER_PROTOCOL']) ? 'html' : 'plain'; + } + } + + if ($format == 'html') { + $out = ''."\n"; + $out .= + ''. + ''. + ''. + ''. + "\n"; + } else { + $dashes = $out = str_pad("\n", ($this->_maxStringLength + 75), '-', STR_PAD_LEFT); + $out .= str_pad('Section', $this->_maxStringLength + 10); + $out .= str_pad("Total Ex Time", 22); + $out .= str_pad("Netto Ex Time", 22); + $out .= str_pad("#Calls", 10); + $out .= "Percentage\n"; + $out .= $dashes; + } + + foreach($informations as $name => $values) { + $percentage = $values['percentage']; + $calls_str = ""; + + foreach($values['calls'] as $key => $val) { + if ($calls_str) { + $calls_str .= ", "; + } + + $calls_str .= "$key ($val)"; + } + + $callers_str = ""; + + foreach($values['callers'] as $key => $val) { + if ($callers_str) { + $callers_str .= ", "; + } + + $callers_str .= "$key ($val)"; + } + + if ($format == 'html') { + $out .= ""; + if (is_numeric($values['percentage'])) { + $out .= "\n"; + } else { + $out .= "\n"; + } + $out .= ""; + } else { + $out .= str_pad($name, $this->_maxStringLength + 10); + $out .= str_pad($values['time'], 22); + $out .= str_pad($values['netto_time'], 22); + $out .= str_pad($values['num_calls'], 10); + if (is_numeric($values['percentage'])) { + $out .= str_pad($values['percentage']."%\n", 8, ' ', STR_PAD_LEFT); + } else { + $out .= str_pad($values['percentage']."\n", 8, ' ', STR_PAD_LEFT); + } + } + } + + if ($format == 'html') { + return $out . '
     total ex. timenetto ex. time#calls%callscallers
    $name{$values['time']}{$values['netto_time']}{$values['num_calls']}{$values['percentage']}%{$values['percentage']}$calls_str$callers_str
    '; + } else { + return $out; + } + } + + /** + * Returns formatted profiling information. + * + * @param string output format (auto, plain or html), default auto + * @access public + */ + function display($format = 'auto') { + echo $this->_getOutput($format); + } + + /** + * Enters "Global" section. + * + * @see enterSection(), stop() + * @access public + */ + function start() { + $this->enterSection('Global'); + } + + /** + * Leaves "Global" section. + * + * @see leaveSection(), start() + * @access public + */ + function stop() { + $this->leaveSection('Global'); + } + + /** + * Enters code section. + * + * @param string name of the code section + * @see start(), leaveSection() + * @access public + */ + function enterSection($name) { + if (count($this->_stack)) { + if (isset($this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]])) { + $this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]]++; + } else { + $this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]] = 1; + } + + if (isset($this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name])) { + $this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name]++; + } else { + $this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name] = 1; + } + } else { + if ($name != 'Global') { + $this->raiseError("tried to enter section ".$name." but profiling was not started\n", NULL, PEAR_ERROR_DIE); + } + } + + if (isset($this->_numberOfCalls[$name])) { + $this->_numberOfCalls[$name]++; + } else { + $this->_numberOfCalls[$name] = 1; + } + + array_push($this->_stack, array("name" => $name, "time" => $this->_getMicrotime())); + } + + /** + * Leaves code section. + * + * @param string name of the marker to be set + * @see stop(), enterSection() + * @access public + */ + function leaveSection($name) { + $microtime = $this->_getMicrotime(); + + if (!count($this->_stack)) { + $this->raiseError("tried to leave section ".$name." but profiling was not started\n", NULL, PEAR_ERROR_DIE); + } + + $x = array_pop($this->_stack); + + if ($x["name"] != $name) { + $this->raiseError("reached end of section $name but expecting end of " . $x["name"]."\n", NULL, PEAR_ERROR_DIE); + } + + if (isset($this->_sections[$name])) { + $this->_sections[$name] += $microtime - $x["time"]; + } else { + $this->_sections[$name] = $microtime - $x["time"]; + } + + $parent = array_pop($this->_stack); + + if (isset($parent)) { + if (isset($this->_subSectionsTime[$parent['name']])) { + $this->_subSectionsTime[$parent['name']] += $microtime - $x['time']; + } else { + $this->_subSectionsTime[$parent['name']] = $microtime - $x['time']; + } + + array_push($this->_stack, $parent); + } + } + + /** + * Wrapper for microtime(). + * + * @return float + * @access private + * @since 1.3.0 + */ + function _getMicrotime() { + $microtime = explode(' ', microtime()); + return $microtime[1] . substr($microtime[0], 1); + } +} diff --git a/gulliver/thirdparty/pear/Benchmark/Timer.php b/gulliver/thirdparty/pear/Benchmark/Timer.php new file mode 100755 index 000000000..093f46129 --- /dev/null +++ b/gulliver/thirdparty/pear/Benchmark/Timer.php @@ -0,0 +1,321 @@ +. | +// +------------------------------------------------------------------------+ +// | This source file is subject to the New BSD license, That is bundled | +// | with this package in the file LICENSE, and is available through | +// | the world-wide-web at | +// | http://www.opensource.org/licenses/bsd-license.php | +// | If you did not receive a copy of the new BSDlicense and are unable | +// | to obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +------------------------------------------------------------------------+ +// +// $Id: Timer.php,v 1.2 2007/05/24 05:23:20 anant Exp $ +// + +require_once 'PEAR.php'; + +/** + * Provides timing and profiling information. + * + * Example 1: Automatic profiling start, stop, and output. + * + * + * setMarker('Marker 1'); + * ?> + * + * + * Example 2: Manual profiling start, stop, and output. + * + * + * start(); + * $timer->setMarker('Marker 1'); + * $timer->stop(); + * + * $timer->display(); // to output html formated + * // AND/OR : + * $profiling = $timer->getProfiling(); // get the profiler info as an associative array + * ?> + * + * + * @author Sebastian Bergmann + * @author Ludovico Magnocavallo + * @copyright Copyright © 2002-2005 Sebastian Bergmann + * @license http://www.php.net/license/3_0.txt The PHP License, Version 3.0 + * @category Benchmarking + * @package Benchmark + */ +class Benchmark_Timer extends PEAR { + /** + * Contains the markers. + * + * @var array + * @access private + */ + var $markers = array(); + + /** + * Auto-start and stop timer. + * + * @var boolean + * @access private + */ + var $auto = FALSE; + + /** + * Max marker name length for non-html output. + * + * @var integer + * @access private + */ + var $maxStringLength = 0; + + /** + * Constructor. + * + * @param boolean $auto + * @access public + */ + function Benchmark_Timer($auto = FALSE) { + $this->auto = $auto; + + if ($this->auto) { + $this->start(); + } + + $this->PEAR(); + } + + /** + * Close method. Stop timer and display output. + * + * @access public + */ + function close() { + if ($this->auto) { + $this->stop(); + $this->display(); + } + } + + /** + * Set "Start" marker. + * + * @see setMarker(), stop() + * @access public + */ + function start() { + $this->setMarker('Start'); + } + + /** + * Set "Stop" marker. + * + * @see setMarker(), start() + * @access public + */ + function stop() { + $this->setMarker('Stop'); + } + + /** + * Set marker. + * + * @param string $name Name of the marker to be set. + * @see start(), stop() + * @access public + */ + function setMarker($name) { + $this->markers[$name] = $this->_getMicrotime(); + } + + /** + * Returns the time elapsed betweens two markers. + * + * @param string $start start marker, defaults to "Start" + * @param string $end end marker, defaults to "Stop" + * @return double $time_elapsed time elapsed between $start and $end + * @access public + */ + function timeElapsed($start = 'Start', $end = 'Stop') { + if ($end == 'Stop' && !isset($this->markers['Stop'])) { + $this->markers['Stop'] = $this->_getMicrotime(); + } + $end = isset($this->markers[$end]) ? $this->markers[$end] : 0; + $start = isset($this->markers[$start]) ? $this->markers[$start] : 0; + + if (extension_loaded('bcmath')) { + return bcsub($end, $start, 6); + } else { + return $end - $start; + } + } + + /** + * Returns profiling information. + * + * $profiling[x]['name'] = name of marker x + * $profiling[x]['time'] = time index of marker x + * $profiling[x]['diff'] = execution time from marker x-1 to this marker x + * $profiling[x]['total'] = total execution time up to marker x + * + * @return array + * @access public + */ + function getProfiling() { + $i = $total = 0; + $result = array(); + $temp = reset($this->markers); + $this->maxStringLength = 0; + + foreach ($this->markers as $marker => $time) { + if (extension_loaded('bcmath')) { + $diff = bcsub($time, $temp, 6); + $total = bcadd($total, $diff, 6); + } else { + $diff = $time - $temp; + $total = $total + $diff; + } + + $result[$i]['name'] = $marker; + $result[$i]['time'] = $time; + $result[$i]['diff'] = $diff; + $result[$i]['total'] = $total; + + $this->maxStringLength = (strlen($marker) > $this->maxStringLength ? strlen($marker) + 1 : $this->maxStringLength); + + $temp = $time; + $i++; + } + + $result[0]['diff'] = '-'; + $result[0]['total'] = '-'; + $this->maxStringLength = (strlen('total') > $this->maxStringLength ? strlen('total') : $this->maxStringLength); + $this->maxStringLength += 2; + + return $result; + } + + /** + * Return formatted profiling information. + * + * @param boolean $showTotal Optionnaly includes total in output, default no + * @param string $format output format (auto, plain or html), default auto + * @return string + * @see getProfiling() + * @access public + */ + function getOutput($showTotal = FALSE, $format = 'auto') { + if ($format == 'auto') { + if (function_exists('version_compare') && + version_compare(phpversion(), '4.1', 'ge')) + { + $format = isset($_SERVER['SERVER_PROTOCOL']) ? 'html' : 'plain'; + } else { + global $HTTP_SERVER_VARS; + $format = isset($HTTP_SERVER_VARS['SERVER_PROTOCOL']) ? 'html' : 'plain'; + } + } + + $total = $this->TimeElapsed(); + $result = $this->getProfiling(); + $dashes = ''; + + if ($format == 'html') { + $out = ''."\n"; + $out .= ''. + ($showTotal ? + '' + : '')."\n"; + } else { + $dashes = $out = str_pad("\n", + $this->maxStringLength + ($showTotal ? 70 : 45), '-', STR_PAD_LEFT); + $out .= str_pad('marker', $this->maxStringLength) . + str_pad("time index", 22) . + str_pad("ex time", 16) . + str_pad("perct ", 8) . + ($showTotal ? ' '.str_pad("elapsed", 16)."perct" : '')."\n" . + $dashes; + } + + foreach ($result as $k => $v) { + $perc = (($v['diff'] * 100) / $total); + $tperc = (($v['total'] * 100) / $total); + + if ($format == 'html') { + $out .= "". + ($showTotal ? + "" : ''). + "\n"; + } else { + $out .= str_pad($v['name'], $this->maxStringLength, ' ') . + str_pad($v['time'], 22) . + str_pad($v['diff'], 14) . + str_pad(number_format($perc, 2, '.', '')."%",8, ' ', STR_PAD_LEFT) . + ($showTotal ? ' '. + str_pad($v['total'], 14) . + str_pad(number_format($tperc, 2, '.', '')."%", + 8, ' ', STR_PAD_LEFT) : ''). + "\n"; + } + + $out .= $dashes; + } + + if ($format == 'html') { + $out .= "".($showTotal ? "" : "")."\n"; + $out .= "
     time indexex time%elapsed%
    " . $v['name'] . + "" . $v['time'] . + "" . $v['diff'] . + "" . number_format($perc, 2, '.', '') . + "%" . $v['total'] . + "" . + number_format($tperc, 2, '.', '') . + "%
    total-${total}100.00%--
    \n"; + } else { + $out .= str_pad('total', $this->maxStringLength); + $out .= str_pad('-', 22); + $out .= str_pad($total, 15); + $out .= "100.00%\n"; + $out .= $dashes; + } + + return $out; + } + + /** + * Prints the information returned by getOutput(). + * + * @param boolean $showTotal Optionnaly includes total in output, default no + * @param string $format output format (auto, plain or html), default auto + * @see getOutput() + * @access public + */ + function display($showTotal = FALSE, $format = 'auto') { + print $this->getOutput($showTotal, $format); + } + + /** + * Wrapper for microtime(). + * + * @return float + * @access private + * @since 1.3.0 + */ + function _getMicrotime() { + $microtime = explode(' ', microtime()); + return $microtime[1] . substr($microtime[0], 1); + } +} diff --git a/gulliver/thirdparty/pear/CMD.php b/gulliver/thirdparty/pear/CMD.php new file mode 100644 index 000000000..f65de96c3 --- /dev/null +++ b/gulliver/thirdparty/pear/CMD.php @@ -0,0 +1,285 @@ + | +// +----------------------------------------------------------------------+ +// +define('CMD_RCSID', '$Id: CMD.php,v 1.5 2002/12/31 16:18:22 sebastian Exp $'); + +/** + * The Cmd:: class implements an abstraction for various ways + * of executing commands (directly using the backtick operator, + * as a background task after the script has terminated using + * register_shutdown_function() or as a detached process using nohup). + * + * @author Anders Johannsen + * @version $Revision: 1.5 $ + **/ + +require_once 'PEAR.php'; + + +class Cmd extends PEAR +{ + var $arrSetting = array(); + var $arrConstant = array(); + var $arrCommand = array(); + + /** + * Class constructor + * + * Defines all necessary constants and sets defaults + * + * @author Anders Johannsen + * + * @access public + * + **/ + + function Cmd () + { + // Defining constants + $this->arrConstant = array ("CMD_SEQUENCE", + "CMD_SHUTDOWN", + "CMD_SHELL", + "CMD_OUTPUT", + "CMD_NOHUP", + "CMD_VERBOSE" + ); + + foreach ($this->arrConstant as $key => $value) { + if (!defined($value)) { + define($value, $key); + } + } + + // Setting default values + $this->arrSetting[CMD_SEQUENCE] = true; + $this->arrSetting[CMD_SHUTDOWN] = false; + $this->arrSetting[CMD_OUTPUT] = false; + $this->arrSetting[CMD_NOHUP] = false; + $this->arrSetting[CMD_VERBOSE] = false; + + $arrShell = array ("sh", "bash", "zsh", "tcsh", "csh", "ash", "sash", "esh", "ksh"); + + foreach ($arrShell as $shell) { + if ($this->arrSetting[CMD_SHELL] = $this->which($shell)) { + break; + } + } + + if (empty($this->arrSetting[CMD_SHELL])) { + $this->raiseError("No shell found"); + } + } + + /** + * Sets any option + * + * The options are currently: + * CMD_SHUTDOWN : Execute commands via a shutdown function + * CMD_SHELL : Path to shell + * CMD_OUTPUT : Output stdout from process + * CMD_NOHUP : Use nohup to detach process + * CMD_VERBOSE : Print errors to stdout + * + * @param $option is a constant, which corresponds to the + * option that should be changed + * + * @param $setting is the value of the option currently + * being toggled. + * + * @return bool true if succes, else false + * + * @access public + * + * @author Anders Johannsen + * + **/ + + function setOption ($option, $setting) + { + if (empty($this->arrConstant[$option])) { + $this->raiseError("No such option: $option"); + return false; + } + + + switch ($option) { + case CMD_OUTPUT: + case CMD_SHUTDOWN: + case CMD_VERBOSE: + case CMD_SEQUENCE: + $this->arrSetting[$option] = $setting; + return true; + break; + + case CMD_SHELL: + if (is_executable($setting)) { + $this->arrSetting[$option] = $setting; + return true; + } else { + $this->raiseError("No such shell: $setting"); + return false; + } + break; + + + case CMD_NOHUP: + if (empty($setting)) { + $this->arrSetting[$option] = false; + + } else if ($location = $this->which("nohup")) { + $this->arrSetting[$option] = true; + + } else { + $this->raiseError("Nohup was not found on your system"); + return false; + } + break; + + } + } + + /** + * Add command for execution + * + * @param $command accepts both arrays and regular strings + * + * @return bool true if succes, else false + * + * @access public + * + * @author Anders Johannsen + * + **/ + + function command($command) + { + if (is_array($command)) { + foreach ($command as $key => $value) { + $this->arrCommand[] = $value; + } + return true; + + } else if (is_string($command)) { + $this->arrCommand[] = $command; + return true; + } + + $this->raiseError("Argument not valid"); + return false; + } + + /** + * Executes the code according to given options + * + * @return bool true if succes, else false + * + * @access public + * + * @author Anders Johannsen + * + **/ + + function exec() + { + // Warning about impossible mix of options + if (!empty($this->arrSetting[CMD_OUTPUT])) { + if (!empty($this->arrSetting[CMD_SHUTDOWN]) || !empty($this->arrSetting[CMD_NOHUP])) { + $this->raiseError("Error: Commands executed via shutdown functions or nohup cannot return output"); + return false; + } + } + + // Building command + $strCommand = implode(";", $this->arrCommand); + + $strExec = "echo '$strCommand' | ".$this->arrSetting[CMD_SHELL]; + + if (empty($this->arrSetting[CMD_OUTPUT])) { + $strExec = $strExec . ' > /dev/null'; + } + + if (!empty($this->arrSetting[CMD_NOHUP])) { + $strExec = 'nohup ' . $strExec; + } + + // Executing + if (!empty($this->arrSetting[CMD_SHUTDOWN])) { + $line = "system(\"$strExec\");"; + $function = create_function('', $line); + register_shutdown_function($function); + return true; + } else { + return `$strExec`; + } + } + + /** + * Errorhandler. If option CMD_VERBOSE is true, + * the error is printed to stdout, otherwise it + * is avaliable in lastError + * + * @return bool always returns true + * + * @access private + * + * @author Anders Johannsen + **/ + + function raiseError($strError) + { + if (!empty($this->arrSetting[CMD_VERBOSE])) { + echo $strError; + } else { + $this->lastError = $strError; + } + + return true; + } + + /** + * Functionality similiar to unix 'which'. Searches the path + * for the specified program. + * + * @param $cmd name of the executable to search for + * + * @return string returns the full path if found, + * false if not + * + * @access private + * + * @author Anders Johannsen + **/ + + function which($cmd) + { + global $HTTP_ENV_VARS; + + $arrPath = explode(":", $HTTP_ENV_VARS['PATH']); + + foreach ($arrPath as $path) { + $location = $path . "/" . $cmd; + + if (is_executable($location)) { + return $location; + } + } + return false; + } +} + +?> diff --git a/gulliver/thirdparty/pear/CODING_STANDARDS b/gulliver/thirdparty/pear/CODING_STANDARDS new file mode 100644 index 000000000..5687c9a9d --- /dev/null +++ b/gulliver/thirdparty/pear/CODING_STANDARDS @@ -0,0 +1,8 @@ +=========================================================================== +|| PEAR Coding Standards || +=========================================================================== + +$Id: CODING_STANDARDS,v 1.14 2002/01/24 15:02:05 cox Exp $ + +This document is no longer maintained, see +http://pear.php.net/manual/ instead. diff --git a/gulliver/thirdparty/pear/Console/Getopt.php b/gulliver/thirdparty/pear/Console/Getopt.php new file mode 100644 index 000000000..f6b281378 --- /dev/null +++ b/gulliver/thirdparty/pear/Console/Getopt.php @@ -0,0 +1,251 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Getopt.php 6820 2007-06-20 13:35:30Z kevin_fourie $ + +require_once 'PEAR.php'; + +/** + * Command-line options parsing class. + * + * @author Andrei Zmievski + * + */ +class Console_Getopt { + /** + * Parses the command-line options. + * + * The first parameter to this function should be the list of command-line + * arguments without the leading reference to the running program. + * + * The second parameter is a string of allowed short options. Each of the + * option letters can be followed by a colon ':' to specify that the option + * requires an argument, or a double colon '::' to specify that the option + * takes an optional argument. + * + * The third argument is an optional array of allowed long options. The + * leading '--' should not be included in the option name. Options that + * require an argument should be followed by '=', and options that take an + * option argument should be followed by '=='. + * + * The return value is an array of two elements: the list of parsed + * options and the list of non-option command-line arguments. Each entry in + * the list of parsed options is a pair of elements - the first one + * specifies the option, and the second one specifies the option argument, + * if there was one. + * + * Long and short options can be mixed. + * + * Most of the semantics of this function are based on GNU getopt_long(). + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * + * @return array two-element array containing the list of parsed options and + * the non-option arguments + * + * @access public + * + */ + function getopt2($args, $short_options, $long_options = null) + { + return Console_Getopt::doGetopt(2, $args, $short_options, $long_options); + } + + /** + * This function expects $args to start with the script name (POSIX-style). + * Preserved for backwards compatibility. + * @see getopt2() + */ + function getopt($args, $short_options, $long_options = null) + { + return Console_Getopt::doGetopt(1, $args, $short_options, $long_options); + } + + /** + * The actual implementation of the argument parsing code. + */ + function doGetopt($version, $args, $short_options, $long_options = null) + { + // in case you pass directly readPHPArgv() as the first arg + if (PEAR::isError($args)) { + return $args; + } + if (empty($args)) { + return array(array(), array()); + } + $opts = array(); + $non_opts = array(); + + settype($args, 'array'); + + if ($long_options) { + sort($long_options); + } + + /* + * Preserve backwards compatibility with callers that relied on + * erroneous POSIX fix. + */ + if ($version < 2) { + if (isset($args[0]{0}) && $args[0]{0} != '-') { + array_shift($args); + } + } + + reset($args); + while (list($i, $arg) = each($args)) { + + /* The special element '--' means explicit end of + options. Treat the rest of the arguments as non-options + and end the loop. */ + if ($arg == '--') { + $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); + break; + } + + if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; + } elseif (strlen($arg) > 1 && $arg{1} == '-') { + $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); + if (PEAR::isError($error)) + return $error; + } else { + $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); + if (PEAR::isError($error)) + return $error; + } + } + + return array($opts, $non_opts); + } + + /** + * @access private + * + */ + function _parseShortOption($arg, $short_options, &$opts, &$args) + { + for ($i = 0; $i < strlen($arg); $i++) { + $opt = $arg{$i}; + $opt_arg = null; + + /* Try to find the short option in the specifier string. */ + if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') + { + return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); + } + + if (strlen($spec) > 1 && $spec{1} == ':') { + if (strlen($spec) > 2 && $spec{2} == ':') { + if ($i + 1 < strlen($arg)) { + /* Option takes an optional argument. Use the remainder of + the arg string if there is anything left. */ + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + } else { + /* Option requires an argument. Use the remainder of the arg + string if there is anything left. */ + if ($i + 1 < strlen($arg)) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } else if (list(, $opt_arg) = each($args)) + /* Else use the next argument. */; + else + return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + } + } + + $opts[] = array($opt, $opt_arg); + } + } + + /** + * @access private + * + */ + function _parseLongOption($arg, $long_options, &$opts, &$args) + { + @list($opt, $opt_arg) = explode('=', $arg); + $opt_len = strlen($opt); + + for ($i = 0; $i < count($long_options); $i++) { + $long_opt = $long_options[$i]; + $opt_start = substr($long_opt, 0, $opt_len); + + /* Option doesn't match. Go on to the next one. */ + if ($opt_start != $opt) + continue; + + $opt_rest = substr($long_opt, $opt_len); + + /* Check that the options uniquely matches one of the allowed + options. */ + if ($opt_rest != '' && $opt{0} != '=' && + $i + 1 < count($long_options) && + $opt == substr($long_options[$i+1], 0, $opt_len)) { + return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); + } + + if (substr($long_opt, -1) == '=') { + if (substr($long_opt, -2) != '==') { + /* Long option requires an argument. + Take the next argument if one wasn't specified. */; + if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { + return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); + } + } + } else if ($opt_arg) { + return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); + } + + $opts[] = array('--' . $opt, $opt_arg); + return; + } + + return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); + } + + /** + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @access public + * @return mixed the $argv PHP array or PEAR error if not registered + */ + function readPHPArgv() + { + global $argv; + if (!is_array($argv)) { + if (!@is_array($_SERVER['argv'])) { + if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { + return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); + } + return $GLOBALS['HTTP_SERVER_VARS']['argv']; + } + return $_SERVER['argv']; + } + return $argv; + } + +} + +?> diff --git a/gulliver/thirdparty/pear/DB.php b/gulliver/thirdparty/pear/DB.php new file mode 100644 index 000000000..1ff4dc228 --- /dev/null +++ b/gulliver/thirdparty/pear/DB.php @@ -0,0 +1,1114 @@ + | +// | Tomas V.V.Cox | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: DB.php 3355 2005-06-11 22:14:40Z nbm $ +// +// Database independent query interface. + + +require_once 'PEAR.php'; + +// {{{ constants +// {{{ error codes + +/* + * The method mapErrorCode in each DB_dbtype implementation maps + * native error codes to one of these. + * + * If you add an error code here, make sure you also add a textual + * version of it in DB::errorMessage(). + */ +define('DB_OK', 1); +define('DB_ERROR', -1); +define('DB_ERROR_SYNTAX', -2); +define('DB_ERROR_CONSTRAINT', -3); +define('DB_ERROR_NOT_FOUND', -4); +define('DB_ERROR_ALREADY_EXISTS', -5); +define('DB_ERROR_UNSUPPORTED', -6); +define('DB_ERROR_MISMATCH', -7); +define('DB_ERROR_INVALID', -8); +define('DB_ERROR_NOT_CAPABLE', -9); +define('DB_ERROR_TRUNCATED', -10); +define('DB_ERROR_INVALID_NUMBER', -11); +define('DB_ERROR_INVALID_DATE', -12); +define('DB_ERROR_DIVZERO', -13); +define('DB_ERROR_NODBSELECTED', -14); +define('DB_ERROR_CANNOT_CREATE', -15); +define('DB_ERROR_CANNOT_DELETE', -16); +define('DB_ERROR_CANNOT_DROP', -17); +define('DB_ERROR_NOSUCHTABLE', -18); +define('DB_ERROR_NOSUCHFIELD', -19); +define('DB_ERROR_NEED_MORE_DATA', -20); +define('DB_ERROR_NOT_LOCKED', -21); +define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); +define('DB_ERROR_INVALID_DSN', -23); +define('DB_ERROR_CONNECT_FAILED', -24); +define('DB_ERROR_EXTENSION_NOT_FOUND',-25); +define('DB_ERROR_ACCESS_VIOLATION', -26); +define('DB_ERROR_NOSUCHDB', -27); +define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); + + +// }}} +// {{{ prepared statement-related + + +/* + * These constants are used when storing information about prepared + * statements (using the "prepare" method in DB_dbtype). + * + * The prepare/execute model in DB is mostly borrowed from the ODBC + * extension, in a query the "?" character means a scalar parameter. + * There are two extensions though, a "&" character means an opaque + * parameter. An opaque parameter is simply a file name, the real + * data are in that file (useful for putting uploaded files into your + * database and such). The "!" char means a parameter that must be + * left as it is. + * They modify the quote behavoir: + * DB_PARAM_SCALAR (?) => 'original string quoted' + * DB_PARAM_OPAQUE (&) => 'string from file quoted' + * DB_PARAM_MISC (!) => original string + */ +define('DB_PARAM_SCALAR', 1); +define('DB_PARAM_OPAQUE', 2); +define('DB_PARAM_MISC', 3); + + +// }}} +// {{{ binary data-related + + +/* + * These constants define different ways of returning binary data + * from queries. Again, this model has been borrowed from the ODBC + * extension. + * + * DB_BINMODE_PASSTHRU sends the data directly through to the browser + * when data is fetched from the database. + * DB_BINMODE_RETURN lets you return data as usual. + * DB_BINMODE_CONVERT returns data as well, only it is converted to + * hex format, for example the string "123" would become "313233". + */ +define('DB_BINMODE_PASSTHRU', 1); +define('DB_BINMODE_RETURN', 2); +define('DB_BINMODE_CONVERT', 3); + + +// }}} +// {{{ fetch modes + + +/** + * This is a special constant that tells DB the user hasn't specified + * any particular get mode, so the default should be used. + */ +define('DB_FETCHMODE_DEFAULT', 0); + +/** + * Column data indexed by numbers, ordered from 0 and up + */ +define('DB_FETCHMODE_ORDERED', 1); + +/** + * Column data indexed by column names + */ +define('DB_FETCHMODE_ASSOC', 2); + +/** + * Column data as object properties + */ +define('DB_FETCHMODE_OBJECT', 3); + +/** + * For multi-dimensional results: normally the first level of arrays + * is the row number, and the second level indexed by column number or name. + * DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays + * is the column name, and the second level the row number. + */ +define('DB_FETCHMODE_FLIPPED', 4); + +/* for compatibility */ +define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); +define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); +define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); + + +// }}} +// {{{ tableInfo() && autoPrepare()-related + + +/** + * these are constants for the tableInfo-function + * they are bitwised or'ed. so if there are more constants to be defined + * in the future, adjust DB_TABLEINFO_FULL accordingly + */ +define('DB_TABLEINFO_ORDER', 1); +define('DB_TABLEINFO_ORDERTABLE', 2); +define('DB_TABLEINFO_FULL', 3); + +/* + * Used by autoPrepare() + */ +define('DB_AUTOQUERY_INSERT', 1); +define('DB_AUTOQUERY_UPDATE', 2); + + +// }}} +// {{{ portability modes + + +/** + * Portability: turn off all portability features. + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_NONE', 0); + +/** + * Portability: convert names of tables and fields to lower case + * when using the get*(), fetch*() and tableInfo() methods. + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_LOWERCASE', 1); + +/** + * Portability: right trim the data output by get*() and fetch*(). + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_RTRIM', 2); + +/** + * Portability: force reporting the number of rows deleted. + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_DELETE_COUNT', 4); + +/** + * Portability: enable hack that makes numRows() work in Oracle. + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_NUMROWS', 8); + +/** + * Portability: makes certain error messages in certain drivers compatible + * with those from other DBMS's. + * + * + mysql, mysqli: change unique/primary key constraints + * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT + * + * + odbc(access): MS's ODBC driver reports 'no such field' as code + * 07001, which means 'too few parameters.' When this option is on + * that code gets mapped to DB_ERROR_NOSUCHFIELD. + * + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_ERRORS', 16); + +/** + * Portability: convert null values to empty strings in data output by + * get*() and fetch*(). + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_NULL_TO_EMPTY', 32); + +/** + * Portability: turn on all portability features. + * @see DB_common::setOption() + */ +define('DB_PORTABILITY_ALL', 63); + +// }}} + + +// }}} +// {{{ class DB + +/** + * The main "DB" class is simply a container class with some static + * methods for creating DB objects as well as some utility functions + * common to all parts of DB. + * + * The object model of DB is as follows (indentation means inheritance): + * + * DB The main DB class. This is simply a utility class + * with some "static" methods for creating DB objects as + * well as common utility functions for other DB classes. + * + * DB_common The base for each DB implementation. Provides default + * | implementations (in OO lingo virtual methods) for + * | the actual DB implementations as well as a bunch of + * | query utility functions. + * | + * +-DB_mysql The DB implementation for MySQL. Inherits DB_common. + * When calling DB::factory or DB::connect for MySQL + * connections, the object returned is an instance of this + * class. + * + * @package DB + * @author Stig Bakken + * @author Tomas V.V.Cox + * @since PHP 4.0 + * @version $Id: DB.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + */ +class DB +{ + // {{{ &factory() + + /** + * Create a new DB object for the specified database type. + * + * Allows creation of a DB_ object from which the object's + * methods can be utilized without actually connecting to a database. + * + * @param string $type database type, for example "mysql" + * @param array $options associative array of option names and values + * + * @return object a new DB object. On error, an error object. + * + * @see DB_common::setOption() + * @access public + */ + function &factory($type, $options = false) + { + if (!is_array($options)) { + $options = array('persistent' => $options); + } + + if (isset($options['debug']) && $options['debug'] >= 2) { + // expose php errors with sufficient debug level + include_once "DB/{$type}.php"; + } else { + @include_once "DB/{$type}.php"; + } + + $classname = "DB_${type}"; + + if (!class_exists($classname)) { + $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, + "Unable to include the DB/{$type}.php file", + 'DB_Error', true); + return $tmp; + } + + @$obj =& new $classname; + + foreach ($options as $option => $value) { + $test = $obj->setOption($option, $value); + if (DB::isError($test)) { + return $test; + } + } + + return $obj; + } + + // }}} + // {{{ &connect() + + /** + * Create a new DB object and connect to the specified database. + * + * Example 1. + * 2, + * 'portability' => DB_PORTABILITY_ALL, + * ); + * + * $dbh =& DB::connect($dsn, $options); + * if (DB::isError($dbh)) { + * die($dbh->getMessage()); + * } + * ?> + * + * @param mixed $dsn string "data source name" or an array in the + * format returned by DB::parseDSN() + * + * @param array $options an associative array of option names and + * their values + * + * @return object a newly created DB connection object, or a DB + * error object on error + * + * @see DB::parseDSN(), DB_common::setOption(), DB::isError() + * @access public + */ + function &connect($dsn, $options = array()) + { + $dsninfo = DB::parseDSN($dsn); + $type = $dsninfo['phptype']; + + if (!is_array($options)) { + /* + * For backwards compatibility. $options used to be boolean, + * indicating whether the connection should be persistent. + */ + $options = array('persistent' => $options); + } + + if (isset($options['debug']) && $options['debug'] >= 2) { + // expose php errors with sufficient debug level + include_once "DB/${type}.php"; + } else { + @include_once "DB/${type}.php"; + } + + $classname = "DB_${type}"; + if (!class_exists($classname)) { + $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, + "Unable to include the DB/{$type}.php file for `$dsn'", + 'DB_Error', true); + return $tmp; + } + + @$obj =& new $classname; + + foreach ($options as $option => $value) { + $test = $obj->setOption($option, $value); + if (DB::isError($test)) { + return $test; + } + } + + $err = $obj->connect($dsninfo, $obj->getOption('persistent')); + if (DB::isError($err)) { + $err->addUserInfo($dsn); + return $err; + } + + return $obj; + } + + // }}} + // {{{ apiVersion() + + /** + * Return the DB API version + * + * @return int the DB API version number + * + * @access public + */ + function apiVersion() + { + return 2; + } + + // }}} + // {{{ isError() + + /** + * Tell whether a result code from a DB method is an error + * + * @param int $value result code + * + * @return bool whether $value is an error + * + * @access public + */ + function isError($value) + { + return is_a($value, 'DB_Error'); + } + + // }}} + // {{{ isConnection() + + /** + * Tell whether a value is a DB connection + * + * @param mixed $value value to test + * + * @return bool whether $value is a DB connection + * + * @access public + */ + function isConnection($value) + { + return (is_object($value) && + is_subclass_of($value, 'db_common') && + method_exists($value, 'simpleQuery')); + } + + // }}} + // {{{ isManip() + + /** + * Tell whether a query is a data manipulation query (insert, + * update or delete) or a data definition query (create, drop, + * alter, grant, revoke). + * + * @access public + * + * @param string $query the query + * + * @return boolean whether $query is a data manipulation query + */ + function isManip($query) + { + $manips = 'INSERT|UPDATE|DELETE|LOAD DATA|'.'REPLACE|CREATE|DROP|'. + 'ALTER|GRANT|REVOKE|'.'LOCK|UNLOCK'; + if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) { + return true; + } + return false; + } + + // }}} + // {{{ errorMessage() + + /** + * Return a textual error message for a DB error code + * + * @param integer $value error code + * + * @return string error message, or false if the error code was + * not recognized + */ + function errorMessage($value) + { + static $errorMessages; + if (!isset($errorMessages)) { + $errorMessages = array( + DB_ERROR => 'unknown error', + DB_ERROR_ALREADY_EXISTS => 'already exists', + DB_ERROR_CANNOT_CREATE => 'can not create', + DB_ERROR_CANNOT_DELETE => 'can not delete', + DB_ERROR_CANNOT_DROP => 'can not drop', + DB_ERROR_CONSTRAINT => 'constraint violation', + DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', + DB_ERROR_DIVZERO => 'division by zero', + DB_ERROR_INVALID => 'invalid', + DB_ERROR_INVALID_DATE => 'invalid date or time', + DB_ERROR_INVALID_NUMBER => 'invalid number', + DB_ERROR_MISMATCH => 'mismatch', + DB_ERROR_NODBSELECTED => 'no database selected', + DB_ERROR_NOSUCHFIELD => 'no such field', + DB_ERROR_NOSUCHTABLE => 'no such table', + DB_ERROR_NOT_CAPABLE => 'DB backend not capable', + DB_ERROR_NOT_FOUND => 'not found', + DB_ERROR_NOT_LOCKED => 'not locked', + DB_ERROR_SYNTAX => 'syntax error', + DB_ERROR_UNSUPPORTED => 'not supported', + DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', + DB_ERROR_INVALID_DSN => 'invalid DSN', + DB_ERROR_CONNECT_FAILED => 'connect failed', + DB_OK => 'no error', + DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', + DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', + DB_ERROR_NOSUCHDB => 'no such database', + DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', + DB_ERROR_TRUNCATED => 'truncated' + ); + } + + if (DB::isError($value)) { + $value = $value->getCode(); + } + + return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR]; + } + + // }}} + // {{{ parseDSN() + + /** + * Parse a data source name. + * + * Additional keys can be added by appending a URI query string to the + * end of the DSN. + * + * The format of the supplied DSN is in its fullest form: + * + * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true + * + * + * Most variations are allowed: + * + * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 + * phptype://username:password@hostspec/database_name + * phptype://username:password@hostspec + * phptype://username@hostspec + * phptype://hostspec/database + * phptype://hostspec + * phptype(dbsyntax) + * phptype + * + * + * @param string $dsn Data Source Name to be parsed + * + * @return array an associative array with the following keys: + * + phptype: Database backend used in PHP (mysql, odbc etc.) + * + dbsyntax: Database used with regards to SQL syntax etc. + * + protocol: Communication protocol to use (tcp, unix etc.) + * + hostspec: Host specification (hostname[:port]) + * + database: Database to use on the DBMS server + * + username: User name for login + * + password: Password for login + * + * @author Tomas V.V.Cox + */ + function parseDSN($dsn) + { + $parsed = array( + 'phptype' => false, + 'dbsyntax' => false, + 'username' => false, + 'password' => false, + 'protocol' => false, + 'hostspec' => false, + 'port' => false, + 'socket' => false, + 'database' => false, + ); + + if (is_array($dsn)) { + $dsn = array_merge($parsed, $dsn); + if (!$dsn['dbsyntax']) { + $dsn['dbsyntax'] = $dsn['phptype']; + } + return $dsn; + } + + // Find phptype and dbsyntax + if (($pos = strpos($dsn, '://')) !== false) { + $str = substr($dsn, 0, $pos); + $dsn = substr($dsn, $pos + 3); + } else { + $str = $dsn; + $dsn = null; + } + + // Get phptype and dbsyntax + // $str => phptype(dbsyntax) + if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { + $parsed['phptype'] = $arr[1]; + $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; + } else { + $parsed['phptype'] = $str; + $parsed['dbsyntax'] = $str; + } + + if (!count($dsn)) { + return $parsed; + } + + // Get (if found): username and password + // $dsn => username:password@protocol+hostspec/database + if (($at = strrpos($dsn,'@')) !== false) { + $str = substr($dsn, 0, $at); + $dsn = substr($dsn, $at + 1); + if (($pos = strpos($str, ':')) !== false) { + $parsed['username'] = rawurldecode(substr($str, 0, $pos)); + $parsed['password'] = rawurldecode(substr($str, $pos + 1)); + } else { + $parsed['username'] = rawurldecode($str); + } + } + + // Find protocol and hostspec + + // $dsn => proto(proto_opts)/database + if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { + $proto = $match[1]; + $proto_opts = $match[2] ? $match[2] : false; + $dsn = $match[3]; + + // $dsn => protocol+hostspec/database (old format) + } else { + if (strpos($dsn, '+') !== false) { + list($proto, $dsn) = explode('+', $dsn, 2); + } + if (strpos($dsn, '/') !== false) { + list($proto_opts, $dsn) = explode('/', $dsn, 2); + } else { + $proto_opts = $dsn; + $dsn = null; + } + } + + // process the different protocol options + $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; + $proto_opts = rawurldecode($proto_opts); + if ($parsed['protocol'] == 'tcp') { + if (strpos($proto_opts, ':') !== false) { + list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts); + } else { + $parsed['hostspec'] = $proto_opts; + } + } elseif ($parsed['protocol'] == 'unix') { + $parsed['socket'] = $proto_opts; + } + + // Get dabase if any + // $dsn => database + if ($dsn) { + // /database + if (($pos = strpos($dsn, '?')) === false) { + $parsed['database'] = rawurldecode($dsn); + // /database?param1=value1¶m2=value2 + } else { + $parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); + $dsn = substr($dsn, $pos + 1); + if (strpos($dsn, '&') !== false) { + $opts = explode('&', $dsn); + } else { // database?param1=value1 + $opts = array($dsn); + } + foreach ($opts as $opt) { + list($key, $value) = explode('=', $opt); + if (!isset($parsed[$key])) { + // don't allow params overwrite + $parsed[$key] = rawurldecode($value); + } + } + } + } + + return $parsed; + } + + // }}} + // {{{ assertExtension() + + /** + * Load a PHP database extension if it is not loaded already. + * + * @access public + * + * @param string $name the base name of the extension (without the .so or + * .dll suffix) + * + * @return boolean true if the extension was already or successfully + * loaded, false if it could not be loaded + */ + function assertExtension($name) + { + if (!extension_loaded($name)) { + $dlext = OS_WINDOWS ? '.dll' : '.so'; + $dlprefix = OS_WINDOWS ? 'php_' : ''; + @dl($dlprefix . $name . $dlext); + return extension_loaded($name); + } + return true; + } + // }}} +} + +// }}} +// {{{ class DB_Error + +/** + * DB_Error implements a class for reporting portable database error + * messages. + * + * @package DB + * @author Stig Bakken + */ +class DB_Error extends PEAR_Error +{ + // {{{ constructor + + /** + * DB_Error constructor. + * + * @param mixed $code DB error code, or string with error message. + * @param integer $mode what "error mode" to operate in + * @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER + * @param mixed $debuginfo additional debug info, such as the last query + * + * @access public + * + * @see PEAR_Error + */ + function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, + $level = E_USER_NOTICE, $debuginfo = null) + { + if (is_int($code)) { + $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo); + } else { + $this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo); + } + } + // }}} +} + +// }}} +// {{{ class DB_result + +/** + * This class implements a wrapper for a DB result set. + * A new instance of this class will be returned by the DB implementation + * after processing a query that returns data. + * + * @package DB + * @author Stig Bakken + */ +class DB_result +{ + // {{{ properties + + var $dbh; + var $result; + var $row_counter = null; + + /** + * for limit queries, the row to start fetching + * @var integer + */ + var $limit_from = null; + + /** + * for limit queries, the number of rows to fetch + * @var integer + */ + var $limit_count = null; + + // }}} + // {{{ constructor + + /** + * DB_result constructor. + * @param resource &$dbh DB object reference + * @param resource $result result resource id + * @param array $options assoc array with optional result options + */ + function DB_result(&$dbh, $result, $options = array()) + { + $this->dbh = &$dbh; + $this->result = $result; + foreach ($options as $key => $value) { + $this->setOption($key, $value); + } + $this->limit_type = $dbh->features['limit']; + $this->autofree = $dbh->options['autofree']; + $this->fetchmode = $dbh->fetchmode; + $this->fetchmode_object_class = $dbh->fetchmode_object_class; + } + + function setOption($key, $value = null) + { + switch ($key) { + case 'limit_from': + $this->limit_from = $value; break; + case 'limit_count': + $this->limit_count = $value; break; + } + } + + // }}} + // {{{ fetchRow() + + /** + * Fetch a row of data and return it by reference into an array. + * + * The type of array returned can be controlled either by setting this + * method's $fetchmode parameter or by changing the default + * fetch mode setFetchMode() before calling this method. + * + * There are two options for standardizing the information returned + * from databases, ensuring their values are consistent when changing + * DBMS's. These portability options can be turned on when creating a + * new DB object or by using setOption(). + * + * + DB_PORTABILITY_LOWERCASE + * convert names of fields to lower case + * + * + DB_PORTABILITY_RTRIM + * right trim the data + * + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return array a row of data, null on no more rows or PEAR_Error + * object on error + * + * @see DB_common::setOption(), DB_common::setFetchMode() + * @access public + */ + function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) + { + if ($fetchmode === DB_FETCHMODE_DEFAULT) { + $fetchmode = $this->fetchmode; + } + if ($fetchmode === DB_FETCHMODE_OBJECT) { + $fetchmode = DB_FETCHMODE_ASSOC; + $object_class = $this->fetchmode_object_class; + } + if ($this->limit_from !== null) { + if ($this->row_counter === null) { + $this->row_counter = $this->limit_from; + // Skip rows + if ($this->limit_type == false) { + $i = 0; + while ($i++ < $this->limit_from) { + $this->dbh->fetchInto($this->result, $arr, $fetchmode); + } + } + } + if ($this->row_counter >= ( + $this->limit_from + $this->limit_count)) + { + if ($this->autofree) { + $this->free(); + } + $tmp = null; + return $tmp; + } + if ($this->limit_type == 'emulate') { + $rownum = $this->row_counter; + } + $this->row_counter++; + } + $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); + if ($res === DB_OK) { + if (isset($object_class)) { + // default mode specified in DB_common::fetchmode_object_class property + if ($object_class == 'stdClass') { + $arr = (object) $arr; + } else { + $arr = &new $object_class($arr); + } + } + return $arr; + } + if ($res == null && $this->autofree) { + $this->free(); + } + return $res; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row of data into an array which is passed by reference. + * + * The type of array returned can be controlled either by setting this + * method's $fetchmode parameter or by changing the default + * fetch mode setFetchMode() before calling this method. + * + * There are two options for standardizing the information returned + * from databases, ensuring their values are consistent when changing + * DBMS's. These portability options can be turned on when creating a + * new DB object or by using setOption(). + * + * + DB_PORTABILITY_LOWERCASE + * convert names of fields to lower case + * + * + DB_PORTABILITY_RTRIM + * right trim the data + * + * @param array &$arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null on no more rows or + * a DB_Error object on error + * + * @see DB_common::setOption(), DB_common::setFetchMode() + * @access public + */ + function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) + { + if ($fetchmode === DB_FETCHMODE_DEFAULT) { + $fetchmode = $this->fetchmode; + } + if ($fetchmode === DB_FETCHMODE_OBJECT) { + $fetchmode = DB_FETCHMODE_ASSOC; + $object_class = $this->fetchmode_object_class; + } + if ($this->limit_from !== null) { + if ($this->row_counter === null) { + $this->row_counter = $this->limit_from; + // Skip rows + if ($this->limit_type == false) { + $i = 0; + while ($i++ < $this->limit_from) { + $this->dbh->fetchInto($this->result, $arr, $fetchmode); + } + } + } + if ($this->row_counter >= ( + $this->limit_from + $this->limit_count)) + { + if ($this->autofree) { + $this->free(); + } + return null; + } + if ($this->limit_type == 'emulate') { + $rownum = $this->row_counter; + } + + $this->row_counter++; + } + $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); + if ($res === DB_OK) { + if (isset($object_class)) { + // default mode specified in DB_common::fetchmode_object_class property + if ($object_class == 'stdClass') { + $arr = (object) $arr; + } else { + $arr = new $object_class($arr); + } + } + return DB_OK; + } + if ($res == null && $this->autofree) { + $this->free(); + } + return $res; + } + + // }}} + // {{{ numCols() + + /** + * Get the the number of columns in a result set. + * + * @return int the number of columns, or a DB error + * + * @access public + */ + function numCols() + { + return $this->dbh->numCols($this->result); + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @return int the number of rows, or a DB error + * + * @access public + */ + function numRows() + { + return $this->dbh->numRows($this->result); + } + + // }}} + // {{{ nextResult() + + /** + * Get the next result if a batch of queries was executed. + * + * @return bool true if a new result is available or false if not. + * + * @access public + */ + function nextResult() + { + return $this->dbh->nextResult($this->result); + } + + // }}} + // {{{ free() + + /** + * Frees the resources allocated for this result set. + * @return int error code + * + * @access public + */ + function free() + { + $err = $this->dbh->freeResult($this->result); + if (DB::isError($err)) { + return $err; + } + $this->result = false; + return true; + } + + // }}} + // {{{ tableInfo() + + /** + * @deprecated + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($mode = null) + { + if (is_string($mode)) { + return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); + } + return $this->dbh->tableInfo($this, $mode); + } + + // }}} + // {{{ getRowCounter() + + /** + * returns the actual row number + * @return integer + */ + function getRowCounter() + { + return $this->row_counter; + } + // }}} +} + +// }}} +// {{{ class DB_row + +/** + * Pear DB Row Object + * @see DB_common::setFetchMode() + */ +class DB_row +{ + // {{{ constructor + + /** + * constructor + * + * @param resource row data as array + */ + function DB_row(&$arr) + { + foreach ($arr as $key => $value) { + $this->$key = &$arr[$key]; + } + } + + // }}} +} + +// }}} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/common.php b/gulliver/thirdparty/pear/DB/common.php new file mode 100644 index 000000000..13bb1df8c --- /dev/null +++ b/gulliver/thirdparty/pear/DB/common.php @@ -0,0 +1,2042 @@ + | +// | Tomas V.V.Cox | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: common.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'PEAR.php'; + +/** + * DB_common is a base class for DB implementations, and must be + * inherited by all such + * + * @package DB + * @version $Id: common.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Stig Bakken + * @author Tomas V.V.Cox + */ +class DB_common extends PEAR +{ + // {{{ properties + + /** + * assoc of capabilities for this DB implementation + * $features['limit'] => 'emulate' => emulate with fetch row by number + * 'alter' => alter the query + * false => skip rows + * @var array + */ + var $features = array(); + + /** + * assoc mapping native error codes to DB ones + * @var array + */ + var $errorcode_map = array(); + + /** + * DB type (mysql, oci8, odbc etc.) + * @var string + */ + var $phptype; + + /** + * @var string + */ + var $prepare_tokens; + + /** + * @var string + */ + var $prepare_types; + + /** + * @var string + */ + var $prepared_queries; + + /** + * @var integer + */ + var $prepare_maxstmt = 0; + + /** + * @var string + */ + var $last_query = ''; + + /** + * @var integer + */ + var $fetchmode = DB_FETCHMODE_ORDERED; + + /** + * @var string + */ + var $fetchmode_object_class = 'stdClass'; + + /** + * Run-time configuration options. + * + * The 'optimize' option has been deprecated. Use the 'portability' + * option instead. + * + * @see DB_common::setOption() + * @var array + */ + var $options = array( + 'persistent' => false, + 'ssl' => false, + 'debug' => 0, + 'seqname_format' => '%s_seq', + 'autofree' => false, + 'portability' => DB_PORTABILITY_NONE, + 'optimize' => 'performance', // Deprecated. Use 'portability'. + ); + + /** + * DB handle + * @var resource + */ + var $dbh; + + // }}} + // {{{ toString() + + /** + * String conversation + * + * @return string + * @access private + */ + function toString() + { + $info = strtolower(get_class($this)); + $info .= ': (phptype=' . $this->phptype . + ', dbsyntax=' . $this->dbsyntax . + ')'; + + if ($this->connection) { + $info .= ' [connected]'; + } + + return $info; + } + + // }}} + // {{{ constructor + + /** + * Constructor + */ + function DB_common() + { + $this->PEAR('DB_Error'); + } + + // }}} + // {{{ quoteString() + + /** + * DEPRECATED: Quotes a string so it can be safely used within string + * delimiters in a query + * + * @return string quoted string + * + * @see DB_common::quoteSmart(), DB_common::escapeSimple() + * @deprecated Deprecated in release 1.2 or lower + * @internal + */ + function quoteString($string) + { + $string = $this->quote($string); + if ($string{0} == "'") { + return substr($string, 1, -1); + } + return $string; + } + + // }}} + // {{{ quote() + + /** + * DEPRECATED: Quotes a string so it can be safely used in a query + * + * @param string $string the input string to quote + * + * @return string The NULL string or the string quotes + * in magic_quote_sybase style + * + * @see DB_common::quoteSmart(), DB_common::escapeSimple() + * @deprecated Deprecated in release 1.6.0 + * @internal + */ + function quote($string = null) + { + return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'"; + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table or column name + * + * Delimiting style depends on which database driver is being used. + * + * NOTE: just because you CAN use delimited identifiers doesn't mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * Portability is broken by using the following characters inside + * delimited identifiers: + * + backtick (`) -- due to MySQL + * + double quote (") -- due to Oracle + * + brackets ([ or ]) -- due to Access + * + * Delimited identifiers are known to generally work correctly under + * the following drivers: + * + mssql + * + mysql + * + mysqli + * + oci8 + * + odbc(access) + * + odbc(db2) + * + pgsql + * + sqlite + * + sybase + * + * InterBase doesn't seem to be able to use delimited identifiers + * via PHP 4. They work fine under PHP 5. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + */ + function quoteIdentifier($str) + { + return '"' . str_replace('"', '""', $str) . '"'; + } + + // }}} + // {{{ quoteSmart() + + /** + * Format input so it can be safely used in a query + * + * The output depends on the PHP data type of input and the database + * type being used. + * + * @param mixed $in data to be quoted + * + * @return mixed the format of the results depends on the input's + * PHP type: + * + *
      + *
    • + * input -> returns + *
    • + *
    • + * null -> the string NULL + *
    • + *
    • + * integer or double -> the unquoted number + *
    • + *
    • + * &type.bool; -> output depends on the driver in use + * Most drivers return integers: 1 if + * true or 0 if + * false. + * Some return strings: TRUE if + * true or FALSE if + * false. + * Finally one returns strings: T if + * true or F if + * false. Here is a list of each DBMS, + * the values returned and the suggested column type: + *
        + *
      • + * dbase -> T/F + * (Logical) + *
      • + *
      • + * fbase -> TRUE/FALSE + * (BOOLEAN) + *
      • + *
      • + * ibase -> 1/0 + * (SMALLINT) [1] + *
      • + *
      • + * ifx -> 1/0 + * (SMALLINT) [1] + *
      • + *
      • + * msql -> 1/0 + * (INTEGER) + *
      • + *
      • + * mssql -> 1/0 + * (BIT) + *
      • + *
      • + * mysql -> 1/0 + * (TINYINT(1)) + *
      • + *
      • + * mysqli -> 1/0 + * (TINYINT(1)) + *
      • + *
      • + * oci8 -> 1/0 + * (NUMBER(1)) + *
      • + *
      • + * odbc -> 1/0 + * (SMALLINT) [1] + *
      • + *
      • + * pgsql -> TRUE/FALSE + * (BOOLEAN) + *
      • + *
      • + * sqlite -> 1/0 + * (INTEGER) + *
      • + *
      • + * sybase -> 1/0 + * (TINYINT(1)) + *
      • + *
      + * [1] Accommodate the lowest common denominator because not all + * versions of have BOOLEAN. + *
    • + *
    • + * other (including strings and numeric strings) -> + * the data with single quotes escaped by preceeding + * single quotes, backslashes are escaped by preceeding + * backslashes, then the whole string is encapsulated + * between single quotes + *
    • + *
    + * + * @since 1.6.0 + * @see DB_common::escapeSimple() + * @access public + */ + function quoteSmart($in) + { + if (is_int($in) || is_double($in)) { + return $in; + } elseif (is_bool($in)) { + return $in ? 1 : 0; + } elseif (is_null($in)) { + return 'NULL'; + } else { + return "'" . $this->escapeSimple($in) . "'"; + } + } + + // }}} + // {{{ escapeSimple() + + /** + * Escape a string according to the current DBMS's standards + * + * In SQLite, this makes things safe for inserts/updates, but may + * cause problems when performing text comparisons against columns + * containing binary data. See the + * {@link http://php.net/sqlite_escape_string PHP manual} for more info. + * + * @param string $str the string to be escaped + * + * @return string the escaped string + * + * @since 1.6.0 + * @see DB_common::quoteSmart() + * @access public + */ + function escapeSimple($str) { + return str_replace("'", "''", $str); + } + + // }}} + // {{{ provides() + + /** + * Tell whether a DB implementation or its backend extension + * supports a given feature + * + * @param array $feature name of the feature (see the DB class doc) + * @return bool whether this DB implementation supports $feature + * @access public + */ + function provides($feature) + { + return $this->features[$feature]; + } + + // }}} + // {{{ errorCode() + + /** + * Map native error codes to DB's portable ones + * + * Requires that the DB implementation's constructor fills + * in the $errorcode_map property. + * + * @param mixed $nativecode the native error code, as returned by the + * backend database extension (string or integer) + * + * @return int a portable DB error code, or DB_ERROR if this DB + * implementation has no mapping for the given error code. + * + * @access public + */ + function errorCode($nativecode) + { + if (isset($this->errorcode_map[$nativecode])) { + return $this->errorcode_map[$nativecode]; + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; + } + + // }}} + // {{{ errorMessage() + + /** + * Map a DB error code to a textual message. This is actually + * just a wrapper for DB::errorMessage() + * + * @param integer $dbcode the DB error code + * + * @return string the corresponding error message, of false + * if the error code was unknown + * + * @access public + */ + function errorMessage($dbcode) + { + return DB::errorMessage($this->errorcode_map[$dbcode]); + } + + // }}} + // {{{ raiseError() + + /** + * Communicate an error and invoke error callbacks, etc + * + * Basically a wrapper for PEAR::raiseError without the message string. + * + * @param mixed integer error code, or a PEAR error object (all + * other parameters are ignored if this parameter is + * an object + * + * @param int error mode, see PEAR_Error docs + * + * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the + * error level (E_USER_NOTICE etc). If error mode is + * PEAR_ERROR_CALLBACK, this is the callback function, + * either as a function name, or as an array of an + * object and method name. For other error modes this + * parameter is ignored. + * + * @param string Extra debug information. Defaults to the last + * query and native error code. + * + * @param mixed Native error code, integer or string depending the + * backend. + * + * @return object a PEAR error object + * + * @access public + * @see PEAR_Error + */ + function &raiseError($code = DB_ERROR, $mode = null, $options = null, + $userinfo = null, $nativecode = null) + { + // The error is yet a DB error object + if (is_object($code)) { + // because we the static PEAR::raiseError, our global + // handler should be used if it is set + if ($mode === null && !empty($this->_default_error_mode)) { + $mode = $this->_default_error_mode; + $options = $this->_default_error_options; + } + $tmp = PEAR::raiseError($code, null, $mode, $options, null, null, true); + return $tmp; + } + + if ($userinfo === null) { + $userinfo = $this->last_query; + } + + if ($nativecode) { + $userinfo .= ' [nativecode=' . trim($nativecode) . ']'; + } + + $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, + 'DB_Error', true); + return $tmp; + } + + // }}} + // {{{ setFetchMode() + + /** + * Sets which fetch mode should be used by default on queries + * on this connection + * + * @param integer $fetchmode DB_FETCHMODE_ORDERED or + * DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with + * DB_FETCHMODE_FLIPPED. + * + * @param string $object_class The class of the object + * to be returned by the fetch methods when + * the DB_FETCHMODE_OBJECT mode is selected. + * If no class is specified by default a cast + * to object from the assoc array row will be done. + * There is also the posibility to use and extend the + * 'DB_row' class. + * + * @see DB_FETCHMODE_ORDERED + * @see DB_FETCHMODE_ASSOC + * @see DB_FETCHMODE_FLIPPED + * @see DB_FETCHMODE_OBJECT + * @see DB_row::DB_row() + * @access public + */ + function setFetchMode($fetchmode, $object_class = 'stdClass') + { + switch ($fetchmode) { + case DB_FETCHMODE_OBJECT: + $this->fetchmode_object_class = $object_class; + case DB_FETCHMODE_ORDERED: + case DB_FETCHMODE_ASSOC: + $this->fetchmode = $fetchmode; + break; + default: + return $this->raiseError('invalid fetchmode mode'); + } + } + + // }}} + // {{{ setOption() + + /** + * Set run-time configuration options for PEAR DB + * + * Options, their data types, default values and description: + *
      + *
    • + * autofree boolean = false + *
      should results be freed automatically when there are no + * more rows? + *
    • + * debug integer = 0 + *
      debug level + *
    • + * persistent boolean = false + *
      should the connection be persistent? + *
    • + * portability integer = DB_PORTABILITY_NONE + *
      portability mode constant (see below) + *
    • + * seqname_format string = %s_seq + *
      the sprintf() format string used on sequence names. This + * format is applied to sequence names passed to + * createSequence(), nextID() and dropSequence(). + *
    • + * ssl boolean = false + *
      use ssl to connect? + *
    • + *
    + * + * ----------------------------------------- + * + * PORTABILITY MODES + * + * These modes are bitwised, so they can be combined using | + * and removed using ^. See the examples section below on how + * to do this. + * + * DB_PORTABILITY_NONE + * turn off all portability features + * + * This mode gets automatically turned on if the deprecated + * optimize option gets set to performance. + * + * + * DB_PORTABILITY_LOWERCASE + * convert names of tables and fields to lower case when using + * get*(), fetch*() and tableInfo() + * + * This mode gets automatically turned on in the following databases + * if the deprecated option optimize gets set to + * portability: + * + oci8 + * + * + * DB_PORTABILITY_RTRIM + * right trim the data output by get*() fetch*() + * + * + * DB_PORTABILITY_DELETE_COUNT + * force reporting the number of rows deleted + * + * Some DBMS's don't count the number of rows deleted when performing + * simple DELETE FROM tablename queries. This portability + * mode tricks such DBMS's into telling the count by adding + * WHERE 1=1 to the end of DELETE queries. + * + * This mode gets automatically turned on in the following databases + * if the deprecated option optimize gets set to + * portability: + * + fbsql + * + mysql + * + mysqli + * + sqlite + * + * + * DB_PORTABILITY_NUMROWS + * enable hack that makes numRows() work in Oracle + * + * This mode gets automatically turned on in the following databases + * if the deprecated option optimize gets set to + * portability: + * + oci8 + * + * + * DB_PORTABILITY_ERRORS + * makes certain error messages in certain drivers compatible + * with those from other DBMS's + * + * + mysql, mysqli: change unique/primary key constraints + * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT + * + * + odbc(access): MS's ODBC driver reports 'no such field' as code + * 07001, which means 'too few parameters.' When this option is on + * that code gets mapped to DB_ERROR_NOSUCHFIELD. + * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD + * + * + * DB_PORTABILITY_NULL_TO_EMPTY + * convert null values to empty strings in data output by get*() and + * fetch*(). Needed because Oracle considers empty strings to be null, + * while most other DBMS's know the difference between empty and null. + * + * + * DB_PORTABILITY_ALL + * turn on all portability features + * + * ----------------------------------------- + * + * Example 1. Simple setOption() example + * setOption('autofree', true); + * ?> + * + * Example 2. Portability for lowercasing and trimming + * setOption('portability', + * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); + * ?> + * + * Example 3. All portability options except trimming + * setOption('portability', + * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM); + * ?> + * + * @param string $option option name + * @param mixed $value value for the option + * + * @return int DB_OK on success. DB_Error object on failure. + * + * @see DB_common::$options + */ + function setOption($option, $value) + { + if (isset($this->options[$option])) { + $this->options[$option] = $value; + + /* + * Backwards compatibility check for the deprecated 'optimize' + * option. Done here in case settings change after connecting. + */ + if ($option == 'optimize') { + if ($value == 'portability') { + switch ($this->phptype) { + case 'oci8': + $this->options['portability'] = + DB_PORTABILITY_LOWERCASE | + DB_PORTABILITY_NUMROWS; + break; + case 'fbsql': + case 'mysql': + case 'mysqli': + case 'sqlite': + $this->options['portability'] = + DB_PORTABILITY_DELETE_COUNT; + break; + } + } else { + $this->options['portability'] = DB_PORTABILITY_NONE; + } + } + + return DB_OK; + } + return $this->raiseError("unknown option $option"); + } + + // }}} + // {{{ getOption() + + /** + * Returns the value of an option + * + * @param string $option option name + * + * @return mixed the option value + */ + function getOption($option) + { + if (isset($this->options[$option])) { + return $this->options[$option]; + } + return $this->raiseError("unknown option $option"); + } + + // }}} + // {{{ prepare() + + /** + * Prepares a query for multiple execution with execute() + * + * Creates a query that can be run multiple times. Each time it is run, + * the placeholders, if any, will be replaced by the contents of + * execute()'s $data argument. + * + * Three types of placeholders can be used: + * + ? scalar value (i.e. strings, integers). The system + * will automatically quote and escape the data. + * + ! value is inserted 'as is' + * + & requires a file name. The file's contents get + * inserted into the query (i.e. saving binary + * data in a db) + * + * Example 1. + * prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); + * $data = array( + * "John's text", + * "'it''s good'", + * 'filename.txt' + * ); + * $res = $dbh->execute($sth, $data); + * ?> + * + * Use backslashes to escape placeholder characters if you don't want + * them to be interpreted as placeholders: + *
    +     *    "UPDATE foo SET col=? WHERE col='over \& under'"
    +     * 
    + * + * With some database backends, this is emulated. + * + * {@internal ibase and oci8 have their own prepare() methods.}} + * + * @param string $query query to be prepared + * + * @return mixed DB statement resource on success. DB_Error on failure. + * + * @see DB_common::execute() + * @access public + */ + function prepare($query) + { + $tokens = preg_split('/((?prepare_tokens[] = &$newtokens; + end($this->prepare_tokens); + + $k = key($this->prepare_tokens); + $this->prepare_types[$k] = $types; + $this->prepared_queries[$k] = implode(' ', $newtokens); + + return $k; + } + + // }}} + // {{{ autoPrepare() + + /** + * Automaticaly generate an insert or update query and pass it to prepare() + * + * @param string $table name of the table + * @param array $table_fields ordered array containing the fields names + * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) + * @param string $where in case of update queries, this string will be put after the sql WHERE statement + * @return resource handle for the query + * @see DB_common::prepare(), DB_common::buildManipSQL() + * @access public + */ + function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, $where = false) + { + $query = $this->buildManipSQL($table, $table_fields, $mode, $where); + return $this->prepare($query); + } + + // }}} + // {{{ autoExecute() + + /** + * Automaticaly generate an insert or update query and call prepare() + * and execute() with it + * + * @param string $table name of the table + * @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value + * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) + * @param string $where in case of update queries, this string will be put after the sql WHERE statement + * @return mixed a new DB_Result or a DB_Error when fail + * @see DB_common::autoPrepare(), DB_common::buildManipSQL() + * @access public + */ + function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, $where = false) + { + $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, $where); + $ret =& $this->execute($sth, array_values($fields_values)); + $this->freePrepared($sth); + return $ret; + + } + + // }}} + // {{{ buildManipSQL() + + /** + * Make automaticaly an sql query for prepare() + * + * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), DB_AUTOQUERY_INSERT) + * will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) + * NB : - This belongs more to a SQL Builder class, but this is a simple facility + * - Be carefull ! If you don't give a $where param with an UPDATE query, all + * the records of the table will be updated ! + * + * @param string $table name of the table + * @param array $table_fields ordered array containing the fields names + * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) + * @param string $where in case of update queries, this string will be put after the sql WHERE statement + * @return string sql query for prepare() + * @access public + */ + function buildManipSQL($table, $table_fields, $mode, $where = false) + { + if (count($table_fields) == 0) { + $this->raiseError(DB_ERROR_NEED_MORE_DATA); + } + $first = true; + switch ($mode) { + case DB_AUTOQUERY_INSERT: + $values = ''; + $names = ''; + foreach ($table_fields as $value) { + if ($first) { + $first = false; + } else { + $names .= ','; + $values .= ','; + } + $names .= $value; + $values .= '?'; + } + return "INSERT INTO $table ($names) VALUES ($values)"; + case DB_AUTOQUERY_UPDATE: + $set = ''; + foreach ($table_fields as $value) { + if ($first) { + $first = false; + } else { + $set .= ','; + } + $set .= "$value = ?"; + } + $sql = "UPDATE $table SET $set"; + if ($where) { + $sql .= " WHERE $where"; + } + return $sql; + default: + $this->raiseError(DB_ERROR_SYNTAX); + } + } + + // }}} + // {{{ execute() + + /** + * Executes a DB statement prepared with prepare() + * + * Example 1. + * prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); + * $data = array( + * "John's text", + * "'it''s good'", + * 'filename.txt' + * ); + * $res =& $dbh->execute($sth, $data); + * ?> + * + * @param resource $stmt a DB statement resource returned from prepare() + * @param mixed $data array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return object a new DB_Result or a DB_Error when fail + * + * {@internal ibase and oci8 have their own execute() methods.}} + * + * @see DB_common::prepare() + * @access public + */ + function &execute($stmt, $data = array()) + { + $realquery = $this->executeEmulateQuery($stmt, $data); + if (DB::isError($realquery)) { + return $realquery; + } + $result = $this->simpleQuery($realquery); + + if (DB::isError($result) || $result === DB_OK) { + return $result; + } else { + $tmp =& new DB_result($this, $result); + return $tmp; + } + } + + // }}} + // {{{ executeEmulateQuery() + + /** + * Emulates the execute statement, when not supported + * + * @param resource $stmt a DB statement resource returned from execute() + * @param mixed $data array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return mixed a string containing the real query run when emulating + * prepare/execute. A DB error code is returned on failure. + * + * @see DB_common::execute() + * @access private + */ + function executeEmulateQuery($stmt, $data = array()) + { + $stmt = (int)$stmt; + if (!is_array($data)) { + $data = array($data); + } + + if (count($this->prepare_types[$stmt]) != count($data)) { + $this->last_query = $this->prepared_queries[$stmt]; + return $this->raiseError(DB_ERROR_MISMATCH); + } + + $realquery = $this->prepare_tokens[$stmt][0]; + + $i = 0; + foreach ($data as $value) { + if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { + $realquery .= $this->quoteSmart($value); + } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { + $fp = @fopen($value, 'rb'); + if (!$fp) { + return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); + } + $realquery .= $this->quoteSmart(fread($fp, filesize($value))); + fclose($fp); + } else { + $realquery .= $value; + } + + $realquery .= $this->prepare_tokens[$stmt][++$i]; + } + + return $realquery; + } + + // }}} + // {{{ executeMultiple() + + /** + * This function does several execute() calls on the same + * statement handle + * + * $data must be an array indexed numerically + * from 0, one execute call is done for every "row" in the array. + * + * If an error occurs during execute(), executeMultiple() does not + * execute the unfinished rows, but rather returns that error. + * + * @param resource $stmt query handle from prepare() + * @param array $data numeric array containing the + * data to insert into the query + * + * @return mixed DB_OK or DB_Error + * + * @see DB_common::prepare(), DB_common::execute() + * @access public + */ + function executeMultiple($stmt, $data) + { + foreach ($data as $value) { + $res =& $this->execute($stmt, $value); + if (DB::isError($res)) { + return $res; + } + } + return DB_OK; + } + + // }}} + // {{{ freePrepared() + + /** + * Free the resource used in a prepared query + * + * @param $stmt The resurce returned by the prepare() function + * @see DB_common::prepare() + */ + function freePrepared($stmt) + { + $stmt = (int)$stmt; + // Free the internal prepared vars + if (isset($this->prepare_tokens[$stmt])) { + unset($this->prepare_tokens[$stmt]); + unset($this->prepare_types[$stmt]); + unset($this->prepared_queries[$stmt]); + return true; + } + return false; + } + + // }}} + // {{{ modifyQuery() + + /** + * This method is used by backends to alter queries for various + * reasons + * + * It is defined here to assure that all implementations + * have this method defined. + * + * @param string $query query to modify + * + * @return the new (modified) query + * + * @access private + */ + function modifyQuery($query) { + return $query; + } + + // }}} + // {{{ modifyLimitQuery() + + /** + * This method is used by backends to alter limited queries + * + * @param string $query query to modify + * @param integer $from the row to start to fetching + * @param integer $count the numbers of rows to fetch + * + * @return the new (modified) query + * + * @access private + */ + function modifyLimitQuery($query, $from, $count, $params = array()) + { + return $query; + } + + // }}} + // {{{ query() + + /** + * Send a query to the database and return any results with a + * DB_result object + * + * The query string can be either a normal statement to be sent directly + * to the server OR if $params are passed the query can have + * placeholders and it will be passed through prepare() and execute(). + * + * @param string $query the SQL query or the statement to prepare + * @param mixed $params array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return mixed a DB_result object or DB_OK on success, a DB + * error on failure + * + * @see DB_result, DB_common::prepare(), DB_common::execute() + * @access public + */ + function &query($query, $params = array()) + { + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + if (DB::isError($sth)) { + return $sth; + } + $ret =& $this->execute($sth, $params); + $this->freePrepared($sth); + return $ret; + } else { + $result = $this->simpleQuery($query); + if (DB::isError($result) || $result === DB_OK) { + return $result; + } else { + $tmp =& new DB_result($this, $result); + return $tmp; + } + } + } + + // }}} + // {{{ limitQuery() + + /** + * Generates a limited query + * + * @param string $query query + * @param integer $from the row to start to fetching + * @param integer $count the numbers of rows to fetch + * @param mixed $params array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return mixed a DB_Result object, DB_OK or a DB_Error + * + * @access public + */ + function &limitQuery($query, $from, $count, $params = array()) + { + $query = $this->modifyLimitQuery($query, $from, $count, $params); + if (DB::isError($query)){ + return $query; + } + $result =& $this->query($query, $params); + if (is_a($result, 'DB_result')) { + $result->setOption('limit_from', $from); + $result->setOption('limit_count', $count); + } + return $result; + } + + // }}} + // {{{ getOne() + + /** + * Fetch the first column of the first row of data returned from + * a query + * + * Takes care of doing the query and freeing the results when finished. + * + * @param string $query the SQL query + * @param mixed $params array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return mixed the returned value of the query. DB_Error on failure. + * + * @access public + */ + function &getOne($query, $params = array()) + { + settype($params, 'array'); + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + if (DB::isError($sth)) { + return $sth; + } + $res =& $this->execute($sth, $params); + $this->freePrepared($sth); + } else { + $res =& $this->query($query); + } + + if (DB::isError($res)) { + return $res; + } + + $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); + $res->free(); + + if ($err !== DB_OK) { + return $err; + } + + return $row[0]; + } + + // }}} + // {{{ getRow() + + /** + * Fetch the first row of data returned from a query + * + * Takes care of doing the query and freeing the results when finished. + * + * @param string $query the SQL query + * @param array $params array to be used in execution of the statement. + * Quantity of array elements must match quantity + * of placeholders in query. This function does + * NOT support scalars. + * @param int $fetchmode the fetch mode to use + * + * @return array the first row of results as an array indexed from + * 0, or a DB error code. + * + * @access public + */ + function &getRow($query, + $params = array(), + $fetchmode = DB_FETCHMODE_DEFAULT) + { + // compat check, the params and fetchmode parameters used to + // have the opposite order + if (!is_array($params)) { + if (is_array($fetchmode)) { + if ($params === null) { + $tmp = DB_FETCHMODE_DEFAULT; + } else { + $tmp = $params; + } + $params = $fetchmode; + $fetchmode = $tmp; + } elseif ($params !== null) { + $fetchmode = $params; + $params = array(); + } + } + + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + if (DB::isError($sth)) { + return $sth; + } + $res =& $this->execute($sth, $params); + $this->freePrepared($sth); + } else { + $res =& $this->query($query); + } + + if (DB::isError($res)) { + return $res; + } + + $err = $res->fetchInto($row, $fetchmode); + + $res->free(); + + if ($err !== DB_OK) { + return $err; + } + + return $row; + } + + // }}} + // {{{ getCol() + + /** + * Fetch a single column from a result set and return it as an + * indexed array + * + * @param string $query the SQL query + * @param mixed $col which column to return (integer [column number, + * starting at 0] or string [column name]) + * @param mixed $params array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * + * @return array an indexed array with the data from the first + * row at index 0, or a DB error code + * + * @see DB_common::query() + * @access public + */ + function &getCol($query, $col = 0, $params = array()) + { + settype($params, 'array'); + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + + if (DB::isError($sth)) { + return $sth; + } + + $res =& $this->execute($sth, $params); + $this->freePrepared($sth); + } else { + $res =& $this->query($query); + } + + if (DB::isError($res)) { + return $res; + } + + $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; + + if (!is_array($row = $res->fetchRow($fetchmode))) { + $ret = array(); + } else { + if (!array_key_exists($col, $row)) { + $ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD); + } else { + $ret = array($row[$col]); + while (is_array($row = $res->fetchRow($fetchmode))) { + $ret[] = $row[$col]; + } + } + } + + $res->free(); + + if (DB::isError($row)) { + $ret = $row; + } + + return $ret; + } + + // }}} + // {{{ getAssoc() + + /** + * Fetch the entire result set of a query and return it as an + * associative array using the first column as the key + * + * If the result set contains more than two columns, the value + * will be an array of the values from column 2-n. If the result + * set contains only two columns, the returned value will be a + * scalar with the value of the second column (unless forced to an + * array with the $force_array parameter). A DB error code is + * returned on errors. If the result set contains fewer than two + * columns, a DB_ERROR_TRUNCATED error is returned. + * + * For example, if the table "mytable" contains: + * + *
    +     *  ID      TEXT       DATE
    +     * --------------------------------
    +     *  1       'one'      944679408
    +     *  2       'two'      944679408
    +     *  3       'three'    944679408
    +     * 
    + * + * Then the call getAssoc('SELECT id,text FROM mytable') returns: + *
    +     *   array(
    +     *     '1' => 'one',
    +     *     '2' => 'two',
    +     *     '3' => 'three',
    +     *   )
    +     * 
    + * + * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns: + *
    +     *   array(
    +     *     '1' => array('one', '944679408'),
    +     *     '2' => array('two', '944679408'),
    +     *     '3' => array('three', '944679408')
    +     *   )
    +     * 
    + * + * If the more than one row occurs with the same value in the + * first column, the last row overwrites all previous ones by + * default. Use the $group parameter if you don't want to + * overwrite like this. Example: + * + *
    +     * getAssoc('SELECT category,id,name FROM mytable', false, null,
    +     *          DB_FETCHMODE_ASSOC, true) returns:
    +     *
    +     *   array(
    +     *     '1' => array(array('id' => '4', 'name' => 'number four'),
    +     *                  array('id' => '6', 'name' => 'number six')
    +     *            ),
    +     *     '9' => array(array('id' => '4', 'name' => 'number four'),
    +     *                  array('id' => '6', 'name' => 'number six')
    +     *            )
    +     *   )
    +     * 
    + * + * Keep in mind that database functions in PHP usually return string + * values for results regardless of the database's internal type. + * + * @param string $query the SQL query + * @param boolean $force_array used only when the query returns + * exactly two columns. If true, the values + * of the returned array will be one-element + * arrays instead of scalars. + * @param mixed $params array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 placeholder for non-array + * parameters or 1 placeholder per array element. + * @param int $fetchmode the fetch mode to use + * @param boolean $group if true, the values of the returned array + * is wrapped in another array. If the same + * key value (in the first column) repeats + * itself, the values will be appended to + * this array instead of overwriting the + * existing values. + * + * @return array associative array with results from the query. + * DB Error on failure. + * + * @access public + */ + function &getAssoc($query, $force_array = false, $params = array(), + $fetchmode = DB_FETCHMODE_DEFAULT, $group = false) + { + settype($params, 'array'); + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + + if (DB::isError($sth)) { + return $sth; + } + + $res =& $this->execute($sth, $params); + $this->freePrepared($sth); + } else { + $res =& $this->query($query); + } + + if (DB::isError($res)) { + return $res; + } + if ($fetchmode == DB_FETCHMODE_DEFAULT) { + $fetchmode = $this->fetchmode; + } + $cols = $res->numCols(); + + if ($cols < 2) { + $tmp =& $this->raiseError(DB_ERROR_TRUNCATED); + return $tmp; + } + + $results = array(); + + if ($cols > 2 || $force_array) { + // return array values + // XXX this part can be optimized + if ($fetchmode == DB_FETCHMODE_ASSOC) { + while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { + reset($row); + $key = current($row); + unset($row[key($row)]); + if ($group) { + $results[$key][] = $row; + } else { + $results[$key] = $row; + } + } + } elseif ($fetchmode == DB_FETCHMODE_OBJECT) { + while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { + $arr = get_object_vars($row); + $key = current($arr); + if ($group) { + $results[$key][] = $row; + } else { + $results[$key] = $row; + } + } + } else { + while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { + // we shift away the first element to get + // indices running from 0 again + $key = array_shift($row); + if ($group) { + $results[$key][] = $row; + } else { + $results[$key] = $row; + } + } + } + if (DB::isError($row)) { + $results = $row; + } + } else { + // return scalar values + while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { + if ($group) { + $results[$row[0]][] = $row[1]; + } else { + $results[$row[0]] = $row[1]; + } + } + if (DB::isError($row)) { + $results = $row; + } + } + + $res->free(); + + return $results; + } + + // }}} + // {{{ getAll() + + /** + * Fetch all the rows returned from a query + * + * @param string $query the SQL query + * @param array $params array to be used in execution of the statement. + * Quantity of array elements must match quantity + * of placeholders in query. This function does + * NOT support scalars. + * @param int $fetchmode the fetch mode to use + * + * @return array an nested array. DB error on failure. + * + * @access public + */ + function &getAll($query, + $params = array(), + $fetchmode = DB_FETCHMODE_DEFAULT) + { + // compat check, the params and fetchmode parameters used to + // have the opposite order + if (!is_array($params)) { + if (is_array($fetchmode)) { + if ($params === null) { + $tmp = DB_FETCHMODE_DEFAULT; + } else { + $tmp = $params; + } + $params = $fetchmode; + $fetchmode = $tmp; + } elseif ($params !== null) { + $fetchmode = $params; + $params = array(); + } + } + + if (sizeof($params) > 0) { + $sth = $this->prepare($query); + + if (DB::isError($sth)) { + return $sth; + } + + $res =& $this->execute($sth, $params); + $this->freePrepared($sth); + } else { + $res =& $this->query($query); + } + + if (DB::isError($res) || $res === DB_OK) { + return $res; + } + + $results = array(); + while (DB_OK === $res->fetchInto($row, $fetchmode)) { + if ($fetchmode & DB_FETCHMODE_FLIPPED) { + foreach ($row as $key => $val) { + $results[$key][] = $val; + } + } else { + $results[] = $row; + } + } + + $res->free(); + + if (DB::isError($row)) { + $tmp =& $this->raiseError($row); + return $tmp; + } + return $results; + } + + // }}} + // {{{ autoCommit() + + /** + * enable automatic Commit + * + * @param boolean $onoff + * @return mixed DB_Error + * + * @access public + */ + function autoCommit($onoff=false) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ commit() + + /** + * starts a Commit + * + * @return mixed DB_Error + * + * @access public + */ + function commit() + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ rollback() + + /** + * starts a rollback + * + * @return mixed DB_Error + * + * @access public + */ + function rollback() + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ numRows() + + /** + * Returns the number of rows in a result object + * + * @param object DB_Result the result object to check + * + * @return mixed DB_Error or the number of rows + * + * @access public + */ + function numRows($result) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ affectedRows() + + /** + * Returns the affected rows of a query + * + * @return mixed DB_Error or number of rows + * + * @access public + */ + function affectedRows() + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ errorNative() + + /** + * Returns an errormessage, provides by the database + * + * @return mixed DB_Error or message + * + * @access public + */ + function errorNative() + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ getSequenceName() + + /** + * Generate the name used inside the database for a sequence + * + * The createSequence() docblock contains notes about storing sequence + * names. + * + * @param string $sqn the sequence's public name + * + * @return string the sequence's name in the backend + * + * @see DB_common::createSequence(), DB_common::dropSequence(), + * DB_common::nextID(), DB_common::setOption() + * @access private + */ + function getSequenceName($sqn) + { + return sprintf($this->getOption('seqname_format'), + preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @see DB_common::createSequence(), DB_common::dropSequence(), + * DB_common::getSequenceName() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ createSequence() + + /** + * Creates a new sequence + * + * The name of a given sequence is determined by passing the string + * provided in the $seq_name argument through PHP's sprintf() + * function using the value from the seqname_format option as + * the sprintf()'s format argument. + * + * seqname_format is set via setOption(). + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @see DB_common::dropSequence(), DB_common::getSequenceName(), + * DB_common::nextID() + * @access public + */ + function createSequence($seq_name) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @see DB_common::createSequence(), DB_common::getSequenceName(), + * DB_common::nextID() + * @access public + */ + function dropSequence($seq_name) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set + * + * The format of the resulting array depends on which $mode + * you select. The sample output below is based on this query: + *
    +     *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
    +     *    FROM tblFoo
    +     *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
    +     * 
    + * + *
      + *
    • + * + * null (default) + *
      +     *   [0] => Array (
      +     *       [table] => tblFoo
      +     *       [name] => fldId
      +     *       [type] => int
      +     *       [len] => 11
      +     *       [flags] => primary_key not_null
      +     *   )
      +     *   [1] => Array (
      +     *       [table] => tblFoo
      +     *       [name] => fldPhone
      +     *       [type] => string
      +     *       [len] => 20
      +     *       [flags] =>
      +     *   )
      +     *   [2] => Array (
      +     *       [table] => tblBar
      +     *       [name] => fldId
      +     *       [type] => int
      +     *       [len] => 11
      +     *       [flags] => primary_key not_null
      +     *   )
      +     *   
      + * + *
    • + * + * DB_TABLEINFO_ORDER + * + *

      In addition to the information found in the default output, + * a notation of the number of columns is provided by the + * num_fields element while the order + * element provides an array with the column names as the keys and + * their location index number (corresponding to the keys in the + * the default output) as the values.

      + * + *

      If a result set has identical field names, the last one is + * used.

      + * + *
      +     *   [num_fields] => 3
      +     *   [order] => Array (
      +     *       [fldId] => 2
      +     *       [fldTrans] => 1
      +     *   )
      +     *   
      + * + *
    • + * + * DB_TABLEINFO_ORDERTABLE + * + *

      Similar to DB_TABLEINFO_ORDER but adds more + * dimensions to the array in which the table names are keys and + * the field names are sub-keys. This is helpful for queries that + * join tables which have identical field names.

      + * + *
      +     *   [num_fields] => 3
      +     *   [ordertable] => Array (
      +     *       [tblFoo] => Array (
      +     *           [fldId] => 0
      +     *           [fldPhone] => 1
      +     *       )
      +     *       [tblBar] => Array (
      +     *           [fldId] => 2
      +     *       )
      +     *   )
      +     *   
      + * + *
    • + *
    + * + * The flags element contains a space separated list + * of extra information about the field. This data is inconsistent + * between DBMS's due to the way each DBMS works. + * + primary_key + * + unique_key + * + multiple_key + * + not_null + * + * Most DBMS's only provide the table and flags + * elements if $result is a table name. The following DBMS's + * provide full information from queries: + * + fbsql + * + mysql + * + * If the 'portability' option has DB_PORTABILITY_LOWERCASE + * turned on, the names of tables and fields will be lowercased. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table. + * While this also accepts a query result + * resource identifier, this behavior is + * deprecated. + * @param int $mode either unused or one of the tableInfo modes: + * DB_TABLEINFO_ORDERTABLE, + * DB_TABLEINFO_ORDER or + * DB_TABLEINFO_FULL (which does both). + * These are bitwise, so the first two can be + * combined using |. + * @return array an associative array with the information requested. + * If something goes wrong an error object is returned. + * + * @see DB_common::setOption() + * @access public + */ + function tableInfo($result, $mode = null) + { + /* + * If the DB_ class has a tableInfo() method, that one + * overrides this one. But, if the driver doesn't have one, + * this method runs and tells users about that fact. + */ + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ getTables() + + /** + * @deprecated Deprecated in release 1.2 or lower + */ + function getTables() + { + return $this->getListOf('tables'); + } + + // }}} + // {{{ getListOf() + + /** + * list internal DB info + * valid values for $type are db dependent, + * often: databases, users, view, functions + * + * @param string $type type of requested info + * + * @return mixed DB_Error or the requested data + * + * @access public + */ + function getListOf($type) + { + $sql = $this->getSpecialQuery($type); + if ($sql === null) { // No support + return $this->raiseError(DB_ERROR_UNSUPPORTED); + } elseif (is_int($sql) || DB::isError($sql)) { // Previous error + return $this->raiseError($sql); + } elseif (is_array($sql)) { // Already the result + return $sql; + } + return $this->getCol($sql); // Launch this query + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * + * @param string $type What kind of info you want to retrieve + * + * @return string The SQL query string + * + * @access public + */ + function getSpecialQuery($type) + { + return $this->raiseError(DB_ERROR_UNSUPPORTED); + } + + // }}} + // {{{ _rtrimArrayValues() + + /** + * Right trim all strings in an array + * + * @param array $array the array to be trimmed (passed by reference) + * @return void + * @access private + */ + function _rtrimArrayValues(&$array) + { + foreach ($array as $key => $value) { + if (is_string($value)) { + $array[$key] = rtrim($value); + } + } + } + + // }}} + // {{{ _convertNullArrayValuesToEmpty() + + /** + * Convert all null values in an array to empty strings + * + * @param array $array the array to be de-nullified (passed by reference) + * @return void + * @access private + */ + function _convertNullArrayValuesToEmpty(&$array) + { + foreach ($array as $key => $value) { + if (is_null($value)) { + $array[$key] = ''; + } + } + } + + // }}} +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/dbase.php b/gulliver/thirdparty/pear/DB/dbase.php new file mode 100644 index 000000000..89b27a16d --- /dev/null +++ b/gulliver/thirdparty/pear/DB/dbase.php @@ -0,0 +1,225 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: dbase.php 3355 2005-06-11 22:14:40Z nbm $ + + +// XXX legend: +// You have to compile your PHP with the --enable-dbase option + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's dbase + * extension. + * + * @package DB + * @version $Id: dbase.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Stig Bakken + */ +class DB_dbase extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $res_row = array(); + var $result = 0; + + // }}} + // {{{ constructor + + /** + * DB_mysql constructor. + * + * @access public + */ + function DB_dbase() + { + $this->DB_common(); + $this->phptype = 'dbase'; + $this->dbsyntax = 'dbase'; + $this->features = array( + 'prepare' => false, + 'pconnect' => false, + 'transactions' => false, + 'limit' => false + ); + $this->errorcode_map = array(); + } + + // }}} + // {{{ connect() + + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('dbase')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + + $ini = ini_get('track_errors'); + if ($ini) { + $conn = @dbase_open($dsninfo['database'], 0); + } else { + ini_set('track_errors', 1); + $conn = @dbase_open($dsninfo['database'], 0); + ini_set('track_errors', $ini); + } + if (!$conn) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, + null, null, strip_tags($php_errormsg)); + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + function disconnect() + { + $ret = @dbase_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ &query() + + function &query($query = null) + { + // emulate result resources + $this->res_row[(int)$this->result] = 0; + $tmp =& new DB_result($this, $this->result++); + return $tmp; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum === null) { + $rownum = $this->res_row[(int)$result]++; + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @dbase_get_record_with_names($this->connection, $rownum); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @dbase_get_record($this->connection, $rownum); + } + if (!$arr) { + return null; + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ numCols() + + function numCols($foo) + { + return @dbase_numfields($this->connection); + } + + // }}} + // {{{ numRows() + + function numRows($foo) + { + return @dbase_numrecords($this->connection); + } + + // }}} + // {{{ quoteSmart() + + /** + * Format input so it can be safely used in a query + * + * @param mixed $in data to be quoted + * + * @return mixed Submitted variable's type = returned value: + * + null = the string NULL + * + boolean = T if true or + * F if false. Use the Logical + * data type. + * + integer or double = the unquoted number + * + other (including strings and numeric strings) = + * the data with single quotes escaped by preceeding + * single quotes then the whole string is encapsulated + * between single quotes + * + * @internal + */ + function quoteSmart($in) + { + if (is_int($in) || is_double($in)) { + return $in; + } elseif (is_bool($in)) { + return $in ? 'T' : 'F'; + } elseif (is_null($in)) { + return 'NULL'; + } else { + return "'" . $this->escapeSimple($in) . "'"; + } + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/fbsql.php b/gulliver/thirdparty/pear/DB/fbsql.php new file mode 100644 index 000000000..540580a79 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/fbsql.php @@ -0,0 +1,655 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: fbsql.php 3355 2005-06-11 22:14:40Z nbm $ + + +// XXX legend: +// +// XXX ERRORMSG: The error message from the fbsql function should +// be registered here. +// +// TODO/wishlist: +// longReadlen +// binmode + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's FrontBase + * extension. + * + * @package DB + * @version $Id: fbsql.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Frank M. Kromann + */ +class DB_fbsql extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $num_rows = array(); + var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ + + // }}} + // {{{ constructor + + /** + * DB_fbsql constructor. + * + * @access public + */ + function DB_fbsql() + { + $this->DB_common(); + $this->phptype = 'fbsql'; + $this->dbsyntax = 'fbsql'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'emulate' + ); + $this->errorcode_map = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1046 => DB_ERROR_NODBSELECTED, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * @access public + * @return int DB_OK on success, a DB error on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('fbsql')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; + + $php_errormsg = ''; + $connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect'; + + if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { + $conn = @$connect_function($dbhost, $dsninfo['username'], + $dsninfo['password']); + } elseif ($dbhost && $dsninfo['username']) { + $conn = @$connect_function($dbhost, $dsninfo['username']); + } elseif ($dbhost) { + $conn = @$connect_function($dbhost); + } else { + $conn = false; + } + if (!$conn) { + if (empty($php_errormsg)) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED); + } else { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $php_errormsg); + } + } + + if ($dsninfo['database']) { + if (!fbsql_select_db($dsninfo['database'], $conn)) { + return $this->fbsqlRaiseError(); + } + } + + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @access public + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @fbsql_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to fbsql and return the results as a fbsql resource + * identifier. + * + * @param the SQL query + * + * @access public + * + * @return mixed returns a valid fbsql result for successful SELECT + * queries, DB_OK for other successful queries. A DB error is + * returned on failure. + */ + function simpleQuery($query) + { + $this->last_query = $query; + $query = $this->modifyQuery($query); + $result = @fbsql_query("$query;", $this->connection); + if (!$result) { + return $this->fbsqlRaiseError(); + } + // Determine which queries that should return data, and which + // should return an error code only. + if (DB::isManip($query)) { + return DB_OK; + } + $numrows = $this->numrows($result); + if (is_object($numrows)) { + return $numrows; + } + $this->num_rows[(int)$result] = $numrows; + return $result; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal fbsql result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return @fbsql_next_result($result); + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@fbsql_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @fbsql_fetch_array($result, FBSQL_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @fbsql_fetch_row($result); + } + if (!$arr) { + $errno = @fbsql_errno($this->connection); + if (!$errno) { + return null; + } + return $this->fbsqlRaiseError($errno); + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result fbsql result identifier + * + * @access public + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + return @fbsql_free_result($result); + } + + // }}} + // {{{ autoCommit() + + function autoCommit($onoff=false) + { + if ($onoff) { + $this->query("SET COMMIT TRUE"); + } else { + $this->query("SET COMMIT FALSE"); + } + } + + // }}} + // {{{ commit() + + function commit() + { + @fbsql_commit(); + } + + // }}} + // {{{ rollback() + + function rollback() + { + @fbsql_rollback(); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result fbsql result identifier + * + * @access public + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @fbsql_num_fields($result); + + if (!$cols) { + return $this->fbsqlRaiseError(); + } + + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @param $result fbsql result identifier + * + * @access public + * + * @return int the number of rows in $result + */ + function numRows($result) + { + $rows = @fbsql_num_rows($result); + if ($rows === null) { + return $this->fbsqlRaiseError(); + } + return $rows; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the data manipulation + * query. For other queries, this function returns 0. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + $result = @fbsql_affected_rows($this->connection); + } else { + $result = 0; + } + return $result; + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that + * occured on the current connection. + * + * @access public + * + * @return int native fbsql error code + */ + function errorNative() + { + return @fbsql_errno($this->connection); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + $repeat = 0; + do { + $result = $this->query("INSERT INTO ${seqname} (id) VALUES (NULL)"); + if ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) { + $repeat = 1; + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $result; + } + } else { + $repeat = 0; + } + } while ($repeat); + if (DB::isError($result)) { + return $result; + } + return @fbsql_insert_id($this->connection); + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("CREATE TABLE ${seqname} ". + '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. + ' PRIMARY KEY(id))'); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP TABLE ${seqname} RESTRICT"); + } + + // }}} + // {{{ modifyQuery() + + function modifyQuery($query) + { + if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { + // "DELETE FROM table" gives 0 affected rows in fbsql. + // This little hack lets you know how many rows were deleted. + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { + $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', + 'DELETE FROM \1 WHERE 1=1', $query); + } + } + return $query; + } + + // }}} + // {{{ quoteSmart() + + /** + * Format input so it can be safely used in a query + * + * @param mixed $in data to be quoted + * + * @return mixed Submitted variable's type = returned value: + * + null = the string NULL + * + boolean = string TRUE or FALSE + * + integer or double = the unquoted number + * + other (including strings and numeric strings) = + * the data escaped according to MySQL's settings + * then encapsulated between single quotes + * + * @internal + */ + function quoteSmart($in) + { + if (is_int($in) || is_double($in)) { + return $in; + } elseif (is_bool($in)) { + return $in ? 'TRUE' : 'FALSE'; + } elseif (is_null($in)) { + return 'NULL'; + } else { + return "'" . $this->escapeSimple($in) . "'"; + } + } + + // }}} + // {{{ fbsqlRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function fbsqlRaiseError($errno = null) + { + if ($errno === null) { + $errno = $this->errorCode(fbsql_errno($this->connection)); + } + return $this->raiseError($errno, null, null, null, + @fbsql_error($this->connection)); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @fbsql_list_fields($this->dsn['database'], + $result, $this->connection); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @fbsql_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $case_func(@fbsql_field_table($id, $i)); + $res[$i]['name'] = $case_func(@fbsql_field_name($id, $i)); + $res[$i]['type'] = @fbsql_field_type($id, $i); + $res[$i]['len'] = @fbsql_field_len($id, $i); + $res[$i]['flags'] = @fbsql_field_flags($id, $i); + } + } else { // full + $res["num_fields"]= $count; + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $case_func(@fbsql_field_table($id, $i)); + $res[$i]['name'] = $case_func(@fbsql_field_name($id, $i)); + $res[$i]['type'] = @fbsql_field_type($id, $i); + $res[$i]['len'] = @fbsql_field_len($id, $i); + $res[$i]['flags'] = @fbsql_field_flags($id, $i); + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @fbsql_free_result($id); + } + return $res; + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return 'select "table_name" from information_schema.tables'; + default: + return null; + } + } + + // }}} +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/ibase.php b/gulliver/thirdparty/pear/DB/ibase.php new file mode 100644 index 000000000..7100975bf --- /dev/null +++ b/gulliver/thirdparty/pear/DB/ibase.php @@ -0,0 +1,784 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: ibase.php 3355 2005-06-11 22:14:40Z nbm $ + + +// Bugs: +// - If dbsyntax is not firebird, the limitQuery may fail + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Interbase + * extension. + * + * @package DB + * @version $Id: ibase.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Sterling Hughes + */ +class DB_ibase extends DB_common +{ + + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $autocommit = 1; + var $manip_query = array(); + + // }}} + // {{{ constructor + + function DB_ibase() + { + $this->DB_common(); + $this->phptype = 'ibase'; + $this->dbsyntax = 'ibase'; + $this->features = array( + 'prepare' => true, + 'pconnect' => true, + 'transactions' => true, + 'limit' => false + ); + // just a few of the tons of Interbase error codes listed in the + // Language Reference section of the Interbase manual + $this->errorcode_map = array( + -104 => DB_ERROR_SYNTAX, + -150 => DB_ERROR_ACCESS_VIOLATION, + -151 => DB_ERROR_ACCESS_VIOLATION, + -155 => DB_ERROR_NOSUCHTABLE, + 88 => DB_ERROR_NOSUCHTABLE, + -157 => DB_ERROR_NOSUCHFIELD, + -158 => DB_ERROR_VALUE_COUNT_ON_ROW, + -170 => DB_ERROR_MISMATCH, + -171 => DB_ERROR_MISMATCH, + -172 => DB_ERROR_INVALID, + -204 => DB_ERROR_INVALID, + -205 => DB_ERROR_NOSUCHFIELD, + -206 => DB_ERROR_NOSUCHFIELD, + -208 => DB_ERROR_INVALID, + -219 => DB_ERROR_NOSUCHTABLE, + -297 => DB_ERROR_CONSTRAINT, + -530 => DB_ERROR_CONSTRAINT, + -607 => DB_ERROR_NOSUCHTABLE, + -803 => DB_ERROR_CONSTRAINT, + -551 => DB_ERROR_ACCESS_VIOLATION, + -552 => DB_ERROR_ACCESS_VIOLATION, + -922 => DB_ERROR_NOSUCHDB, + -923 => DB_ERROR_CONNECT_FAILED, + -924 => DB_ERROR_CONNECT_FAILED + ); + } + + // }}} + // {{{ connect() + + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('interbase')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + $dbhost = $dsninfo['hostspec'] ? + ($dsninfo['hostspec'] . ':' . $dsninfo['database']) : + $dsninfo['database']; + + $connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; + + $params = array(); + $params[] = $dbhost; + $params[] = $dsninfo['username'] ? $dsninfo['username'] : null; + $params[] = $dsninfo['password'] ? $dsninfo['password'] : null; + $params[] = isset($dsninfo['charset']) ? $dsninfo['charset'] : null; + $params[] = isset($dsninfo['buffers']) ? $dsninfo['buffers'] : null; + $params[] = isset($dsninfo['dialect']) ? $dsninfo['dialect'] : null; + $params[] = isset($dsninfo['role']) ? $dsninfo['role'] : null; + + $conn = @call_user_func_array($connect_function, $params); + if (!$conn) { + return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); + } + $this->connection = $conn; + if ($this->dsn['dbsyntax'] == 'firebird') { + $this->features['limit'] = 'alter'; + } + return DB_OK; + } + + // }}} + // {{{ disconnect() + + function disconnect() + { + $ret = @ibase_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $query = $this->modifyQuery($query); + $result = @ibase_query($this->connection, $query); + if (!$result) { + return $this->ibaseRaiseError(); + } + if ($this->autocommit && $ismanip) { + @ibase_commit($this->connection); + } + // Determine which queries that should return data, and which + // should return an error code only. + return $ismanip ? DB_OK : $result; + } + + // }}} + // {{{ modifyLimitQuery() + + /** + * This method is used by backends to alter limited queries + * Uses the new FIRST n SKIP n Firebird 1.0 syntax, so it is + * only compatible with Firebird 1.x + * + * @param string $query query to modify + * @param integer $from the row to start to fetching + * @param integer $count the numbers of rows to fetch + * + * @return the new (modified) query + * @author Ludovico Magnocavallo + * @access private + */ + function modifyLimitQuery($query, $from, $count, $params = array()) + { + if ($this->dsn['dbsyntax'] == 'firebird') { + //$from++; // SKIP starts from 1, ie SKIP 1 starts from the first record + // (cox) Seems that SKIP starts in 0 + $query = preg_replace('/^\s*select\s(.*)$/is', + "SELECT FIRST $count SKIP $from $1", $query); + } + return $query; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal ibase result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + if (function_exists('ibase_fetch_assoc')) { + $arr = @ibase_fetch_assoc($result); + } else { + $arr = get_object_vars(ibase_fetch_object($result)); + } + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @ibase_fetch_row($result); + } + if (!$arr) { + if ($errmsg = @ibase_errmsg()) { + return $this->ibaseRaiseError(null, $errmsg); + } else { + return null; + } + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + function freeResult($result) + { + return @ibase_free_result($result); + } + + // }}} + // {{{ freeQuery() + + function freeQuery($query) + { + @ibase_free_query($query); + return true; + } + + // }}} + // {{{ numCols() + + function numCols($result) + { + $cols = @ibase_num_fields($result); + if (!$cols) { + return $this->ibaseRaiseError(); + } + return $cols; + } + + // }}} + // {{{ prepare() + + /** + * Prepares a query for multiple execution with execute(). + * + * prepare() requires a generic query as string like + * INSERT INTO numbers VALUES (?, ?, ?) + * . The ? characters are placeholders. + * + * Three types of placeholders can be used: + * + ? a quoted scalar value, i.e. strings, integers + * + ! value is inserted 'as is' + * + & requires a file name. The file's contents get + * inserted into the query (i.e. saving binary + * data in a db) + * + * Use backslashes to escape placeholder characters if you don't want + * them to be interpreted as placeholders. Example: + * "UPDATE foo SET col=? WHERE col='over \& under'" + * + * + * @param string $query query to be prepared + * @return mixed DB statement resource on success. DB_Error on failure. + */ + function prepare($query) + { + $tokens = preg_split('/((? $val) { + switch ($val) { + case '?': + $types[$token++] = DB_PARAM_SCALAR; + break; + case '&': + $types[$token++] = DB_PARAM_OPAQUE; + break; + case '!': + $types[$token++] = DB_PARAM_MISC; + break; + default: + $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); + $newquery .= $tokens[$key] . '?'; + } + } + + $newquery = substr($newquery, 0, -1); + $this->last_query = $query; + $newquery = $this->modifyQuery($newquery); + $stmt = @ibase_prepare($this->connection, $newquery); + $this->prepare_types[(int)$stmt] = $types; + $this->manip_query[(int)$stmt] = DB::isManip($query); + return $stmt; + } + + // }}} + // {{{ execute() + + /** + * Executes a DB statement prepared with prepare(). + * + * @param resource $stmt a DB statement resource returned from prepare() + * @param mixed $data array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 for non-array items or the + * quantity of elements in the array. + * @return object a new DB_Result or a DB_Error when fail + * @see DB_ibase::prepare() + * @access public + */ + function &execute($stmt, $data = array()) + { + if (!is_array($data)) { + $data = array($data); + } + + $types =& $this->prepare_types[(int)$stmt]; + if (count($types) != count($data)) { + $tmp =& $this->raiseError(DB_ERROR_MISMATCH); + return $tmp; + } + + $i = 0; + foreach ($data as $key => $value) { + if ($types[$i] == DB_PARAM_MISC) { + /* + * ibase doesn't seem to have the ability to pass a + * parameter along unchanged, so strip off quotes from start + * and end, plus turn two single quotes to one single quote, + * in order to avoid the quotes getting escaped by + * ibase and ending up in the database. + */ + $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); + $data[$key] = str_replace("''", "'", $data[$key]); + } elseif ($types[$i] == DB_PARAM_OPAQUE) { + $fp = @fopen($data[$key], 'rb'); + if (!$fp) { + $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); + return $tmp; + } + $data[$key] = fread($fp, filesize($data[$key])); + fclose($fp); + } + $i++; + } + + array_unshift($data, $stmt); + + $res = call_user_func_array('ibase_execute', $data); + if (!$res) { + $tmp =& $this->ibaseRaiseError(); + return $tmp; + } + /* XXX need this? + if ($this->autocommit && $this->manip_query[(int)$stmt]) { + @ibase_commit($this->connection); + }*/ + if ($this->manip_query[(int)$stmt]) { + $tmp = DB_OK; + } else { + $tmp =& new DB_result($this, $res); + } + return $tmp; + } + + /** + * Free the internal resources associated with a prepared query. + * + * @param $stmt The interbase_query resource type + * + * @return bool true on success, false if $result is invalid + */ + function freePrepared($stmt) + { + if (!is_resource($stmt)) { + return false; + } + @ibase_free_query($stmt); + unset($this->prepare_tokens[(int)$stmt]); + unset($this->prepare_types[(int)$stmt]); + unset($this->manip_query[(int)$stmt]); + return true; + } + + // }}} + // {{{ autoCommit() + + function autoCommit($onoff = false) + { + $this->autocommit = $onoff ? 1 : 0; + return DB_OK; + } + + // }}} + // {{{ commit() + + function commit() + { + return @ibase_commit($this->connection); + } + + // }}} + // {{{ rollback() + + function rollback() + { + return @ibase_rollback($this->connection); + } + + // }}} + // {{{ transactionInit() + + function transactionInit($trans_args = 0) + { + return $trans_args ? @ibase_trans($trans_args, $this->connection) : @ibase_trans(); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $sqn = strtoupper($this->getSequenceName($seq_name)); + $repeat = 0; + do { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result =& $this->query("SELECT GEN_ID(${sqn}, 1) " + . 'FROM RDB$GENERATORS ' + . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); + $this->popErrorHandling(); + if ($ondemand && DB::isError($result)) { + $repeat = 1; + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $result; + } + } else { + $repeat = 0; + } + } while ($repeat); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); + $result->free(); + return $arr[0]; + } + + // }}} + // {{{ createSequence() + + /** + * Create the sequence + * + * @param string $seq_name the name of the sequence + * @return mixed DB_OK on success or DB error on error + * @access public + */ + function createSequence($seq_name) + { + $sqn = strtoupper($this->getSequenceName($seq_name)); + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("CREATE GENERATOR ${sqn}"); + $this->popErrorHandling(); + + return $result; + } + + // }}} + // {{{ dropSequence() + + /** + * Drop a sequence + * + * @param string $seq_name the name of the sequence + * @return mixed DB_OK on success or DB error on error + * @access public + */ + function dropSequence($seq_name) + { + $sqn = strtoupper($this->getSequenceName($seq_name)); + return $this->query('DELETE FROM RDB$GENERATORS ' + . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); + } + + // }}} + // {{{ _ibaseFieldFlags() + + /** + * get the Flags of a Field + * + * @param string $field_name the name of the field + * @param string $table_name the name of the table + * + * @return string The flags of the field ("primary_key", "unique_key", "not_null" + * "default", "computed" and "blob" are supported) + * @access private + */ + function _ibaseFieldFlags($field_name, $table_name) + { + $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' + .' FROM RDB$INDEX_SEGMENTS I' + .' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' + .' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' + .' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; + + $result = @ibase_query($this->connection, $sql); + if (!$result) { + return $this->ibaseRaiseError(); + } + + $flags = ''; + if ($obj = @ibase_fetch_object($result)) { + @ibase_free_result($result); + if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { + $flags .= 'primary_key '; + } + if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { + $flags .= 'unique_key '; + } + } + + $sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' + .' R.RDB$DEFAULT_SOURCE AS DSOURCE,' + .' F.RDB$FIELD_TYPE AS FTYPE,' + .' F.RDB$COMPUTED_SOURCE AS CSOURCE' + .' FROM RDB$RELATION_FIELDS R ' + .' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' + .' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' + .' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; + + $result = @ibase_query($this->connection, $sql); + if (!$result) { + return $this->ibaseRaiseError(); + } + if ($obj = @ibase_fetch_object($result)) { + @ibase_free_result($result); + if (isset($obj->NFLAG)) { + $flags .= 'not_null '; + } + if (isset($obj->DSOURCE)) { + $flags .= 'default '; + } + if (isset($obj->CSOURCE)) { + $flags .= 'computed '; + } + if (isset($obj->FTYPE) && $obj->FTYPE == 261) { + $flags .= 'blob '; + } + } + + return trim($flags); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @ibase_query($this->connection, + "SELECT * FROM $result WHERE 1=0"); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @ibase_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + for ($i=0; $i<$count; $i++) { + $info = @ibase_field_info($id, $i); + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func($info['name']); + $res[$i]['type'] = $info['type']; + $res[$i]['len'] = $info['length']; + $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; + } + } else { // full + $res['num_fields']= $count; + + for ($i=0; $i<$count; $i++) { + $info = @ibase_field_info($id, $i); + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func($info['name']); + $res[$i]['type'] = $info['type']; + $res[$i]['len'] = $info['length']; + $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @ibase_free_result($id); + } + return $res; + } + + // }}} + // {{{ ibaseRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $db_errno PEAR error number (usually a DB constant) if + * manually raising an error + * @param string $native_errmsg text of error message if known + * @return object DB error object + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function &ibaseRaiseError($db_errno = null, $native_errmsg = null) + { + if ($native_errmsg === null) { + $native_errmsg = @ibase_errmsg(); + } + // memo for the interbase php module hackers: we need something similar + // to mysql_errno() to retrieve error codes instead of this ugly hack + if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $native_errmsg, $m)) { + $native_errno = (int)$m[2]; + } else { + $native_errno = null; + } + // try to map the native error to the DB one + if ($db_errno === null) { + if ($native_errno) { + // try to interpret Interbase error code (that's why we need ibase_errno() + // in the interbase module to return the real error code) + switch ($native_errno) { + case -204: + if (is_int(strpos($m[3], 'Table unknown'))) { + $db_errno = DB_ERROR_NOSUCHTABLE; + } + break; + default: + $db_errno = $this->errorCode($native_errno); + } + } else { + $error_regexps = array( + '/[tT]able not found/' => DB_ERROR_NOSUCHTABLE, + '/[tT]able .* already exists/' => DB_ERROR_ALREADY_EXISTS, + '/validation error for column .* value "\*\*\* null/' => DB_ERROR_CONSTRAINT_NOT_NULL, + '/violation of [\w ]+ constraint/' => DB_ERROR_CONSTRAINT, + '/conversion error from string/' => DB_ERROR_INVALID_NUMBER, + '/no permission for/' => DB_ERROR_ACCESS_VIOLATION, + '/arithmetic exception, numeric overflow, or string truncation/' => DB_ERROR_DIVZERO + ); + foreach ($error_regexps as $regexp => $code) { + if (preg_match($regexp, $native_errmsg)) { + $db_errno = $code; + $native_errno = null; + break; + } + } + } + } + $tmp =& $this->raiseError($db_errno, null, null, null, $native_errmsg); + return $tmp; + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/ifx.php b/gulliver/thirdparty/pear/DB/ifx.php new file mode 100644 index 000000000..89204a633 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/ifx.php @@ -0,0 +1,579 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: ifx.php 3355 2005-06-11 22:14:40Z nbm $ + + +// Legend: +// For more info on Informix errors see: +// http://www.informix.com/answers/english/ierrors.htm +// +// TODO: +// - set needed env Informix vars on connect +// - implement native prepare/execute + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Informix + * extension. + * + * @package DB + * @version $Id: ifx.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Tomas V.V.Cox + */ +class DB_ifx extends DB_common +{ + // {{{ properties + + var $connection; + var $affected = 0; + var $dsn = array(); + var $transaction_opcount = 0; + var $autocommit = true; + var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ + + // }}} + // {{{ constructor + + function DB_ifx() + { + $this->phptype = 'ifx'; + $this->dbsyntax = 'ifx'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'emulate' + ); + $this->errorcode_map = array( + '-201' => DB_ERROR_SYNTAX, + '-206' => DB_ERROR_NOSUCHTABLE, + '-217' => DB_ERROR_NOSUCHFIELD, + '-239' => DB_ERROR_CONSTRAINT, + '-253' => DB_ERROR_SYNTAX, + '-292' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-310' => DB_ERROR_ALREADY_EXISTS, + '-329' => DB_ERROR_NODBSELECTED, + '-346' => DB_ERROR_CONSTRAINT, + '-386' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-391' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-554' => DB_ERROR_SYNTAX, + '-691' => DB_ERROR_CONSTRAINT, + '-703' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-1204' => DB_ERROR_INVALID_DATE, + '-1205' => DB_ERROR_INVALID_DATE, + '-1206' => DB_ERROR_INVALID_DATE, + '-1209' => DB_ERROR_INVALID_DATE, + '-1210' => DB_ERROR_INVALID_DATE, + '-1212' => DB_ERROR_INVALID_DATE, + '-1213' => DB_ERROR_INVALID_NUMBER, + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * + * @return int DB_OK on success, a DB error code on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('informix') && + !DB::assertExtension('Informix')) + { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + $dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : ''; + $dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : ''; + $user = $dsninfo['username'] ? $dsninfo['username'] : ''; + $pw = $dsninfo['password'] ? $dsninfo['password'] : ''; + + $connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect'; + + $this->connection = @$connect_function($dbname, $user, $pw); + if (!is_resource($this->connection)) { + return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED); + } + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @ifx_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to Informix and return the results as a + * Informix resource identifier. + * + * @param $query the SQL query + * + * @return int returns a valid Informix result for successful SELECT + * queries, DB_OK for other successful queries. A DB error code + * is returned on failure. + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $this->affected = null; + if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()? + // the scroll is needed for fetching absolute row numbers + // in a select query result + $result = @ifx_query($query, $this->connection, IFX_SCROLL); + } else { + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @ifx_query('BEGIN WORK', $this->connection); + if (!$result) { + return $this->ifxraiseError(); + } + } + $this->transaction_opcount++; + } + $result = @ifx_query($query, $this->connection); + } + if (!$result) { + return $this->ifxraiseError(); + } + $this->affected = @ifx_affected_rows($result); + // Determine which queries should return data, and which + // should return an error code only. + if (preg_match('/(SELECT)/i', $query)) { + return $result; + } + // XXX Testme: free results inside a transaction + // may cause to stop it and commit the work? + + // Result has to be freed even with a insert or update + @ifx_free_result($result); + + return DB_OK; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal ifx result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the last query. + * if the last query was a select, returns 0. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + return $this->affected; + } else { + return 0; + } + + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if (($rownum !== null) && ($rownum < 0)) { + return null; + } + if ($rownum === null) { + /* + * Even though fetch_row() should return the next row if + * $rownum is null, it doesn't in all cases. Bug 598. + */ + $rownum = 'NEXT'; + } else { + // Index starts at row 1, unlike most DBMS's starting at 0. + $rownum++; + } + if (!$arr = @ifx_fetch_row($result, $rownum)) { + return null; + } + if ($fetchmode !== DB_FETCHMODE_ASSOC) { + $i=0; + $order = array(); + foreach ($arr as $val) { + $order[$i++] = $val; + } + $arr = $order; + } elseif ($fetchmode == DB_FETCHMODE_ASSOC && + $this->options['portability'] & DB_PORTABILITY_LOWERCASE) + { + $arr = array_change_key_case($arr, CASE_LOWER); + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ numRows() + + function numRows($result) + { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result Informix result identifier + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + if (!$cols = @ifx_num_fields($result)) { + return $this->ifxraiseError(); + } + return $cols; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result Informix result identifier + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + return @ifx_free_result($result); + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + */ + function autoCommit($onoff = true) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + $result = @ifx_query('COMMIT WORK', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->ifxRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + $result = @ifx_query('ROLLBACK WORK', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->ifxRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ ifxraiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorNative() + * @see errorCode() + * @see DB_common::raiseError() + */ + function ifxraiseError($errno = null) + { + if ($errno === null) { + $errno = $this->errorCode(ifx_error()); + } + + return $this->raiseError($errno, null, null, null, + $this->errorNative()); + } + + // }}} + // {{{ errorCode() + + /** + * Map native error codes to DB's portable ones. + * + * Requires that the DB implementation's constructor fills + * in the $errorcode_map property. + * + * @param string $nativecode error code returned by the database + * @return int a portable DB error code, or DB_ERROR if this DB + * implementation has no mapping for the given error code. + */ + function errorCode($nativecode) + { + if (ereg('SQLCODE=(.*)]', $nativecode, $match)) { + $code = $match[1]; + if (isset($this->errorcode_map[$code])) { + return $this->errorcode_map[$code]; + } + } + return DB_ERROR; + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error message of the last error (if any) that + * occured on the current connection. + * + * @return int native Informix error code + */ + function errorNative() + { + return @ifx_error() . ' ' . @ifx_errormsg(); + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return 'select tabname from systables where tabid >= 100'; + default: + return null; + } + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' if $result is a table name. + * + * If analyzing a query result and the result has duplicate field names, + * an error will be raised saying + * can't distinguish duplicate field names. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @since 1.6.0 + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @ifx_query("SELECT * FROM $result WHERE 1=0", + $this->connection); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + $flds = @ifx_fieldproperties($id); + $count = @ifx_num_fields($id); + + if (count($flds) != $count) { + return $this->raiseError("can't distinguish duplicate field names"); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $i = 0; + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + foreach ($flds as $key => $value) { + $props = explode(';', $value); + + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func($key); + $res[$i]['type'] = $props[0]; + $res[$i]['len'] = $props[1]; + $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : ''; + $i++; + } + + } else { // full + $res['num_fields'] = $count; + + foreach ($flds as $key => $value) { + $props = explode(';', $value); + + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func($key); + $res[$i]['type'] = $props[0]; + $res[$i]['len'] = $props[1]; + $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + $i++; + } + } + + // free the result only if we were called on a table + if ($got_string) { + @ifx_free_result($id); + } + return $res; + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/msql.php b/gulliver/thirdparty/pear/DB/msql.php new file mode 100644 index 000000000..8f87689ab --- /dev/null +++ b/gulliver/thirdparty/pear/DB/msql.php @@ -0,0 +1,242 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: msql.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Mini-SQL + * extension. + * + * @package DB + * @version $Id: msql.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Sterling Hughes + */ +class DB_msql extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + + // }}} + // {{{ constructor + + function DB_msql() + { + $this->DB_common(); + $this->phptype = 'msql'; + $this->dbsyntax = 'msql'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => false, + 'limit' => 'emulate' + ); + } + + // }}} + // {{{ connect() + + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('msql')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; + + $connect_function = $persistent ? 'msql_pconnect' : 'msql_connect'; + + if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { + $conn = $connect_function($dbhost, $dsninfo['username'], + $dsninfo['password']); + } elseif ($dbhost && $dsninfo['username']) { + $conn = $connect_function($dbhost, $dsninfo['username']); + } else { + $conn = $connect_function($dbhost); + } + if (!$conn) { + $this->raiseError(DB_ERROR_CONNECT_FAILED); + } + if (!@msql_select_db($dsninfo['database'], $conn)){ + return $this->raiseError(DB_ERROR_NODBSELECTED); + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + function disconnect() + { + $ret = @msql_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + function simpleQuery($query) + { + $this->last_query = $query; + $query = $this->modifyQuery($query); + $result = @msql_query($query, $this->connection); + if (!$result) { + return $this->raiseError(); + } + // Determine which queries that should return data, and which + // should return an error code only. + return DB::isManip($query) ? DB_OK : $result; + } + + + // }}} + // {{{ nextResult() + + /** + * Move the internal msql result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@msql_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @msql_fetch_array($result, MSQL_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @msql_fetch_row($result); + } + if (!$arr) { + if ($error = @msql_error()) { + return $this->raiseError($error); + } else { + return null; + } + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + function freeResult($result) + { + return @msql_free_result($result); + } + + // }}} + // {{{ numCols() + + function numCols($result) + { + $cols = @msql_num_fields($result); + if (!$cols) { + return $this->raiseError(); + } + return $cols; + } + + // }}} + // {{{ numRows() + + function numRows($result) + { + $rows = @msql_num_rows($result); + if (!$rows) { + return $this->raiseError(); + } + return $rows; + } + + // }}} + // {{{ affected() + + /** + * Gets the number of rows affected by a query. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + return @msql_affected_rows($this->connection); + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/mssql.php b/gulliver/thirdparty/pear/DB/mssql.php new file mode 100644 index 000000000..57ba03920 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/mssql.php @@ -0,0 +1,738 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: mssql.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Microsoft SQL Server + * extension. + * + * @package DB + * @version $Id: mssql.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Sterling Hughes + */ +class DB_mssql extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $transaction_opcount = 0; + var $autocommit = true; + var $_db = null; + + // }}} + // {{{ constructor + + function DB_mssql() + { + $this->DB_common(); + $this->phptype = 'mssql'; + $this->dbsyntax = 'mssql'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'emulate' + ); + // XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX + $this->errorcode_map = array( + 170 => DB_ERROR_SYNTAX, + 207 => DB_ERROR_NOSUCHFIELD, + 208 => DB_ERROR_NOSUCHTABLE, + 245 => DB_ERROR_INVALID_NUMBER, + 515 => DB_ERROR_CONSTRAINT_NOT_NULL, + 547 => DB_ERROR_CONSTRAINT, + 2627 => DB_ERROR_CONSTRAINT, + 2714 => DB_ERROR_ALREADY_EXISTS, + 3701 => DB_ERROR_NOSUCHTABLE, + 8134 => DB_ERROR_DIVZERO, + ); + } + + // }}} + // {{{ connect() + + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('mssql') && !DB::assertExtension('sybase') + && !DB::assertExtension('sybase_ct')) + { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; + $dbhost .= $dsninfo['port'] ? ',' . $dsninfo['port'] : ''; + + $connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect'; + + if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { + $conn = @$connect_function($dbhost, $dsninfo['username'], + $dsninfo['password']); + } elseif ($dbhost && $dsninfo['username']) { + $conn = @$connect_function($dbhost, $dsninfo['username']); + } else { + $conn = @$connect_function($dbhost); + } + if (!$conn) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, @mssql_get_last_message()); + } + if ($dsninfo['database']) { + if (!@mssql_select_db($dsninfo['database'], $conn)) { + return $this->raiseError(DB_ERROR_NODBSELECTED, null, null, + null, @mssql_get_last_message()); + } + $this->_db = $dsninfo['database']; + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + function disconnect() + { + $ret = @mssql_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + if (!@mssql_select_db($this->_db, $this->connection)) { + return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); + } + $query = $this->modifyQuery($query); + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @mssql_query('BEGIN TRAN', $this->connection); + if (!$result) { + return $this->mssqlRaiseError(); + } + } + $this->transaction_opcount++; + } + $result = @mssql_query($query, $this->connection); + if (!$result) { + return $this->mssqlRaiseError(); + } + // Determine which queries that should return data, and which + // should return an error code only. + return $ismanip ? DB_OK : $result; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal mssql result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return @mssql_next_result($result); + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@mssql_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @mssql_fetch_array($result, MSSQL_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @mssql_fetch_row($result); + } + if (!$arr) { + /* This throws informative error messages, + don't use it for now + if ($msg = @mssql_get_last_message()) { + return $this->raiseError($msg); + } + */ + return null; + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + function freeResult($result) + { + return @mssql_free_result($result); + } + + // }}} + // {{{ numCols() + + function numCols($result) + { + $cols = @mssql_num_fields($result); + if (!$cols) { + return $this->mssqlRaiseError(); + } + return $cols; + } + + // }}} + // {{{ numRows() + + function numRows($result) + { + $rows = @mssql_num_rows($result); + if ($rows === false) { + return $this->mssqlRaiseError(); + } + return $rows; + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + */ + function autoCommit($onoff = false) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + if (!@mssql_select_db($this->_db, $this->connection)) { + return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); + } + $result = @mssql_query('COMMIT TRAN', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mssqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + if (!@mssql_select_db($this->_db, $this->connection)) { + return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); + } + $result = @mssql_query('ROLLBACK TRAN', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mssqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the last query. + * if the last query was a select, returns 0. + * + * @return number of rows affected by the last query or DB_ERROR + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + $res = @mssql_query('select @@rowcount', $this->connection); + if (!$res) { + return $this->mssqlRaiseError(); + } + $ar = @mssql_fetch_row($res); + if (!$ar) { + $result = 0; + } else { + @mssql_free_result($res); + $result = $ar[0]; + } + } else { + $result = 0; + } + return $result; + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + if (!@mssql_select_db($this->_db, $this->connection)) { + return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); + } + $repeat = 0; + do { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); + $this->popErrorHandling(); + if ($ondemand && DB::isError($result) && + ($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) + { + $repeat = 1; + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $this->raiseError($result); + } + } elseif (!DB::isError($result)) { + $result =& $this->query("SELECT @@IDENTITY FROM $seqname"); + $repeat = 0; + } else { + $repeat = false; + } + } while ($repeat); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $result = $result->fetchRow(DB_FETCHMODE_ORDERED); + return $result[0]; + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("CREATE TABLE $seqname ". + '([id] [int] IDENTITY (1, 1) NOT NULL ,' . + '[vapor] [int] NULL)'); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP TABLE $seqname"); + } + + // }}} + // {{{ errorNative() + + /** + * Determine MS SQL Server error code by querying @@ERROR. + * + * @return mixed mssql's native error code or DB_ERROR if unknown. + */ + function errorNative() + { + $res = @mssql_query('select @@ERROR as ErrorCode', $this->connection); + if (!$res) { + return DB_ERROR; + } + $row = @mssql_fetch_row($res); + return $row[0]; + } + + // }}} + // {{{ errorCode() + + /** + * Determine PEAR::DB error code from mssql's native codes. + * + * If $nativecode isn't known yet, it will be looked up. + * + * @param mixed $nativecode mssql error code, if known + * @return integer an error number from a DB error constant + * @see errorNative() + */ + function errorCode($nativecode = null) + { + if (!$nativecode) { + $nativecode = $this->errorNative(); + } + if (isset($this->errorcode_map[$nativecode])) { + return $this->errorcode_map[$nativecode]; + } else { + return DB_ERROR; + } + } + + // }}} + // {{{ mssqlRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $code PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorCode() + * @see errorNative() + * @see DB_common::raiseError() + */ + function mssqlRaiseError($code = null) + { + $message = @mssql_get_last_message(); + if (!$code) { + $code = $this->errorNative(); + } + return $this->raiseError($this->errorCode($code), null, null, null, + "$code - $message"); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + if (!@mssql_select_db($this->_db, $this->connection)) { + return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); + } + $id = @mssql_query("SELECT * FROM $result WHERE 1=0", + $this->connection); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @mssql_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func(@mssql_field_name($id, $i)); + $res[$i]['type'] = @mssql_field_type($id, $i); + $res[$i]['len'] = @mssql_field_length($id, $i); + // We only support flags for tables + $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : ''; + } + + } else { // full + $res['num_fields']= $count; + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func(@mssql_field_name($id, $i)); + $res[$i]['type'] = @mssql_field_type($id, $i); + $res[$i]['len'] = @mssql_field_length($id, $i); + // We only support flags for tables + $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @mssql_free_result($id); + } + return $res; + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return "select name from sysobjects where type = 'U' order by name"; + case 'views': + return "select name from sysobjects where type = 'V'"; + default: + return null; + } + } + + // }}} + // {{{ _mssql_field_flags() + + /** + * Get the flags for a field, currently supports "not_null", "primary_key", + * "auto_increment" (mssql identity), "timestamp" (mssql timestamp), + * "unique_key" (mssql unique index, unique check or primary_key) and + * "multiple_key" (multikey index) + * + * mssql timestamp is NOT similar to the mysql timestamp so this is maybe + * not useful at all - is the behaviour of mysql_field_flags that primary + * keys are alway unique? is the interpretation of multiple_key correct? + * + * @param string The table name + * @param string The field + * @author Joern Barthel + * @access private + */ + function _mssql_field_flags($table, $column) + { + static $tableName = null; + static $flags = array(); + + if ($table != $tableName) { + + $flags = array(); + $tableName = $table; + + // get unique and primary keys + $res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC); + + foreach ($res as $val) { + $keys = explode(', ', $val['index_keys']); + + if (sizeof($keys) > 1) { + foreach ($keys as $key) { + $this->_add_flag($flags[$key], 'multiple_key'); + } + } + + if (strpos($val['index_description'], 'primary key')) { + foreach ($keys as $key) { + $this->_add_flag($flags[$key], 'primary_key'); + } + } elseif (strpos($val['index_description'], 'unique')) { + foreach ($keys as $key) { + $this->_add_flag($flags[$key], 'unique_key'); + } + } + } + + // get auto_increment, not_null and timestamp + $res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC); + + foreach ($res as $val) { + $val = array_change_key_case($val, CASE_LOWER); + if ($val['nullable'] == '0') { + $this->_add_flag($flags[$val['column_name']], 'not_null'); + } + if (strpos($val['type_name'], 'identity')) { + $this->_add_flag($flags[$val['column_name']], 'auto_increment'); + } + if (strpos($val['type_name'], 'timestamp')) { + $this->_add_flag($flags[$val['column_name']], 'timestamp'); + } + } + } + + if (array_key_exists($column, $flags)) { + return(implode(' ', $flags[$column])); + } + return ''; + } + + // }}} + // {{{ _add_flag() + + /** + * Adds a string to the flags array if the flag is not yet in there + * - if there is no flag present the array is created. + * + * @param reference Reference to the flag-array + * @param value The flag value + * @access private + * @author Joern Barthel + */ + function _add_flag(&$array, $value) + { + if (!is_array($array)) { + $array = array($value); + } elseif (!in_array($value, $array)) { + array_push($array, $value); + } + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table / column name + * + * Quoting style depends on which database driver is being used. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + */ + function quoteIdentifier($str) + { + return '[' . str_replace(']', ']]', $str) . ']'; + } + + // }}} +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/mysql.php b/gulliver/thirdparty/pear/DB/mysql.php new file mode 100644 index 000000000..f7f032c17 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/mysql.php @@ -0,0 +1,916 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: mysql.php 3355 2005-06-11 22:14:40Z nbm $ + + +// XXX legend: +// +// XXX ERRORMSG: The error message from the mysql function should +// be registered here. +// +// TODO/wishlist: +// longReadlen +// binmode + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's MySQL + * extension. + * + * This is for MySQL versions 4.0 and below. + * + * @package DB + * @version $Id: mysql.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Stig Bakken + */ +class DB_mysql extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $num_rows = array(); + var $transaction_opcount = 0; + var $autocommit = true; + var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ + var $_db = false; + + // }}} + // {{{ constructor + + /** + * DB_mysql constructor. + * + * @access public + */ + function DB_mysql() + { + $this->DB_common(); + $this->phptype = 'mysql'; + $this->dbsyntax = 'mysql'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'alter' + ); + $this->errorcode_map = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1022 => DB_ERROR_ALREADY_EXISTS, + 1046 => DB_ERROR_NODBSELECTED, + 1048 => DB_ERROR_CONSTRAINT, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + 1216 => DB_ERROR_CONSTRAINT, + 1217 => DB_ERROR_CONSTRAINT, + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * @access public + * @return int DB_OK on success, a DB error on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('mysql')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + if ($dsninfo['protocol'] && $dsninfo['protocol'] == 'unix') { + $dbhost = ':' . $dsninfo['socket']; + } else { + $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; + if ($dsninfo['port']) { + $dbhost .= ':' . $dsninfo['port']; + } + } + + $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect'; + + if ($dbhost && $dsninfo['username'] && isset($dsninfo['password'])) { + $conn = @$connect_function($dbhost, $dsninfo['username'], + $dsninfo['password']); + } elseif ($dbhost && $dsninfo['username']) { + $conn = @$connect_function($dbhost, $dsninfo['username']); + } elseif ($dbhost) { + $conn = @$connect_function($dbhost); + } else { + $conn = false; + } + if (!$conn) { + if (($err = @mysql_error()) != '') { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $err); + } elseif (empty($php_errormsg)) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED); + } else { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $php_errormsg); + } + } + + if ($dsninfo['database']) { + if (!@mysql_select_db($dsninfo['database'], $conn)) { + switch(mysql_errno($conn)) { + case 1049: + return $this->raiseError(DB_ERROR_NOSUCHDB, null, null, + null, @mysql_error($conn)); + case 1044: + return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null, + null, @mysql_error($conn)); + default: + return $this->raiseError(DB_ERROR, null, null, + null, @mysql_error($conn)); + } + } + // fix to allow calls to different databases in the same script + $this->_db = $dsninfo['database']; + } + + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @access public + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @mysql_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to MySQL and return the results as a MySQL resource + * identifier. + * + * @param the SQL query + * + * @access public + * + * @return mixed returns a valid MySQL result for successful SELECT + * queries, DB_OK for other successful queries. A DB error is + * returned on failure. + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $query = $this->modifyQuery($query); + if ($this->_db) { + if (!@mysql_select_db($this->_db, $this->connection)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); + $result = @mysql_query('BEGIN', $this->connection); + if (!$result) { + return $this->mysqlRaiseError(); + } + } + $this->transaction_opcount++; + } + $result = @mysql_query($query, $this->connection); + if (!$result) { + return $this->mysqlRaiseError(); + } + if (is_resource($result)) { + $numrows = $this->numrows($result); + if (is_object($numrows)) { + return $numrows; + } + $this->num_rows[(int)$result] = $numrows; + return $result; + } + return DB_OK; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal mysql result pointer to the next available result + * + * This method has not been implemented yet. + * + * @param a valid sql result resource + * + * @access public + * + * @return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@mysql_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @mysql_fetch_array($result, MYSQL_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @mysql_fetch_row($result); + } + if (!$arr) { + // See: http://bugs.php.net/bug.php?id=22328 + // for why we can't check errors on fetching + return null; + /* + $errno = @mysql_errno($this->connection); + if (!$errno) { + return null; + } + return $this->mysqlRaiseError($errno); + */ + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + /* + * Even though this DBMS already trims output, we do this because + * a field might have intentional whitespace at the end that + * gets removed by DB_PORTABILITY_RTRIM under another driver. + */ + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result MySQL result identifier + * + * @access public + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + unset($this->num_rows[(int)$result]); + return @mysql_free_result($result); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result MySQL result identifier + * + * @access public + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @mysql_num_fields($result); + + if (!$cols) { + return $this->mysqlRaiseError(); + } + + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @param $result MySQL result identifier + * + * @access public + * + * @return int the number of rows in $result + */ + function numRows($result) + { + $rows = @mysql_num_rows($result); + if ($rows === null) { + return $this->mysqlRaiseError(); + } + return $rows; + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + */ + function autoCommit($onoff = false) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + if ($this->_db) { + if (!@mysql_select_db($this->_db, $this->connection)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + $result = @mysql_query('COMMIT', $this->connection); + $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mysqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + if ($this->_db) { + if (!@mysql_select_db($this->_db, $this->connection)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + $result = @mysql_query('ROLLBACK', $this->connection); + $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mysqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the data manipulation + * query. For other queries, this function returns 0. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + return @mysql_affected_rows($this->connection); + } else { + return 0; + } + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that + * occured on the current connection. + * + * @access public + * + * @return int native MySQL error code + */ + function errorNative() + { + return @mysql_errno($this->connection); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + do { + $repeat = 0; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("UPDATE ${seqname} ". + 'SET id=LAST_INSERT_ID(id+1)'); + $this->popErrorHandling(); + if ($result === DB_OK) { + /** COMMON CASE **/ + $id = @mysql_insert_id($this->connection); + if ($id != 0) { + return $id; + } + /** EMPTY SEQ TABLE **/ + // Sequence table must be empty for some reason, so fill it and return 1 + // Obtain a user-level lock + $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + if ($result == 0) { + // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error + return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); + } + + // add the default value + $result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + + // Release the lock + $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + // We know what the result will be, so no need to try again + return 1; + + /** ONDEMAND TABLE CREATION **/ + } elseif ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) + { + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $this->raiseError($result); + } else { + $repeat = 1; + } + + /** BACKWARDS COMPAT **/ + } elseif (DB::isError($result) && + $result->getCode() == DB_ERROR_ALREADY_EXISTS) + { + // see _BCsequence() comment + $result = $this->_BCsequence($seqname); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $repeat = 1; + } + } while ($repeat); + + return $this->raiseError($result); + } + + // }}} + // {{{ createSequence() + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + $res = $this->query("CREATE TABLE ${seqname} ". + '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. + ' PRIMARY KEY(id))'); + if (DB::isError($res)) { + return $res; + } + // insert yields value 1, nextId call will generate ID 2 + $res = $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); + if (DB::isError($res)) { + return $res; + } + // so reset to zero + return $this->query("UPDATE ${seqname} SET id = 0;"); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); + } + + // }}} + // {{{ _BCsequence() + + /** + * Backwards compatibility with old sequence emulation implementation + * (clean up the dupes) + * + * @param string $seqname The sequence name to clean up + * @return mixed DB_Error or true + */ + function _BCsequence($seqname) + { + // Obtain a user-level lock... this will release any previous + // application locks, but unlike LOCK TABLES, it does not abort + // the current transaction and is much less frequently used. + $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); + if (DB::isError($result)) { + return $result; + } + if ($result == 0) { + // Failed to get the lock, can't do the conversion, bail + // with a DB_ERROR_NOT_LOCKED error + return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); + } + + $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); + if (DB::isError($highest_id)) { + return $highest_id; + } + // This should kill all rows except the highest + // We should probably do something if $highest_id isn't + // numeric, but I'm at a loss as how to handle that... + $result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id"); + if (DB::isError($result)) { + return $result; + } + + // If another thread has been waiting for this lock, + // it will go thru the above procedure, but will have no + // real effect + $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); + if (DB::isError($result)) { + return $result; + } + return true; + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table or column name + * + * Quoting style depends on which database driver is being used. + * + * MySQL can't handle the backtick character (`) in + * table or column names. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + * @internal + */ + function quoteIdentifier($str) + { + return '`' . $str . '`'; + } + + // }}} + // {{{ quote() + + /** + * @deprecated Deprecated in release 1.6.0 + * @internal + */ + function quote($str) { + return $this->quoteSmart($str); + } + + // }}} + // {{{ escapeSimple() + + /** + * Escape a string according to the current DBMS's standards + * + * @param string $str the string to be escaped + * + * @return string the escaped string + * + * @internal + */ + function escapeSimple($str) { + if (function_exists('mysql_real_escape_string')) { + return @mysql_real_escape_string($str, $this->connection); + } else { + return @mysql_escape_string($str); + } + } + + // }}} + // {{{ modifyQuery() + + function modifyQuery($query) + { + if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { + // "DELETE FROM table" gives 0 affected rows in MySQL. + // This little hack lets you know how many rows were deleted. + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { + $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', + 'DELETE FROM \1 WHERE 1=1', $query); + } + } + return $query; + } + + // }}} + // {{{ modifyLimitQuery() + + function modifyLimitQuery($query, $from, $count, $params = array()) + { + if (DB::isManip($query)) { + return $query . " LIMIT $count"; + } else { + return $query . " LIMIT $from, $count"; + } + } + + // }}} + // {{{ mysqlRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function mysqlRaiseError($errno = null) + { + if ($errno === null) { + if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { + $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; + $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; + $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; + } else { + // Doing this in case mode changes during runtime. + $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; + $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; + $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; + } + $errno = $this->errorCode(mysql_errno($this->connection)); + } + return $this->raiseError($errno, null, null, null, + @mysql_errno($this->connection) . ' ** ' . + @mysql_error($this->connection)); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @mysql_list_fields($this->dsn['database'], + $result, $this->connection); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @mysql_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); + $res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); + $res[$i]['type'] = @mysql_field_type($id, $i); + $res[$i]['len'] = @mysql_field_len($id, $i); + $res[$i]['flags'] = @mysql_field_flags($id, $i); + } + } else { // full + $res['num_fields']= $count; + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); + $res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); + $res[$i]['type'] = @mysql_field_type($id, $i); + $res[$i]['len'] = @mysql_field_len($id, $i); + $res[$i]['flags'] = @mysql_field_flags($id, $i); + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @mysql_free_result($id); + } + return $res; + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return 'SHOW TABLES'; + case 'views': + return DB_ERROR_NOT_CAPABLE; + case 'users': + $sql = 'select distinct User from user'; + if ($this->dsn['database'] != 'mysql') { + $dsn = $this->dsn; + $dsn['database'] = 'mysql'; + if (DB::isError($db = DB::connect($dsn))) { + return $db; + } + $sql = $db->getCol($sql); + $db->disconnect(); + // XXX Fixme the mysql driver should take care of this + if (!@mysql_select_db($this->dsn['database'], $this->connection)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + return $sql; + case 'databases': + return 'SHOW DATABASES'; + default: + return null; + } + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/mysqli.php b/gulliver/thirdparty/pear/DB/mysqli.php new file mode 100644 index 000000000..3c0fd1db4 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/mysqli.php @@ -0,0 +1,960 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: mysqli.php 3355 2005-06-11 22:14:40Z nbm $ + + +// EXPERIMENTAL + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's mysqli + * extension. + * + * This is for MySQL versions 4.1 and above. Requires PHP 5. + * + * Note that persistent connections no longer exist. + * + * @package DB + * @version $Id: mysqli.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Daniel Convissor + * @since Class functional since Release 1.6.3 + */ +class DB_mysqli extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $num_rows = array(); + var $transaction_opcount = 0; + var $autocommit = true; + var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ + var $_db = false; + + /** + * Array for converting MYSQLI_*_FLAG constants to text values + * @var array + * @access public + * @since Property available since Release 1.6.5 + */ + var $mysqli_flags = array( + MYSQLI_NOT_NULL_FLAG => 'not_null', + MYSQLI_PRI_KEY_FLAG => 'primary_key', + MYSQLI_UNIQUE_KEY_FLAG => 'unique_key', + MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key', + MYSQLI_BLOB_FLAG => 'blob', + MYSQLI_UNSIGNED_FLAG => 'unsigned', + MYSQLI_ZEROFILL_FLAG => 'zerofill', + MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment', + MYSQLI_TIMESTAMP_FLAG => 'timestamp', + MYSQLI_SET_FLAG => 'set', + // MYSQLI_NUM_FLAG => 'numeric', // unnecessary + // MYSQLI_PART_KEY_FLAG => 'multiple_key', // duplicatvie + MYSQLI_GROUP_FLAG => 'group_by' + ); + + /** + * Array for converting MYSQLI_TYPE_* constants to text values + * @var array + * @access public + * @since Property available since Release 1.6.5 + */ + var $mysqli_types = array( + MYSQLI_TYPE_DECIMAL => 'decimal', + MYSQLI_TYPE_TINY => 'tinyint', + MYSQLI_TYPE_SHORT => 'int', + MYSQLI_TYPE_LONG => 'int', + MYSQLI_TYPE_FLOAT => 'float', + MYSQLI_TYPE_DOUBLE => 'double', + // MYSQLI_TYPE_NULL => 'DEFAULT NULL', // let flags handle it + MYSQLI_TYPE_TIMESTAMP => 'timestamp', + MYSQLI_TYPE_LONGLONG => 'bigint', + MYSQLI_TYPE_INT24 => 'mediumint', + MYSQLI_TYPE_DATE => 'date', + MYSQLI_TYPE_TIME => 'time', + MYSQLI_TYPE_DATETIME => 'datetime', + MYSQLI_TYPE_YEAR => 'year', + MYSQLI_TYPE_NEWDATE => 'date', + MYSQLI_TYPE_ENUM => 'enum', + MYSQLI_TYPE_SET => 'set', + MYSQLI_TYPE_TINY_BLOB => 'tinyblob', + MYSQLI_TYPE_MEDIUM_BLOB => 'mediumblob', + MYSQLI_TYPE_LONG_BLOB => 'longblob', + MYSQLI_TYPE_BLOB => 'blob', + MYSQLI_TYPE_VAR_STRING => 'varchar', + MYSQLI_TYPE_STRING => 'char', + MYSQLI_TYPE_GEOMETRY => 'geometry', + ); + + // }}} + // {{{ constructor + + /** + * DB_mysql constructor. + * + * @access public + */ + function DB_mysqli() + { + $this->DB_common(); + $this->phptype = 'mysqli'; + $this->dbsyntax = 'mysqli'; + $this->features = array( + 'prepare' => false, + 'ssl' => true, + 'transactions' => true, + 'limit' => 'alter' + ); + $this->errorcode_map = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1022 => DB_ERROR_ALREADY_EXISTS, + 1046 => DB_ERROR_NODBSELECTED, + 1048 => DB_ERROR_CONSTRAINT, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + 1216 => DB_ERROR_CONSTRAINT, + 1217 => DB_ERROR_CONSTRAINT, + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param string $dsn the data source name (see DB::parseDSN for syntax) + * @param boolean $persistent (optional) whether the connection should + * be persistent + * @return mixed DB_OK on success, a DB error on failure + * @access public + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('mysqli')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + $conn = false; + @ini_set('track_errors', true); + + if ($this->getOption('ssl') === true) { + $init = mysqli_init(); + mysqli_ssl_set( + $init, + empty($dsninfo['key']) ? null : $dsninfo['key'], + empty($dsninfo['cert']) ? null : $dsninfo['cert'], + empty($dsninfo['ca']) ? null : $dsninfo['ca'], + empty($dsninfo['capath']) ? null : $dsninfo['capath'], + empty($dsninfo['cipher']) ? null : $dsninfo['cipher'] + ); + if ($conn = @mysqli_real_connect($init, + $dsninfo['hostspec'], + $dsninfo['username'], + $dsninfo['password'], + $dsninfo['database'], + $dsninfo['port'], + $dsninfo['socket'])) + { + $conn = $init; + } + } else { + $conn = @mysqli_connect( + $dsninfo['hostspec'], + $dsninfo['username'], + $dsninfo['password'], + $dsninfo['database'], + $dsninfo['port'], + $dsninfo['socket'] + ); + } + + @ini_restore('track_errors'); + + if (!$conn) { + if (($err = @mysqli_connect_error()) != '') { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $err); + } elseif (empty($php_errormsg)) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED); + } else { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $php_errormsg); + } + } + + if ($dsninfo['database']) { + $this->_db = $dsninfo['database']; + } + + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @return boolean true on success, false if not connected + * @access public + */ + function disconnect() + { + $ret = @mysqli_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to MySQL and return the results as a MySQL resource + * identifier. + * + * @param string $query the SQL query + * @return mixed a valid MySQL result for successful SELECT + * queries, DB_OK for other successful queries. + * A DB error is returned on failure. + * @access public + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $query = $this->modifyQuery($query); + if ($this->_db) { + if (!@mysqli_select_db($this->connection, $this->_db)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0'); + $result = @mysqli_query($this->connection, 'BEGIN'); + if (!$result) { + return $this->mysqlRaiseError(); + } + } + $this->transaction_opcount++; + } + $result = @mysqli_query($this->connection, $query); + if (!$result) { + return $this->mysqlRaiseError(); + } +# this next block is still sketchy.. + if (is_object($result)) { + $numrows = $this->numrows($result); + if (is_object($numrows)) { + return $numrows; + } +# need to come up with different means for next line +# since $result is object (int)$result won't fly... +// $this->num_rows[(int)$result] = $numrows; + return $result; + } + return DB_OK; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal mysql result pointer to the next available result. + * + * This method has not been implemented yet. + * + * @param resource $result a valid sql result resource + * @return false + * @access public + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@mysqli_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @mysqli_fetch_array($result, MYSQLI_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @mysqli_fetch_row($result); + } + if (!$arr) { + $errno = @mysqli_errno($this->connection); + if (!$errno) { + return null; + } + return $this->mysqlRaiseError($errno); + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + /* + * Even though this DBMS already trims output, we do this because + * a field might have intentional whitespace at the end that + * gets removed by DB_PORTABILITY_RTRIM under another driver. + */ + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param resource $result MySQL result identifier + * @return bool true on success, false if $result is invalid + * @access public + */ + function freeResult($result) + { +# need to come up with different means for next line +# since $result is object (int)$result won't fly... +// unset($this->num_rows[(int)$result]); + return @mysqli_free_result($result); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result MySQL result identifier + * + * @access public + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @mysqli_num_fields($result); + + if (!$cols) { + return $this->mysqlRaiseError(); + } + + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @param resource $result MySQL result identifier + * @return int the number of rows in $result + * @access public + */ + function numRows($result) + { + $rows = @mysqli_num_rows($result); + if ($rows === null) { + return $this->mysqlRaiseError(); + } + return $rows; + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits. + */ + function autoCommit($onoff = false) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + if ($this->_db) { + if (!@mysqli_select_db($this->connection, $this->_db)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + $result = @mysqli_query($this->connection, 'COMMIT'); + $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mysqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + if ($this->_db) { + if (!@mysqli_select_db($this->connection, $this->_db)) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + $result = @mysqli_query($this->connection, 'ROLLBACK'); + $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=1'); + $this->transaction_opcount = 0; + if (!$result) { + return $this->mysqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the data manipulation + * query. For other queries, this function returns 0. + * + * @return integer number of rows affected by the last query + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + return @mysqli_affected_rows($this->connection); + } else { + return 0; + } + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that + * occured on the current connection. + * + * @return int native MySQL error code + * @access public + */ + function errorNative() + { + return @mysqli_errno($this->connection); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + do { + $repeat = 0; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("UPDATE ${seqname} ". + 'SET id=LAST_INSERT_ID(id+1)'); + $this->popErrorHandling(); + if ($result === DB_OK) { + /** COMMON CASE **/ + $id = @mysqli_insert_id($this->connection); + if ($id != 0) { + return $id; + } + /** EMPTY SEQ TABLE **/ + // Sequence table must be empty for some reason, so fill it and return 1 + // Obtain a user-level lock + $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + if ($result == 0) { + // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error + return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); + } + + // add the default value + $result = $this->query("REPLACE INTO ${seqname} (id) VALUES (0)"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + + // Release the lock + $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); + if (DB::isError($result)) { + return $this->raiseError($result); + } + // We know what the result will be, so no need to try again + return 1; + + /** ONDEMAND TABLE CREATION **/ + } elseif ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) + { + $result = $this->createSequence($seq_name); + // Since createSequence initializes the ID to be 1, + // we do not need to retrieve the ID again (or we will get 2) + if (DB::isError($result)) { + return $this->raiseError($result); + } else { + // First ID of a newly created sequence is 1 + return 1; + } + + /** BACKWARDS COMPAT **/ + } elseif (DB::isError($result) && + $result->getCode() == DB_ERROR_ALREADY_EXISTS) + { + // see _BCsequence() comment + $result = $this->_BCsequence($seqname); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $repeat = 1; + } + } while ($repeat); + + return $this->raiseError($result); + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + $res = $this->query("CREATE TABLE ${seqname} ". + '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. + ' PRIMARY KEY(id))'); + if (DB::isError($res)) { + return $res; + } + // insert yields value 1, nextId call will generate ID 2 + return $this->query("INSERT INTO ${seqname} (id) VALUES (0)"); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); + } + + // }}} + // {{{ _BCsequence() + + /** + * Backwards compatibility with old sequence emulation implementation + * (clean up the dupes). + * + * @param string $seqname The sequence name to clean up + * @return mixed DB_Error or true + */ + function _BCsequence($seqname) + { + // Obtain a user-level lock... this will release any previous + // application locks, but unlike LOCK TABLES, it does not abort + // the current transaction and is much less frequently used. + $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); + if (DB::isError($result)) { + return $result; + } + if ($result == 0) { + // Failed to get the lock, can't do the conversion, bail + // with a DB_ERROR_NOT_LOCKED error + return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); + } + + $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); + if (DB::isError($highest_id)) { + return $highest_id; + } + // This should kill all rows except the highest + // We should probably do something if $highest_id isn't + // numeric, but I'm at a loss as how to handle that... + $result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id"); + if (DB::isError($result)) { + return $result; + } + + // If another thread has been waiting for this lock, + // it will go thru the above procedure, but will have no + // real effect + $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); + if (DB::isError($result)) { + return $result; + } + return true; + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table or column name + * + * Quoting style depends on which database driver is being used. + * + * MySQL can't handle the backtick character (`) in + * table or column names. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + * @internal + */ + function quoteIdentifier($str) + { + return '`' . $str . '`'; + } + + // }}} + // {{{ escapeSimple() + + /** + * Escape a string according to the current DBMS's standards + * + * @param string $str the string to be escaped + * + * @return string the escaped string + * + * @internal + */ + function escapeSimple($str) { + return @mysqli_real_escape_string($this->connection, $str); + } + + // }}} + // {{{ modifyQuery() + + function modifyQuery($query) + { + return $query; + } + + // }}} + // {{{ modifyLimitQuery() + + function modifyLimitQuery($query, $from, $count, $params = array()) + { + if (DB::isManip($query)) { + return $query . " LIMIT $count"; + } else { + return $query . " LIMIT $from, $count"; + } + } + + // }}} + // {{{ mysqlRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function mysqlRaiseError($errno = null) + { + if ($errno === null) { + if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { + $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; + $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; + $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; + } else { + // Doing this in case mode changes during runtime. + $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; + $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; + $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; + } + $errno = $this->errorCode(mysqli_errno($this->connection)); + } + return $this->raiseError($errno, null, null, null, + @mysqli_errno($this->connection) . ' ** ' . + @mysqli_error($this->connection)); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * WARNING: this method will probably not work because the mysqli_*() + * functions it relies upon may not exist. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @mysqli_query($this->connection, + "SELECT * FROM $result LIMIT 0"); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_a($id, 'mysqli_result')) { + return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @mysqli_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + for ($i=0; $i<$count; $i++) { + $tmp = @mysqli_fetch_field($id); + $res[$i]['table'] = $case_func($tmp->table); + $res[$i]['name'] = $case_func($tmp->name); + $res[$i]['type'] = isset($this->mysqli_types[$tmp->type]) ? + $this->mysqli_types[$tmp->type] : + 'unknown'; + $res[$i]['len'] = $tmp->max_length; + + $res[$i]['flags'] = ''; + foreach ($this->mysqli_flags as $const => $means) { + if ($tmp->flags & $const) { + $res[$i]['flags'] .= $means . ' '; + } + } + if ($tmp->def) { + $res[$i]['flags'] .= 'default_' . rawurlencode($tmp->def); + } + $res[$i]['flags'] = trim($res[$i]['flags']); + } + } else { // full + $res['num_fields']= $count; + + for ($i=0; $i<$count; $i++) { + $tmp = @mysqli_fetch_field($id); + $res[$i]['table'] = $case_func($tmp->table); + $res[$i]['name'] = $case_func($tmp->name); + $res[$i]['type'] = isset($this->mysqli_types[$tmp->type]) ? + $this->mysqli_types[$tmp->type] : + 'unknown'; + $res[$i]['len'] = $tmp->max_length; + + $res[$i]['flags'] = ''; + foreach ($this->mysqli_flags as $const => $means) { + if ($tmp->flags & $const) { + $res[$i]['flags'] .= $means . ' '; + } + } + if ($tmp->def) { + $res[$i]['flags'] .= 'default_' . rawurlencode($tmp->def); + } + $res[$i]['flags'] = trim($res[$i]['flags']); + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @mysqli_free_result($id); + } + return $res; + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info. + * + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return 'SHOW TABLES'; + case 'views': + return DB_ERROR_NOT_CAPABLE; + case 'users': + $sql = 'select distinct User from user'; + if ($this->dsn['database'] != 'mysql') { + $dsn = $this->dsn; + $dsn['database'] = 'mysql'; + if (DB::isError($db = DB::connect($dsn))) { + return $db; + } + $sql = $db->getCol($sql); + $db->disconnect(); + // XXX Fixme the mysql driver should take care of this + if (!@mysqli_select_db($this->connection, $this->dsn['database'])) { + return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); + } + } + return $sql; + case 'databases': + return 'SHOW DATABASES'; + default: + return null; + } + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/oci8.php b/gulliver/thirdparty/pear/DB/oci8.php new file mode 100644 index 000000000..ad3fb69ae --- /dev/null +++ b/gulliver/thirdparty/pear/DB/oci8.php @@ -0,0 +1,899 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: oci8.php 3355 2005-06-11 22:14:40Z nbm $ + + +// be aware... OCIError() only appears to return anything when given a +// statement, so functions return the generic DB_ERROR instead of more +// useful errors that have to do with feedback from the database. + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Oracle 8 + * call-interface extension. + * + * Definitely works with versions 8 and 9 of Oracle. + * + * @package DB + * @version $Id: oci8.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author James L. Pine + */ +class DB_oci8 extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $manip_query = array(); + var $prepare_types = array(); + var $autoCommit = 1; + var $last_stmt = false; + + /** + * stores the $data passed to execute() in the oci8 driver + * + * Gets reset to array() when simpleQuery() is run. + * + * Needed in case user wants to call numRows() after prepare/execute + * was used. + * + * @var array + * @access private + */ + var $_data = array(); + + // }}} + // {{{ constructor + + function DB_oci8() + { + $this->DB_common(); + $this->phptype = 'oci8'; + $this->dbsyntax = 'oci8'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'alter' + ); + $this->errorcode_map = array( + 1 => DB_ERROR_CONSTRAINT, + 900 => DB_ERROR_SYNTAX, + 904 => DB_ERROR_NOSUCHFIELD, + 921 => DB_ERROR_SYNTAX, + 923 => DB_ERROR_SYNTAX, + 942 => DB_ERROR_NOSUCHTABLE, + 955 => DB_ERROR_ALREADY_EXISTS, + 1400 => DB_ERROR_CONSTRAINT_NOT_NULL, + 1407 => DB_ERROR_CONSTRAINT_NOT_NULL, + 1476 => DB_ERROR_DIVZERO, + 1722 => DB_ERROR_INVALID_NUMBER, + 2289 => DB_ERROR_NOSUCHTABLE, + 2291 => DB_ERROR_CONSTRAINT, + 2292 => DB_ERROR_CONSTRAINT, + 2449 => DB_ERROR_CONSTRAINT, + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * + * @return int DB_OK on success, a DB error code on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('oci8')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + $this->dsn = $dsninfo; + + $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; + + if ($dsninfo['hostspec']) { + $conn = @$connect_function($dsninfo['username'], + $dsninfo['password'], + $dsninfo['hostspec']); + } elseif ($dsninfo['username'] || $dsninfo['password']) { + $conn = @$connect_function($dsninfo['username'], + $dsninfo['password']); + } else { + $conn = false; + } + if ($conn == false) { + $error = OCIError(); + $error = (is_array($error)) ? $error['message'] : null; + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $error); + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @OCILogOff($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to oracle and return the results as an oci8 resource + * identifier. + * + * @param $query the SQL query + * + * @return int returns a valid oci8 result for successful SELECT + * queries, DB_OK for other successful queries. A DB error code + * is returned on failure. + */ + function simpleQuery($query) + { + $this->_data = array(); + $this->last_query = $query; + $query = $this->modifyQuery($query); + $result = @OCIParse($this->connection, $query); + if (!$result) { + return $this->oci8RaiseError(); + } + if ($this->autoCommit) { + $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); + } else { + $success = @OCIExecute($result,OCI_DEFAULT); + } + if (!$success) { + return $this->oci8RaiseError($result); + } + $this->last_stmt=$result; + // Determine which queries that should return data, and which + // should return an error code only. + return DB::isManip($query) ? DB_OK : $result; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal oracle result pointer to the next available result + * + * @param a valid oci8 result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && + $moredata) + { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); + } + if (!$moredata) { + return null; + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result oci8 result identifier + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + return @OCIFreeStatement($result); + } + + /** + * Free the internal resources associated with a prepared query. + * + * @param $stmt oci8 statement identifier + * + * @return bool true on success, false if $result is invalid + */ + function freePrepared($stmt) + { + if (isset($this->prepare_types[(int)$stmt])) { + unset($this->prepare_types[(int)$stmt]); + unset($this->manip_query[(int)$stmt]); + } else { + return false; + } + return true; + } + + // }}} + // {{{ numRows() + + function numRows($result) + { + // emulate numRows for Oracle. yuck. + if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && + $result === $this->last_stmt) + { + $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; + $save_query = $this->last_query; + $save_stmt = $this->last_stmt; + + if (count($this->_data)) { + $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')'); + $count = $this->execute($smt, $this->_data); + } else { + $count =& $this->query($countquery); + } + + if (DB::isError($count) || + DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) + { + $this->last_query = $save_query; + $this->last_stmt = $save_stmt; + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + return $row[0]; + } + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result oci8 result identifier + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @OCINumCols($result); + if (!$cols) { + return $this->oci8RaiseError($result); + } + return $cols; + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that occured + * on the current connection. This does not work, as OCIError does + * not work unless given a statement. If OCIError does return + * something, so will this. + * + * @return int native oci8 error code + */ + function errorNative() + { + if (is_resource($this->last_stmt)) { + $error = @OCIError($this->last_stmt); + } else { + $error = @OCIError($this->connection); + } + if (is_array($error)) { + return $error['code']; + } + return false; + } + + // }}} + // {{{ prepare() + + /** + * Prepares a query for multiple execution with execute(). + * + * With oci8, this is emulated. + * + * prepare() requires a generic query as string like + * INSERT INTO numbers VALUES (?, ?, ?) + * . The ? characters are placeholders. + * + * Three types of placeholders can be used: + * + ? a quoted scalar value, i.e. strings, integers + * + ! value is inserted 'as is' + * + & requires a file name. The file's contents get + * inserted into the query (i.e. saving binary + * data in a db) + * + * Use backslashes to escape placeholder characters if you don't want + * them to be interpreted as placeholders. Example: + * "UPDATE foo SET col=? WHERE col='over \& under'" + * + * + * @param string $query query to be prepared + * @return mixed DB statement resource on success. DB_Error on failure. + */ + function prepare($query) + { + $tokens = preg_split('/((? $val) { + switch ($val) { + case '?': + $types[$token++] = DB_PARAM_SCALAR; + unset($tokens[$key]); + break; + case '&': + $types[$token++] = DB_PARAM_OPAQUE; + unset($tokens[$key]); + break; + case '!': + $types[$token++] = DB_PARAM_MISC; + unset($tokens[$key]); + break; + default: + $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); + if ($key != $binds) { + $newquery .= $tokens[$key] . ':bind' . $token; + } else { + $newquery .= $tokens[$key]; + } + } + } + + $this->last_query = $query; + $newquery = $this->modifyQuery($newquery); + if (!$stmt = @OCIParse($this->connection, $newquery)) { + return $this->oci8RaiseError(); + } + $this->prepare_types[(int)$stmt] = $types; + $this->manip_query[(int)$stmt] = DB::isManip($query); + return $stmt; + } + + // }}} + // {{{ execute() + + /** + * Executes a DB statement prepared with prepare(). + * + * @param resource $stmt a DB statement resource returned from prepare() + * @param mixed $data array, string or numeric data to be used in + * execution of the statement. Quantity of items + * passed must match quantity of placeholders in + * query: meaning 1 for non-array items or the + * quantity of elements in the array. + * @return int returns an oci8 result resource for successful + * SELECT queries, DB_OK for other successful queries. A DB error + * code is returned on failure. + * @see DB_oci::prepare() + */ + function &execute($stmt, $data = array()) + { + if (!is_array($data)) { + $data = array($data); + } + + $this->_data = $data; + + $types =& $this->prepare_types[(int)$stmt]; + if (count($types) != count($data)) { + $tmp =& $this->raiseError(DB_ERROR_MISMATCH); + return $tmp; + } + + $i = 0; + foreach ($data as $key => $value) { + if ($types[$i] == DB_PARAM_MISC) { + /* + * Oracle doesn't seem to have the ability to pass a + * parameter along unchanged, so strip off quotes from start + * and end, plus turn two single quotes to one single quote, + * in order to avoid the quotes getting escaped by + * Oracle and ending up in the database. + */ + $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); + $data[$key] = str_replace("''", "'", $data[$key]); + } elseif ($types[$i] == DB_PARAM_OPAQUE) { + $fp = @fopen($data[$key], 'rb'); + if (!$fp) { + $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); + return $tmp; + } + $data[$key] = fread($fp, filesize($data[$key])); + fclose($fp); + } + if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { + $tmp = $this->oci8RaiseError($stmt); + return $tmp; + } + $i++; + } + if ($this->autoCommit) { + $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); + } else { + $success = @OCIExecute($stmt, OCI_DEFAULT); + } + if (!$success) { + $tmp = $this->oci8RaiseError($stmt); + return $tmp; + } + $this->last_stmt = $stmt; + if ($this->manip_query[(int)$stmt]) { + $tmp = DB_OK; + } else { + $tmp =& new DB_result($this, $stmt); + } + return $tmp; + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + * + * @param $onoff true/false whether to autocommit + */ + function autoCommit($onoff = false) + { + $this->autoCommit = (bool)$onoff;; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit transactions on the current connection + * + * @return DB_ERROR or DB_OK + */ + function commit() + { + $result = @OCICommit($this->connection); + if (!$result) { + return $this->oci8RaiseError(); + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back all uncommitted transactions on the current connection. + * + * @return DB_ERROR or DB_OK + */ + function rollback() + { + $result = @OCIRollback($this->connection); + if (!$result) { + return $this->oci8RaiseError(); + } + return DB_OK; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the last query. + * if the last query was a select, returns 0. + * + * @return number of rows affected by the last query or DB_ERROR + */ + function affectedRows() + { + if ($this->last_stmt === false) { + return $this->oci8RaiseError(); + } + $result = @OCIRowCount($this->last_stmt); + if ($result === false) { + return $this->oci8RaiseError($this->last_stmt); + } + return $result; + } + + // }}} + // {{{ modifyQuery() + + function modifyQuery($query) + { + // "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle + if (preg_match('/^\s*SELECT/i', $query) && + !preg_match('/\sFROM\s/i', $query)) { + $query .= ' FROM dual'; + } + return $query; + } + + // }}} + // {{{ modifyLimitQuery() + + /** + * Emulate the row limit support altering the query + * + * @param string $query The query to treat + * @param int $from The row to start to fetch from + * @param int $count The offset + * @return string The modified query + * + * @author Tomas V.V.Cox + */ + function modifyLimitQuery($query, $from, $count, $params = array()) + { + // Let Oracle return the name of the columns instead of + // coding a "home" SQL parser + + if (count($params)) { + $result = $this->prepare("SELECT * FROM ($query) " + . 'WHERE NULL = NULL'); + $tmp =& $this->execute($result, $params); + } else { + $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; + + if (!$result = @OCIParse($this->connection, $q_fields)) { + $this->last_query = $q_fields; + return $this->oci8RaiseError(); + } + if (!@OCIExecute($result, OCI_DEFAULT)) { + $this->last_query = $q_fields; + return $this->oci8RaiseError($result); + } + } + + $ncols = OCINumCols($result); + $cols = array(); + for ( $i = 1; $i <= $ncols; $i++ ) { + $cols[] = '"' . OCIColumnName($result, $i) . '"'; + } + $fields = implode(', ', $cols); + // XXX Test that (tip by John Lim) + //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) { + // // Introduce the FIRST_ROWS Oracle query optimizer + // $query = substr($query, strlen($match[0]), strlen($query)); + // $query = "SELECT /* +FIRST_ROWS */ " . $query; + //} + + // Construct the query + // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2 + // Perhaps this could be optimized with the use of Unions + $query = "SELECT $fields FROM". + " (SELECT rownum as linenum, $fields FROM". + " ($query)". + ' WHERE rownum <= '. ($from + $count) . + ') WHERE linenum >= ' . ++$from; + return $query; + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + $repeat = 0; + do { + $this->expectError(DB_ERROR_NOSUCHTABLE); + $result =& $this->query("SELECT ${seqname}.nextval FROM dual"); + $this->popExpect(); + if ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) { + $repeat = 1; + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $this->raiseError($result); + } + } else { + $repeat = 0; + } + } while ($repeat); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); + return $arr[0]; + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("CREATE SEQUENCE ${seqname}"); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP SEQUENCE ${seqname}"); + } + + // }}} + // {{{ oci8RaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function oci8RaiseError($errno = null) + { + if ($errno === null) { + $error = @OCIError($this->connection); + return $this->raiseError($this->errorCode($error['code']), + null, null, null, $error['message']); + } elseif (is_resource($errno)) { + $error = @OCIError($errno); + return $this->raiseError($this->errorCode($error['code']), + null, null, null, $error['message']); + } + return $this->raiseError($this->errorCode($errno)); + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return 'SELECT table_name FROM user_tables'; + default: + return null; + } + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * NOTE: flags won't contain index information. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + if (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $result = strtoupper($result); + $q_fields = 'SELECT column_name, data_type, data_length, ' + . 'nullable ' + . 'FROM user_tab_columns ' + . "WHERE table_name='$result' ORDER BY column_id"; + + $this->last_query = $q_fields; + + if (!$stmt = @OCIParse($this->connection, $q_fields)) { + return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); + } + if (!@OCIExecute($stmt, OCI_DEFAULT)) { + return $this->oci8RaiseError($stmt); + } + + $i = 0; + while (@OCIFetch($stmt)) { + $res[$i]['table'] = $case_func($result); + $res[$i]['name'] = $case_func(@OCIResult($stmt, 1)); + $res[$i]['type'] = @OCIResult($stmt, 2); + $res[$i]['len'] = @OCIResult($stmt, 3); + $res[$i]['flags'] = (@OCIResult($stmt, 4) == 'N') ? 'not_null' : ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + $i++; + } + + if ($mode) { + $res['num_fields'] = $i; + } + @OCIFreeStatement($stmt); + + } else { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $result = $result->result; + } else { + /* + * ELSE, probably received a result resource identifier. + * Deprecated. Here for compatibility only. + */ + } + + if ($result === $this->last_stmt) { + $count = @OCINumCols($result); + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = ''; + $res[$i]['name'] = $case_func(@OCIColumnName($result, $i+1)); + $res[$i]['type'] = @OCIColumnType($result, $i+1); + $res[$i]['len'] = @OCIColumnSize($result, $i+1); + $res[$i]['flags'] = ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + + if ($mode) { + $res['num_fields'] = $count; + } + + } else { + return $this->raiseError(DB_ERROR_NOT_CAPABLE); + } + } + return $res; + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/odbc.php b/gulliver/thirdparty/pear/DB/odbc.php new file mode 100644 index 000000000..0f0532769 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/odbc.php @@ -0,0 +1,585 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: odbc.php 3355 2005-06-11 22:14:40Z nbm $ + + +// XXX legend: +// More info on ODBC errors could be found here: +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp +// +// XXX ERRORMSG: The error message from the odbc function should +// be registered here. + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's ODBC + * extension. + * + * @package DB + * @version $Id: odbc.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Stig Bakken + */ +class DB_odbc extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $row = array(); + + // }}} + // {{{ constructor + + function DB_odbc() + { + $this->DB_common(); + $this->phptype = 'odbc'; + $this->dbsyntax = 'sql92'; + $this->features = array( + 'prepare' => true, + 'pconnect' => true, + 'transactions' => false, + 'limit' => 'emulate' + ); + $this->errorcode_map = array( + '01004' => DB_ERROR_TRUNCATED, + '07001' => DB_ERROR_MISMATCH, + '21S01' => DB_ERROR_MISMATCH, + '21S02' => DB_ERROR_MISMATCH, + '22003' => DB_ERROR_INVALID_NUMBER, + '22005' => DB_ERROR_INVALID_NUMBER, + '22008' => DB_ERROR_INVALID_DATE, + '22012' => DB_ERROR_DIVZERO, + '23000' => DB_ERROR_CONSTRAINT, + '23502' => DB_ERROR_CONSTRAINT_NOT_NULL, + '23503' => DB_ERROR_CONSTRAINT, + '23505' => DB_ERROR_CONSTRAINT, + '24000' => DB_ERROR_INVALID, + '34000' => DB_ERROR_INVALID, + '37000' => DB_ERROR_SYNTAX, + '42000' => DB_ERROR_SYNTAX, + '42601' => DB_ERROR_SYNTAX, + 'IM001' => DB_ERROR_UNSUPPORTED, + 'S0000' => DB_ERROR_NOSUCHTABLE, + 'S0001' => DB_ERROR_ALREADY_EXISTS, + 'S0002' => DB_ERROR_NOSUCHTABLE, + 'S0011' => DB_ERROR_ALREADY_EXISTS, + 'S0012' => DB_ERROR_NOT_FOUND, + 'S0021' => DB_ERROR_ALREADY_EXISTS, + 'S0022' => DB_ERROR_NOSUCHFIELD, + 'S1000' => DB_ERROR_CONSTRAINT_NOT_NULL, + 'S1009' => DB_ERROR_INVALID, + 'S1090' => DB_ERROR_INVALID, + 'S1C00' => DB_ERROR_NOT_CAPABLE + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * + * @return int DB_OK on success, a DB error code on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('odbc')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + if ($dsninfo['dbsyntax']) { + $this->dbsyntax = $dsninfo['dbsyntax']; + } + switch ($this->dbsyntax) { + case 'solid': + $this->features = array( + 'prepare' => true, + 'pconnect' => true, + 'transactions' => true + ); + break; + case 'navision': + // the Navision driver doesn't support fetch row by number + $this->features['limit'] = false; + } + + /* + * This is hear for backwards compatibility. + * Should have been using 'database' all along, but used hostspec. + */ + if ($dsninfo['database']) { + $odbcdsn = $dsninfo['database']; + } elseif ($dsninfo['hostspec']) { + $odbcdsn = $dsninfo['hostspec']; + } else { + $odbcdsn = 'localhost'; + } + + if ($this->provides('pconnect')) { + $connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect'; + } else { + $connect_function = 'odbc_connect'; + } + + if (empty($dsninfo['cursor'])) { + $conn = @$connect_function($odbcdsn, $dsninfo['username'], + $dsninfo['password']); + } else { + $conn = @$connect_function($odbcdsn, $dsninfo['username'], + $dsninfo['password'], + $dsninfo['cursor']); + } + + if (!is_resource($conn)) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, + null, $this->errorNative()); + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + function disconnect() + { + $err = @odbc_close($this->connection); + $this->connection = null; + return $err; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to ODBC and return the results as a ODBC resource + * identifier. + * + * @param $query the SQL query + * + * @return int returns a valid ODBC result for successful SELECT + * queries, DB_OK for other successful queries. A DB error code + * is returned on failure. + */ + function simpleQuery($query) + { + $this->last_query = $query; + $query = $this->modifyQuery($query); + $result = @odbc_exec($this->connection, $query); + if (!$result) { + return $this->odbcRaiseError(); // XXX ERRORMSG + } + // Determine which queries that should return data, and which + // should return an error code only. + if (DB::isManip($query)) { + $this->manip_result = $result; // For affectedRows() + return DB_OK; + } + $this->row[(int)$result] = 0; + $this->manip_result = 0; + return $result; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal odbc result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return @odbc_next_result($result); + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + $arr = array(); + if ($rownum !== null) { + $rownum++; // ODBC first row is 1 + if (version_compare(phpversion(), '4.2.0', 'ge')) { + $cols = @odbc_fetch_into($result, $arr, $rownum); + } else { + $cols = @odbc_fetch_into($result, $rownum, $arr); + } + } else { + $cols = @odbc_fetch_into($result, $arr); + } + + if (!$cols) { + /* XXX FIXME: doesn't work with unixODBC and easysoft + (get corrupted $errno values) + if ($errno = @odbc_error($this->connection)) { + return $this->RaiseError($errno); + }*/ + return null; + } + if ($fetchmode !== DB_FETCHMODE_ORDERED) { + for ($i = 0; $i < count($arr); $i++) { + $colName = @odbc_field_name($result, $i+1); + $a[$colName] = $arr[$i]; + } + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $a = array_change_key_case($a, CASE_LOWER); + } + $arr = $a; + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + function freeResult($result) + { + unset($this->row[(int)$result]); + return @odbc_free_result($result); + } + + // }}} + // {{{ numCols() + + function numCols($result) + { + $cols = @odbc_num_fields($result); + if (!$cols) { + return $this->odbcRaiseError(); + } + return $cols; + } + + // }}} + // {{{ affectedRows() + + /** + * Returns the number of rows affected by a manipulative query + * (INSERT, DELETE, UPDATE) + * @return mixed int affected rows, 0 when non manip queries or + * DB error on error + */ + function affectedRows() + { + if (empty($this->manip_result)) { // In case of SELECT stms + return 0; + } + $nrows = @odbc_num_rows($this->manip_result); + if ($nrows == -1) { + return $this->odbcRaiseError(); + } + return $nrows; + } + + // }}} + // {{{ numRows() + + /** + * ODBC may or may not support counting rows in the result set of + * SELECTs. + * + * @param $result the odbc result resource + * @return the number of rows, or 0 + */ + function numRows($result) + { + $nrows = @odbc_num_rows($result); + if ($nrows == -1) { + return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED); + } + return $nrows; + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table / column name + * + * Quoting style depends on which dbsyntax was passed in the DSN. + * + * Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked + * "Use ANSI quoted identifiers" when setting up the ODBC data source. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + */ + function quoteIdentifier($str) + { + switch ($this->dsn['dbsyntax']) { + case 'access': + return '[' . $str . ']'; + case 'mssql': + case 'sybase': + return '[' . str_replace(']', ']]', $str) . ']'; + case 'mysql': + case 'mysqli': + return '`' . $str . '`'; + default: + return '"' . str_replace('"', '""', $str) . '"'; + } + } + + // }}} + // {{{ quote() + + /** + * @deprecated Deprecated in release 1.6.0 + * @internal + */ + function quote($str) { + return $this->quoteSmart($str); + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that + * occured on the current connection. + * + * @access public + * + * @return int ODBC error code + */ + function errorNative() + { + if (!isset($this->connection) || !is_resource($this->connection)) { + return @odbc_error() . ' ' . @odbc_errormsg(); + } + return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection); + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + $repeat = 0; + do { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("update ${seqname} set id = id + 1"); + $this->popErrorHandling(); + if ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) { + $repeat = 1; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->createSequence($seq_name); + $this->popErrorHandling(); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $result = $this->query("insert into ${seqname} (id) values(0)"); + } else { + $repeat = 0; + } + } while ($repeat); + + if (DB::isError($result)) { + return $this->raiseError($result); + } + + $result = $this->query("select id from ${seqname}"); + if (DB::isError($result)) { + return $result; + } + + $row = $result->fetchRow(DB_FETCHMODE_ORDERED); + if (DB::isError($row || !$row)) { + return $row; + } + + return $row[0]; + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("CREATE TABLE ${seqname} ". + '(id integer NOT NULL,'. + ' PRIMARY KEY(id))'); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP TABLE ${seqname}"); + } + + // }}} + // {{{ autoCommit() + + function autoCommit($onoff = false) + { + if (!@odbc_autocommit($this->connection, $onoff)) { + return $this->odbcRaiseError(); + } + return DB_OK; + } + + // }}} + // {{{ commit() + + function commit() + { + if (!@odbc_commit($this->connection)) { + return $this->odbcRaiseError(); + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + function rollback() + { + if (!@odbc_rollback($this->connection)) { + return $this->odbcRaiseError(); + } + return DB_OK; + } + + // }}} + // {{{ odbcRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorNative() + * @see DB_common::errorCode() + * @see DB_common::raiseError() + */ + function odbcRaiseError($errno = null) + { + if ($errno === null) { + switch ($this->dbsyntax) { + case 'access': + if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { + $this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD; + } else { + // Doing this in case mode changes during runtime. + $this->errorcode_map['07001'] = DB_ERROR_MISMATCH; + } + } + $errno = $this->errorCode(odbc_error($this->connection)); + } + return $this->raiseError($errno, null, null, null, + $this->errorNative()); + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/pgsql.php b/gulliver/thirdparty/pear/DB/pgsql.php new file mode 100644 index 000000000..0a95eb132 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/pgsql.php @@ -0,0 +1,847 @@ + | +// | Stig Bakken | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: pgsql.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's PostgreSQL + * extension. + * + * @package DB + * @version $Id: pgsql.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Rui Hirokawa + * @author Stig Bakken + */ +class DB_pgsql extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $transaction_opcount = 0; + var $dsn = array(); + var $row = array(); + var $num_rows = array(); + var $affected = 0; + var $autocommit = true; + var $fetchmode = DB_FETCHMODE_ORDERED; + + // }}} + // {{{ constructor + + function DB_pgsql() + { + $this->DB_common(); + $this->phptype = 'pgsql'; + $this->dbsyntax = 'pgsql'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => true, + 'limit' => 'alter' + ); + $this->errorcode_map = array( + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * + * @return int DB_OK on success, a DB error code on failure. + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('pgsql')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + $protocol = $dsninfo['protocol'] ? $dsninfo['protocol'] : 'tcp'; + $connstr = ''; + + if ($protocol == 'tcp') { + if ($dsninfo['hostspec']) { + $connstr .= 'host=' . $dsninfo['hostspec']; + } + if ($dsninfo['port']) { + $connstr .= ' port=' . $dsninfo['port']; + } + } elseif ($protocol == 'unix') { + // Allow for pg socket in non-standard locations. + if ($dsninfo['socket']) { + $connstr .= 'host=' . $dsninfo['socket']; + } + if ($dsninfo['port']) { + $connstr .= ' port=' . $dsninfo['port']; + } + } + + if ($dsninfo['database']) { + $connstr .= ' dbname=\'' . addslashes($dsninfo['database']) . '\''; + } + if ($dsninfo['username']) { + $connstr .= ' user=\'' . addslashes($dsninfo['username']) . '\''; + } + if ($dsninfo['password']) { + $connstr .= ' password=\'' . addslashes($dsninfo['password']) . '\''; + } + if (!empty($dsninfo['options'])) { + $connstr .= ' options=' . $dsninfo['options']; + } + if (!empty($dsninfo['tty'])) { + $connstr .= ' tty=' . $dsninfo['tty']; + } + + $connect_function = $persistent ? 'pg_pconnect' : 'pg_connect'; + + $ini = ini_get('track_errors'); + if ($ini) { + $conn = @$connect_function($connstr); + } else { + ini_set('track_errors', 1); + $conn = @$connect_function($connstr); + ini_set('track_errors', $ini); + } + if ($conn == false) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, + null, null, strip_tags($php_errormsg)); + } + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @pg_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to PostgreSQL and return the results as a + * PostgreSQL resource identifier. + * + * @param $query the SQL query + * + * @return int returns a valid PostgreSQL result for successful SELECT + * queries, DB_OK for other successful queries. A DB error code + * is returned on failure. + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $query = $this->modifyQuery($query); + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @pg_exec($this->connection, 'begin;'); + if (!$result) { + return $this->pgsqlRaiseError(); + } + } + $this->transaction_opcount++; + } + $result = @pg_exec($this->connection, $query); + if (!$result) { + return $this->pgsqlRaiseError(); + } + // Determine which queries that should return data, and which + // should return an error code only. + if ($ismanip) { + $this->affected = @pg_cmdtuples($result); + return DB_OK; + } elseif (preg_match('/^\s*\(?\s*(SELECT(?!\s+INTO)|EXPLAIN|SHOW)\s/si', $query)) { + /* PostgreSQL commands: + ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY, + CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH, + GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET, + REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW, + UNLISTEN, UPDATE, VACUUM + */ + $this->row[(int)$result] = 0; // reset the row counter. + $numrows = $this->numrows($result); + if (is_object($numrows)) { + return $numrows; + } + $this->num_rows[(int)$result] = $numrows; + $this->affected = 0; + return $result; + } else { + $this->affected = 0; + return DB_OK; + } + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal pgsql result pointer to the next available result + * + * @param a valid fbsql result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ errorCode() + + /** + * Determine PEAR::DB error code from the database's text error message. + * + * @param string $errormsg error message returned from the database + * @return integer an error number from a DB error constant + */ + function errorCode($errormsg) + { + static $error_regexps; + if (!isset($error_regexps)) { + $error_regexps = array( + '/(([Rr]elation|[Ss]equence|[Tt]able)( [\"\'].*[\"\'])? does not exist|[Cc]lass ".+" not found)$/' => DB_ERROR_NOSUCHTABLE, + '/[Cc]olumn [\"\'].*[\"\'] .*does not exist/' => DB_ERROR_NOSUCHFIELD, + '/[Rr]elation [\"\'].*[\"\'] already exists|[Cc]annot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, + '/(divide|division) by zero$/' => DB_ERROR_DIVZERO, + '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, + '/invalid input syntax for integer/' => DB_ERROR_INVALID_NUMBER, + '/ttribute [\"\'].*[\"\'] not found$|[Rr]elation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, + '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, + '/syntax error at/' => DB_ERROR_SYNTAX, + '/permission denied/' => DB_ERROR_ACCESS_VIOLATION, + '/violates not-null constraint/' => DB_ERROR_CONSTRAINT_NOT_NULL, + '/violates [\w ]+ constraint/' => DB_ERROR_CONSTRAINT, + '/referential integrity violation/' => DB_ERROR_CONSTRAINT + ); + } + foreach ($error_regexps as $regexp => $code) { + if (preg_match($regexp, $errormsg)) { + return $code; + } + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + $result_int = (int)$result; + $rownum = ($rownum !== null) ? $rownum : $this->row[$result_int]; + if ($rownum >= $this->num_rows[$result_int]) { + return null; + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @pg_fetch_row($result, $rownum); + } + if (!$arr) { + $err = pg_errormessage($this->connection); + if (!$err) { + return null; + } + return $this->pgsqlRaiseError(); + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + $this->row[$result_int] = ++$rownum; + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result int PostgreSQL result identifier + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + if (is_resource($result)) { + unset($this->row[(int)$result]); + unset($this->num_rows[(int)$result]); + $this->affected = 0; + return @pg_freeresult($result); + } + return false; + } + + // }}} + // {{{ quote() + + /** + * @deprecated Deprecated in release 1.6.0 + * @internal + */ + function quote($str) { + return $this->quoteSmart($str); + } + + // }}} + // {{{ quoteSmart() + + /** + * Format input so it can be safely used in a query + * + * @param mixed $in data to be quoted + * + * @return mixed Submitted variable's type = returned value: + * + null = the string NULL + * + boolean = string TRUE or FALSE + * + integer or double = the unquoted number + * + other (including strings and numeric strings) = + * the data escaped according to MySQL's settings + * then encapsulated between single quotes + * + * @internal + */ + function quoteSmart($in) + { + if (is_int($in) || is_double($in)) { + return $in; + } elseif (is_bool($in)) { + return $in ? 'TRUE' : 'FALSE'; + } elseif (is_null($in)) { + return 'NULL'; + } else { + return "'" . $this->escapeSimple($in) . "'"; + } + } + + // }}} + // {{{ escapeSimple() + + /** + * Escape a string according to the current DBMS's standards + * + * PostgreSQL treats a backslash as an escape character, so they are + * removed. + * + * Not using pg_escape_string() yet because it requires PostgreSQL + * to be at version 7.2 or greater. + * + * @param string $str the string to be escaped + * + * @return string the escaped string + * + * @internal + */ + function escapeSimple($str) { + return str_replace("'", "''", str_replace('\\', '\\\\', $str)); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result resource PostgreSQL result identifier + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @pg_numfields($result); + if (!$cols) { + return $this->pgsqlRaiseError(); + } + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @param $result resource PostgreSQL result identifier + * + * @return int the number of rows in $result + */ + function numRows($result) + { + $rows = @pg_numrows($result); + if ($rows === null) { + return $this->pgsqlRaiseError(); + } + return $rows; + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error code of the last error (if any) that + * occured on the current connection. + * + * @return int native PostgreSQL error code + */ + function errorNative() + { + return pg_errormessage($this->connection); + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + */ + function autoCommit($onoff = false) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + // (disabled) hack to shut up error messages from libpq.a + //@fclose(@fopen("php://stderr", "w")); + $result = @pg_exec($this->connection, 'end;'); + $this->transaction_opcount = 0; + if (!$result) { + return $this->pgsqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + $result = @pg_exec($this->connection, 'abort;'); + $this->transaction_opcount = 0; + if (!$result) { + return $this->pgsqlRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the last query. + * if the last query was a select, returns 0. + * + * @return int number of rows affected by the last query or DB_ERROR + */ + function affectedRows() + { + return $this->affected; + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + $repeat = false; + do { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result =& $this->query("SELECT NEXTVAL('${seqname}')"); + $this->popErrorHandling(); + if ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) { + $repeat = true; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->createSequence($seq_name); + $this->popErrorHandling(); + if (DB::isError($result)) { + return $this->raiseError($result); + } + } else { + $repeat = false; + } + } while ($repeat); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); + $result->free(); + return $arr[0]; + } + + // }}} + // {{{ createSequence() + + /** + * Create the sequence + * + * @param string $seq_name the name of the sequence + * @return mixed DB_OK on success or DB error on error + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + $result = $this->query("CREATE SEQUENCE ${seqname}"); + return $result; + } + + // }}} + // {{{ dropSequence() + + /** + * Drop a sequence + * + * @param string $seq_name the name of the sequence + * @return mixed DB_OK on success or DB error on error + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP SEQUENCE ${seqname}"); + } + + // }}} + // {{{ modifyLimitQuery() + + function modifyLimitQuery($query, $from, $count, $params = array()) + { + $query = $query . " LIMIT $count OFFSET $from"; + return $query; + } + + // }}} + // {{{ pgsqlRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorNative() + * @see errorCode() + * @see DB_common::raiseError() + */ + function pgsqlRaiseError($errno = null) + { + $native = $this->errorNative(); + if ($errno === null) { + $err = $this->errorCode($native); + } else { + $err = $errno; + } + return $this->raiseError($err, null, null, null, $native); + } + + // }}} + // {{{ _pgFieldFlags() + + /** + * Flags of a Field + * + * @param int $resource PostgreSQL result identifier + * @param int $num_field the field number + * + * @return string The flags of the field ("not_null", "default_value", + * "primary_key", "unique_key" and "multiple_key" + * are supported). The default value is passed + * through rawurlencode() in case there are spaces in it. + * @access private + */ + function _pgFieldFlags($resource, $num_field, $table_name) + { + $field_name = @pg_fieldname($resource, $num_field); + + $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef + FROM pg_attribute f, pg_class tab, pg_type typ + WHERE tab.relname = typ.typname + AND typ.typrelid = f.attrelid + AND f.attname = '$field_name' + AND tab.relname = '$table_name'"); + if (@pg_numrows($result) > 0) { + $row = @pg_fetch_row($result, 0); + $flags = ($row[0] == 't') ? 'not_null ' : ''; + + if ($row[1] == 't') { + $result = @pg_exec($this->connection, "SELECT a.adsrc + FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a + WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid + AND f.attrelid = a.adrelid AND f.attname = '$field_name' + AND tab.relname = '$table_name' AND f.attnum = a.adnum"); + $row = @pg_fetch_row($result, 0); + $num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); + $flags .= 'default_' . rawurlencode($num) . ' '; + } + } else { + $flags = ''; + } + $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey + FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i + WHERE tab.relname = typ.typname + AND typ.typrelid = f.attrelid + AND f.attrelid = i.indrelid + AND f.attname = '$field_name' + AND tab.relname = '$table_name'"); + $count = @pg_numrows($result); + + for ($i = 0; $i < $count ; $i++) { + $row = @pg_fetch_row($result, $i); + $keys = explode(' ', $row[2]); + + if (in_array($num_field + 1, $keys)) { + $flags .= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : ''; + $flags .= ($row[1] == 't') ? 'primary_key ' : ''; + if (count($keys) > 1) + $flags .= 'multiple_key '; + } + } + + return trim($flags); + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + $id = @pg_exec($this->connection, "SELECT * FROM $result LIMIT 0"); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @pg_numfields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func(@pg_fieldname($id, $i)); + $res[$i]['type'] = @pg_fieldtype($id, $i); + $res[$i]['len'] = @pg_fieldsize($id, $i); + $res[$i]['flags'] = $got_string ? $this->_pgFieldflags($id, $i, $result) : ''; + } + + } else { // full + $res['num_fields']= $count; + + for ($i=0; $i<$count; $i++) { + $res[$i]['table'] = $got_string ? $case_func($result) : ''; + $res[$i]['name'] = $case_func(@pg_fieldname($id, $i)); + $res[$i]['type'] = @pg_fieldtype($id, $i); + $res[$i]['len'] = @pg_fieldsize($id, $i); + $res[$i]['flags'] = $got_string ? $this->_pgFieldFlags($id, $i, $result) : ''; + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @pg_freeresult($id); + } + return $res; + } + + // }}} + // {{{ getTablesQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return "SELECT c.relname as \"Name\" + FROM pg_class c, pg_user u + WHERE c.relowner = u.usesysid AND c.relkind = 'r' + AND not exists (select 1 from pg_views where viewname = c.relname) + AND c.relname !~ '^(pg_|sql_)' + UNION + SELECT c.relname as \"Name\" + FROM pg_class c + WHERE c.relkind = 'r' + AND not exists (select 1 from pg_views where viewname = c.relname) + AND not exists (select 1 from pg_user where usesysid = c.relowner) + AND c.relname !~ '^pg_'"; + case 'views': + // Table cols: viewname | viewowner | definition + return 'SELECT viewname FROM pg_views'; + case 'users': + // cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil + return 'SELECT usename FROM pg_user'; + case 'databases': + return 'SELECT datname FROM pg_database'; + case 'functions': + return 'SELECT proname FROM pg_proc'; + default: + return null; + } + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/sqlite.php b/gulliver/thirdparty/pear/DB/sqlite.php new file mode 100644 index 000000000..cd5a12ca3 --- /dev/null +++ b/gulliver/thirdparty/pear/DB/sqlite.php @@ -0,0 +1,695 @@ + | +// | Mika Tuupola | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: sqlite.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for the SQLite + * PECL extension. + * + * @package DB + * @version $Id: sqlite.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Urs Gehrig + * @author Mika Tuupola + */ +class DB_sqlite extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $_lasterror = ''; + + // }}} + // {{{ constructor + + /** + * Constructor for this class. + * + * Error codes according to sqlite_exec. Error Codes specification is + * in the {@link http://sqlite.org/c_interface.html online manual}. + * + * This errorhandling based on sqlite_exec is not yet implemented. + * + * @access public + */ + function DB_sqlite() + { + + $this->DB_common(); + $this->phptype = 'sqlite'; + $this->dbsyntax = 'sqlite'; + $this->features = array ( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => false, + 'limit' => 'alter' + ); + + // SQLite data types, http://www.sqlite.org/datatypes.html + $this->keywords = array ( + 'BLOB' => '', + 'BOOLEAN' => '', + 'CHARACTER' => '', + 'CLOB' => '', + 'FLOAT' => '', + 'INTEGER' => '', + 'KEY' => '', + 'NATIONAL' => '', + 'NUMERIC' => '', + 'NVARCHAR' => '', + 'PRIMARY' => '', + 'TEXT' => '', + 'TIMESTAMP' => '', + 'UNIQUE' => '', + 'VARCHAR' => '', + 'VARYING' => '' + ); + $this->errorcode_map = array( + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database represented by a file. + * + * @param $dsn the data source name; the file is taken as + * database; "sqlite://root:@host/test.db?mode=0644" + * @param $persistent (optional) whether the connection should + * be persistent + * @access public + * @return int DB_OK on success, a DB error on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('sqlite')) { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + + if ($dsninfo['database']) { + if (!file_exists($dsninfo['database'])) { + if (!touch($dsninfo['database'])) { + return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); + } + if (!isset($dsninfo['mode']) || + !is_numeric($dsninfo['mode'])) + { + $mode = 0644; + } else { + $mode = octdec($dsninfo['mode']); + } + if (!chmod($dsninfo['database'], $mode)) { + return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); + } + if (!file_exists($dsninfo['database'])) { + return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); + } + } + if (!is_file($dsninfo['database'])) { + return $this->sqliteRaiseError(DB_ERROR_INVALID); + } + if (!is_readable($dsninfo['database'])) { + return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); + } + } else { + return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); + } + + $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; + if (!($conn = @$connect_function($dsninfo['database']))) { + return $this->sqliteRaiseError(DB_ERROR_NODBSELECTED); + } + $this->connection = $conn; + + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @access public + * @return bool true on success, false if not connected. + * @todo fix return values + */ + function disconnect() + { + $ret = @sqlite_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to SQLite and returns the results as a SQLite resource + * identifier. + * + * @param the SQL query + * @access public + * @return mixed returns a valid SQLite result for successful SELECT + * queries, DB_OK for other successful queries. A DB error is + * returned on failure. + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + $query = $this->_modifyQuery($query); + ini_set('track_errors', true); + $result = @sqlite_query($query, $this->connection); + ini_restore('track_errors'); + $this->_lasterror = isset($php_errormsg) ? $php_errormsg : ''; + $this->result = $result; + if (!$this->result) { + return $this->sqliteRaiseError(null); + } + + /* sqlite_query() seems to allways return a resource */ + /* so cant use that. Using $ismanip instead */ + if (!$ismanip) { + $numRows = $this->numRows($result); + + /* if numRows() returned PEAR_Error */ + if (is_object($numRows)) { + return $numRows; + } + return $result; + } + return DB_OK; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal sqlite result pointer to the next available result. + * + * @param a valid sqlite result resource + * @access public + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@sqlite_seek($this->result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + $arr = @sqlite_fetch_array($result, SQLITE_ASSOC); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @sqlite_fetch_array($result, SQLITE_NUM); + } + if (!$arr) { + /* See: http://bugs.php.net/bug.php?id=22328 */ + return null; + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + /* + * Even though this DBMS already trims output, we do this because + * a field might have intentional whitespace at the end that + * gets removed by DB_PORTABILITY_RTRIM under another driver. + */ + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result SQLite result identifier + * @access public + * @return bool true on success, false if $result is invalid + */ + function freeResult(&$result) + { + // XXX No native free? + if (!is_resource($result)) { + return false; + } + $result = null; + return true; + } + + // }}} + // {{{ numCols() + + /** + * Gets the number of columns in a result set. + * + * @return number of columns in a result set + */ + function numCols($result) + { + $cols = @sqlite_num_fields($result); + if (!$cols) { + return $this->sqliteRaiseError(); + } + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Gets the number of rows affected by a query. + * + * @return number of rows affected by the last query + */ + function numRows($result) + { + $rows = @sqlite_num_rows($result); + if (!is_integer($rows)) { + return $this->raiseError(); + } + return $rows; + } + + // }}} + // {{{ affected() + + /** + * Gets the number of rows affected by a query. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + return @sqlite_changes($this->connection); + } + + // }}} + // {{{ errorNative() + + /** + * Get the native error string of the last error (if any) that + * occured on the current connection. + * + * This is used to retrieve more meaningfull error messages DB_pgsql + * way since sqlite_last_error() does not provide adequate info. + * + * @return string native SQLite error message + */ + function errorNative() + { + return($this->_lasterror); + } + + // }}} + // {{{ errorCode() + + /** + * Determine PEAR::DB error code from the database's text error message. + * + * @param string $errormsg error message returned from the database + * @return integer an error number from a DB error constant + */ + function errorCode($errormsg) + { + static $error_regexps; + if (!isset($error_regexps)) { + $error_regexps = array( + '/^no such table:/' => DB_ERROR_NOSUCHTABLE, + '/^table .* already exists$/' => DB_ERROR_ALREADY_EXISTS, + '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, + '/is not unique/' => DB_ERROR_CONSTRAINT, + '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, + '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, + '/^no such column:/' => DB_ERROR_NOSUCHFIELD, + '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX + ); + } + foreach ($error_regexps as $regexp => $code) { + if (preg_match($regexp, $errormsg)) { + return $code; + } + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP TABLE $seqname"); + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + $query = 'CREATE TABLE ' . $seqname . + ' (id INTEGER UNSIGNED PRIMARY KEY) '; + $result = $this->query($query); + if (DB::isError($result)) { + return($result); + } + $query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname + BEGIN + DELETE FROM $seqname WHERE idquery($query); + if (DB::isError($result)) { + return($result); + } + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + + do { + $repeat = 0; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)"); + $this->popErrorHandling(); + if ($result === DB_OK) { + $id = @sqlite_last_insert_rowid($this->connection); + if ($id != 0) { + return $id; + } + } elseif ($ondemand && DB::isError($result) && + $result->getCode() == DB_ERROR_NOSUCHTABLE) + { + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $this->raiseError($result); + } else { + $repeat = 1; + } + } + } while ($repeat); + + return $this->raiseError($result); + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info. + * + * Refer to the online manual at http://sqlite.org/sqlite.html. + * + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type, $args=array()) + { + if (!is_array($args)) + return $this->raiseError('no key specified', null, null, null, + 'Argument has to be an array.'); + switch (strtolower($type)) { + case 'master': + return 'SELECT * FROM sqlite_master;'; + case 'tables': + return "SELECT name FROM sqlite_master WHERE type='table' " + . 'UNION ALL SELECT name FROM sqlite_temp_master ' + . "WHERE type='table' ORDER BY name;"; + case 'schema': + return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL ' + . 'SELECT * FROM sqlite_temp_master) ' + . "WHERE type!='meta' ORDER BY tbl_name, type DESC, name;"; + case 'schemax': + case 'schema_x': + /* + * Use like: + * $res = $db->query($db->getSpecialQuery('schema_x', array('table' => 'table3'))); + */ + return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL ' + . 'SELECT * FROM sqlite_temp_master) ' + . "WHERE tbl_name LIKE '{$args['table']}' AND type!='meta' " + . 'ORDER BY type DESC, name;'; + case 'alter': + /* + * SQLite does not support ALTER TABLE; this is a helper query + * to handle this. 'table' represents the table name, 'rows' + * the news rows to create, 'save' the row(s) to keep _with_ + * the data. + * + * Use like: + * $args = array( + * 'table' => $table, + * 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", + * 'save' => "NULL, titel, content, datetime" + * ); + * $res = $db->query( $db->getSpecialQuery('alter', $args)); + */ + $rows = strtr($args['rows'], $this->keywords); + + $q = array( + 'BEGIN TRANSACTION', + "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", + "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", + "DROP TABLE {$args['table']}", + "CREATE TABLE {$args['table']} ({$args['rows']})", + "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", + "DROP TABLE {$args['table']}_backup", + 'COMMIT', + ); + + // This is a dirty hack, since the above query will no get executed with a single + // query call; so here the query method will be called directly and return a select instead. + foreach ($q as $query) { + $this->query($query); + } + return "SELECT * FROM {$args['table']};"; + default: + return null; + } + } + + // }}} + // {{{ getDbFileStats() + + /** + * Get the file stats for the current database. + * + * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, + * atime, mtime, ctime, blksize, blocks or a numeric key between + * 0 and 12. + * + * @param string $arg Array key for stats() + * @return mixed array on an unspecified key, integer on a passed arg and + * false at a stats error. + */ + function getDbFileStats($arg = '') + { + $stats = stat($this->dsn['database']); + if ($stats == false) { + return false; + } + if (is_array($stats)) { + if (is_numeric($arg)) { + if (((int)$arg <= 12) & ((int)$arg >= 0)) { + return false; + } + return $stats[$arg ]; + } + if (array_key_exists(trim($arg), $stats)) { + return $stats[$arg ]; + } + } + return $stats; + } + + // }}} + // {{{ escapeSimple() + + /** + * Escape a string according to the current DBMS's standards + * + * In SQLite, this makes things safe for inserts/updates, but may + * cause problems when performing text comparisons against columns + * containing binary data. See the + * {@link http://php.net/sqlite_escape_string PHP manual} for more info. + * + * @param string $str the string to be escaped + * + * @return string the escaped string + * + * @since 1.6.1 + * @see DB_common::escapeSimple() + * @internal + */ + function escapeSimple($str) { + return @sqlite_escape_string($str); + } + + // }}} + // {{{ modifyLimitQuery() + + function modifyLimitQuery($query, $from, $count, $params = array()) + { + $query = $query . " LIMIT $count OFFSET $from"; + return $query; + } + + // }}} + // {{{ modifyQuery() + + /** + * "DELETE FROM table" gives 0 affected rows in SQLite. + * + * This little hack lets you know how many rows were deleted. + * + * @param string $query The SQL query string + * @return string The SQL query string + */ + function _modifyQuery($query) + { + if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { + $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', + 'DELETE FROM \1 WHERE 1=1', $query); + } + } + return $query; + } + + // }}} + // {{{ sqliteRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorNative() + * @see errorCode() + * @see DB_common::raiseError() + */ + function sqliteRaiseError($errno = null) + { + + $native = $this->errorNative(); + if ($errno === null) { + $errno = $this->errorCode($native); + } + + $errorcode = @sqlite_last_error($this->connection); + $userinfo = "$errorcode ** $this->last_query"; + + return $this->raiseError($errno, null, null, $userinfo, $native); + } + + // }}} +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/storage.php b/gulliver/thirdparty/pear/DB/storage.php new file mode 100644 index 000000000..1e446d93f --- /dev/null +++ b/gulliver/thirdparty/pear/DB/storage.php @@ -0,0 +1,495 @@ + | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: storage.php 3355 2005-06-11 22:14:40Z nbm $ + +require_once 'DB.php'; + +/** + * Provides an object interface to a table row. + * + * It lets you add, delete and change rows using objects rather than SQL + * statements. + * + * @package DB + * @version $Id: storage.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Stig Bakken + */ +class DB_storage extends PEAR +{ + // {{{ properties + + /** the name of the table (or view, if the backend database supports + updates in views) we hold data from */ + var $_table = null; + + /** which column(s) in the table contains primary keys, can be a + string for single-column primary keys, or an array of strings + for multiple-column primary keys */ + var $_keycolumn = null; + + /** DB connection handle used for all transactions */ + var $_dbh = null; + + /** an assoc with the names of database fields stored as properties + in this object */ + var $_properties = array(); + + /** an assoc with the names of the properties in this object that + have been changed since they were fetched from the database */ + var $_changes = array(); + + /** flag that decides if data in this object can be changed. + objects that don't have their table's key column in their + property lists will be flagged as read-only. */ + var $_readonly = false; + + /** function or method that implements a validator for fields that + are set, this validator function returns true if the field is + valid, false if not */ + var $_validator = null; + + // }}} + // {{{ constructor + + /** + * Constructor + * + * @param $table string the name of the database table + * + * @param $keycolumn mixed string with name of key column, or array of + * strings if the table has a primary key of more than one column + * + * @param $dbh object database connection object + * + * @param $validator mixed function or method used to validate + * each new value, called with three parameters: the name of the + * field/column that is changing, a reference to the new value and + * a reference to this object + * + */ + function DB_storage($table, $keycolumn, &$dbh, $validator = null) + { + $this->PEAR('DB_Error'); + $this->_table = $table; + $this->_keycolumn = $keycolumn; + $this->_dbh = $dbh; + $this->_readonly = false; + $this->_validator = $validator; + } + + // }}} + // {{{ _makeWhere() + + /** + * Utility method to build a "WHERE" clause to locate ourselves in + * the table. + * + * XXX future improvement: use rowids? + * + * @access private + */ + function _makeWhere($keyval = null) + { + if (is_array($this->_keycolumn)) { + if ($keyval === null) { + for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { + $keyval[] = $this->{$this->_keycolumn[$i]}; + } + } + $whereclause = ''; + for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { + if ($i > 0) { + $whereclause .= ' AND '; + } + $whereclause .= $this->_keycolumn[$i]; + if (is_null($keyval[$i])) { + // there's not much point in having a NULL key, + // but we support it anyway + $whereclause .= ' IS NULL'; + } else { + $whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]); + } + } + } else { + if ($keyval === null) { + $keyval = @$this->{$this->_keycolumn}; + } + $whereclause = $this->_keycolumn; + if (is_null($keyval)) { + // there's not much point in having a NULL key, + // but we support it anyway + $whereclause .= ' IS NULL'; + } else { + $whereclause .= ' = ' . $this->_dbh->quote($keyval); + } + } + return $whereclause; + } + + // }}} + // {{{ setup() + + /** + * Method used to initialize a DB_storage object from the + * configured table. + * + * @param $keyval mixed the key[s] of the row to fetch (string or array) + * + * @return int DB_OK on success, a DB error if not + */ + function setup($keyval) + { + $whereclause = $this->_makeWhere($keyval); + $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause; + $sth = $this->_dbh->query($query); + if (DB::isError($sth)) { + return $sth; + } + $row = $sth->fetchRow(DB_FETCHMODE_ASSOC); + if (DB::isError($row)) { + return $row; + } + if (!$row) { + return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null, + $query, null, true); + } + foreach ($row as $key => $value) { + $this->_properties[$key] = true; + $this->$key = $value; + } + return DB_OK; + } + + // }}} + // {{{ insert() + + /** + * Create a new (empty) row in the configured table for this + * object. + */ + function insert($newpk) + { + if (is_array($this->_keycolumn)) { + $primarykey = $this->_keycolumn; + } else { + $primarykey = array($this->_keycolumn); + } + settype($newpk, "array"); + for ($i = 0; $i < sizeof($primarykey); $i++) { + $pkvals[] = $this->_dbh->quote($newpk[$i]); + } + + $sth = $this->_dbh->query("INSERT INTO $this->_table (" . + implode(",", $primarykey) . ") VALUES(" . + implode(",", $pkvals) . ")"); + if (DB::isError($sth)) { + return $sth; + } + if (sizeof($newpk) == 1) { + $newpk = $newpk[0]; + } + $this->setup($newpk); + } + + // }}} + // {{{ toString() + + /** + * Output a simple description of this DB_storage object. + * @return string object description + */ + function toString() + { + $info = strtolower(get_class($this)); + $info .= " (table="; + $info .= $this->_table; + $info .= ", keycolumn="; + if (is_array($this->_keycolumn)) { + $info .= "(" . implode(",", $this->_keycolumn) . ")"; + } else { + $info .= $this->_keycolumn; + } + $info .= ", dbh="; + if (is_object($this->_dbh)) { + $info .= $this->_dbh->toString(); + } else { + $info .= "null"; + } + $info .= ")"; + if (sizeof($this->_properties)) { + $info .= " [loaded, key="; + $keyname = $this->_keycolumn; + if (is_array($keyname)) { + $info .= "("; + for ($i = 0; $i < sizeof($keyname); $i++) { + if ($i > 0) { + $info .= ","; + } + $info .= $this->$keyname[$i]; + } + $info .= ")"; + } else { + $info .= $this->$keyname; + } + $info .= "]"; + } + if (sizeof($this->_changes)) { + $info .= " [modified]"; + } + return $info; + } + + // }}} + // {{{ dump() + + /** + * Dump the contents of this object to "standard output". + */ + function dump() + { + foreach ($this->_properties as $prop => $foo) { + print "$prop = "; + print htmlentities($this->$prop); + print "
    \n"; + } + } + + // }}} + // {{{ &create() + + /** + * Static method used to create new DB storage objects. + * @param $data assoc. array where the keys are the names + * of properties/columns + * @return object a new instance of DB_storage or a subclass of it + */ + function &create($table, &$data) + { + $classname = strtolower(get_class($this)); + $obj =& new $classname($table); + foreach ($data as $name => $value) { + $obj->_properties[$name] = true; + $obj->$name = &$value; + } + return $obj; + } + + // }}} + // {{{ loadFromQuery() + + /** + * Loads data into this object from the given query. If this + * object already contains table data, changes will be saved and + * the object re-initialized first. + * + * @param $query SQL query + * + * @param $params parameter list in case you want to use + * prepare/execute mode + * + * @return int DB_OK on success, DB_WARNING_READ_ONLY if the + * returned object is read-only (because the object's specified + * key column was not found among the columns returned by $query), + * or another DB error code in case of errors. + */ +// XXX commented out for now +/* + function loadFromQuery($query, $params = null) + { + if (sizeof($this->_properties)) { + if (sizeof($this->_changes)) { + $this->store(); + $this->_changes = array(); + } + $this->_properties = array(); + } + $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params); + if (DB::isError($rowdata)) { + return $rowdata; + } + reset($rowdata); + $found_keycolumn = false; + while (list($key, $value) = each($rowdata)) { + if ($key == $this->_keycolumn) { + $found_keycolumn = true; + } + $this->_properties[$key] = true; + $this->$key = &$value; + unset($value); // have to unset, or all properties will + // refer to the same value + } + if (!$found_keycolumn) { + $this->_readonly = true; + return DB_WARNING_READ_ONLY; + } + return DB_OK; + } + */ + + // }}} + // {{{ set() + + /** + * Modify an attriute value. + */ + function set($property, $newvalue) + { + // only change if $property is known and object is not + // read-only + if ($this->_readonly) { + return $this->raiseError(null, DB_WARNING_READ_ONLY, null, + null, null, null, true); + } + if (@isset($this->_properties[$property])) { + if (empty($this->_validator)) { + $valid = true; + } else { + $valid = @call_user_func($this->_validator, + $this->_table, + $property, + $newvalue, + $this->$property, + $this); + } + if ($valid) { + $this->$property = $newvalue; + if (empty($this->_changes[$property])) { + $this->_changes[$property] = 0; + } else { + $this->_changes[$property]++; + } + } else { + return $this->raiseError(null, DB_ERROR_INVALID, null, + null, "invalid field: $property", + null, true); + } + return true; + } + return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null, + null, "unknown field: $property", + null, true); + } + + // }}} + // {{{ &get() + + /** + * Fetch an attribute value. + * + * @param string attribute name + * + * @return attribute contents, or null if the attribute name is + * unknown + */ + function &get($property) + { + // only return if $property is known + if (isset($this->_properties[$property])) { + return $this->$property; + } + $tmp = null; + return $tmp; + } + + // }}} + // {{{ _DB_storage() + + /** + * Destructor, calls DB_storage::store() if there are changes + * that are to be kept. + */ + function _DB_storage() + { + if (sizeof($this->_changes)) { + $this->store(); + } + $this->_properties = array(); + $this->_changes = array(); + $this->_table = null; + } + + // }}} + // {{{ store() + + /** + * Stores changes to this object in the database. + * + * @return DB_OK or a DB error + */ + function store() + { + foreach ($this->_changes as $name => $foo) { + $params[] = &$this->$name; + $vars[] = $name . ' = ?'; + } + if ($vars) { + $query = 'UPDATE ' . $this->_table . ' SET ' . + implode(', ', $vars) . ' WHERE ' . + $this->_makeWhere(); + $stmt = $this->_dbh->prepare($query); + $res = $this->_dbh->execute($stmt, $params); + if (DB::isError($res)) { + return $res; + } + $this->_changes = array(); + } + return DB_OK; + } + + // }}} + // {{{ remove() + + /** + * Remove the row represented by this object from the database. + * + * @return mixed DB_OK or a DB error + */ + function remove() + { + if ($this->_readonly) { + return $this->raiseError(null, DB_WARNING_READ_ONLY, null, + null, null, null, true); + } + $query = 'DELETE FROM ' . $this->_table .' WHERE '. + $this->_makeWhere(); + $res = $this->_dbh->query($query); + if (DB::isError($res)) { + return $res; + } + foreach ($this->_properties as $prop => $foo) { + unset($this->$prop); + } + $this->_properties = array(); + $this->_changes = array(); + return DB_OK; + } + + // }}} +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/DB/sybase.php b/gulliver/thirdparty/pear/DB/sybase.php new file mode 100644 index 000000000..34451d2ce --- /dev/null +++ b/gulliver/thirdparty/pear/DB/sybase.php @@ -0,0 +1,835 @@ + | +// | Antônio Carlos Venâncio Júnior | +// | Maintainer: Daniel Convissor | +// +----------------------------------------------------------------------+ +// +// $Id: sybase.php 3355 2005-06-11 22:14:40Z nbm $ + + +// TODO +// - This driver may fail with multiple connections under the same +// user/pass/host and different databases + + +require_once 'DB/common.php'; + +/** + * Database independent query interface definition for PHP's Sybase + * extension. + * + * @package DB + * @version $Id: sybase.php 3355 2005-06-11 22:14:40Z nbm $ + * @category Database + * @author Sterling Hughes + * @author Antônio Carlos Venâncio Júnior + */ +class DB_sybase extends DB_common +{ + // {{{ properties + + var $connection; + var $phptype, $dbsyntax; + var $prepare_tokens = array(); + var $prepare_types = array(); + var $transaction_opcount = 0; + var $autocommit = true; + + // }}} + // {{{ constructor + + /** + * DB_sybase constructor. + * + * @access public + */ + function DB_sybase() + { + $this->DB_common(); + $this->phptype = 'sybase'; + $this->dbsyntax = 'sybase'; + $this->features = array( + 'prepare' => false, + 'pconnect' => true, + 'transactions' => false, + 'limit' => 'emulate' + ); + $this->errorcode_map = array( + ); + } + + // }}} + // {{{ connect() + + /** + * Connect to a database and log in as the specified user. + * + * @param $dsn the data source name (see DB::parseDSN for syntax) + * @param $persistent (optional) whether the connection should + * be persistent + * @access public + * @return int DB_OK on success, a DB error on failure + */ + function connect($dsninfo, $persistent = false) + { + if (!DB::assertExtension('sybase') && + !DB::assertExtension('sybase_ct')) + { + return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); + } + + $this->dsn = $dsninfo; + + $interface = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; + $connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect'; + $dsninfo['password'] = !empty($dsninfo['password']) ? $dsninfo['password'] : false; + $dsninfo['charset'] = isset($dsninfo['charset']) ? $dsninfo['charset'] : false; + $dsninfo['appname'] = isset($dsninfo['appname']) ? $dsninfo['appname'] : false; + + if ($interface && $dsninfo['username']) { + $conn = @$connect_function($interface, $dsninfo['username'], + $dsninfo['password'], + $dsninfo['charset'], + $dsninfo['appname']); + } else { + $conn = false; + } + + if (!$conn) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED); + } + + if ($dsninfo['database']) { + if (!@sybase_select_db($dsninfo['database'], $conn)) { + return $this->raiseError(DB_ERROR_NODBSELECTED, null, + null, null, @sybase_get_last_message()); + } + $this->_db = $dsninfo['database']; + } + + $this->connection = $conn; + return DB_OK; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @access public + * + * @return bool true on success, false if not connected. + */ + function disconnect() + { + $ret = @sybase_close($this->connection); + $this->connection = null; + return $ret; + } + + // }}} + // {{{ errorNative() + + /** + * Get the last server error messge (if any) + * + * @return string sybase last error message + */ + function errorNative() + { + return @sybase_get_last_message(); + } + + // }}} + // {{{ errorCode() + + /** + * Determine PEAR::DB error code from the database's text error message. + * + * @param string $errormsg error message returned from the database + * @return integer an error number from a DB error constant + */ + function errorCode($errormsg) + { + static $error_regexps; + if (!isset($error_regexps)) { + $error_regexps = array( + '/Incorrect syntax near/' + => DB_ERROR_SYNTAX, + '/^Unclosed quote before the character string [\"\'].*[\"\']\./' + => DB_ERROR_SYNTAX, + '/Implicit conversion from datatype [\"\'].+[\"\'] to [\"\'].+[\"\'] is not allowed\./' + => DB_ERROR_INVALID_NUMBER, + '/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./' + => DB_ERROR_NOSUCHTABLE, + '/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./' + => DB_ERROR_ACCESS_VIOLATION, + '/^.+ permission denied on object .+, database .+, owner .+/' + => DB_ERROR_ACCESS_VIOLATION, + '/^.* permission denied, database .+, owner .+/' + => DB_ERROR_ACCESS_VIOLATION, + '/[^.*] not found\./' + => DB_ERROR_NOSUCHTABLE, + '/There is already an object named/' + => DB_ERROR_ALREADY_EXISTS, + '/Invalid column name/' + => DB_ERROR_NOSUCHFIELD, + '/does not allow null values/' + => DB_ERROR_CONSTRAINT_NOT_NULL, + '/Command has been aborted/' + => DB_ERROR_CONSTRAINT, + ); + } + + foreach ($error_regexps as $regexp => $code) { + if (preg_match($regexp, $errormsg)) { + return $code; + } + } + return DB_ERROR; + } + + // }}} + // {{{ sybaseRaiseError() + + /** + * Gather information about an error, then use that info to create a + * DB error object and finally return that object. + * + * @param integer $errno PEAR error number (usually a DB constant) if + * manually raising an error + * @return object DB error object + * @see errorNative() + * @see errorCode() + * @see DB_common::raiseError() + */ + function sybaseRaiseError($errno = null) + { + $native = $this->errorNative(); + if ($errno === null) { + $errno = $this->errorCode($native); + } + return $this->raiseError($errno, null, null, null, $native); + } + + // }}} + // {{{ simpleQuery() + + /** + * Send a query to Sybase and return the results as a Sybase resource + * identifier. + * + * @param the SQL query + * + * @access public + * + * @return mixed returns a valid Sybase result for successful SELECT + * queries, DB_OK for other successful queries. A DB error is + * returned on failure. + */ + function simpleQuery($query) + { + $ismanip = DB::isManip($query); + $this->last_query = $query; + if (!@sybase_select_db($this->_db, $this->connection)) { + return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); + } + $query = $this->modifyQuery($query); + if (!$this->autocommit && $ismanip) { + if ($this->transaction_opcount == 0) { + $result = @sybase_query('BEGIN TRANSACTION', $this->connection); + if (!$result) { + return $this->sybaseRaiseError(); + } + } + $this->transaction_opcount++; + } + $result = @sybase_query($query, $this->connection); + if (!$result) { + return $this->sybaseRaiseError(); + } + if (is_resource($result)) { + $numrows = $this->numRows($result); + if (is_object($numrows)) { + return $numrows; + } + $this->num_rows[(int)$result] = $numrows; + return $result; + } + // Determine which queries that should return data, and which + // should return an error code only. + return $ismanip ? DB_OK : $result; + } + + // }}} + // {{{ nextResult() + + /** + * Move the internal sybase result pointer to the next available result + * + * @param a valid sybase result resource + * + * @access public + * + * @return true if a result is available otherwise return false + */ + function nextResult($result) + { + return false; + } + + // }}} + // {{{ fetchInto() + + /** + * Fetch a row and insert the data into an existing array. + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * @param resource $result query result identifier + * @param array $arr (reference) array where data from the row + * should be placed + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch + * + * @return mixed DB_OK on success, null when end of result set is + * reached or on failure + * + * @see DB_result::fetchInto() + * @access private + */ + function fetchInto($result, &$arr, $fetchmode, $rownum=null) + { + if ($rownum !== null) { + if (!@sybase_data_seek($result, $rownum)) { + return null; + } + } + if ($fetchmode & DB_FETCHMODE_ASSOC) { + if (function_exists('sybase_fetch_assoc')) { + $arr = @sybase_fetch_assoc($result); + } else { + if ($arr = @sybase_fetch_array($result)) { + foreach ($arr as $key => $value) { + if (is_int($key)) { + unset($arr[$key]); + } + } + } + } + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } + } else { + $arr = @sybase_fetch_row($result); + } + if (!$arr) { + // reported not work as seems that sybase_get_last_message() + // always return a message here + //if ($errmsg = @sybase_get_last_message()) { + // return $this->sybaseRaiseError($errmsg); + //} else { + return null; + //} + } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } + return DB_OK; + } + + // }}} + // {{{ freeResult() + + /** + * Free the internal resources associated with $result. + * + * @param $result Sybase result identifier + * + * @access public + * + * @return bool true on success, false if $result is invalid + */ + function freeResult($result) + { + unset($this->num_rows[(int)$result]); + return @sybase_free_result($result); + } + + // }}} + // {{{ numCols() + + /** + * Get the number of columns in a result set. + * + * @param $result Sybase result identifier + * + * @access public + * + * @return int the number of columns per row in $result + */ + function numCols($result) + { + $cols = @sybase_num_fields($result); + if (!$cols) { + return $this->sybaseRaiseError(); + } + return $cols; + } + + // }}} + // {{{ numRows() + + /** + * Get the number of rows in a result set. + * + * @param $result Sybase result identifier + * + * @access public + * + * @return int the number of rows in $result + */ + function numRows($result) + { + $rows = @sybase_num_rows($result); + if ($rows === false) { + return $this->sybaseRaiseError(); + } + return $rows; + } + + // }}} + // {{{ affectedRows() + + /** + * Gets the number of rows affected by the data manipulation + * query. For other queries, this function returns 0. + * + * @return number of rows affected by the last query + */ + function affectedRows() + { + if (DB::isManip($this->last_query)) { + $result = @sybase_affected_rows($this->connection); + } else { + $result = 0; + } + return $result; + } + + // }}} + // {{{ nextId() + + /** + * Returns the next free id in a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true, the seqence is automatically + * created if it does not exist + * + * @return int the next id number in the sequence. DB_Error if problem. + * + * @internal + * @see DB_common::nextID() + * @access public + */ + function nextId($seq_name, $ondemand = true) + { + $seqname = $this->getSequenceName($seq_name); + if (!@sybase_select_db($this->_db, $this->connection)) { + return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); + } + $repeat = 0; + do { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); + $this->popErrorHandling(); + if ($ondemand && DB::isError($result) && + ($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) + { + $repeat = 1; + $result = $this->createSequence($seq_name); + if (DB::isError($result)) { + return $this->raiseError($result); + } + } elseif (!DB::isError($result)) { + $result =& $this->query("SELECT @@IDENTITY FROM $seqname"); + $repeat = 0; + } else { + $repeat = false; + } + } while ($repeat); + if (DB::isError($result)) { + return $this->raiseError($result); + } + $result = $result->fetchRow(DB_FETCHMODE_ORDERED); + return $result[0]; + } + + /** + * Creates a new sequence + * + * @param string $seq_name name of the new sequence + * + * @return int DB_OK on success. A DB_Error object is returned if + * problems arise. + * + * @internal + * @see DB_common::createSequence() + * @access public + */ + function createSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("CREATE TABLE $seqname ". + '(id numeric(10,0) IDENTITY NOT NULL ,' . + 'vapor int NULL)'); + } + + // }}} + // {{{ dropSequence() + + /** + * Deletes a sequence + * + * @param string $seq_name name of the sequence to be deleted + * + * @return int DB_OK on success. DB_Error if problems. + * + * @internal + * @see DB_common::dropSequence() + * @access public + */ + function dropSequence($seq_name) + { + $seqname = $this->getSequenceName($seq_name); + return $this->query("DROP TABLE $seqname"); + } + + // }}} + // {{{ getSpecialQuery() + + /** + * Returns the query needed to get some backend info + * @param string $type What kind of info you want to retrieve + * @return string The SQL query string + */ + function getSpecialQuery($type) + { + switch ($type) { + case 'tables': + return "select name from sysobjects where type = 'U' order by name"; + case 'views': + return "select name from sysobjects where type = 'V'"; + default: + return null; + } + } + + // }}} + // {{{ autoCommit() + + /** + * Enable/disable automatic commits + */ + function autoCommit($onoff = false) + { + // XXX if $this->transaction_opcount > 0, we should probably + // issue a warning here. + $this->autocommit = $onoff ? true : false; + return DB_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the current transaction. + */ + function commit() + { + if ($this->transaction_opcount > 0) { + if (!@sybase_select_db($this->_db, $this->connection)) { + return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); + } + $result = @sybase_query('COMMIT', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->sybaseRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ rollback() + + /** + * Roll back (undo) the current transaction. + */ + function rollback() + { + if ($this->transaction_opcount > 0) { + if (!@sybase_select_db($this->_db, $this->connection)) { + return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); + } + $result = @sybase_query('ROLLBACK', $this->connection); + $this->transaction_opcount = 0; + if (!$result) { + return $this->sybaseRaiseError(); + } + } + return DB_OK; + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set. + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * @param object|string $result DB_result object from a query or a + * string containing the name of a table + * @param int $mode a valid tableInfo mode + * @return array an associative array with the information requested + * or an error object if something is wrong + * @access public + * @internal + * @since 1.6.0 + * @see DB_common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (isset($result->result)) { + /* + * Probably received a result object. + * Extract the result resource identifier. + */ + $id = $result->result; + $got_string = false; + } elseif (is_string($result)) { + /* + * Probably received a table name. + * Create a result resource identifier. + */ + if (!@sybase_select_db($this->_db, $this->connection)) { + return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); + } + $id = @sybase_query("SELECT * FROM $result WHERE 1=0", + $this->connection); + $got_string = true; + } else { + /* + * Probably received a result resource identifier. + * Copy it. + * Deprecated. Here for compatibility only. + */ + $id = $result; + $got_string = false; + } + + if (!is_resource($id)) { + return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $count = @sybase_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$mode) { + + for ($i=0; $i<$count; $i++) { + $f = @sybase_fetch_field($id, $i); + + // column_source is often blank + if ($got_string) { + $res[$i]['table'] = $case_func($result); + } else { + $res[$i]['table'] = $case_func($f->column_source); + } + $res[$i]['name'] = $case_func($f->name); + $res[$i]['type'] = $f->type; + $res[$i]['len'] = $f->max_length; + if ($res[$i]['table']) { + $res[$i]['flags'] = $this->_sybase_field_flags( + $res[$i]['table'], $res[$i]['name']); + } else { + $res[$i]['flags'] = ''; + } + } + + } else { + // get full info + + $res['num_fields'] = $count; + + for ($i=0; $i<$count; $i++) { + $f = @sybase_fetch_field($id, $i); + + // column_source is often blank + if ($got_string) { + $res[$i]['table'] = $case_func($result); + } else { + $res[$i]['table'] = $case_func($f->column_source); + } + $res[$i]['name'] = $case_func($f->name); + $res[$i]['type'] = $f->type; + $res[$i]['len'] = $f->max_length; + if ($res[$i]['table']) { + $res[$i]['flags'] = $this->_sybase_field_flags( + $res[$i]['table'], $res[$i]['name']); + } else { + $res[$i]['flags'] = ''; + } + + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + } + + // free the result only if we were called on a table + if ($got_string) { + @sybase_free_result($id); + } + return $res; + } + + // }}} + // {{{ _sybase_field_flags() + + /** + * Get the flags for a field. + * + * Currently supports: + * + unique_key (unique index, unique check or primary_key) + * + multiple_key (multi-key index) + * + * @param string $table table name + * @param string $column field name + * @return string space delimited string of flags. Empty string if none. + * @access private + */ + function _sybase_field_flags($table, $column) + { + static $tableName = null; + static $flags = array(); + + if ($table != $tableName) { + $flags = array(); + $tableName = $table; + + // get unique/primary keys + $res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC); + + if (!isset($res[0]['index_description'])) { + return ''; + } + + foreach ($res as $val) { + $keys = explode(', ', trim($val['index_keys'])); + + if (sizeof($keys) > 1) { + foreach ($keys as $key) { + $this->_add_flag($flags[$key], 'multiple_key'); + } + } + + if (strpos($val['index_description'], 'unique')) { + foreach ($keys as $key) { + $this->_add_flag($flags[$key], 'unique_key'); + } + } + } + + } + + if (array_key_exists($column, $flags)) { + return(implode(' ', $flags[$column])); + } + + return ''; + } + + // }}} + // {{{ _add_flag() + + /** + * Adds a string to the flags array if the flag is not yet in there + * - if there is no flag present the array is created. + * + * @param array $array reference of flags array to add a value to + * @param mixed $value value to add to the flag array + * @access private + */ + function _add_flag(&$array, $value) + { + if (!is_array($array)) { + $array = array($value); + } elseif (!in_array($value, $array)) { + array_push($array, $value); + } + } + + // }}} + // {{{ quoteIdentifier() + + /** + * Quote a string so it can be safely used as a table / column name + * + * Quoting style depends on which database driver is being used. + * + * @param string $str identifier name to be quoted + * + * @return string quoted identifier string + * + * @since 1.6.0 + * @access public + */ + function quoteIdentifier($str) + { + return '[' . str_replace(']', ']]', $str) . ']'; + } + + // }}} + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> diff --git a/gulliver/thirdparty/pear/HTTP/HTTP.php b/gulliver/thirdparty/pear/HTTP/HTTP.php new file mode 100644 index 000000000..98af71fad --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/HTTP.php @@ -0,0 +1,343 @@ + | +// | Sterling Hughes | +// | Tomas V.V.Cox | +// | Richard Heyes | +// | Philippe Jausions | +// | Michael Wallner | +// +----------------------------------------------------------------------+ +// +// $Id: HTTP.php,v 1.35 2004/09/21 15:28:07 mike Exp $ + +/** + * HTTP + * + * HTTP utility functions + * + * @package HTTP + * @category HTTP + * @license PHP License + * @access public + * @version $Revision: 1.35 $ + */ +class HTTP +{ + /** + * Date + * + * Format a RFC compliant GMT date HTTP header. This function honors the + * "y2k_compliance" php.ini directive and formats the GMT date corresponding + * to either RFC850 or RFC822. + * + * @static + * @access public + * @return mixed GMT date string, or false for an invalid $time parameter + * @param mixed $time unix timestamp or date (default = current time) + */ + function Date($time = null) + { + if (!isset($time)) { + $time = time(); + } elseif (!is_numeric($time) && (-1 === $time = strtotime($time))) { + return false; + } + + // RFC822 or RFC850 + $format = ini_get('y2k_compliance') ? 'D, d M Y' : 'l, d-M-y'; + + return gmdate($format .' H:i:s \G\M\T', $time); + } + + /** + * Negotiate Language + * + * Negotiate language with the user's browser through the Accept-Language + * HTTP header or the user's host address. Language codes are generally in + * the form "ll" for a language spoken in only one country, or "ll-CC" for a + * language spoken in a particular country. For example, U.S. English is + * "en-US", while British English is "en-UK". Portugese as spoken in + * Portugal is "pt-PT", while Brazilian Portugese is "pt-BR". + * + * Quality factors in the Accept-Language: header are supported, e.g.: + * Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8 + * + * + * require_once 'HTTP.php'; + * $langs = array( + * 'en' => 'locales/en', + * 'en-US'=> 'locales/en', + * 'en-UK'=> 'locales/en', + * 'de' => 'locales/de', + * 'de-DE'=> 'locales/de', + * 'de-AT'=> 'locales/de', + * ); + * $neg = HTTP::negotiateLanguage($langs); + * $dir = $langs[$neg]; + * + * + * @static + * @access public + * @return string The negotiated language result or the supplied default. + * @param array $supported An associative array of supported languages, + * whose values must evaluate to true. + * @param string $default The default language to use if none is found. + */ + function negotiateLanguage($supported, $default = 'en-US') + { + $supp = array(); + foreach ($supported as $lang => $isSupported) { + if ($isSupported) { + $supp[strToLower($lang)] = $lang; + } + } + + if (!count($supp)) { + return $default; + } + + $matches = array(); + if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) { + @list($l, $q) = array_map('strtolower', + array_map('trim', explode(';', $lang))); + if (isset($supp[$l])) { + if (isset($q)) { + $matches[$l] = (float) str_replace('q=', '', $q); + } else { + $matches[$l] = 1000 - count($matches); + } + } + } + } + + if (count($matches)) { + asort($matches, SORT_NUMERIC); + return $supp[array_pop(array_keys($matches))]; + } + + if (isset($_SERVER['REMOTE_HOST'])) { + $lang = strtolower(array_pop(explode('.', $_SERVER['REMOTE_HOST']))); + if (isset($supp[$lang])) { + return $supp[$lang]; + } + } + + return $default; + } + + /** + * Head + * + * Sends a "HEAD" HTTP command to a server and returns the headers + * as an associative array. Example output could be: + * + * Array + * ( + * [response_code] => 200 // The HTTP response code + * [response] => HTTP/1.1 200 OK // The full HTTP response string + * [Date] => Fri, 11 Jan 2002 01:41:44 GMT + * [Server] => Apache/1.3.20 (Unix) PHP/4.1.1 + * [X-Powered-By] => PHP/4.1.1 + * [Connection] => close + * [Content-Type] => text/html + * ) + * + * + * @see HTTP_Client::head() + * @see HTTP_Request + * + * @static + * @access public + * @return mixed Returns associative array of response headers on success + * or PEAR error on failure. + * @param string $url A valid URL, e.g.: http://pear.php.net/credits.php + * @param integer $timeout Timeout in seconds (default = 10) + */ + function head($url, $timeout = 10) + { + $p = parse_url($url); + if (!isset($p['scheme'])) { + $p = parse_url(HTTP::absoluteURI($url)); + } elseif ($p['scheme'] != 'http') { + return HTTP::raiseError('Unsupported protocol: '. $p['scheme']); + } + + $port = isset($p['port']) ? $p['port'] : 80; + + if (!$fp = @fsockopen($p['host'], $port, $eno, $estr, $timeout)) { + return HTTP::raiseError("Connection error: $estr ($eno)"); + } + + $path = !empty($p['path']) ? $p['path'] : '/'; + $path .= !empty($p['query']) ? '?' . $p['query'] : ''; + + fputs($fp, "HEAD $path HTTP/1.0\r\n"); + fputs($fp, 'Host: ' . $p['host'] . ':' . $port . "\r\n"); + fputs($fp, "Connection: close\r\n\r\n"); + + $response = rtrim(fgets($fp, 4096)); + if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $response, $status)) { + $headers['response_code'] = $status[1]; + } + $headers['response'] = $response; + + while ($line = fgets($fp, 4096)) { + if (!trim($line)) { + break; + } + if (($pos = strpos($line, ':')) !== false) { + $header = substr($line, 0, $pos); + $value = trim(substr($line, $pos + 1)); + $headers[$header] = $value; + } + } + fclose($fp); + return $headers; + } + + /** + * Redirect + * + * This function redirects the client. This is done by issuing + * a "Location" header and exiting if wanted. If you set $rfc2616 to true + * HTTP will output a hypertext note with the location of the redirect. + * + * @static + * @access public + * @return mixed Returns true on succes (or exits) or false if headers + * have already been sent. + * @param string $url URL where the redirect should go to. + * @param bool $exit Whether to exit immediately after redirection. + * @param bool $rfc2616 Wheter to output a hypertext note where we're + * redirecting to (Redirecting to ....) + */ + function redirect($url, $exit = true, $rfc2616 = false) + { + if (headers_sent()) { + return false; + } + + $url = HTTP::absoluteURI($url); + header('Location: '. $url); + + if ($rfc2616 && @$_SERVER['REQUEST_METHOD'] != 'HEAD') { + printf('Redirecting to: %s.', $url, $url); + } + if ($exit) { + exit; + } + return true; + } + + /** + * Absolute URI + * + * This function returns the absolute URI for the partial URL passed. + * The current scheme (HTTP/HTTPS), host server, port, current script + * location are used if necessary to resolve any relative URLs. + * + * Offsets potentially created by PATH_INFO are taken care of to resolve + * relative URLs to the current script. + * + * You can choose a new protocol while resolving the URI. This is + * particularly useful when redirecting a web browser using relative URIs + * and to switch from HTTP to HTTPS, or vice-versa, at the same time. + * + * @author Philippe Jausions + * @static + * @access public + * @return string The absolute URI. + * @param string $url Absolute or relative URI the redirect should go to. + * @param string $protocol Protocol to use when redirecting URIs. + * @param integer $port A new port number. + */ + function absoluteURI($url = null, $protocol = null, $port = null) + { + // Mess around with already absolute URIs + if (preg_match('!^([a-z0-9]+)://!i', $url)) { + if (empty($protocol) && empty($port)) { + return $url; + } + if (!empty($protocol)) { + $url = $protocol .':'. array_pop(explode(':', $url, 2)); + } + if (!empty($port)) { + $url = preg_replace('!^(([a-z0-9]+)://[^/:]+)(:[\d]+)?!i', + '\1:'. $port, $url); + } + return $url; + } + + $host = 'localhost'; + if (!empty($_SERVER['HTTP_HOST'])) { + list($host) = explode(':', $_SERVER['HTTP_HOST']); + } elseif (!empty($_SERVER['SERVER_NAME'])) { + list($host) = explode(':', $_SERVER['SERVER_NAME']); + } + + if (empty($protocol)) { + $protocol = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + if (!isset($port) || $port != intval($port)) { + $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80; + } + } + + if ($protocol == 'http' && $port == 80) { + unset($port); + } + if ($protocol == 'https' && $port == 443) { + unset($port); + } + + $server = $protocol .'://'. $host . (isset($port) ? ':'. $port : ''); + + if (!strlen($url)) { + $url = isset($_SERVER['REQUEST_URI']) ? + $_SERVER['REQUEST_URI'] : $_SERVER['PHP_SELF']; + } + + if ($url{0} == '/') { + return $server . $url; + } + + // Check for PATH_INFO + if (isset($_SERVER['PATH_INFO'])) { + $path = dirname(substr($_SERVER['PHP_SELF'], 0, -strlen($_SERVER['PATH_INFO']))); + } else { + $path = dirname($_SERVER['PHP_SELF']); + } + + if (substr($path, -1) != '/') { + $path .= '/'; + } + + return $server . strtr($path, '\\', '/') . $url; + } + + /** + * Raise Error + * + * Lazy raising of PEAR_Errors. + * + * @static + * @access protected + * @return object PEAR_Error + * @param mixed $error + * @param int $code + */ + function raiseError($error = null, $code = null) + { + require_once 'PEAR.php'; + return PEAR::raiseError($error, $code); + } +} +?> diff --git a/gulliver/thirdparty/pear/HTTP/Request.php b/gulliver/thirdparty/pear/HTTP/Request.php new file mode 100644 index 000000000..64609e2b1 --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/Request.php @@ -0,0 +1,1191 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: Request.php 6820 2007-06-20 13:35:30Z kevin_fourie $ +// +// HTTP_Request Class +// +// Simple example, (Fetches yahoo.com and displays it): +// +// $a = &new HTTP_Request('http://www.yahoo.com/'); +// $a->sendRequest(); +// echo $a->getResponseBody(); +// + +require_once 'PEAR.php'; +require_once 'Net/Socket.php'; +require_once 'Net/URL.php'; + +define('HTTP_REQUEST_METHOD_GET', 'GET', true); +define('HTTP_REQUEST_METHOD_HEAD', 'HEAD', true); +define('HTTP_REQUEST_METHOD_POST', 'POST', true); +define('HTTP_REQUEST_METHOD_PUT', 'PUT', true); +define('HTTP_REQUEST_METHOD_DELETE', 'DELETE', true); +define('HTTP_REQUEST_METHOD_OPTIONS', 'OPTIONS', true); +define('HTTP_REQUEST_METHOD_TRACE', 'TRACE', true); + +define('HTTP_REQUEST_HTTP_VER_1_0', '1.0', true); +define('HTTP_REQUEST_HTTP_VER_1_1', '1.1', true); + +class HTTP_Request { + + /** + * Instance of Net_URL + * @var object Net_URL + */ + var $_url; + + /** + * Type of request + * @var string + */ + var $_method; + + /** + * HTTP Version + * @var string + */ + var $_http; + + /** + * Request headers + * @var array + */ + var $_requestHeaders; + + /** + * Basic Auth Username + * @var string + */ + var $_user; + + /** + * Basic Auth Password + * @var string + */ + var $_pass; + + /** + * Socket object + * @var object Net_Socket + */ + var $_sock; + + /** + * Proxy server + * @var string + */ + var $_proxy_host; + + /** + * Proxy port + * @var integer + */ + var $_proxy_port; + + /** + * Proxy username + * @var string + */ + var $_proxy_user; + + /** + * Proxy password + * @var string + */ + var $_proxy_pass; + + /** + * Post data + * @var array + */ + var $_postData; + + /** + * Request body + * @var string + */ + var $_body; + + /** + * A list of methods that MUST NOT have a request body, per RFC 2616 + * @var array + */ + var $_bodyDisallowed = array('TRACE'); + + /** + * Files to post + * @var array + */ + var $_postFiles = array(); + + /** + * Connection timeout. + * @var float + */ + var $_timeout; + + /** + * HTTP_Response object + * @var object HTTP_Response + */ + var $_response; + + /** + * Whether to allow redirects + * @var boolean + */ + var $_allowRedirects; + + /** + * Maximum redirects allowed + * @var integer + */ + var $_maxRedirects; + + /** + * Current number of redirects + * @var integer + */ + var $_redirects; + + /** + * Whether to append brackets [] to array variables + * @var bool + */ + var $_useBrackets = true; + + /** + * Attached listeners + * @var array + */ + var $_listeners = array(); + + /** + * Whether to save response body in response object property + * @var bool + */ + var $_saveBody = true; + + /** + * Timeout for reading from socket (array(seconds, microseconds)) + * @var array + */ + var $_readTimeout = null; + + /** + * Options to pass to Net_Socket::connect. See stream_context_create + * @var array + */ + var $_socketOptions = null; + + /** + * Constructor + * + * Sets up the object + * @param string The url to fetch/access + * @param array Associative array of parameters which can have the following keys: + *
      + *
    • method - Method to use, GET, POST etc (string)
    • + *
    • http - HTTP Version to use, 1.0 or 1.1 (string)
    • + *
    • user - Basic Auth username (string)
    • + *
    • pass - Basic Auth password (string)
    • + *
    • proxy_host - Proxy server host (string)
    • + *
    • proxy_port - Proxy server port (integer)
    • + *
    • proxy_user - Proxy auth username (string)
    • + *
    • proxy_pass - Proxy auth password (string)
    • + *
    • timeout - Connection timeout in seconds (float)
    • + *
    • allowRedirects - Whether to follow redirects or not (bool)
    • + *
    • maxRedirects - Max number of redirects to follow (integer)
    • + *
    • useBrackets - Whether to append [] to array variable names (bool)
    • + *
    • saveBody - Whether to save response body in response object property (bool)
    • + *
    • readTimeout - Timeout for reading / writing data over the socket (array (seconds, microseconds))
    • + *
    • socketOptions - Options to pass to Net_Socket object (array)
    • + *
    + * @access public + */ + function HTTP_Request($url = '', $params = array()) + { + $this->_sock = &new Net_Socket(); + $this->_method = HTTP_REQUEST_METHOD_GET; + $this->_http = HTTP_REQUEST_HTTP_VER_1_1; + $this->_requestHeaders = array(); + $this->_postData = array(); + $this->_body = null; + + $this->_user = null; + $this->_pass = null; + + $this->_proxy_host = null; + $this->_proxy_port = null; + $this->_proxy_user = null; + $this->_proxy_pass = null; + + $this->_allowRedirects = false; + $this->_maxRedirects = 3; + $this->_redirects = 0; + + $this->_timeout = null; + $this->_response = null; + + foreach ($params as $key => $value) { + $this->{'_' . $key} = $value; + } + + if (!empty($url)) { + $this->setURL($url); + } + + // Default useragent + $this->addHeader('User-Agent', 'PEAR HTTP_Request class ( http://pear.php.net/ )'); + + // Make sure keepalives dont knobble us + $this->addHeader('Connection', 'close'); + + // Basic authentication + if (!empty($this->_user)) { + $this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass)); + } + + // Use gzip encoding if possible + // Avoid gzip encoding if using multibyte functions (see #1781) + if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && extension_loaded('zlib') && + 0 == (2 & ini_get('mbstring.func_overload'))) { + + $this->addHeader('Accept-Encoding', 'gzip'); + } + } + + /** + * Generates a Host header for HTTP/1.1 requests + * + * @access private + * @return string + */ + function _generateHostHeader() + { + if ($this->_url->port != 80 AND strcasecmp($this->_url->protocol, 'http') == 0) { + $host = $this->_url->host . ':' . $this->_url->port; + + } elseif ($this->_url->port != 443 AND strcasecmp($this->_url->protocol, 'https') == 0) { + $host = $this->_url->host . ':' . $this->_url->port; + + } elseif ($this->_url->port == 443 AND strcasecmp($this->_url->protocol, 'https') == 0 AND strpos($this->_url->url, ':443') !== false) { + $host = $this->_url->host . ':' . $this->_url->port; + + } else { + $host = $this->_url->host; + } + + return $host; + } + + /** + * Resets the object to its initial state (DEPRECATED). + * Takes the same parameters as the constructor. + * + * @param string $url The url to be requested + * @param array $params Associative array of parameters + * (see constructor for details) + * @access public + * @deprecated deprecated since 1.2, call the constructor if this is necessary + */ + function reset($url, $params = array()) + { + $this->HTTP_Request($url, $params); + } + + /** + * Sets the URL to be requested + * + * @param string The url to be requested + * @access public + */ + function setURL($url) + { + $this->_url = &new Net_URL($url, $this->_useBrackets); + + if (!empty($this->_url->user) || !empty($this->_url->pass)) { + $this->setBasicAuth($this->_url->user, $this->_url->pass); + } + + if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http) { + $this->addHeader('Host', $this->_generateHostHeader()); + } + } + + /** + * Sets a proxy to be used + * + * @param string Proxy host + * @param int Proxy port + * @param string Proxy username + * @param string Proxy password + * @access public + */ + function setProxy($host, $port = 8080, $user = null, $pass = null) + { + $this->_proxy_host = $host; + $this->_proxy_port = $port; + $this->_proxy_user = $user; + $this->_proxy_pass = $pass; + + if (!empty($user)) { + $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); + } + } + + /** + * Sets basic authentication parameters + * + * @param string Username + * @param string Password + */ + function setBasicAuth($user, $pass) + { + $this->_user = $user; + $this->_pass = $pass; + + $this->addHeader('Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); + } + + /** + * Sets the method to be used, GET, POST etc. + * + * @param string Method to use. Use the defined constants for this + * @access public + */ + function setMethod($method) + { + $this->_method = $method; + } + + /** + * Sets the HTTP version to use, 1.0 or 1.1 + * + * @param string Version to use. Use the defined constants for this + * @access public + */ + function setHttpVer($http) + { + $this->_http = $http; + } + + /** + * Adds a request header + * + * @param string Header name + * @param string Header value + * @access public + */ + function addHeader($name, $value) + { + $this->_requestHeaders[strtolower($name)] = $value; + } + + /** + * Removes a request header + * + * @param string Header name to remove + * @access public + */ + function removeHeader($name) + { + if (isset($this->_requestHeaders[strtolower($name)])) { + unset($this->_requestHeaders[strtolower($name)]); + } + } + + /** + * Adds a querystring parameter + * + * @param string Querystring parameter name + * @param string Querystring parameter value + * @param bool Whether the value is already urlencoded or not, default = not + * @access public + */ + function addQueryString($name, $value, $preencoded = false) + { + $this->_url->addQueryString($name, $value, $preencoded); + } + + /** + * Sets the querystring to literally what you supply + * + * @param string The querystring data. Should be of the format foo=bar&x=y etc + * @param bool Whether data is already urlencoded or not, default = already encoded + * @access public + */ + function addRawQueryString($querystring, $preencoded = true) + { + $this->_url->addRawQueryString($querystring, $preencoded); + } + + /** + * Adds postdata items + * + * @param string Post data name + * @param string Post data value + * @param bool Whether data is already urlencoded or not, default = not + * @access public + */ + function addPostData($name, $value, $preencoded = false) + { + if ($preencoded) { + $this->_postData[$name] = $value; + } else { + $this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value); + } + } + + /** + * Recursively applies the callback function to the value + * + * @param mixed Callback function + * @param mixed Value to process + * @access private + * @return mixed Processed value + */ + function _arrayMapRecursive($callback, $value) + { + if (!is_array($value)) { + return call_user_func($callback, $value); + } else { + $map = array(); + foreach ($value as $k => $v) { + $map[$k] = $this->_arrayMapRecursive($callback, $v); + } + return $map; + } + } + + /** + * Adds a file to upload + * + * This also changes content-type to 'multipart/form-data' for proper upload + * + * @access public + * @param string name of file-upload field + * @param mixed file name(s) + * @param mixed content-type(s) of file(s) being uploaded + * @return bool true on success + * @throws PEAR_Error + */ + function addFile($inputName, $fileName, $contentType = 'application/octet-stream') + { + if (!is_array($fileName) && !is_readable($fileName)) { + return PEAR::raiseError("File '{$fileName}' is not readable"); + } elseif (is_array($fileName)) { + foreach ($fileName as $name) { + if (!is_readable($name)) { + return PEAR::raiseError("File '{$name}' is not readable"); + } + } + } + $this->addHeader('Content-Type', 'multipart/form-data'); + $this->_postFiles[$inputName] = array( + 'name' => $fileName, + 'type' => $contentType + ); + return true; + } + + /** + * Adds raw postdata (DEPRECATED) + * + * @param string The data + * @param bool Whether data is preencoded or not, default = already encoded + * @access public + * @deprecated deprecated since 1.3.0, method addBody() should be used instead + */ + function addRawPostData($postdata, $preencoded = true) + { + $this->_body = $preencoded ? $postdata : urlencode($postdata); + } + + /** + * Sets the request body (for POST, PUT and similar requests) + * + * @param string Request body + * @access public + */ + function setBody($body) + { + $this->_body = $body; + } + + /** + * Clears any postdata that has been added (DEPRECATED). + * + * Useful for multiple request scenarios. + * + * @access public + * @deprecated deprecated since 1.2 + */ + function clearPostData() + { + $this->_postData = null; + } + + /** + * Appends a cookie to "Cookie:" header + * + * @param string $name cookie name + * @param string $value cookie value + * @access public + */ + function addCookie($name, $value) + { + $cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : ''; + $this->addHeader('Cookie', $cookies . $name . '=' . $value); + } + + /** + * Clears any cookies that have been added (DEPRECATED). + * + * Useful for multiple request scenarios + * + * @access public + * @deprecated deprecated since 1.2 + */ + function clearCookies() + { + $this->removeHeader('Cookie'); + } + + /** + * Sends the request + * + * @access public + * @param bool Whether to store response body in Response object property, + * set this to false if downloading a LARGE file and using a Listener + * @return mixed PEAR error on error, true otherwise + */ + function sendRequest($saveBody = true) + { + if (!is_a($this->_url, 'Net_URL')) { + return PEAR::raiseError('No URL given.'); + } + + $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host; + $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port; + + // 4.3.0 supports SSL connections using OpenSSL. The function test determines + // we running on at least 4.3.0 + if (strcasecmp($this->_url->protocol, 'https') == 0 AND function_exists('file_get_contents') AND extension_loaded('openssl')) { + if (isset($this->_proxy_host)) { + return PEAR::raiseError('HTTPS proxies are not supported.'); + } + $host = 'ssl://' . $host; + } + + // magic quotes may fuck up file uploads and chunked response processing + $magicQuotes = ini_get('magic_quotes_runtime'); + ini_set('magic_quotes_runtime', false); + + // If this is a second request, we may get away without + // re-connecting if they're on the same server + $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions); + PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest()); + + if (!PEAR::isError($err)) { + if (!empty($this->_readTimeout)) { + $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]); + } + + $this->_notify('sentRequest'); + + // Read the response + $this->_response = &new HTTP_Response($this->_sock, $this->_listeners); + $err = $this->_response->process($this->_saveBody && $saveBody); + } + + ini_set('magic_quotes_runtime', $magicQuotes); + + if (PEAR::isError($err)) { + return $err; + } + + + // Check for redirection + if ( $this->_allowRedirects + AND $this->_redirects <= $this->_maxRedirects + AND $this->getResponseCode() > 300 + AND $this->getResponseCode() < 399 + AND !empty($this->_response->_headers['location'])) { + + + $redirect = $this->_response->_headers['location']; + + // Absolute URL + if (preg_match('/^https?:\/\//i', $redirect)) { + $this->_url = &new Net_URL($redirect); + $this->addHeader('Host', $this->_generateHostHeader()); + // Absolute path + } elseif ($redirect{0} == '/') { + $this->_url->path = $redirect; + + // Relative path + } elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') { + if (substr($this->_url->path, -1) == '/') { + $redirect = $this->_url->path . $redirect; + } else { + $redirect = dirname($this->_url->path) . '/' . $redirect; + } + $redirect = Net_URL::resolvePath($redirect); + $this->_url->path = $redirect; + + // Filename, no path + } else { + if (substr($this->_url->path, -1) == '/') { + $redirect = $this->_url->path . $redirect; + } else { + $redirect = dirname($this->_url->path) . '/' . $redirect; + } + $this->_url->path = $redirect; + } + + $this->_redirects++; + return $this->sendRequest($saveBody); + + // Too many redirects + } elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) { + return PEAR::raiseError('Too many redirects'); + } + + $this->_sock->disconnect(); + + return true; + } + + /** + * Returns the response code + * + * @access public + * @return mixed Response code, false if not set + */ + function getResponseCode() + { + return isset($this->_response->_code) ? $this->_response->_code : false; + } + + /** + * Returns either the named header or all if no name given + * + * @access public + * @param string The header name to return, do not set to get all headers + * @return mixed either the value of $headername (false if header is not present) + * or an array of all headers + */ + function getResponseHeader($headername = null) + { + if (!isset($headername)) { + return isset($this->_response->_headers)? $this->_response->_headers: array(); + } else { + $headername = strtolower($headername); + return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false; + } + } + + /** + * Returns the body of the response + * + * @access public + * @return mixed response body, false if not set + */ + function getResponseBody() + { + return isset($this->_response->_body) ? $this->_response->_body : false; + } + + /** + * Returns cookies set in response + * + * @access public + * @return mixed array of response cookies, false if none are present + */ + function getResponseCookies() + { + return isset($this->_response->_cookies) ? $this->_response->_cookies : false; + } + + /** + * Builds the request string + * + * @access private + * @return string The request string + */ + function _buildRequest() + { + $separator = ini_get('arg_separator.output'); + ini_set('arg_separator.output', '&'); + $querystring = ($querystring = $this->_url->getQueryString()) ? '?' . $querystring : ''; + ini_set('arg_separator.output', $separator); + + $host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : ''; + $port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : ''; + $path = (empty($this->_url->path)? '/': $this->_url->path) . $querystring; + $url = $host . $port . $path; + + $request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n"; + + if (in_array($this->_method, $this->_bodyDisallowed) || + (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body)) || + (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_postData) && empty($this->_postFiles))) { + + $this->removeHeader('Content-Type'); + } else { + if (empty($this->_requestHeaders['content-type'])) { + // Add default content-type + $this->addHeader('Content-Type', 'application/x-www-form-urlencoded'); + } elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) { + $boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime()); + $this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary); + } + } + + // Request Headers + if (!empty($this->_requestHeaders)) { + foreach ($this->_requestHeaders as $name => $value) { + $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); + $request .= $canonicalName . ': ' . $value . "\r\n"; + } + } + + // No post data or wrong method, so simply add a final CRLF + if (in_array($this->_method, $this->_bodyDisallowed) || + (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body))) { + + $request .= "\r\n"; + + // Post data if it's an array + } elseif (HTTP_REQUEST_METHOD_POST == $this->_method && + (!empty($this->_postData) || !empty($this->_postFiles))) { + + // "normal" POST request + if (!isset($boundary)) { + $postdata = implode('&', array_map( + create_function('$a', 'return $a[0] . \'=\' . $a[1];'), + $this->_flattenArray('', $this->_postData) + )); + + // multipart request, probably with file uploads + } else { + $postdata = ''; + if (!empty($this->_postData)) { + $flatData = $this->_flattenArray('', $this->_postData); + foreach ($flatData as $item) { + $postdata .= '--' . $boundary . "\r\n"; + $postdata .= 'Content-Disposition: form-data; name="' . $item[0] . '"'; + $postdata .= "\r\n\r\n" . urldecode($item[1]) . "\r\n"; + } + } + foreach ($this->_postFiles as $name => $value) { + if (is_array($value['name'])) { + $varname = $name . ($this->_useBrackets? '[]': ''); + } else { + $varname = $name; + $value['name'] = array($value['name']); + } + foreach ($value['name'] as $key => $filename) { + $fp = fopen($filename, 'r'); + $data = fread($fp, filesize($filename)); + fclose($fp); + $basename = basename($filename); + $type = is_array($value['type'])? @$value['type'][$key]: $value['type']; + + $postdata .= '--' . $boundary . "\r\n"; + $postdata .= 'Content-Disposition: form-data; name="' . $varname . '"; filename="' . $basename . '"'; + $postdata .= "\r\nContent-Type: " . $type; + $postdata .= "\r\n\r\n" . $data . "\r\n"; + } + } + $postdata .= '--' . $boundary . "--\r\n"; + } + $request .= 'Content-Length: ' . strlen($postdata) . "\r\n\r\n"; + $request .= $postdata; + + // Explicitly set request body + } elseif (!empty($this->_body)) { + + $request .= 'Content-Length: ' . strlen($this->_body) . "\r\n\r\n"; + $request .= $this->_body; + } + + return $request; + } + + /** + * Helper function to change the (probably multidimensional) associative array + * into the simple one. + * + * @param string name for item + * @param mixed item's values + * @return array array with the following items: array('item name', 'item value'); + */ + function _flattenArray($name, $values) + { + if (!is_array($values)) { + return array(array($name, $values)); + } else { + $ret = array(); + foreach ($values as $k => $v) { + if (empty($name)) { + $newName = $k; + } elseif ($this->_useBrackets) { + $newName = $name . '[' . $k . ']'; + } else { + $newName = $name; + } + $ret = array_merge($ret, $this->_flattenArray($newName, $v)); + } + return $ret; + } + } + + + /** + * Adds a Listener to the list of listeners that are notified of + * the object's events + * + * @param object HTTP_Request_Listener instance to attach + * @return boolean whether the listener was successfully attached + * @access public + */ + function attach(&$listener) + { + if (!is_a($listener, 'HTTP_Request_Listener')) { + return false; + } + $this->_listeners[$listener->getId()] =& $listener; + return true; + } + + + /** + * Removes a Listener from the list of listeners + * + * @param object HTTP_Request_Listener instance to detach + * @return boolean whether the listener was successfully detached + * @access public + */ + function detach(&$listener) + { + if (!is_a($listener, 'HTTP_Request_Listener') || + !isset($this->_listeners[$listener->getId()])) { + return false; + } + unset($this->_listeners[$listener->getId()]); + return true; + } + + + /** + * Notifies all registered listeners of an event. + * + * Events sent by HTTP_Request object + * 'sentRequest': after the request was sent + * Events sent by HTTP_Response object + * 'gotHeaders': after receiving response headers (headers are passed in $data) + * 'tick': on receiving a part of response body (the part is passed in $data) + * 'gzTick': on receiving a gzip-encoded part of response body (ditto) + * 'gotBody': after receiving the response body (passes the decoded body in $data if it was gzipped) + * + * @param string Event name + * @param mixed Additional data + * @access private + */ + function _notify($event, $data = null) + { + foreach (array_keys($this->_listeners) as $id) { + $this->_listeners[$id]->update($this, $event, $data); + } + } +} + + +/** +* Response class to complement the Request class +*/ +class HTTP_Response +{ + /** + * Socket object + * @var object + */ + var $_sock; + + /** + * Protocol + * @var string + */ + var $_protocol; + + /** + * Return code + * @var string + */ + var $_code; + + /** + * Response headers + * @var array + */ + var $_headers; + + /** + * Cookies set in response + * @var array + */ + var $_cookies; + + /** + * Response body + * @var string + */ + var $_body = ''; + + /** + * Used by _readChunked(): remaining length of the current chunk + * @var string + */ + var $_chunkLength = 0; + + /** + * Attached listeners + * @var array + */ + var $_listeners = array(); + + /** + * Constructor + * + * @param object Net_Socket socket to read the response from + * @param array listeners attached to request + * @return mixed PEAR Error on error, true otherwise + */ + function HTTP_Response(&$sock, &$listeners) + { + $this->_sock =& $sock; + $this->_listeners =& $listeners; + } + + + /** + * Processes a HTTP response + * + * This extracts response code, headers, cookies and decodes body if it + * was encoded in some way + * + * @access public + * @param bool Whether to store response body in object property, set + * this to false if downloading a LARGE file and using a Listener. + * This is assumed to be true if body is gzip-encoded. + * @throws PEAR_Error + * @return mixed true on success, PEAR_Error in case of malformed response + */ + function process($saveBody = true) + { + do { + $line = $this->_sock->readLine(); + if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) { + return PEAR::raiseError('Malformed response.'); + } else { + $this->_protocol = 'HTTP/' . $http_version; + $this->_code = intval($returncode); + } + while ('' !== ($header = $this->_sock->readLine())) { + $this->_processHeader($header); + } + } while (100 == $this->_code); + + $this->_notify('gotHeaders', $this->_headers); + + // If response body is present, read it and decode + $chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']); + $gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']); + $hasBody = false; + if (!isset($this->_headers['content-length']) || 0 != $this->_headers['content-length']) { + while (!$this->_sock->eof()) { + if ($chunked) { + $data = $this->_readChunked(); + } else { + $data = $this->_sock->read(4096); + } + if ('' == $data) { + break; + } else { + $hasBody = true; + if ($saveBody || $gzipped) { + $this->_body .= $data; + } + $this->_notify($gzipped? 'gzTick': 'tick', $data); + } + } + } + if ($hasBody) { + // Uncompress the body if needed + if ($gzipped) { + $this->_body = gzinflate(substr($this->_body, 10)); + $this->_notify('gotBody', $this->_body); + } else { + $this->_notify('gotBody'); + } + } + return true; + } + + + /** + * Processes the response header + * + * @access private + * @param string HTTP header + */ + function _processHeader($header) + { + list($headername, $headervalue) = explode(':', $header, 2); + $headername = strtolower($headername); + $headervalue = ltrim($headervalue); + + if ('set-cookie' != $headername) { + if (isset($this->_headers[$headername])) { + $this->_headers[$headername] .= ',' . $headervalue; + } else { + $this->_headers[$headername] = $headervalue; + } + } else { + $this->_parseCookie($headervalue); + } + } + + + /** + * Parse a Set-Cookie header to fill $_cookies array + * + * @access private + * @param string value of Set-Cookie header + */ + function _parseCookie($headervalue) + { + $cookie = array( + 'expires' => null, + 'domain' => null, + 'path' => null, + 'secure' => false + ); + + // Only a name=value pair + if (!strpos($headervalue, ';')) { + $pos = strpos($headervalue, '='); + $cookie['name'] = trim(substr($headervalue, 0, $pos)); + $cookie['value'] = trim(substr($headervalue, $pos + 1)); + + // Some optional parameters are supplied + } else { + $elements = explode(';', $headervalue); + $pos = strpos($elements[0], '='); + $cookie['name'] = trim(substr($elements[0], 0, $pos)); + $cookie['value'] = trim(substr($elements[0], $pos + 1)); + + for ($i = 1; $i < count($elements); $i++) { + if (false === strpos($elements[$i], '=')) { + $elName = trim($elements[$i]); + $elValue = null; + } else { + list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); + } + $elName = strtolower($elName); + if ('secure' == $elName) { + $cookie['secure'] = true; + } elseif ('expires' == $elName) { + $cookie['expires'] = str_replace('"', '', $elValue); + } elseif ('path' == $elName || 'domain' == $elName) { + $cookie[$elName] = urldecode($elValue); + } else { + $cookie[$elName] = $elValue; + } + } + } + $this->_cookies[] = $cookie; + } + + + /** + * Read a part of response body encoded with chunked Transfer-Encoding + * + * @access private + * @return string + */ + function _readChunked() + { + // at start of the next chunk? + if (0 == $this->_chunkLength) { + $line = $this->_sock->readLine(); + if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) { + $this->_chunkLength = hexdec($matches[1]); + // Chunk with zero length indicates the end + if (0 == $this->_chunkLength) { + $this->_sock->readLine(); // make this an eof() + return ''; + } + } else { + return ''; + } + } + $data = $this->_sock->read($this->_chunkLength); + $this->_chunkLength -= strlen($data); + if (0 == $this->_chunkLength) { + $this->_sock->readLine(); // Trailing CRLF + } + return $data; + } + + + /** + * Notifies all registered listeners of an event. + * + * @param string Event name + * @param mixed Additional data + * @access private + * @see HTTP_Request::_notify() + */ + function _notify($event, $data = null) + { + foreach (array_keys($this->_listeners) as $id) { + $this->_listeners[$id]->update($this, $event, $data); + } + } +} // End class HTTP_Response +?> diff --git a/gulliver/thirdparty/pear/HTTP/WebDAV/Server.php b/gulliver/thirdparty/pear/HTTP/WebDAV/Server.php new file mode 100644 index 000000000..aca232d7a --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/WebDAV/Server.php @@ -0,0 +1,2000 @@ + | +// | Christian Stocker | +// +----------------------------------------------------------------------+ +// +// $Id: Server.php,v 1.46 2006/03/03 21:43:09 hholzgra Exp $ +// +require_once "HTTP/WebDAV/Tools/_parse_propfind.php"; +require_once "HTTP/WebDAV/Tools/_parse_proppatch.php"; +require_once "HTTP/WebDAV/Tools/_parse_lockinfo.php"; + + + +/** + * Virtual base class for implementing WebDAV servers + * + * WebDAV server base class, needs to be extended to do useful work + * + * @package HTTP_WebDAV_Server + * @author Hartmut Holzgraefe + * @version 0.99.1dev + */ +class HTTP_WebDAV_Server +{ + // {{{ Member Variables + + /** + * complete URI for this request + * + * @var string + */ + var $uri; + + + /** + * base URI for this request + * + * @var string + */ + var $base_uri; + + + /** + * URI path for this request + * + * @var string + */ + var $path; + + /** + * Realm string to be used in authentification popups + * + * @var string + */ + var $http_auth_realm = "PHP WebDAV"; + + /** + * String to be used in "X-Dav-Powered-By" header + * + * @var string + */ + var $dav_powered_by = ""; + + /** + * Remember parsed If: (RFC2518/9.4) header conditions + * + * @var array + */ + var $_if_header_uris = array(); + + /** + * HTTP response status/message + * + * @var string + */ + var $_http_status = "200 OK"; + + /** + * encoding of property values passed in + * + * @var string + */ + var $_prop_encoding = "utf-8"; + + // }}} + + // {{{ Constructor + + /** + * Constructor + * + * @param void + */ + function HTTP_WebDAV_Server() + { + // PHP messages destroy XML output -> switch them off + ini_set("display_errors", 0); + } + + // }}} + + // {{{ ServeRequest() + /** + * Serve WebDAV HTTP request + * + * dispatch WebDAV HTTP request to the apropriate method handler + * + * @param void + * @return void + */ + function ServeRequest() + { + // prevent warning in litmus check 'delete_fragment' + if (strstr($_SERVER["REQUEST_URI"], '#')) { + $this->http_status("400 Bad Request"); + return; + } + + // default uri is the complete request uri + $uri = (@$_SERVER["HTTPS"] === "on" ? "https:" : "http:"); + $uri.= "//$_SERVER[HTTP_HOST]$_SERVER[SCRIPT_NAME]"; + + $path_info = empty($_SERVER["PATH_INFO"]) ? "/" : $_SERVER["PATH_INFO"]; + + $this->base_uri = $uri; + $this->uri = $uri . $path_info; + + $requestUri = $_SERVER['REQUEST_URI']; + if ( substr ( $requestUri, -1 ) == '/' ) $requestUri = substr ( $requestUri, 0, strlen ($requestUri) -1 ); + $paths = explode ( '/', $requestUri ); + array_shift ( $paths ); + array_shift ( $paths ); + array_shift ( $paths ); + array_shift ( $paths ); + array_shift ( $paths ); + array_shift ( $paths ); + $this->paths = $paths; + + // set path + //$this->path = $this->_urldecode($path_info); + $this->path = implode ('/', $paths ); + + if (!strlen($this->path)) { + if ($_SERVER["REQUEST_METHOD"] == "GET") { + // redirect clients that try to GET a collection + // WebDAV clients should never try this while + // regular HTTP clients might ... + header("Location: ".$this->base_uri."/"); + return; + } else { + // if a WebDAV client didn't give a path we just assume '/' + $this->path = "/"; + } + } + + if(ini_get("magic_quotes_gpc")) { + $this->path = stripslashes($this->path); + } + + + // identify ourselves + if (empty($this->dav_powered_by)) { + header("X-Dav-Powered-By: PHP class: ".get_class($this)); + } else { + header("X-Dav-Powered-By: ".$this->dav_powered_by ); + } + + // check authentication + // for the motivation for not checking OPTIONS requests on / see + // http://pear.php.net/bugs/bug.php?id=5363 + if ( ( !(($_SERVER['REQUEST_METHOD'] == 'OPTIONS') && ($this->path == "/"))) + && (!$this->_check_auth())) { + // RFC2518 says we must use Digest instead of Basic + // but Microsoft Clients do not support Digest + // and we don't support NTLM and Kerberos + // so we are stuck with Basic here + header('WWW-Authenticate: Basic realm="'.($this->http_auth_realm).'"'); + + // Windows seems to require this being the last header sent + // (changed according to PECL bug #3138) + $this->http_status('401 Unauthorized'); + + return; + } + + // check + if(! $this->_check_if_header_conditions()) { + return; + } + + // detect requested method names + $method = strtolower($_SERVER["REQUEST_METHOD"]); + $wrapper = "http_".$method; + + // activate HEAD emulation by GET if no HEAD method found + if ($method == "head" && !method_exists($this, "head")) { + $method = "get"; + } + + if (method_exists($this, $wrapper) && ($method == "options" || method_exists($this, $method))) { + $this->$wrapper(); // call method by name + } else { // method not found/implemented + if ($_SERVER["REQUEST_METHOD"] == "LOCK") { + $this->http_status("412 Precondition failed"); + } else { + $this->http_status("405 Method not allowed"); + header("Allow: ".join(", ", $this->_allow())); // tell client what's allowed + } + } + } + + // }}} + + // {{{ abstract WebDAV methods + + // {{{ GET() + /** + * GET implementation + * + * overload this method to retrieve resources from your server + *
    + * + * + * @abstract + * @param array &$params Array of input and output parameters + *
    input
      + *
    • path - + *
    + *
    output
      + *
    • size - + *
    + * @returns int HTTP-Statuscode + */ + + /* abstract + function GET(&$params) + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ PUT() + /** + * PUT implementation + * + * PUT implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function PUT() + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ COPY() + + /** + * COPY implementation + * + * COPY implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function COPY() + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ MOVE() + + /** + * MOVE implementation + * + * MOVE implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function MOVE() + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ DELETE() + + /** + * DELETE implementation + * + * DELETE implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function DELETE() + { + // dummy entry for PHPDoc + } + */ + // }}} + + // {{{ PROPFIND() + + /** + * PROPFIND implementation + * + * PROPFIND implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function PROPFIND() + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ PROPPATCH() + + /** + * PROPPATCH implementation + * + * PROPPATCH implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function PROPPATCH() + { + // dummy entry for PHPDoc + } + */ + // }}} + + // {{{ LOCK() + + /** + * LOCK implementation + * + * LOCK implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function LOCK() + { + // dummy entry for PHPDoc + } + */ + // }}} + + // {{{ UNLOCK() + + /** + * UNLOCK implementation + * + * UNLOCK implementation + * + * @abstract + * @param array &$params + * @returns int HTTP-Statuscode + */ + + /* abstract + function UNLOCK() + { + // dummy entry for PHPDoc + } + */ + // }}} + + // }}} + + // {{{ other abstract methods + + // {{{ check_auth() + + /** + * check authentication + * + * overload this method to retrieve and confirm authentication information + * + * @abstract + * @param string type Authentication type, e.g. "basic" or "digest" + * @param string username Transmitted username + * @param string passwort Transmitted password + * @returns bool Authentication status + */ + + /* abstract + function checkAuth($type, $username, $password) + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // {{{ checklock() + + /** + * check lock status for a resource + * + * overload this method to return shared and exclusive locks + * active for this resource + * + * @abstract + * @param string resource Resource path to check + * @returns array An array of lock entries each consisting + * of 'type' ('shared'/'exclusive'), 'token' and 'timeout' + */ + + /* abstract + function checklock($resource) + { + // dummy entry for PHPDoc + } + */ + + // }}} + + // }}} + + // {{{ WebDAV HTTP method wrappers + + // {{{ http_OPTIONS() + + /** + * OPTIONS method handler + * + * The OPTIONS method handler creates a valid OPTIONS reply + * including Dav: and Allowed: heaers + * based on the implemented methods found in the actual instance + * + * @param void + * @return void + */ + function http_OPTIONS() + { + // Microsoft clients default to the Frontpage protocol + // unless we tell them to use WebDAV + header("MS-Author-Via: DAV"); + + // get allowed methods + $allow = $this->_allow(); + + // dav header + $dav = array(1); // assume we are always dav class 1 compliant + if (isset($allow['LOCK'])) { + $dav[] = 2; // dav class 2 requires that locking is supported + } + + // tell clients what we found + $this->http_status("200 OK"); + header("DAV: " .join("," , $dav)); + header("Allow: ".join(", ", $allow)); + + header("Content-length: 0"); + } + + // }}} + + + // {{{ http_PROPFIND() + + /** + * PROPFIND method handler + * + * @param void + * @return void + */ + function http_PROPFIND() + { + $options = Array(); + $options["path"] = $this->path; + + // search depth from header (default is "infinity) + if (isset($_SERVER['HTTP_DEPTH'])) { + $options["depth"] = $_SERVER["HTTP_DEPTH"]; + } else { + $options["depth"] = "infinity"; + } + + // analyze request payload + $propinfo = new _parse_propfind("php://input"); + if (!$propinfo->success) { + $this->http_status("400 Error"); + return; + } + $options['props'] = $propinfo->props; + + // call user handler + if (!$this->PROPFIND($options, $files)) { + $this->http_status("404 Not Found"); + return; + } + + // collect namespaces here + $ns_hash = array(); + + // Microsoft Clients need this special namespace for date and time values + $ns_defs = "xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\""; + + // now we loop over all returned file entries + foreach($files["files"] as $filekey => $file) { + + // nothing to do if no properties were returend for a file + if (!isset($file["props"]) || !is_array($file["props"])) { + continue; + } + + // now loop over all returned properties + foreach($file["props"] as $key => $prop) { + // as a convenience feature we do not require that user handlers + // restrict returned properties to the requested ones + // here we strip all unrequested entries out of the response + + switch($options['props']) { + case "all": + // nothing to remove + break; + + case "names": + // only the names of all existing properties were requested + // so we remove all values + unset($files["files"][$filekey]["props"][$key]["val"]); + break; + + default: + $found = false; + + // search property name in requested properties + foreach((array)$options["props"] as $reqprop) { + if ( $reqprop["name"] == $prop["name"] + && @$reqprop["xmlns"] == $prop["ns"]) { + $found = true; + break; + } + } + + // unset property and continue with next one if not found/requested + if (!$found) { + $files["files"][$filekey]["props"][$key]=""; + continue(2); + } + break; + } + + // namespace handling + if (empty($prop["ns"])) continue; // no namespace + $ns = $prop["ns"]; + if ($ns == "DAV:") continue; // default namespace + if (isset($ns_hash[$ns])) continue; // already known + + // register namespace + $ns_name = "ns".(count($ns_hash) + 1); + $ns_hash[$ns] = $ns_name; + $ns_defs .= " xmlns:$ns_name=\"$ns\""; + } + + // we also need to add empty entries for properties that were requested + // but for which no values where returned by the user handler + if (is_array($options['props'])) { + foreach($options["props"] as $reqprop) { + if($reqprop['name']=="") continue; // skip empty entries + + $found = false; + + // check if property exists in result + foreach($file["props"] as $prop) { + if ( $reqprop["name"] == $prop["name"] + && @$reqprop["xmlns"] == $prop["ns"]) { + $found = true; + break; + } + } + + if (!$found) { + if($reqprop["xmlns"]==="DAV:" && $reqprop["name"]==="lockdiscovery") { + // lockdiscovery is handled by the base class + $files["files"][$filekey]["props"][] + = $this->mkprop("DAV:", + "lockdiscovery" , + $this->lockdiscovery($files["files"][$filekey]['path'])); + } else { + // add empty value for this property + $files["files"][$filekey]["noprops"][] = + $this->mkprop($reqprop["xmlns"], $reqprop["name"], ""); + + // register property namespace if not known yet + if ($reqprop["xmlns"] != "DAV:" && !isset($ns_hash[$reqprop["xmlns"]])) { + $ns_name = "ns".(count($ns_hash) + 1); + $ns_hash[$reqprop["xmlns"]] = $ns_name; + $ns_defs .= " xmlns:$ns_name=\"$reqprop[xmlns]\""; + } + } + } + } + } + } + + // now we generate the reply header ... + $this->http_status("207 Multi-Status"); + header('Content-Type: text/xml; charset="utf-8"'); + + // ... and payload + echo "\n"; + echo "\n"; + + foreach($files["files"] as $file) { + // ignore empty or incomplete entries + if(!is_array($file) || empty($file) || !isset($file["path"])) continue; + $path = $file['path']; + if(!is_string($path) || $path==="") continue; + + echo " \n"; + + /* TODO right now the user implementation has to make sure + collections end in a slash, this should be done in here + by checking the resource attribute */ + //$href = $this->_mergePathes($_SERVER['SCRIPT_NAME'], $path); + $href = $this->_mergePathes($this->uriBase, $path); + + echo " $href\n"; + + // report all found properties and their values (if any) + if (isset($file["props"]) && is_array($file["props"])) { + echo " \n"; + echo " \n"; + + foreach($file["props"] as $key => $prop) { + + if (!is_array($prop)) continue; + if (!isset($prop["name"])) continue; + + if (!isset($prop["val"]) || $prop["val"] === "" || $prop["val"] === false) { + // empty properties (cannot use empty() for check as "0" is a legal value here) + if($prop["ns"]=="DAV:") { + echo " \n"; + } else if(!empty($prop["ns"])) { + echo " <".$ns_hash[$prop["ns"]].":$prop[name]/>\n"; + } else { + echo " <$prop[name] xmlns=\"\"/>"; + } + } else if ($prop["ns"] == "DAV:") { + // some WebDAV properties need special treatment + switch ($prop["name"]) { + case "creationdate": + echo " " + . gmdate("Y-m-d\\TH:i:s\\Z",$prop['val']) + . "\n"; + break; + case "getlastmodified": + echo " " + . gmdate("D, d M Y H:i:s ", $prop['val']) + . "GMT\n"; + break; + case "lastaccessed": + echo " " + . gmdate("D, d M Y H:i:s ", $prop['val']) + . "GMT\n"; + break; + case "resourcetype": + echo " \n"; + break; + case "supportedlock": + echo " $prop[val]\n"; + break; + case "lockdiscovery": + echo " \n"; + echo $prop["val"]; + echo " \n"; + break; + default: + echo " " + . $this->_prop_encode(htmlspecialchars($prop['val'])) + . "\n"; + break; + } + } else { + // properties from namespaces != "DAV:" or without any namespace + if ($prop["ns"]) { + echo " <" . $ns_hash[$prop["ns"]] . ":$prop[name]>" + . $this->_prop_encode(htmlspecialchars($prop['val'])) + . "\n"; + } else { + echo " <$prop[name] xmlns=\"\">" + . $this->_prop_encode(htmlspecialchars($prop['val'])) + . "\n"; + } + } + } + + echo " \n"; + echo " HTTP/1.1 200 OK\n"; + echo " \n"; + } + /* commented by Onti. + // now report all properties requested but not found + if (isset($file["noprops"])) { + echo " \n"; + echo " \n"; + + foreach($file["noprops"] as $key => $prop) { + if ($prop["ns"] == "DAV:") { + echo " \n"; + } else if ($prop["ns"] == "") { + echo " <$prop[name] xmlns=\"\"/>\n"; + } else { + echo " <" . $ns_hash[$prop["ns"]] . ":$prop[name]/>\n"; + } + } + + echo " \n"; + echo " HTTP/1.1 404 Not Found\n"; + echo " \n"; + } + */ + echo " \n"; + } + + echo "\n"; + } + + + // }}} + + // {{{ http_PROPPATCH() + + /** + * PROPPATCH method handler + * + * @param void + * @return void + */ + function http_PROPPATCH() + { + if($this->_check_lock_status($this->path)) { + $options = Array(); + $options["path"] = $this->path; + + $propinfo = new _parse_proppatch("php://input"); + + if (!$propinfo->success) { + $this->http_status("400 Error"); + return; + } + + $options['props'] = $propinfo->props; + + $responsedescr = $this->PROPPATCH($options); + + $this->http_status("207 Multi-Status"); + header('Content-Type: text/xml; charset="utf-8"'); + + echo "\n"; + + echo "\n"; + echo " \n"; + echo " ".$this->_urlencode($this->_mergePathes($_SERVER["SCRIPT_NAME"], $this->path))."\n"; + + foreach($options["props"] as $prop) { + echo " \n"; + echo " <$prop[name] xmlns=\"$prop[ns]\"/>\n"; + echo " HTTP/1.1 $prop[status]\n"; + echo " \n"; + } + + if ($responsedescr) { + echo " ". + $this->_prop_encode(htmlspecialchars($responsedescr)). + "\n"; + } + + echo " \n"; + echo "\n"; + } else { + $this->http_status("423 Locked"); + } + } + + // }}} + + + // {{{ http_MKCOL() + + /** + * MKCOL method handler + * + * @param void + * @return void + */ + function http_MKCOL() + { + $options = Array(); + $options["path"] = $this->path; + + $stat = $this->MKCOL($options); + + $this->http_status($stat); + } + + // }}} + + + // {{{ http_GET() + + /** + * GET method handler + * + * @param void + * @returns void + */ + function http_GET() + { + // TODO check for invalid stream + $options = Array(); + $options["path"] = $this->path; + + $this->_get_ranges($options); + + if (true === ($status = $this->GET($options))) { + if (!headers_sent()) { + $status = "200 OK"; + + if (!isset($options['mimetype'])) { + $options['mimetype'] = "application/octet-stream"; + } + header("Content-type: $options[mimetype]"); + + if (isset($options['mtime'])) { + header("Last-modified:".gmdate("D, d M Y H:i:s ", $options['mtime'])."GMT"); + } + + if (isset($options['stream'])) { + // GET handler returned a stream + if (!empty($options['ranges']) && (0===fseek($options['stream'], 0, SEEK_SET))) { + // partial request and stream is seekable + + if (count($options['ranges']) === 1) { + $range = $options['ranges'][0]; + + if (isset($range['start'])) { + fseek($options['stream'], $range['start'], SEEK_SET); + if (feof($options['stream'])) { + $this->http_status("416 Requested range not satisfiable"); + return; + } + + if (isset($range['end'])) { + $size = $range['end']-$range['start']+1; + $this->http_status("206 partial"); + header("Content-length: $size"); + header("Content-range: $range[start]-$range[end]/" + . (isset($options['size']) ? $options['size'] : "*")); + while ($size && !feof($options['stream'])) { + $buffer = fread($options['stream'], 4096); + $size -= strlen($buffer); + echo $buffer; + } + } else { + $this->http_status("206 partial"); + if (isset($options['size'])) { + header("Content-length: ".($options['size'] - $range['start'])); + header("Content-range: $start-$end/" + . (isset($options['size']) ? $options['size'] : "*")); + } + fpassthru($options['stream']); + } + } else { + header("Content-length: ".$range['last']); + fseek($options['stream'], -$range['last'], SEEK_END); + fpassthru($options['stream']); + } + } else { + $this->_multipart_byterange_header(); // init multipart + foreach ($options['ranges'] as $range) { + // TODO what if size unknown? 500? + if (isset($range['start'])) { + $from = $range['start']; + $to = !empty($range['end']) ? $range['end'] : $options['size']-1; + } else { + $from = $options['size'] - $range['last']-1; + $to = $options['size'] -1; + } + $total = isset($options['size']) ? $options['size'] : "*"; + $size = $to - $from + 1; + $this->_multipart_byterange_header($options['mimetype'], $from, $to, $total); + + + fseek($options['stream'], $start, SEEK_SET); + while ($size && !feof($options['stream'])) { + $buffer = fread($options['stream'], 4096); + $size -= strlen($buffer); + echo $buffer; + } + } + $this->_multipart_byterange_header(); // end multipart + } + } else { + // normal request or stream isn't seekable, return full content + if (isset($options['size'])) { + header("Content-length: ".$options['size']); + } + fpassthru($options['stream']); + return; // no more headers + } + } elseif (isset($options['data'])) { + if (is_array($options['data'])) { + // reply to partial request + } else { + header("Content-length: ".strlen($options['data'])); + echo $options['data']; + } + } + } + } + + if (!headers_sent()) { + if (false === $status) { + $this->http_status("404 not found"); + } else { + // TODO: check setting of headers in various code pathes above + $this->http_status("$status"); + } + } + } + + + /** + * parse HTTP Range: header + * + * @param array options array to store result in + * @return void + */ + function _get_ranges(&$options) + { + // process Range: header if present + if (isset($_SERVER['HTTP_RANGE'])) { + + // we only support standard "bytes" range specifications for now + if (preg_match('/bytes\s*=\s*(.+)/', $_SERVER['HTTP_RANGE'], $matches)) { + $options["ranges"] = array(); + + // ranges are comma separated + foreach (explode(",", $matches[1]) as $range) { + // ranges are either from-to pairs or just end positions + list($start, $end) = explode("-", $range); + $options["ranges"][] = ($start==="") + ? array("last"=>$end) + : array("start"=>$start, "end"=>$end); + } + } + } + } + + /** + * generate separator headers for multipart response + * + * first and last call happen without parameters to generate + * the initial header and closing sequence, all calls inbetween + * require content mimetype, start and end byte position and + * optionaly the total byte length of the requested resource + * + * @param string mimetype + * @param int start byte position + * @param int end byte position + * @param int total resource byte size + */ + function _multipart_byterange_header($mimetype = false, $from = false, $to=false, $total=false) + { + if ($mimetype === false) { + if (!isset($this->multipart_separator)) { + // initial + + // a little naive, this sequence *might* be part of the content + // but it's really not likely and rather expensive to check + $this->multipart_separator = "SEPARATOR_".md5(microtime()); + + // generate HTTP header + header("Content-type: multipart/byteranges; boundary=".$this->multipart_separator); + } else { + // final + + // generate closing multipart sequence + echo "\n--{$this->multipart_separator}--"; + } + } else { + // generate separator and header for next part + echo "\n--{$this->multipart_separator}\n"; + echo "Content-type: $mimetype\n"; + echo "Content-range: $from-$to/". ($total === false ? "*" : $total); + echo "\n\n"; + } + } + + + + // }}} + + // {{{ http_HEAD() + + /** + * HEAD method handler + * + * @param void + * @return void + */ + function http_HEAD() + { + $status = false; + $options = Array(); + $options["path"] = $this->path; + + if (method_exists($this, "HEAD")) { + $status = $this->head($options); + } else if (method_exists($this, "GET")) { + ob_start(); + $status = $this->GET($options); + if (!isset($options['size'])) { + $options['size'] = ob_get_length(); + } + ob_end_clean(); + } + + if (isset($options['size'])) { + header("Content-length: ".$options['size']); + } + + if($status===true) $status = "200 OK"; + if($status===false) $status = "404 Not found"; + + $this->http_status($status); + } + + // }}} + + // {{{ http_PUT() + + /** + * PUT method handler + * + * @param void + * @return void + */ + function http_PUT() + { + if ($this->_check_lock_status($this->path)) { + $options = Array(); + $options["path"] = $this->path; + $options["content_length"] = $_SERVER["CONTENT_LENGTH"]; + + // get the Content-type + if (isset($_SERVER["CONTENT_TYPE"])) { + // for now we do not support any sort of multipart requests + if (!strncmp($_SERVER["CONTENT_TYPE"], "multipart/", 10)) { + $this->http_status("501 not implemented"); + echo "The service does not support mulipart PUT requests"; + return; + } + $options["content_type"] = $_SERVER["CONTENT_TYPE"]; + } else { + // default content type if none given + $options["content_type"] = "application/octet-stream"; + } + + /* RFC 2616 2.6 says: "The recipient of the entity MUST NOT + ignore any Content-* (e.g. Content-Range) headers that it + does not understand or implement and MUST return a 501 + (Not Implemented) response in such cases." + */ + foreach ($_SERVER as $key => $val) { + if (strncmp($key, "HTTP_CONTENT", 11)) continue; + switch ($key) { + case 'HTTP_CONTENT_ENCODING': // RFC 2616 14.11 + // TODO support this if ext/zlib filters are available + $this->http_status("501 not implemented"); + echo "The service does not support '$val' content encoding"; + return; + + case 'HTTP_CONTENT_LANGUAGE': // RFC 2616 14.12 + // we assume it is not critical if this one is ignored + // in the actual PUT implementation ... + $options["content_language"] = $value; + break; + + case 'HTTP_CONTENT_LOCATION': // RFC 2616 14.14 + /* The meaning of the Content-Location header in PUT + or POST requests is undefined; servers are free + to ignore it in those cases. */ + break; + + case 'HTTP_CONTENT_RANGE': // RFC 2616 14.16 + // single byte range requests are supported + // the header format is also specified in RFC 2616 14.16 + // TODO we have to ensure that implementations support this or send 501 instead + if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $val, $matches)) { + $this->http_status("400 bad request"); + echo "The service does only support single byte ranges"; + return; + } + + $range = array("start"=>$matches[1], "end"=>$matches[2]); + if (is_numeric($matches[3])) { + $range["total_length"] = $matches[3]; + } + $option["ranges"][] = $range; + + // TODO make sure the implementation supports partial PUT + // this has to be done in advance to avoid data being overwritten + // on implementations that do not support this ... + break; + + case 'HTTP_CONTENT_MD5': // RFC 2616 14.15 + // TODO: maybe we can just pretend here? + $this->http_status("501 not implemented"); + echo "The service does not support content MD5 checksum verification"; + return; + + default: + // any other unknown Content-* headers + $this->http_status("501 not implemented"); + echo "The service does not support '$key'"; + return; + } + } + + + $options["stream"] = fopen("php://input", "r"); + + $stat = $this->PUT($options); + + if ($stat === false) { + $stat = "403 Forbidden"; + } +/* + else if (is_resource($stat) && get_resource_type($stat) == "stream") { + $stream = $stat; + + $stat = $options["new"] ? "201 Created" : "204 No Content"; + if (!empty($options["ranges"])) { + // TODO multipart support is missing (see also above) + if (0 == fseek($stream, $range[0]["start"], SEEK_SET)) { + $length = $range[0]["end"]-$range[0]["start"]+1; + if (!fwrite($stream, fread($options["stream"], $length))) { + $stat = "403 Forbidden"; + } + } else { + $stat = "403 Forbidden"; + } + } else { + while (!feof($options["stream"])) { + if (false === fwrite($stream, fread($options["stream"], 4096))) { + $stat = "403 Forbidden"; + break; + } + } + } + + fclose($stream); + + } +*/ + $this->http_status($stat); + } else { + $this->http_status("423 Locked"); + } + } + + // }}} + + + // {{{ http_DELETE() + + /** + * DELETE method handler + * + * @param void + * @return void + */ + function http_DELETE() + { + // check RFC 2518 Section 9.2, last paragraph + if (isset($_SERVER["HTTP_DEPTH"])) { + if ($_SERVER["HTTP_DEPTH"] != "infinity") { + $this->http_status("400 Bad Request"); + return; + } + } + + // check lock status + if ($this->_check_lock_status($this->path)) { + // ok, proceed + $options = Array(); + $options["path"] = $this->path; + + $stat = $this->DELETE($options); + + $this->http_status($stat); + } else { + // sorry, its locked + $this->http_status("423 Locked"); + } + } + + // }}} + + // {{{ http_COPY() + + /** + * COPY method handler + * + * @param void + * @return void + */ + function http_COPY() + { + // no need to check source lock status here + // destination lock status is always checked by the helper method + $this->_copymove("copy"); + } + + // }}} + + // {{{ http_MOVE() + + /** + * MOVE method handler + * + * @param void + * @return void + */ + function http_MOVE() + { + if ($this->_check_lock_status($this->path)) { + // destination lock status is always checked by the helper method + $this->_copymove("move"); + } else { + $this->http_status("423 Locked"); + } + } + + // }}} + + + // {{{ http_LOCK() + + /** + * LOCK method handler + * + * @param void + * @return void + */ + function http_LOCK() + { + $options = Array(); + $options["path"] = $this->path; + + if (isset($_SERVER['HTTP_DEPTH'])) { + $options["depth"] = $_SERVER["HTTP_DEPTH"]; + } else { + $options["depth"] = "infinity"; + } + + if (isset($_SERVER["HTTP_TIMEOUT"])) { + $options["timeout"] = explode(",", $_SERVER["HTTP_TIMEOUT"]); + } + + if(empty($_SERVER['CONTENT_LENGTH']) && !empty($_SERVER['HTTP_IF'])) { + // check if locking is possible + if(!$this->_check_lock_status($this->path)) { + $this->http_status("423 Locked"); + return; + } + + // refresh lock + $options["update"] = substr($_SERVER['HTTP_IF'], 2, -2); + $stat = $this->LOCK($options); + } else { + // extract lock request information from request XML payload + $lockinfo = new _parse_lockinfo("php://input"); + if (!$lockinfo->success) { + $this->http_status("400 bad request"); + } + + // check if locking is possible + if(!$this->_check_lock_status($this->path, $lockinfo->lockscope === "shared")) { + $this->http_status("423 Locked"); + return; + } + + // new lock + $options["scope"] = $lockinfo->lockscope; + $options["type"] = $lockinfo->locktype; + $options["owner"] = $lockinfo->owner; + + $options["locktoken"] = $this->_new_locktoken(); + + $stat = $this->LOCK($options); + } + + if(is_bool($stat)) { + $http_stat = $stat ? "200 OK" : "423 Locked"; + } else { + $http_stat = $stat; + } + + $this->http_status($http_stat); + + if ($http_stat{0} == 2) { // 2xx states are ok + if($options["timeout"]) { + // more than a million is considered an absolute timestamp + // less is more likely a relative value + if($options["timeout"]>1000000) { + $timeout = "Second-".($options['timeout']-time()); + } else { + $timeout = "Second-$options[timeout]"; + } + } else { + $timeout = "Infinite"; + } + + header('Content-Type: text/xml; charset="utf-8"'); + header("Lock-Token: <$options[locktoken]>"); + echo "\n"; + echo "\n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo " $options[depth]\n"; + echo " $options[owner]\n"; + echo " $timeout\n"; + echo " $options[locktoken]\n"; + echo " \n"; + echo " \n"; + echo "\n\n"; + } + } + + + // }}} + + // {{{ http_UNLOCK() + + /** + * UNLOCK method handler + * + * @param void + * @return void + */ + function http_UNLOCK() + { + $options = Array(); + $options["path"] = $this->path; + + if (isset($_SERVER['HTTP_DEPTH'])) { + $options["depth"] = $_SERVER["HTTP_DEPTH"]; + } else { + $options["depth"] = "infinity"; + } + + // strip surrounding <> + $options["token"] = substr(trim($_SERVER["HTTP_LOCK_TOKEN"]), 1, -1); + + // call user method + $stat = $this->UNLOCK($options); + + $this->http_status($stat); + } + + // }}} + + // }}} + + // {{{ _copymove() + + function _copymove($what) + { + $options = Array(); + $options["path"] = $this->path; + + if (isset($_SERVER["HTTP_DEPTH"])) { + $options["depth"] = $_SERVER["HTTP_DEPTH"]; + } else { + $options["depth"] = "infinity"; + } + + extract(parse_url($_SERVER["HTTP_DESTINATION"])); + $path = urldecode($path); + $http_host = $host; + if (isset($port) && $port != 80) + $http_host.= ":$port"; + + $http_header_host = preg_replace("/:80$/", "", $_SERVER["HTTP_HOST"]); + + if ($http_host == $http_header_host && + !strncmp($_SERVER["SCRIPT_NAME"], $path, + strlen($_SERVER["SCRIPT_NAME"]))) { + $options["dest"] = substr($path, strlen($_SERVER["SCRIPT_NAME"])); + if (!$this->_check_lock_status($options["dest"])) { + $this->http_status("423 Locked"); + return; + } + + } else { + $options["dest_url"] = $_SERVER["HTTP_DESTINATION"]; + } + + // see RFC 2518 Sections 9.6, 8.8.4 and 8.9.3 + if (isset($_SERVER["HTTP_OVERWRITE"])) { + $options["overwrite"] = $_SERVER["HTTP_OVERWRITE"] == "T"; + } else { + $options["overwrite"] = true; + } + + $stat = $this->$what($options); + $this->http_status($stat); + } + + // }}} + + // {{{ _allow() + + /** + * check for implemented HTTP methods + * + * @param void + * @return array something + */ + function _allow() + { + // OPTIONS is always there + $allow = array("OPTIONS" =>"OPTIONS"); + + // all other METHODS need both a http_method() wrapper + // and a method() implementation + // the base class supplies wrappers only + foreach(get_class_methods($this) as $method) { + if (!strncmp("http_", $method, 5)) { + $method = strtoupper(substr($method, 5)); + if (method_exists($this, $method)) { + $allow[$method] = $method; + } + } + } + + // we can emulate a missing HEAD implemetation using GET + if (isset($allow["GET"])) + $allow["HEAD"] = "HEAD"; + + // no LOCK without checklok() + if (!method_exists($this, "checklock")) { + unset($allow["LOCK"]); + unset($allow["UNLOCK"]); + } + + return $allow; + } + + // }}} + + /** + * helper for property element creation + * + * @param string XML namespace (optional) + * @param string property name + * @param string property value + * @return array property array + */ + function mkprop() + { + $args = func_get_args(); + if (count($args) == 3) { + return array("ns" => $args[0], + "name" => $args[1], + "val" => $args[2]); + } else { + return array("ns" => "DAV:", + "name" => $args[0], + "val" => $args[1]); + } + } + + // {{{ _check_auth + + /** + * check authentication if check is implemented + * + * @param void + * @return bool true if authentication succeded or not necessary + */ + function _check_auth() + { + if (method_exists($this, "checkAuth")) { + // PEAR style method name + return $this->checkAuth(@$_SERVER["AUTH_TYPE"], + @$_SERVER["PHP_AUTH_USER"], + @$_SERVER["PHP_AUTH_PW"]); + } else if (method_exists($this, "check_auth")) { + // old (pre 1.0) method name + return $this->check_auth(@$_SERVER["AUTH_TYPE"], + @$_SERVER["PHP_AUTH_USER"], + @$_SERVER["PHP_AUTH_PW"]); + } else { + // no method found -> no authentication required + return true; + } + } + + // }}} + + // {{{ UUID stuff + + /** + * generate Unique Universal IDentifier for lock token + * + * @param void + * @return string a new UUID + */ + function _new_uuid() + { + // use uuid extension from PECL if available + if (function_exists("uuid_create")) { + return uuid_create(); + } + + // fallback + $uuid = md5(microtime().getmypid()); // this should be random enough for now + + // set variant and version fields for 'true' random uuid + $uuid{12} = "4"; + $n = 8 + (ord($uuid{16}) & 3); + $hex = "0123456789abcdef"; + $uuid{16} = $hex{$n}; + + // return formated uuid + return substr($uuid, 0, 8)."-" + . substr($uuid, 8, 4)."-" + . substr($uuid, 12, 4)."-" + . substr($uuid, 16, 4)."-" + . substr($uuid, 20); + } + + /** + * create a new opaque lock token as defined in RFC2518 + * + * @param void + * @return string new RFC2518 opaque lock token + */ + function _new_locktoken() + { + return "opaquelocktoken:".$this->_new_uuid(); + } + + // }}} + + // {{{ WebDAV If: header parsing + + /** + * + * + * @param string header string to parse + * @param int current parsing position + * @return array next token (type and value) + */ + function _if_header_lexer($string, &$pos) + { + // skip whitespace + while (ctype_space($string{$pos})) { + ++$pos; + } + + // already at end of string? + if (strlen($string) <= $pos) { + return false; + } + + // get next character + $c = $string{$pos++}; + + // now it depends on what we found + switch ($c) { + case "<": + // URIs are enclosed in <...> + $pos2 = strpos($string, ">", $pos); + $uri = substr($string, $pos, $pos2 - $pos); + $pos = $pos2 + 1; + return array("URI", $uri); + + case "[": + //Etags are enclosed in [...] + if ($string{$pos} == "W") { + $type = "ETAG_WEAK"; + $pos += 2; + } else { + $type = "ETAG_STRONG"; + } + $pos2 = strpos($string, "]", $pos); + $etag = substr($string, $pos + 1, $pos2 - $pos - 2); + $pos = $pos2 + 1; + return array($type, $etag); + + case "N": + // "N" indicates negation + $pos += 2; + return array("NOT", "Not"); + + default: + // anything else is passed verbatim char by char + return array("CHAR", $c); + } + } + + /** + * parse If: header + * + * @param string header string + * @return array URIs and their conditions + */ + function _if_header_parser($str) + { + $pos = 0; + $len = strlen($str); + + $uris = array(); + + // parser loop + while ($pos < $len) { + // get next token + $token = $this->_if_header_lexer($str, $pos); + + // check for URI + if ($token[0] == "URI") { + $uri = $token[1]; // remember URI + $token = $this->_if_header_lexer($str, $pos); // get next token + } else { + $uri = ""; + } + + // sanity check + if ($token[0] != "CHAR" || $token[1] != "(") { + return false; + } + + $list = array(); + $level = 1; + $not = ""; + while ($level) { + $token = $this->_if_header_lexer($str, $pos); + if ($token[0] == "NOT") { + $not = "!"; + continue; + } + switch ($token[0]) { + case "CHAR": + switch ($token[1]) { + case "(": + $level++; + break; + case ")": + $level--; + break; + default: + return false; + } + break; + + case "URI": + $list[] = $not."<$token[1]>"; + break; + + case "ETAG_WEAK": + $list[] = $not."[W/'$token[1]']>"; + break; + + case "ETAG_STRONG": + $list[] = $not."['$token[1]']>"; + break; + + default: + return false; + } + $not = ""; + } + + if (@is_array($uris[$uri])) { + $uris[$uri] = array_merge($uris[$uri],$list); + } else { + $uris[$uri] = $list; + } + } + + return $uris; + } + + /** + * check if conditions from "If:" headers are meat + * + * the "If:" header is an extension to HTTP/1.1 + * defined in RFC 2518 section 9.4 + * + * @param void + * @return void + */ + function _check_if_header_conditions() + { + if (isset($_SERVER["HTTP_IF"])) { + $this->_if_header_uris = + $this->_if_header_parser($_SERVER["HTTP_IF"]); + + foreach($this->_if_header_uris as $uri => $conditions) { + if ($uri == "") { + $uri = $this->uri; + } + // all must match + $state = true; + foreach($conditions as $condition) { + // lock tokens may be free form (RFC2518 6.3) + // but if opaquelocktokens are used (RFC2518 6.4) + // we have to check the format (litmus tests this) + if (!strncmp($condition, "$/', $condition)) { + $this->http_status("423 Locked"); + return false; + } + } + if (!$this->_check_uri_condition($uri, $condition)) { + $this->http_status("412 Precondition failed"); + $state = false; + break; + } + } + + // any match is ok + if ($state == true) { + return true; + } + } + return false; + } + return true; + } + + /** + * Check a single URI condition parsed from an if-header + * + * Check a single URI condition parsed from an if-header + * + * @abstract + * @param string $uri URI to check + * @param string $condition Condition to check for this URI + * @returns bool Condition check result + */ + function _check_uri_condition($uri, $condition) + { + // not really implemented here, + // implementations must override + return true; + } + + + /** + * + * + * @param string path of resource to check + * @param bool exclusive lock? + */ + function _check_lock_status($path, $exclusive_only = false) + { + // FIXME depth -> ignored for now + if (method_exists($this, "checkLock")) { + // is locked? + $lock = $this->checkLock($path); + + // ... and lock is not owned? + if (is_array($lock) && count($lock)) { + // FIXME doesn't check uri restrictions yet + if (!isset($_SERVER["HTTP_IF"]) || !strstr($_SERVER["HTTP_IF"], $lock["token"])) { + if (!$exclusive_only || ($lock["scope"] !== "shared")) + return false; + } + } + } + return true; + } + + + // }}} + + + /** + * Generate lockdiscovery reply from checklock() result + * + * @param string resource path to check + * @return string lockdiscovery response + */ + function lockdiscovery($path) + { + // no lock support without checklock() method + if (!method_exists($this, "checklock")) { + return ""; + } + + // collect response here + $activelocks = ""; + + // get checklock() reply + $lock = $this->checklock($path); + + // generate block for returned data + if (is_array($lock) && count($lock)) { + // check for 'timeout' or 'expires' + if (!empty($lock["expires"])) { + $timeout = "Second-".($lock["expires"] - time()); + } else if (!empty($lock["timeout"])) { + $timeout = "Second-$lock[timeout]"; + } else { + $timeout = "Infinite"; + } + + // genreate response block + $activelocks.= " + + + + $lock[depth] + $lock[owner] + $timeout + $lock[token] + + "; + } + + // return generated response + return $activelocks; + } + + /** + * set HTTP return status and mirror it in a private header + * + * @param string status code and message + * @return void + */ + function http_status($status) + { + // simplified success case + if($status === true) { + $status = "200 OK"; + } + + // remember status + $this->_http_status = $status; + + // generate HTTP status response + header("HTTP/1.1 $status"); + header("X-WebDAV-Status: $status", true); + } + + /** + * private minimalistic version of PHP urlencode() + * + * only blanks and XML special chars must be encoded here + * full urlencode() encoding confuses some clients ... + * + * @param string URL to encode + * @return string encoded URL + */ + function _urlencode($url) + { + return strtr($url, array(" "=>"%20", + "&"=>"%26", + "<"=>"%3C", + ">"=>"%3E", + )); + } + + /** + * private version of PHP urldecode + * + * not really needed but added for completenes + * + * @param string URL to decode + * @return string decoded URL + */ + function _urldecode($path) + { + return urldecode($path); + } + + /** + * UTF-8 encode property values if not already done so + * + * @param string text to encode + * @return string utf-8 encoded text + */ + function _prop_encode($text) + { + switch (strtolower($this->_prop_encoding)) { + case "utf-8": + return $text; + case "iso-8859-1": + case "iso-8859-15": + case "latin-1": + default: + return utf8_encode($text); + } + } + + /** + * Slashify - make sure path ends in a slash + * + * @param string directory path + * @returns string directory path wiht trailing slash + */ + function _slashify($path) { + if ($path[strlen($path)-1] != '/') { + $path = $path."/"; + } + return $path; + } + + /** + * Unslashify - make sure path doesn't in a slash + * + * @param string directory path + * @returns string directory path wihtout trailing slash + */ + function _unslashify($path) { + if ($path[strlen($path)-1] == '/') { + $path = substr($path, 0, strlen($path, 0, -1)); + } + return $path; + } + + /** + * Merge two pathes, make sure there is exactly one slash between them + * + * @param string parent path + * @param string child path + * @return string merged path + */ + function _mergePathes($parent, $child) + { + if ($child{0} == '/') { + return $this->_unslashify($parent).$child; + } else { + return $this->_slashify($parent).$child; + } + } +} diff --git a/gulliver/thirdparty/pear/HTTP/WebDAV/Server/Filesystem.php b/gulliver/thirdparty/pear/HTTP/WebDAV/Server/Filesystem.php new file mode 100644 index 000000000..ae87e5462 --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/WebDAV/Server/Filesystem.php @@ -0,0 +1,755 @@ + $value) { + if (stristr($key,"litmus")) { + error_log("Litmus test $value"); + header("X-Litmus-reply: ".$value); + } + } + } + + // set root directory, defaults to webserver document root if not set + if ($base) { + $this->base = realpath($base); // TODO throw if not a directory + } else if (!$this->base) { + $this->base = $_SERVER['DOCUMENT_ROOT']; + } + + // establish connection to property/locking db + //mysql_connect($this->db_host, $this->db_user, $this->db_passwd) or die(mysql_error()); + //mysql_select_db($this->db_name) or die(mysql_error()); + // TODO throw on connection problems + + // let the base class do all the work + parent::ServeRequest(); + } + + /** + * No authentication is needed here + * + * @access private + * @param string HTTP Authentication type (Basic, Digest, ...) + * @param string Username + * @param string Password + * @return bool true on successful authentication + */ + function check_auth($type, $user, $pass) + { + return true; + } + + + /** + * PROPFIND method handler + * + * @param array general parameter passing array + * @param array return array for file properties + * @return bool true on success + */ + function PROPFIND(&$options, &$files) + { + // get absolute fs path to requested resource + $fspath = $this->base . $options["path"]; + + // sanity check + if (!file_exists($fspath)) { + return false; + } + + // prepare property array + $files["files"] = array(); + + // store information for the requested path itself + $files["files"][] = $this->fileinfo($options["path"]); + + // information for contained resources requested? + if (!empty($options["depth"])) { // TODO check for is_dir() first? + + // make sure path ends with '/' + $options["path"] = $this->_slashify($options["path"]); + + // try to open directory + $handle = @opendir($fspath); + + if ($handle) { + // ok, now get all its contents + while ($filename = readdir($handle)) { + if ($filename != "." && $filename != "..") { + $files["files"][] = $this->fileinfo($options["path"].$filename); + } + } + // TODO recursion needed if "Depth: infinite" + } + } + + // ok, all done + return true; + } + + /** + * Get properties for a single file/resource + * + * @param string resource path + * @return array resource properties + */ + function fileinfo($path) + { + // map URI path to filesystem path + $fspath = $this->base . $path; + + // create result array + $info = array(); + // TODO remove slash append code when base clase is able to do it itself + $info["path"] = is_dir($fspath) ? $this->_slashify($path) : $path; + $info["props"] = array(); + + // no special beautified displayname here ... + $info["props"][] = $this->mkprop("displayname", strtoupper($path)); + + // creation and modification time + $info["props"][] = $this->mkprop("creationdate", filectime($fspath)); + $info["props"][] = $this->mkprop("getlastmodified", filemtime($fspath)); + + // type and size (caller already made sure that path exists) + if (is_dir($fspath)) { + // directory (WebDAV collection) + $info["props"][] = $this->mkprop("resourcetype", "collection"); + $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory"); + } else { + // plain file (WebDAV resource) + $info["props"][] = $this->mkprop("resourcetype", ""); + if (is_readable($fspath)) { + $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath)); + } else { + $info["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable"); + } + $info["props"][] = $this->mkprop("getcontentlength", filesize($fspath)); + } + + // get additional properties from database + $query = "SELECT ns, name, value FROM properties WHERE path = '$path'"; + $res = mysql_query($query); + while ($row = mysql_fetch_assoc($res)) { + $info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]); + } + mysql_free_result($res); + + return $info; + } + + /** + * detect if a given program is found in the search PATH + * + * helper function used by _mimetype() to detect if the + * external 'file' utility is available + * + * @param string program name + * @param string optional search path, defaults to $PATH + * @return bool true if executable program found in path + */ + function _can_execute($name, $path = false) + { + // path defaults to PATH from environment if not set + if ($path === false) { + $path = getenv("PATH"); + } + + // check method depends on operating system + if (!strncmp(PHP_OS, "WIN", 3)) { + // on Windows an appropriate COM or EXE file needs to exist + $exts = array(".exe", ".com"); + $check_fn = "file_exists"; + } else { + // anywhere else we look for an executable file of that name + $exts = array(""); + $check_fn = "is_executable"; + } + + // now check the directories in the path for the program + foreach (explode(PATH_SEPARATOR, $path) as $dir) { + // skip invalid path entries + if (!file_exists($dir)) continue; + if (!is_dir($dir)) continue; + + // and now look for the file + foreach ($exts as $ext) { + if ($check_fn("$dir/$name".$ext)) return true; + } + } + + return false; + } + + + /** + * try to detect the mime type of a file + * + * @param string file path + * @return string guessed mime type + */ + function _mimetype($fspath) + { + if (@is_dir($fspath)) { + // directories are easy + return "httpd/unix-directory"; + } else if (function_exists("mime_content_type")) { + // use mime magic extension if available + $mime_type = mime_content_type($fspath); + } else if ($this->_can_execute("file")) { + // it looks like we have a 'file' command, + // lets see it it does have mime support + $fp = popen("file -i '$fspath' 2>/dev/null", "r"); + $reply = fgets($fp); + pclose($fp); + + // popen will not return an error if the binary was not found + // and find may not have mime support using "-i" + // so we test the format of the returned string + + // the reply begins with the requested filename + if (!strncmp($reply, "$fspath: ", strlen($fspath)+2)) { + $reply = substr($reply, strlen($fspath)+2); + // followed by the mime type (maybe including options) + if (preg_match('/^[[:alnum:]_-]+/[[:alnum:]_-]+;?.*/', $reply, $matches)) { + $mime_type = $matches[0]; + } + } + } + + if (empty($mime_type)) { + // Fallback solution: try to guess the type by the file extension + // TODO: add more ... + // TODO: it has been suggested to delegate mimetype detection + // to apache but this has at least three issues: + // - works only with apache + // - needs file to be within the document tree + // - requires apache mod_magic + // TODO: can we use the registry for this on Windows? + // OTOH if the server is Windos the clients are likely to + // be Windows, too, and tend do ignore the Content-Type + // anyway (overriding it with information taken from + // the registry) + // TODO: have a seperate PEAR class for mimetype detection? + switch (strtolower(strrchr(basename($fspath), "."))) { + case ".html": + $mime_type = "text/html"; + break; + case ".gif": + $mime_type = "image/gif"; + break; + case ".jpg": + $mime_type = "image/jpeg"; + break; + default: + $mime_type = "application/octet-stream"; + break; + } + } + + return $mime_type; + } + + /** + * GET method handler + * + * @param array parameter passing array + * @return bool true on success + */ + function GET(&$options) + { + // get absolute fs path to requested resource + $fspath = $this->base . $options["path"]; + + // sanity check + if (!file_exists($fspath)) return false; + + // is this a collection? + if (is_dir($fspath)) { + return $this->GetDir($fspath, $options); + } + + // detect resource type + $options['mimetype'] = $this->_mimetype($fspath); + + // detect modification time + // see rfc2518, section 13.7 + // some clients seem to treat this as a reverse rule + // requiering a Last-Modified header if the getlastmodified header was set + $options['mtime'] = filemtime($fspath); + + // detect resource size + $options['size'] = filesize($fspath); + + // no need to check result here, it is handled by the base class + $options['stream'] = fopen($fspath, "r"); + + return true; + } + + /** + * GET method handler for directories + * + * This is a very simple mod_index lookalike. + * See RFC 2518, Section 8.4 on GET/HEAD for collections + * + * @param string directory path + * @return void function has to handle HTTP response itself + */ + function GetDir($fspath, &$options) + { + $path = $this->_slashify($options["path"]); + if ($path != $options["path"]) { + header("Location: ".$this->base_uri.$path); + exit; + } + + // fixed width directory column format + $format = "%15s %-19s %-s\n"; + + $handle = @opendir($fspath); + if (!$handle) { + return false; + } + + echo "Index of ".htmlspecialchars($options['path'])."\n"; + + echo "

    Index of ".htmlspecialchars($options['path'])."

    \n"; + + echo "
    ";
    +            printf($format, "Size", "Last modified", "Filename");
    +            echo "
    "; + + while ($filename = readdir($handle)) { + if ($filename != "." && $filename != "..") { + $fullpath = $fspath."/".$filename; + $name = htmlspecialchars($filename); + printf($format, + number_format(filesize($fullpath)), + strftime("%Y-%m-%d %H:%M:%S", filemtime($fullpath)), + "$name"); + } + } + + echo "
    "; + + closedir($handle); + + echo "\n"; + + exit; + } + + /** + * PUT method handler + * + * @param array parameter passing array + * @return bool true on success + */ + function PUT(&$options) + { + $fspath = $this->base . $options["path"]; + + if (!@is_dir(dirname($fspath))) { + return "409 Conflict"; + } + + $options["new"] = ! file_exists($fspath); + + $fp = fopen($fspath, "w"); + + return $fp; + } + + + /** + * MKCOL method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function MKCOL($options) + { + $path = $this->base .$options["path"]; + $parent = dirname($path); + $name = basename($path); + + if (!file_exists($parent)) { + return "409 Conflict"; + } + + if (!is_dir($parent)) { + return "403 Forbidden"; + } + + if ( file_exists($parent."/".$name) ) { + return "405 Method not allowed"; + } + + if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet + return "415 Unsupported media type"; + } + + $stat = mkdir ($parent."/".$name,0777); + if (!$stat) { + return "403 Forbidden"; + } + + return ("201 Created"); + } + + + /** + * DELETE method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function DELETE($options) + { + $path = $this->base . "/" .$options["path"]; + + if (!file_exists($path)) { + return "404 Not found"; + } + + if (is_dir($path)) { + $query = "DELETE FROM properties WHERE path LIKE '".$this->_slashify($options["path"])."%'"; + mysql_query($query); + System::rm("-rf $path"); + } else { + unlink ($path); + } + $query = "DELETE FROM properties WHERE path = '$options[path]'"; + mysql_query($query); + + return "204 No Content"; + } + + + /** + * MOVE method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function MOVE($options) + { + return $this->COPY($options, true); + } + + /** + * COPY method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function COPY($options, $del=false) + { + // TODO Property updates still broken (Litmus should detect this?) + + if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet + return "415 Unsupported media type"; + } + + // no copying to different WebDAV Servers yet + if (isset($options["dest_url"])) { + return "502 bad gateway"; + } + + $source = $this->base .$options["path"]; + if (!file_exists($source)) return "404 Not found"; + + $dest = $this->base . $options["dest"]; + + $new = !file_exists($dest); + $existing_col = false; + + if (!$new) { + if ($del && is_dir($dest)) { + if (!$options["overwrite"]) { + return "412 precondition failed"; + } + $dest .= basename($source); + if (file_exists($dest)) { + $options["dest"] .= basename($source); + } else { + $new = true; + $existing_col = true; + } + } + } + + if (!$new) { + if ($options["overwrite"]) { + $stat = $this->DELETE(array("path" => $options["dest"])); + if (($stat{0} != "2") && (substr($stat, 0, 3) != "404")) { + return $stat; + } + } else { + return "412 precondition failed"; + } + } + + if (is_dir($source) && ($options["depth"] != "infinity")) { + // RFC 2518 Section 9.2, last paragraph + return "400 Bad request"; + } + + if ($del) { + if (!rename($source, $dest)) { + return "500 Internal server error"; + } + $destpath = $this->_unslashify($options["dest"]); + if (is_dir($source)) { + $query = "UPDATE properties + SET path = REPLACE(path, '".$options["path"]."', '".$destpath."') + WHERE path LIKE '".$this->_slashify($options["path"])."%'"; + mysql_query($query); + } + + $query = "UPDATE properties + SET path = '".$destpath."' + WHERE path = '".$options["path"]."'"; + mysql_query($query); + } else { + if (is_dir($source)) { + $files = System::find($source); + $files = array_reverse($files); + } else { + $files = array($source); + } + + if (!is_array($files) || empty($files)) { + return "500 Internal server error"; + } + + + foreach ($files as $file) { + if (is_dir($file)) { + $file = $this->_slashify($file); + } + + $destfile = str_replace($source, $dest, $file); + + if (is_dir($file)) { + if (!is_dir($destfile)) { + // TODO "mkdir -p" here? (only natively supported by PHP 5) + if (!mkdir($destfile)) { + return "409 Conflict"; + } + } else { + error_log("existing dir '$destfile'"); + } + } else { + if (!copy($file, $destfile)) { + return "409 Conflict"; + } + } + } + + $query = "INSERT INTO properties SELECT ... FROM properties WHERE path = '".$options['path']."'"; + } + + return ($new && !$existing_col) ? "201 Created" : "204 No Content"; + } + + /** + * PROPPATCH method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function PROPPATCH(&$options) + { + global $prefs, $tab; + + $msg = ""; + + $path = $options["path"]; + + $dir = dirname($path)."/"; + $base = basename($path); + + foreach($options["props"] as $key => $prop) { + if ($prop["ns"] == "DAV:") { + $options["props"][$key]['status'] = "403 Forbidden"; + } else { + if (isset($prop["val"])) { + $query = "REPLACE INTO properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'"; + error_log($query); + } else { + $query = "DELETE FROM properties WHERE path = '$options[path]' AND name = '$prop[name]' AND ns = '$prop[ns]'"; + } + mysql_query($query); + } + } + + return ""; + } + + + /** + * LOCK method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function LOCK(&$options) + { + if (isset($options["update"])) { // Lock Update + $query = "UPDATE locks SET expires = ".(time()+300); + mysql_query($query); + + if (mysql_affected_rows()) { + $options["timeout"] = 300; // 5min hardcoded + return true; + } else { + return false; + } + } + + $options["timeout"] = time()+300; // 5min. hardcoded + + $query = "INSERT INTO locks + SET token = '$options[locktoken]' + , path = '$options[path]' + , owner = '$options[owner]' + , expires = '$options[timeout]' + , exclusivelock = " .($options['scope'] === "exclusive" ? "1" : "0") + ; + mysql_query($query); + + return mysql_affected_rows() ? "200 OK" : "409 Conflict"; + } + + /** + * UNLOCK method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function UNLOCK(&$options) + { + $query = "DELETE FROM locks + WHERE path = '$options[path]' + AND token = '$options[token]'"; + mysql_query($query); + + return mysql_affected_rows() ? "204 No Content" : "409 Conflict"; + } + + /** + * checkLock() helper + * + * @param string resource path to check for locks + * @return bool true on success + */ + function checkLock($path) + { + $result = false; + + $query = "SELECT owner, token, expires, exclusivelock + FROM locks + WHERE path = '$path' + "; + $res = mysql_query($query); + + if ($res) { + $row = mysql_fetch_array($res); + mysql_free_result($res); + + if ($row) { + $result = array( "type" => "write", + "scope" => $row["exclusivelock"] ? "exclusive" : "shared", + "depth" => 0, + "owner" => $row['owner'], + "token" => $row['token'], + "expires" => $row['expires'] + ); + } + } + + return $result; + } + + + /** + * create database tables for property and lock storage + * + * @param void + * @return bool true on success + */ + function create_database() + { + // TODO + return false; + } + + } + + +?> diff --git a/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_lockinfo.php b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_lockinfo.php new file mode 100644 index 000000000..3b32e2ff6 --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_lockinfo.php @@ -0,0 +1,237 @@ + | +// | Christian Stocker | +// +----------------------------------------------------------------------+ +// +// $Id: _parse_lockinfo.php,v 1.2 2004/01/05 12:32:40 hholzgra Exp $ +// + +/** + * helper class for parsing LOCK request bodies + * + * @package HTTP_WebDAV_Server + * @author Hartmut Holzgraefe + * @version 0.99.1dev + */ +class _parse_lockinfo +{ + /** + * success state flag + * + * @var bool + * @access public + */ + var $success = false; + + /** + * lock type, currently only "write" + * + * @var string + * @access public + */ + var $locktype = ""; + + /** + * lock scope, "shared" or "exclusive" + * + * @var string + * @access public + */ + var $lockscope = ""; + + /** + * lock owner information + * + * @var string + * @access public + */ + var $owner = ""; + + /** + * flag that is set during lock owner read + * + * @var bool + * @access private + */ + var $collect_owner = false; + + /** + * constructor + * + * @param string path of stream to read + * @access public + */ + function _parse_lockinfo($path) + { + // we assume success unless problems occur + $this->success = true; + + // remember if any input was parsed + $had_input = false; + + // open stream + $f_in = fopen($path, "r"); + if (!$f_in) { + $this->success = false; + return; + } + + // create namespace aware parser + $xml_parser = xml_parser_create_ns("UTF-8", " "); + + // set tag and data handlers + xml_set_element_handler($xml_parser, + array(&$this, "_startElement"), + array(&$this, "_endElement")); + xml_set_character_data_handler($xml_parser, + array(&$this, "_data")); + + // we want a case sensitive parser + xml_parser_set_option($xml_parser, + XML_OPTION_CASE_FOLDING, false); + + // parse input + while($this->success && !feof($f_in)) { + $line = fgets($f_in); + if (is_string($line)) { + $had_input = true; + $this->success &= xml_parse($xml_parser, $line, false); + } + } + + // finish parsing + if($had_input) { + $this->success &= xml_parse($xml_parser, "", true); + } + + // check if required tags where found + $this->success &= !empty($this->locktype); + $this->success &= !empty($this->lockscope); + + // free parser resource + xml_parser_free($xml_parser); + + // close input stream + fclose($f_in); + } + + + /** + * tag start handler + * + * @param resource parser + * @param string tag name + * @param array tag attributes + * @return void + * @access private + */ + function _startElement($parser, $name, $attrs) + { + // namespace handling + if (strstr($name, " ")) { + list($ns, $tag) = explode(" ", $name); + } else { + $ns = ""; + $tag = $name; + } + + + if ($this->collect_owner) { + // everything within the tag needs to be collected + $ns_short = ""; + $ns_attr = ""; + if ($ns) { + if ($ns == "DAV:") { + $ns_short = "D:"; + } else { + $ns_attr = " xmlns='$ns'"; + } + } + $this->owner .= "<$ns_short$tag$ns_attr>"; + } else if ($ns == "DAV:") { + // parse only the essential tags + switch ($tag) { + case "write": + $this->locktype = $tag; + break; + case "exclusive": + case "shared": + $this->lockscope = $tag; + break; + case "owner": + $this->collect_owner = true; + break; + } + } + } + + /** + * data handler + * + * @param resource parser + * @param string data + * @return void + * @access private + */ + function _data($parser, $data) + { + // only the tag has data content + if ($this->collect_owner) { + $this->owner .= $data; + } + } + + /** + * tag end handler + * + * @param resource parser + * @param string tag name + * @return void + * @access private + */ + function _endElement($parser, $name) + { + // namespace handling + if (strstr($name, " ")) { + list($ns, $tag) = explode(" ", $name); + } else { + $ns = ""; + $tag = $name; + } + + // finished? + if (($ns == "DAV:") && ($tag == "owner")) { + $this->collect_owner = false; + } + + // within we have to collect everything + if ($this->collect_owner) { + $ns_short = ""; + $ns_attr = ""; + if ($ns) { + if ($ns == "DAV:") { + $ns_short = "D:"; + } else { + $ns_attr = " xmlns='$ns'"; + } + } + $this->owner .= ""; + } + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_propfind.php b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_propfind.php new file mode 100644 index 000000000..15234cb15 --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_propfind.php @@ -0,0 +1,178 @@ + | +// | Christian Stocker | +// +----------------------------------------------------------------------+ +// +// $Id: _parse_propfind.php,v 1.2 2004/01/05 12:33:22 hholzgra Exp $ +// + +/** + * helper class for parsing PROPFIND request bodies + * + * @package HTTP_WebDAV_Server + * @author Hartmut Holzgraefe + * @version 0.99.1dev + */ +class _parse_propfind +{ + /** + * success state flag + * + * @var bool + * @access public + */ + var $success = false; + + /** + * found properties are collected here + * + * @var array + * @access public + */ + var $props = false; + + /** + * internal tag nesting depth counter + * + * @var int + * @access private + */ + var $depth = 0; + + + /** + * constructor + * + * @access public + */ + function _parse_propfind($path) + { + // success state flag + $this->success = true; + + // property storage array + $this->props = array(); + + // internal tag depth counter + $this->depth = 0; + + // remember if any input was parsed + $had_input = false; + + // open input stream + $f_in = fopen($path, "r"); + if (!$f_in) { + $this->success = false; + return; + } + + // create XML parser + $xml_parser = xml_parser_create_ns("UTF-8", " "); + + // set tag and data handlers + xml_set_element_handler($xml_parser, + array(&$this, "_startElement"), + array(&$this, "_endElement")); + + // we want a case sensitive parser + xml_parser_set_option($xml_parser, + XML_OPTION_CASE_FOLDING, false); + + + // parse input + while($this->success && !feof($f_in)) { + $line = fgets($f_in); + if (is_string($line)) { + $had_input = true; + $this->success &= xml_parse($xml_parser, $line, false); + } + } + + // finish parsing + if($had_input) { + $this->success &= xml_parse($xml_parser, "", true); + } + + // free parser + xml_parser_free($xml_parser); + + // close input stream + fclose($f_in); + + // if no input was parsed it was a request + if(!count($this->props)) $this->props = "all"; // default + } + + + /** + * start tag handler + * + * @access private + * @param resource parser + * @param string tag name + * @param array tag attributes + */ + function _startElement($parser, $name, $attrs) + { + // name space handling + if (strstr($name, " ")) { + list($ns, $tag) = explode(" ", $name); + if ($ns == "") + $this->success = false; + } else { + $ns = ""; + $tag = $name; + } + + // special tags at level 1: and + if ($this->depth == 1) { + if ($tag == "allprop") + $this->props = "all"; + + if ($tag == "propname") + $this->props = "names"; + } + + // requested properties are found at level 2 + if ($this->depth == 2) { + $prop = array("name" => $tag); + if ($ns) + $prop["xmlns"] = $ns; + $this->props[] = $prop; + } + + // increment depth count + $this->depth++; + } + + + /** + * end tag handler + * + * @access private + * @param resource parser + * @param string tag name + */ + function _endElement($parser, $name) + { + // here we only need to decrement the depth count + $this->depth--; + } +} + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_proppatch.php b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_proppatch.php new file mode 100644 index 000000000..9836ab228 --- /dev/null +++ b/gulliver/thirdparty/pear/HTTP/WebDAV/Tools/_parse_proppatch.php @@ -0,0 +1,214 @@ + | +// | Christian Stocker | +// +----------------------------------------------------------------------+ +// +// $Id: _parse_proppatch.php,v 1.3 2004/01/05 12:41:34 hholzgra Exp $ +// + +/** + * helper class for parsing PROPPATCH request bodies + * + * @package HTTP_WebDAV_Server + * @author Hartmut Holzgraefe + * @version 0.99.1dev + */ +class _parse_proppatch +{ + /** + * + * + * @var + * @access + */ + var $success; + + /** + * + * + * @var + * @access + */ + var $props; + + /** + * + * + * @var + * @access + */ + var $depth; + + /** + * + * + * @var + * @access + */ + var $mode; + + /** + * + * + * @var + * @access + */ + var $current; + + /** + * constructor + * + * @param string path of input stream + * @access public + */ + function _parse_proppatch($path) + { + $this->success = true; + + $this->depth = 0; + $this->props = array(); + $had_input = false; + + $f_in = fopen($path, "r"); + if (!$f_in) { + $this->success = false; + return; + } + + $xml_parser = xml_parser_create_ns("UTF-8", " "); + + xml_set_element_handler($xml_parser, + array(&$this, "_startElement"), + array(&$this, "_endElement")); + + xml_set_character_data_handler($xml_parser, + array(&$this, "_data")); + + xml_parser_set_option($xml_parser, + XML_OPTION_CASE_FOLDING, false); + + while($this->success && !feof($f_in)) { + $line = fgets($f_in); + if (is_string($line)) { + $had_input = true; + $this->success &= xml_parse($xml_parser, $line, false); + } + } + + if($had_input) { + $this->success &= xml_parse($xml_parser, "", true); + } + + xml_parser_free($xml_parser); + + fclose($f_in); + } + + /** + * tag start handler + * + * @param resource parser + * @param string tag name + * @param array tag attributes + * @return void + * @access private + */ + function _startElement($parser, $name, $attrs) + { + if (strstr($name, " ")) { + list($ns, $tag) = explode(" ", $name); + if ($ns == "") + $this->success = false; + } else { + $ns = ""; + $tag = $name; + } + + if ($this->depth == 1) { + $this->mode = $tag; + } + + if ($this->depth == 3) { + $prop = array("name" => $tag); + $this->current = array("name" => $tag, "ns" => $ns, "status"=> 200); + if ($this->mode == "set") { + $this->current["val"] = ""; // default set val + } + } + + if ($this->depth >= 4) { + $this->current["val"] .= "<$tag"; + foreach ($attr as $key => $val) { + $this->current["val"] .= ' '.$key.'="'.str_replace('"','"', $val).'"'; + } + $this->current["val"] .= ">"; + } + + + + $this->depth++; + } + + /** + * tag end handler + * + * @param resource parser + * @param string tag name + * @return void + * @access private + */ + function _endElement($parser, $name) + { + if (strstr($name, " ")) { + list($ns, $tag) = explode(" ", $name); + if ($ns == "") + $this->success = false; + } else { + $ns = ""; + $tag = $name; + } + + $this->depth--; + + if ($this->depth >= 4) { + $this->current["val"] .= ""; + } + + if ($this->depth == 3) { + if (isset($this->current)) { + $this->props[] = $this->current; + unset($this->current); + } + } + } + + /** + * input data handler + * + * @param resource parser + * @param string data + * @return void + * @access private + */ + function _data($parser, $data) { + if (isset($this->current)) { + $this->current["val"] .= $data; + } + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Log.php b/gulliver/thirdparty/pear/Log.php new file mode 100644 index 000000000..51891a0ec --- /dev/null +++ b/gulliver/thirdparty/pear/Log.php @@ -0,0 +1,832 @@ + + * @author Jon Parise + * @since Horde 1.3 + * @package Log + */ +class Log +{ + /** + * Indicates whether or not the log can been opened / connected. + * + * @var boolean + * @access protected + */ + var $_opened = false; + + /** + * Instance-specific unique identification number. + * + * @var integer + * @access protected + */ + var $_id = 0; + + /** + * The label that uniquely identifies this set of log messages. + * + * @var string + * @access protected + */ + var $_ident = ''; + + /** + * The default priority to use when logging an event. + * + * @var integer + * @access protected + */ + var $_priority = PEAR_LOG_INFO; + + /** + * The bitmask of allowed log levels. + * + * @var integer + * @access protected + */ + var $_mask = PEAR_LOG_ALL; + + /** + * Holds all Log_observer objects that wish to be notified of new messages. + * + * @var array + * @access protected + */ + var $_listeners = array(); + + /** + * Maps canonical format keys to position arguments for use in building + * "line format" strings. + * + * @var array + * @access protected + */ + var $_formatMap = array('%{timestamp}' => '%1$s', + '%{ident}' => '%2$s', + '%{priority}' => '%3$s', + '%{message}' => '%4$s', + '%{file}' => '%5$s', + '%{line}' => '%6$s', + '%{function}' => '%7$s', + '%\{' => '%%{'); + + + /** + * Attempts to return a concrete Log instance of type $handler. + * + * @param string $handler The type of concrete Log subclass to return. + * Attempt to dynamically include the code for + * this subclass. Currently, valid values are + * 'console', 'syslog', 'sql', 'file', and 'mcal'. + * + * @param string $name The name of the actually log file, table, or + * other specific store to use. Defaults to an + * empty string, with which the subclass will + * attempt to do something intelligent. + * + * @param string $ident The identity reported to the log system. + * + * @param array $conf A hash containing any additional configuration + * information that a subclass might need. + * + * @param int $level Log messages up to and including this level. + * + * @return object Log The newly created concrete Log instance, or + * null on an error. + * @access public + * @since Log 1.0 + */ + function &factory($handler, $name = '', $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $handler = strtolower($handler); + $class = 'Log_' . $handler; + $classfile = 'Log/' . $handler . '.php'; + + /* + * Attempt to include our version of the named class, but don't treat + * a failure as fatal. The caller may have already included their own + * version of the named class. + */ + if (!class_exists($class, false)) { + include_once $classfile; + } + + /* If the class exists, return a new instance of it. */ + if (class_exists($class, false)) { + $obj = &new $class($name, $ident, $conf, $level); + return $obj; + } + + $null = null; + return $null; + } + + /** + * Attempts to return a reference to a concrete Log instance of type + * $handler, only creating a new instance if no log instance with the same + * parameters currently exists. + * + * You should use this if there are multiple places you might create a + * logger, you don't want to create multiple loggers, and you don't want to + * check for the existance of one each time. The singleton pattern does all + * the checking work for you. + * + * You MUST call this method with the $var = &Log::singleton() syntax. + * Without the ampersand (&) in front of the method name, you will not get + * a reference, you will get a copy. + * + * @param string $handler The type of concrete Log subclass to return. + * Attempt to dynamically include the code for + * this subclass. Currently, valid values are + * 'console', 'syslog', 'sql', 'file', and 'mcal'. + * + * @param string $name The name of the actually log file, table, or + * other specific store to use. Defaults to an + * empty string, with which the subclass will + * attempt to do something intelligent. + * + * @param string $ident The identity reported to the log system. + * + * @param array $conf A hash containing any additional configuration + * information that a subclass might need. + * + * @param int $level Log messages up to and including this level. + * + * @return object Log The newly created concrete Log instance, or + * null on an error. + * @access public + * @since Log 1.0 + */ + function &singleton($handler, $name = '', $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + static $instances; + if (!isset($instances)) $instances = array(); + + $signature = serialize(array($handler, $name, $ident, $conf, $level)); + if (!isset($instances[$signature])) { + $instances[$signature] = &Log::factory($handler, $name, $ident, + $conf, $level); + } + + return $instances[$signature]; + } + + /** + * Abstract implementation of the open() method. + * @since Log 1.0 + */ + function open() + { + return false; + } + + /** + * Abstract implementation of the close() method. + * @since Log 1.0 + */ + function close() + { + return false; + } + + /** + * Abstract implementation of the flush() method. + * @since Log 1.8.2 + */ + function flush() + { + return false; + } + + /** + * Abstract implementation of the log() method. + * @since Log 1.0 + */ + function log($message, $priority = null) + { + return false; + } + + /** + * A convenience function for logging a emergency event. It will log a + * message at the PEAR_LOG_EMERG log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function emerg($message) + { + return $this->log($message, PEAR_LOG_EMERG); + } + + /** + * A convenience function for logging an alert event. It will log a + * message at the PEAR_LOG_ALERT log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function alert($message) + { + return $this->log($message, PEAR_LOG_ALERT); + } + + /** + * A convenience function for logging a critical event. It will log a + * message at the PEAR_LOG_CRIT log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function crit($message) + { + return $this->log($message, PEAR_LOG_CRIT); + } + + /** + * A convenience function for logging a error event. It will log a + * message at the PEAR_LOG_ERR log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function err($message) + { + return $this->log($message, PEAR_LOG_ERR); + } + + /** + * A convenience function for logging a warning event. It will log a + * message at the PEAR_LOG_WARNING log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function warning($message) + { + return $this->log($message, PEAR_LOG_WARNING); + } + + /** + * A convenience function for logging a notice event. It will log a + * message at the PEAR_LOG_NOTICE log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function notice($message) + { + return $this->log($message, PEAR_LOG_NOTICE); + } + + /** + * A convenience function for logging a information event. It will log a + * message at the PEAR_LOG_INFO log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function info($message) + { + return $this->log($message, PEAR_LOG_INFO); + } + + /** + * A convenience function for logging a debug event. It will log a + * message at the PEAR_LOG_DEBUG log level. + * + * @param mixed $message String or object containing the message + * to log. + * + * @return boolean True if the message was successfully logged. + * + * @access public + * @since Log 1.7.0 + */ + function debug($message) + { + return $this->log($message, PEAR_LOG_DEBUG); + } + + /** + * Returns the string representation of the message data. + * + * If $message is an object, _extractMessage() will attempt to extract + * the message text using a known method (such as a PEAR_Error object's + * getMessage() method). If a known method, cannot be found, the + * serialized representation of the object will be returned. + * + * If the message data is already a string, it will be returned unchanged. + * + * @param mixed $message The original message data. This may be a + * string or any object. + * + * @return string The string representation of the message. + * + * @access protected + */ + function _extractMessage($message) + { + /* + * If we've been given an object, attempt to extract the message using + * a known method. If we can't find such a method, default to the + * "human-readable" version of the object. + * + * We also use the human-readable format for arrays. + */ + if (is_object($message)) { + if (method_exists($message, 'getmessage')) { + $message = $message->getMessage(); + } else if (method_exists($message, 'tostring')) { + $message = $message->toString(); + } else if (method_exists($message, '__tostring')) { + if (version_compare(PHP_VERSION, '5.0.0', 'ge')) { + $message = (string)$message; + } else { + $message = $message->__toString(); + } + } else { + $message = print_r($message, true); + } + } else if (is_array($message)) { + if (isset($message['message'])) { + $message = $message['message']; + } else { + $message = print_r($message, true); + } + } + + /* Otherwise, we assume the message is a string. */ + return $message; + } + + /** + * Using debug_backtrace(), returns the file, line, and enclosing function + * name of the source code context from which log() was invoked. + * + * @param int $depth The initial number of frames we should step + * back into the trace. + * + * @return array Array containing three strings: the filename, the line, + * and the function name from which log() was called. + * + * @access private + * @since Log 1.9.4 + */ + function _getBacktraceVars($depth) + { + /* Start by generating a backtrace from the current call (here). */ + $backtrace = debug_backtrace(); + + /* + * If we were ultimately invoked by the composite handler, we need to + * increase our depth one additional level to compensate. + */ + if (strcasecmp(@$backtrace[$depth+1]['class'], 'Log_composite') == 0) { + $depth++; + } + + /* + * We're interested in the frame which invoked the log() function, so + * we need to walk back some number of frames into the backtrace. The + * $depth parameter tells us where to start looking. We go one step + * further back to find the name of the encapsulating function from + * which log() was called. + */ + $file = @$backtrace[$depth]['file']; + $line = @$backtrace[$depth]['line']; + $func = @$backtrace[$depth + 1]['function']; + + /* + * However, if log() was called from one of our "shortcut" functions, + * we're going to need to go back an additional step. + */ + if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning', + 'notice', 'info', 'debug'))) { + $file = @$backtrace[$depth + 1]['file']; + $line = @$backtrace[$depth + 1]['line']; + $func = @$backtrace[$depth + 2]['function']; + } + + /* + * If we couldn't extract a function name (perhaps because we were + * executed from the "main" context), provide a default value. + */ + if (is_null($func)) { + $func = '(none)'; + } + $functions = ''; + for ( $i = count(@$backtrace) -1 ; $i > 2 ; $i-- ) { + $parts = explode ( PATH_SEP, @$backtrace[$i]['file']); + $filename = $parts [ count($parts) -1] . ':' . @$backtrace[$i]['line'] . ':'; + $functions .= $filename. @$backtrace[$i]['function'] . '()->'; + } + + /* Return a 4-tuple containing (file, line, function). */ + return array($file, $line, $func, $functions); + } + + /** + * Produces a formatted log line based on a format string and a set of + * variables representing the current log record and state. + * + * @return string Formatted log string. + * + * @access protected + * @since Log 1.9.4 + */ + function _format($format, $timestamp, $priority, $message) + { + /* + * If the format string references any of the backtrace-driven + * variables (%5, %6, %7), generate the backtrace and fetch them. + */ + if (strpos($format, '%5') || strpos($format, '%6') || strpos($format, '%7')) { + list($file, $line, $func) = $this->_getBacktraceVars(2); + } + + /* + * Build the formatted string. We use the sprintf() function's + * "argument swapping" capability to dynamically select and position + * the variables which will ultimately appear in the log string. + */ + return sprintf($format, + $timestamp, + $this->_ident, + $this->priorityToString($priority), + $message, + isset($file) ? $file : '', + isset($line) ? $line : '', + isset($func) ? $func : ''); + } + + /** + * Returns the string representation of a PEAR_LOG_* integer constant. + * + * @param int $priority A PEAR_LOG_* integer constant. + * + * @return string The string representation of $level. + * + * @access public + * @since Log 1.0 + */ + function priorityToString($priority) + { + $levels = array( + PEAR_LOG_EMERG => 'emergency', + PEAR_LOG_ALERT => 'alert', + PEAR_LOG_CRIT => 'critical', + PEAR_LOG_ERR => 'error', + PEAR_LOG_WARNING => 'warning', + PEAR_LOG_NOTICE => 'notice', + PEAR_LOG_INFO => 'info', + PEAR_LOG_DEBUG => 'debug' + ); + + return $levels[$priority]; + } + + /** + * Returns the the PEAR_LOG_* integer constant for the given string + * representation of a priority name. This function performs a + * case-insensitive search. + * + * @param string $name String containing a priority name. + * + * @return string The PEAR_LOG_* integer contstant corresponding + * the the specified priority name. + * + * @access public + * @since Log 1.9.0 + */ + function stringToPriority($name) + { + $levels = array( + 'emergency' => PEAR_LOG_EMERG, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG + ); + + return $levels[strtolower($name)]; + } + + /** + * Calculate the log mask for the given priority. + * + * This method may be called statically. + * + * @param integer $priority The priority whose mask will be calculated. + * + * @return integer The calculated log mask. + * + * @access public + * @since Log 1.7.0 + */ + function MASK($priority) + { + return (1 << $priority); + } + + /** + * Calculate the log mask for all priorities up to the given priority. + * + * This method may be called statically. + * + * @param integer $priority The maximum priority covered by this mask. + * + * @return integer The resulting log mask. + * + * @access public + * @since Log 1.7.0 + * + * @deprecated deprecated since Log 1.9.4; use Log::MAX() instead + */ + function UPTO($priority) + { + return Log::MAX($priority); + } + + /** + * Calculate the log mask for all priorities greater than or equal to the + * given priority. In other words, $priority will be the lowest priority + * matched by the resulting mask. + * + * This method may be called statically. + * + * @param integer $priority The minimum priority covered by this mask. + * + * @return integer The resulting log mask. + * + * @access public + * @since Log 1.9.4 + */ + function MIN($priority) + { + return PEAR_LOG_ALL ^ ((1 << $priority) - 1); + } + + /** + * Calculate the log mask for all priorities less than or equal to the + * given priority. In other words, $priority will be the highests priority + * matched by the resulting mask. + * + * This method may be called statically. + * + * @param integer $priority The maximum priority covered by this mask. + * + * @return integer The resulting log mask. + * + * @access public + * @since Log 1.9.4 + */ + function MAX($priority) + { + return ((1 << ($priority + 1)) - 1); + } + + /** + * Set and return the level mask for the current Log instance. + * + * @param integer $mask A bitwise mask of log levels. + * + * @return integer The current level mask. + * + * @access public + * @since Log 1.7.0 + */ + function setMask($mask) + { + $this->_mask = $mask; + + return $this->_mask; + } + + /** + * Returns the current level mask. + * + * @return interger The current level mask. + * + * @access public + * @since Log 1.7.0 + */ + function getMask() + { + return $this->_mask; + } + + /** + * Check if the given priority is included in the current level mask. + * + * @param integer $priority The priority to check. + * + * @return boolean True if the given priority is included in the current + * log mask. + * + * @access protected + * @since Log 1.7.0 + */ + function _isMasked($priority) + { + return (Log::MASK($priority) & $this->_mask); + } + + /** + * Returns the current default priority. + * + * @return integer The current default priority. + * + * @access public + * @since Log 1.8.4 + */ + function getPriority() + { + return $this->_priority; + } + + /** + * Sets the default priority to the specified value. + * + * @param integer $priority The new default priority. + * + * @access public + * @since Log 1.8.4 + */ + function setPriority($priority) + { + $this->_priority = $priority; + } + + /** + * Adds a Log_observer instance to the list of observers that are listening + * for messages emitted by this Log instance. + * + * @param object $observer The Log_observer instance to attach as a + * listener. + * + * @param boolean True if the observer is successfully attached. + * + * @access public + * @since Log 1.0 + */ + function attach(&$observer) + { + if (!is_a($observer, 'Log_observer')) { + return false; + } + + $this->_listeners[$observer->_id] = &$observer; + + return true; + } + + /** + * Removes a Log_observer instance from the list of observers. + * + * @param object $observer The Log_observer instance to detach from + * the list of listeners. + * + * @param boolean True if the observer is successfully detached. + * + * @access public + * @since Log 1.0 + */ + function detach($observer) + { + if (!is_a($observer, 'Log_observer') || + !isset($this->_listeners[$observer->_id])) { + return false; + } + + unset($this->_listeners[$observer->_id]); + + return true; + } + + /** + * Informs each registered observer instance that a new message has been + * logged. + * + * @param array $event A hash describing the log event. + * + * @access protected + */ + function _announce($event) + { + foreach ($this->_listeners as $id => $listener) { + if ($event['priority'] <= $this->_listeners[$id]->_priority) { + $this->_listeners[$id]->notify($event); + } + } + } + + /** + * Indicates whether this is a composite class. + * + * @return boolean True if this is a composite class. + * + * @access public + * @since Log 1.0 + */ + function isComposite() + { + return false; + } + + /** + * Sets this Log instance's identification string. + * + * @param string $ident The new identification string. + * + * @access public + * @since Log 1.6.3 + */ + function setIdent($ident) + { + $this->_ident = $ident; + } + + /** + * Returns the current identification string. + * + * @return string The current Log instance's identification string. + * + * @access public + * @since Log 1.6.3 + */ + function getIdent() + { + return $this->_ident; + } +} diff --git a/gulliver/thirdparty/pear/Log/composite.php b/gulliver/thirdparty/pear/Log/composite.php new file mode 100644 index 000000000..98a1d814c --- /dev/null +++ b/gulliver/thirdparty/pear/Log/composite.php @@ -0,0 +1,231 @@ + + * @author Jon Parise + * + * @since Horde 1.3 + * @since Log 1.0 + * @package Log + * + * @example composite.php Using the composite handler. + */ +class Log_composite extends Log +{ + /** + * Array holding all of the Log instances to which log events should be + * sent. + * + * @var array + * @access private + */ + var $_children = array(); + + + /** + * Constructs a new composite Log object. + * + * @param boolean $name This parameter is ignored. + * @param boolean $ident This parameter is ignored. + * @param boolean $conf This parameter is ignored. + * @param boolean $level This parameter is ignored. + * + * @access public + */ + function Log_composite($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_ident = $ident; + } + + /** + * Opens all of the child instances. + * + * @return True if all of the child instances were successfully opened. + * + * @access public + */ + function open() + { + /* Attempt to open each of our children. */ + $this->_opened = true; + foreach ($this->_children as $id => $child) { + $this->_opened &= $this->_children[$id]->open(); + } + + /* If all children were opened, return success. */ + return $this->_opened; + } + + /** + * Closes all of the child instances. + * + * @return True if all of the child instances were successfully closed. + * + * @access public + */ + function close() + { + /* Attempt to close each of our children. */ + $closed = true; + foreach ($this->_children as $id => $child) { + $closed &= $this->_children[$id]->close(); + } + + /* Track the _opened state for consistency. */ + $this->_opened = false; + + /* If all children were closed, return success. */ + return $closed; + } + + /** + * Flushes all child instances. It is assumed that all of the children + * have been successfully opened. + * + * @return True if all of the child instances were successfully flushed. + * + * @access public + * @since Log 1.8.2 + */ + function flush() + { + /* Attempt to flush each of our children. */ + $flushed = true; + foreach ($this->_children as $id => $child) { + $flushed &= $this->_children[$id]->flush(); + } + + /* If all children were flushed, return success. */ + return $flushed; + } + + /** + * Sends $message and $priority to each child of this composite. If the + * children aren't already open, they will be opened here. + * + * @param mixed $message String or object containing the message + * to log. + * @param string $priority (optional) The priority of the message. + * Valid values are: PEAR_LOG_EMERG, + * PEAR_LOG_ALERT, PEAR_LOG_CRIT, + * PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and + * PEAR_LOG_DEBUG. + * + * @return boolean True if the entry is successfully logged. + * + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* + * If the handlers haven't been opened, attempt to open them now. + * However, we don't treat failure to open all of the handlers as a + * fatal error. We defer that consideration to the success of calling + * each handler's log() method below. + */ + if (!$this->_opened) { + $this->open(); + } + + /* Attempt to log the event using each of the children. */ + $success = true; + foreach ($this->_children as $id => $child) { + $success &= $this->_children[$id]->log($message, $priority); + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + /* Return success if all of the children logged the event. */ + return $success; + } + + /** + * Returns true if this is a composite. + * + * @return boolean True if this is a composite class. + * + * @access public + */ + function isComposite() + { + return true; + } + + /** + * Sets this identification string for all of this composite's children. + * + * @param string $ident The new identification string. + * + * @access public + * @since Log 1.6.7 + */ + function setIdent($ident) + { + /* Call our base class's setIdent() method. */ + parent::setIdent($ident); + + /* ... and then call setIdent() on all of our children. */ + foreach ($this->_children as $id => $child) { + $this->_children[$id]->setIdent($ident); + } + } + + /** + * Adds a Log instance to the list of children. + * + * @param object $child The Log instance to add. + * + * @return boolean True if the Log instance was successfully added. + * + * @access public + */ + function addChild(&$child) + { + /* Make sure this is a Log instance. */ + if (!is_a($child, 'Log')) { + return false; + } + + $this->_children[$child->_id] = &$child; + + return true; + } + + /** + * Removes a Log instance from the list of children. + * + * @param object $child The Log instance to remove. + * + * @return boolean True if the Log instance was successfully removed. + * + * @access public + */ + function removeChild($child) + { + if (!is_a($child, 'Log') || !isset($this->_children[$child->_id])) { + return false; + } + + unset($this->_children[$child->_id]); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/console.php b/gulliver/thirdparty/pear/Log/console.php new file mode 100644 index 000000000..0c1f9b685 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/console.php @@ -0,0 +1,208 @@ + + * @since Log 1.1 + * @package Log + * + * @example console.php Using the console handler. + */ +class Log_console extends Log +{ + /** + * Handle to the current output stream. + * @var resource + * @access private + */ + var $_stream = STDOUT; + + /** + * Should the output be buffered or displayed immediately? + * @var string + * @access private + */ + var $_buffering = false; + + /** + * String holding the buffered output. + * @var string + * @access private + */ + var $_buffer = ''; + + /** + * String containing the format of a log line. + * @var string + * @access private + */ + var $_lineFormat = '%1$s %2$s [%3$s] %4$s'; + + /** + * String containing the timestamp format. It will be passed directly to + * strftime(). Note that the timestamp string will generated using the + * current locale. + * @var string + * @access private + */ + var $_timeFormat = '%b %d %H:%M:%S'; + + /** + * Constructs a new Log_console object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_console($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (!empty($conf['stream'])) { + $this->_stream = $conf['stream']; + } + + if (isset($conf['buffering'])) { + $this->_buffering = $conf['buffering']; + } + + if (!empty($conf['lineFormat'])) { + $this->_lineFormat = str_replace(array_keys($this->_formatMap), + array_values($this->_formatMap), + $conf['lineFormat']); + } + + if (!empty($conf['timeFormat'])) { + $this->_timeFormat = $conf['timeFormat']; + } + + /* + * If output buffering has been requested, we need to register a + * shutdown function that will dump the buffer upon termination. + */ + if ($this->_buffering) { + register_shutdown_function(array(&$this, '_Log_console')); + } + } + + /** + * Destructor + */ + function _Log_console() + { + $this->close(); + } + + /** + * Open the output stream. + * + * @access public + * @since Log 1.9.7 + */ + function open() + { + $this->_opened = true; + return true; + } + + /** + * Closes the output stream. + * + * This results in a call to flush(). + * + * @access public + * @since Log 1.9.0 + */ + function close() + { + $this->flush(); + $this->_opened = false; + return true; + } + + /** + * Flushes all pending ("buffered") data to the output stream. + * + * @access public + * @since Log 1.8.2 + */ + function flush() + { + /* + * If output buffering is enabled, dump the contents of the buffer to + * the output stream. + */ + if ($this->_buffering && (strlen($this->_buffer) > 0)) { + fwrite($this->_stream, $this->_buffer); + $this->_buffer = ''; + } + + if (is_resource($this->_stream)) { + return fflush($this->_stream); + } + + return false; + } + + /** + * Writes $message to the text console. Also, passes the message + * along to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build the string containing the complete log line. */ + $line = $this->_format($this->_lineFormat, + strftime($this->_timeFormat), + $priority, $message) . "\n"; + + /* + * If buffering is enabled, append this line to the output buffer. + * Otherwise, print the line to the output stream immediately. + */ + if ($this->_buffering) { + $this->_buffer .= $line; + } else { + fwrite($this->_stream, $line); + } + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/daemon.php b/gulliver/thirdparty/pear/Log/daemon.php new file mode 100644 index 000000000..9873f2a40 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/daemon.php @@ -0,0 +1,230 @@ + + * @version $Revision: 1.2 $ + * @package Log + */ +class Log_daemon extends Log +{ + /** + * Integer holding the log facility to use. + * @var string + */ + var $_name = LOG_DAEMON; + + /** + * Var holding the resource pointer to the socket + * @var resource + */ + var $_socket; + + /** + * The ip address or servername + * @see http://www.php.net/manual/en/transports.php + * @var string + */ + var $_ip = '127.0.0.1'; + + /** + * Protocol to use (tcp, udp, etc.) + * @see http://www.php.net/manual/en/transports.php + * @var string + */ + var $_proto = 'udp'; + + /** + * Port to connect to + * @var int + */ + var $_port = 514; + + /** + * Maximum message length in bytes + * @var int + */ + var $_maxsize = 4096; + + /** + * Socket timeout in seconds + * @var int + */ + var $_timeout = 1; + + + /** + * Constructs a new syslog object. + * + * @param string $name The syslog facility. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $maxLevel Maximum level at which to log. + * @access public + */ + function Log_daemon($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + /* Ensure we have a valid integer value for $name. */ + if (empty($name) || !is_int($name)) { + $name = LOG_SYSLOG; + } + + $this->_id = md5(microtime()); + $this->_name = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (isset($conf['ip'])) { + $this->_ip = $conf['ip']; + } + if (isset($conf['proto'])) { + $this->_proto = $conf['proto']; + } + if (isset($conf['port'])) { + $this->_port = $conf['port']; + } + if (isset($conf['maxsize'])) { + $this->_maxsize = $conf['maxsize']; + } + if (isset($conf['timeout'])) { + $this->_timeout = $conf['timeout']; + } + $this->_proto = $this->_proto . '://'; + + register_shutdown_function(array(&$this, '_Log_daemon')); + } + + /** + * Destructor. + * + * @access private + */ + function _Log_daemon() + { + $this->close(); + } + + /** + * Opens a connection to the system logger, if it has not already + * been opened. This is implicitly called by log(), if necessary. + * @access public + */ + function open() + { + if (!$this->_opened) { + $this->_opened = (bool)($this->_socket = @fsockopen( + $this->_proto . $this->_ip, + $this->_port, + $errno, + $errstr, + $this->_timeout)); + } + return $this->_opened; + } + + /** + * Closes the connection to the system logger, if it is open. + * @access public + */ + function close() + { + if ($this->_opened) { + $this->_opened = false; + return fclose($this->_socket); + } + return true; + } + + /** + * Sends $message to the currently open syslog connection. Calls + * open() if necessary. Also passes the message along to any Log_observer + * instances that are observing this Log. + * + * @param string $message The textual message to be logged. + * @param int $priority (optional) The priority of the message. Valid + * values are: LOG_EMERG, LOG_ALERT, LOG_CRIT, + * LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, + * and LOG_DEBUG. The default is LOG_INFO. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Set the facility level. */ + $facility_level = intval($this->_name) + + intval($this->_toSyslog($priority)); + + /* Prepend ident info. */ + if (!empty($this->_ident)) { + $message = $this->_ident . ' ' . $message; + } + + /* Check for message length. */ + if (strlen($message) > $this->_maxsize) { + $message = substr($message, 0, ($this->_maxsize) - 10) . ' [...]'; + } + + /* Write to socket. */ + fwrite($this->_socket, '<' . $facility_level . '>' . $message . "\n"); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + } + + /** + * Converts a PEAR_LOG_* constant into a syslog LOG_* constant. + * + * This function exists because, under Windows, not all of the LOG_* + * constants have unique values. Instead, the PEAR_LOG_* were introduced + * for global use, with the conversion to the LOG_* constants kept local to + * to the syslog driver. + * + * @param int $priority PEAR_LOG_* value to convert to LOG_* value. + * + * @return The LOG_* representation of $priority. + * + * @access private + */ + function _toSyslog($priority) + { + static $priorities = array( + PEAR_LOG_EMERG => LOG_EMERG, + PEAR_LOG_ALERT => LOG_ALERT, + PEAR_LOG_CRIT => LOG_CRIT, + PEAR_LOG_ERR => LOG_ERR, + PEAR_LOG_WARNING => LOG_WARNING, + PEAR_LOG_NOTICE => LOG_NOTICE, + PEAR_LOG_INFO => LOG_INFO, + PEAR_LOG_DEBUG => LOG_DEBUG + ); + + /* If we're passed an unknown priority, default to LOG_INFO. */ + if (!is_int($priority) || !in_array($priority, $priorities)) { + return LOG_INFO; + } + + return $priorities[$priority]; + } + +} diff --git a/gulliver/thirdparty/pear/Log/display.php b/gulliver/thirdparty/pear/Log/display.php new file mode 100644 index 000000000..31ad1e7da --- /dev/null +++ b/gulliver/thirdparty/pear/Log/display.php @@ -0,0 +1,141 @@ + + * @since Log 1.8.0 + * @package Log + * + * @example display.php Using the display handler. + */ +class Log_display extends Log +{ + /** + * String to output before an error message + * @var string + * @access private + */ + var $_error_prepend = ''; + + /** + * String to output after an error message + * @var string + * @access private + */ + var $_error_append = ''; + + /** + * String used to represent a line break. + * @var string + * @access private + */ + var $_linebreak = "
    \n"; + + /** + * Constructs a new Log_display object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_display($name = '', $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (isset($conf['error_prepend'])) { + $this->_error_prepend = $conf['error_prepend']; + } else { + $this->_error_prepend = ini_get('error_prepend_string'); + } + + if (isset($conf['error_append'])) { + $this->_error_append = $conf['error_append']; + } else { + $this->_error_append = ini_get('error_append_string'); + } + + if (isset($conf['linebreak'])) { + $this->_linebreak = $conf['linebreak']; + } + } + + /** + * Opens the display handler. + * + * @access public + * @since Log 1.9.6 + */ + function open() + { + $this->_opened = true; + return true; + } + + /** + * Closes the display handler. + * + * @access public + * @since Log 1.9.6 + */ + function close() + { + $this->_opened = false; + return true; + } + + /** + * Writes $message to the text browser. Also, passes the message + * along to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build and output the complete log line. */ + echo $this->_error_prepend . + '' . ucfirst($this->priorityToString($priority)) . ': '. + nl2br(htmlspecialchars($message)) . + $this->_error_append . $this->_linebreak; + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/error_log.php b/gulliver/thirdparty/pear/Log/error_log.php new file mode 100644 index 000000000..117e96c48 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/error_log.php @@ -0,0 +1,127 @@ + + * @since Log 1.7.0 + * @package Log + * + * @example error_log.php Using the error_log handler. + */ +class Log_error_log extends Log +{ + /** + * The error_log() log type. + * @var integer + * @access private + */ + var $_type = PEAR_LOG_TYPE_SYSTEM; + + /** + * The type-specific destination value. + * @var string + * @access private + */ + var $_destination = ''; + + /** + * Additional headers to pass to the mail() function when the + * PEAR_LOG_TYPE_MAIL type is used. + * @var string + * @access private + */ + var $_extra_headers = ''; + + /** + * Constructs a new Log_error_log object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_error_log($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_type = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (!empty($conf['destination'])) { + $this->_destination = $conf['destination']; + } + if (!empty($conf['extra_headers'])) { + $this->_extra_headers = $conf['extra_headers']; + } + } + + /** + * Opens the handler. + * + * @access public + * @since Log 1.9.6 + */ + function open() + { + $this->_opened = true; + return true; + } + + /** + * Closes the handler. + * + * @access public + * @since Log 1.9.6 + */ + function close() + { + $this->_opened = false; + return true; + } + + /** + * Logs $message using PHP's error_log() function. The message is also + * passed along to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + $success = error_log($this->_ident . ': ' . $message, $this->_type, + $this->_destination, $this->_extra_headers); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return $success; + } + +} diff --git a/gulliver/thirdparty/pear/Log/file.php b/gulliver/thirdparty/pear/Log/file.php new file mode 100644 index 000000000..0d4f37b08 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/file.php @@ -0,0 +1,322 @@ + + * @author Roman Neuhauser + * @since Log 1.0 + * @package Log + * + * @example file.php Using the file handler. + */ +class Log_file extends Log +{ + /** + * String containing the name of the log file. + * @var string + * @access private + */ + var $_filename = 'php.log'; + + /** + * Handle to the log file. + * @var resource + * @access private + */ + var $_fp = false; + + /** + * Should new log entries be append to an existing log file, or should the + * a new log file overwrite an existing one? + * @var boolean + * @access private + */ + var $_append = true; + + /** + * Should advisory file locking (i.e., flock()) be used? + * @var boolean + * @access private + */ + var $_locking = false; + + /** + * Integer (in octal) containing the log file's permissions mode. + * @var integer + * @access private + */ + var $_mode = 0644; + + /** + * Integer (in octal) specifying the file permission mode that will be + * used when creating directories that do not already exist. + * @var integer + * @access private + */ + var $_dirmode = 0755; + + /** + * String containing the format of a log line. + * @var string + * @access private + */ + var $_lineFormat = '%1$s %2$s [%3$s] %4$s'; + + /** + * String containing the timestamp format. It will be passed directly to + * strftime(). Note that the timestamp string will generated using the + * current locale. + * @var string + * @access private + */ + var $_timeFormat = '%b %d %H:%M:%S'; + + /** + * String containing the end-on-line character sequence. + * @var string + * @access private + */ + var $_eol = "\n"; + + /** + * Constructs a new Log_file object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_file($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_filename = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (isset($conf['append'])) { + $this->_append = $conf['append']; + } + + if (isset($conf['locking'])) { + $this->_locking = $conf['locking']; + } + + if (!empty($conf['mode'])) { + if (is_string($conf['mode'])) { + $this->_mode = octdec($conf['mode']); + } else { + $this->_mode = $conf['mode']; + } + } + + if (!empty($conf['dirmode'])) { + if (is_string($conf['dirmode'])) { + $this->_dirmode = octdec($conf['dirmode']); + } else { + $this->_dirmode = $conf['dirmode']; + } + } + + if (!empty($conf['lineFormat'])) { + $this->_lineFormat = str_replace(array_keys($this->_formatMap), + array_values($this->_formatMap), + $conf['lineFormat']); + } + + if (!empty($conf['timeFormat'])) { + $this->_timeFormat = $conf['timeFormat']; + } + + if (!empty($conf['eol'])) { + $this->_eol = $conf['eol']; + } else { + $this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n"; + } + + register_shutdown_function(array(&$this, '_Log_file')); + } + + /** + * Destructor + */ + function _Log_file() + { + if ($this->_opened) { + $this->close(); + } + } + + /** + * Creates the given directory path. If the parent directories don't + * already exist, they will be created, too. + * + * This implementation is inspired by Python's os.makedirs function. + * + * @param string $path The full directory path to create. + * @param integer $mode The permissions mode with which the + * directories will be created. + * + * @return True if the full path is successfully created or already + * exists. + * + * @access private + */ + function _mkpath($path, $mode = 0700) + { + /* Separate the last pathname component from the rest of the path. */ + $head = dirname($path); + $tail = basename($path); + + /* Make sure we've split the path into two complete components. */ + if (empty($tail)) { + $head = dirname($path); + $tail = basename($path); + } + + /* Recurse up the path if our current segment does not exist. */ + if (!empty($head) && !empty($tail) && !is_dir($head)) { + $this->_mkpath($head, $mode); + } + + /* Create this segment of the path. */ + return @mkdir($head, $mode); + } + + /** + * Opens the log file for output. If the specified log file does not + * already exist, it will be created. By default, new log entries are + * appended to the end of the log file. + * + * This is implicitly called by log(), if necessary. + * + * @access public + */ + function open() + { + if (!$this->_opened) { + /* If the log file's directory doesn't exist, create it. */ + if (!is_dir(dirname($this->_filename))) { + $this->_mkpath($this->_filename, $this->_dirmode); + } + + /* Determine whether the log file needs to be created. */ + $creating = !file_exists($this->_filename); + + /* Obtain a handle to the log file. */ + $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w'); + + /* We consider the file "opened" if we have a valid file pointer. */ + $this->_opened = ($this->_fp !== false); + + /* Attempt to set the file's permissions if we just created it. */ + if ($creating && $this->_opened) { + chmod($this->_filename, $this->_mode); + } + } + + return $this->_opened; + } + + /** + * Closes the log file if it is open. + * + * @access public + */ + function close() + { + /* If the log file is open, close it. */ + if ($this->_opened && fclose($this->_fp)) { + $this->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * Flushes all pending data to the file handle. + * + * @access public + * @since Log 1.8.2 + */ + function flush() + { + if (is_resource($this->_fp)) { + return fflush($this->_fp); + } + + return false; + } + + /** + * Logs $message to the output window. The message is also passed along + * to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the log file isn't already open, open it now. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /*********************** change here >> depth value *************/ + $uri = $_SERVER['REQUEST_URI']; + $backTrace = $this->_getBacktraceVars( 5 ); + $trace = " [ $uri -> $backTrace[3] ]"; + /* Build the string containing the complete log line. */ + $t = microtime(true); + $micro = date('H:i:s.') . sprintf("%03d",($t - floor($t)) * 1000); + $line = $this->_format($this->_lineFormat, + $micro . ' ' . getenv('REMOTE_ADDR'), + $priority, $message . $trace ) . $this->_eol; + + /* If locking is enabled, acquire an exclusive lock on the file. */ + if ($this->_locking) { + flock($this->_fp, LOCK_EX); + } + + /* Write the log line to the log file. */ + $success = (fwrite($this->_fp, $line) !== false); + + /* Unlock the file now that we're finished writing to it. */ + if ($this->_locking) { + flock($this->_fp, LOCK_UN); + } + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return $success; + } + +} diff --git a/gulliver/thirdparty/pear/Log/firebug.php b/gulliver/thirdparty/pear/Log/firebug.php new file mode 100644 index 000000000..9f013f684 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/firebug.php @@ -0,0 +1,214 @@ + + * @since Log 1.x.x + * @package Log + * + * @example firebug.php Using the firebug handler. + */ +class Log_firebug extends Log +{ + /** + * Should the output be buffered or displayed immediately? + * @var string + * @access private + */ + var $_buffering = false; + + /** + * String holding the buffered output. + * @var string + * @access private + */ + var $_buffer = array(); + + /** + * String containing the format of a log line. + * @var string + * @access private + */ + var $_lineFormat = '%2$s [%3$s] %4$s'; + + /** + * String containing the timestamp format. It will be passed directly to + * strftime(). Note that the timestamp string will generated using the + * current locale. + * + * Note! Default lineFormat of this driver does not display time. + * + * @var string + * @access private + */ + var $_timeFormat = '%b %d %H:%M:%S'; + + /** + * Mapping of log priorities to Firebug methods. + * @var array + * @access private + */ + var $_methods = array( + PEAR_LOG_EMERG => 'error', + PEAR_LOG_ALERT => 'error', + PEAR_LOG_CRIT => 'error', + PEAR_LOG_ERR => 'error', + PEAR_LOG_WARNING => 'warn', + PEAR_LOG_NOTICE => 'info', + PEAR_LOG_INFO => 'info', + PEAR_LOG_DEBUG => 'debug' + ); + + /** + * Constructs a new Log_firebug object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_firebug($name = '', $ident = 'PHP', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + if (isset($conf['buffering'])) { + $this->_buffering = $conf['buffering']; + } + + if ($this->_buffering) { + register_shutdown_function(array(&$this, '_Log_firebug')); + } + + if (!empty($conf['lineFormat'])) { + $this->_lineFormat = str_replace(array_keys($this->_formatMap), + array_values($this->_formatMap), + $conf['lineFormat']); + } + + if (!empty($conf['timeFormat'])) { + $this->_timeFormat = $conf['timeFormat']; + } + } + + /** + * Opens the firebug handler. + * + * @access public + */ + function open() + { + $this->_opened = true; + return true; + } + + /** + * Destructor + */ + function _Log_firebug() + { + $this->close(); + } + + /** + * Closes the firebug handler. + * + * @access public + */ + function close() + { + $this->flush(); + $this->_opened = false; + return true; + } + + /** + * Flushes all pending ("buffered") data. + * + * @access public + */ + function flush() { + if (count($this->_buffer)) { + print '\n"; + }; + $this->_buffer = array(); + } + + /** + * Writes $message to Firebug console. Also, passes the message + * along to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + $method = $this->_methods[$priority]; + + /* normalize line breaks */ + $message = str_replace("\r\n", "\n", $message); + + /* escape line breaks */ + $message = str_replace("\n", "\\n\\\n", $message); + + /* escape quotes */ + $message = str_replace('"', '\\"', $message); + + /* Build the string containing the complete log line. */ + $line = $this->_format($this->_lineFormat, + strftime($this->_timeFormat), + $priority, + $message); + + if ($this->_buffering) { + $this->_buffer[] = sprintf('console.%s("%s");', $method, $line); + } else { + print '\n"; + } + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/mail.php b/gulliver/thirdparty/pear/Log/mail.php new file mode 100644 index 000000000..d4eea6c67 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/mail.php @@ -0,0 +1,257 @@ + + * @author Jon Parise + * @since Log 1.3 + * @package Log + * + * @example mail.php Using the mail handler. + */ +class Log_mail extends Log +{ + /** + * String holding the recipients' email addresses. Multiple addresses + * should be separated with commas. + * @var string + * @access private + */ + var $_recipients = ''; + + /** + * String holding the sender's email address. + * @var string + * @access private + */ + var $_from = ''; + + /** + * String holding the email's subject. + * @var string + * @access private + */ + var $_subject = '[Log_mail] Log message'; + + /** + * String holding an optional preamble for the log messages. + * @var string + * @access private + */ + var $_preamble = ''; + + /** + * String containing the format of a log line. + * @var string + * @access private + */ + var $_lineFormat = '%1$s %2$s [%3$s] %4$s'; + + /** + * String containing the timestamp format. It will be passed directly to + * strftime(). Note that the timestamp string will generated using the + * current locale. + * @var string + * @access private + */ + var $_timeFormat = '%b %d %H:%M:%S'; + + /** + * String holding the mail message body. + * @var string + * @access private + */ + var $_message = ''; + + /** + * Flag used to indicated that log lines have been written to the message + * body and the message should be sent on close(). + * @var boolean + * @access private + */ + var $_shouldSend = false; + + /** + * Constructs a new Log_mail object. + * + * Here is how you can customize the mail driver with the conf[] hash : + * $conf['from'] : the mail's "From" header line, + * $conf['subject'] : the mail's "Subject" line. + * + * @param string $name The message's recipients. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_mail($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_recipients = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (!empty($conf['from'])) { + $this->_from = $conf['from']; + } else { + $this->_from = ini_get('sendmail_from'); + } + + if (!empty($conf['subject'])) { + $this->_subject = $conf['subject']; + } + + if (!empty($conf['preamble'])) { + $this->_preamble = $conf['preamble']; + } + + if (!empty($conf['lineFormat'])) { + $this->_lineFormat = str_replace(array_keys($this->_formatMap), + array_values($this->_formatMap), + $conf['lineFormat']); + } + + if (!empty($conf['timeFormat'])) { + $this->_timeFormat = $conf['timeFormat']; + } + + /* register the destructor */ + register_shutdown_function(array(&$this, '_Log_mail')); + } + + /** + * Destructor. Calls close(). + * + * @access private + */ + function _Log_mail() + { + $this->close(); + } + + /** + * Starts a new mail message. + * This is implicitly called by log(), if necessary. + * + * @access public + */ + function open() + { + if (!$this->_opened) { + if (!empty($this->_preamble)) { + $this->_message = $this->_preamble . "\r\n\r\n"; + } + $this->_opened = true; + $_shouldSend = false; + } + + return $this->_opened; + } + + /** + * Closes the message, if it is open, and sends the mail. + * This is implicitly called by the destructor, if necessary. + * + * @access public + */ + function close() + { + if ($this->_opened) { + if ($this->_shouldSend && !empty($this->_message)) { + $headers = "From: $this->_from\r\n"; + $headers .= "User-Agent: Log_mail"; + + if (mail($this->_recipients, $this->_subject, $this->_message, + $headers) == false) { + error_log("Log_mail: Failure executing mail()", 0); + return false; + } + + /* Clear the message string now that the email has been sent. */ + $this->_message = ''; + $this->_shouldSend = false; + } + $this->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * Flushes the log output by forcing the email message to be sent now. + * Events that are logged after flush() is called will be appended to a + * new email message. + * + * @access public + * @since Log 1.8.2 + */ + function flush() + { + /* + * It's sufficient to simply call close() to flush the output. + * The next call to log() will cause the handler to be reopened. + */ + return $this->close(); + } + + /** + * Writes $message to the currently open mail message. + * Calls open(), if necessary. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the message isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Append the string containing the complete log line. */ + $this->_message .= $this->_format($this->_lineFormat, + strftime($this->_timeFormat), + $priority, $message) . "\r\n"; + $this->_shouldSend = true; + + /* Notify observers about this log message. */ + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } +} diff --git a/gulliver/thirdparty/pear/Log/mcal.php b/gulliver/thirdparty/pear/Log/mcal.php new file mode 100644 index 000000000..ab88d457e --- /dev/null +++ b/gulliver/thirdparty/pear/Log/mcal.php @@ -0,0 +1,170 @@ + + * @since Horde 1.3 + * @since Log 1.0 + * @package Log + */ +class Log_mcal extends Log +{ + /** + * holding the calendar specification to connect to. + * @var string + * @access private + */ + var $_calendar = '{localhost/mstore}'; + + /** + * holding the username to use. + * @var string + * @access private + */ + var $_username = ''; + + /** + * holding the password to use. + * @var string + * @access private + */ + var $_password = ''; + + /** + * holding the options to pass to the calendar stream. + * @var integer + * @access private + */ + var $_options = 0; + + /** + * ResourceID of the MCAL stream. + * @var string + * @access private + */ + var $_stream = ''; + + /** + * Integer holding the log facility to use. + * @var string + * @access private + */ + var $_name = LOG_SYSLOG; + + + /** + * Constructs a new Log_mcal object. + * + * @param string $name The category to use for our events. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_mcal($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_name = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + $this->_calendar = $conf['calendar']; + $this->_username = $conf['username']; + $this->_password = $conf['password']; + $this->_options = $conf['options']; + } + + /** + * Opens a calendar stream, if it has not already been + * opened. This is implicitly called by log(), if necessary. + * @access public + */ + function open() + { + if (!$this->_opened) { + $this->_stream = mcal_open($this->_calendar, $this->_username, + $this->_password, $this->_options); + $this->_opened = true; + } + + return $this->_opened; + } + + /** + * Closes the calendar stream, if it is open. + * @access public + */ + function close() + { + if ($this->_opened) { + mcal_close($this->_stream); + $this->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * Logs $message and associated information to the currently open + * calendar stream. Calls open() if necessary. Also passes the + * message along to any Log_observer instances that are observing + * this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + $date_str = date('Y:n:j:G:i:s'); + $dates = explode(':', $date_str); + + mcal_event_init($this->_stream); + mcal_event_set_title($this->_stream, $this->_ident); + mcal_event_set_category($this->_stream, $this->_name); + mcal_event_set_description($this->_stream, $message); + mcal_event_add_attribute($this->_stream, 'priority', $priority); + mcal_event_set_start($this->_stream, $dates[0], $dates[1], $dates[2], + $dates[3], $dates[4], $dates[5]); + mcal_event_set_end($this->_stream, $dates[0], $dates[1], $dates[2], + $dates[3], $dates[4], $dates[5]); + mcal_append_event($this->_stream); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/mdb2.php b/gulliver/thirdparty/pear/Log/mdb2.php new file mode 100644 index 000000000..cc06787a3 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/mdb2.php @@ -0,0 +1,358 @@ + + * @author Jon Parise + * @since Log 1.9.0 + * @package Log + */ +class Log_mdb2 extends Log +{ + /** + * Variable containing the DSN information. + * @var mixed + * @access private + */ + var $_dsn = ''; + + /** + * Array containing our set of DB configuration options. + * @var array + * @access private + */ + var $_options = array('persistent' => true); + + /** + * Object holding the database handle. + * @var object + * @access private + */ + var $_db = null; + + /** + * Resource holding the prepared statement handle. + * @var resource + * @access private + */ + var $_statement = null; + + /** + * Flag indicating that we're using an existing database connection. + * @var boolean + * @access private + */ + var $_existingConnection = false; + + /** + * String holding the database table to use. + * @var string + * @access private + */ + var $_table = 'log_table'; + + /** + * String holding the name of the ID sequence. + * @var string + * @access private + */ + var $_sequence = 'log_id'; + + /** + * Maximum length of the $ident string. This corresponds to the size of + * the 'ident' column in the SQL table. + * @var integer + * @access private + */ + var $_identLimit = 16; + + /** + * Set of field types used in the database table. + * @var array + * @access private + */ + var $_types = array( + 'id' => 'integer', + 'logtime' => 'timestamp', + 'ident' => 'text', + 'priority' => 'text', + 'message' => 'clob' + ); + + /** + * Constructs a new sql logging object. + * + * @param string $name The target SQL table. + * @param string $ident The identification field. + * @param array $conf The connection configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_mdb2($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_table = $name; + $this->_mask = Log::UPTO($level); + + /* If an options array was provided, use it. */ + if (isset($conf['options']) && is_array($conf['options'])) { + $this->_options = $conf['options']; + } + + /* If a specific sequence name was provided, use it. */ + if (!empty($conf['sequence'])) { + $this->_sequence = $conf['sequence']; + } + + /* If a specific sequence name was provided, use it. */ + if (isset($conf['identLimit'])) { + $this->_identLimit = $conf['identLimit']; + } + + /* Now that the ident limit is confirmed, set the ident string. */ + $this->setIdent($ident); + + /* If an existing database connection was provided, use it. */ + if (isset($conf['db'])) { + $this->_db = &$conf['db']; + $this->_existingConnection = true; + $this->_opened = true; + } elseif (isset($conf['singleton'])) { + $this->_db = &MDB2::singleton($conf['singleton'], $this->_options); + $this->_existingConnection = true; + $this->_opened = true; + } else { + $this->_dsn = $conf['dsn']; + } + } + + /** + * Opens a connection to the database, if it has not already + * been opened. This is implicitly called by log(), if necessary. + * + * @return boolean True on success, false on failure. + * @access public + */ + function open() + { + if (!$this->_opened) { + /* Use the DSN and options to create a database connection. */ + $this->_db = &MDB2::connect($this->_dsn, $this->_options); + if (PEAR::isError($this->_db)) { + return false; + } + + /* Create a prepared statement for repeated use in log(). */ + if (!$this->_prepareStatement()) { + return false; + } + + /* We now consider out connection open. */ + $this->_opened = true; + } + + return $this->_opened; + } + + /** + * Closes the connection to the database if it is still open and we were + * the ones that opened it. It is the caller's responsible to close an + * existing connection that was passed to us via $conf['db']. + * + * @return boolean True on success, false on failure. + * @access public + */ + function close() + { + /* If we have a statement object, free it. */ + if (is_object($this->_statement)) { + $this->_statement->free(); + $this->_statement = null; + } + + /* If we opened the database connection, disconnect it. */ + if ($this->_opened && !$this->_existingConnection) { + $this->_opened = false; + return $this->_db->disconnect(); + } + + return ($this->_opened === false); + } + + /** + * Sets this Log instance's identification string. Note that this + * SQL-specific implementation will limit the length of the $ident string + * to sixteen (16) characters. + * + * @param string $ident The new identification string. + * + * @access public + * @since Log 1.8.5 + */ + function setIdent($ident) + { + $this->_ident = substr($ident, 0, $this->_identLimit); + } + + /** + * Inserts $message to the currently open database. Calls open(), + * if necessary. Also passes the message along to any Log_observer + * instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* If we don't already have a statement object, create one. */ + if (!is_object($this->_statement) && !$this->_prepareStatement()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build our set of values for this log entry. */ + $values = array( + 'id' => $this->_db->nextId($this->_sequence), + 'logtime' => MDB2_Date::mdbNow(), + 'ident' => $this->_ident, + 'priority' => $priority, + 'message' => $message + ); + + /* Execute the SQL query for this log entry insertion. */ + $this->_db->expectError(MDB2_ERROR_NOSUCHTABLE); + $result = &$this->_statement->execute($values); + $this->_db->popExpect(); + + /* Attempt to handle any errors. */ + if (PEAR::isError($result)) { + /* We can only handle MDB2_ERROR_NOSUCHTABLE errors. */ + if ($result->getCode() != MDB2_ERROR_NOSUCHTABLE) { + return false; + } + + /* Attempt to create the target table. */ + if (!$this->_createTable()) { + return false; + } + + /* Recreate our prepared statement resource. */ + $this->_statement->free(); + if (!$this->_prepareStatement()) { + return false; + } + + /* Attempt to re-execute the insertion query. */ + $result = $this->_statement->execute($values); + if (PEAR::isError($result)) { + return false; + } + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + + /** + * Create the log table in the database. + * + * @return boolean True on success or false on failure. + * @access private + */ + function _createTable() + { + $this->_db->loadModule('Manager', null, true); + $result = $this->_db->manager->createTable( + $this->_table, + array( + 'id' => array('type' => $this->_types['id']), + 'logtime' => array('type' => $this->_types['logtime']), + 'ident' => array('type' => $this->_types['ident']), + 'priority' => array('type' => $this->_types['priority']), + 'message' => array('type' => $this->_types['message']) + ) + ); + if (PEAR::isError($result)) { + return false; + } + + $result = $this->_db->manager->createIndex( + $this->_table, + 'unique_id', + array('fields' => array('id' => true), 'unique' => true) + ); + if (PEAR::isError($result)) { + return false; + } + + return true; + } + + /** + * Prepare the SQL insertion statement. + * + * @return boolean True if the statement was successfully created. + * + * @access private + * @since Log 1.9.0 + */ + function _prepareStatement() + { + $this->_statement = &$this->_db->prepare( + 'INSERT INTO ' . $this->_table . + ' (id, logtime, ident, priority, message)' . + ' VALUES(:id, :logtime, :ident, :priority, :message)', + $this->_types, MDB2_PREPARE_MANIP); + + /* Return success if we didn't generate an error. */ + return (PEAR::isError($this->_statement) === false); + } +} diff --git a/gulliver/thirdparty/pear/Log/null.php b/gulliver/thirdparty/pear/Log/null.php new file mode 100644 index 000000000..58cb9b43f --- /dev/null +++ b/gulliver/thirdparty/pear/Log/null.php @@ -0,0 +1,91 @@ + + * @since Log 1.8.2 + * @package Log + * + * @example null.php Using the null handler. + */ +class Log_null extends Log +{ + /** + * Constructs a new Log_null object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_null($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + } + + /** + * Opens the handler. + * + * @access public + * @since Log 1.9.6 + */ + function open() + { + $this->_opened = true; + return true; + } + + /** + * Closes the handler. + * + * @access public + * @since Log 1.9.6 + */ + function close() + { + $this->_opened = false; + return true; + } + + /** + * Simply consumes the log event. The message will still be passed + * along to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/observer.php b/gulliver/thirdparty/pear/Log/observer.php new file mode 100644 index 000000000..d167ca93e --- /dev/null +++ b/gulliver/thirdparty/pear/Log/observer.php @@ -0,0 +1,129 @@ + + * @since Horde 1.3 + * @since Log 1.0 + * @package Log + * + * @example observer_mail.php An example Log_observer implementation. + */ +class Log_observer +{ + /** + * Instance-specific unique identification number. + * + * @var integer + * @access private + */ + var $_id = 0; + + /** + * The minimum priority level of message that we want to hear about. + * PEAR_LOG_EMERG is the highest priority, so we will only hear messages + * with an integer priority value less than or equal to ours. It defaults + * to PEAR_LOG_INFO, which listens to everything except PEAR_LOG_DEBUG. + * + * @var string + * @access private + */ + var $_priority = PEAR_LOG_INFO; + + /** + * Creates a new basic Log_observer instance. + * + * @param integer $priority The highest priority at which to receive + * log event notifications. + * + * @access public + */ + function Log_observer($priority = PEAR_LOG_INFO) + { + $this->_id = md5(microtime()); + $this->_priority = $priority; + } + + /** + * Attempts to return a new concrete Log_observer instance of the requested + * type. + * + * @param string $type The type of concreate Log_observer subclass + * to return. + * @param integer $priority The highest priority at which to receive + * log event notifications. + * @param array $conf Optional associative array of additional + * configuration values. + * + * @return object The newly created concrete Log_observer + * instance, or null on an error. + */ + function &factory($type, $priority = PEAR_LOG_INFO, $conf = array()) + { + $type = strtolower($type); + $class = 'Log_observer_' . $type; + + /* + * If the desired class already exists (because the caller has supplied + * it from some custom location), simply instantiate and return a new + * instance. + */ + if (class_exists($class)) { + $object = &new $class($priority, $conf); + return $object; + } + + /* Support both the new-style and old-style file naming conventions. */ + $newstyle = true; + $classfile = dirname(__FILE__) . '/observer_' . $type . '.php'; + + if (!file_exists($classfile)) { + $classfile = 'Log/' . $type . '.php'; + $newstyle = false; + } + + /* + * Attempt to include our version of the named class, but don't treat + * a failure as fatal. The caller may have already included their own + * version of the named class. + */ + @include_once $classfile; + + /* If the class exists, return a new instance of it. */ + if (class_exists($class)) { + /* Support both new-style and old-style construction. */ + if ($newstyle) { + $object = &new $class($priority, $conf); + } else { + $object = &new $class($priority); + } + return $object; + } + + $null = null; + return $null; + } + + /** + * This is a stub method to make sure that Log_Observer classes do + * something when they are notified of a message. The default behavior + * is to just print the message, which is obviously not desireable in + * practically any situation - which is why you need to override this + * method. :) + * + * @param array $event A hash describing the log event. + */ + function notify($event) + { + print_r($event); + } +} diff --git a/gulliver/thirdparty/pear/Log/sql.php b/gulliver/thirdparty/pear/Log/sql.php new file mode 100644 index 000000000..99f7a6dba --- /dev/null +++ b/gulliver/thirdparty/pear/Log/sql.php @@ -0,0 +1,294 @@ + + * @since Horde 1.3 + * @since Log 1.0 + * @package Log + * + * @example sql.php Using the SQL handler. + */ +class Log_sql extends Log +{ + /** + * Variable containing the DSN information. + * @var mixed + * @access private + */ + var $_dsn = ''; + + /** + * String containing the SQL insertion statement. + * + * @var string + * @access private + */ + var $_sql = ''; + + /** + * Array containing our set of DB configuration options. + * @var array + * @access private + */ + var $_options = array('persistent' => true); + + /** + * Object holding the database handle. + * @var object + * @access private + */ + var $_db = null; + + /** + * Resource holding the prepared statement handle. + * @var resource + * @access private + */ + var $_statement = null; + + /** + * Flag indicating that we're using an existing database connection. + * @var boolean + * @access private + */ + var $_existingConnection = false; + + /** + * String holding the database table to use. + * @var string + * @access private + */ + var $_table = 'log_table'; + + /** + * String holding the name of the ID sequence. + * @var string + * @access private + */ + var $_sequence = 'log_id'; + + /** + * Maximum length of the $ident string. This corresponds to the size of + * the 'ident' column in the SQL table. + * @var integer + * @access private + */ + var $_identLimit = 16; + + + /** + * Constructs a new sql logging object. + * + * @param string $name The target SQL table. + * @param string $ident The identification field. + * @param array $conf The connection configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_sql($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_table = $name; + $this->_mask = Log::UPTO($level); + + /* Now that we have a table name, assign our SQL statement. */ + if (!empty($this->_sql)) { + $this->_sql = $conf['sql']; + } else { + $this->_sql = 'INSERT INTO ' . $this->_table . + ' (id, logtime, ident, priority, message)' . + ' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)'; + } + + /* If an options array was provided, use it. */ + if (isset($conf['options']) && is_array($conf['options'])) { + $this->_options = $conf['options']; + } + + /* If a specific sequence name was provided, use it. */ + if (!empty($conf['sequence'])) { + $this->_sequence = $conf['sequence']; + } + + /* If a specific sequence name was provided, use it. */ + if (isset($conf['identLimit'])) { + $this->_identLimit = $conf['identLimit']; + } + + /* Now that the ident limit is confirmed, set the ident string. */ + $this->setIdent($ident); + + /* If an existing database connection was provided, use it. */ + if (isset($conf['db'])) { + $this->_db = &$conf['db']; + $this->_existingConnection = true; + $this->_opened = true; + } else { + $this->_dsn = $conf['dsn']; + } + } + + /** + * Opens a connection to the database, if it has not already + * been opened. This is implicitly called by log(), if necessary. + * + * @return boolean True on success, false on failure. + * @access public + */ + function open() + { + if (!$this->_opened) { + /* Use the DSN and options to create a database connection. */ + $this->_db = &DB::connect($this->_dsn, $this->_options); + if (DB::isError($this->_db)) { + return false; + } + + /* Create a prepared statement for repeated use in log(). */ + if (!$this->_prepareStatement()) { + return false; + } + + /* We now consider out connection open. */ + $this->_opened = true; + } + + return $this->_opened; + } + + /** + * Closes the connection to the database if it is still open and we were + * the ones that opened it. It is the caller's responsible to close an + * existing connection that was passed to us via $conf['db']. + * + * @return boolean True on success, false on failure. + * @access public + */ + function close() + { + if ($this->_opened && !$this->_existingConnection) { + $this->_opened = false; + $this->_db->freePrepared($this->_statement); + return $this->_db->disconnect(); + } + + return ($this->_opened === false); + } + + /** + * Sets this Log instance's identification string. Note that this + * SQL-specific implementation will limit the length of the $ident string + * to sixteen (16) characters. + * + * @param string $ident The new identification string. + * + * @access public + * @since Log 1.8.5 + */ + function setIdent($ident) + { + $this->_ident = substr($ident, 0, $this->_identLimit); + } + + /** + * Inserts $message to the currently open database. Calls open(), + * if necessary. Also passes the message along to any Log_observer + * instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* If we don't already have our statement object yet, create it. */ + if (!is_object($this->_statement) && !$this->_prepareStatement()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build our set of values for this log entry. */ + $id = $this->_db->nextId($this->_sequence); + $values = array($id, $this->_ident, $priority, $message); + + /* Execute the SQL query for this log entry insertion. */ + $result =& $this->_db->execute($this->_statement, $values); + if (DB::isError($result)) { + return false; + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + + /** + * Prepare the SQL insertion statement. + * + * @return boolean True if the statement was successfully created. + * + * @access private + * @since Log 1.9.1 + */ + function _prepareStatement() + { + $this->_statement = $this->_db->prepare($this->_sql); + + /* Return success if we didn't generate an error. */ + return (DB::isError($this->_statement) === false); + } +} diff --git a/gulliver/thirdparty/pear/Log/sqlite.php b/gulliver/thirdparty/pear/Log/sqlite.php new file mode 100644 index 000000000..a558fee13 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/sqlite.php @@ -0,0 +1,225 @@ + + * @author Jon Parise + * @since Log 1.8.3 + * @package Log + * + * @example sqlite.php Using the Sqlite handler. + */ +class Log_sqlite extends Log +{ + /** + * Array containing the connection defaults + * @var array + * @access private + */ + var $_options = array('mode' => 0666, + 'persistent' => false); + + /** + * Object holding the database handle. + * @var object + * @access private + */ + var $_db = null; + + /** + * Flag indicating that we're using an existing database connection. + * @var boolean + * @access private + */ + var $_existingConnection = false; + + /** + * String holding the database table to use. + * @var string + * @access private + */ + var $_table = 'log_table'; + + + /** + * Constructs a new sql logging object. + * + * @param string $name The target SQL table. + * @param string $ident The identification field. + * @param mixed $conf Can be an array of configuration options used + * to open a new database connection + * or an already opened sqlite connection. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_sqlite($name, $ident = '', &$conf, $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_table = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (is_array($conf)) { + foreach ($conf as $k => $opt) { + $this->_options[$k] = $opt; + } + } else { + // If an existing database connection was provided, use it. + $this->_db =& $conf; + $this->_existingConnection = true; + } + } + + /** + * Opens a connection to the database, if it has not already + * been opened. This is implicitly called by log(), if necessary. + * + * @return boolean True on success, false on failure. + * @access public + */ + function open() + { + if (is_resource($this->_db)) { + $this->_opened = true; + return $this->_createTable(); + } else { + /* Set the connection function based on the 'persistent' option. */ + if (empty($this->_options['persistent'])) { + $connectFunction = 'sqlite_open'; + } else { + $connectFunction = 'sqlite_popen'; + } + + /* Attempt to connect to the database. */ + if ($this->_db = $connectFunction($this->_options['filename'], + (int)$this->_options['mode'], + $error)) { + $this->_opened = true; + return $this->_createTable(); + } + } + + return $this->_opened; + } + + /** + * Closes the connection to the database if it is still open and we were + * the ones that opened it. It is the caller's responsible to close an + * existing connection that was passed to us via $conf['db']. + * + * @return boolean True on success, false on failure. + * @access public + */ + function close() + { + /* We never close existing connections. */ + if ($this->_existingConnection) { + return false; + } + + if ($this->_opened) { + $this->_opened = false; + sqlite_close($this->_db); + } + + return ($this->_opened === false); + } + + /** + * Inserts $message to the currently open database. Calls open(), + * if necessary. Also passes the message along to any Log_observer + * instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + // Extract the string representation of the message. + $message = $this->_extractMessage($message); + + // Build the SQL query for this log entry insertion. + $q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' . + "VALUES ('%s', '%s', %d, '%s')", + $this->_table, + strftime('%Y-%m-%d %H:%M:%S', time()), + sqlite_escape_string($this->_ident), + $priority, + sqlite_escape_string($message)); + if (!($res = @sqlite_unbuffered_query($this->_db, $q))) { + return false; + } + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + + /** + * Checks whether the log table exists and creates it if necessary. + * + * @return boolean True on success or false on failure. + * @access private + */ + function _createTable() + { + $q = "SELECT name FROM sqlite_master WHERE name='" . $this->_table . + "' AND type='table'"; + + $res = sqlite_query($this->_db, $q); + + if (sqlite_num_rows($res) == 0) { + $q = 'CREATE TABLE [' . $this->_table . '] (' . + 'id INTEGER PRIMARY KEY NOT NULL, ' . + 'logtime NOT NULL, ' . + 'ident CHAR(16) NOT NULL, ' . + 'priority INT NOT NULL, ' . + 'message)'; + + if (!($res = sqlite_unbuffered_query($this->_db, $q))) { + return false; + } + } + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Log/syslog.php b/gulliver/thirdparty/pear/Log/syslog.php new file mode 100644 index 000000000..22af4b64e --- /dev/null +++ b/gulliver/thirdparty/pear/Log/syslog.php @@ -0,0 +1,179 @@ + + * @author Jon Parise + * @since Horde 1.3 + * @since Log 1.0 + * @package Log + * + * @example syslog.php Using the syslog handler. + */ +class Log_syslog extends Log +{ + /** + * Integer holding the log facility to use. + * @var integer + * @access private + */ + var $_name = LOG_SYSLOG; + + /** + * Should we inherit the current syslog connection for this process, or + * should we call openlog() to start a new syslog connection? + * @var boolean + * @access private + */ + var $_inherit = false; + + /** + * Constructs a new syslog object. + * + * @param string $name The syslog facility. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_syslog($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + /* Ensure we have a valid integer value for $name. */ + if (empty($name) || !is_int($name)) { + $name = LOG_SYSLOG; + } + + if (isset($conf['inherit'])) { + $this->_inherit = $conf['inherit']; + $this->_opened = $this->_inherit; + } + + $this->_id = md5(microtime()); + $this->_name = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + } + + /** + * Opens a connection to the system logger, if it has not already + * been opened. This is implicitly called by log(), if necessary. + * @access public + */ + function open() + { + if (!$this->_opened) { + $this->_opened = openlog($this->_ident, LOG_PID, $this->_name); + } + + return $this->_opened; + } + + /** + * Closes the connection to the system logger, if it is open. + * @access public + */ + function close() + { + if ($this->_opened && !$this->_inherit) { + closelog(); + $this->_opened = false; + } + + return true; + } + + /** + * Sends $message to the currently open syslog connection. Calls + * open() if necessary. Also passes the message along to any Log_observer + * instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param int $priority (optional) The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* If the connection isn't open and can't be opened, return failure. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + + /* Build a syslog priority value based on our current configuration. */ + $priority = $this->_toSyslog($priority); + if ($this->_inherit) { + $priority |= $this->_name; + } + + if (!syslog($priority, $message)) { + return false; + } + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + + /** + * Converts a PEAR_LOG_* constant into a syslog LOG_* constant. + * + * This function exists because, under Windows, not all of the LOG_* + * constants have unique values. Instead, the PEAR_LOG_* were introduced + * for global use, with the conversion to the LOG_* constants kept local to + * to the syslog driver. + * + * @param int $priority PEAR_LOG_* value to convert to LOG_* value. + * + * @return The LOG_* representation of $priority. + * + * @access private + */ + function _toSyslog($priority) + { + static $priorities = array( + PEAR_LOG_EMERG => LOG_EMERG, + PEAR_LOG_ALERT => LOG_ALERT, + PEAR_LOG_CRIT => LOG_CRIT, + PEAR_LOG_ERR => LOG_ERR, + PEAR_LOG_WARNING => LOG_WARNING, + PEAR_LOG_NOTICE => LOG_NOTICE, + PEAR_LOG_INFO => LOG_INFO, + PEAR_LOG_DEBUG => LOG_DEBUG + ); + + /* If we're passed an unknown priority, default to LOG_INFO. */ + if (!is_int($priority) || !in_array($priority, $priorities)) { + return LOG_INFO; + } + + return $priorities[$priority]; + } + +} diff --git a/gulliver/thirdparty/pear/Log/win.php b/gulliver/thirdparty/pear/Log/win.php new file mode 100644 index 000000000..21795d965 --- /dev/null +++ b/gulliver/thirdparty/pear/Log/win.php @@ -0,0 +1,269 @@ + + * @since Log 1.7.0 + * @package Log + * + * @example win.php Using the window handler. + */ +class Log_win extends Log +{ + /** + * The name of the output window. + * @var string + * @access private + */ + var $_name = 'LogWindow'; + + /** + * The title of the output window. + * @var string + * @access private + */ + var $_title = 'Log Output Window'; + + /** + * Mapping of log priorities to styles. + * @var array + * @access private + */ + var $_styles = array( + PEAR_LOG_EMERG => 'color: red;', + PEAR_LOG_ALERT => 'color: orange;', + PEAR_LOG_CRIT => 'color: yellow;', + PEAR_LOG_ERR => 'color: green;', + PEAR_LOG_WARNING => 'color: blue;', + PEAR_LOG_NOTICE => 'color: indigo;', + PEAR_LOG_INFO => 'color: violet;', + PEAR_LOG_DEBUG => 'color: black;' + ); + + /** + * String buffer that holds line that are pending output. + * @var array + * @access private + */ + var $_buffer = array(); + + /** + * Constructs a new Log_win object. + * + * @param string $name Ignored. + * @param string $ident The identity string. + * @param array $conf The configuration array. + * @param int $level Log messages up to and including this level. + * @access public + */ + function Log_win($name, $ident = '', $conf = array(), + $level = PEAR_LOG_DEBUG) + { + $this->_id = md5(microtime()); + $this->_name = $name; + $this->_ident = $ident; + $this->_mask = Log::UPTO($level); + + if (isset($conf['title'])) { + $this->_title = $conf['title']; + } + if (isset($conf['styles']) && is_array($conf['styles'])) { + $this->_styles = $conf['styles']; + } + if (isset($conf['colors']) && is_array($conf['colors'])) { + foreach ($conf['colors'] as $level => $color) { + $this->_styles[$level] .= "color: $color;"; + } + } + + register_shutdown_function(array(&$this, '_Log_win')); + } + + /** + * Destructor + */ + function _Log_win() + { + if ($this->_opened || (count($this->_buffer) > 0)) { + $this->close(); + } + } + + /** + * The first time open() is called, it will open a new browser window and + * prepare it for output. + * + * This is implicitly called by log(), if necessary. + * + * @access public + */ + function open() + { + if (!$this->_opened) { + $win = $this->_name; + $styles = $this->_styles; + + if (!empty($this->_ident)) { + $identHeader = "$win.document.writeln('Ident')"; + } else { + $identHeader = ''; + } + + echo <<< EOT + +EOT; + $this->_opened = true; + } + + return $this->_opened; + } + + /** + * Closes the output stream if it is open. If there are still pending + * lines in the output buffer, the output window will be opened so that + * the buffer can be drained. + * + * @access public + */ + function close() + { + /* + * If there are still lines waiting to be written, open the output + * window so that we can drain the buffer. + */ + if (!$this->_opened && (count($this->_buffer) > 0)) { + $this->open(); + } + + if ($this->_opened) { + $this->_writeln(''); + $this->_writeln(''); + $this->_opened = false; + } + + return ($this->_opened === false); + } + + /** + * Writes a single line of text to the output window. + * + * @param string $line The line of text to write. + * + * @access private + */ + function _writeln($line) + { + /* Add this line to our output buffer. */ + $this->_buffer[] = $line; + + /* Buffer the output until this page's headers have been sent. */ + if (!headers_sent()) { + return; + } + + /* If we haven't already opened the output window, do so now. */ + if (!$this->_opened && !$this->open()) { + return false; + } + + /* Drain the buffer to the output window. */ + $win = $this->_name; + foreach ($this->_buffer as $line) { + echo "\n"; + } + + /* Now that the buffer has been drained, clear it. */ + $this->_buffer = array(); + } + + /** + * Logs $message to the output window. The message is also passed along + * to any Log_observer instances that are observing this Log. + * + * @param mixed $message String or object containing the message to log. + * @param string $priority The priority of the message. Valid + * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, + * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, + * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. + * @return boolean True on success or false on failure. + * @access public + */ + function log($message, $priority = null) + { + /* If a priority hasn't been specified, use the default value. */ + if ($priority === null) { + $priority = $this->_priority; + } + + /* Abort early if the priority is above the maximum logging level. */ + if (!$this->_isMasked($priority)) { + return false; + } + + /* Extract the string representation of the message. */ + $message = $this->_extractMessage($message); + $message = preg_replace('/\r\n|\n|\r/', '
    ', $message); + + list($usec, $sec) = explode(' ', microtime()); + + /* Build the output line that contains the log entry row. */ + $line = ''; + $line .= sprintf('%s.%s', + strftime('%H:%M:%S', $sec), substr($usec, 2, 2)); + if (!empty($this->_ident)) { + $line .= '' . $this->_ident . ''; + } + $line .= '' . ucfirst($this->priorityToString($priority)) . ''; + $line .= sprintf('%s', $priority, $message); + $line .= ''; + + $this->_writeln($line); + + $this->_announce(array('priority' => $priority, 'message' => $message)); + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Net/CheckIP.php b/gulliver/thirdparty/pear/Net/CheckIP.php new file mode 100644 index 000000000..e7309db67 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/CheckIP.php @@ -0,0 +1,80 @@ + +* +* @author Martin Jansen +* @author Guido Haeger +* @package Net_CheckIP +* @version 1.1 +* @access public +*/ +class Net_CheckIP +{ + + /** + * Validate the syntax of the given IP adress + * + * This function splits the IP address in 4 pieces + * (separated by ".") and checks for each piece + * if it's an integer value between 0 and 255. + * If all 4 parameters pass this test, the function + * returns true. + * + * @param string $ip IP adress + * @return bool true if syntax is valid, otherwise false + */ + function check_ip($ip) + { + $oct = explode('.', $ip); + if (count($oct) != 4) { + return false; + } + + for ($i = 0; $i < 4; $i++) { + if (!preg_match("/^[0-9]+$/", $oct[$i])) { + return false; + } + + if ($oct[$i] < 0 || $oct[$i] > 255) { + return false; + } + } + + return true; + } +} +?> diff --git a/gulliver/thirdparty/pear/Net/Curl.php b/gulliver/thirdparty/pear/Net/Curl.php new file mode 100644 index 000000000..ef9ceb5e2 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/Curl.php @@ -0,0 +1,876 @@ + + * @author Sterling Hughes + * @author Joe Stump + * @author Philippe Jausions + * @copyright 1997-2008 The PHP Group + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Revision: 1.15 $ + * @link http://pear.php.net/package/Net_Curl + */ + +/** + * Include PEAR package for error handling + */ +require_once 'PEAR.php'; + +/** + * Object-oriented implementation of the Curl extension + * + * @category Net + * @package Net_Curl + * @author David Costa + * @author Sterling Hughes + * @author Joe Stump + * @author Philippe Jausions + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/Net_Curl + */ +class Net_Curl +{ + // {{{ Public Properties + /** + * The URL for cURL to work with + * + * @var string $url + * @access public + */ + var $url; + + /** + * The Username for standard HTTP Authentication + * + * @var string $username + * @access public + */ + var $username = ''; + + /** + * The Password for standard HTTP Authentication + * + * @var string $password + * @access public + */ + var $password = ''; + + /** + * The SSL version for the transfer + * + * @var integer $sslVersion + * @access public + */ + var $sslVersion; + + /** + * The filename of the SSL certificate + * + * @var string $sslCert + * @access public + */ + var $sslCert; + + /** + * The password corresponding to the certificate + * in the $sslCert property + * + * @var string $sslCertPasswd + * @access public + */ + var $sslCertPasswd; + + /** + * User Agent string when making an HTTP request + * + * @var string $userAgent + * @access public + */ + var $userAgent; + + /** + * Whether or not to include the header in the results + * of the CURL transfer + * + * @var boolean $header + */ + var $header = false; + + /** + * Whether or not to output debug information while executing a + * curl transfer + * + * @var boolean $verbose + * @access public + */ + var $verbose = false; + + /** + * Whether or not to display a progress meter for the current transfer + * + * @var boolean $progress + * @access public + */ + var $progress = false; + + /** + * Whether or not to suppress error messages + * + * @var boolean $mute + * @access public + */ + var $mute = false; + + /** + * Whether or not to follow HTTP Location headers. + * + * @var boolean $followLocation + * @access public + */ + var $followLocation = true; + + /** + * Whether or not to follow HTTP Location headers. + * + * @var boolean $follow_location + * @access public + * @deprecated + */ + var $follow_location = false; + + /** + * Time allowed for current transfer, in seconds. 0 means no limit + * + * @var int $timeout + * @access public + */ + var $timeout = 0; + + /** + * Whether or not to return the results of the + * current transfer + * + * @var boolean $returnTransfer + * @access public + */ + var $returnTransfer = true; + + /** + * Whether or not to return the results of the + * current transfer + * + * @var boolean $return_transfer + * @access public + * @deprecated + */ + var $return_transfer = false; + + /** + * The type of transfer to perform (ie. 'POST', 'GET', 'PUT', etc) + * + * @var string $type + * @access public + */ + var $type; + + /** + * The file to upload (PUT, or FTP methods) + * + * @var string $file + * @access public + */ + var $file; + + /** + * The file size of the file pointed to by the $file + * property + * + * @var integer $fileSize + * @access public + */ + var $fileSize; + + /** + * The file size of the file pointed to by the $file + * property + * + * @var integer $file_size + * @access public + * @deprecated + */ + var $file_size = false; + + + /** + * The cookies to send to the remote site + * + * @var array $cookies + * @access public + */ + var $cookies = array(); + + /** + * Additional HTTP headers to send to the remote site + * + * @var array $httpHeaders + * @access public + */ + var $httpHeaders = null; + + /** + * Additional HTTP headers to send to the remote site + * + * @var array $http_headers + * @access public + * @deprecated + */ + var $http_headers = false; + + /** + * The fields to send in a 'POST' request + * + * @var array $fields + * @access public + */ + var $fields; + + /** + * The proxy server to go through + * + * @var string $proxy + * @access public + */ + var $proxy; + + /** + * The username for the Proxy server + * + * @var string $proxyUser + * @access public + */ + var $proxyUser; + + /** + * The password for the Proxy server + * + * @var string $proxyPassword + * @access public + */ + var $proxyPassword; + + /** + * $verifyPeer + * + * FALSE to stop CURL from verifying the peer's certificate. + * Alternate certificates to verify against can be specified + * with the CURLOPT_CAINFO option or a certificate directory + * can be specified with the CURLOPT_CAPATH option. + * CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE + * if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). + * + * @var boolean $verifyPeer + * @access public + */ + var $verifyPeer = true; + + /** + * $verifyHost + * + * 0 : to stop CURL from verifying the host's certificate. + * 1 : to check the existence of a common name in the SSL peer certificate. + * 2 : to check the existence of a common name and also verify that it + * matches the hostname provided. + * + * @var bool $verifyHost + * @access public + */ + var $verifyHost = 2; + + /** + * $caInfo + * + * Set value for CURLOPT_CAINFO. The name of a file holding one or more + * certificates to verify the peer with. This only makes sense when used + * in combination with CURLOPT_SSL_VERIFYPEER. curl-ca-bundle.crt is + * avaible on the Curl website http://curl.haxx.se/ for download inside + * the packages. + * + * @var string $caInfo + * @access public + */ + var $caInfo = ''; + + /** + * $caPath + * + * Set value for CURLOPT_CAPATH. A directory that holds multiple CA + * certificates. Use this option alongside CURLOPT_SSL_VERIFYPEER. + * + * @var string $caPath + * @access public + */ + var $caPath; + // }}} + // {{{ Private Properties + /** + * The current curl handle + * + * @var resource $_ch + * @access private + * @see Net_Curl::create() + */ + var $_ch = null; + + /** + * The file upload resource + * + * The CURLOPT_INFILE requires a file resource and not just a file name. + * This is used by execute to open the file. + * + * @var resource $_fp + * @access private + * @see Net_Curl::execute() + */ + var $_fp = null; + // }}} + + // {{{ __construct($url = '', $userAgent = '') + /** + * The Net_Curl PHP 5.x constructor, called when a new Net_Curl object + * is initialized (also called via 4.x constructor) + * + * @param string $url The URL to fetch (can be set using the $url + * property as well) + * @param string $userAgent The userAgent string (can be set using the + * $userAgent property as well) + * + * @access public + * @author Joe Stump + * @return void + */ + function __construct($url = '', $userAgent = '') + { + if (is_string($url) && strlen($url)) { + $this->url = $url; + } + + if (is_string($userAgent) && strlen($userAgent)) { + $this->userAgent = $userAgent; + } + } + // }}} + + // {{{ Net_Curl($url = '', $userAgent = '') + /** + * Net_Curl + * + * PHP 4.x constructor. + * + * @param string $url The URL to fetch (can be set using the $url + * property as well) + * @param string $userAgent The userAgent string (can be set using the + * $userAgent property as well) + * + * @access public + * @return void + */ + function Net_Curl($url = '', $userAgent = '') + { + $this->__construct($url, $userAgent); + } + // }}} + + // {{{ execute() + /** + * Executes a prepared CURL transfer + * + * Run this function to execute your cURL request. If all goes well you + * should get a string (the output from the remote host regarding your + * request) or true (if you choose to output directly to the browser). If + * something fails then PEAR_Error is returned. + * + * + * fields = array('foo' => '1', 'bar' => 'apple'); + * $result = $curl->execute(); + * if (!PEAR::isError($result)) { + * echo $result; + * } + * ?> + * + * + * @access public + * @author Sterling Hughes + * @author Joe Stump + * @return PEAR_Error on failure, true/result on success + * @since PHP 4.0.5 + */ + function execute() + { + // Create cURL handle if it hasn't already been created + if (!is_resource($this->_ch)) { + $result = $this->create(); + if (PEAR::isError($result)) { + return $result; + } + } + + // Map the deprecated variables and throw a bunch of errors + $this->_mapDeprecatedVariables(); + + // Default return value is true. + $ret = true; + + // Basic stuff + $ret = curl_setopt($this->_ch, CURLOPT_URL, $this->url); + $ret = curl_setopt($this->_ch, CURLOPT_HEADER, $this->header); + + // Whether or not to return the transfer contents + if ($this->returnTransfer === true || $this->mute === true) { + $ret = curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, true); + } + + // HTTP Authentication + if ($this->username != '') { + $ret = curl_setopt($this->_ch, + CURLOPT_USERPWD, + $this->username . ':' . $this->password); + } + + // SSL Checks + if (isset($this->sslVersion)) { + $ret = curl_setopt($this->_ch, + CURLOPT_SSLVERSION, + $this->sslVersion); + } + + if (isset($this->sslCert)) { + $ret = curl_setopt($this->_ch, CURLOPT_SSLCERT, $this->sslCert); + } + + if (isset($this->sslCertPasswd)) { + $ret = curl_setopt($this->_ch, + CURLOPT_SSLCERTPASSWD, + $this->sslCertPasswd); + } + + // Proxy Related checks + if (isset($this->proxy)) { + $ret = curl_setopt($this->_ch, CURLOPT_PROXY, $this->proxy); + } + + if (isset($this->proxyUser) || isset($this->proxyPassword)) { + $ret = curl_setopt($this->_ch, + CURLOPT_PROXYUSERPWD, + $this->proxyUser . ':' . $this->proxyPassword); + } + + if (is_bool($this->verifyPeer)) { + if (!$this->setOption(CURLOPT_SSL_VERIFYPEER, $this->verifyPeer)) { + return PEAR::raiseError('Error setting CURLOPT_SSL_VERIFYPEER'); + } + } + + if (is_numeric($this->verifyHost) && $this->verifyHost >= 0 && + $this->verifyHost <= 2) { + if (!$this->setOption(CURLOPT_SSL_VERIFYHOST, $this->verifyHost)) { + return PEAR::raiseError('Error setting CURLOPT_SSL_VERIFYPEER'); + } + } + + if (is_bool($this->verifyPeer) && $this->verifyPeer == true) { + if (isset($this->caInfo) && strlen($this->caInfo)) { + if (file_exists($this->caInfo)) { + if (!$this->setOption(CURLOPT_CAINFO, $this->caInfo)) { + return PEAR::raiseError('Error setting CURLOPT_CAINFO'); + } + } else { + return PEAR::raiseError('Could not find CA info: '. + $this->caInfo); + } + } + + if (isset($this->caPath) && is_string($this->caPath)) { + if (!$this->setOption(CURLOPT_CAPATH, $this->caPath)) { + return PEAR::raiseError('Error setting CURLOPT_CAPATH'); + } + } + } + + // Transfer type + if (isset($this->type)) { + switch (strtolower($this->type)) { + case 'post': + $ret = curl_setopt($this->_ch, CURLOPT_POST, true); + break; + case 'put': + $ret = curl_setopt($this->_ch, CURLOPT_PUT, true); + break; + } + } + + // Transfer upload, etc. related + if (isset($this->file)) { + if (!file_exists($this->file)) { + return PEAR::raiseError('File does not exist: '.$this->file); + } + + $this->_fp = fopen($this->file, 'r'); + if (!is_resource($this->_fp)) { + return PEAR::raiseError('Could not open file: '.$this->file); + } + + if (!isset($this->fileSize)) { + $this->fileSize = filesize($this->file); + } + + $ret = curl_setopt($this->_ch, CURLOPT_INFILE, $this->_fp); + $ret = curl_setopt($this->_ch, CURLOPT_INFILESIZE, $this->fileSize); + $ret = curl_setopt($this->_ch, CURLOPT_UPLOAD, true); + } + + if (isset($this->fields)) { + $sets = null; + if (!isset($this->type)) { + $this->type = 'post'; + $ret = curl_setopt($this->_ch, CURLOPT_POST, true); + } + + // If fields is an array then turn it into a string. Sometimes + // cURL doesn't like fields as an array. + // Exception: if a value is prefixed with "@" and the rest of the + // value resolves to an existing file, then pass + // the values as the original array. + if (is_array($this->fields)) { + $sets = array(); + foreach ($this->fields as $key => $val) { + if (strlen($val) > 1 && $val{0} == '@') { + $file = substr($val, 1); + if (is_file($file) && is_readable($file)) { + $sets = null; + break; + } + } + $sets[] = urlencode($key) . '=' . urlencode($val); + } + } + + if (!is_null($sets)) { + $fields = implode('&', $sets); + } else { + $fields = $this->fields; + } + $ret = curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $fields); + } + + // Error related + if ($this->progress === true) { + $ret = curl_setopt($this->_ch, CURLOPT_PROGRESS, true); + } + + if ($this->verbose === true) { + $ret = curl_setopt($this->_ch, CURLOPT_VERBOSE, true); + } + + // If a Location: header is passed then follow it + $ret = curl_setopt($this->_ch, + CURLOPT_FOLLOWLOCATION, + $this->followLocation); + + // If a timeout is set and is greater then zero then set it + if (is_numeric($this->timeout) && $this->timeout > 0) { + $ret = curl_setopt($this->_ch, CURLOPT_TIMEOUT, $this->timeout); + } + + if (isset($this->userAgent)) { + $ret = curl_setopt($this->_ch, CURLOPT_USERAGENT, $this->userAgent); + } + + // Cookies + if (is_array($this->cookies) && count($this->cookies)) { + $cookieData = ''; + foreach ($this->cookies as $name => $value) { + $cookieData .= $name . '=' . $value . ';'; + } + + $ret = curl_setopt($this->_ch, CURLOPT_COOKIE, $cookieData); + } + + // Other HTTP headers + if ($this->httpHeaders !== null) { + if (is_array($this->httpHeaders)) { + $ret = curl_setopt($this->_ch, + CURLOPT_HTTPHEADER, + $this->httpHeaders); + } else { + return PEAR::raiseError('Net_Curl::$httpHeaders must be an array'); + } + } + + $ret = curl_exec($this->_ch); + + // Close the file before we return anything + if (is_resource($this->_fp)) { + fclose($this->_fp); + } + + if (curl_errno($this->_ch)) { + return PEAR::raiseError(curl_error($this->_ch), curl_errno($this->_ch)); + } + + // Check to make sure we get a 2XX/3XX code and not a 404 or something. + $info = $this->getInfo(); + if (!isset($info['http_code'])) { + return PEAR::raiseError('Unknown or invalid HTTP response'); + } else { + $type = substr($info['http_code'], 0, 1); + if ($type != 2 && $type != 3) { + return PEAR::raiseError('Unexpected HTTP code: ' . + $info['http_code']); + } + } + + return $ret; + } + // }}} + + // {{{ setOption($option, $value) + /** + * Sets an option for your cURL session. Please note that the cURL handler + * is NOT created before execute(). This is for error checking purposes. + * You should use setOption() in the following manner: + * + * + * create(); + * if (!PEAR::isError($check)) { + * $curl->setOption(CURLOPT_FOO, 'bar'); + * $result = $curl->execute(); + * if (!PEAR::isError($result)) { + * echo $result; + * } + * } + * + * ?> + * + * + * @param int $option cURL constant (ie. CURLOPT_URL) + * @param mixed $value The option's value + * + * @author Joe Stump + * @access public + * @return boolean + */ + function setOption($option, $value) + { + if (is_resource($this->_ch)) { + return curl_setopt($this->_ch, $option, $value); + } + + return false; + } + // }}} + + // {{{ getInfo() + /** + * Returns the info from the cURL session. PEAR_Error if you try and run + * this before you execute the session. + * + * @author Joe Stump + * @access public + * @return mixed PEAR_Error if there is no resource, info on success + */ + function getInfo() + { + if (is_resource($this->_ch)) { + return curl_getinfo($this->_ch); + } + + return PEAR::isError('cURL handler does not exist!'); + } + // }}} + + // {{{ create() + /** + * Creates a cURL resource. If curl_init() doesn't exist or we could not + * create a resource it will error out. + * + * @author Joe Stump + * @return boolean TRUE on success, PEAR_Error on failure + */ + function create() + { + if (!PEAR::loadExtension('curl')) { + return PEAR::raiseError('CURL extension is not available'); + } + if (!function_exists('curl_init')) { + return PEAR::raiseError('Function curl_init() not found'); + } + + $this->_ch = curl_init(); + if (!is_resource($this->_ch)) { + return PEAR::raiseError('Could not initialize cURL handler'); + } + + return true; + } + // }}} + + // {{{ verboseAll() + /** + * Sets verbose output + * + * Turns on super debugging mode by not suppressing errors, turning on + * verbose mode, showing headers and displaying progress. + * + * @access public + * @author David Costa + * @return void + */ + function verboseAll() + { + $this->verbose = true; + $this->mute = false; + $this->header = true; + $this->progress = true; + } + // }}} + + // {{{ verbose_all() + /** + * Sets verbose output + * + * @access public + * @author David Costa + * @return void + * @deprecated + */ + function verbose_all() + { + $this->verboseAll(); + PEAR::raiseError('Net_Curl::verbose_all() is deprecated! Please use Net_Curl::verboseAll()'."
    \n", null, PEAR_ERROR_PRINT); + } + // }}} + + // {{{ close() + /** + * Closes the curl transfer and finishes the object (kinda ;) + * + * @access public + * @author Sterling Hughes + * @return void + * @since PHP 4.0.5 + */ + function close() + { + if (is_resource($this->_ch)) { + curl_close($this->_ch); + } + } + // }}} + + // {{{ _mapDeprecatedVariables() + /** + * Maps deprecated variables into the appropriate places. It also throws + * the necessary notices. + * + * @author Joe Stump + * @access private + * @return void + */ + function _mapDeprecatedVariables() + { + $bad = array(); + if ($this->follow_location !== false) { + if ($this->follow_location > 0) { + $this->followLocation = true; + } else { + $this->followLocation = false; + } + + $bad[] = array('follow_location', 'followLocation'); + } + + if ($this->return_transfer !== false) { + if ($this->return_transfer > 0) { + $this->returnTransfer = true; + } else { + $this->returnTransfer = false; + } + + $bad[] = array('return_transfer', 'returnTransfer'); + } + + if ($this->file_size !== false) { + $this->fileSize = $this->file_size; + $bad[] = array('file_size', 'fileSize'); + } + + if ($this->http_headers !== false) { + $this->httpHeaders = $this->http_headers; + $bad[] = array('http_headers', 'httpHeaders'); + } + + foreach ($bad as $map) { + PEAR::raiseError('Net_Curl::$'. $map[0]. ' is deprecated! Please use Net_Curl::$'.$map[1]." instead!
    \n", null, PEAR_ERROR_PRINT); + } + } + // }}} + + // {{{ __destruct() + /** + * PHP 5.x destructor. + * + * Runs Net_Curl::close() to make sure we close our cURL connection. + * + * @author Joe Stump + * @see Net_Curl::close() + */ + function __destruct() + { + $this->close(); + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Net/DIME.php b/gulliver/thirdparty/pear/Net/DIME.php new file mode 100644 index 000000000..6c54208ea --- /dev/null +++ b/gulliver/thirdparty/pear/Net/DIME.php @@ -0,0 +1,629 @@ + | +// | Ralf Hofmann | +// +----------------------------------------------------------------------+ +// +// $Id: DIME.php,v 1.5 2002/09/29 01:55:16 shane Exp $ +// + +require_once 'PEAR.php'; +/** + * + * DIME Encoding/Decoding + * + * What is it? + * This class enables you to manipulate and build + * a DIME encapsulated message. + * + * http://www.ietf.org/internet-drafts/draft-nielsen-dime-02.txt + * + * 09/18/02 Ralf - A huge number of changes to be compliant + * with the DIME Specification Release 17 June 2002 + * + * TODO: lots of stuff needs to be tested. + * Definitily have to go through DIME spec and + * make things work right, most importantly, sec 3.3 + * make examples, document + * + * see test/dime_mesage_test.php for example of usage + * + * @author Shane Caraveo , + * Ralf Hofmann + * @version $Revision: 1.5 $ + * @package Net_DIME + */ +define('NET_DIME_TYPE_UNCHANGED',0x00); +define('NET_DIME_TYPE_MEDIA',0x01); +define('NET_DIME_TYPE_URI',0x02); +define('NET_DIME_TYPE_UNKNOWN',0x03); +define('NET_DIME_TYPE_NONE',0x04); + +define('NET_DIME_VERSION',0x0001); + +define('NET_DIME_RECORD_HEADER',12); + +define('NET_DIME_FLAGS', 0); +define('NET_DIME_OPTS_LEN', 1); +define('NET_DIME_ID_LEN', 2); +define('NET_DIME_TYPE_LEN', 3); +define('NET_DIME_DATA_LEN', 4); +define('NET_DIME_OPTS', 5); +define('NET_DIME_ID', 6); +define('NET_DIME_TYPE', 7); +define('NET_DIME_DATA', 8); + +class Net_DIME_Record extends PEAR +{ + // these are used to hold the padded length + var $OPTS_LENGTH = 0; + var $ID_LENGTH = 0; + var $TYPE_LENGTH = 0; + var $DATA_LENGTH = 0; + var $_haveOpts = FALSE; + var $_haveID = FALSE; + var $_haveType = FALSE; + var $_haveData = FALSE; + var $debug = FALSE; + var $padstr = "\0"; + /** + * Elements + * [NET_DIME_FLAGS], 16 bits: VERSION:MB:ME:CF:TYPE_T + * [NET_DIME_OPTS_LEN], 16 bits: OPTIONS_LENGTH + * [NET_DIME_ID_LEN], 16 bits: ID_LENGTH + * [NET_DIME_TYPE_LEN], 16 bits: TYPE_LENGTH + * [NET_DIME_DATA_LEN], 32 bits: DATA_LENGTH + * [NET_DIME_OPTS] : OPTIONS + * [NET_DIME_ID] : ID + * [NET_DIME_TYPE] : TYPE + * [NET_DIME_DATA] : DATA + */ + var $Elements = array(NET_DIME_FLAGS => 0, NET_DIME_OPTS_LEN => 0, + NET_DIME_ID_LEN => 0, NET_DIME_TYPE_LEN => 0, + NET_DIME_DATA_LEN => 0, + NET_DIME_OPTS => '', + NET_DIME_ID => '', + NET_DIME_TYPE => '', + NET_DIME_DATA => ''); + + function Net_DIME_Record($debug = FALSE) + { + $this->debug = $debug; + if ($debug) $this->padstr = '*'; + } + + function setMB() + { + $this->Elements[NET_DIME_FLAGS] |= 0x0400; + } + + function setME() + { + $this->Elements[NET_DIME_FLAGS] |= 0x0200; + } + + function setCF() + { + $this->Elements[NET_DIME_FLAGS] |= 0x0100; + } + + function isChunk() + { + return $this->Elements[NET_DIME_FLAGS] & 0x0100; + } + + function isEnd() + { + return $this->Elements[NET_DIME_FLAGS] & 0x0200; + } + + function isStart() + { + return $this->Elements[NET_DIME_FLAGS] & 0x0400; + } + + function getID() + { + return $this->Elements[NET_DIME_ID]; + } + + function getType() + { + return $this->Elements[NET_DIME_TYPE]; + } + + function getData() + { + return $this->Elements[NET_DIME_DATA]; + } + + function getDataLength() + { + return $this->Elements[NET_DIME_DATA_LEN]; + } + + function setType($typestring, $type=NET_DIME_TYPE_UNKNOWN) + { + $typelen = strlen($typestring) & 0xFFFF; + $type = $type << 4; + $this->Elements[NET_DIME_FLAGS] = ($this->Elements[NET_DIME_FLAGS] & 0xFF0F) | $type; + $this->Elements[NET_DIME_TYPE_LEN] = $typelen; + $this->TYPE_LENGTH = $this->_getPadLength($typelen); + $this->Elements[NET_DIME_TYPE] = $typestring; + } + + function generateID() + { + $id = md5(time()); + $this->setID($id); + return $id; + } + + function setID($id) + { + $idlen = strlen($id) & 0xFFFF; + $this->Elements[NET_DIME_ID_LEN] = $idlen; + $this->ID_LENGTH = $this->_getPadLength($idlen); + $this->Elements[NET_DIME_ID] = $id; + } + + function setData($data, $size=0) + { + $datalen = $size?$size:strlen($data); + $this->Elements[NET_DIME_DATA_LEN] = $datalen; + $this->DATA_LENGTH = $this->_getPadLength($datalen); + $this->Elements[NET_DIME_DATA] = $data; + } + + function encode() + { + // insert version + $this->Elements[NET_DIME_FLAGS] = ($this->Elements[NET_DIME_FLAGS] & 0x07FF) | (NET_DIME_VERSION << 11); + + // the real dime encoding + $format = '%c%c%c%c%c%c%c%c%c%c%c%c'. + '%'.$this->OPTS_LENGTH.'s'. + '%'.$this->ID_LENGTH.'s'. + '%'.$this->TYPE_LENGTH.'s'. + '%'.$this->DATA_LENGTH.'s'; + return sprintf($format, + ($this->Elements[NET_DIME_FLAGS]&0x0000FF00)>>8, + ($this->Elements[NET_DIME_FLAGS]&0x000000FF), + ($this->Elements[NET_DIME_OPTS_LEN]&0x0000FF00)>>8, + ($this->Elements[NET_DIME_OPTS_LEN]&0x000000FF), + ($this->Elements[NET_DIME_ID_LEN]&0x0000FF00)>>8, + ($this->Elements[NET_DIME_ID_LEN]&0x000000FF), + ($this->Elements[NET_DIME_TYPE_LEN]&0x0000FF00)>>8, + ($this->Elements[NET_DIME_TYPE_LEN]&0x000000FF), + ($this->Elements[NET_DIME_DATA_LEN]&0xFF000000)>>24, + ($this->Elements[NET_DIME_DATA_LEN]&0x00FF0000)>>16, + ($this->Elements[NET_DIME_DATA_LEN]&0x0000FF00)>>8, + ($this->Elements[NET_DIME_DATA_LEN]&0x000000FF), + str_pad($this->Elements[NET_DIME_OPTS], $this->OPTS_LENGTH, $this->padstr), + str_pad($this->Elements[NET_DIME_ID], $this->ID_LENGTH, $this->padstr), + str_pad($this->Elements[NET_DIME_TYPE], $this->TYPE_LENGTH, $this->padstr), + str_pad($this->Elements[NET_DIME_DATA], $this->DATA_LENGTH, $this->padstr)); + } + + function _getPadLength($len) + { + $pad = 0; + if ($len) { + $pad = $len % 4; + if ($pad) $pad = 4 - $pad; + } + return $len + $pad; + } + + function decode(&$data) + { + // REAL DIME decoding + $this->Elements[NET_DIME_FLAGS] = (hexdec(bin2hex($data[0]))<<8) + hexdec(bin2hex($data[1])); + $this->Elements[NET_DIME_OPTS_LEN] = (hexdec(bin2hex($data[2]))<<8) + hexdec(bin2hex($data[3])); + $this->Elements[NET_DIME_ID_LEN] = (hexdec(bin2hex($data[4]))<<8) + hexdec(bin2hex($data[5])); + $this->Elements[NET_DIME_TYPE_LEN] = (hexdec(bin2hex($data[6]))<<8) + hexdec(bin2hex($data[7])); + $this->Elements[NET_DIME_DATA_LEN] = (hexdec(bin2hex($data[8]))<<24) + + (hexdec(bin2hex($data[9]))<<16) + + (hexdec(bin2hex($data[10]))<<8) + + hexdec(bin2hex($data[11])); + $p = 12; + + $version = (($this->Elements[NET_DIME_FLAGS]>>11) & 0x001F); + + if ($version == NET_DIME_VERSION) + { + $this->OPTS_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_OPTS_LEN]); + $this->ID_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_ID_LEN]); + $this->TYPE_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_TYPE_LEN]); + $this->DATA_LENGTH = $this->_getPadLength($this->Elements[NET_DIME_DATA_LEN]); + + $datalen = strlen($data); + $this->Elements[NET_DIME_OPTS] = substr($data,$p,$this->Elements[NET_DIME_OPTS_LEN]); + $this->_haveOpts = (strlen($this->Elements[NET_DIME_OPTS]) == $this->Elements[NET_DIME_OPTS_LEN]); + if ($this->_haveOpts) { + $p += $this->OPTS_LENGTH; + $this->Elements[NET_DIME_ID] = substr($data,$p,$this->Elements[NET_DIME_ID_LEN]); + $this->_haveID = (strlen($this->Elements[NET_DIME_ID]) == $this->Elements[NET_DIME_ID_LEN]); + if ($this->_haveID) { + $p += $this->ID_LENGTH; + $this->Elements[NET_DIME_TYPE] = substr($data,$p,$this->Elements[NET_DIME_TYPE_LEN]); + $this->_haveType = (strlen($this->Elements[NET_DIME_TYPE]) == $this->Elements[NET_DIME_TYPE_LEN]); + if ($this->_haveType) { + $p += $this->TYPE_LENGTH; + $this->Elements[NET_DIME_DATA] = substr($data,$p,$this->Elements[NET_DIME_DATA_LEN]); + $this->_haveData = (strlen($this->Elements[NET_DIME_DATA]) == $this->Elements[NET_DIME_DATA_LEN]); + if ($this->_haveData) { + $p += $this->DATA_LENGTH; + } else { + $p += strlen($this->Elements[NET_DIME_DATA]); + } + } else { + $p += strlen($this->Elements[NET_DIME_TYPE]); + } + } else { + $p += strlen($this->Elements[NET_DIME_ID]); + } + } else { + $p += strlen($this->Elements[NET_DIME_OPTS]); + } + } + return substr($data, $p); + } + + function addData(&$data) + { + $datalen = strlen($data); + $p = 0; + if (!$this->_haveOpts) { + $have = strlen($this->Elements[NET_DIME_OPTS]); + $this->Elements[NET_DIME_OPTS] .= substr($data,$p,$this->Elements[NET_DIME_OPTS_LEN]-$have); + $this->_haveOpts = (strlen($this->Elements[NET_DIME_OPTS]) == $this->Elements[DIME_OTPS_LEN]); + if (!$this->_haveOpts) return NULL; + $p += $this->OPTS_LENGTH-$have; + } + if (!$this->_haveID) { + $have = strlen($this->Elements[NET_DIME_ID]); + $this->Elements[NET_DIME_ID] .= substr($data,$p,$this->Elements[NET_DIME_ID_LEN]-$have); + $this->_haveID = (strlen($this->Elements[NET_DIME_ID]) == $this->Elements[NET_DIME_ID_LEN]); + if (!$this->_haveID) return NULL; + $p += $this->ID_LENGTH-$have; + } + if (!$this->_haveType && $p < $datalen) { + $have = strlen($this->Elements[NET_DIME_TYPE]); + $this->Elements[NET_DIME_TYPE] .= substr($data,$p,$this->Elements[NET_DIME_TYPE_LEN]-$have); + $this->_haveType = (strlen($this->Elements[NET_DIME_TYPE]) == $this->Elements[NET_DIME_TYPE_LEN]); + if (!$this->_haveType) return NULL; + $p += $this->TYPE_LENGTH-$have; + } + if (!$this->_haveData && $p < $datalen) { + $have = strlen($this->Elements[NET_DIME_DATA]); + $this->Elements[NET_DIME_DATA] .= substr($data,$p,$this->Elements[NET_DIME_DATA_LEN]-$have); + $this->_haveData = (strlen($this->Elements[NET_DIME_DATA]) == $this->Elements[NET_DIME_DATA_LEN]); + if (!$this->_haveData) return NULL; + $p += $this->DATA_LENGTH-$have; + } + return substr($data,$p); + } +} + + +class Net_DIME_Message extends PEAR +{ + + var $record_size = 4096; + #var $records =array(); + var $parts = array(); + var $currentPart = -1; + var $stream = NULL; + var $_currentRecord; + var $_proc = array(); + var $type; + var $typestr; + var $mb = 1; + var $me = 0; + var $cf = 0; + var $id = NULL; + var $debug = FALSE; + /** + * constructor + * + * this currently takes a file pointer as provided + * by fopen + * + * TODO: integrate with the php streams stuff + */ + function Net_DIME_Message($stream=NULL, $record_size = 4096, $debug = FALSE) + { + $this->stream = $stream; + $this->record_size = $record_size; + $this->debug = $debug; + } + + function _makeRecord(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $record = new Net_DIME_Record($this->debug); + if ($this->mb) { + $record->setMB(); + // all subsequent records are not message begin! + $this->mb = 0; + } + if ($this->me) $record->setME(); + if ($this->cf) $record->setCF(); + $record->setData($data); + $record->setType($typestr,$type); + if ($id) $record->setID($id); + #if ($this->debug) { + # print str_replace('\0','*',$record->encode()); + #} + return $record->encode(); + } + + function startChunk(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $this->me = 0; + $this->cf = 1; + $this->type = $type; + $this->typestr = $typestr; + if ($id) { + $this->id = $id; + } else { + $this->id = md5(time()); + } + return $this->_makeRecord($data, $this->typestr, $this->id, $this->type); + } + + function doChunk(&$data) + { + $this->me = 0; + $this->cf = 1; + return $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_UNCHANGED); + } + + function endChunk() + { + $this->cf = 0; + $data = NULL; + $rec = $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_UNCHANGED); + $this->id = 0; + $this->cf = 0; + $this->id = 0; + $this->type = NET_DIME_TYPE_UNKNOWN; + $this->typestr = NULL; + return $rec; + } + + function endMessage() + { + $this->me = 1; + $data = NULL; + $rec = $this->_makeRecord($data, NULL, NULL, NET_DIME_TYPE_NONE); + $this->me = 0; + $this->mb = 1; + $this->id = 0; + return $rec; + } + + /** + * sendRecord + * + * given a chunk of data, it creates DIME records + * and writes them to the stream + * + */ + function sendData(&$data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $len = strlen($data); + if ($len > $this->record_size) { + $chunk = substr($data, 0, $this->record_size); + $p = $this->record_size; + $rec = $this->startChunk($chunk,$typestr,$id,$type); + fwrite($this->stream, $rec); + while ($p < $len) { + $chunk = substr($data, $p, $this->record_size); + $p += $this->record_size; + $rec = $this->doChunk($chunk); + fwrite($this->stream, $rec); + } + $rec = $this->endChunk(); + fwrite($this->stream, $rec); + return; + } + $rec = $this->_makeRecord($data, $typestr,$id,$type); + fwrite($this->stream, $rec); + } + + function sendEndMessage() + { + $rec = $this->endMessage(); + fwrite($this->stream, $rec); + } + + /** + * sendFile + * + * given a filename, it reads the file, + * creates records and writes them to the stream + * + */ + function sendFile($filename, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $f = fopen($filename, "rb"); + if ($f) { + if ($data = fread($f, $this->record_size)) { + $this->startChunk($data,$typestr,$id,$type); + } + while ($data = fread($f, $this->record_size)) { + $this->doChunk($data,$typestr,$id,$type); + } + $this->endChunk(); + fclose($f); + } + } + + /** + * encodeData + * + * given data, encode it in DIME + * + */ + function encodeData($data, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $len = strlen($data); + $resp = ''; + if ($len > $this->record_size) { + $chunk = substr($data, 0, $this->record_size); + $p = $this->record_size; + $resp .= $this->startChunk($chunk,$typestr,$id,$type); + while ($p < $len) { + $chunk = substr($data, $p, $this->record_size); + $p += $this->record_size; + $resp .= $this->doChunk($chunk); + } + $resp .= $this->endChunk(); + } else { + $resp .= $this->_makeRecord($data, $typestr,$id,$type); + } + return $resp; + } + + /** + * sendFile + * + * given a filename, it reads the file, + * creates records and writes them to the stream + * + */ + function encodeFile($filename, $typestr='', $id=NULL, $type=NET_DIME_TYPE_UNKNOWN) + { + $f = fopen($filename, "rb"); + if ($f) { + if ($data = fread($f, $this->record_size)) { + $resp = $this->startChunk($data,$typestr,$id,$type); + } + while ($data = fread($f, $this->record_size)) { + $resp = $this->doChunk($data,$typestr,$id,$type); + } + $resp = $this->endChunk(); + fclose($f); + } + return $resp; + } + + /** + * _processData + * + * creates Net_DIME_Records from provided data + * + */ + function _processData(&$data) + { + $leftover = NULL; + if (!$this->_currentRecord) { + $this->_currentRecord = new Net_DIME_Record($this->debug); + $data = $this->_currentRecord->decode($data); + } else { + $data = $this->_currentRecord->addData($data); + } + + if ($this->_currentRecord->_haveData) { + if (count($this->parts)==0 && !$this->_currentRecord->isStart()) { + // raise an error! + return PEAR::raiseError('First Message is not a DIME begin record!'); + } + + if ($this->_currentRecord->isEnd() && $this->_currentRecord->getDataLength()==0) { + return NULL; + } + + if ($this->currentPart < 0 && !$this->_currentRecord->isChunk()) { + $this->parts[] = array(); + $this->currentPart = count($this->parts)-1; + $this->parts[$this->currentPart]['id'] = $this->_currentRecord->getID(); + $this->parts[$this->currentPart]['type'] = $this->_currentRecord->getType(); + $this->parts[$this->currentPart]['data'] = $this->_currentRecord->getData(); + $this->currentPart = -1; + } else { + if ($this->currentPart < 0) { + $this->parts[] = array(); + $this->currentPart = count($this->parts)-1; + $this->parts[$this->currentPart]['id'] = $this->_currentRecord->getID(); + $this->parts[$this->currentPart]['type'] = $this->_currentRecord->getType(); + $this->parts[$this->currentPart]['data'] = $this->_currentRecord->getData(); + } else { + $this->parts[$this->currentPart]['data'] .= $this->_currentRecord->getData(); + if (!$this->_currentRecord->isChunk()) { + // we reached the end of the chunk + $this->currentPart = -1; + } + } + } + #$this->records[] = $this->_currentRecord; + if (!$this->_currentRecord->isEnd()) $this->_currentRecord = NULL; + } + return NULL; + } + + /** + * decodeData + * + * decodes a DIME encrypted string of data + * + */ + function decodeData(&$data) { + while (strlen($data) >= NET_DIME_RECORD_HEADER) { + $err = $this->_processData($data); + if (PEAR::isError($err)) { + return $err; + } + } + } + + /** + * read + * + * reads the stream and creates + * an array of records + * + * it can accept the start of a previously read buffer + * this is usefull in situations where you need to read + * headers before discovering that the data is DIME encoded + * such as in the case of reading an HTTP response. + */ + function read($buf=NULL) + { + while ($data = fread($this->stream, 8192)) { + if ($buf) { + $data = $buf.$data; + $buf = NULL; + } + if ($this->debug) + echo "read: ".strlen($data)." bytes\n"; + $err = $this->decodeData($data); + if (PEAR::isError($err)) { + return $err; + } + + // store any leftover data to be used again + // should be < NET_DIME_RECORD_HEADER bytes + $buf = $data; + } + if (!$this->_currentRecord || !$this->_currentRecord->isEnd()) { + return PEAR::raiseError('reached stream end without end record'); + } + return NULL; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Net/FTP.php b/gulliver/thirdparty/pear/Net/FTP.php new file mode 100644 index 000000000..bd6e6b3b7 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/FTP.php @@ -0,0 +1,2332 @@ + + * @author Jorrit Schippers + * @copyright 1997-2008 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id: FTP.php,v 1.53.2.10 2008/05/19 18:01:08 jschippers Exp $ + * @link http://pear.php.net/package/Net_FTP + * @since File available since Release 0.0.1 + */ + +/** + * Include PEAR.php to obtain the PEAR base class + */ +require_once 'PEAR.php'; + +/** + * Option to let the ls() method return only files. + * + * @since 1.3 + * @name NET_FTP_FILES_ONLY + * @see Net_FTP::ls() + */ +define('NET_FTP_FILES_ONLY', 0, true); + +/** + * Option to let the ls() method return only directories. + * + * @since 1.3 + * @name NET_FTP_DIRS_ONLY + * @see Net_FTP::ls() + */ +define('NET_FTP_DIRS_ONLY', 1, true); + +/** + * Option to let the ls() method return directories and files (default). + * + * @since 1.3 + * @name NET_FTP_DIRS_FILES + * @see Net_FTP::ls() + */ +define('NET_FTP_DIRS_FILES', 2, true); + +/** + * Option to let the ls() method return the raw directory listing from ftp_rawlist() + * + * @since 1.3 + * @name NET_FTP_RAWLIST + * @see Net_FTP::ls() + */ +define('NET_FTP_RAWLIST', 3, true); + +/** + * Error code to indicate a failed connection + * This error code indicates, that the connection you tryed to set up + * could not be established. Check your connection settings (host & port)! + * + * @since 1.3 + * @name NET_FTP_ERR_CONNECT_FAILED + * @see Net_FTP::connect() + */ +define('NET_FTP_ERR_CONNECT_FAILED', -1); + +/** + * Error code to indicate a failed login + * This error code indicates, that the login to the FTP server failed. Check + * your user data (username & password). + * + * @since 1.3 + * @name NET_FTP_ERR_LOGIN_FAILED + * @see Net_FTP::login() + */ +define('NET_FTP_ERR_LOGIN_FAILED', -2); + +/** + * Error code to indicate a failed directory change + * The cd() method failed. Ensure that the directory you wanted to access exists. + * + * @since 1.3 + * @name NET_FTP_ERR_DIRCHANGE_FAILED + * @see Net_FTP::cd() + */ +define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons! + +/** + * Error code to indicate that Net_FTP could not determine the current path + * The cwd() method failed and could not determine the path you currently reside + * in on the FTP server. + * + * @since 1.3 + * @name NET_FTP_ERR_DETERMINEPATH_FAILED + * @see Net_FTP::pwd() + */ +define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons! + +/** + * Error code to indicate that the creation of a directory failed + * The directory you tryed to create could not be created. Check the + * access rights on the parent directory! + * + * @since 1.3 + * @name NET_FTP_ERR_CREATEDIR_FAILED + * @see Net_FTP::mkdir() + */ +define('NET_FTP_ERR_CREATEDIR_FAILED', -4); + +/** + * Error code to indicate that the EXEC execution failed. + * The execution of a command using EXEC failed. Ensure, that your + * FTP server supports the EXEC command. + * + * @since 1.3 + * @name NET_FTP_ERR_EXEC_FAILED + * @see Net_FTP::execute() + */ +define('NET_FTP_ERR_EXEC_FAILED', -5); + +/** + * Error code to indicate that the SITE command failed. + * The execution of a command using SITE failed. Ensure, that your + * FTP server supports the SITE command. + * + * @since 1.3 + * @name NET_FTP_ERR_SITE_FAILED + * @see Net_FTP::site() + */ +define('NET_FTP_ERR_SITE_FAILED', -6); + +/** + * Error code to indicate that the CHMOD command failed. + * The execution of CHMOD failed. Ensure, that your + * FTP server supports the CHMOD command and that you have the appropriate + * access rights to use CHMOD. + * + * @since 1.3 + * @name NET_FTP_ERR_CHMOD_FAILED + * @see Net_FTP::chmod() + */ +define('NET_FTP_ERR_CHMOD_FAILED', -7); + +/** + * Error code to indicate that a file rename failed + * The renaming of a file on the server failed. Ensure that you have the + * appropriate access rights to rename the file. + * + * @since 1.3 + * @name NET_FTP_ERR_RENAME_FAILED + * @see Net_FTP::rename() + */ +define('NET_FTP_ERR_RENAME_FAILED', -8); + +/** + * Error code to indicate that the MDTM command failed + * The MDTM command is not supported for directories. Ensure that you gave + * a file path to the mdtm() method, not a directory path. + * + * @since 1.3 + * @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED + * @see Net_FTP::mdtm() + */ +define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9); + +/** + * Error code to indicate that the MDTM command failed + * The MDTM command failed. Ensure that your server supports the MDTM command. + * + * @since 1.3 + * @name NET_FTP_ERR_MDTM_FAILED + * @see Net_FTP::mdtm() + */ +define('NET_FTP_ERR_MDTM_FAILED', -10); + +/** + * Error code to indicate that a date returned by the server was misformated + * A date string returned by your server seems to be missformated and could not be + * parsed. Check that the server is configured correctly. If you're sure, please + * send an email to the auhtor with a dumped output of + * $ftp->ls('./', NET_FTP_RAWLIST); to get the date format supported. + * + * @since 1.3 + * @name NET_FTP_ERR_DATEFORMAT_FAILED + * @see Net_FTP::mdtm(), Net_FTP::ls() + */ +define('NET_FTP_ERR_DATEFORMAT_FAILED', -11); + +/** + * Error code to indicate that the SIZE command failed + * The determination of the filesize of a file failed. Ensure that your server + * supports the SIZE command. + * + * @since 1.3 + * @name NET_FTP_ERR_SIZE_FAILED + * @see Net_FTP::size() + */ +define('NET_FTP_ERR_SIZE_FAILED', -12); + +/** + * Error code to indicate that a local file could not be overwritten + * You specified not to overwrite files. Therefore the local file has not been + * overwriten. If you want to get the file overwriten, please set the option to + * do so. + * + * @since 1.3 + * @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN + * @see Net_FTP::get(), Net_FTP::getRecursive() + */ +define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13); + +/** + * Error code to indicate that a local file could not be overwritten + * Also you specified to overwrite the local file you want to download to, + * it has not been possible to do so. Check that you have the appropriate access + * rights on the local file to overwrite it. + * + * @since 1.3 + * @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED + * @see Net_FTP::get(), Net_FTP::getRecursive() + */ +define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14); + +/** + * Error code to indicate that the file you wanted to upload does not exist + * The file you tried to upload does not exist. Ensure that it exists. + * + * @since 1.3 + * @name NET_FTP_ERR_LOCALFILENOTEXIST + * @see Net_FTP::put(), Net_FTP::putRecursive() + */ +define('NET_FTP_ERR_LOCALFILENOTEXIST', -15); + +/** + * Error code to indicate that a remote file could not be overwritten + * You specified not to overwrite files. Therefore the remote file has not been + * overwriten. If you want to get the file overwriten, please set the option to + * do so. + * + * @since 1.3 + * @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN + * @see Net_FTP::put(), Net_FTP::putRecursive() + */ +define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16); + +/** + * Error code to indicate that the upload of a file failed + * The upload you tried failed. Ensure that you have appropriate access rights + * to upload the desired file. + * + * @since 1.3 + * @name NET_FTP_ERR_UPLOADFILE_FAILED + * @see Net_FTP::put(), Net_FTP::putRecursive() + */ +define('NET_FTP_ERR_UPLOADFILE_FAILED', -17); + +/** + * Error code to indicate that you specified an incorrect directory path + * The remote path you specified seems not to be a directory. Ensure that + * the path you specify is a directory and that the path string ends with + * a /. + * + * @since 1.3 + * @name NET_FTP_ERR_REMOTEPATHNODIR + * @see Net_FTP::putRecursive(), Net_FTP::getRecursive() + */ +define('NET_FTP_ERR_REMOTEPATHNODIR', -18); + +/** + * Error code to indicate that you specified an incorrect directory path + * The local path you specified seems not to be a directory. Ensure that + * the path you specify is a directory and that the path string ends with + * a /. + * + * @since 1.3 + * @name NET_FTP_ERR_LOCALPATHNODIR + * @see Net_FTP::putRecursive(), Net_FTP::getRecursive() + */ +define('NET_FTP_ERR_LOCALPATHNODIR', -19); + +/** + * Error code to indicate that a local directory failed to be created + * You tried to create a local directory through getRecursive() method, + * which has failed. Ensure that you have the appropriate access rights + * to create it. + * + * @since 1.3 + * @name NET_FTP_ERR_CREATELOCALDIR_FAILED + * @see Net_FTP::getRecursive() + */ +define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20); + +/** + * Error code to indicate that the provided hostname was incorrect + * The hostname you provided was invalid. Ensure to provide either a + * full qualified domain name or an IP address. + * + * @since 1.3 + * @name NET_FTP_ERR_HOSTNAMENOSTRING + * @see Net_FTP::setHostname() + */ +define('NET_FTP_ERR_HOSTNAMENOSTRING', -21); + +/** + * Error code to indicate that the provided port was incorrect + * The port number you provided was invalid. Ensure to provide either a + * a numeric port number greater zero. + * + * @since 1.3 + * @name NET_FTP_ERR_PORTLESSZERO + * @see Net_FTP::setPort() + */ +define('NET_FTP_ERR_PORTLESSZERO', -22); + +/** + * Error code to indicate that you provided an invalid mode constant + * The mode constant you provided was invalid. You may only provide + * FTP_ASCII or FTP_BINARY. + * + * @since 1.3 + * @name NET_FTP_ERR_NOMODECONST + * @see Net_FTP::setMode() + */ +define('NET_FTP_ERR_NOMODECONST', -23); + +/** + * Error code to indicate that you provided an invalid timeout + * The timeout you provided was invalid. You have to provide a timeout greater + * or equal to zero. + * + * @since 1.3 + * @name NET_FTP_ERR_TIMEOUTLESSZERO + * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() + */ +define('NET_FTP_ERR_TIMEOUTLESSZERO', -24); + +/** + * Error code to indicate that you provided an invalid timeout + * An error occured while setting the timeout. Ensure that you provide a + * valid integer for the timeount and that your PHP installation works + * correctly. + * + * @since 1.3 + * @name NET_FTP_ERR_SETTIMEOUT_FAILED + * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout() + */ +define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25); + +/** + * Error code to indicate that the provided extension file doesn't exist + * The provided extension file does not exist. Ensure to provided an + * existant extension file. + * + * @since 1.3 + * @name NET_FTP_ERR_EXTFILENOTEXIST + * @see Net_FTP::getExtensionsFile() + */ +define('NET_FTP_ERR_EXTFILENOTEXIST', -26); + +/** + * Error code to indicate that the provided extension file is not readable + * The provided extension file is not readable. Ensure to have sufficient + * access rights for it. + * + * @since 1.3 + * @name NET_FTP_ERR_EXTFILEREAD_FAILED + * @see Net_FTP::getExtensionsFile() + */ +define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27); + +/** + * Error code to indicate that the deletion of a file failed + * The specified file could not be deleted. Ensure to have sufficient + * access rights to delete the file. + * + * @since 1.3 + * @name NET_FTP_ERR_EXTFILEREAD_FAILED + * @see Net_FTP::rm() + */ +define('NET_FTP_ERR_DELETEFILE_FAILED', -28); + +/** + * Error code to indicate that the deletion of a directory faild + * The specified file could not be deleted. Ensure to have sufficient + * access rights to delete the file. + * + * @since 1.3 + * @name NET_FTP_ERR_EXTFILEREAD_FAILED + * @see Net_FTP::rm() + */ +define('NET_FTP_ERR_DELETEDIR_FAILED', -29); + +/** + * Error code to indicate that the directory listing failed + * PHP could not list the directory contents on the server. Ensure + * that your server is configured appropriate. + * + * @since 1.3 + * @name NET_FTP_ERR_RAWDIRLIST_FAILED + * @see Net_FTP::ls() + */ +define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30); + +/** + * Error code to indicate that the directory listing failed + * The directory listing format your server uses seems not to + * be supported by Net_FTP. Please send the output of the + * call ls('./', NET_FTP_RAWLIST); to the author of this + * class to get it supported. + * + * @since 1.3 + * @name NET_FTP_ERR_DIRLIST_UNSUPPORTED + * @see Net_FTP::ls() + */ +define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31); + +/** + * Error code to indicate failed disconnecting + * This error code indicates, that disconnection was not possible. + * + * @since 1.3 + * @name NET_FTP_ERR_DISCONNECT_FAILED + * @see Net_FTP::disconnect() + */ +define('NET_FTP_ERR_DISCONNECT_FAILED', -32); + +/** + * Error code to indicate that the username you provided was invalid. + * Check that you provided a non-empty string as the username. + * + * @since 1.3 + * @name NET_FTP_ERR_USERNAMENOSTRING + * @see Net_FTP::setUsername() + */ +define('NET_FTP_ERR_USERNAMENOSTRING', -33); + +/** + * Error code to indicate that the username you provided was invalid. + * Check that you provided a non-empty string as the username. + * + * @since 1.3 + * @name NET_FTP_ERR_PASSWORDNOSTRING + * @see Net_FTP::setPassword() + */ +define('NET_FTP_ERR_PASSWORDNOSTRING', -34); + +/** + * Error code to indicate that the provided extension file is not loadable + * The provided extension file is not loadable. Ensure to have a correct file + * syntax. + * + * @since 1.3.3 + * @name NET_FTP_ERR_EXTFILELOAD_FAILED + * @see Net_FTP::getExtensionsFile() + */ +define('NET_FTP_ERR_EXTFILELOAD_FAILED', -35); + +/** + * Class for comfortable FTP-communication + * + * This class provides comfortable communication with FTP-servers. You may do + * everything enabled by the PHP-FTP-extension and further functionalities, like + * recursive-deletion, -up- and -download. Another feature is to create directories + * recursively. + * + * @category Networking + * @package FTP + * @author Tobias Schlitt + * @author Jorrit Schippers + * @copyright 1997-2008 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: 1.3.7 + * @link http://pear.php.net/package/Net_FTP + * @since 0.0.1 + * @access public + */ +class Net_FTP extends PEAR +{ + /** + * The host to connect to + * + * @access private + * @var string + */ + var $_hostname; + + /** + * The port for ftp-connection (standard is 21) + * + * @access private + * @var int + */ + var $_port = 21; + + /** + * The username for login + * + * @access private + * @var string + */ + var $_username; + + /** + * The password for login + * + * @access private + * @var string + */ + var $_password; + + /** + * Determine whether to use passive-mode (true) or active-mode (false) + * + * @access private + * @var bool + */ + var $_passv; + + /** + * The standard mode for ftp-transfer + * + * @access private + * @var int + */ + var $_mode = FTP_BINARY; + + /** + * This holds the handle for the ftp-connection + * + * @access private + * @var resource + */ + var $_handle; + + /** + * Contains the timeout for FTP operations + * + * @access private + * @var int + * @since 1.3 + */ + var $_timeout = 90; + + /** + * Saves file-extensions for ascii- and binary-mode + * + * The array contains 2 sub-arrays ("ascii" and "binary"), which both contain + * file-extensions without the "." (".php" = "php"). + * + * @access private + * @var array + */ + var $_file_extensions; + + /** + * ls match + * Matches the ls entries against a regex and maps the resulting array to + * speaking names + * + * The values are set in the constructor because of line length constaints. + * + * Typical lines for the Windows format: + * 07-05-07 08:40AM 4701 SomeFile.ext + * 04-29-07 10:28PM
    SomeDir + * + * @access private + * @var array + * @since 1.3 + */ + var $_ls_match = null; + + /** + * matcher + * Stores the matcher for the current connection + * + * @access private + * @var array + * @since 1.3 + */ + var $_matcher = null; + + /** + * Holds all Net_FTP_Observer objects + * that wish to be notified of new messages. + * + * @var array + * @access private + * @since 1.3 + */ + var $_listeners = array(); + + /** + * This generates a new FTP-Object. The FTP-connection will not be established, + * yet. + * You can leave $host and $port blank, if you want. The $host will not be set + * and the $port will be left at 21. You have to set the $host manualy before + * trying to connect or with the connect() method. + * + * @param string $host (optional) The hostname + * @param int $port (optional) The port + * @param int $timeout (optional) Sets the standard timeout + * + * @access public + * @return void + * @see Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect() + */ + function Net_FTP($host = null, $port = null, $timeout = 90) + { + $this->PEAR(); + if (isset($host)) { + $this->setHostname($host); + } + if (isset($port)) { + $this->setPort($port); + } + $this->_timeout = $timeout; + $this->_file_extensions[FTP_ASCII] = array(); + $this->_file_extensions[FTP_BINARY] = array(); + + $this->_ls_match = array( + 'unix' => array( + 'pattern' => '/(?:(d)|.)([rwxts-]{9})\s+(\w+)\s+([\w\d-()?.]+)\s+'. + '([\w\d-()?.]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/', + 'map' => array( + 'is_dir' => 1, + 'rights' => 2, + 'files_inside' => 3, + 'user' => 4, + 'group' => 5, + 'size' => 6, + 'date' => 7, + 'name' => 8, + ) + ), + 'windows' => array( + 'pattern' => '/([0-9\-]+)\s+([0-9:APM]+)\s+(()|\d+)\s+(.+)/', + 'map' => array( + 'date' => 1, + 'time' => 2, + 'size' => 3, + 'is_dir' => 4, + 'name' => 5, + ) + ) + ); + } + + /** + * This function generates the FTP-connection. You can optionally define a + * hostname and/or a port. If you do so, this data is stored inside the object. + * + * @param string $host (optional) The Hostname + * @param int $port (optional) The Port + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_CONNECT_FAILED + */ + function connect($host = null, $port = null) + { + $this->_matcher = null; + if (isset($host)) { + $this->setHostname($host); + } + if (isset($port)) { + $this->setPort($port); + } + $handle = @ftp_connect($this->getHostname(), $this->getPort(), + $this->_timeout); + if (!$handle) { + return $this->raiseError("Connection to host failed", + NET_FTP_ERR_CONNECT_FAILED); + } else { + $this->_handle =& $handle; + return true; + } + } + + /** + * This function close the FTP-connection + * + * @access public + * @return bool|PEAR_Error Returns true on success, PEAR_Error on failure + */ + function disconnect() + { + $res = @ftp_close($this->_handle); + if (!$res) { + return PEAR::raiseError('Disconnect failed.', + NET_FTP_ERR_DISCONNECT_FAILED); + } + return true; + } + + /** + * This logs you into the ftp-server. You are free to specify username and + * password in this method. If you specify it, the values will be taken into + * the corresponding attributes, if do not specify, the attributes are taken. + * + * @param string $username (optional) The username to use + * @param string $password (optional) The password to use + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_LOGIN_FAILED + */ + function login($username = null, $password = null) + { + if (!isset($username)) { + $username = $this->getUsername(); + } else { + $this->setUsername($username); + } + + if (!isset($password)) { + $password = $this->getPassword(); + } else { + $this->setPassword($password); + } + + $res = @ftp_login($this->_handle, $username, $password); + + if (!$res) { + return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED); + } else { + return true; + } + } + + /** + * This changes the currently used directory. You can use either an absolute + * directory-path (e.g. "/home/blah") or a relative one (e.g. "../test"). + * + * @param string $dir The directory to go to. + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_DIRCHANGE_FAILED + */ + function cd($dir) + { + $erg = @ftp_chdir($this->_handle, $dir); + if (!$erg) { + return $this->raiseError("Directory change failed", + NET_FTP_ERR_DIRCHANGE_FAILED); + } else { + return true; + } + } + + /** + * Show's you the actual path on the server + * This function questions the ftp-handle for the actual selected path and + * returns it. + * + * @access public + * @return mixed The actual path or PEAR::Error + * @see NET_FTP_ERR_DETERMINEPATH_FAILED + */ + function pwd() + { + $res = @ftp_pwd($this->_handle); + if (!$res) { + return $this->raiseError("Could not determine the actual path.", + NET_FTP_ERR_DETERMINEPATH_FAILED); + } else { + return $res; + } + } + + /** + * This works similar to the mkdir-command on your local machine. You can either + * give it an absolute or relative path. The relative path will be completed + * with the actual selected server-path. (see: pwd()) + * + * @param string $dir Absolute or relative dir-path + * @param bool $recursive (optional) Create all needed directories + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_CREATEDIR_FAILED + */ + function mkdir($dir, $recursive = false) + { + $dir = $this->_constructPath($dir); + $savedir = $this->pwd(); + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $e = $this->cd($dir); + $this->popErrorHandling(); + if ($e === true) { + $this->cd($savedir); + return true; + } + $this->cd($savedir); + if ($recursive === false) { + $res = @ftp_mkdir($this->_handle, $dir); + if (!$res) { + return $this->raiseError("Creation of '$dir' failed", + NET_FTP_ERR_CREATEDIR_FAILED); + } else { + return true; + } + } else { + // do not look at the first character, as $dir is absolute, + // it will always be a / + if (strpos(substr($dir, 1), '/') === false) { + return $this->mkdir($dir, false); + } + if (substr($dir, -1) == '/') { + $dir = substr($dir, 0, -1); + } + $parent = substr($dir, 0, strrpos($dir, '/')); + $res = $this->mkdir($parent, true); + if ($res === true) { + $res = $this->mkdir($dir, false); + } + if ($res !== true) { + return $res; + } + return true; + } + } + + /** + * This method tries executing a command on the ftp, using SITE EXEC. + * + * @param string $command The command to execute + * + * @access public + * @return mixed The result of the command (if successfull), otherwise + * PEAR::Error + * @see NET_FTP_ERR_EXEC_FAILED + */ + function execute($command) + { + $res = @ftp_exec($this->_handle, $command); + if (!$res) { + return $this->raiseError("Execution of command '$command' failed.", + NET_FTP_ERR_EXEC_FAILED); + } else { + return $res; + } + } + + /** + * Execute a SITE command on the server + * This method tries to execute a SITE command on the ftp server. + * + * @param string $command The command with parameters to execute + * + * @access public + * @return mixed True if successful, otherwise PEAR::Error + * @see NET_FTP_ERR_SITE_FAILED + */ + function site($command) + { + $res = @ftp_site($this->_handle, $command); + if (!$res) { + return $this->raiseError("Execution of SITE command '$command' failed.", + NET_FTP_ERR_SITE_FAILED); + } else { + return $res; + } + } + + /** + * This method will try to chmod the file specified on the server + * Currently, you must give a number as the the permission argument (777 or + * similar). The file can be either a relative or absolute path. + * NOTE: Some servers do not support this feature. In that case, you will + * get a PEAR error object returned. If successful, the method returns true + * + * @param mixed $target The file or array of files to set permissions for + * @param integer $permissions The mode to set the file permissions to + * + * @access public + * @return mixed True if successful, otherwise PEAR::Error + * @see NET_FTP_ERR_CHMOD_FAILED + */ + function chmod($target, $permissions) + { + // If $target is an array: Loop through it. + if (is_array($target)) { + + for ($i = 0; $i < count($target); $i++) { + $res = $this->chmod($target[$i], $permissions); + if (PEAR::isError($res)) { + return $res; + } // end if isError + } // end for i < count($target) + + } else { + + $res = $this->site("CHMOD " . $permissions . " " . $target); + if (!$res) { + return PEAR::raiseError("CHMOD " . $permissions . " " . $target . + " failed", NET_FTP_ERR_CHMOD_FAILED); + } else { + return $res; + } + + } // end if is_array + + } // end method chmod + + /** + * This method will try to chmod a folder and all of its contents + * on the server. The target argument must be a folder or an array of folders + * and the permissions argument have to be an integer (i.e. 777). + * The file can be either a relative or absolute path. + * NOTE: Some servers do not support this feature. In that case, you + * will get a PEAR error object returned. If successful, the method + * returns true + * + * @param mixed $target The folder or array of folders to + * set permissions for + * @param integer $permissions The mode to set the folder + * and file permissions to + * + * @access public + * @return mixed True if successful, otherwise PEAR::Error + * @see NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED, + * NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED + */ + function chmodRecursive($target, $permissions) + { + static $dir_permissions; + + if (!isset($dir_permissions)) { // Making directory specific permissions + $dir_permissions = $this->_makeDirPermissions($permissions); + } + + // If $target is an array: Loop through it + if (is_array($target)) { + + for ($i = 0; $i < count($target); $i++) { + $res = $this->chmodRecursive($target[$i], $permissions); + if (PEAR::isError($res)) { + return $res; + } // end if isError + } // end for i < count($target) + + } else { + + $remote_path = $this->_constructPath($target); + + // Chmod the directory itself + $result = $this->chmod($remote_path, $dir_permissions); + + if (PEAR::isError($result)) { + return $result; + } + + // If $remote_path last character is not a slash, add one + if (substr($remote_path, strlen($remote_path)-1) != "/") { + + $remote_path .= "/"; + } + + $dir_list = array(); + $mode = NET_FTP_DIRS_ONLY; + $dir_list = $this->ls($remote_path, $mode); + foreach ($dir_list as $dir_entry) { + if ($dir_entry['name'] == '.' || $dir_entry['name'] == '..') { + continue; + } + + $remote_path_new = $remote_path.$dir_entry["name"]."/"; + + // Chmod the directory we're about to enter + $result = $this->chmod($remote_path_new, $dir_permissions); + + if (PEAR::isError($result)) { + return $result; + } + + $result = $this->chmodRecursive($remote_path_new, $permissions); + + if (PEAR::isError($result)) { + return $result; + } + + } // end foreach dir_list as dir_entry + + $file_list = array(); + $mode = NET_FTP_FILES_ONLY; + $file_list = $this->ls($remote_path, $mode); + + foreach ($file_list as $file_entry) { + + $remote_file = $remote_path.$file_entry["name"]; + + $result = $this->chmod($remote_file, $permissions); + + if (PEAR::isError($result)) { + return $result; + } + + } // end foreach $file_list + + } // end if is_array + + return true; // No errors + + } // end method chmodRecursive + + /** + * Rename or move a file or a directory from the ftp-server + * + * @param string $remote_from The remote file or directory original to rename or + * move + * @param string $remote_to The remote file or directory final to rename or + * move + * + * @access public + * @return bool $res True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_RENAME_FAILED + */ + function rename ($remote_from, $remote_to) + { + $res = @ftp_rename($this->_handle, $remote_from, $remote_to); + if (!$res) { + return $this->raiseError("Could not rename ".$remote_from." to ". + $remote_to." !", NET_FTP_ERR_RENAME_FAILED); + } + return true; + } + + /** + * This will return logical permissions mask for directory. + * if directory has to be readable it have also be executable + * + * @param string $permissions File permissions in digits for file (i.e. 666) + * + * @access private + * @return string File permissions in digits for directory (i.e. 777) + */ + function _makeDirPermissions($permissions) + { + $permissions = (string)$permissions; + + // going through (user, group, world) + for ($i = 0; $i < strlen($permissions); $i++) { + // Read permission is set but execute not yet + if ((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)) { + // Adding execute flag + (int)$permissions{$i} = (int)$permissions{$i} + 1; + } + } + + return (string)$permissions; + } + + /** + * This will return the last modification-time of a file. You can either give + * this function a relative or an absolute path to the file to check. + * NOTE: Some servers will not support this feature and the function works + * only on files, not directories! When successful, + * it will return the last modification-time as a unix-timestamp or, when + * $format is specified, a preformated timestring. + * + * @param string $file The file to check + * @param string $format (optional) The format to give the date back + * if not set, it will return a Unix timestamp + * + * @access public + * @return mixed Unix timestamp, a preformated date-string or PEAR::Error + * @see NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED, + * NET_FTP_ERR_DATEFORMAT_FAILED + */ + function mdtm($file, $format = null) + { + $file = $this->_constructPath($file); + if ($this->_checkDir($file)) { + return $this->raiseError("Filename '$file' seems to be a directory.", + NET_FTP_ERR_MDTMDIR_UNSUPPORTED); + } + $res = @ftp_mdtm($this->_handle, $file); + if ($res == -1) { + return $this->raiseError("Could not get last-modification-date of '". + $file."'.", NET_FTP_ERR_MDTM_FAILED); + } + if (isset($format)) { + $res = date($format, $res); + if (!$res) { + return $this->raiseError("Date-format failed on timestamp '".$res. + "'.", NET_FTP_ERR_DATEFORMAT_FAILED); + } + } + return $res; + } + + /** + * This will return the size of a given file in bytes. You can either give this + * function a relative or an absolute file-path. NOTE: Some servers do not + * support this feature! + * + * @param string $file The file to check + * + * @access public + * @return mixed Size in bytes or PEAR::Error + * @see NET_FTP_ERR_SIZE_FAILED + */ + function size($file) + { + $file = $this->_constructPath($file); + $res = @ftp_size($this->_handle, $file); + if ($res == -1) { + return $this->raiseError("Could not determine filesize of '$file'.", + NET_FTP_ERR_SIZE_FAILED); + } else { + return $res; + } + } + + /** + * This method returns a directory-list of the current directory or given one. + * To display the current selected directory, simply set the first parameter to + * null + * or leave it blank, if you do not want to use any other parameters. + *

    + * There are 4 different modes of listing directories. Either to list only + * the files (using NET_FTP_FILES_ONLY), to list only directories (using + * NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is + * default). + *

    + * The 4th one is the NET_FTP_RAWLIST, which returns just the array created by + * the ftp_rawlist()-function build into PHP. + *

    + * The other function-modes will return an array containing the requested data. + * The files and dirs are listed in human-sorted order, but if you select + * NET_FTP_DIRS_FILES the directories will be added above the files, + * but although both sorted. + *

    + * All elements in the arrays are associative arrays themselves. They have the + * following structure: + *

    + * Dirs:
    + * ["name"] => string The name of the directory
    + * ["rights"] => string The rights of the directory (in style + * "rwxr-xr-x")
    + * ["user"] => string The owner of the directory
    + * ["group"] => string The group-owner of the directory
    + * ["files_inside"]=> string The number of files/dirs inside the + * directory excluding "." and ".."
    + * ["date"] => int The creation-date as Unix timestamp
    + * ["is_dir"] => bool true, cause this is a dir
    + *

    + * Files:
    + * ["name"] => string The name of the file
    + * ["size"] => int Size in bytes
    + * ["rights"] => string The rights of the file (in style + * "rwxr-xr-x")
    + * ["user"] => string The owner of the file
    + * ["group"] => string The group-owner of the file
    + * ["date"] => int The creation-date as Unix timestamp
    + * ["is_dir"] => bool false, cause this is a file
    + * + * @param string $dir (optional) The directory to list or null, when listing + * the current directory. + * @param int $mode (optional) The mode which types to list (files, + * directories or both). + * + * @access public + * @return mixed The directory list as described above or PEAR::Error on failure + * @see NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY, + * NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED, + * NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED + */ + function ls($dir = null, $mode = NET_FTP_DIRS_FILES) + { + if (!isset($dir)) { + $dir = @ftp_pwd($this->_handle); + if (!$dir) { + return $this->raiseError("Could not retrieve current directory", + NET_FTP_ERR_DETERMINEPATH_FAILED); + } + } + if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) && + ($mode != NET_FTP_RAWLIST)) { + $mode = NET_FTP_DIRS_FILES; + } + + switch ($mode) { + case NET_FTP_DIRS_FILES: + $res = $this->_lsBoth($dir); + break; + case NET_FTP_DIRS_ONLY: + $res = $this->_lsDirs($dir); + break; + case NET_FTP_FILES_ONLY: + $res = $this->_lsFiles($dir); + break; + case NET_FTP_RAWLIST: + $res = @ftp_rawlist($this->_handle, $dir); + break; + } + + return $res; + } + + /** + * This method will delete the given file or directory ($path) from the server + * (maybe recursive). + * + * Whether the given string is a file or directory is only determined by the + * last sign inside the string ("/" or not). + * + * If you specify a directory, you can optionally specify $recursive as true, + * to let the directory be deleted recursive (with all sub-directories and files + * inherited). + * + * You can either give a absolute or relative path for the file / dir. If you + * choose to use the relative path, it will be automatically completed with the + * actual selected directory. + * + * @param string $path The absolute or relative path to the file/directory. + * @param bool $recursive (optional) + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED, + * NET_FTP_ERR_REMOTEPATHNODIR + */ + function rm($path, $recursive = false) + { + $path = $this->_constructPath($path); + if ($this->_checkDir($path)) { + if ($recursive) { + return $this->_rmDirRecursive($path); + } else { + return $this->_rmDir($path); + } + } else { + return $this->_rmFile($path); + } + } + + /** + * This function will download a file from the ftp-server. You can either + * specify an absolute path to the file (beginning with "/") or a relative one, + * which will be completed with the actual directory you selected on the server. + * You can specify the path to which the file will be downloaded on the local + * machine, if the file should be overwritten if it exists (optionally, default + * is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file + * should be downloaded (if you do not specify this, the method tries to + * determine it automatically from the mode-directory or uses the default-mode, + * set by you). + * If you give a relative path to the local-file, the script-path is used as + * basepath. + * + * @param string $remote_file The absolute or relative path to the file to + * download + * @param string $local_file The local file to put the downloaded in + * @param bool $overwrite (optional) Whether to overwrite existing file + * @param int $mode (optional) Either FTP_ASCII or FTP_BINARY + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, + * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, + * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED + */ + function get($remote_file, $local_file, $overwrite = false, $mode = null) + { + if (!isset($mode)) { + $mode = $this->checkFileExtension($remote_file); + } + + $remote_file = $this->_constructPath($remote_file); + + if (@file_exists($local_file) && !$overwrite) { + return $this->raiseError("Local file '".$local_file. + "' exists and may not be overwriten.", + NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN); + } + if (@file_exists($local_file) && + !@is_writeable($local_file) && $overwrite) { + return $this->raiseError("Local file '".$local_file. + "' is not writeable. Can not overwrite.", + NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); + } + + if (@function_exists('ftp_nb_get')) { + $res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode); + while ($res == FTP_MOREDATA) { + $this->_announce('nb_get'); + $res = @ftp_nb_continue($this->_handle); + } + } else { + $res = @ftp_get($this->_handle, $local_file, $remote_file, $mode); + } + if (!$res) { + return $this->raiseError("File '".$remote_file. + "' could not be downloaded to '$local_file'.", + NET_FTP_ERR_OVERWRITELOCALFILE_FAILED); + } else { + return true; + } + } + + /** + * This function will upload a file to the ftp-server. You can either specify a + * absolute path to the remote-file (beginning with "/") or a relative one, + * which will be completed with the actual directory you selected on the server. + * You can specify the path from which the file will be uploaded on the local + * maschine, if the file should be overwritten if it exists (optionally, default + * is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file + * should be downloaded (if you do not specify this, the method tries to + * determine it automatically from the mode-directory or uses the default-mode, + * set by you). + * If you give a relative path to the local-file, the script-path is used as + * basepath. + * + * @param string $local_file The local file to upload + * @param string $remote_file The absolute or relative path to the file to + * upload to + * @param bool $overwrite (optional) Whether to overwrite existing file + * @param int $mode (optional) Either FTP_ASCII or FTP_BINARY + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_LOCALFILENOTEXIST, + * NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, + * NET_FTP_ERR_UPLOADFILE_FAILED + */ + function put($local_file, $remote_file, $overwrite = false, $mode = null) + { + if (!isset($mode)) { + $mode = $this->checkFileExtension($local_file); + } + $remote_file = $this->_constructPath($remote_file); + + if (!@file_exists($local_file)) { + return $this->raiseError("Local file '$local_file' does not exist.", + NET_FTP_ERR_LOCALFILENOTEXIST); + } + if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) { + return $this->raiseError("Remote file '".$remote_file. + "' exists and may not be overwriten.", + NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN); + } + + if (function_exists('ftp_alloc')) { + ftp_alloc($this->_handle, filesize($local_file)); + } + if (function_exists('ftp_nb_put')) { + $res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode); + while ($res == FTP_MOREDATA) { + $this->_announce('nb_put'); + $res = @ftp_nb_continue($this->_handle); + } + + } else { + $res = @ftp_put($this->_handle, $remote_file, $local_file, $mode); + } + if (!$res) { + return $this->raiseError("File '$local_file' could not be uploaded to '" + .$remote_file."'.", + NET_FTP_ERR_UPLOADFILE_FAILED); + } else { + return true; + } + } + + /** + * This functionality allows you to transfer a whole directory-structure from + * the remote-ftp to your local host. You have to give a remote-directory + * (ending with '/') and the local directory (ending with '/') where to put the + * files you download. + * The remote path is automatically completed with the current-remote-dir, if + * you give a relative path to this function. You can give a relative path for + * the $local_path, too. Then the script-basedir will be used for comletion of + * the path. + * The parameter $overwrite will determine, whether to overwrite existing files + * or not. Standard for this is false. Fourth you can explicitly set a mode for + * all transfer actions done. If you do not set this, the method tries to + * determine the transfer mode by checking your mode-directory for the file + * extension. If the extension is not inside the mode-directory, it will get + * your default mode. + * + * @param string $remote_path The path to download + * @param string $local_path The path to download to + * @param bool $overwrite (optional) Whether to overwrite existing files + * (true) or not (false, standard). + * @param int $mode (optional) The transfermode (either FTP_ASCII or + * FTP_BINARY). + * + * @access public + * @return mixed True on succes, otherwise PEAR::Error + * @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN, + * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, + * NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR, + * NET_FTP_ERR_CREATELOCALDIR_FAILED + */ + function getRecursive($remote_path, $local_path, $overwrite = false, + $mode = null) + { + $remote_path = $this->_constructPath($remote_path); + if (!$this->_checkDir($remote_path)) { + return $this->raiseError("Given remote-path '".$remote_path. + "' seems not to be a directory.", + NET_FTP_ERR_REMOTEPATHNODIR); + } + if (!$this->_checkDir($local_path)) { + return $this->raiseError("Given local-path '".$local_path. + "' seems not to be a directory.", + NET_FTP_ERR_LOCALPATHNODIR); + } + + if (!@is_dir($local_path)) { + $res = @mkdir($local_path); + if (!$res) { + return $this->raiseError("Could not create dir '$local_path'", + NET_FTP_ERR_CREATELOCALDIR_FAILED); + } + } + $dir_list = array(); + $dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY); + if (PEAR::isError($dir_list)) { + return $dir_list; + } + foreach ($dir_list as $dir_entry) { + if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') { + $remote_path_new = $remote_path.$dir_entry["name"]."/"; + $local_path_new = $local_path.$dir_entry["name"]."/"; + $result = $this->getRecursive($remote_path_new, + $local_path_new, $overwrite, $mode); + if ($this->isError($result)) { + return $result; + } + } + } + $file_list = array(); + $file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY); + if (PEAR::isError($file_list)) { + return $file_list; + } + foreach ($file_list as $file_entry) { + $remote_file = $remote_path.$file_entry["name"]; + $local_file = $local_path.$file_entry["name"]; + $result = $this->get($remote_file, $local_file, $overwrite, $mode); + if ($this->isError($result)) { + return $result; + } + } + return true; + } + + /** + * This functionality allows you to transfer a whole directory-structure from + * your local host to the remote-ftp. You have to give a remote-directory + * (ending with '/') and the local directory (ending with '/') where to put the + * files you download. The remote path is automatically completed with the + * current-remote-dir, if you give a relative path to this function. You can + * give a relative path for the $local_path, too. Then the script-basedir will + * be used for comletion of the path. + * The parameter $overwrite will determine, whether to overwrite existing files + * or not. + * Standard for this is false. Fourth you can explicitly set a mode for all + * transfer actions done. If you do not set this, the method tries to determine + * the transfer mode by checking your mode-directory for the file-extension. If + * the extension is not inside the mode-directory, it will get your default + * mode. + * + * @param string $local_path The path to download to + * @param string $remote_path The path to download + * @param bool $overwrite (optional) Whether to overwrite existing files + * (true) or not (false, standard). + * @param int $mode (optional) The transfermode (either FTP_ASCII or + * FTP_BINARY). + * + * @access public + * @return mixed True on succes, otherwise PEAR::Error + * @see NET_FTP_ERR_LOCALFILENOTEXIST, + * NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN, + * NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR, + * NET_FTP_ERR_REMOTEPATHNODIR + */ + function putRecursive($local_path, $remote_path, $overwrite = false, + $mode = null) + { + $remote_path = $this->_constructPath($remote_path); + if (!file_exists($local_path) || !is_dir($local_path)) { + return $this->raiseError("Given local-path '".$local_path. + "' seems not to be a directory.", + NET_FTP_ERR_LOCALPATHNODIR); + } + if (!$this->_checkDir($remote_path)) { + return $this->raiseError("Given remote-path '".$remote_path. + "' seems not to be a directory.", + NET_FTP_ERR_REMOTEPATHNODIR); + } + $old_path = $this->pwd(); + if ($this->isError($this->cd($remote_path))) { + $res = $this->mkdir($remote_path); + if ($this->isError($res)) { + return $res; + } + } + $this->cd($old_path); + $dir_list = $this->_lsLocal($local_path); + foreach ($dir_list["dirs"] as $dir_entry) { + // local directories do not have arrays as entry + $remote_path_new = $remote_path.$dir_entry."/"; + $local_path_new = $local_path.$dir_entry."/"; + $result = $this->putRecursive($local_path_new, + $remote_path_new, $overwrite, $mode); + if ($this->isError($result)) { + return $result; + } + } + + foreach ($dir_list["files"] as $file_entry) { + $remote_file = $remote_path.$file_entry; + $local_file = $local_path.$file_entry; + $result = $this->put($local_file, $remote_file, $overwrite, $mode); + if ($this->isError($result)) { + return $result; + } + } + return true; + } + + /** + * This checks, whether a file should be transfered in ascii- or binary-mode + * by it's file-extension. If the file-extension is not set or + * the extension is not inside one of the extension-dirs, the actual set + * transfer-mode is returned. + * + * @param string $filename The filename to be checked + * + * @access public + * @return int Either FTP_ASCII or FTP_BINARY + */ + function checkFileExtension($filename) + { + if (($pos = strrpos($filename, '.')) === false) { + return $this->_mode; + } else { + $ext = substr($filename, $pos + 1); + } + + if (isset($this->_file_extensions[$ext])) { + return $this->_file_extensions[$ext]; + } + + return $this->_mode; + } + + /** + * Set the hostname + * + * @param string $host The hostname to set + * + * @access public + * @return bool True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_HOSTNAMENOSTRING + */ + function setHostname($host) + { + if (!is_string($host)) { + return PEAR::raiseError("Hostname must be a string.", + NET_FTP_ERR_HOSTNAMENOSTRING); + } + $this->_hostname = $host; + return true; + } + + /** + * Set the Port + * + * @param int $port The port to set + * + * @access public + * @return bool True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_PORTLESSZERO + */ + function setPort($port) + { + if (!is_int($port) || ($port < 0)) { + PEAR::raiseError("Invalid port. Has to be integer >= 0", + NET_FTP_ERR_PORTLESSZERO); + } + $this->_port = $port; + return true; + } + + /** + * Set the Username + * + * @param string $user The username to set + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_USERNAMENOSTRING + */ + function setUsername($user) + { + if (empty($user) || !is_string($user)) { + return PEAR::raiseError('Username $user invalid.', + NET_FTP_ERR_USERNAMENOSTRING); + } + $this->_username = $user; + } + + /** + * Set the password + * + * @param string $password The password to set + * + * @access private + * @return void + * @see NET_FTP_ERR_PASSWORDNOSTRING + */ + function setPassword($password) + { + if (empty($password) || !is_string($password)) { + return PEAR::raiseError('Password xxx invalid.', + NET_FTP_ERR_PASSWORDNOSTRING); + } + $this->_password = $password; + } + + /** + * Set the transfer-mode. You can use the predefined constants + * FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers. + * + * @param int $mode The mode to set + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_NOMODECONST + */ + function setMode($mode) + { + if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) { + $this->_mode = $mode; + return true; + } else { + return $this->raiseError('FTP-Mode has either to be FTP_ASCII or'. + 'FTP_BINARY', NET_FTP_ERR_NOMODECONST); + } + } + + /** + * Set the transfer-method to passive mode + * + * @access public + * @return void + */ + function setPassive() + { + $this->_passv = true; + @ftp_pasv($this->_handle, true); + } + + /** + * Set the transfer-method to active mode + * + * @access public + * @return void + */ + function setActive() + { + $this->_passv = false; + @ftp_pasv($this->_handle, false); + } + + /** + * Set the timeout for FTP operations + * + * Use this method to set a timeout for FTP operation. Timeout has to be an + * integer. + * + * @param int $timeout the timeout to use + * + * @access public + * @return bool True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED + */ + function setTimeout ( $timeout = 0 ) + { + if (!is_int($timeout) || ($timeout < 0)) { + return PEAR::raiseError('Timeout '.$timeout. + ' is invalid, has to be an integer >= 0', + NET_FTP_ERR_TIMEOUTLESSZERO); + } + $this->_timeout = $timeout; + if (isset($this->_handle) && is_resource($this->_handle)) { + $res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout); + } else { + $res = true; + } + if (!$res) { + return PEAR::raiseError("Set timeout failed.", + NET_FTP_ERR_SETTIMEOUT_FAILED); + } + return true; + } + + /** + * Adds an extension to a mode-directory + * + * The mode-directory saves file-extensions coresponding to filetypes + * (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...). + * The extensions have to be saved without the '.'. And + * can be predefined in an external file (see: getExtensionsFile()). + * + * The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY + * + * To change the mode of an extension, just add it again with the new mode! + * + * @param int $mode Either FTP_ASCII or FTP_BINARY + * @param string $ext Extension + * + * @access public + * @return void + */ + function addExtension($mode, $ext) + { + $this->_file_extensions[$ext] = $mode; + } + + /** + * This function removes an extension from the mode-directories + * (described above). + * + * @param string $ext The extension to remove + * + * @access public + * @return void + */ + function removeExtension($ext) + { + if (isset($this->_file_extensions[$ext])) { + unset($this->_file_extensions[$ext]); + } + } + + /** + * This get's both (ascii- and binary-mode-directories) from the given file. + * Beware, if you read a file into the mode-directory, all former set values + * will be unset! + * + * Example file contents: + * [ASCII] + * asc = 0 + * txt = 0 + * [BINARY] + * bin = 1 + * jpg = 1 + * + * @param string $filename The file to get from + * + * @access public + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED + */ + function getExtensionsFile($filename) + { + if (!file_exists($filename)) { + return $this->raiseError("Extensions-file '$filename' does not exist", + NET_FTP_ERR_EXTFILENOTEXIST); + } + + if (!is_readable($filename)) { + return $this->raiseError("Extensions-file '$filename' is not readable", + NET_FTP_ERR_EXTFILEREAD_FAILED); + } + + $exts = @parse_ini_file($filename, true); + if (!is_array($exts)) { + return $this->raiseError("Extensions-file '$filename' could not be". + "loaded", NET_FTP_ERR_EXTFILELOAD_FAILED); + } + + $this->_file_extensions = array(); + + if (isset($exts['ASCII'])) { + foreach ($exts['ASCII'] as $ext => $bogus) { + $this->_file_extensions[$ext] = FTP_ASCII; + } + } + + if (isset($exts['BINARY'])) { + foreach ($exts['BINARY'] as $ext => $bogus) { + $this->_file_extensions[$ext] = FTP_BINARY; + } + } + + return true; + } + + /** + * Returns the hostname + * + * @access public + * @return string The hostname + */ + function getHostname() + { + return $this->_hostname; + } + + /** + * Returns the port + * + * @access public + * @return int The port + */ + function getPort() + { + return $this->_port; + } + + /** + * Returns the username + * + * @access public + * @return string The username + */ + function getUsername() + { + return $this->_username; + } + + /** + * Returns the password + * + * @access public + * @return string The password + */ + function getPassword() + { + return $this->_password; + } + + /** + * Returns the transfermode + * + * @access public + * @return int The transfermode, either FTP_ASCII or FTP_BINARY. + */ + function getMode() + { + return $this->_mode; + } + + /** + * Returns, whether the connection is set to passive mode or not + * + * @access public + * @return bool True if passive-, false if active-mode + */ + function isPassive() + { + return $this->_passv; + } + + /** + * Returns the mode set for a file-extension + * + * @param string $ext The extension you wanna ask for + * + * @return int Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it) + * @access public + */ + function getExtensionMode($ext) + { + return @$this->_file_extensions[$ext]; + } + + /** + * Get the currently set timeout. + * Returns the actual timeout set. + * + * @access public + * @return int The actual timeout + */ + function getTimeout() + { + return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC); + } + + /** + * Adds a Net_FTP_Observer instance to the list of observers + * that are listening for messages emitted by this Net_FTP instance. + * + * @param object &$observer The Net_FTP_Observer instance to attach + * as a listener. + * + * @return boolean True if the observer is successfully attached. + * @access public + * @since 1.3 + */ + function attach(&$observer) + { + if (!is_a($observer, 'Net_FTP_Observer')) { + return false; + } + + $this->_listeners[$observer->getId()] = &$observer; + return true; + } + + /** + * Removes a Net_FTP_Observer instance from the list of observers. + * + * @param object $observer The Net_FTP_Observer instance to detach + * from the list of listeners. + * + * @return boolean True if the observer is successfully detached. + * @access public + * @since 1.3 + */ + function detach($observer) + { + if (!is_a($observer, 'Net_FTP_Observer') || + !isset($this->_listeners[$observer->getId()])) { + return false; + } + + unset($this->_listeners[$observer->getId()]); + return true; + } + + /** + * Informs each registered observer instance that a new message has been + * sent. + * + * @param mixed $event A hash describing the net event. + * + * @access private + * @since 1.3 + * @return void + */ + function _announce($event) + { + foreach ($this->_listeners as $id => $listener) { + $this->_listeners[$id]->notify($event); + } + } + + /** + * Rebuild the path, if given relative + * + * This method will make a relative path absolute by prepending the current + * remote directory in front of it. + * + * @param string $path The path to check and construct + * + * @access private + * @return string The build path + */ + function _constructPath($path) + { + if ((substr($path, 0, 1) != '/') && (substr($path, 0, 2) != './')) { + $actual_dir = @ftp_pwd($this->_handle); + if (substr($actual_dir, -1) != '/') { + $actual_dir .= '/'; + } + $path = $actual_dir.$path; + } + return $path; + } + + /** + * Checks, whether a given string is a directory-path (ends with "/") or not. + * + * @param string $path Path to check + * + * @access private + * @return bool True if $path is a directory, otherwise false + */ + function _checkDir($path) + { + if (!empty($path) && substr($path, (strlen($path) - 1), 1) == "/") { + return true; + } else { + return false; + } + } + + /** + * This will remove a file + * + * @param string $file The file to delete + * + * @access private + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_DELETEFILE_FAILED + */ + function _rmFile($file) + { + if (substr($file, 0, 1) != "/") { + $actual_dir = @ftp_pwd($this->_handle); + if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") { + $actual_dir .= "/"; + } + $file = $actual_dir.$file; + } + $res = @ftp_delete($this->_handle, $file); + + if (!$res) { + return $this->raiseError("Could not delete file '$file'.", + NET_FTP_ERR_DELETEFILE_FAILED); + } else { + return true; + } + } + + /** + * This will remove a dir + * + * @param string $dir The dir to delete + * + * @access private + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED + */ + function _rmDir($dir) + { + if (substr($dir, (strlen($dir) - 1), 1) != "/") { + return $this->raiseError("Directory name '".$dir. + "' is invalid, has to end with '/'", + NET_FTP_ERR_REMOTEPATHNODIR); + } + $res = @ftp_rmdir($this->_handle, $dir); + if (!$res) { + return $this->raiseError("Could not delete directory '$dir'.", + NET_FTP_ERR_DELETEDIR_FAILED); + } else { + return true; + } + } + + /** + * This will remove a dir and all subdirs and -files + * + * @param string $dir The dir to delete recursively + * + * @access private + * @return mixed True on success, otherwise PEAR::Error + * @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED + */ + function _rmDirRecursive($dir) + { + if (substr($dir, (strlen($dir) - 1), 1) != "/") { + return $this->raiseError("Directory name '".$dir. + "' is invalid, has to end with '/'", + NET_FTP_ERR_REMOTEPATHNODIR); + } + $file_list = $this->_lsFiles($dir); + foreach ($file_list as $file) { + $file = $dir.$file["name"]; + $res = $this->rm($file); + if ($this->isError($res)) { + return $res; + } + } + $dir_list = $this->_lsDirs($dir); + foreach ($dir_list as $new_dir) { + if ($new_dir["name"] == '.' || $new_dir["name"] == '..') { + continue; + } + $new_dir = $dir.$new_dir["name"]."/"; + $res = $this->_rmDirRecursive($new_dir); + if ($this->isError($res)) { + return $res; + } + } + $res = $this->_rmDir($dir); + if (PEAR::isError($res)) { + return $res; + } else { + return true; + } + } + + /** + * Lists up files and directories + * + * @param string $dir The directory to list up + * + * @access private + * @return array An array of dirs and files + */ + function _lsBoth($dir) + { + $list_splitted = $this->_listAndParse($dir); + if (PEAR::isError($list_splitted)) { + return $list_splitted; + } + if (!is_array($list_splitted["files"])) { + $list_splitted["files"] = array(); + } + if (!is_array($list_splitted["dirs"])) { + $list_splitted["dirs"] = array(); + } + $res = array(); + @array_splice($res, 0, 0, $list_splitted["files"]); + @array_splice($res, 0, 0, $list_splitted["dirs"]); + return $res; + } + + /** + * Lists up directories + * + * @param string $dir The directory to list up + * + * @access private + * @return array An array of dirs + */ + function _lsDirs($dir) + { + $list = $this->_listAndParse($dir); + if (PEAR::isError($list)) { + return $list; + } + return $list["dirs"]; + } + + /** + * Lists up files + * + * @param string $dir The directory to list up + * + * @access private + * @return array An array of files + */ + function _lsFiles($dir) + { + $list = $this->_listAndParse($dir); + if (PEAR::isError($list)) { + return $list; + } + return $list["files"]; + } + + /** + * This lists up the directory-content and parses the items into well-formated + * arrays. + * The results of this array are sorted (dirs on top, sorted by name; + * files below, sorted by name). + * + * @param string $dir The directory to parse + * + * @access private + * @return array Lists of dirs and files + * @see NET_FTP_ERR_RAWDIRLIST_FAILED + */ + function _listAndParse($dir) + { + $dirs_list = array(); + $files_list = array(); + $dir_list = @ftp_rawlist($this->_handle, $dir); + if (!is_array($dir_list)) { + return PEAR::raiseError('Could not get raw directory listing.', + NET_FTP_ERR_RAWDIRLIST_FAILED); + } + + foreach ($dir_list AS $k=>$v) { + if (strncmp($v, 'total: ', 7) == 0 && preg_match('/total: \d+/', $v)) { + unset($dir_list[$k]); + break; // usually there is just one line like this + } + } + + // Handle empty directories + if (count($dir_list) == 0) { + return array('dirs' => $dirs_list, 'files' => $files_list); + } + + // Exception for some FTP servers seem to return this wiered result instead + // of an empty list + if (count($dirs_list) == 1 && $dirs_list[0] == 'total 0') { + return array('dirs' => array(), 'files' => $files_list); + } + + if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) { + $this->_matcher = $this->_determineOSMatch($dir_list); + if (PEAR::isError($this->_matcher)) { + return $this->_matcher; + } + } + foreach ($dir_list as $entry) { + if (!preg_match($this->_matcher['pattern'], $entry, $m)) { + continue; + } + $entry = array(); + foreach ($this->_matcher['map'] as $key=>$val) { + $entry[$key] = $m[$val]; + } + $entry['stamp'] = $this->_parseDate($entry['date']); + + if ($entry['is_dir']) { + $dirs_list[] = $entry; + } else { + $files_list[] = $entry; + } + } + @usort($dirs_list, array("Net_FTP", "_natSort")); + @usort($files_list, array("Net_FTP", "_natSort")); + $res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array(); + $res["files"] = (is_array($files_list)) ? $files_list : array(); + return $res; + } + + /** + * Determine server OS + * This determines the server OS and returns a valid regex to parse + * ls() output. + * + * @param array &$dir_list The raw dir list to parse + * + * @access private + * @return mixed An array of 'pattern' and 'map' on success, otherwise + * PEAR::Error + * @see NET_FTP_ERR_DIRLIST_UNSUPPORTED + */ + function _determineOSMatch(&$dir_list) + { + foreach ($dir_list as $entry) { + foreach ($this->_ls_match as $os => $match) { + $matches = array(); + if (preg_match($match['pattern'], $entry, $matches)) { + return $match; + } + } + } + $error = 'The list style of your server seems not to be supported. Please'. + 'email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the'. + 'server to the maintainer of this package to get it supported!'. + 'Thanks for your help!'; + return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED); + } + + /** + * Lists a local directory + * + * @param string $dir_path The dir to list + * + * @access private + * @return array The list of dirs and files + */ + function _lsLocal($dir_path) + { + $dir = dir($dir_path); + $dir_list = array(); + $file_list = array(); + while (false !== ($entry = $dir->read())) { + if (($entry != '.') && ($entry != '..')) { + if (is_dir($dir_path.$entry)) { + $dir_list[] = $entry; + } else { + $file_list[] = $entry; + } + } + } + $dir->close(); + $res['dirs'] = $dir_list; + $res['files'] = $file_list; + return $res; + } + + /** + * Function for use with usort(). + * Compares the list-array-elements by name. + * + * @param string $item_1 first item to be compared + * @param string $item_2 second item to be compared + * + * @access private + * @return int < 0 if $item_1 is less than $item_2, 0 if equal and > 0 otherwise + */ + function _natSort($item_1, $item_2) + { + return strnatcmp($item_1['name'], $item_2['name']); + } + + /** + * Parse dates to timestamps + * + * @param string $date Date + * + * @access private + * @return int Timestamp + * @see NET_FTP_ERR_DATEFORMAT_FAILED + */ + function _parseDate($date) + { + // Sep 10 22:06 => Sep 10, 22:06 + if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date, + $res)) { + $year = date('Y'); + $month = $res[1]; + $day = $res[2]; + $hour = $res[3]; + $minute = $res[4]; + $date = "$month $day, $year $hour:$minute"; + $tmpDate = strtotime($date); + if ($tmpDate > time()) { + $year--; + $date = "$month $day, $year $hour:$minute"; + } + } elseif (preg_match('/^\d\d-\d\d-\d\d/', $date)) { + // 09-10-04 => 09/10/04 + $date = str_replace('-', '/', $date); + } + $res = strtotime($date); + if (!$res) { + return $this->raiseError('Dateconversion failed.', + NET_FTP_ERR_DATEFORMAT_FAILED); + } + return $res; + } +} +?> diff --git a/gulliver/thirdparty/pear/Net/FTP/Observer.php b/gulliver/thirdparty/pear/Net/FTP/Observer.php new file mode 100644 index 000000000..507486974 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/FTP/Observer.php @@ -0,0 +1,101 @@ + + * @author Laurent Laville + * @author Chuck Hagenbuch + * @copyright 1997-2008 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id: Observer.php,v 1.4.2.1 2008/01/07 14:21:22 jschippers Exp $ + * @link http://pear.php.net/package/Net_FTP + * @since File available since Release 0.0.1 + */ + +/** + * This class implements the Observer part of a Subject-Observer + * design pattern. It listens to the events sent by a Net_FTP instance. + * This module had many influences from the Log_observer code. + * + * @category Networking + * @package FTP + * @author Laurent Laville + * @author Chuck Hagenbuch + * @author Tobias Schlitt + * @copyright 1997-2008 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: 1.3.7 + * @link http://pear.php.net/package/Net_FTP + * @since 1.3.0.0 + * @access public + * + * @example observer_upload.php An example of Net_FTP_Observer implementation. + */ +class Net_FTP_Observer +{ + /** + * Instance-specific unique identification number. + * + * @var integer + * @since 1.3.0 + * @access private + */ + var $_id; + + /** + * Creates a new basic Net_FTP_Observer instance. + * + * @since 1.3.0 + * @access public + */ + function Net_FTP_Observer() + { + $this->_id = md5(microtime()); + } + + /** + * Returns the listener's identifier + * + * @return string The listener's identifier + * @since 1.3.0 + * @access public + */ + function getId() + { + return $this->_id; + } + + /** + * This is a stub method to make sure that Net_FTP_Observer classes do + * something when they are notified of a message. The default behavior + * is to just do nothing. + * You should override this method. + * + * @param mixed $event A hash describing the net event. + * + * @since 1.3.0 + * @access public + * @return void + */ + function notify($event) + { + return; + } +} +?> diff --git a/gulliver/thirdparty/pear/Net/FTP/Socket.php b/gulliver/thirdparty/pear/Net/FTP/Socket.php new file mode 100644 index 000000000..c86198329 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/FTP/Socket.php @@ -0,0 +1,783 @@ + + * @copyright 1997-2008 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id: Socket.php,v 1.5.2.2 2008/04/22 19:47:08 jschippers Exp $ + * @link http://pear.php.net/package/Net_FTP + * @since File available since Release 0.0.1 + */ + +error_reporting(E_ALL); + +/** +* Default FTP extension constants +*/ +define('FTP_ASCII', 0); +define('FTP_TEXT', 0); +define('FTP_BINARY', 1); +define('FTP_IMAGE', 1); +define('FTP_TIMEOUT_SEC', 0); + +/** +* What needs to be done overall? +* #1 Install the rest of these functions +* #2 Document better +* #3 Alot of other things I don't remember +*/ + +/* + * !!! NOTE !!! + * Most of the comment's are "not working", + * meaning they are not all up-to-date + * !!! NOTE !!! + */ + +/** + * &resource ftp_connect ( string host [, int port [, int timeout ] ] ); + * + * Opens an FTP connection and return resource or false on failure. + * + * FTP Success respons code: 220 + * + * @param string $host Host to connect to + * @param int $port Optional, port to connect to + * @param int $timeout Optional, seconds until function timeouts + * + * @todo The FTP extension has ftp_get_option() function which returns the + * timeout variable. This function needs to be created and contain it as + * static variable. + * @todo The FTP extension has ftp_set_option() function which sets the + * timeout variable. This function needs to be created and called here. + * @access public + * @return &resource + */ +function &ftp_connect($host, $port = 21, $timeout = 90) +{ + $false = false; // We are going to return refrence (E_STRICT) + + if (!is_string($host) || !is_integer($port) || !is_integer($timeout)) { + return $false; + } + + $control = @fsockopen($host, $port, $iError, $sError, + $timeout); + $GLOBALS['_NET_FTP']['timeout'] = $timeout; + + if (!is_resource($control)) { + return $false; + } + + stream_set_blocking($control, true); + stream_set_timeout($control, $timeout); + + do { + $content[] = fgets($control, 8129); + $array = socket_get_status($control); + } while ($array['unread_bytes'] > 0); + + if (substr($content[count($content)-1], 0, 3) == 220) { + return $control; + } + + return $false; +} + +/** + * boolean ftp_login ( resource stream, string username, string password ); + * + * Logs in to an given FTP connection stream. + * Returns TRUE on success or FALSE on failure. + * + * NOTE: + * Username and password are *not* optional. Function will *not* + * assume "anonymous" if username and/or password is empty + * + * FTP Success respons code: 230 + * + * @param resource &$control FTP resource to login to + * @param string $username FTP Username to be used + * @param string $password FTP Password to be used + * + * @access public + * @return boolean + */ +function ftp_login(&$control, $username, $password) +{ + if (!is_resource($control) || is_null($username)) { + return false; + } + + fputs($control, 'USER '.$username."\r\n"); + $contents = array(); + do { + $contents[] = fgets($control, 8192); + $array = socket_get_status($control); + } while ($array['unread_bytes'] > 0); + + if (substr($contents[count($contents)-1], 0, 3) != 331) { + return false; + } + + fputs($control, 'PASS '.$password."\r\n"); + $contents = array(); + do { + $contents[] = fgets($control, 8192); + $array = socket_get_status($control); + } while ($array['unread_bytes']); + + if (substr($contents[count($contents)-1], 0, 3) == 230) { + return true; + } + + trigger_error('ftp_login() [function.ftp-login'. + ']: '.$contents[count($contents)-1], E_USER_WARNING); + + return false; +} + +/** + * boolean ftp_quit ( resource stream ); + * + * Closes FTP connection. + * Returns TRUE or FALSE on error. + * + * NOTE: The PHP function ftp_quit is *alias* to ftp_close, here it is + * the *other-way-around* ( ftp_close() is alias to ftp_quit() ). + * + * NOTE: + * resource is set to null since unset() can't unset the variable. + * + * @param resource &$control FTP resource + * + * @access public + * @return boolean + */ +function ftp_quit(&$control) +{ + if (!is_resource($control)) { + return false; + } + + fputs($control, 'QUIT'."\r\n"); + fclose($control); + $control = null; + return true; +} + +/** + * Alias to ftp_quit() + * + * @param resource &$control FTP resource + * + * @see ftp_quit() + * @access public + * @return boolean + */ +function ftp_close(&$control) +{ + return ftp_quit($control); +} + +/** + * string ftp_pwd ( resource stream ); + * + * Gets the current directory name. + * Returns the current directory. + * + * Needs data connection: NO + * Success response code: 257 + * + * @param resource &$control FTP resource + * + * @access public + * @return string + */ +function ftp_pwd(&$control) +{ + if (!is_resource($control)) { + return $control; + } + + fputs($control, 'PWD'."\r\n"); + + $content = array(); + do { + $content[] = fgets($control, 8192); + $array = socket_get_status($control); + } while ($array['unread_bytes'] > 0); + + if (substr($cont = $content[count($content)-1], 0, 3) == 257) { + $pos = strpos($cont, '"')+1; + $pos2 = strrpos($cont, '"') - $pos; + $path = substr($cont, $pos, $pos2); + return $path; + } + + return false; +} + +/** + * boolean ftp_chdir ( resource stream, string directory ); + * + * Changes the current directory to the specified directory. + * Returns TRUE on success or FALSE on failure. + * + * FTP success response code: 250 + * Needs data connection: NO + * + * @param resource &$control FTP stream + * @param string $pwd Directory name + * + * @access public + * @return boolean + */ +function ftp_chdir(&$control, $pwd) +{ + if (!is_resource($control) || !is_string($pwd)) { + return false; + } + + fputs($control, 'CWD '.$pwd."\r\n"); + $content = array(); + do { + $content[] = fgets($control, 8192); + $array = socket_get_status($control); + } while ($array['unread_bytes'] > 0); + + if (substr($content[count($content)-1], 0, 3) == 250) { + return true; + } + + trigger_error('ftp_chdir() [function.ftp-chdir]: + ' .$content[count($content)-1], E_USER_WARNING); + + return false; +} + +$_NET_FTP = array(); +$_NET_FTP['USE_PASSIVE'] = false; +$_NET_FTP['DATA'] = null; + +/** + * boolean ftp_pasv ( resource stream, boolean passive ); + * + * Toggles passive mode ON/OFF. + * Returns TRUE on success or FALSE on failure. + * + * Comment: + * Although my lack of C knowlege I checked how the PHP FTP extension + * do things here. Seems like they create the data connection and store + * it in object for other functions to use. + * This is now done here. + * + * FTP success response code: 227 + * + * @param stream &$control FTP stream + * @param boolean $pasv True to switch to passive, false for active mode + * + * @access public + * @return boolean + */ +function ftp_pasv(&$control, $pasv) +{ + if (!is_resource($control) || !is_bool($pasv)) { + return false; + } + + // If data connection exists, destroy it + if (isset($GLOBALS['_NET_FTP']['DATA'])) { + fclose($GLOBALS['_NET_FTP']['DATA']); + $GLOBALS['_NET_FTP']['DATA'] = null; + + do { + fgets($control, 16); + $array = socket_get_status($control); + } while ($array['unread_bytes'] > 0); + } + + // Are we suppost to create active or passive connection? + if (!$pasv) { + $GLOBALS['_NET_FTP']['USE_PASSIVE'] = false; + // Pick random "low bit" + $low = rand(39, 250); + // Pick random "high bit" + $high = rand(39, 250); + // Lowest possible port would be; 10023 + // Highest possible port would be; 64246 + + $port = ($low<<8)+$high; + $ip = str_replace('.', ',', $_SERVER['SERVER_ADDR']); + $s = $ip.','.$low.','.$high; + + $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if (is_resource($socket)) { + if (socket_bind($socket, '0.0.0.0', $port)) { + if (socket_listen($socket)) { + $GLOBALS['_NET_FTP']['DATA'] = &$socket; + fputs($control, 'PORT '.$s."\r\n"); + $line = fgets($control, 512); + if (substr($line, 0, 3) == 200) { + return true; + } + } + } + } + return false; + } + + // Since we are here, we are suppost to create passive data connection. + $i = fputs($control, 'PASV' ."\r\n"); + + $content = array(); + do { + $content[] = fgets($control, 128); + $array = socket_get_status($control); + } while ($array['unread_bytes']); + + if (substr($cont = $content[count($content)-1], 0, 3) != 227) { + return false; + } + + $pos = strpos($cont, '(')+1; + $pos2 = strrpos($cont, ')')-$pos; + $string = substr($cont, $pos, $pos2); + + $array = split(',', $string); + // IP we are connecting to + $ip = $array[0]. '.' .$array[1]. '.' .$array[2]. '.' .$array[3]; + // Port ( 256*lowbit + highbit + $port = ($array[4] << 8)+$array[5]; + + // Our data connection + $data = fsockopen($ip, $port, $iError, $sError, + $GLOBALS['_NET_FTP']['timeout']); + + if (is_resource($data)) { + $GLOBALS['_NET_FTP']['USE_PASSIVE'] = true; + $GLOBALS['_NET_FTP']['DATA'] = &$data; + stream_set_blocking($data, true); + stream_set_timeout($data, $GLOBALS['_NET_FTP']['timeout']); + + return true; + } + + return false; +} + +/** + * array ftp_rawlist ( resource stream, string directory [,bool recursive] ); + * + * Returns a detailed list of files in the given directory. + * + * Needs data connection: YES + * + * @param integer &$control FTP resource + * @param string $pwd Path to retrieve + * @param boolean $recursive Optional, retrieve recursive listing + * + * @todo Enable the recursive feature. + * @access public + * @return array + */ +function ftp_rawlist(&$control, $pwd, $recursive = false) +{ + if (!is_resource($control) || !is_string($pwd)) { + return false; + } + + if (!isset($GLOBALS['_NET_FTP']['DATA']) || + !is_resource($GLOBALS['_NET_FTP']['DATA'])) { + ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']); + } + fputs($control, 'LIST '.$pwd."\r\n"); + + $msg = fgets($control, 512); + if (substr($msg, 0, 3) == 425) { + return false; + } + + $data = &$GLOBALS['_NET_FTP']['DATA']; + if (!$GLOBALS['_NET_FTP']['USE_PASSIVE']) { + $data = &socket_accept($data); + } + + $content = array(); + + switch ($GLOBALS['_NET_FTP']['USE_PASSIVE']) { + case true: + while (true) { + $string = rtrim(fgets($data, 1024)); + + if ($string=='') { + break; + } + + $content[] = $string; + } + + fclose($data); + break; + + case false: + $string = socket_read($data, 1024, PHP_BINARY_READ); + + $content = explode("\n", $string); + unset($content[count($content)-1]); + + socket_close($GLOBALS['_NET_FTP']['DATA']); + socket_close($data); + break; + } + + $data = $GLOBALS['_NET_FTP']['DATA'] = null; + + $f = fgets($control, 1024); + return $content; +} + +/** + * string ftp_systype ( resource stream ); + * + * Gets system type identifier of remote FTP server + * Returns the remote system type + * + * @param resource &$control FTP resource + * + * @access public + * @return string + */ +function ftp_systype(&$control) +{ + if (!is_resource($control)) { + return false; + } + + fputs($control, 'SYST'."\r\n"); + $line = fgets($control, 256); + + if (substr($line, 0, 3) != 215) { + return false; + } + + $os = substr($line, 4, strpos($line, ' ', 4)-4); + return $os; +} + +/** + * boolean ftp_alloc ( resource stream, integer bytes [, string &message ] ); + * + * Allocates space for a file to be uploaded + * Return TRUE on success or FALSE on failure + * + * NOTE; Many FTP servers do not support this command and/or don't need it. + * + * FTP success respons key: Belive it's 200 + * Needs data connection: NO + * + * @param resource &$control FTP stream + * @param integer $int Space to allocate + * @param string &$msg Optional, textual representation of the servers response + * will be returned by reference + * + * @access public + * @return boolean + */ +function ftp_alloc(&$control, $int, &$msg = null) +{ + if (!is_resource($control) || !is_integer($int)) { + return false; + } + + fputs($control, 'ALLO '.$int.' R '.$int."\r\n"); + + $msg = rtrim(fgets($control, 256)); + + $code = substr($msg, 0, 3); + if ($code == 200 || $code == 202) { + return true; + } + + return false; +} + +/** + * bool ftp_put ( resource stream, string remote_file, string local_file, + * int mode [, int startpos ] ); + * + * Uploads a file to the FTP server + * Returns TRUE on success or FALSE on failure. + * + * NOTE: + * The transfer mode specified must be either FTP_ASCII or FTP_BINARY. + * + * @param resource &$control FTP stream + * @param string $remote Remote file to write + * @param string $local Local file to upload + * @param integer $mode Upload mode, FTP_ASCI || FTP_BINARY + * @param integer $pos Optional, start upload at position + * + * @access public + * @return boolean + */ +function ftp_put(&$control, $remote, $local, $mode, $pos = 0) +{ + if (!is_resource($control) || !is_readable($local) || + !is_integer($mode) || !is_integer($pos)) { + return false; + } + + $types = array ( + 0 => 'A', + 1 => 'I' + ); + $windows = array ( + 0 => 't', + 1 => 'b' + ); + + /** + * TYPE values: + * A ( ASCII ) + * I ( BINARY ) + * E ( EBCDIC ) + * L ( BYTE ) + */ + + if (!isset($GLOBALS['_NET_FTP']['DATA']) || + !is_resource($GLOBALS['_NET_FTP']['DATA'])) { + ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']); + + } + // Establish data connection variable + $data = &$GLOBALS['_NET_FTP']['DATA']; + + // Decide TYPE to use + fputs($control, 'TYPE '.$types[$mode]."\r\n"); + $line = fgets($control, 256); // "Type set to TYPE" + if (substr($line, 0, 3) != 200) { + return false; + } + + fputs($control, 'STOR '.$remote."\r\n"); + sleep(1); + $line = fgets($control, 256); // "Opening TYPE mode data connect." + + if (substr($line, 0, 3) != 150) { + return false; + } + + // Creating resource to $local file + $fp = fopen($local, 'r'. $windows[$mode]); + if (!is_resource($fp)) { + $fp = null; + return false; + } + + // Loop throu that file and echo it to the data socket + $i = 0; + switch ($GLOBALS['_NET_FTP']['USE_PASSIVE']) { + case false: + $data = &socket_accept($data); + while (!feof($fp)) { + $i += socket_write($data, fread($fp, 10240), 10240); + } + socket_close($data); + break; + + case true: + while (!feof($fp)) { + $i += fputs($data, fread($fp, 10240), 10240); + } + + fclose($data); + break; + } + + $data = null; + do { + $line = fgets($control, 256); + } while (substr($line, 0, 4) != "226 "); + return true; +} + +/** + * Retrieve a remote file to a local file + * Returns TRUE on success or FALSE on failure + * + * @param integer &$control Stream ID + * @param string $local Local filename + * @param string $remote Remote filename + * @param integer $mode Transfer mode (FTP_ASCII or FTP_BINARY) + * @param integer $resume Resume the file transfer or not + * + * @access public + * @return boolean + */ +function ftp_get(&$control, $local, $remote, $mode, $resume = 0) +{ + if (!is_resource($control) || !is_writable(dirname($local)) || + !is_integer($mode) || !is_integer($resume)) { + return false; + } + $types = array ( + 0 => 'A', + 1 => 'I' + ); + $windows = array ( + 0 => 't', + 1 => 'b' + ); + + if (!isset($GLOBALS['_NET_FTP']['DATA']) || + !is_resource($GLOBALS['_NET_FTP'][ 'DATA'])) { + ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']); + } + $data = &$GLOBALS['NET_FTP']['DATA']; + + fputs($control, 'TYPE '.$types[$mode]."\r\n"); + $line = fgets($control, 256); + if (substr($line, 0, 3) != 200) { + return false; + } + + $fp = fopen($local, 'w'.$windows[$mode]); + if (!is_resource($fp)) { + $fp = null; + return false; + } +} + +/** + * Changes to the parent directory + * Returns TRUE on success or FALSE on failure + * + * @param integer &$control Stream ID + * + * @access public + * @return boolean + */ +function ftp_cdup(&$control) +{ + fputs($control, 'CDUP'."\r\n"); + $line = fgets($control, 256); + + if (substr($line, 0, 3) != 250) { + return false; + } + + return true; +} + +/** + * Set permissions on a file via FTP + * Returns the new file permission on success or false on error + * + * NOTE: This command is *not* supported by the standard + * NOTE: This command not ready! + * + * @param integer &$control Stream ID + * @param integer $mode Octal value + * @param string $file File to change permissions on + * + * @todo Figure out a way to chmod files via FTP + * @access public + * @return integer + */ +function ftp_chmod(&$control, $mode, $file) +{ + if (!is_resource($control) || !is_integer($mode) || !is_string($file)) { + return false; + } + + // chmod not in the standard, proftpd doesn't recognize it + // use SITE CHMOD? + fputs($control, 'SITE CHMOD '.$mode. ' ' .$file."\r\n"); + $line = fgets($control, 256); + + if (substr($line, 0, 3) == 200) { + return $mode; + } + + trigger_error('ftp_chmod() [function.ftp-chmod]: ' . + rtrim($line), E_USER_WARNING); + return false; +} + +/** + * Deletes a file on the FTP server + * Returns TRUE on success or FALSE on failure + * + * @param integer &$control Stream ID + * @param string $path File to delete + * + * @access public + * @return boolean + */ +function ftp_delete(&$control, $path) +{ + if (!is_resource($control) || !is_string($path)) { + return false; + } + + fputs($control, 'DELE '.$path."\r\n"); + $line = fgets($control, 256); + + if (substr($line, 0, 3) == 250) { + return true; + } + + return false; +} + +/** + * Requests execution of a program on the FTP server + * NOTE; SITE EXEC is *not* supported by the standart + * Returns TRUE on success or FALSE on error + * + * @param integer &$control Stream ID + * @param string $cmd Command to send + * + * @access public + * @todo Look a littlebit better into this + * @return boolean + */ +function ftp_exec(&$control, $cmd) +{ + if (!is_resource($control) || !is_string($cmd)) { + return false; + } + // Command not defined in the standart + // proftpd doesn't recognize SITE EXEC (only help,chgrp,chmod and ratio) + fputs($control, 'SITE EXEC '.$cmd."\r\n"); + $line = fgets($control, 256); + + // php.net/ftp_exec uses respons code 200 to verify if command was sent + // successfully or not, so we'll just do the same + if (substr($line, 0, 3) == 200) { + return true; + } + + return false; +} +?> diff --git a/gulliver/thirdparty/pear/Net/IDNA.php b/gulliver/thirdparty/pear/Net/IDNA.php new file mode 100644 index 000000000..14749d580 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/IDNA.php @@ -0,0 +1,101 @@ + + * @author Matthias Sommerfeld + * @package Net + * @version $Id: IDNA.php,v 1.1 2008/03/22 12:39:37 neufeind Exp $ + */ + +class Net_IDNA +{ + // {{{ factory + /** + * Attempts to return a concrete IDNA instance for either php4 or php5. + * + * @param array $params Set of paramaters + * @return object IDNA The newly created concrete Log instance, or an + * false on an error. + * @access public + */ + function &getInstance($params = array()) + { + $version = explode( '.', phpversion() ); + $handler = ((int)$version[0] > 4) ? 'php5' : 'php4'; + $class = 'Net_IDNA_' . $handler; + $classfile = 'Net/IDNA/' . $handler . '.php'; + + /* + * Attempt to include our version of the named class, but don't treat + * a failure as fatal. The caller may have already included their own + * version of the named class. + */ + @include_once $classfile; + + /* If the class exists, return a new instance of it. */ + if (class_exists($class)) { + $instance = &new $class($params); + return $instance; + } + + return false; + } + // }}} + + // {{{ singleton + /** + * Attempts to return a concrete IDNA instance for either php4 or php5, + * only creating a new instance if no IDNA instance with the same + * parameters currently exists. + * + * @param array $params Set of paramaters + * @return object IDNA The newly created concrete Log instance, or an + * false on an error. + * @access public + */ + function &singleton($params = array()) + { + static $instances; + if (!isset($instances)) { + $instances = array(); + } + + $signature = serialize($params); + if (!isset($instances[$signature])) { + $instances[$signature] = &Net_IDNA::getInstance($params); + } + + return $instances[$signature]; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Net/IDNA/php4.php b/gulliver/thirdparty/pear/Net/IDNA/php4.php new file mode 100644 index 000000000..3e93bb474 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/IDNA/php4.php @@ -0,0 +1,3011 @@ + + * @author Matthias Sommerfeld + * @author Stefan Neufeind + * @package Net + * @version $Id: php4.php,v 1.3 2008/03/22 15:24:17 neufeind Exp $ + */ + +class Net_IDNA_php4 +{ + // {{{ npdata + /** + * These Unicode codepoints are mapped to nothing, + * See RFC3454 for details + * + * @static + * @var array + * @access private + */ + var $_np_map_nothing = array( + 0xAD, + 0x34F, + 0x1806, + 0x180B, + 0x180C, + 0x180D, + 0x200B, + 0x200C, + 0x200D, + 0x2060, + 0xFE00, + 0xFE01, + 0xFE02, + 0xFE03, + 0xFE04, + 0xFE05, + 0xFE06, + 0xFE07, + 0xFE08, + 0xFE09, + 0xFE0A, + 0xFE0B, + 0xFE0C, + 0xFE0D, + 0xFE0E, + 0xFE0F, + 0xFEFF + ); + + /** + * @static + * @var array + * @access private + */ + var $_general_prohibited = array( + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0xA, + 0xB, + 0xC, + 0xD, + 0xE, + 0xF, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2F, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x5B, + 0x5C, + 0x5D, + 0x5E, + 0x5F, + 0x60, + 0x7B, + 0x7C, + 0x7D, + 0x7E, + 0x7F, + 0x3002 + ); + + /** + * @static + * @var array + * @access private + */ + var $_np_prohibit = array( + 0xA0, + 0x1680, + 0x2000, + 0x2001, + 0x2002, + 0x2003, + 0x2004, + 0x2005, + 0x2006, + 0x2007, + 0x2008, + 0x2009, + 0x200A, + 0x200B, + 0x202F, + 0x205F, + 0x3000, + 0x6DD, + 0x70F, + 0x180E, + 0x200C, + 0x200D, + 0x2028, + 0x2029, + 0xFEFF, + 0xFFF9, + 0xFFFA, + 0xFFFB, + 0xFFFC, + 0xFFFE, + 0xFFFF, + 0x1FFFE, + 0x1FFFF, + 0x2FFFE, + 0x2FFFF, + 0x3FFFE, + 0x3FFFF, + 0x4FFFE, + 0x4FFFF, + 0x5FFFE, + 0x5FFFF, + 0x6FFFE, + 0x6FFFF, + 0x7FFFE, + 0x7FFFF, + 0x8FFFE, + 0x8FFFF, + 0x9FFFE, + 0x9FFFF, + 0xAFFFE, + 0xAFFFF, + 0xBFFFE, + 0xBFFFF, + 0xCFFFE, + 0xCFFFF, + 0xDFFFE, + 0xDFFFF, + 0xEFFFE, + 0xEFFFF, + 0xFFFFE, + 0xFFFFF, + 0x10FFFE, + 0x10FFFF, + 0xFFF9, + 0xFFFA, + 0xFFFB, + 0xFFFC, + 0xFFFD, + 0x340, + 0x341, + 0x200E, + 0x200F, + 0x202A, + 0x202B, + 0x202C, + 0x202D, + 0x202E, + 0x206A, + 0x206B, + 0x206C, + 0x206D, + 0x206E, + 0x206F, + 0xE0001 + ); + + /** + * @static + * @var array + * @access private + */ + var $_np_prohibit_ranges = array( + array(0x80, 0x9F ), + array(0x2060, 0x206F ), + array(0x1D173, 0x1D17A ), + array(0xE000, 0xF8FF ), + array(0xF0000, 0xFFFFD ), + array(0x100000, 0x10FFFD), + array(0xFDD0, 0xFDEF ), + array(0xD800, 0xDFFF ), + array(0x2FF0, 0x2FFB ), + array(0xE0020, 0xE007F ) + ); + + /** + * @static + * @var array + * @access private + */ + var $_np_replacemaps = array( + 0x41 => array(0x61), + 0x42 => array(0x62), + 0x43 => array(0x63), + 0x44 => array(0x64), + 0x45 => array(0x65), + 0x46 => array(0x66), + 0x47 => array(0x67), + 0x48 => array(0x68), + 0x49 => array(0x69), + 0x4A => array(0x6A), + 0x4B => array(0x6B), + 0x4C => array(0x6C), + 0x4D => array(0x6D), + 0x4E => array(0x6E), + 0x4F => array(0x6F), + 0x50 => array(0x70), + 0x51 => array(0x71), + 0x52 => array(0x72), + 0x53 => array(0x73), + 0x54 => array(0x74), + 0x55 => array(0x75), + 0x56 => array(0x76), + 0x57 => array(0x77), + 0x58 => array(0x78), + 0x59 => array(0x79), + 0x5A => array(0x7A), + 0xB5 => array(0x3BC), + 0xC0 => array(0xE0), + 0xC1 => array(0xE1), + 0xC2 => array(0xE2), + 0xC3 => array(0xE3), + 0xC4 => array(0xE4), + 0xC5 => array(0xE5), + 0xC6 => array(0xE6), + 0xC7 => array(0xE7), + 0xC8 => array(0xE8), + 0xC9 => array(0xE9), + 0xCA => array(0xEA), + 0xCB => array(0xEB), + 0xCC => array(0xEC), + 0xCD => array(0xED), + 0xCE => array(0xEE), + 0xCF => array(0xEF), + 0xD0 => array(0xF0), + 0xD1 => array(0xF1), + 0xD2 => array(0xF2), + 0xD3 => array(0xF3), + 0xD4 => array(0xF4), + 0xD5 => array(0xF5), + 0xD6 => array(0xF6), + 0xD8 => array(0xF8), + 0xD9 => array(0xF9), + 0xDA => array(0xFA), + 0xDB => array(0xFB), + 0xDC => array(0xFC), + 0xDD => array(0xFD), + 0xDE => array(0xFE), + 0xDF => array(0x73, 0x73), + 0x100 => array(0x101), + 0x102 => array(0x103), + 0x104 => array(0x105), + 0x106 => array(0x107), + 0x108 => array(0x109), + 0x10A => array(0x10B), + 0x10C => array(0x10D), + 0x10E => array(0x10F), + 0x110 => array(0x111), + 0x112 => array(0x113), + 0x114 => array(0x115), + 0x116 => array(0x117), + 0x118 => array(0x119), + 0x11A => array(0x11B), + 0x11C => array(0x11D), + 0x11E => array(0x11F), + 0x120 => array(0x121), + 0x122 => array(0x123), + 0x124 => array(0x125), + 0x126 => array(0x127), + 0x128 => array(0x129), + 0x12A => array(0x12B), + 0x12C => array(0x12D), + 0x12E => array(0x12F), + 0x130 => array(0x69, 0x307), + 0x132 => array(0x133), + 0x134 => array(0x135), + 0x136 => array(0x137), + 0x139 => array(0x13A), + 0x13B => array(0x13C), + 0x13D => array(0x13E), + 0x13F => array(0x140), + 0x141 => array(0x142), + 0x143 => array(0x144), + 0x145 => array(0x146), + 0x147 => array(0x148), + 0x149 => array(0x2BC, 0x6E), + 0x14A => array(0x14B), + 0x14C => array(0x14D), + 0x14E => array(0x14F), + 0x150 => array(0x151), + 0x152 => array(0x153), + 0x154 => array(0x155), + 0x156 => array(0x157), + 0x158 => array(0x159), + 0x15A => array(0x15B), + 0x15C => array(0x15D), + 0x15E => array(0x15F), + 0x160 => array(0x161), + 0x162 => array(0x163), + 0x164 => array(0x165), + 0x166 => array(0x167), + 0x168 => array(0x169), + 0x16A => array(0x16B), + 0x16C => array(0x16D), + 0x16E => array(0x16F), + 0x170 => array(0x171), + 0x172 => array(0x173), + 0x174 => array(0x175), + 0x176 => array(0x177), + 0x178 => array(0xFF), + 0x179 => array(0x17A), + 0x17B => array(0x17C), + 0x17D => array(0x17E), + 0x17F => array(0x73), + 0x181 => array(0x253), + 0x182 => array(0x183), + 0x184 => array(0x185), + 0x186 => array(0x254), + 0x187 => array(0x188), + 0x189 => array(0x256), + 0x18A => array(0x257), + 0x18B => array(0x18C), + 0x18E => array(0x1DD), + 0x18F => array(0x259), + 0x190 => array(0x25B), + 0x191 => array(0x192), + 0x193 => array(0x260), + 0x194 => array(0x263), + 0x196 => array(0x269), + 0x197 => array(0x268), + 0x198 => array(0x199), + 0x19C => array(0x26F), + 0x19D => array(0x272), + 0x19F => array(0x275), + 0x1A0 => array(0x1A1), + 0x1A2 => array(0x1A3), + 0x1A4 => array(0x1A5), + 0x1A6 => array(0x280), + 0x1A7 => array(0x1A8), + 0x1A9 => array(0x283), + 0x1AC => array(0x1AD), + 0x1AE => array(0x288), + 0x1AF => array(0x1B0), + 0x1B1 => array(0x28A), + 0x1B2 => array(0x28B), + 0x1B3 => array(0x1B4), + 0x1B5 => array(0x1B6), + 0x1B7 => array(0x292), + 0x1B8 => array(0x1B9), + 0x1BC => array(0x1BD), + 0x1C4 => array(0x1C6), + 0x1C5 => array(0x1C6), + 0x1C7 => array(0x1C9), + 0x1C8 => array(0x1C9), + 0x1CA => array(0x1CC), + 0x1CB => array(0x1CC), + 0x1CD => array(0x1CE), + 0x1CF => array(0x1D0), + 0x1D1 => array(0x1D2), + 0x1D3 => array(0x1D4), + 0x1D5 => array(0x1D6), + 0x1D7 => array(0x1D8), + 0x1D9 => array(0x1DA), + 0x1DB => array(0x1DC), + 0x1DE => array(0x1DF), + 0x1E0 => array(0x1E1), + 0x1E2 => array(0x1E3), + 0x1E4 => array(0x1E5), + 0x1E6 => array(0x1E7), + 0x1E8 => array(0x1E9), + 0x1EA => array(0x1EB), + 0x1EC => array(0x1ED), + 0x1EE => array(0x1EF), + 0x1F0 => array(0x6A, 0x30C), + 0x1F1 => array(0x1F3), + 0x1F2 => array(0x1F3), + 0x1F4 => array(0x1F5), + 0x1F6 => array(0x195), + 0x1F7 => array(0x1BF), + 0x1F8 => array(0x1F9), + 0x1FA => array(0x1FB), + 0x1FC => array(0x1FD), + 0x1FE => array(0x1FF), + 0x200 => array(0x201), + 0x202 => array(0x203), + 0x204 => array(0x205), + 0x206 => array(0x207), + 0x208 => array(0x209), + 0x20A => array(0x20B), + 0x20C => array(0x20D), + 0x20E => array(0x20F), + 0x210 => array(0x211), + 0x212 => array(0x213), + 0x214 => array(0x215), + 0x216 => array(0x217), + 0x218 => array(0x219), + 0x21A => array(0x21B), + 0x21C => array(0x21D), + 0x21E => array(0x21F), + 0x220 => array(0x19E), + 0x222 => array(0x223), + 0x224 => array(0x225), + 0x226 => array(0x227), + 0x228 => array(0x229), + 0x22A => array(0x22B), + 0x22C => array(0x22D), + 0x22E => array(0x22F), + 0x230 => array(0x231), + 0x232 => array(0x233), + 0x345 => array(0x3B9), + 0x37A => array(0x20, 0x3B9), + 0x386 => array(0x3AC), + 0x388 => array(0x3AD), + 0x389 => array(0x3AE), + 0x38A => array(0x3AF), + 0x38C => array(0x3CC), + 0x38E => array(0x3CD), + 0x38F => array(0x3CE), + 0x390 => array(0x3B9, 0x308, 0x301), + 0x391 => array(0x3B1), + 0x392 => array(0x3B2), + 0x393 => array(0x3B3), + 0x394 => array(0x3B4), + 0x395 => array(0x3B5), + 0x396 => array(0x3B6), + 0x397 => array(0x3B7), + 0x398 => array(0x3B8), + 0x399 => array(0x3B9), + 0x39A => array(0x3BA), + 0x39B => array(0x3BB), + 0x39C => array(0x3BC), + 0x39D => array(0x3BD), + 0x39E => array(0x3BE), + 0x39F => array(0x3BF), + 0x3A0 => array(0x3C0), + 0x3A1 => array(0x3C1), + 0x3A3 => array(0x3C3), + 0x3A4 => array(0x3C4), + 0x3A5 => array(0x3C5), + 0x3A6 => array(0x3C6), + 0x3A7 => array(0x3C7), + 0x3A8 => array(0x3C8), + 0x3A9 => array(0x3C9), + 0x3AA => array(0x3CA), + 0x3AB => array(0x3CB), + 0x3B0 => array(0x3C5, 0x308, 0x301), + 0x3C2 => array(0x3C3), + 0x3D0 => array(0x3B2), + 0x3D1 => array(0x3B8), + 0x3D2 => array(0x3C5), + 0x3D3 => array(0x3CD), + 0x3D4 => array(0x3CB), + 0x3D5 => array(0x3C6), + 0x3D6 => array(0x3C0), + 0x3D8 => array(0x3D9), + 0x3DA => array(0x3DB), + 0x3DC => array(0x3DD), + 0x3DE => array(0x3DF), + 0x3E0 => array(0x3E1), + 0x3E2 => array(0x3E3), + 0x3E4 => array(0x3E5), + 0x3E6 => array(0x3E7), + 0x3E8 => array(0x3E9), + 0x3EA => array(0x3EB), + 0x3EC => array(0x3ED), + 0x3EE => array(0x3EF), + 0x3F0 => array(0x3BA), + 0x3F1 => array(0x3C1), + 0x3F2 => array(0x3C3), + 0x3F4 => array(0x3B8), + 0x3F5 => array(0x3B5), + 0x400 => array(0x450), + 0x401 => array(0x451), + 0x402 => array(0x452), + 0x403 => array(0x453), + 0x404 => array(0x454), + 0x405 => array(0x455), + 0x406 => array(0x456), + 0x407 => array(0x457), + 0x408 => array(0x458), + 0x409 => array(0x459), + 0x40A => array(0x45A), + 0x40B => array(0x45B), + 0x40C => array(0x45C), + 0x40D => array(0x45D), + 0x40E => array(0x45E), + 0x40F => array(0x45F), + 0x410 => array(0x430), + 0x411 => array(0x431), + 0x412 => array(0x432), + 0x413 => array(0x433), + 0x414 => array(0x434), + 0x415 => array(0x435), + 0x416 => array(0x436), + 0x417 => array(0x437), + 0x418 => array(0x438), + 0x419 => array(0x439), + 0x41A => array(0x43A), + 0x41B => array(0x43B), + 0x41C => array(0x43C), + 0x41D => array(0x43D), + 0x41E => array(0x43E), + 0x41F => array(0x43F), + 0x420 => array(0x440), + 0x421 => array(0x441), + 0x422 => array(0x442), + 0x423 => array(0x443), + 0x424 => array(0x444), + 0x425 => array(0x445), + 0x426 => array(0x446), + 0x427 => array(0x447), + 0x428 => array(0x448), + 0x429 => array(0x449), + 0x42A => array(0x44A), + 0x42B => array(0x44B), + 0x42C => array(0x44C), + 0x42D => array(0x44D), + 0x42E => array(0x44E), + 0x42F => array(0x44F), + 0x460 => array(0x461), + 0x462 => array(0x463), + 0x464 => array(0x465), + 0x466 => array(0x467), + 0x468 => array(0x469), + 0x46A => array(0x46B), + 0x46C => array(0x46D), + 0x46E => array(0x46F), + 0x470 => array(0x471), + 0x472 => array(0x473), + 0x474 => array(0x475), + 0x476 => array(0x477), + 0x478 => array(0x479), + 0x47A => array(0x47B), + 0x47C => array(0x47D), + 0x47E => array(0x47F), + 0x480 => array(0x481), + 0x48A => array(0x48B), + 0x48C => array(0x48D), + 0x48E => array(0x48F), + 0x490 => array(0x491), + 0x492 => array(0x493), + 0x494 => array(0x495), + 0x496 => array(0x497), + 0x498 => array(0x499), + 0x49A => array(0x49B), + 0x49C => array(0x49D), + 0x49E => array(0x49F), + 0x4A0 => array(0x4A1), + 0x4A2 => array(0x4A3), + 0x4A4 => array(0x4A5), + 0x4A6 => array(0x4A7), + 0x4A8 => array(0x4A9), + 0x4AA => array(0x4AB), + 0x4AC => array(0x4AD), + 0x4AE => array(0x4AF), + 0x4B0 => array(0x4B1), + 0x4B2 => array(0x4B3), + 0x4B4 => array(0x4B5), + 0x4B6 => array(0x4B7), + 0x4B8 => array(0x4B9), + 0x4BA => array(0x4BB), + 0x4BC => array(0x4BD), + 0x4BE => array(0x4BF), + 0x4C1 => array(0x4C2), + 0x4C3 => array(0x4C4), + 0x4C5 => array(0x4C6), + 0x4C7 => array(0x4C8), + 0x4C9 => array(0x4CA), + 0x4CB => array(0x4CC), + 0x4CD => array(0x4CE), + 0x4D0 => array(0x4D1), + 0x4D2 => array(0x4D3), + 0x4D4 => array(0x4D5), + 0x4D6 => array(0x4D7), + 0x4D8 => array(0x4D9), + 0x4DA => array(0x4DB), + 0x4DC => array(0x4DD), + 0x4DE => array(0x4DF), + 0x4E0 => array(0x4E1), + 0x4E2 => array(0x4E3), + 0x4E4 => array(0x4E5), + 0x4E6 => array(0x4E7), + 0x4E8 => array(0x4E9), + 0x4EA => array(0x4EB), + 0x4EC => array(0x4ED), + 0x4EE => array(0x4EF), + 0x4F0 => array(0x4F1), + 0x4F2 => array(0x4F3), + 0x4F4 => array(0x4F5), + 0x4F8 => array(0x4F9), + 0x500 => array(0x501), + 0x502 => array(0x503), + 0x504 => array(0x505), + 0x506 => array(0x507), + 0x508 => array(0x509), + 0x50A => array(0x50B), + 0x50C => array(0x50D), + 0x50E => array(0x50F), + 0x531 => array(0x561), + 0x532 => array(0x562), + 0x533 => array(0x563), + 0x534 => array(0x564), + 0x535 => array(0x565), + 0x536 => array(0x566), + 0x537 => array(0x567), + 0x538 => array(0x568), + 0x539 => array(0x569), + 0x53A => array(0x56A), + 0x53B => array(0x56B), + 0x53C => array(0x56C), + 0x53D => array(0x56D), + 0x53E => array(0x56E), + 0x53F => array(0x56F), + 0x540 => array(0x570), + 0x541 => array(0x571), + 0x542 => array(0x572), + 0x543 => array(0x573), + 0x544 => array(0x574), + 0x545 => array(0x575), + 0x546 => array(0x576), + 0x547 => array(0x577), + 0x548 => array(0x578), + 0x549 => array(0x579), + 0x54A => array(0x57A), + 0x54B => array(0x57B), + 0x54C => array(0x57C), + 0x54D => array(0x57D), + 0x54E => array(0x57E), + 0x54F => array(0x57F), + 0x550 => array(0x580), + 0x551 => array(0x581), + 0x552 => array(0x582), + 0x553 => array(0x583), + 0x554 => array(0x584), + 0x555 => array(0x585), + 0x556 => array(0x586), + 0x587 => array(0x565, 0x582), + 0x1E00 => array(0x1E01), + 0x1E02 => array(0x1E03), + 0x1E04 => array(0x1E05), + 0x1E06 => array(0x1E07), + 0x1E08 => array(0x1E09), + 0x1E0A => array(0x1E0B), + 0x1E0C => array(0x1E0D), + 0x1E0E => array(0x1E0F), + 0x1E10 => array(0x1E11), + 0x1E12 => array(0x1E13), + 0x1E14 => array(0x1E15), + 0x1E16 => array(0x1E17), + 0x1E18 => array(0x1E19), + 0x1E1A => array(0x1E1B), + 0x1E1C => array(0x1E1D), + 0x1E1E => array(0x1E1F), + 0x1E20 => array(0x1E21), + 0x1E22 => array(0x1E23), + 0x1E24 => array(0x1E25), + 0x1E26 => array(0x1E27), + 0x1E28 => array(0x1E29), + 0x1E2A => array(0x1E2B), + 0x1E2C => array(0x1E2D), + 0x1E2E => array(0x1E2F), + 0x1E30 => array(0x1E31), + 0x1E32 => array(0x1E33), + 0x1E34 => array(0x1E35), + 0x1E36 => array(0x1E37), + 0x1E38 => array(0x1E39), + 0x1E3A => array(0x1E3B), + 0x1E3C => array(0x1E3D), + 0x1E3E => array(0x1E3F), + 0x1E40 => array(0x1E41), + 0x1E42 => array(0x1E43), + 0x1E44 => array(0x1E45), + 0x1E46 => array(0x1E47), + 0x1E48 => array(0x1E49), + 0x1E4A => array(0x1E4B), + 0x1E4C => array(0x1E4D), + 0x1E4E => array(0x1E4F), + 0x1E50 => array(0x1E51), + 0x1E52 => array(0x1E53), + 0x1E54 => array(0x1E55), + 0x1E56 => array(0x1E57), + 0x1E58 => array(0x1E59), + 0x1E5A => array(0x1E5B), + 0x1E5C => array(0x1E5D), + 0x1E5E => array(0x1E5F), + 0x1E60 => array(0x1E61), + 0x1E62 => array(0x1E63), + 0x1E64 => array(0x1E65), + 0x1E66 => array(0x1E67), + 0x1E68 => array(0x1E69), + 0x1E6A => array(0x1E6B), + 0x1E6C => array(0x1E6D), + 0x1E6E => array(0x1E6F), + 0x1E70 => array(0x1E71), + 0x1E72 => array(0x1E73), + 0x1E74 => array(0x1E75), + 0x1E76 => array(0x1E77), + 0x1E78 => array(0x1E79), + 0x1E7A => array(0x1E7B), + 0x1E7C => array(0x1E7D), + 0x1E7E => array(0x1E7F), + 0x1E80 => array(0x1E81), + 0x1E82 => array(0x1E83), + 0x1E84 => array(0x1E85), + 0x1E86 => array(0x1E87), + 0x1E88 => array(0x1E89), + 0x1E8A => array(0x1E8B), + 0x1E8C => array(0x1E8D), + 0x1E8E => array(0x1E8F), + 0x1E90 => array(0x1E91), + 0x1E92 => array(0x1E93), + 0x1E94 => array(0x1E95), + 0x1E96 => array(0x68, 0x331), + 0x1E97 => array(0x74, 0x308), + 0x1E98 => array(0x77, 0x30A), + 0x1E99 => array(0x79, 0x30A), + 0x1E9A => array(0x61, 0x2BE), + 0x1E9B => array(0x1E61), + 0x1EA0 => array(0x1EA1), + 0x1EA2 => array(0x1EA3), + 0x1EA4 => array(0x1EA5), + 0x1EA6 => array(0x1EA7), + 0x1EA8 => array(0x1EA9), + 0x1EAA => array(0x1EAB), + 0x1EAC => array(0x1EAD), + 0x1EAE => array(0x1EAF), + 0x1EB0 => array(0x1EB1), + 0x1EB2 => array(0x1EB3), + 0x1EB4 => array(0x1EB5), + 0x1EB6 => array(0x1EB7), + 0x1EB8 => array(0x1EB9), + 0x1EBA => array(0x1EBB), + 0x1EBC => array(0x1EBD), + 0x1EBE => array(0x1EBF), + 0x1EC0 => array(0x1EC1), + 0x1EC2 => array(0x1EC3), + 0x1EC4 => array(0x1EC5), + 0x1EC6 => array(0x1EC7), + 0x1EC8 => array(0x1EC9), + 0x1ECA => array(0x1ECB), + 0x1ECC => array(0x1ECD), + 0x1ECE => array(0x1ECF), + 0x1ED0 => array(0x1ED1), + 0x1ED2 => array(0x1ED3), + 0x1ED4 => array(0x1ED5), + 0x1ED6 => array(0x1ED7), + 0x1ED8 => array(0x1ED9), + 0x1EDA => array(0x1EDB), + 0x1EDC => array(0x1EDD), + 0x1EDE => array(0x1EDF), + 0x1EE0 => array(0x1EE1), + 0x1EE2 => array(0x1EE3), + 0x1EE4 => array(0x1EE5), + 0x1EE6 => array(0x1EE7), + 0x1EE8 => array(0x1EE9), + 0x1EEA => array(0x1EEB), + 0x1EEC => array(0x1EED), + 0x1EEE => array(0x1EEF), + 0x1EF0 => array(0x1EF1), + 0x1EF2 => array(0x1EF3), + 0x1EF4 => array(0x1EF5), + 0x1EF6 => array(0x1EF7), + 0x1EF8 => array(0x1EF9), + 0x1F08 => array(0x1F00), + 0x1F09 => array(0x1F01), + 0x1F0A => array(0x1F02), + 0x1F0B => array(0x1F03), + 0x1F0C => array(0x1F04), + 0x1F0D => array(0x1F05), + 0x1F0E => array(0x1F06), + 0x1F0F => array(0x1F07), + 0x1F18 => array(0x1F10), + 0x1F19 => array(0x1F11), + 0x1F1A => array(0x1F12), + 0x1F1B => array(0x1F13), + 0x1F1C => array(0x1F14), + 0x1F1D => array(0x1F15), + 0x1F28 => array(0x1F20), + 0x1F29 => array(0x1F21), + 0x1F2A => array(0x1F22), + 0x1F2B => array(0x1F23), + 0x1F2C => array(0x1F24), + 0x1F2D => array(0x1F25), + 0x1F2E => array(0x1F26), + 0x1F2F => array(0x1F27), + 0x1F38 => array(0x1F30), + 0x1F39 => array(0x1F31), + 0x1F3A => array(0x1F32), + 0x1F3B => array(0x1F33), + 0x1F3C => array(0x1F34), + 0x1F3D => array(0x1F35), + 0x1F3E => array(0x1F36), + 0x1F3F => array(0x1F37), + 0x1F48 => array(0x1F40), + 0x1F49 => array(0x1F41), + 0x1F4A => array(0x1F42), + 0x1F4B => array(0x1F43), + 0x1F4C => array(0x1F44), + 0x1F4D => array(0x1F45), + 0x1F50 => array(0x3C5, 0x313), + 0x1F52 => array(0x3C5, 0x313, 0x300), + 0x1F54 => array(0x3C5, 0x313, 0x301), + 0x1F56 => array(0x3C5, 0x313, 0x342), + 0x1F59 => array(0x1F51), + 0x1F5B => array(0x1F53), + 0x1F5D => array(0x1F55), + 0x1F5F => array(0x1F57), + 0x1F68 => array(0x1F60), + 0x1F69 => array(0x1F61), + 0x1F6A => array(0x1F62), + 0x1F6B => array(0x1F63), + 0x1F6C => array(0x1F64), + 0x1F6D => array(0x1F65), + 0x1F6E => array(0x1F66), + 0x1F6F => array(0x1F67), + 0x1F80 => array(0x1F00, 0x3B9), + 0x1F81 => array(0x1F01, 0x3B9), + 0x1F82 => array(0x1F02, 0x3B9), + 0x1F83 => array(0x1F03, 0x3B9), + 0x1F84 => array(0x1F04, 0x3B9), + 0x1F85 => array(0x1F05, 0x3B9), + 0x1F86 => array(0x1F06, 0x3B9), + 0x1F87 => array(0x1F07, 0x3B9), + 0x1F88 => array(0x1F00, 0x3B9), + 0x1F89 => array(0x1F01, 0x3B9), + 0x1F8A => array(0x1F02, 0x3B9), + 0x1F8B => array(0x1F03, 0x3B9), + 0x1F8C => array(0x1F04, 0x3B9), + 0x1F8D => array(0x1F05, 0x3B9), + 0x1F8E => array(0x1F06, 0x3B9), + 0x1F8F => array(0x1F07, 0x3B9), + 0x1F90 => array(0x1F20, 0x3B9), + 0x1F91 => array(0x1F21, 0x3B9), + 0x1F92 => array(0x1F22, 0x3B9), + 0x1F93 => array(0x1F23, 0x3B9), + 0x1F94 => array(0x1F24, 0x3B9), + 0x1F95 => array(0x1F25, 0x3B9), + 0x1F96 => array(0x1F26, 0x3B9), + 0x1F97 => array(0x1F27, 0x3B9), + 0x1F98 => array(0x1F20, 0x3B9), + 0x1F99 => array(0x1F21, 0x3B9), + 0x1F9A => array(0x1F22, 0x3B9), + 0x1F9B => array(0x1F23, 0x3B9), + 0x1F9C => array(0x1F24, 0x3B9), + 0x1F9D => array(0x1F25, 0x3B9), + 0x1F9E => array(0x1F26, 0x3B9), + 0x1F9F => array(0x1F27, 0x3B9), + 0x1FA0 => array(0x1F60, 0x3B9), + 0x1FA1 => array(0x1F61, 0x3B9), + 0x1FA2 => array(0x1F62, 0x3B9), + 0x1FA3 => array(0x1F63, 0x3B9), + 0x1FA4 => array(0x1F64, 0x3B9), + 0x1FA5 => array(0x1F65, 0x3B9), + 0x1FA6 => array(0x1F66, 0x3B9), + 0x1FA7 => array(0x1F67, 0x3B9), + 0x1FA8 => array(0x1F60, 0x3B9), + 0x1FA9 => array(0x1F61, 0x3B9), + 0x1FAA => array(0x1F62, 0x3B9), + 0x1FAB => array(0x1F63, 0x3B9), + 0x1FAC => array(0x1F64, 0x3B9), + 0x1FAD => array(0x1F65, 0x3B9), + 0x1FAE => array(0x1F66, 0x3B9), + 0x1FAF => array(0x1F67, 0x3B9), + 0x1FB2 => array(0x1F70, 0x3B9), + 0x1FB3 => array(0x3B1, 0x3B9), + 0x1FB4 => array(0x3AC, 0x3B9), + 0x1FB6 => array(0x3B1, 0x342), + 0x1FB7 => array(0x3B1, 0x342, 0x3B9), + 0x1FB8 => array(0x1FB0), + 0x1FB9 => array(0x1FB1), + 0x1FBA => array(0x1F70), + 0x1FBB => array(0x1F71), + 0x1FBC => array(0x3B1, 0x3B9), + 0x1FBE => array(0x3B9), + 0x1FC2 => array(0x1F74, 0x3B9), + 0x1FC3 => array(0x3B7, 0x3B9), + 0x1FC4 => array(0x3AE, 0x3B9), + 0x1FC6 => array(0x3B7, 0x342), + 0x1FC7 => array(0x3B7, 0x342, 0x3B9), + 0x1FC8 => array(0x1F72), + 0x1FC9 => array(0x1F73), + 0x1FCA => array(0x1F74), + 0x1FCB => array(0x1F75), + 0x1FCC => array(0x3B7, 0x3B9), + 0x1FD2 => array(0x3B9, 0x308, 0x300), + 0x1FD3 => array(0x3B9, 0x308, 0x301), + 0x1FD6 => array(0x3B9, 0x342), + 0x1FD7 => array(0x3B9, 0x308, 0x342), + 0x1FD8 => array(0x1FD0), + 0x1FD9 => array(0x1FD1), + 0x1FDA => array(0x1F76), + 0x1FDB => array(0x1F77), + 0x1FE2 => array(0x3C5, 0x308, 0x300), + 0x1FE3 => array(0x3C5, 0x308, 0x301), + 0x1FE4 => array(0x3C1, 0x313), + 0x1FE6 => array(0x3C5, 0x342), + 0x1FE7 => array(0x3C5, 0x308, 0x342), + 0x1FE8 => array(0x1FE0), + 0x1FE9 => array(0x1FE1), + 0x1FEA => array(0x1F7A), + 0x1FEB => array(0x1F7B), + 0x1FEC => array(0x1FE5), + 0x1FF2 => array(0x1F7C, 0x3B9), + 0x1FF3 => array(0x3C9, 0x3B9), + 0x1FF4 => array(0x3CE, 0x3B9), + 0x1FF6 => array(0x3C9, 0x342), + 0x1FF7 => array(0x3C9, 0x342, 0x3B9), + 0x1FF8 => array(0x1F78), + 0x1FF9 => array(0x1F79), + 0x1FFA => array(0x1F7C), + 0x1FFB => array(0x1F7D), + 0x1FFC => array(0x3C9, 0x3B9), + 0x20A8 => array(0x72, 0x73), + 0x2102 => array(0x63), + 0x2103 => array(0xB0, 0x63), + 0x2107 => array(0x25B), + 0x2109 => array(0xB0, 0x66), + 0x210B => array(0x68), + 0x210C => array(0x68), + 0x210D => array(0x68), + 0x2110 => array(0x69), + 0x2111 => array(0x69), + 0x2112 => array(0x6C), + 0x2115 => array(0x6E), + 0x2116 => array(0x6E, 0x6F), + 0x2119 => array(0x70), + 0x211A => array(0x71), + 0x211B => array(0x72), + 0x211C => array(0x72), + 0x211D => array(0x72), + 0x2120 => array(0x73, 0x6D), + 0x2121 => array(0x74, 0x65, 0x6C), + 0x2122 => array(0x74, 0x6D), + 0x2124 => array(0x7A), + 0x2126 => array(0x3C9), + 0x2128 => array(0x7A), + 0x212A => array(0x6B), + 0x212B => array(0xE5), + 0x212C => array(0x62), + 0x212D => array(0x63), + 0x2130 => array(0x65), + 0x2131 => array(0x66), + 0x2133 => array(0x6D), + 0x213E => array(0x3B3), + 0x213F => array(0x3C0), + 0x2145 => array(0x64), + 0x2160 => array(0x2170), + 0x2161 => array(0x2171), + 0x2162 => array(0x2172), + 0x2163 => array(0x2173), + 0x2164 => array(0x2174), + 0x2165 => array(0x2175), + 0x2166 => array(0x2176), + 0x2167 => array(0x2177), + 0x2168 => array(0x2178), + 0x2169 => array(0x2179), + 0x216A => array(0x217A), + 0x216B => array(0x217B), + 0x216C => array(0x217C), + 0x216D => array(0x217D), + 0x216E => array(0x217E), + 0x216F => array(0x217F), + 0x24B6 => array(0x24D0), + 0x24B7 => array(0x24D1), + 0x24B8 => array(0x24D2), + 0x24B9 => array(0x24D3), + 0x24BA => array(0x24D4), + 0x24BB => array(0x24D5), + 0x24BC => array(0x24D6), + 0x24BD => array(0x24D7), + 0x24BE => array(0x24D8), + 0x24BF => array(0x24D9), + 0x24C0 => array(0x24DA), + 0x24C1 => array(0x24DB), + 0x24C2 => array(0x24DC), + 0x24C3 => array(0x24DD), + 0x24C4 => array(0x24DE), + 0x24C5 => array(0x24DF), + 0x24C6 => array(0x24E0), + 0x24C7 => array(0x24E1), + 0x24C8 => array(0x24E2), + 0x24C9 => array(0x24E3), + 0x24CA => array(0x24E4), + 0x24CB => array(0x24E5), + 0x24CC => array(0x24E6), + 0x24CD => array(0x24E7), + 0x24CE => array(0x24E8), + 0x24CF => array(0x24E9), + 0x3371 => array(0x68, 0x70, 0x61), + 0x3373 => array(0x61, 0x75), + 0x3375 => array(0x6F, 0x76), + 0x3380 => array(0x70, 0x61), + 0x3381 => array(0x6E, 0x61), + 0x3382 => array(0x3BC, 0x61), + 0x3383 => array(0x6D, 0x61), + 0x3384 => array(0x6B, 0x61), + 0x3385 => array(0x6B, 0x62), + 0x3386 => array(0x6D, 0x62), + 0x3387 => array(0x67, 0x62), + 0x338A => array(0x70, 0x66), + 0x338B => array(0x6E, 0x66), + 0x338C => array(0x3BC, 0x66), + 0x3390 => array(0x68, 0x7A), + 0x3391 => array(0x6B, 0x68, 0x7A), + 0x3392 => array(0x6D, 0x68, 0x7A), + 0x3393 => array(0x67, 0x68, 0x7A), + 0x3394 => array(0x74, 0x68, 0x7A), + 0x33A9 => array(0x70, 0x61), + 0x33AA => array(0x6B, 0x70, 0x61), + 0x33AB => array(0x6D, 0x70, 0x61), + 0x33AC => array(0x67, 0x70, 0x61), + 0x33B4 => array(0x70, 0x76), + 0x33B5 => array(0x6E, 0x76), + 0x33B6 => array(0x3BC, 0x76), + 0x33B7 => array(0x6D, 0x76), + 0x33B8 => array(0x6B, 0x76), + 0x33B9 => array(0x6D, 0x76), + 0x33BA => array(0x70, 0x77), + 0x33BB => array(0x6E, 0x77), + 0x33BC => array(0x3BC, 0x77), + 0x33BD => array(0x6D, 0x77), + 0x33BE => array(0x6B, 0x77), + 0x33BF => array(0x6D, 0x77), + 0x33C0 => array(0x6B, 0x3C9), + 0x33C1 => array(0x6D, 0x3C9), /* + 0x33C2 => array(0x61, 0x2E, 0x6D, 0x2E), */ + 0x33C3 => array(0x62, 0x71), + 0x33C6 => array(0x63, 0x2215, 0x6B, 0x67), + 0x33C7 => array(0x63, 0x6F, 0x2E), + 0x33C8 => array(0x64, 0x62), + 0x33C9 => array(0x67, 0x79), + 0x33CB => array(0x68, 0x70), + 0x33CD => array(0x6B, 0x6B), + 0x33CE => array(0x6B, 0x6D), + 0x33D7 => array(0x70, 0x68), + 0x33D9 => array(0x70, 0x70, 0x6D), + 0x33DA => array(0x70, 0x72), + 0x33DC => array(0x73, 0x76), + 0x33DD => array(0x77, 0x62), + 0xFB00 => array(0x66, 0x66), + 0xFB01 => array(0x66, 0x69), + 0xFB02 => array(0x66, 0x6C), + 0xFB03 => array(0x66, 0x66, 0x69), + 0xFB04 => array(0x66, 0x66, 0x6C), + 0xFB05 => array(0x73, 0x74), + 0xFB06 => array(0x73, 0x74), + 0xFB13 => array(0x574, 0x576), + 0xFB14 => array(0x574, 0x565), + 0xFB15 => array(0x574, 0x56B), + 0xFB16 => array(0x57E, 0x576), + 0xFB17 => array(0x574, 0x56D), + 0xFF21 => array(0xFF41), + 0xFF22 => array(0xFF42), + 0xFF23 => array(0xFF43), + 0xFF24 => array(0xFF44), + 0xFF25 => array(0xFF45), + 0xFF26 => array(0xFF46), + 0xFF27 => array(0xFF47), + 0xFF28 => array(0xFF48), + 0xFF29 => array(0xFF49), + 0xFF2A => array(0xFF4A), + 0xFF2B => array(0xFF4B), + 0xFF2C => array(0xFF4C), + 0xFF2D => array(0xFF4D), + 0xFF2E => array(0xFF4E), + 0xFF2F => array(0xFF4F), + 0xFF30 => array(0xFF50), + 0xFF31 => array(0xFF51), + 0xFF32 => array(0xFF52), + 0xFF33 => array(0xFF53), + 0xFF34 => array(0xFF54), + 0xFF35 => array(0xFF55), + 0xFF36 => array(0xFF56), + 0xFF37 => array(0xFF57), + 0xFF38 => array(0xFF58), + 0xFF39 => array(0xFF59), + 0xFF3A => array(0xFF5A), + 0x10400 => array(0x10428), + 0x10401 => array(0x10429), + 0x10402 => array(0x1042A), + 0x10403 => array(0x1042B), + 0x10404 => array(0x1042C), + 0x10405 => array(0x1042D), + 0x10406 => array(0x1042E), + 0x10407 => array(0x1042F), + 0x10408 => array(0x10430), + 0x10409 => array(0x10431), + 0x1040A => array(0x10432), + 0x1040B => array(0x10433), + 0x1040C => array(0x10434), + 0x1040D => array(0x10435), + 0x1040E => array(0x10436), + 0x1040F => array(0x10437), + 0x10410 => array(0x10438), + 0x10411 => array(0x10439), + 0x10412 => array(0x1043A), + 0x10413 => array(0x1043B), + 0x10414 => array(0x1043C), + 0x10415 => array(0x1043D), + 0x10416 => array(0x1043E), + 0x10417 => array(0x1043F), + 0x10418 => array(0x10440), + 0x10419 => array(0x10441), + 0x1041A => array(0x10442), + 0x1041B => array(0x10443), + 0x1041C => array(0x10444), + 0x1041D => array(0x10445), + 0x1041E => array(0x10446), + 0x1041F => array(0x10447), + 0x10420 => array(0x10448), + 0x10421 => array(0x10449), + 0x10422 => array(0x1044A), + 0x10423 => array(0x1044B), + 0x10424 => array(0x1044C), + 0x10425 => array(0x1044D), + 0x1D400 => array(0x61), + 0x1D401 => array(0x62), + 0x1D402 => array(0x63), + 0x1D403 => array(0x64), + 0x1D404 => array(0x65), + 0x1D405 => array(0x66), + 0x1D406 => array(0x67), + 0x1D407 => array(0x68), + 0x1D408 => array(0x69), + 0x1D409 => array(0x6A), + 0x1D40A => array(0x6B), + 0x1D40B => array(0x6C), + 0x1D40C => array(0x6D), + 0x1D40D => array(0x6E), + 0x1D40E => array(0x6F), + 0x1D40F => array(0x70), + 0x1D410 => array(0x71), + 0x1D411 => array(0x72), + 0x1D412 => array(0x73), + 0x1D413 => array(0x74), + 0x1D414 => array(0x75), + 0x1D415 => array(0x76), + 0x1D416 => array(0x77), + 0x1D417 => array(0x78), + 0x1D418 => array(0x79), + 0x1D419 => array(0x7A), + 0x1D434 => array(0x61), + 0x1D435 => array(0x62), + 0x1D436 => array(0x63), + 0x1D437 => array(0x64), + 0x1D438 => array(0x65), + 0x1D439 => array(0x66), + 0x1D43A => array(0x67), + 0x1D43B => array(0x68), + 0x1D43C => array(0x69), + 0x1D43D => array(0x6A), + 0x1D43E => array(0x6B), + 0x1D43F => array(0x6C), + 0x1D440 => array(0x6D), + 0x1D441 => array(0x6E), + 0x1D442 => array(0x6F), + 0x1D443 => array(0x70), + 0x1D444 => array(0x71), + 0x1D445 => array(0x72), + 0x1D446 => array(0x73), + 0x1D447 => array(0x74), + 0x1D448 => array(0x75), + 0x1D449 => array(0x76), + 0x1D44A => array(0x77), + 0x1D44B => array(0x78), + 0x1D44C => array(0x79), + 0x1D44D => array(0x7A), + 0x1D468 => array(0x61), + 0x1D469 => array(0x62), + 0x1D46A => array(0x63), + 0x1D46B => array(0x64), + 0x1D46C => array(0x65), + 0x1D46D => array(0x66), + 0x1D46E => array(0x67), + 0x1D46F => array(0x68), + 0x1D470 => array(0x69), + 0x1D471 => array(0x6A), + 0x1D472 => array(0x6B), + 0x1D473 => array(0x6C), + 0x1D474 => array(0x6D), + 0x1D475 => array(0x6E), + 0x1D476 => array(0x6F), + 0x1D477 => array(0x70), + 0x1D478 => array(0x71), + 0x1D479 => array(0x72), + 0x1D47A => array(0x73), + 0x1D47B => array(0x74), + 0x1D47C => array(0x75), + 0x1D47D => array(0x76), + 0x1D47E => array(0x77), + 0x1D47F => array(0x78), + 0x1D480 => array(0x79), + 0x1D481 => array(0x7A), + 0x1D49C => array(0x61), + 0x1D49E => array(0x63), + 0x1D49F => array(0x64), + 0x1D4A2 => array(0x67), + 0x1D4A5 => array(0x6A), + 0x1D4A6 => array(0x6B), + 0x1D4A9 => array(0x6E), + 0x1D4AA => array(0x6F), + 0x1D4AB => array(0x70), + 0x1D4AC => array(0x71), + 0x1D4AE => array(0x73), + 0x1D4AF => array(0x74), + 0x1D4B0 => array(0x75), + 0x1D4B1 => array(0x76), + 0x1D4B2 => array(0x77), + 0x1D4B3 => array(0x78), + 0x1D4B4 => array(0x79), + 0x1D4B5 => array(0x7A), + 0x1D4D0 => array(0x61), + 0x1D4D1 => array(0x62), + 0x1D4D2 => array(0x63), + 0x1D4D3 => array(0x64), + 0x1D4D4 => array(0x65), + 0x1D4D5 => array(0x66), + 0x1D4D6 => array(0x67), + 0x1D4D7 => array(0x68), + 0x1D4D8 => array(0x69), + 0x1D4D9 => array(0x6A), + 0x1D4DA => array(0x6B), + 0x1D4DB => array(0x6C), + 0x1D4DC => array(0x6D), + 0x1D4DD => array(0x6E), + 0x1D4DE => array(0x6F), + 0x1D4DF => array(0x70), + 0x1D4E0 => array(0x71), + 0x1D4E1 => array(0x72), + 0x1D4E2 => array(0x73), + 0x1D4E3 => array(0x74), + 0x1D4E4 => array(0x75), + 0x1D4E5 => array(0x76), + 0x1D4E6 => array(0x77), + 0x1D4E7 => array(0x78), + 0x1D4E8 => array(0x79), + 0x1D4E9 => array(0x7A), + 0x1D504 => array(0x61), + 0x1D505 => array(0x62), + 0x1D507 => array(0x64), + 0x1D508 => array(0x65), + 0x1D509 => array(0x66), + 0x1D50A => array(0x67), + 0x1D50D => array(0x6A), + 0x1D50E => array(0x6B), + 0x1D50F => array(0x6C), + 0x1D510 => array(0x6D), + 0x1D511 => array(0x6E), + 0x1D512 => array(0x6F), + 0x1D513 => array(0x70), + 0x1D514 => array(0x71), + 0x1D516 => array(0x73), + 0x1D517 => array(0x74), + 0x1D518 => array(0x75), + 0x1D519 => array(0x76), + 0x1D51A => array(0x77), + 0x1D51B => array(0x78), + 0x1D51C => array(0x79), + 0x1D538 => array(0x61), + 0x1D539 => array(0x62), + 0x1D53B => array(0x64), + 0x1D53C => array(0x65), + 0x1D53D => array(0x66), + 0x1D53E => array(0x67), + 0x1D540 => array(0x69), + 0x1D541 => array(0x6A), + 0x1D542 => array(0x6B), + 0x1D543 => array(0x6C), + 0x1D544 => array(0x6D), + 0x1D546 => array(0x6F), + 0x1D54A => array(0x73), + 0x1D54B => array(0x74), + 0x1D54C => array(0x75), + 0x1D54D => array(0x76), + 0x1D54E => array(0x77), + 0x1D54F => array(0x78), + 0x1D550 => array(0x79), + 0x1D56C => array(0x61), + 0x1D56D => array(0x62), + 0x1D56E => array(0x63), + 0x1D56F => array(0x64), + 0x1D570 => array(0x65), + 0x1D571 => array(0x66), + 0x1D572 => array(0x67), + 0x1D573 => array(0x68), + 0x1D574 => array(0x69), + 0x1D575 => array(0x6A), + 0x1D576 => array(0x6B), + 0x1D577 => array(0x6C), + 0x1D578 => array(0x6D), + 0x1D579 => array(0x6E), + 0x1D57A => array(0x6F), + 0x1D57B => array(0x70), + 0x1D57C => array(0x71), + 0x1D57D => array(0x72), + 0x1D57E => array(0x73), + 0x1D57F => array(0x74), + 0x1D580 => array(0x75), + 0x1D581 => array(0x76), + 0x1D582 => array(0x77), + 0x1D583 => array(0x78), + 0x1D584 => array(0x79), + 0x1D585 => array(0x7A), + 0x1D5A0 => array(0x61), + 0x1D5A1 => array(0x62), + 0x1D5A2 => array(0x63), + 0x1D5A3 => array(0x64), + 0x1D5A4 => array(0x65), + 0x1D5A5 => array(0x66), + 0x1D5A6 => array(0x67), + 0x1D5A7 => array(0x68), + 0x1D5A8 => array(0x69), + 0x1D5A9 => array(0x6A), + 0x1D5AA => array(0x6B), + 0x1D5AB => array(0x6C), + 0x1D5AC => array(0x6D), + 0x1D5AD => array(0x6E), + 0x1D5AE => array(0x6F), + 0x1D5AF => array(0x70), + 0x1D5B0 => array(0x71), + 0x1D5B1 => array(0x72), + 0x1D5B2 => array(0x73), + 0x1D5B3 => array(0x74), + 0x1D5B4 => array(0x75), + 0x1D5B5 => array(0x76), + 0x1D5B6 => array(0x77), + 0x1D5B7 => array(0x78), + 0x1D5B8 => array(0x79), + 0x1D5B9 => array(0x7A), + 0x1D5D4 => array(0x61), + 0x1D5D5 => array(0x62), + 0x1D5D6 => array(0x63), + 0x1D5D7 => array(0x64), + 0x1D5D8 => array(0x65), + 0x1D5D9 => array(0x66), + 0x1D5DA => array(0x67), + 0x1D5DB => array(0x68), + 0x1D5DC => array(0x69), + 0x1D5DD => array(0x6A), + 0x1D5DE => array(0x6B), + 0x1D5DF => array(0x6C), + 0x1D5E0 => array(0x6D), + 0x1D5E1 => array(0x6E), + 0x1D5E2 => array(0x6F), + 0x1D5E3 => array(0x70), + 0x1D5E4 => array(0x71), + 0x1D5E5 => array(0x72), + 0x1D5E6 => array(0x73), + 0x1D5E7 => array(0x74), + 0x1D5E8 => array(0x75), + 0x1D5E9 => array(0x76), + 0x1D5EA => array(0x77), + 0x1D5EB => array(0x78), + 0x1D5EC => array(0x79), + 0x1D5ED => array(0x7A), + 0x1D608 => array(0x61), + 0x1D609 => array(0x62), + 0x1D60A => array(0x63), + 0x1D60B => array(0x64), + 0x1D60C => array(0x65), + 0x1D60D => array(0x66), + 0x1D60E => array(0x67), + 0x1D60F => array(0x68), + 0x1D610 => array(0x69), + 0x1D611 => array(0x6A), + 0x1D612 => array(0x6B), + 0x1D613 => array(0x6C), + 0x1D614 => array(0x6D), + 0x1D615 => array(0x6E), + 0x1D616 => array(0x6F), + 0x1D617 => array(0x70), + 0x1D618 => array(0x71), + 0x1D619 => array(0x72), + 0x1D61A => array(0x73), + 0x1D61B => array(0x74), + 0x1D61C => array(0x75), + 0x1D61D => array(0x76), + 0x1D61E => array(0x77), + 0x1D61F => array(0x78), + 0x1D620 => array(0x79), + 0x1D621 => array(0x7A), + 0x1D63C => array(0x61), + 0x1D63D => array(0x62), + 0x1D63E => array(0x63), + 0x1D63F => array(0x64), + 0x1D640 => array(0x65), + 0x1D641 => array(0x66), + 0x1D642 => array(0x67), + 0x1D643 => array(0x68), + 0x1D644 => array(0x69), + 0x1D645 => array(0x6A), + 0x1D646 => array(0x6B), + 0x1D647 => array(0x6C), + 0x1D648 => array(0x6D), + 0x1D649 => array(0x6E), + 0x1D64A => array(0x6F), + 0x1D64B => array(0x70), + 0x1D64C => array(0x71), + 0x1D64D => array(0x72), + 0x1D64E => array(0x73), + 0x1D64F => array(0x74), + 0x1D650 => array(0x75), + 0x1D651 => array(0x76), + 0x1D652 => array(0x77), + 0x1D653 => array(0x78), + 0x1D654 => array(0x79), + 0x1D655 => array(0x7A), + 0x1D670 => array(0x61), + 0x1D671 => array(0x62), + 0x1D672 => array(0x63), + 0x1D673 => array(0x64), + 0x1D674 => array(0x65), + 0x1D675 => array(0x66), + 0x1D676 => array(0x67), + 0x1D677 => array(0x68), + 0x1D678 => array(0x69), + 0x1D679 => array(0x6A), + 0x1D67A => array(0x6B), + 0x1D67B => array(0x6C), + 0x1D67C => array(0x6D), + 0x1D67D => array(0x6E), + 0x1D67E => array(0x6F), + 0x1D67F => array(0x70), + 0x1D680 => array(0x71), + 0x1D681 => array(0x72), + 0x1D682 => array(0x73), + 0x1D683 => array(0x74), + 0x1D684 => array(0x75), + 0x1D685 => array(0x76), + 0x1D686 => array(0x77), + 0x1D687 => array(0x78), + 0x1D688 => array(0x79), + 0x1D689 => array(0x7A), + 0x1D6A8 => array(0x3B1), + 0x1D6A9 => array(0x3B2), + 0x1D6AA => array(0x3B3), + 0x1D6AB => array(0x3B4), + 0x1D6AC => array(0x3B5), + 0x1D6AD => array(0x3B6), + 0x1D6AE => array(0x3B7), + 0x1D6AF => array(0x3B8), + 0x1D6B0 => array(0x3B9), + 0x1D6B1 => array(0x3BA), + 0x1D6B2 => array(0x3BB), + 0x1D6B3 => array(0x3BC), + 0x1D6B4 => array(0x3BD), + 0x1D6B5 => array(0x3BE), + 0x1D6B6 => array(0x3BF), + 0x1D6B7 => array(0x3C0), + 0x1D6B8 => array(0x3C1), + 0x1D6B9 => array(0x3B8), + 0x1D6BA => array(0x3C3), + 0x1D6BB => array(0x3C4), + 0x1D6BC => array(0x3C5), + 0x1D6BD => array(0x3C6), + 0x1D6BE => array(0x3C7), + 0x1D6BF => array(0x3C8), + 0x1D6C0 => array(0x3C9), + 0x1D6D3 => array(0x3C3), + 0x1D6E2 => array(0x3B1), + 0x1D6E3 => array(0x3B2), + 0x1D6E4 => array(0x3B3), + 0x1D6E5 => array(0x3B4), + 0x1D6E6 => array(0x3B5), + 0x1D6E7 => array(0x3B6), + 0x1D6E8 => array(0x3B7), + 0x1D6E9 => array(0x3B8), + 0x1D6EA => array(0x3B9), + 0x1D6EB => array(0x3BA), + 0x1D6EC => array(0x3BB), + 0x1D6ED => array(0x3BC), + 0x1D6EE => array(0x3BD), + 0x1D6EF => array(0x3BE), + 0x1D6F0 => array(0x3BF), + 0x1D6F1 => array(0x3C0), + 0x1D6F2 => array(0x3C1), + 0x1D6F3 => array(0x3B8), + 0x1D6F4 => array(0x3C3), + 0x1D6F5 => array(0x3C4), + 0x1D6F6 => array(0x3C5), + 0x1D6F7 => array(0x3C6), + 0x1D6F8 => array(0x3C7), + 0x1D6F9 => array(0x3C8), + 0x1D6FA => array(0x3C9), + 0x1D70D => array(0x3C3), + 0x1D71C => array(0x3B1), + 0x1D71D => array(0x3B2), + 0x1D71E => array(0x3B3), + 0x1D71F => array(0x3B4), + 0x1D720 => array(0x3B5), + 0x1D721 => array(0x3B6), + 0x1D722 => array(0x3B7), + 0x1D723 => array(0x3B8), + 0x1D724 => array(0x3B9), + 0x1D725 => array(0x3BA), + 0x1D726 => array(0x3BB), + 0x1D727 => array(0x3BC), + 0x1D728 => array(0x3BD), + 0x1D729 => array(0x3BE), + 0x1D72A => array(0x3BF), + 0x1D72B => array(0x3C0), + 0x1D72C => array(0x3C1), + 0x1D72D => array(0x3B8), + 0x1D72E => array(0x3C3), + 0x1D72F => array(0x3C4), + 0x1D730 => array(0x3C5), + 0x1D731 => array(0x3C6), + 0x1D732 => array(0x3C7), + 0x1D733 => array(0x3C8), + 0x1D734 => array(0x3C9), + 0x1D747 => array(0x3C3), + 0x1D756 => array(0x3B1), + 0x1D757 => array(0x3B2), + 0x1D758 => array(0x3B3), + 0x1D759 => array(0x3B4), + 0x1D75A => array(0x3B5), + 0x1D75B => array(0x3B6), + 0x1D75C => array(0x3B7), + 0x1D75D => array(0x3B8), + 0x1D75E => array(0x3B9), + 0x1D75F => array(0x3BA), + 0x1D760 => array(0x3BB), + 0x1D761 => array(0x3BC), + 0x1D762 => array(0x3BD), + 0x1D763 => array(0x3BE), + 0x1D764 => array(0x3BF), + 0x1D765 => array(0x3C0), + 0x1D766 => array(0x3C1), + 0x1D767 => array(0x3B8), + 0x1D768 => array(0x3C3), + 0x1D769 => array(0x3C4), + 0x1D76A => array(0x3C5), + 0x1D76B => array(0x3C6), + 0x1D76C => array(0x3C7), + 0x1D76D => array(0x3C8), + 0x1D76E => array(0x3C9), + 0x1D781 => array(0x3C3), + 0x1D790 => array(0x3B1), + 0x1D791 => array(0x3B2), + 0x1D792 => array(0x3B3), + 0x1D793 => array(0x3B4), + 0x1D794 => array(0x3B5), + 0x1D795 => array(0x3B6), + 0x1D796 => array(0x3B7), + 0x1D797 => array(0x3B8), + 0x1D798 => array(0x3B9), + 0x1D799 => array(0x3BA), + 0x1D79A => array(0x3BB), + 0x1D79B => array(0x3BC), + 0x1D79C => array(0x3BD), + 0x1D79D => array(0x3BE), + 0x1D79E => array(0x3BF), + 0x1D79F => array(0x3C0), + 0x1D7A0 => array(0x3C1), + 0x1D7A1 => array(0x3B8), + 0x1D7A2 => array(0x3C3), + 0x1D7A3 => array(0x3C4), + 0x1D7A4 => array(0x3C5), + 0x1D7A5 => array(0x3C6), + 0x1D7A6 => array(0x3C7), + 0x1D7A7 => array(0x3C8), + 0x1D7A8 => array(0x3C9), + 0x1D7BB => array(0x3C3), + 0x3F9 => array(0x3C3), + 0x1D2C => array(0x61), + 0x1D2D => array(0xE6), + 0x1D2E => array(0x62), + 0x1D30 => array(0x64), + 0x1D31 => array(0x65), + 0x1D32 => array(0x1DD), + 0x1D33 => array(0x67), + 0x1D34 => array(0x68), + 0x1D35 => array(0x69), + 0x1D36 => array(0x6A), + 0x1D37 => array(0x6B), + 0x1D38 => array(0x6C), + 0x1D39 => array(0x6D), + 0x1D3A => array(0x6E), + 0x1D3C => array(0x6F), + 0x1D3D => array(0x223), + 0x1D3E => array(0x70), + 0x1D3F => array(0x72), + 0x1D40 => array(0x74), + 0x1D41 => array(0x75), + 0x1D42 => array(0x77), + 0x213B => array(0x66, 0x61, 0x78), + 0x3250 => array(0x70, 0x74, 0x65), + 0x32CC => array(0x68, 0x67), + 0x32CE => array(0x65, 0x76), + 0x32CF => array(0x6C, 0x74, 0x64), + 0x337A => array(0x69, 0x75), + 0x33DE => array(0x76, 0x2215, 0x6D), + 0x33DF => array(0x61, 0x2215, 0x6D) + ); + + /** + * Normalization Combining Classes; Code Points not listed + * got Combining Class 0. + * + * @static + * @var array + * @access private + */ + var $_np_norm_combcls = array( + 0x334 => 1, + 0x335 => 1, + 0x336 => 1, + 0x337 => 1, + 0x338 => 1, + 0x93C => 7, + 0x9BC => 7, + 0xA3C => 7, + 0xABC => 7, + 0xB3C => 7, + 0xCBC => 7, + 0x1037 => 7, + 0x3099 => 8, + 0x309A => 8, + 0x94D => 9, + 0x9CD => 9, + 0xA4D => 9, + 0xACD => 9, + 0xB4D => 9, + 0xBCD => 9, + 0xC4D => 9, + 0xCCD => 9, + 0xD4D => 9, + 0xDCA => 9, + 0xE3A => 9, + 0xF84 => 9, + 0x1039 => 9, + 0x1714 => 9, + 0x1734 => 9, + 0x17D2 => 9, + 0x5B0 => 10, + 0x5B1 => 11, + 0x5B2 => 12, + 0x5B3 => 13, + 0x5B4 => 14, + 0x5B5 => 15, + 0x5B6 => 16, + 0x5B7 => 17, + 0x5B8 => 18, + 0x5B9 => 19, + 0x5BB => 20, + 0x5Bc => 21, + 0x5BD => 22, + 0x5BF => 23, + 0x5C1 => 24, + 0x5C2 => 25, + 0xFB1E => 26, + 0x64B => 27, + 0x64C => 28, + 0x64D => 29, + 0x64E => 30, + 0x64F => 31, + 0x650 => 32, + 0x651 => 33, + 0x652 => 34, + 0x670 => 35, + 0x711 => 36, + 0xC55 => 84, + 0xC56 => 91, + 0xE38 => 103, + 0xE39 => 103, + 0xE48 => 107, + 0xE49 => 107, + 0xE4A => 107, + 0xE4B => 107, + 0xEB8 => 118, + 0xEB9 => 118, + 0xEC8 => 122, + 0xEC9 => 122, + 0xECA => 122, + 0xECB => 122, + 0xF71 => 129, + 0xF72 => 130, + 0xF7A => 130, + 0xF7B => 130, + 0xF7C => 130, + 0xF7D => 130, + 0xF80 => 130, + 0xF74 => 132, + 0x321 => 202, + 0x322 => 202, + 0x327 => 202, + 0x328 => 202, + 0x31B => 216, + 0xF39 => 216, + 0x1D165 => 216, + 0x1D166 => 216, + 0x1D16E => 216, + 0x1D16F => 216, + 0x1D170 => 216, + 0x1D171 => 216, + 0x1D172 => 216, + 0x302A => 218, + 0x316 => 220, + 0x317 => 220, + 0x318 => 220, + 0x319 => 220, + 0x31C => 220, + 0x31D => 220, + 0x31E => 220, + 0x31F => 220, + 0x320 => 220, + 0x323 => 220, + 0x324 => 220, + 0x325 => 220, + 0x326 => 220, + 0x329 => 220, + 0x32A => 220, + 0x32B => 220, + 0x32C => 220, + 0x32D => 220, + 0x32E => 220, + 0x32F => 220, + 0x330 => 220, + 0x331 => 220, + 0x332 => 220, + 0x333 => 220, + 0x339 => 220, + 0x33A => 220, + 0x33B => 220, + 0x33C => 220, + 0x347 => 220, + 0x348 => 220, + 0x349 => 220, + 0x34D => 220, + 0x34E => 220, + 0x353 => 220, + 0x354 => 220, + 0x355 => 220, + 0x356 => 220, + 0x591 => 220, + 0x596 => 220, + 0x59B => 220, + 0x5A3 => 220, + 0x5A4 => 220, + 0x5A5 => 220, + 0x5A6 => 220, + 0x5A7 => 220, + 0x5AA => 220, + 0x655 => 220, + 0x656 => 220, + 0x6E3 => 220, + 0x6EA => 220, + 0x6ED => 220, + 0x731 => 220, + 0x734 => 220, + 0x737 => 220, + 0x738 => 220, + 0x739 => 220, + 0x73B => 220, + 0x73C => 220, + 0x73E => 220, + 0x742 => 220, + 0x744 => 220, + 0x746 => 220, + 0x748 => 220, + 0x952 => 220, + 0xF18 => 220, + 0xF19 => 220, + 0xF35 => 220, + 0xF37 => 220, + 0xFC6 => 220, + 0x193B => 220, + 0x20E8 => 220, + 0x1D17B => 220, + 0x1D17C => 220, + 0x1D17D => 220, + 0x1D17E => 220, + 0x1D17F => 220, + 0x1D180 => 220, + 0x1D181 => 220, + 0x1D182 => 220, + 0x1D18A => 220, + 0x1D18B => 220, + 0x59A => 222, + 0x5AD => 222, + 0x1929 => 222, + 0x302D => 222, + 0x302E => 224, + 0x302F => 224, + 0x1D16D => 226, + 0x5AE => 228, + 0x18A9 => 228, + 0x302B => 228, + 0x300 => 230, + 0x301 => 230, + 0x302 => 230, + 0x303 => 230, + 0x304 => 230, + 0x305 => 230, + 0x306 => 230, + 0x307 => 230, + 0x308 => 230, + 0x309 => 230, + 0x30A => 230, + 0x30B => 230, + 0x30C => 230, + 0x30D => 230, + 0x30E => 230, + 0x30F => 230, + 0x310 => 230, + 0x311 => 230, + 0x312 => 230, + 0x313 => 230, + 0x314 => 230, + 0x33D => 230, + 0x33E => 230, + 0x33F => 230, + 0x340 => 230, + 0x341 => 230, + 0x342 => 230, + 0x343 => 230, + 0x344 => 230, + 0x346 => 230, + 0x34A => 230, + 0x34B => 230, + 0x34C => 230, + 0x350 => 230, + 0x351 => 230, + 0x352 => 230, + 0x357 => 230, + 0x363 => 230, + 0x364 => 230, + 0x365 => 230, + 0x366 => 230, + 0x367 => 230, + 0x368 => 230, + 0x369 => 230, + 0x36A => 230, + 0x36B => 230, + 0x36C => 230, + 0x36D => 230, + 0x36E => 230, + 0x36F => 230, + 0x483 => 230, + 0x484 => 230, + 0x485 => 230, + 0x486 => 230, + 0x592 => 230, + 0x593 => 230, + 0x594 => 230, + 0x595 => 230, + 0x597 => 230, + 0x598 => 230, + 0x599 => 230, + 0x59C => 230, + 0x59D => 230, + 0x59E => 230, + 0x59F => 230, + 0x5A0 => 230, + 0x5A1 => 230, + 0x5A8 => 230, + 0x5A9 => 230, + 0x5AB => 230, + 0x5AC => 230, + 0x5AF => 230, + 0x5C4 => 230, + 0x610 => 230, + 0x611 => 230, + 0x612 => 230, + 0x613 => 230, + 0x614 => 230, + 0x615 => 230, + 0x653 => 230, + 0x654 => 230, + 0x657 => 230, + 0x658 => 230, + 0x6D6 => 230, + 0x6D7 => 230, + 0x6D8 => 230, + 0x6D9 => 230, + 0x6DA => 230, + 0x6DB => 230, + 0x6DC => 230, + 0x6DF => 230, + 0x6E0 => 230, + 0x6E1 => 230, + 0x6E2 => 230, + 0x6E4 => 230, + 0x6E7 => 230, + 0x6E8 => 230, + 0x6EB => 230, + 0x6EC => 230, + 0x730 => 230, + 0x732 => 230, + 0x733 => 230, + 0x735 => 230, + 0x736 => 230, + 0x73A => 230, + 0x73D => 230, + 0x73F => 230, + 0x740 => 230, + 0x741 => 230, + 0x743 => 230, + 0x745 => 230, + 0x747 => 230, + 0x749 => 230, + 0x74A => 230, + 0x951 => 230, + 0x953 => 230, + 0x954 => 230, + 0xF82 => 230, + 0xF83 => 230, + 0xF86 => 230, + 0xF87 => 230, + 0x170D => 230, + 0x193A => 230, + 0x20D0 => 230, + 0x20D1 => 230, + 0x20D4 => 230, + 0x20D5 => 230, + 0x20D6 => 230, + 0x20D7 => 230, + 0x20DB => 230, + 0x20DC => 230, + 0x20E1 => 230, + 0x20E7 => 230, + 0x20E9 => 230, + 0xFE20 => 230, + 0xFE21 => 230, + 0xFE22 => 230, + 0xFE23 => 230, + 0x1D185 => 230, + 0x1D186 => 230, + 0x1D187 => 230, + 0x1D189 => 230, + 0x1D188 => 230, + 0x1D1AA => 230, + 0x1D1AB => 230, + 0x1D1AC => 230, + 0x1D1AD => 230, + 0x315 => 232, + 0x31A => 232, + 0x302C => 232, + 0x35F => 233, + 0x362 => 233, + 0x35D => 234, + 0x35E => 234, + 0x360 => 234, + 0x361 => 234, + 0x345 => 240 + ); + // }}} + + + // Internal settings, do not mess with them + var $_punycode_prefix = 'xn--'; + var $_invalid_ucs = 0x80000000; + var $_max_ucs = 0x10FFFF; + var $_base = 36; + var $_tmin = 1; + var $_tmax = 26; + var $_skew = 38; + var $_damp = 700; + var $_initial_bias = 72; + var $_initial_n = 0x80; + var $_sbase = 0xAC00; + var $_lbase = 0x1100; + var $_vbase = 0x1161; + var $_tbase = 0x11a7; + var $_lcount = 19; + var $_vcount = 21; + var $_tcount = 28; + var $_ncount = 588; // _vcount * _tcount + var $_scount = 11172; // _lcount * _tcount * _vcount + var $_error = false; + + // See set_parameter() for details of how to change the following settings + // from within your script / application + var $_api_encoding = 'utf8'; // Default input charset is UTF-8 + var $_allow_overlong = false; // Overlong UTF-8 encodings are forbidden + var $_strict_mode = false; // Behave strict or not + + // The constructor + function Net_IDNA_php4($options = false) + { + $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount; + // If parameters are given, pass these to the respective method + if (is_array($options)) { + return $this->set_parameter($options); + } + return true; + } + + /** + * Sets a new option value. Available options and values: + * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8, + * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8] + * [overlong - Unicode does not allow unnecessarily long encodings of chars, + * to allow this, set this parameter to true, else to false; + * default is false.] + * [strict - true: strict mode, good for registration purposes - Causes errors + * on failures; false: loose mode, ideal for "wildlife" applications + * by silently ignoring errors and returning the original input instead + * + * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs) + * @param string Value to use (if parameter 1 is a string) + * @return boolean true on success, false otherwise + * @access public + */ + function set_parameter($option, $value = false) + { + if (!is_array($option)) { + $option = array($option => $value); + } + foreach ($option as $k => $v) { + switch ($k) { + case 'encoding': + switch ($v) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + $this->_api_encoding = $v; + break; + default: + $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k); + return false; + } + break; + case 'overlong': + $this->_allow_overlong = ($v) ? true : false; + break; + case 'strict': + $this->_strict_mode = ($v) ? true : false; + break; + default: + $this->_error('Set Parameter: Unknown option '.$k); + return false; + } + } + return true; + } + + /** + * Decode a given ACE domain name + * @param string Domain name (ACE string) + * [@param string Desired output encoding, see {@link set_parameter}] + * @return string Decoded Domain name (UTF-8 or UCS-4) + * @access public + */ + function decode($input, $one_time_encoding = false) + { + // Optionally set + if ($one_time_encoding) { + switch ($one_time_encoding) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + break; + default: + $this->_error('Unknown encoding '.$one_time_encoding); + return false; + } + } + // Make sure to drop any newline characters around + $input = trim($input); + + // Negotiate input and try to determine, wether it is a plain string, + // an email address or something like a complete URL + if (strpos($input, '@')) { // Maybe it is an email address + // No no in strict mode + if ($this->_strict_mode) { + $this->_error('Only simple domain name parts can be handled in strict mode'); + return false; + } + list($email_pref, $input) = explode('@', $input, 2); + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $return = $email_pref . '@' . join('.', $arr); + } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters) + // No no in strict mode + if ($this->_strict_mode) { + $this->_error('Only simple domain name parts can be handled in strict mode'); + return false; + } + $parsed = parse_url($input); + if (isset($parsed['host'])) { + $arr = explode('.', $parsed['host']); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $parsed['host'] = join('.', $arr); + if (isset($parsed['scheme'])) { + $parsed['scheme'] .= (strtolower($parsed['scheme']) == 'mailto') ? ':' : '://'; + } + $return = join('', $parsed); + } else { // parse_url seems to have failed, try without it + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $return = join('.', $arr); + } + } else { // Otherwise we consider it being a pure domain name string + $return = $this->_decode($input); + } + // The output is UTF-8 by default, other output formats need conversion here + // If one time encoding is given, use this, else the objects property + switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + return $return; + break; + case 'ucs4_string': + return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return)); + break; + case 'ucs4_array': + return $this->_utf8_to_ucs4($return); + break; + default: + $this->_error('Unsupported output format'); + return false; + } + } + + /** + * Encode a given UTF-8 domain name + * @param string Domain name (UTF-8 or UCS-4) + * [@param string Desired input encoding, see {@link set_parameter}] + * @return string Encoded Domain name (ACE string) + * @access public + */ + function encode($decoded, $one_time_encoding = false) + { + // Forcing conversion of input to UCS4 array + // If one time encoding is given, use this, else the objects property + switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + $decoded = $this->_utf8_to_ucs4($decoded); + break; + case 'ucs4_string': + $decoded = $this->_ucs4_string_to_ucs4($decoded); + case 'ucs4_array': + break; + default: + // $this->_error('Unsupported input format: '.$this->_api_encoding); + $this->_error('Unsupported input format'); + return false; + } + + // No input, no output, what else did you expect? + if (empty($decoded)) return ''; + + // Anchors for iteration + $last_begin = 0; + // Output string + $output = ''; + foreach ($decoded as $k => $v) { + // Make sure to use just the plain dot + switch($v) { + case 0x3002: + case 0xFF0E: + case 0xFF61: + $decoded[$k] = 0x2E; + // It's right, no break here + // The codepoints above have to be converted to dots anyway + + // Stumbling across an anchoring character + case 0x2E: + case 0x2F: + case 0x3A: + case 0x3F: + case 0x40: + // Neither email addresses nor URLs allowed in strict mode + if ($this->_strict_mode) { + $this->_error('Neither email addresses nor URLs are allowed in strict mode.'); + return false; + } else { + // Skip first char + if ($k) { + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin))); + } + $output .= chr($decoded[$k]); + } + $last_begin = $k + 1; + } + } + } + // Catch the rest of the string + if ($last_begin) { + $inp_len = sizeof($decoded); + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + } + return $output; + } else { + if ($output = $this->_encode($decoded)) { + return $output; + } else { + return $this->_ucs4_to_utf8($decoded); + } + } + } + + /** + * Use this method to get the last error ocurred + * @param void + * @return string The last error, that occured + * @access public + */ + function get_last_error() + { + return $this->_error; + } + + /** + * The actual decoding algorithm + * @access private + */ + function _decode($encoded) + { + // We do need to find the Punycode prefix + if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) { + $this->_error('This is not a punycode string'); + return false; + } + $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded); + // If nothing left after removing the prefix, it is hopeless + if (!$encode_test) { + $this->_error('The given encoded string was empty'); + return false; + } + // Find last occurence of the delimiter + $delim_pos = strrpos($encoded, '-'); + if ($delim_pos > strlen($this->_punycode_prefix)) { + for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) { + $decoded[] = ord($encoded{$k}); + } + } else { + $decoded = array(); + } + $deco_len = count($decoded); + $enco_len = strlen($encoded); + + // Wandering through the strings; init + $is_first = true; + $bias = $this->_initial_bias; + $idx = 0; + $char = $this->_initial_n; + + for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) { + for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) { + $digit = $this->_decode_digit($encoded{$enco_idx++}); + $idx += $digit * $w; + $t = ($k <= $bias) ? $this->_tmin : + (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias)); + if ($digit < $t) break; + $w = (int) ($w * ($this->_base - $t)); + } + $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first); + $is_first = false; + $char += (int) ($idx / ($deco_len + 1)); + $idx %= ($deco_len + 1); + if ($deco_len > 0) { + // Make room for the decoded char + for ($i = $deco_len; $i > $idx; $i--) { + $decoded[$i] = $decoded[($i - 1)]; + } + } + $decoded[$idx++] = $char; + } + return $this->_ucs4_to_utf8($decoded); + } + + /** + * The actual encoding algorithm + * @access private + */ + function _encode($decoded) + { + // We cannot encode a domain name containing the Punycode prefix + $extract = strlen($this->_punycode_prefix); + $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix); + $check_deco = array_slice($decoded, 0, $extract); + + if ($check_pref == $check_deco) { + $this->_error('This is already a punycode string'); + return false; + } + // We will not try to encode strings consisting of basic code points only + $encodable = false; + foreach ($decoded as $k => $v) { + if ($v > 0x7a) { + $encodable = true; + break; + } + } + if (!$encodable) { + $this->_error('The given string does not contain encodable chars'); + return false; + } + + // Do NAMEPREP + $decoded = $this->_nameprep($decoded); + if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed + + $deco_len = count($decoded); + if (!$deco_len) return false; // Empty array + + $codecount = 0; // How many chars have been consumed + + $encoded = ''; + // Copy all basic code points to output + for ($i = 0; $i < $deco_len; ++$i) { + $test = $decoded[$i]; + // Will match [0-9a-zA-Z-] + if ((0x2F < $test && $test < 0x40) + || (0x40 < $test && $test < 0x5B) + || (0x60 < $test && $test <= 0x7B) + || (0x2D == $test)) { + $encoded .= chr($decoded[$i]); + $codecount++; + } + } + + // All codepoints were basic ones + if ($codecount == $deco_len) { + return $encoded; + } + + // Start with the prefix; copy it to output + $encoded = $this->_punycode_prefix.$encoded; + + // If we have basic code points in output, add an hyphen to the end + if ($codecount) $encoded .= '-'; + + // Now find and encode all non-basic code points + $is_first = true; + $cur_code = $this->_initial_n; + $bias = $this->_initial_bias; + $delta = 0; + while ($codecount < $deco_len) { + // Find the smallest code point >= the current code point and + // remember the last ouccrence of it in the input + for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) { + if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) { + $next_code = $decoded[$i]; + } + } + + $delta += ($next_code - $cur_code) * ($codecount + 1); + $cur_code = $next_code; + + // Scan input again and encode all characters whose code point is $cur_code + for ($i = 0; $i < $deco_len; $i++) { + if ($decoded[$i] < $cur_code) { + $delta++; + } elseif ($decoded[$i] == $cur_code) { + for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) { + $t = ($k <= $bias) ? $this->_tmin : + (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias); + if ($q < $t) break; + $encoded .= $this->_encode_digit(ceil($t + (($q - $t) % ($this->_base - $t)))); + $q = ($q - $t) / ($this->_base - $t); + } + $encoded .= $this->_encode_digit($q); + $bias = $this->_adapt($delta, $codecount+1, $is_first); + $codecount++; + $delta = 0; + $is_first = false; + } + } + $delta++; + $cur_code++; + } + return $encoded; + } + + /** + * Adapt the bias according to the current code point and position + * @access private + */ + function _adapt($delta, $npoints, $is_first) + { + $delta = (int) ($is_first ? ($delta / $this->_damp) : ($delta / 2)); + $delta += (int) ($delta / $npoints); + for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) { + $delta = (int) ($delta / ($this->_base - $this->_tmin)); + } + return (int) ($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew)); + } + + /** + * Encoding a certain digit + * @access private + */ + function _encode_digit($d) + { + return chr($d + 22 + 75 * ($d < 26)); + } + + /** + * Decode a certain digit + * @access private + */ + function _decode_digit($cp) + { + $cp = ord($cp); + return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base)); + } + + /** + * Internal error handling method + * @access private + */ + function _error($error = '') + { + $this->_error = $error; + } + + /** + * Do Nameprep according to RFC3491 and RFC3454 + * @param array Unicode Characters + * @return string Unicode Characters, Nameprep'd + * @access private + */ + function _nameprep($input) + { + $output = array(); + $error = false; + // + // Mapping + // Walking through the input array, performing the required steps on each of + // the input chars and putting the result into the output array + // While mapping required chars we apply the cannonical ordering + + // $this->_show_hex($input); + foreach ($input as $v) { + // Map to nothing == skip that code point + if (in_array($v, $this->_np_map_nothing)) continue; + + // Try to find prohibited input + if (in_array($v, $this->_np_prohibit) || in_array($v, $this->_general_prohibited)) { + $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); + return false; + } + foreach ($this->_np_prohibit_ranges as $range) { + if ($range[0] <= $v && $v <= $range[1]) { + $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v)); + return false; + } + } + // + // Hangul syllable decomposition + if (0xAC00 <= $v && $v <= 0xD7AF) { + foreach ($this->_hangul_decompose($v) as $out) { + $output[] = $out; + } + // There's a decomposition mapping for that code point + } elseif (isset($this->_np_replacemaps[$v])) { + foreach ($this->_apply_cannonical_ordering($this->_np_replacemaps[$v]) as $out) { + $output[] = $out; + } + } else { + $output[] = $v; + } + } + // + // Combine code points + // + $last_class = 0; + $last_starter = 0; + $out_len = count($output); + for ($i = 0; $i < $out_len; ++$i) { + $class = $this->_get_combining_class($output[$i]); + if ((!$last_class || $last_class != $class) && $class) { + // Try to match + $seq_len = $i - $last_starter; + $out = $this->_combine(array_slice($output, $last_starter, $seq_len)); + // On match: Replace the last starter with the composed character and remove + // the now redundant non-starter(s) + if ($out) { + $output[$last_starter] = $out; + if (count($out) != $seq_len) { + for ($j = $i+1; $j < $out_len; ++$j) { + $output[$j-1] = $output[$j]; + } + unset($output[$out_len]); + } + // Rewind the for loop by one, since there can be more possible compositions + $i--; + $out_len--; + $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]); + continue; + } + } + if (!$class) { // The current class is 0 + $last_starter = $i; + } + $last_class = $class; + } + return $output; + } + + /** + * Decomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul + * @param integer 32bit UCS4 code point + * @return array Either Hangul Syllable decomposed or original 32bit value as one value array + * @access private + */ + function _hangul_decompose($char) + { + $sindex = $char - $this->_sbase; + if ($sindex < 0 || $sindex >= $this->_scount) { + return array($char); + } + $result = array(); + $T = $this->_tbase + $sindex % $this->_tcount; + $result[] = (int) ($this->_lbase + $sindex / $this->_ncount); + $result[] = (int) ($this->_vbase + ($sindex % $this->_ncount) / $this->_tcount); + if ($T != $this->_tbase) $result[] = $T; + return $result; + } + + /** + * Ccomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul + * @param array Decomposed UCS4 sequence + * @return array UCS4 sequence with syllables composed + * @access private + */ + function _hangul_compose($input) + { + $inp_len = count($input); + if (!$inp_len) return array(); + $result = array(); + $last = $input[0]; + $result[] = $last; // copy first char from input to output + + for ($i = 1; $i < $inp_len; ++$i) { + $char = $input[$i]; + + // Find out, wether two current characters from L and V + $lindex = $last - $this->_lbase; + if (0 <= $lindex && $lindex < $this->_lcount) { + $vindex = $char - $this->_vbase; + if (0 <= $vindex && $vindex < $this->_vcount) { + // create syllable of form LV + $last = ($this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount); + $out_off = count($result) - 1; + $result[$out_off] = $last; // reset last + continue; // discard char + } + } + + // Find out, wether two current characters are LV and T + $sindex = $last - $this->_sbase; + if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount) == 0) { + $tindex = $char - $this->_tbase; + if (0 <= $tindex && $tindex <= $this->_tcount) { + // create syllable of form LVT + $last += $tindex; + $out_off = count($result) - 1; + $result[$out_off] = $last; // reset last + continue; // discard char + } + } + // if neither case was true, just add the character + $last = $char; + $result[] = $char; + } + return $result; + } + + /** + * Returns the combining class of a certain wide char + * @param integer Wide char to check (32bit integer) + * @return integer Combining class if found, else 0 + * @access private + */ + function _get_combining_class($char) + { + return isset($this->np_norm_combcls[$char]) ? $this->np_norm_combcls[$char] : 0; + } + + /** + * Apllies the cannonical ordering of a decomposed UCS4 sequence + * @param array Decomposed UCS4 sequence + * @return array Ordered USC4 sequence + * @access private + */ + function _apply_cannonical_ordering($input) + { + $swap = true; + $size = count($input); + while ($swap) { + $swap = false; + $last = $this->_get_combining_class($input[0]); + for ($i = 0; $i < $size - 1; ++$i) { + $next = $this->_get_combining_class($input[$i+1]); + if ($next != 0 && $last > $next) { + // Move item leftward until it fits + for ($j = $i + 1; $j > 0; --$j) { + if ($this->_get_combining_class($input[$j - 1]) <= $next) break; + $t = $input[$j]; + $input[$j] = $input[$j - 1]; + $input[$j - 1] = $t; + $swap = 1; + } + // Reentering the loop looking at the old character again + $next = $last; + } + $last = $next; + } + } + return $input; + } + + /** + * Do composition of a sequence of starter and non-starter + * @param array UCS4 Decomposed sequence + * @return array Ordered USC4 sequence + * @access private + */ + function _combine($input) + { + $inp_len = count($input); + // Is it a Hangul syllable? + if (1 != $inp_len) { + $hangul = $this->_hangul_compose($input); + if (count($hangul) != $inp_len) return $hangul; // This place is probably wrong + } + foreach ($this->np_casemap as $np_src => $np_target) { + if ($np_target[0] != $input[0]) continue; + if (count($np_target) != $inp_len) continue; + $hit = false; + foreach ($input as $k2 => $v2) { + if ($v2 == $np_target[$k2]) { + $hit = true; + } else { + $hit = false; + break; + } + } + if ($hit) return $np_src; + } + return false; + } + + /** + * This converts an UTF-8 encoded string to its UCS-4 representation + * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing + * each of the "chars". This is due to PHP not being able to handle strings with + * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too. + * The following UTF-8 encodings are supported: + * bytes bits representation + * 1 7 0xxxxxxx + * 2 11 110xxxxx 10xxxxxx + * 3 16 1110xxxx 10xxxxxx 10xxxxxx + * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * Each x represents a bit that can be used to store character data. + * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000 + * @access private + */ + function _utf8_to_ucs4($input) + { + $output = array(); + $out_len = 0; + $inp_len = strlen($input); + $mode = 'next'; + $test = 'none'; + for ($k = 0; $k < $inp_len; ++$k) { + $v = ord($input{$k}); // Extract byte from input string + + if ($v < 128) { // We found an ASCII char - put into stirng as is + $output[$out_len] = $v; + ++$out_len; + if ('add' == $mode) { + $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + continue; + } + if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char + $start_byte = $v; + $mode = 'add'; + $test = 'range'; + if ($v >> 5 == 6) { // &110xxxxx 10xxxxx + $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left + $v = ($v - 192) << 6; + } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx + $next_byte = 1; + $v = ($v - 224) << 12; + } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 2; + $v = ($v - 240) << 18; + } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 3; + $v = ($v - 248) << 24; + } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 4; + $v = ($v - 252) << 30; + } else { + $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k); + return false; + } + if ('add' == $mode) { + $output[$out_len] = (int) $v; + ++$out_len; + continue; + } + } + if ('add' == $mode) { + if (!$this->_allow_overlong && $test == 'range') { + $test = 'none'; + if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) { + $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k); + return false; + } + } + if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx + $v = ($v - 128) << ($next_byte * 6); + $output[($out_len - 1)] += $v; + --$next_byte; + } else { + $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + if ($next_byte < 0) { + $mode = 'next'; + } + } + } // for + return $output; + } + + /** + * Convert UCS-4 string into UTF-8 string + * See _utf8_to_ucs4() for details + * @access private + */ + function _ucs4_to_utf8($input) + { + $output = ''; + foreach ($input as $v) { + // $v = ord($v); + if ($v < 128) { // 7bit are transferred literally + $output .= chr($v); + } elseif ($v < (1 << 11)) { // 2 bytes + $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 16)) { // 3 bytes + $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 21)) { // 4 bytes + $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } elseif ($v < (1 << 26)) { // 5 bytes + $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63)) + . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } elseif ($v < (1 << 31)) { // 6 bytes + $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63)) + . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63)); + } else { + $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k); + return false; + } + } + return $output; + } + + /** + * Convert UCS-4 array into UCS-4 string + * + * @access private + */ + function _ucs4_to_ucs4_string($input) + { + $output = ''; + // Take array values and split output to 4 bytes per value + // The bit mask is 255, which reads &11111111 + foreach ($input as $v) { + $output .= chr(($v >> 24) & 255) + . chr(($v >> 16) & 255) + . chr(($v >> 8) & 255) + . chr($v & 255); + } + return $output; + } + + /** + * Convert UCS-4 strin into UCS-4 garray + * + * @access private + */ + function _ucs4_string_to_ucs4($input) + { + $output = array(); + + $inp_len = strlen($input); + // Input length must be dividable by 4 + if ($inp_len % 4) { + $this->_error('Input UCS4 string is broken'); + return false; + } + + // Empty input - return empty output + if (!$inp_len) return $output; + + for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) { + // Increment output position every 4 input bytes + if (!($i % 4)) { + $out_len++; + $output[$out_len] = 0; + } + $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) ); + } + return $output; + } + + /** + * Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits) + * Output width is automagically determined + * @access private + */ + function show_bitmask($octet) + { + if ($octet >= (1 << 16)) $w = 31; + elseif ($octet >= (1 << 8)) $w = 15; + else $w = 7; + $return = ''; + for ($i = $w; $i > -1; $i--) { + $return .= ($octet & (1 << $i)) ? 1 : '0'; + } + return $return; + } + + /** + * echo hex represnatation of UCS4 sequence to STDOUT + * @param array UCS4 sequence + * @param boolean include bitmask in output + * @return void + * @access private + */ + function _show_hex($input, $include_bit = false) + { + foreach ($input as $k => $v) { + echo '[', $k, '] => ', sprintf('%X', $v); + if ($include_bit) { + echo ' (', $this->show_bitmask($v), ')'; + } + echo "\n"; + } + } +} + +/** +* Adapter class for aligning the API of Net_IDNA_php4 with that of +* Net_IDNA +* @author Matthias Sommerfeld +*/ +class Net_IDNA extends Net_IDNA_php4 +{ + /** + * Constructor + * + * @param array $options + * @access public + * @see setParams() + */ + function Net_IDNA($options = false) + { + $this->IC = new idna_convert($options); + return $this->IC; + } + + /** + * Sets a new option value. Available options and values: + * + * [utf8 - Use either UTF-8 or ISO-8859-1 as input (true for UTF-8, false + * otherwise); The output is always UTF-8] + * [overlong - Unicode does not allow unnecessarily long encodings of chars, + * to allow this, set this parameter to true, else to false; + * default is false.] + * [strict - true: strict mode, good for registration purposes - Causes errors + * on failures; false: loose mode, ideal for "wildlife" applications + * by silently ignoring errors and returning the original input instead] + * + * @param mixed $option Parameter to set (string: single parameter; array of Parameter => Value pairs) + * @param string $value Value to use (if parameter 1 is a string) + * @return boolean true on success, false otherwise + * @access public + */ + function setParams($option, $param = false) + { + return $this->IC->set_parameters($option, $param); + } +} + +?> diff --git a/gulliver/thirdparty/pear/Net/IDNA/php5.php b/gulliver/thirdparty/pear/Net/IDNA/php5.php new file mode 100644 index 000000000..cc8484b92 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/IDNA/php5.php @@ -0,0 +1,3233 @@ + + * @author Matthias Sommerfeld + * @author Stefan Neufeind + * @package Net + * @version $Id: php5.php,v 1.3 2008/03/22 15:24:17 neufeind Exp $ + */ + +class Net_IDNA_php5 +{ + // {{{ npdata + /** + * These Unicode codepoints are + * mapped to nothing, See RFC3454 for details + * + * @static + * @var array + * @access private + */ + private static $_np_map_nothing = array( + 0xAD, + 0x34F, + 0x1806, + 0x180B, + 0x180C, + 0x180D, + 0x200B, + 0x200C, + 0x200D, + 0x2060, + 0xFE00, + 0xFE01, + 0xFE02, + 0xFE03, + 0xFE04, + 0xFE05, + 0xFE06, + 0xFE07, + 0xFE08, + 0xFE09, + 0xFE0A, + 0xFE0B, + 0xFE0C, + 0xFE0D, + 0xFE0E, + 0xFE0F, + 0xFEFF + ); + + /** + * Prohibited codepints + * + * @static + * @var array + * @access private + */ + private static $_general_prohibited = array( + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 0xA, + 0xB, + 0xC, + 0xD, + 0xE, + 0xF, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2F, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x5B, + 0x5C, + 0x5D, + 0x5E, + 0x5F, + 0x60, + 0x7B, + 0x7C, + 0x7D, + 0x7E, + 0x7F, + 0x3002 + ); + + /** + * Codepints prohibited by Nameprep + * @static + * @var array + * @access private + */ + private static $_np_prohibit = array( + 0xA0, + 0x1680, + 0x2000, + 0x2001, + 0x2002, + 0x2003, + 0x2004, + 0x2005, + 0x2006, + 0x2007, + 0x2008, + 0x2009, + 0x200A, + 0x200B, + 0x202F, + 0x205F, + 0x3000, + 0x6DD, + 0x70F, + 0x180E, + 0x200C, + 0x200D, + 0x2028, + 0x2029, + 0xFEFF, + 0xFFF9, + 0xFFFA, + 0xFFFB, + 0xFFFC, + 0xFFFE, + 0xFFFF, + 0x1FFFE, + 0x1FFFF, + 0x2FFFE, + 0x2FFFF, + 0x3FFFE, + 0x3FFFF, + 0x4FFFE, + 0x4FFFF, + 0x5FFFE, + 0x5FFFF, + 0x6FFFE, + 0x6FFFF, + 0x7FFFE, + 0x7FFFF, + 0x8FFFE, + 0x8FFFF, + 0x9FFFE, + 0x9FFFF, + 0xAFFFE, + 0xAFFFF, + 0xBFFFE, + 0xBFFFF, + 0xCFFFE, + 0xCFFFF, + 0xDFFFE, + 0xDFFFF, + 0xEFFFE, + 0xEFFFF, + 0xFFFFE, + 0xFFFFF, + 0x10FFFE, + 0x10FFFF, + 0xFFF9, + 0xFFFA, + 0xFFFB, + 0xFFFC, + 0xFFFD, + 0x340, + 0x341, + 0x200E, + 0x200F, + 0x202A, + 0x202B, + 0x202C, + 0x202D, + 0x202E, + 0x206A, + 0x206B, + 0x206C, + 0x206D, + 0x206E, + 0x206F, + 0xE0001 + ); + + /** + * Codepoint ranges prohibited by nameprep + * + * @static + * @var array + * @access private + */ + private static $_np_prohibit_ranges = array( + array(0x80, 0x9F ), + array(0x2060, 0x206F ), + array(0x1D173, 0x1D17A ), + array(0xE000, 0xF8FF ), + array(0xF0000, 0xFFFFD ), + array(0x100000, 0x10FFFD), + array(0xFDD0, 0xFDEF ), + array(0xD800, 0xDFFF ), + array(0x2FF0, 0x2FFB ), + array(0xE0020, 0xE007F ) + ); + + /** + * Replacement mappings (casemapping, replacement sequences, ...) + * + * @static + * @var array + * @access private + */ + private static $_np_replacemaps = array( + 0x41 => array(0x61), + 0x42 => array(0x62), + 0x43 => array(0x63), + 0x44 => array(0x64), + 0x45 => array(0x65), + 0x46 => array(0x66), + 0x47 => array(0x67), + 0x48 => array(0x68), + 0x49 => array(0x69), + 0x4A => array(0x6A), + 0x4B => array(0x6B), + 0x4C => array(0x6C), + 0x4D => array(0x6D), + 0x4E => array(0x6E), + 0x4F => array(0x6F), + 0x50 => array(0x70), + 0x51 => array(0x71), + 0x52 => array(0x72), + 0x53 => array(0x73), + 0x54 => array(0x74), + 0x55 => array(0x75), + 0x56 => array(0x76), + 0x57 => array(0x77), + 0x58 => array(0x78), + 0x59 => array(0x79), + 0x5A => array(0x7A), + 0xB5 => array(0x3BC), + 0xC0 => array(0xE0), + 0xC1 => array(0xE1), + 0xC2 => array(0xE2), + 0xC3 => array(0xE3), + 0xC4 => array(0xE4), + 0xC5 => array(0xE5), + 0xC6 => array(0xE6), + 0xC7 => array(0xE7), + 0xC8 => array(0xE8), + 0xC9 => array(0xE9), + 0xCA => array(0xEA), + 0xCB => array(0xEB), + 0xCC => array(0xEC), + 0xCD => array(0xED), + 0xCE => array(0xEE), + 0xCF => array(0xEF), + 0xD0 => array(0xF0), + 0xD1 => array(0xF1), + 0xD2 => array(0xF2), + 0xD3 => array(0xF3), + 0xD4 => array(0xF4), + 0xD5 => array(0xF5), + 0xD6 => array(0xF6), + 0xD8 => array(0xF8), + 0xD9 => array(0xF9), + 0xDA => array(0xFA), + 0xDB => array(0xFB), + 0xDC => array(0xFC), + 0xDD => array(0xFD), + 0xDE => array(0xFE), + 0xDF => array(0x73, 0x73), + 0x100 => array(0x101), + 0x102 => array(0x103), + 0x104 => array(0x105), + 0x106 => array(0x107), + 0x108 => array(0x109), + 0x10A => array(0x10B), + 0x10C => array(0x10D), + 0x10E => array(0x10F), + 0x110 => array(0x111), + 0x112 => array(0x113), + 0x114 => array(0x115), + 0x116 => array(0x117), + 0x118 => array(0x119), + 0x11A => array(0x11B), + 0x11C => array(0x11D), + 0x11E => array(0x11F), + 0x120 => array(0x121), + 0x122 => array(0x123), + 0x124 => array(0x125), + 0x126 => array(0x127), + 0x128 => array(0x129), + 0x12A => array(0x12B), + 0x12C => array(0x12D), + 0x12E => array(0x12F), + 0x130 => array(0x69, 0x307), + 0x132 => array(0x133), + 0x134 => array(0x135), + 0x136 => array(0x137), + 0x139 => array(0x13A), + 0x13B => array(0x13C), + 0x13D => array(0x13E), + 0x13F => array(0x140), + 0x141 => array(0x142), + 0x143 => array(0x144), + 0x145 => array(0x146), + 0x147 => array(0x148), + 0x149 => array(0x2BC, 0x6E), + 0x14A => array(0x14B), + 0x14C => array(0x14D), + 0x14E => array(0x14F), + 0x150 => array(0x151), + 0x152 => array(0x153), + 0x154 => array(0x155), + 0x156 => array(0x157), + 0x158 => array(0x159), + 0x15A => array(0x15B), + 0x15C => array(0x15D), + 0x15E => array(0x15F), + 0x160 => array(0x161), + 0x162 => array(0x163), + 0x164 => array(0x165), + 0x166 => array(0x167), + 0x168 => array(0x169), + 0x16A => array(0x16B), + 0x16C => array(0x16D), + 0x16E => array(0x16F), + 0x170 => array(0x171), + 0x172 => array(0x173), + 0x174 => array(0x175), + 0x176 => array(0x177), + 0x178 => array(0xFF), + 0x179 => array(0x17A), + 0x17B => array(0x17C), + 0x17D => array(0x17E), + 0x17F => array(0x73), + 0x181 => array(0x253), + 0x182 => array(0x183), + 0x184 => array(0x185), + 0x186 => array(0x254), + 0x187 => array(0x188), + 0x189 => array(0x256), + 0x18A => array(0x257), + 0x18B => array(0x18C), + 0x18E => array(0x1DD), + 0x18F => array(0x259), + 0x190 => array(0x25B), + 0x191 => array(0x192), + 0x193 => array(0x260), + 0x194 => array(0x263), + 0x196 => array(0x269), + 0x197 => array(0x268), + 0x198 => array(0x199), + 0x19C => array(0x26F), + 0x19D => array(0x272), + 0x19F => array(0x275), + 0x1A0 => array(0x1A1), + 0x1A2 => array(0x1A3), + 0x1A4 => array(0x1A5), + 0x1A6 => array(0x280), + 0x1A7 => array(0x1A8), + 0x1A9 => array(0x283), + 0x1AC => array(0x1AD), + 0x1AE => array(0x288), + 0x1AF => array(0x1B0), + 0x1B1 => array(0x28A), + 0x1B2 => array(0x28B), + 0x1B3 => array(0x1B4), + 0x1B5 => array(0x1B6), + 0x1B7 => array(0x292), + 0x1B8 => array(0x1B9), + 0x1BC => array(0x1BD), + 0x1C4 => array(0x1C6), + 0x1C5 => array(0x1C6), + 0x1C7 => array(0x1C9), + 0x1C8 => array(0x1C9), + 0x1CA => array(0x1CC), + 0x1CB => array(0x1CC), + 0x1CD => array(0x1CE), + 0x1CF => array(0x1D0), + 0x1D1 => array(0x1D2), + 0x1D3 => array(0x1D4), + 0x1D5 => array(0x1D6), + 0x1D7 => array(0x1D8), + 0x1D9 => array(0x1DA), + 0x1DB => array(0x1DC), + 0x1DE => array(0x1DF), + 0x1E0 => array(0x1E1), + 0x1E2 => array(0x1E3), + 0x1E4 => array(0x1E5), + 0x1E6 => array(0x1E7), + 0x1E8 => array(0x1E9), + 0x1EA => array(0x1EB), + 0x1EC => array(0x1ED), + 0x1EE => array(0x1EF), + 0x1F0 => array(0x6A, 0x30C), + 0x1F1 => array(0x1F3), + 0x1F2 => array(0x1F3), + 0x1F4 => array(0x1F5), + 0x1F6 => array(0x195), + 0x1F7 => array(0x1BF), + 0x1F8 => array(0x1F9), + 0x1FA => array(0x1FB), + 0x1FC => array(0x1FD), + 0x1FE => array(0x1FF), + 0x200 => array(0x201), + 0x202 => array(0x203), + 0x204 => array(0x205), + 0x206 => array(0x207), + 0x208 => array(0x209), + 0x20A => array(0x20B), + 0x20C => array(0x20D), + 0x20E => array(0x20F), + 0x210 => array(0x211), + 0x212 => array(0x213), + 0x214 => array(0x215), + 0x216 => array(0x217), + 0x218 => array(0x219), + 0x21A => array(0x21B), + 0x21C => array(0x21D), + 0x21E => array(0x21F), + 0x220 => array(0x19E), + 0x222 => array(0x223), + 0x224 => array(0x225), + 0x226 => array(0x227), + 0x228 => array(0x229), + 0x22A => array(0x22B), + 0x22C => array(0x22D), + 0x22E => array(0x22F), + 0x230 => array(0x231), + 0x232 => array(0x233), + 0x345 => array(0x3B9), + 0x37A => array(0x20, 0x3B9), + 0x386 => array(0x3AC), + 0x388 => array(0x3AD), + 0x389 => array(0x3AE), + 0x38A => array(0x3AF), + 0x38C => array(0x3CC), + 0x38E => array(0x3CD), + 0x38F => array(0x3CE), + 0x390 => array(0x3B9, 0x308, 0x301), + 0x391 => array(0x3B1), + 0x392 => array(0x3B2), + 0x393 => array(0x3B3), + 0x394 => array(0x3B4), + 0x395 => array(0x3B5), + 0x396 => array(0x3B6), + 0x397 => array(0x3B7), + 0x398 => array(0x3B8), + 0x399 => array(0x3B9), + 0x39A => array(0x3BA), + 0x39B => array(0x3BB), + 0x39C => array(0x3BC), + 0x39D => array(0x3BD), + 0x39E => array(0x3BE), + 0x39F => array(0x3BF), + 0x3A0 => array(0x3C0), + 0x3A1 => array(0x3C1), + 0x3A3 => array(0x3C3), + 0x3A4 => array(0x3C4), + 0x3A5 => array(0x3C5), + 0x3A6 => array(0x3C6), + 0x3A7 => array(0x3C7), + 0x3A8 => array(0x3C8), + 0x3A9 => array(0x3C9), + 0x3AA => array(0x3CA), + 0x3AB => array(0x3CB), + 0x3B0 => array(0x3C5, 0x308, 0x301), + 0x3C2 => array(0x3C3), + 0x3D0 => array(0x3B2), + 0x3D1 => array(0x3B8), + 0x3D2 => array(0x3C5), + 0x3D3 => array(0x3CD), + 0x3D4 => array(0x3CB), + 0x3D5 => array(0x3C6), + 0x3D6 => array(0x3C0), + 0x3D8 => array(0x3D9), + 0x3DA => array(0x3DB), + 0x3DC => array(0x3DD), + 0x3DE => array(0x3DF), + 0x3E0 => array(0x3E1), + 0x3E2 => array(0x3E3), + 0x3E4 => array(0x3E5), + 0x3E6 => array(0x3E7), + 0x3E8 => array(0x3E9), + 0x3EA => array(0x3EB), + 0x3EC => array(0x3ED), + 0x3EE => array(0x3EF), + 0x3F0 => array(0x3BA), + 0x3F1 => array(0x3C1), + 0x3F2 => array(0x3C3), + 0x3F4 => array(0x3B8), + 0x3F5 => array(0x3B5), + 0x400 => array(0x450), + 0x401 => array(0x451), + 0x402 => array(0x452), + 0x403 => array(0x453), + 0x404 => array(0x454), + 0x405 => array(0x455), + 0x406 => array(0x456), + 0x407 => array(0x457), + 0x408 => array(0x458), + 0x409 => array(0x459), + 0x40A => array(0x45A), + 0x40B => array(0x45B), + 0x40C => array(0x45C), + 0x40D => array(0x45D), + 0x40E => array(0x45E), + 0x40F => array(0x45F), + 0x410 => array(0x430), + 0x411 => array(0x431), + 0x412 => array(0x432), + 0x413 => array(0x433), + 0x414 => array(0x434), + 0x415 => array(0x435), + 0x416 => array(0x436), + 0x417 => array(0x437), + 0x418 => array(0x438), + 0x419 => array(0x439), + 0x41A => array(0x43A), + 0x41B => array(0x43B), + 0x41C => array(0x43C), + 0x41D => array(0x43D), + 0x41E => array(0x43E), + 0x41F => array(0x43F), + 0x420 => array(0x440), + 0x421 => array(0x441), + 0x422 => array(0x442), + 0x423 => array(0x443), + 0x424 => array(0x444), + 0x425 => array(0x445), + 0x426 => array(0x446), + 0x427 => array(0x447), + 0x428 => array(0x448), + 0x429 => array(0x449), + 0x42A => array(0x44A), + 0x42B => array(0x44B), + 0x42C => array(0x44C), + 0x42D => array(0x44D), + 0x42E => array(0x44E), + 0x42F => array(0x44F), + 0x460 => array(0x461), + 0x462 => array(0x463), + 0x464 => array(0x465), + 0x466 => array(0x467), + 0x468 => array(0x469), + 0x46A => array(0x46B), + 0x46C => array(0x46D), + 0x46E => array(0x46F), + 0x470 => array(0x471), + 0x472 => array(0x473), + 0x474 => array(0x475), + 0x476 => array(0x477), + 0x478 => array(0x479), + 0x47A => array(0x47B), + 0x47C => array(0x47D), + 0x47E => array(0x47F), + 0x480 => array(0x481), + 0x48A => array(0x48B), + 0x48C => array(0x48D), + 0x48E => array(0x48F), + 0x490 => array(0x491), + 0x492 => array(0x493), + 0x494 => array(0x495), + 0x496 => array(0x497), + 0x498 => array(0x499), + 0x49A => array(0x49B), + 0x49C => array(0x49D), + 0x49E => array(0x49F), + 0x4A0 => array(0x4A1), + 0x4A2 => array(0x4A3), + 0x4A4 => array(0x4A5), + 0x4A6 => array(0x4A7), + 0x4A8 => array(0x4A9), + 0x4AA => array(0x4AB), + 0x4AC => array(0x4AD), + 0x4AE => array(0x4AF), + 0x4B0 => array(0x4B1), + 0x4B2 => array(0x4B3), + 0x4B4 => array(0x4B5), + 0x4B6 => array(0x4B7), + 0x4B8 => array(0x4B9), + 0x4BA => array(0x4BB), + 0x4BC => array(0x4BD), + 0x4BE => array(0x4BF), + 0x4C1 => array(0x4C2), + 0x4C3 => array(0x4C4), + 0x4C5 => array(0x4C6), + 0x4C7 => array(0x4C8), + 0x4C9 => array(0x4CA), + 0x4CB => array(0x4CC), + 0x4CD => array(0x4CE), + 0x4D0 => array(0x4D1), + 0x4D2 => array(0x4D3), + 0x4D4 => array(0x4D5), + 0x4D6 => array(0x4D7), + 0x4D8 => array(0x4D9), + 0x4DA => array(0x4DB), + 0x4DC => array(0x4DD), + 0x4DE => array(0x4DF), + 0x4E0 => array(0x4E1), + 0x4E2 => array(0x4E3), + 0x4E4 => array(0x4E5), + 0x4E6 => array(0x4E7), + 0x4E8 => array(0x4E9), + 0x4EA => array(0x4EB), + 0x4EC => array(0x4ED), + 0x4EE => array(0x4EF), + 0x4F0 => array(0x4F1), + 0x4F2 => array(0x4F3), + 0x4F4 => array(0x4F5), + 0x4F8 => array(0x4F9), + 0x500 => array(0x501), + 0x502 => array(0x503), + 0x504 => array(0x505), + 0x506 => array(0x507), + 0x508 => array(0x509), + 0x50A => array(0x50B), + 0x50C => array(0x50D), + 0x50E => array(0x50F), + 0x531 => array(0x561), + 0x532 => array(0x562), + 0x533 => array(0x563), + 0x534 => array(0x564), + 0x535 => array(0x565), + 0x536 => array(0x566), + 0x537 => array(0x567), + 0x538 => array(0x568), + 0x539 => array(0x569), + 0x53A => array(0x56A), + 0x53B => array(0x56B), + 0x53C => array(0x56C), + 0x53D => array(0x56D), + 0x53E => array(0x56E), + 0x53F => array(0x56F), + 0x540 => array(0x570), + 0x541 => array(0x571), + 0x542 => array(0x572), + 0x543 => array(0x573), + 0x544 => array(0x574), + 0x545 => array(0x575), + 0x546 => array(0x576), + 0x547 => array(0x577), + 0x548 => array(0x578), + 0x549 => array(0x579), + 0x54A => array(0x57A), + 0x54B => array(0x57B), + 0x54C => array(0x57C), + 0x54D => array(0x57D), + 0x54E => array(0x57E), + 0x54F => array(0x57F), + 0x550 => array(0x580), + 0x551 => array(0x581), + 0x552 => array(0x582), + 0x553 => array(0x583), + 0x554 => array(0x584), + 0x555 => array(0x585), + 0x556 => array(0x586), + 0x587 => array(0x565, 0x582), + 0x1E00 => array(0x1E01), + 0x1E02 => array(0x1E03), + 0x1E04 => array(0x1E05), + 0x1E06 => array(0x1E07), + 0x1E08 => array(0x1E09), + 0x1E0A => array(0x1E0B), + 0x1E0C => array(0x1E0D), + 0x1E0E => array(0x1E0F), + 0x1E10 => array(0x1E11), + 0x1E12 => array(0x1E13), + 0x1E14 => array(0x1E15), + 0x1E16 => array(0x1E17), + 0x1E18 => array(0x1E19), + 0x1E1A => array(0x1E1B), + 0x1E1C => array(0x1E1D), + 0x1E1E => array(0x1E1F), + 0x1E20 => array(0x1E21), + 0x1E22 => array(0x1E23), + 0x1E24 => array(0x1E25), + 0x1E26 => array(0x1E27), + 0x1E28 => array(0x1E29), + 0x1E2A => array(0x1E2B), + 0x1E2C => array(0x1E2D), + 0x1E2E => array(0x1E2F), + 0x1E30 => array(0x1E31), + 0x1E32 => array(0x1E33), + 0x1E34 => array(0x1E35), + 0x1E36 => array(0x1E37), + 0x1E38 => array(0x1E39), + 0x1E3A => array(0x1E3B), + 0x1E3C => array(0x1E3D), + 0x1E3E => array(0x1E3F), + 0x1E40 => array(0x1E41), + 0x1E42 => array(0x1E43), + 0x1E44 => array(0x1E45), + 0x1E46 => array(0x1E47), + 0x1E48 => array(0x1E49), + 0x1E4A => array(0x1E4B), + 0x1E4C => array(0x1E4D), + 0x1E4E => array(0x1E4F), + 0x1E50 => array(0x1E51), + 0x1E52 => array(0x1E53), + 0x1E54 => array(0x1E55), + 0x1E56 => array(0x1E57), + 0x1E58 => array(0x1E59), + 0x1E5A => array(0x1E5B), + 0x1E5C => array(0x1E5D), + 0x1E5E => array(0x1E5F), + 0x1E60 => array(0x1E61), + 0x1E62 => array(0x1E63), + 0x1E64 => array(0x1E65), + 0x1E66 => array(0x1E67), + 0x1E68 => array(0x1E69), + 0x1E6A => array(0x1E6B), + 0x1E6C => array(0x1E6D), + 0x1E6E => array(0x1E6F), + 0x1E70 => array(0x1E71), + 0x1E72 => array(0x1E73), + 0x1E74 => array(0x1E75), + 0x1E76 => array(0x1E77), + 0x1E78 => array(0x1E79), + 0x1E7A => array(0x1E7B), + 0x1E7C => array(0x1E7D), + 0x1E7E => array(0x1E7F), + 0x1E80 => array(0x1E81), + 0x1E82 => array(0x1E83), + 0x1E84 => array(0x1E85), + 0x1E86 => array(0x1E87), + 0x1E88 => array(0x1E89), + 0x1E8A => array(0x1E8B), + 0x1E8C => array(0x1E8D), + 0x1E8E => array(0x1E8F), + 0x1E90 => array(0x1E91), + 0x1E92 => array(0x1E93), + 0x1E94 => array(0x1E95), + 0x1E96 => array(0x68, 0x331), + 0x1E97 => array(0x74, 0x308), + 0x1E98 => array(0x77, 0x30A), + 0x1E99 => array(0x79, 0x30A), + 0x1E9A => array(0x61, 0x2BE), + 0x1E9B => array(0x1E61), + 0x1EA0 => array(0x1EA1), + 0x1EA2 => array(0x1EA3), + 0x1EA4 => array(0x1EA5), + 0x1EA6 => array(0x1EA7), + 0x1EA8 => array(0x1EA9), + 0x1EAA => array(0x1EAB), + 0x1EAC => array(0x1EAD), + 0x1EAE => array(0x1EAF), + 0x1EB0 => array(0x1EB1), + 0x1EB2 => array(0x1EB3), + 0x1EB4 => array(0x1EB5), + 0x1EB6 => array(0x1EB7), + 0x1EB8 => array(0x1EB9), + 0x1EBA => array(0x1EBB), + 0x1EBC => array(0x1EBD), + 0x1EBE => array(0x1EBF), + 0x1EC0 => array(0x1EC1), + 0x1EC2 => array(0x1EC3), + 0x1EC4 => array(0x1EC5), + 0x1EC6 => array(0x1EC7), + 0x1EC8 => array(0x1EC9), + 0x1ECA => array(0x1ECB), + 0x1ECC => array(0x1ECD), + 0x1ECE => array(0x1ECF), + 0x1ED0 => array(0x1ED1), + 0x1ED2 => array(0x1ED3), + 0x1ED4 => array(0x1ED5), + 0x1ED6 => array(0x1ED7), + 0x1ED8 => array(0x1ED9), + 0x1EDA => array(0x1EDB), + 0x1EDC => array(0x1EDD), + 0x1EDE => array(0x1EDF), + 0x1EE0 => array(0x1EE1), + 0x1EE2 => array(0x1EE3), + 0x1EE4 => array(0x1EE5), + 0x1EE6 => array(0x1EE7), + 0x1EE8 => array(0x1EE9), + 0x1EEA => array(0x1EEB), + 0x1EEC => array(0x1EED), + 0x1EEE => array(0x1EEF), + 0x1EF0 => array(0x1EF1), + 0x1EF2 => array(0x1EF3), + 0x1EF4 => array(0x1EF5), + 0x1EF6 => array(0x1EF7), + 0x1EF8 => array(0x1EF9), + 0x1F08 => array(0x1F00), + 0x1F09 => array(0x1F01), + 0x1F0A => array(0x1F02), + 0x1F0B => array(0x1F03), + 0x1F0C => array(0x1F04), + 0x1F0D => array(0x1F05), + 0x1F0E => array(0x1F06), + 0x1F0F => array(0x1F07), + 0x1F18 => array(0x1F10), + 0x1F19 => array(0x1F11), + 0x1F1A => array(0x1F12), + 0x1F1B => array(0x1F13), + 0x1F1C => array(0x1F14), + 0x1F1D => array(0x1F15), + 0x1F28 => array(0x1F20), + 0x1F29 => array(0x1F21), + 0x1F2A => array(0x1F22), + 0x1F2B => array(0x1F23), + 0x1F2C => array(0x1F24), + 0x1F2D => array(0x1F25), + 0x1F2E => array(0x1F26), + 0x1F2F => array(0x1F27), + 0x1F38 => array(0x1F30), + 0x1F39 => array(0x1F31), + 0x1F3A => array(0x1F32), + 0x1F3B => array(0x1F33), + 0x1F3C => array(0x1F34), + 0x1F3D => array(0x1F35), + 0x1F3E => array(0x1F36), + 0x1F3F => array(0x1F37), + 0x1F48 => array(0x1F40), + 0x1F49 => array(0x1F41), + 0x1F4A => array(0x1F42), + 0x1F4B => array(0x1F43), + 0x1F4C => array(0x1F44), + 0x1F4D => array(0x1F45), + 0x1F50 => array(0x3C5, 0x313), + 0x1F52 => array(0x3C5, 0x313, 0x300), + 0x1F54 => array(0x3C5, 0x313, 0x301), + 0x1F56 => array(0x3C5, 0x313, 0x342), + 0x1F59 => array(0x1F51), + 0x1F5B => array(0x1F53), + 0x1F5D => array(0x1F55), + 0x1F5F => array(0x1F57), + 0x1F68 => array(0x1F60), + 0x1F69 => array(0x1F61), + 0x1F6A => array(0x1F62), + 0x1F6B => array(0x1F63), + 0x1F6C => array(0x1F64), + 0x1F6D => array(0x1F65), + 0x1F6E => array(0x1F66), + 0x1F6F => array(0x1F67), + 0x1F80 => array(0x1F00, 0x3B9), + 0x1F81 => array(0x1F01, 0x3B9), + 0x1F82 => array(0x1F02, 0x3B9), + 0x1F83 => array(0x1F03, 0x3B9), + 0x1F84 => array(0x1F04, 0x3B9), + 0x1F85 => array(0x1F05, 0x3B9), + 0x1F86 => array(0x1F06, 0x3B9), + 0x1F87 => array(0x1F07, 0x3B9), + 0x1F88 => array(0x1F00, 0x3B9), + 0x1F89 => array(0x1F01, 0x3B9), + 0x1F8A => array(0x1F02, 0x3B9), + 0x1F8B => array(0x1F03, 0x3B9), + 0x1F8C => array(0x1F04, 0x3B9), + 0x1F8D => array(0x1F05, 0x3B9), + 0x1F8E => array(0x1F06, 0x3B9), + 0x1F8F => array(0x1F07, 0x3B9), + 0x1F90 => array(0x1F20, 0x3B9), + 0x1F91 => array(0x1F21, 0x3B9), + 0x1F92 => array(0x1F22, 0x3B9), + 0x1F93 => array(0x1F23, 0x3B9), + 0x1F94 => array(0x1F24, 0x3B9), + 0x1F95 => array(0x1F25, 0x3B9), + 0x1F96 => array(0x1F26, 0x3B9), + 0x1F97 => array(0x1F27, 0x3B9), + 0x1F98 => array(0x1F20, 0x3B9), + 0x1F99 => array(0x1F21, 0x3B9), + 0x1F9A => array(0x1F22, 0x3B9), + 0x1F9B => array(0x1F23, 0x3B9), + 0x1F9C => array(0x1F24, 0x3B9), + 0x1F9D => array(0x1F25, 0x3B9), + 0x1F9E => array(0x1F26, 0x3B9), + 0x1F9F => array(0x1F27, 0x3B9), + 0x1FA0 => array(0x1F60, 0x3B9), + 0x1FA1 => array(0x1F61, 0x3B9), + 0x1FA2 => array(0x1F62, 0x3B9), + 0x1FA3 => array(0x1F63, 0x3B9), + 0x1FA4 => array(0x1F64, 0x3B9), + 0x1FA5 => array(0x1F65, 0x3B9), + 0x1FA6 => array(0x1F66, 0x3B9), + 0x1FA7 => array(0x1F67, 0x3B9), + 0x1FA8 => array(0x1F60, 0x3B9), + 0x1FA9 => array(0x1F61, 0x3B9), + 0x1FAA => array(0x1F62, 0x3B9), + 0x1FAB => array(0x1F63, 0x3B9), + 0x1FAC => array(0x1F64, 0x3B9), + 0x1FAD => array(0x1F65, 0x3B9), + 0x1FAE => array(0x1F66, 0x3B9), + 0x1FAF => array(0x1F67, 0x3B9), + 0x1FB2 => array(0x1F70, 0x3B9), + 0x1FB3 => array(0x3B1, 0x3B9), + 0x1FB4 => array(0x3AC, 0x3B9), + 0x1FB6 => array(0x3B1, 0x342), + 0x1FB7 => array(0x3B1, 0x342, 0x3B9), + 0x1FB8 => array(0x1FB0), + 0x1FB9 => array(0x1FB1), + 0x1FBA => array(0x1F70), + 0x1FBB => array(0x1F71), + 0x1FBC => array(0x3B1, 0x3B9), + 0x1FBE => array(0x3B9), + 0x1FC2 => array(0x1F74, 0x3B9), + 0x1FC3 => array(0x3B7, 0x3B9), + 0x1FC4 => array(0x3AE, 0x3B9), + 0x1FC6 => array(0x3B7, 0x342), + 0x1FC7 => array(0x3B7, 0x342, 0x3B9), + 0x1FC8 => array(0x1F72), + 0x1FC9 => array(0x1F73), + 0x1FCA => array(0x1F74), + 0x1FCB => array(0x1F75), + 0x1FCC => array(0x3B7, 0x3B9), + 0x1FD2 => array(0x3B9, 0x308, 0x300), + 0x1FD3 => array(0x3B9, 0x308, 0x301), + 0x1FD6 => array(0x3B9, 0x342), + 0x1FD7 => array(0x3B9, 0x308, 0x342), + 0x1FD8 => array(0x1FD0), + 0x1FD9 => array(0x1FD1), + 0x1FDA => array(0x1F76), + 0x1FDB => array(0x1F77), + 0x1FE2 => array(0x3C5, 0x308, 0x300), + 0x1FE3 => array(0x3C5, 0x308, 0x301), + 0x1FE4 => array(0x3C1, 0x313), + 0x1FE6 => array(0x3C5, 0x342), + 0x1FE7 => array(0x3C5, 0x308, 0x342), + 0x1FE8 => array(0x1FE0), + 0x1FE9 => array(0x1FE1), + 0x1FEA => array(0x1F7A), + 0x1FEB => array(0x1F7B), + 0x1FEC => array(0x1FE5), + 0x1FF2 => array(0x1F7C, 0x3B9), + 0x1FF3 => array(0x3C9, 0x3B9), + 0x1FF4 => array(0x3CE, 0x3B9), + 0x1FF6 => array(0x3C9, 0x342), + 0x1FF7 => array(0x3C9, 0x342, 0x3B9), + 0x1FF8 => array(0x1F78), + 0x1FF9 => array(0x1F79), + 0x1FFA => array(0x1F7C), + 0x1FFB => array(0x1F7D), + 0x1FFC => array(0x3C9, 0x3B9), + 0x20A8 => array(0x72, 0x73), + 0x2102 => array(0x63), + 0x2103 => array(0xB0, 0x63), + 0x2107 => array(0x25B), + 0x2109 => array(0xB0, 0x66), + 0x210B => array(0x68), + 0x210C => array(0x68), + 0x210D => array(0x68), + 0x2110 => array(0x69), + 0x2111 => array(0x69), + 0x2112 => array(0x6C), + 0x2115 => array(0x6E), + 0x2116 => array(0x6E, 0x6F), + 0x2119 => array(0x70), + 0x211A => array(0x71), + 0x211B => array(0x72), + 0x211C => array(0x72), + 0x211D => array(0x72), + 0x2120 => array(0x73, 0x6D), + 0x2121 => array(0x74, 0x65, 0x6C), + 0x2122 => array(0x74, 0x6D), + 0x2124 => array(0x7A), + 0x2126 => array(0x3C9), + 0x2128 => array(0x7A), + 0x212A => array(0x6B), + 0x212B => array(0xE5), + 0x212C => array(0x62), + 0x212D => array(0x63), + 0x2130 => array(0x65), + 0x2131 => array(0x66), + 0x2133 => array(0x6D), + 0x213E => array(0x3B3), + 0x213F => array(0x3C0), + 0x2145 => array(0x64), + 0x2160 => array(0x2170), + 0x2161 => array(0x2171), + 0x2162 => array(0x2172), + 0x2163 => array(0x2173), + 0x2164 => array(0x2174), + 0x2165 => array(0x2175), + 0x2166 => array(0x2176), + 0x2167 => array(0x2177), + 0x2168 => array(0x2178), + 0x2169 => array(0x2179), + 0x216A => array(0x217A), + 0x216B => array(0x217B), + 0x216C => array(0x217C), + 0x216D => array(0x217D), + 0x216E => array(0x217E), + 0x216F => array(0x217F), + 0x24B6 => array(0x24D0), + 0x24B7 => array(0x24D1), + 0x24B8 => array(0x24D2), + 0x24B9 => array(0x24D3), + 0x24BA => array(0x24D4), + 0x24BB => array(0x24D5), + 0x24BC => array(0x24D6), + 0x24BD => array(0x24D7), + 0x24BE => array(0x24D8), + 0x24BF => array(0x24D9), + 0x24C0 => array(0x24DA), + 0x24C1 => array(0x24DB), + 0x24C2 => array(0x24DC), + 0x24C3 => array(0x24DD), + 0x24C4 => array(0x24DE), + 0x24C5 => array(0x24DF), + 0x24C6 => array(0x24E0), + 0x24C7 => array(0x24E1), + 0x24C8 => array(0x24E2), + 0x24C9 => array(0x24E3), + 0x24CA => array(0x24E4), + 0x24CB => array(0x24E5), + 0x24CC => array(0x24E6), + 0x24CD => array(0x24E7), + 0x24CE => array(0x24E8), + 0x24CF => array(0x24E9), + 0x3371 => array(0x68, 0x70, 0x61), + 0x3373 => array(0x61, 0x75), + 0x3375 => array(0x6F, 0x76), + 0x3380 => array(0x70, 0x61), + 0x3381 => array(0x6E, 0x61), + 0x3382 => array(0x3BC, 0x61), + 0x3383 => array(0x6D, 0x61), + 0x3384 => array(0x6B, 0x61), + 0x3385 => array(0x6B, 0x62), + 0x3386 => array(0x6D, 0x62), + 0x3387 => array(0x67, 0x62), + 0x338A => array(0x70, 0x66), + 0x338B => array(0x6E, 0x66), + 0x338C => array(0x3BC, 0x66), + 0x3390 => array(0x68, 0x7A), + 0x3391 => array(0x6B, 0x68, 0x7A), + 0x3392 => array(0x6D, 0x68, 0x7A), + 0x3393 => array(0x67, 0x68, 0x7A), + 0x3394 => array(0x74, 0x68, 0x7A), + 0x33A9 => array(0x70, 0x61), + 0x33AA => array(0x6B, 0x70, 0x61), + 0x33AB => array(0x6D, 0x70, 0x61), + 0x33AC => array(0x67, 0x70, 0x61), + 0x33B4 => array(0x70, 0x76), + 0x33B5 => array(0x6E, 0x76), + 0x33B6 => array(0x3BC, 0x76), + 0x33B7 => array(0x6D, 0x76), + 0x33B8 => array(0x6B, 0x76), + 0x33B9 => array(0x6D, 0x76), + 0x33BA => array(0x70, 0x77), + 0x33BB => array(0x6E, 0x77), + 0x33BC => array(0x3BC, 0x77), + 0x33BD => array(0x6D, 0x77), + 0x33BE => array(0x6B, 0x77), + 0x33BF => array(0x6D, 0x77), + 0x33C0 => array(0x6B, 0x3C9), + 0x33C1 => array(0x6D, 0x3C9), /* + 0x33C2 => array(0x61, 0x2E, 0x6D, 0x2E), */ + 0x33C3 => array(0x62, 0x71), + 0x33C6 => array(0x63, 0x2215, 0x6B, 0x67), + 0x33C7 => array(0x63, 0x6F, 0x2E), + 0x33C8 => array(0x64, 0x62), + 0x33C9 => array(0x67, 0x79), + 0x33CB => array(0x68, 0x70), + 0x33CD => array(0x6B, 0x6B), + 0x33CE => array(0x6B, 0x6D), + 0x33D7 => array(0x70, 0x68), + 0x33D9 => array(0x70, 0x70, 0x6D), + 0x33DA => array(0x70, 0x72), + 0x33DC => array(0x73, 0x76), + 0x33DD => array(0x77, 0x62), + 0xFB00 => array(0x66, 0x66), + 0xFB01 => array(0x66, 0x69), + 0xFB02 => array(0x66, 0x6C), + 0xFB03 => array(0x66, 0x66, 0x69), + 0xFB04 => array(0x66, 0x66, 0x6C), + 0xFB05 => array(0x73, 0x74), + 0xFB06 => array(0x73, 0x74), + 0xFB13 => array(0x574, 0x576), + 0xFB14 => array(0x574, 0x565), + 0xFB15 => array(0x574, 0x56B), + 0xFB16 => array(0x57E, 0x576), + 0xFB17 => array(0x574, 0x56D), + 0xFF21 => array(0xFF41), + 0xFF22 => array(0xFF42), + 0xFF23 => array(0xFF43), + 0xFF24 => array(0xFF44), + 0xFF25 => array(0xFF45), + 0xFF26 => array(0xFF46), + 0xFF27 => array(0xFF47), + 0xFF28 => array(0xFF48), + 0xFF29 => array(0xFF49), + 0xFF2A => array(0xFF4A), + 0xFF2B => array(0xFF4B), + 0xFF2C => array(0xFF4C), + 0xFF2D => array(0xFF4D), + 0xFF2E => array(0xFF4E), + 0xFF2F => array(0xFF4F), + 0xFF30 => array(0xFF50), + 0xFF31 => array(0xFF51), + 0xFF32 => array(0xFF52), + 0xFF33 => array(0xFF53), + 0xFF34 => array(0xFF54), + 0xFF35 => array(0xFF55), + 0xFF36 => array(0xFF56), + 0xFF37 => array(0xFF57), + 0xFF38 => array(0xFF58), + 0xFF39 => array(0xFF59), + 0xFF3A => array(0xFF5A), + 0x10400 => array(0x10428), + 0x10401 => array(0x10429), + 0x10402 => array(0x1042A), + 0x10403 => array(0x1042B), + 0x10404 => array(0x1042C), + 0x10405 => array(0x1042D), + 0x10406 => array(0x1042E), + 0x10407 => array(0x1042F), + 0x10408 => array(0x10430), + 0x10409 => array(0x10431), + 0x1040A => array(0x10432), + 0x1040B => array(0x10433), + 0x1040C => array(0x10434), + 0x1040D => array(0x10435), + 0x1040E => array(0x10436), + 0x1040F => array(0x10437), + 0x10410 => array(0x10438), + 0x10411 => array(0x10439), + 0x10412 => array(0x1043A), + 0x10413 => array(0x1043B), + 0x10414 => array(0x1043C), + 0x10415 => array(0x1043D), + 0x10416 => array(0x1043E), + 0x10417 => array(0x1043F), + 0x10418 => array(0x10440), + 0x10419 => array(0x10441), + 0x1041A => array(0x10442), + 0x1041B => array(0x10443), + 0x1041C => array(0x10444), + 0x1041D => array(0x10445), + 0x1041E => array(0x10446), + 0x1041F => array(0x10447), + 0x10420 => array(0x10448), + 0x10421 => array(0x10449), + 0x10422 => array(0x1044A), + 0x10423 => array(0x1044B), + 0x10424 => array(0x1044C), + 0x10425 => array(0x1044D), + 0x1D400 => array(0x61), + 0x1D401 => array(0x62), + 0x1D402 => array(0x63), + 0x1D403 => array(0x64), + 0x1D404 => array(0x65), + 0x1D405 => array(0x66), + 0x1D406 => array(0x67), + 0x1D407 => array(0x68), + 0x1D408 => array(0x69), + 0x1D409 => array(0x6A), + 0x1D40A => array(0x6B), + 0x1D40B => array(0x6C), + 0x1D40C => array(0x6D), + 0x1D40D => array(0x6E), + 0x1D40E => array(0x6F), + 0x1D40F => array(0x70), + 0x1D410 => array(0x71), + 0x1D411 => array(0x72), + 0x1D412 => array(0x73), + 0x1D413 => array(0x74), + 0x1D414 => array(0x75), + 0x1D415 => array(0x76), + 0x1D416 => array(0x77), + 0x1D417 => array(0x78), + 0x1D418 => array(0x79), + 0x1D419 => array(0x7A), + 0x1D434 => array(0x61), + 0x1D435 => array(0x62), + 0x1D436 => array(0x63), + 0x1D437 => array(0x64), + 0x1D438 => array(0x65), + 0x1D439 => array(0x66), + 0x1D43A => array(0x67), + 0x1D43B => array(0x68), + 0x1D43C => array(0x69), + 0x1D43D => array(0x6A), + 0x1D43E => array(0x6B), + 0x1D43F => array(0x6C), + 0x1D440 => array(0x6D), + 0x1D441 => array(0x6E), + 0x1D442 => array(0x6F), + 0x1D443 => array(0x70), + 0x1D444 => array(0x71), + 0x1D445 => array(0x72), + 0x1D446 => array(0x73), + 0x1D447 => array(0x74), + 0x1D448 => array(0x75), + 0x1D449 => array(0x76), + 0x1D44A => array(0x77), + 0x1D44B => array(0x78), + 0x1D44C => array(0x79), + 0x1D44D => array(0x7A), + 0x1D468 => array(0x61), + 0x1D469 => array(0x62), + 0x1D46A => array(0x63), + 0x1D46B => array(0x64), + 0x1D46C => array(0x65), + 0x1D46D => array(0x66), + 0x1D46E => array(0x67), + 0x1D46F => array(0x68), + 0x1D470 => array(0x69), + 0x1D471 => array(0x6A), + 0x1D472 => array(0x6B), + 0x1D473 => array(0x6C), + 0x1D474 => array(0x6D), + 0x1D475 => array(0x6E), + 0x1D476 => array(0x6F), + 0x1D477 => array(0x70), + 0x1D478 => array(0x71), + 0x1D479 => array(0x72), + 0x1D47A => array(0x73), + 0x1D47B => array(0x74), + 0x1D47C => array(0x75), + 0x1D47D => array(0x76), + 0x1D47E => array(0x77), + 0x1D47F => array(0x78), + 0x1D480 => array(0x79), + 0x1D481 => array(0x7A), + 0x1D49C => array(0x61), + 0x1D49E => array(0x63), + 0x1D49F => array(0x64), + 0x1D4A2 => array(0x67), + 0x1D4A5 => array(0x6A), + 0x1D4A6 => array(0x6B), + 0x1D4A9 => array(0x6E), + 0x1D4AA => array(0x6F), + 0x1D4AB => array(0x70), + 0x1D4AC => array(0x71), + 0x1D4AE => array(0x73), + 0x1D4AF => array(0x74), + 0x1D4B0 => array(0x75), + 0x1D4B1 => array(0x76), + 0x1D4B2 => array(0x77), + 0x1D4B3 => array(0x78), + 0x1D4B4 => array(0x79), + 0x1D4B5 => array(0x7A), + 0x1D4D0 => array(0x61), + 0x1D4D1 => array(0x62), + 0x1D4D2 => array(0x63), + 0x1D4D3 => array(0x64), + 0x1D4D4 => array(0x65), + 0x1D4D5 => array(0x66), + 0x1D4D6 => array(0x67), + 0x1D4D7 => array(0x68), + 0x1D4D8 => array(0x69), + 0x1D4D9 => array(0x6A), + 0x1D4DA => array(0x6B), + 0x1D4DB => array(0x6C), + 0x1D4DC => array(0x6D), + 0x1D4DD => array(0x6E), + 0x1D4DE => array(0x6F), + 0x1D4DF => array(0x70), + 0x1D4E0 => array(0x71), + 0x1D4E1 => array(0x72), + 0x1D4E2 => array(0x73), + 0x1D4E3 => array(0x74), + 0x1D4E4 => array(0x75), + 0x1D4E5 => array(0x76), + 0x1D4E6 => array(0x77), + 0x1D4E7 => array(0x78), + 0x1D4E8 => array(0x79), + 0x1D4E9 => array(0x7A), + 0x1D504 => array(0x61), + 0x1D505 => array(0x62), + 0x1D507 => array(0x64), + 0x1D508 => array(0x65), + 0x1D509 => array(0x66), + 0x1D50A => array(0x67), + 0x1D50D => array(0x6A), + 0x1D50E => array(0x6B), + 0x1D50F => array(0x6C), + 0x1D510 => array(0x6D), + 0x1D511 => array(0x6E), + 0x1D512 => array(0x6F), + 0x1D513 => array(0x70), + 0x1D514 => array(0x71), + 0x1D516 => array(0x73), + 0x1D517 => array(0x74), + 0x1D518 => array(0x75), + 0x1D519 => array(0x76), + 0x1D51A => array(0x77), + 0x1D51B => array(0x78), + 0x1D51C => array(0x79), + 0x1D538 => array(0x61), + 0x1D539 => array(0x62), + 0x1D53B => array(0x64), + 0x1D53C => array(0x65), + 0x1D53D => array(0x66), + 0x1D53E => array(0x67), + 0x1D540 => array(0x69), + 0x1D541 => array(0x6A), + 0x1D542 => array(0x6B), + 0x1D543 => array(0x6C), + 0x1D544 => array(0x6D), + 0x1D546 => array(0x6F), + 0x1D54A => array(0x73), + 0x1D54B => array(0x74), + 0x1D54C => array(0x75), + 0x1D54D => array(0x76), + 0x1D54E => array(0x77), + 0x1D54F => array(0x78), + 0x1D550 => array(0x79), + 0x1D56C => array(0x61), + 0x1D56D => array(0x62), + 0x1D56E => array(0x63), + 0x1D56F => array(0x64), + 0x1D570 => array(0x65), + 0x1D571 => array(0x66), + 0x1D572 => array(0x67), + 0x1D573 => array(0x68), + 0x1D574 => array(0x69), + 0x1D575 => array(0x6A), + 0x1D576 => array(0x6B), + 0x1D577 => array(0x6C), + 0x1D578 => array(0x6D), + 0x1D579 => array(0x6E), + 0x1D57A => array(0x6F), + 0x1D57B => array(0x70), + 0x1D57C => array(0x71), + 0x1D57D => array(0x72), + 0x1D57E => array(0x73), + 0x1D57F => array(0x74), + 0x1D580 => array(0x75), + 0x1D581 => array(0x76), + 0x1D582 => array(0x77), + 0x1D583 => array(0x78), + 0x1D584 => array(0x79), + 0x1D585 => array(0x7A), + 0x1D5A0 => array(0x61), + 0x1D5A1 => array(0x62), + 0x1D5A2 => array(0x63), + 0x1D5A3 => array(0x64), + 0x1D5A4 => array(0x65), + 0x1D5A5 => array(0x66), + 0x1D5A6 => array(0x67), + 0x1D5A7 => array(0x68), + 0x1D5A8 => array(0x69), + 0x1D5A9 => array(0x6A), + 0x1D5AA => array(0x6B), + 0x1D5AB => array(0x6C), + 0x1D5AC => array(0x6D), + 0x1D5AD => array(0x6E), + 0x1D5AE => array(0x6F), + 0x1D5AF => array(0x70), + 0x1D5B0 => array(0x71), + 0x1D5B1 => array(0x72), + 0x1D5B2 => array(0x73), + 0x1D5B3 => array(0x74), + 0x1D5B4 => array(0x75), + 0x1D5B5 => array(0x76), + 0x1D5B6 => array(0x77), + 0x1D5B7 => array(0x78), + 0x1D5B8 => array(0x79), + 0x1D5B9 => array(0x7A), + 0x1D5D4 => array(0x61), + 0x1D5D5 => array(0x62), + 0x1D5D6 => array(0x63), + 0x1D5D7 => array(0x64), + 0x1D5D8 => array(0x65), + 0x1D5D9 => array(0x66), + 0x1D5DA => array(0x67), + 0x1D5DB => array(0x68), + 0x1D5DC => array(0x69), + 0x1D5DD => array(0x6A), + 0x1D5DE => array(0x6B), + 0x1D5DF => array(0x6C), + 0x1D5E0 => array(0x6D), + 0x1D5E1 => array(0x6E), + 0x1D5E2 => array(0x6F), + 0x1D5E3 => array(0x70), + 0x1D5E4 => array(0x71), + 0x1D5E5 => array(0x72), + 0x1D5E6 => array(0x73), + 0x1D5E7 => array(0x74), + 0x1D5E8 => array(0x75), + 0x1D5E9 => array(0x76), + 0x1D5EA => array(0x77), + 0x1D5EB => array(0x78), + 0x1D5EC => array(0x79), + 0x1D5ED => array(0x7A), + 0x1D608 => array(0x61), + 0x1D609 => array(0x62), + 0x1D60A => array(0x63), + 0x1D60B => array(0x64), + 0x1D60C => array(0x65), + 0x1D60D => array(0x66), + 0x1D60E => array(0x67), + 0x1D60F => array(0x68), + 0x1D610 => array(0x69), + 0x1D611 => array(0x6A), + 0x1D612 => array(0x6B), + 0x1D613 => array(0x6C), + 0x1D614 => array(0x6D), + 0x1D615 => array(0x6E), + 0x1D616 => array(0x6F), + 0x1D617 => array(0x70), + 0x1D618 => array(0x71), + 0x1D619 => array(0x72), + 0x1D61A => array(0x73), + 0x1D61B => array(0x74), + 0x1D61C => array(0x75), + 0x1D61D => array(0x76), + 0x1D61E => array(0x77), + 0x1D61F => array(0x78), + 0x1D620 => array(0x79), + 0x1D621 => array(0x7A), + 0x1D63C => array(0x61), + 0x1D63D => array(0x62), + 0x1D63E => array(0x63), + 0x1D63F => array(0x64), + 0x1D640 => array(0x65), + 0x1D641 => array(0x66), + 0x1D642 => array(0x67), + 0x1D643 => array(0x68), + 0x1D644 => array(0x69), + 0x1D645 => array(0x6A), + 0x1D646 => array(0x6B), + 0x1D647 => array(0x6C), + 0x1D648 => array(0x6D), + 0x1D649 => array(0x6E), + 0x1D64A => array(0x6F), + 0x1D64B => array(0x70), + 0x1D64C => array(0x71), + 0x1D64D => array(0x72), + 0x1D64E => array(0x73), + 0x1D64F => array(0x74), + 0x1D650 => array(0x75), + 0x1D651 => array(0x76), + 0x1D652 => array(0x77), + 0x1D653 => array(0x78), + 0x1D654 => array(0x79), + 0x1D655 => array(0x7A), + 0x1D670 => array(0x61), + 0x1D671 => array(0x62), + 0x1D672 => array(0x63), + 0x1D673 => array(0x64), + 0x1D674 => array(0x65), + 0x1D675 => array(0x66), + 0x1D676 => array(0x67), + 0x1D677 => array(0x68), + 0x1D678 => array(0x69), + 0x1D679 => array(0x6A), + 0x1D67A => array(0x6B), + 0x1D67B => array(0x6C), + 0x1D67C => array(0x6D), + 0x1D67D => array(0x6E), + 0x1D67E => array(0x6F), + 0x1D67F => array(0x70), + 0x1D680 => array(0x71), + 0x1D681 => array(0x72), + 0x1D682 => array(0x73), + 0x1D683 => array(0x74), + 0x1D684 => array(0x75), + 0x1D685 => array(0x76), + 0x1D686 => array(0x77), + 0x1D687 => array(0x78), + 0x1D688 => array(0x79), + 0x1D689 => array(0x7A), + 0x1D6A8 => array(0x3B1), + 0x1D6A9 => array(0x3B2), + 0x1D6AA => array(0x3B3), + 0x1D6AB => array(0x3B4), + 0x1D6AC => array(0x3B5), + 0x1D6AD => array(0x3B6), + 0x1D6AE => array(0x3B7), + 0x1D6AF => array(0x3B8), + 0x1D6B0 => array(0x3B9), + 0x1D6B1 => array(0x3BA), + 0x1D6B2 => array(0x3BB), + 0x1D6B3 => array(0x3BC), + 0x1D6B4 => array(0x3BD), + 0x1D6B5 => array(0x3BE), + 0x1D6B6 => array(0x3BF), + 0x1D6B7 => array(0x3C0), + 0x1D6B8 => array(0x3C1), + 0x1D6B9 => array(0x3B8), + 0x1D6BA => array(0x3C3), + 0x1D6BB => array(0x3C4), + 0x1D6BC => array(0x3C5), + 0x1D6BD => array(0x3C6), + 0x1D6BE => array(0x3C7), + 0x1D6BF => array(0x3C8), + 0x1D6C0 => array(0x3C9), + 0x1D6D3 => array(0x3C3), + 0x1D6E2 => array(0x3B1), + 0x1D6E3 => array(0x3B2), + 0x1D6E4 => array(0x3B3), + 0x1D6E5 => array(0x3B4), + 0x1D6E6 => array(0x3B5), + 0x1D6E7 => array(0x3B6), + 0x1D6E8 => array(0x3B7), + 0x1D6E9 => array(0x3B8), + 0x1D6EA => array(0x3B9), + 0x1D6EB => array(0x3BA), + 0x1D6EC => array(0x3BB), + 0x1D6ED => array(0x3BC), + 0x1D6EE => array(0x3BD), + 0x1D6EF => array(0x3BE), + 0x1D6F0 => array(0x3BF), + 0x1D6F1 => array(0x3C0), + 0x1D6F2 => array(0x3C1), + 0x1D6F3 => array(0x3B8), + 0x1D6F4 => array(0x3C3), + 0x1D6F5 => array(0x3C4), + 0x1D6F6 => array(0x3C5), + 0x1D6F7 => array(0x3C6), + 0x1D6F8 => array(0x3C7), + 0x1D6F9 => array(0x3C8), + 0x1D6FA => array(0x3C9), + 0x1D70D => array(0x3C3), + 0x1D71C => array(0x3B1), + 0x1D71D => array(0x3B2), + 0x1D71E => array(0x3B3), + 0x1D71F => array(0x3B4), + 0x1D720 => array(0x3B5), + 0x1D721 => array(0x3B6), + 0x1D722 => array(0x3B7), + 0x1D723 => array(0x3B8), + 0x1D724 => array(0x3B9), + 0x1D725 => array(0x3BA), + 0x1D726 => array(0x3BB), + 0x1D727 => array(0x3BC), + 0x1D728 => array(0x3BD), + 0x1D729 => array(0x3BE), + 0x1D72A => array(0x3BF), + 0x1D72B => array(0x3C0), + 0x1D72C => array(0x3C1), + 0x1D72D => array(0x3B8), + 0x1D72E => array(0x3C3), + 0x1D72F => array(0x3C4), + 0x1D730 => array(0x3C5), + 0x1D731 => array(0x3C6), + 0x1D732 => array(0x3C7), + 0x1D733 => array(0x3C8), + 0x1D734 => array(0x3C9), + 0x1D747 => array(0x3C3), + 0x1D756 => array(0x3B1), + 0x1D757 => array(0x3B2), + 0x1D758 => array(0x3B3), + 0x1D759 => array(0x3B4), + 0x1D75A => array(0x3B5), + 0x1D75B => array(0x3B6), + 0x1D75C => array(0x3B7), + 0x1D75D => array(0x3B8), + 0x1D75E => array(0x3B9), + 0x1D75F => array(0x3BA), + 0x1D760 => array(0x3BB), + 0x1D761 => array(0x3BC), + 0x1D762 => array(0x3BD), + 0x1D763 => array(0x3BE), + 0x1D764 => array(0x3BF), + 0x1D765 => array(0x3C0), + 0x1D766 => array(0x3C1), + 0x1D767 => array(0x3B8), + 0x1D768 => array(0x3C3), + 0x1D769 => array(0x3C4), + 0x1D76A => array(0x3C5), + 0x1D76B => array(0x3C6), + 0x1D76C => array(0x3C7), + 0x1D76D => array(0x3C8), + 0x1D76E => array(0x3C9), + 0x1D781 => array(0x3C3), + 0x1D790 => array(0x3B1), + 0x1D791 => array(0x3B2), + 0x1D792 => array(0x3B3), + 0x1D793 => array(0x3B4), + 0x1D794 => array(0x3B5), + 0x1D795 => array(0x3B6), + 0x1D796 => array(0x3B7), + 0x1D797 => array(0x3B8), + 0x1D798 => array(0x3B9), + 0x1D799 => array(0x3BA), + 0x1D79A => array(0x3BB), + 0x1D79B => array(0x3BC), + 0x1D79C => array(0x3BD), + 0x1D79D => array(0x3BE), + 0x1D79E => array(0x3BF), + 0x1D79F => array(0x3C0), + 0x1D7A0 => array(0x3C1), + 0x1D7A1 => array(0x3B8), + 0x1D7A2 => array(0x3C3), + 0x1D7A3 => array(0x3C4), + 0x1D7A4 => array(0x3C5), + 0x1D7A5 => array(0x3C6), + 0x1D7A6 => array(0x3C7), + 0x1D7A7 => array(0x3C8), + 0x1D7A8 => array(0x3C9), + 0x1D7BB => array(0x3C3), + 0x3F9 => array(0x3C3), + 0x1D2C => array(0x61), + 0x1D2D => array(0xE6), + 0x1D2E => array(0x62), + 0x1D30 => array(0x64), + 0x1D31 => array(0x65), + 0x1D32 => array(0x1DD), + 0x1D33 => array(0x67), + 0x1D34 => array(0x68), + 0x1D35 => array(0x69), + 0x1D36 => array(0x6A), + 0x1D37 => array(0x6B), + 0x1D38 => array(0x6C), + 0x1D39 => array(0x6D), + 0x1D3A => array(0x6E), + 0x1D3C => array(0x6F), + 0x1D3D => array(0x223), + 0x1D3E => array(0x70), + 0x1D3F => array(0x72), + 0x1D40 => array(0x74), + 0x1D41 => array(0x75), + 0x1D42 => array(0x77), + 0x213B => array(0x66, 0x61, 0x78), + 0x3250 => array(0x70, 0x74, 0x65), + 0x32CC => array(0x68, 0x67), + 0x32CE => array(0x65, 0x76), + 0x32CF => array(0x6C, 0x74, 0x64), + 0x337A => array(0x69, 0x75), + 0x33DE => array(0x76, 0x2215, 0x6D), + 0x33DF => array(0x61, 0x2215, 0x6D) + ); + + /** + * Normalization Combining Classes; Code Points not listed + * got Combining Class 0. + * + * @static + * @var array + * @access private + */ + private static $_np_norm_combcls = array( + 0x334 => 1, + 0x335 => 1, + 0x336 => 1, + 0x337 => 1, + 0x338 => 1, + 0x93C => 7, + 0x9BC => 7, + 0xA3C => 7, + 0xABC => 7, + 0xB3C => 7, + 0xCBC => 7, + 0x1037 => 7, + 0x3099 => 8, + 0x309A => 8, + 0x94D => 9, + 0x9CD => 9, + 0xA4D => 9, + 0xACD => 9, + 0xB4D => 9, + 0xBCD => 9, + 0xC4D => 9, + 0xCCD => 9, + 0xD4D => 9, + 0xDCA => 9, + 0xE3A => 9, + 0xF84 => 9, + 0x1039 => 9, + 0x1714 => 9, + 0x1734 => 9, + 0x17D2 => 9, + 0x5B0 => 10, + 0x5B1 => 11, + 0x5B2 => 12, + 0x5B3 => 13, + 0x5B4 => 14, + 0x5B5 => 15, + 0x5B6 => 16, + 0x5B7 => 17, + 0x5B8 => 18, + 0x5B9 => 19, + 0x5BB => 20, + 0x5Bc => 21, + 0x5BD => 22, + 0x5BF => 23, + 0x5C1 => 24, + 0x5C2 => 25, + 0xFB1E => 26, + 0x64B => 27, + 0x64C => 28, + 0x64D => 29, + 0x64E => 30, + 0x64F => 31, + 0x650 => 32, + 0x651 => 33, + 0x652 => 34, + 0x670 => 35, + 0x711 => 36, + 0xC55 => 84, + 0xC56 => 91, + 0xE38 => 103, + 0xE39 => 103, + 0xE48 => 107, + 0xE49 => 107, + 0xE4A => 107, + 0xE4B => 107, + 0xEB8 => 118, + 0xEB9 => 118, + 0xEC8 => 122, + 0xEC9 => 122, + 0xECA => 122, + 0xECB => 122, + 0xF71 => 129, + 0xF72 => 130, + 0xF7A => 130, + 0xF7B => 130, + 0xF7C => 130, + 0xF7D => 130, + 0xF80 => 130, + 0xF74 => 132, + 0x321 => 202, + 0x322 => 202, + 0x327 => 202, + 0x328 => 202, + 0x31B => 216, + 0xF39 => 216, + 0x1D165 => 216, + 0x1D166 => 216, + 0x1D16E => 216, + 0x1D16F => 216, + 0x1D170 => 216, + 0x1D171 => 216, + 0x1D172 => 216, + 0x302A => 218, + 0x316 => 220, + 0x317 => 220, + 0x318 => 220, + 0x319 => 220, + 0x31C => 220, + 0x31D => 220, + 0x31E => 220, + 0x31F => 220, + 0x320 => 220, + 0x323 => 220, + 0x324 => 220, + 0x325 => 220, + 0x326 => 220, + 0x329 => 220, + 0x32A => 220, + 0x32B => 220, + 0x32C => 220, + 0x32D => 220, + 0x32E => 220, + 0x32F => 220, + 0x330 => 220, + 0x331 => 220, + 0x332 => 220, + 0x333 => 220, + 0x339 => 220, + 0x33A => 220, + 0x33B => 220, + 0x33C => 220, + 0x347 => 220, + 0x348 => 220, + 0x349 => 220, + 0x34D => 220, + 0x34E => 220, + 0x353 => 220, + 0x354 => 220, + 0x355 => 220, + 0x356 => 220, + 0x591 => 220, + 0x596 => 220, + 0x59B => 220, + 0x5A3 => 220, + 0x5A4 => 220, + 0x5A5 => 220, + 0x5A6 => 220, + 0x5A7 => 220, + 0x5AA => 220, + 0x655 => 220, + 0x656 => 220, + 0x6E3 => 220, + 0x6EA => 220, + 0x6ED => 220, + 0x731 => 220, + 0x734 => 220, + 0x737 => 220, + 0x738 => 220, + 0x739 => 220, + 0x73B => 220, + 0x73C => 220, + 0x73E => 220, + 0x742 => 220, + 0x744 => 220, + 0x746 => 220, + 0x748 => 220, + 0x952 => 220, + 0xF18 => 220, + 0xF19 => 220, + 0xF35 => 220, + 0xF37 => 220, + 0xFC6 => 220, + 0x193B => 220, + 0x20E8 => 220, + 0x1D17B => 220, + 0x1D17C => 220, + 0x1D17D => 220, + 0x1D17E => 220, + 0x1D17F => 220, + 0x1D180 => 220, + 0x1D181 => 220, + 0x1D182 => 220, + 0x1D18A => 220, + 0x1D18B => 220, + 0x59A => 222, + 0x5AD => 222, + 0x1929 => 222, + 0x302D => 222, + 0x302E => 224, + 0x302F => 224, + 0x1D16D => 226, + 0x5AE => 228, + 0x18A9 => 228, + 0x302B => 228, + 0x300 => 230, + 0x301 => 230, + 0x302 => 230, + 0x303 => 230, + 0x304 => 230, + 0x305 => 230, + 0x306 => 230, + 0x307 => 230, + 0x308 => 230, + 0x309 => 230, + 0x30A => 230, + 0x30B => 230, + 0x30C => 230, + 0x30D => 230, + 0x30E => 230, + 0x30F => 230, + 0x310 => 230, + 0x311 => 230, + 0x312 => 230, + 0x313 => 230, + 0x314 => 230, + 0x33D => 230, + 0x33E => 230, + 0x33F => 230, + 0x340 => 230, + 0x341 => 230, + 0x342 => 230, + 0x343 => 230, + 0x344 => 230, + 0x346 => 230, + 0x34A => 230, + 0x34B => 230, + 0x34C => 230, + 0x350 => 230, + 0x351 => 230, + 0x352 => 230, + 0x357 => 230, + 0x363 => 230, + 0x364 => 230, + 0x365 => 230, + 0x366 => 230, + 0x367 => 230, + 0x368 => 230, + 0x369 => 230, + 0x36A => 230, + 0x36B => 230, + 0x36C => 230, + 0x36D => 230, + 0x36E => 230, + 0x36F => 230, + 0x483 => 230, + 0x484 => 230, + 0x485 => 230, + 0x486 => 230, + 0x592 => 230, + 0x593 => 230, + 0x594 => 230, + 0x595 => 230, + 0x597 => 230, + 0x598 => 230, + 0x599 => 230, + 0x59C => 230, + 0x59D => 230, + 0x59E => 230, + 0x59F => 230, + 0x5A0 => 230, + 0x5A1 => 230, + 0x5A8 => 230, + 0x5A9 => 230, + 0x5AB => 230, + 0x5AC => 230, + 0x5AF => 230, + 0x5C4 => 230, + 0x610 => 230, + 0x611 => 230, + 0x612 => 230, + 0x613 => 230, + 0x614 => 230, + 0x615 => 230, + 0x653 => 230, + 0x654 => 230, + 0x657 => 230, + 0x658 => 230, + 0x6D6 => 230, + 0x6D7 => 230, + 0x6D8 => 230, + 0x6D9 => 230, + 0x6DA => 230, + 0x6DB => 230, + 0x6DC => 230, + 0x6DF => 230, + 0x6E0 => 230, + 0x6E1 => 230, + 0x6E2 => 230, + 0x6E4 => 230, + 0x6E7 => 230, + 0x6E8 => 230, + 0x6EB => 230, + 0x6EC => 230, + 0x730 => 230, + 0x732 => 230, + 0x733 => 230, + 0x735 => 230, + 0x736 => 230, + 0x73A => 230, + 0x73D => 230, + 0x73F => 230, + 0x740 => 230, + 0x741 => 230, + 0x743 => 230, + 0x745 => 230, + 0x747 => 230, + 0x749 => 230, + 0x74A => 230, + 0x951 => 230, + 0x953 => 230, + 0x954 => 230, + 0xF82 => 230, + 0xF83 => 230, + 0xF86 => 230, + 0xF87 => 230, + 0x170D => 230, + 0x193A => 230, + 0x20D0 => 230, + 0x20D1 => 230, + 0x20D4 => 230, + 0x20D5 => 230, + 0x20D6 => 230, + 0x20D7 => 230, + 0x20DB => 230, + 0x20DC => 230, + 0x20E1 => 230, + 0x20E7 => 230, + 0x20E9 => 230, + 0xFE20 => 230, + 0xFE21 => 230, + 0xFE22 => 230, + 0xFE23 => 230, + 0x1D185 => 230, + 0x1D186 => 230, + 0x1D187 => 230, + 0x1D189 => 230, + 0x1D188 => 230, + 0x1D1AA => 230, + 0x1D1AB => 230, + 0x1D1AC => 230, + 0x1D1AD => 230, + 0x315 => 232, + 0x31A => 232, + 0x302C => 232, + 0x35F => 233, + 0x362 => 233, + 0x35D => 234, + 0x35E => 234, + 0x360 => 234, + 0x361 => 234, + 0x345 => 240 + ); + // }}} + + // {{{ properties + /** + * @var string + * @access private + */ + private $_punycode_prefix = 'xn--'; + + /** + * @access private + */ + private $_invalid_ucs = 0x80000000; + + /** + * @access private + */ + private $_max_ucs = 0x10FFFF; + + /** + * @var int + * @access private + */ + private $_base = 36; + + /** + * @var int + * @access private + */ + private $_tmin = 1; + + /** + * @var int + * @access private + */ + private $_tmax = 26; + + /** + * @var int + * @access private + */ + private $_skew = 38; + + /** + * @var int + * @access private + */ + private $_damp = 700; + + /** + * @var int + * @access private + */ + private $_initial_bias = 72; + + /** + * @var int + * @access private + */ + private $_initial_n = 0x80; + + /** + * @var int + * @access private + */ + private $_slast; + + /** + * @access private + */ + private $_sbase = 0xAC00; + + /** + * @access private + */ + private $_lbase = 0x1100; + + /** + * @access private + */ + private $_vbase = 0x1161; + + /** + * @access private + */ + private $_tbase = 0x11a7; + + /** + * @var int + * @access private + */ + private $_lcount = 19; + + /** + * @var int + * @access private + */ + private $_vcount = 21; + + /** + * @var int + * @access private + */ + private $_tcount = 28; + + /** + * vcount * tcount + * + * @var int + * @access private + */ + private $_ncount = 588; + + /** + * lcount * tcount * vcount + * + * @var int + * @access private + */ + private $_scount = 11172; + + /** + * Default encoding for encode()'s input and decode()'s output is UTF-8; + * Other possible encodings are ucs4_string and ucs4_array + * See {@link setParams()} for how to select these + * + * @var bool + * @access private + */ + private $_api_encoding = 'utf8'; + + /** + * Overlong UTF-8 encodings are forbidden + * + * @var bool + * @access private + */ + private $_allow_overlong = false; + + /** + * Behave strict or not + * + * @var bool + * @access private + */ + private $_strict_mode = false; + // }}} + + + // {{{ constructor + /** + * Constructor + * + * @param array $options + * @access public + * @see setParams() + */ + public function __construct($options = null) + { + $this->_slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount; + + if (is_array($options)) { + $this->setParams($options); + } + } + // }}} + + + /** + * Sets a new option value. Available options and values: + * + * [utf8 - Use either UTF-8 or ISO-8859-1 as input (true for UTF-8, false + * otherwise); The output is always UTF-8] + * [overlong - Unicode does not allow unnecessarily long encodings of chars, + * to allow this, set this parameter to true, else to false; + * default is false.] + * [strict - true: strict mode, good for registration purposes - Causes errors + * on failures; false: loose mode, ideal for "wildlife" applications + * by silently ignoring errors and returning the original input instead] + * + * @param mixed $option Parameter to set (string: single parameter; array of Parameter => Value pairs) + * @param string $value Value to use (if parameter 1 is a string) + * @return boolean true on success, false otherwise + * @access public + */ + public function setParams($option, $value = false) + { + if (!is_array($option)) { + $option = array($option => $value); + } + + foreach ($option as $k => $v) { + switch ($k) { + case 'encoding': + switch ($v) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + $this->_api_encoding = $v; + break; + + default: + throw new Exception('Set Parameter: Unknown parameter '.$v.' for option '.$k); + } + + break; + + case 'overlong': + $this->_allow_overlong = ($v) ? true : false; + break; + + case 'strict': + $this->_strict_mode = ($v) ? true : false; + break; + + default: + return false; + } + } + + return true; + } + + /** + * Encode a given UTF-8 domain name. + * + * @param string $decoded Domain name (UTF-8 or UCS-4) + * [@param string $encoding Desired input encoding, see {@link set_parameter}] + * @return string Encoded Domain name (ACE string) + * @return mixed processed string + * @throws Exception + * @access public + */ + public function encode($decoded, $one_time_encoding = false) + { + // Forcing conversion of input to UCS4 array + // If one time encoding is given, use this, else the objects property + switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + $decoded = $this->_utf8_to_ucs4($decoded); + break; + case 'ucs4_string': + $decoded = $this->_ucs4_string_to_ucs4($decoded); + case 'ucs4_array': // No break; before this line. Catch case, but do nothing + break; + default: + throw new Exception('Unsupported input format'); + } + + // No input, no output, what else did you expect? + if (empty($decoded)) return ''; + + // Anchors for iteration + $last_begin = 0; + // Output string + $output = ''; + + foreach ($decoded as $k => $v) { + // Make sure to use just the plain dot + switch($v) { + case 0x3002: + case 0xFF0E: + case 0xFF61: + $decoded[$k] = 0x2E; + // It's right, no break here + // The codepoints above have to be converted to dots anyway + + // Stumbling across an anchoring character + case 0x2E: + case 0x2F: + case 0x3A: + case 0x3F: + case 0x40: + // Neither email addresses nor URLs allowed in strict mode + if ($this->_strict_mode) { + throw new Exception('Neither email addresses nor URLs are allowed in strict mode.'); + } else { + // Skip first char + if ($k) { + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin))); + } + $output .= chr($decoded[$k]); + } + $last_begin = $k + 1; + } + } + } + // Catch the rest of the string + if ($last_begin) { + $inp_len = sizeof($decoded); + $encoded = ''; + $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + if ($encoded) { + $output .= $encoded; + } else { + $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin))); + } + return $output; + } else { + if ($output = $this->_encode($decoded)) { + return $output; + } else { + return $this->_ucs4_to_utf8($decoded); + } + } + } + + /** + * Decode a given ACE domain name. + * + * @param string $encoded Domain name (ACE string) + * @param string $encoding Desired output encoding, see {@link set_parameter} + * @return string Decoded Domain name (UTF-8 or UCS-4) + * @throws Exception + * @access public + */ + public function decode($input, $one_time_encoding = false) + { + // Optionally set + if ($one_time_encoding) { + switch ($one_time_encoding) { + case 'utf8': + case 'ucs4_string': + case 'ucs4_array': + break; + default: + throw new Exception('Unknown encoding '.$one_time_encoding); + return false; + } + } + // Make sure to drop any newline characters around + $input = trim($input); + + // Negotiate input and try to determine, wether it is a plain string, + // an email address or something like a complete URL + if (strpos($input, '@')) { // Maybe it is an email address + // No no in strict mode + if ($this->_strict_mode) { + throw new Exception('Only simple domain name parts can be handled in strict mode'); + } + list($email_pref, $input) = explode('@', $input, 2); + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $return = $email_pref . '@' . join('.', $arr); + } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters) + // No no in strict mode + if ($this->_strict_mode) { + throw new Exception('Only simple domain name parts can be handled in strict mode'); + } + $parsed = parse_url($input); + if (isset($parsed['host'])) { + $arr = explode('.', $parsed['host']); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $parsed['host'] = join('.', $arr); + if (isset($parsed['scheme'])) { + $parsed['scheme'] .= (strtolower($parsed['scheme']) == 'mailto') ? ':' : '://'; + } + $return = join('', $parsed); + } else { // parse_url seems to have failed, try without it + $arr = explode('.', $input); + foreach ($arr as $k => $v) { + $conv = $this->_decode($v); + if ($conv) $arr[$k] = $conv; + } + $return = join('.', $arr); + } + } else { // Otherwise we consider it being a pure domain name string + $return = $this->_decode($input); + } + // The output is UTF-8 by default, other output formats need conversion here + // If one time encoding is given, use this, else the objects property + switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) { + case 'utf8': + return $return; + break; + case 'ucs4_string': + return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return)); + break; + case 'ucs4_array': + return $this->_utf8_to_ucs4($return); + break; + default: + throw new Exception('Unsupported output format'); + } + } + + + // {{{ private + /** + * The actual encoding algorithm. + * + * @return string + * @throws Exception + * @access private + */ + private function _encode($decoded) + { + // We cannot encode a domain name containing the Punycode prefix + $extract = strlen($this->_punycode_prefix); + $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix); + $check_deco = array_slice($decoded, 0, $extract); + + if ($check_pref == $check_deco) { + throw new Exception('This is already a punycode string'); + } + // We will not try to encode strings consisting of basic code points only + $encodable = false; + foreach ($decoded as $k => $v) { + if ($v > 0x7a) { + $encodable = true; + break; + } + } + if (!$encodable) { + if ($this->_strict_mode) { + throw new Exception('The given string does not contain encodable chars'); + } else { + return false; + } + } + + // Do NAMEPREP + try { + $decoded = $this->_nameprep($decoded); + } catch (Exception $e) { + // hmm, serious - rethrow + throw $e; + } + + $deco_len = count($decoded); + + // Empty array + if (!$deco_len) { + return false; + } + + // How many chars have been consumed + $codecount = 0; + + // Start with the prefix; copy it to output + $encoded = $this->_punycode_prefix; + + $encoded = ''; + // Copy all basic code points to output + for ($i = 0; $i < $deco_len; ++$i) { + $test = $decoded[$i]; + // Will match [0-9a-zA-Z-] + if ((0x2F < $test && $test < 0x40) + || (0x40 < $test && $test < 0x5B) + || (0x60 < $test && $test <= 0x7B) + || (0x2D == $test)) { + $encoded .= chr($decoded[$i]); + $codecount++; + } + } + + // All codepoints were basic ones + if ($codecount == $deco_len) { + return $encoded; + } + + // Start with the prefix; copy it to output + $encoded = $this->_punycode_prefix . $encoded; + + // If we have basic code points in output, add an hyphen to the end + if ($codecount) { + $encoded .= '-'; + } + + // Now find and encode all non-basic code points + $is_first = true; + $cur_code = $this->_initial_n; + $bias = $this->_initial_bias; + $delta = 0; + + while ($codecount < $deco_len) { + // Find the smallest code point >= the current code point and + // remember the last ouccrence of it in the input + for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) { + if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) { + $next_code = $decoded[$i]; + } + } + + $delta += ($next_code - $cur_code) * ($codecount + 1); + $cur_code = $next_code; + + // Scan input again and encode all characters whose code point is $cur_code + for ($i = 0; $i < $deco_len; $i++) { + if ($decoded[$i] < $cur_code) { + $delta++; + } else if ($decoded[$i] == $cur_code) { + for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) { + $t = ($k <= $bias)? + $this->_tmin : + (($k >= $bias + $this->_tmax)? $this->_tmax : $k - $bias); + + if ($q < $t) { + break; + } + + $encoded .= $this->_encodeDigit(ceil($t + (($q - $t) % ($this->_base - $t)))); + $q = ($q - $t) / ($this->_base - $t); + } + + $encoded .= $this->_encodeDigit($q); + $bias = $this->_adapt($delta, $codecount + 1, $is_first); + $codecount++; + $delta = 0; + $is_first = false; + } + } + + $delta++; + $cur_code++; + } + + return $encoded; + } + + /** + * The actual decoding algorithm. + * + * @return string + * @throws Exception + * @access private + */ + private function _decode($encoded) + { + // We do need to find the Punycode prefix + if (!preg_match('!^' . preg_quote($this->_punycode_prefix, '!') . '!', $encoded)) { + return false; + } + + $encode_test = preg_replace('!^' . preg_quote($this->_punycode_prefix, '!') . '!', '', $encoded); + + // If nothing left after removing the prefix, it is hopeless + if (!$encode_test) { + return false; + } + + // Find last occurence of the delimiter + $delim_pos = strrpos($encoded, '-'); + + if ($delim_pos > strlen($this->_punycode_prefix)) { + for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) { + $decoded[] = ord($encoded{$k}); + } + } else { + $decoded = array(); + } + + $deco_len = count($decoded); + $enco_len = strlen($encoded); + + // Wandering through the strings; init + $is_first = true; + $bias = $this->_initial_bias; + $idx = 0; + $char = $this->_initial_n; + + for ($enco_idx = ($delim_pos)? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) { + for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) { + $digit = $this->_decodeDigit($encoded{$enco_idx++}); + $idx += $digit * $w; + + $t = ($k <= $bias) ? + $this->_tmin : + (($k >= $bias + $this->_tmax)? $this->_tmax : ($k - $bias)); + + if ($digit < $t) { + break; + } + + $w = (int)($w * ($this->_base - $t)); + } + + $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first); + $is_first = false; + $char += (int) ($idx / ($deco_len + 1)); + $idx %= ($deco_len + 1); + + if ($deco_len > 0) { + // Make room for the decoded char + for ($i = $deco_len; $i > $idx; $i--) { + $decoded[$i] = $decoded[($i - 1)]; + } + } + + $decoded[$idx++] = $char; + } + + try { + return $this->_ucs4_to_utf8($decoded); + } catch (Exception $e) { + // rethrow + throw $e; + } + } + + /** + * Adapt the bias according to the current code point and position. + * + * @access private + */ + private function _adapt($delta, $npoints, $is_first) + { + $delta = (int) ($is_first ? ($delta / $this->_damp) : ($delta / 2)); + $delta += (int) ($delta / $npoints); + + for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) { + $delta = (int) ($delta / ($this->_base - $this->_tmin)); + } + + return (int) ($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew)); + } + + /** + * Encoding a certain digit. + * + * @access private + */ + private function _encodeDigit($d) + { + return chr($d + 22 + 75 * ($d < 26)); + } + + /** + * Decode a certain digit. + * + * @access private + */ + private function _decodeDigit($cp) + { + $cp = ord($cp); + return ($cp - 48 < 10)? $cp - 22 : (($cp - 65 < 26)? $cp - 65 : (($cp - 97 < 26)? $cp - 97 : $this->_base)); + } + + /** + * Do Nameprep according to RFC3491 and RFC3454. + * + * @param array $input Unicode Characters + * @return string Unicode Characters, Nameprep'd + * @throws Exception + * @access private + */ + private function _nameprep($input) + { + $output = array(); + + // Walking through the input array, performing the required steps on each of + // the input chars and putting the result into the output array + // While mapping required chars we apply the cannonical ordering + + foreach ($input as $v) { + // Map to nothing == skip that code point + if (in_array($v, self::$_np_map_nothing)) { + continue; + } + + // Try to find prohibited input + if (in_array($v, self::$_np_prohibit) || in_array($v, self::$_general_prohibited)) { + throw new Exception('NAMEPREP: Prohibited input U+' . sprintf('%08X', $v)); + } + + foreach (self::$_np_prohibit_ranges as $range) { + if ($range[0] <= $v && $v <= $range[1]) { + throw new Exception('NAMEPREP: Prohibited input U+' . sprintf('%08X', $v)); + } + } + + // Hangul syllable decomposition + if (0xAC00 <= $v && $v <= 0xD7AF) { + foreach ($this->_hangulDecompose($v) as $out) { + $output[] = $out; + } + } else if (isset(self::$_np_replacemaps[$v])) { // There's a decomposition mapping for that code point + foreach ($this->_applyCannonicalOrdering(self::$_np_replacemaps[$v]) as $out) { + $output[] = $out; + } + } else { + $output[] = $v; + } + } + + // Combine code points + + $last_class = 0; + $last_starter = 0; + $out_len = count($output); + + for ($i = 0; $i < $out_len; ++$i) { + $class = $this->_getCombiningClass($output[$i]); + + if ((!$last_class || $last_class != $class) && $class) { + // Try to match + $seq_len = $i - $last_starter; + $out = $this->_combine(array_slice($output, $last_starter, $seq_len)); + + // On match: Replace the last starter with the composed character and remove + // the now redundant non-starter(s) + if ($out) { + $output[$last_starter] = $out; + + if (count($out) != $seq_len) { + for ($j = $i + 1; $j < $out_len; ++$j) { + $output[$j - 1] = $output[$j]; + } + + unset($output[$out_len]); + } + + // Rewind the for loop by one, since there can be more possible compositions + $i--; + $out_len--; + $last_class = ($i == $last_starter)? 0 : $this->_getCombiningClass($output[$i - 1]); + + continue; + } + } + + // The current class is 0 + if (!$class) { + $last_starter = $i; + } + + $last_class = $class; + } + + return $output; + } + + /** + * Decomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul). + * + * @param integer $char 32bit UCS4 code point + * @return array Either Hangul Syllable decomposed or original 32bit + * value as one value array + * @access private + */ + private function _hangulDecompose($char) + { + $sindex = $char - $this->_sbase; + + if ($sindex < 0 || $sindex >= $this->_scount) { + return array($char); + } + + $result = array(); + $T = $this->_tbase + $sindex % $this->_tcount; + $result[] = (int)($this->_lbase + $sindex / $this->_ncount); + $result[] = (int)($this->_vbase + ($sindex % $this->_ncount) / $this->_tcount); + + if ($T != $this->_tbase) { + $result[] = $T; + } + + return $result; + } + + /** + * Ccomposes a Hangul syllable + * (see http://www.unicode.org/unicode/reports/tr15/#Hangul). + * + * @param array $input Decomposed UCS4 sequence + * @return array UCS4 sequence with syllables composed + * @access private + */ + private function _hangulCompose($input) + { + $inp_len = count($input); + + if (!$inp_len) { + return array(); + } + + $result = array(); + $last = $input[0]; + $result[] = $last; // copy first char from input to output + + for ($i = 1; $i < $inp_len; ++$i) { + $char = $input[$i]; + + // Find out, wether two current characters from L and V + $lindex = $last - $this->_lbase; + + if (0 <= $lindex && $lindex < $this->_lcount) { + $vindex = $char - $this->_vbase; + + if (0 <= $vindex && $vindex < $this->_vcount) { + // create syllable of form LV + $last = ($this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount); + $out_off = count($result) - 1; + $result[$out_off] = $last; // reset last + + // discard char + continue; + } + } + + // Find out, wether two current characters are LV and T + $sindex = $last - $this->_sbase; + + if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount) == 0) { + $tindex = $char - $this->_tbase; + + if (0 <= $tindex && $tindex <= $this->_tcount) { + // create syllable of form LVT + $last += $tindex; + $out_off = count($result) - 1; + $result[$out_off] = $last; // reset last + + // discard char + continue; + } + } + + // if neither case was true, just add the character + $last = $char; + $result[] = $char; + } + + return $result; + } + + /** + * Returns the combining class of a certain wide char. + * + * @param integer $char Wide char to check (32bit integer) + * @return integer Combining class if found, else 0 + * @access private + */ + private function _getCombiningClass($char) + { + return isset(self::$_np_norm_combcls[$char])? self::$_np_norm_combcls[$char] : 0; + } + + /** + * Apllies the cannonical ordering of a decomposed UCS4 sequence. + * + * @param array $input Decomposed UCS4 sequence + * @return array Ordered USC4 sequence + * @access private + */ + private function _applyCannonicalOrdering($input) + { + $swap = true; + $size = count($input); + + while ($swap) { + $swap = false; + $last = $this->_getCombiningClass($input[0]); + + for ($i = 0; $i < $size - 1; ++$i) { + $next = $this->_getCombiningClass($input[$i + 1]); + + if ($next != 0 && $last > $next) { + // Move item leftward until it fits + for ($j = $i + 1; $j > 0; --$j) { + if ($this->_getCombiningClass($input[$j - 1]) <= $next) { + break; + } + + $t = $input[$j]; + $input[$j] = $input[$j - 1]; + $input[$j - 1] = $t; + $swap = 1; + } + + // Reentering the loop looking at the old character again + $next = $last; + } + + $last = $next; + } + } + + return $input; + } + + /** + * Do composition of a sequence of starter and non-starter. + * + * @param array $input UCS4 Decomposed sequence + * @return array Ordered USC4 sequence + * @access private + */ + private function _combine($input) + { + $inp_len = count($input); + + // Is it a Hangul syllable? + if (1 != $inp_len) { + $hangul = $this->_hangulCompose($input); + + // This place is probably wrong + if (count($hangul) != $inp_len) { + return $hangul; + } + } + + foreach (self::$_np_replacemaps as $np_src => $np_target) { + if ($np_target[0] != $input[0]) { + continue; + } + + if (count($np_target) != $inp_len) { + continue; + } + + $hit = false; + + foreach ($input as $k2 => $v2) { + if ($v2 == $np_target[$k2]) { + $hit = true; + } else { + $hit = false; + break; + } + } + + if ($hit) { + return $np_src; + } + } + + return false; + } + + /** + * This converts an UTF-8 encoded string to its UCS-4 (array) representation + * By talking about UCS-4 we mean arrays of 32bit integers representing + * each of the "chars". This is due to PHP not being able to handle strings with + * bit depth different from 8. This applies to the reverse method _ucs4_to_utf8(), too. + * The following UTF-8 encodings are supported: + * + * bytes bits representation + * 1 7 0xxxxxxx + * 2 11 110xxxxx 10xxxxxx + * 3 16 1110xxxx 10xxxxxx 10xxxxxx + * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Each x represents a bit that can be used to store character data. + * + * @access private + */ + private function _utf8_to_ucs4($input) + { + $output = array(); + $out_len = 0; + $inp_len = strlen($input); + $mode = 'next'; + $test = 'none'; + for ($k = 0; $k < $inp_len; ++$k) { + $v = ord($input{$k}); // Extract byte from input string + + if ($v < 128) { // We found an ASCII char - put into stirng as is + $output[$out_len] = $v; + ++$out_len; + if ('add' == $mode) { + throw new Exception('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + continue; + } + if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char + $start_byte = $v; + $mode = 'add'; + $test = 'range'; + if ($v >> 5 == 6) { // &110xxxxx 10xxxxx + $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left + $v = ($v - 192) << 6; + } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx + $next_byte = 1; + $v = ($v - 224) << 12; + } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 2; + $v = ($v - 240) << 18; + } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 3; + $v = ($v - 248) << 24; + } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + $next_byte = 4; + $v = ($v - 252) << 30; + } else { + throw new Exception('This might be UTF-8, but I don\'t understand it at byte '.$k); + return false; + } + if ('add' == $mode) { + $output[$out_len] = (int) $v; + ++$out_len; + continue; + } + } + if ('add' == $mode) { + if (!$this->_allow_overlong && $test == 'range') { + $test = 'none'; + if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) { + throw new Exception('Bogus UTF-8 character detected (out of legal range) at byte '.$k); + return false; + } + } + if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx + $v = ($v - 128) << ($next_byte * 6); + $output[($out_len - 1)] += $v; + --$next_byte; + } else { + throw new Exception('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k); + return false; + } + if ($next_byte < 0) { + $mode = 'next'; + } + } + } // for + return $output; + } + + /** + * Convert UCS-4 array into UTF-8 string. + * + * @throws Exception + * @access private + */ + private function _ucs4_to_utf8($input) + { + $output = ''; + + foreach ($input as $v) { + // $v = ord($v); + + if ($v < 128) { + // 7bit are transferred literally + $output .= chr($v); + } else if ($v < 1 << 11) { + // 2 bytes + $output .= chr(192 + ($v >> 6)) + . chr(128 + ($v & 63)); + } else if ($v < 1 << 16) { + // 3 bytes + $output .= chr(224 + ($v >> 12)) + . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } else if ($v < 1 << 21) { + // 4 bytes + $output .= chr(240 + ($v >> 18)) + . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } else if ($v < 1 << 26) { + // 5 bytes + $output .= chr(248 + ($v >> 24)) + . chr(128 + (($v >> 18) & 63)) + . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } else if ($v < 1 << 31) { + // 6 bytes + $output .= chr(252 + ($v >> 30)) + . chr(128 + (($v >> 24) & 63)) + . chr(128 + (($v >> 18) & 63)) + . chr(128 + (($v >> 12) & 63)) + . chr(128 + (($v >> 6) & 63)) + . chr(128 + ($v & 63)); + } else { + throw new Exception('Conversion from UCS-4 to UTF-8 failed: malformed input at byte ' . $k); + } + } + + return $output; + } + + /** + * Convert UCS-4 array into UCS-4 string + * + * @throws Exception + * @access private + */ + private function _ucs4_to_ucs4_string($input) + { + $output = ''; + // Take array values and split output to 4 bytes per value + // The bit mask is 255, which reads &11111111 + foreach ($input as $v) { + $output .= ($v & (255 << 24) >> 24) . ($v & (255 << 16) >> 16) . ($v & (255 << 8) >> 8) . ($v & 255); + } + return $output; + } + + /** + * Convert UCS-4 strin into UCS-4 garray + * + * @throws Exception + * @access private + */ + private function _ucs4_string_to_ucs4($input) + { + $output = array(); + + $inp_len = strlen($input); + // Input length must be dividable by 4 + if ($inp_len % 4) { + throw new Exception('Input UCS4 string is broken'); + return false; + } + + // Empty input - return empty output + if (!$inp_len) return $output; + + for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) { + // Increment output position every 4 input bytes + if (!$i % 4) { + $out_len++; + $output[$out_len] = 0; + } + $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) ); + } + return $output; + } + + /** + * Echo hex representation of UCS4 sequence. + * + * @param array $input UCS4 sequence + * @param boolean $include_bit Include bitmask in output + * @return void + * @static + * @access private + */ + private static function _showHex($input, $include_bit = false) + { + foreach ($input as $k => $v) { + echo '[', $k, '] => ', sprintf('%X', $v); + + if ($include_bit) { + echo ' (', Net_IDNA::_showBitmask($v), ')'; + } + + echo "\n"; + } + } + + /** + * Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits) + * Output width is automagically determined + * + * @static + * @access private + */ + private static function _showBitmask($octet) + { + if ($octet >= (1 << 16)) { + $w = 31; + } else if ($octet >= (1 << 8)) { + $w = 15; + } else { + $w = 7; + } + + $return = ''; + + for ($i = $w; $i > -1; $i--) { + $return .= ($octet & (1 << $i))? 1 : '0'; + } + + return $return; + } + // }}}} +} + +?> diff --git a/gulliver/thirdparty/pear/Net/IPv4.php b/gulliver/thirdparty/pear/Net/IPv4.php new file mode 100644 index 000000000..68de17e4d --- /dev/null +++ b/gulliver/thirdparty/pear/Net/IPv4.php @@ -0,0 +1,458 @@ + +* @author Marco Kaiser +* @author Florian Anderiasch +* @copyright 1997-2005 The PHP Group +* @license http://www.php.net/license/3_01.txt PHP License 3.01 +* @version CVS: $Id: IPv4.php,v 1.11 2005/11/29 12:56:35 fa Exp $ +* @link http://pear.php.net/package/Net_IPv4 +*/ + +require_once 'PEAR.php'; + +// {{{ GLOBALS +/** + * Map of bitmasks to subnets + * + * This array contains every valid netmask. The index of the dot quad + * netmask value is the corresponding CIDR notation (bitmask). + * + * @global array $GLOBALS['Net_IPv4_Netmask_Map'] + */ +$GLOBALS['Net_IPv4_Netmask_Map'] = array( + 0 => "0.0.0.0", + 1 => "128.0.0.0", + 2 => "192.0.0.0", + 3 => "224.0.0.0", + 4 => "240.0.0.0", + 5 => "248.0.0.0", + 6 => "252.0.0.0", + 7 => "254.0.0.0", + 8 => "255.0.0.0", + 9 => "255.128.0.0", + 10 => "255.192.0.0", + 11 => "255.224.0.0", + 12 => "255.240.0.0", + 13 => "255.248.0.0", + 14 => "255.252.0.0", + 15 => "255.254.0.0", + 16 => "255.255.0.0", + 17 => "255.255.128.0", + 18 => "255.255.192.0", + 19 => "255.255.224.0", + 20 => "255.255.240.0", + 21 => "255.255.248.0", + 22 => "255.255.252.0", + 23 => "255.255.254.0", + 24 => "255.255.255.0", + 25 => "255.255.255.128", + 26 => "255.255.255.192", + 27 => "255.255.255.224", + 28 => "255.255.255.240", + 29 => "255.255.255.248", + 30 => "255.255.255.252", + 31 => "255.255.255.254", + 32 => "255.255.255.255" + ); +// }}} +// {{{ Net_IPv4 + +/** +* Class to provide IPv4 calculations +* +* Provides methods for validating IP addresses, calculating netmasks, +* broadcast addresses, network addresses, conversion routines, etc. +* +* @category Net +* @package Net_IPv4 +* @author Eric Kilfoil +* @author Marco Kaiser +* @author Florian Anderiasch +* @copyright 1997-2005 The PHP Group +* @license http://www.php.net/license/3_01.txt PHP License 3.01 +* @version CVS: 1.3.0 +* @link http://pear.php.net/package/Net_IPv4 +* @access public +*/ +class Net_IPv4 +{ + // {{{ properties + var $ip = ""; + var $bitmask = false; + var $netmask = ""; + var $network = ""; + var $broadcast = ""; + var $long = 0; + + // }}} + // {{{ validateIP() + + /** + * Validate the syntax of the given IP adress + * + * Using the PHP long2ip() and ip2long() functions, convert the IP + * address from a string to a long and back. If the original still + * matches the converted IP address, it's a valid address. This + * function does not allow for IP addresses to be formatted as long + * integers. + * + * @param string $ip IP address in the format x.x.x.x + * @return bool true if syntax is valid, otherwise false + */ + function validateIP($ip) + { + if ($ip == long2ip(ip2long($ip))) { + return true; + } else { + return false; + } + } + + // }}} + // {{{ check_ip() + + /** + * Validate the syntax of the given IP address (compatibility) + * + * This function is identical to Net_IPv4::validateIP(). It is included + * merely for compatibility reasons. + * + * @param string $ip IP address + * @return bool true if syntax is valid, otherwise false + */ + function check_ip($ip) + { + return $this->validateIP($ip); + } + + // }}} + // {{{ validateNetmask() + + /** + * Validate the syntax of a four octet netmask + * + * There are 33 valid netmask values. This function will compare the + * string passed as $netmask to the predefined 33 values and return + * true or false. This is most likely much faster than performing the + * calculation to determine the validity of the netmask. + * + * @param string $netmask Netmask + * @return bool true if syntax is valid, otherwise false + */ + function validateNetmask($netmask) + { + if (! in_array($netmask, $GLOBALS['Net_IPv4_Netmask_Map'])) { + return false; + } + return true; + } + + // }}} + // {{{ parseAddress() + + /** + * Parse a formatted IP address + * + * Given a network qualified IP address, attempt to parse out the parts + * and calculate qualities of the address. + * + * The following formats are possible: + * + * [dot quad ip]/[ bitmask ] + * [dot quad ip]/[ dot quad netmask ] + * [dot quad ip]/[ hex string netmask ] + * + * The first would be [IP Address]/[BitMask]: + * 192.168.0.0/16 + * + * The second would be [IP Address] [Subnet Mask in dot quad notation]: + * 192.168.0.0/255.255.0.0 + * + * The third would be [IP Address] [Subnet Mask as Hex string] + * 192.168.0.0/ffff0000 + * + * Usage: + * + * $cidr = '192.168.0.50/16'; + * $net = Net_IPv4::parseAddress($cidr); + * echo $net->network; // 192.168.0.0 + * echo $net->ip; // 192.168.0.50 + * echo $net->broadcast; // 192.168.255.255 + * echo $net->bitmask; // 16 + * echo $net->long; // 3232235520 (long/double version of 192.168.0.50) + * echo $net->netmask; // 255.255.0.0 + * + * @param string $ip IP address netmask combination + * @return object true if syntax is valid, otherwise false + */ + function parseAddress($address) + { + $myself = new Net_IPv4; + if (strchr($address, "/")) { + $parts = explode("/", $address); + if (! $myself->validateIP($parts[0])) { + return PEAR::raiseError("invalid IP address"); + } + $myself->ip = $parts[0]; + + // Check the style of netmask that was entered + /* + * a hexadecimal string was entered + */ + if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$", $parts[1], $regs)) { + // hexadecimal string + $myself->netmask = hexdec($regs[1]) . "." . hexdec($regs[2]) . "." . + hexdec($regs[3]) . "." . hexdec($regs[4]); + + /* + * a standard dot quad netmask was entered. + */ + } else if (strchr($parts[1], ".")) { + if (! $myself->validateNetmask($parts[1])) { + return PEAR::raiseError("invalid netmask value"); + } + $myself->netmask = $parts[1]; + + /* + * a CIDR bitmask type was entered + */ + } else if ($parts[1] >= 0 && $parts[1] <= 32) { + // bitmask was entered + $myself->bitmask = $parts[1]; + + /* + * Some unknown format of netmask was entered + */ + } else { + return PEAR::raiseError("invalid netmask value"); + } + $myself->calculate(); + return $myself; + } else if ($myself->validateIP($address)) { + $myself->ip = $address; + return $myself; + } else { + return PEAR::raiseError("invalid IP address"); + } + } + + // }}} + // {{{ calculate() + + /** + * Calculates network information based on an IP address and netmask. + * + * Fully populates the object properties based on the IP address and + * netmask/bitmask properties. Once these two fields are populated, + * calculate() will perform calculations to determine the network and + * broadcast address of the network. + * + * @return mixed true if no errors occured, otherwise PEAR_Error object + */ + function calculate() + { + $validNM = $GLOBALS['Net_IPv4_Netmask_Map']; + + if (! is_a($this, "net_ipv4")) { + $myself = new Net_IPv4; + return PEAR::raiseError("cannot calculate on uninstantiated Net_IPv4 class"); + } + + /* Find out if we were given an ip address in dot quad notation or + * a network long ip address. Whichever was given, populate the + * other field + */ + if (strlen($this->ip)) { + if (! $this->validateIP($this->ip)) { + return PEAR::raiseError("invalid IP address"); + } + $this->long = $this->ip2double($this->ip); + } else if (is_numeric($this->long)) { + $this->ip = long2ip($this->long); + } else { + return PEAR::raiseError("ip address not specified"); + } + + /* + * Check to see if we were supplied with a bitmask or a netmask. + * Populate the other field as needed. + */ + if (strlen($this->bitmask)) { + $this->netmask = $validNM[$this->bitmask]; + } else if (strlen($this->netmask)) { + $validNM_rev = array_flip($validNM); + $this->bitmask = $validNM_rev[$this->netmask]; + } else { + return PEAR::raiseError("netmask or bitmask are required for calculation"); + } + $this->network = long2ip(ip2long($this->ip) & ip2long($this->netmask)); + $this->broadcast = long2ip(ip2long($this->ip) | + (ip2long($this->netmask) ^ ip2long("255.255.255.255"))); + return true; + } + + // }}} + // {{{ getNetmask() + + function getNetmask($length) + { + if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $length))) { + $mask = $ipobj->netmask; + unset($ipobj); + return $mask; + } + return false; + } + + // }}} + // {{{ getNetLength() + + function getNetLength($netmask) + { + if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $netmask))) { + $bitmask = $ipobj->bitmask; + unset($ipobj); + return $bitmask; + } + return false; + } + + // }}} + // {{{ getSubnet() + + function getSubnet($ip, $netmask) + { + if (! PEAR::isError($ipobj = Net_IPv4::parseAddress($ip . "/" . $netmask))) { + $net = $ipobj->network; + unset($ipobj); + return $net; + } + return false; + } + + // }}} + // {{{ inSameSubnet() + + function inSameSubnet($ip1, $ip2) + { + if (! is_object($ip1) || strcasecmp(get_class($ip1), 'net_ipv4') <> 0) { + $ipobj1 = Net_IPv4::parseAddress($ip1); + if (PEAR::isError($ipobj)) { + return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object"); + } + } + if (! is_object($ip2) || strcasecmp(get_class($ip2), 'net_ipv4') <> 0) { + $ipobj2 = Net_IPv4::parseAddress($ip2); + if (PEAR::isError($ipobj)) { + return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object"); + } + } + if ($ipobj1->network == $ipobj2->network && + $ipobj1->bitmask == $ipobj2->bitmask) { + return true; + } + return false; + } + + // }}} + // {{{ atoh() + + /** + * Converts a dot-quad formatted IP address into a hexadecimal string + * @param string $addr IP-adress in dot-quad format + * @return mixed false if invalid IP and hexadecimal representation as string if valid + */ + function atoh($addr) + { + if (! Net_IPv4::validateIP($addr)) { + return false; + } + $ap = explode(".", $addr); + return sprintf("%02x%02x%02x%02x", $ap[0], $ap[1], $ap[2], $ap[3]); + } + + // }}} + // {{{ htoa() + + /** + * Converts a hexadecimal string into a dot-quad formatted IP address + * @param string $addr IP-adress in hexadecimal format + * @return mixed false if invalid IP and dot-quad formatted IP as string if valid + */ + function htoa($addr) + { + if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$", + $addr, $regs)) { + return hexdec($regs[1]) . "." . hexdec($regs[2]) . "." . + hexdec($regs[3]) . "." . hexdec($regs[4]); + } + return false; + } + + // }}} + // {{{ ip2double() + + /** + * Converts an IP address to a PHP double. Better than ip2long because + * a long in PHP is a signed integer. + * @param string $ip dot-quad formatted IP adress + * @return float IP adress as double - positive value unlike ip2long + */ + function ip2double($ip) + { + return (double)(sprintf("%u", ip2long($ip))); + } + + // }}} + // {{{ ipInNetwork() + + /** + * Determines whether or not the supplied IP is within the supplied network. + * + * This function determines whether an IP address is within a network. + * The IP address ($ip) must be supplied in dot-quad format, and the + * network ($network) may be either a string containing a CIDR + * formatted network definition, or a Net_IPv4 object. + * + * @param string $ip A dot quad representation of an IP address + * @param string $network A string representing the network in CIDR format or a Net_IPv4 object. + * @return bool true if the IP address exists within the network + */ + function ipInNetwork($ip, $network) + { + if (! is_object($network) || strcasecmp(get_class($network), 'net_ipv4') <> 0) { + $network = Net_IPv4::parseAddress($network); + } + + $net = Net_IPv4::ip2double($network->network); + $bcast = Net_IPv4::ip2double($network->broadcast); + $ip = Net_IPv4::ip2double($ip); + unset($network); + if ($ip >= $net && $ip <= $bcast) { + return true; + } + return false; + } + + // }}} +} + +// }}} + +/* + * vim: sts=4 ts=4 sw=4 cindent fdm=marker + */ +?> diff --git a/gulliver/thirdparty/pear/Net/IPv6.php b/gulliver/thirdparty/pear/Net/IPv6.php new file mode 100644 index 000000000..296abe668 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/IPv6.php @@ -0,0 +1,218 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: IPv6.php,v 1.12 2005/09/01 12:42:00 alexmerz Exp $ + +/** +* Class to validate and to work with IPv6 +* +* @author Alexander Merz +* @author elfrink at introweb dot nl +* @package Net_IPv6 +* @version $Id: IPv6.php,v 1.12 2005/09/01 12:42:00 alexmerz Exp $ +* @access public +*/ +class Net_IPv6 { + + // {{{ Uncompress() + + /** + * Uncompresses an IPv6 adress + * + * RFC 2373 allows you to compress zeros in an adress to '::'. This + * function expects an valid IPv6 adress and expands the '::' to + * the required zeros. + * + * Example: FF01::101 -> FF01:0:0:0:0:0:0:101 + * ::1 -> 0:0:0:0:0:0:0:1 + * + * @access public + * @see Compress() + * @static + * @param string $ip a valid IPv6-adress (hex format) + * @return string the uncompressed IPv6-adress (hex format) + */ + function Uncompress($ip) { + $uip = $ip; + $c1 = -1; + $c2 = -1; + if (false !== strpos($ip, '::') ) { + list($ip1, $ip2) = explode('::', $ip); + if(""==$ip1) { + $c1 = -1; + } else { + $pos = 0; + if(0 < ($pos = substr_count($ip1, ':'))) { + $c1 = $pos; + } else { + $c1 = 0; + } + } + if(""==$ip2) { + $c2 = -1; + } else { + $pos = 0; + if(0 < ($pos = substr_count($ip2, ':'))) { + $c2 = $pos; + } else { + $c2 = 0; + } + } + if(strstr($ip2, '.')) { + $c2++; + } + if(-1 == $c1 && -1 == $c2) { // :: + $uip = "0:0:0:0:0:0:0:0"; + } else if(-1==$c1) { // ::xxx + $fill = str_repeat('0:', 7-$c2); + $uip = str_replace('::', $fill, $uip); + } else if(-1==$c2) { // xxx:: + $fill = str_repeat(':0', 7-$c1); + $uip = str_replace('::', $fill, $uip); + } else { // xxx::xxx + $fill = str_repeat(':0:', 6-$c2-$c1); + $uip = str_replace('::', $fill, $uip); + $uip = str_replace('::', ':', $uip); + } + } + return $uip; + } + + // }}} + // {{{ Compress() + + /** + * Compresses an IPv6 adress + * + * RFC 2373 allows you to compress zeros in an adress to '::'. This + * function expects an valid IPv6 adress and compresses successive zeros + * to '::' + * + * Example: FF01:0:0:0:0:0:0:101 -> FF01::101 + * 0:0:0:0:0:0:0:1 -> ::1 + * + * @access public + * @see Uncompress() + * @static + * @param string $ip a valid IPv6-adress (hex format) + * @return string the compressed IPv6-adress (hex format) + * @author elfrink at introweb dot nl + */ + function Compress($ip) { + $cip = $ip; + + if (!strstr($ip, '::')) { + $ipp = explode(':',$ip); + for($i=0; $i0) { + $match = ''; + foreach($zeros[0] as $zero) { + if (strlen($zero) > strlen($match)) + $match = $zero; + } + $cip = preg_replace('/' . $match . '/', ':', $cip, 1); + } + $cip = preg_replace('/((^:)|(:$))/', '' ,$cip); + $cip = preg_replace('/((^:)|(:$))/', '::' ,$cip); + } + return $cip; + } + + // }}} + // {{{ SplitV64() + + /** + * Splits an IPv6 adress into the IPv6 and a possible IPv4 part + * + * RFC 2373 allows you to note the last two parts of an IPv6 adress as + * an IPv4 compatible adress + * + * Example: 0:0:0:0:0:0:13.1.68.3 + * 0:0:0:0:0:FFFF:129.144.52.38 + * + * @access public + * @static + * @param string $ip a valid IPv6-adress (hex format) + * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format) + */ + function SplitV64($ip) { + $ip = Net_IPv6::Uncompress($ip); + if (strstr($ip, '.')) { + $pos = strrpos($ip, ':'); + $ip{$pos} = '_'; + $ipPart = explode('_', $ip); + return $ipPart; + } else { + return array($ip, ""); + } + } + + // }}} + // {{{ checkIPv6 + + /** + * Checks an IPv6 adress + * + * Checks if the given IP is IPv6-compatible + * + * @access public + * @static + * @param string $ip a valid IPv6-adress + * @return boolean true if $ip is an IPv6 adress + */ + function checkIPv6($ip) { + + $ipPart = Net_IPv6::SplitV64($ip); + $count = 0; + if (!empty($ipPart[0])) { + $ipv6 =explode(':', $ipPart[0]); + for ($i = 0; $i < count($ipv6); $i++) { + $dec = hexdec($ipv6[$i]); + $hex = strtoupper(preg_replace("/^[0]{1,3}(.*[0-9a-fA-F])$/", "\\1", $ipv6[$i])); + if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex == strtoupper(dechex($dec))) { + $count++; + } + } + if (8 == $count) { + return true; + } elseif (6 == $count and !empty($ipPart[1])) { + $ipv4 = explode('.',$ipPart[1]); + $count = 0; + for ($i = 0; $i < count($ipv4); $i++) { + if ($ipv4[$i] >= 0 && (integer)$ipv4[$i] <= 255 && preg_match("/^\d{1,3}$/", $ipv4[$i])) { + $count++; + } + } + if (4 == $count) { + return true; + } + } else { + return false; + } + + } else { + return false; + } + } + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Net/JSON.php b/gulliver/thirdparty/pear/Net/JSON.php new file mode 100644 index 000000000..71dcdea5d --- /dev/null +++ b/gulliver/thirdparty/pear/Net/JSON.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/gulliver/thirdparty/pear/Net/LDAP.php b/gulliver/thirdparty/pear/Net/LDAP.php new file mode 100644 index 000000000..7a8f43f21 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP.php @@ -0,0 +1,1065 @@ + '', + 'host' => 'localhost', + 'password' => '', + 'tls' => false, + 'base' => '', + 'port' => 389, + 'version' => 3, + 'options' => array(), + 'filter' => '(objectClass=*)', + 'scope' => 'sub'); + + /** + * LDAP resource link. + * + * @access private + * @var resource + */ + var $_link; + + /** + * Net_LDAP Release Version + * + * @access private + * @var string + */ + var $_version = "0.6.6"; + + /** + * Net_LDAP_Schema object + * + * @access private + * @var object Net_LDAP_Schema + */ + var $_schema = null; + + /** + * Cache for attribute encoding checks + * + * @access private + * @var array Hash with attribute names as key and boolean value + * to determine whether they should be utf8 encoded or not. + */ + var $_schemaAttrs = array(); + + /** + * Net_LDAP constructor + * + * Sets the config array + * + * @access protected + * @param array Configuration array + * @return void + * @see $_config + */ + function Net_LDAP($_config = array()) + { + $this->PEAR('Net_LDAP_Error'); + + foreach ($_config as $k => $v) { + $this->_config[$k] = $v; + } + } + + /** + * Creates the initial ldap-object + * + * Static function that returns either an error object or the new Net_LDAP object. + * Something like a factory. Takes a config array with the needed parameters. + * + * @access public + * @param array Configuration array + * @return mixed object Net_LDAP_Error or Net_LDAP + * @see $_config + */ + function &connect($config = array()) + { + if (!function_exists('ldap_connect')){ + return Net_LDAP::raiseError("It seems that you do not have the ldap-extension installed. Please install it before using this package."); + } + @$obj =& new Net_LDAP($config); + $err = $obj->bind(); + + if (Net_LDAP::isError($err)) { + return $err; + } + return $obj; + } + + /** + * Bind to the ldap-server + * + * The function may be used if you do not create the object using Net_LDAP::connect. + * + * @access public + * @param array Configuration array + * @return mixed Net_LDAP_Error or true + * @see $_config + */ + function bind($config = array()) + { + foreach ($config as $k => $v) { + $this->_config[$k] = $v; + } + + if ($this->_config['host']) { + $this->_link = @ldap_connect($this->_config['host'], $this->_config['port']); + } else { + return $this->raiseError("Host not defined in config. {$this->_config['host']}"); + } + + if (!$this->_link) { + // there is no good errorcode for this one! I chose 52. + return $this->raiseError("Could not connect to server. ldap_connect failed.", 52); + } + // You must set the version and start tls BEFORE binding! + + if ($this->_config['version'] != 2 && Net_LDAP::isError($msg = $this->setLDAPVersion())) { + return $msg; + } + + if ($this->_config['tls'] && Net_LDAP::isError($msg = $this->startTLS())) { + return $msg; + } + + if (isset($this->_config['options']) && + is_array($this->_config['options']) && + count($this->_config['options'])) + { + foreach ($this->_config['options'] as $opt => $val) { + $err = $this->setOption($opt, $val); + if (Net_LDAP::isError($err)) { + return $err; + } + } + } + + if (isset($this->_config['dn']) && isset($this->_config['password'])) { + $bind = @ldap_bind($this->_link, $this->_config['dn'], $this->_config['password']); + } else { + $bind = @ldap_bind($this->_link); + } + + if (!$bind) { + return $this->raiseError("Bind failed " . @ldap_error($this->_link), @ldap_errno($this->_link)); + } + + return true; + } + + /** + * ReBind to the ldap-server using another dn and password + * + * The function may be used if you do not create the object using Net_LDAP::connect. + * + * @access public + * @param string $dn - the DN to bind as. + * string $password - the bassword to use. + * @return mixed Net_LDAP_Error or true + * @see $_config + */ + + function reBind ($dn = null, $password = null) + { + + if ($dn && $password ) { + $bind = @ldap_bind($this->_link, $dn, $password); + } else { + $bind = @ldap_bind($this->_link); + } + + if (!$bind) { + return $this->raiseError("Bind failed " . @ldap_error($this->_link), @ldap_errno($this->_link)); + } + return true; + } + + /** + * Starts an encrypted session + * + * @access public + * @return mixed True or Net_LDAP_Error + */ + function startTLS() + { + if (!@ldap_start_tls($this->_link)) { + return $this->raiseError("TLS not started. Error:" . @ldap_error($this->_link), @ldap_errno($this->_link)); + } + return true; + } + + /** + * alias function of startTLS() for perl-ldap interface + * + * @see startTLS() + */ + function start_tls() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'startTLS' ), $args); + } + + /** + * Close LDAP connection. + * + * Closes the connection. Use this when the session is over. + * + * @return void + */ + function done() + { + $this->_Net_LDAP(); + } + + /** + * Destructor + * + * @access private + */ + function _Net_LDAP() + { + @ldap_close($this->_link); + } + + /** + * Add a new entryobject to a directory. + * + * Use add to add a new Net_LDAP_Entry object to the directory. + * + * @param object Net_LDAP_Entry + * @return mixed Net_LDAP_Error or true + */ + function add($entry) + { + if (@ldap_add($this->_link, $entry->dn(), $entry->attributes())) { + return true; + } else { + return $this->raiseError("Could not add entry " . $entry->dn() . " " . @ldap_error($this->_link), + @ldap_errno($this->_link)); + } + } + + /** + * Delete an entry from the directory + * + * The object may either be a string representing the dn or a Net_LDAP_Entry object. + * The param array may contain a boolean value named recursive. When set, all subentries + * of the Entry will be deleted as well + * + * @access public + * @param mixed string or Net_LDAP_Entry + * @param array + * @return mixed Net_LDAP_Error or true + */ + function delete($dn, $param = array()) + { + if (is_object($dn) && strtolower(get_class($dn)) == 'net_ldap_entry') { + $dn = $dn->dn(); + } else { + if (!is_string($dn)) { + // this is what the server would say: invalid_dn_syntax. + return $this->raiseError("$dn not a string nor an entryobject!", 34); + } + } + + if ($param['recursive'] ) { + $searchresult = @ldap_list($this->_link, $dn, '(objectClass=*)', array()); + + if ($searchresult) { + $entries = @ldap_get_entries($this->_link, $searchresult); + + for ($i=0; $i<$entries['count']; $i++) { + $result = $this->delete($entries[$i]['dn'], array('recursive' => true)); + if (!$result) { + $errno = @ldap_errno($this->_link); + return $this->raiseMessage ("Net_LDAP::delete: " . $this->errorMessage($errno), $errno); + } + if(PEAR::isError($result)){ + return $result; + } + } + } + } + if (!@ldap_delete($this->_link, $dn)) { + $error = ldap_errno($this->_link ); + if ($error == 66) { + /* entry has subentries */ + return $this->raiseError('Net_LDAP::delete: Cound not delete entry ' . $dn . + ' because of subentries. Use the recursive param to delete them.'); + } else { + return $this->raiseError("Net_LDAP::delete: Could not delete entry " . $dn ." because: ". + $this->errorMessage($error), $error); + } + } + return true; + } + + /** + * Modify an ldapentry + * + * This is taken from the perlpod of net::ldap, and explains things quite nicely. + * modify ( DN, OPTIONS ) + * Modify the contents of DN on the server. DN May be a + * string or a Net::LDAP::Entry object. + * + * dn This option is here for compatibility only, and + * may be removed in future. Previous releases did + * not take the DN argument which replaces this + * option. + * + * add The add option should be a reference to a HASH. + * The values of the HASH are the attributes to add, + * and the values may be a string or a reference to a + * list of values. + * + * delete + * A reference to an ARRAY of attributes to delete. + * TODO: This does not support deleting one or two values yet - use + * replace. + * + * replace + * The option takes a argument in the same + * form as add, but will cause any existing + * attributes with the same name to be replaced. If + * the value for any attribute in the årray is a ref­ + * erence to an empty string the all instances of the + * attribute will be deleted. + * + * changes + * This is an alternative to add, delete and replace + * where the whole operation can be given in a single + * argument. The argument should be a array + * + * Values in the ARRAY are used in pairs, the first + * is the operation add, delete or replace and the + * second is a reference to an ARRAY of attribute + * values. + * + * The attribute value list is also used in pairs. + * The first value in each pair is the attribute name + * and the second is a reference to a list of values. + * + * Example: + * $ldap->modify ( $dn, array (changes => array( + * 'delete' => array('faxNumber' => ''), + * 'add' => array('sn' => 'Barr'), + * 'replace' => array(email => 'tarjei@nu.no')))); + * + * @access public + * @param string + * @param array + * @return mixed Net_LDAP_Error or true + */ + function modify($dn , $params = array()) + { + if (is_object($dn)) { + $dn = $dn->dn(); + } + // since $params['dn'] is not used in net::ldap now: + if (isset($params['dn'])) { + return $this->raiseError("This feature will not be implemented!"); + } + // new code from rafael at krysciak dot de + if(array_key_exists('changes', $params)) { + $_params = $params; + } else { + $_params['changes'] = $params; + } + if (is_array($_params['changes'])) { + foreach($_params['changes'] AS $option => $atrr) { + switch($option) { + case 'add': + $command = $dn_exists ? 'ldap_mod_add':'ldap_add'; + break; + case 'replace': + $command = 'ldap_mod_replace'; + break; + case 'delete': + $command = 'ldap_mod_del'; + // to delete an attribute with a specific value you + // need a hash array('attr_name' => array('attr_value_1', ... ,'attr_value_n')) + // the hash array('attr_name' => 'attr_value') will be converted + // automatically to array('attr_name' => array('attr_value')) + foreach($atrr AS $atrr_field => $atrr_value) { + if(!is_array($atrr_value)) { + $atrr[$atrr_field] = array($atrr_value); + } + } + break; + default: + return $this->raiseError("Net_LDAP::modify: not supported option " . $option); + break; + } // end switch($option) { + + if(!@call_user_func($command, $this->_link, $dn, $atrr)) { + return $this->raiseError("Net_LDAP::modify: $dn not modified because:" . ldap_error($this->_link), ldap_errno($this->_link)); + } + } // end foreach($_params['changes'] AS $option => $atrr) { + } // end if (is_array($_params['changes'])) { + // everything went fine :) + return true; + + /* old broken code see bug#2987 + if (isset($params['changes'])) { + + if (isset($params['changes']['add']) && + !@ldap_modify($this->_link, $dn, $params['changes']['add'])) { + + return $this->raiseError("Net_LDAP::modify: $dn not modified because:" . ldap_error($this->_link), + ldap_errno($this->_link)); + } + + if (isset($params['changes']['replace']) && + !@ldap_modify($this->_link, $dn, $params['changes']['replace'])) { + + return $this->raiseError("Net_LDAP::modify: replace change didn't work: " . ldap_error($this->_link), + ldap_errno($this->_link)); + } + + if (isset($params['changes']['delete']) && + !@ldap_mod_del($this->_link, $dn, $params['changes']['delete'])) { + + return $this->raiseError("Net_LDAP::modify:delete did not work" . ldap_error($this->_link), + ldap_errno($this->_link)); + } + } + + if (isset($params['add']) && !@ldap_add($this->_link, $dn, $params['add'])) { + return $this->raiseError(ldap_error($this->_link), ldap_errno($this->_link)); + } + + if (isset($params['replace']) && !@ldap_modify($this->_link, $dn, $params['replace'])) { + return $this->raiseError(ldap_error($this->_link), ldap_errno($this->_link)); + } + + if (isset($params['delete'])) { + // since you delete an attribute by making it empty: + foreach ($params['delete'] as $k) { + $params['delete'][$k] = ''; + } + + if (!@ldap_modify($this->_link, $dn, $params['delete'])) { + return $this->raiseError(ldap_error($this->_link), ldap_errno($this->_link)); + } + } + // everything went fine :) + return true; + */ + + } + + /** + * Run a ldap query + * + * Search is used to query the ldap-database. + * $base and $filter may be ommitted. BaseDN and default filter will then be used. + * Params may contain: + * + * scope: The scope which will be used for searching + * base - Just one entry + * sub - The whole tree + * one - Immediately below $base + * sizelimit: Limit the number of entries returned (default: 0), + * timelimit: Limit the time spent for searching (default: 0), + * attrsonly: If true, the search will only return the attribute names, NO values + * attributes: Array of attribute names, which the entry should contain. It is good practice + * to limit this to just the ones you need, so by default this function does not + * return any attributes at all. + * [NOT IMPLEMENTED] + * deref: By default aliases are dereferenced to locate the base object for the search, but not when + * searching subordinates of the base object. This may be changed by specifying one of the + * following values: + * + * never - Do not dereference aliases in searching or in locating the base object of the search. + * search - Dereference aliases in subordinates of the base object in searching, but not in + * locating the base object of the search. + * find + * always + * + * @access public + * @param string LDAP searchbase + * @param string LDAP search filter + * @param array Array of options + * @return object mixed Net_LDAP_Search or Net_LDAP_Error + */ + function search($base = null, $filter = null, $params = array()) + { + if (is_null($base)) { + $base = $this->_config['base']; + } + if (is_null($filter)) { + $filter = $this->_config['filter']; + } + + /* setting searchparameters */ + (isset($params['sizelimit'])) ? $sizelimit = $params['sizelimit'] : $sizelimit = 0; + (isset($params['timelimit'])) ? $timelimit = $params['timelimit'] : $timelimit = 0; + (isset($params['attrsonly'])) ? $attrsonly = $params['attrsonly'] : $attrsonly = 0; + (isset($params['attributes'])) ? $attributes = $params['attributes'] : $attributes = array(''); + + if (!is_array($attributes)) { + $this->raiseError("The param attributes must be an array!"); + } + + /* scoping makes searches faster! */ + $scope = (isset($params['scope']) ? $params['scope'] : $this->_config['scope']); + + switch ($scope) { + case 'one': + $search_function = 'ldap_list'; + break; + case 'base': + $search_function = 'ldap_read'; + break; + default: + $search_function = 'ldap_search'; + } + + $search = @call_user_func($search_function, + $this->_link, + $base, + $filter, + $attributes, + $attrsonly, + $sizelimit, + $timelimit); + + if ($err = ldap_errno($this->_link)) { + + if ($err == 32) { + // Errorcode 32 = no such object, i.e. a nullresult. + return $obj =& new Net_LDAP_Search ($search, $this->_link); + + // Errorcode 4 = sizelimit exeeded. this will be handled better in time... + //} elseif ($err == 4) { + // return $obj = & new Net_LDAP_Search ($search, $this->_link); + + } elseif ($err == 87) { + // bad search filter + return $this->raiseError($this->errorMessage($err) . "($filter)", $err); + } else { + $msg = "\nParameters:\nBase: $base\nFilter: $filter\nScope: $scope"; + return $this->raiseError($this->errorMessage($err) . $msg, $err); + } + } else { + @$obj =& new Net_LDAP_Search($search, $this->_link); + return $obj; + } + + } + + /** + * Set an LDAP option + * + * @access public + * @param string Option to set + * @param mixed Value to set Option to + * @return mixed Net_LDAP_Error or true + */ + function setOption($option, $value) + { + if ($this->_link) { + if (defined($option)) { + if (@ldap_set_option($this->_link, constant($option), $value)) { + return true; + } else { + $err = @ldap_errno($this->_link); + if ($err) { + $msg = @ldap_err2str($err); + } else { + $err = NET_LDAP_ERROR; + $msg = $this->errorMessage($err); + } + return $this->raiseError($msg, $err); + } + } else { + return $this->raiseError("Unkown Option requested"); + } + } else { + return $this->raiseError("No LDAP connection"); + } + } + + /** + * Get an LDAP option value + * + * @access public + * @param string Option to get + * @return mixed Net_LDAP_Error or option value + */ + function getOption($option) + { + if ($this->_link) { + if (defined($option)) { + if (@ldap_get_option($this->_link, constant($option), $value)) { + return $value; + } else { + $err = @ldap_errno($this->_link); + if ($err) { + $msg = @ldap_err2str($err); + } else { + $err = NET_LDAP_ERROR; + $msg = $this->errorMessage($err); + } + return $this->raiseError($msg, $err); + } + } else { + $this->raiseError("Unkown Option requested"); + } + } else { + $this->raiseError("No LDAP connection"); + } + } + + /** + * Get the LDAP_PROTOCOL_VERSION that is used on the connection. + * + * A lot of ldap functionality is defined by what protocol version the ldap server speaks. + * This might be 2 or 3. + * + * @return int + */ + function getLDAPVersion() + { + if($this->_link) { + $version = $this->getOption("LDAP_OPT_PROTOCOL_VERSION"); + } else { + $version = $this->_config['version']; + } + return $version; + } + + /** + * Set the LDAP_PROTOCOL_VERSION that is used on the connection. + * + * @param int Version to set + * @return mixed Net_LDAP_Error or TRUE + */ + function setLDAPVersion($version = 0) + { + if (!$version) { + $version = $this->_config['version']; + } + return $this->setOption("LDAP_OPT_PROTOCOL_VERSION", $version); + } + + /** + * Get the Net_LDAP version. + * + * Return the Net_LDAP version + * + * @return string Net_LDAP version + */ + function getVersion () + { + return $this->_version; + } + + /** + * Tell if a dn already exists + * + * @param string + * @return boolean + */ + function dnExists($dn) + { + $dns = explode(",",$dn); + $filter = array_shift($dns); + $base= implode($dns,','); + //$base = $dn; + //$filter = '(objectclass=*)'; + + $result = @ldap_list($this->_link, $base, $filter, array(), 1, 1); + if (ldap_errno($this->_link) == 32) { + return false; + } + if (ldap_errno($this->_link) != 0) { + $this->raiseError(ldap_error($this->_link), ldap_errno($this->_link)); + } + if (@ldap_count_entries($this->_link, $result)) { + return true; + } + return false; + } + + + /** + * Get a specific entry based on the dn + * + * @param string dn + * @param array Array of Attributes to select + * @return object Net_LDAP_Entry or Net_LDAP_Error + */ + function &getEntry($dn, $attr = array('')) + { + $result = $this->search($dn, '(objectClass=*)', array('scope' => 'base', 'attributes' => $attr)); + if (Net_LDAP::isError($result)) { + return $result; + } + $entry = $result->shiftEntry(); + if (false == $entry) { + return $this->raiseError('Could not fetch entry'); + } + return $entry; + } + + + /** + * Returns the string for an ldap errorcode. + * + * Made to be able to make better errorhandling + * Function based on DB::errorMessage() + * Tip: The best description of the errorcodes is found here: http://www.directory-info.com/LDAP/LDAPErrorCodes.html + * + * @param int Error code + * @return string The errorstring for the error. + */ + function errorMessage($errorcode) + { + $errorMessages = array( + 0x00 => "LDAP_SUCCESS", + 0x01 => "LDAP_OPERATIONS_ERROR", + 0x02 => "LDAP_PROTOCOL_ERROR", + 0x03 => "LDAP_TIMELIMIT_EXCEEDED", + 0x04 => "LDAP_SIZELIMIT_EXCEEDED", + 0x05 => "LDAP_COMPARE_FALSE", + 0x06 => "LDAP_COMPARE_TRUE", + 0x07 => "LDAP_AUTH_METHOD_NOT_SUPPORTED", + 0x08 => "LDAP_STRONG_AUTH_REQUIRED", + 0x09 => "LDAP_PARTIAL_RESULTS", + 0x0a => "LDAP_REFERRAL", + 0x0b => "LDAP_ADMINLIMIT_EXCEEDED", + 0x0c => "LDAP_UNAVAILABLE_CRITICAL_EXTENSION", + 0x0d => "LDAP_CONFIDENTIALITY_REQUIRED", + 0x0e => "LDAP_SASL_BIND_INPROGRESS", + 0x10 => "LDAP_NO_SUCH_ATTRIBUTE", + 0x11 => "LDAP_UNDEFINED_TYPE", + 0x12 => "LDAP_INAPPROPRIATE_MATCHING", + 0x13 => "LDAP_CONSTRAINT_VIOLATION", + 0x14 => "LDAP_TYPE_OR_VALUE_EXISTS", + 0x15 => "LDAP_INVALID_SYNTAX", + 0x20 => "LDAP_NO_SUCH_OBJECT", + 0x21 => "LDAP_ALIAS_PROBLEM", + 0x22 => "LDAP_INVALID_DN_SYNTAX", + 0x23 => "LDAP_IS_LEAF", + 0x24 => "LDAP_ALIAS_DEREF_PROBLEM", + 0x30 => "LDAP_INAPPROPRIATE_AUTH", + 0x31 => "LDAP_INVALID_CREDENTIALS", + 0x32 => "LDAP_INSUFFICIENT_ACCESS", + 0x33 => "LDAP_BUSY", + 0x34 => "LDAP_UNAVAILABLE", + 0x35 => "LDAP_UNWILLING_TO_PERFORM", + 0x36 => "LDAP_LOOP_DETECT", + 0x3C => "LDAP_SORT_CONTROL_MISSING", + 0x3D => "LDAP_INDEX_RANGE_ERROR", + 0x40 => "LDAP_NAMING_VIOLATION", + 0x41 => "LDAP_OBJECT_CLASS_VIOLATION", + 0x42 => "LDAP_NOT_ALLOWED_ON_NONLEAF", + 0x43 => "LDAP_NOT_ALLOWED_ON_RDN", + 0x44 => "LDAP_ALREADY_EXISTS", + 0x45 => "LDAP_NO_OBJECT_CLASS_MODS", + 0x46 => "LDAP_RESULTS_TOO_LARGE", + 0x47 => "LDAP_AFFECTS_MULTIPLE_DSAS", + 0x50 => "LDAP_OTHER", + 0x51 => "LDAP_SERVER_DOWN", + 0x52 => "LDAP_LOCAL_ERROR", + 0x53 => "LDAP_ENCODING_ERROR", + 0x54 => "LDAP_DECODING_ERROR", + 0x55 => "LDAP_TIMEOUT", + 0x56 => "LDAP_AUTH_UNKNOWN", + 0x57 => "LDAP_FILTER_ERROR", + 0x58 => "LDAP_USER_CANCELLED", + 0x59 => "LDAP_PARAM_ERROR", + 0x5a => "LDAP_NO_MEMORY", + 0x5b => "LDAP_CONNECT_ERROR", + 0x5c => "LDAP_NOT_SUPPORTED", + 0x5d => "LDAP_CONTROL_NOT_FOUND", + 0x5e => "LDAP_NO_RESULTS_RETURNED", + 0x5f => "LDAP_MORE_RESULTS_TO_RETURN", + 0x60 => "LDAP_CLIENT_LOOP", + 0x61 => "LDAP_REFERRAL_LIMIT_EXCEEDED", + 1000 => "Unknown Net_LDAP error" + ); + + return isset($errorMessages[$errorcode]) ? $errorMessages[$errorcode] : $errorMessages[NET_LDAP_ERROR]; + } + + /** + * Tell whether value is a Net_LDAP_Error or not + * + * @access public + * @param mixed + * @return boolean + */ + function isError($value) + { + return (is_a($value, "Net_LDAP_Error") || parent::isError($value)); + } + + /** + * gets a root dse object + * + * @access public + * @author Jan Wagner + * @param array Array of attributes to search for + * @return object mixed Net_LDAP_Error or Net_LDAP_RootDSE + */ + function &rootDse($attrs = null) + { + require_once('Net/LDAP/RootDSE.php'); + + if (is_array($attrs) && count($attrs) > 0 ) { + $attributes = $attrs; + } else { + $attributes = array('namingContexts', + 'altServer', + 'supportedExtension', + 'supportedControl', + 'supportedSASLMechanisms', + 'supportedLDAPVersion', + 'subschemaSubentry' ); + } + $result = $this->search('', '(objectClass=*)', array('attributes' => $attributes, 'scope' => 'base')); + if (Net_LDAP::isError($result)) return $result; + + $entry = $result->shift_entry(); + if (false === $entry) return $this->raiseError('Could not fetch RootDSE entry'); + + return new Net_LDAP_RootDSE($entry); + } + + /** + * alias function of rootDse() for perl-ldap interface + * + * @access public + * @see rootDse() + */ + function &root_dse() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'rootDse'), $args); + } + + /** + * get a schema object + * + * @access public + * @author Jan Wagner + * @param string Subschema entry dn + * @return object mixed Net_LDAP_Schema or Net_LDAP_Error + */ + function &schema($dn = null) + { + require_once('Net/LDAP/Schema.php'); + + $schema =& new Net_LDAP_Schema(); + + if (is_null($dn)) { + // get the subschema entry via root dse + $dse = $this->rootDSE(array('subschemaSubentry')); + if (false == Net_LDAP::isError($dse)) { + $base = $dse->getValue('subschemaSubentry', 'single'); + if (!Net_LDAP::isError($base)) { + $dn = $base; + } + } + } + if (is_null($dn)) { + $dn = 'cn=Subschema'; + } + + // fetch the subschema entry + $result = $this->search($dn, '(objectClass=*)', + array('attributes' => array_values($schema->types), 'scope' => 'base')); + if (Net_LDAP::isError($result)) { + return $result; + } + + $entry = $result->shift_entry(); + if (false === $entry) { + return $this->raiseError('Could not fetch Subschema entry'); + } + + $schema->parse($entry); + + return $schema; + } + + /** + * Encodes given attributes to UTF8 if needed + * + * This function takes attributes in an array and then checks against the schema if they need + * UTF8 encoding. If that is so, they will be encoded. An encoded array will be returned and + * can be used for adding or modifying. + * + * @access public + * @param array Array of attributes + * @return array Array of UTF8 encoded attributes + */ + function utf8Encode($attributes) + { + return $this->_utf8($attributes, 'utf8_encode'); + } + + /** + * Decodes the given attribute values + * + * @access public + * @param array Array of attributes + * @return array Array with decoded attribute values + */ + function utf8Decode($attributes) + { + return $this->_utf8($attributes, 'utf8_decode'); + } + + /** + * Encodes or decodes attribute values if needed + * + * @access private + * @param array Array of attributes + * @param array Function to apply to attribute values + * @return array Array of attributes with function applied to values + */ + function _utf8($attributes, $function) + { + if (!$this->_schema) { + $this->_schema = $this->schema(); + } + + if (!$this->_link || Net_LDAP::isError($this->_schema) || !function_exists($function)) { + return $attributes; + } + + if (is_array($attributes) && count($attributes) > 0) { + + foreach( $attributes as $k => $v ) { + + if (!isset($this->_schemaAttrs[$k])) { + + $attr = $this->_schema->get('attribute', $k); + if (Net_LDAP::isError($attr)) { + continue; + } + + if (false !== strpos($attr['syntax'], '1.3.6.1.4.1.1466.115.121.1.15')) { + $encode = true; + } else { + $encode = false; + } + $this->_schemaAttrs[$k] = $encode; + + } else { + $encode = $this->_schemaAttrs[$k]; + } + + if ($encode) { + if (is_array($v)) { + foreach ($v as $ak => $av) { + $v[$ak] = call_user_func($function, $av ); + } + } else { + $v = call_user_func($function, $v); + } + } + $attributes[$k] = $v; + } + } + return $attributes; + } +} + +/** + * Net_LDAP_Error implements a class for reporting portable LDAP error messages. + * + * @package Net_LDAP + */ +class Net_LDAP_Error extends PEAR_Error +{ + /** + * Net_LDAP_Error constructor. + * + * @param mixed Net_LDAP error code, or string with error message. + * @param integer what "error mode" to operate in + * @param integer what error level to use for $mode & PEAR_ERROR_TRIGGER + * @param mixed additional debug info, such as the last query + * @access public + * @see PEAR_Error + */ + function Net_LDAP_Error($code = NET_LDAP_ERROR, $mode = PEAR_ERROR_RETURN, + $level = E_USER_NOTICE, $debuginfo = null) + { + $mode = PEAR_ERROR_RETURN; + if (is_int($code)) { + $this->PEAR_Error('Net_LDAP_Error: ' . Net_LDAP::errorMessage($code), $code, $mode, $level, $debuginfo); + } else { + $this->PEAR_Error("Net_LDAP_Error: $code", NET_LDAP_ERROR, $mode, $level, $debuginfo); + } + } +} +?> diff --git a/gulliver/thirdparty/pear/Net/LDAP/Entry.php b/gulliver/thirdparty/pear/Net/LDAP/Entry.php new file mode 100644 index 000000000..56ecdefa8 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/Entry.php @@ -0,0 +1,524 @@ + false, + 'modify' => false, + 'newEntry' => true + ); // since the entry is not changed before the update(); + + /** + * Net_LDAP_Schema object TO BE REMOVED + */ + var $_schema; + /**#@-*/ + + /** Constructor + * + * @param - link - ldap_resource_link, dn = string entry dn, attributes - array entry attributes array. + * @return - none + **/ + function Net_LDAP_Entry($link = null, $dn = null, $attributes = null) + { + if (!is_null($link)) { + $this->_link = $link; + } + if (!is_null($dn)) { + $this->_set_dn($dn); + } + if (is_array($attributes) && count($attributes) > 0) { + $this->_set_attributes($attributes); + } else { + $this->updateCheck['newEntry'] = true; + } + } + + /** + * Set the reasourcelink to the ldapserver. + * + * @access private + * @param resource LDAP link + */ + function _set_link(&$link) + { + $this->_link = $link; + } + + /** + * set the entrys DN + * + * @access private + * @param string + */ + function _set_dn($dn) + { + $this->_dn = $dn; + } + + /** + * sets the internal array of the entrys attributes. + * + * @access private + * @param array + */ + function _set_attributes($attributes= array()) + { + $this->_attrs = $attributes; + // this is the sign that the entry exists in the first place: + $this->updateCheck['newEntry'] = false; + } + + /** + * removes [count] entries from the array. + * + * remove all the count elements in the array: + * Used before ldap_modify, ldap_add + * + * @access private + * @return array Cleaned array of attributes + */ + function _clean_entry() + { + $attributes = array(); + + for ($i=0; $i < $this->_attrs['count'] ; $i++) { + + $attr = $this->_attrs[$i]; + + if ($this->_attrs[$attr]['count'] == 1) { + $attributes[$this->_attrs[$i]] = $this->_attrs[$attr][0]; + } else { + $attributes[$attr] = $this->_attrs[$attr]; + unset ($attributes[ $attr ]['count']); + } + } + + return $attributes; + + } + + /** + * returns an assosiative array of all the attributes in the array + * + * attributes - returns an assosiative array of all the attributes in the array + * of the form array ('attributename'=>'singelvalue' , 'attribute'=>array('multiple','values')) + * + * @param none + * @return array Array of attributes and values. + */ + function attributes() + { + return $this->_clean_entry(); + } + + /** + * Add one or more attribute to the entry + * + * The values given will be added to the values which already exist for the given attributes. + * usage: + * $entry->add ( array('sn'=>'huse',objectclass=>array(top,posixAccount))) + * + * @param array Array of attributes + * @return mixed Net_Ldap_Error if error, else true. + */ + function add($attr = array()) + { + if (!isset($this->_attrs['count'])) { + $this->_attrs['count'] = 0; + } + if (!is_array($attr)) { + return $this->raiseError("Net_LDAP::add : the parameter supplied is not an array, $attr", 1000); + } + /* if you passed an empty array, that is your problem! */ + if (count ($attr)==0) { + return true; + } + foreach ($attr as $k => $v ) { + // empty entrys should not be added to the entry. + if ($v == '') { + continue; + } + + if ($this->exists($k)) { + if (!is_array($this->_attrs[$k])) { + return $this->raiseError("Possible malformed array as parameter to Net_LDAP::add()."); + } + array_push($this->_attrs[$k],$v); + $this->_attrs[$k]['count']++; + } else { + $this->_attrs[$k][0] = $v; + $this->_attrs[$k]['count'] = 1; + $this->_attrs[$this->_attrs['count']] = $k; + $this->_attrs['count']++; + } + // Fix for bug #952 + if (empty($this->_addAttrs[$k])) { + $this->_addAttrs[$k] = array(); + } + if (false == is_array($v)) { + $v = array($v); + } + foreach ($v as $value) { + array_push($this->_addAttrs[$k], $value); + } + } + return true; + } + + /** + * Set or get the DN for the object + * + * If a new dn is supplied, this will move the object when running $obj->update(); + * + * @param string DN + */ + function dn($newdn = '') + { + if ($newdn == '') { + return $this->_dn; + } + + $this->_olddn = $this->_dn; + $this->_dn = $newdn; + $this->updateCheck['newdn'] = true; + } + + /** + * check if a certain attribute exists in the directory + * + * @param string attribute name. + * @return boolean + */ + function exists($attr) + { + if (array_key_exists($attr, $this->_attrs)) { + return true; + } + return false; + } + + /** + * get_value get the values for a attribute + * + * returns either an array or a string + * possible values for option: + * alloptions - returns an array with the values + a countfield. + * i.e.: array (count=>1, 'sn'=>'huse'); + * single - returns the, first value in the array as a string. + * + * @param $attr string attribute name + * @param $options array + */ + function get_value($attr = '', $options = '') + { + if (array_key_exists($attr, $this->_attrs)) { + + if ($options == 'single') { + if (is_array($this->_attrs[$attr])) { + return $this->_attrs[$attr][0]; + } else { + return $this->_attrs[$attr]; + } + } + + $value = $this->_attrs[$attr]; + + if (!$options == 'alloptions') { + unset ($value['count']); + } + return $value; + } else { + return ''; + } + } + + /** + * add/delete/modify attributes + * + * this function tries to do all the things that replace(),delete() and add() does on an object. + * Syntax: + * array ( 'attribute' => newval, 'delattribute' => '', newattrivute => newval); + * Note: You cannot use this function to modify parts of an attribute. You must modify the whole attribute. + * You may call the function many times before running $entry->update(); + * + * @param array attributes to be modified + * @return mixed errorObject if failure, true if success. + */ + function modify($attrs = array()) { + + if (!is_array($attrs) || count ($attrs) < 1 ) { + return $this->raiseError("You did not supply an array as expected",1000); + } + + foreach ($attrs as $k => $v) { + // empty values are deleted (ldap v3 handling is in update() ) + if ($v == '' && $this->exists($k)) { + $this->_delAttrs[$k] = ''; + continue; + } + /* existing attributes are modified*/ + if ($this->exists($k) ) { + if (is_array($v)) { + $this->_modAttrs[$k] = $v; + } else { + $this->_modAttrs[$k][0] = $v; + } + } else { + /* new ones are created */ + if (is_array($v) ) { + // an empty array is deleted... + if (count($v) == 0 ) { + $this->_delAttrs[$k] = ''; + } else { + $this->_addAttrs[$k] = $v; + } + } else { + // dont't add empty attributes + if ($v != null) $this->_addAttrs[$k][0] = $v; + } + } + } + return true; + } + + + /** + * replace a certain attributes value + * + * replace - replace a certain attributes value + * example: + * $entry->replace(array('uid'=>array('tarjei'))); + * + * @param array attributes to be replaced + * @return mixed error if failure, true if sucess. + */ + function replace($attrs = array() ) + { + foreach ($attrs as $k => $v) { + + if ($this->exists($k)) { + + if (is_array($v)) { + $this->_attrs[$k] = $v; + $this->_attrs[$k]['count'] = count($v); + $this->_modAttrs[$k] = $v; + } else { + $this->_attrs[$k]['count'] = 1; + $this->_attrs[$k][0] = $v; + $this->_modAttrs[$k][0] = $v; + } + } else { + return $this->raiseError("Attribute $k does not exist",16); // 16 = no such attribute exists. + } + } + return true; + } + + /** + * delete attributes + * + * Use this function to delete certain attributes from an object. + * + * @param - array of attributes to be deleted + * @return mixed Net_Ldap_Error if failure, true if success. + */ + function delete($attrs = array()) + { + foreach ($attrs as $k => $v) { + + if ($this->exists ($k)) { + // if v is a null, then remove the whole attribute, else only the value. + if ($v == '') { + unset($this->_attrs[$k]); + $this->_delAttrs[$k] = ""; + // else we remove only the correct value. + } else { + for ($i = 0;$i< $this->_attrs[$k]['count'];$i++) { + if ($this->_attrs[$k][$i] == $v ) { + unset ($this->_attrs[$k][$i]); + $this->_delAttrs[$k] = $v; + continue; + } + } + } + } else { + $this->raiseError("You tried to delete a nonexisting attribute!",16); + } + } + return true; + } + + /** + * update the Entry in LDAP + * + * After modifying an object, you must run update() to + * make the updates on the ldap server. Before that, they only exists in the object. + * + * @param object Net_LDAP + * @return mixed Net_LDAP_Error object on failure or true on success + */ + function update ($ldapObject = null) + { + if ($ldapObject == null && $this->_link == null ) { + $this->raiseError("No link to database"); + } + + if ($ldapObject != null) { + $this->_link =& $ldapObject->_link; + } + + //if it's a new + if ($this->updateCheck['newdn'] && !$this->updateCheck['newEntry']) { + if (@ldap_get_option( $this->_link, LDAP_OPT_PROTOCOL_VERSION, $version) && $version != 3) { + return $this->raiseError("Moving or renaming an dn is only supported in LDAP V3!", 80); + } + + $newparent = ldap_explode_dn($this->_dn, 0); + unset($newparent['count']); + $relativeDn = array_shift($newparent); + $newparent = join(',', $newparent); + + if (!@ldap_rename($this->_link, $this->_olddn, $relativeDn, $newparent, true)) { + return $this->raiseError("DN not renamed: " . ldap_error($this->_link), ldap_errno($this->_link)); + } + } + + if ($this->updateCheck['newEntry']) { + //print "
    "; print_r($this->_clean_entry()); + + if (!@ldap_add($this->_link, $this->dn(), $this->_clean_entry()) ) { + return $this->raiseError("Entry" . $this->dn() . " not added!" . + ldap_error($this->_link), ldap_errno($this->_link)); + } else { + return true; + } + // update existing entry + } else { + $this->_error['first'] = $this->_modAttrs; + $this->_error['count'] = count($this->_modAttrs); + + // modified attributes + if (( count($this->_modAttrs)>0) && + !ldap_modify($this->_link, $this->dn(), $this->_modAttrs)) + { + return $this->raiseError("Entry " . $this->dn() . " not modified(attribs not modified): " . + ldap_error($this->_link),ldap_errno($this->_link)); + } + + // attributes to be deleted + if (( count($this->_delAttrs) > 0 )) + { + // in ldap v3 we need to supply the old attribute values for deleting + if (@ldap_get_option( $this->_link, LDAP_OPT_PROTOCOL_VERSION, $version) && $version == 3) { + foreach ( $this->_delAttrs as $k => $v ) { + if ( $v == '' && $this->exists($k) ) { + $this->_delAttrs[$k] = $this->get_value( $k ); + } + } + } + if ( !ldap_mod_del($this->_link, $this->dn(), $this->_delAttrs) ) { + return $this->raiseError("Entry " . $this->dn() . " not modified (attributes not deleted): " . + ldap_error($this->_link),ldap_errno($this->_link)); + } + } + + // new attributes + if ((count($this->_addAttrs)) > 0 && !ldap_modify($this->_link, $this->dn(), $this->_addAttrs)) { + return $this->raiseError( "Entry " . $this->dn() . " not modified (attributes not added): " . + ldap_error($this->_link),ldap_errno($this->_link)); + } + return true; + } + } +} + +?> diff --git a/gulliver/thirdparty/pear/Net/LDAP/RootDSE.php b/gulliver/thirdparty/pear/Net/LDAP/RootDSE.php new file mode 100644 index 000000000..a2f3fc090 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/RootDSE.php @@ -0,0 +1,192 @@ + + * @version $Revision: 4831 $ + */ +class Net_LDAP_RootDSE extends PEAR +{ + /** + * @access private + * @var object Net_LDAP_Entry + **/ + var $_entry; + + /** + * class constructor + * + * @param object Net_LDAP_Entry + */ + function Net_LDAP_RootDSE(&$entry) + { + $this->_entry = $entry; + } + + /** + * Gets the requested attribute value + * + * Same usuage as Net_LDAP_Entry::get_value() + * + * @access public + * @param string Attribute name + * @param array Array of options + * @return mixed Net_LDAP_Error object or attribute values + * @see Net_LDAP_Entry::get_value() + */ + function getValue($attr = '', $options = '') + { + return $this->_entry->get_value($attr, $options); + } + + /** + * alias function of getValue() for perl-ldap interface + * + * @see getValue() + */ + function get_value() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'getValue' ), $args); + } + + /** + * Determines if the extension is supported + * + * @access public + * @param array Array of oids to check + * @return boolean + */ + function supportedExtension($oids) + { + return $this->_checkAttr($oids, 'supportedExtension'); + } + + /** + * alias function of supportedExtension() for perl-ldap interface + * + * @see supportedExtension() + */ + function supported_extension() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'supportedExtension'), $args); + } + + /** + * Determines if the version is supported + * + * @access public + * @param array Versions to check + * @return boolean + */ + function supportedVersion($versions) + { + return $this->_checkAttr($versions, 'supportedLDAPVersion'); + } + + /** + * alias function of supportedVersion() for perl-ldap interface + * + * @see supportedVersion() + */ + function supported_version() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'supportedVersion'), $args); + } + + /** + * Determines if the control is supported + * + * @access public + * @param array Control oids to check + * @return boolean + */ + function supportedControl($oids) + { + return $this->_checkAttr($oids, 'supportedControl'); + } + + /** + * alias function of supportedControl() for perl-ldap interface + * + * @see supportedControl() + */ + function supported_control() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'supportedControl' ), $args); + } + + /** + * Determines if the sasl mechanism is supported + * + * @access public + * @param array SASL mechanisms to check + * @return boolean + */ + function supportedSASLMechanism($mechlist) + { + return $this->_checkAttr($mechlist, 'supportedSASLMechanisms'); + } + + /** + * alias function of supportedSASLMechanism() for perl-ldap interface + * + * @see supportedSASLMechanism() + */ + function supported_sasl_mechanism() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'supportedSASLMechanism'), $args); + } + + /** + * Checks for existance of value in attribute + * + * @access private + * @param array $values values to check + * @param attr $attr attribute name + * @return boolean + */ + function _checkAttr($values, $attr) + { + if (!is_array($values)) $values = array($values); + + foreach ($values as $value) { + if (!@in_array($value, $this->get_value($attr))) { + return false; + } + } + return true; + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Net/LDAP/Schema.php b/gulliver/thirdparty/pear/Net/LDAP/Schema.php new file mode 100644 index 000000000..5fdd650d8 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/Schema.php @@ -0,0 +1,355 @@ + + * @version $Revision: 4831 $ + */ + class Net_LDAP_Schema extends PEAR + { + /** + * Map of entry types to ldap attributes of subschema entry + * + * @access public + * @var array + */ + var $types = array('attribute' => 'attributeTypes', + 'ditcontentrule' => 'dITContentRules', + 'ditstructurerule' => 'dITStructureRules', + 'matchingrule' => 'matchingRules', + 'matchingruleuse' => 'matchingRuleUse', + 'nameform' => 'nameForms', + 'objectclass' => 'objectClasses', + 'syntax' => 'ldapSyntaxes'); + + /**#@+ + * Array of entries belonging to this type + * + * @access private + * @var array + */ + var $_attributeTypes = array(); + var $_matchingRules = array(); + var $_matchingRuleUse = array(); + var $_ldapSyntaxes = array(); + var $_objectClasses = array(); + var $_dITContentRules = array(); + var $_dITStructureRules = array(); + var $_nameForms = array(); + /**#@-*/ + + /** + * hash of all fetched oids + * + * @access private + * @var array + */ + var $_oids = array(); + + /** + * constructor of the class + * + * @access protected + */ + function Net_LDAP_Schema() + { + $this->PEAR('Net_LDAP_Error'); // default error class + } + + /** + * Return a hash of entries for the given type + * + * Returns a hash of entry for th givene type. Types may be: + * objectclasses, attributes, ditcontentrules, ditstructurerules, matchingrules, + * matchingruleuses, nameforms, syntaxes + * + * @access public + * @param string Type to fetch + * @return mixed Array or Net_LDAP_Error + */ + function &getAll($type) + { + $map = array('objectclasses' => &$this->_objectClasses, + 'attributes' => &$this->_attributeTypes, + 'ditcontentrules' => &$this->_dITContentRules, + 'ditstructurerules' => &$this->_dITStructureRules, + 'matchingrules' => &$this->_matchingRules, + 'matchingruleuses' => &$this->_matchingRuleUse, + 'nameforms' => &$this->_nameForms, + 'syntaxes' => &$this->_ldapSyntaxes ); + + $key = strtolower($type); + return ((key_exists($key, $map)) ? $map[$key] : $this->raiseError("Unknown type $type")); + } + + /** + * Return a specific entry + * + * @access public + * @param string Type of name + * @param string Name or OID to fetch + * @return mixed Entry or Net_LDAP_Error + */ + function &get($type, $name) + { + $type = strtolower($type); + if (false == key_exists($type, $this->types)) { + return $this->raiseError("No such type $type"); + } + + $name = strtolower($name); + $type_var = &$this->{'_' . $this->types[$type]}; + + if( key_exists($name, $type_var)) { + return $type_var[$name]; + } elseif(key_exists($name, $this->_oids) && $this->_oids[$name]['type'] == $type) { + return $this->_oids[$name]; + } else { + return $this->raiseError("Could not find $type $name"); + } + } + + + /** + * Fetches attributes that MAY be present in the given objectclass + * + * @access public + * @param string Name or OID of objectclass + * @return mixed Array with attributes or Net_LDAP_Error + */ + function may($oc) + { + return $this->_getAttr($oc, 'may'); + } + + /** + * Fetches attributes that MUST be present in the given objectclass + * + * @access public + * @param string Name or OID of objectclass + * @return mixed Array with attributes or Net_LDAP_Error + */ + function must($oc) + { + return $this->_getAttr($oc, 'must'); + } + + /** + * Fetches the given attribute from the given objectclass + * + * @access private + * @param string Name or OID of objectclass + * @param string Name of attribute to fetch + * @return mixed The attribute or Net_LDAP_Error + */ + function _getAttr($oc, $attr) + { + $oc = strtolower($oc); + if (key_exists($oc, $this->_objectClasses) && key_exists($attr, $this->_objectClasses[$oc])) { + return $this->_objectClasses[$oc][$attr]; + } + elseif (key_exists($oc, $this->_oids) && + $this->_oids[$oc]['type'] == 'objectclass' && + key_exists($attr, $this->_oids[$oc])) { + return $this->_oids[$oc][$attr]; + } else { + return $this->raiseError("Could not find $attr attributes for $oc "); + } + } + + /** + * Returns the name(s) of the immediate superclass(es) + * + * @param string Name or OID of objectclass + * @return mixed Array of names or Net_LDAP_Error + */ + function superclass($oc) + { + $o = $this->get('objectclass', $oc); + if (Net_LDAP::isError($o)) { + return $o; + } + return (key_exists('sup', $o) ? $o['sup'] : array()); + } + + /** + * Parses the schema of the given Subschema entry + * + * @access public + * @param object Net_LDAP_Entry Subschema entry + */ + function parse(&$entry) + { + foreach ($this->types as $type => $attr) + { + // initialize map type to entry + $type_var = '_' . $attr; + $this->{$type_var} = array(); + + // get values for this type + $values = $entry->get_value($attr); + + if (is_array($values)) + { + foreach ($values as $value) { + + unset($schema_entry); // this was a real mess without it + + // get the schema entry + $schema_entry = $this->_parse_entry($value); + + // set the type + $schema_entry['type'] = $type; + + // save a ref in $_oids + $this->_oids[$schema_entry['oid']] =& $schema_entry; + + // save refs for all names in type map + $names = $schema_entry['aliases']; + array_push($names, $schema_entry['name']); + foreach ($names as $name) { + $this->{$type_var}[strtolower($name)] =& $schema_entry; + } + } + } + } + } + + /** + * parses an attribute value into a schema entry + * + * @access private + * @param string Attribute value + * @return mixed Schema entry array or false + */ + function &_parse_entry($value) + { + // tokens that have no value associated + $noValue = array('single-value', + 'obsolete', + 'collective', + 'no-user-modification', + 'abstract', + 'structural', + 'auxiliary'); + + // tokens that can have multiple values + $multiValue = array('must', 'may', 'sup'); + + $schema_entry = array('aliases' => array()); // initilization + + $tokens = $this->_tokenize($value); // get an array of tokens + + // remove surrounding brackets + if ($tokens[0] == '(') array_shift($tokens); + if ($tokens[count($tokens) - 1] == ')') array_pop($tokens); // -1 doesnt work on arrays :-( + + $schema_entry['oid'] = array_shift($tokens); // first token is the oid + + // cycle over the tokens until none are left + while (count($tokens) > 0) { + $token = strtolower(array_shift($tokens)); + if (in_array($token, $noValue)) { + $schema_entry[$token] = 1; // single value token + } else { + // this one follows a string or a list if it is multivalued + if (($schema_entry[$token] = array_shift($tokens)) == '(') { + // this creates the list of values and cycles through the tokens + // until the end of the list is reached ')' + $schema_entry[$token] = array(); + while ($tmp = array_shift($tokens)) { + if ($tmp == ')') break; + if ($tmp != '$') array_push($schema_entry[$token], $tmp); + } + } + // create a array if the value should be multivalued but was not + if (in_array($token, $multiValue ) && !is_array($schema_entry[$token])) { + $schema_entry[$token] = array($schema_entry[$token]); + } + } + } + // get max length from syntax + if (key_exists('syntax', $schema_entry)) { + if (preg_match('/{(\d+)}/', $schema_entry['syntax'], $matches)) { + $schema_entry['max_length'] = $matches[1]; + } + } + // force a name + if (empty($schema_entry['name'])) { + $schema_entry['name'] = $schema_entry['oid']; + } + // make one name the default and put the other ones into aliases + if (is_array($schema_entry['name'])) { + $aliases = $schema_entry['name']; + $schema_entry['name'] = array_shift($aliases); + $schema_entry['aliases'] = $aliases; + } + return $schema_entry; + } + + /** + * tokenizes the given value into an array of tokens + * + * @access private + * @param string String to parse + * @return array Array of tokens + */ + function _tokenize($value) + { + $tokens = array(); // array of tokens + $matches = array(); // matches[0] full pattern match, [1,2,3] subpatterns + + // this one is taken from perl-ldap, modified for php + $pattern = "/\s* (?:([()]) | ([^'\s()]+) | '((?:[^']+|'[^\s)])*)') \s*/x"; + + /** + * This one matches one big pattern wherin only one of the three subpatterns matched + * We are interested in the subpatterns that matched. If it matched its value will be + * non-empty and so it is a token. Tokens may be round brackets, a string, or a string + * enclosed by ' + */ + preg_match_all($pattern, $value, $matches); + + for ($i = 0; $i < count($matches[0]); $i++) { // number of tokens (full pattern match) + for ($j = 1; $j < 4; $j++) { // each subpattern + if (null != trim($matches[$j][$i])) { // pattern match in this subpattern + $tokens[$i] = trim($matches[$j][$i]); // this is the token + } + } + } + return $tokens; + } + } + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Net/LDAP/Search.php b/gulliver/thirdparty/pear/Net/LDAP/Search.php new file mode 100644 index 000000000..f6b67f460 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/Search.php @@ -0,0 +1,245 @@ +_setSearch($search, $link); + $this->_errorCode = ldap_errno($link); + } + + /** + * Returns an assosiative array of entry objects + * + * @return array Array of entry objects. + */ + function entries() + { + if ($this->count() == 0) { + return array(); + } + + $this->_elink = @ldap_first_entry( $this->_link,$this->_search); + $entry = new Net_LDAP_Entry($this->_link, + @ldap_get_dn($this->_link, $this->_elink), + @ldap_get_attributes($this->_link, $this->_elink)); + array_push($this->_entries, $entry); + + while ($this->_elink = @ldap_next_entry($this->_link,$this->_elink)) { + $entry = new Net_LDAP_Entry($this->_link, + @ldap_get_dn($this->_link, $this->_elink), + @ldap_get_attributes($this->_link, $this->_elink)); + array_push($this->_entries, $entry); + } + return $this->_entries; + } + + /** + * Get the next entry in the searchresult. + * + * @return mixed Net_LDAP_Entry object or false + */ + function shiftEntry() + { + if ($this->count() == 0 ) { + return false; + } + + if (is_null($this->_elink)) { + $this->_elink = @ldap_first_entry($this->_link, $this->_search); + $entry = new Net_LDAP_Entry($this->_link, + ldap_get_dn($this->_link, $this->_elink), + ldap_get_attributes($this->_link, $this->_elink)); + } else { + if (!$this->_elink = ldap_next_entry($this->_link, $this->_elink)) { + return false; + } + $entry = new Net_LDAP_Entry($this->_link, + ldap_get_dn($this->_link,$this->_elink), + ldap_get_attributes($this->_link,$this->_elink)); + } + return $entry; + } + + /** + * alias function of shiftEntry() for perl-ldap interface + * + * @see shiftEntry() + */ + function shift_entry() + { + $args = func_get_args(); + return call_user_func_array(array($this, 'shiftEntry'), $args); + } + + /** + * Retrieve the last entry of the searchset. NOT IMPLEMENTED + * + * @return object Net_LDAP_Error + */ + function pop_entry () + { + $this->raiseError("Not implemented"); + } + + /** + * Return entries sorted NOT IMPLEMENTED + * + * @param array Array of sort attributes + * @return object Net_LDAP_Error + */ + function sorted ($attrs = array()) + { + $this->raiseError("Not impelented"); + } + + /** + * Return entries as object NOT IMPLEMENTED + * + * @return object Net_LDAP_Error + */ + function as_struct () + { + $this->raiseError("Not implemented"); + } + + /** + * Set the searchobjects resourcelinks + * + * @access private + * @param resource Search result identifier + * @param resource Resource link identifier + */ + function _setSearch(&$search,&$link) + { + $this->_search = $search; + $this->_link = $link; + } + + /** + * Returns the number of entries in the searchresult + * + * @return int Number of entries in search. + */ + function count() + { + /* this catches the situation where OL returned errno 32 = no such object! */ + if (!$this->_search) { + return 0; + } + return @ldap_count_entries($this->_link, $this->_search); + } + + /** + * Get the errorcode the object got in its search. + * + * @return int The ldap error number. + */ + function getErrorCode() + { + return $this->_errorCode; + } + + /** Destructor + * + * @access protected + */ + function _Net_LDAP_Search() + { + @ldap_free_result($this->_search); + } + + /** + * Closes search result + */ + function done() + { + $this->_Net_LDAP_Search(); + } +} + +?> diff --git a/gulliver/thirdparty/pear/Net/LDAP/Util.php b/gulliver/thirdparty/pear/Net/LDAP/Util.php new file mode 100644 index 000000000..19f37020b --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/Util.php @@ -0,0 +1,132 @@ + + * @version $Revision: 4831 $ + */ +class Net_LDAP_Util extends PEAR +{ + /** + * Reference to LDAP object + * + * @access private + * @var object Net_LDAP + */ + var $_ldap = null; + + /** + * Net_LDAP_Schema object + * + * @access private + * @var object Net_LDAP_Schema + */ + var $_schema = null; + + /** + * Constructur + * + * Takes an LDAP object by reference and saves it. Then the schema will be fetched. + * + * @access public + * @param object Net_LDAP + */ + function Net_LDAP_Util(&$ldap) + { + if (is_object($ldap) && (strtolower(get_class($ldap)) == 'net_ldap')) { + $this->_ldap = $ldap; + $this->_schema = $this->_ldap->schema(); + if (Net_LDAP::isError($this->_schema)) $this->_schema = null; + } + } + + /** + * Encodes given attributes to UTF8 if needed + * + * This function takes attributes in an array and then checks against the schema if they need + * UTF8 encoding. If that is so, they will be encoded. An encoded array will be returned and + * can be used for adding or modifying. + * + * @access public + * @param array Array of attributes + * @return array Array of UTF8 encoded attributes + */ + function utf8Encode($attributes) + { + return $this->_utf8($attributes, 'utf8_encode'); + } + + /** + * Decodes the given attribute values + * + * @access public + * @param array Array of attributes + * @return array Array with decoded attribute values + */ + function utf8Decode($attributes) + { + return $this->_utf8($attributes, 'utf8_decode'); + } + + /** + * Encodes or decodes attribute values if needed + * + * @access private + * @param array Array of attributes + * @param array Function to apply to attribute values + * @return array Array of attributes with function applied to values + */ + function _utf8($attributes, $function) + { + if (!$this->_ldap || !$this->_schema || !function_exists($function)) { + return $attributes; + } + if (is_array($attributes) && count($attributes) > 0) { + foreach( $attributes as $k => $v ) { + $attr = $this->_schema->get('attribute', $k); + if (Net_LDAP::isError($attr)) { + continue; + } + if (false !== strpos($attr['syntax'], '1.3.6.1.4.1.1466.115.121.1.15')) { + if (is_array($v)) { + foreach ($v as $ak => $av ) { + $v[$ak] = call_user_func($function, $av ); + } + } else { + $v = call_user_func($function, $v); + } + } + $attributes[$k] = $v; + } + } + return $attributes; + } +} + +?> diff --git a/gulliver/thirdparty/pear/Net/LDAP/fg.php b/gulliver/thirdparty/pear/Net/LDAP/fg.php new file mode 100644 index 000000000..a7f0bfddf --- /dev/null +++ b/gulliver/thirdparty/pear/Net/LDAP/fg.php @@ -0,0 +1,38 @@ + $oAuthenticator->sSearchUser, + 'password' => $oAuthenticator->sSearchPassword, + 'host' => $oAuthenticator->sLdapServer, + 'base' => $oAuthenticator->sBaseDN, +); + +$oLdap =& Net_LDAP::connect($config); +if (PEAR::isError($oLdap)) { + var_dump($oLdap); + exit(0); +} + +$aParams = array( + 'scope' => 'sub', + 'attributes' => array('cn', 'dn', 'displayClass'), +); +$rootDn = $oAuthenticator->sBaseDN; +if (is_array($rootDn)) { + $rootDn = join(",", $rootDn); +} +$oResults = $oLdap->search($rootDn, '(objectClass=group)', $aParams); +foreach ($oResults->entries() as $oEntry) { + var_dump($oEntry->dn()); +} + diff --git a/gulliver/thirdparty/pear/Net/POP3.php b/gulliver/thirdparty/pear/Net/POP3.php new file mode 100644 index 000000000..316a1423b --- /dev/null +++ b/gulliver/thirdparty/pear/Net/POP3.php @@ -0,0 +1,1226 @@ + | +// | Co-Author: Damian Fernandez Sosa | +// +-----------------------------------------------------------------------+ +// +// $Id: POP3.php,v 1.2 2004/12/05 16:34:39 damian Exp $ + +require_once('Net/Socket.php'); + + + +/** +* +----------------------------- IMPORTANT ------------------------------+ +* | Usage of this class compared to native php extensions such as IMAP | +* | is slow and may be feature deficient. If available you are STRONGLY | +* | recommended to use the php extensions. | +* +----------------------------------------------------------------------+ +* +* POP3 Access Class +* +* For usage see the example script +*/ + +define('NET_POP3_STATE_DISCONNECTED', 1, true); +define('NET_POP3_STATE_AUTHORISATION', 2, true); +define('NET_POP3_STATE_TRANSACTION', 4, true); + +class Net_POP3 { + + /* + * Some basic information about the mail drop + * garnered from the STAT command + * + * @var array + */ + var $_maildrop; + + /* + * Used for APOP to store the timestamp + * + * @var string + */ + var $_timestamp; + + /* + * Timeout that is passed to the socket object + * + * @var integer + */ + var $_timeout; + + /* + * Socket object + * + * @var object + */ + var $_socket; + + /* + * Current state of the connection. Used with the + * constants defined above. + * + * @var integer + */ + var $_state; + + /* + * Hostname to connect to + * + * @var string + */ + var $_host; + + /* + * Port to connect to + * + * @var integer + */ + var $_port; + + /** + * To allow class debuging + * @var boolean + */ + var $_debug = false; + + + /** + * The auth methods this class support + * @var array + */ + //var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER'); + //Disabling DIGEST-MD5 for now + var $supportedAuthMethods=array( 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER'); + //var $supportedAuthMethods=array( 'CRAM-MD5', 'PLAIN' , 'LOGIN'); + //var $supportedAuthMethods=array( 'PLAIN' , 'LOGIN'); + + + /** + * The auth methods this class support + * @var array + */ + var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5'); + + + /** + * The capability response + * @var array + */ + var $_capability; + + /* + * Constructor. Sets up the object variables, and instantiates + * the socket object. + * + */ + + + function Net_POP3() + { + $this->_timestamp = ''; // Used for APOP + $this->_maildrop = array(); + $this->_timeout = 3; + $this->_state = NET_POP3_STATE_DISCONNECTED; + $this->_socket =& new Net_Socket(); + /* + * Include the Auth_SASL package. If the package is not available, + * we disable the authentication methods that depend upon it. + */ + if ((@include_once 'Auth/SASL.php') == false) { + if($this->_debug){ + echo "AUTH_SASL NOT PRESENT!\n"; + } + foreach($this->supportedSASLAuthMethods as $SASLMethod){ + $pos = array_search( $SASLMethod, $this->supportedAuthMethods ); + if($this->_debug){ + echo "DISABLING METHOD $SASLMethod\n"; + } + unset($this->supportedAuthMethods[$pos]); + } + } + + + + } + + + /** + * Handles the errors the class can find + * on the server + * + * @access private + * @return PEAR_Error + */ + + function _raiseError($msg, $code =-1) + { + include_once 'PEAR.php'; + return PEAR::raiseError($msg, $code); + } + + + + /* + * Connects to the given host on the given port. + * Also looks for the timestamp in the greeting + * needed for APOP authentication + * + * @param string $host Hostname/IP address to connect to + * @param string $port Port to use to connect to on host + * @return bool Success/Failure + */ + function connect($host = 'localhost', $port = 110) + { + $this->_host = $host; + $this->_port = $port; + + $result = $this->_socket->connect($host, $port, false, $this->_timeout); + if ($result === true) { + $data = $this->_recvLn(); + + if( $this->_checkResponse($data) ){ + // if the response begins with '+OK' ... +// if (@substr(strtoupper($data), 0, 3) == '+OK') { + // Check for string matching apop timestamp + if (preg_match('/<.+@.+>/U', $data, $matches)) { + $this->_timestamp = $matches[0]; + } + $this->_maildrop = array(); + $this->_state = NET_POP3_STATE_AUTHORISATION; + + return true; + } + } + + $this->_socket->disconnect(); + return false; + } + + /* + * Disconnect function. Sends the QUIT command + * and closes the socket. + * + * @return bool Success/Failure + */ + function disconnect() + { + return $this->_cmdQuit(); + } + + /* + * Performs the login procedure. If there is a timestamp + * stored, APOP will be tried first, then basic USER/PASS. + * + * @param string $user Username to use + * @param string $pass Password to use + * @param mixed $apop Whether to try APOP first, if used as string you can select the auth methd to use ( $pop3->login('validlogin', 'validpass', "CRAM-MD5"); + * Valid methods are: 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER' + * @return mixed true on Success/ PEAR_ERROR on error + */ + function login($user, $pass, $apop = true) + { + if ($this->_state == NET_POP3_STATE_AUTHORISATION) { + + if(PEAR::isError($ret= $this->_cmdAuthenticate($user , $pass , $apop ) ) ){ + return $ret; + } + if( ! PEAR::isError($ret)){ + $this->_state = NET_POP3_STATE_TRANSACTION; + return true; + } + + } + return $this->_raiseError('Generic login error' , 1); + } + + + + /** + * Parses the response from the capability command. Stores + * the result in $this->_capability + * + * @access private + */ + function _parseCapability() + { + + if(!PEAR::isError($data = $this->_sendCmd('CAPA'))){ + $data = $this->_getMultiline(); + }else { + // CAPA command not supported, reset data var + // to avoid Notice errors of preg_split on an object + $data = ''; + } + $data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY); + + for ($i = 0; $i < count($data); $i++) { + + $capa=''; + if (preg_match('/^([a-z,\-]+)( ((.*))|$)$/i', $data[$i], $matches)) { + + $capa=strtolower($matches[1]); + switch ($capa) { + case 'implementation': + $this->_capability['implementation'] = $matches[3]; + break; + case 'sasl': + $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); + break; + default : + $this->_capability[$capa] = $matches[2]; + break; + } + } + } + } + + + + + /** + * Returns the name of the best authentication method that the server + * has advertised. + * + * @param string if !=null,authenticate with this method ($userMethod). + * + * @return mixed Returns a string containing the name of the best + * supported authentication method or a PEAR_Error object + * if a failure condition is encountered. + * @access private + * @since 1.0 + */ + function _getBestAuthMethod($userMethod = null) + { + +/* + return 'USER'; + return 'APOP'; + return 'DIGEST-MD5'; + return 'CRAM-MD5'; +*/ + + + $this->_parseCapability(); + + //unset($this->_capability['sasl']); + + if( isset($this->_capability['sasl']) ){ + $serverMethods=$this->_capability['sasl']; + }else{ + $serverMethods=array('USER'); + // Check for timestamp before attempting APOP + if ($this->_timestamp != null) + { + $serverMethods[] = 'APOP'; + } + } + + if($userMethod !== null && $userMethod !== true ){ + $methods = array(); + $methods[] = $userMethod; + return $userMethod; + }else{ + $methods = $this->supportedAuthMethods; + } + + if( ($methods != null) && ($serverMethods != null)){ + + foreach ( $methods as $method ) { + + if ( in_array( $method , $serverMethods ) ) { + return $method; + } + } + $serverMethods=implode(',' , $serverMethods ); + $myMethods=implode(',' ,$this->supportedAuthMethods); + return $this->_raiseError("$method NOT supported authentication method!. This server " . + "supports these methods: $serverMethods, but I support $myMethods"); + }else{ + return $this->_raiseError("This server don't support any Auth methods"); + } + } + + + + + + + /* Handles the authentication using any known method + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * @param string The method to use ( if $usermethod == '' then the class chooses the best method (the stronger is the best ) ) + * + * @return mixed string or PEAR_Error + * + * @access private + * @since 1.0 + */ + function _cmdAuthenticate($uid , $pwd , $userMethod = null ) + { + + + if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) { + return $method; + } + + switch ($method) { + case 'DIGEST-MD5': + $result = $this->_authDigest_MD5( $uid , $pwd ); + break; + case 'CRAM-MD5': + $result = $this->_authCRAM_MD5( $uid , $pwd ); + break; + case 'LOGIN': + $result = $this->_authLOGIN( $uid , $pwd ); + break; + case 'PLAIN': + $result = $this->_authPLAIN( $uid , $pwd ); + break; + case 'APOP': + $result = $this->_cmdApop( $uid , $pwd ); + // if APOP fails fallback to USER auth + if( PEAR::isError( $result ) ){ + //echo "APOP FAILED!!!\n"; + $result=$this->_authUSER( $uid , $pwd ); + } + break; + case 'USER': + $result = $this->_authUSER( $uid , $pwd ); + break; + + + default : + $result = $this->_raiseError( "$method is not a supported authentication method" ); + break; + } + return $result; + } + + + + + /* Authenticates the user using the USER-PASS method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return mixed true on success or PEAR_Error on failure + * + * @access private + * @since 1.0 + */ + function _authUSER($user, $pass ) + { + if ( PEAR::isError($ret=$this->_cmdUser($user) ) ){ + return $ret; + } + if ( PEAR::isError($ret=$this->_cmdPass($pass) ) ){ + return $ret; + } + return true; + } + + + + + + + + + /* Authenticates the user using the PLAIN method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return array Returns an array containing the response + * + * @access private + * @since 1.0 + */ + function _authPLAIN($user, $pass ) + { + $cmd=sprintf('AUTH PLAIN %s', base64_encode( chr(0) . $user . chr(0) . $pass ) ); + + if ( PEAR::isError( $ret = $this->_send($cmd) ) ) { + return $ret; + } + if ( PEAR::isError( $challenge = $this->_recvLn() ) ){ + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + + return true; + } + + + + /* Authenticates the user using the PLAIN method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return array Returns an array containing the response + * + * @access private + * @since 1.0 + */ + function _authLOGIN($user, $pass ) + { + $this->_send('AUTH LOGIN'); + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + + + if ( PEAR::isError( $ret = $this->_send(sprintf('%s', base64_encode($user))) ) ) { + return $ret; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + + if ( PEAR::isError( $ret = $this->_send(sprintf('%s', base64_encode($pass))) ) ) { + return $ret; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + return $this->_checkResponse($challenge); + } + + + + + + /* Authenticates the user using the CRAM-MD5 method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return array Returns an array containing the response + * + * @access private + * @since 1.0 + */ + function _authCRAM_MD5($uid, $pwd ) + { + if ( PEAR::isError( $ret = $this->_send( 'AUTH CRAM-MD5' ) ) ) { + return $ret; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + + // remove '+ ' + + $challenge=substr($challenge,2); + + $challenge = base64_decode( $challenge ); + + $cram = &Auth_SASL::factory('crammd5'); + $auth_str = base64_encode( $cram->getResponse( $uid , $pwd , $challenge ) ); + + + if ( PEAR::isError($error = $this->_send( $auth_str ) ) ) { + return $error; + } + if ( PEAR::isError( $ret = $this->_recvLn() ) ) { + return $ret; + } + //echo "RET:$ret\n"; + return $this->_checkResponse($ret); + } + + + + /* Authenticates the user using the DIGEST-MD5 method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * @param string The efective user + * + * @return array Returns an array containing the response + * + * @access private + * @since 1.0 + */ + function _authDigest_MD5($uid, $pwd) + { + if ( PEAR::isError( $ret = $this->_send( 'AUTH DIGEST-MD5' ) ) ) { + return $ret; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + + // remove '+ ' + $challenge=substr($challenge,2); + + $challenge = base64_decode( $challenge ); + $digest = &Auth_SASL::factory('digestmd5'); + $auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge, "localhost", "pop3" )); + + if ( PEAR::isError($error = $this->_send( $auth_str ) ) ) { + return $error; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + if( PEAR::isError($ret=$this->_checkResponse($challenge) )){ + return $ret; + } + /* + * We don't use the protocol's third step because POP3 doesn't allow + * subsequent authentication, so we just silently ignore it. + */ + + if ( PEAR::isError( $challenge = $this->_send("\r\n") ) ) { + return $challenge ; + } + + if ( PEAR::isError( $challenge = $this->_recvLn() ) ) { + return $challenge; + } + + return $this->_checkResponse($challenge); + + + } + + + + + + + + + + + /* + * Sends the APOP command + * + * @param $user Username to send + * @param $pass Password to send + * @return bool Success/Failure + */ + function _cmdApop($user, $pass) + { + if ($this->_state == NET_POP3_STATE_AUTHORISATION) { + + if (!empty($this->_timestamp)) { + if(PEAR::isError($data = $this->_sendCmd('APOP ' . $user . ' ' . md5($this->_timestamp . $pass)) ) ){ + return $data; + } + $this->_state = NET_POP3_STATE_TRANSACTION; + return true; + } + } + return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State1'); + } + + + + + + + + + + + + + + + + /* + * Returns the raw headers of the specified message. + * + * @param integer $msg_id Message number + * @return mixed Either raw headers or false on error + */ + function getRawHeaders($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + return $this->_cmdTop($msg_id, 0); + } + + return false; + } + + /* + * Returns the headers of the specified message in an + * associative array. Array keys are the header names, array + * values are the header values. In the case of multiple headers + * having the same names, eg Received:, the array value will be + * an indexed array of all the header values. + * + * @param integer $msg_id Message number + * @return mixed Either array of headers or false on error + */ + function getParsedHeaders($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + + $raw_headers = rtrim($this->getRawHeaders($msg_id)); + + $raw_headers = preg_replace("/\r\n[ \t]+/", ' ', $raw_headers); // Unfold headers + $raw_headers = explode("\r\n", $raw_headers); + foreach ($raw_headers as $value) { + $name = substr($value, 0, $pos = strpos($value, ':')); + $value = ltrim(substr($value, $pos + 1)); + if (isset($headers[$name]) AND is_array($headers[$name])) { + $headers[$name][] = $value; + } elseif (isset($headers[$name])) { + $headers[$name] = array($headers[$name], $value); + } else { + $headers[$name] = $value; + } + } + + return $headers; + } + + return false; + } + + /* + * Returns the body of the message with given message number. + * + * @param integer $msg_id Message number + * @return mixed Either message body or false on error + */ + function getBody($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + $msg = $this->_cmdRetr($msg_id); + return substr($msg, strpos($msg, "\r\n\r\n")+4); + } + + return false; + } + + /* + * Returns the entire message with given message number. + * + * @param integer $msg_id Message number + * @return mixed Either entire message or false on error + */ + function getMsg($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + return $this->_cmdRetr($msg_id); + } + + return false; + } + + /* + * Returns the size of the maildrop + * + * @return mixed Either size of maildrop or false on error + */ + function getSize() + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if (isset($this->_maildrop['size'])) { + return $this->_maildrop['size']; + } else { + list(, $size) = $this->_cmdStat(); + return $size; + } + } + + return false; + } + + /* + * Returns number of messages in this maildrop + * + * @return mixed Either number of messages or false on error + */ + function numMsg() + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if (isset($this->_maildrop['num_msg'])) { + return $this->_maildrop['num_msg']; + } else { + list($num_msg, ) = $this->_cmdStat(); + return $num_msg; + } + } + + return false; + } + + /* + * Marks a message for deletion. Only will be deleted if the + * disconnect() method is called. + * + * @param integer $msg_id Message to delete + * @return bool Success/Failure + */ + function deleteMsg($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + return $this->_cmdDele($msg_id); + } + + return false; + } + + /* + * Combination of LIST/UIDL commands, returns an array + * of data + * + * @param integer $msg_id Optional message number + * @return mixed Array of data or false on error + */ + function getListing($msg_id = null) + { + + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if (!isset($msg_id)){ + + $list=array(); + if ($list = $this->_cmdList()) { + if ($uidl = $this->_cmdUidl()) { + foreach ($uidl as $i => $value) { + $list[$i]['uidl'] = $value['uidl']; + } + } + return $list; + }else{ + return array(); + } + } else { + if ($list = $this->_cmdList($msg_id) AND $uidl = $this->_cmdUidl($msg_id)) { + return array_merge($list, $uidl); + } + } + } + + return false; + } + + /* + * Sends the USER command + * + * @param string $user Username to send + * @return bool Success/Failure + */ + function _cmdUser($user) + { + if ($this->_state == NET_POP3_STATE_AUTHORISATION) { + return $this->_sendCmd('USER ' . $user); + } + return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State'); + } + + + /* + * Sends the PASS command + * + * @param string $pass Password to send + * @return bool Success/Failure + */ + function _cmdPass($pass) + { + if ($this->_state == NET_POP3_STATE_AUTHORISATION) { + return $this->_sendCmd('PASS ' . $pass); + } + return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State'); + } + + + /* + * Sends the STAT command + * + * @return mixed Indexed array of number of messages and + * maildrop size, or false on error. + */ + function _cmdStat() + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if(!PEAR::isError($data = $this->_sendCmd('STAT'))){ + sscanf($data, '+OK %d %d', $msg_num, $size); + $this->_maildrop['num_msg'] = $msg_num; + $this->_maildrop['size'] = $size; + + return array($msg_num, $size); + } + } + return false; + } + + + /* + * Sends the LIST command + * + * @param integer $msg_id Optional message number + * @return mixed Indexed array of msg_id/msg size or + * false on error + */ + function _cmdList($msg_id = null) + { + $return=array(); + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if (!isset($msg_id)) { + if(!PEAR::isError($data = $this->_sendCmd('LIST') )){ + $data = $this->_getMultiline(); + $data = explode("\r\n", $data); + foreach ($data as $line) { + if($line !=''){ + sscanf($line, '%s %s', $msg_id, $size); + $return[] = array('msg_id' => $msg_id, 'size' => $size); + } + } + return $return; + } + } else { + if(!PEAR::isError($data = $this->_sendCmd('LIST ' . $msg_id))){ + if($data!=''){ + sscanf($data, '+OK %d %d', $msg_id, $size); + return array('msg_id' => $msg_id, 'size' => $size); + } + return array(); + } + } + } + + + return false; + } + + + /* + * Sends the RETR command + * + * @param integer $msg_id The message number to retrieve + * @return mixed The message or false on error + */ + function _cmdRetr($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if(!PEAR::isError($data = $this->_sendCmd('RETR ' . $msg_id) )){ + $data = $this->_getMultiline(); + return $data; + } + } + + return false; + } + + + /* + * Sends the DELE command + * + * @param integer $msg_id Message number to mark as deleted + * @return bool Success/Failure + */ + function _cmdDele($msg_id) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + return $this->_sendCmd('DELE ' . $msg_id); + } + + return false; + } + + + /* + * Sends the NOOP command + * + * @return bool Success/Failure + */ + function _cmdNoop() + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if(!PEAR::isError($data = $this->_sendCmd('NOOP'))){ + return true; + } + } + + return false; + } + + /* + * Sends the RSET command + * + * @return bool Success/Failure + */ + function _cmdRset() + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + if(!PEAR::isError($data = $this->_sendCmd('RSET'))){ + return true; + } + } + + return false; + } + + /* + * Sends the QUIT command + * + * @return bool Success/Failure + */ + function _cmdQuit() + { + $data = $this->_sendCmd('QUIT'); + $this->_state = NET_POP3_STATE_DISCONNECTED; + $this->_socket->disconnect(); + + return (bool)$data; + } + + + /* + * Sends the TOP command + * + * @param integer $msg_id Message number + * @param integer $num_lines Number of lines to retrieve + * @return mixed Message data or false on error + */ + function _cmdTop($msg_id, $num_lines) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + + if(!PEAR::isError($data = $this->_sendCmd('TOP ' . $msg_id . ' ' . $num_lines))){ + return $this->_getMultiline(); + } + } + + return false; + } + + /* + * Sends the UIDL command + * + * @param integer $msg_id Message number + * @return mixed indexed array of msg_id/uidl or false on error + */ + function _cmdUidl($msg_id = null) + { + if ($this->_state == NET_POP3_STATE_TRANSACTION) { + + if (!isset($msg_id)) { + if(!PEAR::isError($data = $this->_sendCmd('UIDL') )){ + $data = $this->_getMultiline(); + $data = explode("\r\n", $data); + foreach ($data as $line) { + sscanf($line, '%d %s', $msg_id, $uidl); + $return[] = array('msg_id' => $msg_id, 'uidl' => $uidl); + } + + return $return; + } + } else { + + $data = $this->_sendCmd('UIDL ' . $msg_id); + sscanf($data, '+OK %d %s', $msg_id, $uidl); + return array('msg_id' => $msg_id, 'uidl' => $uidl); + } + } + + return false; + } + + + + + + + + + + /* + * Sends a command, checks the reponse, and + * if good returns the reponse, other wise + * returns false. + * + * @param string $cmd Command to send (\r\n will be appended) + * @return mixed First line of response if successful, otherwise false + */ + function _sendCmd($cmd) + { + if (PEAR::isError($result = $this->_send($cmd) )){ + return $result ; + } + + if (PEAR::isError($data = $this->_recvLn() )){ + return $data; + } + + if ( strtoupper(substr($data, 0, 3)) == '+OK') { + return $data; + } + + + return $this->_raiseError($data); + } + + /* + * Reads a multiline reponse and returns the data + * + * @return string The reponse. + */ + function _getMultiline() + { + $data = ''; + while(!PEAR::isError($tmp = $this->_recvLn() ) ) { + if($tmp == '.'){ + return substr($data, 0, -2); + } + if (substr($tmp, 0, 2) == '..') { + $tmp = substr($tmp, 1); + } + $data .= $tmp . "\r\n"; + } + return substr($data, 0, -2); + } + + + /** + * Sets the bebug state + * + * @param bool $debug + * @access public + * @return void + */ + function setDebug($debug=true) + { + $this->_debug=$debug; + } + + + + + + /** + * Send the given string of data to the server. + * + * @param string $data The string of data to send. + * + * @return mixed True on success or a PEAR_Error object on failure. + * + * @access private + * @since 1.0 + */ + function _send($data) + { + if ($this->_debug) { + echo "C: $data\n"; + } + + if (PEAR::isError($error = $this->_socket->writeLine($data))) { + return $this->_raiseError('Failed to write to socket: ' . $error->getMessage()); + } + return true; + } + + + + /** + * Receive the given string of data from the server. + * + * @return mixed a line of response on success or a PEAR_Error object on failure. + * + * @access private + * @since 1.0 + */ + function _recvLn() + { + if (PEAR::isError( $lastline = $this->_socket->readLine( 8192 ) ) ) { + return $this->_raiseError('Failed to write to socket: ' . $this->lastline->getMessage() ); + } + if($this->_debug){ + // S: means this data was sent by the POP3 Server + echo "S:$lastline\n" ; + } + return $lastline; + } + + /** + * Checks de server Response + * + * @param string $response the response + * @return mixed true on success or a PEAR_Error object on failure. + * + * @access private + * @since 1.3.3 + */ + + function _checkResponse($response) + { + if (@substr(strtoupper($response), 0, 3) == '+OK') { + return true; + }else{ + if (@substr(strtoupper($response), 0, 4) == '-ERR') { + return $this->_raiseError($response); + }else{ + if (@substr(strtoupper($response), 0, 2) == '+ ') { + return true; + } + } + + } + return $this->_raiseError("Unknown Response ($response)"); + } + + + +} + +?> diff --git a/gulliver/thirdparty/pear/Net/SMTP.php b/gulliver/thirdparty/pear/Net/SMTP.php new file mode 100644 index 000000000..d632258d6 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/SMTP.php @@ -0,0 +1,1082 @@ + | +// | Jon Parise | +// | Damian Alejandro Fernandez Sosa | +// +----------------------------------------------------------------------+ +// +// $Id: SMTP.php,v 1.63 2008/06/10 05:39:12 jon Exp $ + +require_once 'PEAR.php'; +require_once 'Net/Socket.php'; + +/** + * Provides an implementation of the SMTP protocol using PEAR's + * Net_Socket:: class. + * + * @package Net_SMTP + * @author Chuck Hagenbuch + * @author Jon Parise + * @author Damian Alejandro Fernandez Sosa + * + * @example basic.php A basic implementation of the Net_SMTP package. + */ +class Net_SMTP +{ + /** + * The server to connect to. + * @var string + * @access public + */ + var $host = 'localhost'; + + /** + * The port to connect to. + * @var int + * @access public + */ + var $port = 25; + + /** + * The value to give when sending EHLO or HELO. + * @var string + * @access public + */ + var $localhost = 'localhost'; + + /** + * List of supported authentication methods, in preferential order. + * @var array + * @access public + */ + var $auth_methods = array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN', 'PLAIN'); + + /** + * Use SMTP command pipelining (specified in RFC 2920) if the SMTP + * server supports it. + * + * When pipeling is enabled, rcptTo(), mailFrom(), sendFrom(), + * somlFrom() and samlFrom() do not wait for a response from the + * SMTP server but return immediately. + * + * @var bool + * @access public + */ + var $pipelining = false; + + /** + * Number of pipelined commands. + * @var int + * @access private + */ + var $_pipelined_commands = 0; + + /** + * Should debugging output be enabled? + * @var boolean + * @access private + */ + var $_debug = false; + + /** + * The socket resource being used to connect to the SMTP server. + * @var resource + * @access private + */ + var $_socket = null; + + /** + * The most recent server response code. + * @var int + * @access private + */ + var $_code = -1; + + /** + * The most recent server response arguments. + * @var array + * @access private + */ + var $_arguments = array(); + + /** + * Stores detected features of the SMTP server. + * @var array + * @access private + */ + var $_esmtp = array(); + + /** + * Instantiates a new Net_SMTP object, overriding any defaults + * with parameters that are passed in. + * + * If you have SSL support in PHP, you can connect to a server + * over SSL using an 'ssl://' prefix: + * + * // 465 is a common smtps port. + * $smtp = new Net_SMTP('ssl://mail.host.com', 465); + * $smtp->connect(); + * + * @param string $host The server to connect to. + * @param integer $port The port to connect to. + * @param string $localhost The value to give when sending EHLO or HELO. + * @param boolean $pipeling Use SMTP command pipelining + * + * @access public + * @since 1.0 + */ + function Net_SMTP($host = null, $port = null, $localhost = null, $pipelining = false) + { + if (isset($host)) { + $this->host = $host; + } + if (isset($port)) { + $this->port = $port; + } + if (isset($localhost)) { + $this->localhost = $localhost; + } + $this->pipelining = $pipelining; + + $this->_socket = new Net_Socket(); + + /* Include the Auth_SASL package. If the package is not + * available, we disable the authentication methods that + * depend upon it. */ + if ((@include_once 'Auth/SASL.php') === false) { + $pos = array_search('DIGEST-MD5', $this->auth_methods); + unset($this->auth_methods[$pos]); + $pos = array_search('CRAM-MD5', $this->auth_methods); + unset($this->auth_methods[$pos]); + } + } + + /** + * Set the value of the debugging flag. + * + * @param boolean $debug New value for the debugging flag. + * + * @access public + * @since 1.1.0 + */ + function setDebug($debug) + { + $this->_debug = $debug; + } + + /** + * Send the given string of data to the server. + * + * @param string $data The string of data to send. + * + * @return mixed True on success or a PEAR_Error object on failure. + * + * @access private + * @since 1.1.0 + */ + function _send($data) + { + if ($this->_debug) { + echo "DEBUG: Send: $data\n"; + } + + if (PEAR::isError($error = $this->_socket->write($data))) { + return PEAR::raiseError('Failed to write to socket: ' . + $error->getMessage()); + } + + return true; + } + + /** + * Send a command to the server with an optional string of + * arguments. A carriage return / linefeed (CRLF) sequence will + * be appended to each command string before it is sent to the + * SMTP server - an error will be thrown if the command string + * already contains any newline characters. Use _send() for + * commands that must contain newlines. + * + * @param string $command The SMTP command to send to the server. + * @param string $args A string of optional arguments to append + * to the command. + * + * @return mixed The result of the _send() call. + * + * @access private + * @since 1.1.0 + */ + function _put($command, $args = '') + { + if (!empty($args)) { + $command .= ' ' . $args; + } + + if (strcspn($command, "\r\n") !== strlen($command)) { + return PEAR::raiseError('Commands cannot contain newlines'); + } + + return $this->_send($command . "\r\n"); + } + + /** + * Read a reply from the SMTP server. The reply consists of a response + * code and a response message. + * + * @param mixed $valid The set of valid response codes. These + * may be specified as an array of integer + * values or as a single integer value. + * @param bool $later Do not parse the response now, but wait + * until the last command in the pipelined + * command group + * + * @return mixed True if the server returned a valid response code or + * a PEAR_Error object is an error condition is reached. + * + * @access private + * @since 1.1.0 + * + * @see getResponse + */ + function _parseResponse($valid, $later = false) + { + $this->_code = -1; + $this->_arguments = array(); + + if ($later) { + $this->_pipelined_commands++; + return true; + } + + for ($i = 0; $i <= $this->_pipelined_commands; $i++) { + while ($line = $this->_socket->readLine()) { + if ($this->_debug) { + echo "DEBUG: Recv: $line\n"; + } + + /* If we receive an empty line, the connection has been closed. */ + if (empty($line)) { + $this->disconnect(); + return PEAR::raiseError('Connection was unexpectedly closed'); + } + + /* Read the code and store the rest in the arguments array. */ + $code = substr($line, 0, 3); + $this->_arguments[] = trim(substr($line, 4)); + + /* Check the syntax of the response code. */ + if (is_numeric($code)) { + $this->_code = (int)$code; + } else { + $this->_code = -1; + break; + } + + /* If this is not a multiline response, we're done. */ + if (substr($line, 3, 1) != '-') { + break; + } + } + } + + $this->_pipelined_commands = 0; + + /* Compare the server's response code with the valid code/codes. */ + if (is_int($valid) && ($this->_code === $valid)) { + return true; + } elseif (is_array($valid) && in_array($this->_code, $valid, true)) { + return true; + } + + return PEAR::raiseError('Invalid response code received from server', + $this->_code); + } + + /** + * Return a 2-tuple containing the last response from the SMTP server. + * + * @return array A two-element array: the first element contains the + * response code as an integer and the second element + * contains the response's arguments as a string. + * + * @access public + * @since 1.1.0 + */ + function getResponse() + { + return array($this->_code, join("\n", $this->_arguments)); + } + + /** + * Attempt to connect to the SMTP server. + * + * @param int $timeout The timeout value (in seconds) for the + * socket connection. + * @param bool $persistent Should a persistent socket connection + * be used? + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function connect($timeout = null, $persistent = false) + { + $result = $this->_socket->connect($this->host, $this->port, + $persistent, $timeout); + if (PEAR::isError($result)) { + return PEAR::raiseError('Failed to connect socket: ' . + $result->getMessage()); + } + + if (PEAR::isError($error = $this->_parseResponse(220))) { + return $error; + } + if (PEAR::isError($error = $this->_negotiate())) { + return $error; + } + + return true; + } + + /** + * Attempt to disconnect from the SMTP server. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function disconnect() + { + if (PEAR::isError($error = $this->_put('QUIT'))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(221))) { + return $error; + } + if (PEAR::isError($error = $this->_socket->disconnect())) { + return PEAR::raiseError('Failed to disconnect socket: ' . + $error->getMessage()); + } + + return true; + } + + /** + * Attempt to send the EHLO command and obtain a list of ESMTP + * extensions available, and failing that just send HELO. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * + * @access private + * @since 1.1.0 + */ + function _negotiate() + { + if (PEAR::isError($error = $this->_put('EHLO', $this->localhost))) { + return $error; + } + + if (PEAR::isError($this->_parseResponse(250))) { + /* If we receive a 503 response, we're already authenticated. */ + if ($this->_code === 503) { + return true; + } + + /* If the EHLO failed, try the simpler HELO command. */ + if (PEAR::isError($error = $this->_put('HELO', $this->localhost))) { + return $error; + } + if (PEAR::isError($this->_parseResponse(250))) { + return PEAR::raiseError('HELO was not accepted: ', $this->_code); + } + + return true; + } + + foreach ($this->_arguments as $argument) { + $verb = strtok($argument, ' '); + $arguments = substr($argument, strlen($verb) + 1, + strlen($argument) - strlen($verb) - 1); + $this->_esmtp[$verb] = $arguments; + } + + if (!isset($this->_esmtp['PIPELINING'])) { + $this->pipelining = false; + } + + return true; + } + + /** + * Returns the name of the best authentication method that the server + * has advertised. + * + * @return mixed Returns a string containing the name of the best + * supported authentication method or a PEAR_Error object + * if a failure condition is encountered. + * @access private + * @since 1.1.0 + */ + function _getBestAuthMethod() + { + $available_methods = explode(' ', $this->_esmtp['AUTH']); + + foreach ($this->auth_methods as $method) { + if (in_array($method, $available_methods)) { + return $method; + } + } + + return PEAR::raiseError('No supported authentication methods'); + } + + /** + * Attempt to do SMTP authentication. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * @param string The requested authentication method. If none is + * specified, the best supported method will be used. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function auth($uid, $pwd , $method = '') + { + if (empty($this->_esmtp['AUTH'])) { + if (version_compare(PHP_VERSION, '5.1.0', '>=')) { + if (!isset($this->_esmtp['STARTTLS'])) { + return PEAR::raiseError('SMTP server does not support authentication'); + } + if (PEAR::isError($result = $this->_put('STARTTLS'))) { + return $result; + } + if (PEAR::isError($result = $this->_parseResponse(220))) { + return $result; + } + if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) { + return $result; + } elseif ($result !== true) { + return PEAR::raiseError('STARTTLS failed'); + } + + /* Send EHLO again to recieve the AUTH string from the + * SMTP server. */ + $this->_negotiate(); + if (empty($this->_esmtp['AUTH'])) { + return PEAR::raiseError('SMTP server does not support authentication'); + } + } else { + return PEAR::raiseError('SMTP server does not support authentication'); + } + } + + /* If no method has been specified, get the name of the best + * supported method advertised by the SMTP server. */ + if (empty($method)) { + if (PEAR::isError($method = $this->_getBestAuthMethod())) { + /* Return the PEAR_Error object from _getBestAuthMethod(). */ + return $method; + } + } else { + $method = strtoupper($method); + if (!in_array($method, $this->auth_methods)) { + return PEAR::raiseError("$method is not a supported authentication method"); + } + } + + switch ($method) { + case 'DIGEST-MD5': + $result = $this->_authDigest_MD5($uid, $pwd); + break; + + case 'CRAM-MD5': + $result = $this->_authCRAM_MD5($uid, $pwd); + break; + + case 'LOGIN': + $result = $this->_authLogin($uid, $pwd); + break; + + case 'PLAIN': + $result = $this->_authPlain($uid, $pwd); + break; + + default: + $result = PEAR::raiseError("$method is not a supported authentication method"); + break; + } + + /* If an error was encountered, return the PEAR_Error object. */ + if (PEAR::isError($result)) { + return $result; + } + + return true; + } + + /** + * Authenticates the user using the DIGEST-MD5 method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access private + * @since 1.1.0 + */ + function _authDigest_MD5($uid, $pwd) + { + if (PEAR::isError($error = $this->_put('AUTH', 'DIGEST-MD5'))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + /* 503: Error: already authenticated */ + if ($this->_code === 503) { + return true; + } + return $error; + } + + $challenge = base64_decode($this->_arguments[0]); + $digest = &Auth_SASL::factory('digestmd5'); + $auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge, + $this->host, "smtp")); + + if (PEAR::isError($error = $this->_put($auth_str))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + return $error; + } + + /* We don't use the protocol's third step because SMTP doesn't + * allow subsequent authentication, so we just silently ignore + * it. */ + if (PEAR::isError($error = $this->_put(''))) { + return $error; + } + /* 235: Authentication successful */ + if (PEAR::isError($error = $this->_parseResponse(235))) { + return $error; + } + } + + /** + * Authenticates the user using the CRAM-MD5 method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access private + * @since 1.1.0 + */ + function _authCRAM_MD5($uid, $pwd) + { + if (PEAR::isError($error = $this->_put('AUTH', 'CRAM-MD5'))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + /* 503: Error: already authenticated */ + if ($this->_code === 503) { + return true; + } + return $error; + } + + $challenge = base64_decode($this->_arguments[0]); + $cram = &Auth_SASL::factory('crammd5'); + $auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge)); + + if (PEAR::isError($error = $this->_put($auth_str))) { + return $error; + } + + /* 235: Authentication successful */ + if (PEAR::isError($error = $this->_parseResponse(235))) { + return $error; + } + } + + /** + * Authenticates the user using the LOGIN method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access private + * @since 1.1.0 + */ + function _authLogin($uid, $pwd) + { + if (PEAR::isError($error = $this->_put('AUTH', 'LOGIN'))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + /* 503: Error: already authenticated */ + if ($this->_code === 503) { + return true; + } + return $error; + } + + if (PEAR::isError($error = $this->_put(base64_encode($uid)))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + return $error; + } + + if (PEAR::isError($error = $this->_put(base64_encode($pwd)))) { + return $error; + } + + /* 235: Authentication successful */ + if (PEAR::isError($error = $this->_parseResponse(235))) { + return $error; + } + + return true; + } + + /** + * Authenticates the user using the PLAIN method. + * + * @param string The userid to authenticate as. + * @param string The password to authenticate with. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access private + * @since 1.1.0 + */ + function _authPlain($uid, $pwd) + { + if (PEAR::isError($error = $this->_put('AUTH', 'PLAIN'))) { + return $error; + } + /* 334: Continue authentication request */ + if (PEAR::isError($error = $this->_parseResponse(334))) { + /* 503: Error: already authenticated */ + if ($this->_code === 503) { + return true; + } + return $error; + } + + $auth_str = base64_encode(chr(0) . $uid . chr(0) . $pwd); + + if (PEAR::isError($error = $this->_put($auth_str))) { + return $error; + } + + /* 235: Authentication successful */ + if (PEAR::isError($error = $this->_parseResponse(235))) { + return $error; + } + + return true; + } + + /** + * Send the HELO command. + * + * @param string The domain name to say we are. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function helo($domain) + { + if (PEAR::isError($error = $this->_put('HELO', $domain))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250))) { + return $error; + } + + return true; + } + + /** + * Return the list of SMTP service extensions advertised by the server. + * + * @return array The list of SMTP service extensions. + * @access public + * @since 1.3 + */ + function getServiceExtensions() + { + return $this->_esmtp; + } + + /** + * Send the MAIL FROM: command. + * + * @param string $sender The sender (reverse path) to set. + * @param string $params String containing additional MAIL parameters, + * such as the NOTIFY flags defined by RFC 1891 + * or the VERP protocol. + * + * If $params is an array, only the 'verp' option + * is supported. If 'verp' is true, the XVERP + * parameter is appended to the MAIL command. If + * the 'verp' value is a string, the full + * XVERP=value parameter is appended. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function mailFrom($sender, $params = null) + { + $args = "FROM:<$sender>"; + + /* Support the deprecated array form of $params. */ + if (is_array($params) && isset($params['verp'])) { + /* XVERP */ + if ($params['verp'] === true) { + $args .= ' XVERP'; + + /* XVERP=something */ + } elseif (trim($params['verp'])) { + $args .= ' XVERP=' . $params['verp']; + } + } elseif (is_string($params)) { + $args .= ' ' . $params; + } + + if (PEAR::isError($error = $this->_put('MAIL', $args))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Send the RCPT TO: command. + * + * @param string $recipient The recipient (forward path) to add. + * @param string $params String containing additional RCPT parameters, + * such as the NOTIFY flags defined by RFC 1891. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * + * @access public + * @since 1.0 + */ + function rcptTo($recipient, $params = null) + { + $args = "TO:<$recipient>"; + if (is_string($params)) { + $args .= ' ' . $params; + } + + if (PEAR::isError($error = $this->_put('RCPT', $args))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(array(250, 251), $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Quote the data so that it meets SMTP standards. + * + * This is provided as a separate public function to facilitate + * easier overloading for the cases where it is desirable to + * customize the quoting behavior. + * + * @param string $data The message text to quote. The string must be passed + * by reference, and the text will be modified in place. + * + * @access public + * @since 1.2 + */ + function quotedata(&$data) + { + /* Change Unix (\n) and Mac (\r) linefeeds into + * Internet-standard CRLF (\r\n) linefeeds. */ + $data = preg_replace(array('/(?_esmtp['SIZE']) && ($this->_esmtp['SIZE'] > 0)) { + if (strlen($data) >= $this->_esmtp['SIZE']) { + $this->disconnect(); + return PEAR::raiseError('Message size excedes the server limit'); + } + } + + /* Quote the data based on the SMTP standards. */ + $this->quotedata($data); + + if (PEAR::isError($error = $this->_put('DATA'))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(354))) { + return $error; + } + + if (PEAR::isError($result = $this->_send($data . "\r\n.\r\n"))) { + return $result; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Send the SEND FROM: command. + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.2.6 + */ + function sendFrom($path) + { + if (PEAR::isError($error = $this->_put('SEND', "FROM:<$path>"))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Backwards-compatibility wrapper for sendFrom(). + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * + * @access public + * @since 1.0 + * @deprecated 1.2.6 + */ + function send_from($path) + { + return sendFrom($path); + } + + /** + * Send the SOML FROM: command. + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.2.6 + */ + function somlFrom($path) + { + if (PEAR::isError($error = $this->_put('SOML', "FROM:<$path>"))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Backwards-compatibility wrapper for somlFrom(). + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * + * @access public + * @since 1.0 + * @deprecated 1.2.6 + */ + function soml_from($path) + { + return somlFrom($path); + } + + /** + * Send the SAML FROM: command. + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.2.6 + */ + function samlFrom($path) + { + if (PEAR::isError($error = $this->_put('SAML', "FROM:<$path>"))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Backwards-compatibility wrapper for samlFrom(). + * + * @param string The reverse path to send. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * + * @access public + * @since 1.0 + * @deprecated 1.2.6 + */ + function saml_from($path) + { + return samlFrom($path); + } + + /** + * Send the RSET command. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function rset() + { + if (PEAR::isError($error = $this->_put('RSET'))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { + return $error; + } + + return true; + } + + /** + * Send the VRFY command. + * + * @param string The string to verify + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function vrfy($string) + { + /* Note: 251 is also a valid response code */ + if (PEAR::isError($error = $this->_put('VRFY', $string))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(array(250, 252)))) { + return $error; + } + + return true; + } + + /** + * Send the NOOP command. + * + * @return mixed Returns a PEAR_Error with an error message on any + * kind of failure, or true on success. + * @access public + * @since 1.0 + */ + function noop() + { + if (PEAR::isError($error = $this->_put('NOOP'))) { + return $error; + } + if (PEAR::isError($error = $this->_parseResponse(250))) { + return $error; + } + + return true; + } + + /** + * Backwards-compatibility method. identifySender()'s functionality is + * now handled internally. + * + * @return boolean This method always return true. + * + * @access public + * @since 1.0 + */ + function identifySender() + { + return true; + } + +} diff --git a/gulliver/thirdparty/pear/Net/Socket.php b/gulliver/thirdparty/pear/Net/Socket.php new file mode 100644 index 000000000..d7a049566 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/Socket.php @@ -0,0 +1,576 @@ + | +// | Chuck Hagenbuch | +// +----------------------------------------------------------------------+ +// +// $Id: Socket.php,v 1.31 2007/05/04 04:30:29 chagenbu Exp $ + +require_once 'PEAR.php'; + +define('NET_SOCKET_READ', 1); +define('NET_SOCKET_WRITE', 2); +define('NET_SOCKET_ERROR', 4); + +/** + * Generalized Socket class. + * + * @version 1.1 + * @author Stig Bakken + * @author Chuck Hagenbuch + */ +class Net_Socket extends PEAR { + + /** + * Socket file pointer. + * @var resource $fp + */ + var $fp = null; + + /** + * Whether the socket is blocking. Defaults to true. + * @var boolean $blocking + */ + var $blocking = true; + + /** + * Whether the socket is persistent. Defaults to false. + * @var boolean $persistent + */ + var $persistent = false; + + /** + * The IP address to connect to. + * @var string $addr + */ + var $addr = ''; + + /** + * The port number to connect to. + * @var integer $port + */ + var $port = 0; + + /** + * Number of seconds to wait on socket connections before assuming + * there's no more data. Defaults to no timeout. + * @var integer $timeout + */ + var $timeout = false; + + /** + * Number of bytes to read at a time in readLine() and + * readAll(). Defaults to 2048. + * @var integer $lineLength + */ + var $lineLength = 2048; + + /** + * Connect to the specified port. If called when the socket is + * already connected, it disconnects and connects again. + * + * @param string $addr IP address or host name. + * @param integer $port TCP port number. + * @param boolean $persistent (optional) Whether the connection is + * persistent (kept open between requests + * by the web server). + * @param integer $timeout (optional) How long to wait for data. + * @param array $options See options for stream_context_create. + * + * @access public + * + * @return boolean | PEAR_Error True on success or a PEAR_Error on failure. + */ + function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) + { + if (is_resource($this->fp)) { + @fclose($this->fp); + $this->fp = null; + } + + if (!$addr) { + return $this->raiseError('$addr cannot be empty'); + } elseif (strspn($addr, '.0123456789') == strlen($addr) || + strstr($addr, '/') !== false) { + $this->addr = $addr; + } else { + $this->addr = @gethostbyname($addr); + } + + $this->port = $port % 65536; + + if ($persistent !== null) { + $this->persistent = $persistent; + } + + if ($timeout !== null) { + $this->timeout = $timeout; + } + + $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; + $errno = 0; + $errstr = ''; + if ($options && function_exists('stream_context_create')) { + if ($this->timeout) { + $timeout = $this->timeout; + } else { + $timeout = 0; + } + $context = stream_context_create($options); + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); + } else { + if ($this->timeout) { + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout); + } else { + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr); + } + } + + if (!$fp) { + return $this->raiseError($errstr, $errno); + } + + $this->fp = $fp; + + return $this->setBlocking($this->blocking); + } + + /** + * Disconnects from the peer, closes the socket. + * + * @access public + * @return mixed true on success or an error object otherwise + */ + function disconnect() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + @fclose($this->fp); + $this->fp = null; + return true; + } + + /** + * Find out if the socket is in blocking mode. + * + * @access public + * @return boolean The current blocking mode. + */ + function isBlocking() + { + return $this->blocking; + } + + /** + * Sets whether the socket connection should be blocking or + * not. A read call to a non-blocking socket will return immediately + * if there is no data available, whereas it will block until there + * is data for blocking sockets. + * + * @param boolean $mode True for blocking sockets, false for nonblocking. + * @access public + * @return mixed true on success or an error object otherwise + */ + function setBlocking($mode) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $this->blocking = $mode; + socket_set_blocking($this->fp, $this->blocking); + return true; + } + + /** + * Sets the timeout value on socket descriptor, + * expressed in the sum of seconds and microseconds + * + * @param integer $seconds Seconds. + * @param integer $microseconds Microseconds. + * @access public + * @return mixed true on success or an error object otherwise + */ + function setTimeout($seconds, $microseconds) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return socket_set_timeout($this->fp, $seconds, $microseconds); + } + + /** + * Sets the file buffering size on the stream. + * See php's stream_set_write_buffer for more information. + * + * @param integer $size Write buffer size. + * @access public + * @return mixed on success or an PEAR_Error object otherwise + */ + function setWriteBuffer($size) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $returned = stream_set_write_buffer($this->fp, $code); + if ($returned == 0) { + return true; + } + return $this->raiseError('Cannot set write buffer.'); + } + + /** + * Returns information about an existing socket resource. + * Currently returns four entries in the result array: + * + *

    + * timed_out (bool) - The socket timed out waiting for data
    + * blocked (bool) - The socket was blocked
    + * eof (bool) - Indicates EOF event
    + * unread_bytes (int) - Number of bytes left in the socket buffer
    + *

    + * + * @access public + * @return mixed Array containing information about existing socket resource or an error object otherwise + */ + function getStatus() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return socket_get_status($this->fp); + } + + /** + * Get a specified line of data + * + * @access public + * @return $size bytes of data from the socket, or a PEAR_Error if + * not connected. + */ + function gets($size) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return @fgets($this->fp, $size); + } + + /** + * Read a specified amount of data. This is guaranteed to return, + * and has the added benefit of getting everything in one fread() + * chunk; if you know the size of the data you're getting + * beforehand, this is definitely the way to go. + * + * @param integer $size The number of bytes to read from the socket. + * @access public + * @return $size bytes of data from the socket, or a PEAR_Error if + * not connected. + */ + function read($size) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return @fread($this->fp, $size); + } + + /** + * Write a specified amount of data. + * + * @param string $data Data to write. + * @param integer $blocksize Amount of data to write at once. + * NULL means all at once. + * + * @access public + * @return mixed true on success or an error object otherwise + */ + function write($data, $blocksize = null) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + if (is_null($blocksize) && !OS_WINDOWS) { + return fwrite($this->fp, $data); + } else { + if (is_null($blocksize)) { + $blocksize = 1024; + } + + $pos = 0; + $size = strlen($data); + while ($pos < $size) { + $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); + if ($written === false) { + return false; + } + $pos += $written; + } + + return $pos; + } + } + + /** + * Write a line of data to the socket, followed by a trailing "\r\n". + * + * @access public + * @return mixed fputs result, or an error + */ + function writeLine($data) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return fwrite($this->fp, $data . "\r\n"); + } + + /** + * Tests for end-of-file on a socket descriptor. + * + * Also returns true if the socket is disconnected. + * + * @access public + * @return bool + */ + function eof() + { + return (!is_resource($this->fp) || feof($this->fp)); + } + + /** + * Reads a byte of data + * + * @access public + * @return 1 byte of data from the socket, or a PEAR_Error if + * not connected. + */ + function readByte() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + return ord(@fread($this->fp, 1)); + } + + /** + * Reads a word of data + * + * @access public + * @return 1 word of data from the socket, or a PEAR_Error if + * not connected. + */ + function readWord() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $buf = @fread($this->fp, 2); + return (ord($buf[0]) + (ord($buf[1]) << 8)); + } + + /** + * Reads an int of data + * + * @access public + * @return integer 1 int of data from the socket, or a PEAR_Error if + * not connected. + */ + function readInt() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $buf = @fread($this->fp, 4); + return (ord($buf[0]) + (ord($buf[1]) << 8) + + (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); + } + + /** + * Reads a zero-terminated string of data + * + * @access public + * @return string, or a PEAR_Error if + * not connected. + */ + function readString() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $string = ''; + while (($char = @fread($this->fp, 1)) != "\x00") { + $string .= $char; + } + return $string; + } + + /** + * Reads an IP Address and returns it in a dot formated string + * + * @access public + * @return Dot formated string, or a PEAR_Error if + * not connected. + */ + function readIPAddress() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $buf = @fread($this->fp, 4); + return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]), + ord($buf[2]), ord($buf[3])); + } + + /** + * Read until either the end of the socket or a newline, whichever + * comes first. Strips the trailing newline from the returned data. + * + * @access public + * @return All available data up to a newline, without that + * newline, or until the end of the socket, or a PEAR_Error if + * not connected. + */ + function readLine() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $line = ''; + $timeout = time() + $this->timeout; + while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { + $line .= @fgets($this->fp, $this->lineLength); + if (substr($line, -1) == "\n") { + return rtrim($line, "\r\n"); + } + } + return $line; + } + + /** + * Read until the socket closes, or until there is no more data in + * the inner PHP buffer. If the inner buffer is empty, in blocking + * mode we wait for at least 1 byte of data. Therefore, in + * blocking mode, if there is no data at all to be read, this + * function will never exit (unless the socket is closed on the + * remote end). + * + * @access public + * + * @return string All data until the socket closes, or a PEAR_Error if + * not connected. + */ + function readAll() + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $data = ''; + while (!feof($this->fp)) { + $data .= @fread($this->fp, $this->lineLength); + } + return $data; + } + + /** + * Runs the equivalent of the select() system call on the socket + * with a timeout specified by tv_sec and tv_usec. + * + * @param integer $state Which of read/write/error to check for. + * @param integer $tv_sec Number of seconds for timeout. + * @param integer $tv_usec Number of microseconds for timeout. + * + * @access public + * @return False if select fails, integer describing which of read/write/error + * are ready, or PEAR_Error if not connected. + */ + function select($state, $tv_sec, $tv_usec = 0) + { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + + $read = null; + $write = null; + $except = null; + if ($state & NET_SOCKET_READ) { + $read[] = $this->fp; + } + if ($state & NET_SOCKET_WRITE) { + $write[] = $this->fp; + } + if ($state & NET_SOCKET_ERROR) { + $except[] = $this->fp; + } + if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { + return false; + } + + $result = 0; + if (count($read)) { + $result |= NET_SOCKET_READ; + } + if (count($write)) { + $result |= NET_SOCKET_WRITE; + } + if (count($except)) { + $result |= NET_SOCKET_ERROR; + } + return $result; + } + + /** + * Turns encryption on/off on a connected socket. + * + * @param bool $enabled Set this parameter to true to enable encryption + * and false to disable encryption. + * @param integer $type Type of encryption. See + * http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values. + * + * @access public + * @return false on error, true on success and 0 if there isn't enough data and the + * user should try again (non-blocking sockets only). A PEAR_Error object + * is returned if the socket is not connected + */ + function enableCrypto($enabled, $type) + { + if (version_compare(phpversion(), "5.1.0", ">=")) { + if (!is_resource($this->fp)) { + return $this->raiseError('not connected'); + } + return @stream_socket_enable_crypto($this->fp, $enabled, $type); + } else { + return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0'); + } + } + +} diff --git a/gulliver/thirdparty/pear/Net/URL.php b/gulliver/thirdparty/pear/Net/URL.php new file mode 100644 index 000000000..3dcfef60d --- /dev/null +++ b/gulliver/thirdparty/pear/Net/URL.php @@ -0,0 +1,485 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: URL.php,v 1.49 2007/06/28 14:43:07 davidc Exp $ +// +// Net_URL Class + + +class Net_URL +{ + var $options = array('encode_query_keys' => false); + /** + * Full url + * @var string + */ + var $url; + + /** + * Protocol + * @var string + */ + var $protocol; + + /** + * Username + * @var string + */ + var $username; + + /** + * Password + * @var string + */ + var $password; + + /** + * Host + * @var string + */ + var $host; + + /** + * Port + * @var integer + */ + var $port; + + /** + * Path + * @var string + */ + var $path; + + /** + * Query string + * @var array + */ + var $querystring; + + /** + * Anchor + * @var string + */ + var $anchor; + + /** + * Whether to use [] + * @var bool + */ + var $useBrackets; + + /** + * PHP4 Constructor + * + * @see __construct() + */ + function Net_URL($url = null, $useBrackets = true) + { + $this->__construct($url, $useBrackets); + } + + /** + * PHP5 Constructor + * + * Parses the given url and stores the various parts + * Defaults are used in certain cases + * + * @param string $url Optional URL + * @param bool $useBrackets Whether to use square brackets when + * multiple querystrings with the same name + * exist + */ + function __construct($url = null, $useBrackets = true) + { + $this->url = $url; + $this->useBrackets = $useBrackets; + + $this->initialize(); + } + + function initialize() + { + $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + + $this->user = ''; + $this->pass = ''; + $this->host = ''; + $this->port = 80; + $this->path = ''; + $this->querystring = array(); + $this->anchor = ''; + + // Only use defaults if not an absolute URL given + if (!preg_match('/^[a-z0-9]+:\/\//i', $this->url)) { + $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); + + /** + * Figure out host/port + */ + if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) && + preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) + { + $host = $matches[1]; + if (!empty($matches[3])) { + $port = $matches[3]; + } else { + $port = $this->getStandardPort($this->protocol); + } + } + + $this->user = ''; + $this->pass = ''; + $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); + $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); + $this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; + $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; + $this->anchor = ''; + } + + // Parse the url and store the various parts + if (!empty($this->url)) { + $urlinfo = parse_url($this->url); + + // Default querystring + $this->querystring = array(); + + foreach ($urlinfo as $key => $value) { + switch ($key) { + case 'scheme': + $this->protocol = $value; + $this->port = $this->getStandardPort($value); + break; + + case 'user': + case 'pass': + case 'host': + case 'port': + $this->$key = $value; + break; + + case 'path': + if ($value{0} == '/') { + $this->path = $value; + } else { + $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); + $this->path = sprintf('%s/%s', $path, $value); + } + break; + + case 'query': + $this->querystring = $this->_parseRawQueryString($value); + break; + + case 'fragment': + $this->anchor = $value; + break; + } + } + } + } + /** + * Returns full url + * + * @return string Full url + * @access public + */ + function getURL() + { + $querystring = $this->getQueryString(); + + $this->url = $this->protocol . '://' + . $this->user . (!empty($this->pass) ? ':' : '') + . $this->pass . (!empty($this->user) ? '@' : '') + . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) + . $this->path + . (!empty($querystring) ? '?' . $querystring : '') + . (!empty($this->anchor) ? '#' . $this->anchor : ''); + + return $this->url; + } + + /** + * Adds or updates a querystring item (URL parameter). + * Automatically encodes parameters with rawurlencode() if $preencoded + * is false. + * You can pass an array to $value, it gets mapped via [] in the URL if + * $this->useBrackets is activated. + * + * @param string $name Name of item + * @param string $value Value of item + * @param bool $preencoded Whether value is urlencoded or not, default = not + * @access public + */ + function addQueryString($name, $value, $preencoded = false) + { + if ($this->getOption('encode_query_keys')) { + $name = rawurlencode($name); + } + + if ($preencoded) { + $this->querystring[$name] = $value; + } else { + $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); + } + } + + /** + * Removes a querystring item + * + * @param string $name Name of item + * @access public + */ + function removeQueryString($name) + { + if ($this->getOption('encode_query_keys')) { + $name = rawurlencode($name); + } + + if (isset($this->querystring[$name])) { + unset($this->querystring[$name]); + } + } + + /** + * Sets the querystring to literally what you supply + * + * @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc + * @access public + */ + function addRawQueryString($querystring) + { + $this->querystring = $this->_parseRawQueryString($querystring); + } + + /** + * Returns flat querystring + * + * @return string Querystring + * @access public + */ + function getQueryString() + { + if (!empty($this->querystring)) { + foreach ($this->querystring as $name => $value) { + // Encode var name + $name = rawurlencode($name); + + if (is_array($value)) { + foreach ($value as $k => $v) { + $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); + } + } elseif (!is_null($value)) { + $querystring[] = $name . '=' . $value; + } else { + $querystring[] = $name; + } + } + $querystring = implode(ini_get('arg_separator.output'), $querystring); + } else { + $querystring = ''; + } + + return $querystring; + } + + /** + * Parses raw querystring and returns an array of it + * + * @param string $querystring The querystring to parse + * @return array An array of the querystring data + * @access private + */ + function _parseRawQuerystring($querystring) + { + $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); + $return = array(); + + foreach ($parts as $part) { + if (strpos($part, '=') !== false) { + $value = substr($part, strpos($part, '=') + 1); + $key = substr($part, 0, strpos($part, '=')); + } else { + $value = null; + $key = $part; + } + + if (!$this->getOption('encode_query_keys')) { + $key = rawurldecode($key); + } + + if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { + $key = $matches[1]; + $idx = $matches[2]; + + // Ensure is an array + if (empty($return[$key]) || !is_array($return[$key])) { + $return[$key] = array(); + } + + // Add data + if ($idx === '') { + $return[$key][] = $value; + } else { + $return[$key][$idx] = $value; + } + } elseif (!$this->useBrackets AND !empty($return[$key])) { + $return[$key] = (array)$return[$key]; + $return[$key][] = $value; + } else { + $return[$key] = $value; + } + } + + return $return; + } + + /** + * Resolves //, ../ and ./ from a path and returns + * the result. Eg: + * + * /foo/bar/../boo.php => /foo/boo.php + * /foo/bar/../../boo.php => /boo.php + * /foo/bar/.././/boo.php => /foo/boo.php + * + * This method can also be called statically. + * + * @param string $path URL path to resolve + * @return string The result + */ + function resolvePath($path) + { + $path = explode('/', str_replace('//', '/', $path)); + + for ($i=0; $i 1 OR ($i == 1 AND $path[0] != '') ) ) { + unset($path[$i]); + unset($path[$i-1]); + $path = array_values($path); + $i -= 2; + + } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { + unset($path[$i]); + $path = array_values($path); + $i--; + + } else { + continue; + } + } + + return implode('/', $path); + } + + /** + * Returns the standard port number for a protocol + * + * @param string $scheme The protocol to lookup + * @return integer Port number or NULL if no scheme matches + * + * @author Philippe Jausions + */ + function getStandardPort($scheme) + { + switch (strtolower($scheme)) { + case 'http': return 80; + case 'https': return 443; + case 'ftp': return 21; + case 'imap': return 143; + case 'imaps': return 993; + case 'pop3': return 110; + case 'pop3s': return 995; + default: return null; + } + } + + /** + * Forces the URL to a particular protocol + * + * @param string $protocol Protocol to force the URL to + * @param integer $port Optional port (standard port is used by default) + */ + function setProtocol($protocol, $port = null) + { + $this->protocol = $protocol; + $this->port = is_null($port) ? $this->getStandardPort($protocol) : $port; + } + + /** + * Set an option + * + * This function set an option + * to be used thorough the script. + * + * @access public + * @param string $optionName The optionname to set + * @param string $value The value of this option. + */ + function setOption($optionName, $value) + { + if (!array_key_exists($optionName, $this->options)) { + return false; + } + + $this->options[$optionName] = $value; + $this->initialize(); + } + + /** + * Get an option + * + * This function gets an option + * from the $this->options array + * and return it's value. + * + * @access public + * @param string $opionName The name of the option to retrieve + * @see $this->options + */ + function getOption($optionName) + { + if (!isset($this->options[$optionName])) { + return false; + } + + return $this->options[$optionName]; + } + +} +?> diff --git a/gulliver/thirdparty/pear/Net/URL2.php b/gulliver/thirdparty/pear/Net/URL2.php new file mode 100644 index 000000000..7a654aed8 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/URL2.php @@ -0,0 +1,813 @@ + | +// +-----------------------------------------------------------------------+ +// +// $Id: URL2.php,v 1.10 2008/04/26 21:57:08 schmidt Exp $ +// +// Net_URL2 Class (PHP5 Only) + +// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php +/** + * @license BSD License + */ +class Net_URL2 +{ + /** + * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default + * is true. + */ + const OPTION_STRICT = 'strict'; + + /** + * Represent arrays in query using PHP's [] notation. Default is true. + */ + const OPTION_USE_BRACKETS = 'use_brackets'; + + /** + * URL-encode query variable keys. Default is true. + */ + const OPTION_ENCODE_KEYS = 'encode_keys'; + + /** + * Query variable separators when parsing the query string. Every character + * is considered a separator. Default is specified by the + * arg_separator.input php.ini setting (this defaults to "&"). + */ + const OPTION_SEPARATOR_INPUT = 'input_separator'; + + /** + * Query variable separator used when generating the query string. Default + * is specified by the arg_separator.output php.ini setting (this defaults + * to "&"). + */ + const OPTION_SEPARATOR_OUTPUT = 'output_separator'; + + /** + * Default options corresponds to how PHP handles $_GET. + */ + private $options = array( + self::OPTION_STRICT => true, + self::OPTION_USE_BRACKETS => true, + self::OPTION_ENCODE_KEYS => true, + self::OPTION_SEPARATOR_INPUT => 'x&', + self::OPTION_SEPARATOR_OUTPUT => 'x&', + ); + + /** + * @var string|bool + */ + private $scheme = false; + + /** + * @var string|bool + */ + private $userinfo = false; + + /** + * @var string|bool + */ + private $host = false; + + /** + * @var int|bool + */ + private $port = false; + + /** + * @var string + */ + private $path = ''; + + /** + * @var string|bool + */ + private $query = false; + + /** + * @var string|bool + */ + private $fragment = false; + + /** + * @param string $url an absolute or relative URL + * @param array $options + */ + public function __construct($url, $options = null) + { + $this->setOption(self::OPTION_SEPARATOR_INPUT, + ini_get('arg_separator.input')); + $this->setOption(self::OPTION_SEPARATOR_OUTPUT, + ini_get('arg_separator.output')); + if (is_array($options)) { + foreach ($options as $optionName => $value) { + $this->setOption($optionName); + } + } + + if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) { + $this->scheme = $reg[1]; + $url = substr($url, strlen($reg[0])); + } + + if (preg_match('@^//([^/#?]+)@', $url, $reg)) { + $this->setAuthority($reg[1]); + $url = substr($url, strlen($reg[0])); + } + + $i = strcspn($url, '?#'); + $this->path = substr($url, 0, $i); + $url = substr($url, $i); + + if (preg_match('@^\?([^#]*)@', $url, $reg)) { + $this->query = $reg[1]; + $url = substr($url, strlen($reg[0])); + } + + if ($url) { + $this->fragment = substr($url, 1); + } + } + + /** + * Returns the scheme, e.g. "http" or "urn", or false if there is no + * scheme specified, i.e. if this is a relative URL. + * + * @return string|bool + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * @param string|bool $scheme + * + * @return void + * @see getScheme() + */ + public function setScheme($scheme) + { + $this->scheme = $scheme; + } + + /** + * Returns the user part of the userinfo part (the part preceding the first + * ":"), or false if there is no userinfo part. + * + * @return string|bool + */ + public function getUser() + { + return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false; + } + + /** + * Returns the password part of the userinfo part (the part after the first + * ":"), or false if there is no userinfo part (i.e. the URL does not + * contain "@" in front of the hostname) or the userinfo part does not + * contain ":". + * + * @return string|bool + */ + public function getPassword() + { + return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false; + } + + /** + * Returns the userinfo part, or false if there is none, i.e. if the + * authority part does not contain "@". + * + * @return string|bool + */ + public function getUserinfo() + { + return $this->userinfo; + } + + /** + * Sets the userinfo part. If two arguments are passed, they are combined + * in the userinfo part as username ":" password. + * + * @param string|bool $userinfo userinfo or username + * @param string|bool $password + * + * @return void + */ + public function setUserinfo($userinfo, $password = false) + { + $this->userinfo = $userinfo; + if ($password !== false) { + $this->userinfo .= ':' . $password; + } + } + + /** + * Returns the host part, or false if there is no authority part, e.g. + * relative URLs. + * + * @return string|bool + */ + public function getHost() + { + return $this->host; + } + + /** + * @param string|bool $host + * + * @return void + */ + public function setHost($host) + { + $this->host = $host; + } + + /** + * Returns the port number, or false if there is no port number specified, + * i.e. if the default port is to be used. + * + * @return int|bool + */ + public function getPort() + { + return $this->port; + } + + /** + * @param int|bool $port + * + * @return void + */ + public function setPort($port) + { + $this->port = intval($port); + } + + /** + * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or + * false if there is no authority none. + * + * @return string|bool + */ + public function getAuthority() + { + if (!$this->host) { + return false; + } + + $authority = ''; + + if ($this->userinfo !== false) { + $authority .= $this->userinfo . '@'; + } + + $authority .= $this->host; + + if ($this->port !== false) { + $authority .= ':' . $this->port; + } + + return $authority; + } + + /** + * @param string|false $authority + * + * @return void + */ + public function setAuthority($authority) + { + $this->user = false; + $this->pass = false; + $this->host = false; + $this->port = false; + if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) { + if ($reg[1]) { + $this->userinfo = $reg[2]; + } + + $this->host = $reg[3]; + if (isset($reg[5])) { + $this->port = intval($reg[5]); + } + } + } + + /** + * Returns the path part (possibly an empty string). + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * @param string $path + * + * @return void + */ + public function setPath($path) + { + $this->path = $path; + } + + /** + * Returns the query string (excluding the leading "?"), or false if "?" + * isn't present in the URL. + * + * @return string|bool + * @see self::getQueryVariables() + */ + public function getQuery() + { + return $this->query; + } + + /** + * @param string|bool $query + * + * @return void + * @see self::setQueryVariables() + */ + public function setQuery($query) + { + $this->query = $query; + } + + /** + * Returns the fragment name, or false if "#" isn't present in the URL. + * + * @return string|bool + */ + public function getFragment() + { + return $this->fragment; + } + + /** + * @param string|bool $fragment + * + * @return void + */ + public function setFragment($fragment) + { + $this->fragment = $fragment; + } + + /** + * Returns the query string like an array as the variables would appear in + * $_GET in a PHP script. + * + * @return array + */ + public function getQueryVariables() + { + $pattern = '/[' . + preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') . + ']/'; + $parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY); + $return = array(); + + foreach ($parts as $part) { + if (strpos($part, '=') !== false) { + list($key, $value) = explode('=', $part, 2); + } else { + $key = $part; + $value = null; + } + + if ($this->getOption(self::OPTION_ENCODE_KEYS)) { + $key = rawurldecode($key); + } + $value = rawurldecode($value); + + if ($this->getOption(self::OPTION_USE_BRACKETS) && + preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { + + $key = $matches[1]; + $idx = $matches[2]; + + // Ensure is an array + if (empty($return[$key]) || !is_array($return[$key])) { + $return[$key] = array(); + } + + // Add data + if ($idx === '') { + $return[$key][] = $value; + } else { + $return[$key][$idx] = $value; + } + } elseif (!$this->getOption(self::OPTION_USE_BRACKETS) + && !empty($return[$key]) + ) { + $return[$key] = (array) $return[$key]; + $return[$key][] = $value; + } else { + $return[$key] = $value; + } + } + + return $return; + } + + /** + * @param array $array (name => value) array + * + * @return void + */ + public function setQueryVariables(array $array) + { + if (!$array) { + $this->query = false; + } else { + foreach ($array as $name => $value) { + if ($this->getOption(self::OPTION_ENCODE_KEYS)) { + $name = rawurlencode($name); + } + + if (is_array($value)) { + foreach ($value as $k => $v) { + $parts[] = $this->getOption(self::OPTION_USE_BRACKETS) + ? sprintf('%s[%s]=%s', $name, $k, $v) + : ($name . '=' . $v); + } + } elseif (!is_null($value)) { + $parts[] = $name . '=' . $value; + } else { + $parts[] = $name; + } + } + $this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT), + $parts); + } + } + + /** + * @param string $name + * @param mixed $value + * + * @return array + */ + public function setQueryVariable($name, $value) + { + $array = $this->getQueryVariables(); + $array[$name] = $value; + $this->setQueryVariables($array); + } + + /** + * @param string $name + * + * @return void + */ + public function unsetQueryVariable($name) + { + $array = $this->getQueryVariables(); + unset($array[$name]); + $this->setQueryVariables($array); + } + + /** + * Returns a string representation of this URL. + * + * @return string + */ + public function getURL() + { + // See RFC 3986, section 5.3 + $url = ""; + + if ($this->scheme !== false) { + $url .= $this->scheme . ':'; + } + + $authority = $this->getAuthority(); + if ($authority !== false) { + $url .= '//' . $authority; + } + $url .= $this->path; + + if ($this->query !== false) { + $url .= '?' . $this->query; + } + + if ($this->fragment !== false) { + $url .= '#' . $this->fragment; + } + + return $url; + } + + /** + * Returns a normalized string representation of this URL. This is useful + * for comparison of URLs. + * + * @return string + */ + public function getNormalizedURL() + { + $url = clone $this; + $url->normalize(); + return $url->getUrl(); + } + + /** + * Returns a normalized Net_URL2 instance. + * + * @return Net_URL2 + */ + public function normalize() + { + // See RFC 3886, section 6 + + // Schemes are case-insensitive + if ($this->scheme) { + $this->scheme = strtolower($this->scheme); + } + + // Hostnames are case-insensitive + if ($this->host) { + $this->host = strtolower($this->host); + } + + // Remove default port number for known schemes (RFC 3986, section 6.2.3) + if ($this->port && + $this->scheme && + $this->port == getservbyname($this->scheme, 'tcp')) { + + $this->port = false; + } + + // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) + foreach (array('userinfo', 'host', 'path') as $part) { + if ($this->$part) { + $this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part); + } + } + + // Path segment normalization (RFC 3986, section 6.2.2.3) + $this->path = self::removeDotSegments($this->path); + + // Scheme based normalization (RFC 3986, section 6.2.3) + if ($this->host && !$this->path) { + $this->path = '/'; + } + } + + /** + * Returns whether this instance represents an absolute URL. + * + * @return bool + */ + public function isAbsolute() + { + return (bool) $this->scheme; + } + + /** + * Returns an Net_URL2 instance representing an absolute URL relative to + * this URL. + * + * @param Net_URL2|string $reference relative URL + * + * @return Net_URL2 + */ + public function resolve($reference) + { + if (is_string($reference)) { + $reference = new self($reference); + } + if (!$this->isAbsolute()) { + throw new Exception('Base-URL must be absolute'); + } + + // A non-strict parser may ignore a scheme in the reference if it is + // identical to the base URI's scheme. + if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) { + $reference->scheme = false; + } + + $target = new self(''); + if ($reference->scheme !== false) { + $target->scheme = $reference->scheme; + $target->setAuthority($reference->getAuthority()); + $target->path = self::removeDotSegments($reference->path); + $target->query = $reference->query; + } else { + $authority = $reference->getAuthority(); + if ($authority !== false) { + $target->setAuthority($authority); + $target->path = self::removeDotSegments($reference->path); + $target->query = $reference->query; + } else { + if ($reference->path == '') { + $target->path = $this->path; + if ($reference->query !== false) { + $target->query = $reference->query; + } else { + $target->query = $this->query; + } + } else { + if (substr($reference->path, 0, 1) == '/') { + $target->path = self::removeDotSegments($reference->path); + } else { + // Merge paths (RFC 3986, section 5.2.3) + if ($this->host !== false && $this->path == '') { + $target->path = '/' . $this->path; + } else { + $i = strrpos($this->path, '/'); + if ($i !== false) { + $target->path = substr($this->path, 0, $i + 1); + } + $target->path .= $reference->path; + } + $target->path = self::removeDotSegments($target->path); + } + $target->query = $reference->query; + } + $target->setAuthority($this->getAuthority()); + } + $target->scheme = $this->scheme; + } + + $target->fragment = $reference->fragment; + + return $target; + } + + /** + * Removes dots as described in RFC 3986, section 5.2.4, e.g. + * "/foo/../bar/baz" => "/bar/baz" + * + * @param string $path a path + * + * @return string a path + */ + private static function removeDotSegments($path) + { + $output = ''; + + // Make sure not to be trapped in an infinite loop due to a bug in this + // method + $j = 0; + while ($path && $j++ < 100) { + // Step A + if (substr($path, 0, 2) == './') { + $path = substr($path, 2); + } elseif (substr($path, 0, 3) == '../') { + $path = substr($path, 3); + + // Step B + } elseif (substr($path, 0, 3) == '/./' || $path == '/.') { + $path = '/' . substr($path, 3); + + // Step C + } elseif (substr($path, 0, 4) == '/../' || $path == '/..') { + $path = '/' . substr($path, 4); + $i = strrpos($output, '/'); + $output = $i === false ? '' : substr($output, 0, $i); + + // Step D + } elseif ($path == '.' || $path == '..') { + $path = ''; + + // Step E + } else { + $i = strpos($path, '/'); + if ($i === 0) { + $i = strpos($path, '/', 1); + } + if ($i === false) { + $i = strlen($path); + } + $output .= substr($path, 0, $i); + $path = substr($path, $i); + } + } + + return $output; + } + + /** + * Returns a Net_URL2 instance representing the canonical URL of the + * currently executing PHP script. + * + * @return string + */ + public static function getCanonical() + { + if (!isset($_SERVER['REQUEST_METHOD'])) { + // ALERT - no current URL + throw new Exception('Script was not called through a webserver'); + } + + // Begin with a relative URL + $url = new self($_SERVER['PHP_SELF']); + $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + $url->host = $_SERVER['SERVER_NAME']; + $port = intval($_SERVER['SERVER_PORT']); + if ($url->scheme == 'http' && $port != 80 || + $url->scheme == 'https' && $port != 443) { + + $url->port = $port; + } + return $url; + } + + /** + * Returns the URL used to retrieve the current request. + * + * @return string + */ + public static function getRequestedURL() + { + return self::getRequested()->getUrl(); + } + + /** + * Returns a Net_URL2 instance representing the URL used to retrieve the + * current request. + * + * @return Net_URL2 + */ + public static function getRequested() + { + if (!isset($_SERVER['REQUEST_METHOD'])) { + // ALERT - no current URL + throw new Exception('Script was not called through a webserver'); + } + + // Begin with a relative URL + $url = new self($_SERVER['REQUEST_URI']); + $url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; + // Set host and possibly port + $url->setAuthority($_SERVER['HTTP_HOST']); + return $url; + } + + /** + * Sets the specified option. + * + * @param string $optionName a self::OPTION_ constant + * @param mixed $value option value + * + * @return void + * @see self::OPTION_STRICT + * @see self::OPTION_USE_BRACKETS + * @see self::OPTION_ENCODE_KEYS + */ + function setOption($optionName, $value) + { + if (!array_key_exists($optionName, $this->options)) { + return false; + } + $this->options[$optionName] = $value; + } + + /** + * Returns the value of the specified option. + * + * @param string $optionName The name of the option to retrieve + * + * @return mixed + */ + function getOption($optionName) + { + return isset($this->options[$optionName]) + ? $this->options[$optionName] : false; + } +} diff --git a/gulliver/thirdparty/pear/Net/UserAgent/Detect.php b/gulliver/thirdparty/pear/Net/UserAgent/Detect.php new file mode 100644 index 000000000..0ceb95faa --- /dev/null +++ b/gulliver/thirdparty/pear/Net/UserAgent/Detect.php @@ -0,0 +1,967 @@ + | +// | Jason Rust | +// +----------------------------------------------------------------------+ + +// $Id: Detect.php,v 1.26 2007/09/19 21:31:54 jrust Exp $ + +// }}} +// {{{ constants + +define('NET_USERAGENT_DETECT_BROWSER', 'browser'); +define('NET_USERAGENT_DETECT_OS', 'os'); +define('NET_USERAGENT_DETECT_FEATURES', 'features'); +define('NET_USERAGENT_DETECT_QUIRKS', 'quirks'); +define('NET_USERAGENT_DETECT_ACCEPT', 'accept'); +define('NET_USERAGENT_DETECT_ALL', 'all'); + +// }}} +// {{{ class Net_UserAgent_Detect + +/** + * The Net_UserAgent_Detect object does a number of tests on an HTTP user + * agent string. The results of these tests are available via methods of + * the object. Note that all methods in this class can be called + * statically. The constructor and singleton methods are only retained + * for BC. + * + * This module is based upon the JavaScript browser detection code + * available at http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html. + * This module had many influences from the lib/Browser.php code in + * version 1.3 of Horde. + * + * @author Jason Rust + * @author Dan Allen + * @author Chuck Hagenbuch + * @author Jon Parise + * @package Net_UserAgent + */ + +// }}} +class Net_UserAgent_Detect { + // {{{ constructor + + function Net_UserAgent_Detect($in_userAgent = null, $in_detect = null) + { + $this->detect($in_userAgent, $in_detect); + } + + // }}} + // {{{ singleton + + /** + * To be used in place of the contructor to return only open instance. + * + * @access public + * @return object Net_UserAgent_Detect instance + */ + function &singleton($in_userAgent = null, $in_detect = null) + { + static $instance; + + if (!isset($instance)) { + $instance = new Net_UserAgent_Detect($in_userAgent, $in_detect); + } + + return $instance; + } + + // }}} + // {{{ detect() + + /** + * Detect the user agent and prepare flags, features and quirks + * based on what is found + * + * This is the core of the Net_UserAgent_Detect class. It moves its + * way through the user agent string setting up the flags based on + * the vendors and versions of the browsers, determining the OS and + * setting up the features and quirks owned by each of the relevant + * clients. Note that if you are going to be calling methods of + * this class statically then set all the parameters using th + * setOption() + * + * @param string $in_userAgent (optional) User agent override. + * @param mixed $in_detect (optional) The level of checking to do. + * + * @access public + * @return void + */ + function detect($in_userAgent = null, $in_detect = null) + { + static $hasRun; + $options = &Net_UserAgent_Detect::_getStaticProperty('options'); + if (!empty($hasRun) && empty($options['re-evaluate'])) { + return; + } + + $hasRun = true; + // {{{ set up static properties + + $in_userAgent = isset($options['userAgent']) && is_null($in_userAgent) ? $options['userAgent'] : $in_userAgent; + $in_detect = isset($options['detectOptions']) && is_null($in_detect) ? $options['detectOptions'] : $in_detect; + + // User agent string that is being analyzed + $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent'); + + // Array that stores all of the flags for the vendor and version + // of the different browsers + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + $browser = array_flip(array('ns', 'ns2', 'ns3', 'ns4', 'ns4up', 'nav', 'ns6', 'belowns6', 'ns6up', 'firefox', 'firefox0.x', 'firefox1.x', 'firefox1.5', 'firefox2.x', 'gecko', 'ie', 'ie3', 'ie4', 'ie4up', 'ie5', 'ie5_5', 'ie5up', 'ie6', 'belowie6', 'ie6up', 'ie7', 'ie7up', 'opera', 'opera2', 'opera3', 'opera4', 'opera5', 'opera6', 'opera7', 'opera8', 'opera9', 'opera5up', 'opera6up', 'opera7up', 'belowopera8', 'opera8up', 'opera9up', 'aol', 'aol3', 'aol4', 'aol5', 'aol6', 'aol7', 'aol8', 'webtv', 'aoltv', 'tvnavigator', 'hotjava', 'hotjava3', 'hotjava3up', 'konq', 'safari', 'netgem', 'webdav', 'icab')); + + // Array that stores all of the flags for the operating systems, + // and in some cases the versions of those operating systems (windows) + $os = &Net_UserAgent_Detect::_getStaticProperty('os'); + $os = array_flip(array('win', 'win95', 'win16', 'win31', 'win9x', 'win98', 'wince', 'winme', 'win2k', 'winxp', 'winnt', 'win2003', 'os2', 'mac', 'mac68k', 'macppc', 'linux', 'unix', 'vms', 'sun', 'sun4', 'sun5', 'suni86', 'irix', 'irix5', 'irix6', 'hpux', 'hpux9', 'hpux10', 'aix', 'aix1', 'aix2', 'aix3', 'aix4', 'sco', 'unixware', 'mpras', 'reliant', 'dec', 'sinix', 'freebsd', 'bsd')); + + // Array which stores known issues with the given client that can + // be used for on the fly tweaking so that the client may recieve + // the proper handling of this quirk. + $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks'); + $quirks = array( + 'must_cache_forms' => false, + 'popups_disabled' => false, + 'empty_file_input_value' => false, + 'cache_ssl_downloads' => false, + 'scrollbar_in_way' => false, + 'break_disposition_header' => false, + 'nested_table_render_bug' => false); + + // Array that stores credentials for each of the browser/os + // combinations. These allow quick access to determine if the + // current client has a feature that is going to be implemented + // in the script. + $features = &Net_UserAgent_Detect::_getStaticProperty('features'); + $features = array( + 'javascript' => false, + 'dhtml' => false, + 'dom' => false, + 'sidebar' => false, + 'gecko' => false, + 'svg' => false, + 'css2' => false, + 'ajax' => false); + + // The leading identifier is the very first term in the user + // agent string, which is used to identify clients which are not + // Mosaic-based browsers. + $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier'); + + // The full version of the client as supplied by the very first + // numbers in the user agent + $version = &Net_UserAgent_Detect::_getStaticProperty('version'); + $version = 0; + + // The major part of the client version, which is the integer + // value of the version. + $majorVersion = &Net_UserAgent_Detect::_getStaticProperty('majorVersion'); + $majorVersion = 0; + + // The minor part of the client version, which is the decimal + // parts of the version + $subVersion = &Net_UserAgent_Detect::_getStaticProperty('subVersion'); + $subVersion = 0; + + // }}} + // detemine what user agent we are using + if (is_null($in_userAgent)) { + if (isset($_SERVER['HTTP_USER_AGENT'])) { + $userAgent = $_SERVER['HTTP_USER_AGENT']; + } + elseif (isset($GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'])) { + $userAgent = $GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT']; + } + else { + $userAgent = ''; + } + } + else { + $userAgent = $in_userAgent; + } + + // get the lowercase version for case-insensitive searching + $agt = strtolower($userAgent); + + // figure out what we need to look for + $detectOptions = array(NET_USERAGENT_DETECT_BROWSER, + NET_USERAGENT_DETECT_OS, NET_USERAGENT_DETECT_FEATURES, + NET_USERAGENT_DETECT_QUIRKS, NET_USERAGENT_DETECT_ACCEPT, + NET_USERAGENT_DETECT_ALL); + $detect = is_null($in_detect) ? NET_USERAGENT_DETECT_ALL : $in_detect; + settype($detect, 'array'); + foreach($detectOptions as $option) { + if (in_array($option, $detect)) { + $detectFlags[$option] = true; + } + else { + $detectFlags[$option] = false; + } + } + + // initialize the arrays of browsers and operating systems + + // Get the type and version of the client + if (preg_match(";^([[:alnum:]]+)[ /\(]*[[:alpha:]]*([\d]*)(\.[\d\.]*);", $agt, $matches)) { + list(, $leadingIdentifier, $majorVersion, $subVersion) = $matches; + } + + if (empty($leadingIdentifier)) { + $leadingIdentifier = 'Unknown'; + } + + $version = $majorVersion . $subVersion; + + // Browser type + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_BROWSER]) { + $browser['webdav'] = ($agt == 'microsoft data access internet publishing provider dav' || $agt == 'microsoft data access internet publishing provider protocol discovery'); + $browser['konq'] = $browser['safari'] = (strpos($agt, 'konqueror') !== false || strpos($agt, 'safari') !== false); + $browser['text'] = strpos($agt, 'links') !== false || strpos($agt, 'lynx') !== false || strpos($agt, 'w3m') !== false; + $browser['ns'] = strpos($agt, 'mozilla') !== false && !(strpos($agt, 'spoofer') !== false) && !(strpos($agt, 'compatible') !== false) && !(strpos($agt, 'hotjava') !== false) && !(strpos($agt, 'opera') !== false) && !(strpos($agt, 'webtv') !== false) ? 1 : 0; + $browser['netgem'] = strpos($agt, 'netgem') !== false; + $browser['icab'] = strpos($agt, 'icab') !== false; + $browser['ns2'] = $browser['ns'] && $majorVersion == 2; + $browser['ns3'] = $browser['ns'] && $majorVersion == 3; + $browser['ns4'] = $browser['ns'] && $majorVersion == 4; + $browser['ns4up'] = $browser['ns'] && $majorVersion >= 4; + // determine if this is a Netscape Navigator + $browser['nav'] = $browser['belowns6'] = $browser['ns'] && $majorVersion < 5; + $browser['ns6'] = !$browser['konq'] && $browser['ns'] && $majorVersion == 5; + $browser['ns6up'] = $browser['ns6'] && $majorVersion >= 5; + $browser['gecko'] = strpos($agt, 'gecko') !== false && !$browser['konq']; + $browser['firefox'] = $browser['gecko'] && strpos($agt, 'firefox') !== false; + $browser['firefox0.x'] = $browser['firefox'] && strpos($agt, 'firefox/0.') !== false; + $browser['firefox1.x'] = $browser['firefox'] && strpos($agt, 'firefox/1.') !== false; + $browser['firefox1.5'] = $browser['firefox'] && strpos($agt, 'firefox/1.5') !== false; + $browser['firefox2.x'] = $browser['firefox'] && strpos($agt, 'firefox/2.') !== false; + $browser['ie'] = strpos($agt, 'msie') !== false && !(strpos($agt, 'opera') !== false); + $browser['ie3'] = $browser['ie'] && $majorVersion < 4; + $browser['ie4'] = $browser['ie'] && $majorVersion == 4 && (strpos($agt, 'msie 4') !== false); + $browser['ie4up'] = $browser['ie'] && !$browser['ie3']; + $browser['ie5'] = $browser['ie4up'] && (strpos($agt, 'msie 5') !== false); + $browser['ie5_5'] = $browser['ie4up'] && (strpos($agt, 'msie 5.5') !== false); + $browser['ie5up'] = $browser['ie4up'] && !$browser['ie3'] && !$browser['ie4']; + $browser['ie5_5up'] = $browser['ie5up'] && !$browser['ie5']; + $browser['ie6'] = strpos($agt, 'msie 6') !== false; + $browser['ie6up'] = $browser['ie5up'] && !$browser['ie5'] && !$browser['ie5_5']; + $browser['ie7'] = strpos($agt, 'msie 7') !== false; + $browser['ie7up'] = $browser['ie6up'] && !$browser['ie6']; + $browser['belowie6']= $browser['ie'] && !$browser['ie6up']; + $browser['opera'] = strpos($agt, 'opera') !== false; + $browser['opera2'] = strpos($agt, 'opera 2') !== false || strpos($agt, 'opera/2') !== false; + $browser['opera3'] = strpos($agt, 'opera 3') !== false || strpos($agt, 'opera/3') !== false; + $browser['opera4'] = strpos($agt, 'opera 4') !== false || strpos($agt, 'opera/4') !== false; + $browser['opera5'] = strpos($agt, 'opera 5') !== false || strpos($agt, 'opera/5') !== false; + $browser['opera6'] = strpos($agt, 'opera 6') !== false || strpos($agt, 'opera/6') !== false; + $browser['opera7'] = strpos($agt, 'opera 7') !== false || strpos($agt, 'opera/7') !== false; + $browser['opera8'] = strpos($agt, 'opera 8') !== false || strpos($agt, 'opera/8') !== false; + $browser['opera9'] = strpos($agt, 'opera 9') !== false || strpos($agt, 'opera/9') !== false; + $browser['opera5up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4']; + $browser['opera6up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5']; + $browser['opera7up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6']; + $browser['opera8up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6'] && !$browser['opera7']; + $browser['opera9up'] = $browser['opera'] && !$browser['opera2'] && !$browser['opera3'] && !$browser['opera4'] && !$browser['opera5'] && !$browser['opera6'] && !$browser['opera7'] && !$browser['opera8']; + $browser['belowopera8'] = $browser['opera'] && !$browser['opera8up']; + $browser['aol'] = strpos($agt, 'aol') !== false; + $browser['aol3'] = $browser['aol'] && $browser['ie3']; + $browser['aol4'] = $browser['aol'] && $browser['ie4']; + $browser['aol5'] = strpos($agt, 'aol 5') !== false; + $browser['aol6'] = strpos($agt, 'aol 6') !== false; + $browser['aol7'] = strpos($agt, 'aol 7') !== false || strpos($agt, 'aol7') !== false; + $browser['aol8'] = strpos($agt, 'aol 8') !== false || strpos($agt, 'aol8') !== false; + $browser['webtv'] = strpos($agt, 'webtv') !== false; + $browser['aoltv'] = $browser['tvnavigator'] = strpos($agt, 'navio') !== false || strpos($agt, 'navio_aoltv') !== false; + $browser['hotjava'] = strpos($agt, 'hotjava') !== false; + $browser['hotjava3'] = $browser['hotjava'] && $majorVersion == 3; + $browser['hotjava3up'] = $browser['hotjava'] && $majorVersion >= 3; + $browser['iemobile'] = strpos($agt, 'iemobile') !== false || strpos($agt, 'windows ce') !== false && (strpos($agt, 'ppc') !== false || strpos($agt, 'smartphone') !== false); + } + + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || + ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) { + // Javascript Check + if ($browser['ns2'] || $browser['ie3']) { + Net_UserAgent_Detect::setFeature('javascript', 1.0); + } + elseif ($browser['iemobile']) { + // no javascript + } + elseif ($browser['opera5up']) { + Net_UserAgent_Detect::setFeature('javascript', 1.3); + } + elseif ($browser['opera'] || $browser['ns3']) { + Net_UserAgent_Detect::setFeature('javascript', 1.1); + } + elseif (($browser['ns4'] && ($version <= 4.05)) || $browser['ie4']) { + Net_UserAgent_Detect::setFeature('javascript', 1.2); + } + elseif (($browser['ie5up'] && strpos($agt, 'mac') !== false) || $browser['konq']) { + Net_UserAgent_Detect::setFeature('javascript', 1.4); + } + // I can't believe IE6 still has javascript 1.3, what a shitty browser + elseif (($browser['ns4'] && ($version > 4.05)) || $browser['ie5up'] || $browser['hotjava3up']) { + Net_UserAgent_Detect::setFeature('javascript', 1.3); + } + elseif ($browser['ns6up'] || $browser['gecko'] || $browser['netgem']) { + Net_UserAgent_Detect::setFeature('javascript', 1.5); + } + } + + /** OS Check **/ + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_OS]) { + $os['win'] = strpos($agt, 'win') !== false || strpos($agt, '16bit') !== false; + $os['win95'] = strpos($agt, 'win95') !== false || strpos($agt, 'windows 95') !== false; + $os['win16'] = strpos($agt, 'win16') !== false || strpos($agt, '16bit') !== false || strpos($agt, 'windows 3.1') !== false || strpos($agt, 'windows 16-bit') !== false; + $os['win31'] = strpos($agt, 'windows 3.1') !== false || strpos($agt, 'win16') !== false || strpos($agt, 'windows 16-bit') !== false; + $os['winme'] = strpos($agt, 'win 9x 4.90') !== false; + $os['wince'] = strpos($agt, 'windows ce') !== false; + $os['win2k'] = strpos($agt, 'windows nt 5.0') !== false; + $os['winxp'] = strpos($agt, 'windows nt 5.1') !== false; + $os['win2003'] = strpos($agt, 'windows nt 5.2') !== false; + $os['win98'] = strpos($agt, 'win98') !== false || strpos($agt, 'windows 98') !== false; + $os['win9x'] = $os['win95'] || $os['win98']; + $os['winnt'] = (strpos($agt, 'winnt') !== false || strpos($agt, 'windows nt') !== false) && strpos($agt, 'windows nt 5') === false; + $os['win32'] = $os['win95'] || $os['winnt'] || $os['win98'] || $majorVersion >= 4 && strpos($agt, 'win32') !== false || strpos($agt, '32bit') !== false; + $os['os2'] = strpos($agt, 'os/2') !== false || strpos($agt, 'ibm-webexplorer') !== false; + $os['mac'] = strpos($agt, 'mac') !== false; + $os['mac68k'] = $os['mac'] && (strpos($agt, '68k') !== false || strpos($agt, '68000') !== false); + $os['macppc'] = $os['mac'] && (strpos($agt, 'ppc') !== false || strpos($agt, 'powerpc') !== false); + $os['sun'] = strpos($agt, 'sunos') !== false; + $os['sun4'] = strpos($agt, 'sunos 4') !== false; + $os['sun5'] = strpos($agt, 'sunos 5') !== false; + $os['suni86'] = $os['sun'] && strpos($agt, 'i86') !== false; + $os['irix'] = strpos($agt, 'irix') !== false; + $os['irix5'] = strpos($agt, 'irix 5') !== false; + $os['irix6'] = strpos($agt, 'irix 6') !== false || strpos($agt, 'irix6') !== false; + $os['hpux'] = strpos($agt, 'hp-ux') !== false; + $os['hpux9'] = $os['hpux'] && strpos($agt, '09.') !== false; + $os['hpux10'] = $os['hpux'] && strpos($agt, '10.') !== false; + $os['aix'] = strpos($agt, 'aix') !== false; + $os['aix1'] = strpos($agt, 'aix 1') !== false; + $os['aix2'] = strpos($agt, 'aix 2') !== false; + $os['aix3'] = strpos($agt, 'aix 3') !== false; + $os['aix4'] = strpos($agt, 'aix 4') !== false; + $os['linux'] = strpos($agt, 'inux') !== false; + $os['sco'] = strpos($agt, 'sco') !== false || strpos($agt, 'unix_sv') !== false; + $os['unixware'] = strpos($agt, 'unix_system_v') !== false; + $os['mpras'] = strpos($agt, 'ncr') !== false; + $os['reliant'] = strpos($agt, 'reliant') !== false; + $os['dec'] = strpos($agt, 'dec') !== false || strpos($agt, 'osf1') !== false || strpos($agt, 'dec_alpha') !== false || strpos($agt, 'alphaserver') !== false || strpos($agt, 'ultrix') !== false || strpos($agt, 'alphastation') !== false; + $os['sinix'] = strpos($agt, 'sinix') !== false; + $os['freebsd'] = strpos($agt, 'freebsd') !== false; + $os['bsd'] = strpos($agt, 'bsd') !== false; + $os['unix'] = strpos($agt, 'x11') !== false || strpos($agt, 'unix') !== false || $os['sun'] || $os['irix'] || $os['hpux'] || $os['sco'] || $os['unixware'] || $os['mpras'] || $os['reliant'] || $os['dec'] || $os['sinix'] || $os['aix'] || $os['linux'] || $os['bsd'] || $os['freebsd']; + $os['vms'] = strpos($agt, 'vax') !== false || strpos($agt, 'openvms') !== false; + } + + // Setup the quirks + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || + ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_QUIRKS])) { + if ($browser['konq']) { + Net_UserAgent_Detect::setQuirk('empty_file_input_value'); + } + + if ($browser['ie']) { + Net_UserAgent_Detect::setQuirk('cache_ssl_downloads'); + } + + if ($browser['ie6']) { + Net_UserAgent_Detect::setQuirk('scrollbar_in_way'); + } + + if ($browser['ie5']) { + Net_UserAgent_Detect::setQuirk('break_disposition_header'); + } + + if ($browser['ie7']) { + Net_UserAgent_Detect::setQuirk('popups_disabled'); + } + + if ($browser['ns6']) { + Net_UserAgent_Detect::setQuirk('popups_disabled'); + Net_UserAgent_Detect::setQuirk('must_cache_forms'); + } + + if ($browser['nav'] && $subVersion < .79) { + Net_UserAgent_Detect::setQuirk('nested_table_render_bug'); + } + } + + // Set features + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || + ($detectFlags[NET_USERAGENT_DETECT_BROWSER] && $detectFlags[NET_USERAGENT_DETECT_FEATURES])) { + if ($browser['gecko']) { + preg_match(';gecko/([\d]+)\b;i', $agt, $matches); + Net_UserAgent_Detect::setFeature('gecko', $matches[1]); + } + + if ($browser['gecko'] || ($browser['ie5up'] && !$browser['iemobile']) || $browser['konq'] || $browser['opera8up'] && !$os['wince']) { + Net_UserAgent_Detect::setFeature('ajax'); + } + + if ($browser['ns6up'] || $browser['opera5up'] || $browser['konq'] || $browser['netgem']) { + Net_UserAgent_Detect::setFeature('dom'); + } + + if ($browser['ie4up'] || $browser['ns4up'] || $browser['opera5up'] || $browser['konq'] || $browser['netgem']) { + Net_UserAgent_Detect::setFeature('dhtml'); + } + + if ($browser['firefox1.5'] || $browser['firefox2.x'] || $browser['opera9up']) { + Net_UserAgent_Detect::setFeature('svg'); + } + + if ($browser['gecko'] || $browser['ns6up'] || $browser['ie5up'] || $browser['konq'] || $browser['opera7up']) { + Net_UserAgent_Detect::setFeature('css2'); + } + } + + if ($detectFlags[NET_USERAGENT_DETECT_ALL] || $detectFlags[NET_USERAGENT_DETECT_ACCEPT]) { + $mimetypes = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT'), 0, strpos(getenv('HTTP_ACCEPT') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY); + Net_UserAgent_Detect::setAcceptType((array) $mimetypes, 'mimetype'); + + $languages = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_LANGUAGE'), 0, strpos(getenv('HTTP_ACCEPT_LANGUAGE') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY); + if (empty($languages)) { + $languages = 'en'; + } + + Net_UserAgent_Detect::setAcceptType((array) $languages, 'language'); + + $encodings = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_ENCODING'), 0, strpos(getenv('HTTP_ACCEPT_ENCODING') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY); + Net_UserAgent_Detect::setAcceptType((array) $encodings, 'encoding'); + + $charsets = preg_split(';[\s,]+;', substr(getenv('HTTP_ACCEPT_CHARSET'), 0, strpos(getenv('HTTP_ACCEPT_CHARSET') . ';', ';')), -1, PREG_SPLIT_NO_EMPTY); + Net_UserAgent_Detect::setAcceptType((array) $charsets, 'charset'); + } + } + + // }}} + // {{{ setOption() + + /** + * Sets a class option. The available settings are: + * o 'userAgent' => The user agent string to detect (useful for + * checking a string manually). + * o 'detectOptions' => The level of checking to do. A single level + * or an array of options. Default is NET_USERAGENT_DETECT_ALL. + * + * @param string $in_field The option field (userAgent or detectOptions) + * @param mixed $in_value The value for the field + */ + function setOption($in_field, $in_value) + { + $options = &Net_UserAgent_Detect::_getStaticProperty('options'); + $options[$in_field] = $in_value; + } + + // }}} + // {{{ isBrowser() + + /** + * Look up the provide browser flag and return a boolean value + * + * Given one of the flags listed in the properties, this function will return + * the value associated with that flag. + * + * @param string $in_match flag to lookup + * + * @access public + * @return boolean whether or not the browser satisfies this flag + */ + function isBrowser($in_match) + { + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + return isset($browser[strtolower($in_match)]) ? $browser[strtolower($in_match)] : false; + } + + // }}} + // {{{ getBrowser() + + /** + * Since simply returning the "browser" is somewhat ambiguous since there + * are different ways to classify the browser, this function works by taking + * an expect list and returning the string of the first match, so put the important + * ones first in the array. + * + * @param array $in_expectList the browser flags to search for + * + * @access public + * @return string first flag that matches + */ + function getBrowser($in_expectList) + { + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + foreach((array) $in_expectList as $brwsr) { + if (!empty($browser[strtolower($brwsr)])) { + return $brwsr; + } + } + } + + // }}} + // {{{ getBrowserString() + + /** + * This function returns the vendor string corresponding to the flag. + * + * Either use the default matches or pass in an associative array of + * flags and corresponding vendor strings. This function will find + * the highest version flag and return the vendor string corresponding + * to the appropriate flag. Be sure to pass in the flags in ascending order + * if you want a basic matches first, followed by more detailed matches. + * + * @param array $in_vendorStrings (optional) array of flags matched with vendor strings + * + * @access public + * @return string vendor string matches appropriate flag + */ + function getBrowserString($in_vendorStrings = null) + { + if (is_null($in_vendorStrings)) { + $in_vendorStrings = array ( + 'ie' => 'Microsoft Internet Explorer', + 'ie4up' => 'Microsoft Internet Explorer 4.x', + 'ie5up' => 'Microsoft Internet Explorer 5.x', + 'ie6up' => 'Microsoft Internet Explorer 6.x', + 'ie7up' => 'Microsoft Internet Explorer 7.x', + 'opera4' => 'Opera 4.x', + 'opera5up' => 'Opera 5.x', + 'nav' => 'Netscape Navigator', + 'ns4' => 'Netscape 4.x', + 'ns6up' => 'Mozilla/Netscape 6.x', + 'firefox0.x' => 'Firefox 0.x', + 'firefox1.x' => 'Firefox 1.x', + 'firefox1.5' => 'Firefox 1.5', + 'firefox2.x' => 'Firefox 2.x', + 'konq' => 'Konqueror/Safari', + 'netgem' => 'Netgem/iPlayer'); + } + + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + foreach((array) $in_vendorStrings as $flag => $string) { + if (!empty($browser[$flag])) { + $vendorString = $string; + } + } + + // if there are no matches just use the user agent leading idendifier (usually Mozilla) + if (!isset($vendorString)) { + $leadingIdentifier = &Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier'); + $vendorString = $leadingIdentifier; + } + + return $vendorString; + } + + // }}} + // {{{ isIE() + + /** + * Determine if the browser is an Internet Explorer browser + * + * @access public + * @return bool whether or not this browser is an ie browser + */ + function isIE() + { + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + return !empty($browser['ie']); + } + + // }}} + // {{{ isNavigator() + + /** + * Determine if the browser is a Netscape Navigator browser + * + * @access public + * @return bool whether or not this browser is a Netscape Navigator browser + */ + function isNavigator() + { + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + return !empty($browser['nav']); + } + + // }}} + // {{{ isNetscape() + + /** + * Determine if the browser is a Netscape or Mozilla browser + * + * Note that this function is not the same as isNavigator, since the + * new Mozilla browsers are still sponsered by Netscape, and hence are + * Netscape products, but not the original Navigators + * + * @access public + * @return bool whether or not this browser is a Netscape product + */ + function isNetscape() + { + Net_UserAgent_Detect::detect(); + $browser = &Net_UserAgent_Detect::_getStaticProperty('browser'); + return !empty($browser['ns4up']); + } + + // }}} + // {{{ isOS() + + /** + * Look up the provide OS flag and return a boolean value + * + * Given one of the flags listed in the properties, this function will return + * the value associated with that flag for the operating system. + * + * @param string $in_match flag to lookup + * + * @access public + * @return boolean whether or not the OS satisfies this flag + */ + function isOS($in_match) + { + Net_UserAgent_Detect::detect(); + $os = &Net_UserAgent_Detect::_getStaticProperty('os'); + return isset($os[strtolower($in_match)]) ? $os[strtolower($in_match)] : false; + } + + // }}} + // {{{ getOS() + + /** + * Since simply returning the "os" is somewhat ambiguous since there + * are different ways to classify the browser, this function works by taking + * an expect list and returning the string of the first match, so put the important + * ones first in the array. + * + * @access public + * @return string first flag that matches + */ + function getOS($in_expectList) + { + Net_UserAgent_Detect::detect(); + $os = &Net_UserAgent_Detect::_getStaticProperty('os'); + foreach((array) $in_expectList as $expectOs) { + if (!empty($os[strtolower($expectOs)])) { + return $expectOs; + } + } + } + + // }}} + // {{{ getOSString() + + /** + * This function returns the os string corresponding to the flag. + * + * Either use the default matches or pass in an associative array of + * flags and corresponding os strings. This function will find + * the highest version flag and return the os string corresponding + * to the appropriate flag. Be sure to pass in the flags in ascending order + * if you want a basic matches first, followed by more detailed matches. + * + * @param array $in_osStrings (optional) array of flags matched with os strings + * + * @access public + * @return string os string matches appropriate flag + */ + function getOSString($in_osStrings = null) + { + if (is_null($in_osStrings)) { + $in_osStrings = array( + 'win' => 'Microsoft Windows', + 'wince' => 'Microsoft Windows CE', + 'win9x' => 'Microsoft Windows 9x', + 'winme' => 'Microsoft Windows Millenium', + 'win2k' => 'Microsoft Windows 2000', + 'winnt' => 'Microsoft Windows NT', + 'winxp' => 'Microsoft Windows XP', + 'win2003' => 'Microsoft Windows 2003', + 'mac' => 'Macintosh', + 'unix' => 'Linux/Unix'); + } + + Net_UserAgent_Detect::detect(); + $osString = 'Unknown'; + + $os = &Net_UserAgent_Detect::_getStaticProperty('os'); + foreach((array) $in_osStrings as $flag => $string) { + if (!empty($os[$flag])) { + $osString = $string; + } + } + + return $osString; + } + + // }}} + // {{{ setQuirk() + + /** + * Set a unique behavior for the current browser. + * + * Many client browsers do some really funky things, and this + * mechanism allows the coder to determine if an excepetion must + * be made with the current client. + * + * @param string $in_quirk The quirk to set + * @param string $in_hasQuirk (optional) Does the browser have the quirk? + * + * @access public + * @return void + */ + function setQuirk($in_quirk, $in_hasQuirk = true) + { + $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks'); + $hasQuirk = !empty($in_hasQuirk); + $quirks[strtolower($in_quirk)] = $hasQuirk; + } + + // }}} + // {{{ hasQuirk() + + /** + * Check a unique behavior for the current browser. + * + * Many client browsers do some really funky things, and this + * mechanism allows the coder to determine if an excepetion must + * be made with the current client. + * + * @param string $in_quirk The quirk to detect + * + * @access public + * @return bool whether or not browser has this quirk + */ + function hasQuirk($in_quirk) + { + return (bool) Net_UserAgent_Detect::getQuirk($in_quirk); + } + + // }}} + // {{{ getQuirk() + + /** + * Get the unique behavior for the current browser. + * + * Many client browsers do some really funky things, and this + * mechanism allows the coder to determine if an excepetion must + * be made with the current client. + * + * @param string $in_quirk The quirk to detect + * + * @access public + * @return string value of the quirk, in this case usually a boolean + */ + function getQuirk($in_quirk) + { + Net_UserAgent_Detect::detect(); + $quirks = &Net_UserAgent_Detect::_getStaticProperty('quirks'); + return isset($quirks[strtolower($in_quirk)]) ? $quirks[strtolower($in_quirk)] : null; + } + + // }}} + // {{{ setFeature() + + /** + * Set capabilities for the current browser. + * + * Since the capabilities of client browsers vary widly, this interface + * helps keep track of the core features of a client, such as if the client + * supports dhtml, dom, javascript, etc. + * + * @param string $in_feature The feature to set + * @param string $in_hasFeature (optional) Does the browser have the feature? + * + * @access public + * @return void + */ + function setFeature($in_feature, $in_hasFeature = true) + { + $features = &Net_UserAgent_Detect::_getStaticProperty('features'); + $features[strtolower($in_feature)] = $in_hasFeature; + } + + // }}} + // {{{ hasFeature() + + /** + * Check the capabilities for the current browser. + * + * Since the capabilities of client browsers vary widly, this interface + * helps keep track of the core features of a client, such as if the client + * supports dhtml, dom, javascript, etc. + * + * @param string $in_feature The feature to detect + * + * @access public + * @return bool whether or not the current client has this feature + */ + function hasFeature($in_feature) + { + return (bool) Net_UserAgent_Detect::getFeature($in_feature); + } + + // }}} + // {{{ getFeature() + + /** + * Get the capabilities for the current browser. + * + * Since the capabilities of client browsers vary widly, this interface + * helps keep track of the core features of a client, such as if the client + * supports dhtml, dom, javascript, etc. + * + * @param string $in_feature The feature to detect + * + * @access public + * @return string value of the feature requested + */ + function getFeature($in_feature) + { + Net_UserAgent_Detect::detect(); + $features = &Net_UserAgent_Detect::_getStaticProperty('features'); + return isset($features[strtolower($in_feature)]) ? $features[strtolower($in_feature)] : null; + } + + // }}} + // {{{ getAcceptType() + + /** + * Retrive the accept type for the current browser. + * + * To keep track of the mime-types, languages, charsets and encodings + * that each browser accepts we use associative arrays for each type. + * This function works like getBrowser() as it takes an expect list + * and returns the first match. For instance, to find the language + * you would pass in your allowed languages and see if any of the + * languages set in the browser match. + * + * @param string $in_expectList values to check + * @param string $in_type type of accept + * + * @access public + * @return string the first matched value + */ + function getAcceptType($in_expectList, $in_type) + { + Net_UserAgent_Detect::detect(); + $type = strtolower($in_type); + + if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') { + $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type); + foreach((array) $in_expectList as $match) { + if (!empty($typeArray[$match])) { + return $match; + } + } + } + + return null; + } + + // }}} + // {{{ setAcceptType() + + /** + * Set the accept types for the current browser. + * + * To keep track of the mime-types, languages, charsets and encodings + * that each browser accepts we use associative arrays for each type. + * This function takes and array of accepted values for the type and + * records them for retrieval. + * + * @param array $in_values values of the accept type + * @param string $in_type type of accept + * + * @access public + * @return void + */ + function setAcceptType($in_values, $in_type) + { + $type = strtolower($in_type); + + if ($type == 'mimetype' || $type == 'language' || $type == 'charset' || $type == 'encoding') { + $typeArray = &Net_UserAgent_Detect::_getStaticProperty($type); + foreach((array) $in_values as $value) { + $typeArray[$value] = true; + } + } + } + + // }}} + // {{{ hasAcceptType() + + /** + * Check the accept types for the current browser. + * + * To keep track of the mime-types, languages, charsets and encodings + * that each browser accepts we use associative arrays for each type. + * This function checks the array for the given type and determines if + * the browser accepts it. + * + * @param string $in_value values to check + * @param string $in_type type of accept + * + * @access public + * @return bool whether or not the value is accept for this type + */ + function hasAcceptType($in_value, $in_type) + { + return (bool) Net_UserAgent_Detect::getAcceptType((array) $in_value, $in_type); + } + + // }}} + // {{{ getUserAgent() + + /** + * Return the user agent string that is being worked on + * + * @access public + * @return string user agent + */ + function getUserAgent() + { + Net_UserAgent_Detect::detect(); + $userAgent = &Net_UserAgent_Detect::_getStaticProperty('userAgent'); + return $userAgent; + } + + // }}} + // {{{ _getStaticProperty() + + /** + * Copy of getStaticProperty() from PEAR.php to avoid having to + * include PEAR.php + * + * @access private + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + function &_getStaticProperty($var) + { + static $properties; + return $properties[$var]; + } + + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Net/UserAgent/Detect/APC.php b/gulliver/thirdparty/pear/Net/UserAgent/Detect/APC.php new file mode 100644 index 000000000..467907217 --- /dev/null +++ b/gulliver/thirdparty/pear/Net/UserAgent/Detect/APC.php @@ -0,0 +1,114 @@ + | +// +----------------------------------------------------------------------+ + +// $Id: APC.php,v 1.1 2007/09/19 21:35:22 jrust Exp $ + +require_once 'Net_UserAgent/detect.php'; + +class Net_UserAgent_Detect_APC extends Net_UserAgent_Detect +{ + var $key = ''; + + function Net_UserAgent_Detect_APC($in_userAgent = null, $in_detect = null, $ua_cache_window = 600) + { + $data = ''; + $restored = false; + $ua_cache_timeout = apc_fetch('useragent:cache_timeout'); // don't cache after time period + + if ($ua_cache_window > 0) { + if (!$ua_cache_timeout) { + // check apc uptime and disable after x mins + $apc_data = apc_cache_info('file', true); + + if (isset($apc_data['start_time'])) { + $uptime = $apc_data['start_time']; + + if (time() - $uptime > $ua_cache_window) { // timeout and disable after 10 minutes of uptime + apc_store('useragent:cache_timeout', true); + $ua_cache_timeout = true; // don't cache this one either + } + } + } + + if (!$this->key) { + $key_flags = ''; + if ($in_detect !== null) { + $key_flags = implode('-', $in_detect); + } + $this->key = 'useragent:'.md5($in_userAgent.$key_flags); + } + + if ($data = apc_fetch($this->key)) { + $success = null; + $data = unserialize($data); + if ($data) { + $restored = $this->cache_restore($data); + } + } + } + + if (!$data) { + $this->detect($in_userAgent, $in_detect); + + if ($ua_cache_window > 0 && !$ua_cache_timeout) { + $this->cache_save(); + } + } + } + + function &singleton($in_userAgent = null, $in_detect = null) + { + static $instance; + + if (!isset($instance)) { + $instance = new Net_UserAgent_Detect_APC($in_userAgent, $in_detect); + } + + return $instance; + } + + function cache_restore($cache) + { + if (is_array($cache)) { + foreach($cache as $prop => $value) { + $ptr = Net_UserAgent_Detect::_getStaticProperty($prop); + $ptr = $value; + } + return true; + } + return false; + } + + function cache_save() + { + if ($this->key) { + $data = array('browser' => Net_UserAgent_Detect::_getStaticProperty('browser'), + 'features' => Net_UserAgent_Detect::_getStaticProperty('features'), + 'leadingIdentifier' => Net_UserAgent_Detect::_getStaticProperty('leadingIdentifier'), + 'majorVersion' => Net_UserAgent_Detect::_getStaticProperty('majorVersion'), + 'options' => Net_UserAgent_Detect::_getStaticProperty('options'), + 'os' => Net_UserAgent_Detect::_getStaticProperty('os'), + 'quirks' => Net_UserAgent_Detect::_getStaticProperty('quirks'), + 'subVersion' => Net_UserAgent_Detect::_getStaticProperty('subVersion'), + 'userAgent' => Net_UserAgent_Detect::_getStaticProperty('userAgent'), + 'version' => Net_UserAgent_Detect::_getStaticProperty('version'), + ); + apc_store($this->key, serialize($data)); + } + } +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words.php b/gulliver/thirdparty/pear/Numbers/Words.php new file mode 100644 index 000000000..7397a6437 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words.php @@ -0,0 +1,145 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Words.php,v 1.7 2003/09/29 12:23:58 makler Exp $ +// + +/** + * The Numbers_Words class provides method to convert arabic numerals to + * words (also with currency name). + * + * @author Piotr Klaban + * @package Numbers_Words + */ + +// {{{ Numbers_Words + +/** + * The Numbers_Words class provides method to convert arabic numerals to words. + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + * @package Numbers_Words + */ +class Numbers_Words +{ + // {{{ toWords() + + /** + * Converts a number to its word representation + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that should be converted to a words representation + * + * @param string $locale Language name abbreviation. Optional. Defaults to en_US. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $locale = 'en_US') { + + include_once("Numbers/Words/lang.${locale}.php"); + + $classname = "Numbers_Words_${locale}"; + + if (!class_exists($classname)) { + return Numbers_Words::raiseError("Unable to include the Numbers/Words/lang.${locale}.php file"); + } + + $methods = get_class_methods($classname); + + if (!in_array('toWords', $methods) && !in_array('towords', $methods)) { + return Numbers_Words::raiseError("Unable to find toWords method in '$classname' class"); + } + + @$obj =& new $classname; + + return trim($obj->toWords($num)); + } + // }}} + // {{{ toCurrency() + /** + * Converts a currency value to word representation (1.02 => one dollar two cents) + * If the number has not any fraction part, the "cents" number is omitted. + * + * @param float $num A float/integer number representing currency value + * + * @param string $locale Language name abbreviation. Optional. Defaults to en_US. + * + * @param string $int_curr International currency symbol + * as defined by the ISO 4217 standard (three characters). + * E.g. 'EUR', 'USD', 'PLN'. Optional. + * Defaults to $def_currency defined in the language class. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toCurrency($num, $locale = 'en_US', $int_curr = '') { + $ret = $num; + + @include_once("Numbers/Words/lang.${locale}.php"); + + $classname = "Numbers_Words_${locale}"; + + if (!class_exists($classname)) { + return Numbers_Words::raiseError("Unable to include the Numbers/Words/lang.${locale}.php file"); + } + + $methods = get_class_methods($classname); + + if (!in_array('toCurrencyWords', $methods) && !in_array('tocurrencywords', $methods)) { + return Numbers_Words::raiseError("Unable to find toCurrencyWords method in '$classname' class"); + } + + @$obj =& new $classname; + + if (strpos($num, '.') === false) + { + $ret = trim($obj->toCurrencyWords($int_curr, $num)); + } else { + $currency = explode('.', $num, 2); + $ret = trim($obj->toCurrencyWords($int_curr, $currency[0], $currency[1])); + } + return $ret; + } + // }}} + // {{{ raiseError() + /** + * Trigger a PEAR error + * + * To improve performances, the PEAR.php file is included dynamically. + * + * @param string error message + */ + function raiseError($msg) + { + include_once('PEAR.php'); + return PEAR::raiseError($msg); + } + // }}} +} + +// }}} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.bg.php b/gulliver/thirdparty/pear/Numbers/Words/lang.bg.php new file mode 100644 index 000000000..1204d29b7 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.bg.php @@ -0,0 +1,505 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id$ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Bulgarian. + * + * @author Kouber Saparev + * @package Numbers_Words + */ +class Numbers_Words_bg extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name. + * @var string + * @access public + */ + var $locale = 'bg'; + + /** + * Language name in English. + * @var string + * @access public + */ + var $lang = 'Bulgarian'; + + /** + * Native language name. + * @var string + * @access public + */ + var $lang_native = 'Áúëãàðñêè'; + + /** + * Some miscellaneous words and language constructs. + * @var string + * @access private + */ + var $_misc_strings = array( + 'deset'=>'äåñåò', // "ten" + 'edinadeset'=>'åäèíàäåñåò', // "eleven" + 'na'=>'íà', // liaison particle for 12 to 19 + 'sto'=>'ñòî', // "hundred" + 'sta'=>'ñòà', // suffix for 2 and 3 hundred + 'stotin'=>'ñòîòèí', // suffix for 4 to 9 hundred + 'hiliadi'=>'õèëÿäè' // plural form of "thousand" + ); + + + /** + * The words for digits (except zero). Note that, there are three genders for them (neuter, masculine and feminine). + * The words for 3 to 9 (masculine) and for 2 to 9 (feminine) are the same as neuter, so they're filled + * in the _initDigits() method, which is invoked from the constructor. + * @var string + * @access private + */ + var $_digits = array( + 0=>array(1=>"åäíî", "äâå", "òðè", "÷åòèðè", "ïåò", "øåñò", "ñåäåì", "îñåì", "äåâåò"), // neuter + 1=>array(1=>'åäèí', 'äâà'), // masculine + -1=>array(1=>'åäíà') // feminine + ); + + /** + * A flag, that determines if the _digits array is filled for masculine and feminine genders. + * @var string + * @access private + */ + var $_digits_initialized = false; + + /** + * A flag, that determines if the "and" word is placed already before the last non-empty group of digits. + * @var string + * @access private + */ + var $_last_and = false; + + /** + * The word for zero. + * @var string + * @access private + */ + var $_zero = 'íóëà'; + + /** + * The word for infinity. + * @var string + * @access private + */ + var $_infinity = 'áåçêðàéíîñò'; + + /** + * The word for the "and" language construct. + * @var string + * @access private + */ + var $_and = 'è'; + + /** + * The word separator. + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The word for the minus sign. + * @var string + * @access private + */ + var $_minus = 'ìèíóñ'; // minus sign + + /** + * The plural suffix (except for thousand). + * @var string + * @access private + */ + var $_plural = 'à'; // plural suffix + + /** + * The suffixes for exponents (singular). + * @var array + * @access private + */ + var $_exponent = array( + 0 => '', + 3 => 'õèëÿäà', + 6 => 'ìèëèîí', + 9 => 'ìèëèàðä', + 12 => 'òðèëèîí', + 15 => 'êâàäðèëèîí', + 18 => 'êâèíòèëèîí', + 21 => 'ñåêñòèëèîí', + 24 => 'ñåïòèëèîí', + 27 => 'îêòèëèîí', + 30 => 'íîíàëèîí', + 33 => 'äåêàëèîí', + 36 => 'óíäåêàëèîí', + 39 => 'äóîäåêàëèîí', + 42 => 'òðåäåêàëèîí', + 45 => 'êâàòîðäåêàëèîí', + 48 => 'êâèíòäåêàëèîí', + 51 => 'ñåêñäåêàëèîí', + 54 => 'ñåïòäåêàëèîí', + 57 => 'îêòîäåêàëèîí', + 60 => 'íîâåìäåêàëèîí', + 63 => 'âèãèíòèëèîí', + 66 => 'óíâèãèíòèëèîí', + 69 => 'äóîâèãèíòèëèîí', + 72 => 'òðåâèãèíòèëèîí', + 75 => 'êâàòîðâèãèíòèëèîí', + 78 => 'êâèíâèãèíòèëèîí', + 81 => 'ñåêñâèãèíòèëèîí', + 84 => 'ñåïòåíâèãèíòèëèîí', + 87 => 'îêòîâèãèíòèëèîí', + 90 => 'íîâåìâèãèíòèëèîí', + 93 => 'òðèãèíòèëèîí', + 96 => 'óíòðèãèíòèëèîí', + 99 => 'äóîòðèãèíòèëèîí', + 102 => 'òðåòðèãèíòèëèîí', + 105 => 'êâàòîðòðèãèíòèëèîí', + 108 => 'êâèíòðèãèíòèëèîí', + 111 => 'ñåêñòðèãèíòèëèîí', + 114 => 'ñåïòåíòðèãèíòèëèîí', + 117 => 'îêòîòðèãèíòèëèîí', + 120 => 'íîâåìòðèãèíòèëèîí', + 123 => 'êâàäðàãèíòèëèîí', + 126 => 'óíêâàäðàãèíòèëèîí', + 129 => 'äóîêâàäðàãèíòèëèîí', + 132 => 'òðåêâàäðàãèíòèëèîí', + 135 => 'êâàòîðêâàäðàãèíòèëèîí', + 138 => 'êâèíêâàäðàãèíòèëèîí', + 141 => 'ñåêñêâàäðàãèíòèëèîí', + 144 => 'ñåïòåíêâàäðàãèíòèëèîí', + 147 => 'îêòîêâàäðàãèíòèëèîí', + 150 => 'íîâåìêâàäðàãèíòèëèîí', + 153 => 'êâèíêâàãèíòèëèîí', + 156 => 'óíêâèíêàãèíòèëèîí', + 159 => 'äóîêâèíêàãèíòèëèîí', + 162 => 'òðåêâèíêàãèíòèëèîí', + 165 => 'êâàòîðêâèíêàãèíòèëèîí', + 168 => 'êâèíêâèíêàãèíòèëèîí', + 171 => 'ñåêñêâèíêàãèíòèëèîí', + 174 => 'ñåïòåíêâèíêàãèíòèëèîí', + 177 => 'îêòîêâèíêàãèíòèëèîí', + 180 => 'íîâåìêâèíêàãèíòèëèîí', + 183 => 'ñåêñàãèíòèëèîí', + 186 => 'óíñåêñàãèíòèëèîí', + 189 => 'äóîñåêñàãèíòèëèîí', + 192 => 'òðåñåêñàãèíòèëèîí', + 195 => 'êâàòîðñåêñàãèíòèëèîí', + 198 => 'êâèíñåêñàãèíòèëèîí', + 201 => 'ñåêññåêñàãèíòèëèîí', + 204 => 'ñåïòåíñåêñàãèíòèëèîí', + 207 => 'îêòîñåêñàãèíòèëèîí', + 210 => 'íîâåìñåêñàãèíòèëèîí', + 213 => 'ñåïòàãèíòèëèîí', + 216 => 'óíñåïòàãèíòèëèîí', + 219 => 'äóîñåïòàãèíòèëèîí', + 222 => 'òðåñåïòàãèíòèëèîí', + 225 => 'êâàòîðñåïòàãèíòèëèîí', + 228 => 'êâèíñåïòàãèíòèëèîí', + 231 => 'ñåêññåïòàãèíòèëèîí', + 234 => 'ñåïòåíñåïòàãèíòèëèîí', + 237 => 'îêòîñåïòàãèíòèëèîí', + 240 => 'íîâåìñåïòàãèíòèëèîí', + 243 => 'îêòîãèíòèëèîí', + 246 => 'óíîêòîãèíòèëèîí', + 249 => 'äóîîêòîãèíòèëèîí', + 252 => 'òðåîêòîãèíòèëèîí', + 255 => 'êâàòîðîêòîãèíòèëèîí', + 258 => 'êâèíîêòîãèíòèëèîí', + 261 => 'ñåêñîêòîãèíòèëèîí', + 264 => 'ñåïòîêòîãèíòèëèîí', + 267 => 'îêòîîêòîãèíòèëèîí', + 270 => 'íîâåìîêòîãèíòèëèîí', + 273 => 'íîíàãèíòèëèîí', + 276 => 'óííîíàãèíòèëèîí', + 279 => 'äóîíîíàãèíòèëèîí', + 282 => 'òðåíîíàãèíòèëèîí', + 285 => 'êâàòîðíîíàãèíòèëèîí', + 288 => 'êâèííîíàãèíòèëèîí', + 291 => 'ñåêñíîíàãèíòèëèîí', + 294 => 'ñåïòåííîíàãèíòèëèîí', + 297 => 'îêòîíîíàãèíòèëèîí', + 300 => 'íîâåìíîíàãèíòèëèîí', + 303 => 'öåíòèëèîí' + ); + // }}} + + // {{{ Numbers_Words_bg() + + /** + * The class constructor, used for calling the _initDigits method. + * + * @return void + * + * @access public + * @author Kouber Saparev + * @see function _initDigits + */ + function Numbers_Words_bg() { + $this->_initDigits(); + } + // }}} + + // {{{ _initDigits() + + /** + * Fills the _digits array for masculine and feminine genders with + * corresponding references to neuter words (when they're the same). + * + * @return void + * + * @access private + * @author Kouber Saparev + */ + function _initDigits() { + if (!$this->_digits_initialized) { + for ($i=3; $i<=9; $i++) { + $this->_digits[1][$i] =& $this->_digits[0][$i]; + } + for ($i=2; $i<=9; $i++) { + $this->_digits[-1][$i] =& $this->_digits[0][$i]; + } + $this->_digits_initialized = true; + } + } + // }}} + + // {{{ _splitNumber() + + /** + * Split a number to groups of three-digit numbers. + * + * @param mixed $num An integer or its string representation + * that need to be split + * + * @return array Groups of three-digit numbers. + * + * @access private + * @author Kouber Saparev + * @since PHP 4.2.3 + */ + + function _splitNumber($num) + { + if (is_string($num)) { + $ret = array(); + $strlen = strlen($num); + $first = substr($num, 0, $strlen%3); + preg_match_all('/\d{3}/', substr($num, $strlen%3, $strlen), $m); + $ret =& $m[0]; + if ($first) array_unshift($ret, $first); + return $ret; + } + else + return explode(' ', number_format($num, 0, '', ' ')); // a faster version for integers + } + // }}} + + // {{{ _showDigitsGroup() + + /** + * Converts a three-digit number to its word representation + * in Bulgarian language. + * + * @param integer $num An integer between 1 and 999 inclusive. + * + * @param integer $gender An integer which represents the gender of + * the current digits group. + * 0 - neuter + * 1 - masculine + * -1 - feminine + * + * @param boolean $last A flag that determines if the current digits group + * is the last one. + * + * @return string The words for the given number. + * + * @access private + * @author Kouber Saparev + */ + function _showDigitsGroup($num, $gender = 0, $last = false) + { + /* A storage array for the return string. + Positions 1, 3, 5 are intended for digit words + and everything else (0, 2, 4) for "and" words. + Both of the above types are optional, so the size of + the array may vary. + */ + $ret = array(); + + // extract the value of each digit from the three-digit number + $e = $num%10; // ones + $d = ($num-$e)%100/10; // tens + $s = ($num-$d*10-$e)%1000/100; // hundreds + + // process the "hundreds" digit. + if ($s) { + switch ($s) { + case 1: + $ret[1] = $this->_misc_strings['sto']; + break; + case 2: + case 3: + $ret[1] = $this->_digits[0][$s].$this->_misc_strings['sta']; + break; + default: + $ret[1] = $this->_digits[0][$s].$this->_misc_strings['stotin']; + } + } + + // process the "tens" digit, and optionally the "ones" digit. + if ($d) { + // in the case of 1, the "ones" digit also must be processed + if ($d==1) { + if (!$e) { + $ret[3] = $this->_misc_strings['deset']; // ten + } else { + if ($e==1) { + $ret[3] = $this->_misc_strings['edinadeset']; // eleven + } else { + $ret[3] = $this->_digits[1][$e].$this->_misc_strings['na'].$this->_misc_strings['deset']; // twelve - nineteen + } + // the "ones" digit is alredy processed, so skip a second processment + $e = 0; + } + } else { + $ret[3] = $this->_digits[1][$d].$this->_misc_strings['deset']; // twenty - ninety + } + } + + // process the "ones" digit + if ($e) { + $ret[5] = $this->_digits[$gender][$e]; + } + + // put "and" where needed + if (count($ret)>1) { + if ($e) { + $ret[4] = $this->_and; + } else { + $ret[2] = $this->_and; + } + } + + // put "and" optionally in the case this is the last non-empty group + if ($last) { + if (!$s||count($ret)==1) { + $ret[0] = $this->_and; + } + $this->_last_and = true; + } + + // sort the return array so that "and" constructs go to theirs appropriate places + ksort($ret); + + return implode($this->_sep, $ret); + } + // }}} + + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Bulgarian language. + * + * @param integer $num An integer between 9.99*-10^302 and 9.99*10^302 (999 centillions) + * that need to be converted to words + * + * @return string The corresponding word representation + * + * @access public + * @author Kouber Saparev + */ + function toWords($num = 0) + { + $ret = array(); + $ret_minus = ''; + + // check if $num is a valid non-zero number + if (!$num || preg_match('/^-?0+$/', $num) || !preg_match('/^-?\d+$/', $num)) return $this->_zero; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret_minus = $this->_minus . $this->_sep; + $num = substr($num, 1); + } + + // if the absolute value is greater than 9.99*10^302, return infinity + if (strlen($num)>306) { + return $ret_minus . $this->_infinity; + } + + // strip excessive zero signs + $num = ltrim($num, '0'); + + // split $num to groups of three-digit numbers + $num_groups = $this->_splitNumber($num); + + $sizeof_numgroups = count($num_groups); + + // go through the groups in reverse order, so that the last group could be determined + for ($i=$sizeof_numgroups-1, $j=1; $i>=0; $i--, $j++) { + if (!isset($ret[$j])) { + $ret[$j] = ''; + } + + // what is the corresponding exponent for the current group + $pow = $sizeof_numgroups-$i; + + // skip processment for empty groups + if ($num_groups[$i]!='000') { + if ($num_groups[$i]>1) { + if ($pow==1) { + $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 0, !$this->_last_and && $i).$this->_sep; + $ret[$j] .= $this->_exponent[($pow-1)*3]; + } elseif ($pow==2) { + $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], -1, !$this->_last_and && $i).$this->_sep; + $ret[$j] .= $this->_misc_strings['hiliadi'].$this->_sep; + } else { + $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 1, !$this->_last_and && $i).$this->_sep; + $ret[$j] .= $this->_exponent[($pow-1)*3].$this->_plural.$this->_sep; + } + } else { + if ($pow==1) { + $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 0, !$this->_last_and && $i).$this->_sep; + } elseif ($pow==2) { + $ret[$j] .= $this->_exponent[($pow-1)*3].$this->_sep; + } else { + $ret[$j] .= $this->_digits[1][1].$this->_sep.$this->_exponent[($pow-1)*3].$this->_sep; + } + } + } + } + + return $ret_minus . rtrim(implode('', array_reverse($ret)), $this->_sep); + } + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.de.php b/gulliver/thirdparty/pear/Numbers/Words/lang.de.php new file mode 100644 index 000000000..5d6026d26 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.de.php @@ -0,0 +1,318 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.de.php,v 1.5 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in German language. +// + +/** + * + * Class for translating numbers into German. + * @author Piotr Klaban + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into German. + * + * @author Piotr Klaban + * @package Numbers_Words + */ +class Numbers_Words_de extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'de'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'German'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Deutsch'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'Minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names partly based on: + * http://german.about.com/library/blzahlenaud.htm + * http://www3.osk.3web.ne.jp/~nagatani/common/zahlwort.htm + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 3 => array('tausend','tausend'), + 6 => array('Millione','Millionen'), + 9 => array('Milliarde','Milliarden'), + 12 => array('Billion','Billionen'), + 15 => array('Billiarde','Billiarden'), + 18 => array('Trillion','Trillionen'), + 21 => array('Trilliarde','Trilliarden'), + 24 => array('Quadrillion','Quadrillionen'), + 27 => array('Quadrilliarde','Quadrilliarden'), + 30 => array('Quintillion','Quintillionen'), + 33 => array('Quintilliarde','Quintilliarden'), + 36 => array('Sextillion','Sextillionen'), + 39 => array('Sextilliarde','Sextilliarden'), + 42 => array('Septillion','Septillionen'), + 45 => array('Septilliarde','Septilliarden'), + 48 => array('Oktillion','Oktillionen'), // oder Octillionen + 51 => array('Oktilliarde','Oktilliarden'), + 54 => array('Nonillion','Nonillionen'), + 57 => array('Nonilliarde','Nonilliarden'), + 60 => array('Dezillion','Dezillionen'), + 63 => array('Dezilliarde','Dezilliarden'), + 120 => array('Vigintillion','Vigintillionen'), + 123 => array('Vigintilliarde','Vigintilliarden'), + 600 => array('Zentillion','Zentillionen'), // oder Centillion + 603 => array('Zentilliarde','Zentilliarden') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'null', 'ein', 'zwei', 'drei', 'vier', + 'fünf', 'sechs', 'sieben', 'acht', 'neun' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ''; + + /** + * The exponent word separator + * @var string + * @access private + */ + var $_sep2 = ' '; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in German language. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access private + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'hundert'; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + if ($t > 0) { + $ret .= $this->_digits[$d] . 'und'; + } else { + $ret .= $this->_digits[$d]; + if ($d == 1) + if ($power == 0) + $ret .= 's'; // fuer eins + else + $ret .= 'e'; // fuer eine + } + } + + // ten, twenty etc. + switch ($t) { + case 9: + case 8: + case 5: + $ret .= $this->_sep . $this->_digits[$t] . 'zig'; + break; + + case 7: + $ret .= $this->_sep . 'siebzig'; + break; + + case 6: + $ret .= $this->_sep . 'sechzig'; + break; + + case 4: + $ret .= $this->_sep . 'vierzig'; + break; + + case 3: + $ret .= $this->_sep . 'dreißig'; + break; + + case 2: + $ret .= $this->_sep . 'zwanzig'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'zehn'; + break; + + case 1: + $ret .= $this->_sep . 'elf'; + break; + + case 2: + $ret .= $this->_sep . 'zwölf'; + break; + + case 3: + case 4: + case 5: + case 8: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . 'zehn'; + break; + + case 6: + $ret .= $this->_sep . 'sechzehn'; + break; + + case 7: + $ret .= $this->_sep . 'siebzehn'; + break; + } + break; + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + if ($power == 3) + $ret .= $this->_sep . $lev[0]; + elseif ($d == 1 && ($t+$h) == 0) + $ret .= $this->_sep2 . $lev[0] . $this->_sep2; + else + $ret .= $this->_sep2 . $lev[1] . $this->_sep2; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.ee.php b/gulliver/thirdparty/pear/Numbers/Words/lang.ee.php new file mode 100644 index 000000000..2b27d1f1e --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.ee.php @@ -0,0 +1,349 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.ee.php,v 1.5 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Estonian language. +// + +/** + * Class for translating numbers into Estonian. + * + * @author Erkki Saarniit + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Estonian. + * + * @author Erkki Saarniit + * @package Numbers_Words + */ +class Numbers_Words_ee extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'ee'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Estonian'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'eesti keel'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'miinus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names partly based on: + * http://home.earthlink.net/~mrob/pub/math/largenum.html + * http://mathforum.org/dr.math/faq/faq.large.numbers.html + * http://www.mazes.com/AmericanNumberingSystem.html + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 3 => array('tuhat'), + 6 => array('miljon'), + 9 => array('miljard'), + 12 => array('triljon'), + 15 => array('kvadriljon'), + 18 => array('kvintiljon'), + 21 => array('sekstiljon'), + 24 => array('septiljon'), + 27 => array('oktiljon'), + 30 => array('noniljon'), + 33 => array('dekiljon'), + 36 => array('undekiljon'), + 39 => array('duodekiljon'), + 42 => array('tredekiljon'), + 45 => array('kvattuordekiljon'), + 48 => array('kvindekiljon'), + 51 => array('seksdekiljon'), + 54 => array('septendekiljon'), + 57 => array('oktodekiljon'), + 60 => array('novemdekiljon'), + 63 => array('vigintiljon'), + 66 => array('unvigintiljon'), + 69 => array('duovigintiljon'), + 72 => array('trevigintiljon'), + 75 => array('kvattuorvigintiljon'), + 78 => array('kvinvigintiljon'), + 81 => array('seksvigintiljon'), + 84 => array('septenvigintiljon'), + 87 => array('oktovigintiljon'), + 90 => array('novemvigintiljon'), + 93 => array('trigintiljon'), + 96 => array('untrigintiljon'), + 99 => array('duotrigintiljon'), + 102 => array('trestrigintiljon'), + 105 => array('kvattuortrigintiljon'), + 108 => array('kvintrigintiljon'), + 111 => array('sekstrigintiljon'), + 114 => array('septentrigintiljon'), + 117 => array('oktotrigintiljon'), + 120 => array('novemtrigintiljon'), + 123 => array('kvadragintiljon'), + 126 => array('unkvadragintiljon'), + 129 => array('duokvadragintiljon'), + 132 => array('trekvadragintiljon'), + 135 => array('kvattuorkvadragintiljon'), + 138 => array('kvinkvadragintiljon'), + 141 => array('sekskvadragintiljon'), + 144 => array('septenkvadragintiljon'), + 147 => array('oktokvadragintiljon'), + 150 => array('novemkvadragintiljon'), + 153 => array('kvinkvagintiljon'), + 156 => array('unkvinkvagintiljon'), + 159 => array('duokvinkvagintiljon'), + 162 => array('trekvinkvagintiljon'), + 165 => array('kvattuorkvinkvagintiljon'), + 168 => array('kvinkvinkvagintiljon'), + 171 => array('sekskvinkvagintiljon'), + 174 => array('septenkvinkvagintiljon'), + 177 => array('oktokvinkvagintiljon'), + 180 => array('novemkvinkvagintiljon'), + 183 => array('seksagintiljon'), + 186 => array('unseksagintiljon'), + 189 => array('duoseksagintiljon'), + 192 => array('treseksagintiljon'), + 195 => array('kvattuorseksagintiljon'), + 198 => array('kvinseksagintiljon'), + 201 => array('seksseksagintiljon'), + 204 => array('septenseksagintiljon'), + 207 => array('oktoseksagintiljon'), + 210 => array('novemseksagintiljon'), + 213 => array('septuagintiljon'), + 216 => array('unseptuagintiljon'), + 219 => array('duoseptuagintiljon'), + 222 => array('treseptuagintiljon'), + 225 => array('kvattuorseptuagintiljon'), + 228 => array('kvinseptuagintiljon'), + 231 => array('seksseptuagintiljon'), + 234 => array('septenseptuagintiljon'), + 237 => array('oktoseptuagintiljon'), + 240 => array('novemseptuagintiljon'), + 243 => array('oktogintiljon'), + 246 => array('unoktogintiljon'), + 249 => array('duooktogintiljon'), + 252 => array('treoktogintiljon'), + 255 => array('kvattuoroktogintiljon'), + 258 => array('kvinoktogintiljon'), + 261 => array('seksoktogintiljon'), + 264 => array('septoktogintiljon'), + 267 => array('oktooktogintiljon'), + 270 => array('novemoktogintiljon'), + 273 => array('nonagintiljon'), + 276 => array('unnonagintiljon'), + 279 => array('duononagintiljon'), + 282 => array('trenonagintiljon'), + 285 => array('kvattuornonagintiljon'), + 288 => array('kvinnonagintiljon'), + 291 => array('seksnonagintiljon'), + 294 => array('septennonagintiljon'), + 297 => array('oktononagintiljon'), + 300 => array('novemnonagintiljon'), + 303 => array('kentiljon'), + 309 => array('duokentiljon'), + 312 => array('trekentiljon'), + 366 => array('primo-vigesimo-kentiljon'), + 402 => array('trestrigintakentiljon'), + 603 => array('dukentiljon'), + 624 => array('septendukentiljon'), + 2421 => array('seksoktingentiljon'), + 3003 => array('milliljon'), + 3000003 => array('milli-milliljon') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'null', 'üks', 'kaks', 'kolm', 'neli', + 'viis', 'kuus', 'seitse', 'kaheksa', 'üheksa' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Estonian language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + if (isset($this->_exponent[$p])) { + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + $ret .= $this->_sep . $this->_digits[$h] . 'sada'; + + } + + switch ($t) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 3: + case 2: + $ret .= $this->_sep . $this->_digits[$t] . 'kümmend'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'kümme'; + break; + + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . 'teist'; + break; + } + break; + } + if ($t != 1 && $d > 0) { + if ($t > 1) { + $ret .= ' ' . $this->_digits[$d]; + } else { + $ret .= $this->_sep . $this->_digits[$d]; + } + } + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + $ret .= $this->_sep . $lev[0].($num != 1 && $power!= 3 ? 'it' : ''); + } + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.en_100.php b/gulliver/thirdparty/pear/Numbers/Words/lang.en_100.php new file mode 100644 index 000000000..0032622ac --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.en_100.php @@ -0,0 +1,307 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.en_100.php,v 1.6 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Donald Knuth system, in English language. +// + +/** + * Class for translating numbers into Donald Knuth system, in English language. + * + * @author Piotr Klaban + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Donald Knuth system, in English language. + * + * @author Piotr Klaban + * @package Numbers_Words + */ +class Numbers_Words_en_100 extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'en_100'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'English (Donald Knuth system)'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'English (Donald Knuth system)'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names based on: + * http://home.earthlink.net/~mrob/pub/math/largenum.html + * Donald Knuth system (power of 2) + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 2 => array('hundred'), + 4 => array('myriad'), + 8 => array('myllion'), + 16 => array('byllion'), + 32 => array('tryllion'), + 64 => array('quadryllion'), + 128 => array('quintyllion'), + 256 => array('sextyllion'), + 512 => array('septyllion'), + 1024 => array('octyllion'), + 2048 => array('nonyllion'), + 4096 => array('decyllion'), + 8192 => array('undecyllion'), + 16384 => array('duodecyllion'), + 32768 => array('tredecyllion'), + 65536 => array('quattuordecyllion'), + 131072 => array('quindecyllion'), + 262144 => array('sexdecyllion'), + 524288 => array('septendecyllion'), + 1048576 => array('octodecyllion'), + 2097152 => array('novemdecyllion'), + 4194304 => array('vigintyllion') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'zero', 'one', 'two', 'three', 'four', + 'five', 'six', 'seven', 'eight', 'nine' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + // }}} + // {{{ toWords() + /** + * Converts a number to its word representation + * in Donald Knuth system, in English language. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, ''); // $cursuffix); + // normally cursuffix is added at the end, but not here + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'hundred'; + + // in English only - add ' and' for [1-9]01..[1-9]99 + // (also for 1001..1099, 10001..10099 but it is harder) + // for now it is switched off, maybe some language purists + // can force me to enable it, or to remove it completely + // if (($t + $d) > 0) + // $ret .= $this->_sep . 'and'; + } + + // ten, twenty etc. + switch ($t) { + case 9: + case 7: + case 6: + $ret .= $this->_sep . $this->_digits[$t] . 'ty'; + break; + + case 8: + $ret .= $this->_sep . 'eighty'; + break; + + case 5: + $ret .= $this->_sep . 'fifty'; + break; + + case 4: + $ret .= $this->_sep . 'forty'; + break; + + case 3: + $ret .= $this->_sep . 'thirty'; + break; + + case 2: + $ret .= $this->_sep . 'twenty'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'ten'; + break; + + case 1: + $ret .= $this->_sep . 'eleven'; + break; + + case 2: + $ret .= $this->_sep . 'twelve'; + break; + + case 3: + $ret .= $this->_sep . 'thirteen'; + break; + + case 4: + case 6: + case 7: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . 'teen'; + break; + + case 5: + $ret .= $this->_sep . 'fifteen'; + break; + + case 8: + $ret .= $this->_sep . 'eighteen'; + break; + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + // add minus sign between [2-9] and digit + if ($t > 1) { + $ret .= '-' . $this->_digits[$d]; + } else { + $ret .= $this->_sep . $this->_digits[$d]; + } + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.en_GB.php b/gulliver/thirdparty/pear/Numbers/Words/lang.en_GB.php new file mode 100644 index 000000000..961aed54b --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.en_GB.php @@ -0,0 +1,308 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.en_GB.php,v 1.7 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in British English language. +// + +/** + * Class for translating numbers into British English. + * + * @author Piotr Klaban + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into British English. + * + * @author Piotr Klaban + * @package Numbers_Words + */ +class Numbers_Words_en_GB extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'en_GB'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'British English'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'British English'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names partly based on: + * http://www.users.dircon.co.uk/~shaunf/shaun/numbers/millions.htm + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 3 => array('thousand'), + 6 => array('million'), + 12 => array('billion'), + 18 => array('trillion'), + 24 => array('quadrillion'), + 30 => array('quintillion'), + 36 => array('sextillion'), + 42 => array('septillion'), + 48 => array('octillion'), + 54 => array('nonillion'), + 60 => array('decillion'), + 66 => array('undecillion'), + 72 => array('duodecillion'), + 78 => array('tredecillion'), + 84 => array('quattuordecillion'), + 90 => array('quindecillion'), + 96 => array('sexdecillion'), + 102 => array('septendecillion'), + 108 => array('octodecillion'), + 114 => array('novemdecillion'), + 120 => array('vigintillion'), + 192 => array('duotrigintillion'), + 600 => array('centillion') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'zero', 'one', 'two', 'three', 'four', + 'five', 'six', 'seven', 'eight', 'nine' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in British English language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'hundred'; + + // in English only - add ' and' for [1-9]01..[1-9]99 + // (also for 1001..1099, 10001..10099 but it is harder) + // for now it is switched off, maybe some language purists + // can force me to enable it, or to remove it completely + // if (($t + $d) > 0) + // $ret .= $this->_sep . 'and'; + } + + // ten, twenty etc. + switch ($t) { + case 9: + case 7: + case 6: + $ret .= $this->_sep . $this->_digits[$t] . 'ty'; + break; + + case 8: + $ret .= $this->_sep . 'eighty'; + break; + + case 5: + $ret .= $this->_sep . 'fifty'; + break; + + case 4: + $ret .= $this->_sep . 'forty'; + break; + + case 3: + $ret .= $this->_sep . 'thirty'; + break; + + case 2: + $ret .= $this->_sep . 'twenty'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'ten'; + break; + + case 1: + $ret .= $this->_sep . 'eleven'; + break; + + case 2: + $ret .= $this->_sep . 'twelve'; + break; + + case 3: + $ret .= $this->_sep . 'thirteen'; + break; + + case 4: + case 6: + case 7: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . 'teen'; + break; + + case 5: + $ret .= $this->_sep . 'fifteen'; + break; + + case 8: + $ret .= $this->_sep . 'eighteen'; + break; + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + // add minus sign between [2-9] and digit + if ($t > 1) { + $ret .= '-' . $this->_digits[$d]; + } else { + $ret .= $this->_sep . $this->_digits[$d]; + } + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.en_US.php b/gulliver/thirdparty/pear/Numbers/Words/lang.en_US.php new file mode 100644 index 000000000..47e2f7bfa --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.en_US.php @@ -0,0 +1,509 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.en_US.php,v 1.7 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in American English language. +// + +/** + * Class for translating numbers into American English. + * + * @author Piotr Klaban + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into American English. + * + * @author Piotr Klaban + * @package Numbers_Words + */ +class Numbers_Words_en_US extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'en_US'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'American English'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'American English'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names partly based on: + * http://home.earthlink.net/~mrob/pub/math/largenum.html + * http://mathforum.org/dr.math/faq/faq.large.numbers.html + * http://www.mazes.com/AmericanNumberingSystem.html + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 3 => array('thousand'), + 6 => array('million'), + 9 => array('billion'), + 12 => array('trillion'), + 15 => array('quadrillion'), + 18 => array('quintillion'), + 21 => array('sextillion'), + 24 => array('septillion'), + 27 => array('octillion'), + 30 => array('nonillion'), + 33 => array('decillion'), + 36 => array('undecillion'), + 39 => array('duodecillion'), + 42 => array('tredecillion'), + 45 => array('quattuordecillion'), + 48 => array('quindecillion'), + 51 => array('sexdecillion'), + 54 => array('septendecillion'), + 57 => array('octodecillion'), + 60 => array('novemdecillion'), + 63 => array('vigintillion'), + 66 => array('unvigintillion'), + 69 => array('duovigintillion'), + 72 => array('trevigintillion'), + 75 => array('quattuorvigintillion'), + 78 => array('quinvigintillion'), + 81 => array('sexvigintillion'), + 84 => array('septenvigintillion'), + 87 => array('octovigintillion'), + 90 => array('novemvigintillion'), + 93 => array('trigintillion'), + 96 => array('untrigintillion'), + 99 => array('duotrigintillion'), + // 100 => array('googol') - not latin name + // 10^googol = 1 googolplex + 102 => array('trestrigintillion'), + 105 => array('quattuortrigintillion'), + 108 => array('quintrigintillion'), + 111 => array('sextrigintillion'), + 114 => array('septentrigintillion'), + 117 => array('octotrigintillion'), + 120 => array('novemtrigintillion'), + 123 => array('quadragintillion'), + 126 => array('unquadragintillion'), + 129 => array('duoquadragintillion'), + 132 => array('trequadragintillion'), + 135 => array('quattuorquadragintillion'), + 138 => array('quinquadragintillion'), + 141 => array('sexquadragintillion'), + 144 => array('septenquadragintillion'), + 147 => array('octoquadragintillion'), + 150 => array('novemquadragintillion'), + 153 => array('quinquagintillion'), + 156 => array('unquinquagintillion'), + 159 => array('duoquinquagintillion'), + 162 => array('trequinquagintillion'), + 165 => array('quattuorquinquagintillion'), + 168 => array('quinquinquagintillion'), + 171 => array('sexquinquagintillion'), + 174 => array('septenquinquagintillion'), + 177 => array('octoquinquagintillion'), + 180 => array('novemquinquagintillion'), + 183 => array('sexagintillion'), + 186 => array('unsexagintillion'), + 189 => array('duosexagintillion'), + 192 => array('tresexagintillion'), + 195 => array('quattuorsexagintillion'), + 198 => array('quinsexagintillion'), + 201 => array('sexsexagintillion'), + 204 => array('septensexagintillion'), + 207 => array('octosexagintillion'), + 210 => array('novemsexagintillion'), + 213 => array('septuagintillion'), + 216 => array('unseptuagintillion'), + 219 => array('duoseptuagintillion'), + 222 => array('treseptuagintillion'), + 225 => array('quattuorseptuagintillion'), + 228 => array('quinseptuagintillion'), + 231 => array('sexseptuagintillion'), + 234 => array('septenseptuagintillion'), + 237 => array('octoseptuagintillion'), + 240 => array('novemseptuagintillion'), + 243 => array('octogintillion'), + 246 => array('unoctogintillion'), + 249 => array('duooctogintillion'), + 252 => array('treoctogintillion'), + 255 => array('quattuoroctogintillion'), + 258 => array('quinoctogintillion'), + 261 => array('sexoctogintillion'), + 264 => array('septoctogintillion'), + 267 => array('octooctogintillion'), + 270 => array('novemoctogintillion'), + 273 => array('nonagintillion'), + 276 => array('unnonagintillion'), + 279 => array('duononagintillion'), + 282 => array('trenonagintillion'), + 285 => array('quattuornonagintillion'), + 288 => array('quinnonagintillion'), + 291 => array('sexnonagintillion'), + 294 => array('septennonagintillion'), + 297 => array('octononagintillion'), + 300 => array('novemnonagintillion'), + 303 => array('centillion'), + 309 => array('duocentillion'), + 312 => array('trecentillion'), + 366 => array('primo-vigesimo-centillion'), + 402 => array('trestrigintacentillion'), + 603 => array('ducentillion'), + 624 => array('septenducentillion'), + // bug on a earthlink page: 903 => array('trecentillion'), + 2421 => array('sexoctingentillion'), + 3003 => array('millillion'), + 3000003 => array('milli-millillion') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'zero', 'one', 'two', 'three', 'four', + 'five', 'six', 'seven', 'eight', 'nine' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The currency names (based on the below links, + * informations from central bank websites and on encyclopedias) + * + * @var array + * @link http://30-03-67.dreamstation.com/currency_alfa.htm World Currency Information + * @link http://www.jhall.demon.co.uk/currency/by_abbrev.html World currencies + * @link http://www.shoestring.co.kr/world/p.visa/change.htm Currency names in English + * @access private + */ + var $_currency_names = array( + 'ALL' => array(array('lek'), array('qindarka')), + 'AUD' => array(array('Australian dollar'), array('cent')), + 'BAM' => array(array('convertible marka'), array('fenig')), + 'BGN' => array(array('lev'), array('stotinka')), + 'BRL' => array(array('real'), array('centavos')), + 'BYR' => array(array('Belarussian rouble'), array('kopiejka')), + 'CAD' => array(array('Canadian dollar'), array('cent')), + 'CHF' => array(array('Swiss franc'), array('rapp')), + 'CYP' => array(array('Cypriot pound'), array('cent')), + 'CZK' => array(array('Czech koruna'), array('halerz')), + 'DKK' => array(array('Danish krone'), array('ore')), + 'EEK' => array(array('kroon'), array('senti')), + 'EUR' => array(array('euro'), array('euro-cent')), + 'GBP' => array(array('pound', 'pounds'), array('pence')), + 'HKD' => array(array('Hong Kong dollar'), array('cent')), + 'HRK' => array(array('Croatian kuna'), array('lipa')), + 'HUF' => array(array('forint'), array('filler')), + 'ISK' => array(array('Icelandic króna'), array('aurar')), + 'JPY' => array(array('yen'), array('sen')), + 'LTL' => array(array('litas'), array('cent')), + 'LVL' => array(array('lat'), array('sentim')), + 'MKD' => array(array('Macedonian dinar'), array('deni')), + 'MTL' => array(array('Maltese lira'), array('centym')), + 'NOK' => array(array('Norwegian krone'), array('oere')), + 'PLN' => array(array('zloty', 'zlotys'), array('grosz')), + 'ROL' => array(array('Romanian leu'), array('bani')), + 'RUB' => array(array('Russian Federation rouble'), array('kopiejka')), + 'SEK' => array(array('Swedish krona'), array('oere')), + 'SIT' => array(array('Tolar'), array('stotinia')), + 'SKK' => array(array('Slovak koruna'), array()), + 'TRL' => array(array('lira'), array('kuruþ')), + 'UAH' => array(array('hryvna'), array('cent')), + 'USD' => array(array('dollar'), array('cent')), + 'YUM' => array(array('dinars'), array('para')), + 'ZAR' => array(array('rand'), array('cent')), + 'MXN' => array(array('Mexican Peso'), array('cent')) + ); + + /** + * The default currency name + * @var string + * @access public + */ + var $def_currency = 'USD'; // Polish zloty + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in American English language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'hundred'; + + // in English only - add ' and' for [1-9]01..[1-9]99 + // (also for 1001..1099, 10001..10099 but it is harder) + // for now it is switched off, maybe some language purists + // can force me to enable it, or to remove it completely + // if (($t + $d) > 0) + // $ret .= $this->_sep . 'and'; + } + + // ten, twenty etc. + switch ($t) { + case 9: + case 7: + case 6: + $ret .= $this->_sep . $this->_digits[$t] . 'ty'; + break; + + case 8: + $ret .= $this->_sep . 'eighty'; + break; + + case 5: + $ret .= $this->_sep . 'fifty'; + break; + + case 4: + $ret .= $this->_sep . 'forty'; + break; + + case 3: + $ret .= $this->_sep . 'thirty'; + break; + + case 2: + $ret .= $this->_sep . 'twenty'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'ten'; + break; + + case 1: + $ret .= $this->_sep . 'eleven'; + break; + + case 2: + $ret .= $this->_sep . 'twelve'; + break; + + case 3: + $ret .= $this->_sep . 'thirteen'; + break; + + case 4: + case 6: + case 7: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . 'teen'; + break; + + case 5: + $ret .= $this->_sep . 'fifteen'; + break; + + case 8: + $ret .= $this->_sep . 'eighteen'; + break; + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + // add minus sign between [2-9] and digit + if ($t > 1) { + $ret .= '-' . $this->_digits[$d]; + } else { + $ret .= $this->_sep . $this->_digits[$d]; + } + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} + // {{{ toCurrency() + + /** + * Converts a currency value to its word representation + * (with monetary units) in English language + * + * @param integer $int_curr An international currency symbol + * as defined by the ISO 4217 standard (three characters) + * @param integer $decimal A money total amount without fraction part (e.g. amount of dollars) + * @param integer $fraction Fractional part of the money amount (e.g. amount of cents) + * Optional. Defaults to false. + * + * @return string The corresponding word representation for the currency + * + * @access public + * @author Piotr Klaban + * @since Numbers_Words 0.4 + */ + function toCurrencyWords($int_curr, $decimal, $fraction = false) { + $int_curr = strtoupper($int_curr); + if (!isset($this->_currency_names[$int_curr])) { + $int_curr = $this->def_currency; + } + $curr_names = $this->_currency_names[$int_curr]; + $ret = trim($this->toWords($decimal)); + $lev = ($decimal == 1) ? 0 : 1; + if ($lev > 0) { + if (count($curr_names[0]) > 1) { + $ret .= $this->_sep . $curr_names[0][$lev]; + } else { + $ret .= $this->_sep . $curr_names[0][0] . 's'; + } + } else { + $ret .= $this->_sep . $curr_names[0][0]; + } + + if ($fraction !== false) { + $ret .= $this->_sep . trim($this->toWords($fraction)); + $lev = ($fraction == 1) ? 0 : 1; + if ($lev > 0) { + if (count($curr_names[1]) > 1) { + $ret .= $this->_sep . $curr_names[1][$lev]; + } else { + $ret .= $this->_sep . $curr_names[1][0] . 's'; + } + } else { + $ret .= $this->_sep . $curr_names[1][0]; + } + } + return $ret; + } + // }}} + +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.es.php b/gulliver/thirdparty/pear/Numbers/Words/lang.es.php new file mode 100644 index 000000000..267937c28 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.es.php @@ -0,0 +1,343 @@ + array('',''), + 3 => array('mil','mil'), + 6 => array('millón','millones'), + 12 => array('billón','billones'), + 18 => array('trilón','trillones'), + 24 => array('cuatrillón','cuatrillones'), + 30 => array('quintillón','quintillones'), + 36 => array('sextillón','sextillones'), + 42 => array('septillón','septillones'), + 48 => array('octallón','octallones'), + 54 => array('nonallón','nonallones'), + 60 => array('decallón','decallones'), + ); + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'cero', 'uno', 'dos', 'tres', 'cuatro', + 'cinco', 'seis', 'siete', 'ocho', 'nueve' + ); + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + // }}} + // {{{ toWords() + /** + * Converts a number to its word representation + * in Spanish (Castellano). + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that should be converted to a words representation + * @param integer $power The power of ten for the rest of the number to the right. + * For example toWords(12,3) should give "doce mil". + * Optional, defaults to 0. + * @return string The corresponding word representation + * + * @access private + * @author Xavier Noguer + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0) + { + // The return string; + $ret = ''; + + // add a the word for the minus sign if necessary + if (substr($num, 0, 1) == '-') + { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + + // strip excessive zero signs + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 6) + { + $current_power = 6; + // check for highest power + if (isset($this->_exponent[$power])) + { + // convert the number above the first 6 digits + // with it's corresponding $power. + $snum = substr($num, 0, -6); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $ret .= $this->toWords($snum, $power + 6); + } + } + $num = substr($num, -6); + if ($num == 0) { + return $ret; + } + } + elseif ($num == 0 || $num == '') { + return(' '.$this->_digits[0]); + $current_power = strlen($num); + } + else { + $current_power = strlen($num); + } + + // See if we need "thousands" + $thousands = floor($num / 1000); + if ($thousands == 1) { + $ret .= $this->_sep . 'mil'; + } + elseif ($thousands > 1) { + $ret .= $this->toWords($thousands, 3); + } + + // values for digits, tens and hundreds + $h = floor(($num / 100) % 10); + $t = floor(($num / 10) % 10); + $d = floor($num % 10); + + // cientos: doscientos, trescientos, etc... + switch ($h) + { + case 1: + if (($d == 0) and ($t == 0)) { // is it's '100' use 'cien' + $ret .= $this->_sep . 'cien'; + } + else { + $ret .= $this->_sep . 'ciento'; + } + break; + case 2: + case 3: + case 4: + case 6: + case 8: + $ret .= $this->_sep . $this->_digits[$h] . 'cientos'; + break; + case 5: + $ret .= $this->_sep . 'quinientos'; + break; + case 7: + $ret .= $this->_sep . 'setecientos'; + break; + case 9: + $ret .= $this->_sep . 'novecientos'; + break; + } + + // decenas: veinte, treinta, etc... + switch ($t) + { + case 9: + $ret .= $this->_sep . 'noventa'; + break; + + case 8: + $ret .= $this->_sep . 'ochenta'; + break; + + case 7: + $ret .= $this->_sep . 'setenta'; + break; + + case 6: + $ret .= $this->_sep . 'sesenta'; + break; + + case 5: + $ret .= $this->_sep . 'cincuenta'; + break; + + case 4: + $ret .= $this->_sep . 'cuarenta'; + break; + + case 3: + $ret .= $this->_sep . 'treinta'; + break; + + case 2: + if ($d == 0) { + $ret .= $this->_sep . 'veinte'; + } + else { + if (($power > 0) and ($d == 1)) { + $ret .= $this->_sep . 'veintiún'; + } + else { + $ret .= $this->_sep . 'veinti' . $this->_digits[$d]; + } + } + break; + + case 1: + switch ($d) + { + case 0: + $ret .= $this->_sep . 'diez'; + break; + + case 1: + $ret .= $this->_sep . 'once'; + break; + + case 2: + $ret .= $this->_sep . 'doce'; + break; + + case 3: + $ret .= $this->_sep . 'trece'; + break; + + case 4: + $ret .= $this->_sep . 'catorce'; + break; + + case 5: + $ret .= $this->_sep . 'quince'; + break; + + case 6: + case 7: + case 9: + case 8: + $ret .= $this->_sep . 'dieci' . $this->_digits[$d]; + break; + } + break; + } + + // add digits only if it is a multiple of 10 and not 1x or 2x + if (($t != 1) and ($t != 2) and ($d > 0)) + { + if($t != 0) // don't add 'y' for numbers below 10 + { + // use 'un' instead of 'uno' when there is a suffix ('mil', 'millones', etc...) + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.' y un'; + } + else { + $ret .= $this->_sep.'y '.$this->_digits[$d]; + } + } + else { + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.'un'; + } + else { + $ret .= $this->_sep.$this->_digits[$d]; + } + } + } + + if ($power > 0) + { + if (isset($this->_exponent[$power])) { + $lev = $this->_exponent[$power]; + } + + if (!isset($lev) || !is_array($lev)) { + return null; + } + + // if it's only one use the singular suffix + if (($d == 1) and ($t == 0) and ($h == 0)) { + $suffix = $lev[0]; + } + else { + $suffix = $lev[1]; + } + if ($num != 0) { + $ret .= $this->_sep . $suffix; + } + } + + return $ret; + } + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.es_AR.php b/gulliver/thirdparty/pear/Numbers/Words/lang.es_AR.php new file mode 100644 index 000000000..4750631c5 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.es_AR.php @@ -0,0 +1,470 @@ + | +// | Based On: lang_es.php - Xavier Noguer | +// +----------------------------------------------------------------------+ +// $Id: lang.es_AR.php 503 2004-02-23 19:25:42Z mmarre $ +// +// Numbers_Words class extension to spell numbers in Argentinian Spanish +// +// + +/** + * Class for translating numbers into Argentinian Spanish. + * + * @author Martin Marrese + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Argentinian Spanish. + * It supports up to decallones (10^6). + * It doesn't support spanish tonic accents (acentos). + * + * @author Martin Marrese + * @package Numbers_Words + */ +class Numbers_Words_es_AR extends Numbers_Words +{ + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'es_AR'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Spanish'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Español'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'menos'; + + /** + * The sufixes for exponents (singular and plural) + * @var array + * @access private + */ + var $_exponent = array( + 0 => array('',''), + 3 => array('mil','mil'), + 6 => array('millón','millones'), + 12 => array('billón','billones'), + 18 => array('trilón','trillones'), + 24 => array('cuatrillón','cuatrillones'), + 30 => array('quintillón','quintillones'), + 36 => array('sextillón','sextillones'), + 42 => array('septillón','septillones'), + 48 => array('octallón','octallones'), + 54 => array('nonallón','nonallones'), + 60 => array('decallón','decallones'), + ); + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'cero', 'uno', 'dos', 'tres', 'cuatro', + 'cinco', 'seis', 'siete', 'ocho', 'nueve' + ); + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The currency names (based on the below links, + * informations from central bank websites and on encyclopedias) + * + * @var array + * @link http://30-03-67.dreamstation.com/currency_alfa.htm World Currency Information + * @link http://www.jhall.demon.co.uk/currency/by_abbrev.html World currencies + * @link http://www.shoestring.co.kr/world/p.visa/change.htm Currency names in English + * @access private + */ + var $_currency_names = array( + 'ALL' => array(array('lek'), array('qindarka')), + 'AUD' => array(array('Australian dollar'), array('cent')), + 'ARS' => array(array('Peso'), array ('centavo')), + 'BAM' => array(array('convertible marka'), array('fenig')), + 'BGN' => array(array('lev'), array('stotinka')), + 'BRL' => array(array('real'), array('centavos')), + 'BYR' => array(array('Belarussian rouble'), array('kopiejka')), + 'CAD' => array(array('Canadian dollar'), array('cent')), + 'CHF' => array(array('Swiss franc'), array('rapp')), + 'CYP' => array(array('Cypriot pound'), array('cent')), + 'CZK' => array(array('Czech koruna'), array('halerz')), + 'DKK' => array(array('Danish krone'), array('ore')), + 'EEK' => array(array('kroon'), array('senti')), + 'EUR' => array(array('euro'), array('euro-cent')), + 'GBP' => array(array('pound', 'pounds'), array('pence')), + 'HKD' => array(array('Hong Kong dollar'), array('cent')), + 'HRK' => array(array('Croatian kuna'), array('lipa')), + 'HUF' => array(array('forint'), array('filler')), + 'ISK' => array(array('Icelandic króna'), array('aurar')), + 'JPY' => array(array('yen'), array('sen')), + 'LTL' => array(array('litas'), array('cent')), + 'LVL' => array(array('lat'), array('sentim')), + 'MKD' => array(array('Macedonian dinar'), array('deni')), + 'MTL' => array(array('Maltese lira'), array('centym')), + 'NOK' => array(array('Norwegian krone'), array('oere')), + 'PLN' => array(array('zloty', 'zlotys'), array('grosz')), + 'ROL' => array(array('Romanian leu'), array('bani')), + 'RUB' => array(array('Russian Federation rouble'), array('kopiejka')), + 'SEK' => array(array('Swedish krona'), array('oere')), + 'SIT' => array(array('Tolar'), array('stotinia')), + 'SKK' => array(array('Slovak koruna'), array()), + 'TRL' => array(array('lira'), array('kuruþ')), + 'UAH' => array(array('hryvna'), array('cent')), + 'USD' => array(array('dolar', 'DÓLARES'), array('centavo')), + 'YUM' => array(array('dinars'), array('para')), + 'ZAR' => array(array('rand'), array('cent')), + 'MXN' => array(array('Peso Mexicano', 'Pesos Mexicanos'), array('centavo')) + ); + + /** + * The default currency name + * @var string + * @access public + */ + var $def_currency = 'ARS'; // Argentinian Peso + + // }}} + // {{{ toWords() + /** + * Converts a number to its word representation + * in Argentinian Spanish. + * + * @param float $num An float between -infinity and infinity inclusive :) + * that should be converted to a words representation + * @param integer $power The power of ten for the rest of the number to the right. + * For example toWords(12,3) should give "doce mil". + * Optional, defaults to 0. + * @return string The corresponding word representation + * + * @access private + * @author Martin Marrese + */ + function toWords($num, $power = 0) + { + // The return string; + $ret = ''; + + // add a the word for the minus sign if necessary + if (substr($num, 0, 1) == '-') + { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + + // strip excessive zero signs + $num = preg_replace('/^0+/','',$num); + + $num_tmp = split ('\.', $num); + + $num = $num_tmp[0]; + $dec = (@$num_tmp[1]) ? $num_tmp[1] : ''; + + if (strlen($num) > 6) + { + $current_power = 6; + // check for highest power + if (isset($this->_exponent[$power])) + { + // convert the number above the first 6 digits + // with it's corresponding $power. + $snum = substr($num, 0, -6); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $ret .= $this->toWords($snum, $power + 6); + } + } + $num = substr($num, -6); + if ($num == 0) { + return $ret; + } + } + elseif ($num == 0 || $num == '') { + return(' '.$this->_digits[0]); + $current_power = strlen($num); + } + else { + $current_power = strlen($num); + } + + // See if we need "thousands" + $thousands = floor($num / 1000); + if ($thousands == 1) { + $ret .= $this->_sep . 'mil'; + } + elseif ($thousands > 1) { + $ret .= $this->toWords($thousands, 3); + } + + // values for digits, tens and hundreds + $h = floor(($num / 100) % 10); + $t = floor(($num / 10) % 10); + $d = floor($num % 10); + + // cientos: doscientos, trescientos, etc... + switch ($h) + { + case 1: + if (($d == 0) and ($t == 0)) { // is it's '100' use 'cien' + $ret .= $this->_sep . 'cien'; + } + else { + $ret .= $this->_sep . 'ciento'; + } + break; + case 2: + case 3: + case 4: + case 6: + case 8: + $ret .= $this->_sep . $this->_digits[$h] . 'cientos'; + break; + case 5: + $ret .= $this->_sep . 'quinientos'; + break; + case 7: + $ret .= $this->_sep . 'setecientos'; + break; + case 9: + $ret .= $this->_sep . 'novecientos'; + break; + } + + // decenas: veinte, treinta, etc... + switch ($t) + { + case 9: + $ret .= $this->_sep . 'noventa'; + break; + + case 8: + $ret .= $this->_sep . 'ochenta'; + break; + + case 7: + $ret .= $this->_sep . 'setenta'; + break; + + case 6: + $ret .= $this->_sep . 'sesenta'; + break; + + case 5: + $ret .= $this->_sep . 'cincuenta'; + break; + + case 4: + $ret .= $this->_sep . 'cuarenta'; + break; + + case 3: + $ret .= $this->_sep . 'treinta'; + break; + + case 2: + if ($d == 0) { + $ret .= $this->_sep . 'veinte'; + } + else { + if (($power > 0) and ($d == 1)) { + $ret .= $this->_sep . 'veintiún'; + } + else { + $ret .= $this->_sep . 'veinti' . $this->_digits[$d]; + } + } + break; + + case 1: + switch ($d) + { + case 0: + $ret .= $this->_sep . 'diez'; + break; + + case 1: + $ret .= $this->_sep . 'once'; + break; + + case 2: + $ret .= $this->_sep . 'doce'; + break; + + case 3: + $ret .= $this->_sep . 'trece'; + break; + + case 4: + $ret .= $this->_sep . 'catorce'; + break; + + case 5: + $ret .= $this->_sep . 'quince'; + break; + + case 6: + case 7: + case 9: + case 8: + $ret .= $this->_sep . 'dieci' . $this->_digits[$d]; + break; + } + break; + } + + // add digits only if it is a multiple of 10 and not 1x or 2x + if (($t != 1) and ($t != 2) and ($d > 0)) + { + if($t != 0) // don't add 'y' for numbers below 10 + { + // use 'un' instead of 'uno' when there is a suffix ('mil', 'millones', etc...) + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.' y un'; + } + else { + $ret .= $this->_sep.'y '.$this->_digits[$d]; + } + } + else { + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.'un'; + } + else { + $ret .= $this->_sep.$this->_digits[$d]; + } + } + } + + if ($power > 0) + { + if (isset($this->_exponent[$power])) { + $lev = $this->_exponent[$power]; + } + + if (!isset($lev) || !is_array($lev)) { + return null; + } + + // if it's only one use the singular suffix + if (($d == 1) and ($t == 0) and ($h == 0)) { + $suffix = $lev[0]; + } + else { + $suffix = $lev[1]; + } + if ($num != 0) { + $ret .= $this->_sep . $suffix; + } + } + + if ($dec) { + $dec = $this->toWords(trim($dec)); + $ret.= ' con ' . trim ($dec); + } + + return $ret; + } + // }}} + + // {{{ toCurrency() + + /** + * Converts a currency value to its word representation + * (with monetary units) in Agentinian Spanish language + * + * @param integer $int_curr An international currency symbol + * as defined by the ISO 4217 standard (three characters) + * @param integer $decimal A money total amount without fraction part (e.g. amount of dollars) + * @param integer $fraction Fractional part of the money amount (e.g. amount of cents) + * Optional. Defaults to false. + * + * @return string The corresponding word representation for the currency + * + * @access public + * @author Martin Marrese + */ + function toCurrencyWords($int_curr, $decimal, $fraction = false) { + $int_curr = strtoupper($int_curr); + if (!isset($this->_currency_names[$int_curr])) { + $int_curr = $this->def_currency; + } + $curr_names = $this->_currency_names[$int_curr]; + $ret .= $this->_sep . trim($this->toWords($decimal)); + $lev = ($decimal == 1) ? 0 : 1; + + if ($lev > 0) { + if (count($curr_names[0]) > 1) { + $ret .= $this->_sep . $curr_names[0][$lev]; + } else { + $ret .= $this->_sep . $curr_names[0][0] . 's'; + } + } else { + $ret .= $this->_sep . $curr_names[0][0]; + } + + + if ($fraction !== false) { + $ret .= $this->_sep .'con'. $this->_sep . trim($this->toWords($fraction)); + $lev = ($fraction == 1) ? 0 : 1; + if ($lev > 0) { + if (count($curr_names[1]) > 1) { + $ret .= $this->_sep . $curr_names[1][$lev]; + } else { + $ret .= $this->_sep . $curr_names[1][0] . 's'; + } + } else { + $ret .= $this->_sep . $curr_names[1][0]; + } + } + return $ret; + } + // }}} + + + +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.fr.php b/gulliver/thirdparty/pear/Numbers/Words/lang.fr.php new file mode 100644 index 000000000..ed756163f --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.fr.php @@ -0,0 +1,439 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id$ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into French. + * + * @author Kouber Saparev + * @package Numbers_Words + */ +class Numbers_Words_fr extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name. + * @var string + * @access public + */ + var $locale = 'fr'; + + /** + * Language name in English. + * @var string + * @access public + */ + var $lang = 'French'; + + /** + * Native language name. + * @var string + * @access public + */ + var $lang_native = 'Français'; + + /** + * The words for some numbers. + * @var string + * @access private + */ + var $_misc_numbers = array( + 10=>'dix', // 10 + 'onze', // 11 + 'douze', // 12 + 'treize', // 13 + 'quatorze', // 14 + 'quinze', // 15 + 'seize', // 16 + 20=>'vingt', // 20 + 30=>'trente', // 30 + 40=>'quarante', // 40 + 50=>'cinquante',// 50 + 60=>'soixante', // 60 + 100=>'cent' // 100 + ); + + + /** + * The words for digits (except zero). + * @var string + * @access private + */ + var $_digits = array(1=>"un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"); + + /** + * The word for zero. + * @var string + * @access private + */ + var $_zero = 'zéro'; + + /** + * The word for infinity. + * @var string + * @access private + */ + var $_infinity = 'infini'; + + /** + * The word for the "and" language construct. + * @var string + * @access private + */ + var $_and = 'et'; + + /** + * The word separator. + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The dash liaison. + * @var string + * @access private + */ + var $_dash = '-'; + + /** + * The word for the minus sign. + * @var string + * @access private + */ + var $_minus = 'moins'; // minus sign + + /** + * The plural suffix (except for hundred). + * @var string + * @access private + */ + var $_plural = 's'; // plural suffix + + /** + * The suffixes for exponents (singular). + * @var array + * @access private + */ + var $_exponent = array( + 0 => '', + 3 => 'mille', + 6 => 'million', + 9 => 'milliard', + 12 => 'trillion', + 15 => 'quadrillion', + 18 => 'quintillion', + 21 => 'sextillion', + 24 => 'septillion', + 27 => 'octillion', + 30 => 'nonillion', + 33 => 'decillion', + 36 => 'undecillion', + 39 => 'duodecillion', + 42 => 'tredecillion', + 45 => 'quattuordecillion', + 48 => 'quindecillion', + 51 => 'sexdecillion', + 54 => 'septendecillion', + 57 => 'octodecillion', + 60 => 'novemdecillion', + 63 => 'vigintillion', + 66 => 'unvigintillion', + 69 => 'duovigintillion', + 72 => 'trevigintillion', + 75 => 'quattuorvigintillion', + 78 => 'quinvigintillion', + 81 => 'sexvigintillion', + 84 => 'septenvigintillion', + 87 => 'octovigintillion', + 90 => 'novemvigintillion', + 93 => 'trigintillion', + 96 => 'untrigintillion', + 99 => 'duotrigintillion', + 102 => 'trestrigintillion', + 105 => 'quattuortrigintillion', + 108 => 'quintrigintillion', + 111 => 'sextrigintillion', + 114 => 'septentrigintillion', + 117 => 'octotrigintillion', + 120 => 'novemtrigintillion', + 123 => 'quadragintillion', + 126 => 'unquadragintillion', + 129 => 'duoquadragintillion', + 132 => 'trequadragintillion', + 135 => 'quattuorquadragintillion', + 138 => 'quinquadragintillion', + 141 => 'sexquadragintillion', + 144 => 'septenquadragintillion', + 147 => 'octoquadragintillion', + 150 => 'novemquadragintillion', + 153 => 'quinquagintillion', + 156 => 'unquinquagintillion', + 159 => 'duoquinquagintillion', + 162 => 'trequinquagintillion', + 165 => 'quattuorquinquagintillion', + 168 => 'quinquinquagintillion', + 171 => 'sexquinquagintillion', + 174 => 'septenquinquagintillion', + 177 => 'octoquinquagintillion', + 180 => 'novemquinquagintillion', + 183 => 'sexagintillion', + 186 => 'unsexagintillion', + 189 => 'duosexagintillion', + 192 => 'tresexagintillion', + 195 => 'quattuorsexagintillion', + 198 => 'quinsexagintillion', + 201 => 'sexsexagintillion', + 204 => 'septensexagintillion', + 207 => 'octosexagintillion', + 210 => 'novemsexagintillion', + 213 => 'septuagintillion', + 216 => 'unseptuagintillion', + 219 => 'duoseptuagintillion', + 222 => 'treseptuagintillion', + 225 => 'quattuorseptuagintillion', + 228 => 'quinseptuagintillion', + 231 => 'sexseptuagintillion', + 234 => 'septenseptuagintillion', + 237 => 'octoseptuagintillion', + 240 => 'novemseptuagintillion', + 243 => 'octogintillion', + 246 => 'unoctogintillion', + 249 => 'duooctogintillion', + 252 => 'treoctogintillion', + 255 => 'quattuoroctogintillion', + 258 => 'quinoctogintillion', + 261 => 'sexoctogintillion', + 264 => 'septoctogintillion', + 267 => 'octooctogintillion', + 270 => 'novemoctogintillion', + 273 => 'nonagintillion', + 276 => 'unnonagintillion', + 279 => 'duononagintillion', + 282 => 'trenonagintillion', + 285 => 'quattuornonagintillion', + 288 => 'quinnonagintillion', + 291 => 'sexnonagintillion', + 294 => 'septennonagintillion', + 297 => 'octononagintillion', + 300 => 'novemnonagintillion', + 303 => 'centillion' + ); + // }}} + + // {{{ _splitNumber() + + /** + * Split a number to groups of three-digit numbers. + * + * @param mixed $num An integer or its string representation + * that need to be split + * + * @return array Groups of three-digit numbers. + * + * @access private + * @author Kouber Saparev + * @since PHP 4.2.3 + */ + + function _splitNumber($num) + { + if (is_string($num)) { + $ret = array(); + $strlen = strlen($num); + $first = substr($num, 0, $strlen%3); + preg_match_all('/\d{3}/', substr($num, $strlen%3, $strlen), $m); + $ret =& $m[0]; + if ($first) array_unshift($ret, $first); + return $ret; + } + else + return explode(' ', number_format($num, 0, '', ' ')); // a faster version for integers + } + // }}} + + // {{{ _showDigitsGroup() + + /** + * Converts a three-digit number to its word representation + * in French language. + * + * @param integer $num An integer between 1 and 999 inclusive. + * + * @param boolean $last A flag, that determines if it is the last group of digits - + * this is used to accord the plural suffix of the "hundreds". + * Example: 200 = "deux cents", but 200000 = "deux cent mille". + * + * + * @return string The words for the given number. + * + * @access private + * @author Kouber Saparev + */ + function _showDigitsGroup($num, $last = false) + { + $ret = ''; + + // extract the value of each digit from the three-digit number + $e = $num%10; // ones + $d = ($num-$e)%100/10; // tens + $s = ($num-$d*10-$e)%1000/100; // hundreds + + // process the "hundreds" digit. + if ($s) { + if ($s>1) { + $ret .= $this->_digits[$s].$this->_sep.$this->_misc_numbers[100]; + if ($last && !$e && !$d) { + $ret .= $this->_plural; + } + } else { + $ret .= $this->_misc_numbers[100]; + } + $ret .= $this->_sep; + } + + // process the "tens" digit, and optionally the "ones" digit. + if ($d) { + // in the case of 1, the "ones" digit also must be processed + if ($d==1) { + if ($e<=6) { + $ret .= $this->_misc_numbers[10+$e]; + } else { + $ret .= $this->_misc_numbers[10].'-'.$this->_digits[$e]; + } + $e = 0; + } elseif ($d>5) { + if ($d<8) { + $ret .= $this->_misc_numbers[60]; + $resto = $d*10+$e-60; + if ($e==1) { + $ret .= $this->_sep.$this->_and.$this->_sep; + } + elseif ($resto) { + $ret .= $this->_dash; + } + + if ($resto) { + $ret .= $this->_showDigitsGroup($resto); + } + $e = 0; + } else { + $ret .= $this->_digits[4].$this->_dash.$this->_misc_numbers[20]; + $resto = $d*10+$e-80; + if ($resto) { + $ret .= $this->_dash; + $ret .= $this->_showDigitsGroup($resto); + $e = 0; + } else { + $ret .= $this->_plural; + } + } + } else { + $ret .= $this->_misc_numbers[$d*10]; + } + } + + // process the "ones" digit + if ($e) { + if ($d) { + if ($e==1) { + $ret .= $this->_sep.$this->_and.$this->_sep; + } else { + $ret .= $this->_dash; + } + } + $ret .= $this->_digits[$e]; + } + + // strip excessive separators + $ret = rtrim($ret, $this->_sep); + + return $ret; + } + // }}} + + // {{{ toWords() + + /** + * Converts a number to its word representation + * in French language. + * + * @param integer $num An integer (or its string representation) between 9.99*-10^302 + * and 9.99*10^302 (999 centillions) that need to be converted to words + * + * @return string The corresponding word representation + * + * @access public + * @author Kouber Saparev + */ + function toWords($num = 0) + { + $ret = ''; + + // check if $num is a valid non-zero number + if (!$num || preg_match('/^-?0+$/', $num) || !preg_match('/^-?\d+$/', $num)) return $this->_zero; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_minus . $this->_sep; + $num = substr($num, 1); + } + + // if the absolute value is greater than 9.99*10^302, return infinity + if (strlen($num)>306) { + return $ret . $this->_infinity; + } + + // strip excessive zero signs + $num = ltrim($num, '0'); + + // split $num to groups of three-digit numbers + $num_groups = $this->_splitNumber($num); + + $sizeof_numgroups = count($num_groups); + + foreach ($num_groups as $i=>$number) { + // what is the corresponding exponent for the current group + $pow = $sizeof_numgroups-$i; + + // skip processment for empty groups + if ($number!='000') { + if ($number!=1 || $pow!=2) { + $ret .= $this->_showDigitsGroup($number, $i+1==$sizeof_numgroups).$this->_sep; + } + $ret .= $this->_exponent[($pow-1)*3]; + if ($pow>2 && $number>1) { + $ret .= $this->_plural; + } + $ret .= $this->_sep; + } + } + + return rtrim($ret, $this->_sep); + } + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.id.php b/gulliver/thirdparty/pear/Numbers/Words/lang.id.php new file mode 100644 index 000000000..21ab30cfb --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.id.php @@ -0,0 +1,277 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.en_GB.php,v 1.3 2002/11/26 10:33:35 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Indonesian language. +// + +require_once("PEAR.php"); +require_once("Numbers/Words.php"); + +/** +* Class for translating numbers into Indonesian. +* +* @author Ernas M. Jamil +*/ +class Numbers_Words_id extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + */ + var $locale = 'id'; + + /** + * Language name in English + * @var string + */ + var $lang = 'Indonesia Language'; + + /** + * Native language name + * @var string + */ + var $lang_native = 'Bahasa Indonesia'; + + /** + * The word for the minus sign + * @var string + */ + var $_minus = 'minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names partly based on: + * http://www.users.dircon.co.uk/~shaunf/shaun/numbers/millions.htm + * @var array + */ + var $_exponent = array( + 0 => array(''), + 3 => array('ribu'), + 6 => array('juta'), + 9 => array('milyar'), + 12 => array('trilyun'), + 24 => array('quadrillion'), + 30 => array('quintillion'), + 36 => array('sextillion'), + 42 => array('septillion'), + 48 => array('octillion'), + 54 => array('nonillion'), + 60 => array('decillion'), + 66 => array('undecillion'), + 72 => array('duodecillion'), + 78 => array('tredecillion'), + 84 => array('quattuordecillion'), + 90 => array('quindecillion'), + 96 => array('sexdecillion'), + 102 => array('septendecillion'), + 108 => array('octodecillion'), + 114 => array('novemdecillion'), + 120 => array('vigintillion'), + 192 => array('duotrigintillion'), + 600 => array('centillion') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + */ + var $_digits = array( + 0 => 'nol', 'satu', 'dua', 'tiga', 'empat', + 'lima', 'enam', 'tujuh', 'delapan', 'sembilan' + ); + + /** + * The word separator + * @var string + */ + var $_sep = ' '; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Indonesian language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Ernas M. Jamil + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 4) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = $th = 0; + + switch(strlen($num)) { + case 4: + $th = (int)substr($num,-4,1); + + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($th) { + if ($th==1) + $ret .= $this->_sep . 'seribu'; + else + $ret .= $this->_sep . $this->_digits[$th] . $this->_sep . 'ribu'; + } + + if ($h) { + if ($h==1) + $ret .= $this->_sep . 'seratus'; + else + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'ratus'; + + // in English only - add ' and' for [1-9]01..[1-9]99 + // (also for 1001..1099, 10001..10099 but it is harder) + // for now it is switched off, maybe some language purists + // can force me to enable it, or to remove it completely + // if (($t + $d) > 0) + // $ret .= $this->_sep . 'and'; + } + + // ten, twenty etc. + switch ($t) { + case 9: + case 8: + case 7: + case 6: + case 5: + case 4: + case 3: + case 2: + $ret .= $this->_sep . $this->_digits[$t] . ' puluh'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'sepuluh'; + break; + + case 1: + $ret .= $this->_sep . 'sebelas'; + break; + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + $ret .= $this->_sep . $this->_digits[$d] . ' belas'; + break; + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + // add minus sign between [2-9] and digit + if ($t > 1) { + $ret .= ' ' . $this->_digits[$d]; + } else { + $ret .= $this->_sep . $this->_digits[$d]; + } + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.it_IT.php b/gulliver/thirdparty/pear/Numbers/Words/lang.it_IT.php new file mode 100644 index 000000000..50694f7bc --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.it_IT.php @@ -0,0 +1,348 @@ + + * @author Davide Caironi + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Italian. + * It supports up to quadrilions + * + * @author Filippo Beltramini + * @author Davide Caironi + * @package Numbers_Words + */ +class Numbers_Words_it_IT extends Numbers_Words +{ + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'it_IT'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Italian'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Italiano'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'meno '; + + /** + * The sufixes for exponents (singular and plural) + * @var array + * @access private + */ + var $_exponent = array( + 0 => array('',''), + 3 => array('mille','mila'), + 6 => array('milione','miloni'), + 12 => array('miliardo','miliardi'), + 18 => array('trillone','trilloni'), + 24 => array('quadrilione','quadrilioni'), + ); + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'zero', 'uno', 'due', 'tre', 'quattro', + 'cinque', 'sei', 'sette', 'otto', 'nove' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ''; + // }}} + // {{{ toWords() + /** + * Converts a number to its word representation + * in italiano. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that should be converted to a words representation + * @param integer $power The power of ten for the rest of the number to the right. + * For example toWords(12,3) should give "doce mil". + * Optional, defaults to 0. + * @return string The corresponding word representation + * + * @access private + * @author Filippo Beltramini + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0) + { + // The return string; + $ret = ''; + + // add a the word for the minus sign if necessary + if (substr($num, 0, 1) == '-') + { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + + // strip excessive zero signs + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 6) + { + $current_power = 6; + // check for highest power + if (isset($this->_exponent[$power])) + { + // convert the number above the first 6 digits + // with it's corresponding $power. + $snum = substr($num, 0, -6); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $ret .= $this->toWords($snum, $power + 6); + } + } + $num = substr($num, -6); + if ($num == 0) { + return $ret; + } + } + elseif ($num == 0 || $num == '') { + return(' '.$this->_digits[0].' '); + $current_power = strlen($num); + } + else { + $current_power = strlen($num); + } + + // See if we need "thousands" + $thousands = floor($num / 1000); + if ($thousands == 1) { + $ret .= $this->_sep . 'mille' . $this->_sep; + } + elseif ($thousands > 1) { + $ret .= $this->toWords($thousands, 3) . $this->_sep;//. 'mil' . $this->_sep; + } + + // values for digits, tens and hundreds + $h = floor(($num / 100) % 10); + $t = floor(($num / 10) % 10); + $d = floor($num % 10); + + // centinaia: duecento, trecento, etc... + switch ($h) + { + case 1: + if (($d == 0) and ($t == 0)) { // is it's '100' use 'cien' + $ret .= $this->_sep . 'cento'; + } + else { + $ret .= $this->_sep . 'cento'; + } + break; + case 2: + case 3: + case 4: + case 6: + case 8: + $ret .= $this->_sep . $this->_digits[$h] . 'cento'; + break; + case 5: + $ret .= $this->_sep . 'cinquecento'; + break; + case 7: + $ret .= $this->_sep . 'settecento'; + break; + case 9: + $ret .= $this->_sep . 'novecento'; + break; + } + + // decine: venti trenta, etc... + switch ($t) + { + case 9: + $ret .= $this->_sep . 'novanta'; + break; + + case 8: + $ret .= $this->_sep . 'ottanta'; + break; + + case 7: + $ret .= $this->_sep . 'settanta'; + break; + + case 6: + $ret .= $this->_sep . 'sessanta'; + break; + + case 5: + $ret .= $this->_sep . 'cinquanta'; + break; + + case 4: + $ret .= $this->_sep . 'quaranta'; + break; + + case 3: + $ret .= $this->_sep . 'trenta'; + break; + + case 2: + if ($d == 0) { + $ret .= $this->_sep . 'venti'; + } + else { + if (($power > 0) and ($d == 1)) { + $ret .= $this->_sep . 'ventuno'; + } + else { + $ret .= $this->_sep . 'venti' . $this->_digits[$d]; + } + } + break; + + case 1: + switch ($d) + { + case 0: + $ret .= $this->_sep . 'dieci'; + break; + + case 1: + $ret .= $this->_sep . 'undici'; + break; + + case 2: + $ret .= $this->_sep . 'dodici'; + break; + + case 3: + $ret .= $this->_sep . 'tredici'; + break; + + case 4: + $ret .= $this->_sep . 'quattordici'; + break; + + case 5: + $ret .= $this->_sep . 'quindici'; + break; + + case 6: + $ret .= $this->_sep . 'sedici'; + break; + + case 7: + $ret .= $this->_sep . 'diciassette'; + break; + + case 8: + $ret .= $this->_sep . 'diciotto'; + break; + + case 9: + $ret .= $this->_sep . 'diciannove'; + break; + } + break; + } + + // add digits only if it is a multiple of 10 and not 1x or 2x + if (($t != 1) and ($t != 2) and ($d > 0)) + { + if($t != 0) // don't add 'e' for numbers below 10 + { + // use 'un' instead of 'uno' when there is a suffix ('mila', 'milloni', etc...) + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.' e un'; + } + else { + $ret .= $this->_sep.''.$this->_digits[$d]; + } + } + else { + if(($power > 0) and ($d == 1)) { + $ret .= $this->_sep.'un '; + } + else { + $ret .= $this->_sep.$this->_digits[$d]; + } + } + } + + if ($power > 0) + { + if (isset($this->_exponent[$power])) { + $lev = $this->_exponent[$power]; + } + + if (!isset($lev) || !is_array($lev)) { + return null; + } + + // if it's only one use the singular suffix + if (($d == 1) and ($t == 0) and ($h == 0)) { + $suffix = $lev[0]; + } + else { + $suffix = $lev[1]; + } + if ($num != 0) { + $ret .= $this->_sep . $suffix; + } + } + + return $ret; + } + // }}} +} +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.lt.php b/gulliver/thirdparty/pear/Numbers/Words/lang.lt.php new file mode 100644 index 000000000..48a418b2f --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.lt.php @@ -0,0 +1,310 @@ + array(''), + 3 => array('tûkstantis','tûkstanèiai','tûkstanèiø'), + 6 => array('milijonas','milijonai','milijonø'), + 9 => array('bilijonas','bilijonai','bilijonø'), + 12 => array('trilijonas','trilijonai','trilijonø'), + 15 => array('kvadrilijonas','kvadrilijonai','kvadrilijonø'), + 18 => array('kvintilijonas','kvintilijonai','kvintilijonø') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'nulis', 'vienas', 'du', 'trys', 'keturi', + 'penki', 'ðeði', 'septyni', 'aðtuoni', 'devyni' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The default currency name + * @var string + * @access public + */ + var $def_currency = 'LTL'; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Lithuanian language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Laurynas Butkus + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ( $h > 1 ) + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'ðimtai'; + elseif ( $h ) + $ret .= $this->_sep . 'ðimtas'; + + // ten, twenty etc. + switch ($t) { + case 9: + $ret .= $this->_sep . 'devyniasdeðimt'; + break; + + case 8: + $ret .= $this->_sep . 'aðtuoniasdeðimt'; + break; + + case 7: + $ret .= $this->_sep . 'septyniasdeðimt'; + break; + + case 6: + $ret .= $this->_sep . 'ðeðiasdeðimt'; + break; + + case 5: + $ret .= $this->_sep . 'penkiasdeðimt'; + break; + + case 4: + $ret .= $this->_sep . 'keturiasdeðimt'; + break; + + case 3: + $ret .= $this->_sep . 'trisdeðimt'; + break; + + case 2: + $ret .= $this->_sep . 'dvideðimt'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'deðimt'; + break; + + case 1: + $ret .= $this->_sep . 'vienuolika'; + break; + + case 2: + $ret .= $this->_sep . 'dvylika'; + break; + + case 3: + $ret .= $this->_sep . 'trylika'; + break; + + case 4: + $ret .= $this->_sep . 'keturiolika'; + break; + + case 5: + $ret .= $this->_sep . 'penkiolika'; + break; + + case 6: + $ret .= $this->_sep . 'ðeðiolika'; + break; + + case 7: + $ret .= $this->_sep . 'septyniolika'; + break; + + case 8: + $ret .= $this->_sep . 'aðtuoniolika'; + break; + + case 9: + $ret .= $this->_sep . 'devyniolika'; + break; + + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + if ( $d > 1 || !$power || $t ) + $ret .= $this->_sep . $this->_digits[$d]; + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + //echo " $t $d
    "; + + if ( $t == 1 || ( $t > 0 && $d == 0 ) ) + $ret .= $this->_sep . $lev[2]; + elseif ( $d > 1 ) + $ret .= $this->_sep . $lev[1]; + else + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} + +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.pl.php b/gulliver/thirdparty/pear/Numbers/Words/lang.pl.php new file mode 100644 index 000000000..54519e293 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.pl.php @@ -0,0 +1,513 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.pl.php,v 1.9 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Polish. +// + +/** + * Class for translating numbers into Polish. + * + * @author Piotr Klaban + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Polish. + * + * @author Piotr Klaban + * @package Numbers_Words + */ +class Numbers_Words_pl extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'pl'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Polish'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'polski'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * Names based on: + * mathematical tables, my memory, and also: + * http://ux1.math.us.edu.pl/~szyjewski/FAQ/liczby/iony.htm + * @var array + * @access private + */ + var $_exponent = array( + // potêga dziesi±tki => liczba pojedyncza, podwójna, mnoga + 0 => array('','',''), + 3 => array('tysi±c','tysi±ce','tysiêcy'), + 6 => array('milion','miliony','milionów'), + 9 => array('miliard','miliardy','miliardów'), + 12 => array('bilion','biliony','bilionów'), + 15 => array('biliard','biliardy','biliardów'), + 18 => array('trylion','tryliony','trylionów'), + 21 => array('tryliard','tryliardy','tryliardów'), + 24 => array('kwadrylion','kwadryliony','kwadrylionów'), + 27 => array('kwadryliard','kwadryliardy','kwadryliardów'), + 30 => array('kwintylion','kwintyliony','kwintylionów'), + 33 => array('kwintyliiard','kwintyliardy','kwintyliardów'), + 36 => array('sekstylion','sekstyliony','sekstylionów'), + 39 => array('sekstyliard','sekstyliardy','sekstyliardów'), + 42 => array('septylion','septyliony','septylionów'), + 45 => array('septyliard','septyliardy','septyliardów'), + 48 => array('oktylion','oktyliony','oktylionów'), + 51 => array('oktyliard','oktyliardy','oktyliardów'), + 54 => array('nonylion','nonyliony','nonylionów'), + 57 => array('nonyliard','nonyliardy','nonyliardów'), + 60 => array('decylion','decyliony','decylionów'), + 63 => array('decyliard','decyliardy','decyliardów'), + 100 => array('centylion','centyliony','centylionów'), + 103 => array('centyliard','centyliardy','centyliardów'), + 120 => array('wicylion','wicylion','wicylion'), + 123 => array('wicyliard','wicyliardy','wicyliardów'), + 180 => array('trycylion','trycylion','trycylion'), + 183 => array('trycyliard','trycyliardy','trycyliardów'), + 240 => array('kwadragilion','kwadragilion','kwadragilion'), + 243 => array('kwadragiliard','kwadragiliardy','kwadragiliardów'), + 300 => array('kwinkwagilion','kwinkwagilion','kwinkwagilion'), + 303 => array('kwinkwagiliard','kwinkwagiliardy','kwinkwagiliardów'), + 360 => array('seskwilion','seskwilion','seskwilion'), + 363 => array('seskwiliard','seskwiliardy','seskwiliardów'), + 420 => array('septagilion','septagilion','septagilion'), + 423 => array('septagiliard','septagiliardy','septagiliardów'), + 480 => array('oktogilion','oktogilion','oktogilion'), + 483 => array('oktogiliard','oktogiliardy','oktogiliardów'), + 540 => array('nonagilion','nonagilion','nonagilion'), + 543 => array('nonagiliard','nonagiliardy','nonagiliardów'), + 600 => array('centylion','centyliony','centylionów'), + 603 => array('centyliard','centyliardy','centyliardów'), + 6000018 => array('milinilitrylion','milinilitryliony','milinilitrylionów') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'zero', 'jeden', 'dwa', 'trzy', 'cztery', + 'piêæ', 'sze¶æ', 'siedem', 'osiem', 'dziewiêæ' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The currency names (based on the below links, + * informations from central bank websites and on encyclopedias) + * + * @var array + * @link http://www.xe.com/iso4217.htm Currency codes + * @link http://www.republika.pl/geographia/peuropy.htm Europe review + * @link http://pieniadz.hoga.pl/waluty_objasnienia.asp Currency service + * @access private + */ + var $_currency_names = array( + 'ALL' => array(array('lek','leki','leków'), array('quindarka','quindarki','quindarek')), + 'AUD' => array(array('dolar australijski', 'dolary australijskie', 'dolarów australijskich'), array('cent', 'centy', 'centów')), + 'BAM' => array(array('marka','marki','marek'), array('fenig','fenigi','fenigów')), + 'BGN' => array(array('lew','lewy','lew'), array('stotinka','stotinki','stotinek')), + 'BRL' => array(array('real','reale','realów'), array('centavos','centavos','centavos')), + 'BYR' => array(array('rubel','ruble','rubli'), array('kopiejka','kopiejki','kopiejek')), + 'CAD' => array(array('dolar kanadyjski', 'dolary kanadyjskie', 'dolarów kanadyjskich'), array('cent', 'centy', 'centów')), + 'CHF' => array(array('frank szwajcarski','franki szwajcarskie','franków szwajcarskich'), array('rapp','rappy','rappów')), + 'CYP' => array(array('funt cypryjski','funty cypryjskie','funtów cypryjskich'), array('cent', 'centy', 'centów')), + 'CZK' => array(array('korona czeska','korony czeskie','koron czeskich'), array('halerz','halerze','halerzy')), + 'DKK' => array(array('korona duñska','korony duñskie','koron duñskich'), array('ore','ore','ore')), + 'EEK' => array(array('korona estoñska','korony estoñskie','koron estoñskich'), array('senti','senti','senti')), + 'EUR' => array(array('euro', 'euro', 'euro'), array('eurocent', 'eurocenty', 'eurocentów')), + 'GBP' => array(array('funt szterling','funty szterlingi','funtów szterlingów'), array('pens','pensy','pensów')), + 'HKD' => array(array('dolar Hongkongu','dolary Hongkongu','dolarów Hongkongu'), array('cent', 'centy', 'centów')), + 'HRK' => array(array('kuna','kuny','kun'), array('lipa','lipy','lip')), + 'HUF' => array(array('forint','forinty','forintów'), array('filler','fillery','fillerów')), + 'ISK' => array(array('korona islandzka','korony islandzkie','koron islandzkich'), array('aurar','aurar','aurar')), + 'JPY' => array(array('jen','jeny','jenów'), array('sen','seny','senów')), + 'LTL' => array(array('lit','lity','litów'), array('cent', 'centy', 'centów')), + 'LVL' => array(array('³at','³aty','³atów'), array('sentim','sentimy','sentimów')), + 'MKD' => array(array('denar','denary','denarów'), array('deni','deni','deni')), + 'MTL' => array(array('lira maltañska','liry maltañskie','lir maltañskich'), array('centym','centymy','centymów')), + 'NOK' => array(array('korona norweska','korony norweskie','koron norweskich'), array('oere','oere','oere')), + 'PLN' => array(array('z³oty', 'z³ote', 'z³otych'), array('grosz', 'grosze', 'groszy')), + 'ROL' => array(array('lej','leje','lei'), array('bani','bani','bani')), + 'RUB' => array(array('rubel','ruble','rubli'), array('kopiejka','kopiejki','kopiejek')), + 'SEK' => array(array('korona szwedzka','korony szwedzkie','koron szweckich'), array('oere','oere','oere')), + 'SIT' => array(array('tolar','tolary','tolarów'), array('stotinia','stotinie','stotini')), + 'SKK' => array(array('korona s³owacka','korony s³owackie','koron s³owackich'), array('halerz','halerze','halerzy')), + 'TRL' => array(array('lira turecka','liry tureckie','lir tureckich'), array('kurusza','kurysze','kuruszy')), + 'UAH' => array(array('hrywna','hrywna','hrywna'), array('cent', 'centy', 'centów')), + 'USD' => array(array('dolar','dolary','dolarów'), array('cent', 'centy', 'centów')), + 'YUM' => array(array('dinar','dinary','dinarów'), array('para','para','para')), + 'ZAR' => array(array('rand','randy','randów'), array('cent', 'centy', 'centów')) + ); + + /** + * The default currency name + * @var string + * @access public + */ + var $def_currency = 'PLN'; // Polish zloty + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Polish language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access public + * @author Piotr Klaban + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + switch ($h) { + case 9: + $ret .= $this->_sep . 'dziewiêæset'; + break; + + case 8: + $ret .= $this->_sep . 'osiemset'; + break; + + case 7: + $ret .= $this->_sep . 'siedemset'; + break; + + case 6: + $ret .= $this->_sep . 'sze¶æset'; + break; + + case 5: + $ret .= $this->_sep . 'piêæset'; + break; + + case 4: + $ret .= $this->_sep . 'czterysta'; + break; + + case 3: + $ret .= $this->_sep . 'trzysta'; + break; + + case 2: + $ret .= $this->_sep . 'dwie¶cie'; + break; + + case 1: + $ret .= $this->_sep . 'sto'; + break; + } + + switch ($t) { + case 9: + case 8: + case 7: + case 6: + case 5: + $ret .= $this->_sep . $this->_digits[$t] . 'dziesi±t'; + break; + + case 4: + $ret .= $this->_sep . 'czterdzie¶ci'; + break; + + case 3: + $ret .= $this->_sep . 'trzydzie¶ci'; + break; + + case 2: + $ret .= $this->_sep . 'dwadzie¶cia'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'dziesiêæ'; + break; + + case 1: + $ret .= $this->_sep . 'jedena¶cie'; + break; + + case 2: + case 3: + case 7: + case 8: + $ret .= $this->_sep . $this->_digits[$d] . 'na¶cie'; + break; + + case 4: + $ret .= $this->_sep . 'czterna¶cie'; + break; + + case 5: + $ret .= $this->_sep . 'piêtna¶cie'; + break; + + case 6: + $ret .= $this->_sep . 'szesna¶cie'; + break; + + case 9: + $ret .= $this->_sep . 'dziewiêtna¶cie'; + break; + } + break; + } + + if ($t != 1 && $d > 0) + $ret .= $this->_sep . $this->_digits[$d]; + + if ($t == 1) + $d = 0; + + if (( $h + $t ) > 0 && $d == 1) + $d = 0; + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + switch ($d) { + case 1: + $suf = $lev[0]; + break; + case 2: + case 3: + case 4: + $suf = $lev[1]; + break; + case 0: + case 5: + case 6: + case 7: + case 8: + case 9: + $suf = $lev[2]; + break; + } + $ret .= $this->_sep . $suf; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} + // {{{ toCurrency() + + /** + * Converts a currency value to its word representation + * (with monetary units) in Polish language + * + * @param integer $int_curr An international currency symbol + * as defined by the ISO 4217 standard (three characters) + * @param integer $decimal A money total amount without fraction part (e.g. amount of dollars) + * @param integer $fraction Fractional part of the money amount (e.g. amount of cents) + * Optional. Defaults to false. + * + * @return string The corresponding word representation for the currency + * + * @access public + * @author Piotr Klaban + * @since Numbers_Words 0.4 + */ + function toCurrencyWords($int_curr, $decimal, $fraction = false) { + $int_curr = strtoupper($int_curr); + if (!isset($this->_currency_names[$int_curr])) { + $int_curr = $this->def_currency; + } + $curr_names = $this->_currency_names[$int_curr]; + $ret = trim($this->toWords($decimal)); + $lev = $this->_get_numlevel($decimal); + $ret .= $this->_sep . $curr_names[0][$lev]; + + if ($fraction !== false) { + $ret .= $this->_sep . trim($this->toWords($fraction)); + $lev = $this->_get_numlevel($fraction); + $ret .= $this->_sep . $curr_names[1][$lev]; + } + return $ret; + } + // }}} + // {{{ _get_numlevel() + + /** + * Returns grammatical "level" of the number - this is necessary + * for choosing the right suffix for exponents and currency names. + * + * @param integer $num An integer between -infinity and infinity inclusive + * that need to be converted to words + * + * @return integer The grammatical "level" of the number. + * + * @access private + * @author Piotr Klaban + * @since Numbers_Words 0.4 + */ + function _get_numlevel($num) { + $num = (int)substr($num,-3); + $h = $t = $d = $lev = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return $lev; + break; + } + if ($t == 1) + $d = 0; + + if (( $h + $t ) > 0 && $d == 1) + $d = 0; + + switch ($d) { + case 1: + $lev = 0; + break; + case 2: + case 3: + case 4: + $lev = 1; + break; + default: + $lev = 2; + } + return $lev; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.pt_BR.php b/gulliver/thirdparty/pear/Numbers/Words/lang.pt_BR.php new file mode 100644 index 000000000..665afe092 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.pt_BR.php @@ -0,0 +1,241 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: lang.pt_BR.php,v 1.6 2003/09/29 12:23:58 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Brazilian Portuguese language. +// + + +/** + * Class for translating numbers into Brazilian Portuguese. + * + * @author Marcelo Subtil Marcal + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once "Numbers/Words.php"; + +/** + * Class for translating numbers into Brazilian Portuguese. + * + * @author Marcelo Subtil Marcal + * @package Numbers_Words + */ +class Numbers_Words_pt_BR extends Numbers_Words +{ + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'pt_BR'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Brazilian Portuguese'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Português Brasileiro'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'menos'; + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_unidade = array( + '', + 'um', + 'dois', + 'três', + 'quatro', + 'cinco', + 'seis', + 'sete', + 'oito', + 'nove' + ); + + /** + * The array containing numbers 10-19. + * @var array + * @access private + */ + var $_dezena10 = array( + 'dez', + 'onze', + 'doze', + 'treze', + 'quatorze', + 'quinze', + 'dezesseis', + 'dezessete', + 'dezoito', + 'dezenove' + ); + + /** + * The array containing numbers for 10,20,...,90. + * @var array + * @access private + */ + var $_dezena = array( + '', + 'dez', + 'vinte', + 'trinta', + 'quarenta', + 'cinquenta', + 'sessenta', + 'setenta', + 'oitenta', + 'noventa' + ); + + /** + * The array containing numbers for hundrets. + * @var array + * @access private + */ + var $_centena = array( + '', + 'cem', + 'duzentos', + 'trezentos', + 'quatrocentos', + 'quinhentos', + 'seiscentos', + 'setecentos', + 'oitocentos', + 'novecentos' + ); + + /** + * The sufixes for exponents (singular and plural) + * @var array + * @access private + */ + var $_expoente = array( + '', + 'mil', + 'milhão', + 'bilhão', + 'trilhão', + 'quatrilhão', + 'quintilhão', + 'sextilhão', + 'setilhão', + 'octilhão', + 'nonilhão', + 'decilhão', + 'undecilhão', + 'dodecilhão', + 'tredecilhão', + 'quatuordecilhão', + 'quindecilhão', + 'sedecilhão', + 'septendecilhão' + ); + + + + /** + * Converts a number to its word representation + * in Brazilian Portuguese language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * + * @return string The corresponding word representation + * + * @access public + * @author Marcelo Subtil Marcal + * @since PHP 4.2.3 + */ + function toWords($num) { + + $ret = ''; + + $num = trim($num); + + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + while (strlen($num) % 3 != 0) { + $num = "0" . $num; + } + + $num = ereg_replace("(...)", "\\1.", $num); + $num = ereg_replace("\.$", "", $num); + + $inteiro = explode(".", $num); + + for ($i = 0; $i < count($inteiro); $i++) { + $ret .= (($inteiro[$i] > 100) && ($inteiro[$i] < 200)) ? "cento" : $this->_centena[$inteiro[$i][0]]; + $ret .= ($inteiro[$i][0] && ($inteiro[$i][1] || $inteiro[$i][2])) ? " e " : ""; + $ret .= ($inteiro[$i][1] < 2) ? "" : $this->_dezena[$inteiro[$i][1]]; + $ret .= (($inteiro[$i][1] > 1) && ($inteiro[$i][2])) ? " e " : ""; + $ret .= ($inteiro > 0) ? ( ($inteiro[$i][1] == 1) ? $this->_dezena10[$inteiro[$i][2]] : $this->_unidade[$inteiro[$i][2]] ) : ""; + $ret .= $inteiro[$i] > 0 ? " " . ($inteiro[$i] > 1 ? str_replace("ão", "ões", $this->_expoente[count($inteiro)-1-$i]) : $this->_expoente[count($inteiro)-1-$i]) : ""; + + if ($ret && (isset($inteiro[$i+1]))) { + if ($inteiro[$i+1] != "000") { + $ret .= ($i+1) == (count($inteiro)-1) ? " e " : ", "; + } + } + + } + + return $ret ? " $ret" : " zero"; + + } +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.ru.php b/gulliver/thirdparty/pear/Numbers/Words/lang.ru.php new file mode 100644 index 000000000..28735326a --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.ru.php @@ -0,0 +1,616 @@ + | +// | Andrey Demenev | +// +----------------------------------------------------------------------+ +// +// $Id: $ +// +// Numbers_Words class extension to spell numbers in Russian language. +// + +/** + * Class for translating numbers into Russian. + * + * @author Andrey Demenev + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Russian. + * + * @author Andrey Demenev + * @package Numbers_Words + */ +class Numbers_Words_ru extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'ru'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Russian'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Ðóññêèé'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'ìèíóñ'; // minus sign + + /** + * The sufixes for exponents (singular) + * Names partly based on: + * http://home.earthlink.net/~mrob/pub/math/largenum.html + * http://mathforum.org/dr.math/faq/faq.large.numbers.html + * http://www.mazes.com/AmericanNumberingSystem.html + * @var array + * @access private + */ + var $_exponent = array( + 0 => '', + 6 => 'ìèëëèîí', + 9 => 'ìèëëèàðä', + 12 => 'òðèëëèîí', + 15 => 'êâàäðèëëèîí', + 18 => 'êâèíòèëëèîí', + 21 => 'ñåêñòèëëèîí', + 24 => 'ñåïòèëëèîí', + 27 => 'îêòèëëèîí', + 30 => 'íîíèëëèîí', + 33 => 'äåöèëëèîí', + 36 => 'óíäåöèëëèîí', + 39 => 'äóîäåöèëëèîí', + 42 => 'òðåäåöèëëèîí', + 45 => 'êâàòóîðäåöèëëèîí', + 48 => 'êâèíäåöèëëèîí', + 51 => 'ñåêñäåöèëëèîí', + 54 => 'ñåïòåíäåöèëëèîí', + 57 => 'îêòîäåöèëëèîí', + 60 => 'íîâåìäåöèëëèîí', + 63 => 'âèãèíòèëëèîí', + 66 => 'óíâèãèíòèëëèîí', + 69 => 'äóîâèãèíòèëëèîí', + 72 => 'òðåâèãèíòèëëèîí', + 75 => 'êâàòóîðâèãèíòèëëèîí', + 78 => 'êâèíâèãèíòèëëèîí', + 81 => 'ñåêñâèãèíòèëëèîí', + 84 => 'ñåïòåíâèãèíòèëëèîí', + 87 => 'îêòîâèãèíòèëëèîí', + 90 => 'íîâåìâèãèíòèëëèîí', + 93 => 'òðèãèíòèëëèîí', + 96 => 'óíòðèãèíòèëëèîí', + 99 => 'äóîòðèãèíòèëëèîí', + 102 => 'òðåòðèãèíòèëëèîí', + 105 => 'êâàòîðòðèãèíòèëëèîí', + 108 => 'êâèíòðèãèíòèëëèîí', + 111 => 'ñåêñòðèãèíòèëëèîí', + 114 => 'ñåïòåíòðèãèíòèëëèîí', + 117 => 'îêòîòðèãèíòèëëèîí', + 120 => 'íîâåìòðèãèíòèëëèîí', + 123 => 'êâàäðàãèíòèëëèîí', + 126 => 'óíêâàäðàãèíòèëëèîí', + 129 => 'äóîêâàäðàãèíòèëëèîí', + 132 => 'òðåêâàäðàãèíòèëëèîí', + 135 => 'êâàòîðêâàäðàãèíòèëëèîí', + 138 => 'êâèíêâàäðàãèíòèëëèîí', + 141 => 'ñåêñêâàäðàãèíòèëëèîí', + 144 => 'ñåïòåíêâàäðàãèíòèëëèîí', + 147 => 'îêòîêâàäðàãèíòèëëèîí', + 150 => 'íîâåìêâàäðàãèíòèëëèîí', + 153 => 'êâèíêâàãèíòèëëèîí', + 156 => 'óíêâèíêàãèíòèëëèîí', + 159 => 'äóîêâèíêàãèíòèëëèîí', + 162 => 'òðåêâèíêàãèíòèëëèîí', + 165 => 'êâàòîðêâèíêàãèíòèëëèîí', + 168 => 'êâèíêâèíêàãèíòèëëèîí', + 171 => 'ñåêñêâèíêàãèíòèëëèîí', + 174 => 'ñåïòåíêâèíêàãèíòèëëèîí', + 177 => 'îêòîêâèíêàãèíòèëëèîí', + 180 => 'íîâåìêâèíêàãèíòèëëèîí', + 183 => 'ñåêñàãèíòèëëèîí', + 186 => 'óíñåêñàãèíòèëëèîí', + 189 => 'äóîñåêñàãèíòèëëèîí', + 192 => 'òðåñåêñàãèíòèëëèîí', + 195 => 'êâàòîðñåêñàãèíòèëëèîí', + 198 => 'êâèíñåêñàãèíòèëëèîí', + 201 => 'ñåêññåêñàãèíòèëëèîí', + 204 => 'ñåïòåíñåêñàãèíòèëëèîí', + 207 => 'îêòîñåêñàãèíòèëëèîí', + 210 => 'íîâåìñåêñàãèíòèëëèîí', + 213 => 'ñåïòàãèíòèëëèîí', + 216 => 'óíñåïòàãèíòèëëèîí', + 219 => 'äóîñåïòàãèíòèëëèîí', + 222 => 'òðåñåïòàãèíòèëëèîí', + 225 => 'êâàòîðñåïòàãèíòèëëèîí', + 228 => 'êâèíñåïòàãèíòèëëèîí', + 231 => 'ñåêññåïòàãèíòèëëèîí', + 234 => 'ñåïòåíñåïòàãèíòèëëèîí', + 237 => 'îêòîñåïòàãèíòèëëèîí', + 240 => 'íîâåìñåïòàãèíòèëëèîí', + 243 => 'îêòîãèíòèëëèîí', + 246 => 'óíîêòîãèíòèëëèîí', + 249 => 'äóîîêòîãèíòèëëèîí', + 252 => 'òðåîêòîãèíòèëëèîí', + 255 => 'êâàòîðîêòîãèíòèëëèîí', + 258 => 'êâèíîêòîãèíòèëëèîí', + 261 => 'ñåêñîêòîãèíòèëëèîí', + 264 => 'ñåïòîêòîãèíòèëëèîí', + 267 => 'îêòîîêòîãèíòèëëèîí', + 270 => 'íîâåìîêòîãèíòèëëèîí', + 273 => 'íîíàãèíòèëëèîí', + 276 => 'óííîíàãèíòèëëèîí', + 279 => 'äóîíîíàãèíòèëëèîí', + 282 => 'òðåíîíàãèíòèëëèîí', + 285 => 'êâàòîðíîíàãèíòèëëèîí', + 288 => 'êâèííîíàãèíòèëëèîí', + 291 => 'ñåêñíîíàãèíòèëëèîí', + 294 => 'ñåïòåííîíàãèíòèëëèîí', + 297 => 'îêòîíîíàãèíòèëëèîí', + 300 => 'íîâåìíîíàãèíòèëëèîí', + 303 => 'öåíòèëëèîí' + ); + + /** + * The array containing the teens' :) names + * @var array + * @access private + */ + var $_teens = array( + 11=>'îäèííàäöàòü', + 12=>'äâåíàäöàòü', + 13=>'òðèíàäöàòü', + 14=>'÷åòûðíàäöàòü', + 15=>'ïÿòíàäöàòü', + 16=>'øåñòíàäöàòü', + 17=>'ñåìíàäöàòü', + 18=>'âîñåìíàäöàòü', + 19=>'äåâÿòíàäöàòü' + ); + + /** + * The array containing the tens' names + * @var array + * @access private + */ + var $_tens = array( + 2=>'äâàäöàòü', + 3=>'òðèäöàòü', + 4=>'ñîðîê', + 5=>'ïÿòüäåñÿò', + 6=>'øåñòüäåñÿò', + 7=>'ñåìüäåñÿò', + 8=>'âîñåìüäåñÿò', + 9=>'äåâÿíîñòî' + ); + + /** + * The array containing the hundreds' names + * @var array + * @access private + */ + var $_hundreds = array( + 1=>'ñòî', + 2=>'äâåñòè', + 3=>'òðèñòà', + 4=>'÷åûðåñòà', + 5=>'ïÿòüñîò', + 6=>'øåñòüñîò', + 7=>'ñåìüñîò', + 8=>'âîñåìüñîò', + 9=>'äåâÿòüñîò' + ); + + /** + * The array containing the digits + * for neutral, male and female + * @var array + * @access private + */ + var $_digits = array( + array('íîëü', 'îäíî', 'äâà', 'òðè', '÷åòûðå','ïÿòü', 'øåñòü', 'ñåìü', 'âîñåìü', 'äåâÿòü'), + array('íîëü', 'îäèí', 'äâà', 'òðè', '÷åòûðå','ïÿòü', 'øåñòü', 'ñåìü', 'âîñåìü', 'äåâÿòü'), + array('íîëü', 'îäíà', 'äâå', 'òðè', '÷åòûðå','ïÿòü', 'øåñòü', 'ñåìü', 'âîñåìü', 'äåâÿòü') + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ' '; + + /** + * The currency names (based on the below links, + * informations from central bank websites and on encyclopedias) + * + * @var array + * @link http://www.jhall.demon.co.uk/currency/by_abbrev.html World currencies + * @link http://www.rusimpex.ru/Content/Reference/Refinfo/valuta.htm Foreign currencies names + * @link http://www.cofe.ru/Finance/money.asp Currencies names + * @access private + */ + var $_currency_names = array( + 'ALL' => array( + array(1,'ëåê','ëåêà','ëåêîâ'), + array(2,'êèíäàðêà','êèíäàðêè','êèíäàðîê') + ), + 'AUD' => array( + array(1,'àâñòðàëèéñêèé äîëëàð','àâñòðàëèéñêèõ äîëëàðà','àâñòðàëèéñêèõ äîëëàðîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'BGN' => array( + array(1,'ëåâ','ëåâà','ëåâîâ'), + array(2,'ñòîòèíêà','ñòîòèíêè','ñòîòèíîê') + ), + 'BRL' => array( + array(1,'áðàçèëüñêèé ðåàë','áðàçèëüñêèõ ðåàëà','áðàçèëüñêèõ ðåàëîâ'), + array(1,'ñåíòàâî','ñåíòàâî','ñåíòàâî') + ), + 'BYR' => array( + array(1,'áåëîðóññêèé ðóáëü','áåëîðóññêèõ ðóáëÿ','áåëîðóññêèõ ðóáëåé'), + array(2,'êîïåéêà','êîïåéêè','êîïååê') + ), + 'CAD' => array( + array(1,'êàíàäñêèé äîëëàð','êàíàäñêèõ äîëëàðà','êàíàäñêèõ äîëëàðîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'CHF' => array( + array(1,'øâåéöàðñêèé ôðàíê','øâåéöàðñêèõ ôðàíêà','øâåéöàðñêèõ ôðàíêîâ'), + array(1,'ñàíòèì','ñàíòèìà','ñàíòèìîâ') + ), + 'CYP' => array( + array(1,'êèïðñêèé ôóíò','êèïðñêèõ ôóíòà','êèïðñêèõ ôóíòîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'CZK' => array( + array(2,'÷åøñêàÿ êðîíà','÷åøñêèõ êðîíû','÷åøñêèõ êðîí'), + array(1,'ãàëèðæ','ãàëèðæà','ãàëèðæåé') + ), + 'DKK' => array( + array(2,'äàòñêàÿ êðîíà','äàòñêèõ êðîíû','äàòñêèõ êðîí'), + array(1,'ýðå','ýðå','ýðå') + ), + 'EEK' => array( + array(2,'ýñòîíñêàÿ êðîíà','ýñòîíñêèõ êðîíû','ýñòîíñêèõ êðîí'), + array(1,'ñåíòè','ñåíòè','ñåíòè') + ), + 'EUR' => array( + array(1,'åâðî','åâðî','åâðî'), + array(1,'åâðîöåíò','åâðîöåíòà','åâðîöåíòîâ') + ), + 'CYP' => array( + array(1,'ôóíò ñòåðëèíãîâ','ôóíòà ñòåðëèíãîâ','ôóíòîâ ñòåðëèíãîâ'), + array(1,'ïåíñ','ïåíñà','ïåíñîâ') + ), + 'CAD' => array( + array(1,'ãîíêîíãñêèé äîëëàð','ãîíêîíãñêèõ äîëëàðà','ãîíêîíãñêèõ äîëëàðîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'HRK' => array( + array(2,'õîðâàòñêàÿ êóíà','õîðâàòñêèõ êóíû','õîðâàòñêèõ êóí'), + array(2,'ëèïà','ëèïû','ëèï') + ), + 'HUF' => array( + array(1,'âåíãåðñêèé ôîðèíò','âåíãåðñêèõ ôîðèíòà','âåíãåðñêèõ ôîðèíòîâ'), + array(1,'ôèëëåð','ôèëëåðà','ôèëëåðîâ') + ), + 'ISK' => array( + array(2,'èñëàíäñêàÿ êðîíà','èñëàíäñêèõ êðîíû','èñëàíäñêèõ êðîí'), + array(1,'ýðå','ýðå','ýðå') + ), + 'JPY' => array( + array(2,'èåíà','èåíû','èåí'), + array(2,'ñåíà','ñåíû','ñåí') + ), + 'LTL' => array( + array(1,'ëèò','ëèòà','ëèòîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'LVL' => array( + array(1,'ëàò','ëàòà','ëàòîâ'), + array(1,'ñåíòèì','ñåíòèìà','ñåíòèìîâ') + ), + 'MKD' => array( + array(1,'ìàêåäîíñêèé äèíàð','ìàêåäîíñêèõ äèíàðà','ìàêåäîíñêèõ äèíàðîâ'), + array(1,'äåíè','äåíè','äåíè') + ), + 'MTL' => array( + array(2,'ìàëüòèéñêàÿ ëèðà','ìàëüòèéñêèõ ëèðû','ìàëüòèéñêèõ ëèð'), + array(1,'ñåíòèì','ñåíòèìà','ñåíòèìîâ') + ), + 'NOK' => array( + array(2,'íîðâåæñêàÿ êðîíà','íîðâåæñêèõ êðîíû','íîðâåæñêèõ êðîí'), + array(0,'ýðå','ýðå','ýðå') + ), + 'PLN' => array( + array(1,'çëîòûé','çëîòûõ','çëîòûõ'), + array(1,'ãðîø','ãðîøà','ãðîøåé') + ), + 'ROL' => array( + array(1,'ðóìûíñêèé ëåé','ðóìûíñêèõ ëåé','ðóìûíñêèõ ëåé'), + array(1,'áàíè','áàíè','áàíè') + ), + // both RUR and RUR are used, I use RUB for shorter form + 'RUB' => array( + array(1,'ðóáëü','ðóáëÿ','ðóáëåé'), + array(2,'êîïåéêà','êîïåéêè','êîïååê') + ), + 'RUR' => array( + array(1,'ðîññèéñêèé ðóáëü','ðîññèéñêèõ ðóáëÿ','ðîññèéñêèõ ðóáëåé'), + array(2,'êîïåéêà','êîïåéêè','êîïååê') + ), + 'SEK' => array( + array(2,'øâåäñêàÿ êðîíà','øâåäñêèõ êðîíû','øâåäñêèõ êðîí'), + array(1,'ýðå','ýðå','ýðå') + ), + 'SIT' => array( + array(1,'ñëîâåíñêèé òîëàð','ñëîâåíñêèõ òîëàðà','ñëîâåíñêèõ òîëàðîâ'), + array(2,'ñòîòèíà','ñòîòèíû','ñòîòèí') + ), + 'SKK' => array( + array(2,'ñëîâàöêàÿ êðîíà','ñëîâàöêèõ êðîíû','ñëîâàöêèõ êðîí'), + array(0,'','','') + ), + 'TRL' => array( + array(2,'òóðåöêàÿ ëèðà','òóðåöêèõ ëèðû','òóðåöêèõ ëèð'), + array(1,'ïèàñòð','ïèàñòðà','ïèàñòðîâ') + ), + 'UAH' => array( + array(2,'ãðèâíà','ãðèâíû','ãðèâåí'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'USD' => array( + array(1,'äîëëàð ÑØÀ','äîëëàðà ÑØÀ','äîëëàðîâ ÑØÀ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ), + 'YUM' => array( + array(1,'þãîñëàâñêèé äèíàð','þãîñëàâñêèõ äèíàðà','þãîñëàâñêèõ äèíàðîâ'), + array(1,'ïàðà','ïàðà','ïàðà') + ), + 'ZAR' => array( + array(1,'ðàíä','ðàíäà','ðàíäîâ'), + array(1,'öåíò','öåíòà','öåíòîâ') + ) + ); + + /** + * The default currency name + * @var string + * @access public + */ + var $def_currency = 'RUB'; // Russian rouble + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Russian language + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $gender Gender of string, 0=neutral, 1=male, 2=female. + * Optional, defaults to 1. + * + * @return string The corresponding word representation + * + * @access private + * @author Andrey Demenev + */ + function toWords($num, $gender = 1) + { + return $this->_toWordsWithCase($num, $dummy, $gender); + } + + /** + * Converts a number to its word representation + * in Russian language and determines the case of string. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $case A variable passed by reference which is set to case + * of the word associated with the number + * @param integer $gender Gender of string, 0=neutral, 1=male, 2=female. + * Optional, defaults to 1. + * + * @return string The corresponding word representation + * + * @access private + * @author Andrey Demenev + */ + function _toWordsWithCase($num, &$case, $gender = 1) + { + $ret = ''; + $case = 3; + + $num = trim($num); + + $sign = ""; + if (substr($num, 0, 1) == '-') { + $sign = $this->_minus . $this->_sep; + $num = substr($num, 1); + } + + while (strlen($num) % 3) $num = '0' . $num; + if ($num == 0 || $num == '') { + $ret .= $this->_digits[$gender][0]; + } + + else { + $power = 0; + while ($power < strlen($num)) { + if (!$power) { + $groupgender = $gender; + } elseif ($power == 3) { + $groupgender = 2; + } else { + $groupgender = 1; + } + $group = $this->_groupToWords(substr($num,-$power-3,3),$groupgender,$_case); + if (!$power) { + $case = $_case; + } + if ($power == 3) { + if ($_case == 1) { + $group .= $this->_sep . 'òûñÿ÷à'; + } elseif ($_case == 2) { + $group .= $this->_sep . 'òûñÿ÷è'; + } else { + $group .= $this->_sep . 'òûñÿ÷'; + } + } elseif ($group && $power>3 && isset($this->_exponent[$power])) { + $group .= $this->_sep . $this->_exponent[$power]; + if ($_case == 2) { + $group .= 'à'; + } elseif ($_case == 3) { + $group .= 'îâ'; + } + } + if ($group) { + $ret = $group . $this->_sep . $ret; + } + $power+=3; + } + } + + return $sign . $ret; + } + + // }}} + // {{{ _groupToWords() + + /** + * Converts a group of 3 digits to its word representation + * in Russian language. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $gender Gender of string, 0=neutral, 1=male, 2=female. + * @param integer $case A variable passed by reference which is set to case + * of the word associated with the number + * + * @return string The corresponding word representation + * + * @access private + * @author Andrey Demenev + */ + function _groupToWords($num, $gender, &$case) + { + $ret = ''; + $case = 3; + if ((int)$num == 0) { + $ret = ''; + } elseif ($num < 10) { + $ret = $this->_digits[$gender][(int)$num]; + if ($num == 1) $case = 1; + elseif ($num < 5) $case = 2; + else $case = 3; + } else { + $num = str_pad($num,3,'0',STR_PAD_LEFT); + $hundreds = (int)$num{0}; + if ($hundreds) { + $ret = $this->_hundreds[$hundreds]; + if (substr($num,1) != '00') { + $ret .= $this->_sep; + } + $case = 3; + } + $tens=(int)$num{1}; + $ones=(int)$num{2}; + if ($tens || $ones) { + if ($tens == 1 && $ones == 0) $ret .= 'äåñÿòü'; + elseif ($tens < 2) $ret .= $this->_teens[$ones+10]; + else { + $ret .= $this->_tens[(int)$tens]; + if ($ones > 0) { + $ret .= $this->_sep + .$this->_digits[$gender][$ones]; + if ($ones == 1) { + $case = 1; + } elseif ($ones < 5) { + $case = 2; + } else { + $case = 3; + } + } + } + } + } + return $ret; + } + // }}} + // {{{ toCurrencyWords() + + /** + * Converts a currency value to its word representation + * (with monetary units) in Russian language + * + * @param integer $int_curr An international currency symbol + * as defined by the ISO 4217 standard (three characters) + * @param integer $decimal A money total amount without fraction part (e.g. amount of dollars) + * @param integer $fraction Fractional part of the money amount (e.g. amount of cents) + * Optional. Defaults to false. + * + * @return string The corresponding word representation for the currency + * + * @access public + * @author Andrey Demenev + */ + function toCurrencyWords($int_curr, $decimal, $fraction = false) + { + $int_curr = strtoupper($int_curr); + if (!isset($this->_currency_names[$int_curr])) { + $int_curr = $this->def_currency; + } + $curr_names = $this->_currency_names[$int_curr]; + $ret = trim($this->_toWordsWithCase($decimal, $case, 0, '', $curr_names[0][0])); + $ret .= $this->_sep . $curr_names[0][$case]; + + if ($fraction !== false) { + $ret .= $this->_sep . trim($this->_toWordsWithCase($fraction, $case, 0, '', $curr_names[1][0])); + $ret .= $this->_sep . $curr_names[1][$case]; + } + return $ret; + } + // }}} + +} + +?> diff --git a/gulliver/thirdparty/pear/Numbers/Words/lang.sv.php b/gulliver/thirdparty/pear/Numbers/Words/lang.sv.php new file mode 100644 index 000000000..ac8024805 --- /dev/null +++ b/gulliver/thirdparty/pear/Numbers/Words/lang.sv.php @@ -0,0 +1,310 @@ + | +// | Robin Ericsson | +// +----------------------------------------------------------------------+ +// +// $Id: lang.de.php,v 1.1.1.1 2004/03/10 10:33:10 makler Exp $ +// +// Numbers_Words class extension to spell numbers in Swedish language. +// + +/** + * + * Class for translating numbers into Swedish. + * @author Robin Ericsson + * @package Numbers_Words + */ + +/** + * Include needed files + */ +require_once("Numbers/Words.php"); + +/** + * Class for translating numbers into Swedish. + * + * @author Robin Ericsson + * @package Numbers_Words + */ +class Numbers_Words_sv extends Numbers_Words +{ + + // {{{ properties + + /** + * Locale name + * @var string + * @access public + */ + var $locale = 'sv'; + + /** + * Language name in English + * @var string + * @access public + */ + var $lang = 'Swedish'; + + /** + * Native language name + * @var string + * @access public + */ + var $lang_native = 'Svenska'; + + /** + * The word for the minus sign + * @var string + * @access private + */ + var $_minus = 'Minus'; // minus sign + + /** + * The sufixes for exponents (singular and plural) + * @var array + * @access private + */ + var $_exponent = array( + 0 => array(''), + 3 => array('tusen', 'tusen'), + 6 => array('miljon','miljoner'), + 9 => array('miljard','miljarder'), + 12 => array('biljon','biljoner'), + 15 => array('biljard','biljarder'), + 18 => array('triljon','triljoner'), + 21 => array('triljard','triljarder'), + 24 => array('kvadriljon','kvadriljoner'), + 27 => array('kvadriljard','kvadriljarder'), + 30 => array('kvintiljon','kvintiljoner'), + 33 => array('kvintiljard','kvintiljarder'), + 36 => array('sextiljon','sextiljoner'), + 39 => array('sextiljard','sextiljarder'), + 42 => array('septiljon','septiljoner'), + 45 => array('septiljard','septiljarder'), + 48 => array('oktiljon','oktiljoner'), + 51 => array('oktiljard','oktiljarder'), + 54 => array('noniljon','noniljoner'), + 57 => array('noniljard','noniljarder'), + 60 => array('dekiljon','dekiljoner'), + 63 => array('dekiljard','dekiljarder'), + 120 => array('vigintiljon','vigintiljoner'), + 123 => array('vigintiljard','vigintiljarder'), + 600 => array('centiljon','centiljoner'), + 603 => array('centiljard','centiljarder') + ); + + /** + * The array containing the digits (indexed by the digits themselves). + * @var array + * @access private + */ + var $_digits = array( + 0 => 'noll', 'ett', 'två', 'tre', 'fyra', + 'fem', 'sex', 'sju', 'åtta', 'nio' + ); + + /** + * The word separator + * @var string + * @access private + */ + var $_sep = ''; + + /** + * The exponent word separator + * @var string + * @access private + */ + var $_sep2 = ' '; + + // }}} + // {{{ toWords() + + /** + * Converts a number to its word representation + * in Swedish language. + * + * @param integer $num An integer between -infinity and infinity inclusive :) + * that need to be converted to words + * @param integer $power The power of ten for the rest of the number to the right. + * Optional, defaults to 0. + * @param integer $powsuffix The power name to be added to the end of the return string. + * Used internally. Optional, defaults to ''. + * + * @return string The corresponding word representation + * + * @access private + * @author Piotr Klaban + * @author Robin Ericsson + * @since PHP 4.2.3 + */ + function toWords($num, $power = 0, $powsuffix = '') { + $ret = ''; + + // add a minus sign + if (substr($num, 0, 1) == '-') { + $ret = $this->_sep . $this->_minus; + $num = substr($num, 1); + } + + // strip excessive zero signs and spaces + $num = trim($num); + $num = preg_replace('/^0+/','',$num); + + if (strlen($num) > 3) { + $maxp = strlen($num)-1; + $curp = $maxp; + for ($p = $maxp; $p > 0; --$p) { // power + + // check for highest power + if (isset($this->_exponent[$p])) { + // send substr from $curp to $p + $snum = substr($num, $maxp - $curp, $curp - $p + 1); + $snum = preg_replace('/^0+/','',$snum); + if ($snum !== '') { + $cursuffix = $this->_exponent[$power][count($this->_exponent[$power])-1]; + if ($powsuffix != '') + $cursuffix .= $this->_sep . $powsuffix; + $ret .= $this->toWords($snum, $p, $cursuffix); + } + $curp = $p - 1; + continue; + } + } + $num = substr($num, $maxp - $curp, $curp - $p + 1); + if ($num == 0) { + return $ret; + } + } elseif ($num == 0 || $num == '') { + return $this->_sep . $this->_digits[0]; + } + + $h = $t = $d = 0; + + switch(strlen($num)) { + case 3: + $h = (int)substr($num,-3,1); + + case 2: + $t = (int)substr($num,-2,1); + + case 1: + $d = (int)substr($num,-1,1); + break; + + case 0: + return; + break; + } + + if ($h) { + $ret .= $this->_sep . $this->_digits[$h] . $this->_sep . 'hundra'; + } + + // ten, twenty etc. + switch ($t) { + case 5: + case 6: + case 7: + $ret .= $this->_sep . $this->_digits[$t] . 'tio'; + break; + + case 9: + $ret .= $this->_sep . 'nittio'; + break; + + case 8: + $ret .= $this->_sep . 'åttio'; + break; + + case 4: + $ret .= $this->_sep . 'fyrtio'; + break; + + case 3: + $ret .= $this->_sep . 'trettio'; + break; + + case 2: + $ret .= $this->_sep . 'tjugo'; + break; + + case 1: + switch ($d) { + case 0: + $ret .= $this->_sep . 'tio'; + break; + + case 1: + $ret .= $this->_sep . 'elva'; + break; + + case 2: + $ret .= $this->_sep . 'tolv'; + break; + + case 3: + $ret .= $this->_sep . 'tretton'; + break; + + case 4: + $ret .= $this->_sep . 'fjorton'; + break; + + case 5: + case 6: + $ret .= $this->_sep . $this->_digits[$d] . 'ton'; + break; + + case 7: + $ret .= $this->_sep . 'sjutton'; + break; + + case 8: + $ret .= $this->_sep . 'arton'; + break; + case 9: + $ret .= $this->_sep . 'nitton'; + } + break; + } + + if ($t != 1 && $d > 0) { // add digits only in <0>,<1,9> and <21,inf> + // add minus sign between [2-9] and digit + $ret .= $this->_sep . $this->_digits[$d]; + } + + if ($power > 0) { + if (isset($this->_exponent[$power])) + $lev = $this->_exponent[$power]; + + if (!isset($lev) || !is_array($lev)) + return null; + + $ret .= $this->_sep . $lev[0]; + } + + if ($powsuffix != '') + $ret .= $this->_sep . $powsuffix; + + return $ret; + } + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/OLE/OLE.php b/gulliver/thirdparty/pear/OLE/OLE.php new file mode 100644 index 000000000..637e189c8 --- /dev/null +++ b/gulliver/thirdparty/pear/OLE/OLE.php @@ -0,0 +1,410 @@ + | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: OLE.php,v 1.7 2003/08/21 15:15:40 xnoguer Exp $ + + +/** +* Constants for OLE package +*/ +define('OLE_PPS_TYPE_ROOT', 5); +define('OLE_PPS_TYPE_DIR', 1); +define('OLE_PPS_TYPE_FILE', 2); +define('OLE_DATA_SIZE_SMALL', 0x1000); +define('OLE_LONG_INT_SIZE', 4); +define('OLE_PPS_SIZE', 0x80); + +require_once('PEAR.php'); +require_once 'OLE/PPS.php'; + +/** +* OLE package base class. +* +* @author Xavier Noguer +* @category Structures +* @package OLE +*/ +class OLE extends PEAR +{ + /** + * The file handle for reading an OLE container + * @var resource + */ + var $_file_handle; + + /** + * Array of PPS's found on the OLE container + * @var array + */ + var $_list; + + /** + * Creates a new OLE object + * Remember to use ampersand when creating an OLE object ($my_ole =& new OLE();) + * @access public + */ + function OLE() + { + $this->_list = array(); + } + + /** + * Reads an OLE container from the contents of the file given. + * + * @acces public + * @param string $file + * @return mixed true on success, PEAR_Error on failure + */ + function read($file) + { + /* consider storing offsets as constants */ + $big_block_size_offset = 30; + $iBdbCnt_offset = 44; + $bd_start_offset = 68; + + $fh = @fopen($file, "r"); + if ($fh == false) { + return $this->raiseError("Can't open file $file"); + } + $this->_file_handle = $fh; + + /* begin reading OLE attributes */ + fseek($fh, 0); + $signature = fread($fh, 8); + if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) { + return $this->raiseError("File doesn't seem to be an OLE container."); + } + fseek($fh, $big_block_size_offset); + $packed_array = unpack("v", fread($fh, 2)); + $big_block_size = pow(2, $packed_array['']); + + $packed_array = unpack("v", fread($fh, 2)); + $small_block_size = pow(2, $packed_array['']); + $i1stBdL = ($big_block_size - 0x4C) / OLE_LONG_INT_SIZE; + + fseek($fh, $iBdbCnt_offset); + $packed_array = unpack("V", fread($fh, 4)); + $iBdbCnt = $packed_array['']; + + $packed_array = unpack("V", fread($fh, 4)); + $pps_wk_start = $packed_array['']; + + fseek($fh, $bd_start_offset); + $packed_array = unpack("V", fread($fh, 4)); + $bd_start = $packed_array['']; + $packed_array = unpack("V", fread($fh, 4)); + $bd_count = $packed_array['']; + $packed_array = unpack("V", fread($fh, 4)); + $iAll = $packed_array['']; // this may be wrong + /* create OLE_PPS objects from */ + $ret = $this->_readPpsWks($pps_wk_start, $big_block_size); + if (PEAR::isError($ret)) { + return $ret; + } + return true; + } + + /** + * Destructor (using PEAR) + * Just closes the file handle on the OLE file. + * + * @access private + */ + function _OLE() + { + fclose($this->_file_handle); + } + + /** + * Gets information about all PPS's on the OLE container from the PPS WK's + * creates an OLE_PPS object for each one. + * + * @access private + * @param integer $pps_wk_start Position inside the OLE file where PPS WK's start + * @param integer $big_block_size Size of big blobks in the OLE file + * @return mixed true on success, PEAR_Error on failure + */ + function _readPpsWks($pps_wk_start, $big_block_size) + { + $pointer = ($pps_wk_start + 1) * $big_block_size; + while (1) + { + fseek($this->_file_handle, $pointer); + $pps_wk = fread($this->_file_handle, OLE_PPS_SIZE); + if (strlen($pps_wk) != OLE_PPS_SIZE) { + break; // Excel likes to add a trailing byte sometimes + //return $this->raiseError("PPS at $pointer seems too short: ".strlen($pps_wk)); + } + $name_length = unpack("c", substr($pps_wk, 64, 2)); // FIXME (2 bytes??) + $name_length = $name_length[''] - 2; + $name = substr($pps_wk, 0, $name_length); + $type = unpack("c", substr($pps_wk, 66, 1)); + if (($type[''] != OLE_PPS_TYPE_ROOT) and + ($type[''] != OLE_PPS_TYPE_DIR) and + ($type[''] != OLE_PPS_TYPE_FILE)) + { + return $this->raiseError("PPS at $pointer has unknown type: {$type['']}"); + } + $prev = unpack("V", substr($pps_wk, 68, 4)); + $next = unpack("V", substr($pps_wk, 72, 4)); + $dir = unpack("V", substr($pps_wk, 76, 4)); + // there is no magic number, it can take different values. + //$magic = unpack("V", strrev(substr($pps_wk, 92, 4))); + $time_1st = substr($pps_wk, 100, 8); + $time_2nd = substr($pps_wk, 108, 8); + $start_block = unpack("V", substr($pps_wk, 116, 4)); + $size = unpack("V", substr($pps_wk, 120, 4)); + // _data member will point to position in file!! + // OLE_PPS object is created with an empty children array!! + $this->_list[] = new OLE_PPS(null, '', $type[''], $prev[''], $next[''], + $dir[''], OLE::OLE2LocalDate($time_1st), + OLE::OLE2LocalDate($time_2nd), + ($start_block[''] + 1) * $big_block_size, array()); + // give it a size + $this->_list[count($this->_list) - 1]->Size = $size['']; + // check if the PPS tree (starting from root) is complete + if ($this->_ppsTreeComplete(0)) { + break; + } + $pointer += OLE_PPS_SIZE; + } + } + + /** + * It checks whether the PPS tree is complete (all PPS's read) + * starting with the given PPS (not necessarily root) + * + * @access private + * @param integer $index The index of the PPS from which we are checking + * @return boolean Whether the PPS tree for the given PPS is complete + */ + function _ppsTreeComplete($index) + { + if ($this->_list[$index]->NextPps != -1) { + if (!isset($this->_list[$this->_list[$index]->NextPps])) { + return false; + } + else { + return $this->_ppsTreeComplete($this->_list[$index]->NextPps); + } + } + if ($this->_list[$index]->DirPps != -1) { + if (!isset($this->_list[$this->_list[$index]->DirPps])) { + return false; + } + else { + return $this->_ppsTreeComplete($this->_list[$index]->DirPps); + } + } + return true; + } + + /** + * Checks whether a PPS is a File PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS + * @return bool true if it's a File PPS, false otherwise + */ + function isFile($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == OLE_PPS_TYPE_FILE); + } + return false; + } + + /** + * Checks whether a PPS is a Root PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS. + * @return bool true if it's a Root PPS, false otherwise + */ + function isRoot($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == OLE_PPS_TYPE_ROOT); + } + return false; + } + + /** + * Gives the total number of PPS's found in the OLE container. + * + * @access public + * @return integer The total number of PPS's found in the OLE container + */ + function ppsTotal() + { + return count($this->_list); + } + + /** + * Gets data from a PPS + * If there is no PPS for the index given, it will return an empty string. + * + * @access public + * @param integer $index The index for the PPS + * @param integer $position The position from which to start reading + * (relative to the PPS) + * @param integer $length The amount of bytes to read (at most) + * @return string The binary string containing the data requested + */ + function getData($index, $position, $length) + { + // if position is not valid return empty string + if (!isset($this->_list[$index]) or ($position >= $this->_list[$index]->Size) or ($position < 0)) { + return ''; + } + // Beware!!! _data member is actually a position + fseek($this->_file_handle, $this->_list[$index]->_data + $position); + return fread($this->_file_handle, $length); + } + + /** + * Gets the data length from a PPS + * If there is no PPS for the index given, it will return 0. + * + * @access public + * @param integer $index The index for the PPS + * @return integer The amount of bytes in data the PPS has + */ + function getDataLength($index) + { + if (isset($this->_list[$index])) { + return $this->_list[$index]->Size; + } + return 0; + } + + /** + * Utility function to transform ASCII text to Unicode + * + * @access public + * @static + * @param string $ascii The ASCII string to transform + * @return string The string in Unicode + */ + function Asc2Ucs($ascii) + { + $rawname = ''; + for ($i = 0; $i < strlen($ascii); $i++) { + $rawname .= $ascii{$i}."\x00"; + } + return $rawname; + } + + /** + * Utility function + * Returns a string for the OLE container with the date given + * + * @access public + * @static + * @param integer $date A timestamp + * @return string The string for the OLE container + */ + function LocalDate2OLE($date = null) + { + if (!isset($date)) { + return "\x00\x00\x00\x00\x00\x00\x00\x00"; + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2,32); + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + // calculate seconds + $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), + date("m",$date),date("d",$date),date("Y",$date)); + // multiply just to make MS happy + $big_date *= 10000000; + + $high_part = floor($big_date/$factor); + // lower 4 bytes + $low_part = floor((($big_date/$factor) - $high_part)*$factor); + + // Make HEX string + $res = ''; + + for ($i=0; $i<4; $i++) + { + $hex = $low_part % 0x100; + $res .= pack('c', $hex); + $low_part /= 0x100; + } + for ($i=0; $i<4; $i++) + { + $hex = $high_part % 0x100; + $res .= pack('c', $hex); + $high_part /= 0x100; + } + return $res; + } + + /** + * Returns a timestamp from an OLE container's date + * + * @access public + * @static + * @param integer $string A binary string with the encoded date + * @return string The timestamp corresponding to the string + */ + function OLE2LocalDate($string) + { + if (strlen($string) != 8) { + return new PEAR_Error("Expecting 8 byte string"); + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2,32); + $high_part = 0; + for ($i=0; $i<4; $i++) + { + $al = unpack('C', $string{(7 - $i)}); + $high_part += $al['']; + if ($i < 3) { + $high_part *= 0x100; + } + } + $low_part = 0; + for ($i=4; $i<8; $i++) + { + $al = unpack('C', $string{(7 - $i)}); + $low_part += $al['']; + if ($i < 7) { + $low_part *= 0x100; + } + } + $big_date = ($high_part*$factor) + $low_part; + // translate to seconds + $big_date /= 10000000; + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + + // translate to seconds from beggining of UNIX era + $big_date -= $days*24*3600; + return floor($big_date); + } +} +?> diff --git a/gulliver/thirdparty/pear/OLE/PPS.php b/gulliver/thirdparty/pear/OLE/PPS.php new file mode 100644 index 000000000..03dbd9018 --- /dev/null +++ b/gulliver/thirdparty/pear/OLE/PPS.php @@ -0,0 +1,219 @@ + | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: PPS.php,v 1.5 2003/12/14 18:12:28 xnoguer Exp $ + + +require_once('PEAR.php'); +require_once('OLE.php'); + +/** +* Class for creating PPS's for OLE containers +* +* @author Xavier Noguer +* @category Structures +* @package OLE +*/ +class OLE_PPS extends PEAR +{ + /** + * The PPS index + * @var integer + */ + var $No; + + /** + * The PPS name (in Unicode) + * @var string + */ + var $Name; + + /** + * The PPS type. Dir, Root or File + * @var integer + */ + var $Type; + + /** + * The index of the previous PPS + * @var integer + */ + var $PrevPps; + + /** + * The index of the next PPS + * @var integer + */ + var $NextPps; + + /** + * The index of it's first child if this is a Dir or Root PPS + * @var integer + */ + var $DirPps; + + /** + * A timestamp + * @var integer + */ + var $Time1st; + + /** + * A timestamp + * @var integer + */ + var $Time2nd; + + /** + * Starting block (small or big) for this PPS's data inside the container + * @var integer + */ + var $_StartBlock; + + /** + * The size of the PPS's data (in bytes) + * @var integer + */ + var $Size; + + /** + * The PPS's data (only used if it's not using a temporary file) + * @var string + */ + var $_data; + + /** + * Array of child PPS's (only used by Root and Dir PPS's) + * @var array + */ + var $children = array(); + + /** + * The constructor + * + * @access public + * @param integer $No The PPS index + * @param string $name The PPS name (in Unicode) + * @param integer $type The PPS type. Dir, Root or File + * @param integer $prev The index of the previous PPS + * @param integer $next The index of the next PPS + * @param integer $dir The index of it's first child if this is a Dir or Root PPS + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + * @param array $children Array containing children PPS for this PPS + */ + function OLE_PPS($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children) + { + $this->No = $No; + $this->Name = $name; + $this->Type = $type; + $this->PrevPps = $prev; + $this->NextPps = $next; + $this->DirPps = $dir; + $this->Time1st = $time_1st; + $this->Time2nd = $time_2nd; + $this->_data = $data; + $this->children = $children; + if ($data != '') { + $this->Size = strlen($data); + } + else { + $this->Size = 0; + } + } + + /** + * Returns the amount of data saved for this PPS + * + * @access private + * @return integer The amount of data (in bytes) + */ + function _DataLen() + { + if (!isset($this->_data)) { + return 0; + } + if (isset($this->_PPS_FILE)) + { + fseek($this->_PPS_FILE, 0); + $stats = fstat($this->_PPS_FILE); + return $stats[7]; + } + else { + return strlen($this->_data); + } + } + + /** + * Returns a string with the PPS's WK (What is a WK?) + * + * @access private + * @return string The binary string + */ + function _getPpsWk() + { + $ret = $this->Name; + for ($i = 0; $i < (64 - strlen($this->Name)); $i++) { + $ret .= "\x00"; + } + $ret .= pack("v", strlen($this->Name) + 2) // 66 + . pack("c", $this->Type) // 67 + . pack("c", 0x00) //UK // 68 + . pack("V", $this->PrevPps) //Prev // 72 + . pack("V", $this->NextPps) //Next // 76 + . pack("V", $this->DirPps) //Dir // 80 + . "\x00\x09\x02\x00" // 84 + . "\x00\x00\x00\x00" // 88 + . "\xc0\x00\x00\x00" // 92 + . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root + . "\x00\x00\x00\x00" // 100 + . OLE::LocalDate2OLE($this->Time1st) // 108 + . OLE::LocalDate2OLE($this->Time2nd) // 116 + . pack("V", isset($this->_StartBlock)? + $this->_StartBlock:0) // 120 + . pack("V", $this->Size) // 124 + . pack("V", 0); // 128 + return $ret; + } + + /** + * Updates index and pointers to previous, next and children PPS's for this + * PPS. I don't think it'll work with Dir PPS's. + * + * @access private + * @param array &$pps_array Reference to the array of PPS's for the whole OLE + * container + * @return integer The index for this PPS + */ + function _savePpsSetPnt(&$pps_array) + { + $pps_array[count($pps_array)] = &$this; + $this->No = count($pps_array) - 1; + $this->PrevPps = 0xFFFFFFFF; + $this->NextPps = 0xFFFFFFFF; + if (count($this->children) > 0) { + $this->DirPps = $this->children[0]->_savePpsSetPnt($pps_array); + } + else { + $this->DirPps = 0xFFFFFFFF; + } + return $this->No; + } +} +?> diff --git a/gulliver/thirdparty/pear/OLE/PPS/File.php b/gulliver/thirdparty/pear/OLE/PPS/File.php new file mode 100644 index 000000000..852c7af10 --- /dev/null +++ b/gulliver/thirdparty/pear/OLE/PPS/File.php @@ -0,0 +1,114 @@ + | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: File.php,v 1.8 2003/12/12 21:10:10 xnoguer Exp $ + + +require_once ('OLE/PPS.php'); + +/** +* Class for creating File PPS's for OLE containers +* +* @author Xavier Noguer +* @category Structures +* @package OLE +*/ +class OLE_PPS_File extends OLE_PPS +{ + /** + * The temporary dir for storing the OLE file + * @var string + */ + var $_tmp_dir; + + /** + * The constructor + * + * @access public + * @param string $name The name of the file (in Unicode) + * @see OLE::Asc2Ucs() + */ + function OLE_PPS_File($name) + { + $this->_tmp_dir = ''; + $this->OLE_PPS( + null, + $name, + OLE_PPS_TYPE_FILE, + null, + null, + null, + null, + null, + '', + array()); + } + + /** + * Sets the temp dir used for storing the OLE file + * + * @access public + * @param string $dir The dir to be used as temp dir + * @return true if given dir is valid, false otherwise + */ + function setTempDir($dir) + { + if (is_dir($dir)) { + $this->_tmp_dir = $dir; + return true; + } + return false; + } + + /** + * Initialization method. Has to be called right after OLE_PPS_File(). + * + * @access public + * @return mixed true on success. PEAR_Error on failure + */ + function init() + { + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_File"); + $fh = @fopen($this->_tmp_filename, "w+b"); + if ($fh == false) { + return $this->raiseError("Can't create temporary file"); + } + $this->_PPS_FILE = $fh; + if ($this->_PPS_FILE) { + fseek($this->_PPS_FILE, 0); + } + } + + /** + * Append data to PPS + * + * @access public + * @param string $data The data to append + */ + function append($data) + { + if ($this->_PPS_FILE) { + fwrite($this->_PPS_FILE, $data); + } + else { + $this->_data .= $data; + } + } +} +?> diff --git a/gulliver/thirdparty/pear/OLE/PPS/Root.php b/gulliver/thirdparty/pear/OLE/PPS/Root.php new file mode 100644 index 000000000..9b86d18d7 --- /dev/null +++ b/gulliver/thirdparty/pear/OLE/PPS/Root.php @@ -0,0 +1,519 @@ + | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: Root.php,v 1.7 2003/12/12 21:10:10 xnoguer Exp $ + + +require_once ('OLE/PPS.php'); + +/** +* Class for creating Root PPS's for OLE containers +* +* @author Xavier Noguer +* @category Structures +* @package OLE +*/ +class OLE_PPS_Root extends OLE_PPS +{ + /** + * The temporary dir for storing the OLE file + * @var string + */ + var $_tmp_dir; + + /** + * Constructor + * + * @access public + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + */ + function OLE_PPS_Root($time_1st, $time_2nd, $raChild) + { + $this->_tmp_dir = ''; + $this->OLE_PPS( + null, + OLE::Asc2Ucs('Root Entry'), + OLE_PPS_TYPE_ROOT, + null, + null, + null, + $time_1st, + $time_2nd, + null, + $raChild); + } + + /** + * Sets the temp dir used for storing the OLE file + * + * @access public + * @param string $dir The dir to be used as temp dir + * @return true if given dir is valid, false otherwise + */ + function setTempDir($dir) + { + if (is_dir($dir)) { + $this->_tmp_dir = $dir; + return true; + } + return false; + } + + /** + * Method for saving the whole OLE container (including files). + * In fact, if called with an empty argument (or '-'), it saves to a + * temporary file and then outputs it's contents to stdout. + * + * @param string $filename The name of the file where to save the OLE container + * @access public + * @return mixed true on success, PEAR_Error on failure + */ + function save($filename) + { + // Initial Setting for saving + $this->_BIG_BLOCK_SIZE = pow(2, + ((isset($this->_BIG_BLOCK_SIZE))? $this->_adjust2($this->_BIG_BLOCK_SIZE) : 9)); + $this->_SMALL_BLOCK_SIZE= pow(2, + ((isset($this->_SMALL_BLOCK_SIZE))? $this->_adjust2($this->_SMALL_BLOCK_SIZE): 6)); + + // Open temp file if we are sending output to stdout + if (($filename == '-') or ($filename == '')) + { + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_FILEH_ = @fopen($this->_tmp_filename,"w+b"); + if ($this->_FILEH_ == false) { + return $this->raiseError("Can't create temporary file."); + } + } + else + { + $this->_FILEH_ = @fopen($filename, "wb"); + if ($this->_FILEH_ == false) { + return $this->raiseError("Can't open $filename. It may be in use or protected."); + } + } + // Make an array of PPS's (for Save) + $aList = array(); + $this->_savePpsSetPnt($aList); + // calculate values for header + list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); + // Save Header + $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt); + + // Make Small Data string (write SBD) + $this->_data = $this->_makeSmallData($aList); + + // Write BB + $this->_saveBigData($iSBDcnt, $aList); + // Write PPS + $this->_savePps($aList); + // Write Big Block Depot and BDList and Adding Header informations + $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); + // Close File, send it to stdout if necessary + if(($filename == '-') or ($filename == '')) + { + fseek($this->_FILEH_, 0); + fpassthru($this->_FILEH_); + @fclose($this->_FILEH_); + // Delete the temporary file. + @unlink($this->_tmp_filename); + } + else { + @fclose($this->_FILEH_); + } + return true; + } + + /** + * Calculate some numbers + * + * @access private + * @param array $raList Reference to an array of PPS's + * @return array The array of numbers + */ + function _calcSize(&$raList) + { + // Calculate Basic Setting + list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0); + $iSmallLen = 0; + $iSBcnt = 0; + for ($i = 0; $i < count($raList); $i++) { + if($raList[$i]->Type == OLE_PPS_TYPE_FILE) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if($raList[$i]->Size < OLE_DATA_SIZE_SMALL) { + $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + } + else { + $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + } + } + $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE; + $iSlCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE); + $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0); + $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) + + (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0)); + $iCnt = count($raList); + $iBdCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE; + $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0)); + + return array($iSBDcnt, $iBBcnt, $iPPScnt); + } + + /** + * Helper function for caculating a magic value for block sizes + * + * @access private + * @param integer $i2 The argument + * @see save() + * @return integer + */ + function _adjust2($i2) + { + $iWk = log($i2)/log(2); + return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; + } + + /** + * Save OLE header + * + * @access private + * @param integer $iSBDcnt + * @param integer $iBBcnt + * @param integer $iPPScnt + */ + function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) + { + $FILE = $this->_FILEH_; + + // Calculate Basic Setting + $iBlCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + + // Calculate BD count + if ($iBdCnt >$i1stBdL) + { + while (1) + { + $iBdExL++; + $iAllW++; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) { + break; + } + } + } + + // Save Header + fwrite($FILE, + "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("v", 0x3b) + . pack("v", 0x03) + . pack("v", -2) + . pack("v", 9) + . pack("v", 6) + . pack("v", 0) + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("V", $iBdCnt) + . pack("V", $iBBcnt+$iSBDcnt) //ROOT START + . pack("V", 0) + . pack("V", 0x1000) + . pack("V", 0) //Small Block Depot + . pack("V", 1) + ); + // Extra BDList Start, Count + if ($iBdCnt < $i1stBdL) + { + fwrite($FILE, + pack("V", -2). // Extra BDList Start + pack("V", 0) // Extra BDList Count + ); + } + else + { + fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); + } + + // BDList + for ($i=0; $i<$i1stBdL and $i < $iBdCnt; $i++) { + fwrite($FILE, pack("V", $iAll+$i)); + } + if ($i < $i1stBdL) + { + for ($j = 0; $j < ($i1stBdL-$i); $j++) { + fwrite($FILE, (pack("V", -1))); + } + } + } + + /** + * Saving big data (PPS's with data bigger than OLE_DATA_SIZE_SMALL) + * + * @access private + * @param integer $iStBlk + * @param array &$raList Reference to array of PPS's + */ + function _saveBigData($iStBlk, &$raList) + { + $FILE = $this->_FILEH_; + + // cycle through PPS's + for ($i = 0; $i < count($raList); $i++) + { + if($raList[$i]->Type != OLE_PPS_TYPE_DIR) + { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if(($raList[$i]->Size >= OLE_DATA_SIZE_SMALL) or + (($raList[$i]->Type == OLE_PPS_TYPE_ROOT) and isset($raList[$i]->_data))) + { + // Write Data + if(isset($raList[$i]->_PPS_FILE)) + { + $iLen = 0; + fseek($raList[$i]->_PPS_FILE, 0); // To The Top + while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) + { + $iLen += strlen($sBuff); + fwrite($FILE, $sBuff); + } + } + else { + fwrite($FILE, $raList[$i]->_data); + } + + if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) + { + for ($j = 0; $j < ($this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)); $j++) { + fwrite($FILE, "\x00"); + } + } + // Set For PPS + $raList[$i]->_StartBlock = $iStBlk; + $iStBlk += + (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + // Close file for each PPS, and unlink it + if (isset($raList[$i]->_PPS_FILE)) + { + @fclose($raList[$i]->_PPS_FILE); + $raList[$i]->_PPS_FILE = null; + @unlink($raList[$i]->_tmp_filename); + } + } + } + } + + /** + * get small data (PPS's with data smaller than OLE_DATA_SIZE_SMALL) + * + * @access private + * @param array &$raList Reference to array of PPS's + */ + function _makeSmallData(&$raList) + { + $sRes = ''; + $FILE = $this->_FILEH_; + $iSmBlk = 0; + + for ($i = 0; $i < count($raList); $i++) + { + // Make SBD, small data string + if ($raList[$i]->Type == OLE_PPS_TYPE_FILE) + { + if ($raList[$i]->Size <= 0) { + continue; + } + if ($raList[$i]->Size < OLE_DATA_SIZE_SMALL) + { + $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + // Add to SBD + for ($j = 0; $j < ($iSmbCnt-1); $j++) { + fwrite($FILE, pack("V", $j+$iSmBlk+1)); + } + fwrite($FILE, pack("V", -2)); + + // Add to Data String(this will be written for RootEntry) + if ($raList[$i]->_PPS_FILE) + { + fseek($raList[$i]->_PPS_FILE, 0); // To The Top + while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + $sRes .= $sBuff; + } + } + else { + $sRes .= $raList[$i]->_data; + } + if($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) + { + for ($j = 0; $j < ($this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); $j++) { + $sRes .= "\x00"; + } + } + // Set for PPS + $raList[$i]->_StartBlock = $iSmBlk; + $iSmBlk += $iSmbCnt; + } + } + } + $iSbCnt = floor($this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE); + if($iSmBlk % $iSbCnt) + { + for ($i = 0; $i < ($iSbCnt - ($iSmBlk % $iSbCnt)); $i++) { + fwrite($FILE, pack("V", -1)); + } + } + return $sRes; + } + + /** + * Saves all the PPS's WKs + * + * @access private + * @param array $raList Reference to an array with all PPS's + */ + function _savePps(&$raList) + { + // Save each PPS WK + for ($i = 0; $i < count($raList); $i++) { + fwrite($this->_FILEH_, $raList[$i]->_getPpsWk()); + } + // Adjust for Block + $iCnt = count($raList); + $iBCnt = $this->_BIG_BLOCK_SIZE / OLE_PPS_SIZE; + if ($iCnt % $iBCnt) + { + for ($i = 0; $i < (($iBCnt - ($iCnt % $iBCnt)) * OLE_PPS_SIZE); $i++) { + fwrite($this->_FILEH_, "\x00"); + } + } + } + + /** + * Saving Big Block Depot + * + * @access private + * @param integer $iSbdSize + * @param integer $iBsize + * @param integer $iPpsCnt + */ + function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) + { + $FILE = $this->_FILEH_; + // Calculate Basic Setting + $iBbCnt = $this->_BIG_BLOCK_SIZE / OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBsize + $iPpsCnt + $iSbdSize; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + // Calculate BD count + if ($iBdCnt >$i1stBdL) + { + while (1) + { + $iBdExL++; + $iAllW++; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) { + break; + } + } + } + + // Making BD + // Set for SBD + if ($iSbdSize > 0) + { + for ($i = 0; $i<($iSbdSize-1); $i++) { + fwrite($FILE, pack("V", $i+1)); + } + fwrite($FILE, pack("V", -2)); + } + // Set for B + for ($i = 0; $i<($iBsize-1); $i++) { + fwrite($FILE, pack("V", $i+$iSbdSize+1)); + } + fwrite($FILE, pack("V", -2)); + + // Set for PPS + for ($i = 0; $i<($iPpsCnt-1); $i++) { + fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); + } + fwrite($FILE, pack("V", -2)); + // Set for BBD itself ( 0xFFFFFFFD : BBD) + for ($i=0; $i<$iBdCnt;$i++) { + fwrite($FILE, pack("V", 0xFFFFFFFD)); + } + // Set for ExtraBDList + for ($i=0; $i<$iBdExL;$i++) { + fwrite($FILE, pack("V", 0xFFFFFFFC)); + } + // Adjust for Block + if (($iAllW + $iBdCnt) % $iBbCnt) + { + for ($i = 0; $i < ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); $i++) { + fwrite($FILE, pack("V", -1)); + } + } + // Extra BDList + if ($iBdCnt > $i1stBdL) + { + $iN=0; + $iNb=0; + for ($i=$i1stBdL;$i<$iBdCnt; $i++, $iN++) + { + if ($iN>=($iBbCnt-1)) + { + $iN = 0; + $iNb++; + fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb)); + } + fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); + } + if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) + { + for ($i = 0; $i < (($iBbCnt-1) - (($iBdCnt-$i1stBdL) % ($iBbCnt-1))); $i++) { + fwrite($FILE, pack("V", -1)); + } + } + fwrite($FILE, pack("V", -2)); + } + } +} +?> diff --git a/gulliver/thirdparty/pear/OS/Guess.php b/gulliver/thirdparty/pear/OS/Guess.php new file mode 100644 index 000000000..42d7391a7 --- /dev/null +++ b/gulliver/thirdparty/pear/OS/Guess.php @@ -0,0 +1,265 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Guess.php,v 1.9 2003/04/03 23:11:50 ssb Exp $ + +// {{{ uname examples + +// php_uname() without args returns the same as 'uname -a', or a PHP-custom +// string for Windows. +// PHP versions prior to 4.3 return the uname of the host where PHP was built, +// as of 4.3 it returns the uname of the host running the PHP code. +// +// PC RedHat Linux 7.1: +// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown +// +// PC Debian Potato: +// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown +// +// PC FreeBSD 3.3: +// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.3: +// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386 +// +// PC FreeBSD 4.5 w/uname from GNU shellutils: +// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown +// +// HP 9000/712 HP-UX 10: +// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license +// +// HP 9000/712 HP-UX 10 w/uname from GNU shellutils: +// HP-UX host B.10.10 A 9000/712 unknown +// +// IBM RS6000/550 AIX 4.3: +// AIX host 3 4 000003531C00 +// +// AIX 4.3 w/uname from GNU shellutils: +// AIX host 3 4 000003531C00 unknown +// +// SGI Onyx IRIX 6.5 w/uname from GNU shellutils: +// IRIX64 host 6.5 01091820 IP19 mips +// +// SGI Onyx IRIX 6.5: +// IRIX64 host 6.5 01091820 IP19 +// +// SparcStation 20 Solaris 8 w/uname from GNU shellutils: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc +// +// SparcStation 20 Solaris 8: +// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 +// + +// }}} + +/* TODO: + * - define endianness, to allow matchSignature("bigend") etc. + */ + +class OS_Guess +{ + var $sysname; + var $nodename; + var $cpu; + var $release; + var $extra; + + function OS_Guess($uname = null) + { + list($this->sysname, + $this->release, + $this->cpu, + $this->extra, + $this->nodename) = $this->parseSignature($uname); + } + + function parseSignature($uname = null) + { + static $sysmap = array( + 'HP-UX' => 'hpux', + 'IRIX64' => 'irix', + // Darwin? + ); + static $cpumap = array( + 'i586' => 'i386', + 'i686' => 'i386', + ); + if ($uname === null) { + $uname = php_uname(); + } + $parts = split('[[:space:]]+', trim($uname)); + $n = count($parts); + + $release = $machine = $cpu = ''; + $sysname = $parts[0]; + $nodename = $parts[1]; + $cpu = $parts[$n-1]; + $extra = ''; + if ($cpu == 'unknown') { + $cpu = $parts[$n-2]; + } + + switch ($sysname) { + case 'AIX': + $release = "$parts[3].$parts[2]"; + break; + case 'Windows': + switch ($parts[1]) { + case '95/98': + $release = '9x'; + break; + default: + $release = $parts[1]; + break; + } + $cpu = 'i386'; + break; + case 'Linux': + $extra = $this->_detectGlibcVersion(); + // use only the first two digits from the kernel version + $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]); + break; + default: + $release = ereg_replace('-.*', '', $parts[2]); + break; + } + + + if (isset($sysmap[$sysname])) { + $sysname = $sysmap[$sysname]; + } else { + $sysname = strtolower($sysname); + } + if (isset($cpumap[$cpu])) { + $cpu = $cpumap[$cpu]; + } + return array($sysname, $release, $cpu, $extra, $nodename); + } + + function _detectGlibcVersion() + { + // Use glibc's header file to + // get major and minor version number: + include_once "System.php"; + $tmpfile = System::mktemp("glibctest"); + $fp = fopen($tmpfile, "w"); + fwrite($fp, "#include \n__GLIBC__ __GLIBC_MINOR__\n"); + fclose($fp); + $cpp = popen("/usr/bin/cpp $tmpfile", "r"); + $major = $minor = 0; + while ($line = fgets($cpp, 1024)) { + if ($line{0} == '#') { + continue; + } + if (list($major, $minor) = explode(' ', trim($line))) { + break; + } + } + pclose($cpp); + unlink($tmpfile); + if (!($major && $minor) && file_exists('/lib/libc.so.6')) { + // Let's try reading the libc.so.6 symlink + if (ereg('^libc-([.*])\.so$', basename(readlink('/lib/libc.so.6')), $matches)) { + list($major, $minor) = explode('.', $matches); + } + } + if (!($major && $minor)) { + return ''; + } + return "glibc{$major}.{$minor}"; + } + + function getSignature() + { + if (empty($this->extra)) { + return "{$this->sysname}-{$this->release}-{$this->cpu}"; + } + return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}"; + } + + function getSysname() + { + return $this->sysname; + } + + function getNodename() + { + return $this->nodename; + } + + function getCpu() + { + return $this->cpu; + } + + function getRelease() + { + return $this->release; + } + + function getExtra() + { + return $this->extra; + } + + function matchSignature($match) + { + if (is_array($match)) { + $fragments = $match; + } else { + $fragments = explode('-', $match); + } + $n = count($fragments); + $matches = 0; + if ($n > 0) { + $matches += $this->_matchFragment($fragments[0], $this->sysname); + } + if ($n > 1) { + $matches += $this->_matchFragment($fragments[1], $this->release); + } + if ($n > 2) { + $matches += $this->_matchFragment($fragments[2], $this->cpu); + } + if ($n > 3) { + $matches += $this->_matchFragment($fragments[3], $this->extra); + } + return ($matches == $n); + } + + function _matchFragment($fragment, $value) + { + if (strcspn($fragment, '*?') < strlen($fragment)) { + $reg = '^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '$'; + return eregi($reg, $value); + } + return ($fragment == '*' || !strcasecmp($fragment, $value)); + } + +} + +/* + * Local Variables: + * indent-tabs-mode: nil + * c-basic-offset: 4 + * End: + */ +?> diff --git a/gulliver/thirdparty/pear/PEAR.php b/gulliver/thirdparty/pear/PEAR.php new file mode 100644 index 000000000..0cda6864d --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR.php @@ -0,0 +1,1056 @@ + | +// | Stig Bakken | +// | Tomas V.V.Cox | +// +--------------------------------------------------------------------+ +// +// $Id: PEAR.php 3355 2005-06-11 22:14:40Z nbm $ +// + +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); +/** + * WARNING: obsolete + * @deprecated + */ +define('PEAR_ERROR_EXCEPTION', 32); +define('PEAR_ZE2', (function_exists('version_compare') && + version_compare(zend_version(), "2-dev", "ge"))); + +if (substr(PHP_OS, 0, 3) == 'WIN') { + define('OS_WINDOWS', true); + define('OS_UNIX', false); + define('PEAR_OS', 'Windows'); +} else { + define('OS_WINDOWS', false); + define('OS_UNIX', true); + define('PEAR_OS', 'Unix'); // blatant assumption +} + +// instant backwards compatibility +if (!defined('PATH_SEPARATOR')) { + if (OS_WINDOWS) { + define('PATH_SEPARATOR', ';'); + } else { + define('PATH_SEPARATOR', ':'); + } +} + +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; +$GLOBALS['_PEAR_destructor_object_list'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); + +ini_set('track_errors', true); + +/** + * Base class for other PEAR classes. Provides rudimentary + * emulation of destructors. + * + * If you want a destructor in your class, inherit PEAR and make a + * destructor method called _yourclassname (same name as the + * constructor, but with a "_" prefix). Also, in your constructor you + * have to call the PEAR constructor: $this->PEAR();. + * The destructor method will be called without parameters. Note that + * at in some SAPI implementations (such as Apache), any output during + * the request shutdown (in which destructors are called) seems to be + * discarded. If you need to get any debug information from your + * destructor, use error_log(), syslog() or something similar. + * + * IMPORTANT! To use the emulated destructors you need to create the + * objects by reference: $obj =& new PEAR_child; + * + * @since PHP 4.0.2 + * @author Stig Bakken + * @see http://pear.php.net/manual/ + */ +class PEAR +{ + // {{{ properties + + /** + * Whether to enable internal debug messages. + * + * @var bool + * @access private + */ + var $_debug = false; + + /** + * Default error mode for this object. + * + * @var int + * @access private + */ + var $_default_error_mode = null; + + /** + * Default error options used for this object when error mode + * is PEAR_ERROR_TRIGGER. + * + * @var int + * @access private + */ + var $_default_error_options = null; + + /** + * Default error handler (callback) for this object, if error mode is + * PEAR_ERROR_CALLBACK. + * + * @var string + * @access private + */ + var $_default_error_handler = ''; + + /** + * Which class to use for error objects. + * + * @var string + * @access private + */ + var $_error_class = 'PEAR_Error'; + + /** + * An array of expected errors. + * + * @var array + * @access private + */ + var $_expected_errors = array(); + + // }}} + + // {{{ constructor + + /** + * Constructor. Registers this object in + * $_PEAR_destructor_object_list for destructor emulation if a + * destructor object exists. + * + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. + * @access public + * @return void + */ + function PEAR($error_class = null) + { + $classname = strtolower(get_class($this)); + if ($this->_debug) { + print "PEAR constructor called, class=$classname\n"; + } + if ($error_class !== null) { + $this->_error_class = $error_class; + } + while ($classname && strcasecmp($classname, "pear")) { + $destructor = "_$classname"; + if (method_exists($this, $destructor)) { + global $_PEAR_destructor_object_list; + $_PEAR_destructor_object_list[] = &$this; + static $registered = false; + if (!$registered) { + register_shutdown_function("_PEAR_call_destructors"); + $registered = true; + } + break; + } else { + $classname = get_parent_class($classname); + } + } + } + + // }}} + // {{{ destructor + + /** + * Destructor (the emulated type of...). Does nothing right now, + * but is included for forward compatibility, so subclass + * destructors should always call it. + * + * See the note in the class desciption about output from + * destructors. + * + * @access public + * @return void + */ + function _PEAR() { + if ($this->_debug) { + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + } + } + + // }}} + // {{{ getStaticProperty() + + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + function &getStaticProperty($class, $var) + { + static $properties; + return $properties[$class][$var]; + } + + // }}} + // {{{ registerShutdownFunc() + + /** + * Use this function to register a shutdown method for static + * classes. + * + * @access public + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * @return void + */ + function registerShutdownFunc($func, $args = array()) + { + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); + } + + // }}} + // {{{ isError() + + /** + * Tell whether a value is a PEAR error. + * + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code + * @access public + * @return bool true if parameter is an error + */ + function isError($data, $code = null) + { + if (is_a($data, 'PEAR_Error')) { + if (is_null($code)) { + return true; + } elseif (is_string($code)) { + return $data->getMessage() == $code; + } else { + return $data->getCode() == $code; + } + } + return false; + } + + // }}} + // {{{ setErrorHandling() + + /** + * Sets how errors generated by this object should be handled. + * Can be invoked both in objects and statically. If called + * statically, setErrorHandling sets the default behaviour for all + * PEAR objects. If called in an object, setErrorHandling sets + * the default behaviour for that object. + * + * @param int $mode + * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. + * + * @param mixed $options + * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one + * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * + * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected + * to be the callback function or method. A callback + * function is a string with the name of the function, a + * callback method is an array of two elements: the element + * at index 0 is the object, and the element at index 1 is + * the name of the method to call in the object. + * + * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is + * a printf format string used when printing the error + * message. + * + * @access public + * @return void + * @see PEAR_ERROR_RETURN + * @see PEAR_ERROR_PRINT + * @see PEAR_ERROR_TRIGGER + * @see PEAR_ERROR_DIE + * @see PEAR_ERROR_CALLBACK + * @see PEAR_ERROR_EXCEPTION + * + * @since PHP 4.0.5 + */ + + function setErrorHandling($mode = null, $options = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + $setmode = &$this->_default_error_mode; + $setoptions = &$this->_default_error_options; + } else { + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + } + + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + } + + // }}} + // {{{ expectError() + + /** + * This method is used to tell which errors you expect to get. + * Expected errors are always returned with error mode + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, + * and this method pushes a new element onto it. The list of + * expected errors are in effect until they are popped off the + * stack with the popExpect() method. + * + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect + * + * @return int the new depth of the "expected errors" stack + * @access public + */ + function expectError($code = '*') + { + if (is_array($code)) { + array_push($this->_expected_errors, $code); + } else { + array_push($this->_expected_errors, array($code)); + } + return sizeof($this->_expected_errors); + } + + // }}} + // {{{ popExpect() + + /** + * This method pops one element off the expected error codes + * stack. + * + * @return array the list of error codes that were popped + */ + function popExpect() + { + return array_pop($this->_expected_errors); + } + + // }}} + // {{{ _checkDelExpect() + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + + foreach ($this->_expected_errors AS $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + return $deleted; + } + + // }}} + // {{{ delExpect() + + /** + * This method deletes all occurences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; + // we walk through it trying to unset all + // values + foreach($error_code as $key => $error) { + if ($this->_checkDelExpect($error)) { + $deleted = true; + } else { + $deleted = false; + } + } + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } else { + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + } else { + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + } + + // }}} + // {{{ raiseError() + + /** + * This method is a wrapper that returns an instance of the + * configured error class with this object's default error + * handling applied. If the $mode and $options parameters are not + * specified, the object's defaults are used. + * + * @param mixed $message a text error message or a PEAR error object + * + * @param int $code a numeric error code (it is up to your class + * to define these if you want to use codes) + * + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. + * + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter + * specifies the PHP-internal error level (one of + * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * If $mode is PEAR_ERROR_CALLBACK, this + * parameter specifies the callback function or + * method. In other error modes this parameter + * is ignored. + * + * @param string $userinfo If you need to pass along for example debug + * information, this parameter is meant for that. + * + * @param string $error_class The returned error object will be + * instantiated from this class, if specified. + * + * @param bool $skipmsg If true, raiseError will only pass error codes, + * the error message parameter will be dropped. + * + * @access public + * @return object a PEAR error object + * @see PEAR::setErrorHandling + * @since PHP 4.0.5 + */ + function raiseError($message = null, + $code = null, + $mode = null, + $options = null, + $userinfo = null, + $error_class = null, + $skipmsg = false) + { + // The error is yet a PEAR error object + if (is_object($message)) { + $code = $message->getCode(); + $userinfo = $message->getUserInfo(); + $error_class = $message->getType(); + $message->error_message_prefix = ''; + $message = $message->getMessage(); + } + + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { + if ($exp[0] == "*" || + (is_int(reset($exp)) && in_array($code, $exp)) || + (is_string(reset($exp)) && in_array($message, $exp))) { + $mode = PEAR_ERROR_RETURN; + } + } + // No mode given, try global ones + if ($mode === null) { + // Class error handler + if (isset($this) && isset($this->_default_error_mode)) { + $mode = $this->_default_error_mode; + $options = $this->_default_error_options; + // Global error handler + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { + $mode = $GLOBALS['_PEAR_default_error_mode']; + $options = $GLOBALS['_PEAR_default_error_options']; + } + } + + if ($error_class !== null) { + $ec = $error_class; + } elseif (isset($this) && isset($this->_error_class)) { + $ec = $this->_error_class; + } else { + $ec = 'PEAR_Error'; + } + if ($skipmsg) { + return new $ec($code, $mode, $options, $userinfo); + } else { + return new $ec($message, $code, $mode, $options, $userinfo); + } + } + + // }}} + // {{{ throwError() + + /** + * Simpler form of raiseError with fewer options. In most cases + * message, code and userinfo are enough. + * + * @param string $message + * + */ + function throwError($message = null, + $code = null, + $userinfo = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + return $this->raiseError($message, $code, null, null, $userinfo); + } else { + return PEAR::raiseError($message, $code, null, null, $userinfo); + } + } + + // }}} + function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + + // {{{ pushErrorHandling() + + /** + * Push a new error handler on top of the error handler options stack. With this + * you can easily override the actual error handler for some code and restore + * it later with popErrorHandling. + * + * @param mixed $mode (same as setErrorHandling) + * @param mixed $options (same as setErrorHandling) + * + * @return bool Always true + * + * @see PEAR::setErrorHandling + */ + function pushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + if (isset($this) && is_a($this, 'PEAR')) { + $def_mode = &$this->_default_error_mode; + $def_options = &$this->_default_error_options; + } else { + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + } + $stack[] = array($def_mode, $def_options); + + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + $stack[] = array($mode, $options); + return true; + } + + // }}} + // {{{ popErrorHandling() + + /** + * Pop the last error handler used + * + * @return bool Always true + * + * @see PEAR::pushErrorHandling + */ + function popErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + return true; + } + + // }}} + // {{{ loadExtension() + + /** + * OS independant PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + function loadExtension($ext) + { + if (!extension_loaded($ext)) { + // if either returns true dl() will produce a FATAL error, stop that + if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { + return false; + } + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + } + return true; + } + + // }}} +} + +// {{{ _PEAR_call_destructors() + +function _PEAR_call_destructors() +{ + global $_PEAR_destructor_object_list; + if (is_array($_PEAR_destructor_object_list) && + sizeof($_PEAR_destructor_object_list)) + { + reset($_PEAR_destructor_object_list); + if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } + while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + $classname = get_class($objref); + while ($classname) { + $destructor = "_$classname"; + if (method_exists($objref, $destructor)) { + $objref->$destructor(); + break; + } else { + $classname = get_parent_class($classname); + } + } + } + // Empty the object list to ensure that destructors are + // not called more than once. + $_PEAR_destructor_object_list = array(); + } + + // Now call the shutdown functions + if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { + call_user_func_array($value[0], $value[1]); + } + } +} + +// }}} + +class PEAR_Error +{ + // {{{ properties + + var $error_message_prefix = ''; + var $mode = PEAR_ERROR_RETURN; + var $level = E_USER_NOTICE; + var $code = -1; + var $message = ''; + var $userinfo = ''; + var $backtrace = null; + + // }}} + // {{{ constructor + + /** + * PEAR_Error constructor + * + * @param string $message message + * + * @param int $code (optional) error code + * + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION + * + * @param mixed $options (optional) error level, _OR_ in the case of + * PEAR_ERROR_CALLBACK, the callback function or object/method + * tuple. + * + * @param string $userinfo (optional) additional user/debug info + * + * @access public + * + */ + function PEAR_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + if ($mode === null) { + $mode = PEAR_ERROR_RETURN; + } + $this->message = $message; + $this->code = $code; + $this->mode = $mode; + $this->userinfo = $userinfo; + if (function_exists("debug_backtrace")) { + if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { + $this->backtrace = debug_backtrace(); + } + } + if ($mode & PEAR_ERROR_CALLBACK) { + $this->level = E_USER_NOTICE; + $this->callback = $options; + } else { + if ($options === null) { + $options = E_USER_NOTICE; + } + $this->level = $options; + $this->callback = null; + } + if ($this->mode & PEAR_ERROR_PRINT) { + if (is_null($options) || is_int($options)) { + $format = "%s"; + } else { + $format = $options; + } + printf($format, $this->getMessage()); + } + if ($this->mode & PEAR_ERROR_TRIGGER) { + trigger_error($this->getMessage(), $this->level); + } + if ($this->mode & PEAR_ERROR_DIE) { + $msg = $this->getMessage(); + if (is_null($options) || is_int($options)) { + $format = "%s"; + if (substr($msg, -1) != "\n") { + $msg .= "\n"; + } + } else { + $format = $options; + } + die(sprintf($format, $msg)); + } + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_callable($this->callback)) { + call_user_func($this->callback, $this); + } + } + if ($this->mode & PEAR_ERROR_EXCEPTION) { + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING); + eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);'); + } + } + + // }}} + // {{{ getMode() + + /** + * Get the error mode from an error object. + * + * @return int error mode + * @access public + */ + function getMode() { + return $this->mode; + } + + // }}} + // {{{ getCallback() + + /** + * Get the callback function/method from an error object. + * + * @return mixed callback function or object/method array + * @access public + */ + function getCallback() { + return $this->callback; + } + + // }}} + // {{{ getMessage() + + + /** + * Get the error message from an error object. + * + * @return string full error message + * @access public + */ + function getMessage() + { + return ($this->error_message_prefix . $this->message); + } + + + // }}} + // {{{ getCode() + + /** + * Get error code from an error object + * + * @return int error code + * @access public + */ + function getCode() + { + return $this->code; + } + + // }}} + // {{{ getType() + + /** + * Get the name of this error/exception. + * + * @return string error/exception name (type) + * @access public + */ + function getType() + { + return get_class($this); + } + + // }}} + // {{{ getUserInfo() + + /** + * Get additional user-supplied information. + * + * @return string user-supplied information + * @access public + */ + function getUserInfo() + { + return $this->userinfo; + } + + // }}} + // {{{ getDebugInfo() + + /** + * Get additional debug information supplied by the application. + * + * @return string debug information + * @access public + */ + function getDebugInfo() + { + return $this->getUserInfo(); + } + + // }}} + // {{{ getBacktrace() + + /** + * Get the call backtrace from where the error was generated. + * Supported with PHP 4.3.0 or newer. + * + * @param int $frame (optional) what frame to fetch + * @return array Backtrace, or NULL if not available. + * @access public + */ + function getBacktrace($frame = null) + { + if ($frame === null) { + return $this->backtrace; + } + return $this->backtrace[$frame]; + } + + // }}} + // {{{ addUserInfo() + + function addUserInfo($info) + { + if (empty($this->userinfo)) { + $this->userinfo = $info; + } else { + $this->userinfo .= " ** $info"; + } + } + + // }}} + // {{{ toString() + + /** + * Make a string representation of this object. + * + * @return string a string with an object summary + * @access public + */ + function toString() { + $modes = array(); + $levels = array(E_USER_NOTICE => 'notice', + E_USER_WARNING => 'warning', + E_USER_ERROR => 'error'); + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_array($this->callback)) { + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . + $this->callback[1]; + } else { + $callback = $this->callback; + } + return sprintf('[%s: message="%s" code=%d mode=callback '. + 'callback=%s prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + $callback, $this->error_message_prefix, + $this->userinfo); + } + if ($this->mode & PEAR_ERROR_PRINT) { + $modes[] = 'print'; + } + if ($this->mode & PEAR_ERROR_TRIGGER) { + $modes[] = 'trigger'; + } + if ($this->mode & PEAR_ERROR_DIE) { + $modes[] = 'die'; + } + if ($this->mode & PEAR_ERROR_RETURN) { + $modes[] = 'return'; + } + return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. + 'prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + implode("|", $modes), $levels[$this->level], + $this->error_message_prefix, + $this->userinfo); + } + + // }}} +} + +/* + * Local Variables: + * mode: php + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ +?> diff --git a/gulliver/thirdparty/pear/PEAR/Autoloader.php b/gulliver/thirdparty/pear/PEAR/Autoloader.php new file mode 100644 index 000000000..711a71896 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Autoloader.php @@ -0,0 +1,186 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Autoloader.php,v 1.6 2003/03/18 12:06:06 ssb Exp $ + +if (!extension_loaded("overload")) { + // die hard without ext/overload + die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader"); +} + +require_once "PEAR.php"; + +/** + * This class is for objects where you want to separate the code for + * some methods into separate classes. This is useful if you have a + * class with not-frequently-used methods that contain lots of code + * that you would like to avoid always parsing. + * + * The PEAR_Autoloader class provides autoloading and aggregation. + * The autoloading lets you set up in which classes the separated + * methods are found. Aggregation is the technique used to import new + * methods, an instance of each class providing separated methods is + * stored and called every time the aggregated method is called. + * + * @author Stig Sæther Bakken + */ +class PEAR_Autoloader extends PEAR +{ + /** + * Map of methods and classes where they are defined + * + * @var array + * + * @access private + */ + var $_autoload_map = array(); + + /** + * Map of methods and aggregate objects + * + * @var array + * + * @access private + */ + var $_method_map = array(); + + /** + * Add one or more autoload entries. + * + * @param string $method which method to autoload + * + * @param string $classname (optional) which class to find the method in. + * If the $method parameter is an array, this + * parameter may be omitted (and will be ignored + * if not), and the $method parameter will be + * treated as an associative array with method + * names as keys and class names as values. + * + * @return void + * + * @access public + */ + function addAutoload($method, $classname = null) + { + if (is_array($method)) { + $this->_autoload_map = array_merge($this->_autoload_map, $method); + } else { + $this->_autoload_map[$method] = $classname; + } + } + + /** + * Remove an autoload entry. + * + * @param string $method which method to remove the autoload entry for + * + * @return bool TRUE if an entry was removed, FALSE if not + * + * @access public + */ + function removeAutoload($method) + { + $ok = isset($this->_autoload_map[$method]); + unset($this->_autoload_map[$method]); + return $ok; + } + + /** + * Add an aggregate object to this object. If the specified class + * is not defined, loading it will be attempted following PEAR's + * file naming scheme. All the methods in the class will be + * aggregated, except private ones (name starting with an + * underscore) and constructors. + * + * @param string $classname what class to instantiate for the object. + * + * @return void + * + * @access public + */ + function addAggregateObject($classname) + { + $classname = strtolower($classname); + if (!class_exists($classname)) { + $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname); + include_once $include_file; + } + $obj =& new $classname; + $methods = get_class_methods($classname); + foreach ($methods as $method) { + // don't import priviate methods and constructors + if ($method{0} != '_' && $method != $classname) { + $this->_method_map[$method] = $obj; + } + } + } + + /** + * Remove an aggregate object. + * + * @param string $classname the class of the object to remove + * + * @return bool TRUE if an object was removed, FALSE if not + * + * @access public + */ + function removeAggregateObject($classname) + { + $ok = false; + $classname = strtolower($classname); + reset($this->_method_map); + while (list($method, $obj) = each($this->_method_map)) { + if (get_class($obj) == $classname) { + unset($this->_method_map[$method]); + $ok = true; + } + } + return $ok; + } + + /** + * Overloaded object call handler, called each time an + * undefined/aggregated method is invoked. This method repeats + * the call in the right aggregate object and passes on the return + * value. + * + * @param string $method which method that was called + * + * @param string $args An array of the parameters passed in the + * original call + * + * @return mixed The return value from the aggregated method, or a PEAR + * error if the called method was unknown. + */ + function __call($method, $args, &$retval) + { + if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) { + $this->addAggregateObject($this->_autoload_map[$method]); + } + if (isset($this->_method_map[$method])) { + $retval = call_user_func_array(array($this->_method_map[$method], $method), $args); + return true; + } + return false; + } +} + +overload("PEAR_Autoloader"); + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Builder.php b/gulliver/thirdparty/pear/PEAR/Builder.php new file mode 100644 index 000000000..9e3ab3411 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Builder.php @@ -0,0 +1,383 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Builder.php,v 1.10 2003/03/21 07:57:27 ssb Exp $ + +require_once 'PEAR/Common.php'; + +/** + * Class to handle building (compiling) extensions. + * + * @author Stig Sæther Bakken + */ +class PEAR_Builder extends PEAR_Common +{ + // {{{ properties + + var $php_api_version = 0; + var $zend_module_api_no = 0; + var $zend_extension_api_no = 0; + + var $extensions_built = array(); + + var $current_callback = null; + + // used for msdev builds + var $_lastline = null; + var $_firstline = null; + // }}} + // {{{ constructor + + /** + * PEAR_Builder constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function PEAR_Builder(&$ui) + { + parent::PEAR_Common(); + $this->setFrontendObject($ui); + } + + // }}} + + // {{{ _build_win32() + + /** + * Build an extension from source on windows. + * requires msdev + */ + function _build_win32($descfile, $callback = null) + { + if (PEAR::isError($info = $this->infoFromDescriptionFile($descfile))) { + return $info; + } + $dir = dirname($descfile); + $old_cwd = getcwd(); + + if (!@chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } + $this->log(2, "building in $dir"); + + $dsp = $info['package'].'.dsp'; + if (!@is_file("$dir/$dsp")) { + return $this->raiseError("The DSP $dsp does not exist."); + } + // XXX TODO: make release build type configurable + $command = 'msdev '.$dsp.' /MAKE "'.$info['package']. ' - Release"'; + + $this->current_callback = $callback; + $err = $this->_runCommand($command, array(&$this, 'msdevCallback')); + if (PEAR::isError($err)) { + return $err; + } + + // figure out the build platform and type + $platform = 'Win32'; + $buildtype = 'Release'; + if (preg_match('/.*?'.$info['package'].'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) { + $platform = $matches[1]; + $buildtype = $matches[2]; + } + + if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/',$this->_lastline,$matches)) { + if ($matches[2]) { + // there were errors in the build + return $this->raiseError("There were errors during compilation."); + } + $out = $matches[1]; + } else { + return $this->raiseError("Did not understand the completion status returned from msdev.exe."); + } + + // msdev doesn't tell us the output directory :/ + // open the dsp, find /out and use that directory + $dsptext = join(file($dsp),''); + + // this regex depends on the build platform and type having been + // correctly identified above. + $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'. + $info['package'].'\s-\s'. + $platform.'\s'. + $buildtype.'").*?'. + '\/out:"(.*?)"/is'; + + if ($dsptext && preg_match($regex,$dsptext,$matches)) { + // what we get back is a relative path to the output file itself. + $outfile = realpath($matches[2]); + } else { + return $this->raiseError("Could not retrieve output information from $dsp."); + } + if (@copy($outfile, "$dir/$out")) { + $outfile = "$dir/$out"; + } + + $built_files[] = array( + 'file' => "$outfile", + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + + return $built_files; + } + // }}} + + // {{{ msdevCallback() + function msdevCallback($what, $data) + { + if (!$this->_firstline) + $this->_firstline = $data; + $this->_lastline = $data; + } + // }}} + + // {{{ build() + + /** + * Build an extension from source. Runs "phpize" in the source + * directory, but compiles in a temporary directory + * (/var/tmp/pear-build-USER/PACKAGE-VERSION). + * + * @param string $descfile path to XML package description file + * + * @param mixed $callback callback function used to report output, + * see PEAR_Builder::_runCommand for details + * + * @return array an array of associative arrays with built files, + * format: + * array( array( 'file' => '/path/to/ext.so', + * 'php_api' => YYYYMMDD, + * 'zend_mod_api' => YYYYMMDD, + * 'zend_ext_api' => YYYYMMDD ), + * ... ) + * + * @access public + * + * @see PEAR_Builder::_runCommand + * @see PEAR_Common::infoFromDescriptionFile + */ + function build($descfile, $callback = null) + { + if (PEAR_OS == "Windows") { + return $this->_build_win32($descfile,$callback); + } + if (PEAR_OS != 'Unix') { + return $this->raiseError("building extensions not supported on this platform"); + } + if (PEAR::isError($info = $this->infoFromDescriptionFile($descfile))) { + return $info; + } + $dir = dirname($descfile); + $old_cwd = getcwd(); + if (!@chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } + $vdir = "$info[package]-$info[version]"; + if (is_dir($vdir)) { + chdir($vdir); + } + $dir = getcwd(); + $this->log(2, "building in $dir"); + $this->current_callback = $callback; + $err = $this->_runCommand("phpize", array(&$this, 'phpizeCallback')); + if (PEAR::isError($err)) { + return $err; + } + if (!$err) { + return $this->raiseError("`phpize' failed"); + } + + // start of interactive part + $configure_command = "$dir/configure"; + if (isset($info['configure_options'])) { + foreach ($info['configure_options'] as $o) { + list($r) = $this->ui->userDialog('build', + array($o['prompt']), + array('text'), + array(@$o['default'])); + if (substr($o['name'], 0, 5) == 'with-' && + ($r == 'yes' || $r == 'autodetect')) { + $configure_command .= " --$o[name]"; + } else { + $configure_command .= " --$o[name]=$r"; + } + } + } + // end of interactive part + + // make configurable + if(!$user=getenv('USER')){ + $user='defaultuser'; + } + $build_basedir = "/var/tmp/pear-build-$user"; + $build_dir = "$build_basedir/$info[package]-$info[version]"; + $this->log(1, "building in $build_dir"); + if (is_dir($build_dir)) { + System::rm("-rf $build_dir"); + } + if (!System::mkDir("-p $build_dir")) { + return $this->raiseError("could not create build dir: $build_dir"); + } + $this->addTempFile($build_dir); + if (getenv('MAKE')) { + $make_command = getenv('MAKE'); + } else { + $make_command = 'make'; + } + $to_run = array( + $configure_command, + $make_command, + ); + if (!@chdir($build_dir)) { + return $this->raiseError("could not chdir to $build_dir"); + } + foreach ($to_run as $cmd) { + $err = $this->_runCommand($cmd, $callback); + if (PEAR::isError($err)) { + chdir($old_cwd); + return $err; + } + if (!$err) { + chdir($old_cwd); + return $this->raiseError("`$cmd' failed"); + } + } + if (!($dp = opendir("modules"))) { + chdir($old_cwd); + return $this->raiseError("no `modules' directory found"); + } + $built_files = array(); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -3) == '.la') { + continue; + } + // harvest! + if (@copy("modules/$ent", "$dir/$ent")) { + $built_files[] = array( + 'file' => "$dir/$ent", + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + + $this->log(1, "$ent copied to $dir/$ent"); + } else { + chdir($old_cwd); + return $this->raiseError("failed copying $ent to $dir"); + } + } + closedir($dp); + chdir($old_cwd); + return $built_files; + } + + // }}} + // {{{ phpizeCallback() + + /** + * Message callback function used when running the "phpize" + * program. Extracts the API numbers used. Ignores other message + * types than "cmdoutput". + * + * @param string $what the type of message + * @param mixed $data the message + * + * @return void + * + * @access public + */ + function phpizeCallback($what, $data) + { + if ($what != 'cmdoutput') { + return; + } + $this->log(3, rtrim($data)); + if (preg_match('/You should update your .aclocal.m4/', $data)) { + return; + } + $matches = array(); + if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) { + $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1])); + $apino = (int)$matches[2]; + if (isset($this->$member)) { + $this->$member = $apino; + $msg = sprintf("%-22s : %d", $matches[1], $apino); + $this->log(1, $msg); + } + } + } + + // }}} + // {{{ _runCommand() + + /** + * Run an external command, using a message callback to report + * output. The command will be run through popen and output is + * reported for every line with a "cmdoutput" message with the + * line string, including newlines, as payload. + * + * @param string $command the command to run + * + * @param mixed $callback (optional) function to use as message + * callback + * + * @return bool whether the command was successful (exit code 0 + * means success, any other means failure) + * + * @access private + */ + function _runCommand($command, $callback = null) + { + $this->log(1, "running: $command"); + $pp = @popen("$command 2>&1", "r"); + if (!$pp) { + return $this->raiseError("failed to run `$command'"); + } + while ($line = fgets($pp, 1024)) { + if ($callback) { + call_user_func($callback, 'cmdoutput', $line); + } else { + $this->log(2, rtrim($line)); + } + } + $exitcode = @pclose($pp); + return ($exitcode == 0); + } + + // }}} + // {{{ log() + + function log($level, $msg) + { + if ($this->current_callback) { + if ($this->debug >= $level) { + call_user_func($this->current_callback, 'output', $msg); + } + return; + } + return PEAR_Common::log($level, $msg); + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Command.php b/gulliver/thirdparty/pear/PEAR/Command.php new file mode 100644 index 000000000..ba78c9136 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command.php @@ -0,0 +1,322 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Command.php,v 1.18 2003/03/18 12:06:06 ssb Exp $ + + +require_once "PEAR.php"; + +/** + * List of commands and what classes they are implemented in. + * @var array command => implementing class + */ +$GLOBALS['_PEAR_Command_commandlist'] = array(); + +/** + * List of shortcuts to common commands. + * @var array shortcut => command + */ +$GLOBALS['_PEAR_Command_shortcuts'] = array(); + +/** + * Array of command objects + * @var array class => object + */ +$GLOBALS['_PEAR_Command_objects'] = array(); + +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_Frontend_CLI'; + +/** + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_Command_uiobject'] = null; + +/** + * PEAR command class, a simple factory class for administrative + * commands. + * + * How to implement command classes: + * + * - The class must be called PEAR_Command_Nnn, installed in the + * "PEAR/Common" subdir, with a method called getCommands() that + * returns an array of the commands implemented by the class (see + * PEAR/Command/Install.php for an example). + * + * - The class must implement a run() function that is called with three + * params: + * + * (string) command name + * (array) assoc array with options, freely defined by each + * command, for example: + * array('force' => true) + * (array) list of the other parameters + * + * The run() function returns a PEAR_CommandResponse object. Use + * these methods to get information: + * + * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) + * *_PARTIAL means that you need to issue at least + * one more command to complete the operation + * (used for example for validation steps). + * + * string getMessage() Returns a message for the user. Remember, + * no HTML or other interface-specific markup. + * + * If something unexpected happens, run() returns a PEAR error. + * + * - DON'T OUTPUT ANYTHING! Return text for output instead. + * + * - DON'T USE HTML! The text you return will be used from both Gtk, + * web and command-line interfaces, so for now, keep everything to + * plain text. + * + * - DON'T USE EXIT OR DIE! Always use pear errors. From static + * classes do PEAR::raiseError(), from other classes do + * $this->raiseError(). + */ +class PEAR_Command +{ + /** + * Get the right object for executing a command. + * + * @param string $command The name of the command + * @param object $config Instance of PEAR_Config object + * + * @return object the command object or a PEAR error + * + * @access public + */ + function factory($command, &$config) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + $class = @$GLOBALS['_PEAR_Command_commandlist'][$command]; + if (empty($class)) { + return PEAR::raiseError("unknown command `$command'"); + } + $ui = PEAR_Command::getFrontendObject(); + $obj = &new $class($ui, $config); + return $obj; + } + + /** + * Get instance of frontend object. + * + * @return object + */ + function &getFrontendObject() + { + if (empty($GLOBALS['_PEAR_Command_uiobject'])) { + $GLOBALS['_PEAR_Command_uiobject'] = &new $GLOBALS['_PEAR_Command_uiclass']; + } + return $GLOBALS['_PEAR_Command_uiobject']; + } + + /** + * Load current frontend class. + * + * @param string $uiclass Name of class implementing the frontend + * + * @return object the frontend object, or a PEAR error + */ + function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_Command_uiobject']) && + strtolower($uiclass) == get_class($GLOBALS['_PEAR_Command_uiobject'])) { + return; + } + $file = str_replace('_', '/', $uiclass) . '.php'; + @include_once $file; + if (class_exists(strtolower($uiclass))) { + $obj = &new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (method_exists($obj, 'userConfirm')) { + $GLOBALS['_PEAR_Command_uiobject'] = &$obj; + $GLOBALS['_PEAR_Command_uiclass'] = $uiclass; + return $obj; + } else { + return PEAR::raiseError("not a frontend class: $uiclass"); + } + } + return PEAR::raiseError("no such class: $uiclass"); + } + + /** + * Set current frontend. + * + * @param string $uitype Name of the frontend type (for example "CLI") + * + * @return object the frontend object, or a PEAR error + */ + function setFrontendType($uitype) + { + $uiclass = 'PEAR_Frontend_' . $uitype; + return PEAR_Command::setFrontendClass($uiclass); + } + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * + * @param bool (optional) if FALSE (default), the new list of + * commands should replace the current one. If TRUE, + * new entries will be merged with old. + * + * @param string (optional) where (what directory) to look for + * classes, defaults to the Command subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * + * @access public + */ + function registerCommands($merge = false, $dir = null) + { + if ($dir === null) { + $dir = dirname(__FILE__) . '/Command'; + } + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerCommands: opendir($dir) failed"); + } + if (!$merge) { + $GLOBALS['_PEAR_Command_commandlist'] = array(); + } + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.php' || $entry == 'Common.php') { + continue; + } + $class = "PEAR_Command_".substr($entry, 0, -4); + $file = "$dir/$entry"; + include_once $file; + // List of commands + if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { + $GLOBALS['_PEAR_Command_objects'][$class] = &new $class($ui, $config); + } + $implements = $GLOBALS['_PEAR_Command_objects'][$class]->getCommands(); + foreach ($implements as $command => $desc) { + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; + $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc; + } + $shortcuts = $GLOBALS['_PEAR_Command_objects'][$class]->getShortcuts(); + foreach ($shortcuts as $shortcut => $command) { + $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; + } + } + return true; + } + + /** + * Get the list of currently supported commands, and what + * classes implement them. + * + * @return array command => implementing class + * + * @access public + */ + function getCommands() + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_commandlist']; + } + + /** + * Get the list of command shortcuts. + * + * @return array shortcut => command + * + * @access public + */ + function getShortcuts() + { + if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_shortcuts']; + } + + /** + * Compiles arguments for getopt. + * + * @param string $command command to get optstring for + * @param string $short_args (reference) short getopt format + * @param array $long_args (reference) long getopt format + * + * @return void + * + * @access public + */ + function getGetoptArgs($command, &$short_args, &$long_args) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + $class = @$GLOBALS['_PEAR_Command_commandlist'][$command]; + if (empty($class)) { + return null; + } + $obj = &$GLOBALS['_PEAR_Command_objects'][$class]; + return $obj->getGetoptArgs($command, $short_args, $long_args); + } + + /** + * Get description for a command. + * + * @param string $command Name of the command + * + * @return string command description + * + * @access public + */ + function getDescription($command) + { + return @$GLOBALS['_PEAR_Command_commanddesc'][$command]; + } + + /** + * Get help for command. + * + * @param string $command Name of the command to return help for + * + * @access public + */ + function getHelp($command) + { + $cmds = PEAR_Command::getCommands(); + if (isset($cmds[$command])) { + $class = $cmds[$command]; + return $GLOBALS['_PEAR_Command_objects'][$class]->getHelp($command); + } + return false; + } +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Command/Auth.php b/gulliver/thirdparty/pear/PEAR/Command/Auth.php new file mode 100644 index 000000000..ae25f9b3a --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Auth.php @@ -0,0 +1,155 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Auth.php,v 1.13 2003/03/18 12:06:07 ssb Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Remote.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Auth extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'login' => array( + 'summary' => 'Connects and authenticates to remote server', + 'shortcut' => 'li', + 'function' => 'doLogin', + 'options' => array(), + 'doc' => ' +Log in to the remote server. To use remote functions in the installer +that require any kind of privileges, you need to log in first. The +username and password you enter here will be stored in your per-user +PEAR configuration (~/.pearrc on Unix-like systems). After logging +in, your username and password will be sent along in subsequent +operations on the remote server.', + ), + 'logout' => array( + 'summary' => 'Logs out from the remote server', + 'shortcut' => 'lo', + 'function' => 'doLogout', + 'options' => array(), + 'doc' => ' +Logs out from the remote server. This command does not actually +connect to the remote server, it only deletes the stored username and +password from your user configuration.', + ) + + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Auth constructor. + * + * @access public + */ + function PEAR_Command_Auth(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doLogin() + + /** + * Execute the 'login' command. + * + * @param string $command command name + * + * @param array $options option_name => value + * + * @param array $params list of additional parameters + * + * @return bool TRUE on success, FALSE for unknown commands, or + * a PEAR error on failure + * + * @access public + */ + function doLogin($command, $options, $params) + { + $server = $this->config->get('master_server'); + $remote = new PEAR_Remote($this->config); + $username = $this->config->get('username'); + if (empty($username)) { + $username = @$_ENV['USER']; + } + $this->ui->outputData("Logging in to $server.", $command); + + list($username, $password) = $this->ui->userDialog( + $command, + array('Username', 'Password'), + array('text', 'password'), + array($username, '') + ); + $username = trim($username); + $password = trim($password); + + $this->config->set('username', $username); + $this->config->set('password', $password); + + $remote->expectError(401); + $ok = $remote->call('logintest'); + $remote->popExpect(); + if ($ok === true) { + $this->ui->outputData("Logged in.", $command); + $this->config->store(); + } else { + return $this->raiseError("Login failed!"); + } + + } + + // }}} + // {{{ doLogout() + + /** + * Execute the 'logout' command. + * + * @param string $command command name + * + * @param array $options option_name => value + * + * @param array $params list of additional parameters + * + * @return bool TRUE on success, FALSE for unknown commands, or + * a PEAR error on failure + * + * @access public + */ + function doLogout($command, $options, $params) + { + $server = $this->config->get('master_server'); + $this->ui->outputData("Logging out from $server.", $command); + $this->config->remove('username'); + $this->config->remove('password'); + $this->config->store(); + } + + // }}} +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/PEAR/Command/Build.php b/gulliver/thirdparty/pear/PEAR/Command/Build.php new file mode 100644 index 000000000..07dea6036 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Build.php @@ -0,0 +1,89 @@ + | +// | Tomas V.V.Cox | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Build.php,v 1.6 2003/03/18 12:06:07 ssb Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Builder.php"; + +/** + * PEAR commands for building extensions. + * + */ +class PEAR_Command_Build extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'build' => array( + 'summary' => 'Build an Extension From C Source', + 'function' => 'doBuild', + 'shortcut' => 'b', + 'options' => array(), + 'doc' => '[package.xml] +Builds one or more extensions contained in a package.' + ), + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Build constructor. + * + * @access public + */ + function PEAR_Command_Build(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doBuild() + + function doBuild($command, $options, $params) + { + if (sizeof($params) < 1) { + $params[0] = 'package.xml'; + } + $builder = &new PEAR_Builder($this->ui); + $this->verbose = $this->config->get('verbose'); + $err = $builder->build($params[0], array(&$this, 'buildCallback')); + if (PEAR::isError($err)) { + return $err; + } + return true; + } + + // }}} + // {{{ buildCallback() + + function buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->verbose > 1) || + ($what == 'output' && $this->verbose > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } + + // }}} +} diff --git a/gulliver/thirdparty/pear/PEAR/Command/Common.php b/gulliver/thirdparty/pear/PEAR/Command/Common.php new file mode 100644 index 000000000..430ad0356 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Common.php @@ -0,0 +1,249 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Common.php,v 1.22 2003/03/18 12:06:07 ssb Exp $ + +require_once "PEAR.php"; + +class PEAR_Command_Common extends PEAR +{ + // {{{ properties + + /** + * PEAR_Config object used to pass user system and configuration + * on when executing commands + * + * @var object + */ + var $config; + + /** + * User Interface object, for all interaction with the user. + * @var object + */ + var $ui; + + var $_deps_rel_trans = array( + 'lt' => '<', + 'le' => '<=', + 'eq' => '=', + 'ne' => '!=', + 'gt' => '>', + 'ge' => '>=', + 'has' => '==' + ); + + var $_deps_type_trans = array( + 'pkg' => 'package', + 'extension' => 'extension', + 'php' => 'PHP', + 'prog' => 'external program', + 'ldlib' => 'external library for linking', + 'rtlib' => 'external runtime library', + 'os' => 'operating system', + 'websrv' => 'web server', + 'sapi' => 'SAPI backend' + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Common constructor. + * + * @access public + */ + function PEAR_Command_Common(&$ui, &$config) + { + parent::PEAR(); + $this->config = &$config; + $this->ui = &$ui; + } + + // }}} + + // {{{ getCommands() + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + $ret[$command] = $this->commands[$command]['summary']; + } + return $ret; + } + + // }}} + // {{{ getShortcuts() + + /** + * Return a list of all the command shortcuts defined by this class. + * @return array shortcut => command + * @access public + */ + function getShortcuts() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + if (isset($this->commands[$command]['shortcut'])) { + $ret[$this->commands[$command]['shortcut']] = $command; + } + } + return $ret; + } + + // }}} + // {{{ getOptions() + + function getOptions($command) + { + return @$this->commands[$command]['options']; + } + + // }}} + // {{{ getGetoptArgs() + + function getGetoptArgs($command, &$short_args, &$long_args) + { + $short_args = ""; + $long_args = array(); + if (empty($this->commands[$command])) { + return; + } + reset($this->commands[$command]); + while (list($option, $info) = each($this->commands[$command]['options'])) { + $larg = $sarg = ''; + if (isset($info['arg'])) { + if ($info['arg']{0} == '(') { + $larg = '=='; + $sarg = '::'; + $arg = substr($info['arg'], 1, -1); + } else { + $larg = '='; + $sarg = ':'; + $arg = $info['arg']; + } + } + if (isset($info['shortopt'])) { + $short_args .= $info['shortopt'] . $sarg; + } + $long_args[] = $option . $larg; + } + } + + // }}} + // {{{ getHelp() + /** + * Returns the help message for the given command + * + * @param string $command The command + * @return mixed A fail string if the command does not have help or + * a two elements array containing [0]=>help string, + * [1]=> help string for the accepted cmd args + */ + function getHelp($command) + { + $config = &PEAR_Config::singleton(); + $help = @$this->commands[$command]['doc']; + if (empty($help)) { + // XXX (cox) Fallback to summary if there is no doc (show both?) + if (!$help = @$this->commands[$command]['summary']) { + return "No help for command \"$command\""; + } + } + if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) { + foreach($matches[0] as $k => $v) { + $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); + } + } + return array($help, $this->getHelpArgs($command)); + } + + // }}} + // {{{ getHelpArgs() + /** + * Returns the help for the accepted arguments of a command + * + * @param string $command + * @return string The help string + */ + function getHelpArgs($command) + { + if (isset($this->commands[$command]['options']) && + count($this->commands[$command]['options'])) + { + $help = "Options:\n"; + foreach ($this->commands[$command]['options'] as $k => $v) { + if (isset($v['arg'])) { + if ($v['arg']{0} == '(') { + $arg = substr($v['arg'], 1, -1); + $sapp = " [$arg]"; + $lapp = "[=$arg]"; + } else { + $sapp = " $v[arg]"; + $lapp = "=$v[arg]"; + } + } else { + $sapp = $lapp = ""; + } + if (isset($v['shortopt'])) { + $s = $v['shortopt']; + @$help .= " -$s$sapp, --$k$lapp\n"; + } else { + @$help .= " --$k$lapp\n"; + } + $p = " "; + $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); + $help .= " $doc\n"; + } + return $help; + } + return null; + } + + // }}} + // {{{ run() + + function run($command, $options, $params) + { + $func = @$this->commands[$command]['function']; + if (empty($func)) { + // look for shortcuts + foreach (array_keys($this->commands) as $cmd) { + if (@$this->commands[$cmd]['shortcut'] == $command) { + $command = $cmd; + $func = @$this->commands[$command]['function']; + if (empty($func)) { + return $this->raiseError("unknown command `$command'"); + } + break; + } + } + } + return $this->$func($command, $options, $params); + } + + // }}} +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/PEAR/Command/Config.php b/gulliver/thirdparty/pear/PEAR/Command/Config.php new file mode 100644 index 000000000..fdbaed270 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Config.php @@ -0,0 +1,225 @@ + | +// | Tomas V.V.Cox | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Config.php,v 1.24 2003/03/18 12:06:07 ssb Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Config extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'config-show' => array( + 'summary' => 'Show All Settings', + 'function' => 'doConfigShow', + 'shortcut' => 'csh', + 'options' => array(), + 'doc' => ' +Displays all configuration values. An optional argument +may be used to tell which configuration layer to display. Valid +configuration layers are "user", "system" and "default". +', + ), + 'config-get' => array( + 'summary' => 'Show One Setting', + 'function' => 'doConfigGet', + 'shortcut' => 'cg', + 'options' => array(), + 'doc' => ' [layer] +Displays the value of one configuration parameter. The +first argument is the name of the parameter, an optional second argument +may be used to tell which configuration layer to look in. Valid configuration +layers are "user", "system" and "default". If no layer is specified, a value +will be picked from the first layer that defines the parameter, in the order +just specified. +', + ), + 'config-set' => array( + 'summary' => 'Change Setting', + 'function' => 'doConfigSet', + 'shortcut' => 'cs', + 'options' => array(), + 'doc' => ' [layer] +Sets the value of one configuration parameter. The first argument is +the name of the parameter, the second argument is the new value. Some +parameters are subject to validation, and the command will fail with +an error message if the new value does not make sense. An optional +third argument may be used to specify in which layer to set the +configuration parameter. The default layer is "user". +', + ), + 'config-help' => array( + 'summary' => 'Show Information About Setting', + 'function' => 'doConfigHelp', + 'shortcut' => 'ch', + 'options' => array(), + 'doc' => '[parameter] +Displays help for a configuration parameter. Without arguments it +displays help for all configuration parameters. +', + ), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Config constructor. + * + * @access public + */ + function PEAR_Command_Config(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doConfigShow() + + function doConfigShow($command, $options, $params) + { + // $params[0] -> the layer + if ($error = $this->_checkLayer(@$params[0])) { + return $this->raiseError($error); + } + $keys = $this->config->getKeys(); + sort($keys); + $data = array('caption' => 'Configuration:'); + foreach ($keys as $key) { + $type = $this->config->getType($key); + $value = $this->config->get($key, @$params[0]); + if ($type == 'password' && $value) { + $value = '********'; + } + if ($value === false) { + $value = 'false'; + } elseif ($value === true) { + $value = 'true'; + } + $data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value); + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doConfigGet() + + function doConfigGet($command, $options, $params) + { + // $params[0] -> the parameter + // $params[1] -> the layer + if ($error = $this->_checkLayer(@$params[1])) { + return $this->raiseError($error); + } + if (sizeof($params) < 1 || sizeof($params) > 2) { + return $this->raiseError("config-get expects 1 or 2 parameters"); + } elseif (sizeof($params) == 1) { + $this->ui->outputData("$params[0]=" . $this->config->get($params[0]), $command); + } else { + $data = "$params[1].$params[0]=" .$this->config->get($params[0], $params[1]); + $this->ui->outputData($data, $command); + } + return true; + } + + // }}} + // {{{ doConfigSet() + + function doConfigSet($command, $options, $params) + { + // $param[0] -> a parameter to set + // $param[1] -> the value for the parameter + // $param[2] -> the layer + $failmsg = ''; + if (sizeof($params) < 2 || sizeof($params) > 3) { + $failmsg .= "config-set expects 2 or 3 parameters"; + return PEAR::raiseError($failmsg); + } + if ($error = $this->_checkLayer(@$params[2])) { + $failmsg .= $error; + return PEAR::raiseError($failmsg); + } + if (!call_user_func_array(array(&$this->config, 'set'), $params)) + { + $failmsg = "config-set (" . implode(", ", $params) . ") failed"; + } else { + $this->config->store(); + } + if ($failmsg) { + return $this->raiseError($failmsg); + } + return true; + } + + // }}} + // {{{ doConfigHelp() + + function doConfigHelp($command, $options, $params) + { + if (empty($params)) { + $params = $this->config->getKeys(); + } + $data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : ''); + $data['headline'] = array('Name', 'Type', 'Description'); + $data['border'] = true; + foreach ($params as $name) { + $type = $this->config->getType($name); + $docs = $this->config->getDocs($name); + if ($type == 'set') { + $docs = rtrim($docs) . "\nValid set: " . + implode(' ', $this->config->getSetValues($name)); + } + $data['data'][] = array($name, $type, $docs); + } + $this->ui->outputData($data, $command); + } + + // }}} + // {{{ _checkLayer() + + /** + * Checks if a layer is defined or not + * + * @param string $layer The layer to search for + * @return mixed False on no error or the error message + */ + function _checkLayer($layer = null) + { + if (!empty($layer) && $layer != 'default') { + $layers = $this->config->getLayers(); + if (!in_array($layer, $layers)) { + return " only the layers: \"" . implode('" or "', $layers) . "\" are supported"; + } + } + return false; + } + + // }}} +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/PEAR/Command/Install.php b/gulliver/thirdparty/pear/PEAR/Command/Install.php new file mode 100644 index 000000000..e4581aaba --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Install.php @@ -0,0 +1,302 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Install.php,v 1.42 2003/03/18 12:06:07 ssb Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Installer.php"; +require_once "Console/Getopt.php"; + +/** + * PEAR commands for installation or deinstallation/upgrading of + * packages. + * + */ +class PEAR_Command_Install extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'install' => array( + 'summary' => 'Install Package', + 'function' => 'doInstall', + 'shortcut' => 'i', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'will overwrite newer installed packages', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, install anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as installed', + ), + 'soft' => array( + 'shortopt' => 's', + 'doc' => 'soft install, fail silently, or upgrade if already installed', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => ' ... +Installs one or more PEAR packages. You can specify a package to +install in four ways: + +"Package-1.0.tgz" : installs from a local file + +"http://example.com/Package-1.0.tgz" : installs from +anywhere on the net. + +"package.xml" : installs the package described in +package.xml. Useful for testing, or for wrapping a PEAR package in +another package manager such as RPM. + +"Package" : queries your configured server +({config master_server}) and downloads the newest package with +the preferred quality/state ({config preferred_state}). + +More than one package may be specified at once. It is ok to mix these +four ways of specifying packages. +'), + 'upgrade' => array( + 'summary' => 'Upgrade Package', + 'function' => 'doInstall', + 'shortcut' => 'up', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'overwrite newer installed packages', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => ' ... +Upgrades one or more PEAR packages. See documentation for the +"install" command for ways to specify a package. + +When upgrading, your package will be updated if the provided new +package has a higher version number (use the -f option if you need to +upgrade anyway). + +More than one package may be specified at once. +'), + 'upgrade-all' => array( + 'summary' => 'Upgrade All Packages', + 'function' => 'doInstall', + 'shortcut' => 'ua', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => ' +Upgrades all packages that have a newer release available. Upgrades are +done only if there is a release available of the state specified in +"preferred_state" (currently {config preferred_state}), or a state considered +more stable. +'), + 'uninstall' => array( + 'summary' => 'Un-install Package', + 'function' => 'doUninstall', + 'shortcut' => 'un', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, uninstall anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not remove files, only register the packages as not installed', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => ' ... +Uninstalls one or more PEAR packages. More than one package may be +specified at once. +'), + + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Install constructor. + * + * @access public + */ + function PEAR_Command_Install(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doInstall() + + function doInstall($command, $options, $params) + { + if (empty($this->installer)) { + $this->installer = &new PEAR_Installer($this->ui); + } + if ($command == 'upgrade') { + $options[$command] = true; + } + if ($command == 'upgrade-all') { + include_once "PEAR/Remote.php"; + $options['upgrade'] = true; + $remote = new PEAR_Remote($this->config); + $state = $this->config->get('preferred_state'); + if (empty($state) || $state == 'any') { + $latest = $remote->call("package.listLatestReleases"); + } else { + $latest = $remote->call("package.listLatestReleases", $state); + } + if (PEAR::isError($latest)) { + return $latest; + } + $reg = new PEAR_Registry($this->config->get('php_dir')); + $installed = array_flip($reg->listPackages()); + $params = array(); + foreach ($latest as $package => $info) { + if (!isset($installed[$package])) { + // skip packages we don't have installed + continue; + } + $inst_version = $reg->packageInfo($package, 'version'); + if (version_compare("$info[version]", "$inst_version", "le")) { + // installed version is up-to-date + continue; + } + $params[] = $package; + $this->ui->outputData("will upgrade $package", $command); + } + } + foreach ($params as $pkg) { + $bn = basename($pkg); + $info = $this->installer->install($pkg, $options, $this->config); + if (is_array($info)) { + if ($this->config->get('verbose') > 0) { + $label = "$info[package] $info[version]"; + $out = array('data' => "$command ok: $label"); + if (isset($info['release_warnings'])) { + $out['release_warnings'] = $info['release_warnings']; + } + $this->ui->outputData($out, $command); + } + } else { + return $this->raiseError("$command failed"); + } + } + return true; + } + + // }}} + // {{{ doUninstall() + + function doUninstall($command, $options, $params) + { + if (empty($this->installer)) { + $this->installer = &new PEAR_Installer($this->ui); + } + if (sizeof($params) < 1) { + return $this->raiseError("Please supply the package(s) you want to uninstall"); + } + foreach ($params as $pkg) { + if ($this->installer->uninstall($pkg, $options)) { + if ($this->config->get('verbose') > 0) { + $this->ui->outputData("uninstall ok: $pkg", $command); + } + } else { + return $this->raiseError("uninstall failed: $pkg"); + } + } + return true; + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Command/Mirror.php b/gulliver/thirdparty/pear/PEAR/Command/Mirror.php new file mode 100644 index 000000000..226ed0892 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Mirror.php @@ -0,0 +1,99 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Mirror.php,v 1.1 2003/05/05 07:07:51 alexmerz Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Command.php"; +require_once "PEAR/Remote.php"; +require_once "PEAR.php"; + +/** + * PEAR commands for providing file mirrors + * + */ +class PEAR_Command_Mirror extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'download-all' => array( + 'summary' => 'Downloads each avaible Package from master_server', + 'function' => 'doDownloadAll', + 'shortcut' => 'da', + 'options' => array(), + 'doc' => ' + Request a list of avaible Packages from the Package-Server + (master_server) and downloads them to current working dir' + ), + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Mirror constructor. + * + * @access public + * @param object PEAR_Frontend a reference to an frontend + * @param object PEAR_Config a reference to the configuration data + */ + function PEAR_Command_Mirror(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doDownloadAll() + /** + * retrieves a list of avaible Packages from master server + * and downloads them + * + * @access public + * @param string $command the command + * @param array $options the command options before the command + * @param array $params the stuff after the command name + * @return bool true if succesful + * @throw PEAR_Error + */ + function doDownloadAll($command, $options, $params) + { + $this->config->set("php_dir", "."); + $remote = &new PEAR_Remote($this->config); + $remoteInfo = $remote->call("package.listAll"); + if(PEAR::isError($remoteInfo)) { + return $remoteInfo; + } + $cmd = &PEAR_Command::factory("download", $this->config); + if(PEAR::isError($cmd)) { + return $cmd; + } + foreach($remoteInfo as $pkgn=>$pkg) { + // error handling not neccesary, because + // already done by the download command + $cmd->run("download", array(), array($pkgn)); + } + + return true; + } + + // }}} +} diff --git a/gulliver/thirdparty/pear/PEAR/Command/Package.php b/gulliver/thirdparty/pear/PEAR/Command/Package.php new file mode 100644 index 000000000..544452e4e --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Package.php @@ -0,0 +1,660 @@ + | +// | Martin Jansen | +// +----------------------------------------------------------------------+ +// +// $Id: Package.php,v 1.50 2003/03/18 12:06:07 ssb Exp $ + +require_once 'PEAR/Common.php'; +require_once 'PEAR/Command/Common.php'; + +class PEAR_Command_Package extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'package' => array( + 'summary' => 'Build Package', + 'function' => 'doPackage', + 'shortcut' => 'p', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' + ), + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', + ), + ), + 'doc' => '[descfile] +Creates a PEAR package from its description file (usually called +package.xml). +' + ), + 'package-validate' => array( + 'summary' => 'Validate Package Consistency', + 'function' => 'doPackageValidate', + 'shortcut' => 'pv', + 'options' => array(), + 'doc' => ' +', + ), + 'cvsdiff' => array( + 'summary' => 'Run a "cvs diff" for all files in a package', + 'function' => 'doCvsDiff', + 'shortcut' => 'cd', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'date' => array( + 'shortopt' => 'D', + 'doc' => 'Diff against revision of DATE', + 'arg' => 'DATE', + ), + 'release' => array( + 'shortopt' => 'R', + 'doc' => 'Diff against tag for package release REL', + 'arg' => 'REL', + ), + 'revision' => array( + 'shortopt' => 'r', + 'doc' => 'Diff against revision REV', + 'arg' => 'REV', + ), + 'context' => array( + 'shortopt' => 'c', + 'doc' => 'Generate context diff', + ), + 'unified' => array( + 'shortopt' => 'u', + 'doc' => 'Generate unified diff', + ), + 'ignore-case' => array( + 'shortopt' => 'i', + 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', + ), + 'ignore-whitespace' => array( + 'shortopt' => 'b', + 'doc' => 'Ignore changes in amount of white space', + ), + 'ignore-blank-lines' => array( + 'shortopt' => 'B', + 'doc' => 'Ignore changes that insert or delete blank lines', + ), + 'brief' => array( + 'doc' => 'Report only whether the files differ, no details', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. +', + ), + 'cvstag' => array( + 'summary' => 'Set CVS Release Tag', + 'function' => 'doCvsTag', + 'shortcut' => 'ct', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. +', + ), + 'run-tests' => array( + 'summary' => 'Run Regression Tests', + 'function' => 'doRunTests', + 'shortcut' => 'rt', + 'options' => array(), + 'doc' => '[testfile|dir ...] +Run regression tests with PHP\'s regression testing script (run-tests.php).', + ), + 'package-dependencies' => array( + 'summary' => 'Show package dependencies', + 'function' => 'doPackageDependencies', + 'shortcut' => 'pd', + 'options' => array(), + 'doc' => ' +List all depencies the package has.' + ), + 'sign' => array( + 'summary' => 'Sign a package distribution file', + 'function' => 'doSign', + 'shortcut' => 'si', + 'options' => array(), + 'doc' => ' +Signs a package distribution (.tar or .tgz) file with GnuPG.', + ), + 'makerpm' => array( + 'summary' => 'Builds an RPM spec file from a PEAR package', + 'function' => 'doMakeRPM', + 'shortcut' => 'rpm', + 'options' => array( + 'spec-template' => array( + 'shortopt' => 't', + 'arg' => 'FILE', + 'doc' => 'Use FILE as RPM spec file template' + ), + 'rpm-pkgname' => array( + 'shortopt' => 'p', + 'arg' => 'FORMAT', + 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced +by the PEAR package name, defaults to "PEAR::%s".', + ), + ), + 'doc' => ' + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm +', + ), + ); + + var $output; + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Package constructor. + * + * @access public + */ + function PEAR_Command_Package(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ _displayValidationResults() + + function _displayValidationResults($err, $warn, $strict = false) + { + foreach ($err as $e) { + $this->output .= "Error: $e\n"; + } + foreach ($warn as $w) { + $this->output .= "Warning: $w\n"; + } + $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", + sizeof($err), sizeof($warn)); + if ($strict && sizeof($err) > 0) { + $this->output .= "Fix these errors and try again."; + return false; + } + return true; + } + + // }}} + // {{{ doPackage() + + function doPackage($command, $options, $params) + { + $this->output = ''; + include_once 'PEAR/Packager.php'; + $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; + $packager =& new PEAR_Packager($this->config->get('php_dir'), + $this->config->get('ext_dir'), + $this->config->get('doc_dir')); + $packager->debug = $this->config->get('verbose'); + $err = $warn = array(); + $dir = dirname($pkginfofile); + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress); + if (PEAR::isError($result)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError($result); + } + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->output = $result; + } + /* (cox) What is supposed to do that code? + $lines = explode("\n", $this->output); + foreach ($lines as $line) { + $this->output .= $line."n"; + } + */ + if (PEAR::isError($result)) { + $this->output .= "Package failed: ".$result->getMessage(); + } + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doPackageValidate() + + function doPackageValidate($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $params[0] = "package.xml"; + } + $obj = new PEAR_Common; + $info = null; + if ($fp = @fopen($params[0], "r")) { + $test = fread($fp, 5); + fclose($fp); + if ($test == "infoFromDescriptionFile($params[0]); + } + } + if (empty($info)) { + $info = $obj->infoFromTgzFile($params[0]); + } + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $obj->validatePackageInfo($info, $err, $warn); + $this->_displayValidationResults($err, $warn); + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doCvsTag() + + function doCvsTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromDescriptionFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $err = $warn = array(); + $obj->validatePackageInfo($info, $err, $warn); + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + break; + } + $version = $info['version']; + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); + $cvstag = "RELEASE_$cvsversion"; + $files = array_keys($info['filelist']); + $command = "cvs"; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + if (isset($options['reallyquiet'])) { + $command .= ' -Q'; + } + $command .= ' tag'; + if (isset($options['slide'])) { + $command .= ' -F'; + } + if (isset($options['delete'])) { + $command .= ' -d'; + } + $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); + foreach ($files as $file) { + $command .= ' ' . escapeshellarg($file); + } + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + $this->ui->outputData($this->output, $_cmd); + return true; + } + + // }}} + // {{{ doCvsDiff() + + function doCvsDiff($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromDescriptionFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $files = array_keys($info['filelist']); + $cmd = "cvs"; + if (isset($options['quiet'])) { + $cmd .= ' -q'; + unset($options['quiet']); + } + if (isset($options['reallyquiet'])) { + $cmd .= ' -Q'; + unset($options['reallyquiet']); + } + if (isset($options['release'])) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); + $cvstag = "RELEASE_$cvsversion"; + $options['revision'] = $cvstag; + unset($options['release']); + } + $execute = true; + if (isset($options['dry-run'])) { + $execute = false; + unset($options['dry-run']); + } + $cmd .= ' diff'; + // the rest of the options are passed right on to "cvs diff" + foreach ($options as $option => $optarg) { + $arg = @$this->commands[$command]['options'][$option]['arg']; + $short = @$this->commands[$command]['options'][$option]['shortopt']; + $cmd .= $short ? " -$short" : " --$option"; + if ($arg && $optarg) { + $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); + } + } + foreach ($files as $file) { + $cmd .= ' ' . escapeshellarg($file); + } + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $cmd\n"; + } + if ($execute) { + $fp = popen($cmd, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doRunTests() + + function doRunTests($command, $options, $params) + { + $cwd = getcwd(); + $php = PHP_BINDIR . '/php' . (OS_WINDOWS ? '.exe' : ''); + putenv("TEST_PHP_EXECUTABLE=$php"); + $ip = ini_get("include_path"); + $ps = OS_WINDOWS ? ';' : ':'; + $run_tests = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . 'run-tests.php'; + if (!file_exists($run_tests)) { + $run_tests = PEAR_INSTALL_DIR . DIRECTORY_SEPARATOR . 'run-tests.php'; + if (!file_exists($run_tests)) { + return $this->raiseError("No `run-tests.php' file found"); + } + } + $plist = implode(" ", $params); + $cmd = "$php -C -d include_path=$cwd$ps$ip -f $run_tests -- $plist"; + system($cmd); + return true; + } + + // }}} + // {{{ doPackageDependencies() + + function doPackageDependencies($command, $options, $params) + { + // $params[0] -> the PEAR package to list its information + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + $obj = new PEAR_Common(); + if (PEAR::isError($info = $obj->infoFromAny($params[0]))) { + return $this->raiseError($info); + } + + if (is_array($info['release_deps'])) { + $data = array( + 'caption' => 'Dependencies for ' . $info['package'], + 'border' => true, + 'headline' => array("Type", "Name", "Relation", "Version"), + ); + + foreach ($info['release_deps'] as $d) { + + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + + if (isset($d['name'])) { + $name = $d['name']; + } else { + $name = ''; + } + + if (isset($d['version'])) { + $version = $d['version']; + } else { + $version = ''; + } + + $data['data'][] = array($type, $name, $rel, $version); + } + + $this->ui->outputData($data, $command); + return true; + } + + // Fallback + $this->ui->outputData("This package does not have any dependencies.", $command); + } + + // }}} + // {{{ doSign() + + function doSign($command, $options, $params) + { + // should move most of this code into PEAR_Packager + // so it'll be easy to implement "pear package --sign" + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromTgzFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + include_once "Archive/Tar.php"; + include_once "System.php"; + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pearsign'); + if (!$tar->extractList('package.xml package.sig', $tmpdir)) { + return $this->raiseError("failed to extract tar file"); + } + if (file_exists("$tmpdir/package.sig")) { + return $this->raiseError("package already signed"); + } + @unlink("$tmpdir/package.sig"); + $input = $this->ui->userDialog($command, + array('GnuPG Passphrase'), + array('password')); + $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/package.xml 2>/dev/null", "w"); + if (!$gpg) { + return $this->raiseError("gpg command failed"); + } + fwrite($gpg, "$input[0]\r"); + if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { + return $this->raiseError("gpg sign failed"); + } + $tar->addModify("$tmpdir/package.sig", '', $tmpdir); + return true; + } + + // }}} + // {{{ doMakeRPM() + + function doMakeRPM($command, $options, $params) + { + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + include_once "Archive/Tar.php"; + include_once "PEAR/Installer.php"; + include_once "System.php"; + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pear2rpm'); + $instroot = System::mktemp('-d pear2rpm'); + $tmp = $this->config->get('verbose'); + $this->config->set('verbose', 0); + $installer = new PEAR_Installer($this->ui); + $info = $installer->install($params[0], + array('installroot' => $instroot, + 'nodeps' => true)); + $pkgdir = "$info[package]-$info[version]"; +// print "instroot=$instroot\n"; +// print_r($info); +// return true; + + $info['rpm_xml_dir'] = '/var/lib/pear'; + $this->config->set('verbose', $tmp); + if (!$tar->extractList("$pkgdir/package.xml", $tmpdir, $pkgdir)) { + return $this->raiseError("failed to extract $params[0]"); + } + if (!file_exists("$tmpdir/package.xml")) { + return $this->raiseError("no package.xml found in $params[0]"); + } +// System::mkdir("-p $instroot$info[rpm_xml_dir]"); +// if (!@copy("$tmpdir/package.xml", "$instroot$info[rpm_xml_dir]/$info[package].xml")) { +// return $this->raiseError("could not copy package.xml file: $php_errormsg"); +// } + if (isset($options['spec-template'])) { + $spec_template = $options['spec-template']; + } else { + $spec_template = $this->config->get('data_dir') . + '/PEAR/template.spec'; + } + if (isset($options['rpm-pkgname'])) { + $rpm_pkgname_format = $options['rpm-pkgname']; + } else { + $rpm_pkgname_format = "PEAR::%s"; + } + + $info['extra_headers'] = ''; + $info['doc_files'] = ''; + $info['files'] = ''; + $info['rpm_package'] = sprintf($rpm_pkgname_format, $info['package']); + $srcfiles = 0; + foreach ($info['filelist'] as $name => $attr) { + if ($attr['role'] == 'doc') { + $info['doc_files'] .= " $name"; + } elseif ($attr['role'] == 'src') { + $srcfiles++; + } + $info['files'] .= "$attr[installed_as]\n"; + } + if ($srcfiles > 0) { + include_once "OS/Guess.php"; + $os = new OS_Guess; + $arch = $os->getCpu(); + } else { + $arch = 'noarch'; + } + $cfk = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', + 'bin_dir', 'data_dir', 'test_dir'); + foreach ($cfg as $k) { + $info[$k] = $this->config->get($k); + } + $info['arch'] = $arch; + $fp = @fopen($spec_template, "r"); + if (!$fp) { + return $this->raiseError("could not open RPM spec file template $spec_template: $php_errormsg"); + } + $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]', fread($fp, filesize($spec_template))); + fclose($fp); + $spec_file = "$info[rpm_package]-$info[version].spec"; + $wp = fopen($spec_file, "w"); + if (!$wp) { + return $this->raiseError("could not write RPM spec file $spec_file: $php_errormsg"); + } + fwrite($wp, $spec_contents); + fclose($wp); + $this->ui->outputData("Wrote RPM spec file $spec_file", $command); + + return true; + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Command/Registry.php b/gulliver/thirdparty/pear/PEAR/Command/Registry.php new file mode 100644 index 000000000..a4b9e76a6 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Registry.php @@ -0,0 +1,319 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Registry.php,v 1.30 2003/03/18 12:06:07 ssb Exp $ + +require_once 'PEAR/Command/Common.php'; +require_once 'PEAR/Registry.php'; +require_once 'PEAR/Config.php'; + +class PEAR_Command_Registry extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'list' => array( + 'summary' => 'List Installed Packages', + 'function' => 'doList', + 'shortcut' => 'l', + 'options' => array(), + 'doc' => '[package] +If invoked without parameters, this command lists the PEAR packages +installed in your php_dir ({config php_dir)). With a parameter, it +lists the files in that package. +', + ), + 'shell-test' => array( + 'summary' => 'Shell Script Test', + 'function' => 'doShellTest', + 'shortcut' => 'st', + 'options' => array(), + 'doc' => ' [[relation] version] +Tests if a package is installed in the system. Will exit(1) if it is not. + The version comparison operator. One of: + <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne + The version to compare with +'), + 'info' => array( + 'summary' => 'Display information about a package', + 'function' => 'doInfo', + 'shortcut' => 'in', + 'options' => array(), + 'doc' => ' +Displays information about a package. The package argument may be a +local package file, an URL to a package file, or the name of an +installed package.' + ) + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Registry constructor. + * + * @access public + */ + function PEAR_Command_Registry(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doList() + + function _sortinfo($a, $b) + { + return strcmp($a['package'], $b['package']); + } + + function doList($command, $options, $params) + { + $reg = new PEAR_Registry($this->config->get('php_dir')); + if (sizeof($params) == 0) { + $installed = $reg->packageInfo(); + usort($installed, array(&$this, '_sortinfo')); + $i = $j = 0; + $data = array( + 'caption' => 'Installed packages:', + 'border' => true, + 'headline' => array('Package', 'Version', 'State') + ); + foreach ($installed as $package) { + $data['data'][] = array($package['package'], + $package['version'], + @$package['release_state']); + } + if (count($installed)==0) { + $data = '(no packages installed)'; + } + $this->ui->outputData($data, $command); + } else { + if (file_exists($params[0]) && !is_dir($params[0])) { + include_once "PEAR/Common.php"; + $obj = &new PEAR_Common; + $info = $obj->infoFromAny($params[0]); + $headings = array('Package File', 'Install Path'); + $installed = false; + } else { + $info = $reg->packageInfo($params[0]); + $headings = array('Type', 'Install Path'); + $installed = true; + } + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + if ($info === null) { + return $this->raiseError("`$params[0]' not installed"); + } + $list = $info['filelist']; + if ($installed) { + $caption = 'Installed Files For ' . $params[0]; + } else { + $caption = 'Contents of ' . basename($params[0]); + } + $data = array( + 'caption' => $caption, + 'border' => true, + 'headline' => $headings); + foreach ($list as $file => $att) { + if ($installed) { + if (empty($att['installed_as'])) { + continue; + } + $data['data'][] = array($att['role'], $att['installed_as']); + } else { + if (isset($att['baseinstalldir'])) { + $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR . + $file; + } else { + $dest = $file; + } + switch ($att['role']) { + case 'test': + case 'data': + if ($installed) { + break 2; + } + $dest = '-- will not be installed --'; + break; + case 'doc': + $dest = $this->config->get('doc_dir') . DIRECTORY_SEPARATOR . + $dest; + break; + case 'php': + default: + $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . + $dest; + } + $dest = preg_replace('!/+!', '/', $dest); + $file = preg_replace('!/+!', '/', $file); + $data['data'][] = array($file, $dest); + } + } + $this->ui->outputData($data, $command); + + + } + return true; + } + + // }}} + // {{{ doShellTest() + + function doShellTest($command, $options, $params) + { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $reg = &new PEAR_Registry($this->config->get('php_dir')); + // "pear shell-test Foo" + if (sizeof($params) == 1) { + if (!$reg->packageExists($params[0])) { + exit(1); + } + // "pear shell-test Foo 1.0" + } elseif (sizeof($params) == 2) { + $v = $reg->packageInfo($params[0], 'version'); + if (!$v || !version_compare("$v", "{$params[1]}", "ge")) { + exit(1); + } + // "pear shell-test Foo ge 1.0" + } elseif (sizeof($params) == 3) { + $v = $reg->packageInfo($params[0], 'version'); + if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) { + exit(1); + } + } else { + $this->popErrorHandling(); + $this->raiseError("$command: expects 1 to 3 parameters"); + exit(1); + } + } + + // }}} + // {{{ doInfo + + function doInfo($command, $options, $params) + { + // $params[0] The package for showing info + if (sizeof($params) != 1) { + return $this->raiseError("This command only accepts one param: ". + "the package you want information"); + } + if (@is_file($params[0])) { + $obj = &new PEAR_Common(); + $info = $obj->infoFromAny($params[0]); + } else { + $reg = &new PEAR_Registry($this->config->get('php_dir')); + $info = $reg->packageInfo($params[0]); + } + if (PEAR::isError($info)) { + return $info; + } + if (empty($info)) { + $this->ui->displayError("Nothing found for `$params[0]'"); + return; + } + unset($info['filelist']); + unset($info['changelog']); + $keys = array_keys($info); + $longtext = array('description', 'summary'); + foreach ($keys as $key) { + if (is_array($info[$key])) { + switch ($key) { + case 'maintainers': { + $i = 0; + $mstr = ''; + foreach ($info[$key] as $m) { + if ($i++ > 0) { + $mstr .= "\n"; + } + $mstr .= $m['name'] . " <"; + if (isset($m['email'])) { + $mstr .= $m['email']; + } else { + $mstr .= $m['handle'] . '@php.net'; + } + $mstr .= "> ($m[role])"; + } + $info[$key] = $mstr; + break; + } + case 'release_deps': { + $i = 0; + $dstr = ''; + foreach ($info[$key] as $d) { + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + if (isset($d['name'])) { + $name = $d['name'] . ' '; + } else { + $name = ''; + } + if (isset($d['version'])) { + $version = $d['version'] . ' '; + } else { + $version = ''; + } + $dstr .= "$type $name$rel $version\n"; + } + $info[$key] = $dstr; + break; + } + default: { + $info[$key] = implode(", ", $info[$key]); + break; + } + } + } + if ($key == '_lastmodified') { + $hdate = date('Y-m-d', $info[$key]); + unset($info[$key]); + $info['Last Modified'] = $hdate; + } else { + $info[$key] = trim($info[$key]); + if (in_array($key, $longtext)) { + $info[$key] = preg_replace('/ +/', ' ', $info[$key]); + } + } + } + $caption = 'About ' . $info['package'] . '-' . $info['version']; + $data = array( + 'caption' => $caption, + 'border' => true); + foreach ($info as $key => $value) { + $key = ucwords(trim(str_replace('_', ' ', $key))); + $data['data'][] = array($key, $value); + } + + $this->ui->outputData($data, 'package-info'); + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Command/Remote.php b/gulliver/thirdparty/pear/PEAR/Command/Remote.php new file mode 100644 index 000000000..366d9daba --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Command/Remote.php @@ -0,0 +1,407 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Remote.php,v 1.29 2003/03/18 12:06:07 ssb Exp $ + +require_once 'PEAR/Command/Common.php'; +require_once 'PEAR/Common.php'; +require_once 'PEAR/Remote.php'; +require_once 'PEAR/Registry.php'; + +class PEAR_Command_Remote extends PEAR_Command_Common +{ + // {{{ command definitions + + var $commands = array( + 'remote-info' => array( + 'summary' => 'Information About Remote Packages', + 'function' => 'doRemoteInfo', + 'shortcut' => 'ri', + 'options' => array(), + 'doc' => ' +Get details on a package from the server.', + ), + 'list-upgrades' => array( + 'summary' => 'List Available Upgrades', + 'function' => 'doListUpgrades', + 'shortcut' => 'lu', + 'options' => array(), + 'doc' => ' +List releases on the server of packages you have installed where +a newer version is available with the same release state (stable etc.).' + ), + 'remote-list' => array( + 'summary' => 'List Remote Packages', + 'function' => 'doRemoteList', + 'shortcut' => 'rl', + 'options' => array(), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'search' => array( + 'summary' => 'Search remote package database', + 'function' => 'doSearch', + 'shortcut' => 'sp', + 'options' => array(), + 'doc' => ' +Lists all packages which match the search parameters (first param +is package name, second package info)', + ), + 'list-all' => array( + 'summary' => 'List All Packages', + 'function' => 'doListAll', + 'shortcut' => 'la', + 'options' => array(), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'download' => array( + 'summary' => 'Download Package', + 'function' => 'doDownload', + 'shortcut' => 'd', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'download an uncompressed (.tar) file', + ), + ), + 'doc' => '{package|package-version} +Download a package tarball. The file will be named as suggested by the +server, for example if you download the DB package and the latest stable +version of DB is 1.2, the downloaded file will be DB-1.2.tgz.', + ), + 'clear-cache' => array( + 'summary' => 'Clear XML-RPC Cache', + 'function' => 'doClearCache', + 'shortcut' => 'cc', + 'options' => array(), + 'doc' => ' +Clear the XML-RPC cache. See also the cache_ttl configuration +parameter. +', + ), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Remote constructor. + * + * @access public + */ + function PEAR_Command_Remote(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doRemoteInfo() + + function doRemoteInfo($command, $options, $params) + { + if (sizeof($params) != 1) { + return $this->raiseError("$command expects one param: the remote package name"); + } + $r = new PEAR_Remote($this->config); + $info = $r->call('package.info', $params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $reg = new PEAR_Registry($this->config->get('php_dir')); + $installed = $reg->packageInfo($info['name']); + $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; + + $this->ui->outputData($info, $command); + + return true; + } + + // }}} + // {{{ doRemoteList() + + function doRemoteList($command, $options, $params) + { + $r = new PEAR_Remote($this->config); + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') + $list_options = true; + $available = $r->call('package.listAll', $list_options); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + $i = $j = 0; + $data = array( + 'caption' => 'Available packages:', + 'border' => true, + 'headline' => array('Package', 'Version'), + ); + foreach ($available as $name => $info) { + $data['data'][] = array($name, isset($info['stable']) ? $info['stable'] : '-n/a-'); + } + if (count($available)==0) { + $data = '(no packages installed yet)'; + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doListAll() + + function doListAll($command, $options, $params) + { + $r = new PEAR_Remote($this->config); + $reg = new PEAR_Registry($this->config->get('php_dir')); + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') + $list_options = true; + $available = $r->call('package.listAll', $list_options); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + if (!is_array($available)) { + return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "'.$available.'")'); + } + $data = array( + 'caption' => 'All packages:', + 'border' => true, + 'headline' => array('Package', 'Latest', 'Local'), + ); + + foreach ($available as $name => $info) { + $installed = $reg->packageInfo($name); + $desc = $info['summary']; + if (isset($params[$name])) + $desc .= "\n\n".$info['description']; + + if (isset($options['mode'])) + { + if ($options['mode'] == 'installed' && !isset($installed['version'])) + continue; + if ($options['mode'] == 'notinstalled' && isset($installed['version'])) + continue; + if ($options['mode'] == 'upgrades' + && (!isset($installed['version']) || $installed['version'] == $info['stable'])) + { + continue; + }; + }; + + $data['data'][$info['category']][] = array( + $name, + @$info['stable'], + @$installed['version'], + @$desc, + @$info['deps'], + ); + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doSearch() + + function doSearch($command, $options, $params) + { + if ((!isset($params[0]) || empty($params[0])) + && (!isset($params[1]) || empty($params[1]))) + { + return $this->raiseError('no valid search string supplied'); + }; + + $r = new PEAR_Remote($this->config); + $reg = new PEAR_Registry($this->config->get('php_dir')); + $available = $r->call('package.listAll', true); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + $data = array( + 'caption' => 'Matched packages:', + 'border' => true, + 'headline' => array('Package', 'Latest', 'Local'), + ); + + foreach ($available as $name => $info) { + $found = (!empty($params[0]) && stristr($name, $params[0]) !== false); + if (!$found && !(isset($params[1]) && !empty($params[1]) + && (stristr($info['summary'], $params[1]) !== false + || stristr($info['description'], $params[1]) !== false))) + { + continue; + }; + + $installed = $reg->packageInfo($name); + $desc = $info['summary']; + if (isset($params[$name])) + $desc .= "\n\n".$info['description']; + + $data['data'][$info['category']][] = array( + $name, + $info['stable'], + $installed['version'], + $desc, + ); + } + if (!isset($data['data'])) { + return $this->raiseError('no packages found'); + }; + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doDownload() + + function doDownload($command, $options, $params) + { + //$params[0] -> The package to download + if (count($params) != 1) { + return PEAR::raiseError("download expects one argument: the package to download"); + } + $server = $this->config->get('master_server'); + if (!ereg('^http://', $params[0])) { + $pkgfile = "http://$server/get/$params[0]"; + } else { + $pkgfile = $params[0]; + } + $this->bytes_downloaded = 0; + $saved = PEAR_Common::downloadHttp($pkgfile, $this->ui, '.', + array(&$this, 'downloadCallback')); + if (PEAR::isError($saved)) { + return $this->raiseError($saved); + } + $fname = basename($saved); + $this->ui->outputData("File $fname downloaded ($this->bytes_downloaded bytes)", $command); + return true; + } + + function downloadCallback($msg, $params = null) + { + if ($msg == 'done') { + $this->bytes_downloaded = $params; + } + } + + // }}} + // {{{ doListUpgrades() + + function doListUpgrades($command, $options, $params) + { + include_once "PEAR/Registry.php"; + $remote = new PEAR_Remote($this->config); + if (empty($params[0])) { + $state = $this->config->get('preferred_state'); + } else { + $state = $params[0]; + } + $caption = 'Available Upgrades'; + if (empty($state) || $state == 'any') { + $latest = $remote->call("package.listLatestReleases"); + } else { + $latest = $remote->call("package.listLatestReleases", $state); + $caption .= ' (' . $state . ')'; + } + $caption .= ':'; + if (PEAR::isError($latest)) { + return $latest; + } + $reg = new PEAR_Registry($this->config->get('php_dir')); + $inst = array_flip($reg->listPackages()); + $data = array( + 'caption' => $caption, + 'border' => 1, + 'headline' => array('Package', 'Version', 'Size'), + ); + foreach ($latest as $package => $info) { + if (!isset($inst[$package])) { + // skip packages we don't have installed + continue; + } + extract($info); + $inst_version = $reg->packageInfo($package, 'version'); + if (version_compare("$version", "$inst_version", "le")) { + // installed version is up-to-date + continue; + } + if ($filesize >= 20480) { + $filesize += 1024 - ($filesize % 1024); + $fs = sprintf("%dkB", $filesize / 1024); + } elseif ($filesize > 0) { + $filesize += 103 - ($filesize % 103); + $fs = sprintf("%.1fkB", $filesize / 1024.0); + } else { + $fs = " -"; // XXX center instead + } + $data['data'][] = array($package, $version, $fs); + } + if (empty($data['data'])) { + $this->ui->outputData('No upgrades available'); + } else { + $this->ui->outputData($data, $command); + } + return true; + } + + // }}} + // {{{ doClearCache() + + function doClearCache($command, $options, $params) + { + $cache_dir = $this->config->get('cache_dir'); + $verbose = $this->config->get('verbose'); + $output = ''; + if (!($dp = @opendir($cache_dir))) { + return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); + } + if ($verbose >= 1) { + $output .= "reading directory $cache_dir\n"; + } + $num = 0; + while ($ent = readdir($dp)) { + if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent)) { + $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; + $ok = @unlink($path); + if ($ok) { + if ($verbose >= 2) { + $output .= "deleted $path\n"; + } + $num++; + } elseif ($verbose >= 1) { + $output .= "failed to delete $path\n"; + } + } + } + closedir($dp); + if ($verbose >= 1) { + $output .= "$num cache entries cleared\n"; + } + $this->ui->outputData(rtrim($output), $command); + return $num; + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Common.php b/gulliver/thirdparty/pear/PEAR/Common.php new file mode 100644 index 000000000..8c49511b3 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Common.php @@ -0,0 +1,1674 @@ + | +// | Tomas V.V.Cox | +// +----------------------------------------------------------------------+ +// +// $Id: Common.php,v 1.91 2003/05/09 12:03:09 derick Exp $ + +require_once 'PEAR.php'; +require_once 'Archive/Tar.php'; +require_once 'System.php'; +require_once 'PEAR/Config.php'; + +// {{{ constants and globals + +define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^([A-Z][a-zA-Z0-9_]+|[a-z][a-z0-9_]+)$/'); + +/** + * List of temporary files and directories registered by + * PEAR_Common::addTempFile(). + * @var array + */ +$GLOBALS['_PEAR_Common_tempfiles'] = array(); + +/** + * Valid maintainer roles + * @var array + */ +$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); + +/** + * Valid release states + * @var array + */ +$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); + +/** + * Valid dependency types + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); + +/** + * Valid dependency relations + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge'); + +/** + * Valid file roles + * @var array + */ +$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); + +/** + * Valid replacement types + * @var array + */ +$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); + +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); + +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); + +// }}} + +/** + * Class providing common functionality for PEAR adminsitration classes. + */ +class PEAR_Common extends PEAR +{ + // {{{ properties + + /** stack of elements, gives some sort of XML context */ + var $element_stack = array(); + + /** name of currently parsed XML element */ + var $current_element; + + /** array of attributes of the currently parsed XML element */ + var $current_attributes = array(); + + /** assoc with information about a package */ + var $pkginfo = array(); + + /** + * User Interface object (PEAR_Frontend_* class). If null, + * the log() method uses print. + * @var object + */ + var $ui = null; + + /** + * Configuration object (PEAR_Config). + * @var object + */ + var $config = null; + + var $current_path = null; + + /** + * PEAR_SourceAnalyzer instance + * @var object + */ + var $source_analyzer = null; + + // }}} + + // {{{ constructor + + /** + * PEAR_Common constructor + * + * @access public + */ + function PEAR_Common() + { + parent::PEAR(); + $this->config = &PEAR_Config::singleton(); + $this->debug = $this->config->get('verbose'); + } + + // }}} + // {{{ destructor + + /** + * PEAR_Common destructor + * + * @access private + */ + function _PEAR_Common() + { + // doesn't work due to bug #14744 + //$tempfiles = $this->_tempfiles; + $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; + while ($file = array_shift($tempfiles)) { + if (@is_dir($file)) { + System::rm("-rf $file"); + } elseif (file_exists($file)) { + unlink($file); + } + } + } + + // }}} + // {{{ addTempFile() + + /** + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string $file name of file or directory + * + * @return void + * + * @access public + */ + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } + + // }}} + // {{{ mkDirHier() + + /** + * Wrapper to System::mkDir(), creates a directory as well as + * any necessary parent directories. + * + * @param string $dir directory name + * + * @return bool TRUE on success, or a PEAR error + * + * @access public + */ + function mkDirHier($dir) + { + $this->log(2, "+ create dir $dir"); + return System::mkDir("-p $dir"); + } + + // }}} + // {{{ log() + + /** + * Logging method. + * + * @param int $level log level (0 is quiet, higher is noisier) + * @param string $msg message to write to the log + * + * @return void + * + * @access public + */ + function log($level, $msg) + { + if ($this->debug >= $level) { + if (is_object($this->ui)) { + $this->ui->log($msg); + } else { + print "$msg\n"; + } + } + } + + // }}} + // {{{ mkTempDir() + + /** + * Create and register a temporary directory. + * + * @param string $tmpdir (optional) Directory to use as tmpdir. + * Will use system defaults (for example + * /tmp or c:\windows\temp) if not specified + * + * @return string name of created directory + * + * @access public + */ + function mkTempDir($tmpdir = '') + { + if ($tmpdir) { + $topt = "-t $tmpdir "; + } else { + $topt = ''; + } + if (!$tmpdir = System::mktemp($topt . '-d pear')) { + return false; + } + $this->addTempFile($tmpdir); + return $tmpdir; + } + + // }}} + // {{{ setFrontendObject() + + /** + * Set object that represents the frontend to be used. + * + * @param object Reference of the frontend object + * @return void + * @access public + */ + function setFrontendObject(&$ui) + { + $this->ui = &$ui; + } + + // }}} + + // {{{ _unIndent() + + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } + } + return $data; + } + + // }}} + // {{{ _element_start() + + /** + * XML parser callback for starting elements. Used while package + * format version is not yet known. + * + * @param resource $xp XML parser resource + * @param string $name name of starting element + * @param array $attribs element attributes, name => value + * + * @return void + * + * @access private + */ + function _element_start($xp, $name, $attribs) + { + array_push($this->element_stack, $name); + $this->current_element = $name; + $spos = sizeof($this->element_stack) - 2; + $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; + $this->current_attributes = $attribs; + switch ($name) { + case 'package': { + if (isset($attribs['version'])) { + $vs = preg_replace('/[^0-9a-z]/', '_', $attribs['version']); + } else { + $vs = '1_0'; + } + $elem_start = '_element_start_'. $vs; + $elem_end = '_element_end_'. $vs; + $cdata = '_pkginfo_cdata_'. $vs; + xml_set_element_handler($xp, $elem_start, $elem_end); + xml_set_character_data_handler($xp, $cdata); + break; + } + } + } + + // }}} + // {{{ _element_end() + + /** + * XML parser callback for ending elements. Used while package + * format version is not yet known. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_end($xp, $name) + { + } + + // }}} + + // Support for package DTD v1.0: + // {{{ _element_start_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_start_1_0($xp, $name, $attribs) + { + array_push($this->element_stack, $name); + $this->current_element = $name; + $spos = sizeof($this->element_stack) - 2; + $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; + $this->current_attributes = $attribs; + $this->cdata = ''; + switch ($name) { + case 'dir': + if ($this->in_changelog) { + break; + } + if ($attribs['name'] != '/') { + $this->dir_names[] = $attribs['name']; + } + if (isset($attribs['baseinstalldir'])) { + $this->dir_install = $attribs['baseinstalldir']; + } + if (isset($attribs['role'])) { + $this->dir_role = $attribs['role']; + } + break; + case 'file': + if ($this->in_changelog) { + break; + } + if (isset($attribs['name'])) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . DIRECTORY_SEPARATOR; + } + } + $path .= $attribs['name']; + unset($attribs['name']); + $this->current_path = $path; + $this->filelist[$path] = $attribs; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; + } + } + break; + case 'replace': + if (!$this->in_changelog) { + $this->filelist[$this->current_path]['replacements'][] = $attribs; + } + break; + case 'maintainers': + $this->pkginfo['maintainers'] = array(); + $this->m_i = 0; // maintainers array index + break; + case 'maintainer': + // compatibility check + if (!isset($this->pkginfo['maintainers'])) { + $this->pkginfo['maintainers'] = array(); + $this->m_i = 0; + } + $this->pkginfo['maintainers'][$this->m_i] = array(); + $this->current_maintainer =& $this->pkginfo['maintainers'][$this->m_i]; + break; + case 'changelog': + $this->pkginfo['changelog'] = array(); + $this->c_i = 0; // changelog array index + $this->in_changelog = true; + break; + case 'release': + if ($this->in_changelog) { + $this->pkginfo['changelog'][$this->c_i] = array(); + $this->current_release = &$this->pkginfo['changelog'][$this->c_i]; + } else { + $this->current_release = &$this->pkginfo; + } + break; + case 'deps': + if (!$this->in_changelog) { + $this->pkginfo['release_deps'] = array(); + } + break; + case 'dep': + // dependencies array index + if (!$this->in_changelog) { + $this->d_i++; + $this->pkginfo['release_deps'][$this->d_i] = $attribs; + } + break; + case 'configureoptions': + if (!$this->in_changelog) { + $this->pkginfo['configure_options'] = array(); + } + break; + case 'configureoption': + if (!$this->in_changelog) { + $this->pkginfo['configure_options'][] = $attribs; + } + break; + case 'provides': + if (empty($attribs['type']) || empty($attribs['name'])) { + break; + } + $attribs['explicit'] = true; + $this->pkginfo['provides']["$attribs[type];$attribs[name]"] = $attribs; + break; + } + } + + // }}} + // {{{ _element_end_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_end_1_0($xp, $name) + { + $data = trim($this->cdata); + switch ($name) { + case 'name': + switch ($this->prev_element) { + case 'package': + // XXX should we check the package name here? + $this->pkginfo['package'] = ereg_replace('[^a-zA-Z0-9._]', '_', $data); + break; + case 'maintainer': + $this->current_maintainer['name'] = $data; + break; + } + break; + case 'summary': + $this->pkginfo['summary'] = $data; + break; + case 'description': + $data = $this->_unIndent($this->cdata); + $this->pkginfo['description'] = $data; + break; + case 'user': + $this->current_maintainer['handle'] = $data; + break; + case 'email': + $this->current_maintainer['email'] = $data; + break; + case 'role': + $this->current_maintainer['role'] = $data; + break; + case 'version': + $data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data); + if ($this->in_changelog) { + $this->current_release['version'] = $data; + } else { + $this->pkginfo['version'] = $data; + } + break; + case 'date': + if ($this->in_changelog) { + $this->current_release['release_date'] = $data; + } else { + $this->pkginfo['release_date'] = $data; + } + break; + case 'notes': + // try to "de-indent" release notes in case someone + // has been over-indenting their xml ;-) + $data = $this->_unIndent($this->cdata); + if ($this->in_changelog) { + $this->current_release['release_notes'] = $data; + } else { + $this->pkginfo['release_notes'] = $data; + } + break; + case 'warnings': + if ($this->in_changelog) { + $this->current_release['release_warnings'] = $data; + } else { + $this->pkginfo['release_warnings'] = $data; + } + break; + case 'state': + if ($this->in_changelog) { + $this->current_release['release_state'] = $data; + } else { + $this->pkginfo['release_state'] = $data; + } + break; + case 'license': + $this->pkginfo['release_license'] = $data; + break; + case 'dep': + if ($data && !$this->in_changelog) { + $this->pkginfo['release_deps'][$this->d_i]['name'] = $data; + } + break; + case 'dir': + if ($this->in_changelog) { + break; + } + array_pop($this->dir_names); + break; + case 'file': + if ($this->in_changelog) { + break; + } + if ($data) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . DIRECTORY_SEPARATOR; + } + } + $path .= $data; + $this->filelist[$path] = $this->current_attributes; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; + } + } + break; + case 'maintainer': + if (empty($this->pkginfo['maintainers'][$this->m_i]['role'])) { + $this->pkginfo['maintainers'][$this->m_i]['role'] = 'lead'; + } + $this->m_i++; + break; + case 'release': + if ($this->in_changelog) { + $this->c_i++; + } + break; + case 'changelog': + $this->in_changelog = false; + break; + case 'summary': + $this->pkginfo['summary'] = $data; + break; + } + array_pop($this->element_stack); + $spos = sizeof($this->element_stack) - 1; + $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; + $this->cdata = ''; + } + + // }}} + // {{{ _pkginfo_cdata_1_0() + + /** + * XML parser callback for character data. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name character data + * + * @return void + * + * @access private + */ + function _pkginfo_cdata_1_0($xp, $data) + { + if (isset($this->cdata)) { + $this->cdata .= $data; + } + } + + // }}} + + // {{{ infoFromTgzFile() + + /** + * Returns information about a package file. Expects the name of + * a gzipped tar file as input. + * + * @param string $file name of .tgz file + * + * @return array array with package information + * + * @access public + * + */ + function infoFromTgzFile($file) + { + if (!@is_file($file)) { + return $this->raiseError("could not open file \"$file\""); + } + $tar = new Archive_Tar($file); + $content = $tar->listContent(); + if (!is_array($content)) { + return $this->raiseError("could not get contents of package \"$file\""); + } + $xml = null; + foreach ($content as $file) { + $name = $file['filename']; + if ($name == 'package.xml') { + $xml = $name; + break; + } elseif (ereg('package.xml$', $name, $match)) { + $xml = $match[0]; + break; + } + } + $tmpdir = System::mkTemp('-d pear'); + $this->addTempFile($tmpdir); + if (!$xml || !$tar->extractList($xml, $tmpdir)) { + return $this->raiseError('could not extract the package.xml file'); + } + return $this->infoFromDescriptionFile("$tmpdir/$xml"); + } + + // }}} + // {{{ infoFromDescriptionFile() + + /** + * Returns information about a package file. Expects the name of + * a package xml file as input. + * + * @param string $descfile name of package xml file + * + * @return array array with package information + * + * @access public + * + */ + function infoFromDescriptionFile($descfile) + { + if (!@is_file($descfile) || !is_readable($descfile) || + (!$fp = @fopen($descfile, 'r'))) { + return $this->raiseError("Unable to open $descfile"); + } + + // read the whole thing so we only get one cdata callback + // for each block of cdata + $data = fread($fp, filesize($descfile)); + return $this->infoFromString($data); + } + + // }}} + // {{{ infoFromString() + + /** + * Returns information about a package file. Expects the contents + * of a package xml file as input. + * + * @param string $data name of package xml file + * + * @return array array with package information + * + * @access public + * + */ + function infoFromString($data) + { + require_once('PEAR/Dependency.php'); + if (PEAR_Dependency::checkExtension($error, 'xml')) { + return $this->raiseError($error); + } + $xp = @xml_parser_create(); + if (!$xp) { + return $this->raiseError('Unable to create XML parser'); + } + xml_set_object($xp, $this); + xml_set_element_handler($xp, '_element_start', '_element_end'); + xml_set_character_data_handler($xp, '_pkginfo_cdata'); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); + + $this->element_stack = array(); + $this->pkginfo = array('provides' => array()); + $this->current_element = false; + unset($this->dir_install); + $this->pkginfo['filelist'] = array(); + $this->filelist =& $this->pkginfo['filelist']; + $this->dir_names = array(); + $this->in_changelog = false; + $this->d_i = 0; + $this->cdata = ''; + + if (!xml_parse($xp, $data, 1)) { + $code = xml_get_error_code($xp); + $msg = sprintf("XML error: %s at line %d", + xml_error_string($code), + xml_get_current_line_number($xp)); + xml_parser_free($xp); + return $this->raiseError($msg, $code); + } + + xml_parser_free($xp); + + foreach ($this->pkginfo as $k => $v) { + if (!is_array($v)) { + $this->pkginfo[$k] = trim($v); + } + } + return $this->pkginfo; + } + // }}} + // {{{ infoFromAny() + + /** + * Returns package information from different sources + * + * This method is able to extract information about a package + * from a .tgz archive or from a XML package definition file. + * + * @access public + * @param string Filename of the source ('package.xml', '.tgz') + * @return string + */ + function infoFromAny($info) + { + if (is_string($info) && file_exists($info)) { + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = $this->infoFromDescriptionFile($info); + } elseif ($tmp == '.tar' || $tmp == '.tgz') { + $info = $this->infoFromTgzFile($info); + } else { + $fp = fopen($info, "r"); + $test = fread($fp, 5); + fclose($fp); + if ($test == "infoFromDescriptionFile($info); + } else { + $info = $this->infoFromTgzFile($info); + } + } + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + } + return $info; + } + + // }}} + // {{{ xmlFromInfo() + + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @param array $pkginfo package info + * + * @return string XML data + * + * @access public + */ + function xmlFromInfo($pkginfo) + { + static $maint_map = array( + "handle" => "user", + "name" => "name", + "email" => "email", + "role" => "role", + ); + $ret = "\n"; + //$ret .= "\n"; + $ret .= " + $pkginfo[package] + ".htmlspecialchars($pkginfo['summary'])." + ".htmlspecialchars($pkginfo['description'])." + +"; + foreach ($pkginfo['maintainers'] as $maint) { + $ret .= " \n"; + foreach ($maint_map as $idx => $elm) { + $ret .= " <$elm>"; + $ret .= htmlspecialchars($maint[$idx]); + $ret .= "\n"; + } + $ret .= " \n"; + } + $ret .= " \n"; + $ret .= $this->_makeReleaseXml($pkginfo); + if (@sizeof($pkginfo['changelog']) > 0) { + $ret .= " \n"; + foreach ($pkginfo['changelog'] as $oldrelease) { + $ret .= $this->_makeReleaseXml($oldrelease, true); + } + $ret .= " \n"; + } + $ret .= "\n"; + return $ret; + } + + // }}} + // {{{ _makeReleaseXml() + + /** + * Generate part of an XML description with release information. + * + * @param array $pkginfo array with release information + * @param bool $changelog whether the result will be in a changelog element + * + * @return string XML data + * + * @access private + */ + function _makeReleaseXml($pkginfo, $changelog = false) + { + // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! + $indent = $changelog ? " " : ""; + $ret = "$indent \n"; + if (!empty($pkginfo['version'])) { + $ret .= "$indent $pkginfo[version]\n"; + } + if (!empty($pkginfo['release_date'])) { + $ret .= "$indent $pkginfo[release_date]\n"; + } + if (!empty($pkginfo['release_license'])) { + $ret .= "$indent $pkginfo[release_license]\n"; + } + if (!empty($pkginfo['release_state'])) { + $ret .= "$indent $pkginfo[release_state]\n"; + } + if (!empty($pkginfo['release_notes'])) { + $ret .= "$indent ".htmlspecialchars($pkginfo['release_notes'])."\n"; + } + if (!empty($pkginfo['release_warnings'])) { + $ret .= "$indent ".htmlspecialchars($pkginfo['release_warnings'])."\n"; + } + if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { + $ret .= "$indent \n"; + foreach ($pkginfo['release_deps'] as $dep) { + $ret .= "$indent $what) { + $ret .= "$indent $fa) { + @$ret .= "$indent $v) { + $ret .= " $k=\"" . htmlspecialchars($v) .'"'; + } + $ret .= "/>\n"; + } + @$ret .= "$indent \n"; + } + } + $ret .= "$indent \n"; + } + $ret .= "$indent \n"; + return $ret; + } + + // }}} + // {{{ validatePackageInfo() + + /** + * Validate XML package definition file. + * + * @param string $info Filename of the package archive or of the + * package definition file + * @param array $errors Array that will contain the errors + * @param array $warnings Array that will contain the warnings + * @param string $dir_prefix (optional) directory where source files + * may be found, or empty if they are not available + * @access public + * @return boolean + */ + function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') + { + global $_PEAR_Common_maintainer_roles, + $_PEAR_Common_release_states, + $_PEAR_Common_dependency_types, + $_PEAR_Common_dependency_relations, + $_PEAR_Common_file_roles, + $_PEAR_Common_replacement_types; + if (PEAR::isError($info = $this->infoFromAny($info))) { + return $this->raiseError($info); + } + if (!is_array($info)) { + return false; + } + $errors = array(); + $warnings = array(); + if (empty($info['package'])) { + $errors[] = 'missing package name'; + } + if (empty($info['summary'])) { + $errors[] = 'missing summary'; + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $warnings[] = 'summary should be on a single line'; + } + if (empty($info['description'])) { + $errors[] = 'missing description'; + } + if (empty($info['release_license'])) { + $errors[] = 'missing license'; + } + if (empty($info['version'])) { + $errors[] = 'missing version'; + } + if (empty($info['release_state'])) { + $errors[] = 'missing release state'; + } elseif (!in_array($info['release_state'], $_PEAR_Common_release_states)) { + $errors[] = "invalid release state `$info[release_state]', should be one of: ".implode(' ', $_PEAR_Common_release_states); + } + if (empty($info['release_date'])) { + $errors[] = 'missing release date'; + } elseif (!preg_match('/^\d{4}-\d\d-\d\d$/', $info['release_date'])) { + $errors[] = "invalid release date `$info[release_date]', format is YYYY-MM-DD"; + } + if (empty($info['release_notes'])) { + $errors[] = "missing release notes"; + } + if (empty($info['maintainers'])) { + $errors[] = 'no maintainer(s)'; + } else { + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $errors[] = "maintainer $i: missing handle"; + } + if (empty($m['role'])) { + $errors[] = "maintainer $i: missing role"; + } elseif (!in_array($m['role'], $_PEAR_Common_maintainer_roles)) { + $errors[] = "maintainer $i: invalid role `$m[role]', should be one of: ".implode(' ', $_PEAR_Common_maintainer_roles); + } + if (empty($m['name'])) { + $errors[] = "maintainer $i: missing name"; + } + if (empty($m['email'])) { + $errors[] = "maintainer $i: missing email"; + } + $i++; + } + } + if (!empty($info['deps'])) { + $i = 1; + foreach ($info['deps'] as $d) { + if (empty($d['type'])) { + $errors[] = "depenency $i: missing type"; + } elseif (!in_array($d['type'], $_PEAR_Common_dependency_types)) { + $errors[] = "dependency $i: invalid type, should be one of: ".implode(' ', $_PEAR_Common_depenency_types); + } + if (empty($d['rel'])) { + $errors[] = "dependency $i: missing relation"; + } elseif (!in_array($d['rel'], $_PEAR_Common_dependency_relations)) { + $errors[] = "dependency $i: invalid relation, should be one of: ".implode(' ', $_PEAR_Common_dependency_relations); + } + if ($d['rel'] != 'has' && empty($d['version'])) { + $warnings[] = "dependency $i: missing version"; + } elseif ($d['rel'] == 'has' && !empty($d['version'])) { + $warnings[] = "dependency $i: version ignored for `has' dependencies"; + } + if ($d['type'] == 'php' && !empty($d['name'])) { + $warnings[] = "dependency $i: name ignored for php type dependencies"; + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $errors[] = "dependency $i: missing name"; + } + $i++; + } + } + if (!empty($info['configure_options'])) { + $i = 1; + foreach ($info['configure_options'] as $c) { + if (empty($c['name'])) { + $errors[] = "configure option $i: missing name"; + } + if (empty($c['prompt'])) { + $errors[] = "configure option $i: missing prompt"; + } + } + } + if (empty($info['filelist'])) { + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $errors[] = "file $file: missing role"; + continue; + } elseif (!in_array($fa['role'], $_PEAR_Common_file_roles)) { + $errors[] = "file $file: invalid role, should be one of: ".implode(' ', $_PEAR_Common_file_roles); + } + if ($fa['role'] == 'php' && $dir_prefix) { + $this->log(1, "Analyzing $file"); + $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->buildProvidesArray($srcinfo); + } + } + // (ssb) Any checks we can do for baseinstalldir? + // (cox) Perhaps checks that either the target dir and + // baseInstall doesn't cointain "../../" + } + } + $pn = $info['package']; + $pnl = strlen($pn); + foreach ((array)$this->pkginfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $warnings[] = "in $file: class \"$name\" not prefixed with package name \"$pn\""; + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $warnings[] = "in $file: function \"$name\" not prefixed with package name \"$pn\""; + } + //print "$file: provides $what[type] $what[name]\n"; + } + return true; + } + + // }}} + // {{{ buildProvidesArray() + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access public + * + */ + function buildProvidesArray($srcinfo) + { + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->pkginfo['provides'][$key])) { + continue; + } + $this->pkginfo['provides'][$key] = + array('type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->pkginfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->pkginfo['provides'][$key])) { + continue; + } + $this->pkginfo['provides'][$key] = + array('type' => 'function', 'name' => $function); + } + } + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { + continue; + } + $this->pkginfo['provides'][$key] = + array('type' => 'function', 'name' => $function); + } + } + + // }}} + // {{{ analyzeSourceCode() + + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access public + */ + function analyzeSourceCode($file) + { + if (!function_exists("token_get_all")) { + return false; + } + if (!$fp = @fopen($file, "r")) { + return false; + } + $contents = fread($fp, filesize($file)); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $nodeps = array(); + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + switch ($token) { + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_CLASS: + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + $look_for = $token; + continue 2; + case T_STRING: + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; + } + } + return array( + "declared_classes" => $declared_classes, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + ); + } + + // }}} + // {{{ detectDependencies() + + function detectDependencies($any, $status_callback = null) + { + if (!function_exists("token_get_all")) { + return false; + } + if (PEAR::isError($info = $this->infoFromAny($any))) { + return $this->raiseError($info); + } + if (!is_array($info)) { + return false; + } + $deps = array(); + $used_c = $decl_c = $decl_f = $decl_m = array(); + foreach ($info['filelist'] as $file => $fa) { + $tmp = $this->analyzeSourceCode($file); + $used_c = @array_merge($used_c, $tmp['used_classes']); + $decl_c = @array_merge($decl_c, $tmp['declared_classes']); + $decl_f = @array_merge($decl_f, $tmp['declared_functions']); + $decl_m = @array_merge($decl_m, $tmp['declared_methods']); + $inheri = @array_merge($inheri, $tmp['inheritance']); + } + $used_c = array_unique($used_c); + $decl_c = array_unique($decl_c); + $undecl_c = array_diff($used_c, $decl_c); + return array('used_classes' => $used_c, + 'declared_classes' => $decl_c, + 'declared_methods' => $decl_m, + 'declared_functions' => $decl_f, + 'undeclared_classes' => $undecl_c, + 'inheritance' => $inheri, + ); + } + + // }}} + // {{{ getUserRoles() + + /** + * Get the valid roles for a PEAR package maintainer + * + * @return array + * @static + */ + function getUserRoles() + { + return $GLOBALS['_PEAR_Common_maintainer_roles']; + } + + // }}} + // {{{ getReleaseStates() + + /** + * Get the valid package release states of packages + * + * @return array + * @static + */ + function getReleaseStates() + { + return $GLOBALS['_PEAR_Common_release_states']; + } + + // }}} + // {{{ getDependencyTypes() + + /** + * Get the implemented dependency types (php, ext, pkg etc.) + * + * @return array + * @static + */ + function getDependencyTypes() + { + return $GLOBALS['_PEAR_Common_dependency_types']; + } + + // }}} + // {{{ getDependencyRelations() + + /** + * Get the implemented dependency relations (has, lt, ge etc.) + * + * @return array + * @static + */ + function getDependencyRelations() + { + return $GLOBALS['_PEAR_Common_dependency_relations']; + } + + // }}} + // {{{ getFileRoles() + + /** + * Get the implemented file roles + * + * @return array + * @static + */ + function getFileRoles() + { + return $GLOBALS['_PEAR_Common_file_roles']; + } + + // }}} + // {{{ getReplacementTypes() + + /** + * Get the implemented file replacement types in + * + * @return array + * @static + */ + function getReplacementTypes() + { + return $GLOBALS['_PEAR_Common_replacement_types']; + } + + // }}} + // {{{ getProvideTypes() + + /** + * Get the implemented file replacement types in + * + * @return array + * @static + */ + function getProvideTypes() + { + return $GLOBALS['_PEAR_Common_provide_types']; + } + + // }}} + // {{{ getScriptPhases() + + /** + * Get the implemented file replacement types in + * + * @return array + * @static + */ + function getScriptPhases() + { + return $GLOBALS['_PEAR_Common_script_phases']; + } + + // }}} + // {{{ validPackageName() + + /** + * Test whether a string contains a valid package name. + * + * @param string $name the package name to test + * + * @return bool + * + * @access public + */ + function validPackageName($name) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); + } + + + // }}} + + // {{{ downloadHttp() + + /** + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir (optional) directory to save file in + * @param mixed $callback (optional) function/method to call for status + * updates + * + * @return string Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). + * + * @access public + */ + function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) + { + if ($callback) { + call_user_func($callback, 'setup', array(&$ui)); + } + if (preg_match('!^http://([^/:?#]*)(:(\d+))?(/.*)!', $url, $matches)) { + list(,$host,,$port,$path) = $matches; + } + if (isset($this)) { + $config = &$this->config; + } else { + $config = &PEAR_Config::singleton(); + } + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($proxy = parse_url($config->get('http_proxy'))) { + $proxy_host = @$proxy['host']; + $proxy_port = @$proxy['port']; + $proxy_user = @$proxy['user']; + $proxy_pass = @$proxy['pass']; + + if ($proxy_port == '') { + $proxy_port = 8080; + } + if ($callback) { + call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); + } + } + if (empty($port)) { + $port = 80; + } + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); + } + $request = "GET $url HTTP/1.0\r\n"; + } else { + $fp = @fsockopen($host, $port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($host, $port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + $request = "GET $path HTTP/1.0\r\n"; + } + $request .= "Host: $host:$port\r\n". + "User-Agent: PHP/".PHP_VERSION."\r\n"; + if ($proxy_host != '' && $proxy_user != '') { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; + } + $request .= "\r\n"; + fwrite($fp, $request); + $headers = array(); + while (trim($line = fgets($fp, 1024))) { + if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) { + $headers[strtolower($matches[1])] = trim($matches[2]); + } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { + if ($matches[1] != 200) { + return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)"); + } + } + } + if (isset($headers['content-disposition']) && + preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) { + $save_as = basename($matches[1]); + } else { + $save_as = basename($url); + } + if ($callback) { + $tmp = call_user_func($callback, 'saveas', $save_as); + if ($tmp) { + $save_as = $tmp; + } + } + $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; + if (!$wp = @fopen($dest_file, 'wb')) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("could not open $dest_file for writing"); + } + if (isset($headers['content-length'])) { + $length = $headers['content-length']; + } else { + $length = -1; + } + $bytes = 0; + if ($callback) { + call_user_func($callback, 'start', $length); + } + while ($data = @fread($fp, 1024)) { + $bytes += strlen($data); + if ($callback) { + call_user_func($callback, 'bytesread', $bytes); + } + if (!@fwrite($wp, $data)) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); + } + } + fclose($fp); + fclose($wp); + if ($callback) { + call_user_func($callback, 'done', $bytes); + } + return $dest_file; + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Config.php b/gulliver/thirdparty/pear/PEAR/Config.php new file mode 100644 index 000000000..6cc2e40f4 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Config.php @@ -0,0 +1,1139 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Config.php,v 1.43 2003/03/18 12:06:06 ssb Exp $ + +require_once 'PEAR.php'; +require_once 'System.php'; + +/** + * Last created PEAR_Config instance. + * @var object + */ +$GLOBALS['_PEAR_Config_instance'] = null; + +// Below we define constants with default values for all configuration +// parameters except username/password. All of them can have their +// defaults set through environment variables. The reason we use the +// PHP_ prefix is for some security, PHP protects environment +// variables starting with PHP_*. + +if (getenv('PHP_PEAR_SYSCONF_DIR')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); +} elseif (getenv('SystemRoot')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); +} else { + define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); +} + +// Default for master_server +if (getenv('PHP_PEAR_MASTER_SERVER')) { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); +} else { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); +} + +// Default for http_proxy +if (getenv('PHP_PEAR_HTTP_PROXY')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); +} elseif (getenv('http_proxy')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); +} else { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); +} + +// Default for php_dir +if (getenv('PHP_PEAR_INSTALL_DIR')) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); +} else { + if (@is_dir(PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'lib')) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', + PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'lib'); + } else { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', PEAR_INSTALL_DIR); + } +} + +// Default for ext_dir +if (getenv('PHP_PEAR_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); +} + +// Default for doc_dir +if (getenv('PHP_PEAR_DOC_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', + PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); +} + +// Default for bin_dir +if (getenv('PHP_PEAR_BIN_DIR')) { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); +} + +// Default for data_dir +if (getenv('PHP_PEAR_DATA_DIR')) { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', + PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); +} + +// Default for test_dir +if (getenv('PHP_PEAR_TEST_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', + PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); +} + +// Default for cache_dir +if (getenv('PHP_PEAR_CACHE_DIR')) { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'cache'); +} + +// Default for php_bin +if (getenv('PHP_PEAR_PHP_BIN')) { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. + DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); +} + +// Default for verbose +if (getenv('PHP_PEAR_VERBOSE')) { + define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); +} else { + define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); +} + +// Default for preferred_state +if (getenv('PHP_PEAR_PREFERRED_STATE')) { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); +} else { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); +} + +// Default for umask +if (getenv('PHP_PEAR_UMASK')) { + define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); +} else { + define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); +} + +// Default for cache_ttl +if (getenv('PHP_PEAR_CACHE_TTL')) { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); +} + +// Default for sig_type +if (getenv('PHP_PEAR_SIG_TYPE')) { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); +} + +// Default for sig_bin +if (getenv('PHP_PEAR_SIG_BIN')) { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', + System::which( + 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); +} + +// Default for sig_keydir +if (getenv('PHP_PEAR_SIG_KEYDIR')) { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', + PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); +} + +/** + * This is a class for storing configuration data, keeping track of + * which are system-defined, user-defined or defaulted. + */ +class PEAR_Config extends PEAR +{ + // {{{ properties + + /** + * Array of config files used. + * + * @var array layer => config file + */ + var $files = array( + 'system' => '', + 'user' => '', + ); + + var $layers = array(); + + /** + * Configuration data, two-dimensional array where the first + * dimension is the config layer ('user', 'system' and 'default'), + * and the second dimension is keyname => value. + * + * The order in the first dimension is important! Earlier + * layers will shadow later ones when a config value is + * requested (if a 'user' value exists, it will be returned first, + * then 'system' and finally 'default'). + * + * @var array layer => array(keyname => value, ...) + */ + var $configuration = array( + 'user' => array(), + 'system' => array(), + 'default' => array(), + ); + + /** + * Information about the configuration data. Stores the type, + * default value and a documentation string for each configuration + * value. + * + * @var array layer => array(infotype => value, ...) + */ + var $configuration_info = array( + // Internet Access + 'master_server' => array( + 'type' => 'string', + 'default' => 'pear.php.net', + 'doc' => 'name of the main PEAR server', + 'prompt' => 'PEAR server', + 'group' => 'Internet Access', + ), + 'http_proxy' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, + 'doc' => 'HTTP proxy (host:port) to use when downloading packages', + 'prompt' => 'HTTP Proxy Server Address', + 'group' => 'Internet Access', + ), + // File Locations + 'php_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, + 'doc' => 'directory where .php files are installed', + 'prompt' => 'PEAR directory', + 'group' => 'File Locations', + ), + 'ext_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, + 'doc' => 'directory where loadable extensions are installed', + 'prompt' => 'PHP extension directory', + 'group' => 'File Locations', + ), + 'doc_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, + 'doc' => 'directory where documentation is installed', + 'prompt' => 'PEAR documentation directory', + 'group' => 'File Locations', + ), + 'bin_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, + 'doc' => 'directory where executables are installed', + 'prompt' => 'PEAR executables directory', + 'group' => 'File Locations', + ), + 'data_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, + 'doc' => 'directory where data files are installed', + 'prompt' => 'PEAR data directory', + 'group' => 'File Locations (Advanced)', + ), + 'test_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, + 'doc' => 'directory where regression tests are installed', + 'prompt' => 'PEAR test directory', + 'group' => 'File Locations (Advanced)', + ), + 'cache_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, + 'doc' => 'directory which is used for XMLRPC cache', + 'prompt' => 'PEAR Installer cache directory', + 'group' => 'File Locations (Advanced)', + ), + 'php_bin' => array( + 'type' => 'file', + 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, + 'doc' => 'PHP CLI/CGI binary for executing scripts', + 'prompt' => 'PHP CLI/CGI binary', + 'group' => 'File Locations (Advanced)', + ), + // Maintainers + 'username' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '(maintainers) your PEAR account name', + 'prompt' => 'PEAR username (for maintainers)', + 'group' => 'Maintainers', + ), + 'password' => array( + 'type' => 'password', + 'default' => '', + 'doc' => '(maintainers) your PEAR account password', + 'prompt' => 'PEAR password (for maintainers)', + 'group' => 'Maintainers', + ), + // Advanced + 'verbose' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, + 'doc' => 'verbosity level +0: really quiet +1: somewhat quiet +2: verbose +3: debug', + 'prompt' => 'Debug Log Level', + 'group' => 'Advanced', + ), + 'preferred_state' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, + 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', + 'valid_set' => array( + 'stable', 'beta', 'alpha', 'devel', 'snapshot'), + 'prompt' => 'Preferred Package State', + 'group' => 'Advanced', + ), + 'umask' => array( + 'type' => 'mask', + 'default' => PEAR_CONFIG_DEFAULT_UMASK, + 'doc' => 'umask used when creating files (Unix-like systems only)', + 'prompt' => 'Unix file mask', + 'group' => 'Advanced', + ), + 'cache_ttl' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, + 'doc' => 'amount of secs where the local cache is used and not updated', + 'prompt' => 'Cache TimeToLive', + 'group' => 'Advanced', + ), + 'sig_type' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, + 'doc' => 'which package signature mechanism to use', + 'valid_set' => array('gpg'), + 'prompt' => 'Package Signature Type', + 'group' => 'Maintainers', + ), + 'sig_bin' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, + 'doc' => 'which package signature mechanism to use', + 'prompt' => 'Signature Handling Program', + 'group' => 'Maintainers', + ), + 'sig_keyid' => array( + 'type' => 'string', + 'default' => '', + 'doc' => 'which key to use for signing with', + 'prompt' => 'Signature Key Id', + 'group' => 'Maintainers', + ), + 'sig_keydir' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, + 'doc' => 'which package signature mechanism to use', + 'prompt' => 'Signature Key Directory', + 'group' => 'Maintainers', + ), + ); + + // }}} + + // {{{ PEAR_Config([file], [defaults_file]) + + /** + * Constructor. + * + * @param string (optional) file to read user-defined options from + * @param string (optional) file to read system-wide defaults from + * + * @access public + * + * @see PEAR_Config::singleton + */ + function PEAR_Config($user_file = '', $system_file = '') + { + $this->PEAR(); + $sl = DIRECTORY_SEPARATOR; + if (empty($user_file)) { + if (OS_WINDOWS) { + $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; + } else { + $user_file = getenv('HOME') . $sl . '.pearrc'; + } + } + if (empty($system_file)) { + if (OS_WINDOWS) { + $system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'; + } else { + $system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'; + } + } + $this->layers = array_keys($this->configuration); + $this->files['user'] = $user_file; + $this->files['system'] = $system_file; + if ($user_file && file_exists($user_file)) { + $this->readConfigFile($user_file); + } + if ($system_file && file_exists($system_file)) { + $this->mergeConfigFile($system_file, false, 'system'); + } + foreach ($this->configuration_info as $key => $info) { + $this->configuration['default'][$key] = $info['default']; + } + //$GLOBALS['_PEAR_Config_instance'] = &$this; + } + + // }}} + // {{{ singleton([file], [defaults_file]) + + /** + * Static singleton method. If you want to keep only one instance + * of this class in use, this method will give you a reference to + * the last created PEAR_Config object if one exists, or create a + * new object. + * + * @param string (optional) file to read user-defined options from + * @param string (optional) file to read system-wide defaults from + * + * @return object an existing or new PEAR_Config instance + * + * @access public + * + * @see PEAR_Config::PEAR_Config + */ + function &singleton($user_file = '', $system_file = '') + { + if (is_object($GLOBALS['_PEAR_Config_instance'])) { + return $GLOBALS['_PEAR_Config_instance']; + } + $GLOBALS['_PEAR_Config_instance'] = + &new PEAR_Config($user_file, $system_file); + return $GLOBALS['_PEAR_Config_instance']; + } + + // }}} + // {{{ readConfigFile([file], [layer]) + + /** + * Reads configuration data from a file. All existing values in + * the config layer are discarded and replaced with data from the + * file. + * + * @param string (optional) file to read from, if NULL or not + * specified, the last-used file for the same layer (second param) + * is used + * + * @param string (optional) config layer to insert data into + * ('user' or 'system') + * + * @return bool TRUE on success or a PEAR error on failure + * + * @access public + */ + function readConfigFile($file = null, $layer = 'user') + { + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } + if ($file === null) { + $file = $this->files[$layer]; + } + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + return $data; + } + $this->_decodeInput($data); + $this->configuration[$layer] = $data; + return true; + } + + // }}} + // {{{ mergeConfigFile(file, [override], [layer]) + + /** + * Merges data into a config layer from a file. Does the same + * thing as readConfigFile, except it does not replace all + * existing values in the config layer. + * + * @param string file to read from + * + * @param bool (optional) whether to overwrite existing data + * (default TRUE) + * + * @param string config layer to insert data into ('user' or + * 'system') + * + * @return bool TRUE on success or a PEAR error on failure + * + * @access public. + */ + function mergeConfigFile($file, $override = true, $layer = 'user') + { + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } + if ($file === null) { + $file = $this->files[$layer]; + } + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + return $data; + } + $this->_decodeInput($data); + if ($override) { + $this->configuration[$layer] = array_merge($this->configuration[$layer], $data); + } else { + $this->configuration[$layer] = array_merge($data, $this->configuration[$layer]); + } + return true; + } + + // }}} + // {{{ writeConfigFile([file], [layer]) + + /** + * Writes data into a config layer from a file. + * + * @param string file to read from + * + * @param bool (optional) whether to overwrite existing data + * (default TRUE) + * + * @param string config layer to insert data into ('user' or + * 'system') + * + * @return bool TRUE on success or a PEAR error on failure + * + * @access public. + */ + function writeConfigFile($file = null, $layer = 'user') + { + if ($layer == 'both' || $layer == 'all') { + foreach ($this->files as $type => $file) { + $err = $this->writeConfigFile($file, $type); + if (PEAR::isError($err)) { + return $err; + } + } + return true; + } + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } + if ($file === null) { + $file = $this->files[$layer]; + } + $data = $this->configuration[$layer]; + $this->_encodeOutput($data); + if (!@System::mkDir("-p " . dirname($file))) { + return $this->raiseError("could not create directory: " . dirname($file)); + } + if (@is_file($file) && !@is_writeable($file)) { + return $this->raiseError("no write access to $file!"); + } + $fp = @fopen($file, "w"); + if (!$fp) { + return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed"); + } + $contents = "#PEAR_Config 0.9\n" . serialize($data); + if (!@fwrite($fp, $contents)) { + return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed"); + } + return true; + } + + // }}} + // {{{ _readConfigDataFrom(file) + + /** + * Reads configuration data from a file and returns the parsed data + * in an array. + * + * @param string file to read from + * + * @return array configuration data or a PEAR error on failure + * + * @access private + */ + function _readConfigDataFrom($file) + { + $fp = @fopen($file, "r"); + if (!$fp) { + return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); + } + $size = filesize($file); + $contents = fread($fp, $size); + fclose($fp); + $version = '0.1'; + if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { + $version = $matches[1]; + $contents = substr($contents, strlen($matches[0])); + } + if (version_compare("$version", '1', '<')) { + $data = unserialize($contents); + if (!is_array($data)) { + if (strlen(trim($contents)) > 0) { + $error = "PEAR_Config: bad data in $file"; +// if (isset($this)) { + return $this->raiseError($error); +// } else { +// return PEAR::raiseError($error); + } else { + $data = array(); + } + } + // add parsing of newer formats here... + } else { + return $this->raiseError("$file: unknown version `$version'"); + } + return $data; + } + + // }}} + // {{{ _encodeOutput(&data) + + /** + * Encodes/scrambles configuration data before writing to files. + * Currently, 'password' values will be base64-encoded as to avoid + * that people spot cleartext passwords by accident. + * + * @param array (reference) array to encode values in + * + * @return bool TRUE on success + * + * @access private + */ + function _encodeOutput(&$data) + { + foreach ($data as $key => $value) { + if (!isset($this->configuration_info[$key])) { + continue; + } + $type = $this->configuration_info[$key]['type']; + switch ($type) { + // we base64-encode passwords so they are at least + // not shown in plain by accident + case 'password': { + $data[$key] = base64_encode($data[$key]); + break; + } + case 'mask': { + $data[$key] = octdec($data[$key]); + break; + } + } + } + return true; + } + + // }}} + // {{{ _decodeInput(&data) + + /** + * Decodes/unscrambles configuration data after reading from files. + * + * @param array (reference) array to encode values in + * + * @return bool TRUE on success + * + * @access private + * + * @see PEAR_Config::_encodeOutput + */ + function _decodeInput(&$data) + { + if (!is_array($data)) { + return true; + } + foreach ($data as $key => $value) { + if (!isset($this->configuration_info[$key])) { + continue; + } + $type = $this->configuration_info[$key]['type']; + switch ($type) { + case 'password': { + $data[$key] = base64_decode($data[$key]); + break; + } + case 'mask': { + $data[$key] = decoct($data[$key]); + break; + } + } + } + return true; + } + + // }}} + // {{{ get(key, [layer]) + + /** + * Returns a configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * + * @return mixed the config value, or NULL if not found + * + * @access public + */ + function get($key, $layer = null) + { + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return $this->configuration[$layer][$key]; + } + } + } elseif (isset($this->configuration[$layer][$key])) { + return $this->configuration[$layer][$key]; + } + return null; + } + + // }}} + // {{{ set(key, value, [layer]) + + /** + * Set a config value in a specific layer (defaults to 'user'). + * Enforces the types defined in the configuration_info array. An + * integer config variable will be cast to int, and a set config + * variable will be validated against its legal values. + * + * @param string config key + * + * @param string config value + * + * @param string (optional) config layer + * + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function set($key, $value, $layer = 'user') + { + if (empty($this->configuration_info[$key])) { + return false; + } + extract($this->configuration_info[$key]); + switch ($type) { + case 'integer': + $value = (int)$value; + break; + case 'set': { + // If a valid_set is specified, require the value to + // be in the set. If there is no valid_set, accept + // any value. + if ($valid_set) { + reset($valid_set); + if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || + (key($valid_set) !== 0 && empty($valid_set[$value]))) + { + return false; + } + } + break; + } + } + $this->configuration[$layer][$key] = $value; + return true; + } + + // }}} + // {{{ getType(key) + + /** + * Get the type of a config value. + * + * @param string config key + * + * @return string type, one of "string", "integer", "file", + * "directory", "set" or "password". + * + * @access public + * + */ + function getType($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['type']; + } + return false; + } + + // }}} + // {{{ getDocs(key) + + /** + * Get the documentation for a config value. + * + * @param string config key + * + * @return string documentation string + * + * @access public + * + */ + function getDocs($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['doc']; + } + return false; + } + // }}} + // {{{ getPrompt(key) + + /** + * Get the short documentation for a config value. + * + * @param string config key + * + * @return string short documentation string + * + * @access public + * + */ + function getPrompt($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['prompt']; + } + return false; + } + // }}} + // {{{ getGroup(key) + + /** + * Get the parameter group for a config key. + * + * @param string config key + * + * @return string parameter group + * + * @access public + * + */ + function getGroup($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['group']; + } + return false; + } + + // }}} + // {{{ getGroups() + + /** + * Get the list of parameter groups. + * + * @return array list of parameter groups + * + * @access public + * + */ + function getGroups() + { + $tmp = array(); + foreach ($this->configuration_info as $key => $info) { + $tmp[$info['group']] = 1; + } + return array_keys($tmp); + } + + // }}} + // {{{ getGroupKeys() + + /** + * Get the list of the parameters in a group. + * + * @param string $group parameter group + * + * @return array list of parameters in $group + * + * @access public + * + */ + function getGroupKeys($group) + { + $keys = array(); + foreach ($this->configuration_info as $key => $info) { + if ($info['group'] == $group) { + $keys[] = $key; + } + } + return $keys; + } + + // }}} + // {{{ getSetValues(key) + + /** + * Get the list of allowed set values for a config value. Returns + * NULL for config values that are not sets. + * + * @param string config key + * + * @return array enumerated array of set values, or NULL if the + * config key is unknown or not a set + * + * @access public + * + */ + function getSetValues($key) + { + if (isset($this->configuration_info[$key]) && + isset($this->configuration_info[$key]['type']) && + $this->configuration_info[$key]['type'] == 'set') + { + $valid_set = $this->configuration_info[$key]['valid_set']; + reset($valid_set); + if (key($valid_set) === 0) { + return $valid_set; + } + return array_keys($valid_set); + } + return false; + } + + // }}} + // {{{ getKeys() + + /** + * Get all the current config keys. + * + * @return array simple array of config keys + * + * @access public + */ + function getKeys() + { + $keys = array(); + foreach ($this->layers as $layer) { + $keys = array_merge($keys, $this->configuration[$layer]); + } + return array_keys($keys); + } + + // }}} + // {{{ remove(key, [layer]) + + /** + * Remove the a config key from a specific config layer. + * + * @param string config key + * + * @param string (optional) config layer + * + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function remove($key, $layer = 'user') + { + if (isset($this->configuration[$layer][$key])) { + unset($this->configuration[$layer][$key]); + return true; + } + return false; + } + + // }}} + // {{{ removeLayer(layer) + + /** + * Temporarily remove an entire config layer. USE WITH CARE! + * + * @param string config key + * + * @param string (optional) config layer + * + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function removeLayer($layer) + { + if (isset($this->configuration[$layer])) { + unset($this->configuration[$layer]); + return true; + } + return false; + } + + // }}} + // {{{ store([layer]) + + /** + * Stores configuration data in a layer. + * + * @param string config layer to store + * + * @return bool TRUE on success, or PEAR error on failure + * + * @access public + */ + function store($layer = 'user') + { + return $this->writeConfigFile(null, $layer); + } + + // }}} + // {{{ toDefault(key) + + /** + * Unset the user-defined value of a config key, reverting the + * value to the system-defined one. + * + * @param string config key + * + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function toDefault($key) + { + trigger_error("PEAR_Config::toDefault() deprecated, use PEAR_Config::remove() instead", E_USER_NOTICE); + return $this->remove($key, 'user'); + } + + // }}} + // {{{ definedBy(key) + + /** + * Tells what config layer that gets to define a key. + * + * @param string config key + * + * @return string the config layer, or an empty string if not found + * + * @access public + */ + function definedBy($key) + { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return $layer; + } + } + return ''; + } + + // }}} + // {{{ isDefaulted(key) + + /** + * Tells whether a config value has a system-defined value. + * + * @param string config key + * + * @return bool + * + * @access public + * + * @deprecated + */ + function isDefaulted($key) + { + trigger_error("PEAR_Config::isDefaulted() deprecated, use PEAR_Config::definedBy() instead", E_USER_NOTICE); + return $this->definedBy($key) == 'system'; + } + + // }}} + // {{{ isDefined(key) + + /** + * Tells whether a given key exists as a config value. + * + * @param string config key + * + * @return bool whether exists in this object + * + * @access public + */ + function isDefined($key) + { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return true; + } + } + return false; + } + + // }}} + // {{{ isDefinedLayer(key) + + /** + * Tells whether a given config layer exists. + * + * @param string config layer + * + * @return bool whether exists in this object + * + * @access public + */ + function isDefinedLayer($layer) + { + return isset($this->configuration[$layer]); + } + + // }}} + // {{{ getLayers() + + /** + * Returns the layers defined (except the 'default' one) + * + * @return array of the defined layers + */ + function getLayers() + { + $cf = $this->configuration; + unset($cf['default']); + return array_keys($cf); + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Dependency.php b/gulliver/thirdparty/pear/PEAR/Dependency.php new file mode 100644 index 000000000..b4ae1599f --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Dependency.php @@ -0,0 +1,356 @@ + | +// | Stig Bakken | +// +----------------------------------------------------------------------+ +// +// $Id: Dependency.php,v 1.20 2003/05/15 19:44:32 mj Exp $ + +require_once "PEAR.php"; + +define('PEAR_DEPENDENCY_MISSING', -1); +define('PEAR_DEPENDENCY_CONFLICT', -2); +define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3); +define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4); +define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5); + +/** + * Dependency check for PEAR packages + * + * The class is based on the dependency RFC that can be found at + * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1 + * + * @author Tomas V.V.Vox + * @author Stig Bakken + */ +class PEAR_Dependency +{ + /** + * Constructor + * + * @access public + * @param object Registry object + * @return void + */ + function PEAR_Dependency(&$registry) + { + $this->registry = &$registry; + } + + /** + * This method maps the XML dependency definition to the + * corresponding one from PEAR_Dependency + * + * $opts => Array + * ( + * [type] => pkg + * [rel] => ge + * [version] => 3.4 + * [name] => HTML_Common + * ) + * + * @param string Error message + * @param array Options + * @return boolean + */ + function callCheckMethod(&$errmsg, $opts) + { + $rel = isset($opts['rel']) ? $opts['rel'] : 'has'; + $req = isset($opts['version']) ? $opts['version'] : null; + $name = isset($opts['name']) ? $opts['name'] : null; + $errmsg = ''; + switch ($opts['type']) { + case 'pkg': + return $this->checkPackage($errmsg, $name, $req, $rel); + break; + case 'ext': + return $this->checkExtension($errmsg, $name, $req, $rel); + break; + case 'php': + return $this->checkPHP($errmsg, $req, $rel); + break; + case 'prog': + return $this->checkProgram($errmsg, $name); + break; + case 'os': + return $this->checkOS($errmsg, $name); + break; + case 'sapi': + return $this->checkSAPI($errmsg, $name); + break; + case 'zend': + return $this->checkZend($errmsg, $name); + break; + default: + return "'{$opts['type']}' dependency type not supported"; + } + } + + /** + * Package dependencies check method + * + * @param string $name Name of the package to test + * @param string $version The package version required + * @param string $relation How to compare versions with eachother + * + * @return mixed bool false if no error or the error string + */ + function checkPackage(&$errmsg, $name, $req = null, $relation = 'has') + { + if (substr($relation, 0, 2) == 'v.') { + $relation = substr($relation, 2); + } + switch ($relation) { + case 'has': + if (!$this->registry->packageExists($name)) { + $errmsg = "requires package `$name'"; + return PEAR_DEPENDENCY_MISSING; + } + return false; + case 'not': + if (!$this->registry->packageExists($name)) { + $errmsg = "conflicts with package `$name'"; + return PEAR_DEPENDENCY_CONFLICT; + } + return false; + case 'lt': + case 'le': + case 'eq': + case 'ne': + case 'ge': + case 'gt': + $version = $this->registry->packageInfo($name, 'version'); + if (!$this->registry->packageExists($name) + || !version_compare("$version", "$req", $relation)) + { + $errmsg = "requires package `$name' " . + $this->signOperator($relation) . " $req"; + $code = $this->codeFromRelation($relation, $version, $req); + } + return false; + } + $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$name)"; + return PEAR_DEPENDENCY_BAD_DEPENDENCY; + } + + /** + * Extension dependencies check method + * + * @param string $name Name of the extension to test + * @param string $req_ext_ver Required extension version to compare with + * @param string $relation How to compare versions with eachother + * + * @return mixed bool false if no error or the error string + */ + function checkExtension(&$errmsg, $name, $req = null, $relation = 'has') + { + // XXX (ssb): could we avoid loading the extension here? + if (!PEAR::loadExtension($name)) { + $errmsg = "'$name' PHP extension is not installed"; + return PEAR_DEPENDENCY_MISSING; + } + if ($relation == 'has') { + return false; + } + $code = false; + if (substr($relation, 0, 2) == 'v.') { + $ext_ver = phpversion($name); + $operator = substr($relation, 2); + // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90) + settype($req, "string"); + if (!version_compare("$ext_ver", "$req", $operator)) { + $retval = "'$name' PHP extension version " . + $this->signOperator($operator) . " $req is required"; + $code = $this->codeFromRelation($relation, $ext_ver, $req); + } + } + return $code; + } + + /** + * Operating system dependencies check method + * + * @param string $os Name of the operating system + * + * @return mixed bool false if no error or the error string + */ + function checkOS(&$errmsg, $os) + { + // XXX Fixme: Implement a more flexible way, like + // comma separated values or something similar to PEAR_OS + static $myos; + if (empty($myos)) { + include_once "OS/Guess.php"; + $myos = new OS_Guess(); + } + // only 'has' relation is currently supported + if ($myos->matchSignature($os)) { + return false; + } + $errmsg = "'$os' operating system not supported"; + return PEAR_DEPENDENCY_CONFLICT; + } + + /** + * PHP version check method + * + * @param string $req which version to compare + * @param string $relation how to compare the version + * + * @return mixed bool false if no error or the error string + */ + function checkPHP(&$errmsg, $req, $relation = 'ge') + { + if (substr($req, 0, 2) == 'v.') { + $req = substr($req,2, strlen($req) - 2); + } + $php_ver = phpversion(); + $operator = substr($relation,0,2); + if (!version_compare("$php_ver", "$req", $operator)) { + $errmsg = "PHP version " . $this->signOperator($operator) . + " $req is required"; + return PEAR_DEPENDENCY_CONFLICT; + } + return false; + } + + /** + * External program check method. Looks for executable files in + * directories listed in the PATH environment variable. + * + * @param string $program which program to look for + * + * @return mixed bool false if no error or the error string + */ + function checkProgram(&$errmsg, $program) + { + // XXX FIXME honor safe mode + $path_delim = OS_WINDOWS ? ';' : ':'; + $exe_suffix = OS_WINDOWS ? '.exe' : ''; + $path_elements = explode($path_delim, getenv('PATH')); + foreach ($path_elements as $dir) { + $file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix; + if (@file_exists($file) && @is_executable($file)) { + return false; + } + } + $errmsg = "'$program' program is not present in the PATH"; + return PEAR_DEPENDENCY_MISSING; + } + + /** + * SAPI backend check method. Version comparison is not yet + * available here. + * + * @param string $name name of SAPI backend + * @param string $req which version to compare + * @param string $relation how to compare versions (currently + * hardcoded to 'has') + * @return mixed bool false if no error or the error string + */ + function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has') + { + // XXX Fixme: There is no way to know if the user has or + // not other SAPI backends installed than the installer one + + $sapi_backend = php_sapi_name(); + // Version comparisons not supported, sapi backends don't have + // version information yet. + if ($sapi_backend == $name) { + return false; + } + $errmsg = "'$sapi_backend' SAPI backend not supported"; + return PEAR_DEPENDENCY_CONFLICT; + } + + + /** + * Zend version check method + * + * @param string $req which version to compare + * @param string $relation how to compare the version + * + * @return mixed bool false if no error or the error string + */ + function checkZend(&$errmsg, $req, $relation = 'ge') + { + if (substr($req, 0, 2) == 'v.') { + $req = substr($req,2, strlen($req) - 2); + } + $zend_ver = zend_version(); + $operator = substr($relation,0,2); + if (!version_compare("$zend_ver", "$req", $operator)) { + $errmsg = "Zend version " . $this->signOperator($operator) . + " $req is required"; + return PEAR_DEPENDENCY_CONFLICT; + } + return false; + } + + /** + * Converts text comparing operators to them sign equivalents + * + * Example: 'ge' to '>=' + * + * @access public + * @param string Operator + * @return string Sign equivalent + */ + function signOperator($operator) + { + switch($operator) { + case 'lt': return '<'; + case 'le': return '<='; + case 'gt': return '>'; + case 'ge': return '>='; + case 'eq': return '=='; + case 'ne': return '!='; + default: + return $operator; + } + } + + /** + * Convert relation into corresponding code + * + * @access public + * @param string Relation + * @param string Version + * @param string Requirement + * @return integer + */ + function codeFromRelation($relation, $version, $req) + { + $code = PEAR_DEPENDENCY_BAD_DEPENDENCY; + switch ($relation) { + case 'gt': case 'ge': case 'eq': + // upgrade + $have_major = preg_replace('/\D.*/', '', $version); + $need_major = preg_replace('/\D.*/', '', $req); + if ($need_major > $have_major) { + $code = PEAR_DEPENDENCY_UPGRADE_MAJOR; + } else { + $code = PEAR_DEPENDENCY_UPGRADE_MINOR; + } + break; + case 'lt': case 'le': case 'ne': + $code = PEAR_DEPENDENCY_CONFLICT; + break; + } + return $code; + } +} +?> diff --git a/gulliver/thirdparty/pear/PEAR/Frontend/CLI.php b/gulliver/thirdparty/pear/PEAR/Frontend/CLI.php new file mode 100644 index 000000000..55ee979eb --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Frontend/CLI.php @@ -0,0 +1,487 @@ + | + +----------------------------------------------------------------------+ + + $Id: CLI.php,v 1.31 2003/04/03 23:12:40 ssb Exp $ +*/ + +require_once "PEAR.php"; + +class PEAR_Frontend_CLI extends PEAR +{ + // {{{ properties + + /** + * What type of user interface this frontend is for. + * @var string + * @access public + */ + var $type = 'CLI'; + var $lp = ''; // line prefix + + var $params = array(); + var $term = array( + 'bold' => '', + 'normal' => '', + ); + + // }}} + + // {{{ constructor + + function PEAR_Frontend_CLI() + { + parent::PEAR(); + $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 + if ($term) { + // XXX can use ncurses extension here, if available + if (preg_match('/^(xterm|vt220|linux)/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); + $this->term['normal']=sprintf("%c%c%c", 27, 91, 109); + } elseif (preg_match('/^vt100/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); + $this->term['normal']=sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); + } + } elseif (OS_WINDOWS) { + // XXX add ANSI codes here + } + } + + // }}} + + // {{{ displayLine(text) + + function displayLine($text) + { + trigger_error("PEAR_Frontend_CLI::displayLine deprecated", E_USER_ERROR); + } + + function _displayLine($text) + { + print "$this->lp$text\n"; + } + + // }}} + // {{{ display(text) + + function display($text) + { + trigger_error("PEAR_Frontend_CLI::display deprecated", E_USER_ERROR); + } + + function _display($text) + { + print $text; + } + + // }}} + // {{{ displayError(eobj) + + function displayError($eobj) + { + return $this->_displayLine($eobj->getMessage()); + } + + // }}} + // {{{ displayFatalError(eobj) + + function displayFatalError($eobj) + { + $this->displayError($eobj); + exit(1); + } + + // }}} + // {{{ displayHeading(title) + + function displayHeading($title) + { + trigger_error("PEAR_Frontend_CLI::displayHeading deprecated", E_USER_ERROR); + } + + function _displayHeading($title) + { + print $this->lp.$this->bold($title)."\n"; + print $this->lp.str_repeat("=", strlen($title))."\n"; + } + + // }}} + // {{{ userDialog(prompt, [type], [default]) + + function userDialog($command, $prompts, $types = array(), $defaults = array()) + { + $result = array(); + if (is_array($prompts)) { + $fp = fopen("php://stdin", "r"); + foreach ($prompts as $key => $prompt) { + $type = $types[$key]; + $default = @$defaults[$key]; + if ($type == 'password') { + system('stty -echo'); + } + print "$this->lp$prompt "; + if ($default) { + print "[$default] "; + } + print ": "; + $line = fgets($fp, 2048); + if ($type == 'password') { + system('stty echo'); + print "\n"; + } + if ($default && trim($line) == "") { + $result[$key] = $default; + } else { + $result[$key] = $line; + } + } + fclose($fp); + } + return $result; + } + + // }}} + // {{{ userConfirm(prompt, [default]) + + function userConfirm($prompt, $default = 'yes') + { + trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); + static $positives = array('y', 'yes', 'on', '1'); + static $negatives = array('n', 'no', 'off', '0'); + print "$this->lp$prompt [$default] : "; + $fp = fopen("php://stdin", "r"); + $line = fgets($fp, 2048); + fclose($fp); + $answer = strtolower(trim($line)); + if (empty($answer)) { + $answer = $default; + } + if (in_array($answer, $positives)) { + return true; + } + if (in_array($answer, $negatives)) { + return false; + } + if (in_array($default, $positives)) { + return true; + } + return false; + } + + // }}} + // {{{ startTable([params]) + + function startTable($params = array()) + { + trigger_error("PEAR_Frontend_CLI::startTable deprecated", E_USER_ERROR); + } + + function _startTable($params = array()) + { + $params['table_data'] = array(); + $params['widest'] = array(); // indexed by column + $params['highest'] = array(); // indexed by row + $params['ncols'] = 0; + $this->params = $params; + } + + // }}} + // {{{ tableRow(columns, [rowparams], [colparams]) + + function tableRow($columns, $rowparams = array(), $colparams = array()) + { + trigger_error("PEAR_Frontend_CLI::tableRow deprecated", E_USER_ERROR); + } + + function _tableRow($columns, $rowparams = array(), $colparams = array()) + { + $highest = 1; + for ($i = 0; $i < sizeof($columns); $i++) { + $col = &$columns[$i]; + if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { + $col = wordwrap($col, $colparams[$i]['wrap'], "\n", 1); + } + if (strpos($col, "\n") !== false) { + $multiline = explode("\n", $col); + $w = 0; + foreach ($multiline as $n => $line) { + if (strlen($line) > $w) { + $w = strlen($line); + } + } + $lines = sizeof($multiline); + } else { + $w = strlen($col); + } + if ($w > @$this->params['widest'][$i]) { + $this->params['widest'][$i] = $w; + } + $tmp = count_chars($columns[$i], 1); + // handle unix, mac and windows formats + $lines = (isset($tmp[10]) ? $tmp[10] : @$tmp[13]) + 1; + if ($lines > $highest) { + $highest = $lines; + } + } + if (sizeof($columns) > $this->params['ncols']) { + $this->params['ncols'] = sizeof($columns); + } + $new_row = array( + 'data' => $columns, + 'height' => $highest, + 'rowparams' => $rowparams, + 'colparams' => $colparams, + ); + $this->params['table_data'][] = $new_row; + } + + // }}} + // {{{ endTable() + + function endTable() + { + trigger_error("PEAR_Frontend_CLI::endTable deprecated", E_USER_ERROR); + } + + function _endTable() + { + extract($this->params); + if (!empty($caption)) { + $this->_displayHeading($caption); + } + if (count($table_data) == 0) { + return; + } + if (!isset($width)) { + $width = $widest; + } else { + for ($i = 0; $i < $ncols; $i++) { + if (!isset($width[$i])) { + $width[$i] = $widest[$i]; + } + } + } + $border = false; + if (empty($border)) { + $cellstart = ''; + $cellend = ' '; + $rowend = ''; + $padrowend = false; + $borderline = ''; + } else { + $cellstart = '| '; + $cellend = ' '; + $rowend = '|'; + $padrowend = true; + $borderline = '+'; + foreach ($width as $w) { + $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); + $borderline .= '+'; + } + } + if ($borderline) { + $this->_displayLine($borderline); + } + for ($i = 0; $i < sizeof($table_data); $i++) { + extract($table_data[$i]); + $rowlines = array(); + if ($height > 1) { + for ($c = 0; $c < sizeof($data); $c++) { + $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); + if (sizeof($rowlines[$c]) < $height) { + $rowlines[$c] = array_pad($rowlines[$c], $height, ''); + } + } + } else { + for ($c = 0; $c < sizeof($data); $c++) { + $rowlines[$c] = array($data[$c]); + } + } + for ($r = 0; $r < $height; $r++) { + $rowtext = ''; + for ($c = 0; $c < sizeof($data); $c++) { + if (isset($colparams[$c])) { + $attribs = array_merge($rowparams, $colparams); + } else { + $attribs = $rowparams; + } + $w = isset($width[$c]) ? $width[$c] : 0; + //$cell = $data[$c]; + $cell = $rowlines[$c][$r]; + $l = strlen($cell); + if ($l > $w) { + $cell = substr($cell, 0, $w); + } + if (isset($attribs['bold'])) { + $cell = $this->bold($cell); + } + if ($l < $w) { + // not using str_pad here because we may + // add bold escape characters to $cell + $cell .= str_repeat(' ', $w - $l); + } + + $rowtext .= $cellstart . $cell . $cellend; + } + $rowtext .= $rowend; + $this->_displayLine($rowtext); + } + } + if ($borderline) { + $this->_displayLine($borderline); + } + } + + // }}} + // {{{ outputData() + + function outputData($data, $command = '_default') + { + switch ($command) + { + case 'install': + case 'upgrade': + case 'upgrade-all': + if (isset($data['release_warnings'])) { + $this->_displayLine(''); + $this->_startTable(array( + 'border' => false, + 'caption' => 'Release Warnings' + )); + $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); + $this->_endTable(); + $this->_displayLine(''); + }; + $this->_displayLine($data['data']); + break; + case 'search': + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + + foreach($data['data'] as $category) { + foreach($category as $pkg) { + $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); + } + }; + $this->_endTable(); + break; + case 'list-all': + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + + foreach($data['data'] as $category) { + foreach($category as $pkg) { + unset($pkg[3]); + unset($pkg[4]); + $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); + } + }; + $this->_endTable(); + break; + case 'config-show': + $data['border'] = false; + $opts = array(0 => array('wrap' => 30), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35)); + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], + array('bold' => true), + $opts); + } + foreach($data['data'] as $group) { + foreach($group as $value) { + if ($value[2] == '') { + $value[2] = ""; + } + $this->_tableRow($value, null, $opts); + } + } + $this->_endTable(); + break; + case 'remote-info': + $data = array( + 'caption' => 'Package details:', + 'border' => false, + 'data' => array( + array("Latest", $data['stable']), + array("Installed", $data['installed']), + array("Package", $data['name']), + array("License", $data['license']), + array("Category", $data['category']), + array("Summary", $data['summary']), + array("Description", $data['description']), + ), + ); + default: { + if (is_array($data)) + { + $this->_startTable($data); + $count = count($data['data'][0]); + if ($count == 2) { + $opts = array(0 => array('wrap' => 25), + 1 => array('wrap' => 48) + ); + } elseif ($count == 3) { + $opts = array(0 => array('wrap' => 20), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35) + ); + } + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], + array('bold' => true), + $opts); + } + foreach($data['data'] as $row) { + $this->_tableRow($row, null, $opts); + } + $this->_endTable(); + } else { + $this->_displayLine($data); + } + } + } + } + + // }}} + // {{{ log(text) + + + function log($text) + { + return $this->_displayLine($text); + } + + + // }}} + // {{{ bold($text) + + function bold($text) + { + if (empty($this->term['bold'])) { + return strtoupper($text); + } + return $this->term['bold'] . $text . $this->term['normal']; + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Installer.php b/gulliver/thirdparty/pear/PEAR/Installer.php new file mode 100644 index 000000000..6ef191c98 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Installer.php @@ -0,0 +1,874 @@ + | +// | Tomas V.V.Cox | +// +----------------------------------------------------------------------+ +// +// $Id: Installer.php,v 1.86 2003/03/18 12:06:06 ssb Exp $ + +require_once 'PEAR/Common.php'; +require_once 'PEAR/Registry.php'; +require_once 'PEAR/Dependency.php'; +require_once 'System.php'; + +define('PEAR_INSTALLER_OK', 1); +define('PEAR_INSTALLER_FAILED', 0); +define('PEAR_INSTALLER_SKIPPED', -1); + +/** + * Administration class used to install PEAR packages and maintain the + * installed package database. + * + * TODO: + * - Check dependencies break on package uninstall (when no force given) + * - add a guessInstallDest() method with the code from _installFile() and + * use that method in Registry::_rebuildFileMap() & Command_Registry::doList(), + * others.. + * + * @since PHP 4.0.2 + * @author Stig Bakken + */ +class PEAR_Installer extends PEAR_Common +{ + // {{{ properties + + /** name of the package directory, for example Foo-1.0 + * @var string + */ + var $pkgdir; + + /** directory where PHP code files go + * @var string + */ + var $phpdir; + + /** directory where PHP extension files go + * @var string + */ + var $extdir; + + /** directory where documentation goes + * @var string + */ + var $docdir; + + /** installation root directory (ala PHP's INSTALL_ROOT or + * automake's DESTDIR + * @var string + */ + var $installroot = ''; + + /** debug level + * @var int + */ + var $debug = 1; + + /** temporary directory + * @var string + */ + var $tmpdir; + + /** PEAR_Registry object used by the installer + * @var object + */ + var $registry; + + /** List of file transactions queued for an install/upgrade/uninstall. + * + * Format: + * array( + * 0 => array("rename => array("from-file", "to-file")), + * 1 => array("delete" => array("file-to-delete")), + * ... + * ) + * + * @var array + */ + var $file_operations = array(); + + // }}} + + // {{{ constructor + + /** + * PEAR_Installer constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function PEAR_Installer(&$ui) + { + parent::PEAR_Common(); + $this->setFrontendObject($ui); + $this->debug = $this->config->get('verbose'); + $this->registry = &new PEAR_Registry($this->config->get('php_dir')); + } + + // }}} + + // {{{ _deletePackageFiles() + + /** + * Delete a package's installed files, remove empty directories. + * + * @param string $package package name + * + * @return bool TRUE on success, or a PEAR error on failure + * + * @access private + */ + function _deletePackageFiles($package) + { + if (!strlen($package)) { + return $this->raiseError("No package to uninstall given"); + } + $filelist = $this->registry->packageInfo($package, 'filelist'); + if ($filelist == null) { + return $this->raiseError("$package not installed"); + } + foreach ($filelist as $file => $props) { + if (empty($props['installed_as'])) { + continue; + } + $path = $this->_prependPath($props['installed_as'], $this->installroot); + $this->addFileOperation('delete', array($path)); + } + return true; + } + + // }}} + // {{{ _installFile() + + function _installFile($file, $atts, $tmp_path) + { + static $os; + if (isset($atts['platform'])) { + if (empty($os)) { + include_once "OS/Guess.php"; + $os = new OS_Guess(); + } + // return if this file is meant for another platform + if (!$os->matchSignature($atts['platform'])) { + $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); + return PEAR_INSTALLER_SKIPPED; + } + } + + switch ($atts['role']) { + case 'doc': + case 'data': + case 'test': + $dest_dir = $this->config->get($atts['role'] . '_dir') . + DIRECTORY_SEPARATOR . $this->pkginfo['package']; + unset($atts['baseinstalldir']); + break; + case 'ext': + case 'php': + $dest_dir = $this->config->get($atts['role'] . '_dir'); + break; + case 'script': + $dest_dir = $this->config->get('bin_dir'); + break; + case 'src': + case 'extsrc': + $this->source_files++; + return; + default: + return $this->raiseError("Invalid role `$atts[role]' for file $file"); + } + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); + } + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; + + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + DIRECTORY_SEPARATOR, + array($dest_file, $orig_file)); + $installed_as = $dest_file; + $final_dest_file = $this->_prependPath($dest_file, $this->installroot); + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + if (!@is_dir($dest_dir)) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $dest_dir"); + } + if (empty($atts['replacements'])) { + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($atts['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { + $fp = fopen($orig_file, "r"); + $contents = fread($fp, filesize($orig_file)); + fclose($fp); + if (isset($atts['md5sum'])) { + $md5sum = md5($contents); + } + $subst_from = $subst_to = array(); + foreach ($atts['replacements'] as $a) { + $to = ''; + if ($a['type'] == 'php-const') { + if (preg_match('/^[a-z0-9_]+$/i', $a['to'])) { + eval("\$to = $a[to];"); + } else { + $this->log(0, "invalid php-const replacement: $a[to]"); + continue; + } + } elseif ($a['type'] == 'pear-config') { + $to = $this->config->get($a['to']); + } elseif ($a['type'] == 'package-info') { + $to = $this->pkginfo[$a['to']]; + } + if ($to) { + $subst_from[] = $a['from']; + $subst_to[] = $to; + } + } + $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); + } + $wp = @fopen($dest_file, "w"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + if (!fwrite($wp, $contents)) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + fclose($wp); + } + if (isset($md5sum)) { + if ($md5sum == $atts['md5sum']) { + $this->log(3, "md5sum ok: $final_dest_file"); + } else { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } + if (!OS_WINDOWS) { + if ($atts['role'] == 'script') { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + $this->log(0, "failed to change mode of $dest_file"); + } + } + $this->addFileOperation("rename", array($dest_file, $final_dest_file)); + + // XXX SHOULD BE DONE ONLY AFTER COMMIT + // Store the full path where the file was installed for easy unistall + $this->pkginfo['filelist'][$file]['installed_as'] = $installed_as; + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; + } + + // }}} + // {{{ addFileOperation() + + function addFileOperation($type, $data) + { + if ($type == 'chmod') { + $octmode = decoct($data[0]); + $this->log(3, "adding to transaction: $type $octmode $data[1]"); + } else { + $this->log(3, "adding to transaction: $type " . implode(" ", $data)); + } + $this->file_operations[] = array($type, $data); + } + + // }}} + // {{{ startFileTransaction() + + function startFileTransaction($rollback_in_case = false) + { + if (count($this->file_operations) && $rollback_in_case) { + $this->rollbackFileTransaction(); + } + $this->file_operations = array(); + } + + // }}} + // {{{ commitFileTransaction() + + function commitFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "about to commit $n file operations"); + // first, check permissions and such manually + $errors = array(); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + // check that dest dir. is writable + if (!is_writable(dirname($data[1]))) { + $errors[] = "permission denied ($type): $data[1]"; + } + break; + case 'chmod': + // check that file is writable + if (!is_writable($data[1])) { + $errors[] = "permission denied ($type): $data[1]"; + } + break; + case 'delete': + // check that directory is writable + if (file_exists($data[0]) && !is_writable(dirname($data[0]))) { + $errors[] = "permission denied ($type): $data[0]"; + } + break; + } + + } + $m = sizeof($errors); + if ($m > 0) { + foreach ($errors as $error) { + $this->log(1, $error); + } + return false; + } + // really commit the transaction + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + @rename($data[0], $data[1]); + $this->log(3, "+ mv $data[0] $data[1]"); + break; + case 'chmod': + @chmod($data[0], $data[1]); + $octmode = decoct($data[0]); + $this->log(3, "+ chmod $octmode $data[1]"); + break; + case 'delete': + @unlink($data[0]); + $this->log(3, "+ rm $data[0]"); + break; + case 'rmdir': + @rmdir($data[0]); + $this->log(3, "+ rmdir $data[0]"); + break; + } + } + $this->log(2, "successfully commited $n file operations"); + $this->file_operations = array(); + return true; + } + + // }}} + // {{{ rollbackFileTransaction() + + function rollbackFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "rolling back $n file operations"); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + @unlink($data[0]); + $this->log(3, "+ rm $data[0]"); + break; + case 'mkdir': + @rmdir($data[0]); + $this->log(3, "+ rmdir $data[0]"); + break; + case 'chmod': + break; + case 'delete': + break; + } + } + $this->file_operations = array(); + } + + // }}} + // {{{ getPackageDownloadUrl() + + function getPackageDownloadUrl($package) + { + if ($this === null || $this->config === null) { + $package = "http://pear.php.net/get/$package"; + } else { + $package = "http://" . $this->config->get('master_server') . + "/get/$package"; + } + if (!extension_loaded("zlib")) { + $package .= '?uncompress=yes'; + } + return $package; + } + + // }}} + // {{{ mkDirHier($dir) + + function mkDirHier($dir) + { + $this->addFileOperation('mkdir', array($dir)); + return parent::mkDirHier($dir); + } + + // }}} + + // {{{ _prependPath($path, $prepend) + + function _prependPath($path, $prepend) + { + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + $path = $prepend . substr($path, 2); + } else { + $path = $prepend . $path; + } + } + return $path; + } + + // }}} + + // {{{ install() + + /** + * Installs the files within the package file specified. + * + * @param $pkgfile path to the package file + * + * @return array package info if successful, null if not + */ + + function install($pkgfile, $options = array()) + { + // recognized options: + // - force : force installation + // - register-only : update registry but don't install files + // - upgrade : upgrade existing install + // - soft : fail silently + // + $php_dir = $this->config->get('php_dir'); + if (isset($options['installroot'])) { + if (substr($options['installroot'], -1) == DIRECTORY_SEPARATOR) { + $options['installroot'] = substr($options['installroot'], 0, -1); + } + $php_dir = $this->_prependPath($php_dir, $options['installroot']); + $this->registry = &new PEAR_Registry($php_dir); + $this->installroot = $options['installroot']; + } else { + $registry = &$this->registry; + $this->installroot = ''; + } + $need_download = false; + // ==> XXX should be removed later on + $flag_old_format = false; + if (preg_match('#^(http|ftp)://#', $pkgfile)) { + $need_download = true; + } elseif (!@is_file($pkgfile)) { + if ($this->validPackageName($pkgfile)) { + if ($this->registry->packageExists($pkgfile) && + empty($options['upgrade']) && empty($options['force'])) + { + return $this->raiseError("$pkgfile already installed"); + } + $pkgfile = $this->getPackageDownloadUrl($pkgfile); + $need_download = true; + } else { + if (strlen($pkgfile)) { + return $this->raiseError("Could not open the package file: $pkgfile"); + } else { + return $this->raiseError("No package file given"); + } + } + } + + // Download package ----------------------------------------------- + if ($need_download) { + $downloaddir = $this->config->get('download_dir'); + if (empty($downloaddir)) { + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $this->log(2, '+ tmp dir created at ' . $downloaddir); + } + $callback = $this->ui ? array(&$this, '_downloadCallback') : null; + $file = $this->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); + if (PEAR::isError($file)) { + return $this->raiseError($file); + } + $pkgfile = $file; + } + + if (substr($pkgfile, -4) == '.xml') { + $descfile = $pkgfile; + } else { + // Decompress pack in tmp dir ------------------------------------- + + // To allow relative package file names + $oldcwd = getcwd(); + if (@chdir(dirname($pkgfile))) { + $pkgfile = getcwd() . DIRECTORY_SEPARATOR . basename($pkgfile); + chdir($oldcwd); + } + + if (PEAR::isError($tmpdir = System::mktemp('-d'))) { + return $tmpdir; + } + $this->log(2, '+ tmp dir created at ' . $tmpdir); + + $tar = new Archive_Tar($pkgfile); + if (!@$tar->extract($tmpdir)) { + return $this->raiseError("unable to unpack $pkgfile"); + } + + // ----- Look for existing package file + $descfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; + + if (!is_file($descfile)) { + // ----- Look for old package archive format + // In this format the package.xml file was inside the + // Package-n.n directory + $dp = opendir($tmpdir); + do { + $pkgdir = readdir($dp); + } while ($pkgdir{0} == '.'); + + $descfile = $tmpdir . DIRECTORY_SEPARATOR . $pkgdir . DIRECTORY_SEPARATOR . 'package.xml'; + $flag_old_format = true; + $this->log(0, "warning : you are using an archive with an old format"); + } + // <== XXX This part should be removed later on + } + + if (!is_file($descfile)) { + return $this->raiseError("no package.xml file after extracting the archive"); + } + + // Parse xml file ----------------------------------------------- + $pkginfo = $this->infoFromDescriptionFile($descfile); + if (PEAR::isError($pkginfo)) { + return $pkginfo; + } + $this->validatePackageInfo($pkginfo, $errors, $warnings); + // XXX We allow warnings, do we have to do it? + if (count($errors)) { + if (empty($options['force'])) { + return $this->raiseError("The following errors where found (use force option to install anyway):\n". + implode("\n", $errors)); + } else { + $this->log(0, "warning : the following errors were found:\n". + implode("\n", $errors)); + } + } + + $pkgname = $pkginfo['package']; + + // Check dependencies ------------------------------------------- + if (isset($pkginfo['release_deps']) && empty($options['nodeps'])) { + $error = $this->checkDeps($pkginfo); + if ($error) { + if (empty($options['soft'])) { + $this->log(0, $error); + } + return $this->raiseError("$pkgname: dependencies failed"); + } + } + + if (empty($options['force'])) { + // checks to do when not in "force" mode + $test = $this->registry->checkFileMap($pkginfo); + if (sizeof($test)) { + $tmp = $test; + foreach ($tmp as $file => $pkg) { + if ($pkg == $pkgname) { + unset($test[$file]); + } + } + if (sizeof($test)) { + $msg = "$pkgname: conflicting files found:\n"; + $longest = max(array_map("strlen", array_keys($test))); + $fmt = "%${longest}s (%s)\n"; + foreach ($test as $file => $pkg) { + $msg .= sprintf($fmt, $file, $pkg); + } + return $this->raiseError($msg); + } + } + } + + if (empty($options['upgrade'])) { + // checks to do only when installing new packages + if (empty($options['force']) && $this->registry->packageExists($pkgname)) { + return $this->raiseError("$pkgname already installed"); + } + } else { + // checks to do only when upgrading packages + if (!$this->registry->packageExists($pkgname)) { + return $this->raiseError("$pkgname not installed"); + } + $v1 = $this->registry->packageInfo($pkgname, 'version'); + $v2 = $pkginfo['version']; + $cmp = version_compare("$v1", "$v2", 'gt'); + if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { + return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); + } + if (empty($options['register-only'])) { + // when upgrading, remove old release's files first: + if (PEAR::isError($err = $this->_deletePackageFiles($pkgname))) { + return $this->raiseError($err); + } + } + } + + // Copy files to dest dir --------------------------------------- + + // info from the package it self we want to access from _installFile + $this->pkginfo = &$pkginfo; + // used to determine whether we should build any C code + $this->source_files = 0; + + if (empty($options['register-only'])) { + if (!is_dir($php_dir)) { + return $this->raiseError("no script destination directory\n", + null, PEAR_ERROR_DIE); + } + + // don't want strange characters + $pkgname = ereg_replace ('[^a-zA-Z0-9._]', '_', $pkginfo['package']); + $pkgversion = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $pkginfo['version']); + $tmp_path = dirname($descfile); + if (substr($pkgfile, -4) != '.xml') { + $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkgversion; + } + + // ==> XXX This part should be removed later on + if ($flag_old_format) { + $tmp_path = dirname($descfile); + } + // <== XXX This part should be removed later on + + foreach ($pkginfo['filelist'] as $file => $atts) { + $this->expectError(PEAR_INSTALLER_FAILED); + $res = $this->_installFile($file, $atts, $tmp_path); + $this->popExpect(); + if (PEAR::isError($res)) { + if (empty($options['ignore-errors'])) { + $this->rollbackFileTransaction(); + return $this->raiseError($res); + } else { + $this->log(0, "Warning: " . $res->getMessage()); + } + } + if ($res != PEAR_INSTALLER_OK) { + // Do not register files that were not installed + unset($pkginfo['filelist'][$file]); + } + } + + if ($this->source_files > 0 && empty($options['nobuild'])) { + $this->log(1, "$this->source_files source files, building"); + $bob = &new PEAR_Builder($this->ui); + $bob->debug = $this->debug; + $built = $bob->build($descfile, array(&$this, '_buildCallback')); + if (PEAR::isError($built)) { + $this->rollbackFileTransaction(); + return $built; + } + foreach ($built as $ext) { + $bn = basename($ext['file']); + $this->log(2, "installing $bn"); + $dest = $this->config->get('ext_dir') . DIRECTORY_SEPARATOR . $bn; + $this->log(3, "+ cp $ext[file] ext_dir"); + $copyto = $this->_prependPath($dest, $this->installroot); + if (!@copy($ext['file'], $copyto)) { + $this->rollbackFileTransaction(); + return $this->raiseError("failed to copy $bn to $copyto"); + } + $pkginfo['filelist'][$bn] = array( + 'role' => 'ext', + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); + } + } + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); + } + + // Register that the package is installed ----------------------- + if (empty($options['upgrade'])) { + // if 'force' is used, replace the info in registry + if (!empty($options['force']) && $this->registry->packageExists($pkgname)) { + $this->registry->deletePackage($pkgname); + } + $ret = $this->registry->addPackage($pkgname, $pkginfo); + } else { + $ret = $this->registry->updatePackage($pkgname, $pkginfo, false); + } + if (!$ret) { + return null; + } + return $pkginfo; + } + + // }}} + // {{{ uninstall() + + function uninstall($package, $options = array()) + { + $php_dir = $this->config->get('php_dir'); + if (isset($options['installroot'])) { + if (substr($options['installroot'], -1) == DIRECTORY_SEPARATOR) { + $options['installroot'] = substr($options['installroot'], 0, -1); + } + $this->installroot = $options['installroot']; + $php_dir = $this->_prependPath($php_dir, $this->installroot); + } else { + $this->installroot = ''; + } + $this->registry = &new PEAR_Registry($php_dir); + + // Delete the files + if (PEAR::isError($err = $this->_deletePackageFiles($package))) { + $this->rollbackFileTransaction(); + return $this->raiseError($err); + } + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + return $this->raiseError("uninstall failed"); + } + + // Register that the package is no longer installed + return $this->registry->deletePackage($package); + } + + // }}} + // {{{ checkDeps() + + function checkDeps(&$pkginfo) + { + $depchecker = &new PEAR_Dependency($this->registry); + $error = $errors = ''; + $failed_deps = array(); + if (is_array($pkginfo['release_deps'])) { + foreach($pkginfo['release_deps'] as $dep) { + $code = $depchecker->callCheckMethod($error, $dep); + if ($code) { + $failed_deps[] = array($dep, $code, $error); + } + } + $n = count($failed_deps); + if ($n > 0) { + $depinstaller =& new PEAR_Installer($this->ui); + $to_install = array(); + for ($i = 0; $i < $n; $i++) { + if (isset($failed_deps[$i]['type'])) { + $type = $failed_deps[$i]['type']; + } else { + $type = 'pkg'; + } + switch ($failed_deps[$i][1]) { + case PEAR_DEPENDENCY_MISSING: + if ($type == 'pkg') { + // install + } + $errors .= "\n" . $failed_deps[$i][2]; + break; + case PEAR_DEPENDENCY_UPGRADE_MINOR: + if ($type == 'pkg') { + // upgrade + } + $errors .= "\n" . $failed_deps[$i][2]; + break; + default: + $errors .= "\n" . $failed_deps[$i][2]; + break; + } + } + return substr($errors, 1); + } + } + return false; + } + + // }}} + // {{{ _downloadCallback() + + function _downloadCallback($msg, $params = null) + { + switch ($msg) { + case 'saveas': + $this->log(1, "downloading $params ..."); + break; + case 'done': + $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); + break; + } + if (method_exists($this->ui, '_downloadCallback')) + $this->ui->_downloadCallback($msg, $params); + } + + // }}} + // {{{ _buildCallback() + + function _buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } + + // }}} +} + +if (!function_exists("md5_file")) { + function md5_file($filename) { + $fp = fopen($filename, "r"); + if (!$fp) return null; + $contents = fread($fp, filesize($filename)); + fclose($fp); + return md5($contents); + } +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Packager.php b/gulliver/thirdparty/pear/PEAR/Packager.php new file mode 100644 index 000000000..c56e70265 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Packager.php @@ -0,0 +1,176 @@ + | +// | Tomas V.V.Cox | +// +----------------------------------------------------------------------+ +// +// $Id: Packager.php,v 1.46 2003/03/18 12:06:06 ssb Exp $ + +require_once 'PEAR/Common.php'; +require_once 'System.php'; + +/** + * Administration class used to make a PEAR release tarball. + * + * TODO: + * - add an extra param the dir where to place the created package + * + * @since PHP 4.0.2 + * @author Stig Bakken + */ +class PEAR_Packager extends PEAR_Common +{ + // {{{ constructor + + function PEAR_Packager() + { + parent::PEAR_Common(); + } + + // }}} + // {{{ destructor + + function _PEAR_Packager() + { + parent::_PEAR_Common(); + } + + // }}} + + // {{{ package() + + function package($pkgfile = null, $compress = true) + { + if (empty($pkgfile)) { + $pkgfile = 'package.xml'; + } + $pkginfo = $this->infoFromDescriptionFile($pkgfile); + if (PEAR::isError($pkginfo)) { + return $this->raiseError($pkginfo); + } + if (empty($this->pkginfo['version'])) { + return $this->raiseError("No version info found in $pkgfile"); + } + // TMP DIR ------------------------------------------------- + // We allow calls like "pear package /home/user/mypack/package.xml" + $oldcwd = getcwd(); + $dir = dirname($pkgfile); + if (!@chdir($dir)) { + return $this->raiseError('Could not chdir to '.$dir); + } + $pkgfile = basename($pkgfile); + if (@$this->pkginfo['release_state'] == 'snapshot' && empty($this->pkginfo['version'])) { + $this->pkginfo['version'] = date('Ymd'); + } + // don't want strange characters + $pkgname = preg_replace('/[^a-z0-9._]/i', '_', $this->pkginfo['package']); + $pkgversion = preg_replace('/[^a-z0-9._-]/i', '_', $this->pkginfo['version']); + $pkgver = $pkgname . '-' . $pkgversion; + + $errors = $warnings = array(); + $this->validatePackageInfo($this->pkginfo, $errors, $warnings, $dir); + foreach ($warnings as $w) { + $this->log(1, "Warning: $w"); + } + foreach ($errors as $e) { + $this->log(0, "Error: $e"); + } + if (sizeof($errors) > 0) { + chdir($oldcwd); + return $this->raiseError('Errors in package'); + } + + // ----- Create the package file list + $filelist = array(); + $i = 0; + + // Copy files ----------------------------------------------- + foreach ($this->pkginfo['filelist'] as $fname => $atts) { + if (!file_exists($fname)) { + chdir($oldcwd); + return $this->raiseError("File does not exist: $fname"); + } else { + $filelist[$i++] = $fname; + if (empty($this->pkginfo['filelist'][$fname]['md5sum'])) { + $md5sum = md5_file($fname); + $this->pkginfo['filelist'][$fname]['md5sum'] = $md5sum; + } + $this->log(2, "Adding file $fname"); + } + } + $new_xml = $this->xmlFromInfo($this->pkginfo); + if (PEAR::isError($new_xml)) { + chdir($oldcwd); + return $this->raiseError($new_xml); + } + if (!($tmpdir = System::mktemp('-t '.getcwd().' -d'))) { + chdir($oldcwd); + return $this->raiseError("PEAR_Packager: mktemp failed"); + } + $newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; + $np = @fopen($newpkgfile, "w"); + if (!$np) { + chdir($oldcwd); + return $this->raiseError("PEAR_Packager: unable to rewrite $pkgfile as $newpkgfile"); + } + fwrite($np, $new_xml); + fclose($np); + + // TAR the Package ------------------------------------------- + $ext = $compress ? '.tgz' : '.tar'; + $dest_package = $oldcwd . DIRECTORY_SEPARATOR . $pkgver . $ext; + $tar =& new Archive_Tar($dest_package, $compress); + $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors + // ----- Creates with the package.xml file + $ok = $tar->createModify($newpkgfile, '', $tmpdir); + if (PEAR::isError($ok)) { + chdir($oldcwd); + return $this->raiseError($ok); + } elseif (!$ok) { + chdir($oldcwd); + return $this->raiseError('PEAR_Packager: tarball creation failed'); + } + // ----- Add the content of the package + if (!$tar->addModify($filelist, $pkgver)) { + chdir($oldcwd); + return $this->raiseError('PEAR_Packager: tarball creation failed'); + } + $this->log(1, "Package $dest_package done"); + if (file_exists("CVS/Root")) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pkgversion); + $cvstag = "RELEASE_$cvsversion"; + $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); + $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } + chdir($oldcwd); + return $dest_package; + } + + // }}} +} + +if (!function_exists('md5_file')) { + function md5_file($file) { + if (!$fd = @fopen($file, 'r')) { + return false; + } + $md5 = md5(fread($fd, filesize($file))); + fclose($fd); + return $md5; + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/PEAR/Registry.php b/gulliver/thirdparty/pear/PEAR/Registry.php new file mode 100644 index 000000000..1fb1bc0b0 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Registry.php @@ -0,0 +1,690 @@ + | +// | Tomas V.V.Cox | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Registry.php,v 1.39 2003/05/08 17:11:02 pajoye Exp $ + +/* +TODO: + - Transform into singleton() + - Add application level lock (avoid change the registry from the cmdline + while using the GTK interface, for ex.) +*/ +require_once "System.php"; +require_once "PEAR.php"; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); + +/** + * Administration class used to maintain the installed package database. + */ +class PEAR_Registry extends PEAR +{ + // {{{ properties + + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; + + /** File where the file map is stored + * @var string + */ + var $filemap = ''; + + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; + + /** File descriptor used during locking + * @var resource + */ + var $lock_fp = null; + + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED + + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) + * @var array + */ + var $pkginfo_cache = array(); + + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array + */ + var $filemap_cache = array(); + + // }}} + + // {{{ constructor + + /** + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * + * @access public + */ + function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR) + { + parent::PEAR(); + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + $this->statedir = $pear_install_dir.$ds.'.registry'; + $this->filemap = $pear_install_dir.$ds.'.filemap'; + $this->lockfile = $pear_install_dir.$ds.'.lock'; + if (!file_exists($this->filemap)) { + $this->rebuildFileMap(); + } + } + + // }}} + // {{{ destructor + + /** + * PEAR_Registry destructor. Makes sure no locks are forgotten. + * + * @access private + */ + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); + } + } + + // }}} + + // {{{ _assertStateDir() + + /** + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertStateDir() + { + if (!@is_dir($this->statedir)) { + if (!System::mkdir("-p {$this->statedir}")) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + } + return true; + } + + // }}} + // {{{ _packageFileName() + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _packageFileName($package) + { + return "{$this->statedir}/{$package}.reg"; + } + + // }}} + // {{{ _openPackageFile() + + function _openPackageFile($package, $mode) + { + $this->_assertStateDir(); + $file = $this->_packageFileName($package); + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + return $fp; + } + + // }}} + // {{{ _closePackageFile() + + function _closePackageFile($fp) + { + fclose($fp); + } + + // }}} + // {{{ rebuildFileMap() + + function rebuildFileMap() + { + $packages = $this->listPackages(); + $files = array(); + foreach ($packages as $package) { + $version = $this->packageInfo($package, 'version'); + $filelist = $this->packageInfo($package, 'filelist'); + if (!is_array($filelist)) { + continue; + } + foreach ($filelist as $name => $attrs) { + if (isset($attrs['role']) && $attrs['role'] != 'php') { + continue; + } + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } else { + $file = $name; + } + $file = preg_replace(',^/+,', '', $file); + $files[$file] = $package; + } + } + $this->_assertStateDir(); + $fp = @fopen($this->filemap, 'w'); + if (!$fp) { + return false; + } + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; + } + + // }}} + // {{{ readFileMap() + + function readFileMap() + { + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + $fsize = filesize($this->filemap); + $data = fread($fp, $fsize); + fclose($fp); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + $this->filemap_cache = $tmp; + return true; + } + + // }}} + // {{{ _lock() + + /** + * Lock the registry. + * + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (!eregi('Windows 9', php_uname())) { + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + if (PEAR::isError($err = $this->_assertStateDir())) { + return $err; + } + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH) { + if (@!is_file($this->lockfile)) { + touch($this->lockfile); + } + $open_mode = 'r'; + } + + $this->lock_fp = @fopen($this->lockfile, $open_mode); + + if (!is_resource($this->lock_fp)) { + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; + } + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); + } + } + return true; + } + + // }}} + // {{{ _unlock() + + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + $this->lock_fp = null; + return $ret; + } + + // }}} + // {{{ _packageExists() + + function _packageExists($package) + { + return file_exists($this->_packageFileName($package)); + } + + // }}} + // {{{ _packageInfo() + + function _packageInfo($package = null, $key = null) + { + if ($package === null) { + return array_map(array($this, '_packageInfo'), + $this->_listPackages()); + } + $fp = $this->_openPackageFile($package, 'r'); + if ($fp === null) { + return null; + } + $data = fread($fp, filesize($this->_packageFileName($package))); + $this->_closePackageFile($fp); + $data = unserialize($data); + if ($key === null) { + return $data; + } + if (isset($data[$key])) { + return $data[$key]; + } + return null; + } + + // }}} + // {{{ _listPackages() + + function _listPackages() + { + $pkglist = array(); + $dp = @opendir($this->statedir); + if (!$dp) { + return $pkglist; + } + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = substr($ent, 0, -4); + } + return $pkglist; + } + + // }}} + + // {{{ packageExists() + + function packageExists($package) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ packageInfo() + + function packageInfo($package = null, $key = null) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listPackages() + + function listPackages() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ addPackage() + + function addPackage($package, $info) + { + if ($this->packageExists($package)) { + return false; + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + $this->_unlock(); + return false; + } + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_unlock(); + return true; + } + + // }}} + // {{{ deletePackage() + + function deletePackage($package) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $file = $this->_packageFileName($package); + $ret = @unlink($file); + $this->rebuildFileMap(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ updatePackage() + + function updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->packageInfo($package); + if (empty($oldinfo)) { + return false; + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + $this->_unlock(); + return false; + } + $info['_lastmodified'] = time(); + if ($merge) { + fwrite($fp, serialize(array_merge($oldinfo, $info))); + } else { + fwrite($fp, serialize($info)); + } + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->rebuildFileMap(); + } + $this->_unlock(); + return true; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file belongs to a package. + * + * @param string $path file path, absolute or relative to the pear + * install dir + * + * @return string which package the file belongs to, or an empty + * string if the file does not belong to an installed package + * + * @access public + */ + function checkFileMap($path) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + $notempty = create_function('$a','return !empty($a);'); + } + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs) && isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } + $pkgs[$name] = $this->checkFileMap($name); + } + return array_filter($pkgs, $notempty); + } + if (empty($this->filemap_cache) && PEAR::isError($this->readFileMap())) { + return $err; + } + if (isset($this->filemap_cache[$path])) { + return $this->filemap_cache[$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$path])) { + return $this->filemap_cache[$path]; + } + return ''; + } + + // }}} + + // {{{ rebuildDepsFile() + + /** + Experimental dependencies database handling functions (not yet in production) + + TODO: + - test it + - Think on the "not" dep relation. It's supposed that a package can't + be installed if conflicts with another. The problem comes when the + user forces the installation and later upgrades it + **/ + + // XXX Terrible slow, a lot of read, lock, write, unlock + function rebuildDepsFile() + { + // Init the file with empty data + $error = $this->_depWriteDepDB(array()); + if (PEAR::isError($error)) { + return $error; + } + $packages = $this->listPackages(); + foreach ($packages as $package) { + $deps = $this->packageInfo($package, 'release_deps'); + $error = $this->setPackageDep($package, $deps); + if (PEAR::isError($error)) { + return $error; + } + } + return true; + } + + function &_depGetDepDB() + { + if (!$fp = fopen($this->depfile, 'r')) { + return $this->raiseError("Could not open dependencies file `".$this->depfile."'"); + } + $data = fread($fp, filesize($this->depfile)); + fclose($fp); + return unserialize($data); + } + + function _depWriteDepDB(&$deps) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + if (!$fp = fopen($this->depfile, 'w')) { + $this->_unlock(); + return $this->raiseError("Could not open dependencies file `".$this->depfile."' for writting"); + } + fwrite($fp, serialize($deps)); + fclose($fp); + $this->_unlock(); + return true; + } + + /* + The data structure is as follows: + $dep_db = array( + // Other packages depends in some manner on this packages + 'deps' => array( + 'Package Name' => array( + 0 => array( + // This package depends on 'Package Name' + 'depend' => 'Package', + // Which version 'Package' needs of 'Package Name' + 'version' => '1.0', + // The requirement (version_compare() operator) + 'rel' => 'ge' + ), + ), + ) + // This packages are dependant on other packages + 'pkgs' => array( + 'Package Dependant' => array( + // This is a index list with paths over the 'deps' array for quick + // searching things like "what dependecies has this package?" + // $dep_db['deps']['Package Name'][3] + 'Package Name' => 3 // key in array ['deps']['Package Name'] + ), + ) + ) + + Note: It only supports package dependencies no other type + */ + + function removePackageDep($package) + { + $data = &$this->_depGetDepDB(); + if (PEAR::isError($data)) { + return $data; + } + // Other packages depends on this package, can't be removed + if (isset($data['deps'][$package])) { + return $data['deps'][$package]; + } + // The package depends on others, remove those dependencies + if (isset($data['pkgs'][$package])) { + foreach ($data['pkgs'][$package] as $pkg => $key) { + // remove the dependency + unset($data['deps'][$pkg][$key]); + // if no more dependencies, remove the subject too + if (!count($data['deps'][$pkg])) { + unset($data['deps'][$pkg]); + } + } + // remove the package from the index list + unset($data['pkgs'][$package]); + } + return $this->_depWriteDepDB(); + } + + /** + * Update or insert a the dependencies of a package, prechecking + * that the package won't break any dependency in the process + */ + function setPackageDep($package, $new_version, $rel_deps = array()) + { + $data = &$this->_depGetDepDB(); + if (PEAR::isError($deps)) { + return $deps; + } + // Other packages depend on this package, check deps. Mostly for + // handling uncommon cases like: + // Foo and we are trying to + // update Foo to version 2.0 + if (isset($data['deps'][$package])) { + foreach ($data['deps'][$package] as $dep) { + $require = $dep['version']; + $relation = $dep['rel']; + // XXX (cox) Possible problem with changes in the way + // PEAR_Dependency::checkPackage() works + if ($relation != 'has') { + if (!version_compare("$new_version", "$require", $relation)) { + $fails[] = $dep; + } + } + } + if (isset($fails)) { + return $fails; + } + } + + // This package has no dependencies + if (!is_array($rel_deps) || !count($rel_deps)) { + return true; + } + + // The package depends on others, register that + foreach ($rel_deps as $dep) { + // We only support deps of type 'pkg's + if ($dep && $dep['type'] == 'pkg' && isset($dep['name'])) { + $write = array('depend' => $package, + 'version' => $dep['version'], + 'rel' => $dep['rel']); + settype($data['deps'][$dep['name']], 'array'); + + // The dependency already exists, update it + if (isset($data['pkgs'][$package][$dep['name']])) { + $key = $data['pkgs'][$package][$dep['name']]; + $data['deps'][$dep['name']][$key] = $write; + + // New dependency, insert it + } else { + $data['deps'][$dep['name']][] = $write; + $key = key($data['deps'][$dep['name']]); + settype($data['pkgs'][$package], 'array'); + $data['pkgs'][$package][$dep['name']] = $key; + } + } + } + return $this->_depWriteDepDB($data); + } + + // }}} +} + +?> diff --git a/gulliver/thirdparty/pear/PEAR/Remote.php b/gulliver/thirdparty/pear/PEAR/Remote.php new file mode 100644 index 000000000..f03dd5d09 --- /dev/null +++ b/gulliver/thirdparty/pear/PEAR/Remote.php @@ -0,0 +1,367 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Remote.php,v 1.39 2003/03/18 12:06:06 ssb Exp $ + +require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; + +/** + * This is a class for doing remote operations against the central + * PEAR database. + * + * @nodep XML_RPC_Value + * @nodep XML_RPC_Message + * @nodep XML_RPC_Client + */ +class PEAR_Remote extends PEAR +{ + // {{{ properties + + var $config = null; + var $cache = null; + + // }}} + + // {{{ PEAR_Remote(config_object) + + function PEAR_Remote(&$config) + { + $this->PEAR(); + $this->config = &$config; + } + + // }}} + + // {{{ getCache() + + + function getCache($args) + { + $id = md5(serialize($args)); + $cachedir = $this->config->get('cache_dir'); + if (!file_exists($cachedir)) { + System::mkdir('-p '.$cachedir); + } + $filename = $cachedir . DIRECTORY_SEPARATOR . 'xmlrpc_cache_' . $id; + if (!file_exists($filename)) { + return null; + }; + + $fp = fopen($filename, "rb"); + if ($fp === null) { + return null; + } + $content = fread($fp, filesize($filename)); + fclose($fp); + $result = array( + 'age' => time() - filemtime($filename), + 'lastChange' => filemtime($filename), + 'content' => unserialize($content), + ); + return $result; + } + + // }}} + + // {{{ saveCache() + + function saveCache($args, $data) + { + $id = md5(serialize($args)); + $cachedir = $this->config->get('cache_dir'); + if (!file_exists($cachedir)) { + System::mkdir('-p '.$cachedir); + } + $filename = $cachedir.'/xmlrpc_cache_'.$id; + + $fp = @fopen($filename, "wb"); + if ($fp !== null) { + fwrite($fp, serialize($data)); + fclose($fp); + }; + } + + // }}} + + // {{{ call(method, [args...]) + + function call($method) + { + $_args = $args = func_get_args(); + + $this->cache = $this->getCache($args); + $cachettl = $this->config->get('cache_ttl'); + // If cache is newer than $cachettl seconds, we use the cache! + if ($this->cache !== null && $this->cache['age'] < $cachettl) { + return $this->cache['content']; + }; + + if (extension_loaded("xmlrpc")) { + $result = call_user_func_array(array(&$this, 'call_epi'), $args); + if (!PEAR::isError($result)) { + $this->saveCache($_args, $result); + }; + return $result; + } + if (!@include_once("XML/RPC.php")) { + return $this->raiseError("For this remote PEAR operation you need to install the XML_RPC package"); + } + array_shift($args); + $server_host = $this->config->get('master_server'); + $username = $this->config->get('username'); + $password = $this->config->get('password'); + $eargs = array(); + foreach($args as $arg) $eargs[] = $this->_encode($arg); + $f = new XML_RPC_Message($method, $eargs); + if ($this->cache !== null) { + $maxAge = '?maxAge='.$this->cache['lastChange']; + } else { + $maxAge = ''; + }; + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($proxy = parse_url($this->config->get('http_proxy'))) { + $proxy_host = @$proxy['host']; + $proxy_port = @$proxy['port']; + $proxy_user = @$proxy['user']; + $proxy_pass = @$proxy['pass']; + } + $c = new XML_RPC_Client('/xmlrpc.php'.$maxAge, $server_host, 80, $proxy_host, $proxy_port, $proxy_user, $proxy_pass); + if ($username && $password) { + $c->setCredentials($username, $password); + } + if ($this->config->get('verbose') >= 3) { + $c->setDebug(1); + } + $r = $c->send($f); + if (!$r) { + return $this->raiseError("XML_RPC send failed"); + } + $v = $r->value(); + if ($e = $r->faultCode()) { + if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) { + return $this->cache['content']; + } + return $this->raiseError($r->faultString(), $e); + } + + $result = XML_RPC_decode($v); + $this->saveCache($_args, $result); + return $result; + } + + // }}} + + // {{{ call_epi(method, [args...]) + + function call_epi($method) + { + do { + if (extension_loaded("xmlrpc")) { + break; + } + if (OS_WINDOWS) { + $ext = 'dll'; + } elseif (PHP_OS == 'HP-UX') { + $ext = 'sl'; + } elseif (PHP_OS == 'AIX') { + $ext = 'a'; + } else { + $ext = 'so'; + } + $ext = OS_WINDOWS ? 'dll' : 'so'; + @dl("xmlrpc-epi.$ext"); + if (extension_loaded("xmlrpc")) { + break; + } + @dl("xmlrpc.$ext"); + if (extension_loaded("xmlrpc")) { + break; + } + return $this->raiseError("unable to load xmlrpc extension"); + } while (false); + $params = func_get_args(); + array_shift($params); + $method = str_replace("_", ".", $method); + $request = xmlrpc_encode_request($method, $params); + $server_host = $this->config->get("master_server"); + if (empty($server_host)) { + return $this->raiseError("PEAR_Remote::call: no master_server configured"); + } + $server_port = 80; + $fp = @fsockopen($server_host, $server_port); + if (!$fp) { + return $this->raiseError("PEAR_Remote::call: fsockopen(`$server_host', $server_port) failed"); + } + $len = strlen($request); + $req_headers = "Host: $server_host:$server_port\r\n" . + "Content-type: text/xml\r\n" . + "Content-length: $len\r\n"; + $username = $this->config->get('username'); + $password = $this->config->get('password'); + if ($username && $password) { + $req_headers .= "Cookie: PEAR_USER=$username; PEAR_PW=$password\r\n"; + $tmp = base64_encode("$username:$password"); + $req_headers .= "Authorization: Basic $tmp\r\n"; + } + if ($this->cache !== null) { + $maxAge = '?maxAge='.$this->cache['lastChange']; + } else { + $maxAge = ''; + }; + + if ($this->config->get('verbose') > 3) { + print "XMLRPC REQUEST HEADERS:\n"; + var_dump($req_headers); + print "XMLRPC REQUEST BODY:\n"; + var_dump($request); + } + + fwrite($fp, ("POST /xmlrpc.php$maxAge HTTP/1.0\r\n$req_headers\r\n$request")); + $response = ''; + $line1 = fgets($fp, 2048); + if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, $matches)) { + return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server"); + } + switch ($matches[1]) { + case "200": // OK + break; + case "304": // Not Modified + return $this->cache['content']; + case "401": // Unauthorized + if ($username && $password) { + return $this->raiseError("PEAR_Remote: authorization failed", 401); + } else { + return $this->raiseError("PEAR_Remote: authorization required, please log in first", 401); + } + default: + return $this->raiseError("PEAR_Remote: unexpected HTTP response", (int)$matches[1], null, null, "$matches[1] $matches[2]"); + } + while (trim(fgets($fp, 2048)) != ''); // skip rest of headers + while ($chunk = fread($fp, 10240)) { + $response .= $chunk; + } + fclose($fp); + if ($this->config->get('verbose') > 3) { + print "XMLRPC RESPONSE:\n"; + var_dump($response); + } + $ret = xmlrpc_decode($response); + if (is_array($ret) && isset($ret['__PEAR_TYPE__'])) { + if ($ret['__PEAR_TYPE__'] == 'error') { + if (isset($ret['__PEAR_CLASS__'])) { + $class = $ret['__PEAR_CLASS__']; + } else { + $class = "PEAR_Error"; + } + if ($ret['code'] === '') $ret['code'] = null; + if ($ret['message'] === '') $ret['message'] = null; + if ($ret['userinfo'] === '') $ret['userinfo'] = null; + if (strtolower($class) == 'db_error') { + $ret = $this->raiseError(PEAR::errorMessage($ret['code']), + $ret['code'], null, null, + $ret['userinfo']); + } else { + $ret = $this->raiseError($ret['message'], $ret['code'], + null, null, $ret['userinfo']); + } + } + } elseif (is_array($ret) && sizeof($ret) == 1 && is_array($ret[0]) && + !empty($ret[0]['faultString']) && + !empty($ret[0]['faultCode'])) { + extract($ret[0]); + $faultString = "XML-RPC Server Fault: " . + str_replace("\n", " ", $faultString); + return $this->raiseError($faultString, $faultCode); + } + return $ret; + } + + // }}} + + // {{{ _encode + + // a slightly extended version of XML_RPC_encode + function _encode($php_val) + { + global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double; + global $XML_RPC_String, $XML_RPC_Array, $XML_RPC_Struct; + + $type = gettype($php_val); + $xmlrpcval = new XML_RPC_Value; + + switch($type) { + case "array": + reset($php_val); + $firstkey = key($php_val); + end($php_val); + $lastkey = key($php_val); + if ($firstkey === 0 && is_int($lastkey) && + ($lastkey + 1) == count($php_val)) { + $is_continuous = true; + reset($php_val); + $size = count($php_val); + for ($expect = 0; $expect < $size; $expect++, next($php_val)) { + if (key($php_val) !== $expect) { + $is_continuous = false; + break; + } + } + if ($is_continuous) { + reset($php_val); + $arr = array(); + while (list($k, $v) = each($php_val)) { + $arr[$k] = $this->_encode($v); + } + $xmlrpcval->addArray($arr); + break; + } + } + // fall though if not numerical and continuous + case "object": + $arr = array(); + while (list($k, $v) = each($php_val)) { + $arr[$k] = $this->_encode($v); + } + $xmlrpcval->addStruct($arr); + break; + case "integer": + $xmlrpcval->addScalar($php_val, $XML_RPC_Int); + break; + case "double": + $xmlrpcval->addScalar($php_val, $XML_RPC_Double); + break; + case "string": + case "NULL": + $xmlrpcval->addScalar($php_val, $XML_RPC_String); + break; + case "boolean": + $xmlrpcval->addScalar($php_val, $XML_RPC_Boolean); + break; + case "unknown type": + default: + return null; + } + return $xmlrpcval; + } + + // }}} + +} + +?> diff --git a/gulliver/thirdparty/pear/README b/gulliver/thirdparty/pear/README new file mode 100644 index 000000000..c953c26b1 --- /dev/null +++ b/gulliver/thirdparty/pear/README @@ -0,0 +1,18 @@ + PEAR - PHP Extension and Application Repository + =============================================== + Dedicated to Malin Bakken, born 1999-11-21 + +WHAT IS PEAR? + +PEAR is a code repository for PHP extensions and PHP library code +similar to TeX's CTAN and Perl's CPAN. + +The intention behind PEAR is to provide a means for library code +authors to organize their code in a defined way shared by other +developers, and to give the PHP community a single source for such +code. + + +DOCUMENTATION + +Documentation for PEAR can be found at http://pear.php.net/manual/. diff --git a/gulliver/thirdparty/pear/SOAP/Base.php b/gulliver/thirdparty/pear/SOAP/Base.php new file mode 100644 index 000000000..10efa991d --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Base.php @@ -0,0 +1,1116 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2007 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +define('MAIL_MIMEPART_CRLF', "\r\n"); +require_once 'PEAR.php'; + +if (!defined('INF')) { + define('INF', 1.8e307); +} +if (!defined('NAN')) { + define('NAN', 0.0); +} + +define('SOAP_LIBRARY_VERSION', '0.11.0'); +define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.11.0-beta'); + +// Set schema version. +define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema'); +define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance'); +define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema'); +define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/'); +define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/'); +define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/'); + +define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/'); +define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/'); + +define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/'); +define('SCHEMA_SOAP12', 'http://schemas.xmlsoap.org/wsdl/soap12/'); +define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http'); +define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/'); +define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/'); +define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/'); +define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/'); +define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/'); +define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/'); + +define('SOAP_DEFAULT_ENCODING', 'UTF-8'); + +class SOAP_Base_Object extends PEAR +{ + + /** + * Supported encodings, limited by XML extension. + * + * @var array $_encodings + */ + var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8'); + + /** + * Fault code. + * + * @var string $_myfaultcode + */ + var $_myfaultcode = ''; + + /** + * Recent PEAR_Error object. + * + * @var PEAR_Error $fault + */ + var $fault = null; + + /** + * Constructor. + * + * @param string $faultcode Error code. + */ + function SOAP_Base_Object($faultcode = 'Client') + { + $this->_myfaultcode = $faultcode; + parent::PEAR('SOAP_Fault'); + } + + /** + * Raises a SOAP error. + * + * Please refer to the SOAP definition for an impression of what a certain + * parameter stands for. + * + * @param string|object $str Error message or object. + * @param string $detail Detailed error message. + * @param string $actorURI + * @param mixed $code + * @param mixed $mode + * @param mixed $options + * @param boolean $skipmsg + */ + function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, + $mode = null, $options = null, $skipmsg = false) + { + // Pass through previous faults. + $is_instance = isset($this) && is_a($this, 'SOAP_Base_Object'); + if (is_object($str)) { + $fault =& $str; + } else { + if (!$code) { + $code = $is_instance ? $this->_myfaultcode : 'Client'; + } + require_once 'SOAP/Fault.php'; + $fault =& new SOAP_Fault($str, + $code, + $actorURI, + $detail, + $mode, + $options); + } + if ($is_instance) { + $this->fault =& $fault; + } + + return $fault; + } + + function _isfault() + { + return $this->fault != null; + } + + function &_getfault() + { + return $this->fault; + } + +} + +/** + * Common base class of all SOAP classes. + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + */ +class SOAP_Base extends SOAP_Base_Object +{ + var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema', + 'http://www.w3.org/1999/XMLSchema'); + var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + // load types into typemap array + var $_typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string' => 'string', + 'boolean' => 'boolean', + 'float' => 'float', + 'double' => 'float', + 'decimal' => 'float', + 'duration' => 'integer', + 'dateTime' => 'string', + 'time' => 'string', + 'date' => 'string', + 'gYearMonth' => 'integer', + 'gYear' => 'integer', + 'gMonthDay' => 'integer', + 'gDay' => 'integer', + 'gMonth' => 'integer', + 'hexBinary' => 'string', + 'base64Binary' => 'string', + // derived datatypes + 'normalizedString' => 'string', + 'token' => 'string', + 'language' => 'string', + 'NMTOKEN' => 'string', + 'NMTOKENS' => 'string', + 'Name' => 'string', + 'NCName' => 'string', + 'ID' => 'string', + 'IDREF' => 'string', + 'IDREFS' => 'string', + 'ENTITY' => 'string', + 'ENTITIES' => 'string', + 'integer' => 'integer', + 'nonPositiveInteger' => 'integer', + 'negativeInteger' => 'integer', + // longs (64bit ints) are not supported cross-platform. + 'long' => 'string', + 'int' => 'integer', + 'short' => 'integer', + 'byte' => 'string', + 'nonNegativeInteger' => 'integer', + 'unsignedLong' => 'integer', + 'unsignedInt' => 'integer', + 'unsignedShort' => 'integer', + 'unsignedByte' => 'integer', + 'positiveInteger' => 'integer', + 'anyType' => 'string', + 'anyURI' => 'string', + 'QName' => 'string' + ), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4' => 'integer', + 'int' => 'integer', + 'boolean' => 'boolean', + 'string' => 'string', + 'double' => 'float', + 'float' => 'float', + 'dateTime' => 'string', + 'timeInstant' => 'string', + 'base64Binary' => 'string', + 'base64' => 'string', + 'ur-type' => 'string' + ), + 'http://schemas.xmlsoap.org/soap/encoding/' => array( + 'base64' => 'string', + 'array' => 'array', + 'Array' => 'array', + 'Struct' => 'array') + ); + + /** + * Default class name to use for decoded response objects. + * + * @var string $_defaultObjectClassname + */ + var $_defaultObjectClassname = 'stdClass'; + + /** + * Hash with used namespaces. + * + * @array + */ + var $_namespaces; + + /** + * The default namespace. + * + * @string + */ + var $_namespace; + + var $_xmlEntities = array('&' => '&', + '<' => '<', + '>' => '>', + "'" => ''', + '"' => '"'); + + var $_doconversion = false; + + var $_attachments = array(); + + var $_wsdl = null; + + /** + * True if we use section 5 encoding, or false if this is literal. + * + * @var boolean $_section5 + */ + var $_section5 = true; + + // Handle type to class mapping. + var $_auto_translation = false; + var $_type_translation = array(); + + /** + * Constructor. + * + * @param string $faultcode Error code. + */ + function SOAP_Base($faultcode = 'Client') + { + parent::SOAP_Base_Object($faultcode); + $this->_resetNamespaces(); + } + + /** + * Sets the default namespace. + * + * @param string $namespace The default namespace. + */ + function setDefaultNamespace($namespace) + { + $this->_namespace = $namespace; + } + + function _resetNamespaces() + { + $this->_namespaces = array( + 'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV', + 'http://www.w3.org/2001/XMLSchema' => 'xsd', + 'http://www.w3.org/2001/XMLSchema-instance' => 'xsi', + 'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC'); + } + + /** + * Sets the schema version used in the SOAP message. + * + * @access private + * @see $_XMLSchema + * + * @param string $schemaVersion The schema version. + */ + function _setSchemaVersion($schemaVersion) + { + if (!in_array($schemaVersion, $this->_XMLSchema)) { + return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion"); + } + $this->_XMLSchemaVersion = $schemaVersion; + $tmpNS = array_flip($this->_namespaces); + $tmpNS['xsd'] = $this->_XMLSchemaVersion; + $tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance'; + $this->_namespaces = array_flip($tmpNS); + } + + function _getNamespacePrefix($ns) + { + if ($this->_namespace && $ns == $this->_namespace) { + return ''; + } + if (isset($this->_namespaces[$ns])) { + return $this->_namespaces[$ns]; + } + $prefix = 'ns' . count($this->_namespaces); + $this->_namespaces[$ns] = $prefix; + return $prefix; + } + + function _getNamespaceForPrefix($prefix) + { + $flipped = array_flip($this->_namespaces); + if (isset($flipped[$prefix])) { + return $flipped[$prefix]; + } + return null; + } + + function _isSoapValue(&$value) + { + return is_a($value, 'SOAP_Value'); + } + + function _serializeValue(&$value, $name = '', $type = false, + $elNamespace = null, $typeNamespace = null, + $options = array(), $attributes = array(), + $artype = '') + { + $namespaces = array(); + $arrayType = $array_depth = $xmlout_value = null; + $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = ''; + $xmlout_type = $xmlns = $ptype = $array_type_ns = ''; + + if (!$name || is_numeric($name)) { + $name = 'item'; + } + + if ($this->_wsdl) { + list($ptype, $arrayType, $array_type_ns, $array_depth) + = $this->_wsdl->getSchemaType($type, $name, $typeNamespace); + } + + if (!$arrayType) { + $arrayType = $artype; + } + if (!$ptype) { + $ptype = $this->_getType($value); + } + if (!$type) { + $type = $ptype; + } + + if (strcasecmp($ptype, 'Struct') == 0 || + strcasecmp($type, 'Struct') == 0) { + // Struct + $vars = null; + if (is_object($value)) { + $vars = get_object_vars($value); + } else { + $vars = &$value; + } + if (is_array($vars)) { + foreach (array_keys($vars) as $k) { + // Hide private vars. + if ($k[0] == '_') { + continue; + } + if (is_object($vars[$k])) { + if (is_a($vars[$k], 'SOAP_Value')) { + $xmlout_value .= $vars[$k]->serialize($this); + } else { + // XXX get the members and serialize them instead + // converting to an array is more overhead than we + // should really do. + $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace); + } + } else { + $xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace); + } + } + } + } elseif (strcasecmp($ptype, 'Array') == 0 || + strcasecmp($type, 'Array') == 0) { + // Array. + $typeNamespace = SOAP_SCHEMA_ENCODING; + $orig_type = $type; + $type = 'Array'; + $numtypes = 0; + $value = (array)$value; + // XXX this will be slow on larger arrays. Basically, it flattens + // arrays to allow us to serialize multi-dimensional arrays. We + // only do this if arrayType is set, which will typically only + // happen if we are using WSDL + if (isset($options['flatten']) || + ($arrayType && + (strchr($arrayType, ',') || strstr($arrayType, '][')))) { + $numtypes = $this->_multiArrayType($value, $arrayType, + $ar_size, $xmlout_value); + } + + $array_type = $array_type_prefix = ''; + if ($numtypes != 1) { + $arrayTypeQName = new QName($arrayType); + $arrayType = $arrayTypeQName->name; + $array_types = array(); + $array_val = null; + + // Serialize each array element. + $ar_size = count($value); + foreach ($value as $array_val) { + if ($this->_isSoapValue($array_val)) { + $array_type = $array_val->type; + $array_types[$array_type] = 1; + $array_type_ns = $array_val->type_namespace; + $xmlout_value .= $array_val->serialize($this); + } else { + $array_type = $this->_getType($array_val); + $array_types[$array_type] = 1; + $xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace); + } + } + + $xmlout_offset = ' SOAP-ENC:offset="[0]"'; + if (!$arrayType) { + $numtypes = count($array_types); + if ($numtypes == 1) { + $arrayType = $array_type; + } + // Using anyType is more interoperable. + if ($array_type == 'Struct') { + $array_type = ''; + } elseif ($array_type == 'Array') { + $arrayType = 'anyType'; + $array_type_prefix = 'xsd'; + } else { + if (!$arrayType) { + $arrayType = $array_type; + } + } + } + } + if (!$arrayType || $numtypes > 1) { + // Should reference what schema we're using. + $arrayType = 'xsd:anyType'; + } else { + if ($array_type_ns) { + $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); + } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) { + $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; + } + if ($array_type_prefix) { + $arrayType = $array_type_prefix . ':' . $arrayType; + } + } + + $xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType; + if ($array_depth != null) { + for ($i = 0; $i < $array_depth; $i++) { + $xmlout_arrayType .= '[]'; + } + } + $xmlout_arrayType .= "[$ar_size]\""; + } elseif ($this->_isSoapValue($value)) { + $xmlout_value = $value->serialize($this); + } elseif ($type == 'string') { + $xmlout_value = htmlspecialchars($value); + } elseif ($type == 'rawstring') { + $xmlout_value =& $value; + } elseif ($type == 'boolean') { + $xmlout_value = $value ? 'true' : 'false'; + } else { + $xmlout_value =& $value; + } + + // Add namespaces. + if ($elNamespace) { + $elPrefix = $this->_getNamespacePrefix($elNamespace); + if ($elPrefix) { + $xmlout_name = "$elPrefix:$name"; + } else { + $xmlout_name = $name; + } + } else { + $xmlout_name = $name; + } + + if ($typeNamespace) { + $typePrefix = $this->_getNamespacePrefix($typeNamespace); + if ($typePrefix) { + $xmlout_type = "$typePrefix:$type"; + } else { + $xmlout_type = $type; + } + } elseif ($type && + isset($this->_typemap[$this->_XMLSchemaVersion][$type])) { + $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; + if ($typePrefix) { + $xmlout_type = "$typePrefix:$type"; + } else { + $xmlout_type = $type; + } + } + + // Handle additional attributes. + $xml_attr = ''; + if (count($attributes)) { + foreach ($attributes as $k => $v) { + $kqn = new QName($k); + $vqn = new QName($v); + $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"'; + } + } + + // Store the attachment for mime encoding. + if (isset($options['attachment']) && + !PEAR::isError($options['attachment'])) { + $this->_attachments[] = $options['attachment']; + } + + if ($this->_section5) { + if ($xmlout_type) { + $xmlout_type = " xsi:type=\"$xmlout_type\""; + } + if (is_null($xmlout_value)) { + $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . + "$xml_attr xsi:nil=\"true\"/>"; + } else { + $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . + "$xmlout_offset$xml_attr>$xmlout_value"; + } + } else { + if (is_null($xmlout_value)) { + $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>"; + } else { + $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" . + $xmlout_value . ""; + } + } + + return $xml; + } + + /** + * Converts a PHP type to a SOAP type. + * + * @access private + * + * @param string $value The value to inspect. + * + * @return string The value's SOAP type. + */ + function _getType(&$value) + { + $type = gettype($value); + switch ($type) { + case 'object': + if (is_a($value, 'soap_value')) { + $type = $value->type; + } else { + $type = 'Struct'; + } + break; + + case 'array': + // Hashes are always handled as structs. + if ($this->_isHash($value)) { + $type = 'Struct'; + } else { + $ar_size = count($value); + reset($value); + $key1 = key($value); + if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) { + // FIXME: for non-wsdl structs that are all the same type + $key2 = key($value); + if ($ar_size > 1 && + $this->_isSoapValue($key1) && + $this->_isSoapValue($key2) && + $key1->name != $key2->name) { + // This is a struct, not an array. + $type = 'Struct'; + } else { + $type = 'Array'; + } + } else { + $type = 'Array'; + } + } + break; + + case 'integer': + case 'long': + $type = 'int'; + break; + + case 'boolean': + break; + + case 'double': + // double is deprecated in PHP 4.2 and later. + $type = 'float'; + break; + + case 'null': + $type = ''; + break; + + case 'string': + default: + break; + } + + return $type; + } + + function _multiArrayType($value, &$type, &$size, &$xml) + { + if (is_array($value)) { + // Seems we have a multi dimensional array, figure it out if we + // do. + for ($i = 0, $c = count($value); $i < $c; ++$i) { + $this->_multiArrayType($value[$i], $type, $size, $xml); + } + + $sz = count($value); + if ($size) { + $size = $sz . ',' . $size; + } else { + $size = $sz; + } + return 1; + } elseif (is_object($value)) { + $type = $value->type; + $xml .= $value->serialize($this); + } else { + $type = $this->_getType($value); + $xml .= $this->_serializeValue($value, 'item', $type); + } + $size = null; + + return 1; + } + + /** + * Returns whether a type is a base64 type. + * + * @param string $type A type name. + * + * @return boolean True if the type name is a base64 type. + */ + function _isBase64Type($type) + { + return $type == 'base64' || $type == 'base64Binary'; + } + + /** + * Returns whether an array is a hash. + * + * @param array $a An array to check. + * + * @return boolean True if the specified array is a hash. + */ + function _isHash(&$a) + { + // I really dislike having to loop through this in PHP code, really + // large arrays will be slow. We need a C function to do this. + $it = 0; + foreach ($a as $k => $v) { + // Checking the type is faster than regexp. + if (!is_int($k)) { + return true; + } + // If someone has a large hash they should really be defining the + // type. + if ($it++ > 10) { + $this->_raiseSoapFault('Large associative array passed where a SOAP_Value was expected'); + return false; + } + } + return false; + } + + function _un_htmlentities($string) + { + $trans_tbl = get_html_translation_table(HTML_ENTITIES); + $trans_tbl = array_flip($trans_tbl); + return strtr($string, $trans_tbl); + } + + /** + * Converts a SOAP_Value object into a StdClass PHP object + */ + function &_decode(&$soapval) + { + if (!$this->_isSoapValue($soapval)) { + return $soapval; + } elseif (is_array($soapval->value)) { + if ($soapval->type != 'Array') { + $classname = $this->_defaultObjectClassname; + if (isset($this->_type_translation[$soapval->tqn->fqn()])) { + // This will force an error in PHP if the class does not + // exist. + $classname = $this->_type_translation[$soapval->tqn->fqn()]; + } elseif (isset($this->_type_translation[$soapval->type])) { + // This will force an error in PHP if the class does not + // exist. + $classname = $this->_type_translation[$soapval->type]; + } elseif ($this->_auto_translation) { + if (class_exists($soapval->type)) { + $classname = $soapval->type; + } elseif ($this->_wsdl) { + $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace); + if ($t && class_exists($t)) { + $classname = $t; + } + } + } + $return =& new $classname; + } else { + $return = array(); + } + + $counter = 1; + $isstruct = !is_array($return); + foreach ($soapval->value as $item) { + if (is_object($return)) { + if ($this->_wsdl) { + // Get this child's WSDL information. + // /$soapval->ns/$soapval->type/$item->ns/$item->name + $child_type = $this->_wsdl->getComplexTypeChildType( + $soapval->namespace, + $soapval->name, + $item->namespace, + $item->name); + if ($child_type) { + $item->type = $child_type; + } + } + if (!$isstruct || $item->type == 'Array') { + if (isset($return->{$item->name}) && + is_object($return->{$item->name})) { + $return->{$item->name} =& $this->_decode($item); + } elseif (isset($return->{$item->name}) && + is_array($return->{$item->name})) { + $return->{$item->name}[] = $this->_decode($item); + } elseif (isset($return->{$item->name})) { + $return->{$item->name} = array( + $return->{$item->name}, + $this->_decode($item) + ); + } elseif (is_array($return)) { + $return[] =& $this->_decode($item); + } else { + $return->{$item->name} =& $this->_decode($item); + } + } elseif (isset($return->{$item->name})) { + //$isstruct = false; + if (count(get_object_vars($return)) == 1) { + $d =& $this->_decode($item); + $return = array($return->{$item->name}, $d); + } else { + $d =& $this->_decode($item); + $return->{$item->name} = array($return->{$item->name}, $d); + } + } else { + $return->{$item->name} =& $this->_decode($item); + } + // Set the attributes as members in the class. + if (method_exists($return, '__set_attribute')) { + foreach ($soapval->attributes as $key => $value) { + call_user_func_array(array(&$return, + '__set_attribute'), + array($key, $value)); + } + } + } else { + if ($soapval->arrayType && $this->_isSoapValue($item)) { + if ($this->_isBase64Type($item->type) && + !$this->_isBase64Type($soapval->arrayType)) { + // Decode the value if we're losing the base64 + // type information. + $item->value = base64_decode($item->value); + } + $item->type = $soapval->arrayType; + } + if (!$isstruct) { + $return[] = $this->_decode($item); + } elseif (isset($return[$item->name])) { + $isstruct = false; + $d =& $this->_decode($item); + $return = array($return[$item->name], $d); + } else { + $return[$item->name] = $this->_decode($item); + } + } + } + + return $return; + } + + if ($soapval->type == 'boolean') { + if ($soapval->value != '0' && + strcasecmp($soapval->value, 'false') != 0) { + $soapval->value = true; + } else { + $soapval->value = false; + } + } elseif ($soapval->type && + isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) { + // If we can, set variable type. + settype($soapval->value, + $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]); + } + + return $soapval->value; + } + + /** + * Creates the SOAP envelope with the SOAP envelop data. + * + * @param mixed $method + * @param array $headers + * @param string $encoding + * @param array $options + * + * @return string + */ + function makeEnvelope(&$method, &$headers, + $encoding = SOAP_DEFAULT_ENCODING, + $options = array()) + { + $smsg = $header_xml = $ns_string = ''; + + if ($headers) { + $c = count($headers); + for ($i = 0; $i < $c; $i++) { + $header_xml .= $headers[$i]->serialize($this); + } + $header_xml = "\r\n$header_xml\r\n\r\n"; + } + + if (!isset($options['input']) || $options['input'] == 'parse') { + if (is_array($method)) { + $c = count($method); + for ($i = 0; $i < $c; $i++) { + $smsg .= $method[$i]->serialize($this); + } + } else { + $smsg = $method->serialize($this); + } + } else { + $smsg = $method; + } + $body = "\r\n" . $smsg . "\r\n\r\n"; + + foreach ($this->_namespaces as $k => $v) { + $ns_string .= " xmlns:$v=\"$k\"\r\n"; + } + if ($this->_namespace) { + $ns_string .= " xmlns=\"{$this->_namespace}\"\r\n"; + } + + /* If 'use' == 'literal', we do not put in the encodingStyle. This is + * denoted by $this->_section5 being false. 'use' can be defined at a + * more granular level than we are dealing with here, so this does not + * work for all services. */ + $xml = "\r\n\r\n". + "_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : ''). + ">\r\n". + "$header_xml$body\r\n"; + + return $xml; + } + + function _makeMimeMessage($xml, $encoding = SOAP_DEFAULT_ENCODING) + { + if (!@include_once 'Mail/mimePart.php') { + return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); + } + + // Encode any attachments. See http://www.w3.org/TR/SOAP-attachments + // Now we have to mime encode the message. + $params = array('content_type' => 'multipart/related; type="text/xml"'); + $msg = new Mail_mimePart('', $params); + + // Add the xml part. + $params['content_type'] = 'text/xml'; + $params['charset'] = $encoding; + $params['encoding'] = 'base64'; + $msg->addSubPart($xml, $params); + + // Add the attachements + for ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) { + $msg->addSubPart($this->_attachments[$i]['body'], + $this->_attachments[$i]); + } + + return $msg->encode(); + } + + // TODO: this needs to be used from the Transport system. + function _makeDIMEMessage($xml) + { + if (!@include_once 'Net/DIME.php') { + return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); + } + + // Encode any attachments. See + // http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt + // Now we have to DIME encode the message + $dime = new Net_DIME_Message(); + $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI); + + // Add the attachments. + $c = count($this->_attachments); + for ($i = 0; $i < $c; $i++) { + $msg .= $dime->encodeData($this->_attachments[$i]['body'], + $this->_attachments[$i]['content_type'], + $this->_attachments[$i]['cid'], + NET_DIME_TYPE_MEDIA); + } + $msg .= $dime->endMessage(); + + return $msg; + } + + function _decodeMimeMessage(&$data, &$headers, &$attachments) + { + if (!@include_once 'Mail/mimeDecode.php') { + return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); + } + + $params['include_bodies'] = true; + $params['decode_bodies'] = true; + $params['decode_headers'] = true; + + // Lame thing to have to do for decoding. + $decoder =& new Mail_mimeDecode($data); + $structure = $decoder->decode($params); + + if (isset($structure->body)) { + $data = $structure->body; + $headers = $structure->headers; + + return; + } elseif (isset($structure->parts)) { + $data = $structure->parts[0]->body; + $headers = array_merge($structure->headers, + $structure->parts[0]->headers); + if (count($structure->parts) > 1) { + $mime_parts = array_splice($structure->parts,1); + // Prepare the parts for the SOAP parser. + + $c = count($mime_parts); + for ($i = 0; $i < $c; $i++) { + $p =& $mime_parts[$i]; + if (isset($p->headers['content-location'])) { + // TODO: modify location per SwA note section 3 + // http://www.w3.org/TR/SOAP-attachments + $attachments[$p->headers['content-location']] = $p->body; + } else { + $cid = 'cid:' . substr($p->headers['content-id'], 1, -1); + $attachments[$cid] = $p->body; + } + } + } + + return; + } + + $this->_raiseSoapFault('Mime parsing error', '', '', 'Server'); + } + + function _decodeDIMEMessage(&$data, &$headers, &$attachments) + { + if (!@include_once 'Net/DIME.php') { + return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); + } + + // This SHOULD be moved to the transport layer, e.g. PHP itself should + // handle parsing DIME ;) + $dime =& new Net_DIME_Message(); + $err = $dime->decodeData($data); + if (PEAR::isError($err)) { + $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server'); + return; + } + if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) { + $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server'); + return; + } + + $data = $dime->parts[0]['data']; + // Fake it for now. + $headers['content-type'] = 'text/xml'; + $c = count($dime->parts); + for ($i = 0; $i < $c; $i++) { + $part =& $dime->parts[$i]; + // We need to handle URI's better. + $id = strncmp($part['id'], 'cid:', 4) + ? 'cid:' . $part['id'] + : $part['id']; + $attachments[$id] = $part['data']; + } + } + + /** + * @deprecated Use setTypeTranslation(). + */ + function __set_type_translation($type, $class = null) + { + $this->setTypeTranslation($type, $class); + } + + /** + * Explicitly sets the translation for a specific class. + * + * Auto translation works for all cases, but opens ANY class in the script + * to be used as a data type, and may not be desireable. + * + * @param string $type A SOAP type. + * @param string $class A PHP class name. + */ + function setTypeTranslation($type, $class = null) + { + $tq = new QName($type); + if (!$class) { + $class = $tq->name; + } + $this->_type_translation[$type]=$class; + } + +} + +/** + * Class used to handle QNAME values in XML. + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + */ +class QName +{ + var $name = ''; + var $ns = ''; + var $namespace=''; + + function QName($name, $namespace = '') + { + if ($name && $name[0] == '{') { + preg_match('/\{(.*?)\}(.*)/', $name, $m); + $this->name = $m[2]; + $this->namespace = $m[1]; + } elseif (substr_count($name, ':') == 1) { + $s = explode(':', $name); + $s = array_reverse($s); + $this->name = $s[0]; + $this->ns = $s[1]; + $this->namespace = $namespace; + } else { + $this->name = $name; + $this->namespace = $namespace; + } + + // A little more magic than should be in a qname. + $p = strpos($this->name, '['); + if ($p) { + // TODO: Need to re-examine this logic later. + // Chop off []. + $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2)); + $this->arrayInfo = substr($this->name, $p); + $this->name = substr($this->name, 0, $p); + } + } + + function fqn() + { + if ($this->namespace) { + return '{' . $this->namespace . '}' . $this->name; + } elseif ($this->ns) { + return $this->ns . ':' . $this->name; + } + return $this->name; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Client.php b/gulliver/thirdparty/pear/SOAP/Client.php new file mode 100644 index 000000000..3ca23a1cb --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Client.php @@ -0,0 +1,855 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Value.php'; +require_once 'SOAP/Base.php'; +require_once 'SOAP/Transport.php'; +require_once 'SOAP/WSDL.php'; +require_once 'SOAP/Fault.php'; +require_once 'SOAP/Parser.php'; + +// Arnaud: the following code was taken from DataObject and adapted to suit + +// this will be horrifically slow!!!! +// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer +// these two are BC/FC handlers for call in PHP4/5 + +if (!class_exists('SOAP_Client_Overload')) { + if (substr(zend_version(), 0, 1) > 1) { + class SOAP_Client_Overload extends SOAP_Base { + function __call($method, $args) + { + $return = null; + $this->_call($method, $args, $return); + return $return; + } + } + } else { + if (!function_exists('clone')) { + eval('function clone($t) { return $t; }'); + } + eval(' + class SOAP_Client_Overload extends SOAP_Base { + function __call($method, $args, &$return) + { + return $this->_call($method, $args, $return); + } + }'); + } +} + +/** + * SOAP Client Class + * + * This class is the main interface for making soap requests. + * + * basic usage: + * $soapclient = new SOAP_Client( string path [ , boolean wsdl] ); + * echo $soapclient->call( string methodname [ , array parameters] ); + * + * or, if using PHP 5+ or the overload extension: + * $soapclient = new SOAP_Client( string path [ , boolean wsdl] ); + * echo $soapclient->methodname( [ array parameters] ); + * + * + * Originally based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Stig Bakken Conversion to PEAR + * @author Dietrich Ayala Original Author + */ +class SOAP_Client extends SOAP_Client_Overload +{ + /** + * Communication endpoint. + * + * Currently the following transport formats are supported: + * - HTTP + * - SMTP + * + * Example endpoints: + * http://www.example.com/soap/server.php + * https://www.example.com/soap/server.php + * mailto:soap@example.com + * + * @see SOAP_Client() + * @var string + */ + var $_endpoint = ''; + + /** + * The SOAP PORT name that is used by the client. + * + * @var string + */ + var $_portName = ''; + + /** + * Endpoint type e.g. 'wdsl'. + * + * @var string + */ + var $_endpointType = ''; + + /** + * The received xml. + * + * @var string + */ + var $xml; + + /** + * The outgoing and incoming data stream for debugging. + * + * @var string + */ + var $wire; + + /** + * The outgoing data stream for debugging. + * + * @var string + */ + var $_last_request = null; + + /** + * The incoming data stream for debugging. + * + * @var string + */ + var $_last_response = null; + + /** + * Options. + * + * @var array + */ + var $_options = array('trace' => false); + + /** + * The character encoding used for XML parser, etc. + * + * @var string + */ + var $_encoding = SOAP_DEFAULT_ENCODING; + + /** + * The array of SOAP_Headers that we are sending. + * + * @var array + */ + var $headersOut = null; + + /** + * The headers we recieved back in the response. + * + * @var array + */ + var $headersIn = null; + + /** + * Options for the HTTP_Request class (see HTTP/Request.php). + * + * @var array + */ + var $_proxy_params = array(); + + /** + * The SOAP_Transport instance. + * + * @var SOAP_Transport + */ + var $_soap_transport = null; + + /** + * Constructor. + * + * @access public + * + * @param string $endpoint An URL. + * @param boolean $wsdl Whether the endpoint is a WSDL file. + * @param string $portName The service's port name to use. + * @param array $proxy_params Options for the HTTP_Request class + * @see HTTP_Request + * @param boolean|string $cache Use WSDL caching? The cache directory if + * a string. + */ + function SOAP_Client($endpoint, $wsdl = false, $portName = false, + $proxy_params = array(), $cache = false) + { + parent::SOAP_Base('Client'); + + $this->_endpoint = $endpoint; + $this->_portName = $portName; + $this->_proxy_params = $proxy_params; + + // This hack should perhaps be removed as it might cause unexpected + // behaviour. + $wsdl = $wsdl + ? $wsdl + : strtolower(substr($endpoint, -4)) == 'wsdl'; + + // make values + if ($wsdl) { + $this->_endpointType = 'wsdl'; + // instantiate wsdl class + $this->_wsdl = new SOAP_WSDL($this->_endpoint, + $this->_proxy_params, + $cache); + if ($this->_wsdl->fault) { + $this->_raiseSoapFault($this->_wsdl->fault); + } + } + } + + function _reset() + { + $this->xml = null; + $this->wire = null; + $this->_last_request = null; + $this->_last_response = null; + $this->headersIn = null; + $this->headersOut = null; + } + + /** + * Sets the character encoding. + * + * Limited to 'UTF-8', 'US_ASCII' and 'ISO-8859-1'. + * + * @access public + * + * @param string encoding + * + * @return mixed SOAP_Fault on error. + */ + function setEncoding($encoding) + { + if (in_array($encoding, $this->_encodings)) { + $this->_encoding = $encoding; + return; + } + return $this->_raiseSoapFault('Invalid Encoding'); + } + + /** + * Adds a header to the envelope. + * + * @access public + * + * @param SOAP_Header $soap_value A SOAP_Header or an array with the + * elements 'name', 'namespace', + * 'mustunderstand', and 'actor' to send + * as a header. + */ + function addHeader($soap_value) + { + // Add a new header to the message. + if (is_a($soap_value, 'SOAP_Header')) { + $this->headersOut[] = $soap_value; + } elseif (is_array($soap_value)) { + // name, value, namespace, mustunderstand, actor + $this->headersOut[] = new SOAP_Header($soap_value[0], + null, + $soap_value[1], + $soap_value[2], + $soap_value[3]); + } else { + $this->_raiseSoapFault('Invalid parameter provided to addHeader(). Must be an array or a SOAP_Header.'); + } + } + + /** + * Calls a method on the SOAP endpoint. + * + * The namespace parameter is overloaded to accept an array of options + * that can contain data necessary for various transports if it is used as + * an array, it MAY contain a namespace value and a soapaction value. If + * it is overloaded, the soapaction parameter is ignored and MUST be + * placed in the options array. This is done to provide backwards + * compatibility with current clients, but may be removed in the future. + * The currently supported values are:
    +     *   namespace
    +     *   soapaction
    +     *   timeout (HTTP socket timeout)
    +     *   transfer-encoding (SMTP, Content-Transfer-Encoding: header)
    +     *   from (SMTP, From: header)
    +     *   subject (SMTP, Subject: header)
    +     *   headers (SMTP, hash of extra SMTP headers)
    +     * 
    + * + * @access public + * + * @param string $method The method to call. + * @param array $params The method parameters. + * @param string|array $namespace Namespace or hash with options. + * @param string $soapAction + * + * @return mixed The method result or a SOAP_Fault on error. + */ + function &call($method, &$params, $namespace = false, $soapAction = false) + { + $this->headersIn = null; + $this->_last_request = null; + $this->_last_response = null; + $this->wire = null; + $this->xml = null; + + $soap_data = $this->_generate($method, $params, $namespace, $soapAction); + if (PEAR::isError($soap_data)) { + $fault = $this->_raiseSoapFault($soap_data); + return $fault; + } + + // _generate() may have changed the endpoint if the WSDL has more + // than one service, so we need to see if we need to generate a new + // transport to hook to a different URI. Since the transport protocol + // can also change, we need to get an entirely new object. This could + // probably be optimized. + if (!$this->_soap_transport || + $this->_endpoint != $this->_soap_transport->url) { + $this->_soap_transport =& SOAP_Transport::getTransport($this->_endpoint); + if (PEAR::isError($this->_soap_transport)) { + $fault =& $this->_soap_transport; + $this->_soap_transport = null; + $fault = $this->_raiseSoapFault($fault); + return $fault; + } + } + $this->_soap_transport->encoding = $this->_encoding; + + // Send the message. + $transport_options = array_merge_recursive($this->_proxy_params, + $this->_options); + $this->xml = $this->_soap_transport->send($soap_data, $transport_options); + + // Save the wire information for debugging. + if ($this->_options['trace']) { + $this->_last_request = $this->_soap_transport->outgoing_payload; + $this->_last_response = $this->_soap_transport->incoming_payload; + $this->wire = $this->getWire(); + } + if ($this->_soap_transport->fault) { + $fault = $this->_raiseSoapFault($this->xml); + return $fault; + } + + if (isset($this->_options['result']) && + $this->_options['result'] != 'parse') { + return $this->xml; + } + + $this->__result_encoding = $this->_soap_transport->result_encoding; + + $result = &$this->parseResponse($this->xml, $this->__result_encoding, + $this->_soap_transport->attachments); + return $result; + } + + /** + * Sets an option to use with the transport layers. + * + * For example: + * + * $soapclient->setOpt('curl', CURLOPT_VERBOSE, 1) + * + * to pass a specific option to curl if using an SSL connection. + * + * @access public + * + * @param string $category Category to which the option applies or option + * name. + * @param string $option An option name if $category is a category name, + * an option value if $category is an option name. + * @param string $value An option value if $category is a category + * name. + */ + function setOpt($category, $option, $value = null) + { + if (!is_null($value)) { + if (!isset($this->_options[$category])) { + $this->_options[$category] = array(); + } + $this->_options[$category][$option] = $value; + } else { + $this->_options[$category] = $option; + } + } + + /** + * Call method supporting the overload extension. + * + * If the overload extension is loaded, you can call the client class with + * a soap method name: + * + * $soap = new SOAP_Client(....); + * $value = $soap->getStockQuote('MSFT'); + * + * + * @access public + * + * @param string $method The method to call. + * @param array $params The method parameters. + * @param mixed $return_value Will get the method's return value + * assigned. + * + * @return boolean Always true. + */ + function _call($method, $params, &$return_value) + { + // Overloading lowercases the method name, we need to look into the + // WSDL and try to find the correct method name to get the correct + // case for the call. + if ($this->_wsdl) { + $this->_wsdl->matchMethod($method); + } + + $return_value =& $this->call($method, $params); + + return true; + } + + /** + * @deprecated Use getLastRequest(). + */ + function &__getlastrequest() + { + $request = $this->getLastRequest(); + return $request; + } + + /** + * Returns the XML content of the last SOAP request. + * + * @return string The last request. + */ + function getLastRequest() + { + return $this->_last_request; + } + + /** + * @deprecated Use getLastResponse(). + */ + function &__getlastresponse() + { + $response =& $this->getLastResponse; + return $response; + } + + /** + * Returns the XML content of the last SOAP response. + * + * @return string The last response. + */ + function getLastResponse() + { + return $this->_last_response; + } + + /** + * @deprecated Use setUse(). + */ + function __use($use) + { + $this->setUse($use); + } + + /** + * Sets the SOAP encoding. + * + * @param string $use Either 'literal' or 'encoded' (section 5). + */ + function setUse($use) + { + $this->_options['use'] = $use; + } + + /** + * @deprecated Use setStyle(). + */ + function __style($style) + { + $this->setStyle($style); + } + + /** + * Sets the SOAP encoding style. + * + * @param string $style Either 'document' or 'rpc'. + */ + function setStyle($style) + { + $this->_options['style'] = $style; + } + + /** + * @deprecated Use setTrace(). + */ + function __trace($level) + { + $this->setTrace($level); + } + + /** + * Sets whether to trace the traffic on the transport level. + * + * @see getWire() + * + * @param boolean $trace + */ + function setTrace($trace) + { + $this->_options['trace'] = $trace; + } + + function _generate($method, &$params, $namespace = false, + $soapAction = false) + { + $this->fault = null; + $this->_options['input'] = 'parse'; + $this->_options['result'] = 'parse'; + $this->_options['parameters'] = false; + + if ($params && gettype($params) != 'array') { + $params = array($params); + } + + if (gettype($namespace) == 'array') { + foreach ($namespace as $optname => $opt) { + $this->_options[strtolower($optname)] = $opt; + } + if (isset($this->_options['namespace'])) { + $namespace = $this->_options['namespace']; + } else { + $namespace = false; + } + } else { + // We'll place $soapAction into our array for usage in the + // transport. + $this->_options['soapaction'] = $soapAction; + $this->_options['namespace'] = $namespace; + } + + if ($this->_endpointType == 'wsdl') { + $this->_setSchemaVersion($this->_wsdl->xsd); + + // Get port name. + if (!$this->_portName) { + $this->_portName = $this->_wsdl->getPortName($method); + } + if (PEAR::isError($this->_portName)) { + return $this->_raiseSoapFault($this->_portName); + } + + // Get endpoint. + $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName); + if (PEAR::isError($this->_endpoint)) { + return $this->_raiseSoapFault($this->_endpoint); + } + + // Get operation data. + $opData = $this->_wsdl->getOperationData($this->_portName, $method); + + if (PEAR::isError($opData)) { + return $this->_raiseSoapFault($opData); + } + $namespace = $opData['namespace']; + $this->_options['style'] = $opData['style']; + $this->_options['use'] = $opData['input']['use']; + $this->_options['soapaction'] = $opData['soapAction']; + + // Set input parameters. + if ($this->_options['input'] == 'parse') { + $this->_options['parameters'] = $opData['parameters']; + $nparams = array(); + if (isset($opData['input']['parts']) && + count($opData['input']['parts'])) { + foreach ($opData['input']['parts'] as $name => $part) { + $xmlns = ''; + $attrs = array(); + // Is the name a complex type? + if (isset($part['element'])) { + $xmlns = $this->_wsdl->namespaces[$part['namespace']]; + $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; + $name = $part['name']; + } + if (isset($params[$name]) || + $this->_wsdl->getDataHandler($name, $part['namespace'])) { + $nparams[$name] =& $params[$name]; + } else { + // We now force an associative array for + // parameters if using WSDL. + return $this->_raiseSoapFault("The named parameter $name is not in the call parameters."); + } + if (gettype($nparams[$name]) != 'object' || + !is_a($nparams[$name], 'SOAP_Value')) { + // Type is likely a qname, split it apart, and get + // the type namespace from WSDL. + $qname = new QName($part['type']); + if ($qname->ns) { + $type_namespace = $this->_wsdl->namespaces[$qname->ns]; + } elseif (isset($part['namespace'])) { + $type_namespace = $this->_wsdl->namespaces[$part['namespace']]; + } else { + $type_namespace = null; + } + $qname->namespace = $type_namespace; + $pqname = $name; + if ($xmlns) { + $pqname = '{' . $xmlns . '}' . $name; + } + $nparams[$name] = new SOAP_Value($pqname, + $qname->fqn(), + $nparams[$name], + $attrs); + } else { + // WSDL fixups to the SOAP value. + } + } + } + $params =& $nparams; + unset($nparams); + } + } else { + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + } + + // Serialize the message. + $this->_section5 = (!isset($this->_options['use']) || + $this->_options['use'] != 'literal'); + + if (!isset($this->_options['style']) || + $this->_options['style'] == 'rpc') { + $this->_options['style'] = 'rpc'; + $this->docparams = true; + $mqname = new QName($method, $namespace); + $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params); + $soap_msg = $this->makeEnvelope($methodValue, + $this->headersOut, + $this->_encoding, + $this->_options); + } else { + if (!$params) { + $mqname = new QName($method, $namespace); + $mynull = null; + $params = new SOAP_Value($mqname->fqn(), 'Struct', $mynull); + } elseif ($this->_options['input'] == 'parse') { + if (is_array($params)) { + $nparams = array(); + $keys = array_keys($params); + foreach ($keys as $k) { + if (gettype($params[$k]) != 'object') { + $nparams[] = new SOAP_Value($k, + false, + $params[$k]); + } else { + $nparams[] =& $params[$k]; + } + } + $params =& $nparams; + } + if ($this->_options['parameters']) { + $mqname = new QName($method, $namespace); + $params = new SOAP_Value($mqname->fqn(), + 'Struct', + $params); + } + } + $soap_msg = $this->makeEnvelope($params, + $this->headersOut, + $this->_encoding, + $this->_options); + } + unset($this->headersOut); + + if (PEAR::isError($soap_msg)) { + return $this->_raiseSoapFault($soap_msg); + } + + // Handle MIME or DIME encoding. + // TODO: DIME encoding should move to the transport, do it here for + // now and for ease of getting it done. + if (count($this->_attachments)) { + if ((isset($this->_options['attachments']) && + $this->_options['attachments'] == 'Mime') || + isset($this->_options['Mime'])) { + $soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding); + } else { + // default is dime + $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding); + $this->_options['headers']['Content-Type'] = 'application/dime'; + } + if (PEAR::isError($soap_msg)) { + return $this->_raiseSoapFault($soap_msg); + } + } + + // Instantiate client. + if (is_array($soap_msg)) { + $soap_data = $soap_msg['body']; + if (count($soap_msg['headers'])) { + if (isset($this->_options['headers'])) { + $this->_options['headers'] = array_merge($this->_options['headers'], $soap_msg['headers']); + } else { + $this->_options['headers'] = $soap_msg['headers']; + } + } + } else { + $soap_data = $soap_msg; + } + + return $soap_data; + } + + /** + * @deprecated Use parseResponse(). + */ + function &__parse(&$response, $encoding, &$attachments) + { + return $this->parseResponse($response, $encoding, $attachments); + } + + /** + * Parses a SOAP response. + * + * @see SOAP_Parser:: + * + * @param string $response XML content of SOAP response. + * @param string $encoding Character set encoding, defaults to 'UTF-8'. + * @param array $attachments List of attachments. + */ + function &parseResponse($response, $encoding, &$attachments) + { + // Parse the response. + $response =& new SOAP_Parser($response, $encoding, $attachments); + if ($response->fault) { + $fault =& $this->_raiseSoapFault($response->fault); + return $fault; + } + + // Return array of parameters. + $return =& $response->getResponse(); + $headers =& $response->getHeaders(); + if ($headers) { + $this->headersIn =& $this->_decodeResponse($headers, false); + } + + $decoded = &$this->_decodeResponse($return); + return $decoded; + } + + /** + * Converts a complex SOAP_Value into a PHP Array + * + * @param SOAP_Value $response value object + * @param boolean $shift FIXME + * @return Array + */ + function &_decodeResponse($response, $shift = true) + { + if (!$response) { + $decoded = null; + return $decoded; + } + + // Check for valid response. + if (PEAR::isError($response)) { + $fault =& $this->_raiseSoapFault($response); + return $fault; + } elseif (!is_a($response, 'soap_value')) { + $fault =& $this->_raiseSoapFault("Didn't get SOAP_Value object back from client"); + return $fault; + } + + // Decode to native php datatype. + $returnArray =& $this->_decode($response); + + // Fault? + if (PEAR::isError($returnArray)) { + $fault =& $this->_raiseSoapFault($returnArray); + return $fault; + } + + if (is_object($returnArray) && + strcasecmp(get_class($returnArray), 'stdClass') == 0) { + $returnArray = get_object_vars($returnArray); + } + if (is_array($returnArray)) { + if (isset($returnArray['faultcode']) || + isset($returnArray['SOAP-ENV:faultcode'])) { + $faultcode = $faultstring = $faultdetail = $faultactor = ''; + foreach ($returnArray as $k => $v) { + if (stristr($k, 'faultcode')) $faultcode = $v; + if (stristr($k, 'faultstring')) $faultstring = $v; + if (stristr($k, 'detail')) $faultdetail = $v; + if (stristr($k, 'faultactor')) $faultactor = $v; + } + $fault =& $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); + return $fault; + } + // Return array of return values. + if ($shift && count($returnArray) == 1) { + $decoded = array_shift($returnArray); + return $decoded; + } + return $returnArray; + } + return $returnArray; + } + + /** + * @deprecated Use getWire(). + */ + function __get_wire() + { + return $this->getWire(); + } + + /** + * Returns the outgoing and incoming traffic on the transport level. + * + * Tracing has to be enabled. + * + * @see setTrace() + * + * @return string The complete traffic between the client and the server. + */ + function getWire() + { + if ($this->_options['trace'] && + ($this->_last_request || $this->_last_response)) { + return "OUTGOING:\n\n" . + $this->_last_request . + "\n\nINCOMING\n\n" . + preg_replace("/>\r\n<", $this->_last_response); + } + + return null; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Disco.php b/gulliver/thirdparty/pear/SOAP/Disco.php new file mode 100644 index 000000000..618e63d46 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Disco.php @@ -0,0 +1,383 @@ + + * @author Chuck Hagenbuch + * @author Jan Schneider + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; + +class SOAP_DISCO_Server extends SOAP_Base_Object { + + var $namespaces = array(SCHEMA_WSDL => 'wsdl', SCHEMA_SOAP => 'soap'); + var $import_ns = array(); + var $wsdl = ''; + var $disco = ''; + var $_wsdl = array(); + var $_disco = array(); + var $_service_name = ''; + var $_service_ns = ''; + var $_service_desc = ''; + var $_portname = ''; + var $_bindingname = ''; + var $soap_server = NULL; + + + function SOAP_DISCO_Server($soap_server, $service_name, $service_desc = '', + $import_ns = null) + { + parent::SOAP_Base_Object('Server'); + + if ( !is_object($soap_server) + || !get_class($soap_server) == 'soap_server') return; + + $this->_service_name = $service_name; + $this->_service_ns = "urn:$service_name"; + $this->_service_desc = $service_desc; + $this->import_ns = isset($import_ns) ? $import_ns : $this->import_ns; + $this->soap_server = $soap_server; + $this->host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; + } + + function getDISCO() + { + $this->_generate_DISCO(); + return $this->disco; + } + + function getWSDL() + { + $this->_generate_WSDL(); + return $this->wsdl; + } + + function _generate_DISCO() + { + // DISCO + $this->_disco['disco:discovery']['attr']['xmlns:disco'] = SCHEMA_DISCO; + $this->_disco['disco:discovery']['attr']['xmlns:scl'] = SCHEMA_DISCO_SCL; + $this->_disco['disco:discovery']['scl:contractRef']['attr']['ref'] = + (array_key_exists('HTTPS', $_SERVER) && $_SERVER['HTTPS'] == 'on') + ? 'https://' . $this->host . $_SERVER['PHP_SELF'] . '?wsdl' + : 'http://' . $this->host . $_SERVER['PHP_SELF'] . '?wsdl'; + + // generate disco xml + $this->_generate_DISCO_XML($this->_disco); + } + + function _generate_WSDL() + { + // WSDL + if (is_array($this->soap_server->_namespaces)) { + // need to get: typens, xsd & SOAP-ENC + $flipped = array_flip($this->soap_server->_namespaces); + $this->namespaces[$this->_service_ns] = 'tns'; + $this->namespaces[$flipped['xsd']] = 'xsd'; + $this->namespaces[$flipped['SOAP-ENC']] = 'SOAP-ENC'; + } + + // DEFINITIONS + $this->_wsdl['definitions']['attr']['name'] = $this->_service_name; + $this->_wsdl['definitions']['attr']['targetNamespace'] = $this->_service_ns; + foreach ($this->namespaces as $ns => $prefix) { + $this->_wsdl['definitions']['attr']['xmlns:' . $prefix] = $ns; + } + $this->_wsdl['definitions']['attr']['xmlns'] = SCHEMA_WSDL; + + // Import namespaces. Seems to not work yet: wsdl.exe fom .NET can't + // handle imported complete wsdl-definitions. + if (count($this->import_ns)) { + $i = 0; + foreach ($this->import_ns as $_ns => $_location) { + $this->_wsdl['definitions']['import'][$i]['attr']['location'] = $_location; + $this->_wsdl['definitions']['import'][$i]['attr']['namespace'] = $_ns; + $i++; + } + } + $this->_wsdl['definitions']['types']['attr']['xmlns']='http://schemas.xmlsoap.org/wsdl/'; + $this->_wsdl['definitions']['types']['schema']=array(); + + // Placeholder for messages + $this->_wsdl['definitions']['message'] = array(); + + // PORTTYPE-NAME + $this->_portname = $this->_service_name . 'Port'; + $this->_wsdl['definitions']['portType']['attr']['name'] = $this->_portname; + + // BINDING-NAME + $this->_bindingname = $this->_service_name . 'Binding'; + $this->_wsdl['definitions']['binding']['attr']['name'] = $this->_bindingname; + $this->_wsdl['definitions']['binding']['attr']['type'] = 'tns:' . $this->_portname; + $this->_wsdl['definitions']['binding']['soap:binding']['attr']['style'] = 'rpc'; + $this->_wsdl['definitions']['binding']['soap:binding']['attr']['transport'] = SCHEMA_SOAP_HTTP; + + // SERVICE + $this->_wsdl['definitions']['service']['attr']['name'] = $this->_service_name . 'Service'; + $this->_wsdl['definitions']['service']['documentation']['attr'] = ''; + $this->_wsdl['definitions']['service']['documentation'] = htmlentities($this->_service_desc); + $this->_wsdl['definitions']['service']['port']['attr']['name'] = $this->_portname; + $this->_wsdl['definitions']['service']['port']['attr']['binding'] = 'tns:' . $this->_bindingname; + $this->_wsdl['definitions']['service']['port']['soap:address']['attr']['location'] = + (array_key_exists('HTTPS', $_SERVER) && $_SERVER['HTTPS'] == 'on') + ? 'https://' . $this->host . $_SERVER['PHP_SELF'] + : 'http://' . $this->host . $_SERVER['PHP_SELF']; + + // + $dispatch_keys = array_keys($this->soap_server->dispatch_objects); + $dc = count($dispatch_keys); + for ($di = 0; $di < $dc; $di++) { + $namespace = $dispatch_keys[$di]; + $namespace_objects =& $this->soap_server->dispatch_objects[$namespace]; + $oc = count($namespace_objects); + for ($oi = 0; $oi < $oc; $oi++) { + $object = $namespace_objects[$oi]; + // types definitions + $this->addSchemaFromMap($object->__typedef); + // MESSAGES + $this->addMethodsFromMap($object->__dispatch_map, $namespace, get_class($object)); + } + } + if (isset($this->soap_server->dispatch_map)) { + $this->addMethodsFromMap($this->soap_server->dispatch_map, $namespace); + } + + // generate wsdl + $this->_generate_WSDL_XML(); + } + + function &_getSchema($namespace) + { + // SCHEMA + $c = count($this->_wsdl['definitions']['types']['schema']); + for($i = 0; $i < $c; $i++) { + if ($this->_wsdl['definitions']['types']['schema'][$i]['attr']['targetNamespace'] == $namespace) { + return $this->_wsdl['definitions']['types']['schema'][$i]; + } + } + + // don't have this namespace + $schema = array(); + $schema['attr'] = array(); + $schema['complexType'] = array(); + $schema['attr']['xmlns'] = array_search('xsd',$this->namespaces); + $schema['attr']['targetNamespace'] = $namespace; + $this->_wsdl['definitions']['types']['schema'][] =& $schema; + + return $schema; + } + + function addSchemaFromMap(&$map) + { + if (!$map) { + return; + } + + foreach ($map as $_type_name => $_type_def) { + list($typens,$type) = $this->_getTypeNs($_type_name); + if ($typens == 'xsd') { + // cannot add to xsd, lets use method_namespace + $typens = 'tns'; + } + $schema =& $this->_getSchema(array_search($typens, $this->namespaces)); + if (!$this->_ifComplexTypeExists($schema['complexType'], $type)) { + $ctype =& $schema['complexType'][]; + $ctype['attr']['name'] = $type; + foreach ($_type_def as $_varname => $_vartype) { + if (!is_int($_varname)) { + list($_vartypens,$_vartype) = $this->_getTypeNs($_vartype); + $ctype['all']['attr'] = ''; + $el =& $ctype['all']['element'][]; + $el['attr']['name'] = $_varname; + $el['attr']['type'] = $_vartypens . ':' . $_vartype; + } else { + $ctype['complexContent']['attr'] = ''; + $ctype['complexContent']['restriction']['attr']['base'] = 'SOAP-ENC:Array'; + foreach ($_vartype as $array_type) { + list($_vartypens, $_vartype) = $this->_getTypeNs($array_type); + $ctype['complexContent']['restriction']['attribute']['attr']['ref'] = 'SOAP-ENC:arrayType'; + $ctype['complexContent']['restriction']['attribute']['attr']['wsdl:arrayType'] = $_vartypens . ':' . $_vartype . '[]'; + } + } + } + } + } + } + + function addMethodsFromMap(&$map, $namespace, $classname = null) + { + if (!$map) { + return; + } + + foreach ($map as $method_name => $method_types) { + if (array_key_exists('namespace', $method_types)) { + $method_namespace = $method_types['namespace']; + } else { + $method_namespace = $namespace; + } + + // INPUT + $input_message = array('attr' => array('name' => $method_name . 'Request')); + if (isset($method_types['in']) && is_array($method_types['in'])) { + foreach ($method_types['in'] as $name => $type) { + list($typens, $type) = $this->_getTypeNs($type); + $part = array(); + $part['attr']['name'] = $name; + $part['attr']['type'] = $typens . ':' . $type; + $input_message['part'][] = $part; + } + } + $this->_wsdl['definitions']['message'][] = $input_message; + + // OUTPUT + $output_message = array('attr' => array('name' => $method_name . 'Response')); + if (isset($method_types['out']) && is_array($method_types['out'])) { + foreach ($method_types['out'] as $name => $type) { + list($typens, $type) = $this->_getTypeNs($type); + $part = array(); + $part['attr']['name'] = $name; + $part['attr']['type'] = $typens . ':' . $type; + $output_message['part'][] = $part; + } + } + $this->_wsdl['definitions']['message'][] = $output_message; + + // PORTTYPES + $operation = array(); + $operation['attr']['name'] = $method_name; + // INPUT + $operation['input']['attr']['message'] = 'tns:' . $input_message['attr']['name']; + // OUTPUT + $operation['output']['attr']['message'] = 'tns:' . $output_message['attr']['name']; + $this->_wsdl['definitions']['portType']['operation'][] = $operation; + + // BINDING + $binding = array(); + $binding['attr']['name'] = $method_name; + $action = $method_namespace . '#' . ($classname ? $classname . '#' : '') . $method_name; + $binding['soap:operation']['attr']['soapAction'] = $action; + // INPUT + $binding['input']['attr'] = ''; + $binding['input']['soap:body']['attr']['use'] = 'encoded'; + $binding['input']['soap:body']['attr']['namespace'] = $method_namespace; + $binding['input']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; + // OUTPUT + $binding['output']['attr'] = ''; + $binding['output']['soap:body']['attr']['use'] = 'encoded'; + $binding['output']['soap:body']['attr']['namespace'] = $method_namespace; + $binding['output']['soap:body']['attr']['encodingStyle'] = SOAP_SCHEMA_ENCODING; + $this->_wsdl['definitions']['binding']['operation'][] = $binding; + } + } + + function _generate_DISCO_XML($disco_array) + { + $disco = ''; + foreach ($disco_array as $key => $val) { + $disco .= $this->_arrayToNode($key,$val); + } + $this->disco = $disco; + } + + function _generate_WSDL_XML() + { + $wsdl = ''; + foreach ($this->_wsdl as $key => $val) { + $wsdl .= $this->_arrayToNode($key, $val); + } + $this->wsdl = $wsdl; + } + + function _arrayToNode($node_name = '', $array) + { + $return = ''; + if (is_array($array)) { + // we have a node if there's key 'attr' + if (array_key_exists('attr',$array)) { + $return .= "<$node_name"; + if (is_array($array['attr'])) { + foreach ($array['attr'] as $attr_name => $attr_value) { + $return .= " $attr_name=\"$attr_value\""; + } + } + + // unset 'attr' and proceed other childs... + unset($array['attr']); + + if (count($array) > 0) { + $i = 0; + foreach ($array as $child_node_name => $child_node_value) { + $return .= $i == 0 ? ">\n" : ''; + $return .= $this->_arrayToNode($child_node_name,$child_node_value); + $i++; + } + $return .= "\n"; + } else { + $return .= " />\n"; + } + } else { + // we have no 'attr' key in array - so it's list of nodes with + // the same name ... + foreach ($array as $child_node_name => $child_node_value) { + $return .= $this->_arrayToNode($node_name,$child_node_value); + } + } + } else { + // $array is not an array + if ($array !='') { + // and its not empty + $return .= "<$node_name>$array\n"; + } else { + // and its empty... + $return .= "<$node_name />\n"; + } + } + return $return; + } + + function _getTypeNs($type) + { + preg_match_all("'\{(.*)\}'sm", $type, $m); + if (isset($m[1][0]) && $m[1][0] != '') { + if (!array_key_exists($m[1][0],$this->namespaces)) { + $ns_pref = 'ns' . count($this->namespaces); + $this->namespaces[$m[1][0]] = $ns_pref; + $this->_wsdl['definitions']['attr']['xmlns:' . $ns_pref] = $m[1][0]; + } + $typens = $this->namespaces[$m[1][0]]; + $type = ereg_replace($m[0][0],'',$type); + } else { + $typens = 'xsd'; + } + return array($typens,$type); + } + + function _ifComplexTypeExists($typesArray, $type_name) + { + if (is_array($typesArray)) { + foreach ($typesArray as $type_data) { + if ($type_data['attr']['name'] == $type_name) { + return true; + } + } + } + return false; + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Fault.php b/gulliver/thirdparty/pear/SOAP/Fault.php new file mode 100644 index 000000000..594b817ca --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Fault.php @@ -0,0 +1,127 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2006 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'PEAR.php'; + +/** + * PEAR::Error wrapper used to match SOAP Faults to PEAR Errors + * + * SOAP_Fault transmissions normally contain a complete backtrace of the + * error. Revealing these details in a public web services is a bad idea + * because it can be used by attackers. Backtrace information can be kept out + * of SOAP_Fault responses by putting the following code in your script after + * your "require_once 'SOAP/Server.php';" line: + * + * + * $skiptrace =& PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); + * $skiptrace = true; + * + * + * @package SOAP + * @access public + * @author Shane Caraveo Port to PEAR and more + * @author Dietrich Ayala Original Author + */ +class SOAP_Fault extends PEAR_Error +{ + /** + * Constructor. + * + * @param string $faultstring Message string for fault. + * @param mixed $faultcode The faultcode. + * @param mixed $faultactor + * @param mixed $detail @see PEAR_Error + * @param array $mode @see PEAR_Error + * @param array $options @see PEAR_Error + */ + function SOAP_Fault($faultstring = 'unknown error', $faultcode = 'Client', + $faultactor = null, $detail = null, $mode = null, + $options = null) + { + parent::PEAR_Error($faultstring, $faultcode, $mode, $options, $detail); + if ($faultactor) { + $this->error_message_prefix = $faultactor; + } + } + + /** + * Returns a SOAP XML message that can be sent as a server response. + * + * @return string + */ + function message($encoding = SOAP_DEFAULT_ENCODING) + { + $msg = new SOAP_Base(); + $params = array(); + $params[] = new SOAP_Value('faultcode', 'QName', 'SOAP-ENV:' . $this->code); + $params[] = new SOAP_Value('faultstring', 'string', $this->message); + $params[] = new SOAP_Value('faultactor', 'anyURI', $this->error_message_prefix); + if (isset($this->backtrace)) { + $params[] = new SOAP_Value('detail', 'string', $this->backtrace); + } else { + $params[] = new SOAP_Value('detail', 'string', $this->userinfo); + } + + $methodValue = new SOAP_Value('{' . SOAP_ENVELOP . '}Fault', 'Struct', $params); + $headers = null; + return $msg->makeEnvelope($methodValue, $headers, $encoding); + } + + /** + * Returns a simple native PHP array containing the fault data. + * + * @return array + */ + function getFault() + { + $fault = new stdClass(); + $fault->faultcode = $this->code; + $fault->faultstring = $this->message; + $fault->faultactor = $this->error_message_prefix; + $fault->detail = $this->userinfo; + return $fault; + } + + /** + * Returns the SOAP actor for the fault. + * + * @return string + */ + function getActor() + { + return $this->error_message_prefix; + } + + /** + * Returns the fault detail. + * + * @return string + */ + function getDetail() + { + return $this->userinfo; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/config.php.dist b/gulliver/thirdparty/pear/SOAP/Interop/config.php.dist new file mode 100644 index 000000000..4d8201cb1 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/config.php.dist @@ -0,0 +1,4 @@ + + + + + PEAR SOAP Interop + + + + +

    PEAR SOAP Interop

    +

    Welcome to the PEAR SOAP Interop pages. These pages are set up for +SOAP Builder interop tests.

    + +\n"; +} + +?> +
    $test\n"; + echo "WSDL: wsdlURL}\">{$ep->wsdlURL}
    \n"; + echo "Endpoint: {$ep->endpointURL}
    \n"; + echo "
    +

    Interop Client

    + +

    +Notes: +Tests are done both "Direct" and with "WSDL". WSDL tests use the supplied interop WSDL +to run the tests against. The Direct method uses an internal prebuilt list of methods and parameters +for the test.

    +

    +Tests are also run against two methods of generating method parameters. The first, 'php', attempts +to directly serialize PHP variables into soap values. The second method, 'soapval', uses a SOAP_Value +class to define what the type of the value is. The second method is more interopable than the first +by nature. +

    + +

    Interop Client Test Results

    +

    This is a database of the current test results using PEAR SOAP Clients against interop servers.

    +

    +More detail (wire) about errors (marked yellow or red) can be obtained by clicking on the +link in the result box. If we have an HTTP error +attempting to connect to the endpoint, we will mark all consecutive attempts as errors, and skip +testing that endpoint. This reduces the time it takes to run the tests if a server is unavailable. +WSDLCACHE errors mean we cannot retreive the WSDL file specified for the endpoint. +

    + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2Base.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2Base.php new file mode 100644 index 000000000..cf36be7d9 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2Base.php @@ -0,0 +1,155 @@ + Port to PEAR and more | +// | Authors: Dietrich Ayala Original Author | +// +----------------------------------------------------------------------+ +// +// $Id: interop_Round2Base.php,v 1.9 2007/01/26 00:06:11 yunosh Exp $ +// +require_once 'params_classes.php'; + +function &generateFault($short, $long) +{ + $params = array( + 'faultcode' => 'Server', + 'faultstring' => $short, + 'detail' => $long + ); + + $faultmsg = new SOAP_Message('Fault', $params, 'http://schemas.xmlsoap.org/soap/envelope/'); + return $faultmsg; +} + +function hex2bin($data) +{ + $len = strlen($data); + return pack('H' . $len, $data); +} + + +class SOAP_Interop_Base { + + function echoString($inputString) + { + return new SOAP_Value('outputString', 'string', $inputString); + } + + function echoStringArray($inputStringArray) + { + $ra = array(); + if ($inputStringArray) { + foreach($inputStringArray as $s) { + $ra[] = new SOAP_Value('item', 'string', $s); + } + } + return new SOAP_Value('outputStringArray', null, $ra); + } + + + function echoInteger($inputInteger) + { + return new SOAP_Value('outputInteger', 'int', (integer)$inputInteger); + } + + function echoIntegerArray($inputIntegerArray) + { + $ra = array(); + if ($inputIntegerArray) { + foreach ($inputIntegerArray as $i) { + $ra[] = new SOAP_Value('item', 'int', $i); + } + } + return new SOAP_Value('outputIntArray', null, $ra); + } + + function echoFloat($inputFloat) + { + return new SOAP_Value('outputFloat', 'float', (float)$inputFloat); + } + + function echoFloatArray($inputFloatArray) + { + $ra = array(); + if ($inputFloatArray) { + foreach($inputFloatArray as $float) { + $ra[] = new SOAP_Value('item', 'float', (FLOAT)$float); + } + } + return new SOAP_Value('outputFloatArray', null, $ra); + } + + function echoStruct($inputStruct) + { + if (strtolower(get_class($inputStruct)) == 'soapstruct') { + return $inputStruct->__to_soap(); + } + return $inputStruct; + } + + function echoStructArray($inputStructArray) + { + $ra = array(); + if ($inputStructArray) { + $c = count($inputStructArray); + for ($i = 0; $i < $c; $i++) { + $ra[] = $this->echoStruct($inputStructArray[$i]); + } + } + return $ra; + } + + function echoVoid() + { + return NULL; + } + + function echoBase64($b_encoded) + { + return new SOAP_Value('return', 'base64Binary', base64_encode(base64_decode($b_encoded))); + } + + function echoDate($timeInstant) + { + require_once 'SOAP/Type/dateTime.php'; + $dt = new SOAP_Type_dateTime($timeInstant); + if ($dt->toUnixtime() != -1) { + $value = $dt->toSOAP(); + return new SOAP_Value('return', 'dateTime', $value); + } else { + return new SOAP_Fault("Value $timeInstant is not a dateTime value"); + } + } + + function echoHexBinary($hb) + { + return new SOAP_Value('return', 'hexBinary', bin2hex(hex2bin($hb))); + } + + function echoDecimal($dec) + { + return new SOAP_Value('return', 'decimal', (float)$dec); + } + + function echoBoolean($boolean) + { + return new SOAP_Value('return', 'boolean', $boolean); + } + + function echoMimeAttachment($stuff) + { + return new SOAP_Attachment('return', 'application/octet-stream', null, $stuff); + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupB.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupB.php new file mode 100644 index 000000000..f02404826 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupB.php @@ -0,0 +1,99 @@ + Port to PEAR and more | +// | Authors: Dietrich Ayala Original Author | +// +----------------------------------------------------------------------+ +// +// $Id: interop_Round2GroupB.php,v 1.9 2007/01/22 14:53:21 yunosh Exp $ +// +require_once 'params_classes.php'; + +class SOAP_Interop_GroupB { + + var $__dispatch_map = array(); + + function SOAP_Interop_GroupB() + { + $this->__dispatch_map['echoStructAsSimpleTypes'] = + array('in' => array('inputStruct' => 'SOAPStruct'), + 'out' => array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float')); + $this->__dispatch_map['echoSimpleTypesAsStruct'] = + array('in' => array('inputString' => 'string', 'inputInteger' => 'int', 'inputFloat' => 'float'), + 'out' => array('return' => 'SOAPStruct')); + $this->__dispatch_map['echoNestedStruct'] = + array('in' => array('inputStruct' => 'SOAPStructStruct'), + 'out' => array('return' => 'SOAPStructStruct')); + $this->__dispatch_map['echo2DStringArray'] = + array('in' => array('input2DStringArray' => 'ArrayOfString2D'), + 'out' => array('return' => 'ArrayOfString2D')); + $this->__dispatch_map['echoNestedArray'] = + array('in' => array('inputString' => 'SOAPArrayStruct'), + 'out' => array('return' => 'SOAPArrayStruct')); + } + + /* this private function is called on by SOAP_Server to determine any + * special dispatch information that might be necessary. This, for + * example, can be used to set up a dispatch map for functions that return + * multiple OUT parameters. */ + function __dispatch($methodname) + { + if (array_key_exists($methodname,$this->__dispatch_map)) { + return $this->__dispatch_map[$methodname]; + } + return null; + } + + function echoStructAsSimpleTypes ($struct) + { + // Convert a SOAPStruct to an array. + return array( + new SOAP_Value('outputString','string',$struct->varString), + new SOAP_Value('outputInteger','int',$struct->varInt), + new SOAP_Value('outputFloat','float',$struct->varFloat)); + } + + function echoSimpleTypesAsStruct($string, $int, $float) + { + // Convert a input into struct. + $v = new SOAPStruct($string, $int, $float); + return new SOAP_Value('return', '{http://soapinterop.org/xsd}SOAPStruct', $v); + } + + function echoNestedStruct($struct) + { + $separator = "\n"; + $methods = get_class_methods($struct); + $arr_str = $separator . strtolower(implode($separator, $methods)); + $string = $separator . '__to_soap' . $separator; + if (strpos($arr_str, $string) !== false) { + return $struct->__to_soap(); + } + return $struct; + } + + function echo2DStringArray($array) + { + $ret = new SOAP_Value('return', 'Array', $array); + $ret->options['flatten'] = true; + return $ret; + } + + function echoNestedArray($array) + { + return $array; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupC.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupC.php new file mode 100644 index 000000000..aca3d86db --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round2GroupC.php @@ -0,0 +1,35 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_Round2GroupC.php,v 1.5 2007/01/22 14:53:21 yunosh Exp $ +// +require_once 'SOAP/Value.php'; + +class SOAP_Interop_GroupC_Headers { + + function echoMeStringRequest($string) + { + return new SOAP_Value('{http://soapinterop.org/echoheader/}echoMeStringResponse', 'string', $string); + } + + function echoMeStructRequest($struct) + { + return new SOAP_Value('{http://soapinterop.org/echoheader/}echoMeStructResponse', 'SOAPStruct', $struct); + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_Round3GroupD.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round3GroupD.php new file mode 100644 index 000000000..b4e198d2a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_Round3GroupD.php @@ -0,0 +1,82 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_Round3GroupD.php,v 1.5 2007/01/22 14:53:21 yunosh Exp $ +// +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupD { + + // wsdlns:SoapInteropEmptySABinding + function echoString($inputString) + { + return new SOAP_Value('outputString', 'string', $inputString); + } + + function echoStringArray($inputStringArray) + { + $ra = array(); + if ($inputStringArray) { + foreach ($inputStringArray as $s) { + $ra[] = new SOAP_Value('item', 'string', $s); + } + } + return new SOAP_Value('outputStringArray', null, $ra); + } + + function echoStruct($inputStruct) + { + return $inputStruct->to_soap(); + } + + function echoStructArray($inputStructArray) + { + $ra = array(); + if ($inputStructArray) { + $c = count($inputStructArray); + for ($i = 0; $i < $c; $i++) { + $ra[] = $inputStructArray[$i]->to_soap(); + } + } + return $ra; + } + + function echoVoid() + { + return null; + } + + function echoPerson() + { + return null; + } + + function x_Document(&$document) + { + return new SOAP_Value('result_Document', '{http://soapinterop.org/xsd}x_Document', $document); + } + + function echoEmployee() + { + return null; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_client.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_client.php new file mode 100644 index 000000000..50b62fb30 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_client.php @@ -0,0 +1,805 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_client.php,v 1.16 2007/01/26 17:21:26 yunosh Exp $ +// +require_once 'DB.php'; // PEAR/DB +require_once 'SOAP/Client.php'; + +require_once 'config.php'; +require_once 'interop_test_functions.php'; +require_once 'interop_test.php'; +require_once 'params_Round2Base.php'; +require_once 'params_Round2GroupB.php'; +require_once 'params_Round2GroupC.php'; +require_once 'params_Round3GroupD.php'; +require_once 'registrationAndNotification.php'; + +error_reporting(E_ALL ^ E_NOTICE); +$INTEROP_LOCAL_SERVER = false; + +class Interop_Client +{ + // database DNS + var $DSN; + + // our central interop server, where we can get the list of endpoints + var $registrationDB; + + // our local endpoint, will always get added to the database for all tests + var $localEndpoint; + + // specify testing + var $currentTest = ''; // see $tests above + var $paramType = 'php'; // 'php' or 'soapval' + var $useWSDL = false; // true: do wsdl tests + var $numServers = 0; // 0: all + var $specificEndpoint = ''; // test only this endpoint + var $testMethod = ''; // test only this method + var $skipEndpointList = array(); // endpoints to skip + var $nosave = false; + var $client_type = 'pear'; // name of client + + // debug output + var $show = 1; + var $debug = 0; + var $showFaults = 0; // used in result table output + + // PRIVATE VARIABLES + var $dbc = null; + var $totals = array(); + var $tests = array('Round 2 Base', + 'Round 2 Group B', + 'Round 2 Group C', + 'Round 3 Group D Compound 1', + 'Round 3 Group D Compound 2', + 'Round 3 Group D DocLit', + 'Round 3 Group D DocLitParams', + 'Round 3 Group D Import 1', + 'Round 3 Group D Import 2', + 'Round 3 Group D Import 3', + 'Round 3 Group D RpcEnc' + ); + var $paramTypes = array('php', 'soapval'); + var $endpoints = array(); + + function Interop_Client() { + global $interopConfig; + $this->DSN = $interopConfig['DSN']; + $this->registrationDB =& new SOAP_Interop_registrationDB(); + + // XXX for now, share the database for results also + $this->dbc =& $this->registrationDB->dbc; + } + + /** + * fetchEndpoints + * retreive endpoints interop server + * + * @return boolean result + * @access private + */ + function fetchEndpoints($name = 'Round 2 Base') { + $service =& $this->registrationDB->findService($name); + $this->endpoints =& $this->registrationDB->getServerList($service->id,true); + return true; + } + + /** + * getEndpoints + * retreive endpoints from either database or interop server + * + * @param string name (see local var $tests) + * @param boolean all (if false, only get valid endpoints, status=1) + * @return boolean result + * @access private + */ + function getEndpoints($name = 'Round 2 Base', $all = 0) { + $service =& $this->registrationDB->findService($name); + $this->endpoints =& $this->registrationDB->getServerList($service->id); + return true; + } + + /** + * Retreives results from the database and stuffs them into the endpoint + * array. + * + * @access private + */ + function getResults($test = 'Round 2 Base', $type = 'php', $wsdl = 0) + { + // Be sure we have the right endpoints for this test result. + $this->getEndpoints($test); + $c = count($this->endpoints); + + // Retreive the results and put them into the endpoint info. + $sql = "SELECT * FROM results WHERE class='$test' AND type='$type' AND wsdl=$wsdl"; + $results = $this->dbc->getAll($sql, null, DB_FETCHMODE_ASSOC); + for ($j = 0, $rc = count($results); $j < $rc; ++$j) { + $result = $results[$j]; + // Find the endpoint. + for ($i = 0; $i < $c; $i++) { + if ($this->endpoints[$i]->id == $result['endpoint']) { + // Store the info. + if (!isset($this->endpoints[$i]->methods)) { + $this->endpoints[$i]->methods = array(); + } + $this->endpoints[$i]->methods[$result['function']] = $result; + break; + } + } + } + } + + /** + * Saves the results of a method test into the database. + * + * @access private + */ + function _saveResults($endpoint_id, &$soap_test) + { + if ($this->nosave) { + return; + } + + $result =& $soap_test->result; + $wire = $result['wire']; + if ($result['success']) { + $success = 'OK'; + $error = ''; + } else { + $success = $result['fault']->faultcode; + $error = $result['fault']->faultstring; + if (!$wire) { + $wire = $result['fault']->faultdetail; + } + if (!$wire) { + $wire = $result['fault']->faultstring; + } + } + + $test_name = $soap_test->test_name; + // add header info to the test name + if ($soap_test->headers) { + foreach ($soap_test->headers as $h) { + $destination = 0; + if (strtolower(get_class($h)) == 'soap_header') { + if ($h->attributes['SOAP-ENV:actor'] == 'http://schemas.xmlsoap.org/soap/actor/next') { + $destination = 1; + } + $test_name .= ":{$h->name},$destination,{$h->attributes['SOAP-ENV:mustUnderstand']}"; + } else { + if (!$h[3] || + $h[3] == 'http://schemas.xmlsoap.org/soap/actor/next') { + $destination = 1; + } + if (!$h[2]) { + $h[2] = 0; + } + $qn = new QName($h[0]); + $test_name .= ":{$qn->name},$destination," . (int)$h[2]; + } + } + } + + $sql = 'DELETE FROM results WHERE endpoint = ? AND class = ? AND type = ? AND wsdl = ? AND client = ? AND function = ?'; + $values = array($endpoint_id, $this->currentTest, $this->paramType, + $this->useWSDL, $this->client_type, $test_name); + $res = $this->dbc->query($sql, $values); + if (DB::isError($res)) { + die($res->getMessage()); + } + if (is_object($res)) { + $res->free(); + } + + $sql = 'INSERT INTO results (client, endpoint, stamp, class, type, wsdl, function, result, error, wire) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + $values = array($this->client_type, $endpoint_id, time(), + $this->currentTest, $this->paramType, $this->useWSDL, + $test_name, $success, $error, + $wire ? $wire : ''); + //echo "\n".$sql; + $res = $this->dbc->query($sql, $values); + if (DB::isError($res)) { + die($res->getMessage()); + } + if (is_object($res)) { + $res->free(); + } + } + + /** + * Compares two PHP types for a match. + * + * @param mixed $expect + * @param mixed $test_result + * + * @return boolean + */ + function compareResult(&$expect, &$result, $type = null) + { + $expect_type = gettype($expect); + $result_type = gettype($result); + if ($expect_type == 'array' && $result_type == 'array') { + // compare arrays + return array_compare($expect, $result); + } + if ($type == 'float') { + // We'll only compare to 3 digits of precision. + return number_compare($expect, $result); + } + if ($type == 'boolean') { + return boolean_compare($expect, $result); + } + return string_compare($expect, $result); + } + + + /** + * Runs a method on an endpoint and stores its results to the database. + * + * @param array $endpoint_info + * @param SOAP_Test $soap_test + * + * @return boolean result + */ + function doEndpointMethod(&$endpoint_info, &$soap_test) + { + $ok = false; + + // Prepare a holder for the test results. + $soap_test->result['class'] = $this->currentTest; + $soap_test->result['type'] = $this->paramType; + $soap_test->result['wsdl'] = $this->useWSDL; + $opdata = null; + //global $soap_value_total; + //echo "SOAP VALUES TEST-START: $soap_value_total\n"; + + if ($this->useWSDL) { + if ($endpoint_info->wsdlURL) { + if (!$endpoint_info->client) { + if (0 /* dynamic client */) { + $endpoint_info->wsdl = new SOAP_WSDL($endpoint_info->wsdlURL); + $endpoint_info->wsdl->trace=1; + $endpoint_info->client = $endpoint_info->wsdl->getProxy('', $endpoint_info->name); + } else { + $endpoint_info->client = new SOAP_Client($endpoint_info->wsdlURL, 1); + } + $endpoint_info->client->_auto_translation = true; + } + if ($endpoint_info->client->_wsdl->_isfault()) { + $fault = $endpoint_info->client->_wsdl->fault->getFault(); + $detail = $fault->faultstring . "\n\n" . $fault->faultdetail; + $soap_test->setResult(0, + 'WSDL', + $detail, + $fault->faultstring, + $fault); + return false; + } + if ($soap_test->service) { + $endpoint_info->client->_wsdl->setService($soap_test->service); + } + $soap =& $endpoint_info->client; + //$port = $soap->_wsdl->getPortName($soap_test->method_name); + //$opdata = $soap->_wsdl->getOperationData($port, $soap_test->method_name); + } else { + $fault = array('faultcode' => 'WSDL', + 'faultstring' => "no WSDL defined for $endpoint"); + $soap_test->setResult(0, + 'WSDL', + $fault->faultstring, + $fault->faultstring, + $fault); + return false; + } + $options = array('trace' => 1); + } else { + $namespace = $soapaction = 'http://soapinterop.org/'; + // Hack to make tests work with MS SoapToolkit. + // It's the only one that uses this soapaction, and breaks if + // it isn't right. Can't wait for soapaction to be fully deprecated + // 8/25/2002, seems this is fixed now + //if ($this->currentTest == 'Round 2 Base' && + // strstr($endpoint_info->name,'MS SOAP ToolKit 2.0')) { + // $soapaction = 'urn:soapinterop'; + //} + if (!$endpoint_info->client) { + $endpoint_info->client = new SOAP_Client($endpoint_info->endpointURL); + $endpoint_info->client->_auto_translation = true; + } + $soap = &$endpoint_info->client; + $options = array('namespace' => $namespace, + 'soapaction' => $soapaction, + 'trace' => 1); + } + + // Add headers to the test. + if ($soap_test->headers) { + // $header is already a SOAP_Header class + $soap->headersOut = array(); + $soap->headersIn = array(); + for ($i = 0, $hc = count($soap_test->headers); $i < $hc; $i++) { + $soap->addHeader($soap_test->headers[$i]); + } + } + $soap->setEncoding($soap_test->encoding); + + //if ($opdata) { + // if (isset($opdata['style'])) + // $options['style'] = $opdata['style']; + // if (isset($opdata['soapAction'])) + // $options['soapaction'] = $opdata['soapAction']; + // if (isset($opdata['input']) && + // isset($opdata['input']['use'])) + // $options['use'] = $opdata['input']['use']; + // if (isset($opdata['input']) && + // isset($opdata['input']['namespace'])) + // $options['namespace'] = $soap->_wsdl->namespaces[$opdata['input']['namespace']]; + //} + //if ($this->useWSDL) { + // $wsdlcall = '$return = $soap->'.$soap_test->method_name.'('; + // $args = ''; + // if ($soap_test->method_params) { + // $pnames = array_keys($soap_test->method_params); + // foreach ($pnames as $argname) { + // if ($args) $args .=','; + // $args .= '$soap_test->method_params[\''.$argname.'\']'; + // } + // } + // $wsdlcall = $wsdlcall.$args.');'; + // eval($wsdlcall); + //} else { + $return =& $soap->call($soap_test->method_name, $soap_test->method_params, $options); + //} + + if (!PEAR::isError($return)) { + if (is_array($soap_test->method_params) && + count($soap_test->method_params) == 1) { + $sent = array_shift(array_values($soap_test->method_params)); + } else { + $sent = $soap_test->method_params; + } + + // Compare header results. + $header_result = array(); + $headers_ok = true; + if ($soap_test->headers) { + // $header is already a SOAP_Header class + for ($i = 0, $hc = count($soap_test->headers); $i < $hc; $i++) { + $header = $soap_test->headers[$i]; + if (strtolower(get_class($header)) != 'soap_header') { + // Assume it's an array. + $header = new SOAP_Header($header[0], null, $header[1], $header[2], $header[3], $header[4]); + } + $expect = $soap_test->headers_expect[$header->name]; + $header_result[$header->name] = array(); + // XXX need to fix need_result to identify the actor correctly + $need_result = $hresult || + ($header->attributes['SOAP-ENV:actor'] == 'http://schemas.xmlsoap.org/soap/actor/next' + && $header->attributes['SOAP-ENV:mustUnderstand']); + if ($expect) { + $hresult = $soap->headersIn[key($expect)]; + $ok = !$need_result || $this->compareResult($hresult ,$expect[key($expect)]); + } else { + $hresult = $soap->headersIn[$header->name]; + $expect =& $soap->_decode($header); + $ok = !$need_result || $this->compareResult($hresult ,$expect); + } + $header_result[$header->name]['ok'] = $ok; + if (!$ok) { + $headers_ok = false; + } + } + } + + // We need to decode what we sent so we can compare! + if (gettype($sent) == 'object' && + (strtolower(get_class($sent)) == 'soap_value' || + is_subclass_of($sent, 'soap_value'))) { + $sent_d =& $soap->_decode($sent); + } else { + $sent_d =& $sent; + } + + // compare the results with what we sent + $ok = $this->compareResult($sent_d, $return, $sent->type); + $expected = $sent_d; + unset($sent_d); + unset($sent); + if (!$ok && $soap_test->expect) { + $ok = $this->compareResult($soap_test->expect, $return); + $expected = $soap_test->expect; + } + + if ($ok) { + if (!$headers_ok) { + $fault = new stdClass(); + $fault->faultcode = 'HEADER'; + $fault->faultstring = 'The returned result did not match what we expected to receive'; + $soap_test->setResult(0, + $fault->faultcode, + $soap->getWire(), + $fault->faultstring, + $fault); + } else { + $soap_test->setResult(1, 'OK', $soap->getWire()); + $success = true; + } + } else { + $fault = new stdClass(); + $fault->faultcode = 'RESULT'; + $fault->faultstring = 'The returned result did not match what we expected to receive'; + $fault->faultdetail = "RETURNED:\n" . var_export($return, true) . "\n\nEXPECTED:\n" . var_export($expected, true); + $soap_test->setResult(0, + $fault->faultcode, + $soap->getWire(), + $fault->faultstring, + $fault); + } + } else { + $fault = $return->getFault(); + if ($soap_test->expect_fault) { + $ok = 1; + $res = 'OK'; + } else { + $ok = 0; + $res = $fault->faultcode; + } + $soap_test->setResult($ok, + $res, + $soap->getWire(), + $fault->faultstring, + $fault); + } + $soap->_reset(); + unset($return); + + return $ok; + } + + /** + * Runs a single round of tests. + */ + function doTest() + { + global $soap_tests; + + $empty_string = ''; + // Get endpoints for this test. + if (!$this->currentTest) { + die("Asked to run a test, but no testname!\n"); + } + $this->getEndpoints($this->currentTest); + // Clear totals. + $this->totals = array(); + + for ($i = 0, $c = count($this->endpoints); $i < $c; ++$i) { + $endpoint_info = $this->endpoints[$i]; + // If we specify an endpoint, skip until we find it. + if (($this->specificEndpoint && + $endpoint_info->name != $this->specificEndpoint) || + ($this->useWSDL && !$endpoint_info->wsdlURL)) { + continue; + } + + $skipendpoint = false; + $this->totals['servers']++; + //$endpoint_info['tests'] = array(); + + if ($this->show) { + echo "Processing {$endpoint_info->name} at {$endpoint_info->endpointURL}\n"; + } + + for ($ti = 0, $tc = count($soap_tests[$this->currentTest]); $ti < $tc; ++$ti) { + $soap_test = $soap_tests[$this->currentTest][$ti]; + + // Only run the type of test we're looking for (php or + // soapval). + if ($soap_test->type != $this->paramType) { + continue; + } + + // If this is in our skip list, skip it. + if (in_array($endpoint_info->name, $this->skipEndpointList)) { + $skipendpoint = true; + $skipfault = new stdClass(); + $skipfault->faultcode = 'SKIP'; + $skipfault->faultstring = 'endpoint skipped'; + $soap_test->setResult(0, + $skipfault->faultcode, + $empty_string, + $skipfault->faultstring, + $skipfault); + //$endpoint_info['tests'][] = &$soap_test; + //$soap_test->showTestResult($this->debug); + //$this->_saveResults($endpoint_info['id'], $soap_test->method_name); + $soap_test->result = null; + continue; + } + + // If we're looking for a specific method, skip unless we have + // it. + if ($this->testMethod && + strcmp($this->testMethod, $soap_test->test_name) != 0) { + continue; + } + if ($this->testMethod && + $this->currentTest == 'Round 2 Group C') { + // We have to figure things out now. + if (!preg_match('/(.*):(.*),(\d),(\d)/', $this->testMethod, $m)) { + continue; + } + + // Is the header in the headers list? + $gotit = false; + $thc = count($soap_test->headers); + for ($thi = 0; $thi < $thc; $thi++) { + $header = $soap_test->headers[$thi]; + if (strtolower(get_class($header)) == 'soap_header') { + if ($header->name == $m[2]) { + $gotit = $header->attributes['SOAP-ENV:actor'] == ($m[3] ? SOAP_TEST_ACTOR_NEXT : SOAP_TEST_ACTOR_OTHER); + $gotit = $gotit && $header->attributes['SOAP-ENV:mustUnderstand'] == $m[4]; + } + } elseif ($header[0] == $m[2]) { + $gotit = $gotit && $header[3] == ($m[3] ? SOAP_TEST_ACTOR_NEXT : SOAP_TEST_ACTOR_OTHER); + $gotit = $gotit && $header[4] == $m[4]; + } + } + if (!$gotit) { + continue; + } + } + + // If we are skipping the rest of the tests (due to error) + // note a fault. + if ($skipendpoint) { + $soap_test->setResult(0, + $skipfault->faultcode, + $empty_string, + $skipfault->faultstring, + $skipfault); + //$endpoint_info['tests'][] = &$soap_test; + $this->totals['fail']++; + } else { + // Run the endpoint test. + unset($soap_test->result); + if ($this->doEndpointMethod($endpoint_info, $soap_test)) { + $this->totals['success']++; + } else { + $skipendpoint = $soap_test->result['fault']->faultcode == 'HTTP'; + $skipfault = $skipendpoint ? $soap_test->result['fault'] : null; + $this->totals['fail']++; + } + //$endpoint_info['tests'][] = &$soap_test; + } + $soap_test->showTestResult($this->debug); + $this->_saveResults($endpoint_info->id, $soap_test); + $soap_test->reset(); + $this->totals['calls']++; + } + unset($endpoint_info->client); + if ($this->numservers && ++$i >= $this->numservers) { + break; + } + } + } + + function doGroupTests() { + $dowsdl = array(0,1); + foreach($dowsdl as $usewsdl) { + $this->useWSDL = $usewsdl; + foreach($this->paramTypes as $ptype) { + // skip a pointless test + if ($usewsdl && $ptype == 'soapval') break; + if (stristr($this->currentTest, 'Round 3') && !$usewsdl) break; + $this->paramType = $ptype; + $this->doTest(); + } + } + } + + /** + * Go all out. This takes time. + */ + function doTests() + { + // The mother of all interop tests. + $dowsdl = array(0, 1); + foreach ($this->tests as $test) { + $this->currentTest = $test; + foreach ($dowsdl as $usewsdl) { + $this->useWSDL = $usewsdl; + foreach ($this->paramTypes as $ptype) { + // Skip a pointless test. + if ($usewsdl && $ptype == 'soapval') { + break; + } + if (stristr($this->currentTest, 'Round 3') && !$usewsdl) { + break; + } + $this->paramType = $ptype; + $this->doTest(); + } + } + } + } + + /** + * @access private + */ + function getMethodList($test = 'base') + { + $this->dbc->setFetchMode(DB_FETCHMODE_ORDERED); + // Retreive the results and put them into the endpoint info. + $sql = "SELECT DISTINCT(function) FROM results WHERE client='$this->client_type' AND class='$test' ORDER BY function"; + $results = $this->dbc->getAll($sql); + $ar = array(); + foreach($results as $result) { + $ar[] = $result[0]; + } + return $ar; + } + + function outputTable() + { + $methods = $this->getMethodList($this->currentTest); + if (!$methods) { + return; + } + $this->getResults($this->currentTest,$this->paramType,$this->useWSDL); + + echo "Testing $this->currentTest "; + if ($this->useWSDL) { + echo "using WSDL "; + } else { + echo "using Direct calls "; + } + echo "with $this->paramType values
    \n"; + + // Calculate totals for this table. + $this->totals['success'] = 0; + $this->totals['fail'] = 0; + $this->totals['result'] = 0; + $this->totals['wsdl'] = 0; + $this->totals['connect'] = 0; + $this->totals['servers'] = 0; //count($this->endpoints); + for ($i = 0, $c = count($this->endpoints); $i < $c; ++$i) { + $endpoint_info = $this->endpoints[$i]; + if (!$endpoint_info->name) { + continue; + } + if (count($endpoint_info->methods) > 0) { + $this->totals['servers']++; + foreach ($methods as $method) { + $r = $endpoint_info->methods[$method]['result']; + if ($r == 'OK') { + $this->totals['success']++; + } elseif (stristr($r, 'result')) { + $this->totals['result']++; + } elseif (stristr($r, 'wsdlcache')) { + $this->totals['connect']++; + } elseif (stristr($r, 'wsdl')) { + $this->totals['wsdl']++; + } elseif (stristr($r, 'http')) { + $this->totals['connect']++; + } else { + $this->totals['fail']++; + } + } + } else { + //unset($this->endpoints[$i]); + } + } + $this->totals['calls'] = count($methods) * $this->totals['servers']; + + //if ($this->totals['fail'] == $this->totals['calls']) { + // // assume tests have not run, skip outputing table + // echo "No Data Available
    \n"; + // return; + //} + + echo "\n\nServers: {$this->totals['servers']} Calls: {$this->totals['calls']} Success: {$this->totals['success']}
    \n" + . "System-Fail: {$this->totals['fail']} Result-Failure: {$this->totals['result']} Connect-Failure: {$this->totals['connect']} WSDL-Failure: {$this->totals['wsdl']}

    \n" + + . "\n" + . "\n"; + foreach ($methods as $method) { + $info = split(':', $method); + echo "\n"; + } + echo "\n"; + $faults = array(); + $fi = 0; + for ($i = 0, $c = count($this->endpoints); $i < $c; ++$i) { + $endpoint_info = $this->endpoints[$i]; + if (!$endpoint_info->name) { + continue; + } + if ($endpoint_info->wsdlURL) { + echo "\n"; + } else { + echo "\n"; + } + foreach ($methods as $method) { + $id = $endpoint_info->methods[$method]['id']; + $r = $endpoint_info->methods[$method]['result']; + $e = $endpoint_info->methods[$method]['error']; + if ($e) { + $faults[$fi++] = $e; + } + if ($r) { + echo "\n"; + } else { + echo "\n"; + } + } + echo "\n"; + } + echo "
    Endpoint"; + foreach ($info as $m) { + $hi = split(',', $m); + echo ''. $hi[0] . "
    \n"; + if (count($hi) > 1) { + echo "  Actor=" + . ($hi[1] ? 'Target' : 'Not Target') + . "
    \n  MustUnderstand=$hi[2]
    \n"; + } + } + echo "
    wsdlURL}\">{$endpoint_info->name}
    {$endpoint_info->name}$runtested

    \n"; + if ($this->showFaults && count($faults) > 0) { + echo "ERROR Details:
    \n
      \n"; + // output more error detail + foreach ($faults as $fault) { + echo '
    • ' . htmlspecialchars($fault) . "
    • \n"; + } + } + echo "


    \n"; + } + + function outputTables() + { + $dowsdl = array(0, 1); + foreach($this->tests as $test) { + $this->currentTest = $test; + foreach ($dowsdl as $usewsdl) { + $this->useWSDL = $usewsdl; + foreach ($this->paramTypes as $ptype) { + // Skip a pointless test. + if ($usewsdl && $ptype == 'soapval') { + break; + } + if (stristr($this->currentTest, 'Round 3') && !$usewsdl) { + break; + } + $this->paramType = $ptype; + $this->outputTable(); + } + } + } + } + + function showWire($id) + { + $results = $this->dbc->getAll("SELECT * FROM results WHERE id=$id", null, DB_FETCHMODE_ASSOC ); + //$wire = preg_replace("/>/",">\n",$results[0]['wire']); + $wire = $results[0]['wire']; + echo "
    \n" . htmlspecialchars($wire) . "
    \n"; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_client_results.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_client_results.php new file mode 100644 index 000000000..43e8ebc74 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_client_results.php @@ -0,0 +1,75 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_client_results.php,v 1.3 2003/04/07 00:51:17 shane Exp $ +// +require_once 'interop_client.php'; +?> + + + + + + PEAR-PHP SOAP Interop Tests + + + +

    SOAP Client Interop Test Results: Round2

    + +Back to Interop Index
    +

     

    + +showFaults = 1; + +if ($_GET['wire']) { + $iop->showWire($_GET['wire']); +} else { + $iop->getEndpoints(); + $iop->getResults(); + + if ($_GET['test']) { + $iop->currentTest = $_GET['test']; + $iop->useWSDL = $_GET['wsdl']?$_GET['wsdl']:0; + $iop->paramType = $_GET['type']?$_GET['type']:'php'; + $iop->outputTable(); + } else { + $iop->outputTables(); + } +} +?> + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_client_run.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_client_run.php new file mode 100644 index 000000000..c77eb78f1 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_client_run.php @@ -0,0 +1,177 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_client_run.php,v 1.11 2007/01/26 15:03:24 yunosh Exp $ +// + +if (isset($_SERVER['SERVER_NAME'])) { + die("full test run cannot be done via webserver."); +} + +set_time_limit(0); +error_reporting(E_ALL); + +require 'Console/Getopt.php'; +require_once 'interop_client.php'; + +$INTEROP_LOCAL_SERVER = TRUE;// add local server to endpoints + +$iop =& new Interop_Client(); + +// debug output +$iop->show = 1; +$iop->debug = 0; +$iop->showFaults = 0; // used in result table output +$restrict = null; + +$args = Console_Getopt::getopt($_SERVER['argv'], + 'c:dehl:m:np:r:s:t:v:wq', + array('help')); +if (PEAR::isError($args)) { + echo "\n" . $args->getMessage() . "\n\n"; + help(); + exit; +} + +function help() { +print <<tests as $test) { + print " $test\n"; + } +} + +function print_endpoint_names() +{ + global $iop; + if (!$iop->getEndpoints($iop->currentTest)) { + die("Unable to retrieve endpoints for $iop->currentTest\n"); + } + print "Interop Servers for $iop->currentTest:\n"; + foreach ($iop->endpoints as $server) { + print " $server->name\n"; + } +} + +foreach ($args[0] as $arg) { + switch($arg[0]) { + case 'c': + $iop->client_type = $arg[1]; + break; + case 'd': + $iop->debug = true; + break; + case 'e': + $iop->fetchEndpoints(); + break; + case 'h': + case '--help': + help(); + exit(0); + case 'l': + $iop->skipEndpointList = split(',', $arg[1]); + break; + case 'm': + $iop->testMethod = $arg[1]; + break; + case 'n': + $iop->nosave = true; + break; + case 'p': + if ($arg[1] == 't') { + print_test_names(); + } elseif ($arg[1] == 'e') { + if (!$iop->currentTest) { + print "You need to specify a test with -t\n"; + exit(0); + } + print_endpoint_names(); + } else { + die("invalid print argument\n"); + } + exit(0); + case 'r': + $restrict = $arg[1]; + break; + case 's': + $iop->specificEndpoint = $arg[1]; + break; + case 't': + $iop->currentTest = $arg[1]; + break; + case 'v': + if ($arg[1] != 'php' && $arg[1] != 'soapval') { + die('Incorrect value for argument v: ' . $arg[1] . "\n"); + } + $iop->paramType = $arg[1]; + break; + case 'w': + $iop->useWSDL = true; + break; + case 'q': + exit(0); + } +} + +// These are endpoints that are listed in the interop server, but do not realy +// exist any longer. +$bad = array('Spheon JSOAP', 'Phalanx', 'SilverStream', 'SOAPx4 (PHP)', + 'Virtuoso (development)', 'Zolera SOAP Infrastructure'); +$iop->skipEndpointList = array_merge($iop->skipEndpointList, $bad); + +if ($restrict) { + $tests = $iop->tests; + $iop->tests = array(); + foreach ($tests as $test) { + if (stristr($test, $restrict)) { + $iop->tests[] = $test; + } + } +} + +if ($iop->currentTest) { + $iop->doTest(); // run a single set of tests using above options +} else { + // $iop->doGroupTests(); // run a group of tests set in $currentTest + $iop->doTests(); // run all tests, ignore above options +} + +echo "done\n"; diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_database.sql b/gulliver/thirdparty/pear/SOAP/Interop/interop_database.sql new file mode 100644 index 000000000..1c8f0cf09 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_database.sql @@ -0,0 +1,76 @@ +# Database soapinterop running on localhost + +# phpMyAdmin MySQL-Dump +# version 2.2.5 +# http://phpwizard.net/phpMyAdmin/ +# http://phpmyadmin.sourceforge.net/ (download page) +# +# Host: localhost +# Generation Time: Aug 31, 2002 at 06:36 PM +# Server version: 3.23.49 +# PHP Version: 4.2.1 +# Database : `soapinterop` +# -------------------------------------------------------- + +# +# Table structure for table `clientinfo` +# + +CREATE TABLE clientinfo ( + id char(40) NOT NULL default '', + name char(100) NOT NULL default '', + version char(20) NOT NULL default '', + resultsURL char(255) NOT NULL default '' +) TYPE=MyISAM; +# -------------------------------------------------------- + +# +# Table structure for table `results` +# + +CREATE TABLE results ( + id int(11) NOT NULL auto_increment, + client varchar(100) NOT NULL default '0', + endpoint int(11) NOT NULL default '0', + stamp int(11) NOT NULL default '0', + class varchar(50) NOT NULL default '', + type varchar(10) default NULL, + wsdl int(11) NOT NULL default '0', + function varchar(255) NOT NULL default '', + result varchar(25) NOT NULL default '', + error text, + wire text NOT NULL, + PRIMARY KEY (id) +) TYPE=MyISAM; +# -------------------------------------------------------- + +# +# Table structure for table `serverinfo` +# + +CREATE TABLE serverinfo ( + id int(11) NOT NULL auto_increment, + service_id char(40) NOT NULL default '', + name char(100) NOT NULL default '', + version char(20) NOT NULL default '', + endpointURL char(255) NOT NULL default '', + wsdlURL char(255) NOT NULL default '', + PRIMARY KEY (id) +) TYPE=MyISAM; +# -------------------------------------------------------- + +# +# Table structure for table `services` +# + +CREATE TABLE services ( + id char(40) NOT NULL default '', + name char(50) NOT NULL default '', + description char(255) NOT NULL default '', + wsdlURL char(255) NOT NULL default '', + websiteURL char(255) NOT NULL default '', + PRIMARY KEY (id) +) TYPE=MyISAM; + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_test.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_test.php new file mode 100644 index 000000000..4b3107989 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_test.php @@ -0,0 +1,137 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: interop_test.php,v 1.10 2007/01/26 17:21:44 yunosh Exp $ +// +require_once 'SOAP/Value.php'; + +define('SOAP_TEST_ACTOR_NEXT','http://schemas.xmlsoap.org/soap/actor/next'); +define('SOAP_TEST_ACTOR_OTHER','http://some/other/actor'); + +class SOAP_Interop_Test { + + var $type = 'php'; + var $test_name = null; + var $method_name = null; + var $method_params = null; + var $expect = null; + var $expect_fault = false; + var $headers = null; + var $headers_expect = null; + var $result = array(); + var $show = 1; + var $debug = 0; + var $encoding = SOAP_DEFAULT_ENCODING; + + /** + * If multiple services, this sets to a specific service. + */ + var $service = null; + + function SOAP_Interop_Test($methodname, $params, $expect = null) + { + if (strchr($methodname, '(')) { + preg_match('/(.*)\((.*)\)/', $methodname, $matches); + $this->test_name = $methodname; + $this->method_name = $matches[1]; + } else { + $this->test_name = $this->method_name = $methodname; + } + $this->method_params = $params; + $this->expect = $expect; + + // determine test type + if ($params) { + $v = array_values($params); + if (gettype($v[0]) == 'object' && + strtolower(get_class($v[0])) == 'soap_value') { + $this->type = 'soapval'; + } + } + } + + function setResult($ok, $result, $wire, $error = '', $fault = null) + { + $this->result['success'] = $ok; + $this->result['result'] = $result; + $this->result['error'] = $error; + $this->result['wire'] = $wire; + $this->result['fault'] = $fault; + } + + function reset() + { + $this->result = array(); + } + + /** + * Prints simple output about a methods result. + */ + function showTestResult($debug = 0) + { + // Debug output + if ($debug) { + $this->show = 1; + echo str_repeat('-', 50) . "\n"; + } + + echo "Testing $this->test_name: "; + if ($this->headers) { + $hc = count($this->headers); + for ($i = 0; $i < $hc; $i++) { + $h = $this->headers[$i]; + if (strtolower(get_class($h)) == 'soap_header') { + echo "\n {$h->name},{$h->attributes['SOAP-ENV:actor']},{$h->attributes['SOAP-ENV:mustUnderstand']} : "; + } else { + if (!$h[4]) { + $h[4] = SOAP_TEST_ACTOR_NEXT; + } + if (!$h[3]) { + $h[3] = 0; + } + echo "\n $h[0],$h[4],$h[3] : "; + } + } + } + + if ($debug) { + echo "method params: "; + print_r($this->params); + echo "\n"; + } + + $ok = $this->result['success']; + if ($ok) { + echo "SUCCESS\n"; + } else { + $fault = $this->result['fault']; + if ($fault) { + echo "FAILED: [{$fault->faultcode}] {$fault->faultstring}\n"; + if (!empty($fault->faultdetail)) { + echo $fault->faultdetail . "\n"; + } + } else { + echo "FAILED: " . $this->result['result'] . "\n"; + } + } + if ($debug) { + echo "\n" . $this->result['wire'] . "\n"; + } + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/interop_test_functions.php b/gulliver/thirdparty/pear/SOAP/Interop/interop_test_functions.php new file mode 100644 index 000000000..e6277eaab --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/interop_test_functions.php @@ -0,0 +1,90 @@ + 3) $d = 3; + $f1 = round($f1, $d); + $f2 = round($f2, $d); + return bccomp($f1, $f2, $d) == 0; +} + +function boolean_compare($f1, $f2) +{ + if (($f1 == 'true' || $f1 === TRUE || $f1 != 0) && + ($f2 == 'true' || $f2 === TRUE || $f2 != 0)) return TRUE; + if (($f1 == 'false' || $f1 === FALSE || $f1 == 0) && + ($f2 == 'false' || $f2 === FALSE || $f2 == 0)) return TRUE; + return FALSE; +} + +function string_compare($e1, $e2) +{ + if (is_numeric($e1) && is_numeric($e2)) { + return number_compare($e1, $e2); + } + # handle dateTime comparison + $e1_type = gettype($e1); + $e2_type = gettype($e2); + $ok = FALSE; + if ($e1_type == "string") { + require_once 'SOAP/Type/dateTime.php'; + $dt =& new SOAP_Type_dateTime(); + $ok = $dt->compare($e1, $e2) == 0; + } + return $ok || $e1 == $e2 || strcasecmp(trim($e1), trim($e2)) == 0; +} + +function array_compare(&$ar1, &$ar2) +{ + if (gettype($ar1) != 'array' || gettype($ar2) != 'array') return FALSE; + # first a shallow diff + if (count($ar1) != count($ar2)) return FALSE; + $diff = array_diff($ar1, $ar2); + if (count($diff) == 0) return TRUE; + + # diff failed, do a full check of the array + foreach ($ar1 as $k => $v) { + #print "comparing $v == $ar2[$k]\n"; + if (gettype($v) == "array") { + if (!array_compare($v, $ar2[$k])) return FALSE; + } else { + if (!string_compare($v, $ar2[$k])) return FALSE; + if ($type == 'float') + # we'll only compare to 3 digits of precision + $ok = number_compare($expect, $result,3); + if ($type == 'boolean') + $ok = boolean_compare($expect, $result); + else + $ok = string_compare($expect, $result); + } + } + return TRUE; +} + + +function &parseMessage($msg) +{ + # strip line endings + #$msg = preg_replace('/\r|\n/', ' ', $msg); + $response =& new SOAP_Parser($msg); + if ($response->fault) { + return $response->fault->getFault(); + } + $return =& $response->getResponse(); + $v =& $response->decode($return); + if (gettype($v) == 'array' && count($v)==1) { + return array_shift($v); + } + return $v; +} + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_Round2Base.php b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2Base.php new file mode 100644 index 000000000..cfc821b15 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2Base.php @@ -0,0 +1,230 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_Round2Base.php,v 1.6 2007/01/26 14:54:51 yunosh Exp $ +// + +require_once 'params_values.php'; +require_once 'interop_test.php'; +define('INTEROP_R2BASE', 'Round 2 Base'); + +//*********************************************************** +// Base echoString + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString', + array('inputString' => $string), + $soap_test_null); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString', + array('inputString' => $string_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString(null)', + array('inputString' => $string_null)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString(null)', + array('inputString' => $string_null_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString(entities)', + array('inputString' => $string_entities)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoString(entities)', + array('inputString' => $string_entities_soapval)); +$test = new SOAP_Interop_Test( + 'echoString(utf-8)', + array('inputString' => $string_utf8)); +$test->encoding = 'UTF-8'; +$soap_tests[INTEROP_R2BASE][] = $test; +unset($test); + +$test = new SOAP_Interop_Test( + 'echoString(utf-8)', + array('inputString' => $string_utf8_soapval)); +$test->encoding = 'UTF-8'; +$soap_tests[INTEROP_R2BASE][] = $test; +unset($test); + +//*********************************************************** +// Base echoStringArray + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray', + array('inputStringArray' => $string_array)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray', + array('inputStringArray' => $string_array_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray(one)', + array('inputStringArray' => $string_array_one)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray(one)', + array('inputStringArray' => $string_array_one_soapval)); +// null array test +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray(null)', + array('inputStringArray' => $string_array_null)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStringArray(null)', + array('inputStringArray' => $string_array_null_soapval)); + +//*********************************************************** +// Base echoInteger + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoInteger', + array('inputInteger' => $integer)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoInteger', + array('inputInteger' => $integer_soapval)); + +//*********************************************************** +// Base echoIntegerArray + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoIntegerArray', + array('inputIntegerArray' => $integer_array)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoIntegerArray', + array('inputIntegerArray' => $integer_array_soapval)); + +// null array test +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoIntegerArray(null)', + array('inputIntegerArray' => $integer_array_null)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoIntegerArray(null)', + array('inputIntegerArray' => $integer_array_null_soapval)); + +//*********************************************************** +// Base echoFloat + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoFloat', + array('inputFloat' => $float)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoFloat', + array('inputFloat' => $float_soapval)); + +//*********************************************************** +// Base echoFloatArray + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoFloatArray', + array('inputFloatArray' => $float_array)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoFloatArray', + array('inputFloatArray' => $float_array_soapval)); + +//*********************************************************** +// Base echoStruct + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStruct', + array('inputStruct' => $soapstruct)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStruct', + array('inputStruct' => $soapstruct_soapval)); + +//*********************************************************** +// Base echoStructArray + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStructArray', + array('inputStructArray' => $soapstruct_array)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoStructArray', + array('inputStructArray' => $soapstruct_array_soapval)); + +//*********************************************************** +// Base echoVoid + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test('echoVoid', null); +$test = new SOAP_Interop_Test('echoVoid', null); +$test->type = 'soapval'; +$soap_tests[INTEROP_R2BASE][] = $test; +unset($test); + +//*********************************************************** +// Base echoBase64 + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBase64', + array('inputBase64' => $base64), + 'Nebraska'); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBase64', + array('inputBase64' => $base64_soapval), + 'Nebraska'); + +//*********************************************************** +// Base echoHexBinary + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoHexBinary', + array('inputHexBinary' => $hexBin)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoHexBinary', + array('inputHexBinary' => $hexBin_soapval)); + +//*********************************************************** +// Base echoDecimal + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoDecimal', + array('inputDecimal' => $decimal)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoDecimal', + array('inputDecimal' => $decimal_soapval)); + +//*********************************************************** +// Base echoDate + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoDate', + array('inputDate' => $dateTime)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoDate', + array('inputDate' => $dateTime_soapval)); + +//*********************************************************** +// Base echoBoolean + +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(TRUE)', + array('inputBoolean' => $boolean_true)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(TRUE)', + array('inputBoolean' => $boolean_true_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(FALSE)', + array('inputBoolean' => $boolean_false)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(FALSE)', + array('inputBoolean' => $boolean_false_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(1)', + array('inputBoolean' => $boolean_one)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(1)', + array('inputBoolean' => $boolean_one_soapval)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(0)', + array('inputBoolean' => $boolean_zero)); +$soap_tests[INTEROP_R2BASE][] = new SOAP_Interop_Test( + 'echoBoolean(0)', + array('inputBoolean' => $boolean_zero_soapval)); diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupB.php b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupB.php new file mode 100644 index 000000000..ba48201d2 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupB.php @@ -0,0 +1,72 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_Round2GroupB.php,v 1.4 2003/04/07 00:51:17 shane Exp $ +// +require_once 'params_values.php'; +require_once 'interop_test.php'; +define('INTEROP_R2GROUPB','Round 2 Group B'); +//*********************************************************** +// GroupB echoStructAsSimpleTypes + +$expect = array( + 'outputString'=>'arg', + 'outputInteger'=>34, + 'outputFloat'=>325.325 + ); +$soap_tests[INTEROP_R2GROUPB][] = + new SOAP_Interop_Test('echoStructAsSimpleTypes', + array('inputStruct' => &$soapstruct), $expect); +$soap_tests[INTEROP_R2GROUPB][] = + new SOAP_Interop_Test('echoStructAsSimpleTypes', + array('inputStruct' => &$soapstruct_soapval), $expect); + +//*********************************************************** +// GroupB echoSimpleTypesAsStruct + +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoSimpleTypesAsStruct', + $simpletypes, $soapstruct); +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoSimpleTypesAsStruct', + $simpletypes_soapval, $soapstruct); + +//*********************************************************** +// GroupB echo2DStringArray + +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echo2DStringArray', + array('input2DStringArray' => &$multidimarray)); +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echo2DStringArray', + array('input2DStringArray' => &$multidimarray_soapval)); + +//*********************************************************** +// GroupB echoNestedStruct + +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoNestedStruct', + array('inputStruct' => &$soapstructstruct)); +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoNestedStruct', + array('inputStruct' => &$soapstructstruct_soapval)); + +//*********************************************************** +// GroupB echoNestedArray + +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoNestedArray', + array('inputStruct' => &$soaparraystruct)); +$soap_tests[INTEROP_R2GROUPB][] =& new SOAP_Interop_Test('echoNestedArray', + array('inputStruct' => &$soaparraystruct_soapval)); + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupC.php b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupC.php new file mode 100644 index 000000000..9681d8851 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_Round2GroupC.php @@ -0,0 +1,235 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_Round2GroupC.php,v 1.4 2003/04/07 00:51:17 shane Exp $ +// +require_once 'params_values.php'; +require_once 'interop_test.php'; +define('INTEROP_R2GROUPC','Round 2 Group C'); +//*********************************************************** +// echoMeStringRequest php val tests + +// echoMeStringRequest with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', &$string, 0,SOAP_TEST_ACTOR_NEXT); +$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>&$string); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', &$string, 1,SOAP_TEST_ACTOR_NEXT); +$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>&$string); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', &$string, 0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStringRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', &$string, 1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStringRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +//*********************************************************** +// echoMeStringRequest soapval tests + +// echoMeStringRequest with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', $string); +$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>&$string); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', $string, 1); +$test->type = 'soapval'; // force a soapval version of this test +$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>&$string); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', $string, 0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStringRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', $string, 1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStringRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStringRequest with endpoint header destination, must understand, +// invalid namespace, should recieve a fault +#$test =& new SOAP_Interop_Test('echoVoid', NULL); +#$test->type = 'soapval'; +#$test->headers[] =& new SOAP_Header('{http://unknown.org/echoheader/}echoMeStringRequest', 'string', 'hello world', 1); +#$test->headers_expect['echoMeStringRequest'] = array(); +#$test->expect_fault = TRUE; +#$soap_tests[INTEROP_R2GROUPC][] = $test; + +//*********************************************************** +// php val tests +// echoMeStructRequest with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE); +$test->headers_expect['echoMeStructRequest'] = + array('echoMeStructResponse'=> &$soapstruct); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,1); +$test->headers_expect['echoMeStructRequest'] = + array('echoMeStructResponse'=> &$soapstruct); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStructRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStructRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +//*********************************************************** +// soapval tests +// echoMeStructRequest with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE); +$test->headers_expect['echoMeStructRequest'] = + array('echoMeStructResponse'=> &$soapstruct); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,1); +$test->headers_expect['echoMeStructRequest'] = + array('echoMeStructResponse'=> &$soapstruct); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStructRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeStructRequest with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest',TRUE,1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeStructRequest'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +//*********************************************************** +// echoMeUnknown php val tests +// echoMeUnknown with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', $string,0,SOAP_TEST_ACTOR_NEXT); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', $string,1,SOAP_TEST_ACTOR_NEXT); +$test->headers_expect['echoMeUnknown'] = array(); +$test->expect_fault = TRUE; +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', $string,0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', $string, 1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +//*********************************************************** +// echoMeUnknown soapval tests +// echoMeUnknown with endpoint as header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string',$string); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint as header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string',$string,1); +$test->headers_expect['echoMeUnknown'] = array(); +$test->expect_fault = TRUE; +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint NOT header destination, doesn't have to understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string',$string, 0, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + +// echoMeUnknown with endpoint NOT header destination, must understand +$test =& new SOAP_Interop_Test('echoVoid', NULL); +$test->type = 'soapval'; +$test->headers[] =& new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string',$string, 1, SOAP_TEST_ACTOR_OTHER); +$test->headers_expect['echoMeUnknown'] = array(); +$soap_tests[INTEROP_R2GROUPC][] =& $test; +unset($test); + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_Round3GroupD.php b/gulliver/thirdparty/pear/SOAP/Interop/params_Round3GroupD.php new file mode 100644 index 000000000..70fde94e1 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_Round3GroupD.php @@ -0,0 +1,121 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_Round3GroupD.php,v 1.7 2003/04/14 01:40:21 shane Exp $ +// +require_once 'params_values.php'; +require_once 'interop_test.php'; +define('INTEROP_R3D_COMPOUND1','Round 3 Group D Compound 1'); +define('INTEROP_R3D_COMPOUND2','Round 3 Group D Compound 2'); +define('INTEROP_R3D_DOCLIT','Round 3 Group D DocLit'); +define('INTEROP_R3D_DOCLIT_PARAM','Round 3 Group D DocLitParams'); +define('INTEROP_R3D_IMPORT1','Round 3 Group D Import 1'); +define('INTEROP_R3D_IMPORT2','Round 3 Group D Import 2'); +define('INTEROP_R3D_IMPORT3','Round 3 Group D Import 3'); +define('INTEROP_R3D_RPCENC','Round 3 Group D RpcEnc'); +//*********************************************************** +// GroupD + +# COMPOUND 1 tests +# http://www.whitemesa.net/wsdl/r3/compound1.wsdl +$test =& new SOAP_Interop_Test('echoPerson', array('x_Person'=>&$person)); +$test->type = 'php'; // force to php testing +$soap_tests[INTEROP_R3D_COMPOUND1][] = &$test; +unset($test); + +$test =& new SOAP_Interop_Test('echoDocument', array('x_Document'=>'Test Document Here')); +$test->type = 'php'; // force to php testing +$soap_tests[INTEROP_R3D_COMPOUND1][] = &$test; +unset($test); + +# COMPOUND 2 tests +# http://www.whitemesa.net/wsdl/r3/compound2.wsdl +$test =& new SOAP_Interop_Test('echoEmployee', array('x_Employee'=>&$employee)); +$test->type = 'php'; // force to php testing +$soap_tests[INTEROP_R3D_COMPOUND2][] = &$test; +unset($test); + +# DOC LIT Tests +# http://www.whitemesa.net/wsdl/r3/interoptestdoclit.wsdl +$soap_tests[INTEROP_R3D_DOCLIT][] =& + new SOAP_Interop_Test('echoString', + array('echoStringParam' => &$string)); +$soap_tests[INTEROP_R3D_DOCLIT][] =& + new SOAP_Interop_Test('echoStringArray', + array('echoStringArrayParam' => &$string_array)); +$soap_tests[INTEROP_R3D_DOCLIT][] =& + new SOAP_Interop_Test('echoStruct', + array('echoStructParam' => &$soapstruct)); +#$soap_tests[INTEROP_R3D_DOCLIT][] = +# new SOAP_Interop_Test('echoVoid', NULL); + +# DOC LIT w/Params Tests +# http://www.whitemesa.net/wsdl/r3/interoptestdoclitparameters.wsdl +$soap_tests[INTEROP_R3D_DOCLIT_PARAM][] =& + new SOAP_Interop_Test('echoString', + array('param0' => $string)); +$soap_tests[INTEROP_R3D_DOCLIT_PARAM][] =& + new SOAP_Interop_Test('echoStringArray', + array('param0' => &$string_array)); +$soap_tests[INTEROP_R3D_DOCLIT_PARAM][] =& + new SOAP_Interop_Test('echoStruct', + array('param0' => &$soapstruct)); +$soap_tests[INTEROP_R3D_DOCLIT_PARAM][] =& + new SOAP_Interop_Test('echoVoid', NULL); + +# IMPORT 1 tests +# http://www.whitemesa.net/wsdl/r3/import1.wsdl +$soap_tests[INTEROP_R3D_IMPORT1][] =& + new SOAP_Interop_Test('echoString', + array('x' => &$string)); + +# IMPORT 2 tests +# http://www.whitemesa.net/wsdl/r3/import2.wsdl +$soap_tests[INTEROP_R3D_IMPORT2][] =& + new SOAP_Interop_Test('echoStruct', + array('inputStruct' => &$soapstruct)); + +# IMPORT 2 tests +# http://www.whitemesa.net/wsdl/r3/import3.wsdl +$test =& new SOAP_Interop_Test('echoStruct', + array('inputStruct' => &$soapstruct)); +$test->service = 'Import3'; +$soap_tests[INTEROP_R3D_IMPORT3][] = &$test; +unset($test); + +$test =& new SOAP_Interop_Test('echoStructArray', + array('inputArray' =>&$soapstruct_array)); +$test->service = 'Import3'; +$soap_tests[INTEROP_R3D_IMPORT3][] = &$test; +unset($test); + +# RPC ENCODED Tests +# http://www.whitemesa.net/wsdl/r3/interoptestdoclitparameters.wsdl +$soap_tests[INTEROP_R3D_RPCENC][] =& + new SOAP_Interop_Test('echoString', + array('param0' => &$string)); +$soap_tests[INTEROP_R3D_RPCENC][] =& + new SOAP_Interop_Test('echoStringArray', + array('param0' => &$string_array)); +$soap_tests[INTEROP_R3D_RPCENC][] =& + new SOAP_Interop_Test('echoStruct', + array('param0' => &$soapstruct)); +$soap_tests[INTEROP_R3D_RPCENC][] =& + new SOAP_Interop_Test('echoVoid', NULL); + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_classes.php b/gulliver/thirdparty/pear/SOAP/Interop/params_classes.php new file mode 100644 index 000000000..187b311ce --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_classes.php @@ -0,0 +1,162 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_classes.php,v 1.8 2007/01/21 16:15:00 yunosh Exp $ +// +require_once 'SOAP/Value.php'; + +class SOAPStruct { + var $varString; + var $varInt; + var $varFloat; + function SOAPStruct($s=NULL, $i=NULL, $f=NULL) { + $this->varString = $s; + $this->varInt = $i; + $this->varFloat = $f; + } + + function __to_soap($name = 'inputStruct', $header=false, $mustUnderstand=0, $actor='http://schemas.xmlsoap.org/soap/actor/next') + { + $inner[] = new SOAP_Value('varString','string',$this->varString); + $inner[] = new SOAP_Value('varInt','int',$this->varInt); + $inner[] = new SOAP_Value('varFloat','float',$this->varFloat); + if ($header) { + return new SOAP_Header($name,'{http://soapinterop.org/xsd}SOAPStruct',$inner,$mustUnderstand,$actor); + } + return new SOAP_Value($name,'{http://soapinterop.org/xsd}SOAPStruct',$inner); + + } +} + +class SOAPStructStruct { + var $varString; + var $varInt; + var $varFloat; + var $varStruct; + function SOAPStructStruct($s=NULL, $i=NULL, $f=NULL, $ss=NULL) { + // XXX unfortunately, a copy of $ss will occure here + // ze2 can fix this I think + $this->varString = $s; + $this->varInt = $i; + $this->varFloat = $f; + $this->varStruct = $ss; + } + + function __to_soap($name = 'inputStruct') + { + $v[] = new SOAP_Value('varString','string',$this->varString); + $v[] = new SOAP_Value('varInt','int',$this->varInt); + $v[] = new SOAP_Value('varFloat','float',$this->varFloat); + $v[] = $this->varStruct->__to_soap('varStruct'); + return new SOAP_Value($name,'{http://soapinterop.org/xsd}SOAPStructStruct',$v); + } +} + +class SOAPArrayStruct { + var $varString; + var $varInt; + var $varFloat; + var $varArray; + function SOAPArrayStruct($s=NULL, $i=NULL, $f=NULL, $ss=NULL) { + // XXX unfortunately, a copy of $ss will occure here + // ze2 can fix this I think + $this->varString = $s; + $this->varInt = $i; + $this->varFloat = $f; + $this->varArray = $ss; + } + + function __to_soap($name = 'inputStruct') + { + $ar = array(); + $c = count($this->varArray); + for ($i=0; $i<$c; $i++) { + $ar[] = new SOAP_Value('item','string',$this->varArray[$i]); + } + $v[] = new SOAP_Value('varString','string',$this->varString); + $v[] = new SOAP_Value('varInt','int',$this->varInt); + $v[] = new SOAP_Value('varFloat','float',$this->varFloat); + $v[] = new SOAP_Value('varArray',false,$ar); + + return new SOAP_Value($name,'{http://soapinterop.org/xsd}SOAPArrayStruct',$v); + } +} + +class Person { + var $Age; + var $ID; + var $Name; + var $Male; + function Person($a=NULL, $i=NULL, $n=NULL, $m=NULL) { + $this->Age = $a; + $this->ID = $i; + $this->Name = $n; + $this->Male = $m; + } + + function __set_attribute($key, $value) + { + $this->$key = $value; + } + + function __to_soap($name = 'x_Person',$ns = 'http://soapinterop.org/xsd', $compound2=false) + { + if (!$compound2) { + $v[] = new SOAP_Value("\{$ns}Age",'double',$this->Age); + $v[] = new SOAP_Value("\{$ns}ID",'float',$this->ID); + return new SOAP_Value("\{$ns}$name",'Person', + $v,array('Name'=>$this->Name,'Male'=>$this->Male)); + } else + $v[] = new SOAP_Value("\{$ns}Name",'string',$this->Name); + $v[] = new SOAP_Value("\{$ns}Male",'boolean',$this->Male); + return new SOAP_Value("\{$ns}$name",'Person',$v); + } +} + +class x_Person extends Person { + function x_Person($a=NULL, $i=NULL, $n=NULL, $m=NULL) { + $parent->Person($a,$i,$n,$m); + } +} + +class Employee { + var $ID; + var $salary; + var $person; // class person2 + function Employee($person=NULL,$id=NULL,$salary=NULL) { + $this->person = $person; + $this->ID = $id; + $this->salary = $salary; + } + + function __to_soap($name = 'x_Employee', $ns='http://soapinterop.org/employee') + { + $person = $this->person->__to_soap('person','http://soapinterop.org/person',true); + $person->namespace = $ns; + $va[] = $person; + $va[] = new SOAP_Value("\{$ns}salary",'double',$this->salary); + $va[] = new SOAP_Value("\{$ns}ID",'int',$this->ID); + return new SOAP_Value("\{$ns}$name",'Employee',$va); + } +} + +class x_Employee extends Employee { + function x_Employee($person=NULL,$id=NULL,$salary=NULL) { + $parent->Employee($person,$id,$salary); + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/params_values.php b/gulliver/thirdparty/pear/SOAP/Interop/params_values.php new file mode 100644 index 000000000..cfa27f09a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/params_values.php @@ -0,0 +1,173 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: params_values.php,v 1.7 2007/01/26 15:18:21 yunosh Exp $ +// + +require_once 'SOAP/Value.php'; +require_once 'params_classes.php'; + +$soap_test_null = null; + +$string = 'Hello World'; +$string_soapval = new SOAP_Value('inputString', 'string', $string); +$string_null = null; +$string_null_soapval = new SOAP_Value('inputString', 'string', $string_null); +$string_entities = "this is a test \n"; +$string_entities_soapval = new SOAP_Value('inputString', 'string', $string_entities); +$string_utf8 = utf8_encode('ỗÈéóÒ₧⅜ỗỸ'); +$string_utf8_soapval = new SOAP_Value('inputString', 'string', $string_utf8); +$string_array = array('good', 'bad'); +$string_array_soapval = new SOAP_Value( + 'inputStringArray', + 'Array', + array(new SOAP_Value('item', 'string', 'good'), + new SOAP_Value('item', 'string', 'bad'))); + +$string_array_one = array('good'); +$string_array_one_soapval = new SOAP_Value( + 'inputStringArray', + 'Array', + array(new SOAP_Value('item', 'string', 'good'))); + +$string_array_null = null; +$string_array_null_soapval = new SOAP_Value('inputStringArray', 'Array', null); +$string_array_null_soapval->arrayType='{http://www.w3.org/2001/XMLSchema}string'; + +$integer = 12345; +$integer_soapval = new SOAP_Value('inputInteger', 'int', $integer); +$integer_array = array(1, 234324324, 2); +$integer_array_soapval = new SOAP_Value( + 'inputIntegerArray', + 'Array', + array(new SOAP_Value('item', 'int', 1), + new SOAP_Value('item', 'int', 234324324), + new SOAP_Value('item', 'int', 2))); + +$integer_array_null = null; +$integer_array_null_soapval = new SOAP_Value('inputIntegerArray', 'Array', null); +$integer_array_null_soapval->arrayType='{http://www.w3.org/2001/XMLSchema}int'; + +$float = 123.45; +$float_soapval = new SOAP_Value('inputFloat', 'float', $float); +$float_array = array(1.0, 2343.24324, -2.5); +$float_array_soapval = new SOAP_Value( + 'inputFloatArray', + 'Array', + array(new SOAP_Value('item', 'float', 1.0), + new SOAP_Value('item', 'float', 2343.24324), + new SOAP_Value('item', 'float', -2.5))); + +$float_array_null = null; +$float_array_null_soapval = new SOAP_Value('inputFloatArray', 'Array', null); +$float_array_null_soapval->arrayType='{http://www.w3.org/2001/XMLSchema}float'; + +$soapstruct = new SOAPStruct('arg', 34, 325.325); +$soapstruct_soapval = $soapstruct->__to_soap(); +$soapstruct_header_soapval = $soapstruct->__to_soap('{http://soapinterop.org/echoheader/}echoMeStructRequest'); +$soapstruct_array = array($soapstruct, $soapstruct, $soapstruct); +$soapstruct_array_soapval = new SOAP_Value( + 'inputStructArray', + 'Array', + array($soapstruct_soapval, + $soapstruct_soapval, + $soapstruct_soapval)); + +$soapstructstruct = new SOAPStructStruct('arg', 34, 325.325, $soapstruct); +$soapstructstruct_soapval = $soapstructstruct->__to_soap(); +$soapstructstruct_array = array($soapstructstruct, $soapstructstruct, $soapstructstruct); +$soapstructstruct_array_soapval = new SOAP_Value( + 'inputStructArray', + 'Array', + array($soapstructstruct_soapval, + $soapstructstruct_soapval, + $soapstructstruct_soapval)); + +$soaparraystruct = new SOAPArrayStruct('arg', 34, 325.325, + array('good', 'bad', 'ugly')); +$soaparraystruct_soapval = $soaparraystruct->__to_soap(); +$soaparraystruct_array = array($soaparraystruct, $soaparraystruct, $soaparraystruct); +$soaparraystruct_array_soapval = new SOAP_Value( + 'inputStructArray', + 'Array', + array($soaparraystruct_soapval, + $soaparraystruct_soapval, + $soaparraystruct_soapval)); + +$simpletypes = array( + 'inputString'=>'arg', + 'inputInteger'=>34, + 'inputFloat'=>325.325 + ); + +$simpletypes_soapval = array(); +$simpletypes_soapval[] = new SOAP_Value('inputString', 'string', 'arg'); +$simpletypes_soapval[] = new SOAP_Value('inputInteger', 'int', 34); +$simpletypes_soapval[] = new SOAP_Value('inputFloat', 'float', 325.325); + +$base64 = 'TmVicmFza2E='; +$base64_soapval = new SOAP_Value('inputBase64', 'base64Binary', $base64); + +$hexBin = '736F61707834'; +$hexBin_soapval = new SOAP_Value('inputHexBinary', 'hexBinary', $hexBin); + +$decimal = 12345.67890; +$decimal_soapval =new SOAP_Value('inputDecimal', 'decimal', $decimal); + +$dateTime = '2001-05-24T17:31:41Z'; +$dateTime_soapval = new SOAP_Value('inputDate', 'dateTime', $dateTime); + +$boolean_true = true; +$boolean_true_soapval = new SOAP_Value('inputBoolean', 'boolean', true); +$boolean_false = false; +$boolean_false_soapval = new SOAP_Value('inputBoolean', 'boolean', false); +$boolean_one = 1; +$boolean_one_soapval = new SOAP_Value('inputBoolean', 'boolean', 1); +$boolean_zero = 0; +$boolean_zero_soapval = new SOAP_Value('inputBoolean', 'boolean', 0); + +// XXX I know this isn't quite right, need to deal with this better +function &make_2d($x, $y) +{ + $a = array(); + for ($_x = 0; $_x < $x; $_x++) { + $a[$_x] = array(); + for ($_y = 0; $_y < $y; $_y++) { + $a[$_x][$_y] = "x{$_x}y{$_y}"; + } + } + return $a; +} + +$multidimarray = make_2d(3, 3); +$multidimarray_soapval = new SOAP_Value( + 'input2DStringArray', + 'Array', + array(array(new SOAP_Value('item', 'string', 'row0col0'), + new SOAP_Value('item', 'string', 'row0col1'), + new SOAP_Value('item', 'string', 'row0col2')), + array(new SOAP_Value('item', 'string', 'row1col0'), + new SOAP_Value('item', 'string', 'row1col1'), + new SOAP_Value('item', 'string', 'row1col2')))); +$multidimarray_soapval->options['flatten'] = true; + +// Round2GroupC values +$_person = new Person(32, 12345, 'Shane', true); +$person = $_person->__to_soap(); +$_employee = new Employee($_person, 12345, 1000000.00); +$employee = $_employee->__to_soap(); diff --git a/gulliver/thirdparty/pear/SOAP/Interop/readme.txt b/gulliver/thirdparty/pear/SOAP/Interop/readme.txt new file mode 100644 index 000000000..933e65265 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/readme.txt @@ -0,0 +1,23 @@ +Round 2 Interop Test files + +Resources: +http://www.whitemesa.com/interop.htm +http://www.whitemesa.com/r3/interop3.html +http://www.pocketsoap.com/registration/ + +Requires an SQL database, schema for MySQL is in interop_database.sql. + +Run interop_client_run.php to store test results. +View index.php to see test results. + +To setup an interop server: + +1. Copy config.php.dist to config.php. +2. Web server must alias url /soap_interop/ to the pear/SOAP_Interop + directory. The alias url can be set in config.php. +3. index.php should be set for the default document. +4. MySQL should be set up, with a database called interop, schema is in + interop_database.sql. Database name, user, and password can be set in + config.php. +5. interop_client_run.php should not be left under the web root, it is + available for manual testing. diff --git a/gulliver/thirdparty/pear/SOAP/Interop/registrationAndNotification.php b/gulliver/thirdparty/pear/SOAP/Interop/registrationAndNotification.php new file mode 100644 index 000000000..bda1d5a5c --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/registrationAndNotification.php @@ -0,0 +1,473 @@ +$v) { + $this->$k = $v; + } + } + } +} + +class serverInfo { + var $id; + var $service_id; + var $name; + var $version; + var $endpointURL; + var $wsdlURL; + + function serverInfo($ar=NULL) { + if (is_array($ar)) { + foreach ($ar as $k=>$v) { + $this->$k = $v; + } + } + } +} + +class Service { + var $id; + var $name; + var $description; + var $wsdlURL; + var $websiteURL; + + function Service($ar=NULL) { + if (is_array($ar)) { + foreach ($ar as $k=>$v) { + $this->$k = $v; + } + } + } +} + +class subscriberInfo { + var $notificationID; + var $expires; /* dateTime */ +} + +class ChangeItem { + var $id; + var $timestamp; /* dateTime */ + var $headline; + var $notes; + var $url; +} + +function getLocalInteropServer($testname,$id,$localBaseUrl='http://localhost/soap_interop/') { + $localServer = array(); + $localServer['service_id']=$id; + $localServer['name']='Local PEAR::SOAP'; + $localServer['version']=SOAP_LIBRARY_VERSION; + switch ($testname) { + case 'Round 2 Base': + $localServer['endpointURL']=$localBaseUrl.'server_Round2Base.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/interop.wsdl.php'; + return new serverInfo($localServer); + case 'Round 2 Group B': + $localServer['endpointURL']=$localBaseUrl.'server_Round2GroupB.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/interopB.wsdl.php'; + return new serverInfo($localServer); + case 'Round 2 Group C': + $localServer['endpointURL']=$localBaseUrl.'server_Round2GroupC.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/echoheadersvc.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D EmptySA': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDEmptySA.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/emptysa.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D Compound 1': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDCompound1.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/compound1.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D Compound 2': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDCompound2.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/compound2.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D DocLit': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDDocLit.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/InteropTestDocLit.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D DocLitParams': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDDocLitParams.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/InteropTestDocLitParameters.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D Import 1': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDImport1.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/import1.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D Import 2': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDImport2.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/import2.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D Import 3': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDImport3.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/import3.wsdl.php'; + return new serverInfo($localServer); + case 'Round 3 Group D RpcEnc': + $localServer['endpointURL']=$localBaseUrl.'server_Round3GroupDRpcEnc.php'; + $localServer['wsdlURL']=$localBaseUrl.'wsdl/InteropTestRpcEnc.wsdl.php'; + return new serverInfo($localServer); + #case 'Round 3 Group E DocLit': + #case 'Round 3 Group E RpcEnc': + #case 'Round 3 Group F Extensibility': + #case 'Round 3 Group F ExtensibilityRequired': + #case 'Round 3 Group F Headers': + #case 'Round 4 DIME/Doc Attachments': + #case 'Round 4 DIME/RPC Attachments': + #case 'Round 4 MIME/Doc Attachments': + #case 'Round 4 SwA/RPC Attachments': + } + return NULL; +} + +class SOAP_Interop_registrationAndNotificationService_ServicesPort extends SOAP_Client { + function SOAP_Interop_registrationAndNotificationService_ServicesPort() { + $this->SOAP_Client("http://soap.4s4c.com/registration/soap.asp", 0); + $this->_auto_translation = true; + } + function &ServiceList() { + return $this->call("ServiceList", + $v = NULL, + array('namespace'=>'http://soap.pocketsoap.com/registration/services', + 'soapaction'=>'http://soap.pocketsoap.com/registration/services#ServiceList', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &Servers($serviceID) { + return $this->call("Servers", + $v = array("serviceID"=>$serviceID), + array('namespace'=>'http://soap.pocketsoap.com/registration/services', + 'soapaction'=>'http://soap.pocketsoap.com/registration/services#Servers', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &Clients($serviceID) { + return $this->call("Clients", + $v = array("serviceID"=>$serviceID), + array('namespace'=>'http://soap.pocketsoap.com/registration/services', + 'soapaction'=>'http://soap.pocketsoap.com/registration/services#Clients', + 'style'=>'rpc', + 'use'=>'encoded')); + } +} +class SOAP_Interop_registrationAndNotificationService_ClientsPort extends SOAP_Client { + function SOAP_Interop_registrationAndNotificationService_ClientsPort() { + $this->SOAP_Client("http://soap.4s4c.com/registration/soap.asp", 0); + $this->_auto_translation = true; + } + function &RegisterClient($serviceID, $clientInfo) { + return $this->call("RegisterClient", + $v = array("serviceID"=>$serviceID, "clientInfo"=>$clientInfo), + array('namespace'=>'http://soap.pocketsoap.com/registration/clients', + 'soapaction'=>'http://soap.pocketsoap.com/registration/clients#RegisterClient', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &UpdateClient($clientID, $clientInfo) { + return $this->call("UpdateClient", + $v = array("clientID"=>$clientID, "clientInfo"=>$clientInfo), + array('namespace'=>'http://soap.pocketsoap.com/registration/clients', + 'soapaction'=>'http://soap.pocketsoap.com/registration/clients#UpdateClient', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &RemoveClient($clientID) { + return $this->call("RemoveClient", + $v = array("clientID"=>$clientID), + array('namespace'=>'http://soap.pocketsoap.com/registration/clients', + 'soapaction'=>'http://soap.pocketsoap.com/registration/clients#RemoveClient', + 'style'=>'rpc', + 'use'=>'encoded')); + } +} +class SOAP_Interop_registrationAndNotificationService_ServersPort extends SOAP_Client { + function SOAP_Interop_registrationAndNotificationService_ServersPort() { + $this->SOAP_Client("http://soap.4s4c.com/registration/soap.asp", 0); + $this->_auto_translation = true; + } + function &RegisterServer($serviceID, $serverInfo) { + return $this->call("RegisterServer", + $v = array("serviceID"=>$serviceID, "serverInfo"=>$serverInfo), + array('namespace'=>'http://soap.pocketsoap.com/registration/servers', + 'soapaction'=>'http://soap.pocketsoap.com/registration/servers#RegisterServer', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &UpdateServer($serverID, $serverInfo) { + return $this->call("UpdateServer", + $v = array("serverID"=>$serverID, "serverInfo"=>$serverInfo), + array('namespace'=>'http://soap.pocketsoap.com/registration/servers', + 'soapaction'=>'http://soap.pocketsoap.com/registration/servers#UpdateServer', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &RemoveServer($serverID) { + return $this->call("RemoveServer", + $v = array("serverID"=>$serverID), + array('namespace'=>'http://soap.pocketsoap.com/registration/servers', + 'soapaction'=>'http://soap.pocketsoap.com/registration/servers#RemoveServer', + 'style'=>'rpc', + 'use'=>'encoded')); + } +} +class SOAP_Interop_registrationAndNotificationService_SubscriberPort extends SOAP_Client { + function SOAP_Interop_registrationAndNotificationService_SubscriberPort() { + $this->SOAP_Client("http://soap.4s4c.com/registration/soap.asp", 0); + $this->_auto_translation = true; + } + function &Subscribe($serviceID, $ServerChanges, $ClientChanges, $NotificationURL) { + return $this->call("Subscribe", + $v = array("serviceID"=>$serviceID, "ServerChanges"=>$ServerChanges, "ClientChanges"=>$ClientChanges, "NotificationURL"=>$NotificationURL), + array('namespace'=>'http://soap.pocketsoap.com/registration/subscriber', + 'soapaction'=>'http://soap.pocketsoap.com/registration/subscriber#Subscribe', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &Renew($notificationID) { + return $this->call("Renew", + $v = array("notificationID"=>$notificationID), + array('namespace'=>'http://soap.pocketsoap.com/registration/subscriber', + 'soapaction'=>'http://soap.pocketsoap.com/registration/subscriber#Renew', + 'style'=>'rpc', + 'use'=>'encoded')); + } + function &Cancel($notificationID) { + return $this->call("Cancel", + $v = array("notificationID"=>$notificationID), + array('namespace'=>'http://soap.pocketsoap.com/registration/subscriber', + 'soapaction'=>'http://soap.pocketsoap.com/registration/subscriber#Cancel', + 'style'=>'rpc', + 'use'=>'encoded')); + } +} +class SOAP_Interop_registrationAndNotificationService_ChangeLogPort extends SOAP_Client { + function SOAP_Interop_registrationAndNotificationService_ChangeLogPort() { + $this->SOAP_Client("http://soap.4s4c.com/registration/soap.asp", 0); + $this->_auto_translation = true; + } + function &RecentChanges($MaxEntries) { + return $this->call("RecentChanges", + $v = array("MaxEntries"=>$MaxEntries), + array('namespace'=>'http://soap.pocketsoap.com/registration/changeLog', + 'soapaction'=>'http://soap.pocketsoap.com/registration/changeLog#RecentChanges', + 'style'=>'rpc', + 'use'=>'encoded')); + } +} + +class SOAP_Interop_registrationDB { + var $DSN; + var $dbc = NULL; + + var $client; // soap_client + var $services; + var $currentServiceId; + var $servers; + var $clients; + + function SOAP_Interop_registrationDB() + { + global $interopConfig; + $this->DSN = $interopConfig['DSN']; + $this->client =& new SOAP_Interop_registrationAndNotificationService_ServicesPort(); + $this->connectDB(); + $this->getServiceList(); + } + + function connectDB() + { + if (!$this->dbc) + $this->dbc =& DB::connect($this->DSN, true); + if (PEAR::isError($this->dbc)) { + echo $this->dbc->getMessage(); + $this->dbc = NULL; + return false; + } + return true; + } + + function updateDB() + { + $this->updateServiceDb(); + $this->updateServerDb(); + $this->updateClientsDb(); + } + + function &retreiveServiceList() + { + if (!$this->services) { + $this->services =& $this->client->ServiceList(); + } + return $this->services; + } + + function &retreiveServerList($serviceID) + { + if (!$this->servers || $this->currentServiceId != $serviceID) { + $this->currentServiceId = $serviceID; + $this->servers =& $this->client->Servers($serviceID); + } + return $this->servers; + } + + function &retreiveClientList($serviceID) + { + if (!$this->clients || $this->currentServiceId != $serviceID) { + $this->currentServiceId = $serviceID; + $this->clients =& $this->client->Clients($serviceID); + } + return $this->clients; + } + + function updateServiceDb() + { + if (!$this->connectDB()) return false; + $this->retreiveServiceList(); + echo "Updating Services\n"; + foreach ($this->services as $service) { + $res = $this->dbc->getRow("select id from services where id='{$service->id}'"); + if ($res && !PEAR::isError($res)) { + $res = $this->dbc->query("update services set name='{$service->name}',". + "description='{$service->description}',wsdlURL='{$service->wsdlURL}',". + "websiteURL='{$service->websiteURL}' where id='{$service->id}'"); + } else { + $res = $this->dbc->query("insert into services (id,name,description,wsdlURL,websiteURL) ". + "values('{$service->id}','{$service->name}','{$service->description}','{$service->wsdlURL}','{$service->websiteURL}')"); + } + } + } + + function _updateOrAddServer($id, $server) { + $res = $this->dbc->getRow("select * from serverinfo where service_id='$id' and name='{$server->name}'"); + if ($res && !PEAR::isError($res)) { + $res = $this->dbc->query("update serverinfo set ". + "version='{$server->version}', ". + "endpointURL='{$server->endpointURL}', ". + "wsdlURL='{$server->wsdlURL}' where id={$res->id}"); + } else { + $res = $this->dbc->query("insert into serverinfo (service_id,name,version,endpointURL,wsdlURL) ". + "values('$id','{$server->name}','{$server->version}','{$server->endpointURL}','{$server->wsdlURL}')"); + } + if (PEAR::isError($res)) { + echo $res->toString() . "\n"; + } + } + + function updateServerDb() + { + global $INTEROP_LOCAL_SERVER; + if (!$this->connectDB()) return false; + $this->retreiveServiceList(); + $c = count($this->services); + for ($i=0;$i<$c;$i++) { + $this->retreiveServerList($this->services[$i]->id); + echo "Updating Servers for {$this->services[$i]->name}\n"; + if (!$this->servers) continue; + foreach ($this->servers as $server) { + $this->_updateOrAddServer($this->services[$i]->id, $server); + } + // add the local server now + if ($INTEROP_LOCAL_SERVER) { + $server = getLocalInteropServer($this->services[$i]->name, $this->services[$i]->id); + if ($server) { + $this->_updateOrAddServer($this->services[$i]->id, $server); + } + } + } + } + + function updateClientsDb() + { + if (!$this->connectDB()) return false; + $this->retreiveServiceList(); + foreach ($this->services as $service) { + $this->retreiveClientList($service->id); + echo "Updating Clients for {$service->name}\n"; + if (!$this->clients) continue; + foreach ($this->clients as $client) { + $res = $this->dbc->getRow("select id from clientinfo where id='{$service->id}' and name='{$client->name}'"); + if ($res && !PEAR::isError($res)) { + $res = $this->dbc->query("update clientinfo set ". + "version='{$client->version}', ". + "resultsURL='{$client->resultsURL}' where ". + "id='{$service->id}',name='{$client->name}'"); + } else { + $res = $this->dbc->query("insert into clientinfo (id,name,version,resultsURL) ". + "values('{$service->id}','{$client->name}','{$client->version}','{$client->resultsURL}')"); + } + + } + } + } + + function &getServiceList($forcefetch=FALSE) + { + if (!$forcefetch && !$this->services) { + $this->dbc->setFetchMode(DB_FETCHMODE_OBJECT,'Service'); + $this->services = $this->dbc->getAll('select * from services',NULL, DB_FETCHMODE_OBJECT ); + } + if ($forcefetch || !$this->services) { + $this->updateServiceDb(); + } + return $this->services; + } + + function &getServerList($serviceID,$forcefetch=FALSE) + { + if (!$forcefetch && (!$this->servers || $this->currentServiceId != $serviceID)) { + $this->dbc->setFetchMode(DB_FETCHMODE_OBJECT,'serverInfo'); + $this->servers = $this->dbc->getAll("select * from serverinfo where service_id = '$serviceID'",NULL, DB_FETCHMODE_OBJECT ); + } + if ($forcefetch || !$this->servers) { + $this->updateServerDb(); + $this->dbc->setFetchMode(DB_FETCHMODE_OBJECT,'serverInfo'); + $this->servers = $this->dbc->getAll("select * from serverinfo where service_id = '$serviceID'",NULL, DB_FETCHMODE_OBJECT ); + if (!$this->servers) { + die("Error retrieving server list!\n"); + } + } + return $this->servers; + } + + function &getClientList($serviceID,$forcefetch=FALSE) + { + if (!$forcefetch && (!$this->clients || $this->currentServiceId != $serviceID)) { + $this->dbc->setFetchMode(DB_FETCHMODE_OBJECT,'clientInfo'); + $this->clients = $this->dbc->getAll("select * from clientinfo where id = '$serviceID'",NULL, DB_FETCHMODE_OBJECT ); + } + if ($forcefetch || !$this->clients) { + $this->updateClientDb(); + $this->dbc->setFetchMode(DB_FETCHMODE_OBJECT,'clientInfo'); + $this->clients = $this->dbc->getAll("select * from clientinfo where id = '$serviceID'",NULL, DB_FETCHMODE_OBJECT ); + if (!$this->clients) { + die("Error retrieving client list!\n"); + } + } + return $this->clients; + } + + function &findService($serviceName) + { + $this->getServiceList(); + $c = count($this->services); + for ($i=0 ; $i<$c; $i++) { + if (strcmp($serviceName, $this->services[$i]->name)==0) return $this->services[$i]; + } + return NULL; + } +} + +#$reg =& new SOAP_Interop_registrationAndNotificationDB(); +#$reg->updateDB(); +//print_r($l); +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round2Base.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2Base.php new file mode 100644 index 000000000..9a6f8ab6a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2Base.php @@ -0,0 +1,51 @@ + Port to PEAR and more | +// | Authors: Dietrich Ayala Original Author | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round2Base.php,v 1.5 2003/08/05 16:56:43 arnaud Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'interop_Round2Base.php'; + +$base =& new SOAP_Interop_Base(); +$server =& new SOAP_Server; +$server->_auto_translation = true; + +$server->addObjectMap($base,'http://soapinterop.org/'); +$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL); + +$test = ' + + + + + + +arg +34 +325.325 + +'; +#$server->service($test,'',TRUE); + +?> diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupB.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupB.php new file mode 100644 index 000000000..833c2e966 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupB.php @@ -0,0 +1,55 @@ + Port to PEAR and more | +// | Authors: Dietrich Ayala Original Author | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round2GroupB.php,v 1.5 2003/08/05 16:56:43 arnaud Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'interop_Round2GroupB.php'; + +$groupb =& new SOAP_Interop_GroupB(); +$server =& new SOAP_Server; +$server->_auto_translation = true; + +$server->addObjectMap($groupb,'http://soapinterop.org/'); +$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL); + +$test = ' + + + + + + +arg +34 +325.325 + +arg +34 +325.325 + +'; +#$server->service($test,'',TRUE); + +?> diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupC.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupC.php new file mode 100644 index 000000000..d8a4cd9f5 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round2GroupC.php @@ -0,0 +1,33 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round2GroupC.php,v 1.5 2003/08/05 16:56:43 arnaud Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'interop_Round2Base.php'; +require_once 'interop_Round2GroupC.php'; + +$groupc_headers =& new SOAP_Interop_GroupC_Headers(); +$base =& new SOAP_Interop_Base(); +$server =& new SOAP_Server; +$server->_auto_translation = true; + +$server->addObjectMap($groupc_headers,'http://soapinterop.org/echoheader/'); +$server->addObjectMap($base,'http://soapinterop.org/'); +$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL); +?> diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupD.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupD.php new file mode 100644 index 000000000..08f3e46de --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupD.php @@ -0,0 +1,49 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupD.php,v 1.4 2005/04/01 16:18:00 chagenbu Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'interop_Round3GroupD.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$groupd = new SOAP_Interop_GroupD(); +$server = new SOAP_Server; +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +$server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : NULL); + +$test = ' + + + + +Test Document Here + +'; +#$server->service($test,'',TRUE); diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound1.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound1.php new file mode 100644 index 000000000..83227ce80 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound1.php @@ -0,0 +1,72 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDCompound1.php,v 1.5 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDCompound1 { + + function echoPerson($person) + { + return $person->__to_soap('result_Person'); + } + + function echoDocument($document) + { + $ns = '{http://soapinterop.org/xsd}'; + return new SOAP_Value($ns . 'result_Document', $ns . 'x_Document', $document); + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$options = array('use' => 'literal', 'style' => 'document'); +$groupd = new SOAP_Interop_GroupDCompound1(); +$server = new SOAP_Server($options); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +$server->bind('http://localhost/soap_interop/wsdl/compound1.wsdl.php'); +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); +} else { + // allows command line testing of specific request + $test = ' + + + + +Test Document Here + +'; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound2.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound2.php new file mode 100644 index 000000000..e14d2950b --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDCompound2.php @@ -0,0 +1,70 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDCompound2.php,v 1.5 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDCompound2 { + + function echoEmployee(&$employee) + { + return $employee->__to_soap('result_Employee'); + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$options = array('use' => 'literal', 'style' => 'document'); +$groupd = new SOAP_Interop_GroupDCompound2(); +$server = new SOAP_Server($options); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop.org/employee'); + +$server->bind('http://localhost/soap_interop/wsdl/compound2.wsdl.php'); +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : NULL); +} else { + $test = ' + + + + + + + Shane + true + 1000000 + 12345 + + '; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLit.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLit.php new file mode 100644 index 000000000..91dc69213 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLit.php @@ -0,0 +1,98 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDDocLit.php,v 1.6 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDDocLit { + + // wsdlns:SoapInteropEmptySABinding + function echoString($inputString) + { + return new SOAP_Value('{http://soapinterop.org/xsd}echoStringReturn', 'string', $inputString); + } + + function echoStringArray($inputStringArray) + { + $ra = array(); + if ($inputStringArray) { + foreach ($inputStringArray as $s) { + $ra[] =& new SOAP_Value('item', 'string', $s); + } + } + return new SOAP_Value('{http://soapinterop.org/xsd}echoStringArrayReturn', null, $ra); + } + + function echoStruct($inputStruct) + { + $ns = '{http://soapinterop.org/xsd}'; + if (is_object($inputStruct) && + strtolower(get_class($inputStruct)) == 'soapstruct') { + return $inputStruct->__to_soap($ns.'echoStructReturn'); + } else { + if (is_object($inputStruct)) { + $inputStruct = get_object_vars($inputStruct); + } + $struct = new SOAPStruct($inputStruct['varString'], $inputStruct['varInt'], $inputStruct['varFloat']); + return $struct->__to_soap($ns.'echoStructReturn'); + } + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$options = array('use'=>'literal', 'style'=>'document'); +$groupd = new SOAP_Interop_GroupDDocLit(); +$server = new SOAP_Server($options); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop.org/WSDLInteropTestDocLit'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +$server->bind('http://localhost/soap_interop/wsdl/InteropTestDocLit.wsdl.php'); + +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : NULL); +} else { + // allows command line testing of specific request + $test = ' + + + + + +arg +34 +325.325 + +'; + $server->service($test, '', true); +} + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLitParams.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLitParams.php new file mode 100644 index 000000000..48bb6c7a4 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDDocLitParams.php @@ -0,0 +1,96 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDDocLitParams.php,v 1.5 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDDocLitParams { + + function echoString($inputString) + { + return new SOAP_Value('return', 'string', $inputString); + } + + function echoStringArray($inputStringArray) + { + $ra = array(); + if ($inputStringArray) { + foreach ($inputStringArray as $s) { + $ra[] =& new SOAP_Value('item', 'string', $s); + } + } + return new SOAP_Value('return', null, $ra); + } + + function echoStruct($inputStruct) + { + if (is_object($inputStruct) && + get_class($inputStruct) == 'soapstruct') { + return $inputStruct->__to_soap('return'); + } else { + if (is_object($inputStruct)) { + $inputStruct = get_object_vars($inputStruct); + } + $struct = new SOAPStruct($inputStruct['varString'], $inputStruct['varInt'], $inputStruct['varFloat']); + return $struct->__to_soap('return'); + } + } + + function echoVoid() + { + return null; + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$options = array('use' => 'literal', 'style' => 'document'); +$groupd = new SOAP_Interop_GroupDDocLitParams(); +$server = new SOAP_Server($options); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +$server->bind('http://localhost/soap_interop/wsdl/InteropTestDocLitParameters.wsdl.php'); +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); +} else { + // allows command line testing of specific request + $test = ' + + + + + + +'; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDEmptySA.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDEmptySA.php new file mode 100644 index 000000000..31446b76e --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDEmptySA.php @@ -0,0 +1,38 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDEmptySA.php,v 1.4 2003/08/05 16:56:43 arnaud Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'interop_Round3GroupD.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$options = array('use'=>'literal','style'=>'document'); +$groupd =& new SOAP_Interop_GroupD(); +$server =& new SOAP_Server($options); +$server->_auto_translation = true; + +$server->addObjectMap($groupd,'http://soapinterop/'); +$server->addObjectMap($groupd,'http://soapinterop.org/xsd'); + +$server->bind('http://localhost/soap_interop/wsdl/emptysa.wsdl.php'); +$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL); + +?> diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport1.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport1.php new file mode 100644 index 000000000..afb8b8694 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport1.php @@ -0,0 +1,64 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDImport1.php,v 1.5 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDImport1 { + + function echoString($inputString) + { + return new SOAP_Value('Result', 'string', $inputString); + } +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$groupd = new SOAP_Interop_GroupDImport1(); +$server = new SOAP_Server(); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/echoString/'); + +$server->bind('http://localhost/soap_interop/wsdl/import1.wsdl.php'); +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); +} else { + // allows command line testing of specific request + $test = ' + + + + + +Hello World + +'; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport2.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport2.php new file mode 100644 index 000000000..64fd0405f --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport2.php @@ -0,0 +1,81 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDImport2.php,v 1.6 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDImport2 { + + function echoStruct($inputStruct) + { + if (is_object($inputStruct) && + strtolower(get_class($inputStruct)) == 'soapstruct') { + return $inputStruct->__to_soap('Result'); + } else { + if (is_object($inputStruct)) { + $inputStruct = get_object_vars($inputStruct); + } + $struct = new SOAPStruct($inputStruct['varString'], $inputStruct['varInt'], $inputStruct['varFloat']); + return $struct->__to_soap('Result'); + } + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$groupd = new SOAP_Interop_GroupDImport2(); +$server = new SOAP_Server(); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +if (isset($_SERVER['SERVER_NAME'])) { + $baseurl = 'http://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . '/soap_interop/'; + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); +} else { + $baseurl = 'http://localhost/soap_interop/'; + $server->bind($baseurl.'wsdl/import2.wsdl.php'); + // allows command line testing of specific request + $test = ' + + + + + + +arg +34 +325.325 + +'; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport3.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport3.php new file mode 100644 index 000000000..6a2d88903 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDImport3.php @@ -0,0 +1,101 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDImport3.php,v 1.6 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDImport3 { + + function echoStruct($inputStruct) + { + $ns = '{http://soapinterop.org/xsd}'; + if (is_object($inputStruct) && + strtolower(get_class($inputStruct)) == 'soapstruct') { + return $inputStruct->__to_soap($ns . 'return'); + } else { + if (is_object($inputStruct)) { + $inputStruct = get_object_vars($inputStruct); + } + $struct = new SOAPStruct($inputStruct['varString'], $inputStruct['varInt'], $inputStruct['varFloat']); + return $struct->__to_soap($ns.'return'); + } + } + + function echoStructArray($inputStructArray) + { + $ra = array(); + if ($inputStructArray) { + $c = count($inputStructArray); + for ($i = 0; $i < $c; $i++) { + $ra[] = $inputStructArray[$i]->__to_soap('item'); + } + } + return $ra; + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$groupd = new SOAP_Interop_GroupDImport3(); +$server = new SOAP_Server(); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); + +$server->bind('http://localhost/soap_interop/wsdl/import3.wsdl.php'); +if (isset($_SERVER['SERVER_NAME'])) { + $server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); +} else { + // allows command line testing of specific request + $test = ' + + + + + + + +arg +34 +325.325 + +arg +34 +325.325 + +arg +34 +325.325 + +'; + $server->service($test, '', true); +} diff --git a/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDRpcEnc.php b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDRpcEnc.php new file mode 100644 index 000000000..cb67ae374 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/server_Round3GroupDRpcEnc.php @@ -0,0 +1,79 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: server_Round3GroupDRpcEnc.php,v 1.6 2007/01/22 14:53:22 yunosh Exp $ +// +require_once 'SOAP/Server.php'; +require_once 'params_classes.php'; + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +class SOAP_Interop_GroupDRpcEnc { + + // wsdlns:SoapInteropEmptySABinding + function echoString($inputString) + { + return new SOAP_Value('echoStringReturn', 'string', $inputString); + } + + function echoStringArray($inputStringArray) + { + $ra = array(); + if ($inputStringArray) { + foreach($inputStringArray as $s) { + $ra[] = new SOAP_Value('item', 'string', $s); + } + } + return new SOAP_Value('echoStringArrayReturn', null, $ra); + } + + function echoStruct($inputStruct) + { + if (is_object($inputStruct) && + strtolower(get_class($inputStruct)) == 'soapstruct') { + return $inputStruct->__to_soap('return'); + } else { + if (is_object($inputStruct)) { + $inputStruct = get_object_vars($inputStruct); + } + $struct = new SOAPStruct($inputStruct['varString'], $inputStruct['varInt'], $inputStruct['varFloat']); + return $struct->__to_soap('return'); + } + } + + function echoVoid() + { + return null; + } + +} + +// http://www.whitemesa.com/r3/interop3.html +// http://www.whitemesa.com/r3/plan.html + +$groupd = new SOAP_Interop_GroupDRpcEnc(); +$server = new SOAP_Server(); +$server->_auto_translation = true; + +$server->addObjectMap($groupd, 'http://soapinterop/'); +$server->addObjectMap($groupd, 'http://soapinterop.org/xsd'); +$server->addObjectMap($groupd, 'http://soapinterop.org/WSDLInteropTestRpcEnc'); + +$server->bind('http://localhost/soap_interop/wsdl/InteropTestRpcEnc.wsdl.php'); +$server->service(isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : null); diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLit.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLit.wsdl.php new file mode 100644 index 000000000..1d4adad41 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLit.wsdl.php @@ -0,0 +1,136 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDDocLit.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLitParameters.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLitParameters.wsdl.php new file mode 100644 index 000000000..6c6da053f --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestDocLitParameters.wsdl.php @@ -0,0 +1,176 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDDocLitParams.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibility.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibility.wsdl.php new file mode 100644 index 000000000..b34fa689b --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibility.wsdl.php @@ -0,0 +1,74 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_round3.php"/> + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibilityRequired.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibilityRequired.wsdl.php new file mode 100644 index 000000000..001aa35a6 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestExtensibilityRequired.wsdl.php @@ -0,0 +1,75 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_round3.php"/> + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestList.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestList.wsdl.php new file mode 100644 index 000000000..6f172bb42 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestList.wsdl.php @@ -0,0 +1,62 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_round3.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestRpcEnc.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestRpcEnc.wsdl.php new file mode 100644 index 000000000..8357194f3 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestRpcEnc.wsdl.php @@ -0,0 +1,127 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDRpcEnc.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestheaders.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestheaders.wsdl.php new file mode 100644 index 000000000..21cfeab52 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/InteropTestheaders.wsdl.php @@ -0,0 +1,72 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_round3.php"/> + + + \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound1.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound1.wsdl.php new file mode 100644 index 000000000..1a4dd73f0 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound1.wsdl.php @@ -0,0 +1,86 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDCompound1.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound2.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound2.wsdl.php new file mode 100644 index 000000000..7a3bbd9e7 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/compound2.wsdl.php @@ -0,0 +1,67 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDCompound2.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/echoheadersvc.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/echoheadersvc.wsdl.php new file mode 100644 index 000000000..67b7e676a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/echoheadersvc.wsdl.php @@ -0,0 +1,18 @@ +\n"; ?> + + + + + + + + + + /soap_interop/server_Round2GroupC.php"/> + + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/emptysa.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/emptysa.wsdl.php new file mode 100644 index 000000000..d51a6eef3 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/emptysa.wsdl.php @@ -0,0 +1,39 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDEmptySA.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import1.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import1.wsdl.php new file mode 100644 index 000000000..f0ed6586a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import1.wsdl.php @@ -0,0 +1,28 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDImport1.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import2.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import2.wsdl.php new file mode 100644 index 000000000..3875f10cf --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import2.wsdl.php @@ -0,0 +1,28 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDImport2.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import3.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import3.wsdl.php new file mode 100644 index 000000000..4396de741 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/import3.wsdl.php @@ -0,0 +1,77 @@ +\n"; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /soap_interop/server_Round3GroupDImport3.php"/> + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import1B.wsdl b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import1B.wsdl new file mode 100644 index 000000000..26ab6dbdd --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import1B.wsdl @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.wsdl b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.wsdl new file mode 100644 index 000000000..8a397bc0b --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.wsdl @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.xsd b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.xsd new file mode 100644 index 000000000..b35eded4f --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/imported/import2B.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interop.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interop.wsdl.php new file mode 100644 index 000000000..12a74b338 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interop.wsdl.php @@ -0,0 +1,19 @@ +\n"; ?> + + + + + + + + + /soap_interop/server_Round2Base.php"/> + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interopB.wsdl.php b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interopB.wsdl.php new file mode 100644 index 000000000..09c250c5a --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Interop/wsdl/interopB.wsdl.php @@ -0,0 +1,15 @@ +\n"; ?> + + + + + + + + /soap_interop/server_Round2GroupB.php"/> + + + + diff --git a/gulliver/thirdparty/pear/SOAP/Parser.php b/gulliver/thirdparty/pear/SOAP/Parser.php new file mode 100644 index 000000000..17924085c --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Parser.php @@ -0,0 +1,504 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; +require_once 'SOAP/Value.php'; + +/** + * SOAP Parser + * + * This class is used by SOAP::Message and SOAP::Server to parse soap + * packets. Originally based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Dietrich Ayala Original Author + */ +class SOAP_Parser extends SOAP_Base +{ + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $message = array(); + var $depth_array = array(); + var $parent = 0; + var $root_struct_name = array(); + var $header_struct_name = array(); + var $curent_root_struct_name = ''; + var $root_struct = array(); + var $header_struct = array(); + var $curent_root_struct = 0; + var $references = array(); + var $need_references = array(); + + /** + * Used to handle non-root elements before root body element. + * + * @var integer + */ + var $bodyDepth; + + /** + * Constructor. + * + * @param string $xml XML content. + * @param string $encoding Character set encoding, defaults to 'UTF-8'. + * @param array $attachments List of attachments. + */ + function SOAP_Parser($xml, $encoding = SOAP_DEFAULT_ENCODING, + $attachments = null) + { + parent::SOAP_Base('Parser'); + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + + $this->attachments = $attachments; + + // Check the XML tag for encoding. + if (preg_match('/<\?xml[^>]+encoding\s*?=\s*?(\'([^\']*)\'|"([^"]*)")[^>]*?[\?]>/', $xml, $m)) { + $encoding = strtoupper($m[2] ? $m[2] : $m[3]); + } + + // Determine where in the message we are (envelope, header, body, + // method). Check whether content has been read. + if (!empty($xml)) { + // Prepare the XML parser. + $parser = xml_parser_create($encoding); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($parser, $this); + xml_set_element_handler($parser, '_startElement', '_endElement'); + xml_set_character_data_handler($parser, '_characterData'); + + // Some lame SOAP implementations add nul bytes at the end of the + // SOAP stream, and expat chokes on that. + if ($xml[strlen($xml) - 1] == 0) { + $xml = trim($xml); + } + + // Parse the XML file. + if (!xml_parse($parser, $xml, true)) { + $err = sprintf('XML error on line %d col %d byte %d %s', + xml_get_current_line_number($parser), + xml_get_current_column_number($parser), + xml_get_current_byte_index($parser), + xml_error_string(xml_get_error_code($parser))); + $this->_raiseSoapFault($err, htmlspecialchars($xml)); + } + xml_parser_free($parser); + } + } + + /** + * Returns an array of responses. + * + * After parsing a SOAP message, use this to get the response. + * + * @return array + */ + function getResponse() + { + if (!empty($this->root_struct[0])) { + return $this->_buildResponse($this->root_struct[0]); + } else { + return $this->_raiseSoapFault('Cannot build response'); + } + } + + /** + * Returns an array of header responses. + * + * After parsing a SOAP message, use this to get the response. + * + * @return array + */ + function getHeaders() + { + if (!empty($this->header_struct[0])) { + return $this->_buildResponse($this->header_struct[0]); + } else { + // We don't fault if there are no headers; that can be handled by + // the application if necessary. + return null; + } + } + + /** + * Recurses to build a multi dimensional array. + * + * @see _buildResponse() + */ + function _domulti($d, &$ar, &$r, &$v, $ad = 0) + { + if ($d) { + $this->_domulti($d - 1, $ar, $r[$ar[$ad]], $v, $ad + 1); + } else { + $r = $v; + } + } + + /** + * Loops through the message, building response structures. + * + * @param integer $pos Position. + * + * @return SOAP_Value + */ + function _buildResponse($pos) + { + $response = null; + + if (isset($this->message[$pos]['children'])) { + $children = explode('|', $this->message[$pos]['children']); + foreach ($children as $c => $child_pos) { + if ($this->message[$child_pos]['type'] != null) { + $response[] = $this->_buildResponse($child_pos); + } + } + if (isset($this->message[$pos]['arraySize'])) { + $ardepth = count($this->message[$pos]['arraySize']); + if ($ardepth > 1) { + $ar = array_pad(array(), $ardepth, 0); + if (isset($this->message[$pos]['arrayOffset'])) { + for ($i = 0; $i < $ardepth; $i++) { + $ar[$i] += $this->message[$pos]['arrayOffset'][$i]; + } + } + $elc = count($response); + for ($i = 0; $i < $elc; $i++) { + // Recurse to build a multi dimensional array. + $this->_domulti($ardepth, $ar, $newresp, $response[$i]); + + // Increment our array pointers. + $ad = $ardepth - 1; + $ar[$ad]++; + while ($ad > 0 && + $ar[$ad] >= $this->message[$pos]['arraySize'][$ad]) { + $ar[$ad] = 0; + $ad--; + $ar[$ad]++; + } + } + $response = $newresp; + } elseif (isset($this->message[$pos]['arrayOffset']) && + $this->message[$pos]['arrayOffset'][0] > 0) { + // Check for padding. + $pad = $this->message[$pos]['arrayOffset'][0] + count($response) * -1; + $response = array_pad($response, $pad, null); + } + } + } + + // Build attributes. + $attrs = array(); + foreach ($this->message[$pos]['attrs'] as $atn => $atv) { + if (!strstr($atn, 'xmlns') && !strpos($atn, ':')) { + $attrs[$atn] = $atv; + } + } + + // Add current node's value. + if ($response) { + $nqn = new QName($this->message[$pos]['name'], + $this->message[$pos]['namespace']); + $tqn = new QName($this->message[$pos]['type'], + $this->message[$pos]['type_namespace']); + $response = new SOAP_Value($nqn->fqn(), + $tqn->fqn(), + $response, + $attrs); + if (isset($this->message[$pos]['arrayType'])) { + $response->arrayType = $this->message[$pos]['arrayType']; + } + } else { + $nqn = new QName($this->message[$pos]['name'], + $this->message[$pos]['namespace']); + $tqn = new QName($this->message[$pos]['type'], + $this->message[$pos]['type_namespace']); + // Check if value is an empty array + if ($tqn->name == 'Array') { + $response =& new SOAP_Value($nqn->fqn(), $tqn->fqn(), + array(), $attrs); + } else { + $response = new SOAP_Value($nqn->fqn(), + $tqn->fqn(), + $this->message[$pos]['cdata'], + $attrs); + } + } + + // Handle header attribute that we need. + if (array_key_exists('actor', $this->message[$pos])) { + $response->actor = $this->message[$pos]['actor']; + } + if (array_key_exists('mustUnderstand', $this->message[$pos])) { + $response->mustunderstand = $this->message[$pos]['mustUnderstand']; + } + return $response; + } + + /** + * Start element handler used with the XML parser. + */ + function _startElement($parser, $name, $attrs) + { + // Position in a total number of elements, starting from 0. + // Update class level position. + $pos = $this->position++; + + // And set mine. + $this->message[$pos] = array( + 'type' => '', + 'type_namespace' => '', + 'cdata' => '', + 'pos' => $pos, + 'id' => ''); + + // Parent/child/depth determinations. + + // depth = How many levels removed from root? + // Set mine as current global depth and increment global depth value. + $this->message[$pos]['depth'] = $this->depth++; + + // Else add self as child to whoever the current parent is. + if ($pos != 0) { + if (isset($this->message[$this->parent]['children'])) { + $this->message[$this->parent]['children'] .= '|' . $pos; + } else { + $this->message[$this->parent]['children'] = $pos; + } + } + + // Set my parent. + $this->message[$pos]['parent'] = $this->parent; + + // Set self as current value for this depth. + $this->depth_array[$this->depth] = $pos; + // Set self as current parent. + $this->parent = $pos; + $qname = new QName($name); + // Set status. + if (strcasecmp('envelope', $qname->name) == 0) { + $this->status = 'envelope'; + } elseif (strcasecmp('header', $qname->name) == 0) { + $this->status = 'header'; + $this->header_struct_name[] = $this->curent_root_struct_name = $qname->name; + $this->header_struct[] = $this->curent_root_struct = $pos; + $this->message[$pos]['type'] = 'Struct'; + } elseif (strcasecmp('body', $qname->name) == 0) { + $this->status = 'body'; + $this->bodyDepth = $this->depth; + + // Set method + } elseif ($this->status == 'body') { + // Is this element allowed to be a root? + // TODO: this needs to be optimized, we loop through $attrs twice + // now. + $can_root = $this->depth == $this->bodyDepth + 1; + if ($can_root) { + foreach ($attrs as $key => $value) { + if (stristr($key, ':root') && !$value) { + $can_root = false; + } + } + } + + if ($can_root) { + $this->status = 'method'; + $this->root_struct_name[] = $this->curent_root_struct_name = $qname->name; + $this->root_struct[] = $this->curent_root_struct = $pos; + $this->message[$pos]['type'] = 'Struct'; + } + } + + // Set my status. + $this->message[$pos]['status'] = $this->status; + + // Set name. + $this->message[$pos]['name'] = htmlspecialchars($qname->name); + + // Set attributes. + $this->message[$pos]['attrs'] = $attrs; + + // Loop through attributes, logging ns and type declarations. + foreach ($attrs as $key => $value) { + // If ns declarations, add to class level array of valid + // namespaces. + $kqn = new QName($key); + if ($kqn->ns == 'xmlns') { + $prefix = $kqn->name; + + if (in_array($value, $this->_XMLSchema)) { + $this->_setSchemaVersion($value); + } + + $this->_namespaces[$value] = $prefix; + + // Set method namespace. + } elseif ($key == 'xmlns') { + $qname->ns = $this->_getNamespacePrefix($value); + $qname->namespace = $value; + } elseif ($kqn->name == 'actor') { + $this->message[$pos]['actor'] = $value; + } elseif ($kqn->name == 'mustUnderstand') { + $this->message[$pos]['mustUnderstand'] = $value; + + // If it's a type declaration, set type. + } elseif ($kqn->name == 'type') { + $vqn = new QName($value); + $this->message[$pos]['type'] = $vqn->name; + $this->message[$pos]['type_namespace'] = $this->_getNamespaceForPrefix($vqn->ns); + + // Should do something here with the namespace of specified + // type? + + } elseif ($kqn->name == 'arrayType') { + $vqn = new QName($value); + $this->message[$pos]['type'] = 'Array'; + if (isset($vqn->arraySize)) { + $this->message[$pos]['arraySize'] = $vqn->arraySize; + } + $this->message[$pos]['arrayType'] = $vqn->name; + + } elseif ($kqn->name == 'offset') { + $this->message[$pos]['arrayOffset'] = split(',', substr($value, 1, strlen($value) - 2)); + + } elseif ($kqn->name == 'id') { + // Save id to reference array. + $this->references[$value] = $pos; + $this->message[$pos]['id'] = $value; + + } elseif ($kqn->name == 'href') { + if ($value[0] == '#') { + $ref = substr($value, 1); + if (isset($this->references[$ref])) { + // cdata, type, inval. + $ref_pos = $this->references[$ref]; + $this->message[$pos]['children'] = &$this->message[$ref_pos]['children']; + $this->message[$pos]['cdata'] = &$this->message[$ref_pos]['cdata']; + $this->message[$pos]['type'] = &$this->message[$ref_pos]['type']; + $this->message[$pos]['arraySize'] = &$this->message[$ref_pos]['arraySize']; + $this->message[$pos]['arrayType'] = &$this->message[$ref_pos]['arrayType']; + } else { + // Reverse reference, store in 'need reference'. + if (!isset($this->need_references[$ref])) { + $this->need_references[$ref] = array(); + } + $this->need_references[$ref][] = $pos; + } + } elseif (isset($this->attachments[$value])) { + $this->message[$pos]['cdata'] = $this->attachments[$value]; + } + } + } + // See if namespace is defined in tag. + if (isset($attrs['xmlns:' . $qname->ns])) { + $namespace = $attrs['xmlns:' . $qname->ns]; + } elseif ($qname->ns && !$qname->namespace) { + $namespace = $this->_getNamespaceForPrefix($qname->ns); + } else { + // Get namespace. + $namespace = $qname->namespace ? $qname->namespace : $this->default_namespace; + } + $this->message[$pos]['namespace'] = $namespace; + $this->default_namespace = $namespace; + } + + /** + * End element handler used with the XML parser. + */ + function _endElement($parser, $name) + { + // Position of current element is equal to the last value left in + // depth_array for my depth. + $pos = $this->depth_array[$this->depth]; + + // Bring depth down a notch. + $this->depth--; + $qname = new QName($name); + + // Get type if not explicitly declared in an xsi:type attribute. + // TODO: check on integrating WSDL validation here. + if ($this->message[$pos]['type'] == '') { + if (isset($this->message[$pos]['children'])) { + /* this is slow, need to look at some faster method + $children = explode('|', $this->message[$pos]['children']); + if (count($children) > 2 && + $this->message[$children[1]]['name'] == $this->message[$children[2]]['name']) { + $this->message[$pos]['type'] = 'Array'; + } else { + $this->message[$pos]['type'] = 'Struct'; + }*/ + $this->message[$pos]['type'] = 'Struct'; + } else { + $parent = $this->message[$pos]['parent']; + if ($this->message[$parent]['type'] == 'Array' && + isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['type'] = $this->message[$parent]['arrayType']; + } else { + $this->message[$pos]['type'] = 'string'; + } + } + } + + // If tag we are currently closing is the method wrapper. + if ($pos == $this->curent_root_struct) { + $this->status = 'body'; + } elseif ($qname->name == 'Body' || $qname->name == 'Header') { + $this->status = 'envelope'; + } + + // Set parent back to my parent. + $this->parent = $this->message[$pos]['parent']; + + // Handle any reverse references now. + $idref = $this->message[$pos]['id']; + + if ($idref != '' && isset($this->need_references[$idref])) { + foreach ($this->need_references[$idref] as $ref_pos) { + // XXX is this stuff there already? + $this->message[$ref_pos]['children'] = &$this->message[$pos]['children']; + $this->message[$ref_pos]['cdata'] = &$this->message[$pos]['cdata']; + $this->message[$ref_pos]['type'] = &$this->message[$pos]['type']; + $this->message[$ref_pos]['arraySize'] = &$this->message[$pos]['arraySize']; + $this->message[$ref_pos]['arrayType'] = &$this->message[$pos]['arrayType']; + } + } + } + + /** + * Element content handler used with the XML parser. + */ + function _characterData($parser, $data) + { + $pos = $this->depth_array[$this->depth]; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } else { + $this->message[$pos]['cdata'] = $data; + } + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Server.php b/gulliver/thirdparty/pear/SOAP/Server.php new file mode 100644 index 000000000..bfdc837ac --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Server.php @@ -0,0 +1,816 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; +require_once 'SOAP/Fault.php'; +require_once 'SOAP/Parser.php'; +require_once 'SOAP/Value.php'; +require_once 'SOAP/WSDL.php'; + +/** + * SOAP Server Class + * + * Originaly based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Dietrich Ayala Original Author + */ +class SOAP_Server extends SOAP_Base +{ + /** + * + * @var array + */ + var $dispatch_map = array(); // create empty dispatch map + var $dispatch_objects = array(); + var $soapobject = null; + var $call_methodname = null; + var $callHandler = null; + var $callValidation = true; + + /** + * A list of headers that are going to be sent back to the client. + * + * @var array + */ + var $headers = array(); + + /** + * + * @var string + */ + var $request = ''; + + /** + * + * @var string XML-Encoding + */ + var $xml_encoding = SOAP_DEFAULT_ENCODING; + var $response_encoding = 'UTF-8'; + + var $result = 'successful'; // for logging interop results to db + + var $endpoint = ''; // the uri to ME! + + var $service = ''; //soapaction header + var $method_namespace = null; + + /** + * Options. + * + * @var array + */ + var $_options = array('use' => 'encoded', + 'style' => 'rpc', + 'parameters' => 0, + 'http_status_success' => '200 OK', + 'http_status_fault' => '500 SOAP Fault'); + + function SOAP_Server($options = null) + { + ini_set('track_errors', 1); + parent::SOAP_Base('Server'); + + if (is_array($options)) { + if (isset($options['use'])) { + $this->_options['use'] = $options['use']; + } + if (isset($options['style'])) { + $this->_options['style'] = $options['style']; + } + if (isset($options['parameters'])) { + $this->_options['parameters'] = $options['parameters']; + } + } + // assume we encode with section 5 + $this->_section5 = true; + if ($this->_options['use'] == 'literal') { + $this->_section5 = false; + } + } + + /** + * Error handler for errors that happen in proxied methods. + * + * To always return a valid SOAP response even on errors that don't happen + * in this code, the errors are catched, transformed to a SOAP fault and + * immediately sent to the client. + * + * @see http://www.php.net/set_error_handler + */ + function _errorHandler($errno, $errmsg, $filename, $linenum) + { + /* The error handler should ignore '0' errors, eg. hidden by @ - see + * the set_error_handler manual page. (thanks to Alan Knowles). */ + if (!$errno || !error_reporting() || $errno == E_NOTICE || + (defined('E_STRICT') && $errno == constant('E_STRICT'))) { + return false; + } + + $this->fault = new SOAP_Fault($errmsg, 'Server', 'PHP', "Errno: $errno\nFilename: $filename\nLineno: $linenum\n"); + + $this->_sendResponse(); + exit; + } + + function _getContentEncoding($content_type) + { + /* Get the character encoding of the incoming request treat incoming + * data as UTF-8 if no encoding set. */ + $this->xml_encoding = 'UTF-8'; + if (strpos($content_type, '=')) { + $enc = strtoupper(str_replace('"', '', substr(strstr($content_type, '='), 1))); + if (!in_array($enc, $this->_encodings)) { + return false; + } + $this->xml_encoding = $enc; + } + + return true; + } + + + /** + * Parses the request and posts or returns the response. + * + * @param string $data The SOAP request data. + * @param string $endpoint The service endpoint. Determined automatically + * if left empty. + * @param boolean $test + * @param boolean $return Whether to return the SOAP response data + * instead of sending it to the client. + */ + function service($data, $endpoint = '', $test = false, $return = false) + { + $response = null; + $attachments = array(); + $useEncoding = 'DIME'; + + /* Figure out our endpoint. */ + $this->endpoint = $endpoint; + if (!$test && !$this->endpoint) { + /* We'll try to build our endpoint. */ + $this->endpoint = 'http://' . $_SERVER['SERVER_NAME']; + if ($_SERVER['SERVER_PORT']) { + $this->endpoint .= ':' . $_SERVER['SERVER_PORT']; + } + $this->endpoint .= $_SERVER['SCRIPT_NAME']; + } + + /* Get the character encoding of the incoming request treat incoming + * data as UTF-8 if no encoding set. */ + if (isset($_SERVER['CONTENT_TYPE'])) { + if (strcasecmp($_SERVER['CONTENT_TYPE'], 'application/dime') == 0) { + $this->_decodeDIMEMessage($data, $headers, $attachments); + $useEncoding = 'DIME'; + } elseif (stristr($_SERVER['CONTENT_TYPE'], 'multipart/related')) { + /* This is a mime message, let's decode it. */ + $data = 'Content-Type: ' . + stripslashes($_SERVER['CONTENT_TYPE']) . + "\r\n\r\n" . $data; + $this->_decodeMimeMessage($data, $headers, $attachments); + $useEncoding = 'Mime'; + } + if (!isset($headers['content-type'])) { + $headers['content-type'] = stripslashes($_SERVER['CONTENT_TYPE']); + } + if (!$this->fault && + !$this->_getContentEncoding($headers['content-type'])) { + $this->xml_encoding = SOAP_DEFAULT_ENCODING; + /* Found encoding we don't understand; return a fault. */ + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8', '', '', 'Server'); + } + } + + /* If this is not a POST with Content-Type text/xml, try to return a + * WSDL file. */ + if (!$this->fault && !$test && + ($_SERVER['REQUEST_METHOD'] != 'POST' || + strncmp($headers['content-type'], 'text/xml', 8) != 0)) { + /* This is not possibly a valid SOAP request, try to return a WSDL + * file. */ + $this->_raiseSoapFault('Invalid SOAP request, must be POST with content-type: text/xml, got: ' . (isset($headers['content-type']) ? $headers['content-type'] : 'Nothing!'), '', '', 'Server'); + } + + if (!$this->fault) { + /* $response is a SOAP_Msg object. */ + $soap_msg = $this->parseRequest($data, $attachments); + + /* Handle Mime or DIME encoding. */ + /* TODO: DIME decoding should move to the transport, do it here + * for now and for ease of getting it done. */ + if (count($this->_attachments)) { + if ($useEncoding == 'Mime') { + $soap_msg = $this->_makeMimeMessage($soap_msg); + } else { + // default is dime + $soap_msg = $this->_makeDIMEMessage($soap_msg); + $this->headers['Content-Type'] = 'application/dime'; + } + if (PEAR::isError($soap_msg)) { + return $this->_raiseSoapFault($soap_msg); + } + } + + if (is_array($soap_msg)) { + $response = $soap_msg['body']; + if (count($soap_msg['headers'])) { + $this->headers = $soap_msg['headers']; + } + } else { + $response = $soap_msg; + } + } + + if ($return) { + if ($this->fault) { + $response = $this->fault->message(); + } + return $response; + } + + $this->_sendResponse($response); + } + + /** + * Sends the final HTTP response to the client, including the HTTP header + * and the HTTP body. + * + * If an error happened, it returns a SOAP fault instead of the response + * body. + * + * @param string $response The response body. + */ + function _sendResponse($response = '') + { + /* Make distinction between the different SAPIs, running PHP as CGI or + * as a module. */ + if (stristr(php_sapi_name(), 'cgi') === 0) { + $hdrs_type = 'Status:'; + } else { + $hdrs_type = 'HTTP/1.1'; + } + + if ($this->fault) { + $hdrs = $hdrs_type . ' ' . $this->_options['http_status_fault'] . "\r\n"; + $response = $this->fault->message($this->response_encoding); + } else { + $hdrs = $hdrs_type . ' ' . $this->_options['http_status_success'] . "\r\n"; + } + header($hdrs); + + $this->headers['Server'] = SOAP_LIBRARY_NAME; + if (!isset($this->headers['Content-Type'])) { + $this->headers['Content-Type'] = 'text/xml; charset=' . + $this->response_encoding; + } + $this->headers['Content-Length'] = strlen($response); + + foreach ($this->headers as $k => $v) { + header("$k: $v"); + $hdrs .= "$k: $v\r\n"; + } + + $this->response = $hdrs . "\r\n" . $response; + print $response; + } + + function &callMethod($methodname, &$args) + { + if ($this->callHandler) { + $ret = @call_user_func_array($this->callHandler, array($methodname, $args)); + return $ret; + } + + set_error_handler(array($this, '_errorHandler')); + + if ($args) { + /* Call method with parameters. */ + if (isset($this->soapobject) && is_object($this->soapobject)) { + $ret = call_user_func_array(array(&$this->soapobject, $methodname), $args); + } else { + $ret = call_user_func_array($methodname, $args); + } + } else { + /* Call method withour parameters. */ + if (is_object($this->soapobject)) { + $ret = call_user_func(array(&$this->soapobject, $methodname)); + } else { + $ret = call_user_func($methodname); + } + } + + restore_error_handler(); + + return $ret; + } + + /** + * Creates SOAP_Value objects with return values from method. + * Uses method signature to determine type. + * + * @param mixed $method_response The result(s). + * @param array|string $type The type(s) of the return value(s). + * @param string $return_name The name of the return value. + * @param string $namespace The namespace of the return value. + * + * @return array List of SOAP_Value objects. + */ + function buildResult(&$method_response, &$return_type, + $return_name = 'return', $namespace = '') + { + if (is_a($method_response, 'SOAP_Value')) { + $return_val = array($method_response); + } else { + if (is_array($return_type) && is_array($method_response)) { + $i = 0; + + foreach ($return_type as $key => $type) { + if (is_numeric($key)) { + $key = 'item'; + } + if (is_a($method_response[$i], 'SOAP_Value')) { + $return_val[] =& $method_response[$i++]; + } else { + $qn = new QName($key, $namespace); + $return_val[] = new SOAP_Value($qn->fqn(), $type, $method_response[$i++]); + } + } + } else { + if (is_array($return_type)) { + $keys = array_keys($return_type); + if (!is_numeric($keys[0])) { + $return_name = $keys[0]; + } + $values = array_values($return_type); + $return_type = $values[0]; + } + $qn = new QName($return_name, $namespace); + $return_val = array(new SOAP_Value($qn->fqn(), $return_type, $method_response)); + } + } + return $return_val; + } + + function parseRequest($data = '', $attachments = null) + { + /* Parse response, get SOAP_Parser object. */ + $parser =& new SOAP_Parser($data, $this->xml_encoding, $attachments); + /* If fault occurred during message parsing. */ + if ($parser->fault) { + $this->fault = $parser->fault; + return null; + } + + /* Handle message headers. */ + $request_headers = $parser->getHeaders(); + $header_results = array(); + + if ($request_headers) { + if (!is_a($request_headers, 'SOAP_Value')) { + $this->_raiseSoapFault('Parser did not return SOAP_Value object: ' . $request_headers, '', '', 'Server'); + return null; + } + if ($request_headers->value) { + /* Handle headers now. */ + foreach ($request_headers->value as $header_val) { + $f_exists = $this->validateMethod($header_val->name, $header_val->namespace); + + /* TODO: this does not take into account message routing + * yet. */ + $myactor = !$header_val->actor || + $header_val->actor == 'http://schemas.xmlsoap.org/soap/actor/next' || + $header_val->actor == $this->endpoint; + + if (!$f_exists && $header_val->mustunderstand && $myactor) { + $this->_raiseSoapFault('I don\'t understand header ' . $header_val->name, '', '', 'MustUnderstand'); + return null; + } + + /* We only handle the header if it's for us. */ + $isok = $f_exists && $myactor; + + if ($isok) { + /* Call our header now! */ + $header_method = $header_val->name; + $header_data = array($this->_decode($header_val)); + /* If there are parameters to pass. */ + $hr =& $this->callMethod($header_method, $header_data); + if (PEAR::isError($hr)) { + $this->_raiseSoapFault($hr); + return null; + } + $results = $this->buildResult($hr, $this->return_type, $header_method, $header_val->namespace); + $header_results[] = $results[0]; + } + } + } + } + + /* Handle the method call. */ + /* Evaluate message, getting back a SOAP_Value object. */ + $this->call_methodname = $this->methodname = $parser->root_struct_name[0]; + + /* Figure out the method namespace. */ + $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace']; + + if ($this->_wsdl) { + $this->_setSchemaVersion($this->_wsdl->xsd); + $dataHandler = $this->_wsdl->getDataHandler($this->methodname, $this->method_namespace); + if ($dataHandler) + $this->call_methodname = $this->methodname = $dataHandler; + + $this->_portName = $this->_wsdl->getPortName($this->methodname); + if (PEAR::isError($this->_portName)) { + $this->_raiseSoapFault($this->_portName); + return null; + } + $opData = $this->_wsdl->getOperationData($this->_portName, $this->methodname); + if (PEAR::isError($opData)) { + $this->_raiseSoapFault($opData); + return null; + } + $this->_options['style'] = $opData['style']; + $this->_options['use'] = $opData['output']['use']; + $this->_options['parameters'] = $opData['parameters']; + } + + /* Does method exist? */ + if (!$this->methodname || + !$this->validateMethod($this->methodname, $this->method_namespace)) { + $this->_raiseSoapFault('method "' . $this->method_namespace . $this->methodname . '" not defined in service', '', '', 'Server'); + return null; + } + + if (!$request_val = $parser->getResponse()) { + return null; + } + if (!is_a($request_val, 'SOAP_Value')) { + $this->_raiseSoapFault('Parser did not return SOAP_Value object: ' . $request_val, '', '', 'Server'); + return null; + } + + /* Verify that SOAP_Value objects in request match the methods + * signature. */ + if (!$this->verifyMethod($request_val)) { + /* verifyMethod() creates the fault. */ + return null; + } + + /* Need to set special error detection inside the value class to + * differentiate between no params passed, and an error decoding. */ + $request_data = $this->__decodeRequest($request_val); + if (PEAR::isError($request_data)) { + $this->_raiseSoapFault($request_data); + return null; + } + $method_response =& $this->callMethod($this->call_methodname, $request_data); + if (PEAR::isError($method_response)) { + $this->_raiseSoapFault($method_response); + return null; + } + + if ($this->_options['parameters'] || + !$method_response || + $this->_options['style'] == 'rpc') { + /* Get the method result. */ + if (is_null($method_response)) { + $return_val = null; + } else { + $return_val = $this->buildResult($method_response, $this->return_type); + } + + $qn = new QName($this->methodname . 'Response', $this->method_namespace); + $methodValue = new SOAP_Value($qn->fqn(), 'Struct', $return_val); + } else { + $methodValue =& $method_response; + } + return $this->makeEnvelope($methodValue, $header_results, $this->response_encoding); + } + + function &__decodeRequest($request, $shift = false) + { + if (!$request) { + $decoded = null; + return $decoded; + } + + /* Check for valid response. */ + if (PEAR::isError($request)) { + $fault = &$this->_raiseSoapFault($request); + return $fault; + } else if (!is_a($request, 'SOAP_Value')) { + $fault = &$this->_raiseSoapFault('Invalid data in server::__decodeRequest'); + return $fault; + } + + /* Decode to native php datatype. */ + $requestArray = $this->_decode($request); + /* Fault? */ + if (PEAR::isError($requestArray)) { + $fault = &$this->_raiseSoapFault($requestArray); + return $fault; + } + if (is_object($requestArray) && + get_class($requestArray) == 'stdClass') { + $requestArray = get_object_vars($requestArray); + } elseif ($this->_options['style'] == 'document') { + $requestArray = array($requestArray); + } + if (is_array($requestArray)) { + if (isset($requestArray['faultcode']) || + isset($requestArray['SOAP-ENV:faultcode'])) { + $faultcode = $faultstring = $faultdetail = $faultactor = ''; + foreach ($requestArray as $k => $v) { + if (stristr($k, 'faultcode')) { + $faultcode = $v; + } + if (stristr($k, 'faultstring')) { + $faultstring = $v; + } + if (stristr($k, 'detail')) { + $faultdetail = $v; + } + if (stristr($k, 'faultactor')) { + $faultactor = $v; + } + } + $fault = &$this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); + return $fault; + } + /* Return array of return values. */ + if ($shift && count($requestArray) == 1) { + $decoded = array_shift($requestArray); + return $decoded; + } + return $requestArray; + } + return $requestArray; + } + + function verifyMethod($request) + { + if (!$this->callValidation) { + return true; + } + + $params = $request->value; + + /* Get the dispatch map if one exists. */ + $map = null; + if (array_key_exists($this->methodname, $this->dispatch_map)) { + $map = $this->dispatch_map[$this->methodname]; + } elseif (isset($this->soapobject)) { + if (method_exists($this->soapobject, '__dispatch')) { + $map = $this->soapobject->__dispatch($this->methodname); + } elseif (method_exists($this->soapobject, $this->methodname)) { + /* No map, all public functions are SOAP functions. */ + return true; + } + } + if (!$map) { + $this->_raiseSoapFault('SOAP request specified an unhandled method "' . $this->methodname . '"', '', '', 'Client'); + return false; + } + + /* If we aliased the SOAP method name to a PHP function, change + * call_methodname so we do the right thing. */ + if (array_key_exists('alias', $map) && !empty($map['alias'])) { + $this->call_methodname = $map['alias']; + } + + /* If there are input parameters required. */ + if ($map['in']) { + $this->input_value = count($map['in']); + $this->return_type = false; + if (is_array($map['out'])) { + $this->return_type = count($map['out']) > 1 + ? $map['out'] + : array_shift($map['out']); + } + if (is_array($params)) { + /* Validate the number of parameters. */ + if (count($params) == count($map['in'])) { + /* Make array of param types. */ + foreach ($params as $param) { + $p[] = strtolower($param->type); + } + $sig_t = array_values($map['in']); + /* Validate each param's type. */ + for ($i = 0; $i < count($p); $i++) { + /* If SOAP types do not match, it's still fine if the + * mapped php types match this allows using plain PHP + * variables to work (i.e. stuff like Decimal would + * fail otherwise). We consider this only error if the + * types exist in our type maps, and they differ. */ + if (strcasecmp($sig_t[$i], $p[$i]) != 0 && + isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]]) && + strcasecmp($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]], $this->_typemap[SOAP_XML_SCHEMA_VERSION][$p[$i]]) != 0) { + + $param = $params[$i]; + $this->_raiseSoapFault("SOAP request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? " . (strcasecmp($sig_t[$i], $p[$i])), '', '', 'Client'); + return false; + } + } + return true; + } else { + /* Wrong number of params. */ + $this->_raiseSoapFault('SOAP request contained incorrect number of parameters. method "' . $this->methodname . '" required ' . count($map['in']) . ' and request provided ' . count($params), '', '', 'Client'); + return false; + } + } else { + /* No params. */ + $this->_raiseSoapFault('SOAP request contained incorrect number of parameters. method "' . $this->methodname . '" requires ' . count($map['in']) . ' parameters, and request provided none.', '', '', 'Client'); + return false; + } + } + + /* We'll try it anyway. */ + return true; + } + + function validateMethod($methodname, $namespace = null) + { + unset($this->soapobject); + + if (!$this->callValidation) { + return true; + } + + /* No SOAP access to private functions. */ + if ($methodname[0] == '_') { + return false; + } + + /* if it's in our function list, ok */ + if (array_key_exists($methodname, $this->dispatch_map) && + (!$namespace || + !array_key_exists('namespace', $this->dispatch_map[$methodname]) || + $namespace == $this->dispatch_map[$methodname]['namespace'])) { + if (array_key_exists('namespace', $this->dispatch_map[$methodname])) + $this->method_namespace = $this->dispatch_map[$methodname]['namespace']; + return true; + } + + /* if it's in an object, it's ok */ + if (isset($this->dispatch_objects[$namespace])) { + $c = count($this->dispatch_objects[$namespace]); + for ($i = 0; $i < $c; $i++) { + $obj =& $this->dispatch_objects[$namespace][$i]; + /* If we have a dispatch map, and the function is not in the + * dispatch map, then it is not callable! */ + if (method_exists($obj, '__dispatch')) { + if ($obj->__dispatch($methodname)) { + $this->method_namespace = $namespace; + $this->soapobject =& $obj; + return true; + } + } elseif (method_exists($obj, $methodname)) { + $this->method_namespace = $namespace; + $this->soapobject =& $obj; + return true; + } + } + } + + return false; + } + + function addObjectMap(&$obj, $namespace = null, $service_name = 'Default', + $service_desc = '') + { + if (!$namespace) { + if (isset($obj->namespace)) { + // XXX a bit of backwards compatibility + $namespace = $obj->namespace; + } else { + $this->_raiseSoapFault('No namespace provided for class!', '', '', 'Server'); + return false; + } + } + if (!isset($this->dispatch_objects[$namespace])) { + $this->dispatch_objects[$namespace] = array(); + } + $this->dispatch_objects[$namespace][] =& $obj; + + // Create internal WSDL structures for object + + // XXX Because some internal workings of PEAR::SOAP decide whether to + // do certain things by the presence or absence of _wsdl, we should + // only create a _wsdl structure if we know we can fill it; if + // __dispatch_map or __typedef for the object is missing, we should + // avoid creating it. Later, when we are using PHP 5 introspection, we + // will be able to make the data for all objects without any extra + // information from the developers, and this condition should be + // dropped. + + // XXX Known issue: if imported WSDL (bindWSDL) or another WSDL source + // is used to add _wsdl structure information, then addObjectWSDL is + // used, there is a high possibility of _wsdl data corruption; + // therefore you should avoid using __dispatch_map/__typedef + // definitions AND other WSDL data sources in the same service. We + // exclude classes that don't have __typedefs to allow external WSDL + // files to be used with classes with no internal type definitions + // (the types are defined in the WSDL file). When addObjectWSDL is + // refactored to not cause corruption, this restriction can be + // relaxed. + + // In summary, if you add an object with both a dispatch map and type + // definitions, then previous WSDL file operation and type definitions + // will be overwritten. + if (isset($obj->__dispatch_map) && isset($obj->__typedef)) { + $this->addObjectWSDL($obj, $namespace, $service_name, $service_desc); + } + + return true; + } + + /** + * Adds a method to the dispatch map. + */ + function addToMap($methodname, $in, $out, $namespace = null, $alias = null) + { + if (!$this->callHandler && !function_exists($methodname)) { + $this->_raiseSoapFault('Error mapping function', '', '', 'Server'); + return false; + } + + $this->dispatch_map[$methodname]['in'] = $in; + $this->dispatch_map[$methodname]['out'] = $out; + $this->dispatch_map[$methodname]['alias'] = $alias; + if ($namespace) { + $this->dispatch_map[$methodname]['namespace'] = $namespace; + } + + return true; + } + + function setCallHandler($callHandler, $validation = true) + { + $this->callHandler = $callHandler; + $this->callValidation = $validation; + } + + /** + * @deprecated use bindWSDL from now on + */ + function bind($wsdl_url) + { + $this->bindWSDL($wsdl_url); + } + + /** + * @param string a url to a WSDL resource + * @return void + */ + function bindWSDL($wsdl_url) + { + /* Instantiate WSDL class. */ + $this->_wsdl = new SOAP_WSDL($wsdl_url); + if ($this->_wsdl->fault) { + $this->_raiseSoapFault($this->_wsdl->fault); + } + } + + /** + * @return void + */ + function addObjectWSDL(&$wsdl_obj, $targetNamespace, $service_name, + $service_desc = '') + { + if (!isset($this->_wsdl)) { + $this->_wsdl = new SOAP_WSDL; + } + + $this->_wsdl->parseObject($wsdl_obj, $targetNamespace, $service_name, $service_desc); + + if ($this->_wsdl->fault) { + $this->_raiseSoapFault($this->_wsdl->fault); + } + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Server/Email.php b/gulliver/thirdparty/pear/SOAP/Server/Email.php new file mode 100644 index 000000000..8905f8928 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Server/Email.php @@ -0,0 +1,198 @@ + Port to PEAR and more + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Server.php'; +require_once 'SOAP/Client.php'; +require_once 'SOAP/Transport.php'; +require_once 'Mail/mimeDecode.php'; + +/** + * SOAP Server Class that implements an email SOAP server. + * http://www.pocketsoap.com/specs/smtpbinding/ + * + * This class overrides the default HTTP server, providing the ability to + * parse an email message and execute SOAP calls. This class DOES NOT pop the + * message; the message, complete with headers, must be passed in as a + * parameter to the service function call. + * + * @access public + * @package SOAP + * @author Shane Caraveo + */ +class SOAP_Server_Email extends SOAP_Server { + + var $headers = array(); + + function SOAP_Server_Email($send_response = true) + { + parent::SOAP_Server(); + $this->send_response = $send_response; + } + + /** + * Removes HTTP headers from response. + * + * TODO: use PEAR email classes + * + * @return boolean + * @access private + */ + function _parseEmail(&$data) + { + if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $data, $match)) { + + if (preg_match_all('/^(.*?):\s+(.*)$/m', $match[1], $matches)) { + $hc = count($matches[0]); + for ($i = 0; $i < $hc; $i++) { + $this->headers[strtolower($matches[1][$i])] = trim($matches[2][$i]); + } + } + + if (!stristr($this->headers['content-type'], 'text/xml')) { + $this->_raiseSoapFault('Invalid Content Type', '', '', 'Client'); + return false; + } + + if (strcasecmp($this->headers['content-transfer-encoding'], 'base64')==0) { + /* Unfold lines. */ + $enctext = preg_replace("/[\r|\n]/", '', $match[2]); + $data = base64_decode($enctext); + } else { + $data = $match[2]; + } + + /* If no content, return false. */ + return strlen($this->request) > 0; + } + + $this->_raiseSoapFault('Invalid Email Format', '', '', 'Client'); + + return false; + } + + function client(&$data) + { + $attachments = array(); + + /* If neither matches, we'll just try it anyway. */ + if (stristr($data, 'Content-Type: application/dime')) { + $this->_decodeDIMEMessage($data, $this->headers, $attachments); + } elseif (stristr($data, 'MIME-Version:')) { + /* This is a mime message, let's decode it. */ + $this->_decodeMimeMessage($data, $this->headers, $attachments); + } else { + /* The old fallback, but decodeMimeMessage handles things fine. */ + $this->_parseEmail($data); + } + + /* Get the character encoding of the incoming request treat incoming + * data as UTF-8 if no encoding set. */ + if (!$this->soapfault && + !$this->_getContentEncoding($this->headers['content-type'])) { + $this->xml_encoding = SOAP_DEFAULT_ENCODING; + /* An encoding we don't understand, return a fault. */ + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8', '', '', 'Server'); + } + + if ($this->soapfault) { + return $this->soapfault->getFault(); + } + + $client =& new SOAP_Client(null); + + return $client->parseResponse($data, $this->xml_encoding, $this->attachments); + } + + function service(&$data, $endpoint = '', $send_response = true, + $dump = false) + { + $this->endpoint = $endpoint; + $attachments = array(); + $headers = array(); + + /* If neither matches, we'll just try it anyway. */ + if (stristr($data, 'Content-Type: application/dime')) { + $this->_decodeDIMEMessage($data, $this->headers, $attachments); + $useEncoding = 'DIME'; + } elseif (stristr($data, 'MIME-Version:')) { + /* This is a mime message, let's decode it. */ + $this->_decodeMimeMessage($data, $this->headers, $attachments); + $useEncoding = 'Mime'; + } else { + /* The old fallback, but decodeMimeMessage handles things fine. */ + $this->_parseEmail($data); + } + + /* Get the character encoding of the incoming request treat incoming + * data as UTF-8 if no encoding set. */ + if (!$this->_getContentEncoding($this->headers['content-type'])) { + $this->xml_encoding = SOAP_DEFAULT_ENCODING; + /* An encoding we don't understand, return a fault. */ + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8', '', '', 'Server'); + $response = $this->getFaultMessage(); + } + + if ($this->soapfault) { + $response = $this->soapfault->message(); + } else { + $soap_msg = $this->parseRequest($data,$attachments); + + /* Handle Mime or DIME encoding. */ + /* TODO: DIME Encoding should move to the transport, do it here + * for now and for ease of getting it done. */ + if (count($this->_attachments)) { + if ($useEncoding == 'Mime') { + $soap_msg = $this->_makeMimeMessage($soap_msg); + } else { + /* Default is DIME. */ + $soap_msg = $this->_makeDIMEMessage($soap_msg); + $soap_msg['headers']['Content-Type'] = 'application/dime'; + } + if (PEAR::isError($soap_msg)) { + return $this->raiseSoapFault($soap_msg); + } + } + + if (is_array($soap_msg)) { + $response = $soap_msg['body']; + if (count($soap_msg['headers'])) { + $headers = $soap_msg['headers']; + } + } else { + $response = $soap_msg; + } + } + + if ($this->send_response) { + if ($dump) { + print $response; + } else { + $from = array_key_exists('reply-to', $this->headers) ? $this->headers['reply-to'] : $this->headers['from']; + + $soap_transport =& SOAP_Transport::getTransport('mailto:' . $from, $this->response_encoding); + $from = $this->endpoint ? $this->endpoint : $this->headers['to']; + $headers['In-Reply-To'] = $this->headers['message-id']; + $options = array('from' => $from, 'subject' => $this->headers['subject'], 'headers' => $headers); + $soap_transport->send($response, $options); + } + } + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Server/Email_Gateway.php b/gulliver/thirdparty/pear/SOAP/Server/Email_Gateway.php new file mode 100644 index 000000000..81ddbf1ce --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Server/Email_Gateway.php @@ -0,0 +1,138 @@ + Port to PEAR and more + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Server/Email.php'; +require_once 'SOAP/Transport.php'; + +/** + * SOAP Server Class that implements an email SOAP server. + * http://www.pocketsoap.com/specs/smtpbinding/ + * + * This class overrides the default HTTP server, providing the ability to + * parse an email message and execute soap calls. This class DOES NOT pop the + * message; the message, complete with headers, must be passed in as a + * parameter to the service function call. + * + * This class calls a provided HTTP SOAP server, forwarding the email request, + * then sending the HTTP response out as an email. + * + * @access public + * @package SOAP + * @author Shane Caraveo + */ +class SOAP_Server_Email_Gateway extends SOAP_Server_Email { + + var $gateway = null; + var $dump = false; + + function SOAP_Server_Email_Gateway($gateway = '', $send_response = true, + $dump = false) + { + parent::SOAP_Server(); + $this->send_response = $send_response; + $this->gateway = $gateway; + $this->dump = $dump; + } + + function service(&$data, $gateway = '', $endpoint = '', + $send_response = true, $dump = false) + { + $this->endpoint = $endpoint; + $response = ''; + $useEncoding = 'Mime'; + $options = array(); + if (!$gateway) { + $gateway = $this->gateway; + } + + /* We have a full set of headers, need to find the first blank + * line. */ + $this->_parseEmail($data); + if ($this->fault) { + $response = $this->fault->message(); + } + if ($this->headers['content-type'] == 'application/dime') + $useEncoding = 'DIME'; + + /* Call the HTTP Server. */ + if (!$response) { + $soap_transport =& SOAP_Transport::getTransport($gateway, $this->xml_encoding); + if ($soap_transport->fault) { + $response = $soap_transport->fault->message(); + } + } + + /* Send the message. */ + if (!$response) { + $options['soapaction'] = $this->headers['soapaction']; + $options['headers']['Content-Type'] = $this->headers['content-type']; + + $response = $soap_transport->send($data, $options); + if (isset($this->headers['mime-version'])) + $options['headers']['MIME-Version'] = $this->headers['mime-version']; + + if ($soap_transport->fault) { + $response = $soap_transport->fault->message(); + } else { + foreach ($soap_transport->transport->attachments as $cid => $body) { + $this->attachments[] = array('body' => $body, 'cid' => $cid, 'encoding' => 'base64'); + } + if (count($this->_attachments)) { + if ($useEncoding == 'Mime') { + $soap_msg = $this->_makeMimeMessage($response); + $options['headers']['MIME-Version'] = '1.0'; + } else { + /* Default is DIME. */ + $soap_msg = $this->_makeDIMEMessage($response); + $options['headers']['Content-Type'] = 'application/dime'; + } + if (PEAR::isError($soap_msg)) { + return $this->_raiseSoapFault($soap_msg); + } + if (is_array($soap_msg)) { + $response = $soap_msg['body']; + if (count($soap_msg['headers'])) { + if (isset($options['headers'])) { + $options['headers'] = array_merge($options['headers'], $soap_msg['headers']); + } else { + $options['headers'] = $soap_msg['headers']; + } + } + } + } + } + } + + if ($this->send_response) { + if ($this->dump || $dump) { + print $response; + } else { + $from = array_key_exists('reply-to', $this->headers) ? $this->headers['reply-to'] : $this->headers['from']; + + $soap_transport =& SOAP_Transport::getTransport('mailto:' . $from, $this->response_encoding); + $from = $this->endpoint ? $this->endpoint : $this->headers['to']; + $headers = array('In-Reply-To' => $this->headers['message-id']); + $options = array('from' => $from, 'subject'=> $this->headers['subject'], 'headers' => $headers); + $soap_transport->send($response, $options); + } + } + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Server/TCP.php b/gulliver/thirdparty/pear/SOAP/Server/TCP.php new file mode 100644 index 000000000..039a62722 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Server/TCP.php @@ -0,0 +1,106 @@ + Port to PEAR and more + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Server.php'; + +/** + * SOAP Server Class that implements a TCP SOAP Server. + * http://www.pocketsoap.com/specs/smtpbinding/ + * + * This class overrides the default HTTP server, providing the ability to + * accept socket connections and execute SOAP calls. + * + * TODO: + * use Net_Socket + * implement some security scheme + * implement support for attachments + * + * @access public + * @package SOAP + * @author Shane Caraveo + */ +class SOAP_Server_TCP extends SOAP_Server { + + var $headers = array(); + var $localaddr; + var $port; + var $listen; + var $reuse; + + function SOAP_Server_TCP($localaddr = '127.0.0.1', $port = 10000, + $listen = 5, $reuse = true) + { + parent::SOAP_Server(); + $this->localaddr = $localaddr; + $this->port = $port; + $this->listen = $listen; + $this->reuse = $reuse; + } + + function run() + { + if (($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0) { + return $this->_raiseSoapFault('socket_create() failed. Reason: ' . socket_strerror($sock)); + } + if ($this->reuse && + !@socket_setopt($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { + return $this->_raiseSoapFault('socket_setopt() failed. Reason: ' . socket_strerror(socket_last_error($sock))); + } + if (($ret = socket_bind($sock, $this->localaddr, $this->port)) < 0) { + return $this->_raiseSoapFault('socket_bind() failed. Reason: ' . socket_strerror($ret)); + } + if (($ret = socket_listen($sock, $this->listen)) < 0) { + return $this->_raiseSoapFault('socket_listen() failed. Reason: ' . socket_strerror($ret)); + } + + while (true) { + $data = null; + if (($msgsock = socket_accept($sock)) < 0) { + $this->_raiseSoapFault('socket_accept() failed. Reason: ' . socket_strerror($msgsock)); + break; + } + while ($buf = socket_read($msgsock, 8192)) { + if (!$buf = trim($buf)) { + continue; + } + $data .= $buf; + } + + if ($data) { + $response = $this->service($data); + /* Write to the socket. */ + if (!socket_write($msgsock, $response, strlen($response))) { + return $this->_raiseSoapFault('Error sending response data reason ' . socket_strerror()); + } + } + + socket_close ($msgsock); + } + + socket_close ($sock); + } + + function service(&$data) + { + /* TODO: we need to handle attachments somehow. */ + return $this->parseRequest($data, $attachments); + } +} diff --git a/gulliver/thirdparty/pear/SOAP/Transport.php b/gulliver/thirdparty/pear/SOAP/Transport.php new file mode 100644 index 000000000..76fffad19 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Transport.php @@ -0,0 +1,151 @@ + + * @author Shane Caraveo + * @author Jan Schneider + * @copyright 2003-2006 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; + +/** + * SOAP Transport Layer + * + * This layer can use different protocols dependant on the endpoint url + * provided. + * + * No knowlege of the SOAP protocol is available at this level. + * No knowlege of the transport protocols is available at this level. + * + * @access public + * @package SOAP + * @author Shane Caraveo + * @author Jan Schneider + */ +class SOAP_Transport extends SOAP_Base +{ + /** + * Connection endpoint URL. + * + * @var string + */ + var $url = ''; + + /** + * Array containing urlparts. + * + * @see parse_url() + * + * @var mixed + */ + var $urlparts = null; + + /** + * Incoming payload. + * + * @var string + */ + var $incoming_payload = ''; + + /** + * Outgoing payload. + * + * @var string + */ + var $outgoing_payload = ''; + + /** + * Request encoding. + * + * @var string + */ + var $encoding = SOAP_DEFAULT_ENCODING; + + /** + * Response encoding. + * + * We assume UTF-8 if no encoding is set. + * + * @var string + */ + var $result_encoding = 'UTF-8'; + + /** + * Decoded attachments from the reponse. + * + * @var array + */ + var $attachments; + + /** + * Request User-Agent. + * + * @var string + */ + var $_userAgent = SOAP_LIBRARY_NAME; + + /** + * Sends and receives SOAP data. + * + * @access public + * @abstract + * + * @param string Outgoing SOAP data. + * @param array Options. + * + * @return string|SOAP_Fault + */ + function send($msg, $options = null) + { + return $this->_raiseSoapFault('SOAP_Transport::send() not implemented.'); + } + + function &getTransport($url, $encoding = SOAP_DEFAULT_ENCODING) + { + $urlparts = @parse_url($url); + + if (!$urlparts['scheme']) { + $fault = SOAP_Base_Object::_raiseSoapFault("Invalid transport URI: $url"); + return $fault; + } + + if (strcasecmp($urlparts['scheme'], 'mailto') == 0) { + $transport_type = 'SMTP'; + } elseif (strcasecmp($urlparts['scheme'], 'https') == 0) { + $transport_type = 'HTTP'; + } else { + /* Handle other transport types */ + $transport_type = strtoupper($urlparts['scheme']); + } + $transport_include = 'SOAP/Transport/' . basename($transport_type) . '.php'; + $res = @include_once($transport_include); + if (!$res) { + $fault = SOAP_Base_Object::_raiseSoapFault("No Transport for {$urlparts['scheme']}"); + return $fault; + } + $transport_class = "SOAP_Transport_$transport_type"; + if (!class_exists($transport_class)) { + $fault = SOAP_Base_Object::_raiseSoapFault("No Transport class $transport_class"); + return $fault; + } + $t =& new $transport_class($url, $encoding); + + return $t; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Transport/HTTP.php b/gulliver/thirdparty/pear/SOAP/Transport/HTTP.php new file mode 100644 index 000000000..39f4bed98 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Transport/HTTP.php @@ -0,0 +1,620 @@ + + * @author Jan Schneider + * @copyright 2003-2006 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +/** + * HTTP Transport class + * + * @package SOAP + * @category Web_Services + */ + +/** + * Needed Classes + */ +require_once 'SOAP/Transport.php'; + +/** + * HTTP Transport for SOAP + * + * @access public + * @package SOAP + * @author Shane Caraveo + * @author Jan Schneider + */ +class SOAP_Transport_HTTP extends SOAP_Transport +{ + /** + * Basic Auth string. + * + * @var array + */ + var $headers = array(); + + /** + * Cookies. + * + * @var array + */ + var $cookies; + + /** + * Connection timeout in seconds. 0 = none. + * + * @var integer + */ + var $timeout = 4; + + /** + * HTTP-Response Content-Type. + */ + var $result_content_type; + + var $result_headers = array(); + + var $result_cookies = array(); + + /** + * SOAP_Transport_HTTP Constructor + * + * @access public + * + * @param string $url HTTP url to SOAP endpoint. + * @param string $encoding Encoding to use. + */ + function SOAP_Transport_HTTP($url, $encoding = SOAP_DEFAULT_ENCODING) + { + parent::SOAP_Base('HTTP'); + $this->urlparts = @parse_url($url); + $this->url = $url; + $this->encoding = $encoding; + } + + /** + * Sends and receives SOAP data. + * + * @access public + * + * @param string Outgoing SOAP data. + * @param array Options. + * + * @return string|SOAP_Fault + */ + function send($msg, $options = array()) + { + $this->fault = null; + + if (!$this->_validateUrl()) { + return $this->fault; + } + + if (isset($options['timeout'])) { + $this->timeout = (int)$options['timeout']; + } + + if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) { + return $this->_sendHTTP($msg, $options); + } elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) { + return $this->_sendHTTPS($msg, $options); + } + + return $this->_raiseSoapFault('Invalid url scheme ' . $this->url); + } + + /** + * Sets data for HTTP authentication, creates authorization header. + * + * @param string $username Username. + * @param string $password Response data, minus HTTP headers. + * + * @access public + */ + function setCredentials($username, $password) + { + $this->headers['Authorization'] = 'Basic ' . base64_encode($username . ':' . $password); + } + + /** + * Adds a cookie. + * + * @access public + * @param string $name Cookie name. + * @param mixed $value Cookie value. + */ + function addCookie($name, $value) + { + $this->cookies[$name] = $value; + } + + /** + * Generates the correct headers for the cookies. + * + * @access private + * + * @param array $options Cookie options. If 'nocookies' is set and true + * the cookies from the last response are added + * automatically. 'cookies' is name-value-hash with + * a list of cookies to add. + * + * @return string The cookie header value. + */ + function _generateCookieHeader($options) + { + $this->cookies = array(); + + if (empty($options['nocookies']) && + isset($this->result_cookies)) { + // Add the cookies we got from the last request. + foreach ($this->result_cookies as $cookie) { + if ($cookie['domain'] == $this->urlparts['host']) { + $this->cookies[$cookie['name']] = $cookie['value']; + } + } + } + + // Add cookies the user wants to set. + if (isset($options['cookies'])) { + foreach ($options['cookies'] as $cookie) { + if ($cookie['domain'] == $this->urlparts['host']) { + $this->cookies[$cookie['name']] = $cookie['value']; + } + } + } + + $cookies = ''; + foreach ($this->cookies as $name => $value) { + if (!empty($cookies)) { + $cookies .= '; '; + } + $cookies .= urlencode($name) . '=' . urlencode($value); + } + + return $cookies; + } + + /** + * Validate url data passed to constructor. + * + * @access private + * @return boolean + */ + function _validateUrl() + { + if (!is_array($this->urlparts) ) { + $this->_raiseSoapFault('Unable to parse URL ' . $this->url); + return false; + } + if (!isset($this->urlparts['host'])) { + $this->_raiseSoapFault('No host in URL ' . $this->url); + return false; + } + if (!isset($this->urlparts['port'])) { + if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) { + $this->urlparts['port'] = 80; + } elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) { + $this->urlparts['port'] = 443; + } + + } + if (isset($this->urlparts['user'])) { + $this->setCredentials(urldecode($this->urlparts['user']), + urldecode($this->urlparts['pass'])); + } + if (!isset($this->urlparts['path']) || !$this->urlparts['path']) { + $this->urlparts['path'] = '/'; + } + + return true; + } + + /** + * Finds out what the encoding is. + * Sets the object property accordingly. + * + * @access private + * @param array $headers Headers. + */ + function _parseEncoding($headers) + { + $h = stristr($headers, 'Content-Type'); + preg_match_all('/^Content-Type:\s*(.*)$/im', $h, $ct, PREG_SET_ORDER); + $n = count($ct); + $ct = $ct[$n - 1]; + + // Strip the string of \r. + $this->result_content_type = str_replace("\r", '', $ct[1]); + + if (preg_match('/(.*?)(?:;\s?charset=)(.*)/i', + $this->result_content_type, + $m)) { + $this->result_content_type = $m[1]; + if (count($m) > 2) { + $enc = strtoupper(str_replace('"', '', $m[2])); + if (in_array($enc, $this->_encodings)) { + $this->result_encoding = $enc; + } + } + } + + // Deal with broken servers that don't set content type on faults. + if (!$this->result_content_type) { + $this->result_content_type = 'text/xml'; + } + } + + /** + * Parses the headers. + * + * @param array $headers The headers. + */ + function _parseHeaders($headers) + { + /* Largely borrowed from HTTP_Request. */ + $this->result_headers = array(); + $headers = split("\r?\n", $headers); + foreach ($headers as $value) { + if (strpos($value,':') === false) { + $this->result_headers[0] = $value; + continue; + } + list($name, $value) = split(':', $value); + $headername = strtolower($name); + $headervalue = trim($value); + $this->result_headers[$headername] = $headervalue; + + if ($headername == 'set-cookie') { + // Parse a SetCookie header to fill _cookies array. + $cookie = array('expires' => null, + 'domain' => $this->urlparts['host'], + 'path' => null, + 'secure' => false); + + if (!strpos($headervalue, ';')) { + // Only a name=value pair. + list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $headervalue)); + $cookie['name'] = urldecode($cookie['name']); + $cookie['value'] = urldecode($cookie['value']); + + } else { + // Some optional parameters are supplied. + $elements = explode(';', $headervalue); + list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $elements[0])); + $cookie['name'] = urldecode($cookie['name']); + $cookie['value'] = urldecode($cookie['value']); + + for ($i = 1; $i < count($elements);$i++) { + list($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); + if ('secure' == $elName) { + $cookie['secure'] = true; + } elseif ('expires' == $elName) { + $cookie['expires'] = str_replace('"', '', $elValue); + } elseif ('path' == $elName OR 'domain' == $elName) { + $cookie[$elName] = urldecode($elValue); + } else { + $cookie[$elName] = $elValue; + } + } + } + $this->result_cookies[] = $cookie; + } + } + } + + /** + * Removes HTTP headers from response. + * + * @return boolean + * @access private + */ + function _parseResponse() + { + if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", + $this->incoming_payload, + $match)) { + $this->response = $match[2]; + // Find the response error, some servers response with 500 for + // SOAP faults. + $this->_parseHeaders($match[1]); + + list(, $code, $msg) = sscanf($this->result_headers[0], '%s %s %s'); + unset($this->result_headers[0]); + + switch($code) { + case 100: // Continue + $this->incoming_payload = $match[2]; + return $this->_parseResponse(); + case 400: + $this->_raiseSoapFault("HTTP Response $code Bad Request"); + return false; + break; + case 401: + $this->_raiseSoapFault("HTTP Response $code Authentication Failed"); + return false; + break; + case 403: + $this->_raiseSoapFault("HTTP Response $code Forbidden"); + return false; + break; + case 404: + $this->_raiseSoapFault("HTTP Response $code Not Found"); + return false; + break; + case 407: + $this->_raiseSoapFault("HTTP Response $code Proxy Authentication Required"); + return false; + break; + case 408: + $this->_raiseSoapFault("HTTP Response $code Request Timeout"); + return false; + break; + case 410: + $this->_raiseSoapFault("HTTP Response $code Gone"); + return false; + break; + default: + if ($code >= 400 && $code < 500) { + $this->_raiseSoapFault("HTTP Response $code Not Found, Server message: $msg"); + return false; + } + } + + $this->_parseEncoding($match[1]); + + if ($this->result_content_type == 'application/dime') { + // XXX quick hack insertion of DIME + if (PEAR::isError($this->_decodeDIMEMessage($this->response, $this->headers, $this->attachments))) { + // _decodeDIMEMessage already raised $this->fault + return false; + } + $this->result_content_type = $this->headers['content-type']; + } elseif (stristr($this->result_content_type, 'multipart/related')) { + $this->response = $this->incoming_payload; + if (PEAR::isError($this->_decodeMimeMessage($this->response, $this->headers, $this->attachments))) { + // _decodeMimeMessage already raised $this->fault + return false; + } + } elseif ($this->result_content_type != 'text/xml') { + $this->_raiseSoapFault($this->response); + return false; + } + // if no content, return false + return strlen($this->response) > 0; + } + $this->_raiseSoapFault('Invalid HTTP Response'); + return false; + } + + /** + * Creates an HTTP request, including headers, for the outgoing request. + * + * @access private + * + * @param string $msg Outgoing SOAP package. + * @param array $options Options. + * + * @return string Outgoing payload. + */ + function _getRequest($msg, $options) + { + $this->headers = array(); + + $action = isset($options['soapaction']) ? $options['soapaction'] : ''; + $fullpath = $this->urlparts['path']; + if (isset($this->urlparts['query'])) { + $fullpath .= '?' . $this->urlparts['query']; + } + if (isset($this->urlparts['fragment'])) { + $fullpath .= '#' . $this->urlparts['fragment']; + } + + if (isset($options['proxy_host'])) { + $fullpath = 'http://' . $this->urlparts['host'] . ':' . + $this->urlparts['port'] . $fullpath; + } + + if (isset($options['proxy_user'])) { + $this->headers['Proxy-Authorization'] = 'Basic ' . + base64_encode($options['proxy_user'] . ':' . + $options['proxy_pass']); + } + + if (isset($options['user'])) { + $this->setCredentials($options['user'], $options['pass']); + } + + $this->headers['User-Agent'] = $this->_userAgent; + $this->headers['Host'] = $this->urlparts['host']; + $this->headers['Content-Type'] = "text/xml; charset=$this->encoding"; + $this->headers['Content-Length'] = strlen($msg); + $this->headers['SOAPAction'] = '"' . $action . '"'; + $this->headers['Connection'] = 'close'; + + if (isset($options['headers'])) { + $this->headers = array_merge($this->headers, $options['headers']); + } + + $cookies = $this->_generateCookieHeader($options); + if ($cookies) { + $this->headers['Cookie'] = $cookies; + } + + $headers = ''; + foreach ($this->headers as $k => $v) { + $headers .= "$k: $v\r\n"; + } + $this->outgoing_payload = "POST $fullpath HTTP/1.0\r\n" . $headers . + "\r\n" . $msg; + + return $this->outgoing_payload; + } + + /** + * Sends the outgoing HTTP request and reads and parses the response. + * + * @access private + * + * @param string $msg Outgoing SOAP package. + * @param array $options Options. + * + * @return string Response data without HTTP headers. + */ + function _sendHTTP($msg, $options) + { + $this->incoming_payload = ''; + $this->_getRequest($msg, $options); + $host = $this->urlparts['host']; + $port = $this->urlparts['port']; + if (isset($options['proxy_host'])) { + $host = $options['proxy_host']; + $port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080; + } + // Send. + if ($this->timeout > 0) { + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); + } else { + $fp = @fsockopen($host, $port, $this->errno, $this->errmsg); + } + if (!$fp) { + return $this->_raiseSoapFault("Connect Error to $host:$port"); + } + if ($this->timeout > 0) { + // some builds of PHP do not support this, silence the warning + @socket_set_timeout($fp, $this->timeout); + } + if (!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + return $this->_raiseSoapFault("Error POSTing Data to $host"); + } + + // get reponse + // XXX time consumer + do { + $data = fread($fp, 4096); + $_tmp_status = socket_get_status($fp); + if ($_tmp_status['timed_out']) { + return $this->_raiseSoapFault("Timed out read from $host"); + } else { + $this->incoming_payload .= $data; + } + } while (!$_tmp_status['eof']); + + fclose($fp); + + if (!$this->_parseResponse()) { + return $this->fault; + } + return $this->response; + } + + /** + * Sends the outgoing HTTPS request and reads and parses the response. + * + * @access private + * + * @param string $msg Outgoing SOAP package. + * @param array $options Options. + * + * @return string Response data without HTTP headers. + */ + function _sendHTTPS($msg, $options) + { + /* Check if the required curl extension is installed. */ + if (!extension_loaded('curl')) { + return $this->_raiseSoapFault('CURL Extension is required for HTTPS'); + } + + $ch = curl_init(); + + if (isset($options['proxy_host'])) { + $port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080; + curl_setopt($ch, CURLOPT_PROXY, + $options['proxy_host'] . ':' . $port); + } + if (isset($options['proxy_user'])) { + curl_setopt($ch, CURLOPT_PROXYUSERPWD, + $options['proxy_user'] . ':' . $options['proxy_pass']); + } + + if (isset($options['user'])) { + curl_setopt($ch, CURLOPT_USERPWD, + $options['user'] . ':' . $options['pass']); + } + + if (!isset($options['soapaction'])) { + $options['soapaction'] = ''; + } + if (!isset($options['headers']['Content-Type'])) { + $options['headers']['Content-Type'] = 'text/xml'; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, + array('Content-Type: ' . $options['headers']['Content-Type'] + . ';charset=' . $this->encoding, + 'SOAPAction: "' . $options['soapaction'] . '"')); + curl_setopt($ch, CURLOPT_USERAGENT, + $this->_userAgent); + + if ($this->timeout) { + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); + } + + curl_setopt($ch, CURLOPT_POSTFIELDS, $msg); + curl_setopt($ch, CURLOPT_URL, $this->url); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_FAILONERROR, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, 1); + if (defined('CURLOPT_HTTP_VERSION')) { + curl_setopt($ch, CURLOPT_HTTP_VERSION, 1); + } + if (!ini_get('safe_mode') && !ini_get('open_basedir')) { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + } + $cookies = $this->_generateCookieHeader($options); + if ($cookies) { + curl_setopt($ch, CURLOPT_COOKIE, $cookies); + } + + if (isset($options['curl'])) { + foreach ($options['curl'] as $key => $val) { + curl_setopt($ch, $key, $val); + } + } + + // Save the outgoing XML. This doesn't quite match _sendHTTP as CURL + // generates the headers, but having the XML is usually the most + // important part for tracing/debugging. + $this->outgoing_payload = $msg; + + $this->incoming_payload = curl_exec($ch); + if (!$this->incoming_payload) { + $m = 'curl_exec error ' . curl_errno($ch) . ' ' . curl_error($ch); + curl_close($ch); + return $this->_raiseSoapFault($m); + } + curl_close($ch); + + if (!$this->_parseResponse()) { + return $this->fault; + } + + return $this->response; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Transport/SMTP.php b/gulliver/thirdparty/pear/SOAP/Transport/SMTP.php new file mode 100644 index 000000000..fc511f1cb --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Transport/SMTP.php @@ -0,0 +1,206 @@ + + * @author Jan Schneider + * @copyright 2003-2006 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Transport.php'; +require_once 'Mail/smtp.php'; + +/** + * SMTP Transport for SOAP + * + * Implements SOAP-SMTP as defined at + * http://www.pocketsoap.com/specs/smtpbinding/ + * + * @todo use PEAR smtp and Mime classes + * + * @access public + * @package SOAP + * @author Shane Caraveo + * @author Jan Schneider + */ +class SOAP_Transport_SMTP extends SOAP_Transport +{ + var $credentials = ''; + var $timeout = 4; // connect timeout + var $host = '127.0.0.1'; + var $port = 25; + var $auth = null; + + /** + * SOAP_Transport_SMTP Constructor + * + * @param string $url mailto: address. + * + * @access public + */ + function SOAP_Transport_SMTP($url, $encoding = 'US-ASCII') + { + parent::SOAP_Base('SMTP'); + $this->encoding = $encoding; + $this->urlparts = @parse_url($url); + $this->url = $url; + } + + /** + * Sends and receives SOAP data. + * + * @access public + * + * @param string Outgoing SOAP data. + * @param array Options. + * + * @return string|SOAP_Fault + */ + function send($msg, $options = array()) + { + $this->fault = null; + $this->incoming_payload = ''; + $this->outgoing_payload = $msg; + if (!$this->_validateUrl()) { + return $this->fault; + } + if (!$options || !isset($options['from'])) { + return $this->_raiseSoapFault('No From: address to send message with'); + } + + if (isset($options['host'])) $this->host = $options['host']; + if (isset($options['port'])) $this->port = $options['port']; + if (isset($options['auth'])) $this->auth = $options['auth']; + if (isset($options['username'])) $this->username = $options['username']; + if (isset($options['password'])) $this->password = $options['password']; + + $headers = array(); + $headers['From'] = $options['from']; + $headers['X-Mailer'] = $this->_userAgent; + $headers['MIME-Version'] = '1.0'; + $headers['Message-ID'] = md5(time()) . '.soap@' . $this->host; + $headers['To'] = $this->urlparts['path']; + if (isset($options['soapaction'])) { + $headers['Soapaction'] = "\"{$options['soapaction']}\""; + } + + if (isset($options['headers'])) + $headers = array_merge($headers, $options['headers']); + + // If the content type is already set, we assume that MIME encoding is + // already done. + if (isset($headers['Content-Type'])) { + $out = $msg; + } else { + // Do a simple inline MIME encoding. + $headers['Content-Disposition'] = 'inline'; + $headers['Content-Type'] = "text/xml; charset=\"$this->encoding\""; + if (isset($options['transfer-encoding'])) { + if (strcasecmp($options['transfer-encoding'], 'quoted-printable') == 0) { + $headers['Content-Transfer-Encoding'] = $options['transfer-encoding']; + $out = $msg; + } elseif (strcasecmp($options['transfer-encoding'],'base64') == 0) { + $headers['Content-Transfer-Encoding'] = 'base64'; + $out = chunk_split(base64_encode($msg), 76, "\n"); + } else { + return $this->_raiseSoapFault("Invalid Transfer Encoding: {$options['transfer-encoding']}"); + } + } else { + // Default to base64. + $headers['Content-Transfer-Encoding'] = 'base64'; + $out = chunk_split(base64_encode($msg)); + } + } + + $headers['Subject'] = isset($options['subject']) ? $options['subject'] : 'SOAP Message'; + + foreach ($headers as $key => $value) { + $header_text .= "$key: $value\n"; + } + $this->outgoing_payload = $header_text . "\r\n" . $this->outgoing_payload; + + $mailer_params = array( + 'host' => $this->host, + 'port' => $this->port, + 'username' => $this->username, + 'password' => $this->password, + 'auth' => $this->auth + ); + $mailer = new Mail_smtp($mailer_params); + $result = $mailer->send($this->urlparts['path'], $headers, $out); + if (!PEAR::isError($result)) { + $val = new SOAP_Value('Message-ID', 'string', $headers['Message-ID']); + } else { + $sval[] = new SOAP_Value('faultcode', 'QName', 'SOAP-ENV:Client'); + $sval[] = new SOAP_Value('faultstring', 'string', "couldn't send SMTP message to {$this->urlparts['path']}"); + $val = new SOAP_Value('Fault', 'Struct', $sval); + } + + $methodValue = new SOAP_Value('Response', 'Struct', array($val)); + + $this->incoming_payload = $this->makeEnvelope($methodValue, + $this->headers, + $this->encoding); + + return $this->incoming_payload; + } + + /** + * Sets data for HTTP authentication, creates Authorization header. + * + * @param string $username Username. + * @param string $password Response data, minus HTTP headers. + * + * @access public + */ + function setCredentials($username, $password) + { + $this->username = $username; + $this->password = $password; + } + + /** + * Validates url data passed to constructor. + * + * @return boolean + * @access private + */ + function _validateUrl() + { + if (!is_array($this->urlparts)) { + $this->_raiseSoapFault("Unable to parse URL $this->url"); + return false; + } + if (!isset($this->urlparts['scheme']) || + strcasecmp($this->urlparts['scheme'], 'mailto') != 0) { + $this->_raiseSoapFault("Unable to parse URL $this->url"); + return false; + } + if (!isset($this->urlparts['path'])) { + $this->_raiseSoapFault("Unable to parse URL $this->url"); + return false; + } + return true; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Transport/TCP.php b/gulliver/thirdparty/pear/SOAP/Transport/TCP.php new file mode 100644 index 000000000..cc386c7b8 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Transport/TCP.php @@ -0,0 +1,153 @@ + + * @author Jan Schneider + * @copyright 2003-2006 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Transport.php'; + +/** + * TCP transport for SOAP. + * + * @todo use Net_Socket; implement some security scheme; implement support + * for attachments + * @access public + * @package SOAP + * @author Shane Hanna + * @author Jan Schneider + */ +class SOAP_Transport_TCP extends SOAP_Transport +{ + /** + * Socket. + */ + var $socket = null; + + /** + * Constructor. + * + * @param string $url HTTP url to SOAP endpoint. + * + * @access public + */ + function SOAP_Transport_TCP($url, $encoding = SOAP_DEFAULT_ENCODING) + { + parent::SOAP_Base_Object('TCP'); + $this->urlparts = @parse_url($url); + $this->url = $url; + $this->encoding = $encoding; + } + + function _socket_ping() + { + // XXX how do we restart after socket_shutdown? + //if (!$this->socket) { + // Create socket resource. + $this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($this->socket < 0) { + return 0; + } + + // Connect. + $result = socket_connect($this->socket, $this->urlparts['host'], + $this->urlparts['port']); + if ($result < 0) { + return 0; + } + //} + return 1; + } + + /** + * Sends and receives SOAP data. + * + * @access public + * + * @param string Outgoing SOAP data. + * @param array Options. + * + * @return string|SOAP_Fault + */ + function send($msg, $options = array()) + { + $this->fault = null; + $this->incoming_payload = ''; + $this->outgoing_payload = $msg; + if (!$this->_validateUrl()) { + return $this->fault; + } + + // Check for TCP scheme. + if (strcasecmp($this->urlparts['scheme'], 'TCP') == 0) { + // Check connection. + if (!$this->_socket_ping()) { + return $this->_raiseSoapFault('Error connecting to ' . $this->url . '; reason: ' . socket_strerror(socket_last_error($this->socket))); + } + + // Write to the socket. + if (!@socket_write($this->socket, $this->outgoing_payload, + strlen($this->outgoing_payload))) { + return $this->_raiseSoapFault('Error sending data to ' . $this->url . '; reason: ' . socket_strerror(socket_last_error($this->socket))); + } + + // Shutdown writing. + if(!socket_shutdown($this->socket, 1)) { + return $this->_raiseSoapFault('Cannot change socket mode to read.'); + } + + // Read everything we can. + while ($buf = @socket_read($this->socket, 1024, PHP_BINARY_READ)) { + $this->incoming_payload .= $buf; + } + + // Return payload or die. + if ($this->incoming_payload) { + return $this->incoming_payload; + } + + return $this->_raiseSoapFault('Error reveiving data from ' . $this->url); + } + + return $this->_raiseSoapFault('Invalid url scheme ' . $this->url); + } + + /** + * Validates the url data passed to the constructor. + * + * @return boolean + * @access private + */ + function _validateUrl() + { + if (!is_array($this->urlparts) ) { + $this->_raiseSoapFault("Unable to parse URL $this->url"); + return false; + } + if (!isset($this->urlparts['host'])) { + $this->_raiseSoapFault("No host in URL $this->url"); + return false; + } + if (!isset($this->urlparts['path']) || !$this->urlparts['path']) { + $this->urlparts['path'] = '/'; + } + + return true; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Type/dateTime.php b/gulliver/thirdparty/pear/SOAP/Type/dateTime.php new file mode 100644 index 000000000..b969da722 --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Type/dateTime.php @@ -0,0 +1,243 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Jan Schneider Maintenance + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +/** + * This class converts from and to unix timestamps and ISO 8601 date/time. + * + * @access public + * @package SOAP + * @author Dietrich Ayala Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Jan Schneider Maintenance + */ +class SOAP_Type_dateTime +{ + var $_iso8601 = + '# 1: centuries & years CCYY- + (-?[0-9]{4})- + # 2: months MM- + ([0-9]{2})- + # 3: days DD + ([0-9]{2}) + # 4: separator T + T + # 5: hours hh: + ([0-9]{2}): + # 6: minutes mm: + ([0-9]{2}): + # 7: seconds ss.ss... + ([0-9]{2})(\.[0-9]*)? + # 8: Z to indicate UTC, -+HH:MM:SS.SS... for local zones + (Z|[+\-][0-9]{4}|[+\-][0-9]{2}:[0-9]{2})?'; + + var $timestamp = -1; + + /** + * Constructor. + * + * @param string|integer $date The timestamp or ISO 8601 formatted + * date and time this object is going to + * represent. + */ + function SOAP_Type_dateTime($date = -1) + { + if ($date == -1) { + $this->timestamp = time(); + } elseif (is_int($date)) { + $this->timestamp = $date; + } else { + $this->timestamp = $this->toUnixtime($date); + } + } + + /** + * Alias of {@link SOAP_Type_dateTime::toUTC}. + */ + function toSOAP($date = NULL) + { + return $this->toUTC($date); + } + + /** + * Converts this object or a timestamp to an ISO 8601 date/time string. + * + * @param integer $timestamp A unix timestamp + * + * @return string An ISO 8601 formatted date/time string. + */ + function toString($timestamp = 0) + { + if (!$timestamp) { + $timestamp = $this->timestamp; + } + if ($timestamp < 0) { + return 0; + } + + //simulate PHP5's P parameter + $zone = date('O', $timestamp); + if (strlen($zone) == 5) { + $zone = substr($zone, 0, 3) . ':' . substr($zone, 3); + } + return date('Y-m-d\TH:i:s', $timestamp) . $zone; + } + + /** + * Splits a date/time into its components. + * + * @param string|integer $datestr A unix timestamp or ISO 8601 date/time + * string. If empty, this object is used. + * + * @return boolean|array An array with the date and time components or + * false on failure. + */ + function _split($datestr) + { + if (!$datestr) { + $datestr = $this->toString(); + } elseif (is_int($datestr)) { + $datestr = $this->toString($datestr); + } + + if (preg_match('/' . $this->_iso8601 . '/x', $datestr, $regs)) { + if (empty($regs[8])) { + $timestamp = strtotime(sprintf('%04d-%02d-%02d %02d:%02d:%02d', + $regs[1], + $regs[2], + $regs[3], + $regs[4], + $regs[5], + $regs[6])); + $regs[8] = date('O', $timestamp); + } + if ($regs[8] != 'Z') { + $op = substr($regs[8], 0, 1); + $h = substr($regs[8], 1, 2); + if (strstr($regs[8], ':')) { + $m = substr($regs[8], 4, 2); + } else { + $m = substr($regs[8], 3, 2); + } + if ($op == '+') { + $regs[4] = $regs[4] - $h; + if ($regs[4] < 0) { + $regs[4] += 24; + } + $regs[5] = $regs[5] - $m; + if ($regs[5] < 0) { + $regs[5] += 60; + } + } else { + $regs[4] = $regs[4] + $h; + if ($regs[4] > 23) { + $regs[4] -= 24; + } + $regs[5] = $regs[5] + $m; + if ($regs[5] > 59) { + $regs[5] -= 60; + } + } + } + return $regs; + } + + return false; + } + + /** + * Returns an ISO 8601 formatted UTC date/time string. + * + * @param string|integer $datestr @see SOAP_Type_dateTime::_split + * + * @return string The ISO 8601 formatted UTC date/time string. + */ + function toUTC($datestr = null) + { + $regs = $this->_split($datestr); + + if ($regs) { + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', + $regs[1], + $regs[2], + $regs[3], + $regs[4], + $regs[5], + $regs[6]); + } + + return ''; + } + + /** + * Returns a unix timestamp. + * + * @param string|integer $datestr @see SOAP_Type_dateTime::_split + * + * @return integer The unix timestamp. + */ + function toUnixtime($datestr = null) + { + $regs = $this->_split($datestr); + if ($regs) { + return strtotime(sprintf('%04d-%02d-%02d %02d:%02d:%02dZ', + $regs[1], + $regs[2], + $regs[3], + $regs[4], + $regs[5], + $regs[6])); + } + return -1; + } + + /** + * Compares two dates or this object with a second date. + * + * @param string|integer $date1 A unix timestamp or ISO 8601 date/time + * string. + * @param string|integer $date2 A unix timestamp or ISO 8601 date/time + * string. If empty, this object is used. + * + * @return integer The difference between the first and the second date. + */ + function compare($date1, $date2 = null) + { + if (is_null($date2)) { + $date2 = $date1; + $date1 = $this->timestamp; + } + if (!is_int($date1)) { + $date1 = $this->toUnixtime($date1); + } + if (!is_int($date2)) { + $date2 = $this->toUnixtime($date2); + } + + if ($date1 != -1 && $date2 != -1) { + return $date1 - $date2; + } + + return -1; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Type/duration.php b/gulliver/thirdparty/pear/SOAP/Type/duration.php new file mode 100644 index 000000000..078e4a4fe --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Type/duration.php @@ -0,0 +1,165 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/pear/SOAP/Type/hexBinary.php b/gulliver/thirdparty/pear/SOAP/Type/hexBinary.php new file mode 100644 index 000000000..e6bbdf43d --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Type/hexBinary.php @@ -0,0 +1,45 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @copyright 2003-2007 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ +class SOAP_Type_hexBinary { + + function to_bin($value) + { + return pack('H' . strlen($value), $value); + } + + function to_hex($value) + { + return bin2hex($value); + } + + function is_hexbin($value) + { + // First see if there are any invalid chars. + if (!strlen($value) || preg_match('/[^A-Fa-f0-9]/', $value)) { + return false; + } + + return strcasecmp($value, SOAP_Type_hexBinary::to_hex(SOAP_Type_hexBinary::to_bin($value))) == 0; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/Value.php b/gulliver/thirdparty/pear/SOAP/Value.php new file mode 100644 index 000000000..907d7a4db --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/Value.php @@ -0,0 +1,238 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2007 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; + +/** + * SOAP::Value + * + * This class converts values between PHP and SOAP. + * + * Originally based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Dietrich Ayala Original Author + */ +class SOAP_Value +{ + /** + * @var string + */ + var $value = null; + + /** + * @var string + */ + var $name = ''; + + /** + * @var string + */ + var $type = ''; + + /** + * Namespace + * + * @var string + */ + var $namespace = ''; + var $type_namespace = ''; + + var $attributes = array(); + + /** + * @var string + */ + var $arrayType = ''; + + var $options = array(); + + var $nqn; + var $tqn; + + /** + * Constructor. + * + * @param string $name Name of the SOAP value {namespace}name. + * @param mixed $type SOAP value {namespace}type. Determined + * automatically if not set. + * @param mixed $value Value to set. + * @param array $attributes Attributes. + */ + function SOAP_Value($name = '', $type = false, $value = null, + $attributes = array()) + { + // Detect type if not passed. + $this->nqn = new QName($name); + $this->name = $this->nqn->name; + $this->namespace = $this->nqn->namespace; + $this->tqn = new QName($type); + $this->type = $this->tqn->name; + $this->type_prefix = $this->tqn->ns; + $this->type_namespace = $this->tqn->namespace; + $this->value = $value; + $this->attributes = $attributes; + } + + /** + * Serializes this value. + * + * @param SOAP_Base $serializer A SOAP_Base instance or subclass to + * serialize with. + * + * @return string XML representation of $this. + */ + function serialize(&$serializer) + { + return $serializer->_serializeValue($this->value, + $this->name, + $this->type, + $this->namespace, + $this->type_namespace, + $this->options, + $this->attributes, + $this->arrayType); + } + +} + +/** + * This class converts values between PHP and SOAP. It is a simple wrapper + * around SOAP_Value, adding support for SOAP actor and mustunderstand + * parameters. + * + * Originally based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Dietrich Ayala Original Author + */ +class SOAP_Header extends SOAP_Value +{ + /** + * Constructor + * + * @param string $name Name of the SOAP value {namespace}name. + * @param mixed $type SOAP value {namespace}type. Determined + * automatically if not set. + * @param mixed $value Value to set + * @param integer $mustunderstand Zero or one. + * @param mixed $attributes Attributes. + */ + function SOAP_Header($name = '', $type, $value, $mustunderstand = 0, + $attributes = array()) + { + if (!is_array($attributes)) { + $actor = $attributes; + $attributes = array(); + } + + parent::SOAP_Value($name, $type, $value, $attributes); + + if (isset($actor)) { + $this->attributes['SOAP-ENV:actor'] = $actor; + } elseif (!isset($this->attributes['SOAP-ENV:actor'])) { + $this->attributes['SOAP-ENV:actor'] = 'http://schemas.xmlsoap.org/soap/actor/next'; + } + $this->attributes['SOAP-ENV:mustUnderstand'] = (int)$mustunderstand; + } + +} + +/** + * This class handles MIME attachements per W3C's Note on Soap Attachements at + * http://www.w3.org/TR/SOAP-attachments + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + */ +class SOAP_Attachment extends SOAP_Value +{ + /** + * Constructor. + * + * @param string $name Name of the SOAP value + * @param string $type The attachment's MIME type. + * @param string $filename The attachment's file name. Ignored if $file + * is provide. + * @param string $file The attachment data. + */ + function SOAP_Attachment($name = '', $type = 'application/octet-stream', + $filename, $file = null) + { + parent::SOAP_Value($name, null, null); + + $filedata = ($file === null) ? $this->_file2str($filename) : $file; + $filename = basename($filename); + if (PEAR::isError($filedata)) { + $this->options['attachment'] = $filedata; + return; + } + + $cid = md5(uniqid(time())); + + $this->attributes['href'] = 'cid:' . $cid; + + $this->options['attachment'] = array('body' => $filedata, + 'disposition' => $filename, + 'content_type' => $type, + 'encoding' => 'base64', + 'cid' => $cid); + } + + /** + * Returns the contents of the given file name as string. + * + * @access private + * + * @param string $file_name The file location. + * + * @return string The file data or a PEAR_Error. + */ + function _file2str($file_name) + { + if (!is_readable($file_name)) { + return PEAR::raiseError('File is not readable: ' . $file_name); + } + + if (function_exists('file_get_contents')) { + return file_get_contents($file_name); + } + + if (!$fd = fopen($file_name, 'rb')) { + return PEAR::raiseError('Could not open ' . $file_name); + } + $cont = fread($fd, filesize($file_name)); + fclose($fd); + + return $cont; + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/WSDL.php b/gulliver/thirdparty/pear/SOAP/WSDL.php new file mode 100644 index 000000000..ad521781e --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/WSDL.php @@ -0,0 +1,2280 @@ + Original Author + * @author Shane Caraveo Port to PEAR and more + * @author Chuck Hagenbuch Maintenance + * @author Jan Schneider Maintenance + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/2_02.txt PHP License 2.02 + * @link http://pear.php.net/package/SOAP + */ + +require_once 'SOAP/Base.php'; +require_once 'SOAP/Fault.php'; +require_once 'HTTP/Request.php'; + +define('WSDL_CACHE_MAX_AGE', 43200); + +/** + * This class parses WSDL files, and can be used by SOAP::Client to properly + * register soap values for services. + * + * Originally based on SOAPx4 by Dietrich Ayala + * http://dietrich.ganx4.com/soapx4 + * + * @todo + * - add wsdl caching + * - refactor namespace handling ($namespace/$ns) + * - implement IDL type syntax declaration so we can generate WSDL + * + * @access public + * @package SOAP + * @author Shane Caraveo Conversion to PEAR and updates + * @author Dietrich Ayala Original Author + */ +class SOAP_WSDL extends SOAP_Base +{ + var $tns = null; + var $definition = array(); + var $namespaces = array(); + var $ns = array(); + var $xsd = SOAP_XML_SCHEMA_VERSION; + var $complexTypes = array(); + var $elements = array(); + var $messages = array(); + var $portTypes = array(); + var $bindings = array(); + var $imports = array(); + var $services = array(); + var $service = ''; + + /** + * URL to WSDL file. + * + * @var string + */ + var $uri; + + /** + * Parse documentation in the WSDL? + * + * @var boolean + */ + var $docs; + + /** + * Proxy parameters. + * + * @var array + */ + var $proxy; + + /** + * Enable tracing in the generated proxy class? + * + * @var boolean + */ + var $trace = false; + + /** + * Use WSDL cache? + * + * @var boolean + */ + var $cacheUse; + + /** + * WSDL cache directory. + * + * @var string + */ + var $cacheDir; + + /** + * Cache maximum lifetime (in seconds). + * + * @var integer + */ + var $cacheMaxAge; + + /** + * Class to use for WSDL parsing. Can be overridden for special cases, + * subclasses, etc. + * + * @var string + */ + var $wsdlParserClass = 'SOAP_WSDL_Parser'; + + /** + * Reserved PHP keywords. + * + * @link http://www.php.net/manual/en/reserved.php + * + * @var array + */ + var $_reserved = array('abstract', 'and', 'array', 'as', 'break', 'case', + 'catch', 'cfunction', 'class', 'clone', 'const', + 'continue', 'declare', 'default', 'die', 'do', + 'echo', 'else', 'elseif', 'empty', 'enddeclare', + 'endfor', 'endforeach', 'endif', 'endswitch', + 'endwhile', 'eval', 'exception', 'exit', 'extends', + 'final', 'for', 'foreach', 'function', 'global', + 'if', 'implements', 'include', 'include_once', + 'interface', 'isset', 'list', 'new', 'old_function', + 'or', 'php_user_filter', 'print', 'private', + 'protected', 'public', 'require', 'require_once', + 'return', 'static', 'switch', 'this', 'throw', + 'try', 'unset', 'use', 'var', 'while', 'xor'); + + /** + * Regular expressions for invalid PHP labels. + * + * @link http://www.php.net/manual/en/language.variables.php. + * + * @var string + */ + var $_invalid = array('/^[^a-zA-Z_\x7f-\xff]/', '/[^a-zA-Z0-9_\x7f-\xff]/'); + + /** + * SOAP_WSDL constructor. + * + * @param string $wsdl_uri URL to WSDL file. + * @param array $proxy Options for HTTP_Request class + * @see HTTP_Request. + * @param boolean|string $cacheUse Use WSDL caching? The cache directory + * if a string. + * @param integer $cacheMaxAge Cache maximum lifetime (in seconds). + * @param boolean $docs Parse documentation in the WSDL? + * + * @access public + */ + function SOAP_WSDL($wsdl_uri = false, + $proxy = array(), + $cacheUse = false, + $cacheMaxAge = WSDL_CACHE_MAX_AGE, + $docs = false) + { + parent::SOAP_Base('WSDL'); + $this->uri = $wsdl_uri; + $this->proxy = $proxy; + $this->cacheUse = !empty($cacheUse); + $this->cacheMaxAge = $cacheMaxAge; + $this->docs = $docs; + if (is_string($cacheUse)) { + $this->cacheDir = $cacheUse; + } + + if ($wsdl_uri) { + if (!PEAR::isError($this->parseURL($wsdl_uri))) { + reset($this->services); + $this->service = key($this->services); + } + } + } + + /** + * @deprecated Use setService(). + */ + function set_service($service) + { + $this->setService($service); + } + + /** + * Sets the service currently to be used. + * + * @param string $service An (existing) service name. + */ + function setService($service) + { + if (array_key_exists($service, $this->services)) { + $this->service = $service; + } + } + + /** + * Fills the WSDL array tree with data from a WSDL file. + * + * @param string $wsdl_uri URL to WSDL file. + */ + function parseURL($wsdl_uri) + { + $parser =& new $this->wsdlParserClass($wsdl_uri, $this, $this->docs); + + if ($parser->fault) { + $this->_raiseSoapFault($parser->fault); + } + } + + /** + * Fills the WSDL array tree with data from one or more PHP class objects. + * + * @param mixed $wsdl_obj An object or array of objects to add to + * the internal WSDL tree. + * @param string $targetNamespace The target namespace of schema types + * etc. + * @param string $service_name Name of the WSDL service. + * @param string $service_desc Optional description of the WSDL + * service. + */ + function parseObject(&$wsdl_obj, $targetNamespace, $service_name, + $service_desc = '') + { + $parser =& new SOAP_WSDL_ObjectParser($wsdl_obj, $this, + $targetNamespace, $service_name, + $service_desc); + + if ($parser->fault) { + $this->_raiseSoapFault($parser->fault); + } + } + + function getEndpoint($portName) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + return (isset($this->services[$this->service]['ports'][$portName]['address']['location'])) + ? $this->services[$this->service]['ports'][$portName]['address']['location'] + : $this->_raiseSoapFault("No endpoint for port for $portName", $this->uri); + } + + function _getPortName($operation, $service) + { + if (isset($this->services[$service]['ports'])) { + $ports = $this->services[$service]['ports']; + foreach ($ports as $port => $portAttrs) { + $type = $ports[$port]['type']; + if ($type == 'soap' && + isset($this->bindings[$portAttrs['binding']]['operations'][$operation])) { + return $port; + } + } + } + return null; + } + + /** + * Finds the name of the first port that contains an operation of name + * $operation. Always returns a SOAP portName. + */ + function getPortName($operation, $service = null) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + if (!$service) { + $service = $this->service; + } + if (isset($this->services[$service]['ports'])) { + if ($portName = $this->_getPortName($operation, $service)) { + return $portName; + } + } + // Try any service in the WSDL. + foreach ($this->services as $serviceName => $service) { + if (isset($this->services[$serviceName]['ports'])) { + if ($portName = $this->_getPortName($operation, $serviceName)) { + $this->service = $serviceName; + return $portName; + } + } + } + return $this->_raiseSoapFault("No operation $operation in WSDL.", $this->uri); + } + + function getOperationData($portName, $operation) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + if (!isset($this->services[$this->service]['ports'][$portName]['binding']) || + !($binding = $this->services[$this->service]['ports'][$portName]['binding'])) { + return $this->_raiseSoapFault("No binding for port $portName in WSDL.", $this->uri); + } + + // Get operation data from binding. + if (is_array($this->bindings[$binding]['operations'][$operation])) { + $opData = $this->bindings[$binding]['operations'][$operation]; + } + // get operation data from porttype + $portType = $this->bindings[$binding]['type']; + if (!$portType) { + return $this->_raiseSoapFault("No port type for binding $binding in WSDL.", $this->uri); + } + if (is_array($type = $this->portTypes[$portType][$operation])) { + if (isset($type['parameterOrder'])) { + $opData['parameterOrder'] = $type['parameterOrder']; + } + $opData['input'] = array_merge($opData['input'], $type['input']); + $opData['output'] = array_merge($opData['output'], $type['output']); + } + if (!$opData) + return $this->_raiseSoapFault("No operation $operation for port $portName in WSDL.", $this->uri); + $opData['parameters'] = false; + if (isset($this->bindings[$binding]['operations'][$operation]['input']['namespace'])) + $opData['namespace'] = $this->bindings[$binding]['operations'][$operation]['input']['namespace']; + // Message data from messages. + $inputMsg = $opData['input']['message']; + if (is_array($this->messages[$inputMsg])) { + foreach ($this->messages[$inputMsg] as $pname => $pattrs) { + if ($opData['style'] == 'document' && + $opData['input']['use'] == 'literal' && + $pname == 'parameters') { + $opData['parameters'] = true; + $opData['namespace'] = $this->namespaces[$pattrs['namespace']]; + $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; + if (isset($el['elements'])) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['input']['parts'][$elname] = $elattrs; + } + } + } else { + $opData['input']['parts'][$pname] = $pattrs; + } + } + } + $outputMsg = $opData['output']['message']; + if (is_array($this->messages[$outputMsg])) { + foreach ($this->messages[$outputMsg] as $pname => $pattrs) { + if ($opData['style'] == 'document' && + $opData['output']['use'] == 'literal' && + $pname == 'parameters') { + + $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; + if (isset($el['elements'])) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['output']['parts'][$elname] = $elattrs; + } + } + } else { + $opData['output']['parts'][$pname] = $pattrs; + } + } + } + return $opData; + } + + function matchMethod(&$operation) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + // Overloading lowercases function names :( + foreach ($this->services[$this->service]['ports'] as $portAttrs) { + foreach (array_keys($this->bindings[$portAttrs['binding']]['operations']) as $op) { + if (strcasecmp($op, $operation) == 0) { + $operation = $op; + } + } + } + } + + /** + * Given a datatype, what function handles the processing? + * + * This is used for doc/literal requests where we receive a datatype, and + * we need to pass it to a method in out server class. + * + * @param string $datatype + * @param string $namespace + * @return string + * @access public + */ + function getDataHandler($datatype, $namespace) + { + // See if we have an element by this name. + if (isset($this->namespaces[$namespace])) { + $namespace = $this->namespaces[$namespace]; + } + + if (isset($this->ns[$namespace])) { + $nsp = $this->ns[$namespace]; + //if (!isset($this->elements[$nsp])) + // $nsp = $this->namespaces[$nsp]; + if (isset($this->elements[$nsp][$datatype])) { + $checkmessages = array(); + // Find what messages use this datatype. + foreach ($this->messages as $messagename => $message) { + foreach ($message as $part) { + if ($part['type'] == $datatype) { + $checkmessages[] = $messagename; + break; + } + } + } + // Find the operation that uses this message. + foreach($this->portTypes as $porttype) { + foreach ($porttype as $opname => $opinfo) { + foreach ($checkmessages as $messagename) { + if ($opinfo['input']['message'] == $messagename) { + return $opname; + } + } + } + } + } + } + + return null; + } + + function getSoapAction($portName, $operation) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + if (!empty($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['soapAction'])) { + return $this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['soapAction']; + } + + return false; + } + + function getNamespace($portName, $operation) + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + if (!empty($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace'])) { + return $this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']; + } + + return false; + } + + function getNamespaceAttributeName($namespace) + { + /* If it doesn't exist at first, flip the array and check again. */ + if (empty($this->ns[$namespace])) { + $this->ns = array_flip($this->namespaces); + } + + /* If it doesn't exist now, add it. */ + if (empty($this->ns[$namespace])) { + return $this->addNamespace($namespace); + } + + return $this->ns[$namespace]; + } + + function addNamespace($namespace) + { + if (!empty($this->ns[$namespace])) { + return $this->ns[$namespace]; + } + + $n = count($this->ns); + $attr = 'ns' . $n; + $this->namespaces['ns' . $n] = $namespace; + $this->ns[$namespace] = $attr; + + return $attr; + } + + function _validateString($string) + { + return preg_match('/^[\w_:#\/]+$/', $string); + } + + function _addArg(&$args, &$argarray, $argname) + { + if ($args) { + $args .= ', '; + } + $args .= '$' . $argname; + if (!$this->_validateString($argname)) { + return; + } + if ($argarray) { + $argarray .= ', '; + } + $argarray .= "'$argname' => $" . $argname; + } + + function _elementArg(&$args, &$argarray, &$_argtype, $_argname) + { + $comments = ''; + $el = $this->elements[$_argtype['namespace']][$_argtype['type']]; + $tns = isset($this->ns[$el['namespace']]) + ? $this->ns[$el['namespace']] + : $_argtype['namespace']; + + if (!empty($el['complex']) || + (isset($el['type']) && + isset($this->complexTypes[$tns][$el['type']]))) { + // The element is a complex type. + $comments .= " // {$_argtype['type']} is a ComplexType, refer to the WSDL for more info.\n"; + $attrname = "{$_argtype['type']}_attr"; + if (isset($el['type']) && + isset($this->complexTypes[$tns][$el['type']]['attribute'])) { + $comments .= " // {$_argtype['type']} may require attributes, refer to the WSDL for more info.\n"; + } + $comments .= " \${$attrname}['xmlns'] = '{$this->namespaces[$_argtype['namespace']]}';\n"; + $comments .= " \${$_argtype['type']} = new SOAP_Value('{$_argtype['type']}', false, \${$_argtype['type']}, \$$attrname);\n"; + $this->_addArg($args, $argarray, $_argtype['type']); + if (isset($el['type']) && + isset($this->complexTypes[$tns][$el['type']]['attribute'])) { + if ($args) { + $args .= ', '; + } + $args .= '$' . $attrname; + } + } elseif (isset($el['elements'])) { + foreach ($el['elements'] as $ename => $element) { + $comments .= " \$$ename = new SOAP_Value('{{$this->namespaces[$element['namespace']]}}$ename', '" . + (isset($element['type']) ? $element['type'] : false) . + "', \$$ename);\n"; + $this->_addArg($args, $argarray, $ename); + } + } else { + $comments .= " \$$_argname = new SOAP_Value('{{$this->namespaces[$tns]}}$_argname', '{$el['type']}', \$$_argname);\n"; + $this->_addArg($args, $argarray, $_argname); + } + + return $comments; + } + + function _complexTypeArg(&$args, &$argarray, &$_argtype, $_argname) + { + $comments = ''; + if (isset($this->complexTypes[$_argtype['namespace']][$_argtype['type']])) { + $comments = " // $_argname is a ComplexType {$_argtype['type']},\n" . + " // refer to wsdl for more info\n"; + if (isset($this->complexTypes[$_argtype['namespace']][$_argtype['type']]['attribute'])) { + $comments .= " // $_argname may require attributes, refer to wsdl for more info\n"; + } + $wrapname = '{' . $this->namespaces[$_argtype['namespace']].'}' . $_argtype['type']; + $comments .= " \$$_argname = new SOAP_Value('$_argname', '$wrapname', \$$_argname);\n"; + } + + $this->_addArg($args, $argarray, $_argname); + + return $comments; + } + + /** + * Generates stub code from the WSDL that can be saved to a file or eval'd + * into existence. + */ + function generateProxyCode($port = '', $classname = '') + { + if ($this->_isfault()) { + return $this->_getfault(); + } + + $multiport = count($this->services[$this->service]['ports']) > 1; + if (!$port) { + reset($this->services[$this->service]['ports']); + $port = current($this->services[$this->service]['ports']); + } + // XXX currently do not support HTTP ports + if ($port['type'] != 'soap') { + return null; + } + + // XXX currentPort is BAD + $clienturl = $port['address']['location']; + if (!$classname) { + if ($multiport || $port) { + $classname = 'WebService_' . $this->service . '_' . $port['name']; + } else { + $classname = 'WebService_' . $this->service; + } + $classname = $this->_sanitize($classname); + } + + if (!$this->_validateString($classname)) { + return null; + } + + if (is_array($this->proxy) && count($this->proxy)) { + $class = "class $classname extends SOAP_Client\n{\n" . + " function $classname(\$path = '$clienturl')\n {\n" . + " \$this->SOAP_Client(\$path, 0, 0,\n" . + ' array('; + + foreach ($this->proxy as $key => $val) { + if (is_array($val)) { + $class .= "'$key' => array("; + foreach ($val as $key2 => $val2) { + $class .= "'$key2' => '$val2', "; + } + $class .= ')'; + } else { + $class .= "'$key' => '$val', "; + } + } + $class .= "));\n }\n"; + $class = str_replace(', ))', '))', $class); + } else { + $class = "class $classname extends SOAP_Client\n{\n" . + " function $classname(\$path = '$clienturl')\n {\n" . + " \$this->SOAP_Client(\$path, 0);\n" . + " }\n"; + } + + // Get the binding, from that get the port type. + $primaryBinding = $port['binding']; + $primaryBinding = preg_replace("/^(.*:)/", '', $primaryBinding); + $portType = $this->bindings[$primaryBinding]['type']; + $portType = preg_replace("/^(.*:)/", '', $portType); + $style = $this->bindings[$primaryBinding]['style']; + + // XXX currentPortType is BAD + foreach ($this->portTypes[$portType] as $opname => $operation) { + $binding = $this->bindings[$primaryBinding]['operations'][$opname]; + if (isset($binding['soapAction'])) { + $soapaction = $binding['soapAction']; + } else { + $soapaction = null; + } + if (isset($binding['style'])) { + $opstyle = $binding['style']; + } else { + $opstyle = $style; + } + $use = $binding['input']['use']; + if ($use == 'encoded') { + $namespace = $binding['input']['namespace']; + } else { + $bindingType = $this->bindings[$primaryBinding]['type']; + $ns = $this->portTypes[$bindingType][$opname]['input']['namespace']; + $namespace = $this->namespaces[$ns]; + } + + $args = ''; + $argarray = ''; + $comments = ''; + $wrappers = ''; + foreach ($operation['input'] as $argname => $argtype) { + if ($argname == 'message') { + foreach ($this->messages[$argtype] as $_argname => $_argtype) { + $_argname = $this->_sanitize($_argname); + if ($opstyle == 'document' && $use == 'literal' && + $_argtype['name'] == 'parameters') { + // The type or element refered to is used for + // parameters. + $elattrs = null; + $el = $this->elements[$_argtype['namespace']][$_argtype['type']]; + + if ($el['complex']) { + $namespace = $this->namespaces[$_argtype['namespace']]; + // XXX need to wrap the parameters in a + // SOAP_Value. + } + if (isset($el['elements'])) { + foreach ($el['elements'] as $elname => $elattrs) { + $elname = $this->_sanitize($elname); + // Is the element a complex type? + if (isset($this->complexTypes[$elattrs['namespace']][$elname])) { + $comments .= $this->_complexTypeArg($args, $argarray, $_argtype, $_argname); + } else { + $this->_addArg($args, $argarray, $elname); + } + } + } + if ($el['complex'] && $argarray) { + $wrapname = '{' . $this->namespaces[$_argtype['namespace']].'}' . $el['name']; + $comments .= " \${$el['name']} = new SOAP_Value('$wrapname', false, \$v = array($argarray));\n"; + $argarray = "'{$el['name']}' => \${$el['name']}"; + } + } else { + if (isset($_argtype['element'])) { + // Element argument. + $comments .= $this->_elementArg($args, $argarray, $_argtype, $_argtype['type']); + } else { + // Complex type argument. + $comments .= $this->_complexTypeArg($args, $argarray, $_argtype, $_argname); + } + } + } + } + } + + // Validate entries. + + // Operation names are function names, so try to make sure it's + // legal. This could potentially cause collisions, but let's try + // to make everything callable and see how many problems that + // causes. + $opname_php = $this->_sanitize($opname); + if (!$this->_validateString($opname_php)) { + return null; + } + + if ($argarray) { + $argarray = "array($argarray)"; + } else { + $argarray = 'null'; + } + + $class .= " function &$opname_php($args)\n {\n$comments$wrappers" . + " \$result = \$this->call('$opname',\n" . + " \$v = $argarray,\n" . + " array('namespace' => '$namespace',\n" . + " 'soapaction' => '$soapaction',\n" . + " 'style' => '$opstyle',\n" . + " 'use' => '$use'" . + ($this->trace ? ",\n 'trace' => true" : '') . "));\n" . + " return \$result;\n" . + " }\n"; + } + + $class .= "}\n"; + + return $class; + } + + function generateAllProxies() + { + $proxycode = ''; + foreach (array_keys($this->services[$this->service]['ports']) as $key) { + $port =& $this->services[$this->service]['ports'][$key]; + $proxycode .= $this->generateProxyCode($port); + } + return $proxycode; + } + + function &getProxy($port = '', $name = '') + { + if ($this->_isfault()) { + $fault =& $this->_getfault(); + return $fault; + } + + $multiport = count($this->services[$this->service]['ports']) > 1; + + if (!$port) { + reset($this->services[$this->service]['ports']); + $port = current($this->services[$this->service]['ports']); + } + + if ($multiport || $port) { + $classname = 'WebService_' . $this->service . '_' . $port['name']; + } else { + $classname = 'WebService_' . $this->service; + } + + if ($name) { + $classname = $name . '_' . $classname; + } + + $classname = $this->_sanitize($classname); + if (!class_exists($classname)) { + $proxy = $this->generateProxyCode($port, $classname); + require_once 'SOAP/Client.php'; + eval($proxy); + } + $proxy =& new $classname; + + return $proxy; + } + + /** + * Sanitizes a SOAP value, method or class name so that it can be used as + * a valid PHP identifier. Invalid characters are converted into + * underscores and reserved words are prefixed with an underscore. + * + * @param string $name The identifier to sanitize. + * + * @return string The sanitized identifier. + */ + function _sanitize($name) + { + $name = preg_replace($this->_invalid, '_', $name); + if (in_array($name, $this->_reserved)) { + $name = '_' . $name; + } + return $name; + } + + function &_getComplexTypeForElement($name, $namespace) + { + $t = null; + if (isset($this->ns[$namespace]) && + isset($this->elements[$this->ns[$namespace]][$name]['type'])) { + + $type = $this->elements[$this->ns[$namespace]][$name]['type']; + $ns = $this->elements[$this->ns[$namespace]][$name]['namespace']; + + if (isset($this->complexTypes[$ns][$type])) { + $t = $this->complexTypes[$ns][$type]; + } + } + return $t; + } + + function getComplexTypeNameForElement($name, $namespace) + { + $t = $this->_getComplexTypeForElement($name, $namespace); + if ($t) { + return $t['name']; + } + return null; + } + + function getComplexTypeChildType($ns, $name, $child_ns, $child_name) + { + // Is the type an element? + $t = $this->_getComplexTypeForElement($name, $ns); + if ($t) { + // No, get it from complex types directly. + if (isset($t['elements'][$child_name]['type'])) + return $t['elements'][$child_name]['type']; + } elseif (isset($this->ns[$ns]) && + isset($this->elements[$this->ns[$ns]][$name]['complex']) && + $this->elements[$this->ns[$ns]][$name]['complex']) { + // Type is not an element but complex. + return $this->elements[$this->ns[$ns]][$name]['elements'][$child_name]['type']; + } + return null; + } + + function getSchemaType($type, $name, $type_namespace) + { + // see if it's a complex type so we can deal properly with + // SOAPENC:arrayType. + if ($name && $type) { + // XXX TODO: + // look up the name in the wsdl and validate the type. + foreach ($this->complexTypes as $types) { + if (isset($types[$type])) { + if (isset($types[$type]['type'])) { + list($arraytype_ns, $arraytype, $array_depth) = isset($types[$type]['arrayType']) + ? $this->_getDeepestArrayType($types[$type]['namespace'], $types[$type]['arrayType']) + : array($this->namespaces[$types[$type]['namespace']], null, 0); + return array($types[$type]['type'], $arraytype, $arraytype_ns, $array_depth); + } + if (isset($types[$type]['arrayType'])) { + list($arraytype_ns, $arraytype, $array_depth) = + $this->_getDeepestArrayType($types[$type]['namespace'], $types[$type]['arrayType']); + return array('Array', $arraytype, $arraytype_ns, $array_depth); + } + if (!empty($types[$type]['elements'][$name])) { + $type = $types[$type]['elements']['type']; + return array($type, null, $this->namespaces[$types[$type]['namespace']], null); + } + break; + } + } + } + if ($type && $type_namespace) { + $arrayType = null; + // XXX TODO: + // this code currently handles only one way of encoding array + // types in wsdl need to do a generalized function to figure out + // complex types + $p = $this->ns[$type_namespace]; + if ($p && !empty($this->complexTypes[$p][$type])) { + if ($arrayType = $this->complexTypes[$p][$type]['arrayType']) { + $type = 'Array'; + } elseif ($this->complexTypes[$p][$type]['order'] == 'sequence' && + array_key_exists('elements', $this->complexTypes[$p][$type])) { + reset($this->complexTypes[$p][$type]['elements']); + // assume an array + if (count($this->complexTypes[$p][$type]['elements']) == 1) { + $arg = current($this->complexTypes[$p][$type]['elements']); + $arrayType = $arg['type']; + $type = 'Array'; + } else { + foreach ($this->complexTypes[$p][$type]['elements'] as $element) { + if ($element['name'] == $type) { + $arrayType = $element['type']; + $type = $element['type']; + } + } + } + } else { + $type = 'Struct'; + } + return array($type, $arrayType, $type_namespace, null); + } + } + return array(null, null, null, null); + } + + /** + * Recurse through the WSDL structure looking for the innermost array type + * of multi-dimensional arrays. + * + * Takes a namespace prefix and a type, which can be in the form 'type' or + * 'type[]', and returns the full namespace URI, the type of the most + * deeply nested array type found, and the number of levels of nesting. + * + * @access private + * @return mixed array or nothing + */ + function _getDeepestArrayType($nsPrefix, $arrayType) + { + static $trail = array(); + + $arrayType = ereg_replace('\[\]$', '', $arrayType); + + // Protect against circular references XXX We really need to remove + // trail from this altogether (it's very inefficient and in the wrong + // place!) and put circular reference checking in when the WSDL info + // is generated in the first place + if (array_search($nsPrefix . ':' . $arrayType, $trail)) { + return array(null, null, -count($trail)); + } + + if (array_key_exists($nsPrefix, $this->complexTypes) && + array_key_exists($arrayType, $this->complexTypes[$nsPrefix]) && + array_key_exists('arrayType', $this->complexTypes[$nsPrefix][$arrayType])) { + $trail[] = $nsPrefix . ':' . $arrayType; + $result = $this->_getDeepestArrayType($this->complexTypes[$nsPrefix][$arrayType]['namespace'], + $this->complexTypes[$nsPrefix][$arrayType]['arrayType']); + return array($result[0], $result[1], $result[2] + 1); + } + return array($this->namespaces[$nsPrefix], $arrayType, 0); + } + +} + +class SOAP_WSDL_Cache extends SOAP_Base +{ + /** + * Use WSDL cache? + * + * @var boolean + */ + var $_cacheUse; + + /** + * WSDL cache directory. + * + * @var string + */ + var $_cacheDir; + + /** + * Cache maximum lifetime (in seconds) + * + * @var integer + */ + var $_cacheMaxAge; + + /** + * Constructor. + * + * @param boolean $cashUse Use caching? + * @param integer $cacheMaxAge Cache maximum lifetime (in seconds) + */ + function SOAP_WSDL_Cache($cacheUse = false, + $cacheMaxAge = WSDL_CACHE_MAX_AGE, + $cacheDir = null) + { + parent::SOAP_Base('WSDLCACHE'); + $this->_cacheUse = $cacheUse; + $this->_cacheDir = $cacheDir; + $this->_cacheMaxAge = $cacheMaxAge; + } + + /** + * Returns the path to the cache and creates it, if it doesn't exist. + * + * @private + * + * @return string The directory to use for the cache. + */ + function _cacheDir() + { + if (!empty($this->_cacheDir)) { + $dir = $this->_cacheDir; + } else { + $dir = getenv('WSDLCACHE'); + if (empty($dir)) { + $dir = './wsdlcache'; + } + } + @mkdir($dir, 0700); + return $dir; + } + + /** + * Retrieves a file from cache if it exists, otherwise retreive from net, + * add to cache, and return from cache. + * + * @param string URL to WSDL + * @param array proxy parameters + * @param int expected MD5 of WSDL URL + * @access public + * @return string data + */ + function get($wsdl_fname, $proxy_params = array(), $cache = 0) + { + $cachename = $md5_wsdl = $file_data = ''; + if ($this->_cacheUse) { + // Try to retrieve WSDL from cache + $cachename = $this->_cacheDir() . '/' . md5($wsdl_fname). ' .wsdl'; + if (file_exists($cachename)) { + $wf = fopen($cachename, 'rb'); + if ($wf) { + // Reading cached file + $file_data = fread($wf, filesize($cachename)); + $md5_wsdl = md5($file_data); + fclose($wf); + } + if ($cache) { + if ($cache != $md5_wsdl) { + return $this->_raiseSoapFault('WSDL Checksum error!', $wsdl_fname); + } + } else { + $fi = stat($cachename); + $cache_mtime = $fi[8]; + //print cache_mtime, time() + if ($cache_mtime + $this->_cacheMaxAge < time()) { + // expired + $md5_wsdl = ''; // refetch + } + } + } + } + + if (!$md5_wsdl) { + // Not cached or not using cache. Retrieve WSDL from URL + + // is it a local file? + // this section should be replace by curl at some point + if (!preg_match('/^(https?|file):\/\//', $wsdl_fname)) { + if (!file_exists($wsdl_fname)) { + return $this->_raiseSoapFault("Unable to read local WSDL $wsdl_fname", $wsdl_fname); + } + $file_data = file_get_contents($wsdl_fname); + } else { + $uri = explode('?', $wsdl_fname); + $rq =& new HTTP_Request($uri[0], $proxy_params); + // the user agent HTTP_Request uses fouls things up + if (isset($uri[1])) { + $rq->addRawQueryString($uri[1]); + } + + if (isset($proxy_params['proxy_host']) && + isset($proxy_params['proxy_port']) && + isset($proxy_params['proxy_user']) && + isset($proxy_params['proxy_pass'])) { + $rq->setProxy($proxy_params['proxy_host'], $proxy_params['proxy_port'], + $proxy_params['proxy_user'], $proxy_params['proxy_pass']); + } elseif (isset($proxy_params['proxy_host']) && + isset($proxy_params['proxy_port'])) { + $rq->setProxy($proxy_params['proxy_host'], $proxy_params['proxy_port']); + } + + $result = $rq->sendRequest(); + if (PEAR::isError($result)) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname," . $rq->getResponseCode(), $wsdl_fname); + } + $file_data = $rq->getResponseBody(); + if (!$file_data) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname, no http body", $wsdl_fname); + } + } + + $md5_wsdl = md5($file_data); + + if ($this->_cacheUse) { + $fp = fopen($cachename, "wb"); + fwrite($fp, $file_data); + fclose($fp); + } + } + if ($this->_cacheUse && $cache && $cache != $md5_wsdl) { + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + } + return $file_data; + } + +} + +class SOAP_WSDL_Parser extends SOAP_Base +{ + + /** + * Define internal arrays of bindings, ports, operations, + * messages, etc. + */ + var $currentMessage; + var $currentOperation; + var $currentPortType; + var $currentBinding; + var $currentPort; + + /** + * Parser vars. + */ + var $cache; + + var $tns = null; + var $soapns = array('soap'); + var $uri = ''; + var $wsdl = null; + + var $status = ''; + var $element_stack = array(); + var $parentElement = ''; + + var $schema = ''; + var $schemaStatus = ''; + var $schema_stack = array(); + var $currentComplexType; + var $schema_element_stack = array(); + var $currentElement; + + /** + * Constructor. + */ + function SOAP_WSDL_Parser($uri, &$wsdl, $docs = false) + { + parent::SOAP_Base('WSDLPARSER'); + $this->cache =& new SOAP_WSDL_Cache($wsdl->cacheUse, + $wsdl->cacheMaxAge, + $wsdl->cacheDir); + $this->uri = $uri; + $this->wsdl = &$wsdl; + $this->docs = $docs; + $this->parse($uri); + } + + function parse($uri) + { + // Check whether content has been read. + $fd = $this->cache->get($uri, $this->wsdl->proxy); + if (PEAR::isError($fd)) { + return $this->_raiseSoapFault($fd); + } + + // Create an XML parser. + $parser = xml_parser_create(); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($parser, $this); + xml_set_element_handler($parser, 'startElement', 'endElement'); + if ($this->docs) { + xml_set_character_data_handler($parser, 'characterData'); + } + + if (!xml_parse($parser, $fd, true)) { + $detail = sprintf('XML error on line %d: %s', + xml_get_current_line_number($parser), + xml_error_string(xml_get_error_code($parser))); + return $this->_raiseSoapFault("Unable to parse WSDL file $uri\n$detail"); + } + xml_parser_free($parser); + return true; + } + + /** + * start-element handler + */ + function startElement($parser, $name, $attrs) + { + // Get element prefix. + $qname = new QName($name); + if ($qname->ns) { + $ns = $qname->ns; + if ($ns && ((!$this->tns && strcasecmp($qname->name, 'definitions') == 0) || $ns == $this->tns)) { + $name = $qname->name; + } + } + $this->currentTag = $qname->name; + $this->parentElement = ''; + $stack_size = count($this->element_stack); + if ($stack_size) { + $this->parentElement = $this->element_stack[$stack_size - 1]; + } + $this->element_stack[] = $this->currentTag; + + // Find status, register data. + switch ($this->status) { + case 'types': + // sect 2.2 wsdl:types + // children: xsd:schema + $parent_tag = ''; + $stack_size = count($this->schema_stack); + if ($stack_size) { + $parent_tag = $this->schema_stack[$stack_size - 1]; + } + + switch ($qname->name) { + case 'schema': + // No parent should be in the stack. + if (!$parent_tag || $parent_tag == 'types') { + if (array_key_exists('targetNamespace', $attrs)) { + $this->schema = $this->wsdl->getNamespaceAttributeName($attrs['targetNamespace']); + } else { + $this->schema = $this->wsdl->getNamespaceAttributeName($this->wsdl->tns); + } + $this->wsdl->complexTypes[$this->schema] = array(); + $this->wsdl->elements[$this->schema] = array(); + } + break; + + case 'complexType': + if ($parent_tag == 'schema') { + $this->currentComplexType = $attrs['name']; + if (!isset($attrs['namespace'])) { + $attrs['namespace'] = $this->schema; + } + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType] = $attrs; + if (array_key_exists('base', $attrs)) { + $qn = new QName($attrs['base']); + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = $qn->name; + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['namespace'] = $qn->ns; + } else { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Struct'; + } + $this->schemaStatus = 'complexType'; + } else { + $this->wsdl->elements[$this->schema][$this->currentElement]['complex'] = true; + } + break; + + case 'element': + if (isset($attrs['type'])) { + $qn = new QName($attrs['type']); + $attrs['type'] = $qn->name; + if ($qn->ns && array_key_exists($qn->ns, $this->wsdl->namespaces)) { + $attrs['namespace'] = $qn->ns; + } + } + + $parentElement = ''; + $stack_size = count($this->schema_element_stack); + if ($stack_size > 0) { + $parentElement = $this->schema_element_stack[$stack_size - 1]; + } + + if (isset($attrs['ref'])) { + $qn = new QName($attrs['ref']); + $this->currentElement = $qn->name; + } else { + $this->currentElement = $attrs['name']; + } + $this->schema_element_stack[] = $this->currentElement; + if (!isset($attrs['namespace'])) { + $attrs['namespace'] = $this->schema; + } + + if ($parent_tag == 'schema') { + $this->wsdl->elements[$this->schema][$this->currentElement] = $attrs; + $this->wsdl->elements[$this->schema][$this->currentElement]['complex'] = false; + $this->schemaStatus = 'element'; + } elseif ($this->currentComplexType) { + // we're inside a complexType + if ((isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['order']) && + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['order'] == 'sequence') + && $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] == 'Array') { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['arrayType'] = isset($attrs['type']) ? $attrs['type'] : null; + } + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['elements'][$this->currentElement] = $attrs; + } else { + $this->wsdl->elements[$this->schema][$parentElement]['elements'][$this->currentElement] = $attrs; + } + break; + + case 'complexContent': + case 'simpleContent': + break; + + case 'extension': + case 'restriction': + if ($this->schemaStatus == 'complexType') { + if (!empty($attrs['base'])) { + $qn = new QName($attrs['base']); + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = $qn->name; + + // Types that extend from other types aren't + // *of* those types. Reflect this by denoting + // which type they extend. I'm leaving the + // 'type' setting here since I'm not sure what + // removing it might break at the moment. + if ($qname->name == 'extension') { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['extends'] = $qn->name; + } + } else { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Struct'; + } + } + break; + + case 'sequence': + if ($this->schemaStatus == 'complexType') { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['order'] = $qname->name; + if (!isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'])) { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Array'; + } + } + break; + + case 'all': + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['order'] = $qname->name; + if (!isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'])) { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Struct'; + } + break; + + case 'choice': + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['order'] = $qname->name; + if (!isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'])) { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Array'; + } + + case 'attribute': + if ($this->schemaStatus == 'complexType') { + if (isset($attrs['name'])) { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['attribute'][$attrs['name']] = $attrs; + } else { + if (isset($attrs['ref'])) { + $q = new QName($attrs['ref']); + foreach ($attrs as $k => $v) { + if ($k != 'ref' && strstr($k, $q->name)) { + $vq = new QName($v); + if ($q->name == 'arrayType') { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType][$q->name] = $vq->name. $vq->arrayInfo; + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Array'; + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['namespace'] = $vq->ns; + } else { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType][$q->name] = $vq->name; + } + } + } + } + } + } + break; + } + + $this->schema_stack[] = $qname->name; + break; + + case 'message': + // sect 2.3 wsdl:message child wsdl:part + switch ($qname->name) { + case 'part': + $qn = null; + if (isset($attrs['type'])) { + $qn = new QName($attrs['type']); + } elseif (isset($attrs['element'])) { + $qn = new QName($attrs['element']); + } + if ($qn) { + $attrs['type'] = $qn->name; + $attrs['namespace'] = $qn->ns; + } + $this->wsdl->messages[$this->currentMessage][$attrs['name']] = $attrs; + // error in wsdl + + case 'documentation': + break; + + default: + break; + } + break; + + case 'portType': + // sect 2.4 + switch ($qname->name) { + case 'operation': + // attributes: name + // children: wsdl:input wsdl:output wsdl:fault + $this->currentOperation = $attrs['name']; + $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation] = $attrs; + break; + + case 'input': + case 'output': + case 'fault': + // wsdl:input wsdl:output wsdl:fault + // attributes: name message parameterOrder(optional) + if ($this->currentOperation) { + if (isset($this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name])) { + $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name] = array_merge($this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name], $attrs); + } else { + $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name] = $attrs; + } + if (array_key_exists('message', $attrs)) { + $qn = new QName($attrs['message']); + $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name]['message'] = $qn->name; + $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation][$name]['namespace'] = $qn->ns; + } + } + break; + + case 'documentation': + break; + + default: + break; + } + break; + + case 'binding': + $ns = $qname->ns ? $this->wsdl->namespaces[$qname->ns] : SCHEMA_WSDL; + switch ($ns) { + case SCHEMA_SOAP: + case SCHEMA_SOAP12: + // this deals with wsdl section 3 soap binding + switch ($qname->name) { + case 'binding': + // sect 3.3 + // soap:binding, attributes: transport(required), style(optional, default = document) + // if style is missing, it is assumed to be 'document' + if (!isset($attrs['style'])) { + $attrs['style'] = 'document'; + } + $this->wsdl->bindings[$this->currentBinding] = array_merge($this->wsdl->bindings[$this->currentBinding], $attrs); + break; + + case 'operation': + // sect 3.4 + // soap:operation, attributes: soapAction(required), style(optional, default = soap:binding:style) + if (!isset($attrs['style'])) { + $attrs['style'] = $this->wsdl->bindings[$this->currentBinding]['style']; + } + if (isset($this->wsdl->bindings[$this->currentBinding]['operations'][$this->currentOperation])) { + $this->wsdl->bindings[$this->currentBinding]['operations'][$this->currentOperation] = array_merge($this->wsdl->bindings[$this->currentBinding]['operations'][$this->currentOperation], $attrs); + } else { + $this->wsdl->bindings[$this->currentBinding]['operations'][$this->currentOperation] = $attrs; + } + break; + + case 'body': + // sect 3.5 + // soap:body attributes: + // part - optional. listed parts must appear in body, missing means all parts appear in body + // use - required. encoded|literal + // encodingStyle - optional. space seperated list of encodings (uri's) + $this->wsdl->bindings[$this->currentBinding] + ['operations'][$this->currentOperation][$this->opStatus] = $attrs; + break; + + case 'fault': + // sect 3.6 + // soap:fault attributes: name use encodingStyle namespace + $this->wsdl->bindings[$this->currentBinding] + ['operations'][$this->currentOperation][$this->opStatus] = $attrs; + break; + + case 'header': + // sect 3.7 + // soap:header attributes: message part use encodingStyle namespace + $this->wsdl->bindings[$this->currentBinding] + ['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + + case 'headerfault': + // sect 3.7 + // soap:header attributes: message part use encodingStyle namespace + $header = count($this->wsdl->bindings[$this->currentBinding] + ['operations'][$this->currentOperation][$this->opStatus]['headers'])-1; + $this->wsdl->bindings[$this->currentBinding] + ['operations'][$this->currentOperation][$this->opStatus]['headers'][$header]['fault'] = $attrs; + break; + + case 'documentation': + break; + + default: + // error! not a valid element inside binding + break; + } + break; + + case SCHEMA_WSDL: + // XXX verify correct namespace + // for now, default is the 'wsdl' namespace + // other possible namespaces include smtp, http, etc. for alternate bindings + switch ($qname->name) { + case 'operation': + // sect 2.5 + // wsdl:operation attributes: name + $this->currentOperation = $attrs['name']; + break; + + case 'output': + case 'input': + case 'fault': + // sect 2.5 + // wsdl:input attributes: name + $this->opStatus = $qname->name; + break; + + case 'documentation': + break; + + default: + break; + } + break; + + case SCHEMA_WSDL_HTTP: + switch ($qname->name) { + case 'binding': + // sect 4.4 + // http:binding attributes: verb + // parent: wsdl:binding + $this->wsdl->bindings[$this->currentBinding] = array_merge($this->wsdl->bindings[$this->currentBinding], $attrs); + break; + + case 'operation': + // sect 4.5 + // http:operation attributes: location + // parent: wsdl:operation + $this->wsdl->bindings[$this->currentBinding]['operations'] + [$this->currentOperation] = $attrs; + break; + + case 'urlEncoded': + // sect 4.6 + // http:urlEncoded attributes: location + // parent: wsdl:input wsdl:output etc. + $this->wsdl->bindings[$this->currentBinding]['operations'][$this->opStatus] + [$this->currentOperation]['uri'] = 'urlEncoded'; + break; + + case 'urlReplacement': + // sect 4.7 + // http:urlReplacement attributes: location + // parent: wsdl:input wsdl:output etc. + $this->wsdl->bindings[$this->currentBinding]['operations'][$this->opStatus] + [$this->currentOperation]['uri'] = 'urlReplacement'; + break; + + case 'documentation': + break; + + default: + // error + break; + } + + case SCHEMA_MIME: + // sect 5 + // all mime parts are children of wsdl:input, wsdl:output, etc. + // unsuported as of yet + switch ($qname->name) { + case 'content': + // sect 5.3 mime:content + // + // part attribute only required if content is child of multipart related, + // it contains the name of the part + // type attribute contains the mime type + case 'multipartRelated': + // sect 5.4 mime:multipartRelated + case 'part': + case 'mimeXml': + // sect 5.6 mime:mimeXml + // + // + case 'documentation': + break; + + default: + // error + break; + } + + case SCHEMA_DIME: + // DIME is defined in: + // http://gotdotnet.com/team/xml_wsspecs/dime/WSDL-Extension-for-DIME.htm + // all DIME parts are children of wsdl:input, wsdl:output, etc. + // unsuported as of yet + switch ($qname->name) { + case 'message': + // sect 4.1 dime:message + // appears in binding section + $this->wsdl->bindings[$this->currentBinding]['dime'] = $attrs; + break; + + default: + break; + } + + default: + break; + } + break; + + case 'service': + $ns = $qname->ns ? $this->wsdl->namespaces[$qname->ns] : SCHEMA_WSDL; + + switch ($qname->name) { + case 'port': + // sect 2.6 wsdl:port attributes: name binding + $this->currentPort = $attrs['name']; + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort] = $attrs; + // XXX hack to deal with binding namespaces + $qn = new QName($attrs['binding']); + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['binding'] = $qn->name; + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['namespace'] = $qn->ns; + break; + + case 'address': + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['address'] = $attrs; + // what TYPE of port is it? SOAP or HTTP? + $ns = $qname->ns ? $this->wsdl->namespaces[$qname->ns] : SCHEMA_WSDL; + switch ($ns) { + case SCHEMA_WSDL_HTTP: + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['type']='http'; + break; + + case SCHEMA_SOAP: + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['type']='soap'; + break; + + default: + // Shouldn't happen, we'll assume SOAP. + $this->wsdl->services[$this->currentService]['ports'][$this->currentPort]['type']='soap'; + } + + break; + + case 'documentation': + break; + + default: + break; + } + } + + // Top level elements found under wsdl:definitions. + switch ($qname->name) { + case 'import': + // sect 2.1.1 wsdl:import attributes: namespace location + if ((isset($attrs['location']) || isset($attrs['schemaLocation'])) && + !isset($this->wsdl->imports[$attrs['namespace']])) { + $uri = isset($attrs['location']) ? $attrs['location'] : $attrs['schemaLocation']; + $location = @parse_url($uri); + if (!isset($location['scheme'])) { + $base = @parse_url($this->uri); + $uri = $this->mergeUrl($base, $uri); + } + + $this->wsdl->imports[$attrs['namespace']] = $attrs; + $import_parser_class = get_class($this); + $import_parser =& new $import_parser_class($uri, $this->wsdl, $this->docs); + if ($import_parser->fault) { + unset($this->wsdl->imports[$attrs['namespace']]); + return false; + } + $this->currentImport = $attrs['namespace']; + } + // Continue on to the 'types' case - lack of break; is + // intentional. + + case 'types': + // sect 2.2 wsdl:types + $this->status = 'types'; + break; + + case 'schema': + // We can hit this at the top level if we've been asked to + // import an XSD file. + if (!empty($attrs['targetNamespace'])) { + $this->schema = $this->wsdl->getNamespaceAttributeName($attrs['targetNamespace']); + } else { + $this->schema = $this->wsdl->getNamespaceAttributeName($this->wsdl->tns); + } + $this->wsdl->complexTypes[$this->schema] = array(); + $this->wsdl->elements[$this->schema] = array(); + $this->schema_stack[] = $qname->name; + $this->status = 'types'; + break; + + case 'message': + // sect 2.3 wsdl:message attributes: name children:wsdl:part + $this->status = 'message'; + if (isset($attrs['name'])) { + $this->currentMessage = $attrs['name']; + $this->wsdl->messages[$this->currentMessage] = array(); + } + break; + + case 'portType': + // sect 2.4 wsdl:portType + // attributes: name + // children: wsdl:operation + $this->status = 'portType'; + $this->currentPortType = $attrs['name']; + $this->wsdl->portTypes[$this->currentPortType] = array(); + break; + + case 'binding': + // sect 2.5 wsdl:binding attributes: name type + // children: wsdl:operation soap:binding http:binding + if ($qname->ns && $qname->ns != $this->tns) { + break; + } + $this->status = 'binding'; + $this->currentBinding = $attrs['name']; + $qn = new QName($attrs['type']); + $this->wsdl->bindings[$this->currentBinding]['type'] = $qn->name; + $this->wsdl->bindings[$this->currentBinding]['namespace'] = $qn->ns; + break; + + case 'service': + // sect 2.7 wsdl:service attributes: name children: ports + $this->currentService = $attrs['name']; + $this->wsdl->services[$this->currentService]['ports'] = array(); + $this->status = 'service'; + break; + + case 'definitions': + // sec 2.1 wsdl:definitions + // attributes: name targetNamespace xmlns:* + // children: wsdl:import wsdl:types wsdl:message wsdl:portType wsdl:binding wsdl:service + $this->wsdl->definition = $attrs; + foreach ($attrs as $key => $value) { + if (strstr($key, 'xmlns:') !== false) { + $qn = new QName($key); + // XXX need to refactor ns handling. + $this->wsdl->namespaces[$qn->name] = $value; + $this->wsdl->ns[$value] = $qn->name; + if ($key == 'targetNamespace' || + strcasecmp($value,SOAP_SCHEMA) == 0) { + $this->soapns[] = $qn->name; + } else { + if (in_array($value, $this->_XMLSchema)) { + $this->wsdl->xsd = $value; + } + } + } + } + if (isset($ns) && $ns) { + $namespace = 'xmlns:' . $ns; + if (!$this->wsdl->definition[$namespace]) { + return $this->_raiseSoapFault("parse error, no namespace for $namespace", $this->uri); + } + $this->tns = $ns; + } + break; + } + } + + /** + * end-element handler. + */ + function endElement($parser, $name) + { + $stacksize = count($this->element_stack); + if ($stacksize) { + if ($this->element_stack[$stacksize - 1] == 'definitions') { + $this->status = ''; + } + array_pop($this->element_stack); + } + + if (stristr($name, 'schema')) { + array_pop($this->schema_stack); + $this->schema = ''; + } + + if ($this->schema) { + array_pop($this->schema_stack); + if (count($this->schema_stack) <= 1) { + /* Correct the type for sequences with multiple + * elements. */ + if (isset($this->currentComplexType) && isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type']) + && $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] == 'Array' + && array_key_exists('elements', $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]) + && count($this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['elements']) > 1) { + $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['type'] = 'Struct'; + } + } + if (stristr($name, 'complexType')) { + $this->currentComplexType = ''; + if (count($this->schema_element_stack)) { + $this->currentElement = array_pop($this->schema_element_stack); + } else { + $this->currentElement = ''; + } + } elseif (stristr($name, 'element')) { + if (count($this->schema_element_stack)) { + $this->currentElement = array_pop($this->schema_element_stack); + } else { + $this->currentElement = ''; + } + } + } + } + + /** + * Element content handler. + */ + function characterData($parser, $data) + { + // Store the documentation in the WSDL file. + if ($this->currentTag == 'documentation') { + $data = trim(preg_replace('/\s+/', ' ', $data)); + if (!strlen($data)) { + return; + } + + switch ($this->status) { + case 'service': + $ptr =& $this->wsdl->services[$this->currentService]; + break; + + case 'portType': + $ptr =& $this->wsdl->portTypes[$this->currentPortType][$this->currentOperation]; + break; + + case 'binding': + $ptr =& $this->wsdl->bindings[$this->currentBinding]; + break; + + case 'message': + $ptr =& $this->wsdl->messages[$this->currentMessage]; + break; + + case 'operation': + break; + + case 'types': + if (isset($this->currentComplexType) && + isset($this->wsdl->complexTypes[$this->schema][$this->currentComplexType])) { + if ($this->currentElement) { + $ptr =& $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]['elements'][$this->currentElement]; + } else { + $ptr =& $this->wsdl->complexTypes[$this->schema][$this->currentComplexType]; + } + } + break; + } + + if (isset($ptr)) { + if (!isset($ptr['documentation'])) { + $ptr['documentation'] = ''; + } else { + $ptr['documentation'] .= ' '; + } + $ptr['documentation'] .= $data; + } + } + } + + /** + * $parsed is an array returned by parse_url(). + * + * @access private + */ + function mergeUrl($parsed, $path) + { + if (!is_array($parsed)) { + return false; + } + + $uri = ''; + if (!empty($parsed['scheme'])) { + $sep = (strtolower($parsed['scheme']) == 'mailto' ? ':' : '://'); + $uri = $parsed['scheme'] . $sep; + } + + if (isset($parsed['pass'])) { + $uri .= "$parsed[user]:$parsed[pass]@"; + } elseif (isset($parsed['user'])) { + $uri .= "$parsed[user]@"; + } + + if (isset($parsed['host'])) { + $uri .= $parsed['host']; + } + if (isset($parsed['port'])) { + $uri .= ":$parsed[port]"; + } + if ($path[0] != '/' && isset($parsed['path'])) { + if ($parsed['path'][strlen($parsed['path']) - 1] != '/') { + $path = dirname($parsed['path']) . '/' . $path; + } else { + $path = $parsed['path'] . $path; + } + $path = $this->_normalize($path); + } + $sep = $path[0] == '/' ? '' : '/'; + $uri .= $sep . $path; + + return $uri; + } + + function _normalize($path_str) + { + $pwd = ''; + $strArr = preg_split('/(\/)/', $path_str, -1, PREG_SPLIT_NO_EMPTY); + $pwdArr = ''; + $j = 0; + for ($i = 0; $i < count($strArr); $i++) { + if ($strArr[$i] != ' ..') { + if ($strArr[$i] != ' .') { + $pwdArr[$j] = $strArr[$i]; + $j++; + } + } else { + array_pop($pwdArr); + $j--; + } + } + $pStr = implode('/', $pwdArr); + $pwd = (strlen($pStr) > 0) ? ('/' . $pStr) : '/'; + return $pwd; + } + +} + +/** + * Parses the types and methods used in web service objects into the internal + * data structures used by SOAP_WSDL. + * + * Assumes the SOAP_WSDL class is unpopulated to start with. + * + * @author Chris Coe + */ +class SOAP_WSDL_ObjectParser extends SOAP_Base +{ + /** + * Target namespace for the WSDL document will have the following + * prefix. + */ + var $tnsPrefix = 'tns'; + + /** + * Reference to the SOAP_WSDL object to populate. + */ + var $wsdl = null; + + /** + * Constructor. + * + * @param object|array $objects Reference to the object or array of + * objects to parse. + * @param SOAP_WSDL $wsdl Reference to the SOAP_WSDL object to + * populate. + * @param string $targetNamespace The target namespace of schema types + * etc. + * @param string $service_name Name of the WSDL . + * @param string $service_desc Optional description of the WSDL + * . + */ + function SOAP_WSDL_ObjectParser(&$objects, &$wsdl, $targetNamespace, + $service_name, $service_desc = '') + { + parent::SOAP_Base('WSDLOBJECTPARSER'); + + $this->wsdl = &$wsdl; + + // Set up the SOAP_WSDL object + $this->_initialise($service_name); + + // Parse each web service object + $wsdl_ref = (is_array($objects)? $objects : array(&$objects)); + + foreach ($wsdl_ref as $ref_item) { + if (!is_object($ref_item)) { + $this->_raiseSoapFault('Invalid web service object passed to object parser'); + continue; + } + + if (!$this->_parse($ref_item, $targetNamespace, $service_name)) { + break; + } + } + + // Build bindings from abstract data. + if ($this->fault == null) { + $this->_generateBindingsAndServices($targetNamespace, $service_name, $service_desc); + } + } + + /** + * Initialise the SOAP_WSDL tree (destructive). + * + * If the object has already been initialised, the only effect + * will be to change the tns namespace to the new service name. + * + * @param $service_name Name of the WSDL + * @access private + */ + function _initialise($service_name) + { + // Set up the basic namespaces that all WSDL definitions use. + $this->wsdl->namespaces['wsdl'] = SCHEMA_WSDL; // WSDL language + $this->wsdl->namespaces['soap'] = SCHEMA_SOAP; // WSDL SOAP bindings + $this->wsdl->namespaces[$this->tnsPrefix] = 'urn:' . $service_name; // Target namespace + $this->wsdl->namespaces['xsd'] = array_search('xsd', $this->_namespaces); // XML Schema + $this->wsdl->namespaces['SOAP-ENC'] = array_search('SOAP-ENC', $this->_namespaces); // SOAP types + + // XXX Refactor $namespace/$ns for Shane :-) + unset($this->wsdl->ns['urn:' . $service_name]); + $this->wsdl->ns += array_flip($this->wsdl->namespaces); + + // Imports are not implemented in WSDL generation from classes. + // *** *** + } + + /** + * Parser - takes a single object to add to tree (non-destructive). + * + * @access private + * + * @param object $object Reference to the object to parse. + * @param string $schemaNamespace + * @param string $service_name Name of the WSDL . + */ + function _parse(&$object, $schemaNamespace, $service_name) + { + // Create namespace prefix for the schema + list($schPrefix,) = $this->_getTypeNs('{' . $schemaNamespace . '}'); + + // Parse all the types defined by the object in whatever + // schema language we are using (currently __typedef arrays) + // *** *** + foreach ($object->__typedef as $typeName => $typeValue) { + // Get/create namespace definition + list($nsPrefix, $typeName) = $this->_getTypeNs($typeName); + + // Create type definition + $this->wsdl->complexTypes[$schPrefix][$typeName] = array('name' => $typeName); + $thisType =& $this->wsdl->complexTypes[$schPrefix][$typeName]; + + // According to Dmitri's documentation, __typedef comes in two + // flavors: + // Array = array(array("item" => "value")) + // Struct = array("item1" => "value1", "item2" => "value2", ...) + if (is_array($typeValue)) { + if (is_array(current($typeValue)) && count($typeValue) == 1 + && count(current($typeValue)) == 1) { + // It's an array + $thisType['type'] = 'Array'; + $nsType = current(current($typeValue)); + list($nsPrefix, $typeName) = $this->_getTypeNs($nsType); + $thisType['namespace'] = $nsPrefix; + $thisType['arrayType'] = $typeName . '[]'; + } elseif (!is_array(current($typeValue))) { + // It's a struct + $thisType['type'] = 'Struct'; + $thisType['order'] = 'all'; + $thisType['namespace'] = $nsPrefix; + $thisType['elements'] = array(); + + foreach ($typeValue as $elementName => $elementType) { + list($nsPrefix, $typeName) = $this->_getTypeNs($elementType); + $thisType['elements'][$elementName]['name'] = $elementName; + $thisType['elements'][$elementName]['type'] = $typeName; + $thisType['elements'][$elementName]['namespace'] = $nsPrefix; + } + } else { + // It's erroneous + return $this->_raiseSoapFault("The type definition for $nsPrefix:$typeName is invalid.", 'urn:' . get_class($object)); + } + } else { + // It's erroneous + return $this->_raiseSoapFault("The type definition for $nsPrefix:$typeName is invalid.", 'urn:' . get_class($object)); + } + } + + // Create an empty element array with the target namespace + // prefix, to match the results of WSDL parsing. + $this->wsdl->elements[$schPrefix] = array(); + + // Populate tree with message information + // *** *** + foreach ($object->__dispatch_map as $operationName => $messages) { + foreach ($messages as $messageType => $messageParts) { + unset($thisMessage); + + switch ($messageType) { + case 'in': + $this->wsdl->messages[$operationName . 'Request'] = array(); + $thisMessage =& $this->wsdl->messages[$operationName . 'Request']; + break; + + case 'out': + $this->wsdl->messages[$operationName . 'Response'] = array(); + $thisMessage =& $this->wsdl->messages[$operationName . 'Response']; + break; + + case 'alias': + // Do nothing + break; + + default: + // Error condition + break; + } + + if (isset($thisMessage)) { + foreach ($messageParts as $partName => $partType) { + list ($nsPrefix, $typeName) = $this->_getTypeNs($partType); + + $thisMessage[$partName] = array( + 'name' => $partName, + 'type' => $typeName, + 'namespace' => $nsPrefix + ); + } + } + } + } + + // Populate tree with portType information + // XXX Current implementation only supports one portType that + // encompasses all of the operations available. + // *** *** + if (!isset($this->wsdl->portTypes[$service_name . 'Port'])) { + $this->wsdl->portTypes[$service_name . 'Port'] = array(); + } + $thisPortType =& $this->wsdl->portTypes[$service_name . 'Port']; + + foreach ($object->__dispatch_map as $operationName => $messages) { + $thisPortType[$operationName] = array('name' => $operationName); + + foreach ($messages as $messageType => $messageParts) { + switch ($messageType) { + case 'in': + $thisPortType[$operationName]['input'] = array( + 'message' => $operationName . 'Request', + 'namespace' => $this->tnsPrefix); + break; + + case 'out': + $thisPortType[$operationName]['output'] = array( + 'message' => $operationName . 'Response', + 'namespace' => $this->tnsPrefix); + break; + } + } + } + + return true; + } + + /** + * Takes all the abstract WSDL data and builds concrete bindings and + * services (destructive). + * + * @access private + * @todo Current implementation discards $service_desc. + * + * @param string $schemaNamespace Namespace for types etc. + * @param string $service_name Name of the WSDL . + * @param string $service_desc Optional description of the WSDL + * . + */ + function _generateBindingsAndServices($schemaNamespace, $service_name, + $service_desc = '') + { + // Populate tree with bindings information + // XXX Current implementation only supports one binding that + // matches the single portType and all of its operations. + // XXX Is this the correct use of $schemaNamespace here? + // *** *** + $this->wsdl->bindings[$service_name . 'Binding'] = array( + 'type' => $service_name . 'Port', + 'namespace' => $this->tnsPrefix, + 'style' => 'rpc', + 'transport' => SCHEMA_SOAP_HTTP, + 'operations' => array()); + $thisBinding =& $this->wsdl->bindings[$service_name . 'Binding']; + + foreach ($this->wsdl->portTypes[$service_name . 'Port'] as $operationName => $operationData) { + $thisBinding['operations'][$operationName] = array( + 'soapAction' => $schemaNamespace . '#' . $operationName, + 'style' => $thisBinding['style']); + + foreach (array('input', 'output') as $messageType) + if (isset($operationData[$messageType])) { + $thisBinding['operations'][$operationName][$messageType] = array( + 'use' => 'encoded', + 'namespace' => $schemaNamespace, + 'encodingStyle' => SOAP_SCHEMA_ENCODING); + } + } + + // Populate tree with service information + // XXX Current implementation supports one service which groups + // all of the ports together, one port per binding + // *** *** + + $this->wsdl->services[$service_name . 'Service'] = array('ports' => array()); + $thisService =& $this->wsdl->services[$service_name . 'Service']['ports']; + $https = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) || + getenv('SSL_PROTOCOL_VERSION'); + + foreach ($this->wsdl->bindings as $bindingName => $bindingData) { + $thisService[$bindingData['type']] = array( + 'name' => $bindingData['type'], + 'binding' => $bindingName, + 'namespace' => $this->tnsPrefix, + 'address' => array('location' => + ($https ? 'https://' : 'http://') . + $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . + (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '')), + 'type' => 'soap'); + } + + // Set service + $this->wsdl->set_service($service_name . 'Service'); + $this->wsdl->uri = $this->wsdl->namespaces[$this->tnsPrefix]; + + // Create WSDL definition + // *** *** + + $this->wsdl->definition = array( + 'name' => $service_name, + 'targetNamespace' => $this->wsdl->namespaces[$this->tnsPrefix], + 'xmlns' => SCHEMA_WSDL); + + foreach ($this->wsdl->namespaces as $nsPrefix => $namespace) { + $this->wsdl->definition['xmlns:' . $nsPrefix] = $namespace; + } + } + + /** + * This function is adapted from Dmitri V's implementation of + * DISCO/WSDL generation. It separates namespace from type name in + * a __typedef key and creates a new namespace entry in the WSDL + * structure if the namespace has not been used before. The + * namespace prefix and type name are returned. If no namespace is + * specified, xsd is assumed. + * + * We will not need this function anymore once __typedef is + * eliminated. + */ + function _getTypeNs($type) + { + preg_match_all('/\{(.*)\}/sm', $type, $m); + if (!empty($m[1][0])) { + if (!isset($this->wsdl->ns[$m[1][0]])) { + $ns_pref = 'ns' . count($this->wsdl->namespaces); + $this->wsdl->ns[$m[1][0]] = $ns_pref; + $this->wsdl->namespaces[$ns_pref] = $m[1][0]; + } + $typens = $this->wsdl->ns[$m[1][0]]; + $type = str_replace($m[0][0], '', $type); + } else { + $typens = 'xsd'; + } + + return array($typens, $type); + } + +} diff --git a/gulliver/thirdparty/pear/SOAP/tools/genproxy.php b/gulliver/thirdparty/pear/SOAP/tools/genproxy.php new file mode 100644 index 000000000..8a334e1ef --- /dev/null +++ b/gulliver/thirdparty/pear/SOAP/tools/genproxy.php @@ -0,0 +1,21 @@ + foo.php + * + */ + +function do_wsdl($uri) { + $wsdl =& new SOAP_WSDL($uri); + print $wsdl->generateAllProxies(); +} +echo ""; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php new file mode 100644 index 000000000..eda612035 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php @@ -0,0 +1,104 @@ + +* +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('PEAR.php'); +require_once('Spreadsheet/Excel/Writer/Workbook.php'); + +/** +* Class for writing Excel Spreadsheets. This class should change COMPLETELY. +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer extends Spreadsheet_Excel_Writer_Workbook +{ + /** + * The constructor. It just creates a Workbook + * + * @param string $filename The optional filename for the Workbook. + * @return Spreadsheet_Excel_Writer_Workbook The Workbook created + */ + function Spreadsheet_Excel_Writer($filename = '') + { + $this->_filename = $filename; + $this->Spreadsheet_Excel_Writer_Workbook($filename); + } + + /** + * Send HTTP headers for the Excel file. + * + * @param string $filename The filename to use for HTTP headers + * @access public + */ + function send($filename) + { + header("Content-type: application/vnd.ms-excel"); + header("Content-Disposition: attachment; filename=$filename"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); + header("Pragma: public"); + } + + /** + * Utility function for writing formulas + * Converts a cell's coordinates to the A1 format. + * + * @access public + * @static + * @param integer $row Row for the cell to convert (0-indexed). + * @param integer $col Column for the cell to convert (0-indexed). + * @return string The cell identifier in A1 format + */ + function rowcolToCell($row, $col) + { + if ($col > 255) { //maximum column value exceeded + return new PEAR_Error("Maximum column value exceeded: $col"); + } + + $int = (int)($col / 26); + $frac = $col % 26; + $chr1 = ''; + + if ($int > 0) { + $chr1 = chr(ord('A') + $int - 1); + } + + $chr2 = chr(ord('A') + $frac); + $row++; + + return $chr1.$chr2.$row; + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php.bk b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php.bk new file mode 100644 index 000000000..eda612035 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer.php.bk @@ -0,0 +1,104 @@ + +* +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('PEAR.php'); +require_once('Spreadsheet/Excel/Writer/Workbook.php'); + +/** +* Class for writing Excel Spreadsheets. This class should change COMPLETELY. +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer extends Spreadsheet_Excel_Writer_Workbook +{ + /** + * The constructor. It just creates a Workbook + * + * @param string $filename The optional filename for the Workbook. + * @return Spreadsheet_Excel_Writer_Workbook The Workbook created + */ + function Spreadsheet_Excel_Writer($filename = '') + { + $this->_filename = $filename; + $this->Spreadsheet_Excel_Writer_Workbook($filename); + } + + /** + * Send HTTP headers for the Excel file. + * + * @param string $filename The filename to use for HTTP headers + * @access public + */ + function send($filename) + { + header("Content-type: application/vnd.ms-excel"); + header("Content-Disposition: attachment; filename=$filename"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); + header("Pragma: public"); + } + + /** + * Utility function for writing formulas + * Converts a cell's coordinates to the A1 format. + * + * @access public + * @static + * @param integer $row Row for the cell to convert (0-indexed). + * @param integer $col Column for the cell to convert (0-indexed). + * @return string The cell identifier in A1 format + */ + function rowcolToCell($row, $col) + { + if ($col > 255) { //maximum column value exceeded + return new PEAR_Error("Maximum column value exceeded: $col"); + } + + $int = (int)($col / 26); + $frac = $col % 26; + $chr1 = ''; + + if ($int > 0) { + $chr1 = chr(ord('A') + $int - 1); + } + + $chr2 = chr(ord('A') + $frac); + $row++; + + return $chr1.$chr2.$row; + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/BIFFwriter.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/BIFFwriter.php new file mode 100644 index 000000000..1f700dfb5 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/BIFFwriter.php @@ -0,0 +1,241 @@ + +* +* The majority of this is _NOT_ my code. I simply ported it from the +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@php.net +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('PEAR.php'); + +/** +* Class for writing Excel BIFF records. +* +* From "MICROSOFT EXCEL BINARY FILE FORMAT" by Mark O'Brien (Microsoft Corporation): +* +* BIFF (BInary File Format) is the file format in which Excel documents are +* saved on disk. A BIFF file is a complete description of an Excel document. +* BIFF files consist of sequences of variable-length records. There are many +* different types of BIFF records. For example, one record type describes a +* formula entered into a cell; one describes the size and location of a +* window into a document; another describes a picture format. +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer_BIFFwriter extends PEAR +{ + /** + * The BIFF/Excel version (5). + * @var integer + */ + var $_BIFF_version = 0x0500; + + /** + * The byte order of this architecture. 0 => little endian, 1 => big endian + * @var integer + */ + var $_byte_order; + + /** + * The string containing the data of the BIFF stream + * @var string + */ + var $_data; + + /** + * The size of the data in bytes. Should be the same as strlen($this->_data) + * @var integer + */ + var $_datasize; + + /** + * The maximun length for a BIFF record. See _addContinue() + * @var integer + * @see _addContinue() + */ + var $_limit; + + /** + * Constructor + * + * @access public + */ + function Spreadsheet_Excel_Writer_BIFFwriter() + { + $this->_byte_order = ''; + $this->_data = ''; + $this->_datasize = 0; + $this->_limit = 2080; + // Set the byte order + $this->_setByteOrder(); + } + + /** + * Determine the byte order and store it as class data to avoid + * recalculating it for each call to new(). + * + * @access private + */ + function _setByteOrder() + { + // Check if "pack" gives the required IEEE 64bit float + $teststr = pack("d", 1.2345); + $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); + if ($number == $teststr) { + $byte_order = 0; // Little Endian + } + elseif ($number == strrev($teststr)){ + $byte_order = 1; // Big Endian + } + else { + // Give up. I'll fix this in a later version. + return $this->raiseError("Required floating point format ". + "not supported on this platform."); + } + $this->_byte_order = $byte_order; + } + + /** + * General storage function + * + * @param string $data binary data to prepend + * @access private + */ + function _prepend($data) + { + if (strlen($data) > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_data = $data.$this->_data; + $this->_datasize += strlen($data); + } + + /** + * General storage function + * + * @param string $data binary data to append + * @access private + */ + function _append($data) + { + if (strlen($data) > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_data = $this->_data.$data; + $this->_datasize += strlen($data); + } + + /** + * Writes Excel BOF record to indicate the beginning of a stream or + * sub-stream in the BIFF file. + * + * @param integer $type Type of BIFF file to write: 0x0005 Workbook, + * 0x0010 Worksheet. + * @access private + */ + function _storeBof($type) + { + $record = 0x0809; // Record identifier + + // According to the SDK $build and $year should be set to zero. + // However, this throws a warning in Excel 5. So, use magic numbers. + if ($this->_BIFF_version == 0x0500) { + $length = 0x0008; + $unknown = ''; + $build = 0x096C; + $year = 0x07C9; + } + elseif ($this->_BIFF_version == 0x0600) { + $length = 0x0010; + $unknown = pack("VV", 0x00000041, 0x00000006); //unknown last 8 bytes for BIFF8 + $build = 0x0DBB; + $year = 0x07CC; + } + $version = $this->_BIFF_version; + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $version, $type, $build, $year); + $this->_prepend($header.$data.$unknown); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + function _storeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + $header = pack("vv", $record, $length); + $this->_append($header); + } + + /** + * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In + * Excel 97 the limit is 8228 bytes. Records that are longer than these limits + * must be split up into CONTINUE blocks. + * + * This function takes a long BIFF record and inserts CONTINUE records as + * necessary. + * + * @param string $data The original binary data to be written + * @return string A very convenient string of continue blocks + * @access private + */ + function _addContinue($data) + { + $limit = $this->_limit; + $record = 0x003C; // Record identifier + + // The first 2080/8224 bytes remain intact. However, we have to change + // the length field of the record. + $tmp = substr($data, 0, 2).pack("v", $limit-4).substr($data, 4, $limit - 4); + + $header = pack("vv", $record, $limit); // Headers for continue records + + // Retrieve chunks of 2080/8224 bytes +4 for the header. + for($i = $limit; $i < strlen($data) - $limit; $i += $limit) + { + $tmp .= $header; + $tmp .= substr($data, $i, $limit); + } + + // Retrieve the last chunk of data + $header = pack("vv", $record, strlen($data) - $i); + $tmp .= $header; + $tmp .= substr($data,$i,strlen($data) - $i); + + return $tmp; + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Format.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Format.php new file mode 100644 index 000000000..788d25bb8 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Format.php @@ -0,0 +1,1035 @@ + +* +* The majority of this is _NOT_ my code. I simply ported it from the +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('PEAR.php'); + +/** +* Class for generating Excel XF records (formats) +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer_Format extends PEAR +{ + /** + * The index given by the workbook when creating a new format. + * @var integer + */ + var $_xf_index; + + /** + * Index to the FONT record. + * @var integer + */ + var $font_index; + + /** + * The font name (ASCII). + * @var string + */ + var $_font_name; + + /** + * Height of font (1/20 of a point) + * @var integer + */ + var $_size; + + /** + * Bold style + * @var integer + */ + var $_bold; + + /** + * Bit specifiying if the font is italic. + * @var integer + */ + var $_italic; + + /** + * Index to the cell's color + * @var integer + */ + var $_color; + + /** + * The text underline property + * @var integer + */ + var $_underline; + + /** + * Bit specifiying if the font has strikeout. + * @var integer + */ + var $_font_strikeout; + + /** + * Bit specifiying if the font has outline. + * @var integer + */ + var $_font_outline; + + /** + * Bit specifiying if the font has shadow. + * @var integer + */ + var $_font_shadow; + + /** + * 2 bytes specifiying the script type for the font. + * @var integer + */ + var $_font_script; + + /** + * Byte specifiying the font family. + * @var integer + */ + var $_font_family; + + /** + * Byte specifiying the font charset. + * @var integer + */ + var $_font_charset; + + /** + * An index (2 bytes) to a FORMAT record (number format). + * @var integer + */ + var $_num_format; + + /** + * Bit specifying if formulas are hidden. + * @var integer + */ + var $_hidden; + + /** + * Bit specifying if the cell is locked. + * @var integer + */ + var $_locked; + + /** + * The three bits specifying the text horizontal alignment. + * @var integer + */ + var $_text_h_align; + + /** + * Bit specifying if the text is wrapped at the right border. + * @var integer + */ + var $_text_wrap; + + /** + * The three bits specifying the text vertical alignment. + * @var integer + */ + var $_text_v_align; + + /** + * 1 bit, apparently not used. + * @var integer + */ + var $_text_justlast; + + /** + * The two bits specifying the text rotation. + * @var integer + */ + var $_rotation; + + /** + * The cell's foreground color. + * @var integer + */ + var $_fg_color; + + /** + * The cell's background color. + * @var integer + */ + var $_bg_color; + + /** + * The cell's background fill pattern. + * @var integer + */ + var $_pattern; + + /** + * Style of the bottom border of the cell + * @var integer + */ + var $_bottom; + + /** + * Color of the bottom border of the cell. + * @var integer + */ + var $_bottom_color; + + /** + * Style of the top border of the cell + * @var integer + */ + var $_top; + + /** + * Color of the top border of the cell. + * @var integer + */ + var $_top_color; + + /** + * Style of the left border of the cell + * @var integer + */ + var $_left; + + /** + * Color of the left border of the cell. + * @var integer + */ + var $_left_color; + + /** + * Style of the right border of the cell + * @var integer + */ + var $_right; + + /** + * Color of the right border of the cell. + * @var integer + */ + var $_right_color; + + /** + * Constructor + * + * @access private + * @param integer $index the XF index for the format. + * @param array $properties array with properties to be set on initialization. + */ + function Spreadsheet_Excel_Writer_Format($BIFF_version, $index = 0, $properties = array()) + { + $this->_xf_index = $index; + $this->_BIFF_version = $BIFF_version; + $this->font_index = 0; + $this->_font_name = 'Arial'; + $this->_size = 10; + $this->_bold = 0x0190; + $this->_italic = 0; + $this->_color = 0x7FFF; + $this->_underline = 0; + $this->_font_strikeout = 0; + $this->_font_outline = 0; + $this->_font_shadow = 0; + $this->_font_script = 0; + $this->_font_family = 0; + $this->_font_charset = 0; + + $this->_num_format = 0; + + $this->_hidden = 0; + $this->_locked = 0; + + $this->_text_h_align = 0; + $this->_text_wrap = 0; + $this->_text_v_align = 2; + $this->_text_justlast = 0; + $this->_rotation = 0; + + $this->_fg_color = 0x40; + $this->_bg_color = 0x41; + + $this->_pattern = 0; + + $this->_bottom = 0; + $this->_top = 0; + $this->_left = 0; + $this->_right = 0; + $this->_diag = 0; + + $this->_bottom_color = 0x40; + $this->_top_color = 0x40; + $this->_left_color = 0x40; + $this->_right_color = 0x40; + $this->_diag_color = 0x40; + + // Set properties passed to Spreadsheet_Excel_Writer_Workbook::addFormat() + foreach($properties as $property => $value) + { + if(method_exists($this,'set'.ucwords($property))) + { + $method_name = 'set'.ucwords($property); + $this->$method_name($value); + } + } + } + + + /** + * Generate an Excel BIFF XF record (style or cell). + * + * @param string $style The type of the XF record ('style' or 'cell'). + * @return string The XF record + */ + function getXf($style) + { + // Set the type of the XF record and some of the attributes. + if ($style == "style") { + $style = 0xFFF5; + } + else { + $style = $this->_locked; + $style |= $this->_hidden << 1; + } + + // Flags to indicate if attributes have been set. + $atr_num = ($this->_num_format != 0)?1:0; + $atr_fnt = ($this->font_index != 0)?1:0; + $atr_alc = ($this->_text_wrap)?1:0; + $atr_bdr = ($this->_bottom || + $this->_top || + $this->_left || + $this->_right)?1:0; + $atr_pat = (($this->_fg_color != 0x40) || + ($this->_bg_color != 0x41) || + $this->_pattern)?1:0; + $atr_prot = $this->_locked | $this->_hidden; + + // Zero the default border colour if the border has not been set. + if ($this->_bottom == 0) { + $this->_bottom_color = 0; + } + if ($this->_top == 0) { + $this->_top_color = 0; + } + if ($this->_right == 0) { + $this->_right_color = 0; + } + if ($this->_left == 0) { + $this->_left_color = 0; + } + if ($this->_diag == 0) { + $this->_diag_color = 0; + } + + $record = 0x00E0; // Record identifier + if ($this->_BIFF_version == 0x0500) { + $length = 0x0010; // Number of bytes to follow + } + if ($this->_BIFF_version == 0x0600) { + $length = 0x0014; + } + + $ifnt = $this->font_index; // Index to FONT record + $ifmt = $this->_num_format; // Index to FORMAT record + if ($this->_BIFF_version == 0x0500) + { + $align = $this->_text_h_align; // Alignment + $align |= $this->_text_wrap << 3; + $align |= $this->_text_v_align << 4; + $align |= $this->_text_justlast << 7; + $align |= $this->_rotation << 8; + $align |= $atr_num << 10; + $align |= $atr_fnt << 11; + $align |= $atr_alc << 12; + $align |= $atr_bdr << 13; + $align |= $atr_pat << 14; + $align |= $atr_prot << 15; + + $icv = $this->_fg_color; // fg and bg pattern colors + $icv |= $this->_bg_color << 7; + + $fill = $this->_pattern; // Fill and border line style + $fill |= $this->_bottom << 6; + $fill |= $this->_bottom_color << 9; + + $border1 = $this->_top; // Border line style and color + $border1 |= $this->_left << 3; + $border1 |= $this->_right << 6; + $border1 |= $this->_top_color << 9; + + $border2 = $this->_left_color; // Border color + $border2 |= $this->_right_color << 7; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $ifnt, $ifmt, $style, $align, + $icv, $fill, + $border1, $border2); + } + elseif ($this->_BIFF_version == 0x0600) + { + $align = $this->_text_h_align; // Alignment + $align |= $this->_text_wrap << 3; + $align |= $this->_text_v_align << 4; + $align |= $this->_text_justlast << 7; + + $used_attrib = $atr_num << 2; + $used_attrib |= $atr_fnt << 3; + $used_attrib |= $atr_alc << 4; + $used_attrib |= $atr_bdr << 5; + $used_attrib |= $atr_pat << 6; + $used_attrib |= $atr_prot << 7; + + $icv = $this->_fg_color; // fg and bg pattern colors + $icv |= $this->_bg_color << 7; + + $border1 = $this->_left; // Border line style and color + $border1 |= $this->_right << 4; + $border1 |= $this->_top << 8; + $border1 |= $this->_bottom << 12; + $border1 |= $this->_left_color << 16; + $border1 |= $this->_right_color << 23; + $diag_tl_to_rb = 0; // FIXME: add method + $diag_tr_to_lb = 0; // FIXME: add method + $border1 |= $diag_tl_to_rb << 30; + $border1 |= $diag_tr_to_lb << 31; + + $border2 = $this->_top_color; // Border color + $border2 |= $this->_bottom_color << 7; + $border2 |= $this->_diag_color << 14; + $border2 |= $this->_diag << 21; + $border2 |= $this->_pattern << 26; + + $header = pack("vv", $record, $length); + + $rotation = 0x00; + $biff8_options = 0x00; + $data = pack("vvvC", $ifnt, $ifmt, $style, $align); + $data .= pack("CCC", $rotation, $biff8_options, $used_attrib); + $data .= pack("VVv", $border1, $border2, $icv); + } + + return($header.$data); + } + + /** + * Generate an Excel BIFF FONT record. + * + * @return string The FONT record + */ + function getFont() + { + $dyHeight = $this->_size * 20; // Height of font (1/20 of a point) + $icv = $this->_color; // Index to color palette + $bls = $this->_bold; // Bold style + $sss = $this->_font_script; // Superscript/subscript + $uls = $this->_underline; // Underline + $bFamily = $this->_font_family; // Font family + $bCharSet = $this->_font_charset; // Character set + $encoding = 0; // TODO: Unicode support + + $cch = strlen($this->_font_name); // Length of font name + $record = 0x31; // Record identifier + if ($this->_BIFF_version == 0x0500) { + $length = 0x0F + $cch; // Record length + } + elseif ($this->_BIFF_version == 0x0600) { + $length = 0x10 + $cch; + } + $reserved = 0x00; // Reserved + $grbit = 0x00; // Font attributes + if ($this->_italic) { + $grbit |= 0x02; + } + if ($this->_font_strikeout) { + $grbit |= 0x08; + } + if ($this->_font_outline) { + $grbit |= 0x10; + } + if ($this->_font_shadow) { + $grbit |= 0x20; + } + + $header = pack("vv", $record, $length); + if ($this->_BIFF_version == 0x0500) { + $data = pack("vvvvvCCCCC", $dyHeight, $grbit, $icv, $bls, + $sss, $uls, $bFamily, + $bCharSet, $reserved, $cch); + } + elseif ($this->_BIFF_version == 0x0600) { + $data = pack("vvvvvCCCCCC", $dyHeight, $grbit, $icv, $bls, + $sss, $uls, $bFamily, + $bCharSet, $reserved, $cch, $encoding); + } + return($header . $data. $this->_font_name); + } + + /** + * Returns a unique hash key for a font. + * Used by Spreadsheet_Excel_Writer_Workbook::_storeAllFonts() + * + * The elements that form the key are arranged to increase the probability of + * generating a unique key. Elements that hold a large range of numbers + * (eg. _color) are placed between two binary elements such as _italic + * + * @return string A key for this font + */ + function getFontKey() + { + $key = "$this->_font_name$this->_size"; + $key .= "$this->_font_script$this->_underline"; + $key .= "$this->_font_strikeout$this->_bold$this->_font_outline"; + $key .= "$this->_font_family$this->_font_charset"; + $key .= "$this->_font_shadow$this->_color$this->_italic"; + $key = str_replace(" ","_",$key); + return ($key); + } + + /** + * Returns the index used by Spreadsheet_Excel_Writer_Worksheet::_XF() + * + * @return integer The index for the XF record + */ + function getXfIndex() + { + return($this->_xf_index); + } + + /** + * Used in conjunction with the set_xxx_color methods to convert a color + * string into a number. Color range is 0..63 but we will restrict it + * to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15. + * + * @access private + * @param string $name_color name of the color (i.e.: 'blue', 'red', etc..). Optional. + * @return integer The color index + */ + function _getColor($name_color = '') + { + $colors = array( + 'aqua' => 0x0F, + 'cyan' => 0x0F, + 'black' => 0x08, + 'blue' => 0x0C, + 'brown' => 0x10, + 'magenta' => 0x0E, + 'fuchsia' => 0x0E, + 'gray' => 0x17, + 'grey' => 0x17, + 'green' => 0x11, + 'lime' => 0x0B, + 'navy' => 0x12, + 'orange' => 0x35, + 'purple' => 0x14, + 'red' => 0x0A, + 'silver' => 0x16, + 'white' => 0x09, + 'yellow' => 0x0D + ); + + // Return the default color, 0x7FFF, if undef, + if($name_color == '') { + return(0x7FFF); + } + + // or the color string converted to an integer, + if(isset($colors[$name_color])) { + return($colors[$name_color]); + } + + // or the default color if string is unrecognised, + if(preg_match("/\D/",$name_color)) { + return(0x7FFF); + } + + // or an index < 8 mapped into the correct range, + if($name_color < 8) { + return($name_color + 8); + } + + // or the default color if arg is outside range, + if($name_color > 63) { + return(0x7FFF); + } + + // or an integer in the valid range + return($name_color); + } + + /** + * Set cell alignment. + * + * @access public + * @param string $location alignment for the cell ('left', 'right', etc...). + */ + function setAlign($location) + { + if (preg_match("/\d/",$location)) { + return; // Ignore numbers + } + + $location = strtolower($location); + + if ($location == 'left') { + $this->_text_h_align = 1; + } + if ($location == 'centre') { + $this->_text_h_align = 2; + } + if ($location == 'center') { + $this->_text_h_align = 2; + } + if ($location == 'right') { + $this->_text_h_align = 3; + } + if ($location == 'fill') { + $this->_text_h_align = 4; + } + if ($location == 'justify') { + $this->_text_h_align = 5; + } + if ($location == 'merge') { + $this->_text_h_align = 6; + } + if ($location == 'equal_space') { // For T.K. + $this->_text_h_align = 7; + } + if ($location == 'top') { + $this->_text_v_align = 0; + } + if ($location == 'vcentre') { + $this->_text_v_align = 1; + } + if ($location == 'vcenter') { + $this->_text_v_align = 1; + } + if ($location == 'bottom') { + $this->_text_v_align = 2; + } + if ($location == 'vjustify') { + $this->_text_v_align = 3; + } + if ($location == 'vequal_space') { // For T.K. + $this->_text_v_align = 4; + } + } + + /** + * This is an alias for the unintuitive setAlign('merge') + * + * @access public + */ + function setMerge() + { + $this->setAlign('merge'); + } + + /** + * Sets the boldness of the text. + * Bold has a range 100..1000. + * 0 (400) is normal. 1 (700) is bold. + * + * @access public + * @param integer $weight Weight for the text, 0 maps to 400 (normal text), + 1 maps to 700 (bold text). Valid range is: 100-1000. + It's Optional, default is 1 (bold). + */ + function setBold($weight = 1) + { + if($weight == 1) { + $weight = 0x2BC; // Bold text + } + if($weight == 0) { + $weight = 0x190; // Normal text + } + if($weight < 0x064) { + $weight = 0x190; // Lower bound + } + if($weight > 0x3E8) { + $weight = 0x190; // Upper bound + } + $this->_bold = $weight; + } + + + /************************************ + * FUNCTIONS FOR SETTING CELLS BORDERS + */ + + /** + * Sets the width for the bottom border of the cell + * + * @access public + * @param integer $style style of the cell border. 1 => thin, 2 => thick. + */ + function setBottom($style) + { + $this->_bottom = $style; + } + + /** + * Sets the width for the top border of the cell + * + * @access public + * @param integer $style style of the cell top border. 1 => thin, 2 => thick. + */ + function setTop($style) + { + $this->_top = $style; + } + + /** + * Sets the width for the left border of the cell + * + * @access public + * @param integer $style style of the cell left border. 1 => thin, 2 => thick. + */ + function setLeft($style) + { + $this->_left = $style; + } + + /** + * Sets the width for the right border of the cell + * + * @access public + * @param integer $style style of the cell right border. 1 => thin, 2 => thick. + */ + function setRight($style) + { + $this->_right = $style; + } + + + /** + * Set cells borders to the same style + * + * @access public + * @param integer $style style to apply for all cell borders. 1 => thin, 2 => thick. + */ + function setBorder($style) + { + $this->setBottom($style); + $this->setTop($style); + $this->setLeft($style); + $this->setRight($style); + } + + + /******************************************* + * FUNCTIONS FOR SETTING CELLS BORDERS COLORS + */ + + /** + * Sets all the cell's borders to the same color + * + * @access public + * @param mixed $color The color we are setting. Either a string (like 'blue'), + * or an integer (range is [8...63]). + */ + function setBorderColor($color) + { + $this->setBottomColor($color); + $this->setTopColor($color); + $this->setLeftColor($color); + $this->setRightColor($color); + } + + /** + * Sets the cell's bottom border color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setBottomColor($color) + { + $value = $this->_getColor($color); + $this->_bottom_color = $value; + } + + /** + * Sets the cell's top border color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setTopColor($color) + { + $value = $this->_getColor($color); + $this->_top_color = $value; + } + + /** + * Sets the cell's left border color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setLeftColor($color) + { + $value = $this->_getColor($color); + $this->_left_color = $value; + } + + /** + * Sets the cell's right border color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setRightColor($color) + { + $value = $this->_getColor($color); + $this->_right_color = $value; + } + + + /** + * Sets the cell's foreground color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setFgColor($color) + { + $value = $this->_getColor($color); + $this->_fg_color = $value; + if ($this->_pattern == 0) { // force color to be seen + $this->_pattern = 1; + } + } + + /** + * Sets the cell's background color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setBgColor($color) + { + $value = $this->_getColor($color); + $this->_bg_color = $value; + if ($this->_pattern == 0) { // force color to be seen + $this->_pattern = 1; + } + } + + /** + * Sets the cell's color + * + * @access public + * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]). + */ + function setColor($color) + { + $value = $this->_getColor($color); + $this->_color = $value; + } + + /** + * Sets the fill pattern attribute of a cell + * + * @access public + * @param integer $arg Optional. Defaults to 1. Meaningful values are: 0-18, + * 0 meaning no background. + */ + function setPattern($arg = 1) + { + $this->_pattern = $arg; + } + + /** + * Sets the underline of the text + * + * @access public + * @param integer $underline The value for underline. Possible values are: + * 1 => underline, 2 => double underline. + */ + function setUnderline($underline) + { + $this->_underline = $underline; + } + + /** + * Sets the font style as italic + * + * @access public + */ + function setItalic() + { + $this->_italic = 1; + } + + /** + * Sets the font size + * + * @access public + * @param integer $size The font size (in pixels I think). + */ + function setSize($size) + { + $this->_size = $size; + } + + /** + * Sets text wrapping + * + * @access public + */ + function setTextWrap() + { + $this->_text_wrap = 1; + } + + /** + * Sets the orientation of the text + * + * @access public + * @param integer $angle The rotation angle for the text (clockwise). Possible + values are: 0, 90, 270 and -1 for stacking top-to-bottom. + */ + function setTextRotation($angle) + { + switch ($angle) + { + case 0: + $this->_rotation = 0; + break; + case 90: + $this->_rotation = 3; + break; + case 270: + $this->_rotation = 2; + break; + case -1: + $this->_rotation = 1; + break; + default : + return $this->raiseError("Invalid value for angle.". + " Possible values are: 0, 90, 270 and -1 ". + "for stacking top-to-bottom."); + $this->_rotation = 0; + break; + } + } + + /** + * Sets the numeric format. + * It can be date, time, currency, etc... + * + * @access public + * @param integer $num_format The numeric format. + */ + function setNumFormat($num_format) + { + $this->_num_format = $num_format; + } + + /** + * Sets font as strikeout. + * + * @access public + */ + function setStrikeOut() + { + $this->_font_strikeout = 1; + } + + /** + * Sets outlining for a font. + * + * @access public + */ + function setOutLine() + { + $this->_font_outline = 1; + } + + /** + * Sets font as shadow. + * + * @access public + */ + function setShadow() + { + $this->_font_shadow = 1; + } + + /** + * Sets the script type of the text + * + * @access public + * @param integer $script The value for script type. Possible values are: + * 1 => superscript, 2 => subscript. + */ + function setScript($script) + { + $this->_font_script = $script; + } + + /** + * Locks a cell. + * + * @access public + */ + function setLocked() + { + $this->_locked = 1; + } + + /** + * Unlocks a cell. Useful for unprotecting particular cells of a protected sheet. + * + * @access public + */ + function setUnLocked() + { + $this->_locked = 0; + } + + /** + * Sets the font family name. + * + * @access public + * @param string $fontfamily The font family name. Possible values are: + * 'Times New Roman', 'Arial', 'Courier'. + */ + function setFontFamily($font_family) + { + $this->_font_name = $font_family; + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Parser.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Parser.php new file mode 100644 index 000000000..9e5866cb8 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Parser.php @@ -0,0 +1,1760 @@ +" +*/ +define('SPREADSHEET_EXCEL_WRITER_GT',">"); + +/** +* @const SPREADSHEET_EXCEL_WRITER_LT token identifier for character "<" +*/ +define('SPREADSHEET_EXCEL_WRITER_LT',"<"); + +/** +* @const SPREADSHEET_EXCEL_WRITER_LE token identifier for character "<=" +*/ +define('SPREADSHEET_EXCEL_WRITER_LE',"<="); + +/** +* @const SPREADSHEET_EXCEL_WRITER_GE token identifier for character ">=" +*/ +define('SPREADSHEET_EXCEL_WRITER_GE',">="); + +/** +* @const SPREADSHEET_EXCEL_WRITER_EQ token identifier for character "=" +*/ +define('SPREADSHEET_EXCEL_WRITER_EQ',"="); + +/** +* @const SPREADSHEET_EXCEL_WRITER_NE token identifier for character "<>" +*/ +define('SPREADSHEET_EXCEL_WRITER_NE',"<>"); + + +require_once('PEAR.php'); + +/** +* Class for parsing Excel formulas +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer_Parser extends PEAR +{ + /** + * The index of the character we are currently looking at + * @var integer + */ + var $_current_char; + + /** + * The token we are working on. + * @var string + */ + var $_current_token; + + /** + * The formula to parse + * @var string + */ + var $_formula; + + /** + * The character ahead of the current char + * @var string + */ + var $_lookahead; + + /** + * The parse tree to be generated + * @var string + */ + var $_parse_tree; + + /** + * The byte order. 1 => big endian, 0 => little endian. + * @var integer + */ + var $_byte_order; + + /** + * Array of external sheets + * @var array + */ + var $_ext_sheets; + + /** + * Array of sheet references in the form of REF structures + * @var array + */ + var $_references; + + /** + * The BIFF version for the workbook + * @var integer + */ + var $_BIFF_version; + + /** + * The class constructor + * + * @param integer $byte_order The byte order (Little endian or Big endian) of the architecture + (optional). 1 => big endian, 0 (default) little endian. + */ + function Spreadsheet_Excel_Writer_Parser($byte_order, $biff_version) + { + $this->_current_char = 0; + $this->_BIFF_version = $biff_version; + $this->_current_token = ''; // The token we are working on. + $this->_formula = ""; // The formula to parse. + $this->_lookahead = ''; // The character ahead of the current char. + $this->_parse_tree = ''; // The parse tree to be generated. + $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's + $this->_byte_order = $byte_order; // Little Endian or Big Endian + $this->_ext_sheets = array(); + $this->_references = array(); + } + + /** + * Initialize the ptg and function hashes. + * + * @access private + */ + function _initializeHashes() + { + // The Excel ptg indices + $this->ptg = array( + 'ptgExp' => 0x01, + 'ptgTbl' => 0x02, + 'ptgAdd' => 0x03, + 'ptgSub' => 0x04, + 'ptgMul' => 0x05, + 'ptgDiv' => 0x06, + 'ptgPower' => 0x07, + 'ptgConcat' => 0x08, + 'ptgLT' => 0x09, + 'ptgLE' => 0x0A, + 'ptgEQ' => 0x0B, + 'ptgGE' => 0x0C, + 'ptgGT' => 0x0D, + 'ptgNE' => 0x0E, + 'ptgIsect' => 0x0F, + 'ptgUnion' => 0x10, + 'ptgRange' => 0x11, + 'ptgUplus' => 0x12, + 'ptgUminus' => 0x13, + 'ptgPercent' => 0x14, + 'ptgParen' => 0x15, + 'ptgMissArg' => 0x16, + 'ptgStr' => 0x17, + 'ptgAttr' => 0x19, + 'ptgSheet' => 0x1A, + 'ptgEndSheet' => 0x1B, + 'ptgErr' => 0x1C, + 'ptgBool' => 0x1D, + 'ptgInt' => 0x1E, + 'ptgNum' => 0x1F, + 'ptgArray' => 0x20, + 'ptgFunc' => 0x21, + 'ptgFuncVar' => 0x22, + 'ptgName' => 0x23, + 'ptgRef' => 0x24, + 'ptgArea' => 0x25, + 'ptgMemArea' => 0x26, + 'ptgMemErr' => 0x27, + 'ptgMemNoMem' => 0x28, + 'ptgMemFunc' => 0x29, + 'ptgRefErr' => 0x2A, + 'ptgAreaErr' => 0x2B, + 'ptgRefN' => 0x2C, + 'ptgAreaN' => 0x2D, + 'ptgMemAreaN' => 0x2E, + 'ptgMemNoMemN' => 0x2F, + 'ptgNameX' => 0x39, + 'ptgRef3d' => 0x3A, + 'ptgArea3d' => 0x3B, + 'ptgRefErr3d' => 0x3C, + 'ptgAreaErr3d' => 0x3D, + 'ptgArrayV' => 0x40, + 'ptgFuncV' => 0x41, + 'ptgFuncVarV' => 0x42, + 'ptgNameV' => 0x43, + 'ptgRefV' => 0x44, + 'ptgAreaV' => 0x45, + 'ptgMemAreaV' => 0x46, + 'ptgMemErrV' => 0x47, + 'ptgMemNoMemV' => 0x48, + 'ptgMemFuncV' => 0x49, + 'ptgRefErrV' => 0x4A, + 'ptgAreaErrV' => 0x4B, + 'ptgRefNV' => 0x4C, + 'ptgAreaNV' => 0x4D, + 'ptgMemAreaNV' => 0x4E, + 'ptgMemNoMemN' => 0x4F, + 'ptgFuncCEV' => 0x58, + 'ptgNameXV' => 0x59, + 'ptgRef3dV' => 0x5A, + 'ptgArea3dV' => 0x5B, + 'ptgRefErr3dV' => 0x5C, + 'ptgAreaErr3d' => 0x5D, + 'ptgArrayA' => 0x60, + 'ptgFuncA' => 0x61, + 'ptgFuncVarA' => 0x62, + 'ptgNameA' => 0x63, + 'ptgRefA' => 0x64, + 'ptgAreaA' => 0x65, + 'ptgMemAreaA' => 0x66, + 'ptgMemErrA' => 0x67, + 'ptgMemNoMemA' => 0x68, + 'ptgMemFuncA' => 0x69, + 'ptgRefErrA' => 0x6A, + 'ptgAreaErrA' => 0x6B, + 'ptgRefNA' => 0x6C, + 'ptgAreaNA' => 0x6D, + 'ptgMemAreaNA' => 0x6E, + 'ptgMemNoMemN' => 0x6F, + 'ptgFuncCEA' => 0x78, + 'ptgNameXA' => 0x79, + 'ptgRef3dA' => 0x7A, + 'ptgArea3dA' => 0x7B, + 'ptgRefErr3dA' => 0x7C, + 'ptgAreaErr3d' => 0x7D + ); + + // Thanks to Michael Meeks and Gnumeric for the initial arg values. + // + // The following hash was generated by "function_locale.pl" in the distro. + // Refer to function_locale.pl for non-English function names. + // + // The array elements are as follow: + // ptg: The Excel function ptg code. + // args: The number of arguments that the function takes: + // >=0 is a fixed number of arguments. + // -1 is a variable number of arguments. + // class: The reference, value or array class of the function args. + // vol: The function is volatile. + // + $this->_functions = array( + // function ptg args class vol + 'COUNT' => array( 0, -1, 0, 0 ), + 'IF' => array( 1, -1, 1, 0 ), + 'ISNA' => array( 2, 1, 1, 0 ), + 'ISERROR' => array( 3, 1, 1, 0 ), + 'SUM' => array( 4, -1, 0, 0 ), + 'AVERAGE' => array( 5, -1, 0, 0 ), + 'MIN' => array( 6, -1, 0, 0 ), + 'MAX' => array( 7, -1, 0, 0 ), + 'ROW' => array( 8, -1, 0, 0 ), + 'COLUMN' => array( 9, -1, 0, 0 ), + 'NA' => array( 10, 0, 0, 0 ), + 'NPV' => array( 11, -1, 1, 0 ), + 'STDEV' => array( 12, -1, 0, 0 ), + 'DOLLAR' => array( 13, -1, 1, 0 ), + 'FIXED' => array( 14, -1, 1, 0 ), + 'SIN' => array( 15, 1, 1, 0 ), + 'COS' => array( 16, 1, 1, 0 ), + 'TAN' => array( 17, 1, 1, 0 ), + 'ATAN' => array( 18, 1, 1, 0 ), + 'PI' => array( 19, 0, 1, 0 ), + 'SQRT' => array( 20, 1, 1, 0 ), + 'EXP' => array( 21, 1, 1, 0 ), + 'LN' => array( 22, 1, 1, 0 ), + 'LOG10' => array( 23, 1, 1, 0 ), + 'ABS' => array( 24, 1, 1, 0 ), + 'INT' => array( 25, 1, 1, 0 ), + 'SIGN' => array( 26, 1, 1, 0 ), + 'ROUND' => array( 27, 2, 1, 0 ), + 'LOOKUP' => array( 28, -1, 0, 0 ), + 'INDEX' => array( 29, -1, 0, 1 ), + 'REPT' => array( 30, 2, 1, 0 ), + 'MID' => array( 31, 3, 1, 0 ), + 'LEN' => array( 32, 1, 1, 0 ), + 'VALUE' => array( 33, 1, 1, 0 ), + 'TRUE' => array( 34, 0, 1, 0 ), + 'FALSE' => array( 35, 0, 1, 0 ), + 'AND' => array( 36, -1, 0, 0 ), + 'OR' => array( 37, -1, 0, 0 ), + 'NOT' => array( 38, 1, 1, 0 ), + 'MOD' => array( 39, 2, 1, 0 ), + 'DCOUNT' => array( 40, 3, 0, 0 ), + 'DSUM' => array( 41, 3, 0, 0 ), + 'DAVERAGE' => array( 42, 3, 0, 0 ), + 'DMIN' => array( 43, 3, 0, 0 ), + 'DMAX' => array( 44, 3, 0, 0 ), + 'DSTDEV' => array( 45, 3, 0, 0 ), + 'VAR' => array( 46, -1, 0, 0 ), + 'DVAR' => array( 47, 3, 0, 0 ), + 'TEXT' => array( 48, 2, 1, 0 ), + 'LINEST' => array( 49, -1, 0, 0 ), + 'TREND' => array( 50, -1, 0, 0 ), + 'LOGEST' => array( 51, -1, 0, 0 ), + 'GROWTH' => array( 52, -1, 0, 0 ), + 'PV' => array( 56, -1, 1, 0 ), + 'FV' => array( 57, -1, 1, 0 ), + 'NPER' => array( 58, -1, 1, 0 ), + 'PMT' => array( 59, -1, 1, 0 ), + 'RATE' => array( 60, -1, 1, 0 ), + 'MIRR' => array( 61, 3, 0, 0 ), + 'IRR' => array( 62, -1, 0, 0 ), + 'RAND' => array( 63, 0, 1, 1 ), + 'MATCH' => array( 64, -1, 0, 0 ), + 'DATE' => array( 65, 3, 1, 0 ), + 'TIME' => array( 66, 3, 1, 0 ), + 'DAY' => array( 67, 1, 1, 0 ), + 'MONTH' => array( 68, 1, 1, 0 ), + 'YEAR' => array( 69, 1, 1, 0 ), + 'WEEKDAY' => array( 70, -1, 1, 0 ), + 'HOUR' => array( 71, 1, 1, 0 ), + 'MINUTE' => array( 72, 1, 1, 0 ), + 'SECOND' => array( 73, 1, 1, 0 ), + 'NOW' => array( 74, 0, 1, 1 ), + 'AREAS' => array( 75, 1, 0, 1 ), + 'ROWS' => array( 76, 1, 0, 1 ), + 'COLUMNS' => array( 77, 1, 0, 1 ), + 'OFFSET' => array( 78, -1, 0, 1 ), + 'SEARCH' => array( 82, -1, 1, 0 ), + 'TRANSPOSE' => array( 83, 1, 1, 0 ), + 'TYPE' => array( 86, 1, 1, 0 ), + 'ATAN2' => array( 97, 2, 1, 0 ), + 'ASIN' => array( 98, 1, 1, 0 ), + 'ACOS' => array( 99, 1, 1, 0 ), + 'CHOOSE' => array( 100, -1, 1, 0 ), + 'HLOOKUP' => array( 101, -1, 0, 0 ), + 'VLOOKUP' => array( 102, -1, 0, 0 ), + 'ISREF' => array( 105, 1, 0, 0 ), + 'LOG' => array( 109, -1, 1, 0 ), + 'CHAR' => array( 111, 1, 1, 0 ), + 'LOWER' => array( 112, 1, 1, 0 ), + 'UPPER' => array( 113, 1, 1, 0 ), + 'PROPER' => array( 114, 1, 1, 0 ), + 'LEFT' => array( 115, -1, 1, 0 ), + 'RIGHT' => array( 116, -1, 1, 0 ), + 'EXACT' => array( 117, 2, 1, 0 ), + 'TRIM' => array( 118, 1, 1, 0 ), + 'REPLACE' => array( 119, 4, 1, 0 ), + 'SUBSTITUTE' => array( 120, -1, 1, 0 ), + 'CODE' => array( 121, 1, 1, 0 ), + 'FIND' => array( 124, -1, 1, 0 ), + 'CELL' => array( 125, -1, 0, 1 ), + 'ISERR' => array( 126, 1, 1, 0 ), + 'ISTEXT' => array( 127, 1, 1, 0 ), + 'ISNUMBER' => array( 128, 1, 1, 0 ), + 'ISBLANK' => array( 129, 1, 1, 0 ), + 'T' => array( 130, 1, 0, 0 ), + 'N' => array( 131, 1, 0, 0 ), + 'DATEVALUE' => array( 140, 1, 1, 0 ), + 'TIMEVALUE' => array( 141, 1, 1, 0 ), + 'SLN' => array( 142, 3, 1, 0 ), + 'SYD' => array( 143, 4, 1, 0 ), + 'DDB' => array( 144, -1, 1, 0 ), + 'INDIRECT' => array( 148, -1, 1, 1 ), + 'CALL' => array( 150, -1, 1, 0 ), + 'CLEAN' => array( 162, 1, 1, 0 ), + 'MDETERM' => array( 163, 1, 2, 0 ), + 'MINVERSE' => array( 164, 1, 2, 0 ), + 'MMULT' => array( 165, 2, 2, 0 ), + 'IPMT' => array( 167, -1, 1, 0 ), + 'PPMT' => array( 168, -1, 1, 0 ), + 'COUNTA' => array( 169, -1, 0, 0 ), + 'PRODUCT' => array( 183, -1, 0, 0 ), + 'FACT' => array( 184, 1, 1, 0 ), + 'DPRODUCT' => array( 189, 3, 0, 0 ), + 'ISNONTEXT' => array( 190, 1, 1, 0 ), + 'STDEVP' => array( 193, -1, 0, 0 ), + 'VARP' => array( 194, -1, 0, 0 ), + 'DSTDEVP' => array( 195, 3, 0, 0 ), + 'DVARP' => array( 196, 3, 0, 0 ), + 'TRUNC' => array( 197, -1, 1, 0 ), + 'ISLOGICAL' => array( 198, 1, 1, 0 ), + 'DCOUNTA' => array( 199, 3, 0, 0 ), + 'ROUNDUP' => array( 212, 2, 1, 0 ), + 'ROUNDDOWN' => array( 213, 2, 1, 0 ), + 'RANK' => array( 216, -1, 0, 0 ), + 'ADDRESS' => array( 219, -1, 1, 0 ), + 'DAYS360' => array( 220, -1, 1, 0 ), + 'TODAY' => array( 221, 0, 1, 1 ), + 'VDB' => array( 222, -1, 1, 0 ), + 'MEDIAN' => array( 227, -1, 0, 0 ), + 'SUMPRODUCT' => array( 228, -1, 2, 0 ), + 'SINH' => array( 229, 1, 1, 0 ), + 'COSH' => array( 230, 1, 1, 0 ), + 'TANH' => array( 231, 1, 1, 0 ), + 'ASINH' => array( 232, 1, 1, 0 ), + 'ACOSH' => array( 233, 1, 1, 0 ), + 'ATANH' => array( 234, 1, 1, 0 ), + 'DGET' => array( 235, 3, 0, 0 ), + 'INFO' => array( 244, 1, 1, 1 ), + 'DB' => array( 247, -1, 1, 0 ), + 'FREQUENCY' => array( 252, 2, 0, 0 ), + 'ERROR.TYPE' => array( 261, 1, 1, 0 ), + 'REGISTER.ID' => array( 267, -1, 1, 0 ), + 'AVEDEV' => array( 269, -1, 0, 0 ), + 'BETADIST' => array( 270, -1, 1, 0 ), + 'GAMMALN' => array( 271, 1, 1, 0 ), + 'BETAINV' => array( 272, -1, 1, 0 ), + 'BINOMDIST' => array( 273, 4, 1, 0 ), + 'CHIDIST' => array( 274, 2, 1, 0 ), + 'CHIINV' => array( 275, 2, 1, 0 ), + 'COMBIN' => array( 276, 2, 1, 0 ), + 'CONFIDENCE' => array( 277, 3, 1, 0 ), + 'CRITBINOM' => array( 278, 3, 1, 0 ), + 'EVEN' => array( 279, 1, 1, 0 ), + 'EXPONDIST' => array( 280, 3, 1, 0 ), + 'FDIST' => array( 281, 3, 1, 0 ), + 'FINV' => array( 282, 3, 1, 0 ), + 'FISHER' => array( 283, 1, 1, 0 ), + 'FISHERINV' => array( 284, 1, 1, 0 ), + 'FLOOR' => array( 285, 2, 1, 0 ), + 'GAMMADIST' => array( 286, 4, 1, 0 ), + 'GAMMAINV' => array( 287, 3, 1, 0 ), + 'CEILING' => array( 288, 2, 1, 0 ), + 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), + 'LOGNORMDIST' => array( 290, 3, 1, 0 ), + 'LOGINV' => array( 291, 3, 1, 0 ), + 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), + 'NORMDIST' => array( 293, 4, 1, 0 ), + 'NORMSDIST' => array( 294, 1, 1, 0 ), + 'NORMINV' => array( 295, 3, 1, 0 ), + 'NORMSINV' => array( 296, 1, 1, 0 ), + 'STANDARDIZE' => array( 297, 3, 1, 0 ), + 'ODD' => array( 298, 1, 1, 0 ), + 'PERMUT' => array( 299, 2, 1, 0 ), + 'POISSON' => array( 300, 3, 1, 0 ), + 'TDIST' => array( 301, 3, 1, 0 ), + 'WEIBULL' => array( 302, 4, 1, 0 ), + 'SUMXMY2' => array( 303, 2, 2, 0 ), + 'SUMX2MY2' => array( 304, 2, 2, 0 ), + 'SUMX2PY2' => array( 305, 2, 2, 0 ), + 'CHITEST' => array( 306, 2, 2, 0 ), + 'CORREL' => array( 307, 2, 2, 0 ), + 'COVAR' => array( 308, 2, 2, 0 ), + 'FORECAST' => array( 309, 3, 2, 0 ), + 'FTEST' => array( 310, 2, 2, 0 ), + 'INTERCEPT' => array( 311, 2, 2, 0 ), + 'PEARSON' => array( 312, 2, 2, 0 ), + 'RSQ' => array( 313, 2, 2, 0 ), + 'STEYX' => array( 314, 2, 2, 0 ), + 'SLOPE' => array( 315, 2, 2, 0 ), + 'TTEST' => array( 316, 4, 2, 0 ), + 'PROB' => array( 317, -1, 2, 0 ), + 'DEVSQ' => array( 318, -1, 0, 0 ), + 'GEOMEAN' => array( 319, -1, 0, 0 ), + 'HARMEAN' => array( 320, -1, 0, 0 ), + 'SUMSQ' => array( 321, -1, 0, 0 ), + 'KURT' => array( 322, -1, 0, 0 ), + 'SKEW' => array( 323, -1, 0, 0 ), + 'ZTEST' => array( 324, -1, 0, 0 ), + 'LARGE' => array( 325, 2, 0, 0 ), + 'SMALL' => array( 326, 2, 0, 0 ), + 'QUARTILE' => array( 327, 2, 0, 0 ), + 'PERCENTILE' => array( 328, 2, 0, 0 ), + 'PERCENTRANK' => array( 329, -1, 0, 0 ), + 'MODE' => array( 330, -1, 2, 0 ), + 'TRIMMEAN' => array( 331, 2, 0, 0 ), + 'TINV' => array( 332, 2, 1, 0 ), + 'CONCATENATE' => array( 336, -1, 1, 0 ), + 'POWER' => array( 337, 2, 1, 0 ), + 'RADIANS' => array( 342, 1, 1, 0 ), + 'DEGREES' => array( 343, 1, 1, 0 ), + 'SUBTOTAL' => array( 344, -1, 0, 0 ), + 'SUMIF' => array( 345, -1, 0, 0 ), + 'COUNTIF' => array( 346, 2, 0, 0 ), + 'COUNTBLANK' => array( 347, 1, 0, 0 ), + 'ROMAN' => array( 354, -1, 1, 0 ) + ); + } + + /** + * Convert a token to the proper ptg value. + * + * @access private + * @param mixed $token The token to convert. + * @return mixed the converted token on success. PEAR_Error if the token + * is not recognized + */ + function _convert($token) + { + if (preg_match("/^\"[^\"]{0,255}\"$/", $token)) + { + return $this->_convertString($token); + } + elseif (is_numeric($token)) + { + return $this->_convertNumber($token); + } + // match references like A1 or $A$1 + elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) + { + return $this->_convertRef2d($token); + } + // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 + elseif (preg_match("/^\w+(\:\w+)?\![A-Ia-i]?[A-Za-z](\d+)$/",$token)) + { + return $this->_convertRef3d($token); + } + // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 + elseif (preg_match("/^'\w+(\:\w+)?'\![A-Ia-i]?[A-Za-z](\d+)$/",$token)) + { + return $this->_convertRef3d($token); + } + // match ranges like A1:B2 + elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token)) + { + return $this->_convertRange2d($token); + } + // match ranges like A1..B2 + elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token)) + { + return $this->_convertRange2d($token); + } + // match external ranges like Sheet1!A1 or Sheet1:Sheet2!A1:B2 + elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token)) + { + return $this->_convertRange3d($token); + } + // match external ranges like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1:B2 + elseif (preg_match("/^'\w+(\:\w+)?'\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token)) + { + return $this->_convertRange3d($token); + } + elseif (isset($this->ptg[$token])) // operators (including parentheses) + { + return pack("C", $this->ptg[$token]); + } + // commented so argument number can be processed correctly. See toReversePolish(). + /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) + { + return($this->_convertFunction($token,$this->_func_args)); + }*/ + // if it's an argument, ignore the token (the argument remains) + elseif ($token == 'arg') + { + return ''; + } + // TODO: use real error codes + return $this->raiseError("Unknown token $token"); + } + + /** + * Convert a number token to ptgInt or ptgNum + * + * @access private + * @param mixed $num an integer or double for conversion to its ptg value + */ + function _convertNumber($num) + { + // Integer in the range 0..2**16-1 + if ((preg_match("/^\d+$/",$num)) and ($num <= 65535)) { + return pack("Cv", $this->ptg['ptgInt'], $num); + } + else // A float + { + if ($this->_byte_order) { // if it's Big Endian + $num = strrev($num); + } + return pack("Cd", $this->ptg['ptgNum'], $num); + } + } + + /** + * Convert a string token to ptgStr + * + * @access private + * @param string $string A string for conversion to its ptg value. + * @return mixed the converted token on success. PEAR_Error if the string + * is longer than 255 characters. + */ + function _convertString($string) + { + // chop away beggining and ending quotes + $string = substr($string, 1, strlen($string) - 2); + if (strlen($string) > 255) { + return $this->raiseError("String is too long"); + } + if ($this->_BIFF_version == 0x0500) { + return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string; + } + elseif ($this->_BIFF_version == 0x0600) { + $encoding = 0; // TODO: Unicode support + return pack("CCC", $this->ptg['ptgStr'], strlen($string), $encoding).$string; + } + } + + /** + * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of + * args that it takes. + * + * @access private + * @param string $token The name of the function for convertion to ptg value. + * @param integer $num_args The number of arguments the function receives. + * @return string The packed ptg for the function + */ + function _convertFunction($token, $num_args) + { + $args = $this->_functions[$token][1]; + $volatile = $this->_functions[$token][3]; + + // Fixed number of args eg. TIME($i,$j,$k). + if ($args >= 0) { + return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); + } + // Variable number of args eg. SUM($i,$j,$k, ..). + if ($args == -1) { + return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); + } + } + + /** + * Convert an Excel range such as A1:D4 to a ptgRefV. + * + * @access private + * @param string $range An Excel range in the A1:A2 or A1..A2 format. + */ + function _convertRange2d($range) + { + $class = 2; // as far as I know, this is magick. + + // Split the range into 2 cell refs + if (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\:([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) { + list($cell1, $cell2) = split(':', $range); + } + elseif (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\.\.([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) { + list($cell1, $cell2) = split('\.\.', $range); + + } + else { + // TODO: use real error codes + return $this->raiseError("Unknown range separator", 0, PEAR_ERROR_DIE); + } + + // Convert the cell references + $cell_array1 = $this->_cellToPackedRowcol($cell1); + if (PEAR::isError($cell_array1)) { + return $cell_array1; + } + list($row1, $col1) = $cell_array1; + $cell_array2 = $this->_cellToPackedRowcol($cell2); + if (PEAR::isError($cell_array2)) { + return $cell_array2; + } + list($row2, $col2) = $cell_array2; + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea']); + } + elseif ($class == 1) { + $ptgArea = pack("C", $this->ptg['ptgAreaV']); + } + elseif ($class == 2) { + $ptgArea = pack("C", $this->ptg['ptgAreaA']); + } + else { + // TODO: use real error codes + return $this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); + } + return $ptgArea . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to + * a ptgArea3d. + * + * @access private + * @param string $token An Excel range in the Sheet1!A1:A2 format. + * @return mixed The packed ptgArea3d token on success, PEAR_Error on failure. + */ + function _convertRange3d($token) + { + $class = 2; // as far as I know, this is magick. + + // Split the ref at the ! symbol + list($ext_ref, $range) = split('!', $token); + + // Convert the external reference part (different for BIFF8) + if ($this->_BIFF_version == 0x0500) { + $ext_ref = $this->_packExtRef($ext_ref); + if (PEAR::isError($ext_ref)) { + return $ext_ref; + } + } + elseif ($this->_BIFF_version == 0x0600) { + $ext_ref = $this->_getRefIndex($ext_ref); + if (PEAR::isError($ext_ref)) { + return $ext_ref; + } + } + + // Split the range into 2 cell refs + list($cell1, $cell2) = split(':', $range); + + // Convert the cell references + if (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/", $cell1)) + { + $cell_array1 = $this->_cellToPackedRowcol($cell1); + if (PEAR::isError($cell_array1)) { + return $cell_array1; + } + list($row1, $col1) = $cell_array1; + $cell_array2 = $this->_cellToPackedRowcol($cell2); + if (PEAR::isError($cell_array2)) { + return $cell_array2; + } + list($row2, $col2) = $cell_array2; + } + else { // It's a rows range (like 26:27) + $cells_array = $this->_rangeToPackedRange($cell1.':'.$cell2); + if (PEAR::isError($cells_array)) { + return $cells_array; + } + list($row1, $col1, $row2, $col2) = $cells_array; + } + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea3d']); + } + elseif ($class == 1) { + $ptgArea = pack("C", $this->ptg['ptgArea3dV']); + } + elseif ($class == 2) { + $ptgArea = pack("C", $this->ptg['ptgArea3dA']); + } + else { + return $this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); + } + + return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. + * + * @access private + * @param string $cell An Excel cell reference + * @return string The cell in packed() format with the corresponding ptg + */ + function _convertRef2d($cell) + { + $class = 2; // as far as I know, this is magick. + + // Convert the cell reference + $cell_array = $this->_cellToPackedRowcol($cell); + if (PEAR::isError($cell_array)) { + return $cell_array; + } + list($row, $col) = $cell_array; + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgRef = pack("C", $this->ptg['ptgRef']); + } + elseif ($class == 1) { + $ptgRef = pack("C", $this->ptg['ptgRefV']); + } + elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRefA']); + } + else { + // TODO: use real error codes + return $this->raiseError("Unknown class $class"); + } + return $ptgRef.$row.$col; + } + + /** + * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a + * ptgRef3d. + * + * @access private + * @param string $cell An Excel cell reference + * @return mixed The packed ptgRef3d token on success, PEAR_Error on failure. + */ + function _convertRef3d($cell) + { + $class = 2; // as far as I know, this is magick. + + // Split the ref at the ! symbol + list($ext_ref, $cell) = split('!', $cell); + + // Convert the external reference part (different for BIFF8) + if ($this->_BIFF_version == 0x0500) { + $ext_ref = $this->_packExtRef($ext_ref); + if (PEAR::isError($ext_ref)) { + return $ext_ref; + } + } + elseif ($this->_BIFF_version == 0x0600) { + $ext_ref = $this->_getRefIndex($ext_ref); + if (PEAR::isError($ext_ref)) { + return $ext_ref; + } + } + + // Convert the cell reference part + list($row, $col) = $this->_cellToPackedRowcol($cell); + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgRef = pack("C", $this->ptg['ptgRef3d']); + } + elseif ($class == 1) { + $ptgRef = pack("C", $this->ptg['ptgRef3dV']); + } + elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRef3dA']); + } + else { + return $this->raiseError("Unknown class $class", 0, PEAR_ERROR_DIE); + } + + return $ptgRef . $ext_ref. $row . $col; + } + + /** + * Convert the sheet name part of an external reference, for example "Sheet1" or + * "Sheet1:Sheet2", to a packed structure. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return string The reference index in packed() format + */ + function _packExtRef($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) + { + list($sheet_name1, $sheet_name2) = split(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + return $this->raiseError("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + return $this->raiseError("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } + else // Single sheet name only. + { + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + return $this->raiseError("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // References are stored relative to 0xFFFF. + $offset = -1 - $sheet1; + + return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); + } + + /** + * Look up the REF index that corresponds to an external sheet name + * (or range). If it doesn't exist yet add it to the workbook's references + * array. It assumes all sheet names given must exist. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return mixed The reference index in packed() format on success, + * PEAR_Error on failure + */ + function _getRefIndex($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) + { + list($sheet_name1, $sheet_name2) = split(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + return $this->raiseError("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + return $this->raiseError("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } + else // Single sheet name only. + { + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + return $this->raiseError("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // assume all references belong to this document + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); + $total_references = count($this->_references); + $index = -1; + for ($i = 0; $i < $total_references; $i++) + { + if ($ref == $this->_references[$i]) { + $index = $i; + break; + } + } + // if REF was not found add it to references array + if ($index == -1) + { + $this->_references[$total_references] = $ref; + $index = $total_references; + } + + return pack('v', $index); + } + + /** + * Look up the index that corresponds to an external sheet name. The hash of + * sheet names is updated by the addworksheet() method of the + * Spreadsheet_Excel_Writer_Workbook class. + * + * @access private + * @return integer The sheet index, -1 if the sheet was not found + */ + function _getSheetIndex($sheet_name) + { + if (!isset($this->_ext_sheets[$sheet_name])) { + return -1; + } + else { + return $this->_ext_sheets[$sheet_name]; + } + } + + /** + * This method is used to update the array of sheet names. It is + * called by the addWorksheet() method of the + * Spreadsheet_Excel_Writer_Workbook class. + * + * @access public + * @see Spreadsheet_Excel_Writer_Workbook::addWorksheet() + * @param string $name The name of the worksheet being added + * @param integer $index The index of the worksheet being added + */ + function setExtSheet($name, $index) + { + $this->_ext_sheets[$name] = $index; + } + + /** + * pack() row and column into the required 3 or 4 byte format. + * + * @access private + * @param string $cell The Excel cell reference to be packed + * @return array Array containing the row and column in packed() format + */ + function _cellToPackedRowcol($cell) + { + $cell = strtoupper($cell); + list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); + if ($col >= 256) { + return $this->raiseError("Column in: $cell greater than 255"); + } + // FIXME: change for BIFF8 + if ($row >= 16384) { + return $this->raiseError("Row in: $cell greater than 16384 "); + } + + // Set the high bits to indicate if row or col are relative. + if ($this->_BIFF_version == 0x0500) { + $row |= $col_rel << 14; + $row |= $row_rel << 15; + $col = pack('C', $col); + } + elseif ($this->_BIFF_version == 0x0600) { + $col |= $col_rel << 14; + $col |= $row_rel << 15; + $col = pack('v', $col); + } + $row = pack('v', $row); + + return array($row, $col); + } + + /** + * pack() row range into the required 3 or 4 byte format. + * Just using maximum col/rows, which is probably not the correct solution + * + * @access private + * @param string $range The Excel range to be packed + * @return array Array containing (row1,col1,row2,col2) in packed() format + */ + function _rangeToPackedRange($range) + { + preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); + // return absolute rows if there is a $ in the ref + $row1_rel = empty($match[1]) ? 1 : 0; + $row1 = $match[2]; + $row2_rel = empty($match[3]) ? 1 : 0; + $row2 = $match[4]; + // Convert 1-index to zero-index + $row1--; + $row2--; + // Trick poor inocent Excel + $col1 = 0; + $col2 = 16383; // FIXME: maximum possible value for Excel 5 (change this!!!) + + // FIXME: this changes for BIFF8 + if (($row1 >= 16384) or ($row2 >= 16384)) { + return $this->raiseError("Row in: $range greater than 16384 "); + } + + // Set the high bits to indicate if rows are relative. + if ($this->_BIFF_version == 0x0500) { + $row1 |= $row1_rel << 14; // FIXME: probably a bug + $row2 |= $row2_rel << 15; + $col1 = pack('C', $col1); + $col2 = pack('C', $col2); + } + elseif ($this->_BIFF_version == 0x0600) { + $col1 |= $row1_rel << 15; + $col2 |= $row2_rel << 15; + $col1 = pack('v', $col1); + $col2 = pack('v', $col2); + } + $row1 = pack('v', $row1); + $row2 = pack('v', $row2); + + return array($row1, $col1, $row2, $col2); + } + + /** + * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero + * indexed row and column number. Also returns two (0,1) values to indicate + * whether the row or column are relative references. + * + * @access private + * @param string $cell The Excel cell reference in A1 format. + * @return array + */ + function _cellToRowcol($cell) + { + preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); + // return absolute column if there is a $ in the ref + $col_rel = empty($match[1]) ? 1 : 0; + $col_ref = $match[2]; + $row_rel = empty($match[3]) ? 1 : 0; + $row = $match[4]; + + // Convert base26 column string to a number. + $expn = strlen($col_ref) - 1; + $col = 0; + for ($i=0; $i < strlen($col_ref); $i++) + { + $col += (ord($col_ref{$i}) - ord('A') + 1) * pow(26, $expn); + $expn--; + } + + // Convert 1-index to zero-index + $row--; + $col--; + + return array($row, $col, $row_rel, $col_rel); + } + + /** + * Advance to the next valid token. + * + * @access private + */ + function _advance() + { + $i = $this->_current_char; + // eat up white spaces + if ($i < strlen($this->_formula)) + { + while ($this->_formula{$i} == " ") { + $i++; + } + if ($i < strlen($this->_formula) - 1) { + $this->_lookahead = $this->_formula{$i+1}; + } + $token = ""; + } + while ($i < strlen($this->_formula)) + { + $token .= $this->_formula{$i}; + if ($i < strlen($this->_formula) - 1) { + $this->_lookahead = $this->_formula{$i+1}; + } + else { + $this->_lookahead = ''; + } + if ($this->_match($token) != '') + { + //if ($i < strlen($this->_formula) - 1) { + // $this->_lookahead = $this->_formula{$i+1}; + //} + $this->_current_char = $i + 1; + $this->_current_token = $token; + return 1; + } + if ($i < strlen($this->_formula) - 2) { + $this->_lookahead = $this->_formula{$i+2}; + } + // if we run out of characters _lookahead becomes empty + else { + $this->_lookahead = ''; + } + $i++; + } + //die("Lexical error ".$this->_current_char); + } + + /** + * Checks if it's a valid token. + * + * @access private + * @param mixed $token The token to check. + * @return mixed The checked token or false on failure + */ + function _match($token) + { + switch($token) + { + case SPREADSHEET_EXCEL_WRITER_ADD: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_SUB: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_MUL: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_DIV: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_OPEN: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_CLOSE: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_COMA: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_SEMICOLON: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_GT: + if ($this->_lookahead == '=') { // it's a GE token + break; + } + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_LT: + // it's a LE or a NE token + if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { + break; + } + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_GE: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_LE: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_EQ: + return $token; + break; + case SPREADSHEET_EXCEL_WRITER_NE: + return $token; + break; + default: + // if it's a reference + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and + !ereg("[0-9]",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.') and + ($this->_lookahead != '!')) + { + return $token; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) + elseif (preg_match("/^\w+(\:\w+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) + elseif (preg_match("/^'\w+(\:\w+)?'\![A-Ia-i]?[A-Za-z][0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // if it's a range (A1:A2) + elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead)) + { + return $token; + } + // if it's a range (A1..A2) + elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead)) + { + return $token; + } + // If it's an external range like Sheet1!A1 or Sheet1:Sheet2!A1:B2 + elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead)) + { + return $token; + } + // If it's an external range like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1:B2 + elseif (preg_match("/^'\w+(\:\w+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and + !ereg("[0-9]",$this->_lookahead)) + { + return $token; + } + // If it's a number (check that it's not a sheet name or range) + elseif (is_numeric($token) and + (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and + ($this->_lookahead != '!') and ($this->_lookahead != ':')) + { + return $token; + } + // If it's a string (of maximum 255 characters) + elseif (ereg("^\"[^\"]{0,255}\"$",$token)) + { + return $token; + } + // if it's a function call + elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "(")) + { + return $token; + } + return ''; + } + } + + /** + * The parsing method. It parses a formula. + * + * @access public + * @param string $formula The formula to parse, without the initial equal + * sign (=). + * @return mixed true on success, PEAR_Error on failure + */ + function parse($formula) + { + $this->_current_char = 0; + $this->_formula = $formula; + $this->_lookahead = $formula{1}; + $this->_advance(); + $this->_parse_tree = $this->_condition(); + if (PEAR::isError($this->_parse_tree)) { + return $this->_parse_tree; + } + return true; + } + + /** + * It parses a condition. It assumes the following rule: + * Cond -> Expr [(">" | "<") Expr] + * + * @access private + * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure + */ + function _condition() + { + $result = $this->_expression(); + if (PEAR::isError($result)) { + return $result; + } + if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LT) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgLT', $result, $result2); + } + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GT) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgGT', $result, $result2); + } + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LE) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgLE', $result, $result2); + } + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GE) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgGE', $result, $result2); + } + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_EQ) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgEQ', $result, $result2); + } + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_NE) + { + $this->_advance(); + $result2 = $this->_expression(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgNE', $result, $result2); + } + return $result; + } + + /** + * It parses a expression. It assumes the following rule: + * Expr -> Term [("+" | "-") Term] + * -> "string" + * -> "-" Term + * + * @access private + * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure + */ + function _expression() + { + // If it's a string return a string node + if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token)) { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // catch "-" Term + elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB) { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUminus', $result2, ''); + return $result; + } + $result = $this->_term(); + if (PEAR::isError($result)) { + return $result; + } + while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) or + ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB)) + { + if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) + { + $this->_advance(); + $result2 = $this->_term(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgAdd', $result, $result2); + } + else + { + $this->_advance(); + $result2 = $this->_term(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgSub', $result, $result2); + } + } + return $result; + } + + /** + * This function just introduces a ptgParen element in the tree, so that Excel + * doesn't get confused when working with a parenthesized formula afterwards. + * + * @access private + * @see _fact() + * @return array The parsed ptg'd tree + */ + function _parenthesizedExpression() + { + $result = $this->_createTree('ptgParen', $this->_expression(), ''); + return $result; + } + + /** + * It parses a term. It assumes the following rule: + * Term -> Fact [("*" | "/") Fact] + * + * @access private + * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure + */ + function _term() + { + $result = $this->_fact(); + if (PEAR::isError($result)) { + return $result; + } + while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) or + ($this->_current_token == SPREADSHEET_EXCEL_WRITER_DIV)) + { + if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) + { + $this->_advance(); + $result2 = $this->_fact(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgMul', $result, $result2); + } + else + { + $this->_advance(); + $result2 = $this->_fact(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('ptgDiv', $result, $result2); + } + } + return $result; + } + + /** + * It parses a factor. It assumes the following rule: + * Fact -> ( Expr ) + * | CellRef + * | CellRange + * | Number + * | Function + * + * @access private + * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure + */ + function _fact() + { + if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_OPEN) + { + $this->_advance(); // eat the "(" + $result = $this->_parenthesizedExpression(); + if ($this->_current_token != SPREADSHEET_EXCEL_WRITER_CLOSE) { + return $this->raiseError("')' token expected."); + } + $this->_advance(); // eat the ")" + return $result; + } + // if it's a reference + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) + elseif (preg_match("/^\w+(\:\w+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1) + elseif (preg_match("/^'\w+(\:\w+)?'\![A-Ia-i]?[A-Za-z][0-9]+$/",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // if it's a range + elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token) or + preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token)) + { + $result = $this->_current_token; + $this->_advance(); + return $result; + } + // If it's an external range (Sheet1!A1 or Sheet1!A1:B2) + elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token)) + { + $result = $this->_current_token; + $this->_advance(); + return $result; + } + // If it's an external range ('Sheet1'!A1 or 'Sheet1'!A1:B2) + elseif (preg_match("/^'\w+(\:\w+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token)) + { + $result = $this->_current_token; + $this->_advance(); + return $result; + } + elseif (is_numeric($this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // if it's a function call + elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token)) + { + $result = $this->_func(); + return $result; + } + return $this->raiseError("Syntax error: ".$this->_current_token. + ", lookahead: ".$this->_lookahead. + ", current char: ".$this->_current_char); + } + + /** + * It parses a function call. It assumes the following rule: + * Func -> ( Expr [,Expr]* ) + * + * @access private + * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure + */ + function _func() + { + $num_args = 0; // number of arguments received + $function = $this->_current_token; + $this->_advance(); + $this->_advance(); // eat the "(" + while ($this->_current_token != ')') + { + if ($num_args > 0) + { + if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_COMA || + $this->_current_token == SPREADSHEET_EXCEL_WRITER_SEMICOLON) + { + $this->_advance(); // eat the "," or ";" + } + else { + return $this->raiseError("Syntax error: comma expected in ". + "function $function, arg #{$num_args}"); + } + $result2 = $this->_condition(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('arg', $result, $result2); + } + else // first argument + { + $result2 = $this->_condition(); + if (PEAR::isError($result2)) { + return $result2; + } + $result = $this->_createTree('arg', '', $result2); + } + $num_args++; + } + $args = $this->_functions[$function][1]; + // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. + if (($args >= 0) and ($args != $num_args)) { + return $this->raiseError("Incorrect number of arguments in function $function() "); + } + + $result = $this->_createTree($function, $result, $num_args); + $this->_advance(); // eat the ")" + return $result; + } + + /** + * Creates a tree. In fact an array which may have one or two arrays (sub-trees) + * as elements. + * + * @access private + * @param mixed $value The value of this node. + * @param mixed $left The left array (sub-tree) or a final node. + * @param mixed $right The right array (sub-tree) or a final node. + * @return array A tree + */ + function _createTree($value, $left, $right) + { + return array('value' => $value, 'left' => $left, 'right' => $right); + } + + /** + * Builds a string containing the tree in reverse polish notation (What you + * would use in a HP calculator stack). + * The following tree: + * + * + + * / \ + * 2 3 + * + * produces: "23+" + * + * The following tree: + * + * + + * / \ + * 3 * + * / \ + * 6 A1 + * + * produces: "36A1*+" + * + * In fact all operands, functions, references, etc... are written as ptg's + * + * @access public + * @param array $tree The optional tree to convert. + * @return string The tree in reverse polish notation + */ + function toReversePolish($tree = array()) + { + $polish = ""; // the string we are going to return + if (empty($tree)) // If it's the first call use _parse_tree + { + $tree = $this->_parse_tree; + } + if (is_array($tree['left'])) + { + $converted_tree = $this->toReversePolish($tree['left']); + if (PEAR::isError($converted_tree)) { + return $converted_tree; + } + $polish .= $converted_tree; + } + elseif ($tree['left'] != '') // It's a final node + { + $converted_tree = $this->_convert($tree['left']); + if (PEAR::isError($converted_tree)) { + return $converted_tree; + } + $polish .= $converted_tree; + } + if (is_array($tree['right'])) + { + $converted_tree = $this->toReversePolish($tree['right']); + if (PEAR::isError($converted_tree)) { + return $converted_tree; + } + $polish .= $converted_tree; + } + elseif ($tree['right'] != '') // It's a final node + { + $converted_tree = $this->_convert($tree['right']); + if (PEAR::isError($converted_tree)) { + return $converted_tree; + } + $polish .= $converted_tree; + } + // if it's a function convert it here (so we can set it's arguments) + if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and + !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and + !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and + !is_numeric($tree['value']) and + !isset($this->ptg[$tree['value']])) + { + // left subtree for a function is always an array. + if ($tree['left'] != '') { + $left_tree = $this->toReversePolish($tree['left']); + } + else { + $left_tree = ''; + } + if (PEAR::isError($left_tree)) { + return $left_tree; + } + // add it's left subtree and return. + return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); + } + else + { + $converted_tree = $this->_convert($tree['value']); + if (PEAR::isError($converted_tree)) { + return $converted_tree; + } + } + $polish .= $converted_tree; + return $polish; + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Validator.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Validator.php new file mode 100644 index 000000000..6d99afebf --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Validator.php @@ -0,0 +1,225 @@ + +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//require_once('PEAR.php'); + +// Possible operator types + +/* +FIXME: change prefixes +*/ +define("OP_BETWEEN", 0x00); +define("OP_NOTBETWEEN", 0x01); +define("OP_EQUAL", 0x02); +define("OP_NOTEQUAL", 0x03); +define("OP_GT", 0x04); +define("OP_LT", 0x05); +define("OP_GTE", 0x06); +define("OP_LTE", 0x07); + +/** +* Baseclass for generating Excel DV records (validations) +* +* @author Herman Kuiper +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ +class Spreadsheet_Excel_Writer_Validator +{ + var $_type; + var $_style; + var $_fixedList; + var $_blank; + var $_incell; + var $_showprompt; + var $_showerror; + var $_title_prompt; + var $_descr_prompt; + var $_title_error; + var $_descr_error; + var $_operator; + var $_formula1; + var $_formula2; + /** + * The parser from the workbook. Used to parse validation formulas also + * @var Spreadsheet_Excel_Writer_Parser + */ + var $_parser; + + function Spreadsheet_Excel_Writer_Validator(&$parser) + { + $this->_parser = $parser; + $this->_type = 0x01; // FIXME: add method for setting datatype + $this->_style = 0x00; + $this->_fixedList = false; + $this->_blank = false; + $this->_incell = false; + $this->_showprompt = false; + $this->_showerror = true; + $this->_title_prompt = "\x00"; + $this->_descr_prompt = "\x00"; + $this->_title_error = "\x00"; + $this->_descr_error = "\x00"; + $this->_operator = 0x00; // default is equal + $this->_formula1 = ""; + $this->_formula2 = ""; + } + + function setPrompt($promptTitle = "\x00", $promptDescription = "\x00", $showPrompt = true) + { + $this->_showprompt = $showPrompt; + $this->_title_prompt = $promptTitle; + $this->_descr_prompt = $promptDescription; + } + + function setError($errorTitle = "\x00", $errorDescription = "\x00", $showError = true) + { + $this->_showerror = $showError; + $this->_title_error = $errorTitle; + $this->_descr_error = $errorDescription; + } + + function allowBlank() + { + $this->_blank = true; + } + + function onInvalidStop() + { + $this->_style = 0x00; + } + + function onInvalidWarn() + { + $this->_style = 0x01; + } + + function onInvalidInfo() + { + $this->_style = 0x02; + } + + function setFormula1($formula) + { + // Parse the formula using the parser in Parser.php + $error = $this->_parser->parse($formula); + if (PEAR::isError($error)) { + return $this->_formula1; + } + + $this->_formula1 = $this->_parser->toReversePolish(); + if (PEAR::isError($this->_formula1)) { + return $this->_formula1; + } + return true; + } + + function setFormula2($formula) + { + // Parse the formula using the parser in Parser.php + $error = $this->_parser->parse($formula); + if (PEAR::isError($error)) { + return $this->_formula2; + } + + $this->_formula2 = $this->_parser->toReversePolish(); + if (PEAR::isError($this->_formula2)) { + return $this->_formula2; + } + return true; + } + + function _getOptions() + { + $options = $this->_type; + $options |= $this->_style << 3; + if($this->_fixedList) + $options |= 0x80; + if($this->_blank) + $options |= 0x100; + if(!$this->_incell) + $options |= 0x200; + if($this->_showprompt) + $options |= 0x40000; + if($this->_showerror) + $options |= 0x80000; + $options |= $this->_operator << 20; + + return $options; + } + + function _getData() + { + $title_prompt_len = strlen($this->_title_prompt); + $descr_prompt_len = strlen($this->_descr_prompt); + $title_error_len = strlen($this->_title_error); + $descr_error_len = strlen($this->_descr_error); + + $formula1_size = strlen($this->_formula1); + $formula2_size = strlen($this->_formula2); + + $data = pack("V", $this->_getOptions()); + $data .= pack("vC", $title_prompt_len, 0x00) . $this->_title_prompt; + $data .= pack("vC", $title_error_len, 0x00) . $this->_title_error; + $data .= pack("vC", $descr_prompt_len, 0x00) . $this->_descr_prompt; + $data .= pack("vC", $descr_error_len, 0x00) . $this->_descr_error; + + $data .= pack("vv", $formula1_size, 0x0000) . $this->_formula1; + $data .= pack("vv", $formula2_size, 0x0000) . $this->_formula2; + + return $data; + } +} + +/*class Spreadsheet_Excel_Writer_Validation_List extends Spreadsheet_Excel_Writer_Validation +{ + function Spreadsheet_Excel_Writer_Validation_list() + { + parent::Spreadsheet_Excel_Writer_Validation(); + $this->_type = 0x03; + } + + function setList($source, $incell = true) + { + $this->_incell = $incell; + $this->_fixedList = true; + + $source = implode("\x00", $source); + $this->_formula1 = pack("CCC", 0x17, strlen($source), 0x0c) . $source; + } + + function setRow($row, $col1, $col2, $incell = true) + { + $this->_incell = $incell; + //$this->_formula1 = ...; + } + + function setCol($col, $row1, $row2, $incell = true) + { + $this->_incell = $incell; + //$this->_formula1 = ...; + } +}*/ + +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Workbook.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Workbook.php new file mode 100644 index 000000000..91f8a6b3d --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Workbook.php @@ -0,0 +1,1545 @@ + +* +* The majority of this is _NOT_ my code. I simply ported it from the +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('Spreadsheet/Excel/Writer/Format.php'); +require_once('Spreadsheet/Excel/Writer/BIFFwriter.php'); +require_once('Spreadsheet/Excel/Writer/Worksheet.php'); +require_once('Spreadsheet/Excel/Writer/Parser.php'); +require_once('OLE/PPS/Root.php'); +require_once('OLE/PPS/File.php'); + +/** +* Class for generating Excel Spreadsheets +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwriter +{ + /** + * Filename for the Workbook + * @var string + */ + var $_filename; + + /** + * Formula parser + * @var object Parser + */ + var $_parser; + + /** + * Flag for 1904 date system (0 => base date is 1900, 1 => base date is 1904) + * @var integer + */ + var $_1904; + + /** + * The active worksheet of the workbook (0 indexed) + * @var integer + */ + var $_activesheet; + + /** + * 1st displayed worksheet in the workbook (0 indexed) + * @var integer + */ + var $_firstsheet; + + /** + * Number of workbook tabs selected + * @var integer + */ + var $_selected; + + /** + * Index for creating adding new formats to the workbook + * @var integer + */ + var $_xf_index; + + /** + * Flag for preventing close from being called twice. + * @var integer + * @see close() + */ + var $_fileclosed; + + /** + * The BIFF file size for the workbook. + * @var integer + * @see _calcSheetOffsets() + */ + var $_biffsize; + + /** + * The default sheetname for all sheets created. + * @var string + */ + var $_sheetname; + + /** + * The default XF format. + * @var object Format + */ + var $_tmp_format; + + /** + * Array containing references to all of this workbook's worksheets + * @var array + */ + var $_worksheets; + + /** + * Array of sheetnames for creating the EXTERNSHEET records + * @var array + */ + var $_sheetnames; + + /** + * Array containing references to all of this workbook's formats + * @var array + */ + var $_formats; + + /** + * Array containing the colour palette + * @var array + */ + var $_palette; + + /** + * The default format for URLs. + * @var object Format + */ + var $_url_format; + + /** + * The codepage indicates the text encoding used for strings + * @var integer + */ + var $_codepage; + + /** + * The country code used for localization + * @var integer + */ + var $_country_code; + + /** + * The temporary dir for storing the OLE file + * @var string + */ + var $_tmp_dir; + + /** + * Class constructor + * + * @param string filename for storing the workbook. "-" for writing to stdout. + * @access public + */ + function Spreadsheet_Excel_Writer_Workbook($filename) + { + // It needs to call its parent's constructor explicitly + $this->Spreadsheet_Excel_Writer_BIFFwriter(); + + $this->_filename = $filename; + $this->_parser =& new Spreadsheet_Excel_Writer_Parser($this->_byte_order, $this->_BIFF_version); + $this->_1904 = 0; + $this->_activesheet = 0; + $this->_firstsheet = 0; + $this->_selected = 0; + $this->_xf_index = 16; // 15 style XF's and 1 cell XF. + $this->_fileclosed = 0; + $this->_biffsize = 0; + $this->_sheetname = "Sheet"; + $this->_tmp_format =& new Spreadsheet_Excel_Writer_Format($this->_BIFF_version); + $this->_worksheets = array(); + $this->_sheetnames = array(); + $this->_formats = array(); + $this->_palette = array(); + $this->_codepage = 0x04E4; // FIXME: should change for BIFF8 + $this->_country_code = -1; + + // Add the default format for hyperlinks + $this->_url_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1)); + $this->_str_total = 0; + $this->_str_unique = 0; + $this->_str_table = array(); + $this->_setPaletteXl97(); + $this->_tmp_dir = ''; + + // Add the default format Moneda - Currency (by JHL) + //$this->_currency_format =& $this->addFormat(array('color' => 'blue', 'underline' => 1)); + + } + + /** + * Calls finalization methods. + * This method should always be the last one to be called on every workbook + * + * @access public + * @return mixed true on success. PEAR_Error on failure + */ + function close() + { + if ($this->_fileclosed) { // Prevent close() from being called twice. + return true; + } + $res = $this->_storeWorkbook(); + if ($this->isError($res)) { + return $this->raiseError($res->getMessage()); + } + $this->_fileclosed = 1; + return true; + } + + /** + * An accessor for the _worksheets[] array + * Returns an array of the worksheet objects in a workbook + * It actually calls to worksheets() + * + * @access public + * @see worksheets() + * @return array + */ + function sheets() + { + return $this->worksheets(); + } + + /** + * An accessor for the _worksheets[] array. + * Returns an array of the worksheet objects in a workbook + * + * @access public + * @return array + */ + function worksheets() + { + return $this->_worksheets; + } + + /** + * Sets the BIFF version. + * This method exists just to access experimental functionality + * from BIFF8. It will be deprecated ! + * Only possible value is 8 (Excel 97/2000). + * For any other value it fails silently. + * + * @access public + * @param integer $version The BIFF version + */ + function setVersion($version) + { + if ($version == 8) { // only accept version 8 + $version = 0x0600; + $this->_BIFF_version = $version; + // change BIFFwriter limit for CONTINUE records + $this->_limit = 8224; + $this->_tmp_format->_BIFF_version = $version; + $this->_url_format->_BIFF_version = $version; + $this->_parser->_BIFF_version = $version; + $total_worksheets = count($this->_worksheets); + // change version for all worksheets too + for ($i = 0; $i < $total_worksheets; $i++) { + $this->_worksheets[$i]->_BIFF_version = $version; + } + $total_formats = count($this->_formats); + // change version for all formats too + for ($i = 0; $i < $total_formats; $i++) { + $this->_formats[$i]->_BIFF_version = $version; + } + } + } + + /** + * Set the country identifier for the workbook + * + * @access public + * @param integer $code Is the international calling country code for the + * chosen country. + */ + function setCountry($code) + { + $this->_country_code = $code; + } + + /** + * Add a new worksheet to the Excel workbook. + * If no name is given the name of the worksheet will be Sheeti$i, with + * $i in [1..]. + * + * @access public + * @param string $name the optional name of the worksheet + * @return mixed reference to a worksheet object on success, PEAR_Error + * on failure + */ + function &addWorksheet($name = '') + { + $index = count($this->_worksheets); + $sheetname = $this->_sheetname; + + if ($name == '') { + $name = $sheetname.($index+1); + } + + // Check that sheetname is <= 31 chars (Excel limit). + if (strlen($name) > 31) { + return $this->raiseError("Sheetname $name must be <= 31 chars"); + } + + // Check that the worksheet name doesn't already exist: a fatal Excel error. + $total_worksheets = count($this->_worksheets); + for ($i=0; $i < $total_worksheets; $i++) + { + if ($name == $this->_worksheets[$i]->getName()) { + return $this->raiseError("Worksheet '$name' already exists"); + } + } + + $worksheet = new Spreadsheet_Excel_Writer_Worksheet($this->_BIFF_version, + $name, $index, + $this->_activesheet, $this->_firstsheet, + $this->_str_total, $this->_str_unique, + $this->_str_table, $this->_url_format, + $this->_parser); + + $this->_worksheets[$index] = &$worksheet; // Store ref for iterator + $this->_sheetnames[$index] = $name; // Store EXTERNSHEET names + $this->_parser->setExtSheet($name, $index); // Register worksheet name with parser + return $worksheet; + } + + /** + * Add a new format to the Excel workbook. + * Also, pass any properties to the Format constructor. + * + * @access public + * @param array $properties array with properties for initializing the format. + * @return &Spreadsheet_Excel_Writer_Format reference to an Excel Format + */ + function &addFormat($properties = array()) + { + $format = new Spreadsheet_Excel_Writer_Format($this->_BIFF_version, $this->_xf_index,$properties); + $this->_xf_index += 1; + $this->_formats[] = &$format; + return $format; + } + + /** + * Create new validator. + * + * @access public + * @return &Spreadsheet_Excel_Writer_Validator reference to a Validator + */ + function &addValidator() + { + include_once('Spreadsheet/Excel/Writer/Validator.php'); + /* FIXME: check for successful inclusion*/ + $valid = new Spreadsheet_Excel_Writer_Validator($this->_parser); + return $valid; + } + + /** + * Change the RGB components of the elements in the colour palette. + * + * @access public + * @param integer $index colour index + * @param integer $red red RGB value [0-255] + * @param integer $green green RGB value [0-255] + * @param integer $blue blue RGB value [0-255] + * @return integer The palette index for the custom color + */ + function setCustomColor($index,$red,$green,$blue) + { + // Match a HTML #xxyyzz style parameter + /*if (defined $_[1] and $_[1] =~ /^#(\w\w)(\w\w)(\w\w)/ ) { + @_ = ($_[0], hex $1, hex $2, hex $3); + }*/ + + // Check that the colour index is the right range + if ($index < 8 or $index > 64) { + // TODO: assign real error codes + return $this->raiseError("Color index $index outside range: 8 <= index <= 64"); + } + + // Check that the colour components are in the right range + if ( ($red < 0 or $red > 255) or + ($green < 0 or $green > 255) or + ($blue < 0 or $blue > 255) ) + { + return $this->raiseError("Color component outside range: 0 <= color <= 255"); + } + + $index -= 8; // Adjust colour index (wingless dragonfly) + + // Set the RGB value + $this->_palette[$index] = array($red, $green, $blue, 0); + return($index + 8); + } + + /** + * Sets the colour palette to the Excel 97+ default. + * + * @access private + */ + function _setPaletteXl97() + { + $this->_palette = array( + array(0x00, 0x00, 0x00, 0x00), // 8 + array(0xff, 0xff, 0xff, 0x00), // 9 + array(0xff, 0x00, 0x00, 0x00), // 10 + array(0x00, 0xff, 0x00, 0x00), // 11 + array(0x00, 0x00, 0xff, 0x00), // 12 + array(0xff, 0xff, 0x00, 0x00), // 13 + array(0xff, 0x00, 0xff, 0x00), // 14 + array(0x00, 0xff, 0xff, 0x00), // 15 + array(0x80, 0x00, 0x00, 0x00), // 16 + array(0x00, 0x80, 0x00, 0x00), // 17 + array(0x00, 0x00, 0x80, 0x00), // 18 + array(0x80, 0x80, 0x00, 0x00), // 19 + array(0x80, 0x00, 0x80, 0x00), // 20 + array(0x00, 0x80, 0x80, 0x00), // 21 + array(0xc0, 0xc0, 0xc0, 0x00), // 22 + array(0x80, 0x80, 0x80, 0x00), // 23 + array(0x99, 0x99, 0xff, 0x00), // 24 + array(0x99, 0x33, 0x66, 0x00), // 25 + array(0xff, 0xff, 0xcc, 0x00), // 26 + array(0xcc, 0xff, 0xff, 0x00), // 27 + array(0x66, 0x00, 0x66, 0x00), // 28 + array(0xff, 0x80, 0x80, 0x00), // 29 + array(0x00, 0x66, 0xcc, 0x00), // 30 + array(0xcc, 0xcc, 0xff, 0x00), // 31 + array(0x00, 0x00, 0x80, 0x00), // 32 + array(0xff, 0x00, 0xff, 0x00), // 33 + array(0xff, 0xff, 0x00, 0x00), // 34 + array(0x00, 0xff, 0xff, 0x00), // 35 + array(0x80, 0x00, 0x80, 0x00), // 36 + array(0x80, 0x00, 0x00, 0x00), // 37 + array(0x00, 0x80, 0x80, 0x00), // 38 + array(0x00, 0x00, 0xff, 0x00), // 39 + array(0x00, 0xcc, 0xff, 0x00), // 40 + array(0xcc, 0xff, 0xff, 0x00), // 41 + array(0xcc, 0xff, 0xcc, 0x00), // 42 + array(0xff, 0xff, 0x99, 0x00), // 43 + array(0x99, 0xcc, 0xff, 0x00), // 44 + array(0xff, 0x99, 0xcc, 0x00), // 45 + array(0xcc, 0x99, 0xff, 0x00), // 46 + array(0xff, 0xcc, 0x99, 0x00), // 47 + array(0x33, 0x66, 0xff, 0x00), // 48 + array(0x33, 0xcc, 0xcc, 0x00), // 49 + array(0x99, 0xcc, 0x00, 0x00), // 50 + array(0xff, 0xcc, 0x00, 0x00), // 51 + array(0xff, 0x99, 0x00, 0x00), // 52 + array(0xff, 0x66, 0x00, 0x00), // 53 + array(0x66, 0x66, 0x99, 0x00), // 54 + array(0x96, 0x96, 0x96, 0x00), // 55 + array(0x00, 0x33, 0x66, 0x00), // 56 + array(0x33, 0x99, 0x66, 0x00), // 57 + array(0x00, 0x33, 0x00, 0x00), // 58 + array(0x33, 0x33, 0x00, 0x00), // 59 + array(0x99, 0x33, 0x00, 0x00), // 60 + array(0x99, 0x33, 0x66, 0x00), // 61 + array(0x33, 0x33, 0x99, 0x00), // 62 + array(0x33, 0x33, 0x33, 0x00), // 63 + ); + } + + /** + * Assemble worksheets into a workbook and send the BIFF data to an OLE + * storage. + * + * @access private + * @return mixed true on success. PEAR_Error on failure + */ + function _storeWorkbook() + { + // Ensure that at least one worksheet has been selected. + if ($this->_activesheet == 0) { + $this->_worksheets[0]->selected = 1; + } + + // Calculate the number of selected worksheet tabs and call the finalization + // methods for each worksheet + $total_worksheets = count($this->_worksheets); + for ($i=0; $i < $total_worksheets; $i++) { + if ($this->_worksheets[$i]->selected) { + $this->_selected++; + } + $this->_worksheets[$i]->close($this->_sheetnames); + } + + // Add Workbook globals + $this->_storeBof(0x0005); + if ($this->_BIFF_version == 0x0600) { + $this->_storeCodepage(); + $this->_storeWindow1(); + } + if ($this->_BIFF_version == 0x0500) { + $this->_storeExterns(); // For print area and repeat rows + } + $this->_storeNames(); // For print area and repeat rows + if ($this->_BIFF_version == 0x0500) { + $this->_storeWindow1(); + } + $this->_storeDatemode(); + $this->_storeAllFonts(); + $this->_storeAllNumFormats(); + $this->_storeAllXfs(); + $this->_storeAllStyles(); + $this->_storePalette(); + $this->_calcSheetOffsets(); + + // Add BOUNDSHEET records + for ($i=0; $i < $total_worksheets; $i++) { + $this->_storeBoundsheet($this->_worksheets[$i]->name,$this->_worksheets[$i]->offset); + } + + if ($this->_country_code != -1) { + $this->_storeCountry(); + } + + if ($this->_BIFF_version == 0x0600) { + //$this->_storeSupbookInternal(); + /* TODO: store external SUPBOOK records and XCT and CRN records + in case of external references for BIFF8 */ + //$this->_storeExternsheetBiff8(); + $this->_storeSharedStringsTable(); + } + + // End Workbook globals + $this->_storeEof(); + + // Store the workbook in an OLE container + $res = $this->_storeOLEFile(); + if ($this->isError($res)) { + return $this->raiseError($res->getMessage()); + } + return true; + } + + /** + * Sets the temp dir used for storing the OLE file + * + * @access public + * @param string $dir The dir to be used as temp dir + * @return true if given dir is valid, false otherwise + */ + function setTempDir($dir) + { + if (is_dir($dir)) { + $this->_tmp_dir = $dir; + return true; + } + return false; + } + + /** + * Store the workbook in an OLE container + * + * @access private + * @return mixed true on success. PEAR_Error on failure + */ + function _storeOLEFile() + { + $OLE = new OLE_PPS_File(OLE::Asc2Ucs('Book')); + if ($this->_tmp_dir != '') { + $OLE->setTempDir($this->_tmp_dir); + } + $res = $OLE->init(); + if ($this->isError($res)) { + return $this->raiseError("OLE Error: ".$res->getMessage()); + } + $OLE->append($this->_data); + $total_worksheets = count($this->_worksheets); + for ($i = 0; $i < $total_worksheets; $i++) + { + while ($tmp = $this->_worksheets[$i]->getData()) { + $OLE->append($tmp); + } + } + $root = new OLE_PPS_Root(time(), time(), array($OLE)); + if ($this->_tmp_dir != '') { + $root->setTempDir($this->_tmp_dir); + } + $res = $root->save($this->_filename); + if ($this->isError($res)) { + return $this->raiseError("OLE Error: ".$res->getMessage()); + } + return true; + } + + /** + * Calculate offsets for Worksheet BOF records. + * + * @access private + */ + function _calcSheetOffsets() + { + if ($this->_BIFF_version == 0x0600) { + $boundsheet_length = 12; // fixed length for a BOUNDSHEET record + } + else { + $boundsheet_length = 11; + } + $EOF = 4; + $offset = $this->_datasize; + + if ($this->_BIFF_version == 0x0600) { + // add the length of the SST + /* TODO: check this works for a lot of strings (> 8224 bytes) */ + $offset += $this->_calculateSharedStringsSizes(); + if ($this->_country_code != -1) { + $offset += 8; // adding COUNTRY record + } + // add the lenght of SUPBOOK, EXTERNSHEET and NAME records + //$offset += 8; // FIXME: calculate real value when storing the records + } + $total_worksheets = count($this->_worksheets); + // add the length of the BOUNDSHEET records + for ($i=0; $i < $total_worksheets; $i++) { + $offset += $boundsheet_length + strlen($this->_worksheets[$i]->name); + } + $offset += $EOF; + + for ($i=0; $i < $total_worksheets; $i++) { + $this->_worksheets[$i]->offset = $offset; + $offset += $this->_worksheets[$i]->_datasize; + } + $this->_biffsize = $offset; + } + + /** + * Store the Excel FONT records. + * + * @access private + */ + function _storeAllFonts() + { + // tmp_format is added by the constructor. We use this to write the default XF's + $format = $this->_tmp_format; + $font = $format->getFont(); + + // Note: Fonts are 0-indexed. According to the SDK there is no index 4, + // so the following fonts are 0, 1, 2, 3, 5 + // + for ($i=1; $i <= 5; $i++){ + $this->_append($font); + } + + // Iterate through the XF objects and write a FONT record if it isn't the + // same as the default FONT and if it hasn't already been used. + // + $fonts = array(); + $index = 6; // The first user defined FONT + + $key = $format->getFontKey(); // The default font from _tmp_format + $fonts[$key] = 0; // Index of the default font + + $total_formats = count($this->_formats); + for ($i=0; $i < $total_formats; $i++) + { + $key = $this->_formats[$i]->getFontKey(); + if (isset($fonts[$key])) { + // FONT has already been used + $this->_formats[$i]->font_index = $fonts[$key]; + } + else { + // Add a new FONT record + $fonts[$key] = $index; + $this->_formats[$i]->font_index = $index; + $index++; + $font = $this->_formats[$i]->getFont(); + $this->_append($font); + } + } + } + + /** + * Store user defined numerical formats i.e. FORMAT records + * + * @access private + */ + function _storeAllNumFormats() + { + // Leaning num_format syndrome + $hash_num_formats = array(); + $num_formats = array(); + $index = 164; + + // Iterate through the XF objects and write a FORMAT record if it isn't a + // built-in format type and if the FORMAT string hasn't already been used. + $total_formats = count($this->_formats); + for ($i=0; $i < $total_formats; $i++) + { + $num_format = $this->_formats[$i]->_num_format; + + // Check if $num_format is an index to a built-in format. + // Also check for a string of zeros, which is a valid format string + // but would evaluate to zero. + // + if (!preg_match("/^0+\d/",$num_format)) + { + if (preg_match("/^\d+$/",$num_format)) { // built-in format + continue; + } + } + + if (isset($hash_num_formats[$num_format])) { + // FORMAT has already been used + $this->_formats[$i]->_num_format = $hash_num_formats[$num_format]; + } + else{ + // Add a new FORMAT + $hash_num_formats[$num_format] = $index; + $this->_formats[$i]->_num_format = $index; + array_push($num_formats,$num_format); + $index++; + } + } + + // Write the new FORMAT records starting from 0xA4 + $index = 164; + foreach ($num_formats as $num_format) { + $this->_storeNumFormat($num_format,$index); + $index++; + } + } + + /** + * Write all XF records. + * + * @access private + */ + function _storeAllXfs() + { + // _tmp_format is added by the constructor. We use this to write the default XF's + // The default font index is 0 + // + $format = $this->_tmp_format; + for ($i=0; $i <= 14; $i++) { + $xf = $format->getXf('style'); // Style XF + $this->_append($xf); + } + + $xf = $format->getXf('cell'); // Cell XF + $this->_append($xf); + + // User defined XFs + $total_formats = count($this->_formats); + for ($i=0; $i < $total_formats; $i++) { + $xf = $this->_formats[$i]->getXf('cell'); + $this->_append($xf); + } + } + + /** + * Write all STYLE records. + * + * @access private + */ + function _storeAllStyles() + { + $this->_storeStyle(); + } + + /** + * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for + * the NAME records. + * + * @access private + */ + function _storeExterns() + { + // Create EXTERNCOUNT with number of worksheets + $this->_storeExterncount(count($this->_worksheets)); + + // Create EXTERNSHEET for each worksheet + foreach ($this->_sheetnames as $sheetname) { + $this->_storeExternsheet($sheetname); + } + } + + /** + * Write the NAME record to define the print area and the repeat rows and cols. + * + * @access private + */ + function _storeNames() + { + // Create the print area NAME records + $total_worksheets = count($this->_worksheets); + for ($i = 0; $i < $total_worksheets; $i++) { + // Write a Name record if the print area has been defined + if (isset($this->_worksheets[$i]->print_rowmin)) + { + $this->_storeNameShort( + $this->_worksheets[$i]->index, + 0x06, // NAME type + $this->_worksheets[$i]->print_rowmin, + $this->_worksheets[$i]->print_rowmax, + $this->_worksheets[$i]->print_colmin, + $this->_worksheets[$i]->print_colmax + ); + } + } + + // Create the print title NAME records + $total_worksheets = count($this->_worksheets); + for ($i = 0; $i < $total_worksheets; $i++) { + $rowmin = $this->_worksheets[$i]->title_rowmin; + $rowmax = $this->_worksheets[$i]->title_rowmax; + $colmin = $this->_worksheets[$i]->title_colmin; + $colmax = $this->_worksheets[$i]->title_colmax; + + // Determine if row + col, row, col or nothing has been defined + // and write the appropriate record + // + if (isset($rowmin) and isset($colmin)) { + // Row and column titles have been defined. + // Row title has been defined. + $this->_storeNameLong( + $this->_worksheets[$i]->index, + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + } + elseif (isset($rowmin)) { + // Row title has been defined. + $this->_storeNameShort( + $this->_worksheets[$i]->index, + 0x07, // NAME type + $rowmin, + $rowmax, + 0x00, + 0xff + ); + } + elseif (isset($colmin)) { + // Column title has been defined. + $this->_storeNameShort( + $this->_worksheets[$i]->index, + 0x07, // NAME type + 0x0000, + 0x3fff, + $colmin, + $colmax + ); + } + else { + // Print title hasn't been defined. + } + } + } + + + + + /****************************************************************************** + * + * BIFF RECORDS + * + */ + + /** + * Stores the CODEPAGE biff record. + * + * @access private + */ + function _storeCodepage() + { + $record = 0x0042; // Record identifier + $length = 0x0002; // Number of bytes to follow + $cv = $this->_codepage; // The code page + + $header = pack('vv', $record, $length); + $data = pack('v', $cv); + + $this->_append($header.$data); + } + + /** + * Write Excel BIFF WINDOW1 record. + * + * @access private + */ + function _storeWindow1() + { + $record = 0x003D; // Record identifier + $length = 0x0012; // Number of bytes to follow + + $xWn = 0x0000; // Horizontal position of window + $yWn = 0x0000; // Vertical position of window + $dxWn = 0x25BC; // Width of window + $dyWn = 0x1572; // Height of window + + $grbit = 0x0038; // Option flags + $ctabsel = $this->_selected; // Number of workbook tabs selected + $wTabRatio = 0x0258; // Tab to scrollbar ratio + + $itabFirst = $this->_firstsheet; // 1st displayed worksheet + $itabCur = $this->_activesheet; // Active worksheet + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, + $grbit, + $itabCur, $itabFirst, + $ctabsel, $wTabRatio); + $this->_append($header.$data); + } + + /** + * Writes Excel BIFF BOUNDSHEET record. + * FIXME: inconsistent with BIFF documentation + * + * @param string $sheetname Worksheet name + * @param integer $offset Location of worksheet BOF + * @access private + */ + function _storeBoundsheet($sheetname,$offset) + { + $record = 0x0085; // Record identifier + if ($this->_BIFF_version == 0x0600) { + $length = 0x08 + strlen($sheetname); // Number of bytes to follow + } + else { + $length = 0x07 + strlen($sheetname); // Number of bytes to follow + } + + $grbit = 0x0000; // Visibility and sheet type + $cch = strlen($sheetname); // Length of sheet name + + $header = pack("vv", $record, $length); + if ($this->_BIFF_version == 0x0600) { + $data = pack("Vvv", $offset, $grbit, $cch); + } + else { + $data = pack("VvC", $offset, $grbit, $cch); + } + $this->_append($header.$data.$sheetname); + } + + /** + * Write Internal SUPBOOK record + * + * @access private + */ + function _storeSupbookInternal() + { + $record = 0x01AE; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", count($this->_worksheets), 0x0104); + $this->_append($header.$data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. + * + * @param string $sheetname Worksheet name + * @access private + */ + function _storeExternsheetBiff8() + { + $total_references = count($this->_parser->_references); + $record = 0x0017; // Record identifier + $length = 2 + 6 * $total_references; // Number of bytes to follow + + $supbook_index = 0; // FIXME: only using internal SUPBOOK record + $header = pack("vv", $record, $length); + $data = pack('v', $total_references); + for ($i = 0; $i < $total_references; $i++) { + $data .= $this->_parser->_references[$i]; + } + $this->_append($header.$data); + } + + /** + * Write Excel BIFF STYLE records. + * + * @access private + */ + function _storeStyle() + { + $record = 0x0293; // Record identifier + $length = 0x0004; // Bytes to follow + + $ixfe = 0x8000; // Index to style XF + $BuiltIn = 0x00; // Built-in style + $iLevel = 0xff; // Outline style level + + $header = pack("vv", $record, $length); + $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); + $this->_append($header.$data); + } + + + /** + * Writes Excel FORMAT record for non "built-in" numerical formats. + * + * @param string $format Custom format string + * @param integer $ifmt Format index code + * @access private + */ + function _storeNumFormat($format,$ifmt) + { + $record = 0x041E; // Record identifier + + if ($this->_BIFF_version == 0x0600) { + $length = 5 + strlen($format); // Number of bytes to follow + $encoding = 0x0; + } + elseif ($this->_BIFF_version == 0x0500) { + $length = 3 + strlen($format); // Number of bytes to follow + } + + $cch = strlen($format); // Length of format string + + $header = pack("vv", $record, $length); + if ($this->_BIFF_version == 0x0600) { + $data = pack("vvC", $ifmt, $cch, $encoding); + } + elseif ($this->_BIFF_version == 0x0500) { + $data = pack("vC", $ifmt, $cch); + } + $this->_append($header.$data.$format); + } + + /** + * Write DATEMODE record to indicate the date system in use (1904 or 1900). + * + * @access private + */ + function _storeDatemode() + { + $record = 0x0022; // Record identifier + $length = 0x0002; // Bytes to follow + + $f1904 = $this->_1904; // Flag for 1904 date system + + $header = pack("vv", $record, $length); + $data = pack("v", $f1904); + $this->_append($header.$data); + } + + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in the workbook. + * + * Excel only stores references to external sheets that are used in NAME. + * The workbook NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param integer $cxals Number of external references + * @access private + */ + function _storeExterncount($cxals) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cxals); + $this->_append($header.$data); + } + + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param string $sheetname Worksheet name + * @access private + */ + function _storeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + $length = 0x02 + strlen($sheetname); // Number of bytes to follow + + $cch = strlen($sheetname); // Length of sheet name + $rgch = 0x03; // Filename encoding + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header.$data.$sheetname); + } + + + /** + * Store the NAME record in the short format that is used for storing the print + * area, repeat rows only and repeat columns only. + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + * @access private + */ + function _storeNameShort($index,$type,$rowmin,$rowmax,$colmin,$colmax) + { + $record = 0x0018; // Record identifier + $length = 0x0024; // Number of bytes to follow + + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x0015; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8005; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + $this->_append($header.$data); + } + + + /** + * Store the NAME record in the long format that is used for storing the repeat + * rows and columns when both are specified. This shares a lot of code with + * _storeNameShort() but we use a separate method to keep the code clean. + * Code abstraction for reuse can be carried too far, and I should know. ;-) + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + * @access private + */ + function _storeNameLong($index,$type,$rowmin,$rowmax,$colmin,$colmax) + { + $record = 0x0018; // Record identifier + $length = 0x003d; // Number of bytes to follow + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x002e; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown01 = 0x29; + $unknown02 = 0x002b; + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8008; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown01); + $data .= pack("v", $unknown02); + // Column definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", 0x0000); + $data .= pack("v", 0x3fff); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + // Row definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", 0x00); + $data .= pack("C", 0xff); + // End of data + $data .= pack("C", 0x10); + $this->_append($header.$data); + } + + /** + * Stores the COUNTRY record for localization + * + * @access private + */ + function _storeCountry() + { + $record = 0x008C; // Record identifier + $length = 4; // Number of bytes to follow + + $header = pack('vv', $record, $length); + /* using the same country code always for simplicity */ + $data = pack('vv', $this->_country_code, $this->_country_code); + $this->_append($header.$data); + } + + /** + * Stores the PALETTE biff record. + * + * @access private + */ + function _storePalette() + { + $aref = $this->_palette; + + $record = 0x0092; // Record identifier + $length = 2 + 4 * count($aref); // Number of bytes to follow + $ccv = count($aref); // Number of RGB values to follow + $data = ''; // The RGB data + + // Pack the RGB data + foreach($aref as $color) + { + foreach($color as $byte) { + $data .= pack("C",$byte); + } + } + + $header = pack("vvv", $record, $length, $ccv); + $this->_append($header.$data); + } + + /** + * Calculate + * Handling of the SST continue blocks is complicated by the need to include an + * additional continuation byte depending on whether the string is split between + * blocks or whether it starts at the beginning of the block. (There are also + * additional complications that will arise later when/if Rich Strings are + * supported). + * + * @access private + */ + function _calculateSharedStringsSizes() + { + /* Iterate through the strings to calculate the CONTINUE block sizes. + The SST blocks requires a specialised CONTINUE block, so we have to + ensure that the maximum data block size is less than the limit used by + _add_continue() in BIFFwriter.pm. For simplicity we use the same size + for the SST and CONTINUE records: + 8228 : Maximum Excel97 block size + -4 : Length of block header + -8 : Length of additional SST header information + -8 : Arbitrary number to keep within _add_continue() limit + = 8208 + */ + $total_offset = 12; + $continue_limit = 8208; + $block_length = 0; + $written = 0; + $this->_block_sizes = array(); + $continue = 0; + + foreach (array_keys($this->_str_table) as $string) { + $string_length = strlen($string); + + // Block length is the total length of the strings that will be + // written out in a single SST or CONTINUE block. + $block_length += $string_length; + + // We can write the string if it doesn't cross a CONTINUE boundary + if ($block_length < $continue_limit) { + $written += $string_length; + $total_offset += $string_length; + continue; + } + + // Deal with the cases where the next string to be written will exceed + // the CONTINUE boundary. If the string is very long it may need to be + // written in more than one CONTINUE record. + while ($block_length >= $continue_limit) { + + // We need to avoid the case where a string is continued in the first + // n bytes that contain the string header information. + $header_length = 3; // Min string + header size -1 + $space_remaining = $continue_limit - $written - $continue; + + + /* TODO: Unicode data should only be split on char (2 byte) + boundaries. Therefore, in some cases we need to reduce the + amount of available + */ + + if ($space_remaining > $header_length) { + // Write as much as possible of the string in the current block + $written += $space_remaining; + + // Reduce the current block length by the amount written + $block_length -= $continue_limit + $continue; + + // Store the max size for this block + $this->_block_sizes[] = $continue_limit; + + // If the current string was split then the next CONTINUE block + // should have the string continue flag (grbit) set unless the + // split string fits exactly into the remaining space. + if ($block_length > 0) { + $continue = 1; + } + else { + $continue = 0; + } + + } + else { + // Store the max size for this block + $this->_block_sizes[] = $written + $continue; + + // Not enough space to start the string in the current block + $block_length -= $continue_limit - $space_remaining - $continue; + $continue = 0; + + } + + // If the string (or substr) is small enough we can write it in the + // new CONTINUE block. Else, go through the loop again to write it in + // one or more CONTINUE blocks + if ($block_length < $continue_limit) { + $written = $block_length; + } + else { + $written = 0; + } + } + } + + // Store the max size for the last block unless it is empty + if ($written + $continue) { + $this->_block_sizes[] = $written + $continue; + } + + + /* Calculate the total length of the SST and associated CONTINUEs (if any). + The SST record will have a length even if it contains no strings. + This length is required to set the offsets in the BOUNDSHEET records since + they must be written before the SST records + */ + if (!empty($this->_block_sizes)) { + $total_offset += (count($this->_block_sizes) - 1) * 4; // add CONTINUE headers + } + return $total_offset; + } + + /** + * Write all of the workbooks strings into an indexed array. + * See the comments in _calculate_shared_string_sizes() for more information. + * + * The Excel documentation says that the SST record should be followed by an + * EXTSST record. The EXTSST record is a hash table that is used to optimise + * access to SST. However, despite the documentation it doesn't seem to be + * required so we will ignore it. + * + * @access private + */ + /* FIXME: update _calcSheetOffsets() when updating this method */ + function _storeSharedStringsTable() + { + $record = 0x00fc; // Record identifier + $length = 8 + array_sum($this->_block_sizes); // Number of bytes to follow + + // Write the SST block header information + $header = pack("vv", $record, $length); + $data = pack("VV", $this->_str_total, $this->_str_unique); + $this->_append($header.$data); + + + // Iterate through the strings to calculate the CONTINUE block sizes + $continue_limit = 8208; + $block_length = 0; + $written = 0; + $continue = 0; + + + /* TODO: not good for performance */ + foreach (array_keys($this->_str_table) as $string) { + + $string_length = strlen($string); + $encoding = 0; // assume there are no Unicode strings + $split_string = 0; + + // Block length is the total length of the strings that will be + // written out in a single SST or CONTINUE block. + // + $block_length += $string_length; + + + // We can write the string if it doesn't cross a CONTINUE boundary + if ($block_length < $continue_limit) { + $this->_append($string); + $written += $string_length; + continue; + } + + // Deal with the cases where the next string to be written will exceed + // the CONTINUE boundary. If the string is very long it may need to be + // written in more than one CONTINUE record. + // + while ($block_length >= $continue_limit) { + + // We need to avoid the case where a string is continued in the first + // n bytes that contain the string header information. + // + $header_length = 3; // Min string + header size -1 + $space_remaining = $continue_limit - $written - $continue; + + + // Unicode data should only be split on char (2 byte) boundaries. + // Therefore, in some cases we need to reduce the amount of available + + if ($space_remaining > $header_length) { + // Write as much as possible of the string in the current block + $tmp = substr($string, 0, $space_remaining); + $this->_append($tmp); + + // The remainder will be written in the next block(s) + $string = substr($string, $space_remaining); + + // Reduce the current block length by the amount written + $block_length -= $continue_limit - $continue; + + // If the current string was split then the next CONTINUE block + // should have the string continue flag (grbit) set unless the + // split string fits exactly into the remaining space. + // + if ($block_length > 0) { + $continue = 1; + } + else { + $continue = 0; + } + } + else { + // Not enough space to start the string in the current block + $block_length -= $continue_limit - $space_remaining - $continue; + $continue = 0; + } + + // Write the CONTINUE block header + if (!empty($this->_block_sizes)) { + $record = 0x003C; + $length = array_pop($this->_block_sizes); + + $header = pack('vv', $record, $length); + if ($continue) { + $header .= pack('C', $encoding); + } + $this->_append($header); + } + + // If the string (or substr) is small enough we can write it in the + // new CONTINUE block. Else, go through the loop again to write it in + // one or more CONTINUE blocks + // + if ($block_length < $continue_limit) { + $this->_append($string); + + $written = $block_length; + } + else { + $written = 0; + } + } + } + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Worksheet.php b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Worksheet.php new file mode 100644 index 000000000..fce437db2 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/Excel/Writer/Worksheet.php @@ -0,0 +1,3495 @@ + +* +* The majority of this is _NOT_ my code. I simply ported it from the +* PERL Spreadsheet::WriteExcel module. +* +* The author of the Spreadsheet::WriteExcel module is John McNamara +* +* +* I _DO_ maintain this code, and John McNamara has nothing to do with the +* porting of this code to PHP. Any questions directly related to this +* class library should be directed to me. +* +* License Information: +* +* Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +* Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +require_once('Spreadsheet/Excel/Writer/Parser.php'); +require_once('Spreadsheet/Excel/Writer/BIFFwriter.php'); + +/** +* Class for generating Excel Spreadsheets +* +* @author Xavier Noguer +* @category FileFormats +* @package Spreadsheet_Excel_Writer +*/ + +class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwriter +{ + /** + * Name of the Worksheet + * @var string + */ + var $name; + + /** + * Index for the Worksheet + * @var integer + */ + var $index; + + /** + * Reference to the (default) Format object for URLs + * @var object Format + */ + var $_url_format; + + /** + * Reference to the parser used for parsing formulas + * @var object Format + */ + var $_parser; + + /** + * Filehandle to the temporary file for storing data + * @var resource + */ + var $_filehandle; + + /** + * Boolean indicating if we are using a temporary file for storing data + * @var bool + */ + var $_using_tmpfile; + + /** + * Maximum number of rows for an Excel spreadsheet (BIFF5) + * @var integer + */ + var $_xls_rowmax; + + /** + * Maximum number of columns for an Excel spreadsheet (BIFF5) + * @var integer + */ + var $_xls_colmax; + + /** + * Maximum number of characters for a string (LABEL record in BIFF5) + * @var integer + */ + var $_xls_strmax; + + /** + * First row for the DIMENSIONS record + * @var integer + * @see _storeDimensions() + */ + var $_dim_rowmin; + + /** + * Last row for the DIMENSIONS record + * @var integer + * @see _storeDimensions() + */ + var $_dim_rowmax; + + /** + * First column for the DIMENSIONS record + * @var integer + * @see _storeDimensions() + */ + var $_dim_colmin; + + /** + * Last column for the DIMENSIONS record + * @var integer + * @see _storeDimensions() + */ + var $_dim_colmax; + + /** + * Array containing format information for columns + * @var array + */ + var $_colinfo; + + /** + * Array containing the selected area for the worksheet + * @var array + */ + var $_selection; + + /** + * Array containing the panes for the worksheet + * @var array + */ + var $_panes; + + /** + * The active pane for the worksheet + * @var integer + */ + var $_active_pane; + + /** + * Bit specifying if panes are frozen + * @var integer + */ + var $_frozen; + + /** + * Bit specifying if the worksheet is selected + * @var integer + */ + var $selected; + + /** + * The paper size (for printing) (DOCUMENT!!!) + * @var integer + */ + var $_paper_size; + + /** + * Bit specifying paper orientation (for printing). 0 => landscape, 1 => portrait + * @var integer + */ + var $_orientation; + + /** + * The page header caption + * @var string + */ + var $_header; + + /** + * The page footer caption + * @var string + */ + var $_footer; + + /** + * The horizontal centering value for the page + * @var integer + */ + var $_hcenter; + + /** + * The vertical centering value for the page + * @var integer + */ + var $_vcenter; + + /** + * The margin for the header + * @var float + */ + var $_margin_head; + + /** + * The margin for the footer + * @var float + */ + var $_margin_foot; + + /** + * The left margin for the worksheet in inches + * @var float + */ + var $_margin_left; + + /** + * The right margin for the worksheet in inches + * @var float + */ + var $_margin_right; + + /** + * The top margin for the worksheet in inches + * @var float + */ + var $_margin_top; + + /** + * The bottom margin for the worksheet in inches + * @var float + */ + var $_margin_bottom; + + /** + * First row to reapeat on each printed page + * @var integer + */ + var $title_rowmin; + + /** + * Last row to reapeat on each printed page + * @var integer + */ + var $title_rowmax; + + /** + * First column to reapeat on each printed page + * @var integer + */ + var $title_colmin; + + /** + * First row of the area to print + * @var integer + */ + var $print_rowmin; + + /** + * Last row to of the area to print + * @var integer + */ + var $print_rowmax; + + /** + * First column of the area to print + * @var integer + */ + var $print_colmin; + + /** + * Last column of the area to print + * @var integer + */ + var $print_colmax; + + /** + * Whether to use outline. + * @var integer + */ + var $_outline_on; + + /** + * Auto outline styles. + * @var bool + */ + var $_outline_style; + + /** + * Whether to have outline summary below. + * @var bool + */ + var $_outline_below; + + /** + * Whether to have outline summary at the right. + * @var bool + */ + var $_outline_right; + + /** + * Outline row level. + * @var integer + */ + var $_outline_row_level; + + /** + * Whether to fit to page when printing or not. + * @var bool + */ + var $_fit_page; + + /** + * Number of pages to fit wide + * @var integer + */ + var $_fit_width; + + /** + * Number of pages to fit high + * @var integer + */ + var $_fit_height; + + /** + * Reference to the total number of strings in the workbook + * @var integer + */ + var $_str_total; + + /** + * Reference to the number of unique strings in the workbook + * @var integer + */ + var $_str_unique; + + /** + * Reference to the array containing all the unique strings in the workbook + * @var array + */ + var $_str_table; + + /** + * Merged cell ranges + * @var array + */ + var $_merged_ranges; + + /** + * Constructor + * + * @param string $name The name of the new worksheet + * @param integer $index The index of the new worksheet + * @param mixed &$activesheet The current activesheet of the workbook we belong to + * @param mixed &$firstsheet The first worksheet in the workbook we belong to + * @param mixed &$url_format The default format for hyperlinks + * @param mixed &$parser The formula parser created for the Workbook + * @access private + */ + function Spreadsheet_Excel_Writer_Worksheet($BIFF_version, $name, + $index, &$activesheet, + &$firstsheet, &$str_total, + &$str_unique, &$str_table, + &$url_format, &$parser) + { + // It needs to call its parent's constructor explicitly + $this->Spreadsheet_Excel_Writer_BIFFwriter(); + $this->_BIFF_version = $BIFF_version; + $rowmax = 65536; // 16384 in Excel 5 + $colmax = 256; + + $this->name = $name; + $this->index = $index; + $this->activesheet = &$activesheet; + $this->firstsheet = &$firstsheet; + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_url_format = &$url_format; + $this->_parser = &$parser; + + //$this->ext_sheets = array(); + $this->_filehandle = ""; + $this->_using_tmpfile = true; + //$this->fileclosed = 0; + //$this->offset = 0; + $this->_xls_rowmax = $rowmax; + $this->_xls_colmax = $colmax; + $this->_xls_strmax = 255; + $this->_dim_rowmin = $rowmax + 1; + $this->_dim_rowmax = 0; + $this->_dim_colmin = $colmax + 1; + $this->_dim_colmax = 0; + $this->_colinfo = array(); + $this->_selection = array(0,0,0,0); + $this->_panes = array(); + $this->_active_pane = 3; + $this->_frozen = 0; + $this->selected = 0; + + $this->_paper_size = 0x0; + $this->_orientation = 0x1; + $this->_header = ''; + $this->_footer = ''; + $this->_hcenter = 0; + $this->_vcenter = 0; + $this->_margin_head = 0.50; + $this->_margin_foot = 0.50; + $this->_margin_left = 0.75; + $this->_margin_right = 0.75; + $this->_margin_top = 1.00; + $this->_margin_bottom = 1.00; + + $this->title_rowmin = NULL; + $this->title_rowmax = NULL; + $this->title_colmin = NULL; + $this->title_colmax = NULL; + $this->print_rowmin = NULL; + $this->print_rowmax = NULL; + $this->print_colmin = NULL; + $this->print_colmax = NULL; + + $this->_print_gridlines = 1; + $this->_print_headers = 0; + + $this->_fit_page = 0; + $this->_fit_width = 0; + $this->_fit_height = 0; + + $this->_hbreaks = array(); + $this->_vbreaks = array(); + + $this->_protect = 0; + $this->_password = NULL; + + $this->col_sizes = array(); + $this->row_sizes = array(); + + $this->_zoom = 100; + $this->_print_scale = 100; + + $this->_outline_row_level = 0; + $this->_outline_style = 0; + $this->_outline_below = 1; + $this->_outline_right = 1; + $this->_outline_on = 1; + + $this->_merged_ranges = array(); + + $this->_dv = array(); + + $this->_initialize(); + } + + /** + * Open a tmp file to store the majority of the Worksheet data. If this fails, + * for example due to write permissions, store the data in memory. This can be + * slow for large files. + * + * @access private + */ + function _initialize() + { + // Open tmp file for storing Worksheet data + $fh = tmpfile(); + if ( $fh) { + // Store filehandle + $this->_filehandle = $fh; + } + else { + // If tmpfile() fails store data in memory + $this->_using_tmpfile = false; + } + } + + /** + * Add data to the beginning of the workbook (note the reverse order) + * and to the end of the workbook. + * + * @access public + * @see Spreadsheet_Excel_Writer_Workbook::storeWorkbook() + * @param array $sheetnames The array of sheetnames from the Workbook this + * worksheet belongs to + */ + function close($sheetnames) + { + $num_sheets = count($sheetnames); + + /*********************************************** + * Prepend in reverse order!! + */ + + // Prepend the sheet dimensions + $this->_storeDimensions(); + + // Prepend the sheet password + $this->_storePassword(); + + // Prepend the sheet protection + $this->_storeProtect(); + + // Prepend the page setup + $this->_storeSetup(); + + /* FIXME: margins are actually appended */ + // Prepend the bottom margin + $this->_storeMarginBottom(); + + // Prepend the top margin + $this->_storeMarginTop(); + + // Prepend the right margin + $this->_storeMarginRight(); + + // Prepend the left margin + $this->_storeMarginLeft(); + + // Prepend the page vertical centering + $this->_storeVcenter(); + + // Prepend the page horizontal centering + $this->_storeHcenter(); + + // Prepend the page footer + $this->_storeFooter(); + + // Prepend the page header + $this->_storeHeader(); + + // Prepend the vertical page breaks + $this->_storeVbreak(); + + // Prepend the horizontal page breaks + $this->_storeHbreak(); + + // Prepend WSBOOL + $this->_storeWsbool(); + + // Prepend GRIDSET + $this->_storeGridset(); + + // Prepend GUTS + if ($this->_BIFF_version == 0x0500) { + $this->_storeGuts(); + } + + // Prepend PRINTGRIDLINES + $this->_storePrintGridlines(); + + // Prepend PRINTHEADERS + $this->_storePrintHeaders(); + + // Prepend EXTERNSHEET references + if ($this->_BIFF_version == 0x0500) { + for ($i = $num_sheets; $i > 0; $i--) { + $sheetname = $sheetnames[$i-1]; + $this->_storeExternsheet($sheetname); + } + } + + // Prepend the EXTERNCOUNT of external references. + if ($this->_BIFF_version == 0x0500) { + $this->_storeExterncount($num_sheets); + } + + // Prepend the COLINFO records if they exist + if (!empty($this->_colinfo)) + { + for ($i=0; $i < count($this->_colinfo); $i++) { + $this->_storeColinfo($this->_colinfo[$i]); + } + $this->_storeDefcol(); + } + + // Prepend the BOF record + $this->_storeBof(0x0010); + + /* + * End of prepend. Read upwards from here. + ***********************************************/ + + // Append + $this->_storeWindow2(); + $this->_storeZoom(); + if (!empty($this->_panes)) { + $this->_storePanes($this->_panes); + } + $this->_storeSelection($this->_selection); + $this->_storeMergedCells(); + /* TODO: add data validity */ + /*if ($this->_BIFF_version == 0x0600) { + $this->_storeDataValidity(); + }*/ + $this->_storeEof(); + } + + /** + * Retrieve the worksheet name. + * This is usefull when creating worksheets without a name. + * + * @access public + * @return string The worksheet's name + */ + function getName() + { + return $this->name; + } + + /** + * Retrieves data from memory in one chunk, or from disk in $buffer + * sized chunks. + * + * @return string The data + */ + function getData() + { + $buffer = 4096; + + // Return data stored in memory + if (isset($this->_data)) + { + $tmp = $this->_data; + unset($this->_data); + $fh = $this->_filehandle; + if ($this->_using_tmpfile) { + fseek($fh, 0); + } + return $tmp; + } + // Return data stored on disk + if ($this->_using_tmpfile) + { + if ($tmp = fread($this->_filehandle, $buffer)) { + return $tmp; + } + } + + // No data to return + return ''; + } + + /** + * Sets a merged cell range + * + * @access public + * @param integer $first_row First row of the area to merge + * @param integer $first_col First column of the area to merge + * @param integer $last_row Last row of the area to merge + * @param integer $last_col Last column of the area to merge + */ + function setMerge($first_row, $first_col, $last_row, $last_col) + { + if (($last_row < $first_row) or ($last_col < $first_col)) { + return; + } + // don't check rowmin, rowmax, etc... because we don't know when this + // is going to be called + $this->_merged_ranges[] = array($first_row, $first_col, $last_row, $last_col); + } + + /** + * Set this worksheet as a selected worksheet, + * i.e. the worksheet has its tab highlighted. + * + * @access public + */ + function select() + { + $this->selected = 1; + } + + /** + * Set this worksheet as the active worksheet, + * i.e. the worksheet that is displayed when the workbook is opened. + * Also set it as selected. + * + * @access public + */ + function activate() + { + $this->selected = 1; + $this->activesheet = $this->index; + } + + /** + * Set this worksheet as the first visible sheet. + * This is necessary when there are a large number of worksheets and the + * activated worksheet is not visible on the screen. + * + * @access public + */ + function setFirstSheet() + { + $this->firstsheet = $this->index; + } + + /** + * Set the worksheet protection flag + * to prevent accidental modification and to + * hide formulas if the locked and hidden format properties have been set. + * + * @access public + * @param string $password The password to use for protecting the sheet. + */ + function protect($password) + { + $this->_protect = 1; + $this->_password = $this->_encodePassword($password); + } + + /** + * Set the width of a single column or a range of columns. + * + * @access public + * @param integer $firstcol first column on the range + * @param integer $lastcol last column on the range + * @param integer $width width to set + * @param mixed $format The optional XF format to apply to the columns + * @param integer $hidden The optional hidden atribute + * @param integer $level The optional outline level + */ + function setColumn($firstcol, $lastcol, $width, $format = 0, $hidden = 0, $level = 0) + { + $this->_colinfo[] = array($firstcol, $lastcol, $width, &$format, $hidden, $level); + + // Set width to zero if column is hidden + $width = ($hidden) ? 0 : $width; + + for ($col = $firstcol; $col <= $lastcol; $col++) { + $this->col_sizes[$col] = $width; + } + } + + /** + * Set which cell or cells are selected in a worksheet + * + * @access public + * @param integer $first_row first row in the selected quadrant + * @param integer $first_column first column in the selected quadrant + * @param integer $last_row last row in the selected quadrant + * @param integer $last_column last column in the selected quadrant + */ + function setSelection($first_row,$first_column,$last_row,$last_column) + { + $this->_selection = array($first_row,$first_column,$last_row,$last_column); + } + + /** + * Set panes and mark them as frozen. + * + * @access public + * @param array $panes This is the only parameter received and is composed of the following: + * 0 => Vertical split position, + * 1 => Horizontal split position + * 2 => Top row visible + * 3 => Leftmost column visible + * 4 => Active pane + */ + function freezePanes($panes) + { + $this->_frozen = 1; + $this->_panes = $panes; + } + + /** + * Set panes and mark them as unfrozen. + * + * @access public + * @param array $panes This is the only parameter received and is composed of the following: + * 0 => Vertical split position, + * 1 => Horizontal split position + * 2 => Top row visible + * 3 => Leftmost column visible + * 4 => Active pane + */ + function thawPanes($panes) + { + $this->_frozen = 0; + $this->_panes = $panes; + } + + /** + * Set the page orientation as portrait. + * + * @access public + */ + function setPortrait() + { + $this->_orientation = 1; + } + + /** + * Set the page orientation as landscape. + * + * @access public + */ + function setLandscape() + { + $this->_orientation = 0; + } + + /** + * Set the paper type. Ex. 1 = US Letter, 9 = A4 + * + * @access public + * @param integer $size The type of paper size to use + */ + function setPaper($size = 0) + { + $this->_paper_size = $size; + } + + + /** + * Set the page header caption and optional margin. + * + * @access public + * @param string $string The header text + * @param float $margin optional head margin in inches. + */ + function setHeader($string,$margin = 0.50) + { + if (strlen($string) >= 255) { + //carp 'Header string must be less than 255 characters'; + return; + } + $this->_header = $string; + $this->_margin_head = $margin; + } + + /** + * Set the page footer caption and optional margin. + * + * @access public + * @param string $string The footer text + * @param float $margin optional foot margin in inches. + */ + function setFooter($string,$margin = 0.50) + { + if (strlen($string) >= 255) { + //carp 'Footer string must be less than 255 characters'; + return; + } + $this->_footer = $string; + $this->_margin_foot = $margin; + } + + /** + * Center the page horinzontally. + * + * @access public + * @param integer $center the optional value for centering. Defaults to 1 (center). + */ + function centerHorizontally($center = 1) + { + $this->_hcenter = $center; + } + + /** + * Center the page vertically. + * + * @access public + * @param integer $center the optional value for centering. Defaults to 1 (center). + */ + function centerVertically($center = 1) + { + $this->_vcenter = $center; + } + + /** + * Set all the page margins to the same value in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMargins($margin) + { + $this->setMarginLeft($margin); + $this->setMarginRight($margin); + $this->setMarginTop($margin); + $this->setMarginBottom($margin); + } + + /** + * Set the left and right margins to the same value in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMargins_LR($margin) + { + $this->setMarginLeft($margin); + $this->setMarginRight($margin); + } + + /** + * Set the top and bottom margins to the same value in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMargins_TB($margin) + { + $this->setMarginTop($margin); + $this->setMarginBottom($margin); + } + + /** + * Set the left margin in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMarginLeft($margin = 0.75) + { + $this->_margin_left = $margin; + } + + /** + * Set the right margin in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMarginRight($margin = 0.75) + { + $this->_margin_right = $margin; + } + + /** + * Set the top margin in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMarginTop($margin = 1.00) + { + $this->_margin_top = $margin; + } + + /** + * Set the bottom margin in inches. + * + * @access public + * @param float $margin The margin to set in inches + */ + function setMarginBottom($margin = 1.00) + { + $this->_margin_bottom = $margin; + } + + /** + * Set the rows to repeat at the top of each printed page. + * + * @access public + * @param integer $first_row First row to repeat + * @param integer $last_row Last row to repeat. Optional. + */ + function repeatRows($first_row, $last_row = NULL) + { + $this->title_rowmin = $first_row; + if (isset($last_row)) { //Second row is optional + $this->title_rowmax = $last_row; + } + else { + $this->title_rowmax = $first_row; + } + } + + /** + * Set the columns to repeat at the left hand side of each printed page. + * + * @access public + * @param integer $first_col First column to repeat + * @param integer $last_col Last column to repeat. Optional. + */ + function repeatColumns($first_col, $last_col = NULL) + { + $this->title_colmin = $first_col; + if (isset($last_col)) { // Second col is optional + $this->title_colmax = $last_col; + } + else { + $this->title_colmax = $first_col; + } + } + + /** + * Set the area of each worksheet that will be printed. + * + * @access public + * @param integer $first_row First row of the area to print + * @param integer $first_col First column of the area to print + * @param integer $last_row Last row of the area to print + * @param integer $last_col Last column of the area to print + */ + function printArea($first_row, $first_col, $last_row, $last_col) + { + $this->print_rowmin = $first_row; + $this->print_colmin = $first_col; + $this->print_rowmax = $last_row; + $this->print_colmax = $last_col; + } + + + /** + * Set the option to hide gridlines on the printed page. + * + * @access public + */ + function hideGridlines() + { + $this->_print_gridlines = 0; + } + + /** + * Set the option to print the row and column headers on the printed page. + * + * @access public + * @param integer $print Whether to print the headers or not. Defaults to 1 (print). + */ + function printRowColHeaders($print = 1) + { + $this->_print_headers = $print; + } + + /** + * Set the vertical and horizontal number of pages that will define the maximum area printed. + * It doesn't seem to work with OpenOffice. + * + * @access public + * @param integer $width Maximun width of printed area in pages + * @param integer $height Maximun heigth of printed area in pages + * @see setPrintScale() + */ + function fitToPages($width, $height) + { + $this->_fit_page = 1; + $this->_fit_width = $width; + $this->_fit_height = $height; + } + + /** + * Store the horizontal page breaks on a worksheet (for printing). + * The breaks represent the row after which the break is inserted. + * + * @access public + * @param array $breaks Array containing the horizontal page breaks + */ + function setHPagebreaks($breaks) + { + foreach($breaks as $break) { + array_push($this->_hbreaks,$break); + } + } + + /** + * Store the vertical page breaks on a worksheet (for printing). + * The breaks represent the column after which the break is inserted. + * + * @access public + * @param array $breaks Array containing the vertical page breaks + */ + function setVPagebreaks($breaks) + { + foreach($breaks as $break) { + array_push($this->_vbreaks,$break); + } + } + + + /** + * Set the worksheet zoom factor. + * + * @access public + * @param integer $scale The zoom factor + */ + function setZoom($scale = 100) + { + // Confine the scale to Excel's range + if ($scale < 10 or $scale > 400) + { + $this->raiseError("Zoom factor $scale outside range: 10 <= zoom <= 400"); + $scale = 100; + } + + $this->_zoom = floor($scale); + } + + /** + * Set the scale factor for the printed page. + * It turns off the "fit to page" option + * + * @access public + * @param integer $scale The optional scale factor. Defaults to 100 + */ + function setPrintScale($scale = 100) + { + // Confine the scale to Excel's range + if ($scale < 10 or $scale > 400) + { + $this->raiseError("Print scale $scale outside range: 10 <= zoom <= 400"); + $scale = 100; + } + + // Turn off "fit to page" option + $this->_fit_page = 0; + + $this->_print_scale = floor($scale); + } + + /** + * Map to the appropriate write method acording to the token recieved. + * + * @access public + * @param integer $row The row of the cell we are writing to + * @param integer $col The column of the cell we are writing to + * @param mixed $token What we are writing + * @param mixed $format The optional format to apply to the cell + */ + function write($row, $col, $token, $format = 0) + { + // Check for a cell reference in A1 notation and substitute row and column + /*if ($_[0] =~ /^\D/) { + @_ = $this->_substituteCellref(@_); + }*/ + + + // Match number + if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/",$token)) { + return $this->writeNumber($row,$col,$token,$format); + } + // Match http or ftp URL + elseif (preg_match("/^[fh]tt?p:\/\//",$token)) { + return $this->writeUrl($row, $col, $token, '', $format); + } + // Match mailto: + elseif (preg_match("/^mailto:/",$token)) { + return $this->writeUrl($row, $col, $token, '', $format); + } + // Match internal or external sheet link + elseif (preg_match("/^(?:in|ex)ternal:/",$token)) { + return $this->writeUrl($row, $col, $token, '', $format); + } + // Match formula + elseif (preg_match("/^=/",$token)) { + return $this->writeFormula($row, $col, $token, $format); + } + // Match formula + elseif (preg_match("/^@/",$token)) { + return $this->writeFormula($row, $col, $token, $format); + } + // Match blank + elseif ($token == '') { + return $this->writeBlank($row,$col,$format); + } + // Default: match string + else { + return $this->writeString($row,$col,$token,$format); + } + } + + /** + * Write an array of values as a row + * + * @access public + * @param integer $row The row we are writing to + * @param integer $col The first col (leftmost col) we are writing to + * @param array $val The array of values to write + * @param mixed $format The optional format to apply to the cell + * @return mixed PEAR_Error on failure + */ + + function writeRow($row, $col, $val, $format=0) + { + $retval = ''; + if (is_array($val)) { + foreach($val as $v) { + if (is_array($v)) { + $this->writeCol($row, $col, $v, $format); + } else { + $this->write($row, $col, $v, $format); + } + $col++; + } + } else { + $retval = new PEAR_Error('$val needs to be an array'); + } + return($retval); + } + + /** + * Write an array of values as a column + * + * @access public + * @param integer $row The first row (uppermost row) we are writing to + * @param integer $col The col we are writing to + * @param array $val The array of values to write + * @param mixed $format The optional format to apply to the cell + * @return mixed PEAR_Error on failure + */ + + function writeCol($row, $col, $val, $format=0) + { + $retval = ''; + if (is_array($val)) { + foreach($val as $v) { + $this->write($row, $col, $v, $format); + $row++; + } + } else { + $retval = new PEAR_Error('$val needs to be an array'); + } + return($retval); + } + + /** + * Returns an index to the XF record in the workbook + * + * @access private + * @param mixed &$format The optional XF format + * @return integer The XF record index + */ + function _XF(&$format) + { + if ($format != 0) { + return($format->getXfIndex()); + } + else { + return(0x0F); + } + } + + + /****************************************************************************** + ******************************************************************************* + * + * Internal methods + */ + + + /** + * Store Worksheet data in memory using the parent's class append() or to a + * temporary file, the default. + * + * @access private + * @param string $data The binary data to append + */ + function _append($data) + { + if ($this->_using_tmpfile) + { + // Add CONTINUE records if necessary + if (strlen($data) > $this->_limit) { + $data = $this->_addContinue($data); + } + fwrite($this->_filehandle,$data); + $this->_datasize += strlen($data); + } + else { + parent::_append($data); + } + } + + /** + * Substitute an Excel cell reference in A1 notation for zero based row and + * column values in an argument list. + * + * Ex: ("A4", "Hello") is converted to (3, 0, "Hello"). + * + * @access private + * @param string $cell The cell reference. Or range of cells. + * @return array + */ + function _substituteCellref($cell) + { + $cell = strtoupper($cell); + + // Convert a column range: 'A:A' or 'B:G' + if (preg_match("/([A-I]?[A-Z]):([A-I]?[A-Z])/",$cell,$match)) { + list($no_use, $col1) = $this->_cellToRowcol($match[1] .'1'); // Add a dummy row + list($no_use, $col2) = $this->_cellToRowcol($match[2] .'1'); // Add a dummy row + return(array($col1, $col2)); + } + + // Convert a cell range: 'A1:B7' + if (preg_match("/\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)/",$cell,$match)) { + list($row1, $col1) = $this->_cellToRowcol($match[1]); + list($row2, $col2) = $this->_cellToRowcol($match[2]); + return(array($row1, $col1, $row2, $col2)); + } + + // Convert a cell reference: 'A1' or 'AD2000' + if (preg_match("/\$?([A-I]?[A-Z]\$?\d+)/",$cell)) { + list($row1, $col1) = $this->_cellToRowcol($match[1]); + return(array($row1, $col1)); + } + + // TODO use real error codes + $this->raiseError("Unknown cell reference $cell", 0, PEAR_ERROR_DIE); + } + + /** + * Convert an Excel cell reference in A1 notation to a zero based row and column + * reference; converts C1 to (0, 2). + * + * @access private + * @param string $cell The cell reference. + * @return array containing (row, column) + */ + function _cellToRowcol($cell) + { + preg_match("/\$?([A-I]?[A-Z])\$?(\d+)/",$cell,$match); + $col = $match[1]; + $row = $match[2]; + + // Convert base26 column string to number + $chars = split('', $col); + $expn = 0; + $col = 0; + + while ($chars) { + $char = array_pop($chars); // LS char first + $col += (ord($char) -ord('A') +1) * pow(26,$expn); + $expn++; + } + + // Convert 1-index to zero-index + $row--; + $col--; + + return(array($row, $col)); + } + + /** + * Based on the algorithm provided by Daniel Rentz of OpenOffice. + * + * @access private + * @param string $plaintext The password to be encoded in plaintext. + * @return string The encoded password + */ + function _encodePassword($plaintext) + { + $password = 0x0000; + $i = 1; // char position + + // split the plain text password in its component characters + $chars = preg_split('//', $plaintext, -1, PREG_SPLIT_NO_EMPTY); + foreach($chars as $char) + { + $value = ord($char) << $i; // shifted ASCII value + $rotated_bits = $value >> 15; // rotated bits beyond bit 15 + $value &= 0x7fff; // first 15 bits + $password ^= ($value | $rotated_bits); + $i++; + } + + $password ^= strlen($plaintext); + $password ^= 0xCE4B; + + return($password); + } + + /** + * This method sets the properties for outlining and grouping. The defaults + * correspond to Excel's defaults. + * + * @param bool $visible + * @param bool $symbols_below + * @param bool $symbols_right + * @param bool $auto_style + */ + function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) + { + $this->_outline_on = $visible; + $this->_outline_below = $symbols_below; + $this->_outline_right = $symbols_right; + $this->_outline_style = $auto_style; + + // Ensure this is a boolean vale for Window2 + if ($this->_outline_on) { + $this->_outline_on = 1; + } + } + + /****************************************************************************** + ******************************************************************************* + * + * BIFF RECORDS + */ + + + /** + * Write a double to the specified row and column (zero indexed). + * An integer can be written as a double. Excel will display an + * integer. $format is optional. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param float $num The number to write + * @param mixed $format The optional XF format + * @return integer + */ + function writeNumber($row, $col, $num, $format = 0) + { + + + $record = 0x0203; // Record identifier + $length = 0x000E; // Number of bytes to follow + + $xf = $this->_XF($format); // The cell format + + // Check that row and col are valid and store max and min values + if ($row >= $this->_xls_rowmax) + { + return(-2); + } + if ($col >= $this->_xls_colmax) + { + return(-2); + } + if ($row < $this->_dim_rowmin) + { + $this->_dim_rowmin = $row; + } + if ($row > $this->_dim_rowmax) + { + $this->_dim_rowmax = $row; + } + if ($col < $this->_dim_colmin) + { + $this->_dim_colmin = $col; + } + if ($col > $this->_dim_colmax) + { + $this->_dim_colmax = $col; + } + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xf); + $xl_double = pack("d", $num); + if ($this->_byte_order) // if it's Big Endian + { + $xl_double = strrev($xl_double); + } + + $this->_append($header.$data.$xl_double); + return(0); + } + + /** + * Write a string to the specified row and column (zero indexed). + * NOTE: there is an Excel 5 defined limit of 255 characters. + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $format The XF format for the cell + * @return integer + */ + function writeString($row, $col, $str, $format = 0) + { + + + + if ($this->_BIFF_version == 0x0600) { + return $this->writeStringBIFF8($row, $col, $str, $format); + } + + $strlen = strlen($str); + $record = 0x0204; // Record identifier + $length = 0x0008 + $strlen; // Bytes to follow + $xf = $this->_XF($format); // The cell format + + $str_error = 0; + + // Check that row and col are valid and store max and min values + if ($row >= $this->_xls_rowmax) + { + return(-2); + } + if ($col >= $this->_xls_colmax) + { + return(-2); + } + if ($row < $this->_dim_rowmin) + { + $this->_dim_rowmin = $row; + } + if ($row > $this->_dim_rowmax) + { + $this->_dim_rowmax = $row; + } + if ($col < $this->_dim_colmin) + { + $this->_dim_colmin = $col; + } + if ($col > $this->_dim_colmax) + { + $this->_dim_colmax = $col; + } + + if ($strlen > $this->_xls_strmax) // LABEL must be < 255 chars + { + $str = substr($str, 0, $this->_xls_strmax); + $length = 0x0008 + $this->_xls_strmax; + $strlen = $this->_xls_strmax; + $str_error = -3; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row, $col, $xf, $strlen); + $this->_append($header.$data.$str); + return($str_error); + } + + function writeStringBIFF8($row, $col, $str, $format = 0) + { + $strlen = strlen($str); + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + $xf = $this->_XF($format); // The cell format + $encoding = 0x0; + + $str_error = 0; + + // Check that row and col are valid and store max and min values + if ($this->_checkRowCol($row, $col) == false) { + return -2; + } + + $str = pack('vC', $strlen, $encoding).$str; + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xf, $this->_str_table[$str]); + $this->_append($header.$data); + return $str_error; + } + + /** + * Check row and col before writing to a cell, and update the sheet's + * dimensions accordingly + * + * @access private + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @return boolean true for success, false if row and/or col are grester + * then maximums allowed. + */ + function _checkRowCol($row, $col) + { + if ($row >= $this->_xls_rowmax) { + return false; + } + if ($col >= $this->_xls_colmax) { + return false; + } + if ($row < $this->_dim_rowmin) { + $this->_dim_rowmin = $row; + } + if ($row > $this->_dim_rowmax) { + $this->_dim_rowmax = $row; + } + if ($col < $this->_dim_colmin) { + $this->_dim_colmin = $col; + } + if ($col > $this->_dim_colmax) { + $this->_dim_colmax = $col; + } + return true; + } + + /** + * Writes a note associated with the cell given by the row and column. + * NOTE records don't have a length limit. + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $note The note to write + */ + function writeNote($row, $col, $note) + { + $note_length = strlen($note); + $record = 0x001C; // Record identifier + $max_length = 2048; // Maximun length for a NOTE record + //$length = 0x0006 + $note_length; // Bytes to follow + + // Check that row and col are valid and store max and min values + if ($row >= $this->_xls_rowmax) + { + return(-2); + } + if ($col >= $this->_xls_colmax) + { + return(-2); + } + if ($row < $this->_dim_rowmin) + { + $this->_dim_rowmin = $row; + } + if ($row > $this->_dim_rowmax) + { + $this->_dim_rowmax = $row; + } + if ($col < $this->_dim_colmin) + { + $this->_dim_colmin = $col; + } + if ($col > $this->_dim_colmax) + { + $this->_dim_colmax = $col; + } + + // Length for this record is no more than 2048 + 6 + $length = 0x0006 + min($note_length, 2048); + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $note_length); + $this->_append($header.$data.substr($note, 0, 2048)); + + for($i = $max_length; $i < $note_length; $i += $max_length) + { + $chunk = substr($note, $i, $max_length); + $length = 0x0006 + strlen($chunk); + $header = pack("vv", $record, $length); + $data = pack("vvv", -1, 0, strlen($chunk)); + $this->_append($header.$data.$chunk); + } + return(0); + } + + /** + * Write a blank cell to the specified row and column (zero indexed). + * A blank cell is used to specify formatting without adding a string + * or a number. + * + * A blank cell without a format serves no purpose. Therefore, we don't write + * a BLANK record unless a format is specified. + * + * Returns 0 : normal termination (including no format) + * -1 : insufficient number of arguments + * -2 : row or column out of range + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $format The XF format + */ + function writeBlank($row, $col, $format) + { + // Don't write a blank cell unless it has a format + if ($format == 0) + { + return(0); + } + + $record = 0x0201; // Record identifier + $length = 0x0006; // Number of bytes to follow + $xf = $this->_XF($format); // The cell format + + // Check that row and col are valid and store max and min values + if ($row >= $this->_xls_rowmax) + { + return(-2); + } + if ($col >= $this->_xls_colmax) + { + return(-2); + } + if ($row < $this->_dim_rowmin) + { + $this->_dim_rowmin = $row; + } + if ($row > $this->_dim_rowmax) + { + $this->_dim_rowmax = $row; + } + if ($col < $this->_dim_colmin) + { + $this->_dim_colmin = $col; + } + if ($col > $this->_dim_colmax) + { + $this->_dim_colmax = $col; + } + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xf); + $this->_append($header.$data); + return 0; + } + + /** + * Write a formula to the specified row and column (zero indexed). + * The textual representation of the formula is passed to the parser in + * Parser.php which returns a packed binary string. + * + * Returns 0 : normal termination + * -1 : formula errors (bad formula) + * -2 : row or column out of range + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $formula The formula text string + * @param mixed $format The optional XF format + * @return integer + */ + function writeFormula($row, $col, $formula, $format = 0) + { + $record = 0x0006; // Record identifier + + // Excel normally stores the last calculated value of the formula in $num. + // Clearly we are not in a position to calculate this a priori. Instead + // we set $num to zero and set the option flags in $grbit to ensure + // automatic calculation of the formula when the file is opened. + // + $xf = $this->_XF($format); // The cell format + $num = 0x00; // Current value of formula + $grbit = 0x03; // Option flags + $unknown = 0x0000; // Must be zero + + + // Check that row and col are valid and store max and min values + if ($this->_checkRowCol($row, $col) == false) { + return -2; + } + + // Strip the '=' or '@' sign at the beginning of the formula string + if (preg_match("/^=/",$formula)) { + $formula = preg_replace("/(^=)/","",$formula); + } + elseif (preg_match("/^@/",$formula)) { + $formula = preg_replace("/(^@)/","",$formula); + } + else + { + // Error handling + $this->writeString($row, $col, 'Unrecognised character for formula'); + return -1; + } + + // Parse the formula using the parser in Parser.php + $error = $this->_parser->parse($formula); + if ($this->isError($error)) + { + $this->writeString($row, $col, $error->getMessage()); + return -1; + } + + $formula = $this->_parser->toReversePolish(); + if ($this->isError($formula)) + { + $this->writeString($row, $col, $formula->getMessage()); + return -1; + } + + $formlen = strlen($formula); // Length of the binary string + $length = 0x16 + $formlen; // Length of the record data + + $header = pack("vv", $record, $length); + $data = pack("vvvdvVv", $row, $col, $xf, $num, + $grbit, $unknown, $formlen); + + $this->_append($header.$data.$formula); + return 0; + } + + /** + * Write a hyperlink. + * This is comprised of two elements: the visible label and + * the invisible link. The visible label is the same as the link unless an + * alternative string is specified. The label is written using the + * writeString() method. Therefore the 255 characters string limit applies. + * $string and $format are optional. + * + * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external + * directory url. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Row + * @param integer $col Column + * @param string $url URL string + * @param string $string Alternative label + * @param mixed $format The cell format + * @return integer + */ + function writeUrl($row, $col, $url, $string = '', $format = 0) + { + // Add start row and col to arg list + return($this->_writeUrlRange($row, $col, $row, $col, $url, $string, $format)); + } + + /** + * This is the more general form of writeUrl(). It allows a hyperlink to be + * written to a range of cells. This function also decides the type of hyperlink + * to be written. These are either, Web (http, ftp, mailto), Internal + * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). + * + * @access private + * @see writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @param string $string Alternative label + * @param mixed $format The cell format + * @return integer + */ + + function _writeUrlRange($row1, $col1, $row2, $col2, $url, $string = '', $format = 0) + { + + // Check for internal/external sheet links or default to web link + if (preg_match('[^internal:]', $url)) { + return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url, $string, $format)); + } + if (preg_match('[^external:]', $url)) { + return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url, $string, $format)); + } + return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url, $string, $format)); + } + + + /** + * Used to write http, ftp and mailto hyperlinks. + * The link type ($options) is 0x03 is the same as absolute dir ref without + * sheet. However it is differentiated by the $unknown2 data stream. + * + * @access private + * @see writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @param string $str Alternative label + * @param mixed $format The cell format + * @return integer + */ + function _writeUrlWeb($row1, $col1, $row2, $col2, $url, $str, $format = 0) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + if ($format == 0) { + $format = $this->_url_format; + } + + // Write the visible label using the writeString() method. + if ($str == '') { + $str = $url; + } + $str_error = $this->writeString($row1, $col1, $str, $format); + if (($str_error == -2) or ($str_error == -3)) { + return $str_error; + } + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); + + // Pack the option flags + $options = pack("V", 0x03); + + // Convert URL to a null terminated wchar string + $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); + $url = $url . "\0\0\0"; + + // Pack the length of the URL + $url_len = pack("V", strlen($url)); + + // Calculate the data length + $length = 0x34 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append( $header. $data. + $unknown1. $options. + $unknown2. $url_len. $url); + return($str_error); + } + + /** + * Used to write internal reference hyperlinks such as "Sheet1!A1". + * + * @access private + * @see writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @param string $str Alternative label + * @param mixed $format The cell format + * @return integer + */ + function _writeUrlInternal($row1, $col1, $row2, $col2, $url, $str, $format = 0) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + if ($format == 0) { + $format = $this->_url_format; + } + + // Strip URL type + $url = preg_replace('s[^internal:]', '', $url); + + // Write the visible label + if ($str == '') { + $str = $url; + } + $str_error = $this->writeString($row1, $col1, $str, $format); + if (($str_error == -2) or ($str_error == -3)) { + return $str_error; + } + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + + // Pack the option flags + $options = pack("V", 0x08); + + // Convert the URL type and to a null terminated wchar string + $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); + $url = $url . "\0\0\0"; + + // Pack the length of the URL as chars (not wchars) + $url_len = pack("V", floor(strlen($url)/2)); + + // Calculate the data length + $length = 0x24 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header. $data. + $unknown1. $options. + $url_len. $url); + return($str_error); + } + + /** + * Write links to external directory names such as 'c:\foo.xls', + * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. + * + * Note: Excel writes some relative links with the $dir_long string. We ignore + * these cases for the sake of simpler code. + * + * @access private + * @see writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @param string $str Alternative label + * @param mixed $format The cell format + * @return integer + */ + function _writeUrlExternal($row1, $col1, $row2, $col2, $url, $str, $format = 0) + { + // Network drives are different. We will handle them separately + // MS/Novell network drives and shares start with \\ + if (preg_match('[^external:\\\\]', $url)) { + return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); + } + + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + if ($format == 0) { + $format = $this->_url_format; + } + + // Strip URL type and change Unix dir separator to Dos style (if needed) + // + $url = preg_replace('[^external:]', '', $url); + $url = preg_replace('[/]', "\\", $url); + + // Write the visible label + if ($str == '') { + $str = preg_replace('[\#]', ' - ', $url); + } + $str_error = $this->writeString($row1, $col1, $str, $format); + if (($str_error == -2) or ($str_error == -3)) { + return $str_error; + } + + // Determine if the link is relative or absolute: + // relative if link contains no dir separator, "somefile.xls" + // relative if link starts with up-dir, "..\..\somefile.xls" + // otherwise, absolute + + $absolute = 0x02; // Bit mask + if (!preg_match('[\\]', $url)) { + $absolute = 0x00; + } + if (preg_match('[^\.\.\\]', $url)) { + $absolute = 0x00; + } + + // Determine if the link contains a sheet reference and change some of the + // parameters accordingly. + // Split the dir name and sheet name (if it exists) + list($dir_long , $sheet) = split('/\#/', $url); + $link_type = 0x01 | $absolute; + + if (isset($sheet)) { + $link_type |= 0x08; + $sheet_len = pack("V", strlen($sheet) + 0x01); + $sheet = join("\0", split('', $sheet)); + $sheet .= "\0\0\0"; + } + else { + $sheet_len = ''; + $sheet = ''; + } + + // Pack the link type + $link_type = pack("V", $link_type); + + // Calculate the up-level dir count e.g.. (..\..\..\ == 3) + $up_count = preg_match_all("/\.\.\\/", $dir_long, $useless); + $up_count = pack("v", $up_count); + + // Store the short dos dir name (null terminated) + $dir_short = preg_replace('/\.\.\\/', '', $dir_long) . "\0"; + + // Store the long dir name as a wchar string (non-null terminated) + $dir_long = join("\0", split('', $dir_long)); + $dir_long = $dir_long . "\0"; + + // Pack the lengths of the dir strings + $dir_short_len = pack("V", strlen($dir_short) ); + $dir_long_len = pack("V", strlen($dir_long) ); + $stream_len = pack("V", strlen($dir_long) + 0x06); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); + $unknown2 = pack("H*",'0303000000000000C000000000000046' ); + $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); + $unknown4 = pack("v", 0x03 ); + + // Pack the main data stream + $data = pack("vvvv", $row1, $row2, $col1, $col2) . + $unknown1 . + $link_type . + $unknown2 . + $up_count . + $dir_short_len. + $dir_short . + $unknown3 . + $stream_len . + $dir_long_len . + $unknown4 . + $dir_long . + $sheet_len . + $sheet ; + + // Pack the header data + $length = strlen($data); + $header = pack("vv", $record, $length); + + // Write the packed data + $this->_append($header. $data); + return($str_error); + } + + + /** + * This method is used to set the height and format for a row. + * + * @access public + * @param integer $row The row to set + * @param integer $height Height we are giving to the row. + * Use NULL to set XF without setting height + * @param mixed $format XF format we are giving to the row + * @param bool $hidden The optional hidden attribute + * @param integer $level The optional outline level for row, in range [0,7] + */ + function setRow($row, $height, $format = 0, $hidden = false, $level = 0) + { + $record = 0x0208; // Record identifier + $length = 0x0010; // Number of bytes to follow + + $colMic = 0x0000; // First defined column + $colMac = 0x0000; // Last defined column + $irwMac = 0x0000; // Used by Excel to optimise loading + $reserved = 0x0000; // Reserved + $grbit = 0x0000; // Option flags + $ixfe = $this->_XF($format); // XF index + + // Use setRow($row, NULL, $XF) to set XF format without setting height + if ($height != NULL) { + $miyRw = $height * 20; // row height + } + else { + $miyRw = 0xff; // default row height is 256 + } + + $level = max(0, min($level, 7)); // level should be between 0 and 7 + $this->_outline_row_level = max($level, $this->_outline_row_level); + + + // Set the options flags. fUnsynced is used to show that the font and row + // heights are not compatible. This is usually the case for WriteExcel. + // The collapsed flag 0x10 doesn't seem to be used to indicate that a row + // is collapsed. Instead it is used to indicate that the previous row is + // collapsed. The zero height flag, 0x20, is used to collapse a row. + + $grbit |= $level; + if ($hidden) { + $grbit |= 0x0020; + } + $grbit |= 0x0040; // fUnsynced + if ($format) { + $grbit |= 0x0080; + } + $grbit |= 0x0100; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, + $irwMac,$reserved, $grbit, $ixfe); + $this->_append($header.$data); + } + + /** + * Writes Excel DIMENSIONS to define the area in which there is data. + * + * @access private + */ + function _storeDimensions() + { + $record = 0x0200; // Record identifier + $row_min = $this->_dim_rowmin; // First row + $row_max = $this->_dim_rowmax + 1; // Last row plus 1 + $col_min = $this->_dim_colmin; // First column + $col_max = $this->_dim_colmax + 1; // Last column plus 1 + $reserved = 0x0000; // Reserved by Excel + + if ($this->_BIFF_version == 0x0500) { + $length = 0x000A; // Number of bytes to follow + $data = pack("vvvvv", $row_min, $row_max, + $col_min, $col_max, $reserved); + } + elseif ($this->_BIFF_version == 0x0600) { + $length = 0x000E; + $data = pack("VVvvv", $row_min, $row_max, + $col_min, $col_max, $reserved); + } + $header = pack("vv", $record, $length); + $this->_prepend($header.$data); + } + + /** + * Write BIFF record Window2. + * + * @access private + */ + function _storeWindow2() + { + $record = 0x023E; // Record identifier + if ($this->_BIFF_version == 0x0500) { + $length = 0x000A; // Number of bytes to follow + } + elseif ($this->_BIFF_version == 0x0600) { + $length = 0x0012; + } + + $grbit = 0x00B6; // Option flags + $rwTop = 0x0000; // Top row visible in window + $colLeft = 0x0000; // Leftmost column visible in window + + + // The options flags that comprise $grbit + $fDspFmla = 0; // 0 - bit + $fDspGrid = 1; // 1 + $fDspRwCol = 1; // 2 + $fFrozen = $this->_frozen; // 3 + $fDspZeros = 1; // 4 + $fDefaultHdr = 1; // 5 + $fArabic = 0; // 6 + $fDspGuts = $this->_outline_on; // 7 + $fFrozenNoSplit = 0; // 0 - bit + $fSelected = $this->selected; // 1 + $fPaged = 1; // 2 + + $grbit = $fDspFmla; + $grbit |= $fDspGrid << 1; + $grbit |= $fDspRwCol << 2; + $grbit |= $fFrozen << 3; + $grbit |= $fDspZeros << 4; + $grbit |= $fDefaultHdr << 5; + $grbit |= $fArabic << 6; + $grbit |= $fDspGuts << 7; + $grbit |= $fFrozenNoSplit << 8; + $grbit |= $fSelected << 9; + $grbit |= $fPaged << 10; + + $header = pack("vv", $record, $length); + $data = pack("vvv", $grbit, $rwTop, $colLeft); + // FIXME !!! + if ($this->_BIFF_version == 0x0500) { + $rgbHdr = 0x00000000; // Row/column heading and gridline color + $data .= pack("V", $rgbHdr); + } + elseif ($this->_BIFF_version == 0x0600) { + $rgbHdr = 0x0040; // Row/column heading and gridline color index + $zoom_factor_page_break = 0x0000; + $zoom_factor_normal = 0x0000; + $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); + } + $this->_append($header.$data); + } + + /** + * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. + * + * @access private + */ + function _storeDefcol() + { + $record = 0x0055; // Record identifier + $length = 0x0002; // Number of bytes to follow + $colwidth = 0x0008; // Default column width + + $header = pack("vv", $record, $length); + $data = pack("v", $colwidth); + $this->_prepend($header.$data); + } + + /** + * Write BIFF record COLINFO to define column widths + * + * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C + * length record. + * + * @access private + * @param array $col_array This is the only parameter received and is composed of the following: + * 0 => First formatted column, + * 1 => Last formatted column, + * 2 => Col width (8.43 is Excel default), + * 3 => The optional XF format of the column, + * 4 => Option flags. + * 5 => Optional outline level + */ + function _storeColinfo($col_array) + { + if (isset($col_array[0])) { + $colFirst = $col_array[0]; + } + if (isset($col_array[1])) { + $colLast = $col_array[1]; + } + if (isset($col_array[2])) { + $coldx = $col_array[2]; + } + else { + $coldx = 8.43; + } + if (isset($col_array[3])) { + $format = $col_array[3]; + } + else { + $format = 0; + } + if (isset($col_array[4])) { + $grbit = $col_array[4]; + } + else { + $grbit = 0; + } + if (isset($col_array[5])) { + $level = $col_array[5]; + } + else { + $level = 0; + } + $record = 0x007D; // Record identifier + $length = 0x000B; // Number of bytes to follow + + $coldx += 0.72; // Fudge. Excel subtracts 0.72 !? + $coldx *= 256; // Convert to units of 1/256 of a char + + $ixfe = $this->_XF($format); + $reserved = 0x00; // Reserved + + $level = max(0, min($level, 7)); + $grbit |= $level << 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvC", $colFirst, $colLast, $coldx, + $ixfe, $grbit, $reserved); + $this->_prepend($header.$data); + } + + /** + * Write BIFF record SELECTION. + * + * @access private + * @param array $array array containing ($rwFirst,$colFirst,$rwLast,$colLast) + * @see setSelection() + */ + function _storeSelection($array) + { + list($rwFirst,$colFirst,$rwLast,$colLast) = $array; + $record = 0x001D; // Record identifier + $length = 0x000F; // Number of bytes to follow + + $pnn = $this->_active_pane; // Pane position + $rwAct = $rwFirst; // Active row + $colAct = $colFirst; // Active column + $irefAct = 0; // Active cell ref + $cref = 1; // Number of refs + + if (!isset($rwLast)) { + $rwLast = $rwFirst; // Last row in reference + } + if (!isset($colLast)) { + $colLast = $colFirst; // Last col in reference + } + + // Swap last row/col for first row/col as necessary + if ($rwFirst > $rwLast) + { + list($rwFirst, $rwLast) = array($rwLast, $rwFirst); + } + + if ($colFirst > $colLast) + { + list($colFirst, $colLast) = array($colLast, $colFirst); + } + + $header = pack("vv", $record, $length); + $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, + $irefAct, $cref, + $rwFirst, $rwLast, + $colFirst, $colLast); + $this->_append($header.$data); + } + + /** + * Store the MERGEDCELLS record for all ranges of merged cells + * + * @access private + */ + function _storeMergedCells() + { + // if there are no merged cell ranges set, return + if (count($this->_merged_ranges) == 0) { + return; + } + $record = 0x00E5; + $length = 2 + count($this->_merged_ranges) * 8; + + $header = pack('vv', $record, $length); + $data = pack('v', count($this->_merged_ranges)); + foreach ($this->_merged_ranges as $range) { + $data .= pack('vvvv', $range[0], $range[2], $range[1], $range[3]); + } + $this->_append($header.$data); + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in a worksheet. + * + * Excel only stores references to external sheets that are used in formulas. + * For simplicity we store references to all the sheets in the workbook + * regardless of whether they are used or not. This reduces the overall + * complexity and eliminates the need for a two way dialogue between the formula + * parser the worksheet objects. + * + * @access private + * @param integer $count The number of external sheet references in this worksheet + */ + function _storeExterncount($count) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $count); + $this->_prepend($header.$data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. A formula references a sheet name via an index. Since we store a + * reference to all of the external worksheets the EXTERNSHEET index is the same + * as the worksheet index. + * + * @access private + * @param string $sheetname The name of a external worksheet + */ + function _storeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + + // References to the current sheet are encoded differently to references to + // external sheets. + // + if ($this->name == $sheetname) { + $sheetname = ''; + $length = 0x02; // The following 2 bytes + $cch = 1; // The following byte + $rgch = 0x02; // Self reference + } + else { + $length = 0x02 + strlen($sheetname); + $cch = strlen($sheetname); + $rgch = 0x03; // Reference to a sheet in the current workbook + } + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_prepend($header.$data.$sheetname); + } + + /** + * Writes the Excel BIFF PANE record. + * The panes can either be frozen or thawed (unfrozen). + * Frozen panes are specified in terms of an integer number of rows and columns. + * Thawed panes are specified in terms of Excel's units for rows and columns. + * + * @access private + * @param array $panes This is the only parameter received and is composed of the following: + * 0 => Vertical split position, + * 1 => Horizontal split position + * 2 => Top row visible + * 3 => Leftmost column visible + * 4 => Active pane + */ + function _storePanes($panes) + { + $y = $panes[0]; + $x = $panes[1]; + $rwTop = $panes[2]; + $colLeft = $panes[3]; + if (count($panes) > 4) { // if Active pane was received + $pnnAct = $panes[4]; + } + else { + $pnnAct = NULL; + } + $record = 0x0041; // Record identifier + $length = 0x000A; // Number of bytes to follow + + // Code specific to frozen or thawed panes. + if ($this->_frozen) + { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = $y; + } + if (!isset($colLeft)) { + $colLeft = $x; + } + } + else + { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = 0; + } + if (!isset($colLeft)) { + $colLeft = 0; + } + + // Convert Excel's row and column units to the internal units. + // The default row height is 12.75 + // The default column width is 8.43 + // The following slope and intersection values were interpolated. + // + $y = 20*$y + 255; + $x = 113.879*$x + 390; + } + + + // Determine which pane should be active. There is also the undocumented + // option to override this should it be necessary: may be removed later. + // + if (!isset($pnnAct)) + { + if ($x != 0 and $y != 0) + $pnnAct = 0; // Bottom right + if ($x != 0 and $y == 0) + $pnnAct = 1; // Top right + if ($x == 0 and $y != 0) + $pnnAct = 2; // Bottom left + if ($x == 0 and $y == 0) + $pnnAct = 3; // Top left + } + + $this->_active_pane = $pnnAct; // Used in _storeSelection + + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); + $this->_append($header.$data); + } + + /** + * Store the page setup SETUP BIFF record. + * + * @access private + */ + function _storeSetup() + { + $record = 0x00A1; // Record identifier + $length = 0x0022; // Number of bytes to follow + + $iPaperSize = $this->_paper_size; // Paper size + $iScale = $this->_print_scale; // Print scaling factor + $iPageStart = 0x01; // Starting page number + $iFitWidth = $this->_fit_width; // Fit to number of pages wide + $iFitHeight = $this->_fit_height; // Fit to number of pages high + $grbit = 0x00; // Option flags + $iRes = 0x0258; // Print resolution + $iVRes = 0x0258; // Vertical print resolution + $numHdr = $this->_margin_head; // Header Margin + $numFtr = $this->_margin_foot; // Footer Margin + $iCopies = 0x01; // Number of copies + + $fLeftToRight = 0x0; // Print over then down + $fLandscape = $this->_orientation; // Page orientation + $fNoPls = 0x0; // Setup not read from printer + $fNoColor = 0x0; // Print black and white + $fDraft = 0x0; // Print draft quality + $fNotes = 0x0; // Print notes + $fNoOrient = 0x0; // Orientation not set + $fUsePage = 0x0; // Use custom starting page + + $grbit = $fLeftToRight; + $grbit |= $fLandscape << 1; + $grbit |= $fNoPls << 2; + $grbit |= $fNoColor << 3; + $grbit |= $fDraft << 4; + $grbit |= $fNotes << 5; + $grbit |= $fNoOrient << 6; + $grbit |= $fUsePage << 7; + + $numHdr = pack("d", $numHdr); + $numFtr = pack("d", $numFtr); + if ($this->_byte_order) // if it's Big Endian + { + $numHdr = strrev($numHdr); + $numFtr = strrev($numFtr); + } + + $header = pack("vv", $record, $length); + $data1 = pack("vvvvvvvv", $iPaperSize, + $iScale, + $iPageStart, + $iFitWidth, + $iFitHeight, + $grbit, + $iRes, + $iVRes); + $data2 = $numHdr.$numFtr; + $data3 = pack("v", $iCopies); + $this->_prepend($header.$data1.$data2.$data3); + } + + /** + * Store the header caption BIFF record. + * + * @access private + */ + function _storeHeader() + { + $record = 0x0014; // Record identifier + + $str = $this->_header; // header string + $cch = strlen($str); // Length of header string + if ($this->_BIFF_version == 0x0600) { + $encoding = 0x0; // TODO: Unicode support + $length = 3 + $cch; // Bytes to follow + } + else { + $length = 1 + $cch; // Bytes to follow + } + $header = pack("vv", $record, $length); + if ($this->_BIFF_version == 0x0600) { + $data = pack("vC", $cch, $encoding); + } + else { + $data = pack("C", $cch); + } + + $this->_append($header.$data.$str); + } + + /** + * Store the footer caption BIFF record. + * + * @access private + */ + function _storeFooter() + { + $record = 0x0015; // Record identifier + + $str = $this->_footer; // Footer string + $cch = strlen($str); // Length of footer string + if ($this->_BIFF_version == 0x0600) { + $encoding = 0x0; // TODO: Unicode support + $length = 3 + $cch; // Bytes to follow + } + else { + $length = 1 + $cch; + } + $header = pack("vv", $record, $length); + if ($this->_BIFF_version == 0x0600) { + $data = pack("vC", $cch, $encoding); + } + else { + $data = pack("C", $cch); + } + + $this->_append($header.$data.$str); + } + + /** + * Store the horizontal centering HCENTER BIFF record. + * + * @access private + */ + function _storeHcenter() + { + $record = 0x0083; // Record identifier + $length = 0x0002; // Bytes to follow + + $fHCenter = $this->_hcenter; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fHCenter); + + $this->_append($header.$data); + } + + /** + * Store the vertical centering VCENTER BIFF record. + * + * @access private + */ + function _storeVcenter() + { + $record = 0x0084; // Record identifier + $length = 0x0002; // Bytes to follow + + $fVCenter = $this->_vcenter; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fVCenter); + $this->_append($header.$data); + } + + /** + * Store the LEFTMARGIN BIFF record. + * + * @access private + */ + function _storeMarginLeft() + { + $record = 0x0026; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_margin_left; // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if ($this->_byte_order) // if it's Big Endian + { + $data = strrev($data); + } + + $this->_append($header.$data); + } + + /** + * Store the RIGHTMARGIN BIFF record. + * + * @access private + */ + function _storeMarginRight() + { + $record = 0x0027; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_margin_right; // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if ($this->_byte_order) // if it's Big Endian + { + $data = strrev($data); + } + + $this->_append($header.$data); + } + + /** + * Store the TOPMARGIN BIFF record. + * + * @access private + */ + function _storeMarginTop() + { + $record = 0x0028; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_margin_top; // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if ($this->_byte_order) // if it's Big Endian + { + $data = strrev($data); + } + + $this->_append($header.$data); + } + + /** + * Store the BOTTOMMARGIN BIFF record. + * + * @access private + */ + function _storeMarginBottom() + { + $record = 0x0029; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_margin_bottom; // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if ($this->_byte_order) // if it's Big Endian + { + $data = strrev($data); + } + + $this->_append($header.$data); + } + + /** + * Merges the area given by its arguments. + * This is an Excel97/2000 method. It is required to perform more complicated + * merging than the normal setAlign('merge'). + * + * @access public + * @param integer $first_row First row of the area to merge + * @param integer $first_col First column of the area to merge + * @param integer $last_row Last row of the area to merge + * @param integer $last_col Last column of the area to merge + */ + function mergeCells($first_row, $first_col, $last_row, $last_col) + { + $record = 0x00E5; // Record identifier + $length = 0x000A; // Bytes to follow + $cref = 1; // Number of refs + + // Swap last row/col for first row/col as necessary + if ($first_row > $last_row) { + list($first_row, $last_row) = array($last_row, $first_row); + } + + if ($first_col > $last_col) { + list($first_col, $last_col) = array($last_col, $first_col); + } + + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $cref, $first_row, $last_row, + $first_col, $last_col); + + $this->_append($header.$data); + } + + /** + * Write the PRINTHEADERS BIFF record. + * + * @access private + */ + function _storePrintHeaders() + { + $record = 0x002a; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintRwCol = $this->_print_headers; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintRwCol); + $this->_prepend($header.$data); + } + + /** + * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the + * GRIDSET record. + * + * @access private + */ + function _storePrintGridlines() + { + $record = 0x002b; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintGrid = $this->_print_gridlines; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintGrid); + $this->_prepend($header.$data); + } + + /** + * Write the GRIDSET BIFF record. Must be used in conjunction with the + * PRINTGRIDLINES record. + * + * @access private + */ + function _storeGridset() + { + $record = 0x0082; // Record identifier + $length = 0x0002; // Bytes to follow + + $fGridSet = !($this->_print_gridlines); // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fGridSet); + $this->_prepend($header.$data); + } + + /** + * Write the GUTS BIFF record. This is used to configure the gutter margins + * where Excel outline symbols are displayed. The visibility of the gutters is + * controlled by a flag in WSBOOL. + * + * @see _storeWsbool() + * @access private + */ + function _storeGuts() + { + $record = 0x0080; // Record identifier + $length = 0x0008; // Bytes to follow + + $dxRwGut = 0x0000; // Size of row gutter + $dxColGut = 0x0000; // Size of col gutter + + $row_level = $this->_outline_row_level; + $col_level = 0; + + // Calculate the maximum column outline level. The equivalent calculation + // for the row outline level is carried out in setRow(). + for ($i=0; $i < count($this->_colinfo); $i++) + { + // Skip cols without outline level info. + if (count($col_level) >= 6) { + $col_level = max($this->_colinfo[$i][5], $col_level); + } + } + + // Set the limits for the outline levels (0 <= x <= 7). + $col_level = max(0, min($col_level, 7)); + + // The displayed level is one greater than the max outline levels + if ($row_level) { + $row_level++; + } + if ($col_level) { + $col_level++; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $dxRwGut, $dxColGut, $row_level, $col_level); + + $this->_prepend($header.$data); + } + + + /** + * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction + * with the SETUP record. + * + * @access private + */ + function _storeWsbool() + { + $record = 0x0081; // Record identifier + $length = 0x0002; // Bytes to follow + $grbit = 0x0000; + + // The only option that is of interest is the flag for fit to page. So we + // set all the options in one go. + // + /*if ($this->_fit_page) { + $grbit = 0x05c1; + } + else { + $grbit = 0x04c1; + }*/ + // Set the option flags + $grbit |= 0x0001; // Auto page breaks visible + if ($this->_outline_style) { + $grbit |= 0x0020; // Auto outline styles + } + if ($this->_outline_below) { + $grbit |= 0x0040; // Outline summary below + } + if ($this->_outline_right) { + $grbit |= 0x0080; // Outline summary right + } + if ($this->_fit_page) { + $grbit |= 0x0100; // Page setup fit to page + } + if ($this->_outline_on) { + $grbit |= 0x0400; // Outline symbols displayed + } + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $this->_prepend($header.$data); + } + + /** + * Write the HORIZONTALPAGEBREAKS BIFF record. + * + * @access private + */ + function _storeHbreak() + { + // Return if the user hasn't specified pagebreaks + if (empty($this->_hbreaks)) { + return; + } + + // Sort and filter array of page breaks + $breaks = $this->_hbreaks; + sort($breaks, SORT_NUMERIC); + if ($breaks[0] == 0) { // don't use first break if it's 0 + array_shift($breaks); + } + + $record = 0x001b; // Record identifier + $cbrk = count($breaks); // Number of page breaks + $length = 2 + 6*$cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach($breaks as $break) { + $data .= pack("vvv", $break, 0x0000, 0x00ff); + } + + $this->_prepend($header.$data); + } + + + /** + * Write the VERTICALPAGEBREAKS BIFF record. + * + * @access private + */ + function _storeVbreak() + { + // Return if the user hasn't specified pagebreaks + if (empty($this->_vbreaks)) { + return; + } + + // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. + // It is slightly higher in Excel 97/200, approx. 1026 + $breaks = array_slice($this->_vbreaks,0,1000); + + // Sort and filter array of page breaks + sort($breaks, SORT_NUMERIC); + if ($breaks[0] == 0) { // don't use first break if it's 0 + array_shift($breaks); + } + + $record = 0x001a; // Record identifier + $cbrk = count($breaks); // Number of page breaks + $length = 2 + 6*$cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($breaks as $break) { + $data .= pack("vvv", $break, 0x0000, 0xffff); + } + + $this->_prepend($header.$data); + } + + /** + * Set the Biff PROTECT record to indicate that the worksheet is protected. + * + * @access private + */ + function _storeProtect() + { + // Exit unless sheet protection has been specified + if ($this->_protect == 0) { + return; + } + + $record = 0x0012; // Record identifier + $length = 0x0002; // Bytes to follow + + $fLock = $this->_protect; // Worksheet is protected + + $header = pack("vv", $record, $length); + $data = pack("v", $fLock); + + $this->_prepend($header.$data); + } + + /** + * Write the worksheet PASSWORD record. + * + * @access private + */ + function _storePassword() + { + // Exit unless sheet protection and password have been specified + if (($this->_protect == 0) or (!isset($this->_password))) { + return; + } + + $record = 0x0013; // Record identifier + $length = 0x0002; // Bytes to follow + + $wPassword = $this->_password; // Encoded password + + $header = pack("vv", $record, $length); + $data = pack("v", $wPassword); + + $this->_prepend($header.$data); + } + + + /** + * Insert a 24bit bitmap image in a worksheet. + * + * @access public + * @param integer $row The row we are going to insert the bitmap into + * @param integer $col The column we are going to insert the bitmap into + * @param string $bitmap The bitmap filename + * @param integer $x The horizontal position (offset) of the image inside the cell. + * @param integer $y The vertical position (offset) of the image inside the cell. + * @param integer $scale_x The horizontal scale + * @param integer $scale_y The vertical scale + */ + function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) + { + $bitmap_array = $this->_processBitmap($bitmap); + if ($this->isError($bitmap_array)) + { + $this->writeString($row, $col, $bitmap_array->getMessage()); + return; + } + list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); + + // Scale the frame of the image. + $width *= $scale_x; + $height *= $scale_y; + + // Calculate the vertices of the image and write the OBJ record + $this->_positionImage($col, $row, $x, $y, $width, $height); + + // Write the IMDATA record to store the bitmap data + $record = 0x007f; + $length = 8 + $size; + $cf = 0x09; + $env = 0x01; + $lcb = $size; + + $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); + $this->_append($header.$data); + } + + /** + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * + * @access private + * @note the SDK incorrectly states that the height should be expressed as a + * percentage of 1024. + * @param integer $col_start Col containing upper left corner of object + * @param integer $row_start Row containing top left corner of object + * @param integer $x1 Distance to left side of object + * @param integer $y1 Distance to top of object + * @param integer $width Width of image frame + * @param integer $height Height of image frame + */ + function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + { + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= $this->_sizeCol($col_start)) + { + $x1 = 0; + } + if ($y1 >= $this->_sizeRow($row_start)) + { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= $this->_sizeCol($col_end)) { + $width -= $this->_sizeCol($col_end); + $col_end++; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= $this->_sizeRow($row_end)) { + $height -= $this->_sizeRow($row_end); + $row_end++; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero eight or width. + // + if ($this->_sizeCol($col_start) == 0) + return; + if ($this->_sizeCol($col_end) == 0) + return; + if ($this->_sizeRow($row_start) == 0) + return; + if ($this->_sizeRow($row_end) == 0) + return; + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / $this->_sizeCol($col_start) * 1024; + $y1 = $y1 / $this->_sizeRow($row_start) * 256; + $x2 = $width / $this->_sizeCol($col_end) * 1024; // Distance to right side of object + $y2 = $height / $this->_sizeRow($row_end) * 256; // Distance to bottom of object + + $this->_storeObjPicture( $col_start, $x1, + $row_start, $y1, + $col_end, $x2, + $row_end, $y2 + ); + } + + /** + * Convert the width of a cell from user's units to pixels. By interpolation + * the relationship is: y = 7x +5. If the width hasn't been set by the user we + * use the default value. If the col is hidden we use a value of zero. + * + * @access private + * @param integer $col The column + * @return integer The width in pixels + */ + function _sizeCol($col) + { + // Look up the cell value to see if it has been changed + if (isset($this->col_sizes[$col])) { + if ($this->col_sizes[$col] == 0) { + return(0); + } + else { + return(floor(7 * $this->col_sizes[$col] + 5)); + } + } + else { + return(64); + } + } + + /** + * Convert the height of a cell from user's units to pixels. By interpolation + * the relationship is: y = 4/3x. If the height hasn't been set by the user we + * use the default value. If the row is hidden we use a value of zero. (Not + * possible to hide row yet). + * + * @access private + * @param integer $row The row + * @return integer The width in pixels + */ + function _sizeRow($row) + { + // Look up the cell value to see if it has been changed + if (isset($this->row_sizes[$row])) { + if ($this->row_sizes[$row] == 0) { + return(0); + } + else { + return(floor(4/3 * $this->row_sizes[$row])); + } + } + else { + return(17); + } + } + + /** + * Store the OBJ record that precedes an IMDATA record. This could be generalise + * to support other Excel objects. + * + * @access private + * @param integer $colL Column containing upper left corner of object + * @param integer $dxL Distance from left side of cell + * @param integer $rwT Row containing top left corner of object + * @param integer $dyT Distance from top of cell + * @param integer $colR Column containing lower right corner of object + * @param integer $dxR Distance from right of cell + * @param integer $rwB Row containing bottom right corner of object + * @param integer $dyB Distance from bottom of cell + */ + function _storeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) + { + $record = 0x005d; // Record identifier + $length = 0x003c; // Bytes to follow + + $cObj = 0x0001; // Count of objects in file (set to 1) + $OT = 0x0008; // Object type. 8 = Picture + $id = 0x0001; // Object ID + $grbit = 0x0614; // Option flags + + $cbMacro = 0x0000; // Length of FMLA structure + $Reserved1 = 0x0000; // Reserved + $Reserved2 = 0x0000; // Reserved + + $icvBack = 0x09; // Background colour + $icvFore = 0x09; // Foreground colour + $fls = 0x00; // Fill pattern + $fAuto = 0x00; // Automatic fill + $icv = 0x08; // Line colour + $lns = 0xff; // Line style + $lnw = 0x01; // Line weight + $fAutoB = 0x00; // Automatic border + $frs = 0x0000; // Frame style + $cf = 0x0009; // Image format, 9 = bitmap + $Reserved3 = 0x0000; // Reserved + $cbPictFmla = 0x0000; // Length of FMLA structure + $Reserved4 = 0x0000; // Reserved + $grbit2 = 0x0001; // Option flags + $Reserved5 = 0x0000; // Reserved + + + $header = pack("vv", $record, $length); + $data = pack("V", $cObj); + $data .= pack("v", $OT); + $data .= pack("v", $id); + $data .= pack("v", $grbit); + $data .= pack("v", $colL); + $data .= pack("v", $dxL); + $data .= pack("v", $rwT); + $data .= pack("v", $dyT); + $data .= pack("v", $colR); + $data .= pack("v", $dxR); + $data .= pack("v", $rwB); + $data .= pack("v", $dyB); + $data .= pack("v", $cbMacro); + $data .= pack("V", $Reserved1); + $data .= pack("v", $Reserved2); + $data .= pack("C", $icvBack); + $data .= pack("C", $icvFore); + $data .= pack("C", $fls); + $data .= pack("C", $fAuto); + $data .= pack("C", $icv); + $data .= pack("C", $lns); + $data .= pack("C", $lnw); + $data .= pack("C", $fAutoB); + $data .= pack("v", $frs); + $data .= pack("V", $cf); + $data .= pack("v", $Reserved3); + $data .= pack("v", $cbPictFmla); + $data .= pack("v", $Reserved4); + $data .= pack("v", $grbit2); + $data .= pack("V", $Reserved5); + + $this->_append($header.$data); + } + + /** + * Convert a 24 bit bitmap into the modified internal format used by Windows. + * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the + * MSDN library. + * + * @access private + * @param string $bitmap The bitmap to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmap($bitmap) + { + // Open file. + $bmp_fd = @fopen($bitmap,"rb"); + if (!$bmp_fd) { + $this->raiseError("Couldn't import $bitmap"); + } + + // Slurp the file into a string. + $data = fread($bmp_fd, filesize($bitmap)); + + // Check that the file is big enough to be a bitmap. + if (strlen($data) <= 0x36) { + $this->raiseError("$bitmap doesn't contain enough data.\n"); + } + + // The first 2 bytes are used to identify the bitmap. + $identity = unpack("A2", $data); + if ($identity[''] != "BM") { + $this->raiseError("$bitmap doesn't appear to be a valid bitmap image.\n"); + } + + // Remove bitmap data: ID. + $data = substr($data, 2); + + // Read and remove the bitmap size. This is more reliable than reading + // the data size at offset 0x22. + // + $size_array = unpack("V", substr($data, 0, 4)); + $size = $size_array['']; + $data = substr($data, 4); + $size -= 0x36; // Subtract size of bitmap header. + $size += 0x0C; // Add size of BIFF header. + + // Remove bitmap data: reserved, offset, header length. + $data = substr($data, 12); + + // Read and remove the bitmap width and height. Verify the sizes. + $width_and_height = unpack("V2", substr($data, 0, 8)); + $width = $width_and_height[1]; + $height = $width_and_height[2]; + $data = substr($data, 8); + if ($width > 0xFFFF) { + $this->raiseError("$bitmap: largest image width supported is 65k.\n"); + } + if ($height > 0xFFFF) { + $this->raiseError("$bitmap: largest image height supported is 65k.\n"); + } + + // Read and remove the bitmap planes and bpp data. Verify them. + $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); + $data = substr($data, 4); + if ($planes_and_bitcount[2] != 24) { // Bitcount + $this->raiseError("$bitmap isn't a 24bit true color bitmap.\n"); + } + if ($planes_and_bitcount[1] != 1) { + $this->raiseError("$bitmap: only 1 plane nupported in bitmap image.\n"); + } + + // Read and remove the bitmap compression. Verify compression. + $compression = unpack("V", substr($data, 0, 4)); + $data = substr($data, 4); + + //$compression = 0; + if ($compression[""] != 0) { + $this->raiseError("$bitmap: compression not supported in bitmap image.\n"); + } + + // Remove bitmap data: data size, hres, vres, colours, imp. colours. + $data = substr($data, 20); + + // Add the BITMAPCOREHEADER data + $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + $data = $header . $data; + + return (array($width, $height, $size, $data)); + } + + /** + * Store the window zoom factor. This should be a reduced fraction but for + * simplicity we will store all fractions with a numerator of 100. + * + * @access private + */ + function _storeZoom() + { + // If scale is 100 we don't need to write a record + if ($this->_zoom == 100) { + return; + } + + $record = 0x00A0; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_zoom, 100); + $this->_append($header.$data); + } + + /** + * FIXME: add comments + */ + function setValidation($row1, $col1, $row2, $col2, &$validator) + { + $this->_dv[] = $validator->_getData() . + pack("vvvvv", 1, $row1, $row2, $col1, $col2); + } + + /** + * Store the DVAL and DV records. + * + * @access private + */ + function _storeDataValidity() + { + $record = 0x01b2; // Record identifier + $length = 0x0012; // Bytes to follow + + $grbit = 0x0002; // Prompt box at cell, no cached validity data at DV records + $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position + $verPos = 0x00000000; // Vertical position of prompt box, if fixed position + $objId = 0xffffffff; // Object identifier of drop down arrow object, or -1 if not visible + + $header = pack('vv', $record, $length); + $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, + count($this->_dv)); + $this->_append($header.$data); + + $record = 0x01be; // Record identifier + foreach($this->_dv as $dv) + { + $length = strlen($dv); // Bytes to follow + $header = pack("vv", $record, $length); + $this->_append($header.$dv); + } + } +} +?> diff --git a/gulliver/thirdparty/pear/Spreadsheet/package.xml b/gulliver/thirdparty/pear/Spreadsheet/package.xml new file mode 100644 index 000000000..53fe8ba13 --- /dev/null +++ b/gulliver/thirdparty/pear/Spreadsheet/package.xml @@ -0,0 +1,61 @@ + + + OLE + Package for reading and writing OLE containers + This package allows reading and writing of OLE (Object Linking and Embedding) files, the format used as container for Excel, Word and other MS file formats. + Documentation for the OLE format can be found at: http://user.cs.tu-berlin.de/~schwartz/pmh/guide.html + + + xnoguer + Xavier Noguer + xnoguer@php.net + lead + + + + 0.5 + 2003-12-14 + PHP + beta + - BC break!!! OLE/OLE.php file moved to OLE.php to comply with PEAR + standards. You will have to change your require('OLE/OLE.php')'s + for require('OLE.php')'s +- If you are using Spreadsheet_Excel_Writer, do not upgrade to this + version yet. A new version of Spreadsheet_Excel_Writer will be + released soon so the BC break won't affect you. +- allowing setting of temp dir for OLE_PPS_File and OLE_PPS_Root objects +- fixed problem when reading files (not reading the whole OLE tree) + + + + + + + + + + 0.4 + 2003-09-25 + beta + -deleting tmp files (Herman Kuiper). +-fixed hardcoded tmp dir (Herman Kuiper). +-fixed pass by reference warning (Herman Kuiper). + + + + 0.3 + 2003-08-21 + beta + -added OLE_PPS_File::init() initialization method. +-better error handling. + + + + 0.2.1 + 2003-05-12 + alpha + Fixing install dir + + + + diff --git a/gulliver/thirdparty/pear/System.php b/gulliver/thirdparty/pear/System.php new file mode 100644 index 000000000..910596988 --- /dev/null +++ b/gulliver/thirdparty/pear/System.php @@ -0,0 +1,540 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: System.php 6820 2007-06-20 13:35:30Z kevin_fourie $ +// + +require_once 'PEAR.php'; +require_once 'Console/Getopt.php'; + +$GLOBALS['_System_temp_files'] = array(); + +/** +* System offers cross plattform compatible system functions +* +* Static functions for different operations. Should work under +* Unix and Windows. The names and usage has been taken from its respectively +* GNU commands. The functions will return (bool) false on error and will +* trigger the error with the PHP trigger_error() function (you can silence +* the error by prefixing a '@' sign after the function call). +* +* Documentation on this class you can find in: +* http://pear.php.net/manual/ +* +* Example usage: +* if (!@System::rm('-r file1 dir1')) { +* print "could not delete file1 or dir1"; +* } +* +* In case you need to to pass file names with spaces, +* pass the params as an array: +* +* System::rm(array('-r', $file1, $dir1)); +* +* @package System +* @author Tomas V.V.Cox +* @version $Revision: 6820 $ +* @access public +* @see http://pear.php.net/manual/ +*/ +class System +{ + /** + * returns the commandline arguments of a function + * + * @param string $argv the commandline + * @param string $short_options the allowed option short-tags + * @param string $long_options the allowed option long-tags + * @return array the given options and there values + * @access private + */ + function _parseArgs($argv, $short_options, $long_options = null) + { + if (!is_array($argv) && $argv !== null) { + $argv = preg_split('/\s+/', $argv); + } + return Console_Getopt::getopt2($argv, $short_options); + } + + /** + * Output errors with PHP trigger_error(). You can silence the errors + * with prefixing a "@" sign to the function call: @System::mkdir(..); + * + * @param mixed $error a PEAR error or a string with the error message + * @return bool false + * @access private + */ + function raiseError($error) + { + if (PEAR::isError($error)) { + $error = $error->getMessage(); + } + trigger_error($error, E_USER_WARNING); + return false; + } + + /** + * Creates a nested array representing the structure of a directory + * + * System::_dirToStruct('dir1', 0) => + * Array + * ( + * [dirs] => Array + * ( + * [0] => dir1 + * ) + * + * [files] => Array + * ( + * [0] => dir1/file2 + * [1] => dir1/file3 + * ) + * ) + * @param string $sPath Name of the directory + * @param integer $maxinst max. deep of the lookup + * @param integer $aktinst starting deep of the lookup + * @return array the structure of the dir + * @access private + */ + + function _dirToStruct($sPath, $maxinst, $aktinst = 0) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + System::raiseError("Could not open dir $sPath"); + return $struct; // XXX could not open error + } + $struct['dirs'][] = $sPath; // XXX don't add if '.' or '..' ? + $list = array(); + while ($file = readdir($dir)) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + closedir($dir); + sort($list); + if ($aktinst < $maxinst || $maxinst == 0) { + foreach($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path)) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1); + $struct = array_merge_recursive($tmp, $struct); + } else { + $struct['files'][] = $path; + } + } + } + return $struct; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @see System::_dirToStruct() + */ + function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + settype($files, 'array'); + foreach ($files as $file) { + if (is_dir($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + $struct['files'][] = $file; + } + } + return $struct; + } + + /** + * The rm command for removing files. + * Supports multiple files and dirs and also recursive deletes + * + * @param string $args the arguments for rm + * @return mixed PEAR_Error or true for success + * @access public + */ + function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" do nothing but like it :-) + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + $ret = true; + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + foreach($struct['files'] as $file) { + if (!@unlink($file)) { + $ret = false; + } + } + foreach($struct['dirs'] as $dir) { + if (!@rmdir($dir)) { + $ret = false; + } + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; + if (!@$delete($file)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Make directories. Note that we use call_user_func('mkdir') to avoid + * a problem with ZE2 calling System::mkDir instead of the native PHP func. + * + * @param string $args the name of the director(y|ies) to create + * @return bool True for success + * @access public + */ + function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + $mode = 0777; // default mode + foreach($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif($opt[0] == 'm') { + // if the mode is clearly an octal number (starts with 0) + // convert it to decimal + if (strlen($opt[1]) && $opt[1]{0} == '0') { + $opt[1] = octdec($opt[1]); + } else { + // convert to int + $opt[1] += 0; + } + $mode = $opt[1]; + } + } + $ret = true; + if (isset($create_parents)) { + foreach($opts[1] as $dir) { + $dirstack = array(); + while (!@is_dir($dir) && $dir != DIRECTORY_SEPARATOR) { + array_unshift($dirstack, $dir); + $dir = dirname($dir); + } + while ($newdir = array_shift($dirstack)) { + if (!call_user_func('mkdir', $newdir, $mode)) { + $ret = false; + } + } + } + } else { + foreach($opts[1] as $dir) { + if (!@is_dir($dir) && !call_user_func('mkdir', $dir, $mode)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Concatenate files + * + * Usage: + * 1) $var = System::cat('sample.txt test.txt'); + * 2) System::cat('sample.txt test.txt > final.txt'); + * 3) System::cat('sample.txt test.txt >> final.txt'); + * + * Note: as the class use fopen, urls should work also (test that) + * + * @param string $args the arguments + * @return boolean true on success + * @access public + */ + function &cat($args) + { + $ret = null; + $files = array(); + if (!is_array($args)) { + $args = preg_split('/\s+/', $args); + } + for($i=0; $i < count($args); $i++) { + if ($args[$i] == '>') { + $mode = 'wb'; + $outputfile = $args[$i+1]; + break; + } elseif ($args[$i] == '>>') { + $mode = 'ab+'; + $outputfile = $args[$i+1]; + break; + } else { + $files[] = $args[$i]; + } + } + if (isset($mode)) { + if (!$outputfd = fopen($outputfile, $mode)) { + $err = System::raiseError("Could not open $outputfile"); + return $err; + } + $ret = true; + } + foreach ($files as $file) { + if (!$fd = fopen($file, 'r')) { + System::raiseError("Could not open $file"); + continue; + } + while ($cont = fread($fd, 2048)) { + if (isset($outputfd)) { + fwrite($outputfd, $cont); + } else { + $ret .= $cont; + } + } + fclose($fd); + } + if (@is_resource($outputfd)) { + fclose($outputfd); + } + return $ret; + } + + /** + * Creates temporary files or directories. This function will remove + * the created files when the scripts finish its execution. + * + * Usage: + * 1) $tempfile = System::mktemp("prefix"); + * 2) $tempdir = System::mktemp("-d prefix"); + * 3) $tempfile = System::mktemp(); + * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); + * + * prefix -> The string that will be prepended to the temp name + * (defaults to "tmp"). + * -d -> A temporary dir will be created instead of a file. + * -t -> The target dir where the temporary (file|dir) will be created. If + * this param is missing by default the env vars TMP on Windows or + * TMPDIR in Unix will be used. If these vars are also missing + * c:\windows\temp or /tmp will be used. + * + * @param string $args The arguments + * @return mixed the full path of the created (file|dir) or false + * @see System::tmpdir() + * @access public + */ + function mktemp($args = null) + { + static $first_time = true; + $opts = System::_parseArgs($args, 't:d'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach($opts[0] as $opt) { + if($opt[0] == 'd') { + $tmp_is_dir = true; + } elseif($opt[0] == 't') { + $tmpdir = $opt[1]; + } + } + $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; + if (!isset($tmpdir)) { + $tmpdir = System::tmpdir(); + } + if (!System::mkDir("-p $tmpdir")) { + return false; + } + $tmp = tempnam($tmpdir, $prefix); + if (isset($tmp_is_dir)) { + unlink($tmp); // be careful possible race condition here + if (!call_user_func('mkdir', $tmp, 0700)) { + return System::raiseError("Unable to create temporary directory $tmpdir"); + } + } + $GLOBALS['_System_temp_files'][] = $tmp; + if ($first_time) { + PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); + $first_time = false; + } + return $tmp; + } + + /** + * Remove temporary files created my mkTemp. This function is executed + * at script shutdown time + * + * @access private + */ + function _removeTmpFiles() + { + if (count($GLOBALS['_System_temp_files'])) { + $delete = $GLOBALS['_System_temp_files']; + array_unshift($delete, '-r'); + System::rm($delete); + } + } + + /** + * Get the path of the temporal directory set in the system + * by looking in its environments variables. + * Note: php.ini-recommended removes the "E" from the variables_order setting, + * making unavaible the $_ENV array, that s why we do tests with _ENV + * + * @return string The temporal directory on the system + */ + function tmpdir() + { + if (OS_WINDOWS) { + if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { + return $var; + } + if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { + return $var; + } + if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { + return $var; + } + return getenv('SystemRoot') . '\temp'; + } + if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { + return $var; + } + return '/tmp'; + } + + /** + * The "which" command (show the full path of a command) + * + * @param string $program The command to search for + * @return mixed A string with the full path or false if not found + * @author Stig Bakken + */ + function which($program, $fallback = false) + { + // is_executable() is not available on windows + if (OS_WINDOWS) { + $pear_is_executable = 'is_file'; + } else { + $pear_is_executable = 'is_executable'; + } + + // full path given + if (basename($program) != $program) { + return (@$pear_is_executable($program)) ? $program : $fallback; + } + + // XXX FIXME honor safe mode + $path_delim = OS_WINDOWS ? ';' : ':'; + $exe_suffixes = OS_WINDOWS ? array('.exe','.bat','.cmd','.com') : array(''); + $path_elements = explode($path_delim, getenv('PATH')); + foreach ($exe_suffixes as $suff) { + foreach ($path_elements as $dir) { + $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; + if (@is_file($file) && @$pear_is_executable($file)) { + return $file; + } + } + } + return $fallback; + } + + /** + * The "find" command + * + * Usage: + * + * System::find($dir); + * System::find("$dir -type d"); + * System::find("$dir -type f"); + * System::find("$dir -name *.php"); + * System::find("$dir -name *.php -name *.htm*"); + * System::find("$dir -maxdepth 1"); + * + * Params implmented: + * $dir -> Start the search at this directory + * -type d -> return only directories + * -type f -> return only files + * -maxdepth -> max depth of recursion + * -name -> search pattern (bash style). Multiple -name param allowed + * + * @param mixed Either array or string with the command line + * @return array Array of found files + * + */ + function find($args) + { + if (!is_array($args)) { + $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + } + $dir = array_shift($args); + $patterns = array(); + $depth = 0; + $do_files = $do_dirs = true; + for ($i = 0; $i < count($args); $i++) { + switch ($args[$i]) { + case '-type': + if (in_array($args[$i+1], array('d', 'f'))) { + if ($args[$i+1] == 'd') { + $do_files = false; + } else { + $do_dirs = false; + } + } + $i++; + break; + case '-name': + $patterns[] = "(" . preg_replace(array('/\./', '/\*/'), + array('\.', '.*'), + $args[$i+1]) + . ")"; + $i++; + break; + case '-maxdepth': + $depth = $args[$i+1]; + break; + } + } + $path = System::_dirToStruct($dir, $depth); + if ($do_files && $do_dirs) { + $files = array_merge($path['files'], $path['dirs']); + } elseif ($do_dirs) { + $files = $path['dirs']; + } else { + $files = $path['files']; + } + if (count($patterns)) { + $patterns = implode('|', $patterns); + $ret = array(); + for ($i = 0; $i < count($files); $i++) { + if (preg_match("#^$patterns\$#", $files[$i])) { + $ret[] = $files[$i]; + } + } + return $ret; + } + return $files; + } +} +?> diff --git a/gulliver/thirdparty/pear/UDDI.php b/gulliver/thirdparty/pear/UDDI.php new file mode 100644 index 000000000..bb1ba571c --- /dev/null +++ b/gulliver/thirdparty/pear/UDDI.php @@ -0,0 +1,720 @@ + | +// | Tobias Hauser | +// +----------------------------------------------------------------------+ +// +// $Id$ +/* Original Credits: + + phpUDDI + A PHP class library implementing the Universal Description, + Discovery and Integration API for locating and publishing Web + Services listings in a UBR (UDDI Business Registry). + + Copyright (C) 2002-2004 Lee Reynolds and Jon Stephens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + or point your web browser to http://www.gnu.org/licenses/lgpl.html. + + Conceived and developed in conjunction with the + authors' work for the book "PHP Web Services" from Wrox Press + Ltd. (ISBN-1861008074) + + Original developers: + Lee Reynolds lee@annasart.com + Jon Stephens jon@hiveminds.info + + Useful Links: + + Wrox Press "Programmer To Programmer" Discussion Groups + Pro PHP: http://p2p.wrox.com/list.asp?list=pro_php + Pro XML: http://p2p.wrox.com/list.asp?list=xml + + HiveMinds Group + http://www.hiveminds.info/ + http://forums.hiveminds.info/ + + Version History: + + 0.1 -- 15 November 2002 -- Basic Proof of concept + 0.2 -- 20 November 2002 -- Base class redefinition to + include public and private methods + 0.3 -- 25 November 2002 -- All UDDI 2.0 Inquiry APIs implemented + 0.3.1 -- 14 March 2004 -- small bugfixes (Christian); license change to LPGL (Lee, Jon) + + Objective for 1.0 release is complete implementation of the UDDI 2.0 API + (http://www.uddi.org/pubs/ProgrammersAPI-V2.04-Published-20020719.pdf). + + Objective for 1.5 release is backwards compatibility with UDDI 1.0. + + Objective for 2.0 release is complete implementation of the UDDI 3.0 API + (http://www.uddi.org/pubs/uddi-v3.00-published-20020719.pdf). + +*/ + +require_once 'PEAR.php'; + +/** + * PEAR::UDDI + * class that implements the UDDI API + * @link http://www.uddi.org/ + * + * pearified version of phpUDDI by Stephens & Reynolds + * + * + * @category Web Services + * @package UDDI + * @version 0.2.0alpha4 + * @author Christian Wenz + * @author Tobias Hauser + * @todo fully implement UDDI 2.0 (and later 1.0, 3.0) + * @todo more helper functions (for analyzing the data returned by querying a UBR) + + +Name: + UDDI.php - UDDI Registry access library (PEARified version) + +Synopsis: + require_once 'UDDI/UDDI.php'; + +Currently, PEAR::UDDI supports 1 function call in one UDDI API. + +Variables supported: + $UDDI::_api + currently 2 values are supported, and they represent 2 of the 6 published APIs by UDDI.org. + 'Inquiry' which represents the search and _query API + 'Publish' which represents the publishing API + + Usage: + + $UDDI::_api = 'Inquiry'; // (default) + $UDDI::_api = 'Publish'; + + + $UDDI::_uddiversion + This is the API version of the UPI spec you want to use + Values are either 1, 2, or 3. + + Usage: + + $UDDI::_uddiversion = 2; + + + Default: + currently, the version default is '1'; + + Note: As stated above, we are aiming for a 1.0 release of this library which implements + the UDDI 2.0 Programming API; we cannot guarantee at this time that any of the API functions + as implemented here will work correctly (or at all) unless you set the version to 2 as shown + under 'Usage' immediately above or by setting the version when you call the UDDI class constructor: + + + $my_uddi = new UDDI('Microsoft', 2); + + + At a later date we will make this class compatible with UDDI Versions 1.0 and 3.0. + + $UDDI::_regarray + We currently support 2 test registry entries. These are 'IBM' and 'Microsoft'. + We also support 2 API interfaces. These are, as noted above, 'Inquiry' and 'Publish'. + + To add live registry entries, or your own test registry, you must append a multiple index array element + to $UDDI::_regarray. The form for this follows: + + array('registry name' => + array('Inquiry' => + array('url' => 'url_for_inquiry', + 'port' => 80), + 'Publish' => + array('url' => 'url_for_publish', + 'port' => 443))); + + Internally this is accessed as + URL = $_regarray['registry_name']['Inquiry']['url'] + , and + port = $_regarray['registry_name']['Inquiry']['port'] + + PLEASE NOTE: You're adding elements to this array, instead of overwriting old ones. + + Usage: + + $UDDI::_regarray = array('private' => + array('Inquiry' => + array('url' =>'url_for_inquiry', + 'port' => 80), + 'Publish' => + array('url' => 'url_for_publishing', + 'port' => 443))); + + + $UDDI::_xmlns + You can modify the XML namespace by reassigning a value to this + + Usage: + + $UDDI::_xmlns = 'new_ns_definition'; + + + Default: + 'urn:uddi-org:api' + + $UDDI::_debug + Turns on debugging by echoing HTTP headers and UDDI queries. + + Usage: + + $UDDI::_debug = true; + + + Default: + false + + $UDDI::_transmit + Turns on _posting of UDDI message to UBR. + + Usage: + + $UDDI::_transmit = false; + + + Default: + true; + + +EXAMPLE: + +This queries IBM's UDDI Registry for the first 50 businesses whose names include +the word "Acme", matches sorted first in ascending order by name, then in descending +order by date last updated. The raw XML that's returned is escaped and echoed to the page. + + +$my_uddi = new UDDI('IBM', 1); +$result = htmlspecialchars($my_uddi->find_business(array('name' => '%Acme%', 'maxRows' => 50, 'findQualifiers' => 'sortByNameAsc,sortByDateAsc'))); +echo "
    $result
    "; +
    + +*/ + + +// {{{ constants +/** + * version of corresponding phpUDDI version + * still included so that moving from phpUDDI to PEAR::UDDI is easier + */ + +define('UDDI_PHP_LIB_VERSION', '0.3.1p'); //suffix p = PEAR :-) + +// }}} +// {{{ UDDI + +/** + * UDDI + * + * class that implements the UDDI API + * + * @package UDDI + * @author Christian Wenz + * @author Tobias Hauser +*/ +class UDDI extends PEAR +{ + // {{{ properties + + /** + * version of package + * @var string $_version + */ + var $_version = '0.2.0alpha4'; + + /** + * list of known registries + * @var array $regarray + */ + + var $_regarray = + array('IBM' => + array('Inquiry' => + array('url' => 'www-3.ibm.com/services/uddi/testregistry/inquiryapi', + 'port' => 80), + 'Publish' => + array('url' => 'https://www-3.ibm.com/services/uddi/testregistry/protect/publishapi', + 'port' => 443)), + + 'Microsoft' => + array('Inquiry' => + array('url' => 'test.uddi.microsoft.com/inquire', + 'port' => 80), + 'Publish' => + array('url' => 'https://test.uddi.microsoft.com/publish', + 'port' => 443))); + + + /** + * which API to use (Inquiry/Publish) + * @var string $_api + */ + var $_api = 'Inquiry'; + + /** + * used XML namespace + * @var string $_xmlns + */ + var $_xmlns = 'urn:uddi-org:api'; + + /** + * used UDDI version + * @var string $_uddiversion + */ + var $_uddiversion = 1; + + /** + * used XML generic version + * @var string $_generic + */ + var $_generic; + + /** + * debug mode + * @var boolean $_debug + */ + var $_debug = false; + + /** + * Turns on _posting of UDDI message to UBR + * @var boolean $_transmit + */ + var $_transmit = true; + + /** + * Host to use + * @var string $_host + */ + var $_host; + + /** + * URL to use + * @var string $_url + */ + var $_url; + + // }}} + // {{{ constructor + + /** + * constructor + * + * @access public + * @param string $registry name of registry to use + * @param integer $version UDDI version to use + */ + function UDDI($registry = 'IBM', $version = 1) + { + $this->splitUrl($registry, $version); + } + + // }}} + // {{{ splitUrl() + + /** + * retrieves information from URL and sets params + * + * @access public + * @param string $registry name of registry to use + * @param integer $version UDDI version to use + */ + function splitUrl($registry, $version) + { + $this->_registry = $registry; + $reg = $this->_regarray[$this->_registry][$this->_api]['url']; + $reg = str_replace('http://', '', $reg); + $pos = strpos($reg, '/') + or PEAR::raiseError("Invalid registry (POS = $pos, URL = '$reg')\n"); + $this->_host = substr($reg, 0, $pos); + $this->_url = substr($reg, $pos, strlen($reg) - 1); + + if ($version > 1) { + $this->_xmlns .= "_v$version"; + } + + $this->_generic = "$version.0"; + } + + // }}} + // {{{ post() + + /** + * assembles HTTP headers and posts these and the UDDI message to the UBR + * + * @access public + * @param string $message the UDDI message to send + * @return string $data data returned from the UBR + */ + function post($message) + { + $msg_length = strlen($message); + $php_version = phpversion(); + $date = str_replace('+0000', 'GMT', gmdate('r', time())); + + $header = ''; + $header .= "POST $this->_url HTTP/1.0\r\n"; + $header .= "Date: $date\r\n"; + $header .= "Content-Type: text/xml; charset=UTF-8\r\n"; + $header .= "User-agent: PEAR::UDDI/$this->_version php/$php_version\r\n"; + $header .= "Host: $this->_host\r\n"; + $header .= "SOAPAction: \"\"\r\n"; + $header .= "Content-Length: $msg_length\r\n\r\n"; + + // echoes HTTP header and UDDI message to page if true + if ($this->_debug) { + echo '
    ' . htmlspecialchars(str_replace('><', ">\n<", $header . $message)) . '
    '; + } + + // sends header and message to UBR if true + if ($this->_transmit) { + $port = $this->_regarray[$this->_registry][$this->_api]['port']; + $fp = fsockopen($this->_host, $port, $errno, $errstr, 5) + or PEAR::raiseError("Couldn't connect to server at $this->_host:$port.
    Error #$errno: $errstr."); + + fputs($fp, $header) + or PEAR::raiseError('Couldn\'t send HTTP headers.'); + fputs($fp, "$message\n\n") + or PEAR::raiseError('Couldn\'t send UDDI message.'); + + $response = ''; + while (!feof($fp)) { + $response .= fgets($fp, 1024) + or PEAR::raiseError('No response from server.'); + } + fclose($fp) + or PEAR::raiseError('Warning: Couldn\'t close HTTP connection.'); + + $response = str_replace('><', ">\n<", $response); + return $response; + } + } + + // }}} + // {{{ query() + + /** + * sends and UDDI query to the registry server + * + * @access public + * @param string $method the UDDI message to send + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function query($method, $params) + { + $message = $this->assemble($method, $params); + + return $this->post($message); + } + + // }}} + // {{{ assemble() + + /** + * generate XML creating the UDDI query + * + * @access public + * @param string $method the UDDI message to send + * @param array $params parameters for the query + * @return string $data the desired XML query code + */ + function assemble($method, $params) + { + $head = ''; + $head .= ''; + $head .= ''; + + $end = ""; + + $attrib = ''; + $element = ''; + + if (isset($params['discoveryURLs']) && ($params['discoveryURLs'] != '')) { + $element .= '' . $params['discoveryURLs'] . ''; + } + + if (isset($params['bindingKey']) && ($params['bindingKey'] != '')) { + $element .= '' . $params['bindingKey'] . ''; + } + + if (isset($params['businessKey']) && ($params['businessKey'] != '')) { + $element .= '' . $params['businessKey'] . ''; + } + + if (isset($params['serviceKey']) && ($params['serviceKey'] != '')) { + + if ($method == 'find_binding') { + $attrib .= ' serviceKey="' . $params['serviceKey'] . '"'; + } + if ($method == 'get_serviceDetail') { + $element .= '' . $params['serviceKey'] . ''; + } + } + + if (isset($params['tModelKey']) && ($params['tModelKey'] != '')) { + $element .= 'uuid:' . $params['tModelKey'] . ''; + } + + if (isset($params['findQualifiers']) && ($params['findQualifiers'] != '')) { + $element .= ''; + $findQualifiers = explode(',', $params['findQualifiers']); + for ($i = 0; $i < count($findQualifiers); $i++) { + $element .= '' . $findQualifiers[$i] . ''; + } + $element .= ''; + } + + if (isset($params['tModelBag']) && ($params['tModelBag'] != '')) { + $tModelKey = explode(',', $params['tModelBag']); + $element .= ''; + for ($i = 0; $i < count($tModelKey); $i++) { + $element .= 'uuid:' . $tModelKey[$i] . ''; + $element .= ''; + } + } + + if (isset($params['name']) && ($params['name'] != '')) { + $lang = ''; + if (isset($params['lang']) && ($params['lang'] != '')) { + $lang = "xml:lang=\"$lang\""; + } + $element .= '' . $params['name'] . ''; + } + + if (isset($params['identifierBag']) && ($params['identifierBag'] != '')) { + $element .= ''; + $keyedReference = explode(',', $params['identifierBag']); + for ($i = 0; $i < count($keyedReference); $i++) { + $element .= '' . $keyedReference[$i] . ''; + } + $element .= ''; + } + + if (isset($params['categoryBag']) && ($params['categoryBag'] != '')) { + $element .= ''; + $keyedReference = explode(',', $params['identifierBag']); + for ($i = 0; $i'; + } + $element .= ''; + } + + if (isset($params['maxRows']) && ($params['maxRows'] != '')) { + $attrib .= ' maxRows="' . $params['maxRows'] . '"'; + } + + $head .= "<$method $attrib xmlns=\"$this->_xmlns\" generic=\"$this->_generic\">"; + + $message = $head; + $message .= $element; + $message .= $end; + + return $message; + } + + // }}} + // {{{ find_binding() + + /** + * Sends find_binding inquiry to UBR (searchs for bindings within a businessService element) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function find_binding($params) + { + $data = $this->query('find_binding', $params); + return $data; + } + + // }}} + // {{{ find_business() + + /** + * Sends find_business inquiry to UBR (searchs businessEntity elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function find_business($params) + { + $data = $this->query('find_business', $params); + return $data; + } + + // }}} + // {{{ find_relatedBusinesses() + + /** + * Sends find_relatedBusinesses inquiry to UBR (searchs for related businessEntity elements for a given businessKey) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function find_relatedBusinesses($params) + { + $data = $this->query('find_relatedBusinesses', $params); + return $data; + } + + // }}} + // {{{ find_service() + + /** + * Sends find_service inquiry to UBR (searchs for businessService elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function find_service($params) + { + $data = $this->query('find_service', $params); + return $data; + } + + // }}} + // {{{ find_tModel() + + /** + * Sends find_tModel inquiry to UBR (searchs for tModel elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function find_tModel($params) + { + $data = $this->query('find_tModel', $params); + return $data; + } + + // }}} + // {{{ get_bindingDetail() + + /** + * Sends get_bindingDetail inquiry to UBR (returns bindingDetail elements for one or more bindingKey elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function get_bindingDetail($params) + { + $data = $this->query('get_bindingDetail', $params); + return $data; + } + + // }}} + // {{{ get_businessDetail() + + /** + * Sends get_businessDetail inquiry to UBR (returns information about one or more businessEntity elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function get_businessDetail($params) + { + $data = $this->query('get_businessDetail', $params); + return $data; + } + + // }}} + // {{{ get_businessDetailExt() + + /** + * Sends get_businessDetailExt inquiry to UBR (returns extended information about one or more businessEntity elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function get_businessDetailExt($params) + { + $data = $this->query('get_businessDetailExt', $params); + return $data; + } + + // }}} + // {{{ get_serviceDetail() + + /** + * Sends get_serviceDetail inquiry to UBR (returns information about one or more businessService elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function get_serviceDetail($params) + { + $data = $this->query('get_serviceDetail', $params); + return $data; + } + + // }}} + // {{{ get_tModelDetail() + + /** + * Sends get_tModelDetail inquiry to UBR (returns information about one or more tModel elements) + * + * @access public + * @param array $params parameters for the query + * @return string $data response from the registry server + */ + function get_tModelDetail($params) + { + $data = $this->query('get_tModelDetail', $params); + return $data; + } + + // }}} + +} + +// }}} + +?> diff --git a/gulliver/thirdparty/pear/XML/Parser.php b/gulliver/thirdparty/pear/XML/Parser.php new file mode 100644 index 000000000..737fedc61 --- /dev/null +++ b/gulliver/thirdparty/pear/XML/Parser.php @@ -0,0 +1,684 @@ + | +// | Tomas V.V.Cox | +// | Stephan Schmidt | +// +----------------------------------------------------------------------+ +// +// $Id: Parser.php,v 1.25 2005/03/25 17:13:10 schst Exp $ + +/** + * XML Parser class. + * + * This is an XML parser based on PHP's "xml" extension, + * based on the bundled expat library. + * + * @category XML + * @package XML_Parser + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Stephan Schmidt + */ + +/** + * uses PEAR's error handling + */ +require_once 'PEAR.php'; + +/** + * resource could not be created + */ +define('XML_PARSER_ERROR_NO_RESOURCE', 200); + +/** + * unsupported mode + */ +define('XML_PARSER_ERROR_UNSUPPORTED_MODE', 201); + +/** + * invalid encoding was given + */ +define('XML_PARSER_ERROR_INVALID_ENCODING', 202); + +/** + * specified file could not be read + */ +define('XML_PARSER_ERROR_FILE_NOT_READABLE', 203); + +/** + * invalid input + */ +define('XML_PARSER_ERROR_INVALID_INPUT', 204); + +/** + * remote file cannot be retrieved in safe mode + */ +define('XML_PARSER_ERROR_REMOTE', 205); + +/** + * XML Parser class. + * + * This is an XML parser based on PHP's "xml" extension, + * based on the bundled expat library. + * + * Notes: + * - It requires PHP 4.0.4pl1 or greater + * - From revision 1.17, the function names used by the 'func' mode + * are in the format "xmltag_$elem", for example: use "xmltag_name" + * to handle the tags of your xml file. + * + * @category XML + * @package XML_Parser + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Stephan Schmidt + * @todo create XML_Parser_Namespace to parse documents with namespaces + * @todo create XML_Parser_Pull + * @todo Tests that need to be made: + * - mixing character encodings + * - a test using all expat handlers + * - options (folding, output charset) + * - different parsing modes + */ +class XML_Parser extends PEAR +{ + // {{{ properties + + /** + * XML parser handle + * + * @var resource + * @see xml_parser_create() + */ + var $parser; + + /** + * File handle if parsing from a file + * + * @var resource + */ + var $fp; + + /** + * Whether to do case folding + * + * If set to true, all tag and attribute names will + * be converted to UPPER CASE. + * + * @var boolean + */ + var $folding = true; + + /** + * Mode of operation, one of "event" or "func" + * + * @var string + */ + var $mode; + + /** + * Mapping from expat handler function to class method. + * + * @var array + */ + var $handler = array( + 'character_data_handler' => 'cdataHandler', + 'default_handler' => 'defaultHandler', + 'processing_instruction_handler' => 'piHandler', + 'unparsed_entity_decl_handler' => 'unparsedHandler', + 'notation_decl_handler' => 'notationHandler', + 'external_entity_ref_handler' => 'entityrefHandler' + ); + + /** + * source encoding + * + * @var string + */ + var $srcenc; + + /** + * target encoding + * + * @var string + */ + var $tgtenc; + + /** + * handler object + * + * @var object + */ + var $_handlerObj; + + // }}} + // {{{ constructor + + /** + * Creates an XML parser. + * + * This is needed for PHP4 compatibility, it will + * call the constructor, when a new instance is created. + * + * @param string $srcenc source charset encoding, use NULL (default) to use + * whatever the document specifies + * @param string $mode how this parser object should work, "event" for + * startelement/endelement-type events, "func" + * to have it call functions named after elements + * @param string $tgenc a valid target encoding + */ + function XML_Parser($srcenc = null, $mode = 'event', $tgtenc = null) + { + XML_Parser::__construct($srcenc, $mode, $tgtenc); + } + // }}} + + /** + * PHP5 constructor + * + * @param string $srcenc source charset encoding, use NULL (default) to use + * whatever the document specifies + * @param string $mode how this parser object should work, "event" for + * startelement/endelement-type events, "func" + * to have it call functions named after elements + * @param string $tgenc a valid target encoding + */ + function __construct($srcenc = null, $mode = 'event', $tgtenc = null) + { + $this->PEAR('XML_Parser_Error'); + + $this->mode = $mode; + $this->srcenc = $srcenc; + $this->tgtenc = $tgtenc; + } + // }}} + + /** + * Sets the mode of the parser. + * + * Possible modes are: + * - func + * - event + * + * You can set the mode using the second parameter + * in the constructor. + * + * This method is only needed, when switching to a new + * mode at a later point. + * + * @access public + * @param string mode, either 'func' or 'event' + * @return boolean|object true on success, PEAR_Error otherwise + */ + function setMode($mode) + { + if ($mode != 'func' && $mode != 'event') { + $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); + } + + $this->mode = $mode; + return true; + } + + /** + * Sets the object, that will handle the XML events + * + * This allows you to create a handler object independent of the + * parser object that you are using and easily switch the underlying + * parser. + * + * If no object will be set, XML_Parser assumes that you + * extend this class and handle the events in $this. + * + * @access public + * @param object object to handle the events + * @return boolean will always return true + * @since v1.2.0beta3 + */ + function setHandlerObj(&$obj) + { + $this->_handlerObj = &$obj; + return true; + } + + /** + * Init the element handlers + * + * @access private + */ + function _initHandlers() + { + if (!is_resource($this->parser)) { + return false; + } + + if (!is_object($this->_handlerObj)) { + $this->_handlerObj = &$this; + } + switch ($this->mode) { + + case 'func': + xml_set_object($this->parser, $this->_handlerObj); + xml_set_element_handler($this->parser, array(&$this, 'funcStartHandler'), array(&$this, 'funcEndHandler')); + break; + + case 'event': + xml_set_object($this->parser, $this->_handlerObj); + xml_set_element_handler($this->parser, 'startHandler', 'endHandler'); + break; + default: + return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); + break; + } + + + /** + * set additional handlers for character data, entities, etc. + */ + foreach ($this->handler as $xml_func => $method) { + if (method_exists($this->_handlerObj, $method)) { + $xml_func = 'xml_set_' . $xml_func; + $xml_func($this->parser, $method); + } + } + } + + // {{{ _create() + + /** + * create the XML parser resource + * + * Has been moved from the constructor to avoid + * problems with object references. + * + * Furthermore it allows us returning an error + * if something fails. + * + * @access private + * @return boolean|object true on success, PEAR_Error otherwise + * + * @see xml_parser_create + */ + function _create() + { + if ($this->srcenc === null) { + $xp = @xml_parser_create(); + } else { + $xp = @xml_parser_create($this->srcenc); + } + if (is_resource($xp)) { + if ($this->tgtenc !== null) { + if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING, + $this->tgtenc)) { + return $this->raiseError('invalid target encoding', XML_PARSER_ERROR_INVALID_ENCODING); + } + } + $this->parser = $xp; + $result = $this->_initHandlers($this->mode); + if ($this->isError($result)) { + return $result; + } + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding); + + return true; + } + return $this->raiseError('Unable to create XML parser resource.', XML_PARSER_ERROR_NO_RESOURCE); + } + + // }}} + // {{{ reset() + + /** + * Reset the parser. + * + * This allows you to use one parser instance + * to parse multiple XML documents. + * + * @access public + * @return boolean|object true on success, PEAR_Error otherwise + */ + function reset() + { + $result = $this->_create(); + if ($this->isError( $result )) { + return $result; + } + return true; + } + + // }}} + // {{{ setInputFile() + + /** + * Sets the input xml file to be parsed + * + * @param string Filename (full path) + * @return resource fopen handle of the given file + * @throws XML_Parser_Error + * @see setInput(), setInputString(), parse() + * @access public + */ + function setInputFile($file) + { + /** + * check, if file is a remote file + */ + if (eregi('^(http|ftp)://', substr($file, 0, 10))) { + if (!ini_get('allow_url_fopen')) { + return $this->raiseError('Remote files cannot be parsed, as safe mode is enabled.', XML_PARSER_ERROR_REMOTE); + } + } + + $fp = @fopen($file, 'rb'); + if (is_resource($fp)) { + $this->fp = $fp; + return $fp; + } + return $this->raiseError('File could not be opened.', XML_PARSER_ERROR_FILE_NOT_READABLE); + } + + // }}} + // {{{ setInputString() + + /** + * XML_Parser::setInputString() + * + * Sets the xml input from a string + * + * @param string $data a string containing the XML document + * @return null + **/ + function setInputString($data) + { + $this->fp = $data; + return null; + } + + // }}} + // {{{ setInput() + + /** + * Sets the file handle to use with parse(). + * + * You should use setInputFile() or setInputString() if you + * pass a string + * + * @param mixed $fp Can be either a resource returned from fopen(), + * a URL, a local filename or a string. + * @access public + * @see parse() + * @uses setInputString(), setInputFile() + */ + function setInput($fp) + { + if (is_resource($fp)) { + $this->fp = $fp; + return true; + } + // see if it's an absolute URL (has a scheme at the beginning) + elseif (eregi('^[a-z]+://', substr($fp, 0, 10))) { + return $this->setInputFile($fp); + } + // see if it's a local file + elseif (file_exists($fp)) { + return $this->setInputFile($fp); + } + // it must be a string + else { + $this->fp = $fp; + return true; + } + + return $this->raiseError('Illegal input format', XML_PARSER_ERROR_INVALID_INPUT); + } + + // }}} + // {{{ parse() + + /** + * Central parsing function. + * + * @return true|object PEAR error returns true on success, or a PEAR_Error otherwise + * @access public + */ + function parse() + { + /** + * reset the parser + */ + $result = $this->reset(); + if ($this->isError($result)) { + return $result; + } + // if $this->fp was fopened previously + if (is_resource($this->fp)) { + + while ($data = fread($this->fp, 4096)) { + if (!$this->_parseString($data, feof($this->fp))) { + $error = &$this->raiseError(); + $this->free(); + return $error; + } + } + // otherwise, $this->fp must be a string + } else { + if (!$this->_parseString($this->fp, true)) { + $error = &$this->raiseError(); + $this->free(); + return $error; + } + } + $this->free(); + + return true; + } + + /** + * XML_Parser::_parseString() + * + * @param string $data + * @param boolean $eof + * @return bool + * @access private + * @see parseString() + **/ + function _parseString($data, $eof = false) + { + return xml_parse($this->parser, $data, $eof); + } + + // }}} + // {{{ parseString() + + /** + * XML_Parser::parseString() + * + * Parses a string. + * + * @param string $data XML data + * @param boolean $eof If set and TRUE, data is the last piece of data sent in this parser + * @throws XML_Parser_Error + * @return Pear Error|true true on success or a PEAR Error + * @see _parseString() + */ + function parseString($data, $eof = false) + { + if (!isset($this->parser) || !is_resource($this->parser)) { + $this->reset(); + } + + if (!$this->_parseString($data, $eof)) { + $error = &$this->raiseError(); + $this->free(); + return $error; + } + + if ($eof === true) { + $this->free(); + } + return true; + } + + /** + * XML_Parser::free() + * + * Free the internal resources associated with the parser + * + * @return null + **/ + function free() + { + if (isset($this->parser) && is_resource($this->parser)) { + xml_parser_free($this->parser); + unset( $this->parser ); + } + if (isset($this->fp) && is_resource($this->fp)) { + fclose($this->fp); + } + unset($this->fp); + return null; + } + + /** + * XML_Parser::raiseError() + * + * Throws a XML_Parser_Error + * + * @param string $msg the error message + * @param integer $ecode the error message code + * @return XML_Parser_Error + **/ + function raiseError($msg = null, $ecode = 0) + { + $msg = !is_null($msg) ? $msg : $this->parser; + $err = &new XML_Parser_Error($msg, $ecode); + return parent::raiseError($err); + } + + // }}} + // {{{ funcStartHandler() + + function funcStartHandler($xp, $elem, $attribs) + { + $func = 'xmltag_' . $elem; + if (strchr($func, '.')) { + $func = str_replace('.', '_', $func); + } + if (method_exists($this->_handlerObj, $func)) { + call_user_func(array(&$this->_handlerObj, $func), $xp, $elem, $attribs); + } elseif (method_exists($this->_handlerObj, 'xmltag')) { + call_user_func(array(&$this->_handlerObj, 'xmltag'), $xp, $elem, $attribs); + } + } + + // }}} + // {{{ funcEndHandler() + + function funcEndHandler($xp, $elem) + { + $func = 'xmltag_' . $elem . '_'; + if (strchr($func, '.')) { + $func = str_replace('.', '_', $func); + } + if (method_exists($this->_handlerObj, $func)) { + call_user_func(array(&$this->_handlerObj, $func), $xp, $elem); + } elseif (method_exists($this->_handlerObj, 'xmltag_')) { + call_user_func(array(&$this->_handlerObj, 'xmltag_'), $xp, $elem); + } + } + + // }}} + // {{{ startHandler() + + /** + * + * @abstract + */ + function startHandler($xp, $elem, &$attribs) + { + return NULL; + } + + // }}} + // {{{ endHandler() + + /** + * + * @abstract + */ + function endHandler($xp, $elem) + { + return NULL; + } + + + // }}}me +} + +/** + * error class, replaces PEAR_Error + * + * An instance of this class will be returned + * if an error occurs inside XML_Parser. + * + * There are three advantages over using the standard PEAR_Error: + * - All messages will be prefixed + * - check for XML_Parser error, using is_a( $error, 'XML_Parser_Error' ) + * - messages can be generated from the xml_parser resource + * + * @package XML_Parser + * @access public + * @see PEAR_Error + */ +class XML_Parser_Error extends PEAR_Error +{ + // {{{ properties + + /** + * prefix for all messages + * + * @var string + */ + var $error_message_prefix = 'XML_Parser: '; + + // }}} + // {{{ constructor() + /** + * construct a new error instance + * + * You may either pass a message or an xml_parser resource as first + * parameter. If a resource has been passed, the last error that + * happened will be retrieved and returned. + * + * @access public + * @param string|resource message or parser resource + * @param integer error code + * @param integer error handling + * @param integer error level + */ + function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE) + { + if (is_resource($msgorparser)) { + $code = xml_get_error_code($msgorparser); + $msgorparser = sprintf('%s at XML input line %d', + xml_error_string($code), + xml_get_current_line_number($msgorparser)); + } + $this->PEAR_Error($msgorparser, $code, $mode, $level); + } + // }}} +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/catalog b/gulliver/thirdparty/pear/catalog new file mode 100644 index 000000000..6e0c69d40 --- /dev/null +++ b/gulliver/thirdparty/pear/catalog @@ -0,0 +1 @@ +PUBLIC "-//PHP Group//DTD PEAR Package 1.0//EN//XML" "package.dtd" diff --git a/gulliver/thirdparty/pear/class.nusoap_base.php b/gulliver/thirdparty/pear/class.nusoap_base.php new file mode 100644 index 000000000..332348b37 --- /dev/null +++ b/gulliver/thirdparty/pear/class.nusoap_base.php @@ -0,0 +1,905 @@ +globalDebugLevel = 9; + +/** +* +* nusoap_base +* +* @author Dietrich Ayala +* @version $Id: class.nusoap_base.php,v 1.43 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class nusoap_base { + /** + * Identification for HTTP headers. + * + * @var string + * @access private + */ + var $title = 'NuSOAP'; + /** + * Version for HTTP headers. + * + * @var string + * @access private + */ + var $version = '0.7.2'; + /** + * CVS revision for HTTP headers. + * + * @var string + * @access private + */ + var $revision = '$Revision: 1.43 $'; + /** + * Current error string (manipulated by getError/setError) + * + * @var string + * @access private + */ + var $error_str = ''; + /** + * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) + * + * @var string + * @access private + */ + var $debug_str = ''; + /** + * toggles automatic encoding of special characters as entities + * (should always be true, I think) + * + * @var boolean + * @access private + */ + var $charencoding = true; + /** + * the debug level for this instance + * + * @var integer + * @access private + */ + var $debugLevel; + + /** + * set schema version + * + * @var string + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * charset encoding for outgoing messages + * + * @var string + * @access public + */ + var $soap_defencoding = 'ISO-8859-1'; + //var $soap_defencoding = 'UTF-8'; + + /** + * namespaces in an array of prefix => uri + * + * this is "seeded" by a set of constants, but it may be altered by code + * + * @var array + * @access public + */ + var $namespaces = array( + 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' + ); + + /** + * namespaces used in the current context, e.g. during serialization + * + * @var array + * @access private + */ + var $usedNamespaces = array(); + + /** + * XML Schema types in an array of uri => (array of xml type => php type) + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var array + * @access public + */ + var $typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', + 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', + 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', + // abstract "any" types + 'anyType'=>'string','anySimpleType'=>'string', + // derived datatypes + 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', + 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', + 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', + 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), + 'http://www.w3.org/2000/10/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), + 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), + 'http://xml.apache.org/xml-soap' => array('Map') + ); + + /** + * XML entities to convert + * + * @var array + * @access public + * @deprecated + * @see expandEntities + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * constructor + * + * @access public + */ + function nusoap_base() { + $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * gets the global debug level, which applies to future instances + * + * @return integer Debug level 0-9, where 0 turns off + * @access public + */ + function getGlobalDebugLevel() { + return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * sets the global debug level, which applies to future instances + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setGlobalDebugLevel($level) { + $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; + } + + /** + * gets the debug level for this instance + * + * @return int Debug level 0-9, where 0 turns off + * @access public + */ + function getDebugLevel() { + return $this->debugLevel; + } + + /** + * sets the debug level for this instance + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setDebugLevel($level) { + $this->debugLevel = $level; + } + + /** + * adds debug data to the instance debug string with formatting + * + * @param string $string debug data + * @access private + */ + function debug($string){ + if ($this->debugLevel > 0) { + $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); + } + } + + /** + * adds debug data to the instance debug string without formatting + * + * @param string $string debug data + * @access public + */ + function appendDebug($string){ + if ($this->debugLevel > 0) { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str .= $string; + } + } + + /** + * clears the current debug data for this instance + * + * @access public + */ + function clearDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str = ''; + } + + /** + * gets the current debug data for this instance + * + * @return debug data + * @access public + */ + function &getDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + return $this->debug_str; + } + + /** + * gets the current debug data for this instance as an XML comment + * this may change the contents of the debug data + * + * @return debug data as an XML comment + * @access public + */ + function &getDebugAsXMLComment() { + // it would be nice to use a memory stream here to use + // memory more efficiently + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + return ""; + } + + /** + * expands entities, e.g. changes '<' to '<'. + * + * @param string $val The string in which to expand entities. + * @access private + */ + function expandEntities($val) { + if ($this->charencoding) { + $val = str_replace('&', '&', $val); + $val = str_replace("'", ''', $val); + $val = str_replace('"', '"', $val); + $val = str_replace('<', '<', $val); + $val = str_replace('>', '>', $val); + } + return $val; + } + + /** + * returns error string if present + * + * @return mixed error string or false + * @access public + */ + function getError(){ + if($this->error_str != ''){ + return $this->error_str; + } + return false; + } + + /** + * sets error string + * + * @return boolean $string error string + * @access private + */ + function setError($str){ + $this->error_str = $str; + } + + /** + * detect if array is a simple array or a struct (associative array) + * + * @param mixed $val The PHP array + * @return string (arraySimple|arrayStruct) + * @access private + */ + function isArraySimpleOrStruct($val) { + $keyList = array_keys($val); + foreach ($keyList as $keyListValue) { + if (!is_int($keyListValue)) { + return 'arrayStruct'; + } + } + return 'arraySimple'; + } + + /** + * serializes PHP values in accordance w/ section 5. Type information is + * not serialized if $use == 'literal'. + * + * @param mixed $val The value to serialize + * @param string $name The name (local part) of the XML element + * @param string $type The XML schema type (local part) for the element + * @param string $name_ns The namespace for the name of the XML element + * @param string $type_ns The namespace for the type of the element + * @param array $attributes The attributes to serialize as name=>value pairs + * @param string $use The WSDL "use" (encoded|literal) + * @return string The serialized element, possibly with child elements + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); + $this->appendDebug('value=' . $this->varDump($val)); + $this->appendDebug('attributes=' . $this->varDump($attributes)); + + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + // force valid name if necessary + if (is_numeric($name)) { + $name = '__numeric_' . $name; + } elseif (! $name) { + $name = 'noname'; + } + // if name has ns, add ns prefix to name + $xmlns = ''; + if($name_ns){ + $prefix = 'nu'.rand(1000,9999); + $name = $prefix.':'.$name; + $xmlns .= " xmlns:$prefix=\"$name_ns\""; + } + // if type is prefixed, create type prefix + if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ + // need to fix this. shouldn't default to xsd if no ns specified + // w/o checking against typemap + $type_prefix = 'xsd'; + } elseif($type_ns){ + $type_prefix = 'ns'.rand(1000,9999); + $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; + } + // serialize attributes if present + $atts = ''; + if($attributes){ + foreach($attributes as $k => $v){ + $atts .= " $k=\"".$this->expandEntities($v).'"'; + } + } + // serialize null value + if (is_null($val)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + return "<$name$xmlns $atts/>"; + } else { + if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; + } + } + // serialize if an xsd built-in primitive type + if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ + if (is_bool($val)) { + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + } else if (is_string($val)) { + $val = $this->expandEntities($val); + } + if ($use == 'literal') { + return "<$name$xmlns $atts>$val"; + } else { + return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case (is_bool($val) || $type == 'boolean'): + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val"; + } + break; + case is_object($val): + if (! $name) { + $name = get_class($val); + $this->debug("In serialize_val, used class name $name as element name"); + } else { + $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); + } + foreach(get_object_vars($val) as $k => $v){ + $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); + } + $xml .= '<'.$name.'>'.$pXml.''; + break; + break; + case (is_array($val) || $type): + // detect if struct or array + $valueType = $this->isArraySimpleOrStruct($val); + if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ + $i = 0; + if(is_array($val) && count($val)> 0){ + foreach($val as $v){ + if(is_object($v) && get_class($v) == 'soapval'){ + $tt_ns = $v->type_ns; + $tt = $v->type; + } elseif (is_array($v)) { + $tt = $this->isArraySimpleOrStruct($v); + } else { + $tt = gettype($v); + } + $array_types[$tt] = 1; + // TODO: for literal, the name should be $name + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:anyType'; + } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { + if ($tt == 'integer') { + $tt = 'int'; + } + $array_typename = 'xsd:'.$tt; + } elseif(isset($tt) && $tt == 'arraySimple'){ + $array_typename = 'SOAP-ENC:Array'; + } elseif(isset($tt) && $tt == 'arrayStruct'){ + $array_typename = 'unnamed_struct_use_soapval'; + } else { + // if type is prefixed, create type prefix + if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ + $array_typename = 'xsd:' . $tt; + } elseif ($tt_ns) { + $tt_prefix = 'ns' . rand(1000, 9999); + $array_typename = "$tt_prefix:$tt"; + $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; + } else { + $array_typename = $tt; + } + } + $array_type = $i; + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; + } + // empty array + } else { + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; + } + } + // TODO: for array in literal, there is no wrapper here + $xml = "<$name$xmlns$type_str$atts>".$xml.""; + } else { + // got a struct + if(isset($type) && isset($type_prefix)){ + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>"; + } else { + $xml .= "<$name$xmlns$type_str$atts>"; + } + foreach($val as $k => $v){ + // Apache Map + if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { + $xml .= ''; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= ''; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= ""; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serializes a message + * + * @param string $body the XML of the SOAP body + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param array $namespaces optional the namespaces used in generating the body and headers + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @return string the message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ + // TODO: add an option to automatically run utf8_encode on $body and $headers + // if $this->soap_defencoding is UTF-8. Not doing this automatically allows + // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 + + $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); + $this->debug("headers:"); + $this->appendDebug($this->varDump($headers)); + $this->debug("namespaces:"); + $this->appendDebug($this->varDump($namespaces)); + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($encodingStyle) { + $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; + } + + // serialize headers + if($headers){ + if (is_array($headers)) { + $xml = ''; + foreach ($headers as $header) { + $xml .= $this->serialize_val($header, false, false, false, false, false, $use); + } + $headers = $xml; + $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); + } + $headers = "".$headers.""; + } + // serialize envelope + return + 'soap_defencoding .'"?'.">". + '". + $headers. + "". + $body. + "". + ""; + } + + /** + * formats a string to be inserted into an HTML stream + * + * @param string $str The string to format + * @return string The formatted string + * @access public + * @deprecated + */ + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts (changes namespace to prefix) a qualified name + * + * @param string $qname qname + * @return string contracted qname + * @access private + */ + function contractQname($qname){ + // get element namespace + //$this->xdebug("Contract $qname"); + if (strrpos($qname, ':')) { + // get unqualified name + $name = substr($qname, strrpos($qname, ':') + 1); + // get ns + $ns = substr($qname, 0, strrpos($qname, ':')); + $p = $this->getPrefixFromNamespace($ns); + if ($p) { + return $p . ':' . $name; + } + return $qname; + } else { + return $qname; + } + } + + /** + * expands (changes prefix to namespace) a qualified name + * + * @param string $string qname + * @return string expanded qname + * @access private + */ + function expandQname($qname){ + // get element prefix + if(strpos($qname,':') && !ereg('^http://',$qname)){ + // get unqualified name + $name = substr(strstr($qname,':'),1); + // get ns prefix + $prefix = substr($qname,0,strpos($qname,':')); + if(isset($this->namespaces[$prefix])){ + return $this->namespaces[$prefix].':'.$name; + } else { + return $qname; + } + } else { + return $qname; + } + } + + /** + * returns the local part of a prefixed string + * returns the original string, if not prefixed + * + * @param string $str The prefixed string + * @return string The local part + * @access public + */ + function getLocalPart($str){ + if($sstr = strrchr($str,':')){ + // get unqualified name + return substr( $sstr, 1 ); + } else { + return $str; + } + } + + /** + * returns the prefix part of a prefixed string + * returns false, if not prefixed + * + * @param string $str The prefixed string + * @return mixed The prefix or false if there is no prefix + * @access public + */ + function getPrefix($str){ + if($pos = strrpos($str,':')){ + // get prefix + return substr($str,0,$pos); + } + return false; + } + + /** + * pass it a prefix, it returns a namespace + * + * @param string $prefix The prefix + * @return mixed The namespace, false if no namespace has the specified prefix + * @access public + */ + function getNamespaceFromPrefix($prefix){ + if (isset($this->namespaces[$prefix])) { + return $this->namespaces[$prefix]; + } + //$this->setError("No namespace registered for prefix '$prefix'"); + return false; + } + + /** + * returns the prefix for a given namespace (or prefix) + * or false if no prefixes registered for the given namespace + * + * @param string $ns The namespace + * @return mixed The prefix, false if the namespace has no prefixes + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + /** + * returns the time in ODBC canonical form with microseconds + * + * @return string The time in ODBC canonical form with microseconds + * @access public + */ + function getmicrotime() { + if (function_exists('gettimeofday')) { + $tod = gettimeofday(); + $sec = $tod['sec']; + $usec = $tod['usec']; + } else { + $sec = time(); + $usec = 0; + } + return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); + } + + /** + * Returns a string with the output of var_dump + * + * @param mixed $data The variable to var_dump + * @return string The output of var_dump + * @access public + */ + function varDump($data) { + ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val; + } +} + +// XML Schema Datatype Helper Functions + +//xsd:dateTime helpers + +/** +* convert unix timestamp to ISO 8601 compliant date string +* +* @param string $timestamp Unix time stamp +* @access public +*/ +function timestamp_to_iso8601($timestamp,$utc=true){ + $datestr = date('Y-m-d\TH:i:sO',$timestamp); + if($utc){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + + if(ereg($eregStr,$datestr,$regs)){ + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); + } + return false; + } else { + return $datestr; + } +} + +/** +* convert ISO 8601 compliant date string to unix timestamp +* +* @param string $datestr ISO 8601 compliant date string +* @access public +*/ +function iso8601_to_timestamp($datestr){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + if(ereg($eregStr,$datestr,$regs)){ + // not utc + if($regs[8] != 'Z'){ + $op = substr($regs[8],0,1); + $h = substr($regs[8],1,2); + $m = substr($regs[8],strlen($regs[8])-2,2); + if($op == '-'){ + $regs[4] = $regs[4] + $h; + $regs[5] = $regs[5] + $m; + } elseif($op == '+'){ + $regs[4] = $regs[4] - $h; + $regs[5] = $regs[5] - $m; + } + } + return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); + } else { + return false; + } +} + +/** +* sleeps some number of microseconds +* +* @param string $usec the number of microseconds to sleep +* @access public +* @deprecated +*/ +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soap_fault.php b/gulliver/thirdparty/pear/class.soap_fault.php new file mode 100644 index 000000000..139d375dd --- /dev/null +++ b/gulliver/thirdparty/pear/class.soap_fault.php @@ -0,0 +1,86 @@ + +* @version $Id: class.soap_fault.php,v 1.12 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class soap_fault extends nusoap_base { + /** + * The fault code (client|server) + * @var string + * @access private + */ + var $faultcode; + /** + * The fault actor + * @var string + * @access private + */ + var $faultactor; + /** + * The fault string, a description of the fault + * @var string + * @access private + */ + var $faultstring; + /** + * The fault detail, typically a string or array of string + * @var mixed + * @access private + */ + var $faultdetail; + + /** + * constructor + * + * @param string $faultcode (client | server) + * @param string $faultactor only used when msg routed between multiple actors + * @param string $faultstring human readable error message + * @param mixed $faultdetail detail, typically a string or array of string + */ + function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + parent::nusoap_base(); + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @return string The serialization of the fault instance. + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + 'soap_defencoding.'"?>'. + '\n". + ''. + ''. + $this->serialize_val($this->faultcode, 'faultcode'). + $this->serialize_val($this->faultactor, 'faultactor'). + $this->serialize_val($this->faultstring, 'faultstring'). + $this->serialize_val($this->faultdetail, 'detail'). + ''. + ''. + ''; + return $return_msg; + } +} + + + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soap_parser.php b/gulliver/thirdparty/pear/class.soap_parser.php new file mode 100644 index 000000000..098d1582b --- /dev/null +++ b/gulliver/thirdparty/pear/class.soap_parser.php @@ -0,0 +1,599 @@ + +* @version $Id: class.soap_parser.php,v 1.36 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_parser extends nusoap_base { + + var $xml = ''; + var $xml_encoding = ''; + var $method = ''; + var $root_struct = ''; + var $root_struct_name = ''; + var $root_struct_namespace = ''; + var $root_header = ''; + var $document = ''; // incoming SOAP body (text) + // determines where in the message we are (envelope,header,body,method) + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $namespaces = array(); + var $message = array(); + var $parent = ''; + var $fault = false; + var $fault_code = ''; + var $fault_str = ''; + var $fault_detail = ''; + var $depth_array = array(); + var $debug_flag = true; + var $soapresponse = NULL; + var $responseHeaders = ''; // incoming SOAP headers (text) + var $body_position = 0; + // for multiref parsing: + // array of id => pos + var $ids = array(); + // array of id => hrefs => pos + var $multirefs = array(); + // toggle for auto-decoding element content + var $decode_utf8 = true; + + /** + * constructor that actually does the parsing + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method method for which XML is parsed (unused?) + * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 + * @access public + */ + function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ + parent::nusoap_base(); + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + // Check XML encoding + $pos_xml = strpos($xml, '', $pos_xml + 2) - $pos_xml + 1); + if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { + $xml_encoding = $res[1]; + if (strtoupper($xml_encoding) != $encoding) { + $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; + $this->debug($err); + if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { + $this->setError($err); + return; + } + // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed + } else { + $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); + } + } else { + $this->debug('No encoding specified in XML declaration'); + } + } else { + $this->debug('No XML declaration'); + } + $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); + // Create an XML parser - why not xml_parser_create_ns? + $this->parser = xml_parser_create($this->xml_encoding); + // Set the options for parsing the XML data. + //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element','end_element'); + xml_set_character_data_handler($this->parser,'character_data'); + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $err = sprintf('XML error parsing SOAP payload on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser))); + $this->debug($err); + $this->debug("XML payload:\n" . $xml); + $this->setError($err); + } else { + $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); + // get final value + $this->soapresponse = $this->message[$this->root_struct]['result']; + // get header value: no, because this is documented as XML string +// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ +// $this->responseHeaders = $this->message[$this->root_header]['result']; +// } + // resolve hrefs/ids + if(sizeof($this->multirefs) > 0){ + foreach($this->multirefs as $id => $hrefs){ + $this->debug('resolving multirefs for id: '.$id); + $idVal = $this->buildVal($this->ids[$id]); + if (is_array($idVal) && isset($idVal['!id'])) { + unset($idVal['!id']); + } + foreach($hrefs as $refPos => $ref){ + $this->debug('resolving href at pos '.$refPos); + $this->multirefs[$id][$refPos] = $idVal; + } + } + } + } + xml_parser_free($this->parser); + } else { + $this->debug('xml was empty, didn\'t parse!'); + $this->setError('xml was empty, didn\'t parse!'); + } + } + + /** + * start-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @param array $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) { + // position in a total number of elements, starting from 0 + // update class level pos + $pos = $this->position++; + // and set mine + $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); + // depth = how many levels removed from root? + // set mine as current global depth and increment global depth value + $this->message[$pos]['depth'] = $this->depth++; + + // else add self as child to whoever the current parent is + if($pos != 0){ + $this->message[$this->parent]['children'] .= '|'.$pos; + } + // set my parent + $this->message[$pos]['parent'] = $this->parent; + // set self as current parent + $this->parent = $pos; + // set self as current value for this depth + $this->depth_array[$this->depth] = $pos; + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + // set status + if($name == 'Envelope'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->root_header = $pos; + $this->status = 'header'; + } elseif($name == 'Body'){ + $this->status = 'body'; + $this->body_position = $pos; + // set method + } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->message[$pos]['type'] = 'struct'; + $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); + } + // set my status + $this->message[$pos]['status'] = $this->status; + // set name + $this->message[$pos]['name'] = htmlspecialchars($name); + // set attrs + $this->message[$pos]['attrs'] = $attrs; + + // loop through atts, logging ns and type declarations + $attstr = ''; + foreach($attrs as $key => $value){ + $key_prefix = $this->getPrefix($key); + $key_localpart = $this->getLocalPart($key); + // if ns declarations, add to class level array of valid namespaces + if($key_prefix == 'xmlns'){ + if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ + $this->XMLSchemaVersion = $value; + $this->namespaces['xsd'] = $this->XMLSchemaVersion; + $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; + } + $this->namespaces[$key_localpart] = $value; + // set method namespace + if($name == $this->root_struct_name){ + $this->methodNamespace = $value; + } + // if it's a type declaration, set type + } elseif($key_localpart == 'type'){ + $value_prefix = $this->getPrefix($value); + $value_localpart = $this->getLocalPart($value); + $this->message[$pos]['type'] = $value_localpart; + $this->message[$pos]['typePrefix'] = $value_prefix; + if(isset($this->namespaces[$value_prefix])){ + $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; + } else if(isset($attrs['xmlns:'.$value_prefix])) { + $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; + } + // should do something here with the namespace of specified type? + } elseif($key_localpart == 'arrayType'){ + $this->message[$pos]['type'] = 'array'; + /* do arrayType ereg here + [1] arrayTypeValue ::= atype asize + [2] atype ::= QName rank* + [3] rank ::= '[' (',')* ']' + [4] asize ::= '[' length~ ']' + [5] length ::= nextDimension* Digit+ + [6] nextDimension ::= Digit+ ',' + */ + $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; + if(ereg($expr,$value,$regs)){ + $this->message[$pos]['typePrefix'] = $regs[1]; + $this->message[$pos]['arrayTypePrefix'] = $regs[1]; + if (isset($this->namespaces[$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; + } else if (isset($attrs['xmlns:'.$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; + } + $this->message[$pos]['arrayType'] = $regs[2]; + $this->message[$pos]['arraySize'] = $regs[3]; + $this->message[$pos]['arrayCols'] = $regs[4]; + } + // specifies nil value (or not) + } elseif ($key_localpart == 'nil'){ + $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); + // some other attribute + } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { + $this->message[$pos]['xattrs']['!' . $key] = $value; + } + + if ($key == 'xmlns') { + $this->default_namespace = $value; + } + // log id + if($key == 'id'){ + $this->ids[$value] = $pos; + } + // root + if($key_localpart == 'root' && $value == 1){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->debug("found root struct $this->root_struct_name, pos $pos"); + } + // for doclit + $attstr .= " $key=\"$value\""; + } + // get namespace - must be done after namespace atts are processed + if(isset($prefix)){ + $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; + $this->default_namespace = $this->namespaces[$prefix]; + } else { + $this->message[$pos]['namespace'] = $this->default_namespace; + } + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } elseif($this->root_struct_name != ''){ + $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } + + /** + * end-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name) { + // position of current element is equal to the last value left in depth_array for my depth + $pos = $this->depth_array[$this->depth--]; + + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + + // build to native type + if(isset($this->body_position) && $pos > $this->body_position){ + // deal w/ multirefs + if(isset($this->message[$pos]['attrs']['href'])){ + // get id + $id = substr($this->message[$pos]['attrs']['href'],1); + // add placeholder to href array + $this->multirefs[$id][$pos] = 'placeholder'; + // add set a reference to it as the result value + $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; + // build complexType values + } elseif($this->message[$pos]['children'] != ''){ + // if result has already been generated (struct/array) + if(!isset($this->message[$pos]['result'])){ + $this->message[$pos]['result'] = $this->buildVal($pos); + } + // build complexType values of attributes and possibly simpleContent + } elseif (isset($this->message[$pos]['xattrs'])) { + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + if (isset($this->message[$pos]['type'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; + } + } + } + $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; + // set value of simpleType (or nil complexType) + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['type'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['result'] = $this->message[$pos]['cdata']; + } + } + + /* add value to parent's result, if parent is struct/array + $parent = $this->message[$pos]['parent']; + if($this->message[$parent]['type'] != 'map'){ + if(strtolower($this->message[$parent]['type']) == 'array'){ + $this->message[$parent]['result'][] = $this->message[$pos]['result']; + } else { + $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; + } + } + */ + } + } + + // for doclit + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= ""; + } + } elseif($pos >= $this->root_struct){ + $this->document .= ""; + } + // switch status + if($pos == $this->root_struct){ + $this->status = 'body'; + $this->root_struct_namespace = $this->message[$pos]['namespace']; + } elseif($name == 'Body'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->status = 'envelope'; + } elseif($name == 'Envelope'){ + // + } + // set parent back to my parent + $this->parent = $this->message[$pos]['parent']; + } + + /** + * element content handler + * + * @param resource $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data){ + $pos = $this->depth_array[$this->depth]; + if ($this->xml_encoding=='UTF-8'){ + // TODO: add an option to disable this for folks who want + // raw UTF-8 that, e.g., might not map to iso-8859-1 + // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); + if($this->decode_utf8){ + $data = utf8_decode($data); + } + } + $this->message[$pos]['cdata'] .= $data; + // for doclit + if($this->status == 'header'){ + $this->responseHeaders .= $data; + } else { + $this->document .= $data; + } + } + + /** + * get the parsed message + * + * @return mixed + * @access public + */ + function get_response(){ + return $this->soapresponse; + } + + /** + * get the parsed headers + * + * @return string XML or empty if no headers + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * decodes simple types into PHP variables + * + * @param string $value value to decode + * @param string $type XML type to decode + * @param string $typens XML type namespace to decode + * @return mixed PHP value + * @access private + */ + function decodeSimple($value, $type, $typens) { + // TODO: use the namespace! + if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { + return (string) $value; + } + if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { + return (int) $value; + } + if ($type == 'float' || $type == 'double' || $type == 'decimal') { + return (double) $value; + } + if ($type == 'boolean') { + if (strtolower($value) == 'false' || strtolower($value) == 'f') { + return false; + } + return (boolean) $value; + } + if ($type == 'base64' || $type == 'base64Binary') { + $this->debug('Decode base64 value'); + return base64_decode($value); + } + // obscure numeric types + if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' + || $type == 'nonNegativeInteger' || $type == 'positiveInteger' + || $type == 'unsignedInt' + || $type == 'unsignedShort' || $type == 'unsignedByte') { + return (int) $value; + } + // bogus: parser treats array with no elements as a simple type + if ($type == 'array') { + return array(); + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * and scalars + * + * @param integer $pos position in node tree + * @return mixed PHP value + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['children'] != ''){ + $this->debug('in buildVal, there are children'); + $children = explode('|',$this->message[$pos]['children']); + array_shift($children); // knock off empty + // md array + if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ + $r=0; // rowcount + $c=0; // colcount + foreach($children as $child_pos){ + $this->debug("in buildVal, got an MD array element: $r, $c"); + $params[$r][] = $this->message[$child_pos]['result']; + $c++; + if($c == $this->message[$pos]['arrayCols']){ + $c = 0; + $r++; + } + } + // array + } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ + $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $params[] = &$this->message[$child_pos]['result']; + } + // apache Map type: java hashtable + } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ + $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $kv = explode("|",$this->message[$child_pos]['children']); + $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; + } + // generic compound type + //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { + } else { + // Apache Vector type: treat as an array + $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + $notstruct = 0; + } + // + foreach($children as $child_pos){ + if($notstruct){ + $params[] = &$this->message[$child_pos]['result']; + } else { + if (isset($params[$this->message[$child_pos]['name']])) { + // de-serialize repeated element name into an array + if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { + $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); + } + $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; + } else { + $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; + } + } + } + } + if (isset($this->message[$pos]['xattrs'])) { + $this->debug('in buildVal, handling attributes'); + foreach ($this->message[$pos]['xattrs'] as $n => $v) { + $params[$n] = $v; + } + } + // handle simpleContent + if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + $this->debug('in buildVal, handling simpleContent'); + if (isset($this->message[$pos]['type'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $params['!'] = $this->message[$pos]['cdata']; + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('in buildVal, no children, building scalar'); + $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; + if (isset($this->message[$pos]['type'])) { + return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } + return $this->message[$pos]['cdata']; + } + } +} + + + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soap_server.php b/gulliver/thirdparty/pear/class.soap_server.php new file mode 100644 index 000000000..b4e976424 --- /dev/null +++ b/gulliver/thirdparty/pear/class.soap_server.php @@ -0,0 +1,1038 @@ + +* @version $Id: class.soap_server.php,v 1.48 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_server extends nusoap_base { + /** + * HTTP headers of request + * @var array + * @access private + */ + var $headers = array(); + /** + * HTTP request + * @var string + * @access private + */ + var $request = ''; + /** + * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $requestHeaders = ''; + /** + * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $document = ''; + /** + * SOAP payload for request (text) + * @var string + * @access public + */ + var $requestSOAP = ''; + /** + * requested method namespace URI + * @var string + * @access private + */ + var $methodURI = ''; + /** + * name of method requested + * @var string + * @access private + */ + var $methodname = ''; + /** + * method parameters from request + * @var array + * @access private + */ + var $methodparams = array(); + /** + * SOAP Action from request + * @var string + * @access private + */ + var $SOAPAction = ''; + /** + * character set encoding of incoming (request) messages + * @var string + * @access public + */ + var $xml_encoding = ''; + /** + * toggles whether the parser decodes element content w/ utf8_decode() + * @var boolean + * @access public + */ + var $decode_utf8 = true; + + /** + * HTTP headers of response + * @var array + * @access public + */ + var $outgoing_headers = array(); + /** + * HTTP response + * @var string + * @access private + */ + var $response = ''; + /** + * SOAP headers for response (text) + * @var string + * @access public + */ + var $responseHeaders = ''; + /** + * SOAP payload for response (text) + * @var string + * @access private + */ + var $responseSOAP = ''; + /** + * method return value to place in response + * @var mixed + * @access private + */ + var $methodreturn = false; + /** + * whether $methodreturn is a string of literal XML + * @var boolean + * @access public + */ + var $methodreturnisliteralxml = false; + /** + * SOAP fault for response (or false) + * @var mixed + * @access private + */ + var $fault = false; + /** + * text indication of result (for debugging) + * @var string + * @access private + */ + var $result = 'successful'; + + /** + * assoc array of operations => opData; operations are added by the register() + * method or by parsing an external WSDL definition + * @var array + * @access private + */ + var $operations = array(); + /** + * wsdl instance (if one) + * @var mixed + * @access private + */ + var $wsdl = false; + /** + * URL for WSDL (if one) + * @var mixed + * @access private + */ + var $externalWSDLURL = false; + /** + * whether to append debug to response as XML comment + * @var boolean + * @access public + */ + var $debug_flag = false; + + + /** + * constructor + * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. + * + * @param mixed $wsdl file path or URL (string), or wsdl instance (object) + * @access public + */ + function soap_server($wsdl=false){ + parent::nusoap_base(); + // turn on debugging? + global $debug; + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $this->debug("_SERVER is defined:"); + $this->appendDebug($this->varDump($_SERVER)); + } elseif (isset($HTTP_SERVER_VARS)) { + $this->debug("HTTP_SERVER_VARS is defined:"); + $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); + } else { + $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); + } + + if (isset($debug)) { + $this->debug("In soap_server, set debug_flag=$debug based on global flag"); + $this->debug_flag = $debug; + } elseif (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); + $this->debug_flag = substr($v, 6); + } + } + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); + $this->debug_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + $this->debug("In soap_server, WSDL is specified"); + if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { + $this->wsdl = $wsdl; + $this->externalWSDLURL = $this->wsdl->wsdl; + $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); + } else { + $this->debug('Create wsdl from ' . $wsdl); + $this->wsdl = new wsdl($wsdl); + $this->externalWSDLURL = $wsdl; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($err = $this->wsdl->getError()){ + die('WSDL ERROR: '.$err); + } + } + } + + /** + * processes request and returns response + * + * @param string $data usually is the value of $HTTP_RAW_POST_DATA + * @access public + */ + function service($data){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER['QUERY_STRING'])) { + $qs = $_SERVER['QUERY_STRING']; + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = $HTTP_SERVER_VARS['QUERY_STRING']; + } else { + $qs = ''; + } + $this->debug("In service, query string=$qs"); + + if (ereg('wsdl', $qs) ){ + $this->debug("In service, this is a request for WSDL"); + if($this->externalWSDLURL){ + if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL + header('Location: '.$this->externalWSDLURL); + } else { // assume file + header("Content-Type: text/xml\r\n"); + $fp = fopen($this->externalWSDLURL, 'r'); + fpassthru($fp); + } + } elseif ($this->wsdl) { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize($this->debug_flag); + if ($this->debug_flag) { + $this->debug('wsdl:'); + $this->appendDebug($this->varDump($this->wsdl)); + print $this->getDebugAsXMLComment(); + } + } else { + header("Content-Type: text/html; charset=ISO-8859-1\r\n"); + print "This service does not provide WSDL"; + } + } elseif ($data == '' && $this->wsdl) { + $this->debug("In service, there is no data, so return Web description"); + print $this->wsdl->webDescription(); + } else { + $this->debug("In service, invoke the request"); + $this->parse_request($data); + if (! $this->fault) { + $this->invoke_method(); + } + if (! $this->fault) { + $this->serialize_return(); + } + $this->send_response(); + } + } + + /** + * parses HTTP request headers. + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * + * @access private + */ + function parse_http_headers() { + global $HTTP_SERVER_VARS; + + $this->request = ''; + $this->SOAPAction = ''; + if(function_exists('getallheaders')){ + $this->debug("In parse_http_headers, use getallheaders"); + $headers = getallheaders(); + foreach($headers as $k=>$v){ + $k = strtolower($k); + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + // get SOAPAction header + if(isset($this->headers['soapaction'])){ + $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); + } + // get the character encoding of the incoming request + if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ + $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + $this->debug("In parse_http_headers, use _SERVER"); + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } else { + $this->debug("In parse_http_headers, HTTP headers not accessible"); + $this->setError("HTTP headers not accessible"); + } + } + + /** + * parses a request + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * request + * requestSOAP + * methodURI + * methodname + * methodparams + * requestHeaders + * document + * + * This sets the fault field on error + * + * @param string $data XML string + * @access private + */ + function parse_request($data='') { + $this->debug('entering parse_request()'); + $this->parse_http_headers(); + $this->debug('got character encoding: '.$this->xml_encoding); + // uncompress if necessary + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { + $this->debug('got content encoding: ' . $this->headers['content-encoding']); + if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzuncompress')) { + if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { + $data = $degzdata; + } else { + $this->fault('Client', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Client', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $data = $this->parseRequest($this->headers, $data); + $this->requestSOAP = $data; + $this->debug('leaving parse_request'); + } + + /** + * invokes a PHP function for the requested SOAP method + * + * The following fields are set by this function (when successful) + * + * methodreturn + * + * Note that the PHP function that is called may also set the following + * fields to affect the response sent to the client + * + * responseHeaders + * outgoing_headers + * + * This sets the fault field on error + * + * @access private + */ + function invoke_method() { + $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); + + if ($this->wsdl) { + if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { + $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { + // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element + $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + $this->methodname = $this->opData['name']; + } else { + $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); + $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); + return; + } + } else { + $this->debug('in invoke_method, no WSDL to validate method'); + } + + // if a . is present in $this->methodname, we see if there is a class in scope, + // which could be referred to. We will also distinguish between two deliminators, + // to allow methods to be called a the class or an instance + $class = ''; + $method = ''; + if (strpos($this->methodname, '..') > 0) { + $delim = '..'; + } else if (strpos($this->methodname, '.') > 0) { + $delim = '.'; + } else { + $delim = ''; + } + + if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && + class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { + // get the class and method name + $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); + $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); + $this->debug("in invoke_method, class=$class method=$method delim=$delim"); + } + + // does method exist? + if ($class == '') { + if (!function_exists($this->methodname)) { + $this->debug("in invoke_method, function '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } else { + $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; + if (!in_array($method_to_compare, get_class_methods($class))) { + $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } + + // evaluate message, getting back parameters + // verify that request parameters match the method's signature + if(! $this->verify_method($this->methodname,$this->methodparams)){ + // debug + $this->debug('ERROR: request not verified against method signature'); + $this->result = 'fault: request failed validation against method signature'; + // return fault + $this->fault('Client',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('in invoke_method, params:'); + $this->appendDebug($this->varDump($this->methodparams)); + $this->debug("in invoke_method, calling '$this->methodname'"); + if (!function_exists('call_user_func_array')) { + if ($class == '') { + $this->debug('in invoke_method, calling function using eval()'); + $funcCall = "\$this->methodreturn = $this->methodname("; + } else { + if ($delim == '..') { + $this->debug('in invoke_method, calling class method using eval()'); + $funcCall = "\$this->methodreturn = ".$class."::".$method."("; + } else { + $this->debug('in invoke_method, calling instance method using eval()'); + // generate unique instance name + $instname = "\$inst_".time(); + $funcCall = $instname." = new ".$class."(); "; + $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; + } + } + if ($this->methodparams) { + foreach ($this->methodparams as $param) { + if (is_array($param)) { + $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); + return; + } + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1); + } + $funcCall .= ');'; + $this->debug('in invoke_method, function call: '.$funcCall); + @eval($funcCall); + } else { + if ($class == '') { + $this->debug('in invoke_method, calling function using call_user_func_array()'); + $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() + } elseif ($delim == '..') { + $this->debug('in invoke_method, calling class method using call_user_func_array()'); + $call_arg = array ($class, $method); + } else { + $this->debug('in invoke_method, calling instance method using call_user_func_array()'); + $instance = new $class (); + $call_arg = array(&$instance, $method); + } + $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); + } + $this->debug('in invoke_method, methodreturn:'); + $this->appendDebug($this->varDump($this->methodreturn)); + $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); + } + + /** + * serializes the return value from a PHP function into a full SOAP Envelope + * + * The following fields are set by this function (when successful) + * + * responseSOAP + * + * This sets the fault field on error + * + * @access private + */ + function serialize_return() { + $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); + // if fault + if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { + $this->debug('got a fault object from method'); + $this->fault = $this->methodreturn; + return; + } elseif ($this->methodreturnisliteralxml) { + $return_val = $this->methodreturn; + // returned value(s) + } else { + $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); + $this->debug('serializing return value'); + if($this->wsdl){ + // weak attempt at supporting multiple output params + if(sizeof($this->opData['output']['parts']) > 1){ + $opParams = $this->methodreturn; + } else { + // TODO: is this really necessary? + $opParams = array($this->methodreturn); + } + $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'unable to serialize result'); + return; + } + } else { + if (isset($this->methodreturn)) { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } else { + $return_val = ''; + $this->debug('in absence of WSDL, assume void return for backward compatibility'); + } + } + } + $this->debug('return value:'); + $this->appendDebug($this->varDump($return_val)); + + $this->debug('serializing response'); + if ($this->wsdl) { + $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); + if ($this->opData['style'] == 'rpc') { + $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); + if ($this->opData['output']['use'] == 'literal') { + $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } else { + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + } else { + $this->debug('style is not rpc for serialization: assume document'); + $payload = $return_val; + } + } else { + $this->debug('do not have WSDL for serialization: assume rpc/encoded'); + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->appendDebug($this->wsdl->getDebug()); + // } + if (isset($opData['output']['encodingStyle'])) { + $encodingStyle = $opData['output']['encodingStyle']; + } else { + $encodingStyle = ''; + } + // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); + } else { + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); + } + $this->debug("Leaving serialize_return"); + } + + /** + * sends an HTTP response + * + * The following fields are set by this function (when successful) + * + * outgoing_headers + * response + * + * @access private + */ + function send_response() { + $this->debug('Enter send_response'); + if ($this->fault) { + $payload = $this->fault->serialize(); + $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; + $this->outgoing_headers[] = "Status: 500 Internal Server Error"; + } else { + $payload = $this->responseSOAP; + // Some combinations of PHP+Web server allow the Status + // to come through as a header. Since OK is the default + // just do nothing. + // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; + // $this->outgoing_headers[] = "Status: 200 OK"; + } + // add debug data if in debug mode + if(isset($this->debug_flag) && $this->debug_flag){ + $payload .= $this->getDebugAsXMLComment(); + } + $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; + // Let the Web server decide about this + //$this->outgoing_headers[] = "Connection: Close\r\n"; + $payload = $this->getHTTPBody($payload); + $type = $this->getHTTPContentType(); + $charset = $this->getHTTPContentTypeCharset(); + $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); + //begin code to compress payload - by John + // NOTE: there is no way to know whether the Web server will also compress + // this data. + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { + if (strstr($this->headers['accept-encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { + // Note: MSIE requires gzdeflate output (no Zlib header and checksum), + // instead of gzcompress output, + // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) + if (function_exists('gzdeflate')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzdeflate($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + print $payload; + $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param string $operation The operation to be invoked + * @param array $request The array of parameter values + * @return boolean Whether the operation was found + * @access private + */ + function verify_method($operation,$request){ + if(isset($this->wsdl) && is_object($this->wsdl)){ + if($this->wsdl->getOperationData($operation)){ + return true; + } + } elseif(isset($this->operations[$operation])){ + return true; + } + return false; + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Request not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + // parse response, get soap parser obj + $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); + // parser debug + $this->debug("parser debug: \n".$parser->getDebug()); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Client',"error in msg parsing:\n".$err); + // else successfully parsed request into soapval object + } else { + // get/set methodname + $this->methodURI = $parser->root_struct_namespace; + $this->methodname = $parser->root_struct_name; + $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); + $this->debug('calling parser->get_response()'); + $this->methodparams = $parser->get_response(); + // get SOAP headers + $this->requestHeaders = $parser->getHeaders(); + // add document for doclit support + $this->document = $parser->document; + } + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /** + * add a method to the dispatch map (this has been replaced by the register method) + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + * @deprecated + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service function with the server + * + * @param string $name the name of the PHP function, class.method or class..method + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param mixed $namespace the element namespace for the method or false + * @param mixed $soapaction the soapaction for the method or false + * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param mixed $use optional (encoded|literal) or false + * @param string $documentation optional Description to include in WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ + global $HTTP_SERVER_VARS; + + if($this->externalWSDLURL){ + die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); + } + if (! $name) { + die('You must specify a name when you register an operation'); + } + if (!is_array($in)) { + die('You must provide an array for operation inputs'); + } + if (!is_array($out)) { + die('You must provide an array for operation outputs'); + } + if(false == $namespace) { + } + if(false == $soapaction) { + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + if ($use == 'encoded' && $encodingStyle = '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + $this->operations[$name] = array( + 'name' => $name, + 'in' => $in, + 'out' => $out, + 'namespace' => $namespace, + 'soapaction' => $soapaction, + 'style' => $style); + if($this->wsdl){ + $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); + } + return true; + } + + /** + * Specify a fault to be returned to the client. + * This also acts as a flag to the server that a fault has occured. + * + * @param string $faultcode + * @param string $faultstring + * @param string $faultactor + * @param string $faultdetail + * @access public + */ + function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ + if ($faultdetail == '' && $this->debug_flag) { + $faultdetail = $this->getDebug(); + } + $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); + $this->fault->soap_defencoding = $this->soap_defencoding; + } + + /** + * Sets up wsdl object. + * Acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param mixed $namespace optional 'tns' service namespace or false + * @param mixed $endpoint optional URL of service endpoint or false + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SERVER_PORT = $_SERVER['SERVER_PORT']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + $HTTPS = $HTTP_SERVER_VARS['HTTPS']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if ($HTTPS == '1' || $HTTPS == 'on') { + $SCHEME = 'https'; + } else { + $SCHEME = 'http'; + } + $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; + } + + if(false == $schemaTargetNamespace) { + $schemaTargetNamespace = $namespace; + } + + $this->wsdl = new wsdl; + $this->wsdl->serviceName = $serviceName; + $this->wsdl->endpoint = $endpoint; + $this->wsdl->namespaces['tns'] = $namespace; + $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; + $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; + if ($schemaTargetNamespace != $namespace) { + $this->wsdl->namespaces['types'] = $schemaTargetNamespace; + } + $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); + $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->bindings[$serviceName.'Binding'] = array( + 'name'=>$serviceName.'Binding', + 'style'=>$style, + 'transport'=>$transport, + 'portType'=>$serviceName.'PortType'); + $this->wsdl->ports[$serviceName.'Port'] = array( + 'binding'=>$serviceName.'Binding', + 'location'=>$endpoint, + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); + } +} + + + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soap_transport_http.php b/gulliver/thirdparty/pear/class.soap_transport_http.php new file mode 100644 index 000000000..5db113c7e --- /dev/null +++ b/gulliver/thirdparty/pear/class.soap_transport_http.php @@ -0,0 +1,1038 @@ + +* @version $Id: class.soap_transport_http.php,v 1.57 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class soap_transport_http extends nusoap_base { + + var $url = ''; + var $uri = ''; + var $digest_uri = ''; + var $scheme = ''; + var $host = ''; + var $port = ''; + var $path = ''; + var $request_method = 'POST'; + var $protocol_version = '1.0'; + var $encoding = ''; + var $outgoing_headers = array(); + var $incoming_headers = array(); + var $incoming_cookies = array(); + var $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username = ''; + var $password = ''; + var $authtype = ''; + var $digestRequest = array(); + var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) + // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' + // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' + // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' + // passphrase: SSL key password/passphrase + // verifypeer: default is 1 + // verifyhost: default is 1 + + /** + * constructor + */ + function soap_transport_http($url){ + parent::nusoap_base(); + $this->setURL($url); + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); + } + + function setURL($url) { + $this->url = $url; + + $u = parse_url($url); + foreach($u as $k => $v){ + $this->debug("$k = $v"); + $this->$k = $v; + } + + // add any GET params to path + if(isset($u['query']) && $u['query'] != ''){ + $this->path .= '?' . $u['query']; + } + + // set default port + if(!isset($u['port'])){ + if($u['scheme'] == 'https'){ + $this->port = 443; + } else { + $this->port = 80; + } + } + + $this->uri = $this->path; + $this->digest_uri = $this->uri; + + // build headers + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + $this->debug('set Host: ' . $this->outgoing_headers['Host']); + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); + } + } + + function connect($connection_timeout=0,$response_timeout=30){ + // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like + // "regular" socket. + // TODO: disabled for now because OpenSSL must be *compiled* in (not just + // loaded), and until PHP5 stream_get_wrappers is not available. +// if ($this->scheme == 'https') { +// if (version_compare(phpversion(), '4.3.0') >= 0) { +// if (extension_loaded('openssl')) { +// $this->scheme = 'ssl'; +// $this->debug('Using SSL over OpenSSL'); +// } +// } +// } + $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // use persistent connection + if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ + if (!feof($this->fp)) { + $this->debug('Re-use persistent connection'); + return true; + } + fclose($this->fp); + $this->debug('Closed persistent connection at EOF'); + } + + // munge host if using OpenSSL + if ($this->scheme == 'ssl') { + $host = 'ssl://' . $this->host; + } else { + $host = $this->host; + } + $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); + + // open socket + if($connection_timeout > 0){ + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); + } else { + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); + } + + // test pointer + if(!$this->fp) { + $msg = 'Couldn\'t open socket connection to server ' . $this->url; + if ($this->errno) { + $msg .= ', Error ('.$this->errno.'): '.$this->error_str; + } else { + $msg .= ' prior to connect(). This is often a problem looking up the host name.'; + } + $this->debug($msg); + $this->setError($msg); + return false; + } + + // set response timeout + $this->debug('set response timeout to ' . $response_timeout); + socket_set_timeout( $this->fp, $response_timeout); + + $this->debug('socket connected'); + return true; + } else if ($this->scheme == 'https') { + if (!extension_loaded('curl')) { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + return false; + } + $this->debug('connect using https'); + // init CURL + $this->ch = curl_init(); + // set url + $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; + // add path + $hostURL .= $this->path; + curl_setopt($this->ch, CURLOPT_URL, $hostURL); + // follow location headers (re-directs) + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); + // ask for headers in the response output + curl_setopt($this->ch, CURLOPT_HEADER, 1); + // ask for the response output as the return value + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + // encode + // We manage this ourselves through headers and encoding +// if(function_exists('gzuncompress')){ +// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); +// } + // persistent connection + if ($this->persistentConnection) { + // The way we send data, we cannot use persistent connections, since + // there will be some "junk" at the end of our request. + //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); + $this->persistentConnection = false; + $this->outgoing_headers['Connection'] = 'close'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + // set timeout + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); + } + // TODO: cURL has added a connection timeout separate from the response timeout + //if ($connection_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); + //} + //if ($response_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); + //} + + // recent versions of cURL turn on peer/host checking by default, + // while PHP binaries are not compiled with a default location for the + // CA cert bundle, so disable peer/host checking. +//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); + + // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) + if ($this->authtype == 'certificate') { + if (isset($this->certRequest['cainfofile'])) { + curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); + } + if (isset($this->certRequest['verifypeer'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + } + if (isset($this->certRequest['verifyhost'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + } + if (isset($this->certRequest['sslcertfile'])) { + curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); + } + if (isset($this->certRequest['sslkeyfile'])) { + curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); + } + if (isset($this->certRequest['passphrase'])) { + curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); + } + } + $this->debug('cURL connection set up'); + return true; + } else { + $this->setError('Unknown scheme ' . $this->scheme); + $this->debug('Unknown scheme ' . $this->scheme); + return false; + } + } + + /** + * send the SOAP message via HTTP + * + * @param string $data message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { + + $this->debug('entered send() with data of length: '.strlen($data)); + + $this->tryagain = true; + $tries = 0; + while ($this->tryagain) { + $this->tryagain = false; + if ($tries++ < 2) { + // make connnection + if (!$this->connect($timeout, $response_timeout)){ + return false; + } + + // send request + if (!$this->sendRequest($data, $cookies)){ + return false; + } + + // get response + $respdata = $this->getResponse(); + } else { + $this->setError('Too many tries to get an OK response'); + } + } + $this->debug('end of send()'); + return $respdata; + } + + + /** + * send the SOAP message via HTTPS 1.0 using CURL + * + * @param string $msg message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { + return $this->send($data, $timeout, $response_timeout, $cookies); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic, digest, certificate) + * @param array $digestRequest (keys must be nonce, nc, realm, qop) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); + } elseif ($authtype == 'digest') { + if (isset($digestRequest['nonce'])) { + $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; + + // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) + + // A1 = unq(username-value) ":" unq(realm-value) ":" passwd + $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->digest_uri; + + // H(A2) + $HA2 = md5($A2); + + // KD(secret, data) = H(concat(secret, ":", data)) + // if qop == auth: + // request-digest = <"> < KD ( H(A1), unq(nonce-value) + // ":" nc-value + // ":" unq(cnonce-value) + // ":" unq(qop-value) + // ":" H(A2) + // ) <"> + // if qop is missing, + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> + + $unhashedDigest = ''; + $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; + $cnonce = $nonce; + if ($digestRequest['qop'] != '') { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; + } else { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; + } + + $hashedDigest = md5($unhashedDigest); + + $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } elseif ($authtype == 'certificate') { + $this->certRequest = $certRequest; + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); + } else { + $this->debug('Authorization header not set'); + } + } + + /** + * set the soapaction value + * + * @param string $soapaction + * @access public + */ + function setSOAPAction($soapaction) { + $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; + $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate') { + if (function_exists('gzdeflate')) { + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); + if (!isset($this->outgoing_headers['Connection'])) { + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + set_magic_quotes_runtime(0); + // deprecated + $this->encoding = $enc; + } + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->uri = $this->url; + $this->host = $proxyhost; + $this->port = $proxyport; + if ($proxyusername != '' && $proxypassword != '') { + $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); + $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); + } + } + + /** + * decode a string that is encoded w/ "chunked' transfer encoding + * as defined in RFC2068 19.4.6 + * + * @param string $buffer + * @param string $lb + * @returns string + * @access public + * @deprecated + */ + function decodeChunked($buffer, $lb){ + // length := 0 + $length = 0; + $new = ''; + + // read chunk-size, chunk-extension (if any) and CRLF + // get the position of the linebreak + $chunkend = strpos($buffer, $lb); + if ($chunkend == FALSE) { + $this->debug('no linebreak found in decodeChunked'); + return $new; + } + $temp = substr($buffer,0,$chunkend); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend + strlen($lb); + // while (chunk-size > 0) { + while ($chunk_size > 0) { + $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); + $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); + + // Just in case we got a broken connection + if ($chunkend == FALSE) { + $chunk = substr($buffer,$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + $length += strlen($chunk); + break; + } + + // read chunk-data and CRLF + $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + // length := length + chunk-size + $length += strlen($chunk); + // read chunk-size and CRLF + $chunkstart = $chunkend + strlen($lb); + + $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); + if ($chunkend == FALSE) { + break; //Just in case we got a broken connection + } + $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend; + } + return $new; + } + + /* + * Writes payload, including HTTP headers, to $this->outgoing_payload. + */ + function buildPayload($data, $cookie_str = '') { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); + + // start building outgoing payload: + $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; + $this->debug("HTTP request: $req"); + $this->outgoing_payload = "$req\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $hdr = $k.': '.$v; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // add any cookies + if ($cookie_str != '') { + $hdr = 'Cookie: '.$cookie_str; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data, $cookies = NULL) { + // build cookie string + $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); + + // build payload + $this->buildPayload($data, $cookie_str); + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // send payload + if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + $this->setError('couldn\'t write message data to socket'); + $this->debug('couldn\'t write message data to socket'); + return false; + } + $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); + return true; + } else if ($this->scheme == 'https') { + // set payload + // TODO: cURL does say this should only be the verb, and in fact it + // turns out that the URI and HTTP version are appended to this, which + // some servers refuse to work with + //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); + foreach($this->outgoing_headers as $k => $v){ + $curl_headers[] = "$k: $v"; + } + if ($cookie_str != '') { + $curl_headers[] = 'Cookie: ' . $cookie_str; + } + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); + if ($this->request_method == "POST") { + curl_setopt($this->ch, CURLOPT_POST, 1); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); + } else { + } + $this->debug('set cURL payload'); + return true; + } + } + + function getResponse(){ + $this->incoming_payload = ''; + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // loop until headers have been retrieved + $data = ''; + while (!isset($lb)){ + + // We might EOF during header read. + if(feof($this->fp)) { + $this->incoming_payload = $data; + $this->debug('found no headers before EOF after length ' . strlen($data)); + $this->debug("received before EOF:\n" . $data); + $this->setError('server failed to send headers'); + return false; + } + + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read line of $tmplen bytes: " . trim($tmp)); + + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of headers timed out after length ' . strlen($data)); + $this->debug("read before timeout: " . $data); + $this->setError('socket read of headers timed out'); + return false; + } + + $data .= $tmp; + $pos = strpos($data,"\r\n\r\n"); + if($pos > 1){ + $lb = "\r\n"; + } else { + $pos = strpos($data,"\n\n"); + if($pos > 1){ + $lb = "\n"; + } + } + // remove 100 header + if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ + unset($lb); + $data = ''; + }// + } + // store header data + $this->incoming_payload .= $data; + $this->debug('found end of headers after length ' . strlen($data)); + // process headers + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $this->incoming_headers = array(); + $this->incoming_cookies = array(); + foreach($header_array as $header_line){ + $arr = explode(':',$header_line, 2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $content_length = 2147483647; // ignore any content-length header + $chunked = true; + $this->debug("want to read chunked content"); + } elseif (isset($this->incoming_headers['content-length'])) { + $content_length = $this->incoming_headers['content-length']; + $chunked = false; + $this->debug("want to read content of length $content_length"); + } else { + $content_length = 2147483647; + $chunked = false; + $this->debug("want to read content to EOF"); + } + $data = ''; + do { + if ($chunked) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk line of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk length timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk length timed out'); + return false; + } + $content_length = hexdec(trim($tmp)); + $this->debug("chunk length $content_length"); + } + $strlen = 0; + while (($strlen < $content_length) && (!feof($this->fp))) { + $readlen = min(8192, $content_length - $strlen); + $tmp = fread($this->fp, $readlen); + $tmplen = strlen($tmp); + $this->debug("read buffer of $tmplen bytes"); + if (($tmplen == 0) && (!feof($this->fp))) { + $this->incoming_payload = $data; + $this->debug('socket read of body timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of body timed out'); + return false; + } + $strlen += $tmplen; + $data .= $tmp; + } + if ($chunked && ($content_length > 0)) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk terminator of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk terminator timed out'); + return false; + } + } + } while ($chunked && ($content_length > 0) && (!feof($this->fp))); + if (feof($this->fp)) { + $this->debug('read to EOF'); + } + $this->debug('read body of length ' . strlen($data)); + $this->incoming_payload .= $data; + $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); + + // close filepointer + if( + (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || + (! $this->persistentConnection) || feof($this->fp)){ + fclose($this->fp); + $this->fp = false; + $this->debug('closed socket'); + } + + // connection was closed unexpectedly + if($this->incoming_payload == ''){ + $this->setError('no response from server'); + return false; + } + + // decode transfer-encoding +// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ +// if(!$data = $this->decodeChunked($data, $lb)){ +// $this->setError('Decoding of chunked data failed'); +// return false; +// } + //print "
    \nde-chunked:\n---------------\n$data\n\n---------------\n
    "; + // set decoded payload +// $this->incoming_payload = $header_data.$lb.$lb.$data; +// } + + } else if ($this->scheme == 'https') { + // send and receive + $this->debug('send and receive with cURL'); + $this->incoming_payload = curl_exec($this->ch); + $data = $this->incoming_payload; + + $cErr = curl_error($this->ch); + if ($cErr != '') { + $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'
    '; + // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v
    "; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '
    ';
    +			//var_dump(curl_getinfo($this->ch));
    +			//echo '
    '; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header(s) + while (ereg('^HTTP/1.1 100',$data)) { + if ($pos = strpos($data,"\r\n\r\n")) { + $data = ltrim(substr($data,$pos)); + } elseif($pos = strpos($data,"\n\n") ) { + $data = ltrim(substr($data,$pos)); + } + } + + // separate content from HTTP headers + if ($pos = strpos($data,"\r\n\r\n")) { + $lb = "\r\n"; + } elseif( $pos = strpos($data,"\n\n")) { + $lb = "\n"; + } else { + $this->debug('no proper separation of headers and document'); + $this->setError('no proper separation of headers and document'); + return false; + } + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $data = ltrim(substr($data,$pos)); + $this->debug('found proper separation of headers and document'); + $this->debug('cleaned data, stringlen: '.strlen($data)); + // clean headers + foreach ($header_array as $header_line) { + $arr = explode(':',$header_line,2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + } + + $arr = explode(' ', $header_array[0], 3); + $http_version = $arr[0]; + $http_status = intval($arr[1]); + $http_reason = count($arr) > 2 ? $arr[2] : ''; + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['location']) && $http_status == 301) { + $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); + $this->setURL($this->incoming_headers['location']); + $this->tryagain = true; + return false; + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { + $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); + if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { + $this->debug('Server wants digest authentication'); + // remove "Digest " from our elements + $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); + + // parse elements into array + $digestElements = explode(',', $digestString); + foreach ($digestElements as $val) { + $tempElement = explode('=', trim($val), 2); + $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); + } + + // should have (at least) qop, realm, nonce + if (isset($digestRequest['nonce'])) { + $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); + $this->tryagain = true; + return false; + } + } + $this->debug('HTTP authentication failed'); + $this->setError('HTTP authentication failed'); + return false; + } + + if ( + ($http_status >= 300 && $http_status <= 307) || + ($http_status >= 400 && $http_status <= 417) || + ($http_status >= 501 && $http_status <= 505) + ) { + $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); + return false; + } + + // decode content-encoding + if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ + if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ + // if decoding works, use it. else assume data wasn't gzencoded + if(function_exists('gzinflate')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) + // this means there are no Zlib headers, although there should be + $this->debug('The gzinflate function exists'); + $datalen = strlen($data); + if ($this->incoming_headers['content-encoding'] == 'deflate') { + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The inflated payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to inflate the payload'); + $this->setError('Error using gzinflate to inflate the payload'); + } + } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { + if ($degzdata = @gzinflate(substr($data, 10))) { // do our best + $data = $degzdata; + $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to un-gzip the payload'); + $this->setError('Error using gzinflate to un-gzip the payload'); + } + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "\nde-inflated:\n---------------\n$data\n-------------\n"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + } + } else { + $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + } + } else { + $this->debug('No Content-Encoding header'); + } + + if(strlen($data) == 0){ + $this->debug('no data after headers!'); + $this->setError('no data present after HTTP headers'); + return false; + } + + return $data; + } + + function setContentType($type, $charset = false) { + $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); + $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); + } + + function usePersistentConnection(){ + if (isset($this->outgoing_headers['Accept-Encoding'])) { + return false; + } + $this->protocol_version = '1.1'; + $this->persistentConnection = true; + $this->outgoing_headers['Connection'] = 'Keep-Alive'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + return true; + } + + /** + * parse an incoming Cookie into it's parts + * + * @param string $cookie_str content of cookie + * @return array with data of that cookie + * @access private + */ + /* + * TODO: allow a Set-Cookie string to be parsed into multiple cookies + */ + function parseCookie($cookie_str) { + $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; + $data = split(';', $cookie_str); + $value_str = $data[0]; + + $cookie_param = 'domain='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $domain = substr($cookie_str, $start + strlen($cookie_param)); + $domain = substr($domain, 0, strpos($domain, ';')); + } else { + $domain = ''; + } + + $cookie_param = 'expires='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $expires = substr($cookie_str, $start + strlen($cookie_param)); + $expires = substr($expires, 0, strpos($expires, ';')); + } else { + $expires = ''; + } + + $cookie_param = 'path='; + $start = strpos($cookie_str, $cookie_param); + if ( $start > 0 ) { + $path = substr($cookie_str, $start + strlen($cookie_param)); + $path = substr($path, 0, strpos($path, ';')); + } else { + $path = '/'; + } + + $cookie_param = ';secure;'; + if (strpos($cookie_str, $cookie_param) !== FALSE) { + $secure = true; + } else { + $secure = false; + } + + $sep_pos = strpos($value_str, '='); + + if ($sep_pos) { + $name = substr($value_str, 0, $sep_pos); + $value = substr($value_str, $sep_pos + 1); + $cookie= array( 'name' => $name, + 'value' => $value, + 'domain' => $domain, + 'path' => $path, + 'expires' => $expires, + 'secure' => $secure + ); + return $cookie; + } + return false; + } + + /** + * sort out cookies for the current request + * + * @param array $cookies array with all cookies + * @param boolean $secure is the send-content secure or not? + * @return string for Cookie-HTTP-Header + * @access private + */ + function getCookiesForRequest($cookies, $secure=false) { + $cookie_str = ''; + if ((! is_null($cookies)) && (is_array($cookies))) { + foreach ($cookies as $cookie) { + if (! is_array($cookie)) { + continue; + } + $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) <= time()) { + $this->debug('cookie has expired'); + continue; + } + } + if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { + $domain = preg_quote($cookie['domain']); + if (! preg_match("'.*$domain$'i", $this->host)) { + $this->debug('cookie has different domain'); + continue; + } + } + if ((isset($cookie['path'])) && (! empty($cookie['path']))) { + $path = preg_quote($cookie['path']); + if (! preg_match("'^$path.*'i", $this->path)) { + $this->debug('cookie is for a different path'); + continue; + } + } + if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { + $this->debug('cookie is secure, transport is not'); + continue; + } + $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; + $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); + } + } + return $cookie_str; + } +} + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soap_val.php b/gulliver/thirdparty/pear/class.soap_val.php new file mode 100644 index 000000000..c3618eb08 --- /dev/null +++ b/gulliver/thirdparty/pear/class.soap_val.php @@ -0,0 +1,107 @@ + +* @version $Id: class.soap_val.php,v 1.9 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class soapval extends nusoap_base { + /** + * The XML element name + * + * @var string + * @access private + */ + var $name; + /** + * The XML type name (string or false) + * + * @var mixed + * @access private + */ + var $type; + /** + * The PHP value + * + * @var mixed + * @access private + */ + var $value; + /** + * The XML element namespace (string or false) + * + * @var mixed + * @access private + */ + var $element_ns; + /** + * The XML type namespace (string or false) + * + * @var mixed + * @access private + */ + var $type_ns; + /** + * The XML element attributes (array or false) + * + * @var mixed + * @access private + */ + var $attributes; + + /** + * constructor + * + * @param string $name optional name + * @param mixed $type optional type name + * @param mixed $value optional value + * @param mixed $element_ns optional namespace of value + * @param mixed $type_ns optional namespace of type + * @param mixed $attributes associative array of attributes to add to element serialization + * @access public + */ + function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { + parent::nusoap_base(); + $this->name = $name; + $this->type = $type; + $this->value = $value; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @param string $use The WSDL use value (encoded|literal) + * @return string XML data + * @access public + */ + function serialize($use='encoded') { + return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); + } + + /** + * decodes a soapval object into a PHP native type + * + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.soapclient.php b/gulliver/thirdparty/pear/class.soapclient.php new file mode 100644 index 000000000..55979d2ae --- /dev/null +++ b/gulliver/thirdparty/pear/class.soapclient.php @@ -0,0 +1,859 @@ +call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient); +* +* @author Dietrich Ayala +* @version $Id: class.soapclient.php,v 1.52 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class soapclient extends nusoap_base { + + var $username = ''; + var $password = ''; + var $authtype = ''; + var $certRequest = array(); + var $requestHeaders = false; // SOAP headers in request (text) + var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) + var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) + var $endpoint; + var $forceEndpoint = ''; // overrides WSDL endpoint + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $xml_encoding = ''; // character set encoding of incoming (response) messages + var $http_encoding = false; + var $timeout = 0; // HTTP connection timeout + var $response_timeout = 30; // HTTP response timeout + var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error + var $persistentConnection = false; + var $defaultRpcParams = false; // This is no longer used + var $request = ''; // HTTP request + var $response = ''; // HTTP response + var $responseData = ''; // SOAP payload of response + var $cookies = array(); // Cookies from response or for request + var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() + var $operations = array(); // WSDL operations, empty for WSDL initialization error + + /* + * fault related variables + */ + /** + * @var fault + * @access public + */ + var $fault; + /** + * @var faultcode + * @access public + */ + var $faultcode; + /** + * @var faultstring + * @access public + */ + var $faultstring; + /** + * @var faultdetail + * @access public + */ + var $faultdetail; + + /** + * constructor + * + * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) + * @param bool $wsdl optional, set to true if using WSDL + * @param int $portName optional portName in WSDL document + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + parent::nusoap_base(); + $this->endpoint = $endpoint; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // make values + if($wsdl){ + if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { + $this->wsdl = $endpoint; + $this->endpoint = $this->wsdl->wsdl; + $this->wsdlFile = $this->endpoint; + $this->debug('existing wsdl instance created from ' . $this->endpoint); + } else { + $this->wsdlFile = $this->endpoint; + + // instantiate wsdl object and parse wsdl file + $this->debug('instantiating wsdl class with doc: '.$endpoint); + $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + // catch errors + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + } elseif($this->operations = $this->wsdl->getOperations()){ + $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); + $this->endpointType = 'wsdl'; + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } else { + $this->debug("instantiate SOAP with endpoint at $endpoint"); + $this->endpointType = 'soap'; + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param mixed $params An array, associative or simple, of the parameters + * for the method call, or a string that is the XML + * for the call. For rpc style, this call will + * wrap the XML in a tag named after the method, as + * well as the SOAP Envelope and Body. For document + * style, this will only wrap with the Envelope and Body. + * IMPORTANT: when using an array with document style, + * in which case there + * is really one parameter, the root of the fragment + * used in the call, which encloses what programmers + * normally think of parameters. A parameter array + * *must* include the wrapper. + * @param string $namespace optional method namespace (WSDL can override) + * @param string $soapAction optional SOAPAction value (WSDL can override) + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param boolean $rpcParams optional (no longer used) + * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) + * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) + * @return mixed response from SOAP call + * @access public + */ + function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->setError(''); + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); + $this->appendDebug('params=' . $this->varDump($params)); + $this->appendDebug('headers=' . $this->varDump($headers)); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + $this->debug("found operation"); + $this->appendDebug('opData=' . $this->varDump($opData)); + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + if (! $this->forceEndpoint) { + $this->endpoint = $opData['endpoint']; + } else { + $this->endpoint = $this->forceEndpoint; + } + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $nsPrefix = 'ns' . rand(1000, 9999); + $this->wsdl->namespaces[$nsPrefix] = $namespace; + } + $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); + // serialize payload + if (is_string($params)) { + $this->debug("serializing param string for WSDL operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for WSDL operation $operation"); + $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = $this->wsdl->usedNamespaces; + if (isset($opData['input']['encodingStyle'])) { + $encodingStyle = $opData['input']['encodingStyle']; + } else { + $encodingStyle = ''; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if ($errstr = $this->wsdl->getError()) { + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + return false; + } + } elseif($this->endpointType == 'wsdl') { + // operation not in WSDL + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + $this->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + return false; + } else { + // no WSDL + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns' . rand(1000, 9999); + // serialize + $payload = ''; + if (is_string($params)) { + $this->debug("serializing param string for operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for operation $operation"); + foreach($params as $k => $v){ + $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = array(); + if ($use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + if ($namespace) { + $payload = "<$operation xmlns=\"$namespace\">" . $payload . ""; + } else { + $payload = "<$operation>" . $payload . ""; + } + } else { + $this->debug("wrapping RPC request with encoded method element"); + if ($namespace) { + $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . + $payload . + ""; + } else { + $payload = "<$operation>" . + $payload . + ""; + } + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); + $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); + $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); + // send + $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); + if($errstr = $this->getError()){ + $this->debug('Error: '.$errstr); + return false; + } else { + $this->return = $return; + $this->debug('sent message successfully and got a(n) '.gettype($return)); + $this->appendDebug('return=' . $this->varDump($return)); + + // fault? + if(is_array($return) && isset($return['faultcode'])){ + $this->debug('got fault'); + $this->setError($return['faultcode'].': '.$return['faultstring']); + $this->fault = true; + foreach($return as $k => $v){ + $this->$k = $v; + $this->debug("$k = $v
    "); + } + return $return; + } elseif ($style == 'document') { + // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), + // we are only going to return the first part here...sorry about that + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters, which we return wrapped up + // in the array + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter (normally the return value) + $return = array_shift($return); + $this->debug('return shifted value: '); + $this->appendDebug($this->varDump($return)); + return $return; + // nothing returned (ie, echoVoid) + } else { + return ""; + } + } + } + } + + /** + * get available data pertaining to an operation + * + * @param string $operation operation name + * @return array array of data pertaining to the operation + * @access public + */ + function getOperationData($operation){ + if(isset($this->operations[$operation])){ + return $this->operations[$operation]; + } + $this->debug("No data for operation: $operation"); + } + + /** + * send the SOAP message + * + * Note: if the operation has multiple return values + * the return value of this method will be an array + * of those values. + * + * @param string $msg a SOAPx4 soapmsg object + * @param string $soapaction SOAPAction value + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @return mixed native PHP types. + * @access private + */ + function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { + $this->checkCookies(); + // detect transport + switch(true){ + // http(s) + case ereg('^http',$this->endpoint): + $this->debug('transporting via HTTP'); + if($this->persistentConnection == true && is_object($this->persistentConnection)){ + $http =& $this->persistentConnection; + } else { + $http = new soap_transport_http($this->endpoint); + if ($this->persistentConnection) { + $http->usePersistentConnection(); + } + } + $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); + $http->setSOAPAction($soapaction); + if($this->proxyhost && $this->proxyport){ + $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + if($this->authtype != '') { + $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); + } + if($this->http_encoding != ''){ + $http->setEncoding($this->http_encoding); + } + $this->debug('sending message, length='.strlen($msg)); + if(ereg('^http:',$this->endpoint)){ + //if(strpos($this->endpoint,'http:')){ + $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); + } elseif(ereg('^https',$this->endpoint)){ + //} elseif(strpos($this->endpoint,'https:')){ + //if(phpversion() == '4.3.0-dev'){ + //$response = $http->send($msg,$timeout,$response_timeout); + //$this->request = $http->outgoing_payload; + //$this->response = $http->incoming_payload; + //} else + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->appendDebug($http->getDebug()); + $this->UpdateCookies($http->incoming_cookies); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->clearDebug(); + if (!is_object($this->persistentConnection)) { + $this->persistentConnection = $http; + } + } + + if($err = $http->getError()){ + $this->setError('HTTP Error: '.$err); + return false; + } elseif($this->getError()){ + return false; + } else { + $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); + return $this->parseResponse($http->incoming_headers, $this->responseData); + } + break; + default: + $this->setError('no transport found, or selected transport is not yet supported!'); + return false; + break; + } + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Response not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); + // add parser debug data to our debug + $this->appendDebug($parser->getDebug()); + // if parse errors + if($errstr = $parser->getError()){ + $this->setError( $errstr); + // destroy the parser object + unset($parser); + return false; + } else { + // get SOAP headers + $this->responseHeaders = $parser->getHeaders(); + // get decoded message + $return = $parser->get_response(); + // add document for doclit support + $this->document = $parser->document; + // destroy the parser object + unset($parser); + // return decode message + return $return; + } + } + + /** + * sets the SOAP endpoint, which can override WSDL + * + * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override + * @access public + */ + function setEndpoint($endpoint) { + $this->forceEndpoint = $endpoint; + } + + /** + * set the SOAP headers + * + * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the SOAP response headers (namespace resolution incomplete) + * + * @return string + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic|digest|certificate) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->certRequest = $certRequest; + } + + /** + * use HTTP encoding + * + * @param string $enc + * @access public + */ + function setHTTPEncoding($enc='gzip, deflate'){ + $this->http_encoding = $enc; + } + + /** + * use HTTP persistent connections if possible + * + * @access public + */ + function useHTTPPersistentConnection(){ + $this->persistentConnection = true; + } + + /** + * gets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style. + * Each call() can override this value. + * + * This is no longer used. + * + * @return boolean + * @access public + * @deprecated + */ + function getDefaultRpcParams() { + return $this->defaultRpcParams; + } + + /** + * sets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style + * Each call() can override this value. + * + * This is no longer used. + * + * @param boolean $rpcParams + * @access public + * @deprecated + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates an instance of a proxy class, + * allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $r = rand(); + $evalStr = $this->_getProxyClassCode($r); + //$this->debug("proxy class: $evalStr"; + // eval the class + eval($evalStr); + // instantiate proxy object + eval("\$proxy = new soap_proxy_$r('');"); + // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice + $proxy->endpointType = 'wsdl'; + $proxy->wsdlFile = $this->wsdlFile; + $proxy->wsdl = $this->wsdl; + $proxy->operations = $this->operations; + $proxy->defaultRpcParams = $this->defaultRpcParams; + // transfer other state + $proxy->username = $this->username; + $proxy->password = $this->password; + $proxy->authtype = $this->authtype; + $proxy->proxyhost = $this->proxyhost; + $proxy->proxyport = $this->proxyport; + $proxy->proxyusername = $this->proxyusername; + $proxy->proxypassword = $this->proxypassword; + $proxy->timeout = $this->timeout; + $proxy->response_timeout = $this->response_timeout; + $proxy->http_encoding = $this->http_encoding; + $proxy->persistentConnection = $this->persistentConnection; + $proxy->requestHeaders = $this->requestHeaders; + $proxy->soap_defencoding = $this->soap_defencoding; + $proxy->endpoint = $this->endpoint; + $proxy->forceEndpoint = $this->forceEndpoint; + return $proxy; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access private + */ + function _getProxyClassCode($r) { + if ($this->endpointType != 'wsdl') { + $evalStr = 'A proxy can only be created for a WSDL client'; + $this->setError($evalStr); + return $evalStr; + } + $evalStr = ''; + foreach ($this->operations as $operation => $opData) { + if ($operation != '') { + // create param string and param comment string + if (sizeof($opData['input']['parts']) > 0) { + $paramStr = ''; + $paramArrayStr = ''; + $paramCommentStr = ''; + foreach ($opData['input']['parts'] as $name => $type) { + $paramStr .= "\$$name, "; + $paramArrayStr .= "'$name' => \$$name, "; + $paramCommentStr .= "$type \$$name, "; + } + $paramStr = substr($paramStr, 0, strlen($paramStr)-2); + $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); + $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); + } else { + $paramStr = ''; + $paramCommentStr = 'void'; + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "// $paramCommentStr + function " . str_replace('.', '__', $operation) . "($paramStr) { + \$params = array($paramArrayStr); + return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + } + "; + unset($paramStr); + unset($paramCommentStr); + } + } + $evalStr = 'class soap_proxy_'.$r.' extends soapclient { + '.$evalStr.' +}'; + return $evalStr; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access public + */ + function getProxyClassCode() { + $r = rand(); + return $this->_getProxyClassCode($r); + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /* + * whether or not parser should decode utf8 element content + * + * @return always returns true + * @access public + */ + function decodeUTF8($bool){ + $this->decode_utf8 = $bool; + return true; + } + + /** + * adds a new Cookie into $this->cookies array + * + * @param string $name Cookie Name + * @param string $value Cookie Value + * @return if cookie-set was successful returns true, else false + * @access public + */ + function setCookie($name, $value) { + if (strlen($name) == 0) { + return false; + } + $this->cookies[] = array('name' => $name, 'value' => $value); + return true; + } + + /** + * gets all Cookies + * + * @return array with all internal cookies + * @access public + */ + function getCookies() { + return $this->cookies; + } + + /** + * checks all Cookies and delete those which are expired + * + * @return always return true + * @access private + */ + function checkCookies() { + if (sizeof($this->cookies) == 0) { + return true; + } + $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); + $curr_cookies = $this->cookies; + $this->cookies = array(); + foreach ($curr_cookies as $cookie) { + if (! is_array($cookie)) { + $this->debug('Remove cookie that is not an array'); + continue; + } + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) > time()) { + $this->cookies[] = $cookie; + } else { + $this->debug('Remove expired cookie ' . $cookie['name']); + } + } else { + $this->cookies[] = $cookie; + } + } + $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); + return true; + } + + /** + * updates the current cookies with a new set + * + * @param array $cookies new cookies with which to update current ones + * @return always return true + * @access private + */ + function UpdateCookies($cookies) { + if (sizeof($this->cookies) == 0) { + // no existing cookies: take whatever is new + if (sizeof($cookies) > 0) { + $this->debug('Setting new cookie(s)'); + $this->cookies = $cookies; + } + return true; + } + if (sizeof($cookies) == 0) { + // no new cookies: keep what we've got + return true; + } + // merge + foreach ($cookies as $newCookie) { + if (!is_array($newCookie)) { + continue; + } + if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { + continue; + } + $newName = $newCookie['name']; + + $found = false; + for ($i = 0; $i < count($this->cookies); $i++) { + $cookie = $this->cookies[$i]; + if (!is_array($cookie)) { + continue; + } + if (!isset($cookie['name'])) { + continue; + } + if ($newName != $cookie['name']) { + continue; + } + $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; + $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; + if ($newDomain != $domain) { + continue; + } + $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; + $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; + if ($newPath != $path) { + continue; + } + $this->cookies[$i] = $newCookie; + $found = true; + $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); + break; + } + if (! $found) { + $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); + $this->cookies[] = $newCookie; + } + } + return true; + } +} +?> diff --git a/gulliver/thirdparty/pear/class.wsdl.php b/gulliver/thirdparty/pear/class.wsdl.php new file mode 100644 index 000000000..0d4100927 --- /dev/null +++ b/gulliver/thirdparty/pear/class.wsdl.php @@ -0,0 +1,1727 @@ + +* @version $Id: class.wsdl.php,v 1.56 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class wsdl extends nusoap_base { + // URL or filename of the root of this WSDL + var $wsdl; + // define internal arrays of bindings, ports, operations, messages, etc. + var $schemas = array(); + var $currentSchema; + var $message = array(); + var $complexTypes = array(); + var $messages = array(); + var $currentMessage; + var $currentOperation; + var $portTypes = array(); + var $currentPortType; + var $bindings = array(); + var $currentBinding; + var $ports = array(); + var $currentPort; + var $opData = array(); + var $status = ''; + var $documentation = false; + var $endpoint = ''; + // array of wsdl docs to import + var $import = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + // for getting wsdl + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $timeout = 0; + var $response_timeout = 30; + + /** + * constructor + * + * @param string $wsdl WSDL document URL + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ + parent::nusoap_base(); + $this->wsdl = $wsdl; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // parse wsdl file + if ($wsdl != "") { + $this->debug('initial wsdl URL: ' . $wsdl); + $this->parseWSDL($wsdl); + } + // imports + // TODO: handle imports more properly, grabbing them in-line and nesting them + $imported_urls = array(); + $imported = 1; + while ($imported > 0) { + $imported = 0; + // Schema imports + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($xs->imports as $ns2 => $list2) { + for ($ii = 0; $ii < count($list2); $ii++) { + if (! $list2[$ii]['loaded']) { + $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; + $url = $list2[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + } + // WSDL imports + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($this->import as $ns => $list) { + for ($ii = 0; $ii < count($list); $ii++) { + if (! $list[$ii]['loaded']) { + $this->import[$ns][$ii]['loaded'] = true; + $url = $list[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + // add new data to operation data + foreach($this->bindings as $binding => $bindingData) { + if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { + foreach($bindingData['operations'] as $operation => $data) { + $this->debug('post-parse data gathering for ' . $operation); + $this->bindings[$binding]['operations'][$operation]['input'] = + isset($this->bindings[$binding]['operations'][$operation]['input']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['input']; + $this->bindings[$binding]['operations'][$operation]['output'] = + isset($this->bindings[$binding]['operations'][$operation]['output']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['output']; + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; + } + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; + } + if (isset($bindingData['style'])) { + $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; + } + $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; + $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; + $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; + } + } + } + } + + /** + * parses the wsdl document + * + * @param string $wsdl path or URL + * @access private + */ + function parseWSDL($wsdl = '') + { + if ($wsdl == '') { + $this->debug('no wsdl passed to parseWSDL()!!'); + $this->setError('no wsdl passed to parseWSDL()!!'); + return false; + } + + // parse $wsdl for url format + $wsdl_props = parse_url($wsdl); + + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { + $this->debug('getting WSDL http(s) URL ' . $wsdl); + // get wsdl + $tr = new soap_transport_http($wsdl); + $tr->request_method = 'GET'; + $tr->useSOAPAction = false; + if($this->proxyhost && $this->proxyport){ + $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + $tr->setEncoding('gzip, deflate'); + $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); + //$this->debug("WSDL request\n" . $tr->outgoing_payload); + //$this->debug("WSDL response\n" . $tr->incoming_payload); + $this->appendDebug($tr->getDebug()); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + $this->debug("got WSDL URL"); + } else { + // $wsdl is not http(s), so treat it as a file URL or plain file path + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { + $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; + } else { + $path = $wsdl; + } + $this->debug('getting WSDL file ' . $path); + if ($fp = @fopen($path, 'r')) { + $wsdl_string = ''; + while ($data = fread($fp, 32768)) { + $wsdl_string .= $data; + } + fclose($fp); + } else { + $errstr = "Bad path to WSDL file $path"; + $this->debug($errstr); + $this->setError($errstr); + return false; + } + } + $this->debug('Parse WSDL'); + // end new code added + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element', 'end_element'); + xml_set_character_data_handler($this->parser, 'character_data'); + // Parse the XML file. + if (!xml_parse($this->parser, $wsdl_string, true)) { + // Display an error message. + $errstr = sprintf( + 'XML error parsing WSDL from %s on line %d: %s', + $wsdl, + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $wsdl_string); + $this->setError($errstr); + return false; + } + // free the parser + xml_parser_free($this->parser); + $this->debug('Parsing WSDL done'); + // catch wsdl parse errors + if($this->getError()){ + return false; + } + return true; + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) + { + if ($this->status == 'schema') { + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } elseif (ereg('schema$', $name)) { + $this->debug('Parsing WSDL schema'); + // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); + $this->status = 'schema'; + $this->currentSchema = new xmlschema('', '', $this->namespaces); + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } else { + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + // process attributes + if (count($attrs) > 0) { + // register namespace declarations + foreach($attrs as $k => $v) { + if (ereg("^xmlns", $k)) { + if ($ns_prefix = substr(strrchr($k, ':'), 1)) { + $this->namespaces[$ns_prefix] = $v; + } else { + $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; + } + if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } + } + // expand each attribute prefix to its namespace + foreach($attrs as $k => $v) { + $k = strpos($k, ':') ? $this->expandQname($k) : $k; + if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { + $v = strpos($v, ':') ? $this->expandQname($v) : $v; + } + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // get element prefix, namespace and name + if (ereg(':', $name)) { + // get ns prefix + $prefix = substr($name, 0, strpos($name, ':')); + // get ns + $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; + // get unqualified name + $name = substr(strstr($name, ':'), 1); + } + // process attributes, expanding any prefixes to namespaces + // find status, register data + switch ($this->status) { + case 'message': + if ($name == 'part') { + if (isset($attrs['type'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; + } + if (isset($attrs['element'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; + } + } + break; + case 'portType': + switch ($name) { + case 'operation': + $this->currentPortOperation = $attrs['name']; + $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); + if (isset($attrs['parameterOrder'])) { + $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; + } + break; + case 'documentation': + $this->documentation = true; + break; + // merge input/output data + default: + $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; + $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; + break; + } + break; + case 'binding': + switch ($name) { + case 'binding': + // get ns prefix + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['prefix'] = $prefix; + } + $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); + break; + case 'header': + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + case 'operation': + if (isset($attrs['soapAction'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; + } + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; + } + if (isset($attrs['name'])) { + $this->currentOperation = $attrs['name']; + $this->debug("current binding operation: $this->currentOperation"); + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; + } + break; + case 'input': + $this->opStatus = 'input'; + break; + case 'output': + $this->opStatus = 'output'; + break; + case 'body': + if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); + } else { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; + } + break; + } + break; + case 'service': + switch ($name) { + case 'port': + $this->currentPort = $attrs['name']; + $this->debug('current port: ' . $this->currentPort); + $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); + + break; + case 'address': + $this->ports[$this->currentPort]['location'] = $attrs['location']; + $this->ports[$this->currentPort]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; + break; + } + break; + } + // set status + switch ($name) { + case 'import': + if (isset($attrs['location'])) { + $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); + $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); + } else { + $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); + } + break; + //wait for schema + //case 'types': + // $this->status = 'schema'; + // break; + case 'message': + $this->status = 'message'; + $this->messages[$attrs['name']] = array(); + $this->currentMessage = $attrs['name']; + break; + case 'portType': + $this->status = 'portType'; + $this->portTypes[$attrs['name']] = array(); + $this->currentPortType = $attrs['name']; + break; + case "binding": + if (isset($attrs['name'])) { + // get binding name + if (strpos($attrs['name'], ':')) { + $this->currentBinding = $this->getLocalPart($attrs['name']); + } else { + $this->currentBinding = $attrs['name']; + } + $this->status = 'binding'; + $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); + $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); + } + break; + case 'service': + $this->serviceName = $attrs['name']; + $this->status = 'service'; + $this->debug('current service: ' . $this->serviceName); + break; + case 'definitions': + foreach ($attrs as $name => $value) { + $this->wsdl_info[$name] = $value; + } + break; + } + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name){ + // unset schema status + if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { + $this->status = ""; + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + $this->debug('Parsing WSDL schema done'); + } + if ($this->status == 'schema') { + $this->currentSchema->schemaEndElement($parser, $name); + } else { + // bring depth down a notch + $this->depth--; + } + // end documentation + if ($this->documentation) { + //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. + //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; + $this->documentation = false; + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data) + { + $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } + if ($this->documentation) { + $this->documentation .= $data; + } + } + + function getBindingData($binding) + { + if (is_array($this->bindings[$binding])) { + return $this->bindings[$binding]; + } + } + + /** + * returns an assoc array of operation names => operation data + * + * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) + * @return array + * @access public + */ + function getOperations($bindingType = 'soap') + { + $ops = array(); + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + //$this->debug("getOperations for port $port"); + //$this->debug("port data: " . $this->varDump($portData)); + //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); + // merge bindings + if (isset($this->bindings[ $portData['binding'] ]['operations'])) { + $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); + } + } + } + return $ops; + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $operation , name of operation + * @param string $bindingType , type of binding eg: soap + * @return array + * @access public + */ + function getOperationData($operation, $bindingType = 'soap') + { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // get binding + //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { + // note that we could/should also check the namespace here + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + return $opData; + } + } + } + } + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $soapAction soapAction for operation + * @param string $bindingType type of binding eg: soap + * @return array + * @access public + */ + function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // loop through operations for the binding + foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + if ($opData['soapAction'] == $soapAction) { + return $opData; + } + } + } + } + } + + /** + * returns an array of information about a given type + * returns false if no type exists by the given name + * + * typeDef = array( + * 'elements' => array(), // refs to elements array + * 'restrictionBase' => '', + * 'phpType' => '', + * 'order' => '(sequence|all)', + * 'attrs' => array() // refs to attributes array + * ) + * + * @param $type string the type + * @param $ns string namespace (not prefix) of the type + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + $this->debug("in getTypeDef: type=$type, ns=$ns"); + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + $this->debug("in getTypeDef: type namespace forced to $ns"); + } + if (isset($this->schemas[$ns])) { + $this->debug("in getTypeDef: have schema for namespace $ns"); + for ($i = 0; $i < count($this->schemas[$ns]); $i++) { + $xs = &$this->schemas[$ns][$i]; + $t = $xs->getTypeDef($type); + $this->appendDebug($xs->getDebug()); + $xs->clearDebug(); + if ($t) { + if (!isset($t['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); + $ns = substr($t['type'], 0, strrpos($t['type'], ':')); + $etype = $this->getTypeDef($uqType, $ns); + if ($etype) { + $this->debug("found type for [element] $type:"); + $this->debug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $t['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $t['elements'] = $etype['elements']; + } + if (isset($etype['attrs'])) { + $t['attrs'] = $etype['attrs']; + } + } + } + return $t; + } + } + } else { + $this->debug("in getTypeDef: do not have schema for namespace $ns"); + } + return false; + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $PHP_SELF = $_SERVER['PHP_SELF']; + } elseif (isset($HTTP_SERVER_VARS)) { + $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + + $b = ' + NuSOAP: '.$this->serviceName.' + + + + +
    +

    +
    '.$this->serviceName.'
    + +
    '; + return $b; + } + + /** + * serialize the parsed wsdl + * + * @param mixed $debug whether to put debug=1 in endpoint URL + * @return string serialization of WSDL + * @access public + */ + function serialize($debug = 0) + { + $xml = ''; + $xml .= "\nnamespaces as $k => $v) { + $xml .= " xmlns:$k=\"$v\""; + } + // 10.9.02 - add poulter fix for wsdl and tns declarations + if (isset($this->namespaces['wsdl'])) { + $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; + } + if (isset($this->namespaces['tns'])) { + $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; + } + $xml .= '>'; + // imports + if (sizeof($this->import) > 0) { + foreach($this->import as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= ''; + } else { + $xml .= ''; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= "\n"; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= ''; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= "\n'; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'
    '; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'
    '; + $typePrefix = 'xsd'; + } else { + foreach($this->typemap as $ns => $types) { + if (isset($types[$partType])) { + $typePrefix = $this->getPrefixFromNamespace($ns); + } + } + if (!isset($typePrefix)) { + die("$partType has no namespace!"); + } + } + $ns = $this->getNamespaceFromPrefix($typePrefix); + $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); + if ($typeDef['typeClass'] == 'element') { + $elementortype = 'element'; + } else { + $elementortype = 'type'; + } + $xml .= ''; + } + } + $xml .= '
    '; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= "\n'; + $binding_xml .= ''; + $portType_xml .= "\n'; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= ''; + $binding_xml .= ''; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + $binding_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $portType_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $binding_xml .= ''; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= "\nserviceName . '">'; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= ''; + $xml .= ''; + $xml .= ''; + } + } + $xml .= ''; + return $xml . "\n"; + } + + /** + * serialize PHP values according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $operation operation name + * @param string $direction (input|output) + * @param mixed $parameters parameter value(s) + * @return mixed parameters serialized as XML or false on error (e.g. operation not found) + * @access public + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeRPCParameters returning: $xml"); + return $xml; + } + + /** + * serialize a PHP value according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $ type name + * @param mixed $ param value + * @return mixed new param or false if initial value didn't validate + * @access public + * @deprecated + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug("use=$use"); + $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . $parametersArrayType . ' parameters'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeParameters returning: $xml"); + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name name of value (part or element) + * @param string $type XML schema type of value (type or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @param boolean $unqualified a kludge for what should be XML namespace form handling + * @return string value serialized as an XML string + * @access private + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) + { + $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); + $this->appendDebug("value=" . $this->varDump($value)); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soapval has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } elseif ($value->type) { + $type = $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } else { + $forceType = false; + $this->debug("in serializeType: soapval does not override type"); + } + $attrs = $value->attributes; + $value = $value->value; + $this->debug("in serializeType: soapval overrides value to $value"); + if ($attrs) { + if (!is_array($value)) { + $value['!'] = $value; + } + foreach ($attrs as $n => $v) { + $value['!' . $n] = $v; + } + $this->debug("in serializeType: soapval provides attributes"); + } + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ + $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); + if ($unqualified && $use == 'literal') { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + // TODO: depends on nillable, which should be checked before calling this method + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if ($uqType == 'boolean') { + if ((is_string($value) && $value == 'false') || (! $value)) { + $value = 'false'; + } else { + $value = 'true'; + } + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($value); + } + if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { + $value = sprintf("%.0lf", $value); + } + // it's a scalar + // TODO: what about null/nil values? + // check type isn't a custom type extending xmlschema namespace + if (!$this->getTypeDef($uqType, $ns)) { + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); + } else if ($ns == 'http://xml.apache.org/xml-soap') { + $this->debug('in serializeType: appears to be Apache SOAP type'); + if ($uqType == 'Map') { + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + if (! $tt_prefix) { + $this->debug('in serializeType: Add namespace for Apache SOAP type'); + $tt_prefix = 'ns' . rand(1000, 9999); + $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; + // force this to be added to usedNamespaces + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + } + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= ''; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= ''; + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents"; + } else { + $xml = "<$name>$contents"; + } + } else { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('in serializeType: Apache SOAP type, but only support Map'); + } + } else { + // TODO: should the type be compared to types in XSD, and the namespace + // set to XSD if the type matches? + $this->debug("in serializeType: No namespace for type $type"); + $ns = ''; + $uqType = $type; + } + if(!$typeDef = $this->getTypeDef($uqType, $ns)){ + $this->setError("$type ($uqType) is not a supported type."); + $this->debug("in serializeType: $type ($uqType) is not a supported type."); + return false; + } else { + $this->debug("in serializeType: found typeDef"); + $this->appendDebug('typeDef=' . $this->varDump($typeDef)); + } + $phpType = $typeDef['phpType']; + $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the element names + if ($phpType == 'struct') { + if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { + $elementName = $uqType; + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = " xmlns=\"\""; + } + } else { + $elementName = $name; + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$elementName$elementNS/>"; + } else { + $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (is_object($value)) { + $value = get_object_vars($value); + } + if (is_array($value)) { + $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS$elementAttrs>"; + } + } else { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + $xml .= ""; + } else { + $this->debug("in serializeType: phpType is struct, but value is not an array"); + $this->setError("phpType is struct, but value is not an array: see debug output for details"); + $xml = ''; + } + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ":Array\" " . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ':arrayType="' . + $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . + ':' . + $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (isset($typeDef['multidimensional'])) { + $nv = array(); + foreach($value as $v) { + $cols = ',' . sizeof($v); + $nv = array_merge($nv, $v); + } + $value = $nv; + } else { + $cols = ''; + } + if (is_array($value) && sizeof($value) >= 1) { + $rows = sizeof($value); + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); + //if (strpos($typeDef['arrayType'], ':') ) { + if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { + $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); + } else { + $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); + } + } + } else { + $rows = 0; + $contents = null; + } + // TODO: for now, an empty value will be serialized as a zero element + // array. Revisit this when coding the handling of null/nil values. + if ($use == 'literal') { + $xml = "<$name$elementNS>" + .$contents + .""; + } else { + $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') + .':arrayType="' + .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) + .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" + .$contents + .""; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + + /** + * serializes the attributes for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { + $xml = ''; + if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { + $this->debug("serialize attributes for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + foreach ($typeDef['attrs'] as $aName => $attrs) { + if (isset($xvalue['!' . $aName])) { + $xname = '!' . $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($xvalue[$aName])) { + $xname = $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($attrs['default'])) { + $xname = '!' . $aName; + $xvalue[$xname] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); + } else { + $xname = ''; + $this->debug("no value provided for attribute $aName"); + } + if ($xname) { + $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; + } + } + } else { + $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize attributes for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * serializes the elements for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { + $xml = ''; + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + // toggle whether all elements are present - ideally should validate against schema + if (count($typeDef['elements']) != count($xvalue)){ + $optionals = true; + } + foreach ($typeDef['elements'] as $eName => $attrs) { + if (!isset($xvalue[$eName])) { + if (isset($attrs['default'])) { + $xvalue[$eName] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); + } + } + // if user took advantage of a minOccurs=0, then only serialize named parameters + if (isset($optionals) + && (!isset($xvalue[$eName])) + && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') + ){ + if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { + $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); + } + // do nothing + $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + if (isset($attrs['form'])) { + $unqualified = ($attrs['form'] == 'unqualified'); + } else { + $unqualified = false; + } + if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } else { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } + } + } else { + $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize elements for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @param string name + * @param string typeClass (complexType|simpleType|attribute) + * @param string phpType: currently supported are array and struct (php assoc array) + * @param string compositor (all|sequence|choice) + * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param array elements = array ( name => array(name=>'',type=>'') ) + * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) + * @param string arrayType: namespace:name (xsd:string) + * @see xmlschema + * @access public + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { + if (count($elements) > 0) { + foreach($elements as $n => $e){ + // expand each element + foreach ($e as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $ee[$k] = $v; + } + $eElements[$n] = $ee; + } + $elements = $eElements; + } + + if (count($attrs) > 0) { + foreach($attrs as $n => $a){ + // expand each attribute + foreach ($a as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $aa[$k] = $v; + } + $eAttrs[$n] = $aa; + } + $attrs = $eAttrs; + } + + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); + } + + /** + * adds an XML Schema simple type to the WSDL types + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @see xmlschema + * @access public + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); + } + + /** + * adds an element to the WSDL types + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addElement($attrs); + } + + /** + * register an operation with the server + * + * @param string $name operation (method) name + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param string $namespace optional The namespace for the operation + * @param string $soapaction optional The soapaction for the operation + * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) + * @param string $documentation optional The description to include in the WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ + if ($use == 'encoded' && $encodingStyle == '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + if ($style == 'document') { + $elements = array(); + foreach ($in as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); + $in = array('parameters' => 'tns:' . $name); + + $elements = array(); + foreach ($out as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); + $out = array('parameters' => 'tns:' . $name . 'Response'); + } + + // get binding + $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = + array( + 'name' => $name, + 'binding' => $this->serviceName . 'Binding', + 'endpoint' => $this->endpoint, + 'soapAction' => $soapaction, + 'style' => $style, + 'input' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Request', + 'parts' => $in), + 'output' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Response', + 'parts' => $out), + 'namespace' => $namespace, + 'transport' => 'http://schemas.xmlsoap.org/soap/http', + 'documentation' => $documentation); + // add portTypes + // add messages + if($in) + { + foreach($in as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Request'][$pName] = $pType; + } + } else { + $this->messages[$name.'Request']= '0'; + } + if($out) + { + foreach($out as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Response'][$pName] = $pType; + } + } else { + $this->messages[$name.'Response']= '0'; + } + return true; + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/class.wsdlcache.php b/gulliver/thirdparty/pear/class.wsdlcache.php new file mode 100644 index 000000000..4258ea112 --- /dev/null +++ b/gulliver/thirdparty/pear/class.wsdlcache.php @@ -0,0 +1,184 @@ + +* @author Ingo Fischer +* @version $Id: class.wsdlcache.php,v 1.5 2005/05/20 17:58:17 snichol Exp $ +* @access public +*/ +class wsdlcache { + /** + * @var resource + * @access private + */ + var $fplock; + /** + * @var integer + * @access private + */ + var $cache_lifetime; + /** + * @var string + * @access private + */ + var $cache_dir; + /** + * @var string + * @access public + */ + var $debug_str = ''; + + /** + * constructor + * + * @param string $cache_dir directory for cache-files + * @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited + * @access public + */ + function wsdlcache($cache_dir='.', $cache_lifetime=0) { + $this->fplock = array(); + $this->cache_dir = $cache_dir != '' ? $cache_dir : '.'; + $this->cache_lifetime = $cache_lifetime; + } + + /** + * creates the filename used to cache a wsdl instance + * + * @param string $wsdl The URL of the wsdl instance + * @return string The filename used to cache the instance + * @access private + */ + function createFilename($wsdl) { + return $this->cache_dir.'/wsdlcache-' . md5($wsdl); + } + + /** + * adds debug data to the class level debug string + * + * @param string $string debug data + * @access private + */ + function debug($string){ + $this->debug_str .= get_class($this).": $string\n"; + } + + /** + * gets a wsdl instance from the cache + * + * @param string $wsdl The URL of the wsdl instance + * @return object wsdl The cached wsdl instance, null if the instance is not in the cache + * @access public + */ + function get($wsdl) { + $filename = $this->createFilename($wsdl); + if ($this->obtainMutex($filename, "r")) { + // check for expired WSDL that must be removed from the cache + if ($this->cache_lifetime > 0) { + if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) { + unlink($filename); + $this->debug("Expired $wsdl ($filename) from cache"); + $this->releaseMutex($filename); + return null; + } + } + // see what there is to return + $fp = @fopen($filename, "r"); + if ($fp) { + $s = implode("", @file($filename)); + fclose($fp); + $this->debug("Got $wsdl ($filename) from cache"); + } else { + $s = null; + $this->debug("$wsdl ($filename) not in cache"); + } + $this->releaseMutex($filename); + return (!is_null($s)) ? unserialize($s) : null; + } else { + $this->debug("Unable to obtain mutex for $filename in get"); + } + return null; + } + + /** + * obtains the local mutex + * + * @param string $filename The Filename of the Cache to lock + * @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode + * @return boolean Lock successfully obtained ?! + * @access private + */ + function obtainMutex($filename, $mode) { + if (isset($this->fplock[md5($filename)])) { + $this->debug("Lock for $filename already exists"); + return false; + } + $this->fplock[md5($filename)] = fopen($filename.".lock", "w"); + if ($mode == "r") { + return flock($this->fplock[md5($filename)], LOCK_SH); + } else { + return flock($this->fplock[md5($filename)], LOCK_EX); + } + } + + /** + * adds a wsdl instance to the cache + * + * @param object wsdl $wsdl_instance The wsdl instance to add + * @return boolean WSDL successfully cached + * @access public + */ + function put($wsdl_instance) { + $filename = $this->createFilename($wsdl_instance->wsdl); + $s = serialize($wsdl_instance); + if ($this->obtainMutex($filename, "w")) { + $fp = fopen($filename, "w"); + fputs($fp, $s); + fclose($fp); + $this->debug("Put $wsdl_instance->wsdl ($filename) in cache"); + $this->releaseMutex($filename); + return true; + } else { + $this->debug("Unable to obtain mutex for $filename in put"); + } + return false; + } + + /** + * releases the local mutex + * + * @param string $filename The Filename of the Cache to lock + * @return boolean Lock successfully released + * @access private + */ + function releaseMutex($filename) { + $ret = flock($this->fplock[md5($filename)], LOCK_UN); + fclose($this->fplock[md5($filename)]); + unset($this->fplock[md5($filename)]); + if (! $ret) { + $this->debug("Not able to release lock for $filename"); + } + return $ret; + } + + /** + * removes a wsdl instance from the cache + * + * @param string $wsdl The URL of the wsdl instance + * @return boolean Whether there was an instance to remove + * @access public + */ + function remove($wsdl) { + $filename = $this->createFilename($wsdl); + // ignore errors obtaining mutex + $this->obtainMutex($filename, "w"); + $ret = unlink($filename); + $this->debug("Removed ($ret) $wsdl ($filename) from cache"); + $this->releaseMutex($filename); + return $ret; + } +} +?> diff --git a/gulliver/thirdparty/pear/class.xmlschema.php b/gulliver/thirdparty/pear/class.xmlschema.php new file mode 100644 index 000000000..7a4ece49d --- /dev/null +++ b/gulliver/thirdparty/pear/class.xmlschema.php @@ -0,0 +1,906 @@ + +* @version $Id: class.xmlschema.php,v 1.39 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class XMLSchema extends nusoap_base { + + // files + var $schema = ''; + var $xml = ''; + // namespaces + var $enclosingNamespaces; + // schema info + var $schemaInfo = array(); + var $schemaTargetNamespace = ''; + // types, elements, attributes defined by the schema + var $attributes = array(); + var $complexTypes = array(); + var $complexTypeStack = array(); + var $currentComplexType = null; + var $elements = array(); + var $elementStack = array(); + var $currentElement = null; + var $simpleTypes = array(); + var $simpleTypeStack = array(); + var $currentSimpleType = null; + // imports + var $imports = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + var $message = array(); + var $defaultNamespace = array(); + + /** + * constructor + * + * @param string $schema schema document URI + * @param string $xml xml document URI + * @param string $namespaces namespaces defined in enclosing XML + * @access public + */ + function XMLSchema($schema='',$xml='',$namespaces=array()){ + parent::nusoap_base(); + $this->debug('xmlschema class instantiated, inside constructor'); + // files + $this->schema = $schema; + $this->xml = $xml; + + // namespaces + $this->enclosingNamespaces = $namespaces; + $this->namespaces = array_merge($this->namespaces, $namespaces); + + // parse schema file + if($schema != ''){ + $this->debug('initial schema file: '.$schema); + $this->parseFile($schema, 'schema'); + } + + // parse xml file + if($xml != ''){ + $this->debug('initial xml file: '.$xml); + $this->parseFile($xml, 'xml'); + } + + } + + /** + * parse an XML file + * + * @param string $xml, path/URL to XML file + * @param string $type, (schema | xml) + * @return boolean + * @access public + */ + function parseFile($xml,$type){ + // parse xml file + if($xml != ""){ + $xmlStr = @join("",@file($xml)); + if($xmlStr == ""){ + $msg = 'Error reading XML from '.$xml; + $this->setError($msg); + $this->debug($msg); + return false; + } else { + $this->debug("parsing $xml"); + $this->parseString($xmlStr,$type); + $this->debug("done parsing $xml"); + return true; + } + } + return false; + } + + /** + * parse an XML string + * + * @param string $xml path or URL + * @param string $type, (schema|xml) + * @access private + */ + function parseString($xml,$type){ + // parse xml string + if($xml != ""){ + + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + + // Set the object for the parser. + xml_set_object($this->parser, $this); + + // Set the element handlers for the parser. + if($type == "schema"){ + xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); + xml_set_character_data_handler($this->parser,'schemaCharacterData'); + } elseif($type == "xml"){ + xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); + xml_set_character_data_handler($this->parser,'xmlCharacterData'); + } + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $errstr = sprintf('XML error parsing XML schema on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $xml); + $this->setError($errstr); + } + + xml_parser_free($this->parser); + } else{ + $this->debug('no xml passed to parseString()!!'); + $this->setError('no xml passed to parseString()!!'); + } + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function schemaStartElement($parser, $name, $attrs) { + + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + if ($depth > 0) { + $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; + } else { + $this->defaultNamespace[$pos] = false; + } + + // get element prefix + if($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + + // loop thru attributes, expanding, and registering namespace declarations + if(count($attrs) > 0){ + foreach($attrs as $k => $v){ + // if ns declarations, add to class level array of valid namespaces + if(ereg("^xmlns",$k)){ + //$this->xdebug("$k: $v"); + //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); + if($ns_prefix = substr(strrchr($k,':'),1)){ + //$this->xdebug("Add namespace[$ns_prefix] = $v"); + $this->namespaces[$ns_prefix] = $v; + } else { + $this->defaultNamespace[$pos] = $v; + if (! $this->getPrefixFromNamespace($v)) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; + } + } + if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v.'-instance'; + } + } + } + foreach($attrs as $k => $v){ + // expand each attribute + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // find status, register data + switch($name){ + case 'all': // (optional) compositor content for a complexType + case 'choice': + case 'group': + case 'sequence': + //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + $this->complexTypes[$this->currentComplexType]['compositor'] = $name; + //if($name == 'all' || $name == 'sequence'){ + // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + //} + break; + case 'attribute': // complexType attribute + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute:"); + $this->appendDebug($this->varDump($attrs)); + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['attributeFormDefault']; + } + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + if (!strpos($v, ':')) { + // no namespace in arrayType attribute value... + if ($this->defaultNamespace[$pos]) { + // ...so use the default + $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } + } + } + if(isset($attrs['name'])){ + $this->attributes[$attrs['name']] = $attrs; + $aname = $attrs['name']; + } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $aname = ''; + } + } elseif(isset($attrs['ref'])){ + $aname = $attrs['ref']; + $this->attributes[$attrs['ref']] = $attrs; + } + + if($this->currentComplexType){ // This should *always* be + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } + // arrayType attribute + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + $prefix = $this->getPrefix($aname); + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $v = ''; + } + if(strpos($v,'[,]')){ + $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; + } + $v = substr($v,0,strpos($v,'[')); // clip the [] + if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ + $v = $this->XMLSchemaVersion.':'.$v; + } + $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; + } + break; + case 'complexContent': // (optional) content for a complexType + break; + case 'complexType': + array_push($this->complexTypeStack, $this->currentComplexType); + if(isset($attrs['name'])){ + $this->xdebug('processing named complexType '.$attrs['name']); + //$this->currentElement = false; + $this->currentComplexType = $attrs['name']; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + }else{ + $this->xdebug('processing unnamed complexType for element '.$this->currentElement); + $this->currentComplexType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + array_push($this->elementStack, $this->currentElement); + // elements defined as part of a complex type should + // not really be added to $this->elements, but for some + // reason, they are + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['elementFormDefault']; + } + if(isset($attrs['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + if (! $this->getPrefix($attrs['type'])) { + if ($this->defaultNamespace[$pos]) { + $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; + $this->xdebug('used default namespace to make type ' . $attrs['type']); + } + } + // This is for constructs like + // + // + // + // + // + if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { + $this->xdebug('arrayType for unusual array is ' . $attrs['type']); + $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; + } + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $this->xdebug("processing element as ref to ".$attrs['ref']); + $this->currentElement = "ref to ".$attrs['ref']; + $ename = $this->getLocalPart($attrs['ref']); + } else { + $this->xdebug("processing untyped element ".$attrs['name']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; + $ename = $attrs['name']; + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + case 'enumeration': // restriction value list member + $this->xdebug('enumeration ' . $attrs['value']); + if ($this->currentSimpleType) { + $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; + } elseif ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; + } + break; + case 'extension': // simpleContent or complexContent type extension + $this->xdebug('extension ' . $attrs['base']); + if ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; + } + break; + case 'import': + if (isset($attrs['schemaLocation'])) { + //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); + $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); + } else { + //$this->xdebug('import namespace ' . $attrs['namespace']); + $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + } + break; + case 'list': // simpleType value list + break; + case 'restriction': // simpleType, simpleContent or complexContent value restriction + $this->xdebug('restriction ' . $attrs['base']); + if($this->currentSimpleType){ + $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; + } elseif($this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; + if(strstr($attrs['base'],':') == ':Array'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } + } + break; + case 'schema': + $this->schemaInfo = $attrs; + $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); + if (isset($attrs['targetNamespace'])) { + $this->schemaTargetNamespace = $attrs['targetNamespace']; + } + if (!isset($attrs['elementFormDefault'])) { + $this->schemaInfo['elementFormDefault'] = 'unqualified'; + } + if (!isset($attrs['attributeFormDefault'])) { + $this->schemaInfo['attributeFormDefault'] = 'unqualified'; + } + break; + case 'simpleContent': // (optional) content for a complexType + break; + case 'simpleType': + array_push($this->simpleTypeStack, $this->currentSimpleType); + if(isset($attrs['name'])){ + $this->xdebug("processing simpleType for name " . $attrs['name']); + $this->currentSimpleType = $attrs['name']; + $this->simpleTypes[ $attrs['name'] ] = $attrs; + $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; + $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; + } else { + $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); + $this->currentSimpleType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->simpleTypes[$this->currentSimpleType] = $attrs; + $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; + } + break; + case 'union': // simpleType type list + break; + default: + //$this->xdebug("do not have anything to do for element $name"); + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function schemaEndElement($parser, $name) { + // bring depth down a notch + $this->depth--; + // position of current element is equal to the last value left in depth_array for my depth + if(isset($this->depth_array[$this->depth])){ + $pos = $this->depth_array[$this->depth]; + } + // get element prefix + if ($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + // move on... + if($name == 'complexType'){ + $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); + $this->currentComplexType = array_pop($this->complexTypeStack); + //$this->currentElement = false; + } + if($name == 'element'){ + $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); + $this->currentElement = array_pop($this->elementStack); + } + if($name == 'simpleType'){ + $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); + $this->currentSimpleType = array_pop($this->simpleTypeStack); + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function schemaCharacterData($parser, $data){ + $pos = $this->depth_array[$this->depth - 1]; + $this->message[$pos]['cdata'] .= $data; + } + + /** + * serialize the schema + * + * @access public + */ + function serializeSchema(){ + + $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); + $xml = ''; + // imports + if (sizeof($this->imports) > 0) { + foreach($this->imports as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; + } else { + $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; + } + } + } + } + // complex types + foreach($this->complexTypes as $typeName => $attrs){ + $contentStr = ''; + // serialize child elements + if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ + foreach($attrs['elements'] as $element => $eParts){ + if(isset($eParts['ref'])){ + $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; + } else { + $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; + foreach ($eParts as $aName => $aValue) { + // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable + if ($aName != 'name' && $aName != 'type') { + $contentStr .= " $aName=\"$aValue\""; + } + } + $contentStr .= "/>\n"; + } + } + // compositor wraps elements + if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." \n"; + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute"; + foreach ($aParts as $a => $v) { + if ($a == 'ref' || $a == 'type') { + $contentStr .= " $a=\"".$this->contractQName($v).'"'; + } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; + } else { + $contentStr .= " $a=\"$v\""; + } + } + $contentStr .= "/>\n"; + } + } + // if restriction + if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." \n"; + // complex or simple content + if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." \n"; + } + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." \n"; + } else { + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; + } + $xml .= $contentStr; + } + // simple types + if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ + foreach($this->simpleTypes as $typeName => $eParts){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; + if (isset($eParts['enumeration'])) { + foreach ($eParts['enumeration'] as $e) { + $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; + } + } + $xml .= " "; + } + } + // elements + if(isset($this->elements) && count($this->elements) > 0){ + foreach($this->elements as $element => $eParts){ + $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; + } + } + // attributes + if(isset($this->attributes) && count($this->attributes) > 0){ + foreach($this->attributes as $attr => $aParts){ + $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; + } + } + // finish 'er up + $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; + foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { + $el .= " xmlns:$nsp=\"$ns\"\n"; + } + $xml = $el . ">\n".$xml."\n"; + return $xml; + } + + /** + * adds debug data to the clas level debug string + * + * @param string $string debug data + * @access private + */ + function xdebug($string){ + $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); + } + + /** + * get the PHP type of a user defined type in the schema + * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays + * returns false if no type exists, or not w/ the given namespace + * else returns a string that is either a native php type, or 'struct' + * + * @param string $type, name of defined type + * @param string $ns, namespace of type + * @return mixed + * @access public + * @deprecated + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap
    "; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array
    "; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * returns an associative array of information about a given type + * returns false if no type exists by the given name + * + * For a complexType typeDef = array( + * 'restrictionBase' => '', + * 'phpType' => '', + * 'compositor' => '(sequence|all)', + * 'elements' => array(), // refs to elements array + * 'attrs' => array() // refs to attributes array + * ... and so on (see addComplexType) + * ) + * + * For simpleType or element, the array has different keys. + * + * @param string + * @return mixed + * @access public + * @see addComplexType + * @see addSimpleType + * @see addElement + */ + function getTypeDef($type){ + //$this->debug("in getTypeDef for type $type"); + if(isset($this->complexTypes[$type])){ + $this->xdebug("in getTypeDef, found complexType $type"); + return $this->complexTypes[$type]; + } elseif(isset($this->simpleTypes[$type])){ + $this->xdebug("in getTypeDef, found simpleType $type"); + if (!isset($this->simpleTypes[$type]['phpType'])) { + // get info for type to tack onto the simple type + // TODO: can this ever really apply (i.e. what is a simpleType really?) + $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); + $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for simpleType $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->simpleTypes[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->simpleTypes[$type]['elements'] = $etype['elements']; + } + } + } + return $this->simpleTypes[$type]; + } elseif(isset($this->elements[$type])){ + $this->xdebug("in getTypeDef, found element $type"); + if (!isset($this->elements[$type]['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); + $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for element $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->elements[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->elements[$type]['elements'] = $etype['elements']; + } + } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { + $this->xdebug("in getTypeDef, element $type is an XSD type"); + $this->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } elseif (ereg('_ContainedType$', $type)) { + $this->xdebug("in getTypeDef, have an untyped element $type"); + $typeDef['typeClass'] = 'simpleType'; + $typeDef['phpType'] = 'scalar'; + $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; + return $typeDef; + } + $this->xdebug("in getTypeDef, did not find $type"); + return false; + } + + /** + * returns a sample serialization of a given type, or false if no type by the given name + * + * @param string $type, name of type + * @return mixed + * @access public + * @deprecated + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type
    "; + if($typeDef = $this->getTypeDef($type)){ + $str .= '<'.$type; + if(is_array($typeDef['attrs'])){ + foreach($attrs as $attName => $data){ + $str .= " $attName=\"{type = ".$data['type']."}\""; + } + } + $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; + if(count($typeDef['elements']) > 0){ + $str .= ">"; + foreach($typeDef['elements'] as $element => $eData){ + $str .= $this->serializeTypeDef($element); + } + $str .= ""; + } elseif($typeDef['typeClass'] == 'element') { + $str .= ">"; + } else { + $str .= "/>"; + } + return $str; + } + return false; + } + + /** + * returns HTML form elements that allow a user + * to enter values for creating an instance of the given type. + * + * @param string $name, name for type instance + * @param string $type, name of type + * @return string + * @access public + * @deprecated + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= ''; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + + "; + } + $buffer .= '
    $childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):
    '; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= ''; + for($i=0;$i < 3; $i++){ + $buffer .= " + + "; + } + $buffer .= '
    array item (type: $typeDef[arrayType]):
    '; + // if scalar + } else { + $buffer .= ""; + } + } else { + $buffer .= ""; + } + return $buffer; + } + + /** + * adds a complex type to the schema + * + * example: array + * + * addType( + * 'ArrayOfstring', + * 'complexType', + * 'array', + * '', + * 'SOAP-ENC:Array', + * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), + * 'xsd:string' + * ); + * + * example: PHP associative array ( SOAP Struct ) + * + * addType( + * 'SOAPStruct', + * 'complexType', + * 'struct', + * 'all', + * array('myVar'=> array('name'=>'myVar','type'=>'string') + * ); + * + * @param name + * @param typeClass (complexType|simpleType|attribute) + * @param phpType: currently supported are array and struct (php assoc array) + * @param compositor (all|sequence|choice) + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param elements = array ( name = array(name=>'',type=>'') ) + * @param attrs = array( + * array( + * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", + * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" + * ) + * ) + * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) + * @access public + * @see getTypeDef + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ + $this->complexTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'compositor'=> $compositor, + 'restrictionBase' => $restrictionBase, + 'elements' => $elements, + 'attrs' => $attrs, + 'arrayType' => $arrayType + ); + + $this->xdebug("addComplexType $name:"); + $this->appendDebug($this->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @access public + * @see xmlschema + * @see getTypeDef + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase, + 'enumeration' => $enumeration + ); + + $this->xdebug("addSimpleType $name:"); + $this->appendDebug($this->varDump($this->simpleTypes[$name])); + } + + /** + * adds an element to the schema + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + if (! $this->getPrefix($attrs['type'])) { + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; + } + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + + $this->xdebug("addElement " . $attrs['name']); + $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); + } +} + + + + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/install-pear.php b/gulliver/thirdparty/pear/install-pear.php new file mode 100644 index 000000000..1585ee81f --- /dev/null +++ b/gulliver/thirdparty/pear/install-pear.php @@ -0,0 +1,109 @@ + install_file +$install_files = array(); + +/* +$dp = opendir($pear_dir); +while ($ent = readdir($dp)) { + if (ereg('^package-(.*)\.xml$', $ent, $matches)) { + $install_files[$matches[1]] = $ent; + } +} +closedir($dp); +*/ +foreach ($argv as $arg) { + $bn = basename($arg); + if (ereg('^package-(.*)\.xml$', $bn, $matches) || + ereg('^([A-Za-z0-9_:]+)-.*\.(tar|tgz)$', $bn, $matches)) { + $install_files[$matches[1]] = $arg; + } +} + +$config = &PEAR_Config::singleton(); + +// make sure we use only default values +$config_layers = $config->getLayers(); +foreach ($config_layers as $layer) { + if ($layer == 'default') continue; + $config->removeLayer($layer); +} +$config->set('verbose', 0, 'default'); + +$options = array(); +$install_root = getenv("INSTALL_ROOT"); +$php_dir = $config->get('php_dir'); +if (!empty($install_root)) { + $options['installroot'] = $install_root; + $reg_dir = $install_root . $php_dir; +} else { + $reg_dir = $php_dir; +} + +$reg = &new PEAR_Registry($reg_dir); +$ui = &new PEAR_Frontend_CLI(); +$installer = &new PEAR_Installer($ui); +$installer->registry = &$reg; + +foreach ($install_files as $package => $instfile) { + if ($reg->packageExists($package)) { + $info = $installer->infoFromAny($instfile); + if (PEAR::isError($info)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage())); + continue; + } + $new_ver = $info['version']; + $old_ver = $reg->packageInfo($package, 'version'); + if (version_compare($new_ver, $old_ver, 'gt')) { + $options['upgrade'] = true; + $err = $installer->install($instfile, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- upgraded: %s", $package, $new_ver)); + } else { + if (@$argv[1] == '--force') { + $options['force'] = true; + $err = $installer->install($instfile, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } else { + $ui->outputData(sprintf("[PEAR] %-15s- already installed: %s", $package, $old_ver)); + } + } + } else { + $options['nodeps'] = true; + $err = $installer->install($instfile, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $new_ver = $reg->packageInfo($package, 'version'); + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/install-pear.txt b/gulliver/thirdparty/pear/install-pear.txt new file mode 100644 index 000000000..ec632e8ad --- /dev/null +++ b/gulliver/thirdparty/pear/install-pear.txt @@ -0,0 +1,11 @@ ++----------------------------------------------------------------------+ +| The installation process is incomplete. The following resources were | +| not installed: | +| | +| Self-contained Extension Support | +| PEAR: PHP Extension and Application Repository | +| | +| To install these components, become the superuser and execute: | +| | +| # make install-su | ++----------------------------------------------------------------------+ diff --git a/gulliver/thirdparty/pear/json/class.json.php b/gulliver/thirdparty/pear/json/class.json.php new file mode 100644 index 000000000..9be13db3d --- /dev/null +++ b/gulliver/thirdparty/pear/json/class.json.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/nusoap.colosa.php b/gulliver/thirdparty/pear/nusoap.colosa.php new file mode 100644 index 000000000..3a5ee0eff --- /dev/null +++ b/gulliver/thirdparty/pear/nusoap.colosa.php @@ -0,0 +1,7249 @@ +globalDebugLevel = 9; + +/** +* +* nusoap_base +* +* @author Dietrich Ayala +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class nusoap_base_colosa { + /** + * Identification for HTTP headers. + * + * @var string + * @access private + */ + var $title = 'NuSOAP_colosa'; + /** + * Version for HTTP headers. + * + * @var string + * @access private + */ + var $version = '0.7.2'; + /** + * CVS revision for HTTP headers. + * + * @var string + * @access private + */ + var $revision = '$Revision: 1.94 $'; + /** + * Current error string (manipulated by getError/setError) + * + * @var string + * @access private + */ + var $error_str = ''; + /** + * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) + * + * @var string + * @access private + */ + var $debug_str = ''; + /** + * toggles automatic encoding of special characters as entities + * (should always be true, I think) + * + * @var boolean + * @access private + */ + var $charencoding = true; + /** + * the debug level for this instance + * + * @var integer + * @access private + */ + var $debugLevel; + + /** + * set schema version + * + * @var string + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * charset encoding for outgoing messages + * + * @var string + * @access public + */ + var $soap_defencoding = 'ISO-8859-1'; + //var $soap_defencoding = 'UTF-8'; + + /** + * namespaces in an array of prefix => uri + * + * this is "seeded" by a set of constants, but it may be altered by code + * + * @var array + * @access public + */ + var $namespaces = array( + 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' + ); + + /** + * namespaces used in the current context, e.g. during serialization + * + * @var array + * @access private + */ + var $usedNamespaces = array(); + + /** + * XML Schema types in an array of uri => (array of xml type => php type) + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var array + * @access public + */ + var $typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', + 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', + 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', + // abstract "any" types + 'anyType'=>'string','anySimpleType'=>'string', + // derived datatypes + 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', + 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', + 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', + 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), + 'http://www.w3.org/2000/10/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), + 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), + 'http://xml.apache.org/xml-soap' => array('Map') + ); + + /** + * XML entities to convert + * + * @var array + * @access public + * @deprecated + * @see expandEntities + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * constructor + * + * @access public + */ + function nusoap_base_colosa() { + $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * gets the global debug level, which applies to future instances + * + * @return integer Debug level 0-9, where 0 turns off + * @access public + */ + function getGlobalDebugLevel() { + return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * sets the global debug level, which applies to future instances + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setGlobalDebugLevel($level) { + $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; + } + + /** + * gets the debug level for this instance + * + * @return int Debug level 0-9, where 0 turns off + * @access public + */ + function getDebugLevel() { + return $this->debugLevel; + } + + /** + * sets the debug level for this instance + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setDebugLevel($level) { + $this->debugLevel = $level; + } + + /** + * adds debug data to the instance debug string with formatting + * + * @param string $string debug data + * @access private + */ + function debug($string){ + if ($this->debugLevel > 0) { + $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); + } + } + + /** + * adds debug data to the instance debug string without formatting + * + * @param string $string debug data + * @access public + */ + function appendDebug($string){ + if ($this->debugLevel > 0) { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str .= $string; + } + } + + /** + * clears the current debug data for this instance + * + * @access public + */ + function clearDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str = ''; + } + + /** + * gets the current debug data for this instance + * + * @return debug data + * @access public + */ + function &getDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + return $this->debug_str; + } + + /** + * gets the current debug data for this instance as an XML comment + * this may change the contents of the debug data + * + * @return debug data as an XML comment + * @access public + */ + function &getDebugAsXMLComment() { + // it would be nice to use a memory stream here to use + // memory more efficiently + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + return ""; + } + + /** + * expands entities, e.g. changes '<' to '<'. + * + * @param string $val The string in which to expand entities. + * @access private + */ + function expandEntities($val) { + if ($this->charencoding) { + $val = str_replace('&', '&', $val); + $val = str_replace("'", ''', $val); + $val = str_replace('"', '"', $val); + $val = str_replace('<', '<', $val); + $val = str_replace('>', '>', $val); + } + return $val; + } + + /** + * returns error string if present + * + * @return mixed error string or false + * @access public + */ + function getError(){ + if($this->error_str != ''){ + return $this->error_str; + } + return false; + } + + /** + * sets error string + * + * @return boolean $string error string + * @access private + */ + function setError($str){ + $this->error_str = $str; + } + + /** + * detect if array is a simple array or a struct (associative array) + * + * @param mixed $val The PHP array + * @return string (arraySimple|arrayStruct) + * @access private + */ + function isArraySimpleOrStruct($val) { + $keyList = array_keys($val); + foreach ($keyList as $keyListValue) { + if (!is_int($keyListValue)) { + return 'arrayStruct'; + } + } + return 'arraySimple'; + } + + /** + * serializes PHP values in accordance w/ section 5. Type information is + * not serialized if $use == 'literal'. + * + * @param mixed $val The value to serialize + * @param string $name The name (local part) of the XML element + * @param string $type The XML schema type (local part) for the element + * @param string $name_ns The namespace for the name of the XML element + * @param string $type_ns The namespace for the type of the element + * @param array $attributes The attributes to serialize as name=>value pairs + * @param string $use The WSDL "use" (encoded|literal) + * @return string The serialized element, possibly with child elements + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); + $this->appendDebug('value=' . $this->varDump($val)); + $this->appendDebug('attributes=' . $this->varDump($attributes)); + + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + // force valid name if necessary + if (is_numeric($name)) { + $name = '__numeric_' . $name; + } elseif (! $name) { + $name = 'noname'; + } + // if name has ns, add ns prefix to name + $xmlns = ''; + if($name_ns){ + $prefix = 'nu'.rand(1000,9999); + $name = $prefix.':'.$name; + $xmlns .= " xmlns:$prefix=\"$name_ns\""; + } + // if type is prefixed, create type prefix + if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ + // need to fix this. shouldn't default to xsd if no ns specified + // w/o checking against typemap + $type_prefix = 'xsd'; + } elseif($type_ns){ + $type_prefix = 'ns'.rand(1000,9999); + $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; + } + // serialize attributes if present + $atts = ''; + if($attributes){ + foreach($attributes as $k => $v){ + $atts .= " $k=\"".$this->expandEntities($v).'"'; + } + } + // serialize null value + if (is_null($val)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + return "<$name$xmlns $atts/>"; + } else { + if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; + } + } + // serialize if an xsd built-in primitive type + if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ + if (is_bool($val)) { + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + } else if (is_string($val)) { + $val = $this->expandEntities($val); + } + if ($use == 'literal') { + return "<$name$xmlns $atts>$val"; + } else { + return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case (is_bool($val) || $type == 'boolean'): + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; +// $xml .= "<$name$xmlns xsi:type=\"xsd:long\">$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\">$val"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val"; + } + break; + case is_object($val): + if (! $name) { + $name = get_class($val); + $this->debug("In serialize_val, used class name $name as element name"); + } else { + $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); + } + foreach(get_object_vars($val) as $k => $v){ + $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); + } + $xml .= '<'.$name.'>'.$pXml.''; + break; + break; + case (is_array($val) || $type): + // detect if struct or array + $valueType = $this->isArraySimpleOrStruct($val); + if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ + $i = 0; + if(is_array($val) && count($val)> 0){ + foreach($val as $v){ + if(is_object($v) && get_class($v) == 'soapval'){ + $tt_ns = $v->type_ns; + $tt = $v->type; + } elseif (is_array($v)) { + $tt = $this->isArraySimpleOrStruct($v); + } else { + $tt = gettype($v); + } + $array_types[$tt] = 1; + // TODO: for literal, the name should be $name + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:anyType'; + } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { + if ($tt == 'integer') { + $tt = 'int'; + } + $array_typename = 'xsd:'.$tt; + } elseif(isset($tt) && $tt == 'arraySimple'){ + $array_typename = 'SOAP-ENC:Array'; + } elseif(isset($tt) && $tt == 'arrayStruct'){ + $array_typename = 'unnamed_struct_use_soapval'; + } else { + // if type is prefixed, create type prefix + if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ + $array_typename = 'xsd:' . $tt; + } elseif ($tt_ns) { + $tt_prefix = 'ns' . rand(1000, 9999); + $array_typename = "$tt_prefix:$tt"; + $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; + } else { + $array_typename = $tt; + } + } + $array_type = $i; + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; + } + // empty array + } else { + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; + } + } + // TODO: for array in literal, there is no wrapper here + $xml = "<$name$xmlns$type_str$atts>".$xml.""; + } else { + // got a struct + if(isset($type) && isset($type_prefix)){ + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>"; + } else { + $xml .= "<$name$xmlns$type_str$atts>"; + } + foreach($val as $k => $v){ + // Apache Map + if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { + $xml .= ''; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= ''; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= ""; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serializes a message + * + * @param string $body the XML of the SOAP body + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param array $namespaces optional the namespaces used in generating the body and headers + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @return string the message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ + // TODO: add an option to automatically run utf8_encode on $body and $headers + // if $this->soap_defencoding is UTF-8. Not doing this automatically allows + // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 + + $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); + $this->debug("headers:"); + $this->appendDebug($this->varDump($headers)); + $this->debug("namespaces:"); + $this->appendDebug($this->varDump($namespaces)); + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($encodingStyle) { + $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; + } + + // serialize headers + if($headers){ + if (is_array($headers)) { + $xml = ''; + foreach ($headers as $header) { + $xml .= $this->serialize_val($header, false, false, false, false, false, $use); + } + $headers = $xml; + $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); + } + $headers = "".$headers.""; + } + // serialize envelope + return + 'soap_defencoding .'"?'.">". + '". + $headers. + "". + $body. + "". + ""; + } + + /** + * formats a string to be inserted into an HTML stream + * + * @param string $str The string to format + * @return string The formatted string + * @access public + * @deprecated + */ + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts (changes namespace to prefix) a qualified name + * + * @param string $qname qname + * @return string contracted qname + * @access private + */ + function contractQname($qname){ + // get element namespace + //$this->xdebug("Contract $qname"); + if (strrpos($qname, ':')) { + // get unqualified name + $name = substr($qname, strrpos($qname, ':') + 1); + // get ns + $ns = substr($qname, 0, strrpos($qname, ':')); + $p = $this->getPrefixFromNamespace($ns); + if ($p) { + return $p . ':' . $name; + } + return $qname; + } else { + return $qname; + } + } + + /** + * expands (changes prefix to namespace) a qualified name + * + * @param string $string qname + * @return string expanded qname + * @access private + */ + function expandQname($qname){ + // get element prefix + if(strpos($qname,':') && !ereg('^http://',$qname)){ + // get unqualified name + $name = substr(strstr($qname,':'),1); + // get ns prefix + $prefix = substr($qname,0,strpos($qname,':')); + if(isset($this->namespaces[$prefix])){ + return $this->namespaces[$prefix].':'.$name; + } else { + return $qname; + } + } else { + return $qname; + } + } + + /** + * returns the local part of a prefixed string + * returns the original string, if not prefixed + * + * @param string $str The prefixed string + * @return string The local part + * @access public + */ + function getLocalPart($str){ + if($sstr = strrchr($str,':')){ + // get unqualified name + return substr( $sstr, 1 ); + } else { + return $str; + } + } + + /** + * returns the prefix part of a prefixed string + * returns false, if not prefixed + * + * @param string $str The prefixed string + * @return mixed The prefix or false if there is no prefix + * @access public + */ + function getPrefix($str){ + if($pos = strrpos($str,':')){ + // get prefix + return substr($str,0,$pos); + } + return false; + } + + /** + * pass it a prefix, it returns a namespace + * + * @param string $prefix The prefix + * @return mixed The namespace, false if no namespace has the specified prefix + * @access public + */ + function getNamespaceFromPrefix($prefix){ + if (isset($this->namespaces[$prefix])) { + return $this->namespaces[$prefix]; + } + //$this->setError("No namespace registered for prefix '$prefix'"); + return false; + } + + /** + * returns the prefix for a given namespace (or prefix) + * or false if no prefixes registered for the given namespace + * + * @param string $ns The namespace + * @return mixed The prefix, false if the namespace has no prefixes + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + /** + * returns the time in ODBC canonical form with microseconds + * + * @return string The time in ODBC canonical form with microseconds + * @access public + */ + function getmicrotime() { + if (function_exists('gettimeofday')) { + $tod = gettimeofday(); + $sec = $tod['sec']; + $usec = $tod['usec']; + } else { + $sec = time(); + $usec = 0; + } + return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); + } + + /** + * Returns a string with the output of var_dump + * + * @param mixed $data The variable to var_dump + * @return string The output of var_dump + * @access public + */ + function varDump($data) { + ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val; + } +} + +// XML Schema Datatype Helper Functions + +//xsd:dateTime helpers + +/** +* convert unix timestamp to ISO 8601 compliant date string +* +* @param string $timestamp Unix time stamp +* @access public +*/ +function timestamp_to_iso8601($timestamp,$utc=true){ + $datestr = date('Y-m-d\TH:i:sO',$timestamp); + if($utc){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + + if(ereg($eregStr,$datestr,$regs)){ + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); + } + return false; + } else { + return $datestr; + } +} + +/** +* convert ISO 8601 compliant date string to unix timestamp +* +* @param string $datestr ISO 8601 compliant date string +* @access public +*/ +function iso8601_to_timestamp($datestr){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + if(ereg($eregStr,$datestr,$regs)){ + // not utc + if($regs[8] != 'Z'){ + $op = substr($regs[8],0,1); + $h = substr($regs[8],1,2); + $m = substr($regs[8],strlen($regs[8])-2,2); + if($op == '-'){ + $regs[4] = $regs[4] + $h; + $regs[5] = $regs[5] + $m; + } elseif($op == '+'){ + $regs[4] = $regs[4] - $h; + $regs[5] = $regs[5] - $m; + } + } + return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); + } else { + return false; + } +} + +/** +* sleeps some number of microseconds +* +* @param string $usec the number of microseconds to sleep +* @access public +* @deprecated +*/ +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_fault_colosa extends nusoap_base_colosa { + /** + * The fault code (client|server) + * @var string + * @access private + */ + var $faultcode; + /** + * The fault actor + * @var string + * @access private + */ + var $faultactor; + /** + * The fault string, a description of the fault + * @var string + * @access private + */ + var $faultstring; + /** + * The fault detail, typically a string or array of string + * @var mixed + * @access private + */ + var $faultdetail; + + /** + * constructor + * + * @param string $faultcode (client | server) + * @param string $faultactor only used when msg routed between multiple actors + * @param string $faultstring human readable error message + * @param mixed $faultdetail detail, typically a string or array of string + */ + function soap_fault_colosa($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + parent::nusoap_base_colosa(); + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @return string The serialization of the fault instance. + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + 'soap_defencoding.'"?>'. + '\n". + ''. + ''. + $this->serialize_val($this->faultcode, 'faultcode'). + $this->serialize_val($this->faultactor, 'faultactor'). + $this->serialize_val($this->faultstring, 'faultstring'). + $this->serialize_val($this->faultdetail, 'detail'). + ''. + ''. + ''; + return $return_msg; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class XMLSchema extends nusoap_base_colosa { + + // files + var $schema = ''; + var $xml = ''; + // namespaces + var $enclosingNamespaces; + // schema info + var $schemaInfo = array(); + var $schemaTargetNamespace = ''; + // types, elements, attributes defined by the schema + var $attributes = array(); + var $complexTypes = array(); + var $complexTypeStack = array(); + var $currentComplexType = null; + var $elements = array(); + var $elementStack = array(); + var $currentElement = null; + var $simpleTypes = array(); + var $simpleTypeStack = array(); + var $currentSimpleType = null; + // imports + var $imports = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + var $message = array(); + var $defaultNamespace = array(); + + /** + * constructor + * + * @param string $schema schema document URI + * @param string $xml xml document URI + * @param string $namespaces namespaces defined in enclosing XML + * @access public + */ + function XMLSchema($schema='',$xml='',$namespaces=array()){ + parent::nusoap_base_colosa(); + $this->debug('xmlschema class instantiated, inside constructor'); + // files + $this->schema = $schema; + $this->xml = $xml; + + // namespaces + $this->enclosingNamespaces = $namespaces; + $this->namespaces = array_merge($this->namespaces, $namespaces); + + // parse schema file + if($schema != ''){ + $this->debug('initial schema file: '.$schema); + $this->parseFile($schema, 'schema'); + } + + // parse xml file + if($xml != ''){ + $this->debug('initial xml file: '.$xml); + $this->parseFile($xml, 'xml'); + } + + } + + /** + * parse an XML file + * + * @param string $xml, path/URL to XML file + * @param string $type, (schema | xml) + * @return boolean + * @access public + */ + function parseFile($xml,$type){ + // parse xml file + if($xml != ""){ + $xmlStr = @join("",@file($xml)); + if($xmlStr == ""){ + $msg = 'Error reading XML from '.$xml; + $this->setError($msg); + $this->debug($msg); + return false; + } else { + $this->debug("parsing $xml"); + $this->parseString($xmlStr,$type); + $this->debug("done parsing $xml"); + return true; + } + } + return false; + } + + /** + * parse an XML string + * + * @param string $xml path or URL + * @param string $type, (schema|xml) + * @access private + */ + function parseString($xml,$type){ + // parse xml string + if($xml != ""){ + + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + + // Set the object for the parser. + xml_set_object($this->parser, $this); + + // Set the element handlers for the parser. + if($type == "schema"){ + xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); + xml_set_character_data_handler($this->parser,'schemaCharacterData'); + } elseif($type == "xml"){ + xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); + xml_set_character_data_handler($this->parser,'xmlCharacterData'); + } + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $errstr = sprintf('XML error parsing XML schema on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $xml); + $this->setError($errstr); + } + + xml_parser_free($this->parser); + } else{ + $this->debug('no xml passed to parseString()!!'); + $this->setError('no xml passed to parseString()!!'); + } + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function schemaStartElement($parser, $name, $attrs) { + + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + if ($depth > 0) { + $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; + } else { + $this->defaultNamespace[$pos] = false; + } + + // get element prefix + if($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + + // loop thru attributes, expanding, and registering namespace declarations + if(count($attrs) > 0){ + foreach($attrs as $k => $v){ + // if ns declarations, add to class level array of valid namespaces + if(ereg("^xmlns",$k)){ + //$this->xdebug("$k: $v"); + //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); + if($ns_prefix = substr(strrchr($k,':'),1)){ + //$this->xdebug("Add namespace[$ns_prefix] = $v"); + $this->namespaces[$ns_prefix] = $v; + } else { + $this->defaultNamespace[$pos] = $v; + if (! $this->getPrefixFromNamespace($v)) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; + } + } + if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v.'-instance'; + } + } + } + foreach($attrs as $k => $v){ + // expand each attribute + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // find status, register data + switch($name){ + case 'all': // (optional) compositor content for a complexType + case 'choice': + case 'group': + case 'sequence': + //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + $this->complexTypes[$this->currentComplexType]['compositor'] = $name; + //if($name == 'all' || $name == 'sequence'){ + // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + //} + break; + case 'attribute': // complexType attribute + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute:"); + $this->appendDebug($this->varDump($attrs)); + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['attributeFormDefault']; + } + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + if (!strpos($v, ':')) { + // no namespace in arrayType attribute value... + if ($this->defaultNamespace[$pos]) { + // ...so use the default + $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } + } + } + if(isset($attrs['name'])){ + $this->attributes[$attrs['name']] = $attrs; + $aname = $attrs['name']; + } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $aname = ''; + } + } elseif(isset($attrs['ref'])){ + $aname = $attrs['ref']; + $this->attributes[$attrs['ref']] = $attrs; + } + + if($this->currentComplexType){ // This should *always* be + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } + // arrayType attribute + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + $prefix = $this->getPrefix($aname); + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $v = ''; + } + if(strpos($v,'[,]')){ + $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; + } + $v = substr($v,0,strpos($v,'[')); // clip the [] + if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ + $v = $this->XMLSchemaVersion.':'.$v; + } + $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; + } + break; + case 'complexContent': // (optional) content for a complexType + break; + case 'complexType': + array_push($this->complexTypeStack, $this->currentComplexType); + if(isset($attrs['name'])){ + $this->xdebug('processing named complexType '.$attrs['name']); + //$this->currentElement = false; + $this->currentComplexType = $attrs['name']; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + }else{ + $this->xdebug('processing unnamed complexType for element '.$this->currentElement); + $this->currentComplexType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + array_push($this->elementStack, $this->currentElement); + // elements defined as part of a complex type should + // not really be added to $this->elements, but for some + // reason, they are + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['elementFormDefault']; + } + if(isset($attrs['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + if (! $this->getPrefix($attrs['type'])) { + if ($this->defaultNamespace[$pos]) { + $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; + $this->xdebug('used default namespace to make type ' . $attrs['type']); + } + } + // This is for constructs like + // + // + // + // + // + if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { + $this->xdebug('arrayType for unusual array is ' . $attrs['type']); + $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; + } + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $this->xdebug("processing element as ref to ".$attrs['ref']); + $this->currentElement = "ref to ".$attrs['ref']; + $ename = $this->getLocalPart($attrs['ref']); + } else { + $this->xdebug("processing untyped element ".$attrs['name']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; + $ename = $attrs['name']; + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + case 'enumeration': // restriction value list member + $this->xdebug('enumeration ' . $attrs['value']); + if ($this->currentSimpleType) { + $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; + } elseif ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; + } + break; + case 'extension': // simpleContent or complexContent type extension + $this->xdebug('extension ' . $attrs['base']); + if ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; + } + break; + case 'import': + if (isset($attrs['schemaLocation'])) { + //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); + $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); + } else { + //$this->xdebug('import namespace ' . $attrs['namespace']); + $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + } + break; + case 'list': // simpleType value list + break; + case 'restriction': // simpleType, simpleContent or complexContent value restriction + $this->xdebug('restriction ' . $attrs['base']); + if($this->currentSimpleType){ + $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; + } elseif($this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; + if(strstr($attrs['base'],':') == ':Array'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } + } + break; + case 'schema': + $this->schemaInfo = $attrs; + $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); + if (isset($attrs['targetNamespace'])) { + $this->schemaTargetNamespace = $attrs['targetNamespace']; + } + if (!isset($attrs['elementFormDefault'])) { + $this->schemaInfo['elementFormDefault'] = 'unqualified'; + } + if (!isset($attrs['attributeFormDefault'])) { + $this->schemaInfo['attributeFormDefault'] = 'unqualified'; + } + break; + case 'simpleContent': // (optional) content for a complexType + break; + case 'simpleType': + array_push($this->simpleTypeStack, $this->currentSimpleType); + if(isset($attrs['name'])){ + $this->xdebug("processing simpleType for name " . $attrs['name']); + $this->currentSimpleType = $attrs['name']; + $this->simpleTypes[ $attrs['name'] ] = $attrs; + $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; + $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; + } else { + $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); + $this->currentSimpleType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->simpleTypes[$this->currentSimpleType] = $attrs; + $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; + } + break; + case 'union': // simpleType type list + break; + default: + //$this->xdebug("do not have anything to do for element $name"); + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function schemaEndElement($parser, $name) { + // bring depth down a notch + $this->depth--; + // position of current element is equal to the last value left in depth_array for my depth + if(isset($this->depth_array[$this->depth])){ + $pos = $this->depth_array[$this->depth]; + } + // get element prefix + if ($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + // move on... + if($name == 'complexType'){ + $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); + $this->currentComplexType = array_pop($this->complexTypeStack); + //$this->currentElement = false; + } + if($name == 'element'){ + $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); + $this->currentElement = array_pop($this->elementStack); + } + if($name == 'simpleType'){ + $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); + $this->currentSimpleType = array_pop($this->simpleTypeStack); + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function schemaCharacterData($parser, $data){ + $pos = $this->depth_array[$this->depth - 1]; + $this->message[$pos]['cdata'] .= $data; + } + + /** + * serialize the schema + * + * @access public + */ + function serializeSchema(){ + + $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); + $xml = ''; + // imports + if (sizeof($this->imports) > 0) { + foreach($this->imports as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; + } else { + $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; + } + } + } + } + // complex types + foreach($this->complexTypes as $typeName => $attrs){ + $contentStr = ''; + // serialize child elements + if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ + foreach($attrs['elements'] as $element => $eParts){ + if(isset($eParts['ref'])){ + $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; + } else { + $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; + foreach ($eParts as $aName => $aValue) { + // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable + if ($aName != 'name' && $aName != 'type') { + $contentStr .= " $aName=\"$aValue\""; + } + } + $contentStr .= "/>\n"; + } + } + // compositor wraps elements + if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." \n"; + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute"; + foreach ($aParts as $a => $v) { + if ($a == 'ref' || $a == 'type') { + $contentStr .= " $a=\"".$this->contractQName($v).'"'; + } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; + } else { + $contentStr .= " $a=\"$v\""; + } + } + $contentStr .= "/>\n"; + } + } + // if restriction + if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." \n"; + // complex or simple content + if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." \n"; + } + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." \n"; + } else { + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; + } + $xml .= $contentStr; + } + // simple types + if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ + foreach($this->simpleTypes as $typeName => $eParts){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; + if (isset($eParts['enumeration'])) { + foreach ($eParts['enumeration'] as $e) { + $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; + } + } + $xml .= " "; + } + } + // elements + if(isset($this->elements) && count($this->elements) > 0){ + foreach($this->elements as $element => $eParts){ + $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; + } + } + // attributes + if(isset($this->attributes) && count($this->attributes) > 0){ + foreach($this->attributes as $attr => $aParts){ + $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; + } + } + // finish 'er up + $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; + foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { + $el .= " xmlns:$nsp=\"$ns\"\n"; + } + $xml = $el . ">\n".$xml."\n"; + return $xml; + } + + /** + * adds debug data to the clas level debug string + * + * @param string $string debug data + * @access private + */ + function xdebug($string){ + $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); + } + + /** + * get the PHP type of a user defined type in the schema + * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays + * returns false if no type exists, or not w/ the given namespace + * else returns a string that is either a native php type, or 'struct' + * + * @param string $type, name of defined type + * @param string $ns, namespace of type + * @return mixed + * @access public + * @deprecated + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap
    "; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array
    "; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * returns an associative array of information about a given type + * returns false if no type exists by the given name + * + * For a complexType typeDef = array( + * 'restrictionBase' => '', + * 'phpType' => '', + * 'compositor' => '(sequence|all)', + * 'elements' => array(), // refs to elements array + * 'attrs' => array() // refs to attributes array + * ... and so on (see addComplexType) + * ) + * + * For simpleType or element, the array has different keys. + * + * @param string + * @return mixed + * @access public + * @see addComplexType + * @see addSimpleType + * @see addElement + */ + function getTypeDef($type){ + //$this->debug("in getTypeDef for type $type"); + if(isset($this->complexTypes[$type])){ + $this->xdebug("in getTypeDef, found complexType $type"); + return $this->complexTypes[$type]; + } elseif(isset($this->simpleTypes[$type])){ + $this->xdebug("in getTypeDef, found simpleType $type"); + if (!isset($this->simpleTypes[$type]['phpType'])) { + // get info for type to tack onto the simple type + // TODO: can this ever really apply (i.e. what is a simpleType really?) + $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); + $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for simpleType $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->simpleTypes[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->simpleTypes[$type]['elements'] = $etype['elements']; + } + } + } + return $this->simpleTypes[$type]; + } elseif(isset($this->elements[$type])){ + $this->xdebug("in getTypeDef, found element $type"); + if (!isset($this->elements[$type]['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); + $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for element $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->elements[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->elements[$type]['elements'] = $etype['elements']; + } + } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { + $this->xdebug("in getTypeDef, element $type is an XSD type"); + $this->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } elseif (ereg('_ContainedType$', $type)) { + $this->xdebug("in getTypeDef, have an untyped element $type"); + $typeDef['typeClass'] = 'simpleType'; + $typeDef['phpType'] = 'scalar'; + $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; + return $typeDef; + } + $this->xdebug("in getTypeDef, did not find $type"); + return false; + } + + /** + * returns a sample serialization of a given type, or false if no type by the given name + * + * @param string $type, name of type + * @return mixed + * @access public + * @deprecated + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type
    "; + if($typeDef = $this->getTypeDef($type)){ + $str .= '<'.$type; + if(is_array($typeDef['attrs'])){ + foreach($attrs as $attName => $data){ + $str .= " $attName=\"{type = ".$data['type']."}\""; + } + } + $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; + if(count($typeDef['elements']) > 0){ + $str .= ">"; + foreach($typeDef['elements'] as $element => $eData){ + $str .= $this->serializeTypeDef($element); + } + $str .= ""; + } elseif($typeDef['typeClass'] == 'element') { + $str .= ">"; + } else { + $str .= "/>"; + } + return $str; + } + return false; + } + + /** + * returns HTML form elements that allow a user + * to enter values for creating an instance of the given type. + * + * @param string $name, name for type instance + * @param string $type, name of type + * @return string + * @access public + * @deprecated + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= ''; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + + "; + } + $buffer .= '
    $childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):
    '; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= ''; + for($i=0;$i < 3; $i++){ + $buffer .= " + + "; + } + $buffer .= '
    array item (type: $typeDef[arrayType]):
    '; + // if scalar + } else { + $buffer .= ""; + } + } else { + $buffer .= ""; + } + return $buffer; + } + + /** + * adds a complex type to the schema + * + * example: array + * + * addType( + * 'ArrayOfstring', + * 'complexType', + * 'array', + * '', + * 'SOAP-ENC:Array', + * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), + * 'xsd:string' + * ); + * + * example: PHP associative array ( SOAP Struct ) + * + * addType( + * 'SOAPStruct', + * 'complexType', + * 'struct', + * 'all', + * array('myVar'=> array('name'=>'myVar','type'=>'string') + * ); + * + * @param name + * @param typeClass (complexType|simpleType|attribute) + * @param phpType: currently supported are array and struct (php assoc array) + * @param compositor (all|sequence|choice) + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param elements = array ( name = array(name=>'',type=>'') ) + * @param attrs = array( + * array( + * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", + * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" + * ) + * ) + * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) + * @access public + * @see getTypeDef + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ + $this->complexTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'compositor'=> $compositor, + 'restrictionBase' => $restrictionBase, + 'elements' => $elements, + 'attrs' => $attrs, + 'arrayType' => $arrayType + ); + + $this->xdebug("addComplexType $name:"); + $this->appendDebug($this->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @access public + * @see xmlschema + * @see getTypeDef + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase, + 'enumeration' => $enumeration + ); + + $this->xdebug("addSimpleType $name:"); + $this->appendDebug($this->varDump($this->simpleTypes[$name])); + } + + /** + * adds an element to the schema + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + if (! $this->getPrefix($attrs['type'])) { + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; + } + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + + $this->xdebug("addElement " . $attrs['name']); + $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soapval extends nusoap_base_colosa { + /** + * The XML element name + * + * @var string + * @access private + */ + var $name; + /** + * The XML type name (string or false) + * + * @var mixed + * @access private + */ + var $type; + /** + * The PHP value + * + * @var mixed + * @access private + */ + var $value; + /** + * The XML element namespace (string or false) + * + * @var mixed + * @access private + */ + var $element_ns; + /** + * The XML type namespace (string or false) + * + * @var mixed + * @access private + */ + var $type_ns; + /** + * The XML element attributes (array or false) + * + * @var mixed + * @access private + */ + var $attributes; + + /** + * constructor + * + * @param string $name optional name + * @param mixed $type optional type name + * @param mixed $value optional value + * @param mixed $element_ns optional namespace of value + * @param mixed $type_ns optional namespace of type + * @param mixed $attributes associative array of attributes to add to element serialization + * @access public + */ + function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { + parent::nusoap_base_colosa(); + $this->name = $name; + $this->type = $type; + $this->value = $value; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @param string $use The WSDL use value (encoded|literal) + * @return string XML data + * @access public + */ + function serialize($use='encoded') { + return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); + } + + /** + * decodes a soapval object into a PHP native type + * + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_transport_http extends nusoap_base_colosa { + + var $url = ''; + var $uri = ''; + var $digest_uri = ''; + var $scheme = ''; + var $host = ''; + var $port = ''; + var $path = ''; + var $request_method = 'POST'; + var $protocol_version = '1.0'; + var $encoding = ''; + var $outgoing_headers = array(); + var $incoming_headers = array(); + var $incoming_cookies = array(); + var $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username = ''; + var $password = ''; + var $authtype = ''; + var $digestRequest = array(); + var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) + // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' + // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' + // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' + // passphrase: SSL key password/passphrase + // verifypeer: default is 1 + // verifyhost: default is 1 + + /** + * constructor + */ + function soap_transport_http($url){ + parent::nusoap_base_colosa(); + $this->setURL($url); + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); + } + + function setURL($url) { + $this->url = $url; + + $u = parse_url($url); + foreach($u as $k => $v){ + $this->debug("$k = $v"); + $this->$k = $v; + } + + // add any GET params to path + if(isset($u['query']) && $u['query'] != ''){ + $this->path .= '?' . $u['query']; + } + + // set default port + if(!isset($u['port'])){ + if($u['scheme'] == 'https'){ + $this->port = 443; + } else { + $this->port = 80; + } + } + + $this->uri = $this->path; + $this->digest_uri = $this->uri; + + // build headers + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + $this->debug('set Host: ' . $this->outgoing_headers['Host']); + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); + } + } + + function connect($connection_timeout=0,$response_timeout=30){ + // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like + // "regular" socket. + // TODO: disabled for now because OpenSSL must be *compiled* in (not just + // loaded), and until PHP5 stream_get_wrappers is not available. +// if ($this->scheme == 'https') { +// if (version_compare(phpversion(), '4.3.0') >= 0) { +// if (extension_loaded('openssl')) { +// $this->scheme = 'ssl'; +// $this->debug('Using SSL over OpenSSL'); +// } +// } +// } + $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // use persistent connection + if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ + if (!feof($this->fp)) { + $this->debug('Re-use persistent connection'); + return true; + } + fclose($this->fp); + $this->debug('Closed persistent connection at EOF'); + } + + // munge host if using OpenSSL + if ($this->scheme == 'ssl') { + $host = 'ssl://' . $this->host; + } else { + $host = $this->host; + } + $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); + + // open socket + if($connection_timeout > 0){ + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); + } else { + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); + } + + // test pointer + if(!$this->fp) { + $msg = 'Couldn\'t open socket connection to server ' . $this->url; + if ($this->errno) { + $msg .= ', Error ('.$this->errno.'): '.$this->error_str; + } else { + $msg .= ' prior to connect(). This is often a problem looking up the host name.'; + } + $this->debug($msg); + $this->setError($msg); + return false; + } + + // set response timeout + $this->debug('set response timeout to ' . $response_timeout); + socket_set_timeout( $this->fp, $response_timeout); + + $this->debug('socket connected'); + return true; + } else if ($this->scheme == 'https') { + if (!extension_loaded('curl')) { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + return false; + } + $this->debug('connect using https'); + // init CURL + $this->ch = curl_init(); + // set url + $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; + // add path + $hostURL .= $this->path; + curl_setopt($this->ch, CURLOPT_URL, $hostURL); + // follow location headers (re-directs) + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); + // ask for headers in the response output + curl_setopt($this->ch, CURLOPT_HEADER, 1); + // ask for the response output as the return value + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + // encode + // We manage this ourselves through headers and encoding +// if(function_exists('gzuncompress')){ +// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); +// } + // persistent connection + if ($this->persistentConnection) { + // The way we send data, we cannot use persistent connections, since + // there will be some "junk" at the end of our request. + //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); + $this->persistentConnection = false; + $this->outgoing_headers['Connection'] = 'close'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + // set timeout + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); + } + // TODO: cURL has added a connection timeout separate from the response timeout + //if ($connection_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); + //} + //if ($response_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); + //} + + // recent versions of cURL turn on peer/host checking by default, + // while PHP binaries are not compiled with a default location for the + // CA cert bundle, so disable peer/host checking. +//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); + + // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) + if ($this->authtype == 'certificate') { + if (isset($this->certRequest['cainfofile'])) { + curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); + } + if (isset($this->certRequest['verifypeer'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + } + if (isset($this->certRequest['verifyhost'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + } + if (isset($this->certRequest['sslcertfile'])) { + curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); + } + if (isset($this->certRequest['sslkeyfile'])) { + curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); + } + if (isset($this->certRequest['passphrase'])) { + curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); + } + } + $this->debug('cURL connection set up'); + return true; + } else { + $this->setError('Unknown scheme ' . $this->scheme); + $this->debug('Unknown scheme ' . $this->scheme); + return false; + } + } + + /** + * send the SOAP message via HTTP + * + * @param string $data message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { + + $this->debug('entered send() with data of length: '.strlen($data)); + + $this->tryagain = true; + $tries = 0; + while ($this->tryagain) { + $this->tryagain = false; + if ($tries++ < 2) { + // make connnection + if (!$this->connect($timeout, $response_timeout)){ + return false; + } + + // send request + if (!$this->sendRequest($data, $cookies)){ + return false; + } + + // get response + $respdata = $this->getResponse(); + } else { + $this->setError('Too many tries to get an OK response'); + } + } + $this->debug('end of send()'); + return $respdata; + } + + + /** + * send the SOAP message via HTTPS 1.0 using CURL + * + * @param string $msg message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { + return $this->send($data, $timeout, $response_timeout, $cookies); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic, digest, certificate) + * @param array $digestRequest (keys must be nonce, nc, realm, qop) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); + } elseif ($authtype == 'digest') { + if (isset($digestRequest['nonce'])) { + $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; + + // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) + + // A1 = unq(username-value) ":" unq(realm-value) ":" passwd + $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->digest_uri; + + // H(A2) + $HA2 = md5($A2); + + // KD(secret, data) = H(concat(secret, ":", data)) + // if qop == auth: + // request-digest = <"> < KD ( H(A1), unq(nonce-value) + // ":" nc-value + // ":" unq(cnonce-value) + // ":" unq(qop-value) + // ":" H(A2) + // ) <"> + // if qop is missing, + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> + + $unhashedDigest = ''; + $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; + $cnonce = $nonce; + if ($digestRequest['qop'] != '') { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; + } else { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; + } + + $hashedDigest = md5($unhashedDigest); + + $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } elseif ($authtype == 'certificate') { + $this->certRequest = $certRequest; + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); + } else { + $this->debug('Authorization header not set'); + } + } + + /** + * set the soapaction value + * + * @param string $soapaction + * @access public + */ + function setSOAPAction($soapaction) { + $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; + $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate') { + if (function_exists('gzdeflate')) { + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); + if (!isset($this->outgoing_headers['Connection'])) { + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + set_magic_quotes_runtime(0); + // deprecated + $this->encoding = $enc; + } + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->uri = $this->url; + $this->host = $proxyhost; + $this->port = $proxyport; + if ($proxyusername != '' && $proxypassword != '') { + $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); + $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); + } + } + + /** + * decode a string that is encoded w/ "chunked' transfer encoding + * as defined in RFC2068 19.4.6 + * + * @param string $buffer + * @param string $lb + * @returns string + * @access public + * @deprecated + */ + function decodeChunked($buffer, $lb){ + // length := 0 + $length = 0; + $new = ''; + + // read chunk-size, chunk-extension (if any) and CRLF + // get the position of the linebreak + $chunkend = strpos($buffer, $lb); + if ($chunkend == FALSE) { + $this->debug('no linebreak found in decodeChunked'); + return $new; + } + $temp = substr($buffer,0,$chunkend); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend + strlen($lb); + // while (chunk-size > 0) { + while ($chunk_size > 0) { + $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); + $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); + + // Just in case we got a broken connection + if ($chunkend == FALSE) { + $chunk = substr($buffer,$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + $length += strlen($chunk); + break; + } + + // read chunk-data and CRLF + $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + // length := length + chunk-size + $length += strlen($chunk); + // read chunk-size and CRLF + $chunkstart = $chunkend + strlen($lb); + + $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); + if ($chunkend == FALSE) { + break; //Just in case we got a broken connection + } + $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend; + } + return $new; + } + + /* + * Writes payload, including HTTP headers, to $this->outgoing_payload. + */ + function buildPayload($data, $cookie_str = '') { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); + + // start building outgoing payload: + $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; + $this->debug("HTTP request: $req"); + $this->outgoing_payload = "$req\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $hdr = $k.': '.$v; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // add any cookies + if ($cookie_str != '') { + $hdr = 'Cookie: '.$cookie_str; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data, $cookies = NULL) { + // build cookie string + $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); + + // build payload + $this->buildPayload($data, $cookie_str); + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // send payload + if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + $this->setError('couldn\'t write message data to socket'); + $this->debug('couldn\'t write message data to socket'); + return false; + } + $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); + return true; + } else if ($this->scheme == 'https') { + // set payload + // TODO: cURL does say this should only be the verb, and in fact it + // turns out that the URI and HTTP version are appended to this, which + // some servers refuse to work with + //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); + foreach($this->outgoing_headers as $k => $v){ + $curl_headers[] = "$k: $v"; + } + if ($cookie_str != '') { + $curl_headers[] = 'Cookie: ' . $cookie_str; + } + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); + if ($this->request_method == "POST") { + curl_setopt($this->ch, CURLOPT_POST, 1); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); + } else { + } + $this->debug('set cURL payload'); + return true; + } + } + + function getResponse(){ + $this->incoming_payload = ''; + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // loop until headers have been retrieved + $data = ''; + while (!isset($lb)){ + + // We might EOF during header read. + if(feof($this->fp)) { + $this->incoming_payload = $data; + $this->debug('found no headers before EOF after length ' . strlen($data)); + $this->debug("received before EOF:\n" . $data); + $this->setError('server failed to send headers'); + return false; + } + + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read line of $tmplen bytes: " . trim($tmp)); + + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of headers timed out after length ' . strlen($data)); + $this->debug("read before timeout: " . $data); + $this->setError('socket read of headers timed out'); + return false; + } + + $data .= $tmp; + $pos = strpos($data,"\r\n\r\n"); + if($pos > 1){ + $lb = "\r\n"; + } else { + $pos = strpos($data,"\n\n"); + if($pos > 1){ + $lb = "\n"; + } + } + // remove 100 header + if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ + unset($lb); + $data = ''; + }// + } + // store header data + $this->incoming_payload .= $data; + $this->debug('found end of headers after length ' . strlen($data)); + // process headers + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $this->incoming_headers = array(); + $this->incoming_cookies = array(); + foreach($header_array as $header_line){ + $arr = explode(':',$header_line, 2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $content_length = 2147483647; // ignore any content-length header + $chunked = true; + $this->debug("want to read chunked content"); + } elseif (isset($this->incoming_headers['content-length'])) { + $content_length = $this->incoming_headers['content-length']; + $chunked = false; + $this->debug("want to read content of length $content_length"); + } else { + $content_length = 2147483647; + $chunked = false; + $this->debug("want to read content to EOF"); + } + $data = ''; + do { + if ($chunked) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk line of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk length timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk length timed out'); + return false; + } + $content_length = hexdec(trim($tmp)); + $this->debug("chunk length $content_length"); + } + $strlen = 0; + while (($strlen < $content_length) && (!feof($this->fp))) { + $readlen = min(8192, $content_length - $strlen); + $tmp = fread($this->fp, $readlen); + $tmplen = strlen($tmp); + $this->debug("read buffer of $tmplen bytes"); + if (($tmplen == 0) && (!feof($this->fp))) { + $this->incoming_payload = $data; + $this->debug('socket read of body timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of body timed out'); + return false; + } + $strlen += $tmplen; + $data .= $tmp; + } + if ($chunked && ($content_length > 0)) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk terminator of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk terminator timed out'); + return false; + } + } + } while ($chunked && ($content_length > 0) && (!feof($this->fp))); + if (feof($this->fp)) { + $this->debug('read to EOF'); + } + $this->debug('read body of length ' . strlen($data)); + $this->incoming_payload .= $data; + $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); + + // close filepointer + if( + (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || + (! $this->persistentConnection) || feof($this->fp)){ + fclose($this->fp); + $this->fp = false; + $this->debug('closed socket'); + } + + // connection was closed unexpectedly + if($this->incoming_payload == ''){ + $this->setError('no response from server'); + return false; + } + + // decode transfer-encoding +// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ +// if(!$data = $this->decodeChunked($data, $lb)){ +// $this->setError('Decoding of chunked data failed'); +// return false; +// } + //print "
    \nde-chunked:\n---------------\n$data\n\n---------------\n
    "; + // set decoded payload +// $this->incoming_payload = $header_data.$lb.$lb.$data; +// } + + } else if ($this->scheme == 'https') { + // send and receive + $this->debug('send and receive with cURL'); + $this->incoming_payload = curl_exec($this->ch); + $data = $this->incoming_payload; + + $cErr = curl_error($this->ch); + if ($cErr != '') { + $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'
    '; + // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v
    "; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '
    ';
    +			//var_dump(curl_getinfo($this->ch));
    +			//echo '
    '; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header(s) + while (ereg('^HTTP/1.1 100',$data)) { + if ($pos = strpos($data,"\r\n\r\n")) { + $data = ltrim(substr($data,$pos)); + } elseif($pos = strpos($data,"\n\n") ) { + $data = ltrim(substr($data,$pos)); + } + } + + // separate content from HTTP headers + if ($pos = strpos($data,"\r\n\r\n")) { + $lb = "\r\n"; + } elseif( $pos = strpos($data,"\n\n")) { + $lb = "\n"; + } else { + $this->debug('no proper separation of headers and document'); + $this->setError('no proper separation of headers and document'); + return false; + } + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $data = ltrim(substr($data,$pos)); + $this->debug('found proper separation of headers and document'); + $this->debug('cleaned data, stringlen: '.strlen($data)); + // clean headers + foreach ($header_array as $header_line) { + $arr = explode(':',$header_line,2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + } + + $arr = explode(' ', $header_array[0], 3); + $http_version = $arr[0]; + $http_status = intval($arr[1]); + $http_reason = count($arr) > 2 ? $arr[2] : ''; + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['location']) && $http_status == 301) { + $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); + $this->setURL($this->incoming_headers['location']); + $this->tryagain = true; + return false; + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { + $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); + if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { + $this->debug('Server wants digest authentication'); + // remove "Digest " from our elements + $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); + + // parse elements into array + $digestElements = explode(',', $digestString); + foreach ($digestElements as $val) { + $tempElement = explode('=', trim($val), 2); + $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); + } + + // should have (at least) qop, realm, nonce + if (isset($digestRequest['nonce'])) { + $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); + $this->tryagain = true; + return false; + } + } + $this->debug('HTTP authentication failed'); + $this->setError('HTTP authentication failed'); + return false; + } + + if ( + ($http_status >= 300 && $http_status <= 307) || + ($http_status >= 400 && $http_status <= 417) || + ($http_status >= 501 && $http_status <= 505) + ) { + $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); + return false; + } + + // decode content-encoding + if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ + if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ + // if decoding works, use it. else assume data wasn't gzencoded + if(function_exists('gzinflate')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) + // this means there are no Zlib headers, although there should be + $this->debug('The gzinflate function exists'); + $datalen = strlen($data); + if ($this->incoming_headers['content-encoding'] == 'deflate') { + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The inflated payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to inflate the payload'); + $this->setError('Error using gzinflate to inflate the payload'); + } + } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { + if ($degzdata = @gzinflate(substr($data, 10))) { // do our best + $data = $degzdata; + $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to un-gzip the payload'); + $this->setError('Error using gzinflate to un-gzip the payload'); + } + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "\nde-inflated:\n---------------\n$data\n-------------\n"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + } + } else { + $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + } + } else { + $this->debug('No Content-Encoding header'); + } + + if(strlen($data) == 0){ + $this->debug('no data after headers!'); + $this->setError('no data present after HTTP headers'); + return false; + } + + return $data; + } + + function setContentType($type, $charset = false) { + $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); + $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); + } + + function usePersistentConnection(){ + if (isset($this->outgoing_headers['Accept-Encoding'])) { + return false; + } + $this->protocol_version = '1.1'; + $this->persistentConnection = true; + $this->outgoing_headers['Connection'] = 'Keep-Alive'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + return true; + } + + /** + * parse an incoming Cookie into it's parts + * + * @param string $cookie_str content of cookie + * @return array with data of that cookie + * @access private + */ + /* + * TODO: allow a Set-Cookie string to be parsed into multiple cookies + */ + function parseCookie($cookie_str) { + $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; + $data = split(';', $cookie_str); + $value_str = $data[0]; + + $cookie_param = 'domain='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $domain = substr($cookie_str, $start + strlen($cookie_param)); + $domain = substr($domain, 0, strpos($domain, ';')); + } else { + $domain = ''; + } + + $cookie_param = 'expires='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $expires = substr($cookie_str, $start + strlen($cookie_param)); + $expires = substr($expires, 0, strpos($expires, ';')); + } else { + $expires = ''; + } + + $cookie_param = 'path='; + $start = strpos($cookie_str, $cookie_param); + if ( $start > 0 ) { + $path = substr($cookie_str, $start + strlen($cookie_param)); + $path = substr($path, 0, strpos($path, ';')); + } else { + $path = '/'; + } + + $cookie_param = ';secure;'; + if (strpos($cookie_str, $cookie_param) !== FALSE) { + $secure = true; + } else { + $secure = false; + } + + $sep_pos = strpos($value_str, '='); + + if ($sep_pos) { + $name = substr($value_str, 0, $sep_pos); + $value = substr($value_str, $sep_pos + 1); + $cookie= array( 'name' => $name, + 'value' => $value, + 'domain' => $domain, + 'path' => $path, + 'expires' => $expires, + 'secure' => $secure + ); + return $cookie; + } + return false; + } + + /** + * sort out cookies for the current request + * + * @param array $cookies array with all cookies + * @param boolean $secure is the send-content secure or not? + * @return string for Cookie-HTTP-Header + * @access private + */ + function getCookiesForRequest($cookies, $secure=false) { + $cookie_str = ''; + if ((! is_null($cookies)) && (is_array($cookies))) { + foreach ($cookies as $cookie) { + if (! is_array($cookie)) { + continue; + } + $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) <= time()) { + $this->debug('cookie has expired'); + continue; + } + } + if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { + $domain = preg_quote($cookie['domain']); + if (! preg_match("'.*$domain$'i", $this->host)) { + $this->debug('cookie has different domain'); + continue; + } + } + if ((isset($cookie['path'])) && (! empty($cookie['path']))) { + $path = preg_quote($cookie['path']); + if (! preg_match("'^$path.*'i", $this->path)) { + $this->debug('cookie is for a different path'); + continue; + } + } + if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { + $this->debug('cookie is secure, transport is not'); + continue; + } + $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; + $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); + } + } + return $cookie_str; + } +} + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_server_colosa extends nusoap_base_colosa { + /** + * HTTP headers of request + * @var array + * @access private + */ + var $headers = array(); + /** + * HTTP request + * @var string + * @access private + */ + var $request = ''; + /** + * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $requestHeaders = ''; + /** + * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $document = ''; + /** + * SOAP payload for request (text) + * @var string + * @access public + */ + var $requestSOAP = ''; + /** + * requested method namespace URI + * @var string + * @access private + */ + var $methodURI = ''; + /** + * name of method requested + * @var string + * @access private + */ + var $methodname = ''; + /** + * method parameters from request + * @var array + * @access private + */ + var $methodparams = array(); + /** + * SOAP Action from request + * @var string + * @access private + */ + var $SOAPAction = ''; + /** + * character set encoding of incoming (request) messages + * @var string + * @access public + */ + var $xml_encoding = ''; + /** + * toggles whether the parser decodes element content w/ utf8_decode() + * @var boolean + * @access public + */ + var $decode_utf8 = true; + + /** + * HTTP headers of response + * @var array + * @access public + */ + var $outgoing_headers = array(); + /** + * HTTP response + * @var string + * @access private + */ + var $response = ''; + /** + * SOAP headers for response (text) + * @var string + * @access public + */ + var $responseHeaders = ''; + /** + * SOAP payload for response (text) + * @var string + * @access private + */ + var $responseSOAP = ''; + /** + * method return value to place in response + * @var mixed + * @access private + */ + var $methodreturn = false; + /** + * whether $methodreturn is a string of literal XML + * @var boolean + * @access public + */ + var $methodreturnisliteralxml = false; + /** + * SOAP fault for response (or false) + * @var mixed + * @access private + */ + var $fault = false; + /** + * text indication of result (for debugging) + * @var string + * @access private + */ + var $result = 'successful'; + + /** + * assoc array of operations => opData; operations are added by the register() + * method or by parsing an external WSDL definition + * @var array + * @access private + */ + var $operations = array(); + /** + * wsdl instance (if one) + * @var mixed + * @access private + */ + var $wsdl = false; + /** + * URL for WSDL (if one) + * @var mixed + * @access private + */ + var $externalWSDLURL = false; + /** + * whether to append debug to response as XML comment + * @var boolean + * @access public + */ + var $debug_flag = false; + + + /** + * constructor + * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. + * + * @param mixed $wsdl file path or URL (string), or wsdl instance (object) + * @access public + */ + function soap_server_colosa($wsdl=false){ + parent::nusoap_base_colosa(); + // turn on debugging? + global $debug; + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $this->debug("_SERVER is defined:"); + $this->appendDebug($this->varDump($_SERVER)); + } elseif (isset($HTTP_SERVER_VARS)) { + $this->debug("HTTP_SERVER_VARS is defined:"); + $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); + } else { + $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); + } + + if (isset($debug)) { + $this->debug("In soap_server, set debug_flag=$debug based on global flag"); + $this->debug_flag = $debug; + } elseif (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); + $this->debug_flag = substr($v, 6); + } + } + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); + $this->debug_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + $this->debug("In soap_server, WSDL is specified"); + if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { + $this->wsdl = $wsdl; + $this->externalWSDLURL = $this->wsdl->wsdl; + $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); + } else { + $this->debug('Create wsdl from ' . $wsdl); + $this->wsdl = new wsdl($wsdl); + $this->externalWSDLURL = $wsdl; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($err = $this->wsdl->getError()){ + die('WSDL ERROR: '.$err); + } + } + } + + /** + * processes request and returns response + * + * @param string $data usually is the value of $HTTP_RAW_POST_DATA + * @access public + */ + function service($data){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER['QUERY_STRING'])) { + $qs = $_SERVER['QUERY_STRING']; + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = $HTTP_SERVER_VARS['QUERY_STRING']; + } else { + $qs = ''; + } + $this->debug("In service, query string=$qs"); + + if (ereg('wsdl', $qs) ){ + $this->debug("In service, this is a request for WSDL"); + if($this->externalWSDLURL){ + if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL + header('Location: '.$this->externalWSDLURL); + } else { // assume file + header("Content-Type: text/xml\r\n"); + $fp = fopen($this->externalWSDLURL, 'r'); + fpassthru($fp); + } + } elseif ($this->wsdl) { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize($this->debug_flag); + if ($this->debug_flag) { + $this->debug('wsdl:'); + $this->appendDebug($this->varDump($this->wsdl)); + print $this->getDebugAsXMLComment(); + } + } else { + header("Content-Type: text/html; charset=ISO-8859-1\r\n"); + print "This service does not provide WSDL"; + } + } elseif ($data == '' && $this->wsdl) { + $this->debug("In service, there is no data, so return Web description"); + print $this->wsdl->webDescription(); + } else { + $this->debug("In service, invoke the request"); + $this->parse_request($data); + if (! $this->fault) { + $this->invoke_method(); + } + if (! $this->fault) { + $this->serialize_return(); + } + $this->send_response(); + } + } + + /** + * parses HTTP request headers. + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * + * @access private + */ + function parse_http_headers() { + global $HTTP_SERVER_VARS; + + $this->request = ''; + $this->SOAPAction = ''; + if(function_exists('getallheaders')){ + $this->debug("In parse_http_headers, use getallheaders"); + $headers = getallheaders(); + foreach($headers as $k=>$v){ + $k = strtolower($k); + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + // get SOAPAction header + if(isset($this->headers['soapaction'])){ + $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); + } + // get the character encoding of the incoming request + if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ + $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + $this->debug("In parse_http_headers, use _SERVER"); + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } else { + $this->debug("In parse_http_headers, HTTP headers not accessible"); + $this->setError("HTTP headers not accessible"); + } + } + + /** + * parses a request + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * request + * requestSOAP + * methodURI + * methodname + * methodparams + * requestHeaders + * document + * + * This sets the fault field on error + * + * @param string $data XML string + * @access private + */ + function parse_request($data='') { + $this->debug('entering parse_request()'); + $this->parse_http_headers(); + $this->debug('got character encoding: '.$this->xml_encoding); + // uncompress if necessary + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { + $this->debug('got content encoding: ' . $this->headers['content-encoding']); + if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzuncompress')) { + if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { + $data = $degzdata; + } else { + $this->fault('Client', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Client', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $data = $this->parseRequest($this->headers, $data); + $this->requestSOAP = $data; + $this->debug('leaving parse_request'); + } + + /** + * invokes a PHP function for the requested SOAP method + * + * The following fields are set by this function (when successful) + * + * methodreturn + * + * Note that the PHP function that is called may also set the following + * fields to affect the response sent to the client + * + * responseHeaders + * outgoing_headers + * + * This sets the fault field on error + * + * @access private + */ + function invoke_method() { + $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); + + if ($this->wsdl) { + if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { + $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { + // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element + $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + $this->methodname = $this->opData['name']; + } else { + $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); + $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); + return; + } + } else { + $this->debug('in invoke_method, no WSDL to validate method'); + } + + // if a . is present in $this->methodname, we see if there is a class in scope, + // which could be referred to. We will also distinguish between two deliminators, + // to allow methods to be called a the class or an instance + $class = ''; + $method = ''; + if (strpos($this->methodname, '..') > 0) { + $delim = '..'; + } else if (strpos($this->methodname, '.') > 0) { + $delim = '.'; + } else { + $delim = ''; + } + + if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && + class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { + // get the class and method name + $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); + $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); + $this->debug("in invoke_method, class=$class method=$method delim=$delim"); + } + + // does method exist? + if ($class == '') { + if (!function_exists($this->methodname)) { + $this->debug("in invoke_method, function '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } else { + $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; + if (!in_array($method_to_compare, get_class_methods($class))) { + $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } + + // evaluate message, getting back parameters + // verify that request parameters match the method's signature + if(! $this->verify_method($this->methodname,$this->methodparams)){ + // debug + $this->debug('ERROR: request not verified against method signature'); + $this->result = 'fault: request failed validation against method signature'; + // return fault + $this->fault('Client',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('in invoke_method, params:'); + $this->appendDebug($this->varDump($this->methodparams)); + $this->debug("in invoke_method, calling '$this->methodname'"); + if (!function_exists('call_user_func_array')) { + if ($class == '') { + $this->debug('in invoke_method, calling function using eval()'); + $funcCall = "\$this->methodreturn = $this->methodname("; + } else { + if ($delim == '..') { + $this->debug('in invoke_method, calling class method using eval()'); + $funcCall = "\$this->methodreturn = ".$class."::".$method."("; + } else { + $this->debug('in invoke_method, calling instance method using eval()'); + // generate unique instance name + $instname = "\$inst_".time(); + $funcCall = $instname." = new ".$class."(); "; + $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; + } + } + if ($this->methodparams) { + foreach ($this->methodparams as $param) { + if (is_array($param)) { + $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); + return; + } + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1); + } + $funcCall .= ');'; + $this->debug('in invoke_method, function call: '.$funcCall); + @eval($funcCall); + } else { + if ($class == '') { + $this->debug('in invoke_method, calling function using call_user_func_array()'); + $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() + } elseif ($delim == '..') { + $this->debug('in invoke_method, calling class method using call_user_func_array()'); + $call_arg = array ($class, $method); + } else { + $this->debug('in invoke_method, calling instance method using call_user_func_array()'); + $instance = new $class (); + $call_arg = array(&$instance, $method); + } + $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); + } + $this->debug('in invoke_method, methodreturn:'); + $this->appendDebug($this->varDump($this->methodreturn)); + $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); + } + + /** + * serializes the return value from a PHP function into a full SOAP Envelope + * + * The following fields are set by this function (when successful) + * + * responseSOAP + * + * This sets the fault field on error + * + * @access private + */ + function serialize_return() { + $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); + // if fault + if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault_colosa')) { + $this->debug('got a fault object from method'); + $this->fault = $this->methodreturn; + return; + } elseif ($this->methodreturnisliteralxml) { + $return_val = $this->methodreturn; + // returned value(s) + } else { + $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); + $this->debug('serializing return value'); + if($this->wsdl){ + // weak attempt at supporting multiple output params + if(sizeof($this->opData['output']['parts']) > 1){ + $opParams = $this->methodreturn; + } else { + // TODO: is this really necessary? + $opParams = array($this->methodreturn); + } + $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'unable to serialize result'); + return; + } + } else { + if (isset($this->methodreturn)) { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } else { + $return_val = ''; + $this->debug('in absence of WSDL, assume void return for backward compatibility'); + } + } + } + $this->debug('return value:'); + $this->appendDebug($this->varDump($return_val)); + + $this->debug('serializing response'); + if ($this->wsdl) { + $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); + if ($this->opData['style'] == 'rpc') { + $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); + if ($this->opData['output']['use'] == 'literal') { + $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } else { + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + } else { + $this->debug('style is not rpc for serialization: assume document'); + $payload = $return_val; + } + } else { + $this->debug('do not have WSDL for serialization: assume rpc/encoded'); + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->appendDebug($this->wsdl->getDebug()); + // } + if (isset($opData['output']['encodingStyle'])) { + $encodingStyle = $opData['output']['encodingStyle']; + } else { + $encodingStyle = ''; + } + // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); + } else { + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); + } + $this->debug("Leaving serialize_return"); + } + + /** + * sends an HTTP response + * + * The following fields are set by this function (when successful) + * + * outgoing_headers + * response + * + * @access private + */ + function send_response() { + $this->debug('Enter send_response'); + if ($this->fault) { + $payload = $this->fault->serialize(); + $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; + $this->outgoing_headers[] = "Status: 500 Internal Server Error"; + } else { + $payload = $this->responseSOAP; + // Some combinations of PHP+Web server allow the Status + // to come through as a header. Since OK is the default + // just do nothing. + // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; + // $this->outgoing_headers[] = "Status: 200 OK"; + } + // add debug data if in debug mode + if(isset($this->debug_flag) && $this->debug_flag){ + $payload .= $this->getDebugAsXMLComment(); + } + $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; + // Let the Web server decide about this + //$this->outgoing_headers[] = "Connection: Close\r\n"; + $payload = $this->getHTTPBody($payload); + $type = $this->getHTTPContentType(); + $charset = $this->getHTTPContentTypeCharset(); + $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); + //begin code to compress payload - by John + // NOTE: there is no way to know whether the Web server will also compress + // this data. + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { + if (strstr($this->headers['accept-encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { + // Note: MSIE requires gzdeflate output (no Zlib header and checksum), + // instead of gzcompress output, + // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) + if (function_exists('gzdeflate')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzdeflate($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + print $payload; + $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param string $operation The operation to be invoked + * @param array $request The array of parameter values + * @return boolean Whether the operation was found + * @access private + */ + function verify_method($operation,$request){ + if(isset($this->wsdl) && is_object($this->wsdl)){ + if($this->wsdl->getOperationData($operation)){ + return true; + } + } elseif(isset($this->operations[$operation])){ + return true; + } + return false; + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Request not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + // parse response, get soap parser obj + $parser = new soap_parser_colosa($data,$this->xml_encoding,'',$this->decode_utf8); + // parser debug + $this->debug("parser debug: \n".$parser->getDebug()); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Client',"error in msg parsing:\n".$err); + // else successfully parsed request into soapval object + } else { + // get/set methodname + $this->methodURI = $parser->root_struct_namespace; + $this->methodname = $parser->root_struct_name; + $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); + $this->debug('calling parser->get_response()'); + $this->methodparams = $parser->get_response(); + // get SOAP headers + $this->requestHeaders = $parser->getHeaders(); + // add document for doclit support + $this->document = $parser->document; + } + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /** + * add a method to the dispatch map (this has been replaced by the register method) + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + * @deprecated + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service function with the server + * + * @param string $name the name of the PHP function, class.method or class..method + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param mixed $namespace the element namespace for the method or false + * @param mixed $soapaction the soapaction for the method or false + * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param mixed $use optional (encoded|literal) or false + * @param string $documentation optional Description to include in WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ + global $HTTP_SERVER_VARS; + + if($this->externalWSDLURL){ + die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); + } + if (! $name) { + die('You must specify a name when you register an operation'); + } + if (!is_array($in)) { + die('You must provide an array for operation inputs'); + } + if (!is_array($out)) { + die('You must provide an array for operation outputs'); + } + if(false == $namespace) { + } + if(false == $soapaction) { + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + if ($use == 'encoded' && $encodingStyle = '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + $this->operations[$name] = array( + 'name' => $name, + 'in' => $in, + 'out' => $out, + 'namespace' => $namespace, + 'soapaction' => $soapaction, + 'style' => $style); + if($this->wsdl){ + $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); + } + return true; + } + + /** + * Specify a fault to be returned to the client. + * This also acts as a flag to the server that a fault has occured. + * + * @param string $faultcode + * @param string $faultstring + * @param string $faultactor + * @param string $faultdetail + * @access public + */ + function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ + if ($faultdetail == '' && $this->debug_flag) { + $faultdetail = $this->getDebug(); + } + $this->fault = new soap_fault_colosa($faultcode,$faultactor,$faultstring,$faultdetail); + $this->fault->soap_defencoding = $this->soap_defencoding; + } + + /** + * Sets up wsdl object. + * Acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param mixed $namespace optional 'tns' service namespace or false + * @param mixed $endpoint optional URL of service endpoint or false + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SERVER_PORT = $_SERVER['SERVER_PORT']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + $HTTPS = $HTTP_SERVER_VARS['HTTPS']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if ($HTTPS == '1' || $HTTPS == 'on') { + $SCHEME = 'https'; + } else { + $SCHEME = 'http'; + } + $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; + } + + if(false == $schemaTargetNamespace) { + $schemaTargetNamespace = $namespace; + } + + $this->wsdl = new wsdl; + $this->wsdl->serviceName = $serviceName; + $this->wsdl->endpoint = $endpoint; + $this->wsdl->namespaces['tns'] = $namespace; + $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; + $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; + if ($schemaTargetNamespace != $namespace) { + $this->wsdl->namespaces['types'] = $schemaTargetNamespace; + } + $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); + $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->bindings[$serviceName.'Binding'] = array( + 'name'=>$serviceName.'Binding', + 'style'=>$style, + 'transport'=>$transport, + 'portType'=>$serviceName.'PortType'); + $this->wsdl->ports[$serviceName.'Port'] = array( + 'binding'=>$serviceName.'Binding', + 'location'=>$endpoint, + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class wsdl extends nusoap_base_colosa { + // URL or filename of the root of this WSDL + var $wsdl; + // define internal arrays of bindings, ports, operations, messages, etc. + var $schemas = array(); + var $currentSchema; + var $message = array(); + var $complexTypes = array(); + var $messages = array(); + var $currentMessage; + var $currentOperation; + var $portTypes = array(); + var $currentPortType; + var $bindings = array(); + var $currentBinding; + var $ports = array(); + var $currentPort; + var $opData = array(); + var $status = ''; + var $documentation = false; + var $endpoint = ''; + // array of wsdl docs to import + var $import = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + // for getting wsdl + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $timeout = 0; + var $response_timeout = 30; + + /** + * constructor + * + * @param string $wsdl WSDL document URL + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ + parent::nusoap_base_colosa(); + $this->wsdl = $wsdl; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // parse wsdl file + if ($wsdl != "") { + $this->debug('initial wsdl URL: ' . $wsdl); + $this->parseWSDL($wsdl); + } + // imports + // TODO: handle imports more properly, grabbing them in-line and nesting them + $imported_urls = array(); + $imported = 1; + while ($imported > 0) { + $imported = 0; + // Schema imports + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($xs->imports as $ns2 => $list2) { + for ($ii = 0; $ii < count($list2); $ii++) { + if (! $list2[$ii]['loaded']) { + $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; + $url = $list2[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + } + // WSDL imports + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($this->import as $ns => $list) { + for ($ii = 0; $ii < count($list); $ii++) { + if (! $list[$ii]['loaded']) { + $this->import[$ns][$ii]['loaded'] = true; + $url = $list[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + // add new data to operation data + foreach($this->bindings as $binding => $bindingData) { + if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { + foreach($bindingData['operations'] as $operation => $data) { + $this->debug('post-parse data gathering for ' . $operation); + $this->bindings[$binding]['operations'][$operation]['input'] = + isset($this->bindings[$binding]['operations'][$operation]['input']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['input']; + $this->bindings[$binding]['operations'][$operation]['output'] = + isset($this->bindings[$binding]['operations'][$operation]['output']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['output']; + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; + } + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; + } + if (isset($bindingData['style'])) { + $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; + } + $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; + $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; + $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; + } + } + } + } + + /** + * parses the wsdl document + * + * @param string $wsdl path or URL + * @access private + */ + function parseWSDL($wsdl = '') + { + if ($wsdl == '') { + $this->debug('no wsdl passed to parseWSDL()!!'); + $this->setError('no wsdl passed to parseWSDL()!!'); + return false; + } + + // parse $wsdl for url format + $wsdl_props = parse_url($wsdl); + + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { + $this->debug('getting WSDL http(s) URL ' . $wsdl); + // get wsdl + $tr = new soap_transport_http($wsdl); + $tr->request_method = 'GET'; + $tr->useSOAPAction = false; + if($this->proxyhost && $this->proxyport){ + $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + $tr->setEncoding('gzip, deflate'); + $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); + //$this->debug("WSDL request\n" . $tr->outgoing_payload); + //$this->debug("WSDL response\n" . $tr->incoming_payload); + $this->appendDebug($tr->getDebug()); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + $this->debug("got WSDL URL"); + } else { + // $wsdl is not http(s), so treat it as a file URL or plain file path + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { + $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; + } else { + $path = $wsdl; + } + $this->debug('getting WSDL file ' . $path); + if ($fp = @fopen($path, 'r')) { + $wsdl_string = ''; + while ($data = fread($fp, 32768)) { + $wsdl_string .= $data; + } + fclose($fp); + } else { + $errstr = "Bad path to WSDL file $path"; + $this->debug($errstr); + $this->setError($errstr); + return false; + } + } + $this->debug('Parse WSDL'); + // end new code added + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element', 'end_element'); + xml_set_character_data_handler($this->parser, 'character_data'); + // Parse the XML file. + if (!xml_parse($this->parser, $wsdl_string, true)) { + // Display an error message. + $errstr = sprintf( + 'XML error parsing WSDL from %s on line %d: %s', + $wsdl, + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $wsdl_string); + $this->setError($errstr); + return false; + } + // free the parser + xml_parser_free($this->parser); + $this->debug('Parsing WSDL done'); + // catch wsdl parse errors + if($this->getError()){ + return false; + } + return true; + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) + { + if ($this->status == 'schema') { + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } elseif (ereg('schema$', $name)) { + $this->debug('Parsing WSDL schema'); + // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); + $this->status = 'schema'; + $this->currentSchema = new xmlschema('', '', $this->namespaces); + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } else { + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + // process attributes + if (count($attrs) > 0) { + // register namespace declarations + foreach($attrs as $k => $v) { + if (ereg("^xmlns", $k)) { + if ($ns_prefix = substr(strrchr($k, ':'), 1)) { + $this->namespaces[$ns_prefix] = $v; + } else { + $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; + } + if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } + } + // expand each attribute prefix to its namespace + foreach($attrs as $k => $v) { + $k = strpos($k, ':') ? $this->expandQname($k) : $k; + if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { + $v = strpos($v, ':') ? $this->expandQname($v) : $v; + } + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // get element prefix, namespace and name + if (ereg(':', $name)) { + // get ns prefix + $prefix = substr($name, 0, strpos($name, ':')); + // get ns + $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; + // get unqualified name + $name = substr(strstr($name, ':'), 1); + } + // process attributes, expanding any prefixes to namespaces + // find status, register data + switch ($this->status) { + case 'message': + if ($name == 'part') { + if (isset($attrs['type'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; + } + if (isset($attrs['element'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; + } + } + break; + case 'portType': + switch ($name) { + case 'operation': + $this->currentPortOperation = $attrs['name']; + $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); + if (isset($attrs['parameterOrder'])) { + $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; + } + break; + case 'documentation': + $this->documentation = true; + break; + // merge input/output data + default: + $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; + $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; + break; + } + break; + case 'binding': + switch ($name) { + case 'binding': + // get ns prefix + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['prefix'] = $prefix; + } + $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); + break; + case 'header': + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + case 'operation': + if (isset($attrs['soapAction'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; + } + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; + } + if (isset($attrs['name'])) { + $this->currentOperation = $attrs['name']; + $this->debug("current binding operation: $this->currentOperation"); + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; + } + break; + case 'input': + $this->opStatus = 'input'; + break; + case 'output': + $this->opStatus = 'output'; + break; + case 'body': + if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); + } else { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; + } + break; + } + break; + case 'service': + switch ($name) { + case 'port': + $this->currentPort = $attrs['name']; + $this->debug('current port: ' . $this->currentPort); + $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); + + break; + case 'address': + $this->ports[$this->currentPort]['location'] = $attrs['location']; + $this->ports[$this->currentPort]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; + break; + } + break; + } + // set status + switch ($name) { + case 'import': + if (isset($attrs['location'])) { + $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); + $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); + } else { + $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); + } + break; + //wait for schema + //case 'types': + // $this->status = 'schema'; + // break; + case 'message': + $this->status = 'message'; + $this->messages[$attrs['name']] = array(); + $this->currentMessage = $attrs['name']; + break; + case 'portType': + $this->status = 'portType'; + $this->portTypes[$attrs['name']] = array(); + $this->currentPortType = $attrs['name']; + break; + case "binding": + if (isset($attrs['name'])) { + // get binding name + if (strpos($attrs['name'], ':')) { + $this->currentBinding = $this->getLocalPart($attrs['name']); + } else { + $this->currentBinding = $attrs['name']; + } + $this->status = 'binding'; + $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); + $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); + } + break; + case 'service': + $this->serviceName = $attrs['name']; + $this->status = 'service'; + $this->debug('current service: ' . $this->serviceName); + break; + case 'definitions': + foreach ($attrs as $name => $value) { + $this->wsdl_info[$name] = $value; + } + break; + } + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name){ + // unset schema status + if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { + $this->status = ""; + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + $this->debug('Parsing WSDL schema done'); + } + if ($this->status == 'schema') { + $this->currentSchema->schemaEndElement($parser, $name); + } else { + // bring depth down a notch + $this->depth--; + } + // end documentation + if ($this->documentation) { + //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. + //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; + $this->documentation = false; + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data) + { + $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } + if ($this->documentation) { + $this->documentation .= $data; + } + } + + function getBindingData($binding) + { + if (is_array($this->bindings[$binding])) { + return $this->bindings[$binding]; + } + } + + /** + * returns an assoc array of operation names => operation data + * + * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) + * @return array + * @access public + */ + function getOperations($bindingType = 'soap') + { + $ops = array(); + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + //$this->debug("getOperations for port $port"); + //$this->debug("port data: " . $this->varDump($portData)); + //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); + // merge bindings + if (isset($this->bindings[ $portData['binding'] ]['operations'])) { + $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); + } + } + } + return $ops; + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $operation , name of operation + * @param string $bindingType , type of binding eg: soap + * @return array + * @access public + */ + function getOperationData($operation, $bindingType = 'soap') + { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // get binding + //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { + // note that we could/should also check the namespace here + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + return $opData; + } + } + } + } + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $soapAction soapAction for operation + * @param string $bindingType type of binding eg: soap + * @return array + * @access public + */ + function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // loop through operations for the binding + foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + if ($opData['soapAction'] == $soapAction) { + return $opData; + } + } + } + } + } + + /** + * returns an array of information about a given type + * returns false if no type exists by the given name + * + * typeDef = array( + * 'elements' => array(), // refs to elements array + * 'restrictionBase' => '', + * 'phpType' => '', + * 'order' => '(sequence|all)', + * 'attrs' => array() // refs to attributes array + * ) + * + * @param $type string the type + * @param $ns string namespace (not prefix) of the type + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + $this->debug("in getTypeDef: type=$type, ns=$ns"); + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + $this->debug("in getTypeDef: type namespace forced to $ns"); + } + if (isset($this->schemas[$ns])) { + $this->debug("in getTypeDef: have schema for namespace $ns"); + for ($i = 0; $i < count($this->schemas[$ns]); $i++) { + $xs = &$this->schemas[$ns][$i]; + $t = $xs->getTypeDef($type); + $this->appendDebug($xs->getDebug()); + $xs->clearDebug(); + if ($t) { + if (!isset($t['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); + $ns = substr($t['type'], 0, strrpos($t['type'], ':')); + $etype = $this->getTypeDef($uqType, $ns); + if ($etype) { + $this->debug("found type for [element] $type:"); + $this->debug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $t['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $t['elements'] = $etype['elements']; + } + if (isset($etype['attrs'])) { + $t['attrs'] = $etype['attrs']; + } + } + } + return $t; + } + } + } else { + $this->debug("in getTypeDef: do not have schema for namespace $ns"); + } + return false; + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $PHP_SELF = $_SERVER['PHP_SELF']; + } elseif (isset($HTTP_SERVER_VARS)) { + $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + + $b = ' + NuSOAP: '.$this->serviceName.' + + + + +
    +

    +
    '.$this->serviceName.'
    + +
    '; + return $b; + } + + /** + * serialize the parsed wsdl + * + * @param mixed $debug whether to put debug=1 in endpoint URL + * @return string serialization of WSDL + * @access public + */ + function serialize($debug = 0) + { + $xml = ''; + $xml .= "\nnamespaces as $k => $v) { + $xml .= " xmlns:$k=\"$v\""; + } + // 10.9.02 - add poulter fix for wsdl and tns declarations + if (isset($this->namespaces['wsdl'])) { + $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; + } + if (isset($this->namespaces['tns'])) { + $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; + } + $xml .= '>'; + // imports + if (sizeof($this->import) > 0) { + foreach($this->import as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= ''; + } else { + $xml .= ''; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= "\n"; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= ''; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= "\n'; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'
    '; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'
    '; + $typePrefix = 'xsd'; + } else { + foreach($this->typemap as $ns => $types) { + if (isset($types[$partType])) { + $typePrefix = $this->getPrefixFromNamespace($ns); + } + } + if (!isset($typePrefix)) { + die("$partType has no namespace!"); + } + } + $ns = $this->getNamespaceFromPrefix($typePrefix); + $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); + if ($typeDef['typeClass'] == 'element') { + $elementortype = 'element'; + } else { + $elementortype = 'type'; + } + $xml .= ''; + } + } + $xml .= '
    '; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= "\n'; + $binding_xml .= ''; + $portType_xml .= "\n'; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= ''; + $binding_xml .= ''; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + $binding_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $portType_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $binding_xml .= ''; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= "\nserviceName . '">'; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= ''; + $uri = explode ( '?' , getenv("REQUEST_URI")); + $location = 'http://' . getenv ( 'SERVER_NAME' ) . $uri[0] ; + $xml .= ''; + // $xml .= ''; + $xml .= ''; + } + } + $xml .= ''; + return $xml . "\n"; + } + + /** + * serialize PHP values according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $operation operation name + * @param string $direction (input|output) + * @param mixed $parameters parameter value(s) + * @return mixed parameters serialized as XML or false on error (e.g. operation not found) + * @access public + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeRPCParameters returning: $xml"); + return $xml; + } + + /** + * serialize a PHP value according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $ type name + * @param mixed $ param value + * @return mixed new param or false if initial value didn't validate + * @access public + * @deprecated + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug("use=$use"); + $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . $parametersArrayType . ' parameters'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeParameters returning: $xml"); + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name name of value (part or element) + * @param string $type XML schema type of value (type or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @param boolean $unqualified a kludge for what should be XML namespace form handling + * @return string value serialized as an XML string + * @access private + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) + { + $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); + $this->appendDebug("value=" . $this->varDump($value)); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soapval has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } elseif ($value->type) { + $type = $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } else { + $forceType = false; + $this->debug("in serializeType: soapval does not override type"); + } + $attrs = $value->attributes; + $value = $value->value; + $this->debug("in serializeType: soapval overrides value to $value"); + if ($attrs) { + if (!is_array($value)) { + $value['!'] = $value; + } + foreach ($attrs as $n => $v) { + $value['!' . $n] = $v; + } + $this->debug("in serializeType: soapval provides attributes"); + } + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ + $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); + if ($unqualified && $use == 'literal') { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + // TODO: depends on nillable, which should be checked before calling this method + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if ($uqType == 'boolean') { + if ((is_string($value) && $value == 'false') || (! $value)) { + $value = 'false'; + } else { + $value = 'true'; + } + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($value); + } + if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { + $value = sprintf("%.0lf", $value); + } + // it's a scalar + // TODO: what about null/nil values? + // check type isn't a custom type extending xmlschema namespace + if (!$this->getTypeDef($uqType, $ns)) { + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); + } else if ($ns == 'http://xml.apache.org/xml-soap') { + $this->debug('in serializeType: appears to be Apache SOAP type'); + if ($uqType == 'Map') { + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + if (! $tt_prefix) { + $this->debug('in serializeType: Add namespace for Apache SOAP type'); + $tt_prefix = 'ns' . rand(1000, 9999); + $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; + // force this to be added to usedNamespaces + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + } + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= ''; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= ''; + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents"; + } else { + $xml = "<$name>$contents"; + } + } else { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('in serializeType: Apache SOAP type, but only support Map'); + } + } else { + // TODO: should the type be compared to types in XSD, and the namespace + // set to XSD if the type matches? + $this->debug("in serializeType: No namespace for type $type"); + $ns = ''; + $uqType = $type; + } + if(!$typeDef = $this->getTypeDef($uqType, $ns)){ + $this->setError("$type ($uqType) is not a supported type."); + $this->debug("in serializeType: $type ($uqType) is not a supported type."); + return false; + } else { + $this->debug("in serializeType: found typeDef"); + $this->appendDebug('typeDef=' . $this->varDump($typeDef)); + } + $phpType = $typeDef['phpType']; + $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the element names + if ($phpType == 'struct') { + if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { + $elementName = $uqType; + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = " xmlns=\"\""; + } + } else { + $elementName = $name; + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$elementName$elementNS/>"; + } else { + $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (is_object($value)) { + $value = get_object_vars($value); + } + if (is_array($value)) { + $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS$elementAttrs>"; + } + } else { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + $xml .= ""; + } else { + $this->debug("in serializeType: phpType is struct, but value is not an array"); + $this->setError("phpType is struct, but value is not an array: see debug output for details"); + $xml = ''; + } + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ":Array\" " . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ':arrayType="' . + $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . + ':' . + $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (isset($typeDef['multidimensional'])) { + $nv = array(); + foreach($value as $v) { + $cols = ',' . sizeof($v); + $nv = array_merge($nv, $v); + } + $value = $nv; + } else { + $cols = ''; + } + if (is_array($value) && sizeof($value) >= 1) { + $rows = sizeof($value); + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); + //if (strpos($typeDef['arrayType'], ':') ) { + if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { + $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); + } else { + $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); + } + } + } else { + $rows = 0; + $contents = null; + } + // TODO: for now, an empty value will be serialized as a zero element + // array. Revisit this when coding the handling of null/nil values. + if ($use == 'literal') { + $xml = "<$name$elementNS>" + .$contents + .""; + } else { + $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') + .':arrayType="' + .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) + .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" + .$contents + .""; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + + /** + * serializes the attributes for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { + $xml = ''; + if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { + $this->debug("serialize attributes for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + foreach ($typeDef['attrs'] as $aName => $attrs) { + if (isset($xvalue['!' . $aName])) { + $xname = '!' . $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($xvalue[$aName])) { + $xname = $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($attrs['default'])) { + $xname = '!' . $aName; + $xvalue[$xname] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); + } else { + $xname = ''; + $this->debug("no value provided for attribute $aName"); + } + if ($xname) { + $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; + } + } + } else { + $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize attributes for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * serializes the elements for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { + $xml = ''; + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + // toggle whether all elements are present - ideally should validate against schema + if (count($typeDef['elements']) != count($xvalue)){ + $optionals = true; + } + foreach ($typeDef['elements'] as $eName => $attrs) { + if (!isset($xvalue[$eName])) { + if (isset($attrs['default'])) { + $xvalue[$eName] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); + } + } + // if user took advantage of a minOccurs=0, then only serialize named parameters + if (isset($optionals) + && (!isset($xvalue[$eName])) + && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') + ){ + if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { + $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); + } + // do nothing + $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + if (isset($attrs['form'])) { + $unqualified = ($attrs['form'] == 'unqualified'); + } else { + $unqualified = false; + } + if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } else { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } + } + } else { + $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize elements for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @param string name + * @param string typeClass (complexType|simpleType|attribute) + * @param string phpType: currently supported are array and struct (php assoc array) + * @param string compositor (all|sequence|choice) + * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param array elements = array ( name => array(name=>'',type=>'') ) + * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) + * @param string arrayType: namespace:name (xsd:string) + * @see xmlschema + * @access public + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { + if (count($elements) > 0) { + foreach($elements as $n => $e){ + // expand each element + foreach ($e as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $ee[$k] = $v; + } + $eElements[$n] = $ee; + } + $elements = $eElements; + } + + if (count($attrs) > 0) { + foreach($attrs as $n => $a){ + // expand each attribute + foreach ($a as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $aa[$k] = $v; + } + $eAttrs[$n] = $aa; + } + $attrs = $eAttrs; + } + + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); + } + + /** + * adds an XML Schema simple type to the WSDL types + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @see xmlschema + * @access public + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); + } + + /** + * adds an element to the WSDL types + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addElement($attrs); + } + + /** + * register an operation with the server + * + * @param string $name operation (method) name + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param string $namespace optional The namespace for the operation + * @param string $soapaction optional The soapaction for the operation + * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) + * @param string $documentation optional The description to include in the WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ + if ($use == 'encoded' && $encodingStyle == '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + if ($style == 'document') { + $elements = array(); + foreach ($in as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); + $in = array('parameters' => 'tns:' . $name); + + $elements = array(); + foreach ($out as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); + $out = array('parameters' => 'tns:' . $name . 'Response'); + } + + // get binding + $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = + array( + 'name' => $name, + 'binding' => $this->serviceName . 'Binding', + 'endpoint' => $this->endpoint, + 'soapAction' => $soapaction, + 'style' => $style, + 'input' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Request', + 'parts' => $in), + 'output' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Response', + 'parts' => $out), + 'namespace' => $namespace, + 'transport' => 'http://schemas.xmlsoap.org/soap/http', + 'documentation' => $documentation); + // add portTypes + // add messages + if($in) + { + foreach($in as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Request'][$pName] = $pType; + } + } else { + $this->messages[$name.'Request']= '0'; + } + if($out) + { + foreach($out as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Response'][$pName] = $pType; + } + } else { + $this->messages[$name.'Response']= '0'; + } + return true; + } +} +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_parser_colosa extends nusoap_base_colosa { + + var $xml = ''; + var $xml_encoding = ''; + var $method = ''; + var $root_struct = ''; + var $root_struct_name = ''; + var $root_struct_namespace = ''; + var $root_header = ''; + var $document = ''; // incoming SOAP body (text) + // determines where in the message we are (envelope,header,body,method) + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $namespaces = array(); + var $message = array(); + var $parent = ''; + var $fault = false; + var $fault_code = ''; + var $fault_str = ''; + var $fault_detail = ''; + var $depth_array = array(); + var $debug_flag = true; + var $soapresponse = NULL; + var $responseHeaders = ''; // incoming SOAP headers (text) + var $body_position = 0; + // for multiref parsing: + // array of id => pos + var $ids = array(); + // array of id => hrefs => pos + var $multirefs = array(); + // toggle for auto-decoding element content + var $decode_utf8 = true; + + /** + * constructor that actually does the parsing + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method method for which XML is parsed (unused?) + * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 + * @access public + */ + function soap_parser_colosa($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ + parent::nusoap_base_colosa(); + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + // Check XML encoding + $pos_xml = strpos($xml, '', $pos_xml + 2) - $pos_xml + 1); + if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { + $xml_encoding = $res[1]; + if (strtoupper($xml_encoding) != $encoding) { + $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; + $this->debug($err); + if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { + $this->setError($err); + return; + } + // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed + } else { + $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); + } + } else { + $this->debug('No encoding specified in XML declaration'); + } + } else { + $this->debug('No XML declaration'); + } + $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); + // Create an XML parser - why not xml_parser_create_ns? + $this->parser = xml_parser_create($this->xml_encoding); + // Set the options for parsing the XML data. + //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element','end_element'); + xml_set_character_data_handler($this->parser,'character_data'); + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $err = sprintf('XML error parsing SOAP payload on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser))); + $this->debug($err); + $this->debug("XML payload:\n" . $xml); + $this->setError($err); + } else { + $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); + // get final value + $this->soapresponse = $this->message[$this->root_struct]['result']; + // get header value: no, because this is documented as XML string +// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ +// $this->responseHeaders = $this->message[$this->root_header]['result']; +// } + // resolve hrefs/ids + if(sizeof($this->multirefs) > 0){ + foreach($this->multirefs as $id => $hrefs){ + $this->debug('resolving multirefs for id: '.$id); + $idVal = $this->buildVal($this->ids[$id]); + if (is_array($idVal) && isset($idVal['!id'])) { + unset($idVal['!id']); + } + foreach($hrefs as $refPos => $ref){ + $this->debug('resolving href at pos '.$refPos); + $this->multirefs[$id][$refPos] = $idVal; + } + } + } + } + xml_parser_free($this->parser); + } else { + $this->debug('xml was empty, didn\'t parse!'); + $this->setError('xml was empty, didn\'t parse!'); + } + } + + /** + * start-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @param array $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) { + // position in a total number of elements, starting from 0 + // update class level pos + $pos = $this->position++; + // and set mine + $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); + // depth = how many levels removed from root? + // set mine as current global depth and increment global depth value + $this->message[$pos]['depth'] = $this->depth++; + + // else add self as child to whoever the current parent is + if($pos != 0){ + $this->message[$this->parent]['children'] .= '|'.$pos; + } + // set my parent + $this->message[$pos]['parent'] = $this->parent; + // set self as current parent + $this->parent = $pos; + // set self as current value for this depth + $this->depth_array[$this->depth] = $pos; + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + // set status + if($name == 'Envelope'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->root_header = $pos; + $this->status = 'header'; + } elseif($name == 'Body'){ + $this->status = 'body'; + $this->body_position = $pos; + // set method + } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->message[$pos]['type'] = 'struct'; + $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); + } + // set my status + $this->message[$pos]['status'] = $this->status; + // set name + $this->message[$pos]['name'] = htmlspecialchars($name); + // set attrs + $this->message[$pos]['attrs'] = $attrs; + + // loop through atts, logging ns and type declarations + $attstr = ''; + foreach($attrs as $key => $value){ + $key_prefix = $this->getPrefix($key); + $key_localpart = $this->getLocalPart($key); + // if ns declarations, add to class level array of valid namespaces + if($key_prefix == 'xmlns'){ + if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ + $this->XMLSchemaVersion = $value; + $this->namespaces['xsd'] = $this->XMLSchemaVersion; + $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; + } + $this->namespaces[$key_localpart] = $value; + // set method namespace + if($name == $this->root_struct_name){ + $this->methodNamespace = $value; + } + // if it's a type declaration, set type + } elseif($key_localpart == 'type'){ + $value_prefix = $this->getPrefix($value); + $value_localpart = $this->getLocalPart($value); + $this->message[$pos]['type'] = $value_localpart; + $this->message[$pos]['typePrefix'] = $value_prefix; + if(isset($this->namespaces[$value_prefix])){ + $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; + } else if(isset($attrs['xmlns:'.$value_prefix])) { + $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; + } + // should do something here with the namespace of specified type? + } elseif($key_localpart == 'arrayType'){ + $this->message[$pos]['type'] = 'array'; + /* do arrayType ereg here + [1] arrayTypeValue ::= atype asize + [2] atype ::= QName rank* + [3] rank ::= '[' (',')* ']' + [4] asize ::= '[' length~ ']' + [5] length ::= nextDimension* Digit+ + [6] nextDimension ::= Digit+ ',' + */ + $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; + if(ereg($expr,$value,$regs)){ + $this->message[$pos]['typePrefix'] = $regs[1]; + $this->message[$pos]['arrayTypePrefix'] = $regs[1]; + if (isset($this->namespaces[$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; + } else if (isset($attrs['xmlns:'.$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; + } + $this->message[$pos]['arrayType'] = $regs[2]; + $this->message[$pos]['arraySize'] = $regs[3]; + $this->message[$pos]['arrayCols'] = $regs[4]; + } + // specifies nil value (or not) + } elseif ($key_localpart == 'nil'){ + $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); + // some other attribute + } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { + $this->message[$pos]['xattrs']['!' . $key] = $value; + } + + if ($key == 'xmlns') { + $this->default_namespace = $value; + } + // log id + if($key == 'id'){ + $this->ids[$value] = $pos; + } + // root + if($key_localpart == 'root' && $value == 1){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->debug("found root struct $this->root_struct_name, pos $pos"); + } + // for doclit + $attstr .= " $key=\"$value\""; + } + // get namespace - must be done after namespace atts are processed + if(isset($prefix)){ + $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; + $this->default_namespace = $this->namespaces[$prefix]; + } else { + $this->message[$pos]['namespace'] = $this->default_namespace; + } + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } elseif($this->root_struct_name != ''){ + $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } + + /** + * end-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name) { + // position of current element is equal to the last value left in depth_array for my depth + $pos = $this->depth_array[$this->depth--]; + + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + + // build to native type + if(isset($this->body_position) && $pos > $this->body_position){ + // deal w/ multirefs + if(isset($this->message[$pos]['attrs']['href'])){ + // get id + $id = substr($this->message[$pos]['attrs']['href'],1); + // add placeholder to href array + $this->multirefs[$id][$pos] = 'placeholder'; + // add set a reference to it as the result value + $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; + // build complexType values + } elseif($this->message[$pos]['children'] != ''){ + // if result has already been generated (struct/array) + if(!isset($this->message[$pos]['result'])){ + $this->message[$pos]['result'] = $this->buildVal($pos); + } + // build complexType values of attributes and possibly simpleContent + } elseif (isset($this->message[$pos]['xattrs'])) { + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + if (isset($this->message[$pos]['type'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; + } + } + } + $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; + // set value of simpleType (or nil complexType) + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['type'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['result'] = $this->message[$pos]['cdata']; + } + } + + /* add value to parent's result, if parent is struct/array + $parent = $this->message[$pos]['parent']; + if($this->message[$parent]['type'] != 'map'){ + if(strtolower($this->message[$parent]['type']) == 'array'){ + $this->message[$parent]['result'][] = $this->message[$pos]['result']; + } else { + $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; + } + } + */ + } + } + + // for doclit + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= ""; + } + } elseif($pos >= $this->root_struct){ + $this->document .= ""; + } + // switch status + if($pos == $this->root_struct){ + $this->status = 'body'; + $this->root_struct_namespace = $this->message[$pos]['namespace']; + } elseif($name == 'Body'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->status = 'envelope'; + } elseif($name == 'Envelope'){ + // + } + // set parent back to my parent + $this->parent = $this->message[$pos]['parent']; + } + + /** + * element content handler + * + * @param resource $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data){ + $pos = $this->depth_array[$this->depth]; + if ($this->xml_encoding=='UTF-8'){ + // TODO: add an option to disable this for folks who want + // raw UTF-8 that, e.g., might not map to iso-8859-1 + // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); + if($this->decode_utf8){ + $data = utf8_decode($data); + } + } + $this->message[$pos]['cdata'] .= $data; + // for doclit + if($this->status == 'header'){ + $this->responseHeaders .= $data; + } else { + $this->document .= $data; + } + } + + /** + * get the parsed message + * + * @return mixed + * @access public + */ + function get_response(){ + return $this->soapresponse; + } + + /** + * get the parsed headers + * + * @return string XML or empty if no headers + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * decodes simple types into PHP variables + * + * @param string $value value to decode + * @param string $type XML type to decode + * @param string $typens XML type namespace to decode + * @return mixed PHP value + * @access private + */ + function decodeSimple($value, $type, $typens) { + // TODO: use the namespace! + if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { + return (string) $value; + } + if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { + return (int) $value; + } + if ($type == 'float' || $type == 'double' || $type == 'decimal') { + return (double) $value; + } + if ($type == 'boolean') { + if (strtolower($value) == 'false' || strtolower($value) == 'f') { + return false; + } + return (boolean) $value; + } + if ($type == 'base64' || $type == 'base64Binary') { + $this->debug('Decode base64 value'); + return base64_decode($value); + } + // obscure numeric types + if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' + || $type == 'nonNegativeInteger' || $type == 'positiveInteger' + || $type == 'unsignedInt' + || $type == 'unsignedShort' || $type == 'unsignedByte') { + return (int) $value; + } + // bogus: parser treats array with no elements as a simple type + if ($type == 'array') { + return array(); + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * and scalars + * + * @param integer $pos position in node tree + * @return mixed PHP value + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['children'] != ''){ + $this->debug('in buildVal, there are children'); + $children = explode('|',$this->message[$pos]['children']); + array_shift($children); // knock off empty + // md array + if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ + $r=0; // rowcount + $c=0; // colcount + foreach($children as $child_pos){ + $this->debug("in buildVal, got an MD array element: $r, $c"); + $params[$r][] = $this->message[$child_pos]['result']; + $c++; + if($c == $this->message[$pos]['arrayCols']){ + $c = 0; + $r++; + } + } + // array + } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ + $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $params[] = &$this->message[$child_pos]['result']; + } + // apache Map type: java hashtable + } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ + $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $kv = explode("|",$this->message[$child_pos]['children']); + $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; + } + // generic compound type + //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { + } else { + // Apache Vector type: treat as an array + $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + $notstruct = 0; + } + // + foreach($children as $child_pos){ + if($notstruct){ + $params[] = &$this->message[$child_pos]['result']; + } else { + if (isset($params[$this->message[$child_pos]['name']])) { + // de-serialize repeated element name into an array + if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { + $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); + } + $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; + } else { + $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; + } + } + } + } + if (isset($this->message[$pos]['xattrs'])) { + $this->debug('in buildVal, handling attributes'); + foreach ($this->message[$pos]['xattrs'] as $n => $v) { + $params[$n] = $v; + } + } + // handle simpleContent + if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + $this->debug('in buildVal, handling simpleContent'); + if (isset($this->message[$pos]['type'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $params['!'] = $this->message[$pos]['cdata']; + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('in buildVal, no children, building scalar'); + $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; + if (isset($this->message[$pos]['type'])) { + return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } + return $this->message[$pos]['cdata']; + } + } +} + + + +?>call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient); +* +* @author Dietrich Ayala +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soapclient_colosa extends nusoap_base_colosa { + + var $username = ''; + var $password = ''; + var $authtype = ''; + var $certRequest = array(); + var $requestHeaders = false; // SOAP headers in request (text) + var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) + var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) + var $endpoint; + var $forceEndpoint = ''; // overrides WSDL endpoint + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $xml_encoding = ''; // character set encoding of incoming (response) messages + var $http_encoding = false; + var $timeout = 0; // HTTP connection timeout + var $response_timeout = 30; // HTTP response timeout + var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error + var $persistentConnection = false; + var $defaultRpcParams = false; // This is no longer used + var $request = ''; // HTTP request + var $response = ''; // HTTP response + var $responseData = ''; // SOAP payload of response + var $cookies = array(); // Cookies from response or for request + var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() + var $operations = array(); // WSDL operations, empty for WSDL initialization error + + /* + * fault related variables + */ + /** + * @var fault + * @access public + */ + var $fault; + /** + * @var faultcode + * @access public + */ + var $faultcode; + /** + * @var faultstring + * @access public + */ + var $faultstring; + /** + * @var faultdetail + * @access public + */ + var $faultdetail; + + /** + * constructor + * + * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) + * @param bool $wsdl optional, set to true if using WSDL + * @param int $portName optional portName in WSDL document + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function soapclient_colosa($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + parent::nusoap_base_colosa(); + $this->endpoint = $endpoint; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // make values + if($wsdl){ + if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { + $this->wsdl = $endpoint; + $this->endpoint = $this->wsdl->wsdl; + $this->wsdlFile = $this->endpoint; + $this->debug('existing wsdl instance created from ' . $this->endpoint); + } else { + $this->wsdlFile = $this->endpoint; + + // instantiate wsdl object and parse wsdl file + $this->debug('instantiating wsdl class with doc: '.$endpoint); + $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + // catch errors + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + } elseif($this->operations = $this->wsdl->getOperations()){ + $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); + $this->endpointType = 'wsdl'; + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } else { + $this->debug("instantiate SOAP with endpoint at $endpoint"); + $this->endpointType = 'soap'; + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param mixed $params An array, associative or simple, of the parameters + * for the method call, or a string that is the XML + * for the call. For rpc style, this call will + * wrap the XML in a tag named after the method, as + * well as the SOAP Envelope and Body. For document + * style, this will only wrap with the Envelope and Body. + * IMPORTANT: when using an array with document style, + * in which case there + * is really one parameter, the root of the fragment + * used in the call, which encloses what programmers + * normally think of parameters. A parameter array + * *must* include the wrapper. + * @param string $namespace optional method namespace (WSDL can override) + * @param string $soapAction optional SOAPAction value (WSDL can override) + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param boolean $rpcParams optional (no longer used) + * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) + * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) + * @return mixed response from SOAP call + * @access public + */ + function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->setError(''); + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); + $this->appendDebug('params=' . $this->varDump($params)); + $this->appendDebug('headers=' . $this->varDump($headers)); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + $this->debug("found operation"); + $this->appendDebug('opData=' . $this->varDump($opData)); + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + if (! $this->forceEndpoint) { + $this->endpoint = $opData['endpoint']; + } else { + $this->endpoint = $this->forceEndpoint; + } + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $nsPrefix = 'ns' . rand(1000, 9999); + $this->wsdl->namespaces[$nsPrefix] = $namespace; + } + $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); + // serialize payload + if (is_string($params)) { + $this->debug("serializing param string for WSDL operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for WSDL operation $operation"); + $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = $this->wsdl->usedNamespaces; + if (isset($opData['input']['encodingStyle'])) { + $encodingStyle = $opData['input']['encodingStyle']; + } else { + $encodingStyle = ''; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if ($errstr = $this->wsdl->getError()) { + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + return false; + } + } elseif($this->endpointType == 'wsdl') { + // operation not in WSDL + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + $this->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + return false; + } else { + // no WSDL + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns' . rand(1000, 9999); + // serialize + $payload = ''; + if (is_string($params)) { + $this->debug("serializing param string for operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for operation $operation"); + foreach($params as $k => $v){ + $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = array(); + if ($use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + if ($namespace) { + $payload = "<$operation xmlns=\"$namespace\">" . $payload . ""; + } else { + $payload = "<$operation>" . $payload . ""; + } + } else { + $this->debug("wrapping RPC request with encoded method element"); + if ($namespace) { + $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . + $payload . + ""; + } else { + $payload = "<$operation>" . + $payload . + ""; + } + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); + $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); + $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); + // send + $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); + if($errstr = $this->getError()){ + $this->debug('Error: '.$errstr); + return false; + } else { + $this->return = $return; + $this->debug('sent message successfully and got a(n) '.gettype($return)); + $this->appendDebug('return=' . $this->varDump($return)); + + // fault? + if(is_array($return) && isset($return['faultcode'])){ + $this->debug('got fault'); + $this->setError($return['faultcode'].': '.$return['faultstring']); + $this->fault = true; + foreach($return as $k => $v){ + $this->$k = $v; + $this->debug("$k = $v
    "); + } + return $return; + } elseif ($style == 'document') { + // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), + // we are only going to return the first part here...sorry about that + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters, which we return wrapped up + // in the array + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter (normally the return value) + $return = array_shift($return); + $this->debug('return shifted value: '); + $this->appendDebug($this->varDump($return)); + return $return; + // nothing returned (ie, echoVoid) + } else { + return ""; + } + } + } + } + + /** + * get available data pertaining to an operation + * + * @param string $operation operation name + * @return array array of data pertaining to the operation + * @access public + */ + function getOperationData($operation){ + if(isset($this->operations[$operation])){ + return $this->operations[$operation]; + } + $this->debug("No data for operation: $operation"); + } + + /** + * send the SOAP message + * + * Note: if the operation has multiple return values + * the return value of this method will be an array + * of those values. + * + * @param string $msg a SOAPx4 soapmsg object + * @param string $soapaction SOAPAction value + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @return mixed native PHP types. + * @access private + */ + function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { + $this->checkCookies(); + // detect transport + switch(true){ + // http(s) + case ereg('^http',$this->endpoint): + $this->debug('transporting via HTTP'); + if($this->persistentConnection == true && is_object($this->persistentConnection)){ + $http =& $this->persistentConnection; + } else { + $http = new soap_transport_http($this->endpoint); + if ($this->persistentConnection) { + $http->usePersistentConnection(); + } + } + $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); + $http->setSOAPAction($soapaction); + if($this->proxyhost && $this->proxyport){ + $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + if($this->authtype != '') { + $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); + } + if($this->http_encoding != ''){ + $http->setEncoding($this->http_encoding); + } + $this->debug('sending message, length='.strlen($msg)); + if(ereg('^http:',$this->endpoint)){ + //if(strpos($this->endpoint,'http:')){ + $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); + } elseif(ereg('^https',$this->endpoint)){ + //} elseif(strpos($this->endpoint,'https:')){ + //if(phpversion() == '4.3.0-dev'){ + //$response = $http->send($msg,$timeout,$response_timeout); + //$this->request = $http->outgoing_payload; + //$this->response = $http->incoming_payload; + //} else + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->appendDebug($http->getDebug()); + $this->UpdateCookies($http->incoming_cookies); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->clearDebug(); + if (!is_object($this->persistentConnection)) { + $this->persistentConnection = $http; + } + } + + if($err = $http->getError()){ + $this->setError('HTTP Error: '.$err); + return false; + } elseif($this->getError()){ + return false; + } else { + $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); + return $this->parseResponse($http->incoming_headers, $this->responseData); + } + break; + default: + $this->setError('no transport found, or selected transport is not yet supported!'); + return false; + break; + } + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); +//by onti +/* + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Response not of type text/xml'); + return false; + } + */ + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + $parser = new soap_parser_colosa($data,$this->xml_encoding,$this->operation,$this->decode_utf8); + // add parser debug data to our debug + $this->appendDebug($parser->getDebug()); + // if parse errors + if($errstr = $parser->getError()){ + $this->setError( $errstr); + // destroy the parser object + unset($parser); + return false; + } else { + // get SOAP headers + $this->responseHeaders = $parser->getHeaders(); + // get decoded message + $return = $parser->get_response(); + // add document for doclit support + $this->document = $parser->document; + // destroy the parser object + unset($parser); + // return decode message + return $return; + } + } + + /** + * sets the SOAP endpoint, which can override WSDL + * + * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override + * @access public + */ + function setEndpoint($endpoint) { + $this->forceEndpoint = $endpoint; + } + + /** + * set the SOAP headers + * + * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the SOAP response headers (namespace resolution incomplete) + * + * @return string + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic|digest|certificate) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->certRequest = $certRequest; + } + + /** + * use HTTP encoding + * + * @param string $enc + * @access public + */ + function setHTTPEncoding($enc='gzip, deflate'){ + $this->http_encoding = $enc; + } + + /** + * use HTTP persistent connections if possible + * + * @access public + */ + function useHTTPPersistentConnection(){ + $this->persistentConnection = true; + } + + /** + * gets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style. + * Each call() can override this value. + * + * This is no longer used. + * + * @return boolean + * @access public + * @deprecated + */ + function getDefaultRpcParams() { + return $this->defaultRpcParams; + } + + /** + * sets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style + * Each call() can override this value. + * + * This is no longer used. + * + * @param boolean $rpcParams + * @access public + * @deprecated + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates an instance of a proxy class, + * allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $r = rand(); + $evalStr = $this->_getProxyClassCode($r); + //$this->debug("proxy class: $evalStr"; + // eval the class + eval($evalStr); + // instantiate proxy object + eval("\$proxy = new soap_proxy_$r('');"); + // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice + $proxy->endpointType = 'wsdl'; + $proxy->wsdlFile = $this->wsdlFile; + $proxy->wsdl = $this->wsdl; + $proxy->operations = $this->operations; + $proxy->defaultRpcParams = $this->defaultRpcParams; + // transfer other state + $proxy->username = $this->username; + $proxy->password = $this->password; + $proxy->authtype = $this->authtype; + $proxy->proxyhost = $this->proxyhost; + $proxy->proxyport = $this->proxyport; + $proxy->proxyusername = $this->proxyusername; + $proxy->proxypassword = $this->proxypassword; + $proxy->timeout = $this->timeout; + $proxy->response_timeout = $this->response_timeout; + $proxy->http_encoding = $this->http_encoding; + $proxy->persistentConnection = $this->persistentConnection; + $proxy->requestHeaders = $this->requestHeaders; + $proxy->soap_defencoding = $this->soap_defencoding; + $proxy->endpoint = $this->endpoint; + $proxy->forceEndpoint = $this->forceEndpoint; + return $proxy; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access private + */ + function _getProxyClassCode($r) { + if ($this->endpointType != 'wsdl') { + $evalStr = 'A proxy can only be created for a WSDL client'; + $this->setError($evalStr); + return $evalStr; + } + $evalStr = ''; + foreach ($this->operations as $operation => $opData) { + if ($operation != '') { + // create param string and param comment string + if (sizeof($opData['input']['parts']) > 0) { + $paramStr = ''; + $paramArrayStr = ''; + $paramCommentStr = ''; + foreach ($opData['input']['parts'] as $name => $type) { + $paramStr .= "\$$name, "; + $paramArrayStr .= "'$name' => \$$name, "; + $paramCommentStr .= "$type \$$name, "; + } + $paramStr = substr($paramStr, 0, strlen($paramStr)-2); + $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); + $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); + } else { + $paramStr = ''; + $paramCommentStr = 'void'; + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "// $paramCommentStr + function " . str_replace('.', '__', $operation) . "($paramStr) { + \$params = array($paramArrayStr); + return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + } + "; + unset($paramStr); + unset($paramCommentStr); + } + } + $evalStr = 'class soap_proxy_'.$r.' extends soapclient { + '.$evalStr.' +}'; + return $evalStr; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access public + */ + function getProxyClassCode() { + $r = rand(); + return $this->_getProxyClassCode($r); + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /* + * whether or not parser should decode utf8 element content + * + * @return always returns true + * @access public + */ + function decodeUTF8($bool){ + $this->decode_utf8 = $bool; + return true; + } + + /** + * adds a new Cookie into $this->cookies array + * + * @param string $name Cookie Name + * @param string $value Cookie Value + * @return if cookie-set was successful returns true, else false + * @access public + */ + function setCookie($name, $value) { + if (strlen($name) == 0) { + return false; + } + $this->cookies[] = array('name' => $name, 'value' => $value); + return true; + } + + /** + * gets all Cookies + * + * @return array with all internal cookies + * @access public + */ + function getCookies() { + return $this->cookies; + } + + /** + * checks all Cookies and delete those which are expired + * + * @return always return true + * @access private + */ + function checkCookies() { + if (sizeof($this->cookies) == 0) { + return true; + } + $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); + $curr_cookies = $this->cookies; + $this->cookies = array(); + foreach ($curr_cookies as $cookie) { + if (! is_array($cookie)) { + $this->debug('Remove cookie that is not an array'); + continue; + } + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) > time()) { + $this->cookies[] = $cookie; + } else { + $this->debug('Remove expired cookie ' . $cookie['name']); + } + } else { + $this->cookies[] = $cookie; + } + } + $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); + return true; + } + + /** + * updates the current cookies with a new set + * + * @param array $cookies new cookies with which to update current ones + * @return always return true + * @access private + */ + function UpdateCookies($cookies) { + if (sizeof($this->cookies) == 0) { + // no existing cookies: take whatever is new + if (sizeof($cookies) > 0) { + $this->debug('Setting new cookie(s)'); + $this->cookies = $cookies; + } + return true; + } + if (sizeof($cookies) == 0) { + // no new cookies: keep what we've got + return true; + } + // merge + foreach ($cookies as $newCookie) { + if (!is_array($newCookie)) { + continue; + } + if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { + continue; + } + $newName = $newCookie['name']; + + $found = false; + for ($i = 0; $i < count($this->cookies); $i++) { + $cookie = $this->cookies[$i]; + if (!is_array($cookie)) { + continue; + } + if (!isset($cookie['name'])) { + continue; + } + if ($newName != $cookie['name']) { + continue; + } + $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; + $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; + if ($newDomain != $domain) { + continue; + } + $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; + $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; + if ($newPath != $path) { + continue; + } + $this->cookies[$i] = $newCookie; + $found = true; + $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); + break; + } + if (! $found) { + $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); + $this->cookies[] = $newCookie; + } + } + return true; + } +} +?> diff --git a/gulliver/thirdparty/pear/nusoap.php b/gulliver/thirdparty/pear/nusoap.php new file mode 100644 index 000000000..228f05991 --- /dev/null +++ b/gulliver/thirdparty/pear/nusoap.php @@ -0,0 +1,7246 @@ +globalDebugLevel = 9; + +/** +* +* nusoap_base +* +* @author Dietrich Ayala +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class nusoap_base { + /** + * Identification for HTTP headers. + * + * @var string + * @access private + */ + var $title = 'NuSOAP'; + /** + * Version for HTTP headers. + * + * @var string + * @access private + */ + var $version = '0.7.2'; + /** + * CVS revision for HTTP headers. + * + * @var string + * @access private + */ + var $revision = '$Revision: 1.94 $'; + /** + * Current error string (manipulated by getError/setError) + * + * @var string + * @access private + */ + var $error_str = ''; + /** + * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment) + * + * @var string + * @access private + */ + var $debug_str = ''; + /** + * toggles automatic encoding of special characters as entities + * (should always be true, I think) + * + * @var boolean + * @access private + */ + var $charencoding = true; + /** + * the debug level for this instance + * + * @var integer + * @access private + */ + var $debugLevel; + + /** + * set schema version + * + * @var string + * @access public + */ + var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; + + /** + * charset encoding for outgoing messages + * + * @var string + * @access public + */ + var $soap_defencoding = 'ISO-8859-1'; + //var $soap_defencoding = 'UTF-8'; + + /** + * namespaces in an array of prefix => uri + * + * this is "seeded" by a set of constants, but it may be altered by code + * + * @var array + * @access public + */ + var $namespaces = array( + 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'xsd' => 'http://www.w3.org/2001/XMLSchema', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/' + ); + + /** + * namespaces used in the current context, e.g. during serialization + * + * @var array + * @access private + */ + var $usedNamespaces = array(); + + /** + * XML Schema types in an array of uri => (array of xml type => php type) + * is this legacy yet? + * no, this is used by the xmlschema class to verify type => namespace mappings. + * @var array + * @access public + */ + var $typemap = array( + 'http://www.w3.org/2001/XMLSchema' => array( + 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double', + 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'', + 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string', + // abstract "any" types + 'anyType'=>'string','anySimpleType'=>'string', + // derived datatypes + 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'', + 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer', + 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer', + 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''), + 'http://www.w3.org/2000/10/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://www.w3.org/1999/XMLSchema' => array( + 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double', + 'float'=>'double','dateTime'=>'string', + 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'), + 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'), + 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'), + 'http://xml.apache.org/xml-soap' => array('Map') + ); + + /** + * XML entities to convert + * + * @var array + * @access public + * @deprecated + * @see expandEntities + */ + var $xmlEntities = array('quot' => '"','amp' => '&', + 'lt' => '<','gt' => '>','apos' => "'"); + + /** + * constructor + * + * @access public + */ + function nusoap_base() { + $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * gets the global debug level, which applies to future instances + * + * @return integer Debug level 0-9, where 0 turns off + * @access public + */ + function getGlobalDebugLevel() { + return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel; + } + + /** + * sets the global debug level, which applies to future instances + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setGlobalDebugLevel($level) { + $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level; + } + + /** + * gets the debug level for this instance + * + * @return int Debug level 0-9, where 0 turns off + * @access public + */ + function getDebugLevel() { + return $this->debugLevel; + } + + /** + * sets the debug level for this instance + * + * @param int $level Debug level 0-9, where 0 turns off + * @access public + */ + function setDebugLevel($level) { + $this->debugLevel = $level; + } + + /** + * adds debug data to the instance debug string with formatting + * + * @param string $string debug data + * @access private + */ + function debug($string){ + if ($this->debugLevel > 0) { + $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n"); + } + } + + /** + * adds debug data to the instance debug string without formatting + * + * @param string $string debug data + * @access public + */ + function appendDebug($string){ + if ($this->debugLevel > 0) { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str .= $string; + } + } + + /** + * clears the current debug data for this instance + * + * @access public + */ + function clearDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + $this->debug_str = ''; + } + + /** + * gets the current debug data for this instance + * + * @return debug data + * @access public + */ + function &getDebug() { + // it would be nice to use a memory stream here to use + // memory more efficiently + return $this->debug_str; + } + + /** + * gets the current debug data for this instance as an XML comment + * this may change the contents of the debug data + * + * @return debug data as an XML comment + * @access public + */ + function &getDebugAsXMLComment() { + // it would be nice to use a memory stream here to use + // memory more efficiently + while (strpos($this->debug_str, '--')) { + $this->debug_str = str_replace('--', '- -', $this->debug_str); + } + return ""; + } + + /** + * expands entities, e.g. changes '<' to '<'. + * + * @param string $val The string in which to expand entities. + * @access private + */ + function expandEntities($val) { + if ($this->charencoding) { + $val = str_replace('&', '&', $val); + $val = str_replace("'", ''', $val); + $val = str_replace('"', '"', $val); + $val = str_replace('<', '<', $val); + $val = str_replace('>', '>', $val); + } + return $val; + } + + /** + * returns error string if present + * + * @return mixed error string or false + * @access public + */ + function getError(){ + if($this->error_str != ''){ + return $this->error_str; + } + return false; + } + + /** + * sets error string + * + * @return boolean $string error string + * @access private + */ + function setError($str){ + $this->error_str = $str; + } + + /** + * detect if array is a simple array or a struct (associative array) + * + * @param mixed $val The PHP array + * @return string (arraySimple|arrayStruct) + * @access private + */ + function isArraySimpleOrStruct($val) { + $keyList = array_keys($val); + foreach ($keyList as $keyListValue) { + if (!is_int($keyListValue)) { + return 'arrayStruct'; + } + } + return 'arraySimple'; + } + + /** + * serializes PHP values in accordance w/ section 5. Type information is + * not serialized if $use == 'literal'. + * + * @param mixed $val The value to serialize + * @param string $name The name (local part) of the XML element + * @param string $type The XML schema type (local part) for the element + * @param string $name_ns The namespace for the name of the XML element + * @param string $type_ns The namespace for the type of the element + * @param array $attributes The attributes to serialize as name=>value pairs + * @param string $use The WSDL "use" (encoded|literal) + * @return string The serialized element, possibly with child elements + * @access public + */ + function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){ + $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use"); + $this->appendDebug('value=' . $this->varDump($val)); + $this->appendDebug('attributes=' . $this->varDump($attributes)); + + if(is_object($val) && get_class($val) == 'soapval'){ + return $val->serialize($use); + } + // force valid name if necessary + if (is_numeric($name)) { + $name = '__numeric_' . $name; + } elseif (! $name) { + $name = 'noname'; + } + // if name has ns, add ns prefix to name + $xmlns = ''; + if($name_ns){ + $prefix = 'nu'.rand(1000,9999); + $name = $prefix.':'.$name; + $xmlns .= " xmlns:$prefix=\"$name_ns\""; + } + // if type is prefixed, create type prefix + if($type_ns != '' && $type_ns == $this->namespaces['xsd']){ + // need to fix this. shouldn't default to xsd if no ns specified + // w/o checking against typemap + $type_prefix = 'xsd'; + } elseif($type_ns){ + $type_prefix = 'ns'.rand(1000,9999); + $xmlns .= " xmlns:$type_prefix=\"$type_ns\""; + } + // serialize attributes if present + $atts = ''; + if($attributes){ + foreach($attributes as $k => $v){ + $atts .= " $k=\"".$this->expandEntities($v).'"'; + } + } + // serialize null value + if (is_null($val)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + return "<$name$xmlns $atts/>"; + } else { + if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>"; + } + } + // serialize if an xsd built-in primitive type + if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){ + if (is_bool($val)) { + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + } else if (is_string($val)) { + $val = $this->expandEntities($val); + } + if ($use == 'literal') { + return "<$name$xmlns $atts>$val"; + } else { + return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val"; + } + } + // detect type and serialize + $xml = ''; + switch(true) { + case (is_bool($val) || $type == 'boolean'): + if ($type == 'boolean') { + $val = $val ? 'true' : 'false'; + } elseif (! $val) { + $val = 0; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val"; + } + break; + case (is_int($val) || is_long($val) || $type == 'int'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val"; + } + break; + case (is_float($val)|| is_double($val) || $type == 'float'): + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val"; + } + break; + case (is_string($val) || $type == 'string'): + $val = $this->expandEntities($val); + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>$val"; + } else { + $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val"; + } + break; + case is_object($val): + if (! $name) { + $name = get_class($val); + $this->debug("In serialize_val, used class name $name as element name"); + } else { + $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val)); + } + foreach(get_object_vars($val) as $k => $v){ + $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use); + } + $xml .= '<'.$name.'>'.$pXml.''; + break; + break; + case (is_array($val) || $type): + // detect if struct or array + $valueType = $this->isArraySimpleOrStruct($val); + if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){ + $i = 0; + if(is_array($val) && count($val)> 0){ + foreach($val as $v){ + if(is_object($v) && get_class($v) == 'soapval'){ + $tt_ns = $v->type_ns; + $tt = $v->type; + } elseif (is_array($v)) { + $tt = $this->isArraySimpleOrStruct($v); + } else { + $tt = gettype($v); + } + $array_types[$tt] = 1; + // TODO: for literal, the name should be $name + $xml .= $this->serialize_val($v,'item',false,false,false,false,$use); + ++$i; + } + if(count($array_types) > 1){ + $array_typename = 'xsd:anyType'; + } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) { + if ($tt == 'integer') { + $tt = 'int'; + } + $array_typename = 'xsd:'.$tt; + } elseif(isset($tt) && $tt == 'arraySimple'){ + $array_typename = 'SOAP-ENC:Array'; + } elseif(isset($tt) && $tt == 'arrayStruct'){ + $array_typename = 'unnamed_struct_use_soapval'; + } else { + // if type is prefixed, create type prefix + if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){ + $array_typename = 'xsd:' . $tt; + } elseif ($tt_ns) { + $tt_prefix = 'ns' . rand(1000, 9999); + $array_typename = "$tt_prefix:$tt"; + $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\""; + } else { + $array_typename = $tt; + } + } + $array_type = $i; + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\""; + } + // empty array + } else { + if ($use == 'literal') { + $type_str = ''; + } else if (isset($type) && isset($type_prefix)) { + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\""; + } + } + // TODO: for array in literal, there is no wrapper here + $xml = "<$name$xmlns$type_str$atts>".$xml.""; + } else { + // got a struct + if(isset($type) && isset($type_prefix)){ + $type_str = " xsi:type=\"$type_prefix:$type\""; + } else { + $type_str = ''; + } + if ($use == 'literal') { + $xml .= "<$name$xmlns $atts>"; + } else { + $xml .= "<$name$xmlns$type_str$atts>"; + } + foreach($val as $k => $v){ + // Apache Map + if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') { + $xml .= ''; + $xml .= $this->serialize_val($k,'key',false,false,false,false,$use); + $xml .= $this->serialize_val($v,'value',false,false,false,false,$use); + $xml .= ''; + } else { + $xml .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } + $xml .= ""; + } + break; + default: + $xml .= 'not detected, got '.gettype($val).' for '.$val; + break; + } + return $xml; + } + + /** + * serializes a message + * + * @param string $body the XML of the SOAP body + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param array $namespaces optional the namespaces used in generating the body and headers + * @param string $style optional (rpc|document) + * @param string $use optional (encoded|literal) + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @return string the message + * @access public + */ + function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){ + // TODO: add an option to automatically run utf8_encode on $body and $headers + // if $this->soap_defencoding is UTF-8. Not doing this automatically allows + // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1 + + $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle"); + $this->debug("headers:"); + $this->appendDebug($this->varDump($headers)); + $this->debug("namespaces:"); + $this->appendDebug($this->varDump($namespaces)); + + // serialize namespaces + $ns_string = ''; + foreach(array_merge($this->namespaces,$namespaces) as $k => $v){ + $ns_string .= " xmlns:$k=\"$v\""; + } + if($encodingStyle) { + $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string"; + } + + // serialize headers + if($headers){ + if (is_array($headers)) { + $xml = ''; + foreach ($headers as $header) { + $xml .= $this->serialize_val($header, false, false, false, false, false, $use); + } + $headers = $xml; + $this->debug("In serializeEnvelope, serialzied array of headers to $headers"); + } + $headers = "".$headers.""; + } + // serialize envelope + return + 'soap_defencoding .'"?'.">". + '". + $headers. + "". + $body. + "". + ""; + } + + /** + * formats a string to be inserted into an HTML stream + * + * @param string $str The string to format + * @return string The formatted string + * @access public + * @deprecated + */ + function formatDump($str){ + $str = htmlspecialchars($str); + return nl2br($str); + } + + /** + * contracts (changes namespace to prefix) a qualified name + * + * @param string $qname qname + * @return string contracted qname + * @access private + */ + function contractQname($qname){ + // get element namespace + //$this->xdebug("Contract $qname"); + if (strrpos($qname, ':')) { + // get unqualified name + $name = substr($qname, strrpos($qname, ':') + 1); + // get ns + $ns = substr($qname, 0, strrpos($qname, ':')); + $p = $this->getPrefixFromNamespace($ns); + if ($p) { + return $p . ':' . $name; + } + return $qname; + } else { + return $qname; + } + } + + /** + * expands (changes prefix to namespace) a qualified name + * + * @param string $string qname + * @return string expanded qname + * @access private + */ + function expandQname($qname){ + // get element prefix + if(strpos($qname,':') && !ereg('^http://',$qname)){ + // get unqualified name + $name = substr(strstr($qname,':'),1); + // get ns prefix + $prefix = substr($qname,0,strpos($qname,':')); + if(isset($this->namespaces[$prefix])){ + return $this->namespaces[$prefix].':'.$name; + } else { + return $qname; + } + } else { + return $qname; + } + } + + /** + * returns the local part of a prefixed string + * returns the original string, if not prefixed + * + * @param string $str The prefixed string + * @return string The local part + * @access public + */ + function getLocalPart($str){ + if($sstr = strrchr($str,':')){ + // get unqualified name + return substr( $sstr, 1 ); + } else { + return $str; + } + } + + /** + * returns the prefix part of a prefixed string + * returns false, if not prefixed + * + * @param string $str The prefixed string + * @return mixed The prefix or false if there is no prefix + * @access public + */ + function getPrefix($str){ + if($pos = strrpos($str,':')){ + // get prefix + return substr($str,0,$pos); + } + return false; + } + + /** + * pass it a prefix, it returns a namespace + * + * @param string $prefix The prefix + * @return mixed The namespace, false if no namespace has the specified prefix + * @access public + */ + function getNamespaceFromPrefix($prefix){ + if (isset($this->namespaces[$prefix])) { + return $this->namespaces[$prefix]; + } + //$this->setError("No namespace registered for prefix '$prefix'"); + return false; + } + + /** + * returns the prefix for a given namespace (or prefix) + * or false if no prefixes registered for the given namespace + * + * @param string $ns The namespace + * @return mixed The prefix, false if the namespace has no prefixes + * @access public + */ + function getPrefixFromNamespace($ns) { + foreach ($this->namespaces as $p => $n) { + if ($ns == $n || $ns == $p) { + $this->usedNamespaces[$p] = $n; + return $p; + } + } + return false; + } + + /** + * returns the time in ODBC canonical form with microseconds + * + * @return string The time in ODBC canonical form with microseconds + * @access public + */ + function getmicrotime() { + if (function_exists('gettimeofday')) { + $tod = gettimeofday(); + $sec = $tod['sec']; + $usec = $tod['usec']; + } else { + $sec = time(); + $usec = 0; + } + return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec); + } + + /** + * Returns a string with the output of var_dump + * + * @param mixed $data The variable to var_dump + * @return string The output of var_dump + * @access public + */ + function varDump($data) { + ob_start(); + var_dump($data); + $ret_val = ob_get_contents(); + ob_end_clean(); + return $ret_val; + } +} + +// XML Schema Datatype Helper Functions + +//xsd:dateTime helpers + +/** +* convert unix timestamp to ISO 8601 compliant date string +* +* @param string $timestamp Unix time stamp +* @access public +*/ +function timestamp_to_iso8601($timestamp,$utc=true){ + $datestr = date('Y-m-d\TH:i:sO',$timestamp); + if($utc){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + + if(ereg($eregStr,$datestr,$regs)){ + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]); + } + return false; + } else { + return $datestr; + } +} + +/** +* convert ISO 8601 compliant date string to unix timestamp +* +* @param string $datestr ISO 8601 compliant date string +* @access public +*/ +function iso8601_to_timestamp($datestr){ + $eregStr = + '([0-9]{4})-'. // centuries & years CCYY- + '([0-9]{2})-'. // months MM- + '([0-9]{2})'. // days DD + 'T'. // separator T + '([0-9]{2}):'. // hours hh: + '([0-9]{2}):'. // minutes mm: + '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss... + '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's + if(ereg($eregStr,$datestr,$regs)){ + // not utc + if($regs[8] != 'Z'){ + $op = substr($regs[8],0,1); + $h = substr($regs[8],1,2); + $m = substr($regs[8],strlen($regs[8])-2,2); + if($op == '-'){ + $regs[4] = $regs[4] + $h; + $regs[5] = $regs[5] + $m; + } elseif($op == '+'){ + $regs[4] = $regs[4] - $h; + $regs[5] = $regs[5] - $m; + } + } + return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z"); + } else { + return false; + } +} + +/** +* sleeps some number of microseconds +* +* @param string $usec the number of microseconds to sleep +* @access public +* @deprecated +*/ +function usleepWindows($usec) +{ + $start = gettimeofday(); + + do + { + $stop = gettimeofday(); + $timePassed = 1000000 * ($stop['sec'] - $start['sec']) + + $stop['usec'] - $start['usec']; + } + while ($timePassed < $usec); +} + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_fault extends nusoap_base { + /** + * The fault code (client|server) + * @var string + * @access private + */ + var $faultcode; + /** + * The fault actor + * @var string + * @access private + */ + var $faultactor; + /** + * The fault string, a description of the fault + * @var string + * @access private + */ + var $faultstring; + /** + * The fault detail, typically a string or array of string + * @var mixed + * @access private + */ + var $faultdetail; + + /** + * constructor + * + * @param string $faultcode (client | server) + * @param string $faultactor only used when msg routed between multiple actors + * @param string $faultstring human readable error message + * @param mixed $faultdetail detail, typically a string or array of string + */ + function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){ + parent::nusoap_base(); + $this->faultcode = $faultcode; + $this->faultactor = $faultactor; + $this->faultstring = $faultstring; + $this->faultdetail = $faultdetail; + } + + /** + * serialize a fault + * + * @return string The serialization of the fault instance. + * @access public + */ + function serialize(){ + $ns_string = ''; + foreach($this->namespaces as $k => $v){ + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + 'soap_defencoding.'"?>'. + '\n". + ''. + ''. + $this->serialize_val($this->faultcode, 'faultcode'). + $this->serialize_val($this->faultactor, 'faultactor'). + $this->serialize_val($this->faultstring, 'faultstring'). + $this->serialize_val($this->faultdetail, 'detail'). + ''. + ''. + ''; + return $return_msg; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class XMLSchema extends nusoap_base { + + // files + var $schema = ''; + var $xml = ''; + // namespaces + var $enclosingNamespaces; + // schema info + var $schemaInfo = array(); + var $schemaTargetNamespace = ''; + // types, elements, attributes defined by the schema + var $attributes = array(); + var $complexTypes = array(); + var $complexTypeStack = array(); + var $currentComplexType = null; + var $elements = array(); + var $elementStack = array(); + var $currentElement = null; + var $simpleTypes = array(); + var $simpleTypeStack = array(); + var $currentSimpleType = null; + // imports + var $imports = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + var $message = array(); + var $defaultNamespace = array(); + + /** + * constructor + * + * @param string $schema schema document URI + * @param string $xml xml document URI + * @param string $namespaces namespaces defined in enclosing XML + * @access public + */ + function XMLSchema($schema='',$xml='',$namespaces=array()){ + parent::nusoap_base(); + $this->debug('xmlschema class instantiated, inside constructor'); + // files + $this->schema = $schema; + $this->xml = $xml; + + // namespaces + $this->enclosingNamespaces = $namespaces; + $this->namespaces = array_merge($this->namespaces, $namespaces); + + // parse schema file + if($schema != ''){ + $this->debug('initial schema file: '.$schema); + $this->parseFile($schema, 'schema'); + } + + // parse xml file + if($xml != ''){ + $this->debug('initial xml file: '.$xml); + $this->parseFile($xml, 'xml'); + } + + } + + /** + * parse an XML file + * + * @param string $xml, path/URL to XML file + * @param string $type, (schema | xml) + * @return boolean + * @access public + */ + function parseFile($xml,$type){ + // parse xml file + if($xml != ""){ + $xmlStr = @join("",@file($xml)); + if($xmlStr == ""){ + $msg = 'Error reading XML from '.$xml; + $this->setError($msg); + $this->debug($msg); + return false; + } else { + $this->debug("parsing $xml"); + $this->parseString($xmlStr,$type); + $this->debug("done parsing $xml"); + return true; + } + } + return false; + } + + /** + * parse an XML string + * + * @param string $xml path or URL + * @param string $type, (schema|xml) + * @access private + */ + function parseString($xml,$type){ + // parse xml string + if($xml != ""){ + + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + + // Set the object for the parser. + xml_set_object($this->parser, $this); + + // Set the element handlers for the parser. + if($type == "schema"){ + xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement'); + xml_set_character_data_handler($this->parser,'schemaCharacterData'); + } elseif($type == "xml"){ + xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement'); + xml_set_character_data_handler($this->parser,'xmlCharacterData'); + } + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $errstr = sprintf('XML error parsing XML schema on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $xml); + $this->setError($errstr); + } + + xml_parser_free($this->parser); + } else{ + $this->debug('no xml passed to parseString()!!'); + $this->setError('no xml passed to parseString()!!'); + } + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function schemaStartElement($parser, $name, $attrs) { + + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + if ($depth > 0) { + $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]]; + } else { + $this->defaultNamespace[$pos] = false; + } + + // get element prefix + if($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + + // loop thru attributes, expanding, and registering namespace declarations + if(count($attrs) > 0){ + foreach($attrs as $k => $v){ + // if ns declarations, add to class level array of valid namespaces + if(ereg("^xmlns",$k)){ + //$this->xdebug("$k: $v"); + //$this->xdebug('ns_prefix: '.$this->getPrefix($k)); + if($ns_prefix = substr(strrchr($k,':'),1)){ + //$this->xdebug("Add namespace[$ns_prefix] = $v"); + $this->namespaces[$ns_prefix] = $v; + } else { + $this->defaultNamespace[$pos] = $v; + if (! $this->getPrefixFromNamespace($v)) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $v; + } + } + if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){ + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v.'-instance'; + } + } + } + foreach($attrs as $k => $v){ + // expand each attribute + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // find status, register data + switch($name){ + case 'all': // (optional) compositor content for a complexType + case 'choice': + case 'group': + case 'sequence': + //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement"); + $this->complexTypes[$this->currentComplexType]['compositor'] = $name; + //if($name == 'all' || $name == 'sequence'){ + // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + //} + break; + case 'attribute': // complexType attribute + //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']); + $this->xdebug("parsing attribute:"); + $this->appendDebug($this->varDump($attrs)); + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['attributeFormDefault']; + } + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + if (!strpos($v, ':')) { + // no namespace in arrayType attribute value... + if ($this->defaultNamespace[$pos]) { + // ...so use the default + $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } + } + } + if(isset($attrs['name'])){ + $this->attributes[$attrs['name']] = $attrs; + $aname = $attrs['name']; + } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){ + if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) { + $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $aname = ''; + } + } elseif(isset($attrs['ref'])){ + $aname = $attrs['ref']; + $this->attributes[$attrs['ref']] = $attrs; + } + + if($this->currentComplexType){ // This should *always* be + $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs; + } + // arrayType attribute + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + $prefix = $this->getPrefix($aname); + if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){ + $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']; + } else { + $v = ''; + } + if(strpos($v,'[,]')){ + $this->complexTypes[$this->currentComplexType]['multidimensional'] = true; + } + $v = substr($v,0,strpos($v,'[')); // clip the [] + if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){ + $v = $this->XMLSchemaVersion.':'.$v; + } + $this->complexTypes[$this->currentComplexType]['arrayType'] = $v; + } + break; + case 'complexContent': // (optional) content for a complexType + break; + case 'complexType': + array_push($this->complexTypeStack, $this->currentComplexType); + if(isset($attrs['name'])){ + $this->xdebug('processing named complexType '.$attrs['name']); + //$this->currentElement = false; + $this->currentComplexType = $attrs['name']; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + }else{ + $this->xdebug('processing unnamed complexType for element '.$this->currentElement); + $this->currentComplexType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->complexTypes[$this->currentComplexType] = $attrs; + $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType'; + // This is for constructs like + // + // + // + // + // + if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){ + $this->xdebug('complexType is unusual array'); + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } else { + $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct'; + } + } + break; + case 'element': + array_push($this->elementStack, $this->currentElement); + // elements defined as part of a complex type should + // not really be added to $this->elements, but for some + // reason, they are + if (!isset($attrs['form'])) { + $attrs['form'] = $this->schemaInfo['elementFormDefault']; + } + if(isset($attrs['type'])){ + $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']); + if (! $this->getPrefix($attrs['type'])) { + if ($this->defaultNamespace[$pos]) { + $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type']; + $this->xdebug('used default namespace to make type ' . $attrs['type']); + } + } + // This is for constructs like + // + // + // + // + // + if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') { + $this->xdebug('arrayType for unusual array is ' . $attrs['type']); + $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type']; + } + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $ename = $attrs['name']; + } elseif(isset($attrs['ref'])){ + $this->xdebug("processing element as ref to ".$attrs['ref']); + $this->currentElement = "ref to ".$attrs['ref']; + $ename = $this->getLocalPart($attrs['ref']); + } else { + $this->xdebug("processing untyped element ".$attrs['name']); + $this->currentElement = $attrs['name']; + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType'; + $this->elements[ $attrs['name'] ]['type'] = $attrs['type']; + $ename = $attrs['name']; + } + if(isset($ename) && $this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs; + } + break; + case 'enumeration': // restriction value list member + $this->xdebug('enumeration ' . $attrs['value']); + if ($this->currentSimpleType) { + $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value']; + } elseif ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value']; + } + break; + case 'extension': // simpleContent or complexContent type extension + $this->xdebug('extension ' . $attrs['base']); + if ($this->currentComplexType) { + $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base']; + } + break; + case 'import': + if (isset($attrs['schemaLocation'])) { + //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']); + $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false); + } else { + //$this->xdebug('import namespace ' . $attrs['namespace']); + $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + } + break; + case 'list': // simpleType value list + break; + case 'restriction': // simpleType, simpleContent or complexContent value restriction + $this->xdebug('restriction ' . $attrs['base']); + if($this->currentSimpleType){ + $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base']; + } elseif($this->currentComplexType){ + $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base']; + if(strstr($attrs['base'],':') == ':Array'){ + $this->complexTypes[$this->currentComplexType]['phpType'] = 'array'; + } + } + break; + case 'schema': + $this->schemaInfo = $attrs; + $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix); + if (isset($attrs['targetNamespace'])) { + $this->schemaTargetNamespace = $attrs['targetNamespace']; + } + if (!isset($attrs['elementFormDefault'])) { + $this->schemaInfo['elementFormDefault'] = 'unqualified'; + } + if (!isset($attrs['attributeFormDefault'])) { + $this->schemaInfo['attributeFormDefault'] = 'unqualified'; + } + break; + case 'simpleContent': // (optional) content for a complexType + break; + case 'simpleType': + array_push($this->simpleTypeStack, $this->currentSimpleType); + if(isset($attrs['name'])){ + $this->xdebug("processing simpleType for name " . $attrs['name']); + $this->currentSimpleType = $attrs['name']; + $this->simpleTypes[ $attrs['name'] ] = $attrs; + $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType'; + $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar'; + } else { + $this->xdebug('processing unnamed simpleType for element '.$this->currentElement); + $this->currentSimpleType = $this->currentElement . '_ContainedType'; + //$this->currentElement = false; + $this->simpleTypes[$this->currentSimpleType] = $attrs; + $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar'; + } + break; + case 'union': // simpleType type list + break; + default: + //$this->xdebug("do not have anything to do for element $name"); + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function schemaEndElement($parser, $name) { + // bring depth down a notch + $this->depth--; + // position of current element is equal to the last value left in depth_array for my depth + if(isset($this->depth_array[$this->depth])){ + $pos = $this->depth_array[$this->depth]; + } + // get element prefix + if ($prefix = $this->getPrefix($name)){ + // get unqualified name + $name = $this->getLocalPart($name); + } else { + $prefix = ''; + } + // move on... + if($name == 'complexType'){ + $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)')); + $this->currentComplexType = array_pop($this->complexTypeStack); + //$this->currentElement = false; + } + if($name == 'element'){ + $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)')); + $this->currentElement = array_pop($this->elementStack); + } + if($name == 'simpleType'){ + $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)')); + $this->currentSimpleType = array_pop($this->simpleTypeStack); + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function schemaCharacterData($parser, $data){ + $pos = $this->depth_array[$this->depth - 1]; + $this->message[$pos]['cdata'] .= $data; + } + + /** + * serialize the schema + * + * @access public + */ + function serializeSchema(){ + + $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion); + $xml = ''; + // imports + if (sizeof($this->imports) > 0) { + foreach($this->imports as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n"; + } else { + $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n"; + } + } + } + } + // complex types + foreach($this->complexTypes as $typeName => $attrs){ + $contentStr = ''; + // serialize child elements + if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){ + foreach($attrs['elements'] as $element => $eParts){ + if(isset($eParts['ref'])){ + $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n"; + } else { + $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\""; + foreach ($eParts as $aName => $aValue) { + // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable + if ($aName != 'name' && $aName != 'type') { + $contentStr .= " $aName=\"$aValue\""; + } + } + $contentStr .= "/>\n"; + } + } + // compositor wraps elements + if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) { + $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." \n"; + } + } + // attributes + if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){ + foreach($attrs['attrs'] as $attr => $aParts){ + $contentStr .= " <$schemaPrefix:attribute"; + foreach ($aParts as $a => $v) { + if ($a == 'ref' || $a == 'type') { + $contentStr .= " $a=\"".$this->contractQName($v).'"'; + } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') { + $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl']; + $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"'; + } else { + $contentStr .= " $a=\"$v\""; + } + } + $contentStr .= "/>\n"; + } + } + // if restriction + if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){ + $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." \n"; + // complex or simple content + if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){ + $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." \n"; + } + } + // finalize complex type + if($contentStr != ''){ + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." \n"; + } else { + $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n"; + } + $xml .= $contentStr; + } + // simple types + if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){ + foreach($this->simpleTypes as $typeName => $eParts){ + $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n"; + if (isset($eParts['enumeration'])) { + foreach ($eParts['enumeration'] as $e) { + $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n"; + } + } + $xml .= " "; + } + } + // elements + if(isset($this->elements) && count($this->elements) > 0){ + foreach($this->elements as $element => $eParts){ + $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n"; + } + } + // attributes + if(isset($this->attributes) && count($this->attributes) > 0){ + foreach($this->attributes as $attr => $aParts){ + $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>"; + } + } + // finish 'er up + $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n"; + foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) { + $el .= " xmlns:$nsp=\"$ns\"\n"; + } + $xml = $el . ">\n".$xml."\n"; + return $xml; + } + + /** + * adds debug data to the clas level debug string + * + * @param string $string debug data + * @access private + */ + function xdebug($string){ + $this->debug('<' . $this->schemaTargetNamespace . '> '.$string); + } + + /** + * get the PHP type of a user defined type in the schema + * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays + * returns false if no type exists, or not w/ the given namespace + * else returns a string that is either a native php type, or 'struct' + * + * @param string $type, name of defined type + * @param string $ns, namespace of type + * @return mixed + * @access public + * @deprecated + */ + function getPHPType($type,$ns){ + if(isset($this->typemap[$ns][$type])){ + //print "found type '$type' and ns $ns in typemap
    "; + return $this->typemap[$ns][$type]; + } elseif(isset($this->complexTypes[$type])){ + //print "getting type '$type' and ns $ns from complexTypes array
    "; + return $this->complexTypes[$type]['phpType']; + } + return false; + } + + /** + * returns an associative array of information about a given type + * returns false if no type exists by the given name + * + * For a complexType typeDef = array( + * 'restrictionBase' => '', + * 'phpType' => '', + * 'compositor' => '(sequence|all)', + * 'elements' => array(), // refs to elements array + * 'attrs' => array() // refs to attributes array + * ... and so on (see addComplexType) + * ) + * + * For simpleType or element, the array has different keys. + * + * @param string + * @return mixed + * @access public + * @see addComplexType + * @see addSimpleType + * @see addElement + */ + function getTypeDef($type){ + //$this->debug("in getTypeDef for type $type"); + if(isset($this->complexTypes[$type])){ + $this->xdebug("in getTypeDef, found complexType $type"); + return $this->complexTypes[$type]; + } elseif(isset($this->simpleTypes[$type])){ + $this->xdebug("in getTypeDef, found simpleType $type"); + if (!isset($this->simpleTypes[$type]['phpType'])) { + // get info for type to tack onto the simple type + // TODO: can this ever really apply (i.e. what is a simpleType really?) + $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1); + $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for simpleType $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->simpleTypes[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->simpleTypes[$type]['elements'] = $etype['elements']; + } + } + } + return $this->simpleTypes[$type]; + } elseif(isset($this->elements[$type])){ + $this->xdebug("in getTypeDef, found element $type"); + if (!isset($this->elements[$type]['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1); + $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':')); + $etype = $this->getTypeDef($uqType); + if ($etype) { + $this->xdebug("in getTypeDef, found type for element $type:"); + $this->xdebug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $this->elements[$type]['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $this->elements[$type]['elements'] = $etype['elements']; + } + } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') { + $this->xdebug("in getTypeDef, element $type is an XSD type"); + $this->elements[$type]['phpType'] = 'scalar'; + } + } + return $this->elements[$type]; + } elseif(isset($this->attributes[$type])){ + $this->xdebug("in getTypeDef, found attribute $type"); + return $this->attributes[$type]; + } elseif (ereg('_ContainedType$', $type)) { + $this->xdebug("in getTypeDef, have an untyped element $type"); + $typeDef['typeClass'] = 'simpleType'; + $typeDef['phpType'] = 'scalar'; + $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string'; + return $typeDef; + } + $this->xdebug("in getTypeDef, did not find $type"); + return false; + } + + /** + * returns a sample serialization of a given type, or false if no type by the given name + * + * @param string $type, name of type + * @return mixed + * @access public + * @deprecated + */ + function serializeTypeDef($type){ + //print "in sTD() for type $type
    "; + if($typeDef = $this->getTypeDef($type)){ + $str .= '<'.$type; + if(is_array($typeDef['attrs'])){ + foreach($attrs as $attName => $data){ + $str .= " $attName=\"{type = ".$data['type']."}\""; + } + } + $str .= " xmlns=\"".$this->schema['targetNamespace']."\""; + if(count($typeDef['elements']) > 0){ + $str .= ">"; + foreach($typeDef['elements'] as $element => $eData){ + $str .= $this->serializeTypeDef($element); + } + $str .= ""; + } elseif($typeDef['typeClass'] == 'element') { + $str .= ">"; + } else { + $str .= "/>"; + } + return $str; + } + return false; + } + + /** + * returns HTML form elements that allow a user + * to enter values for creating an instance of the given type. + * + * @param string $name, name for type instance + * @param string $type, name of type + * @return string + * @access public + * @deprecated + */ + function typeToForm($name,$type){ + // get typedef + if($typeDef = $this->getTypeDef($type)){ + // if struct + if($typeDef['phpType'] == 'struct'){ + $buffer .= ''; + foreach($typeDef['elements'] as $child => $childDef){ + $buffer .= " + + "; + } + $buffer .= '
    $childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):
    '; + // if array + } elseif($typeDef['phpType'] == 'array'){ + $buffer .= ''; + for($i=0;$i < 3; $i++){ + $buffer .= " + + "; + } + $buffer .= '
    array item (type: $typeDef[arrayType]):
    '; + // if scalar + } else { + $buffer .= ""; + } + } else { + $buffer .= ""; + } + return $buffer; + } + + /** + * adds a complex type to the schema + * + * example: array + * + * addType( + * 'ArrayOfstring', + * 'complexType', + * 'array', + * '', + * 'SOAP-ENC:Array', + * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'), + * 'xsd:string' + * ); + * + * example: PHP associative array ( SOAP Struct ) + * + * addType( + * 'SOAPStruct', + * 'complexType', + * 'struct', + * 'all', + * array('myVar'=> array('name'=>'myVar','type'=>'string') + * ); + * + * @param name + * @param typeClass (complexType|simpleType|attribute) + * @param phpType: currently supported are array and struct (php assoc array) + * @param compositor (all|sequence|choice) + * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param elements = array ( name = array(name=>'',type=>'') ) + * @param attrs = array( + * array( + * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType", + * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]" + * ) + * ) + * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string) + * @access public + * @see getTypeDef + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){ + $this->complexTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'compositor'=> $compositor, + 'restrictionBase' => $restrictionBase, + 'elements' => $elements, + 'attrs' => $attrs, + 'arrayType' => $arrayType + ); + + $this->xdebug("addComplexType $name:"); + $this->appendDebug($this->varDump($this->complexTypes[$name])); + } + + /** + * adds a simple type to the schema + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @access public + * @see xmlschema + * @see getTypeDef + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $this->simpleTypes[$name] = array( + 'name' => $name, + 'typeClass' => $typeClass, + 'phpType' => $phpType, + 'type' => $restrictionBase, + 'enumeration' => $enumeration + ); + + $this->xdebug("addSimpleType $name:"); + $this->appendDebug($this->varDump($this->simpleTypes[$name])); + } + + /** + * adds an element to the schema + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + if (! $this->getPrefix($attrs['type'])) { + $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type']; + } + $this->elements[ $attrs['name'] ] = $attrs; + $this->elements[ $attrs['name'] ]['typeClass'] = 'element'; + + $this->xdebug("addElement " . $attrs['name']); + $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ])); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soapval extends nusoap_base { + /** + * The XML element name + * + * @var string + * @access private + */ + var $name; + /** + * The XML type name (string or false) + * + * @var mixed + * @access private + */ + var $type; + /** + * The PHP value + * + * @var mixed + * @access private + */ + var $value; + /** + * The XML element namespace (string or false) + * + * @var mixed + * @access private + */ + var $element_ns; + /** + * The XML type namespace (string or false) + * + * @var mixed + * @access private + */ + var $type_ns; + /** + * The XML element attributes (array or false) + * + * @var mixed + * @access private + */ + var $attributes; + + /** + * constructor + * + * @param string $name optional name + * @param mixed $type optional type name + * @param mixed $value optional value + * @param mixed $element_ns optional namespace of value + * @param mixed $type_ns optional namespace of type + * @param mixed $attributes associative array of attributes to add to element serialization + * @access public + */ + function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) { + parent::nusoap_base(); + $this->name = $name; + $this->type = $type; + $this->value = $value; + $this->element_ns = $element_ns; + $this->type_ns = $type_ns; + $this->attributes = $attributes; + } + + /** + * return serialized value + * + * @param string $use The WSDL use value (encoded|literal) + * @return string XML data + * @access public + */ + function serialize($use='encoded') { + return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use); + } + + /** + * decodes a soapval object into a PHP native type + * + * @return mixed + * @access public + */ + function decode(){ + return $this->value; + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_transport_http extends nusoap_base { + + var $url = ''; + var $uri = ''; + var $digest_uri = ''; + var $scheme = ''; + var $host = ''; + var $port = ''; + var $path = ''; + var $request_method = 'POST'; + var $protocol_version = '1.0'; + var $encoding = ''; + var $outgoing_headers = array(); + var $incoming_headers = array(); + var $incoming_cookies = array(); + var $outgoing_payload = ''; + var $incoming_payload = ''; + var $useSOAPAction = true; + var $persistentConnection = false; + var $ch = false; // cURL handle + var $username = ''; + var $password = ''; + var $authtype = ''; + var $digestRequest = array(); + var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional) + // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem' + // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem' + // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem' + // passphrase: SSL key password/passphrase + // verifypeer: default is 1 + // verifyhost: default is 1 + + /** + * constructor + */ + function soap_transport_http($url){ + parent::nusoap_base(); + $this->setURL($url); + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')'; + $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']); + } + + function setURL($url) { + $this->url = $url; + + $u = parse_url($url); + foreach($u as $k => $v){ + $this->debug("$k = $v"); + $this->$k = $v; + } + + // add any GET params to path + if(isset($u['query']) && $u['query'] != ''){ + $this->path .= '?' . $u['query']; + } + + // set default port + if(!isset($u['port'])){ + if($u['scheme'] == 'https'){ + $this->port = 443; + } else { + $this->port = 80; + } + } + + $this->uri = $this->path; + $this->digest_uri = $this->uri; + + // build headers + if (!isset($u['port'])) { + $this->outgoing_headers['Host'] = $this->host; + } else { + $this->outgoing_headers['Host'] = $this->host.':'.$this->port; + } + $this->debug('set Host: ' . $this->outgoing_headers['Host']); + + if (isset($u['user']) && $u['user'] != '') { + $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : ''); + } + } + + function connect($connection_timeout=0,$response_timeout=30){ + // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like + // "regular" socket. + // TODO: disabled for now because OpenSSL must be *compiled* in (not just + // loaded), and until PHP5 stream_get_wrappers is not available. +// if ($this->scheme == 'https') { +// if (version_compare(phpversion(), '4.3.0') >= 0) { +// if (extension_loaded('openssl')) { +// $this->scheme = 'ssl'; +// $this->debug('Using SSL over OpenSSL'); +// } +// } +// } + $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port"); + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // use persistent connection + if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){ + if (!feof($this->fp)) { + $this->debug('Re-use persistent connection'); + return true; + } + fclose($this->fp); + $this->debug('Closed persistent connection at EOF'); + } + + // munge host if using OpenSSL + if ($this->scheme == 'ssl') { + $host = 'ssl://' . $this->host; + } else { + $host = $this->host; + } + $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout); + + // open socket + if($connection_timeout > 0){ + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout); + } else { + $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str); + } + + // test pointer + if(!$this->fp) { + $msg = 'Couldn\'t open socket connection to server ' . $this->url; + if ($this->errno) { + $msg .= ', Error ('.$this->errno.'): '.$this->error_str; + } else { + $msg .= ' prior to connect(). This is often a problem looking up the host name.'; + } + $this->debug($msg); + $this->setError($msg); + return false; + } + + // set response timeout + $this->debug('set response timeout to ' . $response_timeout); + socket_set_timeout( $this->fp, $response_timeout); + + $this->debug('socket connected'); + return true; + } else if ($this->scheme == 'https') { + if (!extension_loaded('curl')) { + $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS'); + return false; + } + $this->debug('connect using https'); + // init CURL + $this->ch = curl_init(); + // set url + $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host"; + // add path + $hostURL .= $this->path; + curl_setopt($this->ch, CURLOPT_URL, $hostURL); + // follow location headers (re-directs) + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1); + // ask for headers in the response output + curl_setopt($this->ch, CURLOPT_HEADER, 1); + // ask for the response output as the return value + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + // encode + // We manage this ourselves through headers and encoding +// if(function_exists('gzuncompress')){ +// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate'); +// } + // persistent connection + if ($this->persistentConnection) { + // The way we send data, we cannot use persistent connections, since + // there will be some "junk" at the end of our request. + //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true); + $this->persistentConnection = false; + $this->outgoing_headers['Connection'] = 'close'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + // set timeout + if ($connection_timeout != 0) { + curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout); + } + // TODO: cURL has added a connection timeout separate from the response timeout + //if ($connection_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout); + //} + //if ($response_timeout != 0) { + // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout); + //} + + // recent versions of cURL turn on peer/host checking by default, + // while PHP binaries are not compiled with a default location for the + // CA cert bundle, so disable peer/host checking. +//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt'); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0); + + // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo) + if ($this->authtype == 'certificate') { + //added by Onti + $this->debug('authtype == certificate'); + if (isset($this->certRequest['cainfofile'])) { + curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']); + } + if (isset($this->certRequest['verifypeer'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1); + } + if (isset($this->certRequest['verifyhost'])) { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']); + } else { + curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1); + } + if (isset($this->certRequest['sslcertfile'])) { + curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']); + } + if (isset($this->certRequest['sslkeyfile'])) { + curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']); + } + if (isset($this->certRequest['passphrase'])) { + curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']); + } + curl_setopt($this->ch, CURLOPT_VERBOSE , 1 ); + //$handle = fopen('/home/xfer/curl.log', "ab+"); + //fwrite ($handle, date('Y-m-d H:i:s')."\n\n"); + //curl_setopt($this->ch, CURLOPT_STDERR, $handle ); + } + $this->debug('cURL connection set up'); + return true; + } else { + $this->setError('Unknown scheme ' . $this->scheme); + $this->debug('Unknown scheme ' . $this->scheme); + return false; + } + } + + /** + * send the SOAP message via HTTP + * + * @param string $data message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) { + + $this->debug('entered send() with data of length: '.strlen($data)); + + $this->tryagain = true; + $tries = 0; + while ($this->tryagain) { + $this->tryagain = false; + if ($tries++ < 2) { + // make connnection + if (!$this->connect($timeout, $response_timeout)){ + return false; + } + + // send request + if (!$this->sendRequest($data, $cookies)){ + return false; + } + + // get response + $respdata = $this->getResponse(); + } else { + $this->setError('Too many tries to get an OK response'); + } + } + $this->debug('end of send()'); + return $respdata; + } + + + /** + * send the SOAP message via HTTPS 1.0 using CURL + * + * @param string $msg message data + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @param array $cookies cookies to send + * @return string data + * @access public + */ + function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) { + return $this->send($data, $timeout, $response_timeout, $cookies); + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic, digest, certificate) + * @param array $digestRequest (keys must be nonce, nc, realm, qop) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) { + $this->debug("Set credentials for authtype $authtype"); + // cf. RFC 2617 + if ($authtype == 'basic') { + $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password); + } elseif ($authtype == 'digest') { + if (isset($digestRequest['nonce'])) { + $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1; + + // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html) + + // A1 = unq(username-value) ":" unq(realm-value) ":" passwd + $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password; + + // H(A1) = MD5(A1) + $HA1 = md5($A1); + + // A2 = Method ":" digest-uri-value + $A2 = 'POST:' . $this->digest_uri; + + // H(A2) + $HA2 = md5($A2); + + // KD(secret, data) = H(concat(secret, ":", data)) + // if qop == auth: + // request-digest = <"> < KD ( H(A1), unq(nonce-value) + // ":" nc-value + // ":" unq(cnonce-value) + // ":" unq(qop-value) + // ":" H(A2) + // ) <"> + // if qop is missing, + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> + + $unhashedDigest = ''; + $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : ''; + $cnonce = $nonce; + if ($digestRequest['qop'] != '') { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2; + } else { + $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2; + } + + $hashedDigest = md5($unhashedDigest); + + $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"'; + } + } elseif ($authtype == 'certificate') { + $this->certRequest = $certRequest; + } + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->digestRequest = $digestRequest; + + if (isset($this->outgoing_headers['Authorization'])) { + $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...'); + } else { + $this->debug('Authorization header not set'); + } + } + + /** + * set the soapaction value + * + * @param string $soapaction + * @access public + */ + function setSOAPAction($soapaction) { + $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"'; + $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']); + } + + /** + * use http encoding + * + * @param string $enc encoding style. supported values: gzip, deflate, or both + * @access public + */ + function setEncoding($enc='gzip, deflate') { + if (function_exists('gzdeflate')) { + $this->protocol_version = '1.1'; + $this->outgoing_headers['Accept-Encoding'] = $enc; + $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']); + if (!isset($this->outgoing_headers['Connection'])) { + $this->outgoing_headers['Connection'] = 'close'; + $this->persistentConnection = false; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + } + set_magic_quotes_runtime(0); + // deprecated + $this->encoding = $enc; + } + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->uri = $this->url; + $this->host = $proxyhost; + $this->port = $proxyport; + if ($proxyusername != '' && $proxypassword != '') { + $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword); + $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']); + } + } + + /** + * decode a string that is encoded w/ "chunked' transfer encoding + * as defined in RFC2068 19.4.6 + * + * @param string $buffer + * @param string $lb + * @returns string + * @access public + * @deprecated + */ + function decodeChunked($buffer, $lb){ + // length := 0 + $length = 0; + $new = ''; + + // read chunk-size, chunk-extension (if any) and CRLF + // get the position of the linebreak + $chunkend = strpos($buffer, $lb); + if ($chunkend == FALSE) { + $this->debug('no linebreak found in decodeChunked'); + return $new; + } + $temp = substr($buffer,0,$chunkend); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend + strlen($lb); + // while (chunk-size > 0) { + while ($chunk_size > 0) { + $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size"); + $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size); + + // Just in case we got a broken connection + if ($chunkend == FALSE) { + $chunk = substr($buffer,$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + $length += strlen($chunk); + break; + } + + // read chunk-data and CRLF + $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart); + // append chunk-data to entity-body + $new .= $chunk; + // length := length + chunk-size + $length += strlen($chunk); + // read chunk-size and CRLF + $chunkstart = $chunkend + strlen($lb); + + $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb); + if ($chunkend == FALSE) { + break; //Just in case we got a broken connection + } + $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart); + $chunk_size = hexdec( trim($temp) ); + $chunkstart = $chunkend; + } + return $new; + } + + /* + * Writes payload, including HTTP headers, to $this->outgoing_payload. + */ + function buildPayload($data, $cookie_str = '') { + // add content-length header + $this->outgoing_headers['Content-Length'] = strlen($data); + $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']); + + // start building outgoing payload: + $req = "$this->request_method $this->uri HTTP/$this->protocol_version"; + $this->debug("HTTP request: $req"); + $this->outgoing_payload = "$req\r\n"; + + // loop thru headers, serializing + foreach($this->outgoing_headers as $k => $v){ + $hdr = $k.': '.$v; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // add any cookies + if ($cookie_str != '') { + $hdr = 'Cookie: '.$cookie_str; + $this->debug("HTTP header: $hdr"); + $this->outgoing_payload .= "$hdr\r\n"; + } + + // header/body separator + $this->outgoing_payload .= "\r\n"; + + // add data + $this->outgoing_payload .= $data; + } + + function sendRequest($data, $cookies = NULL) { + // build cookie string + $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https'))); + + // build payload + $this->buildPayload($data, $cookie_str); + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // send payload + if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { + $this->setError('couldn\'t write message data to socket'); + $this->debug('couldn\'t write message data to socket'); + return false; + } + $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload)); + return true; + } else if ($this->scheme == 'https') { + // set payload + // TODO: cURL does say this should only be the verb, and in fact it + // turns out that the URI and HTTP version are appended to this, which + // some servers refuse to work with + //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload); + foreach($this->outgoing_headers as $k => $v){ + $curl_headers[] = "$k: $v"; + } + if ($cookie_str != '') { + $curl_headers[] = 'Cookie: ' . $cookie_str; + } + curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers); + if ($this->request_method == "POST") { + curl_setopt($this->ch, CURLOPT_POST, 1); + curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); + } else { + } + $this->debug('set cURL payload'); + return true; + } + } + + function getResponse(){ + $this->incoming_payload = ''; + + if ($this->scheme == 'http' || $this->scheme == 'ssl') { + // loop until headers have been retrieved + $data = ''; + while (!isset($lb)){ + + // We might EOF during header read. + if(feof($this->fp)) { + $this->incoming_payload = $data; + $this->debug('found no headers before EOF after length ' . strlen($data)); + $this->debug("received before EOF:\n" . $data); + $this->setError('server failed to send headers'); + return false; + } + + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read line of $tmplen bytes: " . trim($tmp)); + + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of headers timed out after length ' . strlen($data)); + $this->debug("read before timeout: " . $data); + $this->setError('socket read of headers timed out'); + return false; + } + + $data .= $tmp; + $pos = strpos($data,"\r\n\r\n"); + if($pos > 1){ + $lb = "\r\n"; + } else { + $pos = strpos($data,"\n\n"); + if($pos > 1){ + $lb = "\n"; + } + } + // remove 100 header + if(isset($lb) && ereg('^HTTP/1.1 100',$data)){ + unset($lb); + $data = ''; + }// + } + // store header data + $this->incoming_payload .= $data; + $this->debug('found end of headers after length ' . strlen($data)); + // process headers + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $this->incoming_headers = array(); + $this->incoming_cookies = array(); + foreach($header_array as $header_line){ + $arr = explode(':',$header_line, 2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + + // loop until msg has been received + if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') { + $content_length = 2147483647; // ignore any content-length header + $chunked = true; + $this->debug("want to read chunked content"); + } elseif (isset($this->incoming_headers['content-length'])) { + $content_length = $this->incoming_headers['content-length']; + $chunked = false; + $this->debug("want to read content of length $content_length"); + } else { + $content_length = 2147483647; + $chunked = false; + $this->debug("want to read content to EOF"); + } + $data = ''; + do { + if ($chunked) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk line of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk length timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk length timed out'); + return false; + } + $content_length = hexdec(trim($tmp)); + $this->debug("chunk length $content_length"); + } + $strlen = 0; + while (($strlen < $content_length) && (!feof($this->fp))) { + $readlen = min(8192, $content_length - $strlen); + $tmp = fread($this->fp, $readlen); + $tmplen = strlen($tmp); + $this->debug("read buffer of $tmplen bytes"); + if (($tmplen == 0) && (!feof($this->fp))) { + $this->incoming_payload = $data; + $this->debug('socket read of body timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of body timed out'); + return false; + } + $strlen += $tmplen; + $data .= $tmp; + } + if ($chunked && ($content_length > 0)) { + $tmp = fgets($this->fp, 256); + $tmplen = strlen($tmp); + $this->debug("read chunk terminator of $tmplen bytes"); + if ($tmplen == 0) { + $this->incoming_payload = $data; + $this->debug('socket read of chunk terminator timed out after length ' . strlen($data)); + $this->debug("read before timeout:\n" . $data); + $this->setError('socket read of chunk terminator timed out'); + return false; + } + } + } while ($chunked && ($content_length > 0) && (!feof($this->fp))); + if (feof($this->fp)) { + $this->debug('read to EOF'); + } + $this->debug('read body of length ' . strlen($data)); + $this->incoming_payload .= $data; + $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server'); + + // close filepointer + if( + (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || + (! $this->persistentConnection) || feof($this->fp)){ + fclose($this->fp); + $this->fp = false; + $this->debug('closed socket'); + } + + // connection was closed unexpectedly + if($this->incoming_payload == ''){ + $this->setError('no response from server'); + return false; + } + + // decode transfer-encoding +// if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){ +// if(!$data = $this->decodeChunked($data, $lb)){ +// $this->setError('Decoding of chunked data failed'); +// return false; +// } + //print "
    \nde-chunked:\n---------------\n$data\n\n---------------\n
    "; + // set decoded payload +// $this->incoming_payload = $header_data.$lb.$lb.$data; +// } + + } else if ($this->scheme == 'https') { + // send and receive + $this->debug('send and receive with cURL'); + $this->incoming_payload = curl_exec($this->ch); + $data = $this->incoming_payload; + + $cErr = curl_error($this->ch); + if ($cErr != '') { + $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'
    '; + // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE + foreach(curl_getinfo($this->ch) as $k => $v){ + $err .= "$k: $v
    "; + } + $this->debug($err); + $this->setError($err); + curl_close($this->ch); + return false; + } else { + //echo '
    ';
    +			//var_dump(curl_getinfo($this->ch));
    +			//echo '
    '; + } + // close curl + $this->debug('No cURL error, closing cURL'); + curl_close($this->ch); + + // remove 100 header(s) + while (ereg('^HTTP/1.1 100',$data)) { + if ($pos = strpos($data,"\r\n\r\n")) { + $data = ltrim(substr($data,$pos)); + } elseif($pos = strpos($data,"\n\n") ) { + $data = ltrim(substr($data,$pos)); + } + } + + // separate content from HTTP headers + if ($pos = strpos($data,"\r\n\r\n")) { + $lb = "\r\n"; + } elseif( $pos = strpos($data,"\n\n")) { + $lb = "\n"; + } else { + $this->debug('no proper separation of headers and document'); + $this->setError('no proper separation of headers and document'); + return false; + } + $header_data = trim(substr($data,0,$pos)); + $header_array = explode($lb,$header_data); + $data = ltrim(substr($data,$pos)); + $this->debug('found proper separation of headers and document'); + $this->debug('cleaned data, stringlen: '.strlen($data)); + // clean headers + foreach ($header_array as $header_line) { + $arr = explode(':',$header_line,2); + if(count($arr) > 1){ + $header_name = strtolower(trim($arr[0])); + $this->incoming_headers[$header_name] = trim($arr[1]); + if ($header_name == 'set-cookie') { + // TODO: allow multiple cookies from parseCookie + $cookie = $this->parseCookie(trim($arr[1])); + if ($cookie) { + $this->incoming_cookies[] = $cookie; + $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']); + } else { + $this->debug('did not find cookie in ' . trim($arr[1])); + } + } + } else if (isset($header_name)) { + // append continuation line to previous header + $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line; + } + } + } + + $arr = explode(' ', $header_array[0], 3); + $http_version = $arr[0]; + $http_status = intval($arr[1]); + $http_reason = count($arr) > 2 ? $arr[2] : ''; + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['location']) && $http_status == 301) { + $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']); + $this->setURL($this->incoming_headers['location']); + $this->tryagain = true; + return false; + } + + // see if we need to resend the request with http digest authentication + if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) { + $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']); + if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) { + $this->debug('Server wants digest authentication'); + // remove "Digest " from our elements + $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']); + + // parse elements into array + $digestElements = explode(',', $digestString); + foreach ($digestElements as $val) { + $tempElement = explode('=', trim($val), 2); + $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]); + } + + // should have (at least) qop, realm, nonce + if (isset($digestRequest['nonce'])) { + $this->setCredentials($this->username, $this->password, 'digest', $digestRequest); + $this->tryagain = true; + return false; + } + } + $this->debug('HTTP authentication failed'); + $this->setError('HTTP authentication failed'); + return false; + } + + if ( + ($http_status >= 300 && $http_status <= 307) || + ($http_status >= 400 && $http_status <= 417) || + ($http_status >= 501 && $http_status <= 505) + ) { + $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)"); + return false; + } + + // decode content-encoding + if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){ + if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){ + // if decoding works, use it. else assume data wasn't gzencoded + if(function_exists('gzinflate')){ + //$timer->setMarker('starting decoding of gzip/deflated content'); + // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress) + // this means there are no Zlib headers, although there should be + $this->debug('The gzinflate function exists'); + $datalen = strlen($data); + if ($this->incoming_headers['content-encoding'] == 'deflate') { + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The inflated payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate($data)) { + $data = $degzdata; + $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to inflate the payload'); + $this->setError('Error using gzinflate to inflate the payload'); + } + } elseif ($this->incoming_headers['content-encoding'] == 'gzip') { + if ($degzdata = @gzinflate(substr($data, 10))) { // do our best + $data = $degzdata; + $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes'); + if (strlen($data) < $datalen) { + // test for the case that the payload has been compressed twice + $this->debug('The un-gzipped payload is smaller than the gzipped one; try again'); + if ($degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes'); + } + } + } else { + $this->debug('Error using gzinflate to un-gzip the payload'); + $this->setError('Error using gzinflate to un-gzip the payload'); + } + } + //$timer->setMarker('finished decoding of gzip/deflated content'); + //print "\nde-inflated:\n---------------\n$data\n-------------\n"; + // set decoded payload + $this->incoming_payload = $header_data.$lb.$lb.$data; + } else { + $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.'); + } + } else { + $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']); + } + } else { + $this->debug('No Content-Encoding header'); + } + + if(strlen($data) == 0){ + $this->debug('no data after headers!'); + $this->setError('no data present after HTTP headers'); + return false; + } + + return $data; + } + + function setContentType($type, $charset = false) { + $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : ''); + $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']); + } + + function usePersistentConnection(){ + if (isset($this->outgoing_headers['Accept-Encoding'])) { + return false; + } + $this->protocol_version = '1.1'; + $this->persistentConnection = true; + $this->outgoing_headers['Connection'] = 'Keep-Alive'; + $this->debug('set Connection: ' . $this->outgoing_headers['Connection']); + return true; + } + + /** + * parse an incoming Cookie into it's parts + * + * @param string $cookie_str content of cookie + * @return array with data of that cookie + * @access private + */ + /* + * TODO: allow a Set-Cookie string to be parsed into multiple cookies + */ + function parseCookie($cookie_str) { + $cookie_str = str_replace('; ', ';', $cookie_str) . ';'; + $data = split(';', $cookie_str); + $value_str = $data[0]; + + $cookie_param = 'domain='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $domain = substr($cookie_str, $start + strlen($cookie_param)); + $domain = substr($domain, 0, strpos($domain, ';')); + } else { + $domain = ''; + } + + $cookie_param = 'expires='; + $start = strpos($cookie_str, $cookie_param); + if ($start > 0) { + $expires = substr($cookie_str, $start + strlen($cookie_param)); + $expires = substr($expires, 0, strpos($expires, ';')); + } else { + $expires = ''; + } + + $cookie_param = 'path='; + $start = strpos($cookie_str, $cookie_param); + if ( $start > 0 ) { + $path = substr($cookie_str, $start + strlen($cookie_param)); + $path = substr($path, 0, strpos($path, ';')); + } else { + $path = '/'; + } + + $cookie_param = ';secure;'; + if (strpos($cookie_str, $cookie_param) !== FALSE) { + $secure = true; + } else { + $secure = false; + } + + $sep_pos = strpos($value_str, '='); + + if ($sep_pos) { + $name = substr($value_str, 0, $sep_pos); + $value = substr($value_str, $sep_pos + 1); + $cookie= array( 'name' => $name, + 'value' => $value, + 'domain' => $domain, + 'path' => $path, + 'expires' => $expires, + 'secure' => $secure + ); + return $cookie; + } + return false; + } + + /** + * sort out cookies for the current request + * + * @param array $cookies array with all cookies + * @param boolean $secure is the send-content secure or not? + * @return string for Cookie-HTTP-Header + * @access private + */ + function getCookiesForRequest($cookies, $secure=false) { + $cookie_str = ''; + if ((! is_null($cookies)) && (is_array($cookies))) { + foreach ($cookies as $cookie) { + if (! is_array($cookie)) { + continue; + } + $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']); + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) <= time()) { + $this->debug('cookie has expired'); + continue; + } + } + if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) { + $domain = preg_quote($cookie['domain']); + if (! preg_match("'.*$domain$'i", $this->host)) { + $this->debug('cookie has different domain'); + continue; + } + } + if ((isset($cookie['path'])) && (! empty($cookie['path']))) { + $path = preg_quote($cookie['path']); + if (! preg_match("'^$path.*'i", $this->path)) { + $this->debug('cookie is for a different path'); + continue; + } + } + if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) { + $this->debug('cookie is secure, transport is not'); + continue; + } + $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; '; + $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']); + } + } + return $cookie_str; + } +} + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_server extends nusoap_base { + /** + * HTTP headers of request + * @var array + * @access private + */ + var $headers = array(); + /** + * HTTP request + * @var string + * @access private + */ + var $request = ''; + /** + * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $requestHeaders = ''; + /** + * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text) + * @var string + * @access public + */ + var $document = ''; + /** + * SOAP payload for request (text) + * @var string + * @access public + */ + var $requestSOAP = ''; + /** + * requested method namespace URI + * @var string + * @access private + */ + var $methodURI = ''; + /** + * name of method requested + * @var string + * @access private + */ + var $methodname = ''; + /** + * method parameters from request + * @var array + * @access private + */ + var $methodparams = array(); + /** + * SOAP Action from request + * @var string + * @access private + */ + var $SOAPAction = ''; + /** + * character set encoding of incoming (request) messages + * @var string + * @access public + */ + var $xml_encoding = ''; + /** + * toggles whether the parser decodes element content w/ utf8_decode() + * @var boolean + * @access public + */ + var $decode_utf8 = true; + + /** + * HTTP headers of response + * @var array + * @access public + */ + var $outgoing_headers = array(); + /** + * HTTP response + * @var string + * @access private + */ + var $response = ''; + /** + * SOAP headers for response (text) + * @var string + * @access public + */ + var $responseHeaders = ''; + /** + * SOAP payload for response (text) + * @var string + * @access private + */ + var $responseSOAP = ''; + /** + * method return value to place in response + * @var mixed + * @access private + */ + var $methodreturn = false; + /** + * whether $methodreturn is a string of literal XML + * @var boolean + * @access public + */ + var $methodreturnisliteralxml = false; + /** + * SOAP fault for response (or false) + * @var mixed + * @access private + */ + var $fault = false; + /** + * text indication of result (for debugging) + * @var string + * @access private + */ + var $result = 'successful'; + + /** + * assoc array of operations => opData; operations are added by the register() + * method or by parsing an external WSDL definition + * @var array + * @access private + */ + var $operations = array(); + /** + * wsdl instance (if one) + * @var mixed + * @access private + */ + var $wsdl = false; + /** + * URL for WSDL (if one) + * @var mixed + * @access private + */ + var $externalWSDLURL = false; + /** + * whether to append debug to response as XML comment + * @var boolean + * @access public + */ + var $debug_flag = false; + + + /** + * constructor + * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to. + * + * @param mixed $wsdl file path or URL (string), or wsdl instance (object) + * @access public + */ + function soap_server($wsdl=false){ + parent::nusoap_base(); + // turn on debugging? + global $debug; + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $this->debug("_SERVER is defined:"); + $this->appendDebug($this->varDump($_SERVER)); + } elseif (isset($HTTP_SERVER_VARS)) { + $this->debug("HTTP_SERVER_VARS is defined:"); + $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); + } else { + $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); + } + + if (isset($debug)) { + $this->debug("In soap_server, set debug_flag=$debug based on global flag"); + $this->debug_flag = $debug; + } elseif (isset($_SERVER['QUERY_STRING'])) { + $qs = explode('&', $_SERVER['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); + $this->debug_flag = substr($v, 6); + } + } + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); + foreach ($qs as $v) { + if (substr($v, 0, 6) == 'debug=') { + $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); + $this->debug_flag = substr($v, 6); + } + } + } + + // wsdl + if($wsdl){ + $this->debug("In soap_server, WSDL is specified"); + if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { + $this->wsdl = $wsdl; + $this->externalWSDLURL = $this->wsdl->wsdl; + $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); + } else { + $this->debug('Create wsdl from ' . $wsdl); + $this->wsdl = new wsdl($wsdl); + $this->externalWSDLURL = $wsdl; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($err = $this->wsdl->getError()){ + die('WSDL ERROR: '.$err); + } + } + } + + /** + * processes request and returns response + * + * @param string $data usually is the value of $HTTP_RAW_POST_DATA + * @access public + */ + function service($data){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER['QUERY_STRING'])) { + $qs = $_SERVER['QUERY_STRING']; + } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { + $qs = $HTTP_SERVER_VARS['QUERY_STRING']; + } else { + $qs = ''; + } + $this->debug("In service, query string=$qs"); + + if (ereg('wsdl', $qs) ){ + $this->debug("In service, this is a request for WSDL"); + if($this->externalWSDLURL){ + if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL + header('Location: '.$this->externalWSDLURL); + } else { // assume file + header("Content-Type: text/xml\r\n"); + $fp = fopen($this->externalWSDLURL, 'r'); + fpassthru($fp); + } + } elseif ($this->wsdl) { + header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); + print $this->wsdl->serialize($this->debug_flag); + if ($this->debug_flag) { + $this->debug('wsdl:'); + $this->appendDebug($this->varDump($this->wsdl)); + print $this->getDebugAsXMLComment(); + } + } else { + header("Content-Type: text/html; charset=ISO-8859-1\r\n"); + print "This service does not provide WSDL"; + } + } elseif ($data == '' && $this->wsdl) { + $this->debug("In service, there is no data, so return Web description"); + print $this->wsdl->webDescription(); + } else { + $this->debug("In service, invoke the request"); + $this->parse_request($data); + if (! $this->fault) { + $this->invoke_method(); + } + if (! $this->fault) { + $this->serialize_return(); + } + $this->send_response(); + } + } + + /** + * parses HTTP request headers. + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * + * @access private + */ + function parse_http_headers() { + global $HTTP_SERVER_VARS; + + $this->request = ''; + $this->SOAPAction = ''; + if(function_exists('getallheaders')){ + $this->debug("In parse_http_headers, use getallheaders"); + $headers = getallheaders(); + foreach($headers as $k=>$v){ + $k = strtolower($k); + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + // get SOAPAction header + if(isset($this->headers['soapaction'])){ + $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); + } + // get the character encoding of the incoming request + if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ + $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } elseif(isset($_SERVER) && is_array($_SERVER)){ + $this->debug("In parse_http_headers, use _SERVER"); + foreach ($_SERVER as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } elseif (is_array($HTTP_SERVER_VARS)) { + $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); + foreach ($HTTP_SERVER_VARS as $k => $v) { + if (substr($k, 0, 5) == 'HTTP_') { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); + } else { + $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); + } + if ($k == 'soapaction') { + // get SOAPAction header + $k = 'SOAPAction'; + $v = str_replace('"', '', $v); + $v = str_replace('\\', '', $v); + $this->SOAPAction = $v; + } else if ($k == 'content-type') { + // get the character encoding of the incoming request + if (strpos($v, '=')) { + $enc = substr(strstr($v, '='), 1); + $enc = str_replace('"', '', $enc); + $enc = str_replace('\\', '', $enc); + if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + } + $this->headers[$k] = $v; + $this->request .= "$k: $v\r\n"; + $this->debug("$k: $v"); + } + } else { + $this->debug("In parse_http_headers, HTTP headers not accessible"); + $this->setError("HTTP headers not accessible"); + } + } + + /** + * parses a request + * + * The following fields are set by this function (when successful) + * + * headers + * request + * xml_encoding + * SOAPAction + * request + * requestSOAP + * methodURI + * methodname + * methodparams + * requestHeaders + * document + * + * This sets the fault field on error + * + * @param string $data XML string + * @access private + */ + function parse_request($data='') { + $this->debug('entering parse_request()'); + $this->parse_http_headers(); + $this->debug('got character encoding: '.$this->xml_encoding); + // uncompress if necessary + if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { + $this->debug('got content encoding: ' . $this->headers['content-encoding']); + if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzuncompress')) { + if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { + $data = $degzdata; + } else { + $this->fault('Client', 'Errors occurred when trying to decode the data'); + return; + } + } else { + $this->fault('Client', 'This Server does not support compressed data'); + return; + } + } + } + $this->request .= "\r\n".$data; + $data = $this->parseRequest($this->headers, $data); + $this->requestSOAP = $data; + $this->debug('leaving parse_request'); + } + + /** + * invokes a PHP function for the requested SOAP method + * + * The following fields are set by this function (when successful) + * + * methodreturn + * + * Note that the PHP function that is called may also set the following + * fields to affect the response sent to the client + * + * responseHeaders + * outgoing_headers + * + * This sets the fault field on error + * + * @access private + */ + function invoke_method() { + $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); + + if ($this->wsdl) { + if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { + $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { + // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element + $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); + $this->appendDebug('opData=' . $this->varDump($this->opData)); + $this->methodname = $this->opData['name']; + } else { + $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); + $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); + return; + } + } else { + $this->debug('in invoke_method, no WSDL to validate method'); + } + + // if a . is present in $this->methodname, we see if there is a class in scope, + // which could be referred to. We will also distinguish between two deliminators, + // to allow methods to be called a the class or an instance + $class = ''; + $method = ''; + if (strpos($this->methodname, '..') > 0) { + $delim = '..'; + } else if (strpos($this->methodname, '.') > 0) { + $delim = '.'; + } else { + $delim = ''; + } + + if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && + class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { + // get the class and method name + $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); + $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); + $this->debug("in invoke_method, class=$class method=$method delim=$delim"); + } + + // does method exist? + if ($class == '') { + if (!function_exists($this->methodname)) { + $this->debug("in invoke_method, function '$this->methodname' not found!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } else { + $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; + if (!in_array($method_to_compare, get_class_methods($class))) { + $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); + $this->result = 'fault: method not found'; + $this->fault('Client',"method '$this->methodname' not defined in service"); + return; + } + } + + // evaluate message, getting back parameters + // verify that request parameters match the method's signature + if(! $this->verify_method($this->methodname,$this->methodparams)){ + // debug + $this->debug('ERROR: request not verified against method signature'); + $this->result = 'fault: request failed validation against method signature'; + // return fault + $this->fault('Client',"Operation '$this->methodname' not defined in service."); + return; + } + + // if there are parameters to pass + $this->debug('in invoke_method, params:'); + $this->appendDebug($this->varDump($this->methodparams)); + $this->debug("in invoke_method, calling '$this->methodname'"); + if (!function_exists('call_user_func_array')) { + if ($class == '') { + $this->debug('in invoke_method, calling function using eval()'); + $funcCall = "\$this->methodreturn = $this->methodname("; + } else { + if ($delim == '..') { + $this->debug('in invoke_method, calling class method using eval()'); + $funcCall = "\$this->methodreturn = ".$class."::".$method."("; + } else { + $this->debug('in invoke_method, calling instance method using eval()'); + // generate unique instance name + $instname = "\$inst_".time(); + $funcCall = $instname." = new ".$class."(); "; + $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; + } + } + if ($this->methodparams) { + foreach ($this->methodparams as $param) { + if (is_array($param)) { + $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); + return; + } + $funcCall .= "\"$param\","; + } + $funcCall = substr($funcCall, 0, -1); + } + $funcCall .= ');'; + $this->debug('in invoke_method, function call: '.$funcCall); + @eval($funcCall); + } else { + if ($class == '') { + $this->debug('in invoke_method, calling function using call_user_func_array()'); + $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() + } elseif ($delim == '..') { + $this->debug('in invoke_method, calling class method using call_user_func_array()'); + $call_arg = array ($class, $method); + } else { + $this->debug('in invoke_method, calling instance method using call_user_func_array()'); + $instance = new $class (); + $call_arg = array(&$instance, $method); + } + $this->methodreturn = call_user_func_array($call_arg, $this->methodparams); + } + $this->debug('in invoke_method, methodreturn:'); + $this->appendDebug($this->varDump($this->methodreturn)); + $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn)); + } + + /** + * serializes the return value from a PHP function into a full SOAP Envelope + * + * The following fields are set by this function (when successful) + * + * responseSOAP + * + * This sets the fault field on error + * + * @access private + */ + function serialize_return() { + $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); + // if fault + if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) { + $this->debug('got a fault object from method'); + $this->fault = $this->methodreturn; + return; + } elseif ($this->methodreturnisliteralxml) { + $return_val = $this->methodreturn; + // returned value(s) + } else { + $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); + $this->debug('serializing return value'); + if($this->wsdl){ + // weak attempt at supporting multiple output params + if(sizeof($this->opData['output']['parts']) > 1){ + $opParams = $this->methodreturn; + } else { + // TODO: is this really necessary? + $opParams = array($this->methodreturn); + } + $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->fault('Server', 'unable to serialize result'); + return; + } + } else { + if (isset($this->methodreturn)) { + $return_val = $this->serialize_val($this->methodreturn, 'return'); + } else { + $return_val = ''; + $this->debug('in absence of WSDL, assume void return for backward compatibility'); + } + } + } + $this->debug('return value:'); + $this->appendDebug($this->varDump($return_val)); + + $this->debug('serializing response'); + if ($this->wsdl) { + $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); + if ($this->opData['style'] == 'rpc') { + $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); + if ($this->opData['output']['use'] == 'literal') { + $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } else { + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + } else { + $this->debug('style is not rpc for serialization: assume document'); + $payload = $return_val; + } + } else { + $this->debug('do not have WSDL for serialization: assume rpc/encoded'); + $payload = 'methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'methodname."Response>"; + } + $this->result = 'successful'; + if($this->wsdl){ + //if($this->debug_flag){ + $this->appendDebug($this->wsdl->getDebug()); + // } + if (isset($opData['output']['encodingStyle'])) { + $encodingStyle = $opData['output']['encodingStyle']; + } else { + $encodingStyle = ''; + } + // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle); + } else { + $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); + } + $this->debug("Leaving serialize_return"); + } + + /** + * sends an HTTP response + * + * The following fields are set by this function (when successful) + * + * outgoing_headers + * response + * + * @access private + */ + function send_response() { + $this->debug('Enter send_response'); + if ($this->fault) { + $payload = $this->fault->serialize(); + $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; + $this->outgoing_headers[] = "Status: 500 Internal Server Error"; + } else { + $payload = $this->responseSOAP; + // Some combinations of PHP+Web server allow the Status + // to come through as a header. Since OK is the default + // just do nothing. + // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; + // $this->outgoing_headers[] = "Status: 200 OK"; + } + // add debug data if in debug mode + if(isset($this->debug_flag) && $this->debug_flag){ + $payload .= $this->getDebugAsXMLComment(); + } + $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; + ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); + $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; + // Let the Web server decide about this + //$this->outgoing_headers[] = "Connection: Close\r\n"; + $payload = $this->getHTTPBody($payload); + $type = $this->getHTTPContentType(); + $charset = $this->getHTTPContentTypeCharset(); + $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); + //begin code to compress payload - by John + // NOTE: there is no way to know whether the Web server will also compress + // this data. + if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { + if (strstr($this->headers['accept-encoding'], 'gzip')) { + if (function_exists('gzencode')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: gzip"; + $payload = gzencode($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { + // Note: MSIE requires gzdeflate output (no Zlib header and checksum), + // instead of gzcompress output, + // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) + if (function_exists('gzdeflate')) { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + $this->outgoing_headers[] = "Content-Encoding: deflate"; + $payload = gzdeflate($payload); + } else { + if (isset($this->debug_flag) && $this->debug_flag) { + $payload .= ""; + } + } + } + } + //end code + $this->outgoing_headers[] = "Content-Length: ".strlen($payload); + reset($this->outgoing_headers); + foreach($this->outgoing_headers as $hdr){ + header($hdr, false); + } + print $payload; + $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; + } + + /** + * takes the value that was created by parsing the request + * and compares to the method's signature, if available. + * + * @param string $operation The operation to be invoked + * @param array $request The array of parameter values + * @return boolean Whether the operation was found + * @access private + */ + function verify_method($operation,$request){ + if(isset($this->wsdl) && is_object($this->wsdl)){ + if($this->wsdl->getOperationData($operation)){ + return true; + } + } elseif(isset($this->operations[$operation])){ + return true; + } + return false; + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Request not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + // parse response, get soap parser obj + $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8); + // parser debug + $this->debug("parser debug: \n".$parser->getDebug()); + // if fault occurred during message parsing + if($err = $parser->getError()){ + $this->result = 'fault: error in msg parsing: '.$err; + $this->fault('Client',"error in msg parsing:\n".$err); + // else successfully parsed request into soapval object + } else { + // get/set methodname + $this->methodURI = $parser->root_struct_namespace; + $this->methodname = $parser->root_struct_name; + $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); + $this->debug('calling parser->get_response()'); + $this->methodparams = $parser->get_response(); + // get SOAP headers + $this->requestHeaders = $parser->getHeaders(); + // add document for doclit support + $this->document = $parser->document; + } + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /** + * add a method to the dispatch map (this has been replaced by the register method) + * + * @param string $methodname + * @param string $in array of input values + * @param string $out array of output values + * @access public + * @deprecated + */ + function add_to_map($methodname,$in,$out){ + $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); + } + + /** + * register a service function with the server + * + * @param string $name the name of the PHP function, class.method or class..method + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param mixed $namespace the element namespace for the method or false + * @param mixed $soapaction the soapaction for the method or false + * @param mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param mixed $use optional (encoded|literal) or false + * @param string $documentation optional Description to include in WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ + global $HTTP_SERVER_VARS; + + if($this->externalWSDLURL){ + die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); + } + if (! $name) { + die('You must specify a name when you register an operation'); + } + if (!is_array($in)) { + die('You must provide an array for operation inputs'); + } + if (!is_array($out)) { + die('You must provide an array for operation outputs'); + } + if(false == $namespace) { + } + if(false == $soapaction) { + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name"; + } + if(false == $style) { + $style = "rpc"; + } + if(false == $use) { + $use = "encoded"; + } + if ($use == 'encoded' && $encodingStyle = '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + $this->operations[$name] = array( + 'name' => $name, + 'in' => $in, + 'out' => $out, + 'namespace' => $namespace, + 'soapaction' => $soapaction, + 'style' => $style); + if($this->wsdl){ + $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); + } + return true; + } + + /** + * Specify a fault to be returned to the client. + * This also acts as a flag to the server that a fault has occured. + * + * @param string $faultcode + * @param string $faultstring + * @param string $faultactor + * @param string $faultdetail + * @access public + */ + function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ + if ($faultdetail == '' && $this->debug_flag) { + $faultdetail = $this->getDebug(); + } + $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail); + $this->fault->soap_defencoding = $this->soap_defencoding; + } + + /** + * Sets up wsdl object. + * Acts as a flag to enable internal WSDL generation + * + * @param string $serviceName, name of the service + * @param mixed $namespace optional 'tns' service namespace or false + * @param mixed $endpoint optional URL of service endpoint or false + * @param string $style optional (rpc|document) WSDL style (also specified by operation) + * @param string $transport optional SOAP transport + * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false + */ + function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) + { + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $SERVER_NAME = $_SERVER['SERVER_NAME']; + $SERVER_PORT = $_SERVER['SERVER_PORT']; + $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $HTTPS = $_SERVER['HTTPS']; + } elseif (isset($HTTP_SERVER_VARS)) { + $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; + $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; + $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; + $HTTPS = $HTTP_SERVER_VARS['HTTPS']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + if ($SERVER_PORT == 80) { + $SERVER_PORT = ''; + } else { + $SERVER_PORT = ':' . $SERVER_PORT; + } + if(false == $namespace) { + $namespace = "http://$SERVER_NAME/soap/$serviceName"; + } + + if(false == $endpoint) { + if ($HTTPS == '1' || $HTTPS == 'on') { + $SCHEME = 'https'; + } else { + $SCHEME = 'http'; + } + $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; + } + + if(false == $schemaTargetNamespace) { + $schemaTargetNamespace = $namespace; + } + + $this->wsdl = new wsdl; + $this->wsdl->serviceName = $serviceName; + $this->wsdl->endpoint = $endpoint; + $this->wsdl->namespaces['tns'] = $namespace; + $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; + $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; + if ($schemaTargetNamespace != $namespace) { + $this->wsdl->namespaces['types'] = $schemaTargetNamespace; + } + $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces); + $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); + $this->wsdl->bindings[$serviceName.'Binding'] = array( + 'name'=>$serviceName.'Binding', + 'style'=>$style, + 'transport'=>$transport, + 'portType'=>$serviceName.'PortType'); + $this->wsdl->ports[$serviceName.'Port'] = array( + 'binding'=>$serviceName.'Binding', + 'location'=>$endpoint, + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); + } +} + + + +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class wsdl extends nusoap_base { + // URL or filename of the root of this WSDL + var $wsdl; + // define internal arrays of bindings, ports, operations, messages, etc. + var $schemas = array(); + var $currentSchema; + var $message = array(); + var $complexTypes = array(); + var $messages = array(); + var $currentMessage; + var $currentOperation; + var $portTypes = array(); + var $currentPortType; + var $bindings = array(); + var $currentBinding; + var $ports = array(); + var $currentPort; + var $opData = array(); + var $status = ''; + var $documentation = false; + var $endpoint = ''; + // array of wsdl docs to import + var $import = array(); + // parser vars + var $parser; + var $position = 0; + var $depth = 0; + var $depth_array = array(); + // for getting wsdl + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $timeout = 0; + var $response_timeout = 30; + + /** + * constructor + * + * @param string $wsdl WSDL document URL + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){ + parent::nusoap_base(); + $this->wsdl = $wsdl; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // parse wsdl file + if ($wsdl != "") { + $this->debug('initial wsdl URL: ' . $wsdl); + $this->parseWSDL($wsdl); + } + // imports + // TODO: handle imports more properly, grabbing them in-line and nesting them + $imported_urls = array(); + $imported = 1; + while ($imported > 0) { + $imported = 0; + // Schema imports + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($xs->imports as $ns2 => $list2) { + for ($ii = 0; $ii < count($list2); $ii++) { + if (! $list2[$ii]['loaded']) { + $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true; + $url = $list2[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + } + // WSDL imports + $wsdlparts = parse_url($this->wsdl); // this is bogusly simple! + foreach ($this->import as $ns => $list) { + for ($ii = 0; $ii < count($list); $ii++) { + if (! $list[$ii]['loaded']) { + $this->import[$ns][$ii]['loaded'] = true; + $url = $list[$ii]['location']; + if ($url != '') { + $urlparts = parse_url($url); + if (!isset($urlparts['host'])) { + $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') . + substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path']; + } + if (! in_array($url, $imported_urls)) { + $this->parseWSDL($url); + $imported++; + $imported_urls[] = $url; + } + } else { + $this->debug("Unexpected scenario: empty URL for unloaded import"); + } + } + } + } + } + // add new data to operation data + foreach($this->bindings as $binding => $bindingData) { + if (isset($bindingData['operations']) && is_array($bindingData['operations'])) { + foreach($bindingData['operations'] as $operation => $data) { + $this->debug('post-parse data gathering for ' . $operation); + $this->bindings[$binding]['operations'][$operation]['input'] = + isset($this->bindings[$binding]['operations'][$operation]['input']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['input']; + $this->bindings[$binding]['operations'][$operation]['output'] = + isset($this->bindings[$binding]['operations'][$operation]['output']) ? + array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) : + $this->portTypes[ $bindingData['portType'] ][$operation]['output']; + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ]; + } + if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){ + $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ]; + } + if (isset($bindingData['style'])) { + $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style']; + } + $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : ''; + $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : ''; + $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : ''; + } + } + } + } + + /** + * parses the wsdl document + * + * @param string $wsdl path or URL + * @access private + */ + function parseWSDL($wsdl = '') + { + if ($wsdl == '') { + $this->debug('no wsdl passed to parseWSDL()!!'); + $this->setError('no wsdl passed to parseWSDL()!!'); + return false; + } + + // parse $wsdl for url format + $wsdl_props = parse_url($wsdl); + + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) { + $this->debug('getting WSDL http(s) URL ' . $wsdl); + // get wsdl + $tr = new soap_transport_http($wsdl); + $tr->request_method = 'GET'; + $tr->useSOAPAction = false; + if($this->proxyhost && $this->proxyport){ + $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + $tr->setEncoding('gzip, deflate'); + $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout); + //$this->debug("WSDL request\n" . $tr->outgoing_payload); + //$this->debug("WSDL response\n" . $tr->incoming_payload); + $this->appendDebug($tr->getDebug()); + // catch errors + if($err = $tr->getError() ){ + $errstr = 'HTTP ERROR: '.$err; + $this->debug($errstr); + $this->setError($errstr); + unset($tr); + return false; + } + unset($tr); + $this->debug("got WSDL URL"); + } else { + // $wsdl is not http(s), so treat it as a file URL or plain file path + if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) { + $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path']; + } else { + $path = $wsdl; + } + $this->debug('getting WSDL file ' . $path); + if ($fp = @fopen($path, 'r')) { + $wsdl_string = ''; + while ($data = fread($fp, 32768)) { + $wsdl_string .= $data; + } + fclose($fp); + } else { + $errstr = "Bad path to WSDL file $path"; + $this->debug($errstr); + $this->setError($errstr); + return false; + } + } + $this->debug('Parse WSDL'); + // end new code added + // Create an XML parser. + $this->parser = xml_parser_create(); + // Set the options for parsing the XML data. + // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element', 'end_element'); + xml_set_character_data_handler($this->parser, 'character_data'); + // Parse the XML file. + if (!xml_parse($this->parser, $wsdl_string, true)) { + // Display an error message. + $errstr = sprintf( + 'XML error parsing WSDL from %s on line %d: %s', + $wsdl, + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser)) + ); + $this->debug($errstr); + $this->debug("XML payload:\n" . $wsdl_string); + $this->setError($errstr); + return false; + } + // free the parser + xml_parser_free($this->parser); + $this->debug('Parsing WSDL done'); + // catch wsdl parse errors + if($this->getError()){ + return false; + } + return true; + } + + /** + * start-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @param string $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) + { + if ($this->status == 'schema') { + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } elseif (ereg('schema$', $name)) { + $this->debug('Parsing WSDL schema'); + // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")"); + $this->status = 'schema'; + $this->currentSchema = new xmlschema('', '', $this->namespaces); + $this->currentSchema->schemaStartElement($parser, $name, $attrs); + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + } else { + // position in the total number of elements, starting from 0 + $pos = $this->position++; + $depth = $this->depth++; + // set self as current value for this depth + $this->depth_array[$depth] = $pos; + $this->message[$pos] = array('cdata' => ''); + // process attributes + if (count($attrs) > 0) { + // register namespace declarations + foreach($attrs as $k => $v) { + if (ereg("^xmlns", $k)) { + if ($ns_prefix = substr(strrchr($k, ':'), 1)) { + $this->namespaces[$ns_prefix] = $v; + } else { + $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v; + } + if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') { + $this->XMLSchemaVersion = $v; + $this->namespaces['xsi'] = $v . '-instance'; + } + } + } + // expand each attribute prefix to its namespace + foreach($attrs as $k => $v) { + $k = strpos($k, ':') ? $this->expandQname($k) : $k; + if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') { + $v = strpos($v, ':') ? $this->expandQname($v) : $v; + } + $eAttrs[$k] = $v; + } + $attrs = $eAttrs; + } else { + $attrs = array(); + } + // get element prefix, namespace and name + if (ereg(':', $name)) { + // get ns prefix + $prefix = substr($name, 0, strpos($name, ':')); + // get ns + $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; + // get unqualified name + $name = substr(strstr($name, ':'), 1); + } + // process attributes, expanding any prefixes to namespaces + // find status, register data + switch ($this->status) { + case 'message': + if ($name == 'part') { + if (isset($attrs['type'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type']; + } + if (isset($attrs['element'])) { + $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs)); + $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element']; + } + } + break; + case 'portType': + switch ($name) { + case 'operation': + $this->currentPortOperation = $attrs['name']; + $this->debug("portType $this->currentPortType operation: $this->currentPortOperation"); + if (isset($attrs['parameterOrder'])) { + $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder']; + } + break; + case 'documentation': + $this->documentation = true; + break; + // merge input/output data + default: + $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : ''; + $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m; + break; + } + break; + case 'binding': + switch ($name) { + case 'binding': + // get ns prefix + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['prefix'] = $prefix; + } + $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs); + break; + case 'header': + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs; + break; + case 'operation': + if (isset($attrs['soapAction'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction']; + } + if (isset($attrs['style'])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style']; + } + if (isset($attrs['name'])) { + $this->currentOperation = $attrs['name']; + $this->debug("current binding operation: $this->currentOperation"); + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name']; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding; + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : ''; + } + break; + case 'input': + $this->opStatus = 'input'; + break; + case 'output': + $this->opStatus = 'output'; + break; + case 'body': + if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs); + } else { + $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs; + } + break; + } + break; + case 'service': + switch ($name) { + case 'port': + $this->currentPort = $attrs['name']; + $this->debug('current port: ' . $this->currentPort); + $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']); + + break; + case 'address': + $this->ports[$this->currentPort]['location'] = $attrs['location']; + $this->ports[$this->currentPort]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace; + $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location']; + break; + } + break; + } + // set status + switch ($name) { + case 'import': + if (isset($attrs['location'])) { + $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false); + $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')'); + } else { + $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true); + if (! $this->getPrefixFromNamespace($attrs['namespace'])) { + $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace']; + } + $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')'); + } + break; + //wait for schema + //case 'types': + // $this->status = 'schema'; + // break; + case 'message': + $this->status = 'message'; + $this->messages[$attrs['name']] = array(); + $this->currentMessage = $attrs['name']; + break; + case 'portType': + $this->status = 'portType'; + $this->portTypes[$attrs['name']] = array(); + $this->currentPortType = $attrs['name']; + break; + case "binding": + if (isset($attrs['name'])) { + // get binding name + if (strpos($attrs['name'], ':')) { + $this->currentBinding = $this->getLocalPart($attrs['name']); + } else { + $this->currentBinding = $attrs['name']; + } + $this->status = 'binding'; + $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']); + $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']); + } + break; + case 'service': + $this->serviceName = $attrs['name']; + $this->status = 'service'; + $this->debug('current service: ' . $this->serviceName); + break; + case 'definitions': + foreach ($attrs as $name => $value) { + $this->wsdl_info[$name] = $value; + } + break; + } + } + } + + /** + * end-element handler + * + * @param string $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name){ + // unset schema status + if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) { + $this->status = ""; + $this->appendDebug($this->currentSchema->getDebug()); + $this->currentSchema->clearDebug(); + $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema; + $this->debug('Parsing WSDL schema done'); + } + if ($this->status == 'schema') { + $this->currentSchema->schemaEndElement($parser, $name); + } else { + // bring depth down a notch + $this->depth--; + } + // end documentation + if ($this->documentation) { + //TODO: track the node to which documentation should be assigned; it can be a part, message, etc. + //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation; + $this->documentation = false; + } + } + + /** + * element content handler + * + * @param string $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data) + { + $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0; + if (isset($this->message[$pos]['cdata'])) { + $this->message[$pos]['cdata'] .= $data; + } + if ($this->documentation) { + $this->documentation .= $data; + } + } + + function getBindingData($binding) + { + if (is_array($this->bindings[$binding])) { + return $this->bindings[$binding]; + } + } + + /** + * returns an assoc array of operation names => operation data + * + * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported) + * @return array + * @access public + */ + function getOperations($bindingType = 'soap') + { + $ops = array(); + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + //$this->debug("getOperations for port $port"); + //$this->debug("port data: " . $this->varDump($portData)); + //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ])); + // merge bindings + if (isset($this->bindings[ $portData['binding'] ]['operations'])) { + $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']); + } + } + } + return $ops; + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $operation , name of operation + * @param string $bindingType , type of binding eg: soap + * @return array + * @access public + */ + function getOperationData($operation, $bindingType = 'soap') + { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // get binding + //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) { + // note that we could/should also check the namespace here + if ($operation == $bOperation) { + $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation]; + return $opData; + } + } + } + } + } + + /** + * returns an associative array of data necessary for calling an operation + * + * @param string $soapAction soapAction for operation + * @param string $bindingType type of binding eg: soap + * @return array + * @access public + */ + function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') { + if ($bindingType == 'soap') { + $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/'; + } + // loop thru ports + foreach($this->ports as $port => $portData) { + // binding type of port matches parameter + if ($portData['bindingType'] == $bindingType) { + // loop through operations for the binding + foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) { + if ($opData['soapAction'] == $soapAction) { + return $opData; + } + } + } + } + } + + /** + * returns an array of information about a given type + * returns false if no type exists by the given name + * + * typeDef = array( + * 'elements' => array(), // refs to elements array + * 'restrictionBase' => '', + * 'phpType' => '', + * 'order' => '(sequence|all)', + * 'attrs' => array() // refs to attributes array + * ) + * + * @param $type string the type + * @param $ns string namespace (not prefix) of the type + * @return mixed + * @access public + * @see xmlschema + */ + function getTypeDef($type, $ns) { + $this->debug("in getTypeDef: type=$type, ns=$ns"); + if ((! $ns) && isset($this->namespaces['tns'])) { + $ns = $this->namespaces['tns']; + $this->debug("in getTypeDef: type namespace forced to $ns"); + } + if (isset($this->schemas[$ns])) { + $this->debug("in getTypeDef: have schema for namespace $ns"); + for ($i = 0; $i < count($this->schemas[$ns]); $i++) { + $xs = &$this->schemas[$ns][$i]; + $t = $xs->getTypeDef($type); + $this->appendDebug($xs->getDebug()); + $xs->clearDebug(); + if ($t) { + if (!isset($t['phpType'])) { + // get info for type to tack onto the element + $uqType = substr($t['type'], strrpos($t['type'], ':') + 1); + $ns = substr($t['type'], 0, strrpos($t['type'], ':')); + $etype = $this->getTypeDef($uqType, $ns); + if ($etype) { + $this->debug("found type for [element] $type:"); + $this->debug($this->varDump($etype)); + if (isset($etype['phpType'])) { + $t['phpType'] = $etype['phpType']; + } + if (isset($etype['elements'])) { + $t['elements'] = $etype['elements']; + } + if (isset($etype['attrs'])) { + $t['attrs'] = $etype['attrs']; + } + } + } + return $t; + } + } + } else { + $this->debug("in getTypeDef: do not have schema for namespace $ns"); + } + return false; + } + + /** + * prints html description of services + * + * @access private + */ + function webDescription(){ + global $HTTP_SERVER_VARS; + + if (isset($_SERVER)) { + $PHP_SELF = $_SERVER['PHP_SELF']; + } elseif (isset($HTTP_SERVER_VARS)) { + $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF']; + } else { + $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); + } + + $b = ' + NuSOAP: '.$this->serviceName.' + + + + +
    +

    +
    '.$this->serviceName.'
    + +
    '; + return $b; + } + + /** + * serialize the parsed wsdl + * + * @param mixed $debug whether to put debug=1 in endpoint URL + * @return string serialization of WSDL + * @access public + */ + function serialize($debug = 0) + { + $xml = ''; + $xml .= "\nnamespaces as $k => $v) { + $xml .= " xmlns:$k=\"$v\""; + } + // 10.9.02 - add poulter fix for wsdl and tns declarations + if (isset($this->namespaces['wsdl'])) { + $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\""; + } + if (isset($this->namespaces['tns'])) { + $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\""; + } + $xml .= '>'; + // imports + if (sizeof($this->import) > 0) { + foreach($this->import as $ns => $list) { + foreach ($list as $ii) { + if ($ii['location'] != '') { + $xml .= ''; + } else { + $xml .= ''; + } + } + } + } + // types + if (count($this->schemas)>=1) { + $xml .= "\n"; + foreach ($this->schemas as $ns => $list) { + foreach ($list as $xs) { + $xml .= $xs->serializeSchema(); + } + } + $xml .= ''; + } + // messages + if (count($this->messages) >= 1) { + foreach($this->messages as $msgName => $msgParts) { + $xml .= "\n'; + if(is_array($msgParts)){ + foreach($msgParts as $partName => $partType) { + // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'
    '; + if (strpos($partType, ':')) { + $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType)); + } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) { + // print 'checking typemap: '.$this->XMLSchemaVersion.'
    '; + $typePrefix = 'xsd'; + } else { + foreach($this->typemap as $ns => $types) { + if (isset($types[$partType])) { + $typePrefix = $this->getPrefixFromNamespace($ns); + } + } + if (!isset($typePrefix)) { + die("$partType has no namespace!"); + } + } + $ns = $this->getNamespaceFromPrefix($typePrefix); + $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns); + if ($typeDef['typeClass'] == 'element') { + $elementortype = 'element'; + } else { + $elementortype = 'type'; + } + $xml .= ''; + } + } + $xml .= '
    '; + } + } + // bindings & porttypes + if (count($this->bindings) >= 1) { + $binding_xml = ''; + $portType_xml = ''; + foreach($this->bindings as $bindingName => $attrs) { + $binding_xml .= "\n'; + $binding_xml .= ''; + $portType_xml .= "\n'; + foreach($attrs['operations'] as $opName => $opParts) { + $binding_xml .= ''; + $binding_xml .= ''; + if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') { + $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"'; + } else { + $enc_style = ''; + } + $binding_xml .= ''; + $binding_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $portType_xml .= ''; + $portType_xml .= ''; + } + $portType_xml .= ''; + $binding_xml .= ''; + } + $xml .= $portType_xml . $binding_xml; + } + // services + $xml .= "\nserviceName . '">'; + if (count($this->ports) >= 1) { + foreach($this->ports as $pName => $attrs) { + $xml .= ''; + $xml .= ''; + $xml .= ''; + } + } + $xml .= ''; + return $xml . "\n"; + } + + /** + * serialize PHP values according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $operation operation name + * @param string $direction (input|output) + * @param mixed $parameters parameter value(s) + * @return mixed parameters serialized as XML or false on error (e.g. operation not found) + * @access public + */ + function serializeRPCParameters($operation, $direction, $parameters) + { + $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeRPCParameters returning: $xml"); + return $xml; + } + + /** + * serialize a PHP value according to a WSDL message definition + * + * TODO + * - multi-ref serialization + * - validate PHP values against type definitions, return errors if invalid + * + * @param string $ type name + * @param mixed $ param value + * @return mixed new param or false if initial value didn't validate + * @access public + * @deprecated + */ + function serializeParameters($operation, $direction, $parameters) + { + $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); + $this->appendDebug('parameters=' . $this->varDump($parameters)); + + if ($direction != 'input' && $direction != 'output') { + $this->debug('The value of the \$direction argument needs to be either "input" or "output"'); + $this->setError('The value of the \$direction argument needs to be either "input" or "output"'); + return false; + } + if (!$opData = $this->getOperationData($operation)) { + $this->debug('Unable to retrieve WSDL data for operation: ' . $operation); + $this->setError('Unable to retrieve WSDL data for operation: ' . $operation); + return false; + } + $this->debug('opData:'); + $this->appendDebug($this->varDump($opData)); + + // Get encoding style for output and set to current + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) { + $encodingStyle = $opData['output']['encodingStyle']; + $enc_style = $encodingStyle; + } + + // set input params + $xml = ''; + if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) { + + $use = $opData[$direction]['use']; + $this->debug("use=$use"); + $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)'); + if (is_array($parameters)) { + $parametersArrayType = $this->isArraySimpleOrStruct($parameters); + $this->debug('have ' . $parametersArrayType . ' parameters'); + foreach($opData[$direction]['parts'] as $name => $type) { + $this->debug('serializing part "'.$name.'" of type "'.$type.'"'); + // Track encoding style + if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) { + $encodingStyle = $opData[$direction]['encodingStyle']; + $enc_style = $encodingStyle; + } else { + $enc_style = false; + } + // NOTE: add error handling here + // if serializeType returns false, then catch global error and fault + if ($parametersArrayType == 'arraySimple') { + $p = array_shift($parameters); + $this->debug('calling serializeType w/indexed param'); + $xml .= $this->serializeType($name, $type, $p, $use, $enc_style); + } elseif (isset($parameters[$name])) { + $this->debug('calling serializeType w/named param'); + $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style); + } else { + // TODO: only send nillable + $this->debug('calling serializeType w/null param'); + $xml .= $this->serializeType($name, $type, null, $use, $enc_style); + } + } + } else { + $this->debug('no parameters passed.'); + } + } + $this->debug("serializeParameters returning: $xml"); + return $xml; + } + + /** + * serializes a PHP value according a given type definition + * + * @param string $name name of value (part or element) + * @param string $type XML schema type of value (type or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @param boolean $unqualified a kludge for what should be XML namespace form handling + * @return string value serialized as an XML string + * @access private + */ + function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false) + { + $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified")); + $this->appendDebug("value=" . $this->varDump($value)); + if($use == 'encoded' && $encodingStyle) { + $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"'; + } + + // if a soapval has been supplied, let its type override the WSDL + if (is_object($value) && get_class($value) == 'soapval') { + if ($value->type_ns) { + $type = $value->type_ns . ':' . $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } elseif ($value->type) { + $type = $value->type; + $forceType = true; + $this->debug("in serializeType: soapval overrides type to $type"); + } else { + $forceType = false; + $this->debug("in serializeType: soapval does not override type"); + } + $attrs = $value->attributes; + $value = $value->value; + $this->debug("in serializeType: soapval overrides value to $value"); + if ($attrs) { + if (!is_array($value)) { + $value['!'] = $value; + } + foreach ($attrs as $n => $v) { + $value['!' . $n] = $v; + } + $this->debug("in serializeType: soapval provides attributes"); + } + } else { + $forceType = false; + } + + $xml = ''; + if (strpos($type, ':')) { + $uqType = substr($type, strrpos($type, ':') + 1); + $ns = substr($type, 0, strrpos($type, ':')); + $this->debug("in serializeType: got a prefixed type: $uqType, $ns"); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + $this->debug("in serializeType: expanded prefixed type: $uqType, $ns"); + } + + if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){ + $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type'); + if ($unqualified && $use == 'literal') { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + // TODO: depends on nillable, which should be checked before calling this method + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if ($uqType == 'boolean') { + if ((is_string($value) && $value == 'false') || (! $value)) { + $value = 'false'; + } else { + $value = 'true'; + } + } + if ($uqType == 'string' && gettype($value) == 'string') { + $value = $this->expandEntities($value); + } + if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') { + $value = sprintf("%.0lf", $value); + } + // it's a scalar + // TODO: what about null/nil values? + // check type isn't a custom type extending xmlschema namespace + if (!$this->getTypeDef($uqType, $ns)) { + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)'); + } else if ($ns == 'http://xml.apache.org/xml-soap') { + $this->debug('in serializeType: appears to be Apache SOAP type'); + if ($uqType == 'Map') { + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + if (! $tt_prefix) { + $this->debug('in serializeType: Add namespace for Apache SOAP type'); + $tt_prefix = 'ns' . rand(1000, 9999); + $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap'; + // force this to be added to usedNamespaces + $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap'); + } + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing map element: key $k, value $v"); + $contents .= ''; + $contents .= $this->serialize_val($k,'key',false,false,false,false,$use); + $contents .= $this->serialize_val($v,'value',false,false,false,false,$use); + $contents .= ''; + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents"; + } else { + $xml = "<$name>$contents"; + } + } else { + $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + $this->debug('in serializeType: Apache SOAP type, but only support Map'); + } + } else { + // TODO: should the type be compared to types in XSD, and the namespace + // set to XSD if the type matches? + $this->debug("in serializeType: No namespace for type $type"); + $ns = ''; + $uqType = $type; + } + if(!$typeDef = $this->getTypeDef($uqType, $ns)){ + $this->setError("$type ($uqType) is not a supported type."); + $this->debug("in serializeType: $type ($uqType) is not a supported type."); + return false; + } else { + $this->debug("in serializeType: found typeDef"); + $this->appendDebug('typeDef=' . $this->varDump($typeDef)); + } + $phpType = $typeDef['phpType']; + $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); + // if php type == struct, map value to the element names + if ($phpType == 'struct') { + if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') { + $elementName = $uqType; + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + $elementNS = " xmlns=\"\""; + } + } else { + $elementName = $name; + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$elementName$elementNS/>"; + } else { + $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (is_object($value)) { + $value = get_object_vars($value); + } + if (is_array($value)) { + $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + if ($use == 'literal') { + if ($forceType) { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">"; + } else { + $xml = "<$elementName$elementNS$elementAttrs>"; + } + } else { + $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>"; + } + + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + $xml .= ""; + } else { + $this->debug("in serializeType: phpType is struct, but value is not an array"); + $this->setError("phpType is struct, but value is not an array: see debug output for details"); + $xml = ''; + } + } elseif ($phpType == 'array') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if (is_null($value)) { + if ($use == 'literal') { + // TODO: depends on minOccurs + $xml = "<$name$elementNS/>"; + } else { + $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ":Array\" " . + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . + ':arrayType="' . + $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) . + ':' . + $this->getLocalPart($typeDef['arrayType'])."[0]\"/>"; + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + if (isset($typeDef['multidimensional'])) { + $nv = array(); + foreach($value as $v) { + $cols = ',' . sizeof($v); + $nv = array_merge($nv, $v); + } + $value = $nv; + } else { + $cols = ''; + } + if (is_array($value) && sizeof($value) >= 1) { + $rows = sizeof($value); + $contents = ''; + foreach($value as $k => $v) { + $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]"); + //if (strpos($typeDef['arrayType'], ':') ) { + if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) { + $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use); + } else { + $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use); + } + } + } else { + $rows = 0; + $contents = null; + } + // TODO: for now, an empty value will be serialized as a zero element + // array. Revisit this when coding the handling of null/nil values. + if ($use == 'literal') { + $xml = "<$name$elementNS>" + .$contents + .""; + } else { + $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '. + $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') + .':arrayType="' + .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) + .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">" + .$contents + .""; + } + } elseif ($phpType == 'scalar') { + if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) { + $elementNS = " xmlns=\"$ns\""; + } else { + if ($unqualified) { + $elementNS = " xmlns=\"\""; + } else { + $elementNS = ''; + } + } + if ($use == 'literal') { + if ($forceType) { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value"; + } else { + $xml = "<$name$elementNS>$value"; + } + } else { + $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value"; + } + } + $this->debug("in serializeType: returning: $xml"); + return $xml; + } + + /** + * serializes the attributes for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) { + $xml = ''; + if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) { + $this->debug("serialize attributes for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + foreach ($typeDef['attrs'] as $aName => $attrs) { + if (isset($xvalue['!' . $aName])) { + $xname = '!' . $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($xvalue[$aName])) { + $xname = $aName; + $this->debug("value provided for attribute $aName with key $xname"); + } elseif (isset($attrs['default'])) { + $xname = '!' . $aName; + $xvalue[$xname] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName); + } else { + $xname = ''; + $this->debug("no value provided for attribute $aName"); + } + if ($xname) { + $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\""; + } + } + } else { + $this->debug("no attributes to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize attributes for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * serializes the elements for a complexType + * + * @param array $typeDef our internal representation of an XML schema type (or element) + * @param mixed $value a native PHP value (parameter value) + * @param string $ns the namespace of the type + * @param string $uqType the local part of the type + * @param string $use use for part (encoded|literal) + * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) + * @return string value serialized as an XML string + * @access private + */ + function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) { + $xml = ''; + if (isset($typeDef['elements']) && is_array($typeDef['elements'])) { + $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType"); + if (is_array($value)) { + $xvalue = $value; + } elseif (is_object($value)) { + $xvalue = get_object_vars($value); + } else { + $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType"); + $xvalue = array(); + } + // toggle whether all elements are present - ideally should validate against schema + if (count($typeDef['elements']) != count($xvalue)){ + $optionals = true; + } + foreach ($typeDef['elements'] as $eName => $attrs) { + if (!isset($xvalue[$eName])) { + if (isset($attrs['default'])) { + $xvalue[$eName] = $attrs['default']; + $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName); + } + } + // if user took advantage of a minOccurs=0, then only serialize named parameters + if (isset($optionals) + && (!isset($xvalue[$eName])) + && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true') + ){ + if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') { + $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']); + } + // do nothing + $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing"); + } else { + // get value + if (isset($xvalue[$eName])) { + $v = $xvalue[$eName]; + } else { + $v = null; + } + if (isset($attrs['form'])) { + $unqualified = ($attrs['form'] == 'unqualified'); + } else { + $unqualified = false; + } + if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') { + $vv = $v; + foreach ($vv as $k => $v) { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } else { + if (isset($attrs['type']) || isset($attrs['ref'])) { + // serialize schema-defined type + $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified); + } else { + // serialize generic type (can this ever really happen?) + $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use"); + $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use); + } + } + } + } + } else { + $this->debug("no elements to serialize for XML Schema type $ns:$uqType"); + } + if (isset($typeDef['extensionBase'])) { + $ns = $this->getPrefix($typeDef['extensionBase']); + $uqType = $this->getLocalPart($typeDef['extensionBase']); + if ($this->getNamespaceFromPrefix($ns)) { + $ns = $this->getNamespaceFromPrefix($ns); + } + if ($typeDef = $this->getTypeDef($uqType, $ns)) { + $this->debug("serialize elements for extension base $ns:$uqType"); + $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle); + } else { + $this->debug("extension base $ns:$uqType is not a supported type"); + } + } + return $xml; + } + + /** + * adds an XML Schema complex type to the WSDL types + * + * @param string name + * @param string typeClass (complexType|simpleType|attribute) + * @param string phpType: currently supported are array and struct (php assoc array) + * @param string compositor (all|sequence|choice) + * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param array elements = array ( name => array(name=>'',type=>'') ) + * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]')) + * @param string arrayType: namespace:name (xsd:string) + * @see xmlschema + * @access public + */ + function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') { + if (count($elements) > 0) { + foreach($elements as $n => $e){ + // expand each element + foreach ($e as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $ee[$k] = $v; + } + $eElements[$n] = $ee; + } + $elements = $eElements; + } + + if (count($attrs) > 0) { + foreach($attrs as $n => $a){ + // expand each attribute + foreach ($a as $k => $v) { + $k = strpos($k,':') ? $this->expandQname($k) : $k; + $v = strpos($v,':') ? $this->expandQname($v) : $v; + $aa[$k] = $v; + } + $eAttrs[$n] = $aa; + } + $attrs = $eAttrs; + } + + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType); + } + + /** + * adds an XML Schema simple type to the WSDL types + * + * @param string $name + * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array) + * @param string $typeClass (should always be simpleType) + * @param string $phpType (should always be scalar) + * @param array $enumeration array of values + * @see xmlschema + * @access public + */ + function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) { + $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase; + + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration); + } + + /** + * adds an element to the WSDL types + * + * @param array $attrs attributes that must include name and type + * @see xmlschema + * @access public + */ + function addElement($attrs) { + $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns']; + $this->schemas[$typens][0]->addElement($attrs); + } + + /** + * register an operation with the server + * + * @param string $name operation (method) name + * @param array $in assoc array of input values: key = param name, value = param type + * @param array $out assoc array of output values: key = param name, value = param type + * @param string $namespace optional The namespace for the operation + * @param string $soapaction optional The soapaction for the operation + * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically + * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now) + * @param string $documentation optional The description to include in the WSDL + * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded) + * @access public + */ + function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){ + if ($use == 'encoded' && $encodingStyle == '') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } + + if ($style == 'document') { + $elements = array(); + foreach ($in as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name, 'type' => $name . 'RequestType')); + $in = array('parameters' => 'tns:' . $name); + + $elements = array(); + foreach ($out as $n => $t) { + $elements[$n] = array('name' => $n, 'type' => $t); + } + $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements); + $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType')); + $out = array('parameters' => 'tns:' . $name . 'Response'); + } + + // get binding + $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] = + array( + 'name' => $name, + 'binding' => $this->serviceName . 'Binding', + 'endpoint' => $this->endpoint, + 'soapAction' => $soapaction, + 'style' => $style, + 'input' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Request', + 'parts' => $in), + 'output' => array( + 'use' => $use, + 'namespace' => $namespace, + 'encodingStyle' => $encodingStyle, + 'message' => $name . 'Response', + 'parts' => $out), + 'namespace' => $namespace, + 'transport' => 'http://schemas.xmlsoap.org/soap/http', + 'documentation' => $documentation); + // add portTypes + // add messages + if($in) + { + foreach($in as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Request'][$pName] = $pType; + } + } else { + $this->messages[$name.'Request']= '0'; + } + if($out) + { + foreach($out as $pName => $pType) + { + if(strpos($pType,':')) { + $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType); + } + $this->messages[$name.'Response'][$pName] = $pType; + } + } else { + $this->messages[$name.'Response']= '0'; + } + return true; + } +} +?> +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soap_parser extends nusoap_base { + + var $xml = ''; + var $xml_encoding = ''; + var $method = ''; + var $root_struct = ''; + var $root_struct_name = ''; + var $root_struct_namespace = ''; + var $root_header = ''; + var $document = ''; // incoming SOAP body (text) + // determines where in the message we are (envelope,header,body,method) + var $status = ''; + var $position = 0; + var $depth = 0; + var $default_namespace = ''; + var $namespaces = array(); + var $message = array(); + var $parent = ''; + var $fault = false; + var $fault_code = ''; + var $fault_str = ''; + var $fault_detail = ''; + var $depth_array = array(); + var $debug_flag = true; + var $soapresponse = NULL; + var $responseHeaders = ''; // incoming SOAP headers (text) + var $body_position = 0; + // for multiref parsing: + // array of id => pos + var $ids = array(); + // array of id => hrefs => pos + var $multirefs = array(); + // toggle for auto-decoding element content + var $decode_utf8 = true; + + /** + * constructor that actually does the parsing + * + * @param string $xml SOAP message + * @param string $encoding character encoding scheme of message + * @param string $method method for which XML is parsed (unused?) + * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 + * @access public + */ + function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ + parent::nusoap_base(); + $this->xml = $xml; + $this->xml_encoding = $encoding; + $this->method = $method; + $this->decode_utf8 = $decode_utf8; + + // Check whether content has been read. + if(!empty($xml)){ + // Check XML encoding + $pos_xml = strpos($xml, '', $pos_xml + 2) - $pos_xml + 1); + if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { + $xml_encoding = $res[1]; + if (strtoupper($xml_encoding) != $encoding) { + $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; + $this->debug($err); + if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { + $this->setError($err); + return; + } + // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed + } else { + $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); + } + } else { + $this->debug('No encoding specified in XML declaration'); + } + } else { + $this->debug('No XML declaration'); + } + $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding); + // Create an XML parser - why not xml_parser_create_ns? + $this->parser = xml_parser_create($this->xml_encoding); + // Set the options for parsing the XML data. + //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); + xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); + // Set the object for the parser. + xml_set_object($this->parser, $this); + // Set the element handlers for the parser. + xml_set_element_handler($this->parser, 'start_element','end_element'); + xml_set_character_data_handler($this->parser,'character_data'); + + // Parse the XML file. + if(!xml_parse($this->parser,$xml,true)){ + // Display an error message. + $err = sprintf('XML error parsing SOAP payload on line %d: %s', + xml_get_current_line_number($this->parser), + xml_error_string(xml_get_error_code($this->parser))); + $this->debug($err); + $this->debug("XML payload:\n" . $xml); + $this->setError($err); + } else { + $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); + // get final value + $this->soapresponse = $this->message[$this->root_struct]['result']; + // get header value: no, because this is documented as XML string +// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ +// $this->responseHeaders = $this->message[$this->root_header]['result']; +// } + // resolve hrefs/ids + if(sizeof($this->multirefs) > 0){ + foreach($this->multirefs as $id => $hrefs){ + $this->debug('resolving multirefs for id: '.$id); + $idVal = $this->buildVal($this->ids[$id]); + if (is_array($idVal) && isset($idVal['!id'])) { + unset($idVal['!id']); + } + foreach($hrefs as $refPos => $ref){ + $this->debug('resolving href at pos '.$refPos); + $this->multirefs[$id][$refPos] = $idVal; + } + } + } + } + xml_parser_free($this->parser); + } else { + $this->debug('xml was empty, didn\'t parse!'); + $this->setError('xml was empty, didn\'t parse!'); + } + } + + /** + * start-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @param array $attrs associative array of attributes + * @access private + */ + function start_element($parser, $name, $attrs) { + // position in a total number of elements, starting from 0 + // update class level pos + $pos = $this->position++; + // and set mine + $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); + // depth = how many levels removed from root? + // set mine as current global depth and increment global depth value + $this->message[$pos]['depth'] = $this->depth++; + + // else add self as child to whoever the current parent is + if($pos != 0){ + $this->message[$this->parent]['children'] .= '|'.$pos; + } + // set my parent + $this->message[$pos]['parent'] = $this->parent; + // set self as current parent + $this->parent = $pos; + // set self as current value for this depth + $this->depth_array[$this->depth] = $pos; + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + // set status + if($name == 'Envelope'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->root_header = $pos; + $this->status = 'header'; + } elseif($name == 'Body'){ + $this->status = 'body'; + $this->body_position = $pos; + // set method + } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->message[$pos]['type'] = 'struct'; + $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); + } + // set my status + $this->message[$pos]['status'] = $this->status; + // set name + $this->message[$pos]['name'] = htmlspecialchars($name); + // set attrs + $this->message[$pos]['attrs'] = $attrs; + + // loop through atts, logging ns and type declarations + $attstr = ''; + foreach($attrs as $key => $value){ + $key_prefix = $this->getPrefix($key); + $key_localpart = $this->getLocalPart($key); + // if ns declarations, add to class level array of valid namespaces + if($key_prefix == 'xmlns'){ + if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ + $this->XMLSchemaVersion = $value; + $this->namespaces['xsd'] = $this->XMLSchemaVersion; + $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; + } + $this->namespaces[$key_localpart] = $value; + // set method namespace + if($name == $this->root_struct_name){ + $this->methodNamespace = $value; + } + // if it's a type declaration, set type + } elseif($key_localpart == 'type'){ + $value_prefix = $this->getPrefix($value); + $value_localpart = $this->getLocalPart($value); + $this->message[$pos]['type'] = $value_localpart; + $this->message[$pos]['typePrefix'] = $value_prefix; + if(isset($this->namespaces[$value_prefix])){ + $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; + } else if(isset($attrs['xmlns:'.$value_prefix])) { + $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; + } + // should do something here with the namespace of specified type? + } elseif($key_localpart == 'arrayType'){ + $this->message[$pos]['type'] = 'array'; + /* do arrayType ereg here + [1] arrayTypeValue ::= atype asize + [2] atype ::= QName rank* + [3] rank ::= '[' (',')* ']' + [4] asize ::= '[' length~ ']' + [5] length ::= nextDimension* Digit+ + [6] nextDimension ::= Digit+ ',' + */ + $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; + if(ereg($expr,$value,$regs)){ + $this->message[$pos]['typePrefix'] = $regs[1]; + $this->message[$pos]['arrayTypePrefix'] = $regs[1]; + if (isset($this->namespaces[$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; + } else if (isset($attrs['xmlns:'.$regs[1]])) { + $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; + } + $this->message[$pos]['arrayType'] = $regs[2]; + $this->message[$pos]['arraySize'] = $regs[3]; + $this->message[$pos]['arrayCols'] = $regs[4]; + } + // specifies nil value (or not) + } elseif ($key_localpart == 'nil'){ + $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); + // some other attribute + } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { + $this->message[$pos]['xattrs']['!' . $key] = $value; + } + + if ($key == 'xmlns') { + $this->default_namespace = $value; + } + // log id + if($key == 'id'){ + $this->ids[$value] = $pos; + } + // root + if($key_localpart == 'root' && $value == 1){ + $this->status = 'method'; + $this->root_struct_name = $name; + $this->root_struct = $pos; + $this->debug("found root struct $this->root_struct_name, pos $pos"); + } + // for doclit + $attstr .= " $key=\"$value\""; + } + // get namespace - must be done after namespace atts are processed + if(isset($prefix)){ + $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; + $this->default_namespace = $this->namespaces[$prefix]; + } else { + $this->message[$pos]['namespace'] = $this->default_namespace; + } + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } elseif($this->root_struct_name != ''){ + $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; + } + } + + /** + * end-element handler + * + * @param resource $parser XML parser object + * @param string $name element name + * @access private + */ + function end_element($parser, $name) { + // position of current element is equal to the last value left in depth_array for my depth + $pos = $this->depth_array[$this->depth--]; + + // get element prefix + if(strpos($name,':')){ + // get ns prefix + $prefix = substr($name,0,strpos($name,':')); + // get unqualified name + $name = substr(strstr($name,':'),1); + } + + // build to native type + if(isset($this->body_position) && $pos > $this->body_position){ + // deal w/ multirefs + if(isset($this->message[$pos]['attrs']['href'])){ + // get id + $id = substr($this->message[$pos]['attrs']['href'],1); + // add placeholder to href array + $this->multirefs[$id][$pos] = 'placeholder'; + // add set a reference to it as the result value + $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; + // build complexType values + } elseif($this->message[$pos]['children'] != ''){ + // if result has already been generated (struct/array) + if(!isset($this->message[$pos]['result'])){ + $this->message[$pos]['result'] = $this->buildVal($pos); + } + // build complexType values of attributes and possibly simpleContent + } elseif (isset($this->message[$pos]['xattrs'])) { + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + if (isset($this->message[$pos]['type'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; + } + } + } + $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; + // set value of simpleType (or nil complexType) + } else { + //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); + if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { + $this->message[$pos]['xattrs']['!'] = null; + } elseif (isset($this->message[$pos]['type'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $this->message[$pos]['result'] = $this->message[$pos]['cdata']; + } + } + + /* add value to parent's result, if parent is struct/array + $parent = $this->message[$pos]['parent']; + if($this->message[$parent]['type'] != 'map'){ + if(strtolower($this->message[$parent]['type']) == 'array'){ + $this->message[$parent]['result'][] = $this->message[$pos]['result']; + } else { + $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; + } + } + */ + } + } + + // for doclit + if($this->status == 'header'){ + if ($this->root_header != $pos) { + $this->responseHeaders .= ""; + } + } elseif($pos >= $this->root_struct){ + $this->document .= ""; + } + // switch status + if($pos == $this->root_struct){ + $this->status = 'body'; + $this->root_struct_namespace = $this->message[$pos]['namespace']; + } elseif($name == 'Body'){ + $this->status = 'envelope'; + } elseif($name == 'Header'){ + $this->status = 'envelope'; + } elseif($name == 'Envelope'){ + // + } + // set parent back to my parent + $this->parent = $this->message[$pos]['parent']; + } + + /** + * element content handler + * + * @param resource $parser XML parser object + * @param string $data element content + * @access private + */ + function character_data($parser, $data){ + $pos = $this->depth_array[$this->depth]; + if ($this->xml_encoding=='UTF-8'){ + // TODO: add an option to disable this for folks who want + // raw UTF-8 that, e.g., might not map to iso-8859-1 + // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); + if($this->decode_utf8){ + $data = utf8_decode($data); + } + } + $this->message[$pos]['cdata'] .= $data; + // for doclit + if($this->status == 'header'){ + $this->responseHeaders .= $data; + } else { + $this->document .= $data; + } + } + + /** + * get the parsed message + * + * @return mixed + * @access public + */ + function get_response(){ + return $this->soapresponse; + } + + /** + * get the parsed headers + * + * @return string XML or empty if no headers + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * decodes simple types into PHP variables + * + * @param string $value value to decode + * @param string $type XML type to decode + * @param string $typens XML type namespace to decode + * @return mixed PHP value + * @access private + */ + function decodeSimple($value, $type, $typens) { + // TODO: use the namespace! + if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { + return (string) $value; + } + if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { + return (int) $value; + } + if ($type == 'float' || $type == 'double' || $type == 'decimal') { + return (double) $value; + } + if ($type == 'boolean') { + if (strtolower($value) == 'false' || strtolower($value) == 'f') { + return false; + } + return (boolean) $value; + } + if ($type == 'base64' || $type == 'base64Binary') { + $this->debug('Decode base64 value'); + return base64_decode($value); + } + // obscure numeric types + if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' + || $type == 'nonNegativeInteger' || $type == 'positiveInteger' + || $type == 'unsignedInt' + || $type == 'unsignedShort' || $type == 'unsignedByte') { + return (int) $value; + } + // bogus: parser treats array with no elements as a simple type + if ($type == 'array') { + return array(); + } + // everything else + return (string) $value; + } + + /** + * builds response structures for compound values (arrays/structs) + * and scalars + * + * @param integer $pos position in node tree + * @return mixed PHP value + * @access private + */ + function buildVal($pos){ + if(!isset($this->message[$pos]['type'])){ + $this->message[$pos]['type'] = ''; + } + $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); + // if there are children... + if($this->message[$pos]['children'] != ''){ + $this->debug('in buildVal, there are children'); + $children = explode('|',$this->message[$pos]['children']); + array_shift($children); // knock off empty + // md array + if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ + $r=0; // rowcount + $c=0; // colcount + foreach($children as $child_pos){ + $this->debug("in buildVal, got an MD array element: $r, $c"); + $params[$r][] = $this->message[$child_pos]['result']; + $c++; + if($c == $this->message[$pos]['arrayCols']){ + $c = 0; + $r++; + } + } + // array + } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ + $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $params[] = &$this->message[$child_pos]['result']; + } + // apache Map type: java hashtable + } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ + $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); + foreach($children as $child_pos){ + $kv = explode("|",$this->message[$child_pos]['children']); + $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; + } + // generic compound type + //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { + } else { + // Apache Vector type: treat as an array + $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']); + if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { + $notstruct = 1; + } else { + $notstruct = 0; + } + // + foreach($children as $child_pos){ + if($notstruct){ + $params[] = &$this->message[$child_pos]['result']; + } else { + if (isset($params[$this->message[$child_pos]['name']])) { + // de-serialize repeated element name into an array + if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { + $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); + } + $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; + } else { + $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; + } + } + } + } + if (isset($this->message[$pos]['xattrs'])) { + $this->debug('in buildVal, handling attributes'); + foreach ($this->message[$pos]['xattrs'] as $n => $v) { + $params[$n] = $v; + } + } + // handle simpleContent + if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { + $this->debug('in buildVal, handling simpleContent'); + if (isset($this->message[$pos]['type'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } else { + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } else { + $params['!'] = $this->message[$pos]['cdata']; + } + } + } + return is_array($params) ? $params : array(); + } else { + $this->debug('in buildVal, no children, building scalar'); + $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; + if (isset($this->message[$pos]['type'])) { + return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); + } + $parent = $this->message[$pos]['parent']; + if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { + return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); + } + return $this->message[$pos]['cdata']; + } + } +} + + + +?>call( string methodname [ ,array parameters] ); +* +* // bye bye client +* unset($soapclient); +* +* @author Dietrich Ayala +* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $ +* @access public +*/ +class soapclient extends nusoap_base { + + var $username = ''; + var $password = ''; + var $authtype = ''; + var $certRequest = array(); + var $requestHeaders = false; // SOAP headers in request (text) + var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text) + var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text) + var $endpoint; + var $forceEndpoint = ''; // overrides WSDL endpoint + var $proxyhost = ''; + var $proxyport = ''; + var $proxyusername = ''; + var $proxypassword = ''; + var $xml_encoding = ''; // character set encoding of incoming (response) messages + var $http_encoding = false; + var $timeout = 0; // HTTP connection timeout + var $response_timeout = 30; // HTTP response timeout + var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error + var $persistentConnection = false; + var $defaultRpcParams = false; // This is no longer used + var $request = ''; // HTTP request + var $response = ''; // HTTP response + var $responseData = ''; // SOAP payload of response + var $cookies = array(); // Cookies from response or for request + var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode() + var $operations = array(); // WSDL operations, empty for WSDL initialization error + + /* + * fault related variables + */ + /** + * @var fault + * @access public + */ + var $fault; + /** + * @var faultcode + * @access public + */ + var $faultcode; + /** + * @var faultstring + * @access public + */ + var $faultstring; + /** + * @var faultdetail + * @access public + */ + var $faultdetail; + + /** + * constructor + * + * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object) + * @param bool $wsdl optional, set to true if using WSDL + * @param int $portName optional portName in WSDL document + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @param integer $timeout set the connection timeout + * @param integer $response_timeout set the response timeout + * @access public + */ + function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){ + parent::nusoap_base(); + $this->endpoint = $endpoint; + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + $this->timeout = $timeout; + $this->response_timeout = $response_timeout; + + // make values + if($wsdl){ + if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) { + $this->wsdl = $endpoint; + $this->endpoint = $this->wsdl->wsdl; + $this->wsdlFile = $this->endpoint; + $this->debug('existing wsdl instance created from ' . $this->endpoint); + } else { + $this->wsdlFile = $this->endpoint; + + // instantiate wsdl object and parse wsdl file + $this->debug('instantiating wsdl class with doc: '.$endpoint); + $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout); + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + // catch errors + if($errstr = $this->wsdl->getError()){ + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + } elseif($this->operations = $this->wsdl->getOperations()){ + $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile); + $this->endpointType = 'wsdl'; + } else { + $this->debug( 'getOperations returned false'); + $this->setError('no operations defined in the WSDL document!'); + } + } else { + $this->debug("instantiate SOAP with endpoint at $endpoint"); + $this->endpointType = 'soap'; + } + } + + /** + * calls method, returns PHP native type + * + * @param string $method SOAP server URL or path + * @param mixed $params An array, associative or simple, of the parameters + * for the method call, or a string that is the XML + * for the call. For rpc style, this call will + * wrap the XML in a tag named after the method, as + * well as the SOAP Envelope and Body. For document + * style, this will only wrap with the Envelope and Body. + * IMPORTANT: when using an array with document style, + * in which case there + * is really one parameter, the root of the fragment + * used in the call, which encloses what programmers + * normally think of parameters. A parameter array + * *must* include the wrapper. + * @param string $namespace optional method namespace (WSDL can override) + * @param string $soapAction optional SOAPAction value (WSDL can override) + * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers + * @param boolean $rpcParams optional (no longer used) + * @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override) + * @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override) + * @return mixed response from SOAP call + * @access public + */ + function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){ + $this->operation = $operation; + $this->fault = false; + $this->setError(''); + $this->request = ''; + $this->response = ''; + $this->responseData = ''; + $this->faultstring = ''; + $this->faultcode = ''; + $this->opData = array(); + + $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType"); + $this->appendDebug('params=' . $this->varDump($params)); + $this->appendDebug('headers=' . $this->varDump($headers)); + if ($headers) { + $this->requestHeaders = $headers; + } + // serialize parameters + if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){ + // use WSDL for operation + $this->opData = $opData; + $this->debug("found operation"); + $this->appendDebug('opData=' . $this->varDump($opData)); + if (isset($opData['soapAction'])) { + $soapAction = $opData['soapAction']; + } + if (! $this->forceEndpoint) { + $this->endpoint = $opData['endpoint']; + } else { + $this->endpoint = $this->forceEndpoint; + } + $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace; + $style = $opData['style']; + $use = $opData['input']['use']; + // add ns to ns array + if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){ + $nsPrefix = 'ns' . rand(1000, 9999); + $this->wsdl->namespaces[$nsPrefix] = $namespace; + } + $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace); + // serialize payload + if (is_string($params)) { + $this->debug("serializing param string for WSDL operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for WSDL operation $operation"); + $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params); + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = $this->wsdl->usedNamespaces; + if (isset($opData['input']['encodingStyle'])) { + $encodingStyle = $opData['input']['encodingStyle']; + } else { + $encodingStyle = ''; + } + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + if ($errstr = $this->wsdl->getError()) { + $this->debug('got wsdl error: '.$errstr); + $this->setError('wsdl error: '.$errstr); + return false; + } + } elseif($this->endpointType == 'wsdl') { + // operation not in WSDL + $this->appendDebug($this->wsdl->getDebug()); + $this->wsdl->clearDebug(); + $this->setError( 'operation '.$operation.' not present.'); + $this->debug("operation '$operation' not present."); + return false; + } else { + // no WSDL + //$this->namespaces['ns1'] = $namespace; + $nsPrefix = 'ns' . rand(1000, 9999); + // serialize + $payload = ''; + if (is_string($params)) { + $this->debug("serializing param string for operation $operation"); + $payload = $params; + } elseif (is_array($params)) { + $this->debug("serializing param array for operation $operation"); + foreach($params as $k => $v){ + $payload .= $this->serialize_val($v,$k,false,false,false,false,$use); + } + } else { + $this->debug('params must be array or string'); + $this->setError('params must be array or string'); + return false; + } + $usedNamespaces = array(); + if ($use == 'encoded') { + $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; + } else { + $encodingStyle = ''; + } + } + // wrap RPC calls with method element + if ($style == 'rpc') { + if ($use == 'literal') { + $this->debug("wrapping RPC request with literal method element"); + if ($namespace) { + $payload = "<$operation xmlns=\"$namespace\">" . $payload . ""; + } else { + $payload = "<$operation>" . $payload . ""; + } + } else { + $this->debug("wrapping RPC request with encoded method element"); + if ($namespace) { + $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" . + $payload . + ""; + } else { + $payload = "<$operation>" . + $payload . + ""; + } + } + } + // serialize envelope + $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle); + $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle"); + $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000)); + // send + $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout); + if($errstr = $this->getError()){ + $this->debug('Error: '.$errstr); + return false; + } else { + $this->return = $return; + $this->debug('sent message successfully and got a(n) '.gettype($return)); + $this->appendDebug('return=' . $this->varDump($return)); + + // fault? + if(is_array($return) && isset($return['faultcode'])){ + $this->debug('got fault'); + $this->setError($return['faultcode'].': '.$return['faultstring']); + $this->fault = true; + foreach($return as $k => $v){ + $this->$k = $v; + $this->debug("$k = $v
    "); + } + return $return; + } elseif ($style == 'document') { + // NOTE: if the response is defined to have multiple parts (i.e. unwrapped), + // we are only going to return the first part here...sorry about that + return $return; + } else { + // array of return values + if(is_array($return)){ + // multiple 'out' parameters, which we return wrapped up + // in the array + if(sizeof($return) > 1){ + return $return; + } + // single 'out' parameter (normally the return value) + $return = array_shift($return); + $this->debug('return shifted value: '); + $this->appendDebug($this->varDump($return)); + return $return; + // nothing returned (ie, echoVoid) + } else { + return ""; + } + } + } + } + + /** + * get available data pertaining to an operation + * + * @param string $operation operation name + * @return array array of data pertaining to the operation + * @access public + */ + function getOperationData($operation){ + if(isset($this->operations[$operation])){ + return $this->operations[$operation]; + } + $this->debug("No data for operation: $operation"); + } + + /** + * send the SOAP message + * + * Note: if the operation has multiple return values + * the return value of this method will be an array + * of those values. + * + * @param string $msg a SOAPx4 soapmsg object + * @param string $soapaction SOAPAction value + * @param integer $timeout set connection timeout in seconds + * @param integer $response_timeout set response timeout in seconds + * @return mixed native PHP types. + * @access private + */ + function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) { + $this->checkCookies(); + // detect transport + switch(true){ + // http(s) + case ereg('^http',$this->endpoint): + $this->debug('transporting via HTTP'); + if($this->persistentConnection == true && is_object($this->persistentConnection)){ + $http =& $this->persistentConnection; + } else { + $http = new soap_transport_http($this->endpoint); + if ($this->persistentConnection) { + $http->usePersistentConnection(); + } + } + $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset()); + $http->setSOAPAction($soapaction); + if($this->proxyhost && $this->proxyport){ + $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword); + } + if($this->authtype != '') { + $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest); + } + if($this->http_encoding != ''){ + $http->setEncoding($this->http_encoding); + } + $this->debug('sending message, length='.strlen($msg)); + if(ereg('^http:',$this->endpoint)){ + //if(strpos($this->endpoint,'http:')){ + $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies); + } elseif(ereg('^https',$this->endpoint)){ + //} elseif(strpos($this->endpoint,'https:')){ + //if(phpversion() == '4.3.0-dev'){ + //$response = $http->send($msg,$timeout,$response_timeout); + //$this->request = $http->outgoing_payload; + //$this->response = $http->incoming_payload; + //} else + $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies); + } else { + $this->setError('no http/s in endpoint url'); + } + $this->request = $http->outgoing_payload; + $this->response = $http->incoming_payload; + $this->appendDebug($http->getDebug()); + $this->UpdateCookies($http->incoming_cookies); + + // save transport object if using persistent connections + if ($this->persistentConnection) { + $http->clearDebug(); + if (!is_object($this->persistentConnection)) { + $this->persistentConnection = $http; + } + } + + if($err = $http->getError()){ + $this->setError('HTTP Error: '.$err); + return false; + } elseif($this->getError()){ + return false; + } else { + $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']); + return $this->parseResponse($http->incoming_headers, $this->responseData); + } + break; + default: + $this->setError('no transport found, or selected transport is not yet supported!'); + return false; + break; + } + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']); + if (!strstr($headers['content-type'], 'text/xml')) { + $this->setError('Response not of type text/xml'); + return false; + } + if (strpos($headers['content-type'], '=')) { + $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); + $this->debug('Got response encoding: ' . $enc); + if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ + $this->xml_encoding = strtoupper($enc); + } else { + $this->xml_encoding = 'US-ASCII'; + } + } else { + // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 + $this->xml_encoding = 'ISO-8859-1'; + } + $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser'); + $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8); + // add parser debug data to our debug + $this->appendDebug($parser->getDebug()); + // if parse errors + if($errstr = $parser->getError()){ + $this->setError( $errstr); + // destroy the parser object + unset($parser); + return false; + } else { + // get SOAP headers + $this->responseHeaders = $parser->getHeaders(); + // get decoded message + $return = $parser->get_response(); + // add document for doclit support + $this->document = $parser->document; + // destroy the parser object + unset($parser); + // return decode message + return $return; + } + } + + /** + * sets the SOAP endpoint, which can override WSDL + * + * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override + * @access public + */ + function setEndpoint($endpoint) { + $this->forceEndpoint = $endpoint; + } + + /** + * set the SOAP headers + * + * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers + * @access public + */ + function setHeaders($headers){ + $this->requestHeaders = $headers; + } + + /** + * get the SOAP response headers (namespace resolution incomplete) + * + * @return string + * @access public + */ + function getHeaders(){ + return $this->responseHeaders; + } + + /** + * set proxy info here + * + * @param string $proxyhost + * @param string $proxyport + * @param string $proxyusername + * @param string $proxypassword + * @access public + */ + function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') { + $this->proxyhost = $proxyhost; + $this->proxyport = $proxyport; + $this->proxyusername = $proxyusername; + $this->proxypassword = $proxypassword; + } + + /** + * if authenticating, set user credentials here + * + * @param string $username + * @param string $password + * @param string $authtype (basic|digest|certificate) + * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs) + * @access public + */ + function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) { + $this->username = $username; + $this->password = $password; + $this->authtype = $authtype; + $this->certRequest = $certRequest; + } + + /** + * use HTTP encoding + * + * @param string $enc + * @access public + */ + function setHTTPEncoding($enc='gzip, deflate'){ + $this->http_encoding = $enc; + } + + /** + * use HTTP persistent connections if possible + * + * @access public + */ + function useHTTPPersistentConnection(){ + $this->persistentConnection = true; + } + + /** + * gets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style. + * Each call() can override this value. + * + * This is no longer used. + * + * @return boolean + * @access public + * @deprecated + */ + function getDefaultRpcParams() { + return $this->defaultRpcParams; + } + + /** + * sets the default RPC parameter setting. + * If true, default is that call params are like RPC even for document style + * Each call() can override this value. + * + * This is no longer used. + * + * @param boolean $rpcParams + * @access public + * @deprecated + */ + function setDefaultRpcParams($rpcParams) { + $this->defaultRpcParams = $rpcParams; + } + + /** + * dynamically creates an instance of a proxy class, + * allowing user to directly call methods from wsdl + * + * @return object soap_proxy object + * @access public + */ + function getProxy(){ + $r = rand(); + $evalStr = $this->_getProxyClassCode($r); + //$this->debug("proxy class: $evalStr"; + // eval the class + eval($evalStr); + // instantiate proxy object + eval("\$proxy = new soap_proxy_$r('');"); + // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice + $proxy->endpointType = 'wsdl'; + $proxy->wsdlFile = $this->wsdlFile; + $proxy->wsdl = $this->wsdl; + $proxy->operations = $this->operations; + $proxy->defaultRpcParams = $this->defaultRpcParams; + // transfer other state + $proxy->username = $this->username; + $proxy->password = $this->password; + $proxy->authtype = $this->authtype; + $proxy->proxyhost = $this->proxyhost; + $proxy->proxyport = $this->proxyport; + $proxy->proxyusername = $this->proxyusername; + $proxy->proxypassword = $this->proxypassword; + $proxy->timeout = $this->timeout; + $proxy->response_timeout = $this->response_timeout; + $proxy->http_encoding = $this->http_encoding; + $proxy->persistentConnection = $this->persistentConnection; + $proxy->requestHeaders = $this->requestHeaders; + $proxy->soap_defencoding = $this->soap_defencoding; + $proxy->endpoint = $this->endpoint; + $proxy->forceEndpoint = $this->forceEndpoint; + return $proxy; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access private + */ + function _getProxyClassCode($r) { + if ($this->endpointType != 'wsdl') { + $evalStr = 'A proxy can only be created for a WSDL client'; + $this->setError($evalStr); + return $evalStr; + } + $evalStr = ''; + foreach ($this->operations as $operation => $opData) { + if ($operation != '') { + // create param string and param comment string + if (sizeof($opData['input']['parts']) > 0) { + $paramStr = ''; + $paramArrayStr = ''; + $paramCommentStr = ''; + foreach ($opData['input']['parts'] as $name => $type) { + $paramStr .= "\$$name, "; + $paramArrayStr .= "'$name' => \$$name, "; + $paramCommentStr .= "$type \$$name, "; + } + $paramStr = substr($paramStr, 0, strlen($paramStr)-2); + $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2); + $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2); + } else { + $paramStr = ''; + $paramCommentStr = 'void'; + } + $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace']; + $evalStr .= "// $paramCommentStr + function " . str_replace('.', '__', $operation) . "($paramStr) { + \$params = array($paramArrayStr); + return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."'); + } + "; + unset($paramStr); + unset($paramCommentStr); + } + } + $evalStr = 'class soap_proxy_'.$r.' extends soapclient { + '.$evalStr.' +}'; + return $evalStr; + } + + /** + * dynamically creates proxy class code + * + * @return string PHP/NuSOAP code for the proxy class + * @access public + */ + function getProxyClassCode() { + $r = rand(); + return $this->_getProxyClassCode($r); + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + return $soapmsg; + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + return 'text/xml'; + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + return $this->soap_defencoding; + } + + /* + * whether or not parser should decode utf8 element content + * + * @return always returns true + * @access public + */ + function decodeUTF8($bool){ + $this->decode_utf8 = $bool; + return true; + } + + /** + * adds a new Cookie into $this->cookies array + * + * @param string $name Cookie Name + * @param string $value Cookie Value + * @return if cookie-set was successful returns true, else false + * @access public + */ + function setCookie($name, $value) { + if (strlen($name) == 0) { + return false; + } + $this->cookies[] = array('name' => $name, 'value' => $value); + return true; + } + + /** + * gets all Cookies + * + * @return array with all internal cookies + * @access public + */ + function getCookies() { + return $this->cookies; + } + + /** + * checks all Cookies and delete those which are expired + * + * @return always return true + * @access private + */ + function checkCookies() { + if (sizeof($this->cookies) == 0) { + return true; + } + $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies'); + $curr_cookies = $this->cookies; + $this->cookies = array(); + foreach ($curr_cookies as $cookie) { + if (! is_array($cookie)) { + $this->debug('Remove cookie that is not an array'); + continue; + } + if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) { + if (strtotime($cookie['expires']) > time()) { + $this->cookies[] = $cookie; + } else { + $this->debug('Remove expired cookie ' . $cookie['name']); + } + } else { + $this->cookies[] = $cookie; + } + } + $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array'); + return true; + } + + /** + * updates the current cookies with a new set + * + * @param array $cookies new cookies with which to update current ones + * @return always return true + * @access private + */ + function UpdateCookies($cookies) { + if (sizeof($this->cookies) == 0) { + // no existing cookies: take whatever is new + if (sizeof($cookies) > 0) { + $this->debug('Setting new cookie(s)'); + $this->cookies = $cookies; + } + return true; + } + if (sizeof($cookies) == 0) { + // no new cookies: keep what we've got + return true; + } + // merge + foreach ($cookies as $newCookie) { + if (!is_array($newCookie)) { + continue; + } + if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) { + continue; + } + $newName = $newCookie['name']; + + $found = false; + for ($i = 0; $i < count($this->cookies); $i++) { + $cookie = $this->cookies[$i]; + if (!is_array($cookie)) { + continue; + } + if (!isset($cookie['name'])) { + continue; + } + if ($newName != $cookie['name']) { + continue; + } + $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN'; + $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN'; + if ($newDomain != $domain) { + continue; + } + $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH'; + $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH'; + if ($newPath != $path) { + continue; + } + $this->cookies[$i] = $newCookie; + $found = true; + $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']); + break; + } + if (! $found) { + $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']); + $this->cookies[] = $newCookie; + } + } + return true; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/pear/nusoapmime.php b/gulliver/thirdparty/pear/nusoapmime.php new file mode 100644 index 000000000..1d99569fd --- /dev/null +++ b/gulliver/thirdparty/pear/nusoapmime.php @@ -0,0 +1,478 @@ + +* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list +* @version $Id: nusoapmime.php,v 1.7 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class soapclientmime extends soapclient { + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $requestAttachments = array(); + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $responseAttachments; + /** + * @var string + * @access private + */ + var $mimeContentType; + + /** + * adds a MIME attachment to the current request. + * + * If the $data parameter contains an empty string, this method will read + * the contents of the file named by the $filename parameter. + * + * If the $cid parameter is false, this method will generate the cid. + * + * @param string $data The data of the attachment + * @param string $filename The filename of the attachment (default is empty string) + * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) + * @param string $cid The content-id (cid) of the attachment (default is false) + * @return string The content-id (cid) of the attachment + * @access public + */ + function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { + if (! $cid) { + $cid = md5(uniqid(time())); + } + + $info['data'] = $data; + $info['filename'] = $filename; + $info['contenttype'] = $contenttype; + $info['cid'] = $cid; + + $this->requestAttachments[] = $info; + + return $cid; + } + + /** + * clears the MIME attachments for the current request. + * + * @access public + */ + function clearAttachments() { + $this->requestAttachments = array(); + } + + /** + * gets the MIME attachments from the current response. + * + * Each array element in the return is an associative array with keys + * data, filename, contenttype, cid. These keys correspond to the parameters + * for addAttachment. + * + * @return array The attachments. + * @access public + */ + function getAttachments() { + return $this->responseAttachments; + } + + /** + * gets the HTTP body for the current request. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + if (count($this->requestAttachments) > 0) { + $params['content_type'] = 'multipart/related; type=text/xml'; + $mimeMessage =& new Mail_mimePart('', $params); + unset($params); + + $params['content_type'] = 'text/xml'; + $params['encoding'] = '8bit'; + $params['charset'] = $this->soap_defencoding; + $mimeMessage->addSubpart($soapmsg, $params); + + foreach ($this->requestAttachments as $att) { + unset($params); + + $params['content_type'] = $att['contenttype']; + $params['encoding'] = 'base64'; + $params['disposition'] = 'attachment'; + $params['dfilename'] = $att['filename']; + $params['cid'] = $att['cid']; + + if ($att['data'] == '' && $att['filename'] <> '') { + if ($fd = fopen($att['filename'], 'rb')) { + $data = fread($fd, filesize($att['filename'])); + fclose($fd); + } else { + $data = ''; + } + $mimeMessage->addSubpart($data, $params); + } else { + $mimeMessage->addSubpart($att['data'], $params); + } + } + + $output = $mimeMessage->encode(); + $mimeHeaders = $output['headers']; + + foreach ($mimeHeaders as $k => $v) { + $this->debug("MIME header $k: $v"); + if (strtolower($k) == 'content-type') { + // PHP header() seems to strip leading whitespace starting + // the second line, so force everything to one line + $this->mimeContentType = str_replace("\r\n", " ", $v); + } + } + + return $output['body']; + } + + return parent::getHTTPBody($soapmsg); + } + + /** + * gets the HTTP content type for the current request. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current request. + * @access private + */ + function getHTTPContentType() { + if (count($this->requestAttachments) > 0) { + return $this->mimeContentType; + } + return parent::getHTTPContentType(); + } + + /** + * gets the HTTP content type charset for the current request. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current request. + * @access private + */ + function getHTTPContentTypeCharset() { + if (count($this->requestAttachments) > 0) { + return false; + } + return parent::getHTTPContentTypeCharset(); + } + + /** + * processes SOAP message returned from server + * + * @param array $headers The HTTP headers + * @param string $data unprocessed response data from server + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseResponse($headers, $data) { + $this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); + $this->responseAttachments = array(); + if (strstr($headers['content-type'], 'multipart/related')) { + $this->debug('Decode multipart/related'); + $input = ''; + foreach ($headers as $k => $v) { + $input .= "$k: $v\r\n"; + } + $params['input'] = $input . "\r\n" . $data; + $params['include_bodies'] = true; + $params['decode_bodies'] = true; + $params['decode_headers'] = true; + + $structure = Mail_mimeDecode::decode($params); + + foreach ($structure->parts as $part) { + if (!isset($part->disposition)) { + $this->debug('Have root part of type ' . $part->headers['content-type']); + $return = parent::parseResponse($part->headers, $part->body); + } else { + $this->debug('Have an attachment of type ' . $part->headers['content-type']); + $info['data'] = $part->body; + $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; + $info['contenttype'] = $part->headers['content-type']; + $info['cid'] = $part->headers['content-id']; + $this->responseAttachments[] = $info; + } + } + + if (isset($return)) { + return $return; + } + + $this->setError('No root part found in multipart/related content'); + return; + } + $this->debug('Not multipart/related'); + return parent::parseResponse($headers, $data); + } +} + +/** +* nusoapservermime server supporting MIME attachments defined at +* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library. +* +* @author Scott Nichol +* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list +* @version $Id: nusoapmime.php,v 1.7 2005/07/27 19:24:42 snichol Exp $ +* @access public +*/ +class nusoapservermime extends soap_server { + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $requestAttachments = array(); + /** + * @var array Each array element in the return is an associative array with keys + * data, filename, contenttype, cid + * @access private + */ + var $responseAttachments; + /** + * @var string + * @access private + */ + var $mimeContentType; + + /** + * adds a MIME attachment to the current response. + * + * If the $data parameter contains an empty string, this method will read + * the contents of the file named by the $filename parameter. + * + * If the $cid parameter is false, this method will generate the cid. + * + * @param string $data The data of the attachment + * @param string $filename The filename of the attachment (default is empty string) + * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream) + * @param string $cid The content-id (cid) of the attachment (default is false) + * @return string The content-id (cid) of the attachment + * @access public + */ + function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) { + if (! $cid) { + $cid = md5(uniqid(time())); + } + + $info['data'] = $data; + $info['filename'] = $filename; + $info['contenttype'] = $contenttype; + $info['cid'] = $cid; + + $this->responseAttachments[] = $info; + + return $cid; + } + + /** + * clears the MIME attachments for the current response. + * + * @access public + */ + function clearAttachments() { + $this->responseAttachments = array(); + } + + /** + * gets the MIME attachments from the current request. + * + * Each array element in the return is an associative array with keys + * data, filename, contenttype, cid. These keys correspond to the parameters + * for addAttachment. + * + * @return array The attachments. + * @access public + */ + function getAttachments() { + return $this->requestAttachments; + } + + /** + * gets the HTTP body for the current response. + * + * @param string $soapmsg The SOAP payload + * @return string The HTTP body, which includes the SOAP payload + * @access private + */ + function getHTTPBody($soapmsg) { + if (count($this->responseAttachments) > 0) { + $params['content_type'] = 'multipart/related; type=text/xml'; + $mimeMessage =& new Mail_mimePart('', $params); + unset($params); + + $params['content_type'] = 'text/xml'; + $params['encoding'] = '8bit'; + $params['charset'] = $this->soap_defencoding; + $mimeMessage->addSubpart($soapmsg, $params); + + foreach ($this->responseAttachments as $att) { + unset($params); + + $params['content_type'] = $att['contenttype']; + $params['encoding'] = 'base64'; + $params['disposition'] = 'attachment'; + $params['dfilename'] = $att['filename']; + $params['cid'] = $att['cid']; + + if ($att['data'] == '' && $att['filename'] <> '') { + if ($fd = fopen($att['filename'], 'rb')) { + $data = fread($fd, filesize($att['filename'])); + fclose($fd); + } else { + $data = ''; + } + $mimeMessage->addSubpart($data, $params); + } else { + $mimeMessage->addSubpart($att['data'], $params); + } + } + + $output = $mimeMessage->encode(); + $mimeHeaders = $output['headers']; + + foreach ($mimeHeaders as $k => $v) { + $this->debug("MIME header $k: $v"); + if (strtolower($k) == 'content-type') { + // PHP header() seems to strip leading whitespace starting + // the second line, so force everything to one line + $this->mimeContentType = str_replace("\r\n", " ", $v); + } + } + + return $output['body']; + } + + return parent::getHTTPBody($soapmsg); + } + + /** + * gets the HTTP content type for the current response. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type for the current response. + * @access private + */ + function getHTTPContentType() { + if (count($this->responseAttachments) > 0) { + return $this->mimeContentType; + } + return parent::getHTTPContentType(); + } + + /** + * gets the HTTP content type charset for the current response. + * returns false for non-text content types. + * + * Note: getHTTPBody must be called before this. + * + * @return string the HTTP content type charset for the current response. + * @access private + */ + function getHTTPContentTypeCharset() { + if (count($this->responseAttachments) > 0) { + return false; + } + return parent::getHTTPContentTypeCharset(); + } + + /** + * processes SOAP message received from client + * + * @param array $headers The HTTP headers + * @param string $data unprocessed request data from client + * @return mixed value of the message, decoded into a PHP type + * @access private + */ + function parseRequest($headers, $data) { + $this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']); + $this->requestAttachments = array(); + if (strstr($headers['content-type'], 'multipart/related')) { + $this->debug('Decode multipart/related'); + $input = ''; + foreach ($headers as $k => $v) { + $input .= "$k: $v\r\n"; + } + $params['input'] = $input . "\r\n" . $data; + $params['include_bodies'] = true; + $params['decode_bodies'] = true; + $params['decode_headers'] = true; + + $structure = Mail_mimeDecode::decode($params); + + foreach ($structure->parts as $part) { + if (!isset($part->disposition)) { + $this->debug('Have root part of type ' . $part->headers['content-type']); + $return = parent::parseRequest($part->headers, $part->body); + } else { + $this->debug('Have an attachment of type ' . $part->headers['content-type']); + $info['data'] = $part->body; + $info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : ''; + $info['contenttype'] = $part->headers['content-type']; + $info['cid'] = $part->headers['content-id']; + $this->requestAttachments[] = $info; + } + } + + if (isset($return)) { + return $return; + } + + $this->setError('No root part found in multipart/related content'); + return; + } + $this->debug('Not multipart/related'); + return parent::parseRequest($headers, $data); + } +} +?> diff --git a/gulliver/thirdparty/pear/package-Archive_Tar.xml b/gulliver/thirdparty/pear/package-Archive_Tar.xml new file mode 100644 index 000000000..64ee07b5c --- /dev/null +++ b/gulliver/thirdparty/pear/package-Archive_Tar.xml @@ -0,0 +1,60 @@ + + + + Archive_Tar + Tar file management class + This class provides handling of tar files in PHP. +It supports creating, listing, extracting and adding to tar files. +Gzip support is available if PHP has the zlib extension built-in or +loaded. + + PHP License + + + vblavet + lead + Vincent Blavet + vincent@blavet.net + + + ssb + helper + Stig Sæther Bakken + stig@php.net + + + + 0.9 + 2002-05-27 + + * Auto-detect gzip'ed files + + stable + + + + + + + + + + 0.4 + 2002-05-20 + Windows bugfix: use forward slashes inside archives + stable + + + 0.2 + 2002-02-18 + From initial commit to stable + stable + + + 0.3 + 2002-04-13 + Windows bugfix: used wrong directory separators + stable + + + diff --git a/gulliver/thirdparty/pear/package-Console_Getopt.xml b/gulliver/thirdparty/pear/package-Console_Getopt.xml new file mode 100644 index 000000000..1bc3eb02d --- /dev/null +++ b/gulliver/thirdparty/pear/package-Console_Getopt.xml @@ -0,0 +1,63 @@ + + + + + Console_Getopt + Command-line option parser + This is a PHP implementation of "getopt" supporting both +short and long options. + PHP License + + + andrei + lead + Andrei Zmievski + andrei@php.net + + + ssb + developer + Stig Bakken + stig@php.net + + + + 1.0 + 2002-09-13 + Stable release + stable + + + + + + + + + 0.11 + 2002-05-26 + POSIX getopt compatibility fix: treat first element of args + array as command name + + beta + + + + + + + + 0.10 + 2002-05-12 + Packaging fix + beta + + + 0.9 + 2002-05-12 + Initial release + beta + + + diff --git a/gulliver/thirdparty/pear/package-PEAR.xml b/gulliver/thirdparty/pear/package-PEAR.xml new file mode 100644 index 000000000..ad739feae --- /dev/null +++ b/gulliver/thirdparty/pear/package-PEAR.xml @@ -0,0 +1,342 @@ + + + + PEAR + PEAR Base System + The PEAR package contains: + * the PEAR base class + * the PEAR_Error error handling mechanism + * the PEAR installer, for creating, distributing + and installing packages + + PHP License + + + ssb + lead + Stig Sæther Bakken + stig@php.net + + + cox + developer + Tomas V.V.Cox + cox@idecnet.com + + + mj + helper + Martin Jansen + mj@php.net + + + pajoye + developer + Pierre-Alain Joye + pajoye@pearfr.org + + + + 1.1 + stable + 2003-01-10 + +PEAR BASE CLASS: + +* PEAR_Error now supports exceptions when using Zend Engine 2. Set the + error mode to PEAR_ERROR_EXCEPTION to make PEAR_Error throw itself + as an exception (invoke PEAR errors with raiseError() or throwError() + just like before). + +PEAR INSTALLER: + +* Packaging and validation now parses PHP source code (unless + ext/tokenizer is disabled) and does some coding standard conformance + checks. Specifically, the names of classes and functions are + checked to ensure that they are prefixed with the package name. If + your package has symbols that should be without this prefix, you can + override this warning by explicitly adding a "provides" entry in + your package.xml file. See the package.xml file for this release + for an example (OS_Guess, System and md5_file). + + All classes and non-private (not underscore-prefixed) methods and + functions are now registered during "pear package". + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Archive_Tar + Console_Getopt + + + + + 1.0.1 + stable + 2003-01-10 + + * PEAR_Error class has call backtrace available by + calling getBacktrace(). Available if used with + PHP 4.3 or newer. + + * PEAR_Config class uses getenv() rather than $_ENV + to read environment variables. + + * System::which() Windows fix, now looks for + exe/bat/cmd/com suffixes rather than just exe + + * Added "pear cvsdiff" command + + * Windows output buffering bugfix for "pear" command + + * Multiple drives installation now works on windows + + * pear.bat uses ENV variables, allowing the installation + of many PEAR (windows) + + + + Archive_Tar + Console_Getopt + + + + 1.0 + stable + 2002-12-27 + + * set default cache_ttl to 1 hour + * added "clear-cache" command + + + + Archive_Tar + Console_Getopt + + + + 1.0b3 + stable + 2002-12-13 + + * fixed "info" shortcut (conflicted with "install") + * added "php_bin" config parameter + * all "non-personal" config parameters now use + environment variables for defaults (very useful + to override the default php_dir on Windows!) + + + + Archive_Tar + Console_Getopt + + + + 1.0b2 + stable + 2002-11-26 + +Changes, Installer: +* --force option no longer ignores errors, use + --ignore-errors instead +* installer transactions: failed installs abort + cleanly, without leaving half-installed packages + around + + + + 1.0b1 + stable + 2002-10-12 + +New Features, Installer: +* new command: "pear makerpm" +* new command: "pear search" +* new command: "pear upgrade-all" +* new command: "pear config-help" +* new command: "pear sign" +* Windows support for "pear build" (requires + msdev) +* new dependency type: "zend" +* XML-RPC results may now be cached (see + cache_dir and cache_ttl config) +* HTTP proxy authorization support +* install/upgrade install-root support + +Bugfixes, Installer: +* fix for XML-RPC bug that made some remote + commands fail +* fix problems under Windows with + DIRECTORY_SEPARATOR +* lots of other minor fixes +* --force option did not work for "pear install + Package" +* http downloader used "4.2.1" rather than + "PHP/4.2.1" as user agent +* bending over a little more to figure out how + PHP is installed +* "platform" file attribute was not included + during "pear package" + +New Features, PEAR Library: +* added PEAR::loadExtension($ext) +* added PEAR::delExpect() +* System::mkTemp() now cleans up at shutdown +* defined PEAR_ZE2 constant (boolean) +* added PEAR::throwError() with a simpler API + than raiseError() + +Bugfixes, PEAR Library: +* ZE2 compatibility fixes +* use getenv() as fallback for $_ENV + + + + Archive_Tar + Console_Getopt + + + + 0.90 + beta + 2002-05-28 + +* fix: "help" command was broken +* new command: "info" +* new command: "config-help" +* un-indent multi-line data from xml description files +* new command: "build" +* fix: config-set did not work with "set" parameters +* disable magic_quotes_runtime +* "install" now builds and installs C extensions +* added PEAR::delExpect() +* System class no longer inherits PEAR +* grouped PEAR_Config parameters +* add --nobuild option to install/upgrade commands +* new and more generic Frontend API + + + + Archive_Tar + Console_Getopt + + + + 0.10 + beta + 2002-05-26 + +Lots of stuff this time. 0.9 was not actually self-hosting, even +though it claimed to be. This version finally is self-hosting +(really!), meaning you can upgrade the installer with the command +"pear upgrade PEAR". + +* new config paramers: http_proxy and umask +* HTTP proxy support when downloading packages +* generalized command handling code +* and fixed the bug that would not let commands have the + same options as "pear" itself +* added long options to every command +* added command shortcuts ("pear help shortcuts") +* added stub for Gtk installer +* some phpdoc fixes +* added class dependency detector (using ext/tokenizer) +* dependency handling fixes +* added OS_Guess class for detecting OS +* install files with the "platform" attribute set + only on matching operating systems +* PEAR_Remote now falls back to the XML_RPC package + if xmlrpc-epi is not available +* renamed command: package-list -> list +* new command: package-dependencies +* lots of minor fixes + + + + Archive_Tar + Console_Getopt + + + + 0.9 + beta + 2002-04-07 + +First package release. Commands implemented: + remote-package-info + list-upgrades + list-remote-packages + download + config-show + config-get + config-set + list-installed + shell-test + install + uninstall + upgrade + package + package-list + package-info + login + logout + + + + diff --git a/gulliver/thirdparty/pear/package.dtd b/gulliver/thirdparty/pear/package.dtd new file mode 100644 index 000000000..3567564a4 --- /dev/null +++ b/gulliver/thirdparty/pear/package.dtd @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/pear/template.spec b/gulliver/thirdparty/pear/template.spec new file mode 100644 index 000000000..dc6c66550 --- /dev/null +++ b/gulliver/thirdparty/pear/template.spec @@ -0,0 +1,44 @@ +Summary: PEAR: @summary@ +Name: @rpm_package@ +Version: @version@ +Release: 1 +License: @release_license@ +Group: Development/Libraries +Source: http://@master_server@/get/@package@-%{version}.tgz +BuildRoot: %{_tmppath}/%{name}-root +URL: http://@master_server@/ +Prefix: %{_prefix} +Docdir: @doc_dir@/@package@ +BuildArchitectures: @arch@ +@extra_headers@ + +%description +@description@ + +%prep +#rm -rf Console_Getopt-%{version} package.xml +#mkdir -p Console_Getopt-%{version} +#ln -s Console_Getopt-%{version}/package.xml package.xml +%setup -q -D -n @package@-%{version} +mv ../package.xml . + +%build +echo BuildRoot=%{buildroot} + +%post +pear uninstall --nodeps -r @package@ + +%postun +pear install --nodeps -r @rpm_xml_dir@/@package@.xml + +%install +rm -rf %{buildroot}/* +pear -q install -R %{buildroot} -n package.xml +mkdir -p %{buildroot}@rpm_xml_dir@ +cp -p package.xml %{buildroot}@rpm_xml_dir@/@package@.xml + +%files +%defattr(-,root,root) +%doc @doc_files@ +@files@ +@rpm_xml_dir@/@package@.xml diff --git a/gulliver/thirdparty/phing/BuildEvent.php b/gulliver/thirdparty/phing/BuildEvent.php new file mode 100644 index 000000000..19c29807c --- /dev/null +++ b/gulliver/thirdparty/phing/BuildEvent.php @@ -0,0 +1,205 @@ +. + */ + +require_once 'phing/system/lang/EventObject.php'; + +/** + * Encapsulates a build specific event. + * + *

    We have three sources of events all handled by this class: + * + *

      + *
    • Project level events
    • + *
    • Target level events
    • + *
    • Task level events
    • + *
    + * + *

    Events are all fired from the project class by creating an event object + * using this class and passing it to the listeners. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.10 $ + * @package phing + */ +class BuildEvent extends EventObject { + + /** + * A reference to the project + * @var Project + */ + protected $project; + + /** + * A reference to the target + * @var Target + */ + protected $target; + + /** + * A reference to the task + * + * @var Task + */ + protected $task; + + /** + * The message of this event, if the event is a message + * @var string + * @access private + */ + protected $message = null; + + /** + * The priority of the message + * + * @var string + * @see $message + * @access private + */ + protected $priority = PROJECT_MSG_VERBOSE; + + /** + * The execption that caused the event, if any + * + * @var object + * @access private + */ + protected $exception = null; + + /** + * Construct a BuildEvent for a project, task or target source event + * + * @param object project the project that emitted the event. + * @access public + */ + function __construct($source) { + parent::__construct($source); + if ($source instanceof Project) { + $this->project = $source; + $this->target = null; + $this->task = null; + } elseif ($source instanceof Target) { + $this->project = $source->getProject(); + $this->target = $source; + $this->task = null; + } elseif ($source instanceof Task) { + $this->project = $source->getProject(); + $this->target = $source->getOwningTarget(); + $this->task = $source; + } else { + throw new Exception("Can not construct BuildEvent, unknown source given."); + } + } + + /** + * Sets the message with details and the message priority for this event. + * + * @param string The string message of the event + * @param integer The priority this message should have + */ + function setMessage($message, $priority) { + $this->message = (string) $message; + $this->priority = (int) $priority; + } + + /** + * Set the exception that was the cause of this event. + * + * @param Exception The exception that caused the event + */ + function setException($exception) { + $this->exception = $exception; + } + + /** + * Returns the project instance that fired this event. + * + * The reference to the project instance is set by the constructor if this + * event was fired from the project class. + * + * @return Project The project instance that fired this event + */ + function getProject() { + return $this->project; + } + + /** + * Returns the target instance that fired this event. + * + * The reference to the target instance is set by the constructor if this + * event was fired from the target class. + * + * @return object The target that fired this event + * @access public + */ + function getTarget() { + return $this->target; + } + + /** + * Returns the target instance that fired this event. + * + * The reference to the task instance is set by the constructor if this + * event was fired within a task. + * + * @return object The task that fired this event + * @access public + */ + function getTask() { + return $this->task; + } + + /** + * Returns the logging message. This field will only be set for + * "messageLogged" events. + * + * @return string The log message + * @access public + */ + function getMessage() { + return $this->message; + } + + /** + * Returns the priority of the logging message. This field will only + * be set for "messageLogged" events. + * + * @return integer The message priority + * @access public + */ + function getPriority() { + return $this->priority; + } + + /** + * Returns the exception that was thrown, if any. + * This field will only be set for "taskFinished", "targetFinished", and + * "buildFinished" events. + * + * @see BuildListener::taskFinished() + * @see BuildListener::targetFinished() + * @see BuildListener::buildFinished() + */ + function getException() { + return $this->exception; + } +} diff --git a/gulliver/thirdparty/phing/BuildException.php b/gulliver/thirdparty/phing/BuildException.php new file mode 100644 index 000000000..a26676cec --- /dev/null +++ b/gulliver/thirdparty/phing/BuildException.php @@ -0,0 +1,100 @@ +. + */ + +/** + * BuildException is for when things go wrong in a build execution. + * + * @author Andreas Aderhold + * @version $Revision: 1.12 $ + * @package phing + */ +class BuildException extends Exception { + + /** location in the xml file */ + protected $location = null; + + /** The nested "cause" exception. */ + protected $cause; + + /** + * Construct a BuildException. + * Supported signatures: + * throw new BuildException($causeExc); + * throw new BuildException($msg); + * throw new Buildexception($causeExc, $loc); + * throw new BuildException($msg, $causeExc); + * throw new BuildException($msg, $loc); + * throw new BuildException($msg, $causeExc, $loc); + */ + function __construct($p1, $p2 = null, $p3 = null) { + + $cause = null; + $loc = null; + $msg = ""; + + if ($p3 !== null) { + $cause = $p2; + $loc = $p3; + $msg = $p1; + } elseif ($p2 !== null) { + if ($p2 instanceof Exception) { + $cause = $p2; + $msg = $p1; + } elseif ($p2 instanceof Location) { + $loc = $p2; + if ($p1 instanceof Exception) { + $cause = $p1; + } else { + $msg = $p1; + } + } + } elseif ($p1 instanceof Exception) { + $cause = $p1; + } else { + $msg = $p1; + } + + parent::__construct($msg); + + if ($cause !== null) { + $this->cause = $cause; + $this->message .= " [wrapped: " . $cause->getMessage() ."]"; + } + + if ($loc !== null) { + $this->setLocation($loc); + } + } + + function getCause() { + return $this->cause; + } + + function getLocation() { + return $this->location; + } + + function setLocation($loc) { + $this->location = $loc; + $this->message = $loc->toString() . ': ' . $this->message; + } + +} diff --git a/gulliver/thirdparty/phing/BuildListener.php b/gulliver/thirdparty/phing/BuildListener.php new file mode 100644 index 000000000..21c578ae0 --- /dev/null +++ b/gulliver/thirdparty/phing/BuildListener.php @@ -0,0 +1,91 @@ +. + */ + +/** + * Interface for build listeners. + * + * Classes that implement a listener must extend this class and (faux)implement + * all methods that are decleard as dummies below. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.6 $ + * @see BuildEvent + * @see Project::addBuildListener() + * @package phing + */ +interface BuildListener { + + /** + * Fired before any targets are started. + * + * @param BuildEvent The BuildEvent + */ + function buildStarted(BuildEvent $event); + + /** + * Fired after the last target has finished. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent::getException() + */ + function buildFinished(BuildEvent $event); + + /** + * Fired when a target is started. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent::getTarget() + */ + function targetStarted(BuildEvent $event); + + /** + * Fired when a target has finished. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent#getException() + */ + function targetFinished(BuildEvent $event); + + /** + * Fired when a task is started. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent::getTask() + */ + function taskStarted(BuildEvent $event); + + /** + * Fired when a task has finished. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent::getException() + */ + function taskFinished(BuildEvent $event); + + /** + * Fired whenever a message is logged. + * + * @param BuildEvent The BuildEvent + * @see BuildEvent::getMessage() + */ + function messageLogged(BuildEvent $event); +} diff --git a/gulliver/thirdparty/phing/IntrospectionHelper.php b/gulliver/thirdparty/phing/IntrospectionHelper.php new file mode 100644 index 000000000..5cb693885 --- /dev/null +++ b/gulliver/thirdparty/phing/IntrospectionHelper.php @@ -0,0 +1,542 @@ +. + */ + +include_once 'phing/types/Reference.php'; +include_once 'phing/types/Path.php'; +include_once 'phing/util/StringHelper.php'; + +/** + * Helper class that collects the methods that a task or nested element + * holds to set attributes, create nested elements or hold PCDATA + * elements. + * + *

      + *
    • SMART-UP INLINE DOCS
    • + *
    • POLISH-UP THIS CLASS
    • + *
    + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.19 $ + * @package phing + */ +class IntrospectionHelper { + + + + /** + * Holds the attribute setter methods. + * + * @var array string[] + */ + private $attributeSetters = array(); + + /** + * Holds methods to create nested elements. + * + * @var array string[] + */ + private $nestedCreators = array(); + + /** + * Holds methods to store configured nested elements. + * + * @var array string[] + */ + private $nestedStorers = array(); + + /** + * Map from attribute names to nested types. + */ + private $nestedTypes = array(); + + /** + * New idea in phing: any class can register certain + * keys -- e.g. "task.current_file" -- which can be used in + * task attributes, if supported. In the build XML these + * are referred to like this: + * + * In the type/task a listener method must be defined: + * function setListeningReplace($slot) {} + * @var array string[] + */ + private $slotListeners = array(); + + /** + * The method to add PCDATA stuff. + * + * @var string Method name of the addText (redundant?) method, if class supports it :) + */ + private $methodAddText = null; + + /** + * The Class that's been introspected. + * + * @var object + * @access private + */ + private $bean; + + /** + * The cache of IntrospectionHelper classes instantiated by getHelper(). + * @var array IntrospectionHelpers[] + */ + private static $helpers = array(); + + /** + * Factory method for helper objects. + * + * @param string $class The class to create a Helper for + */ + public static function getHelper($class) { + if (!isset(self::$helpers[$class])) { + self::$helpers[$class] = new IntrospectionHelper($class); + } + return self::$helpers[$class]; + } + + /** + * This function constructs a new introspection helper for a specific class. + * + * This method loads all methods for the specified class and categorizes them + * as setters, creators, slot listeners, etc. This way, the setAttribue() doesn't + * need to perform any introspection -- either the requested attribute setter/creator + * exists or it does not & a BuildException is thrown. + * + * @param string $bean The classname for this IH. + */ + function __construct($class) { + + $this->bean = new ReflectionClass($class); + + //$methods = get_class_methods($bean); + foreach($this->bean->getMethods() as $method) { + + if ($method->isPublic()) { + + // We're going to keep case-insensitive method names + // for as long as we're allowed :) It makes it much + // easier to map XML attributes to PHP class method names. + $name = strtolower($method->getName()); + + // There are a few "reserved" names that might look like attribute setters + // but should actually just be skipped. (Note: this means you can't ever + // have an attribute named "location" or "tasktype" or a nested element named "task".) + if ($name === "setlocation" || $name === "settasktype" || $name === "addtask") { + continue; + } + + if ($name === "addtext") { + + $this->methodAddText = $method; + + } elseif (strpos($name, "setlistening") === 0) { + + // Phing supports something unique called "RegisterSlots" + // These are dynamic values that use a basic slot system so that + // classes can register to listen to specific slots, and the value + // will always be grabbed from the slot (and never set in the project + // component). This is useful for things like tracking the current + // file being processed by a filter (e.g. AppendTask sets an append.current_file + // slot, which can be ready by the XSLTParam type.) + + if (count($method->getParameters()) !== 1) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take exactly one parameter."); + } + + $this->slotListeners[$name] = $method; + + } elseif (strpos($name, "set") === 0) { + + // A standard attribute setter. + + if (count($method->getParameters()) !== 1) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take exactly one parameter."); + } + + $this->attributeSetters[$name] = $method; + + } elseif (strpos($name, "create") === 0) { + + if (count($method->getParameters()) > 0) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() may not take any parameters."); + } + + // Because PHP doesn't support return types, we are going to do + // two things here to guess return type: + // 1) parse comments for an explicit value + // 2) if that fails, assume that the part of the method after "create" + // is the name of the return type (in many cases it is not) + + // This isn't super important -- i.e. we're not instantaiting classes + // based on this information. It's more just so that IntrospectionHelper + // can keep track of all the nested types -- and provide more helpful + // exception messages, etc. + + preg_match('/@return[\s]+([\w]+)/', $method->getDocComment(), $matches); + if (!empty($matches[1]) && class_exists($matches[1], false)) { + $this->nestedTypes[$name] = $matches[1]; + } else { + // assume that method createEquals() creates object of type "Equals" + // (that example would be false, of course) + $this->nestedTypes[$name] = $this->getPropertyName($name, "create"); + } + + $this->nestedCreators[$name] = $method; + + } elseif (strpos($name, "addconfigured") === 0) { + + // *must* use class hints if using addConfigured ... + + // 1 param only + $params = $method->getParameters(); + + if (count($params) < 1) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take at least one parameter."); + } + + if (count($params) > 1) { + $this->warn($method->getDeclaringClass()->getName()."::".$method->getName()."() takes more than one parameter. (IH only uses the first)"); + } + + $classname = null; + + if (($hint = $params[0]->getClass()) !== null) { + $classname = $hint->getName(); + } + + if ($classname === null) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() method MUST use a class hint to indicate the class type of parameter."); + } + + $this->nestedTypes[$name] = $classname; + + $this->nestedStorers[$name] = $method; + + } elseif (strpos($name, "add") === 0) { + + // *must* use class hints if using add ... + + // 1 param only + $params = $method->getParameters(); + if (count($params) < 1) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take at least one parameter."); + } + + if (count($params) > 1) { + $this->warn($method->getDeclaringClass()->getName()."::".$method->getName()."() takes more than one parameter. (IH only uses the first)"); + } + + $classname = null; + + if (($hint = $params[0]->getClass()) !== null) { + $classname = $hint->getName(); + } + + // we don't use the classname here, but we need to make sure it exists before + // we later try to instantiate a non-existant class + if ($classname === null) { + throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() method MUST use a class hint to indicate the class type of parameter."); + } + + $this->nestedCreators[$name] = $method; + } + } // if $method->isPublic() + } // foreach + } + + + /** Sets the named attribute. */ + function setAttribute(Project $project, $element, $attributeName, &$value) { + + // we want to check whether the value we are setting looks like + // a slot-listener variable: %{task.current_file} + // + // slot-listener variables are not like properties, in that they cannot be mixed with + // other text values. The reason for this disparity is that properties are only + // set when first constructing objects from XML, whereas slot-listeners are always dynamic. + // + // This is made possible by PHP5 (objects automatically passed by reference) and PHP's loose + // typing. + + if (StringHelper::isSlotVar($value)) { + + $as = "setlistening" . strtolower($attributeName); + + if (!isset($this->slotListeners[$as])) { + $msg = $this->getElementName($project, $element) . " doesn't support a slot-listening '$attributeName' attribute."; + throw new BuildException($msg); + } + + $method = $this->slotListeners[$as]; + + $key = StringHelper::slotVar($value); + $value = Register::getSlot($key); // returns a RegisterSlot object which will hold current value of that register (accessible using getValue()) + + } else { + + // Traditional value options + + $as = "set".strtolower($attributeName); + + if (!isset($this->attributeSetters[$as])) { + $msg = $this->getElementName($project, $element) . " doesn't support the '$attributeName' attribute."; + throw new BuildException($msg); + } + + $method = $this->attributeSetters[$as]; + + if ($as == "setrefid") { + $value = new Reference($value); + } else { + + // decode any html entities in string + $value = html_entity_decode($value); + + // value is a string representation of a boolean type, + // convert it to primitive + if (StringHelper::isBoolean($value)) { + + $value = StringHelper::booleanValue($value); + } + + // does method expect a PhingFile object? if so, then + // pass a project-relative file. + $params = $method->getParameters(); + + $classname = null; + + if (($hint = $params[0]->getClass()) !== null) { + $classname = $hint->getName(); + } + + // there should only be one param; we'll just assume .... + if ($classname !== null) { + switch(strtolower($classname)) { + case "phingfile": + $value = $project->resolveFile($value); + break; + case "path": + $value = new Path($project, $value); + break; + case "reference": + $value = new Reference($value); + break; + // any other object params we want to support should go here ... + } + + } // if hint !== null + + } // if not setrefid + + } // if is slot-listener + + try { + $project->log(" -calling setter ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", PROJECT_MSG_DEBUG); + $method->invoke($element, $value); + } catch(Exception $exc) { + throw new BuildException($exc); + } + + } + + /** Adds PCDATA areas.*/ + function addText(Project $project, $element, $text) { + if ($this->methodAddText === null) { + $msg = $this->getElementName($project, $element)." doesn't support nested text data."; + throw new BuildException($msg); + } + try { + $method = $this->methodAddText; + $method->invoke($element, $text); + } catch (Exception $exc) { + throw new BuildException($exc); + } + } + + /** + * Creates a named nested element. + * + * Valid creators can be in the form createFoo() or addFoo(Bar). + * @return object Returns the nested element. + * @throws BuildException + */ + function createElement(Project $project, $element, $elementName) { + + $addMethod = "add".strtolower($elementName); + $createMethod = "create".strtolower($elementName); + $nestedElement = null; + + if (isset($this->nestedCreators[$createMethod])) { + + $method = $this->nestedCreators[$createMethod]; + try { // try to invoke the creator method on object + $project->log(" -calling creator ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", PROJECT_MSG_DEBUG); + $nestedElement = $method->invoke($element); + } catch (Exception $exc) { + throw new BuildException($exc); + } + + } elseif (isset($this->nestedCreators[$addMethod])) { + + $method = $this->nestedCreators[$addMethod]; + + // project components must use class hints to support the add methods + + try { // try to invoke the adder method on object + + $project->log(" -calling adder ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", PROJECT_MSG_DEBUG); + // we've already assured that correct num of params + // exist and that method is using class hints + $params = $method->getParameters(); + + $classname = null; + + if (($hint = $params[0]->getClass()) !== null) { + $classname = $hint->getName(); + } + + // create a new instance of the object and add it via $addMethod + $nestedElement = new $classname(); + + $method->invoke($element, $nestedElement); + + } catch (Exception $exc) { + throw new BuildException($exc); + } + } else { + $msg = $this->getElementName($project, $element) . " doesn't support the '$elementName' creator/adder."; + throw new BuildException($msg); + } + + if ($nestedElement instanceof ProjectComponent) { + $nestedElement->setProject($project); + } + + return $nestedElement; + } + + /** + * Creates a named nested element. + * @return void + * @throws BuildException + */ + function storeElement($project, $element, $child, $elementName = null) { + + if ($elementName === null) { + return; + } + + $storer = "addconfigured".strtolower($elementName); + + if (isset($this->nestedStorers[$storer])) { + + $method = $this->nestedStorers[$storer]; + + try { + $project->log(" -calling storer ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", PROJECT_MSG_DEBUG); + $method->invoke($element, $child); + } catch (Exception $exc) { + throw new BuildException($exc); + } + } + + } + + /** Does the introspected class support PCDATA? */ + function supportsCharacters() { + return ($this->methodAddText !== null); + } + + /** Return all attribues supported by the introspected class. */ + function getAttributes() { + $attribs = array(); + foreach (array_keys($this->attributeSetters) as $setter) { + $attribs[] =$this->getPropertyName($setter, "set"); + } + return $attribs; + } + + /** Return all nested elements supported by the introspected class. */ + function getNestedElements() { + return $this->nestedTypes; + } + + /** + * Get the the name for an element. + * When possible the full classnam (phing.tasks.system.PropertyTask) will + * be returned. If not available (loaded in taskdefs or typedefs) then the + * XML element name will be returned. + * + * @param Project $project + * @param object $element The Task or type element. + * @return string Fully qualified class name of element when possible. + */ + function getElementName(Project $project, $element) { + + $taskdefs = $project->getTaskDefinitions(); + $typedefs = $project->getDataTypeDefinitions(); + + // check if class of element is registered with project (tasks & types) + // most element types don't have a getTag() method + $elClass = get_class($element); + + if (!in_array('getTag', get_class_methods($elClass))) { + // loop through taskdefs and typesdefs and see if the class name + // matches (case-insensitive) any of the classes in there + foreach(array_merge($taskdefs, $typedefs) as $elName => $class) { + if (0 === strcasecmp($elClass, StringHelper::unqualify($class))) { + return $class; + } + } + return "$elClass (unknown)"; + } else { + // ->getTag() method does exist, so use it + $elName = $element->getTag(); + if (isset($taskdefs[$elName])) { + return $taskdefs[$elName]; + } elseif (isset($typedefs[$elName])) { + + return $typedefs[$elName]; + } else { + return "$elName (unknown)"; + } + } + } + + /** extract the name of a property from a method name - subtracting a given prefix. */ + function getPropertyName($methodName, $prefix) { + $start = strlen($prefix); + return strtolower(substr($methodName, $start)); + } + + /** + * Prints warning message to screen if -debug was used. + */ + function warn($msg) { + if (Phing::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { + print("[IntrospectionHelper] " . $msg . "\n"); + } + } + +} diff --git a/gulliver/thirdparty/phing/Phing.php b/gulliver/thirdparty/phing/Phing.php new file mode 100644 index 000000000..a69b8e365 --- /dev/null +++ b/gulliver/thirdparty/phing/Phing.php @@ -0,0 +1,1161 @@ +. + */ + +require_once 'phing/Project.php'; +require_once 'phing/ProjectComponent.php'; +require_once 'phing/Target.php'; +require_once 'phing/Task.php'; + +include_once 'phing/BuildException.php'; +include_once 'phing/BuildEvent.php'; + +include_once 'phing/parser/Location.php'; +include_once 'phing/parser/ExpatParser.php'; +include_once 'phing/parser/AbstractHandler.php'; +include_once 'phing/parser/ProjectConfigurator.php'; +include_once 'phing/parser/RootHandler.php'; +include_once 'phing/parser/ProjectHandler.php'; +include_once 'phing/parser/TaskHandler.php'; +include_once 'phing/parser/TargetHandler.php'; +include_once 'phing/parser/DataTypeHandler.php'; +include_once 'phing/parser/NestedElementHandler.php'; + +include_once 'phing/system/util/Properties.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/FileReader.php'; +include_once 'phing/system/util/Register.php'; + +/** + * Entry point into Phing. This class handles the full lifecycle of a build -- from + * parsing & handling commandline arguments to assembling the project to shutting down + * and cleaning up in the end. + * + * If you are invoking Phing from an external application, this is still + * the class to use. Your applicaiton can invoke the start() method, passing + * any commandline arguments or additional properties. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.51 $ + * @package phing + */ +class Phing { + + /** The default build file name */ + const DEFAULT_BUILD_FILENAME = "build.xml"; + + /** Our current message output status. Follows PROJECT_MSG_XXX */ + private static $msgOutputLevel = PROJECT_MSG_INFO; + + /** PhingFile that we are using for configuration */ + private $buildFile = null; + + /** The build targets */ + private $targets = array(); + + /** + * Set of properties that are passed in from commandline or invoking code. + * @var Properties + */ + private static $definedProps; + + /** Names of classes to add as listeners to project */ + private $listeners = array(); + + private $loggerClassname = null; + + /** The class to handle input (can be only one). */ + private $inputHandlerClassname; + + /** Indicates if this phing should be run */ + private $readyToRun = false; + + /** Indicates we should only parse and display the project help information */ + private $projectHelp = false; + + /** Used by utility function getResourcePath() */ + private static $importPaths; + + /** System-wide static properties (moved from System) */ + private static $properties = array(); + + /** Static system timer. */ + private static $timer; + + /** The current Project */ + private static $currentProject; + + /** Whether to capture PHP errors to buffer. */ + private static $phpErrorCapture = false; + + /** Array of captured PHP errors */ + private static $capturedPhpErrors = array(); + + /** + * Prints the message of the Exception if it's not null. + */ + function printMessage(Exception $t) { + print($t->getMessage() . "\n"); + if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { + print($t->getTraceAsString()."\n"); + if ($t instanceof Exception) { + $c = $t->getCause(); + if ($c !== null) { + print("Wrapped exception trace:\n"); + print($c->getTraceAsString() . "\n"); + } + } + } // if output level is DEBUG + } + + /** + * Entry point allowing for more options from other front ends. + * + * This method encapsulates the complete build lifecycle. + * + * @param array &$args The commandline args passed to phing shell script. + * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this). + * These additional properties will be available using the getDefinedProperty() method and will + * be added to the project's "user" properties. + * @return void + * @see execute() + * @see runBuild() + */ + public static function start(&$args, $additionalUserProperties = null) { + + try { + $m = new Phing(); + $m->execute($args); + } catch (Exception $exc) { + $m->printMessage($exc); + self::halt(-1); // Parameter error + } + + if ($additionalUserProperties !== null) { + $keys = $m->additionalUserProperties->keys(); + while(count($keys)) { + $key = array_shift($keys); + $property = $m->additionalUserProperties->getProperty($key); + $m->setDefinedProperty($key, $property); + } + } + + try { + $m->runBuild(); + } catch(Exception $exc) { + self::halt(1); // Errors occured + } + + // everything fine, shutdown + self::halt(0); // no errors, everything is cake + } + + /** + * Making output level a static property so that this property + * can be accessed by other parts of the system, enabling + * us to display more information -- e.g. backtraces -- for "debug" level. + * @return int + */ + public static function getMsgOutputLevel() { + return self::$msgOutputLevel; + } + + /** + * Command line entry point. This method kicks off the building + * of a project object and executes a build using either a given + * target or the default target. + * + * @param array $args Command line args. + * @return void + */ + public static function fire($args) { + self::start($args, null); + } + + /** + * Setup/initialize Phing environment from commandline args. + * @param array $args commandline args passed to phing shell. + * @return void + */ + public function execute($args) { + + self::$definedProps = new Properties(); + $this->searchForThis = null; + + // cycle through given args + for ($i = 0, $argcount = count($args); $i < $argcount; ++$i) { + // ++$i intentional here, as first param is script name + $arg = $args[$i]; + + if ($arg == "-help" || $arg == "-h") { + $this->printUsage(); + return; + } elseif ($arg == "-version" || $arg == "-v") { + $this->printVersion(); + return; + } elseif ($arg == "-quiet" || $arg == "-q") { + self::$msgOutputLevel = PROJECT_MSG_WARN; + } elseif ($arg == "-verbose") { + $this->printVersion(); + self::$msgOutputLevel = PROJECT_MSG_VERBOSE; + } elseif ($arg == "-debug") { + $this->printVersion(); + self::$msgOutputLevel = PROJECT_MSG_DEBUG; + } elseif ($arg == "-logfile") { + try { // try to set logfile + if (!isset($args[$i+1])) { + print("You must specify a log file when using the -logfile argument\n"); + return; + } else { + $logFile = new PhingFile($args[++$i]); + $this->loggerClassname = 'phing.listener.PearLogger'; + $this->setDefinedProperty('pear.log.name', $logFile->getAbsolutePath()); + } + } catch (IOException $ioe) { + print("Cannot write to the specified log file. Make sure the path exists and you have write permissions.\n"); + throw $ioe; + } + } elseif ($arg == "-buildfile" || $arg == "-file" || $arg == "-f") { + if (!isset($args[$i+1])) { + print("You must specify a buildfile when using the -buildfile argument\n"); + return; + } else { + $this->buildFile = new PhingFile($args[++$i]); + } + } elseif ($arg == "-listener") { + if (!isset($args[$i+1])) { + print("You must specify a listener class when using the -listener argument\n"); + return; + } else { + $this->listeners[] = $args[++$i]; + } + + } elseif (StringHelper::startsWith("-D", $arg)) { + $name = substr($arg, 2); + $value = null; + $posEq = strpos($name, "="); + if ($posEq !== false) { + $value = substr($name, $posEq+1); + $name = substr($name, 0, $posEq); + } elseif ($i < count($args)-1) { + $value = $args[++$i]; + } + self::$definedProps->setProperty($name, $value); + } elseif ($arg == "-logger") { + if (!isset($args[$i+1])) { + print("You must specify a classname when using the -logger argument\n"); + return; + } else { + $this->loggerClassname = $args[++$i]; + } + } elseif ($arg == "-inputhandler") { + if ($this->inputHandlerClassname !== null) { + throw new BuildException("Only one input handler class may be specified."); + } + if (!isset($args[$i+1])) { + print("You must specify a classname when using the -inputhandler argument\n"); + return; + } else { + $this->inputHandlerClassname = $args[++$i]; + } + } elseif ($arg == "-projecthelp" || $arg == "-targets" || $arg == "-list" || $arg == "-l") { + // set the flag to display the targets and quit + $this->projectHelp = true; + } elseif ($arg == "-find") { + // eat up next arg if present, default to build.xml + if ($i < count($args)-1) { + $this->searchForThis = $args[++$i]; + } else { + $this->searchForThis = self::DEFAULT_BUILD_FILENAME; + } + } elseif (substr($arg,0,1) == "-") { + // we don't have any more args + print("Unknown argument: $arg\n"); + $this->printUsage(); + return; + } else { + // if it's no other arg, it may be the target + array_push($this->targets, $arg); + } + } + + // if buildFile was not specified on the command line, + if ($this->buildFile === null) { + // but -find then search for it + if ($this->searchForThis !== null) { + $this->buildFile = $this->_findBuildFile(self::getProperty("user.dir"), $this->searchForThis); + } else { + $this->buildFile = new PhingFile(self::DEFAULT_BUILD_FILENAME); + } + } + // make sure buildfile exists + if (!$this->buildFile->exists()) { + throw new BuildException("Buildfile: " . $this->buildFile->__toString() . " does not exist!"); + } + + // make sure it's not a directory + if ($this->buildFile->isDirectory()) { + throw new BuildException("Buildfile: " . $this->buildFile->__toString() . " is a dir!"); + } + + $this->readyToRun = true; + } + + /** + * Helper to get the parent file for a given file. + * + * @param PhingFile $file + * @return PhingFile Parent file or null if none + */ + function _getParentFile(PhingFile $file) { + $filename = $file->getAbsolutePath(); + $file = new PhingFile($filename); + $filename = $file->getParent(); + + if ($filename !== null && self::$msgOutputLevel >= PROJECT_MSG_VERBOSE) { + print("Searching in $filename\n"); + } + + return ($filename === null) ? null : new PhingFile($filename); + } + + /** + * Search parent directories for the build file. + * + * Takes the given target as a suffix to append to each + * parent directory in search of a build file. Once the + * root of the file-system has been reached an exception + * is thrown. + * + * @param string $start Start file path. + * @param string $suffix Suffix filename to look for in parents. + * @return PhingFile A handle to the build file + * + * @throws BuildException Failed to locate a build file + */ + function _findBuildFile($start, $suffix) { + if (self::$msgOutputLevel >= PROJECT_MSG_INFO) { + print("Searching for $suffix ...\n"); + } + $startf = new PhingFile($start); + $parent = new PhingFile($startf->getAbsolutePath()); + $file = new PhingFile($parent, $suffix); + + // check if the target file exists in the current directory + while (!$file->exists()) { + // change to parent directory + $parent = $this->_getParentFile($parent); + + // if parent is null, then we are at the root of the fs, + // complain that we can't find the build file. + if ($parent === null) { + throw new BuildException("Could not locate a build file!"); + } + // refresh our file handle + $file = new PhingFile($parent, $suffix); + } + return $file; + } + + /** + * Executes the build. + * @return void + */ + function runBuild() { + + if (!$this->readyToRun) { + return; + } + + $project = new Project(); + + self::setCurrentProject($project); + set_error_handler(array('Phing', 'handlePhpError')); + + $error = null; + + $this->addBuildListeners($project); + $this->addInputHandler($project); + + // set this right away, so that it can be used in logging. + $project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath()); + + try { + $project->fireBuildStarted(); + $project->init(); + } catch (Exception $exc) { + $project->fireBuildFinished($exc); + throw $exc; + } + + $project->setUserProperty("phing.version", $this->getPhingVersion()); + + $e = self::$definedProps->keys(); + while (count($e)) { + $arg = (string) array_shift($e); + $value = (string) self::$definedProps->getProperty($arg); + $project->setUserProperty($arg, $value); + } + unset($e); + + $project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath()); + + // first use the Configurator to create the project object + // from the given build file. + + try { + ProjectConfigurator::configureProject($project, $this->buildFile); + } catch (Exception $exc) { + $project->fireBuildFinished($exc); + restore_error_handler(); + self::unsetCurrentProject(); + throw $exc; + } + + // make sure that we have a target to execute + if (count($this->targets) === 0) { + $this->targets[] = $project->getDefaultTarget(); + } + + // execute targets if help param was not given + if (!$this->projectHelp) { + + try { + $project->executeTargets($this->targets); + } catch (Exception $exc) { + $project->fireBuildFinished($exc); + restore_error_handler(); + self::unsetCurrentProject(); + throw $exc; + } + } + // if help is requested print it + if ($this->projectHelp) { + try { + $this->printDescription($project); + $this->printTargets($project); + } catch (Exception $exc) { + $project->fireBuildFinished($exc); + restore_error_handler(); + self::unsetCurrentProject(); + throw $exc; + } + } + + // finally { + if (!$this->projectHelp) { + $project->fireBuildFinished(null); + } + + restore_error_handler(); + self::unsetCurrentProject(); + } + + /** + * Bind any default build listeners to this project. + * Currently this means adding the logger. + * @param Project $project + * @return void + */ + private function addBuildListeners(Project $project) { + // Add the default listener + $project->addBuildListener($this->createLogger()); + } + + /** + * Creates the InputHandler and adds it to the project. + * + * @param Project $project the project instance. + * + * @throws BuildException if a specified InputHandler + * class could not be loaded. + */ + private function addInputHandler(Project $project) { + if ($this->inputHandlerClassname === null) { + $handler = new DefaultInputHandler(); + } else { + try { + $clz = Phing::import($this->inputHandlerClassname); + $handler = new $clz(); + if ($project !== null && method_exists($handler, 'setProject')) { + $handler->setProject($project); + } + } catch (Exception $e) { + $msg = "Unable to instantiate specified input handler " + . "class " . $this->inputHandlerClassname . " : " + . $e->getMessage(); + throw new BuildException($msg); + } + } + $project->setInputHandler($handler); + } + + /** + * Creates the default build logger for sending build events to the log. + * @return BuildListener The created Logger + */ + private function createLogger() { + if ($this->loggerClassname !== null) { + self::import($this->loggerClassname); + // get class name part + $classname = self::import($this->loggerClassname); + $logger = new $classname; + } else { + require_once 'phing/listener/DefaultLogger.php'; + $logger = new DefaultLogger(); + } + $logger->setMessageOutputLevel(self::$msgOutputLevel); + return $logger; + } + + /** + * Sets the current Project + * @param Project $p + */ + public static function setCurrentProject($p) { + self::$currentProject = $p; + } + + /** + * Unsets the current Project + */ + public static function unsetCurrentProject() { + self::$currentProject = null; + } + + /** + * Gets the current Project. + * @return Project Current Project or NULL if none is set yet/still. + */ + public static function getCurrentProject() { + return self::$currentProject; + } + + /** + * A static convenience method to send a log to the current (last-setup) Project. + * If there is no currently-configured Project, then this will do nothing. + * @param string $message + * @param int $priority PROJECT_MSG_INFO, etc. + */ + public static function log($message, $priority = PROJECT_MSG_INFO) { + $p = self::getCurrentProject(); + if ($p) { + $p->log($message, $priority); + } + } + + /** + * Error handler for PHP errors encountered during the build. + * This uses the logging for the currently configured project. + */ + public static function handlePhpError($level, $message, $file, $line) { + + // don't want to print supressed errors + if (error_reporting() > 0) { + + if (self::$phpErrorCapture) { + + self::$capturedPhpErrors[] = array('message' => $message, 'level' => $level, 'line' => $line, 'file' => $file); + + } else { + + $message = '[PHP Error] ' . $message; + $message .= ' [line ' . $line . ' of ' . $file . ']'; + + switch ($level) { + + case E_STRICT: + case E_NOTICE: + case E_USER_NOTICE: + self::log($message, PROJECT_MSG_VERBOSE); + break; + case E_WARNING: + case E_USER_WARNING: + self::log($message, PROJECT_MSG_WARN); + break; + case E_ERROR: + case E_USER_ERROR: + default: + self::log($message, PROJECT_MSG_ERR); + + } // switch + + } // if phpErrorCapture + + } // if not @ + + } + + /** + * Begins capturing PHP errors to a buffer. + * While errors are being captured, they are not logged. + */ + public static function startPhpErrorCapture() { + self::$phpErrorCapture = true; + self::$capturedPhpErrors = array(); + } + + /** + * Stops capturing PHP errors to a buffer. + * The errors will once again be logged after calling this method. + */ + public static function stopPhpErrorCapture() { + self::$phpErrorCapture = false; + } + + /** + * Clears the captured errors without affecting the starting/stopping of the capture. + */ + public static function clearCapturedPhpErrors() { + self::$capturedPhpErrors = array(); + } + + /** + * Gets any PHP errors that were captured to buffer. + * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level) + */ + public static function getCapturedPhpErrors() { + return self::$capturedPhpErrors; + } + + /** Prints the usage of how to use this class */ + function printUsage() { + $lSep = self::getProperty("line.separator"); + $msg = ""; + $msg .= "phing [options] [target [target2 [target3] ...]]" . $lSep; + $msg .= "Options: " . $lSep; + $msg .= " -h -help print this message" . $lSep; + $msg .= " -l -list list available targets in this project" . $lSep; + $msg .= " -v -version print the version information and exit" . $lSep; + $msg .= " -q -quiet be extra quiet" . $lSep; + $msg .= " -verbose be extra verbose" . $lSep; + $msg .= " -debug print debugging information" . $lSep; + $msg .= " -logfile use given file for log" . $lSep; + $msg .= " -logger the class which is to perform logging" . $lSep; + $msg .= " -f -buildfile use given buildfile" . $lSep; + $msg .= " -D= use value for given property" . $lSep; + $msg .= " -find search for buildfile towards the root of the" . $lSep; + $msg .= " filesystem and use it" . $lSep; + //$msg .= " -recursive search for buildfile downwards and use it" . $lSep; + $msg .= $lSep; + $msg .= "Report bugs to ".$lSep; + print($msg); + } + + function printVersion() { + print(self::getPhingVersion()."\n"); + } + + function getPhingVersion() { + $versionPath = self::getResourcePath("phing/etc/VERSION.TXT"); + if ($versionPath === null) { + $versionPath = self::getResourcePath("etc/VERSION.TXT"); + } + try { // try to read file + $buffer = null; + $file = new PhingFile($versionPath); + $reader = new FileReader($file); + $reader->readInto($buffer); + $buffer = trim($buffer); + //$buffer = "PHING version 1.0, Released 2002-??-??"; + $phingVersion = $buffer; + } catch (IOException $iox) { + print("Can't read version information file\n"); + throw new BuildException("Build failed"); + } + return $phingVersion; + } + + /** Print the project description, if any */ + function printDescription(Project $project) { + if ($project->getDescription() !== null) { + print($project->getDescription()."\n"); + } + } + + /** Print out a list of all targets in the current buildfile */ + function printTargets($project) { + // find the target with the longest name + $maxLength = 0; + $targets = $project->getTargets(); + $targetNames = array_keys($targets); + $targetName = null; + $targetDescription = null; + $currentTarget = null; + + // split the targets in top-level and sub-targets depending + // on the presence of a description + + $subNames = array(); + $topNameDescMap = array(); + + foreach($targets as $currentTarget) { + $targetName = $currentTarget->getName(); + $targetDescription = $currentTarget->getDescription(); + + // subtargets are targets w/o descriptions + if ($targetDescription === null) { + $subNames[] = $targetName; + } else { + // topNames and topDescriptions are handled later + // here we store in hash map (for sorting purposes) + $topNameDescMap[$targetName] = $targetDescription; + if (strlen($targetName) > $maxLength) { + $maxLength = strlen($targetName); + } + } + } + + // Sort the arrays + sort($subNames); // sort array values, resetting keys (which are numeric) + ksort($topNameDescMap); // sort the keys (targetName) keeping key=>val associations + + $topNames = array_keys($topNameDescMap); + $topDescriptions = array_values($topNameDescMap); + + $defaultTarget = $project->getDefaultTarget(); + + if ($defaultTarget !== null && $defaultTarget !== "") { + $defaultName = array(); + $defaultDesc = array(); + $defaultName[] = $defaultTarget; + + $indexOfDefDesc = array_search($defaultTarget, $topNames, true); + if ($indexOfDefDesc !== false && $indexOfDefDesc >= 0) { + $defaultDesc = array(); + $defaultDesc[] = $topDescriptions[$indexOfDefDesc]; + } + + $this->_printTargets($defaultName, $defaultDesc, "Default target:", $maxLength); + + } + $this->_printTargets($topNames, $topDescriptions, "Main targets:", $maxLength); + $this->_printTargets($subNames, null, "Subtargets:", 0); + } + + /** + * Writes a formatted list of target names with an optional description. + * + * @param array $names The names to be printed. + * Must not be null. + * @param array $descriptions The associated target descriptions. + * May be null, in which case + * no descriptions are displayed. + * If non-null, this should have + * as many elements as names. + * @param string $heading The heading to display. + * Should not be null. + * @param int $maxlen The maximum length of the names of the targets. + * If descriptions are given, they are padded to this + * position so they line up (so long as the names really + * are shorter than this). + */ + private function _printTargets($names, $descriptions, $heading, $maxlen) { + $lSep = self::getProperty("line.separator"); + $spaces = ' '; + while (strlen($spaces) < $maxlen) { + $spaces .= $spaces; + } + $msg = ""; + $msg .= $heading . $lSep; + $msg .= str_repeat("-",79) . $lSep; + + $total = count($names); + for($i=0; $i < $total; $i++) { + $msg .= " "; + $msg .= $names[$i]; + if (!empty($descriptions)) { + $msg .= substr($spaces, 0, $maxlen - strlen($names[$i]) + 2); + $msg .= $descriptions[$i]; + } + $msg .= $lSep; + } + if ($total > 0) { + print $msg . $lSep; + } + } + + /** + * Import a dot-path notation class path. + * @param string $dotPath + * @param mixed $classpath String or object supporting __toString() + * @return string The unqualified classname (which can be instantiated). + * @throws BuildException - if cannot find the specified file + */ + public static function import($dotPath, $classpath = null) { + + // first check to see that the class specified hasn't already been included. + // (this also handles case where this method is called w/ a classname rather than dotpath) + $classname = StringHelper::unqualify($dotPath); + if (class_exists($classname, false)) { + return $classname; + } + + $dotClassname = basename($dotPath); + $dotClassnamePos = strlen($dotPath) - strlen($dotClassname); + $classFile = strtr($dotClassname, '.', DIRECTORY_SEPARATOR) . ".php"; + $path = substr_replace($dotPath, $classFile, $dotClassnamePos); + + Phing::__import($path, $classpath); + + return $classname; + } + + /** + * Import a PHP file + * @param string $path Path to the PHP file + * @param mixed $classpath String or object supporting __toString() + * @throws BuildException - if cannot find the specified file + */ + public static function __import($path, $classpath = null) { + + if ($classpath) { + + // Apparently casting to (string) no longer invokes __toString() automatically. + if (is_object($classpath)) { + $classpath = $classpath->__toString(); + } + + // classpaths are currently additive, but we also don't want to just + // indiscriminantly prepand/append stuff to the include_path. This means + // we need to parse current incldue_path, and prepend any + // specified classpath locations that are not already in the include_path. + // + // NOTE: the reason why we do it this way instead of just changing include_path + // and then changing it back, is that in many cases applications (e.g. Propel) will + // include/require class files from within method calls. This means that not all + // necessary files will be included in this import() call, and hence we can't + // change the include_path back without breaking those apps. While this method could + // be more expensive than switching & switching back (not sure, but maybe), it makes it + // possible to write far less expensive run-time applications (e.g. using Propel), which is + // really where speed matters more. + + $curr_parts = explode(PATH_SEPARATOR, ini_get('include_path')); + $add_parts = explode(PATH_SEPARATOR, $classpath); + $new_parts = array_diff($add_parts, $curr_parts); + if ($new_parts) { + if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { + print("Phing::import() prepending new include_path components: " . implode(PATH_SEPARATOR, $new_parts) . "\n"); + } + ini_set('include_path', implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts))); + } + } + + $ret = include_once($path); + + if ($ret === false) { + $e = new BuildException("Error importing $path"); + if (self::getMsgOutputLevel() === PROJECT_MSG_DEBUG) { + // We can't log this because listeners belong + // to projects. We'll just print it -- of course + // that isn't very compatible w/ other frontends (but + // there aren't any right now, so I'm not stressing) + print("Error importing $path\n"); + print($e->getTraceAsString()."\n"); + } + throw $e; + } + + return; + } + + /** + * Looks on include path for specified file. + * @return string File found (null if no file found). + */ + public static function getResourcePath($path) { + + if (self::$importPaths === null) { + $paths = ini_get("include_path"); + self::$importPaths = explode(PATH_SEPARATOR, ini_get("include_path")); + } + + $path = str_replace('\\', DIRECTORY_SEPARATOR, $path); + $path = str_replace('/', DIRECTORY_SEPARATOR, $path); + + foreach (self::$importPaths as $prefix) { + $foo_path = $prefix . DIRECTORY_SEPARATOR . $path; + if (file_exists($foo_path)) { + return $foo_path; + } + } + + // Check for the property phing.home + $home_dir = self::getProperty('phing.home'); + + if ($home_dir) + { + $home_path = $home_dir . DIRECTORY_SEPARATOR . $path; + + if (file_exists($home_path)) + { + return $home_path; + } + } + + // If we are using this via PEAR then check for the file in the data dir + // This is a bit of a hack, but works better than previous solution of assuming + // data_dir is on the include_path. + $data_dir = '@DATA-DIR@'; + if ($data_dir{0} != '@') { // if we're using PEAR then the @ DATA-DIR @ token will have been substituted. + $data_path = $data_dir . DIRECTORY_SEPARATOR . $path; + if (file_exists($data_path)) { + return $data_path; + } + } + + return null; + } + + // ------------------------------------------------------------------------------------------- + // System-wide methods (moved from System class, which had namespace conflicts w/ PEAR System) + // ------------------------------------------------------------------------------------------- + + /** + * Set System constants which can be retrieved by calling Phing::getProperty($propName). + * @return void + */ + private static function setSystemConstants() { + + /* + * PHP_OS returns on + * WindowsNT4.0sp6 => WINNT + * Windows2000 => WINNT + * Windows ME => WIN32 + * Windows 98SE => WIN32 + * FreeBSD 4.5p7 => FreeBSD + * Redhat Linux => Linux + * Mac OS X => Darwin + */ + self::setProperty('host.os', PHP_OS); + + // this is used by some tasks too + self::setProperty('os.name', PHP_OS); + + // it's still possible this won't be defined, + // e.g. if Phing is being included in another app w/o + // using the phing.php script. + if (!defined('PHP_CLASSPATH')) { + define('PHP_CLASSPATH', get_include_path()); + } + + self::setProperty('php.classpath', PHP_CLASSPATH); + + // try to determine the host filesystem and set system property + // used by Fileself::getFileSystem to instantiate the correct + // abstraction layer + + switch (strtoupper(PHP_OS)) { + case 'WINNT': + self::setProperty('host.fstype', 'WINNT'); + break; + case 'WIN32': + self::setProperty('host.fstype', 'WIN32'); + break; + default: + self::setProperty('host.fstype', 'UNIX'); + break; + } + + self::setProperty('php.version', PHP_VERSION); + self::setProperty('user.home', getenv('HOME')); + self::setProperty('application.startdir', getcwd()); + self::setProperty('line.separator', "\n"); + + // try to detect machine dependent information + $sysInfo = array(); + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && function_exists("posix_uname")) { + $sysInfo = posix_uname(); + } else { + $sysInfo['nodename'] = php_uname('n'); + $sysInfo['machine']= php_uname('m') ; + //this is a not so ideal substition, but maybe better than nothing + $sysInfo['domain'] = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : "unknown"; + $sysInfo['release'] = php_uname('r'); + $sysInfo['version'] = php_uname('v'); + } + + + self::setProperty("host.name", isset($sysInfo['nodename']) ? $sysInfo['nodename'] : "unknown"); + self::setProperty("host.arch", isset($sysInfo['machine']) ? $sysInfo['machine'] : "unknown"); + self::setProperty("host.domain",isset($sysInfo['domain']) ? $sysInfo['domain'] : "unknown"); + self::setProperty("host.os.release", isset($sysInfo['release']) ? $sysInfo['release'] : "unknown"); + self::setProperty("host.os.version", isset($sysInfo['version']) ? $sysInfo['version'] : "unknown"); + unset($sysInfo); + } + + /** + * This gets a property that was set via command line or otherwise passed into Phing. + * "Defined" in this case means "externally defined". The reason this method exists is to + * provide a public means of accessing commandline properties for (e.g.) logger or listener + * scripts. E.g. to specify which logfile to use, PearLogger needs to be able to access + * the pear.log.name property. + * + * @param string $name + * @return string value of found property (or null, if none found). + */ + public static function getDefinedProperty($name) { + return self::$definedProps->getProperty($name); + } + + /** + * This sets a property that was set via command line or otherwise passed into Phing. + * + * @param string $name + * @return string value of found property (or null, if none found). + */ + public static function setDefinedProperty($name, $value) { + return self::$definedProps->setProperty($name, $value); + } + + /** + * Returns property value for a System property. + * System properties are "global" properties like line.separator, + * and user.dir. Many of these correspond to similar properties in Java + * or Ant. + * + * @param string $paramName + * @return string Value of found property (or null, if none found). + */ + public static function getProperty($propName) { + + // some properties are detemined on each access + // some are cached, see below + + // default is the cached value: + $val = isset(self::$properties[$propName]) ? self::$properties[$propName] : null; + + // special exceptions + switch($propName) { + case 'user.dir': + $val = getcwd(); + break; + } + + return $val; + } + + /** Retuns reference to all properties*/ + public static function &getProperties() { + return self::$properties; + } + + public static function setProperty($propName, $propValue) { + $propName = (string) $propName; + $oldValue = self::getProperty($propName); + self::$properties[$propName] = $propValue; + return $oldValue; + } + + public static function currentTimeMillis() { + list($usec, $sec) = explode(" ",microtime()); + return ((float)$usec + (float)$sec); + } + + /** + * Sets the include path based on PHP_CLASSPATH constant (set in phing.php). + * @return void + */ + private static function setIncludePaths() { + $success = false; + + if (defined('PHP_CLASSPATH')) { + $success = ini_set('include_path', PHP_CLASSPATH); + } else { + // don't do anything, just assume that include_path has been properly set. + $success = true; + } + + if ($success === false) { + print("SYSTEM FAILURE: Could not set PHP include path\n"); + self::halt(-1); + } + } + + /** + * Sets PHP INI values that Phing needs. + * @return void + */ + private static function setIni() { + error_reporting(E_ALL); + set_time_limit(0); + ini_set('magic_quotes_gpc', 'off'); + ini_set('short_open_tag', 'off'); + ini_set('default_charset', 'iso-8859-1'); + ini_set('register_globals', 'off'); + ini_set('allow_call_time_pass_reference', 'on'); + + // should return memory limit in MB + $mem_limit = (int) ini_get('memory_limit'); + if ($mem_limit < 32) { + ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects + } + } + + /** + * Returns reference to Timer object. + * @return Timer + */ + public static function getTimer() { + if (self::$timer === null) { + include_once 'phing/system/util/Timer.php'; + self::$timer= new Timer(); + } + return self::$timer; + } + + /** + * Start up Phing. + * Sets up the Phing environment -- does NOT initiate the build process. + * @return void + */ + public static function startup() { + + register_shutdown_function(array('Phing', 'shutdown')); + + // some init stuff + self::getTimer()->start(); + + self::setSystemConstants(); + self::setIncludePaths(); + self::setIni(); + } + + /** + * Halts the system. + * @see shutdown() + */ + public static function halt($code=0) { + self::shutdown($code); + } + + /** + * Stops timers & exits. + * @return void + */ + public static function shutdown($exitcode = 0) { + //print("[AUTOMATIC SYSTEM SHUTDOWN]\n"); + self::getTimer()->stop(); + exit($exitcode); // final point where everything stops + } + +} diff --git a/gulliver/thirdparty/phing/Project.php b/gulliver/thirdparty/phing/Project.php new file mode 100644 index 000000000..947c7be0e --- /dev/null +++ b/gulliver/thirdparty/phing/Project.php @@ -0,0 +1,966 @@ +. + */ + +define('PROJECT_MSG_DEBUG', 4); +define('PROJECT_MSG_VERBOSE', 3); +define('PROJECT_MSG_INFO', 2); +define('PROJECT_MSG_WARN', 1); +define('PROJECT_MSG_ERR', 0); + +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/util/FileUtils.php'; +include_once 'phing/TaskAdapter.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/BuildEvent.php'; +include_once 'phing/input/DefaultInputHandler.php'; + +/** + * The Phing project class. Represents a completely configured Phing project. + * The class defines the project and all tasks/targets. It also contains + * methods to start a build as well as some properties and FileSystem + * abstraction. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.29 $ + * @package phing + */ +class Project { + + /** contains the targets */ + private $targets = array(); + /** global filterset (future use) */ + private $globalFilterSet = array(); + /** all globals filters (future use) */ + private $globalFilters = array(); + + /** Project properties map (usually String to String). */ + private $properties = array(); + + /** + * Map of "user" properties (as created in the Ant task, for example). + * Note that these key/value pairs are also always put into the + * project properties, so only the project properties need to be queried. + * Mapping is String to String. + */ + private $userProperties = array(); + + /** + * Map of inherited "user" properties - that are those "user" + * properties that have been created by tasks and not been set + * from the command line or a GUI tool. + * Mapping is String to String. + */ + private $inheritedProperties = array(); + + /** task definitions for this project*/ + private $taskdefs = array(); + + /** type definitions for this project */ + private $typedefs = array(); + + /** holds ref names and a reference to the referred object*/ + private $references = array(); + + /** The InputHandler being used by this project. */ + private $inputHandler; + + /* -- properties that come in via xml attributes -- */ + + /** basedir (PhingFile object) */ + private $basedir; + + /** the default target name */ + private $defaultTarget = 'all'; + + /** project name (required) */ + private $name; + + /** project description */ + private $description; + + /** a FileUtils object */ + private $fileUtils; + + /** Build listeneers */ + private $listeners = array(); + + /** + * Constructor, sets any default vars. + */ + function __construct() { + $this->fileUtils = new FileUtils(); + $this->inputHandler = new DefaultInputHandler(); + } + + /** + * Sets the input handler + */ + public function setInputHandler(InputHandler $handler) { + $this->inputHandler = $handler; + } + + /** + * Retrieves the current input handler. + */ + public function getInputHandler() { + return $this->inputHandler; + } + + /** inits the project, called from main app */ + function init() { + // set builtin properties + $this->setSystemProperties(); + + // load default tasks + $taskdefs = Phing::getResourcePath("phing/tasks/defaults.properties"); + + try { // try to load taskdefs + $props = new Properties(); + $in = new PhingFile((string)$taskdefs); + + if ($in === null) { + throw new BuildException("Can't load default task list"); + } + $props->load($in); + + $enum = $props->propertyNames(); + foreach($enum as $key) { + $value = $props->getProperty($key); + $this->addTaskDefinition($key, $value); + } + } catch (IOException $ioe) { + throw new BuildException("Can't load default task list"); + } + + // load default tasks + $typedefs = Phing::getResourcePath("phing/types/defaults.properties"); + + try { // try to load typedefs + $props = new Properties(); + $in = new PhingFile((string)$typedefs); + if ($in === null) { + throw new BuildException("Can't load default datatype list"); + } + $props->load($in); + + $enum = $props->propertyNames(); + foreach($enum as $key) { + $value = $props->getProperty($key); + $this->addDataTypeDefinition($key, $value); + } + } catch(IOException $ioe) { + throw new BuildException("Can't load default datatype list"); + } + } + + /** returns the global filterset (future use) */ + function getGlobalFilterSet() { + return $this->globalFilterSet; + } + + // --------------------------------------------------------- + // Property methods + // --------------------------------------------------------- + + /** + * Sets a property. Any existing property of the same name + * is overwritten, unless it is a user property. + * @param string $name The name of property to set. + * Must not be null. + * @param string $value The new value of the property. + * Must not be null. + * @return void + */ + public function setProperty($name, $value) { + + // command line properties take precedence + if (isset($this->userProperties[$name])) { + $this->log("Override ignored for user property " . $name, PROJECT_MSG_VERBOSE); + return; + } + + if (isset($this->properties[$name])) { + $this->log("Overriding previous definition of property " . $name, PROJECT_MSG_VERBOSE); + } + + $this->log("Setting project property: " . $name . " -> " . $value, PROJECT_MSG_DEBUG); + $this->properties[$name] = $value; + } + + /** + * Sets a property if no value currently exists. If the property + * exists already, a message is logged and the method returns with + * no other effect. + * + * @param string $name The name of property to set. + * Must not be null. + * @param string $value The new value of the property. + * Must not be null. + * @since 2.0 + */ + public function setNewProperty($name, $value) { + if (isset($this->properties[$name])) { + $this->log("Override ignored for property " . $name, PROJECT_MSG_DEBUG); + return; + } + $this->log("Setting project property: " . $name . " -> " . $value, PROJECT_MSG_DEBUG); + $this->properties[$name] = $value; + } + + /** + * Sets a user property, which cannot be overwritten by + * set/unset property calls. Any previous value is overwritten. + * @param string $name The name of property to set. + * Must not be null. + * @param string $value The new value of the property. + * Must not be null. + * @see #setProperty() + */ + public function setUserProperty($name, $value) { + $this->log("Setting ro project property: " . $name . " -> " . $value, PROJECT_MSG_DEBUG); + $this->userProperties[$name] = $value; + $this->properties[$name] = $value; + } + + /** + * Sets a user property, which cannot be overwritten by set/unset + * property calls. Any previous value is overwritten. Also marks + * these properties as properties that have not come from the + * command line. + * + * @param string $name The name of property to set. + * Must not be null. + * @param string $value The new value of the property. + * Must not be null. + * @see #setProperty() + */ + public function setInheritedProperty($name, $value) { + $this->inheritedProperties[$name] = $value; + $this->setUserProperty($name, $value); + } + + /** + * Sets a property unless it is already defined as a user property + * (in which case the method returns silently). + * + * @param name The name of the property. + * Must not be null. + * @param value The property value. Must not be null. + */ + private function setPropertyInternal($name, $value) { + if (isset($this->userProperties[$name])) { + $this->log("Override ignored for user property " . $name, PROJECT_MSG_VERBOSE); + return; + } + $this->properties[$name] = $value; + } + + /** + * Returns the value of a property, if it is set. + * + * @param string $name The name of the property. + * May be null, in which case + * the return value is also null. + * @return string The property value, or null for no match + * or if a null name is provided. + */ + public function getProperty($name) { + if (!isset($this->properties[$name])) { + return null; + } + return $this->properties[$name]; + } + + /** + * Replaces ${} style constructions in the given value with the + * string value of the corresponding data types. + * + * @param value The string to be scanned for property references. + * May be null. + * + * @return the given string with embedded property names replaced + * by values, or null if the given string is + * null. + * + * @exception BuildException if the given value has an unclosed + * property name, e.g. ${xxx + */ + public function replaceProperties($value) { + return ProjectConfigurator::replaceProperties($this, $value, $this->properties); + } + + /** + * Returns the value of a user property, if it is set. + * + * @param string $name The name of the property. + * May be null, in which case + * the return value is also null. + * @return string The property value, or null for no match + * or if a null name is provided. + */ + public function getUserProperty($name) { + if (!isset($this->userProperties[$name])) { + return null; + } + return $this->userProperties[$name]; + } + + /** + * Returns a copy of the properties table. + * @return array A hashtable containing all properties + * (including user properties). + */ + public function getProperties() { + return $this->properties; + } + + /** + * Returns a copy of the user property hashtable + * @return a hashtable containing just the user properties + */ + public function getUserProperties() { + return $this->userProperties; + } + + /** + * Copies all user properties that have been set on the command + * line or a GUI tool from this instance to the Project instance + * given as the argument. + * + *

    To copy all "user" properties, you will also have to call + * {@link #copyInheritedProperties copyInheritedProperties}.

    + * + * @param Project $other the project to copy the properties to. Must not be null. + * @return void + * @since phing 2.0 + */ + public function copyUserProperties(Project $other) { + foreach($this->userProperties as $arg => $value) { + if (isset($this->inheritedProperties[$arg])) { + continue; + } + $other->setUserProperty($arg, $value); + } + } + + /** + * Copies all user properties that have not been set on the + * command line or a GUI tool from this instance to the Project + * instance given as the argument. + * + *

    To copy all "user" properties, you will also have to call + * {@link #copyUserProperties copyUserProperties}.

    + * + * @param other the project to copy the properties to. Must not be null. + * + * @since phing 2.0 + */ + public function copyInheritedProperties(Project $other) { + foreach($this->userProperties as $arg => $value) { + if ($other->getUserProperty($arg) !== null) { + continue; + } + $other->setInheritedProperty($arg, $value); + } + } + + // --------------------------------------------------------- + // END Properties methods + // --------------------------------------------------------- + + + function setDefaultTarget($targetName) { + $this->defaultTarget = (string) trim($targetName); + } + + function getDefaultTarget() { + return (string) $this->defaultTarget; + } + + /** + * Sets the name of the current project + * + * @param string name of project + * @return void + * @access public + * @author Andreas Aderhold, andi@binarycloud.com + */ + + function setName($name) { + $this->name = (string) trim($name); + $this->setProperty("phing.project.name", $this->name); + } + + /** + * Returns the name of this project + * + * @returns string projectname + * @access public + * @author Andreas Aderhold, andi@binarycloud.com + */ + function getName() { + return (string) $this->name; + } + + /** Set the projects description */ + function setDescription($description) { + $this->description = (string) trim($description); + } + + /** return the description, null otherwise */ + function getDescription() { + return $this->description; + } + + /** Set basedir object from xml*/ + function setBasedir($dir) { + if ($dir instanceof PhingFile) { + $dir = $dir->getAbsolutePath(); + } + + $dir = $this->fileUtils->normalize($dir); + + $dir = new PhingFile((string) $dir); + if (!$dir->exists()) { + throw new BuildException("Basedir ".$dir->getAbsolutePath()." does not exist"); + } + if (!$dir->isDirectory()) { + throw new BuildException("Basedir ".$dir->getAbsolutePath()." is not a directory"); + } + $this->basedir = $dir; + $this->setPropertyInternal("project.basedir", $this->basedir->getAbsolutePath()); + $this->log("Project base dir set to: " . $this->basedir->getPath(), PROJECT_MSG_VERBOSE); + + // [HL] added this so that ./ files resolve correctly. This may be a mistake ... or may be in wrong place. + chdir($dir->getAbsolutePath()); + } + + /** + * Returns the basedir of this project + * + * @returns PhingFile Basedir PhingFile object + * @access public + * @throws BuildException + * @author Andreas Aderhold, andi@binarycloud.com + */ + function getBasedir() { + if ($this->basedir === null) { + try { // try to set it + $this->setBasedir("."); + } catch (BuildException $exc) { + throw new BuildException("Can not set default basedir. ".$exc->getMessage()); + } + } + return $this->basedir; + } + + /** + * Sets system properties and the environment variables for this project. + * + * @return void + */ + function setSystemProperties() { + + // first get system properties + $systemP = array_merge( self::getProperties(), Phing::getProperties() ); + foreach($systemP as $name => $value) { + $this->setPropertyInternal($name, $value); + } + + // and now the env vars + foreach($_SERVER as $name => $value) { + // skip arrays + if (is_array($value)) { + continue; + } + $this->setPropertyInternal('env.' . $name, $value); + } + return true; + } + + + /** + * Adds a task definition. + * @param string $name Name of tag. + * @param string $class The class path to use. + * @param string $classpath The classpat to use. + */ + function addTaskDefinition($name, $class, $classpath = null) { + $name = $name; + $class = $class; + if ($class === "") { + $this->log("Task $name has no class defined.", PROJECT_MSG_ERR); + } elseif (!isset($this->taskdefs[$name])) { + Phing::import($class, $classpath); + $this->taskdefs[$name] = $class; + $this->log(" +Task definiton: $name ($class)", PROJECT_MSG_DEBUG); + } else { + $this->log("Task $name ($class) already registerd, skipping", PROJECT_MSG_VERBOSE); + } + } + + function &getTaskDefinitions() { + return $this->taskdefs; + } + + /** + * Adds a data type definition. + * @param string $name Name of tag. + * @param string $class The class path to use. + * @param string $classpath The classpat to use. + */ + function addDataTypeDefinition($typeName, $typeClass, $classpath = null) { + if (!isset($this->typedefs[$typeName])) { + Phing::import($typeClass, $classpath); + $this->typedefs[$typeName] = $typeClass; + $this->log(" +User datatype: $typeName ($typeClass)", PROJECT_MSG_DEBUG); + } else { + $this->log("Type $name ($class) already registerd, skipping", PROJECT_MSG_VERBOSE); + } + } + + function getDataTypeDefinitions() { + return $this->typedefs; + } + + /** add a new target to the project */ + function addTarget($targetName, &$target) { + if (isset($this->targets[$targetName])) { + throw new BuildException("Duplicate target: $targetName"); + } + $this->addOrReplaceTarget($targetName, $target); + } + + function addOrReplaceTarget($targetName, &$target) { + $this->log(" +Target: $targetName", PROJECT_MSG_DEBUG); + $target->setProject($this); + $this->targets[$targetName] = $target; + } + + function getTargets() { + return $this->targets; + } + + /** + * Create a new task instance and return reference to it. This method is + * sorta factory like. A _local_ instance is created and a reference returned to + * that instance. Usually PHP destroys local variables when the function call + * ends. But not if you return a reference to that variable. + * This is kinda error prone, because if no reference exists to the variable + * it is destroyed just like leaving the local scope with primitive vars. There's no + * central place where the instance is stored as in other OOP like languages. + * + * [HL] Well, ZE2 is here now, and this is still working. We'll leave this alone + * unless there's any good reason not to. + * + * @param string $taskType Task name + * @returns Task A task object + * @throws BuildException + * Exception + */ + function createTask($taskType) { + try { + $cls = ""; + $tasklwr = strtolower($taskType); + foreach ($this->taskdefs as $name => $class) { + if (strtolower($name) === $tasklwr) { + $cls = StringHelper::unqualify($class); + break; + } + } + + if ($cls === "") { + return null; + } + + if (!class_exists($cls)) { + throw new BuildException("Could not instantiate class $cls, even though a class was specified. (Make sure that the specified class file contains a class with the correct name.)"); + } + + $o = new $cls(); + + if ($o instanceof Task) { + $task = $o; + } else { + $this->log (" (Using TaskAdapter for: $taskType)", PROJECT_MSG_DEBUG); + // not a real task, try adapter + $taskA = new TaskAdapter(); + $taskA->setProxy($o); + $task = $taskA; + } + $task->setProject($this); + $task->setTaskType($taskType); + // set default value, can be changed by the user + $task->setTaskName($taskType); + $this->log (" +Task: " . $taskType, PROJECT_MSG_DEBUG); + } catch (Exception $t) { + throw new BuildException("Could not create task of type: " . $taskType, $t); + } + // everything fine return reference + return $task; + } + + /** + * Create a task instance and return reference to it + * See createTask() for explanation how this works + * + * @param string Type name + * @returns object A datatype object + * @throws BuildException + * Exception + */ + function createDataType($typeName) { + try { + $cls = ""; + $typelwr = strtolower($typeName); + foreach ($this->typedefs as $name => $class) { + if (strtolower($name) === $typelwr) { + $cls = StringHelper::unqualify($class); + break; + } + } + + if ($cls === "") { + return null; + } + + if (!class_exists($cls)) { + throw new BuildException("Could not instantiate class $cls, even though a class was specified. (Make sure that the specified class file contains a class with the correct name.)"); + } + + $type = new $cls(); + $this->log(" +Type: $typeName", PROJECT_MSG_DEBUG); + if (!($type instanceof DataType)) { + throw new Exception("$class is not an instance of phing.types.DataType"); + } + if ($type instanceof ProjectComponent) { + $type->setProject($this); + } + } catch (Exception $t) { + throw new BuildException("Could not create type: $typeName", $t); + } + // everything fine return reference + return $type; + } + + /** + * Executes a list of targets + * + * @param array List of target names to execute + * @returns void + * @throws BuildException + */ + function executeTargets($targetNames) { + foreach($targetNames as $tname) { + $this->executeTarget($tname); + } + } + + /** + * Executes a target + * + * @param string Name of Target to execute + * @returns void + * @throws BuildException + */ + function executeTarget($targetName) { + + // complain about executing void + if ($targetName === null) { + throw new BuildException("No target specified"); + } + + // invoke topological sort of the target tree and run all targets + // until targetName occurs. + $sortedTargets = $this->_topoSort($targetName, $this->targets); + + $curIndex = (int) 0; + $curTarget = null; + do { + try { + $curTarget = $sortedTargets[$curIndex++]; + $curTarget->performTasks(); + } catch (BuildException $exc) { + $this->log("Execution of target \"".$curTarget->getName()."\" failed for the following reason: ".$exc->getMessage(), PROJECT_MSG_ERR); + throw $exc; + } + } while ($curTarget->getName() !== $targetName); + } + + + function resolveFile($fileName, $rootDir = null) { + if ($rootDir === null) { + return $this->fileUtils->resolveFile($this->basedir, $fileName); + } else { + return $this->fileUtils->resolveFile($rootDir, $fileName); + } + } + + /** + * Topologically sort a set of Targets. + * @param $root is the (String) name of the root Target. The sort is + * created in such a way that the sequence of Targets until the root + * target is the minimum possible such sequence. + * @param $targets is a array representing a "name to Target" mapping + * @return An array of Strings with the names of the targets in + * sorted order. + */ + function _topoSort($root, &$targets) { + + $root = (string) $root; + $ret = array(); + $state = array(); + $visiting = array(); + + // We first run a DFS based sort using the root as the starting node. + // This creates the minimum sequence of Targets to the root node. + // We then do a sort on any remaining unVISITED targets. + // This is unnecessary for doing our build, but it catches + // circular dependencies or missing Targets on the entire + // dependency tree, not just on the Targets that depend on the + // build Target. + + $this->_tsort($root, $targets, $state, $visiting, $ret); + + $retHuman = ""; + for ($i=0, $_i=count($ret); $i < $_i; $i++) { + $retHuman .= $ret[$i]->toString()." "; + } + $this->log("Build sequence for target '$root' is: $retHuman", PROJECT_MSG_VERBOSE); + + $keys = array_keys($targets); + while($keys) { + $curTargetName = (string) array_shift($keys); + if (!isset($state[$curTargetName])) { + $st = null; + } else { + $st = (string) $state[$curTargetName]; + } + + if ($st === null) { + $this->_tsort($curTargetName, $targets, $state, $visiting, $ret); + } elseif ($st === "VISITING") { + throw new Exception("Unexpected node in visiting state: $curTargetName"); + } + } + + $retHuman = ""; + for ($i=0,$_i=count($ret); $i < $_i; $i++) { + $retHuman .= $ret[$i]->toString()." "; + } + $this->log("Complete build sequence is: $retHuman", PROJECT_MSG_VERBOSE); + + return $ret; + } + + // one step in a recursive DFS traversal of the target dependency tree. + // - The array "state" contains the state (VISITED or VISITING or null) + // of all the target names. + // - The stack "visiting" contains a stack of target names that are + // currently on the DFS stack. (NB: the target names in "visiting" are + // exactly the target names in "state" that are in the VISITING state.) + // 1. Set the current target to the VISITING state, and push it onto + // the "visiting" stack. + // 2. Throw a BuildException if any child of the current node is + // in the VISITING state (implies there is a cycle.) It uses the + // "visiting" Stack to construct the cycle. + // 3. If any children have not been VISITED, tsort() the child. + // 4. Add the current target to the Vector "ret" after the children + // have been visited. Move the current target to the VISITED state. + // "ret" now contains the sorted sequence of Targets upto the current + // Target. + + function _tsort($root, &$targets, &$state, &$visiting, &$ret) { + $state[$root] = "VISITING"; + $visiting[] = $root; + + if (!isset($targets[$root]) || !($targets[$root] instanceof Target)) { + $target = null; + } else { + $target = $targets[$root]; + } + + // make sure we exist + if ($target === null) { + $sb = "Target '$root' does not exist in this project."; + array_pop($visiting); + if (!empty($visiting)) { + $parent = (string) $visiting[count($visiting)-1]; + $sb .= "It is used from target '$parent'."; + } + throw new BuildException($sb); + } + + $deps = $target->getDependencies(); + + while($deps) { + $cur = (string) array_shift($deps); + if (!isset($state[$cur])) { + $m = null; + } else { + $m = (string) $state[$cur]; + } + if ($m === null) { + // not been visited + $this->_tsort($cur, $targets, $state, $visiting, $ret); + } elseif ($m == "VISITING") { + // currently visiting this node, so have a cycle + throw $this->_makeCircularException($cur, $visiting); + } + } + + $p = (string) array_pop($visiting); + if ($root !== $p) { + throw new Exception("Unexpected internal error: expected to pop $root but got $p"); + } + + $state[$root] = "VISITED"; + $ret[] = $target; + } + + function _makeCircularException($end, $stk) { + $sb = "Circular dependency: $end"; + do { + $sb .= " <- ".(string) array_pop($stk); + } while($c != $end); + return new BuildException($sb); + } + + /** + * Adds a reference to an object. This method is called when the parser + * detects a id="foo" attribute. It passes the id as $name and a reference + * to the object assigned to this id as $value + */ + function addReference($name, $object) { + if (isset($this->references[$name])) { + $this->log("Overriding previous definition of reference to $name", PROJECT_MSG_WARN); + } + $this->log("Adding reference: $name -> ".get_class($object), PROJECT_MSG_DEBUG); + $this->references[$name] = $object; + } + + /** + * Returns the references array. + * @return array + */ + function getReferences() { + return $this->references; + } + + /** + * Returns a specific reference. + * @param string $key The reference id/key. + * @return object or null if not defined + */ + function getReference($key) + { + if (isset($this->references[$key])) { + return $this->references[$key]; + } + return null; // just to be explicit + } + + /** + * Abstracting and simplifyling Logger calls for project messages + */ + function log($msg, $level = PROJECT_MSG_INFO) { + $this->logObject($this, $msg, $level); + } + + function logObject($obj, $msg, $level) { + $this->fireMessageLogged($obj, $msg, $level); + } + + function addBuildListener(BuildListener $listener) { + $this->listeners[] = $listener; + } + + function removeBuildListener(BuildListener $listener) { + $newarray = array(); + for ($i=0, $size=count($this->listeners); $i < $size; $i++) { + if ($this->listeners[$i] !== $listener) { + $newarray[] = $this->listeners[$i]; + } + } + $this->listeners = $newarray; + } + + function getBuildListeners() { + return $this->listeners; + } + + function fireBuildStarted() { + $event = new BuildEvent($this); + foreach($this->listeners as $listener) { + $listener->buildStarted($event); + } + } + + function fireBuildFinished($exception) { + $event = new BuildEvent($this); + $event->setException($exception); + foreach($this->listeners as $listener) { + $listener->buildFinished($event); + } + } + + function fireTargetStarted($target) { + $event = new BuildEvent($target); + foreach($this->listeners as $listener) { + $listener->targetStarted($event); + } + } + + function fireTargetFinished($target, $exception) { + $event = new BuildEvent($target); + $event->setException($exception); + foreach($this->listeners as $listener) { + $listener->targetFinished($event); + } + } + + function fireTaskStarted($task) { + $event = new BuildEvent($task); + foreach($this->listeners as $listener) { + $listener->taskStarted($event); + } + } + + function fireTaskFinished($task, $exception) { + $event = new BuildEvent($task); + $event->setException($exception); + foreach($this->listeners as $listener) { + $listener->taskFinished($event); + } + } + + function fireMessageLoggedEvent($event, $message, $priority) { + $event->setMessage($message, $priority); + foreach($this->listeners as $listener) { + $listener->messageLogged($event); + } + } + + function fireMessageLogged($object, $message, $priority) { + $this->fireMessageLoggedEvent(new BuildEvent($object), $message, $priority); + } +} diff --git a/gulliver/thirdparty/phing/ProjectComponent.php b/gulliver/thirdparty/phing/ProjectComponent.php new file mode 100644 index 000000000..d8fc751e7 --- /dev/null +++ b/gulliver/thirdparty/phing/ProjectComponent.php @@ -0,0 +1,72 @@ +. + */ + +/** + * Abstract class providing properties and methods common to all + * the project components + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.5 $ + * @package phing + */ +abstract class ProjectComponent { + + /** + * Holds a reference to the project that a project component + * (a task, a target, etc.) belongs to + * + * @var object A reference to the current project instance + */ + protected $project = null; + + /** + * References the project to the current component. + * + * @param object The reference to the current project + * @access public + */ + function setProject($project) { + $this->project = $project; + } + + /** + * Returns a reference to current project + * + * @return object Reference to current porject object + * @access public + */ + function getProject() { + return $this->project; + } + + /** + * Logs a message with the given priority. + * + * @param string The message to be logged. + * @param integer The message's priority at this message should have + */ + public function log($msg, $level = PROJECT_MSG_INFO) { + if ($this->project !== null) { + $this->project->log($msg, $level); + } + } +} diff --git a/gulliver/thirdparty/phing/RuntimeConfigurable.php b/gulliver/thirdparty/phing/RuntimeConfigurable.php new file mode 100644 index 000000000..2b8c279a2 --- /dev/null +++ b/gulliver/thirdparty/phing/RuntimeConfigurable.php @@ -0,0 +1,118 @@ +. + */ + +/** + * Wrapper class that holds the attributes of a Task (or elements + * nested below that level) and takes care of configuring that element + * at runtime. + * + * SMART-UP INLINE DOCS + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.6 $ + * @package phing + */ +class RuntimeConfigurable { + + private $elementTag = null; + private $children = array(); + private $wrappedObject = null; + private $attributes = array(); + private $characters = ""; + + + /** @param proxy The element to wrap. */ + function __construct($proxy, $elementTag) { + $this->wrappedObject = $proxy; + $this->elementTag = $elementTag; + } + + function setProxy($proxy) { + $this->wrappedObject = $proxy; + } + + /** Set's the attributes for the wrapped element. */ + function setAttributes($attributes) { + $this->attributes = $attributes; + } + + /** Returns the AttributeList of the wrapped element. */ + function getAttributes() { + return $this->attributes; + } + + /** Adds child elements to the wrapped element. */ + function addChild(RuntimeConfigurable $child) { + $this->children[] = $child; + } + + /** Returns the child with index */ + function getChild($index) { + return $this->children[(int)$index]; + } + + /** Add characters from #PCDATA areas to the wrapped element. */ + function addText($data) { + $this->characters .= (string) $data; + } + + function getElementTag() { + return $this->elementTag; + } + + + /** Configure the wrapped element and all children. */ + function maybeConfigure(Project $project) { + $id = null; + + // DataType configured in ProjectConfigurator + // if ( is_a($this->wrappedObject, "DataType") ) + // return; + + if ($this->attributes || $this->characters) { + ProjectConfigurator::configure($this->wrappedObject, $this->attributes, $project); + + if (isset($this->attributes["id"])) { + $id = $this->attributes["id"]; + } + + $this->attributes = null; + + if ($this->characters) { + ProjectConfigurator::addText($project, $this->wrappedObject, (string) $this->characters); + $this->characters=""; + } + if ($id !== null) { + $project->addReference($id, $this->wrappedObject); + } + } + + if ( is_array($this->children) && !empty($this->children) ) { + // Configure all child of this object ... + foreach($this->children as $child) { + $child->maybeConfigure($project); + ProjectConfigurator::storeChild($project, $this->wrappedObject, $child->wrappedObject, strtolower($child->getElementTag())); + } + } + } +} + diff --git a/gulliver/thirdparty/phing/Target.php b/gulliver/thirdparty/phing/Target.php new file mode 100644 index 000000000..d303b6367 --- /dev/null +++ b/gulliver/thirdparty/phing/Target.php @@ -0,0 +1,317 @@ +. + */ + +include_once 'phing/TaskContainer.php'; + +/** + * The Target component. Carries all required target data. Implements the + * abstract class {@link TaskContainer} + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.10 $ $Date: 2005/10/04 19:13:44 $ + * @access public + * @see TaskContainer + * @package phing + */ + +class Target implements TaskContainer { + + /** name of target */ + private $name; + + /** dependencies */ + private $dependencies = array(); + + /** holds objects of children of this target */ + private $children = array(); + + /** the if cond. from xml */ + private $ifCondition = ""; + + /** the unless cond. from xml */ + private $unlessCondition = ""; + + /** description of this target */ + private $description; + + /** reference to project */ + private $project; + + /** + * References the project to the current component. + * + * @param Project The reference to the current project + */ + public function setProject(Project $project) { + $this->project = $project; + } + + /** + * Returns reference to current project + * + * @return Project Reference to current porject object + */ + public function getProject() { + return $this->project; + } + + /** + * Sets the target dependencies from xml + * + * @param string $depends Comma separated list of targetnames that depend on + * this target + * @throws BuildException + */ + public function setDepends($depends) { + // explode should be faster than strtok + $deps = explode(',', $depends); + for ($i=0, $size=count($deps); $i < $size; $i++) { + $trimmed = trim($deps[$i]); + if ($trimmed === "") { + throw new BuildException("Syntax Error: Depend attribute for target ".$this->getName()." is malformed."); + } + $this->addDependency($trimmed); + } + } + + /** + * Adds a singular dependent target name to the list + * + * @param string The dependency target to add + * @access public + */ + public function addDependency($dependency) { + $this->dependencies[] = (string) $dependency; + } + + /** + * Returns reference to indexed array of the dependencies this target has. + * + * @return array Referece to target dependencoes + */ + public function getDependencies() { + return $this->dependencies; + } + + /** + * Sets the name of the target + * + * @param string Name of this target + */ + public function setName($name) { + $this->name = (string) $name; + } + + /** + * Returns name of this target. + * + * @return string The name of the target + * @access public + */ + function getName() { + return (string) $this->name; + } + + /** + * Adds a task element to the list of this targets child elements + * + * @param object The task object to add + * @access public + */ + function addTask(Task $task) { + $this->children[] = $task; + } + + /** + * Adds a runtime configurable element to the list of this targets child + * elements. + * + * @param object The RuntimeConfigurabel object + * @access public + */ + function addDataType($rtc) { + $this->children[] = $rtc; + } + + /** + * Returns an array of all tasks this target has as childrens. + * + * The task objects are copied here. Don't use this method to modify + * task objects. + * + * @return array Task[] + */ + public function getTasks() { + $tasks = array(); + for ($i=0,$size=count($this->children); $i < $size; $i++) { + $tsk = $this->children[$i]; + if ($tsk instanceof Task) { + // note: we're copying objects here! + $tasks[] = clone $tsk; + } + } + return $tasks; + } + + /** + * Set the if-condition from the XML tag, if any. The property name given + * as parameter must be present so the if condition evaluates to true + * + * @param string The property name that has to be present + * @access public + */ + public function setIf($property) { + $this->ifCondition = ($property === null) ? "" : $property; + } + + /** + * Set the unless-condition from the XML tag, if any. The property name + * given as parameter must be present so the unless condition evaluates + * to true + * + * @param string The property name that has to be present + * @access public + */ + public function setUnless($property) { + $this->unlessCondition = ($property === null) ? "" : $property; + } + + /** + * Sets a textual description of this target. + * + * @param string The description text + */ + public function setDescription($description) { + if ($description !== null && strcmp($description, "") !== 0) { + $this->description = (string) $description; + } else { + $this->description = null; + } + } + + /** + * Returns the description of this target. + * + * @return string The description text of this target + */ + public function getDescription() { + return $this->description; + } + + /** + * Returns a string representation of this target. In our case it + * simply returns the target name field + * + * @return string The string representation of this target + */ + function toString() { + return (string) $this->name; + } + + /** + * The entry point for this class. Does some checking, then processes and + * performs the tasks for this target. + * + */ + public function main() { + if ($this->testIfCondition() && $this->testUnlessCondition()) { + foreach($this->children as $o) { + if ($o instanceof Task) { + // child is a task + $o->perform(); + } else { + // child is a RuntimeConfigurable + $o->maybeConfigure($this->project); + } + } + } elseif (!$this->testIfCondition()) { + $this->project->log("Skipped target '".$this->name."' because property '".$this->ifCondition."' not set.", PROJECT_MSG_VERBOSE); + } else { + $this->project->log("Skipped target '".$this->name."' because property '".$this->unlessCondition."' set.", PROJECT_MSG_VERBOSE); + } + } + + /** + * Performs the tasks by calling the main method of this target that + * actually executes the tasks. + * + * This method is for ZE2 and used for proper exception handling of + * task exceptions. + */ + public function performTasks() { + try {// try to execute this target + $this->project->fireTargetStarted($this); + $this->main(); + $this->project->fireTargetFinished($this, $null=null); + } catch (Exception $exc) { + // log here and rethrow + $this->project->fireTargetFinished($this, $exc); + throw $exc; + } + } + + /** + * Tests if the property set in ifConfiditon exists. + * + * @return boolean true if the property specified + * in $this->ifCondition exists; + * false otherwise + */ + private function testIfCondition() { + if ($this->ifCondition === "") { + return true; + } + + $properties = explode(",", $this->ifCondition); + + $result = true; + foreach ($properties as $property) { + $test = ProjectConfigurator::replaceProperties($this->getProject(), $property, $this->project->getProperties()); + $result = $result && ($this->project->getProperty($test) !== null); + } + + return $result; + } + + /** + * Tests if the property set in unlessCondition exists. + * + * @return boolean true if the property specified + * in $this->unlessCondition exists; + * false otherwise + */ + private function testUnlessCondition() { + if ($this->unlessCondition === "") { + return true; + } + + $properties = explode(",", $this->unlessCondition); + + $result = true; + foreach ($properties as $property) { + $test = ProjectConfigurator::replaceProperties($this->getProject(), $property, $this->project->getProperties()); + $result = $result && ($this->project->getProperty($test) === null); + } + return $result; + } + +} diff --git a/gulliver/thirdparty/phing/Task.php b/gulliver/thirdparty/phing/Task.php new file mode 100644 index 000000000..774d8c012 --- /dev/null +++ b/gulliver/thirdparty/phing/Task.php @@ -0,0 +1,266 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +include_once 'phing/RuntimeConfigurable.php'; + +/** + * The base class for all Tasks. + * + * Use {@link Project#createTask} to register a new Task. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.11 $ + * @see Project#createTask() + * @package phing + */ +abstract class Task extends ProjectComponent { + + /** owning Target object */ + protected $target; + + /** description of the task */ + protected $description; + + /** internal taskname (req) */ + protected $taskType; + + /** taskname for logger */ + protected $taskName; + + /** stored buildfile location */ + protected $location; + + /** wrapper of the task */ + protected $wrapper; + + /** + * Sets the owning target this task belongs to. + * + * @param object Reference to owning target + * @access public + */ + function setOwningTarget(Target $target) { + $this->target = $target; + } + + /** + * Returns the owning target of this task. + * + * @return object The target object that owns this task + * @access public + */ + function getOwningTarget() { + return $this->target; + } + + /** + * Returns the name of task, used only for log messages + * + * @return string Name of this task + * @access public + */ + function getTaskName() { + if ($this->taskName === null) { + // if no task name is set, then it's possible + // this task was created from within another task. We don't + // therefore know the XML tag name for this task, so we'll just + // use the class name stripped of "task" suffix. This is only + // for log messages, so we don't have to worry much about accuracy. + return preg_replace('/task$/i', '', get_class($this)); + } + return $this->taskName; + } + + /** + * Sets the name of this task for log messages + * + * @return string A string representing the name of this task for log + * @access public + */ + function setTaskName($name) { + $this->taskName = (string) $name; + } + + /** + * Returns the name of the task under which it was invoked, + * usually the XML tagname + * + * @return string The type of this task (XML Tag) + */ + function getTaskType() { + return $this->taskType; + } + + /** + * Sets the type of the task. Usually this is the name of the XML tag + * + * @param string The type of this task (XML Tag) + */ + function setTaskType($name) { + $this->taskType = (string) $name; + } + + /** + * Returns a name + * + */ + protected function getRegisterSlot($slotName) { + return Register::getSlot('task.' . $this->getTaskName() . '.' . $slotName); + } + + /** + * Provides a project level log event to the task. + * + * @param string The message to log + * @param integer The priority of the message + * @see BuildEvent + * @see BuildListener + */ + function log($msg, $level = PROJECT_MSG_INFO) { + $this->project->logObject($this, $msg, $level); + } + + /** + * Sets a textual description of the task + * + * @param string The text describing the task + */ + public function setDescription($desc) { + $this->description = $desc; + } + + /** + * Returns the textual description of the task + * + * @return string The text description of the task + */ + public function getDescription() { + return $this->description; + } + + /** + * Called by the parser to let the task initialize properly. + * Should throw a BuildException if something goes wrong with the build + * + * This is abstract here, but may not be overloaded by subclasses. + * + * @throws BuildException + */ + public function init() { + } + + /** + * Called by the project to let the task do it's work. This method may be + * called more than once, if the task is invoked more than once. For + * example, if target1 and target2 both depend on target3, then running + * phing target1 target2 will run all tasks in target3 twice. + * + * Should throw a BuildException if someting goes wrong with the build + * + * This is abstract here. Must be overloaded by real tasks. + * + * @access public + */ + abstract function main(); + + /** + * Returns the location within the buildfile this task occurs. Used + * by {@link BuildException} to give detailed error messages. + * + * @return Location The location object describing the position of this + * task within the buildfile. + */ + function getLocation() { + return $this->location; + } + + /** + * Sets the location within the buildfile this task occurs. Called by + * the parser to set location information. + * + * @return object The location object describing the position of this + * task within the buildfile. + * @access public + */ + function setLocation(Location $location) { + $this->location = $location; + } + + /** + * Returns the wrapper object for runtime configuration + * + * @return object The wrapper object used by this task + * @access public + */ + function getRuntimeConfigurableWrapper() { + if ($this->wrapper === null) { + $this->wrapper = new RuntimeConfigurable($this, $this->getTaskName()); + } + return $this->wrapper; + } + + /** + * Sets the wrapper object this task should use for runtime + * configurable elements. + * + * @param object The wrapper object this task should use + * @access public + */ + function setRuntimeConfigurableWrapper(RuntimeConfigurable $wrapper) { + $this->wrapper = $wrapper; + } + + /** + * Configure this task if it hasn't been done already. + * + * @access public + */ + function maybeConfigure() { + if ($this->wrapper !== null) { + $this->wrapper->maybeConfigure($this->project); + } + } + + /** + * Perfrom this task + * + * @access public + */ + function perform() { + + try { // try executing task + $this->project->fireTaskStarted($this); + $this->maybeConfigure(); + $this->main(); + $this->project->fireTaskFinished($this, $null=null); + } catch (Exception $exc) { + if ($exc instanceof BuildException) { + if ($exc->getLocation() === null) { + $exc->setLocation($this->getLocation()); + } + } + $this->project->fireTaskFinished($this, $exc); + throw $exc; + } + } +} diff --git a/gulliver/thirdparty/phing/TaskAdapter.php b/gulliver/thirdparty/phing/TaskAdapter.php new file mode 100644 index 000000000..b44f14041 --- /dev/null +++ b/gulliver/thirdparty/phing/TaskAdapter.php @@ -0,0 +1,84 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Use introspection to "adapt" an arbitrary ( not extending Task, but with + * similar patterns). + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.7 $ + * @package phing + */ +class TaskAdapter extends Task { + + /** target object */ + private $proxy; + + /** + * Main entry point. + * @return void + */ + function main() { + + if (method_exists($this->proxy, "setProject")) { + try { // try to set project + $this->proxy->setProject($this->project); + } catch (Exception $ex) { + $this->log("Error setting project in " . get_class($this->proxy) . PROJECT_MSG_ERR); + throw new BuildException($ex); + } + } else { + throw new Exception("Error setting project in class " . get_class($this->proxy)); + } + + if (method_exists($this->proxy, "main")) { + try { //try to call main + $this->proxy->main($this->project); + } catch (Exception $ex) { + $this->log("Error in " . get_class($this->proxy), PROJECT_MSG_ERR); + throw new BuildException($ex->getMessage()); + } + } else { + throw new BuildException("Your task-like class '" . get_class($this->proxy) ."' does not have a main() method"); + } + } + + /** + * Set the target object. + * @param object $o + * @return void + */ + function setProxy($o) { + $this->proxy = $o; + } + + /** + * Gets the target object. + * @return object + */ + function getProxy() { + return $this->proxy; + } + +} diff --git a/gulliver/thirdparty/phing/TaskContainer.php b/gulliver/thirdparty/phing/TaskContainer.php new file mode 100644 index 000000000..cdbbcf618 --- /dev/null +++ b/gulliver/thirdparty/phing/TaskContainer.php @@ -0,0 +1,42 @@ +. + */ + +/** + * Abstract interface for objects which can contain tasks (targets) + * Used to check if a class can contain tasks (via instanceof) + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.5 $ $Date: 2005/10/04 19:13:44 $ + * @access public + * @package phing + */ +interface TaskContainer { + + /** + * Adds a task to this task container. Must be implemented + * by derived class + * + * @param object The task to be added to the container + * @access public + */ + function addTask(Task $task); +} diff --git a/gulliver/thirdparty/phing/UnknownElement.php b/gulliver/thirdparty/phing/UnknownElement.php new file mode 100644 index 000000000..fa0a5a6c7 --- /dev/null +++ b/gulliver/thirdparty/phing/UnknownElement.php @@ -0,0 +1,211 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Wrapper class that holds all information necessary to create a task + * that did not exist when Phing started. + * + * This has something to do with phing encountering an task XML element + * it is not aware of at start time. This is a situation where special steps + * need to be taken so that the element is then known. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.9 $ + * @package phing + */ +class UnknownElement extends Task { + + private $elementName; + private $realThing; + private $children = array(); + + /** + * Constructs a UnknownElement object + * + * @param string The XML element name that is unknown + * @access public + */ + function __construct($elementName) { + $this->elementName = (string) $elementName; + } + + /** + * Return the XML element name that this UnnownElement + * handles. + * + * @return string The XML element name that is unknown + */ + public function getTag() { + return (string) $this->elementName; + } + + /** + * Tries to configure the unknown element + * + * @throws BuildException if the element can not be configured + */ + public function maybeConfigure() { + + $this->realThing = $this->makeObject($this, $this->wrapper); + $this->wrapper->setProxy($this->realThing); + if ($this->realThing instanceof Task) { + $this->realThing->setRuntimeConfigurableWrapper($this->wrapper); + } + + $this->handleChildren($this->realThing, $this->wrapper); + $this->wrapper->maybeConfigure($this->getProject()); + + } + + /** + * Called when the real task has been configured for the first time. + * + * @throws BuildException if the task can not be created + */ + public function main() { + + if ($this->realThing === null) { + // plain impossible to get here, maybeConfigure should + // have thrown an exception. + throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}"); + } + + if ($this->realThing instanceof Task) { + $this->realThing->main(); + } + + } + + /** + * Add a child element to the unknown element + * + * @param object The object representing the child element + */ + public function addChild(UnknownElement $child) { + $this->children[] = $child; + } + + /** + * Handle child elemets of the unknown element, if any. + * + * @param ProjectComponent The parent object the unkown element belongs to + * @param object The parent wrapper object + */ + function handleChildren(ProjectComponent $parent, $parentWrapper) { + + if ($parent instanceof TaskAdapter) { + $parent = $parent->getProxy(); + } + + $parentClass = get_class($parent); + $ih = IntrospectionHelper::getHelper($parentClass); + + for ($i=0, $childrenCount=count($this->children); $i < $childrenCount; $i++) { + + $childWrapper = $parentWrapper->getChild($i); + $child = $this->children[$i]; + $realChild = null; + if ($parent instanceof TaskContainer) { + $realChild = $this->makeTask($child, $childWrapper, false); + $parent->addTask($realChild); + } else { + $realChild = $ih->createElement($this->project, $parent, $child->getTag()); + } + + $childWrapper->setProxy($realChild); + if ($realChild instanceof Task) { + $realChild->setRuntimeConfigurableWrapper($childWrapper); + } + + $child->handleChildren($realChild, $childWrapper); + if ($realChild instanceof Task) { + $realChild->maybeConfigure(); + } + } + } + + /** + * Creates a named task or data type. If the real object is a task, + * it is configured up to the init() stage. + * + * @param UnknownElement $ue The unknown element to create the real object for. + * Must not be null. + * @param RuntimeConfigurable $w Ignored in this implementation. + * @return object The Task or DataType represented by the given unknown element. + */ + protected function makeObject(UnknownElement $ue, RuntimeConfigurable $w) { + $o = $this->makeTask($ue, $w, true); + if ($o === null) { + $o = $this->project->createDataType($ue->getTag()); + } + if ($o === null) { + throw new BuildException("Could not create task/type: '".$ue->getTag()."'. Make sure that this class has been declared using taskdef / typedef."); + } + return $o; + } + + /** + * Create a named task and configure it up to the init() stage. + * + * @param UnknownElement $ue The unknwon element to create a task from + * @param RuntimeConfigurable $w The wrapper object + * @param boolean $onTopLevel Whether to treat this task as if it is top-level. + * @return Task The freshly created task + */ + protected function makeTask(UnknownElement $ue, RuntimeConfigurable $w, $onTopLevel = false) { + + $task = $this->project->createTask($ue->getTag()); + + if ($task === null) { + if (!$onTopLevel) { + throw new BuildException("Could not create task of type: '".$this->elementName."'. Make sure that this class has been declared using taskdef."); + } + return null; + } + + // used to set the location within the xmlfile so that exceptions can + // give detailed messages + + $task->setLocation($this->getLocation()); + $attrs = $w->getAttributes(); + if (isset($attrs['id'])) { + $this->project->addReference($attrs['id'], $task); + } + + // UnknownElement always has an associated target + $task->setOwningTarget($this->target); + + $task->init(); + return $task; + } + + /** + * Get the name of the task to use in logging messages. + * + * @return string The task's name + */ + function getTaskName() { + return $this->realThing === null ? parent::getTaskName() : $this->realThing->getTaskName(); + } +} diff --git a/gulliver/thirdparty/phing/filters/BaseFilterReader.php b/gulliver/thirdparty/phing/filters/BaseFilterReader.php new file mode 100644 index 000000000..9aa3cbb89 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/BaseFilterReader.php @@ -0,0 +1,157 @@ +. +*/ + +include_once 'phing/system/io/FilterReader.php'; +include_once 'phing/system/io/StringReader.php'; + + +/** + * Base class for core filter readers. + * + * @author Yannick Lecaillez + * @version $Revision: 1.8 $ $Date: 2004/05/20 02:24:10 $ + * @access public + * @see FilterReader + * @package phing.filters + */ +class BaseFilterReader extends FilterReader { + + /** Have the parameters passed been interpreted? */ + protected $initialized = false; + + /** The Phing project this filter is part of. */ + protected $project = null; + + /** + * Constructor used by Phing's introspection mechanism. + * The original filter reader is only used for chaining + * purposes, never for filtering purposes (and indeed + * it would be useless for filtering purposes, as it has + * no real data to filter). ChainedReaderHelper uses + * this placeholder instance to create a chain of real filters. + * + * @param Reader $in + */ + function __construct($in = null) { + if ($in === null) { + $dummy = ""; + $in = new StringReader($dummy); + } + parent::__construct($in); + } + + /** + * Returns the initialized status. + * + * @return boolean whether or not the filter is initialized + */ + function getInitialized() { + return $this->initialized; + } + + /** + * Sets the initialized status. + * + * @param boolean $initialized Whether or not the filter is initialized. + */ + function setInitialized($initialized) { + $this->initialized = (boolean) $initialized; + } + + /** + * Sets the project to work with. + * + * @param object $project The project this filter is part of. + * Should not be null. + */ + function setProject(Project $project) { + // type check, error must never occur, bad code of it does + $this->project = $project; + } + + /** + * Returns the project this filter is part of. + * + * @return object The project this filter is part of + */ + function getProject() { + return $this->project; + } + + /** + * Reads characters. + * + * @param off Offset at which to start storing characters. + * @param len Maximum number of characters to read. + * + * @return Characters read, or -1 if the end of the stream + * has been reached + * + * @throws IOException If an I/O error occurs + */ + function read($len = null) { + return $this->in->read($len); + } + + /** + * Reads a line of text ending with '\n' (or until the end of the stream). + * The returned String retains the '\n'. + * + * @return the line read, or null if the end of the + stream has already been reached + * + * @throws IOException if the underlying reader throws one during + * reading + */ + function readLine() { + $line = null; + + while ( ($ch = $this->in->read(1)) !== -1 ) { + $line .= $ch; + if ( $ch === "\n" ) + break; + } + + return $line; + } + + /** + * Returns whether the end of file has been reached with input stream. + * @return boolean + */ + function eof() { + return $this->in->eof(); + } + + /** + * Convenience method to support logging in filters. + * @param string $msg Message to log. + * @param int $level Priority level. + */ + function log($msg, $level = PROJECT_MSG_INFO) { + if ($this->project !== null) { + $this->project->log("[filter:".get_class($this)."] ".$msg, $level); + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/BaseParamFilterReader.php b/gulliver/thirdparty/phing/filters/BaseParamFilterReader.php new file mode 100644 index 000000000..5d21911c3 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/BaseParamFilterReader.php @@ -0,0 +1,69 @@ +. +*/ + +include_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/types/Parameterizable.php'; +include_once 'phing/types/Parameter.php'; + +/** + * Base class for core filter readers. + * + * @author Yannick Lecaillez + * @copyright © 2003 seasonfive. All rights reserved + * @version $Revision: 1.5 $ $Date: 2005/02/27 20:52:08 $ + * @access public + * @see FilterReader + * @package phing.filters + */ +class BaseParamFilterReader extends BaseFilterReader implements Parameterizable { + + /** The passed in parameter array. */ + protected $_parameters = array(); + + /* + * Sets the parameters used by this filter, and sets + * the filter to an uninitialized status. + * + * @param array Array of parameters to be used by this filter. + * Should not be null. + */ + function setParameters($parameters) { + // type check, error must never occur, bad code of it does + if ( !is_array($parameters) ) { + throw new Exception("Expected parameters array got something else"); + } + + $this->_parameters = $parameters; + $this->setInitialized(false); + } + + /* + * Returns the parameters to be used by this filter. + * + * @return the parameters to be used by this filter + */ + function &getParameters() { + return $this->_parameters; + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/ChainableReader.php b/gulliver/thirdparty/phing/filters/ChainableReader.php new file mode 100644 index 000000000..c5718bc7d --- /dev/null +++ b/gulliver/thirdparty/phing/filters/ChainableReader.php @@ -0,0 +1,42 @@ +. +*/ + +/** + * Interface indicating that a reader may be chained to another one. + * + * @author Magesh Umasankar + */ +interface ChainableReader { + + /** + * Returns a reader with the same configuration as this one, + * but filtering input from the specified reader. + * + * @param Reader $rdr the reader which the returned reader should be filtering + * + * @return Reader A reader with the same configuration as this one, but + * filtering input from the specified reader + */ + public function chain(Reader $rdr); +} + +?> diff --git a/gulliver/thirdparty/phing/filters/ExpandProperties.php b/gulliver/thirdparty/phing/filters/ExpandProperties.php new file mode 100644 index 000000000..8767a1475 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/ExpandProperties.php @@ -0,0 +1,82 @@ +. +*/ + +require_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Expands Phing Properties, if any, in the data. + *

    + * Example:
    + *

    + * Or: + *
    .
    +*/
    +
    +include_once 'phing/filters/BaseParamFilterReader.php';
    +include_once 'phing/filters/ChainableReader.php';
    +
    +/**
    + * Reads the first n lines of a stream.
    + * (Default is first 10 lines.)
    + * 

    + * Example: + *

    + * Or: + *
    
    + *    
    + * 
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.6 $ $Date: 2004/03/15 14:45:06 $ + * @access public + * @see FilterReader + * @package phing.filters + */ +class HeadFilter extends BaseParamFilterReader implements ChainableReader { + + /** + * Parameter name for the number of lines to be returned. + */ + const LINES_KEY = "lines"; + + /** + * Number of lines currently read in. + * @var integer + */ + private $_linesRead = 0; + + /** + * Number of lines to be returned in the filtered stream. + * @var integer + */ + private $_lines = 10; + + /** + * Returns first n lines of stream. + * @return the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + // note, if buffer contains fewer lines than + // $this->_lines this code will not work. + + if($this->_linesRead < $this->_lines) { + + $buffer = $this->in->read($len); + + if($buffer === -1) { + return -1; + } + + // now grab first X lines from buffer + + $lines = explode("\n", $buffer); + + $linesCount = count($lines); + + // must account for possibility that the num lines requested could + // involve more than one buffer read. + $len = ($linesCount > $this->_lines ? $this->_lines - $this->_linesRead : $linesCount); + $filtered_buffer = implode("\n", array_slice($lines, 0, $len) ); + $this->_linesRead += $len; + + return $filtered_buffer; + + } + + return -1; // EOF, since the file is "finished" as far as subsequent filters are concerned. + } + + /** + * Sets the number of lines to be returned in the filtered stream. + * + * @param integer $lines the number of lines to be returned in the filtered stream. + */ + function setLines($lines) { + $this->_lines = (int) $lines; + } + + /** + * Returns the number of lines to be returned in the filtered stream. + * + * @return integer The number of lines to be returned in the filtered stream. + */ + function getLines() { + return $this->_lines; + } + + /** + * Creates a new HeadFilter using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader. + */ + function chain(Reader $reader) { + $newFilter = new HeadFilter($reader); + $newFilter->setLines($this->getLines()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Scans the parameters list for the "lines" parameter and uses + * it to set the number of lines to be returned in the filtered stream. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0, $_i=count($params) ; $i < $_i; $i++) { + if ( self::LINES_KEY == $params[$i]->getName() ) { + $this->_lines = (int) $params[$i]->getValue(); + break; + } + } + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/LineContains.php b/gulliver/thirdparty/phing/filters/LineContains.php new file mode 100644 index 000000000..5b0eea766 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/LineContains.php @@ -0,0 +1,258 @@ +. + */ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Filter which includes only those lines that contain all the user-specified + * strings. + * + * Example: + * + *
    
    + *   
    + *   
    + * 
    + * + * Or: + * + *
    
    + *    
    + *    
    + * 
    + * + * This will include only those lines that contain foo and + * bar. + * + * @author Yannick Lecaillez + * @author Hans Lellelid + * @version $Revision: 1.11 $ + * @see PhingFilterReader + * @package phing.filters +*/ +class LineContains extends BaseParamFilterReader implements ChainableReader { + + /** + * The parameter name for the string to match on. + * @var string + */ + const CONTAINS_KEY = "contains"; + + /** + * Array of Contains objects. + * @var array + */ + private $_contains = array(); + + /** + * [Deprecated] + * @var string + */ + private $_line = null; + + /** + * Returns all lines in a buffer that contain specified strings. + * @return mixed buffer, -1 on EOF + */ + function read($len = null) { + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + + if ($buffer === -1) { + return -1; + } + + $lines = explode("\n", $buffer); + $matched = array(); + $containsSize = count($this->_contains); + + foreach($lines as $line) { + for($i = 0 ; $i < $containsSize ; $i++) { + $containsStr = $this->_contains[$i]->getValue(); + if ( strstr($line, $containsStr) === false ) { + $line = null; + break; + } + } + if($line !== null) { + $matched[] = $line; + } + } + $filtered_buffer = implode("\n", $matched); + return $filtered_buffer; + } + + /** + * [Deprecated. For reference only, used to be read() method.] + * Returns the next character in the filtered stream, only including + * lines from the original stream which contain all of the specified words. + * + * @return the next character in the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + function readChar() { + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $ch = -1; + + if ( $this->_line !== null ) { + $ch = substr($this->_line, 0, 1); + if ( strlen($this->_line) === 1 ) + $this->_line = null; + else + $this->_line = substr($this->_line, 1); + } else { + $this->_line = $this->readLine(); + if ( $this->_line === null ) { + $ch = -1; + } else { + $containsSize = count($this->_contains); + for($i = 0 ; $i < $containsSize ; $i++) { + $containsStr = $this->_contains[$i]->getValue(); + if ( strstr($this->_line, $containsStr) === false ) { + $this->_line = null; + break; + } + } + return $this->readChar(); + } + } + + return $ch; + } + + /** + * Adds a nested element. + * + * @return Contains The contains element added. + * Must not be null. + */ + function createContains() { + $num = array_push($this->_contains, new Contains()); + return $this->_contains[$num-1]; + } + + /** + * Sets the array of words which must be contained within a line read + * from the original stream in order for it to match this filter. + * + * @param array $contains An array of words which must be contained + * within a line in order for it to match in this filter. + * Must not be null. + */ + function setContains($contains) { + // type check, error must never occur, bad code of it does + if ( !is_array($contains) ) { + throw new Exception("Excpected array got something else"); + } + + $this->_contains = $contains; + } + + /** + * Returns the vector of words which must be contained within a line read + * from the original stream in order for it to match this filter. + * + * @return array The array of words which must be contained within a line read + * from the original stream in order for it to match this filter. The + * returned object is "live" - in other words, changes made to the + * returned object are mirrored in the filter. + */ + function getContains() { + return $this->_contains; + } + + /** + * Creates a new LineContains using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new LineContains($reader); + $newFilter->setContains($this->getContains()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Parses the parameters to add user-defined contains strings. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + foreach($params as $param) { + if ( self::CONTAINS_KEY == $param->getType() ) { + $cont = new Contains(); + $cont->setValue($param->getValue()); + array_push($this->_contains, $cont); + break; // because we only support a single contains + } + } + } + } +} + +/** + * Holds a contains element. + */ +class Contains { + + /** + * @var string + */ + private $_value; + + /** + * Set 'contains' value. + * @param string $contains + */ + function setValue($contains) { + $this->_value = (string) $contains; + } + + /** + * Returns 'contains' value. + * @return string + */ + function getValue() { + return $this->_value; + } +} +?> diff --git a/gulliver/thirdparty/phing/filters/LineContainsRegexp.php b/gulliver/thirdparty/phing/filters/LineContainsRegexp.php new file mode 100644 index 000000000..ea53ec87f --- /dev/null +++ b/gulliver/thirdparty/phing/filters/LineContainsRegexp.php @@ -0,0 +1,179 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/types/RegularExpression.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Filter which includes only those lines that contain the user-specified + * regular expression matching strings. + * + * Example: + *
    
    + *   
    + * 
    + * + * Or: + * + *
    
    + *    
    + * 
    + * + * This will fetch all those lines that contain the pattern foo + * + * @author Yannick Lecaillez + * @author Hans Lellelid + * @version $Revision: 1.8 $ + * @see FilterReader + * @package phing.filters + */ +class LineContainsRegexp extends BaseParamFilterReader implements ChainableReader { + + /** + * Parameter name for regular expression. + * @var string + */ + const REGEXP_KEY = "regexp"; + + /** + * Regular expressions that are applied against lines. + * @var array + */ + private $_regexps = array(); + + /** + * Returns all lines in a buffer that contain specified strings. + * @return mixed buffer, -1 on EOF + */ + function read($len = null) { + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + + if ($buffer === -1) { + return -1; + } + + $lines = explode("\n", $buffer); + $matched = array(); + + $regexpsSize = count($this->_regexps); + foreach($lines as $line) { + for($i = 0 ; $i<$regexpsSize ; $i++) { + $regexp = $this->_regexps[$i]; + $re = $regexp->getRegexp($this->getProject()); + $matches = $re->matches($line); + if ( !$matches ) { + $line = null; + break; + } + } + if($line !== null) { + $matched[] = $line; + } + } + $filtered_buffer = implode("\n", $matched); + return $filtered_buffer; + } + + /** + * Adds a regexp element. + * + * @return object regExp The regexp element added. + */ + function createRegexp() { + $num = array_push($this->_regexps, new RegularExpression()); + return $this->_regexps[$num-1]; + } + + /** + * Sets the vector of regular expressions which must be contained within + * a line read from the original stream in order for it to match this + * filter. + * + * @param regexps An array of regular expressions which must be contained + * within a line in order for it to match in this filter. Must not be + * null. + */ + function setRegexps($regexps) { + // type check, error must never occur, bad code of it does + if ( !is_array($regexps) ) { + throw new Exception("Excpected an 'array', got something else"); + } + $this->_regexps = $regexps; + } + + /** + * Returns the array of regular expressions which must be contained within + * a line read from the original stream in order for it to match this + * filter. + * + * @return array The array of regular expressions which must be contained within + * a line read from the original stream in order for it to match this + * filter. The returned object is "live" - in other words, changes made to + * the returned object are mirrored in the filter. + */ + function getRegexps() { + return $this->_regexps; + } + + /** + * Creates a new LineContainsRegExp using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new LineContainsRegExp($reader); + $newFilter->setRegexps($this->getRegexps()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Parses parameters to add user defined regular expressions. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0 ; $igetType() ) { + $pattern = $params[$i]->getValue(); + $regexp = new RegularExpression(); + $regexp->setPattern($pattern); + array_push($this->_regexps, $regexp); + } + } + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/PrefixLines.php b/gulliver/thirdparty/phing/filters/PrefixLines.php new file mode 100644 index 000000000..e594131a6 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/PrefixLines.php @@ -0,0 +1,142 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Attaches a prefix to every line. + * + * Example: + *
    + * + * Or: + * + *
    
    + *  
    + * 
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.6 $ $Date: 2004/03/15 14:45:06 $ + * @access public + * @see FilterReader + * @package phing.filters +*/ +class PrefixLines extends BaseParamFilterReader implements ChainableReader { + + /** + * Parameter name for the prefix. + * @var string + */ + const PREFIX_KEY = "lines"; + + /** + * The prefix to be used. + * @var string + */ + private $_prefix = null; + + /** + * Adds a prefix to each line of input stream and returns resulting stream. + * + * @return mixed buffer, -1 on EOF + */ + function read($len = null) { + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + + if ($buffer === -1) { + return -1; + } + + $lines = explode("\n", $buffer); + $filtered = array(); + + foreach($lines as $line) { + $line = $this->_prefix . $line; + $filtered[] = $line; + } + + $filtered_buffer = implode("\n", $filtered); + return $filtered_buffer; + } + + /** + * Sets the prefix to add at the start of each input line. + * + * @param string $prefix The prefix to add at the start of each input line. + * May be null, in which case no prefix + * is added. + */ + function setPrefix($prefix) { + $this->_prefix = (string) $prefix; + } + + /** + * Returns the prefix which will be added at the start of each input line. + * + * @return string The prefix which will be added at the start of each input line + */ + function getPrefix() { + return $this->_prefix; + } + + /** + * Creates a new PrefixLines filter using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new PrefixLines($reader); + $newFilter->setPrefix($this->getPrefix()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Initializes the prefix if it is available from the parameters. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0, $_i=count($params) ; $i < $_i ; $i++) { + if ( self::PREFIX_KEY == $params[$i]->getName() ) { + $this->_prefix = (string) $params[$i]->getValue(); + break; + } + } + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/ReplaceRegexp.php b/gulliver/thirdparty/phing/filters/ReplaceRegexp.php new file mode 100644 index 000000000..071a9ad17 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/ReplaceRegexp.php @@ -0,0 +1,129 @@ +. +*/ + +require_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; +include_once 'phing/types/RegularExpression.php'; + +/** + * Performs a regexp find/replace on stream. + *

    + * Example:
    + *

    + * 
    + *    
    + *    
    + * 
    + * 
    + * + * @author Hans Lellelid + * @version $Revision: 1.5 $ + * @package phing.filters + */ +class ReplaceRegexp extends BaseFilterReader implements ChainableReader { + + /** + * @var array RegularExpression[] + */ + private $regexps = array(); + + /** + * Creator method handles nested tags. + * @return RegularExpression + */ + function createRegexp() { + $num = array_push($this->regexps, new RegularExpression()); + return $this->regexps[$num-1]; + } + + /** + * Sets the current regexps. + * (Used when, e.g., cloning/chaining the method.) + * @param array RegularExpression[] + */ + function setRegexps($regexps) { + $this->regexps = $regexps; + } + + /** + * Gets the current regexps. + * (Used when, e.g., cloning/chaining the method.) + * @return array RegularExpression[] + */ + function getRegexps() { + return $this->regexps; + } + + /** + * Returns the filtered stream. + * The original stream is first read in fully, and the regex replace is performed. + * + * @param int $len Required $len for Reader compliance. + * + * @return mixed The filtered stream, or -1 if the end of the resulting stream has been reached. + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + $buffer = $this->in->read($len); + + if($buffer === -1) { + return -1; + } + + // perform regex replace here ... + foreach($this->regexps as $exptype) { + $regexp = $exptype->getRegexp($this->project); + try { + $buffer = $regexp->replace($buffer); + $this->log("Performing regexp replace: /".$regexp->getPattern()."/".$regexp->getReplace()."/g".($regexp->getIgnoreCase() ? 'i' : ''), PROJECT_MSG_VERBOSE); + } catch (Exception $e) { + // perhaps mismatch in params (e.g. no replace or pattern specified) + $this->log("Error performing regexp replace: " . $e->getMessage(), PROJECT_MSG_WARN); + } + } + + return $buffer; + } + + /** + * Creates a new ReplaceRegExp filter using the passed in + * Reader for instantiation. + * + * @param Reader $reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return ReplaceRegExp A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new ReplaceRegExp($reader); + $newFilter->setProject($this->getProject()); + $newFilter->setRegexps($this->getRegexps()); + return $newFilter; + } + +} + +?> diff --git a/gulliver/thirdparty/phing/filters/ReplaceTokens.php b/gulliver/thirdparty/phing/filters/ReplaceTokens.php new file mode 100644 index 000000000..2758d8437 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/ReplaceTokens.php @@ -0,0 +1,415 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/types/TokenSource.php'; +include_once 'phing/filters/ChainableReader.php'; + +/* + * Replaces tokens in the original input with user-supplied values. + * + * Example: + * + *
    ;
    + *   
    + * 
    + * + * Or: + * + *
    
    + *   
    + *   
    + *   
    + * 
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.14 $ $Date: 2005/06/16 15:09:10 $ + * @access public + * @see BaseParamFilterReader + * @package phing.filters + */ +class ReplaceTokens extends BaseParamFilterReader implements ChainableReader { + + /** + * Default "begin token" character. + * @var string + */ + const DEFAULT_BEGIN_TOKEN = "@"; + + /** + * Default "end token" character. + * @var string + */ + const DEFAULT_END_TOKEN = "@"; + + /** + * [Deprecated] Data that must be read from, if not null. + * @var string + */ + private $_queuedData = null; + + /** + * Array to hold the replacee-replacer pairs (String to String). + * @var array + */ + private $_tokens = array(); + + /** + * Array to hold the token sources that make tokens from + * different sources available + * @var array + */ + private $_tokensources = array(); + + /** + * Array holding all tokens given directly to the Filter and + * those passed via a TokenSource. + * @var array + */ + private $_alltokens = null; + + /** + * Character marking the beginning of a token. + * @var string + */ + private $_beginToken = "@"; // self::DEFAULT_BEGIN_TOKEN; + + /** + * Character marking the end of a token. + * @var string + */ + private $_endToken = "@"; //self::DEFAULT_END_TOKEN; + + /** + * Performs lookup on key and returns appropriate replacement string. + * @param array $matches Array of 1 el containing key to search for. + * @return string Text with which to replace key or value of key if none is found. + * @access private + */ + private function replaceTokenCallback($matches) { + + $key = $matches[1]; + + /* Get tokens from tokensource and merge them with the + * tokens given directly via build file. This should be + * done a bit more elegantly + */ + if ($this->_alltokens === null) { + $this->_alltokens = array(); + + $count = count($this->_tokensources); + for ($i = 0; $i < $count; $i++) { + $source = $this->_tokensources[$i]; + $this->_alltokens = array_merge($this->_alltokens, $source->getTokens()); + } + + + $this->_alltokens = array_merge($this->_tokens, $this->_alltokens); + } + + $tokens = $this->_alltokens; + + $replaceWith = null; + $count = count($tokens); + + for ($i = 0; $i < $count; $i++) { + if ($tokens[$i]->getKey() === $key) { + $replaceWith = $tokens[$i]->getValue(); + } + } + + if ($replaceWith === null) { + $replaceWith = $this->_beginToken . $key . $this->_endToken; + $this->log("No token defined for key \"".$this->_beginToken . $key . $this->_endToken."\""); + } else { + $this->log("Replaced \"".$this->_beginToken . $key . $this->_endToken ."\" with \"".$replaceWith."\""); + } + + return $replaceWith; + } + + /** + * Returns stream with tokens having been replaced with appropriate values. + * If a replacement value is not found for a token, the token is left in the stream. + * + * @return mixed filtered stream, -1 on EOF. + */ + function read($len = null) { + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + // read from next filter up the chain + $buffer = $this->in->read($len); + + if($buffer === -1) { + return -1; + } + + // filter buffer + $buffer = preg_replace_callback( + "/".preg_quote($this->_beginToken)."([\w\.\-:]+?)".preg_quote($this->_endToken)."/", + array($this, 'replaceTokenCallback'), $buffer); + + return $buffer; + } + + /** + * Sets the "begin token" character. + * + * @param string $beginToken the character used to denote the beginning of a token. + */ + function setBeginToken($beginToken) { + $this->_beginToken = (string) $beginToken; + } + + /** + * Returns the "begin token" character. + * + * @return string The character used to denote the beginning of a token. + */ + function getBeginToken() { + return $this->_beginToken; + } + + /** + * Sets the "end token" character. + * + * @param string $endToken the character used to denote the end of a token + */ + function setEndToken($endToken) { + $this->_endToken = (string) $endToken; + } + + /** + * Returns the "end token" character. + * + * @return the character used to denote the beginning of a token + */ + function getEndToken() { + return $this->_endToken; + } + + /** + * Adds a token element to the map of tokens to replace. + * + * @return object The token added to the map of replacements. + * Must not be null. + */ + function createToken() { + $num = array_push($this->_tokens, new Token()); + return $this->_tokens[$num-1]; + } + + /** + * Adds a token source to the sources of this filter. + * + * @return object A Reference to the source just added. + */ + function createTokensource() { + $num = array_push($this->_tokensources, new TokenSource()); + return $this->_tokensources[$num-1]; + } + + /** + * Sets the map of tokens to replace. + * ; used by ReplaceTokens::chain() + * + * @param array A map (String->String) of token keys to replacement + * values. Must not be null. + */ + function setTokens($tokens) { + // type check, error must never occur, bad code of it does + if ( !is_array($tokens) ) { + throw new Exception("Excpected 'array', got something else"); + } + + $this->_tokens = $tokens; + } + + /** + * Returns the map of tokens which will be replaced. + * ; used by ReplaceTokens::chain() + * + * @return array A map (String->String) of token keys to replacement values. + */ + function getTokens() { + return $this->_tokens; + } + + /** + * Sets the tokensources to use; used by ReplaceTokens::chain() + * + * @param array An array of token sources. + */ + function setTokensources($sources) { + // type check + if ( !is_array($sources)) { + throw new Exception("Exspected 'array', got something else"); + } + $this->_tokensources = $sources; + } + + /** + * Returns the token sources used by this filter; used by ReplaceTokens::chain() + * + * @return array + */ + function getTokensources() { + return $this->_tokensources; + } + + /** + * Creates a new ReplaceTokens using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new ReplaceTokens($reader); + $newFilter->setProject($this->getProject()); + $newFilter->setBeginToken($this->getBeginToken()); + $newFilter->setEndToken($this->getEndToken()); + $newFilter->setTokens($this->getTokens()); + $newFilter->setTokensources($this->getTokensources()); + $newFilter->setInitialized(true); + return $newFilter; + } + + /** + * Initializes tokens and loads the replacee-replacer hashtable. + * This method is only called when this filter is used through + * a tag in build file. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0 ; $igetType(); + if ( $type === "tokenchar" ) { + $name = $params[$i]->getName(); + if ( $name === "begintoken" ) { + $this->_beginToken = substr($params[$i]->getValue(), 0, 1); + } else if ( $name === "endtoken" ) { + $this->_endToken = substr($params[$i]->getValue(), 0, 1); + } + } else if ( $type === "token" ) { + $name = $params[$i]->getName(); + $value = $params[$i]->getValue(); + + $tok = new Token(); + $tok->setKey($name); + $tok->setValue($value); + + array_push($this->_tokens, $tok); + } else if ( $type === "tokensource" ) { + // Store data from nested tags in local array + $arr = array(); $subparams = $params[$i]->getParams(); + $count = count($subparams); + for ($i = 0; $i < $count; $i++) { + $arr[$subparams[$i]->getName()] = $subparams[$i]->getValue(); + } + + // Create TokenSource + $tokensource = new TokenSource(); + if (isset($arr["classname"])) + $tokensource->setClassname($arr["classname"]); + + // Copy other parameters 1:1 to freshly created TokenSource + foreach ($arr as $key => $value) { + if (strtolower($key) === "classname") + continue; + $param = $tokensource->createParam(); + $param->setName($key); + $param->setValue($value); + } + + $this->_tokensources[] = $tokensource; + } + } + } + } + } +} + +/** + * Holds a token. + */ +class Token { + + /** + * Token key. + * @var string + */ + private $_key; + + /** + * Token value. + * @var string + */ + private $_value; + + /** + * Sets the token key. + * + * @param string $key The key for this token. Must not be null. + */ + function setKey($key) { + $this->_key = (string) $key; + } + + /** + * Sets the token value. + * + * @param string $value The value for this token. Must not be null. + */ + function setValue($value) { + $this->_value = (string) $value; + } + + /** + * Returns the key for this token. + * + * @return string The key for this token. + */ + function getKey() { + return $this->_key; + } + + /** + * Returns the value for this token. + * + * @return string The value for this token. + */ + function getValue() { + return $this->_value; + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/StripLineBreaks.php b/gulliver/thirdparty/phing/filters/StripLineBreaks.php new file mode 100644 index 000000000..7dcd5d23d --- /dev/null +++ b/gulliver/thirdparty/phing/filters/StripLineBreaks.php @@ -0,0 +1,148 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Filter to flatten the stream to a single line. + * + * Example: + * + *
    + * + * Or: + * + *
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.8 $ $Date: 2004/03/15 14:45:06 $ + * @access public + * @see BaseParamFilterReader + * @package phing.filters + */ +class StripLineBreaks extends BaseParamFilterReader implements ChainableReader { + + /** + * Default line-breaking characters. + * @var string + */ + const DEFAULT_LINE_BREAKS = "\r\n"; + + /** + * Parameter name for the line-breaking characters parameter. + * @var string + */ + const LINES_BREAKS_KEY = "linebreaks"; + + /** + * The characters that are recognized as line breaks. + * @var string + */ + private $_lineBreaks = "\r\n"; // self::DEFAULT_LINE_BREAKS; + + /** + * Returns the filtered stream, only including + * characters not in the set of line-breaking characters. + * + * @return mixed the resulting stream, or -1 + * if the end of the resulting stream has been reached. + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + if($buffer === -1) { + return -1; + } + + $buffer = preg_replace("/[".$this->_lineBreaks."]/", '', $buffer); + + return $buffer; + } + + /** + * Sets the line-breaking characters. + * + * @param string $lineBreaks A String containing all the characters to be + * considered as line-breaking. + */ + function setLineBreaks($lineBreaks) { + $this->_lineBreaks = (string) $lineBreaks; + } + + /** + * Gets the line-breaking characters. + * + * @return string A String containing all the characters that are considered as line-breaking. + */ + function getLineBreaks() { + return $this->_lineBreaks; + } + + /** + * Creates a new StripLineBreaks using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new StripLineBreaks($reader); + $newFilter->setLineBreaks($this->getLineBreaks()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Parses the parameters to set the line-breaking characters. + */ + private function _initialize() { + $userDefinedLineBreaks = null; + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0 ; $igetName() ) { + $userDefinedLineBreaks = $params[$i]->getValue(); + break; + } + } + } + + if ( $userDefinedLineBreaks !== null ) { + $this->_lineBreaks = $userDefinedLineBreaks; + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/StripLineComments.php b/gulliver/thirdparty/phing/filters/StripLineComments.php new file mode 100644 index 000000000..1f1249bf7 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/StripLineComments.php @@ -0,0 +1,205 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/* + * This filter strips line comments. + * + * Example: + * + *
    
    + *   
    + *   
    + *   
    + *   
    + *   
    + * 
    + * + * Or: + * + *
    
    + *   
    + *   
    + *   
    + *   
    + *   
    + * 
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.8 $ $Date: 2005/02/27 20:52:08 $ + * @access public + * @see BaseParamFilterReader + * @package phing.filters + */ +class StripLineComments extends BaseParamFilterReader implements ChainableReader { + + /** Parameter name for the comment prefix. */ + const COMMENTS_KEY = "comment"; + + /** Array that holds the comment prefixes. */ + private $_comments = array(); + + /** + * Returns stream only including + * lines from the original stream which don't start with any of the + * specified comment prefixes. + * + * @return mixed the resulting stream, or -1 + * if the end of the resulting stream has been reached. + * + * @throws IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + + if ($buffer === -1) { + return -1; + } + + $lines = explode("\n", $buffer); + $filtered = array(); + + $commentsSize = count($this->_comments); + + foreach($lines as $line) { + for($i = 0; $i < $commentsSize; $i++) { + $comment = $this->_comments[$i]->getValue(); + if ( StringHelper::startsWith($comment, ltrim($line)) ) { + $line = null; + break; + } + } + if ($line !== null) { + $filtered[] = $line; + } + } + + $filtered_buffer = implode("\n", $filtered); + return $filtered_buffer; + } + + /* + * Adds a comment element to the list of prefixes. + * + * @return comment The comment element added to the + * list of comment prefixes to strip. + */ + function createComment() { + $num = array_push($this->_comments, new Comment()); + return $this->_comments[$num-1]; + } + + /* + * Sets the list of comment prefixes to strip. + * + * @param comments A list of strings, each of which is a prefix + * for a comment line. Must not be null. + */ + function setComments($lineBreaks) { + if (!is_array($lineBreaks)) { + throw new Exception("Excpected 'array', got something else"); + } + $this->_comments = $lineBreaks; + } + + /* + * Returns the list of comment prefixes to strip. + * + * @return array The list of comment prefixes to strip. + */ + function getComments() { + return $this->_comments; + } + + /* + * Creates a new StripLineComments using the passed in + * Reader for instantiation. + * + * @param reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return a new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new StripLineComments($reader); + $newFilter->setComments($this->getComments()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /* + * Parses the parameters to set the comment prefixes. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0 ; $igetType() ) { + $comment = new Comment(); + $comment->setValue($params[$i]->getValue()); + array_push($this->_comments, $comment); + } + } + } + } +} + +/* + * The class that holds a comment representation. +*/ +class Comment { + + /** The prefix for a line comment. */ + private $_value; + + /* + * Sets the prefix for this type of line comment. + * + * @param string $value The prefix for a line comment of this type. + * Must not be null. + */ + function setValue($value) { + $this->_value = (string) $value; + } + + /* + * Returns the prefix for this type of line comment. + * + * @return string The prefix for this type of line comment. + */ + function getValue() { + return $this->_value; + } +} +?> diff --git a/gulliver/thirdparty/phing/filters/StripPhpComments.php b/gulliver/thirdparty/phing/filters/StripPhpComments.php new file mode 100644 index 000000000..193b7e71a --- /dev/null +++ b/gulliver/thirdparty/phing/filters/StripPhpComments.php @@ -0,0 +1,190 @@ +. +*/ + +include_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * This is a Php comment and string stripper reader that filters + * those lexical tokens out for purposes of simple Php parsing. + * (if you have more complex Php parsing needs, use a real lexer). + * Since this class heavily relies on the single char read function, + * you are reccomended to make it work on top of a buffered reader. + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @version $Revision: 1.6 $ $Date: 2004/07/16 01:36:35 $ + * @access public + * @see FilterReader + * @package phing.filters + * @todo -c use new PHP functions to perform this instead of regex. + */ +class StripPhpComments extends BaseFilterReader implements ChainableReader { + /** + * The read-ahead character, used for effectively pushing a single + * character back. -1 indicates that no character is in the buffer. + */ + private $_readAheadCh = -1; + + /** + * Whether or not the parser is currently in the middle of a string + * literal. + * @var boolean + */ + private $_inString = false; + + /** + * Returns the stream without Php comments. + * + * @return the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @throws IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + $buffer = $this->in->read($len); + if($buffer === -1) { + return -1; + } + + // This regex replace /* */ and // style comments + $buffer = preg_replace('/\/\*[^*]*\*+([^\/*][^*]*\*+)*\/|\/\/[^\n]*|("(\\\\.|[^"\\\\])*"|\'(\\\\.|[^\'\\\\])*\'|.[^\/"\'\\\\]*)/s', "$2", $buffer); + + // The regex above is not identical to, but is based on the expression below: + // + // created by Jeffrey Friedl + // and later modified by Fred Curtis. + // s{ + // /\* ## Start of /* ... */ comment + // [^*]*\*+ ## Non-* followed by 1-or-more *'s + // ( + // [^/*][^*]*\*+ + // )* ## 0-or-more things which don't start with / + // ## but do end with '*' + // / ## End of /* ... */ comment + // + // | ## OR various things which aren't comments: + // + // ( + // " ## Start of " ... " string + // ( + // \\. ## Escaped char + // | ## OR + // [^"\\] ## Non "\ + // )* + // " ## End of " ... " string + // + // | ## OR + // + // ' ## Start of ' ... ' string + // ( + // \\. ## Escaped char + // | ## OR + // [^'\\] ## Non '\ + // )* + // ' ## End of ' ... ' string + // + // | ## OR + // + // . ## Anything other char + // [^/"'\\]* ## Chars which doesn't start a comment, string or escape + // ) + // }{$2}gxs; + + return $buffer; + } + + + /* + * Returns the next character in the filtered stream, not including + * Php comments. + * + * @return the next character in the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @throws IOException if the underlying stream throws an IOException + * during reading + * @deprecated + */ + function readChar() { + $ch = -1; + + if ( $this->_readAheadCh !== -1 ) { + $ch = $this->_readAheadCh; + $this->_readAheadCh = -1; + } else { + $ch = $this->in->readChar(); + if ( $ch === "\"" ) { + $this->_inString = !$this->_inString; + } else { + if ( !$this->_inString ) { + if ( $ch === "/" ) { + $ch = $this->in->readChar(); + if ( $ch === "/" ) { + while ( $ch !== "\n" && $ch !== -1 ) { + $ch = $this->in->readChar(); + } + } else if ( $ch === "*" ) { + while ( $ch !== -1 ) { + $ch = $this->in->readChar(); + while ( $ch === "*" && $ch !== -1 ) { + $ch = $this->in->readChar(); + } + + if ( $ch === "/" ) { + $ch = $this->readChar(); + echo "$ch\n"; + break; + } + } + } else { + $this->_readAheadCh = $ch; + $ch = "/"; + } + } + } + } + } + + return $ch; + } + + /** + * Creates a new StripJavaComments using the passed in + * Reader for instantiation. + * + * @param reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return a new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new StripPhpComments($reader); + $newFilter->setProject($this->getProject()); + return $newFilter; + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/filters/TabToSpaces.php b/gulliver/thirdparty/phing/filters/TabToSpaces.php new file mode 100644 index 000000000..3be1438dc --- /dev/null +++ b/gulliver/thirdparty/phing/filters/TabToSpaces.php @@ -0,0 +1,144 @@ +. +*/ + +require_once 'phing/filters/BaseParamFilterReader.php'; +require_once 'phing/filters/ChainableReader.php'; + +/** + * Converts tabs to spaces. + * + * Example: + * + *
    + * + * Or: + * + *
    
    + *   
    + * 
    + * + * @author Yannick Lecaillez + * @author Hans Lellelid + * @version $Revision: 1.9 $ + * @see BaseParamFilterReader + * @package phing.filters + */ +class TabToSpaces extends BaseParamFilterReader implements ChainableReader { + + /** + * The default tab length. + * @var int + */ + const DEFAULT_TAB_LENGTH = 8; + + /** + * Parameter name for the length of a tab. + * @var string + */ + const TAB_LENGTH_KEY = "tablength"; + + /** + * Tab length in this filter. + * @var int + */ + private $tabLength = 8; //self::DEFAULT_TAB_LENGTH; + + /** + * Returns stream after converting tabs to the specified number of spaces. + * + * @return the resulting stream, or -1 + * if the end of the resulting stream has been reached + * + * @exception IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + + if($buffer === -1) { + return -1; + } + + $buffer = str_replace("\t", str_repeat(' ', $this->tabLength), $buffer); + + return $buffer; + } + + /** + * Sets the tab length. + * + * @param int $tabLength The number of spaces to be used when converting a tab. + */ + function setTablength($tabLength) { + $this->tabLength = (int) $tabLength; + } + + /** + * Returns the tab length. + * + * @return int The number of spaces used when converting a tab + */ + function getTablength() { + return $this->tabLength; + } + + /** + * Creates a new TabsToSpaces using the passed in + * Reader for instantiation. + * + * @param Reader $reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return Reader A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new TabToSpaces($reader); + $newFilter->setTablength($this->getTablength()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Parses the parameters to set the tab length. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0 ; $igetName()) { + $this->tabLength = $params[$i]->getValue(); + break; + } + } + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/TailFilter.php b/gulliver/thirdparty/phing/filters/TailFilter.php new file mode 100644 index 000000000..634bb94a1 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/TailFilter.php @@ -0,0 +1,157 @@ +. +*/ + +require_once 'phing/filters/BaseParamFilterReader.php'; + +/** + * Reads the last n lines of a stream. (Default is last10 lines.) + * + * Example: + * + *
    + * + * Or: + * + *
    
    + *   
    + * 
    + * + * @author Yannick Lecaillez + * @author hans lellelid, hans@velum.net + * @copyright © 2003 seasonfive. All rights reserved + * @version $Revision: 1.7 $ + * @see BaseParamFilterReader + * @package phing.filters + */ +class TailFilter extends BaseParamFilterReader implements ChainableReader { + + /** + * Parameter name for the number of lines to be returned. + * @var string + */ + const LINES_KEY = "lines"; + + + /** + * Number of lines to be returned in the filtered stream. + * @var integer + */ + private $_lines = 10; + + /** + * Array to hold lines. + * @var array + */ + private $_lineBuffer = array(); + + /** + * Returns the last n lines of a file. + * @param int $len Num chars to read. + * @return mixed The filtered buffer or -1 if EOF. + */ + function read($len = null) { + + while ( ($buffer = $this->in->read($len)) !== -1 ) { + // Remove the last "\n" from buffer for + // prevent explode to add an empty cell at + // the end of array + $buffer= trim($buffer, "\n"); + + $lines = explode("\n", $buffer); + + if ( count($lines) >= $this->_lines ) { + // Buffer have more (or same) number of lines than needed. + // Fill lineBuffer with the last "$this->_lines" lasts ones. + $off = count($lines)-$this->_lines; + $this->_lineBuffer = array_slice($lines, $off); + } else { + // Some new lines ... + // Prepare space for insert these new ones + $this->_lineBuffer = array_slice($this->_lineBuffer, count($lines)-1); + $this->_lineBuffer = array_merge($this->_lineBuffer, $lines); + } + } + + if ( empty($this->_lineBuffer) ) + $ret = -1; + else { + $ret = implode("\n", $this->_lineBuffer); + $this->_lineBuffer = array(); + } + + return $ret; + } + + /** + * Sets the number of lines to be returned in the filtered stream. + * + * @param integer $lines the number of lines to be returned in the filtered stream. + */ + function setLines($lines) { + $this->_lines = (int) $lines; + } + + /** + * Returns the number of lines to be returned in the filtered stream. + * + * @return integer The number of lines to be returned in the filtered stream. + */ + function getLines() { + return $this->_lines; + } + + /** + * Creates a new TailFilter using the passed in + * Reader for instantiation. + * + * @param object A Reader object providing the underlying stream. + * Must not be null. + * + * @return object A new filter based on this configuration, but filtering + * the specified reader. + */ + function chain(Reader $reader) { + $newFilter = new TailFilter($reader); + $newFilter->setLines($this->getLines()); + $newFilter->setInitialized(true); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Scans the parameters list for the "lines" parameter and uses + * it to set the number of lines to be returned in the filtered stream. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i=0, $_i=count($params); $i < $_i; $i++) { + if ( self::LINES_KEY == $params[$i]->getName() ) { + $this->_lines = (int) $params[$i]->getValue(); + break; + } + } + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/TidyFilter.php b/gulliver/thirdparty/phing/filters/TidyFilter.php new file mode 100644 index 000000000..8daee3d59 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/TidyFilter.php @@ -0,0 +1,162 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * This filter uses the bundled-with-PHP Tidy extension to filter input. + * + *

    + * Example:
    + *

    + * 
    + *   
    + *   
    + * 
    + * 
    + * + * @author Hans Lellelid + * @version $Revision: 1.2 $ $Date: 2005/12/08 19:15:20 $ + * @package phing.filters + */ +class TidyFilter extends BaseParamFilterReader implements ChainableReader { + + /** @var string Encoding of resulting document. */ + private $encoding = 'utf8'; + + /** @var array Parameter[] */ + private $configParameters = array(); + + /** + * Set the encoding for resulting (X)HTML document. + * @param string $v + */ + public function setEncoding($v) { + $this->encoding = $v; + } + + /** + * Sets the config params. + * @param array Parameter[] + * @see chain() + */ + public function setConfigParameters($params) + { + $this->configParameters = $params; + } + + /** + * Adds a element (which is a Parameter). + * @return Parameter + */ + public function createConfig() { + $num = array_push($this->configParameters, new Parameter()); + return $this->configParameters[$num-1]; + } + + /** + * Converts the Parameter objects being used to store configuration into a simle assoc array. + * @return array + */ + private function getDistilledConfig() { + $config = array(); + foreach($this->configParameters as $p) { + $config[$p->getName()] = $p->getValue(); + } + return $config; + } + + /** + * Reads input and returns Tidy-filtered output. + * + * @return the resulting stream, or -1 if the end of the resulting stream has been reached + * + * @throws IOException if the underlying stream throws an IOException + * during reading + */ + function read($len = null) { + + if (!class_exists('Tidy')) { + throw new BuildException("You must enable the 'tidy' extension in your PHP configuration in order to use the Tidy filter."); + } + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + $buffer = $this->in->read($len); + if($buffer === -1) { + return -1; + } + + $config = $this->getDistilledConfig(); + + $tidy = new Tidy(); + $tidy->parseString($buffer, $config, $this->encoding); + $tidy->cleanRepair(); + + return tidy_get_output($tidy); + + } + + + /** + * Creates a new TidyFilter using the passed in Reader for instantiation. + * + * @param reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return a new filter based on this configuration, but filtering + * the specified reader + */ + public function chain(Reader $reader) { + $newFilter = new TidyFilter($reader); + $newFilter->setConfigParameters($this->configParameters); + $newFilter->setEncoding($this->encoding); + $newFilter->setProject($this->getProject()); + return $newFilter; + } + + /** + * Initializes any parameters (e.g. config options). + * This method is only called when this filter is used through a tag in build file. + */ + private function _initialize() { + $params = $this->getParameters(); + if ($params) { + foreach($params as $param) { + if ($param->getType() == "config") { + $this->configParameters[] = $param; + } else { + + if ($param->getName() == "encoding") { + $this->setEncoding($param->getValue()); + } + + } + + } + } + } + +} diff --git a/gulliver/thirdparty/phing/filters/TranslateGettext.php b/gulliver/thirdparty/phing/filters/TranslateGettext.php new file mode 100644 index 000000000..6864777c5 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/TranslateGettext.php @@ -0,0 +1,285 @@ +. +*/ + +require_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Replaces gettext("message id") and _("message id") with the translated string. + * + * Gettext is great for creating multi-lingual sites, but in some cases (e.g. for + * performance reasons) you may wish to replace the gettext calls with the translations + * of the strings; that's what this task is for. Note that this is similar to + * ReplaceTokens, but both the find and the replace aspect is more complicated -- hence + * this is a separate, stand-alone filter. + * + *

    + * Example:
    + *

    + * 
    + * 
    + * + * @author Hans Lellelid + * @version $Revision: 1.11 $ $Date: 2005/12/08 15:59:56 $ + * @access public + * @see BaseFilterReader + * @package phing.filters + */ +class TranslateGettext extends BaseParamFilterReader implements ChainableReader { + + // constants for specifying keys to expect + // when this is called using + const DOMAIN_KEY = "domain"; + const DIR_KEY = "dir"; + const LOCALE_KEY = "locale"; + + /** The domain to use */ + private $domain = 'messages'; + + /** The dir containing LC_MESSAGES */ + private $dir; + + /** The locale to use */ + private $locale; + + /** The system locale before it was changed for this filter. */ + private $storedLocale; + + /** + * Set the text domain to use. + * The text domain must correspond to the name of the compiled .mo files. + * E.g. "messages" ==> $dir/LC_MESSAGES/messages.mo + * "mydomain" ==> $dir/LC_MESSAGES/mydomain.mo + * @param string $domain + */ + function setDomain($domain) { + $this->domain = $domain; + } + + /** + * Get the current domain. + * @return string + */ + function getDomain() { + return $this->domain; + } + + /** + * Sets the root locale directory. + * @param PhingFile $dir + */ + function setDir(PhingFile $dir) { + $this->dir = $dir; + } + + /** + * Gets the root locale directory. + * @return PhingFile + */ + function getDir() { + return $this->dir; + } + + /** + * Sets the locale to use for translation. + * Note that for gettext() to work, you have to make sure this locale + * is specific enough for your system (e.g. some systems may allow an 'en' locale, + * but others will require 'en_US', etc.). + * @param string $locale + */ + function setLocale($locale) { + $this->locale = $locale; + } + + /** + * Gets the locale to use for translation. + * @return string + */ + function getLocale() { + return $this->locale; + } + + /** + * Make sure that required attributes are set. + * @throws BuldException - if any required attribs aren't set. + */ + protected function checkAttributes() { + if (!$this->domain || !$this->locale || !$this->dir) { + throw new BuildException("You must specify values for domain, locale, and dir attributes."); + } + } + + /** + * Initialize the gettext/locale environment. + * This method will change some env vars and locale settings; the + * restoreEnvironment should put them all back :) + * + * @return void + * @throws BuildException - if locale cannot be set. + * @see restoreEnvironment() + */ + protected function initEnvironment() { + $this->storedLocale = getenv("LANG"); + + $this->log("Setting locale to " . $this->locale, PROJECT_MSG_DEBUG); + putenv("LANG=".$this->locale); + $ret = setlocale(LC_ALL, $this->locale); + if ($ret === false) { + $msg = "Could not set locale to " . $this->locale + . ". You may need to use fully qualified name" + . " (e.g. en_US instead of en)."; + throw new BuildException($msg); + } + + $this->log("Binding domain '".$this->domain."' to " . $this->dir, PROJECT_MSG_DEBUG); + bindtextdomain($this->domain, $this->dir->getAbsolutePath()); + textdomain($this->domain); + } + + /** + * Restores environment settings and locale. + * This does _not_ restore any gettext-specific settings + * (e.g. textdomain()). + * + * @return void + */ + protected function restoreEnvironment() { + putenv("LANG=".$this->storedLocale); + setlocale(LC_ALL, $this->storedLocale); + } + + /** + * Performs gettext translation of msgid and returns translated text. + * + * This function simply wraps gettext() call, but provides ability to log + * string replacements. (alternative would be using preg_replace with /e which + * would probably be faster, but no ability to debug/log.) + * + * @param array $matches Array of matches; we're interested in $matches[2]. + * @return string Translated text + */ + private function xlateStringCallback($matches) { + $charbefore = $matches[1]; + $msgid = $matches[2]; + $translated = gettext($msgid); + $this->log("Translating \"$msgid\" => \"$translated\"", PROJECT_MSG_DEBUG); + return $charbefore . '"' . $translated . '"'; + } + + /** + * Returns the filtered stream. + * The original stream is first read in fully, and then translation is performed. + * + * @return mixed the filtered stream, or -1 if the end of the resulting stream has been reached. + * + * @throws IOException - if the underlying stream throws an IOException during reading + * @throws BuildException - if the correct params are not supplied + */ + function read($len = null) { + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + // Make sure correct params/attribs have been set + $this->checkAttributes(); + + $buffer = $this->in->read($len); + if($buffer === -1) { + return -1; + } + + // Setup the locale/gettext environment + $this->initEnvironment(); + + + // replace any occurrences of _("") or gettext("") with + // the translated value. + // + // ([^\w]|^)_\("((\\"|[^"])*)"\) + // --$1--- -----$2---- + // ---$3-- [match escaped quotes or any char that's not a quote] + // + // also match gettext() -- same as above + + $buffer = preg_replace_callback('/([^\w]|^)_\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer); + $buffer = preg_replace_callback('/([^\w]|^)gettext\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer); + + // Check to see if there are any _('') calls and flag an error + + // Check to see if there are any unmatched gettext() calls -- and flag an error + + $matches = array(); + if (preg_match('/([^\w]|^)(gettext\([^\)]+\))/', $buffer, $matches)) { + $this->log("Unable to perform translation on: " . $matches[2], PROJECT_MSG_WARN); + } + + $this->restoreEnvironment(); + + return $buffer; + } + + /** + * Creates a new TranslateGettext filter using the passed in + * Reader for instantiation. + * + * @param Reader $reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return TranslateGettext A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new TranslateGettext($reader); + $newFilter->setProject($this->getProject()); + $newFilter->setDomain($this->getDomain()); + $newFilter->setLocale($this->getLocale()); + $newFilter->setDir($this->getDir()); + return $newFilter; + } + + /** + * Parses the parameters if this filter is being used in "generic" mode. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + foreach($params as $param) { + switch($param->getType()) { + case self::DOMAIN_KEY: + $this->setDomain($param->getValue()); + break; + case self::DIR_KEY: + $this->setDir($this->project->resolveFile($param->getValue())); + break; + + case self::LOCALE_KEY: + $this->setLocale($param->getValue()); + break; + } // switch + } + } // if params !== null + } +} + +?> diff --git a/gulliver/thirdparty/phing/filters/XsltFilter.php b/gulliver/thirdparty/phing/filters/XsltFilter.php new file mode 100644 index 000000000..d4f7ab6c2 --- /dev/null +++ b/gulliver/thirdparty/phing/filters/XsltFilter.php @@ -0,0 +1,317 @@ +. +*/ + +include_once 'phing/filters/BaseParamFilterReader.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Applies XSL stylesheet to incoming text. + * + * Uses PHP XSLT support (libxslt). + * + * @author Hans Lellelid + * @author Yannick Lecaillez + * @author Andreas Aderhold + * @version $Revision: 1.16 $ + * @see FilterReader + * @package phing.filters + */ +class XsltFilter extends BaseParamFilterReader implements ChainableReader { + + /** + * Path to XSL stylesheet. + * @var string + */ + private $xslFile = null; + + /** + * Whether XML file has been transformed. + * @var boolean + */ + private $processed = false; + + /** + * XSLT Params. + * @var array + */ + private $xsltParams = array(); + + /** + * Whether to use loadHTML() to parse the input XML file. + */ + private $html = false; + + /** + * Create new XSLT Param object, to handle the nested element. + * @return XSLTParam + */ + function createParam() { + $num = array_push($this->xsltParams, new XSLTParam()); + return $this->xsltParams[$num-1]; + } + + /** + * Sets the XSLT params for this class. + * This is used to "clone" this class, in the chain() method. + * @param array $params + */ + function setParams($params) { + $this->xsltParams = $params; + } + + /** + * Returns the XSLT params set for this class. + * This is used to "clone" this class, in the chain() method. + * @return array + */ + function getParams() { + return $this->xsltParams; + } + + /** + * Set the XSLT stylesheet. + * @param mixed $file PhingFile object or path. + */ + function setStyle(PhingFile $file) { + $this->xslFile = $file; + } + + /** + * Whether to use HTML parser for the XML. + * This is supported in libxml2 -- Yay! + * @return boolean + */ + function getHtml() { + return $this->html; + } + + /** + * Whether to use HTML parser for XML. + * @param boolean $b + */ + function setHtml($b) { + $this->html = (boolean) $b; + } + + /** + * Get the path to XSLT stylesheet. + * @return mixed XSLT stylesheet path. + */ + function getStyle() { + return $this->xslFile; + } + + /** + * Reads stream, applies XSLT and returns resulting stream. + * @return string transformed buffer. + * @throws BuildException - if XSLT support missing, if error in xslt processing + */ + function read($len = null) { + + if (!class_exists('XSLTProcessor')) { + throw new BuildException("Could not find the XSLTProcessor class. Make sure PHP has been compiled/configured to support XSLT."); + } + + if ($this->processed === true) { + return -1; // EOF + } + + if ( !$this->getInitialized() ) { + $this->_initialize(); + $this->setInitialized(true); + } + + // Read XML + $_xml = null; + while ( ($data = $this->in->read($len)) !== -1 ) + $_xml .= $data; + + if ($_xml === null ) { // EOF? + return -1; + } + + if(empty($_xml)) { + $this->log("XML file is empty!", PROJECT_MSG_WARN); + return ''; // return empty string, don't attempt to apply XSLT + } + + // Read XSLT + $_xsl = null; + $xslFr = new FileReader($this->xslFile); + $xslFr->readInto($_xsl); + + $this->log("Tranforming XML " . $this->in->getResource() . " using style " . $this->xslFile->getPath(), PROJECT_MSG_VERBOSE); + + $out = ''; + try { + $out = $this->process($_xml, $_xsl); + $this->processed = true; + } catch (IOException $e) { + throw new BuildException($e); + } + + return $out; + } + + // {{{ method _ProcessXsltTransformation($xml, $xslt) throws BuildException + /** + * Try to process the XSLT transformation + * + * @param string XML to process. + * @param string XSLT sheet to use for the processing. + * + * @throws BuildException On XSLT errors + */ + protected function process($xml, $xsl) { + + $processor = new XSLTProcessor(); + + $xmlDom = new DOMDocument(); + $xslDom = new DOMDocument(); + + if ($this->html) { + $xmlDom->loadHTML($xml); + } else { + $xmlDom->loadXML($xml); + } + + $xslDom->loadxml($xsl); + + $processor->importStylesheet($xslDom); + + // ignoring param "type" attrib, because + // we're only supporting direct XSL params right now + foreach($this->xsltParams as $param) { + $this->log("Setting XSLT param: " . $param->getName() . "=>" . $param->getExpression(), PROJECT_MSG_DEBUG); + $processor->setParameter(null, $param->getName(), $param->getExpression()); + } + + $result = $processor->transformToXML($xmlDom); + + if ( !$result ) { + //$errno = xslt_errno($processor); + //$err = xslt_error($processor); + throw new BuildException("XSLT Error"); + } else { + return $result; + } + } + + /** + * Creates a new XsltFilter using the passed in + * Reader for instantiation. + * + * @param Reader A Reader object providing the underlying stream. + * Must not be null. + * + * @return Reader A new filter based on this configuration, but filtering + * the specified reader + */ + function chain(Reader $reader) { + $newFilter = new XsltFilter($reader); + $newFilter->setProject($this->getProject()); + $newFilter->setStyle($this->getStyle()); + $newFilter->setInitialized(true); + $newFilter->setParams($this->getParams()); + $newFilter->setHtml($this->getHtml()); + return $newFilter; + } + + /** + * Parses the parameters to get stylesheet path. + */ + private function _initialize() { + $params = $this->getParameters(); + if ( $params !== null ) { + for($i = 0, $_i=count($params) ; $i < $_i; $i++) { + if ( $params[$i]->getType() === null ) { + if ($params[$i]->getName() === "style") { + $this->setStyle($params[$i]->getValue()); + } + } elseif ($params[$i]->getType() == "param") { + $xp = new XSLTParam(); + $xp->setName($params[$i]->getName()); + $xp->setExpression($params[$i]->getValue()); + $this->xsltParams[] = $xp; + } + } + } + } + +} + + +/** + * Class that holds an XSLT parameter. + */ +class XSLTParam { + + private $name; + + private $expr; + + /** + * Sets param name. + * @param string $name + */ + public function setName($name) { + $this->name = $name; + } + + /** + * Get param name. + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * Sets expression value. + * @param string $expr + */ + public function setExpression($expr) { + $this->expr = $expr; + } + + /** + * Sets expression to dynamic register slot. + * @param RegisterSlot $expr + */ + public function setListeningExpression(RegisterSlot $expr) { + $this->expr = $expr; + } + + /** + * Returns expression value -- performs lookup if expr is registerslot. + * @return string + */ + public function getExpression() { + if ($this->expr instanceof RegisterSlot) { + return $this->expr->getValue(); + } else { + return $this->expr; + } + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/filters/util/ChainReaderHelper.php b/gulliver/thirdparty/phing/filters/util/ChainReaderHelper.php new file mode 100644 index 000000000..a7347ed5b --- /dev/null +++ b/gulliver/thirdparty/phing/filters/util/ChainReaderHelper.php @@ -0,0 +1,184 @@ +. +*/ + +include_once 'phing/Project.php'; +include_once 'phing/filters/BaseFilterReader.php'; +include_once 'phing/types/PhingFilterReader.php'; +include_once 'phing/types/FilterChain.php'; +include_once 'phing/types/Parameter.php'; +include_once 'phing/util/FileUtils.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/filters/ChainableReader.php'; + +/** + * Process a FilterReader chain. + * + * Here, the interesting method is 'getAssembledReader'. + * The purpose of this one is to create a simple Reader object which + * apply all filters on another primary Reader object. + * + * For example : In copyFile (phing.util.FileUtils) the primary Reader + * is a FileReader object (more accuratly, a BufferedReader) previously + * setted for the source file to copy. So, consider this filterchain : + * + * + * + * + * + * + * + * + * + * getAssembledReader will return a Reader object wich read on each + * of these filters. Something like this : ('->' = 'which read data from') : + * + * [TABTOSPACES] -> [LINECONTAINS] -> [STRIPPHPCOMMENTS] -> [FILEREADER] + * (primary reader) + * + * So, getAssembledReader will return the TABTOSPACES Reader object. Then + * each read done with this Reader object will follow this path. + * + * Hope this explanation is clear :) + * + * TODO: Implement the classPath feature. + * + * @author Yannick Lecaillez + * @version $Revision: 1.8 $ $Date: 2005/02/27 20:52:09 $ + * @access public + * @package phing.filters.util +*/ +class ChainReaderHelper { + + /** Primary reader to wich the reader chain is to be attached */ + private $primaryReader = null; + + /** The site of the buffer to be used. */ + private $bufferSize = 8192; + + /** Chain of filters */ + private $filterChains = array(); + + /** The Phing project */ + private $project; + + /* + * Sets the primary reader + */ + function setPrimaryReader(Reader $reader) { + $this->primaryReader = $reader; + } + + /* + * Set the project to work with + */ + function setProject(Project $project) { + $this->project = $project; + } + + /* + * Get the project + */ + function getProject() { + return $this->project; + } + + /* + * Sets the buffer size to be used. Defaults to 8192, + * if this method is not invoked. + */ + function setBufferSize($size) { + $this->bufferSize = $size; + } + + /* + * Sets the collection of filter reader sets + */ + function setFilterChains(&$fchain) { + $this->filterChains = &$fchain; + } + + /* + * Assemble the reader + */ + function getAssembledReader() { + + $instream = $this->primaryReader; + $filterReadersCount = count($this->filterChains); + $finalFilters = array(); + + // Collect all filter readers of all filter chains used ... + for($i = 0 ; $i<$filterReadersCount ; $i++) { + $filterchain = &$this->filterChains[$i]; + $filterReaders = $filterchain->getFilterReaders(); + $readerCount = count($filterReaders); + for($j = 0 ; $j<$readerCount ; $j++) { + $finalFilters[] = $filterReaders[$j]; + } + } + + // ... then chain the filter readers. + $filtersCount = count($finalFilters); + if ( $filtersCount > 0 ) { + for($i = 0 ; $i<$filtersCount ; $i++) { + $filter = $finalFilters[$i]; + + if ( $filter instanceof PhingFilterReader ) { + + // This filter reader is an external class. + $className = $filter->getClassName(); + $classpath = $filter->getClasspath(); + $project = $filter->getProject(); + + if ( $className !== null ) { + $cls = Phing::import($className, $classpath); + $impl = new $cls(); + } + + if ( !($impl instanceof FilterReader) ) { + throw new Exception($className." does not extend phing.system.io.FilterReader"); + } + + $impl->setReader($instream); // chain + $impl->setProject($this->getProject()); // what about $project above ? + + if ( $impl instanceof Parameterizable ) { + $impl->setParameters($filter->getParams()); + } + + $instream = $impl; // now that it's been chained + + } elseif (($filter instanceof ChainableReader) && ($filter instanceof Reader)) { + if ( $this->getProject() !== null && ($filter instanceof BaseFilterReader) ) { + $filter->setProject($this->getProject()); + } + $instream = $filter->chain($instream); + } else { + throw new Exception("Cannot chain invalid filter: " . get_class($filter)); + } + } + } + + return $instream; + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/filters/util/IniFileTokenReader.php b/gulliver/thirdparty/phing/filters/util/IniFileTokenReader.php new file mode 100644 index 000000000..30800f6ef --- /dev/null +++ b/gulliver/thirdparty/phing/filters/util/IniFileTokenReader.php @@ -0,0 +1,96 @@ +. +*/ + +include_once 'phing/types/TokenReader.php'; +include_once 'phing/system/io/IOException.php'; +include_once 'phing/filters/ReplaceTokens.php'; // For class Token + +/** + * Class that allows reading tokens from INI files. + * + * @author Manuel Holtgewe + * @version $Revision: 1.7 $ + * @package phing.filters.util + */ +class IniFileTokenReader extends TokenReader { + + /** + * Holds the path to the INI file that is to be read. + * @var object Reference to a PhingFile Object representing + * the path to the INI file. + */ + private $file = null; + + /** + * @var string Sets the section to load from the INI file. + * if omitted, all sections are loaded. + */ + private $section = null; + + /** + * Reads the next token from the INI file + * + * @throws IOException On error + */ + function readToken() { + if ($this->file === null) { + throw new BuildException("No File set for IniFileTokenReader"); + } + + static $tokens = null; + if ($tokens === null) { + $tokens = array(); + $arr = parse_ini_file($this->file->getAbsolutePath(), true); + if ($this->section === null) { + foreach ($arr as $sec_name => $values) { + foreach($arr[$sec_name] as $key => $value) { + $tok = new Token; + $tok->setKey($key); + $tok->setValue($value); + $tokens[] = $tok; + } + } + } else if (isset($arr[$this->section])) { + foreach ($arr[$this->section] as $key => $value) { + $tok = new Token; + $tok->setKey($key); + $tok->setValue($value); + $tokens[] = $tok; + } + } + } + + if (count($tokens) > 0) { + return array_pop($tokens); + } else + return null; + } + + function setFile(PhingFile $file) { + $this->file = $file; + } + + function setSection($str) { + $this->section = (string) $str; + } +} + +?> diff --git a/gulliver/thirdparty/phing/input/DefaultInputHandler.php b/gulliver/thirdparty/phing/input/DefaultInputHandler.php new file mode 100644 index 000000000..a6ddde2b8 --- /dev/null +++ b/gulliver/thirdparty/phing/input/DefaultInputHandler.php @@ -0,0 +1,82 @@ +. + */ + +require_once 'phing/input/InputHandler.php'; +include_once 'phing/system/io/ConsoleReader.php'; + +/** + * Prompts using print(); reads input from Console. + * + * @author Hans Lellelid (Phing) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.6 $ + * @package phing.input + */ +class DefaultInputHandler implements InputHandler { + + /** + * Prompts and requests input. May loop until a valid input has + * been entered. + * @throws BuildException + */ + public function handleInput(InputRequest $request) { + $prompt = $this->getPrompt($request); + $in = new ConsoleReader(); + do { + print $prompt; + try { + $input = $in->readLine(); + if ($input === "" && ($request->getDefaultValue() !== null) ) { + $input = $request->getDefaultValue(); + } + $request->setInput($input); + } catch (Exception $e) { + throw new BuildException("Failed to read input from Console.", $e); + } + } while (!$request->isInputValid()); + } + + /** + * Constructs user prompt from a request. + * + *

    This implementation adds (choice1,choice2,choice3,...) to the + * prompt for MultipleChoiceInputRequests.

    + * + * @param $request the request to construct the prompt for. + * Must not be null. + */ + protected function getPrompt(InputRequest $request) { + $prompt = $request->getPrompt(); + + // use is_a() to avoid needing the class to be loaded + if (is_a($request, 'YesNoInputRequest')) { // (yes/no) + $prompt .= '(' . implode('/', $request->getChoices()) .')'; + } elseif (is_a($request, 'MultipleChoiceInputRequest')) { // (a,b,c,d) + $prompt .= '(' . implode(',', $request->getChoices()) . ')'; + } + if ($request->getDefaultValue() !== null) { + $prompt .= ' ['.$request->getDefaultValue().']'; + } + $pchar = $request->getPromptChar(); + return $prompt . ($pchar ? $pchar . ' ' : ' '); + } +} diff --git a/gulliver/thirdparty/phing/input/InputHandler.php b/gulliver/thirdparty/phing/input/InputHandler.php new file mode 100644 index 000000000..d11ab8822 --- /dev/null +++ b/gulliver/thirdparty/phing/input/InputHandler.php @@ -0,0 +1,45 @@ +. + */ + +/** + * Plugin to Phing to handle requests for user input. + * + * @author Stefan Bodewig + * @version $Revision: 1.3 $ + * @package phing.input + */ +interface InputHandler { + + /** + * Handle the request encapsulated in the argument. + * + *

    Precondition: the request.getPrompt will return a non-null + * value.

    + * + *

    Postcondition: request.getInput will return a non-null + * value, request.isInputValid will return true.

    + * @return void + * @throws BuildException + */ + public function handleInput(InputRequest $request); + +} diff --git a/gulliver/thirdparty/phing/input/InputRequest.php b/gulliver/thirdparty/phing/input/InputRequest.php new file mode 100644 index 000000000..4aece6582 --- /dev/null +++ b/gulliver/thirdparty/phing/input/InputRequest.php @@ -0,0 +1,107 @@ +. + */ + +/** + * Encapsulates an input request. + * + * @author Hans Lellelid (Phing) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.4 $ + * @package phing.input + */ +class InputRequest { + + protected $prompt; + protected $input; + protected $defaultValue; + protected $promptChar; + + /** + * @param string $prompt The prompt to show to the user. Must not be null. + */ + public function __construct($prompt) { + if ($prompt === null) { + throw new BuildException("prompt must not be null"); + } + $this->prompt = $prompt; + } + + /** + * Retrieves the prompt text. + */ + public function getPrompt() { + return $this->prompt; + } + + /** + * Sets the user provided input. + */ + public function setInput($input) { + $this->input = $input; + } + + /** + * Is the user input valid? + */ + public function isInputValid() { + return true; + } + + /** + * Retrieves the user input. + */ + public function getInput() { + return $this->input; + } + + /** + * Set the default value to use. + * @param mixed $v + */ + public function setDefaultValue($v) { + $this->defaultValue = $v; + } + + /** + * Return the default value to use. + * @return mixed + */ + public function getDefaultValue() { + return $this->defaultValue; + } + + /** + * Set the default value to use. + * @param string $c + */ + public function setPromptChar($c) { + $this->promptChar = $c; + } + + /** + * Return the default value to use. + * @return string + */ + public function getPromptChar() { + return $this->promptChar; + } +} diff --git a/gulliver/thirdparty/phing/input/MultipleChoiceInputRequest.php b/gulliver/thirdparty/phing/input/MultipleChoiceInputRequest.php new file mode 100644 index 000000000..ef9959b6a --- /dev/null +++ b/gulliver/thirdparty/phing/input/MultipleChoiceInputRequest.php @@ -0,0 +1,58 @@ +. + */ + +require_once 'phing/input/InputRequest.php'; + +/** + * Encapsulates an input request. + * + * @author Stefan Bodewig + * @version $Revision: 1.5 $ + * @package phing.input + */ +class MultipleChoiceInputRequest extends InputRequest { + + protected $choices = array(); + + /** + * @param string $prompt The prompt to show to the user. Must not be null. + * @param array $choices holds all input values that are allowed. + * Must not be null. + */ + public function __construct($prompt, $choices) { + parent::__construct($prompt); + $this->choices = $choices; + } + + /** + * @return The possible values. + */ + public function getChoices() { + return $this->choices; + } + + /** + * @return true if the input is one of the allowed values. + */ + public function isInputValid() { + return in_array($this->getInput(), $this->choices); // not strict (?) + } +} diff --git a/gulliver/thirdparty/phing/input/PropertyFileInputHandler.php b/gulliver/thirdparty/phing/input/PropertyFileInputHandler.php new file mode 100644 index 000000000..e588ceade --- /dev/null +++ b/gulliver/thirdparty/phing/input/PropertyFileInputHandler.php @@ -0,0 +1,129 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Ant" and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.input; + +import org.apache.tools.ant.BuildException; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +/** + * Reads input from a property file, the file name is read from the + * system property ant.input.properties, the prompt is the key for input. + * + * @author Stefan Bodewig + * @version $Revision: 1.1 $ + * @since Ant 1.5 + */ +public class PropertyFileInputHandler implements InputHandler { + private Properties props = null; + + /** + * Name of the system property we expect to hold the file name. + */ + public static final String FILE_NAME_KEY = "ant.input.properties"; + + /** + * Empty no-arg constructor. + */ + public PropertyFileInputHandler() { + } + + /** + * Picks up the input from a property, using the prompt as the + * name of the property. + * + * @exception BuildException if no property of that name can be found. + */ + public void handleInput(InputRequest request) throws BuildException { + readProps(); + + Object o = props.get(request.getPrompt()); + if (o == null) { + throw new BuildException("Unable to find input for \'" + + request.getPrompt()+"\'"); + } + request.setInput(o.toString()); + if (!request.isInputValid()) { + throw new BuildException("Found invalid input " + o + + " for \'" + request.getPrompt() + "\'"); + } + } + + /** + * Reads the properties file if it hasn't already been read. + */ + private synchronized void readProps() throws BuildException { + if (props == null) { + String propsFile = System.getProperty(FILE_NAME_KEY); + if (propsFile == null) { + throw new BuildException("System property " + + FILE_NAME_KEY + + " for PropertyFileInputHandler not" + + " set"); + } + + props = new Properties(); + + try { + props.load(new FileInputStream(propsFile)); + } catch (IOException e) { + throw new BuildException("Couldn't load " + propsFile, e); + } + } + } + +} diff --git a/gulliver/thirdparty/phing/input/YesNoInputRequest.php b/gulliver/thirdparty/phing/input/YesNoInputRequest.php new file mode 100644 index 000000000..d13f06de6 --- /dev/null +++ b/gulliver/thirdparty/phing/input/YesNoInputRequest.php @@ -0,0 +1,47 @@ +. + */ + +require_once 'phing/input/MultipleChoiceInputRequest.php'; + +/** + * Encapsulates an input request that returns a boolean (yes/no). + * + * @author Hans Lellelid + * @version $Revision: 1.4 $ + * @package phing.input + */ +class YesNoInputRequest extends MultipleChoiceInputRequest { + + /** + * @return true if the input is one of the allowed values. + */ + public function isInputValid() { + return StringHelper::isBoolean($this->input); + } + + /** + * Converts input to boolean. + * @return boolean + */ + public function getInput() { + return StringHelper::booleanValue($this->input); + } +} diff --git a/gulliver/thirdparty/phing/lib/Capsule.php b/gulliver/thirdparty/phing/lib/Capsule.php new file mode 100644 index 000000000..bab05486a --- /dev/null +++ b/gulliver/thirdparty/phing/lib/Capsule.php @@ -0,0 +1,266 @@ + + * @version $Revision: 1.9 $ $Date: 2004/08/31 20:12:02 $ + */ +class Capsule { + + /** + * Look for templates here (if relative path provided). + * @var string + */ + protected $templatePath; + + /** + * Where should output files be written? + * (This is named inconsistently to be compatible w/ Texen.) + * @var string + */ + protected $outputDirectory; + + /** + * The variables that can be used by the templates. + * @var array Hash of variables. + */ + public $vars = array(); + + /** + * Has template been initialized. + */ + protected $initialized = false; + + /** + * Stores the pre-parse() include_path. + * @var string + */ + private $old_include_path; + + function __construct() { + } + + /** + * Clears one or several or all variables. + * @param mixed $which String name of var, or array of names. + * @return void + */ + function clear($which = null) { + if ($which === null) { + $this->vars = array(); + } elseif (is_array($which)) { + foreach($which as $var) { + unset($this->vars[$var]); + } + } else { + unset($this->vars[$which]); + } + } + + /** + * Set the basepath to use for template lookups. + * @param string $v + */ + function setTemplatePath($v) { + $this->templatePath = rtrim($v, DIRECTORY_SEPARATOR.'/'); + } + + /** + * Get the basepath to use for template lookups. + * @return string + */ + function getTemplatePath() { + return $this->templatePath; + } + + /** + * Set a basepath to use for output file creation. + * @param string $v + */ + function setOutputDirectory($v) { + $this->outputDirectory = rtrim($v, DIRECTORY_SEPARATOR.'/'); + } + + /** + * Get basepath to use for output file creation. + * @return string + */ + function getOutputDirectory() { + return $this->outputDirectory; + } + + /** + * Low overhead (no output buffering) method to simply dump template + * to buffer. + * + * @param string $__template + * @return void + * @throws Exception - if template cannot be found + */ + function display($__template) { + + // Prepend "private" variable names with $__ in this function + // to keep namespace conflict potential to a minimum. + + // Alias this class to $generator. + $generator = $this; + + if (isset($this->vars['this'])) { + throw new Exception("Assigning a variable named \$this to a context conflicts with class namespace."); + } + + // extract variables into local namespace + extract($this->vars); + + // prepend template path to include path, + // so that include "path/relative/to/templates"; can be used within templates + $__old_inc_path = ini_get('include_path'); + ini_set('include_path', $this->templatePath . PATH_SEPARATOR . $__old_inc_path); + + @ini_set('track_errors', true); + include $__template; + @ini_restore('track_errors'); + + // restore the include path + ini_set('include_path', $__old_inc_path); + + if (!empty($php_errormsg)) { + throw new Exception("Unable to parse template " . $__template . ": " . $php_errormsg); + } + } + + /** + * Fetches the results of a tempalte parse and either returns + * the string or writes results to a specified output file. + * + * @param string $template The template filename (relative to templatePath or absolute). + * @param string $outputFile If specified, contents of template will also be written to this file. + * @param boolean $append Should output be appended to source file? + * @return string The "parsed" template output. + * @throws Exception - if template not found. + */ + function parse($template, $outputFile = null, $append = false) { + + // main work done right here: + // hopefully this works recursively ... fingers crossed. + ob_start(); + + try { + $this->display($template); + } catch (Exception $e) { + ob_end_flush(); // flush the output on error (so we can see up to what point it parsed everything) + throw $e; + } + + $output = ob_get_contents(); + ob_end_clean(); + + if ($outputFile !== null) { + $outputFile = $this->resolvePath($outputFile, $this->outputDirectory); + + $flags = null; + if ($append) $flags = FILE_APPEND; + + if (!file_put_contents($outputFile, $output, $flags) && $output != "") { + throw new Exception("Unable to write output to " . $outputFile); + } + } + + return $output; + } + + /** + * This returns a "best guess" path for the given file. + * + * @param string $file File name or possibly absolute path. + * @param string $basepath The basepath that should be prepended if $file is not absolute. + * @return string "Best guess" path for this file. + */ + protected function resolvePath($file, $basepath) { + if ( !($file{0} == DIRECTORY_SEPARATOR || $file{0} == '/') + // also account for C:\ style path + && !($file{1} == ':' && ($file{2} == DIRECTORY_SEPARATOR || $file{2} == '/'))) { + if ($basepath != null) { + $file = $basepath . DIRECTORY_SEPARATOR . $file; + } + } + return $file; + } + + /** + * Gets value of specified var or NULL if var has not been put(). + * @param string $name Variable name to retrieve. + * @return mixed + */ + function get($name) { + if (!isset($this->vars[$name])) return null; + return $this->vars[$name]; + } + + /** + * Merges in passed hash to vars array. + * + * Given an array like: + * + * array( 'myvar' => 'Hello', + * 'myvar2' => 'Hello') + * + * Resulting template will have access to $myvar and $myvar2. + * + * @param array $vars + * @param boolean $recursiveMerge Should matching keys be recursively merged? + * @return void + */ + function putAll($vars, $recursiveMerge = false) { + if ($recursiveMerge) { + $this->vars = array_merge_recursive($this->vars, $vars); + } else { + $this->vars = array_merge($this->vars, $vars); + } + } + + /** + * Adds a variable to the context. + * + * Resulting template will have access to ${$name$} variable. + * + * @param string $name + * @param mixed $value + */ + function put($name, $value) { + $this->vars[$name] = $value; + } + + /** + * Put a variable into the context, assigning it by reference. + * This means that if the template modifies the variable, then it + * will also be modified in the context. + * + * @param $name + * @param &$value + */ + function putRef($name, &$value) { + $this->vars[$name] = &$value; + } + + /** + * Makes a copy of the value and puts it into the context. + * This is primarily to force copying (cloning) of objects, rather + * than the default behavior which is to assign them by reference. + * @param string $name + * @param mixed $value + */ + function putCopy($name, $value) { + if (is_object($value)) { + $value = clone $value; + } + $this->vars[$name] = $value; + } + +} \ No newline at end of file diff --git a/gulliver/thirdparty/phing/lib/Zip.php b/gulliver/thirdparty/phing/lib/Zip.php new file mode 100644 index 000000000..c0995f1af --- /dev/null +++ b/gulliver/thirdparty/phing/lib/Zip.php @@ -0,0 +1,3588 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Zip.php 3076 2006-12-18 08:52:12Z fabien $ + + // ----- Constants + define( 'ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048 ); + + // ----- File list separator + define( 'ARCHIVE_ZIP_SEPARATOR', ',' ); + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', 'C:/Temp/' ); + define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '' ); + + // ----- Error codes + define( 'ARCHIVE_ZIP_ERR_NO_ERROR', 0 ); + define( 'ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'ARCHIVE_ZIP_ERR_MISSING_FILE', -4 ); + define( 'ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_ZIP', -6 ); + define( 'ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9 ); + define( 'ARCHIVE_ZIP_ERR_BAD_FORMAT', -10 ); + define( 'ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16 ); + + // ----- Warning codes + define( 'ARCHIVE_ZIP_WARN_NO_WARNING', 0 ); + define( 'ARCHIVE_ZIP_WARN_FILE_EXIST', 1 ); + + // ----- Methods parameters + define( 'ARCHIVE_ZIP_PARAM_PATH', 'path' ); + define( 'ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path' ); + define( 'ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path' ); + define( 'ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path' ); + define( 'ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod' ); + define( 'ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string' ); + define( 'ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression' ); + define( 'ARCHIVE_ZIP_PARAM_BY_NAME', 'by_name' ); + define( 'ARCHIVE_ZIP_PARAM_BY_INDEX', 'by_index' ); + define( 'ARCHIVE_ZIP_PARAM_BY_EREG', 'by_ereg' ); + define( 'ARCHIVE_ZIP_PARAM_BY_PREG', 'by_preg' ); + + define( 'ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract' ); + define( 'ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract' ); + define( 'ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add' ); + define( 'ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add' ); + + + +/** +* Class for manipulating zip archive files +* +* A class which provided common methods to manipulate ZIP formatted +* archive files. +* It provides creation, extraction, deletion and add features. +* +* @author Vincent Blavet +* @version $Revision: 1.3 $ +* @package phing.lib +*/ +class Archive_Zip +{ + /** + * The filename of the zip archive. + * + * @var string Name of the Zip file + */ + var $_zipname=''; + + /** + * File descriptor of the opened Zip file. + * + * @var int Internal zip file descriptor + */ + var $_zip_fd=0; + + /** + * @var int last error code + */ + var $_error_code=1; + + /** + * @var string Last error description + */ + var $_error_string=''; + + // {{{ constructor + /** + * Archive_Zip Class constructor. This flavour of the constructor only + * declare a new Archive_Zip object, identifying it by the name of the + * zip file. + * + * @param string $p_zipname The name of the zip archive to create + * @access public + */ + function __construct($p_zipname) + { + if (!extension_loaded('zlib')) { + throw new Exception("The extension 'zlib' couldn't be found.\n". + "Please make sure your version of PHP was built ". + "with 'zlib' support."); + } + + // ----- Set the attributes + $this->_zipname = $p_zipname; + $this->_zip_fd = 0; + } + // }}} + + // {{{ create() + /** + * This method creates a Zip Archive with the filename set with + * the constructor. + * The files and directories indicated in $p_filelist + * are added in the archive. + * When a directory is in the list, the directory and its content is added + * in the archive. + * The methods takes a variable list of parameters in $p_params. + * The supported parameters for this method are : + * 'add_path' : Add a path to the archived files. + * 'remove_path' : Remove the specified 'root' path of the archived files. + * 'remove_all_path' : Remove all the path of the archived files. + * 'no_compression' : The archived files will not be compressed. + * + * @access public + * @param mixed $p_filelist The list of the files or folders to add. + * It can be a string with filenames separated + * by a comma, or an array of filenames. + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * an error code on error + */ + function create($p_filelist, $p_params=0) + { + $this->_errorReset(); + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array('no_compression' => false, + 'add_path' => "", + 'remove_path' => "", + 'remove_all_path' => false)) != 1) { + return 0; + } + + // ----- Look if the $p_filelist is really an array + $p_result_list = array(); + if (is_array($p_filelist)) { + $v_result = $this->_create($p_filelist, $p_result_list, $p_params); + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list with the elements from the string + $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist); + + $v_result = $this->_create($v_list, $p_result_list, $p_params); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Invalid variable type p_filelist'); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + if ($v_result != 1) { + return 0; + } + + return $p_result_list; + } + // }}} + + // {{{ add() + /** + * This method add files or directory in an existing Zip Archive. + * If the Zip Archive does not exist it is created. + * The files and directories to add are indicated in $p_filelist. + * When a directory is in the list, the directory and its content is added + * in the archive. + * The methods takes a variable list of parameters in $p_params. + * The supported parameters for this method are : + * 'add_path' : Add a path to the archived files. + * 'remove_path' : Remove the specified 'root' path of the archived files. + * 'remove_all_path' : Remove all the path of the archived files. + * 'no_compression' : The archived files will not be compressed. + * 'callback_pre_add' : A callback function that will be called before + * each entry archiving. + * 'callback_post_add' : A callback function that will be called after + * each entry archiving. + * + * @access public + * @param mixed $p_filelist The list of the files or folders to add. + * It can be a string with filenames separated + * by a comma, or an array of filenames. + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function add($p_filelist, $p_params=0) + { + $this->_errorReset(); + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array ('no_compression' => false, + 'add_path' => '', + 'remove_path' => '', + 'remove_all_path' => false, + 'callback_pre_add' => '', + 'callback_post_add' => '')) != 1) { + return 0; + } + + // ----- Look if the $p_filelist is really an array + $p_result_list = array(); + if (is_array($p_filelist)) { + // ----- Call the create fct + $v_result = $this->_add($p_filelist, $p_result_list, $p_params); + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list with the elements from the string + $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist); + + // ----- Call the create fct + $v_result = $this->_add($v_list, $p_result_list, $p_params); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "add() : Invalid variable type p_filelist"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + if ($v_result != 1) { + return 0; + } + + // ----- Return the result list + return $p_result_list; + } + // }}} + + // {{{ listContent() + /** + * This method gives the names and properties of the files and directories + * which are present in the zip archive. + * The properties of each entries in the list are : + * filename : Name of the file. + * For create() or add() it's the filename given by the user. + * For an extract() it's the filename of the extracted file. + * stored_filename : Name of the file / directory stored in the archive. + * size : Size of the stored file. + * compressed_size : Size of the file's data compressed in the archive + * (without the zip headers overhead) + * mtime : Last known modification date of the file (UNIX timestamp) + * comment : Comment associated with the file + * folder : true | false (indicates if the entry is a folder) + * index : index of the file in the archive (-1 when not available) + * status : status of the action on the entry (depending of the action) : + * Values are : + * ok : OK ! + * filtered : the file/dir was not extracted (filtered by user) + * already_a_directory : the file can't be extracted because a + * directory with the same name already + * exists + * write_protected : the file can't be extracted because a file + * with the same name already exists and is + * write protected + * newer_exist : the file was not extracted because a newer + * file already exists + * path_creation_fail : the file is not extracted because the + * folder does not exists and can't be + * created + * write_error : the file was not extracted because there was a + * error while writing the file + * read_error : the file was not extracted because there was a + * error while reading the file + * invalid_header : the file was not extracted because of an + * archive format error (bad file header) + * Note that each time a method can continue operating when there + * is an error on a single file, the error is only logged in the file status. + * + * @access public + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function listContent() + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + $v_list = array(); + if ($this->_list($v_list) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + // {{{ extract() + /** + * This method extract the files and folders which are in the zip archive. + * It can extract all the archive or a part of the archive by using filter + * feature (extract by name, by index, by ereg, by preg). The extraction + * can occur in the current path or an other path. + * All the advanced features are activated by the use of variable + * parameters. + * The return value is an array of entry descriptions which gives + * information on extracted files (See listContent()). + * The method may return a success value (an array) even if some files + * are not correctly extracted (see the file status in listContent()). + * The supported variable parameters for this method are : + * 'add_path' : Path where the files and directories are to be extracted + * 'remove_path' : First part ('root' part) of the memorized path + * (if similar) to remove while extracting. + * 'remove_all_path' : Remove all the memorized path while extracting. + * 'extract_as_string' : + * 'set_chmod' : After the extraction of the file the indicated mode + * will be set. + * 'by_name' : It can be a string with file/dir names separated by ',', + * or an array of file/dir names to extract from the archive. + * 'by_index' : A string with range of indexes separated by ',', + * (sample "1,3-5,12"). + * 'by_ereg' : A regular expression (ereg) that must match the extracted + * filename. + * 'by_preg' : A regular expression (preg) that must match the extracted + * filename. + * 'callback_pre_extract' : A callback function that will be called before + * each entry extraction. + * 'callback_post_extract' : A callback function that will be called after + * each entry extraction. + * + * @access public + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function extract($p_params=0) + { + + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Set default values + if ($p_params === 0) { + $p_params = array(); + } + if ($this->_check_parameters($p_params, + array ('extract_as_string' => false, + 'add_path' => '', + 'remove_path' => '', + 'remove_all_path' => false, + 'callback_pre_extract' => '', + 'callback_post_extract' => '', + 'set_chmod' => 0, + 'by_name' => '', + 'by_index' => '', + 'by_ereg' => '', + 'by_preg' => '') ) != 1) { + return 0; + } + + // ----- Call the extracting fct + $v_list = array(); + if ($this->_extractByRule($v_list, $p_params) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + + // {{{ delete() + /** + * This methods delete archive entries in the zip archive. + * Notice that at least one filtering rule (set by the variable parameter + * list) must be set. + * Also notice that if you delete a folder entry, only the folder entry + * is deleted, not all the files bellonging to this folder. + * The supported variable parameters for this method are : + * 'by_name' : It can be a string with file/dir names separated by ',', + * or an array of file/dir names to delete from the archive. + * 'by_index' : A string with range of indexes separated by ',', + * (sample "1,3-5,12"). + * 'by_ereg' : A regular expression (ereg) that must match the extracted + * filename. + * 'by_preg' : A regular expression (preg) that must match the extracted + * filename. + * + * @access public + * @param mixed $p_params An array of variable parameters and values. + * @return mixed An array of file description on success, + * 0 on an unrecoverable failure, an error code is logged. + */ + function delete($p_params) + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Set default values + if ($this->_check_parameters($p_params, + array ('by_name' => '', + 'by_index' => '', + 'by_ereg' => '', + 'by_preg' => '') ) != 1) { + return 0; + } + + // ----- Check that at least one rule is set + if ( ($p_params['by_name'] == '') + && ($p_params['by_index'] == '') + && ($p_params['by_ereg'] == '') + && ($p_params['by_preg'] == '')) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'At least one filtering rule must' + .' be set as parameter'); + return 0; + } + + // ----- Call the delete fct + $v_list = array(); + if ($this->_deleteByRule($v_list, $p_params) != 1) { + unset($v_list); + return(0); + } + + return $v_list; + } + // }}} + + // {{{ properties() + /** + * This method gives the global properties of the archive. + * The properties are : + * nb : Number of files in the archive + * comment : Comment associated with the archive file + * status : not_exist, ok + * + * @access public + * @param mixed $p_params {Description} + * @return mixed An array with the global properties or 0 on error. + */ + function properties() + { + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->_zipname)) { + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive \''.$this->_zipname + .'\' in binary read mode'); + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) { + return 0; + } + + $this->_closeFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + return $v_prop; + } + // }}} + + + // {{{ duplicate() + /** + * This method creates an archive by copying the content of an other one. + * If the archive already exist, it is replaced by the new one without + * any warning. + * + * @access public + * @param mixed $p_archive It can be a valid Archive_Zip object or + * the filename of a valid zip archive. + * @return integer 1 on success, 0 on failure. + */ + function duplicate($p_archive) + { + $this->_errorReset(); + + // ----- Look if the $p_archive is a Archive_Zip object + if ( (is_object($p_archive)) + && (strtolower(get_class($p_archive)) == 'archive_zip')) { + $v_result = $this->_duplicate($p_archive->_zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) { + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "No file with filename '".$p_archive."'"); + $v_result = ARCHIVE_ZIP_ERR_MISSING_FILE; + } + else { + $v_result = $this->_duplicate($p_archive); + } + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "Invalid variable type p_archive_to_add"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + return $v_result; + } + // }}} + + // {{{ merge() + /** + * This method merge a valid zip archive at the end of the + * archive identified by the Archive_Zip object. + * If the archive ($this) does not exist, the merge becomes a duplicate. + * If the archive to add does not exist, the merge is a success. + * + * @access public + * @param mixed $p_archive_to_add It can be a valid Archive_Zip object or + * the filename of a valid zip archive. + * @return integer 1 on success, 0 on failure. + */ + function merge($p_archive_to_add) + { + $v_result = 1; + $this->_errorReset(); + + // ----- Check archive + if (!$this->_checkFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a Archive_Zip object + if ( (is_object($p_archive_to_add)) + && (strtolower(get_class($p_archive_to_add)) == 'archive_zip')) { + $v_result = $this->_merge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) { + // ----- Create a temporary archive + $v_object_archive = new Archive_Zip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->_merge($v_object_archive); + } + + // ----- Invalid variable + else { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + "Invalid variable type p_archive_to_add"); + $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER; + } + + return $v_result; + } + // }}} + + // {{{ errorCode() + /** + * Method that gives the lastest error code. + * + * @access public + * @return integer The error code value. + */ + function errorCode() + { + return($this->_error_code); + } + // }}} + + // {{{ errorName() + /** + * This method gives the latest error code name. + * + * @access public + * @param boolean $p_with_code If true, gives the name and the int value. + * @return string The error name. + */ + function errorName($p_with_code=false) + { + $v_const_list = get_defined_constants(); + + // ----- Extract error constants from all const. + for (reset($v_const_list); + list($v_key, $v_value) = each($v_const_list);) { + if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_')) + =='ARCHIVE_ZIP_ERR_') { + $v_error_list[$v_key] = $v_value; + } + } + + // ----- Search the name form the code value + $v_key=array_search($this->_error_code, $v_error_list, true); + if ($v_key!=false) { + $v_value = $v_key; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->_error_code.')'); + } + else { + return($v_value); + } + } + // }}} + + // {{{ errorInfo() + /** + * This method returns the description associated with the latest error. + * + * @access public + * @param boolean $p_full If set to true gives the description with the + * error code, the name and the description. + * If set to false gives only the description + * and the error code. + * @return string The error description. + */ + function errorInfo($p_full=false) + { + if ($p_full) { + return($this->errorName(true)." : ".$this->_error_string); + } + else { + return($this->_error_string." [code ".$this->_error_code."]"); + } + } + // }}} + + +// ----------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// ----------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _checkFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_checkFormat() + * + * { Description } + * + * @param integer $p_level + */ + function _checkFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the error handler + $this->_errorReset(); + + // ----- Look if the file exits + if (!is_file($this->_zipname)) { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "Missing archive file '".$this->_zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->_zipname)) { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + "Unable to read archive '".$this->_zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _create() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_create() + * + * { Description } + * + */ + function _create($p_list, &$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + $p_add_dir = $p_params['add_path']; + $p_remove_dir = $p_params['remove_path']; + $p_remove_all_dir = $p_params['remove_all_path']; + + // ----- Open the file in write mode + if (($v_result = $this->_openFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->_addList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params); + + // ----- Close + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _add() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_add() + * + * { Description } + * + */ + function _add($p_list, &$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + $p_add_dir = $p_params['add_path']; + $p_remove_dir = $p_params['remove_path']; + $p_remove_all_dir = $p_params['remove_all_path']; + + // ----- Look if the archive exists or is empty and need to be created + if ((!is_file($this->_zipname)) || (filesize($this->_zipname) == 0)) { + $v_result = $this->_create($p_list, $p_result_list, $p_params); + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open temporary file \'' + .$v_zip_temp_name.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to + // use the following methods on the temporary fil and not the real archive + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->_addFileList($p_list, $v_header_list, + $p_add_dir, $p_remove_dir, + $p_remove_all_dir, $p_params)) != 1) + { + fclose($v_zip_temp_fd); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->_zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->_zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i_writeCentralFileHeader($v_header_list[$i]))!=1) { + fclose($v_zip_temp_fd); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($this->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_count + +$v_central_dir['entries'], + $v_size, $v_offset, + $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _openFd() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_openFd() + * + * { Description } + * + */ + function _openFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->_zip_fd != 0) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Zip file \''.$this->_zipname.'\' already open'); + return Archive_Zip::errorCode(); + } + + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive \''.$this->_zipname + .'\' in '.$p_mode.' mode'); + return Archive_Zip::errorCode(); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _closeFd() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_closeFd() + * + * { Description } + * + */ + function _closeFd() + { + $v_result=1; + + if ($this->_zip_fd != 0) + @fclose($this->_zip_fd); + $this->_zip_fd = 0; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addList() + * + * { Description } + * + */ + function _addList($p_list, &$p_result_list, + $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->_addFileList($p_list, $v_header_list, + $p_add_dir, $p_remove_dir, + $p_remove_all_dir, $p_params)) != 1) { + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->_zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $i_writeCentralFileHeader($v_header_list[$i])) != 1) { + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($this->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_count, $v_size, $v_offset, + $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addFileList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to + // run the lib in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addFileList() + * + * { Description } + * + */ + function _addFileList($p_list, &$p_result_list, + $p_add_dir, $p_remove_dir, $p_remove_all_dir, + &$p_params) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($j_tool_TranslateWinPath($p_list[$j], false); + + // ----- Skip empty file names + if ($p_filename == "") + { + continue; + } + + // ----- Check the filename + if (!file_exists($p_filename)) + { + $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, + "File '$p_filename' does not exists"); + return Archive_Zip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all pathnre move + if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) { + // ----- Add the file + if (($v_result = $this->_addFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1) + { + // ----- Return status + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + + // ----- Look for directory + if (is_dir($p_filename)) + { + + // ----- Look for path + if ($p_filename != ".") + $v_path = $p_filename."/"; + else + $v_path = ""; + + // ----- Read the directory for files and sub-directories + $p_hdir = opendir($p_filename); + $p_hitem = readdir($p_hdir); // '.' directory + $p_hitem = readdir($p_hdir); // '..' directory + while ($p_hitem = readdir($p_hdir)) + { + + // ----- Look for a file + if (is_file($v_path.$p_hitem)) + { + + // ----- Add the file + if (($v_result = $this->_addFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1) + { + // ----- Return status + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + + // ----- Recursive call to _addFileList() + else + { + + // ----- Need an array as parameter + $p_temp_list[0] = $v_path.$p_hitem; + $v_result = $this->_addFileList($p_temp_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params); + + // ----- Update the number of elements of the list + $v_nb = sizeof($p_result_list); + } + } + + // ----- Free memory for the recursive loop + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _addFile() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_addFile() + * + * { Description } + * + */ + function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params) + { + $v_result=1; + + if ($p_filename == "") + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") + { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) + { + if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) + $p_remove_dir = "./".$p_remove_dir; + if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) + $p_remove_dir = substr($p_remove_dir, 2); + } + + $v_compare = $this->_tool_PathInclusion($p_remove_dir, $p_filename); + if ($v_compare > 0) +// if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + { + + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + } + } + // ----- Look for path to add + if ($p_add_dir != "") + { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = $this->_tool_PathReduction($v_stored_filename); + + + /* filename length moved after call-back in release 1.3 + // ----- Check the path length + if (strlen($v_stored_filename) > 0xFF) + { + // ----- Error log + $this->_errorLog(-5, "Stored file name is too long (max. 255) : '$v_stored_filename'"); + + // ----- Return + return Archive_Zip::errorCode(); + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['mtime'] = filemtime($p_filename); + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['size'] = filesize($p_filename); + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['comment_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010); + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; + $p_header['stored_filename'] = $v_stored_filename; + $p_header['extra'] = ''; + $p_header['comment'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for pre-add callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD])) + && ($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_ADD].'(ARCHIVE_ZIP_PARAM_PRE_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = $this->_tool_PathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if (is_file($p_filename)) + { + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return Archive_Zip::errorCode(); + } + + if ($p_params['no_compression']) { + // ----- Read the file content + $v_content_compressed = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = crc32($v_content_compressed); + } + else { + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = crc32($v_content); + + // ----- Compress the file + $v_content_compressed = gzdeflate($v_content); + } + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content_compressed); + $p_header['compression'] = 8; + + // ----- Call the header generation + if (($v_result = $this->_writeFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed content + $v_binary_data = pack('a'.$p_header['compressed_size'], $v_content_compressed); + @fwrite($this->_zip_fd, $v_binary_data, $p_header['compressed_size']); + + // ----- Close the file + @fclose($v_file); + } + + // ----- Look for a directory + else + { + // ----- Set the file properties + $p_header['filename'] .= '/'; + $p_header['filename_len']++; + $p_header['size'] = 0; + $p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->_writeFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for pre-add callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_ADD])) + && ($p_params[ARCHIVE_ZIP_PARAM_POST_ADD] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_ADD].'(ARCHIVE_ZIP_PARAM_POST_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeFileHeader() + * + * { Description } + * + */ + function _writeFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->_zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->_zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeCentralFileHeader() + * + * { Description } + * + */ + function _writeCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->_zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->_zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _writeCentralHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_writeCentralHeader() + * + * { Description } + * + */ + function _writeCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->_zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->_zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _list() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_list() + * + * { Description } + * + */ + function _list(&$p_list) + { + $v_result=1; + + // ----- Open the zip file + if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->_zipname.'\' in binary read mode'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_central_dir['offset'])) + { + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) + { + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->_convertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _convertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_convertHeader2FileInfo() + * + * { Description } + * + */ + function _convertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $p_info['filename'] = $p_header['filename']; + $p_info['stored_filename'] = $p_header['stored_filename']; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractByRule() + * + * { Description } + * + */ + function _extractByRule(&$p_file_list, &$p_params) + { + $v_result=1; + + $p_path = $p_params['add_path']; + $p_remove_path = $p_params['remove_path']; + $p_remove_all_path = $p_params['remove_all_path']; + + // ----- Check the path + if (($p_path == "") + || ((substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->_openFd('rb')) != 1) + { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + // ----- Read next Central dir entry + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_pos_entry)) { + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + + return Archive_Zip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) { + $this->_closeFd(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->_zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; + ($j strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) { + + if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) { + + if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->_closeFd(); + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_params[ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING]) { + + // ----- Extracting the file + if (($v_result = $this->_extractFileAsString($v_header, $v_string)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + } + else { + // ----- Extracting the file + if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->_closeFd(); + + return $v_result; + } + } + } + } + + // ----- Close the zip file + $this->_closeFd(); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractFile() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractFile() + * + * { Description } + * + */ + function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->_readFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + // TBC + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + //if (strcmp($p_remove_path, $p_entry['filename'])==0) + if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') + { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Look for pre-extract callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT])) + && ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT].'(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Return + //return $v_result; + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Return + //return $v_result; + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + + // ----- Change the file status + $p_entry['status'] = "newer_exist"; + + // ----- Return + //return $v_result; + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->_dirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) + { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by ARCHIVE_ZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + } + else + { + // ----- Trace + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->_zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD])) + && ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) { + + // ----- Change the mode of the file + chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]); + } + + } + } + + // ----- Look for post-extract callback + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT])) + && ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) { + + // ----- Generate a local information + $v_local_header = array(); + $this->_convertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT].'(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);'); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _extractFileAsString() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_extractFileAsString() + * + * { Description } + * + */ + function _extractFileAsString(&$p_entry, &$p_string) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->_readFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + // TBC + + // ----- Trace + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) + { + // ----- Trace + + // ----- Reading the file + $p_string = fread($this->_zip_fd, $p_entry['compressed_size']); + } + else + { + // ----- Trace + + // ----- Reading the file + $v_data = fread($this->_zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $p_string = gzinflate($v_data); + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readFileHeader() + * + * { Description } + * + */ + function _readFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->_zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Other informations + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readCentralFileHeader() + * + * { Description } + * + */ + function _readCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->_zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') + { + $p_header['external'] = 0x41FF0010; + } + + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _readEndCentralDir() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_readEndCentralDir() + * + * { Description } + * + */ + function _readEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->_zipname); + @fseek($this->_zip_fd, $v_size); + if (@ftell($this->_zip_fd) != $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to go to the end of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries + // (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->_zip_fd, $v_size-22); + if (($v_pos = @ftell($this->_zip_fd)) != ($v_size-22)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to seek back to the middle of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->_zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->_zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->_zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->_zip_fd) != ($v_size-$v_maximum_size)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + 'Unable to seek back to the middle of the archive \'' + .$this->_zipname.'\''); + return Archive_Zip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->_zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) { + // ----- Read a byte + $v_byte = @fread($this->_zip_fd, 1); + + // ----- Add the byte + $v_bytes = ($v_bytes << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Unable to find End of Central Dir Record signature"); + return Archive_Zip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->_zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Invalid End of Central Dir Record size : " + .strlen($v_binary_data)); + return Archive_Zip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, + "Fail to find the right signature"); + return Archive_Zip::errorCode(); + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) + $p_central_dir['comment'] = fread($this->_zip_fd, $v_data['comment_size']); + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _deleteByRule() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_deleteByRule() + * + * { Description } + * + */ + function _deleteByRule(&$p_result_list, &$p_params) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) + { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->_zip_fd); + if (@fseek($this->_zip_fd, $v_pos_entry)) { + // ----- Clean + $this->_closeFd(); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + return Archive_Zip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + $v_result + = $this->_readCentralFileHeader($v_header_list[$v_nb_extracted]); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + + return $v_result; + } + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; + ($j strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] + == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) { + + if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], + $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) { + + if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], + $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) + && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; + ($j=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) + && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for deletion + if ($v_found) { + unset($v_header_list[$v_nb_extracted]); + } + else { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-') + .'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new Archive_Zip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->_openFd('wb')) != 1) { + $this->_closeFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i_zip_fd); + if (@fseek($this->_zip_fd, $v_header_list[$i]['offset'])) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, + 'Invalid archive size'); + return Archive_Zip::errorCode(); + } + + // ----- Read the file header + if (($v_result = $this->_readFileHeader($v_header_list[$i])) != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Write the file header + $v_result = $v_temp_zip->_writeFileHeader($v_header_list[$i]); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Read/write the data block + $v_result = $this->_tool_CopyBlock($this->_zip_fd, + $v_temp_zip->_zip_fd, + $v_header_list[$i]['compressed_size']); + if ($v_result != 1) { + // ----- Clean + $this->_closeFd(); + $v_temp_zip->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->_zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $i_writeCentralFileHeader($v_header_list[$i]); + if ($v_result != 1) { + // ----- Clean + $v_temp_zip->_closeFd(); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->_convertHeader2FileInfo($v_header_list[$i], + $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->_zip_fd)-$v_offset; + + // ----- Create the central dir footer + $v_result = $v_temp_zip->_writeCentralHeader(sizeof($v_header_list), + $v_size, $v_offset, + $v_comment); + if ($v_result != 1) { + // ----- Clean + unset($v_header_list); + $v_temp_zip->_closeFd(); + $this->_closeFd(); + @unlink($v_zip_temp_name); + + return $v_result; + } + + // ----- Close + $v_temp_zip->_closeFd(); + $this->_closeFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _dirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_dirCheck() + * + * { Description } + * + * @param [type] $p_is_dir + */ + function _dirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) { + // ----- Look for parent directory + if ($p_parent_dir != "") { + if (($v_result = $this->_dirCheck($p_parent_dir)) != 1) { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL, + "Unable to create directory '$p_dir'"); + return Archive_Zip::errorCode(); + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _merge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_merge() + * + * { Description } + * + */ + function _merge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->_zipname)) { + // ----- Nothing to merge, so merge is a success + return 1; + } + + // ----- Look if the archive exists + if (!is_file($this->_zipname)) { + // ----- Do a duplicate + $v_result = $this->_duplicate($p_archive_to_add->_zipname); + + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('rb')) != 1) { + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) { + $this->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->_zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->_openFd('rb')) != 1) { + $this->_closeFd(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + $v_result = $p_archive_to_add->_readEndCentralDir($v_central_dir_to_add); + if ($v_result != 1) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->_zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open temporary file \'' + .$v_zip_temp_name.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->_zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Zip file comment + // TBC : I should merge the two comments + $v_comment = ''; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->_writeCentralHeader($v_central_dir['entries'] + +$v_central_dir_to_add['entries'], + $v_size, $v_offset, + $v_comment)) != 1) { + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + @fclose($v_zip_temp_fd); + $this->_zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->_zip_fd; + $this->_zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->_closeFd(); + $p_archive_to_add->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->_zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->_zipname); + $this->_tool_Rename($v_zip_temp_name, $this->_zipname); + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _duplicate() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_duplicate() + * + * { Description } + * + */ + function _duplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->_openFd('wb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { + $this->_closeFd(); + $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, + 'Unable to open archive file \'' + .$p_archive_filename.'\' in binary write mode'); + return Archive_Zip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the + // central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->_zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->_closeFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + return $v_result; + } + // --------------------------------------------------------------------------- + + /** + * Archive_Zip::_check_parameters() + * + * { Description } + * + * @param integer $p_error_code + * @param string $p_error_string + */ + function _check_parameters(&$p_params, $p_default) + { + + // ----- Check that param is an array + if (!is_array($p_params)) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Unsupported parameter, waiting for an array'); + return Archive_Zip::errorCode(); + } + + // ----- Check that all the params are valid + for (reset($p_params); list($v_key, $v_value) = each($p_params); ) { + if (!isset($p_default[$v_key])) { + $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, + 'Unsupported parameter with key \''.$v_key.'\''); + + return Archive_Zip::errorCode(); + } + } + + // ----- Set the default values + for (reset($p_default); list($v_key, $v_value) = each($p_default); ) { + if (!isset($p_params[$v_key])) { + $p_params[$v_key] = $p_default[$v_key]; + } + } + + // ----- Check specific parameters + $v_callback_list = array ('callback_pre_add','callback_post_add', + 'callback_pre_extract','callback_post_extract'); + for ($i=0; $i_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE, + "Callback '".$p_params[$v_key] + ."()' is not an existing function for " + ."parameter '".$v_key."'"); + return Archive_Zip::errorCode(); + } + } + } + + return(1); + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _errorLog() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_errorLog() + * + * { Description } + * + * @param integer $p_error_code + * @param string $p_error_string + */ + function _errorLog($p_error_code=0, $p_error_string='') + { + $this->_error_code = $p_error_code; + $this->_error_string = $p_error_string; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : _errorReset() + // Description : + // Parameters : + // --------------------------------------------------------------------------- + /** + * Archive_Zip::_errorReset() + * + * { Description } + * + */ + function _errorReset() + { + $this->_error_code = 1; + $this->_error_string = ''; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_PathReduction() + // Description : + // Parameters : + // Return Values : + // --------------------------------------------------------------------------- + /** + * _tool_PathReduction() + * + * { Description } + * + */ + function _tool_PathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") + { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + for ($i=sizeof($v_list)-1; $i>=0; $i--) + { + // ----- Look for current path + if ($v_list[$i] == ".") + { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") + { + // ----- Ignore it and ignore the $i-1 + $i--; + } + else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0)) + { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + else + { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_PathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // --------------------------------------------------------------------------- + /** + * _tool_PathInclusion() + * + * { Description } + * + */ + function _tool_PathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if ( ($v_list_dir[$i] != $v_list_path[$j]) + && ($v_list_dir[$i] != '') + && ( $v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_CopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // --------------------------------------------------------------------------- + /** + * _tool_CopyBlock() + * + * { Description } + * + * @param integer $p_mode + */ + function _tool_CopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE + ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_Rename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // --------------------------------------------------------------------------- + /** + * _tool_Rename() + * + * { Description } + * + */ + function _tool_Rename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // --------------------------------------------------------------------------- + + // --------------------------------------------------------------------------- + // Function : $this->_tool_TranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // --------------------------------------------------------------------------- + /** + * _tool_TranslateWinPath() + * + * { Description } + * + * @param [type] $p_remove_disk_letter + */ + function _tool_TranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if ( ($p_remove_disk_letter) + && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // --------------------------------------------------------------------------- + + } + // End of class + +?> diff --git a/gulliver/thirdparty/phing/listener/AnsiColorLogger.php b/gulliver/thirdparty/phing/listener/AnsiColorLogger.php new file mode 100644 index 000000000..7cd87200b --- /dev/null +++ b/gulliver/thirdparty/phing/listener/AnsiColorLogger.php @@ -0,0 +1,231 @@ +. + */ + +require_once 'phing/listener/DefaultLogger.php'; +include_once 'phing/system/util/Properties.php'; + +/** + * Uses ANSI Color Code Sequences to colorize messages + * sent to the console. + * + * If used with the -logfile option, the output file + * will contain all the necessary escape codes to + * display the text in colorized mode when displayed + * in the console using applications like cat, more, + * etc. + * + * This is designed to work on terminals that support ANSI + * color codes. It works on XTerm, ETerm, Mindterm, etc. + * It also works on Win9x (with ANSI.SYS loaded.) + * + * NOTE: + * It doesn't work on WinNT's COMMAND.COM even with + * ANSI.SYS loaded. + * + * The default colors used for differentiating + * the message levels can be changed by editing the + * /org/apache/tools/ant/listener/defaults.properties + * file. + * This file contains 5 key/value pairs: + * AnsiColorLogger.ERROR_COLOR=2;31 + * AnsiColorLogger.WARNING_COLOR=2;35 + * AnsiColorLogger.INFO_COLOR=2;36 + * AnsiColorLogger.VERBOSE_COLOR=2;32 + * AnsiColorLogger.DEBUG_COLOR=2;34 + * + * Another option is to pass a system variable named + * ant.logger.defaults, with value set to the path of + * the file that contains user defined Ansi Color + * Codes, to the java command using -D option. + * + * To change these colors use the following chart: + * + * ANSI COLOR LOGGER CONFIGURATION + * + * Format for AnsiColorLogger.*= + * Attribute;Foreground;Background + * + * Attribute is one of the following: + * 0 -> Reset All Attributes (return to normal mode) + * 1 -> Bright (Usually turns on BOLD) + * 2 -> Dim + * 3 -> Underline + * 5 -> link + * 7 -> Reverse + * 8 -> Hidden + * + * Foreground is one of the following: + * 30 -> Black + * 31 -> Red + * 32 -> Green + * 33 -> Yellow + * 34 -> Blue + * 35 -> Magenta + * 36 -> Cyan + * 37 -> White + * + * Background is one of the following: + * 40 -> Black + * 41 -> Red + * 42 -> Green + * 43 -> Yellow + * 44 -> Blue + * 45 -> Magenta + * 46 -> Cyan + * 47 -> White + * + * @author Hans Lellelid (Phing) + * @author Magesh Umasankar (Ant) + * @package phing.listener + * @version $Revision: 1.13 $ + */ +final class AnsiColorLogger extends DefaultLogger { + + const ATTR_NORMAL = 0; + const ATTR_BRIGHT = 1; + const ATTR_DIM = 2; + const ATTR_UNDERLINE = 3; + const ATTR_BLINK = 5; + const ATTR_REVERSE = 7; + const ATTR_HIDDEN = 8; + + const FG_BLACK = 30; + const FG_RED = 31; + const FG_GREEN = 32; + const FG_YELLOW = 33; + const FG_BLUE = 34; + const FG_MAGENTA = 35; + const FG_CYAN = 36; + const FG_WHITE = 37; + + const BG_BLACK = 40; + const BG_RED = 41; + const BG_GREEN = 42; + const BG_YELLOW = 44; + const BG_BLUE = 44; + const BG_MAGENTA = 45; + const BG_CYAN = 46; + const BG_WHITE = 47; + + const PREFIX = "\x1b["; + const SUFFIX = "m"; + const SEPARATOR = ';'; + const END_COLOR = "\x1b[m"; // self::PREFIX . self::SUFFIX; + + private $errColor; + private $warnColor; + private $infoColor; + private $verboseColor; + private $debugColor; + + private $colorsSet = false; + + /** + * Construct new AnsiColorLogger + * Perform initializations that cannot be done in var declarations. + */ + public function __construct() { + parent::__construct(); + $this->errColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_RED . self::SUFFIX; + $this->warnColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_MAGENTA . self::SUFFIX; + $this->infoColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_CYAN . self::SUFFIX; + $this->verboseColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_GREEN . self::SUFFIX; + $this->debugColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_BLUE . self::SUFFIX; + } + + /** + * Set the colors to use from a property file specified by the + * special ant property ant.logger.defaults + */ + private final function setColors() { + + $userColorFile = Phing::getProperty("phing.logger.defaults"); + $systemColorFile = new PhingFile(Phing::getResourcePath("phing/listener/defaults.properties")); + + $in = null; + + try { + $prop = new Properties(); + + if ($userColorFile !== null) { + $prop->load($userColorFile); + } else { + $prop->load($systemColorFile); + } + + $err = $prop->getProperty("AnsiColorLogger.ERROR_COLOR"); + $warn = $prop->getProperty("AnsiColorLogger.WARNING_COLOR"); + $info = $prop->getProperty("AnsiColorLogger.INFO_COLOR"); + $verbose = $prop->getProperty("AnsiColorLogger.VERBOSE_COLOR"); + $debug = $prop->getProperty("AnsiColorLogger.DEBUG_COLOR"); + if ($err !== null) { + $errColor = self::PREFIX . $err . self::SUFFIX; + } + if ($warn !== null) { + $warnColor = self::PREFIX . $warn . self::SUFFIX; + } + if ($info !== null) { + $infoColor = self::PREFIX . $info . self::SUFFIX; + } + if ($verbose !== null) { + $verboseColor = self::PREFIX . $verbose . self::SUFFIX; + } + if ($debug !== null) { + $debugColor = self::PREFIX . $debug . self::SUFFIX; + } + } catch (IOException $ioe) { + //Ignore exception - we will use the defaults. + } + } + + /** + * @see DefaultLogger#printMessage + */ + protected final function printMessage($message, $priority) { + + if ($message !== null) { + + if (!$this->colorsSet) { + $this->setColors(); + $this->colorsSet = true; + } + + switch ($priority) { + case PROJECT_MSG_ERR: + $message = $this->errColor . $message . self::END_COLOR; + break; + case PROJECT_MSG_WARN: + $message = $this->warnColor . $message . self::END_COLOR; + break; + case PROJECT_MSG_INFO: + $message = $this->infoColor . $message . self::END_COLOR; + break; + case PROJECT_MSG_VERBOSE: + $message = $this->verboseColor . $message . self::END_COLOR; + break; + case PROJECT_MSG_DEBUG: + $message = $this->debugColor . $message . self::END_COLOR; + break; + } + print($message."\n"); + } + } +} diff --git a/gulliver/thirdparty/phing/listener/BuildLogger.php b/gulliver/thirdparty/phing/listener/BuildLogger.php new file mode 100644 index 000000000..e53ff2929 --- /dev/null +++ b/gulliver/thirdparty/phing/listener/BuildLogger.php @@ -0,0 +1,42 @@ +. + */ + + require_once 'phing/BuildListener.php'; + /** + * Interface used by Phing Ant to log the build output. + * + * @author Michiel Rook + * @version $Id: BuildLogger.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.listener + */ + interface BuildLogger extends BuildListener + { + /** + * Sets the highest level of message this logger should respond to. + * + * Only messages with a message level lower than or equal to the + * given level should be written to the log. + * + * @param int the logging level for the logger. + */ + function setMessageOutputLevel($level); + }; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/listener/DefaultLogger.php b/gulliver/thirdparty/phing/listener/DefaultLogger.php new file mode 100644 index 000000000..2a706d9b0 --- /dev/null +++ b/gulliver/thirdparty/phing/listener/DefaultLogger.php @@ -0,0 +1,233 @@ +. + */ + +require_once 'phing/BuildListener.php'; +include_once 'phing/BuildEvent.php'; + +/** + * Writes a build event to the console. + * + * Currently, it only writes which targets are being executed, and + * any messages that get logged. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.11 $ $Date: 2005/08/25 19:33:43 $ + * @see BuildEvent + * @package phing.listener + */ +class DefaultLogger implements BuildListener { + + /** + * Size of the left column in output. The default char width is 12. + * @var int + */ + const LEFT_COLUMN_SIZE = 12; + + /** + * The message output level that should be used. The default is + * PROJECT_MSG_VERBOSE. + * @var int + */ + protected $msgOutputLevel = PROJECT_MSG_ERR; + + /** + * Time that the build started + * @var int + */ + protected $startTime; + + /** + * Char that should be used to seperate lines. Default is the system + * property line.seperator. + * @var string + */ + protected $lSep; + + /** + * Construct a new default logger. + */ + public function __construct() { + $this->lSep = Phing::getProperty("line.separator"); + } + + /** + * Set the msgOutputLevel this logger is to respond to. + * + * Only messages with a message level lower than or equal to the given + * level are output to the log. + * + *

    Constants for the message levels are in Project.php. The order of + * the levels, from least to most verbose, is: + * + *

      + *
    • PROJECT_MSG_ERR
    • + *
    • PROJECT_MSG_WARN
    • + *
    • PROJECT_MSG_INFO
    • + *
    • PROJECT_MSG_VERBOSE
    • + *
    • PROJECT_MSG_DEBUG
    • + *
    + * + * The default message level for DefaultLogger is PROJECT_MSG_ERR. + * + * @param integer the logging level for the logger. + * @access public + */ + function setMessageOutputLevel($level) { + $this->msgOutputLevel = (int) $level; + } + + /** + * Sets the start-time when the build started. Used for calculating + * the build-time. + * + * @param object The BuildEvent + * @access public + */ + + function buildStarted(BuildEvent $event) { + $this->startTime = Phing::currentTimeMillis(); + if ($this->msgOutputLevel >= PROJECT_MSG_INFO) { + $this->printMessage("Buildfile: ".$event->getProject()->getProperty("phing.file"), PROJECT_MSG_INFO); + } + } + + /** + * Prints whether the build succeeded or failed, and any errors that + * occured during the build. Also outputs the total build-time. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function buildFinished(BuildEvent $event) { + $error = $event->getException(); + if ($error === null) { + print($this->lSep . "BUILD FINISHED" . $this->lSep); + } else { + print($this->lSep . "BUILD FAILED" . $this->lSep); + if (PROJECT_MSG_VERBOSE <= $this->msgOutputLevel || !($error instanceof BuildException)) { + print($error->__toString().$this->lSep); + } else { + print($error->getMessage()); + } + } + print($this->lSep . "Total time: " .$this->_formatTime(Phing::currentTimeMillis() - $this->startTime) . $this->lSep); + } + + /** + * Prints the current target name + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getTarget() + */ + function targetStarted(BuildEvent $event) { + if (PROJECT_MSG_INFO <= $this->msgOutputLevel) { + print($this->lSep . $event->getProject()->getName() . ' > ' . $event->getTarget()->getName() . ':' . $this->lSep); + } + } + + /** + * Fired when a target has finished. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function targetFinished(BuildEvent $event) {} + + /** + * Fired when a task is started. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getTask() + */ + function taskStarted(BuildEvent $event) {} + + /** + * Fired when a task has finished. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function taskFinished(BuildEvent $event) {} + + /** + * Print a message to the stdout. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getMessage() + */ + function messageLogged(BuildEvent $event) { + if ($event->getPriority() <= $this->msgOutputLevel) { + $msg = ""; + if ($event->getTask() !== null) { + $name = $event->getTask(); + $name = $name->getTaskName(); + $msg = str_pad("[$name] ", self::LEFT_COLUMN_SIZE, " ", STR_PAD_LEFT); + #for ($i=0; $i < ($this->LEFT_COLUMN_SIZE - strlen($msg)); ++$i) { + # print(" "); + #} + #print($msg); + } + $msg .= $event->getMessage(); + $this->printMessage($msg, $event->getPriority()); + } + } + + /** + * Formats a time micro integer to human readable format. + * + * @param integer The time stamp + * @access private + */ + function _formatTime($micros) { + $seconds = $micros; + $minutes = $seconds / 60; + if ($minutes > 1) { + return sprintf("%1.0f minute%s %0.2f second%s", + $minutes, ($minutes === 1 ? " " : "s "), + $seconds - floor($seconds/60) * 60, ($seconds%60 === 1 ? "" : "s")); + } else { + return sprintf("%0.4f second%s", $seconds, ($seconds%60 === 1 ? "" : "s")); + } + } + + /** + * Prints a message to console. + * + * @param string $message The message to print. + * Should not be null. + * @param int $priority The priority of the message. + * (Ignored in this implementation.) + * @return void + */ + protected function printMessage($message, $priority) { + print($message . $this->lSep); + } +} diff --git a/gulliver/thirdparty/phing/listener/NoBannerLogger.php b/gulliver/thirdparty/phing/listener/NoBannerLogger.php new file mode 100644 index 000000000..ffa583f54 --- /dev/null +++ b/gulliver/thirdparty/phing/listener/NoBannerLogger.php @@ -0,0 +1,61 @@ +. + */ + +include_once 'phing/listener/DefaultLogger.php'; + +/** + * Extends DefaultLogger to strip out empty targets. This logger is most + * commonly used and also enforced by the default phing invokation scripts + * in bin/. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.4 $ $Date: 2003/12/24 13:02:08 $ + * @package phing.listener + */ +class NoBannerLogger extends DefaultLogger { + + private $targetName = null; + + function targetStarted(BuildEvent $event) { + $target = $event->getTarget(); + $this->targetName = $target->getName(); + } + + function targetFinished(BuildEvent $event) { + $this->targetName = null; + } + + function messageLogged(BuildEvent $event) { + if ($event->getPriority() > $this->msgOutputLevel || + null === $event->getMessage() || + trim($event->getMessage() === "")) { + return; + } + + if ($this->targetName !== null) { + print($this->lSep . "Target: ".$this->targetName . $this->lSep); + $this->targetName = null; + } + + parent::messageLogged($event); + } +} diff --git a/gulliver/thirdparty/phing/listener/PearLogger.php b/gulliver/thirdparty/phing/listener/PearLogger.php new file mode 100644 index 000000000..f69b9d616 --- /dev/null +++ b/gulliver/thirdparty/phing/listener/PearLogger.php @@ -0,0 +1,246 @@ +. + */ + +require_once 'phing/BuildListener.php'; +include_once 'phing/BuildEvent.php'; +require_once 'Log.php'; + +/** + * Writes log messages to PEAR Log. + * + * By default it will log to file in current directory w/ name 'phing.log'. You can customize + * this behavior by setting properties: + * - pear.log.type + * - pear.log.name + * - pear.log.ident (note that this class changes ident to project name) + * - pear.log.conf (note that array values are currently unsupported in Phing property files) + * + * + * phing -f build.xml -logger phing.listener.PearLogger -Dpear.log.type=file -Dpear.log.name=/path/to/log.log + * + * + * @author Hans Lellelid + * @version $Revision: 1.3 $ $Date: 2004/03/15 14:45:06 $ + * @see BuildEvent + * @package phing.listener + */ +class PearLogger implements BuildListener { + + /** + * Size of the left column in output. The default char width is 12. + * @var int + */ + const LEFT_COLUMN_SIZE = 12; + + /** + * The message output level that should be used. The default is + * PROJECT_MSG_VERBOSE. + * @var int + */ + protected $msgOutputLevel = PROJECT_MSG_ERR; + + /** + * Time that the build started + * @var int + */ + protected $startTime; + + /** + * Maps Phing PROJECT_MSG_* constants to PEAR_LOG_* constants. + * @var array + */ + protected static $levelMap = array( PROJECT_MSG_DEBUG => PEAR_LOG_DEBUG, + PROJECT_MSG_INFO => PEAR_LOG_INFO, + PROJECT_MSG_VERBOSE => PEAR_LOG_NOTICE, + PROJECT_MSG_WARN => PEAR_LOG_WARNING, + PROJECT_MSG_ERR => PEAR_LOG_ERR + ); + /** + * Whether logging has been configured. + * @var boolean + */ + protected $logConfigured = false; + + /** + * Configure the logger. + */ + protected function configureLogging() { + + $type = Phing::getDefinedProperty('pear.log.type'); + $name = Phing::getDefinedProperty('pear.log.name'); + $ident = Phing::getDefinedProperty('pear.log.ident'); + $conf = Phing::getDefinedProperty('pear.log.conf'); + + if ($type === null) $type = 'file'; + if ($name === null) $name = 'phing.log'; + if ($ident === null) $ident = 'phing'; + if ($conf === null) $conf = array(); + + $this->logger = Log::singleton($type, $name, $ident, $conf, self::$levelMap[$this->msgOutputLevel]); + } + + /** + * Get the configured PEAR logger to use. + * This method just ensures that logging has been configured and returns the configured logger. + * @return Log + */ + protected function logger() { + if (!$this->logConfigured) { + $this->configureLogging(); + } + return $this->logger; + } + + /** + * Set the msgOutputLevel this logger is to respond to. + * + * Only messages with a message level lower than or equal to the given + * level are output to the log. + * + *

    Constants for the message levels are in Project.php. The order of + * the levels, from least to most verbose, is: + * + *

      + *
    • PROJECT_MSG_ERR
    • + *
    • PROJECT_MSG_WARN
    • + *
    • PROJECT_MSG_INFO
    • + *
    • PROJECT_MSG_VERBOSE
    • + *
    • PROJECT_MSG_DEBUG
    • + *
    + * + * The default message level for DefaultLogger is PROJECT_MSG_ERR. + * + * @param integer the logging level for the logger. + * @access public + */ + function setMessageOutputLevel($level) { + $this->msgOutputLevel = (int) $level; + } + + /** + * Sets the start-time when the build started. Used for calculating + * the build-time. + * + * @param object The BuildEvent + * @access public + */ + + function buildStarted(BuildEvent $event) { + $this->startTime = Phing::currentTimeMillis(); + $this->logger()->setIdent($event->getProject()->getName()); + $this->logger()->info("Starting build with buildfile: ". $event->getProject()->getProperty("phing.file")); + } + + /** + * Prints whether the build succeeded or failed, and any errors that + * occured during the build. Also outputs the total build-time. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function buildFinished(BuildEvent $event) { + $error = $event->getException(); + if ($error === null) { + $msg = "Finished successful build."; + } else { + $msg = "Build failed. [reason: " . $error->getMessage() ."]"; + } + $this->logger()->log($msg . " Total time: " . $this->_formatTime(Phing::currentTimeMillis() - $this->startTime)); + } + + /** + * Prints the current target name + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getTarget() + */ + function targetStarted(BuildEvent $event) {} + + /** + * Fired when a target has finished. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function targetFinished(BuildEvent $event) {} + + /** + * Fired when a task is started. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getTask() + */ + function taskStarted(BuildEvent $event) {} + + /** + * Fired when a task has finished. We don't need specific action on this + * event. So the methods are empty. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getException() + */ + function taskFinished(BuildEvent $event) {} + + /** + * Print a message to the stdout. + * + * @param object The BuildEvent + * @access public + * @see BuildEvent::getMessage() + */ + function messageLogged(BuildEvent $event) { + if ($event->getPriority() <= $this->msgOutputLevel) { + $msg = ""; + if ($event->getTask() !== null) { + $name = $event->getTask(); + $name = $name->getTaskName(); + $msg = str_pad("[$name] ", self::LEFT_COLUMN_SIZE, " ", STR_PAD_LEFT); + } + $msg .= $event->getMessage(); + $this->logger()->log($msg, self::$levelMap[$event->getPriority()]); + } + } + + /** + * Formats a time micro integer to human readable format. + * + * @param integer The time stamp + * @access private + */ + function _formatTime($micros) { + $seconds = $micros; + $minutes = $seconds / 60; + if ($minutes > 1) { + return sprintf("%1.0f minute%s %0.2f second%s", + $minutes, ($minutes === 1 ? " " : "s "), + $seconds - floor($seconds/60) * 60, ($seconds%60 === 1 ? "" : "s")); + } else { + return sprintf("%0.4f second%s", $seconds, ($seconds%60 === 1 ? "" : "s")); + } + } +} diff --git a/gulliver/thirdparty/phing/listener/XmlLogger.php b/gulliver/thirdparty/phing/listener/XmlLogger.php new file mode 100644 index 000000000..b30a1424e --- /dev/null +++ b/gulliver/thirdparty/phing/listener/XmlLogger.php @@ -0,0 +1,265 @@ +. + */ + + require_once 'phing/listener/BuildLogger.php'; + require_once 'phing/listener/DefaultLogger.php'; + require_once 'phing/system/util/Timer.php'; + /** + * Generates a file in the current directory with + * an XML description of what happened during a build. + * The default filename is "log.xml", but this can be overridden + * with the property XmlLogger.file. + * + * @author Michiel Rook + * @version $Id: XmlLogger.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.listener + */ + class XmlLogger implements BuildLogger + { + /** XML element name for a build. */ + const BUILD_TAG = "build"; + /** XML element name for a target. */ + const TARGET_TAG = "target"; + /** XML element name for a task. */ + const TASK_TAG = "task"; + /** XML element name for a message. */ + const MESSAGE_TAG = "message"; + /** XML attribute name for a name. */ + const NAME_ATTR = "name"; + /** XML attribute name for a time. */ + const TIME_ATTR = "time"; + /** XML attribute name for a message priority. */ + const PRIORITY_ATTR = "priority"; + /** XML attribute name for a file location. */ + const LOCATION_ATTR = "location"; + /** XML attribute name for an error description. */ + const ERROR_ATTR = "error"; + /** XML element name for a stack trace. */ + const STACKTRACE_TAG = "stacktrace"; + + private $doc = NULL; + + private $buildStartTime = 0; + private $targetStartTime = 0; + private $taskStartTime = 0; + + private $buildElement = NULL; + + private $msgOutputLevel = PROJECT_MSG_DEBUG; + + /** + * Constructs a new BuildListener that logs build events to an XML file. + */ + function __construct() + { + $this->doc = new DOMDocument(); + $this->doc->formatOutput = true; + + $this->buildTimer = new Timer(); + $this->targetTimer = new Timer(); + $this->taskTimer = new Timer(); + } + + /** + * Fired when the build starts, this builds the top-level element for the + * document and remembers the time of the start of the build. + * + * @param BuildEvent Ignored. + */ + function buildStarted(BuildEvent $event) + { + $this->buildTimerStart = Phing::currentTimeMillis(); + $this->buildElement = $this->doc->createElement(XmlLogger::BUILD_TAG); + } + + /** + * Fired when the build finishes, this adds the time taken and any + * error stacktrace to the build element and writes the document to disk. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function buildFinished(BuildEvent $event) + { + $this->buildTimer->stop(); + + $elapsedTime = Phing::currentTimeMillis() - $this->buildTimerStart; + + $this->buildElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::_formatTime($elapsedTime)); + + if ($event->getException() != null) + { + $this->buildElement->setAttribute(XmlLogger::ERROR_ATTR, $event->getException()->toString()); + + $errText = $this->doc->createCDATASection($event->getException()->getTraceAsString()); + $stacktrace = $this->doc->createElement(XmlLogger::STACKTRACE_TAG); + $stacktrace->appendChild($errText); + $this->buildElement->appendChild($stacktrace); + } + + $outFilename = $event->getProject()->getProperty("XmlLogger.file"); + + if ($outFilename == "") + { + $outFilename = "log.xml"; + } + $writer = new FileWriter($outFilename); + + $writer->write("\n"); + $writer->write($this->doc->saveXML($this->buildElement)); + $writer->close(); + } + /** + * Fired when a target starts building, remembers the current time and the name of the target. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function targetStarted(BuildEvent $event) + { + $target = $event->getTarget(); + + $this->targetTimerStart = Phing::currentTimeMillis(); + + $this->targetElement = $this->doc->createElement(XmlLogger::TARGET_TAG); + $this->targetElement->setAttribute(XmlLogger::NAME_ATTR, $target->getName()); + } + + /** + * Fired when a target finishes building, this adds the time taken + * to the appropriate target element in the log. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function targetFinished(BuildEvent $event) + { + $target = $event->getTarget(); + + $elapsedTime = Phing::currentTimeMillis() - $this->targetTimerStart; + + $this->targetElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::_formatTime($elapsedTime)); + + $this->buildElement->appendChild($this->targetElement); + } + + /** + * Fired when a task starts building, remembers the current time and the name of the task. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function taskStarted(BuildEvent $event) + { + $task = $event->getTask(); + + $this->taskTimerStart = Phing::currentTimeMillis(); + + $this->taskElement = $this->doc->createElement(XmlLogger::TASK_TAG); + $this->taskElement->setAttribute(XmlLogger::NAME_ATTR, $task->getTaskName()); + $this->taskElement->setAttribute(XmlLogger::LOCATION_ATTR, $task->getLocation()->toString()); + } + /** + * Fired when a task finishes building, this adds the time taken + * to the appropriate task element in the log. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function taskFinished(BuildEvent $event) + { + $task = $event->getTask(); + + $elapsedTime = Phing::currentTimeMillis() - $this->taskTimerStart; + $this->taskElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::_formatTime($elapsedTime)); + + $this->targetElement->appendChild($this->taskElement); + } + + /** + * Fired when a message is logged, this adds a message element to the + * most appropriate parent element (task, target or build) and records + * the priority and text of the message. + * + * @param BuildEvent An event with any relevant extra information. + * Will not be null. + */ + function messageLogged(BuildEvent $event) + { + $priority = $event->getPriority(); + + if ($priority > $this->msgOutputLevel) + { + return; + } + + $messageElement = $this->doc->createElement(XmlLogger::MESSAGE_TAG); + + switch ($priority) + { + case PROJECT_MSG_ERR: + $name = "error"; + break; + + case PROJECT_MSG_WARN: + $name = "warn"; + break; + + case PROJECT_MSG_INFO: + $name = "info"; + break; + + default: + $name = "debug"; + break; + } + + $messageElement->setAttribute(XmlLogger::PRIORITY_ATTR, $name); + + $messageText = $this->doc->createCDATASection($event->getMessage()); + + $messageElement->appendChild($messageText); + + if ($event->getTask() != null) + { + $this->taskElement->appendChild($messageElement); + } + else + if ($event->getTarget() != null) + { + $this->targetElement->appendChild($messageElement); + } + else + if ($this->buildElement != null) + { + $this->buildElement->appendChild($messageElement); + } + } + + /** + * Set the logging level when using this as a Logger + */ + function setMessageOutputLevel($level) + { + $this->msgOutputLevel = $level; + } + }; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/listener/defaults.properties b/gulliver/thirdparty/phing/listener/defaults.properties new file mode 100644 index 000000000..f60a3fd5e --- /dev/null +++ b/gulliver/thirdparty/phing/listener/defaults.properties @@ -0,0 +1,43 @@ +#################################################### +# +# ANSI COLOR LOGGER CONFIGURATION +# +# Format for AnsiColorLogger.*= +# Attribute;Foreground;Background +# +# Attribute is one of the following: +# 0 -> Reset All Attributes (return to normal mode) +# 1 -> Bright (Usually turns on BOLD) +# 2 -> Dim +# 3 -> Underline +# 5 -> link +# 7 -> Reverse +# 8 -> Hidden +# +# Foreground is one of the following: +# 30 -> Black +# 31 -> Red +# 32 -> Green +# 33 -> Yellow +# 34 -> Blue +# 35 -> Magenta +# 36 -> Cyan +# 37 -> White +# +# Background is one of the following: +# 40 -> Black +# 41 -> Red +# 42 -> Green +# 43 -> Yellow +# 44 -> Blue +# 45 -> Magenta +# 46 -> Cyan +# 47 -> White +# +#################################################### + +AnsiColorLogger.ERROR_COLOR=2;31 +AnsiColorLogger.WARNING_COLOR=2;35 +AnsiColorLogger.INFO_COLOR=2;36 +AnsiColorLogger.VERBOSE_COLOR=2;32 +AnsiColorLogger.DEBUG_COLOR=2;34 diff --git a/gulliver/thirdparty/phing/mappers/FileNameMapper.php b/gulliver/thirdparty/phing/mappers/FileNameMapper.php new file mode 100644 index 000000000..7c84ebe37 --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/FileNameMapper.php @@ -0,0 +1,59 @@ +. + */ + +/** + * Interface for filename mapper classes. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @author Hans Lellelid + * @version $Revision: 1.7 $ + * @package phing.mappers + */ +interface FileNameMapper { + + /** + * The mapper implementation. + * + * @param mixed $sourceFileName The data the mapper works on. + * @return array The data after the mapper has been applied; must be in array format (for some reason). + */ + public function main($sourceFileName); + + /** + * Accessor. Sets the to property. The actual implementation + * depends on the child class. + * + * @param string $to To what this mapper should convert the from string + * @return void + */ + public function setTo($to); + + /** + * Accessor. Sets the from property. What this mapper should + * recognize. The actual implementation is dependent upon the + * child class + * + * @param string $from On what this mapper should work + * @return void + */ + public function setFrom($from); + +} diff --git a/gulliver/thirdparty/phing/mappers/FlattenMapper.php b/gulliver/thirdparty/phing/mappers/FlattenMapper.php new file mode 100644 index 000000000..3be79857c --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/FlattenMapper.php @@ -0,0 +1,55 @@ +. + */ + +require_once 'phing/mappers/FileNameMapper.php'; + +/** + * Removes any directory information from the passed path. + * + * @author Andreas Aderhold + * @version $Revision: 1.9 $ + * @package phing.mappers + */ +class FlattenMapper implements FileNameMapper { + + /** + * The mapper implementation. Returns string with source filename + * but without leading directory information + * + * @param string $sourceFileName The data the mapper works on + * @return array The data after the mapper has been applied + */ + function main($sourceFileName) { + $f = new PhingFile($sourceFileName); + return array($f->getName()); + } + + /** + * Ignored here. + */ + function setTo($to) {} + + /** + * Ignored here. + */ + function setFrom($from) {} + +} diff --git a/gulliver/thirdparty/phing/mappers/GlobMapper.php b/gulliver/thirdparty/phing/mappers/GlobMapper.php new file mode 100644 index 000000000..89b0e5705 --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/GlobMapper.php @@ -0,0 +1,113 @@ +. + */ + +include_once 'phing/mappers/FileNameMapper.php'; + +/** + * description here + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.10 $ + * @package phing.mappers + */ +class GlobMapper implements FileNameMapper { + + /** + * Part of "from" pattern before the *. + */ + private $fromPrefix = null; + + /** + * Part of "from" pattern after the *. + */ + private $fromPostfix = null; + + /** + * Length of the prefix ("from" pattern). + */ + private $prefixLength; + + /** + * Length of the postfix ("from" pattern). + */ + private $postfixLength; + + /** + * Part of "to" pattern before the *. + */ + private $toPrefix = null; + + /** + * Part of "to" pattern after the *. + */ + private $toPostfix = null; + + + function main($_sourceFileName) { + if (($this->fromPrefix === null) + || !StringHelper::startsWith($this->fromPrefix, $_sourceFileName) + || !StringHelper::endsWith($this->fromPostfix, $_sourceFileName)) { + return null; + } + $varpart = $this->_extractVariablePart($_sourceFileName); + $substitution = $this->toPrefix.$varpart.$this->toPostfix; + return array($substitution); + } + + + + function setFrom($from) { + $index = strrpos($from, '*'); + + if ($index === false) { + $this->fromPrefix = $from; + $this->fromPostfix = ""; + } else { + $this->fromPrefix = substr($from, 0, $index); + $this->fromPostfix = substr($from, $index+1); + } + $this->prefixLength = strlen($this->fromPrefix); + $this->postfixLength = strlen($this->fromPostfix); + } + + /** + * Sets the "to" pattern. Required. + */ + function setTo($to) { + $index = strrpos($to, '*'); + if ($index === false) { + $this->toPrefix = $to; + $this->toPostfix = ""; + } else { + $this->toPrefix = substr($to, 0, $index); + $this->toPostfix = substr($to, $index+1); + } + } + + private function _extractVariablePart($_name) { + // ergh, i really hate php's string functions .... all but natural + $start = ($this->prefixLength === 0) ? 0 : $this->prefixLength; + $end = ($this->postfixLength === 0) ? strlen($_name) : strlen($_name) - $this->postfixLength; + $len = $end-$start; + return substr($_name, $start, $len); + } + +} diff --git a/gulliver/thirdparty/phing/mappers/IdentityMapper.php b/gulliver/thirdparty/phing/mappers/IdentityMapper.php new file mode 100644 index 000000000..d4de6060c --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/IdentityMapper.php @@ -0,0 +1,54 @@ +. + */ + +require_once 'phing/mappers/FileNameMapper.php'; + +/** + * This mapper does nothing ;) + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.7 $ + * @package phing.mappers + */ +class IdentityMapper implements FileNameMapper { + + /** + * The mapper implementation. Basically does nothing in this case. + * + * @param string $sourceFileName The data the mapper works on. + * @return array The data after the mapper has been applied + */ + function main($sourceFileName) { + return array($sourceFileName); + } + + /** + * Ignored here. + */ + function setTo($to) {} + + /** + * Ignored here. + */ + function setFrom($from) {} + +} diff --git a/gulliver/thirdparty/phing/mappers/MergeMapper.php b/gulliver/thirdparty/phing/mappers/MergeMapper.php new file mode 100644 index 000000000..86d957d76 --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/MergeMapper.php @@ -0,0 +1,69 @@ +. + */ + +include_once 'phing/mappers/FileNameMapper.php'; + +/** + * For merging files into a single file. In practice just returns whatever value + * was set for "to". + * + * @author Andreas Aderhold + * @version $Revision: 1.8 $ + * @package phing.mappers + */ +class MergeMapper implements FileNameMapper { + + /** the merge */ + private $mergedFile; + + /** + * The mapper implementation. Basically does nothing in this case. + * + * @param mixed The data the mapper works on + * @returns mixed The data after the mapper has been applied + * @access public + * @author Andreas Aderhold, andi@binarycloud.com + */ + function main($sourceFileName) { + if ($this->mergedFile === null) { + throw new BuildException("MergeMapper error, to attribute not set"); + } + return array($this->mergedFile); + } + + /** + * Accessor. Sets the to property + * + * @param string To what this mapper should convert the from string + * @returns boolean True + * @access public + * @author Andreas Aderhold, andi@binarycloud.com + */ + function setTo($to) { + $this->mergedFile = $to; + } + + /** + * Ignored. + */ + function setFrom($from) {} + +} diff --git a/gulliver/thirdparty/phing/mappers/RegexpMapper.php b/gulliver/thirdparty/phing/mappers/RegexpMapper.php new file mode 100644 index 000000000..dfb775473 --- /dev/null +++ b/gulliver/thirdparty/phing/mappers/RegexpMapper.php @@ -0,0 +1,97 @@ +. + */ + +require_once 'phing/mappers/FileNameMapper.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/util/regexp/Regexp.php'; + +/** + * Uses regular expressions to perform filename transformations. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.9 $ + * @package phing.mappers + */ +class RegexpMapper implements FileNameMapper { + + /** + * @var string + */ + private $to; + + /** + * The Regexp engine. + * @var Regexp + */ + private $reg; + + function __construct() { + // instantiage regexp matcher here + $this->reg = new Regexp(); + } + + /** + * Sets the "from" pattern. Required. + */ + function setFrom($from) { + $this->reg->SetPattern($from); + } + + /** + * Sets the "to" pattern. Required. + */ + function setTo($to) { + + // [HL] I'm changing the way this works for now to just use string + //$this->to = StringHelper::toCharArray($to); + + $this->to = $to; + } + + function main($sourceFileName) { + if ($this->reg === null || $this->to === null || !$this->reg->matches((string) $sourceFileName)) { + return null; + } + return array($this->replaceReferences($sourceFileName)); + } + + /** + * Replace all backreferences in the to pattern with the matched groups. + * groups of the source. + * @param string $source The source filename. + */ + private function replaceReferences($source) { + + // FIXME + // Can't we just use engine->replace() to handle this? the Preg engine + // will automatically convert \1 references to $1 + + // the expression has already been processed (when ->matches() was run in Main()) + // so no need to pass $source again to the engine. + $groups = (array) $this->reg->getGroups(); + + // replace \1 with value of $groups[1] and return the modified "to" string + return preg_replace('/\\\([\d]+)/e', "\$groups[$1]", $this->to); + } + +} + diff --git a/gulliver/thirdparty/phing/parser/AbstractHandler.php b/gulliver/thirdparty/phing/parser/AbstractHandler.php new file mode 100644 index 000000000..50e66fb8e --- /dev/null +++ b/gulliver/thirdparty/phing/parser/AbstractHandler.php @@ -0,0 +1,98 @@ +. + */ + +include_once 'phing/parser/ExpatParseException.php'; + +/** + * This is an abstract class all SAX handler classes must extend + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.6 $ + * @package phing.parser + */ +abstract class AbstractHandler { + + public $parentHandler = null; + public $parser = null; + + /** + * Constructs a SAX handler parser. + * + * The constructor must be called by all derived classes. + * + * @param object the parser object + * @param object the parent handler of this handler + */ + protected function __construct($parser, $parentHandler) { + $this->parentHandler = $parentHandler; + $this->parser = $parser; + $this->parser->setHandler($this); + } + + /** + * Gets invoked when a XML open tag occurs + * + * Must be overloaded by the child class. Throws an ExpatParseException + * if there is no handler registered for an element. + * + * @param string the name of the XML element + * @param array the attributes of the XML element + */ + public function startElement($name, $attribs) { + throw new ExpatParseException("Unexpected element $name"); + } + + /** + * Gets invoked when element closes method. + * + */ + protected function finished() {} + + /** + * Gets invoked when a XML element ends. + * + * Can be overloaded by the child class. But should not. It hands + * over control to the parentHandler of this. + * + * @param string the name of the XML element + */ + public function endElement($name) { + $this->finished(); + $this->parser->setHandler($this->parentHandler); + } + + /** + * Invoked by occurance of #PCDATA. + * + * @param string the name of the XML element + * @exception ExpatParserException if there is no CDATA but method + * was called + * @access public + */ + public function characters($data) { + $s = trim($data); + if (strlen($s) > 0) { + throw new ExpatParseException("Unexpected text '$s'", $this->parser->getLocation()); + } + } +} diff --git a/gulliver/thirdparty/phing/parser/AbstractSAXParser.php b/gulliver/thirdparty/phing/parser/AbstractSAXParser.php new file mode 100644 index 000000000..9b947f5ba --- /dev/null +++ b/gulliver/thirdparty/phing/parser/AbstractSAXParser.php @@ -0,0 +1,140 @@ +. + */ + +/** + * The abstract SAX parser class. + * + * This class represents a SAX parser. It is a abstract calss that must be + * implemented by the real parser that must extend this class + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.13 $ + * @package phing.parser + */ +abstract class AbstractSAXParser { + + /** The AbstractHandler object. */ + protected $handler; + + /** + * Constructs a SAX parser + */ + function __construct() {} + + /** + * Sets options for PHP interal parser. Must be implemented by the parser + * class if it should be used. + */ + abstract function parserSetOption($opt, $val); + + /** + * Sets the current element handler object for this parser. Usually this + * is an object using extending "AbstractHandler". + * + * @param AbstractHandler $obj The handler object. + */ + function setHandler( $obj) { + $this->handler = $obj; + } + + /** + * Method that gets invoked when the parser runs over a XML start element. + * + * This method is called by PHP's internal parser funcitons and registered + * in the actual parser implementation. + * It gives control to the current active handler object by calling the + * startElement() method. + * + * BECAUSE OF PROBLEMS WITH EXCEPTIONS BUBBLING UP THROUGH xml_parse() THIS + * METHOD WILL CALL Phing::halt(-1) ON EXCEPTION. + * + * @param object the php's internal parser handle + * @param string the open tag name + * @param array the tag's attributes if any + */ + function startElement($parser, $name, $attribs) { + try { + $this->handler->startElement($name, $attribs); + } catch (Exception $e) { + print "[Exception in XML parsing]\n"; + print $e; + Phing::halt(-1); + } + } + + /** + * Method that gets invoked when the parser runs over a XML close element. + * + * This method is called by PHP's internal parser funcitons and registered + * in the actual parser implementation. + * + * It gives control to the current active handler object by calling the + * endElement() method. + * + * BECAUSE OF PROBLEMS WITH EXCEPTIONS BUBBLING UP THROUGH xml_parse() THIS + * METHOD WILL CALL Phing::halt(-1) ON EXCEPTION. + * + * @param object the php's internal parser handle + * @param string the closing tag name + */ + function endElement($parser, $name) { + try { + $this->handler->endElement($name); + } catch (Exception $e) { + print "[Exception in XML parsing]\n"; + print $e; + Phing::halt(-1); + } + } + + /** + * Method that gets invoked when the parser runs over CDATA. + * + * This method is called by PHP's internal parser functions and registered + * in the actual parser implementation. + * + * It gives control to the current active handler object by calling the + * characters() method. That processes the given CDATA. + * + * BECAUSE OF PROBLEMS WITH EXCEPTIONS BUBBLING UP THROUGH xml_parse() THIS + * METHOD WILL CALL Phing::halt(-1) ON EXCEPTION. + * + * @param resource $parser php's internal parser handle. + * @param string $data the CDATA + */ + function characters($parser, $data) { + try { + $this->handler->characters($data); + } catch (Exception $e) { + print "[Exception in XML parsing]\n"; + print $e; + Phing::halt(-1); + } + } + + /** + * Entrypoint for parser. This method needs to be implemented by the + * child classt that utilizes the concrete parser + */ + abstract function parse(); +} diff --git a/gulliver/thirdparty/phing/parser/DataTypeHandler.php b/gulliver/thirdparty/phing/parser/DataTypeHandler.php new file mode 100644 index 000000000..a225412c7 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/DataTypeHandler.php @@ -0,0 +1,144 @@ +. + */ + +include_once 'phing/RuntimeConfigurable.php'; + +/** + * Configures a Project (complete with Targets and Tasks) based on + * a XML build file. + *

    + * Design/ZE2 migration note: + * If PHP would support nested classes. All the phing/parser/*Filter + * classes would be nested within this class + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.8 $ $Date: 2005/11/02 13:55:33 $ + * @access public + * @package phing.parser + */ + +class DataTypeHandler extends AbstractHandler { + + private $target; + private $element; + private $wrapper; + + /** + * Constructs a new DataTypeHandler and sets up everything. + * + * @param AbstractSAXParser $parser The XML parser (default: ExpatParser) + * @param AbstractHandler $parentHandler The parent handler that invoked this handler. + * @param ProjectConfigurator $configurator The ProjectConfigurator object + * @param Target $target The target object this datatype is contained in (null for top-level datatypes). + */ + function __construct(AbstractSAXParser $parser, AbstractHandler $parentHandler, ProjectConfigurator $configurator, $target = null) { // FIXME b2 typehinting + parent::__construct($parser, $parentHandler); + $this->target = $target; + $this->configurator = $configurator; + } + + /** + * Executes initialization actions required to setup the data structures + * related to the tag. + *

    + * This includes: + *

      + *
    • creation of the datatype object
    • + *
    • calling the setters for attributes
    • + *
    • adding the type to the target object if any
    • + *
    • adding a reference to the task (if id attribute is given)
    • + *
    + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @throws ExpatParseException if attributes are incomplete or invalid + * @access public + */ + function init($propType, $attrs) { + // shorthands + $project = $this->configurator->project; + $configurator = $this->configurator; + + try {//try + $this->element = $project->createDataType($propType); + + if ($this->element === null) { + throw new BuildException("Unknown data type $propType"); + } + + if ($this->target !== null) { + $this->wrapper = new RuntimeConfigurable($this->element, $propType); + $this->wrapper->setAttributes($attrs); + $this->target->addDataType($this->wrapper); + } else { + $configurator->configure($this->element, $attrs, $project); + $configurator->configureId($this->element, $attrs); + } + + } catch (BuildException $exc) { + throw new ExpatParseException($exc, $this->parser->getLocation()); + } + } + + /** + * Handles character data. + * + * @param string the CDATA that comes in + * @access public + */ + function characters($data) { + $project = $this->configurator->project; + try {//try + $this->configurator->addText($project, $this->element, $data); + } catch (BuildException $exc) { + throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation()); + } + } + + /** + * Checks for nested tags within the current one. Creates and calls + * handlers respectively. + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @access public + */ + function startElement($name, $attrs) { + $nef = new NestedElementHandler($this->parser, $this, $this->configurator, $this->element, $this->wrapper, $this->target); + $nef->init($name, $attrs); + } + + /** + * Overrides endElement for data types. Tells the type + * handler that processing the element had been finished so + * handlers know they can perform actions that need to be + * based on the data contained within the element. + * + * @param string the name of the XML element + * @return void + */ + function endElement($name) { + $this->element->parsingComplete(); + parent::endElement($name); + } + +} diff --git a/gulliver/thirdparty/phing/parser/ExpatParseException.php b/gulliver/thirdparty/phing/parser/ExpatParseException.php new file mode 100644 index 000000000..faf5596cc --- /dev/null +++ b/gulliver/thirdparty/phing/parser/ExpatParseException.php @@ -0,0 +1,31 @@ +. + */ + +require_once 'phing/BuildException.php'; + +/** + * This class throws errors for Expat, the XML processor. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.5 $ $Date: 2003/11/19 05:48:28 $ + * @package phing.parser + */ +class ExpatParseException extends BuildException {} diff --git a/gulliver/thirdparty/phing/parser/ExpatParser.php b/gulliver/thirdparty/phing/parser/ExpatParser.php new file mode 100644 index 000000000..a20ebe694 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/ExpatParser.php @@ -0,0 +1,140 @@ +. + */ + +require_once 'phing/parser/AbstractSAXParser.php'; +include_once 'phing/parser/ExpatParseException.php'; +include_once 'phing/system/io/IOException.php'; +include_once 'phing/system/io/FileReader.php'; + +/** + * This class is a wrapper for the PHP's internal expat parser. + * + * It takes an XML file represented by a abstract path name, and starts + * parsing the file and calling the different "trap" methods inherited from + * the AbstractParser class. + * + * Those methods then invoke the represenatative methods in the registered + * handler classes. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.8 $ $Date: 2005/05/26 13:10:52 $ + * @access public + * @package phing.parser + */ + +class ExpatParser extends AbstractSAXParser { + + /** @var resource */ + private $parser; + + /** @var Reader */ + private $reader; + + private $file; + + private $buffer = 4096; + + private $error_string = ""; + + private $line = 0; + + /** @var Location Current cursor pos in XML file. */ + private $location; + + /** + * Constructs a new ExpatParser object. + * + * The constructor accepts a PhingFile object that represents the filename + * for the file to be parsed. It sets up php's internal expat parser + * and options. + * + * @param Reader $reader The Reader Object that is to be read from. + * @param string $filename Filename to read. + * @throws Exception if the given argument is not a PhingFile object + */ + function __construct(Reader $reader, $filename=null) { + + $this->reader = $reader; + if ($filename !== null) { + $this->file = new PhingFile($filename); + } + $this->parser = xml_parser_create(); + $this->buffer = 4096; + $this->location = new Location(); + xml_set_object($this->parser, $this); + xml_set_element_handler($this->parser, array($this,"startElement"),array($this,"endElement")); + xml_set_character_data_handler($this->parser, array($this, "characters")); + } + + /** + * Override PHP's parser default settings, created in the constructor. + * + * @param string the option to set + * @throws mixed the value to set + * @return boolean true if the option could be set, otherwise false + * @access public + */ + function parserSetOption($opt, $val) { + return xml_parser_set_option($this->parser, $opt, $val); + } + + /** + * Returns the location object of the current parsed element. It describes + * the location of the element within the XML file (line, char) + * + * @return object the location of the current parser + * @access public + */ + function getLocation() { + if ($this->file !== null) { + $path = $this->file->getAbsolutePath(); + } else { + $path = $this->reader->getResource(); + } + $this->location = new Location($path, xml_get_current_line_number($this->parser), xml_get_current_column_number($this->parser)); + return $this->location; + } + + /** + * Starts the parsing process. + * + * @param string the option to set + * @return int 1 if the parsing succeeded + * @throws ExpatParseException if something gone wrong during parsing + * @throws IOException if XML file can not be accessed + * @access public + */ + function parse() { + + while ( ($data = $this->reader->read()) !== -1 ) { + if (!xml_parse($this->parser, $data, $this->reader->eof())) { + $error = xml_error_string(xml_get_error_code($this->parser)); + $e = new ExpatParseException($error, $this->getLocation()); + xml_parser_free($this->parser); + throw $e; + } + } + xml_parser_free($this->parser); + + return 1; + } +} diff --git a/gulliver/thirdparty/phing/parser/Location.php b/gulliver/thirdparty/phing/parser/Location.php new file mode 100644 index 000000000..2be1bc863 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/Location.php @@ -0,0 +1,72 @@ +. + */ + +/** + * Stores the file name and line number of a XML file + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.6 $ $Date: 2003/12/24 13:02:09 $ + * @access public + * @package phing.parser + */ + +class Location { + + private $fileName; + private $lineNumber; + private $columnNumber; + + /** + * Constructs the location consisting of a file name and line number + * + * @param string the filename + * @param integer the line number + * @param integer the column number + * @access public + */ + function Location($fileName = null, $lineNumber = null, $columnNumber = null) { + $this->fileName = $fileName; + $this->lineNumber = $lineNumber; + $this->columnNumber = $columnNumber; + } + + /** + * Returns the file name, line number and a trailing space. + * + * An error message can be appended easily. For unknown locations, + * returns empty string. + * + * @return string the string representation of this Location object + * @access public + */ + function toString() { + $buf = ""; + if ($this->fileName !== null) { + $buf.=$this->fileName; + if ($this->lineNumber !== null) { + $buf.= ":".$this->lineNumber; + } + $buf.=":".$this->columnNumber; + } + return (string) $buf; + } +} diff --git a/gulliver/thirdparty/phing/parser/NestedElementHandler.php b/gulliver/thirdparty/phing/parser/NestedElementHandler.php new file mode 100644 index 000000000..1b3cfb114 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/NestedElementHandler.php @@ -0,0 +1,186 @@ +. + */ + +include_once 'phing/IntrospectionHelper.php'; +include_once 'phing/TaskContainer.php'; + +/** + * The nested element handler class. + * + * This class handles the occurance of runtime registered tags like + * datatypes (fileset, patternset, etc) and it's possible nested tags. It + * introspects the implementation of the class and sets up the data structures. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.10 $ $Date: 2005/10/04 19:13:44 $ + * @access public + * @package phing.parser + */ + +class NestedElementHandler extends AbstractHandler { + + /** + * Reference to the parent object that represents the parent tag + * of this nested element + * @var object + */ + private $parent; + + /** + * Reference to the child object that represents the child tag + * of this nested element + * @var object + */ + private $child; + + /** + * Reference to the parent wrapper object + * @var object + */ + private $parentWrapper; + + /** + * Reference to the child wrapper object + * @var object + */ + private $childWrapper; + + /** + * Reference to the related target object + * @var object the target instance + */ + private $target; + + /** + * Constructs a new NestedElement handler and sets up everything. + * + * @param object the ExpatParser object + * @param object the parent handler that invoked this handler + * @param object the ProjectConfigurator object + * @param object the parent object this element is contained in + * @param object the parent wrapper object + * @param object the target object this task is contained in + * @access public + */ + function __construct($parser, $parentHandler, $configurator, $parent, $parentWrapper, $target) { + parent::__construct($parser, $parentHandler); + $this->configurator = $configurator; + if ($parent instanceof TaskAdapter) { + $this->parent = $parent->getProxy(); + } else { + $this->parent = $parent; + } + $this->parentWrapper = $parentWrapper; + $this->target = $target; + } + + /** + * Executes initialization actions required to setup the data structures + * related to the tag. + *

    + * This includes: + *

      + *
    • creation of the nested element
    • + *
    • calling the setters for attributes
    • + *
    • adding the element to the container object
    • + *
    • adding a reference to the element (if id attribute is given)
    • + *
    + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @throws ExpatParseException if the setup process fails + * @access public + */ + function init($propType, $attrs) { + $configurator = $this->configurator; + $project = $this->configurator->project; + + // introspect the parent class that is custom + $parentClass = get_class($this->parent); + $ih = IntrospectionHelper::getHelper($parentClass); + try { + if ($this->parent instanceof UnknownElement) { + $this->child = new UnknownElement(strtolower($propType)); + $this->parent->addChild($this->child); + } else { + $this->child = $ih->createElement($project, $this->parent, strtolower($propType)); + } + + $configurator->configureId($this->child, $attrs); + + if ($this->parentWrapper !== null) { + $this->childWrapper = new RuntimeConfigurable($this->child, $propType); + $this->childWrapper->setAttributes($attrs); + $this->parentWrapper->addChild($this->childWrapper); + } else { + $configurator->configure($this->child, $attrs, $project); + $ih->storeElement($project, $this->parent, $this->child, strtolower($propType)); + } + } catch (BuildException $exc) { + throw new ExpatParseException("Error initializing nested element <$propType>", $exc, $this->parser->getLocation()); + } + } + + /** + * Handles character data. + * + * @param string the CDATA that comes in + * @throws ExpatParseException if the CDATA could not be set-up properly + * @access public + */ + function characters($data) { + + $configurator = $this->configurator; + $project = $this->configurator->project; + + if ($this->parentWrapper === null) { + try { + $configurator->addText($project, $this->child, $data); + } catch (BuildException $exc) { + throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation()); + } + } else { + $this->childWrapper->addText($data); + } + } + + /** + * Checks for nested tags within the current one. Creates and calls + * handlers respectively. + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @access public + */ + function startElement($name, $attrs) { + //print(get_class($this) . " name = $name, attrs = " . implode(",",$attrs) . "\n"); + if ($this->child instanceof TaskContainer) { + // taskcontainer nested element can contain other tasks - no other + // nested elements possible + $tc = new TaskHandler($this->parser, $this, $this->configurator, $this->child, $this->childWrapper, $this->target); + $tc->init($name, $attrs); + } else { + $neh = new NestedElementHandler($this->parser, $this, $this->configurator, $this->child, $this->childWrapper, $this->target); + $neh->init($name, $attrs); + } + } +} diff --git a/gulliver/thirdparty/phing/parser/ProjectConfigurator.php b/gulliver/thirdparty/phing/parser/ProjectConfigurator.php new file mode 100644 index 000000000..7fdd118bf --- /dev/null +++ b/gulliver/thirdparty/phing/parser/ProjectConfigurator.php @@ -0,0 +1,246 @@ +. + */ + +include_once 'phing/system/io/BufferedReader.php'; +include_once 'phing/system/io/FileReader.php'; +include_once 'phing/BuildException.php'; +include_once 'phing/system/lang/FileNotFoundException.php'; +include_once 'phing/system/io/PhingFile.php'; + +/** + * The datatype handler class. + * + * This class handles the occurance of registered datatype tags like + * FileSet + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.17 $ $Date: 2006/01/06 14:57:18 $ + * @access public + * @package phing.parser + */ +class ProjectConfigurator { + + public $project; + public $locator; + + public $buildFile; + public $buildFileParent; + + /** + * Static call to ProjectConfigurator. Use this to configure a + * project. Do not use the new operator. + * + * @param object the Project instance this configurator should use + * @param object the buildfile object the parser should use + * @access public + */ + public static function configureProject(Project $project, PhingFile $buildFile) { + $pc = new ProjectConfigurator($project, $buildFile); + $pc->parse(); + } + + /** + * Constructs a new ProjectConfigurator object + * This constructor is private. Use a static call to + * configureProject to configure a project. + * + * @param object the Project instance this configurator should use + * @param object the buildfile object the parser should use + * @access private + */ + function __construct(Project $project, PhingFile $buildFile) { + $this->project = $project; + $this->buildFile = new PhingFile($buildFile->getAbsolutePath()); + $this->buildFileParent = new PhingFile($this->buildFile->getParent()); + } + + /** + * Creates the ExpatParser, sets root handler and kick off parsing + * process. + * + * @throws BuildException if there is any kind of execption during + * the parsing process + * @access private + */ + protected function parse() { + try { + $reader = new BufferedReader(new FileReader($this->buildFile)); + $reader->open(); + $parser = new ExpatParser($reader); + $parser->parserSetOption(XML_OPTION_CASE_FOLDING,0); + $parser->setHandler(new RootHandler($parser, $this)); + $this->project->log("parsing buildfile ".$this->buildFile->getName(), PROJECT_MSG_VERBOSE); + $parser->parse(); + $reader->close(); + } catch (Exception $exc) { + throw new BuildException("Error reading project file", $exc); + } + } + + /** + * Configures an element and resolves eventually given properties. + * + * @param object the element to configure + * @param array the element's attributes + * @param object the project this element belongs to + * @throws Exception if arguments are not valid + * @throws BuildException if attributes can not be configured + * @access public + */ + public static function configure($target, $attrs, Project $project) { + + if ($target instanceof TaskAdapter) { + $target = $target->getProxy(); + } + + // if the target is an UnknownElement, this means that the tag had not been registered + // when the enclosing element (task, target, etc.) was configured. It is possible, however, + // that the tag was registered (e.g. using ) after the original configuration. + // ... so, try to load it again: + if ($target instanceof UnknownElement) { + $tryTarget = $project->createTask($target->getTaskType()); + if ($tryTarget) { + $target = $tryTarget; + } + } + + $bean = get_class($target); + $ih = IntrospectionHelper::getHelper($bean); + + foreach ($attrs as $key => $value) { + if ($key == 'id') { + continue; + // throw new BuildException("I'd must be set Externally"); + } + $value = self::replaceProperties($project, $value, $project->getProperties()); + try { // try to set the attribute + $ih->setAttribute($project, $target, strtolower($key), $value); + } catch (BuildException $be) { + // id attribute must be set externally + if ($key !== "id") { + throw $be; + } + } + } + } + + /** + * Configures the #CDATA of an element. + * + * @param object the project this element belongs to + * @param object the element to configure + * @param string the element's #CDATA + * @access public + */ + public static function addText($project, $target, $text = null) { + if ($text === null || strlen(trim($text)) === 0) { + return; + } + $ih = IntrospectionHelper::getHelper(get_class($target)); + $text = self::replaceProperties($project, $text, $project->getProperties()); + $ih->addText($project, $target, $text); + } + + /** + * Stores a configured child element into its parent object + * + * @param object the project this element belongs to + * @param object the parent element + * @param object the child element + * @param string the XML tagname + * @access public + */ + public static function storeChild($project, $parent, $child, $tag) { + $ih = IntrospectionHelper::getHelper(get_class($parent)); + $ih->storeElement($project, $parent, $child, $tag); + } + + // The following two properties are a sort of hack + // to enable a static function to serve as the callback + // for preg_replace_callback(). Clearly we cannot use object + // variables, since the replaceProperties() is called statically. + // This is IMO better than using global variables in the callback. + + private static $propReplaceProject; + private static $propReplaceProperties; + + /** + * Replace ${} style constructions in the given value with the + * string value of the corresponding data types. This method is + * static. + * + * @param object the project that should be used for property look-ups + * @param string the string to be scanned for property references + * @param array proeprty keys + * @return string the replaced string or null if the string + * itself was null + */ + public static function replaceProperties(Project $project, $value, $keys) { + + if ($value === null) { + return null; + } + + // These are a "hack" to support static callback for preg_replace_callback() + + // make sure these get initialized every time + self::$propReplaceProperties = $keys; + self::$propReplaceProject = $project; + + // Because we're not doing anything special (like multiple passes), + // regex is the simplest / fastest. PropertyTask, though, uses + // the old parsePropertyString() method, since it has more stringent + // requirements. + + $sb = preg_replace_callback('/\$\{([^}]+)\}/', array('ProjectConfigurator', 'replacePropertyCallback'), $value); + return $sb; + } + + /** + * Private [static] function for use by preg_replace_callback to replace a single param. + * This method makes use of a static variable to hold the + */ + private static function replacePropertyCallback($matches) + { + $propertyName = $matches[1]; + if (!isset(self::$propReplaceProperties[$propertyName])) { + self::$propReplaceProject->log('Property ${'.$propertyName.'} has not been set.', PROJECT_MSG_VERBOSE); + return $matches[0]; + } else { + self::$propReplaceProject->log('Property ${'.$propertyName.'} => ' . self::$propReplaceProperties[$propertyName], PROJECT_MSG_DEBUG); + } + return self::$propReplaceProperties[$propertyName]; + } + + /** + * Scan Attributes for the id attribute and maybe add a reference to + * project. + * + * @param object the element's object + * @param array the element's attributes + */ + function configureId(&$target, $attr) { + if (isset($attr['id']) && $attr['id'] !== null) { + $this->project->addReference($attr['id'], $target); + } + } +} diff --git a/gulliver/thirdparty/phing/parser/ProjectHandler.php b/gulliver/thirdparty/phing/parser/ProjectHandler.php new file mode 100644 index 000000000..85b44dc13 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/ProjectHandler.php @@ -0,0 +1,146 @@ +. + */ + +require_once 'phing/parser/AbstractHandler.php'; +require_once 'phing/system/io/PhingFile.php'; + +/** + * Handler class for the XML element This class handles all elements + * under the element. + * + * @author Andreas Aderhold + * @copyright (c) 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.14 $ $Date: 2005/10/04 19:13:44 $ + * @access public + * @package phing.parser + */ +class ProjectHandler extends AbstractHandler { + + /** + * The phing project configurator object. + * @var ProjectConfigurator + */ + private $configurator; + + /** + * Constructs a new ProjectHandler + * + * @param object the ExpatParser object + * @param object the parent handler that invoked this handler + * @param object the ProjectConfigurator object + * @access public + */ + function __construct($parser, $parentHandler, $configurator) { + $this->configurator = $configurator; + parent::__construct($parser, $parentHandler); + } + + /** + * Executes initialization actions required to setup the project. Usually + * this method handles the attributes of a tag. + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @param object the ProjectConfigurator object + * @throws ExpatParseException if attributes are incomplete or invalid + * @access public + */ + function init($tag, $attrs) { + $def = null; + $name = null; + $id = null; + $baseDir = null; + + // some shorthands + $project = $this->configurator->project; + $buildFileParent = $this->configurator->buildFileParent; + + foreach ($attrs as $key => $value) { + if ($key === "default") { + $def = $value; + } elseif ($key === "name") { + $name = $value; + } elseif ($key === "id") { + $id = $value; + } elseif ($key === "basedir") { + $baseDir = $value; + } else { + throw new ExpatParseException("Unexpected attribute '$key'"); + } + } + if ($def === null) { + throw new ExpatParseException("The default attribute of project is required"); + } + $project->setDefaultTarget($def); + + if ($name !== null) { + $project->setName($name); + $project->addReference($name, $project); + } + + if ($id !== null) { + $project->addReference($id, $project); + } + + if ($project->getProperty("project.basedir") !== null) { + $project->setBasedir($project->getProperty("project.basedir")); + } else { + if ($baseDir === null) { + $project->setBasedir($buildFileParent->getAbsolutePath()); + } else { + // check whether the user has specified an absolute path + $f = new PhingFile($baseDir); + if ($f->isAbsolute()) { + $project->setBasedir($baseDir); + } else { + $project->setBaseDir($project->resolveFile($baseDir, $buildFileParent)); + } + } + } + } + + /** + * Handles start elements within the tag by creating and + * calling the required handlers for the detected element. + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @throws ExpatParseException if a unxepected element occurs + * @access public + */ + function startElement($name, $attrs) { + + $project = $this->configurator->project; + $types = $project->getDataTypeDefinitions(); + + if ($name == "target") { + $tf = new TargetHandler($this->parser, $this, $this->configurator); + $tf->init($name, $attrs); + } elseif (isset($types[$name])) { + $tyf = new DataTypeHandler($this->parser, $this, $this->configurator); + $tyf->init($name, $attrs); + } else { + $tf = new TaskHandler($this->parser, $this, $this->configurator); + $tf->init($name, $attrs); + } + } +} + diff --git a/gulliver/thirdparty/phing/parser/RootHandler.php b/gulliver/thirdparty/phing/parser/RootHandler.php new file mode 100644 index 000000000..eabeed6bd --- /dev/null +++ b/gulliver/thirdparty/phing/parser/RootHandler.php @@ -0,0 +1,82 @@ +. + */ + +require_once 'phing/parser/AbstractHandler.php'; +include_once 'phing/parser/ExpatParseException.php'; +include_once 'phing/parser/ProjectHandler.php'; + +/** + * Root filter class for a phing buildfile. + * + * The root filter is called by the parser first. This is where the phing + * specific parsing starts. RootHandler decides what to do next. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.7 $ + * @package phing.parser + */ +class RootHandler extends AbstractHandler { + + /** + * The phing project configurator object + */ + private $configurator; + + /** + * Constructs a new RootHandler + * + * The root filter is required so the parser knows what to do. It's + * called by the ExpatParser that is instatiated in ProjectConfigurator. + * + * It recieves the expat parse object ref and a reference to the + * configurator + * + * @param AbstractSAXParser $parser The ExpatParser object. + * @param ProjectConfigurator $configurator The ProjectConfigurator object. + */ + function __construct(AbstractSAXParser $parser, ProjectConfigurator $configurator) { + $this->configurator = $configurator; + parent::__construct($parser, $this); + } + + /** + * Kick off a custom action for a start element tag. + * + * The root element of our buildfile is the <project> element. The + * root filter handles this element if it occurs, creates ProjectHandler + * to handle any nested tags & attributes of the <project> tag, + * and calls init. + * + * @param string $tag The xml tagname + * @param array $attrs The attributes of the tag + * @throws ExpatParseException if the first element within our build file + * is not the >project< element + */ + function startElement($tag, $attrs) { + if ($tag === "project") { + $ph = new ProjectHandler($this->parser, $this, $this->configurator); + $ph->init($tag, $attrs); + } else { + throw new ExpatParseException("Unexpected tag <$tag> in top-level of build file.", $this->parser->getLocation()); + } + } +} diff --git a/gulliver/thirdparty/phing/parser/TargetHandler.php b/gulliver/thirdparty/phing/parser/TargetHandler.php new file mode 100644 index 000000000..1d3bb5c2c --- /dev/null +++ b/gulliver/thirdparty/phing/parser/TargetHandler.php @@ -0,0 +1,149 @@ +. + */ + +require_once 'phing/parser/AbstractHandler.php'; + +/** + * The target handler class. + * + * This class handles the occurance of a tag and it's possible + * nested tags (datatypes and tasks). + * + * @author Andreas Aderhold + * @copyright 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.10 $ + * @package phing.parser + */ +class TargetHandler extends AbstractHandler { + + /** + * Reference to the target object that represents the currently parsed + * target. + * @var object the target instance + */ + private $target; + + /** + * The phing project configurator object + * @var ProjectConfigurator + */ + private $configurator; + + /** + * Constructs a new TargetHandler + * + * @param object the ExpatParser object + * @param object the parent handler that invoked this handler + * @param object the ProjectConfigurator object + */ + function __construct(AbstractSAXParser $parser, AbstractHandler $parentHandler, ProjectConfigurator $configurator) { + parent::__construct($parser, $parentHandler); + $this->configurator = $configurator; + } + + /** + * Executes initialization actions required to setup the data structures + * related to the tag. + *

    + * This includes: + *

      + *
    • creation of the target object
    • + *
    • calling the setters for attributes
    • + *
    • adding the target to the project
    • + *
    • adding a reference to the target (if id attribute is given)
    • + *
    + * + * @param string the tag that comes in + * @param array attributes the tag carries + * @throws ExpatParseException if attributes are incomplete or invalid + */ + function init($tag, $attrs) { + $name = null; + $depends = ""; + $ifCond = null; + $unlessCond = null; + $id = null; + $description = null; + + foreach($attrs as $key => $value) { + if ($key==="name") { + $name = (string) $value; + } else if ($key==="depends") { + $depends = (string) $value; + } else if ($key==="if") { + $ifCond = (string) $value; + } else if ($key==="unless") { + $unlessCond = (string) $value; + } else if ($key==="id") { + $id = (string) $value; + } else if ($key==="description") { + $description = (string)$value; + } else { + throw new ExpatParseException("Unexpected attribute '$key'", $this->parser->getLocation()); + } + } + + if ($name === null) { + throw new ExpatParseException("target element appears without a name attribute", $this->parser->getLocation()); + } + + // shorthand + $project = $this->configurator->project; + + $this->target = new Target(); + $this->target->setName($name); + $this->target->setIf($ifCond); + $this->target->setUnless($unlessCond); + $this->target->setDescription($description); + + $project->addTarget($name, $this->target); + + if ($id !== null && $id !== "") { + $project->addReference($id, $this->target); + } + // take care of dependencies + if (strlen($depends) > 0) { + $this->target->setDepends($depends); + } + + } + + /** + * Checks for nested tags within the current one. Creates and calls + * handlers respectively. + * + * @param string the tag that comes in + * @param array attributes the tag carries + */ + function startElement($name, $attrs) { + // shorthands + $project = $this->configurator->project; + $types = $project->getDataTypeDefinitions(); + + if (isset($types[$name])) { + $th = new DataTypeHandler($this->parser, $this, $this->configurator, $this->target); + $th->init($name, $attrs); + } else { + $tmp = new TaskHandler($this->parser, $this, $this->configurator, $this->target, null, $this->target); + $tmp->init($name, $attrs); + } + } +} diff --git a/gulliver/thirdparty/phing/parser/TaskHandler.php b/gulliver/thirdparty/phing/parser/TaskHandler.php new file mode 100644 index 000000000..cf4f39417 --- /dev/null +++ b/gulliver/thirdparty/phing/parser/TaskHandler.php @@ -0,0 +1,234 @@ +. + */ + +include_once 'phing/UnknownElement.php'; + +/** + * The task handler class. + * + * This class handles the occurance of a tag and it's possible + * nested tags (datatypes and tasks) that may be unknown off bat and are + * initialized on the fly. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.10 $ + * @package phing.parser + */ +class TaskHandler extends AbstractHandler { + + /** + * Reference to the target object that contains the currently parsed + * task + * @var object the target instance + */ + private $target; + + /** + * Reference to the target object that represents the currently parsed + * target. This must not necessarily be a target, hence extra variable. + * @var object the target instance + */ + private $container; + + /** + * Reference to the task object that represents the currently parsed + * target. + * @var Task + */ + private $task; + + /** + * Wrapper for the parent element, if any. The wrapper for this + * element will be added to this wrapper as a child. + * @var RuntimeConfigurable + */ + private $parentWrapper; + + /** + * Wrapper for this element which takes care of actually configuring + * the element, if this element is contained within a target. + * Otherwise the configuration is performed with the configure method. + * @see ProjectHelper::configure(Object,AttributeList,Project) + */ + private $wrapper; + + /** + * The phing project configurator object + * @var ProjectConfigurator + */ + private $configurator; + + /** + * Constructs a new TaskHandler and sets up everything. + * + * @param AbstractSAXParser The ExpatParser object + * @param object $parentHandler The parent handler that invoked this handler + * @param ProjectConfigurator $configurator + * @param TaskContainer $container The container object this task is contained in (null for top-level tasks). + * @param RuntimeConfigurable $parentWrapper Wrapper for the parent element, if any. + * @param Target $target The target object this task is contained in (null for top-level tasks). + */ + function __construct(AbstractSAXParser $parser, $parentHandler, ProjectConfigurator $configurator, $container = null, $parentWrapper = null, $target = null) { + + parent::__construct($parser, $parentHandler); + + if (($container !== null) && !($container instanceof TaskContainer)) { + throw new Exception("Argument expected to be a TaskContainer, got something else"); + } + if (($parentWrapper !== null) && !($parentWrapper instanceof RuntimeConfigurable)) { + throw new Exception("Argument expected to be a RuntimeConfigurable, got something else."); + } + if (($target !== null) && !($target instanceof Target)) { + throw new Exception("Argument expected to be a Target, got something else"); + } + + $this->configurator = $configurator; + $this->container = $container; + $this->parentWrapper = $parentWrapper; + $this->target = $target; + } + + /** + * Executes initialization actions required to setup the data structures + * related to the tag. + *

    + * This includes: + *

      + *
    • creation of the task object
    • + *
    • calling the setters for attributes
    • + *
    • adding the task to the container object
    • + *
    • adding a reference to the task (if id attribute is given)
    • + *
    • executing the task if the container is the <project> + * element
    • + *
    + * + * @param string $tag The tag that comes in + * @param array $attrs Attributes the tag carries + * @throws ExpatParseException if attributes are incomplete or invalid + */ + function init($tag, $attrs) { + // shorthands + try { + $configurator = $this->configurator; + $project = $this->configurator->project; + + $this->task = $project->createTask($tag); + } catch (BuildException $be) { + // swallow here, will be thrown again in + // UnknownElement->maybeConfigure if the problem persists. + print("Swallowing exception: ".$be->getMessage() . "\n"); + } + + // the task is not known of bat, try to load it on thy fly + if ($this->task === null) { + $this->task = new UnknownElement($tag); + $this->task->setProject($project); + $this->task->setTaskType($tag); + $this->task->setTaskName($tag); + } + + // add file position information to the task (from parser) + // should be used in task exceptions to provide details + $this->task->setLocation($this->parser->getLocation()); + $configurator->configureId($task, $attrs); + + if ($this->container) { + $this->container->addTask($this->task); + } + + // Top level tasks don't have associated targets + // FIXME: if we do like Ant 1.6 and create an implicitTarget in the projectconfigurator object + // then we don't need to check for null here ... but there's a lot of stuff that will break if we + // do that at this point. + if ($this->target !== null) { + $this->task->setOwningTarget($this->target); + $this->task->init(); + $this->wrapper = $this->task->getRuntimeConfigurableWrapper(); + $this->wrapper->setAttributes($attrs); + /* + Commenting this out as per thread on Premature configurate of ReuntimeConfigurables + with Matthias Pigulla: http://phing.tigris.org/servlets/ReadMsg?list=dev&msgNo=251 + + if ($this->parentWrapper !== null) { // this may not make sense only within this if-block, but it + // seems to address current use cases adequately + $this->parentWrapper->addChild($this->wrapper); + } + */ + } else { + $this->task->init(); + $configurator->configure($this->task, $attrs, $project); + } + } + + /** + * Executes the task at once if it's directly beneath the tag. + */ + protected function finished() { + if ($this->task !== null && $this->target === null && $this->container === null) { + try { + $this->task->main(); + } catch (Exception $e) { + $this->task->log($e->getMessage(), PROJECT_MSG_ERR); + throw $e; + } + } + } + + /** + * Handles character data. + * + * @param string $data The CDATA that comes in + */ + function characters($data) { + if ($this->wrapper === null) { + $configurator = $this->configurator; + $project = $this->configurator->project; + try { // try + $configurator->addText($project, $this->task, $data); + } catch (BuildException $exc) { + throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation()); + } + } else { + $this->wrapper->addText($data); + } + } + + /** + * Checks for nested tags within the current one. Creates and calls + * handlers respectively. + * + * @param string $name The tag that comes in + * @param array $attrs Attributes the tag carries + */ + function startElement($name, $attrs) { + $project = $this->configurator->project; + if ($this->task instanceof TaskContainer) { + //print("TaskHandler::startElement() (TaskContainer) name = $name, attrs = " . implode(",",$attrs) . "\n"); + $th = new TaskHandler($this->parser, $this, $this->configurator, $this->task, $this->wrapper, $this->target); + $th->init($name, $attrs); + } else { + //print("TaskHandler::startElement() name = $name, attrs = " . implode(",",$attrs) . "\n"); + $tmp = new NestedElementHandler($this->parser, $this, $this->configurator, $this->task, $this->wrapper, $this->target); + $tmp->init($name, $attrs); + } + } +} diff --git a/gulliver/thirdparty/phing/system/io/BufferedReader.php b/gulliver/thirdparty/phing/system/io/BufferedReader.php new file mode 100644 index 000000000..d4ec0fd71 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/BufferedReader.php @@ -0,0 +1,170 @@ +. +*/ + +include_once 'phing/system/io/Reader.php'; + +/* + * Convenience class for reading files. + * + * @author Yannick Lecaillez + * @version $Revision: 1.6 $ $Date: 2005/12/27 19:12:13 $ + * @access public + * @see FilterReader + * @package phing.system.io +*/ +class BufferedReader extends Reader { + + private $bufferSize = 0; + private $buffer = null; + private $bufferPos = 0; + + /** + * The Reader we are buffering for. + */ + private $in; + + /** + * + * @param object $reader The reader (e.g. FileReader). + * @param integer $buffsize The size of the buffer we should use for reading files. + * A large buffer ensures that most files (all scripts?) are parsed in 1 buffer. + */ + function __construct(Reader $reader, $buffsize = 65536) { + $this->in = $reader; + $this->bufferSize = $buffsize; + } + + /** + * Reads and returns $_bufferSize chunk of data. + * @return mixed buffer or -1 if EOF. + */ + function read($len = null) { + // ignore $len param, not sure how to hanlde it, since + // this should only read bufferSize amount of data. + if ($len !== null) { + $this->currentPosition = ftell($this->fd); + } + + if ( ($data = $this->in->read($this->bufferSize)) !== -1 ) { + + // not all files end with a newline character, so we also need to check EOF + if (!$this->in->eof()) { + + $notValidPart = strrchr($data, "\n"); + $notValidPartSize = strlen($notValidPart); + + if ( $notValidPartSize > 1 ) { + // Block doesn't finish on a EOL + // Find the last EOL and forgot all following stuff + $dataSize = strlen($data); + $validSize = $dataSize - $notValidPartSize + 1; + + $data = substr($data, 0, $validSize); + + // Rewind to the begining of the forgotten stuff. + $this->in->skip(-$notValidPartSize+1); + } + + } // if !EOF + } + return $data; + } + + function skip($n) { + return $this->in->skip($n); + } + + function reset() { + return $this->in->reset(); + } + + function close() { + return $this->in->close(); + } + + function open() { + return $this->in->open(); + } + + /** + * Read a line from input stream. + */ + function readLine() { + $line = null; + while ( ($ch = $this->readChar()) !== -1 ) { + if ( $ch === "\n" ) { + break; + } + $line .= $ch; + } + + // Warning : Not considering an empty line as an EOF + if ( $line === null && $ch !== -1 ) + return ""; + + return $line; + } + + /** + * Reads a single char from the reader. + * @return string single char or -1 if EOF. + */ + function readChar() { + + if ( $this->buffer === null ) { + // Buffer is empty, fill it ... + $read = $this->in->read($this->bufferSize); + if ($read === -1) { + $ch = -1; + } else { + $this->buffer = $read; + return $this->readChar(); // recurse + } + } else { + // Get next buffered char ... + // handle case where buffer is read-in, but is empty. The next readChar() will return -1 EOF, + // so we just return empty string (char) at this point. (Probably could also return -1 ...?) + $ch = ($this->buffer !== "") ? $this->buffer{$this->bufferPos} : ''; + $this->bufferPos++; + if ( $this->bufferPos >= strlen($this->buffer) ) { + $this->buffer = null; + $this->bufferPos = 0; + } + } + + return $ch; + } + + /** + * Returns whether eof has been reached in stream. + * This is important, because filters may want to know if the end of the file (and not just buffer) + * has been reached. + * @return boolean + */ + function eof() { + return $this->in->eof(); + } + + function getResource() { + return $this->in->getResource(); + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/BufferedWriter.php b/gulliver/thirdparty/phing/system/io/BufferedWriter.php new file mode 100644 index 000000000..33198c000 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/BufferedWriter.php @@ -0,0 +1,72 @@ +. + */ + +include_once 'phing/system/io/Writer.php'; + +/** + * Convenience class for writing files. + * + * @author Hans Lellelid + * @version $Revision: 1.10 $ + * @package phing.system.io + */ +class BufferedWriter extends Writer { + + /** + * The size of the buffer in kb. + */ + private $bufferSize = 0; + + /** + * The Writer we are buffering output to. + */ + private $out; + + function __construct(Writer $writer, $buffsize = 8192) { + $this->out = $writer; + $this->bufferSize = $buffsize; + } + + function write($buf, $off = null, $len = null) { + return $this->out->write($buf, $off, $len); + } + + function newLine() { + $this->write(Phing::getProperty('line.separator')); + } + + function getResource() { + return $this->out->getResource(); + } + + function reset() { + return $this->out->reset(); + } + + function close() { + return $this->out->close(); + } + + function open() { + return $this->out->open(); + } + +} diff --git a/gulliver/thirdparty/phing/system/io/ConsoleReader.php b/gulliver/thirdparty/phing/system/io/ConsoleReader.php new file mode 100644 index 000000000..e3ab772e3 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/ConsoleReader.php @@ -0,0 +1,84 @@ +. + */ + +include_once 'phing/system/io/Reader.php'; + +/** + * Convenience class for reading console input. + * + * @author Hans Lellelid + * @author Matthew Hershberger + * @version $Revision: 1.4 $ + * @package phing.system.io + */ +class ConsoleReader extends Reader { + + function readLine() { + + $out = fgets(STDIN); // note: default maxlen is 1kb + $out = rtrim($out); + + return $out; + } + + /** + * + * @param int $len Num chars to read. + * @return string chars read or -1 if eof. + */ + function read($len = null) { + + $out = fread(STDIN, $len); + + + return $out; + // FIXME + // read by chars doesn't work (yet?) with PHP stdin. Maybe + // this is just a language feature, maybe there's a way to get + // ability to read chars w/o ? + + } + + function close() { + // STDIN is always open + } + + function open() { + // STDIN is always open + } + + /** + * Whether eof has been reached with stream. + * @return boolean + */ + function eof() { + return feof(STDIN); + } + + /** + * Returns path to file we are reading. + * @return string + */ + function getResource() { + return "console"; + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/FileReader.php b/gulliver/thirdparty/phing/system/io/FileReader.php new file mode 100644 index 000000000..65edf8d07 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/FileReader.php @@ -0,0 +1,179 @@ +. + */ + +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/Reader.php'; + +/** + * Convenience class for reading files. The constructor of this + * @package phing.system.io + */ + +class FileReader extends Reader { + + protected $file; + protected $fd; + + protected $currentPosition = 0; + protected $mark = 0; + + function __construct($file, $exclusive = false) { + + if ($file instanceof PhingFile) { + $this->file = $file; + } elseif (is_string($file)) { + $this->file = new PhingFile($file); + } else { + throw new Exception("Illegal argument type to " . __METHOD__); + } + } + + function skip($n) { + $this->open(); + + $start = $this->currentPosition; + + $ret = @fseek($this->fd, $n, SEEK_CUR); + if ( $ret === -1 ) + return -1; + + $this->currentPosition = ftell($this->fd); + + if ( $start > $this->currentPosition ) + $skipped = $start - $this->currentPosition; + else + $skipped = $this->currentPosition - $start; + + return $skipped; + } + + /** + * Read data from file. + * @param int $len Num chars to read. + * @return string chars read or -1 if eof. + */ + function read($len = null) { + $this->open(); + if (feof($this->fd)) { + return -1; + } + + // Compute length to read + // possible that filesize($this->file) will be larger than + // available bytes to read, but that's fine -- better to err on high end + $length = ($len === null) ? filesize($this->file->getAbsolutePath()) : $len; + + // Read data + $out = fread($this->fd, $length + 1); // adding 1 seems to ensure that next call to read() will return EOF (-1) + $this->currentPosition = ftell($this->fd); + + return $out; + } + + function mark($n = null) { + $this->mark = $this->currentPosition; + } + + function reset() { + // goes back to last mark, by default this would be 0 (i.e. rewind file). + fseek($this->fd, SEEK_SET, $this->mark); + $this->mark = 0; + } + + function close() { + if ($this->fd === null) { + return true; + } + + if (false === @fclose($this->fd)) { + // FAILED. + $msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg"; + throw new IOException($msg); + } else { + $this->fd = null; + return true; + } + } + + function open() { + global $php_errormsg; + + if ($this->fd === null) { + $this->fd = @fopen($this->file->getAbsolutePath(), "rb"); + } + + if ($this->fd === false) { + // fopen FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "Cannot fopen ".$this->file->getAbsolutePath().". $php_errormsg"; + throw new IOException($msg); + } + + if (false) { + // Locks don't seem to work on windows??? HELP!!!!!!!!! + // if (FALSE === @flock($fp, LOCK_EX)) { // FAILED. + $msg = "Cannot acquire flock on $file. $php_errormsg"; + throw new IOException($msg); + } + + return true; + } + + /** + * Whether eof has been reached with stream. + * @return boolean + */ + function eof() { + return feof($this->fd); + } + + /** + * Reads a entire file and stores the data in the variable + * passed by reference. + * + * @param string $file String. Path and/or name of file to read. + * @param object &$rBuffer Reference. Variable of where to put contents. + * + * @return TRUE on success. Err object on failure. + * @author Charlie Killian, charlie@tizac.com + */ + function readInto(&$rBuffer) { + + $this->open(); + + $fileSize = $this->file->length(); + if ($fileSize === false) { + $msg = "Cannot get filesize of " . $this->file->__toString() . " $php_errormsg"; + throw new IOException($msg); + } + $rBuffer = fread($this->fd, $fileSize); + $this->close(); + } + + /** + * Returns path to file we are reading. + * @return string + */ + function getResource() { + return $this->file->toString(); + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/FileSystem.php b/gulliver/thirdparty/phing/system/io/FileSystem.php new file mode 100644 index 000000000..71133779f --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/FileSystem.php @@ -0,0 +1,657 @@ +. + */ + +/** + * This is an abstract class for platform specific filesystem implementations + * you have to implement each method in the platform specific filesystem implementation + * classes Your local filesytem implementation must extend this class. + * You should also use this class as a template to write your local implementation + * Some native PHP filesystem specific methods are abstracted here as well. Anyway + * you _must_ always use this methods via a PhingFile object (that by nature uses the + * *FileSystem drivers to access the real filesystem via this class using natives. + * + * FIXME: + * - Error handling reduced to min fallthrough runtime excetions + * more precise errorhandling is done by the PhingFile class + * + * @author Charlie Killian + * @author Hans Lellelid + * @version $Revision: 1.11 $ + * @package phing.system.io + */ +abstract class FileSystem { + + /* properties for simple boolean attributes */ + const BA_EXISTS = 0x01; + const BA_REGULAR = 0x02; + const BA_DIRECTORY = 0x04; + const BA_HIDDEN = 0x08; + + /** Instance for getFileSystem() method. */ + private static $fs; + + /** + * Static method to return the FileSystem singelton representing + * this platform's local filesystem driver. + */ + public static function getFileSystem() { + if (self::$fs === null) { + switch(Phing::getProperty('host.fstype')) { + case 'UNIX': + include_once 'phing/system/io/UnixFileSystem.php'; + self::$fs = new UnixFileSystem(); + break; + case 'WIN32': + include_once 'phing/system/io/Win32FileSystem.php'; + self::$fs = new Win32FileSystem(); + break; + case 'WINNT': + include_once 'phing/system/io/WinNTFileSystem.php'; + self::$fs = new WinNTFileSystem(); + break; + default: + throw new Exception("Host uses unsupported filesystem, unable to proceed"); + } + } + return self::$fs; + } + + /* -- Normalization and construction -- */ + + /** + * Return the local filesystem's name-separator character. + */ + abstract function getSeparator(); + + /** + * Return the local filesystem's path-separator character. + */ + abstract function getPathSeparator(); + + /** + * Convert the given pathname string to normal form. If the string is + * already in normal form then it is simply returned. + */ + abstract function normalize($strPath); + + /** + * Compute the length of this pathname string's prefix. The pathname + * string must be in normal form. + */ + abstract function prefixLength($pathname); + + /** + * Resolve the child pathname string against the parent. + * Both strings must be in normal form, and the result + * will be a string in normal form. + */ + abstract function resolve($parent, $child); + + /** + * Resolve the given abstract pathname into absolute form. Invoked by the + * getAbsolutePath and getCanonicalPath methods in the PhingFile class. + */ + abstract function resolveFile(PhingFile $f); + + /** + * Return the parent pathname string to be used when the parent-directory + * argument in one of the two-argument PhingFile constructors is the empty + * pathname. + */ + abstract function getDefaultParent(); + + /** + * Post-process the given URI path string if necessary. This is used on + * win32, e.g., to transform "/c:/foo" into "c:/foo". The path string + * still has slash separators; code in the PhingFile class will translate them + * after this method returns. + */ + abstract function fromURIPath($path); + + /* -- Path operations -- */ + + /** + * Tell whether or not the given abstract pathname is absolute. + */ + abstract function isAbsolute(PhingFile $f); + + /** + * canonicalize filename by checking on disk + * @return mixed Canonical path or false if the file doesn't exist. + */ + function canonicalize($strPath) { + return @realpath($strPath); + } + + /* -- Attribute accessors -- */ + + /** + * Return the simple boolean attributes for the file or directory denoted + * by the given abstract pathname, or zero if it does not exist or some + * other I/O error occurs. + */ + function getBooleanAttributes($f) { + throw new Exception("SYSTEM ERROR method getBooleanAttributes() not implemented by fs driver"); + } + + /** + * Check whether the file or directory denoted by the given abstract + * pathname may be accessed by this process. If the second argument is + * false, then a check for read access is made; if the second + * argument is true, then a check for write (not read-write) + * access is made. Return false if access is denied or an I/O error + * occurs. + */ + function checkAccess(PhingFile $f, $write = false) { + // we clear stat cache, its expensive to look up from scratch, + // but we need to be sure + @clearstatcache(); + + + // Shouldn't this be $f->GetAbsolutePath() ? + // And why doesn't GetAbsolutePath() work? + + $strPath = (string) $f->getPath(); + + // FIXME + // if file object does denote a file that yet not existst + // path rights are checked + if (!@file_exists($strPath) && !is_dir($strPath)) { + $strPath = $f->getParent(); + if ($strPath === null || !is_dir($strPath)) { + $strPath = Phing::getProperty("user.dir"); + } + //$strPath = dirname($strPath); + } + + if (!$write) { + return (boolean) @is_readable($strPath); + } else { + return (boolean) @is_writable($strPath); + } + } + + /** + * Return the time at which the file or directory denoted by the given + * abstract pathname was last modified, or zero if it does not exist or + * some other I/O error occurs. + */ + function getLastModifiedTime(PhingFile $f) { + + if (!$f->exists()) { + return 0; + } + + @clearstatcache(); + $strPath = (string) $f->getPath(); + $mtime = @filemtime($strPath); + if (false === $mtime) { + // FAILED. Log and return err. + $msg = "FileSystem::Filemtime() FAILED. Cannot can not get modified time of $strPath. $php_errormsg"; + throw new Exception($msg); + } else { + return (int) $mtime; + } + } + + /** + * Return the length in bytes of the file denoted by the given abstract + * pathname, or zero if it does not exist, is a directory, or some other + * I/O error occurs. + */ + function getLength(PhingFile $f) { + $strPath = (string) $f->getAbsolutePath(); + $fs = filesize((string) $strPath); + if ($fs !== false) { + return $fs; + } else { + $msg = "FileSystem::Read() FAILED. Cannot get filesize of $strPath. $php_errormsg"; + throw new Exception($msg); + } + } + + /* -- File operations -- */ + + /** + * Create a new empty file with the given pathname. Return + * true if the file was created and false if a + * file or directory with the given pathname already exists. Throw an + * IOException if an I/O error occurs. + * + * @param string Path of the file to be created. + * + * @throws IOException + */ + function createNewFile($strPathname) { + if (@file_exists($strPathname)) + return false; + + // Create new file + $fp = @fopen($strPathname, "w"); + if ($fp === false) { + throw new IOException("The file \"$strPathname\" could not be created"); + } + @fclose($fp); + return true; + } + + /** + * Delete the file or directory denoted by the given abstract pathname, + * returning true if and only if the operation succeeds. + */ + function delete(PhingFile $f) { + if ($f->isDirectory()) { + return $this->rmdir($f->getPath()); + } else { + return $this->unlink($f->getPath()); + } + } + + /** + * Arrange for the file or directory denoted by the given abstract + * pathname to be deleted when Phing::shutdown is called, returning + * true if and only if the operation succeeds. + */ + function deleteOnExit($f) { + throw new Exception("deleteOnExit() not implemented by local fs driver"); + } + + /** + * List the elements of the directory denoted by the given abstract + * pathname. Return an array of strings naming the elements of the + * directory if successful; otherwise, return null. + */ + function listDir(PhingFile $f) { + $strPath = (string) $f->getAbsolutePath(); + $d = @dir($strPath); + if (!$d) { + return null; + } + $list = array(); + while($entry = $d->read()) { + if ($entry != "." && $entry != "..") { + array_push($list, $entry); + } + } + $d->close(); + unset($d); + return $list; + } + + /** + * Create a new directory denoted by the given abstract pathname, + * returning true if and only if the operation succeeds. + */ + function createDirectory(&$f) { + return @mkdir($f->getAbsolutePath(),0755); + } + + /** + * Rename the file or directory denoted by the first abstract pathname to + * the second abstract pathname, returning true if and only if + * the operation succeeds. + * + * @param PhingFile $f1 abstract source file + * @param PhingFile $f2 abstract destination file + * @return void + * @throws Exception if rename cannot be performed + */ + function rename(PhingFile $f1, PhingFile $f2) { + // get the canonical paths of the file to rename + $src = $f1->getAbsolutePath(); + $dest = $f2->getAbsolutePath(); + if (false === @rename($src, $dest)) { + $msg = "Rename FAILED. Cannot rename $src to $dest. $php_errormsg"; + throw new Exception($msg); + } + } + + /** + * Set the last-modified time of the file or directory denoted by the + * given abstract pathname returning true if and only if the + * operation succeeds. + * @return void + * @throws Exception + */ + function setLastModifiedTime(PhingFile $f, $time) { + $path = $f->getPath(); + $success = @touch($path, $time); + if (!$success) { + throw new Exception("Could not create directory due to: $php_errormsg"); + } + } + + /** + * Mark the file or directory denoted by the given abstract pathname as + * read-only, returning true if and only if the operation + * succeeds. + */ + function setReadOnly($f) { + throw new Exception("setReadonle() not implemented by local fs driver"); + } + + /* -- Filesystem interface -- */ + + /** + * List the available filesystem roots, return array of PhingFile objects + */ + function listRoots() { + throw new Exception("SYSTEM ERROR [listRoots() not implemented by local fs driver]"); + } + + /* -- Basic infrastructure -- */ + + /** + * Compare two abstract pathnames lexicographically. + */ + function compare($f1, $f2) { + throw new Exception("SYSTEM ERROR [compare() not implemented by local fs driver]"); + } + + /** + * Copy a file. + * + * @param PhingFile $src Source path and name file to copy. + * @param PhingFile $dest Destination path and name of new file. + * + * @return void + * @throws Exception if file cannot be copied. + */ + function copy(PhingFile $src, PhingFile $dest) { + global $php_errormsg; + $srcPath = $src->getAbsolutePath(); + $destPath = $dest->getAbsolutePath(); + + if (false === @copy($srcPath, $destPath)) { // Copy FAILED. Log and return err. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::copy() FAILED. Cannot copy $srcPath to $destPath. $php_errormsg"; + throw new Exception($msg); + } + + try { + $dest->setMode($src->getMode()); + } catch(Exception $exc) { + // [MA] does chmod returns an error on systems that do not support it ? + // eat it up for now. + } + } + + /** + * Change the permissions on a file or directory. + * + * @param pathname String. Path and name of file or directory. + * @param mode Int. The mode (permissions) of the file or + * directory. If using octal add leading 0. eg. 0777. + * Mode is affected by the umask system setting. + * + * @return void + * @throws Exception if operation failed. + */ + function chmod($pathname, $mode) { + $str_mode = decoct($mode); // Show octal in messages. + if (false === @chmod($pathname, $mode)) {// FAILED. + $msg = "FileSystem::chmod() FAILED. Cannot chmod $pathname. Mode $str_mode. $php_errormsg"; + throw new Exception($msg); + } + } + + /** + * Locks a file and throws an Exception if this is not possible. + * @return void + * @throws Exception + */ + function lock(PhingFile $f) { + $filename = $f->getPath(); + $fp = @fopen($filename, "w"); + $result = @flock($fp, LOCK_EX); + @fclose($fp); + if (!$result) { + throw new Exception("Could not lock file '$filename'"); + } + } + + /** + * Unlocks a file and throws an IO Error if this is not possible. + * + * @throws Exception + * @return void + */ + function unlock(PhingFile $f) { + $filename = $f->getPath(); + $fp = @fopen($filename, "w"); + $result = @flock($fp, LOCK_UN); + fclose($fp); + if (!$result) { + throw new Exception("Could not unlock file '$filename'"); + } + } + + /** + * Delete a file. + * + * @param file String. Path and/or name of file to delete. + * + * @return void + * @throws Exception - if an error is encountered. + */ + function unlink($file) { + global $php_errormsg; + if (false === @unlink($file)) { + $msg = "FileSystem::unlink() FAILED. Cannot unlink '$file'. $php_errormsg"; + throw new Exception($msg); + } + } + + /** + * Symbolically link a file to another name. + * + * Currently symlink is not implemented on Windows. Don't use if the application is to be portable. + * + * @param string $target Path and/or name of file to link. + * @param string $link Path and/or name of link to be created. + * @return void + */ + function symlink($target, $link) { + + // If Windows OS then symlink() will report it is not supported in + // the build. Use this error instead of checking for Windows as the OS. + + if (false === @symlink($target, $link)) { + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::Symlink() FAILED. Cannot symlink '$target' to '$link'. $php_errormsg"; + throw new Exception($msg); + } + + } + + /** + * Set the modification and access time on a file to the present time. + * + * @param string $file Path and/or name of file to touch. + * @param int $time + * @return void + */ + function touch($file, $time = null) { + global $php_errormsg; + + if (null === $time) { + $error = @touch($file); + } else { + $error = @touch($file, $time); + } + + if (false === $error) { // FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::touch() FAILED. Cannot touch '$file'. $php_errormsg"; + throw new Exception($msg); + } + } + + /** + * Delete an empty directory OR a directory and all of its contents. + * + * @param dir String. Path and/or name of directory to delete. + * @param children Boolean. False: don't delete directory contents. + * True: delete directory contents. + * + * @return void + */ + function rmdir($dir, $children = false) { + global $php_errormsg; + + // If children=FALSE only delete dir if empty. + if (false === $children) { + + if (false === @rmdir($dir)) { // FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg"; + throw new Exception($msg); + } + + } else { // delete contents and dir. + + $handle = @opendir($dir); + + if (false === $handle) { // Error. + + $msg = "FileSystem::rmdir() FAILED. Cannot opendir() $dir. $php_errormsg"; + throw new Exception($msg); + + } else { // Read from handle. + + // Don't error on readdir(). + while (false !== ($entry = @readdir($handle))) { + + if ($entry != '.' && $entry != '..') { + + // Only add / if it isn't already the last char. + // This ONLY serves the purpose of making the Logger + // output look nice:) + + if (strpos(strrev($dir), DIRECTORY_SEPARATOR) === 0) {// there is a / + $next_entry = $dir . $entry; + } else { // no / + $next_entry = $dir . DIRECTORY_SEPARATOR . $entry; + } + + // NOTE: As of php 4.1.1 is_dir doesn't return FALSE it + // returns 0. So use == not ===. + + // Don't error on is_dir() + if (false == @is_dir($next_entry)) { // Is file. + + try { + self::unlink($next_entry); // Delete. + } catch (Exception $e) { + $msg = "FileSystem::Rmdir() FAILED. Cannot FileSystem::Unlink() $next_entry. ". $e->getMessage(); + throw new Exception($msg); + } + + } else { // Is directory. + + try { + self::rmdir($next_entry, true); // Delete + } catch (Exception $e) { + $msg = "FileSystem::rmdir() FAILED. Cannot FileSystem::rmdir() $next_entry. ". $e->getMessage(); + throw new Exception($msg); + } + + } // end is_dir else + } // end .. if + } // end while + } // end handle if + + // Don't error on closedir() + @closedir($handle); + + if (false === @rmdir($dir)) { // FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg"; + throw new Exception($msg); + } + + } + + } + + /** + * Set the umask for file and directory creation. + * + * @param mode Int. Permissions ususally in ocatal. Use leading 0 for + * octal. Number between 0 and 0777. + * + * @return void + * @throws Exception if there is an error performing operation. + */ + function umask($mode) { + global $php_errormsg; + + // CONSIDERME: + // Throw a warning if mode is 0. PHP converts illegal octal numbers to + // 0 so 0 might not be what the user intended. + + $str_mode = decoct($mode); // Show octal in messages. + + if (false === @umask($mode)) { // FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::Umask() FAILED. Value $mode. $php_errormsg"; + throw new Exception($msg); + } + } + + /** + * Compare the modified time of two files. + * + * @param file1 String. Path and name of file1. + * @param file2 String. Path and name of file2. + * + * @return Int. 1 if file1 is newer. + * -1 if file2 is newer. + * 0 if files have the same time. + * Err object on failure. + * + * @throws Exception - if cannot get modified time of either file. + */ + function compareMTimes($file1, $file2) { + + $mtime1 = filemtime($file1); + $mtime2 = filemtime($file2); + + if ($mtime1 === false) { // FAILED. Log and return err. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file1."; + throw new Exception($msg); + } elseif ($mtime2 === false) { // FAILED. Log and return err. + // Add error from php to end of log message. $php_errormsg. + $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file2."; + throw new Exception($msg); + } else { // Worked. Log and return compare. + // Compare mtimes. + if ($mtime1 == $mtime2) { + return 0; + } else { + return ($mtime1 < $mtime2) ? -1 : 1; + } // end compare + } + } + +} diff --git a/gulliver/thirdparty/phing/system/io/FileWriter.php b/gulliver/thirdparty/phing/system/io/FileWriter.php new file mode 100644 index 000000000..3d1fe3239 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/FileWriter.php @@ -0,0 +1,139 @@ +. + */ + +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/Writer.php'; + +/** + * Convenience class for reading files. The constructor of this + * + * @package phing.system.io + */ +class FileWriter extends Writer { + + protected $file; + protected $fd; + + /** Whether to append contents to file. */ + protected $append; + + /** Whether we should attempt to lock the file (currently disabled). */ + protected $exclusive; + + /** + * Construct a new FileWriter. + * @param mixed $file PhingFile or string pathname. + * @param boolean $append Append to existing file? + * @param boolean $exclusive Lock file? (currently disabled due to windows incompatibility) + */ + function __construct($file, $append = false, $exclusive = false) { + if ($file instanceof PhingFile) { + $this->file = $file; + } elseif (is_string($file)) { + $this->file = new PhingFile($file); + } else { + throw new Exception("Invalid argument type for \$file."); + } + $this->append = $append; + $this->exclusive = $exclusive; + } + + function close() { + if ($this->fd === null) { + return true; + } + + if (false === @fclose($this->fd)) { + // FAILED. + $msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg"; + throw new IOException($msg); + } else { + $this->fd = null; + return true; + } + } + + function open() { + if ($this->fd === null) { + if ($this->append) { $flags = "ab"; } else { $flags = "wb"; } + $this->fd = @fopen($this->file->getPath(), $flags); + } + + if ($this->fd === false) { + // fopen FAILED. + // Add error from php to end of log message. $php_errormsg. + $msg = "Cannot fopen ".$this->file->getPath()." $php_errormsg"; + throw new IOException($msg); + } + + if (false) { + // Locks don't seem to work on windows??? HELP!!!!!!!!! + // if (FALSE === @flock($fp, LOCK_EX)) { // FAILED. + $msg = "Cannot acquire flock on $file. $php_errormsg"; + throw new IOException($msg); + } + + return true; + } + + function reset() { + // FIXME -- what exactly should this do, if anything? + // reset to beginning of file (i.e. re-open)? + } + + function writeBuffer($buffer) { + + if (!$this->file->canWrite()) { + throw new IOException("No permission to write to file: " . $this->file->__toString()); + } + + $this->open(); + $result = @fwrite($this->fd, $buffer); + $this->close(); + + if ($result === false) { + throw new IOException("Error writing file: ". $this->file->toString()); + } else { + return true; + } + } + + function write($buf, $off = null, $len = null) { + if ( $off === null && $len === null ) + $to_write = $buf; + else + $to_write = substr($buf, $off, $len); + + $this->open(); + $result = @fwrite($this->fd, $to_write); + + if ( $result === false ) { + throw new IOException("Error writing file."); + } else { + return true; + } + } + + function getResource() { + return $this->file->toString(); + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/FilterReader.php b/gulliver/thirdparty/phing/system/io/FilterReader.php new file mode 100644 index 000000000..197f829a1 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/FilterReader.php @@ -0,0 +1,72 @@ +. + */ + +include_once 'phing/system/io/Reader.php'; + +/** + * Convenience class for reading files. The constructor of this + * @package phing.system.io + * + * TODO: All filters should be ProjectComponents, too! + */ +class FilterReader extends Reader { + + protected $in; + + function __construct(Reader $in = null) { + $this->in = $in; + //parent::__construct(new FileReader($file, $exclusive)); + } + + public function setReader(Reader $in) { + $this->in = $in; + } + + public function skip($n) { + return $this->in->skip($n); + } + + /** + * Read data from source. + * FIXME: Clean up this function signature, as it a) params aren't being used + * and b) it doesn't make much sense. + */ + public function read($len = null) { + return $this->in->read($len); + } + + public function reset() { + return $this->in->reset(); + } + + public function close() { + return $this->in->close(); + } + + public function open() { + return $this->in->open(); + } + + function getResource() { + return $this->in->getResource(); + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/IOException.php b/gulliver/thirdparty/phing/system/io/IOException.php new file mode 100644 index 000000000..71c69ae24 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/IOException.php @@ -0,0 +1,28 @@ +. + */ + +/** + * Extends Exception to take advantage of methods therein. + * + * @package phing.system.io + */ +class IOException extends Exception {} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/system/io/PhingFile.php b/gulliver/thirdparty/phing/system/io/PhingFile.php new file mode 100644 index 000000000..4f8d36722 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/PhingFile.php @@ -0,0 +1,866 @@ +. + */ + +include_once 'phing/system/io/FileSystem.php'; +include_once 'phing/system/lang/NullPointerException.php'; + +/** + * An abstract representation of file and directory pathnames. + * + * @version $Revision: 1.1 $ + * @package phing.system.io + */ +class PhingFile { + + /** separator string, static, obtained from FileSystem */ + public static $separator; + + /** path separator string, static, obtained from FileSystem (; or :)*/ + public static $pathSeparator; + + /** + * This abstract pathname's normalized pathname string. A normalized + * pathname string uses the default name-separator character and does not + * contain any duplicate or redundant separators. + */ + private $path = null; + + /** The length of this abstract pathname's prefix, or zero if it has no prefix. */ + private $prefixLength = 0; + + /** constructor */ + function __construct($arg1 = null, $arg2 = null) { + + if (self::$separator === null || self::$pathSeparator === null) { + $fs = FileSystem::getFileSystem(); + self::$separator = $fs->getSeparator(); + self::$pathSeparator = $fs->getPathSeparator(); + } + + /* simulate signature identified constructors */ + if ($arg1 instanceof PhingFile && is_string($arg2)) { + $this->_constructFileParentStringChild($arg1, $arg2); + } elseif (is_string($arg1) && ($arg2 === null)) { + $this->_constructPathname($arg1); + } elseif(is_string($arg1) && is_string($arg2)) { + $this->_constructStringParentStringChild($arg1, $arg2); + } else { + if ($arg1 === null) { + throw new NullPointerException("Argument1 to function must not be null"); + } + $this->path = (string) $arg1; + $this->prefixLength = (int) $arg2; + } + } + + /** Returns the length of this abstract pathname's prefix. */ + function getPrefixLength() { + return (int) $this->prefixLength; + } + + /* -- constructors not called by signature match, so we need some helpers --*/ + + function _constructPathname($pathname) { + // obtain ref to the filesystem layer + $fs = FileSystem::getFileSystem(); + + if ($pathname === null) { + throw new NullPointerException("Argument to function must not be null"); + } + + $this->path = (string) $fs->normalize($pathname); + $this->prefixLength = (int) $fs->prefixLength($this->path); + } + + function _constructStringParentStringChild($parent, $child = null) { + // obtain ref to the filesystem layer + $fs = FileSystem::getFileSystem(); + + if ($child === null) { + throw new NullPointerException("Argument to function must not be null"); + } + if ($parent !== null) { + if ($parent === "") { + $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child)); + } else { + $this->path = $fs->resolve($fs->normalize($parent), $fs->normalize($child)); + } + } else { + $this->path = (string) $fs->normalize($child); + } + $this->prefixLength = (int) $fs->prefixLength($this->path); + } + + function _constructFileParentStringChild($parent, $child = null) { + // obtain ref to the filesystem layer + $fs = FileSystem::getFileSystem(); + + if ($child === null) { + throw new NullPointerException("Argument to function must not be null"); + } + + if ($parent !== null) { + if ($parent->path === "") { + $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child)); + } else { + $this->path = $fs->resolve($parent->path, $fs->normalize($child)); + } + } else { + $this->path = $fs->normalize($child); + } + $this->prefixLength = $fs->prefixLength($this->path); + } + + /* -- Path-component accessors -- */ + + /** + * Returns the name of the file or directory denoted by this abstract + * pathname. This is just the last name in the pathname's name + * sequence. If the pathname's name sequence is empty, then the empty + * string is returned. + * + * @return The name of the file or directory denoted by this abstract + * pathname, or the empty string if this pathname's name sequence + * is empty + */ + function getName() { + // that's a lastIndexOf + $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res); + if ($index < $this->prefixLength) { + return substr($this->path, $this->prefixLength); + } + return substr($this->path, $index + 1); + } + + /** + * Returns the pathname string of this abstract pathname's parent, or + * null if this pathname does not name a parent directory. + * + * The parent of an abstract pathname consists of the pathname's prefix, + * if any, and each name in the pathname's name sequence except for the last. + * If the name sequence is empty then the pathname does not name a parent + * directory. + * + * @return The pathname string of the parent directory named by this + * abstract pathname, or null if this pathname does not name a parent + */ + function getParent() { + // that's a lastIndexOf + $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res); + if ($index < $this->prefixLength) { + if (($this->prefixLength > 0) && (strlen($this->path > $this->prefixLength))) { + return substr($this->path, 0, $this->prefixLength); + } + return null; + } + return substr($this->path, 0, $index); + } + + /** + * Returns the abstract pathname of this abstract pathname's parent, + * or null if this pathname does not name a parent directory. + * + * The parent of an abstract pathname consists of the pathname's prefix, + * if any, and each name in the pathname's name sequence except for the + * last. If the name sequence is empty then the pathname does not name + * a parent directory. + * + * @return The abstract pathname of the parent directory named by this + * abstract pathname, or null if this pathname + * does not name a parent + */ + function getParentFile() { + $p = $this->getParent(); + if ($p === null) { + return null; + } + return new PhingFile((string) $p, (int) $this->prefixLength); + } + + /** + * Converts this abstract pathname into a pathname string. The resulting + * string uses the default name-separator character to separate the names + * in the name sequence. + * + * @return The string form of this abstract pathname + */ + function getPath() { + return (string) $this->path; + } + + /** + * Tests whether this abstract pathname is absolute. The definition of + * absolute pathname is system dependent. On UNIX systems, a pathname is + * absolute if its prefix is "/". On Win32 systems, a pathname is absolute + * if its prefix is a drive specifier followed by "\\", or if its prefix + * is "\\". + * + * @return true if this abstract pathname is absolute, false otherwise + */ + function isAbsolute() { + return ($this->prefixLength !== 0); + } + + + /** + * Returns the absolute pathname string of this abstract pathname. + * + * If this abstract pathname is already absolute, then the pathname + * string is simply returned as if by the getPath method. + * If this abstract pathname is the empty abstract pathname then + * the pathname string of the current user directory, which is named by the + * system property user.dir, is returned. Otherwise this + * pathname is resolved in a system-dependent way. On UNIX systems, a + * relative pathname is made absolute by resolving it against the current + * user directory. On Win32 systems, a relative pathname is made absolute + * by resolving it against the current directory of the drive named by the + * pathname, if any; if not, it is resolved against the current user + * directory. + * + * @return The absolute pathname string denoting the same file or + * directory as this abstract pathname + * @see #isAbsolute() + */ + function getAbsolutePath() { + $fs = FileSystem::getFileSystem(); + return $fs->resolveFile($this); + } + + /** + * Returns the absolute form of this abstract pathname. Equivalent to + * getAbsolutePath. + * + * @return The absolute abstract pathname denoting the same file or + * directory as this abstract pathname + */ + function getAbsoluteFile() { + return new PhingFile((string) $this->getAbsolutePath()); + } + + + /** + * Returns the canonical pathname string of this abstract pathname. + * + * A canonical pathname is both absolute and unique. The precise + * definition of canonical form is system-dependent. This method first + * converts this pathname to absolute form if necessary, as if by invoking the + * getAbsolutePath() method, and then maps it to its unique form in a + * system-dependent way. This typically involves removing redundant names + * such as "." and .. from the pathname, resolving symbolic links + * (on UNIX platforms), and converting drive letters to a standard case + * (on Win32 platforms). + * + * Every pathname that denotes an existing file or directory has a + * unique canonical form. Every pathname that denotes a nonexistent file + * or directory also has a unique canonical form. The canonical form of + * the pathname of a nonexistent file or directory may be different from + * the canonical form of the same pathname after the file or directory is + * created. Similarly, the canonical form of the pathname of an existing + * file or directory may be different from the canonical form of the same + * pathname after the file or directory is deleted. + * + * @return The canonical pathname string denoting the same file or + * directory as this abstract pathname + */ + function getCanonicalPath() { + $fs = FileSystem::getFileSystem(); + return $fs->canonicalize($this->path); + } + + + /** + * Returns the canonical form of this abstract pathname. Equivalent to + * getCanonicalPath(. + * + * @return PhingFile The canonical pathname string denoting the same file or + * directory as this abstract pathname + */ + function getCanonicalFile() { + return new PhingFile($this->getCanonicalPath()); + } + + /** + * Converts this abstract pathname into a file: URL. The + * exact form of the URL is system-dependent. If it can be determined that + * the file denoted by this abstract pathname is a directory, then the + * resulting URL will end with a slash. + * + * Usage note: This method does not automatically escape + * characters that are illegal in URLs. It is recommended that new code + * convert an abstract pathname into a URL by first converting it into a + * URI, via the toURI() method, and then converting the URI + * into a URL via the URI::toURL() + * + * @return A URL object representing the equivalent file URL + * + * + */ + function toURL() { + /* + // URL class not implemented yet + return new URL("file", "", $this->_slashify($this->getAbsolutePath(), $this->isDirectory())); + */ + } + + /** + * Constructs a file: URI that represents this abstract pathname. + * Not implemented yet + */ + function toURI() { + /* + $f = $this->getAbsoluteFile(); + $sp = (string) $this->slashify($f->getPath(), $f->isDirectory()); + if (StringHelper::startsWith('//', $sp)) + $sp = '//' + sp; + return new URI('file', null, $sp, null); + */ + } + + function _slashify($path, $isDirectory) { + $p = (string) $path; + + if (self::$separator !== '/') { + $p = str_replace(self::$separator, '/', $p); + } + + if (!StringHelper::startsWith('/', $p)) { + $p = '/'.$p; + } + + if (!StringHelper::endsWith('/', $p) && $isDirectory) { + $p = $p.'/'; + } + + return $p; + } + + /* -- Attribute accessors -- */ + + /** + * Tests whether the application can read the file denoted by this + * abstract pathname. + * + * @return true if and only if the file specified by this + * abstract pathname exists and can be read by the + * application; false otherwise + */ + function canRead() { + $fs = FileSystem::getFileSystem(); + + if ($fs->checkAccess($this)) { + return (boolean) @is_readable($this->getAbsolutePath()); + } + return false; + } + + /** + * Tests whether the application can modify to the file denoted by this + * abstract pathname. + * + * @return true if and only if the file system actually + * contains a file denoted by this abstract pathname and + * the application is allowed to write to the file; + * false otherwise. + * + */ + function canWrite() { + $fs = FileSystem::getFileSystem(); + return $fs->checkAccess($this, true); + } + + /** + * Tests whether the file denoted by this abstract pathname exists. + * + * @return true if and only if the file denoted by this + * abstract pathname exists; false otherwise + * + */ + function exists() { + if ($this->isFile()) { + return @file_exists($this->path); + } else { + return @is_dir($this->path); + } + } + + /** + * Tests whether the file denoted by this abstract pathname is a + * directory. + * + * @return true if and only if the file denoted by this + * abstract pathname exists and is a directory; + * false otherwise + * + */ + function isDirectory() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this) !== true) { + throw new IOException("No read access to ".$this->path); + } + return @is_dir($this->path); + } + + /** + * Tests whether the file denoted by this abstract pathname is a normal + * file. A file is normal if it is not a directory and, in + * addition, satisfies other system-dependent criteria. Any non-directory + * file created by a Java application is guaranteed to be a normal file. + * + * @return true if and only if the file denoted by this + * abstract pathname exists and is a normal file; + * false otherwise + */ + function isFile() { + //$fs = FileSystem::getFileSystem(); + return @is_file($this->path); + } + + /** + * Tests whether the file named by this abstract pathname is a hidden + * file. The exact definition of hidden is system-dependent. On + * UNIX systems, a file is considered to be hidden if its name begins with + * a period character ('.'). On Win32 systems, a file is considered to be + * hidden if it has been marked as such in the filesystem. Currently there + * seems to be no way to dermine isHidden on Win file systems via PHP + * + * @return true if and only if the file denoted by this + * abstract pathname is hidden according to the conventions of the + * underlying platform + */ + function isHidden() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this) !== true) { + throw new IOException("No read access to ".$this->path); + } + return (($fs->getBooleanAttributes($this) & $fs->BA_HIDDEN) !== 0); + } + + /** + * Returns the time that the file denoted by this abstract pathname was + * last modified. + * + * @return A integer value representing the time the file was + * last modified, measured in milliseconds since the epoch + * (00:00:00 GMT, January 1, 1970), or 0 if the + * file does not exist or if an I/O error occurs + */ + function lastModified() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this) !== true) { + throw new IOException("No read access to " . $this->path); + } + return $fs->getLastModifiedTime($this); + } + + /** + * Returns the length of the file denoted by this abstract pathname. + * The return value is unspecified if this pathname denotes a directory. + * + * @return The length, in bytes, of the file denoted by this abstract + * pathname, or 0 if the file does not exist + */ + function length() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this) !== true) { + throw new IOException("No read access to ".$this->path."\n"); + } + return $fs->getLength($this); + } + + /** + * Convenience method for returning the contents of this file as a string. + * This method uses file_get_contents() to read file in an optimized way. + * @return string + * @throws Exception - if file cannot be read + */ + function contents() { + if (!$this->canRead() || !$this->isFile()) { + throw new IOException("Cannot read file contents!"); + } + return file_get_contents($this->getAbsolutePath()); + } + + /* -- File operations -- */ + + /** + * Atomically creates a new, empty file named by this abstract pathname if + * and only if a file with this name does not yet exist. The check for the + * existence of the file and the creation of the file if it does not exist + * are a single operation that is atomic with respect to all other + * filesystem activities that might affect the file. + * + * @return true if the named file does not exist and was + * successfully created; false if the named file + * already exists + * @throws IOException if file can't be created + */ + function createNewFile($parents=true, $mode=0777) { + $file = FileSystem::getFileSystem()->createNewFile($this->path); + return $file; + } + + /** + * Deletes the file or directory denoted by this abstract pathname. If + * this pathname denotes a directory, then the directory must be empty in + * order to be deleted. + * + * @return true if and only if the file or directory is + * successfully deleted; false otherwise + */ + function delete() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this, true) !== true) { + throw new IOException("No read access to " . $this->path."\n"); + } + return $fs->delete($this); + } + + /** + * Requests that the file or directory denoted by this abstract pathname + * be deleted when php terminates. Deletion will be attempted only for + * normal termination of php and if and if only Phing::shutdown() is + * called. + * + * Once deletion has been requested, it is not possible to cancel the + * request. This method should therefore be used with care. + * + */ + function deleteOnExit() { + $fs = FileSystem::getFileSystem(); + $fs->deleteOnExit($this); + } + + /** + * Returns an array of strings naming the files and directories in the + * directory denoted by this abstract pathname. + * + * If this abstract pathname does not denote a directory, then this + * method returns null Otherwise an array of strings is + * returned, one for each file or directory in the directory. Names + * denoting the directory itself and the directory's parent directory are + * not included in the result. Each string is a file name rather than a + * complete path. + * + * There is no guarantee that the name strings in the resulting array + * will appear in any specific order; they are not, in particular, + * guaranteed to appear in alphabetical order. + * + * @return An array of strings naming the files and directories in the + * directory denoted by this abstract pathname. The array will be + * empty if the directory is empty. Returns null if + * this abstract pathname does not denote a directory, or if an + * I/O error occurs. + * + */ + function listDir($filter = null) { + $fs = FileSystem::getFileSystem(); + return $fs->lister($this, $filter); + } + + function listFiles($filter = null) { + $ss = $this->listDir($filter); + if ($ss === null) { + return null; + } + $n = count($ss); + $fs = array(); + for ($i = 0; $i < $n; $i++) { + $fs[$i] = new PhingFile((string)$this->path, (string)$ss[$i]); + } + return $fs; + } + + /** + * Creates the directory named by this abstract pathname, including any + * necessary but nonexistent parent directories. Note that if this + * operation fails it may have succeeded in creating some of the necessary + * parent directories. + * + * @return true if and only if the directory was created, + * along with all necessary parent directories; false + * otherwise + * @throws IOException + */ + function mkdirs() { + if ($this->exists()) { + return false; + } + try { + if ($this->mkdir()) { + return true; + } + } catch (IOException $ioe) { + // IOException from mkdir() means that directory propbably didn't exist. + } + $parentFile = $this->getParentFile(); + return (($parentFile !== null) && ($parentFile->mkdirs() && $this->mkdir())); + } + + /** + * Creates the directory named by this abstract pathname. + * + * @return true if and only if the directory was created; false otherwise + * @throws IOException + */ + function mkdir() { + $fs = FileSystem::getFileSystem(); + + if ($fs->checkAccess(new PhingFile($this->path), true) !== true) { + throw new IOException("No write access to " . $this->getPath()); + } + return $fs->createDirectory($this); + } + + /** + * Renames the file denoted by this abstract pathname. + * + * @param destFile The new abstract pathname for the named file + * @return true if and only if the renaming succeeded; false otherwise + */ + function renameTo(PhingFile $destFile) { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this) !== true) { + throw new IOException("No write access to ".$this->getPath()); + } + return $fs->rename($this, $destFile); + } + + /** + * Simple-copies file denoted by this abstract pathname into another + * PhingFile + * + * @param PhingFile $destFile The new abstract pathname for the named file + * @return true if and only if the renaming succeeded; false otherwise + */ + function copyTo(PhingFile $destFile) { + $fs = FileSystem::getFileSystem(); + + if ($fs->checkAccess($this) !== true) { + throw new IOException("No read access to ".$this->getPath()."\n"); + } + + if ($fs->checkAccess($destFile, true) !== true) { + throw new IOException("File::copyTo() No write access to ".$destFile->getPath()); + } + return $fs->copy($this, $destFile); + } + + /** + * Sets the last-modified time of the file or directory named by this + * abstract pathname. + * + * All platforms support file-modification times to the nearest second, + * but some provide more precision. The argument will be truncated to fit + * the supported precision. If the operation succeeds and no intervening + * operations on the file take place, then the next invocation of the + * lastModified method will return the (possibly truncated) time argument + * that was passed to this method. + * + * @param time The new last-modified time, measured in milliseconds since + * the epoch (00:00:00 GMT, January 1, 1970) + * @return true if and only if the operation succeeded; false otherwise + */ + function setLastModified($time) { + $time = (int) $time; + if ($time < 0) { + throw new Exception("IllegalArgumentException, Negative $time\n"); + } + + // FIXME check if accessible + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this, true) !== true) { + throw new IOException("File::setLastModified(). No write access to file\n"); + } + return $fs->setLastModifiedTime($this, $time); + } + + /** + * Marks the file or directory named by this abstract pathname so that + * only read operations are allowed. After invoking this method the file + * or directory is guaranteed not to change until it is either deleted or + * marked to allow write access. Whether or not a read-only file or + * directory may be deleted depends upon the underlying system. + * + * @return true if and only if the operation succeeded; false otherwise + */ + function setReadOnly() { + $fs = FileSystem::getFileSystem(); + if ($fs->checkAccess($this, true) !== true) { + // Error, no write access + throw new IOException("No write access to " . $this->getPath()); + } + return $fs->setReadOnly($this); + } + + /** + * Sets the mode of the file + * @param int $mode Ocatal mode. + */ + function setMode($mode) { + $fs = FileSystem::getFileSystem(); + return $fs->chmod($this->getPath(), $mode); + } + + /** + * Retrieve the mode of this file. + * @return int + */ + function getMode() { + return @fileperms($this->getPath()); + } + + /* -- Filesystem interface -- */ + + /** + * List the available filesystem roots. + * + * A particular platform may support zero or more hierarchically-organized + * file systems. Each file system has a root directory from which all + * other files in that file system can be reached. + * Windows platforms, for example, have a root directory for each active + * drive; UNIX platforms have a single root directory, namely "/". + * The set of available filesystem roots is affected by various system-level + * operations such the insertion or ejection of removable media and the + * disconnecting or unmounting of physical or virtual disk drives. + * + * This method returns an array of PhingFile objects that + * denote the root directories of the available filesystem roots. It is + * guaranteed that the canonical pathname of any file physically present on + * the local machine will begin with one of the roots returned by this + * method. + * + * The canonical pathname of a file that resides on some other machine + * and is accessed via a remote-filesystem protocol such as SMB or NFS may + * or may not begin with one of the roots returned by this method. If the + * pathname of a remote file is syntactically indistinguishable from the + * pathname of a local file then it will begin with one of the roots + * returned by this method. Thus, for example, PhingFile objects + * denoting the root directories of the mapped network drives of a Windows + * platform will be returned by this method, while PhingFile + * objects containing UNC pathnames will not be returned by this method. + * + * @return An array of PhingFile objects denoting the available + * filesystem roots, or null if the set of roots + * could not be determined. The array will be empty if there are + * no filesystem roots. + */ + function listRoots() { + $fs = FileSystem::getFileSystem(); + return (array) $fs->listRoots(); + } + + /* -- Tempfile management -- */ + + /** + * Returns the path to the temp directory. + */ + function getTempDir() { + return Phing::getProperty('php.tmpdir'); + } + + /** + * Static method that creates a unique filename whose name begins with + * $prefix and ends with $suffix in the directory $directory. $directory + * is a reference to a PhingFile Object. + * Then, the file is locked for exclusive reading/writing. + * + * @author manuel holtgrewe, grin@gmx.net + * @throws IOException + * @access public + */ + function createTempFile($prefix, $suffix, PhingFile $directory) { + + // quick but efficient hack to create a unique filename ;-) + $result = null; + do { + $result = new PhingFile($directory, $prefix . substr(md5(time()), 0, 8) . $suffix); + } while (file_exists($result->getPath())); + + $fs = FileSystem::getFileSystem(); + $fs->createNewFile($result->getPath()); + $fs->lock($result); + + return $result; + } + + /** + * If necessary, $File the lock on $File is removed and then the file is + * deleted + * + * @access public + */ + function removeTempFile() { + $fs = FileSystem::getFileSystem(); + // catch IO Exception + $fs->unlock($this); + $this->delete(); + } + + + /* -- Basic infrastructure -- */ + + /** + * Compares two abstract pathnames lexicographically. The ordering + * defined by this method depends upon the underlying system. On UNIX + * systems, alphabetic case is significant in comparing pathnames; on Win32 + * systems it is not. + * + * @param PhingFile $file Th file whose pathname sould be compared to the pathname of this file. + * + * @return int Zero if the argument is equal to this abstract pathname, a + * value less than zero if this abstract pathname is + * lexicographically less than the argument, or a value greater + * than zero if this abstract pathname is lexicographically + * greater than the argument + */ + function compareTo(PhingFile $file) { + $fs = FileSystem::getFileSystem(); + return $fs->compare($this, $file); + } + + /** + * Tests this abstract pathname for equality with the given object. + * Returns true if and only if the argument is not + * null and is an abstract pathname that denotes the same file + * or directory as this abstract pathname. Whether or not two abstract + * pathnames are equal depends upon the underlying system. On UNIX + * systems, alphabetic case is significant in comparing pathnames; on Win32 + * systems it is not. + * @return boolean + */ + function equals($obj) { + if (($obj !== null) && ($obj instanceof PhingFile)) { + return ($this->compareTo($obj) === 0); + } + return false; + } + + /** Backwards compatibility -- use PHP5's native __tostring method. */ + function toString() { + return $this->getPath(); + } + + /** PHP5's native method. */ + function __toString() { + return $this->getPath(); + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/Reader.php b/gulliver/thirdparty/phing/system/io/Reader.php new file mode 100644 index 000000000..5e218d8ea --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/Reader.php @@ -0,0 +1,88 @@ +. +*/ + +/** + * Abstract class for reading character streams. + * @author Hans Lellelid + * @author Yannick Lecaillez + * @version $Revision: 1.5 $ + * @package phing.system.io + */ +abstract class Reader { + + /** + * Read data from source. + * If length is specified, then only that number of chars is read, + * otherwise stream is read until EOF. + * @param int $len + */ + abstract public function read($len = null); + + /** + * Close stream. + */ + abstract public function close(); + + /** + * Open stream for reading. + */ + abstract public function open(); + + /** + * Returns the filename, url, etc. that is being read from. + * This is critical for, e.g., ExpatParser's ability to know + * the filename that is throwing an ExpatParserException, etc. + * @return string + */ + abstract function getResource(); + + /** + * Move stream position relative to current pos. + * @param int $n + */ + public function skip($n) {} + + /** + * Reset the current position in stream to beginning or last mark (if supported). + */ + public function reset() {} + + /** + * If supported, places a "marker" (like a bookmark) at current stream position. + * A subsequent call to reset() will move stream position back + * to last marker (if supported). + */ + public function mark() {} + + /** + * Whether marking is supported. + * @return boolean + */ + public function markSupported() {} + + /** + * Is stream ready for reading. + * @return boolean + */ + public function ready() {} + +} +?> diff --git a/gulliver/thirdparty/phing/system/io/StringReader.php b/gulliver/thirdparty/phing/system/io/StringReader.php new file mode 100644 index 000000000..c7cda47b1 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/StringReader.php @@ -0,0 +1,73 @@ +. + */ + +/** + * Dummy class for reading character streams. + * @package phing.system.io + */ +class StringReader extends Reader { + + private $_string; + private $mark = 0; + private $currPos = 0; + + function __construct($string) { + $this->_string = $string; + } + + function skip($n) {} + + function read($len = null) { + if ($len === null) { + return $this->_string; + } else { + if ($this->currPos >= strlen($this->_string)) { + return -1; + } + $out = substr($this->_string, $this->currPos, $len); + $this->currPos += $len; + return $out; + } + } + + function mark() { + $this->mark = $this->currPos; + } + + function reset() { + $this->currPos = $this->mark; + } + + function close() {} + + function open() {} + + function ready() {} + + function markSupported() { + return true; + } + + function getResource() { + return '(string) "'.$this->_string . '"'; + } +} +?> diff --git a/gulliver/thirdparty/phing/system/io/TokenReader.php b/gulliver/thirdparty/phing/system/io/TokenReader.php new file mode 100644 index 000000000..219d72199 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/TokenReader.php @@ -0,0 +1,51 @@ +. +*/ + +include_once 'phing/system/io/Reader.php'; +include_once 'phing/filters/ReplaceTokens.php'; // for class Token + +/** + * Abstract class for reading Tokens from a resource + * + * @author Manuel Holtgewe + * @version $Revision: 1.3 $ + * @access public + * @package phing.system.io + */ +class TokenReader extends Reader { + + /** + * Constructor + */ + function __construct() { + } + + /** + * Reads a token from the resource and returns it as a + * Token object. + * + * @access public + */ + function readToken() { + } +} + +?> diff --git a/gulliver/thirdparty/phing/system/io/UnixFileSystem.php b/gulliver/thirdparty/phing/system/io/UnixFileSystem.php new file mode 100644 index 000000000..449b4e6eb --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/UnixFileSystem.php @@ -0,0 +1,266 @@ +. + */ + +include_once 'phing/system/io/FileSystem.php'; + +/** + * UnixFileSystem class. This class encapsulates the basic file system functions + * for platforms using the unix (posix)-stylish filesystem. It wraps php native + * functions suppressing normal PHP error reporting and instead uses Exception + * to report and error. + * + * This class is part of a oop based filesystem abstraction and targeted to run + * on all supported php platforms. + * + * Note: For debugging turn track_errors on in the php.ini. The error messages + * and log messages from this class will then be clearer because $php_errormsg + * is passed as part of the message. + * + * FIXME: + * - Comments + * - Error handling reduced to min, error are handled by PhingFile mainly + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.10 $ + * @package phing.system.io + */ +class UnixFileSystem extends FileSystem { + + /** + * returns OS dependant path separator char + */ + function getSeparator() { + return '/'; + } + + /** + * returns OS dependant directory separator char + */ + function getPathSeparator() { + return ':'; + } + + /** + * A normal Unix pathname contains no duplicate slashes and does not end + * with a slash. It may be the empty string. + * + * Check that the given pathname is normal. If not, invoke the real + * normalizer on the part of the pathname that requires normalization. + * This way we iterate through the whole pathname string only once. + */ + function normalize($strPathname) { + + if (empty($strPathname)) { + return; + } + + // Resolve home directories. We assume /home is where all home + // directories reside, b/c there is no other way to do this with + // PHP AFAIK. + if ($strPathname{0} === "~") { + if ($strPathname{1} === "/") { // like ~/foo => /home/user/foo + $strPathname = "/home/" . get_current_user() . substr($strPathname, 1); + } else { // like ~foo => /home/foo + $pos = strpos($strPathname, "/"); + $name = substr($strPathname, 1, $pos - 2); + $strPathname = "/home/" . $name . substr($strPathname, $pos); + } + } + + $n = strlen($strPathname); + $prevChar = 0; + for ($i=0; $i < $n; $i++) { + $c = $strPathname{$i}; + if (($prevChar === '/') && ($c === '/')) { + return self::normalizer($strPathname, $n, $i - 1); + } + $prevChar = $c; + } + if ($prevChar === '/') { + return self::normalizer($strPathname, $n, $n - 1); + } + return $strPathname; + } + + /** + * Normalize the given pathname, whose length is $len, starting at the given + * $offset; everything before this offset is already normal. + */ + protected function normalizer($pathname, $len, $offset) { + if ($len === 0) { + return $pathname; + } + $n = (int) $len; + while (($n > 0) && ($pathname{$n-1} === '/')) { + $n--; + } + if ($n === 0) { + return '/'; + } + $sb = ""; + + if ($offset > 0) { + $sb .= substr($pathname, 0, $offset); + } + $prevChar = 0; + for ($i = $offset; $i < $n; $i++) { + $c = $pathname{$i}; + if (($prevChar === '/') && ($c === '/')) { + continue; + } + $sb .= $c; + $prevChar = $c; + } + return $sb; + } + + /** + * Compute the length of the pathname string's prefix. The pathname + * string must be in normal form. + */ + function prefixLength($pathname) { + if (strlen($pathname === 0)) { + return 0; + } + return (($pathname{0} === '/') ? 1 : 0); + } + + /** + * Resolve the child pathname string against the parent. + * Both strings must be in normal form, and the result + * will be in normal form. + */ + function resolve($parent, $child) { + + if ($child === "") { + return $parent; + } + + if ($child{0} === '/') { + if ($parent === '/') { + return $child; + } + return $parent.$child; + } + + if ($parent === '/') { + return $parent.$child; + } + + return $parent.'/'.$child; + } + + function getDefaultParent() { + return '/'; + } + + function isAbsolute(PhingFile $f) { + return ($f->getPrefixLength() !== 0); + } + + /** + * the file resolver + */ + function resolveFile(PhingFile $f) { + // resolve if parent is a file oject only + if ($this->isAbsolute($f)) { + return $f->getPath(); + } else { + return $this->resolve(Phing::getProperty("user.dir"), $f->getPath()); + } + } + + /* -- most of the following is mapped to the php natives wrapped by FileSystem */ + + /* -- Attribute accessors -- */ + function getBooleanAttributes(&$f) { + //$rv = getBooleanAttributes0($f); + $name = $f->getName(); + $hidden = (strlen($name) > 0) && ($name{0} == '.'); + return ($hidden ? $this->BA_HIDDEN : 0); + } + + /** + * set file readonly on unix + */ + function setReadOnly($f) { + if ($f instanceof File) { + $strPath = (string) $f->getPath(); + $perms = (int) (@fileperms($strPath) & 0444); + return FileSystem::Chmod($strPath, $perms); + } else { + throw new Exception("IllegalArgutmentType: Argument is not File"); + } + } + + /** + * compares file paths lexicographically + */ + function compare($f1, $f2) { + if ( ($f1 instanceof PhingFile) && ($f2 instanceof PhingFile) ) { + $f1Path = $f1->getPath(); + $f2Path = $f2->getPath(); + return (boolean) strcmp((string) $f1Path, (string) $f2Path); + } else { + throw new Exception("IllegalArgutmentType: Argument is not PhingFile"); + } + } + + /* -- fs interface --*/ + + function listRoots() { + if (!$this->checkAccess('/', false)) { + die ("Can not access root"); + } + return array(new PhingFile("/")); + } + + /** + * returns the contents of a directory in an array + */ + function lister($f) { + $dir = @opendir($f->getAbsolutePath()); + if (!$dir) { + throw new Exception("Can't open directory " . $f->__toString()); + } + $vv = array(); + while (($file = @readdir($dir)) !== false) { + if ($file == "." || $file == "..") { + continue; + } + $vv[] = (string) $file; + } + @closedir($dir); + return $vv; + } + + function fromURIPath($p) { + if (StringHelper::endsWith("/", $p) && (strlen($p) > 1)) { + + // "/foo/" --> "/foo", but "/" --> "/" + $p = substr($p, 0, strlen($p) - 1); + + } + + return $p; + } + +} diff --git a/gulliver/thirdparty/phing/system/io/Win32FileSystem.php b/gulliver/thirdparty/phing/system/io/Win32FileSystem.php new file mode 100644 index 000000000..3af4b9ed5 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/Win32FileSystem.php @@ -0,0 +1,477 @@ +. + */ + +include_once 'phing/system/io/FileSystem.php'; + +/** + * @package phing.system.io + */ +class Win32FileSystem extends FileSystem { + + protected $slash; + protected $altSlash; + protected $semicolon; + + private static $driveDirCache = array(); + + function __construct() { + $this->slash = self::getSeparator(); + $this->semicolon = self::getPathSeparator(); + $this->altSlash = ($this->slash === '\\') ? '/' : '\\'; + } + + function isSlash($c) { + return ($c == '\\') || ($c == '/'); + } + + function isLetter($c) { + return ((ord($c) >= ord('a')) && (ord($c) <= ord('z'))) + || ((ord($c) >= ord('A')) && (ord($c) <= ord('Z'))); + } + + function slashify($p) { + if ((strlen($p) > 0) && ($p{0} != $this->slash)) { + return $this->slash.$p; + } + else { + return $p; + } + } + + /* -- Normalization and construction -- */ + + function getSeparator() { + // the ascii value of is the \ + return chr(92); + } + + function getPathSeparator() { + return ';'; + } + + /** + * A normal Win32 pathname contains no duplicate slashes, except possibly + * for a UNC prefix, and does not end with a slash. It may be the empty + * string. Normalized Win32 pathnames have the convenient property that + * the length of the prefix almost uniquely identifies the type of the path + * and whether it is absolute or relative: + * + * 0 relative to both drive and directory + * 1 drive-relative (begins with '\\') + * 2 absolute UNC (if first char is '\\'), else directory-relative (has form "z:foo") + * 3 absolute local pathname (begins with "z:\\") + */ + function normalizePrefix($strPath, $len, $sb) { + $src = 0; + while (($src < $len) && $this->isSlash($strPath{$src})) { + $src++; + } + $c = ""; + if (($len - $src >= 2) + && $this->isLetter($c = $strPath{$src}) + && $strPath{$src + 1} === ':') { + /* Remove leading slashes if followed by drive specifier. + * This hack is necessary to support file URLs containing drive + * specifiers (e.g., "file://c:/path"). As a side effect, + * "/c:/path" can be used as an alternative to "c:/path". */ + $sb .= $c; + $sb .= ':'; + $src += 2; + } + else { + $src = 0; + if (($len >= 2) + && $this->isSlash($strPath{0}) + && $this->isSlash($strPath{1})) { + /* UNC pathname: Retain first slash; leave src pointed at + * second slash so that further slashes will be collapsed + * into the second slash. The result will be a pathname + * beginning with "\\\\" followed (most likely) by a host + * name. */ + $src = 1; + $sb.=$this->slash; + } + } + return $src; + } + + /** Normalize the given pathname, whose length is len, starting at the given + offset; everything before this offset is already normal. */ + protected function normalizer($strPath, $len, $offset) { + if ($len == 0) { + return $strPath; + } + if ($offset < 3) { + $offset = 0; //Avoid fencepost cases with UNC pathnames + } + $src = 0; + $slash = $this->slash; + $sb = ""; + + if ($offset == 0) { + // Complete normalization, including prefix + $src = $this->normalizePrefix($strPath, $len, $sb); + } else { + // Partial normalization + $src = $offset; + $sb .= substr($strPath, 0, $offset); + } + + // Remove redundant slashes from the remainder of the path, forcing all + // slashes into the preferred slash + while ($src < $len) { + $c = $strPath{$src++}; + if ($this->isSlash($c)) { + while (($src < $len) && $this->isSlash($strPath{$src})) { + $src++; + } + if ($src === $len) { + /* Check for trailing separator */ + $sn = (int) strlen($sb); + if (($sn == 2) && ($sb{1} === ':')) { + // "z:\\" + $sb .= $slash; + break; + } + if ($sn === 0) { + // "\\" + $sb .= $slash; + break; + } + if (($sn === 1) && ($this->isSlash($sb{0}))) { + /* "\\\\" is not collapsed to "\\" because "\\\\" marks + the beginning of a UNC pathname. Even though it is + not, by itself, a valid UNC pathname, we leave it as + is in order to be consistent with the win32 APIs, + which treat this case as an invalid UNC pathname + rather than as an alias for the root directory of + the current drive. */ + $sb .= $slash; + break; + } + // Path does not denote a root directory, so do not append + // trailing slash + break; + } else { + $sb .= $slash; + } + } else { + $sb.=$c; + } + } + $rv = (string) $sb; + return $rv; + } + + /** + * Check that the given pathname is normal. If not, invoke the real + * normalizer on the part of the pathname that requires normalization. + * This way we iterate through the whole pathname string only once. + * @param string $strPath + * @return string + */ + function normalize($strPath) { + $n = strlen($strPath); + $slash = $this->slash; + $altSlash = $this->altSlash; + $prev = 0; + for ($i = 0; $i < $n; $i++) { + $c = $strPath{$i}; + if ($c === $altSlash) { + return $this->normalizer($strPath, $n, ($prev === $slash) ? $i - 1 : $i); + } + if (($c === $slash) && ($prev === $slash) && ($i > 1)) { + return $this->normalizer($strPath, $n, $i - 1); + } + if (($c === ':') && ($i > 1)) { + return $this->normalizer($strPath, $n, 0); + } + $prev = $c; + } + if ($prev === $slash) { + return $this->normalizer($strPath, $n, $n - 1); + } + return $strPath; + } + + function prefixLength($strPath) { + $path = (string) $strPath; + $slash = (string) $this->slash; + $n = (int) strlen($path); + if ($n === 0) { + return 0; + } + $c0 = $path{0}; + $c1 = ($n > 1) ? $path{1} : + 0; + if ($c0 === $slash) { + if ($c1 === $slash) { + return 2; // absolute UNC pathname "\\\\foo" + } + return 1; // drive-relative "\\foo" + } + + if ($this->isLetter($c0) && ($c1 === ':')) { + if (($n > 2) && ($path{2}) === $slash) { + return 3; // Absolute local pathname "z:\\foo" */ + } + return 2; // Directory-relative "z:foo" + } + return 0; // Completely relative + } + + function resolve($parent, $child) { + $parent = (string) $parent; + $child = (string) $child; + $slash = (string) $this->slash; + + $pn = (int) strlen($parent); + if ($pn === 0) { + return $child; + } + $cn = (int) strlen($child); + if ($cn === 0) { + return $parent; + } + + $c = $child; + if (($cn > 1) && ($c{0} === $slash)) { + if ($c{1} === $slash) { + // drop prefix when child is a UNC pathname + $c = substr($c, 2); + } + else { + //Drop prefix when child is drive-relative */ + $c = substr($c, 1); + } + } + + $p = $parent; + if ($p{$pn - 1} === $slash) { + $p = substr($p, 0, $pn - 1); + } + return $p.$this->slashify($c); + } + + function getDefaultParent() { + return (string) ("".$this->slash); + } + + function fromURIPath($strPath) { + $p = (string) $strPath; + if ((strlen($p) > 2) && ($p{2} === ':')) { + + // "/c:/foo" --> "c:/foo" + $p = substr($p,1); + + // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/" + if ((strlen($p) > 3) && StringHelper::endsWith('/', $p)) { + $p = substr($p, 0, strlen($p) - 1); + } + } elseif ((strlen($p) > 1) && StringHelper::endsWith('/', $p)) { + // "/foo/" --> "/foo" + $p = substr($p, 0, strlen($p) - 1); + } + return (string) $p; + } + + + /* -- Path operations -- */ + + function isAbsolute(PhingFile $f) { + $pl = (int) $f->getPrefixLength(); + $p = (string) $f->getPath(); + return ((($pl === 2) && ($p{0} === $this->slash)) || ($pl === 3) || ($pl === 1 && $p{0} === $this->slash)); + } + + /** private */ + function _driveIndex($d) { + $d = (string) $d{0}; + if ((ord($d) >= ord('a')) && (ord($d) <= ord('z'))) { + return ord($d) - ord('a'); + } + if ((ord($d) >= ord('A')) && (ord($d) <= ord('Z'))) { + return ord($d) - ord('A'); + } + return -1; + } + + /** private */ + function _getDriveDirectory($drive) { + $drive = (string) $drive{0}; + $i = (int) $this->_driveIndex($drive); + if ($i < 0) { + return null; + } + + $s = (isset(self::$driveDirCache[$i]) ? self::$driveDirCache[$i] : null); + + if ($s !== null) { + return $s; + } + + $s = $this->_getDriveDirectory($i + 1); + self::$driveDirCache[$i] = $s; + return $s; + } + + function _getUserPath() { + //For both compatibility and security, we must look this up every time + return (string) $this->normalize(Phing::getProperty("user.dir")); + } + + function _getDrive($path) { + $path = (string) $path; + $pl = $this->prefixLength($path); + return ($pl === 3) ? substr($path, 0, 2) : null; + } + + function resolveFile(PhingFile $f) { + $path = $f->getPath(); + $pl = (int) $f->getPrefixLength(); + + if (($pl === 2) && ($path{0} === $this->slash)) { + return path; // UNC + } + + if ($pl === 3) { + return $path; // Absolute local + } + + if ($pl === 0) { + return (string) ($this->_getUserPath().$this->slashify($path)); //Completely relative + } + + if ($pl === 1) { // Drive-relative + $up = (string) $this->_getUserPath(); + $ud = (string) $this->_getDrive($up); + if ($ud !== null) { + return (string) $ud.$path; + } + return (string) $up.$path; //User dir is a UNC path + } + + if ($pl === 2) { // Directory-relative + $up = (string) $this->_getUserPath(); + $ud = (string) $this->_getDrive($up); + if (($ud !== null) && StringHelper::startsWith($ud, $path)) { + return (string) ($up . $this->slashify(substr($path,2))); + } + $drive = (string) $path{0}; + $dir = (string) $this->_getDriveDirectory($drive); + + $np = (string) ""; + if ($dir !== null) { + /* When resolving a directory-relative path that refers to a + drive other than the current drive, insist that the caller + have read permission on the result */ + $p = (string) $drive . (':'.$dir.$this->slashify(substr($path,2))); + + if (!$this->checkAccess($p, false)) { + // FIXME + // throw security error + die("Can't resolve path $p"); + } + return $p; + } + return (string) $drive.':'.$this->slashify(substr($path,2)); //fake it + } + + throw new Exception("Unresolvable path: " . $path); + } + + /* -- most of the following is mapped to the functions mapped th php natives in FileSystem */ + + /* -- Attribute accessors -- */ + + function setReadOnly($f) { + // dunno how to do this on win + throw new Exception("WIN32FileSystem doesn't support read-only yet."); + } + + /* -- Filesystem interface -- */ + + protected function _access($path) { + if (!$this->checkAccess($path, false)) { + throw new Exception("Can't resolve path $p"); + } + return true; + } + + function _nativeListRoots() { + // FIXME + } + + function listRoots() { + $ds = _nativeListRoots(); + $n = 0; + for ($i = 0; $i < 26; $i++) { + if ((($ds >> $i) & 1) !== 0) { + if (!$this->access((string)( chr(ord('A') + $i) . ':' . $this->slash))) { + $ds &= ~(1 << $i); + } else { + $n++; + } + } + } + $fs = array(); + $j = (int) 0; + $slash = (string) $this->slash; + for ($i = 0; $i < 26; $i++) { + if ((($ds >> $i) & 1) !== 0) { + $fs[$j++] = new PhingFile(chr(ord('A') + $i) . ':' . $this->slash); + } + } + return $fs; + } + + /* -- Basic infrastructure -- */ + + /** compares file paths lexicographically */ + function compare(PhingFile $f1, PhingFile $f2) { + $f1Path = $f1->getPath(); + $f2Path = $f2->getPath(); + return (boolean) strcasecmp((string) $f1Path, (string) $f2Path); + } + + + /** + * returns the contents of a directory in an array + */ + function lister($f) { + $dir = @opendir($f->getAbsolutePath()); + if (!$dir) { + throw new Exception("Can't open directory " . $f->__toString()); + } + $vv = array(); + while (($file = @readdir($dir)) !== false) { + if ($file == "." || $file == "..") { + continue; + } + $vv[] = (string) $file; + } + @closedir($dir); + return $vv; + } + +} + +?> diff --git a/gulliver/thirdparty/phing/system/io/WinNTFileSystem.php b/gulliver/thirdparty/phing/system/io/WinNTFileSystem.php new file mode 100644 index 000000000..948475952 --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/WinNTFileSystem.php @@ -0,0 +1,35 @@ +. + */ + +include_once 'phing/system/io/Win32FileSystem.php'; + +/** + * FileSystem for Windows NT/2000. + * @package phing.system.io + */ + +class WinNTFileSystem extends Win32FileSystem { + + /* -- class only for convenience and future use everything is inherinted --*/ + + +} +?> diff --git a/gulliver/thirdparty/phing/system/io/Writer.php b/gulliver/thirdparty/phing/system/io/Writer.php new file mode 100644 index 000000000..cb319454c --- /dev/null +++ b/gulliver/thirdparty/phing/system/io/Writer.php @@ -0,0 +1,48 @@ +. + */ + +/** + * Abstract class for writing character streams. + * @package phing.system.io + */ +abstract class Writer { + + abstract public function write($buf, $off = null, $len = null); + + abstract public function reset(); + + abstract public function close(); + + abstract public function open(); + + public function mark() {} + + public function ready() {} + + public function markSupported() {} + + /** + * Returns the filename, url, etc. that is being written to. + * @return string + */ + abstract function getResource(); +} +?> diff --git a/gulliver/thirdparty/phing/system/lang/Character.php b/gulliver/thirdparty/phing/system/lang/Character.php new file mode 100644 index 000000000..0738a9366 --- /dev/null +++ b/gulliver/thirdparty/phing/system/lang/Character.php @@ -0,0 +1,49 @@ +. + */ + +/** + * @package phing.system.lang + */ +class Character { + + // this class might be extended with plenty of ordinal char constants + // and the like to support the multibyte aware datatype (char) in php + // in form of an object. + // anyway just a thought + + public static function isLetter($char) { + + if (strlen($char) !== 1) + $char = 0; + + $char = (int) ord($char); + + if ($char >= ord('A') && $char <= ord('Z')) + return true; + + if ($char >= ord('a') && $char <= ord('z')) + return true; + + return false; + } + +} +?> diff --git a/gulliver/thirdparty/phing/system/lang/EventObject.php b/gulliver/thirdparty/phing/system/lang/EventObject.php new file mode 100644 index 000000000..92922e942 --- /dev/null +++ b/gulliver/thirdparty/phing/system/lang/EventObject.php @@ -0,0 +1,52 @@ +. + */ + +/** + * @package phing.system.lang + */ +class EventObject { + + /** The object on which the Event initially occurred. */ + protected $source; + + /** Constructs a prototypical Event. */ + function __construct($source) { + if ($source === null) { + throw new Exception("Null source"); + } + $this->source = $source; + } + + /** The object on which the Event initially occurred. */ + function getSource() { + return $this->source; + } + + /** Returns a String representation of this EventObject.*/ + function toString() { + if (method_exists($this->source, "toString")) { + return get_class($this)."[source=".$this->source->toString()."]"; + } else { + return get_class($this)."[source=".get_class($this->source)."]"; + } + } +} +?> diff --git a/gulliver/thirdparty/phing/system/lang/FileNotFoundException.php b/gulliver/thirdparty/phing/system/lang/FileNotFoundException.php new file mode 100644 index 000000000..612b29840 --- /dev/null +++ b/gulliver/thirdparty/phing/system/lang/FileNotFoundException.php @@ -0,0 +1,27 @@ +. + */ + +/** + * @package phing.system.lang + */ +class FileNotFoundException extends Exception {} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/system/lang/NullPointerException.php b/gulliver/thirdparty/phing/system/lang/NullPointerException.php new file mode 100644 index 000000000..c152aee54 --- /dev/null +++ b/gulliver/thirdparty/phing/system/lang/NullPointerException.php @@ -0,0 +1,27 @@ +. + */ + +/** + * @package phing.system.lang + */ +class NullPointerException extends Exception {} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/system/lang/SecurityException.php b/gulliver/thirdparty/phing/system/lang/SecurityException.php new file mode 100644 index 000000000..0d210142d --- /dev/null +++ b/gulliver/thirdparty/phing/system/lang/SecurityException.php @@ -0,0 +1,27 @@ +. + */ + +/** + * @package phing.system.lang + */ +class SecurityException extends Exception {} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/system/util/Message.php b/gulliver/thirdparty/phing/system/util/Message.php new file mode 100644 index 000000000..bf7bb56b9 --- /dev/null +++ b/gulliver/thirdparty/phing/system/util/Message.php @@ -0,0 +1,9 @@ + diff --git a/gulliver/thirdparty/phing/system/util/Properties.php b/gulliver/thirdparty/phing/system/util/Properties.php new file mode 100644 index 000000000..1bbaf8648 --- /dev/null +++ b/gulliver/thirdparty/phing/system/util/Properties.php @@ -0,0 +1,270 @@ +. + */ + +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/FileWriter.php'; + +/** + * Convenience class for reading and writing property files. + * + * FIXME + * - Add support for arrays (separated by ',') + * + * @package phing.system.util + * @version $Revision: 1.13 $ + */ +class Properties { + + private $properties = array(); + + /** + * Load properties from a file. + * + * @param PhingFile $file + * @return void + * @throws IOException - if unable to read file. + */ + function load(PhingFile $file) { + if ($file->canRead()) { + $this->parse($file->getPath(), false); + } else { + throw new IOException("Can not read file ".$file->getPath()); + } + + } + + /** + * Replaces parse_ini_file() or better_parse_ini_file(). + * Saves a step since we don't have to parse and then check return value + * before throwing an error or setting class properties. + * + * @param string $filePath + * @param boolean $processSections Whether to honor [SectionName] sections in INI file. + * @return array Properties loaded from file (no prop replacements done yet). + */ + protected function parse($filePath) { + + // load() already made sure that file is readable + // but we'll double check that when reading the file into + // an array + + if (($lines = @file($filePath)) === false) { + throw new IOException("Unable to parse contents of $filePath"); + } + + $this->properties = array(); + $sec_name = ""; + + foreach($lines as $line) { + + $line = trim($line); + + if($line == "") + continue; + + if ($line{0} == '#' or $line{0} == ';') { + // it's a comment, so continue to next line + continue; + } else { + $pos = strpos($line, '='); + $property = trim(substr($line, 0, $pos)); + $value = trim(substr($line, $pos + 1)); + $this->properties[$property] = $this->inVal($value); + } + + } // for each line + } + + /** + * Process values when being read in from properties file. + * does things like convert "true" => true + * @param string $val Trimmed value. + * @return mixed The new property value (may be boolean, etc.) + */ + protected function inVal($val) { + if ($val === "true") { + $val = true; + } elseif ($val === "false") { + $val = false; + } + return $val; + } + + /** + * Process values when being written out to properties file. + * does things like convert true => "true" + * @param mixed $val The property value (may be boolean, etc.) + * @return string + */ + protected function outVal($val) { + if ($val === true) { + $val = "true"; + } elseif ($val === false) { + $val = "false"; + } + return $val; + } + + /** + * Create string representation that can be written to file and would be loadable using load() method. + * + * Essentially this function creates a string representation of properties that is ready to + * write back out to a properties file. This is used by store() method. + * + * @return string + */ + public function toString() { + $buf = ""; + foreach($this->properties as $key => $item) { + $buf .= $key . "=" . $this->outVal($item) . Phing::getProperty('line.separator'); + } + return $buf; + } + + /** + * Stores current properties to specified file. + * + * @param PhingFile $file File to create/overwrite with properties. + * @param string $header Header text that will be placed (within comments) at the top of properties file. + * @return void + * @throws IOException - on error writing properties file. + */ + function store(PhingFile $file, $header = null) { + // stores the properties in this object in the file denoted + // if file is not given and the properties were loaded from a + // file prior, this method stores them in the file used by load() + try { + $fw = new FileWriter($file); + $fw->open(); + if ($header !== null) { + $fw->write( "# " . $header . Phing::getProperty("line.separator") ); + } + $fw->write($this->toString()); + $fw->close(); + } catch (IOException $e) { + throw new IOException("Error writing property file: " . $e->getMessage()); + } + } + + /** + * Returns copy of internal properties hash. + * Mostly for performance reasons, property hashes are often + * preferable to passing around objects. + * + * @return array + */ + function getProperties() { + return $this->properties; + } + + /** + * Get value for specified property. + * This is the same as get() method. + * + * @param string $prop The property name (key). + * @return mixed + * @see get() + */ + function getProperty($prop) { + if (!isset($this->properties[$prop])) { + return null; + } + return $this->properties[$prop]; + } + + /** + * Get value for specified property. + * This function exists to provide a hashtable-like interface for + * properties. + * + * @param string $prop The property name (key). + * @return mixed + * @see getProperty() + */ + function get($prop) { + if (!isset($this->properties[$prop])) { + return null; + } + return $this->properties[$prop]; + } + + /** + * Set the value for a property. + * + * @param string $key + * @param mixed $value + * @return mixed Old property value or NULL if none was set. + */ + function setProperty($key, $value) { + $oldValue = @$this->properties[$key]; + $this->properties[$key] = $value; + return $oldValue; + } + + /** + * Set the value for a property. + * This function exists to provide hashtable-lie + * interface for properties. + * + * @param string $key + * @param mixed $value + */ + function put($key, $value) { + return $this->setProperty($key, $value); + } + + /** + * Same as keys() function, returns an array of property names. + * @return array + */ + function propertyNames() { + return $this->keys(); + } + + /** + * Whether loaded properties array contains specified property name. + * @return boolean + */ + function containsKey($key) { + return isset($this->properties[$key]); + } + + /** + * Returns properties keys. + * Use this for foreach() {} iterations, as this is + * faster than looping through property values. + * @return array + */ + function keys() { + return array_keys($this->properties); + } + + /** + * Whether properties list is empty. + * @return boolean + */ + function isEmpty() { + return empty($this->properties); + } + +} +?> diff --git a/gulliver/thirdparty/phing/system/util/Register.php b/gulliver/thirdparty/phing/system/util/Register.php new file mode 100644 index 000000000..5ef2b2fd7 --- /dev/null +++ b/gulliver/thirdparty/phing/system/util/Register.php @@ -0,0 +1,115 @@ + + * + * + * + * The task/type must provide a supporting setter for the attribute: + * + * + * function setListeningReplace(RegisterSlot $slot) { + * $this->replace = $slot; + * } + * + * // in main() + * if ($this->replace instanceof RegisterSlot) { + * $this->regexp->setReplace($this->replace->getValue()); + * } else { + * $this->regexp->setReplace($this->replace); + * } + * + * + * @author Hans Lellelid + * @version $Revision: 1.3 $ + * @package phing.system.util + */ +class Register { + + /** Slots that have been registered */ + private static $slots = array(); + + /** + * Returns RegisterSlot for specified key. + * + * If not slot exists a new one is created for key. + * + * @param string $key + * @return RegisterSlot + */ + public static function getSlot($key) { + if (!isset(self::$slots[$key])) { + self::$slots[$key] = new RegisterSlot($key); + } + return self::$slots[$key]; + } +} + + +/** + * Represents a slot in the register. + */ +class RegisterSlot { + + /** The name of this slot. */ + private $key; + + /** The value for this slot. */ + private $value; + + /** + * Constructs a new RegisterSlot, setting the key to passed param. + * @param string $key + */ + public function __construct($key) { + $this->key = (string) $key; + } + + /** + * Sets the key / name for this slot. + * @param string $k + */ + public function setKey($k) { + $this->key = (string) $k; + } + + /** + * Gets the key / name for this slot. + * @return string + */ + public function getKey() { + return $this->key; + } + + /** + * Sets the value for this slot. + * @param mixed + */ + public function setValue($v) { + $this->value = $v; + } + + /** + * Returns the value at this slot. + * @return mixed + */ + public function getValue() { + return $this->value; + } + +} +?> diff --git a/gulliver/thirdparty/phing/system/util/Timer.php b/gulliver/thirdparty/phing/system/util/Timer.php new file mode 100644 index 000000000..e95191f3b --- /dev/null +++ b/gulliver/thirdparty/phing/system/util/Timer.php @@ -0,0 +1,96 @@ +. + */ + + +/** + * This class can be used to obtain the execution time of all of the scripts + * that are executed in the process of building a page. + * + * Example: + * To be done before any scripts execute: + * + * $Timer = new Timer; + * $Timer->Start_Timer(); + * + * To be done after all scripts have executed: + * + * $timer->Stop_Timer(); + * $timer->Get_Elapsed_Time(int number_of_places); + * + * @author Charles Killian + * @author Hans Lellelid + * @package phing.system.util + * @version $Revision: 1.5 $ $Date: 2003/12/24 13:02:09 $ + */ +class Timer { + + /** start time */ + protected $stime; + + /** end time */ + protected $etime; + + /** + * This function sets the class variable $stime to the current time in + * microseconds. + * @return void + */ + public function start() { + $this->stime = $this->getMicrotime(); + } + + /** + * This function sets the class variable $etime to the current time in + * microseconds. + * @return void + */ + function stop() { + $this->etime = $this->getMicrotime(); + } + + /** + * This function returns the elapsed time in seconds. + * + * Call start_time() at the beginning of script execution and end_time() at + * the end of script execution. Then, call elapsed_time() to obtain the + * difference between start_time() and end_time(). + * + * @param $places decimal place precision of elapsed time (default is 5) + * @return string Properly formatted time. + */ + function getElapsedTime($places=5) { + $etime = $this->etime - $this->stime; + $format = "%0.".$places."f"; + return (sprintf ($format, $etime)); + } + + /** + * This function returns the current time in microseconds. + * + * @author Everett Michaud, Zend.com + * @return current time in microseconds + * @access private + */ + function getMicrotime() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } +} diff --git a/gulliver/thirdparty/phing/tasks/defaults.properties b/gulliver/thirdparty/phing/tasks/defaults.properties new file mode 100644 index 000000000..825d55059 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/defaults.properties @@ -0,0 +1,72 @@ +; ------------------------------------- +; These taskdefs are loaded at startup. +; ------------------------------------- + +; Internal system tasks +; +adhoc=phing.tasks.system.AdhocTask +adhoc-task=phing.tasks.system.AdhocTaskdefTask +adhoc-type=phing.tasks.system.AdhocTypedefTask +append=phing.tasks.system.AppendTask +available=phing.tasks.system.AvailableTask +chmod=phing.tasks.system.ChmodTask +concat=phing.tasks.system.AppendTask +condition=phing.tasks.system.ConditionTask +copy=phing.tasks.system.CopyTask +cvs=phing.tasks.system.CvsTask +cvspass=phing.tasks.system.CvsPassTask +delete=phing.tasks.system.DeleteTask +echo=phing.tasks.system.EchoTask +exec=phing.tasks.system.ExecTask +fail=phing.tasks.system.ExitTask +foreach=phing.tasks.system.ForeachTask +includepath=phing.tasks.system.IncludePathTask +input=phing.tasks.system.InputTask +mkdir=phing.tasks.system.MkdirTask +move=phing.tasks.system.MoveTask +phing=phing.tasks.system.PhingTask +phingcall=phing.tasks.system.PhingCallTask +php=phing.tasks.system.PhpEvalTask +property=phing.tasks.system.PropertyTask +propertyprompt=phing.tasks.system.PropertyPromptTask +reflexive=phing.tasks.system.ReflexiveTask +resolvepath=phing.tasks.system.ResolvePathTask +taskdef=phing.tasks.system.TaskdefTask +touch=phing.tasks.system.TouchTask +tstamp=phing.tasks.system.TstampTask +typedef=phing.tasks.system.TypedefTask +uptodate=phing.tasks.system.UpToDateTask +xslt=phing.tasks.system.XsltTask +if=phing.tasks.system.IfTask +warn=phing.tasks.system.WarnTask + +; "Core" contributed tasks +; -- i.e. no taskdef needed. + +sql=phing.tasks.ext.CreoleSQLExecTask +package-as-path=phing.tasks.ext.PackageAsPathTask +smarty=phing.tasks.ext.SmartyTask +capsule=phing.tasks.ext.CapsuleTask +tar=phing.tasks.ext.TarTask +untar=phing.tasks.ext.UntarTask +pearpkg=phing.tasks.ext.PearPackageTask +mail=phing.tasks.ext.MailTask +zip=phing.tasks.ext.ZipTask +unzip=phing.tasks.ext.UnzipTask +phplint=phing.tasks.ext.PhpLintTask + +; "ext" tasks +phpdoc=phing.tasks.ext.phpdoc.PHPDocumentorTask +svnlastrevision=phing.tasks.ext.svn.SvnLastRevisionTask +svnexport=phing.tasks.ext.svn.SvnExportTask +phpunit2=phing.tasks.ext.phpunit2.PHPUnit2Task +phpunit2report=phing.tasks.ext.phpunit2.PHPUnit2ReportTask +coverage-setup=phing.tasks.ext.coverage.CoverageSetupTask +coverage-merger=phing.tasks.ext.coverage.CoverageMergerTask +coverage-report=phing.tasks.ext.coverage.CoverageReportTask +ioncubeencoder=phing.tasks.ext.ioncube.IoncubeEncoderTask +ioncubelicense=phing.tasks.ext.ioncube.IoncubeLicenseTask +simpletest=phing.tasks.ext.simpletest.SimpleTestTask +phplint=phing.tasks.ext.PhpLintTask +xmllint=phing.tasks.ext.XmlLintTask +analyze=phing.tasks.ext.ZendCodeAnalyzerTask \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/CapsuleTask.php b/gulliver/thirdparty/phing/tasks/ext/CapsuleTask.php new file mode 100644 index 000000000..29088c72d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/CapsuleTask.php @@ -0,0 +1,478 @@ +. + */ + +include_once 'phing/Task.php'; +include_once 'phing/BuildException.php'; +include_once 'phing/lib/Capsule.php'; +include_once 'phing/util/StringHelper.php'; + +/** + * A phing task for generating output by using Capsule. + * + * This is based on the interface to TexenTask from Apache's Velocity engine. + * + * @author Hans Lellelid + * @version $Revision: 1.17 $ + * @package phing.tasks.ext + */ +class CapsuleTask extends Task { + + /** + * Capsule "template" engine. + * @var Capsule + */ + protected $context; + + /** + * Any vars assigned via the build file. + * @var array AssignedVar[] + */ + protected $assignedVars = array(); + + /** + * This is the control template that governs the output. + * It may or may not invoke the services of worker + * templates. + * @var string + */ + protected $controlTemplate; + + /** + * This is where Velocity will look for templates + * using the file template loader. + * @var string + */ + protected $templatePath; + + /** + * This is where texen will place all the output + * that is a product of the generation process. + * @var string + */ + protected $outputDirectory; + + /** + * This is the file where the generated text + * will be placed. + * @var string + */ + protected $outputFile; + + /** + *

    + * These are properties that are fed into the + * initial context from a properties file. This + * is simply a convenient way to set some values + * that you wish to make available in the context. + *

    + *

    + * These values are not critical, like the template path + * or output path, but allow a convenient way to + * set a value that may be specific to a particular + * generation task. + *

    + *

    + * For example, if you are generating scripts to allow + * user to automatically create a database, then + * you might want the $databaseName + * to be placed + * in the initial context so that it is available + * in a script that might look something like the + * following: + *

    +     * #!bin/sh
    +     * 
    +     * echo y | mysqladmin create $databaseName
    +     * 
    + * The value of $databaseName isn't critical to + * output, and you obviously don't want to change + * the ant task to simply take a database name. + * So initial context values can be set with + * properties file. + * + * @var array + */ + protected $contextProperties; + + // ----------------------------------------------------------------------- + // The following getters & setters are used by phing to set properties + // specified in the XML for the capsule task. + // ----------------------------------------------------------------------- + + /** + * [REQUIRED] Set the control template for the + * generating process. + * @param string $controlTemplate + * @return void + */ + public function setControlTemplate ($controlTemplate) { + $this->controlTemplate = $controlTemplate; + } + + /** + * Get the control template for the + * generating process. + * @return string + */ + public function getControlTemplate() { + return $this->controlTemplate; + } + + /** + * [REQUIRED] Set the path where Velocity will look + * for templates using the file template + * loader. + * @return void + * @throws Exception + */ + public function setTemplatePath($templatePath) { + $resolvedPath = ""; + $tok = strtok($templatePath, ","); + while ( $tok ) { + // resolve relative path from basedir and leave + // absolute path untouched. + $fullPath = $this->project->resolveFile($tok); + $cpath = $fullPath->getCanonicalPath(); + if ($cpath === false) { + $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); + } else { + $resolvedPath .= $cpath; + } + $tok = strtok(","); + if ( $tok ) { + $resolvedPath .= ","; + } + } + $this->templatePath = $resolvedPath; + } + + /** + * Get the path where Velocity will look + * for templates using the file template + * loader. + * @return string + */ + public function getTemplatePath() { + return $this->templatePath; + } + + /** + * [REQUIRED] Set the output directory. It will be + * created if it doesn't exist. + * @param PhingFile $outputDirectory + * @return void + * @throws Exception + */ + public function setOutputDirectory(PhingFile $outputDirectory) { + try { + if (!$outputDirectory->exists()) { + $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE); + if (!$outputDirectory->mkdirs()) { + throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); + } + } + $this->outputDirectory = $outputDirectory->getCanonicalPath(); + } catch (IOException $ioe) { + throw new BuildException($ioe); + } + } + + /** + * Get the output directory. + * @return string + */ + public function getOutputDirectory() { + return $this->outputDirectory; + } + + /** + * [REQUIRED] Set the output file for the + * generation process. + * @param string $outputFile (TODO: change this to File) + * @return void + */ + public function setOutputFile($outputFile) { + $this->outputFile = $outputFile; + } + + /** + * Get the output file for the + * generation process. + * @return string + */ + public function getOutputFile() { + return $this->outputFile; + } + + /** + * Set the context properties that will be + * fed into the initial context be the + * generating process starts. + * @param string $file + * @return void + */ + public function setContextProperties($file) { + $sources = explode(",", $file); + $this->contextProperties = new Properties(); + + // Always try to get the context properties resource + // from a file first. Templates may be taken from a JAR + // file but the context properties resource may be a + // resource in the filesystem. If this fails than attempt + // to get the context properties resource from the + // classpath. + for ($i=0, $sourcesLength=count($sources); $i < $sourcesLength; $i++) { + $source = new Properties(); + + try { + + // resolve relative path from basedir and leave + // absolute path untouched. + $fullPath = $this->project->resolveFile($sources[$i]); + $this->log("Using contextProperties file: " . $fullPath->toString()); + $source->load($fullPath); + + } catch (Exception $e) { + + throw new BuildException("Context properties file " . $sources[$i] . + " could not be found in the file system!"); + + } + + $keys = $source->keys(); + + foreach ($keys as $key) { + $name = $key; + $value = $this->project->replaceProperties($source->getProperty($name)); + $this->contextProperties->setProperty($name, $value); + } + } + } + + /** + * Get the context properties that will be + * fed into the initial context be the + * generating process starts. + * @return Properties + */ + public function getContextProperties() { + return $this->contextProperties; + } + + /** + * Creates an "AssignedVar" class. + */ + public function createAssign() { + $a = new AssignedVar(); + $this->assignedVars[] = $a; + return $a; + } + + // --------------------------------------------------------------- + // End of XML setters & getters + // --------------------------------------------------------------- + + /** + * Creates a Smarty object. + * + * @return Smarty initialized (cleared) Smarty context. + * @throws Exception the execute method will catch + * and rethrow as a BuildException + */ + public function initControlContext() { + $this->context->clear(); + foreach($this->assignedVars as $var) { + $this->context->put($var->getName(), $var->getValue()); + } + return $this->context; + } + + /** + * Execute the input script with Velocity + * + * @throws BuildException + * BuildExceptions are thrown when required attributes are missing. + * Exceptions thrown by Velocity are rethrown as BuildExceptions. + */ + public function main() { + + // Make sure the template path is set. + if (empty($this->templatePath)) { + throw new BuildException("The template path needs to be defined!"); + } + + // Make sure the control template is set. + if ($this->controlTemplate === null) { + throw new BuildException("The control template needs to be defined!"); + } + + // Make sure the output directory is set. + if ($this->outputDirectory === null) { + throw new BuildException("The output directory needs to be defined!"); + } + + // Make sure there is an output file. + if ($this->outputFile === null) { + throw new BuildException("The output file needs to be defined!"); + } + + // Setup Smarty runtime. + + // Smarty uses one object to store properties and to store + // the context for the template (unlike Velocity). We setup this object, calling it + // $this->context, and then initControlContext simply zeros out + // any assigned variables. + $this->context = new Capsule(); + + if ($this->templatePath !== null) { + $this->log("Using templatePath: " . $this->templatePath); + $this->context->setTemplatePath($this->templatePath); + } + + // Make sure the output directory exists, if it doesn't + // then create it. + $outputDir = new PhingFile($this->outputDirectory); + if (!$outputDir->exists()) { + $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath()); + $outputDir->mkdirs(); + } + + $this->context->setOutputDirectory($outputDir->getAbsolutePath()); + + $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; + $this->log("Generating to file " . $path); + + //$writer = new FileWriter($path); + + // The generator and the output path should + // be placed in the init context here and + // not in the generator class itself. + $c = $this->initControlContext(); + + // Set any variables that need to always + // be loaded + $this->populateInitialContext($c); + + // Feed all the options into the initial + // control context so they are available + // in the control/worker templates. + if ($this->contextProperties !== null) { + + foreach($this->contextProperties->keys() as $property) { + + $value = $this->contextProperties->getProperty($property); + + // Special exception (from Texen) + // for properties ending in file.contents: + // in that case we dump the contents of the file + // as the "value" for the Property. + if (preg_match('/file\.contents$/', $property)) { + // pull in contents of file specified + + $property = substr($property, 0, strpos($property, "file.contents") - 1); + + // reset value, and then + // read in teh contents of the file into that var + $value = ""; + $f = new PhingFile($project->resolveFile($value)->getCanonicalPath()); + if ($f->exists()) { + $fr = new FileReader($f); + $fr->readInto($value); + } + + } // if ends with file.contents + + if (StringHelper::isBoolean($value)) { + $value = StringHelper::booleanValue($value); + } + + $c->put($property, $value); + + } // foreach property + + } // if contextProperties !== null + + try { + $this->log("Parsing control template: " . $this->controlTemplate); + $c->parse($this->controlTemplate, $path); + } catch (Exception $ioe) { + throw new BuildException("Cannot write parsed template: ". $ioe->getMessage()); + } + + $this->cleanup(); + } + + /** + * Place useful objects into the initial context. + * + * + * @param Capsule $context The context to populate, as retrieved from + * {@link #initControlContext()}. + * @return void + * @throws Exception Error while populating context. The {@link + * #main()} method will catch and rethrow as a + * BuildException. + */ + protected function populateInitialContext(Capsule $context) { + $this->context->put("now", strftime("%c", time())); + $this->context->put("task", $this); + } + + /** + * A hook method called at the end of {@link #execute()} which can + * be overridden to perform any necessary cleanup activities (such + * as the release of database connections, etc.). By default, + * does nothing. + * @return void + * @throws Exception Problem cleaning up. + */ + protected function cleanup() { + } +} + + +/** + * An "inner" class for holding assigned var values. + * May be need to expand beyond name/value in the future. + */ +class AssignedVar { + + private $name; + private $value; + + function setName($v) { + $this->name = $v; + } + + function setValue($v) { + $this->value = $v; + } + + function getName() { + return $this->name; + } + + function getValue() { + return $this->value; + } + +} \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/CreoleSQLExecTask.php b/gulliver/thirdparty/phing/tasks/ext/CreoleSQLExecTask.php new file mode 100644 index 000000000..ef6645cbc --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/CreoleSQLExecTask.php @@ -0,0 +1,556 @@ +. + */ + +require_once 'phing/tasks/ext/CreoleTask.php'; +include_once 'phing/system/io/StringReader.php'; + +/** + * Executes a series of SQL statements on a database using Creole. + * + *

    Statements can + * either be read in from a text file using the src attribute or from + * between the enclosing SQL tags.

    + * + *

    Multiple statements can be provided, separated by semicolons (or the + * defined delimiter). Individual lines within the statements can be + * commented using either --, // or REM at the start of the line.

    + * + *

    The autocommit attribute specifies whether auto-commit should be + * turned on or off whilst executing the statements. If auto-commit is turned + * on each statement will be executed and committed. If it is turned off the + * statements will all be executed as one transaction.

    + * + *

    The onerror attribute specifies how to proceed when an error occurs + * during the execution of one of the statements. + * The possible values are: continue execution, only show the error; + * stop execution and commit transaction; + * and abort execution and transaction and fail task.

    + * + * @author Hans Lellelid (Phing) + * @author Jeff Martin (Ant) + * @author Michael McCallum (Ant) + * @author Tim Stephenson (Ant) + * @package phing.tasks.ext + * @version $Revision: 1.21 $ + */ +class CreoleSQLExecTask extends CreoleTask { + + private $goodSql = 0; + private $totalSql = 0; + + const DELIM_ROW = "row"; + const DELIM_NORMAL = "normal"; + + /** + * Database connection + */ + private $conn = null; + + /** + * files to load + */ + private $filesets = array(); + + /** + * SQL statement + */ + private $statement = null; + + /** + * SQL input file + */ + private $srcFile = null; + + /** + * SQL input command + */ + private $sqlCommand = ""; + + /** + * SQL transactions to perform + */ + private $transactions = array(); + + /** + * SQL Statement delimiter + */ + private $delimiter = ";"; + + /** + * The delimiter type indicating whether the delimiter will + * only be recognized on a line by itself + */ + private $delimiterType = "normal"; // can't use constant just defined + + /** + * Print SQL results. + */ + private $print = false; + + /** + * Print header columns. + */ + private $showheaders = true; + + /** + * Results Output file. + */ + private $output = null; + + + /** + * Action to perform if an error is found + **/ + private $onError = "abort"; + + /** + * Encoding to use when reading SQL statements from a file + */ + private $encoding = null; + + /** + * Append to an existing file or overwrite it? + */ + private $append = false; + + /** + * Set the name of the SQL file to be run. + * Required unless statements are enclosed in the build file + */ + public function setSrc(PhingFile $srcFile) { + $this->srcFile = $srcFile; + } + + /** + * Set an inline SQL command to execute. + * NB: Properties are not expanded in this text. + */ + public function addText($sql) { + $this->sqlCommand .= $sql; + } + + /** + * Adds a set of files (nested fileset attribute). + */ + public function addFileset(FileSet $set) { + $this->filesets[] = $set; + } + + /** + * Add a SQL transaction to execute + */ + public function createTransaction() { + $t = new SQLExecTransaction($this); + $this->transactions[] = $t; + return $t; + } + + /** + * Set the file encoding to use on the SQL files read in + * + * @param encoding the encoding to use on the files + */ + public function setEncoding($encoding) { + $this->encoding = $encoding; + } + + /** + * Set the statement delimiter. + * + *

    For example, set this to "go" and delimitertype to "ROW" for + * Sybase ASE or MS SQL Server.

    + * + * @param delimiter + */ + public function setDelimiter($delimiter) + { + $this->delimiter = $delimiter; + } + + /** + * Set the Delimiter type for this sql task. The delimiter type takes two + * values - normal and row. Normal means that any occurence of the delimiter + * terminate the SQL command whereas with row, only a line containing just + * the delimiter is recognized as the end of the command. + * + * @param string $delimiterType + */ + public function setDelimiterType($delimiterType) + { + $this->delimiterType = $delimiterType; + } + + /** + * Set the print flag. + * + * @param boolean $print + */ + public function setPrint($print) + { + $this->print = (boolean) $print; + } + + /** + * Print headers for result sets from the + * statements; optional, default true. + * @param boolean $showheaders + */ + public function setShowheaders($showheaders) { + $this->showheaders = (boolean) $showheaders; + } + + /** + * Set the output file; + * optional, defaults to the console. + * @param PhingFile $output + */ + public function setOutput(PhingFile $output) { + $this->output = $output; + } + + /** + * whether output should be appended to or overwrite + * an existing file. Defaults to false. + * @param $append + */ + public function setAppend($append) { + $this->append = (boolean) $append; + } + + + /** + * Action to perform when statement fails: continue, stop, or abort + * optional; default "abort" + */ + public function setOnerror($action) { + $this->onError = $action; + } + + /** + * Load the sql file and then execute it + * @throws BuildException + */ + public function main() { + + $savedTransaction = array(); + for($i=0,$size=count($this->transactions); $i < $size; $i++) { + $savedTransaction[] = clone $this->transactions[$i]; + } + + $savedSqlCommand = $this->sqlCommand; + + $this->sqlCommand = trim($this->sqlCommand); + + try { + if ($this->srcFile === null && $this->sqlCommand === "" + && empty($this->filesets)) { + if (count($this->transactions) === 0) { + throw new BuildException("Source file or fileset, " + . "transactions or sql statement " + . "must be set!", $this->location); + } + } + + if ($this->srcFile !== null && !$this->srcFile->exists()) { + throw new BuildException("Source file does not exist!", $this->location); + } + + // deal with the filesets + for ($i = 0,$size=count($this->filesets); $i < $size; $i++) { + $fs = $this->filesets[$i]; + $ds = $fs->getDirectoryScanner($this->project); + $srcDir = $fs->getDir($this->project); + + $srcFiles = $ds->getIncludedFiles(); + + // Make a transaction for each file + for ($j=0, $size=count($srcFiles); $j < $size; $j++) { + $t = $this->createTransaction(); + $t->setSrc(new PhingFile($srcDir, $srcFiles[$j])); + } + } + + // Make a transaction group for the outer command + $t = $this->createTransaction(); + if ($this->srcFile) $t->setSrc($this->srcFile); + $t->addText($this->sqlCommand); + $this->conn = $this->getConnection(); + + try { + + $this->statement = $this->conn->createStatement(); + + $out = null; + + try { + + if ($this->output !== null) { + $this->log("Opening output file " . $this->output, PROJECT_MSG_VERBOSE); + $out = new BufferedWriter(new FileWriter($this->output->getAbsolutePath(), $this->append)); + } + + // Process all transactions + for ($i=0,$size=count($this->transactions); $i < $size; $i++) { + $this->transactions[$i]->runTransaction($out); + if (!$this->isAutocommit()) { + $this->log("Commiting transaction", PROJECT_MSG_VERBOSE); + $this->conn->commit(); + } + } + if ($out) $out->close(); + } catch (Exception $e) { + if ($out) $out->close(); + throw $e; + } + } catch (IOException $e) { + if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") { + try { + $this->conn->rollback(); + } catch (SQLException $ex) {} + } + throw new BuildException($e->getMessage(), $this->location); + } catch (SQLException $e){ + if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") { + try { + $this->conn->rollback(); + } catch (SQLException $ex) {} + } + throw new BuildException($e->getMessage(), $this->location); + } + + $this->log($this->goodSql . " of " . $this->totalSql . + " SQL statements executed successfully"); + } catch (Exception $e) { + $this->transactions = $savedTransaction; + $this->sqlCommand = $savedSqlCommand; + throw $e; + } + // finally { + $this->transactions = $savedTransaction; + $this->sqlCommand = $savedSqlCommand; + + } + + + /** + * read in lines and execute them + * @throws SQLException, IOException + */ + public function runStatements(Reader $reader, $out = null) { + $sql = ""; + $line = ""; + $in = new BufferedReader($reader); + try { + while (($line = $in->readLine()) !== null) { + $line = trim($line); + $line = ProjectConfigurator::replaceProperties($this->project, $line, + $this->project->getProperties()); + + if (StringHelper::startsWith("//", $line) || + StringHelper::startsWith("--", $line) || + StringHelper::startsWith("#", $line)) { + continue; + } + + if (strlen($line) > 4 + && strtoupper(substr($line,0, 4)) == "REM ") { + continue; + } + + $sql .= " " . $line; + $sql = trim($sql); + + // SQL defines "--" as a comment to EOL + // and in Oracle it may contain a hint + // so we cannot just remove it, instead we must end it + if (strpos($line, "--") !== false) { + $sql .= "\n"; + } + + if ($this->delimiterType == self::DELIM_NORMAL + && StringHelper::endsWith($this->delimiter, $sql) + || $this->delimiterType == self::DELIM_ROW + && $line == $this->delimiter) { + $this->log("SQL: " . $sql, PROJECT_MSG_VERBOSE); + $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter) - 1), $out); + $sql = ""; + } + } + + // Catch any statements not followed by ; + if ($sql !== "") { + $this->execSQL($sql, $out); + } + } catch (SQLException $e) { + throw new BuildException("Error running statements", $e); + } + } + + + /** + * Exec the sql statement. + * @throws SQLException + */ + protected function execSQL($sql, $out = null) { + // Check and ignore empty statements + if (trim($sql) == "") { + return; + } + + try { + $this->totalSql++; + if (!$this->statement->execute($sql)) { + $this->log($this->statement->getUpdateCount() . " rows affected", PROJECT_MSG_VERBOSE); + } else { + if ($this->print) { + $this->printResults($out); + } + } + + $this->goodSql++; + + } catch (SQLException $e) { + $this->log("Failed to execute: " . $sql, PROJECT_MSG_ERR); + if ($this->onError != "continue") { + throw new BuildException("Failed to execute SQL", $e); + } + $this->log($e->getMessage(), PROJECT_MSG_ERR); + } + } + + /** + * print any results in the statement. + * @throw SQLException + */ + protected function printResults($out = null) { + $lSep = Phing::getProperty('line.separator'); + $rs = null; + do { + $rs = $this->statement->getResultSet(); + + if ($rs !== null) { + + $this->log("Processing new result set.", PROJECT_MSG_VERBOSE); + + $line = ""; + + $colsprinted = false; + + while ($rs->next()) { + $fields = $rs->getRow(); + + if (!$colsprinted && $this->showheaders) { + $first = true; + foreach($fields as $fieldName => $ignore) { + if ($first) $first = false; else $line .= ","; + $line .= $fieldName; + } + if ($out !== null) { + $out->write($line); + $out->newLine(); + } else { + print($line.$lSep); + } + $line = ""; + $colsprinted = true; + } // if show headers + + $first = true; + foreach($fields as $columnValue) { + + if ($columnValue != null) { + $columnValue = trim($columnValue); + } + + if ($first) { + $first = false; + } else { + $line .= ","; + } + $line .= $columnValue; + } + + if ($out !== null) { + $out->write($line); + $out->newLine(); + } else { + print($line . $lSep); + } + $line = ""; + + } // while rs->next() + } + } while ($this->statement->getMoreResults()); + print($lSep); + if ($out !== null) $out->newLine(); + } +} + + +/** + * "Inner" class that contains the definition of a new transaction element. + * Transactions allow several files or blocks of statements + * to be executed using the same JDBC connection and commit + * operation in between. + */ +class SQLExecTransaction { + + private $tSrcFile = null; + private $tSqlCommand = ""; + private $parent; + + function __construct($parent) + { + // Parent is required so that we can log things ... + $this->parent = $parent; + } + + public function setSrc(PhingFile $src) + { + $this->tSrcFile = $src; + } + + public function addText($sql) + { + $this->tSqlCommand .= $sql; + } + + /** + * @throws IOException, SQLException + */ + public function runTransaction($out = null) + { + if (!empty($this->tSqlCommand)) { + $this->parent->log("Executing commands", PROJECT_MSG_INFO); + $this->parent->runStatements(new StringReader($this->tSqlCommand), $out); + } + + if ($this->tSrcFile !== null) { + $this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(), + PROJECT_MSG_INFO); + $reader = new FileReader($this->tSrcFile); + $this->parent->runStatements($reader, $out); + $reader->close(); + } + } +} + + diff --git a/gulliver/thirdparty/phing/tasks/ext/CreoleTask.php b/gulliver/thirdparty/phing/tasks/ext/CreoleTask.php new file mode 100644 index 000000000..122d7face --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/CreoleTask.php @@ -0,0 +1,242 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/types/Reference.php'; + +/** + * Handles Creole configuration needed by SQL type tasks. + * + * @author Hans Lellelid (Phing) + * @author Nick Chalko (Ant) + * @author Jeff Martin (Ant) + * @author Michael McCallum (Ant) + * @author Tim Stephenson (Ant) + * @version $Revision: 1.13 $ + * @package phing.tasks.system + */ +abstract class CreoleTask extends Task { + + /** + * Used for caching loaders / driver. This is to avoid + * getting an OutOfMemoryError when calling this task + * multiple times in a row. + * + * NOT IMPLEMENTED YET + */ + private static $loaderMap = array(); + + private $caching = true; + + /** + * Autocommit flag. Default value is false + */ + private $autocommit = false; + + /** + * [optional] Classpath to Creole driver to use. + * @param string + */ + private $driver; + + /** + * DB url. + */ + private $url; + + /** + * User name. + */ + private $userId; + + /** + * Password + */ + private $password; + + /** + * RDBMS Product needed for this SQL. + **/ + private $rdbms; + + /** + * Initialize CreoleTask. + * This method includes any necessary Creole libraries and triggers + * appropriate error if they cannot be found. This is not done in header + * because we may want this class to be loaded w/o triggering an error. + */ + function init() { + include_once 'creole/Creole.php'; + if (!class_exists('Creole')) { + throw new Exception("Creole task depends on Creole classes being on include_path. (i.e. include of 'creole/Creole.php' failed.)"); + } + } + + /** + * Caching loaders / driver. This is to avoid + * getting an OutOfMemoryError when calling this task + * multiple times in a row; default: true + * @param $enable + */ + public function setCaching($enable) { + $this->caching = $enable; + } + + /** + * Sets the database connection URL; required. + * @param url The url to set + */ + public function setUrl($url) { + $this->url = $url; + } + + /** + * Set the Creole driver to be used. + * + * @param string $driver driver class name + */ + public function setDriver($driver) + { + $this->driver = $driver; + } + + /** + * Sets the password; required. + * @param password The password to set + */ + public function setPassword($password) { + $this->password = $password; + } + + /** + * Auto commit flag for database connection; + * optional, default false. + * @param autocommit The autocommit to set + */ + public function setAutocommit($autocommit) { + $this->autocommit = $autocommit; + } + + /** + * Sets the version string, execute task only if + * rdbms version match; optional. + * @param version The version to set + */ + public function setVersion($version) { + $this->version = $version; + } + + protected function getLoaderMap() { + return self::$loaderMap; + } + + + /** + * Creates a new Connection as using the driver, url, userid and password specified. + * The calling method is responsible for closing the connection. + * @return Connection the newly created connection. + * @throws BuildException if the UserId/Password/Url is not set or there is no suitable driver or the driver fails to load. + */ + protected function getConnection() { + + if ($this->url === null) { + throw new BuildException("Url attribute must be set!", $this->location); + } + + try { + + $this->log("Connecting to " . $this->getUrl(), PROJECT_MSG_VERBOSE); + $info = new Properties(); + + $dsn = Creole::parseDSN($this->url); + + if (!isset($dsn["username"]) && $this->userId === null) { + throw new BuildException("Username must be in URL or userid attribute must be set.", $this->location); + } + + if ($this->userId) { + $dsn["username"] = $this->getUserId(); + } + + if ($this->password) { + $dsn["password"] = $this->getPassword(); + } + + if ($this->driver) { + Creole::registerDriver($dsn['phptype'], $this->driver); + } + + $conn = Creole::getConnection($dsn); + $conn->setAutoCommit($this->autocommit); + return $conn; + + } catch (SQLException $e) { + throw new BuildException($e->getMessage(), $this->location); + } + + } + + public function isCaching($value) { + $this->caching = $value; + } + + /** + * Gets the autocommit. + * @return Returns a boolean + */ + public function isAutocommit() { + return $this->autocommit; + } + + /** + * Gets the url. + * @return Returns a String + */ + public function getUrl() { + return $this->url; + } + + /** + * Gets the userId. + * @return Returns a String + */ + public function getUserId() { + return $this->userId; + } + + /** + * Set the user name for the connection; required. + * @param userId The userId to set + */ + public function setUserid($userId) { + $this->userId = $userId; + } + + /** + * Gets the password. + * @return Returns a String + */ + public function getPassword() { + return $this->password; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/ext/ExtractBaseTask.php b/gulliver/thirdparty/phing/tasks/ext/ExtractBaseTask.php new file mode 100644 index 000000000..556555eff --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/ExtractBaseTask.php @@ -0,0 +1,183 @@ +. + */ + +require_once 'phing/tasks/system/MatchingTask.php'; + +/** + * Base class for extracting tasks such as Unzip and Untar. + * + * @author Joakim Bodin + * @version $Revision: 1.0 $ + * @package phing.tasks.ext + * @since 2.2.0 + */ +abstract class ExtractBaseTask extends MatchingTask { + /** + * @var PhingFile $file + */ + protected $file; + /** + * @var PhingFile $todir + */ + protected $todir; + protected $removepath; + protected $filesets = array(); // all fileset objects assigned to this task + + /** + * Add a new fileset. + * @return FileSet + */ + public function createFileSet() { + $this->fileset = new FileSet(); + $this->filesets[] = $this->fileset; + return $this->fileset; + } + + /** + * Set the name of the zip file to extract. + * @param PhingFile $file zip file to extract + */ + public function setFile(PhingFile $file) { + $this->file = $file; + } + + /** + * This is the base directory to look in for things to zip. + * @param PhingFile $baseDir + */ + public function setToDir(PhingFile $todir) { + $this->todir = $todir; + } + + public function setRemovePath($removepath) + { + $this->removepath = $removepath; + } + + /** + * do the work + * @throws BuildException + */ + public function main() { + + $this->validateAttributes(); + + $filesToExtract = array(); + if ($this->file !== null) { + if(!$this->isDestinationUpToDate($this->file)) { + $filesToExtract[] = $this->file; + } else { + $this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' . $this->file->getCanonicalPath(), PROJECT_MSG_INFO); + } + } + + foreach($this->filesets as $compressedArchiveFileset) { + $compressedArchiveDirScanner = $compressedArchiveFileset->getDirectoryScanner($this->project); + $compressedArchiveFiles = $compressedArchiveDirScanner->getIncludedFiles(); + $compressedArchiveDir = $compressedArchiveFileset->getDir($this->project); + + foreach ($compressedArchiveFiles as $compressedArchiveFilePath) { + $compressedArchiveFile = new PhingFile($compressedArchiveDir, $compressedArchiveFilePath); + if($compressedArchiveFile->isDirectory()) + { + throw new BuildException($compressedArchiveFile->getAbsolutePath() . ' compressed archive cannot be a directory.'); + } + + if(!$this->isDestinationUpToDate($compressedArchiveFile)) { + $filesToExtract[] = $compressedArchiveFile; + } else { + $this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' . $compressedArchiveFile->getCanonicalPath(), PROJECT_MSG_INFO); + } + } + } + + foreach ($filesToExtract as $compressedArchiveFile) { + $this->extractArchive($compressedArchiveFile); + } + } + + abstract protected function extractArchive(PhingFile $compressedArchiveFile); + + /** + * @param array $files array of filenames + * @param PhingFile $dir + * @return boolean + */ + protected function isDestinationUpToDate(PhingFile $compressedArchiveFile) { + if (!$compressedArchiveFile->exists()) { + throw new BuildException("Could not find file " . $compressedArchiveFile->__toString() . " to extract."); + } + + $compressedArchiveContent = $this->listArchiveContent($compressedArchiveFile); + if(is_array($compressedArchiveContent)) { + + $fileSystem = FileSystem::getFileSystem(); + foreach ($compressedArchiveContent as $compressArchivePathInfo) { + $compressArchiveFilename = $compressArchivePathInfo['filename']; + if(!empty($this->removepath) && strlen($compressArchiveFilename) >= strlen($this->removepath)) + { + $compressArchiveFilename = preg_replace('/^' . $this->removepath . '/','', $compressArchiveFilename); + } + $compressArchivePath = new PhingFile($this->todir, $compressArchiveFilename); + + if(!$compressArchivePath->exists() || + $fileSystem->compareMTimes($compressedArchiveFile->getCanonicalPath(), $compressArchivePath->getCanonicalPath()) == 1) { + return false; + } + } + + } + + return true; + } + + abstract protected function listArchiveContent(PhingFile $compressedArchiveFile); + + /** + * Validates attributes coming in from XML + * + * @access private + * @return void + * @throws BuildException + */ + protected function validateAttributes() { + + if ($this->file === null && count($this->filesets) === 0) { + throw new BuildException("Specify at least one source compressed archive - a file or a fileset."); + } + + if ($this->todir === null) { + throw new BuildException("todir must be set."); + } + + if ($this->todir !== null && $this->todir->exists() && !$this->todir->isDirectory()) { + throw new BuildException("todir must be a directory."); + } + + if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) { + throw new BuildException("Compressed archive file cannot be a directory."); + } + + if ($this->file !== null && !$this->file->exists()) { + throw new BuildException("Could not find compressed archive file " . $this->file->__toString() . " to extract."); + } + } + +} \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/MailTask.php b/gulliver/thirdparty/phing/tasks/ext/MailTask.php new file mode 100644 index 000000000..c6434c3b8 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/MailTask.php @@ -0,0 +1,77 @@ +. + */ + +include_once 'phing/Task.php'; + +/** + * Send a message by mail() + * + * The build process is a success... + * + * @author Francois Harvey at SecuriWeb (http://www.securiweb.net) + * @version $Revision: 1.1 $ + * @package phing.tasks.ext + */ +class MailTask extends Task { + + protected $recipient; + + protected $subject; + + protected $msg; + + function main() { + $this->log('Sending mail to ' . $this->recipient ); + mail($this->recipient, $this->subject, $this->msg); + } + + /** setter for message */ + function setMsg($msg) { + $this->setMessage($msg); + } + + /** alias setter */ + function setMessage($msg) { + $this->msg = (string) $msg; + } + + /** setter for subject **/ + function setSubject($subject) { + $this->subject = (string) $subject; + } + + /** setter for recipient **/ + function setRecipient($recipient) { + $this->recipient = (string) $recipient; + } + + /** alias for recipient **/ + function setTo($recipient) { + $this->recipient = (string) $recipient; + } + + /** Supporting the Message syntax. */ + function addText($msg) + { + $this->msg = (string) $msg; + } +} + diff --git a/gulliver/thirdparty/phing/tasks/ext/PackageAsPathTask.php b/gulliver/thirdparty/phing/tasks/ext/PackageAsPathTask.php new file mode 100644 index 000000000..46f7b3605 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/PackageAsPathTask.php @@ -0,0 +1,65 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Convert dot-notation packages to relative paths. + * + * @author Hans Lellelid + * @version $Revision: 1.5 $ + * @package phing.tasks.ext + */ +class PackageAsPathTask extends Task { + + /** The package to convert. */ + protected $pckg; + + /** The value to store the conversion in. */ + protected $name; + + /** + * Executes the package to patch converstion and stores it + * in the user property value. + */ + public function main() + { + $this->project->setUserProperty($this->name, strtr($this->pckg, '.', '/')); + } + + /** + * @param string $pckg the package to convert + */ + public function setPackage($pckg) + { + $this->pckg = $pckg; + } + + /** + * @param string $name the Ant variable to store the path in + */ + public function setName($name) + { + $this->name = $name; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/ext/PearPackageTask.php b/gulliver/thirdparty/phing/tasks/ext/PearPackageTask.php new file mode 100644 index 000000000..9a6d0e691 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/PearPackageTask.php @@ -0,0 +1,421 @@ +. + */ + +require_once 'phing/tasks/system/MatchingTask.php'; +include_once 'phing/types/FileSet.php'; + +/** + * A task to create PEAR package.xml file. + * + * This class uses the PEAR_PackageFileMaintainer class to perform the work. + * + * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o + * requiring changes to this class. We've accomplished this by having generic
    - %s(line %d): %s + * oneline-comment - One-line comment ends with ?> tag. + * bool-assign - Assignment seen where boolean expression is expected. Did you mean '==' instead of '='? + * bool-print - Print statement used when boolean expression is expected. + * bool-array - Array used when boolean expression is expected. + * bool-object - Object used when boolean expression is expected. + * call-time-ref - Call-time reference is deprecated. Define function as accepting parameter by reference instead. + * if-if-else - In if-if-else construction else relates to the closest if. Use braces to make the code clearer. + * define-params - define() requires two or three parameters. + * define-const - First parameter for define() should be string. Maybe you forgot quotes? + * break-var - Break/continue with variable is dangerous - break level can be out of scope. + * break-depth - Break/continue with depth more than current nesting level. + * var-once - Variable '%s' encountered only once. May be a typo? + * var-arg-unused - Function argument '%s' is never used. + * var-global-unused - Global variable '%s' is defined but never used. + * var-use-before-def - Variable '%s' is used before it was assigned. + * var-use-before-def-global - Global variable '%s' is used without being assigned. You are probably relying on register_globals feature of PHP. Note that this feature is off by default. + * var-no-global - PHP global variable '%s' is used as local. Maybe you wanted to define '%s' as global? + * var-value-unused - Value assigned to variable '%s' is never used + * var-ref-notmodified - Function parameter '%s' is passed by reference but never modified. Consider passing by value. + * return-empty-val - Function '%s' has both empty return and return with value. + * return-empty-used - Function '%s' has empty return but return value is used. + * return-noref - Function '%s' returns reference but the value is not assigned by reference. Maybe you meant '=&' instead of '='? + * return-end-used - Control reaches the end of function '%s'(file %s, line %d) but return value is used. + * sprintf-miss-args - Missing arguments for sprintf: format reqires %d arguments but %d are supplied. + * sprintf-extra-args - Extra arguments for sprintf: format reqires %d arguments but %d are supplied. + * unreach-code - Unreachable code in function '%s'. + * include-var - include/require with user-accessible variable can be dangerous. Consider using constant instead. + * non-object - Variable '%s' used as object, but has different type. + * bad-escape - Bad escape sequence: \%c, did you mean \\%c? + * empty-cond - Condition without a body + * expr-unused - Expression result is never used + * + * @author Knut Urdalen + * @package phing.tasks.ext + */ +class ZendCodeAnalyzerTask extends Task { + + protected $analyzerPath = ""; // Path to ZendCodeAnalyzer binary + protected $file = ""; // the source file (from xml attribute) + protected $filesets = array(); // all fileset objects assigned to this task + protected $warnings = array(); + protected $counter = 0; + protected $disable = array(); + protected $enable = array(); + + /** + * File to be analyzed + * + * @param PhingFile $file + */ + public function setFile(PhingFile $file) { + $this->file = $file; + } + + /** + * Path to ZendCodeAnalyzer binary + * + * @param string $analyzerPath + */ + public function setAnalyzerPath($analyzerPath) { + $this->analyzerPath = $analyzerPath; + } + + /** + * Disable warning levels. Seperate warning levels with ',' + * + * @param string $disable + */ + public function setDisable($disable) { + $this->disable = explode(",", $disable); + } + + /** + * Enable warning levels. Seperate warning levels with ',' + * + * @param string $enable + */ + public function setEnable($enable) { + $this->enable = explode(",", $enable); + } + + /** + * Nested creator, creates a FileSet for this task + * + * @return FileSet The created fileset object + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Analyze against PhingFile or a FileSet + */ + public function main() { + if(!isset($this->analyzerPath)) { + throw new BuildException("Missing attribute 'analyzerPath'"); + } + if(!isset($this->file) and count($this->filesets) == 0) { + throw new BuildException("Missing either a nested fileset or attribute 'file' set"); + } + + if($this->file instanceof PhingFile) { + $this->analyze($this->file->getPath()); + } else { // process filesets + $project = $this->getProject(); + foreach($this->filesets as $fs) { + $ds = $fs->getDirectoryScanner($project); + $files = $ds->getIncludedFiles(); + $dir = $fs->getDir($this->project)->getPath(); + foreach($files as $file) { + $this->analyze($dir.DIRECTORY_SEPARATOR.$file); + } + } + } + $this->log("Number of findings: ".$this->counter, PROJECT_MSG_INFO); + } + + /** + * Analyze file + * + * @param string $file + * @return void + */ + protected function analyze($file) { + if(file_exists($file)) { + if(is_readable($file)) { + + // Construct shell command + $cmd = $this->analyzerPath." "; + foreach($this->enable as $enable) { // Enable warning levels + $cmd .= " --enable $enable "; + } + foreach($this->disable as $disable) { // Disable warning levels + $cmd .= " --disable $disable "; + } + $cmd .= "$file 2>&1"; + + // Execute command + $result = shell_exec($cmd); + $result = explode("\n", $result); + for($i=2, $size=count($result); $i<($size-1); $i++) { + $this->counter++; + $this->log($result[$i], PROJECT_MSG_WARN); + } + } else { + throw new BuildException('Permission denied: '.$file); + } + } else { + throw new BuildException('File not found: '.$file); + } + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/ZipTask.php b/gulliver/thirdparty/phing/tasks/ext/ZipTask.php new file mode 100644 index 000000000..4a6797aa7 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/ZipTask.php @@ -0,0 +1,176 @@ +. + */ + +require_once 'phing/tasks/system/MatchingTask.php'; +include_once 'phing/util/SourceFileScanner.php'; +include_once 'phing/mappers/MergeMapper.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/lib/Zip.php'; + +/** + * Creates a zip archive using PEAR Archive_Zip (which is presently unreleased + * and included with Phing). + * + * @author Michiel Rook + * @version $Revision: 1.2 $ + * @package phing.tasks.ext + * @since 2.1.0 + */ +class ZipTask extends MatchingTask { + + private $zipFile; + private $baseDir; + + private $filesets = array(); + private $fileSetFiles = array(); + + /** + * Add a new fileset. + * @return FileSet + */ + public function createFileSet() { + $this->fileset = new FileSet(); + $this->filesets[] = $this->fileset; + return $this->fileset; + } + + /** + * Set is the name/location of where to create the zip file. + * @param PhingFile $destFile The output of the zip + */ + public function setDestFile(PhingFile $destFile) { + $this->zipFile = $destFile; + } + + /** + * This is the base directory to look in for things to zip. + * @param PhingFile $baseDir + */ + public function setBasedir(PhingFile $baseDir) { + $this->baseDir = $baseDir; + } + + /** + * do the work + * @throws BuildException + */ + public function main() { + + if ($this->zipFile === null) { + throw new BuildException("zipfile attribute must be set!", $this->getLocation()); + } + + if ($this->zipFile->exists() && $this->zipFile->isDirectory()) { + throw new BuildException("zipfile is a directory!", $this->getLocation()); + } + + if ($this->zipFile->exists() && !$this->zipFile->canWrite()) { + throw new BuildException("Can not write to the specified zipfile!", $this->getLocation()); + } + + // shouldn't need to clone, since the entries in filesets + // themselves won't be modified -- only elements will be added + $savedFileSets = $this->filesets; + + try { + if ($this->baseDir !== null) { + if (!$this->baseDir->exists()) { + throw new BuildException("basedir does not exist!", $this->getLocation()); + } + + // add the main fileset to the list of filesets to process. + $mainFileSet = new FileSet($this->fileset); + $mainFileSet->setDir($this->baseDir); + $this->filesets[] = $mainFileSet; + } + + if (empty($this->filesets)) { + throw new BuildException("You must supply either a basedir " + . "attribute or some nested filesets.", + $this->getLocation()); + } + + // check if zip is out of date with respect to each + // fileset + $upToDate = true; + foreach($this->filesets as $fs) { + $ds = $fs->getDirectoryScanner($this->project); + $files = $ds->getIncludedFiles(); + if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) { + $upToDate = false; + } + for ($i=0, $fcount=count($files); $i < $fcount; $i++) { + if ($this->zipFile->equals(new PhingFile($fs->getDir($this->project), $files[$i]))) { + throw new BuildException("A zip file cannot include itself", $this->getLocation()); + } + } + } + + if ($upToDate) { + $this->log("Nothing to do: " . $this->zipFile->__toString() . " is up to date.", PROJECT_MSG_INFO); + return; + } + + $this->log("Building zip: " . $this->zipFile->__toString(), PROJECT_MSG_INFO); + + $zip = new Archive_Zip($this->zipFile->getAbsolutePath()); + + foreach($this->filesets as $fs) { + $ds = $fs->getDirectoryScanner($this->project); + $files = $ds->getIncludedFiles(); + + // FIXME + // Current model is only adding directories implicitly. This + // won't add any empty directories. Perhaps modify FileSet::getFiles() + // to also include empty directories. Not high priority, since non-inclusion + // of empty dirs is probably not unexpected behavior for ZipTask. + $fsBasedir = $fs->getDir($this->project); + $filesToZip = array(); + for ($i=0, $fcount=count($files); $i < $fcount; $i++) { + $f = new PhingFile($fsBasedir, $files[$i]); + $filesToZip[] = $f->getAbsolutePath(); + } + $zip->add($filesToZip, array('remove_path' => $fsBasedir->getCanonicalPath())); + } + + + } catch (IOException $ioe) { + $msg = "Problem creating ZIP: " . $ioe->getMessage(); + $this->filesets = $savedFileSets; + throw new BuildException($msg, $ioe, $this->getLocation()); + } + + $this->filesets = $savedFileSets; + } + + /** + * @param array $files array of filenames + * @param PhingFile $dir + * @return boolean + */ + protected function archiveIsUpToDate($files, $dir) { + $sfs = new SourceFileScanner($this); + $mm = new MergeMapper(); + $mm->setTo($this->zipFile->getAbsolutePath()); + return count($sfs->restrict($files, $dir, null, $mm)) == 0; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMerger.php b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMerger.php new file mode 100644 index 000000000..d71d8fef6 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMerger.php @@ -0,0 +1,127 @@ +. + */ + +require_once 'phing/system/util/Properties.php'; + +/** + * Saves coverage output of the test to a specified database + * + * @author Michiel Rook + * @version $Id: CoverageMerger.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.coverage + * @since 2.1.0 + */ +class CoverageMerger +{ + private static function mergeCodeCoverage($left, $right) + { + $coverageMerged = array(); + + reset($left); + reset($right); + + while (current($left) && current($right)) + { + $linenr_left = key($left); + $linenr_right = key($right); + + if ($linenr_left < $linenr_right) + { + $coverageMerged[$linenr_left] = current($left); + + next($left); + } + else + if ($linenr_right < $linenr_left) + { + $coverageMerged[$linenr_right] = current($right); + next($right); + } + else + { + if (current($left) < 0) + { + $coverageMerged[$linenr_right] = current($right); + } + else + if (current($right) < 0) + { + $coverageMerged[$linenr_right] = current($left); + } + else + { + $coverageMerged[$linenr_right] = current($left) + current($right); + } + + next($left); + next($right); + } + } + + while (current($left)) + { + $coverageMerged[key($left)] = current($left); + next($left); + } + + while (current($right)) + { + $coverageMerged[key($right)] = current($right); + next($right); + } + + return $coverageMerged; + } + + static function merge($project, $codeCoverageInformation) + { + $database = new PhingFile($project->getProperty('coverage.database')); + + $props = new Properties(); + $props->load($database); + + $coverageTotal = $codeCoverageInformation; + + foreach ($coverageTotal as $coverage) + { + foreach ($coverage as $filename => $coverageFile) + { + $filename = strtolower($filename); + + if ($props->getProperty($filename) != null) + { + $file = unserialize($props->getProperty($filename)); + $left = $file['coverage']; + $right = $coverageFile; + + $coverageMerged = CoverageMerger::mergeCodeCoverage($left, $right); + + $file['coverage'] = $coverageMerged; + + $props->setProperty($filename, serialize($file)); + } + } + } + + $props->store($database); + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMergerTask.php b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMergerTask.php new file mode 100644 index 000000000..214b6b858 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageMergerTask.php @@ -0,0 +1,92 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/Writer.php'; +require_once 'phing/system/util/Properties.php'; +require_once 'phing/tasks/ext/coverage/CoverageMerger.php'; + +/** + * Merges code coverage snippets into a code coverage database + * + * @author Michiel Rook + * @version $Id: CoverageMergerTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.coverage + * @since 2.1.0 + */ +class CoverageMergerTask extends Task +{ + /** the list of filesets containing the .php filename rules */ + private $filesets = array(); + + /** + * Add a new fileset containing the .php files to process + * + * @param FileSet the new fileset containing .php files + */ + function addFileSet(FileSet $fileset) + { + $this->filesets[] = $fileset; + } + + /** + * Iterate over all filesets and return all the filenames. + * + * @return array an array of filenames + */ + private function getFilenames() + { + $files = array(); + + foreach ($this->filesets as $fileset) + { + $ds = $fileset->getDirectoryScanner($this->project); + $ds->scan(); + + $includedFiles = $ds->getIncludedFiles(); + + foreach ($includedFiles as $file) + { + $fs = new PhingFile(basename($ds->getBaseDir()), $file); + + $files[] = $fs->getAbsolutePath(); + } + } + + return $files; + } + + function main() + { + $files = $this->getFilenames(); + + $this->log("Merging " . count($files) . " coverage files"); + + foreach ($files as $file) + { + $coverageInformation = unserialize(file_get_contents($file)); + + CoverageMerger::merge($this->project, array($coverageInformation)); + } + } +} +?> diff --git a/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTask.php b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTask.php new file mode 100644 index 000000000..aa0312eae --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTask.php @@ -0,0 +1,407 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/Writer.php'; +require_once 'phing/system/util/Properties.php'; +require_once 'phing/tasks/ext/phpunit2/PHPUnit2Util.php'; +require_once 'phing/tasks/ext/coverage/CoverageReportTransformer.php'; + +/** + * Transforms information in a code coverage database to XML + * + * @author Michiel Rook + * @version $Id: CoverageReportTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.coverage + * @since 2.1.0 + */ +class CoverageReportTask extends Task +{ + private $outfile = "coverage.xml"; + + private $transformers = array(); + + /** the classpath to use (optional) */ + private $classpath = NULL; + + /** the path to the GeSHi library (optional) */ + private $geshipath = ""; + + /** the path to the GeSHi language files (optional) */ + private $geshilanguagespath = ""; + + function setClasspath(Path $classpath) + { + if ($this->classpath === null) + { + $this->classpath = $classpath; + } + else + { + $this->classpath->append($classpath); + } + } + + function createClasspath() + { + $this->classpath = new Path(); + return $this->classpath; + } + + function setGeshiPath($path) + { + $this->geshipath = $path; + } + + function setGeshiLanguagesPath($path) + { + $this->geshilanguagespath = $path; + } + + function __construct() + { + $this->doc = new DOMDocument(); + $this->doc->encoding = 'UTF-8'; + $this->doc->formatOutput = true; + $this->doc->appendChild($this->doc->createElement('snapshot')); + } + + function setOutfile($outfile) + { + $this->outfile = $outfile; + } + + /** + * Generate a report based on the XML created by this task + */ + function createReport() + { + $transformer = new CoverageReportTransformer($this); + $this->transformers[] = $transformer; + return $transformer; + } + + protected function getPackageElement($packageName) + { + $packages = $this->doc->documentElement->getElementsByTagName('package'); + + foreach ($packages as $package) + { + if ($package->getAttribute('name') == $packageName) + { + return $package; + } + } + + return NULL; + } + + protected function addClassToPackage($classname, $element) + { + $packageName = PHPUnit2Util::getPackageName($classname); + + $package = $this->getPackageElement($packageName); + + if ($package === NULL) + { + $package = $this->doc->createElement('package'); + $package->setAttribute('name', $packageName); + $this->doc->documentElement->appendChild($package); + } + + $package->appendChild($element); + } + + protected function stripDiv($source) + { + $openpos = strpos($source, "", $openpos); + + $line = substr($source, $closepos + 1); + + $tagclosepos = strpos($line, ""); + + $line = substr($line, 0, $tagclosepos); + + return $line; + } + + protected function highlightSourceFile($filename) + { + if ($this->geshipath) + { + require_once $this->geshipath . '/geshi.php'; + + $source = file_get_contents($filename); + + $geshi = new GeSHi($source, 'php', $this->geshilanguagespath); + + $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS); + + $geshi->enable_strict_mode(true); + + $geshi->enable_classes(true); + + $geshi->set_url_for_keyword_group(3, ''); + + $html = $geshi->parse_code(); + + $lines = split("
  • |
  • ", $html); + + // skip first and last line + array_pop($lines); + array_shift($lines); + + $lines = array_filter($lines); + + $lines = array_map(array($this, 'stripDiv'), $lines); + + return $lines; + } + else + { + $lines = file($filename); + + for ($i = 0; $i < count($lines); $i++) + { + $line = $lines[$i]; + + $line = rtrim($line); + + $lines[$i] = utf8_encode($line); + } + + return $lines; + } + } + + protected function transformSourceFile($filename, $coverageInformation, $classStartLine = 1) + { + $sourceElement = $this->doc->createElement('sourcefile'); + $sourceElement->setAttribute('name', basename($filename)); + + $filelines = $this->highlightSourceFile($filename); + + $linenr = 1; + + foreach ($filelines as $line) + { + $lineElement = $this->doc->createElement('sourceline'); + $lineElement->setAttribute('coveredcount', (isset($coverageInformation[$linenr]) ? $coverageInformation[$linenr] : '0')); + + if ($linenr == $classStartLine) + { + $lineElement->setAttribute('startclass', 1); + } + + $textnode = $this->doc->createTextNode($line); + $lineElement->appendChild($textnode); + + $sourceElement->appendChild($lineElement); + + $linenr++; + } + + return $sourceElement; + } + + protected function filterCovered($var) + { + return ($var >= 0); + } + + protected function transformCoverageInformation($filename, $coverageInformation) + { + // Strip last line of coverage information + end($coverageInformation); + unset($coverageInformation[key($coverageInformation)]); + + $classes = PHPUnit2Util::getDefinedClasses($filename, $this->classpath); + + if (is_array($classes)) + { + foreach ($classes as $classname) + { + $reflection = new ReflectionClass($classname); + + $methods = $reflection->getMethods(); + + $classElement = $this->doc->createElement('class'); + $classElement->setAttribute('name', $reflection->getName()); + + $this->addClassToPackage($reflection->getName(), $classElement); + + $classStartLine = $reflection->getStartLine(); + + $methodscovered = 0; + $methodcount = 0; + + // Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off + if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0) + { + unset($coverageInformation[$classStartLine + 1]); + } + else + { + unset($coverageInformation[$classStartLine]); + } + + reset($coverageInformation); + + foreach ($methods as $method) + { + // PHP5 reflection considers methods of a parent class to be part of a subclass, we don't + if ($method->getDeclaringClass()->getName() != $reflection->getName()) + { + continue; + } + + // small fix for XDEBUG_CC_UNUSED + if (isset($coverageInformation[$method->getStartLine()])) + { + unset($coverageInformation[$method->getStartLine()]); + } + + if (isset($coverageInformation[$method->getEndLine()])) + { + unset($coverageInformation[$method->getEndLine()]); + } + + if ($method->isAbstract()) + { + continue; + } + + $linenr = key($coverageInformation); + + while ($linenr !== null && $linenr < $method->getStartLine()) + { + next($coverageInformation); + $linenr = key($coverageInformation); + } + + if (current($coverageInformation) > 0 && $method->getStartLine() <= $linenr && $linenr <= $method->getEndLine()) + { + $methodscovered++; + } + + $methodcount++; + } + + $statementcount = count($coverageInformation); + $statementscovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); + + $classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine)); + + $classElement->setAttribute('methodcount', $methodcount); + $classElement->setAttribute('methodscovered', $methodscovered); + $classElement->setAttribute('statementcount', $statementcount); + $classElement->setAttribute('statementscovered', $statementscovered); + $classElement->setAttribute('totalcount', $methodcount + $statementcount); + $classElement->setAttribute('totalcovered', $methodscovered + $statementscovered); + } + } + } + + protected function calculateStatistics() + { + $packages = $this->doc->documentElement->getElementsByTagName('package'); + + $totalmethodcount = 0; + $totalmethodscovered = 0; + + $totalstatementcount = 0; + $totalstatementscovered = 0; + + foreach ($packages as $package) + { + $methodcount = 0; + $methodscovered = 0; + + $statementcount = 0; + $statementscovered = 0; + + $classes = $package->getElementsByTagName('class'); + + foreach ($classes as $class) + { + $methodcount += $class->getAttribute('methodcount'); + $methodscovered += $class->getAttribute('methodscovered'); + + $statementcount += $class->getAttribute('statementcount'); + $statementscovered += $class->getAttribute('statementscovered'); + } + + $package->setAttribute('methodcount', $methodcount); + $package->setAttribute('methodscovered', $methodscovered); + + $package->setAttribute('statementcount', $statementcount); + $package->setAttribute('statementscovered', $statementscovered); + + $package->setAttribute('totalcount', $methodcount + $statementcount); + $package->setAttribute('totalcovered', $methodscovered + $statementscovered); + + $totalmethodcount += $methodcount; + $totalmethodscovered += $methodscovered; + + $totalstatementcount += $statementcount; + $totalstatementscovered += $statementscovered; + } + + $this->doc->documentElement->setAttribute('methodcount', $totalmethodcount); + $this->doc->documentElement->setAttribute('methodscovered', $totalmethodscovered); + + $this->doc->documentElement->setAttribute('statementcount', $totalstatementcount); + $this->doc->documentElement->setAttribute('statementscovered', $totalstatementscovered); + + $this->doc->documentElement->setAttribute('totalcount', $totalmethodcount + $totalstatementcount); + $this->doc->documentElement->setAttribute('totalcovered', $totalmethodscovered + $totalstatementscovered); + } + + function main() + { + $this->log("Transforming coverage report"); + + $database = new PhingFile($this->project->getProperty('coverage.database')); + + $props = new Properties(); + $props->load($database); + + foreach ($props->keys() as $filename) + { + $file = unserialize($props->getProperty($filename)); + + $this->transformCoverageInformation($file['fullname'], $file['coverage']); + } + + $this->calculateStatistics(); + + $this->doc->save($this->outfile); + + foreach ($this->transformers as $transformer) + { + $transformer->setXmlDocument($this->doc); + $transformer->transform(); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTransformer.php b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTransformer.php new file mode 100644 index 000000000..81939d661 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageReportTransformer.php @@ -0,0 +1,121 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/FileWriter.php'; +require_once 'phing/util/ExtendedFileStream.php'; + +/** + * Transform a Phing/Xdebug code coverage xml report. + * The default transformation generates an html report in framed style. + * + * @author Michiel Rook + * @version $Id: CoverageReportTransformer.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.coverage + * @since 2.1.0 + */ +class CoverageReportTransformer +{ + private $task = NULL; + private $styleDir = ""; + private $toDir = ""; + private $document = NULL; + + function __construct(Task $task) + { + $this->task = $task; + } + + function setStyleDir($styleDir) + { + $this->styleDir = $styleDir; + } + + function setToDir($toDir) + { + $this->toDir = $toDir; + } + + function setXmlDocument($document) + { + $this->document = $document; + } + + function transform() + { + $dir = new PhingFile($this->toDir); + + if (!$dir->exists()) + { + throw new BuildException("Directory '" . $this->toDir . "' does not exist"); + } + + $xslfile = $this->getStyleSheet(); + + $xsl = new DOMDocument(); + $xsl->load($xslfile->getAbsolutePath()); + + $proc = new XSLTProcessor(); + $proc->importStyleSheet($xsl); + + ExtendedFileStream::registerStream(); + + // no output for the framed report + // it's all done by extension... + $proc->setParameter('', 'output.dir', $dir->getAbsolutePath()); + $proc->transformToXML($this->document); + } + + private function getStyleSheet() + { + $xslname = "coverage-frames.xsl"; + + if ($this->styleDir) + { + $file = new PhingFile($this->styleDir, $xslname); + } + else + { + $path = Phing::getResourcePath("phing/etc/$xslname"); + + if ($path === NULL) + { + $path = Phing::getResourcePath("etc/$xslname"); + + if ($path === NULL) + { + throw new BuildException("Could not find $xslname in resource path"); + } + } + + $file = new PhingFile($path); + } + + if (!$file->exists()) + { + throw new BuildException("Could not find file " . $file->getPath()); + } + + return $file; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageSetupTask.php b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageSetupTask.php new file mode 100644 index 000000000..36f097a92 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/coverage/CoverageSetupTask.php @@ -0,0 +1,163 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/Writer.php'; +require_once 'phing/system/util/Properties.php'; +require_once 'phing/tasks/ext/coverage/CoverageMerger.php'; + +/** + * Initializes a code coverage database + * + * @author Michiel Rook + * @version $Id: CoverageSetupTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.coverage + * @since 2.1.0 + */ +class CoverageSetupTask extends Task +{ + /** the list of filesets containing the .php filename rules */ + private $filesets = array(); + + /** the filename of the coverage database */ + private $database = "coverage.db"; + + /** the classpath to use (optional) */ + private $classpath = NULL; + + /** + * Add a new fileset containing the .php files to process + * + * @param FileSet the new fileset containing .php files + */ + function addFileSet(FileSet $fileset) + { + $this->filesets[] = $fileset; + } + + /** + * Sets the filename of the coverage database to use + * + * @param string the filename of the database + */ + function setDatabase($database) + { + $this->database = $database; + } + + function setClasspath(Path $classpath) + { + if ($this->classpath === null) + { + $this->classpath = $classpath; + } + else + { + $this->classpath->append($classpath); + } + } + + function createClasspath() + { + $this->classpath = new Path(); + return $this->classpath; + } + + /** + * Iterate over all filesets and return the filename of all files + * that end with .php. This is to avoid loading an xml file + * for example. + * + * @return array an array of (basedir, filenames) pairs + */ + private function getFilenames() + { + $files = array(); + + foreach ($this->filesets as $fileset) + { + $ds = $fileset->getDirectoryScanner($this->project); + $ds->scan(); + + $includedFiles = $ds->getIncludedFiles(); + + foreach ($includedFiles as $file) + { + if (strstr($file, ".php")) + { + $fs = new PhingFile(realpath($ds->getBaseDir()), $file); + + $files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath()); + } + } + } + + return $files; + } + + function init() + { + include_once 'PHPUnit2/Framework/TestCase.php'; + if (!class_exists('PHPUnit2_Framework_TestCase')) { + throw new Exception("PHPUnit2Task depends on PEAR PHPUnit2 package being installed."); + } + } + + function main() + { + $files = $this->getFilenames(); + + $this->log("Setting up coverage database for " . count($files) . " files"); + + $props = new Properties(); + + foreach ($files as $file) + { + $fullname = $file['fullname']; + $filename = $file['key']; + + $props->setProperty($filename, serialize(array('fullname' => $fullname, 'coverage' => array()))); + } + + $dbfile = new PhingFile($this->database); + + $props->store($dbfile); + + $this->project->setProperty('coverage.database', $dbfile->getAbsolutePath()); + + foreach ($files as $file) + { + $fullname = $file['fullname']; + + xdebug_start_code_coverage(XDEBUG_CC_UNUSED); + + Phing::__import($fullname, $this->classpath); + + $coverage = xdebug_get_code_coverage(); + + xdebug_stop_code_coverage(); + + CoverageMerger::merge($this->project, array($coverage)); + } + } +} +?> diff --git a/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeComment.php b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeComment.php new file mode 100644 index 000000000..48bc5b56f --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeComment.php @@ -0,0 +1,44 @@ +. + */ + +/** + * Wrapper for comments for ionCube tasks + * + * @author Michiel Rook + * @version $Id: IoncubeComment.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.ioncube + * @since 2.2.0 + */ +class IoncubeComment +{ + private $value = ""; + + public function getValue() + { + return $this->value; + } + + public function addText($txt) + { + $this->value = trim($txt); + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeEncoderTask.php b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeEncoderTask.php new file mode 100644 index 000000000..c79d1a611 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeEncoderTask.php @@ -0,0 +1,336 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/tasks/ext/ioncube/IoncubeComment.php'; + +/** + * Invokes the ionCube Encoder (PHP4 or PHP5) + * + * @author Michiel Rook + * @version $Id: IoncubeEncoderTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.ioncube + * @since 2.2.0 + */ +class IoncubeEncoderTask extends Task +{ + private $phpVersion = "5"; + private $ioncubePath = "/usr/local/ioncube"; + private $encoderName = "ioncube_encoder"; + + private $fromDir = ""; + private $toDir = ""; + + private $encrypt = ""; + + private $targetOption = ""; + private $binary = false; + private $optimize = ""; + private $withoutRuntimeLoaderSupport = false; + + private $licensePath = ""; + private $passPhrase = ""; + + private $comments = array(); + + /** + * Sets the path to the ionCube encoder + */ + function setIoncubePath($ioncubePath) + { + $this->ioncubePath = $ioncubePath; + } + + /** + * Returns the path to the ionCube encoder + */ + function getIoncubePath() + { + return $this->ioncubePath; + } + + /** + * Sets the version of PHP to use (defaults to 5) + */ + function setPhpVersion($phpVersion) + { + $this->phpVersion = $phpVersion; + } + + /** + * Returns the version of PHP to use (defaults to 5) + */ + function getPhpVersion() + { + return $this->phpVersion; + } + + /** + * Sets the source directory + */ + function setFromDir($fromDir) + { + $this->fromDir = $fromDir; + } + + /** + * Returns the source directory + */ + function getFromDir($fromDir) + { + return $this->fromDir; + } + + /** + * Sets the target directory + */ + function setToDir($toDir) + { + $this->toDir = $toDir; + } + + /** + * Returns the target directory + */ + function getToDir($toDir) + { + return $this->toDir; + } + + /** + * Sets regexps of additional files to encrypt (separated by space) + */ + function setEncrypt($encrypt) + { + $this->encrypt = $encrypt; + } + + /** + * Returns regexps of additional files to encrypt (separated by space) + */ + function getEncrypt() + { + return $this->encrypt; + } + + /** + * Sets the binary option + */ + function setBinary($binary) + { + $this->binary = $binary; + } + + /** + * Returns the binary option + */ + function getBinary() + { + return $this->binary; + } + + /** + * Sets the optimize option + */ + function setOptimize($optimize) + { + $this->optimize = $optimize; + } + + /** + * Returns the optimize option + */ + function getOptimize() + { + return $this->optimize; + } + + /** + * Sets the without-runtime-loader-support option + */ + function setWithoutRuntimeLoaderSupport($withoutRuntimeLoaderSupport) + { + $this->withoutRuntimeLoaderSupport = $withoutRuntimeLoaderSupport; + } + + /** + * Returns the without-runtime-loader-support option + */ + function getWithoutRuntimeLoaderSupport() + { + return $this->withoutRuntimeLoaderSupport; + } + + /** + * Sets the option to use when encoding target directory already exists (defaults to none) + */ + function setTargetOption($targetOption) + { + $this->targetOption = $targetOption; + } + + /** + * Returns he option to use when encoding target directory already exists (defaults to none) + */ + function getTargetOption() + { + return $this->targetOption; + } + + /** + * Sets the path to the license file to use + */ + function setLicensePath($licensePath) + { + $this->licensePath = $licensePath; + } + + /** + * Returns the path to the license file to use + */ + function getLicensePath() + { + return $this->licensePath; + } + + /** + * Sets the passphrase to use when encoding files + */ + function setPassPhrase($passPhrase) + { + $this->passPhrase = $passPhrase; + } + + /** + * Returns the passphrase to use when encoding files + */ + function getPassPhrase() + { + return $this->passPhrase; + } + + /** + * Adds a comment to be used in encoded files + */ + function addComment(IoncubeComment $comment) + { + $this->comments[] = $comment; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $arguments = $this->constructArguments(); + + $encoder = new PhingFile($this->ioncubePath, $this->encoderName . ($this->phpVersion == 5 ? '5' : '')); + + $this->log("Running ionCube Encoder..."); + + exec($encoder->__toString() . " " . $arguments . " 2>&1", $output, $return); + + if ($return != 0) + { + throw new BuildException("Could not execute ionCube Encoder: " . implode(' ', $output)); + } + } + + /** + * Constructs an argument string for the ionCube encoder + */ + private function constructArguments() + { + $arguments = ""; + + if ($this->binary) + { + $arguments.= "--binary "; + } + + if (!empty($this->optimize)) + { + $arguments.= "--optimize " . $this->optimize . " "; + } + + if ($this->withoutRuntimeLoaderSupport) + { + $arguments.= "--without-runtime-loader-support "; + } + + if (!empty($this->targetOption)) + { + switch ($this->targetOption) + { + case "replace": + case "merge": + case "update": + case "rename": + { + $arguments.= "--" . $this->targetOption . "-target "; + } break; + + default: + { + throw new BuildException("Unknown target option '" . $this->targetOption . "'"); + } break; + } + } + + if (!empty($this->encrypt)) + { + foreach (explode(" ", $this->encrypt) as $encrypt) + { + $arguments.= "--encrypt '$encrypt' "; + } + } + + if (!empty($this->licensePath)) + { + $arguments.= "--with-license '" . $this->licensePath . "' "; + } + + if (!empty($this->passPhrase)) + { + $arguments.= "--passphrase '" . $this->passPhrase . "' "; + } + + foreach ($this->comments as $comment) + { + $arguments.= "--add-comment '" . $comment->getValue() . "' "; + } + + if ($this->fromDir != "") + { + $arguments .= $this->fromDir . " "; + } + + if ($this->toDir != "") + { + $arguments .= "-o " . $this->toDir . " "; + } + + return $arguments; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeLicenseTask.php b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeLicenseTask.php new file mode 100644 index 000000000..feccbd299 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/ioncube/IoncubeLicenseTask.php @@ -0,0 +1,144 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/tasks/ext/ioncube/IoncubeComment.php'; + +/** + * Invokes the ionCube "make_license" program + * + * @author Michiel Rook + * @version $Id: IoncubeLicenseTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.ioncube + * @since 2.2.0 + */ +class IoncubeLicenseTask extends Task +{ + private $ioncubePath = "/usr/local/ioncube"; + + private $licensePath = ""; + private $passPhrase = ""; + + private $comments = array(); + + /** + * Sets the path to the ionCube encoder + */ + function setIoncubePath($ioncubePath) + { + $this->ioncubePath = $ioncubePath; + } + + /** + * Returns the path to the ionCube encoder + */ + function getIoncubePath() + { + return $this->ioncubePath; + } + + /** + * Sets the path to the license file to use + */ + function setLicensePath($licensePath) + { + $this->licensePath = $licensePath; + } + + /** + * Returns the path to the license file to use + */ + function getLicensePath() + { + return $this->licensePath; + } + + /** + * Sets the passphrase to use when encoding files + */ + function setPassPhrase($passPhrase) + { + $this->passPhrase = $passPhrase; + } + + /** + * Returns the passphrase to use when encoding files + */ + function getPassPhrase() + { + return $this->passPhrase; + } + + /** + * Adds a comment to be used in encoded files + */ + function addComment(IoncubeComment $comment) + { + $this->comments[] = $comment; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $arguments = $this->constructArguments(); + + $makelicense = new PhingFile($this->ioncubePath, 'make_license'); + + $this->log("Running ionCube make_license..."); + + exec($makelicense->__toString() . " " . $arguments . " 2>&1", $output, $return); + + if ($return != 0) + { + throw new BuildException("Could not execute ionCube make_license: " . implode(' ', $output)); + } + } + + /** + * Constructs an argument string for the ionCube make_license + */ + private function constructArguments() + { + $arguments = ""; + + if (!empty($this->passPhrase)) + { + $arguments.= "--passphrase '" . $this->passPhrase . "' "; + } + + foreach ($this->comments as $comment) + { + $arguments.= "--header-line '" . $comment->getValue() . "' "; + } + + if (!empty($this->licensePath)) + { + $arguments.= "--o '" . $this->licensePath . "' "; + } + + return $arguments; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/pearpackage/Fileset.php b/gulliver/thirdparty/phing/tasks/ext/pearpackage/Fileset.php new file mode 100644 index 000000000..51556d789 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/pearpackage/Fileset.php @@ -0,0 +1,231 @@ +. + */ + +include_once 'phing/system/io/PhingFile.php'; + +/** + * Builds list of files for PEAR_PackageFileManager using a Phing FileSet. + * + * Some code here is taken from PEAR_PackageFileManager_File -- getting results from flat + * array into the assoc array expected from getFileList(). + * + * @author Greg Beaver + * @author Hans Lellelid + * @package phing.tasks.ext.pearpackage + * @version $Revision: 1.7 $ + */ +class PEAR_PackageFileManager_Fileset { + + /** + * @access private + * @var PEAR_PackageFileManager + */ + private $parent; + + /** + * Curent Phing Project. + * @var Project + */ + private $project; + + /** + * FileSets to use. + * @var array FileSet[] + */ + private $filesets = array(); + + /** + * Set up the FileSet filelist generator + * + * 'project' and 'filesets' are the only options that this class uses. + * + * @param PEAR_PackageFileManager + * @param array + */ + function __construct($parent, $options) + { + $this->parent = $parent; + $this->project = $options['phing_project']; + $this->filesets = $options['phing_filesets']; + } + + /** + * Generate the section + * of the package file. + * + * This function performs the backend generation of the array + * containing all files in this package + * @return array structure of all files to include + */ + function getFileList() { + + $allfiles = array(); + + foreach($this->filesets as $fs) { + $ds = $fs->getDirectoryScanner($this->project); + + $files = $ds->getIncludedFiles(); + + // We need to store these files keyed by the basedir from DirectoryScanner + // so that we can resolve the fullpath of the file later. + if (isset($allfiles[$ds->getBasedir()])) + { + $allfiles[$ds->getBasedir()] = array_merge($allfiles[$ds->getBasedir()], $files); + } + else + { + $allfiles[$ds->getBasedir()] = $files; + } + } + + $struc = array(); + + foreach($allfiles as $basedir => $files) { + + foreach($files as $file) { + + // paths are relative to $basedir above + $path = strtr(dirname($file), DIRECTORY_SEPARATOR, '/'); + + if (!$path || $path == '.') { + $path = '/'; // for array index + } + + $parts = explode('.', basename($file)); + $ext = array_pop($parts); + if (strlen($ext) == strlen($file)) { + $ext = ''; + } + + $f = new PhingFile($basedir, $file); + + $struc[$path][] = array('file' => basename($file), + 'ext' => $ext, + 'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)), + 'fullpath' => $f->getAbsolutePath()); + } + } + + uksort($struc,'strnatcasecmp'); + foreach($struc as $key => $ind) { + usort($ind, array($this, 'sortfiles')); + $struc[$key] = $ind; + } + + $tempstruc = $struc; + $struc = array('/' => $tempstruc['/']); + $bv = 0; + foreach($tempstruc as $key => $ind) { + $save = $key; + if ($key != '/') { + $struc['/'] = $this->setupDirs($struc['/'], explode('/', $key), $tempstruc[$key]); + } + } + uksort($struc['/'], array($this, 'mystrucsort')); + + return $struc; + } + + /** + * Recursively move contents of $struc into associative array + * + * The contents of $struc have many indexes like 'dir/subdir/subdir2'. + * This function converts them to + * array('dir' => array('subdir' => array('subdir2'))) + * @param array struc is array('dir' => array of files in dir, + * 'dir/subdir' => array of files in dir/subdir,...) + * @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2') + * @return array same as struc but with array('dir' => + * array(file1,file2,'subdir' => array(file1,...))) + */ + private function setupDirs($struc, $dir, $contents) { + + if (!count($dir)) { + foreach($contents as $dir => $files) { + if (is_string($dir)) { + if (strpos($dir, '/')) { + $test = true; + $a = $contents[$dir]; + unset($contents[$dir]); + $b = explode('/', $dir); + $c = array_shift($b); + if (isset($contents[$c])) { + $contents[$c] = $this->setDir($contents[$c], $this->setupDirs(array(), $b, $a)); + } else { + $contents[$c] = $this->setupDirs(array(), $b, $a); + } + } + } + } + return $contents; + } + $me = array_shift($dir); + if (!isset($struc[$me])) { + $struc[$me] = array(); + } + $struc[$me] = $this->setupDirs($struc[$me], $dir, $contents); + return $struc; + } + + /** + * Recursively add all the subdirectories of $contents to $dir without erasing anything in + * $dir + * @param array + * @param array + * @return array processed $dir + */ + function setDir($dir, $contents) + { + while(list($one,$two) = each($contents)) { + if (isset($dir[$one])) { + $dir[$one] = $this->setDir($dir[$one], $contents[$one]); + } else { + $dir[$one] = $two; + } + } + return $dir; + } + + /** + * Sorting functions for the file list + * @param string + * @param string + * @access private + */ + function sortfiles($a, $b) + { + return strnatcasecmp($a['file'],$b['file']); + } + + function mystrucsort($a, $b) + { + if (is_numeric($a) && is_string($b)) return 1; + if (is_numeric($b) && is_string($a)) return -1; + if (is_numeric($a) && is_numeric($b)) + { + if ($a > $b) return 1; + if ($a < $b) return -1; + if ($a == $b) return 0; + } + return strnatcasecmp($a,$b); + } +} +?> diff --git a/gulliver/thirdparty/phing/tasks/ext/phpdoc/PHPDocumentorTask.php b/gulliver/thirdparty/phing/tasks/ext/phpdoc/PHPDocumentorTask.php new file mode 100644 index 000000000..508a05d2d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpdoc/PHPDocumentorTask.php @@ -0,0 +1,191 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Task to run phpDocumentor. + * + * @author Michiel Rook + * @version $Id: PHPDocumentorTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpdoc + */ +class PHPDocumentorTask extends Task +{ + /** + * The path to the executable for phpDocumentor + */ + private $programPath = 'phpdoc'; + + private $title = "Default Title"; + + private $destdir = "."; + + private $sourcepath = NULL; + + private $output = ""; + + private $linksource = false; + + private $parseprivate = false; + + /** + * Sets the path to the phpDocumentor executable + */ + function setProgramPath($programPath) + { + $this->programPath = $programPath; + } + + /** + * Returns the path to the phpDocumentor executable + */ + function getProgramPath() + { + return $this->programPath; + } + + /** + * Set the title for the generated documentation + */ + function setTitle($title) + { + $this->title = $title; + } + + /** + * Set the destination directory for the generated documentation + */ + function setDestdir($destdir) + { + $this->destdir = $destdir; + } + + /** + * Set the source path + */ + function setSourcepath(Path $sourcepath) + { + if ($this->sourcepath === NULL) + { + $this->sourcepath = $sourcepath; + } + else + { + $this->sourcepath->append($sourcepath); + } + } + + /** + * Set the output type + */ + function setOutput($output) + { + $this->output = $output; + } + + /** + * Should sources be linked in the generated documentation + */ + function setLinksource($linksource) + { + $this->linksource = $linksource; + } + + /** + * Should private members/classes be documented + */ + function setParseprivate($parseprivate) + { + $this->parseprivate = $parseprivate; + } + + /** + * Main entrypoint of the task + */ + function main() + { + $arguments = $this->constructArguments(); + + $this->log("Running phpDocumentor..."); + + exec($this->programPath . " " . $arguments, $output, $return); + + if ($return != 0) + { + throw new BuildException("Could not execute phpDocumentor: " . implode(' ', $output)); + } + + foreach($output as $line) + { + if(strpos($line, 'ERROR') !== false) + { + $this->log($line, PROJECT_MSG_ERR); + continue; + } + + $this->log($line, PROJECT_MSG_VERBOSE); + } + } + + /** + * Constructs an argument string for phpDocumentor + */ + private function constructArguments() + { + $arguments = "-q on "; + + if ($this->title) + { + $arguments.= "-ti \"" . $this->title . "\" "; + } + + if ($this->destdir) + { + $arguments.= "-t \"" . $this->destdir . "\" "; + } + + if ($this->sourcepath !== NULL) + { + $arguments.= "-d \"" . $this->sourcepath->__toString() . "\" "; + } + + if ($this->output) + { + $arguments.= "-o " . $this->output . " "; + } + + if ($this->linksource) + { + $arguments.= "-s on "; + } + + if ($this->parseprivate) + { + $arguments.= "-pp on "; + } + + return $arguments; + } +}; + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/BatchTest.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/BatchTest.php new file mode 100644 index 000000000..af53e157b --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/BatchTest.php @@ -0,0 +1,171 @@ +. + */ + +require_once 'phing/types/FileSet.php'; + +/** + * Scans a list of (.php) files given by the fileset attribute, extracts + * all subclasses of PHPUnit2_Framework_TestCase. + * + * @author Michiel Rook + * @version $Id: BatchTest.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class BatchTest +{ + /** the list of filesets containing the testcase filename rules */ + private $filesets = array(); + + /** the reference to the project */ + private $project = NULL; + + /** the classpath to use with Phing::__import() calls */ + private $classpath = NULL; + + /** names of classes to exclude */ + private $excludeClasses = array(); + + /** + * Create a new batchtest instance + * + * @param Project the project it depends on. + */ + function __construct(Project $project) + { + $this->project = $project; + } + + /** + * Sets the classes to exclude + */ + function setExclude($exclude) + { + $this->excludeClasses = explode(" ", $exclude); + } + + /** + * Sets the classpath + */ + function setClasspath(Path $classpath) + { + if ($this->classpath === null) + { + $this->classpath = $classpath; + } + else + { + $this->classpath->append($classpath); + } + } + + /** + * Creates a new Path object + */ + function createClasspath() + { + $this->classpath = new Path(); + return $this->classpath; + } + + /** + * Returns the classpath + */ + function getClasspath() + { + return $this->classpath; + } + + /** + * Add a new fileset containing the XML results to aggregate + * + * @param FileSet the new fileset containing XML results. + */ + function addFileSet(FileSet $fileset) + { + $this->filesets[] = $fileset; + } + + /** + * Iterate over all filesets and return the filename of all files + * that end with .php. + * + * @return array an array of filenames + */ + private function getFilenames() + { + $filenames = array(); + + foreach ($this->filesets as $fileset) + { + $ds = $fileset->getDirectoryScanner($this->project); + $ds->scan(); + + $files = $ds->getIncludedFiles(); + + foreach ($files as $file) + { + if (strstr($file, ".php")) + { + $filenames[] = $ds->getBaseDir() . "/" . $file; + } + } + } + + return $filenames; + } + + /** + * Filters an array of classes, removes all classes that are not subclasses of PHPUnit2_Framework_TestCase, + * or classes that are declared abstract + */ + private function filterTests($input) + { + $reflect = new ReflectionClass($input); + + return is_subclass_of($input, 'PHPUnit2_Framework_TestCase') && (!$reflect->isAbstract()); + } + + /** + * Returns an array of PHPUnit2_Framework_TestCase classes that are declared + * by the files included by the filesets + * + * @return array an array of PHPUnit2_Framework_TestCase classes. + */ + function elements() + { + $filenames = $this->getFilenames(); + + $declaredClasses = array(); + + foreach ($filenames as $filename) + { + $definedClasses = PHPUnit2Util::getDefinedClasses($filename, $this->classpath); + + $declaredClasses = array_merge($declaredClasses, $definedClasses); + } + + $elements = array_filter($declaredClasses, array($this, "filterTests")); + + return $elements; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/FormatterElement.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/FormatterElement.php new file mode 100644 index 000000000..35c257f71 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/FormatterElement.php @@ -0,0 +1,120 @@ +. + */ + +require_once 'phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php'; +require_once 'phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php'; +require_once 'phing/system/io/PhingFile.php'; + +/** + * A wrapper for the implementations of PHPUnit2ResultFormatter. + * + * @author Michiel Rook + * @version $Id: FormatterElement.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class FormatterElement +{ + protected $formatter = NULL; + + protected $type = ""; + + protected $useFile = true; + + protected $toDir = "."; + + protected $outfile = ""; + + function setType($type) + { + $this->type = $type; + + if ($this->type == "xml") + { + $destFile = new PhingFile($this->toDir, 'testsuites.xml'); + $this->formatter = new XMLPHPUnit2ResultFormatter(); + } + else + if ($this->type == "plain") + { + $this->formatter = new PlainPHPUnit2ResultFormatter(); + } + else + { + throw new BuildException("Formatter '" . $this->type . "' not implemented"); + } + } + + function setClassName($className) + { + $classNameNoDot = Phing::import($className); + + $this->formatter = new $classNameNoDot(); + } + + function setUseFile($useFile) + { + $this->useFile = $useFile; + } + + function getUseFile() + { + return $this->useFile; + } + + function setToDir($toDir) + { + $this->toDir = $toDir; + } + + function getToDir() + { + return $this->toDir; + } + + function setOutfile($outfile) + { + $this->outfile = $outfile; + } + + function getOutfile() + { + if ($this->outfile) + { + return $this->outfile; + } + else + { + return $this->formatter->getPreferredOutfile() . $this->getExtension(); + } + } + + function getExtension() + { + return $this->formatter->getExtension(); + } + + function getFormatter() + { + return $this->formatter; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php new file mode 100644 index 000000000..33b2804bd --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ReportTask.php @@ -0,0 +1,187 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/FileWriter.php'; +require_once 'phing/util/ExtendedFileStream.php'; + +/** + * Transform a PHPUnit2 xml report using XSLT. + * This transformation generates an html report in either framed or non-framed + * style. The non-framed style is convenient to have a concise report via mail, + * the framed report is much more convenient if you want to browse into + * different packages or testcases since it is a Javadoc like report. + * + * @author Michiel Rook + * @version $Id: PHPUnit2ReportTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class PHPUnit2ReportTask extends Task +{ + private $format = "noframes"; + private $styleDir = ""; + private $toDir = ""; + + /** the directory where the results XML can be found */ + private $inFile = "testsuites.xml"; + + /** + * Set the filename of the XML results file to use. + */ + function setInFile($inFile) + { + $this->inFile = $inFile; + } + + /** + * Set the format of the generated report. Must be noframes or frames. + */ + function setFormat($format) + { + $this->format = $format; + } + + /** + * Set the directory where the stylesheets are located. + */ + function setStyleDir($styleDir) + { + $this->styleDir = $styleDir; + } + + /** + * Set the directory where the files resulting from the + * transformation should be written to. + */ + function setToDir($toDir) + { + $this->toDir = $toDir; + } + + /** + * Returns the path to the XSL stylesheet + */ + private function getStyleSheet() + { + $xslname = "phpunit2-" . $this->format . ".xsl"; + + if ($this->styleDir) + { + $file = new PhingFile($this->styleDir, $xslname); + } + else + { + $path = Phing::getResourcePath("phing/etc/$xslname"); + + if ($path === NULL) + { + $path = Phing::getResourcePath("etc/$xslname"); + + if ($path === NULL) + { + throw new BuildException("Could not find $xslname in resource path"); + } + } + + $file = new PhingFile($path); + } + + if (!$file->exists()) + { + throw new BuildException("Could not find file " . $file->getPath()); + } + + return $file; + } + + /** + * Transforms the DOM document + */ + private function transform(DOMDocument $document) + { + $dir = new PhingFile($this->toDir); + + if (!$dir->exists()) + { + throw new BuildException("Directory '" . $this->toDir . "' does not exist"); + } + + $xslfile = $this->getStyleSheet(); + + $xsl = new DOMDocument(); + $xsl->load($xslfile->getAbsolutePath()); + + $proc = new XSLTProcessor(); + $proc->importStyleSheet($xsl); + + if ($this->format == "noframes") + { + $writer = new FileWriter(new PhingFile($this->toDir, "phpunit2-noframes.html")); + $writer->write($proc->transformToXML($document)); + $writer->close(); + } + else + { + ExtendedFileStream::registerStream(); + + // no output for the framed report + // it's all done by extension... + $dir = new PhingFile($this->toDir); + $proc->setParameter('', 'output.dir', $dir->getAbsolutePath()); + $proc->transformToXML($document); + } + } + + /** + * Fixes 'testsuite' elements with no package attribute, adds + * package="default" to those elements. + */ + private function fixPackages(DOMDocument $document) + { + $testsuites = $document->getElementsByTagName('testsuite'); + + foreach ($testsuites as $testsuite) + { + if (!$testsuite->hasAttribute('package')) + { + $testsuite->setAttribute('package', 'default'); + } + } + } + + /** + * The main entry point + * + * @throws BuildException + */ + public function main() + { + $testSuitesDoc = new DOMDocument(); + $testSuitesDoc->load($this->inFile); + + $this->fixPackages($testSuitesDoc); + + $this->transform($testSuitesDoc); + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php new file mode 100644 index 000000000..2b60a40b3 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php @@ -0,0 +1,158 @@ +. + */ + +require_once 'PHPUnit2/Framework/TestListener.php'; + +require_once 'phing/system/io/Writer.php'; + +/** + * This abstract class describes classes that format the results of a PHPUnit2 testrun. + * + * @author Michiel Rook + * @version $Id: PHPUnit2ResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +abstract class PHPUnit2ResultFormatter implements PHPUnit2_Framework_TestListener +{ + protected $out = NULL; + + protected $project = NULL; + + private $timer = NULL; + + private $runCount = 0; + + private $failureCount = 0; + + private $errorCount = 0; + + /** + * Sets the writer the formatter is supposed to write its results to. + */ + function setOutput(Writer $out) + { + $this->out = $out; + } + + /** + * Returns the extension used for this formatter + * + * @return string the extension + */ + function getExtension() + { + return ""; + } + + /** + * Sets the project + * + * @param Project the project + */ + function setProject(Project $project) + { + $this->project = $project; + } + + function getPreferredOutfile() + { + return ""; + } + + function startTestRun() + { + } + + function endTestRun() + { + } + + function startTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + $this->runCount = 0; + $this->failureCount = 0; + $this->errorCount = 0; + + $this->timer = new Timer(); + $this->timer->start(); + } + + function endTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + $this->timer->stop(); + } + + function startTest(PHPUnit2_Framework_Test $test) + { + $this->runCount++; + } + + function endTest(PHPUnit2_Framework_Test $test) + { + } + + function addError(PHPUnit2_Framework_Test $test, Exception $e) + { + $this->errorCount++; + } + + function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t) + { + $this->failureCount++; + } + + function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e) + { + } + + function addSkippedTest(PHPUnit2_Framework_Test $test, Exception $e) + { + } + + function getRunCount() + { + return $this->runCount; + } + + function getFailureCount() + { + return $this->failureCount; + } + + function getErrorCount() + { + return $this->errorCount; + } + + function getElapsedTime() + { + if ($this->timer) + { + return $this->timer->getElapsedTime(); + } + else + { + return 0; + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Task.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Task.php new file mode 100644 index 000000000..3c093f049 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Task.php @@ -0,0 +1,239 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/Writer.php'; +require_once 'phing/util/LogWriter.php'; + +/** + * Runs PHPUnit2 tests. + * + * @author Michiel Rook + * @version $Id: PHPUnit2Task.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @see BatchTest + * @since 2.1.0 + */ +class PHPUnit2Task extends Task +{ + private $batchtests = array(); + private $formatters = array(); + private $haltonerror = false; + private $haltonfailure = false; + private $failureproperty; + private $errorproperty; + private $printsummary = false; + private $testfailed = false; + private $codecoverage = false; + + /** + * Initialize Task. + * This method includes any necessary PHPUnit2 libraries and triggers + * appropriate error if they cannot be found. This is not done in header + * because we may want this class to be loaded w/o triggering an error. + */ + function init() { + include_once 'PHPUnit2/Util/Filter.php'; + if (!class_exists('PHPUnit2_Util_Filter')) { + throw new BuildException("PHPUnit2Task depends on PEAR PHPUnit2 package being installed.", $this->getLocation()); + } + + if (version_compare(PHP_VERSION, '5.0.3') < 0) { + throw new BuildException("PHPUnit2Task requires PHP version >= 5.0.3.", $this->getLocation()); + } + + // other dependencies that should only be loaded when class is actually used. + require_once 'phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php'; + require_once 'phing/tasks/ext/phpunit2/BatchTest.php'; + require_once 'phing/tasks/ext/phpunit2/FormatterElement.php'; + require_once 'phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php'; + + // add some defaults to the PHPUnit2 Filter + PHPUnit2_Util_Filter::addFileToFilter('PHPUnit2Task.php'); + PHPUnit2_Util_Filter::addFileToFilter('PHPUnit2TestRunner.php'); + PHPUnit2_Util_Filter::addFileToFilter('phing/Task.php'); + PHPUnit2_Util_Filter::addFileToFilter('phing/Target.php'); + PHPUnit2_Util_Filter::addFileToFilter('phing/Project.php'); + PHPUnit2_Util_Filter::addFileToFilter('phing/Phing.php'); + PHPUnit2_Util_Filter::addFileToFilter('phing.php'); + + } + + function setFailureproperty($value) + { + $this->failureproperty = $value; + } + + function setErrorproperty($value) + { + $this->errorproperty = $value; + } + + function setHaltonerror($value) + { + $this->haltonerror = $value; + } + + function setHaltonfailure($value) + { + $this->haltonfailure = $value; + } + + function setPrintsummary($printsummary) + { + $this->printsummary = $printsummary; + } + + function setCodecoverage($codecoverage) + { + $this->codecoverage = $codecoverage; + } + + /** + * Add a new formatter to all tests of this task. + * + * @param FormatterElement formatter element + */ + function addFormatter(FormatterElement $fe) + { + $this->formatters[] = $fe; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $tests = array(); + + if ($this->printsummary) + { + $fe = new FormatterElement(); + $fe->setClassName('SummaryPHPUnit2ResultFormatter'); + $fe->setUseFile(false); + $this->formatters[] = $fe; + } + + foreach ($this->batchtests as $batchtest) + { + $tests = array_merge($tests, $batchtest->elements()); + } + + foreach ($this->formatters as $fe) + { + $formatter = $fe->getFormatter(); + $formatter->setProject($this->getProject()); + + if ($fe->getUseFile()) + { + $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile()); + + $writer = new FileWriter($destFile->getAbsolutePath()); + + $formatter->setOutput($writer); + } + else + { + $formatter->setOutput($this->getDefaultOutput()); + } + + $formatter->startTestRun(); + } + + foreach ($tests as $test) + { + $this->execute(new PHPUnit2_Framework_TestSuite(new ReflectionClass($test))); + } + + foreach ($this->formatters as $fe) + { + $formatter = $fe->getFormatter(); + $formatter->endTestRun(); + } + + if ($this->testfailed) + { + throw new BuildException("One or more tests failed"); + } + } + + /** + * @throws BuildException + */ + private function execute($suite) + { + $runner = new PHPUnit2TestRunner($suite, $this->project); + + $runner->setCodecoverage($this->codecoverage); + + foreach ($this->formatters as $fe) + { + $formatter = $fe->getFormatter(); + + $runner->addFormatter($formatter); + } + + $runner->run(); + + $retcode = $runner->getRetCode(); + + if ($retcode == PHPUnit2TestRunner::ERRORS) { + if ($this->errorproperty) { + $this->project->setNewProperty($this->errorproperty, true); + } + if ($this->haltonerror) { + $this->testfailed = true; + } + } elseif ($retcode == PHPUnit2TestRunner::FAILURES) { + if ($this->failureproperty) { + $this->project->setNewProperty($this->failureproperty, true); + } + + if ($this->haltonfailure) { + $this->testfailed = true; + } + } + + } + + private function getDefaultOutput() + { + return new LogWriter($this); + } + + /** + * Adds a set of tests based on pattern matching. + * + * @return BatchTest a new instance of a batch test. + */ + function createBatchTest() + { + $batchtest = new BatchTest($this->getProject()); + + $this->batchtests[] = $batchtest; + + return $batchtest; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php new file mode 100644 index 000000000..213dee435 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2TestRunner.php @@ -0,0 +1,107 @@ +. + */ + +require_once 'PHPUnit2/Framework/TestListener.php'; +require_once 'PHPUnit2/Framework/TestResult.php'; +require_once 'PHPUnit2/Framework/TestSuite.php'; + +require_once 'phing/tasks/ext/coverage/CoverageMerger.php'; + +require_once 'phing/system/util/Timer.php'; + +/** + * Simple Testrunner for PHPUnit2 that runs all tests of a testsuite. + * + * @author Michiel Rook + * @version $Id: PHPUnit2TestRunner.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class PHPUnit2TestRunner +{ + const SUCCESS = 0; + const FAILURES = 1; + const ERRORS = 2; + + private $test = NULL; + private $suite = NULL; + private $retCode = 0; + private $formatters = array(); + + private $codecoverage = false; + + private $project = NULL; + + function __construct(PHPUnit2_Framework_TestSuite $suite, Project $project) + { + $this->suite = $suite; + $this->project = $project; + $this->retCode = self::SUCCESS; + } + + function setCodecoverage($codecoverage) + { + $this->codecoverage = $codecoverage; + } + + function addFormatter(PHPUnit2_Framework_TestListener $formatter) + { + $this->formatters[] = $formatter; + } + + function run() + { + $res = new PHPUnit2_Framework_TestResult(); + + if ($this->codecoverage) + { + $res->collectCodeCoverageInformation(TRUE); + } + + foreach ($this->formatters as $formatter) + { + $res->addListener($formatter); + } + + $this->suite->run($res); + + if ($this->codecoverage) + { + CoverageMerger::merge($this->project, $res->getCodeCoverageInformation()); + } + + if ($res->errorCount() != 0) + { + $this->retCode = self::ERRORS; + } + + else if ($res->failureCount() != 0 || $res->notImplementedCount() != 0) + { + $this->retCode = self::FAILURES; + } + } + + function getRetCode() + { + return $this->retCode; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Util.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Util.php new file mode 100644 index 000000000..2198560ba --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PHPUnit2Util.php @@ -0,0 +1,121 @@ +. + */ + +/** + * Various utility functions + * + * @author Michiel Rook + * @version $Id: PHPUnit2Util.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class PHPUnit2Util +{ + protected static $definedClasses = array(); + + /** + * Returns the package of a class as defined in the docblock of the class using @package + * + * @param string the name of the class + * @return string the name of the package + */ + static function getPackageName($classname) + { + $reflect = new ReflectionClass($classname); + + if (preg_match('/@package[\s]+([\.\w]+)/', $reflect->getDocComment(), $matches)) + { + return $matches[1]; + } + else + { + return "default"; + } + } + + /** + * Derives the classname from a filename. + * Assumes that there is only one class defined in that particular file, and that + * the naming follows the dot-path (Java) notation scheme. + * + * @param string the filename + * @return string the name fo the class + */ + static function getClassFromFileName($filename) + { + $filename = basename($filename); + + $rpos = strrpos($filename, '.'); + + if ($rpos != -1) + { + $filename = substr($filename, 0, $rpos); + } + + return $filename; + } + + /** + * @param string the filename + * @param Path optional classpath + * @return array list of classes defined in the file + */ + static function getDefinedClasses($filename, $classpath = NULL) + { + $filename = realpath($filename); + + if (!file_exists($filename)) + { + throw new Exception("File '" . $filename . "' does not exist"); + } + + if (isset(self::$definedClasses[$filename])) + { + return self::$definedClasses[$filename]; + } + + Phing::__import($filename, $classpath); + + $declaredClasses = get_declared_classes(); + + foreach ($declaredClasses as $classname) + { + $reflect = new ReflectionClass($classname); + + self::$definedClasses[$reflect->getFilename()][] = $classname; + + if (is_array(self::$definedClasses[$reflect->getFilename()])) + { + self::$definedClasses[$reflect->getFilename()] = array_unique(self::$definedClasses[$reflect->getFilename()]); + } + } + + if (isset(self::$definedClasses[$filename])) + { + return self::$definedClasses[$filename]; + } + else + { + return array(); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php new file mode 100644 index 000000000..67542188d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/PlainPHPUnit2ResultFormatter.php @@ -0,0 +1,117 @@ +. + */ + +require_once 'PHPUnit2/Framework/Test.php'; +require_once 'PHPUnit2/Util/Filter.php'; + +require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php'; + +/** + * Prints plain text output of the test to a specified Writer. + * + * @author Michiel Rook + * @version $Id: PlainPHPUnit2ResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class PlainPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter +{ + private $inner = ""; + + function getExtension() + { + return ".txt"; + } + + function getPreferredOutfile() + { + return "testresults"; + } + + function startTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + parent::startTestSuite($suite); + + $this->inner = ""; + } + + function endTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + parent::endTestSuite($suite); + + $sb = "Testsuite: " . $suite->getName() . "\n"; + $sb.= "Tests run: " . $this->getRunCount(); + $sb.= ", Failures: " . $this->getFailureCount(); + $sb.= ", Errors: " . $this->getErrorCount(); + $sb.= ", Time elapsed: " . $this->getElapsedTime(); + $sb.= " sec\n"; + + if ($this->out != NULL) + { + $this->out->write($sb); + $this->out->write($this->inner); + } + } + + function addError(PHPUnit2_Framework_Test $test, Exception $e) + { + parent::addError($test, $e); + + $this->formatError("ERROR", $test, $e); + } + + function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t) + { + parent::addFailure($test, $t); + + $this->formatError("FAILED", $test, $t); + } + + function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e) + { + parent::addIncompleteTest($test, $e); + + $this->formatError("INCOMPLETE", $test, $e); + } + + private function formatError($type, PHPUnit2_Framework_Test $test, Exception $e) + { + if ($test != null) + { + $this->endTest($test); + } + + $this->inner.= $test->getName() . " " . $type . "\n"; + $this->inner.= $e->getMessage() . "\n"; + $this->inner.= PHPUnit2_Util_Filter::getFilteredStackTrace($e) . "\n"; + } + + function endTestRun() + { + parent::endTestRun(); + + if ($this->out != NULL) + { + $this->out->close(); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php new file mode 100644 index 000000000..dbed3458e --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/SummaryPHPUnit2ResultFormatter.php @@ -0,0 +1,58 @@ +. + */ + +require_once 'PHPUnit2/Framework/Test.php'; + +require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php'; + +/** + * Prints short summary output of the test to Phing's logging system. + * + * @author Michiel Rook + * @version $Id: SummaryPHPUnit2ResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class SummaryPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter +{ + function endTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + parent::endTestSuite($suite); + + $sb = "Tests run: " . $this->getRunCount(); + $sb.= ", Failures: " . $this->getFailureCount(); + $sb.= ", Errors: " . $this->getErrorCount(); + $sb.= ", Time elapsed: " . $this->getElapsedTime(); + $sb.= " sec\n"; + + if ($this->out != NULL) + { + $this->out->write($sb); + $this->out->close(); + } + } + + function getExtension() + { + return NULL; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php new file mode 100644 index 000000000..d117b7340 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/phpunit2/XMLPHPUnit2ResultFormatter.php @@ -0,0 +1,117 @@ +. + */ + +require_once 'PHPUnit2/Framework/Test.php'; +require_once 'PHPUnit2/Runner/Version.php'; + +require_once 'PHPUnit2/Util/Log/XML.php'; + +require_once 'phing/tasks/ext/phpunit2/PHPUnit2ResultFormatter.php'; + +/** + * Prints XML output of the test to a specified Writer + * + * @author Michiel Rook + * @version $Id: XMLPHPUnit2ResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.1.0 + */ +class XMLPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter +{ + private $logger = NULL; + + function __construct() + { + $this->logger = new PHPUnit2_Util_Log_XML(); + $this->logger->setWriteDocument(false); + } + + function getExtension() + { + return ".xml"; + } + + function getPreferredOutfile() + { + return "testsuites"; + } + + function startTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + parent::startTestSuite($suite); + + $this->logger->startTestSuite($suite); + } + + function endTestSuite(PHPUnit2_Framework_TestSuite $suite) + { + parent::endTestSuite($suite); + + $this->logger->endTestSuite($suite); + } + + function startTest(PHPUnit2_Framework_Test $test) + { + parent::startTest($test); + + $this->logger->startTest($test); + } + + function endTest(PHPUnit2_Framework_Test $test) + { + parent::endTest($test); + + $this->logger->endTest($test); + } + + function addError(PHPUnit2_Framework_Test $test, Exception $e) + { + parent::addError($test, $e); + + $this->logger->addError($test, $e); + } + + function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t) + { + parent::addFailure($test, $t); + + $this->logger->addFailure($test, $t); + } + + function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e) + { + parent::addIncompleteTest($test, $e); + + $this->logger->addIncompleteTest($test, $e); + } + + function endTestRun() + { + parent::endTestRun(); + + if ($this->out) + { + $this->out->write($this->logger->getXML()); + $this->out->close(); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php new file mode 100644 index 000000000..897807160 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php @@ -0,0 +1,52 @@ +. + */ + +require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php'; + +/** + * Dummy result formatter used to count SimpleTest results + * + * @author Michiel Rook + * @version $Id: SimpleTestCountResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.simpletest + * @since 2.2.0 + */ +class SimpleTestCountResultFormatter extends SimpleTestResultFormatter +{ + const SUCCESS = 0; + const FAILURES = 1; + const ERRORS = 2; + + function getRetCode() + { + if ($this->getExceptionCount() != 0) + { + return self::ERRORS; + } + else if ($this->getFailCount() != 0) + { + return self::FAILURES; + } + + return self::SUCCESS; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php new file mode 100644 index 000000000..617afa04f --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php @@ -0,0 +1,62 @@ +. + */ + +require_once 'phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php'; +require_once 'phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php'; +require_once 'phing/tasks/ext/phpunit2/FormatterElement.php'; + +/** + * Child class of "FormatterElement", overrides setType to provide other + * formatter classes for SimpleTest + * + * @author Michiel Rook + * @version $Id: SimpleTestFormatterElement.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.simpletest + * @since 2.2.0 + */ +class SimpleTestFormatterElement extends FormatterElement +{ + function setType($type) + { + $this->type = $type; + + if ($this->type == "xml") + { + $destFile = new PhingFile($this->toDir, 'testsuites.xml'); + //$this->formatter = new SimpleTestXmlResultFormatter(); + } + else + if ($this->type == "plain") + { + $this->formatter = new SimpleTestPlainResultFormatter(); + } + else + if ($this->type == "summary") + { + $this->formatter = new SimpleTestSummaryResultFormatter(); + } + else + { + throw new BuildException("Formatter '" . $this->type . "' not implemented"); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php new file mode 100644 index 000000000..81ae7585a --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php @@ -0,0 +1,95 @@ +. + */ + +require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php'; + +/** + * Prints plain text output of the test to a specified Writer. + * + * @author Michiel Rook + * @version $Id: SimpleTestPlainResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.simpletest + * @since 2.2.0 + */ +class SimpleTestPlainResultFormatter extends SimpleTestResultFormatter +{ + private $inner = ""; + + function getExtension() + { + return ".txt"; + } + + function getPreferredOutfile() + { + return "testresults"; + } + + function paintCaseStart($test_name) + { + parent::paintCaseStart($test_name); + + $this->inner = ""; + } + + function paintCaseEnd($test_name) + { + parent::paintCaseEnd($test_name); + + /* Only count suites where more than one test was run */ + if ($this->getRunCount()) + { + $sb.= "Testsuite: $test_name\n"; + $sb.= "Tests run: " . $this->getRunCount(); + $sb.= ", Failures: " . $this->getFailureCount(); + $sb.= ", Errors: " . $this->getErrorCount(); + $sb.= ", Time elapsed: " . $this->getElapsedTime(); + $sb.= " sec\n"; + + if ($this->out != NULL) + { + $this->out->write($sb); + $this->out->write($this->inner); + } + } + } + + function paintError($message) + { + parent::paintError($message); + + $this->formatError("ERROR", $message); + } + + function paintFail($message) + { + parent::paintFail($message); + + $this->formatError("FAILED", $message); + } + + private function formatError($type, $message) + { + $this->inner.= $this->getTestName() . " " . $type . "\n"; + $this->inner.= $message . "\n"; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php new file mode 100644 index 000000000..d979095b7 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php @@ -0,0 +1,162 @@ +. + */ + +require_once 'simpletest/scorer.php'; + +require_once 'phing/system/io/Writer.php'; + +/** + * This abstract class describes classes that format the results of a SimpleTest testrun. + * + * @author Michiel Rook + * @version $Id: SimpleTestResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.phpunit2 + * @since 2.2.0 + */ +abstract class SimpleTestResultFormatter extends SimpleReporter +{ + protected $out = NULL; + + protected $project = NULL; + + private $timer = NULL; + + private $runCount = 0; + + private $failureCount = 0; + + private $errorCount = 0; + + private $currentTest = ""; + + /** + * Sets the writer the formatter is supposed to write its results to. + */ + function setOutput(Writer $out) + { + $this->out = $out; + } + + /** + * Returns the extension used for this formatter + * + * @return string the extension + */ + function getExtension() + { + return ""; + } + + /** + * Sets the project + * + * @param Project the project + */ + function setProject(Project $project) + { + $this->project = $project; + } + + function getPreferredOutfile() + { + return ""; + } + + function paintMethodStart($test_name) + { + parent::paintMethodStart($test_name); + + $this->currentTest = $test_name; + } + + function paintMethodEnd($test_name) + { + parent::paintMethodEnd($test_name); + + $this->runCount++; + } + + function paintCaseStart($test_name) + { + parent::paintCaseStart($test_name); + + $this->runCount = 0; + $this->failureCount = 0; + $this->errorCount = 0; + + $this->timer = new Timer(); + $this->timer->start(); + } + + function paintCaseEnd($test_name) + { + parent::paintCaseEnd($test_name); + + $this->timer->stop(); + } + + function paintError($message) + { + parent::paintError($message); + + $this->errorCount++; + } + + function paintFail($message) + { + parent::paintFail($message); + + $this->failureCount++; + } + + function getRunCount() + { + return $this->runCount; + } + + function getFailureCount() + { + return $this->failureCount; + } + + function getErrorCount() + { + return $this->errorCount; + } + + function getTestName() + { + return $this->currentTest; + } + + function getElapsedTime() + { + if ($this->timer) + { + return $this->timer->getElapsedTime(); + } + else + { + return 0; + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php new file mode 100644 index 000000000..dbe239a5b --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php @@ -0,0 +1,54 @@ +. + */ + +require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php'; + +/** + * Prints short summary output of the test to Phing's logging system. + * + * @author Michiel Rook + * @version $Id: SimpleTestSummaryResultFormatter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.simpletest + * @since 2.2.0 + */ +class SimpleTestSummaryResultFormatter extends SimpleTestResultFormatter +{ + function paintCaseEnd($test_name) + { + parent::paintCaseEnd($test_name); + + /* Only count suites where more than one test was run */ + if ($this->getRunCount()) + { + $sb.= "Tests run: " . $this->getRunCount(); + $sb.= ", Failures: " . $this->getFailureCount(); + $sb.= ", Errors: " . $this->getErrorCount(); + $sb.= ", Time elapsed: " . $this->getElapsedTime(); + $sb.= " sec\n"; + + if ($this->out != NULL) + { + $this->out->write($sb); + } + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestTask.php b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestTask.php new file mode 100644 index 000000000..802e14415 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/simpletest/SimpleTestTask.php @@ -0,0 +1,238 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/system/io/PhingFile.php'; +require_once 'phing/system/io/Writer.php'; +require_once 'phing/util/LogWriter.php'; + +/** + * Runs SimpleTest tests. + * + * @author Michiel Rook + * @version $Id: SimpleTestTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.simpletest + * @since 2.2.0 + */ +class SimpleTestTask extends Task +{ + private $formatters = array(); + private $haltonerror = false; + private $haltonfailure = false; + private $failureproperty; + private $errorproperty; + private $printsummary = false; + private $testfailed = false; + + /** + * Initialize Task. + * This method includes any necessary SimpleTest libraries and triggers + * appropriate error if they cannot be found. This is not done in header + * because we may want this class to be loaded w/o triggering an error. + */ + function init() { + @include_once 'simpletest/scorer.php'; + + if (!class_exists('SimpleReporter')) { + throw new BuildException("SimpleTestTask depends on SimpleTest package being installed.", $this->getLocation()); + } + + require_once 'simpletest/reporter.php'; + require_once 'simpletest/xml.php'; + require_once 'simpletest/test_case.php'; + require_once 'phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php'; + require_once 'phing/tasks/ext/simpletest/SimpleTestFormatterElement.php'; + } + + function setFailureproperty($value) + { + $this->failureproperty = $value; + } + + function setErrorproperty($value) + { + $this->errorproperty = $value; + } + + function setHaltonerror($value) + { + $this->haltonerror = $value; + } + + function setHaltonfailure($value) + { + $this->haltonfailure = $value; + } + + function setPrintsummary($printsummary) + { + $this->printsummary = $printsummary; + } + + /** + * Add a new formatter to all tests of this task. + * + * @param SimpleTestFormatterElement formatter element + */ + function addFormatter(SimpleTestFormatterElement $fe) + { + $this->formatters[] = $fe; + } + + /** + * Add a new fileset containing the XML results to aggregate + * + * @param FileSet the new fileset containing XML results. + */ + function addFileSet(FileSet $fileset) + { + $this->filesets[] = $fileset; + } + + /** + * Iterate over all filesets and return the filename of all files + * that end with .php. + * + * @return array an array of filenames + */ + private function getFilenames() + { + $filenames = array(); + + foreach ($this->filesets as $fileset) + { + $ds = $fileset->getDirectoryScanner($this->project); + $ds->scan(); + + $files = $ds->getIncludedFiles(); + + foreach ($files as $file) + { + if (strstr($file, ".php")) + { + $filenames[] = $ds->getBaseDir() . "/" . $file; + } + } + } + + return $filenames; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $group = new GroupTest(); + + $filenames = $this->getFilenames(); + + foreach ($filenames as $testfile) + { + $group->addTestFile($testfile); + } + + if ($this->printsummary) + { + $fe = new SimpleTestFormatterElement(); + $fe->setType('summary'); + $fe->setUseFile(false); + $this->formatters[] = $fe; + } + + foreach ($this->formatters as $fe) + { + $formatter = $fe->getFormatter(); + $formatter->setProject($this->getProject()); + + if ($fe->getUseFile()) + { + $destFile = new PhingFile($fe->getToDir(), $fe->getOutfile()); + + $writer = new FileWriter($destFile->getAbsolutePath()); + + $formatter->setOutput($writer); + } + else + { + $formatter->setOutput($this->getDefaultOutput()); + } + } + + $this->execute($group); + + if ($this->testfailed) + { + throw new BuildException("One or more tests failed"); + } + } + + private function execute($suite) + { + $counter = new SimpleTestCountResultFormatter(); + $reporter = new MultipleReporter(); + $reporter->attachReporter($counter); + + foreach ($this->formatters as $fe) + { + $formatter = $fe->getFormatter(); + + $reporter->attachReporter($formatter); + } + + $suite->run($reporter); + + $retcode = $counter->getRetCode(); + + if ($retcode == SimpleTestCountResultFormatter::ERRORS) + { + if ($this->errorproperty) + { + $this->project->setNewProperty($this->errorproperty, true); + } + + if ($this->haltonerror) + { + $this->testfailed = true; + } + } + elseif ($retcode == SimpleTestCountResultFormatter::FAILURES) + { + if ($this->failureproperty) + { + $this->project->setNewProperty($this->failureproperty, true); + } + + if ($this->haltonfailure) + { + $this->testfailed = true; + } + } + } + + private function getDefaultOutput() + { + return new LogWriter($this); + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/svn/SvnBaseTask.php b/gulliver/thirdparty/phing/tasks/ext/svn/SvnBaseTask.php new file mode 100644 index 000000000..5604ea542 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/svn/SvnBaseTask.php @@ -0,0 +1,180 @@ +. + */ + +include_once 'phing/Task.php'; + +/** + * Send a message by mail() + * + * The build process is a success... + * + * @author Francois Harvey at SecuriWeb (http://www.securiweb.net) + * @version $Id: SvnBaseTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext + */ +abstract class SvnBaseTask extends Task +{ + private $workingCopy = ""; + + private $repositoryUrl = ""; + + private $svnPath = "/usr/bin/svn"; + + private $svn = NULL; + + private $mode = ""; + + private $svnArgs = array(); + + /** + * Initialize Task. + * This method includes any necessary SVN libraries and triggers + * appropriate error if they cannot be found. This is not done in header + * because we may want this class to be loaded w/o triggering an error. + */ + function init() { + include_once 'VersionControl/SVN.php'; + if (!class_exists('VersionControl_SVN')) { + throw new Exception("SvnLastRevisionTask depends on PEAR VersionControl_SVN package being installed."); + } + } + + /** + * Sets the path to the workingcopy + */ + function setWorkingCopy($workingCopy) + { + $this->workingCopy = $workingCopy; + } + + /** + * Returns the path to the workingcopy + */ + function getWorkingCopy() + { + return $this->workingCopy; + } + + /** + * Sets the path/URI to the repository + */ + function setRepositoryUrl($repositoryUrl) + { + $this->repositoryUrl = $repositoryUrl; + } + + /** + * Returns the path/URI to the repository + */ + function getRepositoryUrl() + { + return $this->repositoryUrl; + } + + /** + * Sets the path to the SVN executable + */ + function setSvnPath($svnPath) + { + $this->svnPath = $svnPath; + } + + /** + * Returns the path to the SVN executable + */ + function getSvnPath() + { + return $this->svnPath; + } + + /** + * Creates a VersionControl_SVN class based on $mode + * + * @param string The SVN mode to use (info, export, checkout, ...) + * @throws BuildException + */ + protected function setup($mode) + { + $this->mode = $mode; + + // Set up runtime options. Will be passed to all + // subclasses. + $options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_ASSOC, 'svn_path' => $this->getSvnPath()); + + // Pass array of subcommands we need to factory + $this->svn = VersionControl_SVN::factory($mode, $options); + + if (!empty($this->repositoryUrl)) + { + $this->svnArgs = array($this->repositoryUrl); + } + else + if (!empty($this->workingCopy)) + { + if (is_dir($this->workingCopy)) + { + if (in_array(".svn", scandir($this->workingCopy))) + { + $this->svnArgs = array($this->workingCopy); + } + else + { + throw new BuildException("'".$this->workingCopy."' doesn't seem to be a working copy"); + } + } + else + { + throw new BuildException("'".$this->workingCopy."' is not a directory"); + } + } + } + + /** + * Executes the constructed VersionControl_SVN instance + * + * @param array Additional arguments to pass to SVN. + * @param array Switches to pass to SVN. + * @return string Output generated by SVN. + */ + protected function run($args = array(), $switches = array()) + { + $svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN'); + + $tempArgs = $this->svnArgs; + + $tempArgs = array_merge($tempArgs, $args); + + if ($output = $this->svn->run($tempArgs, $switches)) + { + return $output; + } + else + { + if (count($errs = $svnstack->getErrors())) + { + $err = current($errs); + + throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $err['message']); + } + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/svn/SvnExportTask.php b/gulliver/thirdparty/phing/tasks/ext/svn/SvnExportTask.php new file mode 100644 index 000000000..63c018d3b --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/svn/SvnExportTask.php @@ -0,0 +1,68 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; + +/** + * Exports/checks out a repository to a local directory + * + * @author Michiel Rook + * @version $Id: SvnExportTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.svn + * @see VersionControl_SVN + * @since 2.1.0 + */ +class SvnExportTask extends SvnBaseTask +{ + private $toDir = ""; + + /** + * Sets the path to export/checkout to + */ + function setToDir($toDir) + { + $this->toDir = $toDir; + } + + /** + * Returns the path to export/checkout to + */ + function getToDir() + { + return $this->toDir; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $this->setup('export'); + + $this->log("Exporting SVN repository to '" . $this->toDir . "'"); + + $this->run(array($this->toDir)); + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/ext/svn/SvnLastRevisionTask.php b/gulliver/thirdparty/phing/tasks/ext/svn/SvnLastRevisionTask.php new file mode 100644 index 000000000..bb9ef58b7 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/ext/svn/SvnLastRevisionTask.php @@ -0,0 +1,75 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/tasks/ext/svn/SvnBaseTask.php'; + +/** + * Stores the number of the last revision of a workingcopy in a property + * + * @author Michiel Rook + * @version $Id: SvnLastRevisionTask.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.tasks.ext.svn + * @see VersionControl_SVN + * @since 2.1.0 + */ +class SvnLastRevisionTask extends SvnBaseTask +{ + private $propertyName = "svn.lastrevision"; + + /** + * Sets the name of the property to use + */ + function setPropertyName($propertyName) + { + $this->propertyName = $propertyName; + } + + /** + * Returns the name of the property to use + */ + function getPropertyName() + { + return $this->propertyName; + } + + /** + * The main entry point + * + * @throws BuildException + */ + function main() + { + $this->setup('info'); + + $output = $this->run(); + + if (preg_match('/Rev:[\s]+([\d]+)/', $output, $matches)) + { + $this->project->setProperty($this->getPropertyName(), $matches[1]); + } + else + { + throw new BuildException("Failed to parse the output of 'svn info'."); + } + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/system/AdhocTask.php b/gulliver/thirdparty/phing/tasks/system/AdhocTask.php new file mode 100644 index 000000000..bccf6637a --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/AdhocTask.php @@ -0,0 +1,88 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Abstract class for creating adhoc Phing components in buildfile. + * + * By itself this class can be used to declare a single class within your buildfile. + * You can then reference this class in any task that takes custom classes (selectors, + * mappers, filters, etc.) + * + * Subclasses exist for conveniently declaring and registering tasks and types. + * + * @author Hans Lellelid + * @version $Revision: 1.6 $ + * @package phing.tasks.system + */ +class AdhocTask extends Task { + + /** + * The PHP script + * @var string + */ + protected $script; + + protected $newClasses = array(); + + /** + * Main entry point + */ + public function main() { + $this->execute(); + if ($this->newClasses) { + foreach($this->newClasses as $classname) { + $this->log("Added adhoc class " . $classname, PROJECT_MSG_VERBOSE); + } + } else { + $this->log("Adhoc task executed but did not result in any new classes.", PROJECT_MSG_VERBOSE); + } + } + + /** + * Get array of names of newly defined classes. + * @return array + */ + protected function getNewClasses() { + return $this->newClasses; + } + + /** + * Load the adhoc class, and perform any core validation. + * @return string The classname of the ProjectComponent class. + * @throws BuildException - if more than one class is defined. + */ + protected function execute() { + $classes = get_declared_classes(); + eval($this->script); + $this->newClasses = array_diff(get_declared_classes(), $classes); + } + + /** + * Set the script. + * @param string $script + */ + public function addText($script) { + $this->script = $script; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/AdhocTaskdefTask.php b/gulliver/thirdparty/phing/tasks/system/AdhocTaskdefTask.php new file mode 100644 index 000000000..18ce635eb --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/AdhocTaskdefTask.php @@ -0,0 +1,90 @@ +. + */ + +require_once 'phing/tasks/system/AdhocTask.php'; + +/** + * A class for creating adhoc tasks in build file. + * + * + * bar = $bar; + * } + * + * function main() { + * $this->log("In FooTest: " . $this->bar); + * } + * } + * + * ]]> + * + * + * + * + * @author Hans Lellelid + * @version $Revision: 1.5 $ + * @package phing.tasks.system + */ +class AdhocTaskdefTask extends AdhocTask { + + /** + * The tag that refers to this task. + */ + private $name; + + /** + * Set the tag that will represent this adhoc task/type. + * @param string $name + */ + public function setName($name) { + $this->name = $name; + } + + /** Main entry point */ + public function main() { + if ($this->name === null) { + throw new BuildException("The name attribute is required for adhoc task definition.",$this->location); + } + + $this->execute(); + + $classes = $this->getNewClasses(); + if (count($classes) !== 1) { + throw new BuildException("You must define one (and only one) class for AdhocTaskdefTask."); + } + $classname = array_shift($classes); + + // instantiate it to make sure it is an instance of Task + $t = new $classname(); + if (!($t instanceof Task)) { + throw new BuildException("The adhoc class you defined must be an instance of phing.Task", $this->location); + } + + $this->log("Task " . $this->name . " will be handled by class " . $classname, PROJECT_MSG_VERBOSE); + $this->project->addTaskDefinition($this->name, $classname); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/AdhocTypedefTask.php b/gulliver/thirdparty/phing/tasks/system/AdhocTypedefTask.php new file mode 100644 index 000000000..24330f150 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/AdhocTypedefTask.php @@ -0,0 +1,71 @@ +. + */ + +require_once 'phing/tasks/system/AdhocTask.php'; + +/** + * A class for creating adhoc datatypes in build file. + * + * @author Hans Lellelid + * @version $Revision: 1.4 $ + * @package phing.tasks.system + */ +class AdhocTypedefTask extends AdhocTask { + + /** + * The tag that refers to this task. + */ + private $name; + + /** + * Set the tag that will represent this adhoc task/type. + * @param string $name + */ + public function setName($name) { + $this->name = $name; + } + + /** Main entry point */ + public function main() { + + if ($this->name === null) { + throw new BuildException("The name attribute is required for adhoc task definition.",$this->location); + } + + $this->execute(); + + $classes = $this->getNewClasses(); + if (count($classes) !== 1) { + throw new BuildException("You must define one (and only one) class for AdhocTypedefTask."); + } + $classname = array_shift($classes); + + // instantiate it to make sure it is an instance of ProjectComponent + $t = new $classname(); + if (!($t instanceof ProjectComponent)) { + throw new BuildException("The adhoc class you defined must be an instance of phing.ProjectComponent", $this->location); + } + + $this->log("Datatype " . $this->name . " will be handled by class " . $classname, PROJECT_MSG_VERBOSE); + $this->project->addDataTypeDefinition($this->name, $classname); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/AppendTask.php b/gulliver/thirdparty/phing/tasks/system/AppendTask.php new file mode 100644 index 000000000..ccf260f87 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/AppendTask.php @@ -0,0 +1,240 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/types/FileList.php'; +include_once 'phing/types/FileSet.php'; + +/** + * Appends text, contents of a file or set of files defined by a filelist to a destination file. + * + * + * + * + * OR + * + * + * + * + * + * OR + * + * + * + * + * + * + * + * + * + * + * + * @package phing.tasks.system + * @version $Revision: 1.14 $ + */ +class AppendTask extends Task { + + /** Append stuff to this file. */ + private $to; + + /** Explicit file to append. */ + private $file; + + /** Any filesets of files that should be appended. */ + private $filesets = array(); + + /** Any filelists of files that should be appended. */ + private $filelists = array(); + + /** Any filters to be applied before append happens. */ + private $filterChains = array(); + + /** Text to append. (cannot be used in conjunction w/ files or filesets) */ + private $text; + + /** Sets specific file to append. */ + function setFile(PhingFile $f) { + $this->file = $f; + } + + /** + * Set target file to append to. + * @deprecated Will be removed with final release. + */ + function setTo(PhingFile $f) { + $this->log("The 'to' attribute is deprecated in favor of 'destFile'; please update your code.", PROJECT_MSG_WARN); + $this->to = $f; + } + + /** + * The more conventional naming for method to set destination file. + * @param PhingFile $f + */ + function setDestFile(PhingFile $f) { + $this->to = $f; + } + + /** + * Supports embedded element. + * @return FileList + */ + function createFileList() { + $num = array_push($this->filelists, new FileList()); + return $this->filelists[$num-1]; + } + + /** + * Nested creator, adds a set of files (nested attribute). + * This is for when you don't care what order files get appended. + * @return FileSet + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Creates a filterchain + * + * @return FilterChain The created filterchain object + */ + function createFilterChain() { + $num = array_push($this->filterChains, new FilterChain($this->project)); + return $this->filterChains[$num-1]; + } + + /** + * Sets text to append. (cannot be used in conjunction w/ files or filesets). + * @param string $txt + */ + function setText($txt) { + $this->text = (string) $txt; + } + + /** + * Sets text to append. Supports CDATA. + * @param string $txt + */ + function addText($txt) { + $this->text = (string) $txt; + } + + + /** Append the file(s). */ + function main() { + + if ($this->to === null) { + throw new BuildException("You must specify the 'destFile' attribute"); + } + + if ($this->file === null && empty($this->filelists) && empty($this->filesets) && $this->text === null) { + throw new BuildException("You must specify a file, use a filelist, or specify a text value."); + } + + if ($this->text !== null && ($this->file !== null || !empty($this->filelists))) { + throw new BuildException("Cannot use text attribute in conjunction with file or filelists."); + } + + // create a filwriter to append to "to" file. + $writer = new FileWriter($this->to, $append=true); + + if ($this->text !== null) { + + // simply append the text + $this->log("Appending string to " . $this->to->getPath()); + + // for debugging primarily, maybe comment + // out for better performance(?) + $lines = explode("\n", $this->text); + foreach($lines as $line) { + $this->log($line, PROJECT_MSG_VERBOSE); + } + + $writer->write($this->text); + + } else { + + // append explicitly-specified file + if ($this->file !== null) { + try { + $this->appendFile($writer, $this->file); + } catch (Exception $ioe) { + $this->log("Unable to append contents of file " . $this->file->getAbsolutePath() . ": " . $ioe->getMessage(), PROJECT_MSG_WARN); + } + } + + // append the files in the filelists + foreach($this->filelists as $fl) { + try { + $files = $fl->getFiles($this->project); + $this->appendFiles($writer, $files, $fl->getDir($this->project)); + } catch (BuildException $be) { + $this->log($be->getMessage(), PROJECT_MSG_WARN); + } + } + + // append any files in filesets + foreach($this->filesets as $fs) { + try { + $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles(); + $this->appendFiles($writer, $files, $fs->getDir($this->project)); + } catch (BuildException $be) { + $this->log($be->getMessage(), PROJECT_MSG_WARN); + } + } + + } // if ($text ) {} else {} + + $writer->close(); + } + + /** + * Append an array of files in a directory. + * @param FileWriter $writer The FileWriter that is appending to target file. + * @param array $files array of files to delete; can be of zero length + * @param PhingFile $dir directory to work from + */ + private function appendFiles(FileWriter $writer, $files, PhingFile $dir) { + if (!empty($files)) { + $this->log("Attempting to append " . count($files) . " files" .($dir !== null ? ", using basedir " . $dir->getPath(): "")); + $basenameSlot = Register::getSlot("task.append.current_file"); + $pathSlot = Register::getSlot("task.append.current_file.path"); + foreach($files as $filename) { + try { + $f = new PhingFile($dir, $filename); + $basenameSlot->setValue($filename); + $pathSlot->setValue($f->getPath()); + $this->appendFile($writer, $f); + } catch (Exception $ioe) { + $this->log("Unable to append contents of file " . $f->getAbsolutePath() . ": " . $ioe->getMessage(), PROJECT_MSG_WARN); + } + } + } // if !empty + } + + private function appendFile(FileWriter $writer, PhingFile $f) { + $in = FileUtils::getChainedReader(new FileReader($f), $this->filterChains, $this->project); + while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF + $writer->write($buffer); + } + $this->log("Appending contents of " . $f->getPath() . " to " . $this->to->getPath()); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/AvailableTask.php b/gulliver/thirdparty/phing/tasks/system/AvailableTask.php new file mode 100644 index 000000000..a2a53d4ee --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/AvailableTask.php @@ -0,0 +1,132 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * task. + * + * Note: implements condition interface (see condition/Condition.php) + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.11 $ + * @package phing.tasks.system + */ +class AvailableTask extends Task { + + /** Property to check for. */ + private $property; + + /** Value property should be set to. */ + private $value = "true"; + + /** Resource to check for */ + private $resource; + + private $type = null; + private $filepath = null; + + function setProperty($property) { + $this->property = (string) $property; + } + + function setValue($value) { + $this->value = (string) $value; + } + + function setFile(PhingFile $file) { + $this->file = $file; + } + + function setResource($resource) { + $this->resource = (string) $resource; + } + + function setType($type) { + $this->type = (string) strtolower($type); + } + + function main() { + if ($this->property === null) { + throw new BuildException("property attribute is required", $this->location); + } + if ($this->evaluate()) { + $this->project->setProperty($this->property, $this->value); + } + } + + function evaluate() { + if ($this->file === null && $this->resource === null) { + throw new BuildException("At least one of (file|resource) is required", $this->location); + } + + if ($this->type !== null && ($this->type !== "file" && $this->type !== "dir")) { + throw new BuildException("Type must be one of either dir or file", $this->location); + } + + if (($this->file !== null) && !$this->_checkFile()) { + $this->log("Unable to find " . $this->file->__toString() . " to set property " . $this->property, PROJECT_MSG_VERBOSE); + return false; + } + + if (($this->resource !== null) && !$this->_checkResource($this->resource)) { + $this->log("Unable to load resource " . $this->resource . " to set property " . $this->property, PROJECT_MSG_VERBOSE); + return false; + } + + return true; + } + + // this is prepared for the path type + function _checkFile() { + if ($this->filepath === null) { + return $this->_checkFile1($this->file); + } else { + $paths = $this->filepath->listDir(); + for($i=0,$pcnt=count($paths); $i < $pcnt; $i++) { + $this->log("Searching " . $paths[$i], PROJECT_MSG_VERBOSE); + $tmp = new PhingFile($paths[$i], $this->file->getName()); + if($tmp->isFile()) { + return true; + } + } + } + return false; + } + + function _checkFile1($file) { + if ($this->type !== null) { + if ($this->type === "dir") { + return $file->isDirectory(); + } else if ($this->type === "file") { + return $file->isFile(); + } + } + return $file->exists(); + } + + function _checkResource($resource) { + return $this->_checkFile1(new PhingFile(Phing::getResourcePath($resource))); + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/ChmodTask.php b/gulliver/thirdparty/phing/tasks/system/ChmodTask.php new file mode 100644 index 000000000..f04634e5c --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ChmodTask.php @@ -0,0 +1,177 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/types/FileSet.php'; + +/** + * Task that changes the permissions on a file/directory. + * + * @author Manuel Holtgrewe + * @author Hans Lellelid + * @version $Revision: 1.12 $ + * @package phing.tasks.system + */ +class ChmodTask extends Task { + + private $file; + + private $mode; + + private $filesets = array(); + + private $filesystem; + + private $quiet = false; + private $failonerror = true; + + /** + * This flag means 'note errors to the output, but keep going' + * @see setQuiet() + */ + function setFailonerror($bool) { + $this->failonerror = $bool; + } + + /** + * Set quiet mode, which suppresses warnings if chmod() fails. + * @see setFailonerror() + */ + function setQuiet($bool) { + $this->quiet = $bool; + if ($this->quiet) { + $this->failonerror = false; + } + } + + /** + * Sets a single source file to touch. If the file does not exist + * an empty file will be created. + */ + function setFile(PhingFile $file) { + $this->file = $file; + } + + function setMode($str) { + $this->mode = $str; + } + + /** + * Nested creator, adds a set of files (nested fileset attribute). + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Execute the touch operation. + * @return void + */ + function main() { + // Check Parameters + $this->checkParams(); + $this->chmod(); + } + + /** + * Ensure that correct parameters were passed in. + * @return void + */ + private function checkParams() { + + if ($this->file === null && empty($this->filesets)) { + throw new BuildException("Specify at least one source - a file or a fileset."); + } + + if ($this->mode === null) { + throw new BuildException("You have to specify an octal mode for chmod."); + } + + // check for mode to be in the correct format + if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) { + throw new BuildException("You have specified an invalid mode."); + } + + } + + /** + * Does the actual work. + * @return void + */ + private function chmod() { + + if (strlen($this->mode) === 4) { + $mode = octdec($this->mode); + } else { + // we need to prepend the 0 before converting + $mode = octdec("0". $this->mode); + } + + // one file + if ($this->file !== null) { + $this->chmodFile($this->file, $mode); + } + + // filesets + foreach($this->filesets as $fs) { + + $ds = $fs->getDirectoryScanner($this->project); + $fromDir = $fs->getDir($this->project); + + $srcFiles = $ds->getIncludedFiles(); + $srcDirs = $ds->getIncludedDirectories(); + + for ($j = 0, $filecount = count($srcFiles); $j < $filecount; $j++) { + $this->chmodFile(new PhingFile($fromDir, $srcFiles[$j]), $mode); + } + + for ($j = 0, $dircount = count($srcDirs); $j < $dircount; $j++) { + $this->chmodFile(new PhingFile($fromDir, $srcDirs[$j]), $mode); + } + } + + } + + /** + * Actually change the mode for the file. + * @param PhingFile $file + * @param int $mode + */ + private function chmodFile(PhingFile $file, $mode) { + if ( !$file->exists() ) { + throw new BuildException("The file " . $file->__toString() . " does not exist"); + } + + try { + $file->setMode($mode); + $this->log("Changed file mode on '" . $file->__toString() ."' to " . vsprintf("%o", $mode)); + } catch (Exception $e) { + if($this->failonerror) { + throw $e; + } else { + $this->log($e->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + +} + diff --git a/gulliver/thirdparty/phing/tasks/system/ConditionTask.php b/gulliver/thirdparty/phing/tasks/system/ConditionTask.php new file mode 100644 index 000000000..69618421a --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ConditionTask.php @@ -0,0 +1,74 @@ +. +*/ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * task as a generalization of + * + *

    This task supports boolean logic as well as pluggable conditions + * to decide, whether a property should be set.

    + * + *

    This task does not extend Task to take advantage of + * ConditionBase.

    + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.7 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @access public + * @package phing.tasks.system + */ +class ConditionTask extends ConditionBase { + + private $property; + private $value = "true"; + + /** + * The name of the property to set. Required. + */ + function setProperty($p) { + $this->property = $p; + } + + /** + * The value for the property to set. Defaults to "true". + */ + function setValue($v) { + $this->value = $v; + } + + /** + * See whether our nested condition holds and set the property. + */ + function main() { + + if ($this->countConditions() > 1) { + throw new BuildException("You must not nest more than one condition into "); + } + if ($this->countConditions() < 1) { + throw new BuildException("You must nest a condition into "); + } + $cs = $this->getIterator(); + if ($cs->current()->evaluate()) { + $this->project->setProperty($this->property, $this->value); + } + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/CopyTask.php b/gulliver/thirdparty/phing/tasks/system/CopyTask.php new file mode 100644 index 000000000..371f44218 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/CopyTask.php @@ -0,0 +1,401 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/util/FileUtils.php'; +include_once 'phing/util/SourceFileScanner.php'; +include_once 'phing/mappers/IdentityMapper.php'; +include_once 'phing/mappers/FlattenMapper.php'; + +/** + * A phing copy task. Copies a file or directory to a new file + * or directory. Files are only copied if the source file is newer + * than the destination file, or when the destination file does not + * exist. It is possible to explictly overwrite existing files. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.16 $ $Date: 2006-06-12 21:46:05 +0200 (Mon, 12 Jun 2006) $ + * @package phing.tasks.system + */ +class CopyTask extends Task { + + protected $file = null; // the source file (from xml attribute) + protected $destFile = null; // the destiantion file (from xml attribute) + protected $destDir = null; // the destination dir (from xml attribute) + protected $overwrite = false; // overwrite destination (from xml attribute) + protected $preserveLMT = true; // sync timestamps (from xml attribute) + protected $includeEmpty = true; // include empty dirs? (from XML) + protected $flatten = false; // apply the FlattenMapper right way (from XML) + protected $mapperElement = null; + + protected $fileCopyMap = array(); // asoc array containing mapped file names + protected $dirCopyMap = array(); // asoc array containing mapped file names + protected $fileUtils = null; // a instance of fileutils + protected $filesets = array(); // all fileset objects assigned to this task + protected $filterChains = array(); // all filterchains objects assigned to this task + + protected $verbosity = PROJECT_MSG_VERBOSE; + + /** + * Sets up this object internal stuff. i.e. the Fileutils instance + * + * @return object The CopyTask instnace + * @access public + */ + function __construct() { + $this->fileUtils = new FileUtils(); + } + + /** + * Set the overwrite flag. IntrospectionHelper takes care of + * booleans in set* methods so we can assume that the right + * value (boolean primitive) is coming in here. + * + * @param boolean Overwrite the destination file(s) if it/they already exist + * @return void + * @access public + */ + function setOverwrite($bool) { + $this->overwrite = (boolean) $bool; + } + + /** + * Used to force listing of all names of copied files. + * @param boolean $verbosity + */ + function setVerbose($verbosity) { + if ($verbosity) { + $this->verbosity = PROJECT_MSG_INFO; + } else { + $this->verbosity = PROJECT_MSG_VERBOSE; + } + } + + /** + * Set the preserve timestmap flag. IntrospectionHelper takes care of + * booleans in set* methods so we can assume that the right + * value (boolean primitive) is coming in here. + * + * @param boolean Preserve the timestamp on the destination file + * @return void + * @access public + */ + function setTstamp($bool) { + $this->preserveLMT = (boolean) $bool; + } + + + /** + * Set the include empty dirs flag. IntrospectionHelper takes care of + * booleans in set* methods so we can assume that the right + * value (boolean primitive) is coming in here. + * + * @param boolean Flag if empty dirs should be cpoied too + * @return void + * @access public + */ + function setIncludeEmptyDirs($bool) { + $this->includeEmpty = (boolean) $bool; + } + + + /** + * Set the file. We have to manually take care of the + * type that is coming due to limited type support in php + * in and convert it manually if neccessary. + * + * @param string/object The source file. Either a string or an PhingFile object + * @return void + * @access public + */ + function setFile(PhingFile $file) { + $this->file = $file; + } + + + /** + * Set the toFile. We have to manually take care of the + * type that is coming due to limited type support in php + * in and convert it manually if neccessary. + * + * @param string/object The dest file. Either a string or an PhingFile object + * @return void + * @access public + */ + function setTofile(PhingFile $file) { + $this->destFile = $file; + } + + + /** + * Set the toDir. We have to manually take care of the + * type that is coming due to limited type support in php + * in and convert it manually if neccessary. + * + * @param string/object The directory, either a string or an PhingFile object + * @return void + * @access public + */ + function setTodir(PhingFile $dir) { + $this->destDir = $dir; + } + + /** + * Nested creator, creates a FileSet for this task + * + * @access public + * @return object The created fileset object + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Creates a filterchain + * + * @access public + * @return object The created filterchain object + */ + function createFilterChain() { + $num = array_push($this->filterChains, new FilterChain($this->project)); + return $this->filterChains[$num-1]; + } + + /** + * Nested creator, creates one Mapper for this task + * + * @access public + * @return object The created Mapper type object + * @throws BuildException + */ + function createMapper() { + if ($this->mapperElement !== null) { + throw new BuildException("Cannot define more than one mapper", $this->location); + } + $this->mapperElement = new Mapper($this->project); + return $this->mapperElement; + } + + /** + * The main entry point where everything gets in motion. + * + * @access public + * @return true on success + * @throws BuildException + */ + function main() { + + $this->validateAttributes(); + + if ($this->file !== null) { + if ($this->file->exists()) { + if ($this->destFile === null) { + $this->destFile = new PhingFile($this->destDir, (string) $this->file->getName()); + } + if ($this->overwrite === true || ($this->file->lastModified() > $this->destFile->lastModified())) { + $this->fileCopyMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath(); + } else { + $this->log($this->file->getName()." omitted, is up to date"); + } + } else { + // terminate build + throw new BuildException("Could not find file " . $this->file->__toString() . " to copy."); + } + } + + $project = $this->getProject(); + + // process filesets + foreach($this->filesets as $fs) { + $ds = $fs->getDirectoryScanner($project); + $fromDir = $fs->getDir($project); + $srcFiles = $ds->getIncludedFiles(); + $srcDirs = $ds->getIncludedDirectories(); + $this->_scan($fromDir, $this->destDir, $srcFiles, $srcDirs); + } + + // go and copy the stuff + $this->doWork(); + + if ($this->destFile !== null) { + $this->destDir = null; + } + } + + /** + * Validates attributes coming in from XML + * + * @access private + * @return void + * @throws BuildException + */ + private function validateAttributes() { + + if ($this->file === null && count($this->filesets) === 0) { + throw new BuildException("CopyTask. Specify at least one source - a file or a fileset."); + } + + if ($this->destFile !== null && $this->destDir !== null) { + throw new BuildException("Only one destfile and destdir may be set."); + } + + if ($this->destFile === null && $this->destDir === null) { + throw new BuildException("One destfile or destdir must be set."); + } + + if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) { + throw new BuildException("Use a fileset to copy directories."); + } + + if ($this->destFile !== null && count($this->filesets) > 0) { + throw new BuildException("Cannot concatenate multiple files into a single file."); + } + + if ($this->destFile !== null) { + $this->destDir = new PhingFile($this->destFile->getParent()); + } + } + + /** + * Compares source files to destination files to see if they + * should be copied. + * + * @access private + * @return void + */ + private function _scan(&$fromDir, &$toDir, &$files, &$dirs) { + /* mappers should be generic, so we get the mappers here and + pass them on to builMap. This method is not redundan like it seems */ + $mapper = null; + if ($this->mapperElement !== null) { + $mapper = $this->mapperElement->getImplementation(); + } else if ($this->flatten) { + $mapper = new FlattenMapper(); + } else { + $mapper = new IdentityMapper(); + } + $this->buildMap($fromDir, $toDir, $files, $mapper, $this->fileCopyMap); + $this->buildMap($fromDir, $toDir, $dirs, $mapper, $this->dirCopyMap); + } + + /** + * Builds a map of filenames (from->to) that should be copied + * + * @access private + * @return void + */ + private function buildMap(&$fromDir, &$toDir, &$names, &$mapper, &$map) { + $toCopy = null; + if ($this->overwrite) { + $v = array(); + foreach($names as $name) { + $result = $mapper->main($name); + if ($result !== null) { + $v[] = $name; + } + } + $toCopy = $v; + } else { + $ds = new SourceFileScanner($this); + $toCopy = $ds->restrict($names, $fromDir, $toDir, $mapper); + } + + for ($i=0,$_i=count($toCopy); $i < $_i; $i++) { + $src = new PhingFile($fromDir, $toCopy[$i]); + $mapped = $mapper->main($toCopy[$i]); + $dest = new PhingFile($toDir, $mapped[0]); + $map[$src->getAbsolutePath()] = $dest->getAbsolutePath(); + } + } + + + /** + * Actually copies the files + * + * @access private + * @return void + * @throws BuildException + */ + private function doWork() { + + // These "slots" allow filters to retrieve information about the currently-being-process files + $fromSlot = $this->getRegisterSlot("currentFromFile"); + $fromBasenameSlot = $this->getRegisterSlot("currentFromFile.basename"); + + $toSlot = $this->getRegisterSlot("currentToFile"); + $toBasenameSlot = $this->getRegisterSlot("currentToFile.basename"); + + $mapSize = count($this->fileCopyMap); + $total = $mapSize; + if ($mapSize > 0) { + $this->log("Copying ".$mapSize." file".(($mapSize) === 1 ? '' : 's')." to ". $this->destDir->getAbsolutePath()); + // walks the map and actually copies the files + $count=0; + foreach($this->fileCopyMap as $from => $to) { + if ($from === $to) { + $this->log("Skipping self-copy of " . $from, $this->verbosity); + $total--; + continue; + } + $this->log("From ".$from." to ".$to, $this->verbosity); + try { // try to copy file + + $fromFile = new PhingFile($from); + $toFile = new PhingFile($to); + + $fromSlot->setValue($fromFile->getPath()); + $fromBasenameSlot->setValue($fromFile->getName()); + + $toSlot->setValue($toFile->getPath()); + $toBasenameSlot->setValue($toFile->getName()); + + $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject()); + + $count++; + } catch (IOException $ioe) { + $this->log("Failed to copy " . $from . " to " . $to . ": " . $ioe->getMessage(), PROJECT_MSG_ERR); + } + } + } + + // handle empty dirs if appropriate + if ($this->includeEmpty) { + $destdirs = array_values($this->dirCopyMap); + $count = 0; + foreach ($destdirs as $destdir) { + $d = new PhingFile((string) $destdir); + if (!$d->exists()) { + if (!$d->mkdirs()) { + $this->log("Unable to create directory " . $d->__toString(), PROJECT_MSG_ERR); + } else { + $count++; + } + } + } + if ($count > 0) { + $this->log("Copied ".$count." empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath()); + } + } + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/CvsPassTask.php b/gulliver/thirdparty/phing/tasks/system/CvsPassTask.php new file mode 100644 index 000000000..16d03393c --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/CvsPassTask.php @@ -0,0 +1,173 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/system/io/BufferedReader.php'; +include_once 'phing/system/io/BufferedWriter.php'; +include_once 'phing/util/StringHelper.php'; + +/** + * Adds an new entry to a CVS password file. + * + * @author Hans Lellelid (Phing) + * @author Jeff Martin (Ant) + * @version $Revision: 1.7 $ + * @package phing.tasks.system + */ +class CVSPassTask extends Task { + + /** CVS Root */ + private $cvsRoot; + /** Password file to add password to */ + private $passFile; + /** Password to add to file */ + private $password; + + /** Array contain char conversion data */ + private static $shifts = array( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, + 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105, + 41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35, + 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56, + 36, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, + 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223, + 225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190, + 199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193, + 174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212, + 207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246, + 192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176, + 227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127, + 182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195, + 243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152 + ); + + /** + * Create a CVS task using the default cvspass file location. + */ + public function __construct() { + $this->passFile = new PhingFile( + Phing::getProperty("cygwin.user.home", + Phing::getProperty("user.home")) + . DIRECTORY_SEPARATOR . ".cvspass"); + } + + /** + * Does the work. + * + * @throws BuildException if someting goes wrong with the build + */ + public final function main() { + if ($this->cvsRoot === null) { + throw new BuildException("cvsroot is required"); + } + if ($this->password === null) { + throw new BuildException("password is required"); + } + + $this->log("cvsRoot: " . $this->cvsRoot, PROJECT_MSG_DEBUG); + $this->log("password: " . $this->password, PROJECT_MSG_DEBUG); + $this->log("passFile: " . $this->passFile->__toString(), PROJECT_MSG_DEBUG); + + $reader = null; + $writer = null; + + try { + $buf = ""; + + if ($this->passFile->exists()) { + $reader = new BufferedReader(new FileReader($this->passFile)); + + $line = null; + while (($line = $reader->readLine()) !== null) { + if (!StringHelper::startsWith($this->cvsRoot, $line)) { + $buf .= $line . Phing::getProperty("line.separator"); + } + } + } + + $pwdfile = $buf . $this->cvsRoot . " A" . $this->mangle($this->password); + + $this->log("Writing -> " . $pwdfile , PROJECT_MSG_DEBUG); + + $writer = new BufferedWriter(new FileWriter($this->passFile)); + $writer->write($pwdfile); + $writer->newLine(); + + $writer->close(); + if ($reader) { + $reader->close(); + } + + } catch (IOException $e) { + if ($reader) { + try { + $reader->close(); + } catch (Exception $e) {} + } + + if ($writer) { + try { + $writer->close(); + } catch (Exception $e) {} + } + + throw new BuildException($e); + } + } + + /** + * "Encode" the password. + */ + private final function mangle($password){ + $buf = ""; + for ($i = 0, $plen = strlen($password); $i < $plen; $i++) { + $buf .= chr(self::$shifts[ord($password{$i})]); + } + return $buf; + } + + /** + * The CVS repository to add an entry for. + * @param string $cvsRoot + */ + public function setCvsroot($cvsRoot) { + $this->cvsRoot = $cvsRoot; + } + + /** + * Password file to add the entry to. + * @param PhingFile $passFile + */ + public function setPassfile(PhingFile $passFile) { + $this->passFile = $passFile; + } + + /** + * Password to be added to the password file. + * @param string $password + */ + public function setPassword($password) { + $this->password = $password; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/CvsTask.php b/gulliver/thirdparty/phing/tasks/system/CvsTask.php new file mode 100644 index 000000000..c3071191d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/CvsTask.php @@ -0,0 +1,540 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/tasks/system/ExecTask.php'; +include_once 'phing/types/Commandline.php'; + +/** + * Task for performing CVS operations. + * + * NOTE: This implementation has been moved here from Cvs.java with + * the addition of some accessors for extensibility. Another task + * can extend this with some customized output processing. + * + * @author Hans Lellelid (Phing) + * @author costin@dnt.ro (Ant) + * @author stefano@apache.org (Ant) + * @author Wolfgang Werner (Ant) + * @author Kevin Ross (Ant) + * @version $Revision: 1.14 $ + * @package phing.tasks.system + */ +class CvsTask extends Task { + + /** + * Default compression level to use, if compression is enabled via + * setCompression( true ). + */ + const DEFAULT_COMPRESSION_LEVEL = 3; + + private $cmd; + + /** + * List of Commandline children + * @var array Commandline[] + */ + private $commandlines = array(); + + /** + * the CVSROOT variable. + */ + private $cvsRoot; + + /** + * the CVS_RSH variable. + */ + private $cvsRsh; + + /** + * the package/module to check out. + */ + private $cvsModule; + + /** + * the default command. + */ + private static $default_command = "checkout"; + + /** + * the CVS command to execute. + */ + private $command = null; + + /** + * suppress information messages. + */ + private $quiet = false; + + /** + * compression level to use. + */ + private $compression = 0; + + /** + * report only, don't change any files. + */ + private $noexec = false; + + /** + * CVS port + */ + private $port = 0; + + /** + * CVS password file + * @var File + */ + private $passFile = null; + + /** + * the directory where the checked out files should be placed. + * @var File + */ + private $dest; + + private $error; + + private $output; + + /** + * If true it will stop the build if cvs exits with error. + * Default is false. (Iulian) + * @var boolean + */ + private $failOnError = false; + + public function init() { + $this->cmd = new Commandline(); + } + + /** + * Sets up the environment for toExecute and then runs it. + * @param Commandline $toExecute + * @throws BuildException + */ + protected function runCommand(Commandline $toExecute) { + + // We are putting variables into the script's environment + // and not removing them (!) This should be fine, but is + // worth remembering and testing. + + if ($this->port > 0) { + putenv("CVS_CLIENT_PORT=".$this->port); + } + + // Need a better cross platform integration with , so + // use the same filename. + + if ($this->passFile === null) { + $defaultPassFile = new PhingFile(Phing::getProperty("cygwin.user.home", Phing::getProperty("user.home")) + . DIRECTORY_SEPARATOR . ".cvspass"); + if($defaultPassFile->exists()) { + $this->setPassfile($defaultPassFile); + } + } + + if ($this->passFile !== null) { + if ($this->passFile->isFile() && $this->passFile->canRead()) { + putenv("CVS_PASSFILE=" . $this->passFile->__toString()); + $this->log("Using cvs passfile: " . $this->passFile->__toString(), PROJECT_MSG_INFO); + } elseif (!$this->passFile->canRead()) { + $this->log("cvs passfile: " . $this->passFile->__toString() + . " ignored as it is not readable", PROJECT_MSG_WARN); + } else { + $this->log("cvs passfile: " . $this->passFile->__toString() + . " ignored as it is not a file", + PROJECT_MSG_WARN); + } + } + + if ($this->cvsRsh !== null) { + putenv("CVS_RSH=".$this->cvsRsh); + } + + // Use the ExecTask to handle execution of the command + $exe = new ExecTask($this->project); + $exe->setProject($this->project); + + //exe.setAntRun(project); + if ($this->dest === null) { + $this->dest = $this->project->getBaseDir(); + } + + if (!$this->dest->exists()) { + $this->dest->mkdirs(); + } + + if ($this->output !== null) { + $exe->setOutput($this->output); + } + + if ($this->error !== null) { + $exe->setError($this->error); + } + + $exe->setDir($this->dest); + + if (is_object($toExecute)) { + $toExecuteStr = $toExecute->__toString(); // unfortunately no more automagic for initial 5.0.0 release :( + } + + $exe->setCommand($toExecuteStr); + + try { + $actualCommandLine = $toExecuteStr; // we converted to string above + $this->log($actualCommandLine, PROJECT_MSG_INFO); + $retCode = $exe->execute(); + $this->log("retCode=" . $retCode, PROJECT_MSG_DEBUG); + /*Throw an exception if cvs exited with error. (Iulian)*/ + if ($this->failOnError && $retCode !== 0) { + throw new BuildException("cvs exited with error code " + . $retCode + . Phing::getProperty("line.separator") + . "Command line was [" + . $toExecute->describeCommand() . "]", $this->getLocation()); + } + } catch (IOException $e) { + if ($this->failOnError) { + throw new BuildException($e, $this->getLocation()); + } else { + $this->log("Caught exception: " . $e, PROJECT_MSG_WARN); + } + } catch (BuildException $e) { + if ($this->failOnError) { + throw $e; + } else { + $t = $e->getCause(); + if ($t === null) { + $t = $e; + } + $this->log("Caught exception: " . $t, PROJECT_MSG_WARN); + } + } catch (Exception $e) { + if ($this->failOnError) { + throw new BuildException($e, $this->getLocation()); + } else { + $this->log("Caught exception: " . $e, PROJECT_MSG_WARN); + } + } + } + + /** + * + * @return void + * @throws BuildException + */ + public function main() { + + $savedCommand = $this->getCommand(); + + if ($this->getCommand() === null && empty($this->commandlines)) { + // re-implement legacy behaviour: + $this->setCommand(self::$default_command); + } + + $c = $this->getCommand(); + $cloned = null; + if ($c !== null) { + $cloned = $this->cmd->__copy(); + $cloned->createArgument(true)->setLine($c); + $this->addConfiguredCommandline($cloned, true); + } + + try { + for ($i = 0, $vecsize=count($this->commandlines); $i < $vecsize; $i++) { + $this->runCommand($this->commandlines[$i]); + } + + // finally { + if ($cloned !== null) { + $this->removeCommandline($cloned); + } + $this->setCommand($savedCommand); + + } catch (Exception $e) { + // finally { + if ($cloned !== null) { + $this->removeCommandline($cloned); + } + $this->setCommand($savedCommand); + throw $e; + } + } + + /** + * The CVSROOT variable. + * + * @param string $root + */ + public function setCvsRoot($root) { + + // Check if not real cvsroot => set it to null + if ($root !== null) { + if (trim($root) == "") { + $root = null; + } + } + + $this->cvsRoot = $root; + } + + public function getCvsRoot() { + return $this->cvsRoot; + } + + /** + * The CVS_RSH variable. + * + * @param rsh + */ + public function setCvsRsh($rsh) { + // Check if not real cvsrsh => set it to null + if ($rsh !== null) { + if (trim($rsh) == "") { + $rsh = null; + } + } + + $this->cvsRsh = $rsh; + } + + public function getCvsRsh() { + return $this->cvsRsh; + } + + /** + * Port used by CVS to communicate with the server. + * + * @param int $port + */ + public function setPort($port){ + $this->port = $port; + } + + /** + * @return int + */ + public function getPort() { + return $this->port; + } + + /** + * Password file to read passwords from. + * + * @param passFile + */ + public function setPassfile(PhingFile $passFile) { + $this->passFile = $passFile; + } + + /** + * @return File + */ + public function getPassFile() { + return $this->passFile; + } + + /** + * The directory where the checked out files should be placed. + * + * @param PhingFile $dest + */ + public function setDest(PhingFile $dest) { + $this->dest = $dest; + } + + public function getDest() { + return $this->dest; + } + + /** + * The package/module to operate upon. + * + * @param string $p + */ + public function setModule($m) { + $this->cvsModule = $m; + } + + public function getModule(){ + return $this->cvsModule; + } + + /** + * The tag of the package/module to operate upon. + * @param string $p + */ + public function setTag($p) { + // Check if not real tag => set it to null + if ($p !== null && trim($p) !== "") { + $this->appendCommandArgument("-r"); + $this->appendCommandArgument($p); + } + } + + /** + * This needs to be public to allow configuration + * of commands externally. + */ + public function appendCommandArgument($arg) { + $this->cmd->createArgument()->setValue($arg); + } + + /** + * Use the most recent revision no later than the given date. + * @param p + */ + public function setDate($p) { + if ($p !== null && trim($p) !== "") { + $this->appendCommandArgument("-D"); + $this->appendCommandArgument($p); + } + } + + /** + * The CVS command to execute. + * @param string $c + */ + public function setCommand($c) { + $this->command = $c; + } + + public function getCommand() { + return $this->command; + } + + /** + * If true, suppress informational messages. + * @param boolean $q + */ + public function setQuiet($q) { + $this->quiet = $q; + } + + /** + * If true, report only and don't change any files. + * + * @param boolean $ne + */ + public function setNoexec($ne) { + $this->noexec = (boolean) $ne; + } + + /** + * Stop the build process if the command exits with + * a return code other than 0. + * Defaults to false. + * @param boolean $failOnError + */ + public function setFailOnError($failOnError) { + $this->failOnError = (boolean) $failOnError; + } + + /** + * Configure a commandline element for things like cvsRoot, quiet, etc. + * @return string + */ + protected function configureCommandline($c) { + if ($c === null) { + return; + } + $c->setExecutable("cvs"); + + if ($this->cvsModule !== null) { + $c->createArgument()->setLine($this->cvsModule); + } + if ($this->compression > 0 && $this->compression < 10) { + $c->createArgument(true)->setValue("-z" . $this->compression); + } + if ($this->quiet) { + $c->createArgument(true)->setValue("-q"); + } + if ($this->noexec) { + $c->createArgument(true)->setValue("-n"); + } + if ($this->cvsRoot !== null) { + $c->createArgument(true)->setLine("-d" . $this->cvsRoot); + } + } + + protected function removeCommandline(Commandline $c) { + $idx = array_search($c, $this->commandlines, true); + if ($idx === false) { + return false; + } + $this->commandlines = array_splice($this->commandlines, $idx, 1); + return true; + } + + /** + * Configures and adds the given Commandline. + * @param insertAtStart If true, c is + */ + public function addConfiguredCommandline(Commandline $c, $insertAtStart = false) { + if ($c === null) { + return; + } + $this->configureCommandline($c); + if ($insertAtStart) { + array_unshift($this->commandlines, $c); + } else { + array_push($this->commandlines, $c); + } + } + + /** + * If set to a value 1-9 it adds -zN to the cvs command line, else + * it disables compression. + * @param int $level + */ + public function setCompressionLevel($level) { + $this->compression = $level; + } + + /** + * If true, this is the same as compressionlevel="3". + * + * @param boolean $usecomp If true, turns on compression using default + * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL. + */ + public function setCompression($usecomp) { + $this->setCompressionLevel($usecomp ? + self::DEFAULT_COMPRESSION_LEVEL : 0); + } + + /** + * File to which output should be written. + * @param PhingFile $output + */ + function setOutput(PhingFile $f) { + $this->output = $f; + } + + /** + * File to which error output should be written. + * @param PhingFile $output + */ + function setError(PhingFile $f) { + $this->error = $f; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/DeleteTask.php b/gulliver/thirdparty/phing/tasks/system/DeleteTask.php new file mode 100644 index 000000000..c21be0e5b --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/DeleteTask.php @@ -0,0 +1,277 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Deletes a file or directory, or set of files defined by a fileset. + * + * @version $Revision: 1.13 $ + * @package phing.tasks.system + */ +class DeleteTask extends Task { + + protected $file; + protected $dir; + protected $filesets = array(); + protected $includeEmpty = false; + + protected $quiet = false; + protected $failonerror = true; + protected $verbosity = PROJECT_MSG_VERBOSE; + + /** Any filelists of files that should be deleted. */ + private $filelists = array(); + + /** + * Set the name of a single file to be removed. + * @param PhingFile $file + */ + function setFile(PhingFile $file) { + $this->file = $file; + } + + /** + * Set the directory from which files are to be deleted. + * @param PhingFile $dir + */ + function setDir(PhingFile $dir) { + $this->dir = $dir; + } + + /** + * Used to force listing of all names of deleted files. + * @param boolean $verbosity + */ + function setVerbose($verbosity) { + if ($verbosity) { + $this->verbosity = PROJECT_MSG_INFO; + } else { + $this->verbosity = PROJECT_MSG_VERBOSE; + } + } + + /** + * If the file does not exist, do not display a diagnostic + * message or modify the exit status to reflect an error. + * This means that if a file or directory cannot be deleted, + * then no error is reported. This setting emulates the + * -f option to the Unix rm command. Default is false + * meaning things are verbose + */ + function setQuiet($bool) { + $this->quiet = $bool; + if ($this->quiet) { + $this->failonerror = false; + } + } + + /** this flag means 'note errors to the output, but keep going' */ + function setFailOnError($bool) { + $this->failonerror = $bool; + } + + + /** Used to delete empty directories.*/ + function setIncludeEmptyDirs($includeEmpty) { + $this->includeEmpty = (boolean) $includeEmpty; + } + + /** Nested creator, adds a set of files (nested fileset attribute). */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** Nested creator, adds a set of files (nested fileset attribute). */ + function createFileList() { + $num = array_push($this->filelists, new FileList()); + return $this->filelists[$num-1]; + } + + /** Delete the file(s). */ + function main() { + if ($this->file === null && $this->dir === null && count($this->filesets) === 0 && count($this->filelists) === 0) { + throw new BuildException("At least one of the file or dir attributes, or a fileset element, or a filelist element must be set."); + } + + if ($this->quiet && $this->failonerror) { + throw new BuildException("quiet and failonerror cannot both be set to true", $this->location); + } + + // delete a single file + if ($this->file !== null) { + if ($this->file->exists()) { + if ($this->file->isDirectory()) { + $this->log("Directory " . $this->file->__toString() . " cannot be removed using the file attribute. Use dir instead."); + } else { + $this->log("Deleting: " . $this->file->__toString()); + try { + $this->file->delete(); + } catch(Exception $e) { + $message = "Unable to delete file " . $this->file->__toString() .": " .$e->getMessage(); + if($this->failonerror) { + throw new BuildException($message); + } else { + $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + } else { + $this->log("Could not find file " . $this->file->getAbsolutePath() . " to delete.",PROJECT_MSG_VERBOSE); + } + } + + // delete the directory + if ($this->dir !== null && $this->dir->exists() && $this->dir->isDirectory()) { + if ($this->verbosity === PROJECT_MSG_VERBOSE) { + $this->log("Deleting directory " . $this->dir->__toString()); + } + $this->removeDir($this->dir); + } + + // delete the files in the filelists + foreach($this->filelists as $fl) { + try { + $files = $fl->getFiles($this->project); + $this->removeFiles($fl->getDir($this->project), $files, $empty=array()); + } catch (BuildException $be) { + // directory doesn't exist or is not readable + if ($this->failonerror) { + throw $be; + } else { + $this->log($be->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + + // delete the files in the filesets + foreach($this->filesets as $fs) { + try { + $ds = $fs->getDirectoryScanner($this->project); + $files = $ds->getIncludedFiles(); + $dirs = $ds->getIncludedDirectories(); + $this->removeFiles($fs->getDir($this->project), $files, $dirs); + } catch (BuildException $be) { + // directory doesn't exist or is not readable + if ($this->failonerror) { + throw $be; + } else { + $this->log($be->getMessage(), $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + } + + /** + * Recursively removes a directory. + * @param PhingFile $d The directory to remove. + */ + private function removeDir($d) { + $list = $d->listDir(); + if ($list === null) { + $list = array(); + } + + foreach($list as $s) { + $f = new PhingFile($d, $s); + if ($f->isDirectory()) { + $this->removeDir($f); + } else { + $this->log("Deleting " . $f->__toString(), $this->verbosity); + try { + $f->delete(); + } catch (Exception $e) { + $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage(); + if($this->failonerror) { + throw new BuildException($message); + } else { + $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + } + $this->log("Deleting directory " . $d->getAbsolutePath(), $this->verbosity); + try { + $d->delete(); + } catch (Exception $e) { + $message = "Unable to delete directory " . $d->__toString() . ": " . $e->getMessage(); + if($this->failonerror) { + throw new BuildException($message); + } else { + $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + + /** + * remove an array of files in a directory, and a list of subdirectories + * which will only be deleted if 'includeEmpty' is true + * @param PhingFile $d directory to work from + * @param array &$files array of files to delete; can be of zero length + * @param array &$dirs array of directories to delete; can of zero length + */ + private function removeFiles(PhingFile $d, &$files, &$dirs) { + if (count($files) > 0) { + $this->log("Deleting " . count($files) . " files from " . $d->__toString()); + for ($j=0,$_j=count($files); $j < $_j; $j++) { + $f = new PhingFile($d, $files[$j]); + $this->log("Deleting " . $f->getAbsolutePath(), $this->verbosity); + try { + $f->delete(); + } catch (Exception $e) { + $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage(); + if($this->failonerror) { + throw new BuildException($message); + } else { + $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + + } + } + + if (count($dirs) > 0 && $this->includeEmpty) { + $dirCount = 0; + for ($j=count($dirs)-1; $j>=0; --$j) { + $dir = new PhingFile($d, $dirs[$j]); + $dirFiles = $dir->listDir(); + if ($dirFiles === null || count($dirFiles) === 0) { + $this->log("Deleting " . $dir->__toString(), $this->verbosity); + try { + $dir->delete(); + $dirCount++; + } catch (Exception $e) { + $message="Unable to delete directory " + $dir; + if($this->failonerror) { + throw new BuildException($message); + } else { + $this->log($message, $this->quiet ? PROJECT_MSG_VERBOSE : PROJECT_MSG_WARN); + } + } + } + } + if ($dirCount > 0) { + $this->log("Deleted $dirCount director" . ($dirCount==1 ? "y" : "ies") . " from " . $d->__toString()); + } + } + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/EchoTask.php b/gulliver/thirdparty/phing/tasks/system/EchoTask.php new file mode 100644 index 000000000..5d1fa92db --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/EchoTask.php @@ -0,0 +1,107 @@ +. + */ + +include_once 'phing/Task.php'; + +/** + * Echos a message to the logging system or to a file + * + * @author Michiel Rook + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.5 $ $Date: 2006-07-07 20:15:35 +0200 (Fri, 07 Jul 2006) $ + * @package phing.tasks.system + */ + +class EchoTask extends Task { + + protected $msg = ""; + + protected $file = ""; + + protected $append = false; + + protected $level = "info"; + + function main() { + switch ($this->level) + { + case "error": $loglevel = PROJECT_MSG_ERR; break; + case "warning": $loglevel = PROJECT_MSG_WARN; break; + case "info": $loglevel = PROJECT_MSG_INFO; break; + case "verbose": $loglevel = PROJECT_MSG_VERBOSE; break; + case "debug": $loglevel = PROJECT_MSG_DEBUG; break; + } + + if (empty($this->file)) + { + $this->log($this->msg, $loglevel); + } + else + { + if ($this->append) + { + $handle = fopen($this->file, "a"); + } + else + { + $handle = fopen($this->file, "w"); + } + + fwrite($handle, $this->msg); + + fclose($handle); + } + } + + /** setter for file */ + function setFile($file) + { + $this->file = (string) $file; + } + + /** setter for level */ + function setLevel($level) + { + $this->level = (string) $level; + } + + /** setter for append */ + function setAppend($append) + { + $this->append = $append; + } + + /** setter for message */ + function setMsg($msg) { + $this->setMessage($msg); + } + + /** alias setter */ + function setMessage($msg) { + $this->msg = (string) $msg; + } + + /** Supporting the Message syntax. */ + function addText($msg) + { + $this->msg = (string) $msg; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/ExecTask.php b/gulliver/thirdparty/phing/tasks/system/ExecTask.php new file mode 100644 index 000000000..9c72d639d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ExecTask.php @@ -0,0 +1,248 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Executes a command on the shell. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.17 $ + * @package phing.tasks.system + */ +class ExecTask extends Task { + + /** + * Command to execute. + * @var string + */ + protected $command; + + /** + * Working directory. + * @var File + */ + protected $dir; + + /** + * Operating system. + * @var string + */ + protected $os; + + /** + * Whether to escape shell command using escapeshellcmd(). + * @var boolean + */ + protected $escape = false; + + /** + * Where to direct output. + * @var File + */ + protected $output; + + /** + * Whether to passthru the output + * @var boolean + */ + protected $passthru = false; + + /** + * Where to direct error output. + * @var File + */ + protected $error; + + /** + * If spawn is set then [unix] programs will redirect stdout and add '&'. + * @var boolean + */ + protected $spawn = false; + + /** + * Whether to check the return code. + * @var boolean + */ + protected $checkreturn = false; + + /** + * Main method: wraps execute() command. + * @return void + */ + public function main() { + $this->execute(); + } + + /** + * Executes a program and returns the return code. + * Output from command is logged at INFO level. + * @return int Return code from execution. + */ + public function execute() { + + // test if os match + $myos = Phing::getProperty("os.name"); + $this->log("Myos = " . $myos, PROJECT_MSG_VERBOSE); + if (($this->os !== null) && (strpos($os, $myos) === false)) { + // this command will be executed only on the specified OS + $this->log("Not found in " . $os, PROJECT_MSG_VERBOSE); + return 0; + } + + if ($this->dir !== null) { + if ($this->dir->isDirectory()) { + $currdir = getcwd(); + @chdir($this->dir->getPath()); + } else { + throw new BuildException("Can't chdir to:" . $this->dir->__toString()); + } + } + + + if ($this->escape == true) { + // FIXME - figure out whether this is correct behavior + $this->command = escapeshellcmd($this->command); + } + + if ($this->error !== null) { + $this->command .= ' 2> ' . $this->error->getPath(); + $this->log("Writing error output to: " . $this->error->getPath()); + } + + if ($this->output !== null) { + $this->command .= ' 1> ' . $this->output->getPath(); + $this->log("Writing standard output to: " . $this->output->getPath()); + } elseif ($this->spawn) { + $this->command .= ' 1>/dev/null'; + $this->log("Sending ouptut to /dev/null"); + } + + // If neither output nor error are being written to file + // then we'll redirect error to stdout so that we can dump + // it to screen below. + + if ($this->output === null && $this->error === null) { + $this->command .= ' 2>&1'; + } + + // we ignore the spawn boolean for windows + if ($this->spawn) { + $this->command .= ' &'; + } + + $this->log("Executing command: " . $this->command); + + $output = array(); + $return = null; + exec($this->command, $output, $return); + + if ($this->dir !== null) { + @chdir($currdir); + } + + foreach($output as $line) { + $this->log($line, ($this->passthru ? PROJECT_MSG_INFO : PROJECT_MSG_VERBOSE)); + } + + if($return != 0 && $this->checkreturn) + { + throw new BuildException("Task exited with code $return"); + } + + return $return; + } + + /** + * The command to use. + * @param mixed $command String or string-compatible (e.g. w/ __toString()). + */ + function setCommand($command) { + $this->command = "" . $command; + } + + /** + * Whether to use escapeshellcmd() to escape command. + * @param boolean $escape + */ + function setEscape($escape) { + $this->escape = (bool) $escape; + } + + /** + * Specify the working directory for executing this command. + * @param PhingFile $dir + */ + function setDir(PhingFile $dir) { + $this->dir = $dir; + } + + /** + * Specify OS (or muliple OS) that must match in order to execute this command. + * @param string $os + */ + function setOs($os) { + $this->os = (string) $os; + } + + /** + * File to which output should be written. + * @param PhingFile $output + */ + function setOutput(PhingFile $f) { + $this->output = $f; + } + + /** + * File to which error output should be written. + * @param PhingFile $output + */ + function setError(PhingFile $f) { + $this->error = $f; + } + + /** + * Whether to use passthru the output. + * @param boolean $passthru + */ + function setPassthru($passthru) { + $this->passthru = (bool) $passthru; + } + + /** + * Whether to suppress all output and run in the background. + * @param boolean $spawn + */ + function setSpawn($spawn) { + $this->spawn = (bool) $spawn; + } + + /** + * Whether to check the return code. + * @param boolean $checkreturn + */ + function setCheckreturn($checkreturn) { + $this->checkreturn = (bool) $checkreturn; + } +} + diff --git a/gulliver/thirdparty/phing/tasks/system/ExitTask.php b/gulliver/thirdparty/phing/tasks/system/ExitTask.php new file mode 100644 index 000000000..b0e39e544 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ExitTask.php @@ -0,0 +1,118 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Exits the active build, giving an additional message + * if available. + * + * @author Hans Lellelid (Phing) + * @author Nico Seessle (Ant) + * @version $Revision: 1.7 $ + * @package phing.tasks.system + */ +class ExitTask extends Task { + + private $message; + private $ifCondition; + private $unlessCondition; + + /** + * A message giving further information on why the build exited. + * + * @param string $value message to output + */ + public function setMsg($value) { + $this->setMessage($value); + } + + /** + * A message giving further information on why the build exited. + * + * @param value message to output + */ + public function setMessage($value) { + $this->message = $value; + } + + /** + * Only fail if a property of the given name exists in the current project. + * @param c property name + */ + public function setIf($c) { + $this->ifCondition = $c; + } + + /** + * Only fail if a property of the given name does not + * exist in the current project. + * @param c property name + */ + public function setUnless($c) { + $this->unlessCondition = $c; + } + + /** + * @throws BuildException + */ + public function main() { + if ($this->testIfCondition() && $this->testUnlessCondition()) { + if ($this->message !== null) { + throw new BuildException($this->message); + } else { + throw new BuildException("No message"); + } + } + } + + /** + * Set a multiline message. + */ + public function addText($msg) { + if ($this->message === null) { + $this->message = ""; + } + $this->message .= $this->project->replaceProperties($msg); + } + + /** + * @return boolean + */ + private function testIfCondition() { + if ($this->ifCondition === null || $this->ifCondition === "") { + return true; + } + + return $this->project->getProperty($this->ifCondition) !== null; + } + + /** + * @return boolean + */ + private function testUnlessCondition() { + if ($this->unlessCondition === null || $this->unlessCondition === "") { + return true; + } + return $this->project->getProperty($this->unlessCondition) === null; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/ForeachTask.php b/gulliver/thirdparty/phing/tasks/system/ForeachTask.php new file mode 100644 index 000000000..8b32095ed --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ForeachTask.php @@ -0,0 +1,138 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/tasks/system/PhingTask.php'; + +/** + * task + * + * Task definition for the foreach task. This task takes a list with + * delimited values, and executes a target with set param. + * + * Usage: + * + * + * Attributes: + * list --> The list of values to process, with the delimiter character, + * indicated by the "delimiter" attribute, separating each value. + * target --> The target to call for each token, passing the token as the + * parameter with the name indicated by the "param" attribute. + * param --> The name of the parameter to pass the tokens in as to the + * target. + * delimiter --> The delimiter string that separates the values in the "list" + * parameter. The default is ",". + * + * @author Jason Hines + * @author Hans Lellelid + * @version $Revision: 1.9 $ + * @package phing.tasks.system + */ +class ForeachTask extends Task { + + /** Delimter-separated list of values to process. */ + private $list; + + /** Name of parameter to pass to callee */ + private $param; + + /** Delimter that separates items in $list */ + private $delimiter = ','; + + /** + * PhingCallTask that will be invoked w/ calleeTarget. + * @var PhingCallTask + */ + private $callee; + + /** + * Target to execute. + * @var string + */ + private $calleeTarget; + + function init() { + $this->callee = $this->project->createTask("phingcall"); + $this->callee->setOwningTarget($this->getOwningTarget()); + $this->callee->setTaskName($this->getTaskName()); + $this->callee->setLocation($this->getLocation()); + $this->callee->init(); + } + + /** + * This method does the work. + * @return void + */ + function main() { + if ($this->list === null) { + throw new BuildException("Missing list to iterate through"); + } + if (trim($this->list) === '') { + return; + } + if ($this->param === null) { + throw new BuildException("You must supply a property name to set on each iteration in param"); + } + if ($this->calleeTarget === null) { + throw new BuildException("You must supply a target to perform"); + } + + $callee = $this->callee; + $callee->setTarget($this->calleeTarget); + $callee->setInheritAll(true); + $callee->setInheritRefs(true); + + $arr = explode($this->delimiter, $this->list); + + foreach ($arr as $value) { + $this->log("Setting param '$this->param' to value '$value'", PROJECT_MSG_VERBOSE); + $prop = $callee->createProperty(); + $prop->setOverride(true); + $prop->setName($this->param); + $prop->setValue($value); + $callee->main(); + } + } + + function setList($list) { + $this->list = (string) $list; + } + + function setTarget($target) { + $this->calleeTarget = (string) $target; + } + + function setParam($param) { + $this->param = (string) $param; + } + + function setDelimiter($delimiter) { + $this->delimiter = (string) $delimiter; + } + + /** + * @return Property + */ + function createProperty() { + return $this->callee->createProperty(); + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/IfTask.php b/gulliver/thirdparty/phing/tasks/system/IfTask.php new file mode 100644 index 000000000..cded6e010 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/IfTask.php @@ -0,0 +1,224 @@ +. + */ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; +require_once 'phing/tasks/system/SequentialTask.php'; + +/** + * Perform some tasks based on whether a given condition holds true or + * not. + * + *

    This task is heavily based on the Condition framework that can + * be found in Ant 1.4 and later, therefore it cannot be used in + * conjunction with versions of Ant prior to 1.4.

    + * + *

    This task doesn't have any attributes, the condition to test is + * specified by a nested element - see the documentation of your + * task (see + * the + * online documentation for example) for a complete list of nested + * elements.

    + * + *

    Just like the task, only a single + * condition can be specified - you combine them using + * or conditions.

    + * + *

    In addition to the condition, you can specify three different + * child elements, , and + * . All three subelements are optional. + * + * Both and must not be + * used more than once inside the if task. Both are + * containers for Ant tasks, just like Ant's + * and + * tasks - in fact they are implemented using the same class as Ant's + * task.

    + * + * The behaves exactly like an + * except that it cannot contain the element + * inside of it. You may specify as may of these as you like, and the + * order they are specified is the order they are evaluated in. If the + * condition on the is false, then the first + * who's conditional evaluates to true + * will be executed. The will be executed + * only if the and all + * conditions are false. + * + *

    Use the following task to define the + * task before you use it the first time:

    + * + *
    
    + *   
    + * + *

    Crude Example

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @author Stefan Bodewig + */ +class IfTask extends ConditionBase { + + + private $thenTasks = null; + private $elseIfTasks = array(); + private $elseTasks = null; + + /*** + * A nested Else if task + */ + public function addElseIf(ElseIfTask $ei) + { + $this->elseIfTasks[] = $ei; + } + + /** + * A nested element - a container of tasks that will + * be run if the condition holds true. + * + *

    Not required.

    + */ + public function addThen(SequentialTask $t) { + if ($this->thenTasks != null) { + throw new BuildException("You must not nest more than one into "); + } + $this->thenTasks = $t; + } + + /** + * A nested element - a container of tasks that will + * be run if the condition doesn't hold true. + * + *

    Not required.

    + */ + public function addElse(SequentialTask $e) { + if ($this->elseTasks != null) { + throw new BuildException("You must not nest more than one into "); + } + $this->elseTasks = $e; + } + + public function main() { + + if ($this->countConditions() > 1) { + throw new BuildException("You must not nest more than one condition into "); + } + if ($this->countConditions() < 1) { + throw new BuildException("You must nest a condition into "); + } + $conditions = $this->getConditions(); + $c = $conditions[0]; + + if ($c->evaluate()) { + if ($this->thenTasks != null) { + $this->thenTasks->main(); + } + } else { + $done = false; + $sz = count($this->elseIfTasks); + for($i=0; $i < $sz && !$done; $i++) { + $ei = $this->elseIfTasks[$i]; + if ($ei->evaluate()) { + $done = true; + $ei->main(); + } + } + + if (!$done && $this->elseTasks != null) { + $this->elseTasks->main(); + } + } + } +} + +/** + * "Inner" class for IfTask. + * This class has same basic structure as the IfTask, although of course it doesn't support tags. + */ +class ElseIfTask extends ConditionBase { + + private $thenTasks = null; + + public function addThen(SequentialTask $t) { + if ($this->thenTasks != null) { + throw new BuildException("You must not nest more than one into "); + } + $this->thenTasks = $t; + } + + /** + * @return boolean + */ + public function evaluate() { + + if ($this->countConditions() > 1) { + throw new BuildException("You must not nest more than one condition into "); + } + if ($this->countConditions() < 1) { + throw new BuildException("You must nest a condition into "); + } + + $conditions = $this->getConditions(); + $c = $conditions[0]; + + return $c->evaluate(); + } + + /** + * + */ + public function main() { + if ($this->thenTasks != null) { + $this->thenTasks->main(); + } + } + } \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/system/IncludePathTask.php b/gulliver/thirdparty/phing/tasks/system/IncludePathTask.php new file mode 100644 index 000000000..c8fcf1535 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/IncludePathTask.php @@ -0,0 +1,115 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/types/Path.php'; + +/** + * Adds a normalized path to the PHP include_path. + * + * This provides a way to alter the include_path without editing any global php.ini settings + * or PHP_CLASSPATH environment variable. + * + * + * + * + * + * @author Hans Lellelid + * @version $Revision: 1.1 $ + * @package phing.tasks.system + */ +class IncludePathTask extends Task { + + /** + * Classname of task to register. + * This can be a dot-path -- relative to a location on PHP include_path. + * E.g. path.to.MyClass -> path/to/MyClass.php + * @var string + */ + private $classname; + + /** + * Path to add to PHP include_path to aid in finding specified class. + * @var Path + */ + private $classpath; + + /** + * Refid to already defined classpath + */ + private $classpathId; + + /** + * Set the classpath to be used when searching for component being defined + * + * @param Path $classpath An Path object containing the classpath. + */ + public function setClasspath(Path $classpath) { + if ($this->classpath === null) { + $this->classpath = $classpath; + } else { + $this->classpath->append($classpath); + } + } + + /** + * Create the classpath to be used when searching for component being defined + */ + public function createClasspath() { + if ($this->classpath === null) { + $this->classpath = new Path($this->project); + } + return $this->classpath->createPath(); + } + + /** + * Reference to a classpath to use when loading the files. + */ + public function setClasspathRef(Reference $r) { + $this->classpathId = $r->getRefId(); + $this->createClasspath()->setRefid($r); + } + + + /** Main entry point */ + public function main() { + + // Apparently casting to (string) no longer invokes __toString() automatically. + if (is_object($this->classpath)) { + $this->classpath = $this->classpath->__toString(); + } + + if (empty($this->classpath)) { + throw new BuildException("Provided classpath was empty."); + } + + $curr_parts = explode(PATH_SEPARATOR, get_include_path()); + $add_parts = explode(PATH_SEPARATOR, $this->classpath); + $new_parts = array_diff($add_parts, $curr_parts); + + if ($new_parts) { + $this->log("Prepending new include_path components: " . implode(PATH_SEPARATOR, $new_parts), PROJECT_MSG_VERBOSE); + set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts))); + } + + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/InputTask.php b/gulliver/thirdparty/phing/tasks/system/InputTask.php new file mode 100644 index 000000000..573f391fe --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/InputTask.php @@ -0,0 +1,146 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/input/InputRequest.php'; +include_once 'phing/input/YesNoInputRequest.php'; +include_once 'phing/input/MultipleChoiceInputRequest.php'; + +/** + * Reads input from the InputHandler. + * + * @see Project::getInputHandler() + * @author Hans Lellelid (Phing) + * @author Ulrich Schmidt (Ant) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.6 $ + * @package phing.tasks.system + */ +class InputTask extends Task { + + private $validargs; + private $message = ""; // required + private $propertyName; // required + private $defaultValue; + private $promptChar; + + /** + * Defines valid input parameters as comma separated strings. If set, input + * task will reject any input not defined as accepted and requires the user + * to reenter it. Validargs are case sensitive. If you want 'a' and 'A' to + * be accepted you need to define both values as accepted arguments. + * + * @param validargs A comma separated String defining valid input args. + */ + public function setValidargs ($validargs) { + $this->validargs = $validargs; + } + + /** + * Defines the name of a property to be set from input. + * + * @param string $name Name for the property to be set from input + */ + public function setPropertyName($name) { + $this->propertyName = $name; + } + + /** + * Sets the Message which gets displayed to the user during the build run. + * @param message The message to be displayed. + */ + public function setMessage ($message) { + $this->message = $message; + } + + /** + * Set a multiline message. + */ + public function addText($msg) { + $this->message .= $this->project->replaceProperties($msg); + } + + /** + * Add a default value. + * @param string $v + */ + public function setDefaultValue($v) { + $this->defaultValue = $v; + } + + /** + * Set the character/string to use for the prompt. + * @param string $c + */ + public function setPromptChar($c) { + $this->promptChar = $c; + } + + /** + * Actual method executed by phing. + * @throws BuildException + */ + public function main() { + + if ($this->propertyName === null) { + throw new BuildException("You must specify a value for propertyName attribute."); + } + + if ($this->validargs !== null) { + $accept = preg_split('/[\s,]+/', $this->validargs); + + // is it a boolean (yes/no) inputrequest? + $yesno = false; + if (count($accept) == 2) { + $yesno = true; + foreach($accept as $ans) { + if(!StringHelper::isBoolean($ans)) { + $yesno = false; + break; + } + } + } + if ($yesno) $request = new YesNoInputRequest($this->message, $accept); + else $request = new MultipleChoiceInputRequest($this->message, $accept); + } else { + $request = new InputRequest($this->message); + } + + // default default is curr prop value + $request->setDefaultValue($this->project->getProperty($this->propertyName)); + + $request->setPromptChar($this->promptChar); + + // unless overridden... + if ($this->defaultValue !== null) { + $request->setDefaultValue($this->defaultValue); + } + + $this->project->getInputHandler()->handleInput($request); + + $value = $request->getInput(); + + if ($value !== null) { + $this->project->setUserProperty($this->propertyName, $value); + } + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/MatchingTask.php b/gulliver/thirdparty/phing/tasks/system/MatchingTask.php new file mode 100644 index 000000000..d6ef6568c --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/MatchingTask.php @@ -0,0 +1,361 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/types/selectors/SelectorContainer.php'; +include_once 'phing/types/FileSet.php'; +include_once 'phing/types/PatternSet.php'; +include_once 'phing/util/DirectoryScanner.php'; + +/** + * This is an abstract task that should be used by all those tasks that + * require to include or exclude files based on pattern matching. + * + * This is very closely based on the ANT class of the same name. + * + * @author Hans Lellelid (Phing) + * @author Arnout J. Kuiper (Ant) + * @author Stefano Mazzocchi (Ant) + * @author Sam Ruby (Ant) + * @author Jon S. Stevens (Ant + * @author Stefan Bodewig (Ant) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.4 $ + * @package phing.tasks.system + */ +abstract class MatchingTask extends Task implements SelectorContainer { + + /** @var boolean */ + protected $useDefaultExcludes = true; + + /** @var FileSet */ + protected $fileset; + + /** + * Create instance; set fileset to new FileSet. + */ + public function __construct() { + $this->fileset = new FileSet(); + } + + /** + * @see ProjectComponent::setProject() + */ + public function setProject(Project $project) { + parent::setProject($project); + $this->fileset->setProject($project); + } + + /** + * add a name entry on the include list + * @return PatternSetNameEntry + */ + public function createInclude() { + return $this->fileset->createInclude(); + } + + /** + * add a name entry on the include files list + * @return PatternSetNameEntry + */ + public function createIncludesFile() { + return $this->fileset->createIncludesFile(); + } + + /** + * add a name entry on the exclude list + * @return PatternSetNameEntry + */ + public function createExclude() { + return $this->fileset->createExclude(); + } + + /** + * add a name entry on the include files list + * @return PatternSetNameEntry + */ + public function createExcludesFile() { + return $this->fileset->createExcludesFile(); + } + + /** + * add a set of patterns + * @return PatternSet + */ + public function createPatternSet() { + return $this->fileset->createPatternSet(); + } + + /** + * Sets the set of include patterns. Patterns may be separated by a comma + * or a space. + * + * @param string $includes the string containing the include patterns + * @return void + */ + public function setIncludes($includes) { + $this->fileset->setIncludes($includes); + } + + /** + * Sets the set of exclude patterns. Patterns may be separated by a comma + * or a space. + * + * @param string $excludes the string containing the exclude patterns + */ + public function setExcludes($excludes) { + $this->fileset->setExcludes($excludes); + } + + + /** + * Sets whether default exclusions should be used or not. + * + * @param boolean $useDefaultExcludes "true"|"on"|"yes" when default exclusions + * should be used, "false"|"off"|"no" when they + * shouldn't be used. + */ + public function setDefaultexcludes($useDefaultExcludes) { + $this->useDefaultExcludes = (boolean) $useDefaultExcludes; + } + + /** + * Returns the directory scanner needed to access the files to process. + * @return DirectoryScanner + */ + protected function getDirectoryScanner(PhingFile $baseDir) { + $this->fileset->setDir($baseDir); + $this->fileset->setDefaultexcludes($this->useDefaultExcludes); + return $this->fileset->getDirectoryScanner($this->project); + } + + /** + * Sets the name of the file containing the includes patterns. + * + * @param PhingFile $includesfile A string containing the filename to fetch + * the include patterns from. + * @return void + */ + public function setIncludesfile(PhingFile $includesfile) { + $this->fileset->setIncludesfile(includesfile); + } + + /** + * Sets the name of the file containing the includes patterns. + * + * @param PhingFile $excludesfile A string containing the filename to fetch + * the include patterns from. + * @return void + */ + public function setExcludesfile(PhingFile $excludesfile) { + $this->fileset->setExcludesfile($excludesfile); + } + + /** + * Sets case sensitivity of the file system + * + * @param boolean $isCaseSensitive "true"|"on"|"yes" if file system is case + * sensitive, "false"|"off"|"no" when not. + * @return void + */ + public function setCaseSensitive($isCaseSensitive) { + $this->fileset->setCaseSensitive($isCaseSensitive); + } + + /** + * Sets whether or not symbolic links should be followed. + * + * @param boolean $followSymlinks whether or not symbolic links should be followed + * @return void + */ + public function setFollowSymlinks($followSymlinks) { + $this->fileset->setFollowSymlinks($followSymlinks); + } + + /** + * Indicates whether there are any selectors here. + * + * @return boolean Whether any selectors are in this container + */ + public function hasSelectors() { + return $this->fileset->hasSelectors(); + } + + /** + * Gives the count of the number of selectors in this container + * + * @return int The number of selectors in this container + */ + public function selectorCount() { + return $this->fileset->selectorCount(); + } + + /** + * Returns the set of selectors as an array. + * + * @return array FileSelector[] An array of selectors in this container + */ + public function getSelectors(Project $p) { + return $this->fileset->getSelectors($p); + } + + /** + * Returns an enumerator for accessing the set of selectors. + * + * @return an enumerator that goes through each of the selectors + */ + public function selectorElements() { + return $this->fileset->selectorElements(); + } + + /** + * Add a new selector into this container. + * + * @param FileSelector $selector the new selector to add + * @return void + */ + public function appendSelector(FileSelector $selector) { + $this->fileset->appendSelector($selector); + } + + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + * @return SelectSelector + */ + public function createSelector() { + return $this->fileset->createSelector(); + } + + /** + * add an "And" selector entry on the selector list + * @return AndSelector + */ + public function createAnd() { + return $this->fileset->createAnd(); + } + + /** + * add an "Or" selector entry on the selector list + * @return void + */ + public function createOr() { + return $this->fileset->createOr(); + } + + /** + * add a "Not" selector entry on the selector list + * @return NotSelector + */ + public function createNot() { + return $this->fileset->createNot(); + } + + /** + * add a "None" selector entry on the selector list + * @return NoneSelector + */ + public function createNone() { + return $this->fileset->createNone(); + } + + /** + * add a majority selector entry on the selector list + * @return MajoritySelector + */ + public function createMajority() { + return $this->fileset->createMajority(); + } + + /** + * add a selector date entry on the selector list + * @return DateSelector + */ + public function createDate() { + return $this->fileset->addDate(); + } + + /** + * add a selector size entry on the selector list + * @return SizeSelector + */ + public function createSize() { + return $this->fileset->createSize(); + } + + /** + * add a selector filename entry on the selector list + * @return FilenameSelector + */ + public function createFilename() { + return $this->fileset->createFilename(); + } + + /** + * add an extended selector entry on the selector list + * @return ExtendSelector + */ + public function createCustom() { + return $this->fileset->createCustom(); + } + + /** + * add a contains selector entry on the selector list + * @return ContainsSelector + */ + public function createContains() { + return $this->fileset->createContains(); + } + + /** + * add a present selector entry on the selector list + * @return PresentSelector + */ + public function createPresent() { + return $this->fileset->createPresent(); + } + + /** + * add a depth selector entry on the selector list + * @return DepthSelector + */ + public function createDepth() { + return $this->fileset->createDepth(); + } + + /** + * add a depends selector entry on the selector list + * @return DependSelector + */ + public function createDepend() { + return $this->fileset->createDepend(); + } + + /** + * Accessor for the implict fileset. + * + * @return FileSet + */ + protected final function getImplicitFileSet() { + return $this->fileset; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/MkdirTask.php b/gulliver/thirdparty/phing/tasks/system/MkdirTask.php new file mode 100644 index 000000000..b55f60c7d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/MkdirTask.php @@ -0,0 +1,64 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/system/io/PhingFile.php'; + +/** + * Task to create a directory. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.8 $ + * @package phing.tasks.system + */ +class MkdirTask extends Task { + + /** directory to create*/ + private $dir; + + /** + * create the directory and all parents + * + * @throws BuildException if dir is somehow invalid, or creation failed. + */ + function main() { + if ($this->dir === null) { + throw new BuildException("dir attribute is required", $this->location); + } + if ($this->dir->isFile()) { + throw new BuildException("Unable to create directory since a file already exists with that name: " . $this->dir->getAbsolutePath()); + } + if (!$this->dir->exists()) { + $result = $this->dir->mkdirs(); + if (!$result) { + $msg = "Directory " . $this->dir->getAbsolutePath() . " creation was not successful for an unknown reason"; + throw new BuildException($msg, $this->location); + } + $this->log("Created dir: " . $this->dir->getAbsolutePath()); + } + } + + /** the directory to create; required. */ + function setDir(PhingFile $dir) { + $this->dir = $dir; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/MoveTask.php b/gulliver/thirdparty/phing/tasks/system/MoveTask.php new file mode 100644 index 000000000..84ff37ba9 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/MoveTask.php @@ -0,0 +1,197 @@ +. + */ + +require_once 'phing/tasks/system/CopyTask.php'; +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/IOException.php'; + +/** + * Moves a file or directory to a new file or directory. + * + * By default, the destination file is overwritten if it + * already exists. When overwrite is turned off, then files + * are only moved if the source file is newer than the + * destination file, or when the destination file does not + * exist. + * + * Source files and directories are only deleted when the file or + * directory has been copied to the destination successfully. + * + * @version $Revision: 1.8 $ + * @package phing.tasks.system + */ +class MoveTask extends CopyTask { + + function __construct() { + parent::__construct(); + $this->forceOverwrite = true; + } + + protected function doWork() { + + $copyMapSize = count($this->fileCopyMap); + if ($copyMapSize > 0) { + // files to move + $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath()); + + foreach($this->fileCopyMap as $from => $to) { + if ($from == $to) { + $this->log("Skipping self-move of $from", $this->verbosity); + continue; + } + + $moved = false; + $f = new PhingFile($from); + $d = new PhingFile($to); + + $moved = false; + try { // try to rename + $this->log("Attempting to rename $from to $to", $this->verbosity); + $this->renameFile($f, $d, $this->forceOverwrite); + $moved = true; + } catch (IOException $ioe) { + $moved = false; + $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity); + } + + if (!$moved) { + try { // try to move + $this->log("Moving $from to $to", $this->verbosity); + + $this->fileUtils->copyFile($f, $d, $this->forceOverwrite, $this->preserveLMT, $this->filterChains, $this->getProject()); + + $f = new PhingFile($fromFile); + $f->delete(); + } catch (IOException $ioe) { + $msg = "Failed to move $from to $to: " . $ioe->getMessage(); + throw new BuildException($msg, $this->location); + } + } // if !moved + } // foreach fileCopyMap + } // if copyMapSize + + // handle empty dirs if appropriate + if ($this->includeEmpty) { + $e = array_keys($this->dirCopyMap); + $count = 0; + foreach ($e as $dir) { + $d = new PhingFile((string) $dir); + if (!$d->exists()) { + if (!$d->mkdirs()) { + $this->log("Unable to create directory " . $d->getAbsolutePath(), PROJECT_MSG_ERR); + } else { + $count++; + } + } + } + if ($count > 0) { + $this->log("moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath()); + } + } + + if (count($this->filesets) > 0) { + // process filesets + foreach($this->filesets as $fs) { + $dir = $fs->getDir($this->project); + if ($this->okToDelete($dir)) { + $this->deleteDir($dir); + } + } + } + } + + /** Its only ok to delete a dir tree if there are no files in it. */ + private function okToDelete($d) { + $list = $d->listDir(); + if ($list === null) { + return false; // maybe io error? + } + + foreach($list as $s) { + $f = new PhingFile($d, $s); + if ($f->isDirectory()) { + if (!$this->okToDelete($f)) { + return false; + } + } else { + // found a file + return false; + } + } + return true; + } + + /** Go and delete the directory tree. */ + private function deleteDir($d) { + + $list = $d->listDir(); + if ($list === null) { + return; // on an io error list() can return null + } + + foreach($list as $fname) { + $f = new PhingFile($d, $fname); + if ($f->isDirectory()) { + $this->deleteDir($f); + } else { + throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!"); + } + } + + $this->log("Deleting directory " . $d->getPath(), $this->verbosity); + try { + $d->delete(); + } catch (Exception $e) { + throw new BuildException("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage()); + } + } + + /** + * Attempts to rename a file from a source to a destination. + * If overwrite is set to true, this method overwrites existing file + * even if the destination file is newer. + * Otherwise, the source f + * ile is renamed only if the destination file # + * is older than it. + */ + private function renameFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite) { + $renamed = true; + + // ensure that parent dir of dest file exists! + $parent = $destFile->getParentFile(); + if ($parent !== null) { + if (!$parent->exists()) { + $parent->mkdirs(); + } + } + if ($destFile->exists()) { + try { + $destFile->delete(); + } catch (Exception $e) { + throw new BuildException("Unable to remove existing file " . $destFile->__toString() . ": " . $e->getMessage()); + } + } + $renamed = $sourceFile->renameTo($destFile); + + return $renamed; + } +} +?> diff --git a/gulliver/thirdparty/phing/tasks/system/PhingCallTask.php b/gulliver/thirdparty/phing/tasks/system/PhingCallTask.php new file mode 100644 index 000000000..18cb680f0 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/PhingCallTask.php @@ -0,0 +1,139 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Call another target in the same project. + * + *
    + *    
    + *      
    + *        
    + *        
    + *       
    + *    
    + *
    + *    
    + *      
    + *    
    + *  
    + * + *

    This only works as expected if neither property1 nor foo are + * defined in the project itself. + * + * @author Andreas Aderhold + * @copyright 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.9 $ + * @access public + * @package phing.tasks.system + */ +class PhingCallTask extends Task { + + private $callee; + private $subTarget; + // must match the default value of PhingTask#inheritAll + private $inheritAll = true; + // must match the default value of PhingTask#inheritRefs + private $inheritRefs = false; + + /** + * If true, pass all properties to the new Phing project. + * Defaults to true. Future use. + * @param boolean new value + */ + function setInheritAll($inherit) { + $this->inheritAll = (boolean) $inherit; + } + + /** + * If true, pass all references to the new Phing project. + * Defaults to false. Future use. + * + * @param boolean new value + */ + function setInheritRefs($inheritRefs) { + $this->inheritRefs = (boolean) $inheritRefs; + } + + /** + * init this task by creating new instance of the phing task and + * configuring it's by calling its own init method. + */ + function init() { + $this->callee = $this->project->createTask("phing"); + $this->callee->setOwningTarget($this->getOwningTarget()); + $this->callee->setTaskName($this->getTaskName()); + $this->callee->setLocation($this->getLocation()); + $this->callee->init(); + } + + /** + * hand off the work to the phing task of ours, after setting it up + * @throws BuildException on validation failure or if the target didn't + * execute + */ + function main() { + + $this->log("Running PhingCallTask for target '" . $this->subTarget . "'", PROJECT_MSG_DEBUG); + if ($this->callee === null) { + $this->init(); + } + + if ($this->subTarget === null) { + throw new BuildException("Attribute target is required.", $this->location); + } + + $this->callee->setPhingfile($this->project->getProperty("phing.file")); + $this->callee->setTarget($this->subTarget); + $this->callee->setInheritAll($this->inheritAll); + $this->callee->setInheritRefs($this->inheritRefs); + $this->callee->main(); + } + + /** + * Alias for createProperty + * @see createProperty() + */ + function createParam() { + if ($this->callee === null) { + $this->init(); + } + return $this->callee->createProperty(); + } + + /** + * Property to pass to the invoked target. + */ + function createProperty() { + if ($this->callee === null) { + $this->init(); + } + return $this->callee->createProperty(); + } + + /** + * Target to execute, required. + */ + function setTarget($target) { + $this->subTarget = (string) $target; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/PhingTask.php b/gulliver/thirdparty/phing/tasks/system/PhingTask.php new file mode 100644 index 000000000..2b11dc1ef --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/PhingTask.php @@ -0,0 +1,618 @@ +. +*/ + +include_once 'phing/Task.php'; +include_once 'phing/util/FileUtils.php'; +include_once 'phing/types/Reference.php'; +include_once 'phing/tasks/system/PropertyTask.php'; + +/** + * Task that invokes phing on another build file. + * + * Use this task, for example, if you have nested buildfiles in your project. Unlike + * AntTask, PhingTask can even support filesets: + * + *

    + *   
    + *    
    + *       
    + *      
    + *    
    + *   
    + * 
    + * + * @author Hans Lellelid + * @version $Revision: 1.20 $ + * @package phing.tasks.system + */ +class PhingTask extends Task { + + /** the basedir where is executed the build file */ + private $dir; + + /** build.xml (can be absolute) in this case dir will be ignored */ + private $phingFile; + + /** the target to call if any */ + protected $newTarget; + + /** should we inherit properties from the parent ? */ + private $inheritAll = true; + + /** should we inherit references from the parent ? */ + private $inheritRefs = false; + + /** the properties to pass to the new project */ + private $properties = array(); + + /** the references to pass to the new project */ + private $references = array(); + + /** The filesets that contain the files PhingTask is to be run on. */ + private $filesets = array(); + + /** the temporary project created to run the build file */ + private $newProject; + + /** Fail the build process when the called build fails? */ + private $haltOnFailure = false; + + /** + * If true, abort the build process if there is a problem with or in the target build file. + * Defaults to false. + * + * @param boolean new value + */ + public function setHaltOnFailure($hof) { + $this->haltOnFailure = (boolean) $hof; + } + + /** + * Creates a Project instance for the project to call. + * @return void + */ + public function init() { + $this->newProject = new Project(); + $tdf = $this->project->getTaskDefinitions(); + $this->newProject->addTaskDefinition("property", $tdf["property"]); + } + + /** + * Called in execute or createProperty if newProject is null. + * + *

    This can happen if the same instance of this task is run + * twice as newProject is set to null at the end of execute (to + * save memory and help the GC).

    + * + *

    Sets all properties that have been defined as nested + * property elements.

    + */ + private function reinit() { + $this->init(); + $count = count($this->properties); + for ($i = 0; $i < $count; $i++) { + $p = $this->properties[$i]; + $newP = $this->newProject->createTask("property"); + $newP->setName($p->getName()); + if ($p->getValue() !== null) { + $newP->setValue($p->getValue()); + } + if ($p->getFile() !== null) { + $newP->setFile($p->getFile()); + } + if ($p->getPrefix() !== null) { + $newP->setPrefix($p->getPrefix()); + } + if ($p->getRefid() !== null) { + $newP->setRefid($p->getRefid()); + } + if ($p->getEnvironment() !== null) { + $newP->setEnvironment($p->getEnvironment()); + } + if ($p->getUserProperty() !== null) { + $newP->setUserProperty($p->getUserProperty()); + } + if ($p->getOverride() !== null) { + $newP->setOverride($p->getOverride()); + } + $this->properties[$i] = $newP; + } + } + + /** + * Main entry point for the task. + * + * @return void + */ + public function main() { + + // Call Phing on the file set with the attribute "phingfile" + if ($this->phingFile !== null or $this->dir !== null) { + $this->processFile(); + } + + // if no filesets are given stop here; else process filesets + if (empty($this->filesets)) { + return; + } + + // preserve old settings + $savedDir = $this->dir; + $savedPhingFile = $this->phingFile; + $savedTarget = $this->newTarget; + $buildFailed = false; + + // set no specific target for files in filesets + // [HL] I'm commenting this out; I don't know why this should not be supported! + // $this->newTarget = null; + + foreach($this->filesets as $fs) { + + $ds = $fs->getDirectoryScanner($this->project); + + $fromDir = $fs->getDir($this->project); + $srcFiles = $ds->getIncludedFiles(); + + foreach($srcFiles as $fname) { + $f = new PhingFile($ds->getbasedir(), $fname); + $f = $f->getAbsoluteFile(); + $this->phingFile = $f->getAbsolutePath(); + $this->dir = $f->getParentFile(); + $this->processFile(); // run Phing! + } + } + + // side effect free programming ;-) + $this->dir = $savedDir; + $this->phingFile = $savedPhingFile; + $this->newTarget = $savedTarget; + + // [HL] change back to correct dir + if ($this->dir !== null) { + chdir($this->dir->getAbsolutePath()); + } + + } + + /** + * Execute phing file. + * + * @return void + */ + private function processFile() { + + $savedDir = $this->dir; + $savedPhingFile = $this->phingFile; + $savedTarget = $this->newTarget; + + $savedBasedirAbsPath = null; // this is used to save the basedir *if* we change it + + try { + + if ($this->newProject === null) { + $this->reinit(); + } + + $this->initializeProject(); + + if ($this->dir !== null) { + + $dirAbsPath = $this->dir->getAbsolutePath(); + + // BE CAREFUL! -- when the basedir is changed for a project, + // all calls to getAbsolutePath() on a relative-path dir will + // be made relative to the project's basedir! This means + // that subsequent calls to $this->dir->getAbsolutePath() will be WRONG! + + // We need to save the current project's basedir first. + $savedBasedirAbsPath = $this->getProject()->getBasedir()->getAbsolutePath(); + + $this->newProject->setBasedir($this->dir); + + // Now we must reset $this->dir so that it continues to resolve to the same + // path. + $this->dir = new PhingFile($dirAbsPath); + + if ($savedDir !== null) { // has been set explicitly + $this->newProject->setInheritedProperty("project.basedir", $this->dir->getAbsolutePath()); + } + + } else { + + // Since we're not changing the basedir here (for file resolution), + // we don't need to worry about any side-effects in this scanrio. + $this->dir = $this->getProject()->getBasedir(); + } + + $this->overrideProperties(); + if ($this->phingFile === null) { + $this->phingFile = "build.xml"; + } + + $fu = new FileUtils(); + $file = $fu->resolveFile($this->dir, $this->phingFile); + $this->phingFile = $file->getAbsolutePath(); + + $this->log("Calling Buildfile '" . $this->phingFile . "' with target '" . $this->newTarget . "'"); + + $this->newProject->setUserProperty("phing.file", $this->phingFile); + + ProjectConfigurator::configureProject($this->newProject, new PhingFile($this->phingFile)); + + if ($this->newTarget === null) { + $this->newTarget = $this->newProject->getDefaultTarget(); + } + + // Are we trying to call the target in which we are defined? + if ($this->newProject->getBaseDir() == $this->project->getBaseDir() && + $this->newProject->getProperty("phing.file") == $this->project->getProperty("phing.file") && + $this->getOwningTarget() !== null && + $this->newTarget == $this->getOwningTarget()->getName()) { + + throw new BuildException("phing task calling its own parent target"); + } + + $this->addReferences(); + $this->newProject->executeTarget($this->newTarget); + + } catch (Exception $e) { + $buildFailed = true; + $this->log($e->getMessage(), PROJECT_MSG_ERR); + + // important!!! continue on to perform cleanup tasks. + } + + + // reset environment values to prevent side-effects. + + $this->newProject = null; + $pkeys = array_keys($this->properties); + foreach($pkeys as $k) { + $this->properties[$k]->setProject(null); + } + + $this->dir = $savedDir; + $this->phingFile = $savedPhingFile; + $this->newTarget = $savedTarget; + + // If the basedir for any project was changed, we need to set that back here. + if ($savedBasedirAbsPath !== null) { + chdir($savedBasedirAbsPath); + } + + if ($this->haltOnFailure && $buildFailed) { + throw new BuildException("Execution of the target buildfile failed. Aborting."); + } + } + + /** + * Configure the Project, i.e. make intance, attach build listeners + * (copy from father project), add Task and Datatype definitions, + * copy properties and references from old project if these options + * are set via the attributes of the XML tag. + * + * Developer note: + * This function replaces the old methods "init", "_reinit" and + * "_initializeProject". + * + * @access protected + */ + private function initializeProject() { + + $this->newProject->setInputHandler($this->project->getInputHandler()); + + foreach($this->project->getBuildListeners() as $listener) { + $this->newProject->addBuildListener($listener); + } + + /* Copy things from old project. Datatypes and Tasks are always + * copied, properties and references only if specified so/not + * specified otherwise in the XML definition. + */ + // Add Datatype definitions + foreach ($this->project->getDataTypeDefinitions() as $typeName => $typeClass) { + $this->newProject->addDataTypeDefinition($typeName, $typeClass); + } + + // Add Task definitions + foreach ($this->project->getTaskDefinitions() as $taskName => $taskClass) { + if ($taskClass == "propertytask") { + // we have already added this taskdef in init() + continue; + } + $this->newProject->addTaskDefinition($taskName, $taskClass); + } + + // set user-defined properties + $this->project->copyUserProperties($this->newProject); + + if (!$this->inheritAll) { + // set System built-in properties separately, + // b/c we won't inherit them. + $this->newProject->setSystemProperties(); + + } else { + // set all properties from calling project + $properties = $this->project->getProperties(); + foreach ($properties as $name => $value) { + if ($name == "basedir" || $name == "phing.file" || $name == "phing.version") { + // basedir and phing.file get special treatment in main() + continue; + } + // don't re-set user properties, avoid the warning message + if ($this->newProject->getProperty($name) === null){ + // no user property + $this->newProject->setNewProperty($name, $value); + } + } + + } + + } + + /** + * Override the properties in the new project with the one + * explicitly defined as nested elements here. + * @return void + * @throws BuildException + */ + private function overrideProperties() { + foreach(array_keys($this->properties) as $i) { + $p = $this->properties[$i]; + $p->setProject($this->newProject); + $p->main(); + } + $this->project->copyInheritedProperties($this->newProject); + } + + /** + * Add the references explicitly defined as nested elements to the + * new project. Also copy over all references that don't override + * existing references in the new project if inheritrefs has been + * requested. + * + * @return void + * @throws BuildException + */ + private function addReferences() { + + // parent project references + $projReferences = $this->project->getReferences(); + + $newReferences = $this->newProject->getReferences(); + + $subprojRefKeys = array(); + + if (count($this->references) > 0) { + for ($i=0, $count=count($this->references); $i < $count; $i++) { + $ref = $this->references[$i]; + $refid = $ref->getRefId(); + + if ($refid === null) { + throw new BuildException("the refid attribute is required" + . " for reference elements"); + } + if (!isset($projReferences[$refid])) { + $this->log("Parent project doesn't contain any reference '" + . $refid . "'", + PROJECT_MSG_WARN); + continue; + } + + $subprojRefKeys[] = $refid; + //thisReferences.remove(refid); + $toRefid = $ref->getToRefid(); + if ($toRefid === null) { + $toRefid = $refid; + } + $this->copyReference($refid, $toRefid); + } + } + + // Now add all references that are not defined in the + // subproject, if inheritRefs is true + if ($this->inheritRefs) { + + // get the keys that are were not used by the subproject + $unusedRefKeys = array_diff(array_keys($projReferences), $subprojRefKeys); + + foreach($unusedRefKeys as $key) { + if (isset($newReferences[$key])) { + continue; + } + $this->copyReference($key, $key); + } + } + } + + /** + * Try to clone and reconfigure the object referenced by oldkey in + * the parent project and add it to the new project with the key + * newkey. + * + *

    If we cannot clone it, copy the referenced object itself and + * keep our fingers crossed.

    + * + * @param string $oldKey + * @param string $newKey + * @return void + */ + private function copyReference($oldKey, $newKey) { + $orig = $this->project->getReference($oldKey); + if ($orig === null) { + $this->log("No object referenced by " . $oldKey . ". Can't copy to " + .$newKey, + PROJECT_SG_WARN); + return; + } + + $copy = clone $orig; + + if ($copy instanceof ProjectComponent) { + $copy->setProject($this->newProject); + } elseif (in_array('setProject', get_class_methods(get_class($copy)))) { + $copy->setProject($this->newProject); + } elseif ($copy instanceof Project) { + // don't copy the old "Project" itself + } else { + $msg = "Error setting new project instance for " + . "reference with id " . $oldKey; + throw new BuildException($msg); + } + + $this->newProject->addReference($newKey, $copy); + } + + /** + * If true, pass all properties to the new phing project. + * Defaults to true. + * + * @access public + */ + function setInheritAll($value) { + $this->inheritAll = (boolean) $value; + } + + /** + * If true, pass all references to the new phing project. + * Defaults to false. + * + * @access public + */ + function setInheritRefs($value) { + $this->inheritRefs = (boolean)$value; + } + + /** + * The directory to use as a base directory for the new phing project. + * Defaults to the current project's basedir, unless inheritall + * has been set to false, in which case it doesn't have a default + * value. This will override the basedir setting of the called project. + * + * @access public + */ + function setDir($d) { + if ( is_string($d) ) + $this->dir = new PhingFile($d); + else + $this->dir = $d; + } + + /** + * The build file to use. + * Defaults to "build.xml". This file is expected to be a filename relative + * to the dir attribute given. + * + * @access public + */ + function setPhingfile($s) { + // it is a string and not a file to handle relative/absolute + // otherwise a relative file will be resolved based on the current + // basedir. + $this->phingFile = $s; + } + + /** + * Alias function for setPhingfile + * + * @access public + */ + function setBuildfile($s) { + $this->setPhingFile($s); + } + + /** + * The target of the new Phing project to execute. + * Defaults to the new project's default target. + * + * @access public + */ + function setTarget($s) { + $this->newTarget = $s; + } + + /** + * Support for filesets; This method returns a reference to an instance + * of a FileSet object. + * + * @return FileSet + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Property to pass to the new project. + * The property is passed as a 'user property' + * + * @access public + */ + function createProperty() { + $p = new PropertyTask(); + $p->setFallback($this->newProject); + $p->setUserProperty(true); + $this->properties[] = $p; + return $p; + } + + /** + * Reference element identifying a data type to carry + * over to the new project. + * + * @access public + */ + function createReference() { + $num = array_push($this->references, new PhingReference()); + return $this->references[$num-1]; + } + +} + +/** + * Helper class that implements the nested + * element of and . + */ +class PhingReference extends Reference { + + private $targetid = null; + + /** + * Set the id that this reference to be stored under in the + * new project. + * + * @param targetid the id under which this reference will be passed to + * the new project */ + public function setToRefid($targetid) { + $this->targetid = $targetid; + } + + /** + * Get the id under which this reference will be stored in the new + * project + * + * @return the id of the reference in the new project. + */ + public function getToRefid() { + return $this->targetid; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/PhpEvalTask.php b/gulliver/thirdparty/phing/tasks/system/PhpEvalTask.php new file mode 100644 index 000000000..3ee8035c4 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/PhpEvalTask.php @@ -0,0 +1,169 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Executes PHP function or evaluates expression and sets return value to a property. + * + * WARNING: + * This task can, of course, be abused with devastating effects. E.g. do not + * modify internal Phing classes unless you know what you are doing. + * + * @author Hans Lellelid + * @version $Revision: 1.7 $ + * @package phing.tasks.system + * + * @todo Add support for evaluating expressions + */ +class PhpEvalTask extends Task { + + protected $expression; // Expression to evaluate + protected $function; // Function to execute + protected $class; // Class containing function to execute + protected $returnProperty; // name of property to set to return value + protected $params = array(); // parameters for function calls + + /** Main entry point. */ + function main() { + + if ($this->function === null && $this->expression === null) { + throw new BuildException("You must specify a function to execute or PHP expression to evalute.", $this->location); + } + + if ($this->function !== null && $this->expression !== null) { + throw new BuildException("You can specify function or expression, but not both.", $this->location); + } + + if ($this->expression !== null && !empty($this->params)) { + throw new BuildException("You cannot use nested tags when evaluationg a PHP expression.", $this->location); + } + + $retval = null; + if ($this->function !== null) { + $retval = $this->callFunction(); + } elseif ($this->expression !== null) { + $retval = $this->evalExpression(); + } + + if ($this->returnProperty !== null) { + $this->project->setProperty($this->returnProperty, $retval); + } + } + + /** + * Calls function and returns results. + * @return mixed + */ + protected function callFunction() { + + if ($this->class !== null) { + // import the classname & unqualify it, if necessary + $this->class = Phing::import($this->class); + + $user_func = array($this->class, $this->function); + $h_func = $this->class . '::' . $this->function; // human-readable (for log) + } else { + $user_func = $this->function; + $h_func = $user_func; // human-readable (for log) + } + + // put parameters into simple array + $params = array(); + foreach($this->params as $p) { + $params[] = $p->getValue(); + } + + $this->log("Calling PHP function: " . $h_func . "()"); + foreach($params as $p) { + $this->log(" param: " . $p, PROJECT_MSG_VERBOSE); + } + + $return = call_user_func_array($user_func, $params); + return $return; + } + + /** + * Evaluates expression and returns resulting value. + * @return mixed + */ + protected function evalExpression() { + $this->log("Evaluating PHP expression: " . $this->expression); + if (!StringHelper::endsWith(';', trim($this->expression))) { + $this->expression .= ';'; + } + $retval = null; + eval('$retval = ' . $this->expression); + return $retval; + } + + /** Set function to execute */ + public function setFunction($f) { + $this->function = $f; + } + + /** Set [static] class which contains function to execute */ + public function setClass($c) { + $this->class = $c; + } + + /** Sets property name to set with return value of function or expression.*/ + public function setReturnProperty($r) { + $this->returnProperty = $r; + } + + /** Set PHP expression to evaluate. */ + public function addText($expression) { + $this->expression = $expression; + } + + /** Set PHP expression to evaluate. */ + public function setExpression($expression) { + $this->expression = $expression; + } + + /** Add a nested tag. */ + public function createParam() { + $p = new FunctionParam(); + $this->params[] = $p; + return $p; + } +} + +/** + * Supports the nested tag for PhpTask. + */ +class FunctionParam { + + private $val; + + public function setValue($v) { + $this->val = $v; + } + + public function addText($v) { + $this->val = $v; + } + + public function getValue() { + return $this->val; + } +} \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/system/PropertyPromptTask.php b/gulliver/thirdparty/phing/tasks/system/PropertyPromptTask.php new file mode 100644 index 000000000..a56eed3fa --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/PropertyPromptTask.php @@ -0,0 +1,201 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/system/io/ConsoleReader.php'; + +/** + * Deprecated task that uses console to prompt user for property values. + * + * This class is very slightly simpler than the InputTask, but lacks the ability + * to use a non-console input handler. You should, therefore, use InputTask. This + * class can serve as a reference, but will be removed in the future. + * + * @author Hans Lellelid (Phing) + * @author Anthony J. Young-Garner (Ant) + * @version $Revision: 1.4 $ + * @package phing.tasks.system + * @deprecated - in favor of the more capable InputTask + */ +class PropertyPromptTask extends Task { + + private $propertyName; // required + private $defaultValue; + private $proposedValue; // required + private $promptText; // required + private $promptCharacter; + private $useExistingValue; + + /** + * Sets the prompt text that will be presented to the user. + * @param string $prompt + * @return void + */ + public function addText($prompt) { + $this->setPromptText($prompt); + } + + /** + * Run the PropertyPrompt task. + * @throws BuildException + */ + public function main() { + $this->proposedValue = $this->project->getProperty($this->propertyName); + $currentValue = $this->defaultValue; + if ($currentValue == "" && $this->proposedValue !== null) { $currentValue = $this->proposedValue; } + if (! (($this->useExistingValue === true) && ($this->proposedValue !== null))) { + + $this->log("Prompting user for " . $this->propertyName . ". " . $this->getDefaultMessage(), PROJECT_MSG_VERBOSE); + + print "\n" . $this->promptText . " [" . $currentValue . "] " . $this->promptCharacter . " "; + + /** future version should probably have hooks for validation of user input.*/ + $reader = new ConsoleReader(); + + try { + $this->proposedValue = $reader->readLine(); + } catch (IOException $e) { + $this->log("Prompt failed. Using default. (Failure reason: " . $e->getMessage().")"); + $this->proposedValue = $this->defaultValue; + } + + if (empty($this->proposedValue)) { + $this->log("No value specified, using default.", PROJECT_MSG_VERBOSE); + $this->proposedValue = $this->defaultValue; + } + + if (!empty($this->proposedValue)) { + $this->project->setProperty($this->propertyName, $this->proposedValue); + } + + } + } + + /** + * Returns a string to be inserted in the log message + * indicating whether a default response was specified + * in the build file. + */ + private function getDefaultMessage() { + if ($this->defaultValue == "") { + return "No default response specified."; + } else return "Default response is " . $this->defaultValue . "."; + } + + /** + * Returns defaultValue specified + * in this task for the Property + * being set. + * @return string + */ + public function getDefaultValue() { + return $this->defaultValue; + } + + /** + * Returns the terminating character used to + * punctuate the prompt text. + * @return string + */ + public function getPromptCharacter() { + return $this->promptCharacter; + } + + /** + * Returns text of the prompt. + * @return java.lang.String + */ + public function getPromptText() { + return $this->promptText; + } + + /** + * Returns name of the Ant Project Property + * being set by this task. + * @return string + */ + public function getPropertyName() { + return $this->propertyName; + } + /** + * Initializes this task. + */ + public function init() { + parent::init(); + $this->defaultValue = ""; + $this->promptCharacter = "?"; + $this->useExistingValue = false; + } + + /** + * Insert the method's description here. + * Creation date: (12/10/2001 8:16:16 AM) + * @return boolean + */ + public function isUseExistingValue() { + return $this->useExistingValue; + } + + /** + * Sets defaultValue for the Property + * being set by this task. + * @param string $newDefaultvalue + */ + public function setDefaultvalue($newDefaultvalue) { + $this->defaultValue = $newDefaultvalue; + } + + /** + * Sets the terminating character used to + * punctuate the prompt text (default is "?"). + * @param newPromptcharacter java.lang.String + */ + public function setPromptCharacter($newPromptcharacter) { + $this->promptCharacter = $newPromptcharacter; + } + + /** + * Sets text of the prompt. + * @param newPrompttext java.lang.String + */ + public function setPromptText($newPrompttext) { + $this->promptText = $newPrompttext; + } + + /** + * Specifies the Phing Project Property + * being set by this task. + * @param newPropertyname java.lang.String + */ + public function setPropertyName($newPropertyname) { + $this->propertyName = $newPropertyname; + } + + /** + * + * + * @param boolean newUseExistingValue + */ + public function setUseExistingValue($newUseExistingValue) { + $this->useExistingValue = $newUseExistingValue; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/PropertyTask.php b/gulliver/thirdparty/phing/tasks/system/PropertyTask.php new file mode 100644 index 000000000..522907a13 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/PropertyTask.php @@ -0,0 +1,438 @@ +. + */ + +include_once 'phing/Task.php'; +include_once 'phing/system/util/Properties.php'; + +/** + * Task for setting properties in buildfiles. + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision$ + * @package phing.tasks.system + */ +class PropertyTask extends Task { + + /** name of the property */ + protected $name; + + /** value of the property */ + protected $value; + + protected $reference; + protected $env; // Environment + protected $file; + protected $ref; + protected $prefix; + protected $fallback; + + /** Whether to force overwrite of existing property. */ + protected $override = false; + + /** Whether property should be treated as "user" property. */ + protected $userProperty = false; + + /** + * Sets a the name of current property component + */ + function setName($name) { + $this->name = (string) $name; + } + + /** Get property component name. */ + function getName() { + return $this->name; + } + + /** + * Sets a the value of current property component. + * @param mixed Value of name, all scalars allowed + */ + function setValue($value) { + $this->value = (string) $value; + } + + /** + * Sets value of property to CDATA tag contents. + * @param string $values + * @since 2.2.0 + */ + public function addText($value) { + $this->setValue($value); + } + + /** Get the value of current property component. */ + function getValue() { + return $this->value; + } + + /** Set a file to use as the source for properties. */ + function setFile($file) { + if (is_string($file)) { + $file = new PhingFile($file); + } + $this->file = $file; + } + + /** Get the PhingFile that is being used as property source. */ + function getFile() { + return $this->file; + } + + function setRefid(Reference $ref) { + $this->reference = $ref; + } + + function getRefid() { + return $this->reference; + } + + /** + * Prefix to apply to properties loaded using file. + * A "." is appended to the prefix if not specified. + * @param string $prefix prefix string + * @return void + * @since 2.0 + */ + public function setPrefix($prefix) { + $this->prefix = $prefix; + if (!StringHelper::endsWith(".", $prefix)) { + $this->prefix .= "."; + } + } + + /** + * @return string + * @since 2.0 + */ + public function getPrefix() { + return $this->prefix; + } + + /** + * the prefix to use when retrieving environment variables. + * Thus if you specify environment="myenv" + * you will be able to access OS-specific + * environment variables via property names "myenv.PATH" or + * "myenv.TERM". + *

    + * Note that if you supply a property name with a final + * "." it will not be doubled. ie environment="myenv." will still + * allow access of environment variables through "myenv.PATH" and + * "myenv.TERM". This functionality is currently only implemented + * on select platforms. Feel free to send patches to increase the number of platforms + * this functionality is supported on ;).
    + * Note also that properties are case sensitive, even if the + * environment variables on your operating system are not, e.g. it + * will be ${env.Path} not ${env.PATH} on Windows 2000. + * @param env prefix + */ + function setEnvironment($env) { + $this->env = (string) $env; + } + + function getEnvironment() { + return $this->env; + } + + /** + * Set whether this is a user property (ro). + * This is deprecated in Ant 1.5, but the userProperty attribute + * of the class is still being set via constructor, so Phing will + * allow this method to function. + * @param boolean $v + */ + function setUserProperty($v) { + $this->userProperty = (boolean) $v; + } + + function getUserProperty() { + return $this->userProperty; + } + + function setOverride($v) { + $this->override = (boolean) $v; + } + + function getOverride() { + return $this->override; + } + + function toString() { + return (string) $this->value; + } + + /** + * @param Project $p + */ + function setFallback($p) { + $this->fallback = $p; + } + + function getFallback() { + return $this->fallback; + } + /** + * set the property in the project to the value. + * if the task was give a file or env attribute + * here is where it is loaded + */ + function main() { + if ($this->name !== null) { + if ($this->value === null && $this->ref === null) { + throw new BuildException("You must specify value or refid with the name attribute", $this->getLocation()); + } + } else { + if ($this->file === null && $this->env === null ) { + throw new BuildException("You must specify file or environment when not using the name attribute", $this->getLocation()); + } + } + + if ($this->file === null && $this->prefix !== null) { + throw new BuildException("Prefix is only valid when loading from a file.", $this->getLocation()); + } + + if (($this->name !== null) && ($this->value !== null)) { + $this->addProperty($this->name, $this->value); + } + + if ($this->file !== null) { + $this->loadFile($this->file); + } + + if ( $this->env !== null ) { + $this->loadEnvironment($this->env); + } + + if (($this->name !== null) && ($this->ref !== null)) { + // get the refereced property + try { + $this->addProperty($this->name, $this->reference->getReferencedObject($this->project)->toString()); + } catch (BuildException $be) { + if ($this->fallback !== null) { + $this->addProperty($this->name, $this->reference->getReferencedObject($this->fallback)->toString()); + } else { + throw $be; + } + } + } + } + + /** + * load the environment values + * @param string $prefix prefix to place before them + */ + protected function loadEnvironment($prefix) { + + $props = new Properties(); + if ( substr($prefix, strlen($prefix)-1) == '.' ) { + $prefix .= "."; + } + $this->log("Loading Environment $prefix", PROJECT_MSG_VERBOSE); + foreach($_ENV as $key => $value) { + $props->setProperty($prefix . '.' . $key, $value); + } + $this->addProperties($props); + } + + /** + * iterate through a set of properties, + * resolve them then assign them + */ + protected function addProperties($props) { + $this->resolveAllProperties($props); + foreach($props->keys() as $name) { + $value = $props->getProperty($name); + $v = $this->project->replaceProperties($value); + if ($this->prefix !== null) { + $name = $this->prefix . $name; + } + $this->addProperty($name, $v); + } + } + + /** + * add a name value pair to the project property set + * @param string $name name of property + * @param string $value value to set + */ + protected function addProperty($name, $value) { + if ($this->userProperty) { + if ($this->project->getUserProperty($name) === null || $this->override) { + $this->project->setInheritedProperty($name, $value); + } else { + $this->log("Override ignored for " . $name, PROJECT_MSG_VERBOSE); + } + } else { + if ($this->override) { + $this->project->setProperty($name, $value); + } else { + $this->project->setNewProperty($name, $value); + } + } + } + + /** + * load properties from a file. + * @param PhingFile $file + */ + protected function loadFile(PhingFile $file) { + $props = new Properties(); + $this->log("Loading ". $file->getAbsolutePath(), PROJECT_MSG_INFO); + try { // try to load file + if ($file->exists()) { + $props->load($file); + $this->addProperties($props); + } else { + $this->log("Unable to find property file: ". $file->getAbsolutePath() ."... skipped", PROJECT_MSG_WARN); + } + } catch (IOException $ioe) { + throw new BuildException("Could not load properties from file.", $ioe); + } + } + + /** + * Given a Properties object, this method goes through and resolves + * any references to properties within the object. + * + * @param Properties $props The collection of Properties that need to be resolved. + * @return void + */ + protected function resolveAllProperties(Properties $props) { + + $keys = $props->keys(); + + while(count($keys)) { + + // There may be a nice regex/callback way to handle this + // replacement, but at the moment it is pretty complex, and + // would probably be a lot uglier to work into a preg_replace_callback() + // system. The biggest problem is the fact that a resolution may require + // multiple passes. + + $name = array_shift($keys); + $value = $props->getProperty($name); + $resolved = false; + + while(!$resolved) { + + $fragments = array(); + $propertyRefs = array(); + + // [HL] this was ::parsePropertyString($this->value ...) ... this seems wrong + self::parsePropertyString($value, $fragments, $propertyRefs); + + $resolved = true; + if (count($propertyRefs) !== 0) { + + $sb = ""; + + $i = $fragments; + $j = $propertyRefs; + while(count($i)) { + $fragment = array_shift($i); + if ($fragment === null) { + $propertyName = array_shift($j); + + if ($propertyName === $name) { + // Should we maybe just log this as an error & move on? + // $this->log("Property ".$name." was circularly defined.", PROJECT_MSG_ERR); + throw new BuildException("Property ".$name." was circularly defined."); + } + + $fragment = $this->getProject()->getProperty($propertyName); + if ($fragment === null) { + if ($props->containsKey($propertyName)) { + $fragment = $props->getProperty($propertyName); + $resolved = false; // parse again (could have been replaced w/ another var) + } else { + $fragment = "\${".$propertyName."}"; + } + } + } + $sb .= $fragment; + } + + $this->log("Resolved Property \"$value\" to \"$sb\"", PROJECT_MSG_DEBUG); + $value = $sb; + $props->setProperty($name, $value); + + } // if (count($propertyRefs)) + + } // while (!$resolved) + + } // while (count($keys) + } + + + /** + * This method will parse a string containing ${value} style + * property values into two lists. The first list is a collection + * of text fragments, while the other is a set of string property names + * null entries in the first list indicate a property reference from the + * second list. + * + * This is slower than regex, but useful for this class, which has to handle + * multiple parsing passes for properties. + * + * @param string $value The string to be scanned for property references + * @param array &$fragments The found fragments + * @param array &$propertyRefs The found refs + */ + protected function parsePropertyString($value, &$fragments, &$propertyRefs) { + + $prev = 0; + $pos = 0; + + while (($pos = strpos($value, '$', $prev)) !== false) { + + if ($pos > $prev) { + array_push($fragments, StringHelper::substring($value, $prev, $pos-1)); + } + if ($pos === (strlen($value) - 1)) { + array_push($fragments, '$'); + $prev = $pos + 1; + } elseif ($value{$pos+1} !== '{' ) { + + // the string positions were changed to value-1 to correct + // a fatal error coming from function substring() + array_push($fragments, StringHelper::substring($value, $pos, $pos + 1)); + $prev = $pos + 2; + } else { + $endName = strpos($value, '}', $pos); + if ($endName === false) { + throw new BuildException("Syntax error in property: $value"); + } + $propertyName = StringHelper::substring($value, $pos + 2, $endName-1); + array_push($fragments, null); + array_push($propertyRefs, $propertyName); + $prev = $endName + 1; + } + } + + if ($prev < strlen($value)) { + array_push($fragments, StringHelper::substring($value, $prev)); + } + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/ReflexiveTask.php b/gulliver/thirdparty/phing/tasks/system/ReflexiveTask.php new file mode 100644 index 000000000..7fb9a332f --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ReflexiveTask.php @@ -0,0 +1,155 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * This task is for using filter chains to make changes to files and overwrite the original files. + * + * This task was created to serve the need for "cleanup" tasks -- e.g. a ReplaceRegexp task or strip task + * being used to modify files and then overwrite the modified files. In many (most?) cases you probably + * should just use a copy task to preserve the original source files, but this task supports situations + * where there is no src vs. build directory, and modifying source files is actually desired. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @author Hans Lellelid + * @version $Revision: 1.11 $ + * @package phing.tasks.system + */ +class ReflexiveTask extends Task { + + /** Single file to process. */ + private $file; + + /** Any filesets that should be processed. */ + private $filesets = array(); + + /** Any filters to be applied before append happens. */ + private $filterChains = array(); + + /** Alias for setFrom() */ + function setFile(PhingFile $f) { + $this->file = $f; + } + + /** Nested creator, adds a set of files (nested fileset attribute). */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Creates a filterchain + * + * @return object The created filterchain object + */ + function createFilterChain() { + $num = array_push($this->filterChains, new FilterChain($this->project)); + return $this->filterChains[$num-1]; + } + + /** Append the file(s). */ + function main() { + + if ($this->file === null && empty($this->filesets)) { + throw new BuildException("You must specify a file or fileset(s) for the task."); + } + + // compile a list of all files to modify, both file attrib and fileset elements + // can be used. + + $files = array(); + + if ($this->file !== null) { + $files[] = $this->file; + } + + if (!empty($this->filesets)) { + $filenames = array(); + foreach($this->filesets as $fs) { + try { + $ds = $fs->getDirectoryScanner($this->project); + $filenames = $ds->getIncludedFiles(); // get included filenames + $dir = $fs->getDir($this->project); + foreach ($filenames as $fname) { + $files[] = new PhingFile($dir, $fname); + } + } catch (BuildException $be) { + $this->log($be->getMessage(), PROJECT_MSG_WARN); + } + } + } + + $this->log("Applying reflexive processing to " . count($files) . " files."); + + // These "slots" allow filters to retrieve information about the currently-being-process files + $slot = $this->getRegisterSlot("currentFile"); + $basenameSlot = $this->getRegisterSlot("currentFile.basename"); + + + foreach($files as $file) { + // set the register slots + + $slot->setValue($file->getPath()); + $basenameSlot->setValue($file->getName()); + + // 1) read contents of file, pulling through any filters + $in = null; + try { + $contents = ""; + $in = FileUtils::getChainedReader(new FileReader($file), $this->filterChains, $this->project); + while(-1 !== ($buffer = $in->read())) { + $contents .= $buffer; + } + $in->close(); + } catch (Exception $e) { + if ($in) $in->close(); + $this->log("Erorr reading file: " . $e->getMessage(), PROJECT_MSG_WARN); + } + + try { + // now create a FileWriter w/ the same file, and write to the file + $out = new FileWriter($file); + $out->write($contents); + $out->close(); + $this->log("Applying reflexive processing to " . $file->getPath(), PROJECT_MSG_VERBOSE); + } catch (Exception $e) { + if ($out) $out->close(); + $this->log("Error writing file back: " . $e->getMessage(), PROJECT_MSG_WARN); + } + + } + + } + +} \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/system/ResolvePathTask.php b/gulliver/thirdparty/phing/tasks/system/ResolvePathTask.php new file mode 100644 index 000000000..7110ea371 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/ResolvePathTask.php @@ -0,0 +1,122 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Task for resolving relative paths and setting absolute path in property value. + * + * This task was created to address a need for resolving absolute paths of files / directories. + * In many cases a relative directory (e.g. "./build") is specified, but it needs to be treated + * as an absolute path since other build files (e.g. in subdirs) should all be using the same + * path -- and not treating it as a relative path to their own directory. + * + * + * + * + * Resolved [absolute] path: ${absolute_path} + * + * + * TODO: + * - Possibly integrate this with PackageAsPath, for handling/resolving dot-path paths. + * + * @author Hans Lellelid + * @version $Revision: 1.6 $ + * @package phing.tasks.system + */ +class ResolvePathTask extends Task { + + /** Name of property to set. */ + private $propertyName; + + /** The [possibly] relative file/path that needs to be resolved. */ + private $file; + + /** Base directory used for resolution. */ + private $dir; + + /** + * Set the name of the property to set. + * @param string $v Property name + * @return void + */ + public function setPropertyName($v) { + $this->propertyName = $v; + } + + /** + * Sets a base dir to use for resolution. + * @param PhingFile $d + */ + function setDir(PhingFile $d) { + $this->dir = $d; + } + + /** + * Sets a path (file or directory) that we want to resolve. + * This is the same as setFile() -- just more generic name so that it's + * clear that you can also use it to set directory. + * @param string $f + * @see setFile() + */ + function setPath($f) { + $this->file = $f; + } + + /** + * Sets a file that we want to resolve. + * @param string $f + */ + function setFile($f) { + $this->file = $f; + } + + /** + * Perform the resolution & set property. + */ + public function main() { + + if (!$this->propertyName) { + throw new BuildException("You must specify the propertyName attribute", $this->getLocation()); + } + + // Currently only files are supported + if ($this->file === null) { + throw new BuildException("You must specify a path to resolve", $this->getLocation()); + } + + $fs = FileSystem::getFileSystem(); + + // if dir attribute was specified then we should + // use that as basedir to which file was relative. + // -- unless the file specified is an absolute path + if ($this->dir !== null && !$fs->isAbsolute(new PhingFile($this->file))) { + $resolved = new PhingFile($this->dir->getPath(), $this->file); + } else { + // otherwise just resolve it relative to project basedir + $resolved = $this->project->resolveFile($this->file); + } + + $this->log("Resolved " . $this->file . " to " . $resolved->getAbsolutePath(), PROJECT_MSG_INFO); + $this->project->setProperty($this->propertyName, $resolved->getAbsolutePath()); + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/SequentialTask.php b/gulliver/thirdparty/phing/tasks/system/SequentialTask.php new file mode 100644 index 000000000..cbcd0db11 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/SequentialTask.php @@ -0,0 +1,57 @@ +. + */ + +require_once 'phing/Task.php'; +require_once 'phing/TaskContainer.php'; + +/** + * Sequential is a container task that contains other Phing Task objects. + * + * The sequential task has no attributes and does not support any nested + * elements apart from Ant tasks. Any valid Ant task may be embedded within the + * sequential task. + * + * @since 2.1.2 + */ +class SequentialTask extends Task implements TaskContainer { + + /** Optional Vector holding the nested tasks */ + private $nestedTasks = array(); + + /** + * Add a nested task to Sequential. + * @param Task $nestedTask Nested task to execute Sequential + */ + public function addTask(Task $nestedTask) { + $this->nestedTasks[] = $nestedTask; + } + + /** + * Execute all nestedTasks. + * @throws BuildException if one of the nested tasks fails. + */ + public function main() { + foreach($this->nestedTasks as $task) { + $task->perform(); + } + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/TaskdefTask.php b/gulliver/thirdparty/phing/tasks/system/TaskdefTask.php new file mode 100644 index 000000000..037934453 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/TaskdefTask.php @@ -0,0 +1,127 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Register a task for use within a buildfile. + * + * This is for registering your own tasks -- or any non-core Task -- for use within a buildfile. + * If you find that you are using a particular class frequently, you may want to edit the + * phing/tasks/defaults.properties file so that it is included by default. You may also + * want to submit it (if LGPL or compatible license) to be included in Phing distribution. + * + *

    + *   
    + *   .
    + *   .
    + *   
    + * 
    + * + * TODO: + * -- possibly refactor since this is almost the same as TypeDefTask + * (right now these are just too simple to really justify creating an abstract class) + * + * @author Hans Lellelid + * @version $Revision: 1.11 $ + * @package phing.tasks.system + */ +class TaskdefTask extends Task { + + /** Tag name for task that will be used in XML */ + private $name; + + /** + * Classname of task to register. + * This can be a dot-path -- relative to a location on PHP include_path. + * E.g. path.to.MyClass -> path/to/MyClass.php + * @var string + */ + private $classname; + + /** + * Path to add to PHP include_path to aid in finding specified class. + * @var Path + */ + private $classpath; + + /** + * Refid to already defined classpath + */ + private $classpathId; + + /** + * Set the classpath to be used when searching for component being defined + * + * @param Path $classpath An Path object containing the classpath. + */ + public function setClasspath(Path $classpath) { + if ($this->classpath === null) { + $this->classpath = $classpath; + } else { + $this->classpath->append($classpath); + } + } + + /** + * Create the classpath to be used when searching for component being defined + */ + public function createClasspath() { + if ($this->classpath === null) { + $this->classpath = new Path($this->project); + } + return $this->classpath->createPath(); + } + + /** + * Reference to a classpath to use when loading the files. + */ + public function setClasspathRef(Reference $r) { + $this->classpathId = $r->getRefId(); + $this->createClasspath()->setRefid($r); + } + + /** + * Sets the name that will be used in XML buildfile. + * @param string $name + */ + public function setName($name) { + $this->name = $name; + } + + /** + * Sets the class name / dotpath to use. + * @param string $class + */ + public function setClassname($class) { + $this->classname = $class; + } + + /** Main entry point */ + public function main() { + if ($this->name === null || $this->classname === null) { + throw new BuildException("You must specify name and class attributes for ."); + } + $this->log("Task " . $this->name . " will be handled by class " . $this->classname, PROJECT_MSG_VERBOSE); + $this->project->addTaskDefinition($this->name, $this->classname, $this->classpath); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/TouchTask.php b/gulliver/thirdparty/phing/tasks/system/TouchTask.php new file mode 100644 index 000000000..12d1ea2ec --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/TouchTask.php @@ -0,0 +1,170 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/util/DirectoryScanner.php'; +include_once 'phing/types/FileSet.php'; +include_once 'phing/util/FileUtils.php'; +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/system/io/IOException.php'; + +/** + * Touch a file and/or fileset(s); corresponds to the Unix touch command. + * + * If the file to touch doesn't exist, an empty one is created. + * + * @version $Revision: 1.12 $ + * @package phing.tasks.system + */ +class TouchTask extends Task { + + private $file; + private $millis = -1; + private $dateTime; + private $filesets = array(); + private $fileUtils; + + function __construct() { + $this->fileUtils = new FileUtils(); + } + + /** + * Sets a single source file to touch. If the file does not exist + * an empty file will be created. + */ + function setFile(PhingFile $file) { + $this->file = $file; + } + + /** + * the new modification time of the file + * in milliseconds since midnight Jan 1 1970. + * Optional, default=now + */ + function setMillis($millis) { + $this->millis = (int) $millis; + } + + /** + * the new modification time of the file + * in the format MM/DD/YYYY HH:MM AM or PM; + * Optional, default=now + */ + function setDatetime($dateTime) { + $this->dateTime = (string) $dateTime; + } + + /** + * Nested creator, adds a set of files (nested fileset attribute). + * @return FileSet + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Execute the touch operation. + */ + function main() { + $savedMillis = $this->millis; + + if ($this->file === null && count($this->filesets) === 0) { + throw new BuildException("Specify at least one source - a file or a fileset."); + } + + if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) { + throw new BuildException("Use a fileset to touch directories."); + } + + try { // try to touch file + if ($this->dateTime !== null) { + $this->setMillis(strtotime($this->dateTime)); + if ($this->millis < 0) { + throw new BuildException("Date of {$this->dateTime} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT)."); + } + } + $this->_touch(); + } catch (Exception $ex) { + throw new BuildException("Error touch()ing file", $ex, $this->location); + } + + $this->millis = $savedMillis; + + } + + /** + * Does the actual work. + */ + function _touch() { + if ($this->file !== null) { + if (!$this->file->exists()) { + $this->log("Creating " . $this->file->__toString(), PROJECT_MSG_INFO); + try { // try to create file + $this->file->createNewFile(); + } catch(IOException $ioe) { + throw new BuildException("Error creating new file " . $this->file->__toString(), $ioe, $this->location); + } + } + } + + $resetMillis = false; + if ($this->millis < 0) { + $resetMillis = true; + $this->millis = Phing::currentTimeMillis(); + } + + if ($this->file !== null) { + $this->touchFile($this->file); + } + + // deal with the filesets + foreach($this->filesets as $fs) { + + $ds = $fs->getDirectoryScanner($this->getProject()); + $fromDir = $fs->getDir($this->getProject()); + + $srcFiles = $ds->getIncludedFiles(); + $srcDirs = $ds->getIncludedDirectories(); + + for ($j=0,$_j=count($srcFiles); $j < $_j; $j++) { + $this->touchFile(new PhingFile($fromDir, (string) $srcFiles[$j])); + } + + for ($j=0,$_j=count($srcDirs); $j < $_j ; $j++) { + $this->touchFile(new PhingFile($fromDir, (string) $srcDirs[$j])); + } + } + + if ($resetMillis) { + $this->millis = -1; + } + } + + private function touchFile($file) { + if ( !$file->canWrite() ) { + throw new BuildException("Can not change modification date of read-only file " . $file->__toString()); + } + $file->setLastModified($this->millis); + } + +} + diff --git a/gulliver/thirdparty/phing/tasks/system/TstampTask.php b/gulliver/thirdparty/phing/tasks/system/TstampTask.php new file mode 100644 index 000000000..2afc06fe5 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/TstampTask.php @@ -0,0 +1,168 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Sets properties to the current time, or offsets from the current time. + * The default properties are TSTAMP, DSTAMP and TODAY; + * + * Based on Ant's Tstamp task. + * + * @author Michiel Rook + * @version $Revision: 1.6 $ + * @package phing.tasks.system + * @since 2.2.0 + */ +class TstampTask extends Task +{ + private $customFormats = array(); + + private $prefix = ""; + + /** + * Set a prefix for the properties. If the prefix does not end with a "." + * one is automatically added. + * @param prefix the prefix to use. + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + + if (!empty($this->prefix)) + { + $this->prefix.= "."; + } + } + + /** + * Adds a custom format + * + * @param TstampCustomFormat custom format + */ + public function addFormat(TstampCustomFormat $cf) + { + $this->customFormats[] = $cf; + } + + /** + * Create the timestamps. Custom ones are done before + * the standard ones. + * + * @throws BuildException + */ + public function main() + { + foreach ($this->customFormats as $cf) + { + $cf->execute($this); + } + + $dstamp = strftime('%Y%m%d'); + $this->prefixProperty('DSTAMP', $dstamp); + + $tstamp = strftime('%H%M'); + $this->prefixProperty('TSTAMP', $tstamp); + + $today = strftime('%B %d %Y'); + $this->prefixProperty('TODAY', $today); + } + + /** + * helper that encapsulates prefix logic and property setting + * policy (i.e. we use setNewProperty instead of setProperty). + */ + public function prefixProperty($name, $value) + { + $this->getProject()->setNewProperty($this->prefix . $name, $value); + } +} + +class TstampCustomFormat +{ + private $propertyName = ""; + private $pattern = ""; + private $locale = ""; + + /** + * The property to receive the date/time string in the given pattern + * + * @param propertyName the name of the property. + */ + public function setProperty($propertyName) + { + $this->propertyName = $propertyName; + } + + /** + * The date/time pattern to be used. The values are as + * defined by the PHP strftime() function. + * + * @param pattern + */ + public function setPattern($pattern) + { + $this->pattern = $pattern; + } + + /** + * The locale used to create date/time string. + * + * @param locale + */ + public function setLocale($locale) + { + $this->locale = $locale; + } + + /** + * validate parameter and execute the format. + * + * @param TstampTask reference to task + */ + public function execute(TstampTask $tstamp) + { + if (empty($this->propertyName)) + { + throw new BuildException("property attribute must be provided"); + } + + if (empty($this->pattern)) + { + throw new BuildException("pattern attribute must be provided"); + } + + if (!empty($this->locale)) + { + setlocale(LC_ALL, $this->locale); + } + + $value = strftime($this->pattern); + $tstamp->prefixProperty($this->propertyName, $value); + + if (!empty($this->locale)) + { + // reset locale + setlocale(LC_ALL, NULL); + } + } +} +?> diff --git a/gulliver/thirdparty/phing/tasks/system/TypedefTask.php b/gulliver/thirdparty/phing/tasks/system/TypedefTask.php new file mode 100644 index 000000000..e9404675d --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/TypedefTask.php @@ -0,0 +1,125 @@ +. + */ + +require_once 'phing/Task.php'; + +/** + * Register a datatype for use within a buildfile. + * + * This is for registering your own datatypes for use within a buildfile. + * + * If you find that you are using a particular class frequently, you may want to edit the + * phing/types/defaults.properties file so that it is included by default. You may also + * want to submit it (if LGPL or compatible license) to be included in Phing distribution. + * + *
    + *   
    + *   .
    + *   
    + *     
    + *   
    + * 
    + * + * TODO: + * -- possibly refactor since this is almost the same as TaskDefTask + * (right now these are just too simple to really justify creating an abstract class) + * + * @author Hans Lellelid + * @version $Revision: 1.7 $ + * @package phing.tasks.system + */ +class TypedefTask extends Task { + + /** Tag name for datatype that will be used in XML */ + private $name; + + /** + * Classname of task to register. + * This can be a dot-path -- relative to a location on PHP include_path. + * E.g. path.to.MyClass -> path/to/MyClass.php + * @var string + */ + private $classname; + + /** + * Path to add to PHP include_path to aid in finding specified class. + * @var Path + */ + private $classpath; + + /** Refid to already defined classpath */ + private $classpathId; + + /** + * Set the classpath to be used when searching for component being defined + * + * @param Path $classpath An Path object containing the classpath. + */ + public function setClasspath(Path $classpath) { + if ($this->classpath === null) { + $this->classpath = $classpath; + } else { + $this->classpath->append($classpath); + } + } + + /** + * Create the classpath to be used when searching for component being defined + */ + public function createClasspath() { + if ($this->classpath === null) { + $this->classpath = new Path($this->project); + } + return $this->classpath->createPath(); + } + + /** + * Reference to a classpath to use when loading the files. + */ + public function setClasspathRef(Reference $r) { + $this->classpathId = $r->getRefId(); + $this->createClasspath()->setRefid($r); + } + + /** Main entry point */ + public function main() { + if ($this->name === null || $this->classname === null) { + throw new BuildException("You must specify name and class attributes for ."); + } + $this->project->addDataTypeDefinition($this->name, $this->classname, $this->classpath); + } + + /** + * Sets the name that will be used in XML buildfile. + * @param string $name + */ + public function setName($name) { + $this->name = $name; + } + + /** + * Sets the class name / dotpath to use. + * @param string $class + */ + public function setClassname($class) { + $this->classname = $class; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/UpToDateTask.php b/gulliver/thirdparty/phing/tasks/system/UpToDateTask.php new file mode 100644 index 000000000..407f322eb --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/UpToDateTask.php @@ -0,0 +1,217 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'phing/tasks/system/condition/Condition.php'; +include_once 'phing/util/DirectoryScanner.php'; +include_once 'phing/util/SourceFileScanner.php'; +include_once 'phing/mappers/MergeMapper.php'; + +/** + * Sets the given property if the specified target has a timestamp + * greater than all of the source files. + * + * @author Hans Lellelid (Phing) + * @author William Ferguson (Ant) + * @author Hiroaki Nakamura (Ant) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.6 $ + * @package phing.tasks.system + */ +class UpToDateTask extends Task implements Condition { + + private $_property; + private $_value; + private $_sourceFile; + private $_targetFile; + private $sourceFileSets = array(); + + protected $mapperElement = null; + + /** + * The property to set if the target file is more up-to-date than + * (each of) the source file(s). + * + * @param property the name of the property to set if Target is up-to-date. + */ + public function setProperty($property) { + $this->_property = $property; + } + + /** + * The value to set the named property to if the target file is more + * up-to-date than (each of) the source file(s). Defaults to 'true'. + * + * @param value the value to set the property to if Target is up-to-date + */ + public function setValue($value) { + $this->_value = $value; + } + + /** + * Returns the value, or "true" if a specific value wasn't provided. + */ + private function getValue() { + return ($this->_value !== null) ? $this->_value : "true"; + } + + /** + * The file which must be more up-to-date than (each of) the source file(s) + * if the property is to be set. + * + * @param file the file we are checking against. + */ + public function setTargetFile($file) { + if (is_string($file)) { + $file = new PhingFile($file); + } + $this->_targetFile = $file; + } + + /** + * The file that must be older than the target file + * if the property is to be set. + * + * @param file the file we are checking against the target file. + */ + public function setSrcfile($file) { + if (is_string($file)) { + $file = new PhingFile($file); + } + $this->_sourceFile = $file; + } + + /** + * Nested element. + */ + public function createSrcfiles() { + $fs = new FileSet(); + $this->sourceFileSets[] = $fs; + return $fs; + } + + /** + * Defines the FileNameMapper to use (nested mapper element). + */ + public function createMapper() { + if ($this->mapperElement !== null) { + throw new BuildException("Cannot define more than one mapper", + $this->location); + } + $this->mapperElement = new Mapper($this->getProject()); + return $this->mapperElement; + } + + /** + * Evaluate (all) target and source file(s) to + * see if the target(s) is/are up-to-date. + * @return boolean + */ + public function evaluate() { + if (count($this->sourceFileSets) === 0 && $this->_sourceFile === null) { + throw new BuildException("At least one srcfile or a nested " + . " element must be set."); + } + + if (count($this->sourceFileSets) > 0 && $this->_sourceFile !== null) { + throw new BuildException("Cannot specify both the srcfile " + . "attribute and a nested " + . "element."); + } + + if ($this->_targetFile === null && $this->mapperElement === null) { + throw new BuildException("The targetfile attribute or a nested " + . "mapper element must be set."); + } + + // if the target file is not there, then it can't be up-to-date + if ($this->_targetFile !== null && !$this->_targetFile->exists()) { + return false; + } + + // if the source file isn't there, throw an exception + if ($this->_sourceFile !== null && !$this->_sourceFile->exists()) { + throw new BuildException($this->_sourceFile->getAbsolutePath() + . " not found."); + } + + $upToDate = true; + for($i=0,$size=count($this->sourceFileSets); $i < $size && $upToDate; $i++) { + $fs = $this->sourceFileSets[$i]; + $ds = $fs->getDirectoryScanner($this->project); + $upToDate = $upToDate && $this->scanDir($fs->getDir($this->project), + $ds->getIncludedFiles()); + } + + if ($this->_sourceFile !== null) { + if ($this->mapperElement === null) { + $upToDate = $upToDate && + ($this->_targetFile->lastModified() >= $this->_sourceFile->lastModified()); + } else { + $sfs = new SourceFileScanner($this); + $upToDate = $upToDate && + count($sfs->restrict($this->_sourceFile->getAbsolutePath(), + null, null, + $this->mapperElement->getImplementation())) === 0; + } + } + return $upToDate; + } + + + /** + * Sets property to true if target file(s) have a more recent timestamp + * than (each of) the corresponding source file(s). + * @throws BuildException + */ + public function main() { + if ($this->_property === null) { + throw new BuildException("property attribute is required.", + $this->location); + } + $upToDate = $this->evaluate(); + if ($upToDate) { + $this->project->setNewProperty($this->_property, $this->getValue()); + if ($this->mapperElement === null) { + $this->log("File \"" . $this->_targetFile->getAbsolutePath() + . "\" is up-to-date.", PROJECT_MSG_VERBOSE); + } else { + $this->log("All target files are up-to-date.", + PROJECT_MSG_VERBOSE); + } + } + } + + protected function scanDir(PhingFile $srcDir, $files) { + $sfs = new SourceFileScanner($this); + $mapper = null; + $dir = $srcDir; + if ($this->mapperElement === null) { + $mm = new MergeMapper(); + $mm->setTo($this->_targetFile->getAbsolutePath()); + $mapper = $mm; + $dir = null; + } else { + $mapper = $this->mapperElement->getImplementation(); + } + return (count($sfs->restrict($files, $srcDir, $dir, $mapper)) === 0); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/WarnTask.php b/gulliver/thirdparty/phing/tasks/system/WarnTask.php new file mode 100644 index 000000000..0afa3eb72 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/WarnTask.php @@ -0,0 +1,35 @@ +. + */ + +require_once 'phing/tasks/system/EchoTask.php'; + +/** + * Simple task to echo a warning message (PROJECT_MSG_WARN) to all output devices. + * + * @author Hans Lellelid + * @version $Revision: 1.1 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @package phing.tasks.system + */ +class WarnTask extends EchoTask { + function main() { + $this->log($this->msg, PROJECT_MSG_WARN); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/XsltTask.php b/gulliver/thirdparty/phing/tasks/system/XsltTask.php new file mode 100644 index 000000000..ec1e2950f --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/XsltTask.php @@ -0,0 +1,81 @@ +. + */ + +require_once 'phing/tasks/system/CopyTask.php'; +include_once 'phing/system/io/FileReader.php'; +include_once 'phing/system/io/FileWriter.php'; +include_once 'phing/filters/XsltFilter.php'; + +/** + * Implements an XSLT processing filter while copying files. + * + * This is a shortcut for calling the task with the XSLTFilter used + * in the section. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.8 $ + * @package phing.tasks.system + */ +class XsltTask extends CopyTask { + + /** XSLTFilter object that we use to handle transformation. */ + private $xsltFilter; + + /** Parameters to pass to XSLT procesor. */ + private $parameters = array(); + + /** + * Setup the filterchains w/ XSLTFilter that we will use while copying the files. + */ + function init() { + $xf = new XsltFilter(); + $chain = $this->createFilterChain($this->getProject()); + $chain->addXsltFilter($xf); + $this->xsltFilter = $xf; + } + + /** + * Set any XSLT Param and invoke CopyTask::main() + * @see CopyTask::main() + */ + function main() { + $this->log("Doing XSLT transformation using stylesheet " . $this->xsltFilter->getStyle(), PROJECT_MSG_VERBOSE); + $this->xsltFilter->setParams($this->parameters); + parent::main(); + } + + /** + * Set the stylesheet to use. + * @param PhingFile $style + */ + function setStyle(PhingFile $style) { + $this->xsltFilter->setStyle($style); + } + + /** + * Support nested tags useing XSLTParam class. + * @return XSLTParam + */ + function createParam() { + $num = array_push($this->parameters, new XSLTParam()); + return $this->parameters[$num-1]; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/AndCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/AndCondition.php new file mode 100644 index 000000000..8b3b03302 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/AndCondition.php @@ -0,0 +1,46 @@ +. + */ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * condition container. + * + * Iterates over all conditions and returns false as soon as one + * evaluates to false. + * + * @author Hans Lellelid + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.7 $ + * @package phing.tasks.system.condition + */ +class AndCondition extends ConditionBase implements Condition { + + public function evaluate() { + foreach($this as $c) { // ConditionBase implements IteratorAggregator + if (!$c->evaluate()) { + return false; + } + } + return true; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/Condition.php b/gulliver/thirdparty/phing/tasks/system/condition/Condition.php new file mode 100644 index 000000000..75a77c135 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/Condition.php @@ -0,0 +1,39 @@ +. + */ + +/** + * Condition interface specification: + * + * Each condition must implement a method applying to this prototye: + * + * @author Hans Lellelid + * @version $Revision: 1.4 $ + * @package phing.tasks.system.condition + */ +interface Condition { + /** + * @return boolean + * @throws BuildException + */ + public function evaluate(); +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/tasks/system/condition/ConditionBase.php b/gulliver/thirdparty/phing/tasks/system/condition/ConditionBase.php new file mode 100644 index 000000000..84a376bc7 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/ConditionBase.php @@ -0,0 +1,195 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +include_once 'phing/Project.php'; +include_once 'phing/tasks/system/AvailableTask.php'; +include_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Abstract baseclass for the task as well as several + * conditions - ensures that the types of conditions inside the task + * and the "container" conditions are in sync. + * + * @author Hans Lellelid + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.16 $ + * @package phing.tasks.system.condition + */ +abstract class ConditionBase extends ProjectComponent implements IteratorAggregate { + + public $conditions = array(); // needs to be public for "inner" class access + + function countConditions() { + return count($this->conditions); + } + + /** + * Required for IteratorAggregate + */ + function getIterator() { + return new ConditionEnumeration($this); + } + + function getConditions() { + return $this->conditions; + } + + /** + * @return void + */ + function addAvailable(AvailableTask $a) { + $this->conditions[] = $a; + } + + /** + * @return NotCondition + */ + function createNot() { + include_once 'phing/tasks/system/condition/NotCondition.php'; + $num = array_push($this->conditions, new NotCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return AndCondition + */ + function createAnd() { + include_once 'phing/tasks/system/condition/AndCondition.php'; + $num = array_push($this->conditions, new AndCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return OrCondition + */ + function createOr() { + include_once 'phing/tasks/system/condition/OrCondition.php'; + $num = array_push($this->conditions, new OrCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return EqualsCondition + */ + function createEquals() { + include_once 'phing/tasks/system/condition/EqualsCondition.php'; + $num = array_push($this->conditions, new EqualsCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return OsCondition + */ + function createOs() { + include_once 'phing/tasks/system/condition/OsCondition.php'; + $num = array_push($this->conditions, new OsCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return IsFalseCondition + */ + function createIsFalse() { + include_once 'phing/tasks/system/condition/IsFalseCondition.php'; + $num = array_push($this->conditions, new IsFalseCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return IsTrueCondition + */ + function createIsTrue() { + include_once 'phing/tasks/system/condition/IsTrueCondition.php'; + $num = array_push($this->conditions, new IsTrueCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return ContainsCondition + */ + function createContains() { + include_once 'phing/tasks/system/condition/ContainsCondition.php'; + $num = array_push($this->conditions, new ContainsCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return IsSetCondition + */ + function createIsSet() { + include_once 'phing/tasks/system/condition/IsSetCondition.php'; + $num = array_push($this->conditions, new IsSetCondition()); + return $this->conditions[$num-1]; + } + + /** + * @return ReferenceExistsCondition + */ + function createReferenceExists() { + include_once 'phing/tasks/system/condition/ReferenceExistsCondition.php'; + $num = array_push($this->conditions, new ReferenceExistsCondition()); + return $this->conditions[$num-1]; + } + +} + +/** + * "Inner" class for handling enumerations. + * Uses build-in PHP5 iterator support. + */ +class ConditionEnumeration implements Iterator { + + /** Current element number */ + private $num = 0; + + /** "Outer" ConditionBase class. */ + private $outer; + + function __construct(ConditionBase $outer) { + $this->outer = $outer; + } + + public function valid() { + return $this->outer->countConditions() > $this->num; + } + + function current() { + $o = $this->outer->conditions[$this->num]; + if ($o instanceof ProjectComponent) { + $o->setProject($this->outer->getProject()); + } + return $o; + } + + function next() { + $this->num++; + } + + function key() { + return $this->num; + } + + function rewind() { + $this->num = 0; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/ContainsCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/ContainsCondition.php new file mode 100644 index 000000000..47a32c404 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/ContainsCondition.php @@ -0,0 +1,76 @@ +. + */ + +require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Is one string part of another string? + * + * @author Hans Lellelid (Phing) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.3 $ + * @package phing.tasks.system.condition + */ +class ContainsCondition implements Condition { + + private $string; + private $subString; + private $caseSensitive = true; + + /** + * The string to search in. + * @param string $a1 + */ + public function setString($a1) { + $this->string = $a1; + } + + /** + * The string to search for. + * @param string $a2 + */ + public function setSubstring($a2) { + $this->subString = $a2; + } + + /** + * Whether to search ignoring case or not. + */ + public function setCaseSensitive($b) { + $this->caseSensitive = (boolean) $b; + } + + /** + * Check whether string contains substring. + * @throws BuildException + */ + public function evaluate() { + if ($this->string === null || $this->subString === null) { + throw new BuildException("both string and substring are required " + . "in contains"); + } + + return $this->caseSensitive + ? strpos($this->string, $this->subString) !== false + : substr(strtolower($this->string), strtolower($this->subString)) !== false; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/EqualsCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/EqualsCondition.php new file mode 100644 index 000000000..6e0377d5e --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/EqualsCondition.php @@ -0,0 +1,78 @@ +. + */ + +require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * A simple string comparator. Compares two strings for eqiality in a + * binary safe manner. Implements the condition interface specification. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.7 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @access public + * @package phing.tasks.system.condition + */ +class EqualsCondition implements Condition { + + private $arg1; + private $arg2; + private $trim = false; + private $caseSensitive = true; + + public function setArg1($a1) { + $this->arg1 = $a1; + } + + public function setArg2($a2) { + $this->arg2 = $a2; + } + + /** + * Should we want to trim the arguments before comparing them? + * @param boolean $b + */ + public function setTrim($b) { + $this->trim = (boolean) $b; + } + + /** + * Should the comparison be case sensitive? + * @param boolean $b + */ + public function setCaseSensitive($b) { + $this->caseSensitive = (boolean) $b; + } + + public function evaluate() { + if ($this->arg1 === null || $this->arg2 === null) { + throw new BuildException("Both arg1 and arg2 are required in equals."); + } + + if ($this->trim) { + $this->arg1 = trim($this->arg1); + $this->arg2 = trim($this->arg2); + } + + //print("[comparison] Comparing '".$this->arg1."' and '".$this->arg2."'\n"); + return $this->caseSensitive ? $this->arg1 === $this->arg2 : strtolower($this->arg1) === strtolower($this->arg2); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/IsFalseCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/IsFalseCondition.php new file mode 100644 index 000000000..158f5e692 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/IsFalseCondition.php @@ -0,0 +1,60 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Condition that tests whether a given string evals to false. + * + * @author Hans Lellelid (Phing) + * @author Steve Loughran (Ant) + * @version $Revision: 1.4 $ + * @package phing.tasks.system.condition + */ +class IsFalseCondition extends ProjectComponent implements Condition { + + /** + * what we eval + */ + private $value; + + /** + * Set the value to be tested. + * @param boolean $value + */ + public function setValue($value) { + $this->value = $value; + } + + /** + * return the inverted value; + * @throws BuildException if someone forgot to spec a value + */ + public function evaluate() { + if ($this->value === null) { + throw new BuildException("Nothing to test for falsehood"); + } + return !$this->value; + } + +} + diff --git a/gulliver/thirdparty/phing/tasks/system/condition/IsSetCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/IsSetCondition.php new file mode 100644 index 000000000..b8a7ec2fd --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/IsSetCondition.php @@ -0,0 +1,53 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Condition that tests whether a given property has been set. + * + * @author Hans Lellelid (Phing) + * @author Stefan Bodewig (Ant) + * @version $Revision: 1.4 $ + * @package phing.tasks.system.condition + */ +class IsSetCondition extends ProjectComponent implements Condition { + + private $property; + + public function setProperty($p) { + $this->property = $p; + } + + /** + * Check whether property is set. + * @throws BuildException + */ + public function evaluate() { + if ($this->property === null) { + throw new BuildException("No property specified for isset " + . "condition"); + } + return $this->project->getProperty($this->property) !== null; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/IsTrueCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/IsTrueCondition.php new file mode 100644 index 000000000..6def2a973 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/IsTrueCondition.php @@ -0,0 +1,59 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Condition that tests whether a given string evals to true. + * + * @author Hans Lellelid (Phing) + * @author Steve Loughran (Ant) + * @package phing.tasks.system.condition + */ +class IsTrueCondition extends ProjectComponent implements Condition { + + /** + * what we eval + */ + private $value; + + /** + * Set the value to be tested. + * @param boolean $value + */ + public function setValue($value) { + $this->value = $value; + } + + /** + * return the inverted value; + * @throws BuildException if someone forgot to spec a value + */ + public function evaluate() { + if ($this->value === null) { + throw new BuildException("Nothing to test for falsehood"); + } + return $this->value; + } + +} + diff --git a/gulliver/thirdparty/phing/tasks/system/condition/NotCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/NotCondition.php new file mode 100644 index 000000000..bb1840885 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/NotCondition.php @@ -0,0 +1,48 @@ +. + */ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * condition. + * + * Evaluates to true if the single condition nested into it is false + * and vice versa. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.6 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @access public + * @package phing.tasks.system.condition + */ +class NotCondition extends ConditionBase implements Condition { + + function evaluate() { + if ($this->countConditions() > 1) { + throw new BuildException("You must not nest more than one condition into "); + } + if ($this->countConditions() < 1) { + throw new BuildException("You must nest a condition into "); + } + $conds = $this->getIterator(); + return !$conds->current()->evaluate(); + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/OrCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/OrCondition.php new file mode 100644 index 000000000..966fac2ec --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/OrCondition.php @@ -0,0 +1,46 @@ +. + */ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * condition container. + * + * Iterates over all conditions and returns true as soon as one + * evaluates to true. + * + * @author Andreas Aderhold + * @copyright 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.8 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @access public + * @package phing.tasks.system.condition + */ +class OrCondition extends ConditionBase implements Condition { + + function evaluate() { + foreach($this as $c) { // ConditionBase implements IteratorAggregator + if ($c->evaluate()) { + return true; + } + } + return false; + } +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/OsCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/OsCondition.php new file mode 100644 index 000000000..d110b68a4 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/OsCondition.php @@ -0,0 +1,63 @@ +. + */ + +require_once 'phing/tasks/system/condition/ConditionBase.php'; + +/** + * Condition that tests the OS type. + * + * @author Andreas Aderhold + * @copyright © 2001,2002 THYRELL. All rights reserved + * @version $Revision: 1.8 $ $Date: 2006-04-28 16:49:47 +0200 (Fri, 28 Apr 2006) $ + * @access public + * @package phing.tasks.system.condition + */ +class OsCondition implements Condition { + + private $family; + + function setFamily($f) { + $this->family = strtolower($f); + } + + function evaluate() { + $osName = strtolower(Phing::getProperty("os.name")); + + if ($this->family !== null) { + if ($this->family === "windows") { + return StringHelper::startsWith("win", $osName); + } elseif ($this->family === "mac") { + return (strpos($osName, "mac") !== false || strpos($osName, "darwin") !== false); + } elseif ($this->family === ("unix")) { + return ( + StringHelper::endsWith("ix", $osName) || + StringHelper::endsWith("ux", $osName) || + StringHelper::endsWith("bsd", $osName) || + StringHelper::startsWith("sunos", $osName) || + StringHelper::startsWith("darwin", $osName) + ); + } + throw new BuildException("Don't know how to detect os family '" . $this->family . "'"); + } + return false; + } + +} diff --git a/gulliver/thirdparty/phing/tasks/system/condition/ReferenceExistsCondition.php b/gulliver/thirdparty/phing/tasks/system/condition/ReferenceExistsCondition.php new file mode 100644 index 000000000..ebfe8a0d3 --- /dev/null +++ b/gulliver/thirdparty/phing/tasks/system/condition/ReferenceExistsCondition.php @@ -0,0 +1,52 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; require_once 'phing/tasks/system/condition/Condition.php'; + +/** + * Condition that tests whether a given reference exists. + * + * @author Matthias Pigulla (Phing) + * @version $Revision: 1.1 $ + * @package phing.tasks.system.condition */ +class ReferenceExistsCondition extends ProjectComponent implements Condition { + + private $refid; + + public function setRef($id) { + $this->refid = (string) $id; + } + + /** + * Check whether the reference exists. + * @throws BuildException + */ + public function evaluate() { + if ($this->refid === null) { + throw new BuildException("No ref attribute specified for reference-exists " + . "condition"); + } + $refs = $this->project->getReferences(); + return isset($refs[$this->refid]); + } + +} + diff --git a/gulliver/thirdparty/phing/types/AbstractFileSet.php b/gulliver/thirdparty/phing/types/AbstractFileSet.php new file mode 100644 index 000000000..5a320a103 --- /dev/null +++ b/gulliver/thirdparty/phing/types/AbstractFileSet.php @@ -0,0 +1,570 @@ +. + */ + +include_once 'phing/system/io/PhingFile.php'; +include_once 'phing/types/DataType.php'; +include_once 'phing/types/PatternSet.php'; +include_once 'phing/types/selectors/BaseSelector.php'; +include_once 'phing/types/selectors/SelectorContainer.php'; +include_once 'phing/types/selectors/BaseSelectorContainer.php'; + +// Load all of the selectors (not really necessary but +// helps reveal parse errors right away) + +include_once 'phing/types/selectors/AndSelector.php'; +include_once 'phing/types/selectors/ContainsSelector.php'; +include_once 'phing/types/selectors/ContainsRegexpSelector.php'; +include_once 'phing/types/selectors/DateSelector.php'; +include_once 'phing/types/selectors/DependSelector.php'; +include_once 'phing/types/selectors/DepthSelector.php'; +include_once 'phing/types/selectors/ExtendSelector.php'; +include_once 'phing/types/selectors/FilenameSelector.php'; +include_once 'phing/types/selectors/MajoritySelector.php'; +include_once 'phing/types/selectors/NoneSelector.php'; +include_once 'phing/types/selectors/NotSelector.php'; +include_once 'phing/types/selectors/OrSelector.php'; +include_once 'phing/types/selectors/PresentSelector.php'; +include_once 'phing/types/selectors/SizeSelector.php'; +include_once 'phing/types/selectors/TypeSelector.php'; + +include_once 'phing/util/DirectoryScanner.php'; + +/** + * The FileSet class provides methods and properties for accessing + * and managing filesets. It extends ProjectComponent and thus inherits + * all methods and properties (not explicitly declared). See ProjectComponent + * for further detail. + * + * TODO: + * - merge this with patternsets: FileSet extends PatternSet !!! + * requires additional mods to the parsing algo + * [HL] .... not sure if that really makes so much sense. I think + * that perhaps they should use common utility class if there really + * is that much shared functionality + * + * @author Andreas Aderhold + * @author Hans Lellelid + * @version $Revision: 1.15 $ $Date: 2005/05/26 13:10:53 $ + * @see ProjectComponent + * @package phing.types + */ +class AbstractFileSet extends DataType implements SelectorContainer { + + // These vars are public for cloning purposes + + /** + * @var boolean + */ + public $useDefaultExcludes = true; + + /** + * @var PatternSet + */ + public $defaultPatterns; + + public $additionalPatterns = array(); + public $dir; + public $isCaseSensitive = true; + public $selectors = array(); + + function __construct($fileset = null) { + if ($fileset !== null && ($fileset instanceof FileSet)) { + $this->dir = $fileset->dir; + $this->defaultPatterns = $fileset->defaultPatterns; + $this->additionalPatterns = $fileset->additionalPatterns; + $this->useDefaultExcludes = $fileset->useDefaultExcludes; + $this->isCaseSensitive = $fileset->isCaseSensitive; + $this->selectors = $fileset->selectors; + } + $this->defaultPatterns = new PatternSet(); + } + + + /** + * Makes this instance in effect a reference to another PatternSet + * instance. + * You must not set another attribute or nest elements inside + * this element if you make it a reference. + */ + function setRefid(Reference $r) { + if ((isset($this->dir) && !is_null($this->dir)) || $this->defaultPatterns->hasPatterns()) { + throw $this->tooManyAttributes(); + } + if (!empty($this->additionalPatterns)) { + throw $this->noChildrenAllowed(); + } + if (!empty($this->selectors)) { + throw $this->noChildrenAllowed(); + } + parent::setRefid($r); + } + + + function setDir($dir) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($dir instanceof PhingFile) { + $dir = $dir->getPath(); + } + $this->dir = new PhingFile((string) $dir); + } + + + function getDir(Project $p) { + if ($this->isReference()) { + return $this->getRef($p)->getDir($p); + } + return $this->dir; + } + + + function createPatternSet() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $num = array_push($this->additionalPatterns, new PatternSet()); + return $this->additionalPatterns[$num-1]; + } + + /** + * add a name entry on the include list + */ + function createInclude() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->defaultPatterns->createInclude(); + } + + /** + * add a name entry on the include files list + */ + function createIncludesFile() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->defaultPatterns->createIncludesFile(); + } + + /** + * add a name entry on the exclude list + */ + function createExclude() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->defaultPatterns->createExclude(); + } + + /** + * add a name entry on the include files list + */ + function createExcludesFile() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + return; + } + return $this->defaultPatterns->createExcludesFile(); + } + + /** + * Sets the set of include patterns. Patterns may be separated by a comma + * or a space. + */ + function setIncludes($includes) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->defaultPatterns->setIncludes($includes); + } + + /** + * Sets the set of exclude patterns. Patterns may be separated by a comma + * or a space. + */ + function setExcludes($excludes) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->defaultPatterns->setExcludes($excludes); + } + + /** + * Sets the name of the file containing the includes patterns. + * + * @param $incl The file to fetch the include patterns from. + * @throws BE + */ + function setIncludesfile($incl) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->defaultPatterns->setIncludesfile($incl); + } + + /** + * Sets the name of the file containing the includes patterns. + * + * @param $excl The file to fetch the exclude patterns from. + * @throws BE + */ + function setExcludesfile($excl) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->defaultPatterns->setExcludesfile($excl); + } + + /** + * Sets whether default exclusions should be used or not. + * + * @param $useDefaultExcludes "true"|"on"|"yes" when default exclusions + * should be used, "false"|"off"|"no" when they + * shouldn't be used. + */ + function setDefaultexcludes($useDefaultExcludes) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->useDefaultExcludes = $useDefaultExcludes; + } + + /** + * Sets case sensitivity of the file system + */ + function setCaseSensitive($isCaseSensitive) { + $this->isCaseSensitive = $isCaseSensitive; + } + + /** returns a reference to the dirscanner object belonging to this fileset */ + function getDirectoryScanner(Project $p) { + if ($this->isReference()) { + $o = $this->getRef($p); + return $o->getDirectoryScanner($p); + } + + if ($this->dir === null) { + throw new BuildException("No directory specified for fileset."); + } + if (!$this->dir->exists()) { + throw new BuildException("Directory ".$this->dir->getAbsolutePath()." not found."); + } + if (!$this->dir->isDirectory()) { + throw new BuildException($this->dir->getAbsolutePath()." is not a directory."); + } + $ds = new DirectoryScanner(); + $this->setupDirectoryScanner($ds, $p); + $ds->scan(); + return $ds; + } + + /** feed dirscanner with infos defined by this fileset */ + protected function setupDirectoryScanner(DirectoryScanner $ds, Project $p) { + if ($ds === null) { + throw new Exception("DirectoryScanner cannot be null"); + } + // FIXME - pass dir directly wehn dirscanner supports File + $ds->setBasedir($this->dir->getPath()); + + foreach($this->additionalPatterns as $addPattern) { + $this->defaultPatterns->append($addPattern, $p); + } + + $ds->setIncludes($this->defaultPatterns->getIncludePatterns($p)); + $ds->setExcludes($this->defaultPatterns->getExcludePatterns($p)); + + $p->log("FileSet: Setup file scanner in dir " . $this->dir->__toString() . " with " . $this->defaultPatterns->toString(), PROJECT_MSG_DEBUG); + + if ($ds instanceof SelectorScanner) { + $ds->setSelectors($this->getSelectors($p)); + } + + if ($this->useDefaultExcludes) { + $ds->addDefaultExcludes(); + } + $ds->setCaseSensitive($this->isCaseSensitive); + } + + + /** + * Performs the check for circular references and returns the + * referenced FileSet. + */ + function getRef(Project $p) { + if (!$this->checked) { + $stk = array(); + array_push($stk, $this); + $this->dieOnCircularReference($stk, $p); + } + + $o = $this->ref->getReferencedObject($p); + if (!($o instanceof FileSet)) { + $msg = $this->ref->getRefId()." doesn't denote a fileset"; + throw new BuildException($msg); + } else { + return $o; + } + } + + // SelectorContainer methods + + /** + * Indicates whether there are any selectors here. + * + * @return boolean Whether any selectors are in this container + */ + public function hasSelectors() { + if ($this->isReference() && $this->getProject() !== null) { + return $this->getRef($this->getProject())->hasSelectors(); + } + return !empty($this->selectors); + } + + /** + * Indicates whether there are any patterns here. + * + * @return boolean Whether any patterns are in this container. + */ + public function hasPatterns() { + + if ($this->isReference() && $this->getProject() !== null) { + return $this->getRef($this->getProject())->hasPatterns(); + } + + if ($this->defaultPatterns->hasPatterns($this->getProject())) { + return true; + } + + for($i=0,$size=count($this->additionalPatterns); $i < $size; $i++) { + $ps = $this->additionalPatterns[$i]; + if ($ps->hasPatterns($this->getProject())) { + return true; + } + } + + return false; + } + + /** + * Gives the count of the number of selectors in this container + * + * @return int The number of selectors in this container + */ + public function selectorCount() { + if ($this->isReference() && $this->getProject() !== null) { + try { + return $this->getRef($this->getProject())->selectorCount(); + } catch (Exception $e) { + throw $e; + } + } + return count($this->selectors); + } + + /** + * Returns the set of selectors as an array. + * + * @return an array of selectors in this container + */ + public function getSelectors(Project $p) { + if ($this->isReference()) { + return $this->getRef($p)->getSelectors($p); + } else { + // *copy* selectors + $result = array(); + for($i=0,$size=count($this->selectors); $i < $size; $i++) { + $result[] = clone $this->selectors[$i]; + } + return $result; + } + } + + /** + * Returns an array for accessing the set of selectors. + * + * @return array The array of selectors + */ + public function selectorElements() { + if ($this->isReference() && $this->getProject() !== null) { + return $this->getRef($this->getProject())->selectorElements(); + } + return $this->selectors; + } + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + */ + public function appendSelector(FileSelector $selector) { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $this->selectors[] = $selector; + } + + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public function createSelector() { + $o = new SelectSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an "And" selector entry on the selector list + */ + public function createAnd() { + $o = new AndSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an "Or" selector entry on the selector list + */ + public function createOr() { + $o = new OrSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a "Not" selector entry on the selector list + */ + public function createNot() { + $o = new NotSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a "None" selector entry on the selector list + */ + public function createNone() { + $o = new NoneSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a majority selector entry on the selector list + */ + public function createMajority() { + $o = new MajoritySelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector date entry on the selector list + */ + public function createDate() { + $o = new DateSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector size entry on the selector list + */ + public function createSize() { + $o = new SizeSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector filename entry on the selector list + */ + public function createFilename() { + $o = new FilenameSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an extended selector entry on the selector list + */ + public function createCustom() { + $o = new ExtendSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a contains selector entry on the selector list + */ + public function createContains() { + $o = new ContainsSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a contains selector entry on the selector list + */ + public function createContainsRegexp() { + $o = new ContainsRegexpSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a present selector entry on the selector list + */ + public function createPresent() { + $o = new PresentSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a depth selector entry on the selector list + */ + public function createDepth() { + $o = new DepthSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a depends selector entry on the selector list + */ + public function createDepend() { + $o = new DependSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a type selector entry on the selector list + */ + public function createType() { + $o = new TypeSelector(); + $this->appendSelector($o); + return $o; + } +} diff --git a/gulliver/thirdparty/phing/types/Commandline.php b/gulliver/thirdparty/phing/types/Commandline.php new file mode 100644 index 000000000..f46c36e22 --- /dev/null +++ b/gulliver/thirdparty/phing/types/Commandline.php @@ -0,0 +1,467 @@ +. + */ + + +/** + * Commandline objects help handling command lines specifying processes to + * execute. + * + * The class can be used to define a command line as nested elements or as a + * helper to define a command line by an application. + *

    + * + * <someelement>
    + *   <acommandline executable="/executable/to/run">
    + *     <argument value="argument 1" />
    + *     <argument line="argument_1 argument_2 argument_3" />
    + *     <argument value="argument 4" />
    + *   </acommandline>
    + * </someelement>
    + *
    + * The element someelement must provide a method + * createAcommandline which returns an instance of this class. + * + * @author thomas.haas@softwired-inc.com + * @author Stefan Bodewig + */ +class Commandline { + + /** + * @var array CommandlineArguments[] + */ + public $arguments = array(); // public so "inner" class can access + + /** + * Full path (if not on %PATH% env var) to executable program. + * @var string + */ + public $executable; // public so "inner" class can access + + const DISCLAIMER = "The ' characters around the executable and arguments are not part of the command."; + + public function __construct($to_process = null) { + if ($to_process !== null) { + $tmp = $this->translateCommandline($to_process); + if ($tmp) { + $this->setExecutable(array_shift($tmp)); // removes first el + foreach($tmp as $arg) { // iterate through remaining elements + $this->createArgument()->setValue($arg); + } + } + } + } + + + /** + * Creates an argument object and adds it to our list of args. + * + *

    Each commandline object has at most one instance of the + * argument class.

    + * + * @param boolean $insertAtStart if true, the argument is inserted at the + * beginning of the list of args, otherwise it is appended. + * @return CommandlineArgument + */ + public function createArgument($insertAtStart = false) { + $argument = new CommandlineArgument($this); + if ($insertAtStart) { + array_unshift($this->arguments, $argument); + } else { + array_push($this->arguments, $argument); + } + return $argument; + } + + /** + * Sets the executable to run. + */ + public function setExecutable($executable) { + if (!$executable) { + return; + } + $this->executable = $executable; + $this->executable = strtr($this->executable, '/', DIRECTORY_SEPARATOR); + $this->executable = strtr($this->executable, '\\', DIRECTORY_SEPARATOR); + } + + public function getExecutable() { + return $this->executable; + } + + public function addArguments($line) { + foreach($line as $arg) { + $this->createArgument()->setValue($arg); + } + } + + /** + * Returns the executable and all defined arguments. + * @return array + */ + public function getCommandline() { + $args = $this->getArguments(); + if ($this->executable === null) { + return $args; + } + return array_merge(array($this->executable), $args); + } + + + /** + * Returns all arguments defined by addLine, + * addValue or the argument object. + */ + public function getArguments() { + $result = array(); + foreach($this->arguments as $arg) { + $parts = $arg->getParts(); + if ($parts !== null) { + foreach($parts as $part) { + $result[] = $part; + } + } + } + return $result; + } + + public function __toString() { + return self::toString($this->getCommandline()); + } + + /** + * Put quotes around the given String if necessary. + * + *

    If the argument doesn't include spaces or quotes, return it + * as is. If it contains double quotes, use single quotes - else + * surround the argument by double quotes.

    + * + * @exception BuildException if the argument contains both, single + * and double quotes. + */ + public static function quoteArgument($argument) { + if (strpos($argument, "\"") !== false) { + if (strpos($argument, "'") !== false) { + throw new BuildException("Can't handle single and double quotes in same argument"); + } else { + return escapeshellarg($argument); + } + } elseif (strpos($argument, "'") !== false || strpos($argument, " ") !== false) { + return escapeshellarg($argument); + //return '\"' . $argument . '\"'; + } else { + return $argument; + } + } + + /** + * Quotes the parts of the given array in way that makes them + * usable as command line arguments. + */ + public static function toString($lines) { + // empty path return empty string + if (!$lines) { + return ""; + } + + // path containing one or more elements + $result = ""; + for ($i = 0, $len=count($lines); $i < $len; $i++) { + if ($i > 0) { + $result .= ' '; + } + $result .= self::quoteArgument($lines[$i]); + } + return $result; + } + + /** + * + * @param string $to_process + * @return array + */ + public static function translateCommandline($to_process) { + + if (!$to_process) { + return array(); + } + + // parse with a simple finite state machine + + $normal = 0; + $inQuote = 1; + $inDoubleQuote = 2; + + $state = $normal; + $args = array(); + $current = ""; + $lastTokenHasBeenQuoted = false; + + $tok = strtok($to_process, ""); + $tokens = preg_split('/(["\' ])/', $to_process, -1, PREG_SPLIT_DELIM_CAPTURE); + while(($nextTok = array_shift($tokens)) !== null) { + switch ($state) { + case $inQuote: + if ("'" == $nextTok) { + $lastTokenHasBeenQuoted = true; + $state = $normal; + } else { + $current .= $nextTok; + } + break; + case $inDoubleQuote: + if ("\"" == $nextTok) { + $lastTokenHasBeenQuoted = true; + $state = $normal; + } else { + $current .= $nextTok; + } + break; + default: + if ("'" == $nextTok) { + $state = $inQuote; + } elseif ("\"" == $nextTok) { + $state = $inDoubleQuote; + } elseif (" " == $nextTok) { + if ($lastTokenHasBeenQuoted || strlen($current) != 0) { + $args[] = $current; + $current = ""; + } + } else { + $current .= $nextTok; + } + $lastTokenHasBeenQuoted = false; + break; + } + } + + if ($lastTokenHasBeenQuoted || strlen($current) != 0) { + $args[] = $current; + } + + if ($state == $inQuote || $state == $inDoubleQuote) { + throw new BuildException("unbalanced quotes in " . $to_process); + } + + return $args; + } + + /** + * @return int Number of components in current commandline. + */ + public function size() { + return count($this->getCommandline()); + } + + public function __copy() { + $c = new Commandline(); + $c->setExecutable($this->executable); + $c->addArguments($this->getArguments()); + return $c; + } + + /** + * Clear out the whole command line. */ + public function clear() { + $this->executable = null; + $this->arguments->removeAllElements(); + } + + /** + * Clear out the arguments but leave the executable in place for + * another operation. + */ + public function clearArgs() { + $this->arguments = array(); + } + + /** + * Return a marker. + * + *

    This marker can be used to locate a position on the + * commandline - to insert something for example - when all + * parameters have been set.

    + * @return CommandlineMarker + */ + public function createMarker() { + return new CommandlineMarker($this, count($this->arguments)); + } + + /** + * Returns a String that describes the command and arguments + * suitable for verbose output before a call to + * Runtime.exec(String[]). + * + *

    This method assumes that the first entry in the array is the + * executable to run.

    + * @param array $args CommandlineArgument[] to use + * @return string + */ + public function describeCommand($args = null) { + + if ($args === null) { + $args = $this->getCommandline(); + } + + if (!$args) { + return ""; + } + + $buf = "Executing '"; + $buf .= $args[0]; + $buf .= "'"; + if (count($args) > 0) { + $buf .= " with "; + $buf .= $this->describeArguments($args, 1); + } else { + $buf .= self::DISCLAIMER; + } + return $buf; + } + + /** + * Returns a String that describes the arguments suitable for + * verbose output before a call to + * Runtime.exec(String[]) + * @param $args arguments to use (default is to use current class args) + * @param $offset ignore entries before this index + * @return string + */ + protected function describeArguments($args = null, $offset = 0) { + if ($args === null) { + $args = $this->getArguments(); + } + + if ($args === null || count($args) <= $offset) { + return ""; + } + + $buf = "argument"; + if (count($args) > $offset) { + $buf .= "s"; + } + $buf .= ":" . Phing::getProperty("line.separator"); + for ($i = $offset, $alen=count($args); $i < $alen; $i++) { + $buf .= "'" . $args[$i] . "'" . Phing::getProperty("line.separator"); + } + $buf .= self::DISCLAIMER; + return $buf; + } +} + + +/** + * "Inner" class used for nested xml command line definitions. + */ +class CommandlineArgument { + + private $parts = array(); + private $outer; + + public function __construct(Commandline $outer) { + $this->outer = $outer; + } + + /** + * Sets a single commandline argument. + * + * @param string $value a single commandline argument. + */ + public function setValue($value) { + $this->parts = array($value); + } + + /** + * Line to split into several commandline arguments. + * + * @param line line to split into several commandline arguments + */ + public function setLine($line) { + if ($line === null) { + return; + } + $this->parts = $this->outer->translateCommandline($line); + } + + /** + * Sets a single commandline argument and treats it like a + * PATH - ensures the right separator for the local platform + * is used. + * + * @param value a single commandline argument. + */ + public function setPath($value) { + $this->parts = array( (string) $value ); + } + + /** + * Sets a single commandline argument to the absolute filename + * of the given file. + * + * @param value a single commandline argument. + */ + public function setFile(PhingFile $value) { + $this->parts = array($value->getAbsolutePath()); + } + + /** + * Returns the parts this Argument consists of. + * @return array string[] + */ + public function getParts() { + return $this->parts; + } +} + +/** + * Class to keep track of the position of an Argument. + */ +//

    This class is there to support the srcfile and targetfile +// elements of <execon> and <transform> - don't know +// whether there might be additional use cases.

    --SB +class CommandlineMarker { + + private $position; + private $realPos = -1; + private $outer; + + public function __construct(Comandline $outer, $position) { + $this->outer = $outer; + $this->position = $position; + } + + /** + * Return the number of arguments that preceeded this marker. + * + *

    The name of the executable - if set - is counted as the + * very first argument.

    + */ + public function getPosition() { + if ($this->realPos == -1) { + $realPos = ($this->outer->executable === null ? 0 : 1); + for ($i = 0; $i < $position; $i++) { + $arg = $this->arguments[$i]; + $realPos += count($arg->getParts()); + } + } + return $this->realPos; + } +} + diff --git a/gulliver/thirdparty/phing/types/DataType.php b/gulliver/thirdparty/phing/types/DataType.php new file mode 100644 index 000000000..1282789ed --- /dev/null +++ b/gulliver/thirdparty/phing/types/DataType.php @@ -0,0 +1,182 @@ +. + */ + +require_once 'phing/ProjectComponent.php'; +include_once 'phing/BuildException.php'; + +/** + * Base class for those classes that can appear inside the build file + * as stand alone data types. + * + * This class handles the common description attribute and provides + * a default implementation for reference handling and checking for + * circular references that is appropriate for types that can not be + * nested inside elements of the same type (i.e. patternset but not path) + * + * @package phing.types + */ +class DataType extends ProjectComponent { + + /** The descriptin the user has set. */ + public $description = null; + + /** Value to the refid attribute. Type of Reference*/ + public $ref = null; + + /** + * Are we sure we don't hold circular references? + * + * Subclasses are responsible for setting this value to false + * if we'd need to investigate this condition (usually because a + * child element has been added that is a subclass of DataType). + * @var boolean + */ + protected $checked = true; + + /** + * Sets a description of the current data type. It will be useful + * in commenting what we are doing. + */ + function setDescription($desc) { + $this->description = (string) $desc; + } + + /** Return the description for the current data type. */ + function getDescription() { + return $this->description; + } + + /** Has the refid attribute of this element been set? */ + function isReference() { + return ($this->ref !== null); + } + + /** + * Set the value of the refid attribute. + * + * Subclasses may need to check whether any other attributes + * have been set as well or child elements have been created and + * thus override this method. if they do they must call parent::setRefid() + * + * @param Reference $r + * @return void + */ + function setRefid(Reference $r) { + $this->ref = $r; + $this->checked = false; + } + + /** + * Check to see whether any DataType we hold references to is + * included in the Stack (which holds all DataType instances that + * directly or indirectly reference this instance, including this + * instance itself). + * + * If one is included, throw a BuildException created by circularReference + * + * This implementation is appropriate only for a DataType that + * cannot hold other DataTypes as children. + * + * The general contract of this method is that it shouldn't do + * anything if checked is true and set it to true on exit. + */ + function dieOnCircularReference(&$stk, Project $p) { + if ($this->checked || !$this->isReference()) { + return; + } + + $o = $this->ref->getReferencedObject($p); + + if ($o instanceof DataType) { + + // TESTME - make sure that in_array() works just as well here + // + // check if reference is in stack + //$contains = false; + //for ($i=0, $size=count($stk); $i < $size; $i++) { + // if ($stk[$i] === $o) { + // $contains = true; + // break; + // } + //} + + if (in_array($o, $stk, true)) { + // throw build exception + throw $this->circularReference(); + } else { + array_push($stk, $o); + $o->dieOnCircularReference($stk, $p); + array_pop($stk); + } + } + $this->checked = true; + } + + /** Performs the check for circular references and returns the referenced object. */ + function getCheckedRef($requiredClass, $dataTypeName) { + + if (!$this->checked) { + // should be in stack + $stk = array(); + $stk[] = $this; + $this->dieOnCircularReference($stk, $this->getProject()); + } + + $o = $this->ref->getReferencedObject($this->getProject()); + if (!($o instanceof $requiredClass) ) { + throw new BuildException($this->ref->getRefId()." doesn't denote a " . $dataTypeName); + } else { + return $o; + } + } + + /** + * Creates an exception that indicates that refid has to be the + * only attribute if it is set. + */ + function tooManyAttributes() { + return new BuildException( "You must not specify more than one attribute when using refid" ); + } + + /** + * Creates an exception that indicates that this XML element must + * not have child elements if the refid attribute is set. + */ + function noChildrenAllowed() { + return new BuildException("You must not specify nested elements when using refid"); + } + + /** + * Creates an exception that indicates the user has generated a + * loop of data types referencing each other. + */ + function circularReference() { + return new BuildException("This data type contains a circular reference."); + } + + /** + * Template method being called when the data type has been + * parsed completely. + * @return void + */ + function parsingComplete() {} +} + diff --git a/gulliver/thirdparty/phing/types/Description.php b/gulliver/thirdparty/phing/types/Description.php new file mode 100644 index 000000000..903b8480b --- /dev/null +++ b/gulliver/thirdparty/phing/types/Description.php @@ -0,0 +1,53 @@ +. + */ + +/** + * Description is used to provide a project-wide description element + * (that is, a description that applies to a buildfile as a whole). + * If present, the <description> element is printed out before the + * target descriptions. + * + * Description has no attributes, only text. There can only be one + * project description per project. A second description element will + * overwrite the first. + * + * @author Hans Lellelid (Phing) + * @author Craeg Strong (Ant) + * @package phing.types + */ +class Description extends DataType { + + /** + * Adds descriptive text to the project. + * + * @return void + */ + public function addText($text) { + $currentDescription = $this->project->getDescription(); + if ($currentDescription === null) { + $this->project->setDescription($text); + } else { + $this->project->setDescription($currentDescription . $text); + } + } + +} diff --git a/gulliver/thirdparty/phing/types/DirSet.php b/gulliver/thirdparty/phing/types/DirSet.php new file mode 100644 index 000000000..f68c2e12e --- /dev/null +++ b/gulliver/thirdparty/phing/types/DirSet.php @@ -0,0 +1,49 @@ +. + */ + +include_once 'phing/types/AbstractFileSet.php'; + +/** + * Subclass as hint for supporting tasks that the included directories + * instead of files should be used. + * + * @package phing.types + */ +class DirSet extends AbstractFileSet { + + public function __construct($dirset = null) { + parent::__construct($dirset); + } + + /** + * Return a DirSet that has the same basedir and same patternsets + * as this one. + */ + public function __clone() { + if ($this->isReference()) { + return new DirSet($this->getRef($this->getProject())); + } else { + return new DirSet($this); + } + } + +} diff --git a/gulliver/thirdparty/phing/types/FileList.php b/gulliver/thirdparty/phing/types/FileList.php new file mode 100644 index 000000000..9b0b01075 --- /dev/null +++ b/gulliver/thirdparty/phing/types/FileList.php @@ -0,0 +1,223 @@ +. + */ + +require_once 'phing/types/DataType.php'; +include_once 'phing/system/io/PhingFile.php'; + +/** + * FileList represents an explicitly named list of files. FileLists + * are useful when you want to capture a list of files regardless of + * whether they currently exist. + * + * + * + * OR + * + * + * + * (or a mixture of files="" and listfile="" can be used) + * + * @author Hans Lellelid + * @version $Revision: 1.10 $ + * @package phing.types + */ +class FileList extends DataType { + + // public for "cloning" purposes + + /** Array containing all filenames. */ + public $filenames = array(); + + /** Base directory for this file list. */ + public $dir; + + /** PhingFile that contains a list of files (one per line). */ + public $listfile; + + /** + * Construct a new FileList. + * @param array $filelist; + */ + function __construct($filelist = null) { + if ($filelist !== null) { + $this->dir = $filelist->dir; + $this->filenames = $filelist->filenames; + $this->listfile = $filelist->listfile; + } + } + + /** + * Makes this instance in effect a reference to another FileList + * instance. + */ + function setRefid(Reference $r) { + if ($this->dir !== null || count($this->filenames) !== 0) { + throw $this->tooManyAttributes(); + } + parent::setRefid($r); + } + + /** + * Base directory for files in list. + * @param PhingFile $dir + */ + function setDir(PhingFile $dir) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if (!($dir instanceof PhingFile)) { + $dir = new PhingFile($dir); + } + $this->dir = $dir; + } + + /** + * Get the basedir for files in list. + * @return PhingFile + */ + function getDir(Project $p) { + if ($this->isReference()) { + $ref = $this->getRef($p); + return $ref->getDir($p); + } + return $this->dir; + } + + /** + * Set the array of files in list. + * @param array $filenames + */ + function setFiles($filenames) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if (!empty($filenames)) { + $tok = strtok($filenames, ", \t\n\r"); + while ($tok !== false) { + $fname = trim($tok); + if ($fname !== "") { + $this->filenames[] = $tok; + } + $tok = strtok(", \t\n\r"); + } + } + } + + /** + * Sets a source "list" file that contains filenames to add -- one per line. + * @param string $file + */ + function setListFile($file) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if (!($file instanceof PhingFile)) { + $file = new PhingFile($file); + } + $this->listfile = $file; + } + + /** + * Get the source "list" file that contains file names. + * @return PhingFile + */ + function getListFile() { + if ($this->isReference()) { + $ref = $this->getRef($p); + return $ref->getListFile($p); + } + return $this->listfile; + } + + /** + * Returns the list of files represented by this FileList. + * @param Project $p + * @return array + */ + function getFiles(Project $p) { + + if ($this->isReference()) { + $ret = $this->getRef($p); + $ret = $ret->getFiles($p); + return $ret; + } + + if ($this->listfile !== null) { + $this->readListFile($p); + } + + return $this->filenames; + } + + + /** + * Performs the check for circular references and returns the + * referenced FileSet. + * @param Project $p + */ + function getRef(Project $p) { + if (!$this->checked) { + $stk = array(); + array_push($stk, $this); + $this->dieOnCircularReference($stk, $p); + } + + $o = $this->ref->getReferencedObject($p); + if (!($o instanceof FileList)) { + throw new BuildException($this->ref->getRefId()." doesn't denote a filelist"); + } else { + return $o; + } + } + + /** + * Reads file names from a file and adds them to the files array. + * @param Project $p + */ + private function readListFile(Project $p) { + $listReader = null; + try { + // Get a FileReader + $listReader = new BufferedReader(new FileReader($this->listfile)); + + $line = $listReader->readLine(); + while ($line !== null) { + if (!empty($line)) { + $line = $p->replaceProperties($line); + $this->filenames[] = trim($line); + } + $line = $listReader->readLine(); + } + } catch (Exception $e) { + if ($listReader) $listReader->close(); + throw new BuildException("An error occured while reading from list file " . $this->listfile->__toString() . ": " . $e->getMessage()); + } + + $listReader->close(); + } + +} + diff --git a/gulliver/thirdparty/phing/types/FileSet.php b/gulliver/thirdparty/phing/types/FileSet.php new file mode 100644 index 000000000..c5a97c522 --- /dev/null +++ b/gulliver/thirdparty/phing/types/FileSet.php @@ -0,0 +1,56 @@ +. + */ + +require_once 'phing/types/AbstractFileSet.php'; + +/** + * Moved out of MatchingTask to make it a standalone object that could + * be referenced (by scripts for example). + * + * @author Hans Lellelid (Phing) + * @author Arnout J. Kuiper (Ant) + * @author Stefano Mazzocchi (Ant) + * @author Sam Ruby (Ant) + * @author Jon S. Stevens (Ant) + * @author Stefan Bodewig (Ant) + * @author Magesh Umasankar (Ant) + * @package phing.types + */ +class FileSet extends AbstractFileSet { + + function __construct($fileset = null) { + parent::__construct($fileset); + } + + /** + * Return a FileSet that has the same basedir and same patternsets + * as this one. + */ + public function __clone() { + if ($this->isReference()) { + return new FileSet($this->getRef($this->getProject())); + } else { + return new FileSet($this); + } + } + +} diff --git a/gulliver/thirdparty/phing/types/FilterChain.php b/gulliver/thirdparty/phing/types/FilterChain.php new file mode 100644 index 000000000..05b79e035 --- /dev/null +++ b/gulliver/thirdparty/phing/types/FilterChain.php @@ -0,0 +1,164 @@ +. + */ + +include_once 'phing/types/DataType.php'; +include_once 'phing/filters/HeadFilter.php'; +include_once 'phing/filters/TailFilter.php'; +include_once 'phing/filters/LineContains.php'; +include_once 'phing/filters/LineContainsRegexp.php'; +include_once 'phing/filters/ExpandProperties.php'; +include_once 'phing/filters/PrefixLines.php'; +include_once 'phing/filters/ReplaceRegexp.php'; +include_once 'phing/filters/ReplaceTokens.php'; +include_once 'phing/filters/StripPhpComments.php'; +include_once 'phing/filters/StripLineBreaks.php'; +include_once 'phing/filters/StripLineComments.php'; +include_once 'phing/filters/TabToSpaces.php'; +include_once 'phing/filters/TidyFilter.php'; +include_once 'phing/filters/TranslateGettext.php'; +include_once 'phing/filters/XsltFilter.php'; + +/* + * FilterChain may contain a chained set of filter readers. + * + * @author Yannick Lecaillez + * @version $Revision: 1.11 $ + * @package phing.types + */ +class FilterChain extends DataType { + + private $filterReaders = array(); + + function __construct(Project $project) { + $this->project = $project; + } + + function getFilterReaders() { + return $this->filterReaders; + } + + function addExpandProperties(ExpandProperties $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addGettext(TranslateGettext $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addHeadFilter(HeadFilter $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addTailFilter(TailFilter $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addLineContains(LineContains $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addLineContainsRegExp(LineContainsRegExp $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addPrefixLines(PrefixLines $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addReplaceTokens(ReplaceTokens $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addReplaceRegexp(ReplaceRegexp $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addStripPhpComments(StripPhpComments $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addStripLineBreaks(StripLineBreaks $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addStripLineComments(StripLineComments $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addTidyFilter(TidyFilter $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addTabToSpaces(TabToSpaces $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addXsltFilter(XsltFilter $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + function addFilterReader(PhingFilterReader $o) { + $o->setProject($this->project); + $this->filterReaders[] = $o; + } + + /* + * Makes this instance in effect a reference to another FilterChain + * instance. + * + *

    You must not set another attribute or nest elements inside + * this element if you make it a reference.

    + * + * @param r the reference to which this instance is associated + * @throw BuildException if this instance already has been configured. + */ + function setRefid(Reference $r) { + + if ( count($this->filterReaders) === 0 ) { + throw $this->tooManyAttributes(); + } + + // change this to get the objects from the other reference + $o = $r->getReferencedObject($this->getProject()); + if ( $o instanceof FilterChain ) { + $this->filterReaders = $o->getFilterReaders(); + } else { + throw new BuildException($r->getRefId()." doesn't refer to a FilterChain"); + } + parent::setRefid($r); + } + +} diff --git a/gulliver/thirdparty/phing/types/Mapper.php b/gulliver/thirdparty/phing/types/Mapper.php new file mode 100644 index 000000000..a84d246e5 --- /dev/null +++ b/gulliver/thirdparty/phing/types/Mapper.php @@ -0,0 +1,207 @@ +. + */ + +include_once 'phing/types/DataType.php'; +include_once 'phing/types/Path.php'; + +/** + * Filename Mapper maps source file name(s) to target file name(s). + * + * Built-in mappers can be accessed by specifying they "type" attribute: + * + * + * + * Custom mappers can be specified by providing a dot-path to a include_path-relative + * class: + * + * + * + * + * + * @author Hans Lellelid + * @package phing.types + */ +class Mapper extends DataType { + + protected $type; + protected $classname; + protected $from; + protected $to; + protected $classpath; + protected $classpathId; + + + function __construct(Project $project) { + $this->project = $project; + } + + /** + * Set the classpath to be used when searching for component being defined + * + * @param Path $classpath An Path object containing the classpath. + */ + public function setClasspath(Path $classpath) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($this->classpath === null) { + $this->classpath = $classpath; + } else { + $this->classpath->append($classpath); + } + } + + /** + * Create the classpath to be used when searching for component being defined + */ + public function createClasspath() { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($this->classpath === null) { + $this->classpath = new Path($this->project); + } + return $this->classpath->createPath(); + } + + /** + * Reference to a classpath to use when loading the files. + */ + public function setClasspathRef(Reference $r) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->classpathId = $r->getRefId(); + $this->createClasspath()->setRefid($r); + } + + /** Set the type of FileNameMapper to use. */ + function setType($type) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->type = $type; + } + + /** Set the class name of the FileNameMapper to use. */ + function setClassname($classname) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->classname = $classname; + } + + /** + * Set the argument to FileNameMapper.setFrom + */ + function setFrom($from) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->from = $from; + } + + /** + * Set the argument to FileNameMapper.setTo + */ + function setTo($to) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->to = $to; + } + + /** + * Make this Mapper instance a reference to another Mapper. + * + * You must not set any other attribute if you make it a reference. + */ + function setRefid($r) { + if ($this->type !== null || $this->from !== null || $this->to !== null) { + throw DataType::tooManyAttributes(); + } + parent::setRefid($r); + } + + /** Factory, returns inmplementation of file name mapper as new instance */ + function getImplementation() { + if ($this->isReference()) { + $tmp = $this->getRef(); + return $tmp->getImplementation(); + } + + if ($this->type === null && $this->classname === null) { + throw new BuildException("either type or classname attribute must be set for "); + } + + if ($this->type !== null) { + switch($this->type) { + case 'identity': + $this->classname = 'phing.mappers.IdentityMapper'; + break; + case 'flatten': + $this->classname = 'phing.mappers.FlattenMapper'; + break; + case 'glob': + $this->classname = 'phing.mappers.GlobMapper'; + break; + case 'regexp': + case 'regex': + $this->classname = 'phing.mappers.RegexpMapper'; + break; + case 'merge': + $this->classname = 'phing.mappers.MergeMapper'; + break; + default: + throw new BuildException("Mapper type {$this->type} not known"); + break; + } + } + + // get the implementing class + $cls = Phing::import($this->classname, $this->classpath); + + $m = new $cls; + $m->setFrom($this->from); + $m->setTo($this->to); + + return $m; + } + + /** Performs the check for circular references and returns the referenced Mapper. */ + private function getRef() { + if (!$this->checked) { + $stk = array(); + $stk[] = $this; + $this->dieOnCircularReference($stk, $this->project); + } + + $o = $this->ref->getReferencedObject($this->project); + if (!($o instanceof Mapper)) { + $msg = $this->ref->getRefId()." doesn't denote a mapper"; + throw new BuildException($msg); + } else { + return $o; + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/types/Parameter.php b/gulliver/thirdparty/phing/types/Parameter.php new file mode 100644 index 000000000..9e62fa19b --- /dev/null +++ b/gulliver/thirdparty/phing/types/Parameter.php @@ -0,0 +1,99 @@ +. +*/ + +include_once 'phing/types/DataType.php'; + +/* + * A parameter is composed of a name, type and value. Nested + * Parameters are also possible, but the using task/type has + * to support them + * + * @author Manuel Holtgrewe + * @author Yannick Lecaillez + * @package phing.types +*/ +class Parameter extends DataType { + + /** Parameter name */ + protected $name; + + /** Paramter type */ + protected $type; + + /** Parameter value */ + protected $value; + + /** Nested parameters */ + protected $parameters = array(); + + function setName($name) { + $this->name = (string) $name; + } + + function setType($type) { + $this->type = (string) $type; + } + + /** + * Sets value to dynamic register slot. + * @param RegisterSlot $value + */ + public function setListeningValue(RegisterSlot $value) { + $this->value = $value; + } + + function setValue($value) { + $this->value = (string) $value; + } + + function getName() { + return $this->name; + } + + function getType() { + return $this->type; + } + + function getValue() { + if ($this->value instanceof RegisterSlot) { + return $this->value->getValue(); + } else { + return $this->value; + } + } + + /** + * @return Parameter + */ + function createParam() { + $num = array_push($this->parameters, new Parameter()); + return $this->parameters[$num-1]; + } + + /** + * @return array Nested parameters. + */ + function getParams() { + return $this->parameters; + } +} + +?> diff --git a/gulliver/thirdparty/phing/types/Parameterizable.php b/gulliver/thirdparty/phing/types/Parameterizable.php new file mode 100644 index 000000000..fbce7d1ad --- /dev/null +++ b/gulliver/thirdparty/phing/types/Parameterizable.php @@ -0,0 +1,32 @@ +. + */ + +/** + * Parameterizable objects take genric key value pairs. + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Magesh Umasankar (Ant) + * @package phing.types + */ +interface Parameterizable { + function setParameters($parameters); +} diff --git a/gulliver/thirdparty/phing/types/Path.php b/gulliver/thirdparty/phing/types/Path.php new file mode 100644 index 000000000..2205d92e5 --- /dev/null +++ b/gulliver/thirdparty/phing/types/Path.php @@ -0,0 +1,456 @@ +. + */ + +require_once 'phing/types/DataType.php'; +include_once 'phing/util/PathTokenizer.php'; +include_once 'phing/types/FileSet.php'; + +/** + * This object represents a path as used by include_path or PATH + * environment variable. + * + * This class has been adopted from the Java Ant equivalent. The ability have + * path structures in Phing is important; however, because of how PHP classes interact + * the ability to specify CLASSPATHs makes less sense than Java.Rather than providing + * CLASSPATH for any tasks that take classes as parameters, perhaps a better + * solution in PHP is to have an IncludePath task, which prepends paths to PHP's include_path + * INI variable. This gets around the problem that simply using a path to load the initial + * PHP class is not enough (in most cases the loaded class may assume that it is on the global + * PHP include_path, and will try to load dependent classes accordingly). The other option is + * to provide a way for this class to add paths to the include path, if desired -- or to create + * an IncludePath subclass. Once added, though, when would a path be removed from the include path? + * + *

    + * + * <sometask>
    + *   <somepath>
    + *     <pathelement location="/path/to/file" />
    + *     <pathelement path="/path/to/class2;/path/to/class3" />
    + *     <pathelement location="/path/to/file3" />
    + *   </somepath>
    + * </sometask>
    + *
    + *

    + * The object implemention sometask must provide a method called + * createSomepath which returns an instance of Path. + * Nested path definitions are handled by the Path object and must be labeled + * pathelement.

    + * + * The path element takes a parameter path which will be parsed + * and split into single elements. It will usually be used + * to define a path from an environment variable. + * + * @author Hans Lellelid (Phing) + * @author Thomas.Haas@softwired-inc.com (Ant) + * @author Stefan Bodewig (Ant) + * @package phing.types + */ +class Path extends DataType { + + private $elements = array(); + + /** + * Constructor for internally instantiated objects sets project. + * @param Project $project + * @param string $path (for use by IntrospectionHelper) + */ + public function __construct($project = null, $path = null) { + if ($project !== null) { + $this->setProject($project); + } + if ($path !== null) { + $this->createPathElement()->setPath($path); + } + } + + /** + * Adds a element definition to the path. + * @param $location the location of the element to add (must not be + * null nor empty. + * @throws BuildException + */ + public function setDir(PhingFile $location) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->createPathElement()->setDir($location); + } + + /** + * Parses a path definition and creates single PathElements. + * @param path the path definition. + * @throws BuildException + */ + public function setPath($path) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + $this->createPathElement()->setPath($path); + } + + /** + * Makes this instance in effect a reference to another Path instance. + * + *

    You must not set another attribute or nest elements inside + * this element if you make it a reference.

    + * @throws BuildException + */ + public function setRefid(Reference $r) { + if (!empty($this->elements)) { + throw $this->tooManyAttributes(); + } + $this->elements[] = $r; + parent::setRefid($r); + } + + /** + * Creates the nested <pathelement> element. + * @throws BuildException + */ + public function createPathElement() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $pe = new PathElement($this); + $this->elements[] = $pe; + return $pe; + } + + /** + * Adds a nested <fileset> element. + * @throws BuildException + */ + public function addFileset(FileSet $fs) { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $this->elements[] = $fs; + $this->checked = false; + } + + /** + * Adds a nested <dirset> element. + * @throws BuildException + */ + public function addDirset(DirSet $dset) { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $this->elements[] = $dset; + $this->checked = false; + } + + /** + * Creates a nested <path> element. + * @throws BuildException + */ + public function createPath() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + $p = new Path($this->project); + $this->elements[] = $p; + $this->checked = false; + return $p; + } + + /** + * Append the contents of the other Path instance to this. + */ + public function append(Path $other) { + if ($other === null) { + return; + } + $l = $other->listPaths(); + foreach($l as $path) { + if (!in_array($path, $this->elements, true)) { + $this->elements[] = $path; + } + } + } + + /** + * Adds the components on the given path which exist to this + * Path. Components that don't exist, aren't added. + * + * @param Path $source - Source path whose components are examined for existence. + */ + public function addExisting(Path $source) { + $list = $source->listPaths(); + foreach($list as $el) { + $f = null; + if ($this->project !== null) { + $f = $this->project->resolveFile($el); + } else { + $f = new PhingFile($el); + } + + if ($f->exists()) { + $this->setDir($f); + } else { + $this->log("dropping " . $f->__toString() . " from path as it doesn't exist", + PROJECT_MSG_VERBOSE); + } + } + } + + /** + * Returns all path elements defined by this and nested path objects. + * @return array List of path elements. + */ + public function listPaths() { + if (!$this->checked) { + // make sure we don't have a circular reference here + $stk = array(); + array_push($stk, $this); + $this->dieOnCircularReference($stk, $this->project); + } + + $result = array(); + for ($i = 0, $elSize=count($this->elements); $i < $elSize; $i++) { + $o = $this->elements[$i]; + if ($o instanceof Reference) { + $o = $o->getReferencedObject($this->project); + // we only support references to paths right now + if (!($o instanceof Path)) { + $msg = $r->getRefId() . " doesn't denote a path"; + throw new BuildException($msg); + } + } + + if (is_string($o)) { + $result[] = $o; + } elseif ($o instanceof PathElement) { + $parts = $o->getParts(); + if ($parts === null) { + throw new BuildException("You must either set location or" + . " path on "); + } + foreach($parts as $part) { + $result[] = $part; + } + } elseif ($o instanceof Path) { + $p = $o; + if ($p->getProject() === null) { + $p->setProject($this->getProject()); + } + $parts = $p->listPaths(); + foreach($parts as $part) { + $result[] = $part; + } + } elseif ($o instanceof DirSet) { + $dset = $o; + $ds = $dset->getDirectoryScanner($this->project); + $dirstrs = $ds->getIncludedDirectories(); + $dir = $dset->getDir($this->project); + $this->addUnlessPresent($result, $dir, $s); + + foreach($dirstrs as $dstr) { + $d = new PhingFile($dir, $dstr); + $result[] = $d->getAbsolutePath(); + } + + } elseif ($o instanceof FileList) { + $fl = $o; + $dirstrs = $fl->getFiles($this->project); + $dir = $fl->getDir($this->project); + foreach($dirstrs as $dstr) { + $d = new PhingFile($dir, $dstr); + $result[] = $d->getAbsolutePath(); + } + } + } + + return array_unique($result); + } + + + /** + * Returns a textual representation of the path, which can be used as + * CLASSPATH or PATH environment variable definition. + * @return string A textual representation of the path. + */ + public function __toString() { + + $list = $this->listPaths(); + + // empty path return empty string + if (empty($list)) { + return ""; + } + + return implode(PATH_SEPARATOR, $list); + } + + /** + * Splits a PATH (with : or ; as separators) into its parts. + * @param Project $project + * @param string $source + */ + public static function translatePath(Project $project, $source) { + $result = array(); + if ($source == null) { + return ""; + } + + $tok = new PathTokenizer($source); + $element = ""; + while ($tok->hasMoreTokens()) { + $pathElement = $tok->nextToken(); + try { + $element .= self::resolveFile($project, $pathElement); + } catch (BuildException $e) { + $this->project->log("Dropping path element " . $pathElement + . " as it is not valid relative to the project", + PROJECT_MSG_VERBOSE); + } + + for ($i = 0, $_i=strlen($element); $i < $_i; $i++) { + self::translateFileSep($element, $i); + } + $result[] = $element; + } + + return $result; + } + + /** + * Returns its argument with all file separator characters + * replaced so that they match the local OS conventions. + */ + public static function translateFile($source) { + if ($source == null) { + return ""; + } + + $result = $source; + for ($i = 0, $_i=strlen($source); $i < $_i; $i++) { + self::translateFileSep($result, $i); + } + + return $result; + } + + /** + * Translates all occurrences of / or \ to correct separator of the + * current platform and returns whether it had to do any + * replacements. + */ + protected static function translateFileSep(&$buffer, $pos) { + if ($buffer{$pos} == '/' || $buffer{$pos} == '\\') { + $buffer{$pos} = DIRECTORY_SEPARATOR; + return true; + } + return false; + } + + /** + * How many parts does this Path instance consist of. + * DEV NOTE: expensive call! list is generated, counted, and then + * discareded. + * @return int + */ + public function size() { + return count($this->listPaths()); + } + + /** + * Return a Path that holds the same elements as this instance. + */ + public function __clone() { + $p = new Path($this->project); + $p->append($this); + return $p; + } + + /** + * Overrides the version of DataType to recurse on all DataType + * child elements that may have been added. + * @throws BuildException + */ + public function dieOnCircularReference(&$stk, Project $p) { + + if ($this->checked) { + return; + } + + // elements can contain strings, FileSets, Reference, etc. + foreach($this->elements as $o) { + + if ($o instanceof Reference) { + $o = $o->getReferencedObject($p); + } + + if ($o instanceof DataType) { + if (in_array($o, $stk, true)) { + throw $this->circularReference(); + } else { + array_push($stk, $o); + $o->dieOnCircularReference($stk, $p); + array_pop($stk); + } + } + } + + $this->checked = true; + } + + /** + * Resolve a filename with Project's help - if we know one that is. + * + *

    Assume the filename is absolute if project is null.

    + */ + private static function resolveFile(Project $project, $relativeName) { + if ($project !== null) { + $f = $project->resolveFile($relativeName); + return $f->getAbsolutePath(); + } + return $relativeName; + } + +} + + +/** + * Helper class, holds the nested <pathelement> values. + */ +class PathElement { + + private $parts = array(); + private $outer; + + public function __construct(Path $outer) { + $this->outer = $outer; + } + + public function setDir(PhingFile $loc) { + $this->parts = array(Path::translateFile($loc->getAbsolutePath())); + } + + public function setPath($path) { + $this->parts = Path::translatePath($this->outer->getProject(), $path); + } + + public function getParts() { + return $this->parts; + } +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/types/PatternSet.php b/gulliver/thirdparty/phing/types/PatternSet.php new file mode 100644 index 000000000..27ce31638 --- /dev/null +++ b/gulliver/thirdparty/phing/types/PatternSet.php @@ -0,0 +1,449 @@ +. + */ + +include_once 'phing/system/io/FileReader.php'; +include_once 'phing/types/DataType.php'; + +/** + * The patternset storage component. Carries all necessary data and methods + * for the patternset stuff. + * + * @author Andreas Aderhold, andi@binarycloud.com + * @version $Revision: 1.8 $ + * @package phing.types + */ +class PatternSet extends DataType { + + private $includeList = array(); + private $excludeList = array(); + private $includesFileList = array(); + private $excludesFileList = array(); + + /** + * Makes this instance in effect a reference to another PatternSet + * instance. + * You must not set another attribute or nest elements inside + * this element if you make it a reference. + */ + function setRefid(Reference $r) { + if (!empty($this->includeList) || !empty($this->excludeList)) { + throw $this->tooManyAttributes(); + } + parent::setRefid($r); + } + + + /** + * Add a name entry on the include list + * + * @returns PatternSetNameEntry Reference to object + * @throws BuildException + */ + function createInclude() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->addPatternToList($this->includeList); + } + + + /** + * Add a name entry on the include files list + * + * @returns PatternSetNameEntry Reference to object + * @throws BuildException + */ + function createIncludesFile() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->addPatternToList($this->includesFileList); + } + + /** + * Add a name entry on the exclude list + * + * @returns PatternSetNameEntry Reference to object + * @throws BuildException + */ + function createExclude() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + return $this->addPatternToList($this->excludeList); + } + + /** + * add a name entry on the exclude files list + * + * @returns PatternSetNameEntry Reference to object + * @throws BuildException + */ + + function createExcludesFile() { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + return; + } + return $this->addPatternToList($this->excludesFileList); + } + + + /** + * Sets the set of include patterns. Patterns may be separated by a comma + * or a space. + * + * @param string the string containing the include patterns + * @returns void + * @throws BuildException + */ + function setIncludes($includes) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($includes !== null && strlen($includes) > 0) { + $tok = strtok($includes, ", "); + while ($tok !== false) { + $o = $this->createInclude(); + $o->setName($tok); + $tok = strtok(", "); + } + } + } + + + /** + * Sets the set of exclude patterns. Patterns may be separated by a comma + * or a space. + * + * @param string the string containing the exclude patterns + * @returns void + * @throws BuildException + */ + + function setExcludes($excludes) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($excludes !== null && strlen($excludes) > 0) { + $tok = strtok($excludes, ", "); + while ($tok !== false) { + $o = $this->createExclude(); + $o->setName($tok); + $tok = strtok(", "); + } + } + } + + /** + * add a name entry to the given list + * + * @param array List onto which the nameentry should be added + * @returns PatternSetNameEntry Reference to the created PsetNameEntry instance + */ + private function addPatternToList(&$list) { + $num = array_push($list, new PatternSetNameEntry()); + return $list[$num-1]; + } + + /** + * Sets the name of the file containing the includes patterns. + * + * @param includesFile The file to fetch the include patterns from. + */ + function setIncludesFile($includesFile) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($includesFile instanceof File) { + $includesFile = $includesFile->getPath(); + } + $o = $this->createIncludesFile(); + $o->setName($includesFile); + } + + /** + * Sets the name of the file containing the excludes patterns. + * + * @param excludesFile The file to fetch the exclude patterns from. + */ + function setExcludesFile($excludesFile) { + if ($this->isReference()) { + throw $this->tooManyAttributes(); + } + if ($excludesFile instanceof File) { + $excludesFile = $excludesFile->getPath(); + } + $o = $this->createExcludesFile(); + $o->setName($excludesFile); + } + + + /** + * Reads path matching patterns from a file and adds them to the + * includes or excludes list + */ + private function readPatterns(PhingFile $patternfile, &$patternlist, Project $p) { + $patternReader = null; + try { + // Get a FileReader + $patternReader = new BufferedReader(new FileReader($patternfile)); + + // Create one NameEntry in the appropriate pattern list for each + // line in the file. + $line = $patternReader->readLine(); + while ($line !== null) { + if (!empty($line)) { + $line = $p->replaceProperties($line); + $this->addPatternToList($patternlist)->setName($line); + } + $line = $patternReader->readLine(); + } + + } catch (IOException $ioe) { + $msg = "An error occured while reading from pattern file: " . $patternfile->__toString(); + if($patternReader) $patternReader->close(); + throw new BuildException($msg, $ioe); + } + + $patternReader->close(); + } + + + /** Adds the patterns of the other instance to this set. */ + function append($other, $p) { + if ($this->isReference()) { + throw new BuildException("Cannot append to a reference"); + } + + $incl = $other->getIncludePatterns($p); + if ($incl !== null) { + foreach($incl as $incl_name) { + $o = $this->createInclude(); + $o->setName($incl_name); + } + } + + $excl = $other->getExcludePatterns($p); + if ($excl !== null) { + foreach($excl as $excl_name) { + $o = $this->createExclude(); + $o->setName($excl_name); + } + } + } + + /** Returns the filtered include patterns. */ + function getIncludePatterns(Project $p) { + if ($this->isReference()) { + $o = $this->getRef($p); + return $o->getIncludePatterns($p); + } else { + $this->readFiles($p); + return $this->makeArray($this->includeList, $p); + } + } + + /** Returns the filtered exclude patterns. */ + function getExcludePatterns(Project $p) { + if ($this->isReference()) { + $o = $this->getRef($p); + return $o->getExcludePatterns($p); + } else { + $this->readFiles($p); + return $this->makeArray($this->excludeList, $p); + } + } + + /** helper for FileSet. */ + function hasPatterns() { + return (boolean) count($this->includesFileList) > 0 || count($this->excludesFileList) > 0 + || count($this->includeList) > 0 || count($this->excludeList) > 0; + } + + /** + * Performs the check for circular references and returns the + * referenced PatternSet. + */ + function getRef(Project $p) { + if (!$this->checked) { + $stk = array(); + array_push($stk, $this); + $this->dieOnCircularReference($stk, $p); + } + $o = $this->ref->getReferencedObject($p); + if (!($o instanceof PatternSet)) { + $msg = $this->ref->getRefId()." doesn't denote a patternset"; + throw new BuildException($msg); + } else { + return $o; + } + } + + /** Convert a array of PatternSetNameEntry elements into an array of Strings. */ + private function makeArray(&$list, Project $p) { + + if (count($list) === 0) { + return null; + } + + $tmpNames = array(); + foreach($list as $ne) { + $pattern = (string) $ne->evalName($p); + if ($pattern !== null && strlen($pattern) > 0) { + array_push($tmpNames, $pattern); + } + } + return $tmpNames; + } + + /** Read includesfile or excludesfile if not already done so. */ + private function readFiles(Project $p) { + if (!empty($this->includesFileList)) { + foreach($this->includesFileList as $ne) { + $fileName = (string) $ne->evalName($p); + if ($fileName !== null) { + $inclFile = $p->resolveFile($fileName); + if (!$inclFile->exists()) { + throw new BuildException("Includesfile ".$inclFile->getAbsolutePath()." not found."); + } + $this->readPatterns($inclFile, $this->includeList, $p); + } + } + $this->includesFileList = array(); + } + + if (!empty($this->excludesFileList)) { + foreach($this->excludesFileList as $ne) { + $fileName = (string) $ne->evalName($p); + if ($fileName !== null) { + $exclFile = $p->resolveFile($fileName); + if (!$exclFile->exists()) { + throw new BuildException("Excludesfile ".$exclFile->getAbsolutePath()." not found."); + return; + } + $this->readPatterns($exclFile, $this->excludeList, $p); + } + } + $this->excludesFileList = array(); + } + } + + + function toString() { + + // We can't compile includeList into array because, toString() does + // not know about project: + // + // $includes = $this->makeArray($this->includeList, $this->project); + // $excludes = $this->makeArray($this->excludeList, $this->project); + + if (empty($this->includeList)) { + $includes = "empty"; + } else { + $includes = ""; + foreach($this->includeList as $ne) { + $includes .= $ne->toString() . ","; + } + $includes = rtrim($includes, ","); + } + + if (empty($this->excludeList)) { + $excludes = "empty"; + } else { + $excludes = ""; + foreach($this->excludeList as $ne) { + $excludes .= $ne->toString() . ","; + } + $excludes = rtrim($excludes, ","); + } + + return "patternSet{ includes: $includes excludes: $excludes }"; + } +} + + +/* + * Note, this class here should become a nested class to + * PatternSet (PatternSet:NameEntry) as it is only needed + * internally. + * This is not possible with php 4.x right now so we place + * this class (against good style) in this file. + */ + +class PatternSetNameEntry { + + private $name = null; + private $ifCond = null; + private $unlessCond = null; + + function setName($name) { + $this->name = (string) $name; + } + + + function setIf($cond) { + $this->ifCond = (string) $cond; + } + + + function setUnless($cond) { + $this->unlessCond = (string) $cond; + } + + + function getName() { + return $this->name; + } + + + function evalName($project) { + return $this->valid($project) ? $this->name : null; + } + + + function valid($project) { + if ($this->ifCond !== null && $project->getProperty($this->ifCond) === null) { + return false; + } else if ($this->unlessCond !== null && $project->getProperty($this->unlessCond) !== null) { + return false; + } + return true; + } + + + function toString() { + $buf = $this->name; + if (($this->ifCond !== null) || ($this->unlessCond !== null)) { + $buf .= ":"; + $connector = ""; + + if ($this->ifCond !== null) { + $buf .= "if->{$this->ifCond}"; + $connector = ";"; + } + if ($this->unlessCond !== null) { + $buf .= "$connector unless->{$this->unlessCond}"; + } + } + return $buf; + } +} diff --git a/gulliver/thirdparty/phing/types/PhingFilterReader.php b/gulliver/thirdparty/phing/types/PhingFilterReader.php new file mode 100644 index 000000000..61db347b3 --- /dev/null +++ b/gulliver/thirdparty/phing/types/PhingFilterReader.php @@ -0,0 +1,136 @@ +. +*/ + +include_once 'phing/types/DataType.php'; +include_once 'phing/types/Parameter.php'; + +/* + * A PhingFilterReader is a wrapper class that encloses the className + * and configuration of a Configurable FilterReader. + * + * @author Yannick Lecaillez + * @version $Revision: 1.9 $ + * @see FilterReader + * @package phing.types +*/ +class PhingFilterReader extends DataType { + + private $className; + private $parameters = array(); + private $classPath; + + function setClassName($className) { + $this->className = $className; + } + + function getClassName() { + return $this->className; + } + + /** + * Set the classpath to load the FilterReader through (attribute). + * @param Path $classpath + */ + function setClasspath(Path $classpath) { + if ( $this->isReference() ) { + throw $this->tooManyAttributes(); + } + if ( $this->classPath === null ) { + $this->classPath = $classpath; + } else { + $this->classPath->append($classpath); + } + } + + /* + * Set the classpath to load the FilterReader through (nested element). + */ + function createClasspath() { + if ( $this->isReference() ) { + throw $this->noChildrenAllowed(); + } + if ( $this->classPath === null ) { + $this->classPath = new Path($this->project); + } + return $this->classPath->createPath(); + } + + function getClasspath() { + return $this->classPath; + } + + function setClasspathRef(Reference $r) { + if ( $this->isReference() ) { + throw $this->tooManyAttributes(); + } + $o = $this->createClasspath(); + $o->setRefid($r); + } + + function addParam(Parameter $param) { + $this->parameters[] = $param; + } + + function createParam() { + $num = array_push($this->parameters, new Parameter()); + return $this->parameters[$num-1]; + } + + function getParams() { + // We return a COPY + $ret = array(); + for($i=0,$size=count($this->parameters); $i < $size; $i++) { + $ret[] = clone $this->parameters[$i]; + } + return $ret; + } + + /* + * Makes this instance in effect a reference to another PhingFilterReader + * instance. + * + *

    You must not set another attribute or nest elements inside + * this element if you make it a reference.

    + * + * @param Reference $r the reference to which this instance is associated + * @exception BuildException if this instance already has been configured. + */ + function setRefid(Reference $r) { + if ( (count($this->parameters) !== 0) || ($this->className !== null) ) { + throw $this->tooManyAttributes(); + } + $o = $r->getReferencedObject($this->getProject()); + if ( $o instanceof PhingFilterReader ) { + $this->setClassName($o->getClassName()); + $this->setClasspath($o->getClassPath()); + foreach($o->getParams() as $p) { + $this->addParam($p); + } + } else { + $msg = $r->getRefId()." doesn\'t refer to a PhingFilterReader"; + throw new BuildException($msg); + } + + parent::setRefid($r); + } +} + +?> diff --git a/gulliver/thirdparty/phing/types/Reference.php b/gulliver/thirdparty/phing/types/Reference.php new file mode 100644 index 000000000..7e0af2fb4 --- /dev/null +++ b/gulliver/thirdparty/phing/types/Reference.php @@ -0,0 +1,56 @@ +. + */ + +/** Class to hold a reference to another object in the project. + * @package phing.types + */ +class Reference { + + protected $refid; + + function __construct($id = null) { + if ($id !== null) { + $this->setRefId($id); + } + } + + function setRefId($id) { + $this->refid = (string) $id; + } + + function getRefId() { + return $this->refid; + } + + /** returns reference to object in references container of project */ + function getReferencedObject($project) { + if ($this->refid === null) { + throw new BuildException("No reference specified"); + } + $refs = $project->getReferences(); + $o = @$refs[$this->refid]; + if (!is_object($o)) { + throw new BuildException("Reference {$this->refid} not found."); + } + return $o; + } +} +?> diff --git a/gulliver/thirdparty/phing/types/RegularExpression.php b/gulliver/thirdparty/phing/types/RegularExpression.php new file mode 100644 index 000000000..24626543a --- /dev/null +++ b/gulliver/thirdparty/phing/types/RegularExpression.php @@ -0,0 +1,105 @@ +. +*/ + +include_once 'phing/types/DataType.php'; +include_once 'phing/Project.php'; +include_once 'phing/util/regexp/Regexp.php'; + +/* + * A regular expression datatype. Keeps an instance of the + * compiled expression for speed purposes. This compiled + * expression is lazily evaluated (it is compiled the first + * time it is needed). The syntax is the dependent on which + * regular expression type you are using. + * + * @author Yannick Lecaillez + * @version $Revision: 1.6 $ $Date: 2003/12/24 12:38:42 $ + * @access public + * @see phing.util.regex.RegexMatcher + * @package phing.types +*/ +class RegularExpression extends DataType { + + private $regexp = null; + private $ignoreCase = false; + + function __construct() { + $this->regexp = new Regexp(); + } + + function setPattern($pattern) { + $this->regexp->setPattern($pattern); + } + + function setReplace($replace) { + $this->regexp->setReplace($replace); + } + + function getPattern($p) { + if ( $this->isReference() ) { + $ref = $this->getRef($p); + return $ref->getPattern($p); + } + return $this->regexp->getPattern(); + } + + function getReplace($p) { + if ( $this->isReference() ) { + $ref = $this->getRef($p); + return $ref->getReplace($p); + } + + return $this->regexp->getReplace(); + } + + function setIgnoreCase($bit) { + $this->regexp->setIgnoreCase($bit); + } + + function getIgnoreCase() { + return $this->regexp->getIgnoreCase(); + } + + function getRegexp(Project $p) { + if ( $this->isReference() ) { + $ref = $this->getRef($p); + return $ref->getRegexp($p); + } + return $this->regexp; + } + + function getRef(Project $p) { + if ( !$this->checked ) { + $stk = array(); + array_push($stk, $this); + $this->dieOnCircularReference($stk, $p); + } + + $o = $this->ref->getReferencedObject($p); + if ( !($o instanceof RegularExpression) ) { + throw new BuildException($this->ref->getRefId()." doesn't denote a RegularExpression"); + } else { + return $o; + } + } +} + +?> diff --git a/gulliver/thirdparty/phing/types/TokenReader.php b/gulliver/thirdparty/phing/types/TokenReader.php new file mode 100644 index 000000000..319049fa1 --- /dev/null +++ b/gulliver/thirdparty/phing/types/TokenReader.php @@ -0,0 +1,66 @@ +. +*/ + +// include_once 'phing/system/io/Reader.php'; // really this is unrelated to Reader +include_once 'phing/system/io/IOException.php'; +include_once 'phing/filters/ReplaceTokens.php'; // For class Token + +/** + * Abstract class for TokenReaders. + * + * @author Manuel Holtgewe + * @version $Revision: 1.5 $ + * @package phing.filters.util + */ +abstract class TokenReader { + + /** + * Reference to the Project the TokenReader is used in. + * @var Project + */ + protected $project; + + /** + * Constructor + * @param object Reference to the project the TokenReader is used in. + */ + function __construct(Project $project) { + $this->project = $project; + } + + /** + * Utility function for logging + */ + function log($level, $msg) { + $this->project->log($level, $msg); + } + + /** + * Reads the next token from the Reader + * + * @throws IOException - On error + * @return string + */ + abstract public function readToken(); + +} + +?> diff --git a/gulliver/thirdparty/phing/types/TokenSource.php b/gulliver/thirdparty/phing/types/TokenSource.php new file mode 100644 index 000000000..a3fcf4d43 --- /dev/null +++ b/gulliver/thirdparty/phing/types/TokenSource.php @@ -0,0 +1,157 @@ +. +*/ + +require_once 'phing/types/DataType.php'; +include_once 'phing/util/StringHelper.php'; + +/** + * A parameter is composed of a name, type and value. + * + * Example of usage: + * + * + * + * + * + * + * + * + * or: + * + * + * + * + * + * + * + * @author Yannick Lecaillez + * @package phing.types + */ +class TokenSource extends DataType { + + /** + * String to hold the path to the TokenReader + * @var string + */ + protected $classname = null; + + /** + * Array holding parameters for the wrapped TokenReader. + * @var array + */ + protected $parameters = array(); + + /** + * Reference to the TokenReader used by this TokenSource + * @var TokenReader + */ + protected $reader; + + /** + * Array with key/value pairs of tokens + */ + protected $tokens = array(); + + /** + * This method is called to load the sources from the reader + * into the buffer of the source. + */ + function load() { + // Create new Reader + if ($this->classname === null) { + throw new BuildException("No Classname given to TokenSource."); + } + + $classname = Phing::import($this->classname); + $this->reader = new $classname($this->project); + + // Configure Reader + $this->configureTokenReader($this->reader); + + // Load Tokens + try { + while ($token = $this->reader->readToken()) { + $this->tokens[] = $token; + } + } catch (BuildException $e) { + $this->log("Error reading TokenSource: " . $e->getMessage(), PROJECT_MSG_WARN); + } catch (IOException $e) { + $this->log("Error reading TokenSource: " . $e->getMessage(), PROJECT_MSG_WARN); + } + } + + /** + * This function uses the wrapper to read the tokens and then + * returns them. + * + * @access public + */ + function getTokens() { + if ($this->tokens === null) + $this->Load(); + + return $this->tokens; + } + + /** + * Configures a TokenReader with the parameters passed to the + * TokenSource. + * @param TokenReader $reader + */ + private function configureTokenReader(TokenReader $reader) { + $count = count($this->parameters); + for ($i = 0; $i < $count; $i++) { + $method_name = "Set" . $this->parameters[$i]->getName(); + $value = $this->parameters[$i]->getValue(); + $reader->$method_name($value); + } + } + + /** + * Set the classname (dot-path) to use for handling token replacement. + * @param string $c + */ + function setClassname($c) { + $this->classname = $c; + } + + /** + * Returns the qualified classname (dot-path) to use for handling token replacement. + * @return string + */ + function getClassname() { + return $this->classname; + } + + /** + * Create nested tag. + * Uses standard name/value Parameter class. + * @return Parameter + */ + function createParam() { + $num = array_push($this->parameters, new Parameter()); + return $this->parameters[$num-1]; + } +} + + +?> diff --git a/gulliver/thirdparty/phing/types/defaults.properties b/gulliver/thirdparty/phing/types/defaults.properties new file mode 100644 index 000000000..a2d86350b --- /dev/null +++ b/gulliver/thirdparty/phing/types/defaults.properties @@ -0,0 +1,13 @@ +# phing default types +commandline=phing.types.Commandline +fileset=phing.types.FileSet +dirset=phing.types.DirSet +filelist=phing.types.FileList +patternset=phing.types.PatternSet +mapper=phing.types.Mapper +filterchain=phing.types.FilterChain +filterreader=phing.types.PhingFilterReader +regexp=phing.types.RegularExpression +param=phing.types.Parameter +path=phing.types.Path +selector=phing.types.selectors.SelectSelector \ No newline at end of file diff --git a/gulliver/thirdparty/phing/types/selectors/AndSelector.php b/gulliver/thirdparty/phing/types/selectors/AndSelector.php new file mode 100644 index 000000000..d92525226 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/AndSelector.php @@ -0,0 +1,67 @@ +. + */ + +require_once 'phing/types/selectors/BaseSelectorContainer.php'; + +/** + * This selector has a collection of other selectors, all of which have to + * select a file in order for this selector to select it. + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class AndSelector extends BaseSelectorContainer { + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{andselect: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + /** + * Returns true (the file is selected) only if all other selectors + * agree that the file should be selected. + * + * @param basedir the base directory the scan is being done from + * @param filename the name of the file to check + * @param file a PhingFile object for the filename that the selector + * can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + $this->validate(); + $selectors = $this->selectorElements(); + for($i=0,$size=count($selectors); $i < $size; $i++) { + $result = $selectors[$i]->isSelected($basedir, $filename, $file); + if (!$result) { + return false; + } + } + return true; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/BaseExtendSelector.php b/gulliver/thirdparty/phing/types/selectors/BaseExtendSelector.php new file mode 100644 index 000000000..d2c655644 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/BaseExtendSelector.php @@ -0,0 +1,62 @@ +. + */ + +require_once 'phing/types/selectors/ExtendFileSelector.php'; +require_once 'phing/types/selectors/BaseSelector.php'; +include_once 'phing/types/Parameter.php'; + +/** + * Convenience base class for all selectors accessed through ExtendSelector. + * It provides support for gathering the parameters together as well as for + * assigning an error message and throwing a build exception if an error is + * detected. + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Bruce Atherton, bruce@callenish.com (Ant) + * @package phing.types.selectors + */ +abstract class BaseExtendSelector extends BaseSelector implements ExtendFileSelector { + + /** The passed in parameter array. */ + protected $parameters = null; + + /** + * Set all the Parameters for this custom selector, collected by + * the ExtendSelector class. + * + * @param parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + $this->parameters = $parameters; + } + + /** + * Allows access to the parameters gathered and set within the + * <custom> tag. + * + * @return the set of parameters defined for this selector + */ + protected function getParameters() { + return $this->parameters; + } +} + diff --git a/gulliver/thirdparty/phing/types/selectors/BaseSelector.php b/gulliver/thirdparty/phing/types/selectors/BaseSelector.php new file mode 100644 index 000000000..1b72a85a0 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/BaseSelector.php @@ -0,0 +1,84 @@ +. + */ + +require_once 'phing/types/selectors/FileSelector.php'; + +/** + * A convenience base class that you can subclass Selectors from. It + * provides some helpful common behaviour. Note that there is no need + * for Selectors to inherit from this class, it is only necessary that + * they implement FileSelector. + * + * @author Bruce Atherton + * @package phing.types.selectors + */ +abstract class BaseSelector extends DataType implements FileSelector { + + private $errmsg = null; + + /** + * Allows all selectors to indicate a setup error. Note that only + * the first error message is recorded. + * + * @param msg The error message any BuildException should throw. + */ + public function setError($msg) { + if ($this->errmsg === null) { + $this->errmsg = $msg; + } + } + + /** + * Returns any error messages that have been set. + * + * @return the error condition + */ + public function getError() { + return $this->errmsg; + } + + + /** + *

    Subclasses can override this method to provide checking of their + * state. So long as they call validate() from isSelected(), this will + * be called automatically (unless they override validate()).

    + *

    Implementations should check for incorrect settings and call + * setError() as necessary.

    + */ + public function verifySettings() { + } + + /** + * Subclasses can use this to throw the requisite exception + * in isSelected() in the case of an error condition. + */ + public function validate() { + if ($this->getError() === null) { + $this->verifySettings(); + } + if ($this->getError() !== null) { + throw new BuildException($this->errmsg); + } + } + +} + + diff --git a/gulliver/thirdparty/phing/types/selectors/BaseSelectorContainer.php b/gulliver/thirdparty/phing/types/selectors/BaseSelectorContainer.php new file mode 100644 index 000000000..635dd677f --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/BaseSelectorContainer.php @@ -0,0 +1,270 @@ +. + */ + +require_once 'phing/types/selectors/SelectorContainer.php'; +require_once 'phing/types/selectors/BaseSelector.php'; + +/** + * This is the base class for selectors that can contain other selectors. + * + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +abstract class BaseSelectorContainer extends BaseSelector implements SelectorContainer { + + private $selectorsList = array(); + + /** + * Indicates whether there are any selectors here. + */ + public function hasSelectors() { + return !(empty($this->selectorsList)); + } + + /** + * Gives the count of the number of selectors in this container + */ + public function selectorCount() { + return count($this->selectorsList); + } + + /** + * Returns a copy of the selectors as an array. + */ + public function getSelectors(Project $p) { + $result = array(); + for($i=0,$size=count($this->selectorsList); $i < $size; $i++) { + $result[] = clone $this->selectorsList[$i]; + } + return $result; + } + + /** + * Returns an array for accessing the set of selectors (not a copy). + */ + public function selectorElements() { + return $this->selectorsList; + } + + /** + * Convert the Selectors within this container to a string. This will + * just be a helper class for the subclasses that put their own name + * around the contents listed here. + * + * @return comma separated list of Selectors contained in this one + */ + public function toString() { + $buf = ""; + $arr = $this->selectorElements(); + for($i=0,$size=count($arr); $i < $size; $i++) { + $buf .= $arr[$i]->toString() . (isset($arr[$i+1]) ? ', ' : ''); + } + return $buf; + } + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + * @return the selector that was added + */ + public function appendSelector(FileSelector $selector) { + $this->selectorsList[] = $selector; + } + + /** + *

    This implementation validates the container by calling + * verifySettings() and then validates each contained selector + * provided that the selector implements the validate interface. + *

    + *

    Ordinarily, this will validate all the elements of a selector + * container even if the isSelected() method of some elements is + * never called. This has two effects:

    + *
      + *
    • Validation will often occur twice. + *
    • Since it is not required that selectors derive from + * BaseSelector, there could be selectors in the container whose + * error conditions are not detected if their isSelected() call + * is never made. + *
    + */ + public function validate() { + $this->verifySettings(); + $errmsg = $this->getError(); + if ($errmsg !== null) { + throw new BuildException($errmsg); + } + foreach($this->selectorsList as $o) { + if ($o instanceof BaseSelector) { + $o->validate(); + } + } + } + + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public function createSelector() { + $o = new SelectSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an "And" selector entry on the selector list + */ + public function createAnd() { + $o = new AndSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an "Or" selector entry on the selector list + */ + public function createOr() { + $o = new OrSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a "Not" selector entry on the selector list + */ + public function createNot() { + $o = new NotSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a "None" selector entry on the selector list + */ + public function createNone() { + $o = new NoneSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a majority selector entry on the selector list + */ + public function createMajority() { + $o = new MajoritySelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector date entry on the selector list + */ + public function createDate() { + $o = new DateSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector size entry on the selector list + */ + public function createSize() { + $o = new SizeSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a selector filename entry on the selector list + */ + public function createFilename() { + $o = new FilenameSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add an extended selector entry on the selector list + */ + public function createCustom() { + $o = new ExtendSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a contains selector entry on the selector list + */ + public function createContains() { + $o = new ContainsSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a contains selector entry on the selector list + */ + public function createContainsRegexp() { + $o = new ContainsRegexpSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a present selector entry on the selector list + */ + public function createPresent() { + $o = new PresentSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a depth selector entry on the selector list + */ + public function createDepth() { + $o = new DepthSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a depends selector entry on the selector list + */ + public function createDepend() { + $o = new DependSelector(); + $this->appendSelector($o); + return $o; + } + + /** + * add a type selector entry on the selector list + */ + public function createType() { + $o = new TypeSelector(); + $this->appendSelector($o); + return $o; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/ContainsRegexpSelector.php b/gulliver/thirdparty/phing/types/selectors/ContainsRegexpSelector.php new file mode 100644 index 000000000..66d130059 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/ContainsRegexpSelector.php @@ -0,0 +1,164 @@ +. + */ + +require_once 'phing/types/selectors/BaseExtendSelector.php'; +include_once 'phing/types/RegularExpression.php'; + +/** + * Selector that filters files based on whether they contain a + * particular string using regexp. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.3 $ + * @package phing.types.selectors + */ +class ContainsRegexpSelector extends BaseExtendSelector { + + /** @var string The expression set from XML. */ + private $userProvidedExpression; + + /** @var Regexp */ + private $myExpression; + + private $casesensitive = true; + + /** @var RegularExpression */ + private $myRegExp; + + const EXPRESSION_KEY = "expression"; + + const CASE_KEY = "casesensitive"; + + public function toString() { + $buf = "{containsregexpselector expression: "; + $buf .= $this->userProvidedExpression; + $buf .= " casesensitive: "; + if ($this->casesensitive) { + $buf .= "true"; + } else { + $buf .= "false"; + } + $buf .= "}"; + return $buf; + } + + /** + * The expression to match on within a file. + * + * @param string $exp the string that a file must contain to be selected. + */ + public function setExpression($exp) { + $this->userProvidedExpression = $exp; + } + + /** + * Whether to ignore case in the regex match. + * + * @param boolean $casesensitive whether to pay attention to case sensitivity + */ + public function setCasesensitive($casesensitive) { + $this->casesensitive = $casesensitive; + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param array $parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i=0,$size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::EXPRESSION_KEY: + $this->setExpression($parameters[$i]->getValue()); + break; + case self::CASE_KEY: + $this->setCasesensitive($parameters[$i]->getValue()); + break; + default: + $this->setError("Invalid parameter " . $paramname); + } + } // for each param + } // if params + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the pattern attribute has been set. + * + */ + public function verifySettings() { + if ($this->userProvidedExpression === null) { + $this->setError("The expression attribute is required"); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + if ($file->isDirectory()) { + return true; + } + + if ($this->myRegExp === null) { + $this->myRegExp = new RegularExpression(); + $this->myRegExp->setPattern($this->userProvidedExpression); + if (!$this->casesensitive) { + $this->myRegExp->setIgnoreCase(true); + } + $this->myExpression = $this->myRegExp->getRegexp($this->getProject()); + } + + $in = null; + try { + $in = new BufferedReader(new FileReader($file)); + $teststr = $in->readLine(); + while ($teststr !== null) { + if ($this->myExpression->matches($teststr)) { + return true; + } + $teststr = $in->readLine(); + } + return false; + } catch (IOException $ioe) { + if ($in) $in->close(); + throw new BuildException("Could not read file " . $filename); + } + $in->close(); + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/ContainsSelector.php b/gulliver/thirdparty/phing/types/selectors/ContainsSelector.php new file mode 100644 index 000000000..5ebc7194e --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/ContainsSelector.php @@ -0,0 +1,151 @@ +. + */ + +include_once 'phing/types/selectors/BaseExtendSelector.php'; + +/** + * Selector that filters files based on whether they contain a + * particular string. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class ContainsSelector extends BaseExtendSelector { + + private $contains = null; + private $casesensitive = true; + const CONTAINS_KEY = "text"; + const CASE_KEY = "casesensitive"; + + public function toString() { + $buf = "{containsselector text: "; + $buf .= $this->contains; + $buf .= " casesensitive: "; + if ($this->casesensitive) { + $buf .= "true"; + } else { + $buf .= "false"; + } + $buf .= "}"; + return $buf; + } + + /** + * The string to search for within a file. + * + * @param string $contains the string that a file must contain to be selected. + */ + public function setText($contains) { + $this->contains = $contains; + } + + /** + * Whether to ignore case in the string being searched. + * + * @param boolean $casesensitive whether to pay attention to case sensitivity + */ + public function setCasesensitive($casesensitive) { + $this->casesensitive = $casesensitive; + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param array $parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i=0,$size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::CONTAINS_KEY: + $this->setText($parameters[$i]->getValue()); + break; + case self::CASE_KEY: + $this->setCasesensitive($parameters[$i]->getValue()); + break; + default: + $this->setError("Invalid parameter " . $paramname); + } + } // for each param + } // if params + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the pattern attribute has been set. + * + */ + public function verifySettings() { + if ($this->contains === null) { + $this->setError("The text attribute is required"); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + if ($file->isDirectory()) { + return true; + } + + $userstr = $this->contains; + if (!$this->casesensitive) { + $userstr = strtolower($this->contains); + } + + $in = null; + try { + $in = new BufferedReader(new FileReader($file)); + $teststr = $in->readLine(); + while ($teststr !== null) { + if (!$this->casesensitive) { + $teststr = strtolower($teststr); + } + if (strpos($teststr, $userstr) !== false) { + return true; + } + $teststr = $in->readLine(); + } + return false; + } catch (IOException $ioe) { + if ($in) $in->close(); + throw new BuildException("Could not read file " . $filename); + } + $in->close(); + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/DateSelector.php b/gulliver/thirdparty/phing/types/selectors/DateSelector.php new file mode 100644 index 000000000..af5a52918 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/DateSelector.php @@ -0,0 +1,214 @@ +. + */ + +require_once 'phing/types/selectors/BaseExtendSelector.php'; + +/** + * Selector that chooses files based on their last modified date. Ant uses + * millisecond precision (thanks to Java); PHP is forced to use only seconds + * precision. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.10 $ + * @package phing.types.selecctors + */ +class DateSelector extends BaseExtendSelector { + + private $seconds = -1; // millis in Ant, but PHP doesn't support that level of precision + private $dateTime = null; + private $includeDirs = false; + private $granularity = 0; + private $cmp = 2; + const MILLIS_KEY = "millis"; + const DATETIME_KEY = "datetime"; + const CHECKDIRS_KEY = "checkdirs"; + const GRANULARITY_KEY = "granularity"; + const WHEN_KEY = "when"; + private static $timeComparisons = array("before", "after", "equal"); + + public function __construct() { + //if (Os.isFamily("dos")) { + // granularity = 2000; + //} + } + + public function toString() { + $buf = "{dateselector date: "; + $buf .= $this->dateTime; + $buf .= " compare: "; + if ($this->cmp === 0) { + $buf .= "before"; + } elseif ($this->cmp === 1) { + $buf .= "after"; + } else { + $buf .= "equal"; + } + $buf .= " granularity: "; + $buf .= $this->granularity; + $buf .= "}"; + return $buf; + } + + /** + * For users that prefer to express time in seconds since 1970 + * + * @param int $seconds the time to compare file's last modified date to, + * expressed in milliseconds + */ + public function setSeconds($seconds) { + $this->seconds = (int) $seconds; + } + + /** + * Returns the seconds value the selector is set for. + */ + public function getSeconds() { + return $this->seconds; + } + + /** + * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM + * format + * + * @param string $dateTime a string in MM/DD/YYYY HH:MM AM_PM format + */ + public function setDatetime($dateTime) { + $dt = strtotime($dateTime); + if ($dt == -1) { + $this->setError("Date of " . $dateTime + . " Cannot be parsed correctly. It should be in" + . " a format parsable by PHP's strtotime() function."); + } else { + $this->dateTime = $dateTime; + $this->setSeconds($dt); + } + } + + /** + * Should we be checking dates on directories? + * + * @param boolean $includeDirs whether to check the timestamp on directories + */ + public function setCheckdirs($includeDirs) { + $this->includeDirs = (boolean) $includeDirs; + } + + /** + * Sets the number of milliseconds leeway we will give before we consider + * a file not to have matched a date. + * @param int $granularity + */ + public function setGranularity($granularity) { + $this->granularity = (int) $granularity; + } + + /** + * Sets the type of comparison to be done on the file's last modified + * date. + * + * @param string $cmp The comparison to perform + */ + public function setWhen($cmp) { + $idx = array_search($cmp, self::$timeComparisons, true); + if ($idx === null) { + $this->setError("Invalid value for ".WHEN_KEY.": ".$cmp); + } else { + $this->cmp = $idx; + } + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param array $parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i=0,$size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::MILLIS_KEY: + $this->setMillis($parameters[$i]->getValue()); + break; + case self::DATETIME_KEY: + $this->setDatetime($parameters[$i]->getValue()); + break; + case self::CHECKDIRS_KEY: + $this->setCheckdirs($parameters[$i]->getValue()); + break; + case self::GRANULARITY_KEY: + $this->setGranularity($parameters[$i]->getValue()); + break; + case self::WHEN_KEY: + $this->setWhen($parameters[$i]->getValue()); + break; + default: + $this->setError("Invalid parameter " . $paramname); + } // switch + } + } + } + + /** + * This is a consistency check to ensure the selector's required + * values have been set. + */ + public function verifySettings() { + if ($this->dateTime === null && $this->seconds < 0) { + $this->setError("You must provide a datetime or the number of " + . "seconds."); + } elseif ($this->seconds < 0) { + $this->setError("Date of " . $this->dateTime + . " results in negative seconds" + . " value relative to epoch (January 1, 1970, 00:00:00 GMT)."); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param PhingFile $basedir the base directory the scan is being done from + * @param string $filename is the name of the file to check + * @param PhingFile $file is a PhingFile object the selector can use + * @return boolean Whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + $this->validate(); + if ($file->isDirectory() && ($this->includeDirs === false)) { + return true; + } + if ($this->cmp === 0) { + return (($file->lastModified() - $this->granularity) < $this->seconds); + } elseif ($this->cmp === 1) { + return (($file->lastModified() . $this->granularity) > $this->seconds); + } else { + return (abs($file->lastModified() - $this->seconds) <= $this->granularity); + } + } + +} + + diff --git a/gulliver/thirdparty/phing/types/selectors/DependSelector.php b/gulliver/thirdparty/phing/types/selectors/DependSelector.php new file mode 100644 index 000000000..a0140c96b --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/DependSelector.php @@ -0,0 +1,151 @@ +. + */ + +require_once 'phing/types/selectors/BaseSelector.php'; + +/** + * Selector that filters files based on whether they are newer than + * a matching file in another directory tree. It can contain a mapper + * element, so isn't available as an ExtendSelector (since those + * parameters can't hold other elements). + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.8 $ + * @package phing.types.selectors + */ +class DependSelector extends BaseSelector { + + private $targetdir = null; + private $mapperElement = null; + private $map = null; + private $granularity = 0; + + public function __construct() { + // not yet supported: + //if (Os.isFamily("dos")) { + // $this->granularity = 2000; + //} + } + + public function toString() { + $buf = "{dependselector targetdir: "; + if ($this->targetdir === null) { + $buf .= "NOT YET SET"; + } else { + $buf .= $this->targetdir->getName(); + } + $buf .= " granularity: "; + $buf .= $this->granularity; + if ($this->map !== null) { + $buf .= " mapper: "; + $buf .= $this->map->toString(); + } elseif ($this->mapperElement !== null) { + $buf .= " mapper: "; + $buf .= $this->mapperElement->toString(); + } + $buf .= "}"; + return $buf; + } + + /** + * The name of the file or directory which is checked for out-of-date + * files. + * + * @param targetdir the directory to scan looking for files. + */ + public function setTargetdir(PhingFile $targetdir) { + $this->targetdir = $targetdir; + } + + /** + * Sets the number of milliseconds leeway we will give before we consider + * a file out of date. + */ + public function setGranularity($granularity) { + $this->granularity = (int) granularity; + } + + /** + * Defines the FileNameMapper to use (nested mapper element). + * @throws BuildException + */ + public function createMapper() { + if ($this->mapperElement !== null) { + throw new BuildException("Cannot define more than one mapper"); + } + $this->mapperElement = new Mapper($this->project); + return $this->mapperElement; + } + + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the dest attribute has been set and we have a mapper. + */ + public function verifySettings() { + if ($this->targetdir === null) { + $this->setError("The targetdir attribute is required."); + } + if ($this->mapperElement === null) { + $this->map = new IdentityMapper(); + } else { + $this->map = $this->mapperElement->getImplementation(); + } + if ($this->map === null) { + $this->setError("Could not set element."); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + // Determine file whose out-of-dateness is to be checked + $destfiles = $this->map->main($filename); + + // If filename does not match the To attribute of the mapper + // then filter it out of the files we are considering + if ($destfiles === null) { + return false; + } + // Sanity check + if (count($destfiles) !== 1 || $destfiles[0] === null) { + throw new BuildException("Invalid destination file results for " . $this->targetdir . " with filename " . $filename); + } + $destname = $destfiles[0]; + $destfile = new PhingFile($this->targetdir, $destname); + + return SelectorUtils::isOutOfDate($file, $destfile, $this->granularity); + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/DepthSelector.php b/gulliver/thirdparty/phing/types/selectors/DepthSelector.php new file mode 100644 index 000000000..8f88a2d81 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/DepthSelector.php @@ -0,0 +1,158 @@ +. + */ + +require_once 'phing/types/selectors/BaseExtendSelector.php'; + +/** + * Selector that filters files based on the how deep in the directory + * tree they are. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.7 $ + * @package phing.types.selectors + */ +class DepthSelector extends BaseExtendSelector { + + public $min = -1; + public $max = -1; + const MIN_KEY = "min"; + const MAX_KEY = "max"; + + public function toString() { + $buf = "{depthselector min: "; + $buf .= $this->min; + $buf .= " max: "; + $buf .= $this->max; + $buf .= "}"; + return $buf; + } + + /** + * The minimum depth below the basedir before a file is selected. + * + * @param min minimum directory levels below basedir to go + */ + public function setMin($min) { + $this->min = (int) $min; + } + + /** + * The minimum depth below the basedir before a file is selected. + * + * @param min maximum directory levels below basedir to go + */ + public function setMax($max) { + $this->max = (int) $max; + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i = 0, $size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::MIN_KEY: + $this->setMin($parameters[$i]->getValue()); + break; + case self::MAX_KEY: + $this->setMax($parameters[$i]->getValue()); + break; + + default: + $this->setError("Invalud parameter " . $paramname); + } // switch + } + } + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the max depth is not lower than the min depth. + */ + public function verifySettings() { + if ($this->min < 0 && $this->max < 0) { + $this->setError("You must set at least one of the min or the " . + "max levels."); + } + if ($this->max < $this->min && $this->max > -1) { + $this->setError("The maximum depth is lower than the minimum."); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. Most of the work + * for this selector is offloaded into SelectorUtils, a static class + * that provides the same services for both FilenameSelector and + * DirectoryScanner. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + $depth = -1; + // If you felt daring, you could cache the basedir absolute path + $abs_base = $basedir->getAbsolutePath(); + $abs_file = $file->getAbsolutePath(); + + $tok_base = explode(DIRECTORY_SEPARATOR, $abs_base); + $tok_file = explode(DIRECTORY_SEPARATOR, $abs_file); + + for($i=0,$size=count($tok_file); $i < $size; $i++) { + $filetoken = $tok_file[$i]; + if (isset($tok_base[$i])) { + $basetoken = $tok_base[$i]; + // Sanity check. Ditch it if you want faster performance + if ($basetoken !== $filetoken) { + throw new BuildException("File " . $filename . + " does not appear within " . $abs_base . "directory"); + } + } else { // no more basepath tokens + $depth++; + if ($this->max > -1 && $depth > $this->max) { + return false; + } + } + } + if (isset($tok_base[$i + 1])) { + throw new BuildException("File " . $filename . + " is outside of " . $abs_base . "directory tree"); + } + if ($this->min > -1 && $depth < $this->min) { + return false; + } + return true; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/ExtendFileSelector.php b/gulliver/thirdparty/phing/types/selectors/ExtendFileSelector.php new file mode 100644 index 000000000..f12782bbd --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/ExtendFileSelector.php @@ -0,0 +1,43 @@ +. + */ + +require_once 'phing/types/Parameterizable.php'; +require_once 'phing/types/selectors/FileSelector.php'; + +/** + * This is the interface to be used by all custom selectors, those that are + * called through the <custom> tag. It is the amalgamation of two + * interfaces, the FileSelector and the Paramterizable interface. Note that + * you will almost certainly want the default behaviour for handling + * Parameters, so you probably want to use the BaseExtendSelector class + * as the base class for your custom selector rather than implementing + * this interface from scratch. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +interface ExtendFileSelector extends Parameterizable, FileSelector { + // No further methods necessary. This is just an amalgamation of two other + // interfaces. +} + diff --git a/gulliver/thirdparty/phing/types/selectors/ExtendSelector.php b/gulliver/thirdparty/phing/types/selectors/ExtendSelector.php new file mode 100644 index 000000000..d143544df --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/ExtendSelector.php @@ -0,0 +1,127 @@ +. + */ + +include_once 'phing/util/StringHelper.php'; + +/** + * Selector that selects files by forwarding the request on to other classes. + * + * TODO: + * Consider adding Path (org.apache.tools.ant.types.Path) support to this class + * and to the Mappers class. See Ant versions for implimentation details. + * + * @author Bruce Atherton + * @package phing.types.selectors + */ +class ExtendSelector extends BaseSelector { + + private $classname; + private $dynselector; + private $parameters = array(); + + /** + * Sets the classname of the custom selector. + * + * @param classname is the class which implements this selector + */ + public function setClassname($classname) { + $this->classname = $classname; + } + + /** + * Instantiates the identified custom selector class. + */ + public function selectorCreate() { + if ($this->classname !== null && $this->classname !== "") { + try { + // assume it's fully qualified, import it + $cls = Phing::import($this->classname); + + // make sure class exists + if (class_exists($cls)) { + $this->dynselector = new $cls(); + } else { + $this->setError("Selector " . $this->classname . " not initialized, no such class"); + } + } catch (Exception $e) { + $this->setError("Selector " . $this->classname . " not initialized, could not create class: " . $e->getMessage()); + } + } else { + $this->setError("There is no classname specified"); + } + } + + /** + * Create new parameters to pass to custom selector. + * + * @param p The new Parameter object + */ + public function addParam(Parameter $p) { + $this->parameters[] = $p; + } + + /** + * These are errors specific to ExtendSelector only. If there are + * errors in the custom selector, it should throw a BuildException + * when isSelected() is called. + */ + public function verifySettings() { + // Creation is done here rather than in isSelected() because some + // containers may do a validation pass before running isSelected(), + // but we need to check for the existence of the created class. + if ($this->dynselector === null) { + $this->selectorCreate(); + } + + if (empty($this->classname)) { + $this->setError("The classname attribute is required"); + } elseif ($this->dynselector === null) { + $this->setError("Internal Error: The custom selector was not created"); + } elseif ( !($this->dynselector instanceof ExtendFileSelector) && (count($this->parameters) > 0)) { + $this->setError("Cannot set parameters on custom selector that does not " + . "implement ExtendFileSelector."); + } + } + + + /** + * Allows the custom selector to choose whether to select a file. This + * is also where the Parameters are passed to the custom selector, + * since we know we must have them all by now. And since we must know + * both classpath and classname, creating the class is deferred to here + * as well. + * + * @throws BuildException + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + if (count($this->parameters) > 0 && $this->dynselector instanceof ExtendFileSelector) { + // We know that dynselector must be non-null if no error message + $this->dynselector->setParameters($this->parameters); + } + return $this->dynselector->isSelected($basedir, $filename, $file); + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/FileSelector.php b/gulliver/thirdparty/phing/types/selectors/FileSelector.php new file mode 100644 index 000000000..af1f037d0 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/FileSelector.php @@ -0,0 +1,47 @@ +. + */ + +/** + * This is the interface to be used by all selectors. + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Bruce Atherton, bruce@callenish.com (Ant) + * @package phing.types.selectors + */ +interface FileSelector { + + /** + * Method that each selector will implement to create their + * selection behaviour. If there is a problem with the setup + * of a selector, it can throw a BuildException to indicate + * the problem. + * + * @param basedir A PhingFile object for the base directory + * @param filename The name of the file to check + * @param file A PhingFile object for this filename + * @return whether the file should be selected or not + * @throws BuildException if the selector was not configured correctly + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file); + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/FilenameSelector.php b/gulliver/thirdparty/phing/types/selectors/FilenameSelector.php new file mode 100644 index 000000000..d9aefe932 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/FilenameSelector.php @@ -0,0 +1,157 @@ +. + */ + + +include_once 'phing/types/selectors/BaseExtendSelector.php'; + +/** + * Selector that filters files based on the filename. + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Bruce Atherton, bruce@callenish.com (Ant) + * @package phing.types.selectors + */ +class FilenameSelector extends BaseExtendSelector { + + private $pattern = null; + private $casesensitive = true; + private $negated = false; + const NAME_KEY = "name"; + const CASE_KEY = "casesensitive"; + const NEGATE_KEY = "negate"; + + public function toString() { + $buf = "{filenameselector name: "; + $buf .= $this->pattern; + $buf .= " negate: "; + if ($this->negated) { + $buf .= "true"; + } else { + $buf .= "false"; + } + $buf .= " casesensitive: "; + if ($this->casesensitive) { + $buf .= "true"; + } else { + $buf .= "false"; + } + $buf .= "}"; + return $buf; + } + + /** + * The name of the file, or the pattern for the name, that + * should be used for selection. + * + * @param pattern the file pattern that any filename must match + * against in order to be selected. + */ + public function setName($pattern) { + $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern); + $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern); + + if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) { + $pattern .= "**"; + } + $this->pattern = $pattern; + } + + /** + * Whether to ignore case when checking filenames. + * + * @param casesensitive whether to pay attention to case sensitivity + */ + public function setCasesensitive($casesensitive) { + $this->casesensitive = $casesensitive; + } + + /** + * You can optionally reverse the selection of this selector, + * thereby emulating an <exclude> tag, by setting the attribute + * negate to true. This is identical to surrounding the selector + * with <not></not>. + * + * @param negated whether to negate this selection + */ + public function setNegate($negated) { + $this->negated = $negated; + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param array $parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i=0, $len=count($parameters); $i < $len; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::NAME_KEY: + $this->setName($parameters[$i]->getValue()); + break; + case self::CASE_KEY: + $this->setCasesensitive($parameters[$i]->getValue()); + break; + case self::NEGATE_KEY: + $this->setNegate($parameters[$i]->getValue()); + break; + default: + $this->setError("Invalid parameter " . $paramname); + } + } // for each param + } // if params + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the name attribute has been set. + * + */ + public function verifySettings() { + if ($this->pattern === null) { + $this->setError("The name attribute is required"); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. Most of the work + * for this selector is offloaded into SelectorUtils, a static class + * that provides the same services for both FilenameSelector and + * DirectoryScanner. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + $this->validate(); + return (SelectorUtils::matchPath($this->pattern, $filename, $this->casesensitive) + === !($this->negated)); + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/MajoritySelector.php b/gulliver/thirdparty/phing/types/selectors/MajoritySelector.php new file mode 100644 index 000000000..e98be94b3 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/MajoritySelector.php @@ -0,0 +1,92 @@ +. + */ + + +/** + * This selector is here just to shake up your thinking a bit. Don't get + * too caught up in boolean, there are other ways you can evaluate a + * collection of selectors. This one takes a vote of the selectors it + * contains, and majority wins. You could also have an "all-but-one" + * selector, a "weighted-average" selector, and so on. These are left + * as exercises for the reader (as are the usecases where this would + * be necessary). + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class MajoritySelector extends BaseSelectorContainer { + + private $allowtie = true; + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{majorityselect: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + public function setAllowtie($tiebreaker) { + $this->allowtie = $tiebreaker; + } + + /** + * Returns true (the file is selected) if most of the other selectors + * agree. In case of a tie, go by the allowtie setting. That defaults + * to true, meaning in case of a tie, the file is selected. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a PhingFile object for the filename that the selector + * can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + $yesvotes = 0; + $novotes = 0; + + $selectors = $this->selectorElements(); + for($i=0,$size=count($selectors); $i < $size; $i++) { + $result = $selectors[$i]->isSelected($basedir,$filename,$file); + if ($result) { + $yesvotes = $yesvotes + 1; + } else { + $novotes = $novotes + 1; + } + } + if ($yesvotes > $novotes) { + return true; + } + else if ($novotes > $yesvotes) { + return false; + } + // At this point, we know we have a tie. + return $this->allowtie; + } +} + diff --git a/gulliver/thirdparty/phing/types/selectors/NoneSelector.php b/gulliver/thirdparty/phing/types/selectors/NoneSelector.php new file mode 100644 index 000000000..0b52737b7 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/NoneSelector.php @@ -0,0 +1,71 @@ +. + */ + +require_once 'phing/types/selectors/BaseSelectorContainer.php'; + +/** + * This selector has a collection of other selectors. All of those selectors + * must refuse to select a file before the file is considered selected by + * this selector. + * + * @author Hans Lellelid + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class NoneSelector extends BaseSelectorContainer { + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{noneselect: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + /** + * Returns true (the file is selected) only if all other selectors + * agree that the file should not be selected. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a java.io.File object for the filename that the selector + * can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + $selectors = $this->selectorElements(); + + for($i=0,$size=count($selectors); $i < $size; $i++) { + $result = $selectors[$i]->isSelected($basedir, $filename, $file); + if ($result) { + return false; + } + } + return true; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/NotSelector.php b/gulliver/thirdparty/phing/types/selectors/NotSelector.php new file mode 100644 index 000000000..7cfd1e98e --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/NotSelector.php @@ -0,0 +1,59 @@ +. + */ + +require_once 'phing/types/selectors/NoneSelector.php'; + +/** + * This selector has one other selectors whose meaning it inverts. It + * actually relies on NoneSelector for its implementation of the + * isSelected() method, but it adds a check to ensure there is only one + * other selector contained within. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class NotSelector extends NoneSelector { + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{notselect: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + /** + * Makes sure that there is only one entry, sets an error message if + * not. + */ + public function verifySettings() { + if ($this->selectorCount() != 1) { + $this->setError("One and only one selector is allowed within the " . + " tag"); + } + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/OrSelector.php b/gulliver/thirdparty/phing/types/selectors/OrSelector.php new file mode 100644 index 000000000..0e73cc677 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/OrSelector.php @@ -0,0 +1,72 @@ +. + */ + +require_once 'phing/types/selectors/BaseSelectorContainer.php'; + +/** + * This selector has a collection of other selectors, any of which have to + * select a file in order for this selector to select it. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class OrSelector extends BaseSelectorContainer { + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{orselect: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + /** + * Returns true (the file is selected) if any of the other selectors + * agree that the file should be selected. + * + * @param basedir the base directory the scan is being done from + * @param filename the name of the file to check + * @param file a PhingFile object for the filename that the selector + * can use + * @return boolean Whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + $selectors = $this->selectorElements(); + + // First, check that all elements are correctly configured + + for($i=0,$size=count($selectors); $i < $size; $i++) { + $result = $selectors[$i]->isSelected($basedir, $filename, $file); + if ($result) { + return true; + } + } + return false; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/PresentSelector.php b/gulliver/thirdparty/phing/types/selectors/PresentSelector.php new file mode 100644 index 000000000..9146cddbb --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/PresentSelector.php @@ -0,0 +1,154 @@ +. + */ + +/** + * Selector that filters files based on whether they appear in another + * directory tree. It can contain a mapper element, so isn't available + * as an ExtendSelector (since those parameters can't hold other + * elements). + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class PresentSelector extends BaseSelector { + + private $targetdir = null; + private $mapperElement = null; + private $map = null; + private $destmustexist = true; + private static $filePresence = array("srconly", "both"); + + public function toString() { + $buf = "{presentselector targetdir: "; + if ($this->targetdir === null) { + $buf .= "NOT YET SET"; + } else { + $buf .= $this->targetdir->getName(); + } + $buf .= " present: "; + if ($this->destmustexist) { + $buf .= "both"; + } else { + $buf .= "srconly"; + } + if ($this->map !== null) { + $buf .= $this->map->toString(); + } elseif ($this->mapperElement !== null) { + $buf .= $this->mapperElement->toString(); + } + $buf .= "}"; + return $buf; + } + + /** + * The name of the file or directory which is checked for matching + * files. + * + * @param targetdir the directory to scan looking for matching files. + */ + public function setTargetdir(PhingFile $targetdir) { + $this->targetdir = $targetdir; + } + + /** + * Defines the FileNameMapper to use (nested mapper element). + * @throws BuildException + */ + public function createMapper() { + if ($this->mapperElement !== null) { + throw new BuildException("Cannot define more than one mapper"); + } + $this->mapperElement = new Mapper($this->getProject()); + return $this->mapperElement; + } + + + /** + * This sets whether to select a file if its dest file is present. + * It could be a negate boolean, but by doing things + * this way, we get some documentation on how the system works. + * A user looking at the documentation should clearly understand + * that the ONLY files whose presence is being tested are those + * that already exist in the source directory, hence the lack of + * a destonly option. + * + * @param string $fp An attribute set to either srconlyboth. + */ + public function setPresent($fp) { + $idx = array_search($fp, self::$filePresence, true); + if ( $idx === 0 ) { + $this->destmustexist = false; + } + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the targetdir attribute has been set and we have a mapper. + */ + public function verifySettings() { + if ($this->targetdir === null) { + $this->setError("The targetdir attribute is required."); + } + if ($this->mapperElement === null) { + $this->map = new IdentityMapper(); + } else { + $this->map = $this->mapperElement->getImplementation(); + } + if ($this->map === null) { + $this->setError("Could not set element."); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir the base directory the scan is being done from + * @param filename is the name of the file to check + * @param file is a PhingFile object the selector can use + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + // Determine file whose existence is to be checked + $destfiles = $this->map->main($filename); + // If filename does not match the To attribute of the mapper + // then filter it out of the files we are considering + if ($destfiles === null) { + return false; + } + // Sanity check + if (count($destfiles) !== 1 || $destfiles[0] === null) { + throw new BuildException("Invalid destination file results for " + . $this->targetdir . " with filename " . $filename); + } + $destname = $destfiles[0]; + $destfile = new PhingFile($this->targetdir, $destname); + return $destfile->exists() === $this->destmustexist; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/SelectSelector.php b/gulliver/thirdparty/phing/types/selectors/SelectSelector.php new file mode 100644 index 000000000..d2fc9a0c0 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/SelectSelector.php @@ -0,0 +1,124 @@ +. + */ + +require_once 'phing/types/selectors/AndSelector.php'; + +/** + * This selector just holds one other selector and forwards all + * requests to it. It exists so that there is a single selector + * type that can exist outside of any targets, as an element of + * project. It overrides all of the reference stuff so that it + * works as expected. Note that this is the only selector you + * can reference. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @version $Revision: 1.6 $ + * @package phing.types.selectors + */ +class SelectSelector extends AndSelector { + + public function toString() { + $buf = ""; + if ($this->hasSelectors()) { + $buf .= "{select: "; + $buf .= parent::toString(); + $buf .= "}"; + } + return $buf; + } + + /** + * Performs the check for circular references and returns the + * referenced Selector. + */ + private function getRef() { + $o = $this->getCheckedRef(get_class($this), "SelectSelector"); + return $o; + } + + /** + * Indicates whether there are any selectors here. + */ + public function hasSelectors() { + if ($this->isReference()) { + return $this->getRef()->hasSelectors(); + } + return parent::hasSelectors(); + } + + /** + * Gives the count of the number of selectors in this container + */ + public function selectorCount() { + if ($this->isReference()) { + return $this->getRef()->selectorCount(); + } + return parent::selectorCount(); + } + + /** + * Returns the set of selectors as an array. + */ + public function getSelectors(Project $p) { + if ($this->isReference()) { + return $this->getRef()->getSelectors($p); + } + return parent::getSelectors($p); + } + + /** + * Returns an enumerator for accessing the set of selectors. + */ + public function selectorElements() { + if ($this->isReference()) { + return $this->getRef()->selectorElements(); + } + return parent::selectorElements(); + } + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + * @return the selector that was added + */ + public function appendSelector(FileSelector $selector) { + if ($this->isReference()) { + throw $this->noChildrenAllowed(); + } + parent::appendSelector($selector); + } + + /** + * Makes sure that there is only one entry, sets an error message if + * not. + */ + public function verifySettings() { + if ($this->selectorCount() != 1) { + $this->setError("One and only one selector is allowed within the " + . " tag"); + } + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/SelectorContainer.php b/gulliver/thirdparty/phing/types/selectors/SelectorContainer.php new file mode 100644 index 000000000..5600c1804 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/SelectorContainer.php @@ -0,0 +1,141 @@ +. + */ + + +/** + * This is the interface for selectors that can contain other selectors. + * + * @author Bruce Atherton + * @package phing.types.selectors + */ +interface SelectorContainer { + + /** + * Indicates whether there are any selectors here. + * + * @return whether any selectors are in this container + */ + public function hasSelectors(); + + /** + * Gives the count of the number of selectors in this container + * + * @return the number of selectors in this container + */ + public function selectorCount(); + + /** + * Returns a *copy* of the set of selectors as an array. + * + * @return an array of selectors in this container + */ + public function getSelectors(Project $p); + + /** + * Returns an array for accessing the set of selectors. + * + * @return an enumerator that goes through each of the selectors + */ + public function selectorElements(); + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + * @return the selector that was added + */ + public function appendSelector(FileSelector $selector); + + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public function createSelector(); + + /** + * add an "And" selector entry on the selector list + */ + public function createAnd(); + + /** + * add an "Or" selector entry on the selector list + */ + public function createOr(); + + /** + * add a "Not" selector entry on the selector list + */ + public function createNot(); + + /** + * add a "None" selector entry on the selector list + */ + public function createNone(); + + /** + * add a majority selector entry on the selector list + */ + public function createMajority(); + + /** + * add a selector date entry on the selector list + */ + public function createDate(); + + /** + * add a selector size entry on the selector list + */ + public function createSize(); + + /** + * add a selector filename entry on the selector list + */ + public function createFilename(); + + /** + * add an extended selector entry on the selector list + */ + public function createCustom(); + + /** + * add a contains selector entry on the selector list + */ + public function createContains(); + + /** + * add a present selector entry on the selector list + */ + public function createPresent(); + + /** + * add a depth selector entry on the selector list + */ + public function createDepth(); + + /** + * add a depends selector entry on the selector list + */ + public function createDepend(); + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/SelectorScanner.php b/gulliver/thirdparty/phing/types/selectors/SelectorScanner.php new file mode 100644 index 000000000..d7a483756 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/SelectorScanner.php @@ -0,0 +1,55 @@ +. + */ + + +/** + * An interface used to describe the actions required by any type of + * directory scanner that supports Selecters. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +interface SelectorScanner { + + /** + * Sets the selectors the scanner should use. + * + * @param selectors the list of selectors + */ + public function setSelectors($selectors); + + /** + * Directories which were selected out of a scan. + * + * @param selectors list selector objects + */ + public function getDeselectedDirectories(); + + /** + * Files which were selected out of a scan. + * + * @param selectors list selector objects + */ + public function getDeselectedFiles(); + +} diff --git a/gulliver/thirdparty/phing/types/selectors/SelectorUtils.php b/gulliver/thirdparty/phing/types/selectors/SelectorUtils.php new file mode 100644 index 000000000..ab88886d5 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/SelectorUtils.php @@ -0,0 +1,440 @@ +. + */ + +include_once 'phing/util/StringHelper.php'; + +/** + *

    This is a utility class used by selectors and DirectoryScanner. The + * functionality more properly belongs just to selectors, but unfortunately + * DirectoryScanner exposed these as protected methods. Thus we have to + * support any subclasses of DirectoryScanner that may access these methods. + *

    + *

    This is a Singleton.

    + * + * @author Hans Lellelid, hans@xmpl.org (Phing) + * @author Arnout J. Kuiper, ajkuiper@wxs.nl (Ant) + * @author Magesh Umasankar + * @author Bruce Atherton, bruce@callenish.com (Ant) + * @package phing.types.selectors + */ +class SelectorUtils { + + private static $instance; + + /** + * Retrieves the instance of the Singleton. + */ + public static function getInstance() { + if (!isset(self::$instance)) { + self::$instance = new SelectorUtils(); + } + return self::$instance; + } + + /** + * Tests whether or not a given path matches the start of a given + * pattern up to the first "**". + *

    + * This is not a general purpose test and should only be used if you + * can live with false positives. For example, pattern=**\a + * and str=b will yield true. + * + * @param pattern The pattern to match against. Must not be + * null. + * @param str The path to match, as a String. Must not be + * null. + * @param isCaseSensitive Whether or not matching should be performed + * case sensitively. + * + * @return whether or not a given path matches the start of a given + * pattern up to the first "**". + */ + public static function matchPatternStart($pattern, $str, $isCaseSensitive = true) { + + // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a + // DIRECTORY_SEPARATOR. + // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a + // DIRECTORY_SEPARATOR. + if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !== + StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) { + return false; + } + + $patDirs = explode(DIRECTORY_SEPARATOR, $pattern); + $strDirs = explode(DIRECTORY_SEPARATOR, $str); + + $patIdxStart = 0; + $patIdxEnd = count($patDirs)-1; + $strIdxStart = 0; + $strIdxEnd = count($strDirs)-1; + + // up to first '**' + while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) { + $patDir = $patDirs[$patIdxStart]; + if ($patDir == "**") { + break; + } + if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) { + return false; + } + $patIdxStart++; + $strIdxStart++; + } + + if ($strIdxStart > $strIdxEnd) { + // String is exhausted + return true; + } elseif ($patIdxStart > $patIdxEnd) { + // String not exhausted, but pattern is. Failure. + return false; + } else { + // pattern now holds ** while string is not exhausted + // this will generate false positives but we can live with that. + return true; + } + } + + /** + * Tests whether or not a given path matches a given pattern. + * + * @param pattern The pattern to match against. Must not be + * null. + * @param str The path to match, as a String. Must not be + * null. + * @param isCaseSensitive Whether or not matching should be performed + * case sensitively. + * + * @return true if the pattern matches against the string, + * or false otherwise. + */ + public static function matchPath($pattern, $str, $isCaseSensitive = true) { + + // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a + // DIRECTORY_SEPARATOR. + // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a + // DIRECTORY_SEPARATOR. + if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !== + StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) { + return false; + } + + $patDirs = explode(DIRECTORY_SEPARATOR, $pattern); + $strDirs = explode(DIRECTORY_SEPARATOR, $str); + + $patIdxStart = 0; + $patIdxEnd = count($patDirs)-1; + $strIdxStart = 0; + $strIdxEnd = count($strDirs)-1; + + // up to first '**' + while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) { + $patDir = $patDirs[$patIdxStart]; + if ($patDir == "**") { + break; + } + if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) { + return false; + } + $patIdxStart++; + $strIdxStart++; + } + if ($strIdxStart > $strIdxEnd) { + // String is exhausted + for ($i=$patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patDirs[$i] != "**") { + return false; + } + } + return true; + } elseif ($patIdxStart > $patIdxEnd) { + // String not exhausted, but pattern is. Failure. + return false; + } + + // up to last '**' + while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) { + $patDir = $patDirs[$patIdxEnd]; + if ($patDir == "**") { + break; + } + if (!self::match($patDir, $strDirs[$strIdxEnd], $isCaseSensitive)) { + return false; + } + $patIdxEnd--; + $strIdxEnd--; + } + + if ($strIdxStart > $strIdxEnd) { + // String is exhausted + for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patDirs[$i] != "**") { + return false; + } + } + return true; + } + + while ($patIdxStart != $patIdxEnd && $strIdxStart <= $strIdxEnd) { + $patIdxTmp = -1; + for ($i = $patIdxStart+1; $i <= $patIdxEnd; $i++) { + if ($patDirs[$i] == "**") { + $patIdxTmp = $i; + break; + } + } + if ($patIdxTmp == $patIdxStart+1) { + // '**/**' situation, so skip one + $patIdxStart++; + continue; + } + // Find the pattern between padIdxStart & padIdxTmp in str between + // strIdxStart & strIdxEnd + $patLength = ($patIdxTmp-$patIdxStart-1); + $strLength = ($strIdxEnd-$strIdxStart+1); + $foundIdx = -1; + + //strLoop: (start of outer loop) + for ($i=0; $i <= $strLength - $patLength; $i++) { + for ($j = 0; $j < $patLength; $j++) { + $subPat = $patDirs[$patIdxStart+$j+1]; + $subStr = $strDirs[$strIdxStart+$i+$j]; + if (!self::match($subPat, $subStr, $isCaseSensitive)) { + continue 2; // continue up two levels (to strLoop:) + } + } + $foundIdx = $strIdxStart+$i; // only reached if all sub patterns matched + break; + } + + if ($foundIdx == -1) { + return false; + } + + $patIdxStart = $patIdxTmp; + $strIdxStart = $foundIdx + $patLength; + } + + for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patDirs[$i] != "**") { + return false; + } + } + + return true; + } + + /** + * Tests whether or not a string matches against a pattern. + * The pattern may contain two special characters:
    + * '*' means zero or more characters
    + * '?' means one and only one character + * + * @param pattern The pattern to match against. + * Must not be null. + * @param str The string which must be matched against the pattern. + * Must not be null. + * @param isCaseSensitive Whether or not matching should be performed + * case sensitively. + * + * + * @return true if the string matches against the pattern, + * or false otherwise. + */ + public static function match($pattern, $str, $isCaseSensitive = true) { + + $patArr = StringHelper::toCharArray($pattern); + $strArr = StringHelper::toCharArray($str); + $patIdxStart = 0; + $patIdxEnd = count($patArr)-1; + $strIdxStart = 0; + $strIdxEnd = count($strArr)-1; + + $containsStar = false; + for ($i = 0, $size=count($patArr); $i < $size; $i++) { + if ($patArr[$i] == '*') { + $containsStar = true; + break; + } + } + + if (!$containsStar) { + // No '*'s, so we make a shortcut + if ($patIdxEnd != $strIdxEnd) { + return false; // Pattern and string do not have the same size + } + for ($i = 0; $i <= $patIdxEnd; $i++) { + $ch = $patArr[$i]; + if ($ch != '?') { + if ($isCaseSensitive && $ch !== $strArr[$i]) { + return false;// Character mismatch + } + if (!$isCaseSensitive && strtoupper($ch) !== + strtoupper($strArr[$i])) { + return false; // Character mismatch + } + } + } + return true; // String matches against pattern + } + + if ($patIdxEnd == 0) { + return true; // Pattern contains only '*', which matches anything + } + + // Process characters before first star + while(($ch = $patArr[$patIdxStart]) != '*' && $strIdxStart <= $strIdxEnd) { + if ($ch != '?') { + if ($isCaseSensitive && $ch !== $strArr[$strIdxStart]) { + return false;// Character mismatch + } + if (!$isCaseSensitive && strtoupper($ch) !== + strtoupper($strArr[$strIdxStart])) { + return false;// Character mismatch + } + } + $patIdxStart++; + $strIdxStart++; + } + + if ($strIdxStart > $strIdxEnd) { + // All characters in the string are used. Check if only '*'s are + // left in the pattern. If so, we succeeded. Otherwise failure. + for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patArr[$i] != '*') { + return false; + } + } + return true; + } + + // Process characters after last star + while(($ch = $patArr[$patIdxEnd]) != '*' && $strIdxStart <= $strIdxEnd) { + if ($ch != '?') { + if ($isCaseSensitive && $ch !== $strArr[$strIdxEnd]) { + return false;// Character mismatch + } + if (!$isCaseSensitive && strtoupper($ch) !== + strtoupper($strArr[$strIdxEnd])) { + return false;// Character mismatch + } + } + $patIdxEnd--; + $strIdxEnd--; + } + if ($strIdxStart > $strIdxEnd) { + // All characters in the string are used. Check if only '*'s are + // left in the pattern. If so, we succeeded. Otherwise failure. + for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patArr[$i] != '*') { + return false; + } + } + return true; + } + + // process pattern between stars. padIdxStart and patIdxEnd point + // always to a '*'. + while ($patIdxStart !== $patIdxEnd && $strIdxStart <= $strIdxEnd) { + $patIdxTmp = -1; + for ($i = $patIdxStart+1; $i <= $patIdxEnd; $i++) { + if ($patArr[$i] == '*') { + $patIdxTmp = $i; + break; + } + } + if ($patIdxTmp === $patIdxStart + 1) { + // Two stars next to each other, skip the first one. + $patIdxStart++; + continue; + } + // Find the pattern between padIdxStart & padIdxTmp in str between + // strIdxStart & strIdxEnd + $patLength = ($patIdxTmp - $patIdxStart - 1); + $strLength = ($strIdxEnd - $strIdxStart + 1); + $foundIdx = -1; + + //strLoop: + for ($i = 0; $i <= $strLength - $patLength; $i++) { + for ($j = 0; $j < $patLength; $j++) { + $ch = $patArr[$patIdxStart+$j+1]; + if ($ch != '?') { + if ($isCaseSensitive && $ch !== $strArr[$strIdxStart+$i+$j]) { + continue 2; //continue to strLoop: + } + if (!$isCaseSensitive && strtoupper($ch) !== + strtoupper($strArr[$strIdxStart+$i+$j])) { + continue 2; //continue to strLoop: + } + } + } + // only reached if sub loop completed w/o invoking continue 2 + $foundIdx = $strIdxStart + $i; + break; + } + + if ($foundIdx == -1) { + return false; + } + + $patIdxStart = $patIdxTmp; + $strIdxStart = $foundIdx + $patLength; + } + + // All characters in the string are used. Check if only '*'s are left + // in the pattern. If so, we succeeded. Otherwise failure. + for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) { + if ($patArr[$i] != '*') { + return false; + } + } + return true; + } + + /** + * Returns dependency information on these two files. If src has been + * modified later than target, it returns true. If target doesn't exist, + * it likewise returns true. Otherwise, target is newer than src and + * is not out of date, thus the method returns false. It also returns + * false if the src file doesn't even exist, since how could the + * target then be out of date. + * + * @param PhingFile $src the original file + * @param PhingFile $target the file being compared against + * @param int $granularity the amount in seconds of slack we will give in + * determining out of dateness + * @return whether the target is out of date + */ + public static function isOutOfDate(PhingFile $src, PhingFile $target, $granularity) { + if (!$src->exists()) { + return false; + } + if (!$target->exists()) { + return true; + } + if (($src->lastModified() - $granularity) > $target->lastModified()) { + return true; + } + return false; + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/SizeSelector.php b/gulliver/thirdparty/phing/types/selectors/SizeSelector.php new file mode 100644 index 000000000..1432f317a --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/SizeSelector.php @@ -0,0 +1,228 @@ +. + */ + + +/** + * Selector that filters files based on their size. + * + * @author Hans Lellelid (Phing) + * @author Bruce Atherton (Ant) + * @package phing.types.selectors + */ +class SizeSelector extends BaseExtendSelector { + + private $size = -1; + private $multiplier = 1; + private $sizelimit = -1; + private $cmp = 2; + const SIZE_KEY = "value"; + const UNITS_KEY = "units"; + const WHEN_KEY = "when"; + + private static $sizeComparisons = array("less", "more", "equal"); + private static $byteUnits = array("K", "k", "kilo", "KILO", + "Ki", "KI", "ki", "kibi", "KIBI", + "M", "m", "mega", "MEGA", + "Mi", "MI", "mi", "mebi", "MEBI", + "G", "g", "giga", "GIGA", + "Gi", "GI", "gi", "gibi", "GIBI", + "T", "t", "tera", "TERA", + /* You wish! */ "Ti", "TI", "ti", "tebi", "TEBI" + ); + + public function toString() { + $buf = "{sizeselector value: "; + $buf .= $this->sizelimit; + $buf .= "compare: "; + if ($this->cmp === 0) { + $buf .= "less"; + } elseif ($this->cmp === 1) { + $buf .= "more"; + } else { + $buf .= "equal"; + } + $buf .= "}"; + return $buf; + } + + /** + * A size selector needs to know what size to base its selecting on. + * This will be further modified by the multiplier to get an + * actual size limit. + * + * @param size the size to select against expressed in units + */ + public function setValue($size) { + $this->size = $size; + if (($this->multiplier !== 0) && ($this->size > -1)) { + $this->sizelimit = $size * $this->multiplier; + } + } + + /** + * Sets the units to use for the comparison. This is a little + * complicated because common usage has created standards that + * play havoc with capitalization rules. Thus, some people will + * use "K" for indicating 1000's, when the SI standard calls for + * "k". Others have tried to introduce "K" as a multiple of 1024, + * but that falls down when you reach "M", since "m" is already + * defined as 0.001. + *

    + * To get around this complexity, a number of standards bodies + * have proposed the 2^10 standard, and at least one has adopted + * it. But we are still left with a populace that isn't clear on + * how capitalization should work. + *

    + * We therefore ignore capitalization as much as possible. + * Completely mixed case is not possible, but all upper and lower + * forms are accepted for all long and short forms. Since we have + * no need to work with the 0.001 case, this practice works here. + *

    + * This function translates all the long and short forms that a + * unit prefix can occur in and translates them into a single + * multiplier. + * + * @param $units The units to compare the size to. + * @return void + */ + public function setUnits($units) { + $i = array_search($units, self::$byteUnits, true); + if ($i === false) $i = -1; // make it java-like + + $this->multiplier = 0; + if (($i > -1) && ($i < 4)) { + $this->multiplier = 1000; + } elseif (($i > 3) && ($i < 9)) { + $this->multiplier = 1024; + } elseif (($i > 8) && ($i < 13)) { + $this->multiplier = 1000000; + } elseif (($i > 12) && ($i < 18)) { + $this->multiplier = 1048576; + } elseif (($i > 17) && ($i < 22)) { + $this->multiplier = 1000000000; + } elseif (($i > 21) && ($i < 27)) { + $this->multiplier = 1073741824; + } elseif (($i > 26) && ($i < 31)) { + $this->multiplier = 1000000000000; + } elseif (($i > 30) && ($i < 36)) { + $this->multiplier = 1099511627776; + } + if (($this->multiplier > 0) && ($this->size > -1)) { + $this->sizelimit = $this->size * $this->multiplier; + } + } + + /** + * This specifies when the file should be selected, whether it be + * when the file matches a particular size, when it is smaller, + * or whether it is larger. + * + * @param cmp The comparison to perform, an EnumeratedAttribute + */ + public function setWhen($cmp) { + $c = array_search($cmp, self::$sizeComparisons, true); + if ($c !== false) { + $this->cmp = $c; + } + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i = 0, $size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + switch(strtolower($paramname)) { + case self::SIZE_KEY: + try { + $this->setValue($parameters[$i]->getValue()); + } catch (Exception $nfe) { + $this->setError("Invalid size setting " + . $parameters[$i]->getValue()); + } + break; + case self::UNITS_KEY: + $this->setUnits($parameters[$i]->getValue()); + break; + case self::WHEN_KEY: + $this->setWhen($parameters[$i]->getValue()); + break; + default: + $this->setError("Invalid parameter " . $paramname); + } + } + } + } + + /** + *

    Checks to make sure all settings are kosher. In this case, it + * means that the size attribute has been set (to a positive value), + * that the multiplier has a valid setting, and that the size limit + * is valid. Since the latter is a calculated value, this can only + * fail due to a programming error. + *

    + *

    If a problem is detected, the setError() method is called. + *

    + */ + public function verifySettings() { + if ($this->size < 0) { + $this->setError("The value attribute is required, and must be positive"); + } elseif ($this->multiplier < 1) { + $this->setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti"); + } elseif ($this->sizelimit < 0) { + $this->setError("Internal error: Code is not setting sizelimit correctly"); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param basedir A PhingFile object for the base directory + * @param filename The name of the file to check + * @param file A PhingFile object for this filename + * @return whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + $this->validate(); + + // Directory size never selected for + if ($file->isDirectory()) { + return true; + } + if ($this->cmp === 0) { + return ($file->length() < $this->sizelimit); + } elseif ($this->cmp === 1) { + return ($file->length() > $this->sizelimit); + } else { + return ($file->length() === $this->sizelimit); + } + } + +} + diff --git a/gulliver/thirdparty/phing/types/selectors/TypeSelector.php b/gulliver/thirdparty/phing/types/selectors/TypeSelector.php new file mode 100644 index 000000000..d5fd9bcc5 --- /dev/null +++ b/gulliver/thirdparty/phing/types/selectors/TypeSelector.php @@ -0,0 +1,113 @@ +. + */ + +require_once 'phing/types/selectors/BaseExtendSelector.php'; + +/** + * Selector that selects a certain kind of file: directory or regular file. + * + * @author Hans Lellelid (Phing) + * @author Jeff Turner (Ant) + * @version $Revision: 1.3 $ + * @package phing.types.selectors + */ +class TypeSelector extends BaseExtendSelector { + + private $type; + + /** Key to used for parameterized custom selector */ + const TYPE_KEY = "type"; + + /** Valid types */ + private static $types = array('file', 'dir'); + + /** + * @return string A string describing this object + */ + public function toString() { + $buf = "{typeselector type: " . $this->type . "}"; + return $buf; + } + + /** + * Set the type of file to require. + * @param string $type The type of file - 'file' or 'dir' + */ + public function setType($type) { + $this->type = $type; + } + + /** + * When using this as a custom selector, this method will be called. + * It translates each parameter into the appropriate setXXX() call. + * + * @param array $parameters the complete set of parameters for this selector + */ + public function setParameters($parameters) { + parent::setParameters($parameters); + if ($parameters !== null) { + for ($i = 0, $size=count($parameters); $i < $size; $i++) { + $paramname = $parameters[$i]->getName(); + if (self::TYPE_KEY == strtolower($paramname)) { + $this->setType($parameters[$i]->getValue()); + } else { + $this->setError("Invalid parameter " . $paramname); + } + } + } + } + + /** + * Checks to make sure all settings are kosher. In this case, it + * means that the pattern attribute has been set. + * + */ + public function verifySettings() { + if ($this->type === null) { + $this->setError("The type attribute is required"); + } elseif (!in_array($this->type, self::$types, true)) { + $this->setError("Invalid type specified; must be one of (" . implode(self::$types) . ")"); + } + } + + /** + * The heart of the matter. This is where the selector gets to decide + * on the inclusion of a file in a particular fileset. + * + * @param PhingFile $basedir the base directory the scan is being done from + * @param string $filename is the name of the file to check + * @param PhingFile $file is a PhingFile object the selector can use + * @return boolean Whether the file should be selected or not + */ + public function isSelected(PhingFile $basedir, $filename, PhingFile $file) { + + // throw BuildException on error + $this->validate(); + + if ($file->isDirectory()) { + return $this->type === 'dir'; + } else { + return $this->type === 'file'; + } + } + +} diff --git a/gulliver/thirdparty/phing/util/DirectoryScanner.php b/gulliver/thirdparty/phing/util/DirectoryScanner.php new file mode 100644 index 000000000..d8e1589d3 --- /dev/null +++ b/gulliver/thirdparty/phing/util/DirectoryScanner.php @@ -0,0 +1,710 @@ +. + */ + +require_once 'phing/types/selectors/SelectorScanner.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/types/selectors/SelectorUtils.php'; + +/** + * Class for scanning a directory for files/directories that match a certain + * criteria. + * + * These criteria consist of a set of include and exclude patterns. With these + * patterns, you can select which files you want to have included, and which + * files you want to have excluded. + * + * The idea is simple. A given directory is recursively scanned for all files + * and directories. Each file/directory is matched against a set of include + * and exclude patterns. Only files/directories that match at least one + * pattern of the include pattern list, and don't match a pattern of the + * exclude pattern list will be placed in the list of files/directories found. + * + * When no list of include patterns is supplied, "**" will be used, which + * means that everything will be matched. When no list of exclude patterns is + * supplied, an empty list is used, such that nothing will be excluded. + * + * The pattern matching is done as follows: + * The name to be matched is split up in path segments. A path segment is the + * name of a directory or file, which is bounded by DIRECTORY_SEPARATOR + * ('/' under UNIX, '\' under Windows). + * E.g. "abc/def/ghi/xyz.php" is split up in the segments "abc", "def", "ghi" + * and "xyz.php". + * The same is done for the pattern against which should be matched. + * + * Then the segments of the name and the pattern will be matched against each + * other. When '**' is used for a path segment in the pattern, then it matches + * zero or more path segments of the name. + * + * There are special case regarding the use of DIRECTORY_SEPARATOR at + * the beginning of the pattern and the string to match: + * When a pattern starts with a DIRECTORY_SEPARATOR, the string + * to match must also start with a DIRECTORY_SEPARATOR. + * When a pattern does not start with a DIRECTORY_SEPARATOR, the + * string to match may not start with a DIRECTORY_SEPARATOR. + * When one of these rules is not obeyed, the string will not + * match. + * + * When a name path segment is matched against a pattern path segment, the + * following special characters can be used: + * '*' matches zero or more characters, + * '?' matches one character. + * + * Examples: + * + * "**\*.php" matches all .php files/dirs in a directory tree. + * + * "test\a??.php" matches all files/dirs which start with an 'a', then two + * more characters and then ".php", in a directory called test. + * + * "**" matches everything in a directory tree. + * + * "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where + * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123"). + * + * Case sensitivity may be turned off if necessary. By default, it is + * turned on. + * + * Example of usage: + * $ds = new DirectroyScanner(); + * $includes = array("**\*.php"); + * $excludes = array("modules\*\**"); + * $ds->SetIncludes($includes); + * $ds->SetExcludes($excludes); + * $ds->SetBasedir("test"); + * $ds->SetCaseSensitive(true); + * $ds->Scan(); + * + * print("FILES:"); + * $files = ds->GetIncludedFiles(); + * for ($i = 0; $i < count($files);$i++) { + * println("$files[$i]\n"); + * } + * + * This will scan a directory called test for .php files, but excludes all + * .php files in all directories under a directory called "modules" + * + * This class is complete preg/ereg free port of the Java class + * org.apache.tools.ant.DirectoryScanner. Even functions that use preg/ereg + * internally (like split()) are not used. Only the _fast_ string functions + * and comparison operators (=== !=== etc) are used for matching and tokenizing. + * + * @author Arnout J. Kuiper, ajkuiper@wxs.nl + * @author Magesh Umasankar, umagesh@rediffmail.com + * @author Andreas Aderhold, andi@binarycloud.com + * + * @version $Revision: 1.15 $ + * @package phing.util + */ +class DirectoryScanner implements SelectorScanner { + + /** default set of excludes */ + protected $DEFAULTEXCLUDES = array( + "**/*~", + "**/#*#", + "**/.#*", + "**/%*%", + "**/CVS", + "**/CVS/**", + "**/.cvsignore", + "**/SCCS", + "**/SCCS/**", + "**/vssver.scc", + "**/.svn", + "**/.svn/**", + "**/._*", + "**/.DS_Store", + ); + + /** The base directory which should be scanned. */ + protected $basedir; + + /** The patterns for the files that should be included. */ + protected $includes = null; + + /** The patterns for the files that should be excluded. */ + protected $excludes = null; + + /** + * The files that where found and matched at least one includes, and matched + * no excludes. + */ + protected $filesIncluded; + + /** The files that where found and did not match any includes. Trie */ + protected $filesNotIncluded; + + /** + * The files that where found and matched at least one includes, and also + * matched at least one excludes. Trie object. + */ + protected $filesExcluded; + + /** + * The directories that where found and matched at least one includes, and + * matched no excludes. + */ + protected $dirsIncluded; + + /** The directories that where found and did not match any includes. */ + protected $dirsNotIncluded; + + /** + * The files that where found and matched at least one includes, and also + * matched at least one excludes. + */ + protected $dirsExcluded; + + /** Have the vars holding our results been built by a slow scan? */ + protected $haveSlowResults = false; + + /** Should the file system be treated as a case sensitive one? */ + protected $isCaseSensitive = true; + + /** Selectors */ + protected $selectors = null; + + protected $filesDeselected; + protected $dirsDeselected; + + /** if there are no deselected files */ + protected $everythingIncluded = true; + + /** + * Does the path match the start of this pattern up to the first "**". + * This is a static mehtod and should always be called static + * + * This is not a general purpose test and should only be used if you + * can live with false positives. + * + * pattern=**\a and str=b will yield true. + * + * @param pattern the (non-null) pattern to match against + * @param str the (non-null) string (path) to match + * @param isCaseSensitive must matches be case sensitive? + * @return boolean true if matches, otherwise false + */ + function matchPatternStart($pattern, $str, $isCaseSensitive = true) { + return SelectorUtils::matchPatternStart($pattern, $str, $isCaseSensitive); + } + + /** + * Matches a path against a pattern. Static + * + * @param pattern the (non-null) pattern to match against + * @param str the (non-null) string (path) to match + * @param isCaseSensitive must a case sensitive match be done? + * + * @return true when the pattern matches against the string. + * false otherwise. + */ + function matchPath($pattern, $str, $isCaseSensitive = true) { + return SelectorUtils::matchPath($pattern, $str, $isCaseSensitive); + } + + /** + * Matches a string against a pattern. The pattern contains two special + * characters: + * '*' which means zero or more characters, + * '?' which means one and only one character. + * + * @param pattern the (non-null) pattern to match against + * @param str the (non-null) string that must be matched against the + * pattern + * + * @return boolean true when the string matches against the pattern, + * false otherwise. + * @access public + */ + function match($pattern, $str, $isCaseSensitive = true) { + return SelectorUtils::match($pattern, $str, $isCaseSensitive); + } + + /** + * Sets the basedir for scanning. This is the directory that is scanned + * recursively. All '/' and '\' characters are replaced by + * DIRECTORY_SEPARATOR + * + * @param basedir the (non-null) basedir for scanning + */ + function setBasedir($_basedir) { + $_basedir = str_replace('\\', DIRECTORY_SEPARATOR, $_basedir); + $_basedir = str_replace('/', DIRECTORY_SEPARATOR, $_basedir); + $this->basedir = $_basedir; + } + + /** + * Gets the basedir that is used for scanning. This is the directory that + * is scanned recursively. + * + * @return the basedir that is used for scanning + */ + function getBasedir() { + return $this->basedir; + } + + /** + * Sets the case sensitivity of the file system + * + * @param specifies if the filesystem is case sensitive + */ + function setCaseSensitive($_isCaseSensitive) { + $this->isCaseSensitive = ($_isCaseSensitive) ? true : false; + } + + /** + * Sets the set of include patterns to use. All '/' and '\' characters are + * replaced by DIRECTORY_SEPARATOR. So the separator used need + * not match DIRECTORY_SEPARATOR. + * + * When a pattern ends with a '/' or '\', "**" is appended. + * + * @param includes list of include patterns + */ + function setIncludes($_includes = array()) { + if (empty($_includes) || is_null($_includes)) { + $this->includes = null; + } else { + for ($i = 0; $i < count($_includes); $i++) { + $pattern = null; + $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_includes[$i]); + $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern); + if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) { + $pattern .= "**"; + } + $this->includes[] = $pattern; + } + } + } + + /** + * Sets the set of exclude patterns to use. All '/' and '\' characters are + * replaced by File.separatorChar. So the separator used need + * not match File.separatorChar. + * + * When a pattern ends with a '/' or '\', "**" is appended. + * + * @param excludes list of exclude patterns + */ + + function setExcludes($_excludes = array()) { + if (empty($_excludes) || is_null($_excludes)) { + $this->excludes = null; + } else { + for ($i = 0; $i < count($_excludes); $i++) { + $pattern = null; + $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_excludes[$i]); + $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern); + if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) { + $pattern .= "**"; + } + $this->excludes[] = $pattern; + } + } + } + + /** + * Scans the base directory for files that match at least one include + * pattern, and don't match any exclude patterns. + * + */ + function scan() { + + if ((empty($this->basedir)) || (!@is_dir($this->basedir))) { + return false; + } + + if ($this->includes === null) { + // No includes supplied, so set it to 'matches all' + $this->includes = array("**"); + } + if (is_null($this->excludes)) { + $this->excludes = array(); + } + + $this->filesIncluded = array(); + $this->filesNotIncluded = array(); + $this->filesExcluded = array(); + $this->dirsIncluded = array(); + $this->dirsNotIncluded = array(); + $this->dirsExcluded = array(); + $this->dirsDeselected = array(); + $this->filesDeselected = array(); + + if ($this->isIncluded("")) { + if (!$this->isExcluded("")) { + if ($this->isSelected("", $this->basedir)) { + $this->dirsIncluded[] = ""; + } else { + $this->dirsDeselected[] = ""; + } + } else { + $this->dirsExcluded[] = ""; + } + } else { + $this->dirsNotIncluded[] = ""; + } + + $this->scandir($this->basedir, "", true); + return true; + } + + /** + * Toplevel invocation for the scan. + * + * Returns immediately if a slow scan has already been requested. + */ + protected function slowScan() { + + if ($this->haveSlowResults) { + return; + } + + // copy trie object add CopyInto() method + $excl = $this->dirsExcluded; + $notIncl = $this->dirsNotIncluded; + + for ($i=0, $_i=count($excl); $i < $_i; $i++) { + if (!$this->couldHoldIncluded($excl[$i])) { + $this->scandir($this->basedir.$excl[$i], $excl[$i].DIRECTORY_SEPARATOR, false); + } + } + + for ($i=0, $_i=count($notIncl); $i < $_i; $i++) { + if (!$this->couldHoldIncluded($notIncl[$i])) { + $this->scandir($this->basedir.$notIncl[$i], $notIncl[$i].DIRECTORY_SEPARATOR, false); + } + } + + $this->haveSlowResults = true; + } + + /** + * Lists contens of a given directory and returns array with entries + * + * @param src String. Source path and name file to copy. + * + * @access public + * @return array directory entries + * @author Albert Lash, alash@plateauinnovation.com + */ + + function listDir($_dir) { + $d = dir($_dir); + $list = array(); + while($entry = $d->read()) { + if ($entry != "." && $entry != "..") { + $list[] = $entry; + } + } + $d->close(); + return $list; + } + + /** + * Scans the passed dir for files and directories. Found files and + * directories are placed in their respective collections, based on the + * matching of includes and excludes. When a directory is found, it is + * scanned recursively. + * + * @param dir the directory to scan + * @param vpath the path relative to the basedir (needed to prevent + * problems with an absolute path when using dir) + * + * @access private + * @see #filesIncluded + * @see #filesNotIncluded + * @see #filesExcluded + * @see #dirsIncluded + * @see #dirsNotIncluded + * @see #dirsExcluded + */ + private function scandir($_rootdir, $_vpath, $_fast) { + + if (!is_readable($_rootdir)) { + return; + } + + $newfiles = self::listDir($_rootdir); + + for ($i=0,$_i=count($newfiles); $i < $_i; $i++) { + + $file = $_rootdir . DIRECTORY_SEPARATOR . $newfiles[$i]; + $name = $_vpath . $newfiles[$i]; + + if (@is_dir($file)) { + if ($this->isIncluded($name)) { + if (!$this->isExcluded($name)) { + if ($this->isSelected($name, $file)) { + $this->dirsIncluded[] = $name; + if ($_fast) { + $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast); + } + } else { + $this->everythingIncluded = false; + $this->dirsDeselected[] = $name; + if ($_fast && $this->couldHoldIncluded($name)) { + $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast); + } + } + } else { + $this->everythingIncluded = false; + $this->dirsExcluded[] = $name; + if ($_fast && $this->couldHoldIncluded($name)) { + $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast); + } + } + } else { + $this->everythingIncluded = false; + $this->dirsNotIncluded[] = $name; + if ($_fast && $this->couldHoldIncluded($name)) { + $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast); + } + } + + if (!$_fast) { + $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast); + } + + } elseif (@is_file($file)) { + if ($this->isIncluded($name)) { + if (!$this->isExcluded($name)) { + if ($this->isSelected($name, $file)) { + $this->filesIncluded[] = $name; + } else { + $this->everythingIncluded = false; + $this->filesDeselected[] = $name; + } + } else { + $this->everythingIncluded = false; + $this->filesExcluded[] = $name; + } + } else { + $this->everythingIncluded = false; + $this->filesNotIncluded[] = $name; + } + } + } + } + + /** + * Tests whether a name matches against at least one include pattern. + * + * @param name the name to match + * @return true when the name matches against at least one + * include pattern, false otherwise. + */ + protected function isIncluded($_name) { + for ($i=0, $_i=count($this->includes); $i < $_i; $i++) { + if (DirectoryScanner::matchPath($this->includes[$i], $_name, $this->isCaseSensitive)) { + return true; + } + } + return false; + } + + /** + * Tests whether a name matches the start of at least one include pattern. + * + * @param name the name to match + * @return true when the name matches against at least one + * include pattern, false otherwise. + */ + protected function couldHoldIncluded($_name) { + for ($i = 0; $i < count($this->includes); $i++) { + if (DirectoryScanner::matchPatternStart($this->includes[$i], $_name, $this->isCaseSensitive)) { + return true; + } + } + return false; + } + + /** + * Tests whether a name matches against at least one exclude pattern. + * + * @param name the name to match + * @return true when the name matches against at least one + * exclude pattern, false otherwise. + */ + protected function isExcluded($_name) { + for ($i = 0; $i < count($this->excludes); $i++) { + if (DirectoryScanner::matchPath($this->excludes[$i], $_name, $this->isCaseSensitive)) { + return true; + } + } + return false; + } + + /** + * Get the names of the files that matched at least one of the include + * patterns, and matched none of the exclude patterns. + * The names are relative to the basedir. + * + * @return the names of the files + */ + function getIncludedFiles() { + return $this->filesIncluded; + } + + /** + * Get the names of the files that matched at none of the include patterns. + * The names are relative to the basedir. + * + * @return the names of the files + */ + function getNotIncludedFiles() { + $this->slowScan(); + return $this->filesNotIncluded; + } + + /** + * Get the names of the files that matched at least one of the include + * patterns, an matched also at least one of the exclude patterns. + * The names are relative to the basedir. + * + * @return the names of the files + */ + + function getExcludedFiles() { + $this->slowScan(); + return $this->filesExcluded; + } + + /** + *

    Returns the names of the files which were selected out and + * therefore not ultimately included.

    + * + *

    The names are relative to the base directory. This involves + * performing a slow scan if one has not already been completed.

    + * + * @return the names of the files which were deselected. + * + * @see #slowScan + */ + public function getDeselectedFiles() { + $this->slowScan(); + return $this->filesDeselected; + } + + /** + * Get the names of the directories that matched at least one of the include + * patterns, an matched none of the exclude patterns. + * The names are relative to the basedir. + * + * @return the names of the directories + */ + + function getIncludedDirectories() { + return $this->dirsIncluded; + } + + /** + * Get the names of the directories that matched at none of the include + * patterns. + * The names are relative to the basedir. + * + * @return the names of the directories + */ + function getNotIncludedDirectories() { + $this->slowScan(); + return $this->dirsNotIncluded; + } + + /** + *

    Returns the names of the directories which were selected out and + * therefore not ultimately included.

    + * + *

    The names are relative to the base directory. This involves + * performing a slow scan if one has not already been completed.

    + * + * @return the names of the directories which were deselected. + * + * @see #slowScan + */ + public function getDeselectedDirectories() { + $this->slowScan(); + return $this->dirsDeselected; + } + + /** + * Get the names of the directories that matched at least one of the include + * patterns, an matched also at least one of the exclude patterns. + * The names are relative to the basedir. + * + * @return the names of the directories + */ + function getExcludedDirectories() { + $this->slowScan(); + return $this->dirsExcluded; + } + + /** + * Adds the array with default exclusions to the current exclusions set. + * + */ + function addDefaultExcludes() { + //$excludesLength = ($this->excludes == null) ? 0 : count($this->excludes); + foreach($this->DEFAULTEXCLUDES as $pattern) { + $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern); + $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern); + $this->excludes[] = $pattern; + } + } + + /** + * Sets the selectors that will select the filelist. + * + * @param selectors specifies the selectors to be invoked on a scan + */ + public function setSelectors($selectors) { + $this->selectors = $selectors; + } + + /** + * Returns whether or not the scanner has included all the files or + * directories it has come across so far. + * + * @return true if all files and directories which have + * been found so far have been included. + */ + public function isEverythingIncluded() { + return $this->everythingIncluded; + } + + /** + * Tests whether a name should be selected. + * + * @param string $name The filename to check for selecting. + * @param string $file The full file path. + * @return boolean False when the selectors says that the file + * should not be selected, True otherwise. + */ + protected function isSelected($name, $file) { + if ($this->selectors !== null) { + for ($i=0,$size=count($this->selectors); $i < $size; $i++) { + if (($this->selectors[$i]->isSelected(new PhingFile($this->basedir), $name, new PhingFile($file))) === false) { + return false; + } + } + } + return true; + } + +} diff --git a/gulliver/thirdparty/phing/util/ExtendedFileStream.php b/gulliver/thirdparty/phing/util/ExtendedFileStream.php new file mode 100644 index 000000000..453e512a2 --- /dev/null +++ b/gulliver/thirdparty/phing/util/ExtendedFileStream.php @@ -0,0 +1,133 @@ +. + */ + + /** + * Extended file stream wrapper class which auto-creates directories + * + * @author Michiel Rook + * @version $Id: ExtendedFileStream.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.util + */ + class ExtendedFileStream + { + private $fp = NULL; + + static function registerStream() + { + if (!in_array("efile", stream_get_wrappers())) + { + stream_wrapper_register("efile", "ExtendedFileStream"); + } + } + + private function createDirectories($path) + { + $f = new PhingFile($path); + if (!$f->exists()) { + $f->mkdirs(); + } + } + + function stream_open($path, $mode, $options, &$opened_path) + { + /** Small fix for Windows */ + if ($path[8] == DIRECTORY_SEPARATOR) + { + $filepath = substr($path, 7); + } + else + { + $filepath = substr($path, 8); + } + + $this->createDirectories(dirname($filepath)); + + $this->fp = fopen($filepath, $mode); + + return true; + } + + function stream_close() + { + fclose($this->fp); + $this->fp = NULL; + } + + function stream_read($count) + { + return fread($this->fp, $count); + } + + function stream_write($data) + { + return fwrite($this->fp, $data); + } + + function stream_eof() + { + return feof($this->fp); + } + + function stream_tell() + { + return ftell($this->fp); + } + + function stream_seek($offset, $whence) + { + return fseek($this->fp, $offset, $whence); + } + + function stream_flush() + { + return fflush($this->fp); + } + + function stream_stat() + { + return fstat($this->fp); + } + + function unlink($path) + { + return FALSE; + } + + function rename($path_from, $path_to) + { + return FALSE; + } + + function mkdir($path, $mode, $options) + { + return FALSE; + } + + function rmdir($path, $options) + { + return FALSE; + } + }; + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/util/FileUtils.php b/gulliver/thirdparty/phing/util/FileUtils.php new file mode 100644 index 000000000..2618831e7 --- /dev/null +++ b/gulliver/thirdparty/phing/util/FileUtils.php @@ -0,0 +1,294 @@ +. + */ + +include_once 'phing/system/lang/Character.php'; +include_once 'phing/util/StringHelper.php'; +include_once 'phing/system/io/BufferedReader.php'; +include_once 'phing/system/io/BufferedWriter.php'; +include_once 'phing/filters/util/ChainReaderHelper.php'; +include_once 'phing/system/io/PhingFile.php'; + +/** + * File utility class. + * - handles os independent stuff etc + * - mapper stuff + * - filter stuff + * + * @package phing.util + * @version $Revision: 1.10 $ + */ +class FileUtils { + + /** + * Returns a new Reader with filterchains applied. If filterchains are empty, + * simply returns passed reader. + * + * @param Reader $in Reader to modify (if appropriate). + * @param array &$filterChains filter chains to apply. + * @param Project $project + * @return Reader Assembled Reader (w/ filter chains). + */ + public static function getChainedReader(Reader $in, &$filterChains, Project $project) { + if (!empty($filterChains)) { + $crh = new ChainReaderHelper(); + $crh->setBufferSize(65536); // 64k buffer, but isn't being used (yet?) + $crh->setPrimaryReader($in); + $crh->setFilterChains($filterChains); + $crh->setProject($project); + $rdr = $crh->getAssembledReader(); + return $rdr; + } else { + return $in; + } + } + + /** + * Copies a file using filter chains. + * + * @param PhingFile $sourceFile + * @param PhingFile $destFile + * @param boolean $overwrite + * @param boolean $preserveLastModified + * @param array $filterChains + * @param Project $project + * @return void + */ + function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project) { + + if ($overwrite || !$destFile->exists() || $destFile->lastModified() < $sourceFile->lastModified()) { + if ($destFile->exists() && $destFile->isFile()) { + $destFile->delete(); + } + + // ensure that parent dir of dest file exists! + $parent = $destFile->getParentFile(); + if ($parent !== null && !$parent->exists()) { + $parent->mkdirs(); + } + + if ((is_array($filterChains)) && (!empty($filterChains))) { + + $in = self::getChainedReader(new BufferedReader(new FileReader($sourceFile)), $filterChains, $project); + $out = new BufferedWriter(new FileWriter($destFile)); + + // New read() methods returns a big buffer. + while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF + $out->write($buffer); + } + + if ( $in !== null ) + $in->close(); + if ( $out !== null ) + $out->close(); + } else { + // simple copy (no filtering) + $sourceFile->copyTo($destFile); + } + + if ($preserveLastModified) { + $destFile->setLastModified($sourceFile->lastModified()); + } + + } + } + + /** + * Interpret the filename as a file relative to the given file - + * unless the filename already represents an absolute filename. + * + * @param $file the "reference" file for relative paths. This + * instance must be an absolute file and must not contain + * ./ or ../ sequences (same for \ instead of /). + * @param $filename a file name + * + * @return PhingFile A PhingFile object pointing to an absolute file that doesn't contain ./ or ../ sequences + * and uses the correct separator for the current platform. + */ + function resolveFile($file, $filename) { + // remove this and use the static class constant File::seperator + // as soon as ZE2 is ready + $fs = FileSystem::getFileSystem(); + + $filename = str_replace('/', $fs->getSeparator(), str_replace('\\', $fs->getSeparator(), $filename)); + + // deal with absolute files + if (StringHelper::startsWith($fs->getSeparator(), $filename) || + (strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':')) { + return new PhingFile($this->normalize($filename)); + } + + if (strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':') { + return new PhingFile($this->normalize($filename)); + } + + $helpFile = new PhingFile($file->getAbsolutePath()); + + $tok = strtok($filename, $fs->getSeparator()); + while ($tok !== false) { + $part = $tok; + if ($part === '..') { + $parentFile = $helpFile->getParent(); + if ($parentFile === null) { + $msg = "The file or path you specified ($filename) is invalid relative to ".$file->getPath(); + throw new IOException($msg); + } + $helpFile = new PhingFile($parentFile); + } else if ($part === '.') { + // Do nothing here + } else { + $helpFile = new PhingFile($helpFile, $part); + } + $tok = strtok($fs->getSeparator()); + } + return new PhingFile($helpFile->getAbsolutePath()); + } + + /** + * Normalize the given absolute path. + * + * This includes: + * - Uppercase the drive letter if there is one. + * - Remove redundant slashes after the drive spec. + * - resolve all ./, .\, ../ and ..\ sequences. + * - DOS style paths that start with a drive letter will have + * \ as the separator. + * @param string $path Path to normalize. + * @return string + */ + function normalize($path) { + + $path = (string) $path; + $orig = $path; + + $path = str_replace('/', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $path)); + + // make sure we are dealing with an absolute path + if (!StringHelper::startsWith(DIRECTORY_SEPARATOR, $path) + && !(strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':')) { + throw new IOException("$path is not an absolute path"); + } + + $dosWithDrive = false; + $root = null; + + // Eliminate consecutive slashes after the drive spec + + if (strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':') { + $dosWithDrive = true; + + $ca = str_replace('/', '\\', $path); + $ca = StringHelper::toCharArray($ca); + + $path = strtoupper($ca[0]).':'; + + for ($i=2, $_i=count($ca); $i < $_i; $i++) { + if (($ca[$i] !== '\\') || + ($ca[$i] === '\\' && $ca[$i - 1] !== '\\') + ) { + $path .= $ca[$i]; + } + } + + $path = str_replace('\\', DIRECTORY_SEPARATOR, $path); + + if (strlen($path) == 2) { + $root = $path; + $path = ""; + } else { + $root = substr($path, 0, 3); + $path = substr($path, 3); + } + + } else { + if (strlen($path) == 1) { + $root = DIRECTORY_SEPARATOR; + $path = ""; + } else if ($path{1} == DIRECTORY_SEPARATOR) { + // UNC drive + $root = DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR; + $path = substr($path, 2); + } + else { + $root = DIRECTORY_SEPARATOR; + $path = substr($path, 1); + } + } + + $s = array(); + array_push($s, $root); + $tok = strtok($path, DIRECTORY_SEPARATOR); + while ($tok !== false) { + $thisToken = $tok; + if ("." === $thisToken) { + $tok = strtok(DIRECTORY_SEPARATOR); + continue; + } elseif (".." === $thisToken) { + if (count($s) < 2) { + // using '..' in path that is too short + throw new IOException("Cannot resolve path: $orig"); + } else { + array_pop($s); + } + } else { // plain component + array_push($s, $thisToken); + } + $tok = strtok(DIRECTORY_SEPARATOR); + } + + $sb = ""; + for ($i=0,$_i=count($s); $i < $_i; $i++) { + if ($i > 1) { + // not before the filesystem root and not after it, since root + // already contains one + $sb .= DIRECTORY_SEPARATOR; + } + $sb .= (string) $s[$i]; + } + + + $path = (string) $sb; + if ($dosWithDrive === true) { + $path = str_replace('/', '\\', $path); + } + return $path; + } + + /** + * @return boolean Whether contents of two files is the same. + */ + public function contentEquals(PhingFile $file1, PhingFile $file2) { + + if (!($file1->exists() || $file2->exists())) { + return false; + } + + if (!($file1->canRead() || $file2->canRead())) { + return false; + } + + $c1 = file_get_contents($file1->getAbsolutePath()); + $c2 = file_get_contents($file2->getAbsolutePath()); + + return trim($c1) == trim($c2); + } + +} +?> diff --git a/gulliver/thirdparty/phing/util/LogWriter.php b/gulliver/thirdparty/phing/util/LogWriter.php new file mode 100644 index 000000000..304e03a40 --- /dev/null +++ b/gulliver/thirdparty/phing/util/LogWriter.php @@ -0,0 +1,96 @@ +. + */ + + require_once 'phing/system/io/Writer.php'; + require_once 'phing/Task.php'; + + /** + * Extends the Writer class to output messages to Phing's log + * + * @author Michiel Rook + * @version $Id: LogWriter.php 3076 2006-12-18 08:52:12Z fabien $ + * @package phing.util + */ + class LogWriter extends Writer + { + private $task = NULL; + + private $level = NULL; + + /** + * Constructs a new LogWriter object + */ + function __construct(Task $task, $level = PROJECT_MSG_INFO) + { + $this->task = $task; + $this->level = $level; + } + + /** + * @see Writer::write() + */ + function write($buf, $off = null, $len = null) + { + $lines = explode("\n", $buf); + + foreach ($lines as $line) + { + if ($line == "") + { + continue; + } + + $this->task->log($line, $this->level); + } + } + + /** + * @see Writer::reset() + */ + function reset() + { + } + + /** + * @see Writer::close() + */ + function close() + { + } + + /** + * @see Writer::open() + */ + function open() + { + } + + /** + * @see Writer::getResource() + */ + function getResource() + { + return $this->task; + } + } + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/util/PathTokenizer.php b/gulliver/thirdparty/phing/util/PathTokenizer.php new file mode 100644 index 000000000..1e24c98d9 --- /dev/null +++ b/gulliver/thirdparty/phing/util/PathTokenizer.php @@ -0,0 +1,245 @@ +. + */ + + + +include_once 'phing/util/StringHelper.php'; + + + +/** + + * A Path tokenizer takes a path and returns the components that make up + + * that path. + + * + + * The path can use path separators of either ':' or ';' and file separators + + * of either '/' or '\'. + + * + + * @author Hans Lellelid (Phing) + + * @author Conor MacNeill (Ant) + + * @author Jeff Tulley (Ant) + + * @pacakge phing.util + + */ + +class PathTokenizer { + + + + /** + + * A array of tokens, created by preg_split(). + + */ + + private $tokens = array(); + + + + /** + + * A string which stores any path components which have been read ahead + + * due to DOS filesystem compensation. + + * @var string + + */ + + private $lookahead; + + + + /** + + * Flag to indicate whether or not we are running on a platform with a + + * DOS style filesystem + + * @var boolean + + */ + + private $dosStyleFilesystem; + + + + /** + + * Constructs a path tokenizer for the specified path. + + * + + * @param path The path to tokenize. Must not be null. + + */ + + public function __construct($path) { + + // on Windows and Unix, we can ignore delimiters and still have + + // enough information to tokenize correctly. + + $this->tokens = preg_split("/[;:]/", $path, -1, PREG_SPLIT_NO_EMPTY); + + $this->dosStyleFilesystem = ( PATH_SEPARATOR == ';'); + + } + + + + /** + + * Tests if there are more path elements available from this tokenizer's + + * path. If this method returns true, then a subsequent call + + * to nextToken will successfully return a token. + + * + + * @return true if and only if there is at least one token + + * in the string after the current position; false otherwise. + + */ + + public function hasMoreTokens() { + + if ($this->lookahead !== null) { + + return true; + + } + + return !empty($this->tokens); + + } + + + + /** + + * Returns the next path element from this tokenizer. + + * + + * @return the next path element from this tokenizer. + + * + + * @throws Exception if there are no more elements in this tokenizer's path. + + */ + + public function nextToken() { + + + + if ($this->lookahead !== null) { + + $token = $this->lookahead; + + $this->lookahead = null; + + } else { + + $token = trim(array_shift($this->tokens)); + + } + + + + + + if (strlen($token) === 1 && Character::isLetter($token{0}) + + && $this->dosStyleFilesystem + + && !empty($this->tokens)) { + + // we are on a dos style system so this path could be a drive + + // spec. We look at the next token + + $nextToken = trim(array_shift($this->tokens)); + + if (StringHelper::startsWith('\\', $nextToken) || StringHelper::startsWith('/', $nextToken)) { + + // we know we are on a DOS style platform and the next path + + // starts with a slash or backslash, so we know this is a + + // drive spec + + $token .= ':' . $nextToken; + + } else { + + // store the token just read for next time + + $this->lookahead = $nextToken; + + } + + } + + + + return $token; + + } + + + + /** + + * Non StringTokenizer function, that indicates whether the specified path is contained in loaded tokens. + + * We can do this easily because in PHP implimentation we're using arrays. + + * @param string $path path to search for. + + * @return boolean + + */ + + public function contains($path) { + + return in_array($path, $this->tokens, true); + + } + + + +} + + + diff --git a/gulliver/thirdparty/phing/util/SourceFileScanner.php b/gulliver/thirdparty/phing/util/SourceFileScanner.php new file mode 100644 index 000000000..0c0380422 --- /dev/null +++ b/gulliver/thirdparty/phing/util/SourceFileScanner.php @@ -0,0 +1,159 @@ +. + */ + +/** + * Utility class that collects the functionality of the various + * scanDir methods that have been scattered in several tasks before. + * + * The only method returns an array of source files. The array is a + * subset of the files given as a parameter and holds only those that + * are newer than their corresponding target files. + * @package phing.util + */ +class SourceFileScanner { + + /** Instance of FileUtils */ + private $fileUtils; + + /** Task this class is working for -- for logging purposes. */ + private $task; + + /** + * @param task The task we should log messages through + */ + function __construct($task) { + $this->task = $task; + $this->fileUtils = new FileUtils(); + } + + /** + * Restrict the given set of files to those that are newer than + * their corresponding target files. + * + * @param files the original set of files + * @param srcDir all files are relative to this directory + * @param destDir target files live here. if null file names + * returned by the mapper are assumed to be absolute. + * @param FilenameMapper knows how to construct a target file names from + * source file names. + * @param force Boolean that determines if the files should be + * forced to be copied. + */ + function restrict(&$files, $srcDir, $destDir, $mapper, $force = false) { + $now = time(); + $targetList = ""; + + /* + If we're on Windows, we have to munge the time up to 2 secs to + be able to check file modification times. + (Windows has a max resolution of two secs for modification times) + */ + $osname = strtolower(Phing::getProperty('os.name')); + + // indexOf() + $index = ((($res = strpos($osname, 'win')) === false) ? -1 : $res); + if ($index >= 0 ) { + $now += 2000; + } + + $v = array(); + + for ($i=0, $size=count($files); $i < $size; $i++) { + + $targets = $mapper->main($files[$i]); + if (empty($targets)) { + $this->task->log($files[$i]." skipped - don't know how to handle it", PROJECT_MSG_VERBOSE); + continue; + } + + $src = null; + try { + if ($srcDir === null) { + $src = new PhingFile($files[$i]); + } else { + $src = $this->fileUtils->resolveFile($srcDir, $files[$i]); + } + + if ($src->lastModified() > $now) { + $this->task->log("Warning: ".$files[$i]." modified in the future (".$src->lastModified()." > ".$now.")", PROJECT_MSG_WARN); + } + } catch (IOException $ioe) { + $this->task->log("Unable to read file ".$files[$i]." (skipping): " . $ioe->getMessage()); + continue; + } + + $added = false; + $targetList = ""; + + for ($j=0,$_j=count($targets); (!$added && $j < $_j); $j++) { + + $dest = null; + if ($destDir === null) { + $dest = new PhingFile($targets[$j]); + } else { + $dest = $this->fileUtils->resolveFile($destDir, $targets[$j]); + } + + if (!$dest->exists()) { + $this->task->log($files[$i]." added as " . $dest->__toString() . " doesn't exist.", PROJECT_MSG_VERBOSE); + $v[] =$files[$i]; + $added = true; + } elseif ($src->lastModified() > $dest->lastModified()) { + $this->task->log($files[$i]." added as " . $dest->__toString() . " is outdated.", PROJECT_MSG_VERBOSE ); + $v[]=$files[$i]; + $added = true; + } elseif ($force === true) { + $this->task->log($files[$i]." added as " . $dest->__toString() . " is forced to be overwritten.", PROJECT_MSG_VERBOSE ); + $v[]=$files[$i]; + $added = true; + } else { + if (strlen($targetList) > 0) { + $targetList .= ", "; + } + $targetList .= $dest->getAbsolutePath(); + } + } + + if (!$added) { + $this->task->log($files[$i]." omitted as ".$targetList." ".(count($targets) === 1 ? " is " : " are ")."up to date.", PROJECT_MSG_VERBOSE); + } + + } + $result = array(); + $result = $v; + return $result; + } + + /** + * Convenience layer on top of restrict that returns the source + * files as PhingFile objects (containing absolute paths if srcDir is + * absolute). + */ + function restrictAsFiles(&$files, &$srcDir, &$destDir, &$mapper) { + $res = $this->restrict($files, $srcDir, $destDir, $mapper); + $result = array(); + for ($i=0; $i diff --git a/gulliver/thirdparty/phing/util/StringHelper.php b/gulliver/thirdparty/phing/util/StringHelper.php new file mode 100644 index 000000000..5d4bfd7a3 --- /dev/null +++ b/gulliver/thirdparty/phing/util/StringHelper.php @@ -0,0 +1,209 @@ + + * @package phing.system.util + */ +class StringHelper { + + private static $TRUE_VALUES = array("on", "true", "t", "yes"); + private static $FALSE_VALUES = array("off", "false", "f", "no"); + + /** + * Replaces identifier tokens with corresponding text values in passed string. + * + * @params array $strings Array of strings to multiply. (If string is passed, will convert to array) + * @params array $tokens The tokens to search for. + * @params array $replacements The values with which to replace found tokens. + * @return string + */ + public static function multiply($strings, $tokens, $replacements) { + $strings = (array) $strings; + $results = array(); + foreach ($strings as $string) { + $results[] = str_replace($tokens, $replacements, $string); + } + return $results; + } + + /** + * Remove qualification to name. + * E.g. eg.Cat -> Cat + * @param string $qualifiedName + * @param string $separator Character used to separate. + */ + public static function unqualify($qualifiedName, $separator = '.') { + // if false, then will be 0 + $pos = strrpos($qualifiedName, $separator); + if ($pos === false) { + return $qualifiedName; // there is no '.' in the qualifed name + } else { + return substr($qualifiedName, $pos + 1); // start just after '.' + } + } + + /** + * Converts a string to an indexed array of chars + * There's really no reason for this to be used in PHP, since strings + * are all accessible using the $string{0} notation. + * @param string $string + * @return array + * @deprecated + */ + public static function toCharArray($str) { + $ret=array(); + $len=strlen($str); + for ($i=0; $i < $len; $i++) { + $ret[] = $str{$i}; + } + return $ret; + } + + /** + * Get the qualifier part of a qualified name. + * E.g. eg.Cat -> eg + * @return string + */ + public static function qualifier($qualifiedName, $seperator = '.') { + $pos = strrchr($qualifiedName, $seperator); + if ($pos === false) { + return ''; + } else { + return substr($qualifiedName, 0, $pos); + } + } + + /** + * @param array $columns String[] + * @param string $prefix + * @return array String[] + */ + public static function prefix( $columns, $prefix) { + if ($prefix == null) return $columns; + $qualified = array(); + foreach($columns as $key => $column) { + $qualified[$key] = $prefix . $column; + } + return $qualified; + } + + /** + * + * @return string + */ + public static function root($qualifiedName, $separator = '.') { + $loc = strpos($qualifiedName, $separator); + return ($loc === false) ? $qualifiedName : substr($qualifiedName, 0, $loc); + } + + /** + * @return int + */ + public static function hashCode($string) { + return crc32($string); + } + + /** + * @return boolean + */ + public static function booleanValue($s) { + if (is_bool($s)) { + return $s; // it's already boolean (not a string) + } + // otherwise assume it's something like "true" or "t" + $trimmed = strtolower(trim($s)); + return (boolean) in_array($trimmed, self::$TRUE_VALUES); + } + + /** tests if a string is a representative of a boolean */ + public static function isBoolean($s) { + + if (is_bool($s)) { + return true; // it already is boolean + } + + if ($s === "" || $s === null || !is_string($s)) { + return false; // not a valid string for testing + } + + $test = trim(strtolower($s)); + return (boolean) in_array($test, array_merge(self::$FALSE_VALUES, self::$TRUE_VALUES)); + } + + /** + * Creates a key based on any number of passed params. + * @return string + */ + public static function key() { + $args = func_get_args(); + return serialize($args); + } + + /** tests if a string starts with a given string */ + public static function startsWith($check, $string) { + if ($check === "" || $check === $string) { + return true; + } else { + return (strpos($string, $check) === 0) ? true : false; + } + } + + /** tests if a string ends with a given string */ + public static function endsWith($check, $string) { + if ($check === "" || $check === $string) { + return true; + } else { + return (strpos(strrev($string), strrev($check)) === 0) ? true : false; + } + } + + /** + * a natural way of getting a subtring, php's circular string buffer and strange + * return values suck if you want to program strict as of C or friends + */ + public static function substring($string, $startpos, $endpos = -1) { + $len = strlen($string); + $endpos = (int) (($endpos === -1) ? $len-1 : $endpos); + if ($startpos > $len-1 || $startpos < 0) { + trigger_error("substring(), Startindex out of bounds must be 0 $len-1 || $endpos < $startpos) { + trigger_error("substring(), Endindex out of bounds must be $startpos \ No newline at end of file diff --git a/gulliver/thirdparty/phing/util/regexp/PregEngine.php b/gulliver/thirdparty/phing/util/regexp/PregEngine.php new file mode 100644 index 000000000..16c37e506 --- /dev/null +++ b/gulliver/thirdparty/phing/util/regexp/PregEngine.php @@ -0,0 +1,105 @@ +. + */ + +require_once 'phing/util/regexp/RegexpEngine.php'; + +/** + * PREG Regexp Engine. + * Implements a regexp engine using PHP's preg_match(), preg_match_all(), and preg_replace() functions. + * + * @author hans lellelid, hans@velum.net + * @package phing.util.regex + */ +class PregEngine implements RegexpEngine { + + /** + * @var boolean + */ + private $ignoreCase = false; + + /** + * Sets whether or not regex operation is case sensitive. + * @param boolean $bit + * @return void + */ + function setIgnoreCase($bit) { + $this->ignoreCase = (boolean) $bit; + } + + /** + * Gets whether or not regex operation is case sensitive. + * @return boolean + */ + function getIgnoreCase() { + return $this->ignoreCase; + } + + /** + * The pattern needs to be converted into PREG style -- which includes adding expression delims & any flags, etc. + * @param string $pattern + * @return string prepared pattern. + */ + private function preparePattern($pattern) + { + return '/'.$pattern.'/'.($this->ignoreCase ? 'i' : ''); + } + + /** + * Matches pattern against source string and sets the matches array. + * @param string $pattern The regex pattern to match. + * @param string $source The source string. + * @param array $matches The array in which to store matches. + * @return boolean Success of matching operation. + */ + function match($pattern, $source, &$matches) { + return preg_match($this->preparePattern($pattern), $source, $matches); + } + + /** + * Matches all patterns in source string and sets the matches array. + * @param string $pattern The regex pattern to match. + * @param string $source The source string. + * @param array $matches The array in which to store matches. + * @return boolean Success of matching operation. + */ + function matchAll($pattern, $source, &$matches) { + return preg_match_all($this->preparePattern($pattern), $source, $matches); + } + + /** + * Replaces $pattern with $replace in $source string. + * References to \1 group matches will be replaced with more preg-friendly + * $1. + * @param string $pattern The regex pattern to match. + * @param string $replace The string with which to replace matches. + * @param string $source The source string. + * @return string The replaced source string. + */ + function replace($pattern, $replace, $source) { + // convert \1 -> $1, because we want to use the more generic \1 in the XML + // but PREG prefers $1 syntax. + $replace = preg_replace('/[^\\\]\\\(\d+)/', '$1', $replace); + return preg_replace($this->preparePattern($pattern), $replace, $source); + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/util/regexp/Regexp.php b/gulliver/thirdparty/phing/util/regexp/Regexp.php new file mode 100644 index 000000000..45068ec3f --- /dev/null +++ b/gulliver/thirdparty/phing/util/regexp/Regexp.php @@ -0,0 +1,168 @@ +. + */ + +/** + * A factory class for regex functions. + * @author Hans Lellelid + * @package phing.util.regexp + * @version $Revision: 1.5 $ + */ +class Regexp { + + /** + * Matching groups found. + * @var array + */ + private $groups = array(); + + /** + * Pattern to match. + * @var string + */ + private $pattern; + + /** + * Replacement pattern. + * @var string + */ + private $replace; + + /** + * The regex engine -- e.g. 'preg' or 'ereg'; + * @var RegexpEngine + */ + private $engine; + + /** + * Constructor sets the regex engine to use (preg by default). + * @param string $_engineType The regex engine to use. + */ + function __construct($engineType='preg') { + if ($engineType == 'preg') { + include_once 'phing/util/regexp/PregEngine.php'; + $this->engine = new PregEngine(); + } elseif ($engineType == 'ereg') { + include_once 'phing/util/regexp/EregEngine.php'; + $this->engine = new EregEngine(); + } else { + throw new BuildException("Invalid engine type for Regexp: " . $engineType); + } + } + + /** + * Sets pattern to use for matching. + * @param string $pat The pattern to match on. + * @return void + */ + public function setPattern($pat) { + $this->pattern = (string) $pat; + } + + + /** + * Gets pattern to use for matching. + * @return string The pattern to match on. + */ + public function getPattern() { + return $this->pattern; + } + + /** + * Sets replacement string. + * @param string $rep The pattern to replace matches with. + * @return void + */ + public function setReplace($rep) { + $this->replace = (string) $rep; + } + + /** + * Gets replacement string. + * @return string The pattern to replace matches with. + * @return void + */ + public function getReplace() { + return $this->replace; + } + + /** + * Performs match of specified pattern against $subject. + * @param string $subject The subject, on which to perform matches. + * @return boolean Whether or not pattern matches subject string passed. + */ + public function matches($subject) { + if($this->pattern === null) { + throw new Exception("No pattern specified for regexp match()."); + } + return $this->engine->match($this->pattern, $subject, $this->groups); + } + + /** + * Performs replacement of specified pattern and replacement strings. + * @param string $subject Text on which to perform replacement. + * @return string subject after replacement has been performed. + */ + public function replace($subject) { + if ($this->pattern === null || $this->replace === null) { + throw new Exception("Missing pattern or replacement string regexp replace()."); + } + return $this->engine->replace($this->pattern, $this->replace, $subject); + } + + /** + * Get array of matched groups. + * @return array Matched groups + */ + function getGroups() { + return $this->groups; + } + + /** + * Get specific matched group. + * @param integer $idx + * @return string specified group or NULL if group is not set. + */ + function getGroup($idx) { + if (!isset($this->groups[$idx])) { + return null; + } + return $this->groups[$idx]; + } + + /** + * Sets whether the regexp matching is case insensitive. + * (default is false -- i.e. case sensisitive) + * @param boolean $bit + */ + function setIgnoreCase($bit) { + $this->engine->setIgnoreCase($bit); + } + + /** + * Gets whether the regexp matching is case insensitive. + * @return boolean + */ + function getIgnoreCase() { + return $this->engine->getIgnoreCase(); + } +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phing/util/regexp/RegexpEngine.php b/gulliver/thirdparty/phing/util/regexp/RegexpEngine.php new file mode 100644 index 000000000..d151206ed --- /dev/null +++ b/gulliver/thirdparty/phing/util/regexp/RegexpEngine.php @@ -0,0 +1,74 @@ +. + */ + +/** + * Contains some shared attributes and methods -- and some abstract methods with + * engine-specific implementations that sub-classes must override. + * + * @author Hans Lellelid + * @package phing.util.regex + * @version $Revision: 1.4 $ + */ +interface RegexpEngine { + + /** + * Sets whether or not regex operation should ingore case. + * @param boolean $bit + * @return void + */ + public function setIgnoreCase($bit); + + /** + * Returns status of ignore case flag. + * @return boolean + */ + public function getIgnoreCase(); + + /** + * Matches pattern against source string and sets the matches array. + * @param string $pattern The regex pattern to match. + * @param string $source The source string. + * @param array $matches The array in which to store matches. + * @return boolean Success of matching operation. + */ + function match($pattern, $source, &$matches); + + /** + * Matches all patterns in source string and sets the matches array. + * @param string $pattern The regex pattern to match. + * @param string $source The source string. + * @param array $matches The array in which to store matches. + * @return boolean Success of matching operation. + */ + function matchAll($pattern, $source, &$matches); + + /** + * Replaces $pattern with $replace in $source string. + * @param string $pattern The regex pattern to match. + * @param string $replace The string with which to replace matches. + * @param string $source The source string. + * @return string The replaced source string. + */ + function replace($pattern, $replace, $source); + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/class.phpmailer.php b/gulliver/thirdparty/phpmailer/class.phpmailer.php new file mode 100644 index 000000000..ecc7ae99b --- /dev/null +++ b/gulliver/thirdparty/phpmailer/class.phpmailer.php @@ -0,0 +1,1508 @@ +ContentType = "text/html"; + else + $this->ContentType = "text/plain"; + } + + /** + * Sets Mailer to send message using SMTP. + * @return void + */ + function IsSMTP() { + $this->Mailer = "smtp"; + } + + /** + * Sets Mailer to send message using PHP mail() function. + * @return void + */ + function IsMail() { + $this->Mailer = "mail"; + } + + /** + * Sets Mailer to send message using the $Sendmail program. + * @return void + */ + function IsSendmail() { + $this->Mailer = "sendmail"; + } + + /** + * Sets Mailer to send message using the qmail MTA. + * @return void + */ + function IsQmail() { + $this->Sendmail = "/var/qmail/bin/sendmail"; + $this->Mailer = "sendmail"; + } + + + ///////////////////////////////////////////////// + // RECIPIENT METHODS + ///////////////////////////////////////////////// + + /** + * Adds a "To" address. + * @param string $address + * @param string $name + * @return void + */ + function AddAddress($address, $name = "") { + $cur = count($this->to); + $this->to[$cur][0] = trim($address); + $this->to[$cur][1] = $name; + } + + /** + * Adds a "Cc" address. Note: this function works + * with the SMTP mailer on win32, not with the "mail" + * mailer. + * @param string $address + * @param string $name + * @return void + */ + function AddCC($address, $name = "") { + $cur = count($this->cc); + $this->cc[$cur][0] = trim($address); + $this->cc[$cur][1] = $name; + } + + /** + * Adds a "Bcc" address. Note: this function works + * with the SMTP mailer on win32, not with the "mail" + * mailer. + * @param string $address + * @param string $name + * @return void + */ + function AddBCC($address, $name = "") { + $cur = count($this->bcc); + $this->bcc[$cur][0] = trim($address); + $this->bcc[$cur][1] = $name; + } + + /** + * Adds a "Reply-to" address. + * @param string $address + * @param string $name + * @return void + */ + function AddReplyTo($address, $name = "") { + $cur = count($this->ReplyTo); + $this->ReplyTo[$cur][0] = trim($address); + $this->ReplyTo[$cur][1] = $name; + } + + + ///////////////////////////////////////////////// + // MAIL SENDING METHODS + ///////////////////////////////////////////////// + + /** + * Creates message and assigns Mailer. If the message is + * not sent successfully then it returns false. Use the ErrorInfo + * variable to view description of the error. + * @return bool + */ + function Send() { + $header = ""; + $body = ""; + $result = true; + + if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) + { + $this->SetError($this->Lang("provide_address")); + return false; + } + + // Set whether the message is multipart/alternative + if(!empty($this->AltBody)) + $this->ContentType = "multipart/alternative"; + + $this->error_count = 0; // reset errors + $this->SetMessageType(); + $header .= $this->CreateHeader(); + $body = $this->CreateBody(); + + if($body == "") { return false; } + + // Choose the mailer + switch($this->Mailer) + { + case "sendmail": + $result = $this->SendmailSend($header, $body); + break; + case "mail": + $result = $this->MailSend($header, $body); + break; + case "smtp": + $result = $this->SmtpSend($header, $body); + break; + default: + $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); + $result = false; + break; + } + + return $result; + } + + /** + * Sends mail using the $Sendmail program. + * @access private + * @return bool + */ + function SendmailSend($header, $body) { + if ($this->Sender != "") + $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender); + else + $sendmail = sprintf("%s -oi -t", $this->Sendmail); + + if(!@$mail = popen($sendmail, "w")) + { + $this->SetError($this->Lang("execute") . $this->Sendmail); + return false; + } + + fputs($mail, $header); + fputs($mail, $body); + + $result = pclose($mail) >> 8 & 0xFF; + if($result != 0) + { + $this->SetError($this->Lang("execute") . $this->Sendmail); + return false; + } + + return true; + } + + /** + * Sends mail using the PHP mail() function. + * @access private + * @return bool + */ + function MailSend($header, $body) { + $to = ""; + for($i = 0; $i < count($this->to); $i++) + { + if($i != 0) { $to .= ", "; } + $to .= $this->to[$i][0]; + } + + if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) + { + $old_from = ini_get("sendmail_from"); + ini_set("sendmail_from", $this->Sender); + $params = sprintf("-oi -f %s", $this->Sender); + $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, + $header, $params); + } + else + $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); + + if (isset($old_from)) + ini_set("sendmail_from", $old_from); + + if(!$rt) + { + $this->SetError($this->Lang("instantiate")); + return false; + } + + return true; + } + + /** + * Sends mail via SMTP using PhpSMTP (Author: + * Chris Ryan). Returns bool. Returns false if there is a + * bad MAIL FROM, RCPT, or DATA input. + * @access private + * @return bool + */ + function SmtpSend($header, $body) { + include_once($this->PluginDir . "class.smtp.php"); + $error = ""; + $bad_rcpt = array(); + + if(!$this->SmtpConnect()) + return false; + + $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; + if(!$this->smtp->Mail($smtp_from)) + { + $error = $this->Lang("from_failed") . $smtp_from; + $this->SetError($error); + $this->smtp->Reset(); + return false; + } + + // Attempt to send attach all recipients + for($i = 0; $i < count($this->to); $i++) + { + if(!$this->smtp->Recipient($this->to[$i][0])) + $bad_rcpt[] = $this->to[$i][0]; + } + for($i = 0; $i < count($this->cc); $i++) + { + if(!$this->smtp->Recipient($this->cc[$i][0])) + $bad_rcpt[] = $this->cc[$i][0]; + } + for($i = 0; $i < count($this->bcc); $i++) + { + if(!$this->smtp->Recipient($this->bcc[$i][0])) + $bad_rcpt[] = $this->bcc[$i][0]; + } + + // disable this error, to avoid error in Sending empty recipients + /* + if(count($bad_rcpt) > 0) // Create error message + { + for($i = 0; $i < count($bad_rcpt); $i++) + { + if($i != 0) { $error .= ", "; } + $error .= $bad_rcpt[$i]; + } + $error = $this->Lang("recipients_failed") . $error; + $this->SetError($error); + $this->smtp->Reset(); + return false; + } + */ + if(!$this->smtp->Data($header . $body)) + { + $this->SetError($this->Lang("data_not_accepted")); + $this->smtp->Reset(); + return false; + } + if($this->SMTPKeepAlive == true) + $this->smtp->Reset(); + else + $this->SmtpClose(); + + return true; + } + + /** + * Initiates a connection to an SMTP server. Returns false if the + * operation failed. + * @access private + * @return bool + */ + function SmtpConnect() { + if($this->smtp == NULL) { $this->smtp = new SMTP(); } + + $this->smtp->do_debug = $this->SMTPDebug; + $hosts = explode(";", $this->Host); + $index = 0; + $connection = ($this->smtp->Connected()); + + // Retry while there is no connection + while($index < count($hosts) && $connection == false) + { + if(strstr($hosts[$index], ":")) + { + $hostA = explode(':', $hosts[$index]); + if (is_numeric(end($hostA))) + $port = array_pop($hostA); + else + $port = $this->Port; + $host = implode(':', $hostA); + } + else + { + $host = $hosts[$index]; + $port = $this->Port; + } + + if($this->smtp->Connect($host, $port, $this->Timeout)) + { + if ($this->Helo != '') + $this->smtp->Hello($this->Helo); + else + $this->smtp->Hello($this->ServerHostname()); + + if($this->SMTPAuth) + { + if(!$this->smtp->Authenticate($this->Username, + $this->Password)) + { + $this->SetError($this->Lang("authenticate")); + $this->smtp->Reset(); + $connection = false; + } + } + $connection = true; + } + $index++; + } + if(!$connection) + $this->SetError($this->Lang("connect_host")); + + return $connection; + } + + /** + * Closes the active SMTP session if one exists. + * @return void + */ + function SmtpClose() { + if($this->smtp != NULL) + { + if($this->smtp->Connected()) + { + $this->smtp->Quit(); + $this->smtp->Close(); + } + } + } + + /** + * Sets the language for all class error messages. Returns false + * if it cannot load the language file. The default language type + * is English. + * @param string $lang_type Type of language (e.g. Portuguese: "br") + * @param string $lang_path Path to the language file directory + * @access public + * @return bool + */ + function SetLanguage($lang_type, $lang_path = "/home/workflow/engine/classes/language/") { + if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) + include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); + else if(file_exists($lang_path.'phpmailer.lang-en.php')) + include($lang_path.'phpmailer.lang-en.php'); + else + { + $this->SetError("Could not load language file"); + return false; + } + $this->language = $PHPMAILER_LANG; + + return true; + } + + ///////////////////////////////////////////////// + // MESSAGE CREATION METHODS + ///////////////////////////////////////////////// + + /** + * Creates recipient headers. + * @access private + * @return string + */ + function AddrAppend($type, $addr) { + $addr_str = $type . ": "; + $addr_str .= $this->AddrFormat($addr[0]); + if(count($addr) > 1) + { + for($i = 1; $i < count($addr); $i++) + $addr_str .= ", " . $this->AddrFormat($addr[$i]); + } + $addr_str .= $this->LE; + + return $addr_str; + } + + /** + * Formats an address correctly. + * @access private + * @return string + */ + function AddrFormat($addr) { + if(empty($addr[1])) + $formatted = $addr[0]; + else + { + $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . + $addr[0] . ">"; + } + + return $formatted; + } + + /** + * Wraps message for use with mailers that do not + * automatically perform wrapping and for quoted-printable. + * Original written by philippe. + * @access private + * @return string + */ + function WrapText($message, $length, $qp_mode = false) { + $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; + + $message = $this->FixEOL($message); + if (substr($message, -1) == $this->LE) + $message = substr($message, 0, -1); + + $line = explode($this->LE, $message); + $message = ""; + for ($i=0 ;$i < count($line); $i++) + { + $line_part = explode(" ", $line[$i]); + $buf = ""; + for ($e = 0; $e $length)) + { + $space_left = $length - strlen($buf) - 1; + if ($e != 0) + { + if ($space_left > 20) + { + $len = $space_left; + if (substr($word, $len - 1, 1) == "=") + $len--; + elseif (substr($word, $len - 2, 1) == "=") + $len -= 2; + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= " " . $part; + $message .= $buf . sprintf("=%s", $this->LE); + } + else + { + $message .= $buf . $soft_break; + } + $buf = ""; + } + while (strlen($word) > 0) + { + $len = $length; + if (substr($word, $len - 1, 1) == "=") + $len--; + elseif (substr($word, $len - 2, 1) == "=") + $len -= 2; + $part = substr($word, 0, $len); + $word = substr($word, $len); + + if (strlen($word) > 0) + $message .= $part . sprintf("=%s", $this->LE); + else + $buf = $part; + } + } + else + { + $buf_o = $buf; + $buf .= ($e == 0) ? $word : (" " . $word); + + if (strlen($buf) > $length and $buf_o != "") + { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + } + $message .= $buf . $this->LE; + } + + return $message; + } + + /** + * Set the body wrapping. + * @access private + * @return void + */ + function SetWordWrap() { + if($this->WordWrap < 1) + return; + + switch($this->message_type) + { + case "alt": + // fall through + case "alt_attachments": + $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->WrapText($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assembles message header. + * @access private + * @return string + */ + function CreateHeader() { + $result = ""; + + // Set the boundaries + $uniq_id = md5(uniqid(time())); + $this->boundary[1] = "b1_" . $uniq_id; + $this->boundary[2] = "b2_" . $uniq_id; + + $result .= $this->HeaderLine("Date", $this->RFCDate()); + if($this->Sender == "") + $result .= $this->HeaderLine("Return-Path", trim($this->From)); + else + $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); + + // To be created automatically by mail() + if($this->Mailer != "mail") + { + if(count($this->to) > 0) + $result .= $this->AddrAppend("To", $this->to); + else if (count($this->cc) == 0) + $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); + if(count($this->cc) > 0) + $result .= $this->AddrAppend("Cc", $this->cc); + } + + $from = array(); + $from[0][0] = trim($this->From); + $from[0][1] = $this->FromName; + $result .= $this->AddrAppend("From", $from); + + // sendmail and mail() extract Bcc from the header before sending + if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) + $result .= $this->AddrAppend("Bcc", $this->bcc); + + if(count($this->ReplyTo) > 0) + $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); + + // mail() sets the subject itself + if($this->Mailer != "mail") + $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); + + $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); + $result .= $this->HeaderLine("X-Priority", $this->Priority); + $result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]"); + + if($this->ConfirmReadingTo != "") + { + $result .= $this->HeaderLine("Disposition-Notification-To", + "<" . trim($this->ConfirmReadingTo) . ">"); + } + + // Add custom headers + for($index = 0; $index < count($this->CustomHeader); $index++) + { + $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), + $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); + } + $result .= $this->HeaderLine("MIME-Version", "1.0"); + + switch($this->message_type) + { + case "plain": + $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); + $result .= sprintf("Content-Type: %s; charset=\"%s\"", + $this->ContentType, $this->CharSet); + break; + case "attachments": + // fall through + case "alt_attachments": + if($this->InlineImageExists()) + { + $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", + "multipart/related", $this->LE, $this->LE, + $this->boundary[1], $this->LE); + } + else + { + $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); + } + break; + case "alt": + $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + } + + if($this->Mailer != "mail") + $result .= $this->LE.$this->LE; + + return $result; + } + + /** + * Assembles the message body. Returns an empty string on failure. + * @access private + * @return string + */ + function CreateBody() { + $result = ""; + + $this->SetWordWrap(); + + switch($this->message_type) + { + case "alt": + $result .= $this->GetBoundary($this->boundary[1], "", + "text/plain", ""); + $result .= $this->EncodeString($this->AltBody, $this->Encoding); + $result .= $this->LE.$this->LE; + $result .= $this->GetBoundary($this->boundary[1], "", + "text/html", ""); + + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE.$this->LE; + + $result .= $this->EndBoundary($this->boundary[1]); + break; + case "plain": + $result .= $this->EncodeString($this->Body, $this->Encoding); + break; + case "attachments": + $result .= $this->GetBoundary($this->boundary[1], "", "", ""); + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE; + + $result .= $this->AttachAll(); + break; + case "alt_attachments": + $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); + $result .= sprintf("Content-Type: %s;%s" . + "\tboundary=\"%s\"%s", + "multipart/alternative", $this->LE, + $this->boundary[2], $this->LE.$this->LE); + + // Create text body + $result .= $this->GetBoundary($this->boundary[2], "", + "text/plain", "") . $this->LE; + + $result .= $this->EncodeString($this->AltBody, $this->Encoding); + $result .= $this->LE.$this->LE; + + // Create the HTML body + $result .= $this->GetBoundary($this->boundary[2], "", + "text/html", "") . $this->LE; + + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE.$this->LE; + + $result .= $this->EndBoundary($this->boundary[2]); + + $result .= $this->AttachAll(); + break; + } + if($this->IsError()) + $result = ""; + + return $result; + } + + /** + * Returns the start of a message boundary. + * @access private + */ + function GetBoundary($boundary, $charSet, $contentType, $encoding) { + $result = ""; + if($charSet == "") { $charSet = $this->CharSet; } + if($contentType == "") { $contentType = $this->ContentType; } + if($encoding == "") { $encoding = $this->Encoding; } + + $result .= $this->TextLine("--" . $boundary); + $result .= sprintf("Content-Type: %s; charset = \"%s\"", + $contentType, $charSet); + $result .= $this->LE; + $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); + $result .= $this->LE; + + return $result; + } + + /** + * Returns the end of a message boundary. + * @access private + */ + function EndBoundary($boundary) { + return $this->LE . "--" . $boundary . "--" . $this->LE; + } + + /** + * Sets the message type. + * @access private + * @return void + */ + function SetMessageType() { + if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) + $this->message_type = "plain"; + else + { + if(count($this->attachment) > 0) + $this->message_type = "attachments"; + if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) + $this->message_type = "alt"; + if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) + $this->message_type = "alt_attachments"; + } + } + + /** + * Returns a formatted header line. + * @access private + * @return string + */ + function HeaderLine($name, $value) { + return $name . ": " . $value . $this->LE; + } + + /** + * Returns a formatted mail line. + * @access private + * @return string + */ + function TextLine($value) { + return $value . $this->LE; + } + + ///////////////////////////////////////////////// + // ATTACHMENT METHODS + ///////////////////////////////////////////////// + + /** + * Adds an attachment from a path on the filesystem. + * Returns false if the file could not be found + * or accessed. + * @param string $path Path to the attachment. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return bool + */ + function AddAttachment($path, $name = "", $encoding = "base64", + $type = "application/octet-stream") { + if(!@is_file($path)) + { + $this->SetError($this->Lang("file_access") . $path); + return false; + } + + $filename = basename($path); + if($name == "") + $name = $filename; + + $cur = count($this->attachment); + $this->attachment[$cur][0] = $path; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $name; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = false; // isStringAttachment + $this->attachment[$cur][6] = "attachment"; + $this->attachment[$cur][7] = 0; + + return true; + } + + /** + * Attaches all fs, string, and binary attachments to the message. + * Returns an empty string on failure. + * @access private + * @return string + */ + function AttachAll() { + // Return text of body + $mime = array(); + + // Add all attachments + for($i = 0; $i < count($this->attachment); $i++) + { + // Check for string attachment + $bString = $this->attachment[$i][5]; + if ($bString) + $string = $this->attachment[$i][0]; + else + $path = $this->attachment[$i][0]; + + $filename = $this->attachment[$i][1]; + $name = $this->attachment[$i][2]; + $encoding = $this->attachment[$i][3]; + $type = $this->attachment[$i][4]; + $disposition = $this->attachment[$i][6]; + $cid = $this->attachment[$i][7]; + + $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); + $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); + $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); + + if($disposition == "inline") + $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); + + $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", + $disposition, $name, $this->LE.$this->LE); + + // Encode as string attachment + if($bString) + { + $mime[] = $this->EncodeString($string, $encoding); + if($this->IsError()) { return ""; } + $mime[] = $this->LE.$this->LE; + } + else + { + $mime[] = $this->EncodeFile($path, $encoding); + if($this->IsError()) { return ""; } + $mime[] = $this->LE.$this->LE; + } + } + + $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); + + return join("", $mime); + } + + /** + * Encodes attachment in requested format. Returns an + * empty string on failure. + * @access private + * @return string + */ + function EncodeFile ($path, $encoding = "base64") { + if(!@$fd = fopen($path, "rb")) + { + $this->SetError($this->Lang("file_open") . $path); + return ""; + } + $magic_quotes = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $file_buffer = fread($fd, filesize($path)); + $file_buffer = $this->EncodeString($file_buffer, $encoding); + fclose($fd); + set_magic_quotes_runtime($magic_quotes); + + return $file_buffer; + } + + /** + * Encodes string to requested format. Returns an + * empty string on failure. + * @access private + * @return string + */ + function EncodeString ($str, $encoding = "base64") { + $encoded = ""; + switch(strtolower($encoding)) { + case "base64": + // chunk_split is found in PHP >= 3.0.6 + $encoded = chunk_split(base64_encode($str), 76, $this->LE); + break; + case "7bit": + case "8bit": + $encoded = $this->FixEOL($str); + if (substr($encoded, -(strlen($this->LE))) != $this->LE) + $encoded .= $this->LE; + break; + case "binary": + $encoded = $str; + break; + case "quoted-printable": + $encoded = $this->EncodeQP($str); + break; + default: + $this->SetError($this->Lang("encoding") . $encoding); + break; + } + return $encoded; + } + + /** + * Encode a header string to best of Q, B, quoted or none. + * @access private + * @return string + */ + function EncodeHeader ($str, $position = 'text') { + $x = 0; + + switch (strtolower($position)) { + case 'phrase': + if (!preg_match('/[\200-\377]/', $str)) { + // Can't use addslashes as we don't know what value has magic_quotes_sybase. + $encoded = addcslashes($str, "\0..\37\177\\\""); + + if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) + return ($encoded); + else + return ("\"$encoded\""); + } + $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); + break; + case 'comment': + $x = preg_match_all('/[()"]/', $str, $matches); + // Fall-through + case 'text': + default: + $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); + break; + } + + if ($x == 0) + return ($str); + + $maxlen = 75 - 7 - strlen($this->CharSet); + // Try to select the encoding which should produce the shortest output + if (strlen($str)/3 < $x) { + $encoding = 'B'; + $encoded = base64_encode($str); + $maxlen -= $maxlen % 4; + $encoded = trim(chunk_split($encoded, $maxlen, "\n")); + } else { + $encoding = 'Q'; + $encoded = $this->EncodeQ($str, $position); + $encoded = $this->WrapText($encoded, $maxlen, true); + $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); + } + + $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); + $encoded = trim(str_replace("\n", $this->LE, $encoded)); + + return $encoded; + } + + /** + * Encode string to quoted-printable. + * @access private + * @return string + */ + function EncodeQP ($str) { + $encoded = $this->FixEOL($str); + if (substr($encoded, -(strlen($this->LE))) != $this->LE) + $encoded .= $this->LE; + + // Replace every high ascii, control and = characters + $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', + "'='.sprintf('%02X', ord('\\1'))", $encoded); + // Replace every spaces and tabs when it's the last character on a line + $encoded = preg_replace("/([\011\040])".$this->LE."/e", + "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); + + // Maximum line length of 76 characters before CRLF (74 + space + '=') + $encoded = $this->WrapText($encoded, 74, true); + + return $encoded; + } + + /** + * Encode string to q encoding. + * @access private + * @return string + */ + function EncodeQ ($str, $position = "text") { + // There should not be any EOL in the string + $encoded = preg_replace("[\r\n]", "", $str); + + switch (strtolower($position)) { + case "phrase": + $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + break; + case "comment": + $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + case "text": + default: + // Replace every high ascii, control =, ? and _ characters + $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', + "'='.sprintf('%02X', ord('\\1'))", $encoded); + break; + } + + // Replace every spaces to _ (more readable than =20) + $encoded = str_replace(" ", "_", $encoded); + + return $encoded; + } + + /** + * Adds a string or binary attachment (non-filesystem) to the list. + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * @param string $string String attachment data. + * @param string $filename Name of the attachment. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return void + */ + function AddStringAttachment($string, $filename, $encoding = "base64", + $type = "application/octet-stream") { + // Append to $attachment array + $cur = count($this->attachment); + $this->attachment[$cur][0] = $string; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $filename; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = true; // isString + $this->attachment[$cur][6] = "attachment"; + $this->attachment[$cur][7] = 0; + } + + /** + * Adds an embedded attachment. This can include images, sounds, and + * just about any other document. Make sure to set the $type to an + * image type. For JPEG images use "image/jpeg" and for GIF images + * use "image/gif". + * @param string $path Path to the attachment. + * @param string $cid Content ID of the attachment. Use this to identify + * the Id for accessing the image in an HTML form. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @return bool + */ + function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", + $type = "application/octet-stream") { + + if(!@is_file($path)) + { + $this->SetError($this->Lang("file_access") . $path); + return false; + } + + $filename = basename($path); + if($name == "") + $name = $filename; + + // Append to $attachment array + $cur = count($this->attachment); + $this->attachment[$cur][0] = $path; + $this->attachment[$cur][1] = $filename; + $this->attachment[$cur][2] = $name; + $this->attachment[$cur][3] = $encoding; + $this->attachment[$cur][4] = $type; + $this->attachment[$cur][5] = false; // isStringAttachment + $this->attachment[$cur][6] = "inline"; + $this->attachment[$cur][7] = $cid; + + return true; + } + + /** + * Returns true if an inline attachment is present. + * @access private + * @return bool + */ + function InlineImageExists() { + $result = false; + for($i = 0; $i < count($this->attachment); $i++) + { + if($this->attachment[$i][6] == "inline") + { + $result = true; + break; + } + } + + return $result; + } + + ///////////////////////////////////////////////// + // MESSAGE RESET METHODS + ///////////////////////////////////////////////// + + /** + * Clears all recipients assigned in the TO array. Returns void. + * @return void + */ + function ClearAddresses() { + $this->to = array(); + } + + /** + * Clears all recipients assigned in the CC array. Returns void. + * @return void + */ + function ClearCCs() { + $this->cc = array(); + } + + /** + * Clears all recipients assigned in the BCC array. Returns void. + * @return void + */ + function ClearBCCs() { + $this->bcc = array(); + } + + /** + * Clears all recipients assigned in the ReplyTo array. Returns void. + * @return void + */ + function ClearReplyTos() { + $this->ReplyTo = array(); + } + + /** + * Clears all recipients assigned in the TO, CC and BCC + * array. Returns void. + * @return void + */ + function ClearAllRecipients() { + $this->to = array(); + $this->cc = array(); + $this->bcc = array(); + } + + /** + * Clears all previously set filesystem, string, and binary + * attachments. Returns void. + * @return void + */ + function ClearAttachments() { + $this->attachment = array(); + } + + /** + * Clears all custom headers. Returns void. + * @return void + */ + function ClearCustomHeaders() { + $this->CustomHeader = array(); + } + + + ///////////////////////////////////////////////// + // MISCELLANEOUS METHODS + ///////////////////////////////////////////////// + + /** + * Adds the error message to the error container. + * Returns void. + * @access private + * @return void + */ + function SetError($msg) { + $this->error_count++; + $this->ErrorInfo = $msg; + } + + /** + * Returns the proper RFC 822 formatted date. + * @access private + * @return string + */ + function RFCDate() { + $tz = date("Z"); + $tzs = ($tz < 0) ? "-" : "+"; + $tz = abs($tz); + $tz = ($tz/3600)*100 + ($tz%3600)/60; + $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); + + return $result; + } + + /** + * Returns the appropriate server variable. Should work with both + * PHP 4.1.0+ as well as older versions. Returns an empty string + * if nothing is found. + * @access private + * @return mixed + */ + function ServerVar($varName) { + global $HTTP_SERVER_VARS; + global $HTTP_ENV_VARS; + + if(!isset($_SERVER)) + { + $_SERVER = $HTTP_SERVER_VARS; + if(!isset($_SERVER["REMOTE_ADDR"])) + $_SERVER = $HTTP_ENV_VARS; // must be Apache + } + + if(isset($_SERVER[$varName])) + return $_SERVER[$varName]; + else + return ""; + } + + /** + * Returns the server hostname or 'localhost.localdomain' if unknown. + * @access private + * @return string + */ + function ServerHostname() { + if ($this->Hostname != "") + $result = $this->Hostname; + elseif ($this->ServerVar('SERVER_NAME') != "") + $result = $this->ServerVar('SERVER_NAME'); + else + $result = "localhost.localdomain"; + + return $result; + } + + /** + * Returns a message in the appropriate language. + * @access private + * @return string + */ + function Lang($key) { + if(count($this->language) < 1) + $this->SetLanguage("en"); // set the default language + + if(isset($this->language[$key])) + return $this->language[$key]; + else + return "Language string failed to load: " . $key; + } + + /** + * Returns true if an error occurred. + * @return bool + */ + function IsError() { + return ($this->error_count > 0); + } + + /** + * Changes every end of line from CR or LF to CRLF. + * @access private + * @return string + */ + function FixEOL($str) { + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + $str = str_replace("\n", $this->LE, $str); + return $str; + } + + /** + * Adds a custom header. + * @return void + */ + function AddCustomHeader($custom_header) { + $this->CustomHeader[] = explode(":", $custom_header, 2); + } +} + +?> diff --git a/gulliver/thirdparty/phpmailer/class.smtp.php b/gulliver/thirdparty/phpmailer/class.smtp.php new file mode 100644 index 000000000..ae903ca34 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/class.smtp.php @@ -0,0 +1,1045 @@ +smtp_conn = 0; + $this->error = null; + $this->helo_rply = null; + + $this->do_debug = 0; + } + + /************************************************************* + * CONNECTION FUNCTIONS * + ***********************************************************/ + + /** + * Connect to the server specified on the port specified. + * If the port is not specified use the default SMTP_PORT. + * If tval is specified then a connection will try and be + * established with the server for that number of seconds. + * If tval is not specified the default is 30 seconds to + * try on the connection. + * + * SMTP CODE SUCCESS: 220 + * SMTP CODE FAILURE: 421 + * @access public + * @return bool + */ + function Connect($host,$port=0,$tval=30) { + # set the error val to null so there is no confusion + $this->error = null; + + # make sure we are __not__ connected + if($this->connected()) { + # ok we are connected! what should we do? + # for now we will just give an error saying we + # are already connected + $this->error = + array("error" => "Already connected to a server"); + return false; + } + + if(empty($port)) { + $port = $this->SMTP_PORT; + } + + #connect to the smtp server + $this->smtp_conn = @fsockopen($host, # the host of the server + $port, # the port to use + $errno, # error number if any + $errstr, # error message if any + $tval); # give up after ? secs + # verify we connected properly + if(empty($this->smtp_conn)) { + $this->error = array("error" => "Failed to connect to server", + "errno" => $errno, + "errstr" => $errstr); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": $errstr ($errno)" . $this->CRLF; + } + return false; + } + + # sometimes the SMTP server takes a little longer to respond + # so we will give it a longer timeout for the first read + // Windows still does not have support for this timeout function + if(substr(PHP_OS, 0, 3) != "WIN") + socket_set_timeout($this->smtp_conn, $tval, 0); + + # get any announcement stuff + $announce = $this->get_lines(); + + # set the timeout of any socket functions at 1/10 of a second + //if(function_exists("socket_set_timeout")) + // socket_set_timeout($this->smtp_conn, 0, 100000); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; + } + + return true; + } + + /** + * Performs SMTP authentication. Must be run after running the + * Hello() method. Returns true if successfully authenticated. + * @access public + * @return bool + */ + function Authenticate($username, $password) { + // Start authentication + @fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + // Send encoded username + fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "Username not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + // Send encoded password + fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Password not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return true; + } + + /** + * Returns true if connected to a server otherwise false + * @access private + * @return bool + */ + function Connected() { + if(!empty($this->smtp_conn)) { + $sock_status = socket_get_status($this->smtp_conn); + if($sock_status["eof"]) { + # hmm this is an odd situation... the socket is + # valid but we aren't connected anymore + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE:" . $this->CRLF . + "EOF caught while checking if connected"; + } + $this->Close(); + return false; + } + return true; # everything looks good + } + return false; + } + + /** + * Closes the socket and cleans up the state of the class. + * It is not considered good to use this function without + * first trying to use QUIT. + * @access public + * @return void + */ + function Close() { + $this->error = null; # so there is no confusion + $this->helo_rply = null; + if(!empty($this->smtp_conn)) { + # close the connection and cleanup + fclose($this->smtp_conn); + $this->smtp_conn = 0; + } + } + + + /*************************************************************** + * SMTP COMMANDS * + *************************************************************/ + + /** + * Issues a data command and sends the msg_data to the server + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a with the message headers + * and the message body being seperated by and additional . + * + * Implements rfc 821: DATA + * + * SMTP CODE INTERMEDIATE: 354 + * [data] + * . + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 552,554,451,452 + * SMTP CODE FAILURE: 451,554 + * SMTP CODE ERROR : 500,501,503,421 + * @access public + * @return bool + */ + function Data($msg_data) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Data() without being connected"); + return false; + } + + fputs($this->smtp_conn,"DATA" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 354) { + $this->error = + array("error" => "DATA command not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + # the server is ready to accept data! + # according to rfc 821 we should not send more than 1000 + # including the CRLF + # characters on a single line so we will break the data up + # into lines by \r and/or \n then if needed we will break + # each of those into smaller lines to fit within the limit. + # in addition we will be looking for lines that start with + # a period '.' and append and additional period '.' to that + # line. NOTE: this does not count towards are limit. + + # normalize the line breaks so we know the explode works + $msg_data = str_replace("\r\n","\n",$msg_data); + $msg_data = str_replace("\r","\n",$msg_data); + $lines = explode("\n",$msg_data); + + # we need to find a good way to determine is headers are + # in the msg_data or if it is a straight msg body + # currently I'm assuming rfc 822 definitions of msg headers + # and if the first field of the first line (':' sperated) + # does not contain a space then it _should_ be a header + # and we can process all lines before a blank "" line as + # headers. + $field = substr($lines[0],0,strpos($lines[0],":")); + $in_headers = false; + if(!empty($field) && !strstr($field," ")) { + $in_headers = true; + } + + $max_line_length = 998; # used below; set here for ease in change + + while(list(,$line) = @each($lines)) { + $lines_out = null; + if($line == "" && $in_headers) { + $in_headers = false; + } + # ok we need to break this line up into several + # smaller lines + while(strlen($line) > $max_line_length) { + $pos = strrpos(substr($line,0,$max_line_length)," "); + + # Patch to fix DOS attack + if(!$pos) { + $pos = $max_line_length - 1; + } + + $lines_out[] = substr($line,0,$pos); + $line = substr($line,$pos + 1); + # if we are processing headers we need to + # add a LWSP-char to the front of the new line + # rfc 822 on long msg headers + if($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + # now send the lines to the server + while(list(,$line_out) = @each($lines_out)) { + if(strlen($line_out) > 0) + { + if(substr($line_out, 0, 1) == ".") { + $line_out = "." . $line_out; + } + } + fputs($this->smtp_conn,$line_out . $this->CRLF); + } + } + + # ok all the message data has been sent so lets get this + # over with aleady + fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "DATA not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Expand takes the name and asks the server to list all the + * people who are members of the _list_. Expand will return + * back and array of the result or false if an error occurs. + * Each value in the array returned has the format of: + * [ ] + * The definition of is defined in rfc 821 + * + * Implements rfc 821: EXPN + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 550 + * SMTP CODE ERROR : 500,501,502,504,421 + * @access public + * @return string array + */ + function Expand($name) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Expand() without being connected"); + return false; + } + + fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "EXPN not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + # parse the reply and place in our array to return to user + $entries = explode($this->CRLF,$rply); + while(list(,$l) = @each($entries)) { + $list[] = substr($l,4); + } + + return $list; + } + + /** + * Sends the HELO command to the smtp server. + * This makes sure that we and the server are in + * the same known state. + * + * Implements from rfc 821: HELO + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500, 501, 504, 421 + * @access public + * @return bool + */ + function Hello($host="") { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Hello() without being connected"); + return false; + } + + # if a hostname for the HELO wasn't specified determine + # a suitable one to send + if(empty($host)) { + # we need to determine some sort of appopiate default + # to send to the server + $host = "localhost"; + } + + // Send extended hello first (RFC 2821) + if(!$this->SendHello("EHLO", $host)) + { + if(!$this->SendHello("HELO", $host)) + return false; + } + + return true; + } + + /** + * Sends a HELO/EHLO command. + * @access private + * @return bool + */ + function SendHello($hello, $host) { + @fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => $hello . " not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + $this->helo_rply = $rply; + + return true; + } + + /** + * Gets help information on the keyword specified. If the keyword + * is not specified then returns generic help, ussually contianing + * A list of keywords that help is available on. This function + * returns the results back to the user. It is up to the user to + * handle the returned data. If an error occurs then false is + * returned with $this->error set appropiately. + * + * Implements rfc 821: HELP [ ] + * + * SMTP CODE SUCCESS: 211,214 + * SMTP CODE ERROR : 500,501,502,504,421 + * @access public + * @return string + */ + function Help($keyword="") { + $this->error = null; # to avoid confusion + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Help() without being connected"); + return false; + } + + $extra = ""; + if(!empty($keyword)) { + $extra = " " . $keyword; + } + + fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 211 && $code != 214) { + $this->error = + array("error" => "HELP not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return $rply; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. + * + * Implements rfc 821: MAIL FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,421 + * @access public + * @return bool + */ + function Mail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Mail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "MAIL not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Sends the command NOOP to the SMTP server. + * + * Implements from rfc 821: NOOP + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500, 421 + * @access public + * @return bool + */ + function Noop() { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Noop() without being connected"); + return false; + } + + fputs($this->smtp_conn,"NOOP" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "NOOP not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Sends the quit command to the server and then closes the socket + * if there is no error or the $close_on_error argument is true. + * + * Implements from rfc 821: QUIT + * + * SMTP CODE SUCCESS: 221 + * SMTP CODE ERROR : 500 + * @access public + * @return bool + */ + function Quit($close_on_error=true) { + $this->error = null; # so there is no confusion + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Quit() without being connected"); + return false; + } + + # send the quit command to the server + fputs($this->smtp_conn,"quit" . $this->CRLF); + + # get any good-bye messages + $byemsg = $this->get_lines(); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; + } + + $rval = true; + $e = null; + + $code = substr($byemsg,0,3); + if($code != 221) { + # use e as a tmp var cause Close will overwrite $this->error + $e = array("error" => "SMTP server rejected quit command", + "smtp_code" => $code, + "smtp_rply" => substr($byemsg,4)); + $rval = false; + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $e["error"] . ": " . + $byemsg . $this->CRLF; + } + } + + if(empty($e) || $close_on_error) { + $this->Close(); + } + + return $rval; + } + + /** + * Sends the command RCPT to the SMTP server with the TO: argument of $to. + * Returns true if the recipient was accepted false if it was rejected. + * + * Implements from rfc 821: RCPT TO: + * + * SMTP CODE SUCCESS: 250,251 + * SMTP CODE FAILURE: 550,551,552,553,450,451,452 + * SMTP CODE ERROR : 500,501,503,421 + * @access public + * @return bool + */ + function Recipient($to) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Recipient() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250 && $code != 251) { + $this->error = + array("error" => "RCPT not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Sends the RSET command to abort and transaction that is + * currently in progress. Returns true if successful false + * otherwise. + * + * Implements rfc 821: RSET + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE ERROR : 500,501,504,421 + * @access public + * @return bool + */ + function Reset() { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Reset() without being connected"); + return false; + } + + fputs($this->smtp_conn,"RSET" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "RSET failed", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + + return true; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in. + * + * Implements rfc 821: SEND FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + * @access public + * @return bool + */ + function Send($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Send() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SEND not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * + * Implements rfc 821: SAML FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + * @access public + * @return bool + */ + function SendAndMail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called SendAndMail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SAML not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more Recipient + * commands may be called followed by a Data command. This command + * will send the message to the users terminal if they are logged + * in or mail it to them if they are not. + * + * Implements rfc 821: SOML FROM: + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE SUCCESS: 552,451,452 + * SMTP CODE SUCCESS: 500,501,502,421 + * @access public + * @return bool + */ + function SendOrMail($from) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called SendOrMail() without being connected"); + return false; + } + + fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250) { + $this->error = + array("error" => "SOML not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return true; + } + + /** + * This is an optional command for SMTP that this class does not + * support. This method is here to make the RFC821 Definition + * complete for this class and __may__ be implimented in the future + * + * Implements from rfc 821: TURN + * + * SMTP CODE SUCCESS: 250 + * SMTP CODE FAILURE: 502 + * SMTP CODE ERROR : 500, 503 + * @access public + * @return bool + */ + function Turn() { + $this->error = array("error" => "This method, TURN, of the SMTP ". + "is not implemented"); + if($this->do_debug >= 1) { + echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; + } + return false; + } + + /** + * Verifies that the name is recognized by the server. + * Returns false if the name could not be verified otherwise + * the response from the server is returned. + * + * Implements rfc 821: VRFY + * + * SMTP CODE SUCCESS: 250,251 + * SMTP CODE FAILURE: 550,551,553 + * SMTP CODE ERROR : 500,501,502,421 + * @access public + * @return int + */ + function Verify($name) { + $this->error = null; # so no confusion is caused + + if(!$this->connected()) { + $this->error = array( + "error" => "Called Verify() without being connected"); + return false; + } + + fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($this->do_debug >= 2) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; + } + + if($code != 250 && $code != 251) { + $this->error = + array("error" => "VRFY failed on name '$name'", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error["error"] . + ": " . $rply . $this->CRLF; + } + return false; + } + return $rply; + } + + /******************************************************************* + * INTERNAL FUNCTIONS * + ******************************************************************/ + + /** + * Read in as many lines as possible + * either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + * @access private + * @return string + */ + function get_lines() { + $data = ""; + while($str = @fgets($this->smtp_conn,515)) { + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data was \"$data\"" . + $this->CRLF; + echo "SMTP -> get_lines(): \$str is \"$str\"" . + $this->CRLF; + } + $data .= $str; + if($this->do_debug >= 4) { + echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; + } + # if the 4th character is a space then we are done reading + # so just break the loop + if(substr($str,3,1) == " ") { break; } + } + return $data; + } + +} + + + ?> diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-br.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-br.php new file mode 100644 index 000000000..0ff6c1693 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-br.php @@ -0,0 +1,21 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ca.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ca.php new file mode 100644 index 000000000..819902ede --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ca.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-cz.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-cz.php new file mode 100644 index 000000000..714ed6bd5 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-cz.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-de.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-de.php new file mode 100644 index 000000000..d21836ad0 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-de.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-dk.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-dk.php new file mode 100644 index 000000000..0233492c3 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-dk.php @@ -0,0 +1,24 @@ + + */ + +$PHPMAILER_LANG = array(); + +$PHPMAILER_LANG["provide_address"] = 'Du skal indtaste mindst en ' . + 'modtagers emailadresse.'; +$PHPMAILER_LANG["mailer_not_supported"] = ' mailer understøttes ikke.'; +$PHPMAILER_LANG["execute"] = 'Kunne ikke køre: '; +$PHPMAILER_LANG["instantiate"] = 'Kunne ikke initialisere email funktionen.'; +$PHPMAILER_LANG["authenticate"] = 'SMTP fejl: Kunne ikke logge pÃ¥.'; +$PHPMAILER_LANG["from_failed"] = 'Følgende afsenderadresse er forkert: '; +$PHPMAILER_LANG["recipients_failed"] = 'SMTP fejl: Følgende' . + 'modtagere er forkerte: '; +$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fejl: Data kunne ikke accepteres.'; +$PHPMAILER_LANG["connect_host"] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.'; +$PHPMAILER_LANG["file_access"] = 'Ingen adgang til fil: '; +$PHPMAILER_LANG["file_open"] = 'Fil fejl: Kunne ikke Ã¥bne filen: '; +$PHPMAILER_LANG["encoding"] = 'Ukendt encode-format: '; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-en.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-en.php new file mode 100644 index 000000000..2f45383fe --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-en.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-es.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-es.php new file mode 100644 index 000000000..0c65bb1d2 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-es.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fi.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fi.php new file mode 100644 index 000000000..d881080d4 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fi.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fo.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fo.php new file mode 100644 index 000000000..fffe19cbb --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fo.php @@ -0,0 +1,25 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fr.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fr.php new file mode 100644 index 000000000..57f414b5f --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-fr.php @@ -0,0 +1,24 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-hu.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-hu.php new file mode 100644 index 000000000..4b55a6a46 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-hu.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-it.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-it.php new file mode 100644 index 000000000..26ef64dd1 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-it.php @@ -0,0 +1,28 @@ + +*/ + +$PHPMAILER_LANG = array(); + +$PHPMAILER_LANG["provide_address"] = 'Deve essere fornito almeno un'. + ' indirizzo ricevente'; +$PHPMAILER_LANG["mailer_not_supported"] = 'Mailer non supportato'; +$PHPMAILER_LANG["execute"] = "Impossibile eseguire l'operazione: "; +$PHPMAILER_LANG["instantiate"] = 'Impossibile istanziare la funzione mail'; +$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Impossibile autenticarsi.'; +$PHPMAILER_LANG["from_failed"] = 'I seguenti indirizzi mittenti hanno'. + ' generato errore: '; +$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: I seguenti indirizzi'. + 'destinatari hanno generato errore: '; +$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data non accettati dal'. + 'server.'; +$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Impossibile connettersi'. + ' all\'host SMTP.'; +$PHPMAILER_LANG["file_access"] = 'Impossibile accedere al file: '; +$PHPMAILER_LANG["file_open"] = 'File Error: Impossibile aprire il file: '; +$PHPMAILER_LANG["encoding"] = 'Encoding set dei caratteri sconosciuto: '; +?> diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ja.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ja.php new file mode 100644 index 000000000..837a0f58a --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ja.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-nl.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-nl.php new file mode 100644 index 000000000..13aa73362 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-nl.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-no.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-no.php new file mode 100644 index 000000000..ffaa2e754 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-no.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-pl.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-pl.php new file mode 100644 index 000000000..5691eaf7e --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-pl.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ro.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ro.php new file mode 100644 index 000000000..a330b4ad6 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ro.php @@ -0,0 +1,23 @@ + + */ + +$PHPMAILER_LANG = array(); + +$PHPMAILER_LANG["provide_address"] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; +$PHPMAILER_LANG["mailer_not_supported"] = ' mailer nu este suportat.'; +$PHPMAILER_LANG["execute"] = 'Nu pot executa: '; +$PHPMAILER_LANG["instantiate"] = 'Nu am putut instantia functia mail.'; +$PHPMAILER_LANG["authenticate"] = 'Eroare SMTP: Nu a functionat autentificarea.'; +$PHPMAILER_LANG["from_failed"] = 'Urmatoarele adrese From au dat eroare: '; +$PHPMAILER_LANG["recipients_failed"] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; +$PHPMAILER_LANG["data_not_accepted"] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.'; +$PHPMAILER_LANG["connect_host"] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.'; +$PHPMAILER_LANG["file_access"] = 'Nu pot accesa fisierul: '; +$PHPMAILER_LANG["file_open"] = 'Eroare de fisier: Nu pot deschide fisierul: '; +$PHPMAILER_LANG["encoding"] = 'Encodare necunoscuta: '; +?> diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ru.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ru.php new file mode 100644 index 000000000..3c7d78431 --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-ru.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-se.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-se.php new file mode 100644 index 000000000..f71326fdb --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-se.php @@ -0,0 +1,24 @@ + + */ + +$PHPMAILER_LANG = array(); + +$PHPMAILER_LANG["provide_address"] = 'Du mÃ¥ste ange minst en ' . + 'mottagares e-postadress.'; +$PHPMAILER_LANG["mailer_not_supported"] = ' mailer stöds inte.'; +$PHPMAILER_LANG["execute"] = 'Kunde inte köra: '; +$PHPMAILER_LANG["instantiate"] = 'Kunde inte initiera e-postfunktion.'; +$PHPMAILER_LANG["authenticate"] = 'SMTP fel: Kunde inte autentisera.'; +$PHPMAILER_LANG["from_failed"] = 'Följande avsändaradress är felaktig: '; +$PHPMAILER_LANG["recipients_failed"] = 'SMTP fel: Följande ' . + 'mottagare är felaktig: '; +$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fel: Data accepterades inte.'; +$PHPMAILER_LANG["connect_host"] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; +$PHPMAILER_LANG["file_access"] = 'Ingen Ã¥tkomst till fil: '; +$PHPMAILER_LANG["file_open"] = 'Fil fel: Kunde inte öppna fil: '; +$PHPMAILER_LANG["encoding"] = 'Okänt encode-format: '; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/phpmailer/language/phpmailer.lang-tr.php b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-tr.php new file mode 100644 index 000000000..42b6ea6ab --- /dev/null +++ b/gulliver/thirdparty/phpmailer/language/phpmailer.lang-tr.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/CHANGELOG b/gulliver/thirdparty/propel-generator/CHANGELOG new file mode 100644 index 000000000..ab5098b0d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/CHANGELOG @@ -0,0 +1,150 @@ + + P R O P E L C H A N G E S + ============================ + + Mar 7, 2007 - 1.2.1 + + ChangeLog for 1.2.1 at http://propel.phpdb.org/trac/query?status=closed&milestone=1.2.1&resolution=fixed&order=priority + + Aug 31, 2006 - 1.2.0 + + Breaking Changes: + *** New API for generic accessors and settors (see API docs). The methods are + the same but the default indexing has changed. + *** New API for validators (see Wiki / docs). + + Major Changes (for complete list see issue tracker at http://propel.phpdb.org): + - Propel now compatible w/ PHP >= 5.0.5 & 5.1.x + - New MySQLi driver for Propel (use 'mysqli' instead of 'mysql') + - Added propel-gen script to standard-installed versions of Propel also + - New XSD schema for validating the XML datamodel descriptions (schema.xml) + - Support for specifying vendor-specific info in the schema.xml + - Better support for sequences in reverse engineering PostgreSQL databases + - #146 Added 'size' attribute to and + - New extensible OO builder classes for generating PHP5 classes and SQL DDL + - Identifier escaping in generated SQL (note: for Postgres this means columns + are case-sensitive) + - Numerous improvements to validation framework, including new, cleaner API + - Added doCountJoin*() methods to the generated Peer classes + - Obj->save() calls now return the number of affected rows (if supported by db) + - See http://propel.phpdb.org/trac/report/9 for complete list of closed tickets + by milestone. + + April 7, 2005 - 1.1.0 + + Big Changes: + *** Changed retrieveByPK() to return NULL instead of throw Exception if no row + was matched. (Dave Lawson) + *** New PHP runtime conf format has changed (must regenerate conf file). + *** Dropped support for deprecated ini-format runtime properties file. (Hans) + *** Cleanup of build properties files, removal of deprecated properties. (Hans) + + New Features: + - Schema attributes are no longer case-sensitive. + - New tag allows specifying vendor-specific attributes. (Pavel) + - MySQL identifiers escaping added to SQL generation templates. (Pavel) + - MySQL unique indexes SQL generation added. (Pavel) + - Added support for interface="" attribute of tag; defaults to Persistent. (Hans) + - Added doSelectJoinAll() to generated peer classes. (Hans) + - Added doDeleteAll() method to remove all rows from specified table. (Hans) + - Added support for returning affected rows from update methods in peer classes. (Hans) + - Added PHPUnit2-based unit testing framework to replace old bookstore-test.php + - Added schema validation / error throwing to schema parser. (Pavel) + - Logging is now optional (no log section means no logger used). (David Zülke) + - Added TIMESTAMP_BU, DATE_BU types for "before-unix" (pre 1970) dates. (Hans) + + Bug Fixes: + - Fixed E_STRICT error in generated Peer doCount() method (Hans) + - Fixed bug when using doSelectJoin*() methods with tables that have lazyload columns. (Hans) + - Fixed logic bugs in doSelectJoinExcept*() method generation. (Hans) + - Fixed support for temporal (date/time) default values. (Hans) + - Fixed bug where setting only default values in object would result in no save. (Hans) + - Fixes to PropelSQLExecTask to handle non-typical queries (Dominik, Hans). + - Fixed bug in enumerated inheritance when using string coltype (Kaspars) + - Fixes to charset / encoding in schema creation. (Joe Cai, Pavel) + - Fixed nested external schema bug. (Pavel) + - Fixed unexpected results bug in NodePeer::buildFamilyCriteria(). (Dave Lawson) + - Fixed clearSelectColumns() to also clear $asColumns. (Fabien Potencier) + + Oct. 24, 2004 - 1.0.0 + + Big Changes: + - Removed Transaction class, refactoring functionality into Creole + Connection classes (Dave Lawson) + - New NodePeer for handling hierarchies (Dave Lawson) + - Propel has a new default directory layout for projects. All project + files are now located in one directory. + + projects/ + |- bookstore/ + | |- build/ + | |- schema.xml + | |- runtime.properties <-- deprecated + | |- runtime-conf.xml <-- new standard + + - Added new default XML format for setting Propel's runtime properties. + (see dir layout above). + + - Added new build.xml to wrap build-propel.xml. New file is preferred + way to build projects, as it allows for inclusion of project-specific + build.properties files. Propel is finally fully multi-project friendly. + + - Support for specifying "lazy-load" columns in schema XML. Lazy load + columns will only be populated on demand. This means that by default + object hyradtion will not include these columns (so smaller, faster + objects), but also that an additional query is executed when data is + needed. (This is particularly useful for BLOB/CLOB columns.) + + Minor Changes: + [Generated Classes] + - Peer::populateObject() method deprecated (will remove in Propel 1.1) in + favor of Object->hydrate() + - Removed Peer::buildCriteria() method in favor of Object->buildCriteria() + and Object->buildPkeyCriteria() + - Peer doSelect*() family of methods now [consistently] only takes + Criteria objects for parameter. + - No more support in generated Peer classes for using Criteria with + different DB name. + - Date/time setter methods now perform a strtotime() conversion on passed + data and throw a PropelException is such a conversion cannot be performed. + - New copy() method replaces non-working __clone() impl. __clone() unused due + to desire to have a way to copy objects w/o necessarying copying rows. + + [Default Properties] + - The schema include pattern changed to *schema.xml (instead of + *-schema.xml), for added flexibility in layout. + + [SQL Generator] + - Updated model classes to recognize boolean values in case-insensitive + manner (allow "TRUE" & "true"). + - Updated model classes to recognize Propel types in case-insensitive + manner (allow "integer" & "INTEGER"). + + June 8, 2003 - 1.0.0-beta1 + + Bug Fixes: + - Fixed 'creole' target to include database name in generated schema XML + - Fixed Propel to work correctly with tables that have pkey, but no + autoIncrement cols + - Fixed Criteria toString() method to work [for SELECT clauses only] + - TIMESTAMP defaults to DATETIME for MySQL + - Added support for COMMENT keyword (for descriptions from schema) in + MySQL table definitions + - Fixed Table->containsColumn() method in propel-generator + - Fixed insert-sql to work with multi-line & complex SQL statements (Dominik del Bondio) + + May 2, 2004 - 1.0.0-alpha2 + + Bug Fixes: + - LONGVARCHAR no longer considered LOB column (HL) + - Added INDEX for MySQL/InnoDB foreign keys + - Removed old references to BOOLEANINT/BOOLEANCHAR from platform classes (HL) + - Allow missing autoIncrement column w/o requiring idMethod="none" (HL) + - Fixed parse errors in generated classes w/ multi-column primary key (HL) + + New Features: + - Added column validator framework and validator suite (MA) + - Added doCount() method to generated peers (MA) + + +--$Id: CHANGELOG,v 1.11 2005/04/07 22:25:52 hlellelid Exp $ diff --git a/gulliver/thirdparty/propel-generator/INSTALL b/gulliver/thirdparty/propel-generator/INSTALL new file mode 100644 index 000000000..5512fa9d7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/INSTALL @@ -0,0 +1,176 @@ + + I N S T A L L I N G P R O P E L + ================================== + + This is a quick guide for installing Propel and building the provided sample + bookstore application. For more information on installation / configuration + see the online user guide available from main site: http://propel.phpdb.org + + + Prerequisites + ------------- + + Before you can install and run Propel you will need to have the following: + + * PHP >= 5.0.0 + Propel will only work with PHP5. Additionally, you must have a command- + line version of PHP5 in order to use PHING to build the classes and SQL + files for your data model. PHP must also have compiled in XML (libxml2, xsl) + support in order to take advantage of all build options. + + * PHING >= 2.0.0 + Propel uses the PHING build system to build the classes and SQL definition + files for your data model. PHING is an open-source project build system + based on Apache ANT. PHING 2 is the (development) version built for PHP5. + See http://phing.tigris.org/ to learn how to install Phing (it's easy). + + * Creole >- 1.0.0 + Creole is a Uniform DB API framework for PHP5. Creole is available as a PEAR + package or can be installed in a more traditional manner. See + http://creole.phpdb.org/ to get a copy of the Creole classes. + + * A supported RDBMS + Creole currently supports MySQL, MS SQL Server, PostgreSQL, and SQLite. We + are working on support for Oracle and the new MySQLi drivers but this should + be considered alpha, at best. + + Quick Install (PEAR) + -------------------- + + It is now possible to install both the Propel runtime and the generator classes as + PEAR packages. This is the quickest way to get up and running with Propel, but may + not be quite as easy to configure as the traditional installation method. + + * Propel Generator: + + % pear install http://propel.phpdb.org/pear/propel_generator-current.tgz + + To use the generator to build sql, php classes, etc. simply use the propel-gen shell + script: + + % propel-gen /path/to/my/projectdir + + (See the sample bookstore project directory in your PEAR data directory for a sample + projectdir.) + + * Propel Runtime: + + % pear install http://propel.phpdb.org/pear/propel_runtime-current.tgz + + It is recommended that you read over the traditional install guide also, so that you + understand the roles of some of the various files. In the PEAR install these files + (e.g. the main build.properties and the sample bookstore project) are stored in the + PEAR data dir (e.g. /usr/local/lib/php/data, C:\PHP\PEAR\data). + + + Traditional Installation + ------------------------ + + Installation of Propel involves a few steps because Propel is composed of a generator + and runtime classes which are (now) packaged separately. + + Begin installation of Propel by choosing a base directory and unpacking the archive. + + For the sake of simplicity, we'll assume that you are installing from a package + (instead of CVS) into /var/www/php/. + + % cd /var/www/php + % tar zxf /path/to/propel-x.x.x.tar.gz + % ln -s propel-x.x.x propel + + A. Propel Generator + + The Propel generator classes don't need any special setup. The classes and Phing + scripts are located in the propel-generator/ directory (which in our example is + /var/www/php/propel/generator). + + B. Runtime Classes + + The runtime classes were unpacked to the propel/ directory (in this example, + /var/www/php/propel). In order to use these classes in runtime applications, you will + need to make sure that they are on the PHP include_path. In our example, the + following directory would need to be added to your PHP include_path: + /var/www/php/propel/classes. You could also copy the + /var/www/php/propel/classes/propel directory to a location that is already on your + include_path, e.g. the directory where PEAR classes are located: + + % cp -r /var/www/php/propel/runtime/classes/propel /usr/local/lib/php/ + + Another option on *nix systems is to create a symlink: + + % ln -s /var/www/php/propel/runtime/classes/propel /usr/local/lib/php/propel + + + Quick Test + ---------- + + If you want to quickly test & see whether your installation is working, you can use + the default configuration which will build the example application using SQLite. + + Here is how to run the simple test on Unix (use corresponding commands for Windows). + If you run into trouble, don't panic -- just continue reading the INSTALL guide and + consult the Installation chapter of the online user guide at http://propel.phpdb.org. + + Change to your propel-generator dir (e.g.) + $> cd /var/www/php/propel/generator + + If using Propel from CVS, copy/rename the build.properties-sample file: + $> cp build.properties-sample build.properties + + Run Phing to build the classes and SQL files, specifying the bookstore project + $> phing -Dproject=bookstore + + Run the 'insert-sql' target which will add the tables to the SQLite db + $> phing -Dproject=bookstore insert-sql + + Run the test script that uses the generated classes against the bookstore db: + $> cd test/ + $> php -f bookstore-test.php + + You should see a bunch of output as it tests use cases. Hopefully there aren't any + "FAILED" messages. If you get a failed message immediately indicating that it can't + find one of the tables make sure that you a) ran the 'insert'-sql' target and that + you are running the bookstore-test.php script from the main propel directory *and* + that you call PHP with the -qC options so that it won't chdir() into the scripts + directory. (The path for the bookstore.db is ./test/bookstore.db so you can see + that you need to be in the main propel directory for that to work.) + + + Configure + --------- + + To get Propel to work with your own db setup, create a new project (easiest way is + to use the bookstore project directory as a template). Create your datamodel schema, + modify the build.properties for that project to specify database connection + information, and set the db connection runtime properties in runtime-conf.xml. + + + Build + ----- + + This assumes that you have already installed and configured a copy of PHING 2. + + % cd /var/www/php/propel/generator + % phing -Dproject=mykillerapp + + This will build the SQL files and the object & peer classes based on your datamodel + schema XML file. + + The resulting files will be placed in: + /var/www/php/propel/generator/projects/mykillerapp/build + + If you encounter any problems, try adding -verbose or -debug to get more output + from the PHING build process. + + + You're Done! + ------------ + + At this point hopefully you have successfully built the classes and SQL definitions + for the sample bookstore application. If you encountered problems, please visit + http://propel.phpdb.org to read additional documention, browse through the users + mailing list, or add a bug report. + + Enjoy! + + --$Id: INSTALL,v 1.4 2005/03/24 00:24:07 hlellelid Exp $ diff --git a/gulliver/thirdparty/propel-generator/LICENSE b/gulliver/thirdparty/propel-generator/LICENSE new file mode 100644 index 000000000..b9d61c9de --- /dev/null +++ b/gulliver/thirdparty/propel-generator/LICENSE @@ -0,0 +1,506 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public + Licenses are intended to guarantee your freedom to share and change + free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some + specially designated software packages--typically libraries--of the + Free Software Foundation and other authors who decide to use it. You + can use it too, but we suggest you first think carefully about whether + this license or the ordinary General Public License is the better + strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, + not price. Our General Public Licenses are designed to make sure that + you have the freedom to distribute copies of free software (and charge + for this service if you wish); that you receive source code or can get + it if you want it; that you can change the software and use pieces of + it in new free programs; and that you are informed that you can do + these things. + + To protect your rights, we need to make restrictions that forbid + distributors to deny you these rights or to ask you to surrender these + rights. These restrictions translate to certain responsibilities for + you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link other code with the library, you must provide + complete object files to the recipients, so that they can relink them + with the library after making changes to the library and recompiling + it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the + library, and (2) we offer you this license, which gives you legal + permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that + there is no warranty for the free library. Also, if the library is + modified by someone else and passed on, the recipients should know + that what they have is not the original version, so that the original + author's reputation will not be affected by problems that might be + introduced by others. + + Finally, software patents pose a constant threat to the existence of + any free program. We wish to make sure that a company cannot + effectively restrict the users of a free program by obtaining a + restrictive license from a patent holder. Therefore, we insist that + any patent license obtained for a version of the library must be + consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the + ordinary GNU General Public License. This license, the GNU Lesser + General Public License, applies to certain designated libraries, and + is quite different from the ordinary General Public License. We use + this license for certain libraries in order to permit linking those + libraries into non-free programs. + + When a program is linked with a library, whether statically or using + a shared library, the combination of the two is legally speaking a + combined work, a derivative of the original library. The ordinary + General Public License therefore permits such linking only if the + entire combination fits its criteria of freedom. The Lesser General + Public License permits more lax criteria for linking other code with + the library. + + We call this license the "Lesser" General Public License because it + does Less to protect the user's freedom than the ordinary General + Public License. It also provides other free software developers Less + of an advantage over competing non-free programs. These disadvantages + are the reason we use the ordinary General Public License for many + libraries. However, the Lesser license provides advantages in certain + special circumstances. + + For example, on rare occasions, there may be a special need to + encourage the widest possible use of a certain library, so that it + becomes a de-facto standard. To achieve this, non-free programs must be + allowed to use the library. A more frequent case is that a free + library does the same job as widely used non-free libraries. In this + case, there is little to gain by limiting the free library to free + software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free + programs enables a greater number of people to use a large body of + free software. For example, permission to use the GNU C Library in + non-free programs enables many more people to use the whole GNU + operating system, as well as its variant, the GNU/Linux operating + system. + + Although the Lesser General Public License is Less protective of the + users' freedom, it does ensure that the user of a program that is + linked with the Library has the freedom and the wherewithal to run + that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, whereas the latter must + be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other + program which contains a notice placed by the copyright holder or + other authorized party saying it may be distributed under the terms of + this Lesser General Public License (also called "this License"). + Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control compilation + and installation of the library. + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of + running a program using the Library is not restricted, and output from + such a program is covered only if its contents constitute a work based + on the Library (independent of the use of the Library in a tool for + writing it). Whether that is true depends on what the Library does + and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided that + you conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the + Library. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange for a + fee. + + 2. You may modify your copy or copies of the Library or any portion + of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it. + + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library. + + In addition, mere aggregation of another work not based on the Library + with the Library (or with a work based on the Library) on a volume of + a storage or distribution medium does not bring the other work under + the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. To do + this, you must alter all the notices that refer to this License, so + that they refer to the ordinary GNU General Public License, version 2, + instead of to this License. (If a newer version than version 2 of the + ordinary GNU General Public License has appeared, then you can specify + that version instead if you wish.) Do not make any other change in + these notices. + + Once this change is made in a given copy, it is irreversible for + that copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of + the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable form + under the terms of Sections 1 and 2 above provided that you accompany + it with the complete corresponding machine-readable source code, which + must be distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to + distribute the source code, even though third parties are not + compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being compiled or + linked with it, is called a "work that uses the Library". Such a + work, in isolation, is not a derivative work of the Library, and + therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. + Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data + structure layouts and accessors, and small macros and small inline + functions (ten lines or less in length), then the use of the object + file is unrestricted, regardless of whether it is legally a derivative + work. (Executables containing this object code plus portions of the + Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, + whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or + link a "work that uses the Library" with the Library to produce a + work containing portions of the Library, and distribute that work + under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the materials to be distributed need not include anything that is + normally distributed (in either source or binary form) with the major + components (compiler, kernel, and so on) of the operating system on + which the executable runs, unless that component itself accompanies + the executable. + + It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute. + + 7. You may place library facilities that are a work based on the + Library side-by-side in a single library together with other library + facilities not covered by this License, and distribute such a combined + library, provided that the separate distribution of the work based on + the Library and of the other library facilities is otherwise + permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute + the Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or + distribute the Library is void, and will automatically terminate your + rights under this License. However, parties who have received copies, + or rights, from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Library or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Library (or any work based on the + Library), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying + the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the Library + subject to these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + You are not responsible for enforcing compliance by third parties with + this License. + + 11. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Library at all. For example, if a patent + license would not permit royalty-free redistribution of the Library by + all those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Library. + + If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply, + and the section as a whole is intended to apply in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing + to distribute software through any other system and a licensee cannot + impose that choice. + + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Library under this License may + add an explicit geographical distribution limitation excluding those + countries, so that distribution is permitted only in or among countries + not thus excluded. In such case, this License incorporates the + limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new + versions of the Lesser General Public License from time to time. + Such new versions will be similar in spirit to the present version, + but may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and + "any later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a + license version number, you may choose any version ever published by + the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, + write to the author to ask for permission. For software which is + copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE + LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME + THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest + possible use to the public, we recommend making it free software that + everyone can redistribute and change. You can do so by permitting + redistribution under these terms (or, alternatively, under the terms of the + ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is + safest to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least the + "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Also add information on how to contact you by electronic and paper mail. + + You should also get your employer (if you work as a programmer) or your + school, if any, to sign a "copyright disclaimer" for the library, if + necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + + That's all there is to it! + + --$Id: LICENSE,v 1.1 2004/07/14 02:18:14 hlellelid Exp $ + + diff --git a/gulliver/thirdparty/propel-generator/bin/propel-gen b/gulliver/thirdparty/propel-generator/bin/propel-gen new file mode 100755 index 000000000..11c929f01 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/bin/propel-gen @@ -0,0 +1,67 @@ +#!/bin/sh +# Shell wrapper for Propel generator +# $Id$ +# +# This script will do the following: +# - check for PHING_COMMAND env, if found, use it. +# - if not found assume php is on the path +# - check for PROPEL_GEN_HOME evn, if found use it +# - if not look for it + +if [ -z "$PROPEL_GEN_HOME" ] ; then + + # echo "WARNING: PROPEL_GEN_HOME environment not set. Attempting to guess." + + # try to find Propel + if [ -d /opt/propel/generator ] ; then + PROPEL_GEN_HOME=/opt/propel/generator + fi + + if [ -d "${HOME}/opt/propel/generator" ] ; then + PROPEL_GEN_HOME="${HOME}/opt/propel/generator" + fi + + if [ -d "/usr/local/propel/generator" ] ; then + PROPEL_GEN_HOME="/usr/local/propel/generator" + fi + + if [ -d "${HOME}/usr/propel/generator" ] ; then + PROPEL_GEN_HOME="${HOME}/usr/propel/generator" + fi + + ## resolve links - $0 may be a link to phing's home + PRG="$0" + progname=`basename "$0"` + saveddir=`pwd` + + # need this for relative symlinks + dirname_prg=`dirname "$PRG"` + cd "$dirname_prg" + + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi + done + + PROPEL_GEN_HOME=`dirname "$PRG"`/.. + + cd "$saveddir" + + # make it fully qualified + PROPEL_GEN_HOME=`cd "$PROPEL_GEN_HOME" && pwd` + + # make it available in PHP via getenv("PROPEL_GEN_HOME") + export PROPEL_GEN_HOME +fi + +if (test -z "$PHING_COMMAND") ; then + # echo "WARNING: PHING_COMMAND environment not set. (Assuming phing on PATH)" + export PHING_COMMAND="phing" +fi + +$PHING_COMMAND -f $PROPEL_GEN_HOME/build.xml -Dusing.propel-gen=true -Dproject.dir=$* diff --git a/gulliver/thirdparty/propel-generator/bin/propel-gen.bat b/gulliver/thirdparty/propel-generator/bin/propel-gen.bat new file mode 100644 index 000000000..5dd3e2928 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/bin/propel-gen.bat @@ -0,0 +1,47 @@ +@echo off + +rem ********************************************************************* +rem ** The Propel generator convenience script for Windows based systems +rem ** $Id$ +rem ********************************************************************* + +rem This script will do the following: +rem - check for PHING_COMMAND env, if found, use it. +rem - if not found detect php, if found use it, otherwise err and terminate +rem - check for PROPEL_GEN_HOME evn, if found use it +rem - if not found error and leave + +if "%OS%"=="Windows_NT" @setlocal + +rem %~dp0 is expanded pathname of the current script under NT +set DEFAULT_PROPEL_GEN_HOME=%~dp0.. + +goto init +goto cleanup + +:init + +if "%PROPEL_GEN_HOME%" == "" set PROPEL_GEN_HOME=%DEFAULT_PROPEL_GEN_HOME% +set DEFAULT_PROPEL_GEN_HOME= + +if "%PHING_COMMAND%" == "" goto no_phingcommand + +goto run +goto cleanup + +:run +%PHING_COMMAND% -f %PROPEL_GEN_HOME%\build.xml -Dusing.propel-gen=true -Dproject.dir=%* +goto cleanup + +:no_phingcommand +REM echo ------------------------------------------------------------------------ +REM echo WARNING: Set environment var PHING_COMMAND to the location of your phing +REM echo executable (e.g. C:\PHP\phing.bat). +REM echo Proceeding with assumption that phing.bat is on Path +REM echo ------------------------------------------------------------------------ +set PHING_COMMAND=phing.bat +goto init + +:cleanup +if "%OS%"=="Windows_NT" @endlocal +REM pause diff --git a/gulliver/thirdparty/propel-generator/build-propel.xml b/gulliver/thirdparty/propel-generator/build-propel.xml new file mode 100644 index 000000000..4ba8562b5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/build-propel.xml @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATTENTION: It appears you are using PostgreSQL and you have identifier-quoting turned on. + It is suggested that you disable identifier quoting when using PostgreSQL -- especially if you + have case-sensitive columns in your database. + + To disable identifier quoting, add the following property to your build.properties (or specify + it using -D on commandline): + + propel.disableIdentifierQuoting=true + + You can ignore this warning if you understand the issues related to case-sensitivity and Propel's + DDL-only implementation of identifier quoting. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/propel-generator/build.properties-sample b/gulliver/thirdparty/propel-generator/build.properties-sample new file mode 100644 index 000000000..352acc6cb --- /dev/null +++ b/gulliver/thirdparty/propel-generator/build.properties-sample @@ -0,0 +1,190 @@ +# ------------------------------------------------------------------- +# +# P R O P E L C O N F I G U R A T I O N F I L E +# +# ------------------------------------------------------------------- +# This file contains some example properties. Ideally properties +# should be specified in the project-specific build.properties file; +# however, this file can be used to specify non-default properties +# that you would like to use accross all of your Propel projects. +# ------------------------------------------------------------------- +# + +propel.home = . + +# ------------------------------------------------------------------- +# +# P R O J E C T +# +# ------------------------------------------------------------------- +# This is the name of your Propel project. The name of your Propel +# project is used (by default) to determine where the generator will +# find needed configuration files and will place resuilting build +# files. E.g. if your project is named 'killerapp', Propel will +# look here for schema.xml and runtime-conf.xml files: +# +# projects/killerapp/ +# +# ------------------------------------------------------------------- + +# You can set this here, but it's preferrable to set this in a +# project-specific build.properties file. +# +# propel.project = bookstore + +# ------------------------------------------------------------------- +# +# T A R G E T D A T A B A S E +# +# ------------------------------------------------------------------- +# This is the target database, only considered when generating +# the SQL for your Propel project. Your possible choices are: +# +# mssql, mysql, oracle, pgsql, sqlite +# ------------------------------------------------------------------- + +# You can set this here, but it's preferrable to set this in a +# project-specific build.properties file. +# +# propel.database = mysql + +# ------------------------------------------------------------------- +# +# O B J E C T M O D E L I N F O R M A T I O N +# +# ------------------------------------------------------------------- +# These settings will allow you to customize the way your +# Peer-based object model is created. +# ------------------------------------------------------------------- +# addGenericAccessors +# If true, Propel adds methods to get database fields by name/position. +# +# addGenericMutators +# If true, Propel adds methods to set database fields by name/position. +# +# addSaveMethod +# If true, Propel adds tracking code to determine how to save objects. +# +# addTimeStamp +# If true, Propel true puts time stamps in phpdoc of generated om files. +# +# basePrefix +# A string to pre-pend to the file names of base data and peer objects. +# +# complexObjectModel +# If true, Propel generates data objects with collection support and +# methods to easily retreive foreign key relationships. +# +# targetPackage +# Sets the PHP "package" the om files will generated to, e.g. +# "com.company.project.om". +# +# targetPlatform +# Sets whether Propel is building classes for php5 (default) +# or php4 (experimental). +# +# packageObjectModel +# Sets whether Propel is packaging ObjectModel fro several +# [package].schema.xml files. The +# attribute has to be set then. (warning: this is experimental!) +# +# ------------------------------------------------------------------- + +# classes will be put in (and included from) this directory +# e.g. if package is "bookstore" then om will expect include('bookstore/Book.php'); to work. +# use dot-path notation -- e.g. my.bookstore -> my/bookstore. +# +propel.targetPackage = ${propel.project} + +propel.addGenericAccessors = false +propel.addGenericMutators = false +propel.addSaveMethod = true +propel.addTimeStamp = true +propel.basePrefix = Base +propel.complexObjectModel = true +propel.targetPlatform = php5 +propel.packageObjectModel = false + +# ------------------------------------------------------------------- +# +# D B C O N N E C T I O N S E T T I N G S +# +# ------------------------------------------------------------------- +# Creole connection settings. These connection settings are used by +# build tagets that perform database operations (e.g. 'insert-sql', +# 'creole'). +# +# You can set them here, but it's preferrable to set these properties +# in a project-specific build.properties file. +# + +# If you want to use a custom driver, specify it below, otherwise +# leave it blank or comment it out to use Creole stock driver. +# +# propel.database.driver = creole.drivers.sqlite.SQLiteConnection + +# Note that if you do not wish to specify the database (e.g. if you +# are using multiple databses) you can use the @DB@ token which +# will be replaced with a database at runtime. +# +# propel.database.url = mysql://root@localhost/bookstore + +# Use the URL below to specify a DSN to used to create the database. +# Note that this URL should not contain the database name, as you will +# get an error if the database does not exist. +# (This does not apply to SQLite since the databse is automatically created +# when the connection is made -- if it does not already exist.) +# +# propel.database.createUrl = mysql://root@localhost/ + + +# ------------------------------------------------------------------- +# +# C R E O L E TO X M L +# +# ------------------------------------------------------------------- +# These settings only applies to the 'creole' target. +# ------------------------------------------------------------------- +# +# samePhpName +# If true, the Creole task will set the phpName attribute for the +# tables and columns to be the same as SQL name. +# +# addVendorInfo +# If true, the Creole task will add vendor specific information +# to the database schema +# +# addValidators +# Bitfield like option to turn on/off addition of Validator and +# Rule tags to the schema. Uses a boolean syntax like in php.ini. +# Allowed tokens are: +# none add no validators) +# all add all validators) +# maxlength add maxlengths for string type columns) +# maxvalue add maxvalue for numeric columns) +# type add notmatch validators for numeric columns) +# required add required validators for required columns) +# unique add unique validators for unique indexes) +# Allowed operators are: +# & bitwise AND +# | bitwise OR +# ~ bitwise NOT +# +# ------------------------------------------------------------------- + +# propel.samePhpName = false +# propel.addVendorInfo=true +# propel.addValidators=none + + +# ------------------------------------------------------------------- +# +# D A T A B A S E B U I L D C O N F I G +# +# ------------------------------------------------------------------- +# Some databases provide some configuration options that can be set +# in this script. +# +# === MySQL +# propel.mysql.tableType +# Use this property to set the table type of generated tables (e.g. InnoDB, MyISAM). diff --git a/gulliver/thirdparty/propel-generator/build.xml b/gulliver/thirdparty/propel-generator/build.xml new file mode 100644 index 000000000..7c030199a --- /dev/null +++ b/gulliver/thirdparty/propel-generator/build.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Project name + + + + + No project.dir was specified, using default path: ./projects/${project} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/propel-generator/build.xml-local b/gulliver/thirdparty/propel-generator/build.xml-local new file mode 100644 index 000000000..5fdfe8ea4 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/build.xml-local @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/EngineException.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/EngineException.php new file mode 100644 index 000000000..f2b32d6d4 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/EngineException.php @@ -0,0 +1,33 @@ +. + */ + +require_once 'phing/BuildException.php'; + +/** + * The base class of all exceptions thrown by the engine. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @author Jason van Zyl (Torque) + * @version $Revision: 536 $ + * @package propel.engine + */ +class EngineException extends BuildException {} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/DataModelBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/DataModelBuilder.php new file mode 100644 index 000000000..41305c50d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/DataModelBuilder.php @@ -0,0 +1,221 @@ +. + */ + + +/** + * This is the base class for any builder class that is using the data model. + * + * This could be extended by classes that build SQL DDL, PHP classes, configuration + * files, input forms, etc. + * + * This class has a static method to return the correct builder subclass identified by + * a given key. Note that in order for this factory method to work, the properties have to have + * been loaded first. Usage should look something like this (from within a AbstractProelDataModelTask subclass): + * + * + * DataModelBuilder::setBuildProperties($this->getPropelProperties()); + * $builder = DataModelBuilder::builderFactory($table, 'peer'); + * // $builder (by default) instanceof PHP5ComplexPeerBuilder + * + * + * @author Hans Lellelid + * @package propel.engine.builder + */ +abstract class DataModelBuilder { + + // -------------------------------------------------------------- + // Static properties & methods + // -------------------------------------------------------------- + + /** + * Build properties (after they've been transformed from "propel.some.name" => "someName"). + * @var array string[] + */ + private static $buildProperties = array(); + + /** + * Sets the [name transformed] build properties to use. + * @param array Property values keyed by [transformed] prop names. + */ + public static function setBuildProperties($props) + { + self::$buildProperties = $props; + } + + /** + * Get a specific [name transformed] build property. + * @param string $name + * @return string + */ + public static function getBuildProperty($name) + { + return isset(self::$buildProperties[$name]) ? self::$buildProperties[$name] : null; + } + + /** + * Imports and returns the classname of the builder class for specified 'type'. + * @param $type The "key" for class to load. + * @return string The unqualified classname. + */ + public static function getBuilderClass($type) + { + if (empty(self::$buildProperties)) { + throw new BuildException("Cannot determine builder class when no build properties have been loaded (hint: Did you call DataModelBuilder::setBuildProperties(\$props) first?)"); + } + $propname = 'builder' . ucfirst(strtolower($type)) . 'Class'; + $classpath = self::getBuildProperty($propname); + + if (empty($classpath)) { + throw new BuildException("Unable to find class path for '$propname' property."); + } + + // This is a slight hack to workaround camel case inconsistencies for the DDL classes. + // Basically, we want to turn ?.?.?.sqliteDDLBuilder into ?.?.?.SqliteDDLBuilder + $lastdotpos = strrpos($classpath, '.'); + if ($lastdotpos) $classpath{$lastdotpos+1} = strtoupper($classpath{$lastdotpos+1}); + else ucfirst($classpath); + + return Phing::import($classpath); + } + + /** + * Factory method to load a new builder instance based on specified type. + * @param Table $table + * @param $type The "key" for class to load. + * @throws BuildException if specified class cannot be found / loaded. + */ + public static function builderFactory(Table $table, $type) + { + $classname = self::getBuilderClass($type); + return new $classname($table); + } + + /** + * Utility function to build a path for use in include()/require() statement. + * + * Supports two function signatures: + * (1) getFilePath($dotPathClass); + * (2) getFilePath($dotPathPrefix, $className); + * + * @param string $path dot-path to class or to package prefix. + * @param string $classname class name + * @return string + */ + public static function getFilePath($path, $classname = null, $extension = '.php') + { + $path = strtr(ltrim($path, '.'), '.', '/'); + if ($classname !== null) { + if ($path !== "") { $path .= '/'; } + return $path . $classname . $extension; + } else { + return $path . $extension; + } + } + + // -------------------------------------------------------------- + // Non-static properties & methods inherited by subclasses + // -------------------------------------------------------------- + + /** + * The current table. + * @var Table + */ + private $table; + + /** + * An array of warning messages that can be retrieved for display (e.g. as part of phing build process). + * @var array string[] + */ + private $warnings = array(); + + /** + * Creates new instance of DataModelBuilder subclass. + * @param Table $table The Table which we are using to build [OM, DDL, etc.]. + */ + public function __construct(Table $table) + { + $this->table = $table; + } + + /** + * Returns the Platform class for this table (database). + * @return Platform + */ + protected function getPlatform() + { + return $this->getTable()->getDatabase()->getPlatform(); + } + + /** + * Returns the database for current table. + * @return Database + */ + protected function getDatabase() + { + return $this->getTable()->getDatabase(); + } + + /** + * Returns the current Table object. + * @return Table + */ + protected function getTable() + { + return $this->table; + } + + /** + * Pushes a message onto the stack of warnings. + * @param string $msg The warning message. + */ + protected function warn($msg) + { + $this->warnings[] = $msg; + } + + /** + * Gets array of warning messages. + * @return array string[] + */ + public function getWarnings() + { + return $this->warnings; + } + + /** + * Wraps call to Platform->quoteIdentifier() with a check to see whether quoting is enabled. + * + * All subclasses should call this quoteIdentifier() method rather than calling the Platform + * method directly. This method is used by both DataSQLBuilder and DDLBuilder, and potentially + * in the OM builders also, which is why it is defined in this class. + * + * @param string $text The text to quote. + * @return string Quoted text. + */ + public function quoteIdentifier($text) + { + if (!self::getBuildProperty('disableIdentifierQuoting')) { + return $this->getPlatform()->quoteIdentifier($text); + } + return $text; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ClassTools.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ClassTools.php new file mode 100644 index 000000000..9714139f2 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ClassTools.php @@ -0,0 +1,107 @@ +. + */ + + + /** + * Tools to support class & package inclusion and referencing. + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.engine.builder.om + */ +class ClassTools { + + /** + * Gets just classname, given a dot-path to class. + * @param string $qualifiedName + * @return string + */ + public static function classname($qualifiedName) + { + $pos = strrpos($qualifiedName, '.'); + if ($pos === false) { + return $qualifiedName; // there is no '.' in the qualifed name + } else { + return substr($qualifiedName, $pos + 1); // start just after '.' + } + } + + /** + * Gets the path to be used in include()/require() statement. + * + * Supports two function signatures: + * (1) getFilePath($dotPathClass); + * (2) getFilePath($dotPathPrefix, $className); + * + * @param string $path dot-path to class or to package prefix. + * @param string $classname class name + * @return string + */ + public static function getFilePath($path, $classname = null, $extension = '.php') + { + $path = strtr(ltrim($path, '.'), '.', '/'); + if ($classname !== null) { + if ($path !== "") { $path .= '/'; } + return $path . $classname . $extension; + } else { + return $path . $extension; + } + } + + /** + * Gets the basePeer path if specified for table/db. + * If not, will return 'propel.util.BasePeer' + * @return string + */ + public static function getBasePeer(Table $table) { + $class = $table->getBasePeer(); + if ($class === null) { + $class = "propel.util.BasePeer"; + } + return $class; + } + + /** + * Gets the baseClass path if specified for table/db. + * If not, will return 'propel.om.BaseObject' + * @return string + */ + public static function getBaseClass(Table $table) { + $class = $table->getBaseClass(); + if ($class === null) { + $class = "propel.om.BaseObject"; + } + return $class; + } + + /** + * Gets the interface path if specified for table. + * If not, will return 'propel.om.Persistent'. + * @return string + */ + public static function getInterface(Table $table) { + $interface = $table->getInterface(); + if ($interface === null && !$table->isReadOnly()) { + $interface = "propel.om.Persistent"; + } + return $interface; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/OMBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/OMBuilder.php new file mode 100644 index 000000000..bf4b106e2 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/OMBuilder.php @@ -0,0 +1,409 @@ +. + */ + +require_once 'propel/engine/builder/DataModelBuilder.php'; + +/** + * Baseclass for OM-building classes. + * + * OM-building classes are those that build a PHP (or other) class to service + * a single table. This includes Peer classes, Entity classes, Map classes, + * Node classes, etc. + * + * @author Hans Lellelid + * @package propel.engine.builder.om + */ +abstract class OMBuilder extends DataModelBuilder { + + /** + * Peer builder class for current table. + * @var DataModelBuilder + */ + private $peerBuilder; + + /** + * Stub Peer builder class for current table. + * @var DataModelBuilder + */ + private $stubPeerBuilder; + + /** + * Object builder class for current table. + * @var DataModelBuilder + */ + private $objectBuilder; + + /** + * Stub Object builder class for current table. + * @var DataModelBuilder + */ + private $stubObjectBuilder; + + /** + * MapBuilder builder class for current table. + * @var DataModelBuilder + */ + private $mapBuilderBuilder; + + /** + * Stub Interface builder class for current table. + * @var DataModelBuilder + */ + private $interfaceBuilder; + + /** + * Stub child object for current table. + * @var DataModelBuilder + */ + private $multiExtendObjectBuilder; + + /** + * Node object builder for current table. + * @var DataModelBuilder + */ + private $nodeBuilder; + + /** + * Node peer builder for current table. + * @var DataModelBuilder + */ + private $nodePeerBuilder; + + /** + * Stub node object builder for current table. + * @var DataModelBuilder + */ + private $stubNodeBuilder; + + /** + * Stub node peer builder for current table. + * @var DataModelBuilder + */ + private $stubNodePeerBuilder; + + + /** + * Returns new or existing Peer builder class for this table. + * @return DataModelBuilder + */ + public function getPeerBuilder() + { + if (!isset($this->peerBuilder)) { + $this->peerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'peer'); + } + return $this->peerBuilder; + } + + /** + * Returns new or existing stub Peer builder class for this table. + * @return DataModelBuilder + */ + public function getStubPeerBuilder() + { + if (!isset($this->stubPeerBuilder)) { + $this->stubPeerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'peerstub'); + } + return $this->stubPeerBuilder; + } + + /** + * Returns new or existing Object builder class for this table. + * @return DataModelBuilder + */ + public function getObjectBuilder() + { + if (!isset($this->objectBuilder)) { + $this->objectBuilder = DataModelBuilder::builderFactory($this->getTable(), 'object'); + } + return $this->objectBuilder; + + } + + /** + * Returns new or existing stub Object builder class for this table. + * @return DataModelBuilder + */ + public function getStubObjectBuilder() + { + if (!isset($this->stubObjectBuilder)) { + $this->stubObjectBuilder = DataModelBuilder::builderFactory($this->getTable(), 'objectstub'); + } + return $this->stubObjectBuilder; + } + + /** + * Returns new or existing MapBuilder builder class for this table. + * @return DataModelBuilder + */ + public function getMapBuilderBuilder() + { + if (!isset($this->mapBuilderBuilder)) { + $this->mapBuilderBuilder = DataModelBuilder::builderFactory($this->getTable(), 'mapbuilder'); + } + return $this->mapBuilderBuilder; + } + + /** + * Returns new or existing stub Interface builder class for this table. + * @return DataModelBuilder + */ + public function getInterfaceBuilder() + { + if (!isset($this->interfaceBuilder)) { + $this->interfaceBuilder = DataModelBuilder::builderFactory($this->getTable(), 'interface'); + } + return $this->interfaceBuilder; + } + + /** + * Returns new or existing stub child object builder class for this table. + * @return DataModelBuilder + */ + public function getMultiExtendObjectBuilder() + { + if (!isset($this->multiExtendObjectBuilder)) { + $this->multiExtendObjectBuilder = DataModelBuilder::builderFactory($this->getTable(), 'objectmultiextend'); + } + return $this->multiExtendObjectBuilder; + } + + /** + * Returns new or existing node Object builder class for this table. + * @return DataModelBuilder + */ + public function getNodeBuilder() + { + if (!isset($this->nodeBuilder)) { + $this->nodeBuilder = DataModelBuilder::builderFactory($this->getTable(), 'node'); + } + return $this->nodeBuilder; + } + + /** + * Returns new or existing node Peer builder class for this table. + * @return DataModelBuilder + */ + public function getNodePeerBuilder() + { + if (!isset($this->nodePeerBuilder)) { + $this->nodePeerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nodepeer'); + } + return $this->nodePeerBuilder; + } + + /** + * Returns new or existing stub node Object builder class for this table. + * @return DataModelBuilder + */ + public function getStubNodeBuilder() + { + if (!isset($this->stubNodeBuilder)) { + $this->stubNodeBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nodestub'); + } + return $this->stubNodeBuilder; + } + + /** + * Returns new or existing stub node Peer builder class for this table. + * @return DataModelBuilder + */ + public function getStubNodePeerBuilder() + { + if (!isset($this->stubNodePeerBuilder)) { + $this->stubNodePeerBuilder = DataModelBuilder::builderFactory($this->getTable(), 'nodepeerstub'); + } + return $this->stubNodePeerBuilder; + } + + /** + * Convenience method to return a NEW Peer class builder instance. + * This is used very frequently from the peer and object builders to get + * a peer builder for a RELATED table. + * @param Table $table + * @return PeerBuilder + */ + public static function getNewPeerBuilder(Table $table) + { + return DataModelBuilder::builderFactory($table, 'peer'); + } + + /** + * Convenience method to return a NEW Object class builder instance. + * This is used very frequently from the peer and object builders to get + * an object builder for a RELATED table. + * @param Table $table + * @return ObjectBuilder + */ + public static function getNewObjectBuilder(Table $table) + { + return DataModelBuilder::builderFactory($table, 'object'); + } + + /** + * Builds the PHP source for current class and returns it as a string. + * + * This is the main entry point and defines a basic structure that classes should follow. + * In most cases this method will not need to be overridden by subclasses. This method + * does assume that the output language is PHP code, so it will need to be overridden if + * this is not the case. + * + * @return string The resulting PHP sourcecode. + */ + public function build() + { + $script = "<" . "?php\n"; // intentional concatenation + $this->addIncludes($script); + $this->addClassOpen($script); + $this->addClassBody($script); + $this->addClassClose($script); + return $script; + } + + /** + * Returns the name of the current class being built. + * @return string + */ + abstract public function getClassname(); + + /** + * Gets the dot-path representation of current class being built. + * @return string + */ + public function getClasspath() + { + if ($this->getPackage()) { + $path = $this->getPackage() . '.' . $this->getClassname(); + } else { + $path = $this->getClassname(); + } + return $path; + } + + /** + * Gets the full path to the file for the current class. + * @return string + */ + public function getClassFilePath() + { + return parent::getFilePath($this->getPackage(), $this->getClassname()); + } + + /** + * Gets package name for this table. + * This is overridden by child classes that have different packages. + * @return string + */ + public function getPackage() + { + $pkg = ($this->getTable()->getPackage() ? $this->getTable()->getPackage() : $this->getDatabase()->getPackage()); + if (!$pkg) { + $pkg = $this->getBuildProperty('targetPackage'); + } + return $pkg; + } + + /** + * Returns filesystem path for current package. + * @return string + */ + public function getPackagePath() + { + return strtr($this->getPackage(), '.', '/'); + } + + /** + * Shortcut method to return the [stub] peer classname for current table. + * This is the classname that is used whenever object or peer classes want + * to invoke methods of the peer classes. + * @return string (e.g. 'MyPeer') + * @see StubPeerBuilder::getClassname() + */ + public function getPeerClassname() { + return $this->getStubPeerBuilder()->getClassname(); + } + + /** + * Returns the object classname for current table. + * This is the classname that is used whenever object or peer classes want + * to invoke methods of the object classes. + * @return string (e.g. 'My') + * @see StubPeerBuilder::getClassname() + */ + public function getObjectClassname() { + return $this->getStubObjectBuilder()->getClassname(); + } + + /** + * Get the column constant name (e.g. PeerName::COLUMN_NAME). + * + * @param Column $col The column we need a name for. + * @param string $phpName The PHP Name of the peer class. The 'Peer' is appended automatically. + * + * @return string If $phpName is provided, then will return {$phpName}Peer::COLUMN_NAME; if not, then uses current table COLUMN_NAME. + */ + public function getColumnConstant($col, $phpName = null) + { + if ($col === null) { + $e = new Exception("No col specified."); + print $e; + throw $e; + } + $classname = $this->getPeerClassname($phpName); + + // was it overridden in schema.xml ? + if ($col->getPeerName()) { + $const = strtoupper($col->getPeerName()); + } else { + $const = strtoupper($col->getName()); + } + return $classname.'::'.$const; + } + + /** + * Gets just classname, given a dot-path to class. + * @param string $qualifiedName + * @return string + */ + public function classname($qualifiedName) + { + $pos = strrpos($qualifiedName, '.'); + if ($pos === false) { + return $qualifiedName; // there is no '.' in the qualifed name + } else { + return substr($qualifiedName, $pos + 1); // start just after '.' + } + } + + /** + * Gets the basePeer path if specified for table/db. + * If not, will return 'propel.util.BasePeer' + * @return string + */ + public function getBasePeer(Table $table) { + $class = $table->getBasePeer(); + if ($class === null) { + $class = "propel.util.BasePeer"; + } + return $class; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php new file mode 100644 index 000000000..709696e4f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php @@ -0,0 +1,148 @@ +. + */ + +require_once 'propel/engine/builder/om/OMBuilder.php'; + +/** + * Base class for Peer-building classes. + * + * This class is designed so that it can be extended by a PHP4PeerBuilder in addition + * to the "standard" PHP5PeerBuilder and PHP5ComplexOMPeerBuilder. Hence, this class + * should not have any actual template code in it -- simply basic logic & utility + * methods. + * + * @author Hans Lellelid + */ +abstract class ObjectBuilder extends OMBuilder { + + /** + * Constructs a new PeerBuilder subclass. + */ + public function __construct(Table $table) { + parent::__construct($table); + } + + /** + * This method adds the contents of the generated class to the script. + * + * This method is abstract and should be overridden by the subclasses. + * + * Hint: Override this method in your subclass if you want to reorganize or + * drastically change the contents of the generated peer class. + * + * @param string &$script The script will be modified in this method. + */ + abstract protected function addClassBody(&$script); + + /** + * Adds the getter methods for the column values. + * This is here because it is probably generic enough to apply to templates being generated + * in different langauges (e.g. PHP4 and PHP5). + * @param string &$script The script will be modified in this method. + */ + protected function addColumnAccessorMethods(&$script) + { + $table = $this->getTable(); + + foreach ($table->getColumns() as $col) { + + if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + $this->addTemporalAccessor($script, $col); + } else { + $this->addGenericAccessor($script, $col); + } + if ($col->isLazyLoad()) { + $this->addLazyLoader($script, $col); + } + } + } + + /** + * Adds the mutator (setter) methods for setting column values. + * This is here because it is probably generic enough to apply to templates being generated + * in different langauges (e.g. PHP4 and PHP5). + * @param string &$script The script will be modified in this method. + */ + protected function addColumnMutatorMethods(&$script) + { + foreach ($this->getTable()->getColumns() as $col) { + + if ($col->isLob()) { + $this->addLobMutator($script, $col); + } elseif ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + $this->addTemporalMutator($script, $col); + } else { + $this->addDefaultMutator($script, $col); + } + } + } + + + /** + * Gets the baseClass path if specified for table/db. + * If not, will return 'propel.om.BaseObject' + * @return string + */ + protected function getBaseClass() { + $class = $this->getTable()->getBaseClass(); + if ($class === null) { + $class = "propel.om.BaseObject"; + } + return $class; + } + + /** + * Gets the interface path if specified for current table. + * If not, will return 'propel.om.Persistent'. + * @return string + */ + protected function getInterface() { + $interface = $this->getTable()->getInterface(); + if ($interface === null && !$this->getTable()->isReadOnly()) { + $interface = "propel.om.Persistent"; + } + return $interface; + } + + /** + * Whether to add the generic mutator methods (setByName(), setByPosition(), fromArray()). + * This is based on the build property propel.addGenericMutators, and also whether the + * table is read-only or an alias. + */ + protected function isAddGenericMutators() + { + $table = $this->getTable(); + return (!$table->isAlias() && $this->getBuildProperty('addGenericMutators') && !$table->isReadOnly()); + } + + /** + * Whether to add the generic accessor methods (getByName(), getByPosition(), toArray()). + * This is based on the build property propel.addGenericAccessors, and also whether the + * table is an alias. + */ + protected function isAddGenericAccessors() + { + $table = $this->getTable(); + return (!$table->isAlias() && $this->getBuildProperty('addGenericAccessors')); + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php new file mode 100644 index 000000000..5777be36c --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php @@ -0,0 +1,269 @@ +. + */ + +require_once 'propel/engine/builder/om/OMBuilder.php'; + +/** + * Base class for Peer-building classes. + * + * This class is designed so that it can be extended by a PHP4PeerBuilder in addition + * to the "standard" PHP5PeerBuilder and PHP5ComplexOMPeerBuilder. Hence, this class + * should not have any actual template code in it -- simply basic logic & utility + * methods. + * + * @author Hans Lellelid + */ +abstract class PeerBuilder extends OMBuilder { + + protected $basePeerClass; + protected $basePeerClassname; + + /** + * Constructs a new PeerBuilder subclass. + */ + public function __construct(Table $table) { + parent::__construct($table); + $this->basePeerClass = $this->getBasePeer($table); + $this->basePeerClassname = $this->classname($this->basePeerClass); + } + + /** + * Adds the addSelectColumns(), doCount(), etc. methods. + * @param string &$script The script will be modified in this method. + */ + protected function addSelectMethods(&$script) + { + $this->addAddSelectColumns($script); + + $this->addCountConstants($script); + $this->addDoCount($script); + + // consider refactoring the doSelect stuff + // into a top-level method + $this->addDoSelectOne($script); + $this->addDoSelect($script); + $this->addDoSelectRS($script); // <-- there's Creole code in here + $this->addPopulateObjects($script); // <-- there's Creole code in here + + } + + /** + * Adds the correct getOMClass() method, depending on whether this table uses inheritance. + * @param string &$script The script will be modified in this method. + */ + protected function addGetOMClassMethod(&$script) + { + $table = $this->getTable(); + if ($table->getChildrenColumn()) { + if ($table->isAbstract()) { + $this->addGetOMClass_Inheritance_Abstract($script); + } else { + $this->addGetOMClass_Inheritance($script); + } + } else { + if ($table->isAbstract()) { + $this->addGetOMClass_NoInheritance_Abstract($script); + } else { + $this->addGetOMClass_NoInheritance($script); + } + } + } + + /** + * Adds the doInsert(), doUpdate(), doDeleteAll(), doValidate(), etc. methods. + * @param string &$script The script will be modified in this method. + */ + protected function addUpdateMethods(&$script) + { + $this->addDoInsert($script); + $this->addDoUpdate($script); + $this->addDoDeleteAll($script); + $this->addDoDelete($script); + if ($this->isDeleteCascadeEmulationNeeded()) { + $this->addDoOnDeleteCascade($script); + } + if ($this->isDeleteSetNullEmulationNeeded()) { + $this->addDoOnDeleteSetNull($script); + } + $this->addDoValidate($script); + } + + /** + * Adds the retrieveByPK() (and possibly retrieveByPKs()) method(s) appropriate for this class. + * @param string &$script The script will be modified in this method. + */ + protected function addRetrieveByPKMethods(&$script) + { + if (count($this->getTable()->getPrimaryKey()) === 1) { + $this->addRetrieveByPK_SinglePK($script); + $this->addRetrieveByPKs_SinglePK($script); + } else { + $this->addRetrieveByPK_MultiPK($script); + } + } + + /** + * This method adds the contents of the generated class to the script. + * + * This method contains the high-level logic that determines which methods + * get generated. + * + * Hint: Override this method in your subclass if you want to reorganize or + * drastically change the contents of the generated peer class. + * + * @param string &$script The script will be modified in this method. + */ + protected function addClassBody(&$script) + { + + $table = $this->getTable(); + + if (!$table->isAlias()) { + $this->addConstantsAndAttributes($script); + } + + $this->addGetMapBuilder($script); + $this->addGetPhpNameMap($script); + + $this->addTranslateFieldName($script); + $this->addGetFieldNames($script); + + if (!$table->isAlias()) { + $this->addAlias($script); // alias() utility method (deprecated?) + $this->addSelectMethods($script); + $this->addGetTableMap($script); + } + + $this->addGetOMClassMethod($script); + + // add the insert, update, delete, validate etc. methods + if (!$table->isAlias() && !$table->isReadOnly()) { + $this->addUpdateMethods($script); + } + + if (count($table->getPrimaryKey()) > 0) { + $this->addRetrieveByPKMethods($script); + } + } + + /** + * Whether the platform in use requires ON DELETE CASCADE emulation and whether there are references to this table. + * @return boolean + */ + protected function isDeleteCascadeEmulationNeeded() + { + $table = $this->getTable(); + if ((!$this->getPlatform()->supportsNativeDeleteTrigger() || $this->getBuildProperty('emulateForeignKeyConstraints')) && count($table->getReferrers()) > 0) { + foreach ($table->getReferrers() as $fk) { + if ($fk->getOnDelete() == ForeignKey::CASCADE) { + return true; + } + } + } + return false; + } + + /** + * Whether the platform in use requires ON DELETE SETNULL emulation and whether there are references to this table. + * @return boolean + */ + protected function isDeleteSetNullEmulationNeeded() + { + $table = $this->getTable(); + if ((!$this->getPlatform()->supportsNativeDeleteTrigger() || $this->getBuildProperty('emulateForeignKeyConstraints')) && count($table->getReferrers()) > 0) { + foreach ($table->getReferrers() as $fk) { + if ($fk->getOnDelete() == ForeignKey::SETNULL) { + return true; + } + } + } + return false; + } + + /** + * Whether to add the generic mutator methods (setByName(), setByPosition(), fromArray()). + * This is based on the build property propel.addGenericMutators, and also whether the + * table is read-only or an alias. + * @return boolean + */ + protected function isAddGenericMutators() + { + $table = $this->getTable(); + return (!$table->isAlias() && $this->getBuildProperty('addGenericMutators') && !$table->isReadOnly()); + } + + /** + * Whether to add the generic accessor methods (getByName(), getByPosition(), toArray()). + * This is based on the build property propel.addGenericAccessors, and also whether the + * table is an alias. + * @return boolean + */ + protected function isAddGenericAccessors() + { + $table = $this->getTable(); + return (!$table->isAlias() && $this->getBuildProperty('addGenericAccessors')); + } + + /** + * Returns the retrieveByPK method name to use for this table. + * If the table is an alias then the method name looks like "retrieveTablenameByPK" + * otherwise simply "retrieveByPK". + * @return string + */ + public function getRetrieveMethodName() + { + if ($this->getTable()->isAlias()) { + $retrieveMethod = "retrieve" . $this->getTable()->getPhpName() . "ByPK"; + } else { + $retrieveMethod = "retrieveByPK"; + } + return $retrieveMethod; + } + + + /** + * COMPATIBILITY: Get the column constant name (e.g. PeerName::COLUMN_NAME). + * + * This method exists simply because it belonged to the 'PeerBuilder' that this + * class is replacing (because of name conflict more than actual functionality overlap). + * When the new builder model is finished this method will be removed. + * + * @param Column $col The column we need a name for. + * @param string $phpName The PHP Name of the peer class. The 'Peer' is appended automatically. + * + * @return string If $phpName is provided, then will return {$phpName}Peer::COLUMN_NAME; if not, just COLUMN_NAME. + * @deprecated + */ + public static function getColumnName(Column $col, $phpName = null) { + // was it overridden in schema.xml ? + if ($col->getPeerName()) { + $const = strtoupper($col->getPeerName()); + } else { + $const = strtoupper($col->getName()); + } + if ($phpName !== null) { + return $phpName . 'Peer::' . $const; + } else { + return $const; + } + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php new file mode 100644 index 000000000..83f4a6a64 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php @@ -0,0 +1,1414 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates a PHP5 base Object class for user object model (OM). + * + * This class produces the base object class (e.g. BaseMyTable) which contains all + * the custom-built accessor and setter methods. + * + * This class replaces the Object.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5BasicObjectBuilder extends ObjectBuilder { + + /** + * Gets the package for the [base] object classes. + * @return string + */ + public function getPackage() + { + return parent::getPackage() . ".om"; + } + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getClassname(); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + + $table = $this->getTable(); + $package = $this->getPackage(); + $parentClass = $this->getBaseClass(); + $interface = $this->getInterface(); + + $script .= " +require_once '".$this->getFilePath($parentClass)."'; +"; + + + + if (!empty($interface)) { + $script .= " +require_once '".$this->getFilePath($interface)."'; +"; + } + + + if (!$table->isAlias()) { + + // If any columns in table are BLOB or CLOB then we need to make + // sure those classes are included so we can do things like + // if ($v instanceof Lob) etc. + + $includes_lobs = false; + foreach ($table->getColumns() as $col) { + if ($col->isLob()) { + $includes_lobs = true; + break; + } + } + + if($includes_lobs) { + $script .= " +include_once 'creole/util/Clob.php'; +include_once 'creole/util/Blob.php'; +"; + } + } // if table is not alias + + $script .= " + +include_once 'propel/util/Criteria.php'; +"; + + $script .= " +include_once '".$this->getStubPeerBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + $interface = $this->getInterface(); + + $script .= " +/** + * Base class that represents a row from the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * @package ".$this->getPackage()." + */ +abstract class ".$this->getClassname()." extends ".ClassTools::classname($this->getBaseClass())." "; + + $interface = ClassTools::getInterface($table); + if ($interface) { + $script .= " implements " . ClassTools::classname($interface); + } + + $script .= " { + +"; + } + + /** + * Specifies the methods that are added as part of the basic OM class. + * This can be overridden by subclasses that wish to add more methods. + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $table = $this->getTable(); + if (!$table->isAlias()) { + $this->addConstants($script); + $this->addAttributes($script); + } + + $this->addColumnAccessorMethods($script); + $this->addColumnMutatorMethods($script); + + $this->addHydrate($script); + + $this->addManipulationMethods($script); + $this->addValidationMethods($script); + + if ($this->isAddGenericAccessors()) { + $this->addGetByName($script); + $this->addGetByPosition($script); + $this->addToArray($script); + } + + if ($this->isAddGenericMutators()) { + $this->addSetByName($script); + $this->addSetByPosition($script); + $this->addFromArray($script); + } + + $this->addBuildCriteria($script); + $this->addBuildPkeyCriteria($script); + $this->addGetPrimaryKey($script); + $this->addSetPrimaryKey($script); + + $this->addCopy($script); + + if (!$table->isAlias()) { + $this->addGetPeer($script); + } + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + + /** + * Adds any constants to the class. + * @param string &$script The script will be modified in this method. + */ + protected function addConstants(&$script) + { + // nothing to do here any more + // fieldnameTypeConstants have been moved to class BasePeer [sv] + } + + /** + * Adds class attributes. + * @param string &$script The script will be modified in this method. + */ + protected function addAttributes(&$script) + { + $script .= " + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ".$this->getPeerClassname()." + */ + protected static \$peer; +"; + if (!$this->getTable()->isAlias()) { + $this->addColumnAttributes($script); + } + } + + /** + * Adds variables that store column values. + * @param string &$script The script will be modified in this method. + * @see addColumnNameConstants() + */ + protected function addColumnAttributes(&$script) { + + $table = $this->getTable(); + + foreach ($table->getColumns() as $col) { + + $cptype = $col->getPhpNative(); + $clo=strtolower($col->getName()); + $defVal = ""; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $cptype); + $defaultValue = var_export($val, true); + $defVal = " = " . $defaultValue; + } + + $script .= " + + /** + * The value for the $clo field. + * @var $cptype + */ + protected \$" . $clo . $defVal . "; +"; + + if ($col->isLazyLoad()) { + $script .= " + /** + * Whether the lazy-loaded $clo value has been loaded from database. + * This is necessary to avoid repeated lookups if $clo column is NULL in the db. + * @var boolean + */ + protected \$".$clo."_isLoaded = false; +"; + } + + } // foreach col + + } // addColumnAttributes() + + /** + * Adds the getPeer() method. + * This is a convenient, non introspective way of getting the Peer class for a particular object. + * @param string &$script The script will be modified in this method. + */ + protected function addGetPeer(&$script) + { + $script .= " + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ".$this->getPeerClassname()." + */ + public function getPeer() + { + if (self::\$peer === null) { + self::\$peer = new ".$this->getPeerClassname()."(); + } + return self::\$peer; + } +"; + } + + // -------------------------------------------------------------- + // + // A C C E S S O R M E T H O D S + // + // -------------------------------------------------------------- + + /** + * Adds a date/time/timestamp getter method. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnAccessors() + */ + protected function addTemporalAccessor(&$script, $col) + { + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + + // these default values are based on the Creole defaults + // the date and time default formats are locale-sensitive + if ($col->getType() === PropelTypes::DATE) { + $defaultfmt = $this->getBuildProperty('defaultDateFormat'); + } elseif ($col->getType() === PropelTypes::TIME) { + $defaultfmt = $this->getBuildProperty('defaultTimeFormat'); + } elseif ($col->getType() === PropelTypes::TIMESTAMP) { + $defaultfmt = $this->getBuildProperty('defaultTimeStampFormat'); + } + + // if the default format property was an empty string, then we'll set it + // to NULL, which will return the "native" integer timestamp + if (empty($defaultfmt)) { $defaultfmt = null; } + + $script .= " + /** + * Get the [optionally formatted] [$clo] column value. + * ".$col->getDescription()." + * @param string \$format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function get$cfc(\$format = ".var_export($defaultfmt, true).""; + if ($col->isLazyLoad()) $script .= ", \$con = null"; + $script .= ") + { +"; + if ($col->isLazyLoad()) { + $script .= " + if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) { + \$this->load$cfc(\$con); + } +"; + } + $script .= " + if (\$this->$clo === null || \$this->$clo === '') { + return null; + } elseif (!is_int(\$this->$clo)) { + // a non-timestamp value was set externally, so we convert it + \$ts = strtotime(\$this->$clo); + if (\$ts === -1 || \$ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException(\"Unable to parse value of [$clo] as date/time value: \" . var_export(\$this->$clo, true)); + } + } else { + \$ts = \$this->$clo; + } + if (\$format === null) { + return \$ts; + } elseif (strpos(\$format, '%') !== false) { + return strftime(\$format, \$ts); + } else { + return date(\$format, \$ts); + } + } +"; + } // addTemporalAccessor + + /** + * Adds a normal (non-temporal) getter method. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnAccessors() + */ + protected function addGenericAccessor(&$script, $col) + { + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + + $script .= " + /** + * Get the [$clo] column value. + * ".$col->getDescription()." + * @return ".$col->getPhpNative()." + */ + public function get$cfc("; + if ($col->isLazyLoad()) $script .= "\$con = null"; + $script .= ") + { +"; + if ($col->isLazyLoad()) { + $script .= " + if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) { + \$this->load$cfc(\$con); + } +"; + } + $script .= " + return \$this->$clo; + } +"; + } + + /** + * Adds the lazy loader method. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnAccessors() + */ + protected function addLazyLoader(&$script, $col) + { + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + + $script .= " + /** + * Load the value for the lazy-loaded [$clo] column. + * + * This method performs an additional query to return the value for + * the [$clo] column, since it is not populated by + * the hydrate() method. + * + * @param \$con Connection + * @return void + * @throws PropelException - any underlying error will be wrapped and re-thrown. + */ + protected function load$cfc(\$con = null) + { + \$c = \$this->buildPkeyCriteria(); + \$c->addSelectColumn(".$this->getColumnConstant($col)."); + try { + \$rs = ".$this->getPeerClassname()."::doSelectRS(\$c, \$con); + \$rs->next(); +"; + $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) { + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: + $script .= " + \$this->$clo = \$rs->get$affix(1, null); +"; + break; + default: + $script .= " + \$this->$clo = \$rs->get$affix(1); +"; + } // switch + $script .= " + \$this->".$clo."_isLoaded = true; + } catch (Exception \$e) { + throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e); + } + } +"; + + } // addLazyLoader() + + + + // -------------------------------------------------------------- + // + // M U T A T O R M E T H O D S + // + // -------------------------------------------------------------- + + /** + * Adds the open of the mutator (setter) method for a column. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + */ + protected function addMutatorOpen(&$script, Column $col) + { + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + + $script .= " + /** + * Set the value of [$clo] column. + * ".$col->getDescription()." + * @param ".$col->getPhpNative()." \$v new value + * @return void + */ + public function set$cfc(\$v) + { +"; + if ($col->isLazyLoad()) { + $script .= " + // explicitly set the is-loaded flag to true for this lazy load col; + // it doesn't matter if the value is actually set or not (logic below) as + // any attempt to set the value means that no db lookup should be performed + // when the get$cfc() method is called. + \$this->".$clo."_isLoaded = true; +"; + } + + } + + /** + * Adds the close of the mutator (setter) method for a column. + * This can be overridden (e.g. by PHP5ComplexObjectBuilder) if additional functionality is needed. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + */ + protected function addMutatorClose(&$script, Column $col) + { + $script .= " + } // set".$col->getPhpName()."() +"; + } + + /** + * Adds a setter for date/time/timestamp columns. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnMutators() + */ + protected function addLobMutator(&$script, Column $col) + { + $this->addMutatorOpen($script, $col); + $clo = strtolower($col->getName()); + // Setting of LOB columns gets some special handling + + if ($col->getPropelType() === PropelTypes::BLOB || $col->getPropelType() === PropelTypes::LONGVARBINARY ) { + $lobClass = 'Blob'; + } else { + $lobClass = 'Clob'; + } + $script .= " + // if the passed in parameter is the *same* object that + // is stored internally then we use the Lob->isModified() + // method to know whether contents changed. + if (\$v instanceof Lob && \$v === \$this->$clo) { + \$changed = \$v->isModified(); + } else { + \$changed = (\$this->$clo !== \$v); + } + if (\$changed) { + if ( !(\$v instanceof Lob) ) { + \$obj = new $lobClass(); + \$obj->setContents(\$v); + } else { + \$obj = \$v; + } + \$this->$clo = \$obj; + \$this->modifiedColumns[] = ".$this->getColumnConstant($col)."; + } +"; + $this->addMutatorClose($script, $col); + + } // addLobMutatorSnippet + + + /** + * Adds a setter method for date/time/timestamp columns. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnMutators() + */ + protected function addTemporalMutator(&$script, Column $col) + { + $clo = strtolower($col->getName()); + + $defaultValue = null; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $col->getPhpNative()); + $defaultValue = var_export($val, true); + } + + $this->addMutatorOpen($script, $col); + + $script .= " + if (\$v !== null && !is_int(\$v)) { + \$ts = strtotime(\$v); + if (\$ts === -1 || \$ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException(\"Unable to parse date/time value for [$clo] from input: \" . var_export(\$v, true)); + } + } else { + \$ts = \$v; + } + if (\$this->$clo !== \$ts"; + if ($defaultValue !== null) { + $script .= " || \$ts === $defaultValue"; + } + $script .= ") { + \$this->$clo = \$ts; + \$this->modifiedColumns[] = ".$this->getColumnConstant($col)."; + } +"; + $this->addMutatorClose($script, $col); + } + + /** + * Adds setter method for "normal" columns. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see parent::addColumnMutators() + */ + protected function addDefaultMutator(&$script, Column $col) + { + $clo = strtolower($col->getName()); + + // FIXME: refactor this + $defaultValue = null; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $col->getPhpNative()); + $defaultValue = var_export($val, true); + } + + $this->addMutatorOpen($script, $col); + + // Perform some smart checking here to handle possible type discrepancies + // between the passed-in value and the value from the DB + + if ($col->getPhpNative() === "int") { + $script .= " + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if (\$v !== null && !is_int(\$v) && is_numeric(\$v)) { + \$v = (int) \$v; + } +"; + } elseif ($col->getPhpNative() === "string") { + $script .= " + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if (\$v !== null && !is_string(\$v)) { + \$v = (string) \$v; + } +"; + } + + $script .= " + if (\$this->$clo !== \$v"; + if ($defaultValue !== null) { + $script .= " || \$v === $defaultValue"; + } + $script .= ") { + \$this->$clo = \$v; + \$this->modifiedColumns[] = ".$this->getColumnConstant($col)."; + } +"; + $this->addMutatorClose($script, $col); + } + + /** + * Adds the hydrate() method, which sets attributes of the object based on a ResultSet. + */ + protected function addHydrate(&$script) + { + $table = $this->getTable(); + + $script .= " + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based \"start column\") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet \$rs The ResultSet class with cursor advanced to desired record pos. + * @param int \$startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet \$rs, \$startcol = 1) + { + try { +"; + $n = 0; + foreach($table->getColumns() as $col) { + if(!$col->isLazyLoad()) { + $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) { + + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: + $script .= " + \$this->$clo = \$rs->get$affix(\$startcol + $n, null); +"; + break; + default: + $script .= " + \$this->$clo = \$rs->get$affix(\$startcol + $n); +"; + } + $n++; + } // if col->isLazyLoad() + } /* foreach */ + + if ($this->getBuildProperty("addSaveMethod")) { + $script .= " + \$this->resetModified(); +"; + } + + $script .= " + \$this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception \$e) { + throw new PropelException(\"Error populating ".$table->getPhpName()." object\", \$e); + } + } +"; + + } // addHydrate() + + + /** + * + */ + protected function addBuildPkeyCriteria(&$script) { + + + $script .= " + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME); +"; + foreach ($this->getTable()->getColumns() as $col) { + $clo = strtolower($col->getName()); + if ($col->isPrimaryKey()) { + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);"; + } + } + + $script .= " + + return \$criteria; + } +"; + + } + + /** + * + */ + protected function addBuildCriteria(&$script) + { + $script .= " + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME); +"; + foreach ($this->getTable()->getColumns() as $col) { + $clo = strtolower($col->getName()); + $script .= " + if (\$this->isColumnModified(".$this->getColumnConstant($col).")) \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);"; + } + $script .= " + + return \$criteria; + } +"; + } // addBuildCriteria() + + protected function addToArray(&$script) + { + $script .= " + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string \$keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray(\$keyType = BasePeer::TYPE_PHPNAME) + { + \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType); + \$result = array("; + foreach ($this->getTable()->getColumns() as $num => $col) { + $script .= " + \$keys[$num] => \$this->get".$col->getPhpName()."(),"; + } + $script .= " + ); + return \$result; + } +"; + } // addToArray() + + protected function addGetByName(&$script) + { + $script .= " + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string \$name name + * @param string \$type The type of fieldname the \$name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName(\$name, \$type = BasePeer::TYPE_PHPNAME) + { + \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM); + return \$this->getByPosition(\$pos); + } +"; + } + + protected function addGetByPosition(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int \$pos position in xml schema + * @return mixed Value of field at \$pos + */ + public function getByPosition(\$pos) + { + switch(\$pos) {"; + $i = 0; + foreach ($table->getColumns() as $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative();// not safe to use it because some methods may return objects (Blob) +$script .= " + case $i: + return \$this->get$cfc(); + break;"; + $i++; + } /* foreach */ +$script .= " + default: + return null; + break; + } // switch() + } +"; + } + + protected function addSetByName(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Sets a field from the object by name passed in as a string. + * + * @param string \$name peer name + * @param mixed \$value field value + * @param string \$type The type of fieldname the \$name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName(\$name, \$value, \$type = BasePeer::TYPE_PHPNAME) + { + \$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM); + return \$this->setByPosition(\$pos, \$value); + } +"; + } + + protected function addSetByPosition(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int \$pos position in xml schema + * @param mixed \$value field value + * @return void + */ + public function setByPosition(\$pos, \$value) + { + switch(\$pos) {"; + $i = 0; + foreach ($table->getColumns() as $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); + $script .= " + case $i: + \$this->set$cfc(\$value); + break;"; + $i++; + } /* foreach */ + $script .= " + } // switch() + } +"; + } // addSetByPosition() + + protected function addFromArray(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. \$_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array \$arr An array to populate the object from. + * @param string \$keyType The type of keys the array uses. + * @return void + */ + public function fromArray(\$arr, \$keyType = BasePeer::TYPE_PHPNAME) + { + \$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType); +"; + foreach ($table->getColumns() as $num => $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); + $script .= " + if (array_key_exists(\$keys[$num], \$arr)) \$this->set$cfc(\$arr[\$keys[$num]]);"; + } /* foreach */ + $script .= " + } +"; + } // addFromArray + + + + protected function addDelete(&$script) + { + $script .= " + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection \$con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete(\$con = null) + { + if (\$this->isDeleted()) { + throw new PropelException(\"This object has already been deleted.\"); + } + + if (\$con === null) { + \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); + } + + try { + \$con->begin(); + ".$this->getPeerClassname()."::doDelete(\$this, \$con); + \$this->setDeleted(true); + \$con->commit(); + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + } +"; + } // addDelete() + + /** + * Adds the methods related to saving and deleting the object. + * @param string &$script The script will be modified in this method. + */ + protected function addManipulationMethods(&$script) + { + $this->addDelete($script); + $this->addSave($script); + } + + /** + * Adds the methods related to validationg the object. + * @param string &$script The script will be modified in this method. + */ + protected function addValidationMethods(&$script) + { + $this->addValidationFailuresAttribute($script); + $this->addGetValidationFailures($script); + $this->addValidate($script); + } + + /** + * Adds the save() method. + * @param string &$script The script will be modified in this method. + */ + protected function addSave(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * + * @param Connection \$con + * @return int The number of rows affected by this insert/update operation (for non-complex OM this will be at most 1). + * @throws PropelException + */ + public function save(\$con = null) + { + \$affectedRows = 0; // initialize var to track total num of affected rows + + // If this object has been modified, then save it to the database. + if (\$this->isModified()) { + if (\$this->isNew()) { + \$pk = ".$this->getPeerClassname()."::doInsert(\$this, \$con); + \$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). +"; + if ($table->getIdMethod() != "none") { + if (count($pks = $table->getPrimaryKey())) { + foreach ($pks as $pk) { + if ($pk->isAutoIncrement()) { + $script .= " + \$this->set".$pk->getPhpName()."(\$pk); //[IMV] update autoincrement primary key +"; + } + } + } + } + $script .= " + \$this->setNew(false); + } else { + \$affectedRows += ".$this->getPeerClassname()."::doUpdate(\$this, \$con); + } + \$this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } // if \$this->isModified() + + return \$affectedRows; + } // save() +"; + + } // addSave() + + /** + * Adds the $validationFailures attribute to store ValidationFailed objects. + * @param string &$script The script will be modified in this method. + */ + protected function addValidationFailuresAttribute(&$script) + { + $script .= " + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected \$validationFailures = array(); +"; + } + + /** + * Adds the validate() method. + * @param string &$script The script will be modified in this method. + */ + protected function addValidate(&$script) + { + $script .= " + /** + * Validates the objects modified field values. + * + * If \$columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed \$columns Column name or an array of column names. + * + * @return mixed true if all columns pass validation + * or an array of ValidationFailed objects for columns that fail. + */ + public function validate(\$columns = null) + { + if (\$columns) { + return ".$this->getPeerClassname()."::doValidate(\$this, \$columns); + } + return ".$this->getPeerClassname()."::doValidate(\$this); + } +"; + + } // addValidate() + + /** + * Adds the getValidationFailures() method. + * @param string &$script The script will be modified in this method. + */ + protected function addGetValidationFailures(&$script) + { + $script .= " + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return \$this->validationFailures; + } +"; + } // addGetValidationFailures() + + /** + * Adds the correct getPrimaryKey() method for this object. + * @param string &$script The script will be modified in this method. + */ + protected function addGetPrimaryKey(&$script) + { + $pkeys = $this->getTable()->getPrimaryKey(); + if (count($pkeys) == 1) { + $this->addGetPrimaryKey_SinglePK($script); + } elseif (count($pkeys) > 1) { + $this->addGetPrimaryKey_MultiPK($script); + } else { + // no primary key -- this is deprecated, since we don't *need* this method anymore + $this->addGetPrimaryKey_NoPK($script); + } + } + + /** + * Adds the getPrimaryKey() method for tables that contain a single-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addGetPrimaryKey_SinglePK(&$script) + { + $table = $this->getTable(); + $pkeys = $table->getPrimaryKey(); + $cptype = $pkeys[0]->getPhpType(); + + $script .= " + /** + * Returns the primary key for this object (row). + * @return $cptype + */ + public function getPrimaryKey() + { + return \$this->get".$pkeys[0]->getPhpName()."(); + } +"; + } // addetPrimaryKey_SingleFK + + /** + * Adds the setPrimaryKey() method for tables that contain a multi-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addGetPrimaryKey_MultiPK(&$script) + { + + $script .= " + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + \$pks = array(); +"; + $i = 0; + foreach ($this->getTable()->getPrimaryKey() as $pk) { + $script .= " + \$pks[$i] = \$this->get".$pk->getPhpName()."(); +"; + $i++; + } /* foreach */ + $script .= " + return \$pks; + } +"; + } // addGetPrimaryKey_MultiFK() + + /** + * Adds the getPrimaryKey() method for objects that have no primary key. + * This "feature" is dreprecated, since the getPrimaryKey() method is not required + * by the Persistent interface (or used by the templates). Hence, this method is also + * deprecated. + * @param string &$script The script will be modified in this method. + * @deprecated + */ + protected function addGetPrimaryKey_NoPK(&$script) + { + $script .= " + /** + * Returns NULL since this table doesn't have a primary key. + * This method exists only for BC and is deprecated! + * @return null + */ + public function getPrimaryKey() + { + return null; + } +"; + } + /** + * Adds the correct setPrimaryKey() method for this object. + * @param string &$script The script will be modified in this method. + */ + protected function addSetPrimaryKey(&$script) + { + $pkeys = $this->getTable()->getPrimaryKey(); + if (count($pkeys) == 1) { + $this->addSetPrimaryKey_SinglePK($script); + } elseif (count($pkeys) > 1) { + $this->addSetPrimaryKey_MultiPK($script); + } else { + // no primary key -- this is deprecated, since we don't *need* this method anymore + $this->addSetPrimaryKey_NoPK($script); + } + } + + /** + * Adds the setPrimaryKey() method for tables that contain a single-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addSetPrimaryKey_SinglePK(&$script) + { + + $pkeys = $this->getTable()->getPrimaryKey(); + $col = $pkeys[0]; + $clo=strtolower($col->getName()); + $ctype = $col->getPhpNative(); + + $script .= " + /** + * Generic method to set the primary key ($clo column). + * + * @param $ctype \$key Primary key. + * @return void + */ + public function setPrimaryKey(\$key) + { + \$this->set".$col->getPhpName()."(\$key); + } +"; + } // addSetPrimaryKey_SinglePK + + /** + * Adds the setPrimaryKey() method for tables that contain a multi-columnprimary key. + * @param string &$script The script will be modified in this method. + */ + protected function addSetPrimaryKey_MultiPK(&$script) + { + + $script .=" + /** + * Set the [composite] primary key. + * + * @param array \$keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey(\$keys) + { +"; + $i = 0; + foreach ($this->getTable()->getPrimaryKey() as $pk) { + $pktype = $pk->getPhpNative(); + $script .= " + \$this->set".$pk->getPhpName()."(\$keys[$i]); +"; + $i++; + } /* foreach ($table->getPrimaryKey() */ + $script .= " + } +"; + } // addSetPrimaryKey_MultiPK + + /** + * Adds the setPrimaryKey() method for objects that have no primary key. + * This "feature" is dreprecated, since the setPrimaryKey() method is not required + * by the Persistent interface (or used by the templates). Hence, this method is also + * deprecated. + * @param string &$script The script will be modified in this method. + * @deprecated + */ + protected function addSetPrimaryKey_NoPK(&$script) + { + $script .=" + /** + * Dummy primary key setter. + * + * This function only exists to preserve backwards compatibility. It is no longer + * needed or required by the Persistent interface. It will be removed in next BC-breaking + * release of Propel. + * + * @deprecated + */ + public function setPrimaryKey(\$pk) + { + // do nothing, because this object doesn't have any primary keys + } +"; + } + + /** + * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects. + * @param string &$script The script will be modified in this method. + */ + protected function addCopy(&$script) + { + $this->addCopyInto($script); + + $table = $this->getTable(); + + $script .= " + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * @return ".$table->getPhpName()." Clone of current object. + * @throws PropelException + */ + public function copy() + { + // we use get_class(), because this might be a subclass + \$clazz = get_class(\$this); + \$copyObj = new \$clazz(); + \$this->copyInto(\$copyObj); + return \$copyObj; + } +"; + } // addCopy() + + /** + * Adds the copy() method. + */ + protected function addCopyInto(&$script) + { + $table = $this->getTable(); + + $script .= " + /** + * Sets contents of passed object to values from current object. + * + * @param object \$copyObj An object of ".$table->getPhpName()." (or compatible) type. + * @return ".$table->getPhpName()." Clone of current object. + * @throws PropelException + */ + public function copyInto(\$copyObj) + { +"; + + $pkcols = array(); + foreach ($table->getColumns() as $pkcol) { + if ($pkcol->isPrimaryKey()) { + $pkcols[] = $pkcol->getName(); + } + } + + foreach ($table->getColumns() as $col) { + if (!in_array($col->getName(), $pkcols)) { + $script .= " + \$copyObj->setgetPhpName()?>(\$this->getName()) ?>);"; + } + } // foreach + + $script .= " + + \$copyObj->setNew(true);"; + + foreach ($table->getColumns() as $col) { + if ($col->isPrimaryKey()) { + $coldefval = $col->getPhpDefaultValue(); + $coldefval = var_export($coldefval, true); + $script .= " + \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a pkey column, so set to default value"; + } // if col->isPrimaryKey + } // foreach + $script .= " + return \$copyObj; + } +"; + } // addCopy() + +} // PHP5BasicObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php new file mode 100644 index 000000000..c03c84735 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php @@ -0,0 +1,1478 @@ +. + */ + +require_once 'propel/engine/builder/om/PeerBuilder.php'; + +/** + * Generates a PHP5 base Peer class for user object model (OM). + * + * This class produces the base peer class (e.g. BaseMyPeer) which contains all + * the custom-built query and manipulator methods. + * + * This class replaces the Peer.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5BasicPeerBuilder extends PeerBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getBuildProperty('basePrefix') . $this->getStubPeerBuilder()->getClassname(); + } + + /** + * Gets the package for the [base] peer classes. + * @return string + */ + public function getPackage() + { + return parent::getPackage() . ".om"; + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) { + + $table = $this->getTable(); + + $basePeerFile = $this->getFilePath($this->basePeerClass); + $objectFile = $this->getStubObjectBuilder()->getClassFilePath(); + + $script .= " +require_once '$basePeerFile'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ".$this->getPeerClassname()."::getOMClass() +include_once '$objectFile';"; + + $script .= " +"; + + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) { + + $tableName = $this->getTable()->getName(); + $tableDesc = $this->getTable()->getDescription(); + + $script .= " +/** + * Base static class for performing query and update operations on the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * @package ".$this->getPackage()." + */ +abstract class ".$this->getClassname()." { +"; + } + + /** + * Closes class. + * Adds closing brace at end of class and the static map builder registration code. + * @param string &$script The script will be modified in this method. + * @see addStaticMapBuilderRegistration() + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + $this->addStaticMapBuilderRegistration($script); + } + + /** + * Adds the static map builder registraction code. + * @param string &$script The script will be modified in this method. + */ + protected function addStaticMapBuilderRegistration(&$script) + { + $table = $this->getTable(); + $mapBuilderFile = $this->getMapBuilderBuilder()->getClassFilePath(); + + $script .= " +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + ".$this->getClassname()."::getMapBuilder(); + } catch (Exception \$e) { + Propel::log('Could not initialize Peer: ' . \$e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once '$mapBuilderFile'; + Propel::registerMapBuilder('".$this->getMapBuilderBuilder()->getClasspath()."'); +} +"; + } + + /** + * Adds constant and variable declarations that go at the top of the class. + * @param string &$script The script will be modified in this method. + * @see addColumnNameConstants() + */ + protected function addConstantsAndAttributes(&$script) + { + $tableName = $this->getTable()->getName(); + $dbName = $this->getDatabase()->getName(); + $script .= " + /** the default database name for this class */ + const DATABASE_NAME = '$dbName'; + + /** the table name for this class */ + const TABLE_NAME = '$tableName'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = '".$this->getStubObjectBuilder()->getClasspath()."'; + + /** The total number of columns. */ + const NUM_COLUMNS = ".$this->getTable()->getNumColumns()."; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = ".$this->getTable()->getNumLazyLoadColumns()."; + +"; + $this->addColumnNameConstants($script); + $this->addInheritanceColumnConstants($script); + + $script .= " + /** The PHP to DB Name Mapping */ + private static \$phpNameMap = null; + +"; + + $this->addFieldNamesAttribute($script); + $this->addFieldKeysAttribute($script); + + } + + /** + * Adds the COLUMN_NAME contants to the class definition. + * @param string &$script The script will be modified in this method. + */ + protected function addColumnNameConstants(&$script) + { + foreach ($this->getTable()->getColumns() as $col) { + + $script .= " + /** the column name for the ".strtoupper($col->getName()) ." field */ + const ".$this->getColumnName($col) ." = '".$this->getTable()->getName().".".strtoupper($col->getName())."'; +"; + } // foreach + } + + protected function addFieldNamesAttribute(&$script) + { + $table = $this->getTable(); + + $tableColumns = $table->getColumns(); + $tablePhpname = $table->getPhpName(); + + $script .= " + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::\$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static \$fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ("; + foreach ($tableColumns as $col) { + $script .= "'".$col->getPhpName()."', "; + } + $script .= "), + BasePeer::TYPE_COLNAME => array ("; + foreach ($tableColumns as $col) { + $script .= $this->getColumnConstant($col).", "; + } + $script .= "), + BasePeer::TYPE_FIELDNAME => array ("; + foreach ($tableColumns as $col) { + $script .= "'".$col->getName()."', "; + } + $script .= "), + BasePeer::TYPE_NUM => array ("; + foreach ($tableColumns as $num => $col) { + $script .= "$num, "; + } + $script .= ") + ); +"; + } + + protected function addFieldKeysAttribute(&$script) + { + $table = $this->getTable(); + + $tableColumns = $table->getColumns(); + $tablePhpname = $table->getPhpName(); + + $script .= " + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::\$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static \$fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ("; + foreach ($tableColumns as $num => $col) { + $script .= "'".$col->getPhpName()."' => $num, "; + } + $script .= "), + BasePeer::TYPE_COLNAME => array ("; + foreach ($tableColumns as $num => $col) { + $script .= $this->getColumnConstant($col)." => $num, "; + } + $script .= "), + BasePeer::TYPE_FIELDNAME => array ("; + foreach ($tableColumns as $num => $col) { + $script .= "'".$col->getName()."' => $num, "; + } + $script .= "), + BasePeer::TYPE_NUM => array ("; + foreach ($tableColumns as $num => $col) { + $script .= "$num, "; + } + $script .= ") + ); +"; + } // addFielKeysAttribute + + + protected function addGetFieldNames(&$script) + { + $script .= " + /** + * Returns an array of of field names. + * + * @param string \$type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames(\$type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists(\$type, self::\$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter \$type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . \$type . ' was given.'); + } + return self::\$fieldNames[\$type]; + } +"; + + } // addGetFieldNames() + + protected function addTranslateFieldName(&$script) + { + $script .= " + /** + * Translates a fieldname to another type + * + * @param string \$name field name + * @param string \$fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string \$toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName(\$name, \$fromType, \$toType) + { + \$toNames = self::getFieldNames(\$toType); + \$key = isset(self::\$fieldKeys[\$fromType][\$name]) ? self::\$fieldKeys[\$fromType][\$name] : null; + if (\$key === null) { + throw new PropelException(\"'\$name' could not be found in the field names of type '\$fromType'. These are: \" . print_r(self::\$fieldKeys[\$fromType], true)); + } + return \$toNames[\$key]; + } +"; + } // addTranslateFieldName() + + /** + * Adds the getMapBuilder() method. + * @param string &$script The script will be modified in this method. + */ + protected function addGetMapBuilder(&$script) + { + $script .= " + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once '" . $this->getMapBuilderBuilder()->getClassFilePath()."'; + return ".$this->basePeerClassname."::getMapBuilder('". $this->getMapBuilderBuilder()->getClasspath() ."'); + }"; + } + + /** + * Adds the getPhpNameMap() method. + * @param string &$script The script will be modified in this method. + * @todo Replace with static version (this can be built at build-time). + */ + protected function addGetPhpNameMap(&$script) + { + $script .= " + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::\$phpNameMap === null) { + \$map = ".$this->getTable()->getPhpName()."Peer::getTableMap(); + \$columns = \$map->getColumns(); + \$nameMap = array(); + foreach (\$columns as \$column) { + \$nameMap[\$column->getPhpName()] = \$column->getColumnName(); + } + self::\$phpNameMap = \$nameMap; + } + return self::\$phpNameMap; + }"; + } + + /** + * Adds the CLASSKEY_* and CLASSNAME_* constants used for inheritance. + * @param string &$script The script will be modified in this method. + */ + public function addInheritanceColumnConstants(&$script) + { + if ($this->getTable()->getChildrenColumn()) { + + $col = $this->getTable()->getChildrenColumn(); + $tfc = $this->getTable()->getPhpName(); + $cfc = $col->getPhpName(); + + if ($col->isEnumeratedClasses()) { + + if ($col->isPrimitiveNumeric()) $quote = ""; + else $quote = '"'; + + foreach ($col->getChildren() as $child) { + $childBuilder = $this->getMultiExtendObjectBuilder(); + $childBuilder->setChild($child); + + $script .= " + /** A key representing a particular subclass */ + const CLASSKEY_".strtoupper($child->getKey())." = '" . $child->getKey() . "'; +"; + + if (strtoupper($child->getClassname()) != strtoupper($child->getKey())) { + $script .= " + /** A key representing a particular subclass */ + const CLASSKEY_".strtoupper($child->getClassname())." = '" . $child->getKey() . "'; +"; + } + + $script .= " + /** A class that can be returned by this peer. */ + const CLASSNAME_".strtoupper($child->getKey())." = '". $childBuilder->getClasspath() . "'; +"; + } /* foreach children */ + } /* if col->isenumerated...() */ + } /* if table->getchildrencolumn() */ + + } // + + + + /** + * Adds the alias() utility method. + * @param string &$script The script will be modified in this method. + */ + protected function addAlias(&$script) + { + $script .= " + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * + * \$c->addAlias(\"alias1\", TablePeer::TABLE_NAME); + * \$c->addJoin(TablePeer::alias(\"alias1\", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * + * @param string \$alias The alias for the current table. + * @param string \$column The column name for current table. (i.e. ".$this->getTable()->getPhpName()."Peer::COLUMN_NAME). + * @return string + */ + public static function alias(\$alias, \$column) + { + return str_replace(".$this->getPeerClassname()."::TABLE_NAME.'.', \$alias.'.', \$column); + } +"; + } // addAliasMethod + + /** + * Adds the addSelectColumns() method. + * @param string &$script The script will be modified in this method. + */ + protected function addAddSelectColumns(&$script) + { + $script .= " + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad=\"true\" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria \$criteria) + { +"; + foreach ($this->getTable()->getColumns() as $col) { + if (!$col->isLazyLoad()) { + $script .= " + \$criteria->addSelectColumn(".$this->getPeerClassname()."::".$this->getColumnName($col)."); +"; + } // if !col->isLazyLoad + } // foreach + $script .=" + } +"; + } // addAddSelectColumns() + + + + /** + * Adds the COUNT constants. + * @param string &$script The script will be modified in this method. + */ + protected function addCountConstants(&$script) + { + $table = $this->getTable(); + $count_col = "*"; + /* + * FIXME + * (HL) wanted to remove this because AFAIK count(*) is generally + * optimized in databases, and furthermore the code below isn't correct + * (multi-pkey needs to be accounted for).... + */ + if ($table->hasPrimaryKey()) { + $pk = $table->getPrimaryKey(); + $count_col = $table->getName().".".strtoupper($pk[0]->getName()); + } + + $script .= " + const COUNT = 'COUNT($count_col)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT $count_col)'; +"; + } + + /** + * Adds the doCount() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoCount(&$script) + { + $script .= " + /** + * Returns the number of rows matching criteria. + * + * @param Criteria \$criteria + * @param boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection \$con + * @return int Number of matching rows. + */ + public static function doCount(Criteria \$criteria, \$distinct = false, \$con = null) + { + // we're going to modify criteria, so copy it first + \$criteria = clone \$criteria; + + // clear out anything that might confuse the ORDER BY clause + \$criteria->clearSelectColumns()->clearOrderByColumns(); + if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT); + } else { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach(\$criteria->getGroupByColumns() as \$column) + { + \$criteria->addSelectColumn(\$column); + } + + \$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con); + if (\$rs->next()) { + return \$rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + }"; + } + + /** + * Adds the doSelectOne() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelectOne(&$script) + { + $script .= " + /** + * Method to select one object from the DB. + * + * @param Criteria \$criteria object used to create the SELECT statement. + * @param Connection \$con + * @return ".$this->getTable()->getPhpName()." + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria \$criteria, \$con = null) + { + \$critcopy = clone \$criteria; + \$critcopy->setLimit(1); + \$objects = ".$this->getPeerClassname()."::doSelect(\$critcopy, \$con); + if (\$objects) { + return \$objects[0]; + } + return null; + }"; + } + + /** + * Adds the doSelect() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelect(&$script) + { + $script .= " + /** + * Method to do selects. + * + * @param Criteria \$criteria The Criteria object used to build the SELECT statement. + * @param Connection \$con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria \$criteria, \$con = null) + { + return ".$this->getPeerClassname()."::populateObjects(".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con)); + }"; + } + + /** + * Adds the doSelectRS() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelectRS(&$script) + { + + $script .= " + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria \$criteria The Criteria object used to build the SELECT statement. + * @param Connection \$con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see ".$this->basePeerClassname."::doSelect() + */ + public static function doSelectRS(Criteria \$criteria, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!\$criteria->getSelectColumns()) { + \$criteria = clone \$criteria; + ".$this->getPeerClassname()."::addSelectColumns(\$criteria); + } + + // Set the correct dbName + \$criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return ".$this->basePeerClassname."::doSelect(\$criteria, \$con); + }"; + } + + /** + * Adds the populateObjects() method. + * @param string &$script The script will be modified in this method. + */ + protected function addPopulateObjects(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet \$rs) + { + \$results = array(); + "; + if (!$table->getChildrenColumn()) { + $script .= " + // set the class once to avoid overhead in the loop + \$cls = ".$this->getPeerClassname()."::getOMClass(); + \$cls = Propel::import(\$cls);"; + } + + $script .= " + // populate the object(s) + while(\$rs->next()) { + "; + if ($table->getChildrenColumn()) { + $script .= " + // class must be set each time from the record row + \$cls = Propel::import(".$this->getPeerClassname()."::getOMClass(\$rs, 1)); + \$obj = new \$cls(); + \$obj->hydrate(\$rs); + \$results[] = \$obj; + "; + } else { + $script .= " + \$obj = new \$cls(); + \$obj->hydrate(\$rs); + \$results[] = \$obj; + "; + } + $script .= " + } + return \$results; + }"; + } + + /** + * Adds a getOMClass() for non-abstract tables that have inheritance. + * @param string &$script The script will be modified in this method. + */ + protected function addGetOMClass_Inheritance(&$script) + { + $col = $this->getTable()->getChildrenColumn(); + $script .= " + /** + * The returned Class will contain objects of the default type or + * objects that inherit from the default. + * + * @param ResultSet \$rs ResultSet with pointer to record containing om class. + * @param int \$colnum Column to examine for OM class information (first is 1). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getOMClass(ResultSet \$rs, \$colnum) + { + try { +"; + if ($col->isEnumeratedClasses()) { + $script .= " + \$omClass = null; + \$classKey = \$rs->getString(\$colnum - 1 + " . $col->getPosition() . "); + + switch(\$classKey) { +"; + foreach ($col->getChildren() as $child) { + $script .= " + case self::CLASSKEY_".strtoupper($child->getKey()).": + \$omClass = self::CLASSNAME_".strtoupper($child->getKey())."; + break; +"; + } /* foreach */ + $script .= " + default: + \$omClass = self::CLASS_DEFAULT; +"; + $script .= " + } // switch +"; + } else { /* if not enumerated */ + $script .= " + \$omClass = Propel::import(\$rs->getString(\$colnum - 1 + ".$col->getPosition().")); +"; + } + $script .= " + } catch (Exception \$e) { + throw new PropelException('Unable to get OM class.', \$e); + } + return \$omClass; + } +"; + } + + /** + * Adds a getOMClass() signature for abstract tables that have inheritance. + * @param string &$script The script will be modified in this method. + */ + protected function addGetOMClass_Inheritance_Abstract(&$script) + { + $script .= " + /** + * The returned Class will contain objects of the default type or + * objects that inherit from the default. + * + * This method must be overridden by the stub subclass, because + * ".$this->getTable()->getPhpName()." is declared abstract in the schema. + * + * @param ResultSet \$rs ResultSet with pointer to record containing om class. + * @param int \$colnum Column to examine for OM class information (first is 1). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + abstract public static function getOMClass(); +"; + } + + /** + * Adds a getOMClass() for non-abstract tables that do note use inheritance. + * @param string &$script The script will be modified in this method. + */ + protected function addGetOMClass_NoInheritance(&$script) + { + $script .= " + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ".$this->getPeerClassname()."::CLASS_DEFAULT; + } +"; + } + + /** + * Adds a getOMClass() signature for abstract tables that do not have inheritance. + * @param string &$script The script will be modified in this method. + */ + protected function addGetOMClass_NoInheritance_Abstract(&$script) + { + $script .= " + /** + * The class that the Peer will make instances of. + * + * This method must be overridden by the stub subclass, because + * ".$this->getTable()->getPhpName()." is declared abstract in the schema. + */ + abstract public static function getOMClass(); +"; + } + + /** + * Adds the doInsert() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoInsert(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Method perform an INSERT on the database, given a ".$table->getPhpName()." or Criteria object. + * + * @param mixed \$values Criteria or ".$table->getPhpName()." object containing data that is used to create the INSERT statement. + * @param Connection \$con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert(\$values, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + + if (\$values instanceof Criteria) { + \$criteria = clone \$values; // rename for clarity + } else { + \$criteria = \$values->buildCriteria(); // build Criteria from ".$table->getPhpName()." object + } +"; + + foreach ($table->getColumns() as $col) { + $cfc = $col->getPhpName(); + if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none") { + $script .= " + \$criteria->remove(".$this->getColumnConstant($col)."); // remove pkey col since this table uses auto-increment +"; + } + } + $script .= " + + // Set the correct dbName + \$criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because \$criteria could contain info + // for more than one table (I guess, conceivably) + \$con->begin(); + \$pk = ".$this->basePeerClassname."::doInsert(\$criteria, \$con); + \$con->commit(); + } catch(PropelException \$e) { + \$con->rollback(); + throw \$e; + } + + return \$pk; + } +"; + } + + /** + * Adds the doUpdate() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoUpdate(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Method perform an UPDATE on the database, given a ".$table->getPhpName()." or Criteria object. + * + * @param mixed \$values Criteria or ".$table->getPhpName()." object containing data that is used to create the UPDATE statement. + * @param Connection \$con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate(\$values, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + + \$selectCriteria = new Criteria(self::DATABASE_NAME); + + if (\$values instanceof Criteria) { + \$criteria = clone \$values; // rename for clarity +"; + foreach ($table->getColumns() as $col) { + if($col->isPrimaryKey()) { + $script .= " + \$comparison = \$criteria->getComparison(".$this->getColumnConstant($col)."); + \$selectCriteria->add(".$this->getColumnConstant($col).", \$criteria->remove(".$this->getColumnConstant($col)."), \$comparison); +"; + } /* if col is prim key */ + } /* foreach */ + + $script .= " + } else { // \$values is ".$table->getPhpName()." object + \$criteria = \$values->buildCriteria(); // gets full criteria + \$selectCriteria = \$values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + \$criteria->setDbName(self::DATABASE_NAME); + + return {$this->basePeerClassname}::doUpdate(\$selectCriteria, \$criteria, \$con); + } +"; + } + + /** + * Adds the doDeleteAll() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoDeleteAll(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Method to DELETE all rows from the ".$table->getName()." table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(\$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + \$affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because \$criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + \$con->begin(); + "; + if ($this->isDeleteCascadeEmulationNeeded()) { + $script .="\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(new Criteria(), \$con); + "; + } + if ($this->isDeleteSetNullEmulationNeeded()) { + $script .= $this->getPeerClassname() . "::doOnDeleteSetNull(new Criteria(), \$con); + "; + } + $script .= "\$affectedRows += BasePeer::doDeleteAll(".$this->getPeerClassname()."::TABLE_NAME, \$con); + \$con->commit(); + return \$affectedRows; + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + } +"; + } + + /** + * Adds the doDelete() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoDelete(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Method perform a DELETE on the database, given a ".$table->getPhpName()." or Criteria object OR a primary key value. + * + * @param mixed \$values Criteria or ".$table->getPhpName()." object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection \$con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete(\$values, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); + } + + if (\$values instanceof Criteria) { + \$criteria = clone \$values; // rename for clarity + } elseif (\$values instanceof ".$table->getPhpName().") { +"; + if (count($table->getPrimaryKey()) > 0) { + $script .= " + \$criteria = \$values->buildPkeyCriteria();"; + } else { + $script .= " + \$criteria = \$values->buildCriteria();"; + } + + $script .= " + } else { + // it must be the primary key + \$criteria = new Criteria(self::DATABASE_NAME);"; + + if (count($table->getPrimaryKey()) === 1) { + $pkey = $table->getPrimaryKey(); + $col = array_shift($pkey); + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", (array) \$values, Criteria::IN);"; + } else { + $script .= " + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count(\$values) == count(\$values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + \$values = array(\$values); + } + \$vals = array(); + foreach(\$values as \$value) + { +"; + $i=0; + foreach($table->getPrimaryKey() as $col) { + $script .= " + \$vals[$i][] = \$value[$i];"; + $i++; + } + $script .= " + } +"; + $i=0; + foreach($table->getPrimaryKey() as $col) { + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", \$vals[$i], Criteria::IN);"; + $i++; + } + } /* if count(table->getPrimaryKeys()) */ + + $script .= " + } + + // Set the correct dbName + \$criteria->setDbName(self::DATABASE_NAME); + + \$affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because \$criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + \$con->begin(); + "; + + if ($this->isDeleteCascadeEmulationNeeded()) { + $script .= "\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(\$criteria, \$con);"; + } + if ($this->isDeleteSetNullEmulationNeeded()) { + $script .= $this->getPeerClassname() . "::doOnDeleteSetNull(\$criteria, \$con);"; + } + + $script .= " + \$affectedRows += {$this->basePeerClassname}::doDelete(\$criteria, \$con); + \$con->commit(); + return \$affectedRows; + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + } +"; + } + + /** + * Adds the doOnDeleteCascade() method, which provides ON DELETE CASCADE emulation. + * @param string &$script The script will be modified in this method. + */ + protected function addDoOnDeleteCascade(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * This is a method for emulating ON DELETE CASCADE for DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria \$criteria + * @param Connection \$con + * @return int The number of affected rows (if supported by underlying database driver). + */ + protected static function doOnDeleteCascade(Criteria \$criteria, Connection \$con) + { + // initialize var to track total num of affected rows + \$affectedRows = 0; + + // first find the objects that are implicated by the \$criteria + \$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con); + foreach(\$objects as \$obj) { +"; + + foreach ($table->getReferrers() as $fk) { + + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($tblFK); + $tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage(); + + if (!$tblFK->isForReferenceOnly()) { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete cascade for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::CASCADE && $tblFK->getName() != $table->getName()) { + + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); + + $script .= " + + include_once '".$this->getFilePath($tblFKPackage, $tblFK->getPhpName())."'; + + // delete related $fkClassName objects + \$c = new Criteria(); + "; + for($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) { + $columnFK = $tblFK->getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); + + $script .= " + \$c->add(".$joinedTablePeerBuilder->getColumnConstant($columnFK) .", \$obj->get".$columnL->getPhpName()."());"; + } + + $script .= " + \$affectedRows += ".$joinedTablePeerBuilder->getPeerClassname()."::doDelete(\$c, \$con);"; + + } // if cascade && fkey table name != curr table name + + } // if not for ref only + } // foreach foreign keys + $script .= " + } + return \$affectedRows; + } +"; + } // end addDoOnDeleteCascade + + /** + * Adds the doOnDeleteSetNull() method, which provides ON DELETE SET NULL emulation. + * @param string &$script The script will be modified in this method. + */ + protected function addDoOnDeleteSetNull(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * This is a method for emulating ON DELETE SET NULL DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria \$criteria + * @param Connection \$con + * @return void + */ + protected static function doOnDeleteSetNull(Criteria \$criteria, Connection \$con) + { + + // first find the objects that are implicated by the \$criteria + \$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con); + foreach(\$objects as \$obj) { +"; + + // This logic is almost exactly the same as that in doOnDeleteCascade() + // it may make sense to refactor this, provided that thigns don't + // get too complicated. + + foreach ($table->getReferrers() as $fk) { + + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + $refTablePeerBuilder = OMBuilder::getNewPeerBuilder($tblFK); + + if (!$tblFK->isForReferenceOnly()) { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete setnull for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::SETNULL && + $fk->getTable()->getName() != $table->getName()) { + + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); // should be same num as foreign + $script .= " + // set fkey col in related $fkClassName rows to NULL + \$selectCriteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME); + \$updateValues = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);"; + + for ($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) { + $columnFK = $tblFK->getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); + $script .= " + \$selectCriteria->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", \$obj->get".$columnL->getPhpName()."()); + \$updateValues->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", null); +"; + } + + $script .= " + {$this->basePeerClassname}::doUpdate(\$selectCriteria, \$updateValues, \$con); // use BasePeer because generated Peer doUpdate() methods only update using pkey +"; + } // if setnull && fkey table name != curr table name + } // if not for ref only + } // foreach foreign keys + + $script .= " + } + } +"; + } + + /** + * Adds the doValidate() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoValidate(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Validates all modified columns of given ".$table->getPhpName()." object. + * If parameter \$columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ".$table->getPhpName()." \$obj The object to validate. + * @param mixed \$cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(".$table->getPhpName()." \$obj, \$cols = null) + { + \$columns = array(); + + if (\$cols) { + \$dbMap = Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME); + \$tableMap = \$dbMap->getTable(".$this->getPeerClassname()."::TABLE_NAME); + + if (! is_array(\$cols)) { + \$cols = array(\$cols); + } + + foreach(\$cols as \$colName) { + if (\$tableMap->containsColumn(\$colName)) { + \$get = 'get' . \$tableMap->getColumn(\$colName)->getPhpName(); + \$columns[\$colName] = \$obj->\$get(); + } + } + } else { +"; + foreach ($table->getValidators() as $val) { + $col = $val->getColumn(); + if (!$col->isAutoIncrement()) { + $script .= " + if (\$obj->isNew() || \$obj->isColumnModified(".$this->getColumnConstant($col).")) + \$columns[".$this->getColumnConstant($col)."] = \$obj->get".$col->getPhpName()."(); +"; + } // if + } // foreach + + $script .= " + } + + return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns); + } +"; + } // end addDoValidate() + + /** + * Adds the retrieveByPK method for tables with single-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addRetrieveByPK_SinglePK(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Retrieve a single object by pkey. + * + * @param mixed \$pk the primary key. + * @param Connection \$con the connection to use + * @return " . $table->getPhpName() . " + */ + public static function ".$this->getRetrieveMethodName()."(\$pk, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + + \$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME); +"; + if (count($table->getPrimaryKey()) === 1) { + $pkey = $table->getPrimaryKey(); + $col = array_shift($pkey); + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", \$pk); +"; + } else { + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + $i=0; + foreach($table->getPrimaryKey() as $col) { + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", \$pk[$i]);"; + $i++; + } + } /* if count(table.PrimaryKeys) */ + $script .= " + + \$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con); + + return !empty(\$v) > 0 ? \$v[0] : null; + } +"; + } + + /** + * Adds the retrieveByPKs method for tables with single-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addRetrieveByPKs_SinglePK(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Retrieve multiple objects by pkey. + * + * @param array \$pks List of primary keys + * @param Connection \$con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function ".$this->getRetrieveMethodName()."s(\$pks, \$con = null) + { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + + \$objs = null; + if (empty(\$pks)) { + \$objs = array(); + } else { + \$criteria = new Criteria();"; + if (count($table->getPrimaryKey()) == 1) { + $k1 = $table->getPrimaryKey(); + $script .= " + \$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);"; + } else { + $script .= " + foreach(\$pks as \$pk) {"; + $i = 0; + foreach($table->getPrimaryKey() as $col) { + $script .= " + \$c{$i} = \$criteria->getNewCriterion(".$this->getPeerClassname($col).", \$pk[$i], Criteria::EQUAL);"; + $j = $i - 1; + if ($i > 0) { + $script .= " + \$c{$j}->addAnd(\$c{$i});"; + } /* if $i > 0 */ + $i++; + } /* foreach */ + + $script .= " + + \$criteria->addOr(\$c0); + }"; + } /* if count prim keys == 1 */ + $script .= " + \$objs = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con); + } + return \$objs; + } +"; + } + + /** + * Adds the retrieveByPK method for tables with multi-column primary key. + * @param string &$script The script will be modified in this method. + */ + protected function addRetrieveByPK_MultiPK(&$script) + { + $table = $this->getTable(); + $script .= " + /** + * Retrieve object using using composite pkey values. + * "; + foreach ($table->getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); + $cptype = $col->getPhpNative(); + $script .= "@param $cptype $".$clo." + "; + } + $script .= " + * @param Connection \$con + * @return ".$table->getPhpName()." + */ + public static function ".$this->getRetrieveMethodName()."("; + $co = 0; + foreach ($table->getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); + $script .= ($co++ ? "," : "") . " $".$clo; + } /* foreach */ + $script .= ", \$con = null) { + if (\$con === null) { + \$con = Propel::getConnection(self::DATABASE_NAME); + } + \$criteria = new Criteria();"; + foreach ($table->getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); + $script .= " + \$criteria->add(".$this->getColumnConstant($col).", $".$clo.");"; + } + $script .= " + \$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con); + + return !empty(\$v) ? \$v[0] : null; + }"; + } + + /** + * Adds the getTableMap() method which is a convenience method for apps to get DB metadata. + * @param string &$script The script will be modified in this method. + */ + protected function addGetTableMap(&$script) + { + $script .= " + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } +"; + + } +} // PHP5BasicPeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexObjectBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexObjectBuilder.php new file mode 100644 index 000000000..c66ec70f0 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexObjectBuilder.php @@ -0,0 +1,1273 @@ +. + */ + +require_once 'propel/engine/builder/om/php5/PHP5BasicObjectBuilder.php'; + +/** + * Generates a PHP5 base Object class with complex object model methods. + * + * This class adds on to the PHP5BasicObjectBuilder class by adding more complex + * logic related to relationships to methods like the setters, and save method. Also, + * new get*Join*() methods are added to fetch related rows. + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ComplexObjectBuilder extends PHP5BasicObjectBuilder { + + /** + * Adds additional attributes used for complex object model. + * @param string &$script The script will be modified in this method. + * @see addFKAttributes() + * @see addRefFKAttributes() + * @see addAlreadyInSaveAttribute() + * @see addAlreadyInValidationAttribute() + */ + protected function addAttributes(&$script) + { + $table = $this->getTable(); + parent::addAttributes($script); + + foreach ($table->getForeignKeys() as $fk) { + $this->addFKAttributes($script, $fk); + } + + foreach($table->getReferrers() as $refFK) { + // if ($refFK->getTable()->getName() != $table->getName()) { + $this->addRefFKAttributes($script, $refFK); + // } + } + + $this->addAlreadyInSaveAttribute($script); + $this->addAlreadyInValidationAttribute($script); + } + + /** + * Specifies the methods that are added as part of the basic OM class. + * This can be overridden by subclasses that wish to add more methods. + * @param string &$script The script will be modified in this method. + * @see PHP5BasicObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $table = $this->getTable(); + parent::addClassBody($script); + + + $this->addFKMethods($script); + $this->addRefFKMethods($script); + + } + + /** + * Adds the close of mutator (setter) method for a column. + * This method overrides the method from PHP5BasicObjectBuilder in order to + * account for updating related objects. + * @param string &$script The script will be modified in this method. + * @param Column $col The current column. + * @see PHP5BasicObjectBuilder::addMutatorClose() + */ + protected function addMutatorClose(&$script, Column $col) + { + $table = $this->getTable(); + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + + if ($col->isForeignKey()) { + + $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); + $colFK = $tblFK->getColumn($col->getRelatedColumnName()); + + $varName = $this->getFKVarName($col->getForeignKey()); + + $script .= " + if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) { + \$this->$varName = null; + } +"; + } /* if col is foreign key */ + + foreach ($col->getReferrers() as $fk) { + + $tblFK = $this->getDatabase()->getTable($fk->getForeignTableName()); + + if ( $tblFK->getName() != $table->getName() ) { + + $collName = $this->getRefFKCollVarName($fk); + + $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); + $colFK = $tblFK->getColumn($col->getRelatedColumnName()); + + $script .= " + + // update associated ".$tblFK->getPhpName()." + if (\$this->$collName !== null) { + foreach(\$this->$collName as \$referrerObject) { + \$referrerObject->set".$colFK->getPhpName()."(\$v); + } + } +"; + } // if + } // foreach + + $script .= " + } // set$cfc() +"; + } // addMutatorClose() + + /** + * Adds the methods related to validating, saving and deleting the object. + * @param string &$script The script will be modified in this method. + */ + protected function addManipulationMethods(&$script) + { + $this->addDelete($script); + $this->addSave($script); + $this->addDoSave($script); + } + + /** + * Adds the methods related to validationg the object. + * @param string &$script The script will be modified in this method. + */ + protected function addValidationMethods(&$script) + { + parent::addValidationMethods($script); + $this->addDoValidate($script); + } + + /** + * Convenience method to get the foreign Table object for an fkey. + * @return Table + */ + protected function getForeignTable(ForeignKey $fk) + { + return $this->getTable()->getDatabase()->getTable($fk->getForeignTableName()); + } + + /** + * Gets the PHP method name affix to be used for fkeys for the current table (not referrers to this table). + * + * The difference between this method and the getRefFKPhpNameAffix() method is that in this method the + * classname in the affix is the foreign table classname. + * + * @param ForeignKey $fk The local FK that we need a name for. + * @param boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj() + * @return string + */ + public function getFKPhpNameAffix(ForeignKey $fk, $plural = false) + { + $className = $this->getForeignTable($fk)->getPhpName(); + return $className . ($plural ? 's' : '') . $this->getRelatedBySuffix($fk); + } + + /** + * Gets the PHP method name affix to be used for referencing foreign key methods and variable names (e.g. set????(), $coll???). + * + * The difference between this method and the getFKPhpNameAffix() method is that in this method the + * classname in the affix is the classname of the local fkey table. + * + * @param ForeignKey $fk The referrer FK that we need a name for. + * @param boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj() + * @return string + */ + public function getRefFKPhpNameAffix(ForeignKey $fk, $plural = false) + { + $className = $fk->getTable()->getPhpName(); + return $className . ($plural ? 's' : '') . $this->getRelatedBySuffix($fk); + } + + /** + * Gets the "RelatedBy*" suffix (if needed) that is attached to method and variable names. + * + * The related by suffix is based on the local columns of the foreign key. If there is more than + * one column in a table that points to the same foreign table, then a 'RelatedByLocalColName' suffix + * will be appended. + * + * @return string + */ + protected function getRelatedBySuffix(ForeignKey $fk) + { + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $fk->getTable()->getColumn($columnName); + if (!$column) { + $e = new Exception("Could not fetch column: $columnName in table " . $fk->getTable()->getName()); + print $e; + throw $e; + } + if ($column->isMultipleFK() || $fk->getForeignTableName() == $fk->getTable()->getName()) { + // if there are seeral foreign keys that point to the same table + // then we need to generate methods like getAuthorRelatedByColName() + // instead of just getAuthor(). Currently we are doing the same + // for self-referential foreign keys, to avoid confusion. + $relCol .= $column->getPhpName(); + } + } + + if ($relCol != "") { + $relCol = "RelatedBy" . $relCol; + } + + return $relCol; + } + + protected function getFKVarName(ForeignKey $fk) + { + return 'a' . $this->getFKPhpNameAffix($fk, $plural = false); + } + + protected function getRefFKCollVarName(ForeignKey $fk) + { + return 'coll' . $this->getRefFKPhpNameAffix($fk, $plural = true); + } + + protected function getRefFKLastCriteriaVarName(ForeignKey $fk) + { + return 'last' . $this->getRefFKPhpNameAffix($fk, $plural = false) . 'Criteria'; + } + + // ---------------------------------------------------------------- + // + // F K M E T H O D S + // + // ---------------------------------------------------------------- + + /** + * Adds the methods that get & set objects related by foreign key to the current object. + * @param string &$script The script will be modified in this method. + */ + protected function addFKMethods(&$script) + { + foreach ($this->getTable()->getForeignKeys() as $fk) { + $this->addFKMutator($script, $fk); + $this->addFKAccessor($script, $fk); + } // foreach fk + } + + /** + * Adds the class attributes that are needed to store fkey related objects. + * @param string &$script The script will be modified in this method. + */ + protected function addFKAttributes(&$script, ForeignKey $fk) + { + $className = $this->getForeignTable($fk)->getPhpName(); + $varName = $this->getFKVarName($fk); + + $script .= " + /** + * @var $className + */ + protected $".$varName."; +"; + } + + /** + * Adds the mutator (setter) method for setting an fkey related object. + * @param string &$script The script will be modified in this method. + */ + protected function addFKMutator(&$script, ForeignKey $fk) + { + $table = $this->getTable(); + $tblFK = $this->getForeignTable($fk); + $className = $this->getForeignTable($fk)->getPhpName(); + $varName = $this->getFKVarName($fk); + + $script .= " + /** + * Declares an association between this object and a $className object. + * + * @param $className \$v + * @return void + * @throws PropelException + */ + public function set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$v) + { +"; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $lfmap = $fk->getLocalForeignMapping(); + $colFKName = $lfmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); + $script .= " + + if (\$v === null) { + \$this->set".$column->getPhpName()."(".var_export($column->getDefaultValue(), true)."); + } else { + \$this->set".$column->getPhpName()."(\$v->get".$colFK->getPhpName()."()); + } +"; + + } /* foreach local col */ + + $script .= " + + \$this->$varName = \$v; + } +"; + } + + /** + * Adds the accessor (getter) method for getting an fkey related object. + * @param string &$script The script will be modified in this method. + */ + protected function addFKAccessor(&$script, ForeignKey $fk) + { + $table = $this->getTable(); + + $className = $this->getForeignTable($fk)->getPhpName(); + $varName = $this->getFKVarName($fk); + + $and = ""; + $comma = ""; + $conditional = ""; + $arglist = ""; + $argsize = 0; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $cptype = $column->getPhpNative(); + $clo = strtolower($column->getName()); + + // FIXME: is this correct? what about negative numbers? + if ($cptype == "integer" || $cptype == "float" || $cptype == "double") { + $conditional .= $and . "\$this->". $clo ." > 0"; + } elseif($cptype == "string") { + $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)"; + } else { + $conditional .= $and . "\$this->" . $clo ." !== null"; + } + $arglist .= $comma . "\$this->" . $clo; + $and = " && "; + $comma = ", "; + $argsize = $argsize + 1; + } + + $pCollName = $this->getFKPhpNameAffix($fk, $plural = true); + + $fkPeerBuilder = OMBuilder::getNewPeerBuilder($this->getForeignTable($fk)); + + $script .= " + + /** + * Get the associated $className object + * + * @param Connection Optional Connection object. + * @return $className The associated $className object. + * @throws PropelException + */ + public function get".$this->getFKPhpNameAffix($fk, $plural = false)."(\$con = null) + { + // include the related Peer class + include_once '".$fkPeerBuilder->getClassFilePath()."'; + + if (\$this->$varName === null && ($conditional)) { +"; + $script .= " + \$this->$varName = ".$fkPeerBuilder->getPeerClassname()."::".$fkPeerBuilder->getRetrieveMethodName()."($arglist, \$con); + + /* The following can be used instead of the line above to + guarantee the related object contains a reference + to this object, but this level of coupling + may be undesirable in many circumstances. + As it can lead to a db query with many results that may + never be used. + \$obj = ".$fkPeerBuilder->getPeerClassname()."::retrieveByPK($arglist, \$con); + \$obj->add$pCollName(\$this); + */ + } + return \$this->$varName; + } +"; + + } // addFKAccessor + + /** + * Adds a convenience method for setting a related object by specifying the primary key. + * This can be used in conjunction with the getPrimaryKey() for systems where nothing is known + * about the actual objects being related. + * @param string &$script The script will be modified in this method. + */ + protected function addFKByKeyMutator(&$script, ForeignKey $fk) + { + $table = $this->getTable(); + + #$className = $this->getForeignTable($fk)->getPhpName(); + $methodAffix = $this->getFKPhpNameAffix($fk); + #$varName = $this->getFKVarName($fk); + + $script .= " + /** + * Provides convenient way to set a relationship based on a + * key. e.g. + * \$bar->setFooKey(\$foo->getPrimaryKey()) + *"; + if (count($fk->getLocalColumns()) > 1) { + $script .= " + * Note: It is important that the xml schema used to create this class + * maintains consistency in the order of related columns between + * ".$table->getName()." and ". $tblFK->getName().". + * If for some reason this is impossible, this method should be + * overridden in ".$table->getPhpName()."."; + } + $script .= " + * @return void + * @throws PropelException + */ + public function set".$methodAffix."Key(\$key) + { +"; + if (count($fk->getLocalColumns()) > 1) { + $i = 0; + foreach ($fk->getLocalColumns() as $colName) { + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); + $script .= " + \$this->set".$col->getPhpName()."( ($fktype) \$key[$i] ); +"; + $i++; + } /* foreach */ + } else { + $lcols = $fk->getLocalColumns(); + $colName = $lcols[0]; + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); + $script .= " + \$this->set".$col->getPhpName()."( ($fktype) \$key); +"; + } + $script .= " + } +"; + } // addFKByKeyMutator() + + /** + * Adds the method that fetches fkey-related (referencing) objects but also joins in data from another table. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKGetJoinMethods(&$script, ForeignKey $refFK) + { + $table = $this->getTable(); + $tblFK = $refFK->getTable(); + + $relCol = $this->getRefFKPhpNameAffix($refFK, $plural=true); + $collName = $this->getRefFKCollVarName($refFK); + $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); + + $fkPeerBuilder = OMBuilder::getNewPeerBuilder($tblFK); + + $lastTable = ""; + foreach ($tblFK->getForeignKeys() as $fk2) { + + // Add join methods if the fk2 table is not this table or + // the fk2 table references this table multiple times. + + $doJoinGet = true; + + if ( $fk2->getForeignTableName() == $table->getName() ) { + $doJoinGet = false; + } + + foreach ($fk2->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $doJoinGet = true; + } + } + + $tblFK2 = $this->getForeignTable($fk2); + $doJoinGet = !$tblFK2->isForReferenceOnly(); + + // it doesn't make sense to join in rows from the curent table, since we are fetching + // objects related to *this* table (i.e. the joined rows will all be the same row as current object) + if ($this->getTable()->getPhpName() == $tblFK2->getPhpName()) { + $doJoinGet = false; + } + + $relCol2 = $this->getFKPhpNameAffix($fk2, $plural = false); + + if ( $this->getRelatedBySuffix($refFK) != "" && + ($this->getRelatedBySuffix($refFK) == $this->getRelatedBySuffix($fk2))) { + $doJoinGet = false; + } + + if ($doJoinGet) { + $script .= " + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this ".$table->getPhpName()." is new, it will return + * an empty collection; or if this ".$table->getPhpName()." has previously + * been saved, it will retrieve related $relCol from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in ".$table->getPhpName().". + */ + public function get".$relCol."Join".$relCol2."(\$criteria = null, \$con = null) + { + // include the Peer class + include_once '".$fkPeerBuilder->getClassFilePath()."'; + if (\$criteria === null) { + \$criteria = new Criteria(); + } + elseif (\$criteria instanceof Criteria) + { + \$criteria = clone \$criteria; + } + + if (\$this->$collName === null) { + if (\$this->isNew()) { + \$this->$collName = array(); + } else { +"; + foreach ($refFK->getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + $flMap = $refFK->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); + if ($colFK === null) { + $e = new Exception("Column $colFKName not found in " . $tblFK->getName()); + print $e; + throw $e; + } + $script .= " + \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); +"; + } // end foreach ($fk->getForeignColumns() + + $script .= " + \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con); + } + } else { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +"; + foreach ($refFK->getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + $flMap = $refFK->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); + $script .= " + \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); +"; + } /* end foreach ($fk->getForeignColumns() */ + + $script .= " + if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) { + \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con); + } + } + \$this->$lastCriteriaName = \$criteria; + + return \$this->$collName; + } +"; + } /* end if($doJoinGet) */ + + } /* end foreach ($tblFK->getForeignKeys() as $fk2) { */ + + } // function + + + // ---------------------------------------------------------------- + // + // R E F E R R E R F K M E T H O D S + // + // ---------------------------------------------------------------- + + /** + * Adds the attributes used to store objects that have referrer fkey relationships to this object. + * protected collVarName; + * private lastVarNameCriteria = null; + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKAttributes(&$script, ForeignKey $refFK) + { + $collName = $this->getRefFKCollVarName($refFK); + $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); + + $script .= " + /** + * Collection to store aggregation of $collName. + * @var array + */ + protected $".$collName."; + + /** + * The criteria used to select the current contents of $collName. + * @var Criteria + */ + protected \$".$lastCriteriaName." = null; +"; + } + + /** + * Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKMethods(&$script) + { + foreach($this->getTable()->getReferrers() as $refFK) { + // if ( $refFK->getTable()->getName() != $this->getTable()->getName() ) { + $this->addRefFKInit($script, $refFK); + $this->addRefFKGet($script, $refFK); + $this->addRefFKCount($script, $refFK); + $this->addRefFKAdd($script, $refFK); + $this->addRefFKGetJoinMethods($script, $refFK); + // } + } + } + + /** + * Adds the method that initializes the referrer fkey collection. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKInit(&$script, ForeignKey $refFK) { + + $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); + $collName = $this->getRefFKCollVarName($refFK); + + $script .= " + /** + * Temporary storage of $collName to save a possible db hit in + * the event objects are add to the collection, but the + * complete collection is never requested. + * @return void + */ + public function init$relCol() + { + if (\$this->$collName === null) { + \$this->$collName = array(); + } + } +"; + } // addRefererInit() + + /** + * Adds the method that adds an object into the referrer fkey collection. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKAdd(&$script, ForeignKey $refFK) + { + $tblFK = $refFK->getTable(); + $className = $refFK->getTable()->getPhpName(); + + $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($refFK->getTable()); + + $script .= " + /** + * Method called to associate a ".$tblFK->getPhpName()." object to this object + * through the $className foreign key attribute + * + * @param $className \$l $className + * @return void + * @throws PropelException + */ + public function add".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$l) + { + \$this->coll".$this->getRefFKPhpNameAffix($refFK, $plural = true)."[] = \$l; + \$l->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this); + } +"; + } // addRefererAdd + + /** + * Adds the method that returns the size of the referrer fkey collection. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKCount(&$script, ForeignKey $refFK) + { + $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); + + $fkPeerBuilder = OMBuilder::getNewPeerBuilder($refFK->getTable()); + + $script .= " + /** + * Returns the number of related $relCol. + * + * @param Criteria \$criteria + * @param boolean \$distinct + * @param Connection \$con + * @throws PropelException + */ + public function count$relCol(\$criteria = null, \$distinct = false, \$con = null) + { + // include the Peer class + include_once '".$fkPeerBuilder->getClassFilePath()."'; + if (\$criteria === null) { + \$criteria = new Criteria(); + } + elseif (\$criteria instanceof Criteria) + { + \$criteria = clone \$criteria; + } +"; + foreach ($refFK->getForeignColumns() as $columnName) { + $column = $this->getTable()->getColumn($columnName); + $flmap = $refFK->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $refFK->getTable()->getColumn($colFKName); + $script .= " + \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$column->getPhpName()."()); +"; + } // end foreach ($fk->getForeignColumns() + $script .=" + return ".$fkPeerBuilder->getPeerClassname()."::doCount(\$criteria, \$distinct, \$con); + } +"; + } // addRefererCount + + /** + * Adds the method that returns the referrer fkey collection. + * @param string &$script The script will be modified in this method. + */ + protected function addRefFKGet(&$script, ForeignKey $refFK) + { + $table = $this->getTable(); + $tblFK = $refFK->getTable(); + + $fkPeerBuilder = OMBuilder::getNewPeerBuilder($refFK->getTable()); + $relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true); + + $collName = $this->getRefFKCollVarName($refFK); + $lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK); + + $script .= " + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this ".$table->getPhpName()." has previously + * been saved, it will retrieve related $relCol from storage. + * If this ".$table->getPhpName()." is new, it will return + * an empty collection or the current collection, the criteria + * is ignored on a new object. + * + * @param Connection \$con + * @param Criteria \$criteria + * @throws PropelException + */ + public function get$relCol(\$criteria = null, \$con = null) + { + // include the Peer class + include_once '".$fkPeerBuilder->getClassFilePath()."'; + if (\$criteria === null) { + \$criteria = new Criteria(); + } + elseif (\$criteria instanceof Criteria) + { + \$criteria = clone \$criteria; + } + + if (\$this->$collName === null) { + if (\$this->isNew()) { + \$this->$collName = array(); + } else { +"; + foreach ($refFK->getLocalColumns() as $colFKName) { + // $colFKName is local to the referring table (i.e. foreign to this table) + $lfmap = $refFK->getLocalForeignMapping(); + $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]); + $colFK = $refFK->getTable()->getColumn($colFKName); + + $script .= " + \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."()); +"; + } // end foreach ($fk->getForeignColumns() + + $script .= " + ".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria); + \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con); + } + } else { + // criteria has no effect for a new object + if (!\$this->isNew()) { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +"; + foreach ($refFK->getLocalColumns() as $colFKName) { + // $colFKName is local to the referring table (i.e. foreign to this table) + $lfmap = $refFK->getLocalForeignMapping(); + $localColumn = $this->getTable()->getColumn($lfmap[$colFKName]); + $colFK = $refFK->getTable()->getColumn($colFKName); + $script .= " + + \$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->get".$localColumn->getPhpName()."()); +"; + } // foreach ($fk->getForeignColumns() +$script .= " + ".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria); + if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) { + \$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con); + } + } + } + \$this->$lastCriteriaName = \$criteria; + return \$this->$collName; + } +"; + } // addRefererGet() + + + + // ---------------------------------------------------------------- + // + // M A N I P U L A T I O N M E T H O D S + // + // ---------------------------------------------------------------- + + /** + * Adds the workhourse doSave() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSave(&$script) + { + $table = $this->getTable(); + + $script .= " + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection \$con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(\$con) + { + \$affectedRows = 0; // initialize var to track total num of affected rows + if (!\$this->alreadyInSave) { + \$this->alreadyInSave = true; +"; + + if (count($table->getForeignKeys())) { + + $script .= " + + // We call the save method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. +"; + + foreach($table->getForeignKeys() as $fk) + { + $aVarName = $this->getFKVarName($fk); + $script .= " + if (\$this->$aVarName !== null) { + if (\$this->".$aVarName."->isModified()) { + \$affectedRows += \$this->".$aVarName."->save(\$con); + } + \$this->set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$this->$aVarName); + } +"; + } // foreach foreign k + } // if (count(foreign keys)) + + $script .= " + + // If this object has been modified, then save it to the database. + if (\$this->isModified()"; + + /* + FIXME: this doesn't work right now because the BasePeer::doInsert() method + expects to be passed a Criteria object that contains columns (which tell BasePeer + which table is being updated) + if ($table->hasAutoIncrementPrimaryKey()) { + $script .= " || \$this->isNew()"; + } + */ + + $script .= ") { + if (\$this->isNew()) { + \$pk = ".$this->getPeerClassname()."::doInsert(\$this, \$con); + \$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). +"; + if ($table->getIdMethod() != IDMethod::NO_ID_METHOD) { + + if (count($pks = $table->getPrimaryKey())) { + foreach ($pks as $pk) { + if ($pk->isAutoIncrement()) { + $script .= " + \$this->set".$pk->getPhpName()."(\$pk); //[IMV] update autoincrement primary key +"; + } + } + } + } // if (id method != "none") + + $script .= " + \$this->setNew(false); + } else { + \$affectedRows += ".$this->getPeerClassname()."::doUpdate(\$this, \$con); + } + \$this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } +"; + + foreach ($table->getReferrers() as $fk) { + $collName = $this->getRefFKCollVarName($fk); + //HL: commenting out self-referrential check below + // it seems to work as expected and is desireable since we are also enabling the copy()ing of these related rows + //if ( $fk->getTable()->getName() != $table->getName() ) { + $script .= " + if (\$this->$collName !== null) { + foreach(\$this->$collName as \$referrerFK) { + if (!\$referrerFK->isDeleted()) { + \$affectedRows += \$referrerFK->save(\$con); + } + } + } +"; + //HL: commenting out close of self-referrential check + //} /* if tableFK != table */ + } /* foreach getReferrers() */ + $script .= " + \$this->alreadyInSave = false; + } + return \$affectedRows; + } // doSave() +"; + + } + + /** + * Adds the $alreadyInSave attribute, which prevents attempting to re-save the same object. + * @param string &$script The script will be modified in this method. + */ + protected function addAlreadyInSaveAttribute(&$script) + { + $script .= " + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected \$alreadyInSave = false; +"; + } + + /** + * Adds the save() method. + * @param string &$script The script will be modified in this method. + */ + protected function addSave(&$script) + { + $script .= " + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection \$con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(\$con = null) + { + if (\$this->isDeleted()) { + throw new PropelException(\"You cannot save an object that has been deleted.\"); + } + + if (\$con === null) { + \$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME); + } + + try { + \$con->begin(); + \$affectedRows = \$this->doSave(\$con); + \$con->commit(); + return \$affectedRows; + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + } +"; + + } + + /** + * Adds the $alreadyInValidation attribute, which prevents attempting to re-validate the same object. + * @param string &$script The script will be modified in this method. + */ + protected function addAlreadyInValidationAttribute(&$script) + { + $script .= " + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected \$alreadyInValidation = false; +"; + } + + /** + * Adds the validate() method. + * @param string &$script The script will be modified in this method. + */ + protected function addValidate(&$script) + { + $script .= " + /** + * Validates the objects modified field values and all objects related to this table. + * + * If \$columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed \$columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate(\$columns = null) + { + \$res = \$this->doValidate(\$columns); + if (\$res === true) { + \$this->validationFailures = array(); + return true; + } else { + \$this->validationFailures = \$res; + return false; + } + } +"; + } // addValidate() + + /** + * Adds the workhourse doValidate() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoValidate(&$script) + { + $table = $this->getTable(); + + $script .= " + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then true is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array \$columns Array of column names to validate. + * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. + */ + protected function doValidate(\$columns = null) + { + if (!\$this->alreadyInValidation) { + \$this->alreadyInValidation = true; + \$retval = null; + + \$failureMap = array(); +"; + if (count($table->getForeignKeys()) != 0) { + $script .= " + + // We call the validate method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. +"; + foreach($table->getForeignKeys() as $fk) { + $aVarName = $this->getFKVarName($fk); + $script .= " + if (\$this->".$aVarName." !== null) { + if (!\$this->".$aVarName."->validate(\$columns)) { + \$failureMap = array_merge(\$failureMap, \$this->".$aVarName."->getValidationFailures()); + } + } +"; + } /* for() */ + } /* if count(fkeys) */ + + $script .= " + + if ((\$retval = ".$this->getPeerClassname()."::doValidate(\$this, \$columns)) !== true) { + \$failureMap = array_merge(\$failureMap, \$retval); + } + +"; + + foreach ($table->getReferrers() as $fk) { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) { + $collName = $this->getRefFKCollVarName($fk); + $script .= " + if (\$this->$collName !== null) { + foreach(\$this->$collName as \$referrerFK) { + if (!\$referrerFK->validate(\$columns)) { + \$failureMap = array_merge(\$failureMap, \$referrerFK->getValidationFailures()); + } + } + } +"; + } /* if tableFK !+ table */ + } /* foreach getReferrers() */ + + $script .= " + + \$this->alreadyInValidation = false; + } + + return (!empty(\$failureMap) ? \$failureMap : true); + } +"; + } // addDoValidate() + + /** + * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects. + * @param string &$script The script will be modified in this method. + */ + protected function addCopy(&$script) + { + $this->addCopyInto($script); + + $table = $this->getTable(); + + $script .= " + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ".$table->getPhpName()." Clone of current object. + * @throws PropelException + */ + public function copy(\$deepCopy = false) + { + // we use get_class(), because this might be a subclass + \$clazz = get_class(\$this); + \$copyObj = new \$clazz(); + \$this->copyInto(\$copyObj, \$deepCopy); + return \$copyObj; + } +"; + } // addCopy() + + /** + * Adds the copyInto() method, which takes an object and sets contents to match current object. + * In complex OM this method includes the $deepCopy param for making copies of related objects. + * @param string &$script The script will be modified in this method. + */ + protected function addCopyInto(&$script) + { + $table = $this->getTable(); + + $script .= " + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object \$copyObj An object of ".$table->getPhpName()." (or compatible) type. + * @param boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto(\$copyObj, \$deepCopy = false) + { +"; + + $pkcols = array(); + foreach ($table->getColumns() as $pkcol) { + if ($pkcol->isPrimaryKey()) { + $pkcols[] = $pkcol->getName(); + } + } + + foreach ($table->getColumns() as $col) { + if (!in_array($col->getName(), $pkcols)) { + $script .= " + \$copyObj->set".$col->getPhpName()."(\$this->".strtolower($col->getName())."); +"; + } + } // foreach + + // Avoid useless code by checking to see if there are any referrers + // to this table: + if (count($table->getReferrers()) > 0) { + $script .= " + + if (\$deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + \$copyObj->setNew(false); +"; + foreach ($table->getReferrers() as $fk) { + // Continue if $this and $copyObj are the same class and have the same primary key + // to avoid endless loops + $script .= " + foreach(\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {"; + if ($table->getName() === $fk->getTableName()) { + $script .= " + if(\$this->getPrimaryKey() === \$relObj->getPrimaryKey()) { + continue; + } +"; + } + $script .= " + \$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy)); + } +"; + // HL: commenting out close of self-referential check + // } /* if tblFK != table */ + } /* foreach */ + $script .= " + } // if (\$deepCopy) +"; + } /* if (count referrers > 0 ) */ + + $script .= " + + \$copyObj->setNew(true); +"; + + + foreach ($table->getColumns() as $col) { + if ($col->isPrimaryKey()) { + $coldefval = $col->getPhpDefaultValue(); + $coldefval = var_export($coldefval, true); + $script .= " + \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a pkey column, so set to default value +"; + } // if col->isPrimaryKey + } // foreach + $script .= " + } +"; + } // addCopyInto() + +} // PHP5ComplexObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexPeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexPeerBuilder.php new file mode 100644 index 000000000..d2738c9fb --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ComplexPeerBuilder.php @@ -0,0 +1,866 @@ +. + */ + +require_once 'propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php'; + +/** + * Generates a PHP5 base Peer class with complex object model methods. + * + * This class extends the basic peer builder by adding on the doSelectJoin*() + * methods and other complex object model methods. + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ComplexPeerBuilder extends PHP5BasicPeerBuilder { + + /** + * Adds the complex OM methods to the base addSelectMethods() function. + * @param string &$script The script will be modified in this method. + * @see PeerBuilder::addSelectMethods() + */ + protected function addSelectMethods(&$script) + { + $table = $this->getTable(); + + parent::addSelectMethods($script); + + $this->addDoCountJoin($script); + $this->addDoSelectJoin($script); + + $countFK = count($table->getForeignKeys()); + + $includeJoinAll = true; + + foreach ($this->getTable()->getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + if ($tblFK->isForReferenceOnly()) { + $includeJoinAll = false; + } + } + + if ($includeJoinAll) { + if($countFK > 0) { + $this->addDoCountJoinAll($script); + $this->addDoSelectJoinAll($script); + } + if ($countFK > 1) { + $this->addDoCountJoinAllExcept($script); + $this->addDoSelectJoinAllExcept($script); + } + } + + } + + /** + * Adds the doSelectJoin*() methods. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelectJoin(&$script) + { + $table = $this->getTable(); + $className = $table->getPhpName(); + $countFK = count($table->getForeignKeys()); + + if ($countFK >= 1) { + + foreach ($table->getForeignKeys() as $fk) { + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + + if (!$joinTable->isForReferenceOnly()) { + + // FIXME - look into removing this next condition; it may not + // be necessary: + // --- IT is necessary because there needs to be a system for + // aliasing the table if it is the same table. + if ( $fk->getForeignTableName() != $table->getName() ) { + + /* + REPLACED BY USING THE ObjectBuilder objects below + + // check to see if we need to add something to the method name. + // For example if there are multiple columns that reference the same + // table, then we have to have a methd name like doSelectJoinBooksByBookId + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + // this second part is not currently ever true (right?) + if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) { + $partJoinName = $partJoinName . $column->getPhpName(); + } + } + + + $joinClassName = $joinTable->getPhpName(); + + if ($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } else { + $interfaceName = $joinTable->getPhpName(); + } + + if ($partJoinName == "") { + $joinColumnId = $joinClassName; + $joinInterface = $interfaceName; + $collThisTable = $className . "s"; + $collThisTableMs = $className; + } else { + $joinColumnId = $joinClassName . "RelatedBy" . $partJoinName; + $joinInterface = $interfaceName . "RelatedBy" . $partJoinName; + $collThisTable = $className . "sRelatedBy" . $partJoinName; + $collThisTableMs = $className . "RelatedBy" . $partJoinName; + } + */ + + $joinClassName = $joinTable->getPhpName(); + + $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table); + $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $script .= " + + /** + * Selects a collection of $className objects pre-filled with their $joinClassName objects. + * + * @return array Array of $className objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null) + { + \$c = clone \$c; + + // Set the correct dbName if it has not been overridden + if (\$c->getDbName() == Propel::getDefaultDB()) { + \$c->setDbName(self::DATABASE_NAME); + } + + ".$this->getPeerClassname()."::addSelectColumns(\$c); + \$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1; + ".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c); +"; + + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName] ); + $script .= " + \$c->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk).");"; //CHECKME + } + $script .= " + \$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con); + \$results = array(); + + while(\$rs->next()) { +"; + if ($table->getChildrenColumn()) { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1); +"; + } else { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(); +"; + } + $script .= " + \$cls = Propel::import(\$omClass); + \$obj1 = new \$cls(); + \$obj1->hydrate(\$rs); +"; + if ($joinTable->getChildrenColumn()) { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol); +"; + } else { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(); +"; + } + + $script .= " + \$cls = Propel::import(\$omClass); + \$obj2 = new \$cls(); + \$obj2->hydrate(\$rs, \$startcol); + + \$newObject = true; + foreach(\$results as \$temp_obj1) { + \$temp_obj2 = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(); //CHECKME + if (\$temp_obj2->getPrimaryKey() === \$obj2->getPrimaryKey()) { + \$newObject = false; + // e.g. \$author->addBookRelatedByBookId() + \$temp_obj2->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); //CHECKME + break; + } + } + if (\$newObject) { + \$obj2->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = true)."(); + \$obj2->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); //CHECKME + } + \$results[] = \$obj1; + } + return \$results; + } +"; + } // if fk table name != this table name + } // if ! is reference only + } // foreach column + } // if count(fk) > 1 + + } // addDoSelectJoin() + + /** + * Adds the doCountJoin*() methods. + * @param string &$script The script will be modified in this method. + */ + protected function addDoCountJoin(&$script) + { + $table = $this->getTable(); + $className = $table->getPhpName(); + $countFK = count($table->getForeignKeys()); + + if ($countFK >= 1) { + + foreach ($table->getForeignKeys() as $fk) { + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + + if (!$joinTable->isForReferenceOnly()) { + + if ( $fk->getForeignTableName() != $table->getName() ) { + + $joinClassName = $joinTable->getPhpName(); + + $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table); + $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $script .= " + + /** + * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table + * + * @param Criteria \$c + * @param boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection \$con + * @return int Number of matching rows. + */ + public static function doCountJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, \$con = null) + { + // we're going to modify criteria, so copy it first + \$criteria = clone \$criteria; + + // clear out anything that might confuse the ORDER BY clause + \$criteria->clearSelectColumns()->clearOrderByColumns(); + if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT); + } else { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach(\$criteria->getGroupByColumns() as \$column) + { + \$criteria->addSelectColumn(\$column); + } +"; + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName] ); + $script .= " + \$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk)."); +"; + } + $script .= " + \$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con); + if (\$rs->next()) { + return \$rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } +"; + } // if fk table name != this table name + } // if ! is reference only + } // foreach column + } // if count(fk) > 1 + + } // addDoCountJoin() + + /** + * Adds the doSelectJoinAll() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelectJoinAll(&$script) + { + $table = $this->getTable(); + $className = $table->getPhpName(); + + $script .= " + + /** + * Selects a collection of $className objects pre-filled with all related objects. + * + * @return array Array of $className objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoinAll(Criteria \$c, \$con = null) + { + \$c = clone \$c; + + // Set the correct dbName if it has not been overridden + if (\$c->getDbName() == Propel::getDefaultDB()) { + \$c->setDbName(self::DATABASE_NAME); + } + + ".$this->getPeerClassname()."::addSelectColumns(\$c); + \$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1; +"; + $index = 2; + foreach ($table->getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + // FIXME: why "is the code not there yet" ? + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $new_index = $index + 1; + + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $script .= " + ".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c); + \$startcol$new_index = \$startcol$index + ".$joinedTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS; +"; + $index = $new_index; + + } // if fk->getForeignTableName != table->getName + } // foreach [sub] foreign keys + + + foreach ($table->getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $joinClassName = $joinTable->getPhpName(); + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); + $script .= " + \$c->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk)."); +"; + } + } + } + + $script .= " + \$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con); + \$results = array(); + + while(\$rs->next()) { +"; + + if ($table->getChildrenColumn()) { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1); +"; + } else { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(); +"; + } + + $script .= " + + \$cls = Propel::import(\$omClass); + \$obj1 = new \$cls(); + \$obj1->hydrate(\$rs); +"; + + $index = 1; + foreach ($table->getForeignKeys() as $fk ) { + + // want to cover this case, but the code is not there yet. + // FIXME -- why not? -because we'd have to alias the tables in the JOIN + if ( $fk->getForeignTableName() != $table->getName() ) { + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + /* + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + */ + + $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table); + $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + + $index++; + + $script .= " + + // Add objects for joined $joinClassName rows + "; + if ($joinTable->getChildrenColumn()) { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol$index); +"; + } else { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(); +"; + } /* $joinTable->getChildrenColumn() */ + + $script .= " + + \$cls = Propel::import(\$omClass); + \$obj".$index." = new \$cls(); + \$obj".$index."->hydrate(\$rs, \$startcol$index); + + \$newObject = true; + for (\$j=0, \$resCount=count(\$results); \$j < \$resCount; \$j++) { + \$temp_obj1 = \$results[\$j]; + \$temp_obj$index = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(); // CHECKME + if (\$temp_obj".$index."->getPrimaryKey() === \$obj".$index."->getPrimaryKey()) { + \$newObject = false; + \$temp_obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); // CHECKME + break; + } + } + + if (\$newObject) { + \$obj".$index."->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = true)."(); + \$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); + } +"; + + } // $fk->getForeignTableName() != $table->getName() + } //foreach foreign key + + $script .= " + \$results[] = \$obj1; + } + return \$results; + } +"; + + } // end addDoSelectJoinAll() + + /** + * Adds the doCountJoinAll() method. + * @param string &$script The script will be modified in this method. + */ + protected function addDoCountJoinAll(&$script) + { + $table = $this->getTable(); + $className = $table->getPhpName(); + + $script .= " + + /** + * Returns the number of rows matching criteria, joining all related tables + * + * @param Criteria \$c + * @param boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection \$con + * @return int Number of matching rows. + */ + public static function doCountJoinAll(Criteria \$criteria, \$distinct = false, \$con = null) + { + \$criteria = clone \$criteria; + + // clear out anything that might confuse the ORDER BY clause + \$criteria->clearSelectColumns()->clearOrderByColumns(); + if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT); + } else { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach(\$criteria->getGroupByColumns() as \$column) + { + \$criteria->addSelectColumn(\$column); + } +"; + + foreach ($table->getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $joinClassName = $joinTable->getPhpName(); + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); + $script .= " + \$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk)."); +"; + } + } // if fk->getForeignTableName != table->getName + } // foreach [sub] foreign keys + + $script .= " + \$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con); + if (\$rs->next()) { + return \$rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } +"; + } // end addDoCountJoinAll() + + /** + * Adds the doSelectJoinAllExcept*() methods. + * @param string &$script The script will be modified in this method. + */ + protected function addDoSelectJoinAllExcept(&$script) + { + $table = $this->getTable(); + + // ------------------------------------------------------------------------ + // doSelectJoinAllExcept*() + // ------------------------------------------------------------------------ + + // 2) create a bunch of doSelectJoinAllExcept*() methods + // -- these were existing in original Torque, so we should keep them for compatibility + + $fkeys = $table->getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over + // getForeignKeys() will cause this to only execute one time. + foreach ($fkeys as $fk ) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $excludedClassName = $excludedTable->getPhpName(); + + /* + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $excludeString = $excludedClassName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $excludeString = $excludedClassName . "RelatedBy" . $relatedByCol; + $collThisTable = $className . "sRelatedBy" . $relatedByCol; + $collThisTableMs = $className . "RelatedBy" . $relatedByCol; + } + */ + + $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table); + $excludedTableObjectBuilder = OMBuilder::getNewObjectBuilder($excludedTable); + $excludedTablePeerBuilder = OMBuilder::getNewPeerBuilder($excludedTable); + + $script .= " + + /** + * Selects a collection of ".$table->getPhpName()." objects pre-filled with all related objects except ".$thisTableObjectBuilder->getFKPhpNameAffix($fk).". + * + * @return array Array of ".$table->getPhpName()." objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null) + { + \$c = clone \$c; + + // Set the correct dbName if it has not been overridden + // \$c->getDbName() will return the same object if not set to another value + // so == check is okay and faster + if (\$c->getDbName() == Propel::getDefaultDB()) { + \$c->setDbName(self::DATABASE_NAME); + } + + ".$this->getPeerClassname()."::addSelectColumns(\$c); + \$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1; +"; + $index = 2; + foreach ($table->getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + // FIXME - why not? + if ( !($subfk->getForeignTableName() == $table->getName())) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + if ($joinClassName != $excludedClassName) { + $new_index = $index + 1; + $script .= " + ".$joinTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c); + \$startcol$new_index = \$startcol$index + ".$joinTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS; +"; + $index = $new_index; + } // if joinClassName not excludeClassName + } // if subfk is not curr table + } // foreach [sub] foreign keys + + foreach ($table->getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + if($joinClassName != $excludedClassName) + { + $lfMap = $subfk->getLocalForeignMapping(); + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); + $script .= " + \$c->addJoin(".$this->getColumnConstant($column).", ".$joinTablePeerBuilder->getColumnConstant($columnFk)."); +"; + } + } + } + } // foreach fkeys + $script .= " + + \$rs = ".$this->basePeerClassname ."::doSelect(\$c, \$con); + \$results = array(); + + while(\$rs->next()) { +"; + if ($table->getChildrenColumn()) { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1); +"; + } else { + $script .= " + \$omClass = ".$this->getPeerClassname()."::getOMClass(); +"; + } + + $script .= " + \$cls = Propel::import(\$omClass); + \$obj1 = new \$cls(); + \$obj1->hydrate(\$rs); +"; + + $index = 1; + foreach ($table->getForeignKeys() as $subfk ) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + if ($joinClassName != $excludedClassName) { + + /* + $partJoinName = ""; + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + */ + + $joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable); + $joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + $index++; + + if ($joinTable->getChildrenColumn()) { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol$index); +"; + } else { + $script .= " + \$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(); +"; + } /* $joinTable->getChildrenColumn() */ + + $script .= " + + \$cls = Propel::import(\$omClass); + \$obj$index = new \$cls(); + \$obj".$index."->hydrate(\$rs, \$startcol$index); + + \$newObject = true; + for (\$j=0, \$resCount=count(\$results); \$j < \$resCount; \$j++) { + \$temp_obj1 = \$results[\$j]; + \$temp_obj$index = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($subfk, $plural=false)."(); //CHECKME + if (\$temp_obj".$index."->getPrimaryKey() === \$obj".$index."->getPrimaryKey()) { + \$newObject = false; + \$temp_obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=false)."(\$obj1); + break; + } + } + + if (\$newObject) { + \$obj".$index."->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=true)."(); + \$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=false)."(\$obj1); + } +"; + } // if ($joinClassName != $excludedClassName) { + } // $subfk->getForeignTableName() != $table->getName() + } // foreach + $script .= " + \$results[] = \$obj1; + } + return \$results; + } +"; + } // foreach fk + + } // addDoSelectJoinAllExcept + + /** + * Adds the doCountJoinAllExcept*() methods. + * @param string &$script The script will be modified in this method. + */ + protected function addDoCountJoinAllExcept(&$script) + { + $table = $this->getTable(); + + $fkeys = $table->getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over + // getForeignKeys() will cause this to only execute one time. + foreach ($fkeys as $fk ) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $excludedClassName = $excludedTable->getPhpName(); + + $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table); + $excludedTableObjectBuilder = OMBuilder::getNewObjectBuilder($excludedTable); + $excludedTablePeerBuilder = OMBuilder::getNewPeerBuilder($excludedTable); + + $script .= " + + /** + * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table + * + * @param Criteria \$c + * @param boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection \$con + * @return int Number of matching rows. + */ + public static function doCountJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, \$con = null) + { + // we're going to modify criteria, so copy it first + \$criteria = clone \$criteria; + + // clear out anything that might confuse the ORDER BY clause + \$criteria->clearSelectColumns()->clearOrderByColumns(); + if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT); + } else { + \$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach(\$criteria->getGroupByColumns() as \$column) + { + \$criteria->addSelectColumn(\$column); + } +"; + + foreach ($table->getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable); + + if($joinClassName != $excludedClassName) + { + $lfMap = $subfk->getLocalForeignMapping(); + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); + $script .= " + \$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinTablePeerBuilder->getColumnConstant($columnFk)."); +"; + } + } + } + } // foreach fkeys + $script .= " + \$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con); + if (\$rs->next()) { + return \$rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } +"; + } // foreach fk + + } // addDoCountJoinAllExcept + +} // PHP5ComplexPeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php new file mode 100644 index 000000000..0da472ed4 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php @@ -0,0 +1,124 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates the empty PHP5 stub node object class for user object model (OM). + * + * This class produces the empty stub class that can be customized with application + * business logic, custom behavior, etc. + * + * This class replaces the ExtensionNode.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ExtensionNodeBuilder extends ObjectBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getTable()->getPhpName() . 'Node'; + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + + $script .= " +require_once '".$this->getNodeBuilder()->getClassFilePath()."'; +"; + + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getNodeBuilder()->getClassname(); + + $script .= " + +/** + * Skeleton subclass for representing a node from the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." extends $baseClassname { +"; + } + + /** + * Specifies the methods that are added as part of the stub object class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + // there is no class body + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php new file mode 100644 index 000000000..8c60004d5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php @@ -0,0 +1,127 @@ +. + */ + +require_once 'propel/engine/builder/om/PeerBuilder.php'; + +/** + * Generates the empty PHP5 stub node peer class for user object model (OM). + * + * This class produces the empty stub class that can be customized with application + * business logic, custom behavior, etc. + * + * This class replaces the ExtensionNodePeer.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ExtensionNodePeerBuilder extends PeerBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getStubNodeBuilder()->getClassname() . 'Peer'; + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " + // include base nodepeer class + require_once '".$this->getNodePeerBuilder()->getClassFilePath()."'; + + // include node class + include_once '".$this->getStubNodeBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getNodePeerBuilder()->getClassname(); + + $script .= " + +/** + * Skeleton subclass for performing query and update operations on nodes of the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." extends $baseClassname { +"; + } + + /** + * Specifies the methods that are added as part of the stub peer class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + + protected function addClassBody(&$script) + { + // there is no class body + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionPeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php new file mode 100644 index 000000000..6efe8c0be --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php @@ -0,0 +1,123 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates the empty PHP5 stub object class for user object model (OM). + * + * This class produces the empty stub class that can be customized with application + * business logic, custom behavior, etc. + * + * This class replaces the ExtensionObject.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ExtensionObjectBuilder extends ObjectBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getTable()->getPhpName(); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " +require_once '".$this->getObjectBuilder()->getClassFilePath()."'; +"; + + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getObjectBuilder()->getClassname(); + + $script .= " + +/** + * Skeleton subclass for representing a row from the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." extends $baseClassname { +"; + } + + /** + * Specifies the methods that are added as part of the stub object class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + // there is no class body + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php new file mode 100644 index 000000000..2badbb12d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php @@ -0,0 +1,127 @@ +. + */ + +require_once 'propel/engine/builder/om/PeerBuilder.php'; + +/** + * Generates the empty PHP5 stub peer class for user object model (OM). + * + * This class produces the empty stub class that can be customized with application + * business logic, custom behavior, etc. + * + * This class replaces the ExtensionPeer.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5ExtensionPeerBuilder extends PeerBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getStubObjectBuilder()->getClassname() . 'Peer'; + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " + // include base peer class + require_once '".$this->getPeerBuilder()->getClassFilePath()."'; + + // include object class + include_once '".$this->getStubObjectBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getPeerBuilder()->getClassname(); + + $script .= " + +/** + * Skeleton subclass for performing query and update operations on the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." extends $baseClassname { +"; + } + + /** + * Specifies the methods that are added as part of the stub peer class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + + protected function addClassBody(&$script) + { + // there is no class body + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionPeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php new file mode 100644 index 000000000..536795728 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php @@ -0,0 +1,119 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates the empty PHP5 stub interface for user object model (OM). + * + * This class produces the empty stub interface when the interface="" attribute is used + * in the the schema xml. + * + * This class replaces the Interface.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5InterfaceBuilder extends ObjectBuilder { + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return ClassTools::classname($this->getInterface()); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getObjectBuilder()->getClassname(); + + $script .= " +/** + * This is an interface that should be filled with the public api of the $tableName objects. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional method declarations to this interface to meet the + * application requirements. This interface will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +interface ".$this->getClassname()." { +"; + } + + /** + * Specifies the methods that are added as part of the stub object class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + // there is no class body + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php new file mode 100644 index 000000000..cbecbe72a --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php @@ -0,0 +1,300 @@ +. + */ + +require_once 'propel/engine/builder/om/OMBuilder.php'; + +/** + * Generates the PHP5 map builder class for user object model (OM). + * + * This class replaces the MapBuilder.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5MapBuilderBuilder extends OMBuilder { + + /** + * Gets the package for the map builder classes. + * @return string + */ + public function getPackage() + { + return parent::getPackage() . '.map'; + } + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getTable()->getPhpName() . 'MapBuilder'; + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; +"; + + + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + $table = $this->getTable(); + $script .= " + +/** + * This class adds structure of '".$table->getName()."' table to '".$table->getDatabase()->getName()."' DatabaseMap object. + * + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." { +"; + } + + /** + * Specifies the methods that are added as part of the map builder class. + * This can be overridden by subclasses that wish to add more methods. + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $this->addConstants($script); + $this->addAttributes($script); + + $this->addIsBuilt($script); + $this->addGetDatabaseMap($script); + $this->addDoBuild($script); + } + + /** + * Adds any constants needed for this MapBuilder class. + * @param string &$script The script will be modified in this method. + */ + protected function addConstants(&$script) + { + $script .= " + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = '".$this->getClasspath()."'; +"; + } + + /** + * Adds any attributes needed for this MapBuilder class. + * @param string &$script The script will be modified in this method. + */ + protected function addAttributes(&$script) + { + $script .= " + /** + * The database map. + */ + private \$dbMap; +"; + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + + /** + * Adds the method that indicates whether this map has already been built. + * @param string &$script The script will be modified in this method. + */ + protected function addIsBuilt(&$script) + { + $script .= " + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return (\$this->dbMap !== null); + } +"; + } + + /** + * Adds the DatabaseMap accessor method. + * @param string &$script The script will be modified in this method. + */ + protected function addGetDatabaseMap(&$script) + { + $script .= " + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return \$this->dbMap; + } +"; + } + + /** + * Adds the main doBuild() method to the map builder class. + * @param string &$script The script will be modified in this method. + */ + protected function addDoBuild(&$script) + { + + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + \$this->dbMap = Propel::getDatabaseMap('".$table->getDatabase()->getName()."'); + + \$tMap = \$this->dbMap->addTable('".$table->getName()."'); + \$tMap->setPhpName('".$table->getPhpName()."'); +"; + if ($table->getIdMethod() == "native") { + $script .= " + \$tMap->setUseIdGenerator(true); +"; + } else { + $script .= " + \$tMap->setUseIdGenerator(false); +"; + } + + if ($table->getIdMethodParameters()) { + $params = $table->getIdMethodParameters(); + $imp = $params[0]; + $script .= " + \$tMap->setPrimaryKeyMethodInfo('".$imp->getValue()."'); +"; + } elseif ($table->getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { + $script .= " + \$tMap->setPrimaryKeyMethodInfo('".$table->getSequenceName()."'); +"; + } elseif ($table->getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { + $script .= " + \$tMap->setPrimaryKeyMethodInfo('".$table->getName()."'); +"; + } + + // Add columns to map + foreach ($table->getColumns() as $col) { + $tfc=$table->getPhpName(); + $cfc=$col->getPhpName(); + $cup=strtoupper($col->getName()); + if (!$col->getSize()) { + $size = "null"; + } else { + $size = $col->getSize(); + } + if($col->isPrimaryKey()) { + if($col->isForeignKey()) { + $script .= " + \$tMap->addForeignPrimaryKey('$cup', '$cfc', '".$col->getPhpType()."' , CreoleTypes::".$col->getType().", '".$col->getRelatedTableName()."', '".strtoupper($col->getRelatedColumnName())."', ".($col->isNotNull() ? 'true' : 'false').", ".$size."); +"; + } else { + $script .= " + \$tMap->addPrimaryKey('$cup', '$cfc', '".$col->getPhpType()."', CreoleTypes::".$col->getType().", ".var_export($col->isNotNull(), true).", ".$size."); +"; + } + } else { + if($col->isForeignKey()) { + $script .= " + \$tMap->addForeignKey('$cup', '$cfc', '".$col->getPhpType()."', CreoleTypes::".$col->getType().", '".$col->getRelatedTableName()."', '".strtoupper($col->getRelatedColumnName())."', ".($col->isNotNull() ? 'true' : 'false').", ".$size."); +"; + } else { + $script .= " + \$tMap->addColumn('$cup', '$cfc', '".$col->getPhpType()."', CreoleTypes::".$col->getType().", ".var_export($col->isNotNull(), true).", ".$size."); +"; + } + } // if col-is prim key + } // foreach + + foreach($table->getValidators() as $val) { + $col = $val->getColumn(); + $cup = strtoupper($col->getName()); + foreach($val->getRules() as $rule) { + if ($val->getTranslate() !== Validator::TRANSLATE_NONE) { + $script .= " + \$tMap->addValidator('$cup', '".$rule->getName()."', '".$rule->getClass()."', '".$rule->getValue()."', ".$val->getTranslate()."('".str_replace("'", "\'", $rule->getMessage())."')); +"; + } else { + $script .= " + \$tMap->addValidator('$cup', '".$rule->getName()."', '".$rule->getClass()."', '".$rule->getValue()."', '".str_replace("'", "\'", $rule->getMessage())."'); +"; + } // if ($rule->getTranslation() ... + } // foreach rule + } // foreach validator + + $script .= " + } // doBuild() +"; + + } + +} // PHP5ExtensionPeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php new file mode 100644 index 000000000..0cc572692 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php @@ -0,0 +1,209 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates the empty PHP5 stub object class for use with inheritance in the user object model (OM). + * + * This class produces the empty stub class that can be customized with application + * business logic, custom behavior, etc. + * + * This class replaces the MultiExtendObject.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5MultiExtendObjectBuilder extends ObjectBuilder { + + /** + * The current child "object" we are operating on. + */ + private $child; + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getChild()->getClassName(); + } + + /** + * Override method to return child package, if specified. + * @return string + */ + public function getPackage() + { + return ($this->child->getPackage() ? $this->child->getPackage() : parent::getPackage()); + } + + /** + * Set the child object that we're operating on currrently. + * @param $child Inheritance + */ + public function setChild(Inheritance $child) + { + $this->child = $child; + } + + /** + * Returns the child object we're operating on currently. + * @return Inheritance + * @throws BuildException - if child was not set. + */ + public function getChild() + { + if (!$this->child) { + throw new BuildException("The PHP5MultiExtendObjectBuilder needs to be told which child class to build (via setChild() method) before it can build the stub class."); + } + return $this->child; + } + + /** + * Returns classpath to parent class. + * @return string + */ + protected function getParentClasspath() + { + if ($this->getChild()->getAncestor()) { + return $this->getChild()->getAncestor(); + } else { + return $this->getObjectBuilder()->getClasspath(); + } + } + + /** + * Returns classname of parent class. + * @return string + */ + protected function getParentClassname() + { + return ClassTools::classname($this->getParentClasspath()); + } + + /** + * Gets the file path to the parent class. + * @return string + */ + protected function getParentClassFilePath() + { + return $this->getFilePath($this->getParentClasspath()); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " +require_once '".$this->getParentClassFilePath()."'; +"; + $script .= " +require_once '".$this->getObjectBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $baseClassname = $this->getObjectBuilder()->getClassname(); + + $script .= " + +/** + * Skeleton subclass for representing a row from one of the subclasses of the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package ".$this->getPackage()." + */ +class ".$this->getClassname()." extends ".$this->getParentClassname()." { +"; + } + + /** + * Specifies the methods that are added as part of the stub object class. + * + * By default there are no methods for the empty stub classes; override this method + * if you want to change that behavior. + * + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $child = $this->getChild(); + $col = $child->getColumn(); + $cfc = $col->getPhpName(); + + $const = "CLASSKEY_".strtoupper($child->getKey()); + + $script .= " + /** + * Constructs a new ".$this->getChild()->getClassName()." class, setting the ".$col->getName()." column to ".$this->getPeerClassname()."::$const. + */ + public function __construct() + { +"; + + $script .= " + \$this->set$cfc(".$this->getPeerClassname()."::CLASSKEY_".strtoupper($child->getKey())."); + } +"; + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + +} // PHP5ExtensionObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php new file mode 100644 index 000000000..a9d538387 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php @@ -0,0 +1,1115 @@ +. + */ + +require_once 'propel/engine/builder/om/ObjectBuilder.php'; + +/** + * Generates a PHP5 tree node Object class for user object model (OM). + * + * This class produces the base tree node object class (e.g. BaseMyTable) which contains all + * the custom-built accessor and setter methods. + * + * This class replaces the Node.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5NodeBuilder extends ObjectBuilder { + + /** + * Gets the package for the [base] object classes. + * @return string + */ + public function getPackage() + { + return parent::getPackage() . ".om"; + } + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getBuildProperty('basePrefix') . $this->getStubNodeBuilder()->getClassname(); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " +require_once '".$this->getStubNodePeerBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $script .= " +/** + * Base class that represents a row from the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * @package ".$this->getPackage()." + */ +abstract class ".$this->getClassname()." implements IteratorAggregate { +"; + } + + /** + * Specifies the methods that are added as part of the basic OM class. + * This can be overridden by subclasses that wish to add more methods. + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $table = $this->getTable(); + + $this->addAttributes($script); + + $this->addConstructor($script); + + $this->addCallOverload($script); + $this->addSetIteratorOptions($script); + $this->addGetIterator($script); + + $this->addGetNodeObj($script); + $this->addGetNodePath($script); + $this->addGetNodeIndex($script); + $this->addGetNodeLevel($script); + + $this->addHasChildNode($script); + $this->addGetChildNodeAt($script); + $this->addGetFirstChildNode($script); + $this->addGetLastChildNode($script); + $this->addGetSiblingNode($script); + + $this->addGetParentNode($script); + $this->addGetAncestors($script); + $this->addIsRootNode($script); + + $this->addSetNew($script); + $this->addSetDeleted($script); + $this->addAddChildNode($script); + $this->addMoveChildNode($script); + $this->addSave($script); + + $this->addDelete($script); + $this->addEquals($script); + + $this->addAttachParentNode($script); + $this->addAttachChildNode($script); + $this->addDetachParentNode($script); + $this->addDetachChildNode($script); + $this->addShiftChildNodes($script); + $this->addInsertNewChildNode($script); + + $this->addAdjustStatus($script); + $this->addAdjustNodePath($script); + + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + + + /** + * Adds class attributes. + * @param string &$script The script will be modified in this method. + */ + protected function addAttributes(&$script) + { + $script .= " + /** + * @var ".$this->getStubObjectBuilder()->getClassname()." object wrapped by this node. + */ + protected \$obj = null; + + /** + * The parent node for this node. + * @var ".$this->getStubNodeBuilder()->getClassname()." + */ + protected \$parentNode = null; + + /** + * Array of child nodes for this node. Nodes indexes are one-based. + * @var array + */ + protected \$childNodes = array(); +"; + } + + /** + * Adds the constructor. + * @param string &$script The script will be modified in this method. + */ + protected function addConstructor(&$script) + { + $script .= " + /** + * Constructor. + * + * @param ".$this->getStubObjectBuilder()->getClassname()." \$obj Object wrapped by this node. + */ + public function __construct(\$obj = null) + { + if (\$obj !== null) { + \$this->obj = \$obj; + } else { + \$setNodePath = 'set' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME; + \$this->obj = new ".$this->getStubObjectBuilder()->getClassname()."(); + \$this->obj->\$setNodePath('0'); + } + } +"; + } + + + + protected function addCallOverload(&$script) + { + $script .= " + /** + * Convenience overload for wrapped object methods. + * + * @param string Method name to call on wrapped object. + * @param mixed Parameter accepted by wrapped object set method. + * @return mixed Return value of wrapped object method. + * @throws PropelException Fails if method is not defined for wrapped object. + */ + public function __call(\$name, \$parms) + { + if (method_exists(\$this->obj, \$name)) + return call_user_func_array(array(\$this->obj, \$name), \$parms); + else + throw new PropelException('get method not defined: \$name'); + } +"; + } + + protected function addSetIteratorOptions(&$script) + { + $script .= " + + /** + * Sets the default options for iterators created from this object. + * The options are specified in map format. The following options + * are supported by all iterators. Some iterators may support other + * options: + * + * \"querydb\" - True if nodes should be retrieved from database. + * \"con\" - Connection to use if retrieving from database. + * + * @param string Type of iterator to use (\"pre\", \"post\", \"level\"). + * @param array Map of option name => value. + * @return void + * @todo Implement other iterator types (i.e. post-order, level, etc.) + */ + public function setIteratorOptions(\$type, \$opts) + { + \$this->itType = \$type; + \$this->itOpts = \$opts; + } +"; + } + + protected function addGetIterator(&$script) + { + $script .= " + /** + * Returns a pre-order iterator for this node and its children. + * + * @param string Type of iterator to use (\"pre\", \"post\", \"level\") + * @param array Map of option name => value. + * @return NodeIterator + */ + public function getIterator(\$type = null, \$opts = null) + { + if (\$type === null) + \$type = (isset(\$this->itType) ? \$this->itType : 'Pre'); + + if (\$opts === null) + \$opts = (isset(\$this->itOpts) ? \$this->itOpts : array()); + + \$itclass = ucfirst(strtolower(\$type)) . 'OrderNodeIterator'; + + require_once('propel/om/' . \$itclass . '.php'); + return new \$itclass(\$this, \$opts); + } +"; + } + + protected function addGetNodeObj(&$script) + { + $script .= " + /** + * Returns the object wrapped by this class. + * @return ".$this->getStubObjectBuilder()->getClassname()." + */ + public function getNodeObj() + { + return \$this->obj; + } +"; + } + + protected function addGetNodePath(&$script) + { + $script .= " + /** + * Convenience method for retrieving nodepath. + * @return string + */ + public function getNodePath() + { + \$getNodePath = 'get' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME; + return \$this->obj->\$getNodePath(); + } +"; + } + + protected function addGetNodeIndex(&$script) + { + $script .= " + /** + * Returns one-based node index among siblings. + * @return int + */ + public function getNodeIndex() + { + \$npath =& \$this->getNodePath(); + \$sep = strrpos(\$npath, ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP); + return (int) (\$sep !== false ? substr(\$npath, \$sep+1) : \$npath); + } +"; + } + + protected function addGetNodeLevel(&$script) + { + $script .= " + /** + * Returns one-based node level within tree (root node is level 1). + * @return int + */ + public function getNodeLevel() + { + return (substr_count(\$this->getNodePath(), ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP) + 1); + } +"; + } + + protected function addHasChildNode(&$script) + { + $script .= " + /** + * Returns true if specified node is a child of this node. If recurse is + * true, checks if specified node is a descendant of this node. + * + * @param ".$this->getStubNodeBuilder()->getClassname()." Node to look for. + * @param boolean True if strict comparison should be used. + * @param boolean True if all descendants should be checked. + * @return boolean + */ + public function hasChildNode(\$node, \$strict = false, \$recurse = false) + { + foreach (\$this->childNodes as \$childNode) + { + if (\$childNode->equals(\$node, \$strict)) + return true; + + if (\$recurse && \$childNode->hasChildNode(\$node, \$recurse)) + return true; + } + + return false; + } +"; + } + + protected function addGetChildNodeAt(&$script) + { + $script .= " + /** + * Returns child node at one-based index. Retrieves from database if not + * loaded yet. + * + * @param int One-based child node index. + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return ".$this->getStubNodeBuilder()->getClassname()." + */ + public function getChildNodeAt(\$i, \$querydb = false, \$con = null) + { + if (\$querydb && + !\$this->obj->isNew() && + !\$this->obj->isDeleted() && + !isset(\$this->childNodes[\$i])) + { + \$criteria = new Criteria(".$this->getStubPeerBuilder()->getClassname()."::DATABASE_NAME); + \$criteria->add(".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_COLNAME, \$this->getNodePath() . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP . \$i, Criteria::EQUAL); + + if (\$childObj = ".$this->getStubPeerBuilder()->getClassname()."::doSelectOne(\$criteria, \$con)) + \$this->attachChildNode(new ".$this->getStubNodeBuilder()->getClassname()."(\$childObj)); + } + + return (isset(\$this->childNodes[\$i]) ? \$this->childNodes[\$i] : null); + } +"; + } + + protected function addGetFirstChildNode(&$script) + { + $script .= " + /** + * Returns first child node (if any). Retrieves from database if not loaded yet. + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return ".$this->getStubNodeBuilder()->getClassname()." + */ + public function getFirstChildNode(\$querydb = false, \$con = null) + { + return \$this->getChildNodeAt(1, \$querydb, \$con); + } +"; + } + + protected function addGetLastChildNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Returns last child node (if any). + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + */ + public function getLastChildNode(\$querydb = false, \$con = null) + { + \$lastNode = null; + + if (\$this->obj->isNew() || \$this->obj->isDeleted()) + { + end(\$this->childNodes); + \$lastNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null); + } + else if (\$querydb) + { + \$db = Propel::getDb($peerClassname::DATABASE_NAME); + \$criteria = new Criteria($peerClassname::DATABASE_NAME); + \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%', Criteria::LIKE); + \$criteria->addAnd($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%' . $nodePeerClassname::NPATH_SEP . '%', Criteria::NOT_LIKE); + \$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME)); + \$criteria->addDescendingOrderByColumn('npathlen'); + \$criteria->addDescendingOrderByColumn($nodePeerClassname::NPATH_COLNAME); + + \$lastObj = $peerClassname::doSelectOne(\$criteria, \$con); + + if (\$lastObj !== null) + { + \$lastNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$lastObj); + + end(\$this->childNodes); + \$endNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null); + + if (\$endNode) + { + if (\$endNode->getNodePath() > \$lastNode->getNodePath()) + throw new PropelException('Cached child node inconsistent with database.'); + else if (\$endNode->getNodePath() == \$lastNode->getNodePath()) + \$lastNode = \$endNode; + else + \$this->attachChildNode(\$lastNode); + } + else + { + \$this->attachChildNode(\$lastNode); + } + } + } + + return \$lastNode; + } +"; + } + + protected function addGetSiblingNode(&$script) + { + $script .= " + /** + * Returns next (or previous) sibling node or null. Retrieves from database if + * not loaded yet. + * + * @param boolean True if previous sibling should be returned. + * @param boolean True if sibling should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return ".$this->getStubNodeBuilder()->getClassname()." + */ + public function getSiblingNode(\$prev = false, \$querydb = false, \$con = null) + { + \$nidx = \$this->getNodeIndex(); + + if (\$this->isRootNode()) + { + return null; + } + else if (\$prev) + { + if (\$nidx > 1 && (\$parentNode = \$this->getParentNode(\$querydb, \$con))) + return \$parentNode->getChildNodeAt(\$nidx-1, \$querydb, \$con); + else + return null; + } + else + { + if (\$parentNode = \$this->getParentNode(\$querydb, \$con)) + return \$parentNode->getChildNodeAt(\$nidx+1, \$querydb, \$con); + else + return null; + } + } +"; + } + + protected function addGetParentNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Returns parent node. Loads from database if not cached yet. + * + * @param boolean True if parent should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return ".$this->getStubNodeBuilder()->getClassname()." + */ + public function getParentNode(\$querydb = true, \$con = null) + { + if (\$querydb && + \$this->parentNode === null && + !\$this->isRootNode() && + !\$this->obj->isNew() && + !\$this->obj->isDeleted()) + { + \$npath =& \$this->getNodePath(); + \$sep = strrpos(\$npath, $nodePeerClassname::NPATH_SEP); + \$ppath = substr(\$npath, 0, \$sep); + + \$criteria = new Criteria($peerClassname::DATABASE_NAME); + \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$ppath, Criteria::EQUAL); + + if (\$parentObj = $peerClassname::doSelectOne(\$criteria, \$con)) + { + \$parentNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$parentObj); + \$parentNode->attachChildNode(\$this); + } + } + + return \$this->parentNode; + } +"; + } + + protected function addGetAncestors(&$script) + { + $script .= " + /** + * Returns an array of all ancestor nodes, starting with the root node + * first. + * + * @param boolean True if ancestors should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return array + */ + public function getAncestors(\$querydb = false, \$con = null) + { + \$ancestors = array(); + \$parentNode = \$this; + + while (\$parentNode = \$parentNode->getParentNode(\$querydb, \$con)) + array_unshift(\$ancestors, \$parentNode); + + return \$ancestors; + } +"; + } + + protected function addIsRootNode(&$script) + { + $script .= " + /** + * Returns true if node is the root node of the tree. + * @return boolean + */ + public function isRootNode() + { + return (\$this->getNodePath() === '1'); + } +"; + } + + protected function addSetNew(&$script) + { + $script .= " + /** + * Changes the state of the object and its descendants to 'new'. + * Also changes the node path to '0' to indicate that it is not a + * stored node. + * + * @param boolean + * @return void + */ + public function setNew(\$b) + { + \$this->adjustStatus('new', \$b); + \$this->adjustNodePath(\$this->getNodePath(), '0'); + } +"; + } + + protected function addSetDeleted(&$script) + { + $script .= " + /** + * Changes the state of the object and its descendants to 'deleted'. + * + * @param boolean + * @return void + */ + public function setDeleted(\$b) + { + \$this->adjustStatus('deleted', \$b); + } +"; + } + + protected function addAddChildNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Adds the specified node (and its children) as a child to this node. If a + * valid \$beforeNode is specified, the node will be inserted in front of + * \$beforeNode. If \$beforeNode is not specified the node will be appended to + * the end of the child nodes. + * + * @param ".$this->getStubNodeBuilder()->getClassname()." Node to add. + * @param ".$this->getStubNodeBuilder()->getClassname()." Node to insert before. + * @param Connection Connection to use. + */ + public function addChildNode(\$node, \$beforeNode = null, \$con = null) + { + if (\$this->obj->isNew() && !\$node->obj->isNew()) + throw new PropelException('Cannot add stored nodes to a new node.'); + + if (\$this->obj->isDeleted() || \$node->obj->isDeleted()) + throw new PropelException('Cannot add children in a deleted state.'); + + if (\$this->hasChildNode(\$node)) + throw new PropelException('Node is already a child of this node.'); + + if (\$beforeNode && !\$this->hasChildNode(\$beforeNode)) + throw new PropelException('Invalid beforeNode.'); + + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + try { + + if (!\$this->obj->isNew()) \$con->begin(); + + if (\$beforeNode) + { + // Inserting before a node. + \$childIdx = \$beforeNode->getNodeIndex(); + \$this->shiftChildNodes(1, \$beforeNode->getNodeIndex(), \$con); + } + else + { + // Appending child node. + if (\$lastNode = \$this->getLastChildNode(true, \$con)) + \$childIdx = \$lastNode->getNodeIndex()+1; + else + \$childIdx = 1; + } + + // Add the child (and its children) at the specified index. + + if (!\$this->obj->isNew() && \$node->obj->isNew()) + { + \$this->insertNewChildNode(\$node, \$childIdx, \$con); + } + else + { + // \$this->isNew() && \$node->isNew() || + // !\$this->isNew() && !node->isNew() + + \$srcPath = \$node->getNodePath(); + \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx; + + if (!\$node->obj->isNew()) + { + $nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con); + \$parentNode = \$node->getParentNode(true, \$con); + } + else + { + \$parentNode = \$node->getParentNode(); + } + + if (\$parentNode) + { + \$parentNode->detachChildNode(\$node); + \$parentNode->shiftChildNodes(-1, \$node->getNodeIndex()+1, \$con); + } + + \$node->adjustNodePath(\$srcPath, \$dstPath); + } + + if (!\$this->obj->isNew()) \$con->commit(); + + \$this->attachChildNode(\$node); + + } catch (SQLException \$e) { + if (!\$this->obj->isNew()) \$con->rollback(); + throw new PropelException(\$e); + } + } +"; + } + + protected function addMoveChildNode(&$script) + { + $script .= " + /** + * Moves the specified child node in the specified direction. + * + * @param ".$this->getStubNodeBuilder()->getClassname()." Node to move. + * @param int Number of spaces to move among siblings (may be negative). + * @param Connection Connection to use. + * @throws PropelException + */ + public function moveChildNode(\$node, \$direction, \$con = null) + { + throw new PropelException('moveChildNode() not implemented yet.'); + } +"; + } + + + protected function addSave(&$script) + { + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $script .= " + /** + * Saves modified object data to the datastore. + * + * @param boolean If true, descendants will be saved as well. + * @param Connection Connection to use. + */ + public function save(\$recurse = false, \$con = null) + { + if (\$this->obj->isDeleted()) + throw new PropelException('Cannot save deleted node.'); + + if (substr(\$this->getNodePath(), 0, 1) == '0') + throw new PropelException('Cannot save unattached node.'); + + if (\$this->obj->isColumnModified($nodePeerClassname::NPATH_COLNAME)) + throw new PropelException('Cannot save manually modified node path.'); + + \$this->obj->save(\$con); + + if (\$recurse) + { + foreach (\$this->childNodes as \$childNode) + \$childNode->save(\$recurse, \$con); + } + } +"; + } + + + protected function addDelete(&$script) + { + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $script .= " + /** + * Removes this object and all descendants from datastore. + * + * @param Connection Connection to use. + * @return void + * @throws PropelException + */ + public function delete(\$con = null) + { + if (\$this->obj->isDeleted()) + throw new PropelException('This node has already been deleted.'); + + if (!\$this->obj->isNew()) + { + $nodePeerClassname::deleteNodeSubTree(\$this->getNodePath(), \$con); + } + + if (\$parentNode = \$this->getParentNode(true, \$con)) + { + \$parentNode->detachChildNode(\$this); + \$parentNode->shiftChildNodes(-1, \$this->getNodeIndex()+1, \$con); + } + + \$this->setDeleted(true); + } +"; + } + + protected function addEquals(&$script) + { + $nodeClassname = $this->getStubNodeBuilder()->getClassname(); + $script .= " + /** + * Compares the object wrapped by this node with that of another node. Use + * this instead of equality operators to prevent recursive dependency + * errors. + * + * @param $nodeClassname Node to compare. + * @param boolean True if strict comparison should be used. + * @return boolean + */ + public function equals(\$node, \$strict = false) + { + if (\$strict) { + return (\$this->obj === \$node->obj); + } else { + return (\$this->obj == \$node->obj); + } + } +"; + } + + protected function addAttachParentNode(&$script) + { + $nodeClassname = $this->getStubNodeBuilder()->getClassname(); + $script .= " + /** + * This method is used internally when constructing the tree structure + * from the database. To set the parent of a node, you should call + * addChildNode() on the parent. + * + * @param $nodeClassname Parent node to attach. + * @return void + * @throws PropelException + */ + public function attachParentNode(\$node) + { + if (!\$node->hasChildNode(\$this, true)) + throw new PropelException('Failed to attach parent node for non-child.'); + + \$this->parentNode = \$node; + } +"; + } + + + protected function addAttachChildNode(&$script) + { + $nodeClassname = $this->getStubNodeBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $script .= " + /** + * This method is used internally when constructing the tree structure + * from the database. To add a child to a node you should call the + * addChildNode() method instead. + * + * @param $nodeClassname Child node to attach. + * @return void + * @throws PropelException + */ + public function attachChildNode(\$node) + { + if (\$this->hasChildNode(\$node)) + throw new PropelException('Failed to attach child node. Node already exists.'); + + if (\$this->obj->isDeleted() || \$node->obj->isDeleted()) + throw new PropelException('Failed to attach node in deleted state.'); + + if (\$this->obj->isNew() && !\$node->obj->isNew()) + throw new PropelException('Failed to attach non-new child to new node.'); + + if (!\$this->obj->isNew() && \$node->obj->isNew()) + throw new PropelException('Failed to attach new child to non-new node.'); + + if (\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$node->getNodeIndex() != \$node->getNodePath()) + throw new PropelException('Failed to attach child node. Node path mismatch.'); + + \$this->childNodes[\$node->getNodeIndex()] = \$node; + ksort(\$this->childNodes); + + \$node->attachParentNode(\$this); + } +"; + } + + protected function addDetachParentNode(&$script) + { + $nodeClassname = $this->getStubNodeBuilder()->getClassname(); + $script .= " + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this node's parent. + * @param $nodeClassname Parent node to detach from. + * @return void + * @throws PropelException + */ + public function detachParentNode(\$node) + { + if (!\$node->hasChildNode(\$this, true)) + throw new PropelException('Failed to detach parent node from non-child.'); + + unset(\$node->childNodes[\$this->getNodeIndex()]); + \$this->parentNode = null; + } +"; + } + + protected function addDetachChildNode(&$script) + { + $script .= " + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this between this node and the specified child. + * @param ".$this->getStubNodeBuilder()->getClassname()." Child node to detach. + * @return void + * @throws PropelException + */ + public function detachChildNode(\$node) + { + if (!\$this->hasChildNode(\$node, true)) + throw new PropelException('Failed to detach non-existent child node.'); + + unset(\$this->childNodes[\$node->getNodeIndex()]); + \$node->parentNode = null; + } +"; + } + + protected function addShiftChildNodes(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Shifts child nodes in the specified direction and offset index. This + * method assumes that there is already space available in the + * direction/offset indicated. + * + * @param int Direction/# spaces to shift. 1=leftshift, 1=rightshift + * @param int Node index to start shift at. + * @param Connection The connection to be used. + * @return void + * @throws PropelException + */ + protected function shiftChildNodes(\$direction, \$offsetIdx, \$con) + { + if (\$this->obj->isDeleted()) + throw new PropelException('Cannot shift nodes for deleted object'); + + \$lastNode = \$this->getLastChildNode(true, \$con); + \$lastIdx = (\$lastNode !== null ? \$lastNode->getNodeIndex() : 0); + + if (\$lastNode === null || \$offsetIdx > \$lastIdx) + return; + + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + if (!\$this->obj->isNew()) + { + // Shift nodes in database. + + try { + + \$con->begin(); + + \$n = \$lastIdx - \$offsetIdx + 1; + \$i = \$direction < 1 ? \$offsetIdx : \$lastIdx; + + while (\$n--) + { + \$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i; // 1.2.2 + \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3 + + $nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con); + + \$i -= \$direction; + } + + \$con->commit(); + + } catch (SQLException \$e) { + \$con->rollback(); + throw new PropelException(\$e); + } + } + + // Shift the in-memory objects. + + \$n = \$lastIdx - \$offsetIdx + 1; + \$i = \$direction < 1 ? \$offsetIdx : \$lastIdx; + + while (\$n--) + { + if (isset(\$this->childNodes[\$i])) + { + \$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i; // 1.2.2 + \$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3 + + \$this->childNodes[\$i+\$direction] = \$this->childNodes[\$i]; + \$this->childNodes[\$i+\$direction]->adjustNodePath(\$srcPath, \$dstPath); + + unset(\$this->childNodes[\$i]); + } + + \$i -= \$direction; + } + + ksort(\$this->childNodes); + } +"; + } + + protected function addInsertNewChildNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Inserts the node and its children at the specified childIdx. + * + * @param $nodeClassname Node to insert. + * @param int One-based child index to insert at. + * @param Connection Connection to use. + * @param void + */ + protected function insertNewChildNode(\$node, \$childIdx, \$con) + { + if (!\$node->obj->isNew()) + throw new PropelException('Failed to insert non-new node.'); + + \$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME; + + \$node->obj->\$setNodePath(\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx); + \$node->obj->save(\$con); + + \$i = 1; + foreach (\$node->childNodes as \$childNode) + \$node->insertNewChildNode(\$childNode, \$i++, \$con); + } +"; + } + + protected function addAdjustStatus(&$script) + { + $script .= " + /** + * Adjust new/deleted status of node and all children. + * + * @param string Status to change ('New' or 'Deleted') + * @param boolean Value for status. + * @return void + */ + protected function adjustStatus(\$status, \$b) + { + \$setStatus = 'set' . \$status; + + \$this->obj->\$setStatus(\$b); + + foreach (\$this->childNodes as \$childNode) + \$childNode->obj->\$setStatus(\$b); + } +"; + } + + protected function addAdjustNodePath(&$script) + { + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $script .= " + /** + * Adjust path of node and all children. This is used internally when + * inserting/moving nodes. + * + * @param string Section of old path to change. + * @param string New section to replace old path with. + * @return void + */ + protected function adjustNodePath(\$oldBasePath, \$newBasePath) + { + \$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME; + + \$this->obj->\$setNodePath(\$newBasePath . substr(\$this->getNodePath(), strlen(\$oldBasePath))); + \$this->obj->resetModified($nodePeerClassname::NPATH_COLNAME); + + foreach (\$this->childNodes as \$childNode) + \$childNode->adjustNodePath(\$oldBasePath, \$newBasePath); + } +"; + } + +} // PHP5NodeObjectBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php new file mode 100644 index 000000000..3704d32f9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php @@ -0,0 +1,774 @@ +. + */ + +require_once 'propel/engine/builder/om/PeerBuilder.php'; + +/** + * Generates a PHP5 tree node Peer class for user object model (OM). + * + * This class produces the base tree node object class (e.g. BaseMyTable) which contains all + * the custom-built accessor and setter methods. + * + * This class replaces the Node.tpl, with the intent of being easier for users + * to customize (through extending & overriding). + * + * @author Hans Lellelid + * @package propel.engine.builder.om.php5 + */ +class PHP5NodePeerBuilder extends PeerBuilder { + + /** + * Gets the package for the [base] object classes. + * @return string + */ + public function getPackage() + { + return parent::getPackage() . ".om"; + } + + /** + * Returns the name of the current class being built. + * @return string + */ + public function getClassname() + { + return $this->getBuildProperty('basePrefix') . $this->getStubNodePeerBuilder()->getClassname(); + } + + /** + * Adds the include() statements for files that this class depends on or utilizes. + * @param string &$script The script will be modified in this method. + */ + protected function addIncludes(&$script) + { + $script .= " +require_once '".$this->getStubObjectBuilder()->getClassFilePath()."'; +require_once '".$this->getStubNodeBuilder()->getClassFilePath()."'; +"; + } // addIncludes() + + /** + * Adds class phpdoc comment and openning of class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassOpen(&$script) + { + + $table = $this->getTable(); + $tableName = $table->getName(); + $tableDesc = $table->getDescription(); + + $script .= " +/** + * Base static class for performing query operations on the tree contained by the '$tableName' table. + * + * $tableDesc + *"; + if ($this->getBuildProperty('addTimeStamp')) { + $now = strftime('%c'); + $script .= " + * This class was autogenerated by Propel on: + * + * $now + *"; + } + $script .= " + * @package ".$this->getPackage()." + */ +abstract class ".$this->getClassname()." { +"; + } + + /** + * Specifies the methods that are added as part of the basic OM class. + * This can be overridden by subclasses that wish to add more methods. + * @see ObjectBuilder::addClassBody() + */ + protected function addClassBody(&$script) + { + $table = $this->getTable(); + + // FIXME + // - Probably the build needs to be customized for supporting + // tables that are "aliases". -- definitely a fringe usecase, though. + + $this->addConstants($script); + + $this->addIsCodeBase($script); + + $this->addRetrieveMethods($script); + + $this->addCreateNewRootNode($script); + $this->addInsertNewRootNode($script); + $this->addMoveNodeSubTree($script); + $this->addDeleteNodeSubTree($script); + + $this->addBuildFamilyCriteria($script); + $this->addBuildTree($script); + + $this->addPopulateNodes($script); + + } + + /** + * Closes class. + * @param string &$script The script will be modified in this method. + */ + protected function addClassClose(&$script) + { + $script .= " +} // " . $this->getClassname() . " +"; + } + + protected function addConstants(&$script) + { + $table = $this->getTable(); + + $npath_colname = ''; + $npath_phpname = ''; + $npath_len = 0; + $npath_sep = ''; + foreach ($table->getColumns() as $col) { + if ($col->isNodeKey()) { + $npath_colname = $table->getName() . '.' . strtoupper($col->getName()); + $npath_phpname = $col->getPhpName(); + $npath_len = $col->getSize(); + $npath_sep = $col->getNodeKeySep(); + break; + } + } + $script .= " + const NPATH_COLNAME = '$npath_colname'; + const NPATH_PHPNAME = '$npath_phpname'; + const NPATH_SEP = '$npath_sep'; + const NPATH_LEN = $npath_len; +"; + } + + + protected function addIsCodeBase(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Temp function for CodeBase hacks that will go away. + */ + public static function isCodeBase(\$con = null) + { + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + return (get_class(\$con) == 'ODBCConnection' && + get_class(\$con->getAdapter()) == 'CodeBaseAdapter'); + } +"; + } + + + protected function addCreateNewRootNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Create a new Node at the top of tree. This method will destroy any + * existing root node (along with its children). + * + * Use at your own risk! + * + * @param $objectClassname Object wrapped by new node. + * @param Connection Connection to use. + * @return $nodeObjectClassname + * @throws PropelException + */ + public static function createNewRootNode(\$obj, \$con = null) + { + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + try { + + \$con->begin(); + + self::deleteNodeSubTree('1', \$con); + + \$setNodePath = 'set' . self::NPATH_PHPNAME; + + \$obj->\$setNodePath('1'); + \$obj->save(\$con); + + \$con->commit(); + + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + + return new $nodeObjectClassname(\$obj); + } +"; + } + + protected function addInsertNewRootNode(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Inserts a new Node at the top of tree. Any existing root node (along with + * its children) will be made a child of the new root node. This is a + * safer alternative to createNewRootNode(). + * + * @param $objectClassname Object wrapped by new node. + * @param Connection Connection to use. + * @return $nodeObjectClassname + * @throws PropelException + */ + public static function insertNewRootNode(\$obj, \$con = null) + { + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + try { + + \$con->begin(); + + // Move root tree to an invalid node path. + $nodePeerClassname::moveNodeSubTree('1', '0', \$con); + + \$setNodePath = 'set' . self::NPATH_PHPNAME; + + // Insert the new root node. + \$obj->\$setNodePath('1'); + \$obj->save(\$con); + + // Move the old root tree as a child of the new root. + $nodePeerClassname::moveNodeSubTree('0', '1' . self::NPATH_SEP . '1', \$con); + + \$con->commit(); + + } catch (PropelException \$e) { + \$con->rollback(); + throw \$e; + } + + return new $nodeObjectClassname(\$obj); + } +"; + } + + /** + * Adds the methods for retrieving nodes. + */ + protected function addRetrieveMethods(&$script) + { + $this->addRetrieveNodes($script); + $this->addRetrieveNodeByPK($script); + $this->addRetrieveNodeByNP($script); + $this->addRetrieveRootNode($script); + + } + + protected function addRetrieveNodes(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + + $script .= " + /** + * Retrieves an array of tree nodes based on specified criteria. Optionally + * includes all parent and/or child nodes of the matching nodes. + * + * @param Criteria Criteria to use. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return array Array of root nodes. + */ + public static function retrieveNodes(\$criteria, \$ancestors = false, \$descendants = false, \$con = null) + { + \$criteria = $nodePeerClassname::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants); + \$rs = ".$this->getStubPeerBuilder()->getClassname()."::doSelectRS(\$criteria, \$con); + return self::populateNodes(\$rs, \$criteria); + } +"; + } + + protected function addRetrieveNodeByPK(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Retrieves a tree node based on a primary key. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param mixed $objectClassname primary key (array for composite keys) + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return $nodeObjectClassname + */ + public static function retrieveNodeByPK(\$pk, \$ancestors = false, \$descendants = false, \$con = null) + { + throw new PropelException('retrieveNodeByPK() not implemented yet.'); + } +"; + } + + protected function addRetrieveNodeByNP(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Retrieves a tree node based on a node path. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param string Node path to retrieve. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return $objectClassname + */ + public static function retrieveNodeByNP(\$np, \$ancestors = false, \$descendants = false, \$con = null) + { + \$criteria = new Criteria($peerClassname::DATABASE_NAME); + \$criteria->add(self::NPATH_COLNAME, \$np, Criteria::EQUAL); + \$criteria = self::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants); + \$rs = $peerClassname::doSelectRS(\$criteria, \$con); + \$nodes = self::populateNodes(\$rs, \$criteria); + return (count(\$nodes) == 1 ? \$nodes[0] : null); + } +"; + } + + protected function addRetrieveRootNode(&$script) + { + $script .= " + /** + * Retrieves the root node. + * + * @param string Node path to retrieve. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return ".$this->getStubNodeBuilder()->getClassname()." + */ + public static function retrieveRootNode(\$descendants = false, \$con = null) + { + return self::retrieveNodeByNP('1', false, \$descendants, \$con); + } +"; + } + + protected function addMoveNodeSubTree(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Moves the node subtree at srcpath to the dstpath. This method is intended + * for internal use by the BaseNode object. Note that it does not check for + * preexisting nodes at the dstpath. It also does not update the node path + * of any Node objects that might currently be in memory. + * + * Use at your own risk! + * + * @param string Source node path to move (root of the src subtree). + * @param string Destination node path to move to (root of the dst subtree). + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated 'onCascadeDelete's. + * @todo Need to abstract the SQL better. The CONCAT sql function doesn't + * seem to be standardized (i.e. mssql), so maybe it needs to be moved + * to DBAdapter. + */ + public static function moveNodeSubTree(\$srcPath, \$dstPath, \$con = null) + { + if (substr(\$dstPath, 0, strlen(\$srcPath)) == \$srcPath) + throw new PropelException('Cannot move a node subtree within itself.'); + + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + /** + * Example: + * UPDATE table + * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74)) + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + \$npath = $nodePeerClassname::NPATH_COLNAME; + //the following dot isn`t mean`t a nodeKeySeperator + \$setcol = substr(\$npath, strpos(\$npath, '.')+1); + \$setcollen = $nodePeerClassname::NPATH_LEN; + \$db = Propel::getDb($peerClassname::DATABASE_NAME); + + // + if ($nodePeerClassname::isCodeBase(\$con)) + { + // This is a hack to get CodeBase working. It will eventually be removed. + // It is a workaround for the following CodeBase bug: + // -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT) + \$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" . + \"SET \$setcol=\" . \$db->concatString(\"'\$dstPath'\", \$db->subString(\$npath, strlen(\$srcPath)+1, \$setcollen)) . \" \" . + \"WHERE \$npath = '\$srcPath' OR \$npath LIKE '\" . \$srcPath . $nodePeerClassname::NPATH_SEP . \"%'\"; + + \$con->executeUpdate(\$sql); + } + else + { + // + \$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" . + \"SET \$setcol=\" . \$db->concatString('?', \$db->subString(\$npath, '?', '?')) . \" \" . + \"WHERE \$npath = ? OR \$npath LIKE ?\"; + + \$stmt = \$con->prepareStatement(\$sql); + \$stmt->setString(1, \$dstPath); + \$stmt->setInt(2, strlen(\$srcPath)+1); + \$stmt->setInt(3, \$setcollen); + \$stmt->setString(4, \$srcPath); + \$stmt->setString(5, \$srcPath . $nodePeerClassname::NPATH_SEP . '%'); + \$stmt->executeUpdate(); + // + } + // + } +"; + } + + protected function addDeleteNodeSubTree(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Deletes the node subtree at the specified node path from the database. + * + * @param string Node path to delete + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated 'onCascadeDelete's. + */ + public static function deleteNodeSubTree(\$nodePath, \$con = null) + { + if (\$con === null) + \$con = Propel::getConnection($peerClassname::DATABASE_NAME); + + /** + * DELETE FROM table + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + \$criteria = new Criteria($peerClassname::DATABASE_NAME); + \$criteria->add($nodePeerClassname::NPATH_COLNAME, \$nodePath, Criteria::EQUAL); + \$criteria->addOr($nodePeerClassname::NPATH_COLNAME, \$nodePath . self::NPATH_SEP . '%', Criteria::LIKE); +// For now, we call BasePeer directly since $peerClassname tries to +// do a cascade delete. +// $peerClassname::doDelete(\$criteria, \$con); + BasePeer::doDelete(\$criteria, \$con); + } +"; + } + + protected function addBuildFamilyCriteria(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Builds the criteria needed to retrieve node ancestors and/or descendants. + * + * @param Criteria Criteria to start with + * @param boolean True if ancestors should be retrieved. + * @param boolean True if descendants should be retrieved. + * @return Criteria + */ + public static function buildFamilyCriteria(\$criteria, \$ancestors = false, \$descendants = false) + { + /* + Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants: + + SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH) + FROM test L, test + WHERE test.NPATH='1.2.3' AND + (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR + test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH))) + ORDER BY UCASE(L.NPATH) ASC + */ + + if (\$criteria === null) + \$criteria = new Criteria($peerClassname::DATABASE_NAME); + + if (!\$criteria->getSelectColumns()) + $peerClassname::addSelectColumns(\$criteria); + + \$db = Propel::getDb(\$criteria->getDbName()); + + if ((\$ancestors || \$descendants) && \$criteria->size()) + { + // If we are retrieving ancestors/descendants, we need to do a + // self-join to locate them. The exception to this is if no search + // criteria is specified. In this case we're retrieving all nodes + // anyway, so there is no need to do a self-join. + + // The left-side of the self-join will contain the columns we'll + // use to build node objects (target node records along with their + // ancestors and/or descendants). The right-side of the join will + // contain the target node records specified by the initial criteria. + // These are used to match the appropriate ancestor/descendant on + // the left. + + // Specify an alias for the left-side table to use. + \$criteria->addAlias('L', $peerClassname::TABLE_NAME); + + // Make sure we have select columns to begin with. + if (!\$criteria->getSelectColumns()) + $peerClassname::addSelectColumns(\$criteria); + + // Replace any existing columns for the right-side table with the + // left-side alias. + \$selectColumns = \$criteria->getSelectColumns(); + \$criteria->clearSelectColumns(); + foreach (\$selectColumns as \$colName) + \$criteria->addSelectColumn(str_replace($peerClassname::TABLE_NAME, 'L', \$colName)); + + \$a = null; + \$d = null; + + \$npathL = $peerClassname::alias('L', $nodePeerClassname::NPATH_COLNAME); + \$npathR = $nodePeerClassname::NPATH_COLNAME; + \$npath_len = $nodePeerClassname::NPATH_LEN; + + if (\$ancestors) + { + // For ancestors, match left-side node paths which are contained + // by right-side node paths. + \$a = \$criteria->getNewCriterion(\$npathL, + \"\$npathL=\" . \$db->subString(\$npathR, 1, \$db->strLength(\$npathL), \$npath_len), + Criteria::CUSTOM); + } + + if (\$descendants) + { + // For descendants, match left-side node paths which contain + // right-side node paths. + \$d = \$criteria->getNewCriterion(\$npathR, + \"\$npathR=\" . \$db->subString(\$npathL, 1, \$db->strLength(\$npathR), \$npath_len), + Criteria::CUSTOM); + } + + if (\$a) + { + if (\$d) \$a->addOr(\$d); + \$criteria->addAnd(\$a); + } + else if (\$d) + { + \$criteria->addAnd(\$d); + } + + // Add the target node path column. This is used by populateNodes(). + \$criteria->addSelectColumn(\$npathR); + + // Sort by node path to speed up tree construction in populateNodes() + \$criteria->addAsColumn('npathlen', \$db->strLength(\$npathL)); + \$criteria->addAscendingOrderByColumn('npathlen'); + \$criteria->addAscendingOrderByColumn(\$npathL); + } + else + { + // Add the target node path column. This is used by populateNodes(). + \$criteria->addSelectColumn($nodePeerClassname::NPATH_COLNAME); + + // Sort by node path to speed up tree construction in populateNodes() + \$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME)); + \$criteria->addAscendingOrderByColumn('npathlen'); + \$criteria->addAscendingOrderByColumn($nodePeerClassname::NPATH_COLNAME); + } + + return \$criteria; + } +"; + } + + protected function addBuildTree(&$script) + { + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * This method reconstructs as much of the tree structure as possible from + * the given array of objects. Depending on how you execute your query, it + * is possible for the ResultSet to contain multiple tree fragments (i.e. + * subtrees). The array returned by this method will contain one entry + * for each subtree root node it finds. The remaining subtree nodes are + * accessible from the $nodeObjectClassname methods of the + * subtree root nodes. + * + * @param array Array of $nodeObjectClassname objects + * @return array Array of $nodeObjectClassname objects + */ + public static function buildTree(\$nodes) + { + // Subtree root nodes to return + \$rootNodes = array(); + + // Build the tree relations + foreach (\$nodes as \$node) + { + \$sep = strrpos(\$node->getNodePath(), $nodePeerClassname::NPATH_SEP); + \$parentPath = (\$sep !== false ? substr(\$node->getNodePath(), 0, \$sep) : ''); + \$parentNode = null; + + // Scan other nodes for parent. + foreach (\$nodes as \$pnode) + { + if (\$pnode->getNodePath() === \$parentPath) + { + \$parentNode = \$pnode; + break; + } + } + + // If parent was found, attach as child, otherwise its a subtree root + if (\$parentNode) + \$parentNode->attachChildNode(\$node); + else + \$rootNodes[] = \$node; + } + + return \$rootNodes; + } +"; + } + + protected function addPopulateNodes(&$script) + { + $table = $this->getTable(); + + $peerClassname = $this->getStubPeerBuilder()->getClassname(); + $objectClassname = $this->getStubObjectBuilder()->getClassname(); + + $nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname(); + $nodeObjectClassname = $this->getStubNodeBuilder()->getClassname(); + + $script .= " + /** + * Populates the $objectClassname objects from the + * specified ResultSet, wraps them in $nodeObjectClassname + * objects and build the appropriate node relationships. + * The array returned by this method will only include the initial targets + * of the query, even if ancestors/descendants were also requested. + * The ancestors/descendants will be cached in memory and are accessible via + * the getNode() methods. + * + * @param ResultSet + * @param Criteria + * @return array Array of $nodeObjectClassname objects. + */ + public static function populateNodes(\$rs, \$criteria) + { + \$nodes = array(); + \$targets = array(); + \$targetfld = count(\$criteria->getSelectColumns()); +"; + + if (!$table->getChildrenColumn()) { + $script .= " + // set the class once to avoid overhead in the loop + \$cls = Propel::import($peerClassname::getOMClass()); +"; + } + + $script .= " + // populate the object(s) + while(\$rs->next()) + { + if (!isset(\$nodes[\$rs->getString(1)])) + { +"; + if ($table->getChildrenColumn()) { + $script .= " + // class must be set each time from the record row + $cls = Propel::import($peerClassname::getOMClass($rs, 1)); +"; + } + + $script .= " + \$obj = new \$cls(); + \$obj->hydrate(\$rs); + + \$nodes[\$rs->getString(1)] = new $nodeObjectClassname(\$obj); + } + + \$node = \$nodes[\$rs->getString(1)]; + + if (\$node->getNodePath() === \$rs->getString(\$targetfld)) + \$targets[\$node->getNodePath()] = \$node; + } + + $nodePeerClassname::buildTree(\$nodes); + + return array_values(\$targets); + } +"; + } + +} // PHP5NodePeerBuilder diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php new file mode 100644 index 000000000..d34cee67d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php @@ -0,0 +1,130 @@ +. + */ + +require_once 'propel/engine/builder/DataModelBuilder.php'; + +/** + * Baseclass for SQL DDL-building classes. + * + * DDL-building classes are those that build all the SQL DDL for a single table. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql + */ +abstract class DDLBuilder extends DataModelBuilder { + + /** + * Builds the SQL for current table and returns it as a string. + * + * This is the main entry point and defines a basic structure that classes should follow. + * In most cases this method will not need to be overridden by subclasses. + * + * @return string The resulting SQL DDL. + */ + public function build() + { + $script = ""; + $this->addTable($script); + $this->addIndices($script); + $this->addForeignKeys($script); + return $script; + } + + /** + * Builds the DDL SQL for a Column object. + * @return string + */ + public function getColumnDDL(Column $col) + { + $platform = $this->getPlatform(); + $domain = $col->getDomain(); + + $sb = ""; + $sb .= $this->quoteIdentifier($col->getName()) . " "; + $sb .= $domain->getSqlType(); + if ($platform->hasSize($domain->getSqlType())) { + $sb .= $domain->printSize(); + } + $sb .= " "; + $sb .= $col->getDefaultSetting() . " "; + $sb .= $col->getNotNullString() . " "; + $sb .= $col->getAutoIncrementString(); + return trim($sb); + } + + /** + * Creates a delimiter-delimited string list of column names, quoted using quoteIdentifier(). + * @param array Column[] or string[] + * @param string $delim The delimiter to use in separating the column names. + * @return string + */ + public function getColumnList($columns, $delim=',') + { + $list = array(); + foreach($columns as $col) { + if ($col instanceof Column) { + $col = $col->getName(); + } + $list[] = $this->quoteIdentifier($col); + } + return implode($delim, $list); + } + + /** + * This function adds any _database_ start/initialization SQL. + * This is designed to be called for a database, not a specific table, hence it is static. + * @return string The DDL is returned as astring. + */ + public static function getDatabaseStartDDL() + { + return ''; + } + + /** + * This function adds any _database_ end/cleanup SQL. + * This is designed to be called for a database, not a specific table, hence it is static. + * @return string The DDL is returned as astring. + */ + public static function getDatabaseEndDDL() + { + return ''; + } + + /** + * Adds table definition. + * @param string &$script The script will be modified in this method. + */ + abstract protected function addTable(&$script); + + /** + * Adds index definitions. + * @param string &$script The script will be modified in this method. + */ + abstract protected function addIndices(&$script); + + /** + * Adds foreign key constraint definitions. + * @param string &$script The script will be modified in this method. + */ + abstract protected function addForeignKeys(&$script); + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php new file mode 100644 index 000000000..5316e5870 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php @@ -0,0 +1,215 @@ +. + */ + +require_once 'propel/engine/builder/DataModelBuilder.php'; + +/** + * Baseclass for SQL data dump SQL building classes. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql + */ +abstract class DataSQLBuilder extends DataModelBuilder { + + /** + * The main method in this class, returns the SQL for INSERTing data into a row. + * @param DataRow $row The row to process. + * @return string + */ + public function buildRowSql(DataRow $row) + { + $sql = ""; + $platform = $this->getPlatform(); + $table = $this->getTable(); + + $sql .= "INSERT INTO ".$this->quoteIdentifier($this->getTable()->getName())." ("; + + // add column names to SQL + $colNames = array(); + foreach ($row->getColumnValues() as $colValue) { + $colNames[] = $this->quoteIdentifier($colValue->getColumn()->getName()); + } + + $sql .= implode(',', $colNames); + + $sql .= ") VALUES ("; + + $colVals = array(); + foreach ($row->getColumnValues() as $colValue) { + $colVals[] = $this->getColumnValueSql($colValue); + } + + $sql .= implode(',', $colVals); + $sql .= "); +"; + + return $sql; + } + + /** + * Gets the propertly escaped (and quoted) value for a column. + * @param ColumnValue $colValue + * @return mixed The proper value to be added to the string. + */ + protected function getColumnValueSql(ColumnValue $colValue) + { + $column = $colValue->getColumn(); + $creoleTypeString = PropelTypes::getCreoleType($column->getPropelType()); + $creoleTypeCode = CreoleTypes::getCreoleCode($creoleTypeString); + $method = 'get' . CreoleTypes::getAffix($creoleTypeCode) . 'Sql'; + return $this->$method($colValue->getValue()); + } + + + + /** + * Gets a representation of a binary value suitable for use in a SQL statement. + * Default behavior is true = 1, false = 0. + * @param boolean $value + * @return int + */ + protected function getBooleanSql($value) + { + return (int) $value; + } + + + /** + * Gets a representation of a BLOB/LONGVARBINARY value suitable for use in a SQL statement. + * @param mixed $blob Blob object or string data. + * @return string + */ + protected function getBlobSql($blob) + { + // they took magic __toString() out of PHP5.0.0; this sucks + if (is_object($blob)) { + return "'" . $this->escape($blob->__toString()) . "'"; + } else { + return "'" . $this->escape($blob) . "'"; + } + } + + /** + * Gets a representation of a CLOB/LONGVARCHAR value suitable for use in a SQL statement. + * @param mixed $clob Clob object or string data. + * @return string + */ + protected function getClobSql($clob) + { + // they took magic __toString() out of PHP5.0.0; this sucks + if (is_object($clob)) { + return "'" . $this->escape($clob->__toString()) . "'"; + } else { + return "'" . $this->escape($clob) . "'"; + } + } + + /** + * Gets a representation of a date value suitable for use in a SQL statement. + * @param string $value + * @return string + */ + protected function getDateSql($value) + { + return "'" . date('Y-m-d', strtotime($value)) . "'"; + } + + /** + * Gets a representation of a decimal value suitable for use in a SQL statement. + * @param double $value + * @return float + */ + protected function getDecimalSql($value) + { + return (float) $value; + } + + /** + * Gets a representation of a double value suitable for use in a SQL statement. + * @param double $value + * @return double + */ + protected function getDoubleSql($value) + { + return (double) $value; + } + + /** + * Gets a representation of a float value suitable for use in a SQL statement. + * @param float $value + * @return float + */ + protected function getFloatSql($value) + { + return (float) $value; + } + + /** + * Gets a representation of an integer value suitable for use in a SQL statement. + * @param int $value + * @return int + */ + protected function getIntSql($value) + { + return (int) $value; + } + + /** + * Gets a representation of a NULL value suitable for use in a SQL statement. + * @return null + */ + protected function getNullSql() + { + return 'NULL'; + } + + /** + * Gets a representation of a string value suitable for use in a SQL statement. + * @param string $value + * @return string + */ + protected function getStringSql($value) + { + return "'" . $this->getPlatform()->escapeText($value) . "'"; + } + + /** + * Gets a representation of a time value suitable for use in a SQL statement. + * @param string $value + * @return string + */ + protected function getTimeSql($paramIndex, $value) + { + return "'" . date('H:i:s', strtotime($value)) . "'"; + } + + /** + * Gets a representation of a timestamp value suitable for use in a SQL statement. + * @param string $value + * @return string + */ + function getTimestampSql($value) + { + return "'" . date('Y-m-d H:i:s', strtotime($value)) . "'"; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php new file mode 100644 index 000000000..4ec77f558 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php @@ -0,0 +1,186 @@ +. + */ + +require_once 'propel/engine/builder/sql/DDLBuilder.php'; + +/** + * The SQL DDL-building class for MS SQL Server. + * + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.pgsql + */ +class MssqlDDLBuilder extends DDLBuilder { + + private static $dropCount = 0; + + /** + * + * @see parent::addDropStatement() + */ + protected function addDropStatements(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getForeignKeys() as $fk) { + $script .= " +IF EXISTS (SELECT 1 FROM sysobjects WHERE type ='RI' AND name='".$fk->getName()."') + ALTER TABLE ".$this->quoteIdentifier($table->getName())." DROP CONSTRAINT ".$this->quoteIdentifier($fk->getName())."; +"; + } + + + self::$dropCount++; + + $script .= " +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = '".$table->getName()."') +BEGIN + DECLARE @reftable_".self::$dropCount." nvarchar(60), @constraintname_".self::$dropCount." nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = '".$table->getName()."' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_".self::$dropCount.", @constraintname_".self::$dropCount." + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_".self::$dropCount."+' drop constraint '+@constraintname_".self::$dropCount.") + FETCH NEXT from refcursor into @reftable_".self::$dropCount.", @constraintname_".self::$dropCount." + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE ".$this->quoteIdentifier($table->getName())." +END +"; + } + + /** + * @see parent::addColumns() + */ + protected function addTable(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +/* ---------------------------------------------------------------------- */ +/* ".$table->getName()." */ +/* ---------------------------------------------------------------------- */ + +"; + + $this->addDropStatements($script); + + $script .= " + +CREATE TABLE ".$this->quoteIdentifier($table->getName())." +( + "; + + $lines = array(); + + foreach ($table->getColumns() as $col) { + $lines[] = $this->getColumnDDL($col); + } + + if ($table->hasPrimaryKey()) { +// $lines[] = "CONSTRAINT ".$this->quoteIdentifier($table->getName())."_PK PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")"; + $lines[] = "CONSTRAINT ".$table->getName()."_PK PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")"; + } + + foreach ($table->getUnices() as $unique ) { + $lines[] = "UNIQUE (".$this->getColumnList($unique->getColumns()).")"; + } + + $sep = ", + "; + $script .= implode($sep, $lines); + $script .= " +); +"; + } + + /** + * Adds CREATE INDEX statements for this table. + * @see parent::addIndices() + */ + protected function addIndices(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getIndices() as $index) { + $script .= " +CREATE "; + if($index->getIsUnique()) { + $script .= "UNIQUE"; + } + $script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($table->getName())." (".$this->getColumnList($index->getColumns())."); +"; + } + } + + /** + * + * @see parent::addForeignKeys() + */ + protected function addForeignKeys(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getForeignKeys() as $fk) { + $script .= " +BEGIN +ALTER TABLE ".$this->quoteIdentifier($table->getName())." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($fk->getForeignTableName())." (".$this->getColumnList($fk->getForeignColumns()).")"; + if ($fk->hasOnUpdate()) { + if ($fk->getOnUpdate() == ForeignKey::SETNULL) { // there may be others that also won't work + // we have to skip this because it's unsupported. + $this->warn("MSSQL doesn't support the 'SET NULL' option for ON UPDATE (ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk)."); + } else { + $script .= " ON UPDATE ".$fk->getOnUpdate(); + } + + } + if ($fk->hasOnDelete()) { + if ($fk->getOnDelete() == ForeignKey::SETNULL) { // there may be others that also won't work + // we have to skip this because it's unsupported. + $this->warn("MSSQL doesn't support the 'SET NULL' option for ON DELETE (ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk)."); + } else { + $script .= " ON DELETE ".$fk->getOnDelete(); + } + } + $script .= " +END +; +"; + } + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php new file mode 100644 index 000000000..b821acee3 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php @@ -0,0 +1,48 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * MS SQL Server class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.mssql + */ +class MssqlDataSQLBuilder extends DataSQLBuilder { + + /** + * + * @param mixed $blob Blob object or string containing data. + * @return string + */ + protected function getBlobSql($blob) + { + // they took magic __toString() out of PHP5.0.0; this sucks + if (is_object($blob)) { + $blob = $blob->__toString(); + } + $data = unpack("H*hex", $blob); + return '0x'.$data['hex']; // no surrounding quotes! + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php new file mode 100644 index 000000000..80c5ab120 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php @@ -0,0 +1,306 @@ +. + */ + +require_once 'propel/engine/builder/sql/DDLBuilder.php'; + +/** + * DDL Builder class for MySQL. + * + * @author David Zülke + * @author Hans Lellelid + * @package propel.engine.builder.sql.mysql + */ +class MysqlDDLBuilder extends DDLBuilder { + + /** + * Returns some header SQL that disables foreign key checking. + * @return string DDL + */ + public static function getDatabaseStartDDL() + { + $ddl = " +# This is a fix for InnoDB in MySQL >= 4.1.x +# It \"suspends judgement\" for fkey relationships until are tables are set. +SET FOREIGN_KEY_CHECKS = 0; +"; + return $ddl; + } + + /** + * Returns some footer SQL that re-enables foreign key checking. + * @return string DDL + */ + public static function getDatabaseEndDDL() + { + $ddl = " +# This restores the fkey checks, after having unset them earlier +SET FOREIGN_KEY_CHECKS = 1; +"; + return $ddl; + } + + + /** + * + * @see parent::addDropStatement() + */ + protected function addDropStatements(&$script) + { + $script .= " +DROP TABLE IF EXISTS ".$this->quoteIdentifier($this->getTable()->getName())."; +"; + } + + /** + * Builds the SQL for current table and returns it as a string. + * + * This is the main entry point and defines a basic structure that classes should follow. + * In most cases this method will not need to be overridden by subclasses. + * + * @return string The resulting SQL DDL. + */ + public function build() + { + $script = ""; + $this->addTable($script); + return $script; + } + + /** + * + * @see parent::addColumns() + */ + protected function addTable(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +#----------------------------------------------------------------------------- +#-- ".$table->getName()." +#----------------------------------------------------------------------------- +"; + + $this->addDropStatements($script); + + $script .= " + +CREATE TABLE ".$this->quoteIdentifier($table->getName())." +( + "; + + $lines = array(); + + foreach ($table->getColumns() as $col) { + $entry = $this->getColumnDDL($col); + if ($col->getDescription()) { + $entry .= " COMMENT '".$platform->escapeText($col->getDescription())."'"; + } + $lines[] = $entry; + } + + if ($table->hasPrimaryKey()) { + $lines[] = "PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")"; + } + + $this->addIndicesLines($lines); + $this->addForeignKeysLines($lines); + + $sep = ", + "; + $script .= implode($sep, $lines); + + $script .= " +)"; + + $mysqlTableType = $this->getBuildProperty("mysqlTableType"); + if (!$mysqlTableType) { + $vendorSpecific = $table->getVendorSpecificInfo(); + if(isset($vendorSpecific['Type'])) { + $mysqlTableType = $vendorSpecific['Type']; + } else { + $mysqlTableType = 'MyISAM'; + } + } + + $script .= "Type=$mysqlTableType "; +// print_r ($vendorSpecific); + if($vendorSpecific['Collation'] ) { +// $script .= " DEFAULT CHARSET='". $platform->escapeText( $vendorSpecific['Collation'] )."'"; + $script .= " DEFAULT CHARSET='utf8'"; + } + if($vendorSpecific['Comment'] ) { + $script .= " COMMENT='". $platform->escapeText( $vendorSpecific['Comment'] )."'"; + } +// if($table->getDescription()) { +// $script .= " COMMENT='".$platform->escapeText($table->getDescription())."'"; +// } + $script .= ";"; + } + + /** + * Creates a comma-separated list of column names for the index. + * For MySQL unique indexes there is the option of specifying size, so we cannot simply use + * the getColumnsList() method. + * @param Index $index + * @return string + */ + private function getIndexColumnList(Index $index) + { + $platform = $this->getPlatform(); + + $cols = $index->getColumns(); + $list = array(); + foreach($cols as $col) { + $list[] = $this->quoteIdentifier($col) . ($index->hasColumnSize($col) ? '(' . $index->getColumnSize($col) . ')' : ''); + } + return implode(', ', $list); + } + + /** + * Adds indexes + */ + protected function addIndicesLines(&$lines) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getUnices() as $unique) { + $lines[] = "UNIQUE KEY ".$this->quoteIdentifier($unique->getName())." (".$this->getIndexColumnList($unique).")"; + } + + foreach ($table->getIndices() as $index ) { + $vendor = $index->getVendorSpecificInfo(); + $lines[] .= (($vendor && $vendor['Index_type'] == 'FULLTEXT') ? 'FULLTEXT ' : '') . "KEY " . $this->quoteIdentifier($index->getName()) . "(" . $this->getIndexColumnList($index) . ")"; + } + + } + + /** + * Adds foreign key declarations & necessary indexes for mysql (if they don't exist already). + * @see parent::addForeignKeys() + */ + protected function addForeignKeysLines(&$lines) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + + $_indices = array(); + $_previousColumns = array(); + + // we're building an array of indices here which is smart about multi-column indices. + // for example, if we have to indices foo(ColA) and bar(ColB, ColC), we have actually three indices already defined: + // ColA, ColB+ColC, and ColB (but not ColC!). This is because of the way SQL multi-column indices work. + // we will later match found, defined foreign key and referenced column definitions against this array to know + // whether we should create a new index for mysql or not + foreach($table->getPrimaryKey() as $_primaryKeyColumn) { + // do the above for primary keys + $_previousColumns[] = $this->quoteIdentifier($_primaryKeyColumn->getName()); + $_indices[] = implode(',', $_previousColumns); + } + + $_tableIndices = array_merge($table->getIndices(), $table->getUnices()); + foreach($_tableIndices as $_index) { + // same procedure, this time for unices and indices + $_previousColumns = array(); + $_indexColumns = $_index->getColumns(); + foreach($_indexColumns as $_indexColumn) { + $_previousColumns[] = $this->quoteIdentifier($_indexColumn); + $_indices[] = implode(',', $_previousColumns); + } + } + + // we're determining which tables have foreign keys that point to this table, since MySQL needs an index on + // any column that is referenced by another table (yep, MySQL _is_ a PITA) + $counter = 0; + $allTables = $table->getDatabase()->getTables(); + foreach($allTables as $_table) { + foreach($_table->getForeignKeys() as $_foreignKey) { + if($_foreignKey->getForeignTableName() == $table->getName()) { + if(!in_array($this->getColumnList($_foreignKey->getForeignColumns()), $_indices)) { + // no matching index defined in the schema, so we have to create one + $lines[] = "INDEX ".$this->quoteIdentifier("I_referenced_".$_foreignKey->getName()."_".(++$counter))." (" .$this->getColumnList($_foreignKey->getForeignColumns()).")"; + } + } + } + } + + foreach ($table->getForeignKeys() as $fk) { + + $indexName = $this->quoteIdentifier(substr_replace($fk->getName(), 'FI_', strrpos($fk->getName(), 'FK_'), 3)); + + if(!in_array($this->getColumnList($fk->getLocalColumns()), $_indices)) { + // no matching index defined in the schema, so we have to create one. MySQL needs indices on any columns that serve as foreign keys. these are not auto-created prior to 4.1.2 + $lines[] = "INDEX $indexName (".$this->getColumnList($fk->getLocalColumns()).")"; + } + $str = "CONSTRAINT ".$this->quoteIdentifier($fk->getName())." + FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()).") + REFERENCES ".$this->quoteIdentifier($fk->getForeignTableName()) . " (".$this->getColumnList($fk->getForeignColumns()).")"; + if ($fk->hasOnUpdate()) { + $str .= " + ON UPDATE ".$fk->getOnUpdate(); + } + if ($fk->hasOnDelete()) { + $str .= " + ON DELETE ".$fk->getOnDelete(); + } + $lines[] = $str; + } + + } + + /** + * Checks whether passed-in array of Column objects contains a column with specified name. + * @param array Column[] or string[] + * @param string $searchcol Column name to search for + */ + private function containsColname($columns, $searchcol) + { + foreach($columns as $col) { + if ($col instanceof Column) { + $col = $col->getName(); + } + if ($col == $searchcol) { + return true; + } + } + return false; + } + + /** + * Not used for MySQL since foreign keys are declared inside table declaration. + * @see addForeignKeysLines() + */ + protected function addForeignKeys(&$script) + { + } + + /** + * Not used for MySQL since indexes are declared inside table declaration. + * @see addIndicesLines() + */ + protected function addIndices(&$script) + { + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php new file mode 100644 index 000000000..53f35d4d1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php @@ -0,0 +1,33 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * MySQL class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.mysql + */ +class MysqlDataSQLBuilder extends DataSQLBuilder { + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDDLBuilder.php new file mode 100644 index 000000000..c3eee856d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDDLBuilder.php @@ -0,0 +1,33 @@ +. + */ + +require_once 'propel/engine/builder/sql/mysql/MysqlDDLBuilder.php'; + +/** + * DDL Builder class for MySQL, specifically using new mysqli API. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.mysql + */ +class MysqliDDLBuilder extends MysqlDDLBuilder { + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDataSQLBuilder.php new file mode 100644 index 000000000..ec634b006 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/mysqli/MysqliDataSQLBuilder.php @@ -0,0 +1,33 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * MySQL class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.mysql + */ +class MysqliDataSQLBuilder extends DataSQLBuilder { + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php new file mode 100644 index 000000000..e5ec0f7f7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php @@ -0,0 +1,177 @@ +. + */ + +require_once 'propel/engine/builder/sql/DDLBuilder.php'; + +/** + * The SQL DDL-building class for Oracle. + * + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.pgsql + */ +class OracleDDLBuilder extends DDLBuilder { + + /** + * + * @see parent::addDropStatement() + */ + protected function addDropStatements(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + $script .= " +DROP TABLE ".$this->quoteIdentifier($table->getName())." CASCADE CONSTRAINTS; +"; + if ($table->getIdMethod() == "native") { + $script .= " +DROP SEQUENCE ".$this->quoteIdentifier($table->getSequenceName())."; +"; + } + } + + /** + * + * @see parent::addColumns() + */ + protected function addTable(&$script) + { + $table = $this->getTable(); + $script .= " + +/* ----------------------------------------------------------------------- + ".$table->getName()." + ----------------------------------------------------------------------- */ +"; + + $this->addDropStatements($script); + + $script .= " + +CREATE TABLE ".$this->quoteIdentifier($table->getName())." +( + "; + + $lines = array(); + + foreach ($table->getColumns() as $col) { + $lines[] = $this->getColumnDDL($col); + } + + $sep = ", + "; + $script .= implode($sep, $lines); + $script .= " +); +"; + $this->addPrimaryKey($script); + $this->addIndices($script); + $this->addSequences($script); + + } + + /** + * + * + */ + protected function addPrimaryKey(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + $tableName = $table->getName(); + $length = strlen($tableName); + if ($length > 27) { + $length = 27; + } + if ( is_array($table->getPrimaryKey()) && count($table->getPrimaryKey()) ) { + $script .= " + ALTER TABLE ".$this->quoteIdentifier($table->getName())." + ADD CONSTRAINT ".$this->quoteIdentifier(substr($tableName,0,$length)."_PK")." + PRIMARY KEY ("; + $delim = ""; + foreach ($table->getPrimaryKey() as $col) { + $script .= $delim . $this->quoteIdentifier($col->getName()); + $delim = ","; + } + $script .= "); +"; + } + } + + /** + * Adds CREATE SEQUENCE statements for this table. + * + */ + protected function addSequences(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + if ($table->getIdMethod() == "native") { + $script .= "CREATE SEQUENCE ".$this->quoteIdentifier($table->getSequenceName())." INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER; +"; + } + } + + + /** + * Adds CREATE INDEX statements for this table. + * @see parent::addIndices() + */ + protected function addIndices(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + foreach ($table->getIndices() as $index) { + $script .= "CREATE "; + if($index->getIsUnique()) { + $script .= "UNIQUE"; + } + $script .= "INDEX ".$this->quoteIdentifier($index->getName()) ." ON ".$this->quoteIdentifier($table->getName())." (".$this->getColumnList($index->getColumns())."); +"; + } + } + + /** + * + * @see parent::addForeignKeys() + */ + protected function addForeignKeys(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + foreach ($table->getForeignKeys() as $fk) { + $script .= " +ALTER TABLE ".$this->quoteIdentifier($table->getName())." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($fk->getForeignTableName())." (".$this->getColumnList($fk->getForeignColumns()).")"; + if ($fk->hasOnUpdate()) { + $this->warn("ON UPDATE not yet implemented for Oracle builder.(ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk)."); + //$script .= " ON UPDATE ".$fk->getOnUpdate(); + } + if ($fk->hasOnDelete()) { + $script .= " ON DELETE ".$fk->getOnDelete(); + } + $script .= "; +"; + } + } + + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php new file mode 100644 index 000000000..223a795f7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php @@ -0,0 +1,34 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * Oracle class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.oracle + */ +class OracleDataSQLBuilder extends DataSQLBuilder { + + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php new file mode 100644 index 000000000..dc7df9b54 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php @@ -0,0 +1,248 @@ +. + */ + +require_once 'propel/engine/builder/sql/DDLBuilder.php'; + +/** + * The SQL DDL-building class for PostgreSQL. + * + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.pgsql + */ +class PgsqlDDLBuilder extends DDLBuilder { + + + /** + * Array that keeps track of already + * added schema names + * + * @var Array of schema names + */ + protected static $addedSchemas = array(); + + /** + * Get the schema for the current table + * + * @author Markus Lervik + * @access protected + * @return schema name if table has one, else + * null + **/ + protected function getSchema() + { + + $table = $this->getTable(); + $schema = $table->getVendorSpecificInfo(); + if (!empty($schema) && isset($schema['schema'])) { + return $schema['schema']; + } + + return null; + + } + + /** + * Add a schema to the generated SQL script + * + * @author Markus Lervik + * @access protected + * @return string with CREATE SCHEMA statement if + * applicable, else empty string + **/ + protected function addSchema() + { + + $schemaName = $this->getSchema(); + + if ($schemaName !== null) { + + if (!in_array($schemaName, self::$addedSchemas)) { + $platform = $this->getPlatform(); + self::$addedSchemas[] = $schemaName; + return "\nCREATE SCHEMA " . $this->quoteIdentifier($schemaName) . ";\n"; + } + } + + return ''; + + } + + /** + * + * @see parent::addDropStatement() + */ + protected function addDropStatements(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +DROP TABLE ".$this->quoteIdentifier($table->getName())." CASCADE; +"; + if ($table->getIdMethod() == "native") { + $script .= " +DROP SEQUENCE ".$this->quoteIdentifier(strtolower($table->getSequenceName()))."; +"; + } + } + + /** + * + * @see parent::addColumns() + */ + protected function addTable(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +----------------------------------------------------------------------------- +-- ".$table->getName()." +----------------------------------------------------------------------------- +"; + + $script .= $this->addSchema(); + + $schemaName = $this->getSchema(); + if ($schemaName !== null) { + $script .= "\nSET search_path TO " . $this->quoteIdentifier($schemaName) . ";\n"; + } + + $this->addDropStatements($script); + $this->addSequences($script); + + $script .= " + +CREATE TABLE ".$this->quoteIdentifier($table->getName())." +( + "; + + $lines = array(); + + foreach ($table->getColumns() as $col) { + $lines[] = $this->getColumnDDL($col); + } + + if ($table->hasPrimaryKey()) { + $lines[] = "PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")"; + } + + foreach ($table->getUnices() as $unique ) { + $lines[] = "CONSTRAINT ".$this->quoteIdentifier($unique->getName())." UNIQUE (".$this->getColumnList($unique->getColumns()).")"; + } + + $sep = ", + "; + $script .= implode($sep, $lines); + $script .= " +); + +COMMENT ON TABLE ".$this->quoteIdentifier($table->getName())." IS '" . $platform->escapeText($table->getDescription())."'; + +"; + + $this->addColumnComments($script); + + $script .= "\nSET search_path TO public;"; + + } + + /** + * Adds comments for the columns. + * + */ + protected function addColumnComments(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($this->getTable()->getColumns() as $col) { + if( $col->getDescription() != '' ) { + $script .= " +COMMENT ON COLUMN ".$this->quoteIdentifier($table->getName()).".".$this->quoteIdentifier($col->getName())." IS '".$platform->escapeText($col->getDescription()) ."'; +"; + } + } + } + + /** + * Adds CREATE SEQUENCE statements for this table. + * + */ + protected function addSequences(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + if ($table->getIdMethod() == "native") { + $script .= " +CREATE SEQUENCE ".$this->quoteIdentifier(strtolower($table->getSequenceName()))."; +"; + } + } + + + /** + * Adds CREATE INDEX statements for this table. + * @see parent::addIndices() + */ + protected function addIndices(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getIndices() as $index) { + $script .= " +CREATE "; + if($index->getIsUnique()) { + $script .= "UNIQUE"; + } + $script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($table->getName())." (".$this->getColumnList($index->getColumns())."); +"; + } + } + + /** + * + * @see parent::addForeignKeys() + */ + protected function addForeignKeys(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getForeignKeys() as $fk) { + $script .= " +ALTER TABLE ".$this->quoteIdentifier($table->getName())." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($fk->getForeignTableName())." (".$this->getColumnList($fk->getForeignColumns()).")"; + if ($fk->hasOnUpdate()) { + $script .= " ON UPDATE ".$fk->getOnUpdate(); + } + if ($fk->hasOnDelete()) { + $script .= " ON DELETE ".$fk->getOnDelete(); + } + $script .= "; +"; + } + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php new file mode 100644 index 000000000..46711f554 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php @@ -0,0 +1,60 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * PostgreSQL class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.pgsql + */ +class PgsqlDataSQLBuilder extends DataSQLBuilder { + + /** + * Get SQL value to insert for Postgres BOOLEAN column. + * @param boolean $value + * @return string The representation of boolean for Postgres ('t' or 'f'). + */ + protected function getBooleanSql($value) + { + if ($value === 'f' || $value === 'false' || $value === "0") { + $value = false; + } + return ($value ? "'t'" : "'f'"); + } + + /** + * + * @param mixed $blob Blob object or string containing data. + * @return string + */ + protected function getBlobSql($blob) + { + // they took magic __toString() out of PHP5.0.0; this sucks + if (is_object($blob)) { + $blob = $blob->__toString(); + } + return "'" . pg_escape_bytea($blob) . "'"; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php new file mode 100644 index 000000000..07d5d0d30 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php @@ -0,0 +1,126 @@ +. + */ + +require_once 'propel/engine/builder/sql/DDLBuilder.php'; + +/** + * The SQL DDL-building class for SQLite. + * + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.pgsql + */ +class SqliteDDLBuilder extends DDLBuilder { + + /** + * + * @see parent::addDropStatement() + */ + protected function addDropStatements(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +DROP TABLE ".$this->quoteIdentifier($table->getName())."; +"; + } + + /** + * + * @see parent::addColumns() + */ + protected function addTable(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + $script .= " +----------------------------------------------------------------------------- +-- ".$table->getName()." +----------------------------------------------------------------------------- +"; + + $this->addDropStatements($script); + + $script .= " + +CREATE TABLE ".$this->quoteIdentifier($table->getName())." +( + "; + + $lines = array(); + + foreach ($table->getColumns() as $col) { + $lines[] = $this->getColumnDDL($col); + } + + foreach ($table->getUnices() as $unique ) { + $lines[] = "UNIQUE (".$this->getColumnList($unique->getColumns()).")"; + } + + $sep = ", + "; + $script .= implode($sep, $lines); + $script .= " +); +"; + } + + /** + * Adds CREATE INDEX statements for this table. + * @see parent::addIndices() + */ + protected function addIndices(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getIndices() as $index) { + $script .= " +CREATE "; + if($index->getIsUnique()) { + $script .= "UNIQUE"; + } + $script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($table->getName())." (".$this->getColumnList($index->getColumns())."); +"; + } + } + + /** + * + * @see parent::addForeignKeys() + */ + protected function addForeignKeys(&$script) + { + $table = $this->getTable(); + $platform = $this->getPlatform(); + + foreach ($table->getForeignKeys() as $fk) { + $script .= " +-- SQLite does not support foreign keys; this is just for reference +-- FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()).") REFERENCES ".$fk->getForeignTableName()." (".$this->getColumnList($fk->getForeignColumns()).") +"; + } + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php new file mode 100644 index 000000000..8fa33d8ef --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php @@ -0,0 +1,47 @@ +. + */ + +require_once 'propel/engine/builder/sql/DataSQLBuilder.php'; + +/** + * SQLite class for building data dump SQL. + * + * @author Hans Lellelid + * @package propel.engine.builder.sql.sqlite + */ +class SqliteDataSQLBuilder extends DataSQLBuilder { + + /** + * Returns string processed by sqlite_udf_encode_binary() to ensure that binary contents will be handled correctly by sqlite. + * @param mixed $blob Blob or string + * @return string encoded text + */ + protected function getBlobSql($blob) + { + // they took magic __toString() out of PHP5.0.0; this sucks + if (is_object($blob)) { + $blob = $blob->__toString(); + } + return "'" . sqlite_udf_encode_binary($blob) . "'"; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/AppData.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/AppData.php new file mode 100644 index 000000000..0372147d8 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/AppData.php @@ -0,0 +1,206 @@ +. + */ + +include_once 'propel/engine/EngineException.php'; +include_once 'propel/engine/database/model/Database.php'; + +/** + * A class for holding application data structures. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author John McNally (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class AppData { + + /** + * The list of databases for this application. + * @var array Database[] + */ + private $dbList = array(); + + /** + * The platform class for our database(s). + * @var string + */ + private $platform; + + /** + * Name of the database. Only one database definition + * is allowed in one XML descriptor. + */ + private $name; + + /** + * Flag to ensure that initialization is performed only once. + * @var boolean + */ + private $isInitialized = false; + + /** + * Creates a new instance for the specified database type. + * + * @param Platform $platform The platform class to use for any databases added to this application model. + */ + public function __construct(Platform $platform) + { + $this->platform = $platform; + } + + /** + * Set the name of the database. + * + * @param name of the database. + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Get the name of the database. + * + * @return String name + */ + public function getName() + { + return $this->name; + } + + /** + * Get the short name of the database (without the '-schema' postfix). + * + * @return String name + */ + public function getShortName() + { + return str_replace("-schema", "", $name); + } + + /** + * Return an array of all databases + * + * @return Array of Database objects + */ + public function getDatabases($doFinalInit = true) + { + // this is temporary until we'll have a clean solution + // for packaging datamodels/requiring schemas + if ($doFinalInit) { + $this->doFinalInitialization(); + } + return $this->dbList; + } + + /** + * Returns whether this application has multiple databases. + * + * @return boolean True if the application has multiple databases + */ + public function hasMultipleDatabases() + { + return (count($this->dbList) > 1); + } + + /** + * Return the database with the specified name. + * + * @param name database name + * @return A Database object. If it does not exist it returns null + */ + public function getDatabase($name = null, $doFinalInit = true) + { + // this is temporary until we'll have a clean solution + // for packaging datamodels/requiring schemas + if ($doFinalInit) { + $this->doFinalInitialization(); + } + + if ($name === null) { + return $this->dbList[0]; + } + + for($i=0,$size=count($this->dbList); $i < $size; $i++) { + $db = $this->dbList[$i]; + if ($db->getName() === $name) { + return $db; + } + } + return null; + } + + /** + * Add a database to the list and sets the AppData property to this + * AppData + * + * @param db the database to add + */ + public function addDatabase($db) + { + if ($db instanceof Database) { + $db->setAppData($this); + if ($db->getPlatform() === null) { + $db->setPlatform($this->platform); + } + $this->dbList[] = $db; + return $db; + } else { + // XML attributes array / hash + $d = new Database(); + $d->loadFromXML($db); + return $this->addDatabase($d); // calls self w/ different param type + } + + } + + /** + * + * @return void + */ + private function doFinalInitialization() + { + if (!$this->isInitialized) { + for($i=0, $size=count($this->dbList); $i < $size; $i++) { + $this->dbList[$i]->doFinalInitialization(); + } + $this->isInitialized = true; + } + } + + /** + * Creats a string representation of this AppData. + * The representation is given in xml format. + * + * @return string Representation in xml format + */ + public function toString() + { + $result = "\n"; + for ($i=0,$size=count($this->dbList); $i < $size; $i++) { + $result .= $this->dbList[$i]->toString(); + } + $result .= ""; + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Column.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Column.php new file mode 100644 index 000000000..df5c6e8da --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Column.php @@ -0,0 +1,921 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; +include_once 'propel/engine/EngineException.php'; +include_once 'propel/engine/database/model/PropelTypes.php'; +include_once 'propel/engine/database/model/Inheritance.php'; +include_once 'propel/engine/database/model/Domain.php'; + +/** + * A Class for holding data about a column used in an Application. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author Jason van Zyl (Torque) + * @author Jon S. Stevens (Torque) + * @author Daniel Rall (Torque) + * @author Byron Foster (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Column extends XMLElement { + + const DEFAULT_TYPE = "VARCHAR"; + + private $name; + private $description; + private $phpName = null; + private $phpNamingMethod; + private $isNotNull = false; + private $size; + + /** + * The name to use for the Peer constant that identifies this column. + * (Will be converted to all-uppercase in the templates.) + * @var string + */ + private $peerName; + + /** + * Type as defined in schema.xml + * @var string + */ + private $propelType; + + /** + * Type corresponding to Creole type + * @var int + */ + private $creoleType; + + /** + * Native PHP type + * @var string "string", "boolean", "int", "double" + */ + private $phpType; + private $parentTable; + private $position; + private $isPrimaryKey = false; + private $isNodeKey = false; + private $nodeKeySep; + private $isUnique = false; + private $isAutoIncrement = false; + private $isLazyLoad = false; + private $defaultValue; + private $referrers; + // only one type is supported currently, which assumes the + // column either contains the classnames or a key to + // classnames specified in the schema. Others may be + // supported later. + private $inheritanceType; + private $isInheritance; + private $isEnumeratedClasses; + private $inheritanceList; + private $needsTransactionInPostgres; //maybe this can be retrieved from vendorSpecificInfo + + /** class name to do input validation on this column */ + private $inputValidator = null; + + private $domain; + + /** + * Creates a new column and set the name + * + * @param name column name + */ + public function __construct($name = null) + { + $this->name = $name; + } + + /** + * Return a comma delimited string listing the specified columns. + * + * @param columns Either a list of Column objects, or + * a list of String objects with column names. + * @deprecated Use the DDLBuilder->getColumnList() method instead; this will be removed in 1.3 + */ + public static function makeList($columns, Platform $platform) + { + $list = array(); + foreach($columns as $col) { + if ($col instanceof Column) { + $col = $col->getName(); + } + $list[] = $platform->quoteIdentifier($col); + } + return implode(", ", $list); + } + + /** + * Sets up the Column object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + try { + $dom = $this->getAttribute("domain"); + if ($dom) { + $this->domain = new Domain(); + $this->domain->copy($this->getTable()->getDatabase()->getDomain($dom)); + } else { + $this->domain = new Domain(); + $this->domain->copy($this->getPlatform()->getDomainForType(self::DEFAULT_TYPE)); + $this->setType(strtoupper($this->getAttribute("type"))); + } + + //Name + $this->name = $this->getAttribute("name"); + + $this->phpName = $this->getAttribute("phpName"); + $this->phpType = $this->getAttribute("phpType"); + $this->peerName = $this->getAttribute("peerName"); + + if (empty($this->phpType)) { + $this->phpType = null; + } + + // retrieves the method for converting from specified name to + // a PHP name. + $this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->parentTable->getDatabase()->getDefaultPhpNamingMethod()); + + $this->isPrimaryKey = $this->booleanValue($this->getAttribute("primaryKey")); + + $this->isNodeKey = $this->booleanValue($this->getAttribute("nodeKey")); + $this->nodeKeySep = $this->getAttribute("nodeKeySep", "."); + + $this->isNotNull = $this->booleanValue($this->getAttribute("required"), false); + + // Regardless of above, if this column is a primary key then it can't be null. + if ($this->isPrimaryKey) { + $this->isNotNull = true; + } + + //AutoIncrement/Sequences + $this->isAutoIncrement = $this->booleanValue($this->getAttribute("autoIncrement")); + $this->isLazyLoad = $this->booleanValue($this->getAttribute("lazyLoad")); + + //Default column value. + $this->domain->replaceDefaultValue($this->getAttribute("default")); + $this->domain->replaceSize($this->getAttribute("size")); + $this->domain->replaceScale($this->getAttribute("scale")); + + $this->inheritanceType = $this->getAttribute("inheritance"); + $this->isInheritance = ($this->inheritanceType !== null + && $this->inheritanceType !== "false"); // here we are only checking for 'false', so don't + // use boleanValue() + + $this->inputValidator = $this->getAttribute("inputValidator"); + $this->description = $this->getAttribute("description"); + } catch (Exception $e) { + throw new EngineException("Error setting up column " . var_export($this->getAttribute("name"), true) . ": " . $e->getMessage()); + } + } + + /** + * Gets domain for this column. + * @return Domain + */ + public function getDomain() + { + return $this->domain; + } + + /** + * Returns table.column + */ + public function getFullyQualifiedName() + { + return ($this->parentTable->getName() . '.' . name); + } + + /** + * Get the name of the column + */ + public function getName() + { + return $this->name; + } + + /** + * Set the name of the column + */ + public function setName($newName) + { + $this->name = $newName; + } + + /** + * Get the description for the Table + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set the description for the Table + * + * @param newDescription description for the Table + */ + public function setDescription($newDescription) + { + $this->description = $newDescription; + } + + /** + * Get name to use in PHP sources + * @return string + */ + public function getPhpName() + { + if ($this->phpName === null) { + $inputs = array(); + $inputs[] = $this->name; + $inputs[] = $this->phpNamingMethod; + try { + $this->phpName = NameFactory::generateName(NameFactory::PHP_GENERATOR, $inputs); + } catch (EngineException $e) { + print $e->getMessage() . "\n"; + print $e->getTraceAsString(); + } + } + return $this->phpName; + } + + /** + * Set name to use in PHP sources + */ + public function setPhpName($phpName) + { + $this->phpName = $phpName; + } + + /** + * Get the Peer constant name that will identify this column. + * @return string + */ + public function getPeerName() { + return $this->peerName; + } + + /** + * Set the Peer constant name that will identify this column. + * @param $name string + */ + public function setPeerName($name) { + $this->peerName = $name; + } + + /** + * Get type to use in PHP sources. + * If no type has been specified, then uses results + * of getPhpNative(). + * + * The distinction between getPhpType() and getPhpNative() + * is not as salient in PHP as it is in Java, but we'd like to leave open the + * option of specifying complex types (objects) in the schema. While we can + * always cast to PHP native types, we can't cast objects (in PHP) -- hence the + * importance of maintaining this distinction. + * + * @return string The type name. + * @see getPhpNative() + */ + public function getPhpType() + { + if ($this->phpType !== null) { + return $this->phpType; + } + return $this->getPhpNative(); + } + + /** + * Get the location of this column within the table (one-based). + * @return int value of position. + */ + public function getPosition() + { + return $this->position; + } + + /** + * Get the location of this column within the table (one-based). + * @param int $v Value to assign to position. + */ + public function setPosition($v) + { + $this->position = $v; + } + + /** + * Set the parent Table of the column + */ + public function setTable(Table $parent) + { + $this->parentTable = $parent; + } + + /** + * Get the parent Table of the column + */ + public function getTable() + { + return $this->parentTable; + } + + /** + * Returns the Name of the table the column is in + */ + public function getTableName() + { + return $this->parentTable->getName(); + } + + /** + * Adds a new inheritance definition to the inheritance list and set the + * parent column of the inheritance to the current column + * @param mixed $inhdata Inheritance or XML data. + */ + public function addInheritance($inhdata) + { + if ($inhdata instanceof Inheritance) { + $inh = $inhdata; + $inh->setColumn($this); + if ($this->inheritanceList === null) { + $this->inheritanceList = array(); + $this->isEnumeratedClasses = true; + } + $this->inheritanceList[] = $inh; + return $inh; + } else { + $inh = new Inheritance(); + $inh->loadFromXML($inhdata); + return $this->addInheritance($inh); + } + } + + /** + * Get the inheritance definitions. + */ + public function getChildren() + { + return $this->inheritanceList; + } + + /** + * Determine if this column is a normal property or specifies a + * the classes that are represented in the table containing this column. + */ + public function isInheritance() + { + return $this->isInheritance; + } + + /** + * Determine if possible classes have been enumerated in the xml file. + */ + public function isEnumeratedClasses() + { + return $this->isEnumeratedClasses; + } + + /** + * Return the isNotNull property of the column + */ + public function isNotNull() + { + return $this->isNotNull; + } + + /** + * Set the isNotNull property of the column + */ + public function setNotNull($status) + { + $this->isNotNull = (boolean) $status; + } + + /** + * Return NOT NULL String for this column + * + * @return "NOT NULL" if null values are not allowed or an empty string. + */ + public function getNotNullString() + { + return $this->getTable()->getDatabase()->getPlatform()->getNullString($this->isNotNull()); + } + + /** + * Set if the column is a primary key or not + */ + public function setPrimaryKey($pk) + { + $this->isPrimaryKey = (boolean) $pk; + } + + /** + * Return true if the column is a primary key + */ + public function isPrimaryKey() + { + return $this->isPrimaryKey; + } + + /** + * Set if the column is the node key of a tree + */ + public function setNodeKey($nk) + { + $this->isNodeKey = (boolean) $nk; + } + + /** + * Return true if the column is a node key of a tree + */ + public function isNodeKey() + { + return $this->isNodeKey; + } + + /** + * Set if the column is the node key of a tree + */ + public function setNodeKeySep($sep) + { + $this->nodeKeySep = (string) $sep; + } + + /** + * Return true if the column is a node key of a tree + */ + public function getNodeKeySep() + { + return $this->nodeKeySep; + } + + /** + * Set true if the column is UNIQUE + */ + public function setUnique($u) + { + $this->isUnique = $u; + } + + /** + * Get the UNIQUE property + */ + public function isUnique() + { + return $this->isUnique; + } + + /** + * Return true if the column requires a transaction in Postgres + */ + public function requiresTransactionInPostgres() + { + return $this->needsTransactionInPostgres; + } + + /** + * Utility method to determine if this column is a foreign key. + */ + public function isForeignKey() + { + return ($this->getForeignKey() !== null); + } + + /** + * Determine if this column is a foreign key that refers to the + * same table as another foreign key column in this table. + */ + public function isMultipleFK() + { + $fk = $this->getForeignKey(); + if ($fk !== null) { + $fks = $this->parentTable->getForeignKeys(); + for ($i=0, $len=count($fks); $i < $len; $i++) { + if ($fks[$i]->getForeignTableName() === $fk->getForeignTableName() + && !in_array($this->name, $fks[$i]->getLocalColumns()) ) { + return true; + } + } + } + + // No multiple foreign keys. + return false; + } + + /** + * get the foreign key object for this column + * if it is a foreign key or part of a foreign key + */ + public function getForeignKey() + { + return $this->parentTable->getForeignKey($this->name); + } + + /** + * Utility method to get the related table of this column if it is a foreign + * key or part of a foreign key + */ + public function getRelatedTableName() + { + $fk = $this->getForeignKey(); + return ($fk === null ? null : $fk->getForeignTableName()); + } + + + /** + * Utility method to get the related column of this local column if this + * column is a foreign key or part of a foreign key. + */ + public function getRelatedColumnName() + { + $fk = $this->getForeignKey(); + if ($fk === null) { + return null; + } else { + $m = $fk->getLocalForeignMapping(); + $c = @$m[$this->name]; + if ($c === null) { + return null; + } else { + return $c; + } + } + } + + /** + * Adds the foreign key from another table that refers to this column. + */ + public function addReferrer(ForeignKey $fk) + { + if ($this->referrers === null) { + $this->referrers = array(); + } + $this->referrers[] = $fk; + } + + /** + * Get list of references to this column. + */ + public function getReferrers() + { + if ($this->referrers === null) { + $this->referrers = array(); + } + return $this->referrers; + } + + /** + * Returns the colunm type + */ + public function setType($propelType) + { + $this->domain = new Domain(); + $this->domain->copy($this->getPlatform()->getDomainForType($propelType)); + + $this->propelType = $propelType; + if ($propelType == PropelTypes::VARBINARY|| $propelType == PropelTypes::LONGVARBINARY || $propelType == PropelTypes::BLOB) { + $this->needsTransactionInPostgres = true; + } + } + + /** + * Returns the column Creole type as a string. + * @return string The constant representing Creole type: e.g. "VARCHAR". + */ + public function getType() + { + return PropelTypes::getCreoleType($this->propelType); + } + + /** + * Returns the column type as given in the schema as an object + */ + public function getPropelType() + { + return $this->propelType; + } + + /** + * Utility method to know whether column needs Blob/Lob handling. + * @return boolean + */ + public function isLob() + { + return PropelTypes::isLobType($this->propelType); + } + + /** + * Utility method to see if the column is a string + */ + public function isString() + { + return PropelTypes::isTextxType($this->propelType); + } + + /** + * String representation of the column. This is an xml representation. + */ + public function toString() + { + $result = " name . '"'; + if ($this->phpName !== null) { + $result .= " phpName=\"" . $this->phpName . '"'; + } + if ($this->isPrimaryKey) { + $result .= " primaryKey=\"" . ($this->isPrimaryKey ? "true" : "false"). '"'; + } + + if ($this->isNotNull) { + $result .= " required=\"true\""; + } else { + $result .= " required=\"false\""; + } + + $result .= " type=\"" . $this->propelType . '"'; + + if ($this->domain->getSize() !== null) { + $result .= " size=\"" . $this->domain->getSize() . '"'; + } + + if ($this->domain->getScale() !== null) { + $result .= " scale=\"" . $this->domain->getScale() . '"'; + } + + if ($this->domain->getDefaultValue() !== null) { + $result .= " default=\"" . $this->domain->getDefaultValue() . '"'; + } + + if ($this->isInheritance()) { + $result .= " inheritance=\"" . $this->inheritanceType + . '"'; + } + + if ($this->isNodeKey()) { + $result .= " nodeKey=\"true\""; + if ($this->getNodeKeySep() !== null) { + $result .= " nodeKeySep=\"" . $this->nodeKeySep . '"'; + } + } + + // Close the column. + $result .= " />\n"; + + return $result; + } + + /** + * Returns the size of the column + * @return string + */ + public function getSize() + { + return $this->domain->getSize(); + } + + /** + * Set the size of the column + * @param string $newSize + */ + public function setSize($newSize) + { + $this->domain->setSize($newSize); + } + + /** + * Returns the scale of the column + * @return string + */ + public function getScale() + { + return $this->domain->getScale(); + } + + /** + * Set the scale of the column + * @param string $newScale + */ + public function setScale($newScale) + { + $this->domain->setScale($newScale); + } + + /** + * Return the size in brackets for use in an sql + * schema if the type is String. Otherwise return an empty string + */ + public function printSize() + { + return $this->domain->printSize(); + } + + /** + * Return a string that will give this column a default value. + * @return string + */ + public function getDefaultSetting() + { + $dflt = ""; + if ($this->getDefaultValue() !== null) { + $dflt .= "default "; + if (PropelTypes::isTextType($this->getType())) { + $dflt .= '\'' . $this->getPlatform()->escapeText($this->getDefaultValue()) . '\''; + } elseif ($this->getType() == PropelTypes::BOOLEAN) { + $dflt .= $this->getPlatform()->getBooleanString($this->getDefaultValue()); + } else { + $dflt .= $this->getDefaultValue(); + } + } + return $dflt; + } + + /** + * Set a string that will give this column a default value. + */ + public function setDefaultValue($def) + { + $this->domain->setDefaultValue($def); + } + + /** + * Get the raw string that will give this column a default value. + * @return string + * @see Domain::getDefaultValue() + */ + public function getDefaultValue() + { + return $this->domain->getDefaultValue(); + } + + /** + * Get the default value suitable for use in PHP. + * @return mixed + * @see Domain::getPhpDefaultValue() + */ + public function getPhpDefaultValue() + { + return $this->domain->getPhpDefaultValue(); + } + + /** + * Returns the class name to do input validation + */ + public function getInputValidator() + { + return $this->inputValidator; + } + + /** + * Return auto increment/sequence string for the target database. We need to + * pass in the props for the target database! + */ + public function isAutoIncrement() + { + return $this->isAutoIncrement; + } + + /** + * Return auto increment/sequence string for the target database. We need to + * pass in the props for the target database! + */ + public function isLazyLoad() + { + return $this->isLazyLoad; + } + + /** + * Gets the auto-increment string. + * @return string + */ + public function getAutoIncrementString() + { + if ($this->isAutoIncrement()&& IDMethod::NATIVE === $this->getTable()->getIdMethod()) { + return $this->getPlatform()->getAutoIncrement(); + } elseif ($this->isAutoIncrement()) { + throw new EngineException("You have specified autoIncrement for column '" . $this->name . "' but you have not specified idMethod=\"native\" for table '" . $this->getTable()->getName() . "'."); + } + return ""; + } + + /** + * Set the auto increment value. + * Use isAutoIncrement() to find out if it is set or not. + */ + public function setAutoIncrement($value) + { + $this->isAutoIncrement = (boolean) $value; + } + + /** + * Set the column type from a string property + * (normally a string from an sql input file) + */ + public function setTypeFromString($typeName, $size) + { + $tn = strtoupper($typeName); + $this->setType($tn); + + if ($size !== null) { + $this->size = $size; + } + + if (strpos($tn, "CHAR") !== false) { + $this->domain->setType(PropelTypes::VARCHAR); + } elseif (strpos($tn, "INT") !== false) { + $this->domain->setType(PropelTypes::INTEGER); + } elseif (strpos($tn, "FLOAT") !== false) { + $this->domain->setType(PropelTypes::FLOAT); + } elseif (strpos($tn, "DATE") !== false) { + $this->domain->setType(PropelTypes::DATE); + } elseif (strpos($tn, "TIME") !== false) { + $this->domain->setType(PropelTypes::TIMESTAMP); + } else if (strpos($tn, "BINARY") !== false) { + $this->domain->setType(PropelTypes::LONGVARBINARY); + } else { + $this->domain->setType(PropelTypes::VARCHAR); + } + } + + /** + * Return a string representation of the native PHP type which corresponds + * to the Creole type of this column. Use in the generation of Base objects. + * + * @return string PHP datatype used by propel. + */ + public function getPhpNative() + { + return PropelTypes::getPHPNative($this->propelType); + } + + /** + * Returns true if the column's PHP native type is an + * boolean, int, long, float, double, string + */ + public function isPrimitive() + { + $t = $this->getPhpNative(); + return in_array($t, array("boolean", "int", "double", "string")); + } + + /** + * Return true if column's PHP native type is an + * boolean, int, long, float, double + */ + public function isPrimitiveNumeric() + { + $t = $this->getPhpNative(); + return in_array($t, array("boolean", "int", "double")); + } + + /** + * Get the platform/adapter impl. + * + * @return Platform + */ + public function getPlatform() + { + return $this->getTable()->getDatabase()->getPlatform(); + } + + /** + * + * @return string + * @deprecated Use DDLBuilder->getColumnDDL() instead; this will be removed in 1.3 + */ + public function getSqlString() + { + $sb = ""; + $sb .= $this->getPlatform()->quoteIdentifier($this->getName()) . " "; + $sb .= $this->getDomain()->getSqlType(); + if ($this->getPlatform()->hasSize($this->getDomain()->getSqlType())) { + $sb .= $this->getDomain()->printSize(); + } + $sb .= " "; + $sb .= $this->getDefaultSetting() . " "; + $sb .= $this->getNotNullString() . " "; + $sb .= $this->getAutoIncrementString(); + return trim($sb); + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php new file mode 100644 index 000000000..9f1dc2585 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php @@ -0,0 +1,84 @@ +. + */ + + +/** + * A NameGenerator implementation for table-specific + * constraints. Conforms to the maximum column name length for the + * type of database in use. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class ConstraintNameGenerator implements NameGenerator { + /** + * Conditional compilation flag. + */ + const DEBUG = false; + + /** + * First element of inputs should be of type {@link Database}, second + * should be a table name, third is the type identifier (spared if + * trimming is necessary due to database type length constraints), + * and the fourth is a Integer indicating the number + * of this contraint. + * + * @see NameGenerator + * @throws EngineException + */ + public function generateName($inputs) + { + + $db = $inputs[0]; + $name = $inputs[1]; + $namePostfix = $inputs[2]; + $constraintNbr = (string) $inputs[3]; + + // Calculate maximum RDBMS-specific column character limit. + $maxBodyLength = -1; + try { + $maxColumnNameLength = (int) $db->getPlatform()->getMaxColumnNameLength(); + $maxBodyLength = ($maxColumnNameLength - strlen($namePostfix) + - strlen($constraintNbr) - 2); + + if (self::DEBUG) { + print("maxColumnNameLength=" . $maxColumnNameLength + . " maxBodyLength=" . $maxBodyLength . "\n"); + } + } catch (EngineException $e) { + echo $e; + throw $e; + } + + // Do any necessary trimming. + if ($maxBodyLength !== -1 && strlen($name) > $maxBodyLength) { + $name = substr($name, 0, $maxBodyLength); + } + + $name .= self::STD_SEPARATOR_CHAR . $namePostfix + . self::STD_SEPARATOR_CHAR . $constraintNbr; + + return $name; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Database.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Database.php new file mode 100644 index 000000000..7fe778f67 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Database.php @@ -0,0 +1,463 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; +include_once 'propel/engine/database/model/IDMethod.php'; +include_once 'propel/engine/database/model/NameGenerator.php'; +include_once 'propel/engine/database/model/Table.php'; + +/** + * A class for holding application data structures. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author John McNally (Torque) + * @author Martin Poeschl (Torque) + * @author Daniel Rall (Torque) + * @author Byron Foster (Torque) + * @version $Revision: 576 $ + * @package propel.engine.database.model + */ +class Database extends XMLElement { + + private $platform; + private $tableList = array(); + private $curColumn; + private $name; + private $pkg; + private $baseClass; + private $basePeer; + private $defaultIdMethod; + private $defaultPhpType; + private $defaultPhpNamingMethod; + private $defaultTranslateMethod; + private $dbParent; + private $tablesByName = array(); + private $tablesByPhpName = array(); + private $heavyIndexing; + + private $domainMap = array(); + + /** + * Sets up the Database object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->name = $this->getAttribute("name"); + $this->pkg = $this->getAttribute("package"); + $this->baseClass = $this->getAttribute("baseClass"); + $this->basePeer = $this->getAttribute("basePeer"); + $this->defaultPhpType = $this->getAttribute("defaultPhpType"); + $this->defaultIdMethod = $this->getAttribute("defaultIdMethod"); + $this->defaultPhpNamingMethod = $this->getAttribute("defaultPhpNamingMethod", NameGenerator::CONV_METHOD_UNDERSCORE); + $this->defaultTranslateMethod = $this->getAttribute("defaultTranslateMethod", Validator::TRANSLATE_NONE); + $this->heavyIndexing = $this->booleanValue($this->getAttribute("heavyIndexing")); + } + + /** + * Returns the Platform implementation for this database. + * + * @return Platform a Platform implementation + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Sets the Platform implementation for this database. + * + * @param Platform $platform A Platform implementation + */ + public function setPlatform($platform) + { + $this->platform = $platform; + } + + /** + * Get the name of the Database + */ + public function getName() + { + return $this->name; + } + + /** + * Set the name of the Database + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Get the value of package. + * @return value of package. + */ + public function getPackage() + { + return $this->pkg; + } + + /** + * Set the value of package. + * @param v Value to assign to package. + */ + public function setPackage($v) + { + $this->pkg = $v; + } + + /** + * Get the value of baseClass. + * @return value of baseClass. + */ + public function getBaseClass() + { + return $this->baseClass; + } + + /** + * Set the value of baseClass. + * @param v Value to assign to baseClass. + */ + public function setBaseClass($v) + { + $this->baseClass = $v; + } + + /** + * Get the value of basePeer. + * @return value of basePeer. + */ + public function getBasePeer() + { + return $this->basePeer; + } + + /** + * Set the value of basePeer. + * @param v Value to assign to basePeer. + */ + public function setBasePeer($v) + { + $this->basePeer = $v; + } + + /** + * Get the value of defaultIdMethod. + * @return value of defaultIdMethod. + */ + public function getDefaultIdMethod() + { + return $this->defaultIdMethod; + } + + /** + * Set the value of defaultIdMethod. + * @param v Value to assign to defaultIdMethod. + */ + public function setDefaultIdMethod($v) + { + $this->defaultIdMethod = $v; + } + + /** + * Get the value of defaultPHPNamingMethod which specifies the + * method for converting schema names for table and column to PHP names. + * @return string The default naming conversion used by this database. + */ + public function getDefaultPhpNamingMethod() + { + return $this->defaultPhpNamingMethod; + } + + /** + * Set the value of defaultPHPNamingMethod. + * @param string $v The default naming conversion for this database to use. + */ + public function setDefaultPhpNamingMethod($v) + { + $this->defaultPhpNamingMethod = $v; + } + + /** + * Get the value of defaultTranslateMethod which specifies the + * method for translate validator error messages. + * @return string The default translate method. + */ + public function getDefaultTranslateMethod() + { + return $this->defaultTranslateMethod; + } + + /** + * Set the value of defaultTranslateMethod. + * @param string $v The default translate method to use. + */ + public function setDefaultTranslateMethod($v) + { + $this->defaultTranslateMethod = $v; + } + + /** + * Get the value of heavyIndexing. + * @return boolean Value of heavyIndexing. + */ + public function isHeavyIndexing() + { + return $this->heavyIndexing; + } + + /** + * Set the value of heavyIndexing. + * @param boolean $v Value to assign to heavyIndexing. + */ + public function setHeavyIndexing($v) + { + $this->heavyIndexing = (boolean) $v; + } + + /** + * Return an array of all tables + */ + public function getTables() + { + return $this->tableList; + } + + /** + * Return the table with the specified name. + * @param string $name The name of the table (e.g. 'my_table') + * @return Table a Table object or null if it doesn't exist + */ + public function getTable($name) + { + if (isset($this->tablesByName[$name])) { + return $this->tablesByName[$name]; + } + return null; // just to be explicit + } + + /** + * Return the table with the specified phpName. + * @param string $phpName the PHP Name of the table (e.g. 'MyTable') + * @return Table a Table object or null if it doesn't exist + */ + public function getTableByPhpName($phpName) + { + if (isset($this->tablesByPhpName[$phpName])) { + return $this->tablesByPhpName[$phpName]; + } + return null; // just to be explicit + } + + /** + * An utility method to add a new table from an xml attribute. + */ + public function addTable($data) + { + if ($data instanceof Table) { + $tbl = $data; // alias + $tbl->setDatabase($this); + if (isset($this->tablesByName[$tbl->getName()])) { + throw new EngineException("Duplicate table declared: " . $tbl->getName()); + } + $this->tableList[] = $tbl; + $this->tablesByName[ $tbl->getName() ] = $tbl; + $this->tablesByPhpName[ $tbl->getPhpName() ] = $tbl; + if ($tbl->getPackage() === null) { + $tbl->setPackage($this->getPackage()); + } + return $tbl; + } else { + $tbl = new Table(); + $tbl->setDatabase($this); + $tbl->loadFromXML($data); + return $this->addTable($tbl); // call self w/ different param + } + } + + /** + * Set the parent of the database + */ + public function setAppData(AppData $parent) + { + $this->dbParent = $parent; + } + + /** + * Get the parent of the table + */ + public function getAppData() + { + return $this->dbParent; + } + + /** + * Adds Domain object from tag. + * @param mixed XML attributes (array) or Domain object. + */ + public function addDomain($data) { + + if ($data instanceof Domain) { + $domain = $data; // alias + $domain->setDatabase($this); + $this->domainMap[ $domain->getName() ] = $domain; + return $domain; + } else { + $domain = new Table(); + $domain->setDatabase($this); + $domain->loadFromXML($data); + return $this->addDomain($domain); // call self w/ different param + } + } + + /** + * Get already configured Domain object by name. + * @return Domain + */ + public function getDomain($domainName) { + if (!isset($this->domainMap[$domainName])) { + return null; + } + return $this->domainMap[$domainName]; + } + + public function doFinalInitialization() + { + $tables = $this->getTables(); + + for($i=0,$size=count($tables); $i < $size; $i++) { + $currTable = $tables[$i]; + + // check schema integrity + // if idMethod="autoincrement", make sure a column is + // specified as autoIncrement="true" + // FIXME: Handle idMethod="native" via DB adapter. + /* + + --- REMOVING THIS BECAUSE IT'S ANNOYING + + if ($currTable->getIdMethod() == IDMethod::NATIVE ) { + $columns = $currTable->getColumns(); + $foundOne = false; + for ($j=0, $cLen=count($columns); $j < $cLen && !$foundOne; $j++) { + $foundOne = $columns[$j]->isAutoIncrement(); + } + + if (!$foundOne) { + $errorMessage = "Table '" . $currTable->getName() + . "' is set to use native id generation, but it does not " + . "have a column which declared as the one to " + . "auto increment (i.e. autoIncrement=\"true\")"; + + throw new BuildException($errorMessage); + } + } + */ + + $currTable->doFinalInitialization(); + + // setup reverse fk relations + $fks = $currTable->getForeignKeys(); + for ($j=0, $fksLen=count($fks); $j < $fksLen; $j++) { + $currFK = $fks[$j]; + $foreignTable = $this->getTable($currFK->getForeignTableName()); + if ($foreignTable === null) { + throw new BuildException("ERROR!! Attempt to set foreign" + . " key to nonexistent table, " + . $currFK->getForeignTableName() . "!"); + } + + $referrers = $foreignTable->getReferrers(); + if ($referrers === null || ! in_array($currFK,$referrers) ) { + $foreignTable->addReferrer($currFK); + } + + // local column references + $localColumnNames = $currFK->getLocalColumns(); + + for($k=0,$lcnLen=count($localColumnNames); $k < $lcnLen; $k++) { + + $local = $currTable->getColumn($localColumnNames[$k]); + + // give notice of a schema inconsistency. + // note we do not prevent the npe as there is nothing + // that we can do, if it is to occur. + if ($local === null) { + throw new BuildException("ERROR!! Attempt to define foreign" + . " key with nonexistent column, " + . $localColumnNames[$k] . ", in table, " + . $currTable->getName() . "!"); + } + + //check for foreign pk's + if ($local->isPrimaryKey()) { + $currTable->setContainsForeignPK(true); + } + + } // for each local col name + + // foreign column references + $foreignColumnNames = $currFK->getForeignColumns(); + for($k=0,$fcnLen=count($localColumnNames); $k < $fcnLen; $k++) { + $foreign = $foreignTable->getColumn($foreignColumnNames[$k]); + // if the foreign column does not exist, we may have an + // external reference or a misspelling + if ($foreign === null) { + throw new BuildException("ERROR!! Attempt to set foreign" + . " key to nonexistent column, " + . $foreignColumnNames[$k] . ", in table, " + . $foreignTable->getName() . "!"); + } else { + $foreign->addReferrer($currFK); + } + } // for each foreign col ref + } + } + } + + /** + * Creats a string representation of this Database. + * The representation is given in xml format. + */ + public function toString() + { + $result = "getName() . '"' + . " package=\"" . $this->getPackage() . '"' + . " defaultIdMethod=\"" . $this->getDefaultIdMethod() + . '"' + . " baseClass=\"" . $this->getBaseClass() . '"' + . " basePeer=\"" . $this->getBasePeer() . '"' + . ">\n"; + + for ($i=0, $size=count($this->tableList); $i < $size; $i++) { + $result .= $this->tableList[$i]->toString(); + } + + $result .= ""; + + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Domain.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Domain.php new file mode 100644 index 000000000..4680d4f00 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Domain.php @@ -0,0 +1,313 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; + +/** + * A Class for holding data about a column used in an Application. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Domain extends XMLElement { + + private $name; + private $description; + private $size; + private $scale; + + /** type as defined in schema.xml */ + private $propelType; + private $sqlType; + private $defaultValue; + + /** Database object -- in the event this Domain is specified in the XML. */ + private $database; + + /** + * Creates a new Domain object. + * If this domain needs a name, it must be specified manually. + * + * @param string $type Propel type. + * @param string $sqlType SQL type. + * @param string $size + * @param string $scale + */ + public function __construct($type = null, $sqlType = null, $size = null, $scale = null) + { + $this->propelType = $type; + $this->sqlType = ($sqlType !== null) ? $sqlType : $type; + $this->size = $size; + $this->scale = $scale; + } + + public function copy(Domain $domain) + { + $this->defaultValue = $domain->getDefaultValue(); + $this->description = $domain->getDescription(); + $this->name = $domain->getName(); + $this->scale = $domain->getScale(); + $this->size = $domain->getSize(); + $this->sqlType = $domain->getSqlType(); + $this->propelType = $domain->getType(); + } + + /** + * Sets up the Domain object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $schemaType = strtoupper($this->getAttribute("type")); + $this->copy($this->getDatabase()->getPlatform()->getDomainForType($schemaType)); + + //Name + $this->name = $this->getAttribute("name"); + + //Default column value. + $this->defaultValue = $this->getAttribute("default"); // may need to adjust -- e.g. for boolean values + + $this->size = $this->getAttribute("size"); + $this->scale = $this->getAttribute("scale"); + $this->description = $this->getAttribute("description"); + } + + /** + * Sets the owning database object (if this domain is being setup via XML). + */ + public function setDatabase(Database $database) { + $this->database = $database; + } + + /** + * Gets the owning database object (if this domain was setup via XML). + */ + public function getDatabase() { + return $this->database; + } + + /** + * @return Returns the description. + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param description The description to set. + */ + public function setDescription($description) + { + $this->description = $description; + } + + /** + * @return Returns the name. + */ + public function getName() + { + return $this->name; + } + + /** + * @param name The name to set. + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return Returns the scale. + */ + public function getScale() + { + return $this->scale; + } + + /** + * @param scale The scale to set. + */ + public function setScale($scale) + { + $this->scale = $scale; + } + + /** + * Replaces the size if the new value is not null. + * + * @param value The size to set. + */ + public function replaceScale($value) + { + if ($value !== null) { + $this->scale = $value; + } + } + + /** + * @return Returns the size. + */ + public function getSize() + { + return $this->size; + } + + /** + * @param size The size to set. + */ + public function setSize($size) + { + $this->size = $size; + } + + /** + * Replaces the size if the new value is not null. + * + * @param value The size to set. + */ + public function replaceSize($value) + { + if ($value !== null) { + $this->size = $value; + } + } + + /** + * @return string Returns the propelType. + */ + public function getType() + { + return $this->propelType; + } + + /** + * @param string $propelType The PropelTypes type to set. + */ + public function setType($propelType) + { + $this->propelType = $propelType; + } + + /** + * Replaces the default value if the new value is not null. + * + * @param value The defaultValue to set. + */ + public function replaceType($value) + { + if ($value !== null) { + $this->propelType = $value; + } + } + + /** + * Gets the "raw" default value, suitable for use in SQL. + * @return string Returns the defaultValue. + */ + public function getDefaultValue() + { + if ($this->defaultValue !== null) { + return $this->defaultValue; + } + } + + /** + * Gets the default value, type-casted for use in PHP OM. + * @return mixed + * @see getDefaultValue() + */ + public function getPhpDefaultValue() + { + if ($this->defaultValue === null) { + return null; + } elseif ($this->propelType === PropelTypes::BOOLEAN) { + // convert "true" => TRUE + return $this->booleanValue($this->defaultValue); + } elseif ($this->propelType === PropelTypes::DATE || $this->propelType === PropelTypes::TIME || $this->propelType === PropelTypes::TIMESTAMP) { + // DATE/TIME vals need to be converted to integer timestamp + $ts = strtotime($this->defaultValue); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new EngineException("Unable to parse default value as date/time value: " . var_export($this->defaultValue, true)); + } + return $ts; + } else { + return $this->defaultValue; + } + } + + /** + * @param defaultValue The defaultValue to set. + */ + public function setDefaultValue($defaultValue) + { + $this->defaultValue = $defaultValue; + } + + /** + * Replaces the default value if the new value is not null. + * + * @param string $value The defaultValue to set. + */ + public function replaceDefaultValue($value) + { + if ($value !== null) { + $this->defaultValue = $value; + } + } + + /** + * @return Returns the sqlType. + */ + public function getSqlType() + { + return $this->sqlType; + } + + /** + * @param string $sqlType The sqlType to set. + */ + public function setSqlType($sqlType) + { + $this->sqlType = $sqlType; + } + + /** + * Return the size and scale in brackets for use in an sql schema. + * + * @return size and scale or an empty String if there are no values + * available. + */ + public function printSize() + { + if ($this->size !== null && $this->scale !== null) { + return '(' . $this->size . ',' . $this->scale . ')'; + } elseif ($this->size !== null) { + return '(' . $this->size . ')'; + } else { + return ""; + } + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ForeignKey.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ForeignKey.php new file mode 100644 index 000000000..84a0e15c7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/ForeignKey.php @@ -0,0 +1,278 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; + +/** + * A Class for information about foreign keys of a table. + * + * @author Hans Lellelid + * @author Fedor + * @author Daniel Rall + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class ForeignKey extends XMLElement { + + private $foreignTableName; + private $name; + private $onUpdate; + private $onDelete; + private $parentTable; + private $localColumns = array(); + private $foreignColumns = array(); + + // the uppercase equivalent of the onDelete/onUpdate values in the dtd + const NONE = ""; // No "ON [ DELETE | UPDATE]" behaviour specified. + const NOACTION = "NO ACTION"; + const CASCADE = "CASCADE"; + const RESTRICT = "RESTRICT"; + const SETDEFAULT = "SET DEFAULT"; + const SETNULL = "SET NULL"; + + /** + * Sets up the ForeignKey object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->foreignTableName = $this->getAttribute("foreignTable"); + $this->name = $this->getAttribute("name"); + $this->onUpdate = $this->normalizeFKey($this->getAttribute("onUpdate")); + $this->onDelete = $this->normalizeFKey($this->getAttribute("onDelete")); + } + + /** + * normalizes the input of onDelete, onUpdate attributes + */ + private function normalizeFKey($attrib) + { + if ($attrib === null || strtoupper($attrib) == "NONE") { + $attrib = self::NONE; + } + $attrib = strtoupper($attrib); + if ($attrib == "SETNULL") { + $attrib = self::SETNULL; + } + return $attrib; + } + + /** + * returns whether or not the onUpdate attribute is set + */ + public function hasOnUpdate() + { + return ($this->onUpdate !== self::NONE); + } + + /** + * returns whether or not the onDelete attribute is set + */ + public function hasOnDelete() + { + return ($this->onDelete !== self::NONE); + } + + /** + * returns the onUpdate attribute + */ + public function getOnUpdate() + { + return $this->onUpdate; + } + + /** + * returns the onDelete attribute + */ + public function getOnDelete() + { + return $this->onDelete; + } + + /** + * sets the onDelete attribute + */ + public function setOnDelete($value) + { + $this->onDelete = $this->normalizeFKey($value); + } + + /** + * sets the onUpdate attribute + */ + public function setOnUpdate($value) + { + $this->onUpdate = $this->normalizeFKey($value); + } + + /** + * Returns the name attribute. + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the name attribute. + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Get the foreignTableName of the FK + */ + public function getForeignTableName() + { + return $this->foreignTableName; + } + + /** + * Set the foreignTableName of the FK + */ + public function setForeignTableName($tableName) + { + $this->foreignTableName = $tableName; + } + + /** + * Set the parent Table of the foreign key + */ + public function setTable(Table $parent) + { + $this->parentTable = $parent; + } + + /** + * Get the parent Table of the foreign key + */ + public function getTable() + { + return $this->parentTable; + } + + /** + * Returns the Name of the table the foreign key is in + */ + public function getTableName() + { + return $this->parentTable->getName(); + } + + /** + * adds a new reference entry to the foreign key + */ + public function addReference($p1, $p2 = null) + { + if (is_array($p1)) { + $this->addReference(@$p1["local"], @$p1["foreign"]); + } else { + $this->localColumns[] = $p1; + $this->foreignColumns[] = $p2; + } + } + + /** + * Return a comma delimited string of local column names + * @deprecated because Column::makeList() is deprecated; use the array-returning getLocalColumns() and DDLBuilder->getColumnList() instead instead. + */ + public function getLocalColumnNames() + { + return Column::makeList($this->getLocalColumns(), $this->getTable()->getDatabase()->getPlatform()); + } + + /** + * Return a comma delimited string of foreign column names + * @deprecated because Column::makeList() is deprecated; use the array-returning getForeignColumns() and DDLBuilder->getColumnList() instead instead. + */ + public function getForeignColumnNames() + { + return Column::makeList($this->getForeignColumns(), $this->getTable()->getDatabase()->getPlatform()); + } + + /** + * Return an array of local column names. + * @return array string[] + */ + public function getLocalColumns() + { + return $this->localColumns; + } + + /** + * Utility method to get local column to foreign column + * mapping for this foreign key. + */ + public function getLocalForeignMapping() + { + $h = array(); + for ($i=0, $size=count($this->localColumns); $i < $size; $i++) { + $h[$this->localColumns[$i]] = $this->foreignColumns[$i]; + } + return $h; + } + + /** + * Return an array of foreign column names. + * @return array string[] + */ + public function getForeignColumns() + { + return $this->foreignColumns; + } + + /** + * Utility method to get local column to foreign column + * mapping for this foreign key. + */ + public function getForeignLocalMapping() + { + $h = array(); + for ($i=0, $size=count($this->localColumns); $i < $size; $i++) { + $h[ $this->foreignColumns[$i] ] = $this->localColumns[$i]; + } + return $h; + } + + /** + * String representation of the foreign key. This is an xml representation. + */ + public function toString() + { + $result = " getForeignTableName() + . "\" name=\"" + . $this->getName() + . "\">\n"; + + for ($i=0, $size=count($this->localColumns); $i < $size; $i++) { + $result .= " localColumns[$i] + . "\" foreign=\"" + . $this->foreignColumns[$i] + . "\"/>\n"; + } + $result .= " \n"; + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IDMethod.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IDMethod.php new file mode 100644 index 000000000..98d0c2cac --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IDMethod.php @@ -0,0 +1,46 @@ +. + */ + +/** + * Interface for various ID retrieval method types + * (i.e. auto-increment, sequence, ID broker, etc.). + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +interface IDMethod { + + /** + * Key generation via database-specific ID method + * (i.e. auto-increment for MySQL, sequence for Oracle, etc.). + */ + const NATIVE = "native"; + + /** + * No RDBMS key generation (keys may be generated by the + * application). + */ + const NO_ID_METHOD = "none"; + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php new file mode 100644 index 000000000..33cab3fc5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php @@ -0,0 +1,125 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; + +/** + * Information related to an ID method. + * + * @author Hans Lellelid (Propel) + * @author John McNally (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class IdMethodParameter extends XMLElement { + + private $name; + private $value; + private $parentTable; + + /** + * Sets up the IdMethodParameter object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->name = $this->getAttribute("name"); + $this->value = $this->getAttribute("value"); + } + + /** + * Get the parameter name + */ + public function getName() + { + return $this->name; + } + + /** + * Set the parameter name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Get the parameter value + */ + public function getValue() + { + return $this->value; + } + + /** + * Set the parameter value + */ + public function setValue($value) + { + $this->value = $value; + } + + /** + * Set the parent Table of the id method + */ + public function setTable(Table $parent) + { + $this->parentTable = $parent; + } + + /** + * Get the parent Table of the id method + */ + public function getTable() + { + return $this->parentTable; + } + + /** + * Returns the Name of the table the id method is in + */ + public function getTableName() + { + return $this->parentTable->getName(); + } + + /** + * XML representation of the foreign key. + */ + public function toString() + { + $result = " getName() !== null) { + $result .= " name=\"" + . $this->getName() + . '"'; + } + + $result .= " value=\"" + . $this->getValue() + . "\">\n"; + + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Index.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Index.php new file mode 100644 index 000000000..9e6332271 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Index.php @@ -0,0 +1,276 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; +include_once 'propel/engine/EngineException.php'; + +/** + * Information about indices of a table. + * + * @author Jason van Zyl + * @author Daniel Rall + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Index extends XMLElement { + + /** enables debug output */ + const DEBUG = false; + + private $indexName; + private $parentTable; + + /** @var array string[] */ + private $indexColumns; + + /** @var array */ + private $indexColumnSizes = array(); + + /** + * Creates a new instance with default characteristics (no name or + * parent table, small column list size allocation, non-unique). + * + * @param Table $table + * @param array $indexColumns + */ + public function __construct(Table $table, $indexColumns = array()) + { + $this->indexColumns = $indexColumns; + $this->setTable($table); + if (!empty($indexColumns)) { + + $this->createName(); + + if (self::DEBUG) { + print("Created Index named " . $this->getName() + . " with " . count($indexColumns) . " columns\n"); + } + } + } + + private function createName() + { + $table = $this->getTable(); + $inputs = array(); + $inputs[] = $table->getDatabase(); + $inputs[] = $table->getName(); + if ($this->isUnique()) { + $inputs[] = "U"; + } else { + $inputs[] = "I"; + } + // ASSUMPTION: This Index not yet added to the list. + if ($this->isUnique()) { + $inputs[] = count($table->getUnices()) + 1; + } else { + $inputs[] = count($table->getIndices()) + 1; + } + + $this->indexName = NameFactory::generateName( + NameFactory::CONSTRAINT_GENERATOR, $inputs); + } + + /** + * Sets up the Index object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->indexName = $this->getAttribute("name"); + } + + /** + * @see #isUnique() + * @deprecated Use isUnique() instead. + */ + public function getIsUnique() + { + return $this->isUnique(); + } + + /** + * Returns the uniqueness of this index. + */ + public function isUnique() + { + return false; + } + + /** + * @see #getName() + * @deprecated Use getName() instead. + */ + public function getIndexName() + { + return $this->getName(); + } + + /** + * Gets the name of this index. + */ + public function getName() + { + if ($this->indexName === null) { + try { + // generate an index name if we don't have a supplied one + $this->createName(); + } catch (EngineException $e) { + // still no name + } + } + return $this->indexName; + } + + /** + * @see #setName(String name) + * @deprecated Use setName(String name) instead. + */ + public function setIndexName($name) + { + $this->setName($name); + } + + /** + * Set the name of this index. + */ + public function setName($name) + { + $this->indexName = $name; + } + + /** + * Set the parent Table of the index + */ + public function setTable(Table $parent) + { + $this->parentTable = $parent; + } + + /** + * Get the parent Table of the index + */ + public function getTable() + { + return $this->parentTable; + } + + /** + * Returns the Name of the table the index is in + */ + public function getTableName() + { + return $this->parentTable->getName(); + } + + /** + * Adds a new column to an index. + * @param array $attrib The attribute array from XML parser. + */ + public function addColumn($attrib) + { + $name = $attrib["name"]; + $this->indexColumns[] = $name; + if (isset($attrib["size"])) { + $this->indexColumnSizes[$name] = $attrib["size"]; + } + } + + /** + * Whether there is a size for the specified column. + * @param string $name + * @return boolean + */ + public function hasColumnSize($name) + { + return isset($this->indexColumnSizes[$name]); + } + + /** + * Returns the size for the specified column, if given. + * @param string $name + * @return numeric The size or NULL + */ + public function getColumnSize($name) + { + if (isset($this->indexColumnSizes[$name])) { + return $this->indexColumnSizes[$name]; + } + return null; // just to be explicit + } + + /** + * @see #getColumnList() + * @deprecated Use getColumnList() instead (which is not deprecated too!) + */ + public function getIndexColumnList() + { + return $this->getColumnList(); + } + + /** + * Return a comma delimited string of the columns which compose this index. + * @deprecated because Column::makeList() is deprecated; use the array-returning getColumns() and DDLBuilder->getColumnList() instead instead. + */ + public function getColumnList() + { + return Column::makeList($this->getColumns(), $this->getTable()->getDatabase()->getPlatform()); + } + + /** + * @see #getColumns() + * @deprecated Use getColumns() instead. + */ + public function getIndexColumns() + { + return $this->getColumns(); + } + + /** + * Return the list of local columns. You should not edit this list. + * @return array string[] + */ + public function getColumns() + { + return $this->indexColumns; + } + + /** + * String representation of the index. This is an xml representation. + */ + public function toString() + { + + $result = " getName() + .'"'; + + $result .= ">\n"; + + for ($i=0, $size=count($this->indexColumns); $i < $size; $i++) { + $result .= " indexColumns[$i] + . "\"/>\n"; + } + $result .= " \n"; + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Inheritance.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Inheritance.php new file mode 100644 index 000000000..400a99870 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Inheritance.php @@ -0,0 +1,164 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; + +/** + * A Class for information regarding possible objects representing a table + * + * @author Hans Lellelid (Propel) + * @author John McNally (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Inheritance extends XMLElement { + + private $key; + private $className; + private $pkg; + private $ancestor; + private $parent; + + /** + * Sets up the Inheritance object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->key = $this->getAttribute("key"); + $this->className = $this->getAttribute("class"); + $this->pkg = $this->getAttribute("package"); + $this->ancestor = $this->getAttribute("extends"); + } + + /** + * Get the value of key. + * @return value of key. + */ + public function getKey() + { + return $this->key; + } + + /** + * Set the value of key. + * @param v Value to assign to key. + */ + public function setKey($v) + { + $this->key = $v; + } + + /** + * Get the value of parent. + * @return value of parent. + */ + public function getColumn() + { + return $this->parent; + } + + /** + * Set the value of parent. + * @param v Value to assign to parent. + */ + public function setColumn(Column $v) + { + $this->parent = $v; + } + + /** + * Get the value of className. + * @return value of className. + */ + public function getClassName() + { + return $this->className; + } + + /** + * Set the value of className. + * @param v Value to assign to className. + */ + public function setClassName($v) + { + $this->className = $v; + } + + /** + * Get the value of package. + * @return value of package. + */ + public function getPackage() + { + return $this->pkg; + } + + /** + * Set the value of package. + * @param v Value to assign to package. + */ + public function setPackage($v) + { + $this->pkg = $v; + } + + /** + * Get the value of ancestor. + * @return value of ancestor. + */ + public function getAncestor() + { + return $this->ancestor; + } + + /** + * Set the value of ancestor. + * @param v Value to assign to ancestor. + */ + public function setAncestor($v) + { + $this->ancestor = $v; + } + + /** + * String representation of the foreign key. This is an xml representation. + */ + public function toString() + { + $result = " key + . "\" class=\"" + . $this->className + . '"'; + + if ($this->ancestor !== null) { + $result .= " extends=\"" + . $this->ancestor + . '"'; + } + + $result .= "/>"; + + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameFactory.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameFactory.php new file mode 100644 index 000000000..adea24379 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameFactory.php @@ -0,0 +1,116 @@ +. + */ + +include_once 'propel/engine/EngineException.php'; +include_once 'propel/engine/database/model/NameGenerator.php'; + +/** + * A name generation factory. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class NameFactory { + + /** + * The class name of the PHP name generator. + */ + const PHP_GENERATOR = 'PhpNameGenerator'; + + /** + * The fully qualified class name of the constraint name generator. + */ + const CONSTRAINT_GENERATOR = 'ConstraintNameGenerator'; + + /** + * The single instance of this class. + */ + private static $instance; + + /** + * The cache of NameGenerator algorithms in use for + * name generation, keyed by fully qualified class name. + */ + private $algorithms; + + /** + * Creates a new instance with storage for algorithm implementations. + */ + protected function __construct() + { + $this->algorithms = array(); + } + + private static function instance() + { + if (self::$instance === null) { + self::$instance = new NameFactory(); + } + return self::$instance; + } + + /** + * Factory method which retrieves an instance of the named generator. + * + * @param name The fully qualified class name of the name + * generation algorithm to retrieve. + */ + protected function getAlgorithm($name) + { + $algorithm = isset($this->algorithms[$name]) ? $this->algorithms[$name] : null; + if ($algorithm === null) { + try { + include_once 'propel/engine/database/model/' . $name . '.php'; + if (!class_exists($name)) { + throw new Exception("Unable to instantiate class " . $name + . ": Make sure it's in your include_path"); + } + $algorithm = new $name(); + } catch (BuildException $e) { + print $e->getMessage() . "\n"; + print $e->getTraceAsString(); + } + $this->algorithms[$name] = $algorithm; + } + return $algorithm; + + } + + /** + * Given a list of String objects, implements an + * algorithm which produces a name. + * + * @param algorithmName The fully qualified class name of the + * {@link NameGenerator} + * implementation to use to generate names. + * @param array $inputs Inputs used to generate a name. + * @return The generated name. + * @throws EngineException + */ + public static function generateName($algorithmName, $inputs) + { + $algorithm = self::instance()->getAlgorithm($algorithmName); + return $algorithm->generateName($inputs); + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameGenerator.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameGenerator.php new file mode 100644 index 000000000..a8ebcb2dc --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/NameGenerator.php @@ -0,0 +1,72 @@ +. + */ + +/** + * The generic interface to a name generation algorithm. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @author Byron Foster (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +interface NameGenerator { + /** + * The character used by most implementations as the separator + * between name elements. + */ + const STD_SEPARATOR_CHAR = '_'; + + /** + * Traditional method for converting schema table and column names + * to PHP names. The CONV_METHOD_XXX constants + * define how names for columns and tables in the database schema + * will be converted to PHP source names. + * + * @see PhpNameGenerator::underscoreMethod() + */ + const CONV_METHOD_UNDERSCORE = "underscore"; + + /** + * Similar to {@link #CONV_METHOD_UNDERSCORE} except nothing is + * converted to lowercase. + * + * @see PhpNameGenerator::phpnameMethod() + */ + const CONV_METHOD_PHPNAME = "phpname"; + + /** + * Specifies no modification when converting from a schema column + * or table name to a PHP name. + */ + const CONV_METHOD_NOCHANGE = "nochange"; + + /** + * Given a list of String objects, implements an + * algorithm which produces a name. + * + * @param inputs Inputs used to generate a name. + * @return The generated name. + * @throws EngineException + */ + public function generateName($inputs); +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php new file mode 100644 index 000000000..a45595e6e --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php @@ -0,0 +1,131 @@ +. + */ + +include_once 'propel/engine/database/model/NameGenerator.php'; + +/** + * A NameGenerator implementation for PHP-esque names. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @author Byron Foster (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class PhpNameGenerator implements NameGenerator { + + /** + * inputs should consist of two elements, the + * original name of the database element and the method for + * generating the name. There are currently three methods: + * CONV_METHOD_NOCHANGE - xml names are converted + * directly to php names without modification. + * CONV_METHOD_UNDERSCORE will capitalize the first + * letter, remove underscores, and capitalize each letter before + * an underscore. All other letters are lowercased. "phpname" + * works the same as the CONV_METHOD_PHPNAME method + * but will not lowercase any characters. + * + * @param inputs list expected to contain two parameters, element + * 0 contains name to convert, element 1 contains method for conversion. + * @return The generated name. + * @see NameGenerator + */ + public function generateName($inputs) + { + $schemaName = $inputs[0]; + $method = $inputs[1]; + $phpName = null; + + if ($method == self::CONV_METHOD_UNDERSCORE) { + $phpName = $this->underscoreMethod($schemaName); + } elseif ($method == self::CONV_METHOD_PHPNAME) { + $phpName = $this->phpnameMethod($schemaName); + } else if ($method == self::CONV_METHOD_NOCHANGE) { + $phpName = $this->nochangeMethod($schemaName); + } else { + // if for some reason nothing is defined then we default + // to the traditional method. + $phpName = $this->underscoreMethod($schemaName); + } + + return $phpName; + } + + /** + * Converts a database schema name to php object name. Removes + * STD_SEPARATOR_CHAR, capitilizes first letter of + * name and each letter after the STD_SEPERATOR, + * converts the rest of the letters to lowercase. + * + * my_CLASS_name -> MyClassName + * + * @param string $schemaName name to be converted. + * @return string Converted name. + * @see NameGenerator + * @see #underscoreMethod() + */ + protected function underscoreMethod($schemaName) + { + $name = ""; + $tok = strtok($schemaName, self::STD_SEPARATOR_CHAR); + while($tok) { + $name .= ucfirst(strtolower($tok)); + $tok = strtok(self::STD_SEPARATOR_CHAR); + } + return $name; + } + + /** + * Converts a database schema name to php object name. Operates + * same as underscoreMethod but does not convert anything to + * lowercase. + * + * my_CLASS_name -> MyCLASSName + * + * @param string $schemaName name to be converted. + * @return string Converted name. + * @see NameGenerator + * @see #underscoreMethod(String) + */ + protected function phpnameMethod($schemaName) + { + $name = ""; + $tok = strtok($schemaName, self::STD_SEPARATOR_CHAR); + while($tok) { + $name .= ucfirst($tok); + $tok = strtok(self::STD_SEPARATOR_CHAR); + } + return $name; + } + + /** + * Converts a database schema name to PHP object name. In this + * case no conversion is made. + * + * @param string $name name to be converted. + * @return string The name parameter, unchanged. + */ + protected function nochangeMethod($name) + { + return $name; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PropelTypes.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PropelTypes.php new file mode 100644 index 000000000..a1e97927e --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/PropelTypes.php @@ -0,0 +1,290 @@ +. + */ + +require_once 'creole/CreoleTypes.php'; + +/** + * A class that maps PropelTypes to CreoleTypes and to native PHP types. + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class PropelTypes { + + const CHAR = "CHAR"; + const VARCHAR = "VARCHAR"; + const LONGVARCHAR = "LONGVARCHAR"; + const CLOB = "CLOB"; + const NUMERIC = "NUMERIC"; + const DECIMAL = "DECIMAL"; + const TINYINT = "TINYINT"; + const SMALLINT = "SMALLINT"; + const INTEGER = "INTEGER"; + const BIGINT = "BIGINT"; + const REAL = "REAL"; + const FLOAT = "FLOAT"; + const DOUBLE = "DOUBLE"; + const BINARY = "BINARY"; + const VARBINARY = "VARBINARY"; + const LONGVARBINARY = "LONGVARBINARY"; + const BLOB = "BLOB"; + const DATE = "DATE"; + const TIME = "TIME"; + const TIMESTAMP = "TIMESTAMP"; + + const BU_DATE = "BU_DATE"; + const BU_TIMESTAMP = "BU_TIMESTAMP"; + + const BOOLEAN = "BOOLEAN"; + + private static $TEXT_TYPES = null; + + private static $LOB_TYPES = null; + + const CHAR_NATIVE_TYPE = "string"; + const VARCHAR_NATIVE_TYPE = "string"; + const LONGVARCHAR_NATIVE_TYPE = "string"; + const CLOB_NATIVE_TYPE = "string"; // Clob + const NUMERIC_NATIVE_TYPE = "double"; + const DECIMAL_NATIVE_TYPE = "double"; + const BOOLEAN_NATIVE_TYPE = "boolean"; + const TINYINT_NATIVE_TYPE = "int"; + const SMALLINT_NATIVE_TYPE = "int"; + const INTEGER_NATIVE_TYPE = "int"; + const BIGINT_NATIVE_TYPE = "string"; + const REAL_NATIVE_TYPE = "double"; + const FLOAT_NATIVE_TYPE = "double"; + const DOUBLE_NATIVE_TYPE = "double"; + const BINARY_NATIVE_TYPE = "string"; + const VARBINARY_NATIVE_TYPE = "string"; + const LONGVARBINARY_NATIVE_TYPE = "string"; + const BLOB_NATIVE_TYPE = "string"; + const BU_DATE_NATIVE_TYPE = "string"; + const DATE_NATIVE_TYPE = "int"; + const TIME_NATIVE_TYPE = "int"; + const TIMESTAMP_NATIVE_TYPE = "int"; + const BU_TIMESTAMP_NATIVE_TYPE = "string"; + + private static $propelToPHPNativeMap = null; + private static $propelTypeToCreoleTypeMap = null; + private static $creoleToPropelTypeMap = null; + + private static $isInitialized = false; + + /** + * Initializes the SQL to PHP map so that it + * can be used by client code. + */ + public static function initialize() + { + if (self::$isInitialized === false) { + + self::$TEXT_TYPES = array ( + self::CHAR, self::VARCHAR, self::LONGVARCHAR, self::CLOB, self::DATE, self::TIME, self::TIMESTAMP, self::BU_DATE, self::BU_TIMESTAMP + ); + + self::$LOB_TYPES = array ( + self::VARBINARY, self::LONGVARBINARY, self::CLOB, self::BLOB + ); + + /* + * Create Creole -> native PHP type mappings. + */ + + self::$propelToPHPNativeMap = array(); + + self::$propelToPHPNativeMap[self::CHAR] = self::CHAR_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::VARCHAR] = self::VARCHAR_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::LONGVARCHAR] = self::LONGVARCHAR_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::CLOB] = self::CLOB_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::NUMERIC] = self::NUMERIC_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::DECIMAL] = self::DECIMAL_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::TINYINT] = self::TINYINT_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::SMALLINT] = self::SMALLINT_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::INTEGER] = self::INTEGER_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BIGINT] = self::BIGINT_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::REAL] = self::REAL_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::FLOAT] = self::FLOAT_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::DOUBLE] = self::DOUBLE_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BINARY] = self::BINARY_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::VARBINARY] = self::VARBINARY_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::LONGVARBINARY] = self::LONGVARBINARY_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BLOB] = self::BLOB_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::DATE] = self::DATE_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BU_DATE] = self::BU_DATE_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::TIME] = self::TIME_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::TIMESTAMP] = self::TIMESTAMP_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BU_TIMESTAMP] = self::BU_TIMESTAMP_NATIVE_TYPE; + self::$propelToPHPNativeMap[self::BOOLEAN] = self::BOOLEAN_NATIVE_TYPE; + + /* + * Create Propel -> Creole _name_ mappings (not CreoleType:: mappings). + * (this is now pretty useless since we've designed them to be the same!) + */ + self::$propelTypeToCreoleTypeMap = array(); + self::$propelTypeToCreoleTypeMap[self::CHAR] = self::CHAR; + self::$propelTypeToCreoleTypeMap[self::VARCHAR] = self::VARCHAR; + self::$propelTypeToCreoleTypeMap[self::LONGVARCHAR] = self::LONGVARCHAR; + self::$propelTypeToCreoleTypeMap[self::CLOB] = self::CLOB; + self::$propelTypeToCreoleTypeMap[self::NUMERIC] = self::NUMERIC; + self::$propelTypeToCreoleTypeMap[self::DECIMAL] = self::DECIMAL; + self::$propelTypeToCreoleTypeMap[self::TINYINT] = self::TINYINT; + self::$propelTypeToCreoleTypeMap[self::SMALLINT] = self::SMALLINT; + self::$propelTypeToCreoleTypeMap[self::INTEGER] = self::INTEGER; + self::$propelTypeToCreoleTypeMap[self::BIGINT] = self::BIGINT; + self::$propelTypeToCreoleTypeMap[self::REAL] = self::REAL; + self::$propelTypeToCreoleTypeMap[self::FLOAT] = self::FLOAT; + self::$propelTypeToCreoleTypeMap[self::DOUBLE] = self::DOUBLE; + self::$propelTypeToCreoleTypeMap[self::BINARY] = self::BINARY; + self::$propelTypeToCreoleTypeMap[self::VARBINARY] = self::VARBINARY; + self::$propelTypeToCreoleTypeMap[self::LONGVARBINARY] = self::LONGVARBINARY; + self::$propelTypeToCreoleTypeMap[self::BLOB] = self::BLOB; + self::$propelTypeToCreoleTypeMap[self::DATE] = self::DATE; + self::$propelTypeToCreoleTypeMap[self::TIME] = self::TIME; + self::$propelTypeToCreoleTypeMap[self::TIMESTAMP] = self::TIMESTAMP; + self::$propelTypeToCreoleTypeMap[self::BOOLEAN] = self::BOOLEAN; + + // These are pre-epoch dates, which we need to map to String type + // since they cannot be properly handled using strtotime() -- or even numeric + // timestamps on Windows. + self::$propelTypeToCreoleTypeMap[self::BU_DATE] = self::VARCHAR; + self::$propelTypeToCreoleTypeMap[self::BU_TIMESTAMP] = self::VARCHAR; + + + /* + * Create Creole type code to Propel type map. + */ + self::$creoleToPropelTypeMap = array(); + + self::$creoleToPropelTypeMap[CreoleTypes::CHAR] = self::CHAR; + self::$creoleToPropelTypeMap[CreoleTypes::VARCHAR] = self::VARCHAR; + self::$creoleToPropelTypeMap[CreoleTypes::LONGVARCHAR] = self::LONGVARCHAR; + self::$creoleToPropelTypeMap[CreoleTypes::CLOB] = self::CLOB; + self::$creoleToPropelTypeMap[CreoleTypes::NUMERIC] = self::NUMERIC; + self::$creoleToPropelTypeMap[CreoleTypes::DECIMAL] = self::DECIMAL; + self::$creoleToPropelTypeMap[CreoleTypes::TINYINT] = self::TINYINT; + self::$creoleToPropelTypeMap[CreoleTypes::SMALLINT] = self::SMALLINT; + self::$creoleToPropelTypeMap[CreoleTypes::INTEGER] = self::INTEGER; + self::$creoleToPropelTypeMap[CreoleTypes::BIGINT] = self::BIGINT; + self::$creoleToPropelTypeMap[CreoleTypes::REAL] = self::REAL; + self::$creoleToPropelTypeMap[CreoleTypes::FLOAT] = self::FLOAT; + self::$creoleToPropelTypeMap[CreoleTypes::DOUBLE] = self::DOUBLE; + self::$creoleToPropelTypeMap[CreoleTypes::BINARY] = self::BINARY; + self::$creoleToPropelTypeMap[CreoleTypes::VARBINARY] = self::VARBINARY; + self::$creoleToPropelTypeMap[CreoleTypes::LONGVARBINARY] = self::LONGVARBINARY; + self::$creoleToPropelTypeMap[CreoleTypes::BLOB] = self::BLOB; + self::$creoleToPropelTypeMap[CreoleTypes::DATE] = self::DATE; + self::$creoleToPropelTypeMap[CreoleTypes::TIME] = self::TIME; + self::$creoleToPropelTypeMap[CreoleTypes::TIMESTAMP] = self::TIMESTAMP; + self::$creoleToPropelTypeMap[CreoleTypes::BOOLEAN] = self::BOOLEAN; + self::$creoleToPropelTypeMap[CreoleTypes::YEAR] = self::INTEGER; + + self::$isInitialized = true; + } + } + + /** + * Report whether this object has been initialized. + * + * @return true if this object has been initialized + */ + public static function isInitialized() + { + return self::$isInitialized; + } + + /** + * Return native PHP type which corresponds to the + * Creole type provided. Use in the base object class generation. + * + * @param $propelType The Propel type name. + * @return string Name of the native PHP type + */ + public static function getPhpNative($propelType) + { + return self::$propelToPHPNativeMap[$propelType]; + } + + /** + * Returns the correct Creole type _name_ for propel added types + * + * @param $type the propel added type. + * @return string Name of the the correct Creole type (e.g. "VARCHAR"). + */ + public static function getCreoleType($type) + { + return self::$propelTypeToCreoleTypeMap[$type]; + } + + /** + * Returns Propel type constant corresponding to Creole type code. + * Used but Propel Creole task. + * + * @param int $sqlType The Creole SQL type constant. + * @return string The Propel type to use or NULL if none found. + */ + public static function getPropelType($sqlType) + { + if (isset(self::$creoleToPropelTypeMap[$sqlType])) { + return self::$creoleToPropelTypeMap[$sqlType]; + } + } + + /** + * Get array of Propel types. + * + * @return array string[] + */ + public static function getPropelTypes() + { + return array_keys(self::$propelTypeToCreoleTypeMap); + } + + /** + * Returns true if values for the type need to be quoted. + * + * @param string $type The Propel type to check. + * @return true if values for the type need to be quoted. + */ + public static function isTextType($type) + { + // Make sure the we are initialized. + if (self::$isInitialized === false) { + self::initialize(); + } + return in_array($type, self::$TEXT_TYPES); + } + + /** + * Returns true if type is a LOB type (i.e. would be handled by Blob/Clob class). + * @param string $type Propel type to check. + * @return boolean + */ + public static function isLobType($type) + { + return in_array($type, self::$LOB_TYPES); + } +} + +// static +PropelTypes::initialize(); diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Rule.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Rule.php new file mode 100644 index 000000000..a4a70be69 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Rule.php @@ -0,0 +1,203 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; + +/** + * Data about a validation rule used in an application. + * + * @author Michael Aichler (Propel) + * @author John McNally (Intake) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Rule extends XMLElement { + + private $name; + private $value; + private $message; + private $validator; + private $classname; + + /** + * Sets up the Rule object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->name = $this->getAttribute("name"); + $this->value = $this->getAttribute("value"); + $this->classname = $this->getAttribute("class"); + + /* + * Set some default values if they are not specified. + * This is escpecially useful for maxLength; the size + * is already known by the column and this way it is + * not necessary to manage the same size two times. + * + * Currently there is only one such supported default: + * - maxLength value = column max length + * (this default cannot be easily set at runtime w/o changing + * design of class system in undesired ways) + */ + if ($this->value === null) { + switch($this->name) { + case 'maxLength': + $this->value = $this->validator->getColumn()->getSize(); + break; + } + } + + $this->message = $this->getAttribute("message"); + } + + /** + * Sets the owning validator for this rule. + * @param Validator $validator + * @see Validator::addRule() + */ + public function setValidator(Validator $validator) + { + $this->validator = $validator; + } + + /** + * Gets the owning validator for this rule. + * @return Validator + */ + public function getValidator() + { + return $this->validator; + } + + /** + * Sets the dot-path name of class to use for rule. + * If no class is specified in XML, then a classname will + * be built based on the 'name' attrib. + * @param string $classname dot-path classname (e.g. myapp.propel.MyValidator) + */ + public function setClass($classname) + { + $this->classname = $classname; + } + + /** + * Gets the dot-path name of class to use for rule. + * If no class was specified, this method will build a default classname + * based on the 'name' attribute. E.g. 'maxLength' -> 'propel.validator.MaxLengthValidator' + * @return string dot-path classname (e.g. myapp.propel.MyValidator) + */ + public function getClass() + { + if ($this->classname === null && $this->name !== null) { + return "propel.validator." . ucfirst($this->name) . "Validator"; + } + return $this->classname; + } + + /** + * Sets the name of the validator for this rule. + * This name is used to build the classname if none was specified. + * @param string $name Validator name for this rule (e.g. "maxLength", "required"). + * @see getClass() + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Gets the name of the validator for this rule. + * @return string Validator name for this rule (e.g. "maxLength", "required"). + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the value parameter for this validator rule. + * Note: not all validators need a value parameter (e.g. 'required' validator + * does not). + * @param string $value + */ + public function setValue($value) + { + $this->value = $value; + } + + /** + * Gets the value parameter for this validator rule. + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Sets the message that will be displayed to the user if validation fails. + * This message may be a Gettext msgid (if translation="gettext") or some other + * id for an alternative not-yet-supported translation system. It may also + * be a simple, single-language string. + * @param string $message + * @see setTranslation() + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * Gets the message that will be displayed to the user if validation fails. + * This message may be a Gettext msgid (if translation="gettext") or some other + * id for an alternative not-yet-supported translation system. It may also + * be a simple, single-language string. + * @return string + * @see setTranslation() + */ + public function getMessage() + { + $message = str_replace('${value}', $this->getValue(), $this->message); + return $message; + } + + /** + * Create XML (string) representation of this object. + * @return string + */ + public function toString() + { + $result = "getName() . "\" "; + + if ($this->getValue() !== null) { + $result .= "value=\"" . $this->getValue(). "\" "; + } + if ($this->getClass() !== null) { + $result .= "class=\"".$this->getClass()."\" "; + } + $result .= "message=\"" . $this->getMessage() . "\" "; + $result .= "/>\n"; + + return $result; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Table.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Table.php new file mode 100644 index 000000000..8bb16ffa7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Table.php @@ -0,0 +1,1154 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; +include_once 'propel/engine/EngineException.php'; +include_once 'propel/engine/database/model/IDMethod.php'; +include_once 'propel/engine/database/model/NameFactory.php'; +include_once 'propel/engine/database/model/Column.php'; +include_once 'propel/engine/database/model/Unique.php'; +include_once 'propel/engine/database/model/ForeignKey.php'; +include_once 'propel/engine/database/model/IdMethodParameter.php'; +include_once 'propel/engine/database/model/Validator.php'; + +/** + * Data about a table used in an application. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author Jason van Zyl (Torque) + * @author Martin Poeschl (Torque) + * @author John McNally (Torque) + * @author Daniel Rall (Torque) + * @author Byron Foster (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Table extends XMLElement implements IDMethod { + + /** enables debug output */ + const DEBUG = false; + + //private attributes; + private $columnList; + private $validatorList; + private $foreignKeys; + private $indices; + private $unices; + private $idMethodParameters; + private $name; + private $description; + private $phpName; + private $idMethod; + private $phpNamingMethod; + private $tableParent; + private $referrers = array(); + private $foreignTableNames; + private $containsForeignPK; + private $inheritanceColumn; + private $skipSql; + private $readOnly; + private $abstractValue; + private $alias; + private $enterface; + private $pkg; + private $baseClass; + private $basePeer; + private $columnsByName; + private $columnsByPhpName; + private $needsTransactionInPostgres;//maybe this can be retrieved from vendorSpecificInfo? + private $heavyIndexing; + private $forReferenceOnly; + private $isTree; + + /** + * Constructs a table object with a name + * + * @param string $name table name + */ + public function __construct($name = null) + { + $this->name = $name; + $this->columnList = array(); + $this->validatorList = array(); + $this->foreignKeys = array(); + $this->indices = array(); + $this->unices = array(); + $this->columnsByName = array(); + $this->columnsByPhpName = array(); + $this->vendorSpecificInfo = array(); + } + + /** + * Sets up the Rule object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + public function setupObject() + { + $this->name = $this->getAttribute("name"); + $this->phpName = $this->getAttribute("phpName"); + $this->idMethod = $this->getAttribute("idMethod", $this->getDatabase()->getDefaultIdMethod()); + + // retrieves the method for converting from specified name to a PHP name. + $this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->getDatabase()->getDefaultPhpNamingMethod()); + + $this->skipSql = $this->booleanValue($this->getAttribute("skipSql")); + $this->readOnly = $this->booleanValue($this->getAttribute("readOnly")); + + $this->pkg = $this->getAttribute("package"); + $this->abstractValue = $this->booleanValue($this->getAttribute("abstract")); + $this->baseClass = $this->getAttribute("baseClass"); + $this->basePeer = $this->getAttribute("basePeer"); + $this->alias = $this->getAttribute("alias"); + + $this->heavyIndexing = ( $this->booleanValue($this->getAttribute("heavyIndexing")) + || ("false" !== $this->getAttribute("heavyIndexing") + && $this->getDatabase()->isHeavyIndexing() ) ); + $this->description = $this->getAttribute("description"); + $this->enterface = $this->getAttribute("interface"); // sic ('interface' is reserved word) + $this->isTree = $this->booleanValue($this->getAttribute("isTree")); + } + + /** + *

    A hook for the SAX XML parser to call when this table has + * been fully loaded from the XML, and all nested elements have + * been processed.

    + * + *

    Performs heavy indexing and naming of elements which weren't + * provided with a name.

    + */ + public function doFinalInitialization() + { + // Heavy indexing must wait until after all columns composing + // a table's primary key have been parsed. + if ($this->heavyIndexing) { + $this->doHeavyIndexing(); + } + + // Name any indices which are missing a name using the + // appropriate algorithm. + $this->doNaming(); + + // if idMethod is "native" and in fact there are no autoIncrement + // columns in the table, then change it to "none" + if ($this->getIdMethod() === IDMethod::NATIVE) { + $anyAutoInc = false; + foreach($this->getColumns() as $col) { + if ($col->isAutoIncrement()) { + $anyAutoInc = true; + break; + } + } + if (!$anyAutoInc) { + $this->setIdMethod(IDMethod::NO_ID_METHOD); + } + } + } + + /** + *

    Adds extra indices for multi-part primary key columns.

    + * + *

    For databases like MySQL, values in a where clause much + * match key part order from the left to right. So, in the key + * definition PRIMARY KEY (FOO_ID, BAR_ID), + * FOO_ID must be the first element used in + * the where clause of the SQL query used against + * this table for the primary key index to be used. This feature + * could cause problems under MySQL with heavily indexed tables, + * as MySQL currently only supports 16 indices per table (i.e. it + * might cause too many indices to be created).

    + * + *

    See the + * manual for a better description of why heavy indexing is + * useful for quickly searchable database tables.

    + */ + private function doHeavyIndexing() + { + if (self::DEBUG) { + print("doHeavyIndex() called on table " . $this->name."\n"); + } + + $pk = $this->getPrimaryKey(); + $size = count($pk); + + try { + // We start at an offset of 1 because the entire column + // list is generally implicitly indexed by the fact that + // it's a primary key. + for ($i=1; $i < $size; $i++) { + $this->addIndex(new Index($this, array_slice($pk, $i, $size))); + } + } catch (EngineException $e) { + print $e->getMessage() . "\n"; + print $e->getTraceAsString(); + } + } + + /** + * Names composing objects which haven't yet been named. This + * currently consists of foreign-key and index entities. + */ + private function doNaming() { + + // Assure names are unique across all databases. + try { + for ($i=0, $size = count($this->foreignKeys); $i < $size; $i++) { + $fk = $this->foreignKeys[$i]; + $name = $fk->getName(); + if (empty($name)) { + $name = $this->acquireConstraintName("FK", $i + 1); + $fk->setName($name); + } + } + + for ($i = 0, $size = count($this->indices); $i < $size; $i++) { + $index = $this->indices[$i]; + $name = $index->getName(); + if (empty($name)) { + $name = $this->acquireConstraintName("I", $i + 1); + $index->setName($name); + } + } + + for ($i = 0, $size = count($this->unices); $i < $size; $i++) { + $index = $this->unices[$i]; + $name = $index->getName(); + if (empty($name)) { + $name = $this->acquireConstraintName("U", $i + 1); + $index->setName($name); + } + } + + // NOTE: Most RDBMSes can apparently name unique column + // constraints/indices themselves (using MySQL and Oracle + // as test cases), so we'll assume that we needn't add an + // entry to the system name list for these. + } catch (EngineException $nameAlreadyInUse) { + print $nameAlreadyInUse->getMessage() . "\n"; + print $nameAlreadyInUse->getTraceAsString(); + } + } + + /** + * Macro to a constraint name. + * + * @param nameType constraint type + * @param nbr unique number for this constraint type + * @return unique name for constraint + * @throws EngineException + */ + private function acquireConstraintName($nameType, $nbr) + { + $inputs = array(); + $inputs[] = $this->getDatabase(); + $inputs[] = $this->getName(); + $inputs[] = $nameType; + $inputs[] = $nbr; + return NameFactory::generateName(NameFactory::CONSTRAINT_GENERATOR, $inputs); + } + + /** + * Gets the value of base class for classes produced from this table. + * + * @return The base class for classes produced from this table. + */ + public function getBaseClass() + { + if ($this->isAlias() && $this->baseClass === null) { + return $this->alias; + } elseif ($this->baseClass === null) { + return $this->getDatabase()->getBaseClass(); + } else { + return $this->baseClass; + } + } + + /** + * Set the value of baseClass. + * @param v Value to assign to baseClass. + */ + public function setBaseClass($v) + { + $this->baseClass = $v; + } + + /** + * Get the value of basePeer. + * @return value of basePeer. + */ + public function getBasePeer() + { + if ($this->isAlias() && $this->basePeer === null) { + return $this->alias . "Peer"; + } elseif ($this->basePeer === null) { + return $this->getDatabase()->getBasePeer(); + } else { + return $this->basePeer; + } + } + + /** + * Set the value of basePeer. + * @param v Value to assign to basePeer. + */ + public function setBasePeer($v) + { + $this->basePeer = $v; + } + + /** + * A utility function to create a new column from attrib and add it to this + * table. + * + * @param $coldata xml attributes or Column class for the column to add + * @return the added column + */ + public function addColumn($data) + { + if ($data instanceof Column) { + $col = $data; // alias + $col->setTable($this); + if ($col->isInheritance()) { + $this->inheritanceColumn = $col; + } + $this->columnList[] = $col; + $this->columnsByName[$col->getName()] = $col; + $this->columnsByPhpName[$col->getPhpName()] = $col; + $col->setPosition(count($this->columnList)); + $this->needsTransactionInPostgres |= $col->requiresTransactionInPostgres(); + return $col; + } else { + $col = new Column(); + $col->setTable($this); + $col->loadFromXML($data); + return $this->addColumn($col); // call self w/ different param + } + } + + /** + * Add a validator to this table. + * + * Supports two signatures: + * - addValidator(Validator $validator) + * - addValidator(array $attribs) + * + * @param mixed $data Validator object or XML attribs (array) from element. + * @return Validator The added Validator. + * @throws EngineException + */ + public function addValidator($data) + { + if ($data instanceof Validator) + { + $validator = $data; + $col = $this->getColumn($validator->getColumnName()); + if($col == null) { + throw new EngineException("Failed adding validator to table '" . $this->getName() . + "': column '" . $validator->getColumnName() . "' does not exist !"); + } + $validator->setColumn($col); + $validator->setTable($this); + $this->validatorList[] = $validator; + return $validator; + } + else + { + $validator = new Validator(); + $validator->setTable($this); + $validator->loadFromXML($data); + return $this->addValidator($validator); + } + } + + /** + * A utility function to create a new foreign key + * from attrib and add it to this table. + */ + public function addForeignKey($fkdata) + { + if ($fkdata instanceof ForeignKey) { + $fk = $fkdata; + $fk->setTable($this); + $this->foreignKeys[] = $fk; + + if ($this->foreignTableNames === null) { + $this->foreignTableNames = array(); + } + if (!in_array($fk->getForeignTableName(), $this->foreignTableNames)) { + $this->foreignTableNames[] = $fk->getForeignTableName(); + } + return $fk; + } else { + $fk = new ForeignKey(); + $fk->loadFromXML($fkdata); + return $this->addForeignKey($fk); + } + } + + /** + * Gets the column that subclasses of the class representing this + * table can be produced from. + * @return string + */ + public function getChildrenColumn() + { + return $this->inheritanceColumn; + } + + /** + * Get the subclasses that can be created from this table. + * @return array string[] Class names + */ + public function getChildrenNames() + { + if ($this->inheritanceColumn === null + || !$this->inheritanceColumn->isEnumeratedClasses()) { + return null; + } + $children = $this->inheritanceColumn->getChildren(); + $names = array(); + for ($i = 0, $size=count($children); $i < $size; $i++) { + $names[] = get_class($children[$i]); + } + return $names; + } + + /** + * Adds the foreign key from another table that refers to this table. + */ + public function addReferrer(ForeignKey $fk) + { + if ($this->referrers === null) { + $this->referrers = array(); + } + $this->referrers[] = $fk; + } + + /** + * Get list of references to this table. + */ + public function getReferrers() + { + return $this->referrers; + } + + /** + * Set whether this table contains a foreign PK + */ + public function setContainsForeignPK($b) + { + $this->containsForeignPK = (boolean) $b; + } + + /** + * Determine if this table contains a foreign PK + */ + public function getContainsForeignPK() + { + return $this->containsForeignPK; + } + + /** + * A list of tables referenced by foreign keys in this table + */ + public function getForeignTableNames() + { + if ($this->foreignTableNames === null) { + $this->foreignTableNames = array(); + } + return $this->foreignTableNames; + } + + /** + * Return true if the column requires a transaction in Postgres + */ + public function requiresTransactionInPostgres() + { + return $this->needsTransactionInPostgres; + } + + /** + * A utility function to create a new id method parameter + * from attrib or object and add it to this table. + */ + public function addIdMethodParameter($impdata) + { + if ($impdata instanceof IdMethodParameter) { + $imp = $impdata; + $imp->setTable($this); + if ($this->idMethodParameters === null) { + $this->idMethodParameters = array(); + } + $this->idMethodParameters[] = $imp; + return $imp; + } else { + $imp = new IdMethodParameter(); + $imp->loadFromXML($impdata); + return $this->addIdMethodParameter($imp); // call self w/ diff param + } + } + + /** + * Adds a new index to the index list and set the + * parent table of the column to the current table + */ + public function addIndex($idxdata) + { + if ($idxdata instanceof Index) { + $index = $idxdata; + $index->setTable($this); + $index->getName(); // we call this method so that the name is created now if it doesn't already exist. + $this->indices[] = $index; + return $index; + } else { + $index = new Index($this); + $index->loadFromXML($idxdata); + return $this->addIndex($index); + } + } + + /** + * Adds a new Unique to the Unique list and set the + * parent table of the column to the current table + */ + public function addUnique($unqdata) + { + if ($unqdata instanceof Unique) { + $unique = $unqdata; + $unique->setTable($this); + $unique->getName(); // we call this method so that the name is created now if it doesn't already exist. + $this->unices[] = $unique; + return $unique; + } else { + $unique = new Unique($this); + $unique->loadFromXML($unqdata); + return $this->addUnique($unique); + } + } + + /** + * Get the name of the Table + */ + public function getName() + { + if ( isset ( $this->vendorSpecificInfo['Name'] ) ) + $this->name = $this->vendorSpecificInfo['Name']; + + return $this->name; + } + + /** + * Set the name of the Table + */ + public function setName($newName) + { + $this->name = $newName; + } + + /** + * Get the description for the Table + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set the description for the Table + * + * @param newDescription description for the Table + */ + public function setDescription($newDescription) + { + $this->description = $newDescription; + } + + /** + * Get name to use in PHP sources + * @return string + */ + public function getPhpName() + { + if ($this->phpName === null) { + $inputs = array(); + $inputs[] = $this->name; + $inputs[] = $this->phpNamingMethod; + try { + $this->phpName = NameFactory::generateName(NameFactory::PHP_GENERATOR, $inputs); + } catch (EngineException $e) { + print $e->getMessage() . "\n"; + print $e->getTraceAsString(); + } + } + return $this->phpName; + } + + /** + * Set name to use in PHP sources + * @param string $phpName + */ + public function setPhpName($phpName) + { + $this->phpName = $phpName; + } + + /** + * Get the method for generating pk's + * [HL] changing behavior so that Database default + * method is returned if no method has been specified + * for the table. + * @return string + */ + public function getIdMethod() + { + if ($this->idMethod === null) { + return IDMethod::NO_ID_METHOD; + } else { + return $this->idMethod; + } + } + + /** + * Set the method for generating pk's + */ + public function setIdMethod($idMethod) + { + $this->idMethod = $idMethod; + } + + /** + * Skip generating sql for this table (in the event it should + * not be created from scratch). + * @return boolean Value of skipSql. + */ + public function isSkipSql() + { + return ($this->skipSql || $this->isAlias() || $this->isForReferenceOnly()); + } + + /** + * Is table read-only, in which case only accessors (and relationship setters) + * will be created. + * @return boolan Value of readOnly. + */ + public function isReadOnly() + { + return $this->readOnly; + } + + /** + * Set whether this table should have its creation sql generated. + * @param boolean $v Value to assign to skipSql. + */ + public function setSkipSql($v) + { + $this->skipSql = $v; + } + + /** + * PhpName of om object this entry references. + * @return value of external. + */ + public function getAlias() + { + return $this->alias; + } + + /** + * Is this table specified in the schema or is there just + * a foreign key reference to it. + * @return value of external. + */ + public function isAlias() + { + return ($this->alias !== null); + } + + /** + * Set whether this table specified in the schema or is there just + * a foreign key reference to it. + * @param v Value to assign to alias. + */ + public function setAlias($v) + { + $this->alias = $v; + } + + + /** + * Interface which objects for this table will implement + * @return value of interface. + */ + public function getInterface() + { + return $this->enterface; + } + + /** + * Interface which objects for this table will implement + * @param v Value to assign to interface. + */ + public function setInterface($v) + { + $this->enterface = $v; + } + + /** + * When a table is abstract, it marks the business object class that is + * generated as being abstract. If you have a table called "FOO", then the + * Foo BO will be public abstract class Foo + * This helps support class hierarchies + * + * @return value of abstractValue. + */ + public function isAbstract() + { + return $this->abstractValue; + } + + /** + * When a table is abstract, it marks the business object + * class that is generated as being abstract. If you have a + * table called "FOO", then the Foo BO will be + * public abstract class Foo + * This helps support class hierarchies + * + * @param v Value to assign to abstractValue. + */ + public function setAbstract($v) + { + $this->abstractValue = (boolean) $v; + } + + /** + * Get the value of package. + * @return value of package. + */ + public function getPackage() + { + return $this->pkg; + } + + /** + * Set the value of package. + * @param v Value to assign to package. + */ + public function setPackage($v) + { + $this->pkg = $v; + } + + /** + * Returns an Array containing all the columns in the table + */ + public function getColumns() + { + return $this->columnList; + } + + /** + * Utility method to get the number of columns in this table + */ + public function getNumColumns() + { + return count($this->columnList); + } + + /** + * Utility method to get the number of columns in this table + */ + public function getNumLazyLoadColumns() + { + $count = 0; + foreach($this->columnList as $col) { + if ($col->isLazyLoad()) { + $count++; + } + } + return $count; + } + + /** + * Returns an Array containing all the validators in the table + */ + public function getValidators() + { + return $this->validatorList; + } + + /** + * Returns an Array containing all the FKs in the table + */ + public function getForeignKeys() + { + return $this->foreignKeys; + } + + /** + * Returns a Collection of parameters relevant for the chosen + * id generation method. + */ + public function getIdMethodParameters() + { + return $this->idMethodParameters; + } + + /** + * A name to use for creating a sequence if one is not specified. + */ + public function getSequenceName() + { + static $longNamesMap = array(); + $result = null; + if ($this->getIdMethod() == self::NATIVE) { + $idMethodParams = $this->getIdMethodParameters(); + if ($idMethodParams === null) { + $maxIdentifierLength = $this->getDatabase()->getPlatform()->getMaxColumnNameLength(); + if(strlen($this->getName() . "_SEQ") > $maxIdentifierLength) + { + if(!isset($longNamesMap[$this->getName()])) + { + $longNamesMap[$this->getName()] = strval(count($longNamesMap) + 1); + } + $result = substr($this->getName(), 0, $maxIdentifierLength - strlen("_SEQ_" . $longNamesMap[$this->getName()])) . "_SEQ_" . $longNamesMap[$this->getName()]; + } + else + { + $result = $this->getName() . "_SEQ"; + } + } else { + $result = $idMethodParams[0]->getValue(); + } + } + return $result; + } + + /** + * Returns an Array containing all the FKs in the table + */ + public function getIndices() + { + return $this->indices; + } + + /** + * Returns an Array containing all the UKs in the table + */ + public function getUnices() + { + return $this->unices; + } + + /** + * Returns a specified column. + * @return Return a Column object or null if it does not exist. + */ + public function getColumn($name) + { + return @$this->columnsByName[$name]; + } + + /** + * Returns a specified column. + * @return Return a Column object or null if it does not exist. + */ + public function getColumnByPhpName($phpName) + { + return @$this->columnsByPhpName[$phpName]; + } + + /** + * Return the first foreign key that includes col in it's list + * of local columns. Eg. Foreign key (a,b,c) refrences tbl(x,y,z) + * will be returned of col is either a,b or c. + * @param string $col + * @return Return a Column object or null if it does not exist. + */ + public function getForeignKey($col) + { + $firstFK = null; + for($i=0,$size=count($this->foreignKeys); $i < $size; $i++) { + $key = $this->foreignKeys[$i]; + if (in_array($col, $key->getLocalColumns())) { + if ($firstFK === null) { + $firstFK = $key; + } else { + throw new EngineException($col . " has ben declared as a foreign key multiple times. This is not" + . " being handled properly. (Try moving foreign key declarations to the foreign table.)"); + } + } + } + return $firstFK; + } + + /** + * Returns true if the table contains a specified column + * @param mixed $col Column or column name. + */ + public function containsColumn($col) + { + if ($col instanceof Column) { + return in_array($col, $this->columnList); + } else { + return ($this->getColumn($col) !== null); + } + } + + /** + * Set the parent of the table + * + * @param parent the parant database + */ + public function setDatabase($parent) + { + $this->tableParent = $parent; + } + + /** + * Get the parent of the table + * + * @return the parant database + */ + public function getDatabase() + { + return $this->tableParent; + } + + /** + * Flag to determine if code/sql gets created for this table. + * Table will be skipped, if return true. + * @return value of forReferenceOnly. + */ + public function isForReferenceOnly() + { + return $this->forReferenceOnly; + } + + /** + * Flag to determine if code/sql gets created for this table. + * Table will be skipped, if set to true. + * @param v Value to assign to forReferenceOnly. + */ + public function setForReferenceOnly($v) + { + $this->forReferenceOnly = (boolean) $v; + } + + /** + * Flag to determine if tree node class should be generated for this table. + * @return valur of isTree + */ + public function isTree() + { + return $this->isTree; + } + + /** + * Flag to determine if tree node class should be generated for this table. + * @param v Value to assign to isTree. + */ + public function setIsTree($v) + { + $this->isTree = (boolean) $v; + } + + /** + * Returns a XML representation of this table. + * + * @return XML representation of this table + */ + public function toString() { + + $result = "
    name . "\""; + + if ($this->phpName !== null) { + $result .= " phpName=\"" + . $this->phpName + . '"'; + } + + if ($this->idMethod !== null) { + $result .= " idMethod=\"" + . $this->idMethod + . '"'; + } + + if ($this->skipSql) { + $result .= " skipSql=\"" + . ($this->skipSql ? "true" : "false") + . '"'; + } + + if ($this->readOnly) { + $result .= " readOnly=\"" + . ($this->readOnly ? "true" : "false") + . '"'; + } + + if ($this->isTree) { + $result .= " isTree=\"" + . ($this->isTree ? "true" : "false") + . '"'; + } + + if ($this->forReferenceOnly) { + $result .= " forReferenceOnly=\"" + . ($this->forReferenceOnly ? "true" : "false") + . '"'; + } + + if ($this->abstractValue) { + $result .= " abstract=\"" + . ($abstractValue ? "true" : "false") + . '"'; + } + + if ($this->enterface !== null) { + $result .= " interface=\"" + . $this->enterface + . '"'; + } + + if ($this->description !== null) { + $result .= " description=\"" + . $this->description + . '"'; + } + + if ($this->baseClass !== null) { + $result .= " baseClass=\"" + . $this->baseClass + . '"'; + } + + if ($this->basePeer !== null) { + $result .= " basePeer=\"" + . $this->basePeer + . '"'; + } + + $result .= ">\n"; + + if ($this->columnList !== null) { + for($i=0,$_i=count($this->columnList); $i < $_i; $i++) { + $result .= $this->columnList[$i]->toString(); + } + } + + if ($this->validatorList !== null) { + for($i=0,$_i=count($this->validatorList); $i < $_i; $i++) { + $result .= $this->validatorList[$i]->toString(); + } + } + + if ($this->foreignKeys !== null) { + for($i=0,$_i=count($this->foreignKeys); $i < $_i; $i++) { + $result .= $this->foreignKeys[$i]->toString(); + } + } + + if ($this->idMethodParameters !== null) { + for($i=0,$_i=count($this->idMethodParameters); $i < $_i; $i++) { + $result .= $this->idMethodParameters[$i]->toString(); + } + } + + $result .= "
    \n"; + + return $result; + } + + /** + * Returns the collection of Columns which make up the single primary + * key for this table. + * + * @return array A list of the primary key parts. + */ + public function getPrimaryKey() + { + $pk = array(); + for($i=0,$_i=count($this->columnList); $i < $_i; $i++) { + $col = $this->columnList[$i]; + if ($col->isPrimaryKey()) { + $pk[] = $col; + } + } + return $pk; + } + + /** + * Determine whether this table has a primary key. + * + * @return boolean Whether this table has any primary key parts. + */ + public function hasPrimaryKey() + { + return (count($this->getPrimaryKey()) > 0); + } + + /** + * Determine whether this table has any auto-increment primary key(s). + * + * @return boolean Whether this table has a non-"none" id method and has a primary key column that is auto-increment. + */ + public function hasAutoIncrementPrimaryKey() + { + if ($this->getIdMethod() != IDMethod::NO_ID_METHOD) { + $pks =$this->getPrimaryKey(); + foreach ($pks as $pk) { + if ($pk->isAutoIncrement()) { + return true; + } + } + } + return false; + } + + /** + * Returns all parts of the primary key, separated by commas. + * + * @return A CSV list of primary key parts. + * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method. + */ + public function printPrimaryKey() + { + return $this->printList($this->columnList); + } + + /** + * Returns the elements of the list, separated by commas. + * @param array $list + * @return A CSV list. + * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method. + */ + private function printList($list){ + $result = ""; + $comma = 0; + for($i=0,$_i=count($list); $i < $_i; $i++) { + $col = $list[$i]; + if ($col->isPrimaryKey()) { + $result .= ($comma++ ? ',' : '') . $this->getDatabase()->getPlatform()->quoteIdentifier($col->getName()); + } + } + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Unique.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Unique.php new file mode 100644 index 000000000..ae4486aff --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Unique.php @@ -0,0 +1,69 @@ +. + */ + +include_once 'propel/engine/database/model/Index.php'; + +/** + * Information about unique columns of a table. This class assumes + * that in the underlying RDBMS, unique constraints and unique indices + * are roughly equivalent. For example, adding a unique constraint to + * a column also creates an index on that column (this is known to be + * true for MySQL and Oracle). + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Unique extends Index { + + /** + * Default constructor. + */ + public function __construct(Table $table, $indexColumns = array()) + { + } + + /** + * Returns true. + */ + public function isUnique() + { + return true; + } + + /** + * String representation of the index. This is an xml representation. + */ + public function toString() + { + $result = " getName() . "\">\n"; + $columns = $this->getColumns(); + for ($i=0, $size=count($columns); $i < $size; $i++) { + $result .= " \n"; + } + $result .= " \n"; + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Validator.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Validator.php new file mode 100644 index 000000000..3ccd6fc86 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/Validator.php @@ -0,0 +1,186 @@ +. + */ + +require_once 'propel/engine/database/model/XMLElement.php'; +include_once 'propel/engine/EngineException.php'; +include_once 'propel/engine/database/model/PropelTypes.php'; +include_once 'propel/engine/database/model/Rule.php'; + +/** + * Validator. + * + * @author Michael Aichler (Propel) + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +class Validator extends XMLElement { + + const TRANSLATE_NONE = "none"; + const TRANSLATE_GETTEXT = "gettext"; + + private $columnName; + private $column; + private $ruleList; + private $translate; + private $table; + + /** + * Creates a new column and set the name + * + * @param name validator name + */ + public function __construct() + { + $this->ruleList = array(); + } + + /** + * Sets up the Validator object based on the attributes that were passed to loadFromXML(). + * @see parent::loadFromXML() + */ + protected function setupObject() + { + $this->columnName = $this->getAttribute("column"); + $this->translate = $this->getAttribute("translate", $this->getTable()->getDatabase()->getDefaultTranslateMethod());; + } + + /** + * Add a Rule to this validator. + * Supports two signatures: + * - addRule(Rule $rule) + * - addRule(array $attribs) + * @param mixed $data Rule object or XML attribs (array) from element. + * @return Rule The added Rule. + */ + public function addRule($data) + { + if ($data instanceof Rule) { + $rule = $data; // alias + $rule->setValidator($this); + $this->ruleList[] = $rule; + return $rule; + } + else { + $rule = new Rule(); + $rule->setValidator($this); + $rule->loadFromXML($data); + return $this->addRule($rule); // call self w/ different param + } + } + + /** + * Gets an array of all added rules for this validator. + * @return array Rule[] + */ + public function getRules() + { + return $this->ruleList; + } + + /** + * Gets the name of the column that this Validator applies to. + * @return string + */ + public function getColumnName() + { + return $this->columnName; + } + + /** + * Sets the Column object that this validator applies to. + * @param Column $column + * @see Table::addValidator() + */ + public function setColumn(Column $column) + { + $this->column = $column; + } + + /** + * Gets the Column object that this validator applies to. + * @return Column + */ + public function getColumn() + { + return $this->column; + } + + /** + * Set the owning Table. + * @param Table $table + */ + public function setTable(Table $table) + { + $this->table = $table; + } + + /** + * Get the owning Table. + * @return Table + */ + public function getTable() + { + return $this->table; + } + + /** + * Set the translation mode to use for the message. + * Currently only "gettext" and "none" are supported. The default is "none". + * @param string $method Translation method ("gettext", "none"). + */ + public function setTranslate($method) + { + $this->translate = $method; + } + + /** + * Get the translation mode to use for the message. + * Currently only "gettext" and "none" are supported. The default is "none". + * @return string Translation method ("gettext", "none"). + */ + public function getTranslate() + { + return $this->translate; + } + + /** + * Gets XML (string) representation of this Validator. + * @return string + */ + public function toString() + { + $result = "columnName . "\""; + if ($this->translate !== null) { + $result .= " translate=\"".$this->translate."\""; + } + $result .= ">\n"; + + if ($this->ruleList !== null) { + for($i=0,$_i=count($this->ruleList); $i < $_i; $i++) { + $result .= $this->ruleList[$i]->toString(); + } + } + + $result .= "\n"; + + return $result; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/XMLElement.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/XMLElement.php new file mode 100644 index 000000000..61579e1b6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/model/XMLElement.php @@ -0,0 +1,141 @@ +. + */ + +/** + * An abstract class for elements represented by XML tags (e.g. Column, Table). + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.engine.database.model + */ +abstract class XMLElement { + + protected $attributes = array(); + + protected $vendorSpecificInfo = array(); + + /** + * Replaces the old loadFromXML() so that we can use loadFromXML() to load the attribs into the class. + */ + abstract protected function setupObject(); + + /** + * This is the entry point method for loading data from XML. + * It calls a setupObject() method that must be implemented by the child class. + * @param array $attributes The attributes for the XML tag. + */ + public function loadFromXML($attributes) { + $this->attributes = array_change_key_case($attributes, CASE_LOWER); + $this->setupObject(); + } + + /** + * Returns the assoc array of attributes. + * All attribute names (keys) are lowercase. + * @return array + */ + public function getAttributes() { + return $this->attributes; + } + + /** + * Gets a particular attribute by [case-insensitive] name. + * If attribute is not set then the $defaultValue is returned. + * @param string $name The [case-insensitive] name of the attribute to lookup. + * @param mixed $defaultValue The default value to use in case the attribute is not set. + * @return mixed The value of the attribute or $defaultValue if not set. + */ + public function getAttribute($name, $defaultValue = null) { + $name = strtolower($name); + if (isset($this->attributes[$name])) { + return $this->attributes[$name]; + } else { + return $defaultValue; + } + } + + /** + * Converts value specified in XML to a boolean value. + * This is to support the default value when used w/ a boolean column. + * @return value + */ + protected function booleanValue($val) { + if (is_numeric($val)) { + return (bool) $val; + } else { + return (in_array(strtolower($val), array('true', 't', 'y', 'yes'), true) ? true : false); + } + } + + /** + * Sets vendor specific parameter that applies to this object. + * @param string $name + * @param string $value + */ + public function setVendorParameter($name, $value) + { + $this->vendorSpecificInfo[$name] = $value; + } + + /** + * Whether specified vendor specific information is set. + * @param string $name + * @return boolean + */ + public function hasVendorParameter($name) + { + return isset($this->vendorSpecificInfo[$name]); + } + + /** + * Returns specified vendor specific information is set. + * @param string $name + * @return string + */ + public function getVendorParameter($name) + { + if (isset($this->vendorSpecificInfo[$name])) { + return $this->vendorSpecificInfo[$name]; + } + return null; // just to be explicit + } + + /** + * Sets vendor specific information for this object. + * @param array $info + */ + public function setVendorSpecificInfo($info) + { + $this->vendorSpecificInfo = $info; + } + + /** + * Retrieves vendor specific information for this object. + * @return array + */ + public function getVendorSpecificInfo() + { + return $this->vendorSpecificInfo; + } + + + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php new file mode 100644 index 000000000..7bc7739d1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php @@ -0,0 +1,420 @@ +. + */ + +include_once 'propel/engine/database/model/AppData.php'; + +// Phing dependencies +require_once 'phing/parser/AbstractHandler.php'; +include_once 'phing/system/io/FileReader.php'; + +/** + * A class that is used to parse an input xml schema file and creates an AppData + * PHP object. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author Jason van Zyl (Torque) + * @author Martin Poeschl (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.transform + */ +class XmlToAppData extends AbstractHandler { + + /** enables debug output */ + const DEBUG = false; + + private $app; + private $platform; + private $currDB; + private $currTable; + private $currColumn; + private $currFK; + private $currIndex; + private $currUnique; + private $currValidator; + private $currVendorObject; + + private $isForReferenceOnly; + private $currentPackage; + private $currentXmlFile; + private $defaultPackage; + + private $encoding; + + /** two-dimensional array, + first dimension is for schemas(key is the path to the schema file), + second is for tags within the schema */ + private $schemasTagsStack = array(); + + public $parser; + + /** + * Creates a new instance for the specified database type. + * + * @param Platform $platform The type of database for the application. + * @param string $defaultPackage the default PHP package used for the om + * @param string $encoding The database encoding. + */ + public function __construct(Platform $platform, $defaultPackage, $encoding = 'iso-8859-1') + { + $this->app = new AppData($platform); + $this->platform = $platform; + $this->defaultPackage = $defaultPackage; + $this->firstPass = true; + $this->encoding = $encoding; + } + + /** + * Parses a XML input file and returns a newly created and + * populated AppData structure. + * + * @param string $xmlFile The input file to parse. + * @return AppData populated by xmlFile. + */ + public function parseFile($xmlFile) + { + // we don't want infinite recursion + if($this->isAlreadyParsed($xmlFile)) { + return; + } + + $domDocument = new DomDocument('1.0', 'UTF-8'); + $domDocument->load($xmlFile); + + // store current schema file path + $this->schemasTagsStack[$xmlFile] = array(); + + $this->currentXmlFile = $xmlFile; + + try { + $fr = new FileReader($xmlFile); + } catch (Exception $e) { + $f = new PhingFile($xmlFile); + throw new Exception("XML File not found: " . $f->getAbsolutePath()); + } + + $br = new BufferedReader($fr); + + $this->parser = new ExpatParser($br); + $this->parser->parserSetOption(XML_OPTION_CASE_FOLDING, 0); + $this->parser->setHandler($this); + + try { + $this->parser->parse(); + } catch (Exception $e) { + $br->close(); + throw $e; + } + $br->close(); + + array_pop($this->schemasTagsStack); + + return $this->app; + } + + /** + * Handles opening elements of the xml file. + * + * @param string $uri + * @param string $localName The local name (without prefix), or the empty string if + * Namespace processing is not being performed. + * @param string $rawName The qualified name (with prefix), or the empty string if + * qualified names are not available. + * @param string $attributes The specified or defaulted attributes + */ + public function startElement($name, $attributes) { + + try { + + $parentTag = $this->peekCurrentSchemaTag(); + + if ($parentTag === false) { + + switch($name) { + case "database": + if ($this->isExternalSchema()) { + $this->currentPackage = @$attributes["package"]; + if ($this->currentPackage === null) { + $this->currentPackage = $this->defaultPackage; + } + } else { + $this->currDB = $this->app->addDatabase($attributes); + } + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "database") { + + switch($name) { + + case "external-schema": + $xmlFile = @$attributes["filename"]; + + //"referenceOnly" attribute is valid in the main schema XML file only, + //and it's ingnored in the nested external-schemas + if(!$this->isExternalSchema()) { + $isForRefOnly = @$attributes["referenceOnly"]; + $this->isForReferenceOnly = ($isForRefOnly !== null ? (strtolower($isForRefOnly) === "true") : true); // defaults to TRUE + } + + if ($xmlFile{0} != '/') { + $f = new PhingFile($this->currentXmlFile); + $xf = new PhingFile($f->getParent(), $xmlFile); + $xmlFile = $xf->getPath(); + } + + $this->parseFile($xmlFile); + break; + + case "domain": + $this->currDB->addDomain($attributes); + break; + + case "table": + $this->currTable = $this->currDB->addTable($attributes); + if ($this->isExternalSchema()) { + $this->currTable->setForReferenceOnly($this->isForReferenceOnly); + $this->currTable->setPackage($this->currentPackage); + } + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currDB, $attributes['type']); + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "table") { + + switch($name) { + case "column": + $this->currColumn = $this->currTable->addColumn($attributes); + break; + + case "foreign-key": + $this->currFK = $this->currTable->addForeignKey($attributes); + break; + + case "index": + $this->currIndex = $this->currTable->addIndex($attributes); + break; + + case "unique": + $this->currUnique = $this->currTable->addUnique($attributes); + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currTable, $attributes['type']); + break; + + case "validator": + $this->currValidator = $this->currTable->addValidator($attributes); + break; + + case "id-method-parameter": + $this->currTable->addIdMethodParameter($attributes); + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "column") { + + switch($name) { + case "inheritance": + $this->currColumn->addInheritance($attributes); + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currColumn, $attributes['type']); + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "foreign-key") { + + switch($name) { + case "reference": + $this->currFK->addReference($attributes); + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currFK, $attributes['type']); + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "index") { + + switch($name) { + case "index-column": + $this->currIndex->addColumn($attributes); + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currIndex, $attributes['type']); + break; + + default: + $this->_throwInvalidTagException($name); + } + + } elseif ($parentTag == "unique") { + + switch($name) { + case "unique-column": + $this->currUnique->addColumn($attributes); + break; + + case "vendor": + $this->currVendorObject = new ObjectWithVendorSpecificData($this->currUnique, $attributes['type']); + break; + + default: + $this->_throwInvalidTagException($name); + } + } elseif ($parentTag == "validator") { + switch($name) { + case "rule": + $this->currValidator->addRule($attributes); + break; + default: + $this->_throwInvalidTagException($name); + } + } elseif ($parentTag == "vendor") { + + switch($name) { + case "parameter": + if($this->currVendorObject->isCompatible($this->platform->getDatabaseType())) { + $this->currVendorObject->setVendorParameter($attributes['name'], iconv('utf-8',$this->encoding, $attributes['value'])); + } + break; + + default: + $this->_throwInvalidTagException($name); + } + + } else { + // it must be an invalid tag + $this->_throwInvalidTagException($name); + } + + $this->pushCurrentSchemaTag($name); + + } catch (BuildException $e) { + throw $e; + } catch (Exception $e) { + echo $e; + echo "\n"; + throw $e; + } + } + + function _throwInvalidTagException($tag_name) + { + throw new BuildException("Unexpected tag <" . $tag_name . ">", $this->parser->getLocation()); + } + + /** + * Handles closing elements of the xml file. + * + * @param uri + * @param localName The local name (without prefix), or the empty string if + * Namespace processing is not being performed. + * @param rawName The qualified name (with prefix), or the empty string if + * qualified names are not available. + */ + public function endElement($name) + { + if (self::DEBUG) { + print("endElement(" . $name . ") called\n"); + } + + $this->popCurrentSchemaTag(); + } + + protected function peekCurrentSchemaTag() + { + $keys = array_keys($this->schemasTagsStack); + return end($this->schemasTagsStack[end($keys)]); + } + + protected function popCurrentSchemaTag() + { + $keys = array_keys($this->schemasTagsStack); + array_pop($this->schemasTagsStack[end($keys)]); + } + + protected function pushCurrentSchemaTag($tag) + { + $keys = array_keys($this->schemasTagsStack); + $this->schemasTagsStack[end($keys)][] = $tag; + } + + protected function isExternalSchema() + { + return (sizeof($this->schemasTagsStack) > 1); + } + + protected function isAlreadyParsed($filePath) + { + return isset($this->schemasTagsStack[$filePath]); + } +} + +/** + * Utility class used for objects with vendor data. + * + * @package propel.engine.database.transform + */ +class ObjectWithVendorSpecificData +{ + protected $object; + protected $vendorType; + + public function __construct($object, $vendorType) + { + $this->object = $object; + $this->vendorType = $vendorType; + } + + public function isCompatible($type) + { + return ($this->vendorType == $type); + } + + public function setVendorParameter($name, $value) + { + $this->object->setVendorParameter($name, $value); + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToData.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToData.php new file mode 100644 index 000000000..0b17ad65f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/database/transform/XmlToData.php @@ -0,0 +1,189 @@ +. + */ + +require_once 'phing/parser/AbstractHandler.php'; + +/** + * A Class that is used to parse an input xml schema file and creates an + * AppData object. + * + * @author Hans Lellelid (Propel) + * @author Leon Messerschmidt (Torque) + * @author Jason van Zyl (Torque) + * @author Martin Poeschl (Torque) + * @author Fedor Karpelevitch (Torque) + * @version $Revision: 536 $ + * @package propel.engine.database.transform + */ +class XmlToData extends AbstractHandler { + + private $database; + private $data; + + private $encoding; + + public $parser; + + const DEBUG = false; + + /** + * Construct new XmlToData class. + * + * This class is passed the Database object so that it knows what to expect from + * the XML file. + * + * @param Database $database + */ + public function __construct(Database $database, $encoding = 'iso-8859-1') + { + $this->database = $database; + $this->encoding = $encoding; + } + + /** + * + */ + public function parseFile($xmlFile) + { + try { + + $this->data = array(); + + try { + $fr = new FileReader($xmlFile); + } catch (Exception $e) { + $f = new PhingFile($xmlFile); + throw new BuildException("XML File not found: " . $f->getAbsolutePath()); + } + + $br = new BufferedReader($fr); + + $this->parser = new ExpatParser($br); + $this->parser->parserSetOption(XML_OPTION_CASE_FOLDING, 0); + $this->parser->setHandler($this); + + try { + $this->parser->parse(); + } catch (Exception $e) { + print $e->getMessage() . "\n"; + $br->close(); + } + $br->close(); + } catch (Exception $e) { + print $e->getMessage() . "\n"; + print $e->getTraceAsString(); + } + + return $this->data; + } + + /** + * Handles opening elements of the xml file. + */ + public function startElement($name, $attributes) + { + try { + if ($name == "dataset") { + // we don't do anything w/ tag right now. + } else { + $table = $this->database->getTableByPhpName($name); + + $this->columnValues = array(); + foreach($attributes as $name => $value) { + $col = $table->getColumnByPhpName($name); + $this->columnValues[] = new ColumnValue($col, iconv('utf-8',$this->encoding, $value)); + } + $this->data[] = new DataRow($table, $this->columnValues); + } + } catch (Exception $e) { + print $e; + throw $e; + } + } + + + /** + * Handles closing elements of the xml file. + * + * @param $name The local name (without prefix), or the empty string if + * Namespace processing is not being performed. + */ + public function endElement($name) + { + if (self::DEBUG) { + print("endElement(" . $name . ") called\n"); + } + } + +} // XmlToData + + /** + * "inner class" + * @package propel.engine.database.transform + */ + class DataRow + { + private $table; + private $columnValues; + + public function __construct(Table $table, $columnValues) + { + $this->table = $table; + $this->columnValues = $columnValues; + } + + public function getTable() + { + return $this->table; + } + + public function getColumnValues() + { + return $this->columnValues; + } + } + + /** + * "inner" class + * @package propel.engine.database.transform + */ + class ColumnValue { + + private $col; + private $val; + + public function __construct(Column $col, $val) + { + $this->col = $col; + $this->val = $val; + } + + public function getColumn() + { + return $this->col; + } + + public function getValue() + { + return $this->val; + } + } diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/DefaultPlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/DefaultPlatform.php new file mode 100644 index 000000000..40ebea295 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/DefaultPlatform.php @@ -0,0 +1,169 @@ +. + */ + +require_once 'propel/engine/platform/Platform.php'; +include_once 'propel/engine/database/model/Domain.php'; + +/** + * Default implementation for the Platform interface. + * + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class DefaultPlatform implements Platform { + + private $schemaDomainMap; + + /** + * Default constructor. + */ + public function __construct() + { + $this->initialize(); + } + + protected function initialize() + { + $this->schemaDomainMap = array(); + foreach(PropelTypes::getPropelTypes() as $type) { + $this->schemaDomainMap[$type] = new Domain($type); + } + $this->schemaDomainMap[PropelTypes::BU_DATE] = new Domain("DATE"); + $this->schemaDomainMap[PropelTypes::BU_TIMESTAMP] = new Domain("TIMESTAMP"); + $this->schemaDomainMap[PropelTypes::BOOLEAN] = new Domain("INTEGER"); + } + + protected function setSchemaDomainMapping(Domain $domain) + { + $this->schemaDomainMap[$domain->getType()] = $domain; + } + + /** + * Returns the short name of the database type that this platform represents. + * For example MysqlPlatform->getDatabaseType() returns 'mysql'. + * @return string + */ + public function getDatabaseType() + { + $clazz = get_class($this); + $pos = strpos($clazz, 'Platform'); + return strtolower(substr($clazz,0,$pos)); + } + + /** + * @see Platform::getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 64; + } + + /** + * @see Platform::getNativeIdMethod() + */ + public function getNativeIdMethod() + { + return Platform::IDENTITY; + } + + /** + * @see Platform::getDomainForType() + */ + public function getDomainForType($propelType) + { + if (!isset($this->schemaDomainMap[$propelType])) { + throw new EngineException("Cannot map unknown Propel type " . var_export($propelType, true) . " to native database type."); + } + return $this->schemaDomainMap[$propelType]; + } + + /** + * @return Only produces a SQL fragment if null values are + * disallowed. + * @see Platform::getNullString(boolean) + */ + public function getNullString($notNull) + { + // TODO: Check whether this is true for all DBs. Also verify + // the old Sybase templates. + return ($notNull ? "NOT NULL" : ""); + } + + /** + * @see Platform::getAutoIncrement() + */ + public function getAutoIncrement() + { + return "IDENTITY"; + } + + /** + * @see Platform::hasScale(String) + * TODO collect info for all platforms + */ + public function hasScale($sqlType) + { + return true; + } + + /** + * @see Platform::hasSize(String) + * TODO collect info for all platforms + */ + public function hasSize($sqlType) + { + return true; + } + + /** + * @see Platform::escapeText() + */ + public function escapeText($text) + { + return str_replace("'", "''", $text); + } + + /** + * @see Platform::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '"' . $text . '"'; + } + + /** + * @see Platform::supportsNativeDeleteTrigger() + */ + public function supportsNativeDeleteTrigger() + { + return false; + } + + /** + * @see Platform::getBooleanString() + */ + public function getBooleanString($b) + { + $b = ($b === true || strtolower($b) === 'true' || $b === 1 || $b === '1' || strtolower($b) === 'y' || strtolower($b) === 'yes'); + return ($b ? '1' : '0'); + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MssqlPlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MssqlPlatform.php new file mode 100644 index 000000000..1e3e8e0f9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MssqlPlatform.php @@ -0,0 +1,122 @@ +. + */ + +require_once 'propel/engine/platform/DefaultPlatform.php'; +include_once 'propel/engine/database/model/Domain.php'; + +/** + * MS SQL Platform implementation. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class MssqlPlatform extends DefaultPlatform { + + /** + * Initializes db specific domain mapping. + * Change for standardization + */ + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::INTEGER, "INT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "INT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "FLOAT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "NTEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "NTEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, "CHAR(19)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_DATE, "CHAR(19)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIME, "CHAR(19)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "CHAR(19)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_TIMESTAMP, "CHAR(19)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BINARY(7132)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "IMAGE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "IMAGE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "IMAGE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARCHAR, "NVARCHAR")); + } + +/* + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::INTEGER, "INT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "INT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "FLOAT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "TEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_DATE, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIME, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_TIMESTAMP, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BINARY(7132)")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "IMAGE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "IMAGE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "IMAGE")); + } +*/ + + /** + * @see Platform#getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 128; + } + + /** + * @return Explicitly returns NULL if null values are + * allowed (as recomended by Microsoft). + * @see Platform#getNullString(boolean) + */ + public function getNullString($notNull) + { + return ($notNull ? "NOT NULL" : "NULL"); + } + + /** + * @see Platform::supportsNativeDeleteTrigger() + */ + public function supportsNativeDeleteTrigger() + { + return true; + } + + /** + * @see Platform::hasSize(String) + */ + public function hasSize($sqlType) + { + return !("INT" == $sqlType || "TEXT" == $sqlType); + } + + /** + * @see Platform::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '[' . $text . ']'; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqlPlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqlPlatform.php new file mode 100644 index 000000000..aa49fab9f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqlPlatform.php @@ -0,0 +1,105 @@ +. + */ + +require_once 'propel/engine/platform/DefaultPlatform.php'; + +/** + * MySql Platform implementation. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class MysqlPlatform extends DefaultPlatform { + + /** + * Initializes db specific domain mapping. + */ + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_TIMESTAMP, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT")); + } + + /** + * @see Platform#getAutoIncrement() + */ + public function getAutoIncrement() + { + return "AUTO_INCREMENT"; + } + + /** + * @see Platform#getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 64; + } + + /** + * @see Platform::supportsNativeDeleteTrigger() + */ + public function supportsNativeDeleteTrigger() + { + $usingInnoDB = false; + if(class_exists('DataModelBuilder', false)) + { + $usingInnoDB = strtolower(DataModelBuilder::getBuildProperty('mysqlTableType')) == 'innodb'; + } + return $usingInnoDB || false; + } + + /** + * @see Platform#hasSize(String) + */ + public function hasSize($sqlType) { + return !("MEDIUMTEXT" == $sqlType || "LONGTEXT" == $sqlType + || "BLOB" == $sqlType || "MEDIUMBLOB" == $sqlType + || "LONGBLOB" == $sqlType); + } + + /** + * Escape the string for RDBMS. + * @param string $text + * @return string + */ + public function escapeText($text) { + return mysql_escape_string($text); + } + + /** + * @see Platform::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '`' . $text . '`'; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqliPlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqliPlatform.php new file mode 100644 index 000000000..49036e8b2 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/MysqliPlatform.php @@ -0,0 +1,58 @@ +. + */ + +require_once 'propel/engine/platform/MysqlPlatform.php'; + +/** + * MySql Platform implementation, using new mysqli API. + * + * @author Hans Lellelid (Propel) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class MysqliPlatform extends MysqlPlatform { + + /** + * Initializes db specific domain mapping. + */ + protected function initialize() + { + parent::initialize(); + + // HL -- commenting these out, as it turns out that while the date format is fixed + // there is still a special meaning to TIMESTAMP in MySQL 4.1+ + // $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "TIMESTAMP")); + // $this->setSchemaDomainMapping(new Domain(PropelTypes::BU_TIMESTAMP, "TIMESTAMP")); + } + + /** + * Escape the string for MySQL. + * + * @param string $text + * @return string + */ + public function escapeText($text) { + // Because mysqli requires open connection, we are using addslashes() here. + // This needs to be fixed in a better way ... + return addslashes($text); + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/OraclePlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/OraclePlatform.php new file mode 100644 index 000000000..65fe4a7c7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/OraclePlatform.php @@ -0,0 +1,89 @@ +. + */ + +require_once 'propel/engine/platform/DefaultPlatform.php'; + +/** + * Oracle Platform implementation. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class OraclePlatform extends DefaultPlatform { + + /** + * Initializes db specific domain mapping. + */ + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "NUMBER", "1", "0")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TINYINT, "NUMBER", "3", "0")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::SMALLINT, "NUMBER", "5", "0")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::INTEGER, "NUMBER")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BIGINT, "NUMBER", "20", "0")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::REAL, "NUMBER")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "FLOAT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DECIMAL, "NUMBER")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "NUMBER")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARCHAR, "VARCHAR2")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "VARCHAR2", "2000")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIME, "DATE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATE")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "LONG RAW")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "BLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONG RAW")); + } + + /** + * @see Platform#getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 30; + } + + /** + * @see Platform#getNativeIdMethod() + */ + public function getNativeIdMethod() + { + return Platform::SEQUENCE; + } + + /** + * @see Platform#getAutoIncrement() + */ + public function getAutoIncrement() + { + return ""; + } + + /** + * @see Platform::supportsNativeDeleteTrigger() + */ + public function supportsNativeDeleteTrigger() + { + return true; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php new file mode 100644 index 000000000..ab67ce786 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php @@ -0,0 +1,114 @@ +. + */ + +require_once 'propel/engine/platform/DefaultPlatform.php'; + +/** + * Postgresql Platform implementation. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class PgsqlPlatform extends DefaultPlatform { + + /** + * Initializes db specific domain mapping. + */ + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "BOOLEAN")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::TINYINT, "INT2")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::SMALLINT, "INT2")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BIGINT, "INT8")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::REAL, "FLOAT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "DOUBLE PRECISION")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BYTEA")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "BYTEA")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "BYTEA")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "BYTEA")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "TEXT")); + } + + /** + * @see Platform#getNativeIdMethod() + */ + public function getNativeIdMethod() + { + return Platform::SEQUENCE; + } + + /** + * @see Platform#getAutoIncrement() + */ + public function getAutoIncrement() + { + return ""; + } + + /** + * @see Platform#getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 32; + } + + /** + * Escape the string for RDBMS. + * @param string $text + * @return string + */ + public function escapeText($text) { + return pg_escape_string($text); + } + + /** + * @see Platform::getBooleanString() + */ + public function getBooleanString($b) + { + // parent method does the checking for allowes tring + // representations & returns integer + $b = parent::getBooleanString($b); + return ($b ? "'t'" : "'f'"); + } + + /** + * @see Platform::supportsNativeDeleteTrigger() + */ + public function supportsNativeDeleteTrigger() + { + return true; + } + + /** + * @see Platform::hasSize(String) + * TODO collect info for all platforms + */ + public function hasSize($sqlType) + { + return !("BYTEA" == $sqlType || "TEXT" == $sqlType); + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/Platform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/Platform.php new file mode 100644 index 000000000..188a6c7ab --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/Platform.php @@ -0,0 +1,128 @@ +. + */ + +/** + * Interface for RDBMS platform specific behaviour. + * + * @author Hans Lellelid (Propel) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +interface Platform { + + /** constant for native id method */ + const IDENTITY = "identity"; + + /** constant for native id method */ + const SEQUENCE = "sequence"; + + /** + * Returns the short name of the database type that this platform represents. + * For example MysqlPlatform->getDatabaseType() returns 'mysql'. + * @return string + */ + public function getDatabaseType(); + + /** + * Returns the native IdMethod (sequence|identity) + * + * @return string The native IdMethod (Platform:IDENTITY, Platform::SEQUENCE). + */ + public function getNativeIdMethod(); + + /** + * Returns the max column length supported by the db. + * + * @return int The max column length + */ + public function getMaxColumnNameLength(); + + /** + * Returns the db specific domain for a jdbcType. + * + * @param string $creoleType the creole type name. + * @return Domain The db specific domain. + */ + public function getDomainForType($creoleType); + + /** + * @return string The RDBMS-specific SQL fragment for NULL + * or NOT NULL. + */ + public function getNullString($notNull); + + /** + * @return The RDBMS-specific SQL fragment for autoincrement. + */ + public function getAutoIncrement(); + + /** + * Returns if the RDBMS-specific SQL type has a size attribute. + * + * @param string $sqlType the SQL type + * @return boolean True if the type has a size attribute + */ + public function hasSize($sqlType); + + /** + * Returns if the RDBMS-specific SQL type has a scale attribute. + * + * @param string $sqlType the SQL type + * @return boolean True if the type has a scale attribute + */ + public function hasScale($sqlType); + + /** + * Escape the string for RDBMS. + * @param string $text + * @return string + */ + public function escapeText($text); + + /** + * Quotes identifiers used in database SQL. + * @param string $text + * @return string Quoted identifier. + */ + public function quoteIdentifier($text); + + /** + * Whether RDBMS supports native ON DELETE triggers (e.g. ON DELETE CASCADE). + * @return boolean + */ + public function supportsNativeDeleteTrigger(); + + /** + * Returns the boolean value for the RDBMS. + * + * This value should match the boolean value that is set + * when using Creole's PreparedStatement::setBoolean(). + * + * This function is used to set default column values when building + * SQL. + * + * @param mixed $tf A boolean or string representation of boolean ('y', 'true'). + * @return mixed + */ + public function getBooleanString($tf); + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/SqlitePlatform.php b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/SqlitePlatform.php new file mode 100644 index 000000000..db1477de5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/engine/platform/SqlitePlatform.php @@ -0,0 +1,92 @@ +. + */ + +require_once 'propel/engine/platform/DefaultPlatform.php'; + +/** + * SQLite Platform implementation. + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.engine.platform + */ +class SqlitePlatform extends DefaultPlatform { + + /** + * Initializes db specific domain mapping. + */ + protected function initialize() + { + parent::initialize(); + $this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "MEDIUMTEXT")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, "DATETIME")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB")); + $this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT")); + } + + /** + * @see Platform#getAutoIncrement() + * @link http://www.sqlite.org/autoinc.html + */ + public function getAutoIncrement() + { + + return "PRIMARY KEY"; + } + + /** + * @see Platform#getMaxColumnNameLength() + */ + public function getMaxColumnNameLength() + { + return 1024; + } + + /** + * @see Platform#hasSize(String) + */ + public function hasSize($sqlType) { + return !("MEDIUMTEXT" == $sqlType || "LONGTEXT" == $sqlType + || "BLOB" == $sqlType || "MEDIUMBLOB" == $sqlType + || "LONGBLOB" == $sqlType); + } + + /** + * Escape the string for RDBMS. + * @param string $text + * @return string + */ + public function escapeText($text) { + return sqlite_escape_string($text); + } + + /** + * @see Platform::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '[' . $text . ']'; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php new file mode 100644 index 000000000..6206bce88 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php @@ -0,0 +1,635 @@ +. + */ + +//include_once 'phing/tasks/ext/CapsuleTask.php'; +require_once 'phing/Task.php'; +include_once 'propel/engine/database/model/AppData.php'; +include_once 'propel/engine/database/model/Database.php'; +include_once 'propel/engine/database/transform/XmlToAppData.php'; + +/** + * An abstract base Propel task to perform work related to the XML schema file. + * + * The subclasses invoke templates to do the actual writing of the resulting files. + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @author Daniel Rall (Torque) + * @package propel.phing + */ +abstract class AbstractPropelDataModelTask extends Task { + + /** + * Fileset of XML schemas which represent our data models. + * @var array Fileset[] + */ + protected $schemaFilesets = array(); + + /** + * Data models that we collect. One from each XML schema file. + */ + protected $dataModels = array(); + + /** + * Have datamodels been initialized? + * @var boolean + */ + private $dataModelsLoaded = false; + + /** + * Map of data model name to database name. + * Should probably stick to the convention + * of them being the same but I know right now + * in a lot of cases they won't be. + */ + protected $dataModelDbMap; + + /** + * Hashtable containing the names of all the databases + * in our collection of schemas. + */ + protected $databaseNames; // doesn't seem to be used anywhere + + /** + * The target database(s) we are generating SQL + * for. Right now we can only deal with a single + * target, but we will support multiple targets + * soon. + */ + protected $targetDatabase; + + /** + * DB encoding to use for XmlToAppData object + */ + protected $dbEncoding = 'iso-8859-1'; + + /** + * Target PHP package to place the generated files in. + */ + protected $targetPackage; + + /** + * @var Mapper + */ + protected $mapperElement; + + /** + * Destination directory for results of template scripts. + * @var PhingFile + */ + protected $outputDirectory; + + /** + * Path where Capsule looks for templates. + * @var PhingFile + */ + protected $templatePath; + + /** + * Whether to package the datamodels or not + * @var PhingFile + */ + protected $packageObjectModel; + + /** + * Whether to perform validation (XSD) on the schema.xml file(s). + * @var boolean + */ + protected $validate; + + /** + * The XSD schema file to use for validation. + * @var PhingFile + */ + protected $xsdFile; + + /** + * XSL file to use to normalize (or otherwise transform) schema before validation. + * @var PhingFile + */ + protected $xslFile; + + /** + * Return the data models that have been + * processed. + * + * @return List data models + */ + public function getDataModels() + { + if (!$this->dataModelsLoaded) $this->loadDataModels(); + return $this->dataModels; + } + + /** + * Return the data model to database name map. + * + * @return Hashtable data model name to database name map. + */ + public function getDataModelDbMap() + { + if (!$this->dataModelsLoaded) $this->loadDataModels(); + return $this->dataModelDbMap; + } + + /** + * Adds a set of xml schema files (nested fileset attribute). + * + * @param set a Set of xml schema files + */ + public function addSchemaFileset(Fileset $set) + { + $this->schemaFilesets[] = $set; + } + + /** + * Get the current target database. + * + * @return String target database(s) + */ + public function getTargetDatabase() + { + return $this->targetDatabase; + } + + /** + * Set the current target database. (e.g. mysql, oracle, ..) + * + * @param v target database(s) + */ + public function setTargetDatabase($v) + { + $this->targetDatabase = $v; + } + + /** + * Get the current target package. + * + * @return string target PHP package. + */ + public function getTargetPackage() + { + return $this->targetPackage; + } + + /** + * Set the current target package. This is where generated PHP classes will + * live. + * + * @param string $v target PHP package. + */ + public function setTargetPackage($v) + { + $this->targetPackage = $v; + } + + /** + * Set the packageObjectModel switch on/off + * + * @param string $v The build.property packageObjectModel + */ + public function setPackageObjectModel($v) + { + $this->packageObjectModel = ($v === '1' ? true : false); + } + + /** + * Set whether to perform validation on the datamodel schema.xml file(s). + * @param boolean $v + */ + public function setValidate($v) + { + $this->validate = $v; + } + + /** + * Set the XSD schema to use for validation of any datamodel schema.xml file(s). + * @param $v PhingFile + */ + public function setXsd(PhingFile $v) + { + $this->xsdFile = $v; + } + + /** + * Set the normalization XSLT to use to transform datamodel schema.xml file(s) before validation and parsing. + * @param $v PhingFile + */ + public function setXsl(PhingFile $v) + { + $this->xslFile = $v; + } + + /** + * [REQUIRED] Set the path where Capsule will look + * for templates using the file template + * loader. + * @return void + * @throws Exception + */ + public function setTemplatePath($templatePath) { + $resolvedPath = ""; + $tok = strtok($templatePath, ","); + while ( $tok ) { + // resolve relative path from basedir and leave + // absolute path untouched. + $fullPath = $this->project->resolveFile($tok); + $cpath = $fullPath->getCanonicalPath(); + if ($cpath === false) { + $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); + } else { + $resolvedPath .= $cpath; + } + $tok = strtok(","); + if ( $tok ) { + $resolvedPath .= ","; + } + } + $this->templatePath = $resolvedPath; + } + + /** + * Get the path where Velocity will look + * for templates using the file template + * loader. + * @return string + */ + public function getTemplatePath() { + return $this->templatePath; + } + + /** + * [REQUIRED] Set the output directory. It will be + * created if it doesn't exist. + * @param PhingFile $outputDirectory + * @return void + * @throws Exception + */ + public function setOutputDirectory(PhingFile $outputDirectory) { + try { + if (!$outputDirectory->exists()) { + $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE); + if (!$outputDirectory->mkdirs()) { + throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); + } + } + $this->outputDirectory = $outputDirectory->getCanonicalPath(); + } catch (IOException $ioe) { + throw new BuildException($ioe); + } + } + + /** + * Set the current target database encoding. + * + * @param v target database encoding + */ + public function setDbEncoding($v) + { + $this->dbEncoding = $v; + } + + /** + * Get the output directory. + * @return string + */ + public function getOutputDirectory() { + return $this->outputDirectory; + } + + /** + * Nested creator, creates one Mapper for this task. + * + * @return Mapper The created Mapper type object. + * @throws BuildException + */ + public function createMapper() { + if ($this->mapperElement !== null) { + throw new BuildException("Cannot define more than one mapper.", $this->location); + } + $this->mapperElement = new Mapper($this->project); + return $this->mapperElement; + } + + /** + * Maps the passed in name to a new filename & returns resolved File object. + * @param string $from + * @return PhingFile Resolved File object. + * @throws BuilException - if no Mapper element se + * - if unable to map new filename. + */ + protected function getMappedFile($from) + { + if(!$this->mapperElement) { + throw new BuildException("This task requires you to use a element to describe how filename changes should be handled."); + } + + $mapper = $this->mapperElement->getImplementation(); + $mapped = $mapper->main($from); + if (!$mapped) { + throw new BuildException("Cannot create new filename based on: " . $from); + } + // Mappers always return arrays since it's possible for some mappers to map to multiple names. + $outFilename = array_shift($mapped); + $outFile = new PhingFile($this->getOutputDirectory(), $outFilename); + return $outFile; + } + + /** + * Get the Platform class based on the target database type. + * @return Platform Class that implements the Platform interface. + */ + protected function getPlatformForTargetDatabase() + { + + $classpath = $this->getPropelProperty("platformClass"); + if (empty($classpath)) { + throw new BuildException("Unable to find class path for '$propname' property."); + } + + // This is a slight hack to workaround camel case inconsistencies for the DDL classes. + // Basically, we want to turn ?.?.?.sqliteDDLBuilder into ?.?.?.SqliteDDLBuilder + $lastdotpos = strrpos($classpath, '.'); + if ($lastdotpos) $classpath{$lastdotpos+1} = strtoupper($classpath{$lastdotpos+1}); + else ucfirst($classpath); + + if (empty($classpath)) { + throw new BuildException("Unable to find class path for '$propname' property."); + } + + $clazz = Phing::import($classpath); + return new $clazz(); + } + + /** + * Gets all matching XML schema files and loads them into data models for class. + * @return void + */ + protected function loadDataModels() + { + $ads = array(); + + // Get all matched files from schemaFilesets + foreach($this->schemaFilesets as $fs) { + $ds = $fs->getDirectoryScanner($this->project); + $srcDir = $fs->getDir($this->project); + + $dataModelFiles = $ds->getIncludedFiles(); + + $platform = $this->getPlatformForTargetDatabase(); + + // Make a transaction for each file + foreach($dataModelFiles as $dmFilename) { + + $this->log("Processing: ".$dmFilename); + $xmlFile = new PhingFile($srcDir, $dmFilename); + + $dom = new DomDocument('1.0', 'UTF-8'); + $dom->load($xmlFile->getAbsolutePath()); + + // normalize (or transform) the XML document using XSLT + if ($this->xslFile) { + $this->log("Transforming " . $xmlFile->getPath() . " using stylesheet " . $this->xslFile->getPath(), PROJECT_MSG_VERBOSE); + if (!class_exists('XSLTProcessor')) { + $this->log("Could not perform XLST transformation. Make sure PHP has been compiled/configured to support XSLT.", PROJECT_MSG_ERR); + } else { + // normalize the document using normalizer stylesheet + + $xsl = new XsltProcessor(); + $xsl->importStyleSheet(DomDocument::load($this->xslFile->getAbsolutePath())); + $transformed = $xsl->transformToDoc($dom); + $newXmlFilename = substr($xmlFile->getName(), 0, strrpos($xmlFile->getName(), '.')) . '-transformed.xml'; + + // now overwrite previous vars to point to newly transformed file + $xmlFile = new PhingFile($srcDir, $newXmlFilename); + $transformed->save($xmlFile->getAbsolutePath()); + $this->log("\t- Using new (post-transformation) XML file: " . $xmlFile->getPath(), PROJECT_MSG_VERBOSE); + + $dom = new DomDocument('1.0', 'UTF-8'); + $dom->load($xmlFile->getAbsolutePath()); + } + } + + // validate the XML document using XSD schema + if ($this->validate && $this->xsdFile) { + $this->log("Validating XML doc (".$xmlFile->getPath().") using schema file " . $this->xsdFile->getPath(), PROJECT_MSG_VERBOSE); + if (!$dom->schemaValidate($this->xsdFile->getAbsolutePath())) { + throw new BuildException("XML schema file (".$xmlFile->getPath().") does not validate. See warnings above for reasons validation failed (make sure error_reporting is set to show E_WARNING if you don't see any)."); throw new EngineException("XML schema does not validate (using schema file $xsdFile). See warnings above for reasons validation failed (make sure error_reporting is set to show E_WARNING if you don't see any).", $this->getLocation()); + } + } + + $xmlParser = new XmlToAppData($platform, $this->getTargetPackage(), $this->dbEncoding); + $ad = $xmlParser->parseFile($xmlFile->getAbsolutePath()); + $ad->setName($dmFilename); // <-- Important: use the original name, not the -transformed name. + $ads[] = $ad; + } + } + + if (empty($ads)) { + throw new BuildException("No schema files were found (matching your schema fileset definition)."); + } + + if (!$this->packageObjectModel) { + + $this->dataModels = $ads; + $this->databaseNames = array(); // doesn't seem to be used anywhere + $this->dataModelDbMap = array(); + + // Different datamodels may state the same database + // names, we just want the unique names of databases. + foreach($this->dataModels as $dm) { + $database = $dm->getDatabase(); + $this->dataModelDbMap[$dm->getName()] = $database->getName(); + $this->databaseNames[$database->getName()] = $database->getName(); // making list of *unique* dbnames. + } + } else { + + $this->joinDatamodels($ads); + $this->dataModels[0]->getDatabases(); // calls doFinalInitialization() + } + + $this->dataModelsLoaded = true; + } + + /** + * Joins the datamodels collected from schema.xml files into one big datamodel + * + * This applies only when the the packageObjectModel option is set. We need to + * join the datamodels in this case to allow for foreign keys that point to + * tables in different packages. + * + * @param array $ads The datamodels to join + */ + protected function joinDatamodels($ads) { + + foreach($ads as $ad) { + $db = $ad->getDatabase(null, false); + $this->dataModelDbMap[$ad->getName()] = $db->getName(); + } + + foreach ($ads as $addAd) { + + $ad = &$this->dataModels[0]; + if (!isset($ad)) { + $addAd->setName('JoinedDataModel'); + $ad = $addAd; + continue; + } + foreach ($addAd->getDatabases(false) as $addDb) { + $addDbName = $addDb->getName(); + if (!$package = $addDb->getPackage()) { + throw new BuildException('No package found for database "' . $addDbName . '" in ' . $addAd->getName() . '. The propel.packageObjectModel property requires the package attribute to be set for each database.'); + } + $db = $ad->getDatabase($addDbName, false); + if (!$db) { + $ad->addDatabase($addDb); + continue; + } + foreach ($addDb->getTables() as $addTable) { + $table = $db->getTable($addTable->getName()); + if ($table) { + throw new BuildException('Duplicate table found: ' . $addDbName . '.'); + } + $db->addTable($addTable); + } + } + } + } + + /** + * Creates a new Capsule context with some basic properties set. + * (Capsule is a simple PHP encapsulation system -- aka a php "template" class.) + * @return Capsule + */ + protected function createContext() { + + $context = new Capsule(); + + // Make sure the output directory exists, if it doesn't + // then create it. + $outputDir = new PhingFile($this->outputDirectory); + if (!$outputDir->exists()) { + $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath()); + $outputDir->mkdirs(); + } + + // Place our set of data models into the context along + // with the names of the databases as a convenience for now. + $context->put("targetDatabase", $this->targetDatabase); + $context->put("targetPackage", $this->targetPackage); + $context->put("now", strftime("%c")); + + $this->log("Target database type: " . $this->targetDatabase); + $this->log("Target package: " . $this->targetPackage); + $this->log("Using template path: " . $this->templatePath); + $this->log("Output directory: " . $this->outputDirectory); + + $context->setTemplatePath($this->templatePath); + $context->setOutputDirectory($this->outputDirectory); + + $this->populateContextProperties($context); + + return $context; + } + + /** + * Fetches the propel.xxx properties from project, renaming the propel.xxx properties to just xxx. + * + * Also, renames any xxx.yyy properties to xxxYyy as PHP doesn't like the xxx.yyy syntax. + * + * @return array Assoc array of properties. + */ + protected function getPropelProperties() + { + $allProps = $this->getProject()->getProperties(); + $renamedPropelProps = array(); + foreach ($allProps as $key => $propValue) { + if (strpos($key, "propel.") === 0) { + $newKey = substr($key, strlen("propel.")); + $j = strpos($newKey, '.'); + while ($j !== false) { + $newKey = substr($newKey, 0, $j) . ucfirst(substr($newKey, $j + 1)); + $j = strpos($newKey, '.'); + } + $renamedPropelProps[$newKey] = $propValue; + } + } + return $renamedPropelProps; + } + + /** + * Fetches a single propel.xxx property from project, using "converted" property names. + * @see getPropelProperties() + * @param string $name Name of property to fetch (in converted CamelCase) + * @return string The value of the property (or NULL if not set) + */ + protected function getPropelProperty($name) + { + $props = $this->getPropelProperties(); + if (isset($props[$name])) { + return $props[$name]; + } + return null; // just to be explicit + } + + /** + * Adds the propel.xxx properties to the passed Capsule context, changing names to just xxx. + * + * Also, move xxx.yyy properties to xxxYyy as PHP doesn't like the xxx.yyy syntax. + * + * @param Capsule $context + * @see getPropelProperties() + */ + public function populateContextProperties(Capsule $context) + { + foreach ($this->getPropelProperties() as $key => $propValue) { + $this->log('Adding property ${' . $key . '} to context', PROJECT_MSG_DEBUG); + $context->put($key, $propValue); + } + } + + /** + * Checks this class against Basic requrements of any propel datamodel task. + * + * @throws BuildException - if schema fileset was not defined + * - if no output directory was specified + */ + protected function validate() + { + if (empty($this->schemaFilesets)) { + throw new BuildException("You must specify a fileset of XML schemas.", $this->getLocation()); + } + + // Make sure the output directory is set. + if ($this->outputDirectory === null) { + throw new BuildException("The output directory needs to be defined!", $this->getLocation()); + } + + if ($this->validate) { + if (!$this->xsdFile) { + throw new BuildException("'validate' set to TRUE, but no XSD specified (use 'xsd' attribute).", $this->getLocation()); + } + } + + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php new file mode 100644 index 000000000..17308ce29 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php @@ -0,0 +1,777 @@ +. + */ + +include_once 'creole/Connection.php'; +require_once 'phing/Task.php'; + +/** + * This class generates an XML schema of an existing database from + * Creole metadata. + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @author Fedor Karpelevitch (Torque) + * @version $Revision: 538 $ + * @package propel.phing + */ +class PropelCreoleTransformTask extends Task { + + /** Name of XML database schema produced. */ + protected $xmlSchema; + + /** Creole URL. */ + protected $dbUrl; + + /** Creole driver. */ + protected $dbDriver; + + /** Creole user name. */ + protected $dbUser; + + /** Creole password. */ + protected $dbPassword; + + /** DB encoding to use */ + protected $dbEncoding = 'iso-8859-1'; + + /** DB schema to use. */ + protected $dbSchema; + + /** parsed DB DSN */ + protected $dsn; + + /** DOM document produced. */ + protected $doc; + + /** The document root element. */ + protected $databaseNode; + + /** Hashtable of columns that have primary keys. */ + protected $primaryKeys; + + /** Hashtable to track what table a column belongs to. */ + // doesn't seem to be used + // protected $columnTableMap; + + /** whether to use same name for phpName or not */ + protected $samePhpName; + + /** whether to add vendor info or not */ + protected $addVendorInfo; + + /** + * Bitfield to switch on/off which validators will be created. + * + * @var int + */ + protected $validatorBits; + + /** + * Collect validatorInfos to create validators. + * + * @var int + */ + protected $validatorInfos; + + /** + * Zero bit for no validators + */ + const VALIDATORS_NONE = 0; + + /** + * Bit for maxLength validator + */ + const VALIDATORS_MAXLENGTH = 1; + + /** + * Bit for maxValue validator + */ + const VALIDATORS_MAXVALUE = 2; + + /** + * Bit for type validator + */ + const VALIDATORS_TYPE = 4; + + /** + * Bit for required validator + */ + const VALIDATORS_REQUIRED = 8; + + /** + * Bit for unique validator + */ + const VALIDATORS_UNIQUE = 16; + + /** + * Bit for all validators + */ + const VALIDATORS_ALL = 255; + + /** + * Maps validator type tokens to bits + * + * The tokens are used in the propel.addValidators property to define + * which validators are to be added + * + * @static + * @var array + */ + static protected $validatorBitMap = array ( + 'none' => PropelCreoleTransformTask::VALIDATORS_NONE, + 'maxlength' => PropelCreoleTransformTask::VALIDATORS_MAXLENGTH, + 'maxvalue' => PropelCreoleTransformTask::VALIDATORS_MAXVALUE, + 'type' => PropelCreoleTransformTask::VALIDATORS_TYPE, + 'required' => PropelCreoleTransformTask::VALIDATORS_REQUIRED, + 'unique' => PropelCreoleTransformTask::VALIDATORS_UNIQUE, + 'all' => PropelCreoleTransformTask::VALIDATORS_ALL, + ); + + /** + * Defines messages that are added to validators + * + * @static + * @var array + */ + static protected $validatorMessages = array ( + 'maxlength' => array ( + 'msg' => 'The field %s must be not longer than %s characters.', + 'var' => array('colName', 'value') + ), + 'maxvalue' => array ( + 'msg' => 'The field %s must be not greater than %s.', + 'var' => array('colName', 'value') + ), + 'type' => array ( + 'msg' => 'The field %s is not a valid value.', + 'var' => array('colName') + ), + 'required' => array ( + 'msg' => 'The field %s is required.', + 'var' => array('colName') + ), + 'unique' => array ( + 'msg' => 'This %s already exists in table %s.', + 'var' => array('colName', 'tableName') + ), + ); + + public function getDbSchema() + { + return $this->dbSchema; + } + + public function setDbSchema($dbSchema) + { + $this->dbSchema = $dbSchema; + } + + public function setDbUrl($v) + { + $this->dbUrl = $v; + } + + public function setDbDriver($v) + { + $this->dbDriver = $v; + } + + public function setDbUser($v) + { + $this->dbUser = $v; + } + + public function setDbPassword($v) + { + $this->dbPassword = $v; + } + + public function setDbEncoding($v) + { + $this->dbEncoding = $v; + } + + public function setOutputFile($v) + { + $this->xmlSchema = $v; + } + + public function setSamePhpName($v) + { + $this->samePhpName = $v; + } + + public function setAddVendorInfo($v) + { + $this->addVendorInfo = (boolean) $v; + } + + /** + * Sets set validator bitfield from propel.addValidators property + * + * @param string $v The propel.addValidators property + * @return void + */ + public function setAddValidators($v) + { + // lowercase input + $v = strtolower($v); + // make it a bit expression + $v = str_replace( + array_keys(self::$validatorBitMap), self::$validatorBitMap, $v); + // check if it's a valid boolean expression + if (!preg_match('/[^\d|&~ ]/', $v)) { + // eval the expression + eval("\$v = $v;"); + } else { + $this->log("\n\nERROR: NO VALIDATORS ADDED!\n\nThere is an error in propel.addValidators build property.\n\nAllowed tokens are: " . implode(', ', array_keys(self::$validatorBitMap)) . "\n\nAllowed operators are (like in php.ini):\n\n| bitwise OR\n& bitwise AND\n~ bitwise NOT\n\n", PROJECT_MSG_ERR); + $v = self::VALIDATORS_NONE; + } + $this->validatorBits = $v; + } + + public function isSamePhpName() + { + return $this->samePhpName; + } + + /** + * Default constructor. + * @return void + * @throws BuildException + */ + public function main() + { + $this->log("Propel - CreoleToXMLSchema starting"); + $this->log("Your DB settings are:"); + $this->log("driver : " . ($this->dbDriver ? $this->dbDriver : "(default)")); + $this->log("URL : " . $this->dbUrl); + + //(not yet supported) $this->log("schema : " . $this->dbSchema); + //DocumentTypeImpl docType = new DocumentTypeImpl(null, "database", null, + // "http://jakarta.apache.org/turbine/dtd/database.dtd"); + + $this->doc = new DOMDocument('1.0', 'utf-8'); + $this->doc->formatOutput = true; // pretty printing + + $this->doc->appendChild($this->doc->createComment("Autogenerated by CreoleToXMLSchema!")); + + try { + $this->generateXML(); + $this->log("Writing XML to file: " . $this->xmlSchema); + $outFile = new PhingFile($this->xmlSchema); + $out = new FileWriter($outFile); + $xmlstr = $this->doc->saveXML(); + $out->write($xmlstr); + $out->close(); + } catch (Exception $e) { + $this->log("There was an error building XML from metadata: " . $e->getMessage(), PROJECT_MSG_ERR); + } + $this->log("Propel - CreoleToXMLSchema finished"); + } + + /** + * Generates an XML database schema from Creole metadata. + * + * @return void + * @throws Exception a generic exception. + */ + public function generateXML() + { + // Establish db connection + $con = $this->getConnection(); + + // Get the database Metadata. + $dbInfo = $con->getDatabaseInfo(); + + // create and add the database node + $databaseNode = $this->createDatabaseNode($dbInfo); + $this->doc->appendChild($databaseNode); + } + + /** + * Establishes a Creole database connection + * + * @return object The connection + */ + protected function getConnection() { + + // Attemtp to connect to a database. + $this->dsn = Creole::parseDSN($this->dbUrl); + if($this->dbUser) { + $this->dsn["username"] = $this->dbUser; + } + if ($this->dbPassword) { + $this->dsn["password"] = $this->dbPassword; + } + if ($this->dbDriver) { + Creole::registerDriver($this->dsn['phptype'], $this->dbDriver); + } + $con = Creole::getConnection($this->dsn); + $this->log("DB connection established"); + + return $con; + } + + /** + * Creates a database node + * + * @param object $dbInfo The dbInfo for this db + * @return object The database node instance + */ + protected function createDatabaseNode($dbInfo) { + + $this->log("Processing database"); + + $node = $this->doc->createElement("database"); + $node->setAttribute("name", $dbInfo->getName()); + + if ($vendorNode = $this->createVendorInfoNode($dbInfo->getVendorSpecificInfo())) { + $node->appendChild($vendorNode); + } + + // create and add table nodes + foreach($dbInfo->getTables() as $table) { + $tableNode = $this->createTableNode($table); + $node->appendChild($tableNode); + } + + return $node; + } + + /** + * Creates a table node + * + * @param object $table The table + * @return object The table node instance + */ + protected function createTableNode($table) { + + $this->log("Processing table: " . $table->toString()); + + $node = $this->doc->createElement("table"); + $node->setAttribute("name", $table->getName()); + if ($this->isSamePhpName()) { + $node->setAttribute("phpName", $table->getName()); + } + if ($vendorNode = $this->createVendorInfoNode($table->getVendorSpecificInfo())) { + $node->appendChild($vendorNode); + } + + // Create and add column nodes, register column validators + $columns = $table->getColumns(); + foreach($columns as $column) { + $columnNode = $this->createColumnNode($column); + $node->appendChild($columnNode); + $this->registerValidatorsForColumn($column); + if ($column->isAutoIncrement()) { + $idMethod = 'native'; + } + } + if (isset($idMethod)) { + $node->setAttribute("idMethod", $idMethod); + } + + // Create and add foreign key nodes. + $foreignKeys = $table->getForeignKeys(); + foreach($foreignKeys as $foreignKey) { + $foreignKeyNode = $this->createForeignKeyNode($foreignKey); + $node->appendChild($foreignKeyNode); + } + + // Create and add index nodes. + $indices = $table->getIndices(); + foreach($indices as $index) { + $indexNode = $this->createIndexNode($index); + $node->appendChild($indexNode); + } + + // add an id-method-parameter if we have a sequence that matches table_colname_seq + // + // + $pkey = $table->getPrimaryKey(); + if ($pkey) { + $cols = $pkey->getColumns(); + if (count($cols) === 1) { + $col = array_shift($cols); + if ($col->isAutoIncrement()) { + $seq_name = $table->getName().'_'.$col->getName().'_seq'; + if ($table->getDatabase()->isSequence($seq_name)) { + $idMethodParameterNode = $this->doc->createElement("id-method-parameter"); + $idMethodParameterNode->setAttribute("value", $seq_name); + $node->appendChild($idMethodParameterNode); + } + } + } + } + + + // Create and add validator and rule nodes. + $nodes = array(); + $tableName = $table->getName(); + if (isset($this->validatorInfos[$tableName])) { + foreach ($this->validatorInfos[$tableName] as $colName => $rules) { + $column = $table->getColumn($colName); + $colName = $column->getName(); + foreach ($rules as $rule) { + if (!isset($nodes[$colName])) { + $nodes[$colName] = $this->createValidator($column, $rule['type']); + $node->appendChild($nodes[$colName]); + } + $ruleNode = $this->createRuleNode($column, $rule); + $nodes[$colName]->appendChild($ruleNode); + } + } + } + + return $node; + } + + /** + * Creates an column node + * + * @param object $column The Creole column + * @return object The column node instance + */ + protected function createColumnNode($column) { + + $node = $this->doc->createElement("column"); + + $table = $column->getTable(); + $colName = $column->getName(); + $colType = $column->getType(); + $colSize = $column->getSize(); + $colScale = $column->getScale(); + + if ($colType === CreoleTypes::OTHER) { + $this->log("Column [" . $table->getName() . "." . $colName . "] has a column type (".$column->getNativeType().") that Propel does not support.", PROJECT_MSG_WARN); + } + + $node->setAttribute("name", $colName); + + if ($this->isSamePhpName()) { + $node->setAttribute("phpName", $colName); + } + + $node->setAttribute("type", PropelTypes::getPropelType($colType)); + + if ($colSize > 0 && ( + $colType == CreoleTypes::CHAR + || $colType == CreoleTypes::VARCHAR + || $colType == CreoleTypes::LONGVARCHAR + || $colType == CreoleTypes::DECIMAL + || $colType == CreoleTypes::FLOAT + || $colType == CreoleTypes::NUMERIC)) { + $node->setAttribute("size", (string) $colSize); + } + + if ($colScale > 0 && ( + $colType == CreoleTypes::DECIMAL + || $colType == CreoleTypes::FLOAT + || $colType == CreoleTypes::NUMERIC)) { + $node->setAttribute("scale", (string) $colScale); + } + + if (!$column->isNullable()) { + $node->setAttribute("required", "true"); + } + + if ($column->isAutoIncrement()) { + $node->setAttribute("autoIncrement", "true"); + } + + if (in_array($colName, $this->getTablePkCols($table))) { + $node->setAttribute("primaryKey", "true"); + } + + if (($defValue = $column->getDefaultValue()) !== null) { + $node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue)); + } + + if ($vendorNode = $this->createVendorInfoNode($column->getVendorSpecificInfo())) { + $node->appendChild($vendorNode); + } + + return $node; + } + + /** + * Returns the primary key columns for a table + * + * @param object $table The table + * @return array The primary keys + */ + protected function getTablePkCols($table) { + + static $columns = array(); + + $tableName = $table->getName(); + if (!isset($columns[$tableName])) { + $columns[$tableName] = array(); + $primaryKey = $table->getPrimaryKey(); + if ($primaryKey) { + foreach($primaryKey->getColumns() as $colObject) { + $columns[$tableName][] = $colObject->getName(); + } + } + } + return $columns[$tableName]; + } + + /** + * Creates an foreign key node + * + * @param object $foreignKey The foreign key + * @return object The foreign key node instance + */ + protected function createForeignKeyNode($foreignKey) { + + $node = $this->doc->createElement("foreign-key"); + if ($vendorNode = $this->createVendorInfoNode($foreignKey->getVendorSpecificInfo())) { + $node->appendChild($vendorNode); + } + + $refs = $foreignKey->getReferences(); + // all references must be to same table, so we can grab table from the first, foreign column + $node->setAttribute("foreignTable", $refs[0][1]->getTable()->getName()); + $node->setAttribute("onDelete", $refs[0][2]); + $node->setAttribute("onUpdate", $refs[0][3]); + for($m = 0, $size = count($refs); $m < $size; $m++) { + $refNode = $this->doc->createElement("reference"); + $refData = $refs[$m]; + $refNode->setAttribute("local", $refData[0]->getName()); + $refNode->setAttribute("foreign", $refData[1]->getName()); + $node->appendChild($refNode); + } + + return $node; + } + + /** + * Creates an index node + * + * @param object $index The index + * @return object The index node instance + */ + protected function createIndexNode($index) { + + $indexType = $index->isUnique() ? 'unique' : 'index'; + + $node = $this->doc->createElement($indexType); + $node->setAttribute("name", $index->getName()); + + $columns = $index->getColumns(); + foreach ($columns as $column) { + $tableName = $column->getTable()->getName(); + $colName = $column->getName(); + $columnNode = $this->doc->createElement("{$indexType}-column"); + $columnNode->setAttribute("name", $colName); + $node->appendChild($columnNode); + if ($indexType == 'unique' && $this->isValidatorRequired('unique')) { + $this->validatorInfos[$tableName][$colName][] = array('type' => 'unique'); + } + } + + if ($vendorNode = $this->createVendorInfoNode($index->getVendorSpecificInfo())) { + $node->appendChild($vendorNode); + } + + return $node; + } + + /** + * Checks whether to add validators of specified type or not + * + * @param string $type The validator type + * @return boolean + */ + protected function isValidatorRequired($type) { + $type = strtolower($type); + return ($this->validatorBits & self::$validatorBitMap[$type] ? true : false); + } + + /** + * Registers column type specific validators if necessary + * + * We'll first collect the validators/rule infos and add them later on to + * have them appended to the table tag as a block. + * + * CreoleTypes are: + * + * BOOLEAN + * BIGINT, SMALLINT, TINYINT, INTEGER + * FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL + * BIGINT, SMALLINT, TINYINT, INTEGER + * TEXT + * BLOB, CLOB, BINARY, VARBINARY, LONGVARBINARY + * DATE, YEAR, TIME + * TIMESTAMP + * + * We will add the following type specific validators: + * + * for notNull columns: required validator + * for unique indexes: unique validator + * for varchar types: maxLength validators (CHAR, VARCHAR, LONGVARCHAR) + * for numeric types: maxValue validators (BIGINT, SMALLINT, TINYINT, INTEGER, FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL) + * for integer and timestamp types: notMatch validator with [^\d]+ (BIGINT, SMALLINT, TINYINT, INTEGER, TIMESTAMP) + * for float types: notMatch validator with [^\d\.]+ (FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL) + * + * @param object $column The Creole column + * @return void + * @todo find out how to evaluate the appropriate size and adjust maxValue rule values appropriate + * @todo find out if float type column values must always notMatch('[^\d\.]+'), i.e. digits and point for any db vendor, language etc. + */ + protected function registerValidatorsForColumn($column) { + + $table = $column->getTable(); + $tableName = $table->getName(); + + $colName = $column->getName(); + $colType = $column->getType(); + $colSize = $column->getSize(); + + if ($this->isValidatorRequired('required')) { + $ruleInfo = array('type' => 'required'); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + $isPrimarykeyCol = in_array($colName, $this->getTablePkCols($table)); + if ($this->isValidatorRequired('unique') && $isPrimarykeyCol) { + $ruleInfo = array('type' => 'unique'); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + if ($this->isValidatorRequired('maxLength') && + $colSize > 0 && in_array($colType, array( + CreoleTypes::CHAR, + CreoleTypes::VARCHAR, + CreoleTypes::LONGVARCHAR))) { + $ruleInfo = array('type' => 'maxLength', 'value' => $colSize); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + if ($this->isValidatorRequired('maxValue') && + $colSize > 0 && in_array($colType, array( + CreoleTypes::SMALLINT, + CreoleTypes::TINYINT, + CreoleTypes::INTEGER, + CreoleTypes::BIGINT, + CreoleTypes::FLOAT, + CreoleTypes::DOUBLE, + CreoleTypes::NUMERIC, + CreoleTypes::DECIMAL, + CreoleTypes::REAL))) { + + // TODO: how to evaluate the appropriate size?? + $this->log("WARNING: maxValue validator added for column $colName. You will have to adjust the size value manually.", PROJECT_MSG_WARN); + $ruleInfo = array('type' => 'maxValue', 'value' => $colSize); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + if ($this->isValidatorRequired('type') && + $colSize > 0 && in_array($colType, array( + CreoleTypes::SMALLINT, + CreoleTypes::TINYINT, + CreoleTypes::INTEGER, + CreoleTypes::TIMESTAMP))) { + $ruleInfo = array('type' => 'type', 'value' => '[^\d]+'); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + if ($this->isValidatorRequired('type') && + $colSize > 0 && in_array($colType, array( + CreoleTypes::FLOAT, + CreoleTypes::DOUBLE, + CreoleTypes::NUMERIC, + CreoleTypes::DECIMAL, + CreoleTypes::REAL))) { + // TODO: is this always true?? + $ruleInfo = array('type' => 'type', 'value' => '[^\d\.]+'); + $this->validatorInfos[$tableName][$colName][] = $ruleInfo; + } + } + + /** + * Creates a validator node + * + * @param object $column The Creole column + * @param integer $type The validator type + * @return object The validator node instance + */ + protected function createValidator($column, $type) { + + $node = $this->doc->createElement('validator'); + $node->setAttribute('column', $column->getName()); + + return $node; + } + + /** + * Creates a rule node + * + * @param object $column The Creole column + * @param array $rule The rule info + * @return object The rule node instance + */ + protected function createRuleNode($column, $rule) { + + extract($rule); + + // create message + $colName = $column->getName(); + $tableName = $column->getTable()->getName(); + $msg = self::$validatorMessages[strtolower($rule)]; + array_unshift($tmp = compact($msg['var']), $msg['msg']); + $msg = call_user_func_array('sprintf', $tmp); + + // add node + $node = $this->doc->createElement('rule'); + $node->setAttribute('name', $rule == 'type' ? 'notMatch' : $rule); + $node->setAttribute('message', $msg); + + return $node; + } + + /** + * Creates a vendor info node + * + * returns false if no vendor info can or has to be added + * + * @param array $vendorInfo The validator info + * @return object|boolean The vendor info instance or false + */ + protected function createVendorInfoNode($vendorInfo) + { + if(!$vendorInfo OR !$this->addVendorInfo) { + return false; + } + + $vendorNode = $this->doc->createElement("vendor"); + $vendorNode->setAttribute("type", $this->dsn["phptype"]); + + foreach($vendorInfo as $key => $value) { + $parameterNode = $this->doc->createElement("parameter"); + $value = iconv($this->dbEncoding, "utf-8", $value); + $parameterNode->setAttribute("name", $key); + $parameterNode->setAttribute("value", $value); + $vendorNode->appendChild($parameterNode); + } + + return $vendorNode; + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDTDTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDTDTask.php new file mode 100644 index 000000000..411c18cad --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDTDTask.php @@ -0,0 +1,80 @@ +. + */ + +require_once 'propel/phing/AbstractPropelDataModelTask.php'; +include_once 'propel/engine/builder/om/ClassTools.php'; + +/** + * This Task creates the OM classes based on the XML schema file. + * + * @author Hans Lellelid + * @package propel.phing + */ +class PropelDataDTDTask extends AbstractPropelDataModelTask { + + + public function main() { + + // check to make sure task received all correct params + $this->validate(); + + if(!$this->mapperElement) { + throw new BuildException("You must use a element to describe how names should be transformed."); + } + + $basepath = $this->getOutputDirectory(); + + // Get new Capsule context + $generator = $this->createContext(); + $generator->put("basepath", $basepath); // make available to other templates + + // we need some values that were loaded into the template context + $basePrefix = $generator->get('basePrefix'); + $project = $generator->get('project'); + + foreach ($this->getDataModels() as $dataModel) { + + $this->log("Processing Datamodel : " . $dataModel->getName()); + + foreach ($dataModel->getDatabases() as $database) { + + $outFile = $this->getMappedFile($dataModel->getName()); + + $generator->put("tables", $database->getTables()); + $generator->parse("data/dtd/dataset.tpl", $outFile->getAbsolutePath()); + + $this->log("Generating DTD for database: " . $database->getName()); + $this->log("Creating DTD file: " . $outFile->getPath()); + + foreach ($database->getTables() as $tbl) { + $this->log("\t + " . $tbl->getName()); + $generator->put("table", $tbl); + $generator->parse("data/dtd/table.tpl", $outFile->getAbsolutePath(), true); + } + + } // foreach database + + } // foreach dataModel + + + } // main() +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDumpTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDumpTask.php new file mode 100644 index 000000000..315f32ea0 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataDumpTask.php @@ -0,0 +1,383 @@ +. + */ + +include_once 'creole/Creole.php'; + +/** + * Dumps the contenst of selected databases to XML data dump file. + * + * The generated XML files can have corresponding DTD files generated using the + * PropelDataDTDTask. The results of the data dump can be converted to SQL using + * the PropelDataSQLTask class. + * + * The database may be specified (via 'databaseName' attribute) if you only want to dump + * the contents of one database. Otherwise it is assumed that all databases described + * by datamodel schema file(s) will be dumped. + * + * @author Hans Lellelid (Propel) + * @author Fedor Karpelevitch (Torque) + * @author Jason van Zyl (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.phing + */ +class PropelDataDumpTask extends AbstractPropelDataModelTask { + + /** + * Database name. + * The database name may be optionally specified in the XML if you only want + * to dump the contents of one database. + */ + private $databaseName; + + /** + * Database URL used for Creole connection. + * This is a PEAR-compatible (loosely) DSN URL. + */ + private $databaseUrl; + + /** + * Database driver used for Creole connection. + * This should normally be left blank so that default (Creole built-in) driver for database type is used. + */ + private $databaseDriver; + + /** + * Database user used for Creole connection. + * @deprecated Put username in databaseUrl. + */ + private $databaseUser; + + /** + * Database password used for Creole connection. + * @deprecated Put password in databaseUrl. + */ + private $databasePassword; + + /** + * Properties file that maps a data XML file to a particular database. + * @var PhingFile + */ + private $datadbmap; + + /** + * The database connection used to retrieve the data to dump. + * Needs to be public so that the TableInfo class can access it. + */ + public $conn; + + /** + * The statement used to acquire the data to dump. + */ + private $stmt; + + /** + * Set the file that maps between data XML files and databases. + * + * @param PhingFile $sqldbmap the db map + * @return void + */ + public function setDataDbMap(PhingFile $datadbmap) + { + $this->datadbmap = $datadbmap; + } + + /** + * Get the file that maps between data XML files and databases. + * + * @return PhingFile $datadbmap. + */ + public function getDataDbMap() + { + return $this->datadbmap; + } + + /** + * Get the database name to dump + * + * @return The DatabaseName value + */ + public function getDatabaseName() + { + return $this->databaseName; + } + + /** + * Set the database name + * + * @param v The new DatabaseName value + */ + public function setDatabaseName($v) + { + $this->databaseName = $v; + } + + /** + * Get the database url + * + * @return The DatabaseUrl value + */ + public function getDatabaseUrl() + { + return $this->databaseUrl; + } + + /** + * Set the database url + * + * @param string $v The PEAR-compatible database DSN URL. + */ + public function setDatabaseUrl($v) + { + $this->databaseUrl = $v; + } + + /** + * Get the database user + * + * @return string database user + * @deprecated + */ + public function getDatabaseUser() + { + return $this->databaseUser; + } + + /** + * Set the database user + * + * @param string $v The new DatabaseUser value + * @deprecated Specify user in DSN URL. + */ + public function setDatabaseUser($v) + { + $this->databaseUser = $v; + } + + /** + * Get the database password + * + * @return string database password + */ + public function getDatabasePassword() + { + return $this->databasePassword; + } + + /** + * Set the database password + * + * @param string $v The new DatabasePassword value + * @deprecated Specify database password in DSN URL. + */ + public function setDatabasePassword($v) + { + $this->databasePassword = $v; + } + + /** + * Get the database driver name + * + * @return string database driver name + */ + public function getDatabaseDriver() + { + return $this->databaseDriver; + } + + /** + * Set the database driver name + * + * @param string $v The new DatabaseDriver value + */ + public function setDatabaseDriver($v) + { + $this->databaseDriver = $v; + } + + /** + * Create the data XML -> database map. + * + * This is necessary because there is currently no other method of knowing which + * data XML files correspond to which database. This map allows us to convert multiple + * data XML files into SQL. + * + * @throws IOException - if unable to store properties + */ + private function createDataDbMap() + { + if ($this->getDataDbMap() === null) { + return; + } + + // Produce the sql -> database map + $datadbmap = new Properties(); + + // Check to see if the sqldbmap has already been created. + if ($this->getDataDbMap()->exists()) { + $datadbmap->load($this->getDataDbMap()); + } + + foreach ($this->getDataModels() as $dataModel) { // there is really one 1 db per datamodel + foreach ($dataModel->getDatabases() as $database) { + + // if database name is specified, then we only want to dump that one db. + if (empty($this->databaseName) || ($this->databaseName && $database->getName() == $this->databaseName)) { + $outFile = $this->getMappedFile($dataModel->getName()); + $datadbmap->setProperty($outFile->getName(), $database->getName()); + } + } + } + + try { + $datadbmap->store($this->getDataDbMap(), "Data XML file -> Database map"); + } catch (IOException $e) { + throw new IOException("Unable to store properties: ". $e->getMessage()); + } + } + + /** + * Iterates through each datamodel/database, dumps the contents of all tables and creates a DOM XML doc. + * + * @return void + * @throws BuildException + */ + public function main() + { + $this->validate(); + + $buf = "Database settings:\n" + . " driver: " . ($this->databaseDriver ? $this->databaseDriver : "(default)" ). "\n" + . " URL: " . $this->databaseUrl . "\n" + . ($this->databaseUser ? " user: " . $this->databaseUser . "\n" : "") // deprecated + . ($this->databasePassword ? " password: " . $this->databasePassword . "\n" : ""); // deprecated + + $this->log($buf, PROJECT_MSG_VERBOSE); + + // 1) First create the Data XML -> database name map. + $this->createDataDbMap(); + + // 2) Now go create the XML files from teh database(s) + foreach ($this->getDataModels() as $dataModel) { // there is really one 1 db per datamodel + foreach ($dataModel->getDatabases() as $database) { + + // if database name is specified, then we only want to dump that one db. + if (empty($this->databaseName) || ($this->databaseName && $database->getName() == $this->databaseName)) { + + $outFile = $this->getMappedFile($dataModel->getName()); + + $this->log("Dumping data to XML for database: " . $database->getName()); + $this->log("Writing to XML file: " . $outFile->getName()); + + try { + + $url = str_replace("@DB@", $database->getName(), $this->databaseUrl); + + $buf = "Database settings:\n" + . " driver: " . ($this->databaseDriver ? $this->databaseDriver : "(default)" ). "\n" + . " URL: " . $url . "\n" + . ($this->databaseUser ? " user: " . $this->databaseUser . "\n" : "") + . ($this->databasePassword ? " password: " . $this->databasePassword . "\n" : ""); + + $this->log($buf, PROJECT_MSG_VERBOSE); + + $dsn = Creole::parseDSN($url); + + // deprecated, but here for BC + if ($this->databaseUser) { + $dsn['username'] = $this->databaseUser; + } + + if ($this->databasePassword) { + $dsn['password'] = $this->databasePassword; + } + + if ($this->databaseName) { + $dsn['database'] = $this->databaseName; + } + + if ($this->databaseDriver) { + Creole::registerDriver($dsn['phptype'], $this->databaseDriver); + } + + $this->conn = Creole::getConnection($dsn); + + $doc = $this->createXMLDoc($database); + $doc->save($outFile->getAbsolutePath()); + + } catch (SQLException $se) { + $this->log("SQLException while connecting to DB: ". $se->getMessage(), PROJECT_MSG_ERR); + throw new BuildException($se); + } + } // if databaseName && database->getName == databaseName + } // foreach database + } // foreach datamodel + } + + /** + * Gets ResultSet of query to fetch all data from a table. + * @param string $tableName + * @return ResultSet + */ + private function getTableDataRS($tableName) { + // Set Statement object in associated PropelDataDump + // instance. + return $this->conn->createStatement()->executeQuery("SELECT * FROM " . $this->getPlatformForTargetDatabase()->quoteIdentifier ( $tableName ) ); + } + + /** + * Creates a DOM document containing data for specified database. + * @param Database $database + * @return DOMDocument + */ + private function createXMLDoc(Database $database) { + + $doc = new DOMDocument('1.0', 'utf-8'); + $doc->formatOutput = true; // pretty printing + $doc->appendChild($doc->createComment("Created by data/dump/Control.tpl template.")); + + $dsNode = $doc->createElement("dataset"); + $dsNode->setAttribute("name", "all"); + $doc->appendChild($dsNode); + + $this->log("Building DOM tree containing data from tables:"); + + foreach ($database->getTables() as $tbl) { + $this->log("\t+ " . $tbl->getName()); + $rs = $this->getTableDataRS($tbl->getName()); + while ($rs->next()) { + $rowNode = $doc->createElement($tbl->getPhpName()); + foreach ($tbl->getColumns() as $col) { + $cval = $rs->get($col->getName()); + if ($cval !== null) { + $rowNode->setAttribute($col->getPhpName(), iconv($this->dbEncoding, 'utf-8', $cval)); + } + } + $dsNode->appendChild($rowNode); + unset($rowNode); + } + $rs->close(); + } + + return $doc; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataModelTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataModelTask.php new file mode 100644 index 000000000..083da04da --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataModelTask.php @@ -0,0 +1,131 @@ +. + */ + +require_once 'propel/phing/AbstractPropelDataModelTask.php'; +include_once 'propel/engine/database/model/AppData.php'; +include_once 'propel/engine/database/model/Database.php'; +include_once 'propel/engine/database/transform/XmlToAppData.php'; + +/** + * A generic class that simply loads the data model and parses a control template. + * + * This class exists largely for compatibility with early Propel where this was + * a CapsuleTask subclass. This class also makes it easy to quickly add some custom + * datamodel-based transformations (by allowing you to put the logic in the templates). + * + * @author Hans Lellelid + * @package propel.phing + * @version $Revision: 536 $ + */ +class PropelDataModelTask extends AbstractPropelDataModelTask { + + /** + * This is the file where the generated text + * will be placed. + * @var string + */ + protected $outputFile; + + /** + * This is the control template that governs the output. + * It may or may not invoke the services of worker + * templates. + * @var string + */ + protected $controlTemplate; + + + /** + * [REQUIRED] Set the output file for the + * generation process. + * @param string $outputFile (TODO: change this to File) + * @return void + */ + public function setOutputFile($outputFile) { + $this->outputFile = $outputFile; + } + + /** + * Get the output file for the + * generation process. + * @return string + */ + public function getOutputFile() { + return $this->outputFile; + } + + /** + * [REQUIRED] Set the control template for the + * generating process. + * @param string $controlTemplate + * @return void + */ + public function setControlTemplate ($controlTemplate) { + $this->controlTemplate = $controlTemplate; + } + + /** + * Get the control template for the + * generating process. + * @return string + */ + public function getControlTemplate() { + return $this->controlTemplate; + } + + protected function validate() + { + parent::validate(); + + // Make sure the control template is set. + if ($this->controlTemplate === null) { + throw new BuildException("The control template needs to be defined!"); + } + // Make sure there is an output file. + if ($this->outputFile === null) { + throw new BuildException("The output file needs to be defined!"); + } + + } + + /** + * Creates Capsule context and parses control template. + * @return void + */ + public function main() + { + $this->validate(); + $context = $this->createContext(); + + $context->put("dataModels", $this->getDataModels()); + + $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; + $this->log("Generating to file " . $path); + + try { + $this->log("Parsing control template: " . $this->controlTemplate); + $context->parse($this->controlTemplate, $path); + } catch (Exception $ioe) { + throw new BuildException("Cannot write parsed template: ". $ioe->getMessage()); + } + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataSQLTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataSQLTask.php new file mode 100644 index 000000000..26f4784b4 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelDataSQLTask.php @@ -0,0 +1,219 @@ +. + */ + +include_once 'propel/engine/database/model/AppData.php'; +include_once 'propel/engine/database/model/Database.php'; +include_once 'propel/engine/database/transform/XmlToAppData.php'; +include_once 'propel/engine/database/transform/XmlToData.php'; + +/** + * Task that transforms XML datadump files into files containing SQL INSERT statements. + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @author John McNally (Torque) + * @author Fedor Karpelevitch (Torque) + * @version $Revision: 536 $ + * @package propel.phing + */ +class PropelDataSQLTask extends AbstractPropelDataModelTask { + + /** + * Properties file that maps an SQL file to a particular database. + * @var PhingFile + */ + private $sqldbmap; + + /** + * Properties file that maps a data XML file to a particular database. + * @var PhingFile + */ + private $datadbmap; + + /** + * The base directory in which to find data XML files. + * @var PhingFile + */ + private $srcDir; + + /** + * Set the file that maps between SQL files and databases. + * + * @param PhingFile $sqldbmap the sql -> db map. + * @return void + */ + public function setSqlDbMap(PhingFile $sqldbmap) + { + $this->sqldbmap = $sqldbmap; + } + + /** + * Get the file that maps between SQL files and databases. + * + * @return PhingFile sqldbmap. + */ + public function getSqlDbMap() + { + return $this->sqldbmap; + } + + /** + * Set the file that maps between data XML files and databases. + * + * @param PhingFile $sqldbmap the db map + * @return void + */ + public function setDataDbMap(PhingFile $datadbmap) + { + $this->datadbmap = $datadbmap; + } + + /** + * Get the file that maps between data XML files and databases. + * + * @return PhingFile $datadbmap. + */ + public function getDataDbMap() + { + return $this->datadbmap; + } + + /** + * Set the src directory for the data xml files listed in the datadbmap file. + * @param PhingFile $srcDir data xml source directory + */ + public function setSrcDir(PhingFile $srcDir) + { + $this->srcDir = $srcDir; + } + + /** + * Get the src directory for the data xml files listed in the datadbmap file. + * + * @return PhingFile data xml source directory + */ + public function getSrcDir() + { + return $this->srcDir; + } + + /** + * Search through all data models looking for matching database. + * @return Database or NULL if none found. + */ + private function getDatabase($name) + { + foreach($this->getDataModels() as $dm) { + foreach($dm->getDatabases() as $db) { + if ($db->getName() == $name) { + return $db; + } + } + } + } + + /** + * Main method parses the XML files and creates SQL files. + * + * @return void + * @throws Exception If there is an error parsing the data xml. + */ + public function main() + { + $this->validate(); + + $targetDatabase = $this->getTargetDatabase(); + + $platform = $this->getPlatformForTargetDatabase(); + + // Load the Data XML -> DB Name properties + $map = new Properties(); + try { + $map->load($this->getDataDbMap()); + } catch (IOException $ioe) { + throw new BuildException("Cannot open and process the datadbmap!", $ioe); + } + + DataModelBuilder::setBuildProperties($this->getPropelProperties()); + + // Parse each file in teh data -> db map + + foreach($map->keys() as $dataXMLFilename) { + + $dataXMLFile = new PhingFile($this->srcDir, $dataXMLFilename); + + // if file exists then proceed + if ($dataXMLFile->exists()) { + + $dbname = $map->get($dataXMLFilename); + + $db = $this->getDatabase($dbname); + + if (!$db) { + throw new BuildException("Cannot find instantiated Database for name '$dbname' from datadbmap file."); + } + + $db->setPlatform($platform); + + $outFile = $this->getMappedFile($dataXMLFilename); + + $this->log("Creating SQL from XML data dump file: " . $dataXMLFile->getAbsolutePath()); + + try { + $dataXmlParser = new XmlToData($db, $this->dbEncoding); + $data = $dataXmlParser->parseFile($dataXMLFile->getAbsolutePath()); + } catch (Exception $e) { + throw new Exception("Exception parsing data XML: " . $e->getMessage()); + } + + $fp = fopen($outFile->getAbsolutePath(), 'w'); + + $currTable = null; + foreach ($data as $dataRow) { + if ($currTable !== $dataRow->getTable()) { + $currTable = $dataRow->getTable(); + $builder = DataModelBuilder::builderFactory($currTable, 'datasql'); + } + $sql = $builder->buildRowSql($dataRow); + fwrite($fp, $sql); + } + + fclose($fp); + + // Place the generated SQL file(s) + $p = new Properties(); + if ($this->getSqlDbMap()->exists()) { + $p->load($this->getSqlDbMap()); + } + + $p->setProperty($outFile->getName(), $db->getName()); + $p->store($this->getSqlDbMap(), "Sqlfile -> Database map"); + + } else { + $this->log("File '" . $dataXMLFile->getAbsolutePath() + . "' in datadbmap does not exist, so skipping it.", PROJECT_MSG_WARN); + } + + } // foreach data xml file + + } // main() +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelGraphvizTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelGraphvizTask.php new file mode 100644 index 000000000..0bc0c507a --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelGraphvizTask.php @@ -0,0 +1,177 @@ +. + */ + +include_once 'propel/engine/database/model/AppData.php'; +//require_once 'phing/Task.php'; + +/** + * A task to generate Graphviz png images from propel datamodel. + * + * @author Mark Kimsal + * @version $Revision: 536 $ + * @package propel.phing + */ +class PropelGraphvizTask extends AbstractPropelDataModelTask { + + /** + * The properties file that maps an SQL file to a particular database. + * @var PhingFile + */ + private $sqldbmap; + + /** + * Name of the database. + */ + private $database; + + /** + * Name of the output directory. + */ + private $outDir; + + + /** + * Set the sqldbmap. + * @param PhingFile $sqldbmap The db map. + */ + public function setOutputDirectory(PhingFile $out) + { + if (!$out->exists()) { + $out->mkdirs(); + } + $this->outDir = $out; + } + + + /** + * Set the sqldbmap. + * @param PhingFile $sqldbmap The db map. + */ + public function setSqlDbMap(PhingFile $sqldbmap) + { + $this->sqldbmap = $sqldbmap; + } + + /** + * Get the sqldbmap. + * @return PhingFile $sqldbmap. + */ + public function getSqlDbMap() + { + return $this->sqldbmap; + } + + /** + * Set the database name. + * @param string $database + */ + public function setDatabase($database) + { + $this->database = $database; + } + + /** + * Get the database name. + * @return string + */ + public function getDatabase() + { + return $this->database; + } + + + public function main() + { + + $count = 0; + + $dotSyntax = ''; + + // file we are going to create + + $dbMaps = $this->getDataModelDbMap(); + + foreach ($this->getDataModels() as $dataModel) { + + $dotSyntax .= "digraph G {\n"; + foreach ($dataModel->getDatabases() as $database) { + + $this->log("db: " . $database->getName()); + + //print the tables + foreach($database->getTables() as $tbl) { + + $this->log("\t+ " . $tbl->getName()); + + ++$count; + $dotSyntax .= 'node'.$tbl->getName().' [label="{'.$tbl->getName().'|'; + + foreach ($tbl->getColumns() as $col) { + $dotSyntax .= $col->getName() . ' (' . $col->getType() . ')'; + if ($col->getForeignKey() != null ) { + $dotSyntax .= ' [FK]'; + } elseif ($col->isPrimaryKey()) { + $dotSyntax .= ' [PK]'; + } + $dotSyntax .= '\l'; + } + $dotSyntax .= '}", shape=record];'; + $dotSyntax .= "\n"; + } + + //print the relations + + $count = 0; + $dotSyntax .= "\n"; + foreach($database->getTables() as $tbl) { + ++$count; + + foreach ($tbl->getColumns() as $col) { + $fk = $col->getForeignKey(); + if ( $fk == null ) continue; + $dotSyntax .= 'node'.$tbl->getName() .':cols -> node'.$fk->getForeignTableName() . ':table [label="' . $col->getName() . '=' . implode(',', $fk->getForeignColumns()) . ' "];'; + $dotSyntax .= "\n"; + } + } + + + + } // foreach database + $dotSyntax .= "}\n"; + + $this->writeDot($dotSyntax,$this->outDir); + + } //foreach datamodels + + } // main() + + + /** + * probably insecure + */ + function writeDot($dotSyntax, PhingFile $outputDir) { + $file = new PhingFile($outputDir, 'schema.dot'); + $this->log("Writing dot file to " . $file->getAbsolutePath()); + file_put_contents($file->getAbsolutePath(), $dotSyntax); + } + +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOMTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOMTask.php new file mode 100644 index 000000000..e97b02703 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOMTask.php @@ -0,0 +1,212 @@ +. + */ + +require_once 'propel/phing/AbstractPropelDataModelTask.php'; +include_once 'propel/engine/builder/om/ClassTools.php'; +require_once 'propel/engine/builder/om/OMBuilder.php'; + +/** + * This Task creates the OM classes based on the XML schema file. + * + * @author Hans Lellelid + * @package propel.phing + */ +class PropelOMTask extends AbstractPropelDataModelTask { + + /** + * The platform (php4, php5, etc.) for which the om is being built. + * @var string + */ + private $targetPlatform; + + /** + * Sets the platform (php4, php5, etc.) for which the om is being built. + * @param string $v + */ + public function setTargetPlatform($v) { + $this->targetPlatform = $v; + } + + /** + * Gets the platform (php4, php5, etc.) for which the om is being built. + * @return string + */ + public function getTargetPlatform() { + return $this->targetPlatform; + } + + /** + * Utility method to create directory for package if it doesn't already exist. + * @param string $path The [relative] package path. + * @throws BuildException - if there is an error creating directories + */ + protected function ensureDirExists($path) + { + $f = new PhingFile($this->getOutputDirectory(), $path); + if (!$f->exists()) { + if (!$f->mkdirs()) { + throw new BuildException("Error creating directories: ". $f->getPath()); + } + } + } + + /** + * Uses a builder class to create the output class. + * This method assumes that the DataModelBuilder class has been initialized with the build properties. + * @param OMBuilder $builder + * @param boolean $overwrite Whether to overwrite existing files with te new ones (default is YES). + * @todo -cPropelOMTask Consider refactoring build() method into AbstractPropelDataModelTask (would need to be more generic). + */ + protected function build(OMBuilder $builder, $overwrite = true) + { + + $path = $builder->getClassFilePath(); + $this->ensureDirExists(dirname($path)); + + $_f = new PhingFile($this->getOutputDirectory(), $path); + if ($overwrite || !$_f->exists()) { + $this->log("\t\t-> " . $builder->getClassname() . " [builder: " . get_class($builder) . "]"); + $script = $builder->build(); + file_put_contents($_f->getAbsolutePath(), $script); + foreach($builder->getWarnings() as $warning) { + $this->log($warning, PROJECT_MSG_WARN); + } + } else { + $this->log("\t\t-> (exists) " . $builder->getClassname()); + } + + } + + /** + * Main method builds all the targets for a typical propel project. + */ + public function main() + { + // check to make sure task received all correct params + $this->validate(); + + $basepath = $this->getOutputDirectory(); + + // Get new Capsule context + $generator = $this->createContext(); + $generator->put("basepath", $basepath); // make available to other templates + + $targetPlatform = $this->getTargetPlatform(); // convenience for embedding in strings below + + // we need some values that were loaded into the template context + $basePrefix = $generator->get('basePrefix'); + $project = $generator->get('project'); + + DataModelBuilder::setBuildProperties($this->getPropelProperties()); + + foreach ($this->getDataModels() as $dataModel) { + $this->log("Processing Datamodel : " . $dataModel->getName()); + + foreach ($dataModel->getDatabases() as $database) { + + $this->log(" - processing database : " . $database->getName()); + $generator->put("platform", $database->getPlatform()); + + + foreach ($database->getTables() as $table) { + + if (!$table->isForReferenceOnly()) { + + $this->log("\t+ " . $table->getName()); + + // ----------------------------------------------------------------------------------------- + // Create Peer, Object, and MapBuilder classes + // ----------------------------------------------------------------------------------------- + + // these files are always created / overwrite any existing files + foreach(array('peer', 'object', 'mapbuilder') as $target) { + $builder = DataModelBuilder::builderFactory($table, $target); + $this->build($builder); + } + + // ----------------------------------------------------------------------------------------- + // Create [empty] stub Peer and Object classes if they don't exist + // ----------------------------------------------------------------------------------------- + + // these classes are only generated if they don't already exist + foreach(array('peerstub', 'objectstub') as $target) { + $builder = DataModelBuilder::builderFactory($table, $target); + $this->build($builder, $overwrite=false); + } + + // ----------------------------------------------------------------------------------------- + // Create [empty] stub child Object classes if they don't exist + // ----------------------------------------------------------------------------------------- + + // If table has enumerated children (uses inheritance) then create the empty child stub classes if they don't already exist. + if ($table->getChildrenColumn()) { + $col = $table->getChildrenColumn(); + if ($col->isEnumeratedClasses()) { + foreach ($col->getChildren() as $child) { + $builder = DataModelBuilder::builderFactory($table, 'objectmultiextend'); + $builder->setChild($child); + $this->build($builder, $overwrite=false); + } // foreach + } // if col->is enumerated + } // if tbl->getChildrenCol + + + // ----------------------------------------------------------------------------------------- + // Create [empty] Interface if it doesn't exist + // ----------------------------------------------------------------------------------------- + + // Create [empty] interface if it does not already exist + if ($table->getInterface()) { + $builder = DataModelBuilder::builderFactory($table, 'interface'); + $this->build($builder, $overwrite=false); + } + + // ----------------------------------------------------------------------------------------- + // Create tree Node classes + // ----------------------------------------------------------------------------------------- + + if ($table->isTree()) { + + foreach(array('nodepeer', 'node') as $target) { + $builder = DataModelBuilder::builderFactory($table, $target); + $this->build($builder); + } + + foreach(array('nodepeerstub', 'nodestub') as $target) { + $builder = DataModelBuilder::builderFactory($table, $target); + $this->build($builder, $overwrite=false); + } + + } // if Table->isTree() + + + } // if !$table->isForReferenceOnly() + + } // foreach table + + } // foreach database + + } // foreach dataModel + + + } // main() +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldOMTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldOMTask.php new file mode 100644 index 000000000..28581f547 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldOMTask.php @@ -0,0 +1,236 @@ +. + */ + +require_once 'propel/phing/AbstractPropelDataModelTask.php'; +include_once 'propel/engine/builder/om/ClassTools.php'; + +/** + * This Task creates the OM classes based on the XML schema file using the legacy templates. + * + * @author Hans Lellelid + * @package propel.phing + * @deprecated + */ +class PropelOldOMTask extends AbstractPropelDataModelTask { + + /** + * The platform (php4, php5, etc.) for which the om is being built. + * @var string + */ + private $targetPlatform; + + /** + * Sets the platform (php4, php5, etc.) for which the om is being built. + * @param string $v + */ + public function setTargetPlatform($v) { + $this->targetPlatform = $v; + } + + /** + * Gets the platform (php4, php5, etc.) for which the om is being built. + * @return string + */ + public function getTargetPlatform() { + return $this->targetPlatform; + } + + public function main() { + + // check to make sure task received all correct params + $this->validate(); + + $basepath = $this->getOutputDirectory(); + + // Get new Capsule context + $generator = $this->createContext(); + $generator->put("basepath", $basepath); // make available to other templates + + $targetPlatform = $this->getTargetPlatform(); // convenience for embedding in strings below + + // we need some values that were loaded into the template context + $basePrefix = $generator->get('basePrefix'); + $project = $generator->get('project'); + + foreach ($this->getDataModels() as $dataModel) { + $this->log("Processing Datamodel : " . $dataModel->getName()); + + foreach ($dataModel->getDatabases() as $database) { + + $this->log(" - processing database : " . $database->getName()); + $generator->put("platform", $database->getPlatform()); + + + foreach ($database->getTables() as $table) { + + if (!$table->isForReferenceOnly()) { + if ($table->getPackage()) { + $package = $table->getPackage(); + } else { + $package = $this->targetPackage; + } + + $pkbase = "$package.om"; + $pkpeer = "$package"; + $pkmap = "$package.map"; + + // make these available + $generator->put("package", $package); + $generator->put("pkbase", $pkbase); + //$generator->put("pkpeer", $pkpeer); -- we're not using this yet + $generator->put("pkmap", $pkmap); + + foreach(array($pkpeer, $pkmap, $pkbase) as $pk) { + $path = strtr($pk, '.', '/'); + $f = new PhingFile($this->getOutputDirectory(), $path); + if (!$f->exists()) { + if (!$f->mkdirs()) { + throw new Exception("Error creating directories: ". $f->getPath()); + } + } + } // for each package + + + $this->log("\t+ " . $table->getName()); + + $generator->put("table", $table); + + // Create the Base Peer class + $this->log("\t\t-> " . $basePrefix . $table->getPhpName() . "Peer"); + $path = ClassTools::getFilePath($pkbase, $basePrefix . $table->getPhpName() . "Peer"); + $generator->parse("om/$targetPlatform/Peer.tpl", $path); + + // Create the Base object class + $this->log("\t\t-> " . $basePrefix . $table->getPhpName()); + $path = ClassTools::getFilePath($pkbase, $basePrefix . $table->getPhpName()); + $generator->parse("om/$targetPlatform/Object.tpl", $path); + + if ($table->isTree()) { + // Create the Base NodePeer class + $this->log("\t\t-> " . $basePrefix . $table->getPhpName() . "NodePeer"); + $path = ClassTools::getFilePath($pkbase, $basePrefix . $table->getPhpName() . "NodePeer"); + $generator->parse("om/$targetPlatform/NodePeer.tpl", $path); + + // Create the Base Node class if the table is a tree + $this->log("\t\t-> " . $basePrefix . $table->getPhpName() . "Node"); + $path = ClassTools::getFilePath($pkbase, $basePrefix . $table->getPhpName() . "Node"); + $generator->parse("om/$targetPlatform/Node.tpl", $path); + } + + // Create MapBuilder class if this table is not an alias + if (!$table->isAlias()) { + $this->log("\t\t-> " . $table->getPhpName() . "MapBuilder"); + $path = ClassTools::getFilePath($pkmap, $table->getPhpName() . "MapBuilder"); + $generator->parse("om/$targetPlatform/MapBuilder.tpl", $path); + } // if !$table->isAlias() + + // Create [empty] stub Peer class if it does not already exist + $path = ClassTools::getFilePath($package, $table->getPhpName() . "Peer"); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + $this->log("\t\t-> " . $table->getPhpName() . "Peer"); + $generator->parse("om/$targetPlatform/ExtensionPeer.tpl", $path); + } else { + $this->log("\t\t-> (exists) " . $table->getPhpName() . "Peer"); + } + + // Create [empty] stub object class if it does not already exist + $path = ClassTools::getFilePath($package, $table->getPhpName()); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + $this->log("\t\t-> " . $table->getPhpName()); + $generator->parse("om/$targetPlatform/ExtensionObject.tpl", $path); + } else { + $this->log("\t\t-> (exists) " . $table->getPhpName()); + } + + if ($table->isTree()) { + // Create [empty] stub Node Peer class if it does not already exist + $path = ClassTools::getFilePath($package, $table->getPhpName() . "NodePeer"); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + $this->log("\t\t-> " . $table->getPhpName() . "NodePeer"); + $generator->parse("om/$targetPlatform/ExtensionNodePeer.tpl", $path); + } else { + $this->log("\t\t-> (exists) " . $table->getPhpName() . "NodePeer"); + } + + // Create [empty] stub Node class if it does not already exist + $path = ClassTools::getFilePath($package, $table->getPhpName() . "Node"); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + $this->log("\t\t-> " . $table->getPhpName() . "Node"); + $generator->parse("om/$targetPlatform/ExtensionNode.tpl", $path); + } else { + $this->log("\t\t-> (exists) " . $table->getPhpName() . "Node"); + } + } + + // Create [empty] interface if it does not already exist + if ($table->getInterface()) { + $path = ClassTools::getFilePath($table->getInterface()); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + + $_dir = new PhingFile(dirname($_f->getAbsolutePath())); + $_dir->mkdirs(); + + $this->log("\t\t-> " . $table->getInterface()); + $generator->parse("om/$targetPlatform/Interface.tpl", $path); + + } else { + $this->log("\t\t-> (exists) " . $table->getInterface()); + } + } + + // If table has enumerated children (uses inheritance) then create the empty child stub classes + // if they don't already exist. + if ($table->getChildrenColumn()) { + $col = $table->getChildrenColumn(); + if ($col->isEnumeratedClasses()) { + foreach ($col->getChildren() as $child) { + $childpkg = ($child->getPackage() ? $child->getPackage() : $package); + $generator->put("child", $child); + $generator->put("package", $childpkg); + $path = ClassTools::getFilePath($childpkg, $child->getClassName()); + $_f = new PhingFile($basepath, $path); + if (!$_f->exists()) { + $this->log("\t\t-> " . $child->getClassName()); + $generator->parse("om/$targetPlatform/MultiExtendObject.tpl", $path); + } else { + $this->log("\t\t-> (exists) " . $child->getClassName()); + } + } // foreach + } // if col->is enumerated + } // if tbl->getChildrenCol + + } // if !$table->isForReferenceOnly() + + } // foreach table + + } // foreach database + + } // foreach dataModel + + + } // main() +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldSQLTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldSQLTask.php new file mode 100644 index 000000000..be60092b9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelOldSQLTask.php @@ -0,0 +1,287 @@ +. + */ + +include_once 'propel/engine/database/model/AppData.php'; + +/** + * An extended Capsule task used for generating SQL source from an XML schema describing a database structure. + * + * This is deprecated; the new PropelSQLTask should be used instead. + * + * @author Hans Lellelid (Propel) + * @author Jason van Zyl (Torque) + * @author John McNally (Torque) + * @version $Revision: 536 $ + * @package propel.phing + * @deprecated + */ +class PropelOldSQLTask extends AbstractPropelDataModelTask { + + /** + * The properties file that maps an SQL file to a particular database. + * @var PhingFile + */ + private $sqldbmap; + + /** + * Name of the database. + */ + private $database; + + /** + * Set the sqldbmap. + * @param PhingFile $sqldbmap The db map. + */ + public function setSqlDbMap(PhingFile $sqldbmap) + { + $this->sqldbmap = $sqldbmap; + } + + /** + * Get the sqldbmap. + * @return PhingFile $sqldbmap. + */ + public function getSqlDbMap() + { + return $this->sqldbmap; + } + + /** + * Set the database name. + * @param string $database + */ + public function setDatabase($database) + { + $this->database = $database; + } + + /** + * Get the database name. + * @return string + */ + public function getDatabase() + { + return $this->database; + } + + /** + * Create the sql -> database map. + * + * @throws IOException - if unable to store properties + */ + private function createSqlDbMap() + { + if ($this->getSqlDbMap() === null) { + return; + } + + // Produce the sql -> database map + $sqldbmap = new Properties(); + + // Check to see if the sqldbmap has already been created. + if ($this->getSqlDbMap()->exists()) { + $sqldbmap->load($this->getSqlDbMap()); + } + + if ($this->packageObjectModel) { + // in this case we'll get the sql file name from the package attribute + $dataModels = $this->packageDataModels(); + foreach ($dataModels as $package => $dataModel) { + foreach ($dataModel->getDatabases() as $database) { + $name = ($package ? $package . '.' : '') . 'schema.xml'; + $sqlFile = $this->getMappedFile($name); + $sqldbmap->setProperty($sqlFile->getName(), $database->getName()); + } + } + } else { + // the traditional way is to map the schema.xml filenames + $dmMap = $this->getDataModelDbMap(); + foreach(array_keys($dmMap) as $dataModelName) { + $sqlFile = $this->getMappedFile($dataModelName); + if ($this->getDatabase() === null) { + $databaseName = $dmMap[$dataModelName]; + } else { + $databaseName = $this->getDatabase(); + } + $sqldbmap->setProperty($sqlFile->getName(), $databaseName); + } + } + + try { + $sqldbmap->store($this->getSqlDbMap(), "Sqlfile -> Database map"); + } catch (IOException $e) { + throw new IOException("Unable to store properties: ". $e->getMessage()); + } + } + + public function main() { + + $this->validate(); + + if(!$this->mapperElement) { + throw new BuildException("You must use a element to describe how names should be transformed."); + } + + if ($this->packageObjectModel) { + $dataModels = $this->packageDataModels(); + } else { + $dataModels = $this->getDataModels(); + } + + // 1) first create a map of filenames to databases; this is used by other tasks like + // the SQLExec task. + $this->createSqlDbMap(); + + // 2) Now actually create the DDL based on the datamodel(s) from XML schema file. + $targetDatabase = $this->getTargetDatabase(); + + $basepath = "sql/base/$targetDatabase"; + + $generator = $this->createContext(); + $generator->put("basepath", $basepath); // make available to sub-templates + + + $fname = "sql/base/$targetDatabase/table.tpl" ; + // $generator->put("fname", $fname); // make available to sub-templates + + $fnamekeys= "sql/base/$targetDatabase/tablefk.tpl"; + //$generator->put("fnamekeys", $fnamekeys); // make available to sub-templates + + $ddlStartFile = new PhingFile($this->getTemplatePath(), "sql/base/$targetDatabase/database-start.tpl"); + $ddlEndFile = new PhingFile($this->getTemplatePath(), "sql/base/$targetDatabase/database-end.tpl"); + + foreach ($dataModels as $package => $dataModel) { + + foreach ($dataModel->getDatabases() as $database) { + + // file we are going to create + if (!$this->packageObjectModel) { + $name = $dataModel->getName(); + } else { + $name = ($package ? $package . '.' : '') . 'schema.xml'; + } + $outFile = $this->getMappedFile($name); + + $generator->put("database", $database); // make available to sub-templates + $generator->put("platform", $database->getPlatform()); + + $this->log("Generating SQL tables for database: " . $database->getName()); + + $this->log("Writing to SQL file: " . $outFile->getPath()); + + + // this variable helps us overwrite the first time we write to file + // and then append thereafter + $append=false; + + // First check to see if there is a "header" SQL file + if ($ddlStartFile->exists()) { + $generator->parse($ddlStartFile->getAbsolutePath(), $outFile->getAbsolutePath(), false); + $append = true; + } + + foreach($database->getTables() as $tbl) { + if (!$tbl->isSkipSql()) { + $this->log("\t + " . $tbl->getName()); + $generator->put("table", $tbl); + $generator->parse($fname, $outFile->getAbsolutePath(), $append); + if ($append === false) $append = true; + } else { + $this->log("\t + (skipping) " . $tbl->getName()); + } + } // foreach database->getTables() + + foreach ($database->getTables() as $tbl) { + if (!$tbl->isSkipSql()) { + $generator->put("tablefk", $tbl); + $generator->parse($fnamekeys, $outFile->getAbsolutePath(), true); // always append + } + } + + // Finally check to see if there is a "footer" SQL file + if ($ddlEndFile->exists()) { + $generator->parse($ddlEndFile->getAbsolutePath(), $outFile->getAbsolutePath(), true); + } + + } // foreach database + } //foreach datamodels + + } // main() + + /** + * Packages the datamodels to one datamodel per package + * + * This applies only when the the packageObjectModel option is set. We need to + * re-package the datamodels to allow the database package attribute to control + * which tables go into which SQL file. + * + * @return array The packaged datamodels + */ + protected function packageDataModels() { + + static $packagedDataModels; + + if (is_null($packagedDataModels)) { + + $dataModels = $this->getDataModels(); + $dataModel = array_shift($dataModels); + $packagedDataModels = array(); + + $platform = $this->getPlatformForTargetDatabase(); + + foreach ($dataModel->getDatabases() as $db) { + foreach ($db->getTables() as $table) { + $package = $table->getPackage(); + if (!isset($packagedDataModels[$package])) { + $dbClone = $this->cloneDatabase($db); + $dbClone->setPackage($package); + $ad = new AppData($platform); + $ad->setName($dataModel->getName()); + $ad->addDatabase($dbClone); + $packagedDataModels[$package] = $ad; + } + $packagedDataModels[$package]->getDatabase($db->getName())->addTable($table); + } + } + } + + return $packagedDataModels; + } + + protected function cloneDatabase($db) { + + $attributes = array ( + 'name' => $db->getName(), + 'baseClass' => $db->getBaseClass(), + 'basePeer' => $db->getBasePeer(), + //'defaultPhpType' => $db->getDefaultPhpType(), + 'defaultIdMethod' => $db->getDefaultIdMethod(), + 'defaultPhpNamingMethod' => $db->getDefaultPhpNamingMethod(), + 'defaultTranslateMethod' => $db->getDefaultTranslateMethod(), + //'heavyIndexing' => $db->getHeavyIndexing(), + ); + + $clone = new Database(); + $clone->loadFromXML($attributes); + return $clone; + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLExec.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLExec.php new file mode 100644 index 000000000..76dbb8cfe --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLExec.php @@ -0,0 +1,681 @@ +. + */ + +require_once 'phing/Task.php'; +include_once 'creole/Connection.php'; + +/** + * Executes all SQL files referenced in the sqldbmap file against their mapped databases. + * + * This task uses an SQL -> Database map in the form of a properties + * file to insert each SQL file listed into its designated database. + * + * @author Hans Lellelid + * @author Dominik del Bondio + * @author Jeff Martin (Torque) + * @author Michael McCallum (Torque) + * @author Tim Stephenson (Torque) + * @author Jason van Zyl (Torque) + * @author Martin Poeschl (Torque) + * @version $Revision: 536 $ + * @package propel.phing + */ +class PropelSQLExec extends Task { + + private $goodSql = 0; + private $totalSql = 0; + + const DELIM_ROW = "row"; + const DELIM_NORMAL = "normal"; + + /** + * The delimiter type indicating whether the delimiter will + * only be recognized on a line by itself + */ + private $delimiterType = "normal"; // can't use constant just defined + + //private static $delimiterTypes = array(DELIM_NORMAL, DELIM_ROW); + //private static $errorActions = array("continue", "stop", "abort"); + + /** Database connection */ + private $conn = null; + + /** Autocommit flag. Default value is false */ + private $autocommit = false; + + /** SQL statement */ + private $statement = null; + + /** DB driver. */ + private $driver = null; + + /** DB url. */ + private $url = null; + + /** User name. */ + private $userId = null; + + /** Password */ + private $password = null; + + /** SQL input command */ + private $sqlCommand = ""; + + /** SQL transactions to perform */ + private $transactions = array(); + + /** SQL Statement delimiter */ + private $delimiter = ";"; + + /** Print SQL results. */ + private $print = false; + + /** Print header columns. */ + private $showheaders = true; + + /** Results Output file. */ + private $output = null; + + /** RDBMS Product needed for this SQL. */ + private $rdbms = null; + + /** RDBMS Version needed for this SQL. */ + private $version = null; + + /** Action to perform if an error is found */ + private $onError = "abort"; + + /** Encoding to use when reading SQL statements from a file */ + private $encoding = null; + + /** Src directory for the files listed in the sqldbmap. */ + private $srcDir; + + /** Properties file that maps an individual SQL file to a database. */ + private $sqldbmap; + + /** + * Set the sqldbmap properties file. + * + * @param sqldbmap filename for the sqldbmap + */ + public function setSqlDbMap($sqldbmap) + { + $this->sqldbmap = $this->project->resolveFile($sqldbmap); + } + + /** + * Get the sqldbmap properties file. + * + * @return filename for the sqldbmap + */ + public function getSqlDbMap() + { + return $this->sqldbmap; + } + + /** + * Set the src directory for the sql files listed in the sqldbmap file. + * + * @param PhingFile $srcDir sql source directory + */ + public function setSrcDir(PhingFile $srcDir) + { + $this->srcDir = $srcDir; + } + + /** + * Get the src directory for the sql files listed in the sqldbmap file. + * + * @return PhingFile SQL Source directory + */ + public function getSrcDir() + { + return $this->srcDir; + } + + /** + * Set the sql command to execute + * + * @param sql sql command to execute + */ + public function addText($sql) + { + $this->sqlCommand .= $sql; + } + + /** + * Set the Creole driver to be used. + * + * @param string $driver driver class name + */ + public function setDriver($driver) + { + $this->driver = $driver; + } + + /** + * Set the DB connection url. + * + * @param string $url connection url + */ + public function setUrl($url) + { + $this->url = $url; + } + + /** + * Set the user name for the DB connection. + * + * @param string $userId database user + * @deprecated Specify userid in the DSN URL. + */ + public function setUserid($userId) + { + $this->userId = $userId; + } + + /** + * Set the password for the DB connection. + * + * @param string $password database password + * @deprecated Specify password in the DSN URL. + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * Set the autocommit flag for the DB connection. + * + * @param boolean $autocommit the autocommit flag + */ + public function setAutoCommit($autocommit) + { + $this->autocommit = (boolean) $autocommit; + } + + /** + * Set the statement delimiter. + * + *

    For example, set this to "go" and delimitertype to "ROW" for + * Sybase ASE or MS SQL Server.

    + * + * @param string $delimiter + */ + public function setDelimiter($delimiter) + { + $this->delimiter = $delimiter; + } + + /** + * Set the Delimiter type for this sql task. The delimiter type takes two + * values - normal and row. Normal means that any occurence of the delimiter + * terminate the SQL command whereas with row, only a line containing just + * the delimiter is recognized as the end of the command. + * + * @param string $delimiterType + */ + public function setDelimiterType($delimiterType) + { + $this->delimiterType = $delimiterType; + } + + /** + * Set the print flag. + * + * @param boolean $print + */ + public function setPrint($print) + { + $this->print = (boolean) $print; + } + + /** + * Set the showheaders flag. + * + * @param boolean $showheaders + */ + public function setShowheaders($showheaders) + { + $this->showheaders = (boolean) $showheaders; + } + + /** + * Set the output file. + * + * @param PhingFile $output + */ + public function setOutput(PhingFile $output) + { + $this->output = $output; + } + + /** + * Set the action to perform onerror + * + * @param string $action + */ + public function setOnerror($action) + { + $this->onError = $action; + } + + /** + * Load the sql file and then execute it + * + * @throws BuildException + */ + public function main() + { + $this->sqlCommand = trim($this->sqlCommand); + + if ($this->sqldbmap === null || $this->getSqlDbMap()->exists() === false) { + throw new BuildException("You haven't provided an sqldbmap, or " + . "the one you specified doesn't exist: " . $this->sqldbmap->getPath()); + } + + if ($this->url === null) { + throw new BuildException("DSN url attribute must be set!"); + } + + $map = new Properties(); + + try { + $map->load($this->getSqlDbMap()); + } catch (IOException $ioe) { + throw new BuildException("Cannot open and process the sqldbmap!"); + } + + $databases = array(); + + foreach($map->keys() as $sqlfile) { + + $database = $map->getProperty($sqlfile); + + // Q: already there? + if (!isset($databases[$database])) { + // A: No. + $databases[$database] = array(); + } + + // We want to make sure that the base schemas + // are inserted first. + if (strpos($sqlfile, "schema.sql") !== false) { + // add to the beginning of the array + array_unshift($databases[$database], $sqlfile); + } else { + array_push($databases[$database], $sqlfile); + } + } + + foreach($databases as $db => $files) { + $transactions = array(); + + foreach($files as $fileName) { + + $file = new PhingFile($this->srcDir, $fileName); + + if ($file->exists()) { + $this->log("Executing statements in file: " . $file->__toString()); + $transaction = new PropelSQLExecTransaction($this); + $transaction->setSrc($file); + $transactions[] = $transaction; + } else { + $this->log("File '" . $file->__toString() + . "' in sqldbmap does not exist, so skipping it."); + } + } + $this->insertDatabaseSqlFiles($this->url, $db, $transactions); + } + } + + /** + * Take the base url, the target database and insert a set of SQL + * files into the target database. + * + * @param string $url + * @param string $database + * @param array $transactions + */ + private function insertDatabaseSqlFiles($url, $database, $transactions) + { + $url = str_replace("@DB@", $database, $url); + $this->log("Our new url -> " . $url); + + try { + + $buf = "Database settings:\n" + . " driver: " . ($this->driver ? $this->driver : "(default)" ). "\n" + . " URL: " . $url . "\n" + . ($this->userId ? " user: " . $this->userId . "\n" : "") + . ($this->password ? " password: " . $this->password . "\n" : ""); + + $this->log($buf, PROJECT_MSG_VERBOSE); + + $dsn = Creole::parseDSN($url); + + if($this->userId) { + $dsn["username"] = $this->userId; + } + if ($this->password) { + $dsn["password"] = $this->password; + } + if ($this->driver) { + Creole::registerDriver($dsn['phptype'], $this->driver); + } + + $this->conn = Creole::getConnection($dsn); + + $this->conn->setAutoCommit($this->autocommit); + $this->statement = $this->conn->createStatement(); + + $out = null; + + try { + if ($this->output !== null) { + $this->log("Opening PrintStream to output file " . $this->output->__toString(), PROJECT_MSG_VERBOSE); + $out = new FileWriter($this->output); + } + + // Process all transactions + for ($i=0,$size=count($transactions); $i < $size; $i++) { + $transactions[$i]->runTransaction($out); + if (!$this->autocommit) { + $this->log("Commiting transaction", PROJECT_MSG_VERBOSE); + $this->conn->commit(); + } + } + } catch (Exception $e) { + if ($out) $out->close(); + } + + } catch (IOException $e) { + + if (!$this->autocommit && $this->conn !== null && $this->onError == "abort") { + try { + $this->conn->rollback(); + } catch (SQLException $ex) { + // do nothing. + System::println("Rollback failed."); + } + } + if ($this->statement) $this->statement->close(); + throw new BuildException($e); + } catch (SQLException $e) { + if (!$this->autocommit && $this->conn !== null && $this->onError == "abort") { + try { + $this->conn->rollback(); + } catch (SQLException $ex) { + // do nothing. + System::println("Rollback failed"); + } + } + if ($this->statement) $this->statement->close(); + throw new BuildException($e); + } + + $this->statement->close(); + + $this->log($this->goodSql . " of " . $this->totalSql + . " SQL statements executed successfully"); + } + + /** + * Read the statements from the .sql file and execute them. + * Lines starting with '//', '--' or 'REM ' are ignored. + * + * Developer note: must be public in order to be called from + * sudo-"inner" class PropelSQLExecTransaction. + * + * @param Reader $reader + * @param $out Optional output stream. + * @throws SQLException + * @throws IOException + */ + public function runStatements(Reader $reader, $out = null) + { + $sql = ""; + $line = ""; + $sqlBacklog = ""; + $hasQuery = false; + + $in = new BufferedReader($reader); + + try { + while (($line = $in->readLine()) !== null) { + $line = trim($line); + $line = ProjectConfigurator::replaceProperties($this->project, $line, + $this->project->getProperties()); + + if (StringHelper::startsWith("//", $line) || + StringHelper::startsWith("--", $line) || + StringHelper::startsWith("#", $line)) { + continue; + } + + if (strlen($line) > 4 + && strtoupper(substr($line,0, 4)) == "REM ") { + continue; + } + + if($sqlBacklog !== "") + { + $sql = $sqlBacklog; + $sqlBacklog = ""; + } + + $sql .= " " . $line . "\n"; + + // SQL defines "--" as a comment to EOL + // and in Oracle it may contain a hint + // so we cannot just remove it, instead we must end it + if (strpos($line, "--") !== false) { + $sql .= "\n"; + } + + // DELIM_ROW doesn't need this (as far as i can tell) + if($this->delimiterType == self::DELIM_NORMAL) { + + $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#"; + + $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE); + $sqlBacklog = ""; + foreach($sqlParts as $sqlPart) { + // we always want to append, even if it's a delim (which will be stripped off later) + $sqlBacklog .= $sqlPart; + + // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query + if($sqlPart === $this->delimiter) { + $sql = $sqlBacklog; + $sqlBacklog = ""; + $hasQuery = true; + } + } + } + + if ($hasQuery || ($this->delimiterType == self::DELIM_ROW && $line == $this->delimiter)) { + // this assumes there is always a delimter on the end of the SQL statement. + $sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter)); + $this->log("SQL: " . $sql, PROJECT_MSG_VERBOSE); + $this->execSQL($sql, $out); + $sql = ""; + $hasQuery = false; + } + } + + // Catch any statements not followed by ; + if ($sql !== "") { + $this->execSQL($sql, $out); + } + } catch (SQLException $e) { + throw $e; + } + } + + /** + * Exec the sql statement. + * + * @param sql + * @param out + * @throws SQLException + */ + protected function execSQL($sql, $out = null) + { + // Check and ignore empty statements + if (trim($sql) == "") { + return; + } + + try { + $this->totalSql++; + if (!$this->statement->execute($sql)) { + $this->log($this->statement->getUpdateCount() . " rows affected", + PROJECT_MSG_VERBOSE); + } else { + if ($this->print) { + $this->printResults($out); + } + } + + $this->goodSql++; + + } catch (SQLException $e) { + $this->log("Failed to execute: " . $sql, PROJECT_MSG_ERR); + if ($this->onError != "continue") { + throw $e; + } + $this->log($e->getMessage(), PROJECT_MSG_ERR); + } + } + + /** + * print any results in the statement. + * + * @param out + * @throws SQLException + */ + protected function printResults($out = null) + { + $rs = null; + + do { + $rs = $this->statement->getResultSet(); + + if ($rs !== null) { + + $this->log("Processing new result set.", PROJECT_MSG_VERBOSE); + + $line = ""; + + $colsprinted = false; + + while ($rs->next()) { + + if (!$colsprinted && $this->showheaders) { + $first = true; + foreach($this->fields as $fieldName => $ignore) { + if ($first) $first = false; else $line .= ","; + $line .= $fieldName; + } + } // if show headers + + $first = true; + foreach($rs->fields as $columnValue) { + + if ($columnValue != null) { + $columnValue = trim($columnValue); + } + + if ($first) { + $first = false; + } else { + $line .= ","; + } + $line .= $columnValue; + } + + if ($out !== null) { + $out->write($line); + $out->newLine(); + } + + System::println($line); + $line = ""; + } // while rs->next() + } + } while ($this->statement->getMoreResults()); + System::println(); + if ($out !== null) $out->newLine(); + } + +} + +/** + * "Inner" class that contains the definition of a new transaction element. + * Transactions allow several files or blocks of statements + * to be executed using the same Creole connection and commit + * operation in between. + * @package propel.phing + */ +class PropelSQLExecTransaction { + + private $tSrcFile = null; + private $tSqlCommand = ""; + private $parent; + + function __construct($parent) + { + // Parent is required so that we can log things ... + $this->parent = $parent; + } + + public function setSrc(PhingFile $src) + { + $this->tSrcFile = $src; + } + + public function addText($sql) + { + $this->tSqlCommand .= $sql; + } + + /** + * @throws IOException, SQLException + */ + public function runTransaction($out = null) + { + if (!empty($this->tSqlCommand)) { + $this->parent->log("Executing commands", PROJECT_MSG_INFO); + $this->parent->runStatements($tSqlCommand, $out); + } + + if ($this->tSrcFile !== null) { + $this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(), + PROJECT_MSG_INFO); + $reader = new FileReader($this->tSrcFile); + $this->parent->runStatements($reader, $out); + $reader->close(); + } + } +} diff --git a/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLTask.php b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLTask.php new file mode 100644 index 000000000..651e536b7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/classes/propel/phing/PropelSQLTask.php @@ -0,0 +1,258 @@ +. + */ + +include_once 'propel/engine/database/model/AppData.php'; + +/** + * The task for building SQL DDL based on the XML datamodel. + * + * This class uses the new DDLBuilder classes instead of the Capsule PHP templates. + * + * @author Hans Lellelid + * @package propel.phing + */ +class PropelSQLTask extends AbstractPropelDataModelTask { + + /** + * The properties file that maps an SQL file to a particular database. + * @var PhingFile + */ + private $sqldbmap; + + /** + * Name of the database. + */ + private $database; + + /** + * Set the sqldbmap. + * @param PhingFile $sqldbmap The db map. + */ + public function setSqlDbMap(PhingFile $sqldbmap) + { + $this->sqldbmap = $sqldbmap; + } + + /** + * Get the sqldbmap. + * @return PhingFile $sqldbmap. + */ + public function getSqlDbMap() + { + return $this->sqldbmap; + } + + /** + * Set the database name. + * @param string $database + */ + public function setDatabase($database) + { + $this->database = $database; + } + + /** + * Get the database name. + * @return string + */ + public function getDatabase() + { + return $this->database; + } + + /** + * Create the sql -> database map. + * + * @throws IOException - if unable to store properties + */ + private function createSqlDbMap() + { + if ($this->getSqlDbMap() === null) { + return; + } + + // Produce the sql -> database map + $sqldbmap = new Properties(); + + // Check to see if the sqldbmap has already been created. + if ($this->getSqlDbMap()->exists()) { + $sqldbmap->load($this->getSqlDbMap()); + } + + if ($this->packageObjectModel) { + // in this case we'll get the sql file name from the package attribute + $dataModels = $this->packageDataModels(); + foreach ($dataModels as $package => $dataModel) { + foreach ($dataModel->getDatabases() as $database) { + $name = ($package ? $package . '.' : '') . 'schema.xml'; + $sqlFile = $this->getMappedFile($name); + $sqldbmap->setProperty($sqlFile->getName(), $database->getName()); + } + } + } else { + // the traditional way is to map the schema.xml filenames + $dmMap = $this->getDataModelDbMap(); + foreach(array_keys($dmMap) as $dataModelName) { + $sqlFile = $this->getMappedFile($dataModelName); + if ($this->getDatabase() === null) { + $databaseName = $dmMap[$dataModelName]; + } else { + $databaseName = $this->getDatabase(); + } + $sqldbmap->setProperty($sqlFile->getName(), $databaseName); + } + } + + try { + $sqldbmap->store($this->getSqlDbMap(), "Sqlfile -> Database map"); + } catch (IOException $e) { + throw new IOException("Unable to store properties: ". $e->getMessage()); + } + } + + public function main() { + + $this->validate(); + + if(!$this->mapperElement) { + throw new BuildException("You must use a element to describe how names should be transformed."); + } + + if ($this->packageObjectModel) { + $dataModels = $this->packageDataModels(); + } else { + $dataModels = $this->getDataModels(); + } + + // 1) first create a map of filenames to databases; this is used by other tasks like + // the SQLExec task. + $this->createSqlDbMap(); + + // 2) Now actually create the DDL based on the datamodel(s) from XML schema file. + $targetDatabase = $this->getTargetDatabase(); + + DataModelBuilder::setBuildProperties($this->getPropelProperties()); + $builderClazz = DataModelBuilder::getBuilderClass('ddl'); + + foreach ($dataModels as $package => $dataModel) { + + foreach ($dataModel->getDatabases() as $database) { + + // file we are going to create + if (!$this->packageObjectModel) { + $name = $dataModel->getName(); + } else { + $name = ($package ? $package . '.' : '') . 'schema.xml'; + } + + $outFile = $this->getMappedFile($name); + + $this->log("Writing to SQL file: " . $outFile->getPath()); + + // First add any "header" SQL + $ddl = call_user_func(array($builderClazz, 'getDatabaseStartDDL')); + + foreach($database->getTables() as $table) { + + if (!$table->isSkipSql()) { + $builder = DataModelBuilder::builderFactory($table, 'ddl'); + $this->log("\t+ " . $table->getName() . " [builder: " . get_class($builder) . "]"); + $ddl .= $builder->build(); + foreach($builder->getWarnings() as $warning) { + $this->log($warning, PROJECT_MSG_WARN); + } + } else { + $this->log("\t + (skipping) " . $table->getName()); + } + + } // foreach database->getTables() + + // Finally check to see if there is any "footer" SQL + $ddl .= call_user_func(array($builderClazz, 'getDatabaseEndDDL')); + + + // Now we're done. Write the file! + file_put_contents($outFile->getAbsolutePath(), $ddl); + + } // foreach database + } //foreach datamodels + + } // main() + + /** + * Packages the datamodels to one datamodel per package + * + * This applies only when the the packageObjectModel option is set. We need to + * re-package the datamodels to allow the database package attribute to control + * which tables go into which SQL file. + * + * @return array The packaged datamodels + */ + protected function packageDataModels() { + + static $packagedDataModels; + + if (is_null($packagedDataModels)) { + + $dataModels = $this->getDataModels(); + $dataModel = array_shift($dataModels); + $packagedDataModels = array(); + + $platform = $this->getPlatformForTargetDatabase(); + + foreach ($dataModel->getDatabases() as $db) { + foreach ($db->getTables() as $table) { + $package = $table->getPackage(); + if (!isset($packagedDataModels[$package])) { + $dbClone = $this->cloneDatabase($db); + $dbClone->setPackage($package); + $ad = new AppData($platform); + $ad->setName($dataModel->getName()); + $ad->addDatabase($dbClone); + $packagedDataModels[$package] = $ad; + } + $packagedDataModels[$package]->getDatabase($db->getName())->addTable($table); + } + } + } + + return $packagedDataModels; + } + + protected function cloneDatabase($db) { + + $attributes = array ( + 'name' => $db->getName(), + 'baseClass' => $db->getBaseClass(), + 'basePeer' => $db->getBasePeer(), + //'defaultPhpType' => $db->getDefaultPhpType(), + 'defaultIdMethod' => $db->getDefaultIdMethod(), + 'defaultPhpNamingMethod' => $db->getDefaultPhpNamingMethod(), + 'defaultTranslateMethod' => $db->getDefaultTranslateMethod(), + //'heavyIndexing' => $db->getHeavyIndexing(), + ); + + $clone = new Database(); + $clone->loadFromXML($attributes); + return $clone; + } +} diff --git a/gulliver/thirdparty/propel-generator/default.properties b/gulliver/thirdparty/propel-generator/default.properties new file mode 100644 index 000000000..756dcd8b9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/default.properties @@ -0,0 +1,219 @@ +# ------------------------------------------------------------------- +# +# D E F A U L T P R O P E R T I E S +# +# ------------------------------------------------------------------- +# This file sets default properties. You can override any of these +# by specifying your new value in the build.properties file for your +# project or a top-level build.properties file. Either way, you +# should not need to edit this file. +# ------------------------------------------------------------------- + + +# ------------------------------------------------------------------- +# +# B A S I C P R O P E R T I E S +# +# ------------------------------------------------------------------- + +propel.home = . + +propel.project = +propel.database = +propel.targetPackage = ${propel.project} +propel.runOnlyOnSchemaChange = false +propel.targetPlatform = php5 + +propel.packageObjectModel = false + +propel.schema.validate = true + +# ------------------------------------------------------------------- +# +# D A T A B A S E S E T T I N G S +# +# ------------------------------------------------------------------- + +propel.database.url = +propel.database.buildUrl = ${propel.database.url} +propel.database.createUrl = ${propel.database.buildUrl} + +# by default leave the databaseDriver blank, so that bundled driver is used by Creole +propel.database.driver = + +propel.database.schema = +propel.database.encoding = +propel.database.manualCreation = false + +# ------------------------------------------------------------------- +# +# C R E O L E TO X M L S E T T I N G S +# +# ------------------------------------------------------------------- + +propel.samePhpName = false +propel.addVendorInfo = true +propel.addValidators = none + +# ------------------------------------------------------------------- +# +# T E M P L A T E V A R I A B L E S +# +# ------------------------------------------------------------------- + +propel.addGenericAccessors = false +propel.addGenericMutators = false +propel.addSaveMethod = true +propel.addTimeStamp = true +propel.basePrefix = Base +propel.complexObjectModel = true +propel.saveException = PropelException +propel.emulateForeignKeyConstraints = false + +# Identifier quoting is only implemented at the DDL layer at this point. +# Since this may result in undesired behavior (especially in Postgres), +# it can be disabled by setting this property to true in your build.properties file. +propel.disableIdentifierQuoting = false + +# These are the default formats that will be used when fetching values +# from temporal columns in Propel. You can always specify these when +# calling the methods directly, but for methods like getByName() +# it is nice to change the defaults. + +propel.defaultTimeStampFormat = Y-m-d H:i:s +propel.defaultTimeFormat = H:i:s +propel.defaultDateFormat = Y-m-d + +propel.omtar.src.base = false +propel.omtar.src.extension = false +propel.omtar.bin.base = false +propel.omtar.bin.extension = false +propel.omtar.deleteFiles = false + + +# ------------------------------------------------------------------- +# +# C O N T R O L T E M P L A T E S +# +# ------------------------------------------------------------------- +# +# This is a deprecated idea, that will almost certainly be completely +# removed in Propel 1.2 and/or 2.0. +# + +propel.template.conf = ${propel.home}/templates/conf/Control.tpl +propel.template.sql = ${propel.home}/templates/sql/base/Control.tpl +propel.template.sqlDbInit = ${propel.home}/templates/sql/db-init/Control.tpl + + +# ------------------------------------------------------------------- +# +# D I R E C T O R I E S +# +# ------------------------------------------------------------------- + +propel.project.dir = ${propel.home}/projects/${propel.project} + +propel.output.dir = ${propel.project.dir}/build +propel.schema.dir = ${propel.project.dir} +propel.templatePath = ${propel.home}/templates +propel.conf.dir = ${propel.project.dir} + +propel.doc.dir = ${propel.output.dir}/doc +propel.php.dir = ${propel.output.dir}/classes +propel.phpconf.dir = ${propel.output.dir}/conf +propel.phpdoc.dir = ${propel.output.dir}/phpdoc +propel.sql.dir = ${propel.output.dir}/sql +propel.graph.dir = ${propel.output.dir}/graph +propel.omtar.dir = ${propel.output.dir} + + +# ------------------------------------------------------------------- +# +# D E F A U L T F I L E N A M ES +# +# ------------------------------------------------------------------- + +# propel.sqlfile + +propel.runtime.conf.file = runtime-conf.xml +propel.runtime.phpconf.file = ${propel.project}-conf.php +propel.default.schema.basename = schema + +# Can't use because of inconsistencies in where the files +# are named (some from build-propel.xml, but some from within templates) +# propel.default.data.basename = ${propel.project}-data + +propel.schema.xsd.file = ${propel.home}/resources/xsd/database.xsd +propel.schema.xsl.file = ${propel.home}/resources/xsl/database.xsl + +# ------------------------------------------------------------------- +# +# I N C L U D E A N D E X C L U D E S E T T I N G S +# +# ------------------------------------------------------------------- + +propel.schema.sql.includes = *schema.xml +propel.schema.sql.excludes = +propel.schema.doc.includes = *schema.xml +propel.schema.doc.excludes = +propel.schema.create-db.includes = *schema.xml +propel.schema.create-db.excludes = +propel.schema.init-sql.includes = *schema.xml +propel.schema.init-sql.excludes = id-table-schema.xml +propel.schema.om.includes = *schema.xml +propel.schema.om.excludes = id-table-schema.xml +propel.schema.datadtd.includes = *schema.xml +propel.schema.datadtd.excludes = id-table-schema.xml + +# ------------------------------------------------------------------- +# +# M A P P E R S E T T I N G S +# +# ------------------------------------------------------------------- + +# (note: data xml files are selected based on datadbmap file) +propel.datasql.mapper.from = *.xml +propel.datasql.mapper.to = *.sql + +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +propel.datadtd.mapper.from = *.xml +propel.datadtd.mapper.to = *.dtd + +propel.sql.mapper.from = *.xml +propel.sql.mapper.to = *.sql + + +# ------------------------------------------------------------------- +# +# B U I L D E R S E T T I N G S +# +# ------------------------------------------------------------------- + +# Object Model builders +propel.builder.peer.class = propel.engine.builder.om.php5.PHP5ComplexPeerBuilder +propel.builder.object.class = propel.engine.builder.om.php5.PHP5ComplexObjectBuilder +propel.builder.objectstub.class = propel.engine.builder.om.php5.PHP5ExtensionObjectBuilder +propel.builder.peerstub.class = propel.engine.builder.om.php5.PHP5ExtensionPeerBuilder + +propel.builder.objectmultiextend.class = propel.engine.builder.om.php5.PHP5MultiExtendObjectBuilder + +propel.builder.mapbuilder.class = propel.engine.builder.om.php5.PHP5MapBuilderBuilder + +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder + +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +# SQL builders + +propel.builder.ddl.class = propel.engine.builder.sql.${propel.database}.${propel.database}DDLBuilder +propel.builder.datasql.class = propel.engine.builder.sql.${propel.database}.${propel.database}DataSQLBuilder + +# Platform classes + +propel.platform.class = propel.engine.platform.${propel.database}Platform \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/pear/BuildPropelGenPEARPackageTask.php b/gulliver/thirdparty/propel-generator/pear/BuildPropelGenPEARPackageTask.php new file mode 100644 index 000000000..0f4499c6c --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/BuildPropelGenPEARPackageTask.php @@ -0,0 +1,268 @@ +. + */ + +require_once 'phing/tasks/system/MatchingTask.php'; +include_once 'phing/types/FileSet.php'; +include_once 'phing/tasks/ext/pearpackage/Fileset.php'; + +/** + * + * @author Hans Lellelid + * @package phing.tasks.ext + * @version $Revision: 536 $ + */ +class BuildPropelGenPEARPackageTask extends MatchingTask { + + /** Base directory for reading files. */ + private $dir; + + private $version; + private $state = 'stable'; + private $notes; + + private $filesets = array(); + + /** Package file */ + private $packageFile; + + public function init() { + include_once 'PEAR/PackageFileManager2.php'; + if (!class_exists('PEAR_PackageFileManager2')) { + throw new BuildException("You must have installed PEAR_PackageFileManager2 (PEAR_PackageFileManager >= 1.6.0) in order to create a PEAR package.xml file."); + } + } + + private function setOptions($pkg){ + + $options['baseinstalldir'] = 'propel'; + $options['packagedirectory'] = $this->dir->getAbsolutePath(); + + if (empty($this->filesets)) { + throw new BuildException("You must use a tag to specify the files to include in the package.xml"); + } + + $options['filelistgenerator'] = 'Fileset'; + + // Some PHING-specific options needed by our Fileset reader + $options['phing_project'] = $this->getProject(); + $options['phing_filesets'] = $this->filesets; + + if ($this->packageFile !== null) { + // create one w/ full path + $f = new PhingFile($this->packageFile->getAbsolutePath()); + $options['packagefile'] = $f->getName(); + // must end in trailing slash + $options['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR; + $this->log("Creating package file: " . $f->getPath(), PROJECT_MSG_INFO); + } else { + $this->log("Creating [default] package.xml file in base directory.", PROJECT_MSG_INFO); + } + + // add install exceptions + $options['installexceptions'] = array( 'pear/pear-propel-gen' => '/', + 'pear/pear-propel-gen.bat' => '/', + 'pear/pear-build.xml' => '/', + 'pear/build.properties' => '/', + ); + + $options['dir_roles'] = array( 'projects' => 'data', + 'test' => 'test', + 'templates' => 'data', + 'resources' => 'data'); + + $options['exceptions'] = array( 'pear/pear-propel-gen.bat' => 'script', + 'pear/pear-propel-gen' => 'script', + 'pear/pear-build.xml' => 'data', + 'build.xml' => 'data', + 'build-propel.xml' => 'data', + ); + + $pkg->setOptions($options); + + } + + /** + * Main entry point. + * @return void + */ + public function main() { + + if ($this->dir === null) { + throw new BuildException("You must specify the \"dir\" attribute for PEAR package task."); + } + + if ($this->version === null) { + throw new BuildException("You must specify the \"version\" attribute for PEAR package task."); + } + + $package = new PEAR_PackageFileManager2(); + + $this->setOptions($package); + + // the hard-coded stuff + $package->setPackage('propel_generator'); + $package->setSummary('Generator component of the Propel PHP object persistence layer'); + $package->setDescription('Propel is an object persistence layer for PHP5 based on Apache Torque. This package provides the generator engine that builds PHP classes and SQL DDL based on an XML representation of your data model.'); + $package->setChannel('pear.phpdb.org'); + $package->setPackageType('php'); + + $package->setReleaseVersion($this->version); + $package->setAPIVersion($this->version); + + $package->setReleaseStability($this->state); + $package->setAPIStability($this->state); + + $package->setNotes($this->notes); + + $package->setLicense('LGPL', 'http://www.gnu.org/licenses/lgpl.html'); + + // Add package maintainers + $package->addMaintainer('lead', 'hans', 'Hans Lellelid', 'hans@xmpl.org'); + $package->addMaintainer('lead', 'david', 'David Zuelke', 'dz@bitxtender.com'); + + + + // (wow ... this is a poor design ...) + // + // note that the order of the method calls below is creating + // sub-"release" sections which have specific rules. This replaces + // the platformexceptions system in the older version of PEAR's package.xml + // + // Programmatically, I feel the need to re-iterate that this API for PEAR_PackageFileManager + // seems really wrong. Sub-sections should be encapsulated in objects instead of having + // a "flat" API that does not represent the structure being created.... + + + // creating a sub-section for 'windows' + $package->addRelease(); + $package->setOSInstallCondition('windows'); + $package->addInstallAs('pear/pear-propel-gen.bat', 'propel-gen.bat'); + $package->addIgnoreToRelease('pear/pear-propel-gen'); + + // creating a sub-section for non-windows + $package->addRelease(); + $package->addInstallAs('pear/pear-propel-gen', 'propel-gen'); + $package->addIgnoreToRelease('pear/pear-propel-gen.bat'); + + + // "core" dependencies + $package->setPhpDep('5.0.0'); + $package->setPearinstallerDep('1.4.0'); + + // "package" dependencies + $package->addPackageDepWithChannel( 'required', 'phing', 'pear.phing.info', '2.2.0RC1'); + $package->addPackageDepWithChannel( 'required', 'creole', 'pear.phpdb.org', '1.1.0RC1'); + + // now add the replacements .... + $package->addReplacement('Phing.php', 'pear-config', '@DATA-DIR@', 'data_dir'); + $package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@PHP-BIN@', 'php_bin'); + $package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@BIN-DIR@', 'bin_dir'); + $package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@PEAR-DIR@', 'php_dir'); + $package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@DATA-DIR@', 'data_dir'); + + $package->addReplacement('pear/pear-propel-gen', 'pear-config', '@PHP-BIN@', 'php_bin'); + $package->addReplacement('pear/pear-propel-gen', 'pear-config', '@BIN-DIR@', 'bin_dir'); + $package->addReplacement('pear/pear-propel-gen', 'pear-config', '@PEAR-DIR@', 'php_dir'); + $package->addReplacement('pear/pear-propel-gen', 'pear-config', '@DATA-DIR@', 'data_dir'); + + $package->addReplacement('pear/pear-build.xml', 'pear-config', '@PHP-BIN@', 'php_bin'); + $package->addReplacement('pear/pear-build.xml', 'pear-config', '@BIN-DIR@', 'bin_dir'); + $package->addReplacement('pear/pear-build.xml', 'pear-config', '@PEAR-DIR@', 'php_dir'); + $package->addReplacement('pear/pear-build.xml', 'pear-config', '@DATA-DIR@', 'data_dir'); + + + // now we run this weird generateContents() method that apparently + // is necessary before we can add replacements ... ? + $package->generateContents(); + + $e = $package->writePackageFile(); + + if (PEAR::isError($e)) { + throw new BuildException("Unable to write package file.", new Exception($e->getMessage())); + } + + } + + /** + * Used by the PEAR_PackageFileManager_PhingFileSet lister. + * @return array FileSet[] + */ + public function getFileSets() { + return $this->filesets; + } + + // ------------------------------- + // Set properties from XML + // ------------------------------- + + /** + * Nested creator, creates a FileSet for this task + * + * @return FileSet The created fileset object + */ + function createFileSet() { + $num = array_push($this->filesets, new FileSet()); + return $this->filesets[$num-1]; + } + + /** + * Set the version we are building. + * @param string $v + * @return void + */ + public function setVersion($v){ + $this->version = $v; + } + + /** + * Set the state we are building. + * @param string $v + * @return void + */ + public function setState($v) { + $this->state = $v; + } + + /** + * Sets release notes field. + * @param string $v + * @return void + */ + public function setNotes($v) { + $this->notes = $v; + } + /** + * Sets "dir" property from XML. + * @param PhingFile $f + * @return void + */ + public function setDir(PhingFile $f) { + $this->dir = $f; + } + + /** + * Sets the file to use for generated package.xml + */ + public function setDestFile(PhingFile $f) { + $this->packageFile = $f; + } + +} diff --git a/gulliver/thirdparty/propel-generator/pear/build-pear-package.xml b/gulliver/thirdparty/propel-generator/pear/build-pear-package.xml new file mode 100644 index 000000000..7a9e47555 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/build-pear-package.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Propel version for package + + + + + + + + + ----------------------------- + | Creating directory layout | + ----------------------------- + + + + + + + + + + + + + + + + + + + + + ----------------------------- + | Creating PEAR package.xml | + ----------------------------- + + + + + + + + + + + + + + + ----------------------------- + | Creating tar.gz package | + ----------------------------- + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/pear/build.properties b/gulliver/thirdparty/propel-generator/pear/build.properties new file mode 100644 index 000000000..fe317e435 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/build.properties @@ -0,0 +1,5 @@ +# In this file you can define any properties taht you want to affect +# all projects built using the propel-gen script on this system +# +# See http://propel.phpdb.org/trac/wiki/Users/Documentation/BuildProperties for a +# list of available properties. diff --git a/gulliver/thirdparty/propel-generator/pear/pear-build.xml b/gulliver/thirdparty/propel-generator/pear/pear-build.xml new file mode 100644 index 000000000..dd40150a6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/pear-build.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/pear/pear-propel-gen b/gulliver/thirdparty/propel-generator/pear/pear-propel-gen new file mode 100644 index 000000000..160f9e93f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/pear-propel-gen @@ -0,0 +1,21 @@ +#!/bin/sh + +# ------------------------------------------------------------------------ +# The phing build script for Unix based systems +# $Id: pear-propel-gen,v 1.2 2004/10/17 13:24:09 hlellelid Exp $ +# ------------------------------------------------------------------------ + +# Change this to reflect your environment if the default value doesn't work +export PHING_COMMAND="phing" + +# ------------------------------------------------------------------------- +# Do not change anything below this line unless you know what you're doing. +# ------------------------------------------------------------------------- + +# (currently this is not reached) +if (test -z "$PHING_COMMAND") ; then + echo "WARNING: PHP_COMMAND environment not set. (Assuming phing on PATH)" + export PHING_COMMAND=php +fi + +$PHING_COMMAND -f @DATA-DIR@/propel_generator/pear-build.xml -Dproject.dir=$* diff --git a/gulliver/thirdparty/propel-generator/pear/pear-propel-gen.bat b/gulliver/thirdparty/propel-generator/pear/pear-propel-gen.bat new file mode 100644 index 000000000..a6ccd430f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/pear/pear-propel-gen.bat @@ -0,0 +1,24 @@ +@ECHO OFF + +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: The propel-gen build script for Windows based systems +:: $Id: pear-propel-gen.bat,v 1.2 2004/10/17 13:24:09 hlellelid Exp $ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +::---------------------------------------------------------------------------------- +:: Please set following to the "phing" script. By default this is expected to be +:: on your path. (You don't need to modify this file if that is the case.) + + SET phingScript=phing + +::--------------------------------------------------------------------------------- +::--------------------------------------------------------------------------------- +:: Do not modify below this line!! (Unless you know what your doing :) +::--------------------------------------------------------------------------------- +::--------------------------------------------------------------------------------- + +"%phingScript%" -f @DATA-DIR@\propel_generator\pear-build.xml -Dproject.dir=%* +GOTO :EOF + +:PAUSE_END +PAUSE \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/resources/dtd/database.dtd b/gulliver/thirdparty/propel-generator/resources/dtd/database.dtd new file mode 100644 index 000000000..f2daa5853 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/resources/dtd/database.dtd @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/propel-generator/resources/xsd/custom_datatypes.xsd b/gulliver/thirdparty/propel-generator/resources/xsd/custom_datatypes.xsd new file mode 100644 index 000000000..12e8327cb --- /dev/null +++ b/gulliver/thirdparty/propel-generator/resources/xsd/custom_datatypes.xsd @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/resources/xsd/database.xsd b/gulliver/thirdparty/propel-generator/resources/xsd/database.xsd new file mode 100644 index 000000000..618678b3b --- /dev/null +++ b/gulliver/thirdparty/propel-generator/resources/xsd/database.xsd @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/resources/xsl/database.xsl b/gulliver/thirdparty/propel-generator/resources/xsl/database.xsl new file mode 100644 index 000000000..0c8b7cfc1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/resources/xsl/database.xsl @@ -0,0 +1,226 @@ + + +]> + + + + + + + + + + + + + none + + + underscore + + + false + + + + + + + + + + + + + + + none + + + + + + + + + + + none + + + + + + + + + + + none + + + + + + + + + + + none + + + + + + + + + + + + + + + + + + + + + + +
    + + false + + + false + + + + + + + + + +
    + + + + + + none + + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + + + + + + + + + + + + + + + + class + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + VARCHAR + + + false + + + false + + + + + + + + + + + + + + diff --git a/gulliver/thirdparty/propel-generator/templates/README b/gulliver/thirdparty/propel-generator/templates/README new file mode 100644 index 000000000..e0bf81d94 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/README @@ -0,0 +1,5 @@ +This directory contains PHP templates which are used to build SQL files and object +model (OM) classes. The PHP templates are called from the +propel.phing.PropelDataModelTask class. The templates are managed by the Capsule +engine, which simply provides a mechanism for placing values in the template context +and buffering output, etc. \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/conf/Control.tpl b/gulliver/thirdparty/propel-generator/templates/conf/Control.tpl new file mode 100644 index 000000000..e9e246f81 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/conf/Control.tpl @@ -0,0 +1,30 @@ + + * @version $Revision: 1.2 $ + */ + + // we expect to have: + // $propertiesFile - path to xml/ini file. + + +$pfile = new PhingFile($propertiesFile); +if (!$pfile->exists()) { + throw new BuildException("Property file does not exist: $propertiesFile"); +} + +$pfileName = explode('.', $pfile->getName()); +$format = array_pop($pfileName); + +switch($format) { + case 'xml': + include 'xml.tpl'; + break; + default: + throw new BuildException("Propel now only supports the XML runtime conf format (expected to find a runtime file with .xml extension)."); +} diff --git a/gulliver/thirdparty/propel-generator/templates/conf/xml.tpl b/gulliver/thirdparty/propel-generator/templates/conf/xml.tpl new file mode 100644 index 000000000..726389e3e --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/conf/xml.tpl @@ -0,0 +1,83 @@ + + * @version $Revision: 1.2 $ + */ + + // -------------------------------------------------------------------------------- + +// Added function_exists check for ticket:244, allowing multiple calls to convert-props +if (!function_exists('simplexml_to_array')) { +/** + * Converts simplexml object into array, turning attributes into child elements. + * + * From a helpful php.net comment. + * @author Christophe VG + */ +function &simplexml_to_array( $xml ) { + $ar = array(); + + foreach( $xml->children() as $k => $v ) { + + // recurse the child + $child = simplexml_to_array( $v ); + + //print "Recursed down and found: " . var_export($child, true) . "\n"; + + // if it's not an array, then it was empty, thus a value/string + if( count($child) == 0 ) { + $child = (string)$v; + } + + // add the childs attributes as if they where children + foreach( $v->attributes() as $ak => $av ) { + + // if the child is not an array, transform it into one + if( !is_array( $child ) ) { + $child = array( "value" => $child ); + } + + if ($ak == 'id') { + // special exception: if there is a key named 'id' + // then we will name the current key after that id + $k = (string) $av; + } else { + // otherwise, just add the attribute like a child element + $child[$ak] = (string) $av; + } + } + + // if the $k is already in our children list, we need to transform + // it into an array, else we add it as a value + if( !in_array( $k, array_keys($ar) ) ) { + $ar[$k] = $child; + } else { + // if the $ar[$k] element is not already an array, then we need to make it one + if ( !is_array( $ar[$k] ) ) { $ar[$k] = array( $ar[$k] ); } + $ar[$k][] = $child; + } + + } + return $ar; +} +} // if (!function_exists...) + + // we expect to have: + // $propertiesFile - path to properties file. + + $xmlDom = new DOMDocument(); + + $xmlDom->load($propertiesFile); + $xml = simplexml_load_string($xmlDom->saveXML()); + + echo '<' . '?' . "php\n"; + echo "// This file generated by Propel convert-props target on " . strftime("%c") . "\n"; + echo "// from XML runtime conf file " . $pfile->getPath() . "\n"; + echo "return "; + var_export(simplexml_to_array( $xml )); + echo ";"; diff --git a/gulliver/thirdparty/propel-generator/templates/data/dtd/dataset.tpl b/gulliver/thirdparty/propel-generator/templates/data/dtd/dataset.tpl new file mode 100644 index 000000000..e1969d279 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/data/dtd/dataset.tpl @@ -0,0 +1,13 @@ +getPhpName() ?>* +)> + + diff --git a/gulliver/thirdparty/propel-generator/templates/data/dtd/table.tpl b/gulliver/thirdparty/propel-generator/templates/data/dtd/table.tpl new file mode 100644 index 000000000..941257571 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/data/dtd/table.tpl @@ -0,0 +1,6 @@ +getPhpName() ?> EMPTY> +getPhpName() ?> +getColumns() as $col) { ?> + getPhpName() ?> CDATA isNotNull()) { ?>#REQUIREDIMPLIED +> + diff --git a/gulliver/thirdparty/propel-generator/templates/data/dump/bottom.tpl b/gulliver/thirdparty/propel-generator/templates/data/dump/bottom.tpl new file mode 100644 index 000000000..ec76e0c8d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/data/dump/bottom.tpl @@ -0,0 +1 @@ +
    diff --git a/gulliver/thirdparty/propel-generator/templates/data/dump/row.tpl b/gulliver/thirdparty/propel-generator/templates/data/dump/row.tpl new file mode 100644 index 000000000..dd2030fb0 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/data/dump/row.tpl @@ -0,0 +1,2 @@ + + diff --git a/gulliver/thirdparty/propel-generator/templates/data/dump/top.tpl b/gulliver/thirdparty/propel-generator/templates/data/dump/top.tpl new file mode 100644 index 000000000..e4c2fcff6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/data/dump/top.tpl @@ -0,0 +1,3 @@ +?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?> +-data.dtd"> + diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNode.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNode.tpl new file mode 100644 index 000000000..b9376a1ce --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNode.tpl @@ -0,0 +1,35 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +?> + + +require_once 'getPhpName() . 'Node') ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?>Node extends getPhpName() . 'Node' ?> { + +} \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNodePeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNodePeer.tpl new file mode 100644 index 000000000..395d96559 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionNodePeer.tpl @@ -0,0 +1,35 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +?> + + +require_once 'getPhpName() . 'NodePeer') ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?>NodePeer extends getPhpName() . 'NodePeer' ?> { + +} \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionObject.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionObject.tpl new file mode 100644 index 000000000..9aafaeaca --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionObject.tpl @@ -0,0 +1,36 @@ +getDatabase(); +if ($db->getPackage()) { + $package = $db->getPackage(); +} else { + $package = $targetPackage; +} + +?> + +require_once 'propel/om/Persistent.php'; +require_once 'getPhpName()) ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?> extends getPhpName() +?> +{ + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionPeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionPeer.tpl new file mode 100644 index 000000000..08de55ab0 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/ExtensionPeer.tpl @@ -0,0 +1,36 @@ +getDatabase(); +if ($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$thisClass = $table->getPhpName() . 'Peer'; +$baseClass = $basePrefix . $thisClass; +?> + +require_once 'getPhpName() . 'Peer') ?>'; +include_once 'getPhpName()) ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName()?>Peer extends getPhpName() ?>Peer +{ +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/Interface.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/Interface.tpl new file mode 100644 index 000000000..a4013ccdd --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/Interface.tpl @@ -0,0 +1,30 @@ +getDatabase(); +if ($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} +?> + + +/** + * This is an interface that should be filled with the public api of the + * getPhpName()?> objects. + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * @package + */ +class getInterface() ?> +{ +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/MapBuilder.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/MapBuilder.tpl new file mode 100644 index 000000000..9f3dab0ca --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/MapBuilder.tpl @@ -0,0 +1,135 @@ + + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + +/** + * This class adds structure of 'getName() ?>' table to 'getDatabase()->getName() ?>' DatabaseMap object. + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @see BasePeer + * @see DatabaseMap + * @package .map; + */ +class getPhpName() ?>MapBuilder extends MapBuilder +{ + /** + * Returns the name of this class. + */ + function CLASS_NAME() { return ("getPhpName() ?>MapBuilder"); } + + /** + * The database map. + */ + var $dbMap = null; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean TRUE if this DatabaseMapBuilder is built + */ + function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return DatabaseMap This database map. + */ + function & getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + function doBuild() + { + $this->dbMap =& Propel::getDatabaseMap("getDatabase()->getName() ?>"); + + $tMap =& $this->dbMap->addTable("getName()?>"); + $tMap->setPhpName("getPhpName()?>"); + +getIdMethod() == "native") { ?> + $tMap->setUseIdGenerator(true); + + $tMap->setUseIdGenerator(false); + + + getIdMethodParameters()) { + $params = $table->getIdMethodParameters(); + $imp = $params[0]; ?> + $tMap->setPrimaryKeyMethodInfo("getValue() ?>"); + getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { ?> + $tMap->setPrimaryKeyMethodInfo("getSequenceName() ?>"); + getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { ?> + $tMap->setPrimaryKeyMethodInfo("getName() ?>"); + + // Add columns to map +getColumns() as $col) { + $tfc=$table->getPhpName(); + $cfc=$col->getPhpName(); + $cup=strtoupper($col->getName()); + if($col->isPrimaryKey()) { + if($col->isForeignKey()) { ?> + $tMap->addForeignPrimaryKey("", "", "getPhpType() ?>" , CreoleTypes::getType() ?>(), "getRelatedTableName()?>" , "getRelatedColumnName()) ?>", isNotNull() ? 'true' : 'false' ?>); + + $tMap->addPrimaryKey("", "", "getPhpType() ?>", CreoleTypes::getType() ?>(), isNotNull() ? 'true' : 'false' ?>); +isForeignKey()) { ?> + $tMap->addForeignKey("", "", "getPhpType()?>", CreoleTypes::getType() ?>(), "getRelatedTableName() ?>" , "getRelatedColumnName()) ?>", isNotNull() ? 'true' : 'false' ?>); +getSize()) { + $size = "null"; + } else { + $size = $col->getSize(); + } + ?> + $tMap->addColumn("", "", "getPhpType()?>", CreoleTypes::getType() ?>(), isNotNull() ? 'true' : 'false' ?>, ); +getValidators() as $val) { + $col = $val->getColumn(); + $cup = strtoupper($col->getName()); + foreach($val->getRules() as $rule) { + if ($val->getTranslate() !== Validator::TRANSLATE_NONE) { +?> + $tMap->addValidator("", "getName() ?>", "getClass() ?>", "getValue()?>", getTranslate() ?>("getMessage()) ?>")); + + $tMap->addValidator("", "getName() ?>", "getClass() ?>", "getValue()?>", "getMessage()) ?>"); +getTranslation() ... + } // foreach validator +} +?> + } +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/MultiExtendObject.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/MultiExtendObject.tpl new file mode 100644 index 000000000..f2abe0382 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/MultiExtendObject.tpl @@ -0,0 +1,63 @@ +getDatabase(); +if ($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$packagePath = strtr($package, '.', '/'); +if ($packagePath != "") $packagePath .= '/'; + +if ($child->getAncestor()) { + $parent = $child->getAncestor(); +?> + +require_once '.php'; + +getPhpName(); +?> + +require_once '.php'; + + +/** + + + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + */ +class getClassName()?> extends +{ + + function getClassName()?>() + { +getColumn(); + $cfc = $col->getPhpName(); + $table = $col->getTable(); +?> + $this->set(getPhpName() ?>Peer::CLASSKEY_getKey()) ?>()); + } + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/Node.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/Node.tpl new file mode 100644 index 000000000..64beaff2b --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/Node.tpl @@ -0,0 +1,871 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$CLASS = $table->getPhpName() . 'NodePeer'; +echo '<' . '?' . 'php'; + +?> + + +require_once 'getPhpName() . 'NodePeer') ?>'; + +/** + * Base tree node class for manipulating a tree of getPhpName() ?> objects. + * This class will wrap these objects within a "node" interface. It provides a + * method overload mechanism which allows you to use a getPhpName() ?>Node + * object just like a getPhpName() ?> object. + * + * To avoid tree corruption, you should always use this class to make changes to + * the tree and objects within it rather than using the getPhpName() ?> + * class directly. + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + * + */ +class getPhpName() ?>Node /*implements IteratorAggregate*/ +{ + /** + * @var getPhpName() ?> Object wrapped by this node. + */ + var $obj = null; + + /** + * The parent node for this node. + * @var getPhpName() ?>Node + */ + var $parentNode = null; + + /** + * Array of child nodes for this node. Nodes indexes are one-based. + * @var array + */ + var $childNodes = array(); + + /** + * Constructor. + * + * @param getPhpName() ?> Object wrapped by this node. + */ + function getPhpName() ?>Node($obj = null) + { + Propel::assertParam($obj, '', 'getPhpName() ?>Node', 1); + $obj =& Param::get($obj); + + if ($obj !== null) + { + $this->obj =& $obj; + } + else + { + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + $this->obj =& new getPhpName() ?>(); + $this->obj->$setNodePath('0'); + } + } + + /** + * Convenience overload for wrapped object methods. + * + * @param string Method name to call on wrapped object. + * @param mixed Parameter accepted by wrapped object set method. + * @return mixed Return value of wrapped object method. + * @throws PropelException Fails if method is not defined for wrapped object. + */ + function & callObjMethod($name, $parms = null) + { + $params =& Param::get($parms); + if (method_exists($this->obj, $name)) { + if (is_array($params)) { + $implode = array(); + $keys = array_keys($params); + foreach($keys as $key) + $implode [] = "\$params['{$key}']"; + eval('$result =& $this->obj->$name(' . implode(',', $implode) . ');'); + } + else { + $result =& $this->obj->$name($params); + } + return $result; + } + else + return new PropelException(PROPEL_ERROR, "get method not defined: $name"); + } + + /** + * Sets the default options for iterators created from this object. + * The options are specified in map format. The following options + * are supported by all iterators. Some iterators may support other + * options: + * + * "querydb" - True if nodes should be retrieved from database. + * "con" - Connection to use if retrieving from database. + * + * @param string Type of iterator to use ("pre", "post", "level"). + * @param array Map of option name => value. + * @return void + * @todo Implement other iterator types (i.e. post-order, level, etc.) + */ + function setIteratorOptions($type, $opts) + { + $this->itType = $type; + $this->itOpts = $opts; + } + + /** + * Returns a pre-order iterator for this node and its children. + * + * @param string Type of iterator to use ("pre", "post", "level") + * @param array Map of option name => value. + * @return NodeIterator + */ + function & getIterator($type = null, $opts = null) + { + if ($type === null) + $type = (isset($this->itType) ? $this->itType : 'Pre'); + + if ($opts === null) + $opts = (isset($this->itOpts) ? $this->itOpts : array()); + + $itclass = ucfirst(strtolower($type)) . 'OrderNodeIterator'; + + require_once('propel/om/' . $itclass . '.php'); + return new $itclass($this, $opts); + } + + /** + * Returns the object wrapped by this class. + * @return getPhpName() . "\n" ?> + */ + function & getNodeObj() + { + return $this->obj; + } + + /** + * Convenience method for retrieving nodepath. + * @return string + */ + function getNodePath() + { + $getNodePath = 'get' . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + return $this->obj->$getNodePath(); + } + + /** + * Returns one-based node index among siblings. + * @return int + */ + function getNodeIndex() + { + $npath = $this->getNodePath(); + //strrpos fix + $sep = 0; + while(false !== ($last = strpos($npath, getPhpName() ?>NodePeer::NPATH_SEP(), $sep))) { + $sep = $last + strlen(getPhpName() ?>NodePeer::NPATH_SEP()); + } + return (int) ($sep != 0 ? substr($npath, $sep) : $npath); + } + + /** + * Returns one-based node level within tree (root node is level 1). + * @return int + */ + function getNodeLevel() + { + return (substr_count($this->getNodePath(), getPhpName() ?>NodePeer::NPATH_SEP()) + 1); + } + + /** + * Returns true if specified node is a child of this node. If recurse is + * true, checks if specified node is a descendant of this node. + * + * @param getPhpName() ?>Node Node to look for. + * @param boolean True if strict comparison should be used. + * @param boolean True if all descendants should be checked. + * @return boolean + */ + function hasChildNode(&$node, $strict = false, $recurse = false) + { + foreach ($this->childNodes as $key => $childNode) + { + if ($this->childNodes[$key]->equals($node, $strict)) + return true; + + if ($recurse && $this->childNodes[$key]->hasChildNode($node, $recurse)) + return true; + } + + return false; + } + + /** + * Returns child node at one-based index. Retrieves from database if not + * loaded yet. + * + * @param int One-based child node index. + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + function & getChildNodeAt($i, $querydb = false, $con = null) + { + Propel::assertParam($con, '', 'getChildNodeAt', 3); + $con =& Param::get($con); + + if ($querydb && + !$this->obj->isNew() && + !$this->obj->isDeleted() && + !isset($this->childNodes[$i])) + { + $criteria =& new Criteria(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME(), + $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $i, + Criteria::EQUAL()); + + if ($childObj =& getPhpName() ?>Peer::doSelectOne($criteria, Param::set($con))) + $this->attachChildNode(new getPhpName() ?>Node(Param::set($childObj))); + } + + return (isset($this->childNodes[$i]) ? $this->childNodes[$i] : null); + } + + /** + * Returns first child node (if any). Retrieves from database if not loaded yet. + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + function & getFirstChildNode($querydb = false, $con = null) + { + Propel::assertParam($con, '', 'getFirstChildNode', 2); + $con =& Param::get($con); + return $this->getChildNodeAt(1, $querydb, Param::set($con)); + } + + /** + * Returns last child node (if any). + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + */ + function & getLastChildNode($querydb = false, $con = null) + { + Propel::assertParam($con, '', 'getLastChildNode', 2); + $con =& Param::get($con); + $lastNode = null; + + if ($this->obj->isNew() || $this->obj->isDeleted()) + { + if (count($this->childNodes)) { + end($this->childNodes); + $lastNode =& $this->childNodes[key($this->childNodes)]; + } + } + else if ($querydb) + { + $db =& Propel::getDb(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria =& new Criteria(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME(), + $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . '%', + Criteria::LIKE()); + $criteria->addAnd(getPhpName() ?>NodePeer::NPATH_COLNAME(), + $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . '%' . getPhpName() ?>NodePeer::NPATH_SEP() . '%', + Criteria::NOT_LIKE()); + $criteria->addAsColumn('npathlen', $db->strLength(getPhpName() ?>NodePeer::NPATH_COLNAME())); + $criteria->addDescendingOrderByColumn('npathlen'); + $criteria->addDescendingOrderByColumn(getPhpName() ?>NodePeer::NPATH_COLNAME()); + + $lastObj =& getPhpName() ?>Peer::doSelectOne($criteria, Param::set($con)); + + if ($lastObj !== null) + { + $lastNode =& new getPhpName() ?>Node(Param::set($lastObj)); + $endNode = null; + + if (count($this->childNodes)) { + end($this->childNodes); + $endNode =& $this->childNodes[key($this->childNodes)]; + } + + if ($endNode) + { + if ($endNode->getNodePath() > $lastNode->getNodePath()) + return new PropelException(PROPEL_ERROR, 'Cached child node inconsistent with database.'); + else if ($endNode->getNodePath() == $lastNode->getNodePath()) + $lastNode =& $endNode; + else + $this->attachChildNode($lastNode); + } + else + { + $this->attachChildNode($lastNode); + } + } + } + + return $lastNode; + } + + /** + * Returns next (or previous) sibling node or null. Retrieves from database if + * not loaded yet. + * + * @param boolean True if previous sibling should be returned. + * @param boolean True if sibling should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + function & getSiblingNode($prev = false, $querydb = false, $con = null) + { + Propel::assertParam($con, '', 'getSiblingNode', 3); + $con =& Param::get($con); + $nidx = $this->getNodeIndex(); + + if ($this->isRootNode()) + { + return null; + } + else if ($prev) + { + if ($nidx > 1 && ($parentNode =& $this->getParentNode($querydb, Param::set($con)))) + return $parentNode->getChildNodeAt($nidx-1, $querydb, Param::set($con)); + else + return null; + } + else + { + if ($parentNode =& $this->getParentNode($querydb, Param::set($con))) + return $parentNode->getChildNodeAt($nidx+1, $querydb, Param::set($con)); + else + return null; + } + } + + /** + * Returns parent node. Loads from database if not cached yet. + * + * @param boolean True if parent should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + function & getParentNode($querydb = true, $con = null) + { + Propel::assertParam($con, '', 'getParentNode', 2); + $con =& Param::get($con); + + if ($querydb && + $this->parentNode === null && + !$this->isRootNode() && + !$this->obj->isNew() && + !$this->obj->isDeleted()) + { + $npath =& $this->getNodePath(); + //strrpos fix + $sep = 0; + while(false !== ($last = strpos($npath, getPhpName() ?>NodePeer::NPATH_SEP(), $sep))) { + $sep = $last + strlen(getPhpName() ?>NodePeer::NPATH_SEP()); + } + $ppath = substr($npath, 0, $sep - strlen(getPhpName() ?>NodePeer::NPATH_SEP())); + + $criteria =& new Criteria(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME(), $ppath, Criteria::EQUAL()); + + if ($parentObj =& getPhpName() ?>Peer::doSelectOne($criteria, Param::set($con))) + { + $parentNode =& new getPhpName() ?>Node(Param::set($parentObj)); + $parentNode->attachChildNode($this); + } + } + + return $this->parentNode; + } + + /** + * Returns an array of all ancestor nodes, starting with the root node + * first. + * + * @param boolean True if ancestors should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return array + */ + function & getAncestors($querydb = false, $con = null) + { + Propel::assertParam($con, '', 'getAncestors', 2); + $con =& Param::get($con); + + $ancestors = array(); + $parentNode = $this; + + while ($parentNode =& $parentNode->getParentNode($querydb, Param::set($con))) + array_unshift($ancestors, $parentNode); + + return $ancestors; + } + + /** + * Returns true if node is the root node of the tree. + * @return boolean + */ + function isRootNode() + { + return ($this->getNodePath() === '1'); + } + + /** + * Changes the state of the object and its descendants to 'new'. + * Also changes the node path to '0' to indicate that it is not a + * stored node. + * + * @param boolean + * @return void + */ + function setNew($b) + { + $this->adjustStatus('new', $b); + $this->adjustNodePath($this->getNodePath(), '0'); + } + + /** + * Changes the state of the object and its descendants to 'deleted'. + * + * @param boolean + * @return void + */ + function setDeleted($b) + { + $this->adjustStatus('deleted', $b); + } + + /** + * Adds the specified node (and its children) as a child to this node. If a + * valid $beforeNode is specified, the node will be inserted in front of + * $beforeNode. If $beforeNode is not specified the node will be appended to + * the end of the child nodes. + * + * @param getPhpName() ?>Node Node to add. + * @param getPhpName() ?>Node Node to insert before. + * @param Connection Connection to use. + */ + function addChildNode(&$node, $beforeNode = null, $con = null) + { + Propel::assertParam($beforeNode, '', 'addChildNode', 2); + Propel::assertParam($con, '', 'addChildNode', 3); + $beforeNode =& Param::get($beforeNode); + $con =& Param::get($con); + + if ($this->obj->isNew() && !$node->obj->isNew()) + return new PropelException(PROPEL_ERROR, 'Cannot add stored nodes to a new node.'); + + if ($this->obj->isDeleted() || $node->obj->isDeleted()) + return new PropelException(PROPEL_ERROR, 'Cannot add children in a deleted state.'); + + if ($this->hasChildNode($node)) + return new PropelException(PROPEL_ERROR, 'Node is already a child of this node.'); + + if ($beforeNode && !$this->hasChildNode($beforeNode)) + return new PropelException(PROPEL_ERROR, 'Invalid beforeNode.'); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + if (Propel::isError($con)) + return $con; + + if (!$this->obj->isNew()) { + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + } + + if ($beforeNode) + { + // Inserting before a node. + $childIdx = $beforeNode->getNodeIndex(); + $e = $this->shiftChildNodes(1, $beforeNode->getNodeIndex(), $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + } + else + { + // Appending child node. + if ($lastNode =& $this->getLastChildNode(true, Param::set($con))) + $childIdx = $lastNode->getNodeIndex()+1; + else + $childIdx = 1; + } + + // Add the child (and its children) at the specified index. + + if (!$this->obj->isNew() && $node->obj->isNew()) + { + $e = $this->insertNewChildNode($node, $childIdx, $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + } + else + { + // $this->isNew() && $node->isNew() || + // !$this->isNew() && !node->isNew() + + $srcPath = $node->getNodePath(); + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $childIdx; + + if (!$node->obj->isNew()) + { + $e = getPhpName() ?>NodePeer::moveNodeSubTree($srcPath, $dstPath, Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $parentNode =& $node->getParentNode(true, Param::set($con)); + } + else + { + $parentNode =& $node->getParentNode(); + } + + if ($parentNode) + { + $parentNode->detachChildNode($node); + $e = $parentNode->shiftChildNodes(-1, $node->getNodeIndex()+1, $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + } + + $node->adjustNodePath($srcPath, $dstPath); + } + + if (!$this->obj->isNew()) { + $e = $con->commit(); + if (Creole::isError($e)) { return new PropelException(PROPEL_ERROR_DB, $e); } + } + + $this->attachChildNode($node); + } + + /** + * Moves the specified child node in the specified direction. + * + * @param getPhpName() ?>Node Node to move. + * @param int Number of spaces to move among siblings (may be negative). + * @param Connection Connection to use. + * @throws PropelException + */ + function moveChildNode(&$node, $direction, $con = null) + { + Propel::assertParam($con, '', 'moveChildNode', 3); + $con =& Param::get($con); + return new PropelException(PROPEL_ERROR, 'moveChildNode() not implemented yet.'); + } + + /** + * Saves modified object data to the datastore. + * + * @param boolean If true, descendants will be saved as well. + * @param Connection Connection to use. + */ + function save($recurse = false, $con = null) + { + Propel::assertParam($con, '', 'save', 2); + $con =& Param::get($con); + + if ($this->obj->isDeleted()) + return new PropelException(PROPEL_ERROR, 'Cannot save deleted node.'); + + if (substr($this->getNodePath(), 0, 1) == '0') + return new PropelException(PROPEL_ERROR, 'Cannot save unattached node.'); + + if ($this->obj->isColumnModified(getPhpName() ?>NodePeer::NPATH_COLNAME())) + return new PropelException(PROPEL_ERROR, 'Cannot save manually modified node path.'); + + $this->obj->save(Param::set($con)); + + if ($recurse) + { + foreach ($this->childNodes as $key => $childNode) + $this->childNodes[$key]->save($recurse, Param::set($con)); + } + } + + /** + * Removes this object and all descendants from datastore. + * + * @param Connection Connection to use. + * @return void + * @throws PropelException + */ + function delete($con = null) + { + Propel::assertParam($con, '', 'delete', 1); + $con =& Param::get($con); + + if ($this->obj->isDeleted()) + return new PropelException(PROPEL_ERROR, 'This node has already been deleted.'); + + if (!$this->obj->isNew()) + { + getPhpName() ?>NodePeer::deleteNodeSubTree($this->getNodePath(), Param::set($con)); + } + + if ($parentNode =& $this->getParentNode(true, Param::set($con))) + { + $parentNode->detachChildNode($this); + $parentNode->shiftChildNodes(-1, $this->getNodeIndex()+1, $con); + } + + $this->setDeleted(true); + } + + /** + * Compares the object wrapped by this node with that of another node. Use + * this instead of equality operators to prevent recursive dependency + * errors. + * + * @param getPhpName() ?>Node Node to compare. + * @param boolean True if strict comparison should be used. + * @return boolean + */ + function equals(&$node, $strict = false) + { + if ($strict) + return ($this->obj === $node->obj); + else + return ($this->obj == $node->obj); + } + + /** + * This method is used internally when constructing the tree structure + * from the database. To set the parent of a node, you should call + * addChildNode() on the parent. + * @param getPhpName() ?>Node Parent node to attach. + * @return void + * @throws PropelException + */ + function attachParentNode(&$node) + { + if (!$node->hasChildNode($this, true)) + return new PropelException(PROPEL_ERROR, 'Failed to attach parent node for non-child.'); + + $this->parentNode =& $node; + } + + /** + * This method is used internally when constructing the tree structure + * from the database. To add a child to a node you should call the + * addChildNode() method instead. + * + * @param getPhpName() ?>Node Child node to attach. + * @return void + * @throws PropelException + */ + function attachChildNode(&$node) + { + if ($this->hasChildNode($node)) + return new PropelException(PROPEL_ERROR, 'Failed to attach child node. Node already exists.'); + + if ($this->obj->isDeleted() || $node->obj->isDeleted()) + return new PropelException(PROPEL_ERROR, 'Failed to attach node in deleted state.'); + + if ($this->obj->isNew() && !$node->obj->isNew()) + return new PropelException(PROPEL_ERROR, 'Failed to attach non-new child to new node.'); + + if (!$this->obj->isNew() && $node->obj->isNew()) + return new PropelException(PROPEL_ERROR, 'Failed to attach new child to non-new node.'); + + if ($this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $node->getNodeIndex() != $node->getNodePath()) + return new PropelException(PROPEL_ERROR, 'Failed to attach child node. Node path mismatch.'); + + $this->childNodes[$node->getNodeIndex()] =& $node; + ksort($this->childNodes); + + $node->attachParentNode($this); + } + + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this node's parent. + * @param getPhpName() ?>Node Parent node to detach from. + * @return void + * @throws PropelException + */ + function detachParentNode(&$node) + { + if (!$node->hasChildNode($this, true)) + return new PropelException(PROPEL_ERROR, 'Failed to detach parent node from non-child.'); + + unset($node->childNodes[$this->getNodeIndex()]); + $this->parentNode = null; + } + + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this between this node and the specified child. + * @param getPhpName() ?>Node Child node to detach. + * @return void + * @throws PropelException + */ + function detachChildNode(&$node) + { + if (!$this->hasChildNode($node, true)) + return new PropelException(PROPEL_ERROR, 'Failed to detach non-existent child node.'); + + $this->childNodes[$node->getNodeIndex()] = & Propel::null(); + unset($this->childNodes[$node->getNodeIndex()]); + $node->parentNode =& Propel::null(); + } + + /** + * Shifts child nodes in the specified direction and offset index. This + * method assumes that there is already space available in the + * direction/offset indicated. + * + * @param int Direction/# spaces to shift. 1=leftshift, 1=rightshift + * @param int Node index to start shift at. + * @param Connection The connection to be used. + * @return void + * @throws PropelException + */ + function shiftChildNodes($direction, $offsetIdx, &$con) + { + if ($this->obj->isDeleted()) + return new PropelException(PROPEL_ERROR, 'Cannot shift nodes for deleted object'); + + $lastNode =& $this->getLastChildNode(true, Param::set($con)); + $lastIdx = ($lastNode !== null ? $lastNode->getNodeIndex() : 0); + + if ($lastNode === null || $offsetIdx > $lastIdx) + return; + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + if (Propel::isError($con)) { + return $con; + } + + if (!$this->obj->isNew()) + { + // Shift nodes in database. + + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + $n = $lastIdx - $offsetIdx + 1; + $i = $direction < 1 ? $offsetIdx : $lastIdx; + + while ($n--) + { + $srcPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $i; // 1.2.2 + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . ($i+$direction); // 1.2.3 + + $e = getPhpName() ?>NodePeer::moveNodeSubTree($srcPath, $dstPath, Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $i -= $direction; + } + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + } + + // Shift the in-memory objects. + + $n = $lastIdx - $offsetIdx + 1; + $i = $direction < 1 ? $offsetIdx : $lastIdx; + + while ($n--) + { + if (isset($this->childNodes[$i])) + { + $srcPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $i; // 1.2.2 + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . ($i+$direction); // 1.2.3 + + $this->childNodes[$i+$direction] =& $this->childNodes[$i]; + $this->childNodes[$i+$direction]->adjustNodePath($srcPath, $dstPath); + + unset($this->childNodes[$i]); + } + + $i -= $direction; + } + + ksort($this->childNodes); + } + + /** + * Inserts the node and its children at the specified childIdx. + * + * @param getPhpName() ?>Node Node to insert. + * @param int One-based child index to insert at. + * @param Connection Connection to use. + * @param void + */ + function insertNewChildNode(&$node, $childIdx, &$con) + { + if (!$node->obj->isNew()) + return new PropelException(PROPEL_ERROR, 'Failed to insert non-new node.'); + + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + + $node->obj->$setNodePath($this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP() . $childIdx); + $node->obj->save(Param::set($con)); + + $i = 1; + foreach($node->childNodes as $key => $childNode) + $node->insertNewChildNode($node->childNodes[$key], $i++, $con); + } + + /** + * Adjust new/deleted status of node and all children. + * + * @param string Status to change ('New' or 'Deleted') + * @param boolean Value for status. + * @return void + */ + function adjustStatus($status, $b) + { + $setStatus = 'set' . $status; + + $this->obj->$setStatus($b); + + foreach ($this->childNodes as $key => $childNode) + $this->childNodes[$key]->obj->$setStatus($b); + } + + /** + * Adjust path of node and all children. This is used internally when + * inserting/moving nodes. + * + * @param string Section of old path to change. + * @param string New section to replace old path with. + * @return void + */ + function adjustNodePath($oldBasePath, $newBasePath) + { + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + + $this->obj->$setNodePath($newBasePath . + substr($this->getNodePath(), strlen($oldBasePath))); + $this->obj->resetModified(getPhpName() ?>NodePeer::NPATH_COLNAME()); + + foreach ($this->childNodes as $key => $childNode) + $this->childNodes[$key]->adjustNodePath($oldBasePath, $newBasePath); + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/NodePeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/NodePeer.tpl new file mode 100644 index 000000000..356776763 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/NodePeer.tpl @@ -0,0 +1,563 @@ +getColumns() as $col) { + if ($col->isNodeKey()) { + $npath_colname = $table->getName() . '.' . strtoupper($col->getName()); + $npath_phpname = $col->getPhpName(); + $npath_len = $col->getSize(); + $npath_sep = $col->getNodeKeySep(); + break; + } +} + +$db = $table->getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$CLASS = $table->getPhpName() . 'NodePeer'; +echo '<' . '?' . 'php'; + +?> + + +require_once 'getPhpName()) ?>'; +require_once 'getPhpName() . 'Node') ?>'; + + +/** + * Base static class for performing query operations on the tree contained by the + * 'getPhpName() ?>' table. + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + */ +class getPhpName() ?>NodePeer +{ + function NPATH_COLNAME() { return ''; } + function NPATH_PHPNAME() { return ''; } + function NPATH_SEP() { return ''; } + + /** + * Temp function for CodeBase hacks that will go away. + */ + function isCodeBase($con = null) + { + Propel::assertParam($con, '', 'isCodeBase', 1); + $con =& Param::get($con); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + return (get_class($con) == 'ODBCConnection' && + get_class($con->getAdapter()) == 'CodeBaseAdapter'); + } + + /** + * Create a new Node at the top of tree. This method will destroy any + * existing root node (along with its children). + * + * Use at your own risk! + * + * @param getPhpName() ?> Object wrapped by new node. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + * @throws PropelException + */ + function & createNewRootNode(&$obj, $con = null) + { + Propel::assertParam($con, '', 'createNewRootNode', 2); + $con =& Param::get($con); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + if (Propel::isError($con)) { + return $con; + } + + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + $e = getPhpName() ?>NodePeer::deleteNodeSubTree('1', Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $setNodePath = 'set' . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + $obj->$setNodePath('1'); + + $e = $obj->save(Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return new getPhpName() ?>Node(Param::set($obj)); + } + + /** + * Inserts a new Node at the top of tree. Any existing root node (along with + * its children) will be made a child of the new root node. This is a + * safer alternative to createNewRootNode(). + * + * @param getPhpName() ?> Object wrapped by new node. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + * @throws PropelException + */ + function & insertNewRootNode(&$obj, $con = null) + { + Propel::assertParam($con, '', 'insertNewRootNode', 2); + $con =& Param::get($con); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + // Move root tree to an invalid node path. + $e = getPhpName() ?>NodePeer::moveNodeSubTree('1', '0', Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $setNodePath = 'set' . getPhpName() ?>NodePeer::NPATH_PHPNAME(); + + // Insert the new root node. + $obj->$setNodePath('1'); + + $e = $obj->save(Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + // Move the old root tree as a child of the new root. + $e = getPhpName() ?>NodePeer::moveNodeSubTree('0', '1' . getPhpName() ?>NodePeer::NPATH_SEP() . '1', Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return new getPhpName() ?>Node(Param::set($obj)); + } + + /** + * Retrieves an array of tree nodes based on specified criteria. Optionally + * includes all parent and/or child nodes of the matching nodes. + * + * @param Criteria Criteria to use. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return array Array of root nodes. + */ + function & retrieveNodes(&$criteria, $ancestors = false, $descendants = false, $con = null) + { + Propel::assertParam($con, '', 'retrieveNodes', 4); + $con =& Param::get($con); + $criteria =& getPhpName() ?>NodePeer::buildFamilyCriteria($criteria, $ancestors, $descendants); + $rs =& getPhpName() ?>Peer::doSelectRS($criteria, Param::set($con)); + return getPhpName() ?>NodePeer::populateNodes($rs, $criteria); + } + + /** + * Retrieves a tree node based on a primary key. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param mixed getPhpName() ?> primary key (array for composite keys) + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + function & retrieveNodeByPK($pk, $ancestors = false, $descendants = false, $con = null) + { + Propel::assertParam($con, '', 'retrieveNodeByPK', 4); + $con =& Param::get($con); + return new PropelException(PROPEL_ERROR, 'retrieveNodeByPK() not implemented yet.'); + } + + /** + * Retrieves a tree node based on a node path. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param string Node path to retrieve. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + function & retrieveNodeByNP($np, $ancestors = false, $descendants = false, $con = null) + { + Propel::assertParam($con, '', 'retrieveNodeByNP', 4); + $con =& Param::get($con); + $criteria =& new Criteria(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME(), $np, Criteria::EQUAL()); + $criteria =& getPhpName() ?>NodePeer::buildFamilyCriteria($criteria, $ancestors, $descendants); + $rs =& getPhpName() ?>Peer::doSelectRS($criteria, Param::set($con)); + $nodes =& getPhpName() ?>NodePeer::populateNodes($rs, $criteria); + return (count($nodes) == 1 ? $nodes[0] : null); + } + + /** + * Retrieves the root node. + * + * @param string Node path to retrieve. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + function & retrieveRootNode($descendants = false, $con = null) + { + Propel::assertParam($con, '', 'retrieveRootNode', 2); + $con =& Param::get($con); + return getPhpName() ?>NodePeer::retrieveNodeByNP('1', false, $descendants, Param::set($con)); + } + + /** + * Moves the node subtree at srcpath to the dstpath. This method is intended + * for internal use by the BaseNode object. Note that it does not check for + * preexisting nodes at the dstpath. It also does not update the node path + * of any Node objects that might currently be in memory. + * + * Use at your own risk! + * + * @param string Source node path to move (root of the src subtree). + * @param string Destination node path to move to (root of the dst subtree). + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated "onCascadeDelete"s. + * @todo Need to abstract the SQL better. The CONCAT sql function doesn't + * seem to be standardized (i.e. mssql), so maybe it needs to be moved + * to DBAdapter. + */ + function moveNodeSubTree($srcPath, $dstPath, $con = null) + { + Propel::assertParam($con, '', 'moveNodeSubTree', 3); + $con =& Param::get($con); + + if (substr($dstPath, 0, strlen($srcPath)) == $srcPath) + return new PropelException(PROPEL_ERROR, 'Cannot move a node subtree within itself.'); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + /** + * Example: + * UPDATE table + * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74)) + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + $npath = getPhpName() ?>NodePeer::NPATH_COLNAME(); + //the following dot isn`t mean`t a nodeKeySeperator + $setcol = substr($npath, strpos($npath, '.')+1); + $setcollen = ; + $db = Propel::getDb(getPhpName() ?>Peer::DATABASE_NAME()); + + // + if (getPhpName() ?>NodePeer::isCodeBase(Param::set($con))) + { + // This is a hack to get CodeBase working. It will eventually be removed. + // It is a workaround for the following CodeBase bug: + // -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT) + $sql = "UPDATE " . getPhpName() ?>Peer::TABLE_NAME() . " " . + "SET $setcol=" . $db->concatString("'$dstPath'", $db->subString($npath, strlen($srcPath)+1, $setcollen)) . " " . + "WHERE $npath = '$srcPath' OR $npath LIKE '$srcPath" . getPhpName() ?>NodePeer::NPATH_SEP() . "%'"; + + $con->executeUpdate($sql); + } + else + { + // + $sql = "UPDATE " . getPhpName() ?>Peer::TABLE_NAME() . " " . + "SET $setcol=" . $db->concatString('?', $db->subString($npath, '?', '?')) . " " . + "WHERE $npath = ? OR $npath LIKE ?"; + + $stmt =& $con->prepareStatement($sql); + $stmt->setString(1, $dstPath); + $stmt->setInt(2, strlen($srcPath)+1); + $stmt->setInt(3, $setcollen); + $stmt->setString(4, $srcPath); + $stmt->setString(5, $srcPath . getPhpName() ?>NodePeer::NPATH_SEP() . '%'); + $stmt->executeUpdate(); + // + } + // + } + + /** + * Deletes the node subtree at the specified node path from the database. + * + * @param string Node path to delete + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated "onCascadeDelete"s. + */ + function deleteNodeSubTree($nodePath, $con = null) + { + Propel::assertParam($con, '', 'deleteNodeSubTree', 2); + $con =& Param::get($con); + + if ($con === null) + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + + /** + * DELETE FROM table + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + $criteria =& new Criteria(getPhpName() ?>Peer::DATABASE_NAME()); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME(), $nodePath, Criteria::EQUAL()); + $criteria->addOr(getPhpName() ?>NodePeer::NPATH_COLNAME(), $nodePath . getPhpName() ?>NodePeer::NPATH_SEP() . '%', Criteria::LIKE()); + // For now, we call BasePeer directly since getPhpName() ?>Peer tries to + // do a cascade delete. + // getPhpName() ?>Peer::doDelete($criteria, Param::set($con)); + BasePeer::doDelete($criteria, $con); + } + + /** + * Builds the criteria needed to retrieve node ancestors and/or descendants. + * + * @param Criteria Criteria to start with + * @param boolean True if ancestors should be retrieved. + * @param boolean True if descendants should be retrieved. + * @return Criteria + */ + function & buildFamilyCriteria(&$criteria, $ancestors = false, $descendants = false) + { + /* + Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants: + + SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH) + FROM test L, test + WHERE test.NPATH='1.2.3' AND + (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR + test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH))) + ORDER BY UCASE(L.NPATH) ASC + */ + + if ($criteria === null) + $criteria =& new Criteria(getPhpName() ?>::DATABASE_NAME()); + + if (!$criteria->getSelectColumns()) + getPhpName() ?>Peer::addSelectColumns($criteria); + + $db =& Propel::getDb($criteria->getDbName()); + + if (($ancestors || $descendants) && $criteria->size()) + { + // If we are retrieving ancestors/descendants, we need to do a + // self-join to locate them. The exception to this is if no search + // criteria is specified. In this case we're retrieving all nodes + // anyway, so there is no need to do a self-join. + + // The left-side of the self-join will contain the columns we'll + // use to build node objects (target node records along with their + // ancestors and/or descendants). The right-side of the join will + // contain the target node records specified by the initial criteria. + // These are used to match the appropriate ancestor/descendant on + // the left. + + // Specify an alias for the left-side table to use. + $criteria->addAlias('L', getPhpName() ?>Peer::TABLE_NAME()); + + // Make sure we have select columns to begin with. + if (!$criteria->getSelectColumns()) + getPhpName() ?>Peer::addSelectColumns($criteria); + + // Replace any existing columns for the right-side table with the + // left-side alias. + $selectColumns = $criteria->getSelectColumns(); + $criteria->clearSelectColumns(); + foreach ($selectColumns as $colName) + $criteria->addSelectColumn(str_replace(getPhpName() ?>Peer::TABLE_NAME(), 'L', $colName)); + + $a = null; + $d = null; + + $npathL = getPhpName() ?>Peer::alias('L', getPhpName() ?>NodePeer::NPATH_COLNAME()); + $npathR = getPhpName() ?>NodePeer::NPATH_COLNAME(); + $npath_len = ; + + if ($ancestors) + { + // For ancestors, match left-side node paths which are contained + // by right-side node paths. + $a =& $criteria->getNewCriterion($npathL, + "$npathL=" . $db->subString($npathR, 1, $db->strLength($npathL), $npath_len), + Criteria::CUSTOM()); + } + + if ($descendants) + { + // For descendants, match left-side node paths which contain + // right-side node paths. + $d =& $criteria->getNewCriterion($npathR, + "$npathR=" . $db->subString($npathL, 1, $db->strLength($npathR), $npath_len), + Criteria::CUSTOM()); + } + + if ($a) + { + if ($d) $a->addOr($d); + $criteria->addAnd($a); + } + else if ($d) + { + $criteria->addAnd($d); + } + + // Add the target node path column. This is used by populateNodes(). + $criteria->addSelectColumn($npathR); + + // Sort by node path to speed up tree construction in populateNodes() + $criteria->addAsColumn('npathlen', $db->strLength($npathL)); + $criteria->addAscendingOrderByColumn('npathlen'); + $criteria->addAscendingOrderByColumn($npathL); + } + else + { + // Add the target node path column. This is used by populateNodes(). + $criteria->addSelectColumn(getPhpName() ?>NodePeer::NPATH_COLNAME()); + + // Sort by node path to speed up tree construction in populateNodes() + $criteria->addAsColumn('npathlen', $db->strLength(getPhpName() ?>NodePeer::NPATH_COLNAME())); + $criteria->addAscendingOrderByColumn('npathlen'); + $criteria->addAscendingOrderByColumn(getPhpName() ?>NodePeer::NPATH_COLNAME()); + } + + return $criteria; + } + + /** + * This method reconstructs as much of the tree structure as possible from + * the given array of objects. Depending on how you execute your query, it + * is possible for the ResultSet to contain multiple tree fragments (i.e. + * subtrees). The array returned by this method will contain one entry + * for each subtree root node it finds. The remaining subtree nodes are + * accessible from the getPhpName() ?>Node methods of the + * subtree root nodes. + * + * @param array Array of getPhpName() ?>Node objects + * @return array Array of getPhpName() ?>Node objects + */ + function & buildTree(&$nodes) + { + // Subtree root nodes to return + $rootNodes = array(); + $copy = $nodes; + + // Build the tree relations + foreach ($nodes as $key1 => $node) + { + //strrpos fix + $sep = 0; + while(false !== ($last = strpos($node->getNodePath(), getPhpName() ?>NodePeer::NPATH_SEP(), $sep))) { + $sep = $last + strlen(getPhpName() ?>NodePeer::NPATH_SEP()); + } + $parentPath = ($sep != 0 ? substr($node->getNodePath(), 0, $sep - strlen(getPhpName() ?>NodePeer::NPATH_SEP())) : ''); + $parentNode =& Propel::null(); + + // Scan other nodes for parent. + foreach ($copy as $key2 => $pnode) + { + if ($pnode->getNodePath() == $parentPath) + { + $parentNode =& $nodes[$key2]; + break; + } + } + + // If parent was found, attach as child, otherwise its a subtree root + if ($parentNode) + $parentNode->attachChildNode($nodes[$key1]); + else + $rootNodes[] =& $nodes[$key1]; + } + + return $rootNodes; + } + + /** + * Populates the getPhpName() ?> objects from the + * specified ResultSet, wraps them in getPhpName() ?>Node + * objects and build the appropriate node relationships. + * The array returned by this method will only include the initial targets + * of the query, even if ancestors/descendants were also requested. + * The ancestors/descendants will be cached in memory and are accessible via + * the getNode() methods. + * + * @param ResultSet + * @param Criteria + * @return array Array of getPhpName() ?>Node objects. + */ + function & populateNodes(&$rs, &$criteria) + { + $nodes = array(); + $targets = array(); + $values = array(); + $targetfld = count($criteria->getSelectColumns()); + +getChildrenColumn()) { ?> + // set the class once to avoid overhead in the loop + $cls = getPhpName() ?>Peer::getOMClass(); + if (Propel::isError($cls =& Propel::import($cls))) { + return $cls; + } + + + // populate the object(s) + while($rs->next()) + { + if (!isset($nodes[$rs->getString(1)])) + { +getChildrenColumn()) { ?> + // class must be set each time from the record row + $cls =& Propel::import(getPhpName() ?>Peer::getOMClass($rs, 1)); + if (Propel::isError($cls)) { + return $cls; + } + + $obj =& new $cls(); + + if (Propel::isError($e =& $obj->hydrate($rs))) { + return $e; + } + + $nodes[$rs->getString(1)] =& new getPhpName() ?>Node(Param::set($obj)); + } + $node =& $nodes[$rs->getString(1)]; + + if ($node->getNodePath() == $rs->getString($targetfld)) + $targets[$node->getNodePath()] =& $node; + } + + getPhpName() ?>NodePeer::buildTree($nodes); + + foreach($targets as $key => $value) + $values[] =& $targets[$key]; + + return $values; + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/Object.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/Object.tpl new file mode 100644 index 000000000..55dcb0509 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/Object.tpl @@ -0,0 +1,1938 @@ +getDatabase(); +if ($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$parentClass = ClassTools::getBaseClass($table); +?> + +require_once ''; + +isAlias()) +{ + // If any columns in table are BLOB or CLOB then we need to make + // sure those classes are included so we can do things like + // if ($v instanceof Lob) etc. + $includes_lobs = false; + + foreach ($table->getColumns() as $col) { + if ($col->isLob()) { + $includes_lobs = true; + break; + } + } + + if($includes_lobs) + { +?> +include_once 'creole/util/Clob.php'; +include_once 'creole/util/Blob.php'; + + +include_once 'propel/util/Criteria.php'; +getForeignKeys() as $fk) +{ + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $className = $tblFK->getPhpName(); + if ($tblFK->getInterface()) { + $className = $tblFK->getInterface(); + } + + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } +?> + +// (on-demand) include_once ''; +// (on-demand) include_once 'getPhpName() . 'Peer') ?>'; +getForeignKeys() as $fk) */ +?> + +include_once 'getPhpName() . 'Peer') ?>'; + +/** + * Base class that represents a row from the 'getName() ?>' table. + * + * getDescription() ?> + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * You should not use this class directly. It should not even be + * extended; all references should be to getPhpName() ?> class. + * + * @package + */ +class getPhpName() ?> extends +{ + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var getPhpName() ?>Peer + */ + var $peer; + +isAlias()) +{ + foreach ($table->getColumns() as $col) + { + $cptype = $col->getPhpNative(); + $clo=strtolower($col->getName()); + $defVal = ""; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $cptype); + $defaultValue = var_export($val, true); + $defVal = " = " . $defaultValue; + } +?> + /** + * The value for the field. + * @var + */ + var $; + +isLazyLoad()) { +?> + /** + * Whether the lazy-loaded value has been loaded from database. + * This is necessary to avoid repeated lookups if column is NULL. + * @var boolean + */ + var $_isLoaded = false; + +isLazyLoad()) */ + } /* foreach ($table->getColumns() as $col) */ + + foreach ($table->getColumns() as $col) + { + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + $cptype = $col->getPhpNative(); + + $defaultValue = null; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $cptype); + $defaultValue = var_export($val, true); + } + + if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) + { + // these default values are based on the Creole defaults + // the date and time default formats are locale-sensitive + if ($col->getType() === PropelTypes::DATE) { + $defaultfmt = '%x'; + } elseif ($col->getType() === PropelTypes::TIME) { + $defaultfmt = '%X'; + } elseif ($col->getType() === PropelTypes::TIMESTAMP) { + $defaultfmt = 'Y-m-d H:i:s'; + } +?> + /** + * Get the [optionally formatted] `` value. + * getDescription() ?> + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL) on success, + * PropelException, if unable to convert the date/time to timestamp. + */ + function get($format = '') + { +isLazyLoad()) { +?> + if (! $this->_isLoaded && $this-> === null && !$this->isNew()) { + if (($e = $this->load()) !== true) { + return $e; + } + } +isLazyLoad) */ +?> + if ($this-> === null || $this-> === '') { + return null; + } elseif (!is_int($this->)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->); + if ($ts === -1) { + return new PropelException(PROPEL_ERROR_INVALID, "Unable to parse value of as date/time value: " . $this->); + } + } else { + $ts = $this->; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + +getType() != DATE | TIME | TIMESTAMP */ +?> + /** + * Get the column value. + * getDescription() ?> + * + * @return + */ + function get() + { +isLazyLoad()) + { +?> + if (! $this->_isLoaded && $this-> === null && !$this->isNew()) { + if (($e = $this->load()) !== true) { + return $e; + } + } + +isLazyLoad */ +?> + return $this->; + } +getType() != DATE | TIME | TIMESTAMP */ +?> + +isLazyLoad()) + { +?> + /** + * Load the value for the [lazy-load] `` column. + * + * This method performs an additional query to return the value for + * the `` column, since it is not populated by + * the hydrate() method. + * + * @return void + * @returns mixed boolean TRUE on success, PropelException - any underlying error will be wrapped and re-thrown. + */ + function load() + { + $c = $this->buildPkeyCriteria(); + $c->addSelectColumn(getPhpName()) ?>()); + + $rs =& getPhpName()?>Peer::doSelectRS($c); + + if (Propel::isError($e =& $rs) || Propel::isError($e = $rs->next())) { + return new PropelException(PROPEL_ERROR, "Error loading value for `` column on demand.", $e); + } + +getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) + { + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: +?> + $this-> = $rs->get(1, null); + + $this-> = $rs->get(1); +getType */ +?> + if (Propel::isError($this->)) { + return new PropelException(PROPEL_ERROR, "Error loading value for `` column on demand.", $this->); + } + + $this->_isLoaded = true; + + return true; + } + +isLazyLoad */ + + if (! $table->isReadOnly()) + { + $throwsClause = ""; + if ($complexObjectModel) + { + if ($col->isForeignKey()) { + $throwsClause = "@throws PropelException"; + } + if (count($col->getReferrers()) > 0 ) { + if ($throwsClause == "") { + $throwsClause = "@throws PropelException"; + } + } + } + if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + $throwsClause = "@throws PropelException - If passed [not-null] date/time is in an invalid format."; + } +?> + /** + * Set the value of `` + * getDescription() ?> + * + * @param $v new value + * @return void + * + */ + function set($v) + { +isLazyLoad()) + { +?> + // explicitly set the is-loaded flag to true for this lazy load col; + // it doesn't matter if the value is actually set or not (logic below) as + // any attempt to set the value means that no db lookup should be performed + // when the get() method is called. + $this->_isLoaded = true; +isLazyLoad */ + + if ($addSaveMethod) + { + if ($col->isLob()) + { + // Setting of LOB columns gets some special handling + if ($col->getPropelType() === PropelTypes::BLOB || $col->getPropelType() === PropelTypes::LONGVARBINARY ) { + $lobClass = "Blob"; + } else { + $lobClass = "Clob"; + } +?> + // if the passed in parameter is the *same* object that + // is stored internally then we use the Lob->isModified() + // method to know whether contents changed. + if (is_a($v, 'Lob') && $v === $this->) { + $changed = $v->isModified(); + } else { + $changed = ($this-> !== $v); + } + if ($changed) { + if ( ! is_a($v, 'Lob') ) { + $obj = new (); + $obj->setContents($v); + } else { + $obj =& $v; + } + $this-> = $obj; + $this->modifiedColumns[] = getPhpName()) ?>(); + } +getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) + { + // Setting a DATE/TIME value gets some special handling. +?> + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1) { + return new PropelException(PROPEL_ERROR_INVALID, "Unable to parse date/time value for from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + + if ($this-> !== $ts || $ts === ) { + $this-> = $ts; + $this->modifiedColumns[] = getPhpName()) ?>(); + } + + if ($this-> !== $v || $v === ) { + $this-> = $v; + $this->modifiedColumns[] = getPhpName()) ?>(); + } + + + $this-> =& $v; + +isForeignKey()) + { + $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); + $colFK = $tblFK->getColumn($col->getRelatedColumnName()); + if ($col->isMultipleFK() || $col->getRelatedTableName() == $table->getName()) { + $relCol = ""; + foreach ($col->getForeignKey()->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $relCol .= $column->getPhpName(); + } + if ($relCol != "") { + $relCol = "RelatedBy".$relCol; + } + $varName = "a".$tblFK->getPhpName() . $relCol; + } else { + $varName = "a".$tblFK->getPhpName(); + } +?> + if ($this-> !== null && $this->->getgetPhpName() ?>() !== $v) { + /* + * Save a reference to null instead of null directly as this would + * overwrite a previous stored getPhpName() ?> object. + */ + $this-> =& Propel::null(); + } +isForeignKey) */ + + foreach ($col->getReferrers() as $fk) + { + // used to be getLocalForeignMapping() which did not work. + $flmap = $fk->getForeignLocalMapping(); + $fkColName = $flmap[$col->getName()]; + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) + { + $colFK = $tblFK->getColumn($fkColName); + if ($colFK->isMultipleFK()) { + $collName = "coll" . $tblFK->getPhpName() . "sRelatedBy" . $colFK->getPhpName(); + } else { + $collName = "coll" . $tblFK->getPhpName() . "s"; + } +?> + + // update associated getPhpName() ?> + + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + $this->[$i]->setgetPhpName()?>($v); + } + } + + } + +isReadOnly() */ + } /* foreach ($table->getColumns() as $col) */ +?> + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + function hydrate(&$rs, $startcol = 1) + { + assert('is_a($rs, "ResultSet")'); + +getColumns() as $col) + { + if (! $col->isLazyLoad()) + { + $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) + { + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: +?> + if (Creole::isError($value = $rs->get($startcol + , null))) { + return new PropelException(PROPEL_ERROR_DB, "Error populating getPhpName()?> object", $value); + } + + $this-> = $value; + + if (Creole::isError($value = $rs->get($startcol + ))) { + return new PropelException(PROPEL_ERROR_DB, "Error populating object", $value); + } + + $this-> = $value; +isLazyLoad() */ + } /* foreach ($table->getColumns() as $col) */ + + if ($addSaveMethod) + { +?> + $this->resetModified(); + + $this->setNew(false); + return $startcol + ; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + function &buildPkeyCriteria() + { + $criteria = new Criteria(getPhpName()?>Peer::DATABASE_NAME()); +getColumns() as $col) + { + $clo = strtolower($col->getName()); + if ($col->isPrimaryKey()) + { +?> + $criteria->add(getPhpName()) ?>(), $this->); +isPrimaryKey */ + } /* foreach ($table->getColumns() as $col) */ +?> + return $criteria; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + function &buildCriteria() + { + $criteria = new Criteria(getPhpName()?>Peer::DATABASE_NAME()); + +getColumns() as $col) + { + $clo = strtolower($col->getName()); +?> + if ($this->isColumnModified(getPhpName()) ?>())) { + $criteria->add(getPhpName()) ?>(), $this->); + } + + + return $criteria; + } + +isAlias */ + +// association code +if ($complexObjectModel) +{ + $pVars = array(); // Array of object set method names for later reference. + $aVars = array(); // Array of object field names for later reference. + + foreach ($table->getForeignKeys() as $fk) + { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $className = $tblFK->getPhpName(); + + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } + + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol != "") { + $relCol = "RelatedBy" . $relCol; + } + + $pVarName = $className . $relCol; + $varName = "a" . $pVarName; + $retVal = ($pVars[] = $pVarName); + $retVal = ($aVars[] = $varName); +?> + /** + * @var + */ + var $; + + /** + * Declares an association between this object and a object + * + * @param $v + * @return void + * @throws PropelException + */ + function set(&$v) + { +getLocalColumns() as $columnName) + { + $column = $table->getColumn($columnName); + $lfmap = $fk->getLocalForeignMapping(); + $colFKName = $lfmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + if ($v === null) { + $this->setgetPhpName() ?>(getPhpDefaultValue()) ?>); + } else { + $this->setgetPhpName() ?>($v->getgetPhpName() ?>()); + } + + + $this-> =& $v; + } + +getLocalColumns() as $columnName) + { + $column = $table->getColumn($columnName); + $cptype = $column->getPhpNative(); + $clo = strtolower($column->getName()); + if ($cptype == "integer" || $cptype == "float" || $cptype == "double") { + $conditional .= $and . "\$this->". $clo ." > 0"; + } elseif($cptype == "string") { + $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)"; + } else { + $conditional .= $and . "\$this->" . $clo ." !== null"; + } + $arglist .= $comma . "\$this->" . $clo; + $and = " && "; + $comma = ", "; + $argsize = $argsize + 1; + } + + $pCollName = $table->getPhpName() . 's' . $relCol; +?> + /** + * Get the associated object + * + * @return The associated object. + * @throws PropelException + */ + function & get() + { + // include the Peer class + include_once 'Peer.php'; + + if ($this-> === null && ()) + { +isAlias()) + { + if ($argsize > 1) { +?> + $ =& Peer::retrieveByPK(); + + $ =& Peer::retrieveByPK(); + 1) */ + } + else + { + if ($argsize > 1) { +?> + $ =& Peer::retrieveByPK(); + + $ =& Peer::retrieveByPK(); +isAlias +?> + if (Propel::isError($)) { return $; } + + $this-> =& $; + + /* The following can be used instead of the line above to + guarantee the related object contains a reference + to this object, but this level of coupling + may be undesirable in many circumstances. + As it can lead to a db query with many results that may + never be used. + $obj = Peer::retrieveByPK(); + $obj->add($this); + */ + } + + return $this->; + } + + /** + * Provides convenient way to set a relationship based on a + * key. e.g. + * $bar->setFooKey($foo->getPrimaryKey()) + * +getLocalColumns()) > 1) { +?> + * Note: It is important that the xml schema used to create this class + * maintains consistency in the order of related columns between + * getName() ?> and getName() ?>. + * If for some reason this is impossible, this method should be + * overridden in getPhpName() ?>. + + * @return void + * @throws PropelException + */ + function setKey($key) + { +getLocalColumns()) > 1) + { + $i = 0; + foreach ($fk->getLocalColumns() as $colName) + { + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); +?> + $this->setgetPhpName() ?>( () $key[] ); +getLocalColumns(); + $colName = $lcols[0]; + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); +?> + $this->setgetPhpName() ?>( () $key); + + } + +getReferrers() as $fk) + { + $tblFK = $fk->getTable(); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } + + $className = $tblFK->getPhpName(); + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK() || $tblFK->getName() == $table->getName()) { + // if there are seeral foreign keys that point to the same table + // then we need to generate methods like getAuthorRelatedByColName() + // instead of just getAuthor(). Currently we are doing the same + // for self-referential foreign keys, to avoid confusion. + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $suffix = ""; + $relCol = $className . "s"; + $relColMs = $className; + } else { + $suffix = "RelatedBy" . $relatedByCol; + $relCol= $className . "sRelatedBy" . $relatedByCol; + $relColMs= $className . "RelatedBy" . $relatedByCol; + } + $collName = "coll" . $relCol; +?> + /** + * Collection to store aggregation of + * @var array + */ + var $; + + /** + * Temporary storage of to save a possible db hit in + * the event objects are add to the collection, but the + * complete collection is never requested. + * @return void + */ + function init() + { + if ($this-> === null) { + $this-> = array(); + } + } + + /** + * Method called to associate a getPhpName() ?> object to this object + * through the foreign key attribute + * + * @param $l $className + * @return void + * @throws PropelException + */ + function add(/**/ &$l) + { + $this->[] =& $l; + $l->setgetPhpName() . $suffix ?>($this); + } + + /** + * The criteria used to select the current contents of . + * @var Criteria + */ + var $lastCriteria = null; + + /** + * Returns the number of related + * + * @param Criteria $criteria + * @param boolean $distinct + * @throws PropelException + */ + function count($criteria = null, $distinct = false) + { + // include the Peer class + include_once 'Peer.php'; + if ($criteria === null) { + $criteria = new Criteria(); + } +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + // used to be getLocalForeignMapping() but that didn't seem to work + // (maybe a problem in translation of HashTable code to PHP). + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add((), $this->getgetPhpName() ?>() ); +getForeignColumns() +?> + return Peer::doCount($criteria, $distinct); + } + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this getPhpName() ?> has previously + * been saved, it will retrieve related ${relCol} from storage. + * If this getPhpName() ?> is new, it will return + * an empty collection or the current collection, the criteria + * is ignored on a new object. + * + * @param Criteria $criteria + * @throws PropelException + */ + function & get($criteria = null) + { + // include the Peer class + include_once 'Peer.php'; + + if ($criteria === null) { + $criteria = new Criteria(); + } + + if ($this-> === null) + { + if ($this->isNew()) { + $this-> = array(); + } else { +getForeignColumns() as $columnName) + { + $column = $table->getColumn($columnName); + // used to be getLocalForeignMapping() but that didn't seem to work + // (maybe a problem in translation of HashTable code to PHP). + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add((), $this->getgetPhpName() ?>() ); +getForeignColumns()) */ +?> + + $ =& Peer::doSelect($criteria); + if (Propel::isError($)) { return $; } + + $this-> =& $; + } + } else { + // criteria has no effect for a new object + if (!$this->isNew()) + { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +getForeignColumns() as $columnName) + { + $column = $table->getColumn($columnName); + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add((), $this->getgetPhpName() ?>()); + +getForeignColumns()) */ +?> + if (!isset($this->lastCriteria) || !$this->lastCriteria->equals($criteria)) + { + $ =& Peer::doSelect($criteria); + if (Propel::isError($)) { return $; } + + $this-> =& $; + } + } + } + + $this->lastCriteria = $criteria; + + return $this->; + } + +getForeignKeys() as $dummyFK) { + $countFK = $countFK + 1; + } + +// ------------------------------------------------------------ +// + if ($countFK >= 1) + { + $lastTable = ""; + foreach ($tblFK->getForeignKeys() as $fk2) + { + // Add join methods if the fk2 table is not this table or + // the fk2 table references this table multiple times. + + $doJoinGet = true; + if ( $fk2->getForeignTableName() == $table->getName() ) { + $doJoinGet = false; + } + + foreach ($fk2->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $doJoinGet = true; + } + } + + $tblFK2 = $table->getDatabase()->getTable($fk2->getForeignTableName()); + $doJoinGet = !$tblFK2->isForReferenceOnly(); + $relatedByCol2 = ""; + foreach ($fk2->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol2 .= $column->getPhpName(); + } + } + + $fkClassName = $tblFK2->getPhpName(); + + // do not generate code for self-referencing fk's, it would be + // good to do, but it is just not implemented yet. + if ($className == $fkClassName) { + // $doJoinGet = false; -- SELF REFERENCING FKs UNDER TESTING + } + + if ($relatedByCol2 == "") { + $relCol2 = $fkClassName; + } else { + $relCol2 = $fkClassName . "RelatedBy". $relatedByCol2; + } + + if ( $relatedByCol == "") { + // nothing? + } else { + if ( $relatedByCol == $relatedByCol2 ) { + $doJoinGet = false; + } + } + + if ($doJoinGet) + { +?> + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this getPhpName() ?> is new, it will return + * an empty collection; or if this getPhpName() ?> has previously + * been saved, it will retrieve related from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in getPhpName() ?>. + */ + function & getJoin($criteria = null) + { + // include the Peer class + include_once 'Peer.php'; + + if ($criteria === null) { + $criteria = new Criteria(); + } + + if ($this-> === null) { + if ($this->isNew()) { + $this-> = array(); + } else { +getForeignColumns() as $columnName) + { + $column = $table->getColumn($columnName); + $flMap = $fk->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add((), $this->getgetPhpName() ?>()); +getForeignColumns()) */ +?> + + $ =& Peer::doSelectJoin($criteria); + if (Propel::isError($)) { return $; } + + $this-> =& $; + } + } else { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +getForeignColumns() as $columnName) + { + $column = $table->getColumn($columnName); + $flMap = $fk->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add((), $this->getgetPhpName() ?>()); + +getForeignColumns()) */ +?> + if (!isset($this->lastCriteria) || !$this->lastCriteria->equals($criteria)) + { + $ =& Peer::doSelectJoin($criteria); + if (Propel::isError($)) { return $; } + + $this-> =& $; + } + } + $this->lastCriteria = $criteria; + + return $this->; + } + +getForeignKeys() as $fk2) {*/ + } /* if countFK >= 1 */ + } /*ends foreach over table->getReferrers() */ +} /* the if(complexObjectModel) */ + +// +// add GenericAccessors or GenericMutators? +// +if (!$table->isAlias() && ($addGenericAccessors || ($addGenericMutators && !$table->isReadOnly()))) +{ + $tableColumns = $table->getColumns(); + $tablePhpname = $table->getPhpName(); +?> + /** + * Generate a list of field names. + * + * @return array A list of field names + */ + function & getFieldNames($type = TYPE_FIELDNAME) + { + static $fieldNames = array( + TYPE_PHPNAME => array ('getPhpName(); ?>', ), + TYPE_COLNAME => array ('getName() . '.' . strtoupper($col->getName()) ?>', ), + TYPE_FIELDNAME => array ('getName(); ?>', ), + TYPE_NUM => array ( $col) { echo $num; ?>, ) + ); + + if (!isset($fieldNames[$type])) { + return new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + + return $fieldNames[$type]; + } + + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + function translateFieldName($name, $fromType, $toType) + { + static $fieldKeys = array ( + TYPE_PHPNAME => array ( $col) { ?>'getPhpName(); ?>' => , ), + TYPE_COLNAME => array ( $col) { ?>'getName() . '.' . strtoupper($col->getName()) ?>' => , ), + TYPE_FIELDNAME => array ( $col) { ?>'getName(); ?>' => , ), + TYPE_NUM => array ( $col) { echo $num; ?>, ) + ); + + $toNames =& $this->getFieldNames($toType); + $key = $fieldKeys[$fromType][$name]; + + if ($key === false) { + return new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r($fromNames, true)); + } + + return $toNames[$key]; + } + + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + function & getByName($name, $type = TYPE_COLNAME) + { + $pos = $this->translateFieldName($name, $type, TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified + * in the xml schema. Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + function & getByPosition($pos) + { + switch($pos) + { +getColumns() as $col) + { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative();// not safe to use it because some methods may return objects (Blob) +?> + case : + return $this->get(); + break; + + default: + return null; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + function & toArray($keyType = TYPE_PHPNAME) + { + $keys =& $this->getFieldNames($keyType); + $result = array( +getColumns() as $num => $col) { +?> + $keys[] => $this->getgetPhpName() ?>(), + + ); + return $result; + } + + + + +isReadOnly()) { ?> + + /** + * Sets a field value from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + function setByName($name, &$value, $type = TYPE_COLNAME) + { + $names =& $this->getFieldnames($type); + $pos = array_search($name, $names); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified + * in the xml schema. Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + function setByPosition($pos, &$value) + { + switch($pos) + { +getColumns() as $col) + { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); +?> + case : + $this->set($value); + break; + + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the (peer) column name (e.g. + * 'book.AUTHOR_ID') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + function fromArray(&$arr, $keyType = TYPE_COLNAME) + { + $keys =& $this->getFieldNames($keyType); +getColumns() as $num => $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); +?> + if (array_key_exists($keys[], $arr)) $this->set($arr[$keys[]]); + + } + + + +isAlias() && isset($addSaveMethod) && $addSaveMethod && ! $table->isReadOnly()) { ?> + + /** + * Removes this object from datastore and sets delete attribute. + * + * @return mixed TRUE on success, PropelException on failure. + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + function delete() + { + if ($this->isDeleted()) { + return new PropelException(PROPEL_ERROR, "This object has already been deleted."); + } + + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + $e = getPhpName() ?>Peer::doDelete($this, Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $this->setDeleted(true); + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return true; + } + + + + /** + * flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + var $alreadyInSave = false; + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @return mixed TRUE on success, PropelException on failure. + */ + function save() + { + if ($this->isDeleted()) { + return new PropelException(PROPEL_ERROR, "You cannot save an object that has been deleted."); + } + + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + $e = $this->doSave(Param::set($con)); + if (Propel::isError($e)) { $con->rollback(); return $e; } + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return true; + } + + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. + * + * @return void + * @throws PropelException + */ + + function doSave($con = null) + + function save() + + { + if ($this->isDeleted()) { + return new PropelException(PROPEL_ERROR, "You cannot save an object that has been deleted."); + } + + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + + + /* [MA] temporarily check */ + Propel::assertParam($con, 'getPhpName(); ?>', 'save', 1); + + if (! $this->alreadyInSave) { + $this->alreadyInSave = true; + + + // We call the save method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this-> !== null) { + if ($this->->isModified()) { + if (Propel::isError($e = $this->->save())) { + return $e; + } + } + $this->set($this->); + } + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = getPhpName() ?>Peer::doInsert($this, $conParam::set($con)); + if (Propel::isError($pk)) { return $pk; } +getIdMethod() != "none") { + if (count($pks = $table->getPrimaryKey())) { + foreach ($pks as $pk) { + if ($pk->isAutoIncrement()) { +?> + $this->setgetPhpName();?>( $pk ); //[IMV] update autoincrement primary key + + $this->setNew(false); + } + else { + $e = getPhpName() ?>Peer::doUpdate($this, $conParam::set($con)); + if (Propel::isError($e)) { return $e; } + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + +getReferrers() as $fk) + { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) + { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $relCol = $className . "s"; + } else { + $relCol = $className . "sRelatedBy" . $relCol; + } + + $collName = "coll" . $relCol; +?> + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + if (Propel::isError($e = $this->[$i]->save())) { + return $e; + } + } + } + + + $this->alreadyInSave = false; + } + + + return true; + } + +isAlias && isset .... */ + +if (! $table->isAlias() && ! $table->isReadOnly()) +{ +?> + /** + * Validates the objects modified field values. + + * This includes all objects related to this table. + + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * + * @return mixed true if all columns pass validation + * or an array of ValidationFailed objects for columns that fail. + */ + function & validate($columns = null) + { + if ($columns) + { + return getPhpName()?>Peer::doValidate($this, $columns); + } + + + return getPhpName()?>Peer::doValidate($this); + + return $this->doValidate(); + + } + + + /** + * flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + var $alreadyInValidation = false; + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then true is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. + */ + function & doValidate() + { + if (! $this->alreadyInValidation) + { + $this->alreadyInValidation = true; + $retval = null; + $failureMap = array(); + + + // We call the validate method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this-> !== null) { + if (($retval = $this->->validate()) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + } + + + if (($retval = getPhpName()?>Peer::doValidate($this)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + +getReferrers() as $fk) + { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) + { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $relCol = $className . "s"; + } else { + $relCol = $className . "sRelatedBy" . $relCol; + } + + $collName = "coll" . $relCol; +?> + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + if (($retval = $this->[$i]->validate()) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + } + } + + + $this->alreadyInValidation = false; + return (!empty($failureMap) ? $failureMap : true); + } + + return true; + } + +isAlias()) +{ + if (! $table->isReadOnly()) + { + $throwsClause = "@throws PropelException"; + if (count($table->getPrimaryKey()) == 1) + { + $pkeys = $table->getPrimaryKey(); + $col = $pkeys[0]; + $clo=strtolower($col->getName()); + $cptype= $col->getPhpNative(); +?> + /** + * Set the PrimaryKey. + * + * @param mixed Primary key. + * @return void + * + */ + function setPrimaryKey($key) + { + $this->setgetPhpName() ?>($key); + } + +getPrimaryKey()) > 1) + { +?> + var $pks = array(); + + /** + * Set the PrimaryKey. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + * @throws PropelException + */ + function setPrimaryKey($keys) + { +getPrimaryKey() as $pk) + { + $pktype = $pk->getPhpNative(); +?> + $this->setgetPhpName() ?>($keys[]); +getPrimaryKey() as $pk) */ +?> + } + +getPrimaryKey()) == 1) */ +?> + + /** + * Dummy primary key setter. + * For now this function needs to exist because it's mandated in the Persistent + * interface, and because other methods will attempt to set the primary key. + * + * This should be removed in favor of more complex template work. + */ + function setPrimaryKey($pk) + { + // do nothing, because this doesn't support primary keys + } +getPrimaryKey()) == 1) */ + } /* if ! $table->isReadOnly() */ +?> + + /** + * Returns an id that differentiates this object from others + * of its class. + * @return getPrimaryKey()) === 0) { echo "null"; } elseif (count($table->getPrimaryKey()) > 1) { echo "array"; } else { $pkeys = $table->getPrimaryKey(); echo $pkeys[0]->getPhpType(); } ?> + */ + function getPrimaryKey() + { +getPrimaryKey()) == 1) { +?> + return $this->getgetPrimaryKey(); echo $pkeys[0]->getPhpName()?>(); +getPrimaryKey()) > 1) { + $i = 0; + foreach ($table->getPrimaryKey() as $pk) { +?> + $this->pks[] = $this->getgetPhpName() ?>(); +getPrimaryKey() as $pk) */ +?> + return $this->pks; + + + return null; + + } + +isAbstract()) + { +?> + /** + * Makes a copy of this object. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * + + * @return getPhpName() ?> Clone of current object. + * @throws PropelException + */ + function copy($deepCopy = false) + { + $copyObj = new getPhpName() ?>(); +getColumns() as $pkcol) { + if ($pkcol->isPrimaryKey()) { + $pkcols[] = $pkcol->getName(); + } + } + + foreach ($table->getColumns() as $col) + { + if (!in_array($col->getName(), $pkcols)) { +?> + $copyObj->setgetPhpName()?>($this->getName()) ?>); +getReferrers()) > 0) + { +?> + + if ($deepCopy) { + // important: setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); +getReferrers() as $fk) + { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) + { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $pCollName = $className . "s"; + $pCollNameNoS = $className; + } else { + $pCollName = $className . "sRelatedBy".$relCol; + $pCollNameNoS = $className . "RelatedBy".$relCol; + } +?> + + foreach($this->get() as $relObj) { + $copyObj->add($relObj->copy()); + } + + } /* if ($deepCopy) */ + 0 ) */ +?> + + $copyObj->setNew(true); +getColumns() as $col) + { + if ($col->isPrimaryKey()) + { + $coldefval = $col->getDefaultValue(); + // This seems to work pretty well for getting + // the right value (including NULL) + $coldefval = var_export($coldefval, true); +?> + $copyObj->setgetPhpName()?>(); // this is a pkey column, so set to default value +isPrimaryKey + } // foreach +?> + + return $copyObj; + } + +isAbstract()) */ +?> + /** + * Returns a peer instance associated with this om. Since Peer classes + * are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return getPhpName() ?>Peer + */ + function & getPeer() + { + static $instance; + + if ($instance === null) { + $instance = new getPhpName()?>Peer(); + } + + return $instance; + } +isAlias */ +?> + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php4/Peer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php4/Peer.tpl new file mode 100644 index 000000000..aba3ea6d2 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php4/Peer.tpl @@ -0,0 +1,1780 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +echo '<' . '?' . 'php'; + +$CLASS = $table->getPhpName() . 'Peer'; +$basePeerClass = ClassTools::getBasePeer($table); +$basePeerClassname = ClassTools::classname($basePeerClass); +?> + +require_once ''; + +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by getPhpName() ?>Peer::getOMClass() +include_once 'getPhpName()) ?>'; +getForeignKeys() as $fk) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + + if (!$tblFK->isForReferenceOnly()) { +?> +include_once 'getPhpName()) ?>'; +include_once 'getPhpName() . 'Peer') ?>'; +isForReferenceOnly() +} // foreach +?> + +/** + * Base static class for performing query and update operations on the 'getName() ?>' table. + * + * getDescription() ?> + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + */ +class getPhpName() ?>Peer +{ +isAlias()) { ?> + + /** the default database name for this class */ + function DATABASE_NAME() { return "getDatabase()->getName() ?>"; } + + /** the table name for this class */ + function TABLE_NAME() { return "getName() ?>"; } + +getColumns() as $col) { ?> + /** the column name for the getName()) ?> field */ + function () { return "getName() . '.' . strtoupper($col->getName()) ?>"; } + +isAlias()) */ ?> + + /** number of columns for this peer (static) */ + function numColumns() { return getNumColumns() ?>; } + + /** number of lazy load columns for this peer */ + function numLazyLoadColumns() { return getNumLazyLoadColumns() ?>; } + + /** A class that can be returned by this peer. */ + function CLASS_DEFAULT() { return "getPhpName() ?>"; } + + /** The PHP to DB Name Mapping (static) */ + var $phpNameMap = null; + + /** + * @access private static + */ + function & getInstance() + { + static $instance; + + if ($instance === null) { + $instance = new getPhpName()?>Peer(); + } + + return $instance; + } + + /** + * @return MapBuilder the map builder for this peer + * @access public static + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function & getMapBuilder() + { + include_once 'getPhpName() . 'MapBuilder') ?>'; + return ::getMapBuilder(getPhpName() ?>MapBuilder::CLASS_NAME()); + } + + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @access public static + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @todo Consider having template build the array rather than doing it at runtime. + */ + function getPhpNameMap() + { + $self =& getPhpName()?>Peer::getInstance(); + + if ($self->phpNameMap === null) { + $map = $self->getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + $self->phpNameMap = $nameMap; + } + return $self->phpNameMap; + } +isAlias()) { + + + if ($table->getChildrenColumn()) { + + $col = $table->getChildrenColumn(); + $tfc = $table->getPhpName(); + $cfc = $col->getPhpName(); + + if ($col->isEnumeratedClasses()) { + + if ($col->isPrimitiveNumeric()) $quote = ""; + else $quote = '"'; + + foreach ($col->getChildren() as $child) { + $childpkg = ($child->getPackage() ? $child->getPackage() : $package); +?> + /** A key representing a particular subclass */ + function CLASSKEY_getKey()) ?>() { return getKey() . $quote ?>; } + + /** A class that can be returned by this peer. */ + function CLASSNAME_getKey()) ?>() { return "getClassName() ?>"; } +isenumerated...() */ + } /* if table->getchildrencolumn() */ +?> + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. getPhpName() ?>Peer::COLUMN_NAME). + * @return string + * @access public static + */ + function alias($alias, $column) + { + return $alias . substr($column, strlen(getPhpName()?>Peer::TABLE_NAME())); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @access public static + */ + function addSelectColumns(/*Criteria*/ &$criteria) + { + Propel::typeHint($criteria, 'Criteria', '', 'addSelectColumns', 1); + +getColumns() as $col) { + if (! $col->isLazyLoad()) { +?> + $criteria->addSelectColumn(getPhpName()?>Peer::()); + + } + +hasPrimaryKey()) { + $pk = $table->getPrimaryKey(); + $countColumn = $table->getName() . "." . strtoupper($pk[0]->getName()); + } +?> + + function COUNT() { return "COUNT()"; } + function COUNT_DISTINCT() { return "COUNT(DISTINCT )"; } + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria a Criteria object. + * @param boolean $distinct Whether to select only distinct columns. + * @param Connection $con An optional Connection object. + * + * @return int Number of matching rows. + */ + function doCount(/*Criteria*/ $criteria, $distinct = false, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doCount', 3); + Propel::typeHint($criteria, 'Criteria', '', 'doCount', 1); + + /* + * clear out anything that might confuse the ORDER BY clause. + * Note: unlike php5 version $criteria is passed by value and has not to be cloned. + */ + $criteria->clearSelectColumns(); + $criteria->clearOrderByColumns(); + + if ($distinct || in_array(Criteria::DISTINCT(), $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(getPhpName()?>Peer::COUNT_DISTINCT()); + } else { + $criteria->addSelectColumn(getPhpName()?>Peer::COUNT()); + } + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs =& getPhpName()?>Peer::doSelectRS($criteria, $con); + if (Propel::isError($rs)) { return $rs; } + + if ($rs->next() === true) { + return $rs->getInt(1); + } + + /* no rows returned; we infer that means 0 matches */ + return 0; + } + + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria Object used to create the SELECT statement. + * @param Connection $con An optional Connection object. + * + * @return mixed getPhpName() ?> on success, NULL on failure. + */ + function & doSelectOne($criteria, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelectOne', 2); + + $criteria->setLimit(1); + + $objects =& getPhpName()?>Peer::doSelect($criteria, $con); + if (Propel::isError($objects)) { return $objects; } + + if ($objects) { + return $objects[0]; + } + + return null; + } + + /** + * Method to do selects. + * + * @param Criteria $criteria Object used to create the SELECT statement. + * @param Connection $con An optional Connection object. + * + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function & doSelect($criteria, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelect', 2); + + $rs =& getPhpName()?>Peer::doSelectRS($criteria, $con); + if (Propel::isError($rs)) { return $rs; } + + return getPhpName()?>Peer::populateObjects($rs); + } + + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria + * @param Connection $con An optional Connection object. + * + * @return ResultSet The resultset object with numerically-indexed fields. + * PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @see ::doSelect() + */ + function & doSelectRS($criteria, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelectRS', 2); + + /* [MA] do not retrieve connection here, BasePeer::doSelect will do */ + + if (!$criteria->getSelectColumns()) { + getPhpName()?>Peer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return ::doSelect($criteria, $con); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @return Array of getPhpName()?> objects on success OR + * PropelException Any exceptions caught during processing will be + * returned wrapped into a PropelException. + */ + function & populateObjects(/*ResultSet*/ &$rs) + { + $results = array(); + + if (! is_a($rs, 'ResultSet')) { + return new PropelException(PROPEL_ERROR, "parameter not of type 'ResultSet'"); + } + +getChildrenColumn()) { ?> + // set the class once to avoid overhead in the loop + $cls = getPhpName() ?>Peer::getOMClass(); + + if (Propel::isError($cls =& Propel::import($cls))) { + return $cls; + } + + + // populate the object(s) + while($rs->next()) + { +getChildrenColumn()) { ?> + // class must be set each time from the record row + $cls =& Propel::import(getPhpName() ?>Peer::getOMClass($rs, 1)); + if (Propel::isError($cls)) { + return $cls; + } + $obj =& new $cls(); + + if (Propel::isError($e =& $obj->hydrate($rs))) { + return $e; + } + + $results[] =& $obj; + + $obj =& new $cls(); + + if (Propel::isError($e =& $obj->hydrate($rs))) { + return $e; + } + + $results[] =& $obj; + + } + + return $results; + } + +isAlias() */ ?> + +getChildrenColumn()) { + + $col = $table->getChildrenColumn(); +?> + + /** + * The returned Class will contain objects of the default type or + * objects that inherit from the default. + * + * @param ResultSet $rs ResultSet with pointer to record containing om class. + * @param int $colnum Column to examine for OM class information (first is 1). + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function getOMClass(/*ResultSet*/ &$rs, $colnum) + { + $c = null; + +isEnumeratedClasses()) { ?> + + $omClass = null; + $classKey = $rs->getString($colnum - 1 + getPosition() ?>); + + switch($classKey) + { +getChildren() as $child) { +?> + case getPhpName()?>Peer::CLASSKEY_getKey()) ?>(): + $omClass = getPhpName()?>Peer::CLASSNAME_getKey()) ?>(); + break; + + default: +isAbstract()) { ?> + $error = "You must implement the getOMClass method in your" + ." Peer object in order for things to work properly." + ." This method should return the proper Class that" + ." represents the Peer's Business Object."; + + return new PropelException(PROPEL_ERROR, $error); + + + $omClass = getPhpName()?>Peer::CLASS_DEFAULT(); + + + + } // switch + + $c = $omClass; + + + + $c =& Propel::import($rs->getString($colnum - 1 + getPosition() ?>)); + + if (Propel::isError($c)) { + return $c; + } + + + return $c; + } + +getchildrencolumn */ ?> + + /** + * The class that the Peer will make instances of. + * If the BO is abstract then you must implement this method + * in the BO. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function getOMClass() + { +isAbstract()) { ?> + $error = "You must implement the getOMClass method in your" + ." Peer object in order for things to work properly." + ." This method should return the proper Class that" + ." represents the Peer's Business Object."; + + return new PropelException(PROPEL_ERROR, $error); + + return getPhpName()?>Peer::CLASS_DEFAULT(); + + } +getchildrencolumn */ + +if (!$table->isAlias() && ! $table->isReadOnly()) +{ +?> + /** + * Method to do inserts. This method is to be used during a transaction, + * otherwise use the doInsert(Criteria) method. It will take care of + * the connection details internally. + * + * @param mixed $values Criteria or getPhpName() ?> object containing data + * that is used to create the INSERT statement. + * @param Connection $con The connection to use + * + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function doInsert(&$values, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doInsert', 2); + + $con =& Param::get($con); + + if ($con === null) { + $con =& Propel::getConnection(getPhpName()?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + } + + if (is_a($values, 'Criteria')) { + $criteria =& $values; + } else { + $criteria =& $values->buildCriteria(); + } + +getColumns() as $col) + { + $cfc = $col->getPhpName(); + if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none") + { +?> + $criteria->remove(getPhpName()?>Peer::()); // remove pkey col since this table uses auto-increment + + // Set the correct dbName + $criteria->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + $pk = ::doInsert($criteria, $con); + if (Propel::isError($pk)) { $con->rollback(); return $pk; } + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return $pk; + } + +supportsNativeDeleteTrigger() && count($table->getReferrers()) > 0) { + foreach ($table->getReferrers() as $fk) { + if ( $fk->getOnDelete() == ForeignKey::CASCADE ) { + $deleteCascadeRelevant = true; + } + elseif ($fk->getOnDelete() == ForeignKey::SETNULL) { + $deleteSetNullRelevant = true; + } + } + } // if count(foreign keys) +?> + /** + * Method perform an UPDATE on the database, given a getPhpName() ?> or Criteria object. + * + * @param mixed $values Criteria or getPhpName() ?> object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use. + * + * @return mixed number of affected rows on success, any exceptions returned during processing + * wrapped in a PropelException on failure. + */ + function doUpdate(&$values, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doUpdate', 2); + + $con =& Param::get($con); + + if ($con === null) { + $con =& Propel::getConnection(getPhpName()?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + } + + $selectCriteria =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); + + if (is_a($values, 'Criteria')) { + $criteria =& $values; +getColumns() as $col) + { + if($col->isPrimaryKey()) + { + $pn = $table->getPhpName() . 'Peer'; + $cn = PeerBuilder::getColumnName($col); +?> + $comparison = $criteria->getComparison(::()); + $selectCriteria->add(::(), $criteria->remove(::()), $comparison); + + } else { // $values is getPhpName() ?> object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // Set the correct dbName + $criteria->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + + return ::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the getName() ?> table. + * + * Note: If you want to pass a Connection object as reference, + * use Param::set() : + * + * + * $con =& Propel::getConnection(); + * $e = BasePeer::doDeleteAll(Param::set($con)); + * + * + * @return mixed number of affected rows on success, PropelException on failure. + */ + function doDeleteAll($con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doDeleteAll', 2); + + $con =& Param::get($con); + + if ($con === null) { + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + } + + $affectedRows = 0; // initialize var to track total num of affected rows + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + + $e = getPhpName() ?>Peer::doOnDeleteCascade(new Criteria(), $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + + $e = getPhpName() ?>Peer::doOnDeleteSetNull(new Criteria(), $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + + $e = BasePeer::doDeleteAll(getPhpName() ?>Peer::TABLE_NAME(), $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return $affectedRows; + } + + /** + * Method perform a DELETE on the database, given a getPhpName() ?> or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or getPhpName() ?> object containing data that is used to create the DELETE statement. + * @param Connection $con the connection to use + * + * @return mixed number of affected rows on success, any exception returned during processing wrapped into a PropelException on failure. + */ + function doDelete(&$values, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doDelete', 2); + + $con =& Param::get($con); + + if ($con === null) { + $con =& Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME()); + if (Propel::isError($con)) { return $con; } + } + + if (is_a($values, 'Criteria')) { + $criteria =& $values; + } + elseif (is_a($values, 'getPhpName() ?>')) { +getColumns() as $col) { + if($col->isPrimaryKey()) { + $pkey_count++; + } + } + + if ($pkey_count > 0) { +?> + $criteria =& $values->buildPkeyCriteria(); + + $criteria =& $values->buildCriteria(); + + } + else { + // it must be the primary key + $criteria =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); +getPrimaryKey()) == 1) { + $col = array_shift($table->getPrimaryKey()); +?> + $criteria->add(getPhpName()?>Peer::(), $values); + + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values +getPrimaryKey() as $col) { +?> + $criteria->add(getPhpName()?>Peer::(), $values[]); + + } + + // Set the correct dbName + $criteria->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + + $affectedRows = 0; // initialize var to track total num of affected rows + + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $e = $con->begin(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + + $e = getPhpName()?>Peer::doOnDeleteCascade($criteria, $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + $e = getPhpName()?>Peer::doOnDeleteSetNull($criteria, $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + + $e = ::doDelete($criteria, $con); + if (Propel::isError($e)) { $con->rollback(); return $e; } + $affectedRows += $e; + + $e = $con->commit(); + if (Creole::isError($e)) { $con->rollback(); return new PropelException(PROPEL_ERROR_DB, $e); } + + return $affectedRows; + } + + + /** + * This is a method for emulating ON DELETE CASCADE for DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria $criteria + * @param Connection $con + * + * @return number of affected rows on success, PropelException on failure. + */ + function doOnDeleteCascade(/*Criteria*/ $criteria, /*Connection*/ &$con) + { + // initialize var to track total num of affected rows + $affectedRows = 0; + + // first find the objects that are implicated by the $criteria + $objects =& getPhpName()?>Peer::doSelect($criteria, Param::set($con)); + if (Propel::isError($objects)) { return $objects; } + + for($i=0, $j=count($objects); $i < $j; $i++) + { + $obj =& $objects[$i]; +getReferrers() as $fk) + { + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + + if (!$tblFK->isForReferenceOnly()) + { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete cascade for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::CASCADE && $fk->getTable()->getName() != $table->getName()) + { + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); // should be same num as foreign +?> + + include_once 'getPhpName()); ?>'; + + // delete related objects + $c =& new Criteria(); +getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); +?> + $c->add((), $obj->getgetPhpName() ?>()); + + + $e = Peer::doDelete($c, Param::set($con)); + if (Propel::isError($e)) { return $e; } + $affectedRows += $e; + + } + + return $affectedRows; + } + + + + /** + * This is a method for emulating ON DELETE SET NULL DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria $criteria + * @param Connection $con + * + * @return mixed number of affected rows on success, PropelException on failure. + */ + function doOnDeleteSetNull(/*Criteria*/ $criteria, /*Connection*/ &$con) + { + // initialize var to track total num of affected rows + $affectedRows = 0; + + // first find the objects that are implicated by the $criteria + $objects =& getPhpName()?>Peer::doSelect($criteria, Param::set($con)); + if (Propel::isError($objects)) { return $objects; } + + for($i=0, $j=count($objects); $i < $j; $i++) + { + $obj =& $objects[$i]; +getReferrers() as $fk) { + + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + + if (!$tblFK->isForReferenceOnly()) { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete setnull for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::SETNULL && + $fk->getTable()->getName() != $table->getName()) { + + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); // should be same num as foreign +?> + // set fkey col in related rows to NULL + $selectCriteria =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); + $updateValues =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); +getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); + +?> + $selectCriteria->add((), + $obj->getgetPhpName() ?>()); + $updateValues->add((), null); + + // use BasePeer because generated Peer doUpdate() methods only update using pkey + $e = ::doUpdate($selectCriteria, $updateValues, $con); + if (Propel::isError($e)) { return $e; } + $affectedRows += $e; + + } + + return $affectedRows; + } + + + + + /** + * Validates all modified columns of given getPhpName()?> object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param getPhpName()?> $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + function doValidate(&$obj, $cols = null) + { + Propel::typeHint($obj, 'getPhpName()?>', '', 'doValidate'); + + $dbName = getPhpName()?>Peer::DATABASE_NAME(); + $tableName = getPhpName()?>Peer::TABLE_NAME(); + $columns = array(); + + if ($cols) + { + $dbMap =& Propel::getDatabaseMap($dbName); + $tableMap =& $dbMap->getTable($tableName); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) + { + if ($tableMap->containsColumn($colName)) + { + $colMap =& $tableMap->getColumn($colName); + $get = 'get' . $colMap->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } + else + { +getValidators() as $val) { + $col = $val->getColumn(); + if (! $col->isAutoIncrement()) { + $cfc = $col->getPhpName(); + $cup = strtoupper($col->getName()); +?> + if ($obj->isNew() || $obj->isColumnModified(getPhpName()?>Peer::())) + $columns[getPhpName()?>Peer::()] = $obj->get(); + + } + + return ::doValidate($dbName, $tableName, $columns); + } + + /** + * Build a Criteria object from the data object for this peer or from primary key(s). + * + * @param mixed $obj getPhpName() ?> object or getPrimaryKey()) == 1) { ?>scalar primary keyarray primary keys. + * @return Criteria The compiled Criteria object. + */ + function buildCriteria(&$obj) + { + if (is_a($obj, 'getPhpName() ?>' )) { + $criteria =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); +getColumns() as $col) { + $cfc = $col->getPhpName(); + if ($col->isPrimaryKey() && $table->getIdMethod() != "none") { +?> + if (! $obj->isNew()) + $criteria->add(getPhpName()?>Peer::(), $obj->get()); // primary key on tables w/ id generation is only added if not new + + if ($obj->isColumnModified(getPhpName()?>Peer::())) + $criteria->add(getPhpName()?>Peer::(), $obj->get()); + + + } else { + // it must be the primary key + $criteria =& new Criteria(getPhpName()?>Peer::DATABASE_NAME()); + getPrimaryKey()) == 1) { + $col = array_shift($table->getPrimaryKey()); ?> + + $criteria->add(getPhpName()?>Peer::(), $obj); + + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + getPrimaryKey() as $col) { ?> + $criteria->add(getPhpName()?>Peer::(), $obj[]); + + + } + + return $criteria; + } +isalias */ ?> + +getPrimaryKey()) > 0) { + + if ($table->isAlias()) { + $retrieveMethod = "retrieve" . $table->getPhpName() . "ByPK"; + } else { + $retrieveMethod = "retrieveByPK"; + } + + $pks = $table->getPrimaryKey(); + +if (count($table->getPrimaryKey()) === 1) { ?> + + /** + * Retrieve a single object by pkey or NULL if not found. + * + * @param mixed $pk The primary key. + * @param Connection $con The connection to use. + * + * @return mixed getPhpName(); ?> on success, NULL on failure + */ + function & ($pk, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', '', 2); + + $criteria =& new Criteria(); +getPrimaryKey()) === 1) { + $col = array_shift($table->getPrimaryKey()); +?> + $criteria->add(getPhpName() ?>Peer::(), $pk); + + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values +getPrimaryKey() as $col) { +?> + $criteria->add(getPhpName() ?>Peer::, $pk[]); + + + $v = getPhpName() ?>Peer::doSelect($criteria, $con); + return count($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con The connection to use. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function & s($pks, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', '', 2); + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria =& new Criteria(); +getPrimaryKey()) == 1) { ?> + + $criteria->add(getPhpName() ?>Peer::getPrimaryKey(); echo strtoupper($k1[0]->getName()); ?>(), $pks, Criteria::IN()); + + + for($k=0,$size=count($pks); $k < $size; $k++) { + $pk = $pks[$k]; + getPrimaryKey() as $col) { ?> + + $c =& $criteria->getNewCriterion(getPhpName()?>Peer::(), $pk[], Criteria::EQUAL()); + 0) { ?> + + $c->addAnd($c); + 0 */ + $i++; + } /* foreach */ ?> + + $criteria->addOr($c0); + } + + + $objs =& getPhpName()?>Peer::doSelect($criteria, $con); + if (Propel::isError($objs)) { return $objs; } + } + return $objs; + } + + 1 + +$comma = false; +?> + /** + * Retrieve object using pk values or NULL if not found. + * +getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); + $cptype = $col->getPhpNative(); +?> + * @param $ + + * @param Connection $con + * + * @return getPhpName() ?> + */ + function (getPrimaryKey() as $col) { $clo = strtolower($col->getName()); ?>, $, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', '', -1); + + $criteria = new Criteria(); +getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); +?> + $criteria->add(getPhpName()?>Peer::(), $); + + + $v =& getPhpName()?>Peer::doSelect($criteria, $con); + return count($v) > 0 ? $v[0] : null; + } + + 1 */ + +} /* if pkey > 0 */ ?> + +getPhpName(); + $countFK = count($table->getForeignKeys()); + + if ($countFK >= 1) { + foreach ($table->getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + if (!$tblFK->isForReferenceOnly()) { + // want to cover this other case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) { + $partJoinName = $partJoinName . $column->getPhpName(); + } + } + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if ($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + if ($partJoinName == "") { + $joinColumnId = $joinClassName; + $joinInterface = $interfaceName; + $collThisTable = $className . "s"; + $collThisTableMs = $className; + } else { + $joinColumnId= $joinClassName . "RelatedBy" . $partJoinName; + $joinInterface= $interfaceName . "RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + +// ------------------------------------------------------------ +?> + /** + * Selects a collection of objects pre-filled with their + * objects. + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function & doSelectJoin(/*Criteria*/ $c, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelectJoin', 2); + + // Set the correct dbName if it has not been overridden + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol = getPhpName() ?>Peer::numColumns() - getPhpName() ?>Peer::numLazyLoadColumns() + 1; + Peer::addSelectColumns($c); + +getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); +?> + $c->addJoin(getPhpName()) ?>(), ()); + + + $rs =& ::doSelect($c, $con); + if (Propel::isError($rs)) { return $rs; } + + $results = array(); + + while($rs->next()) + { +getChildrenColumn()) { ?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + + $cls =& Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj1 =& new $cls(); + + $e =& $obj1->hydrate($rs); + if (Propel::isError($e)) { return $e; } + +getChildrenColumn()) { ?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); + + + $cls =& Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj2 =& new $cls(); + + $e =& $obj2->hydrate($rs, $startcol); + if (Propel::isError($e)) { return $e; } + + $newObject = true; + foreach($results as $temp_obj1) + { + $temp_obj2 =& $temp_obj1->get(); + if ($temp_obj2->getPrimaryKey() === $obj2->getPrimaryKey()) { + $newObject = false; + $temp_obj2->add($obj1); + break; + } + } + if ($newObject) { + $obj2->init(); + $obj2->add($obj1); + } + $results[] =& $obj1; + } + + return $results; + } + 1 + +// =========================================================== + + if ($countFK > 1) { + $includeJoinAll = true; + foreach ($table->getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + if ($tblFK->isForReferenceOnly()) { + $includeJoinAll = false; + } + } + + if ($includeJoinAll) { + // ------------------------------------------------------------------------ + // doSelectJoinAll() + // ------------------------------------------------------------------------ + + //1 ) create the master doSelectJoinAll() method + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $collThisTable = $className . "sRelatedBy" . $relatedByCol; + $collThisTableMs = $className . "RelatedBy" . $relatedByCol; + } +?> + + /** + * Selects a collection of objects pre-filled with + * all related objects. + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function doSelectJoinAll(/*Criteria*/ &$c, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelectJoinAll', 2); + + // Set the correct dbName if it has not been overridden + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol2 = getPhpName() ?>Peer::numColumns() - getPhpName() ?>Peer::numLazyLoadColumns() + 1; +getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $new_index = $index + 1; +?> + Peer::addSelectColumns($c); + $startcol = $startcol + Peer::numColumns(); +getForeignTableName != table->getName + } // foreach [sub] foreign keys + + foreach ($table->getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); +?> + $c->addJoin(getPhpName()) ?>(), ()); + + + $rs =& ::doSelect($c, $con); + if (Propel::isError($rs)) { return $rs; } + $results = array(); + + while($rs->next()) { +getChildrenColumn()) { +?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + + $cls = Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj1 =& new $cls(); + + $e =& $obj1->hydrate($rs); + if (Propel::isError($e)) { return $e; } +getForeignKeys() as $fk ) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + + $index++; +?> + + // Add objects for joined rows +getChildrenColumn()) { +?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); +getChildrenColumn() */ +?> + + $cls = Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj =& new $cls(); + + $e = $obj->hydrate($rs, $startcol); + if (Propel::isError($e)) { return $e; } + + $newObject = true; + for ($j=0, $resCount=count($results); $j < $resCount; $j++) { + $temp_obj1 =& $results[$j]; + $temp_obj =& $temp_obj1->get(); + if ($temp_obj->getPrimaryKey() === $obj->getPrimaryKey()) { + $newObject = false; + $temp_obj->add($obj1); + break; + } + } + + if ($newObject) { + $obj->init(); + $obj->add($obj1); + } + getForeignTableName() != $table->getName() + } //foreach foreign key +?> + $results[] =& $obj1; + } + + return $results; + } +getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over + foreach ($fkeys as $fk ) { // getForeignKeys() will cause this to only execute one time. + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $excludeTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $excludeClassName = $excludeTable->getPhpName(); + + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $excludeString = $excludeClassName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $excludeString = $excludeClassName . "RelatedBy" . $relatedByCol; + $collThisTable = $className . "sRelatedBy" . $relatedByCol; + $collThisTableMs = $className . "RelatedBy" . $relatedByCol; + } +?> + + /** + * Selects a collection of objects pre-filled with + * all related objects except . + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function doSelectJoinAllExcept(/*Criteria*/ &$c, $con = null) + { + /* [MA] temporarily check */ + Propel::assertParam($con, '', 'doSelectJoinAllExcept', 2); + + // Set the correct dbName if it has not been overridden + // $c->getDbName() will return the same object if not set to another value + // so == check is okay and faster + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(getPhpName()?>Peer::DATABASE_NAME()); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol2 = getPhpName() ?>Peer::numColumns() - getPhpName() ?>Peer::numLazyLoadColumns() + 1; +getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( !($subfk->getForeignTableName() == $table->getName())) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + + if ($joinClassName != $excludeClassName) { + $new_index = $index + 1; +?> + Peer::addSelectColumns($c); + $startcol = $startcol + Peer::numColumns(); +getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + if($joinClassName != $excludeClassName) + { + $lfMap = $subfk->getLocalForeignMapping(); + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); +?> + $c->addJoin(getPhpName()) ?>(), ()); + + + $rs =& ::doSelect($c, $con); + if (Propel::isError($rs)) { return $rs; } + + $results = array(); + + while($rs->next()) { +getChildrenColumn()) { +?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + + $cls = Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj1 =& new $cls(); + $e = $obj1->hydrate($rs); + if (Propel::isError($e)) { return $e; } + +getForeignKeys() as $subfk ) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + if ($joinClassName != $excludeClassName) { + $partJoinName = ""; + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + + $index++; + + if ($joinTable->getChildrenColumn()) { +?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); +getChildrenColumn() */ +?> + + $cls = Propel::import($omClass); + if (Propel::isError($cls)) { return $cls; } + + $obj =& new $cls(); + + $e = $obj->hydrate($rs, $startcol); + if (Propel::isError($e)) { return $e; } + + $newObject = true; + for ($j=0, $resCount=count($results); $j < $resCount; $j++) { + $temp_obj1 =& $results[$j]; + $temp_obj =& $temp_obj1->get(); + if ($temp_obj->getPrimaryKey() === $obj->getPrimaryKey()) { + $newObject = false; + $temp_obj->add($obj1); + break; + } + } + + if ($newObject) { + $obj->init(); + $obj->add($obj1); + } + getForeignTableName() != $table->getName() + } // foreach +?> + $results[] =& $obj1; + } + + return $results; + } + 2 */ + } /* if complex object model */ + + // two extra #end ... + + +//------------------------------------------------------------ + +if (!$table->isAlias()) { +?> + /** + * Returns the TableMap related to this peer. This method is not + * needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + function & getTableMap() + { + $dbMap =& Propel::getDatabaseMap(getPhpName()?>Peer::DATABASE_NAME()); + if (Propel::isError($dbMap)) { + return $dbMap; + } + return $dbMap->getTable(getPhpName()?>Peer::TABLE_NAME()); + } + +isalias */ ?> +} + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + if (Propel::isError($e = getPhpName() ?>Peer::getMapBuilder())) { + Propel::log("Could not initialize Peer: " . $e->getMessage(), PROPEL_LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'getPhpName() . 'MapBuilder') ?>'; + Propel::registerMapBuilder(getPhpName()?>MapBuilder::CLASS_NAME()); +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNode.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNode.tpl new file mode 100644 index 000000000..1619a303a --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNode.tpl @@ -0,0 +1,35 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +?> + + +require_once 'getPhpName() . 'Node') ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?>Node extends getPhpName() . 'Node' ?> { + +} \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNodePeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNodePeer.tpl new file mode 100644 index 000000000..53ff80364 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionNodePeer.tpl @@ -0,0 +1,35 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +?> + + +require_once 'getPhpName() . 'NodePeer') ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?>NodePeer extends getPhpName() . 'NodePeer' ?> { + +} \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionObject.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionObject.tpl new file mode 100644 index 000000000..992da8d16 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionObject.tpl @@ -0,0 +1,49 @@ + + +require_once ''; + +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$abstract = ""; +if ($table->isAbstract()) { + $abstract = "abstract "; +} +?> + +require_once 'getPhpName()) ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName() ?> extends getPhpName() ?> implements { + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionPeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionPeer.tpl new file mode 100644 index 000000000..414486de6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/ExtensionPeer.tpl @@ -0,0 +1,37 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} +?> + +// The parent class +require_once 'getPhpName() . 'Peer') ?>'; + +// The object class +include_once 'getPhpName()) ?>'; + +/** + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package + */ +class getPhpName()?>Peer extends getPhpName() ?>Peer { + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/Interface.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/Interface.tpl new file mode 100644 index 000000000..eef7e93bb --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/Interface.tpl @@ -0,0 +1,33 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$interface = ClassTools::getInterface($table); + +?> + + +/** + * This is an interface that should be filled with the public api of the + * getPhpName()?> objects. + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + */ +interface { + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/MapBuilder.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/MapBuilder.tpl new file mode 100644 index 000000000..1dc95fcc6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/MapBuilder.tpl @@ -0,0 +1,135 @@ + + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + +/** + * This class adds structure of 'getName() ?>' table to 'getDatabase()->getName() ?>' DatabaseMap object. + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @see BasePeer + * @see DatabaseMap + * @package .map + */ +class getPhpName() ?>MapBuilder implements MapBuilder { + + /** + * The name of this class + */ + const CLASS_NAME = "getPhpName() ?>MapBuilder"; + + /** + * The database map. + */ + private $dbMap = null; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return true if this DatabaseMapBuilder is built + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap("getDatabase()->getName() ?>"); + + $tMap = $this->dbMap->addTable("getName()?>"); + $tMap->setPhpName("getPhpName()?>"); + + getIdMethod() == "native") { ?> + $tMap->setUseIdGenerator(true); + + $tMap->setUseIdGenerator(false); + + + getIdMethodParameters()) { + $params = $table->getIdMethodParameters(); + $imp = $params[0]; ?> + $tMap->setPrimaryKeyMethodInfo("getValue() ?>"); + getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { ?> + $tMap->setPrimaryKeyMethodInfo("getSequenceName() ?>"); + getIdMethod() == "native" && ($platform->getNativeIdMethod() == Platform::SEQUENCE)) { ?> + $tMap->setPrimaryKeyMethodInfo("getName() ?>"); + + + // Add columns to map +getColumns() as $col) { + $tfc=$table->getPhpName(); + $cfc=$col->getPhpName(); + $cup=strtoupper($col->getName()); + if (!$col->getSize()) { + $size = "null"; + } else { + $size = $col->getSize(); + } + if($col->isPrimaryKey()) { + if($col->isForeignKey()) { ?> + $tMap->addForeignPrimaryKey("", "", "getPhpType() ?>" , CreoleTypes::getType() ?>, "getRelatedTableName()?>", "getRelatedColumnName()) ?>", isNotNull() ? 'true' : 'false' ?>, ); + + $tMap->addPrimaryKey("", "", "getPhpType() ?>", CreoleTypes::getType() ?>, isNotNull() ? 'true' : 'false' ?>, ); +isForeignKey()) { ?> + $tMap->addForeignKey("", "", "getPhpType()?>", CreoleTypes::getType() ?>, "getRelatedTableName() ?>" , "getRelatedColumnName()) ?>", isNotNull() ? 'true' : 'false' ?>, ); + + $tMap->addColumn("", "", "getPhpType()?>", CreoleTypes::getType() ?>, isNotNull() ? 'true' : 'false' ?>, ); +getValidators() as $val) { + $col = $val->getColumn(); + $cup = strtoupper($col->getName()); + foreach($val->getRules() as $rule) { + if ($val->getTranslate() !== Validator::TRANSLATE_NONE) { +?> + $tMap->addValidator("", "getName() ?>", "getClass() ?>", "getValue()?>", getTranslate() ?>("getMessage()) ?>")); + + $tMap->addValidator("", "getName() ?>", "getClass() ?>", "getValue()?>", "getMessage()) ?>"); +getTranslation() ... + } // foreach validator +} +?> + + } +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/MultiExtendObject.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/MultiExtendObject.tpl new file mode 100644 index 000000000..68363bc60 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/MultiExtendObject.tpl @@ -0,0 +1,60 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$packagePath = strtr($package, '.', '/'); +if ($packagePath != "") $packagePath .= '/'; + +if ($child->getAncestor()) { + $parent = $child->getAncestor(); +?> + +require_once '.php'; + +getPhpName(); +?> + +require_once '.php'; + + +/** + + + * The skeleton for this class was autogenerated by Propel on: + * + * [] + * + + + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + */ +class getClassName()?> extends { + + public function __construct() + { getColumn(); + $cfc=$col->getPhpName(); + $table = $col->getTable(); + ?> + $this->set(getPhpName() ?>Peer::CLASSKEY_getKey()) ?>); + } +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/Node.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/Node.tpl new file mode 100644 index 000000000..3bfa37fb1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/Node.tpl @@ -0,0 +1,801 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +echo '<' . '?' . 'php'; + +?> + + +require_once 'getPhpName() . 'NodePeer') ?>'; + +/** + * Base tree node class for manipulating a tree of getPhpName() ?> objects. + * This class will wrap these objects within a "node" interface. It provides a + * method overload mechanism which allows you to use a getPhpName() ?>Node + * object just like a getPhpName() ?> object. + * + * To avoid tree corruption, you should always use this class to make changes to + * the tree and objects within it rather than using the getPhpName() ?> + * class directly. + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + * + */ +class getPhpName() ?>Node implements IteratorAggregate +{ + /** + * @var getPhpName() ?> Object wrapped by this node. + */ + protected $obj = null; + + /** + * The parent node for this node. + * @var getPhpName() ?>Node + */ + protected $parentNode = null; + + /** + * Array of child nodes for this node. Nodes indexes are one-based. + * @var array + */ + protected $childNodes = array(); + + /** + * Constructor. + * + * @param getPhpName() ?> Object wrapped by this node. + */ + public function __construct($obj = null) + { + if ($obj !== null) + { + $this->obj = $obj; + } + else + { + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME; + $this->obj = new getPhpName() ?>(); + $this->obj->$setNodePath('0'); + } + } + + /** + * Convenience overload for wrapped object methods. + * + * @param string Method name to call on wrapped object. + * @param mixed Parameter accepted by wrapped object set method. + * @return mixed Return value of wrapped object method. + * @throws PropelException Fails if method is not defined for wrapped object. + */ + public function __call($name, $parms) + { + if (method_exists($this->obj, $name)) + return call_user_func_array(array($this->obj, $name), $parms); + else + throw new PropelException("get method not defined: $name"); + } + + /** + * Sets the default options for iterators created from this object. + * The options are specified in map format. The following options + * are supported by all iterators. Some iterators may support other + * options: + * + * "querydb" - True if nodes should be retrieved from database. + * "con" - Connection to use if retrieving from database. + * + * @param string Type of iterator to use ("pre", "post", "level"). + * @param array Map of option name => value. + * @return void + * @todo Implement other iterator types (i.e. post-order, level, etc.) + */ + public function setIteratorOptions($type, $opts) + { + $this->itType = $type; + $this->itOpts = $opts; + } + + /** + * Returns a pre-order iterator for this node and its children. + * + * @param string Type of iterator to use ("pre", "post", "level") + * @param array Map of option name => value. + * @return NodeIterator + */ + public function getIterator($type = null, $opts = null) + { + if ($type === null) + $type = (isset($this->itType) ? $this->itType : 'Pre'); + + if ($opts === null) + $opts = (isset($this->itOpts) ? $this->itOpts : array()); + + $itclass = ucfirst(strtolower($type)) . 'OrderNodeIterator'; + + require_once('propel/om/' . $itclass . '.php'); + return new $itclass($this, $opts); + } + + /** + * Returns the object wrapped by this class. + * @return getPhpName() . "\n" ?> + */ + public function getNodeObj() + { + return $this->obj; + } + + /** + * Convenience method for retrieving nodepath. + * @return string + */ + public function getNodePath() + { + $getNodePath = 'get' . getPhpName() ?>NodePeer::NPATH_PHPNAME; + return $this->obj->$getNodePath(); + } + + /** + * Returns one-based node index among siblings. + * @return int + */ + public function getNodeIndex() + { + $npath =& $this->getNodePath(); + $sep = strrpos($npath, getPhpName() ?>NodePeer::NPATH_SEP); + return (int) ($sep !== false ? substr($npath, $sep+1) : $npath); + } + + /** + * Returns one-based node level within tree (root node is level 1). + * @return int + */ + public function getNodeLevel() + { + return (substr_count($this->getNodePath(), getPhpName() ?>NodePeer::NPATH_SEP) + 1); + } + + /** + * Returns true if specified node is a child of this node. If recurse is + * true, checks if specified node is a descendant of this node. + * + * @param getPhpName() ?>Node Node to look for. + * @param boolean True if strict comparison should be used. + * @param boolean True if all descendants should be checked. + * @return boolean + */ + public function hasChildNode($node, $strict = false, $recurse = false) + { + foreach ($this->childNodes as $childNode) + { + if ($childNode->equals($node, $strict)) + return true; + + if ($recurse && $childNode->hasChildNode($node, $recurse)) + return true; + } + + return false; + } + + /** + * Returns child node at one-based index. Retrieves from database if not + * loaded yet. + * + * @param int One-based child node index. + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + public function getChildNodeAt($i, $querydb = false, $con = null) + { + if ($querydb && + !$this->obj->isNew() && + !$this->obj->isDeleted() && + !isset($this->childNodes[$i])) + { + $criteria = new Criteria(getPhpName() ?>Peer::DATABASE_NAME); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME, $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $i, Criteria::EQUAL); + + if ($childObj = getPhpName() ?>Peer::doSelectOne($criteria, $con)) + $this->attachChildNode(new getPhpName() ?>Node($childObj)); + } + + return (isset($this->childNodes[$i]) ? $this->childNodes[$i] : null); + } + + /** + * Returns first child node (if any). Retrieves from database if not loaded yet. + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + public function getFirstChildNode($querydb = false, $con = null) + { + return $this->getChildNodeAt(1, $querydb, $con); + } + + /** + * Returns last child node (if any). + * + * @param boolean True if child should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + */ + public function getLastChildNode($querydb = false, $con = null) + { + $lastNode = null; + + if ($this->obj->isNew() || $this->obj->isDeleted()) + { + end($this->childNodes); + $lastNode = (count($this->childNodes) ? current($this->childNodes) : null); + } + else if ($querydb) + { + $db = Propel::getDb(getPhpName() ?>Peer::DATABASE_NAME); + $criteria = new Criteria(getPhpName() ?>Peer::DATABASE_NAME); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME, $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . '%', Criteria::LIKE); + $criteria->addAnd(getPhpName() ?>NodePeer::NPATH_COLNAME, $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . '%' . getPhpName() ?>NodePeer::NPATH_SEP . '%', Criteria::NOT_LIKE); + $criteria->addAsColumn('npathlen', $db->strLength(getPhpName() ?>NodePeer::NPATH_COLNAME)); + $criteria->addDescendingOrderByColumn('npathlen'); + $criteria->addDescendingOrderByColumn(getPhpName() ?>NodePeer::NPATH_COLNAME); + + $lastObj = getPhpName() ?>Peer::doSelectOne($criteria, $con); + + if ($lastObj !== null) + { + $lastNode = new getPhpName() ?>Node($lastObj); + + end($this->childNodes); + $endNode = (count($this->childNodes) ? current($this->childNodes) : null); + + if ($endNode) + { + if ($endNode->getNodePath() > $lastNode->getNodePath()) + throw new PropelException('Cached child node inconsistent with database.'); + else if ($endNode->getNodePath() == $lastNode->getNodePath()) + $lastNode = $endNode; + else + $this->attachChildNode($lastNode); + } + else + { + $this->attachChildNode($lastNode); + } + } + } + + return $lastNode; + } + + /** + * Returns next (or previous) sibling node or null. Retrieves from database if + * not loaded yet. + * + * @param boolean True if previous sibling should be returned. + * @param boolean True if sibling should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + public function getSiblingNode($prev = false, $querydb = false, $con = null) + { + $nidx = $this->getNodeIndex(); + + if ($this->isRootNode()) + { + return null; + } + else if ($prev) + { + if ($nidx > 1 && ($parentNode = $this->getParentNode($querydb, $con))) + return $parentNode->getChildNodeAt($nidx-1, $querydb, $con); + else + return null; + } + else + { + if ($parentNode = $this->getParentNode($querydb, $con)) + return $parentNode->getChildNodeAt($nidx+1, $querydb, $con); + else + return null; + } + } + + /** + * Returns parent node. Loads from database if not cached yet. + * + * @param boolean True if parent should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return getPhpName() ?>Node + */ + public function getParentNode($querydb = true, $con = null) + { + if ($querydb && + $this->parentNode === null && + !$this->isRootNode() && + !$this->obj->isNew() && + !$this->obj->isDeleted()) + { + $npath =& $this->getNodePath(); + $sep = strrpos($npath, getPhpName() ?>NodePeer::NPATH_SEP); + $ppath = substr($npath, 0, $sep); + + $criteria = new Criteria(getPhpName() ?>Peer::DATABASE_NAME); + $criteria->add(getPhpName() ?>NodePeer::NPATH_COLNAME, $ppath, Criteria::EQUAL); + + if ($parentObj = getPhpName() ?>Peer::doSelectOne($criteria, $con)) + { + $parentNode = new getPhpName() ?>Node($parentObj); + $parentNode->attachChildNode($this); + } + } + + return $this->parentNode; + } + + /** + * Returns an array of all ancestor nodes, starting with the root node + * first. + * + * @param boolean True if ancestors should be retrieved from database. + * @param Connection Connection to use if retrieving from database. + * @return array + */ + public function getAncestors($querydb = false, $con = null) + { + $ancestors = array(); + $parentNode = $this; + + while ($parentNode = $parentNode->getParentNode($querydb, $con)) + array_unshift($ancestors, $parentNode); + + return $ancestors; + } + + /** + * Returns true if node is the root node of the tree. + * @return boolean + */ + public function isRootNode() + { + return ($this->getNodePath() === '1'); + } + + /** + * Changes the state of the object and its descendants to 'new'. + * Also changes the node path to '0' to indicate that it is not a + * stored node. + * + * @param boolean + * @return void + */ + public function setNew($b) + { + $this->adjustStatus('new', $b); + $this->adjustNodePath($this->getNodePath(), '0'); + } + + /** + * Changes the state of the object and its descendants to 'deleted'. + * + * @param boolean + * @return void + */ + public function setDeleted($b) + { + $this->adjustStatus('deleted', $b); + } + + /** + * Adds the specified node (and its children) as a child to this node. If a + * valid $beforeNode is specified, the node will be inserted in front of + * $beforeNode. If $beforeNode is not specified the node will be appended to + * the end of the child nodes. + * + * @param getPhpName() ?>Node Node to add. + * @param getPhpName() ?>Node Node to insert before. + * @param Connection Connection to use. + */ + public function addChildNode($node, $beforeNode = null, $con = null) + { + if ($this->obj->isNew() && !$node->obj->isNew()) + throw new PropelException('Cannot add stored nodes to a new node.'); + + if ($this->obj->isDeleted() || $node->obj->isDeleted()) + throw new PropelException('Cannot add children in a deleted state.'); + + if ($this->hasChildNode($node)) + throw new PropelException('Node is already a child of this node.'); + + if ($beforeNode && !$this->hasChildNode($beforeNode)) + throw new PropelException('Invalid beforeNode.'); + + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + try { + + if (!$this->obj->isNew()) $con->begin(); + + if ($beforeNode) + { + // Inserting before a node. + $childIdx = $beforeNode->getNodeIndex(); + $this->shiftChildNodes(1, $beforeNode->getNodeIndex(), $con); + } + else + { + // Appending child node. + if ($lastNode = $this->getLastChildNode(true, $con)) + $childIdx = $lastNode->getNodeIndex()+1; + else + $childIdx = 1; + } + + // Add the child (and its children) at the specified index. + + if (!$this->obj->isNew() && $node->obj->isNew()) + { + $this->insertNewChildNode($node, $childIdx, $con); + } + else + { + // $this->isNew() && $node->isNew() || + // !$this->isNew() && !node->isNew() + + $srcPath = $node->getNodePath(); + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $childIdx; + + if (!$node->obj->isNew()) + { + getPhpName() ?>NodePeer::moveNodeSubTree($srcPath, $dstPath, $con); + $parentNode = $node->getParentNode(true, $con); + } + else + { + $parentNode = $node->getParentNode(); + } + + if ($parentNode) + { + $parentNode->detachChildNode($node); + $parentNode->shiftChildNodes(-1, $node->getNodeIndex()+1, $con); + } + + $node->adjustNodePath($srcPath, $dstPath); + } + + if (!$this->obj->isNew()) $con->commit(); + + $this->attachChildNode($node); + + } catch (SQLException $e) { + if (!$this->obj->isNew()) $con->rollback(); + throw new PropelException($e); + } + } + + /** + * Moves the specified child node in the specified direction. + * + * @param getPhpName() ?>Node Node to move. + * @param int Number of spaces to move among siblings (may be negative). + * @param Connection Connection to use. + * @throws PropelException + */ + public function moveChildNode($node, $direction, $con = null) + { + throw new PropelException('moveChildNode() not implemented yet.'); + } + + /** + * Saves modified object data to the datastore. + * + * @param boolean If true, descendants will be saved as well. + * @param Connection Connection to use. + */ + public function save($recurse = false, $con = null) + { + if ($this->obj->isDeleted()) + throw new PropelException('Cannot save deleted node.'); + + if (substr($this->getNodePath(), 0, 1) == '0') + throw new PropelException('Cannot save unattached node.'); + + if ($this->obj->isColumnModified(getPhpName() ?>NodePeer::NPATH_COLNAME)) + throw new PropelException('Cannot save manually modified node path.'); + + $this->obj->save($con); + + if ($recurse) + { + foreach ($this->childNodes as $childNode) + $childNode->save($recurse, $con); + } + } + + /** + * Removes this object and all descendants from datastore. + * + * @param Connection Connection to use. + * @return void + * @throws PropelException + */ + public function delete($con = null) + { + if ($this->obj->isDeleted()) + throw new PropelException('This node has already been deleted.'); + + if (!$this->obj->isNew()) + { + getPhpName() ?>NodePeer::deleteNodeSubTree($this->getNodePath(), $con); + } + + if ($parentNode = $this->getParentNode(true, $con)) + { + $parentNode->detachChildNode($this); + $parentNode->shiftChildNodes(-1, $this->getNodeIndex()+1, $con); + } + + $this->setDeleted(true); + } + + /** + * Compares the object wrapped by this node with that of another node. Use + * this instead of equality operators to prevent recursive dependency + * errors. + * + * @param getPhpName() ?>Node Node to compare. + * @param boolean True if strict comparison should be used. + * @return boolean + */ + public function equals($node, $strict = false) + { + if ($strict) + return ($this->obj === $node->obj); + else + return ($this->obj == $node->obj); + } + + /** + * This method is used internally when constructing the tree structure + * from the database. To set the parent of a node, you should call + * addChildNode() on the parent. + * + * @param getPhpName() ?>Node Parent node to attach. + * @return void + * @throws PropelException + */ + public function attachParentNode($node) + { + if (!$node->hasChildNode($this, true)) + throw new PropelException('Failed to attach parent node for non-child.'); + + $this->parentNode = $node; + } + + /** + * This method is used internally when constructing the tree structure + * from the database. To add a child to a node you should call the + * addChildNode() method instead. + * + * @param getPhpName() ?>Node Child node to attach. + * @return void + * @throws PropelException + */ + public function attachChildNode($node) + { + if ($this->hasChildNode($node)) + throw new PropelException('Failed to attach child node. Node already exists.'); + + if ($this->obj->isDeleted() || $node->obj->isDeleted()) + throw new PropelException('Failed to attach node in deleted state.'); + + if ($this->obj->isNew() && !$node->obj->isNew()) + throw new PropelException('Failed to attach non-new child to new node.'); + + if (!$this->obj->isNew() && $node->obj->isNew()) + throw new PropelException('Failed to attach new child to non-new node.'); + + if ($this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $node->getNodeIndex() != $node->getNodePath()) + throw new PropelException('Failed to attach child node. Node path mismatch.'); + + $this->childNodes[$node->getNodeIndex()] = $node; + ksort($this->childNodes); + + $node->attachParentNode($this); + } + + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this node's parent. + * @param getPhpName() ?>Node Parent node to detach from. + * @return void + * @throws PropelException + */ + public function detachParentNode($node) + { + if (!$node->hasChildNode($this, true)) + throw new PropelException('Failed to detach parent node from non-child.'); + + unset($node->childNodes[$this->getNodeIndex()]); + $this->parentNode = null; + } + + /** + * This method is used internally when deleting nodes. It is used to break + * the link to this between this node and the specified child. + * @param getPhpName() ?>Node Child node to detach. + * @return void + * @throws PropelException + */ + public function detachChildNode($node) + { + if (!$this->hasChildNode($node, true)) + throw new PropelException('Failed to detach non-existent child node.'); + + unset($this->childNodes[$node->getNodeIndex()]); + $node->parentNode = null; + } + + /** + * Shifts child nodes in the specified direction and offset index. This + * method assumes that there is already space available in the + * direction/offset indicated. + * + * @param int Direction/# spaces to shift. 1=leftshift, 1=rightshift + * @param int Node index to start shift at. + * @param Connection The connection to be used. + * @return void + * @throws PropelException + */ + protected function shiftChildNodes($direction, $offsetIdx, $con) + { + if ($this->obj->isDeleted()) + throw new PropelException('Cannot shift nodes for deleted object'); + + $lastNode = $this->getLastChildNode(true, $con); + $lastIdx = ($lastNode !== null ? $lastNode->getNodeIndex() : 0); + + if ($lastNode === null || $offsetIdx > $lastIdx) + return; + + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + if (!$this->obj->isNew()) + { + // Shift nodes in database. + + try { + + $con->begin(); + + $n = $lastIdx - $offsetIdx + 1; + $i = $direction < 1 ? $offsetIdx : $lastIdx; + + while ($n--) + { + $srcPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $i; // 1.2.2 + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . ($i+$direction); // 1.2.3 + + getPhpName() ?>NodePeer::moveNodeSubTree($srcPath, $dstPath, $con); + + $i -= $direction; + } + + $con->commit(); + + } catch (SQLException $e) { + $con->rollback(); + throw new PropelException($e); + } + } + + // Shift the in-memory objects. + + $n = $lastIdx - $offsetIdx + 1; + $i = $direction < 1 ? $offsetIdx : $lastIdx; + + while ($n--) + { + if (isset($this->childNodes[$i])) + { + $srcPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $i; // 1.2.2 + $dstPath = $this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . ($i+$direction); // 1.2.3 + + $this->childNodes[$i+$direction] = $this->childNodes[$i]; + $this->childNodes[$i+$direction]->adjustNodePath($srcPath, $dstPath); + + unset($this->childNodes[$i]); + } + + $i -= $direction; + } + + ksort($this->childNodes); + } + + /** + * Inserts the node and its children at the specified childIdx. + * + * @param getPhpName() ?>Node Node to insert. + * @param int One-based child index to insert at. + * @param Connection Connection to use. + * @param void + */ + protected function insertNewChildNode($node, $childIdx, $con) + { + if (!$node->obj->isNew()) + throw new PropelException('Failed to insert non-new node.'); + + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME; + + $node->obj->$setNodePath($this->getNodePath() . getPhpName() ?>NodePeer::NPATH_SEP . $childIdx); + $node->obj->save($con); + + $i = 1; + foreach ($node->childNodes as $childNode) + $node->insertNewChildNode($childNode, $i++, $con); + } + + /** + * Adjust new/deleted status of node and all children. + * + * @param string Status to change ('New' or 'Deleted') + * @param boolean Value for status. + * @return void + */ + protected function adjustStatus($status, $b) + { + $setStatus = 'set' . $status; + + $this->obj->$setStatus($b); + + foreach ($this->childNodes as $childNode) + $childNode->obj->$setStatus($b); + } + + /** + * Adjust path of node and all children. This is used internally when + * inserting/moving nodes. + * + * @param string Section of old path to change. + * @param string New section to replace old path with. + * @return void + */ + protected function adjustNodePath($oldBasePath, $newBasePath) + { + $setNodePath = "set" . getPhpName() ?>NodePeer::NPATH_PHPNAME; + + $this->obj->$setNodePath($newBasePath . + substr($this->getNodePath(), strlen($oldBasePath))); + $this->obj->resetModified(getPhpName() ?>NodePeer::NPATH_COLNAME); + + foreach ($this->childNodes as $childNode) + $childNode->adjustNodePath($oldBasePath, $newBasePath); + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/NodePeer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/NodePeer.tpl new file mode 100644 index 000000000..d8b6e39fe --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/NodePeer.tpl @@ -0,0 +1,522 @@ +getColumns() as $col) { + if ($col->isNodeKey()) { + $npath_colname = $table->getName() . '.' . strtoupper($col->getName()); + $npath_phpname = $col->getPhpName(); + $npath_len = $col->getSize(); + $npath_sep = $col->getNodeKeySep(); + break; + } +} + +$db = $table->getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +echo '<' . '?' . 'php'; + +?> + + +require_once 'getPhpName()) ?>'; +require_once 'getPhpName() . 'Node') ?>'; + + +/** + * Base static class for performing query operations on the tree contained by the + * 'getPhpName() ?>' table. + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + */ +class getPhpName() ?>NodePeer +{ + const NPATH_COLNAME = ''; + const NPATH_PHPNAME = ''; + const NPATH_SEP = ''; + + /** + * Temp function for CodeBase hacks that will go away. + */ + public static function isCodeBase($con = null) + { + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + return (get_class($con) == 'ODBCConnection' && + get_class($con->getAdapter()) == 'CodeBaseAdapter'); + } + + /** + * Create a new Node at the top of tree. This method will destroy any + * existing root node (along with its children). + * + * Use at your own risk! + * + * @param getPhpName() ?> Object wrapped by new node. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + * @throws PropelException + */ + public static function createNewRootNode($obj, $con = null) + { + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + try { + + $con->begin(); + + self::deleteNodeSubTree('1', $con); + + $setNodePath = 'set' . self::NPATH_PHPNAME; + + $obj->$setNodePath('1'); + $obj->save($con); + + $con->commit(); + + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + + return new getPhpName() ?>Node($obj); + } + + /** + * Inserts a new Node at the top of tree. Any existing root node (along with + * its children) will be made a child of the new root node. This is a + * safer alternative to createNewRootNode(). + * + * @param getPhpName() ?> Object wrapped by new node. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + * @throws PropelException + */ + public static function insertNewRootNode($obj, $con = null) + { + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + try { + + $con->begin(); + + // Move root tree to an invalid node path. + self::moveNodeSubTree('1', '0', $con); + + $setNodePath = 'set' . self::NPATH_PHPNAME; + + // Insert the new root node. + $obj->$setNodePath('1'); + $obj->save($con); + + // Move the old root tree as a child of the new root. + self::moveNodeSubTree('0', '1' . self::NPATH_SEP . '1', $con); + + $con->commit(); + + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + + return new getPhpName() ?>Node($obj); + } + + /** + * Retrieves an array of tree nodes based on specified criteria. Optionally + * includes all parent and/or child nodes of the matching nodes. + * + * @param Criteria Criteria to use. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return array Array of root nodes. + */ + public static function retrieveNodes($criteria, $ancestors = false, $descendants = false, $con = null) + { + $criteria = self::buildFamilyCriteria($criteria, $ancestors, $descendants); + $rs = getPhpName() ?>Peer::doSelectRS($criteria, $con); + return self::populateNodes($rs, $criteria); + } + + /** + * Retrieves a tree node based on a primary key. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param mixed getPhpName() ?> primary key (array for composite keys) + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + public static function retrieveNodeByPK($pk, $ancestors = false, $descendants = false, $con = null) + { + throw new PropelException('retrieveNodeByPK() not implemented yet.'); + } + + /** + * Retrieves a tree node based on a node path. Optionally includes all + * parent and/or child nodes of the matching node. + * + * @param string Node path to retrieve. + * @param boolean True if ancestors should also be retrieved. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + public static function retrieveNodeByNP($np, $ancestors = false, $descendants = false, $con = null) + { + $criteria = new Criteria(getPhpName() ?>Peer::DATABASE_NAME); + $criteria->add(self::NPATH_COLNAME, $np, Criteria::EQUAL); + $criteria = self::buildFamilyCriteria($criteria, $ancestors, $descendants); + $rs = getPhpName() ?>Peer::doSelectRS($criteria, $con); + $nodes = self::populateNodes($rs, $criteria); + return (count($nodes) == 1 ? $nodes[0] : null); + } + + /** + * Retrieves the root node. + * + * @param string Node path to retrieve. + * @param boolean True if descendants should also be retrieved. + * @param Connection Connection to use. + * @return getPhpName() ?>Node + */ + public static function retrieveRootNode($descendants = false, $con = null) + { + return self::retrieveNodeByNP('1', false, $descendants, $con); + } + + /** + * Moves the node subtree at srcpath to the dstpath. This method is intended + * for internal use by the BaseNode object. Note that it does not check for + * preexisting nodes at the dstpath. It also does not update the node path + * of any Node objects that might currently be in memory. + * + * Use at your own risk! + * + * @param string Source node path to move (root of the src subtree). + * @param string Destination node path to move to (root of the dst subtree). + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated "onCascadeDelete"s. + * @todo Need to abstract the SQL better. The CONCAT sql function doesn't + * seem to be standardized (i.e. mssql), so maybe it needs to be moved + * to DBAdapter. + */ + public static function moveNodeSubTree($srcPath, $dstPath, $con = null) + { + if (substr($dstPath, 0, strlen($srcPath)) == $srcPath) + throw new PropelException('Cannot move a node subtree within itself.'); + + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + /** + * Example: + * UPDATE table + * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74)) + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + $npath = self::NPATH_COLNAME; + //the following dot isn`t mean`t a nodeKeySeperator + $setcol = substr($npath, strpos($npath, '.')+1); + $setcollen = ; + $db = Propel::getDb(getPhpName() ?>Peer::DATABASE_NAME); + + // + if (getPhpName() ?>NodePeer::isCodeBase($con)) + { + // This is a hack to get CodeBase working. It will eventually be removed. + // It is a workaround for the following CodeBase bug: + // -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT) + $sql = "UPDATE " . getPhpName() ?>Peer::TABLE_NAME . " " . + "SET $setcol=" . $db->concatString("'$dstPath'", $db->subString($npath, strlen($srcPath)+1, $setcollen)) . " " . + "WHERE $npath = '$srcPath' OR $npath LIKE '" . $srcPath . self::NPATH_SEP . "%'"; + + $con->executeUpdate($sql); + } + else + { + // + $sql = "UPDATE " . getPhpName() ?>Peer::TABLE_NAME . " " . + "SET $setcol=" . $db->concatString('?', $db->subString($npath, '?', '?')) . " " . + "WHERE $npath = ? OR $npath LIKE ?"; + + $stmt = $con->prepareStatement($sql); + $stmt->setString(1, $dstPath); + $stmt->setInt(2, strlen($srcPath)+1); + $stmt->setInt(3, $setcollen); + $stmt->setString(4, $srcPath); + $stmt->setString(5, $srcPath . self::NPATH_SEP . '%'); + $stmt->executeUpdate(); + // + } + // + } + + /** + * Deletes the node subtree at the specified node path from the database. + * + * @param string Node path to delete + * @param Connection Connection to use. + * @return void + * @throws PropelException + * @todo This is currently broken for simulated "onCascadeDelete"s. + */ + public static function deleteNodeSubTree($nodePath, $con = null) + { + if ($con === null) + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + + /** + * DELETE FROM table + * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%' + */ + + $criteria = new Criteria(getPhpName() ?>Peer::DATABASE_NAME); + $criteria->add(self::NPATH_COLNAME, $nodePath, Criteria::EQUAL); + $criteria->addOr(self::NPATH_COLNAME, $nodePath . self::NPATH_SEP . '%', Criteria::LIKE); +// For now, we call BasePeer directly since getPhpName() ?>Peer tries to +// do a cascade delete. +// getPhpName() ?>Peer::doDelete($criteria, $con); + BasePeer::doDelete($criteria, $con); + } + + /** + * Builds the criteria needed to retrieve node ancestors and/or descendants. + * + * @param Criteria Criteria to start with + * @param boolean True if ancestors should be retrieved. + * @param boolean True if descendants should be retrieved. + * @return Criteria + */ + public static function buildFamilyCriteria($criteria, $ancestors = false, $descendants = false) + { + /* + Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants: + + SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH) + FROM test L, test + WHERE test.NPATH='1.2.3' AND + (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR + test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH))) + ORDER BY UCASE(L.NPATH) ASC + */ + + if ($criteria === null) + $criteria = new Criteria(getPhpName() ?>::DATABASE_NAME); + + if (!$criteria->getSelectColumns()) + getPhpName() ?>Peer::addSelectColumns($criteria); + + $db = Propel::getDb($criteria->getDbName()); + + if (($ancestors || $descendants) && $criteria->size()) + { + // If we are retrieving ancestors/descendants, we need to do a + // self-join to locate them. The exception to this is if no search + // criteria is specified. In this case we're retrieving all nodes + // anyway, so there is no need to do a self-join. + + // The left-side of the self-join will contain the columns we'll + // use to build node objects (target node records along with their + // ancestors and/or descendants). The right-side of the join will + // contain the target node records specified by the initial criteria. + // These are used to match the appropriate ancestor/descendant on + // the left. + + // Specify an alias for the left-side table to use. + $criteria->addAlias('L', getPhpName() ?>Peer::TABLE_NAME); + + // Make sure we have select columns to begin with. + if (!$criteria->getSelectColumns()) + getPhpName() ?>Peer::addSelectColumns($criteria); + + // Replace any existing columns for the right-side table with the + // left-side alias. + $selectColumns = $criteria->getSelectColumns(); + $criteria->clearSelectColumns(); + foreach ($selectColumns as $colName) + $criteria->addSelectColumn(str_replace(getPhpName() ?>Peer::TABLE_NAME, 'L', $colName)); + + $a = null; + $d = null; + + $npathL = getPhpName() ?>Peer::alias('L', self::NPATH_COLNAME); + $npathR = self::NPATH_COLNAME; + $npath_len = ; + + if ($ancestors) + { + // For ancestors, match left-side node paths which are contained + // by right-side node paths. + $a = $criteria->getNewCriterion($npathL, + "$npathL=" . $db->subString($npathR, 1, $db->strLength($npathL), $npath_len), + Criteria::CUSTOM); + } + + if ($descendants) + { + // For descendants, match left-side node paths which contain + // right-side node paths. + $d = $criteria->getNewCriterion($npathR, + "$npathR=" . $db->subString($npathL, 1, $db->strLength($npathR), $npath_len), + Criteria::CUSTOM); + } + + if ($a) + { + if ($d) $a->addOr($d); + $criteria->addAnd($a); + } + else if ($d) + { + $criteria->addAnd($d); + } + + // Add the target node path column. This is used by populateNodes(). + $criteria->addSelectColumn($npathR); + + // Sort by node path to speed up tree construction in populateNodes() + $criteria->addAsColumn('npathlen', $db->strLength($npathL)); + $criteria->addAscendingOrderByColumn('npathlen'); + $criteria->addAscendingOrderByColumn($npathL); + } + else + { + // Add the target node path column. This is used by populateNodes(). + $criteria->addSelectColumn(self::NPATH_COLNAME); + + // Sort by node path to speed up tree construction in populateNodes() + $criteria->addAsColumn('npathlen', $db->strLength(self::NPATH_COLNAME)); + $criteria->addAscendingOrderByColumn('npathlen'); + $criteria->addAscendingOrderByColumn(self::NPATH_COLNAME); + } + + return $criteria; + } + + /** + * This method reconstructs as much of the tree structure as possible from + * the given array of objects. Depending on how you execute your query, it + * is possible for the ResultSet to contain multiple tree fragments (i.e. + * subtrees). The array returned by this method will contain one entry + * for each subtree root node it finds. The remaining subtree nodes are + * accessible from the getPhpName() ?>Node methods of the + * subtree root nodes. + * + * @param array Array of getPhpName() ?>Node objects + * @return array Array of getPhpName() ?>Node objects + */ + public static function buildTree($nodes) + { + // Subtree root nodes to return + $rootNodes = array(); + + // Build the tree relations + foreach ($nodes as $node) + { + $sep = strrpos($node->getNodePath(), self::NPATH_SEP); + $parentPath = ($sep !== false ? substr($node->getNodePath(), 0, $sep) : ''); + $parentNode = null; + + // Scan other nodes for parent. + foreach ($nodes as $pnode) + { + if ($pnode->getNodePath() == $parentPath) + { + $parentNode = $pnode; + break; + } + } + + // If parent was found, attach as child, otherwise its a subtree root + if ($parentNode) + $parentNode->attachChildNode($node); + else + $rootNodes[] = $node; + } + + return $rootNodes; + } + + /** + * Populates the getPhpName() ?> objects from the + * specified ResultSet, wraps them in getPhpName() ?>Node + * objects and build the appropriate node relationships. + * The array returned by this method will only include the initial targets + * of the query, even if ancestors/descendants were also requested. + * The ancestors/descendants will be cached in memory and are accessible via + * the getNode() methods. + * + * @param ResultSet + * @param Criteria + * @return array Array of getPhpName() ?>Node objects. + */ + public static function populateNodes($rs, $criteria) + { + $nodes = array(); + $targets = array(); + $targetfld = count($criteria->getSelectColumns()); + +getChildrenColumn()) { ?> + // set the class once to avoid overhead in the loop + $cls = Propel::import(getPhpName() ?>Peer::getOMClass()); + + + // populate the object(s) + while($rs->next()) + { + if (!isset($nodes[$rs->getString(1)])) + { +getChildrenColumn()) { ?> + // class must be set each time from the record row + $cls = Propel::import(getPhpName() ?>Peer::getOMClass($rs, 1)); + + $obj = new $cls(); + $obj->hydrate($rs); + + $nodes[$rs->getString(1)] = new getPhpName() ?>Node($obj); + } + + $node = $nodes[$rs->getString(1)]; + + if ($node->getNodePath() == $rs->getString($targetfld)) + $targets[$node->getNodePath()] = $node; + } + + self::buildTree($nodes); + + return array_values($targets); + } + +} + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/Object.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/Object.tpl new file mode 100644 index 000000000..f12b2a9d1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/Object.tpl @@ -0,0 +1,1841 @@ +getDatabase(); +if ($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +$parentClass = ClassTools::getBaseClass($table); +?> + +require_once ''; + + +require_once ''; + +isAlias()) { + + // If any columns in table are BLOB or CLOB then we need to make + // sure those classes are included so we can do things like + // if ($v instanceof Lob) etc. + + $includes_lobs = false; + foreach ($table->getColumns() as $col) { + if ($col->isLob()) { + $includes_lobs = true; + break; + } + } + + if($includes_lobs) { ?> +include_once 'creole/util/Clob.php'; +include_once 'creole/util/Blob.php'; + + +include_once 'propel/util/Criteria.php'; +getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $className = $tblFK->getPhpName(); + if ($tblFK->getInterface()) { + $className = $tblFK->getInterface(); + } + + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } ?> + +// (on-demand) include_once ''; +// (on-demand) include_once 'getPhpName() . 'Peer') ?>'; + + +include_once 'getPhpName() . 'Peer') ?>'; + +/** + * Base class that represents a row from the 'getName() ?>' table. + * + * getDescription() ?> + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * You should not use this class directly. It should not even be + * extended; all references should be to getPhpName() ?> class. + * + * @package + */ +abstract class getPhpName() ?> extends implements { + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var getPhpName() ?>Peer + */ + protected static $peer; +isAlias()) { + foreach ($table->getColumns() as $col) { + $cptype = $col->getPhpNative(); + $clo=strtolower($col->getName()); + $defVal = ""; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $cptype); + $defaultValue = var_export($val, true); + $defVal = " = " . $defaultValue; + } +?> + + /** + * The value for the field. + * @var + */ + protected $; +isLazyLoad()) { ?> + + /** + * Whether the lazy-loaded value has been loaded from database. + * This is necessary to avoid repeated lookups if column is NULL. + * @var boolean + */ + protected $_isLoaded = false; +getColumns() as $col) { + + $cfc=$col->getPhpName(); + $clo=strtolower($col->getName()); + $cptype = $col->getPhpNative(); + + $defaultValue = null; + if (($val = $col->getPhpDefaultValue()) !== null) { + settype($val, $cptype); + $defaultValue = var_export($val, true); + } + + if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + // these default values are based on the Creole defaults + // the date and time default formats are locale-sensitive + if ($col->getType() === PropelTypes::DATE) { + $defaultfmt = '%x'; + } elseif ($col->getType() === PropelTypes::TIME) { + $defaultfmt = '%X'; + } elseif ($col->getType() === PropelTypes::TIMESTAMP) { + $defaultfmt = 'Y-m-d H:i:s'; + } +?> + + /** + * Get the [optionally formatted] `` column value. + * getDescription() ?> + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function get($format = ''isLazyLoad()) echo ', $con = null'; ?>) + { +isLazyLoad()) { ?> + if (!$this->_isLoaded && $this-> === null && !$this->isNew()) { + $this->load($con); + } + + if ($this-> === null || $this-> === '') { + return null; + } elseif (!is_int($this->)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->); + if ($ts === -1) { + throw new PropelException("Unable to parse value of as date/time value: " . var_export($this->, true)); + } + } else { + $ts = $this->; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the column value. + * getDescription() ?> + * @return + */ + public function get(isLazyLoad()) echo '$con = null'; ?>) + { +isLazyLoad()) { ?> + if (!$this->_isLoaded && $this-> === null && !$this->isNew()) { + $this->load($con); + } + + return $this->; + } + + +isLazyLoad()) { ?> + /** + * Load the value for the [lazy-load] `` column. + * + * This method performs an additional query to return the value for + * the `` column, since it is not populated by + * the hydrate() method. + * + * @param Connection + * @return void + * @throws PropelException - any underlying error will be wrapped and re-thrown. + */ + protected function load($con = null) + { + $c = $this->buildPkeyCriteria(); + $c->addSelectColumn(getPhpName()) ?>); + try { + $rs = getPhpName()?>Peer::doSelectRS($c, $con); + $rs->next(); +getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) { + + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: + ?> + $this-> = $rs->get(1, null); + + $this-> = $rs->get(1); + + $this->_isLoaded = true; + } catch (Exception $e) { + throw new PropelException("Error loading value for `` column on demand.", $e); + } + } + + +isReadOnly()) { + + + $throwsClause = ""; + if ($complexObjectModel) { + if ($col->isForeignKey()) { + $throwsClause = "@throws PropelException"; + } + if (count($col->getReferrers()) > 0 ) { + if ($throwsClause == "") { + $throwsClause = "@throws PropelException"; + } + } + } + if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + $throwsClause = "@throws PropelException - If passed [not-null] date/time is in an invalid format."; + } + + ?> + + /** + * Set the value of `` column. + * getDescription() ?> + * @param getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) ? 'mixed' : $cptype ?> $v new value + * @return void + * + */ + public function set($v) + { +isLazyLoad()) { ?> + // explicitly set the is-loaded flag to true for this lazy load col; + // it doesn't matter if the value is actually set or not (logic below) as + // any attempt to set the value means that no db lookup should be performed + // when the get() method is called. + $this->_isLoaded = true; + +isLob()) { + // Setting of LOB columns gets some special handling + + if ($col->getPropelType() === PropelTypes::BLOB || $col->getPropelType() === PropelTypes::LONGVARBINARY ) { + $lobClass = "Blob"; + } else { + $lobClass = "Clob"; + } + ?> + // if the passed in parameter is the *same* object that + // is stored internally then we use the Lob->isModified() + // method to know whether contents changed. + if ($v instanceof Lob && $v === $this->) { + $changed = $v->isModified(); + } else { + $changed = ($this-> !== $v); + } + if ($changed) { + if ( !($v instanceof Lob) ) { + $obj = new (); + $obj->setContents($v); + } else { + $obj = $v; + } + $this-> = $obj; + $this->modifiedColumns[] = getPhpName()) ?>; + } +getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) { + // Setting a DATE/TIME value gets some special handling. +?> + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1) { + throw new PropelException("Unable to parse date/time value for from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this-> !== $ts || $ts === ) { + $this-> = $ts; + $this->modifiedColumns[] = getPhpName()) ?>; + } + + if ($this-> !== $v || $v === ) { + $this-> = $v; + $this->modifiedColumns[] = getPhpName()) ?>; + } + + $this-> = $v; +isForeignKey()) { + $tblFK = $table->getDatabase()->getTable($col->getRelatedTableName()); + $colFK = $tblFK->getColumn($col->getRelatedColumnName()); + if ($col->isMultipleFK() || $col->getRelatedTableName() == $table->getName()) { + $relCol = ""; + foreach ($col->getForeignKey()->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $relCol .= $column->getPhpName(); + } + if ($relCol != "") { + $relCol = "RelatedBy".$relCol; + } + $varName = "a".$tblFK->getPhpName() . $relCol; + } else { + $varName = "a".$tblFK->getPhpName(); + } + + ?> + + if ($this-> !== null && $this->->getgetPhpName() ?>() !== $v) { + $this-> = null; + } + getReferrers() as $fk) { + // used to be getLocalForeignMapping() which did not work. + $flmap = $fk->getForeignLocalMapping(); + $fkColName = $flmap[$col->getName()]; + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) { + $colFK = $tblFK->getColumn($fkColName); + if ($colFK->isMultipleFK()) { + $collName = "coll" . $tblFK->getPhpName() . "sRelatedBy" . $colFK->getPhpName(); + } else { + $collName = "coll" . $tblFK->getPhpName() . "s"; + } + ?> + + // update associated getPhpName() ?> + + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + $this->[$i]->setgetPhpName()?>($v); + } + } + + + + + } + +isReadOnly() */ + } /* foreach col */ +?> + + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { +getColumns() as $col) { + if(!$col->isLazyLoad()) { + $affix = CreoleTypes::getAffix(CreoleTypes::getCreoleCode($col->getType())); + $clo = strtolower($col->getName()); + switch($col->getType()) { + + case PropelTypes::DATE: + case PropelTypes::TIME: + case PropelTypes::TIMESTAMP: + ?> + $this-> = $rs->get($startcol + , null); + + $this-> = $rs->get($startcol + ); +isLazyLoad() + } /* foreach */ + ?> + + $this->resetModified(); + + $this->setNew(false); + + return $startcol + ; + + } catch (Exception $e) { + throw new PropelException("Error populating getPhpName()?> object", $e); + } + + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(getPhpName()?>Peer::DATABASE_NAME); +getColumns() as $col) { + $clo = strtolower($col->getName()); + if ($col->isPrimaryKey()) { ?> + $criteria->add(getPhpName()) ?>, $this->); + + return $criteria; + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(getPhpName()?>Peer::DATABASE_NAME); +getColumns() as $col) { + $clo = strtolower($col->getName()); + ?> + if ($this->isColumnModified(getPhpName()) ?>)) $criteria->add(getPhpName()) ?>, $this->); + + return $criteria; + } + +isAlias */ ?> + +getForeignKeys() as $fk) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $className = $tblFK->getPhpName(); + + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } + + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol != "") { + $relCol = "RelatedBy" . $relCol; + } + + $pVarName = $className . $relCol; + $varName = "a" . $pVarName; + $retVal = ($pVars[] = $pVarName); + $retVal = ($aVars[] = $varName); +?> + + /** + * @var + */ + protected $; + + /** + * Declares an association between this object and a object + * + * @param $v + * @return void + * @throws PropelException + */ + public function set($v) + { +getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $lfmap = $fk->getLocalForeignMapping(); + $colFKName = $lfmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); ?> + + if ($v === null) { + $this->setgetPhpName() ?>(getPhpDefaultValue()) ?>); + } else { + $this->setgetPhpName() ?>($v->getgetPhpName() ?>()); + } + + + $this-> = $v; + } + +getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + $cptype = $column->getPhpNative(); + $clo = strtolower($column->getName()); + if ($cptype == "integer" || $cptype == "float" || $cptype == "double") { + $conditional .= $and . "\$this->". $clo ." > 0"; + } elseif($cptype == "string") { + $conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)"; + } else { + $conditional .= $and . "\$this->" . $clo ." !== null"; + } + $arglist .= $comma . "\$this->" . $clo; + $and = " && "; + $comma = ", "; + $argsize = $argsize + 1; + } + + $pCollName = $table->getPhpName() . 's' . $relCol; +?> + + /** + * Get the associated object + * + * @param Connection Optional Connection object. + * @return The associated object. + * @throws PropelException + */ + public function get($con = null) + { + // include the Peer class + include_once 'Peer.php'; + + if ($this-> === null && ()) { +isAlias()) { + if ($argsize > 1) { +?> + + $this-> = Peer::retrieveByPK(, $con); + + + $this-> = Peer::retrieveByPK(, $con); + 1) { ?> + + $this-> = Peer::retrieveByPK(, $con); + + + $this-> = Peer::retrieveByPK(, $con); + isAlias ?> + + /* The following can be used instead of the line above to + guarantee the related object contains a reference + to this object, but this level of coupling + may be undesirable in many circumstances. + As it can lead to a db query with many results that may + never be used. + $obj = Peer::retrieveByPK(, $con); + $obj->add($this); + */ + } + return $this->; + } + + /** + * Provides convenient way to set a relationship based on a + * key. e.g. + * $bar->setFooKey($foo->getPrimaryKey()) + * +getLocalColumns()) > 1) { ?> + * Note: It is important that the xml schema used to create this class + * maintains consistency in the order of related columns between + * getName() ?> and getName() ?>. + * If for some reason this is impossible, this method should be + * overridden in getPhpName() ?>. + + * @return void + * @throws PropelException + */ + public function setKey($key) + { +getLocalColumns()) > 1) { + $i = 0; + foreach ($fk->getLocalColumns() as $colName) { + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); +?> + + $this->setgetPhpName() ?>( () $key[] ); +getLocalColumns(); + $colName = $lcols[0]; + $col = $table->getColumn($colName); + $fktype = $col->getPhpNative(); +?> + + $this->setgetPhpName() ?>( () $key); + + + } +getReferrers() as $fk) { + $tblFK = $fk->getTable(); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + $tblFKPackagePath = strtr($tblFKPackage, '.', '/'); + if ($tblFKPackagePath != "") { + $tblFKPackagePath .= '/'; + } + + $className = $tblFK->getPhpName(); + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK() || $tblFK->getName() == $table->getName()) { + // if there are seeral foreign keys that point to the same table + // then we need to generate methods like getAuthorRelatedByColName() + // instead of just getAuthor(). Currently we are doing the same + // for self-referential foreign keys, to avoid confusion. + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $suffix = ""; + $relCol = $className . "s"; + $relColMs = $className; + } else { + $suffix = "RelatedBy" . $relatedByCol; + $relCol= $className . "sRelatedBy" . $relatedByCol; + $relColMs= $className . "RelatedBy" . $relatedByCol; + } + $collName = "coll" . $relCol; +?> + + /** + * Collection to store aggregation of + * @var array + */ + protected $; + + /** + * Temporary storage of to save a possible db hit in + * the event objects are add to the collection, but the + * complete collection is never requested. + * @return void + */ + public function init() + { + if ($this-> === null) { + $this-> = array(); + } + } + + /** + * Method called to associate a getPhpName() ?> object to this object + * through the foreign key attribute + * + * @param $l $className + * @return void + * @throws PropelException + */ + public function add( $l) + { + $this->[] = $l; + $l->setgetPhpName() . $suffix ?>($this); + } + + /** + * The criteria used to select the current contents of . + * @var Criteria + */ + private $lastCriteria = null; + + /** + * Returns the number of related + * + * @param Criteria $criteria + * @param boolean $distinct + * @param Connection $con + * @throws PropelException + */ + public function count($criteria = null, $distinct = false, $con = null) + { + // include the Peer class + include_once 'Peer.php'; + if ($criteria === null) { + $criteria = new Criteria(); + } +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + // used to be getLocalForeignMapping() but that didn't seem to work + // (maybe a problem in translation of HashTable code to PHP). + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add(, $this->getgetPhpName() ?>() ); +getForeignColumns() +?> + return Peer::doCount($criteria, $distinct, $con); + } + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this getPhpName() ?> has previously + * been saved, it will retrieve related from storage. + * If this getPhpName() ?> is new, it will return + * an empty collection or the current collection, the criteria + * is ignored on a new object. + * + * @param Connection $con + * @param Criteria $criteria + * @throws PropelException + */ + public function get($criteria = null, $con = null) + { + // include the Peer class + include_once 'Peer.php'; + if ($criteria === null) { + $criteria = new Criteria(); + } + + if ($this-> === null) { + if ($this->isNew()) { + $this-> = array(); + } else { +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + // used to be getLocalForeignMapping() but that didn't seem to work + // (maybe a problem in translation of HashTable code to PHP). + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + + $criteria->add(, $this->getgetPhpName() ?>() ); +getForeignColumns() +?> + + $this-> = Peer::doSelect($criteria, $con); + } + } else { + // criteria has no effect for a new object + if (!$this->isNew()) { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + $flmap = $fk->getForeignLocalMapping(); + $colFKName = $flmap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + + $criteria->add(, $this->getgetPhpName() ?>()); +getForeignColumns() +?> + + if (!isset($this->lastCriteria) || !$this->lastCriteria->equals($criteria)) { + $this-> = Peer::doSelect($criteria, $con); + } + } + } + $this->lastCriteria = $criteria; + + return $this->; + } + +getForeignKeys() as $dummyFK) { + $countFK = $countFK + 1; + } + +// ------------------------------------------------------------ +// + + if ($countFK >= 1) { + $lastTable = ""; + foreach ($tblFK->getForeignKeys() as $fk2) { + // Add join methods if the fk2 table is not this table or + // the fk2 table references this table multiple times. + + $doJoinGet = true; + if ( $fk2->getForeignTableName() == $table->getName() ) { + $doJoinGet = false; + } + + foreach ($fk2->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $doJoinGet = true; + } + } + + $tblFK2 = $table->getDatabase()->getTable($fk2->getForeignTableName()); + $doJoinGet = !$tblFK2->isForReferenceOnly(); + $relatedByCol2 = ""; + foreach ($fk2->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol2 .= $column->getPhpName(); + } + } + + $fkClassName = $tblFK2->getPhpName(); + + // do not generate code for self-referencing fk's, it would be + // good to do, but it is just not implemented yet. + if ($className == $fkClassName) { + // $doJoinGet = false; -- SELF REFERENCING FKs UNDER TESTING + } + + if ($relatedByCol2 == "") { + $relCol2 = $fkClassName; + } else { + $relCol2 = $fkClassName . "RelatedBy". $relatedByCol2; + } + + if ( $relatedByCol == "") { + // nothing? + } else { + if ( $relatedByCol == $relatedByCol2 ) { + $doJoinGet = false; + } + } + + if ($doJoinGet) { +?> + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this getPhpName() ?> is new, it will return + * an empty collection; or if this getPhpName() ?> has previously + * been saved, it will retrieve related from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in getPhpName() ?>. + */ + public function getJoin($criteria = null, $con = null) + { + // include the Peer class + include_once 'Peer.php'; + if ($criteria === null) { + $criteria = new Criteria(); + } + + if ($this-> === null) { + if ($this->isNew()) { + $this-> = array(); + } else { +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + $flMap = $fk->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add(, $this->getgetPhpName() ?>()); +getForeignColumns() +?> + $this-> = Peer::doSelectJoin($criteria, $con); + } + } else { + // the following code is to determine if a new query is + // called for. If the criteria is the same as the last + // one, just return the collection. +getForeignColumns() as $columnName) { + $column = $table->getColumn($columnName); + $flMap = $fk->getForeignLocalMapping(); + $colFKName = $flMap[$columnName]; + $colFK = $tblFK->getColumn($colFKName); +?> + $criteria->add(, $this->getgetPhpName() ?>()); +getForeignColumns() */ +?> + if (!isset($this->lastCriteria) || !$this->lastCriteria->equals($criteria)) { + $this-> = Peer::doSelectJoin($criteria, $con); + } + } + $this->lastCriteria = $criteria; + + return $this->; + } +getForeignKeys() as $fk2) { */ + } /* end if countFK >= 1 */ + + } /*ends foreach over table->getReferrers() */ + +} /* the if(complexObjectModel) */ + +// +// add GenericAccessors or GenericMutators? +// +if (!$table->isAlias() && ($addGenericAccessors || ($addGenericMutators && !$table->isReadOnly()))) +{ +?> + + /** + * phpname type + * e.g. 'AuthorId' + */ + const TYPE_PHPNAME = 'phpName'; + + /** + * column (peer) name type + * e.g. 'book.AUTHOR_ID' + */ + const TYPE_COLNAME = 'colName'; + + /** + * column fieldname type + * e.g. 'author_id' + */ + const TYPE_FIELDNAME = 'fieldName'; + + /** + * num type + * simply the numerical array index, e.g. 4 + */ + const TYPE_NUM = 'num'; +getColumns(); + $tablePhpname = $table->getPhpName(); +?> + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + getPhpName() ?>::TYPE_PHPNAME => array ('getPhpName(); ?>', ), + getPhpName() ?>::TYPE_COLNAME => array (, ), + getPhpName() ?>::TYPE_FIELDNAME => array ('getName(); ?>', ), + getPhpName() ?>::TYPE_NUM => array ( $col) { echo $num; ?>, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + getPhpName() ?>::TYPE_PHPNAME => array ( $col) { ?>'getPhpName(); ?>' => , ), + getPhpName() ?>::TYPE_COLNAME => array ( $col) { ?> => , ), + getPhpName() ?>::TYPE_FIELDNAME => array ( $col) { ?>'getName(); ?>' => , ), + getPhpName() ?>::TYPE_NUM => array ( $col) { echo $num; ?>, ) + ); + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = self::TYPE_FIELDNAME) + { + if (!isset(self::$fieldNames[$type])) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = self::$fieldKeys[$fromType][$name]; + if ($key === false) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r($fromNames, true)); + } + return $toNames[$key]; + } + + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = self::TYPE_COLNAME) + { + $names = self::getFieldNames($type); + $pos = self::translateFieldName($name, $type, self::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { +getColumns() as $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative();// not safe to use it because some methods may return objects (Blob) +?> + case : + return $this->get(); + break; + + default: + return null; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = self::TYPE_PHPNAME) + { + $keys = self::getFieldNames($keyType); + $result = array( +getColumns() as $num => $col) { +?> + $keys[] => $this->getgetPhpName(); ?>(), + + ); + return $result; + } + + + +isReadOnly()) { ?> + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = self::TYPE_COLNAME) + { + $names = $this->getFieldnames($type); + $pos = array_search($name, $names); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { +getColumns() as $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); +?> + case : + $this->set($value); + break; + + } // switch() + } + + /** + * Populates the object using an array. + * + * This method is just an alias for populateFromArray() + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function fromArray($arr, $keyType = self::TYPE_COLNAME) + { + return $this->populateFromArray($arr, $keyType); + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the (peer) column name (e.g. + * 'book.AUTHOR_ID') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function populateFromArray($arr, $keyType = self::TYPE_COLNAME) + { + $keys = self::getFieldNames($keyType); +getColumns() as $num => $col) { + $cfc = $col->getPhpName(); + $cptype = $col->getPhpNative(); +?> + if (array_key_exists($keys[], $arr)) $this->set($arr[$keys[]]); + + } + + + +isAlias() && isset($addSaveMethod) && $addSaveMethod && !$table->isReadOnly()) { ?> + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) + $con = Propel::getConnection(getPhpName()?>Peer::DATABASE_NAME); + + try { + $con->begin(); + getPhpName() ?>Peer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + + + /** + * flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + private $alreadyInSave = false; + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return void + * @throws PropelException + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) + $con = Propel::getConnection(getPhpName()?>Peer::DATABASE_NAME); + + try { + $con->begin(); + $this->doSave($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. + * + * @param Connection $con + * @return void + * @throws PropelException + */ + + protected function doSave($con) + public function save($con = null) + { + + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(getPhpName() ?>Peer::DATABASE_NAME); + } + + + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // We call the save method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this-> !== null) { + if ($this->->isModified()) $this->->save($con); + $this->set($this->); + } + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = getPhpName() ?>Peer::doInsert($this, $con); +getIdMethod() != "none") { + + if (count($pks = $table->getPrimaryKey())) { + foreach ($pks as $pk) { + if ($pk->isAutoIncrement()) { +?> + $this->setgetPhpName();?>( $pk ); //[IMV] update autoincrement primary key + + $this->setNew(false); + } else { + getPhpName() ?>Peer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } +getReferrers() as $fk) { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $relCol = $className . "s"; + } else { + $relCol = $className . "sRelatedBy" . $relCol; + } + + $collName = "coll" . $relCol; +?> + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + $this->[$i]->save($con); + } + } + + + + $this->alreadyInSave = false; + } + + } +isAlias && isset .... */ +?> + +isAlias() && !$table->isReadOnly()) { +?> + /** + * Validates the objects modified field values. + + * This includes all objects related to this table. + + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * + * @return mixed true if all columns pass validation + * or an array of ValidationFailed objects for columns that fail. + */ + public function validate($columns = null) + { + if ($columns) + { + return getPhpName()?>Peer::doValidate($this, $columns); + } + + + return getPhpName()?>Peer::doValidate($this); + + return $this->doValidate(); + + } + + + /** + * flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then true is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. + */ + protected function doValidate() + { + if (! $this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + // We call the validate method on the following object(s) if they + // were passed to this object by their coresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this-> !== null) { + if (($retval = $this->->validate()) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + } + + + if (($retval = getPhpName()?>Peer::doValidate($this)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + +getReferrers() as $fk) { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $relCol = $className . "s"; + } else { + $relCol = $className . "sRelatedBy" . $relCol; + } + + $collName = "coll" . $relCol; +?> + if ($this-> !== null) { + for ($i=0,$size=count($this->); $i < $size; $i++) { + if (($retval = $this->[$i]->validate()) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + } + } + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + + +isAlias()) { + + if (!$table->isReadOnly()) { + + $throwsClause = "@throws PropelException"; + + if (count($table->getPrimaryKey()) == 1) { + $pkeys = $table->getPrimaryKey(); + $col = $pkeys[0]; + $clo=strtolower($col->getName()); + $cptype= $col->getPhpNative(); +?> + /** + * Set the PrimaryKey. + * + * @param mixed Primary key. + * @return void + * + */ + public function setPrimaryKey($key) + { + $this->setgetPhpName() ?>($key); + } + +getPrimaryKey()) > 1) { /* if(count($table->getPrimaryKey()) == 1) */ +?> + + private $pks = array(); + + /** + * Set the PrimaryKey. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + * @throws PropelException + */ + public function setPrimaryKey($keys) + { +getPrimaryKey() as $pk) { + $pktype = $pk->getPhpNative(); +?> + + $this->setgetPhpName() ?>($keys[]); +getPrimaryKey() */ +?> + + } + +getPrimaryKey()) == 1) */ +?> + + /** + * Dummy primary key setter. + * + * This function only exists to preserve backwards compatibility. It is no longer + * needed or required by the Persistent interface. It will be removed in next BC-breaking + * release of Propel. + * + * @deprecated + */ + public function setPrimaryKey($pk) + { + // do nothing, because this object doesn't have any primary keys + } +getPrimaryKey()) == 1) */ + + } /* !table->isReadOnly() */ +?> + + /** + * Returns an id that differentiates this object from others + * of its class. + * @return getPrimaryKey()) === 0) { echo "null"; } elseif (count($table->getPrimaryKey()) > 1) { echo "array"; } else { $pkeys = $table->getPrimaryKey(); echo $pkeys[0]->getPhpType(); } ?> + */ + public function getPrimaryKey() + { +getPrimaryKey()) == 1) { +?> + + return $this->getgetPrimaryKey(); echo $pkeys[0]->getPhpName()?>(); +getPrimaryKey()) > 1) { /* if (count($table->getPrimaryKey()) == 1) { */ + $i = 0; + foreach ($table->getPrimaryKey() as $pk) { +?> + $this->pks[] = $this->getgetPhpName() ?>(); + + return $this->pks; +getPrimaryKey()) == 1) { */ +?> + + return null; +getPrimaryKey()) == 1) { */ +?> + + } + +isAbstract()) { +?> + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * + * @return getPhpName() ?> Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + $clazz = get_class($this); + $copyObj = new $clazz(); +getColumns() as $pkcol) { + if ($pkcol->isPrimaryKey()) { + $pkcols[] = $pkcol->getName(); + } + } + + foreach ($table->getColumns() as $col) { + + if (!in_array($col->getName(), $pkcols)) { +?> + $copyObj->setgetPhpName()?>($this->getName()) ?>); +getReferrers()) > 0) { +?> + + if ($deepCopy) { + // important: setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); +getReferrers() as $fk) { + $tblFK = $fk->getTable(); + if ( $tblFK->getName() != $table->getName() ) { + $className = $tblFK->getPhpName(); + $relCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $tblFK->getColumn($columnName); + if ($column->isMultipleFK()) { + $relCol .= $column->getPhpName(); + } + } + + if ($relCol == "") { + $pCollName = $className . "s"; + $pCollNameNoS = $className; + } else { + $pCollName = $className . "sRelatedBy".$relCol; + $pCollNameNoS = $className . "RelatedBy".$relCol; + } +?> + + foreach($this->get() as $relObj) { + $copyObj->add($relObj->copy()); + } + + } // if ($deepCopy) + 0 ) */ +?> + + $copyObj->setNew(true); + +getColumns() as $col) { + if ($col->isPrimaryKey()) { + $coldefval = $col->getPhpDefaultValue(); + + // This seems to work pretty well for getting + // the right value (including NULL) + $coldefval = var_export($coldefval, true); +?> + $copyObj->setgetPhpName()?>(); // this is a pkey column, so set to default value +isPrimaryKey + } // foreach +?> + + return $copyObj; + } + +isAbstract()) */ +?> + + /** + * returns a peer instance associated with this om. Since Peer classes + * are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * @return getPhpName() ?>Peer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new getPhpName() ?>Peer(); + } + return self::$peer; + } +isAlias */ +?> + +} diff --git a/gulliver/thirdparty/propel-generator/templates/om/php5/Peer.tpl b/gulliver/thirdparty/propel-generator/templates/om/php5/Peer.tpl new file mode 100644 index 000000000..4ce7af48f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/om/php5/Peer.tpl @@ -0,0 +1,1501 @@ +getDatabase(); +if($table->getPackage()) { + $package = $table->getPackage(); +} else { + $package = $targetPackage; +} + +echo '<' . '?' . 'php'; + + +$basePeerClass = ClassTools::getBasePeer($table); +$basePeerClassname = ClassTools::classname($basePeerClass); +?> + +require_once ''; + +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by getPhpName() ?>Peer::getOMClass() +include_once 'getPhpName()) ?>'; +getForeignKeys() as $fk) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + + if (!$tblFK->isForReferenceOnly()) { + ?> + +include_once 'getPhpName()) ?>'; +include_once 'getPhpName() . 'Peer') ?>'; +isForReferenceOnly() +} // foreach +?> + +/** + * Base static class for performing query and update operations on the 'getName() ?>' table. + * + * getDescription() ?> + * + + * This class was autogenerated by Propel on: + * + * [] + * + + * @package + */ +abstract class getPhpName() ?>Peer +{ +isAlias()) { ?> + + /** the default database name for this class */ + const DATABASE_NAME = "getDatabase()->getName() ?>"; + + /** the table name for this class */ + const TABLE_NAME = "getName() ?>"; + +getColumns() as $col) { ?> + /** the column name for the getName()) ?> field */ + const = "getName() . '.' . strtoupper($col->getName()) ?>"; + + + +isAlias()) */ ?> + + /** number of columns for this peer */ + public static $numColumns = getNumColumns() ?>; + + /** number of lazy load columns for this peer */ + public static $numLazyLoadColumns = getNumLazyLoadColumns() ?>; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = "getPhpName() ?>"; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'getPhpName() . 'MapBuilder') ?>'; + return ::getMapBuilder(getPhpName() ?>MapBuilder::CLASS_NAME); + } + + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @todo Consider having template build the array rather than doing it at runtime. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = getPhpName() ?>Peer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } +isAlias()) { + + + if ($table->getChildrenColumn()) { + + $col = $table->getChildrenColumn(); + $tfc = $table->getPhpName(); + $cfc = $col->getPhpName(); + + if ($col->isEnumeratedClasses()) { + + if ($col->isPrimitiveNumeric()) $quote = ""; + else $quote = '"'; + + foreach ($col->getChildren() as $child) { + $childpkg = ($child->getPackage() ? $child->getPackage() : $package); +?> + /** A key representing a particular subclass */ + const CLASSKEY_getKey()) ?> = getKey() . $quote ?>; + + /** A class that can be returned by this peer. */ + const CLASSNAME_getKey()) ?> = "getClassName() ?>"; +isenumerated...() */ + } /* if table->getchildrencolumn() */ +?> + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. getPhpName() ?>Peer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return $alias . substr($column, strlen(self::TABLE_NAME)); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { +getColumns() as $col) { + if (!$col->isLazyLoad()) { + ?> + $criteria->addSelectColumn(self::); + + } + +hasPrimaryKey()) { + $pk = $table->getPrimaryKey(); + $count_col = $table->getName() . "." . strtoupper($pk[0]->getName()); + } +?> + const COUNT = "COUNT()"; + const COUNT_DISTINCT = "COUNT(DISTINCT )"; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns. + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(getPhpName()?>Peer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(getPhpName()?>Peer::COUNT); + } + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = getPhpName()?>Peer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return getPhpName() ?> + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = getPhpName() ?>Peer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return getPhpName() ?>Peer::populateObjects(getPhpName() ?>Peer::doSelectRS($criteria, $con)); + } + + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see ::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + getPhpName() ?>Peer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return ::doSelect($criteria, $con); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + +getChildrenColumn()) { ?> + // set the class once to avoid overhead in the loop + $cls = getPhpName() ?>Peer::getOMClass(); + $cls = Propel::import($cls); + + + // populate the object(s) + while($rs->next()) { +getChildrenColumn()) { ?> + // class must be set each time from the record row + $cls = Propel::import(getPhpName() ?>Peer::getOMClass($rs, 1)); + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + +isAlias() */ ?> + +getChildrenColumn()) { + + $col = $table->getChildrenColumn(); +?> + + /** + * The returned Class will contain objects of the default type or + * objects that inherit from the default. + * + * @param ResultSet $rs ResultSet with pointer to record containing om class. + * @param int $colnum Column to examine for OM class information (first is 1). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getOMClass(ResultSet $rs, $colnum) + { + $c = null; + + try { + isEnumeratedClasses()) { ?> + + $omClass = null; + $classKey = $rs->getString($colnum - 1 + getPosition() ?>); + + switch($classKey) { + getChildren() as $child) { + ?> + + case self::CLASSKEY_getKey()) ?>: + $omClass = self::CLASSNAME_getKey()) ?>; + break; + + + default: + + isAbstract()) { ?> + + $error = "You must implement the getOMClass method in your" + ." Peer object in order for things to work properly." + ." This method should return the proper Class that" + ." represents the Peer's Business Object."; + + throw new PropelException($error); + + + $omClass = self::CLASS_DEFAULT; + + + } // switch + + $c = $omClass; + + + + $c = Propel::import($rs->getString($colnum - 1 + getPosition() ?>)); + + + } catch (Exception $e) { + throw new PropelException("Unable to get OM class.", $e); + } + return $c; + } + +getchildrencolumn */ ?> + + /** + * The class that the Peer will make instances of. + * If the BO is abstract then you must implement this method + * in the BO. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getOMClass() + {isAbstract()) { ?> + $error = "You must implement the getOMClass method in your" + ." Peer object in order for things to work properly." + ." This method should return the proper Class that" + ." represents the Peer's Business Object."; + + throw new PropelException($error); + + return self::CLASS_DEFAULT; + + } +getchildrencolumn */ + +if (!$table->isAlias() && !$table->isReadOnly()) { + +?> + + /** + * Method perform an INSERT on the database, given a getPhpName() ?> or Criteria object. + * + * @param mixed $values Criteria or getPhpName() ?> object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) + $con = Propel::getConnection(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = $values; + } else { + $criteria = $values->buildCriteria(); + } + +getColumns() as $col) { + $cfc = $col->getPhpName(); + if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none") { ?> + + $criteria->remove(self::); // remove pkey col since this table uses auto-increment + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = ::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } +supportsNativeDeleteTrigger() && count($table->getReferrers()) > 0) { + foreach ($table->getReferrers() as $fk) { + if ( $fk->getOnDelete() == ForeignKey::CASCADE ) { + $deleteCascadeRelevant = true; + } elseif ($fk->getOnDelete() == ForeignKey::SETNULL) { + $deleteSetNullRelevant = true; + } + } + } // if count(foreign keys) +?> + + /** + * Method perform an UPDATE on the database, given a getPhpName() ?> or Criteria object. + * + * @param mixed $values Criteria or getPhpName() ?> object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = $values; +getColumns() as $col) { + if($col->isPrimaryKey()) { ?> + $comparison = $criteria->getComparison(self::); + $selectCriteria->add(self::, $criteria->remove(self::), $comparison); + + } else { // $values is getPhpName() ?> object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return ::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the getName() ?> table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) $con = Propel::getConnection(self::DATABASE_NAME); + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += getPhpName() ?>Peer::doOnDeleteCascade(new Criteria(), $con); + getPhpName() ?>Peer::doOnDeleteSetNull(new Criteria(), $con); + $affectedRows += BasePeer::doDeleteAll(self::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a getPhpName() ?> or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or getPhpName() ?> object or primary key which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) + $con = Propel::getConnection(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = $values; + } elseif ($values instanceof getPhpName() ?>) { +getColumns() as $col) { + if($col->isPrimaryKey()) $pkey_count++; + } + + if ($pkey_count > 0) { + ?> + $criteria = $values->buildPkeyCriteria(); + + $criteria = $values->buildCriteria(); + + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); +getPrimaryKey()) == 1) { + $pkey = $table->getPrimaryKey(); + $col = array_shift($pkey); ?> + $criteria->add(self::, $values); + + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values +getPrimaryKey() as $col) { ?> + $criteria->add(self::, $values[]); + + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += getPhpName() ?>Peer::doOnDeleteCascade($criteria, $con); + getPhpName() ?>Peer::doOnDeleteSetNull($criteria, $con); + $affectedRows += ::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + + + /** + * This is a method for emulating ON DELETE CASCADE for DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria $criteria + * @param Connection $con + * @return int The number of affected rows (if supported by underlying database driver). + */ + protected static function doOnDeleteCascade(Criteria $criteria, Connection $con) + { + // initialize var to track total num of affected rows + $affectedRows = 0; + + // first find the objects that are implicated by the $criteria + $objects = getPhpName() ?>Peer::doSelect($criteria, $con); + foreach($objects as $obj) { +getReferrers() as $fk) { + + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + $tblFKPackage = ($tblFK->getPackage() ? $tblFK->getPackage() : $package); + + if (!$tblFK->isForReferenceOnly()) { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete cascade for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::CASCADE && + $fk->getTable()->getName() != $table->getName()) { + + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); // should be same num as foreign +?> + + include_once 'getPhpName()); ?>'; + + // delete related objects + $c = new Criteria(); + getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); + + ?>$c->add(, $obj->getgetPhpName() ?>()); + $affectedRows += Peer::doDelete($c, $con); + + } + return $affectedRows; + } + + + + /** + * This is a method for emulating ON DELETE SET NULL DBs that don't support this + * feature (like MySQL or SQLite). + * + * This method is not very speedy because it must perform a query first to get + * the implicated records and then perform the deletes by calling those Peer classes. + * + * This method should be used within a transaction if possible. + * + * @param Criteria $criteria + * @param Connection $con + * @return void + */ + protected static function doOnDeleteSetNull(Criteria $criteria, Connection $con) + { + + // first find the objects that are implicated by the $criteria + $objects = getPhpName() ?>Peer::doSelect($criteria, $con); + foreach($objects as $obj) { + getReferrers() as $fk) { + + // $fk is the foreign key in the other table, so localTableName will + // actually be the table name of other table + $tblFK = $fk->getTable(); + + if (!$tblFK->isForReferenceOnly()) { + // we can't perform operations on tables that are + // not within the schema (i.e. that we have no map for, etc.) + + $fkClassName = $tblFK->getPhpName(); + + // i'm not sure whether we can allow delete setnull for foreign keys + // within the same table? perhaps we can? + if ( $fk->getOnDelete() == ForeignKey::SETNULL && + $fk->getTable()->getName() != $table->getName()) { + + // backwards on purpose + $columnNamesF = $fk->getLocalColumns(); + $columnNamesL = $fk->getForeignColumns(); // should be same num as foreign + ?> + // set fkey col in related rows to NULL + $selectCriteria = new Criteria(self::DATABASE_NAME); + $updateValues = new Criteria(self::DATABASE_NAME); + getColumn($columnNamesF[$x]); + $columnL = $table->getColumn($columnNamesL[$x]); + + ?>$selectCriteria->add(, $obj->getgetPhpName() ?>()); + $updateValues->add(, null); + ::doUpdate($selectCriteria, $updateValues, $con); // use BasePeer because generated Peer doUpdate() methods only update using pkey + + } + } + + + + /** + * Validates all modified columns of given getPhpName()?> object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param getPhpName()?> $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(getPhpName()?> $obj, $cols = null) + { + $columns = array(); + + if ($cols) + { + $dbMap = Propel::getDatabaseMap(self::DATABASE_NAME); + $tableMap = $dbMap->getTable(self::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) + { + if ($tableMap->containsColumn($colName)) + { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } + else + { +getValidators() as $val) { + $col = $val->getColumn(); + if (! $col->isAutoIncrement()) { + $cfc = $col->getPhpName(); +?> + if ($obj->isNew() || $obj->isColumnModified(self::)) + $columns[self::] = $obj->get(); + + } + + return ::doValidate(self::DATABASE_NAME, self::TABLE_NAME, $columns); + } + +isalias */ ?> + +getPrimaryKey()) > 0) { + + if ($table->isAlias()) { + $retrieveMethod = "retrieve" . $table->getPhpName() . "ByPK"; + } else { + $retrieveMethod = "retrieveByPK"; + } + + $pks = $table->getPrimaryKey(); + +if (count($table->getPrimaryKey()) === 1) { ?> + + /** + * Retrieve a single object by pkey or NULL if not found. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return getPhpName() . "\n" ?> + */ + public static function ($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(self::DATABASE_NAME); +getPrimaryKey()) === 1) { + $pkey = $table->getPrimaryKey(); + $col = array_shift($pkey); ?> + $criteria->add(self::, $pk); + + + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values +getPrimaryKey() as $col) { ?> + $criteria->add(self::, $pk[]); + + + $v = getPhpName() ?>Peer::doSelect($criteria, $con); + return count($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function s($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); +getPrimaryKey()) == 1) { ?> + $criteria->add(self::getPrimaryKey(); echo PeerBuilder::getColumnName($k1[0]); ?>, $pks, Criteria::IN); + + + for($k=0,$size=count($pks); $k < $size; $k++) { + $pk = $pks[$k]; + getPrimaryKey() as $col) { ?> + + $c = $criteria->getNewCriterion(self::, $pk[], Criteria::EQUAL); + 0) { ?> + + $c->addAnd($c); + 0 */ + $i++; + } /* foreach */ ?> + + $criteria->addOr($c0); + } + + + $objs = getPhpName() ?>Peer::doSelect($criteria, $con); + } + return $objs; + } + + 1 + +$comma = false; +?> + /** + * Retrieve object using using pk values or NULL if not found. + *getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); + $cptype = $col->getPhpNative(); ?> + * @param $ + + * @param Connection $con + * @return getPhpName() ?> + */ + public static function (getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); ?>, $ +, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); +getPrimaryKey() as $col) { + $clo = strtolower($col->getName()); +?> + $criteria->add(self::, $); + + + $v = getPhpName() ?>Peer::doSelect($criteria, $con); + return count($v) > 0 ? $v[0] : null; + } + + 1 */ + +} /* if pkey > 0 */ ?> + +getPhpName(); + $countFK = count($table->getForeignKeys()); + + if ($countFK >= 1) { + foreach ($table->getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + if (!$tblFK->isForReferenceOnly()) { + // want to cover this other case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) { + $partJoinName = $partJoinName . $column->getPhpName(); + } + } + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if ($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + if ($partJoinName == "") { + $joinColumnId = $joinClassName; + $joinInterface = $interfaceName; + $collThisTable = $className . "s"; + $collThisTableMs = $className; + } else { + $joinColumnId= $joinClassName . "RelatedBy" . $partJoinName; + $joinInterface= $interfaceName . "RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + +// ------------------------------------------------------------ +?> + /** + * Selects a collection of objects pre-filled with their + * objects. + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoin(Criteria $c, $con = null) + { + + // Set the correct dbName if it has not been overridden + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(self::DATABASE_NAME); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol = (self::$numColumns - self::$numLazyLoadColumns) + 1; + Peer::addSelectColumns($c); + + getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); + ?> + $c->addJoin(getPhpName()) ?>, ); + + + $rs = ::doSelect($c, $con); + $results = array(); + + while($rs->next()) { +getChildrenColumn()) { ?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + $cls = Propel::import($omClass); + $obj1 = new $cls(); + $obj1->hydrate($rs); + +getChildrenColumn()) { ?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); + + $cls = Propel::import($omClass); + $obj2 = new $cls(); + $obj2->hydrate($rs, $startcol); + + $newObject = true; + foreach($results as $temp_obj1) { + $temp_obj2 = $temp_obj1->get(); + if ($temp_obj2->getPrimaryKey() === $obj2->getPrimaryKey()) { + $newObject = false; + $temp_obj2->add($obj1); + break; + } + } + if ($newObject) { + $obj2->init(); + $obj2->add($obj1); + } + $results[] = $obj1; + } + return $results; + } + 1 + +// =========================================================== + + if ($countFK >= 2) { + + $includeJoinAll = true; + foreach ($table->getForeignKeys() as $fk) { + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + if ($tblFK->isForReferenceOnly()) { + $includeJoinAll = false; + } + } + + if ($includeJoinAll) { + + // ------------------------------------------------------------------------ + // doSelectJoinAll() + // ------------------------------------------------------------------------ + + //1 ) create the master doSelectJoinAll() method + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $collThisTable = $className . "sRelatedBy" . $relatedByCol; + $collThisTableMs = $className . "RelatedBy" . $relatedByCol; + } +?> + + /** + * Selects a collection of objects pre-filled with + * all related objects. + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoinAll(Criteria $c, $con = null) + { + // Set the correct dbName if it has not been overridden + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(self::DATABASE_NAME); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol2 = (self::$numColumns - self::$numLazyLoadColumns) + 1; +getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $new_index = $index + 1; +?> + Peer::addSelectColumns($c); + $startcol = $startcol + Peer::$numColumns; + getForeignTableName != table->getName + } // foreach [sub] foreign keys + + + foreach ($table->getForeignKeys() as $fk) { + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $lfMap = $fk->getLocalForeignMapping(); + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); +?> + $c->addJoin(getPhpName()) ?>, ); + + + $rs = ::doSelect($c, $con); + $results = array(); + + while($rs->next()) { +getChildrenColumn()) { +?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + + $cls = Propel::import($omClass); + $obj1 = new $cls(); + $obj1->hydrate($rs); + + getForeignKeys() as $fk ) { + + // want to cover this case, but the code is not there yet. + if ( $fk->getForeignTableName() != $table->getName() ) { + + $joinTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + $partJoinName = ""; + foreach ($fk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + + $index++; +?> + + // Add objects for joined rows +getChildrenColumn()) { +?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); +getChildrenColumn() */ +?> + + $cls = Propel::import($omClass); + $obj = new $cls(); + $obj->hydrate($rs, $startcol); + + $newObject = true; + for ($j=0, $resCount=count($results); $j < $resCount; $j++) { + $temp_obj1 = $results[$j]; + $temp_obj = $temp_obj1->get(); + if ($temp_obj->getPrimaryKey() === $obj->getPrimaryKey()) { + $newObject = false; + $temp_obj->add($obj1); + break; + } + } + + if ($newObject) { + $obj->init(); + $obj->add($obj1); + } + getForeignTableName() != $table->getName() + } //foreach foreign key +?> + $results[] = $obj1; + } + return $results; + } +getForeignKeys(); // this sep assignment is necessary otherwise sub-loops over + // getForeignKeys() will cause this to only execute one time. + foreach ($fkeys as $fk ) { + + $tblFK = $table->getDatabase()->getTable($fk->getForeignTableName()); + + $excludeTable = $table->getDatabase()->getTable($fk->getForeignTableName()); + $excludeClassName = $excludeTable->getPhpName(); + + $relatedByCol = ""; + foreach ($fk->getLocalColumns() as $columnName) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $relatedByCol .= $column->getPhpName(); + } + } + + if ($relatedByCol == "") { + $excludeString = $excludeClassName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $excludeString = $excludeClassName . "RelatedBy" . $relatedByCol; + $collThisTable = $className . "sRelatedBy" . $relatedByCol; + $collThisTableMs = $className . "RelatedBy" . $relatedByCol; + } +?> + + /** + * Selects a collection of objects pre-filled with + * all related objects except . + * + * @return array Array of objects. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectJoinAllExcept(Criteria $c, $con = null) + { + // Set the correct dbName if it has not been overridden + // $c->getDbName() will return the same object if not set to another value + // so == check is okay and faster + if ($c->getDbName() == Propel::getDefaultDB()) { + $c->setDbName(self::DATABASE_NAME); + } + + getPhpName() ?>Peer::addSelectColumns($c); + $startcol2 = (self::$numColumns - self::$numLazyLoadColumns) + 1; + getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( !($subfk->getForeignTableName() == $table->getName())) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + + if ($joinClassName != $excludeClassName) { + $new_index = $index + 1; +?> + Peer::addSelectColumns($c); + $startcol = $startcol + Peer::$numColumns; + getForeignKeys() as $subfk) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + if($joinClassName != $excludeClassName) + { + $lfMap = $subfk->getLocalForeignMapping(); + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + $columnFk = $joinTable->getColumn( $lfMap[$columnName]); +?> + $c->addJoin(getPhpName()) ?>, ); + + + + $rs = ::doSelect($c, $con); + $results = array(); + + while($rs->next()) { + getChildrenColumn()) { ?> + $omClass = getPhpName() ?>Peer::getOMClass($rs, 1); + + $omClass = getPhpName() ?>Peer::getOMClass(); + + + $cls = Propel::import($omClass); + $obj1 = new $cls(); + $obj1->hydrate($rs); + + getForeignKeys() as $subfk ) { + // want to cover this case, but the code is not there yet. + if ( $subfk->getForeignTableName() != $table->getName() ) { + + $joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName()); + $joinClassName = $joinTable->getPhpName(); + $interfaceName = $joinTable->getPhpName(); + if($joinTable->getInterface()) { + $interfaceName = $joinTable->getInterface(); + } + + if ($joinClassName != $excludeClassName) { + + $partJoinName = ""; + foreach ($subfk->getLocalColumns() as $columnName ) { + $column = $table->getColumn($columnName); + if ($column->isMultipleFK()) { + $partJoinName .= $column->getPhpName(); + } + } + + if ($partJoinName == "") { + $joinString = $interfaceName; + $collThisTable = "${className}s"; + $collThisTableMs = $className; + } else { + $joinString= $interfaceName."RelatedBy" . $partJoinName; + $collThisTable= $className . "sRelatedBy" . $partJoinName; + $collThisTableMs= $className . "RelatedBy" . $partJoinName; + } + + $index++; + + if ($joinTable->getChildrenColumn()) { +?> + $omClass = Peer::getOMClass($rs, $startcol); + + $omClass = Peer::getOMClass(); +getChildrenColumn() */ +?> + + $cls = Propel::import($omClass); + $obj = new $cls(); + $obj->hydrate($rs, $startcol); + + $newObject = true; + for ($j=0, $resCount=count($results); $j < $resCount; $j++) { + $temp_obj1 = $results[$j]; + $temp_obj = $temp_obj1->get(); + if ($temp_obj->getPrimaryKey() === $obj->getPrimaryKey()) { + $newObject = false; + $temp_obj->add($obj1); + break; + } + } + + if ($newObject) { + $obj->init(); + $obj->add($obj1); + } + getForeignTableName() != $table->getName() + } // foreach +?> + $results[] = $obj1; + } + return $results; + } + 2 + } /* if complex object model */ + + // two extra #end ... + + +//------------------------------------------------------------ + +if (!$table->isAlias()) { +?> + /** + * Returns the TableMap related to this peer. This method is not + * needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + +isalias */ ?> +} + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + getPhpName() ?>Peer::getMapBuilder(); + } catch (Exception $e) { + Propel::log("Could not initialize Peer: " . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'getPhpName() . 'MapBuilder') ?>'; + Propel::registerMapBuilder(getPhpName()?>MapBuilder::CLASS_NAME); +} diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/columns.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/columns.tpl new file mode 100644 index 000000000..345dbafa6 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/columns.tpl @@ -0,0 +1,20 @@ +getColumns() as $col) { + $type = $col->getDomain()->getSqlType(); + if ($type == "INT" || $type == "TEXT") { + $size = ""; + } else { + $size = $col->printSize(); + } + + $default = $col->getDefaultSetting(); + $entry = $col->getName() . ' ' . $type . ' ' . $size . ' ' . $default . ' ' . $col->getNotNullString() . ' ' . $col->getAutoIncrementString(); + + // collapse spaces + $entry = preg_replace('/[\s]+/', ' ', $entry); + + // ' ,' -> ',' + $entry = preg_replace('/[\s]*,[\s]*/', ',', $entry); +?> + , + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/drop.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/drop.tpl new file mode 100644 index 000000000..e597f0622 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/drop.tpl @@ -0,0 +1,42 @@ +getForeignKeys() as $fk) { ?> +IF EXISTS (SELECT 1 FROM sysobjects WHERE type ='RI' AND name='getName() ?>') + ALTER TABLE getName() ?> DROP CONSTRAINT getName()?>; + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'getName() ?>') +BEGIN + DECLARE @reftable_ nvarchar(60), @constraintname_ nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'getName() ?>' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_, @constraintname_ + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_+' drop constraint '+@constraintname_) + FETCH NEXT from refcursor into @reftable_, @constraintname_ + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE getName() ?> + +END + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/foreignkey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/foreignkey.tpl new file mode 100644 index 000000000..0a2d82ed3 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/foreignkey.tpl @@ -0,0 +1,17 @@ +getForeignKeys() as $fk) { ?> + +BEGIN +ALTER TABLE getName() ?> + ADD CONSTRAINT getName() ?> FOREIGN KEY (getLocalColumnNames() ?>) + REFERENCES getForeignTableName() ?> (getForeignColumnNames() ?>) +hasOnUpdate()) { ?> + ON UPDATE getOnUpdate() ?> + +hasOnDelete()) { ?> + ON DELETE getOnDelete() ?> + +END +; + + + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/index.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/index.tpl new file mode 100644 index 000000000..ab54d6073 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/index.tpl @@ -0,0 +1,4 @@ +getIndices() as $index) { ?> +CREATE isUnique()) { ?>UNIQUE INDEX getName() ?> ON getName() ?> (getColumnList()?>); + + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/primarykey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/primarykey.tpl new file mode 100644 index 000000000..ac3b984b4 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/primarykey.tpl @@ -0,0 +1,3 @@ +hasPrimaryKey()) { ?> + CONSTRAINT getName() ?>_PKsss PRIMARY KEY(printPrimaryKey() ?>), + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/table.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/table.tpl new file mode 100644 index 000000000..07262fb94 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/table.tpl @@ -0,0 +1,38 @@ + +/* ---------------------------------------------------------------------- */ +/* getName() ?> */ +/* ---------------------------------------------------------------------- */ + +parse("$basepath/drop.tpl"); ?> +CREATE TABLE getName()?> +( +parse("$basepath/columns.tpl"); + $pk = $g enerator->parse("$basepath/primarykey.tpl"); + + $unique = $generator->parse("$basepath/unique.tpl"); + + if (empty($pk) && empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $cols); + } else { + echo $cols; + } + + if (!empty($pk) && empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $pk); + } else { + echo $pk; + } + + if (!empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $unique); + } +?> +); +parse("$basepath/index.tpl"); + if (!empty($index)) { + echo $index; + } +?> diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/tablefk.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/tablefk.tpl new file mode 100644 index 000000000..98d87e3f5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/tablefk.tpl @@ -0,0 +1,11 @@ + +/* ---------------------------------------------------------------------- */ +/* getName() ?> */ +/* ---------------------------------------------------------------------- */ + +parse("$basepath/foreignkey.tpl"); + if (!empty($fk)) { + echo $fk; + } +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/unique.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/unique.tpl new file mode 100644 index 000000000..10c67be48 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mssql/unique.tpl @@ -0,0 +1,3 @@ +getUnices() as $unique) { ?> + UNIQUE (getColumnList() ?>), + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/columns.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/columns.tpl new file mode 100644 index 000000000..4dcaf4606 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/columns.tpl @@ -0,0 +1,29 @@ +getColumns() as $col) { + if(!$firstIteration): ?>, +getSqlString(); + //using the following code instead of the above line + //for escaping column names: + + $entry = ""; + $entry .= "`" . $col->getName() . "` "; + $entry .= $col->getDomain()->getSqlType(); + if ($col->getPlatform()->hasSize($col->getDomain()->getSqlType())) { + $entry .= $col->getDomain()->printSize(); + } + $entry .= " "; + $entry .= $col->getDefaultSetting() . " "; + $entry .= $col->getNotNullString() . " "; + $entry .= $col->getAutoIncrementString(); + + // collapse spaces + $entry = preg_replace('/[\s]+/', ' ', $entry); + + // ' ,' -> ',' + $entry = preg_replace('/[\s]*,[\s]*/', ',', $entry); +?> + + getDescription()) { ?> COMMENT 'escapeText($col->getDescription()) ?>' += 4.1.x +# It "suspends judgement" for fkey relationships until are tables are set. + +SET FOREIGN_KEY_CHECKS = 0; diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/drop.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/drop.tpl new file mode 100644 index 000000000..4e85e2dc2 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/drop.tpl @@ -0,0 +1 @@ +DROP TABLE IF EXISTS getName() . "`" ?>; diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/foreignkey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/foreignkey.tpl new file mode 100644 index 000000000..256186d77 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/foreignkey.tpl @@ -0,0 +1,86 @@ +getPrimaryKey() as $_primaryKeyColumn) + { + // do the above for primary keys + $_previousColumns[] = "`" . $_primaryKeyColumn->getName() . "`"; + $_indices[] = implode(',', $_previousColumns); + } + $_tableIndices = array_merge($table->getIndices(), $table->getUnices()); + foreach($_tableIndices as $_index) + { + // same procedure, this time for unices and indices + $_previousColumns = array(); + $_indexColumns = $_index->getColumns(); + foreach($_indexColumns as $_indexColumn) + { + $_previousColumns[] = "`" . $_indexColumn . "`"; + $_indices[] = implode(',', $_previousColumns); + } + } + + $_tables = $table->getDatabase()->getTables(); + $counter = 0; + // we're determining which tables have foreign keys that point to this table, since MySQL needs an index on any column that is referenced by another table (yep, MySQL _is_ a PITA) + foreach($_tables as $_table) + { + foreach($_table->getForeignKeys() as $_foreignKey) + { + if($_foreignKey->getForeignTableName() == $table->getName()) + { + $_foreignColumns = array(); + foreach($_foreignKey->getForeignColumns() as $_foreignColumn) + { + $_foreignColumns[] = "`" . $_foreignColumn . "`"; + } + if(!in_array(implode(',', $_foreignColumns), $_indices)) + { + // no matching index defined in the schema, so we have to create one + $counter++; + if($counter > 1): ?>, + INDEX `I_referenced_getName(); ?>_` () 0; + $counter = 0; + foreach ($table->getForeignKeys() as $fk) { + if($counter > 0 || $hasReferencedColumns): ?>,getForeignColumns() as $column) { + $fnames[] = "`" . $column . "`"; + } + + $lnames = array(); + foreach ($fk->getLocalColumns() as $column) { + $lnames[] = "`" . $column . "`"; + } + + $constraintName = "`" . $fk->getName() . "`"; + $indexName = "`" . substr_replace($fk->getName(), 'FI_', strrpos($fk->getName(), 'FK_'), 3) . "`"; + if(!in_array(implode(',', $lnames), $_indices)) + { + // no matching index defined in the schema, so we have to create one. MySQL needs indices on any columns that serve as foreign keys. these are not auto-created prior to 4.1.2 +?> + INDEX (), + CONSTRAINT + FOREIGN KEY () + REFERENCES getForeignTableName() . "`" ?> () +hasOnUpdate()) { ?> + ON UPDATE getOnUpdate(); ?> +hasOnDelete()) { ?> + ON DELETE getOnDelete(); + } +} \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/index.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/index.tpl new file mode 100644 index 000000000..0841b081c --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/index.tpl @@ -0,0 +1,10 @@ +getIndices() as $index ) { + $vendor = $index->getVendorSpecificInfo(); + if(!$firstIteration): ?>, + KEY getName() . "`" ?> (getColumns() as $column) { + $values[] = "`" . $column . "`"; + } + echo implode(',', $values); + ?>)hasPrimaryKey()) { + $values = array(); + foreach ($table->getPrimaryKey() as $column) { + $values[] = "`" . $column->getName() . "`"; + } +?> + PRIMARY KEY()getName() ?> +# ----------------------------------------------------------------------- +parse("$basepath/drop.tpl") ?> + +CREATE TABLE getName() . "`" ?> +( +parse("$basepath/columns.tpl"); + $pk = $generator->parse("$basepath/primarykey.tpl"); + $fk = $generator->parse("$basepath/foreignkey.tpl"); + $unique = $generator->parse("$basepath/unique.tpl"); + $index = $generator->parse("$basepath/index.tpl"); + + $output = array(); + if(!empty($cols)) { + $output[] = $cols; + } + if(!empty($pk)) { + $output[] = $pk; + } + if(!empty($unique)) { + $output[] = $unique; + } + if(!empty($index)) { + $output[] = $index; + } + if(!empty($fk)) { + $output[] = $fk; + } + + echo implode(", ", $output); + +?> +)getVendorSpecificInfo(); + if(isset($vendorSpecific['Type'])) + $mysqlTableType = $vendorSpecific['Type']; + else + $mysqlTableType = 'MyISAM'; + } +?> + +Type= +getDescription()) { ?> COMMENT='escapeText($table->getDescription()) ?>'; diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/tablefk.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/tablefk.tpl new file mode 100644 index 000000000..1a4baf536 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/tablefk.tpl @@ -0,0 +1 @@ + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/unique.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/unique.tpl new file mode 100644 index 000000000..0f0e4088f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/mysql/unique.tpl @@ -0,0 +1,12 @@ +getUnices() as $index ) { + if(!$firstIteration): ?>, + UNIQUE KEY getName() . "`" ?> (getColumns() as $column) { + $values[] = "`" . $column . "`"; + } + echo implode(',', $values); + ?>)getColumns() as $col) { + /* + $type = $col->getSqlType(); + $size = $col->printSize(); + $default = $col->getDefaultSetting(); + + $entry = $col->getName() . " $type $size $default ".$col->getNotNullString(); + */ + $entry = $col->getSqlString(); + + // collapse spaces + $entry = preg_replace('/[\s]+/', ' ', $entry); + + + // ' ,' -> ',' + $entry = preg_replace('/[\s]*,[\s]*/', ',', $entry); +?> + , \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/drop.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/drop.tpl new file mode 100644 index 000000000..f729ae9a9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/drop.tpl @@ -0,0 +1,4 @@ +DROP TABLE getName() ?> CASCADE CONSTRAINTS; +getIdMethod() == "native") { ?> +DROP SEQUENCE getSequenceName() ?>; + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/foreignkey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/foreignkey.tpl new file mode 100644 index 000000000..d1f072d78 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/foreignkey.tpl @@ -0,0 +1,16 @@ +getForeignKeys() as $fk) { ?> +ALTER TABLE getName()?> + ADD CONSTRAINT getName() ?> FOREIGN KEY (getLocalColumnNames()?>) + REFERENCES getForeignTableName()?> (getForeignColumnNames()?>)hasOnDelete()) {?> + ON DELETE getOnDelete(); +}?>; + + + + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/index.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/index.tpl new file mode 100644 index 000000000..cfb450564 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/index.tpl @@ -0,0 +1,3 @@ +getIndices() as $index) { ?> +CREATEisUnique()) { ?> UNIQUE INDEX getName(); ?> ON getName(); ?> (getColumnList(); ?>); + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/primarykey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/primarykey.tpl new file mode 100644 index 000000000..82c7a3bbf --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/primarykey.tpl @@ -0,0 +1,19 @@ +getName(); + $length = strlen($tableName); + if ($length > 27) { + $length = 27; + } +?> +getPrimaryKey()) && count($table->getPrimaryKey()) ) { ?> +ALTER TABLE getName() ?> + + ADD CONSTRAINT _PK +PRIMARY KEY (getPrimaryKey() as $col) { + echo $delim . $col->getName(); + $delim = ","; + } +?>); + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/sequence.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/sequence.tpl new file mode 100644 index 000000000..61b06a80d --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/sequence.tpl @@ -0,0 +1,3 @@ +getIdMethod() == "native") { ?> +CREATE SEQUENCE getSequenceName()?> INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER; + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/table.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/table.tpl new file mode 100644 index 000000000..334425173 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/table.tpl @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------- + getName() ?> + ----------------------------------------------------------------------- */ +parse("$basepath/drop.tpl") ?> +CREATE TABLE getName() ?> +(parse("$basepath/columns.tpl"); + $unique = $generator->parse("$basepath/unique.tpl"); + + if (empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $cols); + } else { + echo $cols; + } + + if (!empty($unique)) { + echo "\n" . preg_replace('/[ ,]+[\s]*$/', '', $unique); + } + +?> +); +parse("$basepath/primarykey.tpl")?> +parse("$basepath/index.tpl")?> +parse("$basepath/sequence.tpl")?> + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/tablefk.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/tablefk.tpl new file mode 100644 index 000000000..98d4ce2a7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/tablefk.tpl @@ -0,0 +1,5 @@ +parse("$basepath/foreignkey.tpl"); + echo $entry; +?> + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/unique.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/unique.tpl new file mode 100644 index 000000000..a28375ea7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/oracle/unique.tpl @@ -0,0 +1,3 @@ +getUnices() as $unique) { ?> + CONSTRAINT getName(); ?> UNIQUE (getColumnList(); ?>), + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/columns.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/columns.tpl new file mode 100644 index 000000000..9d9cce277 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/columns.tpl @@ -0,0 +1,13 @@ +getColumns() as $col) { + $entry = $col->getSqlString(); + + // collapse spaces + $entry = preg_replace('/[\s]+/', ' ', $entry); + + // ' ,' -> ',' + $entry = preg_replace('/[\s]*,[\s]*/', ',', $entry); +?> + , + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/drop.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/drop.tpl new file mode 100644 index 000000000..229181d83 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/drop.tpl @@ -0,0 +1,4 @@ +DROP TABLE getName() ?> CASCADE; +getIdMethod() == "native") { ?> +DROP SEQUENCE getSequenceName() ?>; + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/foreignkey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/foreignkey.tpl new file mode 100644 index 000000000..3a7d220bb --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/foreignkey.tpl @@ -0,0 +1,20 @@ +getForeignKeys() as $fk) { ?> +ALTER TABLE getName() ?> + ADD CONSTRAINT getName() ?> FOREIGN KEY (getLocalColumnNames() ?>) + REFERENCES getForeignTableName() ?> (getForeignColumnNames() ?>) +hasOnUpdate()) { ?> + ON UPDATE getOnUpdate() ?> + +hasOnDelete()) { ?> + ON DELETE getOnDelete() ?> + +; + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/index.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/index.tpl new file mode 100644 index 000000000..30c00e79c --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/index.tpl @@ -0,0 +1,3 @@ +getIndices() as $index) { ?> +CREATE getIsUnique()) { ?>UNIQUE INDEX getName() ?> ON getName() ?> (getColumnList()?>); + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/primarykey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/primarykey.tpl new file mode 100644 index 000000000..9992a84d9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/primarykey.tpl @@ -0,0 +1,3 @@ +hasPrimaryKey()) { ?> + PRIMARY KEY (printPrimaryKey() ?>), + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/sequence.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/sequence.tpl new file mode 100644 index 000000000..dc3686af7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/sequence.tpl @@ -0,0 +1,3 @@ +getIdMethod() == "native") { ?> +CREATE SEQUENCE getSequenceName() ?>; + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/table.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/table.tpl new file mode 100644 index 000000000..34cb98098 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/table.tpl @@ -0,0 +1,55 @@ + +----------------------------------------------------------------------------- +-- getName() ?> +----------------------------------------------------------------------------- +parse("$basepath/drop.tpl"); +$sequence = $generator->parse("$basepath/sequence.tpl"); +if (!empty($sequence)) { + echo $sequence; +} +?> + +CREATE TABLE getName() ?> +( + parse("$basepath/columns.tpl"); + $pk = trim($generator->parse("$basepath/primarykey.tpl")); + $unique = $generator->parse("$basepath/unique.tpl"); + $index = trim($generator->parse("$basepath/index.tpl")); + + if ( empty($pk) && empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $cols); + } else { + echo $cols; + } + + if (empty($unique) && !empty($pk)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $pk); + } else { + echo $pk; + } + + if (!empty($unique)) { + echo preg_replace('/[ ,]+[\s]*$/', '', $unique); + } +?> +); + + +COMMENT ON TABLE getName() ?> IS 'escapeText($table->getDescription()) ?>'; + +getColumns() as $col) { + if( $col->getDescription() != '' ) { +?> +COMMENT ON COLUMN getName() ?>.getName() ?> IS 'escapeText($col->getDescription()) ?>'; + + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/tablefk.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/tablefk.tpl new file mode 100644 index 000000000..bcb5803c9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/tablefk.tpl @@ -0,0 +1,14 @@ + +---------------------------------------------------------------------- +-- getName() ?> +---------------------------------------------------------------------- + +put("table", $tablefk); +$fk = $generator->parse("$basepath/foreignkey.tpl"); +if ($fk != "") { + echo $fk; +} +?> diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/unique.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/unique.tpl new file mode 100644 index 000000000..59cb0e48a --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/pgsql/unique.tpl @@ -0,0 +1,3 @@ +getUnices() as $unique ) { ?> + CONSTRAINT getName() ?> UNIQUE (getColumnList() ?>), + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/columns.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/columns.tpl new file mode 100644 index 000000000..51cbcc390 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/columns.tpl @@ -0,0 +1,13 @@ +getColumns() as $col) { + $entry = $col->getSqlString(); + + // collapse spaces + $entry = preg_replace('/[\s]+/', ' ', $entry); + + // ' ,' -> ',' + $entry = preg_replace('/[\s]*,[\s]*/', ',', $entry); +?> + , + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/drop.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/drop.tpl new file mode 100644 index 000000000..50daffa12 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/drop.tpl @@ -0,0 +1 @@ +drop table getName() ?>; diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/foreignkey.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/foreignkey.tpl new file mode 100644 index 000000000..569b086bf --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/foreignkey.tpl @@ -0,0 +1,4 @@ +getForeignKeys() as $fk) { ?> + -- SQLite does not support foreign keys; this is just for reference + -- FOREIGN KEY (getLocalColumnNames()?>) REFERENCES getForeignTableName() ?> (getForeignColumnNames() ?>), + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/index.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/index.tpl new file mode 100644 index 000000000..17bf22afc --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/index.tpl @@ -0,0 +1,3 @@ +getIndices() as $index ) { ?> + CREATE INDEX getName()?> ON getName() ?> (getColumnList() ?>); + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/table.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/table.tpl new file mode 100644 index 000000000..bd7af651e --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/table.tpl @@ -0,0 +1,33 @@ +-- ----------------------------------------------------------------------- +-- getName() ?> +-- ----------------------------------------------------------------------- +parse("$basepath/drop.tpl") ?> + +CREATE TABLE getName() ?> +( +parse("$basepath/columns.tpl"); + $fk = $generator->parse("$basepath/foreignkey.tpl"); + $unique = $generator->parse("$basepath/unique.tpl"); + $index = $generator->parse("$basepath/index.tpl"); + + if (empty($unique)) { + echo preg_replace('/[,]+\s*$/', '', $cols); + } else { + echo $cols; + echo preg_replace('/[,]+\s*$/', '', $unique); + } + +?> +); + + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/tablefk.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/tablefk.tpl new file mode 100644 index 000000000..92c1a7a42 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/tablefk.tpl @@ -0,0 +1 @@ + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/unique.tpl b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/unique.tpl new file mode 100644 index 000000000..5e6127add --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/base/sqlite/unique.tpl @@ -0,0 +1,3 @@ +getUnices() as $unique) { ?> + UNIQUE (getColumnList() ?>), + \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/Control.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/Control.tpl new file mode 100644 index 000000000..a4d2e81b5 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/Control.tpl @@ -0,0 +1,13 @@ +getDatabases() as $db) { + $databaseNames[] = $db->getName(); + } + } + $databaseNames = array_unique($databaseNames); + + $generator->put("databaseNames", $databaseNames); + $generator->display("sql/db-init/$targetDatabase/createdb.tpl"); +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/unix.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/unix.tpl new file mode 100644 index 000000000..f74340668 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/unix.tpl @@ -0,0 +1,6 @@ +#!/bin/sh + +#foreach ($databaseModel in $appData.Databases) +dropdb $databaseModel.Name +createdb $databaseModel.Name +#end diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/windows.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/windows.tpl new file mode 100644 index 000000000..0148ae2e9 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mssql/windows.tpl @@ -0,0 +1 @@ +ECHO Not implemented diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/mysql/createdb.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mysql/createdb.tpl new file mode 100644 index 000000000..a29bd0d33 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/mysql/createdb.tpl @@ -0,0 +1,4 @@ + +drop database if exists ; +create database ; + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/oracle/createdb.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/oracle/createdb.tpl new file mode 100644 index 000000000..174843acc --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/oracle/createdb.tpl @@ -0,0 +1,4 @@ +-- foreach ($databaseName in $databaseNames) +-- drop database $databaseName; +-- create database $databaseName; +-- end diff --git a/gulliver/thirdparty/propel-generator/templates/sql/db-init/pgsql/createdb.tpl b/gulliver/thirdparty/propel-generator/templates/sql/db-init/pgsql/createdb.tpl new file mode 100644 index 000000000..dc4f54f26 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/db-init/pgsql/createdb.tpl @@ -0,0 +1,4 @@ + +drop database ; +create database ; + diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/row.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/row.tpl new file mode 100644 index 000000000..f7d8f159f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/row.tpl @@ -0,0 +1,14 @@ +INSERT INTO getTable()->getName() ?> (getColumnValues() as $col) { + print $comma; + print $col->getColumn()->getName(); + $comma = ','; +}?>) VALUES (getColumnValues() as $col) { + print $comma; + $generator->put("column", $col); + $generator->display("sql/load/mssql/val.tpl"); + $comma=','; + }?>); diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/val.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/val.tpl new file mode 100644 index 000000000..71741551f --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/mssql/val.tpl @@ -0,0 +1,9 @@ +getColumn()->getPropelType(), array('VARCHAR', 'LONGVARCHAR', 'DATE','CHAR'))) { + echo "'" . str_replace("'", "''", $column->getValue()). "'"; + } else { + echo $column->getValue(); + } + +?> diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/row.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/row.tpl new file mode 100644 index 000000000..4e48056a1 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/row.tpl @@ -0,0 +1,14 @@ +INSERT INTO getTable()->getName() . "`" ?> (getColumnValues() as $col) { + print $comma; + print "`" . $col->getColumn()->getName() . "`"; + $comma = ','; +}?>) VALUES (getColumnValues() as $col) { + print $comma; + $generator->put("column", $col); + $generator->display("sql/load/mysql/val.tpl"); + $comma=','; +}?>); diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/val.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/val.tpl new file mode 100644 index 000000000..fed160b21 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/mysql/val.tpl @@ -0,0 +1,7 @@ +getColumn()->getPropelType(), array('VARCHAR', 'LONGVARCHAR', 'DATE', 'DATETIME','CHAR'))) { + print "'" . mysql_escape_string($column->getValue()) . "'"; +} else { + print $column->getValue(); +} +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/row.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/row.tpl new file mode 100644 index 000000000..d5c209810 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/row.tpl @@ -0,0 +1,14 @@ +INSERT INTO getTable()->getName() ?> (getColumnValues() as $col) { + print $comma; + print $col->getColumn()->getName(); + $comma = ','; +}?>) VALUES (getColumnValues() as $col) { + print $comma; + $generator->put("column", $col); + $generator->display("sql/load/oracle/val.tpl"); + $comma=','; + }?>); diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/val.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/val.tpl new file mode 100644 index 000000000..476257555 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/oracle/val.tpl @@ -0,0 +1,9 @@ +getColumn()->getPropelType(), array('VARCHAR', 'LONGVARCHAR', 'DATE','CHAR'))) { + echo "'" . $column->getValue() . "'"; + } else { + echo $column->getValue(); + } + +?> diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/row.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/row.tpl new file mode 100644 index 000000000..3a65a50b7 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/row.tpl @@ -0,0 +1,14 @@ +INSERT INTO getTable()->getName() ?> (getColumnValues() as $col) { + print $comma; + print $col->getColumn()->getName(); + $comma = ','; +}?>) VALUES (getColumnValues() as $col) { + print $comma; + $generator->put("column", $col); + $generator->display("sql/load/pgsql/val.tpl"); + $comma=','; + }?>); diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/val.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/val.tpl new file mode 100644 index 000000000..11b656b59 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/pgsql/val.tpl @@ -0,0 +1,11 @@ +getColumn()->getPropelType(), array('VARCHAR', 'LONGVARCHAR', 'DATE','CHAR', 'TIMESTAMP'))) { + echo "'" . pg_escape_string($column->getValue()) . "'"; + } elseif ($column->getColumn()->getPropelType() == 'BOOLEAN') { + echo ($column->getValue() == 1 || $column->getValue() == 't' ? "'t'" : "'f'"); + } else { + echo $column->getValue(); + } + +?> diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/row.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/row.tpl new file mode 100644 index 000000000..8a6e91c28 --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/row.tpl @@ -0,0 +1,14 @@ +INSERT INTO getTable()->getName() ?> (getColumnValues() as $col) { + print $comma; + print $col->getColumn()->getName(); + $comma = ','; +}?>) VALUES (getColumnValues() as $col) { + print $comma; + $generator->put("column", $col); + $generator->display("sql/load/sqlite/val.tpl"); + $comma=','; + }?>); diff --git a/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/val.tpl b/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/val.tpl new file mode 100644 index 000000000..6fc1f7b9c --- /dev/null +++ b/gulliver/thirdparty/propel-generator/templates/sql/load/sqlite/val.tpl @@ -0,0 +1,4 @@ +getValue()) . "'"; +?> \ No newline at end of file diff --git a/gulliver/thirdparty/propel/Propel.php b/gulliver/thirdparty/propel/Propel.php new file mode 100644 index 000000000..945872e86 --- /dev/null +++ b/gulliver/thirdparty/propel/Propel.php @@ -0,0 +1,600 @@ +. + */ + +include_once 'propel/PropelException.php'; +include_once 'adapter/DBAdapter.php'; + +/** + * Propel's main resource pool and initialization & configuration class. + * + * This static class is used to handle Propel initialization and to maintain all of the + * open database connections and instantiated database maps. + * + * @author Hans Lellelid (Propel) + * @author Daniel Rall (Torque) + * @author Magnús Þór Torfason (Torque) + * @author Jason van Zyl (Torque) + * @author Rafal Krzewski (Torque) + * @author Martin Poeschl (Torque) + * @author Henning P. Schmiedehausen (Torque) + * @author Kurt Schrader (Torque) + * @version $Revision: 601 $ + * @package propel + */ +class Propel { + + /** + * A constant for default. + */ + const DEFAULT_NAME = "default"; + + /** + * A constant defining 'System is unusuable' logging level + */ + const LOG_EMERG = 0; + + /** + * A constant defining 'Immediate action required' logging level + */ + const LOG_ALERT = 1; + + /** + * A constant defining 'Critical conditions' logging level + */ + const LOG_CRIT = 2; + + /** + * A constant defining 'Error conditions' logging level + */ + const LOG_ERR = 3; + + /** + * A constant defining 'Warning conditions' logging level + */ + const LOG_WARNING = 4; + + /** + * A constant defining 'Normal but significant' logging level + */ + const LOG_NOTICE = 5; + + /** + * A constant defining 'Informational' logging level + */ + const LOG_INFO = 6; + + /** + * A constant defining 'Debug-level messages' logging level + */ + const LOG_DEBUG = 7; + + /** + * The Propel version. + */ + const VERSION = '1.2.1'; + + /** + * The db name that is specified as the default in the property file + */ + private static $defaultDBName; + + /** + * The global cache of database maps + */ + private static $dbMaps = array(); + + /** + * The cache of DB adapter keys + */ + private static $adapterMap; + + /** + * The logging category. + */ + private static $category; + + /** + * Propel-specific configuration. + */ + private static $configuration; + + /** + * flag to set to true once this class has been initialized + */ + private static $isInit = false; + + /** + * @var Log + */ + private static $logger = null; + + /** + * Store mapbuilder classnames for peers that have been referenced prior + * to Propel being initialized. This can happen if the OM Peer classes are + * included before the Propel::init() method has been called. + */ + private static $mapBuilders = array(); + + /** + * Cache of established connections (to eliminate overhead). + * @var array + */ + private static $connectionMap = array(); + + /** + * initialize Propel + * @return void + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function initialize() { + + if (self::$configuration === null) { + throw new PropelException("Propel cannot be initialized without " + . "a valid configuration. Please check the log files " + . "for further details."); + } + + self::configureLogging(); + // Now that we have dealt with processing the log properties + // that may be contained in the configuration we will make the + // configuration consist only of the remaining propel-specific + // properties that are contained in the configuration. First + // look for properties that are in the "propel" namespace. + + + $originalConf = self::$configuration; + self::$configuration = isset(self::$configuration['propel']) ? self::$configuration['propel'] : null; + + if (empty(self::$configuration)) { + // Assume the original configuration already had any + // prefixes stripped. + self::$configuration = $originalConf; + } + + + // reset the connection map (this should enable runtime changes of connection params) + self::$connectionMap = array(); + self::initAdapters(self::$configuration); + + self::$isInit = true; + + // map builders may be registered w/ Propel before Propel has + // been initialized; in this case they are stored in a static + // var of this class & now can be propertly initialized. + foreach(self::$mapBuilders as $mbClass) { + BasePeer::getMapBuilder($mbClass); + } + + // now that the pre-loaded map builders have been propertly initialized + // empty the array. + // any further mapBuilders will be build by the generated MapBuilder classes. + self::$mapBuilders = array(); + } + + /** + * Setup the adapters needed. An adapter must be defined for each database connection. + * Generally the adapter will be the same as the PEAR phpname; e.g. for MySQL, use the + * 'mysql' adapter. + * @param array $configuration the Configuration representing the properties file + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + private static function initAdapters($configuration) { + + self::$adapterMap = array(); + + $c = isset($configuration['datasources']) ? $configuration['datasources'] : null; + if (!empty($c)) { + try { + foreach($c as $handle => $properties) { + if (is_array($properties) && isset($properties['adapter'])) { + $db = DBAdapter::factory($properties['adapter']); + // register the adapter for this name + self::$adapterMap[$handle] = $db; + } + } + } catch (Exception $e) { + throw new PropelException("Unable to initialize adapters.", $e); + } + } else { + self::log("There were no adapters in the configuration.", self::LOG_WARNING); + } + } + + /** + * configure propel + * + * @param string $config Path (absolute or relative to include_path) to config file. + * @return void + * @throws PropelException If configuration file cannot be opened. (E_WARNING probably will also be raised in PHP) + */ + public static function krumo() + { + krumo ( self::$configuration); + } + + + public static function configure($configFile) + { + self::$configuration = include($configFile); + if (self::$configuration === false) { + throw new PropelException("Unable to open configuration file: " . var_export($configFile, true)); + } + //include($configFile ); + } + + /** + * Initialization of Propel with a properties file. + * + * @param string $c The Propel configuration file path. + * @return void + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function init($c) + { + self::configure($c); + self::initialize(); + } + + /** + * Determine whether Propel has already been initialized. + * + * @return boolean True if Propel is already initialized. + */ + public static function isInit() + { + return self::$isInit; + } + + /** + * Sets the configuration for Propel and all dependencies. + * + * @param array $c the Configuration + * @return void + */ + public static function setConfiguration($c) + { + self::$configuration = $c; + } + + /** + * Get the configuration for this component. + * + * @return the Configuration + */ + public static function getConfiguration() + { + return self::$configuration; + } + + /** + * Configure the logging for this subsystem. + * The logging system is only configured if there is a 'log' + * section in the passed-in runtime configuration. + * @return void + */ + protected static function configureLogging() { + if (self::$logger === null) { + if (isset(self::$configuration['log']) && is_array(self::$configuration['log']) && count(self::$configuration['log'])) { + include_once 'Log.php'; // PEAR Log class + $c = self::$configuration['log']; + // array casting handles bug in PHP5b2 where the isset() checks + // below may return true if $c is not an array (e.g. is a string) + + $type = isset($c['type']) ? $c['type'] : 'file'; + $name = isset($c['name']) ? $c['name'] : './propel.log'; + $ident = isset($c['ident']) ? $c['ident'] : 'propel'; + $conf = isset($c['conf']) ? $c['conf'] : array(); + $level = isset($c['level']) ? $c['level'] : PEAR_LOG_DEBUG; + + self::$logger = Log::singleton($type, $name, $ident, $conf, $level); + } // if isset() + } + } + + /** + * Override the configured logger. + * + * This is primarily for things like unit tests / debugging where + * you want to change the logger without altering the configuration file. + * + * You can use any logger class that implements the propel.logger.BasicLogger + * interface. This interface is based on PEAR::Log, so you can also simply pass + * a PEAR::Log object to this method. + * + * @param object $logger The new logger to use. ([PEAR] Log or BasicLogger) + * @return void + */ + public static function setLogger($logger) + { + self::$logger = $logger; + } + + /** + * Returns true if a logger, for example PEAR::Log, has been configured, + * otherwise false. + * + * @return boolean True if Propel uses logging + */ + public static function hasLogger() + { + return self::$logger !== null; + } + + /** + * Get the configured logger. + * @return object Configured log class ([PEAR] Log or BasicLogger). + */ + public static function logger() + { + return self::$logger; + } + + /** + * Logs a message + * If a logger has been configured, the logger will be used, otherwrise the + * logging message will be discarded without any further action + * + * @param string $message The message that will be logged. + * @param string $level The logging level. + * @return boolean True if the message was logged successfully or no logger was used. + */ + public static function log($message, $level = self::LOG_DEBUG) + { + if(self::hasLogger()) + { + $logger = self::logger(); + switch($level) + { + case self::LOG_EMERG: + return $logger->log($message, $level); + case self::LOG_ALERT: + return $logger->alert($message); + case self::LOG_CRIT: + return $logger->crit($message); + case self::LOG_ERR: + return $logger->err($message); + case self::LOG_WARNING: + return $logger->warning($message); + case self::LOG_NOTICE: + return $logger->notice($message); + case self::LOG_INFO: + return $logger->info($message); + default: + return $logger->debug($message); + } + } + return true; + } + + /** + * Returns the database map information. Name relates to the name + * of the connection pool to associate with the map. + * + * The database maps are "registered" by the generated map builder classes. + * + * @param string $name The name of the database corresponding to the DatabaseMapto retrieve. + * @return DatabaseMap The named DatabaseMap. + * @throws PropelException - if database map is null or propel was not initialized properly. + */ + public static function getDatabaseMap($name = null) { + + if ($name === null) { + $name = self::getDefaultDB(); + if ($name === null) { + throw new PropelException("DatabaseMap name was null!"); + } + } + + // CACHEHOOK - this would be a good place + // to add shared memory caching options (database + // maps should be a pretty safe candidate for shared mem caching) + + if (isset(self::$dbMaps[$name])) { + $map = self::$dbMaps[$name]; + } else { + $map = self::initDatabaseMap($name); + } + + return $map; + } + + /** + * Creates and initializes the mape for the named database. + * + * The database maps are "registered" by the generated map builder classes + * by calling this method and then adding the tables, etc. to teh DatabaseMap + * object returned from this method. + * + * @param string $name The name of the database to map. + * @return DatabaseMap The desired map. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + private static function initDatabaseMap($name) + { + $map = new DatabaseMap($name); + self::$dbMaps[$name] = $map; + return $map; + } + + /** + * Register a MapBuilder + * + * @param string $className the MapBuilder + */ + public static function registerMapBuilder($className) + { + self::$mapBuilders[] = $className; + } + + /** + * Returns the specified property of the given database, or the empty + * string if no value is set for the property. + * + * @param string $db The name of the database whose property to get. + * @param string $prop The name of the property to get. + * @return mixed The property's value. + */ + private static function getDatabaseProperty($db, $prop) + { + return isset(self::$configuration['datasources'][$db][$prop]) ? self::$configuration['datasources'][$db][$prop] : null; + } + + /** + * + * @param string $name The database name. + * @return Connection A database connection + * @throws PropelException - if no conneciton params, or SQLException caught when trying to connect. + */ + public static function getConnection($name = null) { + if ($name === null) { + $name = self::getDefaultDB(); + } + $con = isset(self::$connectionMap[$name]) ? self::$connectionMap[$name] : null; + if ($con === null || $name === 'dbarray') { + + $dsn = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; + if ($dsn === null) { + if(isset($_SESSION['PROCESS'])) { + /** Added By Erik Amaru loadAdditionalConnections(); + $dsn = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; + } else { + throw new PropelException("No connection params set for " . $name); + } + } + + include_once 'creole/Creole.php'; + // if specified, use custom driver + if (isset(self::$configuration['datasources'][$name]['driver'])) { + Creole::registerDriver($dsn['phptype'], self::$configuration['datasources'][$name]['driver']); + } + + try { + $con = Creole::getConnection($dsn); + } catch (SQLException $e) { + throw new PropelException($e); + } + self::$connectionMap[$name] = $con; + } + return $con; + } + + /** + * Returns database adapter for a specific connection pool. + * + * @param string $name A database name. + * @return DBAdapter The corresponding database adapter. + * @throws PropelException - if unable to find DBdapter for specified db. + */ + public static function getDB($name = null) + { + if ($name === null) { + $name = self::getDefaultDB(); + } + if (!isset(self::$adapterMap[$name])) { + //throw new PropelException("Unable to load DBAdapter for database '" . var_export($name, true) . "' (check your runtime properties file!)"); + throw new PropelException("Unable to load DBAdapter for database '' (check your runtime properties file!)"); + } + return self::$adapterMap[$name]; + } + + /** + * Returns the name of the default database. + * + * @return string Name of the default DB + */ + public static function getDefaultDB() + { + if (self::$configuration === null) { + return self::DEFAULT_NAME; + } elseif (self::$defaultDBName === null) { + // Determine default database name. + self::$defaultDBName = isset(self::$configuration['datasources']['default']) ? self::$configuration['datasources']['default'] : self::DEFAULT_NAME; + } + return self::$defaultDBName; + } + + /** + * Include once a file specified in DOT notation and reutrn unqualified clasname. + * + * Package notation is expected to be relative to a location + * on the PHP include_path. The dot-path classes are used as a way + * to represent both classname and filesystem location; there is + * an inherent assumption about filenaming. To get around these + * naming requirements you can include the class yourself + * and then just use the classname instead of dot-path. + * + * @param string $class dot-path to clas (e.g. path.to.my.ClassName). + * @return string unqualified classname + */ + public static function import($path) { + + // extract classname + if (($pos = strrpos($path, '.')) === false) { + $class = $path; + } else { + $class = substr($path, $pos + 1); + } + + // check if class exists + if (class_exists($class, false)) { + return $class; + } + + // turn to filesystem path + $path = strtr($path, '.', DIRECTORY_SEPARATOR) . '.php'; + + // include class + $ret = include_once($path); + if ($ret === false) { + throw new PropelException("Unable to import class: " . $class . " from " . $path); + } + + // return qualified name + return $class; + } + + /** + * Closes any associated resource handles. + * + * This method frees any database connection handles that have been + * opened by the getConnection() method. + * + * @return void + */ + public static function close() + { + foreach(self::$connectionMap as $conn) { + $conn->close(); + } + } + +} diff --git a/gulliver/thirdparty/propel/PropelException.php b/gulliver/thirdparty/propel/PropelException.php new file mode 100644 index 000000000..0642adc0d --- /dev/null +++ b/gulliver/thirdparty/propel/PropelException.php @@ -0,0 +1,61 @@ +. + */ + +/** + * The base class of all exceptions thrown by Propel. + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel + */ +class PropelException extends Exception { + + /** The nested "cause" exception. */ + protected $cause; + + function __construct($p1, $p2 = null) { + + $cause = null; + + if ($p2 !== null) { + $msg = $p1; + $cause = $p2; + } else { + if ($p1 instanceof Exception) { + $msg = ""; + $cause = $p1; + } else { + $msg = $p1; + } + } + + parent::__construct($msg); + + if ($cause !== null) { + $this->cause = $cause; + $this->message .= " [wrapped: " . $cause->getMessage() ."]"; + } + } + + function getCause() { + return $this->cause; + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBAdapter.php b/gulliver/thirdparty/propel/adapter/DBAdapter.php new file mode 100644 index 000000000..4f42a4486 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBAdapter.php @@ -0,0 +1,185 @@ +. + */ + +include_once 'creole/Connection.php'; + +/** + * DBAdapter
    defines the interface for a Propel database adapter. + * + *

    Support for new databases is added by subclassing + * DBAdapter and implementing its abstract interface, and by + * registering the new database adapter and corresponding Creole + * driver in the private adapters map (array) in this class.

    + * + *

    The Propel database adapters exist to present a uniform + * interface to database access across all available databases. Once + * the necessary adapters have been written and configured, + * transparent swapping of databases is theoretically supported with + * zero code change and minimal configuration file + * modifications.

    + * + * @author Hans Lellelid (Propel) + * @author Jon S. Stevens (Torque) + * @author Brett McLaughlin (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +abstract class DBAdapter { + + /** + * Creole driver to Propel adapter map. + * @var array + */ + private static $adapters = array( + 'mysql' => 'DBMySQL', + 'mysqli' => 'DBMySQLi', + 'mssql' => 'DBMSSQL', + 'sybase' => 'DBSybase', + 'oracle' => 'DBOracle', + 'pgsql' => 'DBPostgres', + 'sqlite' => 'DBSQLite', + 'dbarray' => 'DBArray', + '' => 'DBNone', + ); + + /** + * Creates a new instance of the database adapter associated + * with the specified Creole driver. + * + * @param string $driver The name of the Propel/Creole driver to + * create a new adapter instance for or a shorter form adapter key. + * @return DBAdapter An instance of a Propel database adapter. + * @throws PropelException if the adapter could not be instantiated. + */ + public static function factory($driver) { + $adapterClass = isset(self::$adapters[$driver]) ? self::$adapters[$driver] : null; + if ($adapterClass !== null) { + require_once 'propel/adapter/'.$adapterClass.'.php'; + $a = new $adapterClass(); + return $a; + } else { + throw new PropelException("Unsupported Propel driver: " . $driver . ": Check your configuration file"); + } + } + + /** + * This method is used to ignore case. + * + * @param in The string to transform to upper case. + * @return string The upper case string. + */ + public abstract function toUpperCase($in); + + /** + * Returns the character used to indicate the beginning and end of + * a piece of text used in a SQL statement (generally a single + * quote). + * + * @return string The text delimeter. + */ + public function getStringDelimiter() + { + return '\''; + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @return void + * @throws SQLException No Statement could be created or executed. + */ + public abstract function lockTable(Connection $con, $table); + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @return void + * @throws SQLException No Statement could be created or executed. + */ + public abstract function unlockTable(Connection $con, $table); + + /** + * This method is used to ignore case. + * + * @param string $in The string whose case to ignore. + * @return string The string in a case that can be ignored. + */ + public abstract function ignoreCase($in); + + /** + * This method is used to ignore case in an ORDER BY clause. + * Usually it is the same as ignoreCase, but some databases + * (Interbase for example) does not use the same SQL in ORDER BY + * and other clauses. + * + * @param string $in The string whose case to ignore. + * @return string The string in a case that can be ignored. + */ + public function ignoreCaseInOrderBy($in) + { + return $this->ignoreCase($in); + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public abstract function concatString($s1, $s2); + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public abstract function subString($s, $pos, $len); + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public abstract function strLength($s); + + + /** + * Quotes database objec identifiers (table names, col names, sequences, etc.). + * @param string $text The identifier to quote. + * @return string The quoted identifier. + */ + public function quoteIdentifier($text) + { + return '"' . $text . '"'; + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBArray.php b/gulliver/thirdparty/propel/adapter/DBArray.php new file mode 100644 index 000000000..36f2028c5 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBArray.php @@ -0,0 +1,114 @@ +createStatement(); + $sql = "LOCK TABLE " . $table . " WRITE"; + $statement->executeUpdate($sql); + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException No Statement could be created or + * executed. + */ + public function unlockTable(Connection $con, $table) + { + $statement = $con->createStatement(); + $statement->executeUpdate("UNLOCK TABLES"); + } + + /** + * @see DBAdapter::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '`' . $text . '`'; + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBMSSQL.php b/gulliver/thirdparty/propel/adapter/DBMSSQL.php new file mode 100644 index 000000000..0d32ac635 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBMSSQL.php @@ -0,0 +1,36 @@ +. + */ + +require_once 'propel/adapter/DBSybase.php'; + +/** + * This is used to connect to a MSSQL database. For now, this class + * simply extends the adaptor for Sybase. + * + * @author Hans Lellelid (Propel) + * @author Gonzalo Diethelm (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBMSSQL extends DBSybase { + // no difference currently +} diff --git a/gulliver/thirdparty/propel/adapter/DBMySQL.php b/gulliver/thirdparty/propel/adapter/DBMySQL.php new file mode 100644 index 000000000..528b6c39a --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBMySQL.php @@ -0,0 +1,133 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * This is used in order to connect to a MySQL database. + * + * @author Hans Lellelid (Propel) + * @author Jon S. Stevens (Torque) + * @author Brett McLaughlin (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBMySQL extends DBAdapter { + + /** + * This method is used to ignore case. + * + * @param in The string to transform to upper case. + * @return The upper case string. + */ + public function toUpperCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * This method is used to ignore case. + * + * @param in The string whose case to ignore. + * @return The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return "CONCAT($s1, $s2)"; + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return "SUBSTRING($s, $pos, $len)"; + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return "CHAR_LENGTH($s)"; + } + + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @throws SQLException No Statement could be created or + * executed. + */ + public function lockTable(Connection $con, $table) + { + $statement = $con->createStatement(); + $sql = "LOCK TABLE " . $table . " WRITE"; + $statement->executeUpdate($sql); + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException No Statement could be created or + * executed. + */ + public function unlockTable(Connection $con, $table) + { + $statement = $con->createStatement(); + $statement->executeUpdate("UNLOCK TABLES"); + } + + /** + * @see DBAdapter::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '`' . $text . '`'; + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBMySQLi.php b/gulliver/thirdparty/propel/adapter/DBMySQLi.php new file mode 100644 index 000000000..93c4baad3 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBMySQLi.php @@ -0,0 +1,34 @@ +. + */ + +require_once 'propel/adapter/DBMySQL.php'; + +/** + * This is used in order to connect to a MySQL database using the new mysqli API. + * + * @author Hans Lellelid (Propel) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBMySQLi extends DBMySQL { + +} diff --git a/gulliver/thirdparty/propel/adapter/DBNone.php b/gulliver/thirdparty/propel/adapter/DBNone.php new file mode 100644 index 000000000..322e12374 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBNone.php @@ -0,0 +1,131 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * This DatabaseHandler is used when you do not have a database + * installed. + * + * @author Hans Lellelid (Propel) + * @author Jon S. Stevens (Torque) + * @author Brett McLaughlin (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBNone extends DBAdapter { + + /** + * @return null + */ + public function getConnection() + { + return null; + } + + /** + * @see DBAdapter::init() + */ + public function init($url, $username, $password) + { + } + + /** + * This method is used to ignore case. + * + * @param in The string to transform to upper case. + * @return The upper case string. + */ + public function toUpperCase($in) + { + return $in; + } + + /** + * This method is used to ignore case. + * + * @param in The string whose case to ignore. + * @return The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return $in; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return ($s1 . $s2); + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return substr($s, $pos, $len); + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return strlen($s); + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @throws SQLException No Statement could be created or executed. + */ + public function lockTable(Connection $con, $table) + { + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException No Statement could be created or executed. + */ + public function unlockTable(Connection $con, $table) + { + } +} diff --git a/gulliver/thirdparty/propel/adapter/DBOracle.php b/gulliver/thirdparty/propel/adapter/DBOracle.php new file mode 100644 index 000000000..0f1c54d0e --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBOracle.php @@ -0,0 +1,123 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * Oracle adapter. + * + * @author David Giffin (Propel) + * @author Hans Lellelid (Propel) + * @author Jon S. Stevens (Torque) + * @author Brett McLaughlin (Torque) + * @author Bill Schneider (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBOracle extends DBAdapter { + + /** + * This method is used to ignore case. + * + * @param string $in The string to transform to upper case. + * @return string The upper case string. + */ + public function toUpperCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * This method is used to ignore case. + * + * @param string $in The string whose case to ignore. + * @return string The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return "CONCAT($s1, $s2)"; + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return "SUBSTR($s, $pos, $len)"; + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return "LENGTH($s)"; + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @throws SQLException No Statement could be created or executed. + */ + public function lockTable(Connection $con, $table) + { + $statement = $con->createStatement(); + $statement->executeQuery("SELECT next_id FROM " . $table ." FOR UPDATE"); + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException - No Statement could be created or executed. + */ + public function unlockTable(Connection $con, $table) + { + // Tables in Oracle are unlocked when a commit is issued. The + // user may have issued a commit but do it here to be sure. + $con->commit(); + } +} diff --git a/gulliver/thirdparty/propel/adapter/DBPostgres.php b/gulliver/thirdparty/propel/adapter/DBPostgres.php new file mode 100644 index 000000000..dbc42dbbb --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBPostgres.php @@ -0,0 +1,117 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * This is used to connect to PostgresQL databases. + * + * http://www.pgsql.org + * + * @author Hans Lellelid (Propel) + * @author Hakan Tandogan (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBPostgres extends DBAdapter { + + /** + * This method is used to ignore case. + * + * @param string $in The string to transform to upper case. + * @return string The upper case string. + */ + public function toUpperCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * This method is used to ignore case. + * + * @param in The string whose case to ignore. + * @return The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return "($s1 || $s2)"; + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return "substring($s from $pos" . ($len > -1 ? "for $len" : "") . ")"; + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return "char_length($s)"; + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @exception SQLException No Statement could be created or executed. + */ + public function lockTable(Connection $con, $table) + { + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @exception SQLException No Statement could be created or executed. + */ + public function unlockTable(Connection $con, $table) + { + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBSQLite.php b/gulliver/thirdparty/propel/adapter/DBSQLite.php new file mode 100644 index 000000000..5c0769316 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBSQLite.php @@ -0,0 +1,124 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * This is used in order to connect to a SQLite database. + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBSQLite extends DBAdapter { + + /** + * This method is used to ignore case. + * + * @param in The string to transform to upper case. + * @return The upper case string. + */ + public function toUpperCase($in) + { + return 'UPPER(' . $in . ')'; + } + + /** + * This method is used to ignore case. + * + * @param in The string whose case to ignore. + * @return The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return 'UPPER(' . $in . ')'; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return "($s1 || $s2)"; + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return "substr($s, $pos, $len)"; + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return "length($s)"; + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @throws SQLException No Statement could be created or + * executed. + */ + public function lockTable(Connection $con, $table) + { + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException No Statement could be created or + * executed. + */ + public function unlockTable(Connection $con, $table) + { + } + + /** + * @see DBAdapter::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '[' . $text . ']'; + } + +} diff --git a/gulliver/thirdparty/propel/adapter/DBSybase.php b/gulliver/thirdparty/propel/adapter/DBSybase.php new file mode 100644 index 000000000..d28c41098 --- /dev/null +++ b/gulliver/thirdparty/propel/adapter/DBSybase.php @@ -0,0 +1,133 @@ +. + */ + +require_once 'propel/adapter/DBAdapter.php'; + +/** + * This is used to connect to a Sybase database using Sybase's + * Creole driver. + * + * NOTE:Currently JConnect does not implement the required + * methods for ResultSetMetaData, and therefore the village API's may + * not function. For connection pooling, everything works. + * + * @author Hans Lellelid (Propel) + * @author Jeff Brekke (Torque) + * @version $Revision: 536 $ + * @package propel.adapter + */ +class DBSybase extends DBAdapter { + + /** + * This method is used to ignore case. + * + * @param in The string to transform to upper case. + * @return The upper case string. + */ + public function toUpperCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * This method is used to ignore case. + * + * @param in The string whose case to ignore. + * @return The string in a case that can be ignored. + */ + public function ignoreCase($in) + { + return "UPPER(" . $in . ")"; + } + + /** + * Returns SQL which concatenates the second string to the first. + * + * @param string String to concatenate. + * @param string String to append. + * @return string + */ + public function concatString($s1, $s2) + { + return "($s1 + $s2)"; + } + + /** + * Returns SQL which extracts a substring. + * + * @param string String to extract from. + * @param int Offset to start from. + * @param int Number of characters to extract. + * @return string + */ + public function subString($s, $pos, $len) + { + return "SUBSTRING($s, $pos, $len)"; + } + + /** + * Returns SQL which calculates the length (in chars) of a string. + * + * @param string String to calculate length of. + * @return string + */ + public function strLength($s) + { + return "LEN($s)"; + } + + /** + * Locks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to lock. + * @throws SQLException No Statement could be created or executed. + */ + public function lockTable(Connection $con, $table) + { + $statement = $con->createStatement(); + $sql = "SELECT next_id FROM " . $table . " FOR UPDATE"; + $statement->executeQuery($sql); + } + + /** + * Unlocks the specified table. + * + * @param Connection $con The Creole connection to use. + * @param string $table The name of the table to unlock. + * @throws SQLException No Statement could be created or executed. + */ + public function unlockTable(Connection $con, $table) + { + // Tables in Sybase are unlocked when a commit is issued. The + // user may have issued a commit but do it here to be sure. + $con->commit(); + } + + /** + * @see DBAdapter::quoteIdentifier() + */ + public function quoteIdentifier($text) + { + return '[' . $text . ']'; + } +} diff --git a/gulliver/thirdparty/propel/logger/BasicLogger.php b/gulliver/thirdparty/propel/logger/BasicLogger.php new file mode 100644 index 000000000..0082b4b7e --- /dev/null +++ b/gulliver/thirdparty/propel/logger/BasicLogger.php @@ -0,0 +1,103 @@ +. + */ + + +/** + * This is a minimalistic interface that any logging class must implement for Propel. + * + * The API for this interface is based on the PEAR::Log interface. It provides a simple + * API that can be used by Propel independently of Log backend. + * + * PEAR::Log and perhaps the Log API was developed by Chuck Hagenbuch + * and Jon Parise . + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.logger + */ +interface BasicLogger { + + /** + * A convenience function for logging an alert event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function alert($message); + + /** + * A convenience function for logging a critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function crit($message); + + /** + * A convenience function for logging an error event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function err($message); + + /** + * A convenience function for logging a warning event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function warning($message); + /** + * A convenience function for logging an critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function notice($message); + /** + * A convenience function for logging an critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function info($message); + + /** + * A convenience function for logging a debug event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function debug($message); + + /** + * Primary method to handle logging. + * + * @param mixed $message String or Exception object containing the message + * to log. + * @param int $severity The numeric severity. Defaults to null so that no + * assumptions are made about the logging backend. + */ + public function log($message, $severity = null); + +} diff --git a/gulliver/thirdparty/propel/logger/MojaviLogAdapter.php b/gulliver/thirdparty/propel/logger/MojaviLogAdapter.php new file mode 100644 index 000000000..cc6cc7048 --- /dev/null +++ b/gulliver/thirdparty/propel/logger/MojaviLogAdapter.php @@ -0,0 +1,173 @@ +. + */ + +// include BasicLogger from include path +require_once('propel/logger/BasicLogger.php'); + +/** + * Mojavi logging adapter for propel + * + * @author Brandon Keepers + * @version $Revision: 536 $ + * @package propel.logger + */ +class MojaviLogAdapter implements BasicLogger { + + /** + * Instance of mojavi logger + */ + private $logger = null; + + /** + * constructor for setting up Mojavi log adapter + * + * @param ErrorLog $logger instance of Mojavi error log obtained by + * calling LogManager::getLogger(); + */ + public function __construct($logger = null) + { + $this->logger = $logger; + } + + /** + * A convenience function for logging an alert event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function alert($message) + { + $this->log($message, 'alert'); + } + + /** + * A convenience function for logging a critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function crit($message) + { + $this->log($message, 'crit'); + } + + /** + * A convenience function for logging an error event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function err($message) + { + $this->log($message, 'err'); + } + + /** + * A convenience function for logging a warning event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function warning($message) + { + $this->log($message, 'warning'); + } + + + /** + * A convenience function for logging an critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function notice($message) + { + $this->log($message, 'notice'); + } + /** + * A convenience function for logging an critical event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function info($message) + { + $this->log($message, 'info'); + } + + /** + * A convenience function for logging a debug event. + * + * @param mixed $message String or Exception object containing the message + * to log. + */ + public function debug($message) + { + $this->log($message, 'debug'); + } + + /** + * Primary method to handle logging. + * + * @param mixed $message String or Exception object containing the message + * to log. + * @param int $severity The numeric severity. Defaults to null so that no + * assumptions are made about the logging backend. + */ + public function log($message, $severity = null) + { + if(is_null($this->logger)) + $this->logger = LogManager::getLogger('propel'); + + switch($severity) + { + case 'crit': + $method = 'fatal'; + break; + case 'err': + $method = 'error'; + break; + case 'alert': + case 'warning': + $method = 'warning'; + break; + case 'notice': + case 'info': + $method = 'info'; + break; + case 'debug': + default: + $method = 'debug'; + } + + // get a backtrace to pass class, function, file, & line to Mojavi logger + $trace = debug_backtrace(); + + // call the appropriate Mojavi logger method + $this->logger->{$method} ( + $message, + $trace[2]['class'], + $trace[2]['function'], + $trace[1]['file'], + $trace[1]['line'] + ); + } +} diff --git a/gulliver/thirdparty/propel/map/ColumnMap.php b/gulliver/thirdparty/propel/map/ColumnMap.php new file mode 100644 index 000000000..5821ff6a5 --- /dev/null +++ b/gulliver/thirdparty/propel/map/ColumnMap.php @@ -0,0 +1,344 @@ +. + */ + +include_once 'propel/map/ValidatorMap.php'; + +/** + * ColumnMap is used to model a column of a table in a database. + * + * GENERAL NOTE + * ------------ + * The propel.map classes are abstract building-block classes for modeling + * the database at runtime. These classes are similar (a lite version) to the + * propel.engine.database.model classes, which are build-time modeling classes. + * These classes in themselves do not do any database metadata lookups, but instead + * are used by the MapBuilder classes that were generated for your datamodel. The + * MapBuilder that was created for your datamodel build a representation of your + * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc. + * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated + * by that template for your datamodel to further understand how these are put + * together. + * + * @author Hans Lellelid (Propel) + * @author John D. McNally (Torque) + * @version $Revision: 536 $ + * @package propel.map + */ +class ColumnMap { + + /** @var int Creole type for this column. */ + private $creoleType; + + /** @var string Native PHP type of the column. */ + private $type = null; + + /** Size of the column. */ + private $size = 0; + + /** Is it a primary key? */ + private $pk = false; + + /** Is null value allowed ?*/ + private $notNull = false; + + /** Name of the table that this column is related to. */ + private $relatedTableName = ""; + + /** Name of the column that this column is related to. */ + private $relatedColumnName = ""; + + /** The TableMap for this column. */ + private $table; + + /** The name of the column. */ + private $columnName; + + /** The php name of the column. */ + private $phpName; + + /** validators for this column */ + private $validators = array(); + + /** + * Constructor. + * + * @param string $name The name of the column. + * @param TableMap containingTable TableMap of the table this column is in. + */ + public function __construct($name, TableMap $containingTable) + { + $this->columnName = $name; + $this->table = $containingTable; + } + + /** + * Get the name of a column. + * + * @return string A String with the column name. + */ + public function getColumnName() + { + return $this->columnName; + } + + /** + * Set the php anme of this column. + * + * @param string $phpName A string representing the PHP name. + * @return void + */ + public function setPhpName($phpName) + { + $this->phpName = $phpName; + } + + /** + * Get the name of a column. + * + * @return string A String with the column name. + */ + public function getPhpName() + { + return $this->phpName; + } + + /** + * Get the table name + column name. + * + * @return string A String with the full column name. + */ + public function getFullyQualifiedName() + { + return $this->table->getName() . "." . $this->columnName; + } + + /** + * Get the table map this column belongs to. + * @return TableMap + */ + public function getTable() + { + return $this->table; + } + + /** + * Get the name of the table this column is in. + * + * @return string A String with the table name. + */ + public function getTableName() + { + return $this->table->getName(); + } + + /** + * Set the type of this column. + * + * @param string $type A string representing the PHP native type. + * @return void + */ + public function setType($type) + { + $this->type = $type; + } + + /** + * Set the Creole type of this column. + * + * @param int $type An int representing Creole type for this column. + * @return void + */ + public function setCreoleType($type) + { + $this->creoleType = $type; + } + + /** + * Set the size of this column. + * + * @param int $size An int specifying the size. + * @return void + */ + public function setSize($size) + { + $this->size = $size; + } + + /** + * Set if this column is a primary key or not. + * + * @param boolean $pk True if column is a primary key. + * @return void + */ + public function setPrimaryKey($pk) + { + $this->pk = $pk; + } + + /** + * Set if this column may be null. + * + * @param boolean nn True if column may be null. + * @return void + */ + public function setNotNull($nn) + { + $this->notNull = $nn; + } + + /** + * Gets the default value for this column. + * @return mixed String or NULL + */ + public function getDefaultValue() + { + return $this->defaultValue; + } + + /** + * Set the foreign key for this column. + * + * @param string tableName The name of the table that is foreign. + * @param string columnName The name of the column that is foreign. + * @return void + */ + public function setForeignKey($tableName, $columnName) + { + if ($tableName && $columnName) { + $this->relatedTableName = $tableName; + $this->relatedColumnName = $columnName; + } else { + $this->relatedTableName = ""; + $this->relatedColumnName = ""; + } + } + + public function addValidator($validator) + { + $this->validators[] = $validator; + } + + public function hasValidators() + { + return count($this->validators) > 0; + } + + public function getValidators() + { + return $this->validators; + } + + + /** + * Get the native PHP type of this column. + * + * @return string A string specifying the native PHP type. + */ + public function getType() + { + return $this->type; + } + + /** + * Get the Creole type of this column. + * + * @return string A string specifying the native PHP type. + */ + public function getCreoleType() + { + return $this->creoleType; + } + + /** + * Get the size of this column. + * + * @return int An int specifying the size. + */ + public function getSize() + { + return $this->size; + } + + /** + * Is this column a primary key? + * + * @return boolean True if column is a primary key. + */ + public function isPrimaryKey() + { + return $this->pk; + } + + /** + * Is null value allowed ? + * + * @return boolean True if column may be null. + */ + public function isNotNull() + { + return ($this->notNull || $this->isPrimaryKey()); + } + + /** + * Is this column a foreign key? + * + * @return boolean True if column is a foreign key. + */ + public function isForeignKey() + { + if ($this->relatedTableName) { + return true; + } else { + return false; + } + } + + /** + * Get the table.column that this column is related to. + * + * @return string A String with the full name for the related column. + */ + public function getRelatedName() + { + return $this->relatedTableName . "." . $this->relatedColumnName; + } + + /** + * Get the table name that this column is related to. + * + * @return string A String with the name for the related table. + */ + public function getRelatedTableName() + { + return $this->relatedTableName; + } + + /** + * Get the column name that this column is related to. + * + * @return string A String with the name for the related column. + */ + public function getRelatedColumnName() + { + return $this->relatedColumnName; + } +} diff --git a/gulliver/thirdparty/propel/map/DatabaseMap.php b/gulliver/thirdparty/propel/map/DatabaseMap.php new file mode 100644 index 000000000..d3c63968c --- /dev/null +++ b/gulliver/thirdparty/propel/map/DatabaseMap.php @@ -0,0 +1,127 @@ +. + */ + +include_once 'propel/map/TableMap.php'; + +/** + * DatabaseMap is used to model a database. + * + * GENERAL NOTE + * ------------ + * The propel.map classes are abstract building-block classes for modeling + * the database at runtime. These classes are similar (a lite version) to the + * propel.engine.database.model classes, which are build-time modeling classes. + * These classes in themselves do not do any database metadata lookups, but instead + * are used by the MapBuilder classes that were generated for your datamodel. The + * MapBuilder that was created for your datamodel build a representation of your + * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc. + * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated + * by that template for your datamodel to further understand how these are put + * together. + * + * @author Hans Lellelid (Propel) + * @author John D. McNally (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.map + */ +class DatabaseMap { + + /** Name of the database. */ + private $name; + + /** Name of the tables in the database. */ + private $tables; + + /** + * Constructor. + * + * @param string $name Name of the database. + */ + function __construct($name) + { + $this->name = $name; + $this->tables = array(); + } + + /** + * Does this database contain this specific table? + * + * @param string $name The String representation of the table. + * @return boolean True if the database contains the table. + */ + public function containsTable($name) + { + if ( strpos($name, '.') > 0) { + $name = substr($name, 0, strpos($name, '.')); + } + return isset($this->tables[$name]); + } + + /** + * Get the name of this database. + * + * @return string The name of the database. + */ + public function getName() + { + return $this->name; + } + + /** + * Get a TableMap for the table by name. + * + * @param string $name Name of the table. + * @return TableMap A TableMap + * @throws PropelException if the table is undefined + */ + public function getTable($name) + { + if (!isset($this->tables[$name])) { + throw new PropelException("Cannot fetch TableMap for undefined table: " . $name); + } + return $this->tables[$name]; + } + + /** + * Get a TableMap[] of all of the tables in the database. + * + * @return array A TableMap[]. + */ + public function getTables() + { + return $this->tables; + } + + /** + * Add a new table to the database by name. It creates an empty + * TableMap that you need to populate. + * + * @param string $tableName The name of the table. + * @return TableMap The newly created TableMap. + */ + public function addTable($tableName) + { + $this->tables[$tableName] = new TableMap($tableName, $this); + return $this->tables[$tableName]; + } +} diff --git a/gulliver/thirdparty/propel/map/MapBuilder.php b/gulliver/thirdparty/propel/map/MapBuilder.php new file mode 100644 index 000000000..cc8aabeb3 --- /dev/null +++ b/gulliver/thirdparty/propel/map/MapBuilder.php @@ -0,0 +1,75 @@ +. + */ + +/** + * MapBuilders are classes that construct a model of a database at runtime. + * + * MapBuilders support a single database, so this class essentially serves as + * a wrapper around the DatabaseMap class. This interface can be used for any + * class that needs to construct a runtime database model; by default in Propel + * the MapBuilder.tpl generates a class for your datamodel that implements this + * interface and re-creates your database using the DatabaseMap, TableMap, + * ColumnMap, and ValidatorMap classes. + * + * GENERAL NOTE + * ------------ + * The propel.map classes are abstract building-block classes for modeling + * the database at runtime. These classes are similar (a lite version) to the + * propel.engine.database.model classes, which are build-time modeling classes. + * These classes in themselves do not do any database metadata lookups, but instead + * are used by the MapBuilder classes that were generated for your datamodel. The + * MapBuilder that was created for your datamodel build a representation of your + * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc. + * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated + * by that template for your datamodel to further understand how these are put + * together. + * + * @author Hans Lellelid (Propel) + * @author John D. McNally (Torque) + * @author Hans Lellelid (Torque) + * @version $Revision: 536 $ + * @package propel.map + */ +interface MapBuilder { + + /** + * Build up the database mapping. + * @return void + * @throws Exception Couldn't build mapping. + */ + function doBuild(); + + /** + * Tells us if the database mapping is built so that we can avoid + * re-building it repeatedly. + * + * @return boolean Whether the DatabaseMap is built. + */ + function isBuilt(); + + /** + * Gets the database mapping this map builder built. + * + * @return DatabaseMap A DatabaseMap. + */ + function getDatabaseMap(); +} diff --git a/gulliver/thirdparty/propel/map/TableMap.php b/gulliver/thirdparty/propel/map/TableMap.php new file mode 100644 index 000000000..7b1ddc9be --- /dev/null +++ b/gulliver/thirdparty/propel/map/TableMap.php @@ -0,0 +1,429 @@ +. + */ + +include_once 'propel/map/ColumnMap.php'; +include_once 'propel/map/ValidatorMap.php'; + +/** + * TableMap is used to model a table in a database. + * + * GENERAL NOTE + * ------------ + * The propel.map classes are abstract building-block classes for modeling + * the database at runtime. These classes are similar (a lite version) to the + * propel.engine.database.model classes, which are build-time modeling classes. + * These classes in themselves do not do any database metadata lookups, but instead + * are used by the MapBuilder classes that were generated for your datamodel. The + * MapBuilder that was created for your datamodel build a representation of your + * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc. + * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated + * by that template for your datamodel to further understand how these are put + * together. + * + * @author Hans Lellelid (Propel) + * @author John D. McNally (Torque) + * @author Daniel Rall (Torque) + * @version $Revision: 536 $ + * @package propel.map + */ +class TableMap { + + /** The columns in the table. */ + private $columns; + + /** The database this table belongs to. */ + private $dbMap; + + /** The name of the table. */ + private $tableName; + + /** The PHP name of the table. */ + private $phpName; + + /** The prefix on the table name. */ + private $prefix; + + /** Whether to use an id generator for pkey. */ + private $useIdGenerator; + + /** + * Object to store information that is needed if the + * for generating primary keys. + */ + private $pkInfo; + + /** + * Construct a new TableMap. + * + * @param string $tableName The name of the table. + * @param DatabaseMap $containingDB A DatabaseMap that this table belongs to. + */ + public function __construct($tableName, DatabaseMap $containingDB) + { + $this->tableName = $tableName; + $this->dbMap = $containingDB; + $this->columns = array(); + } + + /** + * Normalizes the column name, removing table prefix and uppercasing. + * @param string $name + * @return string Normalized column name. + */ + private function normalizeColName($name) { + if (false !== ($pos = strpos($name, '.'))) { + $name = substr($name, $pos + 1); + } + $name = strtoupper($name); + return $name; + } + + /** + * Does this table contain the specified column? + * + * @param string $name name of the column + * @return boolean True if the table contains the column. + */ + public function containsColumn($name) + { + if (!is_string($name)) { + $name = $name->getColumnName(); + } + return isset($this->columns[$this->normalizeColName($name)]); + } + + /** + * Get the DatabaseMap containing this TableMap. + * + * @return DatabaseMap A DatabaseMap. + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * Get the name of the Table. + * + * @return string A String with the name of the table. + */ + public function getName() + { + return $this->tableName; + } + + /** + * Get the PHP name of the Table. + * + * @return string A String with the name of the table. + */ + public function getPhpName() + { + return $this->phpName; + } + + /** + * Set the PHP name of the Table. + * + * @param string $phpName The PHP Name for this table + */ + public function setPhpName($phpName) + { + $this->phpName = $phpName; + } + + /** + * Get table prefix name. + * + * @return string A String with the prefix. + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * Set table prefix name. + * + * @param string $prefix The prefix for the table name (ie: SCARAB for + * SCARAB_PROJECT). + * @return void + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Whether to use Id generator for primary key. + * @return boolean + */ + public function isUseIdGenerator() { + return $this->useIdGenerator; + } + + /** + * Get the information used to generate a primary key + * + * @return An Object. + */ + public function getPrimaryKeyMethodInfo() + { + return $this->pkInfo; + } + + /** + * Get a ColumnMap[] of the columns in this table. + * + * @return array A ColumnMap[]. + */ + public function getColumns() + { + return $this->columns; + } + + /** + * Get a ColumnMap for the named table. + * + * @param string $name A String with the name of the table. + * @return ColumnMap A ColumnMap. + * @throws PropelException if the column is undefined + */ + public function getColumn($name) + { + $name = $this->normalizeColName($name); + if (!isset($this->columns[$name])) { + throw new PropelException("Cannot fetch ColumnMap for undefined column: " . $name); + } + return $this->columns[$name]; + } + + /** + * Add a primary key column to this Table. + * + * @param string $columnName A String with the column name. + * @param string $type A string specifying the PHP native type. + * @param int $creoleType The integer representing the Creole type. + * @param boolean $isNotNull Whether column does not allow NULL values. + * @param $size An int specifying the size. + * @return ColumnMap Newly added PrimaryKey column. + */ + public function addPrimaryKey($columnName, $phpName, $type, $creoleType, $isNotNull = false, $size = null) + { + return $this->addColumn($columnName, $phpName, $type, $creoleType, $isNotNull, $size, true, null, null); + } + + /** + * Add a foreign key column to the table. + * + * @param string $columnName A String with the column name. + * @param string $type A string specifying the PHP native type. + * @param int $creoleType The integer representing the Creole type. + * @param string $fkTable A String with the foreign key table name. + * @param string $fkColumn A String with the foreign key column name. + * @param boolean $isNotNull Whether column does not allow NULL values. + * @param int $size An int specifying the size. + * @param string $defaultValue The default value for this column. + * @return ColumnMap Newly added ForeignKey column. + */ + public function addForeignKey($columnName, $phpName, $type, $creoleType, $fkTable, $fkColumn, $isNotNull = false, $size = 0) + { + return $this->addColumn($columnName, $phpName, $type, $creoleType, $isNotNull, $size, false, $fkTable, $fkColumn); + } + + /** + * Add a foreign primary key column to the table. + * + * @param string $columnName A String with the column name. + * @param string $type A string specifying the PHP native type. + * @param int $creoleType The integer representing the Creole type. + * @param string $fkTable A String with the foreign key table name. + * @param string $fkColumn A String with the foreign key column name. + * @param boolean $isNotNull Whether column does not allow NULL values. + * @param int $size An int specifying the size. + * @param string $defaultValue The default value for this column. + * @return ColumnMap Newly created foreign pkey column. + */ + public function addForeignPrimaryKey($columnName, $phpName, $type, $creoleType, $fkTable, $fkColumn, $isNotNull = false, $size = 0) + { + return $this->addColumn($columnName, $phpName, $type, $creoleType, $isNotNull, $size, true, $fkTable, $fkColumn); + } + + /** + * Add a pre-created column to this table. It will replace any + * existing column. + * + * @param ColumnMap $cmap A ColumnMap. + * @return ColumnMap The added column map. + */ + public function addConfiguredColumn($cmap) + { + $this->columns[ $cmap->getColumnName() ] = $cmap; + return $cmap; + } + + /** + * Add a column to the table. + * + * @param string name A String with the column name. + * @param string $type A string specifying the PHP native type. + * @param int $creoleType The integer representing the Creole type. + * @param boolean $isNotNull Whether column does not allow NULL values. + * @param int $size An int specifying the size. + * @param boolean $pk True if column is a primary key. + * @param string $fkTable A String with the foreign key table name. + * @param $fkColumn A String with the foreign key column name. + * @param string $defaultValue The default value for this column. + * @return ColumnMap The newly created column. + */ + public function addColumn($name, $phpName, $type, $creoleType, $isNotNull = false, $size = null, $pk = null, $fkTable = null, $fkColumn = null) + { + + $col = new ColumnMap($name, $this); + + if ($fkTable && $fkColumn) { + if (substr($fkColumn, '.') > 0 && substr($fkColumn, $fkTable) !== false) { + $fkColumn = substr($fkColumn, strlen($fkTable) + 1); + } + $col->setForeignKey($fkTable, $fkColumn); + } + + $col->setType($type); + $col->setCreoleType($creoleType); + $col->setPrimaryKey($pk); + $col->setSize($size); + $col->setPhpName($phpName); + $col->setNotNull($isNotNull); + + $this->columns[$name] = $col; + + return $this->columns[$name]; + } + + /** + * Add a validator to a table's column + * + * @param string $columnName The name of the validator's column + * @param string $name The rule name of this validator + * @param string $classname The dot-path name of class to use (e.g. myapp.propel.MyValidator) + * @param string $value + * @param string $message The error message which is returned on invalid values + * @return void + */ + public function addValidator($columnName, $name, $classname, $value, $message) + { + if (false !== ($pos = strpos($columnName, '.'))) { + $columnName = substr($columnName, $pos + 1); + } + + $col = $this->getColumn($columnName); + if ($col !== null) { + $validator = new ValidatorMap($col); + $validator->setName($name); + $validator->setClass($classname); + $validator->setValue($value); + $validator->setMessage($message); + $col->addValidator($validator); + } + } + + /** + * Set whether or not to use Id generator for primary key. + * @param boolean $bit + */ + public function setUseIdGenerator($bit) { + $this->useIdGenerator = $bit; + } + + /** + * Sets the pk information needed to generate a key + * + * @param $pkInfo information needed to generate a key + */ + public function setPrimaryKeyMethodInfo($pkInfo) + { + $this->pkInfo = $pkInfo; + } + + //---Utility methods for doing intelligent lookup of table names + + /** + * Tell me if i have PREFIX in my string. + * + * @param data A String. + * @return boolean True if prefix is contained in data. + */ + private function hasPrefix($data) + { + return (substr($data, $this->getPrefix()) !== false); + } + + /** + * Removes the PREFIX. + * + * @param string $data A String. + * @return string A String with data, but with prefix removed. + */ + private function removePrefix($data) + { + return substr($data, strlen($this->getPrefix())); + } + + + + /** + * Removes the PREFIX, removes the underscores and makes + * first letter caps. + * + * SCARAB_FOO_BAR becomes FooBar. + * + * @param data A String. + * @return string A String with data processed. + */ + public final function removeUnderScores($data) + { + $tmp = null; + $out = ""; + if ($this->hasPrefix($data)) { + $tmp = $this->removePrefix($data); + } else { + $tmp = $data; + } + + $tok = strtok($tmp, "_"); + while ($tok) { + $out .= ucfirst($tok); + $tok = strtok("_"); + } + return $out; + } + + /** + * Makes the first letter caps and the rest lowercase. + * + * @param string $data A String. + * @return string A String with data processed. + */ + private function firstLetterCaps($data) + { + return(ucfirst(strtolower($data))); + } +} diff --git a/gulliver/thirdparty/propel/map/ValidatorMap.php b/gulliver/thirdparty/propel/map/ValidatorMap.php new file mode 100644 index 000000000..ab6d88f8f --- /dev/null +++ b/gulliver/thirdparty/propel/map/ValidatorMap.php @@ -0,0 +1,109 @@ +. + */ + +/** + * ValidatorMap is used to model a column validator. + * + * GENERAL NOTE + * ------------ + * The propel.map classes are abstract building-block classes for modeling + * the database at runtime. These classes are similar (a lite version) to the + * propel.engine.database.model classes, which are build-time modeling classes. + * These classes in themselves do not do any database metadata lookups, but instead + * are used by the MapBuilder classes that were generated for your datamodel. The + * MapBuilder that was created for your datamodel build a representation of your + * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc. + * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated + * by that template for your datamodel to further understand how these are put + * together. + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.map + */ +class ValidatorMap +{ + /** rule name of this validator */ + private $name; + /** the dot-path to class to use for validator */ + private $classname; + /** value to check against */ + private $value; + /** execption message thrown on invalid input */ + private $message; + /** related column */ + private $column; + + public function __construct($containingColumn) + { + $this->column = $containingColumn; + } + + public function getColumn() + { + return $this->column; + } + + public function getColumnName() + { + return $this->column->getColumnName(); + } + + public function setName($name) + { + $this->name = $name; + } + + public function setClass($classname) + { + $this->classname = $classname; + } + + public function setValue($value) + { + $this->value = $value; + } + + public function setMessage($message) + { + $this->message = $message; + } + + public function getName() + { + return $this->name; + } + + public function getClass() + { + return $this->classname; + } + + public function getValue() + { + return $this->value; + } + + public function getMessage() + { + return $this->message; + } +} diff --git a/gulliver/thirdparty/propel/om/BaseObject.php b/gulliver/thirdparty/propel/om/BaseObject.php new file mode 100644 index 000000000..d60aff28e --- /dev/null +++ b/gulliver/thirdparty/propel/om/BaseObject.php @@ -0,0 +1,187 @@ +. + */ + +require_once 'propel/om/Persistent.php'; + +/** + * This class contains attributes and methods that are used by all + * business objects within the system. + * + * @author Hans Lellelid (Propel) + * @author Frank Y. Kim (Torque) + * @author John D. McNally (Torque) + * @version $Revision: 536 $ + * @package propel.om + */ +abstract class BaseObject { + + /** + * attribute to determine if this object has previously been saved. + * @var boolean + */ + private $_new = true; + + /** + * attribute to determine whether this object has been deleted. + * @var boolean + */ + private $_deleted = false; + + /** + * The columns that have been modified in current object. + * Tracking modified columns allows us to only update modified columns. + * @var array + */ + protected $modifiedColumns = array(); + + /** + * Returns whether the object has been modified. + * + * @return boolean True if the object has been modified. + */ + public function isModified() + { + return !empty($this->modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->_new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and Peers. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->_new = (boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->_deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->_deleted = (boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if ($col !== null) + { + while (($offset = array_search($col, $this->modifiedColumns)) !== false) + array_splice($this->modifiedColumns, $offset, 1); + } + else + { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another BaseObject instance. If + * obj is an instance of BaseObject, delegates to + * equals(BaseObject). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + if (is_object($obj)) { + if ($this === $obj) { + return true; + } elseif ($this->getPrimaryKey() === null || $obj->getPrimaryKey() === null) { + return false; + } else { + return ($this->getPrimaryKey() === $obj->getPrimaryKey()); + } + } else { + return false; + } + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise calls Object.hashCode(). + * + * @return int Hashcode + */ + public function hashCode() + { + $ok = $this->getPrimaryKey(); + if ($ok === null) { + return crc32(serialize($this)); + } + return crc32(serialize($ok)); // serialize because it could be an array ("ComboKey") + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + +} diff --git a/gulliver/thirdparty/propel/om/Persistent.php b/gulliver/thirdparty/propel/om/Persistent.php new file mode 100644 index 000000000..e26085911 --- /dev/null +++ b/gulliver/thirdparty/propel/om/Persistent.php @@ -0,0 +1,118 @@ +. + */ + +/** + * This interface defines methods related to saving an object + * + * @author Hans Lellelid (Propel) + * @author John D. McNally (Torque) + * @author Fedor K. (Torque) + * @version $Revision: 536 $ + * @package propel.om + */ +interface Persistent { + + /** + * getter for the object primaryKey. + * + * @return ObjectKey the object primaryKey as an Object + */ + public function getPrimaryKey(); + + /** + * Sets the PrimaryKey for the object. + * + * @param mixed $primaryKey The new PrimaryKey object or string (result of PrimaryKey.toString()). + * @return void + * @throws Exception, This method might throw an exceptions + */ + public function setPrimaryKey($primaryKey); + + + /** + * Returns whether the object has been modified, since it was + * last retrieved from storage. + * + * @return boolean True if the object has been modified. + */ + public function isModified(); + + /** + * Has specified column been modified? + * + * @param string $col + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col); + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return boolean True, if the object has never been persisted. + */ + public function isNew(); + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and Peers. + * + * @param boolean $b the state of the object. + */ + public function setNew($b); + + /** + * Resets (to false) the "modified" state for this object. + * + * @return void + */ + public function resetModified(); + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted(); + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b); + + /** + * Deletes the object. + * @param Connection $con + * @return void + * @throws Exception + */ + public function delete($con = null); + + /** + * Saves the object. + * @param Connection $con + * @return void + * @throws Exception + */ + public function save($con = null); +} diff --git a/gulliver/thirdparty/propel/om/PreOrderNodeIterator.php b/gulliver/thirdparty/propel/om/PreOrderNodeIterator.php new file mode 100644 index 000000000..2dc4d053b --- /dev/null +++ b/gulliver/thirdparty/propel/om/PreOrderNodeIterator.php @@ -0,0 +1,90 @@ +. + */ + +/** + * Pre-order node iterator for Node objects. + * + * @author Dave Lawson + * @version $Revision: 536 $ + * @package propel.om + */ +class PreOrderNodeIterator implements Iterator +{ + private $topNode = null; + + private $curNode = null; + + private $querydb = false; + + private $con = null; + + public function __construct($node, $opts) { + $this->topNode = $node; + $this->curNode = $node; + + if (isset($opts['con'])) + $this->con = $opts['con']; + + if (isset($opts['querydb'])) + $this->querydb = $opts['querydb']; + } + + public function rewind() { + $this->curNode = $this->topNode; + } + + public function valid() { + return ($this->curNode !== null); + } + + public function current() { + return $this->curNode; + } + + public function key() { + return $this->curNode->getNodePath(); + } + + public function next() { + + if ($this->valid()) + { + $nextNode = $this->curNode->getFirstChildNode($this->querydb, $this->con); + + while ($nextNode === null) + { + if ($this->curNode === null || $this->curNode->equals($this->topNode)) + break; + + $nextNode = $this->curNode->getSiblingNode(false, $this->querydb, $this->con); + + if ($nextNode === null) + $this->curNode = $this->curNode->getParentNode($this->querydb, $this->con); + } + + $this->curNode = $nextNode; + } + + return $this->curNode; + } + +} diff --git a/gulliver/thirdparty/propel/util/BasePeer.php b/gulliver/thirdparty/propel/util/BasePeer.php new file mode 100644 index 000000000..f2e492245 --- /dev/null +++ b/gulliver/thirdparty/propel/util/BasePeer.php @@ -0,0 +1,1001 @@ +. + */ + +include_once 'propel/adapter/DBAdapter.php'; +include_once 'propel/map/ColumnMap.php'; +include_once 'propel/map/DatabaseMap.php'; +include_once 'propel/map/MapBuilder.php'; +include_once 'propel/map/TableMap.php'; +include_once 'propel/map/ValidatorMap.php'; +include_once 'propel/validator/ValidationFailed.php'; + +/** + * This is a utility class for all generated Peer classes in the system. + * + * Peer classes are responsible for isolating all of the database access + * for a specific business object. They execute all of the SQL + * against the database. Over time this class has grown to include + * utility methods which ease execution of cross-database queries and + * the implementation of concrete Peers. + * + * @author Hans Lellelid (Propel) + * @author Kaspars Jaudzems (Propel) + * @author Frank Y. Kim (Torque) + * @author John D. McNally (Torque) + * @author Brett McLaughlin (Torque) + * @author Stephen Haberman (Torque) + * @version $Revision: 536 $ + * @package propel.util + */ +class BasePeer +{ + + /** Array (hash) that contains the cached mapBuilders. */ + private static $mapBuilders = array(); + + /** Array (hash) that contains cached validators */ + private static $validatorMap = array(); + + /** + * phpname type + * e.g. 'AuthorId' + */ + const TYPE_PHPNAME = 'phpName'; + + /** + * column (peer) name type + * e.g. 'book.AUTHOR_ID' + */ + const TYPE_COLNAME = 'colName'; + + /** + * column fieldname type + * e.g. 'author_id' + */ + const TYPE_FIELDNAME = 'fieldName'; + + /** + * num type + * simply the numerical array index, e.g. 4 + */ + const TYPE_NUM = 'num'; + + static public function getFieldnames ($classname, $type = self::TYPE_PHPNAME) { + + // TODO we should take care of including the peer class here + + $peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true? + $callable = array($peerclass, 'getFieldnames'); + $args = array($type); + + return call_user_func_array($callable, $args); + } + + static public function translateFieldname($classname, $fieldname, $fromType, $toType) { + + // TODO we should take care of including the peer class here + + $peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true? + $callable = array($peerclass, 'translateFieldname'); + $args = array($fieldname, $fromType, $toType); + + return call_user_func_array($callable, $args); + } + + /** + * Method to perform deletes based on values and keys in a + * Criteria. + * + * @param Criteria $criteria The criteria to use. + * @param Connection $con A Connection. + * @return int The number of rows affected by last statement execution. For most + * uses there is only one delete statement executed, so this number + * will correspond to the number of rows affected by the call to this + * method. Note that the return value does require that this information + * is returned (supported) by the Creole db driver. + * @throws PropelException + */ + public static function doDelete(Criteria $criteria, Connection $con) + { + $db = Propel::getDB($criteria->getDbName()); + $dbMap = Propel::getDatabaseMap($criteria->getDbName()); + + // Set up a list of required tables (one DELETE statement will + // be executed per table) + + $tables_keys = array(); + foreach($criteria as $c) { + foreach($c->getAllTables() as $tableName) { + $tableName2 = $criteria->getTableForAlias($tableName); + if ($tableName2 !== null) { + $tables_keys[$tableName2 . ' ' . $tableName] = true; + } else { + $tables_keys[$tableName] = true; + } + } + } // foreach criteria->keys() + + $affectedRows = 0; // initialize this in case the next loop has no iterations. + + $tables = array_keys($tables_keys); + + foreach($tables as $tableName) { + + $whereClause = array(); + $selectParams = array(); + foreach($dbMap->getTable($tableName)->getColumns() as $colMap) { + $key = $tableName . '.' . $colMap->getColumnName(); + if ($criteria->containsKey($key)) { + $sb = ""; + $criteria->getCriterion($key)->appendPsTo($sb, $selectParams); + $whereClause[] = $sb; + } + } + + if (empty($whereClause)) { + throw new PropelException("Cowardly refusing to delete from table $tableName with empty WHERE clause."); + } + + // Execute the statement. + try { + + $sqlSnippet = implode(" AND ", $whereClause); + + if ($criteria->isSingleRecord()) { + $sql = "SELECT COUNT(*) FROM " . $tableName . " WHERE " . $sqlSnippet; + $stmt = $con->prepareStatement($sql); + self::populateStmtValues($stmt, $selectParams, $dbMap); + $rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM); + $rs->next(); + if ($rs->getInt(1) > 1) { + $rs->close(); + throw new PropelException("Expecting to delete 1 record, but criteria match multiple."); + } + $rs->close(); + } + + $sql = "DELETE FROM " . $tableName . " WHERE " . $sqlSnippet; + Propel::log($sql, Propel::LOG_DEBUG); + $stmt = $con->prepareStatement($sql); + self::populateStmtValues($stmt, $selectParams, $dbMap); + $affectedRows = $stmt->executeUpdate(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException("Unable to execute DELETE statement.",$e); + } + + } // for each table + + return $affectedRows; + } + + /** + * Method to deletes all contents of specified table. + * + * This method is invoked from generated Peer classes like this: + * + * public static function doDeleteAll($con = null) + * { + * if ($con === null) $con = Propel::getConnection(self::DATABASE_NAME); + * BasePeer::doDeleteAll(self::TABLE_NAME, $con); + * } + * + * + * @param string $tableName The name of the table to empty. + * @param Connection $con A Connection. + * @return int The number of rows affected by the statement. Note + * that the return value does require that this information + * is returned (supported) by the Creole db driver. + * @throws PropelException - wrapping SQLException caught from statement execution. + */ + public static function doDeleteAll($tableName, Connection $con) + { + try { + $sql = "DELETE FROM " . $tableName; + Propel::log($sql, Propel::LOG_DEBUG); + $stmt = $con->prepareStatement($sql); + return $stmt->executeUpdate(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException("Unable to perform DELETE ALL operation.", $e); + } + } + + /** + * Method to perform inserts based on values and keys in a + * Criteria. + *

    + * If the primary key is auto incremented the data in Criteria + * will be inserted and the auto increment value will be returned. + *

    + * If the primary key is included in Criteria then that value will + * be used to insert the row. + *

    + * If no primary key is included in Criteria then we will try to + * figure out the primary key from the database map and insert the + * row with the next available id using util.db.IDBroker. + *

    + * If no primary key is defined for the table the values will be + * inserted as specified in Criteria and null will be returned. + * + * @param Criteria $criteria Object containing values to insert. + * @param Connection $con A Connection. + * @return mixed The primary key for the new row if (and only if!) the primary key + * is auto-generated. Otherwise will return null. + * @throws PropelException + */ + public static function doInsert(Criteria $criteria, Connection $con) { + + // the primary key + $id = null; + + // Get the table name and method for determining the primary + // key value. + $keys = $criteria->keys(); + if (!empty($keys)) { + $tableName = $criteria->getTableName( $keys[0] ); + } else { + throw new PropelException("Database insert attempted without anything specified to insert"); + } + + $dbMap = Propel::getDatabaseMap($criteria->getDbName()); + $tableMap = $dbMap->getTable($tableName); + $keyInfo = $tableMap->getPrimaryKeyMethodInfo(); + $useIdGen = $tableMap->isUseIdGenerator(); + $keyGen = $con->getIdGenerator(); + + $pk = self::getPrimaryKey($criteria); + + // only get a new key value if you need to + // the reason is that a primary key might be defined + // but you are still going to set its value. for example: + // a join table where both keys are primary and you are + // setting both columns with your own values + + // pk will be null if there is no primary key defined for the table + // we're inserting into. + if ($pk !== null && $useIdGen && !$criteria->containsKey($pk->getFullyQualifiedName())) { + + // If the keyMethod is SEQUENCE get the id before the insert. + if ($keyGen->isBeforeInsert()) { + try { + $id = $keyGen->getId($keyInfo); + } catch (Exception $e) { + throw new PropelException("Unable to get sequence id.", $e); + } + $criteria->add($pk->getFullyQualifiedName(), $id); + } + } + + try { + + $qualifiedCols = $criteria->keys(); // we need table.column cols when populating values + $columns = array(); // but just 'column' cols for the SQL + foreach($qualifiedCols as $qualifiedCol) { + $columns[] = substr($qualifiedCol, strpos($qualifiedCol, '.') + 1); + } + + $sql = "INSERT INTO " . $tableName + . " (" . implode(",", $columns) . ")" + . " VALUES (" . substr(str_repeat("?,", count($columns)), 0, -1) . ")"; + + Propel::log($sql, Propel::LOG_DEBUG); + + $stmt = $con->prepareStatement($sql); + self::populateStmtValues($stmt, self::buildParams($qualifiedCols, $criteria), $dbMap); + $stmt->executeUpdate(); + + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException("Unable to execute INSERT statement.", $e); + } + + // If the primary key column is auto-incremented, get the id + // now. + if ($pk !== null && $useIdGen && $keyGen->isAfterInsert()) { + try { + $id = $keyGen->getId($keyInfo); + } catch (Exception $e) { + throw new PropelException("Unable to get autoincrement id.", $e); + } + } + + return $id; + } + + /** + * Method used to update rows in the DB. Rows are selected based + * on selectCriteria and updated using values in updateValues. + *

    + * Use this method for performing an update of the kind: + *

    + * WHERE some_column = some value AND could_have_another_column = + * another value AND so on. + * + * @param $selectCriteria A Criteria object containing values used in where + * clause. + * @param $updateValues A Criteria object containing values used in set + * clause. + * @param $con The Connection to use. + * @return int The number of rows affected by last update statement. For most + * uses there is only one update statement executed, so this number + * will correspond to the number of rows affected by the call to this + * method. Note that the return value does require that this information + * is returned (supported) by the Creole db driver. + * @throws PropelException + */ + public static function doUpdate(Criteria $selectCriteria, Criteria $updateValues, Connection $con) { + + $db = Propel::getDB($selectCriteria->getDbName()); + $dbMap = Propel::getDatabaseMap($selectCriteria->getDbName()); + + // Get list of required tables, containing all columns + $tablesColumns = $selectCriteria->getTablesColumns(); + + // we also need the columns for the update SQL + $updateTablesColumns = $updateValues->getTablesColumns(); + + $affectedRows = 0; // initialize this in case the next loop has no iterations. + + foreach($tablesColumns as $tableName => $columns) { + + $whereClause = array(); + + $selectParams = array(); + foreach($columns as $colName) { + $sb = ""; + $selectCriteria->getCriterion($colName)->appendPsTo($sb, $selectParams); + $whereClause[] = $sb; + } + + $rs = null; + $stmt = null; + try { + + $sqlSnippet = implode(" AND ", $whereClause); + + if ($selectCriteria->isSingleRecord()) { + // Get affected records. + $sql = "SELECT COUNT(*) FROM " . $tableName . " WHERE " . $sqlSnippet; + $stmt = $con->prepareStatement($sql); + self::populateStmtValues($stmt, $selectParams, $dbMap); + $rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM); + $rs->next(); + if ($rs->getInt(1) > 1) { + $rs->close(); + throw new PropelException("Expected to update 1 record, multiple matched."); + } + $rs->close(); + } + + $sql = "UPDATE " . $tableName . " SET "; + foreach($updateTablesColumns[$tableName] as $col) { + $sql .= substr($col, strpos($col, '.') + 1) . " = ?,"; + } + + $sql = substr($sql, 0, -1) . " WHERE " . $sqlSnippet; + + Propel::log($sql, Propel::LOG_DEBUG); + + $stmt = $con->prepareStatement($sql); + + // Replace '?' with the actual values + self::populateStmtValues($stmt, array_merge(self::buildParams($updateTablesColumns[$tableName], $updateValues), $selectParams), $dbMap); + + $affectedRows = $stmt->executeUpdate(); + $stmt->close(); + + } catch (Exception $e) { + if ($rs) $rs->close(); + if ($stmt) $stmt->close(); + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException("Unable to execute UPDATE statement.", $e); + } + + } // foreach table in the criteria + + return $affectedRows; + } + + /** + * Executes query build by createSelectSql() and returns ResultSet. + * + * @param Criteria $criteria A Criteria. + * @param Connection $con A connection to use. + * @return ResultSet The resultset. + * @throws PropelException + * @see createSelectSql() + */ + public static function doSelect(Criteria $criteria, $con = null) + { + $dbMap = Propel::getDatabaseMap($criteria->getDbName()); + + if ($con === null) + $con = Propel::getConnection($criteria->getDbName()); + + $stmt = null; + try { + + // Transaction support exists for (only?) Postgres, which must + // have SELECT statements that include bytea columns wrapped w/ + // transactions. + if ($criteria->isUseTransaction()) $con->begin(); + + $params = array(); + $sql = self::createSelectSql($criteria, $params); + + $stmt = $con->prepareStatement($sql); + $stmt->setLimit($criteria->getLimit()); + $stmt->setOffset($criteria->getOffset()); + + self::populateStmtValues($stmt, $params, $dbMap); + $rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM); + if ($criteria->isUseTransaction()) $con->commit(); + } catch (Exception $e) { + if ($stmt) $stmt->close(); + if ($criteria->isUseTransaction()) $con->rollback(); + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException($e); + } + + return $rs; + } + + /** + * Applies any validators that were defined in the schema to the specified columns. + * + * @param string $dbName The name of the database + * @param string $tableName The name of the table + * @param array $columns Array of column names as key and column values as value. + */ + public static function doValidate($dbName, $tableName, $columns) + { + $dbMap = Propel::getDatabaseMap($dbName); + $tableMap = $dbMap->getTable($tableName); + $failureMap = array(); // map of ValidationFailed objects + foreach($columns as $colName => $colValue) { + if ($tableMap->containsColumn($colName)) { + $col = $tableMap->getColumn($colName); + foreach($col->getValidators() as $validatorMap) { + $validator = BasePeer::getValidator($validatorMap->getClass()); + if($validator && ($col->isNotNull() || $colValue !== null) && $validator->isValid($validatorMap, $colValue) === false) { + if (!isset($failureMap[$colName])) { // for now we do one ValidationFailed per column, not per rule + $failureMap[$colName] = new ValidationFailed($colName, $validatorMap->getMessage(), $validator); + } + } + } + } + } + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Helper method which returns the primary key contained + * in the given Criteria object. + * + * @param Criteria $criteria A Criteria. + * @return ColumnMap If the Criteria object contains a primary + * key, or null if it doesn't. + * @throws PropelException + */ + private static function getPrimaryKey(Criteria $criteria) + { + // Assume all the keys are for the same table. + $keys = $criteria->keys(); + $key = $keys[0]; + $table = $criteria->getTableName($key); + + $pk = null; + + if (!empty($table)) { + + $dbMap = Propel::getDatabaseMap($criteria->getDbName()); + + if ($dbMap === null) { + throw new PropelException("\$dbMap is null"); + } + + if ($dbMap->getTable($table) === null) { + throw new PropelException("\$dbMap->getTable() is null"); + } + + $columns = $dbMap->getTable($table)->getColumns(); + foreach(array_keys($columns) as $key) { + if ($columns[$key]->isPrimaryKey()) { + $pk = $columns[$key]; + break; + } + } + } + return $pk; + } + + /** + * Method to create an SQL query based on values in a Criteria. + * + * This method creates only prepared statement SQL (using ? where values + * will go). The second parameter ($params) stores the values that need + * to be set before the statement is executed. The reason we do it this way + * is to let the Creole layer handle all escaping & value formatting. + * + * @param Criteria $criteria Criteria for the SELECT query. + * @param array &$params Parameters that are to be replaced in prepared statement. + * @return string + * @throws PropelException Trouble creating the query string. + */ + public static function createSelectSql(Criteria $criteria, &$params) { + + $db = Propel::getDB($criteria->getDbName()); + $dbMap = Propel::getDatabaseMap($criteria->getDbName()); + + // redundant definition $selectModifiers = array(); + $selectClause = array(); + $fromClause = array(); + $joinClause = array(); + $joinTables = array(); + $whereClause = array(); + $orderByClause = array(); + // redundant definition $groupByClause = array(); + + $orderBy = $criteria->getOrderByColumns(); + $groupBy = $criteria->getGroupByColumns(); + $ignoreCase = $criteria->isIgnoreCase(); + $select = $criteria->getSelectColumns(); + $aliases = $criteria->getAsColumns(); + + // simple copy + $selectModifiers = $criteria->getSelectModifiers(); + + // get selected columns + foreach($select as $columnName) { + + // expect every column to be of "table.column" formation + // it could be a function: e.g. MAX(books.price) + + $tableName = null; + + $selectClause[] = $columnName; // the full column name: e.g. MAX(books.price) + + $parenPos = strpos($columnName, '('); + $dotPos = strpos($columnName, '.'); + + // [HL] I think we really only want to worry about adding stuff to + // the fromClause if this function has a TABLE.COLUMN in it at all. + // e.g. COUNT(*) should not need this treatment -- or there needs to + // be special treatment for '*' + if ($dotPos !== false) { + + if ($parenPos === false) { // table.column + $tableName = substr($columnName, 0, $dotPos); + } else { // FUNC(table.column) + $tableName = substr($columnName, $parenPos + 1, $dotPos - ($parenPos + 1)); + // functions may contain qualifiers so only take the last + // word as the table name. + // COUNT(DISTINCT books.price) + $lastSpace = strpos($tableName, ' '); + if ($lastSpace !== false) { // COUNT(DISTINCT books.price) + $tableName = substr($tableName, $lastSpace + 1); + } + } + $tableName2 = $criteria->getTableForAlias($tableName); + if ($tableName2 !== null) { + $fromClause[] = $tableName2 . ' ' . $tableName; + } else { + $fromClause[] = $tableName; + } + + } // if $dotPost !== null + } + + // set the aliases + foreach($aliases as $alias => $col) { + $selectClause[] = $col . " AS " . $alias; + } + + // add the criteria to WHERE clause + // this will also add the table names to the FROM clause if they are not already + // invluded via a LEFT JOIN + foreach($criteria->keys() as $key) { + + $criterion = $criteria->getCriterion($key); + $someCriteria = $criterion->getAttachedCriterion(); + $someCriteriaLength = count($someCriteria); + $table = null; + for ($i=0; $i < $someCriteriaLength; $i++) { + $tableName = $someCriteria[$i]->getTable(); + + $table = $criteria->getTableForAlias($tableName); + if ($table !== null) { + $fromClause[] = $table . ' ' . $tableName; + } else { + $fromClause[] = $tableName; + $table = $tableName; + } + + $ignoreCase = + (($criteria->isIgnoreCase() + || $someCriteria[$i]->isIgnoreCase()) + && ($dbMap->getTable($table)->getColumn($someCriteria[$i]->getColumn())->getType() == "string" ) + ); + + $someCriteria[$i]->setIgnoreCase($ignoreCase); + } + + $criterion->setDB($db); + + $sb = ""; + $criterion->appendPsTo($sb, $params); + $whereClause[] = $sb; + + } + + // handle RIGHT (straight) joins + // Loop through the joins, + // joins with a null join type will be added to the FROM clause and the condition added to the WHERE clause. + // joins of a specified type: the LEFT side will be added to the fromClause and the RIGHT to the joinClause + // New Code. + foreach ((array) $criteria->getJoins() as $join) { // we'll only loop if there's actually something here + + // The join might have been established using an alias name + + $leftTable = $join->getLeftTableName(); + $leftTableAlias = ''; + if ($realTable = $criteria->getTableForAlias($leftTable)) { + $leftTableAlias = " $leftTable"; + $leftTable = $realTable; + } + + $rightTable = $join->getRightTableName(); + $rightTableAlias = ''; + if ($realTable = $criteria->getTableForAlias($rightTable)) { + $rightTableAlias = " $rightTable"; + $rightTable = $realTable; + } + + // determine if casing is relevant. + if ($ignoreCase = $criteria->isIgnoreCase()) { + $leftColType = $dbMap->getTable($leftTable)->getColumn($join->getLeftColumnName())->getType(); + $rightColType = $dbMap->getTable($rightTable)->getColumn($join->getRightColumnName())->getType(); + $ignoreCase = ($leftColType == 'string' || $rightColType == 'string'); + } + + // build the condition + if ($ignoreCase) { + $condition = $db->ignoreCase($join->getLeftColumn()) . '=' . $db->ignoreCase($join->getRightColumn()); + } else { + $condition = $join->getLeftColumn() . '=' . $join->getRightColumn(); + } + + // add 'em to the queues.. + if ($joinType = $join->getJoinType()) { + if (!$fromClause) { + $fromClause[] = $leftTable . $leftTableAlias; + } + $joinTables[] = $rightTable . $rightTableAlias; + $joinClause[] = $join->getJoinType() . ' ' . $rightTable . $rightTableAlias . " ON ($condition)"; + } else { + $fromClause[] = $leftTable . $leftTableAlias; + $fromClause[] = $rightTable . $rightTableAlias; + $whereClause[] = $condition; + } + } + + /****************************************************************************************************************/ + /****************************************************************************************************************/ + // handle RIGHT (straight) joins with multiple conditions + // Loop through the joins, + // joins with a null join type will be added to the FROM clause and the condition added to the WHERE clause. + // joins of a specified type: the LEFT side will be added to the fromClause and the RIGHT to the joinClause + // Custom Code. + foreach ((array) $criteria->getJoinsMC() as $join) { // we'll only loop if there's actually something here + // The join might have been established using an alias name + $leftTable = $join->getLeftTableName($join->conditions[0][0]); + $leftTableAlias = ''; + if ($realTable = $criteria->getTableForAlias($leftTable)) { + $leftTableAlias = " $leftTable"; + $leftTable = $realTable; + } + + $rightTable = $join->getRightTableName($join->conditions[0][1]); + $rightTableAlias = ''; + if ($realTable = $criteria->getTableForAlias($rightTable)) { + $rightTableAlias = " $rightTable"; + $rightTable = $realTable; + } + + $condition = ''; + foreach ($join->conditions as $aCondition) { + // determine if casing is relevant. + if ($ignoreCase = $criteria->isIgnoreCase()) { + $leftColType = $dbMap->getTable($leftTable)->getColumn($join->getLeftColumnName($aCondition[0]))->getType(); + $rightColType = $dbMap->getTable($rightTable)->getColumn($join->getRightColumnName($aCondition[1]))->getType(); + $ignoreCase = ($leftColType == 'string' || $rightColType == 'string'); + } + + // build the condition + if ($ignoreCase) { + $condition .= $db->ignoreCase($aCondition[0]) . '=' . $db->ignoreCase($aCondition[1]) . ' AND '; + } else { + $condition .= $aCondition[0] . '=' . $aCondition[1] . ' AND '; + } + } + $condition = substr($condition, 0, -5); + + // add 'em to the queues.. + if ($joinType = $join->getJoinType()) { + if (!$fromClause) { + $fromClause[] = $leftTable . $leftTableAlias; + } + $joinTables[] = $rightTable . $rightTableAlias; + $joinClause[] = $join->getJoinType() . ' ' . $rightTable . $rightTableAlias . " ON ($condition)"; + } else { + $fromClause[] = $leftTable . $leftTableAlias; + $fromClause[] = $rightTable . $rightTableAlias; + $whereClause[] = $condition; + } + + } + /****************************************************************************************************************/ + /****************************************************************************************************************/ + + // Unique from clause elements + $fromClause = array_unique($fromClause); + + // tables should not exist in both the from and join clauses + if ($joinTables && $fromClause) { + foreach ($fromClause as $fi => $ftable) { + if (in_array($ftable, $joinTables)) { + unset($fromClause[$fi]); + } + } + } +/* + // Old Code. + $joins =& $criteria->getJoins(); + if (!empty($joins)) { + for ($i=0, $joinSize=count($joins); $i < $joinSize; $i++) { + $join =& $joins[$i]; + $join1 = $join->getLeftColumn(); + $join2 = $join->getRightColumn(); + + $tableName = substr($join1, 0, strpos($join1, '.')); + $table = $criteria->getTableForAlias($tableName); + if ($table !== null) { + $fromClause[] = $table . ' ' . $tableName; + } else { + $fromClause[] = $tableName; + } + + $dot = strpos($join2, '.'); + $tableName = substr($join2, 0, $dot); + $table = $criteria->getTableForAlias($tableName); + if ($table !== null) { + $fromClause[] = $table . ' ' . $tableName; + } else { + $fromClause[] = $tableName; + $table = $tableName; + } + $ignoreCase = ($criteria->isIgnoreCase() && ($dbMap->getTable($table)->getColumn(substr($join2, $dot + 1))->getType() == "string")); + if ($ignoreCase) { + $whereClause[] = $db->ignoreCase($join1) . '=' . $db->ignoreCase($join2); + } else { + $whereClause[] = $join1 . '=' . $join2; + } + if ($join->getJoinType()) { + $leftTable = $fromClause[count($fromClause) - 2]; + $rightTable = $fromClause[count($fromClause) - 1]; + $onClause = $whereClause[count($whereClause) - 1]; + unset($whereClause[count($whereClause) - 1]); + $fromClause [] = $leftTable . ' ' . $join->getJoinType() . ' ' . $rightTable . ' ON ' . $onClause; + + // remove all references to joinTables made by selectColumns, criteriaColumns + for ($i = 0, $fromClauseSize=count($fromClause); $i < $fromClauseSize; $i++) { + if ($fromClause[$i] == $leftTable || $fromClause[$i] == $rightTable) { + unset($fromClause[$i]); + } + } + } // If join type + } // Join for loop + } // If Joins +*/ + + // Add the GROUP BY columns + $groupByClause = $groupBy; + + $having = $criteria->getHaving(); + $havingString = null; + if ($having !== null) { + $sb = ""; + $having->appendPsTo($sb, $params); + $havingString = $sb; + } + + if (!empty($orderBy)) { + + foreach($orderBy as $orderByColumn) { + + // Add function expression as-is. + + if (strpos($orderByColumn, '(') !== false) { + $orderByClause[] = $orderByColumn; + continue; + } + + // Split orderByColumn (i.e. "table.column DESC") + + $dotPos = strpos($orderByColumn, '.'); + + if ($dotPos !== false) { + $tableName = substr($orderByColumn, 0, $dotPos); + $columnName = substr($orderByColumn, $dotPos+1); + } + else { + $tableName = ''; + $columnName = $orderByColumn; + } + + $spacePos = strpos($columnName, ' '); + + if ($spacePos !== false) { + $direction = substr($columnName, $spacePos); + $columnName = substr($columnName, 0, $spacePos); + } + else { + $direction = ''; + } + + $tableAlias = $tableName; + if ($aliasTableName = $criteria->getTableForAlias($tableName)) { + $tableName = $aliasTableName; + } + + $columnAlias = $columnName; + if ($asColumnName = $criteria->getColumnForAs($columnName)) { + $columnName = $asColumnName; + } + + $column = $tableName ? $dbMap->getTable($tableName)->getColumn($columnName) : null; + + if ($column && $column->getType() == 'string') { + $orderByClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias") . $direction; + $selectClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias"); + } + else { + $orderByClause[] = $orderByColumn; + } + } + } + + // Build the SQL from the arrays we compiled + $sql = "SELECT " + .($selectModifiers ? implode(" ", $selectModifiers) . " " : "") + .implode(", ", $selectClause) + ." FROM ". ( (!empty($joinClause) && count($fromClause) > 1 && (substr(get_class($db), 0, 7) == 'DBMySQL')) ? "(" . implode(", ", $fromClause) . ")" : implode(", ", $fromClause) ) + .($joinClause ? ' ' . implode(' ', $joinClause) : '') + .($whereClause ? " WHERE ".implode(" AND ", $whereClause) : "") + .($groupByClause ? " GROUP BY ".implode(",", $groupByClause) : "") + .($havingString ? " HAVING ".$havingString : "") + .($orderByClause ? " ORDER BY ".implode(",", $orderByClause) : ""); + + Propel::log($sql . ' [LIMIT: ' . $criteria->getLimit() . ', OFFSET: ' . $criteria->getOffset() . ']', Propel::LOG_DEBUG); +//echo $sql . "\n\n"; + return $sql; + + } + + /** + * Builds a params array, like the kind populated by Criterion::appendPsTo(). + * This is useful for building an array even when it is not using the appendPsTo() method. + * @param array $columns + * @param Criteria $values + * @return array params array('column' => ..., 'table' => ..., 'value' => ...) + */ + private static function buildParams($columns, Criteria $values) { + $params = array(); + foreach($columns as $key) { + if ($values->containsKey($key)) { + $crit = $values->getCriterion($key); + $params[] = array('column' => $crit->getColumn(), 'table' => $crit->getTable(), 'value' => $crit->getValue()); + } + } + return $params; + } + + /** + * Populates values in a prepared statement. + * + * @param PreparedStatement $stmt + * @param array $params array('column' => ..., 'table' => ..., 'value' => ...) + * @param DatabaseMap $dbMap + * @return int The number of params replaced. + */ + private static function populateStmtValues($stmt, $params, DatabaseMap $dbMap) + { + $i = 1; + foreach($params as $param) { + $tableName = $param['table']; + $columnName = $param['column']; + $value = $param['value']; + + if ($value === null) { + $stmt->setNull($i++); + } else { + $cMap = $dbMap->getTable($tableName)->getColumn($columnName); + $setter = 'set' . CreoleTypes::getAffix($cMap->getCreoleType()); + $stmt->$setter($i++, $value); + } + } // foreach + } + + /** + * This function searches for the given validator $name under propel/validator/$name.php, + * imports and caches it. + * + * @param string $classname The dot-path name of class (e.g. myapp.propel.MyValidator) + * @return Validator object or null if not able to instantiate validator class (and error will be logged in this case) + */ + public static function getValidator($classname) + { + try { + $v = isset(self::$validatorMap[$classname]) ? self::$validatorMap[$classname] : null; + if ($v === null) { + $cls = Propel::import($classname); + $v = new $cls(); + self::$validatorMap[$classname] = $v; + } + return $v; + } catch (Exception $e) { + Propel::log("BasePeer::getValidator(): failed trying to instantiate " . $classname . ": ".$e->getMessage(), Propel::LOG_ERR); + } + } + + /** + * This method returns the MapBuilder specified in the name + * parameter. You should pass in the full dot-path path to the class, ie: + * myapp.propel.MyMapMapBuilder. The MapBuilder instances are cached in + * this class for speed. + * + * @param string $classname The dot-path name of class (e.g. myapp.propel.MyMapBuilder) + * @return MapBuilder or null (and logs the error) if the MapBuilder was not found. + * @todo -cBasePeer Consider adding app-level caching support for map builders. + */ + public static function getMapBuilder($classname) + { + try { + $mb = isset(self::$mapBuilders[$classname]) ? self::$mapBuilders[$classname] : null; + if ($mb === null) { + $cls = Propel::import($classname); + $mb = new $cls(); + self::$mapBuilders[$classname] = $mb; + } + if (!$mb->isBuilt()) { + $mb->doBuild(); + } + return $mb; + } catch (Exception $e) { + // Have to catch possible exceptions because method is + // used in initialization of Peers. Log the exception and + // return null. + Propel::log("BasePeer::getMapBuilder() failed trying to instantiate " . $classname . ": " . $e->getMessage(), Propel::LOG_ERR); + } + } + +} diff --git a/gulliver/thirdparty/propel/util/Criteria.php b/gulliver/thirdparty/propel/util/Criteria.php new file mode 100644 index 000000000..744baea66 --- /dev/null +++ b/gulliver/thirdparty/propel/util/Criteria.php @@ -0,0 +1,1922 @@ +. + */ + +/** + * This is a utility class for holding criteria information for a query. + * + * BasePeer constructs SQL statements based on the values in this class. + * + * @author Hans Lellelid (Propel) + * @author Kaspars Jaudzems (Propel) + * @author Frank Y. Kim (Torque) + * @author John D. McNally (Torque) + * @author Brett McLaughlin (Torque) + * @author Eric Dobbs (Torque) + * @author Henning P. Schmiedehausen (Torque) + * @author Sam Joseph (Torque) + * @version $Revision: 561 $ + * @package propel.util + */ +class Criteria implements IteratorAggregate { + + /** Comparison type. */ + const EQUAL = "="; + + /** Comparison type. */ + const NOT_EQUAL = "<>"; + + /** Comparison type. */ + const ALT_NOT_EQUAL = "!="; + + /** Comparison type. */ + const GREATER_THAN = ">"; + + /** Comparison type. */ + const LESS_THAN = "<"; + + /** Comparison type. */ + const GREATER_EQUAL = ">="; + + /** Comparison type. */ + const LESS_EQUAL = "<="; + + /** Comparison type. */ + const LIKE = " LIKE "; + + /** Comparison type. */ + const NOT_LIKE = " NOT LIKE "; + + /** PostgreSQL comparison type */ + const ILIKE = " ILIKE "; + + /** PostgreSQL comparison type */ + const NOT_ILIKE = " NOT ILIKE "; + + /** Comparison type. */ + const CUSTOM = "CUSTOM"; + + /** Comparison type. */ + const DISTINCT = "DISTINCT "; + + /** Comparison type. */ + const IN = " IN "; + + /** Comparison type. */ + const NOT_IN = " NOT IN "; + + /** Comparison type. */ + const ALL = "ALL "; + + /** Comparison type. */ + const JOIN = "JOIN"; + + /** Binary math operator: AND */ + const BINARY_AND = "&"; + + /** Binary math operator: OR */ + const BINARY_OR = "|"; + + /** "Order by" qualifier - ascending */ + const ASC = "ASC"; + + /** "Order by" qualifier - descending */ + const DESC = "DESC"; + + /** "IS NULL" null comparison */ + const ISNULL = " IS NULL "; + + /** "IS NOT NULL" null comparison */ + const ISNOTNULL = " IS NOT NULL "; + + /** "CURRENT_DATE" ANSI SQL function */ + const CURRENT_DATE = "CURRENT_DATE"; + + /** "CURRENT_TIME" ANSI SQL function */ + const CURRENT_TIME = "CURRENT_TIME"; + + /** "CURRENT_TIMESTAMP" ANSI SQL function */ + const CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP"; + + /** "LEFT JOIN" SQL statement */ + const LEFT_JOIN = "LEFT JOIN"; + + /** "RIGHT JOIN" SQL statement */ + const RIGHT_JOIN = "RIGHT JOIN"; + + /** "INNER JOIN" SQL statement */ + const INNER_JOIN = "INNER JOIN"; + + private $ignoreCase = false; + private $singleRecord = false; + private $selectModifiers = array(); + private $selectColumns = array(); + private $orderByColumns = array(); + private $groupByColumns = array(); + private $having = null; + private $asColumns = array(); + private $joins = array(); + /******************************************************************************************************************/ + /******************************************************************************************************************/ + private $joinsMC = array(); + /******************************************************************************************************************/ + /******************************************************************************************************************/ + + /** The name of the database. */ + private $dbName; + public $dbArrayTable; + + /** The name of the database as given in the contructor. */ + private $originalDbName; + + /** + * To limit the number of rows to return. 0 means return all + * rows. + */ + private $limit = 0; + + /** To start the results at a row other than the first one. */ + private $offset = 0; + + // flag to note that the criteria involves a blob. + private $blobFlag = null; + + private $aliases = array(); + + private $useTransaction = false; + + /** + * Primary storage of criteria data. + * @var array + */ + private $map = array(); + + /** + * Creates a new instance with the default capacity which corresponds to + * the specified database. + * + * @param dbName The dabase name. + */ + public function __construct($dbName = null) + { + $this->setDbName($dbName); + $this->originalDbName = $dbName; + } + + /** + * Implementing SPL IteratorAggregate interface. This allows + * you to foreach() over a Criteria object. + */ + public function getIterator() + { + return new CriterionIterator($this); + } + + /** + * Get the criteria map. + * @return array + */ + public function getMap() + { + return $this->map; + } + + /** + * Brings this criteria back to its initial state, so that it + * can be reused as if it was new. Except if the criteria has grown in + * capacity, it is left at the current capacity. + * @return void + */ + public function clear() + { + $this->map = array(); + $this->ignoreCase = false; + $this->singleRecord = false; + $this->selectModifiers = array(); + $this->selectColumns = array(); + $this->orderByColumns = array(); + $this->groupByColumns = array(); + $this->having = null; + $this->asColumns = array(); + $this->joins = array(); + /******************************************************************************************************************/ + /******************************************************************************************************************/ + $this->joinsMC = array(); + /******************************************************************************************************************/ + /******************************************************************************************************************/ + $this->dbName = $this->originalDbName; + $this->offset = 0; + $this->limit = -1; + $this->blobFlag = null; + $this->aliases = array(); + $this->useTransaction = false; + } + + /** + * Add an AS clause to the select columns. Usage: + * + * + * Criteria myCrit = new Criteria(); + * myCrit->addAsColumn("alias", "ALIAS(".MyPeer::ID.")"); + * + * + * @param string $name Wanted Name of the column (alias). + * @param string $clause SQL clause to select from the table + * + * If the name already exists, it is replaced by the new clause. + * + * @return Criteria A modified Criteria object. + */ + public function addAsColumn($name, $clause) + { + $this->asColumns[$name] = $clause; + return $this; + } + + /** + * Get the column aliases. + * + * @return array An assoc array which map the column alias names + * to the alias clauses. + */ + public function getAsColumns() + { + return $this->asColumns; + } + + /** + * Returns the column name associated with an alias (AS-column). + * + * @param string $alias + * @return string $string + */ + public function getColumnForAs($as) + { + if (isset($this->asColumns[$as])) { + return $this->asColumns[$as]; + } + } + + /** + * Allows one to specify an alias for a table that can + * be used in various parts of the SQL. + * + * @param string $alias + * @param string $table + * @return void + */ + public function addAlias($alias, $table) + { + $this->aliases[$alias] = $table; + } + + /** + * Returns the table name associated with an alias. + * + * @param string $alias + * @return string $string + */ + public function getTableForAlias($alias) + { + if (isset($this->aliases[$alias])) { + return $this->aliases[$alias]; + } + } + + /** + * Get the keys for the criteria map. + * @return array + */ + public function keys() + { + return array_keys($this->map); + } + + /** + * Does this Criteria object contain the specified key? + * + * @param string $column [table.]column + * @return boolean True if this Criteria object contain the specified key. + */ + public function containsKey($column) + { + // must use array_key_exists() because the key could + // exist but have a NULL value (that'd be valid). + return array_key_exists($column, $this->map); + } + + /** + * Will force the sql represented by this criteria to be executed within + * a transaction. This is here primarily to support the oid type in + * postgresql. Though it can be used to require any single sql statement + * to use a transaction. + * @return void + */ + public function setUseTransaction($v) + { + $this->useTransaction = (boolean) $v; + } + + /** + * called by BasePeer to determine whether the sql command specified by + * this criteria must be wrapped in a transaction. + * + * @return a boolean value + */ + public function isUseTransaction() + { + return $this->useTransaction; + } + + /** + * Method to return criteria related to columns in a table. + * + * @param string $column Column name. + * @return A Criterion or null if $column is invalid. + */ + public function getCriterion($column) + { + if (isset($this->map[$column])) { + return $this->map[$column]; + } + } + + /** + * Method to return criterion that is not added automatically + * to this Criteria. This can be used to chain the + * Criterions to form a more complex where clause. + * + * @param column String full name of column (for example TABLE.COLUMN). + * @param mixed $value + * @param string $comparison + * @return A Criterion. + */ + public function getNewCriterion($column, $value, $comparison = null) + { + return new Criterion($this, $column, $value, $comparison); + } + + /** + * Method to return a String table name. + * + * @param name A String with the name of the key. + * @return A String with the value of the object at key. + */ + public function getColumnName($name) + { + if ( isset ( $this->map[$name] ) ) { + return $this->map[$name]->getColumn(); + } + return null; + } + + public function getTables() + {//var_dump($this->joins); + $aTables = array(); + foreach ($this->selectColumns as $k => $v) + { + $aAux = explode('.', $v); + if (count($aAux) == 2) { + if (!in_array($aAux[0], $aTables)) { + $aTables[] = $aAux[0]; + } + } + } + foreach ($this->joins as $v) { + $aAux = explode('.', $v->leftColumn); + if (count($aAux) == 2) { + if (!in_array($aAux[0], $aTables)) { + $aTables[] = $aAux[0]; + } + } + $aAux = explode('.', $v->rightColumn); + if (count($aAux) == 2) { + if (!in_array($aAux[0], $aTables)) { + $aTables[] = $aAux[0]; + } + } + } + foreach ($this->joinsMC as $v) { + foreach ($v as $cs) { + foreach ($cs as $c) { + $aAux = explode('.', $c[0]); + if (count($aAux) == 2) { + if (!in_array($aAux[0], $aTables)) { + $aTables[] = $aAux[0]; + } + } + } + } + } + $aWhere = $this->getTablesColumns(); + foreach ($aWhere as $c) { + foreach ($c as $t) { + $aAux = explode('.', $t); + if (count($aAux) == 2) { + if (!in_array($aAux[0], $aTables)) { + $aTables[] = $aAux[0]; + } + } + } + } + return $aTables; + } + + /** + * Shortcut method to get an array of columns indexed by table. + * @return array array(table => array(table.column1, table.column2)) + */ + public function getTablesColumns() + { + $tables = array(); + foreach ( array_keys ( $this->map ) as $key) { + $t = substr ( $key, 0, strpos ( $key, '.' ) ); + if ( ! isset ( $tables[$t] ) ) { + $tables[$t] = array( $key ); + } else { + $tables[$t][] = $key; + } + } + return $tables; + } + + /** + * Method to return a comparison String. + * + * @param string $key String name of the key. + * @return string A String with the value of the object at key. + */ + public function getComparison($key) + { + if ( isset ( $this->map[$key] ) ) { + return $this->map[$key]->getComparison(); + } + return null; + } + + /** + * Get the Database(Map) name. + * + * @return string A String with the Database(Map) name. + */ + public function getDbName() + { + return $this->dbName; + } + + /** + * Set the DatabaseMap name. If null is supplied, uses value + * provided by Propel::getDefaultDB(). + * + * @param $dbName A String with the Database(Map) name. + * @return void + */ + public function setDbName($dbName = null) + { + $this->dbName = ($dbName === null ? Propel::getDefaultDB() : $dbName); + } + + public function setDBArrayTable ( $name = null ) { + global $_DBArray; + if ( !isset ( $_DBArray[$name] ) ) { + throw new Exception ( "Error: the table '$tableName' doesn't exists in DBArray " ); + } + + $this->dbArrayTable = $name; + } + public function getDBArrayTable() + { + if ( isset ( $this->dbArrayTable ) ) { + return $this->dbArrayTable ; + } + return null; + } + + /** + * Method to return a String table name. + * + * @param $name A String with the name of the key. + * @return string A String with the value of table for criterion at key. + */ + public function getTableName($name) + { + if ( isset ( $this->map[$name] ) ) { + return $this->map[$name]->getTable(); + } + return null; + } + + /** + * Method to return the value that was added to Criteria. + * + * @param string $name A String with the name of the key. + * @return mixed The value of object at key. + */ + public function getValue($name) + { + if ( isset ( $this->map[$name] ) ) { + return $this->map[$name]->getValue(); + } + return null; + } + + /** + * An alias to getValue() -- exposing a Hashtable-like interface. + * + * @param string $key An Object. + * @return mixed The value within the Criterion (not the Criterion object). + */ + public function get($key) + { + return $this->getValue($key); + } + + /** + * Overrides Hashtable put, so that this object is returned + * instead of the value previously in the Criteria object. + * The reason is so that it more closely matches the behavior + * of the add() methods. If you want to get the previous value + * then you should first Criteria.get() it yourself. Note, if + * you attempt to pass in an Object that is not a String, it will + * throw a NPE. The reason for this is that none of the add() + * methods support adding anything other than a String as a key. + * + * @param string $key + * @param mixed $value + * @return Instance of self. + */ + public function put($key, $value) + { + return $this->add($key, $value); + } + + /** + * Copies all of the mappings from the specified Map to this Criteria + * These mappings will replace any mappings that this Criteria had for any + * of the keys currently in the specified Map. + * + * if the map was another Criteria, its attributes are copied to this + * Criteria, overwriting previous settings. + * + * @param mixed $t Mappings to be stored in this map. + */ + public function putAll($t) + { + if (is_array($t)) { + + foreach ($t as $key=>$value) { + + if ($value instanceof Criterion) { + + $this->map[$key] = $value; + + } else { + + $this->put($key, $value); + + } + + } + + } elseif ($t instanceof Criteria) { + + $this->joins = $t->joins; + /******************************************************************************************************************/ + /******************************************************************************************************************/ + $this->joinsMC = $t->joinsMC; + /******************************************************************************************************************/ + /******************************************************************************************************************/ + } + + } + + + /** + * This method adds a new criterion to the list of criterias. + * If a criterion for the requested column already exists, it is + * replaced. If is used as follow: + * + *

    + * + * $crit = new Criteria(); + * $crit->add("column", + * "value" + * "Criteria::GREATER_THAN"); + * + * + * Any comparison can be used. + * + * The name of the table must be used implicitly in the column name, + * so the Column name must be something like 'TABLE.id'. If you + * don't like this, you can use the add(table, column, value) method. + * + * @param string $critOrColumn The column to run the comparison on, or Criterion object. + * @param mixed $value + * @param string $comparison A String. + * + * @return A modified Criteria object. + */ + public function add($p1, $value = null, $comparison = null) + { + if ($p1 instanceof Criterion) { + $c = $p1; + $this->map[$c->getTable() . '.' . $c->getColumn()] = $c; + } else { + $column = $p1; + $this->map[$column] = new Criterion($this, $column, $value, $comparison); + } + return $this; + } + + /** + * This is the way that you should add a straight (inner) join of two tables. For + * example: + * + *

    + * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID + *

    + * + * left = PROJECT.PROJECT_ID + * right = FOO.PROJECT_ID + * + * @param string $left A String with the left side of the join. + * @param string $right A String with the right side of the join. + * @param string $operator A String with the join operator e.g. LEFT JOIN, ... + * @return Criteria A modified Criteria object. + */ + public function addJoin($left, $right, $operator = null) + { + $this->joins [] = new Join($left, $right, $operator); + + return $this; + } + + /******************************************************************************************************************/ + /******************************************************************************************************************/ + /** + * @param array $conditions A array with the conditions of the join. + * @param string $operator A String with the join operator e.g. LEFT JOIN, ... + * @return Criteria A modified Criteria object. + */ + public function addJoinMC($conditions = array(), $operator = null) + { + $this->joinsMC [] = new JoinMC($conditions, $operator); + + return $this; + } + /******************************************************************************************************************/ + /******************************************************************************************************************/ + + /** + * Get the array of Joins. This method is meant to + * be called by BasePeer. + * @return an array which contains objects of type Join, + * or an empty array if the criteria does not contains any joins + */ + function & getJoins() + { + return $this->joins; + } + + /******************************************************************************************************************/ + /******************************************************************************************************************/ + /** + * Get the array of Joins with multiple conditions. This method is meant to + * be called by BasePeer. + * @return an array which contains objects of type Join, + * or an empty array if the criteria does not contains any joins + */ + function & getJoinsMC() + { + return $this->joinsMC; + } + /******************************************************************************************************************/ + /******************************************************************************************************************/ + + /** + * get one side of the set of possible joins. This method is meant to + * be called by BasePeer. + * @return array + * @deprecated This method is no longer used by BasePeer. + */ + public function getJoinL() + { + throw new PropelException("getJoinL() in Criteria is no longer supported!"); + } + + /** + * get one side of the set of possible joins. This method is meant to + * be called by BasePeer. + * @return array + * @deprecated This method is no longer used by BasePeer. + */ + public function getJoinR() + { + throw new PropelException("getJoinR() in Criteria is no longer supported!"); + } + + /** + * Adds "ALL " to the SQL statement. + * @return void + */ + public function setAll() + { + $this->selectModifiers[] = self::ALL; + } + + /** + * Adds "DISTINCT " to the SQL statement. + * @return void + */ + public function setDistinct() + { + $this->selectModifiers[] = self::DISTINCT; + } + + /** + * Sets ignore case. + * + * @param boolean $b True if case should be ignored. + * @return A modified Criteria object. + */ + public function setIgnoreCase($b) + { + $this->ignoreCase = (boolean) $b; + return $this; + } + + /** + * Is ignore case on or off? + * + * @return boolean True if case is ignored. + */ + public function isIgnoreCase() + { + return $this->ignoreCase; + } + + /** + * Set single record? Set this to true if you expect the query + * to result in only a single result record (the default behaviour is to + * throw a PropelException if multiple records are returned when the query + * is executed). This should be used in situations where returning multiple + * rows would indicate an error of some sort. If your query might return + * multiple records but you are only interested in the first one then you + * should be using setLimit(1). + * + * @param b set to true if you expect the query to select just + * one record. + * @return A modified Criteria object. + */ + public function setSingleRecord($b) + { + $this->singleRecord = (boolean) $b; + return $this; + } + + /** + * Is single record? + * + * @return boolean True if a single record is being returned. + */ + public function isSingleRecord() + { + return $this->singleRecord; + } + + /** + * Set limit. + * + * @param limit An int with the value for limit. + * @return A modified Criteria object. + */ + public function setLimit($limit) + { + $this->limit = $limit; + return $this; + } + + /** + * Get limit. + * + * @return int An int with the value for limit. + */ + public function getLimit() + { + return $this->limit; + } + + /** + * Set offset. + * + * @param int $offset An int with the value for offset. + * @return A modified Criteria object. + */ + public function setOffset($offset) + { + $this->offset = $offset; + return $this; + } + + /** + * Get offset. + * + * @return An int with the value for offset. + */ + public function getOffset() + { + return $this->offset; + } + + /** + * Add select column. + * + * @param name A String with the name of the select column. + * @return A modified Criteria object. + */ + public function addSelectColumn($name) + { + $this->selectColumns[] = $name; + return $this; + } + + /** + * Get select columns. + * + * @return array An array with the name of the select + * columns. + */ + public function getSelectColumns() + { + return $this->selectColumns; + } + + /** + * Clears current select columns. + * + * @return Criteria A modified Criteria object. + */ + public function clearSelectColumns() { + $this->selectColumns = array(); + $this->asColumns = array(); + return $this; + } + + /** + * Get select modifiers. + * + * @return An array with the select modifiers. + */ + public function getSelectModifiers() + { + return $this->selectModifiers; + } + + /** + * Add group by column name. + * + * @param string $groupBy The name of the column to group by. + * @return A modified Criteria object. + */ + public function addGroupByColumn($groupBy) + { + $this->groupByColumns[] = $groupBy; + return $this; + } + + /** + * Add order by column name, explicitly specifying ascending. + * + * @param name The name of the column to order by. + * @return A modified Criteria object. + */ + public function addAscendingOrderByColumn($name) + { + $this->orderByColumns[] = $name . ' ' . self::ASC; + return $this; + } + + /** + * Add order by column name, explicitly specifying descending. + * + * @param string $name The name of the column to order by. + * @return Criteria The modified Criteria object. + */ + public function addDescendingOrderByColumn($name) + { + $this->orderByColumns[] = $name . ' ' . self::DESC; + return $this; + } + + /** + * Get order by columns. + * + * @return array An array with the name of the order columns. + */ + public function getOrderByColumns() + { + return $this->orderByColumns; + } + + /** + * Clear the order-by columns. + * + * @return Criteria + */ + public function clearOrderByColumns() + { + $this->orderByColumns = array(); + return $this; + } + + /** + * Clear the group-by columns. + * + * @return Criteria + */ + public function clearGroupByColumns() + { + $this->groupByColumns = array(); + return $this; + } + + /** + * Get group by columns. + * + * @return array + */ + public function getGroupByColumns() + { + return $this->groupByColumns; + } + + /** + * Get Having Criterion. + * + * @return Criterion A Criterion object that is the having clause. + */ + public function getHaving() + { + return $this->having; + } + + /** + * Remove an object from the criteria. + * + * @param string $key A string with the key to be removed. + * @return mixed The removed value. + */ + public function remove($key) + { + $c = isset($this->map[$key]) ? $this->map[$key] : null; + unset($this->map[$key]); + if ($c instanceof Criterion) { + return $c->getValue(); + } + return $c; + } + + /** + * Build a string representation of the Criteria. + * + * @return string A String with the representation of the Criteria. + */ + public function toString() + { + $sb = "Criteria:: "; + + try { + + $sb .= "\nCurrent Query SQL (may not be complete or applicable): " + . BasePeer::createSelectSql($this, $params=array()); + + $sb .= "\nParameters to replace: " . var_export($params, true); + + } catch (Exception $exc) { + $sb .= "(Error: " . $exc->getMessage() . ")"; + } + + return $sb; + } + + /** + * Returns the size (count) of this criteria. + * @return int + */ + public function size() + { + return count($this->map); + } + + /** + * This method checks another Criteria to see if they contain + * the same attributes and hashtable entries. + * @return boolean + */ + public function equals($crit) + { + $isEquiv = false; + if ($crit === null || !($crit instanceof Criteria)) { + $isEquiv = false; + } elseif ($this === $crit) { + $isEquiv = true; + } elseif ($this->size() === $crit->size()) { + + // Important: nested criterion objects are checked + + $criteria = $crit; // alias + if ($this->offset === $criteria->getOffset() + && $this->limit === $criteria->getLimit() + && $this->ignoreCase === $criteria->isIgnoreCase() + && $this->singleRecord === $criteria->isSingleRecord() + && $this->dbName === $criteria->getDbName() + && $this->selectModifiers === $criteria->getSelectModifiers() + && $this->selectColumns === $criteria->getSelectColumns() + && $this->orderByColumns === $criteria->getOrderByColumns() + ) + { + $isEquiv = true; + foreach($criteria->keys() as $key) { + if ($this->containsKey($key)) { + $a = $this->getCriterion($key); + $b = $criteria->getCriterion($key); + if (!$a->equals($b)) { + $isEquiv = false; + break; + } + } else { + $isEquiv = false; + break; + } + } + } + } + return $isEquiv; + } + + /** + * This method adds a prepared Criterion object to the Criteria as a having clause. + * You can get a new, empty Criterion object with the + * getNewCriterion() method. + * + *

    + * + * $crit = new Criteria(); + * $c = $crit->getNewCriterion(BasePeer::ID, 5, Criteria::LESS_THAN); + * $crit->addHaving($c); + * + * + * @param having A Criterion object + * + * @return A modified Criteria object. + */ + public function addHaving(Criterion $having) + { + $this->having = $having; + return $this; + } + + /** + * This method adds a new criterion to the list of criterias. + * If a criterion for the requested column already exists, it is + * "AND"ed to the existing criterion. + * + * addAnd(column, value, comparison) + * + * $crit = $orig_crit->addAnd("column", + * "value" + * "Criterion::GREATER_THAN"); + * + * + * addAnd(column, value) + * + * $crit = $orig_crit->addAnd("column", "value"); + * + * + * addAnd(Criterion) + * + * $crit = new Criteria(); + * $c = $crit->getNewCriterion(BasePeer::ID, 5, Criteria::LESS_THAN); + * $crit->addAnd($c); + * + * + * Any comparison can be used, of course. + * + * + * @return Criteria A modified Criteria object. + */ + public function addAnd($p1, $p2 = null, $p3 = null) + { + if ($p3 !== null) { + // addAnd(column, value, comparison) + $oc = $this->getCriterion($p1); + $nc = new Criterion($this, $p1, $p2, $p3); + if ($oc === null) { + $this->map[$p1] = $nc; + } else { + $oc->addAnd($nc); + } + } elseif ($p2 !== null) { + // addAnd(column, value) + $this->addAnd($p1, $p2, self::EQUAL); + } elseif ($p1 instanceof Criterion) { + // addAnd(Criterion) + $c = $p1; + $oc = $this->getCriterion($c->getTable() . '.' . $c->getColumn()); + if ($oc === null) { + $this->add($c); + } else { + $oc->addAnd($c); + } + } elseif ($p2 === null && $p3 === null) { + // client has not specified $p3 (comparison) + // which means Criteria::EQUAL but has also specified $p2 == null + // which is a valid combination we should handle by creating "IS NULL" + $this->addAnd($p1, $p2, self::EQUAL); + } + return $this; + } + + /** + * This method adds a new criterion to the list of criterias. + * If a criterion for the requested column already exists, it is + * "OR"ed to the existing criterion. + * + * Any comparison can be used. + * + * Supports a number of different signatures: + * + * addOr(column, value, comparison) + * + * $crit = $orig_crit->addOr("column", + * "value" + * "Criterion::GREATER_THAN"); + * + * + * addOr(column, value) + * + * $crit = $orig_crit->addOr("column", "value"); + * + * + * addOr(Criterion) + * + * @return Criteria A modified Criteria object. + */ + public function addOr($p1, $p2 = null, $p3 = null) + { + if ($p3 !== null) { + // addOr(column, value, comparison) + $oc = $this->getCriterion($p1); + $nc = new Criterion($this, $p1, $p2, $p3); + if ($oc === null) { + $this->map[$p1] = $nc; + } else { + $oc->addOr($nc); + } + } elseif ($p2 !== null) { + // addOr(column, value) + $this->addOr($p1, $p2, self::EQUAL); + } elseif ($p1 instanceof Criterion) { + // addOr(Criterion) + $c = $p1; + $oc = $this->getCriterion($c->getTable() . '.' . $c->getColumn()); + if ($oc === null) { + $this->add($c); + } else { + $oc->addOr($c); + } + } elseif ($p2 === null && $p3 === null) { + // client has not specified $p3 (comparison) + // which means Criteria::EQUAL but has also specified $p2 == null + // which is a valid combination we should handle by creating "IS NULL" + $this->addOr($p1, $p2, self::EQUAL); + } + + return $this; + } +} + +// -------------------------------------------------------------------- +// Criterion Iterator class -- allows foreach($criteria as $criterion) +// -------------------------------------------------------------------- + +/** + * Class that implements SPL Iterator interface. This allows foreach() to + * be used w/ Criteria objects. Probably there is no performance advantage + * to doing it this way, but it makes sense -- and simpler code. + * + * @author Hans Lellelid + * @package propel.util + */ +class CriterionIterator implements Iterator { + + private $idx = 0; + private $criteria; + private $criteriaKeys; + private $criteriaSize; + + public function __construct($criteria) { + $this->criteria = $criteria; + $this->criteriaKeys = $criteria->keys(); + $this->criteriaSize = count($this->criteriaKeys); + } + + public function rewind() { + $this->idx = 0; + } + + public function valid() { + return $this->idx < $this->criteriaSize; + } + + public function key() { + return $this->criteriaKeys[$this->idx]; + } + + public function current() { + return $this->criteria->getCriterion($this->criteriaKeys[$this->idx]); + } + + public function next() { + $this->idx++; + } + +} + +// -------------------------------------------------------------------- +// Criterion "inner" class +// -------------------------------------------------------------------- + +/** + * This is an "inner" class that describes an object in the criteria. + * + * In Torque this is an inner class of the Criteria class. + * + * @author Hans Lellelid (Propel) + * @package propel.util + */ +class Criterion { + + const UND = " AND "; + const ODER = " OR "; + + /** Value of the CO. */ + private $value; + + /** Comparison value. + * @var SqlEnum + */ + public $comparison; + + /** Table name. */ + public $table; + + /** Real table name */ + private $realtable; + + /** Column name. */ + public $column; + + /** flag to ignore case in comparision */ + private $ignoreStringCase = false; + + /** + * The DBAdaptor which might be used to get db specific + * variations of sql. + */ + private $db; + + /** + * other connected criteria and their conjunctions. + */ + private $clauses = array(); + private $conjunctions = array(); + + /** "Parent" Criteria class */ + private $parent; + + /** + * Create a new instance. + * + * @param Criteria $parent The outer class (this is an "inner" class). + * @param string $column TABLE.COLUMN format. + * @param mixed $value + * @param string $comparison + */ + public function __construct(Criteria $outer, $column, $value, $comparison = null) + { + list($this->table, $this->column) = explode('.', $column); + $this->value = $value; + $this->comparison = ($comparison === null ? Criteria::EQUAL : $comparison); + $this->init($outer); + } + + /** + * Init some properties with the help of outer class + * @param Criteria $criteria The outer class + */ + public function init(Criteria $criteria) + { + //init $this->db + try { + $db = Propel::getDB($criteria->getDbName()); + $this->setDB($db); + } catch (Exception $e) { + // we are only doing this to allow easier debugging, so + // no need to throw up the exception, just make note of it. + Propel::log("Could not get a DBAdapter, generated sql may be wrong", Propel::LOG_ERR); + } + + //init $this->realtable + $realtable = $criteria->getTableForAlias($this->table); + if(!$realtable) $realtable = $this->table; + $this->realtable = $realtable; + + } + + /** + * Get the column name. + * + * @return string A String with the column name. + */ + public function getColumn() + { + return $this->column; + } + + /** + * Set the table name. + * + * @param name A String with the table name. + * @return void + */ + public function setTable($name) + { + $this->table = $name; + } + + /** + * Get the table name. + * + * @return string A String with the table name. + */ + public function getTable() + { + return $this->table; + } + + /** + * Get the comparison. + * + * @return string A String with the comparison. + */ + public function getComparison() + { + return $this->comparison; + } + + /** + * Get the value. + * + * @return mixed An Object with the value. + */ + public function getValue() + { + return $this->value; + } + + /** + * Get the value of db. + * The DBAdapter which might be used to get db specific + * variations of sql. + * @return DBAdapter value of db. + */ + public function getDB() + { + return $this->db; + } + + /** + * Set the value of db. + * The DBAdapter might be used to get db specific variations of sql. + * @param DBAdapter $v Value to assign to db. + * @return void + */ + public function setDB(DBAdapter $v) + { + $this->db = $v; + for($i=0, $_i=count($this->clauses); $i < $_i; $i++) { + $this->clauses[$i]->setDB($v); + } + } + + /** + * Sets ignore case. + * + * @param boolean $b True if case should be ignored. + * @return Criterion A modified Criterion object. + */ + public function setIgnoreCase($b) + { + $this->ignoreStringCase = $b; + return $this; + } + + /** + * Is ignore case on or off? + * + * @return boolean True if case is ignored. + */ + public function isIgnoreCase() + { + return $this->ignoreStringCase; + } + + /** + * Get the list of clauses in this Criterion. + * @return array + */ + private function getClauses() + { + return $this->clauses; + } + + /** + * Get the list of conjunctions in this Criterion + * @return array + */ + public function getConjunctions() + { + return $this->conjunctions; + } + + /** + * Append an AND Criterion onto this Criterion's list. + */ + public function addAnd(Criterion $criterion) + { + $this->clauses[] = $criterion; + $this->conjunctions[] = self::UND; + return $this; + } + + /** + * Append an OR Criterion onto this Criterion's list. + * @return Criterion + */ + public function addOr(Criterion $criterion) + { + $this->clauses[] = $criterion; + $this->conjunctions[] = self::ODER; + return $this; + } + + /** + * Appends a Prepared Statement representation of the Criterion + * onto the buffer. + * + * @param string &$sb The stringbuffer that will receive the Prepared Statement + * @param array $params A list to which Prepared Statement parameters + * will be appended + * @return void + * @throws PropelException - if the expression builder cannot figure out how to turn a specified + * expression into proper SQL. + */ + public function appendPsTo(&$sb, &$params) + { + if ($this->column === null) { + return; + } + + $db = $this->getDb(); + $sb .= str_repeat ( '(', count($this->clauses) ); + + if (Criteria::CUSTOM === $this->comparison) { + if ($this->value !== "") { + $sb .= (string) $this->value; + } + } else { + + if ($this->table === null) { + $field = $this->column; + } else { + $field = $this->table . '.' . $this->column; + } + + // Check to see if table is an alias & store real name, if so + // (real table name is needed for the returned $params array) + $realtable = $this->realtable; + + // There are several different types of expressions that need individual handling: + // IN/NOT IN, LIKE/NOT LIKE, and traditional expressions. + + // OPTION 1: table.column IN (?, ?) or table.column NOT IN (?, ?) + if ($this->comparison === Criteria::IN || $this->comparison === Criteria::NOT_IN) { + + $valuesLength = 0; + foreach ( (array) $this->value as $value ) { + $valuesLength++; + $params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $value); + } + if ( $valuesLength !== 0 ) { + $sb .= $field . $this->comparison . '(' . substr(str_repeat("?,", $valuesLength), 0, -1) . ')'; + } else { + $sb .= ($this->comparison === Criteria::IN) ? "1<>1" : "1=1"; + } + unset ( $value, $valuesLength ); + + + // OPTION 2: table.column LIKE ? or table.column NOT LIKE ? (or ILIKE for Postgres) + } elseif ($this->comparison === Criteria::LIKE || $this->comparison === Criteria::NOT_LIKE + || $this->comparison === Criteria::ILIKE || $this->comparison === Criteria::NOT_ILIKE) { + // Handle LIKE, NOT LIKE (and related ILIKE, NOT ILIKE for Postgres) + + // If selection is case insensitive use ILIKE for PostgreSQL or SQL + // UPPER() function on column name for other databases. + if ($this->ignoreStringCase) { + include_once 'propel/adapter/DBPostgres.php'; + if ($db instanceof DBPostgres) { + if ($this->comparison === Criteria::LIKE) { + $this->comparison = Criteria::ILIKE; + } elseif ($this->comparison === Criteria::NOT_LIKE) { + $this->comparison = Criteria::NOT_ILIKE; + } + } else { + $field = $db->ignoreCase($field); + } + } + + $sb .= $field . $this->comparison; + + // If selection is case insensitive use SQL UPPER() function + // on criteria or, if Postgres we are using ILIKE, so not necessary. + if ($this->ignoreStringCase && !($db instanceof DBPostgres)) { + $sb .= $db->ignoreCase('?'); + } else { + $sb .= '?'; + } + + $params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $this->value); + + // OPTION 3: table.column = ? or table.column >= ? etc. (traditional expressions, the default) + } else { + + // NULL VALUES need special treatment because the SQL syntax is different + // i.e. table.column IS NULL rather than table.column = null + if ($this->value !== null) { + + // ANSI SQL functions get inserted right into SQL (not escaped, etc.) + if ($this->value === Criteria::CURRENT_DATE || $this->value === Criteria::CURRENT_TIME || $this->value === Criteria::CURRENT_TIMESTAMP) { + $sb .= $field . $this->comparison . $this->value; + } else { + // default case, it is a normal col = value expression; value + // will be replaced w/ '?' and will be inserted later using native Creole functions + if ($this->ignoreStringCase) { + $sb .= $db->ignoreCase($field) . $this->comparison . $db->ignoreCase("?"); + } else { + $sb .= $field . $this->comparison . "?"; + } + // need to track the field in params, because + // we'll need it to determine the correct setter + // method later on (e.g. field 'review.DATE' => setDate()); + $params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $this->value); + } + } else { + + // value is null, which means it was either not specified or specifically + // set to null. + if ($this->comparison === Criteria::EQUAL || $this->comparison === Criteria::ISNULL) { + $sb .= $field . Criteria::ISNULL; + } elseif ($this->comparison === Criteria::NOT_EQUAL || $this->comparison === Criteria::ISNOTNULL) { + $sb .= $field . Criteria::ISNOTNULL; + } else { + // for now throw an exception, because not sure how to interpret this + throw new PropelException("Could not build SQL for expression: $field " . $this->comparison . " NULL"); + } + + } + + } + } + + foreach ( $this->clauses as $key=>$clause ) { + $sb .= $this->conjunctions[$key]; + $clause->appendPsTo($sb, $params); + $sb .= ')'; + } + } + + /** + * This method checks another Criteria to see if they contain + * the same attributes and hashtable entries. + * @return boolean + */ + public function equals($obj) + { + if ($this === $obj) { + return true; + } + + if (($obj === null) || !($obj instanceof Criterion)) { + return false; + } + + $crit = $obj; + + $isEquiv = ( ( ($this->table === null && $crit->getTable() === null) + || ( $this->table !== null && $this->table === $crit->getTable() ) + ) + && $this->column === $crit->getColumn() + && $this->comparison === $crit->getComparison()); + + // check chained criterion + + $clausesLength = count($this->clauses); + $isEquiv &= (count($crit->getClauses()) == $clausesLength); + $critConjunctions = $crit->getConjunctions(); + $critClauses = $crit->getClauses(); + for ($i=0; $i < $clausesLength && $isEquiv; $i++) { + $isEquiv &= ($this->conjunctions[$i] === $critConjunctions[$i]); + $isEquiv &= ($this->clauses[$i] === $critClauses[$i]); + } + + if ($isEquiv) { + $isEquiv &= $this->value === $crit->getValue(); + } + + return $isEquiv; + } + + /** + * Returns a hash code value for the object. + */ + public function hashCode() + { + $h = crc32(serialize($this->value)) ^ crc32($this->comparison); + + if ($this->table !== null) { + $h ^= crc32($this->table); + } + + if ($this->column !== null) { + $h ^= crc32($this->column); + } + + foreach ( $this->clauses as $clause ) { + // TODO: i KNOW there is a php incompatibility with the following line + // but i dont remember what it is, someone care to look it up and + // replace it if it doesnt bother us? + // $clause->appendPsTo($sb='',$params=array()); + $sb = ''; + $params = array(); + $clause->appendPsTo($sb,$params); + $h ^= crc32(serialize(array($sb,$params))); + unset ( $sb, $params ); + } + + return $h; + } + + /** + * Get all tables from nested criterion objects + * @return array + */ + public function getAllTables() + { + $tables = array(); + $this->addCriterionTable($this, $tables); + return $tables; + } + + /** + * method supporting recursion through all criterions to give + * us a string array of tables from each criterion + * @return void + */ + private function addCriterionTable(Criterion $c, &$s) + { + $s[] = $c->getTable(); + foreach ( $c->getClauses() as $clause ) { + $this->addCriterionTable($clause, $s); + } + } + + /** + * get an array of all criterion attached to this + * recursing through all sub criterion + * @return array Criterion[] + */ + public function getAttachedCriterion() + { + $crits = array(); + $this->traverseCriterion($this, $crits); + return $crits; + } + + /** + * method supporting recursion through all criterions to give + * us an array of them + * @param Criterion $c + * @param array &$a + * @return void + */ + private function traverseCriterion(Criterion $c, &$a) + { + $a[] = $c; + foreach ( $c->getClauses() as $clause ) { + $this->traverseCriterion($clause, $a); + } + } +} + +/** +* Data object to describe a join between two tables, for example +*

    +* table_a LEFT JOIN table_b ON table_a.id = table_b.a_id
    +* 
    +*/ +class Join +{ + /** the left column of the join condition */ + public $leftColumn = null; + + /** the right column of the join condition */ + public $rightColumn = null; + + /** the type of the join (LEFT JOIN, ...), or null */ + private $joinType = null; + + /** + * Constructor + * @param leftColumn the left column of the join condition; + * might contain an alias name + * @param rightColumn the right column of the join condition + * might contain an alias name + * @param joinType the type of the join. Valid join types are + * null (adding the join condition to the where clause), + * Criteria::LEFT_JOIN(), Criteria::RIGHT_JOIN(), and Criteria::INNER_JOIN() + */ + public function __construct($leftColumn, $rightColumn, $joinType = null) + { + $this->leftColumn = $leftColumn; + $this->rightColumn = $rightColumn; + $this->joinType = $joinType; + } + + /** + * @return the type of the join, i.e. Criteria::LEFT_JOIN(), ..., + * or null for adding the join condition to the where Clause + */ + public function getJoinType() + { + return $this->joinType; + } + + /** + * @return the left column of the join condition + */ + public function getLeftColumn() + { + return $this->leftColumn; + } + + public function getLeftColumnName() + { + return substr($this->leftColumn, strpos($this->leftColumn, '.') + 1); + } + + public function getLeftTableName() + { + return substr($this->leftColumn, 0, strpos($this->leftColumn, '.')); + } + + /** + * @return the right column of the join condition + */ + public function getRightColumn() + { + return $this->rightColumn; + } + + public function getRightColumnName() + { + return substr($this->rightColumn, strpos($this->rightColumn, '.') + 1); + } + + public function getRightTableName() + { + return substr($this->rightColumn, 0, strpos($this->rightColumn, '.')); + } + + /** + * returns a String representation of the class, + * mainly for debugging purposes + * @return a String representation of the class + */ + public function toString() + { + $result = ""; + if ($this->joinType != null) + { + $result .= $this->joinType . " : "; + } + $result .= $this->leftColumn . "=" . $this->rightColumn . " (ignoreCase not considered)"; + + return $result; + } +} + +/****************************************************************************************************************/ +/****************************************************************************************************************/ +/** +* Data object to describe a join between two tables with multiple conditions, for example +*
    +* table_a LEFT JOIN table_b ON table_a.id = table_b.a_id AND table_a.id2 = table_b.a_id2
    +* 
    +*/ +class JoinMC +{ + /** the conditions */ + public $conditions = null; + + /** the type of the join (LEFT JOIN, ...), or null */ + private $joinType = null; + + /** + * Constructor + * @param conditions + * @param joinType the type of the join. Valid join types are + * null (adding the join condition to the where clause), + * Criteria::LEFT_JOIN(), Criteria::RIGHT_JOIN(), and Criteria::INNER_JOIN() + */ + public function __construct($conditions, $joinType = null) + { + $this->conditions = $conditions; + $this->joinType = $joinType; + } + + /** + * @return the type of the join, i.e. Criteria::LEFT_JOIN(), ..., + * or null for adding the join condition to the where Clause + */ + public function getJoinType() + { + return $this->joinType; + } + + public function getLeftColumnName($sAux) + { + return substr($sAux, strpos($sAux, '.') + 1); + } + + public function getLeftTableName($sAux) + { + return substr($sAux, 0, strpos($sAux, '.')); + } + + public function getRightColumnName($sAux) + { + return substr($sAux, strpos($sAux, '.') + 1); + } + + public function getRightTableName($sAux) + { + return substr($sAux, 0, strpos($sAux, '.')); + } + + /** + * returns a String representation of the class, + * mainly for debugging purposes + * @return a String representation of the class + */ + public function toString() + { + $result = ""; + /*if ($this->joinType != null) + { + $result .= $this->joinType . " : "; + } + $result .= $this->leftColumn . "=" . $this->rightColumn . " (ignoreCase not considered)";*/ + + return $result; + } +} +/****************************************************************************************************************/ +/****************************************************************************************************************/ diff --git a/gulliver/thirdparty/propel/util/PeerInfo.php b/gulliver/thirdparty/propel/util/PeerInfo.php new file mode 100644 index 000000000..3b80cfb3c --- /dev/null +++ b/gulliver/thirdparty/propel/util/PeerInfo.php @@ -0,0 +1,188 @@ +. + */ + +/** + * Peer Helper Class + * + * Handle Dynamic Peer Access. Trying to solve the problems associated + * with looking at constants, calling methods on static Peer Objects + * + * @author David Giffin + * @copyright Copyright (c) 2000-2003 David Giffin : LGPL - See LICENCE + * @package propel.util + */ +class PeerInfo +{ + /** Propel Object Peers */ + private static $peers = array(); + + /** Reflection Objects of the Propel Peers */ + private static $reflections = array(); + + /** Table Maps of the Propel Peers */ + private static $maps = array(); + + + /** + * Add a Peer to the list of Peers + * + * @param string $peer The Propel Peer to add + */ + private static function addPeer($peer) + { + + + $peers = array_keys(self::$peers); + + if (!in_array($peer, $peers)) { + + self::$peers[$peer] = self::loadPeer($peer); + self::$reflections[$peer] = new reflectionClass($peer); + self::$maps[$peer] = null; + + } + } + + + /** + * Get a constant from the Peer Reflector + * + * @param String The name of the constant + * @return String The Constant String + */ + public static function getPeerConstant($peer, $name) + { + self::addPeer($peer); + return self::$reflections[$peer]->getConstant($name); + } + + + /** + * Get a Peer from the Peer List + * + * @param string $peer The Propel Peer to add + */ + public static function getPeer($peer) { + self::addPeer($peer); + return self::$peers[$peer]; + } + + + /** + * Load a Peer + * + * You may wat to override this method if your Peers + * are not in the include_path. + * + * @param string $peerName the name of the Peer + */ + public static function loadPeer($peerName) + { + $peerFile = $peerName . ".php"; + require_once($peerFile); + $peerObject = new $peerName(); + return $peerObject; + } + + + /** + * Get a Column Constant from a Peer + * + * @param string The PhpName or DB_NAME for the constant + * @return string the Column Constant + */ + public static function getColumnConstant($peer, $name) + { + self::addPeer($peer); + $map = self::getPeer($peer)->getPhpNameMap(); + foreach ($map as $phpName => $dbName) { + if ($phpName == $name) { + return self::getPeerConstant($peer, $dbName); + } else if ($dbName == $name) { + return self::getPeerConstant($peer, $dbName); + } + } + return null; + } + + + /** + * Get the Primary Key for this Peer + * + * @param string $peer The name of the Peer + * @return string The name of the Primary Key + */ + public static function getPrimaryKey($peer) + { + self::addPeer($peer); + $tableMap = self::getTableMap($peer); + $columns = $tableMap->getColumns(); + foreach ($columns as $columnName => $column) { + if ($column->isPrimaryKey()) { + return $columnName; + } + } + return null; + } + + + /** + * Get the Table Map for a Peer + * + * @param string $peer The name of the Peer + * @return TableMap The table map for this Peer + */ + public static function getTableMap($peer) + { + self::addPeer($peer); + if (!self::$maps[$peer]) { + $tableName = self::getTableName($peer); + $dbMap = self::getPeer($peer)->getMapBuilder()->getDatabaseMap(); + self::$maps[$peer] = $dbMap->getTable($tableName); + } + return self::$maps[$peer]; + } + + + public static function getTableName($peer) + { + self::addPeer($peer); + return self::getPeerConstant($peer, "TABLE_NAME"); + } + + + /** + * Call a Method from the Static Peer Class + * + * @param string $peer The name of the Peer + * @param string $method The name of the method to call + * @param array $params The parameters to pass to the method + * @return mixed What ever the method returns + */ + public static function callMethod($peer, $method, $params = null) + { + if ($params !== null) { + return call_user_func_array(array($peer, $method), $params); + } + return call_user_func(array($peer, $method)); + } + +} diff --git a/gulliver/thirdparty/propel/util/PropelPager.php b/gulliver/thirdparty/propel/util/PropelPager.php new file mode 100644 index 000000000..dc04ef9a1 --- /dev/null +++ b/gulliver/thirdparty/propel/util/PropelPager.php @@ -0,0 +1,543 @@ +. + */ + +/** + * PropelPager + * + * Example Usage: + * + * require_once 'propel/util/PropelPager.php'; + * require_once 'PEACH/Propel/Poem/poemPeer.php'; + * + * $c = new Criteria(); + * $c->addDescendingOrderByColumn(poemPeer::SID); + * + * // with join + * $pager = new PropelPager($c, 'poemPeer', 'doSelectJoinPoemUsers', 1, 50); + * + * // without Join + * + * $pager = new PropelPager($c, 'poemPeer', 'doSelect', 1, 50); + * + * Some template: + * + *

    + * Total Pages: getTotalPages()?> Total Records: getTotalRecordCount()?> + *

    + * + * + * + * + * + * + * + * + * + * + *
    + * getFirstPage):?> + * | + * + * + * getPrev()):?> + * Previous| + * + * + * getPrevLinks() as $link):?> + * | + * + * getPage()?> + * getNextLinks() as $link):?> + * | + * + * + * getNext()):?> + * Last| + * + * + * getLastPage()):?> + * | + * + *
    + * + * + * + * + * + * + * + * getResult() as $poem):?> + * + * + * + * + * + * + * + *
    TitleAuteurDatecomments
    getTitle()?>getPoemUsers()->getUname()?>getTime()?>getComments()?>
    + * + * + * @author Rob Halff + * @version $Revision: 536 $ + * @copyright Copyright (c) 2004 Rob Halff: LGPL - See LICENCE + * @package propel.util + */ +class PropelPager { + + private $recordCount; + private $pages; + private $peerClass; + private $peerSelectMethod; + private $peerCountMethod; + private $criteria; + private $countCriteria; + private $page; + private $rs = null; + + /** @var int Start row (offset) */ + protected $start = 0; + + /** @var int Max rows to return (0 means all) */ + protected $max = 0; + + /** + * Create a new Propel Pager. + * @param Criteria $c + * @param string $peerClass The name of the static Peer class. + * @param string $peerSelectMethod The name of the static method for selecting content from the Peer class. + * @param int $page The current page (1-based). + * @param int $rowsPerPage The number of rows that should be displayed per page. + */ + public function __construct($c = null, $peerClass = null, $peerSelectMethod = null, $page = 1, $rowsPerPage = 25) + { + if(!isset($c)) { + $c = new Criteria(); + } + $this->setCriteria($c); + $this->setPeerClass($peerClass); + $this->setPeerSelectMethod($peerSelectMethod); + $this->guessPeerCountMethod(); + $this->setPage($page); + $this->setRowsPerPage($rowsPerPage); + } + + /** + * Set the criteria for this pager. + * @param Criteria $c + * @return void + */ + public function setCriteria(Criteria $c) + { + $this->criteria = $c; + } + + /** + * Return the Criteria object for this pager. + * @return Criteria + */ + public function getCriteria() + { + return $this->criteria; + } + + /** + * Set the Peer Classname + * + * @param string $class + * @return void + */ + public function setPeerClass($class) + { + $this->peerClass = $class; + } + + /** + * Return the Peer Classname. + * @return string + */ + public function getPeerClass() + { + return $this->peerClass; + } + + /** + * Set the Peer select method. + * This exists for legacy support, please use setPeerSelectMethod(). + * @param string $method The name of the static method to call on the Peer class. + * @return void + * @see setPeerSelectMethod() + * @deprecated + */ + public function setPeerMethod($method) + { + $this->setPeerSelectMethod($method); + } + + /** + * Return the Peer select method. + * This exists for legacy support, please use getPeerSelectMethod(). + * @return string + * @see getPeerSelectMethod() + * @deprecated + */ + public function getPeerMethod() + { + return $this->getPeerSelectMethod(); + } + + /** + * Set the Peer select method. + * + * @param string $method The name of the static method to call on the Peer class. + * @return void + */ + public function setPeerSelectMethod($method) + { + $this->peerSelectMethod = $method; + } + + /** + * Return the Peer select method. + * @return string + */ + public function getPeerSelectMethod() + { + return $this->peerSelectMethod; + } + + /** + * Sets the Count method. + * This is set based on the Peer method, for example if Peer method is doSelectJoin*() then the + * count method will be doCountJoin*(). + * @param string $method The name of the static method to call on the Peer class. + */ + public function setPeerCountMethod($method) + { + $this->peerCountMethod = $method; + } + + /** + * Return the Peer count method. + */ + public function getPeerCountMethod() + { + return $this->peerCountMethod; + } + + /** + * Guesses the Peer count method based on the select method. + */ + private function guessPeerCountMethod() + { + $selectMethod = $this->getPeerSelectMethod(); + if ($selectMethod == 'doSelect') { + $countMethod = 'doCount'; + } elseif ( ($pos = stripos($selectMethod, 'doSelectJoin')) === 0) { + $countMethod = 'doCount' . substr($selectMethod, strlen('doSelect')); + } else { + // we will fall back to doCount() if we don't understand the join + // method; however, it probably won't be accurate. Maybe triggering an error would + // be appropriate ... + $countMethod = 'doCount'; + } + $this->setPeerCountMethod($countMethod); + } + + /** + * Get the paged resultset + * + * @return mixed $rs + */ + public function getResult() + { + if(!isset($this->rs)) { + $this->doRs(); + } + + return $this->rs; + } + + /** + * Get the paged resultset + * + * Main method which creates a paged result set based on the criteria + * and the requested peer select method. + * + */ + private function doRs() + { + $this->criteria->setOffset($this->start); + $this->criteria->setLimit($this->max); + $this->rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $this->criteria); + } + + /** + * Get the first page + * + * For now I can only think of returning 1 always. + * It should probably return 0 if there are no pages + * + * @return int 1 + */ + public function getFirstPage() + { + return '1'; + } + + /** + * Convenience method to indicate whether current page is the first page. + * + * @return boolean + */ + public function atFirstPage() + { + return $this->getPage() == $this->getFirstPage(); + } + + /** + * Get last page + * + * @return int $lastPage + */ + public function getLastPage() + { + $totalPages = $this->getTotalPages(); + if ($totalPages == 0) { + return 1; + } else { + return $totalPages; + } + } + + /** + * Convenience method to indicate whether current page is the last page. + * + * @return boolean + */ + public function atLastPage() + { + return $this->getPage() == $this->getLastPage(); + } + + /** + * get total pages + * + * @return int $this->pages + */ + public function getTotalPages() { + if(!isset($this->pages)) { + $recordCount = $this->getTotalRecordCount(); + if($this->max > 0) { + $this->pages = ceil($recordCount/$this->max); + } else { + $this->pages = 0; + } + } + return $this->pages; + } + + /** + * get an array of previous id's + * + * @param int $range + * @return array $links + */ + public function getPrevLinks($range = 5) + { + $total = $this->getTotalPages(); + $start = $this->getPage() - 1; + $end = $this->getPage() - $range; + $first = $this->getFirstPage(); + $links = array(); + for($i=$start; $i>$end; $i--) { + if($i < $first) { + break; + } + $links[] = $i; + } + + return array_reverse($links); + } + + /** + * get an array of next id's + * + * @param int $range + * @return array $links + */ + public function getNextLinks($range = 5) + { + $total = $this->getTotalPages(); + $start = $this->getPage() + 1; + $end = $this->getPage() + $range; + $last = $this->getLastPage(); + $links = array(); + for($i=$start; $i<$end; $i++) { + if($i > $last) { + break; + } + $links[] = $i; + } + + return $links; + } + + /** + * Returns whether last page is complete + * + * @return bool Last page complete or not + */ + public function isLastPageComplete() + { + return !($this->getTotalRecordCount() % $this->max); + } + + /** + * get previous id + * + * @return mixed $prev + */ + public function getPrev() { + if($this->getPage() != $this->getFirstPage()) { + $prev = $this->getPage() - 1; + } else { + $prev = false; + } + return $prev; + } + + /** + * get next id + * + * @return mixed $next + */ + public function getNext() { + if($this->getPage() != $this->getLastPage()) { + $next = $this->getPage() + 1; + } else { + $next = false; + } + return $next; + } + + /** + * Set the current page number (First page is 1). + * @param int $page + * @return void + */ + public function setPage($page) + { + $this->page = $page; + // (re-)calculate start rec + $this->calculateStart(); + } + + /** + * Get current page. + * @return int + */ + public function getPage() + { + return $this->page; + } + + /** + * Set the number of rows per page. + * @param int $r + */ + public function setRowsPerPage($r) + { + $this->max = $r; + // (re-)calculate start rec + $this->calculateStart(); + } + + /** + * Get number of rows per page. + * @return int + */ + public function getRowsPerPage() + { + return $this->max; + } + + /** + * Calculate startrow / max rows based on current page and rows-per-page. + * @return void + */ + private function calculateStart() + { + $this->start = ( ($this->page - 1) * $this->max ); + } + + /** + * Gets the total number of (un-LIMITed) records. + * + * This method will perform a query that executes un-LIMITed query. + * + * @return int Total number of records - disregarding page, maxrows, etc. + */ + public function getTotalRecordCount() + { + + if(!isset($this->rs)) { + $this->doRs(); + } + + if(empty($this->recordCount)) { + $this->countCriteria = clone $this->criteria; + $this->countCriteria->setLimit(0); + $this->countCriteria->setOffset(0); + + $this->recordCount = call_user_func( + array( + $this->getPeerClass(), + $this->getPeerCountMethod() + ), + $this->countCriteria + ); + + } + + return $this->recordCount; + + } + + /** + * Sets the start row or offset. + * @param int $v + */ + public function setStart($v) + { + $this->start = $v; + } + + /** + * Sets max rows (limit). + * @param int $v + * @return void + */ + public function setMax($v) + { + $this->max = $v; + } + +} diff --git a/gulliver/thirdparty/propel/util/Transaction.php b/gulliver/thirdparty/propel/util/Transaction.php new file mode 100644 index 000000000..2ed75e00d --- /dev/null +++ b/gulliver/thirdparty/propel/util/Transaction.php @@ -0,0 +1,160 @@ +. + */ + +/** + * Utility class to make it easier to begin, commit, and rollback transactions. + * + * This can be used to handle cases where transaction support is optional. + * The second parameter of beginOptionalTransaction() will determine with a transaction + * is used or not. If a transaction is not used, the commit and rollback methods + * do not have any effect. Instead it simply makes the logic easier to follow + * by cutting down on the if statements based solely on whether a transaction + * is needed or not. + * + * @author Hans Lellelid (Propel) + * @author Stephen Haberman (Torque) + * @version $Revision: 536 $ + * @package propel.util + */ +class Transaction { + + /** + * Begin a transaction. This method will fallback gracefully to + * return a normal connection, if the database being accessed does + * not support transactions. + * + * @param string $dbName Name of database. + * @return Connection The Connection for the transaction. + * @throws PropelException + */ + public static function begin($dbName) + { + $con = Propel::getConnection($dbName); + try { + $con->setAutoCommit(false); + } catch (SQLException $e) { + throw new PropelException($e); + } + return $con; + } + + /** + * Begin a transaction. This method will fallback gracefully to + * return a normal connection, if the database being accessed does + * not support transactions. + * + * @param sring $dbName Name of database. + * @param boolean $useTransaction If false, a transaction won't be used. + * @return Connection The Connection for the transaction. + * @throws PropelException + */ + public static function beginOptional($dbName, $useTransaction) + { + $con = Propel::getConnection($dbName); + try { + if ($useTransaction) { + $con->setAutoCommit(false); + } + } catch (SQLException $e) { + throw new PropelException($e); + } + return $con; + } + + /** + * Commit a transaction. This method takes care of releasing the + * connection after the commit. In databases that do not support + * transactions, it only returns the connection. + * + * @param Connection $con The Connection for the transaction. + * @return void + * @throws PropelException + */ + public static function commit($con) + { + if ($con === null) { + throw new PropelException( + "Connection object was null. " + . "This could be due to a misconfiguration. " + . "Check the logs and Propel properties " + . "to better determine the cause."); + } + try { + if ($con->getAutoCommit() === false) { + $con->commit(); + $con->setAutoCommit(true); + } + } catch (SQLException $e) { + throw new PropelException($e); + } + } + + /** + * Roll back a transaction in databases that support transactions. + * It also releases the connection. In databases that do not support + * transactions, this method will log the attempt and release the + * connection. + * + * @param Connection $con The Connection for the transaction. + * @return void + * @throws PropelException + */ + public static function rollback($con) + { + if ($con === null) { + throw new PropelException( + "Connection object was null. " + . "This could be due to a misconfiguration. " + . "Check the logs and Propel properties " + . "to better determine the cause."); + } + + try { + if ($con->getAutoCommit() === false) { + $con->rollback(); + $con->setAutoCommit(true); + } + } catch (SQLException $e) { + Propel::log( + "An attempt was made to rollback a transaction " + . "but the database did not allow the operation to be " + . "rolled back: " . $e->getMessage(), Propel::LOG_ERR); + throw new PropelException($e); + } + } + + /** + * Roll back a transaction without throwing errors if they occur. + * + * @param Connection $con The Connection for the transaction. + * @return void + */ + public static function safeRollback($con) + { + try { + Transaction::rollback($con); + } catch (PropelException $e) { + Propel::log("An error occured during rollback: " . $e->getMessage(), Propel::LOG_ERR); + } + } + + +} diff --git a/gulliver/thirdparty/propel/validator/BasicValidator.php b/gulliver/thirdparty/propel/validator/BasicValidator.php new file mode 100644 index 000000000..a6267ffa9 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/BasicValidator.php @@ -0,0 +1,46 @@ +. + */ + +/** + * Basic Validator interface. + * + * BasicValidator objects perform validation without any knowledge of column/table + * context. They are simply given an input and some value and asked whether the input + * is valid. + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +interface BasicValidator +{ + + /** + * Determine whether a value meets the criteria specified + * + * @param ValidatorMap $map A column map object for the column to be validated. + * @param string $str a String to be tested + * + * @return mixed TRUE if valid, error message otherwise + */ + public function isValid(ValidatorMap $map, $str); + +} diff --git a/gulliver/thirdparty/propel/validator/MatchValidator.php b/gulliver/thirdparty/propel/validator/MatchValidator.php new file mode 100644 index 000000000..810cccb45 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/MatchValidator.php @@ -0,0 +1,81 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for regular expressions. + * + * This validator will return true, when the passed value *matches* the + * regular expression. + * + * ## This class replaces the former class MaskValidator ## + * + * If you do want to test if the value does *not* match an expression, + * you can use the MatchValidator class instead. + * + * Below is an example usage for your Propel xml schema file. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.validator + */ +class MatchValidator implements BasicValidator +{ + /** + * Prepares the regular expression entered in the XML + * for use with preg_match(). + * @param string $exp + * @return string Prepared regular expession. + */ + private function prepareRegexp($exp) + { + // remove surrounding '/' marks so that they don't get escaped in next step + if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) { + $exp = '/' . $exp . '/'; + } + + // if they did not escape / chars; we do that for them + $exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp); + + return $exp; + } + + /** + * Whether the passed string matches regular expression. + */ + public function isValid (ValidatorMap $map, $str) + { + return (preg_match($this->prepareRegexp($map->getValue()), $str) != 0); + } +} diff --git a/gulliver/thirdparty/propel/validator/MaxLengthValidator.php b/gulliver/thirdparty/propel/validator/MaxLengthValidator.php new file mode 100644 index 000000000..fdf9a3863 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/MaxLengthValidator.php @@ -0,0 +1,52 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for maximum string length. + * + * Below is an example usage for your Propel xml schema file. + * + * Note that if you have specified the size attribute in the column tag + * you do not have to specify it as value in the validator rule again as + * this is done automatically. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class MaxLengthValidator implements BasicValidator +{ + + public function isValid (ValidatorMap $map, $str) + { + return strlen($str) <= intval($map->getValue()); + } +} diff --git a/gulliver/thirdparty/propel/validator/MaxValueValidator.php b/gulliver/thirdparty/propel/validator/MaxValueValidator.php new file mode 100644 index 000000000..79ecb2e7b --- /dev/null +++ b/gulliver/thirdparty/propel/validator/MaxValueValidator.php @@ -0,0 +1,56 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for maximum values. + * + * Below is an example usage for your Propel xml schema file. + * + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class MaxValueValidator implements BasicValidator +{ + + /** + * @see BasicValidator::isValid() + */ + public function isValid (ValidatorMap $map, $value) + { + if(is_null($value) == false && is_numeric($value) == true) { + return intval($value) <= intval($map->getValue()); + } + + return false; + } +} diff --git a/gulliver/thirdparty/propel/validator/MinLengthValidator.php b/gulliver/thirdparty/propel/validator/MinLengthValidator.php new file mode 100644 index 000000000..df99d51c5 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/MinLengthValidator.php @@ -0,0 +1,49 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for minimum string length. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class MinLengthValidator implements BasicValidator +{ + + /** + * @see BasicValidator::isValid() + */ + public function isValid (ValidatorMap $map, $str) + { + return strlen($str) >= intval($map->getValue()); + } +} diff --git a/gulliver/thirdparty/propel/validator/MinValueValidator.php b/gulliver/thirdparty/propel/validator/MinValueValidator.php new file mode 100644 index 000000000..49a00a801 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/MinValueValidator.php @@ -0,0 +1,56 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for minimum values. + * + * Below is an example usage for your Propel xml schema file. + * + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class MinValueValidator implements BasicValidator +{ + + /** + * @see BasicValidator::isValid() + */ + public function isValid (ValidatorMap $map, $value) + { + if(is_null($value) == false && is_numeric($value)) { + return intval($value) >= intval($map->getValue()); + } + + return false; + } +} diff --git a/gulliver/thirdparty/propel/validator/NotMatchValidator.php b/gulliver/thirdparty/propel/validator/NotMatchValidator.php new file mode 100644 index 000000000..352da65af --- /dev/null +++ b/gulliver/thirdparty/propel/validator/NotMatchValidator.php @@ -0,0 +1,79 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for regular expressions. + * + * This validator will return true, when the passed value does *not* match + * the regular expression. + * + * If you do want to test if the value *matches* an expression, you can use + * the MatchValidator class instead. + * + * Below is an example usage for your Propel xml schema file. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.validator + */ +class NotMatchValidator implements BasicValidator +{ + /** + * Prepares the regular expression entered in the XML + * for use with preg_match(). + * @param string $exp + * @return string Prepared regular expession. + */ + private function prepareRegexp($exp) + { + // remove surrounding '/' marks so that they don't get escaped in next step + if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) { + $exp = '/' . $exp . '/'; + } + + // if they did not escape / chars; we do that for them + $exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp); + + return $exp; + } + + /** + * Whether the passed string matches regular expression. + */ + public function isValid (ValidatorMap $map, $str) + { + return (preg_match($this->prepareRegexp($map->getValue()), $str) == 0); + } +} diff --git a/gulliver/thirdparty/propel/validator/RequiredValidator.php b/gulliver/thirdparty/propel/validator/RequiredValidator.php new file mode 100644 index 000000000..67043cb3d --- /dev/null +++ b/gulliver/thirdparty/propel/validator/RequiredValidator.php @@ -0,0 +1,51 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for required fields. + * + * Below is an example usage for your Propel xml schema file. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class RequiredValidator implements BasicValidator +{ + + /** + * @see BasicValidator::isValid() + */ + public function isValid (ValidatorMap $map, $str) + { + return ($str !== null && $str !== ""); + } +} diff --git a/gulliver/thirdparty/propel/validator/UniqueValidator.php b/gulliver/thirdparty/propel/validator/UniqueValidator.php new file mode 100644 index 000000000..907682839 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/UniqueValidator.php @@ -0,0 +1,66 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for unique column names. + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class UniqueValidator implements BasicValidator +{ + + /** + * @see BasicValidator::isValid() + */ + public function isValid (ValidatorMap $map, $str) + { + $column = $map->getColumn(); + + $c = new Criteria(); + $c->add($column->getFullyQualifiedName(), $str, Criteria::EQUAL); + + $isValid = false; + + try { + + $table = $column->getTable()->getPhpName(); + $cmd = sprintf('$isValid = %sPeer::doCount($c) == 0;', $table); + eval($cmd); + + } catch(PropelException $e) { + /* what to do here ? */ + } + + return $isValid; + } +} diff --git a/gulliver/thirdparty/propel/validator/ValidValuesValidator.php b/gulliver/thirdparty/propel/validator/ValidValuesValidator.php new file mode 100644 index 000000000..beaf9b42d --- /dev/null +++ b/gulliver/thirdparty/propel/validator/ValidValuesValidator.php @@ -0,0 +1,46 @@ +. + */ + +require_once 'propel/validator/BasicValidator.php'; + +/** + * A validator for valid values (e.g. for enum fields) + * + * + * + * + * + * + * + * + * + * @author Michael Aichler + * @version $Revision: 536 $ + * @package propel.validator + */ +class ValidValuesValidator implements BasicValidator +{ + + public function isValid (ValidatorMap $map, $str) + { + return in_array($str, explode("|", $map->getValue())); + } +} diff --git a/gulliver/thirdparty/propel/validator/ValidationFailed.php b/gulliver/thirdparty/propel/validator/ValidationFailed.php new file mode 100644 index 000000000..8580d9ea8 --- /dev/null +++ b/gulliver/thirdparty/propel/validator/ValidationFailed.php @@ -0,0 +1,126 @@ +. + */ + + +/** + * Simple class that serves as a container for any information about a failed validation. + * + * Currently this class stores the qualified column name (e.g. tablename.COLUMN_NAME) and + * the message that should be displayed to the user. + * + * An array of these objects will be returned by BasePeer::doValidate() if validation + * failed. + * + * @author Hans Lellelid + * @version $Revision: 536 $ + * @package propel.validator + * @see BasePeer::doValidate() + */ +class ValidationFailed { + + /** Column name in tablename.COLUMN_NAME format */ + private $colname; + + /** Message to display to user. */ + private $message; + + /** Validator object that caused this to fail. */ + private $validator; + + /** + * Construct a new ValidationFailed object. + * @param string $colname Column name. + * @param string $message Message to display to user. + * @param object $validator The Validator that caused this column to fail. + */ + public function __construct($colname, $message, $validator = null) + { + $this->colname = $colname; + $this->message = $message; + $this->validator = $validator; + } + + /** + * Set the column name. + * @param string $v + */ + public function setColumn($v) + { + $this->colname = $v; + } + + /** + * Gets the column name. + * @return string Qualified column name (tablename.COLUMN_NAME) + */ + public function getColumn() + { + return $this->colname; + } + + /** + * Set the message for the validation failure. + * @param string $v + */ + public function setMessage($v) + { + $this->message = $v; + } + + /** + * Gets the message for the validation failure. + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * Set the validator object that caused this to fail. + * @param object $v + */ + public function setValidator($v) + { + $this->validator = $v; + } + + /** + * Gets the validator object that caused this to fail. + * @return object + */ + public function getValidator() + { + return $this->validator; + } + + /** + * "magic" method to get string represenation of object. + * Maybe someday PHP5 will support the invoking this method automatically + * on (string) cast. Until then it's pretty useless. + * @return string + */ + public function __toString() + { + return $this->getMessage(); + } + +} diff --git a/gulliver/thirdparty/smarty/BUGS b/gulliver/thirdparty/smarty/BUGS new file mode 100644 index 000000000..9f1a80f31 --- /dev/null +++ b/gulliver/thirdparty/smarty/BUGS @@ -0,0 +1,7 @@ +Smarty is supported only in PHP 4.0.6 or later. + +Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include +the path to the PEAR libraries in your php include_path. Config_file.class.php +uses the PEAR library for its error handling routines. PEAR comes with the PHP +distribution. Unix users check /usr/local/lib/php, windows users check +C:/php/pear. diff --git a/gulliver/thirdparty/smarty/COPYING.lib b/gulliver/thirdparty/smarty/COPYING.lib new file mode 100644 index 000000000..3b204400c --- /dev/null +++ b/gulliver/thirdparty/smarty/COPYING.lib @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/gulliver/thirdparty/smarty/ChangeLog b/gulliver/thirdparty/smarty/ChangeLog new file mode 100644 index 000000000..802891ac8 --- /dev/null +++ b/gulliver/thirdparty/smarty/ChangeLog @@ -0,0 +1,8667 @@ +2007-03-06 Monte Ohrt + + * NEWS + libs/plugins/function.html_select_date.php: + fix html_select_date separator when parts are missing (thanks to kayk for + the patch) + +2007-03-06 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + bumped version number + + * NEWS: + added release headline + + * libs/internals/core.write_compiled_include.php: + fixed detection of non-cached block when writing compiled includes + +2007-03-01 Danilo Buerger + + * NEWS + libs/Smarty_Compiler.class.php: + Applied boots clean up patch and removed commented out code. + Updated NEWS file + +2007-02-27 Danilo Buerger + + * NEWS + docs/en/designers/language-modifiers/language-modifier-date-format.xml + libs/internals/core.write_file.php + libs/plugins/modifier.date_format.php: + Updated smarty_core_write_file() and smarty_modifier_date_format() to speed + up Windows detection. + Emulated more parameters for Windows in smarty_modifier_date_format() and + fixed some old ones. + Updated the docs to tell what parameters are emulated on Windows. + Updated NEWS file. + + * NEWS: + Updated NEWS file to reflect changes commited in the last revision + +2007-02-27 Monte Ohrt + + * docs/en/appendixes/troubleshooting.xml: + fix typo + +2007-02-27 Danilo Buerger + + * libs/Smarty_Compiler.class.php: + Modified _(push|pop)_cacheable_state() to embedd alternate syntax. See this + bug report: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=10502 + +2007-02-26 Peter 'Mash' Morgan + + * docs/en/designers/language-custom-functions/language-function-html-options.xml: + Fix incorrect var name + +2007-02-23 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + escape creating of language=php from interleaving + + * libs/Smarty_Compiler.class.php: + add removed line back in + + * libs/Smarty_Compiler.class.php: + fix up last patch, remove unnecessary lines + + * libs/Smarty_Compiler.class.php: + fix situation when no compiled tags are present + + * libs/Smarty_Compiler.class.php: + fix problem with php open tags generated from tag interleaving + +2007-02-06 boots + + * docs/en/programmers/advanced-features/template-resources.xml: + Correct default template handler function example. + +2007-01-17 Messju Mohr + + * NEWS + libs/plugins/modifier.truncate.php: + fixed handling of $etc in the truncate modifier when $etc is longer + than $length. + + thanks to Sylvinus! + +2007-01-10 boots + + * NEWS + libs/plugins/modifier.date_format.php + libs/plugins/modifier.date_format.php: + fix handling of %I with mysql timestamps + + Thanks to Danilo Buerger + + * NEWS + libs/internals/core.write_file.php: + Better recognize Windows filesystems to reduce warnings + + * NEWS + libs/plugins/modifier.date_format.php: + Emulate %R in the date_format modifier on Windows + + Thanks to Danilo Buerger + +2006-12-10 Yannick Torres + + * docs/fr/getting-started.xml: + fix build + + * docs/fr/language-snippets.ent + docs/fr/designers/language-builtin-functions/language-function-include-php.xml + docs/fr/designers/language-modifiers/language-modifier-truncate.xml + docs/fr/designers/language-variables/language-variables-smarty.xml: + sync with EN + +2006-12-02 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-include-php.xml: + Tidy example, speeling andd add links + + * docs/en/getting-started.xml: + Add/correct entities + + * docs/entities/global.ent: + Fix entities (strange) + +2006-12-01 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update dev version numbers + +2006-12-01 boots + + * (Smarty_2_6_16) + NEWS: + Fixed replacement bug introduced in trimwhitespaces output filter that + was introduced in the last release. + + Thanks to Spuerhund from the forums. + + * (Smarty_2_6_16) + libs/plugins/outputfilter.trimwhitespace.php: + Fixed replacement bug introduced by last changes. + + Thanks to Spuerhund from the forums. + +2006-11-30 Monte Ohrt + + * NEWS + docs/en/designers/language-modifiers/language-modifier-truncate.xml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update dev version numbers, fix manual typo + +2006-11-22 George Miroshnikov + + * docs/ru/getting-started.xml + docs/ru/language-snippets.ent: + sync with EN + + * docs/en/getting-started.xml: + replaced hardcoded path separator with PATH_SEPARATOR constant + +2006-11-20 boots + + * libs/plugins/modifier.debug_print_var.php: + fix depth formatting of arrays and objects in modifier debug_print_var + +2006-11-10 Messju Mohr + + * docs/en/designers/language-variables/language-variables-smarty.xml: + fixed typo. thanks jonez. + +2006-11-08 boots + + * NEWS + libs/internals/core.write_file.php: + change file writing semantics in smarty_core_write_file() + + This avoids unlink() unless rename() fails or a Windows system is detected + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=6956 + + Thanks to c960657 from the forums. + +2006-11-07 boots + + * NEWS + libs/debug.tpl: + update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug + output and apply a Smarty based color scheme + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7178 + + thanks to cybot from the forums! + + * NEWS + libs/plugins/modifier.debug_print_var.php: + enhance reporting precision of debug_print_var modifier + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=9281 + + thanks to cybot from the forums + +2006-11-01 boots + + * NEWS + libs/plugins/function.html_select_date.php: + make html_select_date work consistently with 0000-00-00 00:00:00 and + 0000-00-00 inputs + + Thanks to cybot from forums + +2006-10-16 George Miroshnikov + + * docs/en/language-snippets.ent: + minor typo fix - &$class doesn't make sense. + +2006-10-14 Yannick Torres + + * docs/fr/designers/language-basic-syntax.xml + docs/fr/designers/language-builtin-functions.xml + docs/fr/designers/language-basic-syntax/language-syntax-attributes.xml + docs/fr/designers/language-basic-syntax/language-syntax-comments.xml + docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml + docs/fr/designers/language-builtin-functions/language-function-capture.xml + docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-builtin-functions/language-function-section.xml + docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/programmers/api-functions/api-display.xml + docs/fr/programmers/plugins/plugins-inserts.xml: + sync with EN + +2006-10-14 Fernando Correa da Conceição + + * docs/pt_BR/programmers/api-variables/variable-error-reporting.xml: + New Translation + + * docs/pt_BR/designers/language-basic-syntax/language-escaping.xml + docs/pt_BR/designers/language-basic-syntax/language-syntax-variables.xml: + New Translations + + * docs/pt_BR/translation.xml: + Used in revcheck + + * docs/pt_BR/getting-started.xml + docs/pt_BR/language-snippets.ent + docs/pt_BR/make_chm_index.html + docs/pt_BR/preface.xml + docs/pt_BR/appendixes/resources.xml + docs/pt_BR/appendixes/troubleshooting.xml + docs/pt_BR/designers/language-modifiers/language-modifier-capitalize.xml + docs/pt_BR/designers/language-modifiers/language-modifier-cat.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-characters.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-sentences.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-words.xml + docs/pt_BR/designers/language-modifiers/language-modifier-date-format.xml + docs/pt_BR/designers/language-modifiers/language-modifier-default.xml + docs/pt_BR/designers/language-modifiers/language-modifier-escape.xml + docs/pt_BR/designers/language-modifiers/language-modifier-indent.xml + docs/pt_BR/designers/language-modifiers/language-modifier-lower.xml + docs/pt_BR/designers/language-modifiers/language-modifier-nl2br.xml + docs/pt_BR/designers/language-modifiers/language-modifier-regex-replace.xml + docs/pt_BR/designers/language-modifiers/language-modifier-replace.xml + docs/pt_BR/designers/language-modifiers/language-modifier-spacify.xml + docs/pt_BR/designers/language-modifiers/language-modifier-string-format.xml + docs/pt_BR/designers/language-modifiers/language-modifier-strip-tags.xml + docs/pt_BR/designers/language-modifiers/language-modifier-strip.xml + docs/pt_BR/designers/language-modifiers/language-modifier-truncate.xml + docs/pt_BR/designers/language-modifiers/language-modifier-upper.xml + docs/pt_BR/designers/language-modifiers/language-modifier-wordwrap.xml + docs/pt_BR/designers/language-variables/language-assigned-variables.xml + docs/pt_BR/designers/language-variables/language-config-variables.xml + docs/pt_BR/designers/language-variables/language-variables-smarty.xml + docs/pt_BR/programmers/advanced-features.xml + docs/pt_BR/programmers/api-functions.xml + docs/pt_BR/programmers/api-variables.xml + docs/pt_BR/programmers/caching.xml + docs/pt_BR/programmers/plugins.xml + docs/pt_BR/programmers/smarty-constants.xml + docs/pt_BR/programmers/advanced-features/advanced-features-objects.xml + docs/pt_BR/programmers/advanced-features/advanced-features-outputfilters.xml + docs/pt_BR/programmers/advanced-features/advanced-features-postfilters.xml + docs/pt_BR/programmers/advanced-features/advanced-features-prefilters.xml + docs/pt_BR/programmers/advanced-features/section-template-cache-handler-func.xml + docs/pt_BR/programmers/advanced-features/template-resources.xml + docs/pt_BR/programmers/api-functions/api-append-by-ref.xml + docs/pt_BR/programmers/api-functions/api-append.xml + docs/pt_BR/programmers/api-functions/api-assign-by-ref.xml + docs/pt_BR/programmers/api-functions/api-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-all-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-all-cache.xml + docs/pt_BR/programmers/api-functions/api-clear-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-cache.xml + docs/pt_BR/programmers/api-functions/api-clear-compiled-tpl.xml + docs/pt_BR/programmers/api-functions/api-clear-config.xml + docs/pt_BR/programmers/api-functions/api-config-load.xml + docs/pt_BR/programmers/api-functions/api-display.xml + docs/pt_BR/programmers/api-functions/api-fetch.xml + docs/pt_BR/programmers/api-functions/api-get-config-vars.xml + docs/pt_BR/programmers/api-functions/api-get-registered-object.xml + docs/pt_BR/programmers/api-functions/api-get-template-vars.xml + docs/pt_BR/programmers/api-functions/api-is-cached.xml + docs/pt_BR/programmers/api-functions/api-load-filter.xml + docs/pt_BR/programmers/api-functions/api-register-block.xml + docs/pt_BR/programmers/api-functions/api-register-compiler-function.xml + docs/pt_BR/programmers/api-functions/api-register-function.xml + docs/pt_BR/programmers/api-functions/api-register-modifier.xml + docs/pt_BR/programmers/api-functions/api-register-object.xml + docs/pt_BR/programmers/api-functions/api-register-outputfilter.xml + docs/pt_BR/programmers/api-functions/api-register-postfilter.xml + docs/pt_BR/programmers/api-functions/api-register-prefilter.xml + docs/pt_BR/programmers/api-functions/api-register-resource.xml + docs/pt_BR/programmers/api-functions/api-template-exists.xml + docs/pt_BR/programmers/api-functions/api-trigger-error.xml + docs/pt_BR/programmers/api-functions/api-unregister-block.xml + docs/pt_BR/programmers/api-functions/api-unregister-compiler-function.xml + docs/pt_BR/programmers/api-functions/api-unregister-function.xml + docs/pt_BR/programmers/api-functions/api-unregister-modifier.xml + docs/pt_BR/programmers/api-functions/api-unregister-object.xml + docs/pt_BR/programmers/api-functions/api-unregister-outputfilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-postfilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-prefilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-resource.xml + docs/pt_BR/programmers/api-variables/variable-autoload-filters.xml + docs/pt_BR/programmers/api-variables/variable-cache-dir.xml + docs/pt_BR/programmers/api-variables/variable-cache-handler-func.xml + docs/pt_BR/programmers/api-variables/variable-cache-lifetime.xml + docs/pt_BR/programmers/api-variables/variable-cache-modified-check.xml + docs/pt_BR/programmers/api-variables/variable-caching.xml + docs/pt_BR/programmers/api-variables/variable-compile-check.xml + docs/pt_BR/programmers/api-variables/variable-compile-dir.xml + docs/pt_BR/programmers/api-variables/variable-compile-id.xml + docs/pt_BR/programmers/api-variables/variable-compiler-class.xml + docs/pt_BR/programmers/api-variables/variable-config-booleanize.xml + docs/pt_BR/programmers/api-variables/variable-config-dir.xml + docs/pt_BR/programmers/api-variables/variable-config-fix-newlines.xml + docs/pt_BR/programmers/api-variables/variable-config-overwrite.xml + docs/pt_BR/programmers/api-variables/variable-config-read-hidden.xml + docs/pt_BR/programmers/api-variables/variable-debug-tpl.xml + docs/pt_BR/programmers/api-variables/variable-debugging-ctrl.xml + docs/pt_BR/programmers/api-variables/variable-debugging.xml + docs/pt_BR/programmers/api-variables/variable-default-modifiers.xml + docs/pt_BR/programmers/api-variables/variable-default-resource-type.xml + docs/pt_BR/programmers/api-variables/variable-default-template-handler-func.xml + docs/pt_BR/programmers/api-variables/variable-force-compile.xml + docs/pt_BR/programmers/api-variables/variable-global-assign.xml + docs/pt_BR/programmers/api-variables/variable-left-delimiter.xml + docs/pt_BR/programmers/api-variables/variable-php-handling.xml + docs/pt_BR/programmers/api-variables/variable-plugins-dir.xml + docs/pt_BR/programmers/api-variables/variable-request-use-auto-globals.xml + docs/pt_BR/programmers/api-variables/variable-request-vars-order.xml + docs/pt_BR/programmers/api-variables/variable-right-delimiter.xml + docs/pt_BR/programmers/api-variables/variable-secure-dir.xml + docs/pt_BR/programmers/api-variables/variable-security-settings.xml + docs/pt_BR/programmers/api-variables/variable-security.xml + docs/pt_BR/programmers/api-variables/variable-template-dir.xml + docs/pt_BR/programmers/api-variables/variable-trusted-dir.xml + docs/pt_BR/programmers/api-variables/variable-undefined.xml + docs/pt_BR/programmers/api-variables/variable-use-sub-dirs.xml + docs/pt_BR/programmers/caching/caching-cacheable.xml + docs/pt_BR/programmers/caching/caching-groups.xml + docs/pt_BR/programmers/caching/caching-multiple-caches.xml + docs/pt_BR/programmers/caching/caching-setting-up.xml + docs/pt_BR/programmers/plugins/plugins-block-functions.xml + docs/pt_BR/programmers/plugins/plugins-compiler-functions.xml + docs/pt_BR/programmers/plugins/plugins-functions.xml + docs/pt_BR/programmers/plugins/plugins-howto.xml + docs/pt_BR/programmers/plugins/plugins-inserts.xml + docs/pt_BR/programmers/plugins/plugins-modifiers.xml + docs/pt_BR/programmers/plugins/plugins-naming-conventions.xml + docs/pt_BR/programmers/plugins/plugins-outputfilters.xml + docs/pt_BR/programmers/plugins/plugins-prefilters-postfilters.xml + docs/pt_BR/programmers/plugins/plugins-resources.xml + docs/pt_BR/programmers/plugins/plugins-writing.xml: + Big update. Revision tag for all files. Some updates. Now I can update it + +2006-10-09 Peter 'Mash' Morgan + + * docs/en/getting-started.xml + docs/en/designers/language-basic-syntax.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml + docs/en/programmers/api-functions/api-display.xml + docs/en/programmers/plugins/plugins-inserts.xml: + Minor changes and corrections + + * docs/en/designers/language-basic-syntax.xml + docs/en/designers/language-builtin-functions.xml + docs/en/designers/language-basic-syntax/language-syntax-attributes.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-basic-syntax/language-syntax-quotes.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml: + Minor formatting and error correction + + * docs/en/designers/language-builtin-functions/language-function-capture.xml + docs/en/designers/language-builtin-functions/language-function-php.xml + docs/en/designers/language-builtin-functions/language-function-section.xml: + minor formatting and changes + + * docs/en/getting-started.xml: + Tidied up formatting so more readable, tidied up the install to the paths + are more clear (ta jj) + +2006-10-09 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-section.xml: + sync with EN + +2006-10-08 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/designers/language-variables/language-variables-smarty.xml + docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml: + fix build + + * docs/fr/designers/language-builtin-functions/language-function-strip.xml + docs/fr/programmers/caching.xml + docs/fr/programmers/smarty-constants.xml + docs/fr/programmers/api-variables/variable-autoload-filters.xml + docs/fr/programmers/api-variables/variable-cache-dir.xml + docs/fr/programmers/api-variables/variable-cache-handler-func.xml + docs/fr/programmers/api-variables/variable-cache-lifetime.xml + docs/fr/programmers/api-variables/variable-cache-modified-check.xml + docs/fr/programmers/api-variables/variable-caching.xml + docs/fr/programmers/api-variables/variable-compile-check.xml + docs/fr/programmers/api-variables/variable-compile-dir.xml + docs/fr/programmers/api-variables/variable-compile-id.xml + docs/fr/programmers/api-variables/variable-compiler-class.xml + docs/fr/programmers/api-variables/variable-config-booleanize.xml + docs/fr/programmers/api-variables/variable-config-dir.xml + docs/fr/programmers/api-variables/variable-config-fix-newlines.xml + docs/fr/programmers/api-variables/variable-config-overwrite.xml + docs/fr/programmers/api-variables/variable-config-read-hidden.xml + docs/fr/programmers/api-variables/variable-debug-tpl.xml + docs/fr/programmers/api-variables/variable-debugging-ctrl.xml + docs/fr/programmers/api-variables/variable-debugging.xml + docs/fr/programmers/api-variables/variable-default-modifiers.xml + docs/fr/programmers/api-variables/variable-default-resource-type.xml + docs/fr/programmers/api-variables/variable-default-template-handler-func.xml + docs/fr/programmers/api-variables/variable-error-reporting.xml + docs/fr/programmers/api-variables/variable-force-compile.xml + docs/fr/programmers/api-variables/variable-left-delimiter.xml + docs/fr/programmers/api-variables/variable-php-handling.xml + docs/fr/programmers/api-variables/variable-plugins-dir.xml + docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml + docs/fr/programmers/api-variables/variable-request-vars-order.xml + docs/fr/programmers/api-variables/variable-right-delimiter.xml + docs/fr/programmers/api-variables/variable-secure-dir.xml + docs/fr/programmers/api-variables/variable-security-settings.xml + docs/fr/programmers/api-variables/variable-security.xml + docs/fr/programmers/api-variables/variable-template-dir.xml + docs/fr/programmers/api-variables/variable-trusted-dir.xml + docs/fr/programmers/api-variables/variable-use-sub-dirs.xml + docs/fr/programmers/caching/caching-cacheable.xml + docs/fr/programmers/caching/caching-groups.xml + docs/fr/programmers/caching/caching-multiple-caches.xml + docs/fr/programmers/caching/caching-setting-up.xml + docs/fr/programmers/plugins/plugins-block-functions.xml + docs/fr/programmers/plugins/plugins-compiler-functions.xml + docs/fr/programmers/plugins/plugins-functions.xml + docs/fr/programmers/plugins/plugins-inserts.xml + docs/fr/programmers/plugins/plugins-modifiers.xml + docs/fr/programmers/plugins/plugins-naming-conventions.xml + docs/fr/programmers/plugins/plugins-outputfilters.xml + docs/fr/programmers/plugins/plugins-prefilters-postfilters.xml + docs/fr/programmers/plugins/plugins-resources.xml + docs/fr/programmers/plugins/plugins-writing.xml: + sync with EN + +2006-10-07 Yannick Torres + + * docs/fr/programmers/advanced-features/advanced-features-objects.xml + docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml + docs/fr/programmers/advanced-features/advanced-features-postfilters.xml + docs/fr/programmers/advanced-features/advanced-features-prefilters.xml + docs/fr/programmers/advanced-features/section-template-cache-handler-func.xml + docs/fr/programmers/advanced-features/template-resources.xml + docs/fr/programmers/api-functions/api-append-by-ref.xml + docs/fr/programmers/api-functions/api-append.xml + docs/fr/programmers/api-functions/api-assign-by-ref.xml + docs/fr/programmers/api-functions/api-assign.xml + docs/fr/programmers/api-functions/api-clear-all-assign.xml + docs/fr/programmers/api-functions/api-clear-all-cache.xml + docs/fr/programmers/api-functions/api-clear-assign.xml + docs/fr/programmers/api-functions/api-clear-cache.xml + docs/fr/programmers/api-functions/api-clear-compiled-tpl.xml + docs/fr/programmers/api-functions/api-clear-config.xml + docs/fr/programmers/api-functions/api-config-load.xml + docs/fr/programmers/api-functions/api-display.xml + docs/fr/programmers/api-functions/api-fetch.xml + docs/fr/programmers/api-functions/api-get-config-vars.xml + docs/fr/programmers/api-functions/api-get-registered-object.xml + docs/fr/programmers/api-functions/api-get-template-vars.xml + docs/fr/programmers/api-functions/api-is-cached.xml + docs/fr/programmers/api-functions/api-load-filter.xml + docs/fr/programmers/api-functions/api-register-block.xml + docs/fr/programmers/api-functions/api-register-compiler-function.xml + docs/fr/programmers/api-functions/api-register-function.xml + docs/fr/programmers/api-functions/api-register-modifier.xml + docs/fr/programmers/api-functions/api-register-object.xml + docs/fr/programmers/api-functions/api-register-outputfilter.xml + docs/fr/programmers/api-functions/api-register-postfilter.xml + docs/fr/programmers/api-functions/api-register-prefilter.xml + docs/fr/programmers/api-functions/api-register-resource.xml + docs/fr/programmers/api-functions/api-template-exists.xml + docs/fr/programmers/api-functions/api-trigger-error.xml + docs/fr/programmers/api-functions/api-unregister-block.xml + docs/fr/programmers/api-functions/api-unregister-compiler-function.xml + docs/fr/programmers/api-functions/api-unregister-function.xml + docs/fr/programmers/api-functions/api-unregister-modifier.xml + docs/fr/programmers/api-functions/api-unregister-object.xml + docs/fr/programmers/api-functions/api-unregister-outputfilter.xml + docs/fr/programmers/api-functions/api-unregister-postfilter.xml + docs/fr/programmers/api-functions/api-unregister-prefilter.xml + docs/fr/programmers/api-functions/api-unregister-resource.xml: + sync with EN + +2006-10-03 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-html-select-time.xml + docs/fr/designers/language-custom-functions/language-function-html-table.xml + docs/fr/designers/language-custom-functions/language-function-mailto.xml + docs/fr/designers/language-custom-functions/language-function-math.xml + docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/designers/language-custom-functions/language-function-popup.xml + docs/fr/designers/language-custom-functions/language-function-textformat.xml + docs/fr/designers/language-modifiers/language-modifier-capitalize.xml + docs/fr/designers/language-modifiers/language-modifier-cat.xml + docs/fr/designers/language-modifiers/language-modifier-count-characters.xml + docs/fr/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/fr/designers/language-modifiers/language-modifier-count-sentences.xml + docs/fr/designers/language-modifiers/language-modifier-count-words.xml + docs/fr/designers/language-modifiers/language-modifier-date-format.xml + docs/fr/designers/language-modifiers/language-modifier-default.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/designers/language-modifiers/language-modifier-indent.xml + docs/fr/designers/language-modifiers/language-modifier-lower.xml + docs/fr/designers/language-modifiers/language-modifier-nl2br.xml + docs/fr/designers/language-modifiers/language-modifier-regex-replace.xml + docs/fr/designers/language-modifiers/language-modifier-replace.xml + docs/fr/designers/language-modifiers/language-modifier-spacify.xml + docs/fr/designers/language-modifiers/language-modifier-string-format.xml + docs/fr/designers/language-modifiers/language-modifier-strip-tags.xml + docs/fr/designers/language-modifiers/language-modifier-strip.xml + docs/fr/designers/language-modifiers/language-modifier-truncate.xml + docs/fr/designers/language-modifiers/language-modifier-upper.xml + docs/fr/designers/language-modifiers/language-modifier-wordwrap.xml + docs/fr/designers/language-variables/language-assigned-variables.xml + docs/fr/designers/language-variables/language-config-variables.xml + docs/fr/designers/language-variables/language-variables-smarty.xml: + sync with EN + +2006-10-01 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-include-php.xml + docs/fr/designers/language-builtin-functions/language-function-include.xml + docs/fr/designers/language-builtin-functions/language-function-insert.xml + docs/fr/designers/language-builtin-functions/language-function-ldelim.xml + docs/fr/designers/language-builtin-functions/language-function-literal.xml + docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-custom-functions/language-function-assign.xml + docs/fr/designers/language-custom-functions/language-function-counter.xml + docs/fr/designers/language-custom-functions/language-function-cycle.xml + docs/fr/designers/language-custom-functions/language-function-debug.xml + docs/fr/designers/language-custom-functions/language-function-eval.xml + docs/fr/designers/language-custom-functions/language-function-fetch.xml + docs/fr/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/fr/designers/language-custom-functions/language-function-html-image.xml + docs/fr/designers/language-custom-functions/language-function-html-options.xml + docs/fr/designers/language-custom-functions/language-function-html-radios.xml + docs/fr/designers/language-custom-functions/language-function-html-select-date.xml: + sync with EN + +2006-09-30 Yannick Torres + + * docs/fr/getting-started.xml: + fix build + + * docs/fr/designers/chapter-debugging-console.xml + docs/fr/designers/config-files.xml + docs/fr/designers/language-builtin-functions.xml + docs/fr/designers/language-modifiers.xml + docs/fr/designers/language-variables.xml + docs/fr/designers/language-basic-syntax/language-escaping.xml + docs/fr/designers/language-basic-syntax/language-math.xml + docs/fr/designers/language-basic-syntax/language-syntax-comments.xml + docs/fr/designers/language-basic-syntax/language-syntax-functions.xml + docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml + docs/fr/designers/language-basic-syntax/language-syntax-variables.xml + docs/fr/designers/language-builtin-functions/language-function-capture.xml + docs/fr/designers/language-builtin-functions/language-function-config-load.xml + docs/fr/designers/language-builtin-functions/language-function-foreach.xml + docs/fr/designers/language-builtin-functions/language-function-if.xml: + sync with EN + + * docs/fr/getting-started.xml + docs/fr/language-snippets.ent + docs/fr/appendixes/resources.xml + docs/fr/appendixes/tips.xml + docs/fr/appendixes/troubleshooting.xml: + sync with EN + +2006-09-27 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-section.xml: + Minor tweaks and corrections + + * docs/en/getting-started.xml + docs/en/designers/chapter-debugging-console.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-custom-functions/language-function-html-image.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-custom-functions/language-function-html-radios.xml + docs/en/designers/language-custom-functions/language-function-html-select-date.xml + docs/en/designers/language-custom-functions/language-function-html-select-time.xml + docs/en/designers/language-custom-functions/language-function-html-table.xml + docs/en/designers/language-custom-functions/language-function-mailto.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-custom-functions/language-function-textformat.xml + docs/en/designers/language-variables/language-config-variables.xml + docs/en/designers/language-variables/language-variables-smarty.xml: + Add literal tags to html, general formatting + + * docs/en/getting-started.xml + docs/en/appendixes/resources.xml + docs/en/appendixes/tips.xml + docs/en/appendixes/troubleshooting.xml + docs/en/designers/config-files.xml + docs/en/programmers/caching.xml + docs/en/programmers/smarty-constants.xml + docs/en/programmers/advanced-features/advanced-features-objects.xml + docs/en/programmers/advanced-features/advanced-features-outputfilters.xml + docs/en/programmers/advanced-features/advanced-features-postfilters.xml + docs/en/programmers/advanced-features/advanced-features-prefilters.xml + docs/en/programmers/advanced-features/section-template-cache-handler-func.xml + docs/en/programmers/advanced-features/template-resources.xml + docs/en/programmers/api-variables/variable-autoload-filters.xml + docs/en/programmers/api-variables/variable-cache-dir.xml + docs/en/programmers/api-variables/variable-cache-handler-func.xml + docs/en/programmers/api-variables/variable-cache-lifetime.xml + docs/en/programmers/api-variables/variable-cache-modified-check.xml + docs/en/programmers/api-variables/variable-caching.xml + docs/en/programmers/api-variables/variable-compile-check.xml + docs/en/programmers/api-variables/variable-compile-dir.xml + docs/en/programmers/api-variables/variable-compile-id.xml + docs/en/programmers/api-variables/variable-config-booleanize.xml + docs/en/programmers/api-variables/variable-config-dir.xml + docs/en/programmers/api-variables/variable-config-fix-newlines.xml + docs/en/programmers/api-variables/variable-config-overwrite.xml + docs/en/programmers/api-variables/variable-config-read-hidden.xml + docs/en/programmers/api-variables/variable-debug-tpl.xml + docs/en/programmers/api-variables/variable-debugging-ctrl.xml + docs/en/programmers/api-variables/variable-debugging.xml + docs/en/programmers/api-variables/variable-default-modifiers.xml + docs/en/programmers/api-variables/variable-default-resource-type.xml + docs/en/programmers/api-variables/variable-error-reporting.xml + docs/en/programmers/api-variables/variable-force-compile.xml + docs/en/programmers/api-variables/variable-left-delimiter.xml + docs/en/programmers/api-variables/variable-php-handling.xml + docs/en/programmers/api-variables/variable-plugins-dir.xml + docs/en/programmers/api-variables/variable-request-use-auto-globals.xml + docs/en/programmers/api-variables/variable-request-vars-order.xml + docs/en/programmers/api-variables/variable-right-delimiter.xml + docs/en/programmers/api-variables/variable-secure-dir.xml + docs/en/programmers/api-variables/variable-security-settings.xml + docs/en/programmers/api-variables/variable-security.xml + docs/en/programmers/api-variables/variable-template-dir.xml + docs/en/programmers/api-variables/variable-trusted-dir.xml + docs/en/programmers/api-variables/variable-use-sub-dirs.xml + docs/en/programmers/caching/caching-cacheable.xml + docs/en/programmers/caching/caching-groups.xml + docs/en/programmers/caching/caching-multiple-caches.xml + docs/en/programmers/caching/caching-setting-up.xml: + Tidy up of formatting + + * docs/entities/global.ent: + Adding some more resources + + * docs/en/programmers/plugins/plugins-block-functions.xml + docs/en/programmers/plugins/plugins-compiler-functions.xml + docs/en/programmers/plugins/plugins-functions.xml + docs/en/programmers/plugins/plugins-inserts.xml + docs/en/programmers/plugins/plugins-modifiers.xml + docs/en/programmers/plugins/plugins-naming-conventions.xml + docs/en/programmers/plugins/plugins-outputfilters.xml + docs/en/programmers/plugins/plugins-prefilters-postfilters.xml + docs/en/programmers/plugins/plugins-resources.xml + docs/en/programmers/plugins/plugins-writing.xml: + Tidy up some formatting + +2006-09-26 Peter 'Mash' Morgan + + * docs/en/programmers/api-functions/api-append-by-ref.xml + docs/en/programmers/api-functions/api-append.xml + docs/en/programmers/api-functions/api-assign-by-ref.xml + docs/en/programmers/api-functions/api-assign.xml + docs/en/programmers/api-functions/api-clear-all-assign.xml + docs/en/programmers/api-functions/api-clear-all-cache.xml + docs/en/programmers/api-functions/api-clear-assign.xml + docs/en/programmers/api-functions/api-clear-cache.xml + docs/en/programmers/api-functions/api-clear-compiled-tpl.xml + docs/en/programmers/api-functions/api-clear-config.xml + docs/en/programmers/api-functions/api-config-load.xml + docs/en/programmers/api-functions/api-display.xml + docs/en/programmers/api-functions/api-fetch.xml + docs/en/programmers/api-functions/api-get-config-vars.xml + docs/en/programmers/api-functions/api-get-registered-object.xml + docs/en/programmers/api-functions/api-get-template-vars.xml + docs/en/programmers/api-functions/api-is-cached.xml + docs/en/programmers/api-functions/api-load-filter.xml + docs/en/programmers/api-functions/api-register-block.xml + docs/en/programmers/api-functions/api-register-compiler-function.xml + docs/en/programmers/api-functions/api-register-function.xml + docs/en/programmers/api-functions/api-register-modifier.xml + docs/en/programmers/api-functions/api-register-object.xml + docs/en/programmers/api-functions/api-register-outputfilter.xml + docs/en/programmers/api-functions/api-register-postfilter.xml + docs/en/programmers/api-functions/api-register-prefilter.xml + docs/en/programmers/api-functions/api-register-resource.xml + docs/en/programmers/api-functions/api-template-exists.xml + docs/en/programmers/api-functions/api-trigger-error.xml + docs/en/programmers/api-functions/api-unregister-block.xml + docs/en/programmers/api-functions/api-unregister-compiler-function.xml + docs/en/programmers/api-functions/api-unregister-function.xml + docs/en/programmers/api-functions/api-unregister-modifier.xml + docs/en/programmers/api-functions/api-unregister-object.xml + docs/en/programmers/api-functions/api-unregister-outputfilter.xml + docs/en/programmers/api-functions/api-unregister-postfilter.xml + docs/en/programmers/api-functions/api-unregister-prefilter.xml + docs/en/programmers/api-functions/api-unregister-resource.xml: + Tidy up formatting and examples + + * docs/en/language-snippets.ent: + Moved recurring para for register_* + + * docs/en/designers/language-modifiers.xml: + Spelling on modifiers + + * docs/en/designers/language-builtin-functions.xml + docs/en/designers/language-modifiers.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-modifiers/language-modifier-capitalize.xml + docs/en/designers/language-modifiers/language-modifier-cat.xml + docs/en/designers/language-modifiers/language-modifier-count-characters.xml + docs/en/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/en/designers/language-modifiers/language-modifier-count-sentences.xml + docs/en/designers/language-modifiers/language-modifier-count-words.xml + docs/en/designers/language-modifiers/language-modifier-date-format.xml + docs/en/designers/language-modifiers/language-modifier-default.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml + docs/en/designers/language-modifiers/language-modifier-indent.xml + docs/en/designers/language-modifiers/language-modifier-lower.xml + docs/en/designers/language-modifiers/language-modifier-nl2br.xml + docs/en/designers/language-modifiers/language-modifier-regex-replace.xml + docs/en/designers/language-modifiers/language-modifier-replace.xml + docs/en/designers/language-modifiers/language-modifier-spacify.xml + docs/en/designers/language-modifiers/language-modifier-string-format.xml + docs/en/designers/language-modifiers/language-modifier-strip-tags.xml + docs/en/designers/language-modifiers/language-modifier-strip.xml + docs/en/designers/language-modifiers/language-modifier-truncate.xml + docs/en/designers/language-modifiers/language-modifier-upper.xml + docs/en/designers/language-modifiers/language-modifier-wordwrap.xml: + Tidying up some markup + + * docs/en/designers/language-variables.xml: + typo + + * docs/en/designers/language-variables.xml + docs/en/designers/language-variables/language-assigned-variables.xml + docs/en/designers/language-variables/language-config-variables.xml + docs/en/designers/language-variables/language-variables-smarty.xml: + Tidy up formatting on variables + + * docs/en/designers/language-basic-syntax/language-escaping.xml + docs/en/designers/language-basic-syntax/language-math.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-basic-syntax/language-syntax-functions.xml + docs/en/designers/language-basic-syntax/language-syntax-quotes.xml + docs/en/designers/language-basic-syntax/language-syntax-variables.xml: + Formatting of the basic-syntax dir + + * docs/en/designers/language-custom-functions/language-function-assign.xml + docs/en/designers/language-custom-functions/language-function-counter.xml + docs/en/designers/language-custom-functions/language-function-cycle.xml + docs/en/designers/language-custom-functions/language-function-debug.xml + docs/en/designers/language-custom-functions/language-function-eval.xml + docs/en/designers/language-custom-functions/language-function-fetch.xml + docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/en/designers/language-custom-functions/language-function-html-image.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-custom-functions/language-function-html-radios.xml + docs/en/designers/language-custom-functions/language-function-html-select-date.xml + docs/en/designers/language-custom-functions/language-function-html-select-time.xml + docs/en/designers/language-custom-functions/language-function-html-table.xml + docs/en/designers/language-custom-functions/language-function-mailto.xml + docs/en/designers/language-custom-functions/language-function-math.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-custom-functions/language-function-popup.xml + docs/en/designers/language-custom-functions/language-function-textformat.xml: + More formatting and cleaning up examples + +2006-09-25 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-foreach.xml + docs/en/designers/language-builtin-functions/language-function-section.xml: + Doh! removing tabs + + * docs/en/designers/language-builtin-functions/language-function-capture.xml + docs/en/designers/language-builtin-functions/language-function-config-load.xml + docs/en/designers/language-builtin-functions/language-function-foreach.xml + docs/en/designers/language-builtin-functions/language-function-if.xml + docs/en/designers/language-builtin-functions/language-function-include-php.xml + docs/en/designers/language-builtin-functions/language-function-include.xml + docs/en/designers/language-builtin-functions/language-function-insert.xml + docs/en/designers/language-builtin-functions/language-function-ldelim.xml + docs/en/designers/language-builtin-functions/language-function-literal.xml + docs/en/designers/language-builtin-functions/language-function-php.xml + docs/en/designers/language-builtin-functions/language-function-section.xml + docs/en/designers/language-builtin-functions/language-function-strip.xml: + A lot of formatting, tagging and tidy up. Some consistency at last + + * docs/en/designers/language-builtin-functions/language-function-section.xml: + Major tidy up + + * docs/en/designers/language-builtin-functions/language-function-foreach.xml: + Major tidy up, added index property and some examples + +2006-09-03 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml + docs/fr/programmers/advanced-features/advanced-features-postfilters.xml + docs/fr/programmers/advanced-features/advanced-features-prefilters.xml: + sync with EN + +2006-09-01 George Miroshnikov + + * docs/ru/programmers/api-functions/api-append-by-ref.xml + docs/ru/programmers/api-functions/api-append.xml + docs/ru/programmers/api-functions/api-assign-by-ref.xml + docs/ru/programmers/api-functions/api-assign.xml + docs/ru/programmers/api-functions/api-clear-all-assign.xml + docs/ru/programmers/api-functions/api-clear-all-cache.xml + docs/ru/programmers/api-functions/api-clear-assign.xml + docs/ru/programmers/api-functions/api-clear-cache.xml + docs/ru/programmers/api-functions/api-clear-compiled-tpl.xml + docs/ru/programmers/api-functions/api-clear-config.xml + docs/ru/programmers/api-functions/api-config-load.xml + docs/ru/programmers/api-functions/api-display.xml: + sync with EN + +2006-08-25 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed wrong handling of name attribute in {insert} + thanks to Ivan Kravets for reporting this + + * libs/Smarty_Compiler.class.php: + fixed typo + +2006-08-21 George Miroshnikov + + * docs/ru/designers/language-custom-functions/language-function-popup-init.xml + docs/ru/programmers/advanced-features/advanced-features-objects.xml + docs/ru/programmers/advanced-features/advanced-features-outputfilters.xml + docs/ru/programmers/advanced-features/advanced-features-postfilters.xml + docs/ru/programmers/advanced-features/advanced-features-prefilters.xml + docs/ru/programmers/advanced-features/section-template-cache-handler-func.xml + docs/ru/programmers/advanced-features/template-resources.xml: + sync with EN + + * docs/en/programmers/advanced-features/advanced-features-prefilters.xml: + another missing dot + + * docs/en/programmers/advanced-features/advanced-features-postfilters.xml: + missing dot + + * docs/en/programmers/advanced-features/advanced-features-outputfilters.xml: + missing comma + +2006-08-19 Peter 'Mash' Morgan + + * docs/en/designers/language-custom-functions/language-function-popup-init.xml: + avoid dupes and added remote paths + +2006-08-06 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-html-table.xml + docs/fr/designers/language-custom-functions/language-function-mailto.xml: + sync with EN + +2006-08-03 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix false replacement of "$t" inside double quotes + thanks to checat for reporting this + +2006-07-20 George Miroshnikov + + * docs/ru/designers/language-custom-functions/language-function-html-table.xml + docs/ru/designers/language-custom-functions/language-function-mailto.xml: + incrementing EN-Revision + + * docs/ru/designers/language-custom-functions/language-function-assign.xml + docs/ru/designers/language-custom-functions/language-function-eval.xml + docs/ru/designers/language-custom-functions/language-function-fetch.xml + docs/ru/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/ru/designers/language-custom-functions/language-function-html-image.xml + docs/ru/designers/language-custom-functions/language-function-html-options.xml + docs/ru/designers/language-custom-functions/language-function-html-radios.xml + docs/ru/designers/language-custom-functions/language-function-html-table.xml + docs/ru/designers/language-custom-functions/language-function-mailto.xml + docs/ru/designers/language-custom-functions/language-function-popup-init.xml + docs/ru/designers/language-custom-functions/language-function-popup.xml + docs/ru/designers/language-modifiers/language-modifier-date-format.xml + docs/ru/designers/language-modifiers/language-modifier-default.xml + docs/ru/designers/language-modifiers/language-modifier-escape.xml + docs/ru/designers/language-modifiers/language-modifier-indent.xml + docs/ru/designers/language-modifiers/language-modifier-lower.xml + docs/ru/designers/language-modifiers/language-modifier-nl2br.xml + docs/ru/designers/language-modifiers/language-modifier-strip.xml + docs/ru/designers/language-modifiers/language-modifier-truncate.xml + docs/ru/designers/language-modifiers/language-modifier-upper.xml + docs/ru/designers/language-modifiers/language-modifier-wordwrap.xml + docs/ru/designers/language-variables/language-variables-smarty.xml: + sync with EN + + * docs/en/designers/language-custom-functions/language-function-mailto.xml: + typo + +2006-07-10 boots + + * libs/plugins/function.html_table.php: + fixed email address in comments + + * NEWS + libs/plugins/function.html_table.php: + html_table: fixed th/tr output, added hdir support for column + headings,update docs to reflect new features + +2006-07-08 Messju Mohr + + * libs/plugins/function.html_table.php: + fix occasional notices on undefined variables + +2006-07-08 boots + + * libs/plugins/function.html_table.php: + Added ability to specify column headings in {html_table} + + Added th_attrs attribute which works similary to td_attr and tr_attr but + for TH elements. Changes the cols attribute to allow mixed values; a + numeric still specifies the number of columns to render but now an array + of values can be used to specify TH column values. The number of columns + is determine from the size of the array. Further, a comma-separated + string of column names can be used which is internally coverted to an + array and used as if it was specified as a normal array. + + Thanks for lynlyn for the feature request. + +2006-06-23 boots + + * libs/plugins/outputfilter.trimwhitespace.php: + fix comments in outputfilter.trimwhitespace + + * NEWS + libs/plugins/outputfilter.trimwhitespace.php: + fixed ordering of replacements in trimwhitespace output filter + + Thanks to Getty from IRC for reporting this. + +2006-06-20 boots + + * NEWS + libs/plugins/function.mailto.php: + update mailto function plugin to work around a firefox/thunderbird escaping + bug + + Thanks to elijahlofgren from the forums for reporting this and providing + the necessary patch + + * NEWS + libs/plugins/modifier.date_format.php: + emulate %l in the date_format modifier on windows + + thanks to Gibberish from the forums for reporting this + +2006-06-14 boots + + * NEWS + libs/plugins/modifier.capitalize.php: + Fix handling of apostrophes in the capitalize modifier. + + Thanks to asmecher from the forums for reporting this and providing a + partial solution. + +2006-05-28 Monte Ohrt + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + +2006-05-25 boots + + * NEWS + libs/Smarty_Compiler.class.php: + un-hide hidden xml open tags + +2006-05-09 boots + + * NEWS + libs/Smarty_Compiler.class.php: + separate handling of comment blocks from "special blocks" + + * NEWS + libs/plugins/function.popup_init.php: + reverted {popup_init} as proposed change to insertion behviour was not BC + +2006-05-04 boots + + * NEWS + libs/plugins/function.popup_init.php: + changed {popup_init} to only emit code once during a request + + Thanks to TGKnIght from forums + +2006-04-22 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of block-methods of registered objects + thanks to El Hombre Gris + +2006-04-04 Monte Ohrt + + * libs/plugins/function.html_select_date.php: + fix typo + +2006-03-09 Monte Ohrt + + * (Smarty_2_6_13) + NEWS: + update for release + +2006-03-08 Monte Ohrt + + * libs/plugins/modifier.regex_replace.php: + remove delim quote + + * libs/plugins/modifier.regex_replace.php: + fix delimiter issue + +2006-03-03 Monte Ohrt + + * libs/plugins/modifier.regex_replace.php: + use preg_replace to cover any space chars + + * libs/plugins/modifier.regex_replace.php: + fix problem with allowing "e" modifier + +2006-01-29 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed possiblity for E_NOTICE on an undefined variable in + Smarty_Compiler::_compile_if_tag() - thanks to sbeh + +2006-01-18 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_12) + NEWS: + commit 2.6.12 release + +2006-01-15 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed use of references $cache_attrs and $repeat in Smarty_Compiler. + + php does not allow to pass an assigned by reference to a function. since + php-5.1.2 + the reference to the lval gets lost when passing an assignment. + +2005-12-31 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fixed incompatible use of fread() in Smarty::_read_file() + it choke on php-5.1.1 and later. + thanks to andig for pointing this out. + +2005-12-21 boots + + * NEWS + libs/Smarty_Compiler.class.php: + Fix improper tokenization of certain inline math expressions. + + Thanks to gerard at forums for reporting this. + +2005-12-19 Messju Mohr + + * libs/plugins/function.math.php: + fixed problem with math in certain LC_NUMERIC locales. + thanks to wiebren for providing problem+solution. + +2005-12-14 Messju Mohr + + * NEWS: + fixed iso-latin1 special chars + +2005-12-14 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_11) + NEWS: + commit NEWS file for 2.6.11 + +2005-12-08 Messju Mohr + + * docs/de/getting-started.xml: + sync with en + +2005-11-29 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed code generation of non-cacheable blocks to play well with php's + "Alternative syntax" used for example in compiled {if}..{else}..{/if} + blocks. + + (see: http://php.net/manual/en/control-structures.alternative-syntax.php + on "Alternative syntax") + + thanks to kihara from the forum. + +2005-11-26 Messju Mohr + + * NEWS: + fixed handling of multiple identical calls to {insert}. + + the function was called multiple times, but all inserts where replaced + by the results of the first call to the insert function. + + * libs/plugins/compiler.assign.php + libs/plugins/function.config_load.php: + added credits + + * libs/plugins/function.popup.php: + added "closeclick" from + http://www.bosrup.com/web/overlib/?Command_Reference + +2005-11-23 boots + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/modifier.escape.php: + replace {} string access with equivalent substr() to avoid E_STRICT + warnings in PHP 5.1 + +2005-11-09 boots + + * NEWS + libs/Smarty.class.php: + return valid reference in get_config_vars() when given var is non-existant + +2005-10-11 Monte Ohrt + + * libs/plugins/block.textformat.php + libs/plugins/compiler.assign.php + libs/plugins/function.assign_debug_info.php + libs/plugins/function.config_load.php + libs/plugins/function.counter.php + libs/plugins/function.eval.php + libs/plugins/function.fetch.php + libs/plugins/function.html_options.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/function.math.php + libs/plugins/function.popup.php + libs/plugins/function.popup_init.php + libs/plugins/modifier.capitalize.php + libs/plugins/modifier.count_characters.php + libs/plugins/modifier.count_paragraphs.php + libs/plugins/modifier.count_sentences.php + libs/plugins/modifier.count_words.php + libs/plugins/modifier.date_format.php + libs/plugins/modifier.debug_print_var.php + libs/plugins/modifier.default.php + libs/plugins/modifier.escape.php + libs/plugins/modifier.indent.php + libs/plugins/modifier.lower.php + libs/plugins/modifier.regex_replace.php + libs/plugins/modifier.replace.php + libs/plugins/modifier.spacify.php + libs/plugins/modifier.string_format.php + libs/plugins/modifier.strip_tags.php + libs/plugins/modifier.truncate.php + libs/plugins/modifier.upper.php + libs/plugins/modifier.wordwrap.php + libs/plugins/shared.escape_special_chars.php + libs/plugins/shared.make_timestamp.php: + Added author title to plugins where they don't exist. I put my name where I + was the original or co-author. If there needs to be more credit given + somewhere, speak up! + +2005-10-10 Monte Ohrt + + * NEWS + libs/plugins/function.html_image.php: + add path_prefix to html_image, fix incorrect secure_dir error when image + file is missing + +2005-10-04 Monte Ohrt + + * demo/templates/index.tpl: + remove popup example, update section var syntax + +2005-09-16 Nuno Lopes + + * docs/de/getting-started.xml: + more fixes + + * docs/de/getting-started.xml: + fix php bug #34520: broken example display (de only) + +2005-08-30 Monte Ohrt + + * libs/plugins/modifier.escape.php: + change default charset from utf8 to iso-8859-1 + + * NEWS + libs/plugins/modifier.escape.php: + add char_set param + +2005-08-17 Monte Ohrt + + * NEWS: + fix notice in debug security check + + * libs/Smarty.class.php: + fix typo + + * NEWS + libs/Smarty.class.php: + return valid reference in get_template_vars() when given var is + non-existant + +2005-08-12 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add "urlpathinfo" escape type to escape modifier. (apache does not like %2F + in the PATH_INFO) + +2005-08-05 Monte Ohrt + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + +2005-08-04 Monte Ohrt + + * NEWS: + update secure_dir notes + + * NEWS: + allow debug.tpl to work from arbitrary dir + +2005-08-04 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed proper escaping for literal strings passed to + Smarty_Compiler::_expand_quoted_text() by + Smarty_Compiler::_parse_var_props() + +2005-07-27 Messju Mohr + + * NEWS + libs/plugins/shared.make_timestamp.php: + removed ambiguity for numeric values passed to smarty_make_timestamp(). + numeric values are *always* treated as timestamps now. + +2005-07-18 Messju Mohr + + * libs/Config_File.class.php: + removed E_NOTICE from Config_File::get() + + * libs/Smarty.class.php: + removed E_NOTICE + +2005-07-10 Yannick Torres + + * docs/fr/getting-started.xml: + sync with EN + +2005-07-08 Monte Ohrt + + * NEWS: + correct username in NEWS file + + * NEWS + libs/plugins/function.html_select_date.php: + added passthru attribute feature to html_select_date + +2005-07-03 Yannick Torres + + * docs/fr/language-snippets.ent + docs/fr/preface.xml: + sync with EN + +2005-06-16 Messju Mohr + + * docs/de/preface.xml + docs/de/preface.xml: + sync with en + +2005-06-13 Monte Ohrt + + * NEWS + libs/plugins/modifier.truncate.php: + add "middle" parameter to truncate modifier + +2005-06-10 Messju Mohr + + * docs/de/livedocs.ent: + added german livedocs.ent + + * docs/de/language-snippets.ent + docs/de/preface.xml: + sync with en + +2005-06-09 Messju Mohr + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/getting-started.xml: + sync with en + +2005-05-24 Yannick Torres + + * docs/fr/getting-started.xml + docs/fr/language-snippets.ent: + sync with EN + +2005-05-20 Monte Ohrt + + * libs/plugins/function.html_radios.php: + fix allowable label id characters + +2005-05-06 Monte Ohrt + + * NEWS + libs/plugins/function.html_radios.php: + make form input label ids optional (monte) + +2005-05-02 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + add error message for empty if/elseif statements + +2005-04-15 Monte Ohrt + + * NEWS + libs/plugins/function.html_radios.php: + cast selected value to string for comparison in html_radios + +2005-04-07 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + added xhtml compliance to html_select_date's year_as_text-feature + thanks to Mark West + + * NEWS + libs/plugins/function.html_select_date.php: + fixed handling of selected month html_select_date + thanks to Yuri Weseman for providing problem+solution + +2005-04-07 Nuno Lopes + + * docs/configure.in: + sync configure and file-entities scripts with phpdoc, for better + windows/cygwin support + +2005-03-31 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_9) + NEWS: + update NEWS file + +2005-03-30 Messju Mohr + + * libs/plugins/function.math.php: + re-enabled hex-constant. i hope in a sane way this time. + +2005-03-30 Monte Ohrt + + * libs/plugins/function.math.php: + fix function testing logic + + * libs/Smarty_Compiler.class.php: + disable variable func calls completely + + * libs/Smarty_Compiler.class.php: + disallow variable func calls when security is enabled + +2005-03-22 Messju Mohr + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + bumped version-number to 2.6.9-dev + added headline of 2.6.6 release to NEWS file + +2005-03-21 Messju Mohr + + * (Smarty_2_6_8) + NEWS: + maybe even better this way. thanks monte :) + + * NEWS: + little more clear news-entry + +2005-03-21 Monte Ohrt + + * NEWS: + update NEWS with e-modifier removal + + * (Smarty_2_6_8) + libs/plugins/modifier.regex_replace.php: + remove e-modifier + +2005-03-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + objects don't get casted to arrays anymore in {foreach} + +2005-02-26 Messju Mohr + + * NEWS + libs/Smarty.class.php: + add "null" as a valid token for {if} when security is enabled + +2005-02-25 Monte Ohrt + + * NEWS + libs/plugins/function.mailto.php: + add javascript_charcode option to mailto + +2005-02-24 Monte Ohrt + + * NEWS: + update NEWS file + + * QUICK_START + libs/plugins/function.html_radios.php: + add label ids to html_radios + +2005-02-10 Monte Ohrt + + * QUICK_START: + update with directory structure + +2005-02-10 Nuno Lopes + + * docs/Makefile.in: + fix chm generation + +2005-02-10 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed too agressive {strip} around delimiters inside strip-blocks + +2005-02-10 Monte Ohrt + + * QUICK_START: + fix a couple errors + +2005-02-10 Nuno Lopes + + * docs/Makefile.in + docs/README: + commiting the new tools to make the CHM manual. + +2005-02-09 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of strip-tags with non-default delimiters + +2005-02-04 Messju Mohr + + * libs/plugins/function.html_radios.php: + fixed syntax error. shame on me. + +2005-02-03 Monte Ohrt + + * QUICK_START: + fix example + + * QUICK_START: + initial commit + + * RELEASE_NOTES + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers in cvs + + * (Smarty_2_6_7) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit version numbers for new release + +2005-02-03 Messju Mohr + + * (Smarty_2_6_7) + libs/plugins/function.html_image.php: + fixed comment (thanks to CirTap) + +2005-02-01 Monte Ohrt + + * libs/plugins/function.html_image.php: + remove border tag + +2005-02-01 Messju Mohr + + * libs/Smarty.class.php: + fixed serialization of values containing newlines (like _cache_attrs) + in core_write_cache_file() + + bumped version to 2.6.6-dev-3 to indicate that the fileformat of cache + has changed + +2005-01-30 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of hashed opening php-tags inside strip-blocks + (reported by titi_rafa) + +2005-01-30 Nuno Lopes + + * docs/fr/language-snippets.ent: + fix build + +2005-01-28 Messju Mohr + + * NEWS + libs/plugins/modifier.escape.php: + escape:url now uses the (RFC 1738 compliant) rawurlencode() + +2005-01-23 Messju Mohr + + * libs/Smarty.class.php: + replaced ? true : false and removed intermediate $_cookie_var in the + handling of the SMARTY_DEBUG-cookie + +2005-01-22 Yannick Torres + + * docs/fr/bookinfo.xml: + update EN-Revision tag + +2005-01-21 Monte Ohrt + + * README + RELEASE_NOTES + docs/de/bookinfo.xml + docs/fr/bookinfo.xml + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.cycle.php + libs/plugins/function.debug.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php + libs/plugins/function.mailto.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/outputfilter.trimwhitespace.php: + de-spammify e-mails + + * README + RELEASE_NOTES + docs/de/bookinfo.xml + docs/fr/bookinfo.xml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.cycle.php + libs/plugins/function.debug.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php + libs/plugins/function.mailto.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/outputfilter.trimwhitespace.php: + update copyright notices, e-mail addresses + +2005-01-06 Messju Mohr + + * libs/Smarty_Compiler.class.php: + reduced the code that is generated on a {foreach}-block that has a + name. + + instead of pre-computing all foreach-properties (like first, last, + show) on each iteration, they are computed on demand as soon as + {$smarty.foreach.*}-variables are used. + + * NEWS + libs/Smarty_Compiler.class.php: + slight optimization in the compilation of $smarty.const.FOO . + + more complex consts like $smarty.const.$name still compile to + constant($this->_tpl_vars['name']) + +2005-01-05 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + make block functions and registered objects' block methods use a + local variable for block_content instead of $this->_block_content + + it's not necessary to have $smarty->_block_content accessible. + +2005-01-04 Yannick Torres + + * docs/fr/bookinfo.xml: + sync with EN + +2005-01-01 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + Happy new year from germany. + +2004-12-28 Monte Ohrt + + * libs/Smarty.class.php: + fix _read_file comments + +2004-12-26 Yannick Torres + + * docs/fr/getting-started.xml + docs/fr/preface.xml: + typo + + * docs/fr/language-defs.ent + docs/fr/language-snippets.ent + docs/fr/livedocs.ent: + sync with EN & typo + +2004-12-21 Yannick Torres + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/translation.xml: + sync with EN + +2004-12-17 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed escaping of template-filenames in the generated code that loads + needed plugins + +2004-12-15 Monte Ohrt + + * NEWS + libs/plugins/function.popup.php: + fix invalid HTML issue with popup + +2004-12-06 boots + + * NEWS + libs/plugins/function.popup.php: + - fixed {popup} to properly handle inarray and function parameters and + added support for mouseoff and followmouse options + +2004-11-21 Mehdi Achour + + * docs/fr/livedocs.ent: + add livedocs specific entities files + +2004-11-16 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + cleaned up typecasting + +2004-11-15 Messju Mohr + + * libs/plugins/function.html_options.php: + fixed semantically misleading check for $options (use isset() instead + of is_array() because it is always an array). + + thanks to albert almeida. + +2004-11-08 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused code + +2004-10-25 Mehdi Achour + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml: + sync with en + +2004-10-13 Monte Ohrt + + * NEWS: + update header + +2004-10-02 Messju Mohr + + * NEWS: + fixed nocache-handling with nested includes. there was a logical error + in the replacement of internal nocache-tags to dynamic content that + lead to false results with deeply nested includes or with + nocache-blocks inside nocache-blocks. + + many thanks to Lars Jankowfsky for providing big help on reproducing + and tracking down this bug! + +2004-10-01 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + - better header for compiled includes (more in line with compiled + templates) + + - reuse cache_serials if a file is compiled more than once in one + process (force_compile) + + - don't print nocache-delimiters wenn already inside + process_cached_inserts() + +2004-09-29 Messju Mohr + + * libs/Smarty.class.php: + switched from @count() to !empty() . this was pointed out a few times + by a few people with buggy error-handlers + + * libs/Smarty_Compiler.class.php: + added some property declarations + +2004-09-28 Messju Mohr + + * libs/Smarty.class.php: + bumped up version number to reflect incompatibility in tempfiles of + 'core' vs. 'internals' + +2004-09-24 Messju Mohr + + * libs/plugins/function.html_select_date.php: + fixed $start_year when no value for the year in $time is given. + +2004-09-21 Messju Mohr + + * libs/plugins/function.html_table.php: + fixed handling of "inner"-attribute + + * libs/Smarty_Compiler.class.php: + fixed handling of object derefence inside backticks + +2004-09-20 Monte Ohrt + + * libs/debug.tpl: + add tags + +2004-09-18 boots + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.config_load.php + libs/plugins/function.debug.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + Fixed \\r\\n line endings mistakenly introduced in last commit. d'oh. + +2004-09-16 boots + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.debug.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + Moved /libs/core to /libs/internals and created new constant, + SMARTY_CORE_DIR which defaults to SMARTY_DIR/internals. This should help + CVS and rsynch users butupgrades will require changes and this may affect + 3rd party plugins that use the /core dir. + +2004-09-15 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + moved $this->_num_const_regexp out of $this->_var_regexp and added it + to the places that affect $this->_var_regexp + + this should fix some problems parsing plugin-names endings with digits + +2004-09-14 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update files to 2.6.6-dev + +2004-09-13 Messju Mohr + + * NEWS: + fixed typo + +2004-09-13 Monte Ohrt + + * (Smarty_2_6_5) + NEWS: + update NEWS file with parsing correction note + +2004-09-11 Messju Mohr + + * libs/plugins/function.debug.php: + removed notice from {debug} + thanks to Peter Billen for pointing this one out! + +2004-09-11 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix more object calling syntax issues + +2004-09-10 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added $smarty->security_settings['ALLOW_CONSTANTS'] + including test-cases for them + +2004-09-09 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + break down regex to digestable chunks, fix multiple param problem with + method calls, + add object method testing to unit_test cases + + * libs/Smarty_Compiler.class.php: + update code comment with more examples + + * libs/Smarty_Compiler.class.php: + allow objects in arbitrary param positions + + * libs/Smarty_Compiler.class.php: + fix object parameter regex, allow one level of object indirection + + * libs/Smarty_Compiler.class.php: + fix compile problem with numeric constants and math operator matching + +2004-09-07 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update files to 2.6.5-dev + + * (Smarty_2_6_4) + NEWS: + update NEWS file with 2.6.4 header + +2004-08-31 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix preg_quote + + * libs/Smarty_Compiler.class.php: + fix math in object params, clean up some regex on the way, change + preg_ delimiters to ~ to avoid character clashes with ! and % + +2004-08-30 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + add $smarty.ldelim and $smarty.rdelim to smarty special var + +2004-08-29 Messju Mohr + + * NEWS + libs/core/core.write_file.php: + tempnam() seems to be borken on many installation. + + now we try tempnam first and if that fails we generate our own + temp-filename with uniqid() + +2004-08-23 Monte Ohrt + + * libs/plugins/modifier.capitalize.php: + dont use constant, use static var instead + + * libs/plugins/modifier.capitalize.php: + implement optional param to capitalize for digit behavior + + * libs/plugins/modifier.capitalize.php: + another commit to capitalize, taking special chars into account + +2004-08-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + cleaned up attribute-handling in Smarty_Compiler::_compile_foreach_start() + +2004-08-23 Monte Ohrt + + * NEWS + libs/plugins/function.html_select_date.php + libs/plugins/modifier.capitalize.php: + fix capitalize modifier to not rely on buggy ucwords() func + +2004-08-20 Monte Ohrt + + * libs/plugins/function.html_select_date.php: + update version + + * NEWS + libs/plugins/function.html_select_date.php: + make time param work with negative timestamps, force year range to include + given date unless explicitly set + +2004-08-19 Monte Ohrt + + * NEWS + libs/plugins/function.fetch.php: + fix bug with fetch, passing user/pass in url did not work + +2004-08-13 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed handling of {foreachelse} and {sectionelse} that got borked with + the latest commit (v 1.330) + +2004-08-12 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed occasional wrong error messages on mismatched tags when + {else}, {elseif}, {foreachelse} or {sectionelse} is involved + + thanks to Ooypunk for pointing me on this + +2004-08-12 Nuno Lopes + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in: + enable russian PDF builds + +2004-07-30 Nuno Lopes + + * docs/configure.in: + typo + + * docs/Makefile.in + docs/README + docs/configure.in: + add make test_xml + this is usefull to detect XML problems + +2004-07-29 Nuno Lopes + + * docs/configure.in: + avoid warnings in head + + * docs/.cvsignore + docs/Makefile.in + docs/README + docs/configure.in: + build pdf files + just type make pdf + +2004-07-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of methods arguments. + + thanks to Manfred Wischin for finding this one and providing the + conceptual fix. + +2004-07-23 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + there was little flaw in smarty_function_html_radios() and + smarty_function_html_checkboxes(): + + the newly introduced assign-attribute was still added to the + tag-output as an extra-attribute. + + fixed. + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/modifier.date_format.php: + backed out renaming of _get_plugin_filepath() to get_plugin_filepath() + + we'll stick to _get_plugin_filepath() and look for a more viable + solution to be exposed to plugin-writers. + +2004-07-20 Messju Mohr + + * libs/Smarty_Compiler.class.php + libs/core/core.is_trusted.php + libs/plugins/compiler.assign.php: + Some fixes on PhpDocumentor comments. Thanks go to Ruben Vermeersch. + +2004-07-16 andreas halter + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/language-defs.ent + docs/de/language-snippets.ent + docs/de/preface.xml: + - updated for 2.6.3 + - updates for new build system + - added missing files + - corrections from users + - revcheck comments for all files + - big up to didou and nuno, brilliant work + - make test: ok + - make: ok + +2004-07-16 Nuno Lopes + + * docs/de/getting-started.xml: + fix the revision tracking tag + the revision number might not be right. just check it, please + +2004-07-16 andreas halter + + * docs/de/getting-started.xml: + - updated version (incl revcheck comment) for revcheck testing + +2004-07-14 Monte Ohrt + + * libs/Smarty.class.php: + replace " with ' where literal strings are quoted (ever so slight speedup) + +2004-07-12 Messju Mohr + + * libs/plugins/modifier.date_format.php: + changed call from $smarty->_get_plugin_filepath() to + $smarty->get_plugin_filepath() + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php: + renamed calls to $smarty->_get_plugin_filepath() to + $smarty->get_plugin_filepath() + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php: + renamed Smarty::_get_plugin_filepath() to Smarty::get_plugin_filepath() + + * NEWS + libs/Smarty.class.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + removed touch() call. changing the timestamp of the compiled-template + to the source template's may be irritating for certain + source-code-caches. now a newly compiled template gets the current + time as timestamp. + +2004-07-02 gerald croes + + * docs/fr/getting-started.xml + docs/fr/preface.xml: + Fixed missing tags to be able to make doc again + + * docs/fr/preface.xml: + added the "is a good thing [TM]" as in en docs + + * docs/fr/getting-started.xml: + added ctags, updated screen => programm listing. + added the technical note founded on the en doc + +2004-07-02 Monte Ohrt + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php + libs/plugins/function.mailto.php: + add assign attribute to html_checkboxes and html_radios + +2004-07-01 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed use of get_include_filepath() inside + get_auto_filename(). thanks go to c960657 + + * NEWS + libs/Smarty_Compiler.class.php: + enhanced error-reporting for {foreach} + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of digits inside tagnames. this problem slipped into + the regexps by adding support for numeric contants next to string + constants as variables. + +2004-06-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed escaping of backslashes in Smarty_Compiler::_quote_replace() + +2004-06-23 Monte Ohrt + + * libs/plugins/modifier.date_format.php: + display date_format %e, %T and %D as expected for windows + +2004-06-17 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + changed version-number to 2.6.4-dev + +2004-06-16 Monte Ohrt + + * (Smarty_2_6_3) + NEWS: + update NEWS file with version number + +2004-06-09 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + added escapement of ' + + * docs/fr/translation.xml: + Add other translators. + +2004-06-08 Messju Mohr + + * libs/Smarty.class.php: + made the correct value of "use_sub_dirs" available to the compiler. + (not worth a NEWS-entry, i think) + +2004-06-01 Messju Mohr + + * libs/plugins/function.fetch.php: + fix: proper initialistaion of $content. + thanks to Dmitry Koteroff for pointing this out. + +2004-05-29 Mehdi Achour + + * docs/fr/translation.xml: + oups :) + + * docs/fr/translation.xml: + added translation file + +2004-05-28 Nuno Lopes + + * docs/Makefile.in: + clean also file-entities.php + +2004-05-28 Messju Mohr + + * NEWS + libs/plugins/function.mailto.php: + added obfuscation of protocol-string in {mailto} when using + hex-encoding (thanks to bharat) + +2004-05-26 Messju Mohr + + * NEWS + libs/Smarty.class.php: + enhanced auto-generated filenames for templates_c and cache + + incremented Smarty::_version because the tempfiles' structure changed + a little + +2004-05-23 Mehdi Achour + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/preface.xml: + WS and added revcheck + +2004-05-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed typo in error-messages + + * docs/de/language-snippets.ent + docs/fr/language-snippets.ent: + added empty language-snippets.ent to fix "make web" + +2004-05-12 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add 'nonstd' escape modifier + +2004-05-07 Monte Ohrt + + * NEWS + libs/plugins/block.textformat.php: + update textformat to not output wrap chars after last para + +2004-05-06 Messju Mohr + + * NEWS + libs/core/core.write_file.php: + use tempnam() instead of unqid() to create better temporary files in + smarty_core_write_file(). + + (thanks to xces for finding this race-condition and his work on + fixing it) + +2004-05-04 Messju Mohr + + * libs/Smarty.class.php: + added check if for file_exists() to Smarty::_read_file() + +2004-04-30 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add 'mail' attribute to escape modifier + +2004-04-20 Mehdi Achour + + * docs/manual.xml.in: + added the language-snippets.ent file and started using entities for notes + under en/programmers/api-functions + +2004-04-18 Mehdi Achour + + * docs/de/getting-started.xml + docs/fr/getting-started.xml: + new global entity for zend and php-accelerator + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/preface.xml: + added myself as translator and added vim comments and xml tags + +2004-04-16 Messju Mohr + + * NEWS: + added entry for numeric constants + + * libs/Smarty_Compiler.class.php: + removed unused 2nd param in call to _parse_var() + + * libs/Smarty_Compiler.class.php: + added explanation for $this->_num_const_regexp + + * NEWS + libs/plugins/modifier.escape.php: + added escape type "decentity" to smarty_modifier_escape() + + * libs/Smarty_Compiler.class.php: + enabled numerical constants be parsed as statements. + (like {10} or {10|@range:12} ) + + * libs/Smarty_Compiler.class.php: + removed unused $smarty_compiler->_dvar_num_var_regexp + + * libs/Smarty.class.php: + reverted Stuff + + * libs/debug.tpl + libs/core/core.assemble_plugin_filepath.php + libs/core/core.read_cache_file.php + libs/core/core.write_file.php + libs/plugins/function.eval.php + libs/plugins/function.popup.php + libs/plugins/modifier.escape.php + libs/plugins/shared.make_timestamp.php: + reverted stuff + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/debug.tpl + libs/core/core.assemble_plugin_filepath.php + libs/core/core.read_cache_file.php + libs/core/core.write_file.php + libs/plugins/function.eval.php + libs/plugins/function.popup.php + libs/plugins/modifier.escape.php + libs/plugins/shared.make_timestamp.php: + Smarty_Compiler.class.php + +2004-04-15 Messju Mohr + + * NEWS + libs/core/core.write_compiled_include.php: + made smarty_core_write_compiled_include() php5-aware + + if someone knows a better way than patching the source with the + tokenizer, please stand up! + +2004-04-14 Nuno Lopes + + * docs/Makefile.in: + remove file-entities.ent also + + * docs/.cvsignore + docs/Makefile.in + docs/README: + allow make revcheck + +2004-04-13 Nuno Lopes + + * docs/configure.in: + do not need inipath + +2004-04-13 Mehdi Achour + + * docs/TODO: + done + + * docs/configure.in + docs/manual.xml.in: + now the files entites are generated dynamically + +2004-04-12 Messju Mohr + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php: + removed unused functionality to load a subset of lines from a file in + Smarty::_read_file() + + additionally removed a warning that is emitted since php-4.3.5 when + fread() is called on an empty file (with filesize()==0). thanks to + Andreas Streichardt who pointed this out. + + * NEWS + libs/core/core.is_secure.php: + smarty_core_is_secure() only checks the file for readability now, not + the directory where is in. + + * libs/Smarty.class.php: + removed unused security_setting 'ALLOW_CONSTANTS' + +2004-04-07 Messju Mohr + + * libs/plugins/function.assign_debug_info.php + libs/plugins/function.cycle.php + libs/plugins/function.mailto.php: + removed trailing spaces + + * libs/Smarty.class.php: + removed unused $smarty->_error_msg + +2004-04-04 Nuno Lopes + + * docs/configure.in: + fixing my crap + put build_date back on-line + +2004-04-03 Nuno Lopes + + * docs/Makefile.in + docs/configure.in + docs/manual.xml.in: + trying to fix ru problems + +2004-03-30 Monte Ohrt + + * libs/core/core.display_debug_console.php: + fix problem with debug_tpl path and security + + * NEWS + libs/core/core.display_debug_console.php: + fix problem displaying debug console when $default_resource_type is not + "file:" + +2004-03-29 Mehdi Achour + + * docs/TODO: + and finally, add a TODO here + + * docs/de/bookinfo.xml + docs/de/manual.sgml + docs/fr/bookinfo.xml + docs/fr/manual.xml: + translate bookinfo.xml and put back the translators + +2004-03-28 Mehdi Achour + + * docs/manual.xml.in: + add global.ent and define some general entities + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/language-defs.ent + docs/de/preface.xml: + add new de files + + * docs/de/appendixes.sgml + docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/html-common.dsl + docs/de/preface.sgml + docs/de/programmers.sgml: + drop old de files + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/manual.xml + docs/fr/preface.xml: + add ommited files + + * docs/fr/language-defs.ent: + split the french dir + + * docs/fr/appendixes.sgml + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/html-common.dsl + docs/fr/manual.sgml + docs/fr/preface.sgml + docs/fr/programmers.sgml: + drop old french files + + * docs/manual.xml.in: + let's put the new build system + +2004-03-26 Mehdi Achour + + * docs/de/common.dsl + docs/de/html.dsl + docs/fr/common.dsl + docs/fr/html.dsl + docs/fr/php.dsl: + not needed anymore + +2004-03-24 Nuno Lopes + + * docs/Makefile.in: + updated stylesheets + highlight PHP automatically + + * docs/Makefile.in + docs/html.dsl: + remove unneeded file + +2004-03-23 Nuno Lopes + + * docs/version.ent.in: + remove this also + + * docs/getting-started.sgml: + remove this one too + + * docs/appendixes.sgml + docs/common.dsl + docs/designers.sgml + docs/html-common.dsl + docs/manual.sgml + docs/php.dsl + docs/preface.sgml + docs/programmers.sgml: + removing uneeded files + + * docs/.cvsignore: + commiting missing files for docbook + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in + docs/manual.xml.in: + bundling docbook 4 + now make and make web works + +2004-03-23 Messju Mohr + + * NEWS + libs/plugins/function.config_load.php: + unrolled call to the is_compiled()-check to be able to supply the + correct resource_base_path for config_load. this avoids errors when + config-files are accessed where security is enabled. + + thanks to shuther for pointing out this bug. + +2004-03-20 Nuno Lopes + + * docs/manual.xml.in: + fix build date + +2004-03-18 Messju Mohr + + * libs/core/core.is_secure.php: + removed merging of $smarty->template_dir into $smarty->secure_dir + + the resource_base_path is considerd secure instead. this change should + have absolutely no impact on smarty's security's behaviour + +2004-03-18 Nuno Lopes + + * docs/configure.in: + correcting non-existent var + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in + docs/manual.xml.in + docs/version.ent.in: + generate build date + + * docs/.cvsignore + docs/Makefile.in + docs/README + docs/configure.in + docs/manual.xml.in: + new build/test system + +2004-03-18 Messju Mohr + + * libs/Smarty.class.php: + moved setting of a default resource_base_path from + Smarty::_parse_resource_name() to Smarty::_fetch_resource_info() + + this shouldn't affect anything, since all calls to + _parse_resource_name() that are not done from within + _fetch_resource_info() all pass their own resource_base_path + +2004-03-17 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed '.' from the list of default resource_base_paths in + _parse_resource_name() + + this should only affect _parse_resource_name() for templates, not for + php-resources and not for config_files. the latter pass two their own + resource_base_path. + +2004-03-16 Mehdi Achour + + * docs/appendixes.sgml + docs/getting-started.sgml + docs/preface.sgml: + adding editor comments + + * docs/appendixes.sgml + docs/getting-started.sgml: + cleaning words spacing, killing tabulations, using roles for + programlisting.. + +2004-03-15 Messju Mohr + + * libs/Smarty.class.php: + simplified Smarty::clear_all_cache(); + +2004-03-12 boots + + * docs/programmers.sgml: + Updated is_cached prototype to indicate proper return type. (thanks to + Geoffrey Hoffman) + +2004-03-11 Messju Mohr + + * libs/core/core.assemble_plugin_filepath.php: + fixed little bug that prevented plugins filepaths that are found in + php's include_path (and not in one of the plugins_dirs) from being + cached in the internal plugins-filepath-cache + +2004-03-01 Monte Ohrt + + * docs/designers.sgml: + update include_php docs:wq + :q + + * docs/appendixes.sgml: + update componentized template example to something useful + +2004-02-24 Messju Mohr + + * NEWS + libs/Smarty.class.php: + _parse_resource_name() returned true on non-existant absolute + paths. This caused a warning on _fetch_resource_info() when used in + conjunction with template_exists(). It should be fixed now without + negative effects. + +2004-02-24 Monte Ohrt + + * docs/designers.sgml: + one more typo + + * docs/designers.sgml: + fix typo + +2004-02-24 Messju Mohr + + * NEWS + libs/core/core.is_secure.php: + smarty_resource_*_secure got &$smarty passed errornously as 3rd + parameter and not as 2nd. this is fixed. + +2004-02-23 Messju Mohr + + * NEWS: + fix handling of integer values like width and delay im + smarty_function_popup() + + * libs/plugins/function.popup.php: + fixed handling of integer-attributes + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + updated version to 2.6.3-dev + +2004-02-22 Messju Mohr + + * libs/plugins/function.html_select_date.php: + removed notice on html_select_date with the month_empty-attribute + + * libs/plugins/function.mailto.php: + removed 2 notices of undefined vars (thanks Cit) + +2004-02-17 Monte Ohrt + + * NEWS: + add header + + * (Smarty_2_6_2) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change some info in headers, remove fluff + +2004-02-13 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + correctly handle partially empty dates (like "2004--" or "-12-"). + + * docs/programmers.sgml: + learned something about and sgml and applied this to the + use.sub.dirs-section :) + + * docs/designers.sgml: + changed attribute-name "checked" to "selected" in the docs for + html_radios and html_checkboxes. "checked" is deprecated for ages + AFAIK and selected is recommended for consistency with {html_options} + + * docs/programmers.sgml: + added note about use_sub_dirs and Smarty-2.6.2 . + fixed markup for section about clear_compiled_tpl() . + +2004-02-12 Messju Mohr + + * NEWS + libs/Config_File.class.php: + YES and NO should not be booleanized inside triple-quotes in a + config-file. this behaviour changed by accident in 2.6.1 and is now + reverted to pre-2.6.1 behaviour + +2004-02-10 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fixed slurping of a the next line following a triple-quoted value in a + config-file + +2004-02-07 Messju Mohr + + * libs/Config_File.class.php: + avoid @-operator for handling empty lines in Config_File.class.php + + * libs/Smarty_Compiler.class.php: + removed two notices from Smarty_Compiler::_parse_is_expr() + (thanks shuther!) + + * NEWS + libs/Smarty.class.php: + changed default for use_sub_dirs to false + + * libs/plugins/function.mailto.php: + removed notice of undefined variable. (thanks shuther!) + +2004-01-29 Messju Mohr + + * libs/Smarty_Compiler.class.php: + added file and line-number-information to error-messages regarding + assigned objects an an error messages regarding modifiers with + security. + +2004-01-27 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed use of temporary var $_params in compiled code of block-plugins + + * NEWS + libs/plugins/function.popup.php: + fixed quoting of values in smarty_function_popup() + +2004-01-25 Messju Mohr + + * docs/programmers.sgml: + documented parameters of Smarty::clear_compiled_tpl() + + * libs/Smarty_Compiler.class.php: + Smarty_Compiler::_syntax_error() uses Smarty::_trigger_fatal_error() now + instead of the trigger_error()-function + + * libs/Smarty.class.php: + Smarty::_trigger_fatal_error() uses Smarty::trigger_error() now, + instead of the native trigger_error()-function + + * libs/Smarty_Compiler.class.php: + unrecognized custom-functions trigger an error at compile now, not at + display-time. + +2004-01-23 Monte Ohrt + + * docs/getting-started.sgml: + reword a paragraph + +2004-01-22 Messju Mohr + + * libs/plugins/function.config_load.php: + removed emission of unnecessary notices for unavailable config-files + in config_load() + + * NEWS + libs/Config_File.class.php: + fixed handling of hidden sections in Config_File + +2004-01-21 Messju Mohr + + * NEWS + libs/plugins/function.config_load.php: + added handling of resources for {config_load} + +2004-01-19 Messju Mohr + + * NEWS + libs/plugins/function.html_table.php: + fixed bug when using arrays with tr_attr and td_attr in {html_table} + +2004-01-16 Monte Ohrt + + * NEWS: + add unit testing + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers, add initial unit test directory + + * (Smarty_2_6_1) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers for 2.6.1 release + +2004-01-16 Messju Mohr + + * (Smarty_2_6_1) + NEWS + docs/programmers.sgml + libs/Smarty.class.php: + renamed $smarty->tpl_rror_reporting to $smarty->error_reporting + "tpl_" is a bit redundant here (it's a TemPLate-engine overall :) + +2004-01-15 Messju Mohr + + * libs/plugins/function.html_image.php: + forgot to remove duplicate is_secure()-check + + * NEWS + libs/plugins/function.html_image.php: + fix: $smarty->security is now correctly handled + + minor optimizations: + core/core.is_secure.php is only included when needed + $dpi_default is only determined when needed + +2004-01-14 Messju Mohr + + * docs/appendixes.sgml + docs/programmers.sgml: + removed suggestions to use extract() from the manual + + * docs/designers.sgml: + fixed typo + +2004-01-12 Messju Mohr + + * docs/designers.sgml: + mention SCRIPT_NAME below {$smarty} reserved variable because it got + lost in the docs for $smarty->global_assign + + * docs/designers.sgml: + added docs for {$smarty.version} special variable + + * docs/programmers.sgml: + removed docs for $global_assign + + * docs/programmers.sgml: + added docs for tpl_error_reporting + + * docs/designers.sgml: + added docs for year_empty-, month_empty- and day_emtpy-attributes of + html_select_date. maybe an example is needed to better explain empty + values in YYY-MM-DD. + +2004-01-10 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed handling of {php}-tags + +2004-01-10 Monte Ohrt + + * docs/designers.sgml: + fix html_checkboxes examples + +2004-01-08 Messju Mohr + + * NEWS + libs/core/core.assemble_plugin_filepath.php: + added caching of requested paths to smarty_core_assemble_plugin_filepath() + + * NEWS: + fix handling of comments inside {php}- and {literal}-blocks + + * libs/Smarty_Compiler.class.php: + fixed handling of comments inside {php} and {literal} + +2004-01-06 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fixed bug handling triple-quotes in config-files + + * libs/Config_File.class.php: + fixed bugs with triple-quotes in config-files + thanks BRDude for finding them testing! + +2004-01-02 Messju Mohr + + * libs/Smarty.class.php: + removed unnecessary param in call to _fetch_resource_info() + +2003-12-30 Messju Mohr + + * libs/Smarty.class.php: + oops! removed tabs. + +2003-12-27 Messju Mohr + + * NEWS + libs/Smarty.class.php: + made $SCRIPT_NAME available again + changes default for request_use_auto_global to prefer autoglobals + + * libs/Smarty.class.php: + removed tabs and trailing spaces + + * NEWS + libs/Smarty_Compiler.class.php: + readded default_modifiers. who removed that? + +2003-12-23 Monte Ohrt + + * NEWS: + add portuguese docs + +2003-12-22 Monte Ohrt + + * docs/designers.sgml: + fix counter example + +2003-12-19 Monte Ohrt + + * libs/Smarty.class.php: + add debug console persistance feature + +2003-12-19 Messju Mohr + + * libs/plugins/block.textformat.php + libs/plugins/function.html_table.php + libs/plugins/function.popup.php: + removed extract(). enhanced parameter parsing. + + * libs/plugins/function.counter.php + libs/plugins/function.fetch.php + libs/plugins/function.popup_init.php + libs/plugins/modifier.capitalize.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.date_format.php + libs/plugins/modifier.debug_print_var.php + libs/plugins/modifier.escape.php + libs/plugins/modifier.indent.php + libs/plugins/modifier.lower.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/modifier.upper.php + libs/plugins/modifier.wordwrap.php + libs/plugins/outputfilter.trimwhitespace.php + libs/plugins/shared.escape_special_chars.php: + removed tabs. fixed indentiation. + + * libs/plugins/modifier.truncate.php: + removed tabs + + * libs/plugins/function.counter.php + libs/plugins/function.cycle.php: + removed extract() from parameter-parsing + +2003-12-17 Messju Mohr + + * libs/plugins/function.html_select_date.php: + fix plugin-name in error message + + * libs/plugins/function.html_select_time.php: + remove extract-call from {html_select_time} + + * NEWS + libs/plugins/function.html_select_date.php: + allow single-digit days and months without smarty_make_timestamp() + this makes dates like "1968-11-6" work correctly since no strtotime() + is involved + + add warning when unknown parameter is passed + +2003-12-16 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fix headers sent erroneously with cache_modified_check and fetch() + +2003-12-12 Monte Ohrt + + * libs/plugins/function.config_load.php: + move set_path() call below the conditional bracket + + * NEWS + libs/plugins/function.config_load.php: + fix config_load filepath bug + +2003-12-12 boots + + * docs/designers.sgml: + Updated language.function.if with additional annotation and to fix error + that broke docs build process + +2003-12-11 Messju Mohr + + * libs/Smarty_Compiler.class.php: + little optimization for "is odd" and "is even" + +2003-12-11 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix 'is even by' and 'is odd by' logic + +2003-12-11 Messju Mohr + + * docs/designers.sgml: + update example-output of {mailto} + + * libs/plugins/function.mailto.php: + removed extract-call -> cleaner parameter-handling + + * libs/plugins/function.mailto.php: + fixed indentiation + + * TODO: + removed two done topics + +2003-12-11 boots + + * docs/designers.sgml: + Updated language.function.if to describe qualifiers (thanks andre) + +2003-12-10 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + added day_empty, month_empty, year_empty and all_empty attributes + to pass an undefined date use {html_select_date time="--" ...} + + * libs/plugins/function.html_select_date.php: + removed extract()-call + + * libs/plugins/function.html_select_date.php: + fixed indetiation + +2003-12-10 boots + + * NEWS + docs/designers.sgml: + Added table to language.function.if to describe qualifiers + +2003-12-09 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php: + strict comparason didn't work in all cases. use type-casting now. + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php: + fix bug when comparing array-keys to "selected" in html_options and + html_checkboxes + + in_array() uses "strict" comparason now. + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php: + removed tabs, fixed indentiation + +2003-12-08 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + add better checks for correctly nested tags when compiling + +2003-12-04 Messju Mohr + + * libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix: check $smarty->request_use_auto_globals at the last occurences of + HTTP_*_VARS + +2003-12-03 Messju Mohr + + * NEWS + libs/Smarty.class.php: + remove $global_assign property from Smarty and $global_assign-handling + from the constructor. the only visible change is, that $SCRIPT_NAME is + not available in the tempates anymore. $smarty.server.SCRIPT_NAME has + to be used from now. + +2003-12-03 boots + + * docs/designers.sgml: + Fixed example for count_characters + +2003-12-01 boots + + * docs/designers.sgml: + Added section "Escaping Smarty Parsing" under Basic Syntax. + +2003-12-01 Messju Mohr + + * libs/core/core.create_dir_structure.php: + thought again about my latest commit and backed it out. + + * libs/core/core.create_dir_structure.php: + fix root-dir-handling on windows filepath + +2003-11-29 boots + + * libs/plugins/function.config_load.php: + really make the fixes the last patch was supposed to do + + * libs/plugins/function.config_load.php: + removed tabs and killed trailing white-space + + * libs/plugins/function.config_load.php: + changed $smarty->_syntax_error to $smarty->trigger_error + +2003-11-27 Messju Mohr + + * NEWS + libs/plugins/modifier.debug_print_var.php: + remove warning in debug_print_var on php-resources + + * README: + fix version number + +2003-11-26 Messju Mohr + + * libs/Smarty_Compiler.class.php: + raise max_level for $smarty.config... to 3 to allow arrays of config-vars + +2003-11-25 Messju Mohr + + * libs/Smarty.class.php: + changed version-tag to indicate incompatibility to older compiled + templates + +2003-11-24 Messju Mohr + + * NEWS + libs/plugins/compiler.assign.php + libs/plugins/function.assign.php: + move function.assign.php to compiler.assign.php + + * libs/core/core.get_include_path.php: + silence occasional warnings of open_basedir- and + safe_mode-restrictions in core.get_include_path.php + +2003-11-23 Messju Mohr + + * libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + avoid touch()-ing of recently unlinked files by touch()-ing the + tempfile before rename instead of touch()-ing the resulting file after + rename. + + * NEWS + libs/Smarty.class.php: + add property $tpl_error_reporting + +2003-11-22 Messju Mohr + + * libs/plugins/function.assign.php: + remove use of extract() in smarty_function_assign() + + * NEWS + libs/Smarty.class.php: + remove property $undefined. "null" is used literally instead + +2003-11-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + remove two E_NOTICES + +2003-11-20 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change version to 2.6.1-dev + +2003-11-19 Monte Ohrt + + * (Smarty_2_6_0) + NEWS: + update NEWS file + + * (Smarty_2_6_0) + docs/designers.sgml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change version numbers to 2.6.0 + +2003-11-19 Messju Mohr + + * docs/designers.sgml + docs/de/designers.sgml + docs/fr/designers.sgml: + fix examples of escape-modifier (in docs, docs/de and docs/fr !) + +2003-11-18 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() + + * libs/Smarty.class.php: + removed extract-calls from _include()- and _eval()-wrappers + variables passed with {include_php} have to accessed as members of $params + now + +2003-11-17 Messju Mohr + + * docs/designers.sgml: + fixed typo + +2003-11-13 Messju Mohr + + * libs/Config_File.class.php: + fix occasional notice + +2003-11-13 andreas halter + + * docs/de/designers.sgml: + - added cat modifier, thanks messju :-) + +2003-11-13 Monte Ohrt + + * (Smarty_2_6_0-RC3) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit RC3 tags + +2003-11-13 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of $var.key inside [] + + * libs/Smarty.class.php: + fix unnecessary loading of core.load_resource_plugin.php + + * (Smarty_2_6_0-RC3) + docs/fr/designers.sgml: + fixed example of html_table + +2003-11-11 Messju Mohr + + * NEWS + libs/core/core.process_cached_inserts.php: + fix handling of assign inside {insert}-tags + +2003-11-06 Messju Mohr + + * libs/core/core.read_cache_file.php: + added $exp_time-parameter + + * docs/programmers.sgml: + added $exp_time to cache_handler_func-example + + * libs/Smarty.class.php + libs/core/core.write_cache_file.php: + added $exp_time-parameter of clear_cache() and clear_all_cache() to + cache_handler_func. + +2003-11-05 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fix handling if [...] inside triple-quotes in config-files + +2003-11-04 Messju Mohr + + * libs/Smarty.class.php: + fixed little bug in _parse_resource_name() (jlgunter, messju) + +2003-11-03 andreas halter + + * docs/designers.sgml + docs/de/designers.sgml + docs/fr/designers.sgml: + - changed Smarty.php.class occurences to Smarty.class.php + +2003-10-29 boots + + * docs/appendixes.sgml + docs/designers.sgml + docs/manual.sgml + docs/programmers.sgml + docs/de/appendixes.sgml + docs/de/designers.sgml + docs/de/programmers.sgml + docs/fr/appendixes.sgml + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/manual.sgml + docs/fr/preface.sgml + docs/fr/programmers.sgml: + Fixes to documentation syntax so that all content can be processed used + xsltproc docbook-xsl tools. In particular, fixes unescaped entities, + broken tags, unquoted attributes. + +2003-10-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of simple-math-operators inside modifiers + +2003-10-25 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused property _output_type + removed unused param $tag_attrs of _parse_var_props() + cleaned up alignment of class-properties + +2003-10-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed notice in php-tag handling in Smarty_Compiler::_compile_file() + + * libs/Smarty_Compiler.class.php: + removed two occasional E_NOTICES from + Smarty_Compiler::_compile_include_php_tag() + + * NEWS + libs/core/core.create_dir_structure.php: + fix handling of trailing-slashes in open_basedir in + smarty_core_create_dir_structure() + +2003-10-20 Messju Mohr + + * libs/Smarty_Compiler.class.php: + elements inside `` are bracketed now inside the compiled-tpl. this + fixes some issues with simple-math inside backticks. + +2003-10-16 Monte Ohrt + + * docs/designers.sgml: + update overlib docs, no working examples + +2003-10-12 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.is_secure.php: + move check for template_dir in secure_dir-array into core.is_secure.php + + this makes template_exists() work correctly with security=true even if + template_dir is not inside the secure_dir-array + +2003-10-11 Messju Mohr + + * libs/plugins/shared.make_timestamp.php: + tightened check for YYYYMMDDHHMMSS-format. thanks konstantin for + pointing this out. + + removed a few tabs. + + * libs/Smarty_Compiler.class.php: + fix precedence of simple-math-operators before modifiers. + thanks dominik! + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include_php.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + removed tabs from the main and the core/*.php files + +2003-10-08 Monte Ohrt + + * (Smarty_2_6_0-RC2) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers to RC2 + +2003-09-18 Messju Mohr + + * docs/designers.sgml + docs/de/designers.sgml: + fixed description of cycle's advance-attribute + +2003-09-16 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + apply modifiers only once to section-loop and foreach-from attributes + +2003-09-15 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.write_cache_paths_file.php: + backed out _smarty_cached_paths-file-handling + + * libs/Smarty.class.php + libs/core/core.rm_auto.php: + fixed clear_compiled_tpl with explicit $tpl_file given + fixed return value of smarty_core_rm_auto() + Smarty::_unlink() + + * libs/Smarty.class.php: + little fix in _get_auto_filename() + +2003-09-14 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php: + removed auto-filenames from path-cache. merged assemble_auto_filename + back into Smarty::_get_auto_filename() + +2003-09-12 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed quoting of modifier parameters + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.get_php_resource.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php: + remove Smarty::_plugin_implementation_exists() - use php's native + is_callable() + +2003-09-11 Messju Mohr + + * libs/Smarty.class.php: + silenced two notices acces HTTP_SERVER_VARS + +2003-09-10 andreas halter + + * docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/programmers.sgml: + - minor fixes (2 rep), slight wording changes + - jade transform problem fixed + +2003-09-08 andreas halter + + * docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/manual.sgml + docs/de/preface.sgml + docs/de/programmers.sgml: + all updated for 2.6.0 release, translated everything from 2_5_0 branch to + 20030908 + +2003-09-04 Messju Mohr + + * libs/Smarty.class.php: + proper checking for files in _fetch_resource_info() + +2003-09-02 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + ignore {strip}/{/strip) inside {strip}-blocks + + * libs/plugins/function.mailto.php: + fixed 2 notices in smarty_function_mailto() + +2003-09-01 Messju Mohr + + * libs/Smarty.class.php: + re-include cache_paths on multiple calls to fetch() to avoid + inconsistencies + at multiple calls to fetch() in one script + + * libs/Smarty_Compiler.class.php: + fixed handling of \r in {strip} + renamed $_trailing_lf to $_additional_newline + + * libs/Smarty_Compiler.class.php: + the weekly fix for {strip} :) + + * docs/designers.sgml: + fixed example for simple math. + +2003-08-29 Messju Mohr + + * libs/core/core.assign_smarty_interface.php + libs/core/core.display_debug_console.php + libs/plugins/function.assign.php + libs/plugins/function.html_options.php + libs/plugins/function.html_table.php: + fixed PHPDocumentor-comments (thanks Konstantin) + + * libs/core/core.rmdir.php: + made rmdir a bit more optimistic. especially it now removes + directories correctly that where created accidently by "safe_mode=On + && $use_sub_dirs=true" + +2003-08-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed removal of leading/trailing newlines in {strip}-blocks + +2003-08-25 Messju Mohr + + * INSTALL: + added note emphasizing the introduction of "libs/" with 2.5.0 + + * NEWS + libs/plugins/modifier.escape.php: + fixed proper escaping of " and ' with escape:javascript + +2003-08-22 Messju Mohr + + * NEWS + libs/core/core.assemble_plugin_filepath.php: + fixed bug in traversal of $smarty->plugins_dir-array in + smarty_core_assemble_plugin_filepath(). the first matching plugin in + the path should be used, not the last one. + + * libs/core/core.read_cache_file.php: + discard $_cache_info when the cache should be regenerated + +2003-08-20 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php + libs/plugins/block.strip.php: + reverted {strip} from a block-plugin back into the compiler + + * docs/programmers.sgml: + fixed examples for register_function() and register_block() + + * libs/Smarty.class.php: + made template_exists() quiet when the template does not exist (thanks + to konstatin for pointing this out) + +2003-08-18 Monte Ohrt + + * docs/getting-started.sgml: + fix example title + + * docs/README + docs/getting-started.sgml: + change installation wording confusion + +2003-08-18 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed unnecessary load of source in template_exists() and the + compile-check of smarty_core_read_cache_file() + + * libs/Smarty_Compiler.class.php: + allow section-, array- and object-dereference in $smarty-references + +2003-08-15 Messju Mohr + + * docs/designers.sgml: + added parameter-descriptions for count_characters (thanks Konstantin + A. Pelepelin) + + fixed docs for {html_checkboxes} + +2003-08-14 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed timestamp-check of config-files in smarty_core_read_cache_file() + + * libs/Smarty.class.php: + fixed typecasting for arrays in _parse_resource_name() + + * NEWS + libs/plugins/function.config_load.php: + fixes in config_load: + - handling of section-attribute + - reusing the same config-file multiple times + - serialization of config-data for php<4.2.0 (no var_export) + + many thanks to atu for pointing this out and for testing + +2003-08-13 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.smarty_include_php.php: + fixed problem with vars as attributes in {include_php} + +2003-08-13 Monte Ohrt + + * docs/README: + commit README file for documentation compiling + +2003-08-13 Messju Mohr + + * libs/debug.tpl + libs/plugins/modifier.debug_print_var.php: + removed '\r' from debug_print_vars' output + properly escape vars in javascript-version of debug.tpl + +2003-08-11 Monte Ohrt + + * (Smarty_2_6_0_RC1) + NEWS + docs/designers.sgml + docs/html.dsl + docs/php.dsl + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + get ready for 2.6.0-RC1 release + +2003-08-10 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fixed status-header for cache_modified_check under cgi-sapi + +2003-08-09 Messju Mohr + + * libs/core/core.is_secure.php + libs/core/core.is_trusted.php: + synced secure_dir-checking with trusted_dir-checking + + * libs/core/core.is_secure.php: + tightenend path checking in smarty_core_is_secure() + +2003-08-08 Messju Mohr + + * libs/Smarty.class.php: + fix: proper nesting of $smarty->_cache_including flag in cascaded + cached/not-cached/fetched/inserted/foo-templates + + * libs/debug.tpl: + better escaping for $_debug_tpls[templates].filenames + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + removed redundant $smarty from Smarty::_smarty_include() + + * libs/debug.tpl: + proper escaping of filenames in debug-console (thanks to prossel). + +2003-08-07 Messju Mohr + + * docs/programmers.sgml: + added docs for block-methods of registered objects + + * docs/programmers.sgml: + fixed typo in example for registered objects + + * docs/designers.sgml: + fixed exampls of html_image and html_checkboxes + + * libs/plugins/function.debug.php: + fixed {debug} and removed tabs in function.debug.php + + * docs/programmers.sgml: + fixed example for register_object + + * docs/designers.sgml + docs/programmers.sgml: + updated docs for capture, html_table, html_image and register_object + +2003-08-07 Monte Ohrt + + * docs/designers.sgml + docs/programmers.sgml: + add math and default_resource_type to docs + + * docs/getting-started.sgml: + add core to example, add tech note + +2003-08-07 Messju Mohr + + * docs/manual.sgml + docs/fr/manual.sgml: + upd copyright in the docs + +2003-08-07 Monte Ohrt + + * docs/getting-started.sgml: + added core directory to install instructions + +2003-08-07 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + added docs for php-functions as modifiers + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + better caching of attributes for $cacheable=false-plugins + + * docs/programmers.sgml: + added section "caching.cacheable" to the docs, explaining the usage of + the $cacheable-flag of the register_(block|compiler|function)-functions + + * libs/Smarty_Compiler.class.php: + fixed output of custom-functions with cached attributes + + * docs/programmers.sgml: + docs update on callbacks to the register_*-functions + +2003-08-06 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.process_compiled_include.php: + added optional parameter $cache_attrs to register_function() and + register_block(). $cache_attrs is an array containing attribute- names + that should be cached on calls to functions that have $cacheable set + to false. + + * libs/Smarty.class.php: + fixed bug in _run_mod_handler + + * libs/Smarty_Compiler.class.php: + fixed bug with autoload-handling of modifiers. thanks ándre. + +2003-08-05 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + updated copyright notice + + * libs/Smarty.class.php + libs/core/core.load_plugins.php: + fixed bug that occurred when using the same not-cacheable plugin in + multiple includes + + * docs/programmers.sgml: + docs-update for plugins.writing + +2003-08-04 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + updated docs for register_block_function(), block-functions, + $request_use_auto_globals and html_checkboxes + +2003-07-31 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + enabled registration of class-methods as callbacks for the + register_*-functions + + use: array('classname', 'method_name')) as callback + +2003-07-29 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + modifiers are resolved at compile-time now. _run_mod_handler() is + still used for modifiers with map_array=true (== no preceeding '@') + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.smarty_include.php: + moved _smarty_include() back into Smarty.class.php + + * libs/Smarty.class.php + libs/core/core.load_plugins.php: + prevent unnecessary calls to _read_file() in _is_compiled() + converted method-call to internal function-call in + smarty_core_load_plugins() + +2003-07-28 Messju Mohr + + * libs/Smarty_Compiler.class.php: + quote smarty-header properly to prevent resource-names from escaping from + the comment + +2003-07-25 Messju Mohr + + * libs/core/core.create_dir_structure.php: + weakend race-condition and removed bogus error-message caused by that + in smarty_core_create_dir_structure(). + +2003-07-23 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/plugins/function.eval.php: + moved _fetch_resource_info and _parse_resource_name back into + Smarty.class.php + renamed smarty_include and smarty_eval wrappers to _include and _eval + +2003-07-17 Messju Mohr + + * libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php: + improved checking of compiled_include against cached-template with + non-cached-chunks + + * libs/core/core.write_compiled_include.php: + fixed too short open-tag + + * libs/plugins/function.eval.php: + fixed assign parameter for eval (must have gotton lost on its way to 2.5.0) + cleaned up indentiation + +2003-07-03 Messju Mohr + + * libs/Smarty_Compiler.class.php: + resurrected $foo->$bar syntax + + * libs/Smarty_Compiler.class.php: + i'm so stupid. kick me. + + * libs/Smarty_Compiler.class.php: + fixed initialisation of $this->_plugins in compile_block_tag() + +2003-07-03 Monte Ohrt + + * libs/Config_File.class.php: + add preg_quote delimiter + +2003-07-03 Messju Mohr + + * libs/Smarty_Compiler.class.php: + applied fix for {$var1->p1|modifier:$var2->p2}-syntax - thanks Dominik + +2003-07-02 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed duplicate generation of arg-list in _compile_block_tag() + + * libs/Smarty_Compiler.class.php: + fixed off-by-one-error in nocache-tag-handling + +2003-06-30 Messju Mohr + + * libs/Smarty_Compiler.class.php: + backed out errornously committed support for $foo->$bar + + * libs/core/core.write_file.php: + fixed indentiation, silenced occasional warning + + * libs/plugins/function.html_image.php: + match first character of file-attribute against "/" instead of + DIRECTORY_SEPARATOR since it is a url-path and not a file-path. + + * libs/Smarty_Compiler.class.php + libs/core/core.write_file.php + libs/plugins/function.html_image.php: + libs/plugins/function.html_image.php + + * libs/Smarty_Compiler.class.php: + re-fixed cacheable_state-handling + + * libs/core/core.display_debug_console.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.run_insert_handler.php: + extincting $this out of smarty_core_*-functions + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + fixed handling of nocache-state + +2003-06-29 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/plugins/function.eval.php: + removed $this from smarty_include and smarty_include_php + added cleaner handling of $this to {eval} + + * libs/core/core.load_resource_plugin.php: + fixed inlude_once-call + + * docs/de/designers.sgml + docs/fr/designers.sgml: + fixed examples of html_radios and html_checkboxes in german and french docs + +2003-06-25 Monte Ohrt + + * libs/core/core.assemble_auto_filename.php + libs/core/core.write_cache_paths_file.php: + fix typo, fix write_cache_paths logic + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php: + fix SMARTY_COMPILE_DIR_SEP problem, make local var + +2003-06-24 Monte Ohrt + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.write_cache_paths_file.php: + fixed cache_paths bug, simplified filename assembly logic + +2003-06-24 Messju Mohr + + * libs/plugins/function.html_image.php: + added parsing of forgotton param "basedir" + + * libs/Smarty_Compiler.class.php: + fixed $smarty.get-reference + + * libs/plugins/block.textformat.php: + removed warning + + * libs/Smarty_Compiler.class.php: + fixed value of _cacheable_state on compiler-startup + +2003-06-23 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.write_cache_paths_file.php: + make cache_path per resource, fix a couple directory path issues + +2003-06-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed warning when compiling empty template + + * libs/core/core.write_compiled_include.php: + fixed bug in write_compiled_include + + * libs/core/core.assemble_plugin_filepath.php: + fixed warning + +2003-06-22 Messju Mohr + + * libs/plugins/function.eval.php: + fixed propagation of $this into evald code in smarty_function_eval() + + * libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php: + fix in compiled-include-handling + + * libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.parse_resource_name.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.write_cache_file.php + libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/modifier.date_format.php: + started moving from $this to $smarty in core.*.php + +2003-06-21 Monte Ohrt + + * libs/core/core.create_dir_structure.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php: + fix more dir paths + + * NEWS + libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + fix filepaths to core files to use DIRECTORY_SEPARATOR + +2003-06-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed {plugin|modifier} syntax + + * libs/Smarty.class.php + libs/core/core.write_compiled_include.php: + fixed compiled include handling + +2003-06-21 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.write_cache_paths_file.php: + added filepath caching + +2003-06-20 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + update more varnames + + * libs/Smarty.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_file_info.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_file_path.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_compiled_template.php + libs/plugins/function.config_load.php: + refactored var naming to better reflect "resource" instead of "file" where + appropriate + +2003-06-19 Messju Mohr + + * libs/Smarty.class.php: + updated version-number to 2.5.0-cvs + + * libs/core/core.write_cache_file.php: + omit is-cache_dir-writable-check if a cache_handler_function is in use + + * libs/core/core.smarty_include_php.php: + fixed comments in smarty_include_php + +2003-06-19 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.display_debug_console.php + libs/core/core.smarty_include.php + libs/plugins/function.eval.php: + split up _compile_template to _compile_file and _compile_source, fix eval + function + VS: ---------------------------------------------------------------------- + + * libs/plugins/function.config_load.php: + fix logic for _is_compiled() + +2003-06-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + added optional assign-attribute to {capture}-tag + + * NEWS + libs/Smarty.class.php: + added $cacheable-parameter to register_compiler_function() + +2003-06-18 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_include.php: + added $cacheable-parameter to register_function() and register_block() + + * libs/Smarty.class.php: + append '.php' to all compiled templates regardless of the settings of + $use_sub_dirs + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed $file_path-parameters passed to smarty_core_fetch_file_info() + +2003-06-17 Monte Ohrt + + * NEWS: + fix name + + * libs/Smarty_Compiler.class.php: + change varnames to follow coding methods + + * NEWS + libs/Smarty_Compiler.class.php: + add math patch to core + +2003-06-17 Messju Mohr + + * libs/core/core.smarty_include.php: + switched _process_template() to _is_compiled()-logic + +2003-06-17 Monte Ohrt + + * libs/Smarty.class.php: + fix _is_compiled logic + + * NEWS: + update news file + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + fix _run_mod_handler routine + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_file_info.php + libs/core/core.parse_file_path.php + libs/core/core.write_compiled_template.php + libs/plugins/function.config_load.php: + fix path problems, rename some varibles from "template" to "file" + +2003-06-16 Monte Ohrt + + * libs/core/core.fetch_file_info.php + libs/core/core.fetch_template_info.php: + rename file, commit + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.parse_file_path.php + libs/core/core.read_cache_file.php + libs/plugins/block.strip.php + libs/plugins/block.textformat.php + libs/plugins/compiler.config_load.php + libs/plugins/function.config_load.php + libs/plugins/function.eval.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + fix config_load, compile fetched arrays to compile_dir, switch display + back to runtime. clean up var names and function names, split up compile + testing and compiling to separate funcs, rename some template_* functions + to + file_* functions and update logic so they can be used for file resources + other than templates. + +2003-06-16 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed little bug in _compile_custom_tag() + +2003-06-16 Monte Ohrt + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_template_info.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.parse_file_path.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_template.php + libs/core/core.write_file.php + libs/plugins/core.assign_smarty_interface.php + libs/plugins/core.create_dir_structure.php + libs/plugins/core.display_debug_console.php + libs/plugins/core.fetch_template_info.php + libs/plugins/core.get_include_path.php + libs/plugins/core.get_microtime.php + libs/plugins/core.get_php_resource.php + libs/plugins/core.is_secure.php + libs/plugins/core.is_trusted.php + libs/plugins/core.load_plugins.php + libs/plugins/core.load_resource_plugin.php + libs/plugins/core.parse_file_path.php + libs/plugins/core.process_cached_inserts.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.rm_auto.php + libs/plugins/core.rmdir.php + libs/plugins/core.run_insert_handler.php + libs/plugins/core.smarty_include.php + libs/plugins/core.smarty_include_php.php + libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php + libs/plugins/core.write_file.php: + move core files into their own directory under SMARTY_DIR, + remove abstraction function _execute_core_function + + * libs/Smarty_Compiler.class.php: + fix newline handling for template for all template tags + +2003-06-11 Monte Ohrt + + * libs/plugins/compiler.config_load.php: + add compiler function to cvs repository + +2003-06-11 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added config-option "request_use_auto_globals" to make auto-globals be + used as request vars instead of HTTP_*_VARS + +2003-06-11 Monte Ohrt + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.config_load.php: + make config vars compile statically + +2003-06-11 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + backed out newlines patch + + * NEWS + libs/Smarty_Compiler.class.php: + removed newlines in compiled templates after closing tags + +2003-06-10 Messju Mohr + + * docs/de/designers.sgml: + fixed german note on html_image and disk-access + +2003-06-10 Monte Ohrt + + * libs/plugins/core.parse_file_path.php: + fix bug with resource_type resolving + +2003-06-09 Monte Ohrt + + * docs/designers.sgml: + replace example with more practical one + +2003-06-08 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added block-methods for registered objects + +2003-06-07 Messju Mohr + + * docs/programmers.sgml: + fixed bug in documentation for $smarty->default_modifiers + +2003-06-06 Monte Ohrt + + * libs/plugins/core.parse_file_path.php: + fix problem with new default_resource_type changes + + * NEWS: + update NEWS file info + + * NEWS + libs/Smarty.class.php + libs/plugins/core.parse_file_path.php: + add default_resource_type, ignore 1 char resource names + + * NEWS + libs/Config_File.class.php: + fix bug where config file starts with hidden section + +2003-06-04 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + -** empty log message *** + +2003-06-03 Monte Ohrt + + * libs/plugins/function.html_image.php: + fix example in code comments + +2003-06-03 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed behaviour of start=... for {counter} + +2003-06-02 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed assign for {counter} + +2003-05-30 Monte Ohrt + + * libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php: + add discrete error checking pertaining to $cache_dir + and $compile_dir, their existance and writability + +2003-05-28 Messju Mohr + + * NEWS + libs/plugins/function.html_table.php: + added params vdir, hdir and inner to html_table to allow looping over + the data in various directions + +2003-05-28 Monte Ohrt + + * libs/plugins/core.compile_template.php + libs/plugins/core.display_debug_console.php: + fix problem with security and debug.tpl file + +2003-05-23 Monte Ohrt + + * NEWS: + upd NEWS file + + * libs/Smarty_Compiler.class.php: + allow spaces in literal tags + +2003-05-22 Monte Ohrt + + * docs/fr/programmers.sgml: + fix special chars + +2003-05-19 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + speed up compiled templates, hardcode plugin filepaths instead of + recalculate at runtime + +2003-05-19 Messju Mohr + + * docs/designers.sgml: + fixed example of {html_image} + + * docs/designers.sgml: + fixed typo + +2003-05-12 Messju Mohr + + * libs/Smarty.class.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.smarty_include.php + libs/plugins/function.config_load.php: + fixed multiple redundant occurrences for 'config' and 'template' in + $smarty->_cache_info + +2003-05-10 Messju Mohr + + * libs/plugins/core.create_dir_structure.php: + refurbished create_dir_structure to use '/' internally + + * libs/plugins/core.create_dir_structure.php: + fixed windows absolute-paths in smarty_core_create_dir_structure() + + * libs/plugins/core.create_dir_structure.php: + fixed error-message + +2003-05-09 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed warning due to missing param to _execute_core_function() + + * libs/Smarty_Compiler.class.php: + fixed quoting in _compile_include_php + + * libs/Smarty_Compiler.class.php: + fixed quoting of "file"-parameter in _compile_include_tag() + +2003-05-08 Monte Ohrt + + * docs/programmers.sgml: + fix typo + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/core.compile_template.php + libs/plugins/core.create_dir_structure.php + libs/plugins/core.fetch_template_info.php + libs/plugins/core.get_include_path.php + libs/plugins/core.get_microtime.php + libs/plugins/core.get_php_resource.php + libs/plugins/core.is_secure.php + libs/plugins/core.is_trusted.php + libs/plugins/core.load_plugins.php + libs/plugins/core.load_resource_plugin.php + libs/plugins/core.parse_file_path.php + libs/plugins/core.process_cached_inserts.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.rm_auto.php + libs/plugins/core.rmdir.php + libs/plugins/core.run_insert_handler.php + libs/plugins/core.smarty_include.php + libs/plugins/core.smarty_include_php.php + libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php + libs/plugins/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + abstract more private functions to plugin directory + + * libs/Config_File.class.php: + only add DIRECTORY_SEPARATOR if it isn't already present + + * libs/Config_File.class.php: + fix directory separator code, use DIRECTORY_SEPARATOR + +2003-05-08 Messju Mohr + + * docs/designers.sgml: + fixed example of html_checkboxes + + * NEWS + libs/Smarty.class.php: + fixed bug in _create_dir_structure() when used with + open_basedir-restriction and relative paths + + * docs/designers.sgml: + fixed example for html_radios + +2003-05-07 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/core.assign_smarty_interface.php + libs/plugins/core.display_debug_console.php + libs/plugins/function.display_debug_console.php: + abstracted display_debug_console and assign_smarty_interface to plugin dir + as a test + + * libs/Smarty.class.php + libs/plugins/function.display_debug_console.php: + correct misc varnames, abstract debug console display to plugin function + + * libs/plugins/modifier.escape.php: + fix typo + +2003-05-05 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + add % to math + + * libs/Smarty.class.php: + clean up comments, formatting + + * NEWS + libs/Smarty.class.php: + keep DIR_SEP for 3rd party compatability + + * NEWS + libs/Smarty.class.php: + remove DIR_SEP, use DIRECTORY_SEPARATOR exclusively + + * libs/Smarty_Compiler.class.php: + remove ++ and -- math operators on template vars + +2003-05-04 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused parameter $quote from Smarty_Compiler::_parse_attrs() + + * libs/plugins/function.html_image.php: + fixed DIR_SEP in html_image-plugin + +2003-05-04 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + rename DIR_SEP to SMARTY_DIR_SEP to avoid varname collisions + +2003-05-04 Messju Mohr + + * NEWS + libs/plugins/function.html_image.php: + changed "link" to "href" in html_image. "link" is still working but + deprecated + html_image always renders an alt-tag now (default alt="") + cleaned up indentiation of function.html_image.php + +2003-05-03 Monte Ohrt + + * libs/debug.tpl: + fix typo + +2003-05-02 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed assign attribute for multiple counters + +2003-05-02 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + allow math on negative number + + * NEWS + libs/Smarty_Compiler.class.php: + added simple math operators to variables + +2003-05-02 Messju Mohr + + * docs/designers.sgml: + fixed typos + +2003-04-30 Monte Ohrt + + * docs/fr/appendixes.sgml + docs/fr/common.dsl + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/html-common.dsl + docs/fr/html.dsl + docs/fr/manual.sgml + docs/fr/php.dsl + docs/fr/preface.sgml + docs/fr/programmers.sgml: + add frech docs to cvs repository + +2003-04-29 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + reverted patch for case-insensitive tag-names + +2003-04-28 Messju Mohr + + * docs/programmers.sgml: + reverted back to humerous redundancy in the docs :). although we all + know we are here to generate template-based output, and not to have + fun ;-) + + * docs/getting-started.sgml: + fixed default user and group for max os x installation + + * libs/Smarty.class.php: + made $function[2] and $function[3] options for register_resource + + * libs/Smarty.class.php: + fixed issue with object-callback when fetching a php-resource + + * NEWS + libs/Smarty.class.php: + enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') as + callback for register_resource() + + enabled array(&$obj, 'method') as callback for + $default_template_handler_func + +2003-04-27 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + fixed some typos, thank to mehdi + + * libs/plugins/function.counter.php: + prevent assign from overruling print-attribute in function.counter.php + + * libs/plugins/function.counter.php: + fixed problem with counter and assign + + * libs/Smarty.class.php: + fixed notice in _load_plugins() + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + made plugin-names case-insensitive. this affects + compiler/block/custom-functions and modifers. + +2003-04-26 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + remove unnecessary close/open tags from compiled templates + +2003-04-26 Messju Mohr + + * docs/designers.sgml: + added documentation for foreach.property.* + +2003-04-24 Messju Mohr + + * docs/designers.sgml: + fixed example table_attr and tr_attr in html_table-example + +2003-04-21 Greg Beaver + + * libs/Smarty.class.php: + fixed small bug in doc comments + +2003-04-21 Messju Mohr + + * NEWS + libs/plugins/function.html_image.php: + fixed errornous creation of '//' in image_path in html_image + +2003-04-21 Monte Ohrt + + * libs/plugins/modifier.debug_print_var.php: + fix htmlspecialchars() conflict + + * NEWS + libs/plugins/modifier.debug_print_var.php: + fix escapement of special chars in key values of debug console + + * NEWS + libs/plugins/function.config_load.php: + fixed debug timing logic for config_load + + * docs/designers.sgml: + fix example text + + +2003-04-20 Greg Beaver + * plugins/* + Smarty.class.php + Smarty_Compiler.class.php + Config_File.class.php: + updated all doc comments to phpDocumentor format (whew!) + +2003-04-06 Messju Mohr + + * libs/plugins/function.math.php: + allowed "_" in the name of variable-parameters to {math}-function + +2003-04-04 Monte Ohrt + + * NEWS + docs/designers.sgml + libs/Smarty_Compiler.class.php: + change backtic syntax from $`foo` to `$foo` + + * NEWS + libs/Smarty_Compiler.class.php: + recognize $foo[][] syntax in embedded quotes without backticks + +2003-04-03 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + name=123 is passed as an integer (not a string) to plugins now + +2003-04-01 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added CVS $Id: ChangeLog,v 1.459 2007/03/07 01:31:23 changelog Exp $ + +2003-03-31 Messju Mohr + + * libs/Smarty.class.php: + added missing compile_id inside Smarty_Compiler + + * libs/Smarty_Compiler.class.php: + fixed flaw when generating an error for missing postfilter + +2003-03-31 Monte Ohrt + + * docs/getting-started.sgml + docs/programmers.sgml: + fix typos + +2003-03-27 Messju Mohr + + * NEWS + libs/plugins/modifier.debug_print_var.php: + $length is now propagated to sub-values in debug_print_var + +2003-03-26 Monte Ohrt + + * NEWS: + update header + + * RELEASE_NOTES: + commit changes to release notes + + * (Smarty_2_5_0_RC2) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + committing RC2 + +2003-03-24 Messju Mohr + + * NEWS + libs/Smarty.class.php: + made clear_cache() ignore compile_id when clearing cache_groups + + * libs/plugins/function.popup.php: + made onmouseout XHTML-compatible in function.popup.php + +2003-03-21 Messju Mohr + + * NEWS + libs/Smarty.class.php: + applied new var-names to fetch() + + * NEWS + libs/Smarty.class.php: + renamed $localvars to $_localvars in cache-file-handling-functions, + added _get_auto_id()-function + +2003-03-21 Monte Ohrt + + * libs/plugins/function.mailto.php + libs/plugins/function.popup.php: + update functions for XHTML compatability + +2003-03-21 Messju Mohr + + * libs/Smarty.class.php: + fixed wrong $auto_id in _read_cache_file() + + * NEWS + libs/Smarty.class.php: + swapped compile_id and cache_id in read_cache_file and write_cache_file + + * libs/Smarty.class.php: + reverted patch for ignoring compile-id back to -r1.364, due to problems + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + html_radios and html_checkboxes accept "selected" instead of "checked" + optionally now + + * NEWS + libs/Smarty.class.php: + swapped compile_id and cache_id for cache-file-handling again + +2003-03-20 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix notice when no parameter is passed to default + +2003-03-20 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed notice of undefined var in _rm_auto() + +2003-03-19 Monte Ohrt + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php: + fix a few error messages, follow consistancy format plugin_name: errormsg + + * libs/plugins/function.html_radios.php: + update error messages + + * NEWS + libs/plugins/function.html_radios.php: + add a warning when an array is passed as the 'checked' value of html_radios + +2003-03-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed errormessage in _compile_smarty_ref() + + * NEWS + docs/designers.sgml: + updated docs for html_image + +2003-03-18 Messju Mohr + + * NEWS + libs/Smarty.class.php: + cleaned up calls to readdir() + + * libs/plugins/function.html_options.php: + fixed label for optgroup in html_options + +2003-03-18 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix (newly introduced) bug with passing multiple modifiers to a parameter + +2003-03-18 Messju Mohr + + * NEWS + docs/designers.sgml: + updated docs for html_checkboxes, html_options and html_radios + + * libs/plugins/function.html_options.php: + fixed wrong default-"name" in function.html_options.php + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + renamed "checkbox" and "radios" to "options" in {html_checkboxes} and + {html_radios} + + * libs/plugins/outputfilter.trimwhitespace.php: + tried to optimize re-replacement in outputfilter.trimwhitespace.php a + little + + * libs/plugins/outputfilter.trimwhitespace.php: + fixed greedy str_replace in outputfilter.trimwhitespace.php + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php: + html_options, html_checkboxes and html_radios now pass-thru all unknown + paramters + +2003-03-17 Messju Mohr + + * NEWS + libs/plugins/function.html_options.php: + html_options passthru all unknown paramters now + +2003-03-17 Monte Ohrt + + * NEWS + libs/plugins/function.html_image.php: + Fix link bug in html_image function, also make output XHTML compatible + + * libs/Smarty_Compiler.class.php: + fix issue of embedded var and escaped double quotes + +2003-03-15 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + back out "@" logic, apply only to default modifier special case + + * libs/Smarty_Compiler.class.php: + fix @ logic, only use upon an echo + + * NEWS + libs/Smarty_Compiler.class.php: + append "@" to template var echoes to supress possible notices + + * NEWS + libs/Smarty_Compiler.class.php: + append "@" to _run_mod_handler to supress warnings + +2003-03-14 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix problem with escaped double quotes + + * NEWS + libs/plugins/function.html_radios.php: + fixed html_options to not return an array + +2003-03-12 Messju Mohr + + * NEWS + libs/plugins/modifier.truncate.php: + fixed length in modifier.truncate.php + + * NEWS + libs/plugins/outputfilter.trimwhitespace.php: + fixed handling of '$'-signs in trimwhitespace outputfilter (messju) + +2003-03-12 Monte Ohrt + + * docs/programmers.sgml: + update technical explanation of assign_by_ref and append_by_ref + +2003-03-11 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + fix config file recompiling code + +2003-03-07 Monte Ohrt + + * libs/plugins/function.html_image.php: + change E_USER_ERROR to E_USER_NOTICE + + * libs/plugins/function.html_image.php: + suppress warning in html_image + + * NEWS + libs/plugins/function.html_image.php: + update changes to html_image + +2003-03-06 Monte Ohrt + + * docs/designers.sgml + docs/de/appendixes.sgml + docs/de/common.dsl + docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/html-common.dsl + docs/de/html.dsl + docs/de/manual.sgml + docs/de/preface.sgml + docs/de/programmers.sgml: + add german docs to dist + + * NEWS: + update news file + + * libs/plugins/function.html_image.php: + fix width/height parameter index + + * NEWS + libs/Smarty.class.php: + get rid of unsetting name and script attributes to insert tags + +2003-03-05 Monte Ohrt + + * NEWS + RELEASE_NOTES: + update NEWS file + + * libs/plugins/modifier.string_format.php: + fix argument order, erroneously swapped a while back + + * (Smarty_2_5_0_RC1) + NEWS + README + RELEASE_NOTES + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit final changes for 2.5.0-RC1 + +2003-03-04 Monte Ohrt + + * docs/programmers.sgml: + remove $show_info_header and $show_info_include property vars from docs + +2003-03-03 Monte Ohrt + + * NEWS + libs/plugins/function.popup.php: + fixed PHP notice + +2003-02-28 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + simplify smarty.const.foo and smarty.const.$foo logic + + * libs/Smarty_Compiler.class.php: + only allow $foo syntax in embedded quotes, unless escaped with backticks + then allow any dollar var + + * NEWS + libs/Smarty_Compiler.class.php: + fix "once" var compiling to work with new attr compiling methods for + include_php + + * FAQ + NEWS + README + docs/designers.sgml + docs/getting-started.sgml + libs/Smarty_Compiler.class.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/function.html_table.php: + fix $smarty.const.foo compiling, clean up double quoted strings, + allow full dollar var syntax in quotes again + +2003-02-27 Monte Ohrt + + * docs/designers.sgml + docs/programmers.sgml + libs/Smarty_Compiler.class.php: + update docs, fix smarty var compiling, allow any $smarty.*.$foo syntax, + add $`foobar` for embedded variables + + * libs/plugins/function.html_image.php: + update functionality + +2003-02-26 Monte Ohrt + + * NEWS + libs/plugins/modifier.nl2br.php: + add nl2br modifier + + * libs/plugins/function.html_image.php: + add link parameter + +2003-02-24 Monte Ohrt + + * libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix rename problem in windows, unlink first + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/shared.escape_special_chars.php: + update functions with separate escape_special_chars routine + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + commit checkboxes, update radios + + * NEWS + libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix bug with get_registered_object + + * NEWS + libs/plugins/modifier.cat.php: + added cat modifier to distribution + + * NEWS + libs/Smarty_Compiler.class.php: + added << >> <> support to IF statements + + * libs/plugins/function.html_radios.php: + apply patch to initial html_radios function + + * NEWS + libs/Smarty.class.php: + fix _assign_smarty_interface to not overwrite keys other than 'request' + + * NEWS + libs/plugins/function.html_radios.php: + added html_radios to distribution + + * NEWS + libs/plugins/modifier.string_format.php: + fixed arg order of string_format + + * NEWS + libs/Smarty.class.php: + use tmp file for file writes, avoid race condition + + * NEWS + libs/Smarty_Compiler.class.php: + add $smarty.config.foo var, handle embedded smarty var correctly + + * NEWS + libs/plugins/function.fetch.php: + silence warnings in fetch plugin + +2003-02-21 Monte Ohrt + + * INSTALL: + update wording + + * INSTALL: + update install instructions + + * AUTHORS + BUGS + CREDITS + QUICKSTART + README + RESOURCES + TESTIMONIALS: + remove some files already in docs or elsewhere + + * demo/index.php: + add templates_c to repository + + * index.php: + move demo files to demo directory + + * Config_File.class.php + Smarty.class.php + Smarty_Compiler.class.php + debug.tpl: + moved lib files under libs directory + +2003-02-20 Monte Ohrt + + * NEWS + Smarty.class.php: + add get_config_vars() method, update get_template_vars() functionality + + * NEWS + Smarty.class.php: + fix minor logic in _fetch_template_info() + + * NEWS + Smarty.class.php: + support merging appended vars + + * NEWS + Smarty.class.php: + fix cache groups behavior with compile_id set + +2003-02-19 Monte Ohrt + + * Smarty.class.php: + back out third parameter, extend functionality of append + + * NEWS + Smarty_Compiler.class.php: + update imbedded vars, allow special $smarty vars + + * plugins/function.html_table.php: + add plugin html_table + + * NEWS + Smarty.class.php: + support appending key=>val pairs + + * NEWS + Smarty_Compiler.class.php: + change embedded variable logic to only recognize $foo and $foo[0][bar] + syntax + + * NEWS + Smarty_Compiler.class.php: + allow null as function attribute value + +2003-02-18 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + support foo->bar[index] syntax + + * Smarty_Compiler.class.php: + allow $foo->bar[0] syntax + +2003-02-17 Monte Ohrt + + * plugins/modifier.escape.php: + fix syntax error from previous commit + + * NEWS + Smarty.class.php: + add error msgs to get_registered_object + + * Smarty.class.php: + add function for getting reference to registered object + + * Smarty_Compiler.class.php: + back out patches for object and objref calls on $smarty var + + * NEWS + Smarty_Compiler.class.php: + treat unrecognized param attribute syntax as a string + + * NEWS + Smarty_Compiler.class.php: + support $smarty.const.$foo syntax + + * NEWS + debug.tpl + plugins/modifier.count_words.php + plugins/modifier.escape.php: + fix E_NOTICE messages + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + add @ and === to if tokens, few param cleanups + +2003-02-16 Greg Beaver + + * ChangeLog + Smarty.class.php + Smarty_Compiler.class.php: + many more phpdoc comment upgrades + +2003-02-15 Greg Beaver + * Smarty.class.php + Smarty_Compiler.class.php + continue cleaning of phpdoc comments. All that is needed is the + addition of @return tags and perhaps a bit more verbose comments + and they are finished. + +2003-02-14 Monte Ohrt + + * NEWS + Smarty.class.php: + enable config_load error messages + + * NEWS + plugins/function.html_options.php: + fix html_options to not escape already escaped entities + + * NEWS + Smarty.class.php: + send Last-Modified header on cache creation, misc tab/spacing cleanup + +2003-02-13 Monte Ohrt + + * Smarty_Compiler.class.php + docs/designers.sgml: + allow dash in plain text + + * NEWS + Smarty_Compiler.class.php: + check strict syntax of function attributes + +2003-02-12 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + dropped support for modifiers on object parameters, + added support for objects as modifier parameters + + * NEWS + Smarty_Compiler.class.php + docs/designers.sgml: + fix bug with decimal numbers in if statements, misc doc updates + +2003-02-11 Monte Ohrt + + * (Smarty_2_4_2) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + update version numbers + +2003-02-10 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + add support for $foo->$bar syntax + + * NEWS: + update NEWS file + + * NEWS + Smarty_Compiler.class.php: + support full var syntax in quoted text, fix problem with const var access, + clean up some more regex code, fix object problem with no properties + +2003-02-06 Monte Ohrt + + * (Smarty_2_4_1) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + committed 2.4.1 changes + + * NEWS + Smarty_Compiler.class.php: + ignore case in IF statements + +2003-02-05 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + treat undefined constants as null + + * NEWS + Smarty.class.php: + fix problem with inserts and nested fetches + + * Smarty_Compiler.class.php: + fix "if" regex for math tokens + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/getting-started.sgml: + added support for extracting params to include_php + +2003-02-04 Monte Ohrt + + * RELEASE_NOTES: + reformat text + +2003-02-03 Monte Ohrt + + * NEWS: + update news file + +2003-02-03 Greg Beaver + + * ChangeLog + Smarty.class.php: + begin fixing phpdoc comments in Smarty.class.php + + * ChangeLog + Config_File.class.php: + fixed phpdoc comments + +2003-02-03 Monte Ohrt + + * Smarty_Compiler.class.php: + allow $foo->bar[$x].foo syntax + + * Smarty_Compiler.class.php + index.php + configs/test.conf + templates/index.tpl: + fix accidental commit + + * index.php + configs/test.conf + templates/index.tpl: + allow $foo->bar[$j].blah type of syntax + +2003-02-02 Greg Beaver + + * Smarty.class.php + begin fixing of phpdoc comments + + * Config_File.class.php + fix phpdoc comments, add phpDocumentor docblock templates + +2003-02-02 Monte Ohrt + + * Smarty.class.php + docs/html.dsl + docs/php.dsl: + fix version number + + * (Smarty_2_4_0) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml: + update Smarty version numbers + +2003-01-30 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php + TODO: + fix order of php tag comparisons + + * NEWS + Smarty_Compiler.class.php: + fix known php tag handling problems + +2003-01-29 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + change comments to phpdoc style + +2003-01-28 Monte Ohrt + + * Smarty.class.php + docs/programmers.sgml: + make separate var for compiler file + + * plugins/function.fetch.php: + fix error call + +2003-01-25 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + add support for restriction to registered methods + + * plugins/outputfilter.trimwhitespace.php: + update with textarea support + +2003-01-24 Monte Ohrt + + * Smarty_Compiler.class.php: + fix compiling problem with {foreach} tags + + * Smarty.class.php + Smarty_Compiler.class.php: + put objects in own array, add object param format support, change + object syntax from foo.bar to foo->bar + +2003-01-23 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + add support for object registration + +2003-01-22 Monte Ohrt + + * Smarty.class.php: + add file & line number of calling error to error message + +2003-01-21 Monte Ohrt + + * Smarty_Compiler.class.php: + put php style object syntax back in + +2003-01-20 Monte Ohrt + + * Smarty.class.php: + move security settings to fetch function for template_dir + + * NEWS + Smarty.class.php: + fix debug template and security, add template_dir to secure_dir at runtime + +2003-01-17 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + added new object support without new template syntax + +2003-01-15 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fix if statement syntax for negative integers, fix issue with directories + named '0' + +2003-01-08 Monte Ohrt + + * Smarty.class.php + plugins/function.counter.php + plugins/function.cycle.php + plugins/function.debug.php + plugins/function.eval.php + plugins/function.fetch.php + plugins/function.html_options.php + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/function.mailto.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php: + update plugins to return values instead of echo, fix config file cache + to include global config variables in cache file + + * Smarty_Compiler.class.php: + fix bug with >= tests in if statements, comment out full object support + +2003-01-06 Monte Ohrt + + * NEWS + docs/html.dsl + plugins/modifier.escape.php: + add javascript escape parameter to escape modifier + +2003-01-02 Monte Ohrt + + * templates/header.tpl: + move the title into head where it should be + +2002-12-24 Monte Ohrt + + * Smarty_Compiler.class.php: + added correct line numbers to smarty syntax error messages + + * docs/programmers.sgml: + update append documentation, make more clear on its function + + * Smarty_Compiler.class.php: + fix modifier matching regexp + +2002-12-23 Monte Ohrt + + * Smarty_Compiler.class.php: + support nested function calls in IF statements + +2002-12-20 Monte Ohrt + + * Smarty_Compiler.class.php: + few more fixes, spaces around function parameters + + * Smarty_Compiler.class.php: + fix misc syntax issues with {if} tags + +2002-12-20 Monte Ohrt + + * Smarty_Compiler.class.php: + fix misc syntax issues with {if} tags + +2002-12-19 Monte Ohrt + + * Smarty_Compiler.class.php: + commit updates, passes all smoke tests + + * NEWS: + update NEWS file + + * Smarty_Compiler.class.php: + fixed literal string not in quotes as parameters + + * NEWS + Smarty_Compiler.class.php: + fix misc syntax issues, add ability to pass modifiers to functions + +2002-12-18 Monte Ohrt + + * NEWS: + update NEWS + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + update compiler code, clean up regex, add new syntax features + +2002-12-16 Monte Ohrt + + * NEWS: + update NEWS file + + * Smarty_Compiler.class.php: + commit updates for objects + +2002-12-14 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + fix bug with compiling config files with caching on + +2002-12-13 Monte Ohrt + + * Smarty_Compiler.class.php: + fix problem with matching single quoted strings + + * Smarty_Compiler.class.php: + update embedded variable logic, get rid of ."" at end of output + + * NEWS + docs/designers.sgml + plugins/function.html_select_date.php: + add day_value_format to html_select_date + +2002-12-12 Monte Ohrt + + * plugins/modifier.debug_print_var.php: + fix bug, double escaped values in display + + * Smarty.class.php: + move debug test back into fetch() + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + plugins/outputfilter.trimwhitespace.php: + assigned vars are no longer in global name space, few debug cleanups + +2002-12-11 Monte Ohrt + + * plugins/function.popup.php: + fix error in newline code + + * plugins/function.popup.php: + fix popup to allow newlines in text data + +2002-12-10 Monte Ohrt + + * Smarty.class.php: + fix plugin error logic + + * docs/designers.sgml + docs/programmers.sgml: + edit examples, make more verbose + + * NEWS + plugins/function.html_options.php: + escape html entities in the option values and output + + * NEWS + plugins/function.html_options.php: + fixed bug with label of html_options + +2002-12-09 Monte Ohrt + + * Smarty.class.php: + add support for var_export() + + * Config_File.class.php + Smarty.class.php: + clean up code, respect force_compile and compile_check flags + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/designers.sgml + plugins/function.mailto.php: + add caching feature to config loading, document update, add mailto plugin + +2002-12-08 Monte Ohrt + + * plugins/function.fetch.php: + fix query part of URL + +2002-12-05 Monte Ohrt + + * docs/designers.sgml: + fix typos + +2002-11-22 Monte Ohrt + + * Smarty_Compiler.class.php: + patch for warning message + +2002-11-21 Monte Ohrt + + * RELEASE_NOTES + Smarty.class.php: + get rid of testing for a set value with assign function, just set to + whatever is passed into the template + + * docs/programmers.sgml: + fix typo + +2002-11-19 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + commit changes, ready for 2.3.1 release + +2002-11-01 Monte Ohrt + + * plugins/function.html_options.php: + added label attribute to all option outputs, cover w3c spec. + + * NEWS: update NEWS file + + * docs/designers.sgml: update docs for optgroup output + + * plugins/function.html_options.php: + make html_options work with optgroup, make func modular and recursive. + +2002-10-29 Monte Ohrt + + * NEWS + Smarty.class.php: set mtime on compile files so they match source files + +2002-10-18 Monte Ohrt + + * NEWS + Smarty.class.php: added proper support for open_basedir setting + + * docs/designers.sgml: clear up docs on index, iteration and rownum + +2002-10-16 Monte Ohrt + + * plugins/modifier.default.php: fix warning message in default modifier + +2002-09-25 Monte Ohrt + + * docs/designers.sgml + plugins/modifier.strip.php + NEWS: added strip variable modifier + +2002-09-24 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + Fix to be able to use $smarty.x variables as arrays. + +2002-09-23 Monte Ohrt + + * Config_File.class.php: + add support for mac/dos formatted config files (fix newlines) + + * docs/programmers.sgml: add optional tags to clear_cache parameters + + * docs/designers.sgml: + fix error with include_php description, add $this to description + +2002-09-20 Monte Ohrt + + * NEWS + docs/getting-started.sgml: fixed errors with example setup docs + +2002-09-16 Monte Ohrt + + * plugins/block.textformat.php + docs/designers.sgml + NEWS: add textformat block function + +2002-09-10 Monte Ohrt + + * docs/designers.sgml: + add assign attribute to cycle function documentation + + * docs/designers.sgml + docs/programmers.sgml: fix typos + +2002-09-09 Monte Ohrt + + * plugins/function.debug.php + templates/header.tpl: + fix header in debug template, fix typo in header.tpl example + +2002-08-15 mohrt + + * docs/programmers.sgml: fix typos + +2002-08-08 mohrt + + * RELEASE_NOTES + Smarty.class.php: + supress warnings from unlink() and is_dir(), let error handler deal with it + +2002-08-07 mohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update files with new version numbers + +2002-08-02 mohrt + + * NEWS: update NEWS file with credits + + * NEWS + Smarty.class.php: added assign_by_ref() and append_by_ref() functions + +2002-08-01 mohrt + + * TODO + NEWS + Smarty.class.php: + changed default warning type for plugin errors from E_USER_WARNING to E_USER_ERROR + +2002-07-29 mohrt + + * plugins/function.html_select_time.php + docs/designers.sgml + NEWS: added paramters to html_select_time plugin + +2002-07-25 Andrei Zmievski + + * TODO: *** empty log message *** + +2002-07-24 mohrt + + * QUICKSTART: update QUICKSTART guide + + * NEWS + debug.tpl + plugins/modifier.debug_print_var.php: + update debug console to show objects, fix warning in debug.tpl + +2002-07-23 mohrt + + * docs/programmers.sgml: fix load_filter examples + + * Config_File.class.php + NEWS: fix error when there are no sections in config file + +2002-07-19 mohrt + + * docs/getting-started.sgml: fix error in install guide + +2002-07-18 mohrt + + * Smarty_Compiler.class.php: + correct the expression match for smarty:nodefaults + +2002-07-17 mohrt + + * Smarty_Compiler.class.php: fix default modifier to work with config vars + + * Smarty_Compiler.class.php: got args to strstr backwards... + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + change default modifiers to array instead of string + + * Smarty_Compiler.class.php + docs/designers.sgml + Smarty.class.php: add default modifier logic, minor doc updates + + * NEWS + Smarty.class.php + plugins/function.popup_init.php: + make popup_init xhtml compliant, minor variable name changes for consistancy + +2002-07-16 mohrt + + * NEWS: update NEWS file + + * plugins/function.debug.php + Smarty.class.php + debug.tpl + NEWS: + fix problem with filenames on windows, add ability to supply expire time in seconds when clearing cache or compiled files + +2002-07-15 mohrt + + * Smarty.class.php: + fixed problem with insert tags when loading function from script attribute + and caching enabled (Monte) + +2002-07-14 mohrt + + * NEWS + Smarty.class.php: fix bug with debug_tpl file path for Windows + +2002-07-12 Monte Ohrt + + * Smarty.class.php: fix append function with array/string issue + +2002-07-11 Monte Ohrt + + * RELEASE_NOTES: update release notes + + * NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + Config_File.class.php: update files to 2.2.0 tags, get ready for release + +2002-07-09 Monte Ohrt + + * NEWS + Smarty.class.php: make debug.tpl work with any delimiter + + * NEWS + Smarty.class.php: + change tests in append and assign to != '' instead of empty(), which is more accurate + +2002-07-08 Monte Ohrt + + * docs/designers.sgml: minor doc update + + * Smarty.class.php: + cast var as an array, simplify and get rid of PHP warning messages + +2002-07-03 Monte Ohrt + + * Smarty.class.php: one more N + + * Smarty.class.php: + prepend "N" to filenames to avoid possible OS issues with dir names starting with "-" + + * Smarty.class.php: only set $debug_tpl in constructor if empty + + * Smarty.class.php + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: + make use_sub_dirs go back to crc32 for subdir separation + +2002-06-29 Monte Ohrt + + * plugins/function.eval.php: do nothing if $val is empty + + * TODO + plugins/function.eval.php + plugins/function.popup_init.php: + add zindex to popup init, fix error message for eval. + +2002-06-27 Monte Ohrt + + * Smarty.class.php: + only loop through relative paths for PHP include_path, remove $_relative variable + + * Smarty_Compiler.class.php: added {$smarty.version} variable + +2002-06-26 Monte Ohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml + Smarty.class.php: + update plugin loading logic, look in SMARTY_DIR, then cwd. If all fail, then retry all with include_path + + * templates/header.tpl + Smarty.class.php: update get_include_path, get _path_array only once + + * Smarty.class.php: fix get_include_path function for windows + + * Smarty.class.php: update plugin search logic + + * Smarty.class.php: only search include_path if relative path + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php + Smarty_Compiler.class.php + NEWS + Smarty.class.php: allow plugins_dir to be an array of directories + +2002-06-25 Monte Ohrt + + * docs/programmers.sgml + docs/getting-started.sgml: update installation docs + + * debug.tpl + docs/getting-started.sgml + templates/debug.tpl + NEWS + Smarty.class.php: move debug.tpl to SMARTY_DIR, add to constructor + +2002-06-24 Monte Ohrt + + * plugins/function.assign_debug_info.php + NEWS: fixed warning message in function.assign_debug_info + + * Smarty.class.php: update include_path fixes + + * NEWS: + fixed $template_dir, $compile_dir, $cache_dir, $config_dir to respect include_path + +2002-06-23 Monte Ohrt + + * plugins/shared.make_timestamp.php: + update timestamp plugin to work when passed a timestamp + +2002-06-19 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/modifier.date_format.php + docs/designers.sgml: + update date_format, allow optional 2nd paramater as default date if passed date is empty. update docs. + + * plugins/modifier.date_format.php: + fix date_format modifier, return nothing if given empty string + +2002-06-18 Monte Ohrt + + * NEWS + plugins/function.cycle.php: + gave $reset a default value in cycle function + + * plugins/function.html_select_date.php + plugins/shared.make_timestamp.php + NEWS: + corrected warnings in html_select_time function, made make timestamp always return a timestamp + +2002-06-17 Monte Ohrt + + * Smarty.class.php: swapped around cache_id and compile_id order + +2002-06-14 Monte Ohrt + + * docs/programmers.sgml + plugins/function.popup_init.php + Smarty.class.php: + change directory delimiter to "^" for cache and compile files + +2002-06-13 Andrei Zmievski + + * TODO: done. + + * Smarty_Compiler.class.php: + Optimize the calculation of section 'total' property. + +2002-06-11 Monte Ohrt + + * NEWS + Smarty.class.php: + added support for subdir exclusion, deletion by full or partial cache_id and compile_id, change file format to urlencoded values instead of crc32 + +2002-06-07 Monte Ohrt + + * Smarty.class.php: fix bug with last_modified_check code + + * NEWS + Smarty.class.php: + updated $GLOBALS refererence for HTTP_IF_MODIFIED_SINCE + +2002-06-06 Monte Ohrt + + * docs/designers.sgml + overlib.js: + remove overlib.js file from distribution, update plugin and docs + +2002-06-05 Monte Ohrt + + * docs/designers.sgml + NEWS + Smarty.class.php: fix 304 Not Modified, don't send content + +2002-06-03 Monte Ohrt + + * plugins/function.cycle.php: update version number + + * plugins/function.cycle.php + NEWS: + fixed cycle function to respect delimiter setting after initial setting + + * Smarty.class.php + NEWS: + update $GLOBALS references to work properly with track_globals settings + + * plugins/function.math.php: fixed bug with call $assign + + * docs/appendixes.sgml + docs/designers.sgml + plugins/function.html_options.php + plugins/function.html_select_time.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php: + optimized for loops with count() function calls + +2002-06-01 Andrei Zmievski + + * TODO: *** empty log message *** + +2002-05-21 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/function.html_select_date.php + RESOURCES + docs/designers.sgml + Config_File.class.php: + update html_select_date with month_value_format attribute for controlling the format of the month values. + +2002-05-17 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: + Made it possible to use simple variables inside [] for indexing. + +2002-05-16 Monte Ohrt + + * docs/designers.sgml + docs/getting-started.sgml + NEWS + Smarty.class.php + Smarty_Compiler.class.php + TESTIMONIALS: add "once" attribute to php_include, update docs + +2002-05-09 Andrei Zmievski + + * NEWS + TODO: *** empty log message *** + +2002-05-07 Monte Ohrt + + * plugins/function.cycle.php: remove \n from cycle function + + * docs/designers.sgml + plugins/function.cycle.php + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + NEWS: + update cycle function to handle array as input, update files to 2.1.1 + +2002-05-06 Monte Ohrt + + * plugins/function.fetch.php: + update fetch function with more error checking + +2002-05-03 Monte Ohrt + + * docs/designers.sgml + plugins/function.counter.php: + update counter to use name instead of id (id still works though) + + * plugins/function.cycle.php + docs/designers.sgml: rename id to name for cycle function + + * plugins/function.cycle.php: + update cycle function to allow blank values parameter after initialized + + * plugins/function.cycle.php: fix syntax error + +2002-05-02 Monte Ohrt + + * plugins/function.cycle.php: ugh, another typo + + * plugins/function.cycle.php: update comments + + * docs/designers.sgml + plugins/function.cycle.php + NEWS: added function cycle + + * FAQ + Smarty.class.php: fix register_outputfilter function + +2002-05-01 Monte Ohrt + + * docs/designers.sgml + NEWS + Smarty.class.php: fixed bug with resource testing and include_path + +2002-04-30 Monte Ohrt + + * NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update files for 2.1.0 release + +2002-04-30 Andrei Zmievski + + * plugins/function.fetch.php + docs/programmers.sgml + Smarty.class.php: Fix. + +2002-04-29 Andrei Zmievski + + * docs/programmers.sgml + docs/designers.sgml: A whole bunch of docs. + +2002-04-26 Monte Ohrt + + * FAQ + QUICKSTART + docs/programmers.sgml: update FAQ, QUICKSTART, small doc syntax fix + +2002-04-24 Monte Ohrt + + * docs/programmers.sgml + templates/debug.tpl + Smarty.class.php: changed doc structure a bit + +2002-04-16 Andrei Zmievski + + * Smarty.class.php: Add register/unregister API for output filters. + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + TODO: + Changed the way filters are loaded, which now has to be done explicitly, + either through load_filter() API or by filling in $autoload_filters variable. + Also renamed internal variable to avoid namespace pollution. + +2002-04-15 Andrei Zmievski + + * Smarty.class.php: + Fixed _get_php_resource() to take include_path into account. + +2002-04-15 Monte Ohrt + + * docs/designers.sgml: + update docs, get modifiers and functions into index for easy access + + * docs/programmers.sgml + NEWS + Smarty.class.php: update caching documentation + +2002-04-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php: Only turn down error notices if $debugging is false. + +2002-04-15 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/function.html_select_date.php: + fixed logic so this works right when field_separator = "/" + + * plugins/function.html_select_date.php: + fix regular expression for matching date + +2002-04-13 Monte Ohrt + + * docs/designers.sgml: updated html_select_date docs to reflect changes + + * NEWS + plugins/function.html_select_date.php: + added YYYY-MM-DD support to html_select_date + +2002-04-12 Andrei Zmievski + + * TESTIMONIALS: New entry. + +2002-04-12 Monte Ohrt + + * plugins/modifier.strip_tags.php: back out changes to strip_tags + + * docs/programmers.sgml: update docs regarding cache_lifetime + + * plugins/modifier.strip_tags.php + Smarty.class.php: + update cache_lifetime logic: -1 = never expire, 0 = always expire + +2002-04-11 Andrei Zmievski + + * BUGS + FAQ + INSTALL + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/getting-started.sgml: + Fixed directory separtor issue. Requiring PHP 4.0.6 now. + + * NEWS + Smarty_Compiler.class.php: + Added ability to use simple variables for array indices or object properties. + + * TESTIMONIALS: Another one. + + * TESTIMONIALS: Adding one from Mark P. + +2002-04-05 Andrei Zmievski + + * Smarty_Compiler.class.php + NEWS + Smarty.class.php: Make it possible to unregister pre/postfilter plugins. + +2002-04-05 Monte Ohrt + + * INSTALL: Remove addons file from INSTALL instructions + +2002-04-04 Monte Ohrt + + * docs/designers.sgml: update doc error + + * docs/designers.sgml + plugins/modifier.escape.php + NEWS + Smarty.class.php: added htmlall attribute to escape modifier + +2002-04-03 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixed undefined offset warning in {if} tag. + + * Smarty.class.php + NEWS: Added template_exists() API. + + * Smarty.class.php + Smarty_Compiler.class.php + NEWS: + - Added $smarty.template variable. + - Fixed {include_php} tag when dynamic values were used for 'file' attribute. + + * Config_File.class.php: Separator setting fix. + +2002-03-28 Monte Ohrt + + * FAQ + README: add digest address + + * FAQ + README + Smarty.class.php: update mailing list addresses + +2002-03-28 Andrei Zmievski + + * NEWS: *** empty log message *** + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + Fix for when plugins directory is not the default one. + +2002-03-28 Andrei Zmievski + + * NEWS: *** empty log message *** + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + Fix for when plugins directory is not the default one. + +2002-03-27 Monte Ohrt + + * FAQ: update FAQ page + +2002-03-26 Andrei Zmievski + + * CREDITS + NEWS + Smarty.class.php + Smarty_Compiler.class.php + TODO: Block functions changes. + + * Config_File.class.php: *** empty log message *** + +2002-03-25 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Initial implementation of block functions. + +2002-03-22 Monte Ohrt + + * docs/designers.sgml: fix documentation error in capture + +2002-03-22 Andrei Zmievski + + * Smarty.class.php: *** empty log message *** + + * Smarty.class.php: Turn off notices. + +2002-03-21 Andrei Zmievski + + * Smarty_Compiler.class.php: Make _current_file available to prefilters. + + * NEWS + Smarty.class.php: + Made is possible to assign variables in pre/postfilters. + +2002-03-20 Andrei Zmievski + + * plugins/function.html_select_date.php: Fixed +/- functionality. + + * NEWS: *** empty log message *** + +2002-03-20 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update version numbers + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + move .make_timestamp.php to shared.make_timestamp.php + + * NEWS + Smarty.class.php + docs/designers.sgml + plugins/function.fetch.php + plugins/function.html_select_date.php: + update file generation, replace crc32() '-' with 'N' + +2002-03-20 Andrei Zmievski + + * Smarty_Compiler.class.php: *** empty log message *** + +2002-03-19 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php + Smarty_Compiler.class.php: + Fix plugin behavior for inserts with script attribute. + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: Fix bug with $smarty.cookies. + + * TESTIMONIALS: *** empty log message *** + +2002-03-15 Monte Ohrt + + * NEWS + docs/designers.sgml: update Changelog + + * plugins/modifier.indent.php + plugins/modifier.wordwrap.php: add wordwrap and indent to repository + +2002-03-14 Monte Ohrt + + * Smarty.class.php: + remove show_info_include and show_info_header functions + +2002-03-13 Monte Ohrt + + * plugins/function.fetch.php: update fetch function + + * plugins/function.fetch.php: update fetch function with new parameters + +2002-03-12 Monte Ohrt + + * docs/designers.sgml: update doc tables + + * docs/designers.sgml: update docs columns + + * docs/getting-started.sgml + docs/appendixes.sgml: update docs + + * TESTIMONIALS + docs/appendixes.sgml: update syntax error in docs, add to testimonials + +2002-03-04 Monte Ohrt + + * FAQ + README: update FAQ, README with digest mode info + +2002-03-02 Monte Ohrt + + * QUICKSTART: update quickstart + + * Smarty.class.php: + change behavior so cache_lifetime = 0 never expires (instead of always regenerate) + +2002-03-01 Monte Ohrt + + * docs/designers.sgml: update doc example + +2002-03-01 Andrei Zmievski + + * CREDITS + RELEASE_NOTES + TODO + NEWS: *** empty log message *** + +2002-03-01 Monte Ohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: update document id tags + + * docs.sgml: remove docs.sgml + + * RESOURCES + Smarty.class.php: update resources + +2002-02-28 Andrei Zmievski + + * TESTIMONIALS + docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml: *** empty log message *** + +2002-02-27 Andrei Zmievski + + * plugins/function.eval.php + docs/designers.sgml: *** empty log message *** + +2002-02-27 Monte Ohrt + + * plugins/function.eval.php: added eval function to plugin dir + +2002-02-27 Andrei Zmievski + + * NEWS: *** empty log message *** + +2002-02-27 Monte Ohrt + + * docs/designers.sgml: fix syntax error + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: convert technical notes to docbook format + + * NEWS + docs/designers.sgml: added "eval" plugin docs + +2002-02-26 Andrei Zmievski + + * docs/programmers.sgml + docs/designers.sgml + docs/appendixes.sgml + docs/getting-started.sgml + docs/html-common.dsl + docs/.cvsignore: *** empty log message *** + + * docs/appendixes.sgml + docs/common.dsl + docs/designers.sgml + docs/getting-started.sgml + docs/html-common.dsl + docs/html.dsl + docs/manual.sgml + docs/preface.sgml + docs/programmers.sgml: Split up docs. + +2002-02-25 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-22 Monte Ohrt + + * docs.sgml: update docs + +2002-02-22 Andrei Zmievski + + * docs.sgml + AUTHORS + NEWS: *** empty log message *** + +2002-02-21 Monte Ohrt + + * Config_File.class.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: update misc changes + +2002-02-21 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-20 Monte Ohrt + + * docs.sgml: misc updates + +2002-02-20 Andrei Zmievski + + * docs.sgml: *** empty log message *** + + * Smarty.class.php + plugins/function.assign.php + plugins/function.assign_debug_info.php + plugins/function.counter.php + plugins/function.fetch.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php + plugins/modifier.escape.php: Fixup some naming. + +2002-02-20 Monte Ohrt + + * docs.sgml: update docs + +2002-02-20 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-20 Monte Ohrt + + * NEWS + docs.sgml + plugins/modifier.escape.php: + removed global vars from fetch function, added attrs to escape modifier + + * docs.sgml: add plugin chapter outline + +2002-02-19 Monte Ohrt + + * README + RELEASE_NOTES + RESOURCES + Smarty.class.php + docs.sgml + BUGS + FAQ + INSTALL + QUICKSTART: update docs + +2002-02-19 Andrei Zmievski + + * docs.sgml: Updated resources docs. + + * README: *** empty log message *** + + * docs.sgml: Updated description of {$smarty} variable. + + * BUGS + FAQ + INSTALL + QUICKSTART + RELEASE_NOTES + docs.sgml: Remove PEAR notes. + +2002-02-18 Andrei Zmievski + + * Config_File.class.php + NEWS: Removed dependency on PEAR. + +2002-02-18 Monte Ohrt + + * NEWS + docs.sgml + plugins/function.popup_init.php: add src attribute to popup_init + +2002-02-15 Andrei Zmievski + + * Smarty_Compiler.class.php + plugins/modifier.debug_print_var.php + NEWS + Smarty.class.php: Performance enhancements. + +2002-02-06 Andrei Zmievski + + * plugins/function.html_options.php: + Fix html_options output to be XHTML compatible. + +2002-02-05 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Fix up plugin inclusion. + + * Smarty.class.php + Smarty_Compiler.class.php + TODO + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: Fix plugin directory access. + +2002-02-04 Andrei Zmievski + + * .cvsignore + Smarty_Compiler.class.php: *** empty log message *** + +2002-01-31 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + TODO + plugins/function.assign.php + plugins/function.assign_debug_info.php + plugins/function.counter.php + plugins/function.fetch.php + plugins/function.html_options.php + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php + plugins/modifier.capitalize.php + plugins/modifier.count_characters.php + plugins/modifier.count_paragraphs.php + plugins/modifier.count_sentences.php + plugins/modifier.count_words.php + plugins/modifier.date_format.php + plugins/modifier.debug_print_var.php + plugins/modifier.default.php + plugins/modifier.escape.php + plugins/modifier.lower.php + plugins/modifier.regex_replace.php + plugins/modifier.replace.php + plugins/modifier.spacify.php + plugins/modifier.string_format.php + plugins/modifier.strip_tags.php + plugins/modifier.truncate.php + plugins/modifier.upper.php + plugins/shared.make_timestamp.php + templates/index.tpl + AUTHORS + CREDITS + Config_File.class.php + README: Implemented plugin architecture. + + * NEWS: *** empty log message *** + +2002-01-30 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml: added modifiers wordwrap and indent + +2002-01-28 Monte Ohrt + + * Smarty.class.php + docs.sgml: + add support for is-modified-since headers, adjust a doc example + +2002-01-24 Monte Ohrt + + * Smarty.class.php: cleanup formatting + + * NEWS + Smarty.class.php + docs.sgml: update ChangeLog, remove insert_tag_check parameter + +2002-01-24 Andrei Zmievski + + * plugins/standard.plugin.php: *** empty log message *** + +2002-01-24 Monte Ohrt + + * Smarty.class.php: fix syntax error + + * Smarty.class.php: removed unneccesary test from fetch() + +2002-01-23 Monte Ohrt + + * Smarty.addons.php: update overlib fixes + + * NEWS: update changelog + + * FAQ + NEWS + RESOURCES + Smarty.addons.php: updated overlib fixes + +2001-12-31 Andrei Zmievski + + * NEWS + Smarty.class.php: Fixed compile_id problem. + +2001-12-28 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fixed problem with using assigned var with include_php filepath + +2001-12-21 Monte Ohrt + + * RESOURCES: update RESOURCES + +2001-12-20 Monte Ohrt + + * FAQ + README: update FAQ + +2001-12-18 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: update version numbers + +2001-12-18 Andrei Zmievski + + * NEWS + Smarty.class.php: Fixed clear_cache(). + +2001-12-14 Monte Ohrt + + * NEWS + Smarty.addons.php: + fixed bug in smarty_make_timestamp introduced in PHP 4.1.0 + +2001-12-13 Monte Ohrt + + * NEWS + Smarty.class.php + docs.sgml: update default function args, fix cached insert debug timing + +2001-12-12 Monte Ohrt + + * docs.sgml: fix syntax error in documentation + + * Smarty.class.php: update default template handling functionality + +2001-12-11 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: update file fetching logic + +2001-12-11 Andrei Zmievski + + * NEWS + Smarty.class.php: Added 'script' attribute to {insert..}. + +2001-12-10 Monte Ohrt + + * NEWS + Smarty.class.php: added default template function handler + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version numbers in files to 1.5.1 + +2001-12-10 Andrei Zmievski + + * NEWS + Smarty.class.php: Removed error message from the _read_file() method. + + * Smarty.class.php: Fix check for compile and cache IDs. + +2001-12-06 Monte Ohrt + + * QUICKSTART: fix spelling error in QUICKSTART + + * docs.sgml: fixed spelling errors in documenation + + * Smarty_Compiler.class.php + docs.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: commit 1.5.0 release + + * RESOURCES + docs.sgml: added RESOURCES file + +2001-12-05 Andrei Zmievski + + * Smarty_Compiler.class.php: Refactor. + +2001-12-05 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php + docs.sgml: added assign to include and php_include + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: *** empty log message *** + +2001-12-04 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Formatting. + +2001-12-04 Monte Ohrt + + * Smarty_Compiler.class.php + NEWS + Smarty.class.php: update ChangeLog + +2001-12-04 Andrei Zmievski + + * NEWS + Smarty.class.php: Formatting. + +2001-12-04 Monte Ohrt + + * Smarty.class.php: removed SMARTY_DIR setting in constructor + + * Smarty.class.php: fix Smarty.class.php indention error + + * Smarty.class.php: update trusted logic + +2001-12-03 Monte Ohrt + + * Smarty.class.php: + fix up is_secure, is_trusted, make _parse_tpl_path function + + * Smarty.class.php: fix problem with testing SMARTY_DIR as empty + + * NEWS + docs.sgml: update documentation, change log + + * Smarty.class.php: + update constructor to check for SMARTY_DIR before assigning + +2001-12-03 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-12-03 Monte Ohrt + + * FAQ + INSTALL + RELEASE_NOTES: update a few files + + * NEWS + QUICKSTART + Smarty.class.php + docs.sgml: added trusted_dir functionality, cleaned up secure_dir logic + +2001-12-03 Andrei Zmievski + + * NEWS: *** empty log message *** + + * NEWS + Smarty.class.php: - Introduced $compile_id class variable. + - Fixed a situation where if $cache_id and $compile_id were both null + they were passed to auto functions as empty string instead of null. + +2001-11-30 Monte Ohrt + + * NEWS + Smarty.class.php: + change variable names in fetch() fuction to smarty_* to avoid namespace conflicts + + * NEWS + Smarty.class.php: fixed bug in _rm_auto with catenated null values + +2001-11-29 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Added $smarty.section.* syntax. + + * Smarty_Compiler.class.php: Made 'name' attribute optional for {foreach}. + +2001-11-29 Monte Ohrt + + * Smarty.class.php + index.php: remove assign "now" in index.tpl + +2001-11-29 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty.class.php: Fix formatting. + +2001-11-28 Monte Ohrt + + * NEWS + Smarty.class.php + docs.sgml: + removed return statements from _read_cache_file (how did they get in there?) + +2001-11-27 Monte Ohrt + + * docs.sgml + NEWS + Smarty.addons.php + Smarty.class.php: + fixed bugs and added assign attribute to several functions + +2001-11-27 Andrei Zmievski + + * NEWS: Some rewording. + + * Smarty_Compiler.class.php: Fix $smarty.capture access. + + * TODO: *** empty log message *** + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + Made {config_load ..} merge globals from each config file only once per scope. + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: - Added {foreach ...}. + - Made certain $smarty.* references handled at compilation time. + +2001-11-26 Monte Ohrt + + * Config_File.class.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: commit cache handler functionality + +2001-11-20 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty_Compiler.class.php: Various fixes and additions. + + * NEWS + index.php: *** empty log message *** + +2001-11-05 Monte Ohrt + + * Smarty.class.php: changed _read_file parameter from $end to $lines + + * NEWS + Smarty.class.php: fixed is_cache, make cache reading more efficient + +2001-11-02 Monte Ohrt + + * FAQ + NEWS: update FAQ with mailing list Reply-To header FAQ + + * NEWS + Smarty.class.php + index.php: supress fopen errors, return false if cache file won't load + +2001-11-01 Monte Ohrt + + * QUICKSTART + docs.sgml + index.php: update QUICKSTART guide with index key example + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: commit all updates for 1.4.6 + +2001-11-01 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-10-30 Monte Ohrt + + * Smarty.addons.php: fix assign function problem with empty value passed + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + templates/debug.tpl: + fixed bug in assign function when passing an empty value + +2001-10-26 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + index.php: fix minor typo in debug code + +2001-10-26 Andrei Zmievski + + * Smarty.class.php: Typo. + +2001-10-26 Monte Ohrt + + * Smarty.addons.php: + update debug console output, handle html encoding correctly + +2001-10-26 Andrei Zmievski + + * Smarty.addons.php + templates/debug.tpl: Debug formatting. + + * Smarty.class.php: Disable rmdir warning. + +2001-10-26 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + templates/debug.tpl: update debugging to expand array variables + + * Smarty.class.php + docs.sgml: + update docs for fetching only timestamp with custom template source functions + + * Smarty.addons.php: fix debug console error + +2001-10-26 Andrei Zmievski + + * docs.sgml: Typos. + + * Smarty.addons.php: Cleanup whitespace. + + * Smarty_Compiler.class.php: Clean up whitespace. + + * Smarty.class.php: Cleaning up code, formatting mostly. + + * NEWS: *** empty log message *** + +2001-10-25 Monte Ohrt + + * NEWS + docs.sgml: update documentation to current version + + * NEWS + Smarty.addons.php: + updated fetch to give proper warning when fetching unreadable or nonexistant files + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fixed problem with newline at the end of compiled templates + + * NEWS + Smarty.class.php: recompile cache if config file gets modified too. + + * NEWS + Smarty.class.php: + added feature to regenerate cache if compile_check is enabled and an + involved template is modified + +2001-10-23 Monte Ohrt + + * Smarty.class.php: fix indent for insert tags in debug console + + * templates/debug.tpl: update debug.tpl file format + + * NEWS + Smarty.addons.php + Smarty.class.php + templates/debug.tpl: + update execution time debugging, move into include list + +2001-10-10 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + fixed up execution time output in debug console + +2001-10-09 Andrei Zmievski + + * Config_File.class.php + NEWS + Smarty.class.php + TODO: Added support for hidden config vars. + +2001-10-04 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + templates/debug.tpl: added execution times to debug console + +2001-10-02 Andrei Zmievski + + * Smarty_Compiler.class.php: Add space. + +2001-10-01 Andrei Zmievski + + * Smarty.class.php: Fix reference to compile_id. + +2001-09-28 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: Added postfilter functions. + +2001-09-26 Andrei Zmievski + + * NEWS + Smarty.class.php + docs.sgml: Rename to clear_compiled_tpl(). + +2001-09-25 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: + Fixed line number reporting when removing comments. + +2001-09-20 Monte Ohrt + + * NEWS + RELEASE_NOTES + Smarty.addons.php: made html_options output xhtml compatible + +2001-09-19 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + templates/debug.tpl: updated version numbers + +2001-09-16 Monte Ohrt + + * FAQ + NEWS + docs.sgml: fix doc error with insert function + +2001-09-06 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-08-31 Monte Ohrt + + * NEWS: update ChangeLog + + * overlib.js + Smarty.addons.php + Smarty.class.php + docs.sgml: + update overlib to 3.50, adjust addon code so that the overlib.js file isn't modified + +2001-08-31 Andrei Zmievski + + * Smarty.class.php: - compile_id changes + + * NEWS + Smarty.addons.php: - compile_id support + - new options for html_select_date + +2001-08-23 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-08-10 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + Modified to pass Smarty object as second parameter to insert functions. + Also moved _smarty_mod_handler() and _smarty_insert_handler() into the class. + + * NEWS + Smarty_Compiler.class.php: + Passing Smarty as second parameter to prefilter functions. + +2001-08-09 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-08-09 Monte Ohrt + + * templates/index.tpl + Smarty.class.php: add smarty.now variable to template + +2001-08-06 Monte Ohrt + + * templates/index.tpl: change config_load section back to setup + +2001-08-06 Andrei Zmievski + + * Smarty.addons.php: Optimize a bit. + +2001-08-04 Monte Ohrt + + * docs.sgml: update capture documentation + +2001-08-03 Monte Ohrt + + * FAQ + NEWS + Smarty.class.php: + fix bug with URL controlled debugging, works now (Monte) + +2001-08-01 Andrei Zmievski + + * Config_File.class.php: *** empty log message *** + + * Smarty_Compiler.class.php + Smarty.class.php: - Fixed some E_NOTICE stuff in compiler. + - Generalized assign_smarty_interface() a bit. + +2001-07-24 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php + TODO: See ChangeLog for details. + +2001-07-20 Andrei Zmievski + + * Config_File.class.php: Booleanize case-insensitively. + +2001-07-17 Monte Ohrt + + * NEWS: update ChangeLog + + * Smarty.class.php + docs.sgml: put SMARTY_DIR on Config_File require + +2001-07-11 Monte Ohrt + + * docs.sgml + FAQ + NEWS + Smarty.class.php: + updated security to not include insecure docs, only warning + +2001-07-10 Andrei Zmievski + + * Smarty.class.php: Adding 'sizeof' as an allowed {if} function. + +2001-07-06 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-07-06 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version number to 1.4.4 + + * NEWS + Smarty.addons.php + Smarty_Compiler.class.php + docs.sgml + templates/header.tpl + templates/index.tpl: update documenatation, template examples + +2001-07-03 Andrei Zmievski + + * NEWS + Smarty.class.php: Implemented access to request vars via $smarty var. + + * NEWS + Smarty_Compiler.class.php: + Fixed a bug with parsing function arguments in {if} tags. + +2001-06-30 Monte Ohrt + + * NEWS: update ChangeLog + +2001-06-29 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + docs.sgml + overlib.js: + moved overlib to separate file, added SMARTY_DIR, documented. added much documentation + +2001-06-29 Andrei Zmievski + + * NEWS + RELEASE_NOTES + TODO: *** empty log message *** + +2001-06-29 Monte Ohrt + + * NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + docs.sgml + index.php + templates/debug.tpl + templates/header.tpl + templates/index.tpl: update release notes + +2001-06-27 Andrei Zmievski + + * Smarty_Compiler.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: Implemented 'step' section attribute. + + * Smarty_Compiler.class.php: Negative values of 'max' will mean no max. + + * AUTHORS + NEWS: *** empty log message *** + +2001-06-26 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + index.php: Added 'max' and 'start' section attributes. + Added 'total' and 'iteration' section properties. + +2001-06-25 Andrei Zmievski + + * Config_File.class.php + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: Update version numbers. + +2001-06-23 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-06-21 Andrei Zmievski + + * Config_File.class.php + NEWS: Fixed booleanization bug. + +2001-06-20 Monte Ohrt + + * docs.sgml: + update documents to reflect changes to cached content & debugging + +2001-06-20 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php: Remove debug output for cached and fetched cases. + +2001-06-20 Monte Ohrt + + * Smarty.class.php: update include_info to false + + * Smarty.class.php + docs.sgml + index.php + templates/footer.tpl: + moved debug logic into Smarty completely, created flags for it + +2001-06-19 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php + templates/debug.tpl: *** empty log message *** + + * NEWS + Smarty.class.php: Remove unneeded debug functions. + +2001-06-19 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml + templates/debug.tpl + templates/footer.tpl: commit updates, add debug template + +2001-06-19 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php + TODO: + Moved config loading code inside main class, the compiled template now + simply calls that method. + +2001-06-15 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: * moved config array into class itself + * added 'scope' attribute for config_load + + * Smarty_Compiler.class.php + Smarty.addons.php + Smarty.class.php: Finishing up secure mode. + +2001-06-15 Monte Ohrt + + * NEWS: update ChangeLog + + * Smarty_Compiler.class.php: cleaned up logic of if statement security + + * Smarty_Compiler.class.php: update if logic to cover more situations + + * Smarty_Compiler.class.php + docs.sgml: update if statement security feature + +2001-06-14 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: + Fixed a bug with quoted strings inside if statements. + +2001-06-13 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php: added secure_dir array for multiple secure directories + + * Smarty.addons.php: update fetch funtion to respect security setting + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml: update documentation, changelog + + * Smarty.addons.php + Smarty.class.php: moved _extract setting to assign functions + + * Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + added assign/unassign custom functions, ability to re-extract tpl_vars + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + index.php: commit security features + +2001-06-11 Andrei Zmievski + + * Smarty.class.php: Version variable typo. + +2001-06-05 Andrei Zmievski + + * Smarty.class.php: + Create config object in fetch() or just set the config path if it already + exists. + +2001-06-04 Andrei Zmievski + + * Smarty.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: + Fixed a problem with $ inside strip tags. + +2001-05-31 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Config_File.class.php: Allow empty config_path. + +2001-05-29 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: update version numbers + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: moved version variable to internal variable + +2001-05-22 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + Moved $_smarty_sections and $_smarty_conf_obj into Smarty class. + +2001-05-18 Monte Ohrt + + * NEWS: update ChangeLog + + * FAQ + QUICKSTART: update FAQ, QUICKSTART for windows include_path setup + + * configs/test.conf: added configs directory to cvs + +2001-05-18 Andrei Zmievski + + * Smarty.class.php: Use compiler_class for including the file. + +2001-05-18 Monte Ohrt + + * docs.sgml: fix typo + +2001-05-16 Monte Ohrt + + * README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update files to version 1.4.1 + + * NEWS: update ChangeLog + +2001-05-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * index.php: forget that! + + * NEWS + Smarty_Compiler.class.php + index.php: Fixed a few E_NOTICE warnings. + +2001-05-09 Monte Ohrt + + * NEWS + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + docs.sgml: update dates versions + +2001-05-09 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php: + Use absolute paths when requiring/including Smart components. + + * NEWS: *** empty log message *** + + * Smarty.class.php: Use write mode instead of append. + +2001-05-02 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Fix indexing by section properties. + +2001-05-02 Monte Ohrt + + * NEWS: update changelog + + * Smarty.class.php: remove period from syntax error + +2001-05-02 Andrei Zmievski + + * Smarty_Compiler.class.php: Double-quote the attribute values by default. + +2001-04-30 Monte Ohrt + + * Smarty_Compiler.class.php + NEWS: added simple {capture} logic + +2001-04-30 Andrei Zmievski + + * TODO: *** empty log message *** + + * Smarty_Compiler.class.php + Smarty.class.php: Fix passing config vars to included files. + + * Smarty.class.php + Smarty_Compiler.class.php: Fix inclusion again. + +2001-04-30 Monte Ohrt + + * FAQ + RELEASE_NOTES + Smarty.class.php + misc/fix_vars.php + NEWS: update paths for windows (c:) + +2001-04-28 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Fix passing variables to included files. + + * templates/index.tpl: *** empty log message *** + +2001-04-27 Andrei Zmievski + + * Smarty_Compiler.class.php: Fix includes. + +2001-04-26 Andrei Zmievski + + * Smarty_Compiler.class.php + docs.sgml + Smarty.class.php: Formatting mostly. + + * Smarty_Compiler.class.php + Config_File.class.php: *** empty log message *** + +2001-04-26 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + FAQ + NEWS + QUICKSTART + RELEASE_NOTES + Smarty.class.php: update docs with new changes + +2001-04-26 Andrei Zmievski + + * RELEASE_NOTES: *** empty log message *** + + * docs.sgml + templates/index.tpl + NEWS + Smarty_Compiler.class.php: Added ability to reference object properties. + +2001-04-25 Andrei Zmievski + + * README + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + AUTHORS + Config_File.class.php + CREDITS + RELEASE_NOTES + NEWS: *** empty log message *** + + * docs.sgml: Docs on new parameter to custom functions. + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + Changing the way tpl vars are referenced and passing smarty object + to custom functions. + + * RELEASE_NOTES + docs.sgml: Fixing docs a bit. + +2001-04-24 Andrei Zmievski + + * docs.sgml: Docs for $compiler_class and compiler functions. + + * templates/index.tpl: *** empty log message *** + + * Smarty_Compiler.class.php: Remove debugging. + +2001-04-24 Monte Ohrt + + * docs.sgml: update compiler function docs + +2001-04-24 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: Added compiler function support. + +2001-04-24 Monte Ohrt + + * RELEASE_NOTES + Smarty.class.php: + update notes, change show_info_header to false by default + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + CREDITS + FAQ + NEWS + README + RELEASE_NOTES: update documenation, bug fixes + +2001-04-24 Andrei Zmievski + + * misc/fix_vars.php: Hopefully fix for sure. + +2001-04-23 Monte Ohrt + + * misc/fix_vars.php: uncomment copy/unlink + +2001-04-23 Andrei Zmievski + + * misc/fix_vars.php: Do it more thoroughly. + + * misc/fix_vars.php: check for } + +2001-04-22 Andrei Zmievski + + * misc/fix_vars.php: Fix variable parsing. + +2001-04-20 Monte Ohrt + + * misc/fix_vars.php: fix problem with 4.0.5-dev and preg_replace_callback + +2001-04-19 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + misc/fix_vars.php + NEWS + RELEASE_NOTES + Smarty.class.php: update notes/documentation + + * NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: update files for 1.4.0 release + +2001-04-16 Andrei Zmievski + + * misc/fix_vars.php: Added fix_vars.php script. + +2001-04-16 Monte Ohrt + + * QUICKSTART + RELEASE_NOTES + docs.sgml + templates/index.tpl: + update RELEASE_NOTES & scripts with new section var syntax + +2001-04-13 Andrei Zmievski + + * Smarty_Compiler.class.php: * Implement new variable format parser. + * Optimizing config load a bit. + +2001-04-13 Monte Ohrt + + * FAQ + NEWS + RELEASE_NOTES + Smarty.class.php: + added $check_cached_insert_tags to speed up cached pages if + {insert ...} is not used (Monte) + +2001-04-12 Andrei Zmievski + + * NEWS + Smarty.class.php + RELEASE_NOTES: *** empty log message *** + + * Smarty_Compiler.class.php: Remove redundant functions. + + * Smarty.class.php: Formatting. + +2001-04-12 Monte Ohrt + + * Smarty.class.php: update file: parsing + + * Smarty.class.php + docs.sgml: update documentation + +2001-04-12 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php + TODO: *** empty log message *** + +2001-04-11 Monte Ohrt + + * FAQ + QUICKSTART + RELEASE_NOTES: added RELEASE_NOTES file to cvs + + * NEWS + docs.sgml: update ChangeLog, update documentation + + * Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: + update Smarty to compile at run-time. added ability to get files from + absolute paths, added work around for LOCK_EX and windows, changed a few + file permissions to be more secure. + +2001-03-29 Monte Ohrt + + * NEWS + Smarty.addons.php: + allow arbitrary date strings instead of just timestamps + +2001-03-28 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + FAQ + NEWS + README + Smarty.addons.php: + update version in class, update docs for count_ and new vars + + * templates/index.tpl + docs.sgml: update docs, example template + +2001-03-28 Andrei Zmievski + + * Smarty_Compiler.class.php: Some variable renaming. + +2001-03-23 Andrei Zmievski + + * Smarty_Compiler.class.php + NEWS: Fixed nested include infinite repeat bug. + +2001-03-23 Monte Ohrt + + * Smarty.class.php: fix version number + + * Smarty.class.php + NEWS: added optional HTML header to output + +2001-03-22 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixed inclusion of dynamic files. + +2001-03-16 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixing the config_load scoping. + + * Smarty_Compiler.class.php: making config variables global for now. + +2001-03-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + * Includes are now always done via generated function call to protect + namespace. + * config_load now always uses global config object to improve + performance. + +2001-03-13 Monte Ohrt + + * docs.sgml: update math documentation with format attribute + +2001-03-11 Monte Ohrt + + * docs.sgml + NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update math function with format attribute + +2001-03-10 Andrei Zmievski + + * Smarty.addons.php: *** empty log message *** + + * NEWS + Smarty.addons.php + Smarty.class.php: Added html_select_time custom function. + +2001-03-08 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php + NEWS + README + Smarty.addons.php: rename 1.3.1b to 1.3.1pl1 + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version numbers, changelog + + * Smarty.class.php + Smarty_Compiler.class.php: + moved _syntax_error to Smarty_Compiler.class.php + + * Smarty.class.php + docs.sgml: + missing _syntax_error function recovered. fixed minor syntax in docs + +2001-03-07 Monte Ohrt + + * QUICKSTART + README + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + BUGS + INSTALL + NEWS: update everything to 1.3.1 + +2001-03-03 Monte Ohrt + + * Smarty_Compiler.class.php + Smarty.class.php: fixed bug with cached insert tags + +2001-03-02 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + fix cache fuctions with separated compiled class + + * FAQ + NEWS + docs.sgml: update changelog + +2001-03-02 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Added 'first' and 'last' section properties. + +2001-03-02 Monte Ohrt + + * TODO: remove compiling separation TODO + + * Smarty_Compiler.class.php + Smarty.addons.php + Smarty.class.php: update function headers + + * templates/index.tpl + NEWS + Smarty.class.php + Smarty_Compiler.class.php + index.php: split out compiling code for faster execution + + * Smarty.class.php: fixed a few warning messages + + * Smarty.addons.php + Smarty.class.php + docs.sgml + NEWS: added fetch, unregister mod/fun, updated docs + +2001-03-01 Monte Ohrt + + * Smarty.addons.php: added "int" to available list + + * docs.sgml + FAQ + Smarty.class.php: update FAQ, add math functions & update documetation + + * index.php + Smarty.addons.php + Smarty.class.php + docs.sgml: fixed literal tags and other optional delimiters + +2001-02-26 Andrei Zmievski + + * NEWS + Smarty.class.php: + Added index_prev, index_next section properties and ability to + index by them. + + * NEWS + Smarty.addons.php + Smarty.class.php: Reverting the plugins patch - needs more thought. + + * Smarty.class.php: Fixing plugin loading. + +2001-02-23 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php + plugins/standard.plugin.php + NEWS: Added plugin functionality. + +2001-02-22 Monte Ohrt + + * docs.sgml + templates/index.tpl + NEWS + README + Smarty.class.php: fixed issue with php tags executed in literal blocks + +2001-02-21 Monte Ohrt + + * NEWS: update changelog for LGPL change + + * Smarty.class.php + docs.sgml + README + Smarty.addons.php: updated version numbers to 1.3.0 + + * NEWS + templates/index.tpl: update changelog, rearrange index.tpl file + +2001-02-21 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-02-21 Monte Ohrt + + * docs.sgml: update parameters for is_cached and fetch + +2001-02-21 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-02-21 Monte Ohrt + + * NEWS + Smarty.addons.php + docs.sgml: update docs, remove header function from addons + +2001-02-20 Monte Ohrt + + * FAQ + NEWS: update changelog + + * TODO: update todo + + * TODO: update todo list + + * Smarty.class.php: update php tag handling logic + +2001-02-19 Monte Ohrt + + * index.php + Config_File.class.php + FAQ + Smarty.class.php + docs.sgml: fixed + + * Smarty.addons.php: *** empty log message *** + +2001-02-13 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-02-12 Andrei Zmievski + + * templates/index.tpl + Smarty.class.php: *** empty log message *** + +2001-02-10 Monte Ohrt + + * Smarty.class.php: remove unneeded preg_match + + * Smarty.class.php: remove comment + + * Smarty.class.php: updated php escape to handle +{/if} \ No newline at end of file diff --git a/gulliver/thirdparty/smarty/libs/internals/core.assemble_plugin_filepath.php b/gulliver/thirdparty/smarty/libs/internals/core.assemble_plugin_filepath.php new file mode 100644 index 000000000..690d3ddbc --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.assemble_plugin_filepath.php @@ -0,0 +1,67 @@ +plugins_dir as $_plugin_dir) { + + $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; + + // see if path is relative + if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) { + $_relative_paths[] = $_plugin_dir; + // relative path, see if it is in the SMARTY_DIR + if (@is_readable(SMARTY_DIR . $_plugin_filepath)) { + $_return = SMARTY_DIR . $_plugin_filepath; + break; + } + } + // try relative to cwd (or absolute) + if (@is_readable($_plugin_filepath)) { + $_return = $_plugin_filepath; + break; + } + } + + if($_return === false) { + // still not found, try PHP include_path + if(isset($_relative_paths)) { + foreach ((array)$_relative_paths as $_plugin_dir) { + + $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; + + $_params = array('file_path' => $_plugin_filepath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $smarty)) { + $_return = $_params['new_file_path']; + break; + } + } + } + } + $_filepaths_cache[$_plugin_filename] = $_return; + return $_return; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.assign_smarty_interface.php b/gulliver/thirdparty/smarty/libs/internals/core.assign_smarty_interface.php new file mode 100644 index 000000000..7e65a73ec --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.assign_smarty_interface.php @@ -0,0 +1,43 @@ + + * Name: assign_smarty_interface
    + * Purpose: assign the $smarty interface variable + * @param array Format: null + * @param Smarty + */ +function smarty_core_assign_smarty_interface($params, &$smarty) +{ + if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) { + return; + } + + $_globals_map = array('g' => 'HTTP_GET_VARS', + 'p' => 'HTTP_POST_VARS', + 'c' => 'HTTP_COOKIE_VARS', + 's' => 'HTTP_SERVER_VARS', + 'e' => 'HTTP_ENV_VARS'); + + $_smarty_vars_request = array(); + + foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) { + if (isset($_globals_map[$_c])) { + $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]); + } + } + $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']); + + $smarty->_smarty_vars['request'] = $_smarty_vars_request; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.create_dir_structure.php b/gulliver/thirdparty/smarty/libs/internals/core.create_dir_structure.php new file mode 100644 index 000000000..3eecc4972 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.create_dir_structure.php @@ -0,0 +1,79 @@ +_dir_perms) && !is_dir($_new_dir)) { + $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); + return false; + } + $_new_dir .= '/'; + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.display_debug_console.php b/gulliver/thirdparty/smarty/libs/internals/core.display_debug_console.php new file mode 100644 index 000000000..1a80f3909 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.display_debug_console.php @@ -0,0 +1,61 @@ + + * Name: display_debug_console
    + * Purpose: display the javascript debug console window + * @param array Format: null + * @param Smarty + */ +function smarty_core_display_debug_console($params, &$smarty) +{ + // we must force compile the debug template in case the environment + // changed between separate applications. + + if(empty($smarty->debug_tpl)) { + // set path to debug template from SMARTY_DIR + $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; + if($smarty->security && is_file($smarty->debug_tpl)) { + $smarty->secure_dir[] = realpath($smarty->debug_tpl); + } + $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; + } + + $_ldelim_orig = $smarty->left_delimiter; + $_rdelim_orig = $smarty->right_delimiter; + + $smarty->left_delimiter = '{'; + $smarty->right_delimiter = '}'; + + $_compile_id_orig = $smarty->_compile_id; + $smarty->_compile_id = null; + + $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl); + if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path)) + { + ob_start(); + $smarty->_include($_compile_path); + $_results = ob_get_contents(); + ob_end_clean(); + } else { + $_results = ''; + } + + $smarty->_compile_id = $_compile_id_orig; + + $smarty->left_delimiter = $_ldelim_orig; + $smarty->right_delimiter = $_rdelim_orig; + + return $_results; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.get_include_path.php b/gulliver/thirdparty/smarty/libs/internals/core.get_include_path.php new file mode 100644 index 000000000..43432412b --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.get_include_path.php @@ -0,0 +1,44 @@ + diff --git a/gulliver/thirdparty/smarty/libs/internals/core.get_microtime.php b/gulliver/thirdparty/smarty/libs/internals/core.get_microtime.php new file mode 100644 index 000000000..f1a28e042 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.get_microtime.php @@ -0,0 +1,23 @@ + diff --git a/gulliver/thirdparty/smarty/libs/internals/core.get_php_resource.php b/gulliver/thirdparty/smarty/libs/internals/core.get_php_resource.php new file mode 100644 index 000000000..786d4e78e --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.get_php_resource.php @@ -0,0 +1,80 @@ +trusted_dir; + $smarty->_parse_resource_name($params, $smarty); + + /* + * Find out if the resource exists. + */ + + if ($params['resource_type'] == 'file') { + $_readable = false; + if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) { + $_readable = true; + } else { + // test for file in include_path + $_params = array('file_path' => $params['resource_name']); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $smarty)) { + $_include_path = $_params['new_file_path']; + $_readable = true; + } + } + } else if ($params['resource_type'] != 'file') { + $_template_source = null; + $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0]) + && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0], + array($params['resource_name'], &$_template_source, &$smarty)); + } + + /* + * Set the error function, depending on which class calls us. + */ + if (method_exists($smarty, '_syntax_error')) { + $_error_funcc = '_syntax_error'; + } else { + $_error_funcc = 'trigger_error'; + } + + if ($_readable) { + if ($smarty->security) { + require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); + if (!smarty_core_is_trusted($params, $smarty)) { + $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); + return false; + } + } + } else { + $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable'); + return false; + } + + if ($params['resource_type'] == 'file') { + $params['php_resource'] = $params['resource_name']; + } else { + $params['php_resource'] = $_template_source; + } + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.is_secure.php b/gulliver/thirdparty/smarty/libs/internals/core.is_secure.php new file mode 100644 index 000000000..d54abd432 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.is_secure.php @@ -0,0 +1,59 @@ +security || $smarty->security_settings['INCLUDE_ANY']) { + return true; + } + + if ($params['resource_type'] == 'file') { + $_rp = realpath($params['resource_name']); + if (isset($params['resource_base_path'])) { + foreach ((array)$params['resource_base_path'] as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false && + strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { + return true; + } + } + } + if (!empty($smarty->secure_dir)) { + foreach ((array)$smarty->secure_dir as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false) { + if($_cd == $_rp) { + return true; + } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { + return true; + } + } + } + } + } else { + // resource is not on local file system + return call_user_func_array( + $smarty->_plugins['resource'][$params['resource_type']][0][2], + array($params['resource_name'], &$smarty)); + } + + return false; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.is_trusted.php b/gulliver/thirdparty/smarty/libs/internals/core.is_trusted.php new file mode 100644 index 000000000..429973158 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.is_trusted.php @@ -0,0 +1,47 @@ +trusted_dir)) { + $_rp = realpath($params['resource_name']); + foreach ((array)$smarty->trusted_dir as $curr_dir) { + if (!empty($curr_dir) && is_readable ($curr_dir)) { + $_cd = realpath($curr_dir); + if (strncmp($_rp, $_cd, strlen($_cd)) == 0 + && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { + $_smarty_trusted = true; + break; + } + } + } + } + + } else { + // resource is not on local file system + $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3], + array($params['resource_name'], $smarty)); + } + + return $_smarty_trusted; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.load_plugins.php b/gulliver/thirdparty/smarty/libs/internals/core.load_plugins.php new file mode 100644 index 000000000..6db1dc51d --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.load_plugins.php @@ -0,0 +1,125 @@ +_plugins[$_type][$_name]; + + /* + * We do not load plugin more than once for each instance of Smarty. + * The following code checks for that. The plugin can also be + * registered dynamically at runtime, in which case template file + * and line number will be unknown, so we fill them in. + * + * The final element of the info array is a flag that indicates + * whether the dynamically registered plugin function has been + * checked for existence yet or not. + */ + if (isset($_plugin)) { + if (empty($_plugin[3])) { + if (!is_callable($_plugin[0])) { + $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__); + } else { + $_plugin[1] = $_tpl_file; + $_plugin[2] = $_tpl_line; + $_plugin[3] = true; + if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */ + } + } + continue; + } else if ($_type == 'insert') { + /* + * For backwards compatibility, we check for insert functions in + * the symbol table before trying to load them as a plugin. + */ + $_plugin_func = 'insert_' . $_name; + if (function_exists($_plugin_func)) { + $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false); + continue; + } + } + + $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name); + + if (! $_found = ($_plugin_file != false)) { + $_message = "could not load plugin file '$_type.$_name.php'\n"; + } + + /* + * If plugin file is found, it -must- provide the properly named + * plugin function. In case it doesn't, simply output the error and + * do not fall back on any other method. + */ + if ($_found) { + include_once $_plugin_file; + + $_plugin_func = 'smarty_' . $_type . '_' . $_name; + if (!function_exists($_plugin_func)) { + $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__); + continue; + } + } + /* + * In case of insert plugins, their code may be loaded later via + * 'script' attribute. + */ + else if ($_type == 'insert' && $_delayed_loading) { + $_plugin_func = 'smarty_' . $_type . '_' . $_name; + $_found = true; + } + + /* + * Plugin specific processing and error checking. + */ + if (!$_found) { + if ($_type == 'modifier') { + /* + * In case modifier falls back on using PHP functions + * directly, we only allow those specified in the security + * context. + */ + if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) { + $_message = "(secure mode) modifier '$_name' is not allowed"; + } else { + if (!function_exists($_name)) { + $_message = "modifier '$_name' is not implemented"; + } else { + $_plugin_func = $_name; + $_found = true; + } + } + } else if ($_type == 'function') { + /* + * This is a catch-all situation. + */ + $_message = "unknown tag - '$_name'"; + } + } + + if ($_found) { + $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true); + } else { + // output error + $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__); + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.load_resource_plugin.php b/gulliver/thirdparty/smarty/libs/internals/core.load_resource_plugin.php new file mode 100644 index 000000000..a7d37d1af --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.load_resource_plugin.php @@ -0,0 +1,74 @@ +_plugins['resource'][$params['type']]; + if (isset($_plugin)) { + if (!$_plugin[1] && count($_plugin[0])) { + $_plugin[1] = true; + foreach ($_plugin[0] as $_plugin_func) { + if (!is_callable($_plugin_func)) { + $_plugin[1] = false; + break; + } + } + } + + if (!$_plugin[1]) { + $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__); + } + + return; + } + + $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']); + $_found = ($_plugin_file != false); + + if ($_found) { /* + * If the plugin file is found, it -must- provide the properly named + * plugin functions. + */ + include_once($_plugin_file); + + /* + * Locate functions that we require the plugin to provide. + */ + $_resource_ops = array('source', 'timestamp', 'secure', 'trusted'); + $_resource_funcs = array(); + foreach ($_resource_ops as $_op) { + $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op; + if (!function_exists($_plugin_func)) { + $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__); + return; + } else { + $_resource_funcs[] = $_plugin_func; + } + } + + $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true); + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.process_cached_inserts.php b/gulliver/thirdparty/smarty/libs/internals/core.process_cached_inserts.php new file mode 100644 index 000000000..1d78edd93 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.process_cached_inserts.php @@ -0,0 +1,71 @@ +_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis', + $params['results'], $match); + list($cached_inserts, $insert_args) = $match; + + for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + $args = unserialize($insert_args[$i]); + $name = $args['name']; + + if (isset($args['script'])) { + $_params = array('resource_name' => $smarty->_dequote($args['script'])); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + if(!smarty_core_get_php_resource($_params, $smarty)) { + return false; + } + $resource_type = $_params['resource_type']; + $php_resource = $_params['php_resource']; + + + if ($resource_type == 'file') { + $smarty->_include($php_resource, true); + } else { + $smarty->_eval($php_resource); + } + } + + $function_name = $smarty->_plugins['insert'][$name][0]; + if (empty($args['assign'])) { + $replace = $function_name($args, $smarty); + } else { + $smarty->assign($args['assign'], $function_name($args, $smarty)); + $replace = ''; + } + + $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'insert', + 'filename' => 'insert_'.$name, + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time); + } + } + + return $params['results']; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.process_compiled_include.php b/gulliver/thirdparty/smarty/libs/internals/core.process_compiled_include.php new file mode 100644 index 000000000..d539423bf --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.process_compiled_include.php @@ -0,0 +1,37 @@ +_cache_including; + $smarty->_cache_including = true; + + $_return = $params['results']; + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $smarty->_include($_include_file_path, true); + } + + foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) { + $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', + array(&$smarty, '_process_compiled_include_callback'), + $_return); + } + $smarty->_cache_including = $_cache_including; + return $_return; +} + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.read_cache_file.php b/gulliver/thirdparty/smarty/libs/internals/core.read_cache_file.php new file mode 100644 index 000000000..c60e113a7 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.read_cache_file.php @@ -0,0 +1,101 @@ +force_compile) { + // force compile enabled, always regenerate + return false; + } + + if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) { + list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']]; + return true; + } + + if (!empty($smarty->cache_handler_func)) { + // use cache_handler function + call_user_func_array($smarty->cache_handler_func, + array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); + } else { + // use local cache file + $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); + $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); + $params['results'] = $smarty->_read_file($_cache_file); + } + + if (empty($params['results'])) { + // nothing to parse (error?), regenerate cache + return false; + } + + $_contents = $params['results']; + $_info_start = strpos($_contents, "\n") + 1; + $_info_len = (int)substr($_contents, 0, $_info_start - 1); + $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); + $params['results'] = substr($_contents, $_info_start + $_info_len); + + if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ + // caching by expiration time + if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) { + // cache expired, regenerate + return false; + } + } else { + // caching by lifetime + if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) { + // cache expired, regenerate + return false; + } + } + + if ($smarty->compile_check) { + $_params = array('get_source' => false, 'quiet'=>true); + foreach (array_keys($_cache_info['template']) as $_template_dep) { + $_params['resource_name'] = $_template_dep; + if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { + // template file has changed, regenerate cache + return false; + } + } + + if (isset($_cache_info['config'])) { + $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true); + foreach (array_keys($_cache_info['config']) as $_config_dep) { + $_params['resource_name'] = $_config_dep; + if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { + // config file has changed, regenerate cache + return false; + } + } + } + } + + $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); + + $smarty->_cache_info = $_cache_info; + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.rm_auto.php b/gulliver/thirdparty/smarty/libs/internals/core.rm_auto.php new file mode 100644 index 000000000..b251f6491 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.rm_auto.php @@ -0,0 +1,71 @@ + $params['auto_base'], + 'level' => 0, + 'exp_time' => $params['exp_time'] + ); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); + + if(isset($params['auto_source'])) { + if (isset($params['extensions'])) { + $_res = false; + foreach ((array)$params['extensions'] as $_extension) + $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); + } else { + $_res = $smarty->_unlink($_tname, $params['exp_time']); + } + } elseif ($smarty->use_sub_dirs) { + $_params = array( + 'dirname' => $_tname, + 'level' => 1, + 'exp_time' => $params['exp_time'] + ); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + // remove matching file names + $_handle = opendir($params['auto_base']); + $_res = true; + while (false !== ($_filename = readdir($_handle))) { + if($_filename == '.' || $_filename == '..') { + continue; + } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { + $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); + } + } + } + } + + return $_res; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.rmdir.php b/gulliver/thirdparty/smarty/libs/internals/core.rmdir.php new file mode 100644 index 000000000..2166c44d2 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.rmdir.php @@ -0,0 +1,54 @@ + keep root) + * WARNING: no tests, it will try to remove what you tell it! + * + * @param string $dirname + * @param integer $level + * @param integer $exp_time + * @return boolean + */ + +// $dirname, $level = 1, $exp_time = null + +function smarty_core_rmdir($params, &$smarty) +{ + if(!isset($params['level'])) { $params['level'] = 1; } + if(!isset($params['exp_time'])) { $params['exp_time'] = null; } + + if($_handle = @opendir($params['dirname'])) { + + while (false !== ($_entry = readdir($_handle))) { + if ($_entry != '.' && $_entry != '..') { + if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { + $_params = array( + 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, + 'level' => $params['level'] + 1, + 'exp_time' => $params['exp_time'] + ); + smarty_core_rmdir($_params, $smarty); + } + else { + $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); + } + } + } + closedir($_handle); + } + + if ($params['level']) { + return @rmdir($params['dirname']); + } + return (bool)$_handle; + +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.run_insert_handler.php b/gulliver/thirdparty/smarty/libs/internals/core.run_insert_handler.php new file mode 100644 index 000000000..71c384508 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.run_insert_handler.php @@ -0,0 +1,71 @@ +debugging) { + $_params = array(); + $_debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + if ($smarty->caching) { + $_arg_string = serialize($params['args']); + $_name = $params['args']['name']; + if (!isset($smarty->_cache_info['insert_tags'][$_name])) { + $smarty->_cache_info['insert_tags'][$_name] = array('insert', + $_name, + $smarty->_plugins['insert'][$_name][1], + $smarty->_plugins['insert'][$_name][2], + !empty($params['args']['script']) ? true : false); + } + return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5; + } else { + if (isset($params['args']['script'])) { + $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + if(!smarty_core_get_php_resource($_params, $smarty)) { + return false; + } + + if ($_params['resource_type'] == 'file') { + $smarty->_include($_params['php_resource'], true); + } else { + $smarty->_eval($_params['php_resource']); + } + unset($params['args']['script']); + } + + $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0]; + $_content = $_funcname($params['args'], $smarty); + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'insert', + 'filename' => 'insert_'.$params['args']['name'], + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); + } + + if (!empty($params['args']["assign"])) { + $smarty->assign($params['args']["assign"], $_content); + } else { + return $_content; + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.smarty_include_php.php b/gulliver/thirdparty/smarty/libs/internals/core.smarty_include_php.php new file mode 100644 index 000000000..30c6e7654 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.smarty_include_php.php @@ -0,0 +1,50 @@ + $params['smarty_file']); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); + smarty_core_get_php_resource($_params, $smarty); + $_smarty_resource_type = $_params['resource_type']; + $_smarty_php_resource = $_params['php_resource']; + + if (!empty($params['smarty_assign'])) { + ob_start(); + if ($_smarty_resource_type == 'file') { + $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); + } else { + $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); + } + $smarty->assign($params['smarty_assign'], ob_get_contents()); + ob_end_clean(); + } else { + if ($_smarty_resource_type == 'file') { + $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); + } else { + $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); + } + } +} + + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.write_cache_file.php b/gulliver/thirdparty/smarty/libs/internals/core.write_cache_file.php new file mode 100644 index 000000000..72f785b74 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.write_cache_file.php @@ -0,0 +1,96 @@ +_cache_info['timestamp'] = time(); + if ($smarty->cache_lifetime > -1){ + // expiration set + $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; + } else { + // cache will never expire + $smarty->_cache_info['expires'] = -1; + } + + // collapse nocache.../nocache-tags + if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { + // remove everything between every pair of outermost noache.../nocache-tags + // and replace it by a single nocache-tag + // this new nocache-tag will be replaced by dynamic contents in + // smarty_core_process_compiled_includes() on a cache-read + + $match_count = count($match[0]); + $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); + + $level = 0; + $j = 0; + for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { + if ($results[$i] == $match[0][$j]) { + // nocache tag + if ($match[1][$j]) { // closing tag + $level--; + unset($results[$i]); + } else { // opening tag + if ($level++ > 0) unset($results[$i]); + } + $j++; + } elseif ($level > 0) { + unset($results[$i]); + } + } + $params['results'] = implode('', $results); + } + $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; + + // prepend the cache header info into cache file + $_cache_info = serialize($smarty->_cache_info); + $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; + + if (!empty($smarty->cache_handler_func)) { + // use cache_handler function + call_user_func_array($smarty->cache_handler_func, + array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); + } else { + // use local cache file + + if(!@is_writable($smarty->cache_dir)) { + // cache_dir not writable, see if it exists + if(!@is_dir($smarty->cache_dir)) { + $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); + return false; + } + $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); + return false; + } + + $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); + $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); + $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_include.php b/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_include.php new file mode 100644 index 000000000..c14adb5f4 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_include.php @@ -0,0 +1,91 @@ +caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; + $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; + + preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', + $params['compiled_content'], $_match_source, PREG_SET_ORDER); + + // no nocache-parts found: done + if (count($_match_source)==0) return; + + // convert the matched php-code to functions + $_include_compiled = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; + + $_compile_path = $params['include_file_path']; + + $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; + $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; + + $_include_compiled .= $params['plugins_code']; + $_include_compiled .= "= 5.0) ? '_smarty' : 'this'; + for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { + $_match =& $_match_source[$_i]; + $source = $_match[4]; + if ($this_varname == '_smarty') { + /* rename $this to $_smarty in the sourcecode */ + $tokens = token_get_all('\n"; + + $_params = array('filename' => $_compile_path, + 'contents' => $_include_compiled, 'create_dirs' => true); + + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; +} + + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_resource.php b/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_resource.php new file mode 100644 index 000000000..b902eff3c --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.write_compiled_resource.php @@ -0,0 +1,35 @@ +compile_dir)) { + // compile_dir not writable, see if it exists + if(!@is_dir($smarty->compile_dir)) { + $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); + return false; + } + $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR); + return false; + } + + $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/internals/core.write_file.php b/gulliver/thirdparty/smarty/libs/internals/core.write_file.php new file mode 100644 index 000000000..8a3a3b398 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/internals/core.write_file.php @@ -0,0 +1,54 @@ + $_dirname); + require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); + smarty_core_create_dir_structure($_params, $smarty); + } + + // write to tmp file, then rename it to avoid file locking race condition + $_tmp_file = tempnam($_dirname, 'wrt'); + + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); + return false; + } + } + + fwrite($fd, $params['contents']); + fclose($fd); + + if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { + // On platforms and filesystems that cannot overwrite with rename() + // delete the file before renaming it -- because windows always suffers + // this, it is short-circuited to avoid the initial rename() attempt + @unlink($params['filename']); + @rename($_tmp_file, $params['filename']); + } + @chmod($params['filename'], $smarty->_file_perms); + + return true; +} + +/* vim: set expandtab: */ + +?> \ No newline at end of file diff --git a/gulliver/thirdparty/smarty/libs/plugins/block.textformat.php b/gulliver/thirdparty/smarty/libs/plugins/block.textformat.php new file mode 100644 index 000000000..8cd010acb --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/block.textformat.php @@ -0,0 +1,103 @@ + + * Name: textformat
    + * Purpose: format text a certain way with preset styles + * or custom wrap/indent settings
    + * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * @param array + *
    + * Params:   style: string (email)
    + *           indent: integer (0)
    + *           wrap: integer (80)
    + *           wrap_char string ("\n")
    + *           indent_char: string (" ")
    + *           wrap_boundary: boolean (true)
    + * 
    + * @author Monte Ohrt + * @param string contents of the block + * @param Smarty clever simulation of a method + * @return string string $content re-formatted + */ +function smarty_block_textformat($params, $content, &$smarty) +{ + if (is_null($content)) { + return; + } + + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string)$_val; + break; + + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int)$_val; + break; + + case 'wrap_cut': + $$_key = (bool)$_val; + break; + + default: + $smarty->trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + + // split into paragraphs + $_paragraphs = preg_split('![\r\n][\r\n]!',$content); + $_output = ''; + + for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { + if ($_paragraphs[$_x] == '') { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); + // indent first line + if($indent_first > 0) { + $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; + } + // wordwrap sentences + $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); + // indent lines + if($indent > 0) { + $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + return $assign ? $smarty->assign($assign, $_output) : $_output; + +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/compiler.assign.php b/gulliver/thirdparty/smarty/libs/plugins/compiler.assign.php new file mode 100644 index 000000000..be1729850 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/compiler.assign.php @@ -0,0 +1,40 @@ + + * Name: assign
    + * Purpose: assign a value to a template variable + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} + * (Smarty online manual) + * @author Monte Ohrt (initial author) + * @auther messju mohr (conversion to compiler function) + * @param string containing var-attribute and value-attribute + * @param Smarty_Compiler + */ +function smarty_compiler_assign($tag_attrs, &$compiler) +{ + $_params = $compiler->_parse_attrs($tag_attrs); + + if (!isset($_params['var'])) { + $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); + return; + } + + if (!isset($_params['value'])) { + $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); + return; + } + + return "\$this->assign({$_params['var']}, {$_params['value']});"; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.assign_debug_info.php b/gulliver/thirdparty/smarty/libs/plugins/function.assign_debug_info.php new file mode 100644 index 000000000..654049876 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.assign_debug_info.php @@ -0,0 +1,40 @@ + + * Name: assign_debug_info
    + * Purpose: assign debug info to the template
    + * @author Monte Ohrt + * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, + * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} + * @param Smarty + */ +function smarty_function_assign_debug_info($params, &$smarty) +{ + $assigned_vars = $smarty->_tpl_vars; + ksort($assigned_vars); + if (@is_array($smarty->_config[0])) { + $config_vars = $smarty->_config[0]; + ksort($config_vars); + $smarty->assign("_debug_config_keys", array_keys($config_vars)); + $smarty->assign("_debug_config_vals", array_values($config_vars)); + } + + $included_templates = $smarty->_smarty_debug_info; + + $smarty->assign("_debug_keys", array_keys($assigned_vars)); + $smarty->assign("_debug_vals", array_values($assigned_vars)); + + $smarty->assign("_debug_tpls", $included_templates); +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.config_load.php b/gulliver/thirdparty/smarty/libs/plugins/function.config_load.php new file mode 100644 index 000000000..db89f638c --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.config_load.php @@ -0,0 +1,142 @@ + + * Name: config_load
    + * Purpose: load config file vars + * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} + * (Smarty online manual) + * @author Monte Ohrt + * @author messju mohr (added use of resources) + * @param array Format: + *
    + * array('file' => required config file name,
    + *       'section' => optional config file section to load
    + *       'scope' => local/parent/global
    + *       'global' => overrides scope, setting to parent if true)
    + * 
    + * @param Smarty + */ +function smarty_function_config_load($params, &$smarty) +{ + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $smarty); + } + + $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null; + $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null; + $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global'; + $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false; + + if (!isset($_file) || strlen($_file) == 0) { + $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($_scope)) { + if ($_scope != 'local' && + $_scope != 'parent' && + $_scope != 'global') { + $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } else { + if ($_global) { + $_scope = 'parent'; + } else { + $_scope = 'local'; + } + } + + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + 'get_source' => false); + $smarty->_parse_resource_name($_params); + $_file_path = $_params['resource_type'] . ':' . $_params['resource_name']; + if (isset($_section)) + $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section); + else + $_compile_file = $smarty->_get_compile_path($_file_path); + + if($smarty->force_compile || !file_exists($_compile_file)) { + $_compile = true; + } elseif ($smarty->compile_check) { + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + 'get_source' => false); + $_compile = $smarty->_fetch_resource_info($_params) && + $_params['resource_timestamp'] > filemtime($_compile_file); + } else { + $_compile = false; + } + + if($_compile) { + // compile config file + if(!is_object($smarty->_conf_obj)) { + require_once SMARTY_DIR . $smarty->config_class . '.class.php'; + $smarty->_conf_obj = new $smarty->config_class(); + $smarty->_conf_obj->overwrite = $smarty->config_overwrite; + $smarty->_conf_obj->booleanize = $smarty->config_booleanize; + $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden; + $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines; + } + + $_params = array('resource_name' => $_file, + 'resource_base_path' => $smarty->config_dir, + $_params['get_source'] = true); + if (!$smarty->_fetch_resource_info($_params)) { + return; + } + $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']); + $_config_vars = array_merge($smarty->_conf_obj->get($_file), + $smarty->_conf_obj->get($_file, $_section)); + if(function_exists('var_export')) { + $_output = ''; + } else { + $_output = ''\\\'', '\\'=>'\\\\')) . '\'); ?>'; + } + $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp'])); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $smarty); + } else { + include($_compile_file); + } + + if ($smarty->caching) { + $smarty->_cache_info['config'][$_file] = true; + } + + $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars); + $smarty->_config[0]['files'][$_file] = true; + + if ($_scope == 'parent') { + $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars); + $smarty->_config[1]['files'][$_file] = true; + } else if ($_scope == 'global') { + for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) { + $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars); + $smarty->_config[$i]['files'][$_file] = true; + } + } + + if ($smarty->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $smarty->_smarty_debug_info[] = array('type' => 'config', + 'filename' => $_file.' ['.$_section.'] '.$_scope, + 'depth' => $smarty->_inclusion_depth, + 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); + } + +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.counter.php b/gulliver/thirdparty/smarty/libs/plugins/function.counter.php new file mode 100644 index 000000000..1f26db5fb --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.counter.php @@ -0,0 +1,80 @@ + + * Name: counter
    + * Purpose: print out a counter value + * @author Monte Ohrt + * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * @param array parameters + * @param Smarty + * @return string|null + */ +function smarty_function_counter($params, &$smarty) +{ + static $counters = array(); + + $name = (isset($params['name'])) ? $params['name'] : 'default'; + if (!isset($counters[$name])) { + $counters[$name] = array( + 'start'=>1, + 'skip'=>1, + 'direction'=>'up', + 'count'=>1 + ); + } + $counter =& $counters[$name]; + + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int)$params['start']; + } + + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; + } + + if (isset($counter['assign'])) { + $smarty->assign($counter['assign'], $counter['count']); + } + + if (isset($params['print'])) { + $print = (bool)$params['print']; + } else { + $print = empty($counter['assign']); + } + + if ($print) { + $retval = $counter['count']; + } else { + $retval = null; + } + + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; + } + + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; + } + + if ($counter['direction'] == "down") + $counter['count'] -= $counter['skip']; + else + $counter['count'] += $counter['skip']; + + return $retval; + +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.cycle.php b/gulliver/thirdparty/smarty/libs/plugins/function.cycle.php new file mode 100644 index 000000000..fe78bb87d --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.cycle.php @@ -0,0 +1,102 @@ + + * Name: cycle
    + * Date: May 3, 2002
    + * Purpose: cycle through given values
    + * Input: + * - name = name of cycle (optional) + * - values = comma separated list of values to cycle, + * or an array of values to cycle + * (this can be left out for subsequent calls) + * - reset = boolean - resets given var to true + * - print = boolean - print var or not. default is true + * - advance = boolean - whether or not to advance the cycle + * - delimiter = the value delimiter, default is "," + * - assign = boolean, assigns to template var instead of + * printed. + * + * Examples:
    + *
    + * {cycle values="#eeeeee,#d0d0d0d"}
    + * {cycle name=row values="one,two,three" reset=true}
    + * {cycle name=row}
    + * 
    + * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * @param array + * @param Smarty + * @return string|null + */ +function smarty_function_cycle($params, &$smarty) +{ + static $cycle_vars; + + $name = (empty($params['name'])) ? 'default' : $params['name']; + $print = (isset($params['print'])) ? (bool)$params['print'] : true; + $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true; + $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false; + + if (!in_array('values', array_keys($params))) { + if(!isset($cycle_vars[$name]['values'])) { + $smarty->trigger_error("cycle: missing 'values' parameter"); + return; + } + } else { + if(isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] ) { + $cycle_vars[$name]['index'] = 0; + } + $cycle_vars[$name]['values'] = $params['values']; + } + + $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; + + if(is_array($cycle_vars[$name]['values'])) { + $cycle_array = $cycle_vars[$name]['values']; + } else { + $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); + } + + if(!isset($cycle_vars[$name]['index']) || $reset ) { + $cycle_vars[$name]['index'] = 0; + } + + if (isset($params['assign'])) { + $print = false; + $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + } + + if($print) { + $retval = $cycle_array[$cycle_vars[$name]['index']]; + } else { + $retval = null; + } + + if($advance) { + if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { + $cycle_vars[$name]['index'] = 0; + } else { + $cycle_vars[$name]['index']++; + } + } + + return $retval; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.debug.php b/gulliver/thirdparty/smarty/libs/plugins/function.debug.php new file mode 100644 index 000000000..43452307b --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.debug.php @@ -0,0 +1,35 @@ + + * Name: debug
    + * Date: July 1, 2002
    + * Purpose: popup debug window + * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} + * (Smarty online manual) + * @author Monte Ohrt + * @version 1.0 + * @param array + * @param Smarty + * @return string output from {@link Smarty::_generate_debug_output()} + */ +function smarty_function_debug($params, &$smarty) +{ + if (isset($params['output'])) { + $smarty->assign('_smarty_debug_output', $params['output']); + } + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + return smarty_core_display_debug_console(null, $smarty); +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.eval.php b/gulliver/thirdparty/smarty/libs/plugins/function.eval.php new file mode 100644 index 000000000..ff0472de2 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.eval.php @@ -0,0 +1,49 @@ + + * Name: eval
    + * Purpose: evaluate a template variable as a template
    + * @link http://smarty.php.net/manual/en/language.function.eval.php {eval} + * (Smarty online manual) + * @author Monte Ohrt + * @param array + * @param Smarty + */ +function smarty_function_eval($params, &$smarty) +{ + + if (!isset($params['var'])) { + $smarty->trigger_error("eval: missing 'var' parameter"); + return; + } + + if($params['var'] == '') { + return; + } + + $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled); + + ob_start(); + $smarty->_eval('?>' . $_var_compiled); + $_contents = ob_get_contents(); + ob_end_clean(); + + if (!empty($params['assign'])) { + $smarty->assign($params['assign'], $_contents); + } else { + return $_contents; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.fetch.php b/gulliver/thirdparty/smarty/libs/plugins/function.fetch.php new file mode 100644 index 000000000..81b1bfc6b --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.fetch.php @@ -0,0 +1,221 @@ + + * Name: fetch
    + * Purpose: fetch file, web or ftp data and display results + * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) + * @author Monte Ohrt + * @param array + * @param Smarty + * @return string|null if the assign parameter is passed, Smarty assigns the + * result to a template variable + */ +function smarty_function_fetch($params, &$smarty) +{ + if (empty($params['file'])) { + $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty"); + return; + } + + $content = ''; + if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) { + $_params = array('resource_type' => 'file', 'resource_name' => $params['file']); + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if(!smarty_core_is_secure($_params, $smarty)) { + $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed'); + return; + } + + // fetch the file + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\''); + return; + } + } else { + // not a local file + if(preg_match('!^http://!i',$params['file'])) { + // http fetch + if($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine ".$smarty->_version; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if(empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if(!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if(!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach($params as $param_key => $param_value) { + switch($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if(!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if(!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if(!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if(!empty($param_value)) { + if(!preg_match('![\w\d-]+: .+!',$param_value)) { + $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'"); + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case "proxy_host": + if(!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if(!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + case "agent": + if(!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if(!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if(!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + default: + $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); + return; + } + } + if(!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + } else { + $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } + + if(!$fp) { + $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)"); + return; + } else { + if($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if(!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if(!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if(!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if(!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if(isset($extra_headers) && is_array($extra_headers)) { + foreach($extra_headers as $curr_header) { + fputs($fp, $curr_header."\r\n"); + } + } + if(!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + } + + fputs($fp, "\r\n"); + while(!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = split("\r\n\r\n",$content,2); + + $content = $csplit[1]; + + if(!empty($params['assign_headers'])) { + $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); + } + } + } else { + $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax"); + return; + } + } else { + // ftp fetch + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\''); + return; + } + } + + } + + + if (!empty($params['assign'])) { + $smarty->assign($params['assign'],$content); + } else { + return $content; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.html_checkboxes.php b/gulliver/thirdparty/smarty/libs/plugins/function.html_checkboxes.php new file mode 100644 index 000000000..ed8ad7f33 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.html_checkboxes.php @@ -0,0 +1,143 @@ + + * Type: function
    + * Name: html_checkboxes
    + * Date: 24.Feb.2003
    + * Purpose: Prints out a list of checkbox input types
    + * Input:
    + * - name (optional) - string default "checkbox" + * - values (required) - array + * - options (optional) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie
    or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * Examples: + *
    + * {html_checkboxes values=$ids output=$names}
    + * {html_checkboxes values=$ids name='box' separator='
    ' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
    ' output=$names} + *
    + * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_checkboxes($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $name = 'checkbox'; + $values = null; + $options = null; + $selected = null; + $separator = ''; + $labels = true; + $output = null; + + $extra = ''; + + foreach($params as $_key => $_val) { + switch($_key) { + case 'name': + case 'separator': + $$_key = $_val; + break; + + case 'labels': + $$_key = (bool)$_val; + break; + + case 'options': + $$_key = (array)$_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array)$_val); + break; + + case 'checked': + case 'selected': + $selected = array_map('strval', array_values((array)$_val)); + break; + + case 'checkboxes': + $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array)$_val; + break; + + case 'assign': + break; + + default: + if(!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (!isset($options) && !isset($values)) + return ''; /* raise error here? */ + + settype($selected, 'array'); + $_html_result = array(); + + if (isset($options)) { + + foreach ($options as $_key=>$_val) + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); + + + } else { + foreach ($values as $_i=>$_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); + } + + } + + if(!empty($params['assign'])) { + $smarty->assign($params['assign'], $_html_result); + } else { + return implode("\n",$_html_result); + } + +} + +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) { + $_output = ''; + if ($labels) $_output .= ''; + $_output .= $separator; + + return $_output; +} + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.html_image.php b/gulliver/thirdparty/smarty/libs/plugins/function.html_image.php new file mode 100644 index 000000000..9abae72ef --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.html_image.php @@ -0,0 +1,142 @@ + + * Name: html_image
    + * Date: Feb 24, 2003
    + * Purpose: format HTML tags for the image
    + * Input:
    + * - file = file (and path) of image (required) + * - height = image height (optional, default actual height) + * - width = image width (optional, default actual width) + * - basedir = base directory for absolute paths, default + * is environment variable DOCUMENT_ROOT + * - path_prefix = prefix for path output (optional, default empty) + * + * Examples: {html_image file="/images/masthead.gif"} + * Output: + * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} + * (Smarty online manual) + * @author Monte Ohrt + * @author credits to Duda - wrote first image function + * in repository, helped with lots of functionality + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_image($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $alt = ''; + $file = ''; + $height = ''; + $width = ''; + $extra = ''; + $prefix = ''; + $suffix = ''; + $path_prefix = ''; + $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; + foreach($params as $_key => $_val) { + switch($_key) { + case 'file': + case 'height': + case 'width': + case 'dpi': + case 'path_prefix': + case 'basedir': + $$_key = $_val; + break; + + case 'alt': + if(!is_array($_val)) { + $$_key = smarty_function_escape_special_chars($_val); + } else { + $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + + case 'link': + case 'href': + $prefix = ''; + $suffix = ''; + break; + + default: + if(!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (empty($file)) { + $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE); + return; + } + + if (substr($file,0,1) == '/') { + $_image_path = $basedir . $file; + } else { + $_image_path = $file; + } + + if(!isset($params['width']) || !isset($params['height'])) { + if(!$_image_data = @getimagesize($_image_path)) { + if(!file_exists($_image_path)) { + $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); + return; + } else if(!is_readable($_image_path)) { + $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE); + return; + } else { + $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE); + return; + } + } + if ($smarty->security && + ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && + (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && + (!smarty_core_is_secure($_params, $smarty)) ) { + $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); + } + + if(!isset($params['width'])) { + $width = $_image_data[0]; + } + if(!isset($params['height'])) { + $height = $_image_data[1]; + } + + } + + if(isset($params['dpi'])) { + if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) { + $dpi_default = 72; + } else { + $dpi_default = 96; + } + $_resize = $dpi_default/$params['dpi']; + $width = round($width * $_resize); + $height = round($height * $_resize); + } + + return $prefix . ''.$alt.'' . $suffix; +} + +/* vim: set expandtab: */ + +?> diff --git a/gulliver/thirdparty/smarty/libs/plugins/function.html_options.php b/gulliver/thirdparty/smarty/libs/plugins/function.html_options.php new file mode 100644 index 000000000..cebadde47 --- /dev/null +++ b/gulliver/thirdparty/smarty/libs/plugins/function.html_options.php @@ -0,0 +1,122 @@ + + * Name: html_options
    + * Input:
    + * - name (optional) - string default "select" + * - values (required if no options supplied) - array + * - options (required if no values supplied) - associative array + * - selected (optional) - string default not set + * - output (required if not options supplied) - array + * Purpose: Prints the list of
    "; + + closedir($handle); + + echo "\n"; + + exit; + } + + /** + * GET method handler for directories + * + * This is a very simple mod_index lookalike. + * See RFC 2518, Section 8.4 on GET/HEAD for collections + * + * @param string directory path + * @return void function has to handle HTTP response itself + */ + function GetDir($fspath, &$options) + { + $path = $this->_slashify($options["path"]); + if ($path != $options["path"]) { + header("Location: ".$this->base_uri.$path); + exit; + } + + // fixed width directory column format + $format = "%15s %-19s %-s\n"; + + $handle = @opendir($fspath); + if (!$handle) { + return false; + } + + echo "Index of ".htmlspecialchars($options['path'])."\n"; + + echo "

    Index of ".htmlspecialchars($options['path'])."

    \n"; + + echo "
    ";
    +    printf($format, "Size", "Last modified", "Filename");
    +    echo "
    "; + + while ($filename = readdir($handle)) { + if ($filename != "." && $filename != "..") { + $fullpath = $fspath."/".$filename; + $name = htmlspecialchars($filename); + printf($format, + number_format(filesize($fullpath)), + strftime("%Y-%m-%d %H:%M:%S", filemtime($fullpath)), + "$name"); + } + } + + echo "
    "; + + closedir($handle); + + echo "\n"; + + exit; + } + + /** + * PUT method handler + * + * @param array parameter passing array + * @return bool true on success + */ + function PUT(&$options) + { + $paths = $this->paths; + + $pathClasses = PATH_DB . PATH_SEP . 'classes' . PATH_SEP; + if ( count($paths) > 0 && $paths[0] == 'classes' && is_dir( $pathClasses ) ) { + $fsFile = $pathClasses. $paths[1]; + if ( count($paths) == 2 && file_exists( $fsFile ) ) { + $fp = fopen($fsFile, "w"); + if ( is_resource($fp) && is_resource($options["stream"])) { + while( !feof($options["stream"])) { + fwrite($fp, fread($options["stream"], 4096)); + } + fclose($fp); + fclose($options["stream"]); + } + return "201 Created " . $fsFile; + } + } + + $pathProcesses = PATH_DB . SYS_SYS . PATH_SEP ; + if ( count($paths) > 0 && $paths[0] == 'processes' && is_dir( $pathProcesses ) ) { + if ( $paths[2] == 'xmlforms' ) { + $pathTemplates = $pathProcesses . 'xmlForms' . PATH_SEP . $paths[1] . PATH_SEP; + $fsFile = $pathTemplates. $paths[3]; + if ( count($paths) == 4 && file_exists( $fsFile ) ) { + $fp = fopen($fsFile, "w"); + if ( is_resource($fp) && is_resource($options["stream"])) { + while( !feof($options["stream"])) { + fwrite($fp, fread($options["stream"], 4096)); + } + fclose($fp); + fclose($options["stream"]); + } + return "201 Created " . $fsFile; + } + } + + if ( $paths[2] == 'mailTemplates' ) { + $pathTemplates = $pathProcesses . 'mailTemplates' . PATH_SEP . $paths[1] . PATH_SEP; + $fsFile = $pathTemplates. $paths[3]; + if ( count($paths) == 4 && file_exists( $fsFile ) ) { + $fp = fopen($fsFile, "w"); + if ( is_resource($fp) && is_resource($options["stream"])) { + while( !feof($options["stream"])) { + fwrite($fp, fread($options["stream"], 4096)); + } + fclose($fp); + fclose($options["stream"]); + } + return "201 Created " . $fsFile; + } + } + + + if ( $paths[2] == 'public_html' ) { + $pathPublic = $pathProcesses . 'public' . PATH_SEP . $paths[1] . PATH_SEP; + $fsFile = $pathPublic. $paths[3]; + if ( count($paths) == 4 && file_exists( $fsFile ) ) { + $fp = fopen($fsFile, "w"); + if ( is_resource($fp) && is_resource($options["stream"])) { + while( !feof($options["stream"])) { + fwrite($fp, fread($options["stream"], 4096)); + } + fclose($fp); + fclose($options["stream"]); + } + return "201 Created " . $fsFile; + } + } + + } + + return "409 Conflict"; + + } + + /** + * MKCOL method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function MKCOL($options) + { + $path = $this->base .$options["path"]; + $parent = dirname($path); + $name = basename($path); + + if (!file_exists($parent)) { + return "409 Conflict"; + } + + if (!is_dir($parent)) { + return "403 Forbidden"; + } + + if ( file_exists($parent."/".$name) ) { + return "405 Method not allowed"; + } + + if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet + return "415 Unsupported media type"; + } + + $stat = mkdir ($parent."/".$name,0777); + if (!$stat) { + return "403 Forbidden"; + } + + return ("201 Created"); + } + + + /** + * DELETE method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function DELETE($options) + { + $path = $this->base . "/" .$options["path"]; + + if (!file_exists($path)) { + return "404 Not found"; + } + + if (is_dir($path)) { + $query = "DELETE FROM properties WHERE path LIKE '".$this->_slashify($options["path"])."%'"; + mysql_query($query); + System::rm("-rf $path"); + } else { + unlink ($path); + } + $query = "DELETE FROM properties WHERE path = '$options[path]'"; + mysql_query($query); + + return "204 No Content"; + } + + + /** + * MOVE method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function MOVE($options) + { + return "423 Locked"; + //return $this->COPY($options, true); + } + + /** + * COPY method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function COPY($options, $del=false) + { + // TODO Property updates still broken (Litmus should detect this?) + + if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet + return "415 Unsupported media type"; + } + + // no copying to different WebDAV Servers yet + if (isset($options["dest_url"])) { + return "502 bad gateway"; + } + + $source = $this->base .$options["path"]; + if (!file_exists($source)) return "404 Not found"; + + $dest = $this->base . $options["dest"]; + + $new = !file_exists($dest); + $existing_col = false; + + if (!$new) { + if ($del && is_dir($dest)) { + if (!$options["overwrite"]) { + return "412 precondition failed"; + } + $dest .= basename($source); + if (file_exists($dest)) { + $options["dest"] .= basename($source); + } else { + $new = true; + $existing_col = true; + } + } + } + + if (!$new) { + if ($options["overwrite"]) { + $stat = $this->DELETE(array("path" => $options["dest"])); + if (($stat{0} != "2") && (substr($stat, 0, 3) != "404")) { + return $stat; + } + } else { + return "412 precondition failed"; + } + } + + if (is_dir($source) && ($options["depth"] != "infinity")) { + // RFC 2518 Section 9.2, last paragraph + return "400 Bad request"; + } + + if ($del) { + if (!rename($source, $dest)) { + return "500 Internal server error"; + } + $destpath = $this->_unslashify($options["dest"]); + if (is_dir($source)) { + $query = "UPDATE properties + SET path = REPLACE(path, '".$options["path"]."', '".$destpath."') + WHERE path LIKE '".$this->_slashify($options["path"])."%'"; + mysql_query($query); + } + + $query = "UPDATE properties + SET path = '".$destpath."' + WHERE path = '".$options["path"]."'"; + mysql_query($query); + } else { + if (is_dir($source)) { + $files = System::find($source); + $files = array_reverse($files); + } else { + $files = array($source); + } + + if (!is_array($files) || empty($files)) { + return "500 Internal server error"; + } + + foreach ($files as $file) { + if (is_dir($file)) { + $file = $this->_slashify($file); + } + + $destfile = str_replace($source, $dest, $file); + + if (is_dir($file)) { + if (!is_dir($destfile)) { + // TODO "mkdir -p" here? (only natively supported by PHP 5) + if (!mkdir($destfile)) { + return "409 Conflict"; + } + } else { + error_log("existing dir '$destfile'"); + } + } else { + if (!copy($file, $destfile)) { + return "409 Conflict"; + } + } + } + + $query = "INSERT INTO properties SELECT ... FROM properties WHERE path = '".$options['path']."'"; + } + + return ($new && !$existing_col) ? "201 Created" : "204 No Content"; + } + + /** + * PROPPATCH method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function PROPPATCH(&$options) + { + global $prefs, $tab; + + $msg = ""; + + $path = $options["path"]; + + $dir = dirname($path)."/"; + $base = basename($path); + + foreach($options["props"] as $key => $prop) { + if ($prop["ns"] == "DAV:") { + $options["props"][$key]['status'] = "403 Forbidden"; + } else { + if (isset($prop["val"])) { + $query = "REPLACE INTO properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'"; + error_log($query); + } else { + $query = "DELETE FROM properties WHERE path = '$options[path]' AND name = '$prop[name]' AND ns = '$prop[ns]'"; + } + mysql_query($query); + } + } + return ""; + } + + + /** + * LOCK method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function LOCK(&$options) + { + if (isset($options["update"])) { // Lock Update + $query = "UPDATE locks SET expires = ".(time()+300); + mysql_query($query); + + if (mysql_affected_rows()) { + $options["timeout"] = 300; // 5min hardcoded + return true; + } else { + return false; + } + } + + $options["timeout"] = time()+300; // 5min. hardcoded + + $query = "INSERT INTO locks + SET token = '$options[locktoken]' + , path = '$options[path]' + , owner = '$options[owner]' + , expires = '$options[timeout]' + , exclusivelock = " .($options['scope'] === "exclusive" ? "1" : "0") ; + mysql_query($query); + + return mysql_affected_rows() ? "200 OK" : "409 Conflict"; + } + + /** + * UNLOCK method handler + * + * @param array general parameter passing array + * @return bool true on success + */ + function UNLOCK(&$options) + { + $query = "DELETE FROM locks + WHERE path = '$options[path]' + AND token = '$options[token]'"; + mysql_query($query); + + return mysql_affected_rows() ? "204 No Content" : "409 Conflict"; + } + + /** + * checkLock() helper + * + * @param string resource path to check for locks + * @return bool true on success + */ + function checkLock($path) + { + $result = false; + + $query = "SELECT owner, token, expires, exclusivelock + FROM locks + WHERE path = '$path' "; + $res = mysql_query($query); + + if ($res) { + $row = mysql_fetch_array($res); + mysql_free_result($res); + + if ($row) { + $result = array( "type" => "write", + "scope" => $row["exclusivelock"] ? "exclusive" : "shared", + "depth" => 0, + "owner" => $row['owner'], + "token" => $row['token'], + "expires" => $row['expires'] + ); + } + } + + return $result; + } + + + /** + * create database tables for property and lock storage + * + * @param void + * @return bool true on success + */ + function create_database() + { + // TODO + return false; + } + +} + +?> diff --git a/workflow/engine/classes/class.wsBase.php b/workflow/engine/classes/class.wsBase.php new file mode 100644 index 000000000..f549326cd --- /dev/null +++ b/workflow/engine/classes/class.wsBase.php @@ -0,0 +1,2029 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + */ + + + // * It works with the table CONFIGURATION in a WF dataBase + require_once ( "classes/model/Application.php" ); + require_once ( "classes/model/AppDelegation.php" ); + require_once ( "classes/model/AppDocument.php" ); + require_once ( "classes/model/AppDelay.php"); + require_once ( "classes/model/AppThread.php" ); + require_once ( "classes/model/Department.php" ); + require_once ( "classes/model/Dynaform.php" ); + require_once ( "classes/model/Groupwf.php" ); + require_once ( "classes/model/InputDocument.php" ); + require_once ( "classes/model/Language.php" ); + require_once ( "classes/model/OutputDocument.php" ); + require_once ( "classes/model/Process.php" ); + require_once ( "classes/model/ReportTable.php"); + require_once ( "classes/model/ReportVar.php"); + require_once ( "classes/model/Route.php"); + require_once ( "classes/model/Step.php" ); + require_once ( "classes/model/StepTrigger.php" ); + require_once ( "classes/model/Task.php" ); + require_once ( "classes/model/TaskUser.php" ); + require_once ( "classes/model/Triggers.php" ); + require_once ( "classes/model/Users.php" ); + require_once ( "classes/model/Session.php" ); + require_once ( "classes/model/Content.php" ); + G::LoadClass( "ArrayPeer" ); + G::LoadClass( "BasePeer" ); + G::LoadClass( 'case'); + G::LoadClass( 'derivation'); + G::LoadClass( 'groups'); + G::LoadClass( 'sessions'); + G::LoadClass( 'processes'); + G::LoadClass( 'processMap' ); + G::LoadClass( 'pmScript'); + G::LoadClass( 'spool'); + G::LoadClass( 'tasks'); + G::LoadClass( 'wsResponse'); + + /** + * Copyright (C) 2009 COLOSA + * License: LGPL, see LICENSE + * @Last Modify: 26.06.2008 10:05:00 + * @Last modify by: Erik Amaru Ortiz + * @Last Modify comment(26.06.2008): the session expired verification was removed from here to soap class + */ + +class wsBase +{ + + public $stored_system_variables; //boolean + public $wsSessionId; // web service session id, if the wsbase function is used from a WS request + + function __construct($params=NULL) { + $this->stored_system_variables = FALSE; + + if( $params != NULL ){ + $this->stored_system_variables = isset($params->stored_system_variables)? $params->stored_system_variables: FALSE; + $this->wsSessionId = isset($params->wsSessionId)? $params->wsSessionId: ''; + } + } + + /* + * function to start a web services session in ProcessMaker + * @param string $userid + * @param string $password + * @return $wsResponse will return an object + */ + public function login( $userid, $password ) { + global $RBAC; + + try { + $uid = $RBAC->VerifyLogin( $userid , $password); + switch ($uid) { + case -1: //The user not exists + $wsResponse = new wsResponse (3, G::loadTranslation ('ID_USER_NOT_REGISTERED')); + break; + + case -2://The password is incorrect + $wsResponse = new wsResponse (4, G::loadTranslation ('ID_WRONG_PASS')); + break; + + case -3: //The user is inactive + $wsResponse = new wsResponse (5, G::loadTranslation ('ID_USER_INACTIVE')); + + case -4: //The Due date is finished + $wsResponse = new wsResponse (5, G::loadTranslation ('ID_USER_INACTIVE')); + break; + } + if ($uid < 0 ) { + throw ( new Exception ( serialize ( $wsResponse ) )); + } + // check access to PM + $RBAC->loadUserRolePermission( $RBAC->sSystem, $uid ); + $res = $RBAC->userCanAccess("PM_LOGIN"); + + if ($res != 1 ) { + //if ($res == -2) + // $wsResponse = new wsResponse (1, G::loadTranslation ('ID_USER_HAVENT_RIGHTS_SYSTEM')); + //else + $wsResponse = new wsResponse (2, G::loadTranslation ('ID_USER_HAVENT_RIGHTS_SYSTEM')); + throw ( new Exception ( serialize ( $wsResponse ) )); + } + + $sessionId = G::generateUniqueID(); + $wsResponse = new wsResponse ('0', $sessionId ); + + $session = new Session (); + $session->setSesUid ( $sessionId ); + $session->setSesStatus ( 'ACTIVE'); + $session->setUsrUid ( $uid ); + $session->setSesRemoteIp ( $_SERVER['REMOTE_ADDR'] ); + $session->setSesInitDate ( date ('Y-m-d H:i:s') ); + $session->setSesDueDate ( date ('Y-m-d H:i:s', mktime(date('H'),date('i')+15, date('s'), date('m'),date('d'),date('Y') ) ) ); + $session->setSesEndDate ( '' ); + $session->Save(); + + //save the session in DataBase + return $wsResponse; + } + catch ( Exception $e ) { + $wsResponse = unserialize ( $e->getMessage() ); + return $wsResponse; + } + } + + /* + * get all groups + * @param none + * @return $result will return an object + */ + public function processList() { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + //$oCriteria->add(ProcessPeer::PRO_STATUS , 'ACTIVE' ); + $oCriteria->add(ProcessPeer::PRO_STATUS, 'DISABLED', Criteria::NOT_EQUAL); + $oDataset = ProcessPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + $oProcess = new Process(); + $arrayProcess = $oProcess->Load( $aRow['PRO_UID'] ); + $result[] = array ( 'guid' => $aRow['PRO_UID'], 'name' => $arrayProcess['PRO_TITLE'] ); + $oDataset->next(); + } + + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + /* + * get all roles, to see all roles + * @param none + * @return $result will return an object + */ + public function roleList( ) { + try { + $result = array(); + + $RBAC =& RBAC::getSingleton(); + $RBAC->initRBAC(); + $oCriteria = $RBAC->listAllRoles (); + $oDataset = GulliverBasePeer::doSelectRs ( $oCriteria);; + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + $result[] = array ( 'guid' => $aRow['ROL_UID'], 'name' => $aRow['ROL_CODE'] ); + $oDataset->next(); + } + + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + /* + * get all groups + * @param none + * @return $result will return an object + */ + public function groupList() { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(GroupwfPeer::GRP_STATUS , 'ACTIVE' ); + $oDataset = GroupwfPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + $oGroupwf = new Groupwf(); + $arrayGroupwf = $oGroupwf->Load( $aRow['GRP_UID'] ); + $result[] = array ( 'guid' => $aRow['GRP_UID'], 'name' => $arrayGroupwf['GRP_TITLE'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + /* + * get all department + * @param none + * @return $result will return an object + */ + public function departmentList() { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(DepartmentPeer::DEP_STATUS , 'ACTIVE' ); + $oDataset = DepartmentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + $oDepartment = new Department(); + $aDepartment = $oDepartment->Load( $aRow['DEP_UID'] ); + $node['guid'] = $aRow['DEP_UID']; + $node['name'] = $aDepartment['DEPO_TITLE']; + $node['parentUID'] = $aDepartment['DEP_PARENT']; + $node['dn'] = $aDepartment['DEP_LDAP_DN']; + + //get the users from this department + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn('COUNT(*)'); + $c->add(UsersPeer::DEP_UID, $aRow['DEP_UID'] ); + $rs = UsersPeer::doSelectRS($c); + $rs->next(); + $row = $rs->getRow(); + $count = $row[0]; + + $node['users'] = $count; + $result[] = $node; + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + /* + * Get case list + * @param string $userId + * @return $result will return an object + */ + public function caseList( $userId ) { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + $oCriteria->addSelectColumn(ApplicationPeer::APP_UID); + $oCriteria->addSelectColumn(ApplicationPeer::APP_NUMBER); + $oCriteria->addSelectColumn(ApplicationPeer::APP_STATUS); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addAsColumn('CASE_TITLE', 'C1.CON_VALUE' ); + $oCriteria->addAlias("C1", 'CONTENT'); + $caseTitleConds = array(); + $caseTitleConds[] = array( ApplicationPeer::APP_UID , 'C1.CON_ID' ); + $caseTitleConds[] = array( 'C1.CON_CATEGORY' , $del . 'APP_TITLE' . $del ); + $caseTitleConds[] = array( 'C1.CON_LANG' , $del . SYS_LANG . $del ); + $oCriteria->addJoinMC($caseTitleConds , Criteria::LEFT_JOIN); + + $oCriteria->addJoin(ApplicationPeer::APP_UID, AppDelegationPeer::APP_UID, Criteria::LEFT_JOIN); + + $oCriteria->add(ApplicationPeer::APP_STATUS , array('TO_DO','DRAFT'), Criteria::IN); + $oCriteria->add(AppDelegationPeer::USR_UID, $userId ); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $oCriteria->addDescendingOrderByColumn(ApplicationPeer::APP_NUMBER); + $oDataset = ApplicationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + //$result[] = array ( 'guid' => $aRow['APP_UID'], 'name' => $aRow['CASE_TITLE'], 'status' => $aRow['APP_STATUS'], 'delIndex' => $aRow['DEL_INDEX'] ); + $result[] = array ( 'guid' => $aRow['APP_UID'], 'name' => $aRow['APP_NUMBER'], 'status' => $aRow['APP_STATUS'], 'delIndex' => $aRow['DEL_INDEX'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage(), 'status' => $e->getMessage() , 'status' => $e->getMessage() ); + return $result; + } + } + + + /* + * get all groups + * @param none + * @return $result will return an object + */ + public function userList( ) { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(UsersPeer::USR_STATUS , 'ACTIVE' ); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + + while ($aRow = $oDataset->getRow()) { + //$oProcess = new User(); + //$arrayProcess = $oUser->Load( $aRow['PRO_UID'] ); + $result[] = array ( 'guid' => $aRow['USR_UID'], 'name' => $aRow['USR_USERNAME'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + + /* + * get list of all the available triggers in a workspace + * @param none + * @return $result will return an object + */ + public function triggerList( ) { + try { + $del = DBAdapter::getStringDelimiter(); + + $result = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TriggersPeer::TRI_UID); + $oCriteria->addSelectColumn(TriggersPeer::PRO_UID); + $oCriteria->addAsColumn('TITLE', 'C1.CON_VALUE' ); + $oCriteria->addAlias("C1", 'CONTENT'); + + $caseTitleConds = array(); + $caseTitleConds[] = array( TriggersPeer::TRI_UID , 'C1.CON_ID' ); + $caseTitleConds[] = array( 'C1.CON_CATEGORY' , $del . 'TRI_TITLE' . $del ); + $caseTitleConds[] = array( 'C1.CON_LANG' , $del . SYS_LANG . $del ); + $oCriteria ->addJoinMC($caseTitleConds , Criteria::LEFT_JOIN); + //$oCriteria->add(TriggersPeer::USR_STATUS , 'ACTIVE' ); + $oDataset = TriggersPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + + while ($aRow = $oDataset->getRow()) { + $result[] = array ( 'guid' => $aRow['TRI_UID'], 'name' => $aRow['TITLE'], 'processId' => $aRow['PRO_UID'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + /* + * get list of the uploaded documents for a given case + * @param string $sApplicationUID + * @param string $sUserUID + * @return $result + */ + public function inputDocumentList( $sApplicationUID, $sUserUID ) { + try { + $oCase = new Cases(); + $fields = $oCase->loadCase($sApplicationUID); + $sProcessUID = $fields['PRO_UID']; + $sTaskUID = ''; + $oCriteria = $oCase->getAllUploadedDocumentsCriteria($sProcessUID, $sApplicationUID, $sTaskUID, $sUserUID); + + $result = array(); + global $_DBArray; + foreach ( $_DBArray['inputDocuments'] as $key => $row ) { + if ( isset($row['DOC_VERSION']) ) { + $docrow = array(); + $docrow['guid'] = $row['APP_DOC_UID']; + $docrow['filename'] = $row['APP_DOC_FILENAME']; + $docrow['docId'] = $row['DOC_UID']; + $docrow['version'] = $row['DOC_VERSION']; + $docrow['createDate'] = $row['CREATE_DATE']; + $docrow['createBy'] = $row['CREATED_BY']; + $docrow['type'] = $row['TYPE']; + $docrow['index'] = $row['APP_DOC_INDEX']; + $docrow['link'] = 'cases/' . $row['DOWNLOAD_LINK']; + $result[] = $docrow; + } + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage() ); + return $result; + } + } + + /* + * input document process list + * @param string $sProcessUID + * @return $result will return an object + */ + public function inputDocumentProcessList( $sProcessUID ) { + try { + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + + $oMap = new processMap(); + $oCriteria = $oMap->getInputDocumentsCriteria($sProcessUID); + $oDataset = InputDocumentPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + + $result = array(); + //$result[] = array('guid'=>'char','name'=>'name','description'=>'description'); //not necesary for SOAP message + while ( $aRow = $oDataset->getRow() ) { + if ( $aRow['INP_DOC_TITLE'] == NULL){// There is no transaltion for this Document name, try to get/regenerate the label + $inputDocument = new InputDocument(); + $inputDocumentObj = $inputDocument->load($aRow['INP_DOC_UID']); + $aRow['INP_DOC_TITLE'] = $inputDocumentObj['INP_DOC_TITLE']; + $aRow['INP_DOC_DESCRIPTION'] = $inputDocumentObj['INP_DOC_DESCRIPTION']; + } + $docrow = array(); + $docrow['guid'] = $aRow['INP_DOC_UID']; + $docrow['name'] = $aRow['INP_DOC_TITLE']; + $docrow['description'] = $aRow['INP_DOC_DESCRIPTION']; + $result[] = $docrow; + $oDataset->next (); + } + + //$_DBArray['inputDocArray'] = $inputDocArray; + + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage() ); + return $result; + } + } + + + /* + * output document list + * @param string $sApplicationUID + * @param string $sUserUID + * @return $result will return an object + */ + public function outputDocumentList( $sApplicationUID, $sUserUID ) { + try { + $oCase = new Cases(); + $fields = $oCase->loadCase($sApplicationUID); + $sProcessUID = $fields['PRO_UID']; + $sTaskUID = ''; + $oCriteria = $oCase->getAllGeneratedDocumentsCriteria($sProcessUID, $sApplicationUID, $sTaskUID, $sUserUID); + + $result = array(); + global $_DBArray; + foreach ( $_DBArray['outputDocuments'] as $key => $row ) { + if ( isset($row['DOC_VERSION']) ) { + $docrow = array(); + $docrow['guid'] = $row['APP_DOC_UID']; + $docrow['filename'] = $row['DOWNLOAD_FILE']; + + $docrow['docId'] = $row['DOC_UID']; + $docrow['version'] = $row['DOC_VERSION']; + $docrow['createDate'] = $row['CREATE_DATE']; + $docrow['createBy'] = $row['CREATED_BY']; + $docrow['type'] = $row['TYPE']; + $docrow['index'] = $row['APP_DOC_INDEX']; + $docrow['link'] = 'cases/' . $row['DOWNLOAD_LINK']; + $result[] = $docrow; + } + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage() ); + return $result; + } + } + + /* + * remove document + * @param string $appDocUid + * @return $result will return an object + */ + public function removeDocument($appDocUid) { + try { + $oAppDocument = new AppDocument(); + $oAppDocument->remove( $appDocUid, 1 ); //always send version 1 + $result = new wsResponse (0, " $appDocUid"); + + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + + /* + * get task list + * @param string $userId + * @return $result will return an object + */ + public function taskList( $userId ) { + try { + g::loadClass('groups'); + $oGroup = new Groups(); + $aGroups = $oGroup->getActiveGroupsForAnUser($userId); + + $result = array(); + $oCriteria = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + $oCriteria->addSelectColumn(TaskPeer::TAS_UID); + $oCriteria->setDistinct(); + $oCriteria->addAsColumn('TAS_TITLE', 'C1.CON_VALUE' ); + $oCriteria->addAlias("C1", 'CONTENT'); + $tasTitleConds = array(); + $tasTitleConds[] = array( TaskPeer::TAS_UID , 'C1.CON_ID' ); + $tasTitleConds[] = array( 'C1.CON_CATEGORY' , $del . 'TAS_TITLE' . $del ); + $tasTitleConds[] = array( 'C1.CON_LANG' , $del . SYS_LANG . $del ); + $oCriteria->addJoinMC($tasTitleConds , Criteria::LEFT_JOIN); + + $oCriteria->addJoin ( TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN ); + $oCriteria->addOr ( TaskUserPeer::USR_UID, $userId ); + $oCriteria->addOr ( TaskUserPeer::USR_UID, $aGroups, Criteria::IN ); + + $oDataset = TaskPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aRow = $oDataset->getRow()) { + $result[] = array ( 'guid' => $aRow['TAS_UID'], 'name' => $aRow['TAS_TITLE'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + /* + * send message + * @param string $caseId + * @param string $sFrom + * @param string $sTo + * @param string $sCc + * @param string $sBcc + * @param string $sSubject + * @param string $sTemplate + * @param $appFields = null + * @return $result will return an object + */ + public function sendMessage($caseId, $sFrom, $sTo, $sCc, $sBcc, $sSubject, $sTemplate, $appFields = null ) { + try { + $aSetup = getEmailConfiguration(); + + $oSpool = new spoolRun(); + $oSpool->setConfig(array( + 'MESS_ENGINE' => $aSetup['MESS_ENGINE'], + 'MESS_SERVER' => $aSetup['MESS_SERVER'], + 'MESS_PORT' => $aSetup['MESS_PORT'], + 'MESS_ACCOUNT' => $aSetup['MESS_ACCOUNT'], + 'MESS_PASSWORD' => $aSetup['MESS_PASSWORD'], + 'SMTPAuth' => $aSetup['MESS_RAUTH'] + )); + + + $oCase = new Cases(); + $oldFields = $oCase->loadCase( $caseId ); + + $pathEmail = PATH_DATA_SITE . 'mailTemplates' . PATH_SEP . $oldFields['PRO_UID'] . PATH_SEP; + $fileTemplate = $pathEmail . $sTemplate; + G::mk_dir( $pathEmail, 0777,true); + + if ( ! file_exists ( $fileTemplate ) ) { + $result = new wsResponse (28, "Template file '$fileTemplate' does not exist." ); + return $result; + } + + if ( $appFields == null ) { + $Fields = $oldFields['APP_DATA']; + } else { + $Fields = $appFields; + } + $templateContents = file_get_contents ( $fileTemplate ); + + //$sContent = G::unhtmlentities($sContent); + $iAux = 0; + $iOcurrences = preg_match_all('/\@(?:([\>])([a-zA-Z\_]\w*)|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+)?/', $templateContents, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + + if ($iOcurrences) { + for($i = 0; $i < $iOcurrences; $i++) { + preg_match_all('/@>' . $aMatch[2][$i][0] . '([\w\W]*)' . '@<' . $aMatch[2][$i][0] . '/', $templateContents, $aMatch2, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $sGridName = $aMatch[2][$i][0]; + $sStringToRepeat = $aMatch2[1][0][0]; + if (isset($Fields[$sGridName])) { + if (is_array($Fields[$sGridName])) { + $sAux = ''; + foreach ($Fields[$sGridName] as $aRow) { + $sAux .= G::replaceDataField($sStringToRepeat, $aRow); + } + } + } + $templateContents = str_replace('@>' . $sGridName . $sStringToRepeat . '@<' . $sGridName, $sAux, $templateContents); + } + } + + $sBody = G::replaceDataField( $templateContents, $Fields); + + if ($sFrom != '') { + $sFrom = $sFrom . ' <' . $aSetup['MESS_ACCOUNT'] . '>'; + } + else { + $sFrom = $aSetup['MESS_ACCOUNT']; + } + + $messageArray = array( + 'msg_uid' => '', + 'app_uid' => $caseId, + 'del_index' => 0, + 'app_msg_type' => 'TRIGGER', + 'app_msg_subject' => $sSubject, + 'app_msg_from' => $sFrom, + 'app_msg_to' => $sTo, + 'app_msg_body' => $sBody, + 'app_msg_cc' => $sCc, + 'app_msg_bcc' => $sBcc, + 'app_msg_attach' => '', + 'app_msg_template' => '', + 'app_msg_status' => 'pending' + ); + + $oSpool->create( $messageArray ); + $oSpool->sendMail(); + + if ( $oSpool->status == 'sent' ) + $result = new wsResponse (0, "message sent : $sTo" ); + else + $result = new wsResponse (29, $oSpool->status . ' ' . $oSpool->error . print_r ($aSetup ,1 ) ); + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + + /* + * get case information + * @param string $caseId + * @param string $iDelIndex + * @return $result will return an object + */ + public function getCaseInfo($caseId, $iDelIndex ) { + try { + $oCase = new Cases(); + $aRows = $oCase->loadCase( $caseId, $iDelIndex ); + if ( count($aRows) == 0 ) { + $result = new wsResponse (16, "Case $caseNumber does not exist" ); + return $result; + } + + $oProcess = new Process(); + try { + $uFields = $oProcess->load($aRows['PRO_UID']); + $processName = $uFields['PRO_TITLE']; + } + catch ( Exception $e ) { + $processName = ''; + } + $result = new wsResponse (0, "Command executed successfully" ); + $result->caseId = $aRows['APP_UID']; + $result->caseNumber = $aRows['APP_NUMBER']; + $result->caseName = $aRows['TITLE']; + $result->caseStatus = $aRows['APP_STATUS']; + $result->caseParalell = $aRows['APP_PARALLEL']; + $result->caseCreatorUser = $aRows['APP_INIT_USER']; + $result->caseCreatorUserName = $aRows['CREATOR']; + $result->processId = $aRows['PRO_UID']; + $result->processName = $processName; + $result->createDate = $aRows['CREATE_DATE']; + + //now fill the array of AppDelegationPeer + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppDelegationPeer::USR_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::TAS_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_THREAD); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_THREAD_STATUS); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $oCriteria->add(AppDelegationPeer::APP_UID, $caseId); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL ); + + $oCriteria->addAscendingOrderByColumn(AppDelegationPeer::DEL_INDEX); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aCurrentUsers = array(); + while($oDataset->next()) { + $aAppDel = $oDataset->getRow(); + + $oUser = new Users(); + try { + $oUser->load($aAppDel['USR_UID']); + $uFields = $oUser->toArray(BasePeer::TYPE_FIELDNAME); + $currentUserName = $oUser->getUsrFirstname() . ' ' . $oUser->getUsrLastname(); + } + catch ( Exception $e ) { + $currentUserName = ''; + } + + $oTask = new Task(); + try { + $uFields = $oTask->load($aAppDel['TAS_UID']); + $taskName = $uFields['TAS_TITLE']; + } + catch ( Exception $e ) { + $taskName = ''; + } + + $currentUser = new stdClass(); + $currentUser->userId = $aAppDel['USR_UID']; + $currentUser->userName = $currentUserName; + $currentUser->taskId = $aAppDel['TAS_UID']; + $currentUser->taskName = $taskName; + $currentUser->delIndex = $aAppDel['DEL_INDEX']; + $currentUser->delThread = $aAppDel['DEL_THREAD']; + $currentUser->delThreadStatus = $aAppDel['DEL_THREAD_STATUS']; + $aCurrentUsers[] = $currentUser; + } + + $result->currentUsers = $aCurrentUsers; + + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * creates a new user + * @param string sessionId : The session ID + * @param string userId : The username for the new user. + * @param string firstname : The user's first name. + * @param string lastname : The user's last name. + * @param string email : The user's email address. + * @param string role : The user's role, such as 'PROCESSMAKER_ADMIN' or 'PROCESSMAKER_OPERATOR'. + * @param string password : The user's password such as 'Be@gle2'(It will be automatically encrypted with an MD5 hash). + * @return $result will return an object + */ + public function createUser( $userId, $firstname, $lastname, $email, $role, $password) { + try { + if($userId=='') + { $result = new wsCreateUserResponse (25, "Username is required"); + return $result; + } + + if($password=='') + { $result = new wsCreateUserResponse (26, "Password is required"); + return $result; + } + + if($firstname=='') + { $result = new wsCreateUserResponse (27, "First Name is required"); + return $result; + } + + global $RBAC; + $RBAC->initRBAC(); + + $user = $RBAC->verifyUser($userId); + if ( $user == 1){ + $result = new wsCreateUserResponse (7, "Username '$userId' already exists", '' ) ; + return $result; + } + + $rol=$RBAC->loadById($role); + if ( is_array($rol) ){ + $strRole = $rol['ROL_CODE']; + } + else { + $very_rol = $RBAC->verifyByCode($role); + if ( $very_rol==0 ){ + $result = new wsResponse (6, "Invalid role '$role'"); + return $result; + } + $strRole = $role; + } + + $aData['USR_USERNAME'] = $userId; + $aData['USR_PASSWORD'] = md5($password); + $aData['USR_FIRSTNAME'] = $firstname; + $aData['USR_LASTNAME'] = $lastname; + $aData['USR_EMAIL'] = $email; + $aData['USR_DUE_DATE'] = mktime(0, 0, 0, date("m"), date("d"), date("Y")+1); + $aData['USR_CREATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_STATUS'] = 1; + + $sUserUID = $RBAC->createUser($aData, $strRole ); + + $aData['USR_UID'] = $sUserUID; + $aData['USR_PASSWORD'] = md5($sUserUID); + $aData['USR_STATUS'] = 'ACTIVE'; + $aData['USR_COUNTRY'] = 'US'; + $aData['USR_CITY'] = 'FL'; + $aData['USR_LOCATION'] = 'MIA'; + $aData['USR_ADDRESS'] = ''; + $aData['USR_PHONE'] = ''; + $aData['USR_ZIP_CODE'] = '33314'; + $aData['USR_POSITION'] = ''; + $aData['USR_RESUME'] = ''; + $aData['USR_BIRTHDAY'] = date('Y-m-d'); + $aData['USR_ROLE'] = $strRole ; + + $oUser = new Users(); + $oUser->create($aData); + + $res = new wsResponse (0, "User $firstname $lastname [$userId] created successfully"); + $result = array('status_code' => $res->status_code , + 'message' => $res->message, + 'userUID' => $sUserUID, + 'timestamp' => $res->timestamp ); + + return $result; + } + catch ( Exception $e ) { + $result = wsCreateUserResponse (100 , $e->getMessage(), '' ); + return $result; + } + } + + + /* + * create Group + * @param string $groupName + * @return $result will return an object + */ + public function createGroup( $groupName) { + try { + if( trim($groupName) == '' ) { + $result = new wsCreateGroupResponse (25, "Group name is required", ''); + return $result; + } + + $group = new Groupwf(); + $grpRow['GRP_TITLE'] = $groupName; + $groupId = $group->create( $grpRow ); + + $result = new wsCreateGroupResponse (0, "Group $groupName created successfully", $groupId); + + return $result; + } + catch ( Exception $e ) { + $result = wsCreateGroupResponse (100 , $e->getMessage(), '' ); + return $result; + } + } + + /* + * Create New Department link on the top section of the left pane allows you to create a root-level department. + * @param string $departmentName + * @param string $parentUID + * @return $result will return an object + */ + public function createDepartment( $departmentName, $parentUID ) { + try { + if( trim($departmentName) == '' ) { + $result = new wsCreateDepartmentResponse (25, "Department name is required", ''); + return $result; + } + + $department = new department(); + $row['DEP_TITLE'] = $departmentName; + $row['DEP_PARENT'] = $parentUID; + + $departmentId = $department->create( $row ); + + $result = new wsCreateDepartmentResponse (0, "$departmentName, $parentUID Department $departmentName created successfully", $departmentId); + return $result; + } + catch ( Exception $e ) { + $result = wsCreateDepartmentResponse (100 , $e->getMessage(), '' ); + return $result; + } + } + + /* + * assigns a user to a group + * @param string $userId + * @param string $groupId + * @return $result will return an object + */ + public function assignUserToGroup( $userId, $groupId) { + try { + global $RBAC; + $RBAC->initRBAC(); + $user=$RBAC->verifyUserId($userId); + if($user==0){ + $result = new wsResponse (3, "User not registered in the system"); + return $result; + } + + $groups = new Groups; + $very_group = $groups->verifyGroup( $groupId ); + if ( $very_group==0 ) { + $result = new wsResponse (9, "Group not registered in the system"); + return $result; + } + + $very_user = $groups->verifyUsertoGroup( $groupId, $userId); + if($very_user==1){ + $result = new wsResponse (8, "User already exists in the group"); + return $result; + } + $groups->addUserToGroup( $groupId, $userId); + $result = new wsResponse (0, "command executed successfuly"); + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + + /* + * assigns user to department + * @param string $userId + * @param string $depId + * @param string $manager + * @return $result will return an object + */ + public function assignUserToDepartment( $userId, $depId, $manager) { + try { + global $RBAC; + $RBAC->initRBAC(); + $user=$RBAC->verifyUserId($userId); + if($user==0){ + $result = new wsResponse (3, "User not registered in the system"); + return $result; + } + + $deps = new Department; + if ( !$deps->existsDepartment( $depId ) ) { + $result = new wsResponse (100, "Department $depId is not registered in the system"); + return $result; + } + + if ( ! $deps->existsUserInDepartment( $depId, $userId ) ) { + $deps->addUserToDepartment( $depId, $userId, $manager, true ); + } + + $result = new wsResponse (0, "command executed successfuly"); + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * sends variables to a case + * @param string $caseId + * @param string $variables + * @return $result will return an object + */ + public function sendVariables($caseId, $variables) { + //delegation where app uid (caseId) y usruid(session) ordenar delindes descendente y agaarr el primero + //delfinishdate != null error + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $oCriteria->add(AppDelegationPeer::APP_UID, $caseId); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL ); + + $oCriteria->addDescendingOrderByColumn(AppDelegationPeer::DEL_INDEX); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $cnt = 0; + while($oDataset->next()) { + $aRow = $oDataset->getRow(); + $cnt++; + } + + if ($cnt == 0){ + $result = new wsResponse (18, 'This case delegation is already closed or does not exist'); + return $result; + } + if ( is_array($variables)) { + $cant = count ( $variables ); + + if($cant > 0) { + $oCase = new Cases(); + $oldFields = $oCase->loadCase( $caseId ); + $oldFields['APP_DATA'] = array_merge( $oldFields['APP_DATA'], $variables ); + ob_start(); + print_r($variables); + $cdata = ob_get_contents(); + ob_end_clean(); + $up_case = $oCase->updateCase($caseId, $oldFields); + $result = new wsResponse (0, "$cant variables received: \n".trim(str_replace('Array', '', $cdata)) ); + return $result; + } + else { + $result = new wsResponse (23, "The variables param length is zero"); + return $result; + } + } else { + $result = new wsResponse (24, "The variables param is not an array"); + return $result; + } + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * get variables The variables can be system variables and/or case variables + * @param string $caseId + * @param string $variables + * @return $result will return an object + */ + public function getVariables($caseId, $variables) { + try { + if ( is_array($variables) ) { + $cant = count ( $variables ); + if($cant > 0) { + $oCase = new Cases(); + + $caseFields = $oCase->loadCase( $caseId ); + $oldFields = $caseFields['APP_DATA']; + $resFields = array(); + foreach ( $variables as $key => $val ) { + $a .= $val->name . ', '; + if ( isset ( $oldFields[ $val->name ] ) ) { + if ( !is_array ( $oldFields[ $val->name ] ) ) { + $node = new stdClass(); + $node->name = $val->name ; + $node->value = $oldFields[ $val->name ] ; + $resFields[ ] = $node; + }else{ + foreach($oldFields[ $val->name ] as $gridKey => $gridRow){//Sp?cial Variables like grids or checkgroups + if(is_array($gridRow)){//Grids + foreach($gridRow as $col => $colValue){ + $node = new stdClass(); + $node->name = $val->name."][".$gridKey."][".$col; + $node->value =$colValue; + $resFields[] = $node; + } + }else{//Checkgroups, Radiogroups + $node = new stdClass(); + $node->name = $key; + $node->value =implode("|",$val); + $resFields[] = $node; + } + } + } + } + } + $result = new wsGetVariableResponse (0, count($resFields) . " variables sent" , $resFields ); + return $result; + } + else { + $result = new wsGetVariableResponse (23, "The variables param length is zero", null); + return $result; + } + } + else { + $result = new wsGetVariableResponse (24, "The variables param is not a array", null); + return $result; + } + } + catch ( Exception $e ) { + $result = new wsGetVariableResponse (100, $e->getMessage(), NULL ); + return $result; + } + + } + + /* + * new Case begins a new case under the name of the logged-in user. + * @param string $processId + * @param string $userId + * @param string $taskId + * @param string $variables + * @return $result will return an object + */ + public function newCase($processId, $userId, $taskId, $variables) { + try { + $Fields = array(); + if ( is_array($variables) && count($variables)>0 ) { + $Fields = $variables; + } + $oProcesses = new Processes(); + $pro = $oProcesses->processExists($processId); + if( !$pro ) { + $result = new wsResponse (11, "Invalid process $processId"); + return $result; + } + + $oCase = new Cases(); + $oTask = new Tasks(); + $startingTasks = $oCase->getStartCases($userId); + array_shift ($startingTasks); //remove the first row, the header row + $founded = ''; + $tasksInThisProcess = 0; + $validTaskId = $taskId; + foreach ( $startingTasks as $key=> $val ) { + if ( $val['pro_uid'] == $processId ) { $tasksInThisProcess ++; $validTaskId = $val['uid']; } + if ( $val['uid'] == $taskId ) $founded = $val['value']; + } + + if ( $taskId == '' ) { + if ( $tasksInThisProcess == 1 ) { + $founded = $validTaskId; + $taskId = $validTaskId; + } + if ( $tasksInThisProcess > 1 ) { + $result = new wsResponse (13, "Multiple starting tasks in the process"); + return $result; + } + } + + if( $founded == '') { + $result = new wsResponse (14, "Task invalid or the user is not assigned to the task"); + return $result; + } + + $case = $oCase->startCase($taskId, $userId); + $caseId = $case['APPLICATION']; + $caseNr = $case['CASE_NUMBER']; + + $oldFields = $oCase->loadCase( $caseId ); + + $oldFields['APP_DATA'] = array_merge( $oldFields['APP_DATA'], $Fields); + + $up_case = $oCase->updateCase($caseId, $oldFields); + + $result = new wsResponse (0, "Command executed successfully"); + $result->caseId = $caseId; + $result->caseNumber = $caseNr; + + + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * creates a new case impersonating a user who has the proper privileges to create new cases + * @param string $processId + * @param string $userId + * @param string $variables + * @return $result will return an object + */ + public function newCaseImpersonate($processId, $userId, $variables) { + try { + if(is_array($variables)) { + if(count($variables)>0) { + $c=count($variables); + $Fields = $variables; + if($c == 0) { //Si no tenenmos ninguna variables en el array variables. + $result = new wsResponse (10, "Array of variables is empty"); + return $result; + } + } + } else { + $result = new wsResponse (10, "The variables param is not an array"); + return $result; + } + + $oProcesses = new Processes(); + $pro = $oProcesses->processExists($processId); + + if(!$pro) { + $result = new wsResponse (11, "Invalid process $processId!!"); + return $result; + } + + $oCase = new Cases(); + + $tasks = $oProcesses->getStartingTaskForUser($processId, $userId); + $numTasks=count($tasks); + + if($numTasks==1) + { + $oTask = new Tasks(); + $very = $oTask->verifyUsertoTask($userId, $tasks[0]['TAS_UID']); + if(is_array($very)) + { + if($very['TU_RELATION']==2) + { + $group=$groups->getUsersOfGroup( $tasks[0]['TAS_UID'] ); + if(!is_array($group)) + { $result = new wsResponse (14, "The user is not assigned to the task"); + return $result; + } + } + } + else + { $result = new wsResponse (14, "The user is not assigned to the task"); + return $result; + } + + $case = $oCase->startCase($tasks[0]['TAS_UID'], $userId); + $caseId = $case['APPLICATION']; + + $oldFields = $oCase->loadCase( $caseId ); + + $oldFields['APP_DATA'] = array_merge( $oldFields['APP_DATA'], $Fields); + + $up_case = $oCase->updateCase($caseId, $oldFields); + $result = new wsResponse (0, "Command executed successfully"); + return $result; + } + else { + if($numTasks==0) { + $result = new wsResponse (12, "No starting task defined"); + return $result; + } + if($numTasks > 1){ + $result = new wsResponse (13, "Multiple starting tasks in the process"); + return $result; + } + } + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * derivate Case moves the case to the next task in the process according to the routing rules + * @param string $userId + @param string $caseId + @param string $delIndex + * @return $result will return an object + */ + public function derivateCase($userId, $caseId, $delIndex, $bExecuteTriggersBeforeAssignment = false) { + try { + $sStatus = 'TO_DO'; + + $varResponse = ''; + $varTriggers = "\n"; + + if ($delIndex == '') { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->add(AppDelegationPeer::APP_UID, $caseId); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + if (AppDelegationPeer::doCount($oCriteria) > 1) { + $result = new wsResponse (20, 'Please specify the delegation index'); + return $result; + } + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $delIndex = $aRow['DEL_INDEX']; + } + + $oAppDel = new AppDelegation(); + $appdel = $oAppDel->Load($caseId, $delIndex); + + if($userId!=$appdel['USR_UID']) + { + $result = new wsResponse (17, "This case is assigned to another user"); + return $result; + } + + if($appdel['DEL_FINISH_DATE']!=NULL) + { + $result = new wsResponse (18, 'This case delegation is already closed or does not exist'); + return $result; + } + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelayPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelayPeer::APP_DEL_INDEX); + $oCriteria->add(AppDelayPeer::APP_TYPE, ''); + $oCriteria->add($oCriteria->getNewCriterion(AppDelayPeer::APP_TYPE, 'PAUSE')->addOr($oCriteria->getNewCriterion(AppDelayPeer::APP_TYPE, 'CANCEL'))); + $oCriteria->addAscendingOrderByColumn(AppDelayPeer::APP_ENABLE_ACTION_DATE); + $oDataset = AppDelayPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + if(is_array($aRow)) + { + if ( isset($aRow['APP_DISABLE_ACTION_USER']) && $aRow['APP_DISABLE_ACTION_USER']!=0 && + isset($aRow['APP_DISABLE_ACTION_DATE']) && $aRow['APP_DISABLE_ACTION_DATE']!='' ) { + $result = new wsResponse (19, "This case is in status ". $aRow['APP_TYPE']); + return $result; + } + } + + $aData['APP_UID'] = $caseId; + $aData['DEL_INDEX'] = $delIndex; + + //load data + $oCase = new Cases (); + $appFields = $oCase->loadCase( $caseId ); + $appFields['APP_DATA']['APPLICATION'] = $caseId; + + if ($bExecuteTriggersBeforeAssignment) { + //Execute triggers before assignment + $aTriggers = $oCase->loadTriggers($appdel['TAS_UID'], 'ASSIGN_TASK', -1, 'BEFORE' ); + if (count($aTriggers) > 0) { + $oPMScript = new PMScript(); + foreach ($aTriggers as $aTrigger) { + //$appFields = $oCase->loadCase( $caseId ); + //$appFields['APP_DATA']['APPLICATION'] = $caseId; + + #@Neyek ############################################################################################# + if( !$this->stored_system_variables ) { + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants() ); + } else { + $oParams = new stdClass(); + $oParams->option = 'STORED SESSION'; + $oParams->SID = $this->wsSessionId; + + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants($oParams)); + } + ##################################################################################################### + + $oPMScript->setFields( $appFields['APP_DATA'] ); + $bExecute = true; + if ($aTrigger['ST_CONDITION'] !== '') { + $oPMScript->setScript($aTrigger['ST_CONDITION']); + $bExecute = $oPMScript->evaluate(); + } + if ($bExecute) { + $oPMScript->setScript($aTrigger['TRI_WEBBOT']); + $oPMScript->execute(); + + //$appFields = $oCase->loadCase( $caseId ); + $appFields['APP_DATA'] = $oPMScript->aFields; + $oCase->updateCase ( $caseId, $appFields ); + } + } + } + } + + //Execute triggers before derivation + $aTriggers = $oCase->loadTriggers($appdel['TAS_UID'], 'ASSIGN_TASK', -2, 'BEFORE' ); + if (count($aTriggers) > 0) { + $oPMScript = new PMScript(); + foreach ($aTriggers as $aTrigger) { + //$appFields = $oCase->loadCase( $caseId ); + //$appFields['APP_DATA']['APPLICATION'] = $caseId; + + #@Neyek ############################################################################################# + if( !$this->stored_system_variables ) { + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants() ); + } else { + $oParams = new stdClass(); + $oParams->option = 'STORED SESSION'; + $oParams->SID = $this->wsSessionId; + + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants($oParams)); + } + ##################################################################################################### + + $oPMScript->setFields( $appFields['APP_DATA'] ); + $bExecute = true; + if ($aTrigger['ST_CONDITION'] !== '') { + $oPMScript->setScript($aTrigger['ST_CONDITION']); + $bExecute = $oPMScript->evaluate(); + } + if ($bExecute) { + $oPMScript->setScript($aTrigger['TRI_WEBBOT']); + $oPMScript->execute(); + + //$appFields = $oCase->loadCase( $caseId ); + $appFields['APP_DATA'] = $oPMScript->aFields; + //$appFields['APP_DATA']['APPLICATION'] = $caseId; + $oCase->updateCase ( $caseId, $appFields ); + } + } + } + + $oDerivation = new Derivation(); + $derive = $oDerivation->prepareInformation($aData); + if (isset($derive[1])) { + if ($derive[1]['ROU_TYPE'] == 'SELECT') { + $result = new wsResponse (21, 'Can not route a case with Manual Assignment using webservices'); + return $result; + } + } + else { + $result = new wsResponse (22, 'Task does not have a routing rule; check process definition'); + return $result; + } + foreach ( $derive as $key=>$val ) { + if($val['NEXT_TASK']['TAS_ASSIGN_TYPE']=='MANUAL') + { + $result = new wsResponse (15, "The task is defined for Manual assignment"); + return $result; + } + $nextDelegations[] = array( + 'TAS_UID' => $val['NEXT_TASK']['TAS_UID'], + 'USR_UID' => $val['NEXT_TASK']['USER_ASSIGNED']['USR_UID'], + 'TAS_ASSIGN_TYPE' => $val['NEXT_TASK']['TAS_ASSIGN_TYPE'], + 'TAS_DEF_PROC_CODE' => $val['NEXT_TASK']['TAS_DEF_PROC_CODE'], + 'DEL_PRIORITY' => $appdel['DEL_PRIORITY'], + 'TAS_PARENT' => $val['NEXT_TASK']['TAS_PARENT'] + ); + $varResponse = $varResponse . ($varResponse!=''?',':'') . $val['NEXT_TASK']['TAS_TITLE'].'('.$val['NEXT_TASK']['USER_ASSIGNED']['USR_USERNAME'].')'; + } + + $appFields['DEL_INDEX'] = $delIndex; + if ( isset($derive['TAS_UID']) ) + $appFields['TAS_UID'] = $derive['TAS_UID']; + + //Save data - Start + //$appFields = $oCase->loadCase( $caseId ); + //$oCase->updateCase ( $caseId, $appFields ); + //Save data - End + + $row = array(); + $oCriteria = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + $oCriteria->addSelectColumn(RoutePeer::ROU_TYPE); + $oCriteria->addSelectColumn(RoutePeer::ROU_NEXT_TASK); + $oCriteria->add(RoutePeer::TAS_UID, $appdel['TAS_UID']); + $oDataset = TaskPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $row[] = array ( 'ROU_TYPE' => $aRow['ROU_TYPE'], 'ROU_NEXT_TASK' => $aRow['ROU_NEXT_TASK'] ); + $oDataset->next(); + } + + //derivate case + $aCurrentDerivation = array( + 'APP_UID' => $caseId, + 'DEL_INDEX' => $delIndex, + 'APP_STATUS' => $sStatus, + 'TAS_UID' => $appdel['TAS_UID'], + 'ROU_TYPE' => $row[0]['ROU_TYPE'] + ); + + $oDerivation->derivate( $aCurrentDerivation, $nextDelegations ); + $appFields = $oCase->loadCase($caseId); + + $aTriggers = $oCase->loadTriggers($appdel['TAS_UID'], 'ASSIGN_TASK', -2, 'AFTER' ); + if (count($aTriggers) > 0) { + $oPMScript = new PMScript(); + //$appFields['APP_DATA']['APPLICATION'] = $caseId; + + #@Neyek ############################################################################################# + if( !$this->stored_system_variables ) { + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants() ); + } else { + $oParams = new stdClass(); + $oParams->option = 'STORED SESSION'; + $oParams->SID = $this->wsSessionId; + + $appFields['APP_DATA'] = array_merge ( $appFields['APP_DATA'], G::getSystemConstants($oParams)); + } + ##################################################################################################### + + $oPMScript->setFields( $appFields['APP_DATA'] ); + + foreach ($aTriggers as $aTrigger) { + $bExecute = true; + if ($aTrigger['ST_CONDITION'] !== '') { + $oPMScript->setScript($aTrigger['ST_CONDITION']); + $bExecute = $oPMScript->evaluate(); + } + if ($bExecute) { + $oPMScript->setScript($aTrigger['TRI_WEBBOT']); + $oPMScript->execute(); + + //$varTriggers .= "
    -= After Derivation =-
    " . htmlentities($aTrigger['TRI_WEBBOT'], ENT_QUOTES) . "
    "; + + //$appFields = $oCase->loadCase( $caseId ); + $appFields['APP_DATA'] = $oPMScript->aFields; + //$appFields['APP_DATA']['APPLICATION'] = $caseId; + //$appFields = $oCase->loadCase( $caseId ); + $oCase->updateCase ( $caseId, $appFields ); + } + } + } + + $oUser = new Users(); + $aUser = $oUser->load($userId); + $sFromName = '"' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . '"'; + $oCase->sendNotifications($appdel['TAS_UID'], $nextDelegations, $appFields['APP_DATA'], $caseId, $delIndex, $sFromName); + + //Save data - Start + //$appFields = $oCase->loadCase( $caseId ); + //$oCase->updateCase ( $caseId, $appFields ); + //Save data - End + + + $oProcess = new Process(); + $oProcessFieds = $oProcess->Load($appFields['PRO_UID']); + + $result = new wsResponse (0, $varResponse); + + + $res = $result->getPayloadArray (); + + //now fill the array of AppDelegationPeer + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppDelegationPeer::USR_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::TAS_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_THREAD); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_THREAD_STATUS); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $oCriteria->add(AppDelegationPeer::APP_UID, $caseId); + $oCriteria->add(AppDelegationPeer::DEL_PREVIOUS, $delIndex ); + $oCriteria->addAscendingOrderByColumn(AppDelegationPeer::DEL_INDEX); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aCurrentUsers = array(); + while($oDataset->next()) { + $aAppDel = $oDataset->getRow(); + + $oUser = new Users(); + try { + $oUser->load($aAppDel['USR_UID']); + $uFields = $oUser->toArray(BasePeer::TYPE_FIELDNAME); + $currentUserName = $oUser->getUsrFirstname() . ' ' . $oUser->getUsrLastname(); + } + catch ( Exception $e ) { + $currentUserName = ''; + } + + $oTask = new Task(); + try { + $uFields = $oTask->load($aAppDel['TAS_UID']); + $taskName = $uFields['TAS_TITLE']; + } + catch ( Exception $e ) { + $taskName = ''; + } + + $currentUser = new stdClass(); + $currentUser->userId = $aAppDel['USR_UID']; + $currentUser->userName = $currentUserName; + $currentUser->taskId = $aAppDel['TAS_UID']; + $currentUser->taskName = $taskName; + $currentUser->delIndex = $aAppDel['DEL_INDEX']; + $currentUser->delThread = $aAppDel['DEL_THREAD']; + $currentUser->delThreadStatus = $aAppDel['DEL_THREAD_STATUS']; + $aCurrentUsers[] = $currentUser; + } + + $res['routing'] = $aCurrentUsers; + return $res; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * execute Trigger, executes a ProcessMaker trigger. Note that triggers which are tied to case derivation will executing automatically. + * @param string $userId + * @param string $caseId + * @param string $delIndex + * @return $result will return an object + */ + public function executeTrigger($userId, $caseId, $triggerIndex, $delIndex) { + try { + $oAppDel = new AppDelegation(); + $appdel = $oAppDel->Load($caseId, $delIndex); + + if($userId!=$appdel['USR_UID']) + { + $result = new wsResponse (17, "This case is assigned to another user"); + return $result; + } + + if($appdel['DEL_FINISH_DATE']!=NULL) + { + $result = new wsResponse (18, 'This case delegation is already closed or does not exist'); + return $result; + } + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelayPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelayPeer::APP_DEL_INDEX); + $oCriteria->add(AppDelayPeer::APP_TYPE, ''); + $oCriteria->add($oCriteria->getNewCriterion(AppDelayPeer::APP_TYPE, 'PAUSE')->addOr($oCriteria->getNewCriterion(AppDelayPeer::APP_TYPE, 'CANCEL'))); + $oCriteria->addAscendingOrderByColumn(AppDelayPeer::APP_ENABLE_ACTION_DATE); + $oDataset = AppDelayPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + $aRow = $oDataset->getRow(); + + if(is_array($aRow)) + { + if($aRow['APP_DISABLE_ACTION_USER']!=0 && $aRow['APP_DISABLE_ACTION_DATE']!='') + { + $result = new wsResponse (19, "This case is in status ". $aRow['APP_TYPE']); + return $result; + } + } + + //load data + $oCase = new Cases (); + $appFields = $oCase->loadCase( $caseId ); + $appFields['APP_DATA']['APPLICATION'] = $caseId; + + //executeTrigger + $aTriggers = array(); + $c = new Criteria(); + $c ->add(TriggersPeer::TRI_UID, $triggerIndex ); + $rs = TriggersPeer::doSelectRS($c); + $rs ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs ->next(); + $row = $rs->getRow(); + if (is_array($row) && $row['TRI_TYPE'] == 'SCRIPT' ) { + $aTriggers[] = $row; + $oPMScript = new PMScript(); + $oPMScript ->setFields($appFields['APP_DATA']); + $oPMScript ->setScript($row['TRI_WEBBOT']); + $oPMScript ->execute(); + + //Save data - Start + $appFields['APP_DATA'] = $oPMScript->aFields; + //$appFields = $oCase->loadCase( $caseId ); + $oCase->updateCase ( $caseId, $appFields); + //Save data - End + } + else { + $result = new wsResponse (100, "Invalid trigger '$triggerIndex'" ); + return $result; + } + + + $result = new wsResponse (0, 'executed: '. trim( $row['TRI_WEBBOT']) ); + //$result = new wsResponse (0, 'executed: '. print_r( $oPMScript ,1 ) ); + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * task Case + * @param string sessionId : The session ID which is obtained when logging in + * @param string caseId : The case ID. The caseList() function can be used to find the ID number for cases + * @return $result returns the current task for a given case. Note that the logged-in user must have privileges to access the task + */ + public function taskCase( $caseId ) { + try { + $result = array(); + $oCriteria = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + $oCriteria ->addSelectColumn(AppDelegationPeer::DEL_INDEX); + + $oCriteria ->addAsColumn('TAS_TITLE', 'C1.CON_VALUE' ); + $oCriteria ->addAlias("C1", 'CONTENT'); + $tasTitleConds = array(); + $tasTitleConds[] = array( AppDelegationPeer::TAS_UID , 'C1.CON_ID' ); + $tasTitleConds[] = array( 'C1.CON_CATEGORY' , $del . 'TAS_TITLE' . $del ); + $tasTitleConds[] = array( 'C1.CON_LANG' , $del . SYS_LANG . $del ); + $oCriteria ->addJoinMC($tasTitleConds , Criteria::LEFT_JOIN); + + $oCriteria ->add(AppDelegationPeer::APP_UID, $caseId ); + $oCriteria ->add(AppDelegationPeer::DEL_THREAD_STATUS, 'OPEN'); + $oCriteria ->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL ); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + + while ($aRow = $oDataset->getRow()) { + $result[] = array ( 'guid' => $aRow['DEL_INDEX'], 'name' => $aRow['TAS_TITLE'] ); + $oDataset->next(); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + /* + * process list verified + * @param string sessionId : The session ID which is obtained when logging in + * @param string userId : + * @return $result will return an object + */ + public function processListVerified( $userId ){ + try { + $oCase = new Cases(); + $rows = $oCase->getStartCases($userId); + $result = array(); + + foreach ( $rows as $key=>$val ) { + if ( $key != 0 ) + $result[] = array ( 'guid' => $val['pro_uid'], 'name' => $val['value'] ); + } + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + + /* + * reassign Case + * @param string sessionId : The session ID (which was obtained during login) + * @param string caseId : The case ID (which can be obtained with the caseList() function) + * @param string delIndex : The delegation index number of the case (which can be obtained with the caseList() function). + * @param string userIdSource : The user who is currently assigned the case. + * @param string userIdTarget : The target user who will be newly assigned to the case. + * @return $result will return an object + */ + public function reassignCase( $sessionId, $caseId, $delIndex, $userIdSource, $userIdTarget ){ + try { + if ( $userIdTarget == $userIdSource ) { + $result = new wsResponse (30, "Target and Origin user are the same" ); + return $result; + } + + /******************( 1 )******************/ + $oCriteria = new Criteria('workflow'); + $oCriteria ->add(UsersPeer::USR_STATUS, 'ACTIVE' ); + $oCriteria ->add(UsersPeer::USR_UID, $userIdSource); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + $aRow = $oDataset->getRow(); + if(!is_array($aRow)) + { + $result = new wsResponse (31, "Invalid origin user" ); + return $result; + } + + /******************( 2 )******************/ + $oCase = new Cases(); + $rows = $oCase->loadCase($caseId); + if(!is_array($aRow)) + { + $result = new wsResponse (32, "This case is not open" ); + return $result; + } + + /******************( 3 )******************/ + $oCriteria = new Criteria('workflow'); + $aConditions = array(); + // $aConditions[] = array(AppDelegationPeer::USR_UID, TaskUserPeer::USR_UID); + // $aConditions[] = array(AppDelegationPeer::TAS_UID, TaskUserPeer::TAS_UID); + // $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + //$oCriteria->addJoin(AppDelegationPeer::USR_UID, TaskUserPeer::USR_UID, Criteria::LEFT_JOIN); + $oCriteria ->add(AppDelegationPeer::APP_UID, $caseId ); + $oCriteria ->add(AppDelegationPeer::USR_UID, $userIdSource ); + $oCriteria ->add(AppDelegationPeer::DEL_INDEX, $delIndex); + $oCriteria ->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + $aRow = $oDataset->getRow(); + if(!is_array($aRow)) + { + $result = new wsResponse (33, "Invalid Case Delegation index for this user" ); + return $result; + } + $tasUid = $aRow['TAS_UID']; + $derivation = new Derivation (); + $userList = $derivation->getAllUsersFromAnyTask( $tasUid ); + if ( ! in_array ( $userIdTarget, $userList ) ) { + $result = new wsResponse (34, "The target user does not have rights to execute the task " ); + return $result; + } + + + /******************( 4 )******************/ + $oCriteria = new Criteria('workflow'); + $oCriteria ->add(UsersPeer::USR_STATUS, 'ACTIVE' ); + $oCriteria ->add(UsersPeer::USR_UID, $userIdTarget); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset ->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset ->next(); + $aRow = $oDataset->getRow(); + if(!is_array($aRow)) + { + $result = new wsResponse (35, "The target user destination is invalid" ); + return $result; + } + + + /******************( 5 )******************/ + $var=$oCase->reassignCase($caseId, $delIndex, $userIdSource, $userIdTarget); + + if(!$var) + { + $result = new wsResponse (36, "The case could not be reassigned." ); + return $result; + } + + $result = new wsResponse (0, 'Command executed successfully'); + + return $result; + } + catch ( Exception $e ) { + $result[] = array ( 'guid' => $e->getMessage(), 'name' => $e->getMessage() ); + return $result; + } + } + + /* + * get system information + * @param string sessionId : The session ID (which was obtained at login) + * @return $eturns information about the WAMP/LAMP stack, the workspace database, the IP number and version of ProcessMaker, and the IP number and version of web browser of the user + */ + public function systemInformation() { + try { + define ( 'SKIP_RENDER_SYSTEM_INFORMATION', true ); + require_once ( PATH_METHODS . 'login' . PATH_SEP . 'dbInfo.php' ); + $result->status_code = 0; + $result->message = 'Sucessful'; + $result->timestamp = date ( 'Y-m-d H:i:s'); + $result->version = PM_VERSION; + $result->operatingSystem = $redhat; + $result->webServer = getenv('SERVER_SOFTWARE'); + $result->serverName = getenv('SERVER_NAME'); + $result->serverIp = $Fields['IP']; //lookup ($ip); + $result->phpVersion = phpversion(); + $result->databaseVersion = $Fields['DATABASE']; + $result->databaseServerIp = $Fields['DATABASE_SERVER']; + $result->databaseName = $Fields['DATABASE_NAME']; + $result->availableDatabases = $Fields['AVAILABLE_DB']; + $result->userBrowser = $Fields['HTTP_USER_AGENT']; + $result->userIp = $Fields['IP']; + + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + + /* + * import process fromLibrary: downloads and imports a process from the ProcessMaker library + * @param string sessionId : The session ID (which was obtained at login). + * @param string processId : + * @param string version : + * @param string importOption : + * @param string usernameLibrary : The username to obtain access to the ProcessMaker library. + * @param string passwordLibrary : The password to obtain access to the ProcessMaker library. + * @return $eturns will return an object + */ + public function importProcessFromLibrary ( $processId, $version = '', $importOption = '', $usernameLibrary = '', $passwordLibrary = '' ) { + try { + G::LoadClass('processes'); + //$versionReq = $_GET['v']; + //. (isset($_GET['s']) ? '&s=' . $_GET['s'] : '') + $ipaddress = $_SERVER['REMOTE_ADDR']; + $oProcesses = new Processes(); + $oProcesses ->ws_open_public(); + $oProcess = $oProcesses->ws_processGetData($processId); + if ( $oProcess->status_code != 0 ) { + throw ( new Exception ( $oProcess->message ) ); + } + + $privacy = $oProcess->privacy; + + $strSession = ''; + if ( $privacy != 'FREE' ) { + global $sessionId; + $antSession = $sessionId; + $oProcesses->ws_open ($usernameLibrary, $passwordLibrary ); + $strSession = "&s=" . $sessionId; + $sessionId = $antSession; + } + + //downloading the file + $localPath = PATH_DOCUMENT . 'input' . PATH_SEP ; + G::mk_dir($localPath); + $newfilename = G::GenerateUniqueId() . '.pm'; + + $downloadUrl = PML_DOWNLOAD_URL . '?id=' . $processId . $strSession; + + $oProcess = new Processes(); + $oProcess->downloadFile( $downloadUrl, $localPath, $newfilename); + + //getting the ProUid from the file recently downloaded + $oData = $oProcess->getProcessData ( $localPath . $newfilename ); + if ( is_null($oData)) { + throw new Exception('Error the url ' . $downloadUrl . ' is invalid or the process in '. $localPath . $newfilename. ' is invalid'); + } + + $sProUid = $oData->process['PRO_UID']; + $oData->process['PRO_UID_OLD'] = $sProUid; + + //if the process exists, we need to check the $importOption to and re-import if the user wants, + if ( $oProcess->processExists ( $sProUid ) ) { + + //Update the current Process, overwriting all tasks and steps + if ( $importOption == 1 ) { + $oProcess->updateProcessFromData ($oData, $localPath . $newfilename ); + //delete the xmlform cache + if (file_exists(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid)) { + $oDirectory = dir(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid); + while($sObjectName = $oDirectory->read()) { + if (($sObjectName != '.') && ($sObjectName != '..')) { + unlink(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid . PATH_SEP . $sObjectName); + } + } + $oDirectory->close(); + } + $sNewProUid = $sProUid; + } + + //Disable current Process and create a new version of the Process + if ( $importOption == 2 ) { + $oProcess ->disablePreviousProcesses( $sProUid ); + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess ->setProcessGuid ( $oData, $sNewProUid ); + $oProcess ->setProcessParent( $oData, $sProUid ); + $oData ->process['PRO_TITLE'] = "New - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess ->renewAll ( $oData ); + $oProcess ->createProcessFromData ($oData, $localPath . $newfilename ); + } + + //Create a completely new Process without change the current Process + if ( $importOption == 3 ) { + //krumo ($oData); die; + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess ->setProcessGuid ( $oData, $sNewProUid ); + $oData ->process['PRO_TITLE'] = "Copy of - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess ->renewAll ( $oData ); + $oProcess ->createProcessFromData ($oData, $localPath . $newfilename ); + } + + if ( $importOption != 1 && $importOption != 2 && $importOption != 3 ) { + throw new Exception('The process is already in the System and the value for importOption is not specified.'); + } + } + + //finally, creating the process if the process does not exists + if ( ! $oProcess->processExists ( $processId ) ) { + $oProcess->createProcessFromData ($oData, $localPath . $newfilename ); + } + + //show the info after the imported process + $oProcess = new Processes(); + $oProcess ->ws_open_public (); + $processData = $oProcess->ws_processGetData ( $processId ); + + $result ->status_code = 0; + $result ->message = 'Command executed successfully'; + $result ->timestamp = date ( 'Y-m-d H:i:s'); + $result ->processId = $processId; + $result ->processTitle = $processData->title; + $result ->category = (isset($processData->category) ? $processData->category : ''); + $result ->version = $processData->version; + + return $result; + } + catch ( Exception $e ) { + $result = new wsResponse (100, $e->getMessage()); + return $result; + } + } + +} \ No newline at end of file diff --git a/workflow/engine/classes/class.wsResponse.php b/workflow/engine/classes/class.wsResponse.php new file mode 100644 index 000000000..4db703446 --- /dev/null +++ b/workflow/engine/classes/class.wsResponse.php @@ -0,0 +1,177 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +class wsResponse +{ + public $status_code = 0; + public $message = ''; + public $timestamp = ''; + + /** + * Function __construct + * Constructor of the class + * @param string $status + * @param string $message + * @return void + */ + function __construct( $status, $message ) + { + $this->status_code = $status; + $this->message = $message; + $this->timestamp = date('Y-m-d H:i:s'); + } + + /** + * Function getPayloadString + * @param string $operation + * @return string + */ + function getPayloadString ( $operation ) + { + $res = "<$operation>\n"; + $res .= "" . $this->status_code . ""; + $res .= "" . $this->message . ""; + $res .= "" . $this->timestamp . ""; +// $res .= "" . $this->timestamp . ""; + $res .= "<$operation>"; + return $res; + } + + /** + * Function getPayloadArray + * @return array + */ + function getPayloadArray() + { + return array("status_code" => $this->status_code , 'message'=> $this->message, 'timestamp' => $this->timestamp); + } +} + +/** + * Class wsCreateUserResponse + */ +class wsCreateUserResponse +{ + public $status_code = 0; + public $message = ''; + public $userUID = ''; + public $timestamp = ''; + + /** + * Function __construct + * Constructor of the class + * @param string $status + * @param string $message + * @param string $userUID + * @return void + */ + function __construct( $status, $message, $userUID ) + { + $this->status_code = $status; + $this->message = $message; + $this->userUID = $userUID; + $this->timestamp = date('Y-m-d H:i:s'); + } +} + +/** + * Class wsCreateGroupResponse + */ +class wsCreateGroupResponse +{ + public $status_code = 0; + public $message = ''; + public $groupUID = ''; + public $timestamp = ''; + + /** + * Function __construct + * Constructor of the class + * @param string $status + * @param string $message + * @param string $groupUID + * @return void + */ + function __construct( $status, $message, $groupUID ) { + $this->status_code = $status; + $this->message = $message; + $this->groupUID = $groupUID; + $this->timestamp = date('Y-m-d H:i:s'); + } + +} + +/** + * Class wsCreateDepartmentResponse + */ +class wsCreateDepartmentResponse +{ + public $status_code = 0; + public $message = ''; + public $departmentUID = ''; + public $timestamp = ''; + + /** + * Function __construct + * Constructor of the class + * @param string $status + * @param string $message + * @param string $departmentUID + * @return void + */ + function __construct( $status, $message, $departmentUID ) { + $this->status_code = $status; + $this->message = $message; + $this->departmentUID = $departmentUID; + $this->timestamp = date('Y-m-d H:i:s'); + } +} + +/** + * Class wsGetVariableResponse + */ +class wsGetVariableResponse +{ + public $status_code = 0; + public $message = ''; + public $variables = null; + public $timestamp = ''; + + /** + * Function __construct + * Constructor of the class + * @param string $status + * @param string $message + * @param string $variables + * @return void + */ + function __construct( $status, $message, $variables ) { + $this->status_code = $status; + $this->message = $message; + $this->variables = $variables; + $this->timestamp = date('Y-m-d H:i:s'); + } +} +?> \ No newline at end of file diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php new file mode 100644 index 000000000..d947a0843 --- /dev/null +++ b/workflow/engine/classes/class.wsTools.php @@ -0,0 +1,370 @@ +.*?)' *, *\n* *')(?P.*?)(' *\) *;.*)/"; + + /** + * Create a workspace tools object + * + * @author Alexandre Rosenfeld + * @access public + * @param string $workspaceName name of the workspace + * @return void + */ + function __construct($workspaceName) + { + $this->workspaceName = $workspaceName; + $this->dbFile = PATH_DB . $this->workspaceName . '/db.php'; + } + + function listWorkspaces() { + $oDirectory = dir(PATH_DB); + $aWorkspaces = array (); + while( ($sObject = $oDirectory->read()) ) { + if( is_dir(PATH_DB . $sObject) && substr($sObject, 0, 1) != '.' && file_exists(PATH_DB . $sObject . PATH_SEP . 'db.php') ) { + $aWorkspaces[] = new workspaceTools($sObject); + } + } + return $aWorkspaces; + } + + function getDBInfo() { + if( file_exists($this->dbFile) ) { + $sDbFile = file_get_contents($this->dbFile); + /* This regular expression will match any "define ('', '');" + * with any combination of whitespace between words. + * Each match will have these groups: + * ((define('()2', ')1 ()3 (');)4 )0 + */ + preg_match_all($this->dbInfoRegExp, $sDbFile, $matches, PREG_SET_ORDER); + $config = array(); + foreach ($matches as $match) { + $config[$match['key']] = $match['value']; + } + return $config; + } else { + throw new Exception("Workspace db.php not found."); + } + } + + function getSchema() { + $dbInfo = $this->getDBInfo(); + $DB_ADAPTER = $dbInfo["DB_ADAPTER"]; + $DB_HOST = $dbInfo["DB_HOST"]; + $DB_USER = $dbInfo["DB_USER"]; + $DB_PASS = $dbInfo["DB_PASS"]; + $DB_NAME = $dbInfo["DB_NAME"]; + + try { + G::LoadSystem( 'database_' . strtolower($DB_ADAPTER)); + + $aOldSchema = array(); + $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); + + if ( !$oDataBase->isConnected() ) { + $oDataBase->logQuery ('Not exists an available connection!'); + return NULL; + } + + $oDataBase->iFetchType = MYSQL_NUM; + $oDataset1 = $oDataBase->executeQuery($oDataBase->generateShowTablesSQL()); + + } catch ( Exception $e ) { + $oDataBase->logQuery ( $e->getmessage() ); + return NULL; + } + + //going thru all tables in current WF_ database + while ($aRow1 = $oDataBase->getRegistry( $oDataset1) ) { + $aPrimaryKeys = array(); + $sTable = strtoupper($aRow1[0]); + + //get description of each table, ( column and primary keys ) + //$oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL($aRow1[0]) ); + $oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL($sTable ) ); + $aOldSchema[ $sTable ] = array(); + $oDataBase->iFetchType = MYSQL_ASSOC; + while ($aRow2 = $oDataBase->getRegistry($oDataset2)) { + $aOldSchema[$sTable][$aRow2['Field']]['Field'] = $aRow2['Field']; + $aOldSchema[$sTable][$aRow2['Field']]['Type'] = $aRow2['Type']; + $aOldSchema[$sTable][$aRow2['Field']]['Null'] = $aRow2['Null']; + $aOldSchema[$sTable][$aRow2['Field']]['Default'] = $aRow2['Default']; + } + + //get indexes of each table SHOW INDEX FROM `ADDITIONAL_TABLES`; -- WHERE Key_name <> 'PRIMARY' + $oDataset2 = $oDataBase->executeQuery($oDataBase->generateTableIndexSQL($aRow1[0])); + $oDataBase->iFetchType = MYSQL_ASSOC; + while ($aRow2 = $oDataBase->getRegistry($oDataset2)) { + if ( !isset($aOldSchema[$sTable]['INDEXES']) ) { + $aOldSchema[$sTable]['INDEXES'] = array(); + } + if (!isset($aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] ) ) { + $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] = array(); + } + $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']][] = $aRow2['Column_name']; + } + + $oDataBase->iFetchType = MYSQL_NUM; //this line is neccesary because the next fetch needs to be with MYSQL_NUM + } + //finally return the array with old schema obtained from the Database + if ( count($aOldSchema) == 0 ) $aOldSchema = null; + return $aOldSchema; + } + + function getSchemaFromFile($sSchemaFile, $dbAdapter) { + $aSchema = array(); + $oXml = new DomDocument(); + $oXml->load($sSchemaFile); + $aTables = $oXml->getElementsByTagName('table'); + foreach ($aTables as $oTable) { + $aPrimaryKeys = array(); + $sTableName = $oTable->getAttribute('name'); + $aSchema[$sTableName] = array(); + $aColumns = $oTable->getElementsByTagName('column'); + foreach ($aColumns as $oColumn) { + $sColumName = $oColumn->getAttribute('name'); + $aSchema[$sTableName][$sColumName] = array(); + $aVendors = $oColumn->getElementsByTagName('vendor'); + foreach ($aVendors as $oVendor) { + if ($oVendor->getAttribute('type') == $dbAdapter) { + break; + } + } + $aParameters = $oColumn->getElementsByTagName('parameter'); + foreach ($aParameters as $oParameter) { + $parameterName = ucwords($oParameter->getAttribute('name')); + if ( $parameterName == 'Key' && strtoupper($oParameter->getAttribute('value')) == 'PRI' ) { + $aPrimaryKeys[] = $oColumn->getAttribute('name'); + } + + if ( in_array ( $parameterName, array('Field','Type','Null','Default') ) ) { + $aSchema[$sTableName][$sColumName][$parameterName] = $oParameter->getAttribute('value'); + } + } + } + + if ( is_array($aPrimaryKeys) && count($aPrimaryKeys) > 0 ) { + $aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; + } + $aIndexes = $oTable->getElementsByTagName('index'); + foreach ($aIndexes as $oIndex) { + $aIndex = array(); + $aIndexesColumns = $oIndex->getElementsByTagName('index-column'); + foreach ($aIndexesColumns as $oIndexColumn) { + $aIndex[] = $oIndexColumn->getAttribute('name'); + } + $aSchema[$sTableName]['INDEXES'][ $oIndex->getAttribute('name') ] = $aIndex; + } + } + return $aSchema; + } + + function getSchemaChanges($aOldSchema, $aNewSchema) { + //$aChanges = array('tablesToDelete' => array(), 'tablesToAdd' => array(), 'tablesToAlter' => array()); + //Tables to delete, but this is disabled + //foreach ($aOldSchema as $sTableName => $aColumns) { + // if ( !isset($aNewSchema[$sTableName])) { + // if (!in_array($sTableName, array('KT_APPLICATION', 'KT_DOCUMENT', 'KT_PROCESS'))) { + // $aChanges['tablesToDelete'][] = $sTableName; + // } + // } + //} + + $aChanges = array('tablesToAdd' => array(), 'tablesToAlter' => array(), 'tablesWithNewIndex' => array(), 'tablesToAlterIndex'=> array()); + + //new tables to create and alter + foreach ($aNewSchema as $sTableName => $aColumns) { + if (!isset($aOldSchema[$sTableName])) { + $aChanges['tablesToAdd'][$sTableName] = $aColumns; + } + else { + //drop old columns + foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { + if (!isset($aNewSchema[$sTableName][$sColumName])) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; + } + } + + //create new columns + //foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { + foreach ($aColumns as $sColumName => $aParameters) { + if ($sColumName != 'INDEXES') { + if (!isset($aOldSchema[$sTableName][$sColumName])) { //this column doesnt exist in oldschema + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; + } + else { //the column exists + $newField = $aNewSchema[$sTableName][$sColumName]; + $oldField = $aOldSchema[$sTableName][$sColumName]; + //both are null, no change is required + if ( !isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = false; + //one of them is null, change IS required + if ( !isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default']!= '') $changeDefaultAttr = true; + if ( isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = true; + //both are defined and they are different. + if ( isset($newField['Default']) && isset($oldField['Default']) ) { + if ( $newField['Default'] != $oldField['Default'] ) + $changeDefaultAttr = true; + else + $changeDefaultAttr = false; + } + //special cases + // BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html + if ( in_array(strtolower($newField['Type']), array('text','mediumtext') ) ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for datetime field + if ( in_array($newField['Type'], array('datetime')) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for int field + if ( substr($newField['Type'], 0, 3 ) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //if any difference exists, then insert the difference in aChanges + if ( $newField['Field'] != $oldField['Field'] || + $newField['Type'] != $oldField['Type'] || + $newField['Null'] != $oldField['Null'] || + $changeDefaultAttr ) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; + if ( isset($newField['Default']) ) + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; + else + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; + + } + } + } //only columns, no the indexes column + }//foreach $aColumns + + //now check the indexes of table + if ( isset($aNewSchema[$sTableName]['INDEXES']) ) { + foreach ( $aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields ) { + if (!isset( $aOldSchema[$sTableName]['INDEXES'][$indexName]) ) { + if (!isset($aChanges['tablesWithNewIndex'][$sTableName])) { + $aChanges['tablesWithNewIndex'][$sTableName] = array(); + } + $aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; + } + else { + if ( $aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields ) { + if (!isset($aChanges['tablesToAlterIndex'][$sTableName])) { + $aChanges['tablesToAlterIndex'][$sTableName] = array(); + } + $aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; + } + } + } + } + } //for-else table exists + } //for new schema + return $aChanges; + } + + function repairSchema($checkOnly = false, $progress = true) { + $dbInfo = $this->getDBInfo(); + $DB_ADAPTER = $dbInfo["DB_ADAPTER"]; + $DB_HOST = $dbInfo["DB_HOST"]; + $DB_USER = $dbInfo["DB_USER"]; + $DB_PASS = $dbInfo["DB_PASS"]; + $DB_NAME = $dbInfo["DB_NAME"]; + + if (strcmp($DB_ADAPTER, "mysql") != 0) { + throw new Exception("Only MySQL is supported\n"); + } + + $currentSchema = $this->getSchemaFromFile(PATH_TRUNK . "workflow/engine/config/schema.xml", "mysql"); + $workspaceSchema = $this->getSchema(); + $changes = $this->getSchemaChanges($workspaceSchema, $currentSchema); + $changed = (count($changes['tablesToAdd']) > 0 || + count($changes['tablesToAlter']) > 0 || + count($changes['tablesWithNewIndex']) > 0 || + count($changes['tablesToAlterIndex']) > 0); + if ($checkOnly || (!$changed)) { + if ($changed) + return $changes; + else + return $changed; + } + + $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); + if ( !$oDataBase->isConnected() ) { + throw new Exception("Could not connect to the database"); + } + $oDataBase->iFetchType = MYSQL_NUM; + + $oDataBase->logQuery ( count ($changes ) ); + + if ($progress) + echo "Adding " . count($changes['tablesToAdd']) . " tables\n"; + foreach ($changes['tablesToAdd'] as $sTable => $aColumns) { + $oDataBase->executeQuery($oDataBase->generateCreateTableSQL($sTable, $aColumns)); + if (isset($changes['tablesToAdd'][$sTable]['INDEXES'])) { + foreach ($changes['tablesToAdd'][$sTable]['INDEXES'] as $indexName => $aIndex) { + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $indexName, $aIndex ) ); + } + } + } + + + if ($progress) + echo "Altering " . count($changes['tablesToAlter']) . " tables\n"; + foreach ($changes['tablesToAlter'] as $sTable => $aActions) { + foreach ($aActions as $sAction => $aAction) { + foreach ($aAction as $sColumn => $vData) { + switch ($sAction) { + case 'DROP': + $oDataBase->executeQuery($oDataBase->generateDropColumnSQL($sTable, $vData)); + break; + case 'ADD': + $oDataBase->executeQuery($oDataBase->generateAddColumnSQL($sTable, $sColumn, $vData)); + break; + case 'CHANGE': + $oDataBase->executeQuery($oDataBase->generateChangeColumnSQL($sTable, $sColumn, $vData)); + break; + } + } + } + } + + + if ($progress) + echo "Adding indexes to " . count($changes['tablesWithNewIndex']) . " tables\n"; + foreach ($changes['tablesWithNewIndex'] as $sTable => $aIndexes) { + foreach ($aIndexes as $sIndexName => $aIndexFields ) { + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); + } + } + + + if ($progress) + echo "Altering indexes to " . count($changes['tablesWithNewIndex']) . " tables\n"; + foreach ($changes['tablesToAlterIndex'] as $sTable => $aIndexes) { + foreach ($aIndexes as $sIndexName => $aIndexFields ) { + $oDataBase->executeQuery($oDataBase->generateDropKeySQL($sTable, $sIndexName )); + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); + } + } + $oDataBase->close(); + return true; + } + +} +?> diff --git a/workflow/engine/classes/class.xmlDb.php b/workflow/engine/classes/class.xmlDb.php new file mode 100644 index 000000000..6bd1109ea --- /dev/null +++ b/workflow/engine/classes/class.xmlDb.php @@ -0,0 +1,629 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + + +/** +* XMLDB +* +* ProcessMaker Open Source Edition +* +* @copyright (C) 2004 - 2008 Colosa Inc.23 +*/ +class XMLDB +{ + + /** + * &connect + * + * @param string $dsn + * @return array $options + */ + function &connect ($dsn, $options = array()) + { + //Needed for $mysql_real_escape_string + $mresdbc = new DBConnection(); + + if ( !file_exists( $dsn ) ) { + $err = new DB_Error( "File $dsn not found." ); + return $err; + } + $dbc = new XMLConnection($dsn); + return $dbc; + } + + /** + * isError + * + * @param string $result + * @return boolean is_a($result, 'DB_Error') + */ + function isError ( $result ) + { + return is_a($result, 'DB_Error'); + } +} + +/** +* XMLConnection +* +* ProcessMaker Open Source Edition +* +* @copyright (C) 2004 - 2008 Colosa Inc.23 +*/ +class XMLConnection +{ + var $phptype = 'myxml'; + var $caseFolding = true; + var $xmldoc = NULL; + var $xmlFile = ''; + + /** + * XMLConnection + * + * @param string $file + * @return void + */ + function XMLConnection ( $file ) + { + $this->xmldoc = new Xml_Document(); + $this->xmldoc->parseXmlFile( $file ); + $this->xmlFile = $file; + } + + /** + * &query + * Actualy the only one supported query is simple SELECT. + * + * @param string $sql + * @return object(XMLResult) $result + */ + function &query( $sql ) + { + if ( !isset( $this->xmldoc ) ) { + $err = new DB_Error( "Error: Closed xmlConnection." ); + return $err; + } + if (1===preg_match('/^\s*SELECT\s+([\w\W]+?)(?:\s+FROM\s+`?([^`]+?)`?)(?:\s+WHERE\s+([\w\W]+?))?(?:\s+GROUP\s+BY\s+([\w\W]+?))?(?:\s+ORDER\s+BY\s+([\w\W]+?))?(?:\s+BETWEEN\s+([\w\W]+?)\s+AND\s+([\w\W]+?))?(?:\s+LIMIT\s+(\d+)\s*,\s*(\d+))?\s*$/im', $sql, $matches)) { + $sqlColumns = $matches[1]; + $sqlFrom = isset($matches[2])?$matches[2]:''; + $sqlWhere = isset($matches[3])?$matches[3]:''; + $sqlGroupBy = isset($matches[4])?$matches[4]:''; + $sqlOrderBy = isset($matches[5])?$matches[5]:''; + $sqlLowLimit = isset($matches[8])?$matches[8]:''; + $sqlHighLimit = isset($matches[9])?$matches[9]:''; + /* Start Block: Fields list */ + $count = preg_match_all('/\s*(\*|[\w\.]+)(?:\s+AS\s+([\w\.]+))?/im',$sqlColumns,$match,PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $fieldsList = array(); + for($r=0; $r< $count;$r++) { + $name = (is_array($match[2][$r]) && $match[2][$r][0]!=='') ? $match[2][$r][0] : $match[1][$r][0]; + $fieldsList[$name] = $match[1][$r][0]; + } + /* End Block */ + /* Start Block: Order list */ + $count=preg_match_all('/\s*(\*|[\w\.]+)(\s+ASC|\s+DESC)?\s*,?/im',$sqlOrderBy,$match,PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $orderList = array(); + for($r = $count-1; $r>=0; $r--) { + $direction = (is_array($match[2][$r]) && $match[2][$r][0]!=='') ? $match[2][$r][0] : 'ASC'; + $direction = strtoupper( $direction ); + $orderList[$match[1][$r][0]] = $direction; + } + /* End Block */ + $xmlFrom = '/' . str_replace( '.','/' , $sqlFrom ); + $node =& $this->xmldoc->findNode( $xmlFrom ); + if (!isset($node)) { + //$err = new DB_Error( "$xmlFrom node not found in $dsn." ); + throw new Exception( "$xmlFrom node not found in " . $this->xmlFile . "." ); + return $err; + } else { + $res = $this->fetchChildren ( $node ); + } + /* Start Block: WHERE*/ + if ($sqlWhere!=='') { + /*Start Block: Replace the operator */ + $blocks = preg_split('/("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', $sqlWhere , -1 , PREG_SPLIT_DELIM_CAPTURE ); + $sqlWhere = ''; + for($r = 0 ; $r < sizeof($blocks) ; $r++ ){ + if ( ($r % 2) === 0 ) { + $blocks[$r] = str_replace( '=' , '==', $blocks[$r]); + $blocks[$r] = str_replace( '<>' , '!=', $blocks[$r]); + $blocks[$r] = str_replace( 'AND' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'and' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'OR' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'or' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'NOT' , '!', $blocks[$r]); + $blocks[$r] = str_replace( 'not' , '!', $blocks[$r]); + $blocks[$r] = preg_replace('/\b[a-zA-Z_][\w\.]*\b/im', '$res[$r][\'$0\']', $blocks[$r] ); + $blocks[$r] = preg_replace('/\$res\[\$r\]\[\'(like)\'\]/im', '$1', $blocks[$r] ); + } + $sqlWhere .= $blocks[$r]; + } + $sqlWhere = preg_replace_callback('/(.+)\s+like\s+("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', + array('XMLConnection','sqlWhereLike'), $sqlWhere ); + $sqlWhere = preg_replace_callback('/"(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'/im', + array('XMLConnection','sqlString'), $sqlWhere ); + $newRes = array(); + for( $r=0 ; $r < sizeof($res) ; $r++ ) { + $evalWhere = false; + @eval('$evalWhere = '.$sqlWhere.';'); + if ( $evalWhere ) $newRes[] = $res[$r]; + } + $res = $newRes; + } + /* End Block */ + /* Start Block: Expands the resultant data according to fill an array + * with the required fields in the query. + */ + for( $r=0 ; $r < sizeof($res) ; $r++ ) { + $res[$r] = $this->expandFields( $res[$r] , $fieldsList ); + } + /* End Block */ + /* Start Block: ORDER BY*/ + foreach($orderList as $field => $direction ) { + for( $i=0 ; $i < sizeof($res) ; $i++ ) { + for( $j= $i+1 ; $j < sizeof($res) ; $j++ ) { + $condition = ($direction==='ASC')? + ($res[$j] < $res[$i]) : ($res[$j] > $res[$i]); + if ( $condition ) { + $swap = $res[$i]; + $res[$i] = $res[$j]; + $res[$j] = $swap; + } + } + } + } + /* End Block */ + /* Start Block: Apply limits */ + if ($sqlLowLimit!='' && $sqlHighLimit!='') + { + $sqlLowLimit = (int) $sqlLowLimit; + $sqlHighLimit = (int) $sqlHighLimit; + $res = array_slice( $res , $sqlLowLimit , $sqlHighLimit ); + } + /* End Block */ + $result = new XMLResult( $res ); + return $result; + } + elseif (1===preg_match('/^\s*DELETE\s+FROM\s+`?([^`]+?)`?(?:\s+WHERE\s+([\w\W]+?))?\s*$/im',$sql,$matches)) + { + $sqlFrom = isset($matches[1])?$matches[1]:''; + $sqlWhere = isset($matches[2])?$matches[2]:'1'; + /* Start Block: WHERE*/ + /*Start Block: Replace the operator */ + $blocks = preg_split('/("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', $sqlWhere , -1 , PREG_SPLIT_DELIM_CAPTURE ); + $sqlWhere = ''; + for($r = 0 ; $r < sizeof($blocks) ; $r++ ){ + if ( ($r % 2) === 0 ) { + $blocks[$r] = str_replace( '=' , '==', $blocks[$r]); + $blocks[$r] = str_replace( '<>' , '!=', $blocks[$r]); + $blocks[$r] = str_replace( 'AND' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'and' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'OR' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'or' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'NOT' , '!', $blocks[$r]); + $blocks[$r] = str_replace( 'not' , '!', $blocks[$r]); + $blocks[$r] = preg_replace('/\b[a-zA-Z_][\w\.]*\b/im', '$res[$r][\'$0\']', $blocks[$r] ); + $blocks[$r] = preg_replace('/\$res\[\$r\]\[\'(like)\'\]/im', '$1', $blocks[$r] ); + } + $sqlWhere .= $blocks[$r]; + } + /* End Block */ + $sqlWhere = preg_replace_callback('/(.+)\s+like\s+("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', + array('XMLConnection','sqlWhereLike'), $sqlWhere ); + $sqlWhere = preg_replace_callback('/"(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'/im', + array('XMLConnection','sqlString'), $sqlWhere ); + + /*Start Block: Removing fields */ + $xmlFrom = '/' . str_replace( '.','/' , $sqlFrom ); + $node =& $this->xmldoc->findNode( $xmlFrom ); + if (!isset($node)) { + $err = new DB_Error( "$xmlFrom node not found!." ); + return $err; + } else { + $res = $this->fetchChildren ( $node ); + } + $newRes = array(); + for( $r=0 ; $r < sizeof($res) ; $r++ ) { + $evalWhere = false; + @eval('$evalWhere = '.$sqlWhere.';'); + if ( $evalWhere ) { + unset($node->children[$r]); + $newRes[] = $res[$r]; + } + } + //Re-index + $node->children = array_values( $node->children ); + /* End Block */ + $this->xmldoc->save( $this->xmlFile ); + $result = new XMLResult( $newRes ); + return $result; + } + elseif (1===preg_match('/^\s*INSERT\s+INTO\s+`?([^`]+?)`?\s*\(([\w\W]+?)\)\s+VALUES\s*\(([\w\W]+?)\)\s*$/im',$sql,$matches)) + { + $sqlFrom = isset($matches[1])?$matches[1]:''; + $sqlColumns = isset($matches[2])?$matches[2]:'1'; + $sqlValues = isset($matches[3])?$matches[3]:'1'; + $xmlFrom = '/' . str_replace( '.','/' , $sqlFrom ); + $node =& $this->xmldoc->findNode( $xmlFrom ); + /* Start Block: Fields list */ + $count = preg_match_all('/([\w\.]+)/im',$sqlColumns,$match,PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $fieldsList = array(); + for($r=0; $r< $count;$r++) { + $fieldsList[] = $match[1][$r][0]; + } + /* End Block */ + /* Start Block: Fields Values */ + $count=preg_match_all('/("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'|\d+)/im', $sqlValues,$match,PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $fieldsValues = array(); + for($r=0; $r< $count;$r++) { + if (substr($match[1][$r][0],0,1)==='"') { + $match[1][$r][0] = substr( $match[1][$r][0] ,1, -1 ); + $match[1][$r][0] = str_replace('""', '"' , $match[1][$r][0] ); + $match[1][$r][0] = str_replace("''", "'" , $match[1][$r][0] ); + } if (substr($match[1][$r][0],0,1)==="'") { + $match[1][$r][0] = substr( $match[1][$r][0] ,1, -1 ); + $match[1][$r][0] = str_replace("''", "'" , $match[1][$r][0] ); + $match[1][$r][0] = str_replace('""', '"' , $match[1][$r][0] ); + } + $fieldsValues[$fieldsList[$r]] = $match[1][$r][0]; + } + /* End Block */ + $AAA = getNames($this->xmldoc->children[0]->children); + $this->insertRow( $node , $fieldsValues ); + $DDD = getNames($this->xmldoc->children[0]->children); + $this->xmldoc->save( $this->xmlFile ); + $result = new XMLResult( array( $fieldsValues ) ); + return $result; + } + elseif (1===preg_match('/^\s*UPDATE\s+`?([^`]+?)`?\s+SET\s+((?:(?:[a-z][\w\.]*)\s*=\s*(?:"(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'|\d+)\s*(?:,\s*)?)+)(?:\s+WHERE\s+([\w\W]+?))?\s*$/im',$sql,$matches)) + { + $sqlFrom = isset($matches[1])?$matches[1]:''; + $sqlColumns = isset($matches[2])?$matches[2]:''; + $sqlWhere = isset($matches[3])?$matches[3]:'1'; + $count = preg_match_all('/([a-z][\w\.]*)\s*=\s*("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'|\d+)/im',$sqlColumns,$match,PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $fieldsValues = array(); + for($r=0; $r< $count;$r++) { + if (substr($match[2][$r][0],0,1)==='"') { + $match[2][$r][0] = substr( $match[2][$r][0] ,1, -1 ); + $match[2][$r][0] = str_replace('""', '"' , $match[2][$r][0] ); + $match[2][$r][0] = str_replace("''", "'" , $match[2][$r][0] ); + } if (substr($match[2][$r][0],0,1)==="'") { + $match[2][$r][0] = substr( $match[2][$r][0] ,1, -1 ); + $match[2][$r][0] = str_replace("''", "'" , $match[2][$r][0] ); + $match[2][$r][0] = str_replace('""', '"' , $match[2][$r][0] ); + } + $fieldsValues[$match[1][$r][0]] = $match[2][$r][0]; + } + /* Start Block: WHERE*/ + /*Start Block: Replace the operator */ + $blocks = preg_split('/("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', $sqlWhere , -1 , PREG_SPLIT_DELIM_CAPTURE ); + $sqlWhere = ''; + for($r = 0 ; $r < sizeof($blocks) ; $r++ ){ + if ( ($r % 2) === 0 ) { + $blocks[$r] = str_replace( '=' , '==', $blocks[$r]); + $blocks[$r] = str_replace( '<>' , '!=', $blocks[$r]); + $blocks[$r] = str_replace( 'AND' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'and' , '&&', $blocks[$r]); + $blocks[$r] = str_replace( 'OR' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'or' , '||', $blocks[$r]); + $blocks[$r] = str_replace( 'NOT' , '!', $blocks[$r]); + $blocks[$r] = str_replace( 'not' , '!', $blocks[$r]); + $blocks[$r] = preg_replace('/\b[a-zA-Z_][\w\.]*\b/im', '$res[$r][\'$0\']', $blocks[$r] ); + $blocks[$r] = preg_replace('/\$res\[\$r\]\[\'(like)\'\]/im', '$1', $blocks[$r] ); + } + $sqlWhere .= $blocks[$r]; + } + /* End Block */ + $sqlWhere = preg_replace_callback('/(.+)\s+like\s+("(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\')/im', + array('XMLConnection','sqlWhereLike'), $sqlWhere ); + $sqlWhere = preg_replace_callback('/"(?:(?:[^"]|"")*)"|\'(?:(?:[^\']|\'\')*)\'/im', + array('XMLConnection','sqlString'), $sqlWhere ); + /*Start Block: Removing fields */ + $xmlFrom = '/' . str_replace( '.','/' , $sqlFrom ); + $node =& $this->xmldoc->findNode( $xmlFrom ); + if (!isset($node)) { + $err = new DB_Error( "$xmlFrom node not found in $dsn." ); + return $err; + } else { + $res = $this->fetchChildren ( $node ); + } + $newRes = array(); + for( $r=0 ; $r < sizeof($res) ; $r++ ) { + $evalWhere = false; + @eval('$evalWhere = '.$sqlWhere.';'); + if ( $evalWhere ) { + $this->updateRow( $node->children[$r] , $fieldsValues ); + $newRes[] = array_merge( $res[$r] , $fieldsValues ); + } + } + /* End Block */ + $nodeTEST =& $this->xmldoc->findNode( $xmlFrom ); + $this->xmldoc->save( $this->xmlFile ); + $result = new XMLResult( $newRes ); + return $result; + } + else + { + echo($sql); + $err = new DB_Error( "SQL Query is not well formed." ); + return $err; + } + } + + /** + * sqlLike + * + * @param string $a + * @return void $b + */ + function sqlLike( $a , $b ) + { + $b = addcslashes( $b , '[]()\/{}.?' ); + $b = str_replace( "%" , '.*' , $b ); + $b = '/^'. $b . '$/im'; + return preg_match( $b , $a ); + } + + /** + * expandFields + * + * @param string $resRow + * @param string $fieldsList + * @return array $res + */ + function expandFields( $resRow, $fieldsList ) + { + $res = array(); + foreach($fieldsList as $key => $value ) { + if ($key==='*') { + foreach( $resRow as $k => $v ) $res[$k] = $v; + } else { + $res[$key] = array_key_exists( $value , $resRow ) ? $resRow[$value] : NULL; + } + } + return $res; + } + + /** + * fetchNode + * + * @param object &$node + * @return array $res + */ + function fetchNode( &$node ) + { + $res = array ( + 'XMLNODE_NAME' => $node->name, + 'XMLNODE_TYPE' => $node->type, + 'XMLNODE_VALUE' => $node->value, + ); + foreach( $node->attributes as $name => $value ) { + if ($this->caseFolding) $name = strtoupper( $name ); + $res[$name] = $value; + } + return $res; + } + + /** + * fetchChildren + * + * @param string &$node + * @return array $res + */ + function fetchChildren( &$node ) + { + $res = array(); + foreach( $node->children as $name => $child ) { + $res[] = $this->fetchNode( $child ); + } + return $res; + } + + /** + * disconnect + * + * @return void + */ + function disconnect() + { + unset( $this->xmldoc ); + } + + /** + * + * + * @param array $match + * @return object(DB_Error) $err + */ + function sqlWhereLike( $match ) + { + switch (substr($match[2],0,1)) { + case '"': + return ' $this->sqlLike( '.$match[1].', '.$match[2].' ) '; + break; + case "'": + return ' $this->sqlLike( '.$match[1].', '.$match[2].' ) '; + break; + default: + $err = new DB_Error( "XMLDB: Syntax error on $match[0]" ); + die; + return $err; + } + } + + /** + * sqlString + * + * @param array $match + * @return object(DB_Error) $err + */ + function sqlString( $match ) + { + switch (substr($match[0],0,1)) { + case '"': + $match[0] = substr( $match[0] ,1, -1 ); + $match[0] = str_replace('""', '"' , $match[0] ); + $match[0] = str_replace("''", "'" , $match[0] ); + $match[0] = addcslashes( $match[0] , '\\\'' ); + return "'$match[0]'"; + break; + case "'": + $match[0] = substr( $match[0] ,1, -1 ); + $match[0] = str_replace("''", "'" , $match[0] ); + $match[0] = str_replace('""', '"' , $match[0] ); + $match[0] = addcslashes( $match[0] , '\\\'' ); + return "'$match[0]'"; + break; + default: + $err = new DB_Error( "XMLDB: Syntax error on $match[0]" ); + die; + return $err; + } + } + + /** + * insertRow + * + * @param string &$node + * @param object $values + * @return void + */ + function insertRow( &$node , $values ) + { + $attributes = array(); + foreach( $values as $field => $value ) { + switch( $field ) { + case 'XMLNODE_NAME' : + case 'XMLNODE_TYPE' : + case 'XMLNODE_VALUE': + break; + default: + $attributes[strtolower($field)] = $value; + } + } + $values['XMLNODE_NAME'] = !isset($values['XMLNODE_NAME']) ? + '': $values['XMLNODE_NAME']; + $values['XMLNODE_TYPE'] = !isset($values['XMLNODE_TYPE']) ? + 'open': $values['XMLNODE_TYPE']; + $values['XMLNODE_VALUE'] = !isset($values['XMLNODE_VALUE']) ? + '': $values['XMLNODE_VALUE']; + $node->addChildNode( new Xml_Node( + $values['XMLNODE_NAME'] , $values['XMLNODE_TYPE'] , $values['XMLNODE_VALUE'], $attributes ) ); + } + + /** + * updateRow + * + * @param string &$node + * @param object $values + * @return void + */ + function updateRow( &$node , $values ) + { + foreach( $values as $field => $value ) { + switch( $field ) { + case 'XMLNODE_NAME' : + $node->name = $value; + break; + case 'XMLNODE_TYPE' : + $node->type = $value; + break; + case 'XMLNODE_VALUE': + $node->value = $value; + break; + default: + $node->attributes[strtolower($field)] = $value; + } + } + } +} + +/** +* XMLResult +* +* ProcessMaker Open Source Edition +* +* @copyright (C) 2004 - 2008 Colosa Inc.23 +*/ +class XMLResult +{ + var $result = array(); + var $cursor = 0; + + /** + * XMLResult + * + * @param array $result + * @return void + */ + function XMLResult( $result = array() ) + { + $this->result = $result; + $this->cursor = 0; + } + + /** + * numRows + * + * @return integer sizeof($this->result) + */ + function numRows() + { + return sizeof($this->result); + } + + /** + * fetchRow + * + * @param string $const + * @return integer $this->result[ $this->cursor-1 ]; + */ + function fetchRow ( $const ) + { + if ($this->cursor>=$this->numRows()) + return NULL; + $this->cursor++; + return $this->result[ $this->cursor-1 ]; + } +} + + /** + * getNames + * + * @param object $children + * @return array $names + */ + function getNames( $children ) + { + $names = array(); + $r = 0; + foreach($children as $child) { + $names[$r]=$child->name; + $r++; + } + return $names; + } + +?> \ No newline at end of file diff --git a/workflow/engine/classes/class.xmlfield_Image.php b/workflow/engine/classes/class.xmlfield_Image.php new file mode 100644 index 000000000..20af84733 --- /dev/null +++ b/workflow/engine/classes/class.xmlfield_Image.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +// DEPRECATED this class is also part of the xmlform package this class will be also removed +// in future releases of pm, its discouraged the inclusion this class in the future from a +// external file like this +class XmlForm_Field_Image extends XmlForm_Field +{ + var $file = ''; + var $home = 'public_html'; + var $withoutLabel = false; + function render( $value, $owner = null ) + { + $url = G::replaceDataField($this->file, $owner->values); + if ($this->home === "methods") $url = G::encryptlink( SYS_URI . $url ); + if ($this->home === "public_html") $url ='/' . $url ; + return 'style)?'style="'.$this->style.'"':'') + .' alt ="'.htmlentities($value,ENT_QUOTES,'utf-8').'"/>'; + } + } +?> \ No newline at end of file diff --git a/workflow/engine/classes/class.xmlfield_InputPM.php b/workflow/engine/classes/class.xmlfield_InputPM.php new file mode 100644 index 000000000..4690d9149 --- /dev/null +++ b/workflow/engine/classes/class.xmlfield_InputPM.php @@ -0,0 +1,463 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +class XmlForm_Field_TextPM extends XmlForm_Field_SimpleText +{ + var $size=15; + var $maxLength=64; + var $validate='Any'; + var $mask = ''; + var $defaultValue=''; + var $required=false; + var $dependentFields=''; + var $linkField=''; +//Possible values:(-|UPPER|LOWER|CAPITALIZE) + var $strTo=''; + var $readOnly=false; + var $sqlConnection=0; + var $sql=''; + var $sqlOption=array(); + //Atributes only for grids + var $formula = ''; + var $function = ''; + var $replaceTags = 0; + var $showVars = 0; + var $process = ''; + var $symbol = '@@'; + + /** + * Function render + * @author Julio Cesar Laura Avendano + * @access public + * @parameter string value + * @parameter string owner + * @return string + */ + function render( $value = NULL , $owner = NULL ) + { + //$this->executeSQL(); + //if (isset($this->sqlOption)) { + // reset($this->sqlOption); + // $firstElement=key($this->sqlOption); + // if (isset($firstElement)) $value = $firstElement; + //} + //NOTE: string functions must be in G class + if ($this->strTo==='UPPER') + $value = strtoupper($value); + if ($this->strTo==='LOWER') + $value = strtolower($value); + //if ($this->strTo==='CAPITALIZE') $value = strtocapitalize($value); + $onkeypress = G::replaceDataField( $this->onkeypress, $owner->values ); + if ($this->replaceTags == 1) { + $value = G::replaceDataField( $value, $owner->values ); + } + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + //$sShowVars = ' ' . $this->symbol . ''; + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' readOnly="readOnly" style="'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . $sShowVars; + else + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' style="'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . $sShowVars; + } elseif ($this->mode==='view') { + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' style="display:none;'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . + $this->htmlentities( $value , ENT_COMPAT, 'utf-8'); + } else { + return $this->htmlentities( $value , ENT_COMPAT, 'utf-8'); + } + } + + /** + * Function renderGrid + * @author Julio Cesar Laura Avendano + * @access public + * @parameter array values + * @parameter string owner + * @return string + */ + function renderGrid( $values=array() , $owner ) + { + $result=array(); + $r=1; + foreach($values as $v) { + if ($this->replaceTags == 1) { + $v = G::replaceDataField( $v, $owner->values ); + } + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + //$sShowVars = ' ' . $this->symbol . ''; + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + $result[] = '' . $sShowVars; + else + $result[] = '' . $sShowVars; + } elseif ($this->mode==='view') { + $result[] = $this->htmlentities( $v , ENT_COMPAT, 'utf-8'); + } else { + $result[] = $this->htmlentities( $v , ENT_COMPAT, 'utf-8'); + } + $r++; + } + return $result; + } + + /** + * Function attachEvents + * @access public + * @parameter string $element + * @return string + */ + function attachEvents($element) + { + return "myForm.aElements[i] = new G_Text(myForm, $element,'{$this->name}'); + myForm.aElements[i].setAttributes(" . $this->getAttributes() . ");"; + } +} + +/** + * Class XmlForm_Field_TextareaPM + */ +class XmlForm_Field_TextareaPM extends XmlForm_Field +{ + var $rows = 12; + var $cols = 40; + var $required = false; + var $readOnly = false; + var $wrap = 'OFF'; + var $showVars = 0; + var $process = ''; + var $symbol = '@@'; + + /** + * Function render + * @author Julio Cesar Laura Avendao + * @access public + * @parameter string value + * @parameter string owner + * @return string + */ + function render( $value = NULL, $owner ) + { + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + return '' . $sShowVars; + else + return '' . $sShowVars; + } elseif ($this->mode==='view') { + return ''; + } else { + return ''; + } + } + + /** + * Function renderGrid + * @author Julio Cesar Laura Avendano + * @access public + * @parameter string values + * @parameter string owner + * @return string + */ + function renderGrid( $values = NULL , $owner ) + { + $result=array(); + $r=1; + foreach($values as $v) { + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + //$sShowVars = ' ' . $this->symbol . ''; + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + $result[] = 'htmlentities( $v , ENT_COMPAT, 'utf-8').'\' readOnly="readOnly"/>' . $sShowVars; + else + $result[] = 'htmlentities( $v , ENT_COMPAT, 'utf-8').'\' />' . $sShowVars; + } elseif ($this->mode==='view') { + if(stristr($_SERVER['HTTP_USER_AGENT'], 'iPhone')){ + //$result[] = '
    '.$this->htmlentities( $v , ENT_COMPAT, 'utf-8').'
    '; + $result[] = $this->htmlentities( $v , ENT_COMPAT, 'utf-8'); + } + else{ + //$result[] = '
    '.$this->htmlentities( $v , ENT_COMPAT, 'utf-8').'
    '; + $result[] = $this->htmlentities( $v , ENT_COMPAT, 'utf-8'); + } + } else{ + $result[] = $this->htmlentities( $v , ENT_COMPAT, 'utf-8'); + } + $r++; + } + return $result; + } +} + +/** + * Class XmlForm_Field_hours + */ +class XmlForm_Field_hours extends XmlForm_Field_SimpleText +{ + var $size = 15; + var $maxLength = 64; + var $validate = 'Any'; + var $mask = ''; + var $defaultValue = ''; + var $required = false; + var $dependentFields= ''; + var $linkField = ''; +//Possible values:(-|UPPER|LOWER|CAPITALIZE) + var $strTo = ''; + var $readOnly = false; + var $sqlConnection = 0; + var $sql = ''; + var $sqlOption = array(); + //Atributes only for grids + var $formula = ''; + var $function = ''; + var $replaceTags = 0; + var $showVars = 0; + var $process = ''; + var $symbol = '@@'; + + /** + * Function render + * @author Julio Cesar Laura Avendano + * @access public + * @parameter string value + * @parameter string owner + * @return string + */ + function render( $value = NULL , $owner = NULL ) + { + if ($this->strTo==='UPPER') + $value = strtoupper($value); + if ($this->strTo==='LOWER') + $value = strtolower($value); + //if ($this->strTo==='CAPITALIZE') $value = strtocapitalize($value); + $onkeypress = G::replaceDataField( $this->onkeypress, $owner->values ); + if ($this->replaceTags == 1) { + $value = G::replaceDataField( $value, $owner->values ); + } + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + //$sShowVars = ' ' . $this->symbol . ''; + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' readOnly="readOnly" style="'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . $sShowVars; + else + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' style="'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . $sShowVars; + } elseif ($this->mode==='view') { + return 'htmlentities( $value , ENT_COMPAT, 'utf-8').'\' style="display:none;'.htmlentities( $this->style , ENT_COMPAT, 'utf-8').'" onkeypress="'.htmlentities( $onkeypress , ENT_COMPAT, 'utf-8').'"/>' . + $this->htmlentities( $value , ENT_COMPAT, 'utf-8'); + } else { + return $this->htmlentities( $value , ENT_COMPAT, 'utf-8'); + } + } + + /** + * Function renderGrid + * @author Julio Cesar Laura Avendano + * @access public + * @parameter array values + * @parameter string owner + * @return string + */ + function renderGrid( $values=array() , $owner ) + { + $result=array(); + $r=1; + foreach($values as $v) { + if ($this->replaceTags == 1) { + $v = G::replaceDataField( $v, $owner->values ); + } + if ($this->showVars == 1) { + $this->process = G::replaceDataField($this->process, $owner->values ); + //$sShowVars = ' ' . $this->symbol . ''; + $sShowVars = ' '; + } + else { + $sShowVars = ''; + } + if ($this->mode==='edit') { + if ($this->readOnly) + $result[] = '' . $sShowVars; + else + $result[] = '' . $sShowVars; + } elseif ($this->mode==='view') { + $result[] = '

    '.$this->htmlentities( number_format($v, 2), ENT_COMPAT, 'utf-8').'

    '; + } else { + $result[] = '

    '.$this->htmlentities( number_format($v, 2), ENT_COMPAT, 'utf-8').'

    '; + } + $r++; + } + return $result; + } + + /** + * Function attachEvents + * @access public + * @parameter string $element + * @return string + */ + function attachEvents($element) + { + return "myForm.aElements[i] = new G_Text(myForm, $element,'{$this->name}'); + myForm.aElements[i].setAttributes(" . $this->getAttributes() . ");"; + } +} + + /** + * Function getDynaformsVars + * @access public + * @parameter string $sProcessUID + * @parameter boolean $bSystemVars + * @return array + */ + function getDynaformsVars($sProcessUID, $bSystemVars = true) + { + $aFields = array(); + $aFieldsNames = array(); + if ($bSystemVars) { + $aAux = G::getSystemConstants(); + foreach ($aAux as $sName => $sValue) { + $aFields[] = array('sName' => $sName, 'sType' => 'system', 'sLabel'=> 'System variable'); + } + } + require_once 'classes/model/Dynaform.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(DynaformPeer::DYN_FILENAME); + $oCriteria->add(DynaformPeer::PRO_UID, $sProcessUID); + $oCriteria->add(DynaformPeer::DYN_TYPE, 'xmlform'); + $oDataset = DynaformPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + if (file_exists(PATH_DYNAFORM . PATH_SEP . $aRow['DYN_FILENAME'] . '.xml')) { + $G_FORM = new Form($aRow['DYN_FILENAME'], PATH_DYNAFORM, SYS_LANG); + if (($G_FORM->type == 'xmlform') || ($G_FORM->type == '')) { + foreach($G_FORM->fields as $k => $v) { + if (($v->type != 'title') && ($v->type != 'subtitle') && ($v->type != 'link') && + ($v->type != 'file') && ($v->type != 'button') && ($v->type != 'reset') && + ($v->type != 'submit') && ($v->type != 'listbox') && ($v->type != 'checkgroup') && + ($v->type != 'grid') && ($v->type != 'javascript')) { + if (!in_array($k, $aFieldsNames)) { + $aFields[] = array('sName' => $k, + 'sType' => $v->type, + 'sLabel'=> $v->label + ); + $aFieldsNames[] = $k; + } + } + } + } + } + $oDataset->next(); + } + return $aFields; + } + + /** + * Function getGridsVars + * @access public + * @parameter string $sProcessUID + * @return array + */ + function getGridsVars($sProcessUID) + { + $aFields = array(); + $aFieldsNames = array(); + require_once 'classes/model/Dynaform.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(DynaformPeer::DYN_FILENAME); + $oCriteria->add(DynaformPeer::PRO_UID, $sProcessUID); + $oDataset = DynaformPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $G_FORM = new Form($aRow['DYN_FILENAME'], PATH_DYNAFORM, SYS_LANG); + if ($G_FORM->type == 'xmlform') { + foreach($G_FORM->fields as $k => $v) { + if ($v->type == 'grid') { + if (!in_array($k, $aFieldsNames)) { + $aFields[] = array('sName' => $k, 'sXmlForm' => str_replace($sProcessUID . '/', '', $v->xmlGrid)); + $aFieldsNames[] = $k; + } + } + } + } + $oDataset->next(); + } + return $aFields; + } + +/** + * Class XmlForm_Field_CheckBoxTable + */ +class XmlForm_Field_CheckBoxTable extends XmlForm_Field_Checkbox +{ + /** + * Function render + * @author The Answer + * @access public + * @parameter string value + * @parameter string owner + * @return string + */ + function render( $value = NULL , $owner = NULL ) + { + //$optionName = $owner->values['USR_UID']; + $optionName = $value; + $onclick = (($this->onclick)? ' onclick="' . G::replaceDataField( $this->onclick, $owner->values ) . '" ' : ''); + $html =' '; + return $html; + } +} +?> \ No newline at end of file diff --git a/workflow/engine/classes/model/AdditionalTables.php b/workflow/engine/classes/model/AdditionalTables.php new file mode 100644 index 000000000..f31c85b4f --- /dev/null +++ b/workflow/engine/classes/model/AdditionalTables.php @@ -0,0 +1,1123 @@ + + * @package classes.model + */ +class AdditionalTables extends BaseAdditionalTables { + public function load($sUID, $bFields = false) { + try { + $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($sUID); + if (!is_null($oAdditionalTables)) { + $aFields = $oAdditionalTables->toArray(BasePeer::TYPE_FIELDNAME); + if ($bFields) { + require_once 'classes/model/Fields.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(FieldsPeer::FLD_UID); + $oCriteria->addSelectColumn(FieldsPeer::FLD_INDEX); + $oCriteria->addSelectColumn(FieldsPeer::FLD_NAME); + $oCriteria->addSelectColumn(FieldsPeer::FLD_DESCRIPTION); + $oCriteria->addSelectColumn(FieldsPeer::FLD_TYPE); + $oCriteria->addSelectColumn(FieldsPeer::FLD_SIZE); + $oCriteria->addSelectColumn(FieldsPeer::FLD_NULL); + $oCriteria->addSelectColumn(FieldsPeer::FLD_AUTO_INCREMENT); + $oCriteria->addSelectColumn(FieldsPeer::FLD_KEY); + $oCriteria->addSelectColumn(FieldsPeer::FLD_FOREIGN_KEY); + $oCriteria->addSelectColumn(FieldsPeer::FLD_FOREIGN_KEY_TABLE); + $oCriteria->add(FieldsPeer::ADD_TAB_UID, $sUID); + $oCriteria->addAscendingOrderByColumn(FieldsPeer::FLD_INDEX); + $oDataset = FieldsPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aFields['FIELDS'] = array(); + $i = 1; + while ($aRow = $oDataset->getRow()) { + $aFields['FIELDS'][$i] = $aRow; + $oDataset->next(); + $i++; + } + } + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + +public function loadByName($name) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_UID); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_NAME); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_CLASS_NAME); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_DESCRIPTION); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_PLG_UID); + $oCriteria->addSelectColumn(AdditionalTablesPeer::DBS_UID); + $oCriteria->add(AdditionalTablesPeer::ADD_TAB_NAME, $name, Criteria::LIKE); + + $oDataset = FieldsPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while( $oDataset->next() ){ + $aRows[] = $oDataset->getRow(); + } + + return (sizeof($aRows) > 0)? $aRows: false; + } + catch (Exception $oError) { + throw($oError); + } + } + + function create($aData, $aFields = array()) { + if (!isset($aData['ADD_TAB_UID'])) { + $aData['ADD_TAB_UID'] = G::generateUniqueID(); + } + else { + if ($aData['ADD_TAB_UID'] == '') { + $aData['ADD_TAB_UID'] = G::generateUniqueID(); + } + } + $oConnection = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + try { + $oAdditionalTables = new AdditionalTables(); + $oAdditionalTables->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAdditionalTables->validate()) { + $oConnection->begin(); + $iResult = $oAdditionalTables->save(); + $oConnection->commit(); + require_once 'classes/model/ShadowTable.php'; + $oShadowTable = new ShadowTable(); + $oShadowTable->create(array('ADD_TAB_UID' => $aData['ADD_TAB_UID'], + 'SHD_ACTION' => 'CREATE', + 'SHD_DETAILS' => serialize($aFields), + 'USR_UID' => (isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : ''), + 'APP_UID' => '', + 'SHD_DATE' => date('Y-m-d H:i:s'))); + return $aData['ADD_TAB_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oAdditionalTables->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '
    '; + } + throw(new Exception('The registry cannot be created!
    ' . $sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function update($aData, $aFields = array()) { + $oConnection = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + try { + $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($aData['ADD_TAB_UID']); + if (!is_null($oAdditionalTables)) { + $oAdditionalTables->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAdditionalTables->validate()) { + $oConnection->begin(); + $iResult = $oAdditionalTables->save(); + $oConnection->commit(); + require_once 'classes/model/ShadowTable.php'; + $oShadowTable = new ShadowTable(); + $oShadowTable->create(array('ADD_TAB_UID' => $aData['ADD_TAB_UID'], + 'SHD_ACTION' => 'ALTER', + 'SHD_DETAILS' => serialize($aFields), + 'USR_UID' => (isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : ''), + 'APP_UID' => '', + 'SHD_DATE' => date('Y-m-d H:i:s'))); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oAdditionalTables->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '
    '; + } + throw(new Exception('The registry cannot be updated!
    '.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function remove($sUID) { + $oConnection = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + try { + $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($sUID); + if (!is_null($oAdditionalTables)) { + $aAdditionalTables = $oAdditionalTables->toArray(BasePeer::TYPE_FIELDNAME); + $oConnection->begin(); + $iResult = $oAdditionalTables->delete(); + $oConnection->commit(); + require_once 'classes/model/ShadowTable.php'; + if ($aAdditionalTables['ADD_TAB_SDW_AUTO_DELETE'] == 1) { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ShadowTablePeer::ADD_TAB_UID, $sUID); + ShadowTablePeer::doDelete($oCriteria); + } + else { + $oShadowTable = new ShadowTable(); + $oShadowTable->create(array('ADD_TAB_UID' => $sUID, + 'SHD_ACTION' => 'DROP', + 'SHD_DETAILS' => '', + 'USR_UID' => (isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : ''), + 'APP_UID' => '', + 'SHD_DATE' => date('Y-m-d H:i:s'))); + } + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function createTable($sTableName, $sConnection = 'wf', $aFields = array()) { + $sTableName = $sTableName; + if ($sConnection == '') { + $sConnection = 'wf'; + } + $sDBName = 'DB' . ($sConnection != 'wf' ? '_' . strtoupper($sConnection) : '') . '_NAME'; + $sDBHost = 'DB' . ($sConnection != 'wf' ? '_' . strtoupper($sConnection) : '') . '_HOST'; + $sDBUser = 'DB' . ($sConnection != 'wf' ? '_' . strtoupper($sConnection) : '') . '_USER'; + $sDBPass = 'DB' . ($sConnection != 'wf' ? '_' . strtoupper($sConnection) : '') . '_PASS'; + try { + switch (DB_ADAPTER) { + case 'mysql': + eval('$oConnection = @mysql_connect(' . $sDBHost . ', ' . $sDBUser . ', ' . $sDBPass . ');'); + if (!$oConnection) { + throw new Exception('Cannot connect to the server!'); + } + eval("if (!@mysql_select_db($sDBName)) { + throw new Exception('Cannot connect to the database ' . $sDBName . '!'); + }"); + $sQuery = 'CREATE TABLE IF NOT EXISTS `' . $sTableName . '` ('; + $aPKs = array(); + foreach ($aFields as $aField) { + switch ($aField['sType']) { + case 'VARCHAR': + $sQuery .= '`' . $aField['sFieldName'] . '` ' . $aField['sType'] . '(' . $aField['iSize'] . ')' . " " . ($aField['bNull'] ? 'NULL' : 'NOT NULL') . " DEFAULT '',"; + break; + case 'TEXT': + $sQuery .= '`' . $aField['sFieldName'] . '` ' . $aField['sType'] . " " . ($aField['bNull'] ? 'NULL' : 'NOT NULL') . " DEFAULT '',"; + break; + case 'DATE': + $sQuery .= '`' . $aField['sFieldName'] . '` ' . $aField['sType'] . " " . ($aField['bNull'] ? 'NULL' : 'NOT NULL') . " DEFAULT '0000-00-00',"; + break; + case 'INT': + $sQuery .= '`' . $aField['sFieldName'] . '` ' . $aField['sType'] . '(' . $aField['iSize'] . ')' . " " . ($aField['bNull'] ? 'NULL' : 'NOT NULL') . ' ' . ($aField['bAI'] ? 'AUTO_INCREMENT' : "DEFAULT '0'") . ','; + if ($aField['bAI']) { + if (!in_array('`' . $aField['sFieldName'] . '`', $aPKs)) { + $aPKs[] = '`' . $aField['sFieldName'] . '`'; + } + } + break; + case 'FLOAT': + $sQuery .= '`' . $aField['sFieldName'] . '` ' . $aField['sType'] . '(' . $aField['iSize'] . ')' . " " . ($aField['bNull'] ? 'NULL' : 'NOT NULL') . " DEFAULT '0',"; + break; + } + if ($aField['bPrimaryKey'] == 1) { + if (!in_array('`' . $aField['sFieldName'] . '`', $aPKs)) { + $aPKs[] = '`' . $aField['sFieldName'] . '`'; + } + } + } + $sQuery = substr($sQuery, 0, -1); + if (!empty($aPKs)) { + $sQuery .= ',PRIMARY KEY (' . implode(',', $aPKs) . ')'; + } + $sQuery .= ') DEFAULT CHARSET=utf8;'; + if (!@mysql_query($sQuery)) { + throw new Exception('Cannot create the table "' . $sTableName . '"!'); + } + break; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function updateTable($sTableName, $sConnection = 'wf', $aNewFields = array(), $aOldFields = array()) { + try { + //$aKeys = array('PM_UNIQUE_ID'); + $aKeys = array(); + $aFieldsToAdd = array(); + $aFieldsToDelete = array(); + $aFieldsToAlter = array(); + foreach ($aNewFields as $aNewField) { + if (!isset($aOldFields[$aNewField['FLD_UID']])) { + $aFieldsToAdd[] = $aNewField; + } + if (($aNewField['FLD_KEY'] == 'on') || ($aNewField['FLD_AUTO_INCREMENT'] == 'on')) { + if (!in_array($aNewField['FLD_NAME'], $aKeys)) { + $aKeys[] = $aNewField['FLD_NAME']; + } + } + } + foreach ($aOldFields as $aOldField) { + if (!isset($aNewFields[$aOldField['FLD_UID']])) { + $aFieldsToDelete[] = $aOldField; + } + } + foreach ($aNewFields as $aNewField) { + if (isset($aOldFields[$aNewField['FLD_UID']])) { + $bEqual = true; + if (trim($aNewField['FLD_NAME']) != trim($aOldField['FLD_NAME'])) { + $bEqual = false; + } + if (trim($aNewField['FLD_TYPE']) != trim($aOldField['FLD_TYPE'])) { + $bEqual = false; + } + if (trim($aNewField['FLD_SIZE']) != trim($aOldField['FLD_SIZE'])) { + $bEqual = false; + } + if (trim($aNewField['FLD_NULL']) != trim($aOldField['FLD_NULL'])) { + $bEqual = false; + } + if (trim($aNewField['FLD_AUTO_INCREMENT']) != trim($aOldField['FLD_AUTO_INCREMENT'])) { + $bEqual = false; + } + if (trim($aNewField['FLD_KEY']) != trim($aOldField['FLD_KEY'])) { + $bEqual = false; + } + if (!$bEqual) { + $aNewField['FLD_NAME_OLD'] = $aOldFields[$aNewField['FLD_UID']]['FLD_NAME']; + $aFieldsToAlter[] = $aNewField; + } + } + } + G::LoadSystem('database_' . strtolower(DB_ADAPTER)); + $oDataBase = new database(DB_ADAPTER, DB_HOST, DB_USER, DB_PASS, DB_NAME); + $oDataBase->iFetchType = MYSQL_NUM; + $oDataBase->executeQuery($oDataBase->generateDropPrimaryKeysSQL($sTableName)); + foreach ($aFieldsToAdd as $aFieldToAdd) { + switch ($aFieldToAdd['FLD_TYPE']) { + case 'VARCHAR': + $aData = array('Type' => 'VARCHAR(' . $aFieldToAdd['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAdd['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => ''); + break; + case 'TEXT': + $aData = array('Type' => 'TEXT', + 'Null' => ($aFieldToAdd['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => ''); + break; + case 'DATE': + $aData = array('Type' => 'DATE', + 'Null' => ($aFieldToAdd['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0000-00-00'); + break; + case 'INT': + $aData = array('Type' => 'INT(' . (int)$aFieldToAdd['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAdd['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0', + 'AI' => ($aFieldToAdd['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0)); + break; + case 'FLOAT': + $aData = array('Type' => 'FLOAT(' . (int)$aFieldToAdd['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAdd['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0'); + break; + } + $oDataBase->executeQuery($oDataBase->generateAddColumnSQL($sTableName, $aFieldToAdd['FLD_NAME'], $aData)); + } + foreach ($aFieldsToDelete as $aFieldToDelete) { + $oDataBase->executeQuery($oDataBase->generateDropColumnSQL($sTableName, $aFieldToDelete['FLD_NAME'])); + } + $oDataBase->executeQuery($oDataBase->generateAddPrimaryKeysSQL($sTableName, $aKeys)); + foreach ($aFieldsToAlter as $aFieldToAlter) { + switch ($aFieldToAlter['FLD_TYPE']) { + case 'VARCHAR': + $aData = array('Type' => 'VARCHAR(' . $aFieldToAlter['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAlter['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => ''); + break; + case 'TEXT': + $aData = array('Type' => 'TEXT', + 'Null' => ($aFieldToAlter['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => ''); + break; + case 'DATE': + $aData = array('Type' => 'DATE', + 'Null' => ($aFieldToAlter['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0000-00-00'); + break; + case 'INT': + $aData = array('Type' => 'INT(' . (int)$aFieldToAlter['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAlter['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0', + 'AI' => ($aFieldToAlter['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0)); + break; + case 'FLOAT': + $aData = array('Type' => 'FLOAT(' . (int)$aFieldToAlter['FLD_SIZE'] . ')', + 'Null' => ($aFieldToAlter['FLD_NULL'] == 'on' ? 'YES' : ''), + 'Default' => '0'); + break; + } + $oDataBase->executeQuery($oDataBase->generateChangeColumnSQL($sTableName, $aFieldToAlter['FLD_NAME'], $aData, $aFieldToAlter['FLD_NAME_OLD'])); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function createPropelClasses($sTableName, $sClassName, $aFields, $sAddTabUid) { + try { + /*$aUID = array('FLD_NAME' => 'PM_UNIQUE_ID', + 'FLD_TYPE' => 'INT', + 'FLD_SIZE' => '11', + 'FLD_KEY' => 'on', + 'FLD_NULL' => '', + 'FLD_AUTO_INCREMENT' => 'on'); + array_unshift($aFields, $aUID);*/ + $aTypes = array('VARCHAR' => 'string', + 'TEXT' => 'string', + 'DATE' => 'int', + 'INT' => 'int', + 'FLOAT' => 'double'); + $aCreoleTypes = array('VARCHAR' => 'VARCHAR', + 'TEXT' => 'LONGVARCHAR', + 'DATE' => 'TIMESTAMP', + 'INT' => 'INTEGER', + 'FLOAT' => 'DOUBLE'); + if ($sClassName == '') { + $sClassName = $this->getPHPName($sTableName); + } + + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + if (!file_exists($sPath)) { + G::mk_dir($sPath); + G::mk_dir($sPath . 'map'); + G::mk_dir($sPath . 'om'); + } + $aData = array(); + $aData['pathClasses'] = substr(PATH_DB, 0, -1); + $aData['tableName'] = $sTableName; + $aData['className'] = $sClassName; + $aData['GUID'] = $sAddTabUid; + $aData['firstColumn'] = $aFields[1]['FLD_NAME']; + $aData['totalColumns'] = count($aFields); + $aData['useIdGenerator'] = 'false'; + $oTP1 = new TemplatePower(PATH_TPL . 'additionalTables' . PATH_SEP . 'Table.tpl'); + $oTP1->prepare(); + $oTP1->assignGlobal($aData); + file_put_contents($sPath . $sClassName . '.php', $oTP1->getOutputContent()); + $oTP2 = new TemplatePower(PATH_TPL . 'additionalTables' . PATH_SEP . 'TablePeer.tpl'); + $oTP2->prepare(); + $oTP2->assignGlobal($aData); + file_put_contents($sPath . $sClassName . 'Peer.php', $oTP2->getOutputContent()); + $aColumns = array(); + $aPKs = array(); + $aNotPKs = array(); + $i = 0; + foreach($aFields as $iKey => $aField) { + $aColumn = array('name' => $aField['FLD_NAME'], + 'phpName' => $this->getPHPName($aField['FLD_NAME']), + 'type' => $aTypes[$aField['FLD_TYPE']], + 'creoleType' => $aCreoleTypes[$aField['FLD_TYPE']], + 'notNull' => ($aField['FLD_NULL'] == 'on' ? 'true' : 'false'), + 'size' => (($aField['FLD_TYPE'] == 'VARCHAR') || ($aField['FLD_TYPE'] == 'INT') || ($aField['FLD_TYPE'] == 'FLOAT') ? $aField['FLD_SIZE'] : 'null'), + 'var' => strtolower($aField['FLD_NAME']), + 'attribute' => (($aField['FLD_TYPE'] == 'VARCHAR') || ($aField['FLD_TYPE'] == 'TEXT') || ($aField['FLD_TYPE'] == 'DATE') ? '$' . strtolower($aField['FLD_NAME']) . " = ''" : '$' . strtolower($aField['FLD_NAME']) . ' = 0'), + 'index' => $i, + ); + if ($aField['FLD_TYPE'] == 'DATE') { + $aColumn['getFunction'] = '/** + * Get the [optionally formatted] [' . $aColumn['var'] . '] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function get' . $aColumn['phpName'] . '($format = "Y-m-d") + { + + if ($this->' . $aColumn['var'] . ' === null || $this->' . $aColumn['var'] . ' === "") { + return null; + } elseif (!is_int($this->' . $aColumn['var'] . ')) { + // a non-timestamp value was set externally, so we convert it + if (($this->' . $aColumn['var'] . ' == "0000-00-00 00:00:00") || ($this->' . $aColumn['var'] . ' == "0000-00-00") || !$this->' . $aColumn['var'] . ') { + $ts = "0"; + } + else { + $ts = strtotime($this->' . $aColumn['var'] . '); + } + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [' . $aColumn['var'] . '] as date/time value: " . var_export($this->' . $aColumn['var'] . ', true)); + } + } else { + $ts = $this->' . $aColumn['var'] . '; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, "%") !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + }'; + } + else { + $aColumn['getFunction'] = '/** + * Get the [' . $aColumn['var'] . '] column value. + * + * @return string + */ + public function get' . $aColumn['phpName'] . '() + { + + return $this->' . $aColumn['var'] . '; + }'; + } + switch ($aField['FLD_TYPE']) { + case 'VARCHAR': + case 'TEXT': + $aColumn['setFunction'] = '// Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->' . $aColumn['var'] . ' !== $v) { + $this->' . $aColumn['var'] . ' = $v; + $this->modifiedColumns[] = ' . $aData['className'] . 'Peer::' . $aColumn['name'] . '; + }'; + break; + case 'DATE': + $aColumn['setFunction'] = 'if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + //throw new PropelException("Unable to parse date/time value for [' . $aColumn['var'] . '] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->' . $aColumn['var'] . ' !== $ts) { + $this->' . $aColumn['var'] . ' = $ts; + $this->modifiedColumns[] = ' . $aData['className'] . 'Peer::' . $aColumn['name'] . '; + }'; + break; + case 'INT': + $aColumn['setFunction'] = '// Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->' . $aColumn['var'] . ' !== $v || $v === 1) { + $this->' . $aColumn['var'] . ' = $v; + $this->modifiedColumns[] = ' . $aData['className'] . 'Peer::' . $aColumn['name'] . '; + }'; + break; + case 'FLOAT': + $aColumn['setFunction'] = 'if ($this->' . $aColumn['var'] . ' !== $v || $v === 0) { + $this->' . $aColumn['var'] . ' = $v; + $this->modifiedColumns[] = ' . $aData['className'] . 'Peer::' . $aColumn['name'] . '; + }'; + break; + } + $aColumns[] = $aColumn; + if ($aField['FLD_KEY'] == 'on') { + $aPKs[] = $aColumn; + } + else { + $aNotPKs[] = $aColumn; + } + if ($aField['FLD_AUTO_INCREMENT'] == 'on') { + $aData['useIdGenerator'] = 'true'; + } + $i++; + } + $oTP3 = new TemplatePower(PATH_TPL . 'additionalTables' . PATH_SEP . 'map' . PATH_SEP . 'TableMapBuilder.tpl'); + $oTP3->prepare(); + $oTP3->assignGlobal($aData); + foreach ($aPKs as $iIndex => $aColumn) { + $oTP3->newBlock('primaryKeys'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP3->assign($sKey, $aColumn[$sKey]); + } + } + $oTP3->gotoBlock('_ROOT'); + foreach ($aNotPKs as $iIndex => $aColumn) { + $oTP3->newBlock('columnsWhitoutKeys'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP3->assign($sKey, $aColumn[$sKey]); + } + } + file_put_contents($sPath . PATH_SEP . 'map' . PATH_SEP . $sClassName . 'MapBuilder.php', $oTP3->getOutputContent()); + $oTP4 = new TemplatePower(PATH_TPL . 'additionalTables' . PATH_SEP . 'om' . PATH_SEP . 'BaseTable.tpl'); + $oTP4->prepare(); + switch (count($aPKs)) { + case 0: + $aData['getPrimaryKeyFunction'] = 'return null;'; + $aData['setPrimaryKeyFunction'] = ''; + break; + case 1: + $aData['getPrimaryKeyFunction'] = 'return $this->get' . $aPKs[0]['phpName'] . '();'; + $aData['setPrimaryKeyFunction'] = '$this->set' . $aPKs[0]['phpName'] . '($key);'; + break; + default: + $aData['getPrimaryKeyFunction'] = '$pks = array();' . "\n"; + $aData['setPrimaryKeyFunction'] = ''; + foreach ($aPKs as $iIndex => $aColumn) { + $aData['getPrimaryKeyFunction'] .= '$pks[' . $iIndex . '] = $this->get' . $aColumn['phpName'] . '();' . "\n"; + $aData['setPrimaryKeyFunction'] .= '$this->set' . $aColumn['phpName'] . '($keys[' . $iIndex . ']);' . "\n"; + } + $aData['getPrimaryKeyFunction'] .= 'return $pks;' . "\n"; + break; + } + $oTP4->assignGlobal($aData); + foreach ($aColumns as $iIndex => $aColumn) { + $oTP4->newBlock('allColumns1'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns2'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns3'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns4'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns5'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns6'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns7'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns8'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + $oTP4->newBlock('allColumns9'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + } + $oTP4->gotoBlock('_ROOT'); + foreach ($aPKs as $iIndex => $aColumn) { + $oTP4->newBlock('primaryKeys1'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + } + $oTP4->gotoBlock('_ROOT'); + foreach ($aPKs as $iIndex => $aColumn) { + $oTP4->newBlock('primaryKeys2'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + } + $oTP4->gotoBlock('_ROOT'); + foreach ($aNotPKs as $iIndex => $aColumn) { + $oTP4->newBlock('columnsWhitoutKeys'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP4->assign($sKey, $aColumn[$sKey]); + } + } + file_put_contents($sPath . PATH_SEP . 'om' . PATH_SEP . 'Base' . $sClassName . '.php', $oTP4->getOutputContent()); + $oTP5 = new TemplatePower(PATH_TPL . 'additionalTables' . PATH_SEP . 'om' . PATH_SEP . 'BaseTablePeer.tpl'); + $oTP5->prepare(); + $sKeys = ''; + foreach ($aPKs as $iIndex => $aColumn) { + $sKeys .= '$' . $aColumn['var'] . ', '; + } + $sKeys = substr($sKeys, 0, -2); + //$sKeys = '$pm_unique_id'; + if ($sKeys != '') { + $aData['sKeys'] = $sKeys; + } + else { + $aData['sKeys'] = '$DUMMY'; + } + $oTP5->assignGlobal($aData); + foreach ($aColumns as $iIndex => $aColumn) { + $oTP5->newBlock('allColumns1'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns2'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns3'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns4'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns5'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns6'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns7'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns8'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns9'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + $oTP5->newBlock('allColumns10'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + } + $oTP5->gotoBlock('_ROOT'); + foreach ($aPKs as $iIndex => $aColumn) { + $oTP5->newBlock('primaryKeys1'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + } + foreach ($aPKs as $iIndex => $aColumn) { + $oTP5->newBlock('primaryKeys2'); + $aKeys = array_keys($aColumn); + foreach ($aKeys as $sKey) { + $oTP5->assign($sKey, $aColumn[$sKey]); + } + } + file_put_contents($sPath . PATH_SEP . 'om' . PATH_SEP . 'Base' . $sClassName . 'Peer.php', $oTP5->getOutputContent()); + } + catch (Exception $oError) { + throw($oError); + } + } + + function getPHPName($sName) { + $sName = trim($sName); + $aAux = explode('_', $sName); + foreach ($aAux as $iKey => $sPart) { + $aAux[$iKey] = ucwords(strtolower($sPart)); + } + return implode('', $aAux); + } + + function deleteAll($sUID) { + try { + $aData = $this->load($sUID); + $this->remove($sUID); + require_once 'classes/model/Fields.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->add(FieldsPeer::ADD_TAB_UID, $sUID); + FieldsPeer::doDelete($oCriteria); + G::LoadSystem('database_' . strtolower(DB_ADAPTER)); + $oDataBase = new database(DB_ADAPTER, DB_HOST, DB_USER, DB_PASS, DB_NAME); + $oDataBase->iFetchType = MYSQL_NUM; + $oDataBase->executeQuery($oDataBase->generateDropTableSQL($aData['ADD_TAB_NAME'])); + $sClassName = $this->getPHPName($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $aData['ADD_TAB_NAME']); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + @unlink($sPath . $sClassName . '.php'); + @unlink($sPath . $sClassName . 'Peer.php'); + @unlink($sPath . PATH_SEP . 'map' . PATH_SEP . $sClassName . 'MapBuilder.php'); + @unlink($sPath . PATH_SEP . 'om' . PATH_SEP . 'Base' . $sClassName . '.php'); + @unlink($sPath . PATH_SEP . 'om' . PATH_SEP . 'Base' . $sClassName . 'Peer.php'); + } + catch (Exception $oError) { + throw($oError); + } + } + + function createXmlList($sUID) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DYNAFORM . 'xmlLists' . PATH_SEP; + if (!file_exists($sPath)) { + G::mk_dir($sPath); + } + file_put_contents($sPath . 'additionalTablesDataOptions.xml', ' + + + + + + New + + + + Import + + + + + + + +'); + $sKeys = ''; + $sXml = '' . "\n"; + $sXml .= '' . "\n". + ' + Table: '.$aData['ADD_TAB_NAME'].']]> + '; + + //$sXml .= '' . "\n"; + foreach ($aData['FIELDS'] as $aField) { + + $fZise = $aField['FLD_SIZE'] > (1024/sizeof($aData['FIELDS'])) ? $aField['FLD_SIZE']: 1024/sizeof($aData['FIELDS']); + + + $sXml .= '<' . $aField['FLD_NAME'] . ' type="text" colWidth="'.$fZise.'px" titleAlign="left" align="left">' . "\n"; + $sXml .= '<' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '' . "\n"; + $sXml .= '' . "\n"; + if ($aField['FLD_KEY'] == 1) { + $sKeys .= $aField['FLD_NAME'] . '=@#' . $aField['FLD_NAME'] . '&'; + } + } + $sKeys = substr($sKeys, 0, -5); + $sXml .= '' . "\n"; + $sXml .= '' . "\n"; + $sXml .= ''; + file_put_contents($sPath . $sUID . '.xml', $sXml); + } + catch (Exception $oError) { + throw($oError); + } + } + + function getDataCriteria($sUID) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + + if (file_exists ($sPath . $sClassName . '.php') ) { + require_once $sPath . $sClassName . '.php'; + } else { + return null; + } + + $sClassPeerName = $sClassName . 'Peer'; + $oCriteria = new Criteria('workflow'); + //eval('$oCriteria->addSelectColumn(' . $sClassPeerName . '::PM_UNIQUE_ID);'); + eval('$oCriteria->addSelectColumn("\'1\' AS DUMMY");'); + foreach ($aData['FIELDS'] as $aField) { + eval('$oCriteria->addSelectColumn(' . $sClassPeerName . '::' . $aField['FLD_NAME'] . ');'); + } + + switch ($aField['FLD_TYPE']) { + case 'VARCHAR': + case 'TEXT': + case 'DATE': + if($aField['FLD_NULL']!=1) + eval('$oCriteria->add(' . $sClassPeerName . '::' . $aField['FLD_NAME'] . ', \'(�_�_�)\', Criteria::NOT_EQUAL);'); + break; + case 'INT'; + case 'FLOAT': + eval('$oCriteria->add(' . $sClassPeerName . '::' . $aField['FLD_NAME'] . ', -99999999999, Criteria::NOT_EQUAL);'); + break; + } + //eval('$oCriteria->addAscendingOrderByColumn(' . $sClassPeerName . '::PM_UNIQUE_ID);'); + return $oCriteria; + } + catch (Exception $oError) { + throw($oError); + } + } + + function checkClassNotExist($sUID) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + + if (file_exists ($sPath . $sClassName . '.php') ) { + return $sClassName; + } else { + return ''; + } + + } catch (Exception $oError) { + throw($oError); + } + } + + + function createXmlEdit($sUID, $bEnableKeys) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DYNAFORM . 'xmlLists' . PATH_SEP; + $sXml = '' . "\n"; + $sXml .= ''; + //$sXml .= ''; + $sXml .= ''; + foreach ($aData['FIELDS'] as $aField) { + switch ($aField['FLD_TYPE']) { + case 'VARCHAR': + if( intVal($aField['FLD_SIZE']) <= 100){ + $vCharType = 'text'; + $vCharAtt = 'size="' . $aField['FLD_SIZE'] . '" maxlength="' . $aField['FLD_SIZE'] . '" validate="Any"'; + } else { + $vCharType = 'textarea'; + $vCharAtt = 'rows="3" cols="90"'; + } + $sXml .= '<' . $aField['FLD_NAME'] . ' type="'.$vCharType.'" '. $vCharAtt .' required="' . (($aField['FLD_KEY'] == 1) && ($aField['FLD_AUTO_INCREMENT'] == 0) ? '1' : '0') . '" readonly="0" mode="' . ($bEnableKeys ? 'edit' : ($aField['FLD_KEY'] == 1 ? 'view' : 'edit')) . '"><' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '</' . SYS_LANG . '></' . $aField['FLD_NAME'] . '>'; + break; + case 'TEXT': + $sXml .= '<' . $aField['FLD_NAME'] . ' type="textarea" required="' . (($aField['FLD_KEY'] == 1) && ($aField['FLD_AUTO_INCREMENT'] == 0) ? '1' : '0') . '" readonly="0" rows="8" cols="90" mode="' . ($bEnableKeys ? 'edit' : ($aField['FLD_KEY'] == 1 ? 'view' : 'edit')) . '"><' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '</' . SYS_LANG . '></' . $aField['FLD_NAME'] . '>'; + break; + case 'DATE': + $sXml .= '<' . $aField['FLD_NAME'] . ' type="date" beforedate="-100y" afterdate="100y" mask="Y-m-d" required="' . (($aField['FLD_KEY'] == 1) && ($aField['FLD_AUTO_INCREMENT'] == 0) ? '1' : '0') . '" readonly="0" size="15" mode="' . ($bEnableKeys ? 'edit' : ($aField['FLD_KEY'] == 1 ? 'view' : 'edit')) . '"><' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '</' . SYS_LANG . '></' . $aField['FLD_NAME'] . '>'; + break; + case 'INT': + $sXml .= '<' . $aField['FLD_NAME'] . ' type="text" maxlength="' . $aField['FLD_SIZE'] . '" validate="Int" required="' . (($aField['FLD_KEY'] == 1) && ($aField['FLD_AUTO_INCREMENT'] == 0) ? '1' : '0') . '" readonly="0" size="' .($aField['FLD_SIZE']<=100?$aField['FLD_SIZE']:100). '" mode="' . ($bEnableKeys ? 'edit' : ($aField['FLD_KEY'] == 1 ? 'view' : 'edit')) . '"><' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '</' . SYS_LANG . '></' . $aField['FLD_NAME'] . '>'; + break; + case 'FLOAT': + $sXml .= '<' . $aField['FLD_NAME'] . ' type="text" maxlength="' . $aField['FLD_SIZE'] . '" validate="Real" required="' . (($aField['FLD_KEY'] == 1) && ($aField['FLD_AUTO_INCREMENT'] == 0) ? '1' : '0') . '" readonly="0" size="' . ($aField['FLD_SIZE']<=100?$aField['FLD_SIZE']:100) . '" mode="' . ($bEnableKeys ? 'edit' : ($aField['FLD_KEY'] == 1 ? 'view' : 'edit')) . '"><' . SYS_LANG . '>' . ($aField['FLD_DESCRIPTION'] != '' ? $aField['FLD_DESCRIPTION'] : $aField['FLD_NAME']) . '</' . SYS_LANG . '></' . $aField['FLD_NAME'] . '>'; + break; + } + } + $sXml .= '<btnSave type="submit"><' . SYS_LANG . '>' . G::LoadTranslation('ID_SAVE_CHANGES') . '</' . SYS_LANG . '></btnSave>'; + $sXml .= '<btnBack type="button" onclick="history.back()"><' . SYS_LANG . '>' . G::LoadTranslation('ID_CANCEL') . '</' . SYS_LANG . '></btnBack>'; + $sXml .= '</dynaForm>'; + file_put_contents($sPath . $sUID . 'Edit.xml', $sXml); + } + catch (Exception $oError) { + throw($oError); + } + } + + function saveDataInTable($sUID, $aFields) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + require_once $sPath . $sClassName . '.php'; + $sKeys = ''; + foreach ($aData['FIELDS'] as $aField) { + if ($aField['FLD_KEY'] == 1) { + $vValue = $aFields[$aField['FLD_NAME']]; + eval('$' . $aField['FLD_NAME'] . ' = $vValue;'); + $sKeys .= '$' . $aField['FLD_NAME'] . ','; + } + } + $sKeys = substr($sKeys, 0, -1); + eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK(' . $sKeys . ');'); + if (is_null($oClass)) { + $oClass = new $sClassName; + foreach ($aFields as $sKey => $sValue) { + eval('$oClass->set' . $this->getPHPName($sKey) . '($aFields["' . $sKey . '"]);'); + } + if ($oClass->validate()) { + $oConnection->begin(); + $iResult = $oClass->save(); + $oConnection->commit(); + } + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function getDataTable($sUID, $aKeys) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + require_once $sPath . $sClassName . '.php'; + $sKeys = ''; + foreach ($aKeys as $sName => $vValue) { + eval('$' . $sName . ' = $vValue;'); + $sKeys .= '$' . $sName . ','; + } + $sKeys = substr($sKeys, 0, -1); + eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK(' . $sKeys . ');'); + //eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK($sPMUID);'); + if (!is_null($oClass)) { + return $oClass->toArray(BasePeer::TYPE_FIELDNAME); + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function updateDataInTable($sUID, $aFields) { + try { + //$sPMUID = $aFields['PM_UNIQUE_ID']; + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + require_once $sPath . $sClassName . '.php'; + $sKeys = ''; + foreach ($aData['FIELDS'] as $aField) {//$sName => $vValue + if ($aField['FLD_KEY'] == 1) { + $vValue = $aFields[$aField['FLD_NAME']]; + eval('$' . $aField['FLD_NAME'] . ' = $vValue;'); + $sKeys .= '$' . $aField['FLD_NAME'] . ','; + } + } + $sKeys = substr($sKeys, 0, -1); + eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK(' . $sKeys . ');'); + //eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK($sPMUID);'); + if (!is_null($oClass)) { + $oClass->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + if ($oClass->validate()) { + $oConnection->begin(); + $iResult = $oClass->save(); + $oConnection->commit(); + return $iResult; + } + } + else { + $sMessage = ''; + if ($oClass) { + $aValidationFailures = $oClass->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + } + else { + $sMessage = 'Error, row cannot updated'; + } + throw(new Exception('The registry cannot be updated!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function deleteDataInTable($sUID, $aKeys) { + try { + $aData = $this->load($sUID, true); + $sPath = PATH_DB . SYS_SYS . PATH_SEP . 'classes' . PATH_SEP; + $sClassName = ($aData['ADD_TAB_CLASS_NAME'] != '' ? $aData['ADD_TAB_CLASS_NAME'] : $this->getPHPName($aData['ADD_TAB_NAME'])); + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + require_once $sPath . $sClassName . '.php'; + $sKeys = ''; + foreach ($aKeys as $sName => $vValue) { + eval('$' . $sName . ' = $vValue;'); + $sKeys .= '$' . $sName . ','; + } + $sKeys = substr($sKeys, 0, -1); + eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK(' . $sKeys . ');'); + //eval('$oClass = ' . $sClassName . 'Peer::retrieveByPK($sPMUID);'); + if (!is_null($oClass)) { + if ($oClass->validate()) { + $oConnection->begin(); + $iResult = $oClass->delete(); + $oConnection->commit(); + return $iResult; + } + } + else { + $sMessage = ''; + $aValidationFailures = $oConnection-->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + throw($oError); + } + } +} // AdditionalTables diff --git a/workflow/engine/classes/model/AdditionalTablesPeer.php b/workflow/engine/classes/model/AdditionalTablesPeer.php new file mode 100644 index 000000000..208e24bb7 --- /dev/null +++ b/workflow/engine/classes/model/AdditionalTablesPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAdditionalTablesPeer.php'; + + // include object class + include_once 'classes/model/AdditionalTables.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'ADDITIONAL_TABLES' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AdditionalTablesPeer extends BaseAdditionalTablesPeer { + +} // AdditionalTablesPeer diff --git a/workflow/engine/classes/model/AppCacheView.php b/workflow/engine/classes/model/AppCacheView.php new file mode 100644 index 000000000..7a73770af --- /dev/null +++ b/workflow/engine/classes/model/AppCacheView.php @@ -0,0 +1,1188 @@ +<?php + +require_once 'classes/model/om/BaseAppCacheView.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_CACHE_VIEW' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ + +require_once 'classes/model/Application.php'; +require_once 'classes/model/AppDelegation.php'; +require_once 'classes/model/AppDelay.php'; +require_once 'classes/model/Task.php'; +require_once 'classes/model/AdditionalTables.php'; + +class AppCacheView extends BaseAppCacheView { + var $confCasesList; + var $pathToAppCacheFiles; + + function getAllCounters ( $aTypes, $userUid, $processSummary = false ) { + $aResult = Array(); + foreach($aTypes as $type){ + $aResult[$type] = $this->getListCounters($type, $userUid, $processSummary); + } + return $aResult; + } + + function getListCounters ( $type, $userUid, $processSummary ) { + switch ( $type ) { + case 'to_do' : + $Criteria = $this->getToDoCountCriteria( $userUid ); + break; + case 'draft' : + $Criteria = $this->getDraftCountCriteria( $userUid ); + break; + case 'sent' : + $Criteria = $this->getSentCountCriteria( $userUid ); + return AppCacheViewPeer::doCount($Criteria, true); + break; + case 'selfservice' : + $Criteria = $this->getUnassignedCountCriteria( $userUid ); + break; + case 'paused' : + $Criteria = $this->getPausedCountCriteria( $userUid ); + break; + case 'completed' : + $Criteria = $this->getCompletedCountCriteria( $userUid ); + break; + case 'cancelled' : + $Criteria = $this->getCancelledCountCriteria( $userUid ); + break; + case 'to_revise' : + $Criteria = $this->getToReviseCountCriteria( $userUid ); + break; + default : + return $type; + } + return AppCacheViewPeer::doCount($Criteria); + } + + /** + * gets the todo cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getToDo ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('todo'); + } + $Criteria->add (AppCacheViewPeer::APP_STATUS, "TO_DO" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + $Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + return $Criteria; + } + + /** + * gets the todo cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getToDoCountCriteria ($userUid) { + return $this->getToDo($userUid, true); + } + + /** + * gets the todo cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getToDoListCriteria ($userUid) { + return $this->getToDo($userUid, false); + } + + /** + * gets the DRAFT cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getDraft ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('draft'); + } + $Criteria->add (AppCacheViewPeer::APP_STATUS, "DRAFT" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + //$Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + return $Criteria; + } + + /** + * gets the DRAFT cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getDraftCountCriteria ($userUid) { + return $this->getDraft($userUid, true); + } + + /** + * gets the DRAFT cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getDraftListCriteria ($userUid) { + return $this->getDraft($userUid, false); + } + + /** + * gets the SENT cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getSent ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('sent'); + } + $Criteria->add (AppCacheViewPeer::APP_STATUS, "DRAFT" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + //$Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + return $Criteria; + } + + /** + * gets the SENT cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSentCountCriteria ($userUid) { + $Criteria = new Criteria('workflow'); + $Criteria = $this->addPMFieldsToCriteria('sent'); + + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + return $Criteria; + } + + /** + * gets the SENT cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSentListCriteria ($userUid) { + $Criteria = $this->addPMFieldsToCriteria('sent'); + $Criteria->addAsColumn( 'DEL_INDEX', 'MAX(' . AppDelegationPeer::DEL_INDEX . ')' ); + $Criteria->addJoin ( AppCacheViewPeer::APP_UID , AppDelegationPeer::APP_UID, Criteria::LEFT_JOIN); + + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + $Criteria->addGroupByColumn(AppCacheViewPeer::APP_UID); + //$Criteria->addGroupByColumn(AppCacheViewPeer::APP_); + return $Criteria; + } + + function getSentListProcessCriteria ($userUid) { + $Criteria = $this->addPMFieldsToCriteria('sent'); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + return $Criteria; + } + + /* + * get user's SelfService tasks + * @param string $sUIDUser + * @return $rows + */ + function getSelfServiceTasks($userUid = '') + { + $rows[] = array(); + $tasks = array(); + + //check starting task assigned directly to this user + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn(TaskPeer::TAS_UID); + $c->addSelectColumn(TaskPeer::PRO_UID); + $c->addJoin(TaskPeer::PRO_UID, ProcessPeer::PRO_UID, Criteria::LEFT_JOIN); + $c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN); + $c->add(ProcessPeer::PRO_STATUS, 'ACTIVE'); + $c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE'); + $c->add(TaskUserPeer::USR_UID, $userUid); + + $rs = TaskPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + while (is_array($row)) { + $tasks[] = $row['TAS_UID']; + $rs->next(); + $row = $rs->getRow(); + } + + //check groups assigned to SelfService task + G::LoadClass('groups'); + $group = new Groups(); + $aGroups = $group->getActiveGroupsForAnUser($userUid); + + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn(TaskPeer::TAS_UID); + $c->addSelectColumn(TaskPeer::PRO_UID); + $c->addJoin(TaskPeer::PRO_UID, ProcessPeer::PRO_UID, Criteria::LEFT_JOIN); + $c->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN); + $c->add(ProcessPeer::PRO_STATUS, 'ACTIVE'); + $c->add(TaskPeer::TAS_ASSIGN_TYPE, 'SELF_SERVICE'); + $c->add(TaskUserPeer::USR_UID, $aGroups, Criteria::IN); + + $rs = TaskPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + while (is_array($row)) { + $tasks[] = $row['TAS_UID']; + $rs->next(); + $row = $rs->getRow(); + } + + return $tasks; + } + + /** + * gets the UNASSIGNED cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getUnassigned ( $userUid, $doCount ) { + //get the valid selfservice tasks for this user + if (!class_exists('Cases')){ + G::loadClass('case'); + } + + $oCase = new Cases(); + $tasks = $this->getSelfServiceTasks( $userUid ); + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('unassigned'); + } + // $Criteria->add (AppCacheViewPeer::APP_STATUS, "TO_DO" ); + + $Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); +// $Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); +// $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + + $Criteria->add(AppCacheViewPeer::USR_UID, ''); + $Criteria->add(AppCacheViewPeer::TAS_UID, $tasks , Criteria::IN ); + + return $Criteria; + } + + /** + * gets the UNASSIGNED cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getUnassignedCountCriteria ($userUid) { + return $this->getUnassigned($userUid, true); + } + + /** + * gets the UNASSIGNED cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getUnassignedListCriteria ($userUid) { + return $this->getUnassigned($userUid, false); + } + + /** + * gets the PAUSED cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getPaused ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('paused'); + } + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + //join with APP_DELAY table using APP_UID and DEL_INDEX + $appDelayConds[] = array(AppCacheViewPeer::APP_UID, AppDelayPeer::APP_UID); + $appDelayConds[] = array(AppCacheViewPeer::DEL_INDEX, AppDelayPeer::APP_DEL_INDEX); + $Criteria->addJoinMC($appDelayConds, Criteria::LEFT_JOIN); + + $Criteria->add($Criteria->getNewCriterion(AppDelayPeer::APP_DISABLE_ACTION_USER, null, Criteria::ISNULL)->addOr($Criteria->getNewCriterion(AppDelayPeer::APP_DISABLE_ACTION_USER, 0))); + + $Criteria->add(AppDelayPeer::APP_DELAY_UID, null, Criteria::ISNOTNULL); + $Criteria->add(AppDelayPeer::APP_TYPE, 'PAUSE'); + return $Criteria; + } + + /** + * gets the PAUSED cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getPausedCountCriteria ($userUid) { + return $this->getPaused($userUid, true); + } + + /** + * gets the PAUSED cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getPausedListCriteria ($userUid) { + return $this->getPaused($userUid, false); + } + + /** + * gets the TO_REVISE cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getToRevise ( $userUid, $doCount ) { + require_once 'classes/model/ProcessUser.php'; + // adding configuration fields from the configuration options + // and forming the criteria object + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ProcessUserPeer::USR_UID, $userUid ); + $oCriteria->add(ProcessUserPeer::PU_TYPE, 'SUPERVISOR'); + $oDataset = ProcessUserPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aProcesses = array(); + while ($aRow = $oDataset->getRow()) { + $aProcesses[] = $aRow['PRO_UID']; + $oDataset->next(); + } + + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $c = new Criteria('workflow'); + } + else { + $c = $this->addPMFieldsToCriteria('todo'); + } + $c->add(AppCacheViewPeer::PRO_UID, $aProcesses, Criteria::IN); + $c->add(AppCacheViewPeer::APP_STATUS, 'TO_DO'); + $c->add(AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $c->add(AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $c->add(AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + + return $c; + } + + /** + * gets the ToRevise cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getToReviseCountCriteria ($userUid) { + return $this->getToRevise($userUid, true); + } + + /** + * gets the PAUSED cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getToReviseListCriteria ($userUid) { + return $this->getToRevise($userUid, false); + } + + + /** + * gets the COMPLETED cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getCompleted ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('completed'); + } + $Criteria->add (AppCacheViewPeer::APP_STATUS, "COMPLETED" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + //$Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + + + //$c->add(AppDelegationPeer::DEL_PREVIOUS, '0', Criteria::NOT_EQUAL); + $Criteria->addGroupByColumn(AppCacheViewPeer::APP_UID); + + return $Criteria; + } + + /** + * gets the COMPLETED cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getCompletedCountCriteria ($userUid) { + return $this->getCompleted($userUid, true); + } + + /** + * gets the COMPLETED cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getCompletedListCriteria ($userUid) { + return $this->getCompleted($userUid, false); + } + + + /** + * gets the CANCELLED cases list criteria + * param $userUid the current userUid + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getCancelled ( $userUid, $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('cancelled'); + } + $Criteria->add (AppCacheViewPeer::APP_STATUS, "CANCELLED" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'CLOSED'); + + return $Criteria; + } + + /** + * gets the CANCELLED cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getCancelledCountCriteria ($userUid) { + return $this->getCancelled($userUid, true); + } + + /** + * gets the CANCELLED cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getCancelledListCriteria ($userUid) { + return $this->getCancelled($userUid, false); + } + + /** + * gets the ADVANCED SEARCH cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSearchCountCriteria () { + //$Criteria = new Criteria('workflow'); this sent a outer and cross join :P :P + $Criteria = $this->addPMFieldsToCriteria('sent'); + return $Criteria; + //return $this->getSearchCriteria( true); + } + + function getSearchAllCount ( ) { + $CriteriaCount = new Criteria('workflow'); + $totalCount = ApplicationPeer::doCount( $CriteriaCount); + return $totalCount; + } + + /** + * gets the ADVANCED SEARCH cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSearchListCriteria () { + $Criteria = $this->addPMFieldsToCriteria('sent'); + $Criteria->addAsColumn( 'DEL_INDEX', 'MAX(' . AppCacheViewPeer::DEL_INDEX . ')' ); + + //$Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + $Criteria->addGroupByColumn(AppCacheViewPeer::APP_UID); + return $Criteria; + //return $this->getSearchCriteria(false); + } + + /** + * gets the ADVANCED SEARCH cases list criteria for count + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSimpleSearchCountCriteria () { + //$Criteria = new Criteria('workflow'); this sent a outer and cross join :P :P + $Criteria = $this->addPMFieldsToCriteria('sent'); + $Criteria->add(AppCacheViewPeer::USR_UID, $_SESSION['USER_LOGGED']); + return $Criteria; + //return $this->getSearchCriteria( true); + } + + /** + * gets the ADVANCED SEARCH cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSimpleSearchListCriteria () { + $Criteria = $this->addPMFieldsToCriteria('sent'); + $Criteria->addAsColumn( 'DEL_INDEX', 'MAX(' . AppCacheViewPeer::DEL_INDEX . ')' ); + $Criteria->add(AppCacheViewPeer::USR_UID, $_SESSION['USER_LOGGED']); + //$Criteria->add (AppCacheViewPeer::USR_UID, $userUid); + + $Criteria->addGroupByColumn(AppCacheViewPeer::APP_UID); + return $Criteria; + //return $this->getSearchCriteria(false); + } + + /** + * gets the ADVANCED SEARCH cases list criteria for STATUS + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + function getSearchStatusCriteria () { + $Criteria = new Criteria('workflow'); + return $Criteria; + } + + + /** + * gets the SENT cases list criteria for list + * param $userUid the current userUid + * @return Criteria object $Criteria + */ + + /** + * gets the cases list criteria using the advanced search + * param $doCount if true this will return the criteria for count cases only + * @return Criteria object $Criteria + */ + function getSearchCriteria ( $doCount ) { + // adding configuration fields from the configuration options + // and forming the criteria object + if ( $doCount ) { + $Criteria = new Criteria('workflow'); + } + else { + $Criteria = $this->addPMFieldsToCriteria('sent'); + } + //$Criteria->add (AppCacheViewPeer::APP_STATUS, "TO_DO" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::DEL_INDEX, 1); + + //$Criteria->add (AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + //$Criteria->add (AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + //$Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); + return $Criteria; + } + + + /** + * loads the configuration fields from the database based in an action parameter + * then assemble the Criteria object with these data. + * @param String $action + * @return Criteria object $Criteria + */ + function addPMFieldsToCriteria($action) { + $caseColumns = array(); + if (!class_exists('AdditionalTables')){ + require_once ( "classes/model/AdditionalTables.php" ); + } + $caseReaderFields = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->clearSelectColumns ( ); + // default configuration fields array + $defaultFields = $this->getDefaultFields(); + // if there is PMTABLE for this case list: + if ( !empty($this->confCasesList) && isset($this->confCasesList['PMTable']) && trim($this->confCasesList['PMTable'])!='') { + // getting the table name + + $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($this->confCasesList['PMTable']); + $tableName = $oAdditionalTables->getAddTabName(); + + foreach($this->confCasesList['second']['data'] as $fieldData){ + if ( !in_array($fieldData['name'],$defaultFields) ){ + $fieldName = $tableName.'.'.$fieldData['name']; + $oCriteria->addSelectColumn ( $fieldName ); + } + else { + switch ($fieldData['fieldType']){ + case 'case field': + $configTable = 'APP_CACHE_VIEW'; + break; + case 'delay field': + $configTable = 'APP_DELAY'; + break; + default: + $configTable = 'APP_CACHE_VIEW'; + break; + } + //filterign for some especial cases + switch($action) { + case 'sent': + if ($fieldData['name']!='DEL_INDEX'){ + $fieldName = $configTable . '.' . $fieldData['name']; + } + break; + default: + $fieldName = $configTable . '.' . $fieldData['name']; + break; + } + $oCriteria->addSelectColumn ( $fieldName ); + } + } + + //add the default and hidden DEL_INIT_DATE + $oCriteria->addSelectColumn ( 'APP_CACHE_VIEW.DEL_INIT_DATE' ); +// $oCriteria->addAlias("PM_TABLE", $tableName); + //Add the JOIN + $oCriteria->addJoin(AppCacheViewPeer::APP_UID, $tableName.'.APP_UID', Criteria::LEFT_JOIN); + return $oCriteria; + } + //else this list do not have a PM Table, + else { + if (is_array($this->confCasesList) && !empty($this->confCasesList['second']['data'])){ + foreach($this->confCasesList['second']['data'] as $fieldData){ + switch ($fieldData['fieldType']){ + case 'case field': + $configTable = 'APP_CACHE_VIEW'; + break; + case 'delay field': + $configTable = 'APP_DELAY'; + break; + default: + $configTable = 'APP_CACHE_VIEW'; + break; + } + $fieldName = $configTable.'.'.$fieldData['name']; + switch($action) { + case 'sent': + if ($fieldData['name']!='DEL_INDEX'){ + $fieldName = $configTable . '.' . $fieldData['name']; + } + break; + default: + $fieldName = $configTable . '.' . $fieldData['name']; + break; + } + $oCriteria->addSelectColumn ( $fieldName ); + } + } + else { + //foreach($defaultFields as $field){ + $oCriteria->addSelectColumn('*'); + //} + } + //add the default and hidden DEL_INIT_DATE + $oCriteria->addSelectColumn ( 'APP_CACHE_VIEW.DEL_INIT_DATE' ); + return $oCriteria; + } + } + + /** + * gets the Criteria object for the general cases list. + * @param Boolean $doCount + * @return Criteria + */ + public function getGeneralCases($doCount='false'){ + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $oCriteria = new Criteria('workflow'); + } else { + $oCriteria = $this->addPMFieldsToCriteria('completed'); + } + $oCriteria->addAsColumn( 'DEL_INDEX', 'MIN(' . AppCacheViewPeer::DEL_INDEX . ')' ); + $oCriteria->addJoin( AppCacheViewPeer::APP_UID, AppDelegationPeer::APP_UID, Criteria::LEFT_JOIN ); + $oCriteria->add ( $oCriteria->getNewCriterion(AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN')->addOr($oCriteria->getNewCriterion(AppCacheViewPeer::APP_STATUS, 'COMPLETED')->addAnd($oCriteria->getNewCriterion(AppDelegationPeer::DEL_PREVIOUS, 0)))); + if (!$doCount){ + $oCriteria->addGroupByColumn(AppCacheViewPeer::APP_UID); + } +// $oCriteria->addDescendingOrderByColumn(AppCacheViewPeer::APP_NUMBER); + return $oCriteria; + } + + /** + * gets the ALL cases list criteria for count + * @return Criteria object $Criteria + */ + function getAllCasesCountCriteria ( $userUid ) { + $oCriteria = $this->getGeneralCases( true ); + $oCriteria->add( AppCacheViewPeer::USR_UID, $userUid ); + return $oCriteria; + } + + /** + * gets the ALL cases list criteria for list + * @return Criteria object $Criteria + */ + function getAllCasesListCriteria ( $userUid ) { + $oCriteria = $this->getGeneralCases( false ); + $oCriteria->add( AppCacheViewPeer::USR_UID, $userUid ); + return $oCriteria; + } + + /** + * gets the ALL cases list criteria for count + * @return Criteria object $Criteria + */ + function getGeneralCountCriteria () { + return $this->getGeneralCases( true ); + } + + /** + * gets the ALL cases list criteria for list + * @return Criteria object $Criteria + */ + function getGeneralListCriteria () { + return $this->getGeneralCases( false ); + } + + public function getToReassign( $doCount ){ + if ( $doCount && !isset($this->confCasesList['PMTable']) && !empty($this->confCasesList['PMTable'])) { + $oCriteria = new Criteria('workflow'); + } + else { + $oCriteria = $this->addPMFieldsToCriteria('to_do'); + } + $oCriteria->add(AppCacheViewPeer::APP_STATUS, 'TO_DO'); + $oCriteria->add(AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $oCriteria->add(AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN'); + $oCriteria->add(AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); +// $oCriteria->addDescendingOrderByColumn(AppCacheViewPeer::APP_NUMBER); + return $oCriteria; + } + + /** + * gets the ALL cases list criteria for count + * @return Criteria object $Criteria + */ + function getToReassignCountCriteria () { + return $this->getToReassign( true ); + } + + /** + * gets the ALL cases list criteria for list + * @return Criteria object $Criteria + */ + function getToReassignListCriteria () { + return $this->getToReassign( false ); + } + + + public function getDefaultFields (){ + return array ( + 'APP_UID', + 'DEL_INDEX', + 'APP_NUMBER', + 'APP_STATUS', + 'USR_UID', + 'PREVIOUS_USR_UID', + 'TAS_UID', + 'PRO_UID', + 'DEL_DELEGATE_DATE', + 'DEL_INIT_DATE', + 'DEL_TASK_DUE_DATE', + 'DEL_FINISH_DATE', + 'DEL_THREAD_STATUS', + 'APP_THREAD_STATUS', + 'APP_TITLE', + 'APP_PRO_TITLE', + 'APP_TAS_TITLE', + 'APP_CURRENT_USER', + 'APP_DEL_PREVIOUS_USER', + 'DEL_PRIORITY', + 'DEL_DURATION', + 'DEL_QUEUE_DURATION', + 'DEL_DELAY_DURATION', + 'DEL_STARTED', + 'DEL_FINISHED', + 'DEL_DELAYED', + 'APP_CREATE_DATE', + 'APP_FINISH_DATE', + 'APP_UPDATE_DATE', + 'APP_OVERDUE_PERCENTAGE', + 'APP_DELAY_UID', + 'APP_THREAD_INDEX', + 'APP_DEL_INDEX', + 'APP_TYPE', + 'APP_DELEGATION_USER', + 'APP_ENABLE_ACTION_USER', + 'APP_ENABLE_ACTION_DATE', + 'APP_DISABLE_ACTION_USER', + 'APP_DISABLE_ACTION_DATE', + 'APP_AUTOMATIC_DISABLED_DATE' + ); + } + + + function setPathToAppCacheFiles ( $path ) { + $this->pathToAppCacheFiles = $path; + } + + function getMySQLVersion() { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + $sql = "select version() "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + $rs1->next(); + $row = $rs1->getRow(); + return $row[0]; + + } + + function checkGrantsForUser( $root = false ) { + try { + if ( $root ) + $con = Propel::getConnection("root"); + else + $con = Propel::getConnection("workflow"); + + $stmt = $con->createStatement(); + $sql = "select CURRENT_USER(), USER() "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + $rs1->next(); + $row = $rs1->getRow(); + $mysqlUser = str_replace('@', "'@'", $row[0] ); + + $super = false; + $sql = "SELECT * FROM `information_schema`.`USER_PRIVILEGES` where GRANTEE = \"'$mysqlUser'\" and PRIVILEGE_TYPE = 'SUPER' "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs1->next(); + $row = $rs1->getRow(); + if ( is_array($row = $rs1->getRow() ) ) { + $super = true; + } + + return array( 'user' => $mysqlUser, 'super' => $super ); + } + catch ( Exception $e ) { + return array( 'error' => true, 'msg' => $e->getMessage() ); + } + } + + function setSuperForUser( $mysqlUser ) { + try { + $con = Propel::getConnection("root"); + $stmt = $con->createStatement(); + $sql = "GRANT SUPER on *.* to '$mysqlUser' "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + return array(); + } + catch ( Exception $e ) { + return array( 'error' => true, 'msg' => $e->getMessage() ); + } + + } + + /** + * search for table APP_CACHE_VIEW + * @return void + * + */ + function checkAppCacheView () { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + //check if table APP_CACHE_VIEW exists + $sql="SHOW TABLES"; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + $rs1->next(); + $found = false; + while ( is_array($row = $rs1->getRow() ) && !$found ) { + if ( strtolower($row[0]) == 'app_cache_view' ) { + $found = true; + } + $rs1->next(); + } + + $needCreateTable = $found == false; + + //if exists the APP_CACHE_VIEW Table, we need to check if it has the correct number of fields, if not recreate the table + $tableRecreated = false; + if ( $found ) { + $sql="SHOW FIELDS FROM APP_CACHE_VIEW"; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM); + $rs1->next(); + $fields = array(); + while ( is_array($row = $rs1->getRow() ) ) { + $fields[] = $row[0]; + $rs1->next(); + } + if ( count($fields) != 31 ) { + $needCreateTable = true; + } + } + + if ( $needCreateTable ) { + $stmt->executeQuery( "DROP TABLE IF EXISTS `APP_CACHE_VIEW`; "); + + $filenameSql = $this->pathToAppCacheFiles . 'app_cache_view.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file app_cache_view.sql doesn't exists ") ); + $sql = file_get_contents ( $filenameSql ); + $stmt->executeQuery($sql); + $tableRecreated = true; + $found = true; + } + + //now count how many records there are .. + $count = '-'; + if ( $found ) { + $oCriteria = new Criteria('workflow'); + $count = AppCacheViewPeer::doCount($oCriteria); + } + return array( 'found' => $found, 'recreated' => $tableRecreated, 'count' => $count ); + + } + + /** + * populate (fill) the table APP_CACHE_VIEW + * @return void + */ + function fillAppCacheView ( $lang ) { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + $sql ="truncate table APP_CACHE_VIEW "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + + $filenameSql = $this->pathToAppCacheFiles . 'app_cache_view_insert.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file app_cache_view_insert.sql doesn't exists ") ); + + $sql = explode ( ';', file_get_contents ( $filenameSql ) ); + foreach ( $sql as $key => $val ) { + $val = str_replace('{lang}', $lang, $val); + $stmt->executeQuery($val); + } + + $sql = "select count(*) as CANT from APP_CACHE_VIEW "; + $rs1 = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs1->next(); + $row1 = $rs1->getRow(); + $cant = $row1['CANT']; + + return "done $cant rows in table APP_CACHE_VIEW"; + } + + + /** + * Insert an app delegatiojn trigger + * @return void + */ + function triggerAppDelegationInsert( $lang, $recreate = false ) { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + $rs = $stmt->executeQuery('Show TRIGGERS', ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $found = false; + while ( is_array ( $row ) ) { + if ( strtolower($row['Trigger'] == 'APP_DELEGATION_INSERT') && strtoupper($row['Table']) == 'APP_DELEGATION' ) { + $found = true; + } + $rs->next(); + $row = $rs->getRow(); + } + if ( $recreate ) { + $rs = $stmt->executeQuery('DROP TRIGGER IF EXISTS APP_DELEGATION_INSERT' ); + $found = false; + } + if ( ! $found ) { + $filenameSql = $this->pathToAppCacheFiles . 'triggerAppDelegationInsert.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file triggerAppDelegationInsert.sql doesn't exists ") ); + $sql = file_get_contents ( $filenameSql ); + $sql = str_replace('{lang}', $lang, $sql); + $stmt->executeQuery($sql); + return 'created'; + } + return 'exists'; + } + + + /** + * update the App Delegation triggers + * @return void + */ + function triggerAppDelegationUpdate( $lang, $recreate = false ) { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + $rs = $stmt->executeQuery("Show TRIGGERS", ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $found = false; + while ( is_array ( $row ) ) { + if ( strtolower($row['Trigger'] == 'APP_DELEGATION_UPDATE') && strtoupper($row['Table']) == 'APP_DELEGATION' ) { + $found = true; + } + $rs->next(); + $row = $rs->getRow(); + } + + if ( $recreate ) { + $rs = $stmt->executeQuery('DROP TRIGGER IF EXISTS APP_DELEGATION_UPDATE' ); + $found = false; + } + + if ( ! $found ) { + $filenameSql = $this->pathToAppCacheFiles . '/triggerAppDelegationUpdate.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file triggerAppDelegationUpdate.sql doesn't exists ") ); + $sql = file_get_contents ( $filenameSql ); + $sql = str_replace('{lang}', $lang, $sql); + $stmt->executeQuery($sql); + return 'created'; + } + return 'exists'; + } + + /** + * update the Application triggers + * @return void + */ + function triggerApplicationUpdate( $lang, $recreate = false ) { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + $rs = $stmt->executeQuery("Show TRIGGERS", ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $found = false; + while ( is_array ( $row ) ) { + if ( strtolower($row['Trigger'] == 'APPLICATION_UPDATE') && strtoupper($row['Table']) == 'APPLICATION' ) { + $found = true; + } + $rs->next(); + $row = $rs->getRow(); + } + if ( $recreate ) { + $rs = $stmt->executeQuery('DROP TRIGGER IF EXISTS APPLICATION_UPDATE' ); + $found = false; + } + + if ( ! $found ) { + $filenameSql = $this->pathToAppCacheFiles . '/triggerApplicationUpdate.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file triggerAppDelegationUpdate.sql doesn't exists ") ); + $sql = file_get_contents ( $filenameSql ); + $sql = str_replace('{lang}', $lang, $sql); + $stmt->executeQuery($sql); + return 'created'; + } + return 'exists'; + } + + /** + * update the Application triggers + * @return void + */ + function triggerApplicationDelete( $lang , $recreate = false) { + $con = Propel::getConnection("workflow"); + $stmt = $con->createStatement(); + + $rs = $stmt->executeQuery("Show TRIGGERS", ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $found = false; + while ( is_array ( $row ) ) { + if ( strtolower($row['Trigger'] == 'APPLICATION_DELETE') && strtoupper($row['Table']) == 'APPLICATION' ) { + $found = true; + } + $rs->next(); + $row = $rs->getRow(); + } + + if ( $recreate ) { + $rs = $stmt->executeQuery('DROP TRIGGER IF EXISTS APPLICATION_DELETE' ); + $found = false; + } + + if ( ! $found ) { + $filenameSql = $this->pathToAppCacheFiles . '/triggerApplicationDelete.sql'; + if ( !file_exists ( $filenameSql ) ) + throw ( new Exception ( "file triggerAppDelegationDelete.sql doesn't exists ") ); + $sql = file_get_contents ( $filenameSql ); + $sql = str_replace('{lang}', $lang, $sql); + $stmt->executeQuery($sql); + return 'created'; + } + return 'exists'; + } + + function getFormatedUser($sFormat, $aCaseUser, $userIndex){ + require_once('classes/model/Users.php'); + $oUser = new Users(); + try { + $aCaseUserRecord = $oUser->load($aCaseUser[$userIndex]); + $sCaseUser = G::getFormatUserList ($sFormat,$aCaseUserRecord); + // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')';] + } catch (Exception $e){ + $sCaseUser = ''; + } + return($sCaseUser); + } + + function replaceRowUserData($rowData){ + try { + G::loadClass('configuration'); + $oConfig = new Configuration(); + $aConfig = $oConfig->load('ENVIRONMENT_SETTINGS'); + $aConfig = unserialize($aConfig['CFG_VALUE']); + } catch (Exception $e){ + // if there is no configuration record then. + $aConfig['format'] = '@userName'; + } + if (isset($rowData['USR_UID'])&&isset($rowData['APP_CURRENT_USER'])){ + $rowData['APP_CURRENT_USER'] = $this->getFormatedUser($aConfig['format'],$rowData,'USR_UID'); + } + if (isset($rowData['PREVIOUS_USR_UID'])&&isset($rowData['APP_DEL_PREVIOUS_USER'])){ + $rowData['APP_DEL_PREVIOUS_USER'] = $this->getFormatedUser($aConfig['format'],$rowData,'PREVIOUS_USR_UID'); + } + return ($rowData); + } + +} // AppCacheView diff --git a/workflow/engine/classes/model/AppCacheViewPeer.php b/workflow/engine/classes/model/AppCacheViewPeer.php new file mode 100644 index 000000000..e6b3ee9f6 --- /dev/null +++ b/workflow/engine/classes/model/AppCacheViewPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppCacheViewPeer.php'; + + // include object class + include_once 'classes/model/AppCacheView.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_CACHE_VIEW' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppCacheViewPeer extends BaseAppCacheViewPeer { + +} // AppCacheViewPeer diff --git a/workflow/engine/classes/model/AppDelay.php b/workflow/engine/classes/model/AppDelay.php new file mode 100644 index 000000000..a6762c4fc --- /dev/null +++ b/workflow/engine/classes/model/AppDelay.php @@ -0,0 +1,118 @@ +<?php + +require_once 'classes/model/om/BaseAppDelay.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_DELAY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDelay extends BaseAppDelay { + /** + * Create the application delay registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(AppDelayPeer::DATABASE_NAME); + try { + if ( isset ( $aData['APP_DELAY_UID'] ) && $aData['APP_DELAY_UID']== '' ) + unset ( $aData['APP_DELAY_UID'] ); + if ( !isset ( $aData['APP_DELAY_UID'] ) ) + $aData['APP_DELAY_UID'] = G::generateUniqueID(); + $oAppDelay = new AppDelay(); + $oAppDelay->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAppDelay->validate()) { + $oConnection->begin(); + $iResult = $oAppDelay->save(); + $oConnection->commit(); + return $aData['APP_DELAY_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppDelay->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application delay registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(AppDelayPeer::DATABASE_NAME); + try { + $oAppDelay = AppDelayPeer::retrieveByPK($aData['APP_DELAY_UID']); + if (!is_null($oAppDelay)) + { + $oAppDelay->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAppDelay->validate()) { + $oConnection->begin(); + $iResult = $oAppDelay->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppDelay->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function isPaused($appUid, $delIndex){ + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelayPeer::APP_UID, $appUid); + $oCriteria->add(AppDelayPeer::APP_DEL_INDEX, $delIndex); + $oCriteria->add(AppDelayPeer::APP_TYPE, 'PAUSE'); + $oCriteria->add(AppDelayPeer::APP_DISABLE_ACTION_USER, null); + $oCriteria->add( + $oCriteria->getNewCriterion( + AppDelayPeer::APP_DISABLE_ACTION_USER, + null, + Criteria::ISNULL + )->addOr( + $oCriteria->getNewCriterion(AppDelayPeer::APP_DISABLE_ACTION_USER, 0) + ) + ); + $oDataset = AppDelayPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + if( $aRow ) + return true; + else + return false; + + } +} // AppDelay \ No newline at end of file diff --git a/workflow/engine/classes/model/AppDelayPeer.php b/workflow/engine/classes/model/AppDelayPeer.php new file mode 100644 index 000000000..6f8bfc1a1 --- /dev/null +++ b/workflow/engine/classes/model/AppDelayPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppDelayPeer.php'; + + // include object class + include_once 'classes/model/AppDelay.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_DELAY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDelayPeer extends BaseAppDelayPeer { + +} // AppDelayPeer diff --git a/workflow/engine/classes/model/AppDelegation.php b/workflow/engine/classes/model/AppDelegation.php new file mode 100644 index 000000000..84f87bce5 --- /dev/null +++ b/workflow/engine/classes/model/AppDelegation.php @@ -0,0 +1,415 @@ +<?php +/** + * AppDelegation.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseAppDelegation.php'; +require_once ( "classes/model/HolidayPeer.php" ); +require_once ( "classes/model/TaskPeer.php" ); +G::LoadClass("dates"); + +/** + * Skeleton subclass for representing a row from the 'APP_DELEGATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDelegation extends BaseAppDelegation { + + /** + * create an application delegation + * @param $sProUid process Uid + * @param $sAppUid Application Uid + * @param $sTasUid Task Uid + * @param $sUsrUid User Uid + * @param $iPriority delegation priority + * @param $isSubprocess is a subprocess inside a process? + * @return delegation index of the application delegation. + */ + function createAppDelegation ($sProUid, $sAppUid, $sTasUid, $sUsrUid, $sAppThread, $iPriority = 3, $isSubprocess=false, $sPrevious=-1 ) { + + if (!isset($sProUid) || strlen($sProUid) == 0 ) { + throw ( new Exception ( 'Column "PRO_UID" cannot be null.' ) ); + } + + if (!isset($sAppUid) || strlen($sAppUid ) == 0 ) { + throw ( new Exception ( 'Column "APP_UID" cannot be null.' ) ); + } + + if (!isset($sTasUid) || strlen($sTasUid ) == 0 ) { + throw ( new Exception ( 'Column "TAS_UID" cannot be null.' ) ); + } + + if (!isset($sUsrUid) /*|| strlen($sUsrUid ) == 0*/ ) { + throw ( new Exception ( 'Column "USR_UID" cannot be null.' ) ); + } + if (!isset($sAppThread) || strlen($sAppThread ) == 0 ) { + throw ( new Exception ( 'Column "APP_THREAD" cannot be null.' ) ); + } + //get max DEL_INDEX SELECT MAX(DEL_INDEX) AS M FROM APP_DELEGATION WHERE APP_UID="'.$Fields['APP_UID'].'"' + $c = new Criteria (); + $c->clearSelectColumns(); + $c->addSelectColumn ( 'MAX(' . AppDelegationPeer::DEL_INDEX . ') ' ); + $c->add ( AppDelegationPeer::APP_UID, $sAppUid ); + $rs = AppDelegationPeer::doSelectRS ( $c ); + $rs->next(); + $row = $rs->getRow(); + $delIndex = $row[0] + 1; + + $this->setAppUid ( $sAppUid ); + $this->setProUid ( $sProUid ); + $this->setTasUid ( $sTasUid ); + $this->setDelIndex ( $delIndex ); + $this->setDelPrevious ( $sPrevious == -1 ? 0 : $sPrevious ); + $this->setUsrUid ( $sUsrUid ); + $this->setDelType ( 'NORMAL' ); + $this->setDelPriority ( ($iPriority != '' ? $iPriority : '3') ); + $this->setDelThread ( $sAppThread ); + $this->setDelThreadStatus ( 'OPEN' ); + $this->setDelDelegateDate ( 'now' ); + //The function return an array now. By JHL + $delTaskDueDate=$this->calculateDueDate(); + $this->setDelTaskDueDate ( $delTaskDueDate['DUE_DATE'] ); // Due date formatted + $this->setDelData ( '' ); //$delTaskDueDate['DUE_DATE_LOG'] ); // Log of actions made by Calendar Engine + + // this condition assures that an internal delegation like a subprocess dont have an initial date setted + if ( $delIndex == 1 && !$isSubprocess ) //the first delegation, init date this should be now for draft applications, in other cases, should be null. + $this->setDelInitDate ('now' ); + + if ($this->validate() ) { + try { + $res = $this->save(); + } + catch ( PropelException $e ) { + throw ( $e ); + } + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $this->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + throw ( new Exception ( 'Failed Data validation saving APP_DELEGATION row: ' . $msg ) ); + } + + return $this->getDelIndex(); + } + + /** + * Load the Application Delegation row specified in [app_id] column value. + * + * @param string $AppUid the uid of the application + * @return array $Fields the fields + */ + + function Load ( $AppUid, $sDelIndex ) { + $con = Propel::getConnection(AppDelegationPeer::DATABASE_NAME); + try { + $oAppDel = AppDelegationPeer::retrieveByPk( $AppUid, $sDelIndex ); + if ( get_class ($oAppDel) == 'AppDelegation' ) { + $aFields = $oAppDel->toArray( BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + return $aFields; + } + else { + throw( new Exception( "The row '$AppUid, $sDelIndex' in table AppDelegation doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Update the application row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( AppDelegationPeer::DATABASE_NAME ); + try { + $con->begin(); + $oApp = AppDelegationPeer::retrieveByPK( $aData['APP_UID'], $aData['DEL_INDEX'] ); + if ( get_class ($oApp) == 'AppDelegation' ) { + $oApp->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oApp->validate()) { + $res = $oApp->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "This AppDelegation row doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function remove($sApplicationUID, $iDelegationIndex) { + $oConnection = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try { + $oConnection->begin(); + $oApp = AppDelegationPeer::retrieveByPK( $sApplicationUID, $iDelegationIndex ); + if ( get_class ($oApp) == 'AppDelegation' ) { + $result = $oApp->delete(); + } + $oConnection->commit(); + return $result; + } + catch(Exception $e) { + $oConnection->rollback(); + throw($e); + } + } + + // TasTypeDay = 1 => working days + // TasTypeDay = 2 => calendar days + function calculateDueDate() + { + //Get Task properties + $task = TaskPeer::retrieveByPK( $this->getTasUid() ); + + //use the dates class to calculate dates + $dates = new dates(); + $iDueDate = $dates->calculateDate( $this->getDelDelegateDate(), + $task->getTasDuration(), + $task->getTasTimeUnit(), //hours or days, ( we only accept this two types or maybe weeks + $task->getTasTypeDay(), //working or calendar days + $this->getUsrUid(), + $task->getProUid(), + $this->getTasUid() ); + return $iDueDate; + } + +function getDiffDate ( $date1, $date2 ) { + return ( $date1 - $date2 )/(24*60*60); //days + return ( $date1 - $date2 ) / 3600; + } + function calculateDuration() { + try { + //patch rows with initdate = null and finish_date + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn(AppDelegationPeer::APP_UID ); + $c->addSelectColumn(AppDelegationPeer::DEL_INDEX ); + $c->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $c->add(AppDelegationPeer::DEL_INIT_DATE, NULL, Criteria::ISNULL); + $c->add(AppDelegationPeer::DEL_FINISH_DATE, NULL, Criteria::ISNOTNULL); + //$c->add(AppDelegationPeer::DEL_INDEX, 1); + + $rs = AppDelegationPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + while (is_array($row)) { + $oAppDel = AppDelegationPeer::retrieveByPk($row['APP_UID'], $row['DEL_INDEX'] ); + if ( isset ($row['DEL_FINISH_DATE']) ) + $oAppDel->setDelInitDate($row['DEL_FINISH_DATE']); + else + $oAppDel->setDelInitDate($row['DEL_INIT_DATE']); + $oAppDel->save(); + + $rs->next(); + $row = $rs->getRow(); + } + //walk in all rows with DEL_STARTED = 0 or DEL_FINISHED = 0 + + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn(AppDelegationPeer::APP_UID ); + $c->addSelectColumn(AppDelegationPeer::DEL_INDEX ); + $c->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_QUEUE_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_DELAY_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_STARTED); + $c->addSelectColumn(AppDelegationPeer::DEL_FINISHED); + $c->addSelectColumn(AppDelegationPeer::DEL_DELAYED); + $c->addSelectColumn(TaskPeer::TAS_DURATION); + $c->addSelectColumn(TaskPeer::TAS_TIMEUNIT); + $c->addSelectColumn(TaskPeer::TAS_TYPE_DAY); + + $c->addJoin(AppDelegationPeer::TAS_UID, TaskPeer::TAS_UID, Criteria::LEFT_JOIN ); + //$c->add(AppDelegationPeer::DEL_INIT_DATE, NULL, Criteria::ISNULL); + //$c->add(AppDelegationPeer::APP_UID, '7694483844a37bfeb0931b1063501289'); + //$c->add(AppDelegationPeer::DEL_STARTED, 0); + + $cton1 = $c->getNewCriterion(AppDelegationPeer::DEL_STARTED, 0); + $cton2 = $c->getNewCriterion(AppDelegationPeer::DEL_FINISHED, 0); + $cton1->addOR($cton2); + $c->add($cton1); + + $rs = AppDelegationPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); +$i =0; +//print "<table colspacing='2' border='1'>"; +//print "<tr><td>iDelegateDate </td><td>iInitDate </td><td>iDueDate </td><td>iFinishDate </td><td>isStarted </td><td>isFinished </td><td>isDelayed </td><td>queueDuration </td><td>delDuration </td><td>delayDuration</td></tr>"; + $now = strtotime ( 'now' ); + while ( is_array($row) ) { + $fTaskDuration = $row['TAS_DURATION']; + $iDelegateDate = strtotime ( $row['DEL_DELEGATE_DATE'] ); + $iInitDate = strtotime ( $row['DEL_INIT_DATE'] ); + $iDueDate = strtotime ( $row['DEL_TASK_DUE_DATE'] ); + $iFinishDate = strtotime ( $row['DEL_FINISH_DATE'] ); + $isStarted = intval ( $row['DEL_STARTED'] ); + $isFinished = intval ( $row['DEL_FINISHED'] ); + $isDelayed = intval ( $row['DEL_DELAYED'] ); + $queueDuration = $this->getDiffDate ($iInitDate, $iDelegateDate); + $delDuration = 0; + $delayDuration = 0; + $overduePercentage = 0.0; + //get the object, + $oAppDel = AppDelegationPeer::retrieveByPk($row['APP_UID'], $row['DEL_INDEX'] ); + //if the task is not started + if ( $isStarted == 0 ) { + if ( $row['DEL_INIT_DATE'] != NULL && $row['DEL_INIT_DATE'] != '' ) { + $oAppDel->setDelStarted(1); + $queueDuration = $this->getDiffDate ($iInitDate, $iDelegateDate ); + $oAppDel->setDelQueueDuration( $queueDuration); + } + else {//the task was not started + $queueDuration = $this->getDiffDate ( $now, $iDelegateDate ); + $oAppDel->setDelQueueDuration( $queueDuration); + + //we are putting negative number if the task is not delayed, and positive number for the time the task is delayed + $delayDuration = $this->getDiffDate ($now, $iDueDate ); + $oAppDel->setDelDelayDuration( $delayDuration); + if ( $fTaskDuration != 0) { + $overduePercentage = $delayDuration / $fTaskDuration; + $oAppDel->setAppOverduePercentage( $overduePercentage); + if ( $iDueDate < $now ) { + $oAppDel->setDelDelayed(1); + } + } + } + } + + //if the task was not finished + if ( $isFinished == 0 ) { + if ( $row['DEL_FINISH_DATE'] != NULL && $row['DEL_FINISH_DATE'] != '') { + $oAppDel->setAppOverduePercentage($overduePercentage); + $oAppDel->setDelFinished(1); + + $delDuration = $this->getDiffDate ($iFinishDate, $iInitDate ); + $oAppDel->setDelDuration( $delDuration); + //calculate due date if correspond + if ( $iDueDate < $iFinishDate ) { + $oAppDel->setDelDelayed(1); + $delayDuration = $this->getDiffDate ($iFinishDate, $iDueDate ); + } + else { + $oAppDel->setDelDelayed(0); + $delayDuration = 0; + } + } + else { //the task was not completed + if ( $row['DEL_INIT_DATE'] != NULL && $row['DEL_INIT_DATE'] != '' ) { + $delDuration = $this->getDiffDate ($now, $iInitDate ); + } + else + $delDuration = $this->getDiffDate ($now, $iDelegateDate); + $oAppDel->setDelDuration( $delDuration); + + //we are putting negative number if the task is not delayed, and positive number for the time the task is delayed + $delayDuration = $this->getDiffDate ($now, $iDueDate ); + $oAppDel->setDelDelayDuration( $delayDuration); + if ( $fTaskDuration != 0) { + $overduePercentage = $delayDuration / $fTaskDuration; + $oAppDel->setAppOverduePercentage($overduePercentage ); + if ( $iDueDate < $now ) { + $oAppDel->setDelDelayed(1); + } + } + } + + } + + + //and finally save the record + $RES = $oAppDel->save(); +//print "<tr><td>$iDelegateDate </td><td>$iInitDate </td><td>$iDueDate </td><td>$iFinishDate </td><td>$isStarted </td><td>$isFinished </td><td>$isDelayed</td><td>$queueDuration </td><td>$delDuration </td>" . +// "<td>$delayDuration</td><td>$overduePercentage</td><td>" . $row['DEL_INDEX'] . " $RES </td></tr>"; + +//UPDATE APP_DELEGATION SET DEL_DELAYED = 0 +//where +// APP_OVERDUE_PERCENTAGE < 0 + $rs->next(); + $row = $rs->getRow(); + + } + } + catch ( Exception $oError) { + //krumo ( $oError->getMessage() ); + } + } + + function getLastDeleration($APP_UID){ + $c = new Criteria('workflow'); + $c->addSelectColumn(AppDelegationPeer::APP_UID ); + $c->addSelectColumn(AppDelegationPeer::DEL_INDEX ); + $c->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $c->addSelectColumn(AppDelegationPeer::DEL_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_QUEUE_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_DELAY_DURATION); + $c->addSelectColumn(AppDelegationPeer::DEL_STARTED); + $c->addSelectColumn(AppDelegationPeer::DEL_FINISHED); + $c->addSelectColumn(AppDelegationPeer::DEL_DELAYED); + $c->addSelectColumn(AppDelegationPeer::USR_UID); + + $c->add(AppDelegationPeer::APP_UID, $APP_UID); + $c->addDescendingOrderByColumn(AppDelegationPeer::DEL_INDEX); + $rs = AppDelegationPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + return $rs->getRow(); + } +} // AppDelegation diff --git a/workflow/engine/classes/model/AppDelegationPeer.php b/workflow/engine/classes/model/AppDelegationPeer.php new file mode 100644 index 000000000..3e263491c --- /dev/null +++ b/workflow/engine/classes/model/AppDelegationPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * AppDelegationPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseAppDelegationPeer.php'; + + // include object class + include_once 'classes/model/AppDelegation.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_DELEGATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDelegationPeer extends BaseAppDelegationPeer { + +} // AppDelegationPeer diff --git a/workflow/engine/classes/model/AppDocument.php b/workflow/engine/classes/model/AppDocument.php new file mode 100644 index 000000000..ca28cff9f --- /dev/null +++ b/workflow/engine/classes/model/AppDocument.php @@ -0,0 +1,574 @@ +<?php +/** + * AppDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseAppDocument.php'; +require_once 'classes/model/Content.php'; +require_once 'classes/model/InputDocument.php'; + +/** + * Skeleton subclass for representing a row from the 'APP_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDocument extends BaseAppDocument { + + /** + * This value goes in the content table + * @var string + */ + protected $app_doc_title = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $app_doc_comment = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $app_doc_filename = ''; + + /* + * Load the application document registry + * @param string $sAppDocUid + * @param integer $iVersion (Document version) + * @return variant + */ + public function load($sAppDocUid,$iVersion=NULL) + { + try { + if($iVersion==NULL) $iVersion=$this->getLastAppDocVersion($sAppDocUid); + $oAppDocument = AppDocumentPeer::retrieveByPK($sAppDocUid,$iVersion); + if (!is_null($oAppDocument)) + { + $aFields = $oAppDocument->toArray(BasePeer::TYPE_FIELDNAME); + //optimized for speed + $aContentFields = $oAppDocument->getContentFields(); + $aFields['APP_DOC_TITLE'] = $aContentFields['APP_DOC_TITLE']; + $aFields['APP_DOC_COMMENT'] = $aContentFields['APP_DOC_COMMENT']; + $aFields['APP_DOC_FILENAME'] = $aContentFields['APP_DOC_FILENAME']; + + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('Error loading Document '.$sAppDocUid.'/'.$iVersion.'. This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + public function getLastIndex( $sAppUid ) + { + try { + $oCriteria = new Criteria(); + $oCriteria->add( AppDocumentPeer::APP_UID , $sAppUid ); + //$oCriteria->addAscendingOrderByColumn ( AppDocumentPeer::APP_DOC_INDEX ); + $oCriteria->addDescendingOrderByColumn( AppDocumentPeer::APP_DOC_INDEX ); + $lastAppDoc = AppDocumentPeer::doSelectOne($oCriteria); + if (!is_null($lastAppDoc)) + { + return $lastAppDoc->getAppDocIndex(); + } + else { + return 0; + } + } + catch (Exception $oError) { + throw($oError); + } + } + /** + * Get last Document Version based on Doc UID + * @param s $sAppDocUid + * @return integer + **/ + public function getLastDocVersion( $sDocUid ,$appUID) + { + try { + $oCriteria = new Criteria(); + $oCriteria->add(AppDocumentPeer::DOC_UID, $sDocUid ); + $oCriteria->add(AppDocumentPeer::APP_UID, $appUID); + $oCriteria->addDescendingOrderByColumn( AppDocumentPeer::DOC_VERSION ); + $lastAppDocVersion = AppDocumentPeer::doSelectOne($oCriteria); + if (!is_null($lastAppDocVersion)) + { + return $lastAppDocVersion->getDocVersion(); + } + else { + return 0; + } + } + catch (Exception $oError) { + throw($oError); + } + } + /** + * Get last Document Version based on APPDoc UID + * @param s $sAppDocUid + * @return integer + **/ + public function getLastAppDocVersion( $sAppDocUid ,$appUID=0) + { + try { + $oCriteria = new Criteria(); + $oCriteria->add(AppDocumentPeer::APP_DOC_UID, $sAppDocUid ); + if($appUID!=0) $oCriteria->add(AppDocumentPeer::APP_UID, $appUID); + $oCriteria->addDescendingOrderByColumn( AppDocumentPeer::DOC_VERSION ); + $lastAppDocVersion = AppDocumentPeer::doSelectOne($oCriteria); + if (!is_null($lastAppDocVersion)) + { + return $lastAppDocVersion->getDocVersion(); + } + else { + return 0; + } + } + catch (Exception $oError) { + throw($oError); + } + } + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + try { + $oAppDocument = new AppDocument(); + + if(!isset($aData['APP_DOC_UID'])){ + $sUID = G::generateUniqueID(); + $docVersion = 1; + }else{ + $sUID = $aData['APP_DOC_UID']; + $docVersion = $this->getLastAppDocVersion($aData['APP_DOC_UID'],$oAppDocument->getAppUid()); + $oAppDocument->load($aData['APP_DOC_UID'], $docVersion); + switch( $oAppDocument->getAppDocType() ){ + case "OUTPUT"://Output versioning + $o = new OutputDocument(); + $oOutputDocument = $o->load($oAppDocument->getDocUid()); + + if( !$oOutputDocument['OUT_DOC_VERSIONING'] ){ + throw(new Exception('The Output document has not versioning enabled!')); + } + break; + case "INPUT":// Input versioning + $o = new InputDocument(); + $oInputDocument = $o->load($oAppDocument->getDocUid()); + if( !$oInputDocument['INP_DOC_VERSIONING'] ){ + throw(new Exception('This Input document does not have the versioning enabled, for this reason this operation cannot be completed')); + } + break; + default://Not a valid type + throw(new Exception('The document is not of a valid Type')); + break; + } + + + $docVersion++; + } + + $oAppDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + $oAppDocument->setDocVersion($docVersion); + + $oAppDocument->setAppDocUid( $sUID ); + $oAppDocument->setAppDocIndex($this->getLastIndex( $oAppDocument->getAppUid() )+1); + if ($oAppDocument->validate()) { + $oConnection->begin(); + if (isset($aData['APP_DOC_TITLE'])) { + $oAppDocument->setAppDocTitle($aData['APP_DOC_TITLE']); + } + if (isset($aData['APP_DOC_COMMENT'])) { + $oAppDocument->setAppDocComment($aData['APP_DOC_COMMENT']); + } + if (isset($aData['APP_DOC_FILENAME'])) { + $oAppDocument->setAppDocFilename($aData['APP_DOC_FILENAME']); + } + $iResult = $oAppDocument->save(); + $oConnection->commit(); + $this->fromArray($oAppDocument->toArray( BasePeer::TYPE_FIELDNAME ), BasePeer::TYPE_FIELDNAME); + return $sUID; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application document registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + try { + $oAppDocument = AppDocumentPeer::retrieveByPK($aData['APP_DOC_UID'],$aData['DOC_VERSION']); + if (!is_null($oAppDocument)) + { + $oAppDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAppDocument->validate()) { + $oConnection->begin(); + if (isset($aData['APP_DOC_TITLE'])) + { + $oAppDocument->setAppDocTitle($aData['APP_DOC_TITLE']); + } + if (isset($aData['APP_DOC_COMMENT'])) + { + $oAppDocument->setAppDocComment($aData['APP_DOC_COMMENT']); + } + if (isset($aData['APP_DOC_FILENAME'])) + { + $oAppDocument->setAppDocFilename($aData['APP_DOC_FILENAME']); + } + $iResult = $oAppDocument->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry by changing status only + * Modified by Hugo Loza hugo@colosa.com + * @param array $aData + * @return string + **/ + public function remove($sAppDocUid,$iVersion=1) + { + $oConnection = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + try { + $oAppDocument = AppDocumentPeer::retrieveByPK($sAppDocUid,$iVersion); + if (!is_null($oAppDocument)){ + $arrayDocumentsToDelete=array(); + if($oAppDocument->getAppDocType()=="INPUT"){ + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDocumentPeer::APP_DOC_UID, $sAppDocUid); + $oDataset = AppDocumentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $arrayDocumentsToDelete[]=array('sAppDocUid'=>$aRow['APP_DOC_UID'],'iVersion'=>$aRow['DOC_VERSION']); + $oDataset->next(); + } + + }else{ + $arrayDocumentsToDelete[]=array('sAppDocUid'=>$sAppDocUid,'iVersion'=>$iVersion); + } + + foreach($arrayDocumentsToDelete as $key => $docToDelete){ + $aFields = array('APP_DOC_UID' => $docToDelete['sAppDocUid'], + 'DOC_VERSION' => $docToDelete['iVersion'], + 'APP_DOC_STATUS' => 'DELETED'); + + + $oAppDocument->update($aFields); + } + + + + + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Get the [app_doc_title] column value. + * @return string + */ + public function getAppDocTitle() + { + if ($this->app_doc_title == '') { + try { + $this->app_doc_title = Content::load('APP_DOC_TITLE', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + if($this->app_doc_title=="") $this->app_doc_title = Content::load('APP_DOC_TITLE', '', $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); //For backward compatibility + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->app_doc_title; + } + + /** + * Set the [app_doc_title] column value. + * + * @param string $sValue new value + * @return void + */ + public function setAppDocTitle($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->app_doc_title !== $sValue || $sValue === '') { + try { + $this->app_doc_title = $sValue; + $iResult = Content::addContent('APP_DOC_TITLE', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->app_doc_title); + } + catch (Exception $oError) { + $this->app_doc_title = ''; + throw($oError); + } + } + } + + /** + * Get the [app_doc_comment] column value. + * @return string + */ + public function getAppDocComment() + { + if ($this->app_doc_comment == '') { + try { + $this->app_doc_comment = Content::load('APP_DOC_COMMENT', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + if($this->app_doc_comment=="") $this->app_doc_comment = Content::load('APP_DOC_COMMENT', '', $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); //For backward compatibility + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->app_doc_comment; + } + + /** + * Set the [app_doc_comment] column value. + * + * @param string $sValue new value + * @return void + */ + public function setAppDocComment($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->app_doc_comment !== $sValue || $sValue === '') { + try { + $this->app_doc_comment = $sValue; + $iResult = Content::addContent('APP_DOC_COMMENT', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->app_doc_comment); + } + catch (Exception $oError) { + $this->app_doc_comment = ''; + throw($oError); + } + } + } + + /** + * Get the [app_doc_filename] column value. + * @return string + */ + public function getAppDocFilename() + { + if ($this->app_doc_filename == '') { + try { + $this->app_doc_filename = Content::load('APP_DOC_FILENAME', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + if($this->app_doc_filename=="") $this->app_doc_filename = Content::load('APP_DOC_FILENAME', '', $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); //For backward compatibility + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->app_doc_filename; + } + + /** + * Set the [app_doc_filename] column value. + * + * @param string $sValue new value + * @return void + */ + public function setAppDocFilename($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->app_doc_filename !== $sValue || $sValue === '') { + try { + $this->app_doc_filename = $sValue; + $iResult = Content::addContent('APP_DOC_FILENAME', $this->getDocVersion(), $this->getAppDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->app_doc_filename); + } + catch (Exception $oError) { + $this->app_doc_filename = ''; + throw($oError); + } + } + } + + public function isEmptyInContent ( $content, $field, $lang ) { + if ( isset ( $content[$field][ $lang ] ) ) { + if ( trim( $content[$field][ $lang ] ) != '' ) + return false; + }; + return true; + } + + public function updateInsertContent ( $content, $field, $value ) { + if ( isset ( $content[$field][ 'en' ] ) ) { + //update + $con = ContentPeer::retrieveByPK ( $field, $this->getDocVersion(), $this->getAppDocUid(), 'en' ); + $con->setConValue ( $value ); + if ($con->validate ()) { + $res = $con->save (); + } + } + else {//insert + $con = new Content ( ); + $con->setConCategory ( $field ); + $con->setConParent ($this->getDocVersion() ); + $con->setConId ( $this->getAppDocUid() ); + $con->setConLang ( 'en' ); + $con->setConValue ( $value ); + if ($con->validate ()) { + $res = $con->save (); + } + } + } + + public function normalizeContent( $content, $field , $lang ) { + $value = ''; + //if the lang row is not empty, update in 'en' row and continue + if ( !$this->isEmptyInContent ( $content, $field , $lang ) ) { + //update/insert only if this lang is != 'en', with this always we will have an en row with last value + $value = $content [ $field ][ $lang ]; + if ( $lang != 'en' ) { + $this->updateInsertContent ( $content, $field , $value ); + } + } + else { + //if the lang row is empty, and 'en' row is not empty return 'en' value + if ( !$this->isEmptyInContent ( $content, $field , 'en' ) ) { + $value = $content [ $field ][ 'en' ]; + } + + //if the lang row is empty, and 'en' row is empty get value for 'other' row and update in 'en' row and continue + if ( $this->isEmptyInContent ( $content, $field , 'en' ) ) { + if ( isset($content[$field]) && is_array ($content[$field] ) ) { + foreach ( $content [ $field ] as $lan => $val ) { + if ( trim ( $val ) != '' ) { + $value = $val; + if ( $lan != 'en' ) { + $this->updateInsertContent ( $content, $field , $value ); + continue; + } + } + } + } + else { + $this->updateInsertContent ( $content, $field , '' ); + } + } + } + return $value; + } + + /** + * Get the [app_description] , [app_title] column values. + * @return array of string + */ + public function getContentFields() + { + if ( $this->getAppDocUid() == '' ) { + throw ( new Exception( "Error in getContentFields, the APP_DOC_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn( ContentPeer::CON_CATEGORY ); + $c->addSelectColumn( ContentPeer::CON_PARENT ); + $c->addSelectColumn( ContentPeer::CON_LANG ); + $c->addSelectColumn( ContentPeer::CON_VALUE ); + $c->add( ContentPeer::CON_ID, $this->getAppDocUid() ); + $c->add( ContentPeer::CON_PARENT, $this->getDocVersion() ); + $c->addAscendingOrderByColumn('CON_CATEGORY'); + $c->addAscendingOrderByColumn('CON_LANG'); + $rs = ContentPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $content = array(); + while ($row = $rs->getRow()) { + $conCategory = $row['CON_CATEGORY']; + $conLang = $row['CON_LANG']; + if ( !isset( $content[$conCategory] ) ) $content[$conCategory] = array(); + if ( !isset( $content[$conCategory][$conLang] ) ) $content[$conCategory][$conLang] = array(); + $content[$conCategory][$conLang] = $row['CON_VALUE']; + $rs->next(); + $row = $rs->getRow(); + } + + $res['APP_DOC_TITLE'] = $this->normalizeContent( $content, 'APP_DOC_TITLE', $lang ); + $res['APP_DOC_COMMENT'] = $this->normalizeContent( $content, 'APP_DOC_COMMENT', $lang ); + $res['APP_DOC_FILENAME'] = $this->normalizeContent( $content, 'APP_DOC_FILENAME', $lang ); + return $res; + } + + +} // AppDocument \ No newline at end of file diff --git a/workflow/engine/classes/model/AppDocumentPeer.php b/workflow/engine/classes/model/AppDocumentPeer.php new file mode 100644 index 000000000..99b2754b8 --- /dev/null +++ b/workflow/engine/classes/model/AppDocumentPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * AppDocumentPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseAppDocumentPeer.php'; + + // include object class + include_once 'classes/model/AppDocument.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppDocumentPeer extends BaseAppDocumentPeer { + +} // AppDocumentPeer diff --git a/workflow/engine/classes/model/AppEvent.php b/workflow/engine/classes/model/AppEvent.php new file mode 100644 index 000000000..d9e8f2a0e --- /dev/null +++ b/workflow/engine/classes/model/AppEvent.php @@ -0,0 +1,307 @@ +<?php + +require_once 'classes/model/om/BaseAppEvent.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_EVENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppEvent extends BaseAppEvent { + public function load($sApplicationUID, $iDelegation) { + try { + $oAppEvent = AppEventPeer::retrieveByPK($sApplicationUID, $iDelegation); + if (!is_null($oAppEvent)) { + $aFields = $oAppEvent->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function create($aData) { + $oConnection = Propel::getConnection(AppEventPeer::DATABASE_NAME); + try { + $oAppEvent = new AppEvent(); + $oAppEvent->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAppEvent->validate()) { + $oConnection->begin(); + $iResult = $oAppEvent->save(); + $oConnection->commit(); + return true; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppEvent->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function update($aData) { + $oConnection = Propel::getConnection(AppEventPeer::DATABASE_NAME); + try { + $oAppEvent = AppEventPeer::retrieveByPK($aData['APP_UID'], $aData['DEL_INDEX']); + if (!is_null($oAppEvent)) { + $oAppEvent->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oAppEvent->validate()) { + $oConnection->begin(); + $iResult = $oAppEvent->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oAppEvent->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function remove($sApplicationUID, $iDelegation, $sEvnUid) { + $oConnection = Propel::getConnection(AppEventPeer::DATABASE_NAME); + try { + $oAppEvent = AppEventPeer::retrieveByPK($sApplicationUID, $iDelegation, $sEvnUid); + if (!is_null($oAppEvent)) { + $oConnection->begin(); + $iResult = $oAppEvent->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function getAppEventsCriteria($sProcessUid, $sStatus = '', $EVN_ACTION='') { + try { + require_once 'classes/model/Event.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppEventPeer::APP_UID); + $oCriteria->addSelectColumn(AppEventPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppEventPeer::EVN_UID); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ACTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ATTEMPTS); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_STATUS); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION); + $oCriteria->addAsColumn('EVN_DESCRIPTION', 'C1.CON_VALUE'); + $oCriteria->addAsColumn('TAS_TITLE', 'C2.CON_VALUE'); + $oCriteria->addAsColumn('APP_TITLE', 'C3.CON_VALUE'); + $oCriteria->addAlias('C1', 'CONTENT'); + $oCriteria->addAlias('C2', 'CONTENT'); + $oCriteria->addAlias('C3', 'CONTENT'); + $oCriteria->addJoin(AppEventPeer::EVN_UID, EventPeer::EVN_UID, Criteria::LEFT_JOIN); + $del = DBAdapter::getStringDelimiter(); + $aConditions = array(); + $aConditions[] = array(EventPeer::EVN_UID, 'C1.CON_ID'); + $aConditions[] = array('C1.CON_CATEGORY', $del . 'EVN_DESCRIPTION' . $del); + $aConditions[] = array('C1.CON_LANG', $del . SYS_LANG . $del); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $aConditions = array(); + $aConditions[] = array(AppEventPeer::APP_UID, AppDelegationPeer::APP_UID); + $aConditions[] = array(AppEventPeer::DEL_INDEX, AppDelegationPeer::DEL_INDEX); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::TAS_UID, 'C2.CON_ID'); + $aConditions[] = array('C2.CON_CATEGORY', $del . 'TAS_TITLE' . $del); + $aConditions[] = array('C2.CON_LANG', $del . SYS_LANG . $del); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::APP_UID, 'C3.CON_ID'); + $aConditions[] = array('C3.CON_CATEGORY', $del . 'APP_TITLE' . $del); + $aConditions[] = array('C3.CON_LANG', $del . SYS_LANG . $del); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(AppEventPeer::EVN_UID, '', Criteria::NOT_EQUAL); + $oCriteria->add(EventPeer::PRO_UID, $sProcessUid); + + if($EVN_ACTION != ''){ + $oCriteria->add(EventPeer::EVN_ACTION, $EVN_ACTION); + } + + switch ($sStatus) { + case '': + //Nothing + break; + case 'PENDING': + $oCriteria->add(AppEventPeer::APP_EVN_STATUS, 'OPEN'); + break; + case 'COMPLETED': + $oCriteria->add(AppEventPeer::APP_EVN_STATUS, 'CLOSE'); + break; + } + $oCriteria->addDescendingOrderByColumn(AppEventPeer::APP_EVN_ACTION_DATE); + return $oCriteria; + } + catch (Exception $oError) { + throw($oError); + } + } + + function executeEvents($sNow, $debug=false) { + + require_once 'classes/model/Configuration.php'; + require_once 'classes/model/Triggers.php'; + G::LoadClass('case'); + + $debug = 1; + $oCase = new Cases(); + + try { + $oCriteria = new Criteria('workflow'); + + $oCriteria->addSelectColumn(AppEventPeer::APP_UID); + $oCriteria->addSelectColumn(AppEventPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppEventPeer::EVN_UID); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ACTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ATTEMPTS); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_STATUS); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION); + $oCriteria->addSelectColumn(EventPeer::TRI_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION_PARAMETERS); + $oCriteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + $oCriteria->addSelectColumn(AppDelegationPeer::USR_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + + + $oCriteria->addJoin(AppEventPeer::EVN_UID, EventPeer::EVN_UID, Criteria::JOIN); + + $aConditions = array(); + array_push($aConditions, Array(AppEventPeer::APP_UID, AppDelegationPeer::APP_UID)); + array_push($aConditions, Array(AppEventPeer::DEL_INDEX, AppDelegationPeer::DEL_INDEX)); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $oCriteria->addJoin(ApplicationPeer::APP_UID, AppEventPeer::APP_UID); + + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); //by me + $oCriteria->add(AppEventPeer::APP_EVN_STATUS, 'OPEN'); + $oCriteria->add(AppEventPeer::APP_EVN_ACTION_DATE, $sNow, Criteria::LESS_EQUAL); + + $oDataset = AppEventPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $c = 0; + while ($oDataset->next()){ + + $c++; + $aRow = $oDataset->getRow(); + $oTrigger = new Triggers(); + $aFields = $oCase->loadCase($aRow['APP_UID']); + $oAppEvent = AppEventPeer::retrieveByPK($aRow['APP_UID'], $aRow['DEL_INDEX'], $aRow['EVN_UID']); + + //g::pr($aRow); //die; + + if($debug){ + require_once 'classes/model/Application.php'; + $oApp = ApplicationPeer::retrieveByPk($aRow['APP_UID']); + $oEv = EventPeer::retrieveByPk($aRow['EVN_UID']); + + println("\nOK+ event \"".$oEv->getEvnDescription()."\" with ID {$aRow['EVN_UID']} was found"); + println(" - PROCESS................".$aRow['PRO_UID']); + println(" - APPLICATION............".$aRow['APP_UID']." CASE #".$oApp->getAppNumber()); + println(" - ACTION DATE............".$aRow['APP_EVN_ACTION_DATE']); + println(" - ATTEMPTS...............".$aRow['APP_EVN_ATTEMPTS']); + println(" - INTERVAL WITH TASKS....".$aRow['EVN_RELATED_TO']); + } + + if ($aRow['TRI_UID'] == '') { + //a rare case when the tri_uid is not set. + if($debug) println(" (!) Any trigger was set................................SKIPPED and will be CLOSED"); + $oAppEvent->setAppEvnStatus('CLOSE'); + $oAppEvent->save(); + continue; + } + + $oTrigger = TriggersPeer::retrieveByPk($aRow['TRI_UID']); + if( !is_object($oTrigger) ){ + //the trigger record doesn't exist.. + if($debug) println(" (!) The trigger {$aRow['TRI_UID']} {$oTrigger->getTriTitle()} doesn't exist.......SKIPPED and will be CLOSED"); + $oAppEvent->setAppEvnStatus('CLOSE'); + $oAppEvent->save(); + continue; + } + + $oPMScript = new PMScript(); + + $oPMScript->setFields($aFields['APP_DATA']); + $oPMScript->setScript($oTrigger->getTriWebbot()); + + $oPMScript->execute(); + + $oAppEvent->setAppEvnLastExecutionDate(date('Y-m-d H:i:s')); + + if( sizeof($_SESSION['TRIGGER_DEBUG']['ERRORS']) == 0 ){ + if($debug) println(" - The trigger '{$oTrigger->getTriTitle()}' was executed successfully!"); + //g::pr($aFields); + $aFields['APP_DATA'] = $oPMScript->aFields; + $oCase->updateCase($aRow['APP_UID'], $aFields); + $oAppEvent->setAppEvnStatus('CLOSE'); + } else { + if($debug) { + println(" - The trigger {$aRow['TRI_UID']} throw some errors!"); + print_r($_SESSION['TRIGGER_DEBUG']['ERRORS']); + } + if ( $oAppEvent->getAppEvnAttempts() > 0 ){ + $oAppEvent->setAppEvnAttempts($oAppEvent->getAppEvnAttempts() - 1); + } else { + $oAppEvent->setAppEvnStatus('CLOSE'); + } + } + $oAppEvent->save(); + } + return $c; + } + catch (Exception $oError) { + die($oError->getMessage()); + return $oError->getMessage(); + } + } + + function close($APP_UID, $DEL_INDEX){ + $aRow = $this->load($APP_UID, $DEL_INDEX); + $aRow['APP_EVN_STATUS'] = 'CLOSE'; + $this->update($aRow); + } + +} // AppEvent diff --git a/workflow/engine/classes/model/AppEventPeer.php b/workflow/engine/classes/model/AppEventPeer.php new file mode 100644 index 000000000..c9866d089 --- /dev/null +++ b/workflow/engine/classes/model/AppEventPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppEventPeer.php'; + + // include object class + include_once 'classes/model/AppEvent.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_EVENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppEventPeer extends BaseAppEventPeer { + +} // AppEventPeer diff --git a/workflow/engine/classes/model/AppFolder.php b/workflow/engine/classes/model/AppFolder.php new file mode 100644 index 000000000..4d3a85fa4 --- /dev/null +++ b/workflow/engine/classes/model/AppFolder.php @@ -0,0 +1,424 @@ +<?php + +require_once 'classes/model/om/BaseAppFolder.php'; +require_once 'classes/model/Application.php'; + +/** + * Skeleton subclass for representing a row from the 'APP_FOLDER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +/** + * @author hugo loza + * + */ +class AppFolder extends BaseAppFolder { + /** + * @param string $folderName + * @param strin(32) $folderParent + * @return Ambigous <>|number + */ + function createFolder($folderName, $folderParent = "/") { + //Try to Load the folder (Foldername+FolderParent) + $oCriteria = new Criteria ( 'workflow' ); + $oCriteria->add ( AppFolderPeer::FOLDER_NAME, $folderName ); + $oCriteria->add ( AppFolderPeer::FOLDER_PARENT_UID, $folderParent ); + $oDataset = AppFolderPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + if ($aRow = $oDataset->getRow ()) { //Folder exist, then return the ID + return ($aRow ['FOLDER_UID']); + } else { //Folder doesn't exist. Create and return the ID + + + $folderUID = G::GenerateUniqueID (); + $tr = new AppFolder ( ); + $tr->setFolderUid ( $folderUID ); + $tr->setFolderParentUid ( $folderParent ); + $tr->setFolderName ( $folderName ); + $tr->setFolderCreateDate ( 'now' ); + $tr->setFolderUpdateDate ( 'now' ); + if ($tr->validate ()) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save (); + return $folderUID; + } else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures (); + foreach ( $validationFailuresArray as $objValidationFailure ) { + $msg .= $objValidationFailure->getMessage () . "<br/>"; + } + krumo ( $msg ); + } + } + } + /** + * @param string $folderPath + * @param strin(32) $sessionID + * @return string Last Folder ID generated + */ + function createFromPath($folderPath, $sessionID = "") { + if ($sessionID == "") + $sessionID = $_SESSION ['APPLICATION']; + //Get current Application Fields + $oApplication = new Application ( ); + + $appFields = $oApplication->Load ( $sessionID ); + + $folderPathParsed = G::replaceDataField ( $folderPath, $appFields ); + $folderPathParsed = G::replaceDataField ( $folderPath, unserialize ( $appFields ['APP_DATA'] ) ); + + $folderPathParsedArray = explode ( "/", $folderPathParsed ); + + $folderRoot = "/"; //Always starting from Root + foreach ( $folderPathParsedArray as $folderName ) { + if (trim ( $folderName ) != "") { + $folderRoot = $this->createFolder ( $folderName, $folderRoot ); + } + } + return $folderRoot != "/" ? $folderRoot : ""; + } + + /** + * @param string $fileTags + * @param string(32) $sessionID Application ID + * @return string + */ + function parseTags($fileTags, $sessionID = "") { + + if ($sessionID == "") + $sessionID = $_SESSION ['APPLICATION']; + //Get current Application Fields + $oApplication = new Application ( ); + + $appFields = $oApplication->Load ( $sessionID ); + + $fileTagsParsed = G::replaceDataField ( $fileTags, $appFields ); + $fileTagsParsed = G::replaceDataField ( $fileTags, unserialize ( $appFields ['APP_DATA'] ) ); + + return $fileTagsParsed; + } + /** + * @param string(32) $folderID + * @return multitype: + */ + function getFolderList($folderID) { + $Criteria = new Criteria ( 'workflow' ); + $Criteria->clearSelectColumns ()->clearOrderByColumns (); + + $Criteria->addSelectColumn ( AppFolderPeer::FOLDER_UID ); + $Criteria->addSelectColumn ( AppFolderPeer::FOLDER_PARENT_UID ); + $Criteria->addSelectColumn ( AppFolderPeer::FOLDER_NAME ); + $Criteria->addSelectColumn ( AppFolderPeer::FOLDER_CREATE_DATE ); + $Criteria->addSelectColumn ( AppFolderPeer::FOLDER_UPDATE_DATE ); + + $Criteria->add ( appFolderPeer::FOLDER_PARENT_UID, $folderID, CRITERIA::EQUAL ); + + $Criteria->addAscendingOrderByColumn ( AppFolderPeer::FOLDER_NAME ); + + $rs = appFolderPeer::doSelectRS ( $Criteria ); + $rs->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $rs->next (); + $folderResult = array (); + while ( is_array ( $row = $rs->getRow () ) ) { + $folderResult [] = $row; + $rs->next (); + } + return ($folderResult); + } + /** + * @param string(32) $folderUid + * @return array <multitype:, mixed> + */ + function load($folderUid) { + $tr = AppFolderPeer::retrieveByPK ( $folderUid ); + if ((is_object ( $tr ) && get_class ( $tr ) == 'AppFolder')) { + $fields ['FOLDER_UID'] = $tr->getFolderUid (); + $fields ['FOLDER_PARENT_UID'] = $tr->getFolderParentUid (); + $fields ['FOLDER_NAME'] = $tr->getFolderName (); + $fields ['FOLDER_CREATE_DATE'] = $tr->getFolderCreateDate (); + $fields ['FOLDER_UPDATE_DATE'] = $tr->getFolderUpdateDate (); + } elseif ($folderUid == "/") { + $fields ['FOLDER_UID'] = "/"; + $fields ['FOLDER_PARENT_UID'] = ""; + $fields ['FOLDER_NAME'] = "/"; + $fields ['FOLDER_CREATE_DATE'] = ""; + $fields ['FOLDER_UPDATE_DATE'] = ""; + } else { + $fields = array (); + } + return $fields; + } + function getFolderStructure($folderId) { + + $folderObj = $this->load ( $folderId ); + $folderArray [$folderObj ['FOLDER_UID']] = array ("NAME" => $folderObj ['FOLDER_NAME'], "PARENT" => $folderObj ['FOLDER_PARENT_UID'] ); + $folderArray ['PATH_ARRAY'] [] = $folderObj ['FOLDER_NAME']; + + while ( $folderObj ['FOLDER_PARENT_UID'] != "" ) { + $folderObj = $this->load ( $folderObj ['FOLDER_PARENT_UID'] ); + $folderArray [$folderObj ['FOLDER_UID']] = array ("NAME" => $folderObj ['FOLDER_NAME'], "PARENT" => $folderObj ['FOLDER_PARENT_UID'] ); + $folderArray ['PATH_ARRAY'] [] = $folderObj ['FOLDER_NAME']; + } + + $folderArray ['PATH'] = str_replace ( "//", "/", implode ( "/", array_reverse ( $folderArray ['PATH_ARRAY'] ) ) ); + return $folderArray; + } + + function getFolderContent($folderID, $docIdFilter = array(), $keyword = NULL, $searchType = NULL) { + require_once ("classes/model/AppDocument.php"); + require_once ("classes/model/InputDocument.php"); + require_once ("classes/model/OutputDocument.php"); + require_once ("classes/model/Users.php"); + + G::LoadClass ( 'case' ); + $oCase = new Cases ( ); + G::LoadClass ( 'process' ); + $oProcess = new Process ( ); + + $oAppDocument = new AppDocument ( ); + $oCriteria = new Criteria ( ); + if ((is_array ( $docIdFilter )) && (count ( $docIdFilter ) > 0)) { //Search by App Doc UID no matter what Folder it is + $oCriteria->add ( AppDocumentPeer::APP_DOC_UID, $docIdFilter, CRITERIA::IN ); + } elseif ($folderID != NULL) { + $oCriteria->add ( AppDocumentPeer::FOLDER_UID, $folderID ); + } elseif ($searchType == "TAG") { + $oCriteria->add ( AppDocumentPeer::APP_DOC_TAGS, "%" . $keyword . "%", CRITERIA::LIKE ); + } + + $oCase->verifyTable (); + + $oCriteria->addAscendingOrderByColumn ( AppDocumentPeer::APP_DOC_INDEX ); + + $rs = AppDocumentPeer::doSelectRS ( $oCriteria ); + $rs->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $rs->next (); + $filesResult = array (); + while ( is_array ( $row = $rs->getRow () ) ) { + //**** start get Doc Info + $oApp = new Application ( ); + if (($oApp->exists ( $row ['APP_UID'] )) || ($row ['APP_UID'] == "00000000000000000000000000000000")) { + + $completeInfo = $this->getCompleteDocumentInfo ( $row ['APP_UID'], $row ['APP_DOC_UID'], $row ['DOC_VERSION'], $row ['DOC_UID'], $row ['USR_UID'] ); + + $oAppDocument = new AppDocument ( ); + $lastVersion = $oAppDocument->getLastAppDocVersion ( $row ['APP_DOC_UID'], $row ['APP_UID'] ); + + if ($completeInfo ['APP_DOC_STATUS'] != "DELETED") { + if ((in_array ( $row ['APP_DOC_UID'], $completeInfo ['INPUT_DOCUMENTS'] )) || (in_array ( $row ['APP_DOC_UID'], $completeInfo ['OUTPUT_DOCUMENTS'] )) || (in_array ( $completeInfo ['USR_UID'], array ($_SESSION ['USER_LOGGED'], '-1' ) ))) { + if (count ( $docIdFilter ) > 0) { + if (in_array ( $row ['APP_DOC_UID'], $docIdFilter )) { + $filesResult [] = $completeInfo; + } + } elseif ($lastVersion == $row ['DOC_VERSION']) { //Only Last Document version + if ($searchType == "ALL") {// If search in name of docs is active then filter + if ((stripos ( $completeInfo ['APP_DOC_FILENAME'], $keyword ) !== false) || (stripos ( $completeInfo ['APP_DOC_TAGS'], $keyword ) !== false)) { + $filesResult [] = $completeInfo; + } + } else {//No search filter active + $filesResult [] = $completeInfo; + } + } + + } + } + } + $rs->next (); + } + return ($filesResult); + } + function getCompleteDocumentInfo($appUid, $appDocUid, $docVersion, $docUid, $usrId) { + require_once ("classes/model/AppDocument.php"); + require_once ("classes/model/InputDocument.php"); + require_once ("classes/model/OutputDocument.php"); + require_once ("classes/model/Users.php"); + //**** start get Doc Info + $oApp = new Application ( ); + $oAppDocument = new AppDocument ( ); + G::LoadClass ( 'case' ); + $oCase = new Cases ( ); + G::LoadClass ( 'process' ); + $oProcess = new Process ( ); + if (($oApp->exists ( $appUid )) || ($appUid == "00000000000000000000000000000000")) { + if ($appUid == "00000000000000000000000000000000") { //External Files + $row1 = $oAppDocument->load ( $appDocUid, $docVersion ); + $row2 = array ('PRO_TITLE' => G::LoadTranslation ( 'ID_NOT_PROCESS_RELATED' ) ); + $row3 = array ('APP_TITLE' => G::LoadTranslation ( 'ID_NOT_PROCESS_RELATED' ) ); + } else { + $row1 = $oAppDocument->load ( $appDocUid, $docVersion ); + $row2 = $oCase->loadCase ( $appUid ); + $row3 = $oProcess->Load ( $row2 ['PRO_UID'] ); + } + $lastVersion = $oAppDocument->getLastAppDocVersion ( $appDocUid, $appUid ); + + switch ($row1 ['APP_DOC_TYPE']) { + case "OUTPUT" : + $oOutputDocument = new OutputDocument ( ); + $row4 = $oOutputDocument->load ( $docUid ); + $versioningEnabled = false; //$row4['OUT_DOC_VERSIONING']; //Only enabled for Input or Attached documents. Need to study the best way for Output docs. + switch ($row4 ['OUT_DOC_GENERATE']) { + case "PDF" : + $downloadLink = "../cases/cases_ShowOutputDocument?a=" . $appDocUid . "&v=" . $docVersion . "&ext=pdf" . "&random=" . rand (); + $downloadLink1 = ""; + $downloadLabel = ".pdf"; + $downloadLabel1 = ""; + break; + case "DOC" : + $downloadLink = "../cases/cases_ShowOutputDocument?a=" . $appDocUid . "&v=" . $docVersion . "&ext=doc" . "&random=" . rand (); + $downloadLink1 = ""; + $downloadLabel = ".doc"; + $downloadLabel1 = ""; + break; + case "BOTH" : + $downloadLink = "../cases/cases_ShowOutputDocument?a=" . $appDocUid . "&v=" . $docVersion . "&ext=pdf" . "&random=" . rand (); + $downloadLink1 = "../cases/cases_ShowOutputDocument?a=" . $appDocUid . "&v=" . $docVersion . "&ext=doc" . "&random=" . rand (); + $downloadLabel = ".pdf"; + $downloadLabel1 = ".doc"; + break; + } + + break; + case "INPUT" : + $oInputDocument = new InputDocument ( ); + if ($docUid != - 1) { + if ($oInputDocument->InputExists ( $docUid )) { + $row4 = $oInputDocument->load ( $docUid ); + $versioningEnabled = $row4 ['INP_DOC_VERSIONING']; + } else { + $row4 = array (); + $versioningEnabled = false; + } + $downloadLink = "../cases/cases_ShowDocument?a=" . $appDocUid . "&v=" . $docVersion; + $downloadLink1 = ""; + $downloadLabel = G::LoadTranslation ( 'ID_DOWNLOAD' ); + $downloadLabel1 = ""; + } else { + $row4 = array (); + $versioningEnabled = false; + $downloadLink = "../cases/cases_ShowDocument?a=" . $appDocUid . "&v=" . $docVersion; + $downloadLink1 = ""; + $downloadLabel = G::LoadTranslation ( 'ID_DOWNLOAD' ); + $downloadLabel1 = ""; + } + break; + default : + $row4 = array (); + $versioningEnabled = false; + $downloadLink = "../cases/cases_ShowDocument?a=" . $appDocUid . "&v=" . $docVersion; + $downloadLink1 = ""; + $downloadLabel = G::LoadTranslation ( 'ID_DOWNLOAD' ); + $downloadLabel1 = ""; + break; + + } + $oUser = new Users ( ); + if ($usrId != "-1") { + $row5 = $oUser->load ( $usrId ); + } else { + $row5 ['USR_USERNAME'] = "***"; + } + + //Labels/Links + $row6 = array (); + $row6 ['DELETE_LABEL'] = G::LoadTranslation('ID_DELETE'); + $row6 ['DOWNLOAD_LABEL'] = $downloadLabel; + $row6 ['DOWNLOAD_LINK'] = $downloadLink; + $row6 ['DOWNLOAD_LABEL1'] = $downloadLabel1; + $row6 ['DOWNLOAD_LINK1'] = $downloadLink1; + //if(($docVersion>1)&&($row1['APP_DOC_TYPE']!="OUTPUT")){ + if (($docVersion > 1)) { + $row6 ['VERSIONHISTORY_LABEL'] = G::LoadTranslation ( 'ID_VERSION_HISTORY' ); + } + if ($versioningEnabled) { + $row6 ['NEWVERSION_LABEL'] = G::LoadTranslation ( 'ID_NEW_VERSION' ); + } + $row6 ['APP_DOC_UID_VERSION'] = $appDocUid . "_" . $docVersion; + + if ($appUid == "00000000000000000000000000000000") { //External Files + $row1 ['APP_DOC_TYPE'] = G::LoadTranslation ( 'ID_EXTERNAL_FILE' ); + } + //**** End get docinfo + + + $infoMerged = array_merge ( $row1, $row2, $row3, $row4, $row5, $row6 ); + //krumo($infoMerged); + //**************************************************************************************************** + $sUserUID = $_SESSION ['USER_LOGGED']; + $aObjectPermissions = array (); + if (isset ( $infoMerged ['PRO_UID'] )) { + $aObjectPermissions = $oCase->getAllObjects ( $infoMerged ['PRO_UID'], $infoMerged ['APP_UID'], '', $sUserUID ); + } + + if (! is_array ( $aObjectPermissions )) { + $aObjectPermissions = array ('DYNAFORMS' => array (- 1 ), 'INPUT_DOCUMENTS' => array (- 1 ), 'OUTPUT_DOCUMENTS' => array (- 1 ) ); + } + if (! isset ( $aObjectPermissions ['DYNAFORMS'] )) { + $aObjectPermissions ['DYNAFORMS'] = array (- 1 ); + } else { + if (! is_array ( $aObjectPermissions ['DYNAFORMS'] )) { + $aObjectPermissions ['DYNAFORMS'] = array (- 1 ); + } + } + if (! isset ( $aObjectPermissions ['INPUT_DOCUMENTS'] )) { + $aObjectPermissions ['INPUT_DOCUMENTS'] = array (- 1 ); + } else { + if (! is_array ( $aObjectPermissions ['INPUT_DOCUMENTS'] )) { + $aObjectPermissions ['INPUT_DOCUMENTS'] = array (- 1 ); + } + } + if (! isset ( $aObjectPermissions ['OUTPUT_DOCUMENTS'] )) { + $aObjectPermissions ['OUTPUT_DOCUMENTS'] = array (- 1 ); + } else { + if (! is_array ( $aObjectPermissions ['OUTPUT_DOCUMENTS'] )) { + $aObjectPermissions ['OUTPUT_DOCUMENTS'] = array (- 1 ); + } + } + //**************************************************************************************************** + + + return array_merge ( $infoMerged, $aObjectPermissions ); + } + } + function getFolderChilds($folderID, $folderArray) { + $folderList = $this->getFolderList ( $folderID ); + $foldersList = array (); + foreach ( $folderList as $key => $folderObj ) { + $foldersList [$folderObj ['FOLDER_UID']] = $folderObj ['FOLDER_NAME']; + $foldersList = array_merge ( $foldersList, $this->getFolderChilds ( $folderObj ['FOLDER_UID'], $folderArray ) ); + } + return (array_merge ( $folderArray, $foldersList )); + } + + function getFolderTags($rootFolder) { + $folderArray [$rootFolder] = $rootFolder; + $foldersToProcess = $this->getFolderChilds ( $rootFolder, $folderArray ); + $tagsInfo = array (); + + foreach ( $foldersToProcess as $folderkey => $foldername ) { + $filesList = $this->getFolderContent ( $folderkey ); + + foreach ( $filesList as $key => $fileInfo ) { + $fileTags = explode ( ",", $fileInfo ['APP_DOC_TAGS'] ); + foreach ( $fileTags as $key1 => $tag ) { + if (! (isset ( $tagsInfo [$tag] ))) + $tagsInfo [$tag] = 0; + $tagsInfo [$tag] ++; + } + } + } + return $tagsInfo; + + } + function remove ($FolderUid, $rootfolder ) { + $oCriteria = new Criteria('workflow'); + $oCriteria->add ( AppFolderPeer::FOLDER_UID, $FolderUid ); + AppFolderPeer::doDelete($oCriteria); + } +} // AppFolder \ No newline at end of file diff --git a/workflow/engine/classes/model/AppFolderPeer.php b/workflow/engine/classes/model/AppFolderPeer.php new file mode 100644 index 000000000..0b441f765 --- /dev/null +++ b/workflow/engine/classes/model/AppFolderPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppFolderPeer.php'; + + // include object class + include_once 'classes/model/AppFolder.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_FOLDER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppFolderPeer extends BaseAppFolderPeer { + +} // AppFolderPeer diff --git a/workflow/engine/classes/model/AppHistory.php b/workflow/engine/classes/model/AppHistory.php new file mode 100644 index 000000000..0eb04bc92 --- /dev/null +++ b/workflow/engine/classes/model/AppHistory.php @@ -0,0 +1,199 @@ +<?php + +require_once 'classes/model/om/BaseAppHistory.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_HISTORY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppHistory extends BaseAppHistory { + + function insertHistory($aData){ + + $this->setAppUid($aData['APP_UID']); + $this->setDelIndex($aData['DEL_INDEX']); + $this->setProUid($aData['PRO_UID']); + $this->setTasUid($aData['TAS_UID']); + $this->setDynUid($aData['CURRENT_DYNAFORM']); + $this->setUsrUid($aData['USER_UID']); + $this->setAppStatus($aData['APP_STATUS']); + $this->setHistoryDate($aData['APP_UPDATE_DATE']); + $this->setHistoryData($aData['APP_DATA']); + + + if ($this->validate() ) { + $res = $this->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $this->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + krumo($msg); + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + + + + + + } + + function getDynaformHistory($PRO_UID,$TAS_UID,$APP_UID,$DYN_UID=""){ + G::LoadClass('case'); + $oCase = new Cases(); + + $oCase->verifyTable(); + + $aObjectPermissions = $oCase->getAllObjects($PRO_UID, $APP_UID, $TAS_UID, $_SESSION['USER_LOGGED']); + + if (!is_array($aObjectPermissions)) { + $aObjectPermissions = array('DYNAFORMS' => array(-1), 'INPUT_DOCUMENTS' => array(-1), 'OUTPUT_DOCUMENTS' => array(-1)); + } + if (!isset($aObjectPermissions['DYNAFORMS'])) { + $aObjectPermissions['DYNAFORMS'] = array(-1); + } + else { + if (!is_array($aObjectPermissions['DYNAFORMS'])) { + $aObjectPermissions['DYNAFORMS'] = array(-1); + } + } + if (!isset($aObjectPermissions['INPUT_DOCUMENTS'])) { + $aObjectPermissions['INPUT_DOCUMENTS'] = array(-1); + } + else { + if (!is_array($aObjectPermissions['INPUT_DOCUMENTS'])) { + $aObjectPermissions['INPUT_DOCUMENTS'] = array(-1); + } + } + if (!isset($aObjectPermissions['OUTPUT_DOCUMENTS'])) { + $aObjectPermissions['OUTPUT_DOCUMENTS'] = array(-1); + } + else { + if (!is_array($aObjectPermissions['OUTPUT_DOCUMENTS'])) { + $aObjectPermissions['OUTPUT_DOCUMENTS'] = array(-1); + } + } + + + + + + $c = new Criteria('workflow'); + $c->addSelectColumn(AppHistoryPeer::APP_UID); + $c->addSelectColumn(AppHistoryPeer::DEL_INDEX); + $c->addSelectColumn(AppHistoryPeer::PRO_UID); + $c->addSelectColumn(AppHistoryPeer::TAS_UID); + $c->addSelectColumn(AppHistoryPeer::DYN_UID); + $c->addSelectColumn(AppHistoryPeer::USR_UID); + $c->addSelectColumn(AppHistoryPeer::APP_STATUS); + $c->addSelectColumn(AppHistoryPeer::HISTORY_DATE); + $c->addSelectColumn(AppHistoryPeer::HISTORY_DATA); + $c->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $c->addSelectColumn(UsersPeer::USR_LASTNAME); + $c->addAsColumn('USR_NAME', "CONCAT(USR_LASTNAME, ' ', USR_FIRSTNAME)"); + $c->addJoin(AppHistoryPeer::USR_UID, UsersPeer::USR_UID, Criteria::LEFT_JOIN); + + + //WHERE + $c->add(AppHistoryPeer::DYN_UID, $aObjectPermissions['DYNAFORMS'], Criteria::IN); + $c->add(AppHistoryPeer::PRO_UID, $PRO_UID); + $c->add(AppHistoryPeer::TAS_UID, $TAS_UID); + $c->add(AppHistoryPeer::APP_UID, $APP_UID); + if((isset($DYN_UID))&&($DYN_UID!="")){ + $c->add(AppHistoryPeer::DYN_UID, $DYN_UID); + } + + //ORDER BY + $c->clearOrderByColumns(); + $c->addDescendingOrderByColumn(AppHistoryPeer::HISTORY_DATE); + + + //Execute + $oDataset = AppHistoryPeer::doSelectRS($c); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + $aDynHistory = array(); + $aDynHistory[] = array( + 'DYN_TITLE' => 'char' + ); + + while ($aRow = $oDataset->getRow()) { + + $o = new Dynaform(); + $o->setDynUid($aRow['DYN_UID']); + $aRow['DYN_TITLE'] = $o->getDynTitle(); + $changedValues=unserialize($aRow['HISTORY_DATA']); + $html="<table border='0' cellpadding='0' cellspacing='0'>"; + $sw_add=false; + foreach($changedValues as $key =>$value){ + if(($value!=NULL)&&(!is_array($value))){ + $sw_add=true; + $html.="<tr>"; + $html.="<td><b>$key:</b> </td>"; + $html.="<td>$value</td>"; + $html.="</tr>"; + } + if(is_array($value)){ + $html.="<tr>"; + $html.="<td><b>$key (grid):</b> </td>"; + $html.="<td>"; + $html.="<table>"; + foreach($value as $key1 =>$value1){ + $html.="<tr>"; + $html.="<td><b>$key1</b></td>"; + $html.="<td>"; + if(is_array($value1)){ + $sw_add=true; + $html.="<table>"; + foreach($value1 as $key2 =>$value2){ + $html.="<tr>"; + $html.="<td><b>$key2</b></td>"; + $html.="<td>$value2</td>"; + $html.="</tr>"; + } + $html.="</table>"; + } + $html.="</td>"; + $html.="</tr>"; + + } + $html.="</table>"; + $html.="</td>"; + $html.="</tr>"; + $html.="</td>"; + } + } + $html.="</table>"; + + $aRow['FIELDS'] = $html; + + if($sw_add){ + $aDynHistory[] = $aRow; + } + $oDataset->next(); + } + + global $_DBArray; + $_DBArray['DynaformsHistory'] = $aDynHistory; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('DynaformsHistory'); + $oCriteria->addDescendingOrderByColumn(AppHistoryPeer::HISTORY_DATE); + return $oCriteria; + + } + +} // AppHistory diff --git a/workflow/engine/classes/model/AppHistoryPeer.php b/workflow/engine/classes/model/AppHistoryPeer.php new file mode 100644 index 000000000..65cd2abaa --- /dev/null +++ b/workflow/engine/classes/model/AppHistoryPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppHistoryPeer.php'; + + // include object class + include_once 'classes/model/AppHistory.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_HISTORY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppHistoryPeer extends BaseAppHistoryPeer { + +} // AppHistoryPeer diff --git a/workflow/engine/classes/model/AppMessage.php b/workflow/engine/classes/model/AppMessage.php new file mode 100644 index 000000000..5ed66fa79 --- /dev/null +++ b/workflow/engine/classes/model/AppMessage.php @@ -0,0 +1,120 @@ +<?php +/** + * AppMessage.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseAppMessage.php'; + +/** + * Skeleton subclass for representing a row from the 'APP_MESSAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppMessage extends BaseAppMessage { + + private $data_spool; + private $status_spool; + private $error_spool; + + public function getSpoolStatus() { + return $this->status_spool; + } + + public function getSpoolError() { + return $this->error_spool; + } + + + /** + * AppMessgae quick Save method + * @Param Array(msg_uid, app_uid, del_index, app_msg_type, app_msg_subject, app_msg_from, app_msg_to, + * app_msg_body, app_msg_cc, app_msg_bcc, app_msg_attach, app_msg_template, app_msg_status ) + * + * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmai.com> + * @Date Aug 31th, 2009 + */ + public function quickSave2($data_spool) { + $this->data_spool = $data_spool; + + $sUID = G::generateUniqueID(); + $spool = new AppMessage(); + + $spool->setAppMsgUid($sUID); + $spool->setMsgUid($data_spool['msg_uid']); + $spool->setAppUid($data_spool['app_uid']); + $spool->setDelIndex($data_spool['del_index']); + $spool->setAppMsgType($data_spool['app_msg_type']); + $spool->setAppMsgSubject($data_spool['app_msg_subject']); + $spool->setAppMsgFrom($data_spool['app_msg_from']); + $spool->setAppMsgTo($data_spool['app_msg_to']); + $spool->setAppMsgBody($data_spool['app_msg_body']); + $spool->setAppMsgDate(date('Y-m-d H:i:s')); + $spool->setAppMsgCc($data_spool['app_msg_cc']); + $spool->setAppMsgBcc($data_spool['app_msg_bcc']); + $spool->setappMsgAttach($data_spool['app_msg_attach']); + $spool->setAppMsgTemplate($data_spool['app_msg_template']); + $spool->setAppMsgStatus($data_spool['app_msg_status']); + + if( !$spool->validate() ) { + $this->error_spool = $spool->getValidationFailures(); + $this->status_spool = 'error'; + + $error_msg = "AppMessage::quickSave(): Validation error: \n"; + foreach($errors as $key=>$value) { + $error_msg .= $value->getMessage($key) . "\n"; + } + throw new Exception($error_msg); + } else { + //echo "Saving - validation ok\n"; + $this->error_spool = ''; + $this->status = 'success'; + $spool->save(); + } + return $sUID; + } + + + public function quickSave($aData){ + if(isset($aData['app_msg_uid'])) { + $o = EmployeePeer::retrieveByPk($aData['app_msg_uid']); + } + if (isset($o) && get_class($o) == 'AppMessage') { + $o->fromArray($aData, BasePeer::TYPE_FIELDNAME); + $o->setAppMsgDate(date('Y-m-d H:i:s')); + $o->save(); + return $o->getAppMsgUid(); + } else { + $this->fromArray($aData, BasePeer::TYPE_FIELDNAME); + $this->setAppMsgDate(date('Y-m-d H:i:s')); + $this->save(); + return $this->getAppMsgUid(); + } + } + +} // AppMessage diff --git a/workflow/engine/classes/model/AppMessagePeer.php b/workflow/engine/classes/model/AppMessagePeer.php new file mode 100644 index 000000000..7f562a1b2 --- /dev/null +++ b/workflow/engine/classes/model/AppMessagePeer.php @@ -0,0 +1,46 @@ +<?php +/** + * AppMessagePeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseAppMessagePeer.php'; + + // include object class + include_once 'classes/model/AppMessage.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_MESSAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppMessagePeer extends BaseAppMessagePeer { + +} // AppMessagePeer diff --git a/workflow/engine/classes/model/AppOwner.php b/workflow/engine/classes/model/AppOwner.php new file mode 100644 index 000000000..c7025e36b --- /dev/null +++ b/workflow/engine/classes/model/AppOwner.php @@ -0,0 +1,42 @@ +<?php +/** + * AppOwner.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseAppOwner.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_OWNER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppOwner extends BaseAppOwner { + +} // AppOwner diff --git a/workflow/engine/classes/model/AppOwnerPeer.php b/workflow/engine/classes/model/AppOwnerPeer.php new file mode 100644 index 000000000..0290b1576 --- /dev/null +++ b/workflow/engine/classes/model/AppOwnerPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * AppOwnerPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseAppOwnerPeer.php'; + + // include object class + include_once 'classes/model/AppOwner.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_OWNER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppOwnerPeer extends BaseAppOwnerPeer { + +} // AppOwnerPeer diff --git a/workflow/engine/classes/model/AppSpool.php b/workflow/engine/classes/model/AppSpool.php new file mode 100644 index 000000000..bbaa2d28e --- /dev/null +++ b/workflow/engine/classes/model/AppSpool.php @@ -0,0 +1,19 @@ +<?php + +require_once 'classes/model/om/BaseAppSpool.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_SPOOL' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppSpool extends BaseAppSpool { + +} // AppSpool diff --git a/workflow/engine/classes/model/AppSpoolPeer.php b/workflow/engine/classes/model/AppSpoolPeer.php new file mode 100644 index 000000000..233a496c4 --- /dev/null +++ b/workflow/engine/classes/model/AppSpoolPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseAppSpoolPeer.php'; + + // include object class + include_once 'classes/model/AppSpool.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_SPOOL' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppSpoolPeer extends BaseAppSpoolPeer { + +} // AppSpoolPeer diff --git a/workflow/engine/classes/model/AppThread.php b/workflow/engine/classes/model/AppThread.php new file mode 100644 index 000000000..a65ad8cb7 --- /dev/null +++ b/workflow/engine/classes/model/AppThread.php @@ -0,0 +1,121 @@ +<?php +/** + * AppThread.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseAppThread.php'; + + +/** + * Skeleton subclass for representing a row from the 'APP_THREAD' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppThread extends BaseAppThread { + + function createAppThread ( $sAppUid, $iDelIndex, $iParent ) { + if (!isset($sAppUid) || strlen($sAppUid ) == 0 ) { + throw ( new Exception ( 'Column "APP_UID" cannot be null.' ) ); + } + + if (!isset($iDelIndex) || strlen($iDelIndex ) == 0 ) { + throw ( new Exception ( 'Column "DEL_INDEX" cannot be null.' ) ); + } + + if (!isset($iParent) || strlen($iDelIndex ) == 0 ) { + throw ( new Exception ( 'Column "APP_THREAD_INDEX" cannot be null.' ) ); + } + + $c = new Criteria (); + $c->clearSelectColumns(); + $c->addSelectColumn ( 'MAX(' . AppThreadPeer::APP_THREAD_INDEX . ') ' ); + $c->add ( AppThreadPeer::APP_UID, $sAppUid ); + $rs = AppThreadPeer::doSelectRS ( $c ); + $rs->next(); + $row = $rs->getRow(); + $iAppThreadIndex = $row[0] + 1; + + $this->setAppUid ( $sAppUid ); + $this->setAppThreadIndex ( $iAppThreadIndex ); + $this->setAppThreadParent ( $iParent ); + $this->setAppThreadStatus ( 'OPEN' ); + $this->setDelIndex ( $iDelIndex ); + + if ($this->validate() ) { + try { + $res = $this->save(); + } + catch ( PropelException $e ) { + throw ( $e ); + } + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $this->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage(); + } + throw ( new Exception ( 'Failed Data validation. ' . $msg ) ); + } + return $iAppThreadIndex; + } + + public function update($aData) + { + $con = Propel::getConnection( AppThreadPeer::DATABASE_NAME ); + try { + $con->begin(); + $oApp = AppThreadPeer::retrieveByPK( $aData['APP_UID'], $aData['APP_THREAD_INDEX'] ); + if ( get_class ($oApp) == 'AppThread' ) { + $oApp->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oApp->validate()) { + $res = $oApp->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The AppThread row cannot be created!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "This AppThread row doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + +} // AppThread diff --git a/workflow/engine/classes/model/AppThreadPeer.php b/workflow/engine/classes/model/AppThreadPeer.php new file mode 100644 index 000000000..9a2d0be38 --- /dev/null +++ b/workflow/engine/classes/model/AppThreadPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * AppThreadPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseAppThreadPeer.php'; + + // include object class + include_once 'classes/model/AppThread.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APP_THREAD' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class AppThreadPeer extends BaseAppThreadPeer { + +} // AppThreadPeer diff --git a/workflow/engine/classes/model/Application.php b/workflow/engine/classes/model/Application.php new file mode 100644 index 000000000..69abc8d89 --- /dev/null +++ b/workflow/engine/classes/model/Application.php @@ -0,0 +1,533 @@ +<?php +/** + * Application.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseApplication.php'; +require_once 'classes/model/Content.php'; + + +/** + * Skeleton subclass for representing a row from the 'APPLICATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Application extends BaseApplication { + + /** + * This value goes in the content table + * @var string + */ + protected $app_title = ''; + protected $app_description = ''; + //protected $app_proc_code = ''; + + /** + * Get the [app_title] column value. + * @return string + */ + public function getAppTitle() + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in getAppTitle, the APP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->app_title = Content::load ( 'APP_TITLE', '', $this->getAppUid(), $lang ); + return $this->app_title; + } + + /** + * Set the [app_title] column value. + * + * @param string $v new value + * @return void + */ + public function setAppTitle($v) + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in setAppTitle, the APP_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_title !== $v || $v === '') { + $this->app_title = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'APP_TITLE', '', $this->getAppUid(), $lang, $this->app_title ); + } + + } // set() + + /** + * Get the [app_description] column value. + * @return string + */ + public function getAppDescription() + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in getAppDescription, the APP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->app_description = Content::load ( 'APP_DESCRIPTION', '', $this->getAppUid(), $lang ); + return $this->app_description; + } + + public function isEmptyInContent ( $content, $field, $lang ) { + if ( isset ( $content[$field][ $lang ] ) ) { + if ( trim( $content[$field][ $lang ] ) != '' ) + return false; + }; + return true; + } + + public function updateInsertContent ( $content, $field, $value ) { + if ( isset ( $content[$field][ 'en' ] ) ) { + //update + $con = ContentPeer::retrieveByPK ( $field, '', $this->getAppUid(), 'en' ); + $con->setConValue ( $value ); + if ($con->validate ()) { + $res = $con->save (); + } + } + else {//insert + $con = new Content ( ); + $con->setConCategory ( $field ); + $con->setConParent ( '' ); + $con->setConId ( $this->getAppUid()); + $con->setConLang ( 'en' ); + $con->setConValue ( $value ); + if ($con->validate ()) { + $res = $con->save (); + } + } + } + + public function normalizeContent( $content, $field , $lang ) { + $value = ''; + //if the lang row is not empty, update in 'en' row and continue + if ( !$this->isEmptyInContent ( $content, $field , $lang ) ) { + //update/insert only if this lang is != 'en', with this always we will have an en row with last value + $value = $content [ $field ][ $lang ]; + if ( $lang != 'en' ) { + $this->updateInsertContent ( $content, $field , $value ); + } + } + else { + //if the lang row is empty, and 'en' row is not empty return 'en' value + if ( !$this->isEmptyInContent ( $content, $field , 'en' ) ) { + $value = $content [ $field ][ 'en' ]; + } + + //if the lang row is empty, and 'en' row is empty get value for 'other' row and update in 'en' row and continue + if ( $this->isEmptyInContent ( $content, $field , 'en' ) ) { + if ( isset($content[$field]) && is_array ($content[$field] ) ) { + foreach ( $content [ $field ] as $lan => $val ) { + if ( trim ( $val ) != '' ) { + $value = $val; + if ( $lan != 'en' ) { + $this->updateInsertContent ( $content, $field , $value ); + continue; + } + } + } + } + else { + $this->updateInsertContent ( $content, $field , '' ); + } + } + } + return $value; + } + + /** + * Get the [app_description] , [app_title] column values. + * @return array of string + */ + public function getContentFields() + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in getContentFields, the APP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn( ContentPeer::CON_CATEGORY ); + $c->addSelectColumn( ContentPeer::CON_LANG ); + $c->addSelectColumn( ContentPeer::CON_VALUE ); + $c->add( ContentPeer::CON_ID, $this->getAppUid() ); + //$c->add( ContentPeer::CON_LANG, $lang ); + $c->addAscendingOrderByColumn('CON_CATEGORY'); + $c->addAscendingOrderByColumn('CON_LANG'); + $rs = ContentPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $content = array(); + while ($row = $rs->getRow()) { + $conCategory = $row['CON_CATEGORY']; + $conLang = $row['CON_LANG']; + if ( !isset( $content[$conCategory] ) ) $content[$conCategory] = array(); + if ( !isset( $content[$conCategory][$conLang] ) ) $content[$conCategory][$conLang] = array(); + $content[$conCategory][$conLang] = $row['CON_VALUE']; + $rs->next(); + $row = $rs->getRow(); + } + + $appTitle = $this->normalizeContent( $content, 'APP_TITLE', $lang ); + $appDescription = $this->normalizeContent( $content, 'APP_DESCRIPTION', $lang ); + + $res['APP_TITLE'] = $appTitle; + $res['APP_DESCRIPTION'] = $appDescription; + return $res; + } + + /** + * Set the [app_description] column value. + * + * @param string $v new value + * @return void + */ + public function setAppDescription($v) + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in setAppTitle, the APP_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_description !== $v || $v === '') { + $this->app_description = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'APP_DESCRIPTION', '', $this->getAppUid(), $lang, $this->app_description ); + } + } // set() + + + /** + * Get the [app_proc_code] column value. + * @return string + */ + /*public function getAppProcCode () + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in getAppProcCode, the APP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->app_proc_code = Content::load ( 'APP_PROC_CODE', '', $this->getAppUid(), $lang ); + return $this->app_proc_code; + }*/ + + /** + * Set the [app_proc_code] column value. + * + * @param string $v new value + * @return void + */ + /*public function setAppProcCode ($v) + { + if ( $this->getAppUid() == '' ) { + throw ( new Exception( "Error in setAppProcCode , the APP_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_proc_code !== $v || $v === '') { + $this->app_proc_code = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'APP_PROC_CODE', '', $this->getAppUid(), $lang, $this->app_proc_code ); + } + }*/ // set() + + + /** + * Load the Application row specified in [app_id] column value. + * + * @param string $AppUid the uid of the application + * @return array $Fields the fields + */ + + function Load ( $AppUid ) { + $con = Propel::getConnection(ApplicationPeer::DATABASE_NAME); + try { + $oApplication = ApplicationPeer::retrieveByPk( $AppUid ); + if ( get_class ($oApplication) == 'Application' ) { + $aFields = $oApplication->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + + //this is the new function to optimize content queries + $aContentFields = $oApplication->getContentFields(); + + $aFields['APP_TITLE'] = $aContentFields['APP_TITLE']; + $aFields['APP_DESCRIPTION'] = $aContentFields['APP_DESCRIPTION']; + + $this->app_title = $aFields['APP_TITLE']; + $this->app_description = $aFields['APP_DESCRIPTION']; + + //$aFields['APP_PROC_CODE'] = $oApplication->getAppProcCode(); + //$this->setAppProcCode ( $oApplication->getAppProcCode() ); + return $aFields; + } + else { + throw( new Exception( "The Application row '$AppUid' doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Creates the Application + * + * @param + * $sProUid the process id + * $sUsrUid the userid + * @return void + */ + + function create ($sProUid, $sUsrUid ) { + $con = Propel::getConnection( 'workflow' ); + try { + //fill the default values for new application row + $this->setAppUid ( G::generateUniqueID() ); + $this->setAppParent ( '' ); + $this->setAppStatus ( 'DRAFT' ); + $this->setProUid ( $sProUid ); + $this->setAppProcStatus('' ); + $this->setAppProcCode ( '' ); + $this->setAppParallel ( 'N' ); + $this->setAppInitUser ( $sUsrUid ); + $this->setAppCurUser ( $sUsrUid ); + $this->setAppCreateDate( 'now' ); + $this->setAppInitDate ( 'now' ); + $this->setAppFinishDate( '19020101' ); //to do: what is the empty date for propel???/ + $this->setAppUpdateDate( 'now' ); + + $pin = G::generateCode( 4, 'ALPHANUMERIC'); + $this->setAppData ( serialize ( array('PIN'=>$pin) ) ); + $this->setAppPin ( md5($pin) ); + + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn( 'MAX(' . ApplicationPeer::APP_NUMBER . ')' ); //the appnumber is based in all processes active, not only in the specified process guid + + $result = ApplicationPeer::doSelectRS( $c ); + $result->next(); + $row = $result->getRow(); + + $maxNumber = $row[0] + 1; + $this->setAppNumber ( $maxNumber ); + + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + $con->commit(); + + //to do: ID_CASE in translation $this->setAppTitle ( G::LoadTranslation ( 'ID_CASE') . $maxNumber ); + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + Content::insertContent( 'APP_TITLE', '', $this->getAppUid(), $lang, '#' . $maxNumber ); + Content::insertContent( 'APP_DESCRIPTION', '', $this->getAppUid(), $lang, '' ); + //Content::insertContent( 'APP_PROC_CODE', '', $this->getAppUid(), $lang, '' ); + + $con->commit(); + return $this->getAppUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The APPLICATION row cannot be created!', new PropelException ( $msg ) ) ); + } + + } + catch (Exception $e) { + $con->rollback(); + throw ($e); + } + } + + /** + * Update the application row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( ApplicationPeer::DATABASE_NAME ); + try { + $con->begin(); + $oApp = ApplicationPeer::retrieveByPK( $aData['APP_UID'] ); + if ( get_class ($oApp) == 'Application' ) { + $oApp->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oApp->validate()) { + if ( isset ( $aData['APP_TITLE'] ) ) + $oApp->setAppTitle( $aData['APP_TITLE'] ); + if ( isset ( $aData['APP_DESCRIPTION'] ) ) + $oApp->setAppDescription( $aData['APP_DESCRIPTION'] ); + //if ( isset ( $aData['APP_PROC_CODE'] ) ) + //$oApp->setAppProcCode( $aData['APP_PROC_CODE'] ); + $res = $oApp->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + throw ( new PropelException ( 'The row cannot be updated!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "The row '" . $aData['APP_UID'] . "' in table APPLICATION doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Remove the application document registry + * @param array $aData or string $appUid + * @return string + **/ + public function remove($appUid) + { + if ( is_array ( $appUid ) ) { + $appUid = ( isset ( $appUid['APP_UID'] ) ? $appUid['APP_UID'] : '' ); + } + try { + $oApp = ApplicationPeer::retrieveByPK( $appUid ); + if (!is_null($oApp)) + { + Content::removeContent('APP_TITLE', '', $oApp->getAppUid()); + Content::removeContent('APP_DESCRIPTION', '', $oApp->getAppUid()); + //Content::removeContent('APP_PROC_CODE', '', $oApp->getAppUid()); + return $oApp->delete(); + } + else { + throw(new Exception( "The row '$appUid' in table Application doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function exists( $sAppUid ) + { + $oApplicaton = ApplicationPeer::retrieveByPK( $sAppUid ); + return (!is_null($oApplicaton)); + } + function createApplication ($aData ) { + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn( 'MAX(' . ApplicationPeer::APP_NUMBER . ')' ); + $c->add( ApplicationPeer::PRO_UID, $aData['PRO_UID'] ); + $result = ApplicationPeer::doSelectRS( $c ); + $result->next(); + $row = $result->getRow(); + $maxNumber = $row[0] + 1; + $this->setAppUid ( G::generateUniqueID() ); + + $this->setAppNumber ( $maxNumber ); + $this->setAppParent (isset($aData['APP_PARENT']) ? $aData['APP_PARENT'] : 0 ); + $this->setAppStatus (isset($aData['APP_STATUS']) ? $aData['APP_STATUS'] : 'DRAFT' ); + $this->setProUid ( $aData['PRO_UID'] ); + $this->setAppProcStatus(isset($aData['APP_PROC_STATUS'])? $aData['APP_PROC_STATUS'] : '' ); + $this->setAppProcCode (isset($aData['APP_PROC_CODE']) ? $aData['APP_PROC_CODE'] : '' ); + $this->setAppParallel (isset($aData['APP_PARALLEL']) ? $aData['APP_PARALLEL'] : 'N' ); + $this->setAppInitUser ( $aData['USR_UID'] ); + $this->setAppCurUser ( $aData['USR_UID'] ); + $this->setAppCreateDate(isset($aData['APP_CREATE_DATE'])? $aData['APP_CREATE_DATE'] : 'now' ); + $this->setAppInitDate (isset($aData['APP_INIT_DATE']) ? $aData['APP_INIT_DATE'] : 'now' ); + //$this->setAppFinishDate(isset($aData['APP_FINISH_DATE'])? $aData['APP_FINISH_DATE'] : '' ); + $this->setAppUpdateDate(isset($aData['APP_UPDATE_DATE'])? $aData['APP_UPDATE_DATE'] : 'now' ); + //$this->setAppData ( serialize ( array() ) ); + + /** Start Comment : Sets the $this->Fields['APP_DATA'] + Merge between stored APP_DATA with new APP_DATA. **/ + if (!$this->getAppData()) + { +// if (!$this->is_new) +// { +// $this->load($fields['APP_UID']); +// } + } + $this->Fields['APP_DATA']=isset($this->Fields['APP_DATA'])?$this->Fields['APP_DATA']:array(); + if (isset($fields['APP_DATA']) && is_array($fields['APP_DATA'])) + { + foreach($fields['APP_DATA'] as $k=>$v) + { + $this->Fields['APP_DATA'][$k]=$v; + } + } + /** End Comment **/ + + /** Begin Comment : Replace APP_DATA in APP_TITLE (before to serialize) + $pro = new process( $this->_dbc ); + $pro->load((isset($fields['PRO_UID']) ? $fields['PRO_UID'] : $this->Fields['PRO_UID'])); + $fields['APP_TITLE'] = G::replaceDataField( $pro->Fields['PRO_TITLE'], $this->Fields['APP_DATA']); + /** End Comment **/ + +// parent::save(); +// $this->Fields['APP_DATA'] = unserialize($this->Fields['APP_DATA']); +// /** Start Comment: Save in the table CONTENT */ +// $this->content->saveContent('APP_TITLE',$fields); +// /** End Comment */ + if ($this->validate() ) { + $res = $this->save(); + $this->setAppTitle (''); + $this->setAppDescription (''); + $this->setAppProcCode (''); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $this->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + + return $this->getAppUid(); + } +} // Application diff --git a/workflow/engine/classes/model/ApplicationPeer.php b/workflow/engine/classes/model/ApplicationPeer.php new file mode 100644 index 000000000..e523e8706 --- /dev/null +++ b/workflow/engine/classes/model/ApplicationPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * ApplicationPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseApplicationPeer.php'; + + // include object class + include_once 'classes/model/Application.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'APPLICATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ApplicationPeer extends BaseApplicationPeer { + +} // ApplicationPeer diff --git a/workflow/engine/classes/model/CalendarAssignments.php b/workflow/engine/classes/model/CalendarAssignments.php new file mode 100755 index 000000000..f7586083f --- /dev/null +++ b/workflow/engine/classes/model/CalendarAssignments.php @@ -0,0 +1,19 @@ +<?php + +require_once 'classes/model/om/BaseCalendarAssignments.php'; + + +/** + * Skeleton subclass for representing a row from the 'CALENDAR_ASSIGNMENTS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarAssignments extends BaseCalendarAssignments { + +} // CalendarAssignments diff --git a/workflow/engine/classes/model/CalendarAssignmentsPeer.php b/workflow/engine/classes/model/CalendarAssignmentsPeer.php new file mode 100755 index 000000000..b7efe4eda --- /dev/null +++ b/workflow/engine/classes/model/CalendarAssignmentsPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCalendarAssignmentsPeer.php'; + + // include object class + include_once 'classes/model/CalendarAssignments.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CALENDAR_ASSIGNMENTS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarAssignmentsPeer extends BaseCalendarAssignmentsPeer { + +} // CalendarAssignmentsPeer diff --git a/workflow/engine/classes/model/CalendarBusinessHours.php b/workflow/engine/classes/model/CalendarBusinessHours.php new file mode 100755 index 000000000..7e10f1030 --- /dev/null +++ b/workflow/engine/classes/model/CalendarBusinessHours.php @@ -0,0 +1,107 @@ +<?php + +require_once 'classes/model/om/BaseCalendarBusinessHours.php'; + + +/** + * Skeleton subclass for representing a row from the 'CALENDAR_BUSINESS_HOURS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarBusinessHours extends BaseCalendarBusinessHours { + function getCalendarBusinessHours($CalendarUid){ + $Criteria = new Criteria('workflow'); + $Criteria->clearSelectColumns ( ); + + $Criteria->addSelectColumn ( CalendarBusinessHoursPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY ); + $Criteria->addSelectColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START ); + $Criteria->addSelectColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END ); + + + + $Criteria->add ( CalendarBusinessHoursPeer::CALENDAR_UID, $CalendarUid , CRITERIA::EQUAL ); + $Criteria->addDescendingOrderByColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY ); + $Criteria->addAscendingOrderByColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START ); + //$Criteria->addDescendingOrderByColumn ( CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START ); + + $rs = CalendarBusinessHoursPeer::doSelectRS($Criteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + $fields=array(); + $count=0; + + while (is_array($row)) { + $count++; + $fields[$count] = $row; + $rs->next(); + $row = $rs->getRow(); + } + return $fields; + } + function deleteAllCalendarBusinessHours($CalendarUid){ + $toDelete=$this->getCalendarBusinessHours($CalendarUid); + foreach($toDelete as $key => $businessHoursInfo){ + $CalendarUid = $businessHoursInfo['CALENDAR_UID']; + $CalendarBusinessDay = $businessHoursInfo['CALENDAR_BUSINESS_DAY']; + $CalendarBusinessStart = $businessHoursInfo['CALENDAR_BUSINESS_START']; + $CalendarBusinessEnd = $businessHoursInfo['CALENDAR_BUSINESS_END']; + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarBusinessHoursPeer::retrieveByPK ( $CalendarUid,$CalendarBusinessDay, $CalendarBusinessStart,$CalendarBusinessEnd ); + if ( ( is_object ( $tr ) && get_class ($tr) == 'CalendarBusinessHours' ) ) { + $tr->delete(); + } + } + + } + function saveCalendarBusinessHours($aData){ + $CalendarUid = $aData['CALENDAR_UID']; + $CalendarBusinessDay = $aData['CALENDAR_BUSINESS_DAY']; + $CalendarBusinessStart = $aData['CALENDAR_BUSINESS_START']; + $CalendarBusinessEnd = $aData['CALENDAR_BUSINESS_END']; + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarBusinessHoursPeer::retrieveByPK ( $CalendarUid,$CalendarBusinessDay, $CalendarBusinessStart,$CalendarBusinessEnd ); + if ( ! ( is_object ( $tr ) && get_class ($tr) == 'CalendarBusinessHours' ) ) { + $tr = new CalendarBusinessHours(); + } + + $tr->setCalendarUid( $CalendarUid ); + $tr->setCalendarBusinessDay( $CalendarBusinessDay ); + $tr->setCalendarBusinessStart( $CalendarBusinessStart ); + $tr->setCalendarBusinessEnd( $CalendarBusinessEnd ); + + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = $CalendarBusinessDay.'<hr/>'; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + G::SendTemporalMessage($msg); + } + + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + //to do: uniform coderror structures for all classes + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + } + +} // CalendarBusinessHours diff --git a/workflow/engine/classes/model/CalendarBusinessHoursPeer.php b/workflow/engine/classes/model/CalendarBusinessHoursPeer.php new file mode 100755 index 000000000..70381c0a1 --- /dev/null +++ b/workflow/engine/classes/model/CalendarBusinessHoursPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCalendarBusinessHoursPeer.php'; + + // include object class + include_once 'classes/model/CalendarBusinessHours.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CALENDAR_BUSINESS_HOURS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarBusinessHoursPeer extends BaseCalendarBusinessHoursPeer { + +} // CalendarBusinessHoursPeer diff --git a/workflow/engine/classes/model/CalendarDefinition.php b/workflow/engine/classes/model/CalendarDefinition.php new file mode 100755 index 000000000..812fc99b6 --- /dev/null +++ b/workflow/engine/classes/model/CalendarDefinition.php @@ -0,0 +1,328 @@ +<?php + +require_once 'classes/model/om/BaseCalendarDefinition.php'; +require_once 'classes/model/CalendarBusinessHours.php'; +require_once 'classes/model/CalendarHolidays.php'; +require_once 'classes/model/CalendarAssignments.php'; + +/** + * Skeleton subclass for representing a row from the 'CALENDAR_DEFINITION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarDefinition extends BaseCalendarDefinition { + public $calendarLog = ''; + function getCalendarList($onlyActive = false, $arrayMode = false) { + $Criteria = new Criteria ( 'workflow' ); + $Criteria->clearSelectColumns (); + + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_NAME ); + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_CREATE_DATE ); + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_UPDATE_DATE ); + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_DESCRIPTION ); + $Criteria->addSelectColumn ( CalendarDefinitionPeer::CALENDAR_STATUS ); + // Note: This list doesn't show deleted items (STATUS = DELETED) + if ($onlyActive) { // Show only active. Used on assignment lists + $Criteria->add ( calendarDefinitionPeer::CALENDAR_STATUS, "ACTIVE", CRITERIA::EQUAL ); + } else { // Show Active and Inactive calendars. USed in main list + $Criteria->add ( calendarDefinitionPeer::CALENDAR_STATUS, array ("ACTIVE", "INACTIVE" ), CRITERIA::IN ); + } + if(class_exists('pmLicenseManager')){ + $pmLicenseManagerO =& pmLicenseManager::getSingleton(); + $expireIn=$pmLicenseManagerO->getExpireIn(); + if($expireIn>0){ + $Criteria->add ( calendarDefinitionPeer::CALENDAR_UID, "xx", CRITERIA::NOT_EQUAL ); + }else{ + $Criteria->add ( calendarDefinitionPeer::CALENDAR_UID, "00000000000000000000000000000001", CRITERIA::EQUAL ); + } + }else{ + $Criteria->add ( calendarDefinitionPeer::CALENDAR_UID, "00000000000000000000000000000001", CRITERIA::EQUAL ); + + } + if (! $arrayMode) { + return $Criteria; + } else { + $oDataset = calendarDefinitionPeer::doSelectRS ( $Criteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $calendarA = array (0 => 'dummy' ); + $calendarCount = 0; + while ( is_array ( $aRow = $oDataset->getRow () ) ) { + $calendarCount ++; + $calendarA [$calendarCount] = $aRow; + $oDataset->next (); + } + $return ['criteria'] = $Criteria; + $return ['array'] = $calendarA; + return $return; + } + } + function getCalendarInfo($CalendarUid) { + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarDefinitionPeer::retrieveByPK ( $CalendarUid ); + + if ((is_object ( $tr ) && get_class ( $tr ) == 'CalendarDefinition')) { + $fields ['CALENDAR_UID'] = $tr->getCalendarUid (); + $fields ['CALENDAR_NAME'] = $tr->getCalendarName (); + $fields ['CALENDAR_CREATE_DATE'] = $tr->getCalendarCreateDate (); + $fields ['CALENDAR_UPDATE_DATE'] = $tr->getCalendarUpdateDate (); + $fields ['CALENDAR_DESCRIPTION'] = $tr->getCalendarDescription (); + $fields ['CALENDAR_STATUS'] = $tr->getCalendarStatus (); + $fields ['CALENDAR_WORK_DAYS'] = $tr->getCalendarWorkDays (); + $fields ['CALENDAR_WORK_DAYS_A'] = explode ( "|", $tr->getCalendarWorkDays () ); + } else { + $fields ['CALENDAR_UID'] = "00000000000000000000000000000001"; + $fields ['CALENDAR_NAME'] = "Default"; + $fields ['CALENDAR_CREATE_DATE'] = date ( "Y-m-d" ); + $fields ['CALENDAR_UPDATE_DATE'] = date ( "Y-m-d" ); + $fields ['CALENDAR_DESCRIPTION'] = "Default"; + $fields ['CALENDAR_STATUS'] = "ACTIVE"; + $fields ['CALENDAR_WORK_DAYS'] = "1|2|3|4|5"; + $fields ['CALENDAR_WORK_DAYS'] = explode ( "|", "1|2|3|4|5" ); + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_DAY'] = 7; + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_START'] = "09:00"; + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_END'] = "17:00"; + $fields ['HOLIDAY'] = array (); + $this->saveCalendarInfo ( $fields ); + $fields ['CALENDAR_WORK_DAYS'] = "1|2|3|4|5"; + $fields ['CALENDAR_WORK_DAYS_A'] = explode ( "|", "1|2|3|4|5" ); + $tr = CalendarDefinitionPeer::retrieveByPK ( $CalendarUid ); + } + $CalendarBusinessHoursObj = new CalendarBusinessHours ( ); + $CalendarBusinessHours = $CalendarBusinessHoursObj->getCalendarBusinessHours ( $CalendarUid ); + $fields ['BUSINESS_DAY'] = $CalendarBusinessHours; + + $CalendarHolidaysObj = new CalendarHolidays ( ); + $CalendarHolidays = $CalendarHolidaysObj->getCalendarHolidays ( $CalendarUid ); + $fields ['HOLIDAY'] = $CalendarHolidays; + + return $fields; + + } + function saveCalendarInfo($aData) { + $CalendarUid = $aData ['CALENDAR_UID']; + $CalendarName = $aData ['CALENDAR_NAME']; + $CalendarDescription = $aData ['CALENDAR_DESCRIPTION']; + $CalendarStatus = isset ( $aData ['CALENDAR_STATUS'] ) ? $aData ['CALENDAR_STATUS'] : "INACTIVE"; + $defaultCalendars [] = '00000000000000000000000000000001'; + if (in_array ( $aData ['CALENDAR_UID'], $defaultCalendars )) { + $CalendarStatus = 'ACTIVE'; + $CalendarName = 'Default'; + } + $CalendarWorkDays = isset ( $aData ['CALENDAR_WORK_DAYS'] ) ? implode ( "|", $aData ['CALENDAR_WORK_DAYS'] ) : ""; + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarDefinitionPeer::retrieveByPK ( $CalendarUid ); + if (! (is_object ( $tr ) && get_class ( $tr ) == 'CalendarDefinition')) { + $tr = new CalendarDefinition ( ); + $tr->setCalendarCreateDate ( 'now' ); + } + $tr->setCalendarUid ( $CalendarUid ); + $tr->setCalendarName ( $CalendarName ); + + $tr->setCalendarUpdateDate ( 'now' ); + $tr->setCalendarDescription ( $CalendarDescription ); + $tr->setCalendarStatus ( $CalendarStatus ); + $tr->setCalendarWorkDays ( $CalendarWorkDays ); + + if ($tr->validate ()) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save (); + //Calendar Business Hours Save code. + //First Delete all current records + $CalendarBusinessHoursObj = new CalendarBusinessHours ( ); + $CalendarBusinessHoursObj->deleteAllCalendarBusinessHours ( $CalendarUid ); + //Save all the sent records + foreach ( $aData ['BUSINESS_DAY'] as $key => $objData ) { + $objData ['CALENDAR_UID'] = $CalendarUid; + $CalendarBusinessHoursObj->saveCalendarBusinessHours ( $objData ); + } + + //Holiday Save code. + //First Delete all current records + $CalendarHolidayObj = new CalendarHolidays ( ); + $CalendarHolidayObj->deleteAllCalendarHolidays ( $CalendarUid ); + //Save all the sent records + foreach ( $aData ['HOLIDAY'] as $key => $objData ) { + if (($objData ['CALENDAR_HOLIDAY_NAME'] != "") && ($objData ['CALENDAR_HOLIDAY_START'] != "") && ($objData ['CALENDAR_HOLIDAY_END'] != "")) { + $objData ['CALENDAR_UID'] = $CalendarUid; + $CalendarHolidayObj->saveCalendarHolidays ( $objData ); + } + } + } else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures (); + foreach ( $validationFailuresArray as $objValidationFailure ) { + $msg .= $objValidationFailure->getMessage () . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + + //to do: uniform coderror structures for all classes + + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + + + } + function deleteCalendar($CalendarUid) { + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarDefinitionPeer::retrieveByPK ( $CalendarUid ); + + if (! (is_object ( $tr ) && get_class ( $tr ) == 'CalendarDefinition')) { + // + return false; + } + + $defaultCalendars [] = '00000000000000000000000000000001'; + if (in_array ( $tr->getCalendarUid(), $defaultCalendars )) { + return false; + } + + $tr->setCalendarStatus ( 'DELETED' ); + $tr->setCalendarUpdateDate ( 'now' ); + if ($tr->validate ()) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save (); + + } else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures (); + foreach ( $validationFailuresArray as $objValidationFailure ) { + $msg .= $objValidationFailure->getMessage () . "<br/>"; + } + G::SendMessage ( "ERROR", $msg ); + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + + //to do: uniform coderror structures for all classes + + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + + + } + function getCalendarFor($userUid, $proUid, $tasUid) { + $Criteria = new Criteria ( 'workflow' ); + + //Default Calendar + $calendarUid = "00000000000000000000000000000001"; + $calendarOwner = "DEFAULT"; + + //Try to load a User Calendar if exist + $objectID = $userUid; + $Criteria->clearSelectColumns (); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_TYPE ); + $Criteria->add ( CalendarAssignmentsPeer::OBJECT_UID, $objectID, CRITERIA::EQUAL ); + if (CalendarAssignmentsPeer::doCount ( $Criteria ) > 0) { + $oDataset = CalendarAssignmentsPeer::doSelectRS ( $Criteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRow = $oDataset->getRow (); + $calendarUid = $aRow ['CALENDAR_UID']; + $calendarOwner = "USER"; + } + + //Try to load a Process Calendar if exist + $objectID = $proUid; + $Criteria->clearSelectColumns (); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_TYPE ); + $Criteria->add ( CalendarAssignmentsPeer::OBJECT_UID, $objectID, CRITERIA::EQUAL ); + if (CalendarAssignmentsPeer::doCount ( $Criteria ) > 0) { + $oDataset = CalendarAssignmentsPeer::doSelectRS ( $Criteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRow = $oDataset->getRow (); + $calendarUid = $aRow ['CALENDAR_UID']; + $calendarOwner = "PROCESS"; + } + + //Try to load a Task Calendar if exist + $objectID = $tasUid; + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_UID ); + $Criteria->addSelectColumn ( CalendarAssignmentsPeer::OBJECT_TYPE ); + $Criteria->add ( CalendarAssignmentsPeer::OBJECT_UID, $objectID, CRITERIA::EQUAL ); + $Criteria->clearSelectColumns (); + if (CalendarAssignmentsPeer::doCount ( $Criteria ) > 0) { + $oDataset = CalendarAssignmentsPeer::doSelectRS ( $Criteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRow = $oDataset->getRow (); + $calendarUid = $aRow ['CALENDAR_UID']; + $calendarOwner = "TASK"; + } + + if(class_exists('pmLicenseManager')){ + $pmLicenseManagerO =& pmLicenseManager::getSingleton(); + $expireIn=$pmLicenseManagerO->getExpireIn(); + if($expireIn>0){ + $calendarUid=$calendarUid; + }else{ + $calendarUid = "00000000000000000000000000000001"; + } + }else{ + $calendarUid = "00000000000000000000000000000001"; + } + + //print "<h1>$calendarUid</h1>"; + $calendarDefinition = $this->getCalendarInfo ( $calendarUid ); + $calendarDefinition ['CALENDAR_APPLIED'] = $calendarOwner; + $this->addCalendarLog ( "--=== Calendar Applied: " . $calendarDefinition ['CALENDAR_NAME'] . " -> $calendarOwner" ); + return $calendarDefinition; + } + + function assignCalendarTo($objectUid, $calendarUid, $objectType) { + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarAssignmentsPeer::retrieveByPK ( $objectUid ); + if ($calendarUid != "") { + if (! (is_object ( $tr ) && get_class ( $tr ) == 'CalendarAssignments')) { + $tr = new CalendarAssignments ( ); + + } + $tr->setObjectUid ( $objectUid ); + $tr->setCalendarUid ( $calendarUid ); + $tr->setObjectType ( $objectType ); + + if ($tr->validate ()) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save (); + + } else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures (); + foreach ( $validationFailuresArray as $objValidationFailure ) { + $msg .= $objValidationFailure->getMessage () . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + } else { //Delete record + if ((is_object ( $tr ) && get_class ( $tr ) == 'CalendarAssignments')) { + $tr->delete (); + } + } + + } +} // CalendarDefinition \ No newline at end of file diff --git a/workflow/engine/classes/model/CalendarDefinitionPeer.php b/workflow/engine/classes/model/CalendarDefinitionPeer.php new file mode 100755 index 000000000..6fd16bb46 --- /dev/null +++ b/workflow/engine/classes/model/CalendarDefinitionPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCalendarDefinitionPeer.php'; + + // include object class + include_once 'classes/model/CalendarDefinition.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CALENDAR_DEFINITION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarDefinitionPeer extends BaseCalendarDefinitionPeer { + +} // CalendarDefinitionPeer diff --git a/workflow/engine/classes/model/CalendarHolidays.php b/workflow/engine/classes/model/CalendarHolidays.php new file mode 100755 index 000000000..851eee9a2 --- /dev/null +++ b/workflow/engine/classes/model/CalendarHolidays.php @@ -0,0 +1,111 @@ +<?php + +require_once 'classes/model/om/BaseCalendarHolidays.php'; + + +/** + * Skeleton subclass for representing a row from the 'CALENDAR_HOLIDAYS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarHolidays extends BaseCalendarHolidays { + function getCalendarHolidays($CalendarUid){ + $Criteria = new Criteria('workflow'); + $Criteria->clearSelectColumns ( ); + + $Criteria->addSelectColumn ( CalendarHolidaysPeer::CALENDAR_UID ); + $Criteria->addSelectColumn ( CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME ); + $Criteria->addSelectColumn ( CalendarHolidaysPeer::CALENDAR_HOLIDAY_START ); + $Criteria->addSelectColumn ( CalendarHolidaysPeer::CALENDAR_HOLIDAY_END ); + + + + $Criteria->add ( CalendarHolidaysPeer::CALENDAR_UID, $CalendarUid , CRITERIA::EQUAL ); + + $rs = CalendarHolidaysPeer::doSelectRS($Criteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $fields=array(); + + $count=0; + + while (is_array($row)) { + $count++; + $a=explode(" ",$row['CALENDAR_HOLIDAY_START']); + $row['CALENDAR_HOLIDAY_START']=$a[0]; + $a=explode(" ",$row['CALENDAR_HOLIDAY_END']); + $row['CALENDAR_HOLIDAY_END']=$a[0]; + $fields[$count] = $row; + $rs->next(); + $row = $rs->getRow(); + } + return $fields; + } +function deleteAllCalendarHolidays($CalendarUid){ + $toDelete=$this->getCalendarHolidays($CalendarUid); + foreach($toDelete as $key => $holidayInfo){ + print_r($holidayInfo); + $CalendarUid = $holidayInfo['CALENDAR_UID']; + $CalendarHolidayName = $holidayInfo['CALENDAR_HOLIDAY_NAME']; + $CalendarHolidayStart = $holidayInfo['CALENDAR_HOLIDAY_START']; + $CalendarHolidayEnd = $holidayInfo['CALENDAR_HOLIDAY_END']; + //if exists the row in the database propel will update it, otherwise will insert. + + $tr = CalendarHolidaysPeer::retrieveByPK ( $CalendarUid,$CalendarHolidayName ); + if ( ( is_object ( $tr ) && get_class ($tr) == 'CalendarHolidays' ) ) { + $tr->delete(); + } + } + + } + function saveCalendarHolidays($aData){ + + $CalendarUid = $aData['CALENDAR_UID']; + $CalendarHolidayName = $aData['CALENDAR_HOLIDAY_NAME']; + $CalendarHolidayStart = $aData['CALENDAR_HOLIDAY_START']; + $CalendarHolidayEnd = $aData['CALENDAR_HOLIDAY_END']; + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = CalendarHolidaysPeer::retrieveByPK ( $CalendarUid,$CalendarHolidayName); + if ( ! ( is_object ( $tr ) && get_class ($tr) == 'CalendarHolidays' ) ) { + $tr = new CalendarHolidays(); + } + + $tr->setCalendarUid( $CalendarUid ); + $tr->setCalendarHolidayName( $CalendarHolidayName ); + $tr->setCalendarHolidayStart( $CalendarHolidayStart ); + $tr->setCalendarHolidayEnd( $CalendarHolidayEnd ); + + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + + + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + //to do: uniform coderror structures for all classes + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + } + +} // CalendarHolidays diff --git a/workflow/engine/classes/model/CalendarHolidaysPeer.php b/workflow/engine/classes/model/CalendarHolidaysPeer.php new file mode 100755 index 000000000..64863bbc7 --- /dev/null +++ b/workflow/engine/classes/model/CalendarHolidaysPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCalendarHolidaysPeer.php'; + + // include object class + include_once 'classes/model/CalendarHolidays.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CALENDAR_HOLIDAYS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CalendarHolidaysPeer extends BaseCalendarHolidaysPeer { + +} // CalendarHolidaysPeer diff --git a/workflow/engine/classes/model/CaseScheduler.php b/workflow/engine/classes/model/CaseScheduler.php new file mode 100644 index 000000000..78979a132 --- /dev/null +++ b/workflow/engine/classes/model/CaseScheduler.php @@ -0,0 +1,873 @@ +<?php + +require_once 'classes/model/om/BaseCaseScheduler.php'; + +require_once 'classes/model/Process.php'; +require_once 'classes/model/Task.php'; + +/** + * Skeleton subclass for representing a row from the 'CASE_SCHEDULER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseScheduler extends BaseCaseScheduler { + + /* + private $SchTimeNextRun = null; + private $SchLastRunTime = null; + + public function getSchTimeNextRun() { + if($this->SchTimeNextRun === null) + $this->SchTimeNextRun = time(); + return $this->SchTimeNextRun; + } + public function setSchTimeNextRun($value) { + $this->SchTimeNextRun = $value; + } + public function getSchLastRunTime(){ + if($this->SchTimeNextRun === null) + $this->SchTimeNextRun = time(); + return $this->SchLastRunTime; + } + public function setSchLastRunTime($value){ + $this->SchLastRunTime = $value; + } + */ + + public function load($SchUid) { + try { + $oRow = CaseSchedulerPeer::retrieveByPK ( $SchUid ); + if (! is_null ( $oRow )) { + $aFields = $oRow->toArray ( BasePeer::TYPE_FIELDNAME ); + $this->fromArray ( $aFields, BasePeer::TYPE_FIELDNAME ); + $this->setNew ( false ); + return $aFields; + } else { + throw (new Exception ( "The row '" . $SchUid . "' in table CASE_SCHEDULER doesn't exist!" )); + } + } catch ( Exception $oError ) { + throw ($oError); + } + } + + function create($aData) { + $con = Propel::getConnection ( CaseSchedulerPeer::DATABASE_NAME ); + try { + $this->fromArray ( $aData, BasePeer::TYPE_FIELDNAME ); + if ($this->validate ()) { + $result = $this->save (); + } else { + $e = new Exception ( "Failed Validation in class " . get_class ( $this ) . "." ); + $e->aValidationFailures = $this->getValidationFailures (); + throw ($e); + } + $con->commit (); + return $result; + } catch ( Exception $e ) { + $con->rollback (); + throw ($e); + } + } + + public function update($fields) { + $con = Propel::getConnection ( CaseSchedulerPeer::DATABASE_NAME ); + try { + $con->begin (); + $this->load ( $fields ['SCH_UID'] ); + $this->fromArray ( $fields, BasePeer::TYPE_FIELDNAME ); + if ($this->validate ()) { + $result = $this->save (); + $con->commit (); + return $result; + } else { + $con->rollback (); + throw (new Exception ( "Failed Validation in class " . get_class ( $this ) . "." )); + } + } catch ( Exception $e ) { + $con->rollback (); + throw ($e); + } + } + + function remove($SchUid) { + $con = Propel::getConnection ( CaseSchedulerPeer::DATABASE_NAME ); + try { + $oCaseScheduler = CaseSchedulerPeer::retrieveByPK($SchUid); + if(!is_null($oCaseScheduler)) { + $iResult = $oCaseScheduler->delete(); + $con->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + /* + $con->begin(); + $this->setSchUid ( $SchUid ); + $result = $this->delete(); + $con->commit(); + return $result; + */ + } catch ( Exception $e ) { + $con->rollback(); + throw($e); + } + } + + /* + * change Status of any Process + * @param string $sSchedulerUid + * @return boolean + */ + function changeStatus($sSchedulerUid = '') { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_LAST_STATE'] = $Fields ['SCH_STATE']; + if ($Fields ['SCH_STATE'] == 'ACTIVE') { + $Fields ['SCH_STATE'] = 'INACTIVE'; + } else { + $Fields ['SCH_STATE'] = 'ACTIVE'; + } + $this->Update ( $Fields ); + } + + // SELECT A.SCH_UID, A.SCH_NAME, A.PRO_UID, B.CON_VALUE AS PROCESS, + // A.TAS_UID, B.CON_VALUE AS TASK, A.SCH_TIME_NEXT_RUN, A.SCH_LAST_RUN_TIME, A.SCH_STATE, A.SCH_LAST_STATE, + // A.USR_UID, A.SCH_OPTION + // SCH_START_TIME, SCH_START_DATE, SCH_DAYS_PERFORM_TASK, SCH_EVERY_DAYS, SCH_WEEK_DAYS + // SCH_START_DAY, SCH_MONTHS, SCH_END_DATE, SCH_REPEAT_EVERY, SCH_REPEAT_UNTIL, SCH_REPEAT_STOP_IF_RUNNING + // FROM CASE_SCHEDULER A LEFT JOIN CONTENT B ON A.PRO_UID= B.CON_ID AND B.CON_CATEGORY='PRO_TITLE' AND B.CON_LANG='en' + // LEFT JOIN CONTENT C ON A.TAS_UID= C.CON_ID AND C.CON_CATEGORY='TAS_TITLE' AND C.CON_LANG='en' + // + function getAllCriteria() { + $c = new Criteria ( 'workflow' ); + $c->clearSelectColumns (); + + $c->addSelectColumn ( CaseSchedulerPeer::SCH_UID ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_NAME ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_DEL_USER_NAME ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_DEL_USER_PASS ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_DEL_USER_UID ); + $c->addSelectColumn ( CaseSchedulerPeer::PRO_UID ); + $c->addSelectColumn ( CaseSchedulerPeer::TAS_UID ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_TIME_NEXT_RUN ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_LAST_RUN_TIME ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_STATE ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_LAST_STATE ); + $c->addSelectColumn ( CaseSchedulerPeer::USR_UID ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_OPTION ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_START_TIME ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_START_DATE ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_EVERY_DAYS ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_WEEK_DAYS ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_START_DAY ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_MONTHS ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_END_DATE ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_REPEAT_EVERY ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_REPEAT_UNTIL ); + $c->addSelectColumn ( CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING ); + $c->addSelectColumn ( CaseSchedulerPeer::CASE_SH_PLUGIN_UID ); + + return $c; + + } + + function getAll() { + $oCriteria = $this->getAllCriteria (); + $oDataset = CaseSchedulerPeer::doSelectRS ( $oCriteria ); + + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRows = Array (); + while ( $aRow = $oDataset->getRow () ) { + $aRows [] = $aRow; + $oDataset->next (); + } + foreach ( $aRows as $k => $aRow ) { + $oProcess = new Process (); + $aProcessRow = $oProcess->load ( $aRow ['PRO_UID'] ); + + $oTask = new Task (); + $aTaskRow = $oTask->load ( $aRow ['TAS_UID'] ); + + $aRows [$k] = array_merge ( $aRow, $aProcessRow, $aTaskRow ); + } + + return $aRows; + } + /** + * function getAllByProcess + * @author gustavo cruz + * @desc Get All Scheduled Tasks for some process. + * @param $pro_uid process uid + * @return $aRows a result set array + */ + function getAllByProcess($pro_uid) { + + $oCriteria = $this->getAllCriteria (); + $oCriteria->add ( CaseSchedulerPeer::PRO_UID, $pro_uid ); + $oDataset = CaseSchedulerPeer::doSelectRS ( $oCriteria ); + + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRows = Array (); + while ( $aRow = $oDataset->getRow () ) { + $aRows [] = $aRow; + $oDataset->next (); + } + foreach ( $aRows as $k => $aRow ) { + $oProcess = new Process (); + $aProcessRow = $oProcess->load ( $aRow ['PRO_UID'] ); + $oTask = new Task (); + $aTaskRow = $oTask->load ( $aRow ['TAS_UID'] ); + $aRows [$k] = array_merge ( $aRow, $aProcessRow, $aTaskRow ); + } + return $aRows; + } + + function getProcessDescription() { + $c = new Criteria ( 'workflow' ); + $c->clearSelectColumns (); + $c->addSelectColumn ( ProcessPeer::PRO_UID ); + + $oDataset = ProcessPeer::doSelectRS ( $c ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRows = Array (); + while ( $aRow = $oDataset->getRow () ) { + $aRows [] = $aRow; + $oDataset->next (); + } + + foreach ( $aRows as $k => $aRow ) { + $oProcess = new Process (); + $aProcessRow = $oProcess->load ( $aRow ['PRO_UID'] ); + + $aRows [$k] = array_merge ( $aRow, array ( + 'PRO_TITLE' => $aProcessRow ['PRO_TITLE'] + ) ); + } + return $aRows; + + } + + function getTaskDescription() { + $c = new Criteria ( 'workflow' ); + $c->clearSelectColumns (); + $c->addSelectColumn ( TaskPeer::TAS_UID ); + + $oDataset = TaskPeer::doSelectRS ( $c ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRows = Array (); + while ( $aRow = $oDataset->getRow () ) { + $aRows [] = $aRow; + $oDataset->next (); + } + foreach ( $aRows as $k => $aRow ) { + + $oTask = new Task (); + $aTaskRow = $oTask->load ( $aRow ['TAS_UID'] ); + + $aRows [$k] = array_merge ( $aRow, array ( + 'TAS_TITLE' => $aTaskRow ['TAS_TITLE'] + ), array ( + 'PRO_UID' => $aTaskRow ['PRO_UID'] + ) ); + } + + // g::pr($aRows); die; + + + return $aRows; + + } + + function caseSchedulerCron($date) { + + G::LoadClass ( 'dates' ); + require_once ('classes/model/LogCasesScheduler.php'); + + $oDates = new dates (); + + $nTime = strtotime ( $date ); + + $dCurrentDate = date ( 'Y-m-d', $nTime ) . ' 00:00:00'; + $dNextDay = date ( 'Y-m-d', strtotime ( "$dCurrentDate" ) ) . ' 23:59:59'; + + $oCriteria = $this->getAllCriteria (); + $oCriteria->addAnd ( CaseSchedulerPeer::SCH_STATE, 'INACTIVE', Criteria::NOT_EQUAL ); + $oCriteria->addAnd ( CaseSchedulerPeer::SCH_STATE, 'PROCESSED', Criteria::NOT_EQUAL ); + $oCriteria->add ( CaseSchedulerPeer::SCH_TIME_NEXT_RUN, $dCurrentDate, Criteria::GREATER_EQUAL ); + $oCriteria->addAnd ( CaseSchedulerPeer::SCH_TIME_NEXT_RUN, $dNextDay, Criteria::LESS_EQUAL ); + $oCriteria->add ( CaseSchedulerPeer::SCH_END_DATE, null, Criteria::EQUAL ); + $oCriteria->addOr ( CaseSchedulerPeer::SCH_END_DATE, $dCurrentDate, Criteria::GREATER_EQUAL ); + $oDataset = CaseSchedulerPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + + $sValue = ''; + $sActualTime = ''; + $sDaysPerformTask = ''; + $sWeeks = ''; + $sStartDay = ''; + $sMonths = ''; + while ( $aRow = $oDataset->getRow () ) { + $sSchedulerUid = $aRow ['SCH_UID']; + $sOption = $aRow ['SCH_OPTION']; + switch ($sOption) { + case '1' : + $sDaysPerformTask = $aRow ['SCH_DAYS_PERFORM_TASK']; + $aDaysPerformTask = explode ( '|', $sDaysPerformTask ); + $sValue = $aDaysPerformTask [0]; + if ($sValue != 1) + $sDaysPerformTask = $aDaysPerformTask [1]; + break; + case '2' : + $sDaysPerformTask = $aRow ['SCH_EVERY_DAYS']; + $sWeeks = $aRow ['SCH_WEEK_DAYS']; + break; + case '3' : + $sStartDay = $aRow ['SCH_START_DAY']; + $sMonths = $aRow ['SCH_MONTHS']; + $aStartDay = explode ( '|', $sStartDay ); + $sValue = $aStartDay [0]; + break; + case '4' : + $aRow ['SCH_STATE'] = 'PROCESSED'; + break; + + } + + $sActualTime = $aRow ['SCH_TIME_NEXT_RUN']; + + $sActualDataHour = date ( 'H', strtotime ( $aRow ['SCH_TIME_NEXT_RUN'] ) ); + $sActualDataMinutes = date ( 'i', strtotime ( $aRow ['SCH_TIME_NEXT_RUN'] ) ); + $dActualSysHour = date ( 'H', $nTime ); + $dActualSysMinutes = date ( 'i', $nTime ); + + $sActualDataTime = strtotime ( $aRow ['SCH_TIME_NEXT_RUN'] ); + $sActualSysTime = strtotime ( $nTime ); + + // note added consider the posibility to encapsulate some in functionality in a class method or some funtions + if ($sActualDataHour < $dActualSysHour) { + $_PORT = (SERVER_PORT != '80') ? ':' . SERVER_PORT : ''; + + $defaultEndpoint = 'http://' . SERVER_NAME . $_PORT . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + println(" - Connecting webservice: $defaultEndpoint"); + + $user = $aRow ["SCH_DEL_USER_NAME"]; + $pass = $aRow ["SCH_DEL_USER_PASS"]; + $processId = $aRow ["PRO_UID"]; + $taskId = $aRow ["TAS_UID"]; + + $client = new SoapClient ( $defaultEndpoint ); + $params = array ( + 'userid' => $user, + 'password' => 'md5:' . $pass + ); + $result = $client->__SoapCall ( 'login', array ( + $params + ) ); + + eprint(" - Logging as user $user............."); + if ($result->status_code == 0) { + eprintln("OK+", 'green'); + $sessionId = $result->message; + $newCaseLog = new LogCasesScheduler (); + $newRouteLog = new LogCasesScheduler (); + $variables = Array (); + $params = array ( + 'sessionId' => $sessionId, + 'processId' => $processId, + 'taskId' => $taskId, + 'variables' => $variables + ); + + $paramsLog = array ( + 'PRO_UID' => $processId, + 'TAS_UID' => $taskId, + 'SCH_UID' => $sSchedulerUid, + 'USR_NAME' => $user, + 'RESULT' => '', + 'EXEC_DATE' => date ( 'Y-m-d' ), + 'EXEC_HOUR' => date ( 'H:i:s' ), + 'WS_CREATE_CASE_STATUS' => '', + 'WS_ROUTE_CASE_STATUS' => '' + ); + + $sw_transfer_control_plugin=false;//This SW will be true only if a plugin is allowed to continue the action + //If this Job was was registered to be performed by a plugin + if((isset($aRow['CASE_SH_PLUGIN_UID']))&&($aRow['CASE_SH_PLUGIN_UID']!="")){ + //Check if the plugin is active + $pluginParts=explode("--",$aRow['CASE_SH_PLUGIN_UID']); + if(count($pluginParts)==2){ + //***************** Plugins ************************** + G::LoadClass('plugin'); + //here we are loading all plugins registered + //the singleton has a list of enabled plugins + + $sSerializedFile = PATH_DATA_SITE . 'plugin.singleton'; + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( file_exists ($sSerializedFile) ) + $oPluginRegistry->unSerializeInstance( file_get_contents ( $sSerializedFile ) ); + + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $activePluginsForCaseScheduler=$oPluginRegistry->getCaseSchedulerPlugins(); + foreach($activePluginsForCaseScheduler as $key => $caseSchedulerPlugin){ + if((isset($caseSchedulerPlugin->sNamespace))&&($caseSchedulerPlugin->sNamespace==$pluginParts[0])&&(isset($caseSchedulerPlugin->sActionId))&&($caseSchedulerPlugin->sActionId==$pluginParts[1])){ + $sw_transfer_control_plugin=true; + $caseSchedulerSelected=$caseSchedulerPlugin; + } + } + + } + } + //If there is a trigger that is registered to do this then transfer control + + + if((isset($caseSchedulerSelected))&&(is_object($caseSchedulerSelected))){ + eprintln(" - Transfering control to a Plugin: ".$caseSchedulerSelected->sNamespace."/".$caseSchedulerSelected->sActionId,'green'); + + $oData['OBJ_SOAP'] = $client; + $oData['SCH_UID'] = $aRow['SCH_UID']; + $oData['params'] = $params; + $oData['sessionId'] = $sessionId; + $oData['userId'] = $user; + $paramsLogResultFromPlugin=$oPluginRegistry->executeMethod( $caseSchedulerSelected->sNamespace, $caseSchedulerSelected->sActionExecute, $oData ); + $paramsLog['WS_CREATE_CASE_STATUS']=$paramsLogResultFromPlugin['WS_CREATE_CASE_STATUS']; + $paramsLog['WS_ROUTE_CASE_STATUS']=$paramsLogResultFromPlugin['WS_ROUTE_CASE_STATUS']; + + $paramsLogResult=$paramsLogResultFromPlugin['paramsLogResult']; + $paramsRouteLogResult=$paramsLogResultFromPlugin['paramsRouteLogResult']; + }else{ + + eprint(" - Creating the new case............."); + $result = $client->__SoapCall ( 'NewCase', array ( + $params + ) ); + if ($result->status_code == 0) { + eprintln("OK+ CASE #{$result->caseNumber} was created!", 'green'); + + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $paramsLog ['WS_CREATE_CASE_STATUS'] = "Case " . $caseNumber . " " . strip_tags ( $result->message ); + $paramsLogResult = 'SUCCESS'; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => "1" + ); + eprint(" - Routing the case #$caseNumber.............."); + $result = $client->__SoapCall ( 'RouteCase', array ( + $params + ) ); + if ($result->status_code == 0) { + $paramsLog ['WS_ROUTE_CASE_STATUS'] = strip_tags ( $result->message ); + $retMsg = explode("Debug", $paramsLog ['WS_ROUTE_CASE_STATUS']); + $retMsg = $retMsg[0]; + eprintln("OK+ $retMsg", 'green'); + $paramsRouteLogResult = 'SUCCESS'; + } else { + $paramsLog ['WS_ROUTE_CASE_STATUS'] = strip_tags ( $result->message ); + eprintln("FAILED-> {$paramsLog ['WS_ROUTE_CASE_STATUS']}", 'red'); + $paramsRouteLogResult = 'FAILED'; + } + } else { + $paramsLog ['WS_CREATE_CASE_STATUS'] = strip_tags ( $result->message ); + $paramsLogResult = 'FAILED'; + + } + } + } else { + eprintln($result->message, 'red'); + // invalid user or bad password + } + if ($paramsLogResult == 'SUCCESS' && $paramsRouteLogResult == 'SUCCESS') { + $paramsLog ['RESULT'] = 'SUCCESS'; + } else { + $paramsLog ['RESULT'] = 'FAILED'; + } + + $newCaseLog->saveLogParameters ( $paramsLog ); + $newCaseLog->save (); + + if ($sOption != '4') { + $nSchLastRunTime = $sActualTime; + + $dEstimatedDate = $this->updateNextRun ( $sOption, $sValue, $sActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths ); + + if ($aRow ['SCH_END_DATE'] != '') { + if (date ( "Y-m-d", strtotime ( $dEstimatedDate ) ) > date ( "Y-m-d", strtotime ( $aRow ['SCH_END_DATE'] ) )) { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_LAST_STATE'] = $aRow ['SCH_STATE']; + $Fields ['SCH_STATE'] = 'PROCESSED'; + $this->Update ( $Fields ); + } + } + + $nSchTimeNextRun = $dEstimatedDate; + $this->updateDate ( $sSchedulerUid, $nSchTimeNextRun, $nSchLastRunTime ); + } else { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_LAST_STATE'] = $aRow ['SCH_STATE']; + $Fields ['SCH_LAST_RUN_TIME'] = $Fields ['SCH_TIME_NEXT_RUN']; + $Fields ['SCH_STATE'] = 'PROCESSED'; + $this->Update ( $Fields ); + } + } else if ($sActualDataHour == $dActualSysHour && $sActualDataMinutes <= $dActualSysMinutes) { + + $_PORT = ($_SERVER ['SERVER_PORT'] != '80') ? ':' . $_SERVER ['SERVER_PORT'] : ''; + + //$defaultEndpoint = 'http://' . $_SERVER ['SERVER_NAME'] . ':' . $_PORT . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + $defaultEndpoint = 'http://' . SERVER_NAME . $_PORT . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + println(" - Connecting webservice: $defaultEndpoint"); + $user = $aRow ["SCH_DEL_USER_NAME"]; + $pass = $aRow ["SCH_DEL_USER_PASS"]; + $processId = $aRow ["PRO_UID"]; + $taskId = $aRow ["TAS_UID"]; + + $client = new SoapClient ( $defaultEndpoint ); + $params = array ( + 'userid' => $user, + 'password' => 'md5:' . $pass + ); + $result = $client->__SoapCall ( 'login', array ( + $params + ) ); + + eprint(" - Logging as user $user............."); + if ($result->status_code == 0) { + eprintln("OK+", 'green'); + + $sessionId = $result->message; + $newCaseLog = new LogCasesScheduler (); + $newRouteLog = new LogCasesScheduler (); + $variables = Array (); + $params = array ( + 'sessionId' => $sessionId, + 'processId' => $processId, + 'taskId' => $taskId, + 'variables' => $variables + ); + + $paramsLog = array ( + 'PRO_UID' => $processId, + 'TAS_UID' => $taskId, + 'SCH_UID' => $sSchedulerUid, + 'USR_NAME' => $user, + 'RESULT' => '', + 'EXEC_DATE' => date ( 'Y-m-d' ), + 'EXEC_HOUR' => date ( 'H:i:s' ), + 'WS_CREATE_CASE_STATUS' => '', + 'WS_ROUTE_CASE_STATUS' => '' + ); + + $result = $client->__SoapCall ( 'NewCase', array ( + $params + ) ); + + eprint(" - Creating the new case............."); + if ($result->status_code == 0) { + eprintln("OK+ CASE #{$result->caseNumber} was created!", 'green'); + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $paramsLog ['WS_CREATE_CASE_STATUS'] = "Case " . $caseNumber . " " . strip_tags ( $result->message ); + $paramsLogResult = 'SUCCESS'; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => "1" + ); + $result = $client->__SoapCall ( 'RouteCase', array ( + $params + ) ); + eprint(" - Routing the case #$caseNumber.............."); + if ($result->status_code == 0) { + $paramsLog ['WS_ROUTE_CASE_STATUS'] = strip_tags ( $result->message ); + $retMsg = explode("Debug", $paramsLog ['WS_ROUTE_CASE_STATUS']); + $retMsg = $retMsg[0]; + eprintln("OK+ $retMsg", 'green'); + $paramsRouteLogResult = 'SUCCESS'; + } else { + eprintln("FAILED-> {$paramsLog ['WS_ROUTE_CASE_STATUS']}", 'red'); + $paramsLog ['WS_ROUTE_CASE_STATUS'] = strip_tags ( $result->message ); + $paramsRouteLogResult = 'FAILED'; + } + + } else { + $paramsLog ['WS_CREATE_CASE_STATUS'] = strip_tags ( $result->message ); + eprintln("FAILED->{$paramsLog ['WS_CREATE_CASE_STATUS']}", 'red'); + $paramsLogResult = 'FAILED'; + + } + } else { + // invalid user or bad password + eprintln($result->message, 'red'); + } + if ($paramsLogResult == 'SUCCESS' && $paramsRouteLogResult == 'SUCCESS') { + $paramsLog ['RESULT'] = 'SUCCESS'; + } else { + $paramsLog ['RESULT'] = 'FAILED'; + } + + $newCaseLog->saveLogParameters ( $paramsLog ); + $newCaseLog->save (); + + if ($sOption != '4') { + $nSchLastRunTime = $sActualTime; + + $dEstimatedDate = $this->updateNextRun ( $sOption, $sValue, $sActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths ); + + if ($aRow ['SCH_END_DATE'] != '') { + if (date ( "Y-m-d", strtotime ( $dEstimatedDate ) ) > date ( "Y-m-d", strtotime ( $aRow ['SCH_END_DATE'] ) )) { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_LAST_STATE'] = $aRow ['SCH_STATE']; + $Fields ['SCH_STATE'] = 'PROCESSED'; + $this->Update ( $Fields ); + + } + } + $nSchTimeNextRun = $dEstimatedDate; + + $this->updateDate ( $sSchedulerUid, $nSchTimeNextRun, $nSchLastRunTime ); + } else { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_LAST_STATE'] = $aRow ['SCH_STATE']; + $Fields ['SCH_LAST_RUN_TIME'] = $Fields ['SCH_TIME_NEXT_RUN']; + $Fields ['SCH_STATE'] = 'PROCESSED'; + $this->Update ( $Fields ); + } + } + + $oDataset->next (); + } + + } + + function updateDate($sSchedulerUid = '', $sSchTimeNextRun = '', $sSchLastRunTime = '') { + $Fields = $this->Load ( $sSchedulerUid ); + $Fields ['SCH_TIME_NEXT_RUN'] = strtotime ( $sSchTimeNextRun ); + $Fields ['SCH_LAST_RUN_TIME'] = strtotime ( $sSchLastRunTime ); + $this->Update ( $Fields ); + } + + function updateNextRun($sOption, $sValue = '', $sActualTime = '', $sDaysPerformTask = '', $sWeeks = '', $sStartDay = '', $sMonths = '', $currentDate = '') { + $nActualDate = $currentDate . " " . $sActualTime; // date("Y-m-d H:i:s", $sActualTime); + // date("Y-m-d H:i:s", $sActualTime); + $dEstimatedDate = ''; + switch ($sOption) { + case '1' : + switch ($sValue) { + case '1' : + $dEstimatedDate = date ( 'Y-m-d H:i:s', strtotime ( "$nActualDate +1 day" ) ); + break; + case '2' : + $nDayOfTheWeek = date ( 'w', strtotime ( $sActualTime ) ); + $nDayOfTheWeek = ($nDayOfTheWeek == 0) ? 7 : $nDayOfTheWeek; + if ($nDayOfTheWeek >= 5) + $dEstimatedDate = date ( 'Y-m-d H:i:s', strtotime ( "$nActualDate +3 day" ) ); + else + $dEstimatedDate = date ( 'Y-m-d H:i:s', strtotime ( "$nActualDate +1 day" ) ); + break; + case '3' : + $dEstimatedDate = date ( 'Y-m-d H:i:s', strtotime ( "$nActualDate + " . $sDaysPerformTask . " day" ) ); + break; + } + break; + + case '2' : + if (strlen ( $sWeeks ) > 0) { + + //die($sActualTime); + $nDayOfTheWeek = date ( 'w', strtotime ( $sActualTime ) ); + // $nDayOfTheWeek = 1; + // echo "*".$nDayOfTheWeek."*"; + $aWeeks = explode ( '|', $sWeeks ); + $nFirstDay = $aWeeks [0]; + + $aDaysWeek = array ( + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ); + $nFirstDay = $nFirstDay - 1; + // echo "¨¨".$nFirstDay."¨¨"; + $nDayOfTheWeek = ($nDayOfTheWeek == 0) ? 7 : $nDayOfTheWeek; + // echo $nDayOfTheWeek; + + + $nSW = 0; + $nNextDay = 0; + foreach ( $aWeeks as $value ) { + if ($value > $nDayOfTheWeek) { + $nNextDay = $value - 1; + $nSW = 1; + break; + } + } + + //die; + if ($nSW == 1) { + $dEstimatedDate = date ( 'Y-m-d', strtotime ( "$nActualDate next " . $aDaysWeek [$nNextDay] ) ) . ' ' . date ( 'H:i:s', strtotime ( $sActualTime ) ); + //print_r($dEstimatedDate); + // die("03"); + } else { + $nEveryDays = $sDaysPerformTask; + // $nEveryDays = '1'; + if ($nFirstDay >= $nDayOfTheWeek || $nEveryDays == 1) + $sTypeOperation = "next"; + else + $sTypeOperation = "last"; + if ($nEveryDays == 1) { + // echo "**** $nActualDate *" . $sTypeOperation . "* *" . $aDaysWeek[$nFirstDay] . '*****' . date('H:i:s', strtotime($sActualTime)). "**"; + $dEstimatedDate = date ( 'Y-m-d', strtotime ( "$nActualDate " . $sTypeOperation . " " . $aDaysWeek [$nFirstDay] ) ) . ' ' . date ( 'H:i:s', strtotime ( $sActualTime ) ); + // echo "(date)*".$dEstimatedDate."*"; + // die("01"); + } else { + $nEveryDays = 1; + // $nActualDate = date('Y-m-d').' '.$sActualTime; + $nDataTmp = date ( 'Y-m-d', strtotime ( "$nActualDate + " . $nEveryDays . " Week" ) ); + // echo "$nActualDate + " . $nEveryDays . " Week "; + // echo "++"; + // echo strtotime( "+".$nEveryDays . " week"), "\n"; + // echo strtotime("$nActualDate +" . $nEveryDays . " Week "); + // echo "++"; + // echo $nDataTmp; + // echo "--"; + // echo $sTypeOperation; + // echo $nFirstDay; + // print_r ($aDaysWeek); + // $sTypeOperation = "next"; + $dEstimatedDate = date ( 'Y-m-d', strtotime ( "$nDataTmp " . $sTypeOperation . " " . $aDaysWeek [$nFirstDay] ) ) . ' ' . date ( 'H:i:s', strtotime ( $sActualTime ) ); + + // echo (strtotime ("$nDataTmp " . $sTypeOperation . " " . $aDaysWeek[$nFirstDay])); + // echo "$nDataTmp " . $sTypeOperation . " " . $aDaysWeek[$nFirstDay]; + + + // echo $dEstimatedDate; + // echo "--"; + // echo date('Y-m-d', strtotime ("$nDataTmp " . $sTypeOperation . " " . $aDaysWeek[$nFirstDay])) . ' ' . date('H:i:s', strtotime($sActualTime)); + // die("02"); + } + // die("03"); + } + } + break; + case '3' : + if (strlen ( $sMonths ) > 0) { // Must have at least one selected month + // Calculamos para la siguiente ejecucion, acorde a lo seleccionado + $aStartDay = explode ( '|', $sStartDay ); + $nYear = date ( "Y", strtotime ( $sActualTime ) ); + $nCurrentMonth = date ( "m", strtotime ( $sActualTime ) ); + $nCurrentDay = date ( "d", strtotime ( $sActualTime ) ); + $aMonths = explode ( '|', $sMonths ); + + $nSW = 0; + $nNextMonth = 0; + foreach ( $aMonths as $value ) { + if ($value > $nCurrentMonth) { + $nNextMonth = $value - 1; + $nSW = 1; + break; + } + } + if ($nSW == 1) { // Mes encontrado + $nExecNextMonth = $nNextMonth; + } else { + $nExecNextMonth = $aMonths [0] - 1; + $nYear ++; + } + switch ($sValue) { + case '1' : + $nExecNextMonth ++; + $nCurrentDay = $aStartDay [1]; + $dEstimatedDate = date ( 'Y-m-d', strtotime ( "$nYear-$nExecNextMonth-$nCurrentDay" ) ) . ' ' . date ( 'H:i:s', strtotime ( $sActualTime ) ); + break; + case '2' : + $aMontsShort = array ( + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' + ); + $aWeeksShort = array ( + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday' + ); + $sNumDayWeek = $aStartDay [1]; + $sDayWeek = ($aStartDay [2] == 7 ? 0 : $aStartDay [2]); + switch ($sNumDayWeek) { + case '1' : + $sDaysWeekOpt = "+0"; + break; + case '2' : + $sDaysWeekOpt = "+1"; + break; + case '3' : + $sDaysWeekOpt = "+2"; + break; + case '4' : + $sDaysWeekOpt = "+3"; + break; + case '5' : + $sDaysWeekOpt = "-1"; + $nExecNextMonth ++; + if ($nExecNextMonth >= 12) { + $nExecNextMonth = 0; + $nYear ++; + } + break; + } + + $dEstimatedDate = date ( 'Y-m-d', strtotime ( $sDaysWeekOpt . ' week ' . $aWeeksShort [$sDayWeek - 1] . ' ' . $aMontsShort [$nExecNextMonth] . ' ' . $nYear ) ) . ' ' . date ( 'H:i:s', strtotime ( $sActualTime ) ); + // krumo($nExecNextMonth, $sDayWeek); + // krumo($sDaysWeekOpt . ' week ' . $aWeeksShort[$sDayWeek-1] . ' ' . $aMontsShort[$nExecNextMonth] . ' ' . $nYear); + break; + } + + } + break; + } + + return $dEstimatedDate; + + } + + function Exists( $sUid ) { + try { + $oObj = CaseSchedulerPeer::retrieveByPk( $sUid ); + return (get_class($oObj) == 'CaseScheduler'); + } + catch (Exception $oError) { + throw($oError); + } + } + +} // CaseScheduler diff --git a/workflow/engine/classes/model/CaseSchedulerPeer.php b/workflow/engine/classes/model/CaseSchedulerPeer.php new file mode 100755 index 000000000..59be2d8e2 --- /dev/null +++ b/workflow/engine/classes/model/CaseSchedulerPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCaseSchedulerPeer.php'; + + // include object class + include_once 'classes/model/CaseScheduler.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CASE_SCHEDULER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseSchedulerPeer extends BaseCaseSchedulerPeer { + +} // CaseSchedulerPeer diff --git a/workflow/engine/classes/model/CaseTracker.php b/workflow/engine/classes/model/CaseTracker.php new file mode 100644 index 000000000..2643465f9 --- /dev/null +++ b/workflow/engine/classes/model/CaseTracker.php @@ -0,0 +1,121 @@ +<?php + +require_once 'classes/model/om/BaseCaseTracker.php'; + + +/** + * Skeleton subclass for representing a row from the 'CASE_TRACKER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseTracker extends BaseCaseTracker { + public function load($sProcessUID) { + try { + $oRow = CaseTrackerPeer::retrieveByPK($sProcessUID); + if (!is_null($oRow)) { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception("The row '$sProcessUID' in table CASE_TRACKER doesn't exist!")); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) { + $oConnection = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + try { + if (!isset($aData['CT_MAP_TYPE'])) { + $aData['CT_MAP_TYPE'] = 'PROCESSMAP'; + } + $oCaseTracker = new CaseTracker(); + $oCaseTracker->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oCaseTracker->validate()) { + $oConnection->begin(); + $iResult = $oCaseTracker->save(); + $oConnection->commit(); + return true; + } + else { + $sMessage = ''; + $aValidationFailures = $oCaseTracker->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function update($aData) { + $oConnection = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + try { + $oCaseTracker = CaseTrackerPeer::retrieveByPK($aData['PRO_UID']); + if (!is_null($oCaseTracker)) + { + $oCaseTracker->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oCaseTracker->validate()) { + $oConnection->begin(); + $iResult = $oCaseTracker->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oCaseTracker->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function remove($sProcessUID) { + $oConnection = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + try { + $oConnection->begin(); + $this->setProUid($sProcessUID); + $iResult = $this->delete(); + $oConnection->commit(); + return $iResult; + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function caseTrackerExists ( $sUid ) { + try { + $oObj = CaseTrackerPeer::retrieveByPk($sUid); + return (get_class($oObj) == 'CaseTracker'); + } + catch (Exception $oError) { + throw($oError); + } + } +} // CaseTracker diff --git a/workflow/engine/classes/model/CaseTrackerObject.php b/workflow/engine/classes/model/CaseTrackerObject.php new file mode 100644 index 000000000..94ffb12f8 --- /dev/null +++ b/workflow/engine/classes/model/CaseTrackerObject.php @@ -0,0 +1,169 @@ +<?php + +require_once 'classes/model/om/BaseCaseTrackerObject.php'; + + +/** + * Skeleton subclass for representing a row from the 'CASE_TRACKER_OBJECT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseTrackerObject extends BaseCaseTrackerObject { + public function load($Uid) { + try { + $oRow = CaseTrackerObjectPeer::retrieveByPK( $Uid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw( new Exception( "The row '$Uid' in table CaseTrackerObject doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) { + $oConnection = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + try { + if (!isset($aData['CTO_UID'])) { + $aData['CTO_UID'] = G::generateUniqueID(); + } + $oCaseTrackerObject = new CaseTrackerObject(); + $oCaseTrackerObject->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oCaseTrackerObject->validate()) { + $oConnection->begin(); + $iResult = $oCaseTrackerObject->save(); + $oConnection->commit(); + return true; + } + else { + $sMessage = ''; + $aValidationFailures = $oCaseTrackerObject->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function update($aData) + { + $oConnection = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + try { + $oCaseTrackerObject = CaseTrackerObjectPeer::retrieveByPK($aData['CTO_UID']); + if (!is_null($oCaseTrackerObject)) + { + $oCaseTrackerObject->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oCaseTrackerObject->validate()) { + $oConnection->begin(); + $iResult = $oCaseTrackerObject->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oCaseTrackerObject->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function remove($sCTOUID) { + $oConnection = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + try { + $oCaseTobj = CaseTrackerObjectPeer::retrieveByPK($sCTOUID); + if (get_class($oCaseTobj) == 'CaseTrackerObject') + { + $oConnection->begin(); + $iResult = $oCaseTobj->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw( new Exception( "The row '" . $sCTOUID . "' in table CaseTrackerObject doesn't exist!" )); + } + } + catch (Exception $oError) {var_dump($oError);die; + $oConnection->rollback(); + throw($oError); + } + } + + function reorderPositions($sProcessUID, $iPosition) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(CaseTrackerObjectPeer::PRO_UID, $sProcessUID); + $oCriteria->add(CaseTrackerObjectPeer::CTO_POSITION, $iPosition, '>'); + $oDataset = CaseTrackerObjectPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $this->update(array('CTO_UID' => $aRow['CTO_UID'], + 'PRO_UID' => $aRow['PRO_UID'], + 'CTO_TYPE_OBJ' => $aRow['CTO_TYPE_OBJ'], + 'CTO_UID_OBJ' => $aRow['CTO_UID_OBJ'], + 'CTO_CONDITION' => $aRow['CTO_CONDITION'], + 'CTO_POSITION' => $aRow['CTO_POSITION'] - 1)); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $Exception; + } + } + + function caseTrackerObjectExists ( $Uid ) { + try { + $oObj = CaseTrackerObjectPeer::retrieveByPk( $Uid ); + if ( get_class ($oObj) == 'CaseTrackerObject' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function removeByObject($sType, $sObjUid) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(CaseTrackerObjectPeer::CTO_TYPE_OBJ, $sType); + $oCriteria->add(CaseTrackerObjectPeer::CTO_UID_OBJ, $sObjUid); + CaseTrackerObjectPeer::doDelete($oCriteria); + } + catch(Exception $e) { + throw($e); + } + } +} // CaseTrackerObject diff --git a/workflow/engine/classes/model/CaseTrackerObjectPeer.php b/workflow/engine/classes/model/CaseTrackerObjectPeer.php new file mode 100644 index 000000000..ae124cd85 --- /dev/null +++ b/workflow/engine/classes/model/CaseTrackerObjectPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCaseTrackerObjectPeer.php'; + + // include object class + include_once 'classes/model/CaseTrackerObject.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CASE_TRACKER_OBJECT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseTrackerObjectPeer extends BaseCaseTrackerObjectPeer { + +} // CaseTrackerObjectPeer diff --git a/workflow/engine/classes/model/CaseTrackerPeer.php b/workflow/engine/classes/model/CaseTrackerPeer.php new file mode 100644 index 000000000..466c541e5 --- /dev/null +++ b/workflow/engine/classes/model/CaseTrackerPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseCaseTrackerPeer.php'; + + // include object class + include_once 'classes/model/CaseTracker.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CASE_TRACKER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class CaseTrackerPeer extends BaseCaseTrackerPeer { + +} // CaseTrackerPeer diff --git a/workflow/engine/classes/model/Configuration.php b/workflow/engine/classes/model/Configuration.php new file mode 100644 index 000000000..bd00b35b2 --- /dev/null +++ b/workflow/engine/classes/model/Configuration.php @@ -0,0 +1,145 @@ +<?php +/** + * Configuration.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseConfiguration.php'; +require_once 'classes/model/Content.php'; + + +/** + * Skeleton subclass for representing a row from the 'CONFIGURATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Configuration extends BaseConfiguration { + public function create($aData) + { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->setCfgUid($aData['CFG_UID']); + $this->setObjUid($aData['OBJ_UID']); + $this->setCfgValue(isset($aData['CFG_VALUE'])?$aData['CFG_VALUE']:''); + $this->setProUid($aData['PRO_UID']); + $this->setUsrUid($aData['USR_UID']); + $this->setAppUid($aData['APP_UID']); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function load($CfgUid, $ObjUid='', $ProUid='', $UsrUid='', $AppUid='') + { + try { + $oRow = ConfigurationPeer::retrieveByPK( $CfgUid, $ObjUid, $ProUid, $UsrUid, $AppUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception( "The row '$CfgUid, $ObjUid, $ProUid, $UsrUid, $AppUid' in table Configuration doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + public function update($fields) + { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['CFG_UID'], $fields['OBJ_UID'], $fields['PRO_UID'], $fields['USR_UID'], $fields['APP_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $contentResult=0; + $result=$this->save(); + $result=($result==0)?($contentResult>0?1:0):$result; + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function remove($CfgUid, $ObjUid, $ProUid, $UsrUid, $AppUid) + { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->setCfgUid($CfgUid); + $this->setObjUid($ObjUid); + $this->setProUid($ProUid); + $this->setUsrUid($UsrUid); + $this->setAppUid($AppUid); + $result=$this->delete(); + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function exists($CfgUid, $ObjUid, $ProUid, $UsrUid, $AppUid) + { + $oRow = ConfigurationPeer::retrieveByPK( $CfgUid, $ObjUid, $ProUid, $UsrUid, $AppUid ); + return ( get_class ($oRow) == 'Configuration' ); + } +} // Configuration diff --git a/workflow/engine/classes/model/ConfigurationPeer.php b/workflow/engine/classes/model/ConfigurationPeer.php new file mode 100644 index 000000000..3a3d1b512 --- /dev/null +++ b/workflow/engine/classes/model/ConfigurationPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * ConfigurationPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseConfigurationPeer.php'; + + // include object class + include_once 'classes/model/Configuration.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CONFIGURATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ConfigurationPeer extends BaseConfigurationPeer { + +} // ConfigurationPeer diff --git a/workflow/engine/classes/model/Content.php b/workflow/engine/classes/model/Content.php new file mode 100644 index 000000000..813bee8c6 --- /dev/null +++ b/workflow/engine/classes/model/Content.php @@ -0,0 +1,299 @@ +<?php +/** + * Content.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseContent.php'; + +/** + * Skeleton subclass for representing a row from the 'CONTENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Content extends BaseContent { + + /* + * Load the content row specified by the parameters: + * @param string $sUID + * @return variant + */ + function load($ConCategory, $ConParent, $ConId, $ConLang) { + $content = ContentPeer::retrieveByPK ( $ConCategory, $ConParent, $ConId, $ConLang ); + if (is_null ( $content )) { + //we dont find any value for this field and language in CONTENT table + $ConValue = Content::autoLoadSave ( $ConCategory, $ConParent, $ConId, $ConLang ); + } else { + //krumo($content); + $ConValue = $content->getConValue (); + if ($ConValue == "") { //try to find a valid translation + $ConValue = Content::autoLoadSave ( $ConCategory, $ConParent, $ConId, $ConLang ); + } + } + return $ConValue; + } + /* + * Find a valid Lang for current Content. The most recent + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @return string + * + */ + function getDefaultContentLang($ConCategory, $ConParent, $ConId, $destConLang) { + $Criteria = new Criteria ( 'workflow' ); + $Criteria->clearSelectColumns ()->clearOrderByColumns (); + + $Criteria->addSelectColumn ( ContentPeer::CON_CATEGORY ); + $Criteria->addSelectColumn ( ContentPeer::CON_PARENT ); + $Criteria->addSelectColumn ( ContentPeer::CON_ID ); + $Criteria->addSelectColumn ( ContentPeer::CON_LANG ); + $Criteria->addSelectColumn ( ContentPeer::CON_VALUE ); + + $Criteria->add ( ContentPeer::CON_CATEGORY, $ConCategory, CRITERIA::EQUAL ); + $Criteria->add ( ContentPeer::CON_PARENT, $ConParent, CRITERIA::EQUAL ); + $Criteria->add ( ContentPeer::CON_ID, $ConId, CRITERIA::EQUAL ); + + $Criteria->add ( ContentPeer::CON_LANG, $destConLang, CRITERIA::NOT_EQUAL ); + + $rs = ContentPeer::doSelectRS ( $Criteria ); + $rs->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $rs->next (); + + if (is_array ( $row = $rs->getRow () )) { + $defaultLang = $row ['CON_LANG']; + + } else { + $defaultLang = ""; + } + return ($defaultLang); + } + /* + * Load the content row and the Save automatically the row for the destination language + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @param string $destConLang + * @return string + * if the row doesn't exists, it will be created automatically, even the default 'en' language + */ + function autoLoadSave($ConCategory, $ConParent, $ConId, $destConLang) { + //search in 'en' language, the default language + $content = ContentPeer::retrieveByPK ( $ConCategory, $ConParent, $ConId, 'en' ); + + if ((is_null ( $content )) || ($content->getConValue () == "")) { + $differentLang = Content::getDefaultContentLang ( $ConCategory, $ConParent, $ConId, $destConLang ); + $content = ContentPeer::retrieveByPK ( $ConCategory, $ConParent, $ConId, $differentLang ); + } + + //to do: review if the $destConLang is a valid language/ + if (is_null ( $content )) + $ConValue = ''; //we dont find any value for this field and language in CONTENT table + else + $ConValue = $content->getConValue (); + + try { + $con = ContentPeer::retrieveByPK ( $ConCategory, $ConParent, $ConId, $destConLang ); + if (is_null ( $con )) { + $con = new Content ( ); + } + $con->setConCategory ( $ConCategory ); + $con->setConParent ( $ConParent ); + $con->setConId ( $ConId ); + $con->setConLang ( $destConLang ); + $con->setConValue ( $ConValue ); + if ($con->validate ()) { + $res = $con->save (); + } + } catch ( Exception $e ) { + throw ($e); + } + + return $ConValue; + } + + /* + * Insert a content row + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @param string $ConLang + * @param string $ConValue + * @return variant + */ + function addContent($ConCategory, $ConParent, $ConId, $ConLang, $ConValue) { + try { + $con = ContentPeer::retrieveByPK ( $ConCategory, $ConParent, $ConId, $ConLang ); + + if (is_null ( $con )) { + $con = new Content ( ); + } else { + if ($con->getConParent () == $ConParent && $con->getConCategory () == $ConCategory && $con->getConValue () == $ConValue && $con->getConLang () == $ConLang && $con->getConId () == $ConId) + return true; + } + $con->setConCategory ( $ConCategory ); + if ($con->getConParent () != $ConParent) + $con->setConParent ( $ConParent ); + $con->setConId ( $ConId ); + $con->setConLang ( $ConLang ); + $con->setConValue ( $ConValue ); + if ($con->validate ()) { + $res = $con->save (); + return $res; + } else { + $e = new Exception ( "Error in addcontent, the row $ConCategory, $ConParent, $ConId, $ConLang is not Valid" ); + throw ($e); + } + } catch ( Exception $e ) { + throw ($e); + } + } + + /* + * Insert a content row + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @param string $ConLang + * @param string $ConValue + * @return variant + */ + function insertContent($ConCategory, $ConParent, $ConId, $ConLang, $ConValue) { + try { + $con = new Content ( ); + $con->setConCategory ( $ConCategory ); + $con->setConParent ( $ConParent ); + $con->setConId ( $ConId ); + $con->setConLang ( $ConLang ); + $con->setConValue ( $ConValue ); + if ($con->validate ()) { + $res = $con->save (); + return $res; + } else { + $e = new Exception ( "Error in addcontent, the row $ConCategory, $ConParent, $ConId, $ConLang is not Valid" ); + throw ($e); + } + } catch ( Exception $e ) { + throw ($e); + } + } + + /* + * remove a content row + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @param string $ConLang + * @param string $ConValue + * @return variant + */ + function removeContent($ConCategory, $ConParent, $ConId) { + try { + $c = new Criteria ( ); + $c->add ( ContentPeer::CON_CATEGORY, $ConCategory ); + $c->add ( ContentPeer::CON_PARENT, $ConParent ); + $c->add ( ContentPeer::CON_ID, $ConId ); + $result = ContentPeer::doSelectRS ( $c ); + $result->next (); + $row = $result->getRow (); + while ( is_array ( $row ) ) { + ContentPeer::doDelete ( array ($ConCategory, $ConParent, $ConId, $row [3] ) ); + $result->next (); + $row = $result->getRow (); + } + } catch ( Exception $e ) { + throw ($e); + } + + } + + /* + * Reasons if the record already exists + * + * @param string $ConCategory + * @param string $ConParent + * @param string $ConId + * @param string $ConLang + * @param string $ConValue + * @return boolean true or false + */ + function Exists ($ConCategory, $ConParent, $ConId, $ConLang) + { + try { + $oPro = ContentPeer::retrieveByPk($ConCategory, $ConParent, $ConId, $ConLang); + if ( get_class ($oPro) == 'Content' ) { + return true; + } else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function regenerateContent($langId) + { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(ContentPeer::CON_CATEGORY); + $oCriteria->addSelectColumn(ContentPeer::CON_ID); + $oCriteria->addSelectColumn(ContentPeer::CON_VALUE); + $oCriteria->add(ContentPeer::CON_LANG, 'en'); + $oCriteria->add(ContentPeer::CON_VALUE, '', Criteria::NOT_EQUAL ); + $oDataset = ContentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $oContent = new Content(); + while ($aRow = $oDataset->getRow()) { + $oContent->load($aRow['CON_CATEGORY'], '', $aRow['CON_ID'], $langId); + $oDataset->next(); + } + } + + function removeLanguageContent($lanId) { + try { + $c = new Criteria ( ); + $c->addSelectColumn(ContentPeer::CON_CATEGORY); + $c->addSelectColumn(ContentPeer::CON_PARENT); + $c->addSelectColumn(ContentPeer::CON_ID); + $c->addSelectColumn(ContentPeer::CON_LANG); + + $c->add ( ContentPeer::CON_LANG, $lanId ); + $result = ContentPeer::doSelectRS ( $c ); + $result->next (); + $row = $result->getRow (); + while ( is_array ( $row ) ) { + ContentPeer::doDelete ( array ($row['CON_CATEGORY'], $row['CON_PARENT'], $row['CON_ID'], $lanId ) ); + $result->next (); + $row = $result->getRow (); + } + } catch ( Exception $e ) { + throw ($e); + } + } +} // Content diff --git a/workflow/engine/classes/model/ContentPeer.php b/workflow/engine/classes/model/ContentPeer.php new file mode 100644 index 000000000..ffb6d0f5a --- /dev/null +++ b/workflow/engine/classes/model/ContentPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * ContentPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseContentPeer.php'; + + // include object class + include_once 'classes/model/Content.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'CONTENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ContentPeer extends BaseContentPeer { + +} // ContentPeer diff --git a/workflow/engine/classes/model/DbSource.php b/workflow/engine/classes/model/DbSource.php new file mode 100644 index 000000000..67ee7d37d --- /dev/null +++ b/workflow/engine/classes/model/DbSource.php @@ -0,0 +1,195 @@ +<?php +/** + * DbSource.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/Content.php'; +require_once 'classes/model/om/BaseDbSource.php'; + + +/** + * Skeleton subclass for representing a row from the 'DB_SOURCE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DbSource extends BaseDbSource +{ + + /** + * This value goes in the content table + * @var string + */ + protected $db_source_description = ''; + + /** + * Get the rep_tab_title column value. + * @return string + */ + public function getDBSourceDescription() { + if ( $this->getDbsUid() == "" ) { + throw ( new Exception( "Error in getDBSourceDescription, the getDbsUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG' ) ? SYS_LANG : 'en'; + $this->db_source_description = Content::load ( 'DBS_DESCRIPTION', '', $this->getDbsUid(), $lang ); + return $this->db_source_description; + } + + function getCriteriaDBSList($sProcessUID) + { + $sDelimiter = DBAdapter::getStringDelimiter(); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_UID); + $oCriteria->addSelectColumn(DbSourcePeer::PRO_UID); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_TYPE); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_SERVER); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_DATABASE_NAME); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_USERNAME); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_PASSWORD); + $oCriteria->addSelectColumn(DbSourcePeer::DBS_PORT); + $oCriteria->addAsColumn('DBS_DESCRIPTION', 'C.CON_VALUE'); + $oCriteria->addAlias('C', 'CONTENT'); + $aConditions = array(); + $aConditions[] = array(DbSourcePeer::DBS_UID, 'C.CON_ID'); + $aConditions[] = array('C.CON_CATEGORY', $sDelimiter . 'DBS_DESCRIPTION' . $sDelimiter); + $aConditions[] = array('C.CON_LANG', $sDelimiter . SYS_LANG . $sDelimiter); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(DbSourcePeer::PRO_UID, $sProcessUID); + return $oCriteria; + } + + public function load($Uid) + { + try { + $oRow = DbSourcePeer::retrieveByPK($Uid); + if (!is_null($oRow)) { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $aFields['DBS_DESCRIPTION'] = $this->getDBSourceDescription(); + $this->setNew(false); + return $aFields; + } else { + throw(new Exception( "The row '$Uid' in table DbSource doesn't exist!" )); + } + } + catch (exception $oError) { + throw ($oError); + } + } + + function Exists ( $Uid ) { + try { + $oPro = DbSourcePeer::retrieveByPk( $Uid ); + if ( get_class ($oPro) == 'DbSource' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function update($fields) + { + if( $fields['DBS_ENCODE'] == '0'){ + unset($fields['DBS_ENCODE']); + } + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + try { + $con->begin(); + $this->load($fields['DBS_UID']); + $this->fromArray($fields, BasePeer::TYPE_FIELDNAME); + if ($this->validate()) { + $result = $this->save(); + $con->commit(); + return $result; + } else { + $con->rollback(); + throw (new Exception("Failed Validation in class " . get_class($this) . ".")); + } + } + catch (exception $e) { + $con->rollback(); + throw ($e); + } + } + + function remove($DbsUid) + { + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + try { + $con->begin(); + $this->setDbsUid($DbsUid); + // note added by gustavo cruz gustavo-at-colosa-dot-com + // we assure that the _delete attribute must be set to false + // if a record exists in the database with that uid. + if ($this->Exists($DbsUid)){ + $this->setDeleted(false); + } + $result = $this->delete(); + $con->commit(); + return $result; + } + catch (exception $e) { + $con->rollback(); + throw ($e); + } + } + + function create($aData) + { + if( $aData['DBS_ENCODE'] == '0'){ + unset($aData['DBS_ENCODE']); + } + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + try { + if ( isset ( $aData['DBS_UID'] ) && $aData['DBS_UID']== '' ) + unset ( $aData['DBS_UID'] ); + if ( !isset ( $aData['DBS_UID'] ) ) + $aData['DBS_UID'] = G::generateUniqueID(); + $this->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($this->validate()) { + $result = $this->save(); + } else { + $e = new Exception("Failed Validation in class " . get_class($this) . "."); + $e->aValidationFailures = $this->getValidationFailures(); + throw ($e); + } + $con->commit(); + return $this->getDbsUid(); + } + catch (exception $e) { + $con->rollback(); + throw ($e); + } + } + +} // DbSource diff --git a/workflow/engine/classes/model/DbSourcePeer.php b/workflow/engine/classes/model/DbSourcePeer.php new file mode 100644 index 000000000..de60521cd --- /dev/null +++ b/workflow/engine/classes/model/DbSourcePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseDbSourcePeer.php'; + + // include object class + include_once 'classes/model/DbSource.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'DB_SOURCE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DbSourcePeer extends BaseDbSourcePeer { + +} // DbSourcePeer diff --git a/workflow/engine/classes/model/Department.php b/workflow/engine/classes/model/Department.php new file mode 100644 index 000000000..f202e3112 --- /dev/null +++ b/workflow/engine/classes/model/Department.php @@ -0,0 +1,558 @@ +<?php +/** + * Department.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseDepartment.php'; +require_once 'classes/model/Users.php'; + + +/** + * Skeleton subclass for representing a row from the 'DEPARTMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Department extends BaseDepartment { + + +protected $depo_title = ''; +/** + * Create the Department + * + * @param array $aData + * @return void + */ + + function create ($aData ) { + $con = Propel::getConnection( DepartmentPeer::DATABASE_NAME ); + try { + if ( isset ( $aData['DEP_UID'] ) ) + $this->setDepUid ( $aData['DEP_UID'] ); + else + $this->setDepUid ( G::generateUniqueID() ); + + if ( isset ( $aData['DEP_PARENT'] ) ) + $this->setDepParent ( $aData['DEP_PARENT'] ); + else + $this->setDepParent ( '' ); + + if ( isset ( $aData['DEP_MANAGER'] ) ) + $this->setDepManager ( $aData['DEP_MANAGER'] ); + else + $this->setDepManager ( '' ); + + if ( isset ( $aData['DEP_LOCATION'] ) ) + $this->setDepLocation ( $aData['DEP_LOCATION'] ); + else + $this->setDepLocation ( '' ); + + if ( isset ( $aData['DEP_STATUS'] ) ) + $this->setDepStatus ( $aData['DEP_STATUS'] ); + else + $this->setDepStatus ( 'ACTIVE' ); + + if ( isset ( $aData['DEP_REF_CODE'] ) ) + $this->setDepRefCode ( $aData['DEP_REF_CODE'] ); + else + $this->setDepRefCode ( '' ); + + if ( isset ( $aData['DEP_LDAP_DN'] ) ) + $this->setDepLdapDn ( $aData['DEP_LDAP_DN'] ); + else + $this->setDepLdapDn ( '' ); + + if ( isset ( $aData['DEP_TITLE'] ) ) + $this->setDepTitle ( $aData['DEP_TITLE'] ); + else + $this->setDepTitle ( '' ); + + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + + $con->commit(); + return $this->getDepUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new Exception ( " The Department row cannot be created $msg " ) ); + } + + } + catch (Exception $e) { + $con->rollback(); + throw ($e); + } + } + +/** + * Get the [depo_title] column value. + * @return string + */ + public function getDepTitle() + { + if ( $this->getDepUid() == '' ) { + throw ( new Exception( "Error in getDepTitle, the DEP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->depo_title = Content::load ( 'DEPO_TITLE', '', $this->getDepUid(), $lang ); + return $this->depo_title; + } + + /** + * Set the [depo_title] column value. + * + * @param string $v new value + * @return void + */ + public function setDepTitle($v) + { + if ( $this->getDepUid() == '' ) { + throw ( new Exception( "Error in setGrpTitle, the GRP_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->depo_title !== $v || $v === '') { + $this->depo_title = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'DEPO_TITLE', '', $this->getDepUid(), $lang, $this->depo_title ); + } + + } // set() + + +/** + * Load the Process row specified in [depo_id] column value. + * + * @param string $ProUid the uid of the Prolication + * @return array $Fields the fields + */ + + function Load ( $DepUid ) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + try { + $oDept = DepartmentPeer::retrieveByPk( $DepUid ); + if ( get_class ($oDept) == 'Department' ) { + $aFields = $oDept->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + $aFields['DEPO_TITLE'] = $oDept->getDepTitle(); + return $aFields; + } + else { + throw(new Exception( "The row '$DepUid' in table Department doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + +/** + * Update the Dep row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( DepartmentPeer::DATABASE_NAME ); + try { + $con->begin(); + $oPro = DepartmentPeer::retrieveByPK( $aData['DEP_UID'] ); + if ( get_class ($oPro) == 'Department' ) { + $oPro->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oPro->validate()) { + if ( isset ( $aData['DEPO_TITLE'] ) ) + $oPro->setDepTitle( $aData['DEPO_TITLE'] ); + if ( isset ( $aData['DEP_STATUS'] ) ) + $oPro->setDepStatus( $aData['DEP_STATUS'] ); + if ( isset ( $aData['DEP_PARENT'] ) ) + $oPro->setDepParent( $aData['DEP_PARENT'] ); + if ( isset ( $aData['DEP_MANAGER'] ) ) + $oPro->setDepManager( $aData['DEP_MANAGER'] ); + $res = $oPro->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The Department row cannot be created!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "The row '" . $aData['DEP_UID'] . "' in table Department doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + + /** + * Remove the row + * @param array $aData or string $ProUid + * @return string + **/ + public function remove($ProUid) + { + if ( is_array ( $ProUid ) ) { + $ProUid = ( isset ( $ProUid['DEP_UID'] ) ? $ProUid['DEP_UID'] : '' ); + } + try { + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->add(UsersPeer::DEP_UID, $ProUid, Criteria::EQUAL); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $oDataset->next(); + $aFields = array(); + while ($aRow = $oDataset->getRow()) { + + $aFields['USR_UID'] = $aRow['USR_UID']; + $aFields['DEP_UID'] = ''; + $oDepto = UsersPeer::retrieveByPk($aFields['USR_UID']); + if (get_class($oDepto) == 'UsersPeer') { + return true; + } else { + $oDepto = new Users(); + $oDepto->update($aFields); + } + + $oDataset->next(); + } + + + + $oPro = DepartmentPeer::retrieveByPK( $ProUid ); + if (!is_null($oPro)) + { + Content::removeContent('DEPO_TITLE', '', $oPro->getDepUid()); + Content::removeContent('DEPO_DESCRIPTION', '', $oPro->getDepUid()); + return $oPro->delete(); + } + else { + throw(new Exception( "The row '$ProUid' in table Group doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + +/** + * Load the Department row specified in [depo_id] column value. + * + * @param string $ProUid the uid of the Prolication + * @return array $Fields the fields + */ + + function existsDepartment( $DepUid ) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + $oPro = DepartmentPeer::retrieveByPk( $DepUid ); + if ( get_class ($oPro) == 'Department' ) { + return true; + } + else { + return false; + } + } + + function existsUserInDepartment( $depId, $userId ) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + $oUser = UsersPeer::retrieveByPk( $userId ); + if ( get_class ($oUser) == 'Users' ) { + if ( $oUser->getDepUid() == $depId ) + return true; + } + + return false; + } + + function updateDepartmentManager ($depId) { + $managerId = ''; + $depParent = ''; + $oDept = DepartmentPeer::retrieveByPk( $depId ); + if ( get_class ($oDept) == 'Department' ) { + $managerId = $oDept->getDepManager( ); + $depParent = $oDept->getDepParent( ); + } + + // update the reportsTo field to all users in that department + $conn = Propel::getConnection(UsersPeer::DATABASE_NAME); + $selectCriteria = new Criteria('workflow'); + $selectCriteria->add(UsersPeer::DEP_UID, $depId ); + $selectCriteria->add(UsersPeer::USR_UID, $managerId , Criteria::NOT_EQUAL); + + // Create a Criteria object includes the value you want to set + $updateCriteria = new Criteria('workflow'); + $updateCriteria->add(UsersPeer::USR_REPORTS_TO, $managerId ); + BasePeer::doUpdate($selectCriteria, $updateCriteria, $conn); + + // update manager's manager, getting the manager of PARENT DEPARTMENT in order to enable scalating + $oUser = UsersPeer::retrieveByPk( $managerId ); + if ( get_class ($oUser) == 'Users' ) { + $oDept = DepartmentPeer::retrieveByPk( $depParent ); + $oUser->setUsrReportsTo( '' ); //by default no manager + if ( get_class ($oDept) == 'Department' ) { + $managerParentId = $oDept->getDepManager( ); + if ( trim($managerParentId) != '' ) { + $oUser->setUsrReportsTo( $managerParentId ); + } + } + $oUser->save(); + } + + // get children departments to update the reportsTo of these children + $childrenCriteria = new Criteria('workflow'); + $childrenCriteria->add(DepartmentPeer::DEP_PARENT, $depId ); + $oDataset = DepartmentPeer::doSelectRS($childrenCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $oDataset->next(); + while ( $aRow = $oDataset->getRow() ) { + $oUser = UsersPeer::retrieveByPk($aRow['DEP_MANAGER']); + if (get_class($oUser) == 'Users') { + $oUser->setUsrReportsTo ( $managerId ); + $oUser->save(); + } + $oDataset->next(); + } + + } + + //add an user to a department and sync all about manager info + function addUserToDepartment( $depId, $userId, $manager, $updateManager = false ) { + try { + //update the field in user table + $oUser = UsersPeer::retrieveByPk( $userId ); + if ( get_class ($oUser) == 'Users' ) { + $oUser->setDepUid( $depId ); + $oUser->save(); + } + + //if the user is a manager update Department Table + if ( $manager ) { + $oDept = DepartmentPeer::retrieveByPk( $depId ); + if ( get_class ($oDept) == 'Department' ) { + $oDept->setDepManager( $userId ); + $oDept->save(); + } + } + + //now update the reportsto to all + if ( $updateManager ) { + $this->updateDepartmentManager ($depId); + } + return true; + } + catch ( Exception $oError) { + throw($oError); + } + } + + // select departments + // this function is used to draw the hierachy tree view + function getDepartments( $DepParent ) { + try { + $result = array(); + $criteria = new Criteria('workflow'); + $criteria->add(DepartmentPeer::DEP_PARENT, $DepParent, Criteria::EQUAL); + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + $objects = DepartmentPeer::doSelect($criteria, $con); + foreach( $objects as $oDepartment ) { + $node = array(); + $node['DEP_UID'] = $oDepartment->getDepUid(); + $node['DEP_PARENT'] = $oDepartment->getDepParent(); + $node['DEP_TITLE'] = $oDepartment->getDepTitle(); + $node['DEP_LAST'] = 0; + + $criteriaCount = new Criteria('workflow'); + $criteriaCount->clearSelectColumns(); + $criteriaCount->addSelectColumn( 'COUNT(*)' ); + $criteriaCount->add(DepartmentPeer::DEP_PARENT, $oDepartment->getDepUid(), Criteria::EQUAL); + $rs = DepartmentPeer::doSelectRS($criteriaCount); + $rs->next(); + $row = $rs->getRow(); + $node['HAS_CHILDREN'] = $row[0]; + $result[] = $node; + } + if ( count($result) >= 1 ) + $result[ count($result) -1 ]['DEP_LAST'] = 1; + return $result; + } + catch (exception $e) { + throw $e; + } + } + + function getUsersFromDepartment( $sDepUid, $sManagerUid ) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_REPORTS_TO); + $oCriteria->add(UsersPeer::USR_STATUS, 'CLOSED', Criteria::NOT_EQUAL); + $oCriteria->add(UsersPeer::DEP_UID, $sDepUid); + + $rs = UsersPeer::doSelectRS($oCriteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $oUser = new Users(); + $aUsers[] = array('USR_UID' =>'char', 'USR_USERNAME' =>'char','USR_FULLNAME' =>'char', 'USR_REPORTS_TO'=>'char','USR_MANAGER' =>'char'); + $rs->next(); + $row = $rs->getRow(); + while( is_array($row) ) { + $usrFields = $oUser->LoadDetails( $row['USR_UID'] ); + $row['USR_USERNAME'] = $usrFields['USR_USERNAME']; + $row['USR_FULLNAME'] = $usrFields['USR_FULLNAME']; + $row['USR_MANAGER'] = $row['USR_UID'] == $sManagerUid ? G::loadTranslation("ID_YES") : G::loadTranslation("ID_NO"); + $row['DEP_UID'] = $sDepUid; + if ( $row['USR_REPORTS_TO'] != '' ) { + try { + $managerFields = $oUser->LoadDetails( $row['USR_REPORTS_TO'] ); + $row['USR_REPORTS_NAME'] = $managerFields['USR_FULLNAME']; + } + catch (exception $e) { + $row['USR_REPORTS_NAME'] = '.'; + } + } + else + $row['USR_REPORTS_NAME'] = '.'; + $aUsers[] = $row; + $rs->next(); + $row = $rs->getRow(); + } + + G::LoadClass('ArrayPeer'); + global $_DBArray; + $_DBArray['DepartmentUserList'] = $aUsers ; + $_SESSION['_DBArray'] = $_DBArray; + $oCriteriaT = new Criteria('dbarray'); + $oCriteriaT->setDBArrayTable('DepartmentUserList'); + + return $oCriteriaT; + } + catch (exception $e) { + throw $e; + } + } + + /* + * Remove a user from Departments + * @param string $DepUid, $UsrUid + * @return array + */ + function removeUserFromDepartment($DepUid, $UsrUid) { + $aFields = array ('USR_UID'=> $UsrUid,'DEP_UID'=> '', 'USR_REPORTS_TO' => ''); + try { + $oUser = UsersPeer::retrieveByPk( $UsrUid ); + if ( get_class($oUser) == 'Users' ) { + //$oDepto = new Users(); + $oUser->setDepUid ( ''); + $oUser->setUsrReportsTo ( ''); + $oUser->save(); + } + } + catch (exception $oError) { + throw ($oError); + } + } + + /* + * Return the available users list criteria object + * @param string $sGroupUID + * @return object + */ + function getAvailableUsersCriteria($sGroupUID = '') + { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->add(UsersPeer::DEP_UID, "", Criteria::EQUAL); + $oCriteria->add(UsersPeer::USR_STATUS, 'ACTIVE'); + return $oCriteria; + } + catch (exception $oError) { + throw ($oError); + } + } + + /* + * Return the cant Users In Department + * @param string $sDepUID + * @return object + */ + function cantUsersInDepartment ( $sDepUID ) { + try { + $c = new Criteria('workflow'); + $c->addSelectColumn('COUNT(*)'); + $c->add(UsersPeer::USR_STATUS, 'CLOSED', Criteria::NOT_EQUAL); + $c->add(UsersPeer::DEP_UID, $sDepUID); + + $rs = UsersPeer::doSelectRS($c); + $rs->next(); + $row = $rs->getRow(); + $count = $row[0]; + return $count; + } + catch (exception $oError) { + throw ($oError); + } + } + function loadByGroupname ( $Groupname ) { + $c = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( ContentPeer::CON_CATEGORY ); + $c->addSelectColumn( ContentPeer::CON_VALUE ); + + $c->add(ContentPeer::CON_CATEGORY, 'DEPO_TITLE'); + $c->add(ContentPeer::CON_VALUE, $Groupname); + $c->add(ContentPeer::CON_LANG, SYS_LANG ); + return $c; + } + +} // Department diff --git a/workflow/engine/classes/model/DepartmentPeer.php b/workflow/engine/classes/model/DepartmentPeer.php new file mode 100644 index 000000000..60b5d2f8d --- /dev/null +++ b/workflow/engine/classes/model/DepartmentPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * DepartmentPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseDepartmentPeer.php'; + + // include object class + include_once 'classes/model/Department.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'DEPARTMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DepartmentPeer extends BaseDepartmentPeer { + +} // DepartmentPeer diff --git a/workflow/engine/classes/model/DimTimeComplete.php b/workflow/engine/classes/model/DimTimeComplete.php new file mode 100644 index 000000000..8ed346a9a --- /dev/null +++ b/workflow/engine/classes/model/DimTimeComplete.php @@ -0,0 +1,19 @@ +<?php + +require_once 'classes/model/om/BaseDimTimeComplete.php'; + + +/** + * Skeleton subclass for representing a row from the 'DIM_TIME_COMPLETE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DimTimeComplete extends BaseDimTimeComplete { + +} // DimTimeComplete diff --git a/workflow/engine/classes/model/DimTimeCompletePeer.php b/workflow/engine/classes/model/DimTimeCompletePeer.php new file mode 100644 index 000000000..0787e6fba --- /dev/null +++ b/workflow/engine/classes/model/DimTimeCompletePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseDimTimeCompletePeer.php'; + + // include object class + include_once 'classes/model/DimTimeComplete.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'DIM_TIME_COMPLETE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DimTimeCompletePeer extends BaseDimTimeCompletePeer { + +} // DimTimeCompletePeer diff --git a/workflow/engine/classes/model/DimTimeDelegate.php b/workflow/engine/classes/model/DimTimeDelegate.php new file mode 100644 index 000000000..3a91ba12d --- /dev/null +++ b/workflow/engine/classes/model/DimTimeDelegate.php @@ -0,0 +1,19 @@ +<?php + +require_once 'classes/model/om/BaseDimTimeDelegate.php'; + + +/** + * Skeleton subclass for representing a row from the 'DIM_TIME_DELEGATE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DimTimeDelegate extends BaseDimTimeDelegate { + +} // DimTimeDelegate diff --git a/workflow/engine/classes/model/DimTimeDelegatePeer.php b/workflow/engine/classes/model/DimTimeDelegatePeer.php new file mode 100644 index 000000000..562c8ff64 --- /dev/null +++ b/workflow/engine/classes/model/DimTimeDelegatePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseDimTimeDelegatePeer.php'; + + // include object class + include_once 'classes/model/DimTimeDelegate.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'DIM_TIME_DELEGATE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DimTimeDelegatePeer extends BaseDimTimeDelegatePeer { + +} // DimTimeDelegatePeer diff --git a/workflow/engine/classes/model/Dynaform.php b/workflow/engine/classes/model/Dynaform.php new file mode 100644 index 000000000..d83e03d9b --- /dev/null +++ b/workflow/engine/classes/model/Dynaform.php @@ -0,0 +1,469 @@ +<?php +/** + * Dynaform.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseDynaform.php'; +require_once 'classes/model/Content.php'; +require_once('classes/model/AdditionalTables.php'); +G::LoadClass('dynaFormField'); + +/** + * Skeleton subclass for representing a row from the 'DYNAFORM' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Dynaform extends BaseDynaform { + /** + * This value goes in the content table + * @var string + */ + protected $dyn_title = ''; + + /** + * Get the [Dyn_title] column value. + * @return string + */ + public function getDynTitle() + { + if ( $this->getDynUid() == '' ) { + throw ( new Exception( "Error in getDynTitle, the DYN_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->dyn_title = Content::load ( 'DYN_TITLE', '', $this->getDynUid(), $lang ); + return $this->dyn_title; + } + + /** + * Set the [Dyn_title] column value. + * + * @param string $v new value + * @return void + */ + public function setDynTitle($v) + { + if ( $this->getDynUid() == '' ) { + throw ( new Exception( "Error in setDynTitle, the DYN_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_title !== $v || $v === '') { + $this->dyn_title = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'DYN_TITLE', '', $this->getDynUid(), $lang, $this->dyn_title ); + } + + } // set() + + /** + * This value goes in the content table + * @var string + */ + protected $dyn_description = ''; + + /** + * Get the [Dyn_description] column value. + * @return string + */ + public function getDynDescription() + { + if ( $this->getDynUid() == '' ) { + throw ( new Exception( "Error in getDynDescription, the DYN_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->dyn_description = Content::load ( 'DYN_DESCRIPTION', '', $this->getDynUid(), $lang ); + return $this->dyn_description; + } + + /** + * Set the [Dyn_description] column value. + * + * @param string $v new value + * @return void + */ + public function setDynDescription($v) + { + if ( $this->getDynUid() == '' ) { + throw ( new Exception( "Error in setDynDescription, the DYN_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_description !== $v || $v === '') { + $this->dyn_description = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'DYN_DESCRIPTION', '', $this->getDynUid(), $lang, $this->dyn_description ); + } + + } // set() + + /** + * Creates the Dynaform + * + * @param array $aData Fields with : + * $aData['DYN_UID'] the dynaform id + * $aData['USR_UID'] the userid + * @return void + */ + + function create ($aData ) { + if ( !isset ( $aData['PRO_UID'] ) ) { + throw ( new PropelException ( 'The dynaform cannot be created. The PRO_UID is empty.' ) ); + } + $con = Propel::getConnection( DynaformPeer::DATABASE_NAME ); + try { + if ( isset ( $aData['DYN_UID'] ) && $aData['DYN_UID']== '' ) + unset ( $aData['DYN_UID'] ); + if ( !isset ( $aData['DYN_UID'] ) ) + $dynUid = ( G::generateUniqueID() ); + else + $dynUid = $aData['DYN_UID']; + $this->setDynUid ( $dynUid ); + $this->setProUid ( $aData['PRO_UID'] ); + $this->setDynType ( isset($aData['DYN_TYPE'])?$aData['DYN_TYPE']:'xmlform' ); + $this->setDynFilename ( $aData['PRO_UID'] . PATH_SEP . $dynUid ); + + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + + if (isset ( $aData['DYN_TITLE'] ) ) + $this->setDynTitle ( $aData['DYN_TITLE'] ); + else + $this->setDynTitle ( 'Default Dynaform Title' ); + + if (isset ( $aData['DYN_DESCRIPTION'] ) ) + $this->setDynDescription ( $aData['DYN_DESCRIPTION'] ); + else + $this->setDynDescription ( 'Default Dynaform Description' ); + + $con->commit(); + $sXml = '<?xml version="1.0" encoding="UTF-8"?>'."\n"; + $sXml .= '<dynaForm type="' . $this->getDynType() . '" name="' . $this->getProUid() . '/' . $this->getDynUid() . '" width="500" enabletemplate="0" mode="edit">'."\n"; + $sXml .= '</dynaForm>'; + G::verifyPath(PATH_DYNAFORM . $this->getProUid(), true); + $oFile = fopen(PATH_DYNAFORM . $this->getProUid() . '/' . $this->getDynUid() . '.xml', 'w'); + fwrite($oFile, $sXml); + fclose($oFile); + return $this->getDynUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + + } + catch (Exception $e) { + $con->rollback(); + throw ($e); + } + } + + /** + * + * Creates a Dynaform based on a PMTable + * + * @name createFromPMTable + * @author gustavo cruz gustavo[at]colosa[dot]com + * @param array $aData Fields with : + * $aData['DYN_UID'] the dynaform id + * $aData['USR_UID'] the userid + * string $pmTableUid uid of the PMTable + * + */ + + function createFromPMTable ( $aData, $pmTableUid ) { + $this->create($aData); + $aData['DYN_UID']=$this->getDynUid(); + //krumo(BasePeer::getFieldnames('Content')); + $fields = array(); + //$oCriteria = new Criteria('workflow'); + $pmTable = AdditionalTablesPeer::retrieveByPK($pmTableUid); + $addTabName = $pmTable->getAddTabName(); + $keys = ''; + if (isset($aData['FIELDS'])){ + foreach ($aData['FIELDS'] as $iRow => $row) { + if ($keys!='') + $keys = $keys.'|'.$row['PRO_VARIABLE']; + else + $keys = $row['PRO_VARIABLE']; + } + } else { + $keys = ' '; + } + +// $addTabKeys = $pmTable->getAddTabDynavars(); +// $addTabKeys = unserialize($addTabKeys); +// $keys = ''; +// foreach ( $addTabKeys as $addTabKey ){ +// if (trim($addTabKey['CASE_VARIABLE'])!=''&&$keys!=''){ +// $keys = $keys.'|'.$addTabKey['CASE_VARIABLE']; +// } else { +// $keys = $addTabKey['CASE_VARIABLE']; +// } +// +// } + + $sql = 'DESC '.$addTabName; + $dbh = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + $sth = $dbh->createStatement(); + $res = $sth->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + + $file = $aData['PRO_UID'].'/'.$aData['DYN_UID']; + $dbc = new DBConnection( PATH_DYNAFORM . $file . '.xml' ,'','','','myxml' ); + $ses = new DBSession($dbc); + $fieldXML = new DynaFormField( $dbc ); + + $pmConnectionName = $addTabName.'_CONNECTION'; + + if ($aData['DYN_TYPE']=='xmlform'){ + $labels = array(); + $options = array(); + $attributes = array('XMLNODE_NAME_OLD' => '', 'XMLNODE_NAME' => $pmConnectionName, 'TYPE' => 'pmconnection', 'PMTABLE' => $pmTableUid, 'KEYS'=>$keys); + $fieldXML->Save($attributes, $labels, $options); + } + while ($res->next()){ + if(strtoupper($res->get('Null'))=='NO'){ + $required = '1'; + } else { + $required = '0'; + } + $fieldName = $res->get('Field'); + $defaultValue = $res->get('Default'); + $labels = array ( SYS_LANG => $fieldName ); + $options = array(); + $type = explode('(',$res->get('Type')); + + switch ($type[0]){ + case 'text': + $type = 'textarea'; + break; + case 'date': + $type = 'date'; + break; + default: + $type = 'text'; + break; + } + if ($aData['DYN_TYPE']=='xmlform'){ + $attributes = array( + 'XMLNODE_NAME_OLD' => '', + 'XMLNODE_NAME' => $fieldName, + 'TYPE' => $type, + 'PMCONNECTION' => $pmConnectionName, + 'PMFIELD' => $fieldName, + 'REQUIRED' => $required, + 'DEFAULTVALUE' => $defaultValue + ); + } else { + $attributes = array( + 'XMLNODE_NAME_OLD' => '', + 'XMLNODE_NAME' => $fieldName, + 'TYPE' => $type, + 'REQUIRED' => $required, + 'DEFAULTVALUE' => $defaultValue + ); + } + $fieldXML->Save($attributes, $labels, $options); + } + $labels = array ( SYS_LANG => 'Submit' ); + $attributes = array('XMLNODE_NAME_OLD' => '', 'XMLNODE_NAME' => 'SUBMIT', 'TYPE' => 'submit'); + $fieldXML->Save($attributes, $labels, $options); + } + /** + * Load the Dynaform row specified in [dyn_id] column value. + * + * @param string $ProUid the uid of the Prolication + * @return array $Fields the fields + */ + + function Load ( $ProUid ) { + $con = Propel::getConnection(DynaformPeer::DATABASE_NAME); + try { + $oPro = DynaformPeer::retrieveByPk( $ProUid ); + if ( get_class ($oPro) == 'Dynaform' ) { + $aFields = $oPro->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + $aFields['DYN_TITLE'] = $oPro->getDynTitle(); + $aFields['DYN_DESCRIPTION'] = $oPro->getDynDescription(); + $this->setDynTitle ( $oPro->getDynTitle() ); + $this->setDynDescription ( $oPro->getDynDescription() ); + return $aFields; + } + else { + throw(new Exception( "The row '$ProUid' in table Dynaform doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Update the Prolication row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( DynaformPeer::DATABASE_NAME ); + try { + $con->begin(); + $oPro = DynaformPeer::retrieveByPK( $aData['DYN_UID'] ); + if ( get_class ($oPro) == 'Dynaform' ) { + $oPro->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oPro->validate()) { + if ( isset ( $aData['DYN_TITLE'] ) ) + $oPro->setDynTitle( $aData['DYN_TITLE'] ); + if ( isset ( $aData['DYN_DESCRIPTION'] ) ) + $oPro->setDynDescription( $aData['DYN_DESCRIPTION'] ); + $res = $oPro->save(); + $con->commit(); + return $res; + } + else { + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "The row '" . $aData['DYN_UID'] . "' in table Dynaform doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Remove the Prolication document registry + * @param array $aData or string $ProUid + * @return string + **/ + public function remove($ProUid) + { + if ( is_array ( $ProUid ) ) { + $ProUid = ( isset ( $ProUid['DYN_UID'] ) ? $ProUid['DYN_UID'] : '' ); + } + try { + $oPro = DynaformPeer::retrieveByPK( $ProUid ); + if (!is_null($oPro)) + { + Content::removeContent('DYN_TITLE', '', $oPro->getDynUid()); + Content::removeContent('DYN_DESCRIPTION', '', $oPro->getDynUid()); + $iResult = $oPro->delete(); + if (file_exists(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '.xml')) { + unlink(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '.xml'); + } + if (file_exists(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '_tmp0.xml')) { + unlink(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '_tmp0.xml'); + } + if (file_exists(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '.html')) { + unlink(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '.html'); + } + if (file_exists(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '_tmp0.html')) { + unlink(PATH_DYNAFORM . $oPro->getProUid() . PATH_SEP . $oPro->getDynUid() . '_tmp0.html'); + } + return $iResult; + } + else { + throw(new Exception( "The row '$ProUid' in table Dynaform doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function exists($DynUid) + { + $oPro = DynaformPeer::retrieveByPk( $DynUid ); + return ( get_class ($oPro) == 'Dynaform' ); + } + + /** + * verify if Dynaform row specified in [DynUid] exists. + * + * @param string $sProUid the uid of the Prolication + */ + + function dynaformExists ( $DynUid ) { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + try { + $oDyn = DynaformPeer::retrieveByPk( $DynUid ); + if ( get_class ($oDyn) == 'Dynaform' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function getDynaformContent( $dynaformUid) { + $content = ''; + $fields = $this->Load ( $dynaformUid); + $filename = PATH_DYNAFORM . $fields['PRO_UID'] . PATH_SEP . $fields['DYN_UID'] . '.xml'; + if (file_exists( $filename )) { + $content = file_get_contents ( $filename ); + } + + return $content; + } + + function getDynaformFields( $dynaformUid) { + $content = ''; + $fields = $this->Load ( $dynaformUid); + $filename = PATH_DYNAFORM . $fields['PRO_UID'] . PATH_SEP . $fields['DYN_UID'] . '.xml'; + if (file_exists( $filename )) { + $content = file_get_contents ( $filename ); + } + + $G_FORM = new xmlform ( $fields['DYN_FILENAME'] , PATH_DYNAFORM ); + $G_FORM->parseFile( $filename , SYS_LANG, true ); + + return $G_FORM->fields; + } + +} // Dynaform diff --git a/workflow/engine/classes/model/DynaformPeer.php b/workflow/engine/classes/model/DynaformPeer.php new file mode 100644 index 000000000..9d5370305 --- /dev/null +++ b/workflow/engine/classes/model/DynaformPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * DynaformPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseDynaformPeer.php'; + + // include object class + include_once 'classes/model/Dynaform.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'DYNAFORM' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class DynaformPeer extends BaseDynaformPeer { + +} // DynaformPeer diff --git a/workflow/engine/classes/model/Event.php b/workflow/engine/classes/model/Event.php new file mode 100644 index 000000000..a870f4537 --- /dev/null +++ b/workflow/engine/classes/model/Event.php @@ -0,0 +1,743 @@ +<?php + +require_once 'classes/model/Content.php'; +require_once 'classes/model/om/BaseEvent.php'; + + +/** + * Skeleton subclass for representing a row from the 'EVENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ + +require_once 'classes/model/AppDelegation.php'; +require_once 'classes/model/AppEvent.php'; +require_once 'classes/model/Triggers.php'; + +class Event extends BaseEvent { + + /** + * This value goes in the content table + * @var string + */ + protected $evn_description = ''; + + /** + * Get the evn_description column value. + * @return string + */ + public function getEvnDescription() { + if ( $this->getEvnUid() == "" ) { + throw ( new Exception( "Error in getEvnDescription, the getEvnUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG' ) ? SYS_LANG : 'en'; + $this->evn_description = Content::load ( 'EVN_DESCRIPTION', '', $this->getEvnUid(), $lang ); + return $this->evn_description; + } + + /** + * Set the evn_description column value. + * + * @param string $v new value + * @return void + */ + public function setEvnDescription($v) + { + if ( $this->getEvnUid() == "" ) { + throw ( new Exception( "Error in setEvnDescription, the setEvnUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->evn_description !== $v || $v==="") { + $this->evn_description = $v; + $res = Content::addContent( 'EVN_DESCRIPTION', '', $this->getEvnUid(), $lang, $this->evn_description ); + return $res; + } + return 0; + } + + public function load($sUID) { + try { + $oEvent = EventPeer::retrieveByPK($sUID); + if (!is_null($oEvent)) { + $aFields = $oEvent->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + $this->setEvnDescription($aFields['EVN_DESCRIPTION'] = $this->getEvnDescription()); + //$aFields['EVN_CONDITIONS'] = unserialize($aFields['EVN_CONDITIONS']); + $aFields['EVN_ACTION_PARAMETERS'] = unserialize($aFields['EVN_ACTION_PARAMETERS']); + + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function create($aData) { + if (!isset($aData['EVN_UID']) || $aData['EVN_UID'] == '' ) { + $aData['EVN_UID'] = G::generateUniqueID(); + } + + $oConnection = Propel::getConnection(EventPeer::DATABASE_NAME); + try { + $oEvent = new Event(); + $oEvent->setEvnUid( $aData['EVN_UID'] ); + $oEvent->setProUid( $aData['PRO_UID'] ); + $oEvent->setEvnRelatedTo( $aData['EVN_RELATED_TO'] ); + if ( $aData['EVN_RELATED_TO'] == 'SINGLE' ) { + $oEvent->setTasUid( $aData['TAS_UID'] ); + $oEvent->setEvnTasUidTo( ''); + $oEvent->setEvnTasUidFrom( '' ); + } + else { + $oEvent->setTasUid(''); + $oEvent->setEvnTasUidTo( $aData['EVN_TAS_UID_TO'] ); + $oEvent->setEvnTasUidFrom( $aData['EVN_TAS_UID_FROM'] ); + } + $oEvent->setEvnTasEstimatedDuration( $aData['EVN_TAS_ESTIMATED_DURATION'] ); + $oEvent->setEvnWhenOccurs( $aData['EVN_WHEN_OCCURS'] ); + $oEvent->setEvnStatus( $aData['EVN_STATUS'] ); + $oEvent->setEvnWhen( $aData['EVN_WHEN'] ); + $oEvent->setEvnAction( $aData['EVN_ACTION'] ); + $oEvent->setEvnMaxAttempts( 3 ); + $oEvent->setEvnConditions( $aData['EVN_CONDITIONS'] ); + + //start the transaction + $oConnection->begin(); + + $oTrigger = new Triggers(); + if( trim($aData['TRI_UID']) === "" || ( ! $oTrigger->TriggerExists ( $aData['TRI_UID'] ))){ + //create an empty trigger + + $aTrigger = array(); + $aTrigger['PRO_UID'] = $aData['PRO_UID']; + $aTrigger['TRI_TITLE'] = 'For event: ' . $aData['EVN_DESCRIPTION']; + $aTrigger['TRI_DESCRIPTION'] = 'Autogenerated ' . $aTrigger['TRI_TITLE']; + $aTrigger['TRI_WEBBOT'] = '// ' . $aTrigger['TRI_DESCRIPTION'];; + $oTrigger->create($aTrigger); + + } else { + $oTrigger = TriggersPeer::retrieveByPk($aData['TRI_UID']); + } + + $oEvent->setTriUid( $oTrigger->getTriUid() ); + + $parameters = new StdClass(); + $parameters->hash = md5 ($oTrigger->getTriWebbot()); + + if( isset( $aData['EVN_ACTION_PARAMETERS']->SUBJECT ) ) { + $parameters->SUBJECT = $aData['EVN_ACTION_PARAMETERS']->SUBJECT; + $parameters->TO = $aData['EVN_ACTION_PARAMETERS']->TO; + $parameters->CC = $aData['EVN_ACTION_PARAMETERS']->CC; + $parameters->BCC = $aData['EVN_ACTION_PARAMETERS']->BCC; + $parameters->TEMPLATE = $aData['EVN_ACTION_PARAMETERS']->TEMPLATE; + } + + $oEvent->setEvnActionParameters( serialize ($parameters ) ); + + if ($oEvent->validate()) { + $iResult = $oEvent->save(); + $oEvent->setEvnDescription($aData['EVN_DESCRIPTION']); + $oConnection->commit(); + return $aData['EVN_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oEvent->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The row Event cannot be created!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function update($aData) { + $oConnection = Propel::getConnection(EventPeer::DATABASE_NAME); + try { + $oEvent = EventPeer::retrieveByPK($aData['EVN_UID']); + if (!is_null($oEvent)) { + //$oEvent->setProUid( $aData['PRO_UID'] ); + $oEvent->setEvnRelatedTo( $aData['EVN_RELATED_TO'] ); + if ( $aData['EVN_RELATED_TO'] == 'SINGLE' ) { + $oEvent->setTasUid( $aData['TAS_UID'] ); + $oEvent->setEvnTasUidTo( ''); + $oEvent->setEvnTasUidFrom( '' ); + } + else { + $oEvent->setTasUid( '' ); + $oEvent->setEvnTasUidTo( $aData['EVN_TAS_UID_TO'] ); + $oEvent->setEvnTasUidFrom( $aData['EVN_TAS_UID_FROM'] ); + } + $oEvent->setEvnTasEstimatedDuration( $aData['EVN_TAS_ESTIMATED_DURATION'] ); + $oEvent->setEvnWhenOccurs( $aData['EVN_WHEN_OCCURS'] ); + $oEvent->setEvnStatus( $aData['EVN_STATUS'] ); + $oEvent->setEvnWhen( $aData['EVN_WHEN'] ); + + $oEvent->setTriUid( $aData['TRI_UID'] ); + $oEvent->setEvnConditions( $aData['EVN_CONDITIONS'] ); + + if ( isset ($aData['EVN_ACTION'] ) ) $oEvent->setEvnAction( $aData['EVN_ACTION'] ); + //if ( isset ($aData['ENV_MAX_ATTEMPTS'] )) $oEvent->setEvnMaxAttempts( 3 ); + + if (isset($aData['EVN_ACTION_PARAMETERS'])) { + + $oTP = new TemplatePower(PATH_TPL . 'events' . PATH_SEP . 'sendMessage.tpl'); + $oTP->prepare(); + + $oTP->assign('from', 'info@processmaker.com'); + $oTP->assign('subject', addslashes($aData['EVN_ACTION_PARAMETERS']['SUBJECT'])); + $oTP->assign('template', $aData['EVN_ACTION_PARAMETERS']['TEMPLATE']); + $oTP->assign('timestamp', date("l jS \of F Y h:i:s A")); + + $recipientTO = implode(',', $aData['EVN_ACTION_PARAMETERS']['TO']); + $recipientCC = implode(',', $aData['EVN_ACTION_PARAMETERS']['CC']); + $recipientBCC = implode(',', $aData['EVN_ACTION_PARAMETERS']['BCC']); + + $oTP->assign('TO', addslashes($recipientTO)); + $oTP->assign('CC', addslashes($recipientCC)); + $oTP->assign('BCC', addslashes($recipientBCC)); + + $sTrigger = $oTP->getOutputContent(); + + $oTrigger = new Triggers(); + $aTrigger = $oTrigger->load($oEvent->getTriUid()); + $aTrigger['TRI_WEBBOT'] = $sTrigger; + $oTrigger->update($aTrigger); + $oParameters = new StdClass(); + $oParameters->hash = md5($sTrigger); + $oParameters->SUBJECT = $aData['EVN_ACTION_PARAMETERS']['SUBJECT']; + $oParameters->TO = $aData['EVN_ACTION_PARAMETERS']['TO']; + $oParameters->CC = $aData['EVN_ACTION_PARAMETERS']['CC']; + $oParameters->BCC = $aData['EVN_ACTION_PARAMETERS']['BCC']; + $oParameters->TEMPLATE = $aData['EVN_ACTION_PARAMETERS']['TEMPLATE']; + + //$oParameters->TRI_UID = $sTrigger->getTriUid(); + + $oEvent->setEvnActionParameters(serialize($oParameters)); + } + + if ($oEvent->validate()) { + //start the transaction + $oConnection->begin(); + if (array_key_exists('EVN_DESCRIPTION', $aData)) $oEvent->setEvnDescription($aData['EVN_DESCRIPTION']); + $iResult = $oEvent->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oEvent->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function remove($sUID) { + $oConnection = Propel::getConnection(EventPeer::DATABASE_NAME); + try { + $oEvent = EventPeer::retrieveByPK($sUID); + if (!is_null($oEvent)) { + /* with the new feature for events, a event can to relate a existing trigger + or more of one events can be reusing the same trigger + so, in this point we should't to delete the trigger + + $oConnection->begin(); + $oTrigger = new Triggers(); + $oAppEvent = new AppEvent(); + + $oCriteria = new Criteria('workflow'); + $oCriteria->clearSelectColumns(); + $oCriteria->addSelectColumn( AppEventPeer::EVN_UID ); + $oCriteria->addSelectColumn( EventPeer::TRI_UID ); + $oCriteria->addSelectColumn( AppEventPeer::APP_UID ); + $oCriteria->addSelectColumn( AppEventPeer::DEL_INDEX ); + $oCriteria->add(AppEventPeer::EVN_UID, $sUID ); + $oCriteria->addJoin(EventPeer::EVN_UID, AppEventPeer::EVN_UID, Criteria::JOIN); + $oDataset = AppEventPeer::doSelectRs($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($row = $oDataset->getRow()) { + $oTrigger->remove($row['TRI_UID']); + $oAppEvent->remove( $row['APP_UID'], $row['DEL_INDEX'], $sUID ); + $oDataset->next(); + }*/ + Content::removeContent('EVN_DESCRIPTION', '', $oEvent->getEvnUid()); + + $iResult = $oEvent->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function calculateEventsExecutionDate() { + $line1 = ''; + $line2 = ''; + $line1 = $this->calculateExecutionDateSingle(); + //$line2 = $this->calculateExecutionDateMultiple(); + return $line1 . "<br>\n" . $line2; + } + + function calculateExecutionDateSingle() { + try { + $rowsCreated = 0; + $rowsRejected = 0; + G::LoadClass('dates'); + $oDates = new dates(); + + //SELECT + // EVENT.PRO_UID, + // EVENT.TAS_UID , + // EVENT.EVN_TAS_ESTIMATED_DURATION , + // EVENT.EVN_WHEN, + // APP_DELEGATION.APP_UID , + // APP_DELEGATION.DEL_INDEX , + // APP_DELEGATION.TAS_UID , + // APP_DELEGATION.DEL_DELEGATE_DATE , + // APP_DELEGATION.DEL_INIT_DATE , + // APP_DELEGATION.DEL_TASK_DUE_DATE , + // APP_DELEGATION.DEL_FINISH_DATE + //from APP_DELEGATION + // JOIN EVENT ON ( APP_DELEGATION.TAS_UID = EVENT.TAS_UID AND APP_DELEGATION.DEL_FINISH_DATE IS NULL ) + // LEFT JOIN APP_EVENT ON ( APP_EVENT.APP_UID = APP_DELEGATION.APP_UID AND APP_EVENT.DEL_INDEX = APP_DELEGATION.DEL_INDEX ) + // WHERE + // APP_EVENT.APP_UID IS NULL + // and EVN_STATUS = 'ACTIVE' + // AND EVN_RELATED_TO = 'SINGLE' + // and DEL_FINISH_DATE IS NULL + //-- and APP_DELEGATION.DEL_DELEGATE_DATE > "2009-01-01 12:00:00" + //ORDER BY APP_DELEGATION.DEL_DELEGATE_DATE + + //get info about the Event and the APP_DELEGATION to process + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(EventPeer::EVN_UID); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::TAS_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_ESTIMATED_DURATION); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + $oCriteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + $oCriteria->addSelectColumn(EventPeer::EVN_MAX_ATTEMPTS); + $oCriteria->addSelectColumn(AppDelegationPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppDelegationPeer::TAS_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::TAS_UID, EventPeer::TAS_UID); + //$aConditions[] = array(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::IS_NULL ); //is null is supported by addJoinMC by the way. + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::APP_UID, AppEventPeer::APP_UID); + $aConditions[] = array(AppDelegationPeer::DEL_INDEX, AppEventPeer::DEL_INDEX); + $aConditions[] = array(EventPeer::EVN_UID, AppEventPeer::EVN_UID ); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $oCriteria->add(AppEventPeer::APP_UID, null, Criteria::ISNULL ); + $oCriteria->add(EventPeer::EVN_STATUS, 'ACTIVE' ); + $oCriteria->add(EventPeer::EVN_RELATED_TO, 'SINGLE' ); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL ); +// $oCriteria->add(AppDelegationPeer::DEL_DELEGATE_DATE, date('Y-m-d') , Criteria::GREATER_THAN ); + $oDataset = EventPeer::doSelectRs($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while($oDataset->next()) $aRows[]= $oDataset->getRow(); + + g::pr($aRows); + die; + + $oDataset->next(); + + while ($aData = $oDataset->getRow()) { + $estimatedDuration = (float)$aData['EVN_TAS_ESTIMATED_DURATION']; + $when = (float)$aData['EVN_WHEN']; + $whenOccurs = $aData['EVN_WHEN_OCCURS']; + + if ( $whenOccurs == 'AFTER_TIME' ) { + //for multiple $sDueDate = date('Y-m-d H:i:s', $oDates->calculateDate($aData['DEL_DELEGATE_DATE'], $estimatedDuration, 'days', 1)); + $sDueDate = $aData['DEL_TASK_DUE_DATE']; + $calculatedDueDateA=$oDates->calculateDate( $sDueDate, $when, 'days', 1); + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + $validStartDate = ( $sActionDate >= $aData['DEL_DELEGATE_DATE'] ); + } + else { + $sDueDate = $aData['DEL_DELEGATE_DATE']; + $calculatedDueDateA=$oDates->calculateDate( $sDueDate, $when, 'days', 1); + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + $validStartDate = ( $sActionDate >= $aData['DEL_DELEGATE_DATE'] ); + } + $aData['APP_EVN_ACTION_DATE'] = $sActionDate; + $aData['APP_EVN_ATTEMPTS'] = $aData['EVN_MAX_ATTEMPTS']; + + if ( $validStartDate ) { + $rowsCreated++ ; + $oAppEvent = new AppEvent(); + $oAppEvent->create( $aData ); + } + else { + $rowsRejected++; + $aData['APP_EVN_STATUS'] = 'INVALID'; + $oAppEvent = new AppEvent(); + $oAppEvent->create( $aData ); + } + $oDataset->next(); + } + return "Created $rowsCreated SINGLE rows in APP_EVENT and rejected $rowsRejected rows "; + } + catch (Exception $oError) { + throw new Exception ( $oError->getMessage() ); + } + } + + + function calculateExecutionDateMultiple() { + try { + $rowsCreated = 0; + $rowsRejected = 0; + G::LoadClass('dates'); + $oDates = new dates(); + // SELECT TASK2.* , + // EVENT.EVN_UID, EVENT.PRO_UID, EVENT.EVN_TAS_UID_FROM, + // EVENT.EVN_TAS_ESTIMATED_DURATION, EVENT.EVN_WHEN, + // EVENT.EVN_WHEN_OCCURS, EVENT.EVN_RELATED_TO, APP_DELEGATION.APP_UID, APP_DELEGATION.DEL_INDEX, APP_DELEGATION.TAS_UID, + // APP_DELEGATION.DEL_DELEGATE_DATE, APP_DELEGATION.DEL_INIT_DATE, APP_DELEGATION.DEL_TASK_DUE_DATE, + // APP_DELEGATION.DEL_FINISH_DATE + // FROM + // APP_DELEGATION + // LEFT JOIN EVENT ON (APP_DELEGATION.TAS_UID=EVENT.EVN_TAS_UID_FROM) + // LEFT JOIN APP_EVENT ON (APP_DELEGATION.APP_UID=APP_EVENT.APP_UID AND APP_DELEGATION.DEL_INDEX=APP_EVENT.DEL_INDEX) + // LEFT JOIN APP_DELEGATION AS TASK2 ON (TASK2.TAS_UID = EVENT.EVN_TAS_UID_TO AND TASK2.APP_UID = APP_DELEGATION.APP_UID ) + // + // WHERE + // APP_EVENT.APP_UID IS NULL + // AND EVENT.EVN_STATUS='ACTIVE' + // AND EVENT.EVN_RELATED_TO='MULTIPLE' + // AND TASK2.DEL_FINISH_DATE IS NULL + //get info about the Event and the APP_DELEGATION to process + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(EventPeer::EVN_UID); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_UID_FROM ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_ESTIMATED_DURATION); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + $oCriteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + $oCriteria->addSelectColumn(AppDelegationPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppDelegationPeer::TAS_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + + + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::TAS_UID, EventPeer::EVN_TAS_UID_FROM); + //$aConditions[] = array(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::IS_NULL ); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::APP_UID, AppEventPeer::APP_UID); + $aConditions[] = array(AppDelegationPeer::DEL_INDEX, AppEventPeer::DEL_INDEX); + $aConditions[] = array(EventPeer::EVN_UID, AppEventPeer::EVN_UID ); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $oCriteria->addAlias('DEL2', 'APP_DELEGATION'); + $aConditions = array(); + $aConditions[] = array( AppDelegationPeer::APP_UID, 'DEL2.APP_UID' ); + $aConditions[] = array( EventPeer::EVN_TAS_UID_TO, 'DEL2.TAS_UID' ); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + + $oCriteria->add(AppEventPeer::APP_UID, null, Criteria::ISNULL ); + $oCriteria->add(EventPeer::EVN_STATUS, 'ACTIVE' ); + $oCriteria->add(EventPeer::EVN_RELATED_TO, 'MULTIPLE' ); + $oCriteria->add('DEL2.DEL_FINISH_DATE', null, Criteria::ISNULL ); +// $oCriteria->add(AppDelegationPeer::DEL_DELEGATE_DATE, date('Y-m-d') , Criteria::GREATER_THAN ); + $oDataset = EventPeer::doSelectRs($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while ($aData = $oDataset->getRow()) { + $estimatedDuration = (float)$aData['EVN_TAS_ESTIMATED_DURATION']; + $when = (float)$aData['EVN_WHEN']; + $whenOccurs = $aData['EVN_WHEN_OCCURS']; + + if ( $whenOccurs == 'AFTER_TIME' ) { + //for multiple $sDueDate = date('Y-m-d H:i:s', $oDates->calculateDate($aData['DEL_DELEGATE_DATE'], $estimatedDuration, 'days', 1)); + $sDueDate = $aData['DEL_TASK_DUE_DATE']; + $calculatedDueDateA=$oDates->calculateDate( $sDueDate, $when, 'days', 1); + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + $validStartDate = ( $sActionDate >= $aData['DEL_DELEGATE_DATE'] ); + } + else { + $sDueDate = $aData['DEL_DELEGATE_DATE']; + $calculatedDueDateA=$oDates->calculateDate( $sDueDate, $when, 'days', 1); + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + $validStartDate = ( $sActionDate >= $aData['DEL_DELEGATE_DATE'] ); + } + $aData['APP_EVN_ACTION_DATE'] = $sActionDate; + + if ( $validStartDate ) { + $rowsCreated++ ; + $oAppEvent = new AppEvent(); + $oAppEvent->create( $aData ); + } + else { + $rowsRejected++; + $aData['APP_EVN_STATUS'] = 'INVALID'; + $oAppEvent = new AppEvent(); + $oAppEvent->create( $aData ); + } + $oDataset->next(); + } + return "Created $rowsCreated MULTIPLE rows in APP_EVENT and rejected $rowsRejected rows "; + } + catch (Exception $oError) { + throw new Exception ( $oError->getMessage() ); + } + } + + + function closeAppEvents($PRO_UID, $APP_UID, $DEL_INDEX, $TAS_UID){ + + $aAppEvents = $this->getAppEvents($APP_UID, $DEL_INDEX); + if($aAppEvents){ + foreach ( $aAppEvents as $aRow ) { + if($aRow['EVN_RELATED_TO'] == 'SINGLE' || ($aRow['EVN_RELATED_TO'] == $TAS_UID) ){ + $oAppEvent = AppEventPeer::retrieveByPK($aRow['APP_UID'], $aRow['DEL_INDEX'], $aRow['EVN_UID']); + $oAppEvent->setAppEvnLastExecutionDate(date('Y-m-d H:i:s')); + $oAppEvent->setAppEvnStatus('CLOSE'); + $oAppEvent->save(); + } + } + } + + } + + function createAppEvents($PRO_UID, $APP_UID, $DEL_INDEX, $TAS_UID){ + $aRows = Array(); + $aEventsRows = $this->getBy($PRO_UID, Array('TAS_UID'=>$TAS_UID)); + if( $aEventsRows !== false ){ + $aRows = array_merge($aRows, $aEventsRows); + } + + $aEventsRows = $this->getBy($PRO_UID, Array('EVN_TAS_UID_FROM'=>$TAS_UID)); + if( $aEventsRows !== false ){ + $aRows = array_merge($aRows, $aEventsRows); + } + + foreach($aRows as $aData){ + + // if the events has a condition + if( trim($aData['EVN_CONDITIONS']) != '' ) { + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($APP_UID); + + $Fields = $aFields['APP_DATA']; + $conditionContents = trim($aData['EVN_CONDITIONS']); + + //$sContent = G::unhtmlentities($sContent); + $iAux = 0; + $iOcurrences = preg_match_all('/\@(?:([\>])([a-zA-Z\_]\w*)|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+)?/', $conditionContents, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + + if ($iOcurrences) { + for($i = 0; $i < $iOcurrences; $i++) { + preg_match_all('/@>' . $aMatch[2][$i][0] . '([\w\W]*)' . '@<' . $aMatch[2][$i][0] . '/', $conditionContents, $aMatch2, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $sGridName = $aMatch[2][$i][0]; + $sStringToRepeat = $aMatch2[1][0][0]; + if (isset($Fields[$sGridName])) { + if (is_array($Fields[$sGridName])) { + $sAux = ''; + foreach ($Fields[$sGridName] as $aRow) { + $sAux .= G::replaceDataField($sStringToRepeat, $aRow); + } + } + } + $conditionContents = str_replace('@>' . $sGridName . $sStringToRepeat . '@<' . $sGridName, $sAux, $conditionContents); + } + } + + $sCondition = G::replaceDataField( $conditionContents, $Fields); + + $evalConditionResult = false; + + $sCond = 'try{ $evalConditionResult=('.$sCondition.')? true: false; } catch(Exception $e){$evalConditionResult=false;}'; + @eval($sCond); + + if( !$evalConditionResult ){ + continue; + } + } + + $appEventData['APP_UID'] = $APP_UID; + $appEventData['DEL_INDEX'] = $DEL_INDEX; + $appEventData['EVN_UID'] = $aData['EVN_UID']; + $appEventData['APP_EVN_ACTION_DATE'] = $this->toCalculateTime($aData); + $appEventData['APP_EVN_ATTEMPTS'] = 3; + $appEventData['APP_EVN_LAST_EXECUTION_DATE'] = null; + $appEventData['APP_EVN_STATUS'] = 'OPEN'; + + $oAppEvent = new AppEvent(); + $oAppEvent->create( $appEventData ); + + } + } + + function getBy($PRO_UID, $aFilers){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(EventPeer::EVN_UID); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_STATUS); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + $oCriteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + $oCriteria->addSelectColumn(EventPeer::TAS_UID ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_UID_FROM ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_UID_TO ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_ESTIMATED_DURATION); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN); + $oCriteria->addSelectColumn(EventPeer::EVN_MAX_ATTEMPTS); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION); + $oCriteria->addSelectColumn(EventPeer::EVN_CONDITIONS); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION_PARAMETERS); + $oCriteria->addSelectColumn(EventPeer::TRI_UID); + + $oCriteria->add(EventPeer::EVN_STATUS, 'ACTIVE' ); + foreach($aFilers as $sFilter=>$sValue){ + switch($sFilter){ + case 'TAS_UID': + $oCriteria->add(EventPeer::TAS_UID, $sValue, Criteria::EQUAL); + break; + case 'EVN_TAS_UID_FROM': + $oCriteria->add(EventPeer::EVN_TAS_UID_FROM, $sValue, Criteria::EQUAL); + break; + case 'EVN_TAS_UID_TO': + $oCriteria->add(EventPeer::EVN_TAS_UID_TO, $sValue, Criteria::EQUAL); + break; + } + } + + $oDataset = EventPeer::doSelectRs($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while($oDataset->next()) $aRows[]= $oDataset->getRow(); + + return (count($aRows) > 0)? $aRows: false; + } + + function getAppEvents($APP_UID, $DEL_INDEX){ + //for single task event + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppEventPeer::APP_UID); + $oCriteria->addSelectColumn(AppEventPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppEventPeer::EVN_UID); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ACTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_ATTEMPTS ); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE); + $oCriteria->addSelectColumn(AppEventPeer::APP_EVN_STATUS); + $oCriteria->addSelectColumn(EventPeer::EVN_UID); + $oCriteria->addSelectColumn(EventPeer::PRO_UID); + $oCriteria->addSelectColumn(EventPeer::EVN_STATUS); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + $oCriteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + $oCriteria->addSelectColumn(EventPeer::TAS_UID ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_UID_FROM ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_UID_TO ); + $oCriteria->addSelectColumn(EventPeer::EVN_TAS_ESTIMATED_DURATION); + $oCriteria->addSelectColumn(EventPeer::EVN_WHEN); + $oCriteria->addSelectColumn(EventPeer::EVN_MAX_ATTEMPTS); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION); + $oCriteria->addSelectColumn(EventPeer::EVN_CONDITIONS); + $oCriteria->addSelectColumn(EventPeer::EVN_ACTION_PARAMETERS); + $oCriteria->addSelectColumn(EventPeer::TRI_UID); + + $oCriteria->addJoin(AppEventPeer::EVN_UID, EventPeer::EVN_UID); + + $oCriteria->add(AppEventPeer::APP_UID, $APP_UID); + $oCriteria->add(AppEventPeer::DEL_INDEX, $DEL_INDEX); + $oCriteria->add(AppEventPeer::APP_EVN_STATUS, 'OPEN'); + + $oDataset = AppEventPeer::doSelectRs($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while($oDataset->next()) $aRows[]= $oDataset->getRow(); + + return (count($aRows) > 0)? $aRows: false; + } + + function toCalculateTime($aData, $iDate=null){ + G::LoadClass('dates'); + $oDates = new dates(); + + $iDate = isset($iDate)? $iDate: date('Y-m-d H:i:s'); + + $estimatedDuration = $aData['EVN_TAS_ESTIMATED_DURATION']; //task duration + $when = $aData['EVN_WHEN']; //how many days + $whenOccurs = $aData['EVN_WHEN_OCCURS']; //time on action (AFTER_TIME/TASK_STARTED) + + if ( $whenOccurs == 'TASK_STARTED' ) { + + $calculatedDueDateA=$oDates->calculateDate( $iDate, $when, 'days', 1); + + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + } else { + $calculatedDueDateA=$oDates->calculateDate( $iDate, $estimatedDuration+$when, 'days', 1); + $sActionDate = date('Y-m-d H:i:s', $calculatedDueDateA['DUE_DATE_SECONDS']); + } + + return $sActionDate; + } + + function Exists ( $sUid ) { + try { + $oObj = EventPeer::retrieveByPk($sUid); + return (get_class($oObj) == 'Event'); + } + catch (Exception $oError) { + throw($oError); + } + } +} // Event +?> \ No newline at end of file diff --git a/workflow/engine/classes/model/EventPeer.php b/workflow/engine/classes/model/EventPeer.php new file mode 100644 index 000000000..72768bac5 --- /dev/null +++ b/workflow/engine/classes/model/EventPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseEventPeer.php'; + + // include object class + include_once 'classes/model/Event.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'EVENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class EventPeer extends BaseEventPeer { + +} // EventPeer diff --git a/workflow/engine/classes/model/FieldCondition.php b/workflow/engine/classes/model/FieldCondition.php new file mode 100644 index 000000000..fa9642581 --- /dev/null +++ b/workflow/engine/classes/model/FieldCondition.php @@ -0,0 +1,345 @@ +<?php + +require_once 'classes/model/om/BaseFieldCondition.php'; +require_once 'classes/model/Dynaform.php'; + + +/** + * Skeleton subclass for representing a row from the 'FIELD_CONDITION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class FieldCondition extends BaseFieldCondition { + + var $oDynaformHandler; + /** + * Quick get all records into a criteria object + * + * @author Erik A. Ortiz <erik@colosa.com, aortiz.erik@gmail.com> + */ + public function get( $UID ) { + + $obj = FieldConditionPeer::retrieveByPk($UID); + if( !isset($obj) ) { + throw new Exception("the record with UID: $UID doesn't exits!"); + } + //TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + return $obj->toArray(BasePeer::TYPE_FIELDNAME); + } + + /** + * Quick get all records into a criteria object + * + * @author Erik A. Ortiz <erik@colosa.com, aortiz.erik@gmail.com> + */ + public function getAllCriteriaByDynUid( $DYN_UID, $filter='all' ) { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_UID); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_FUNCTION); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_FIELDS); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_CONDITION); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_EVENTS); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_EVENT_OWNERS); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_STATUS); + $oCriteria->addSelectColumn(FieldConditionPeer::FCD_DYN_UID); + + $oCriteria->add(FieldConditionPeer::FCD_DYN_UID, $DYN_UID); + switch( $filter ) { + case 'active': + $oCriteria->add(FieldConditionPeer::FCD_STATUS, '1', Criteria::EQUAL); + break; + } + + return $oCriteria; + } + + /** + * Quick get all records into a associative array + * + * @author Erik A. Ortiz <erik@colosa.com, aortiz.erik@gmail.com> + */ + public function getAllByDynUid( $DYN_UID, $filter='all' ) { + $aRows = Array(); + + $oCriteria = $this->getAllCriteriaByDynUid($DYN_UID, $filter); + + $oDataset = FieldConditionPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while( $aRow = $oDataset->getRow() ) { + $aRows[] = $aRow; + $oDataset->next(); + } + + return $aRows; + } + + /** + * Quick save a record + * + * @author Erik A. Ortiz <erik@colosa.com, aortiz.erik@gmail.com> + */ + public function quickSave($aData) { + $con = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + try { + if( isset($aData['FCD_UID']) && trim($aData['FCD_UID']) != '' ) { + $obj = FieldConditionPeer::retrieveByPk( $aData['FCD_UID'] ); + if( get_class($obj) != 'FieldCondition') { + $obj = new FieldCondition(); + } + } else { + if ( isset ( $aData['FCD_UID'] ) && $aData['FCD_UID']== '' ) + unset ( $aData['FCD_UID'] ); + if ( !isset ( $aData['FCD_UID'] ) ) + $aData['FCD_UID'] = G::generateUniqueID(); + $obj = new FieldCondition(); + } + + $obj->fromArray($aData, BasePeer::TYPE_FIELDNAME); + + if ($obj->validate()) { + $result = $obj->save(); + $con->commit(); + return $result; + } else { + $e = new Exception("Failed Validation in class " . get_class($this) . "."); + $e->aValidationFailures = $obj->getValidationFailures(); + throw ($e); + } + } catch (exception $e) { + $con->rollback(); + throw ($e); + } + } + + function getConditionScript($DYN_UID) { + require_once 'classes/model/Dynaform.php'; + G::LoadSystem('dynaformhandler'); + + $oDynaform = DynaformPeer::retrieveByPk($DYN_UID); + $PRO_UID = $oDynaform->getProUid(); + + $this->oDynaformHandler = new dynaFormHandler(PATH_DYNAFORM . "$PRO_UID/$DYN_UID" . '.xml'); + $aDynaformFields = $this->oDynaformHandler->getFieldNames(); + for ( $i = 0; $i < count($aDynaformFields); $i++ ) { + $aDynaformFields[$i] = "'$aDynaformFields[$i]'"; + } + + $sDynaformFieldsAsStrings = implode(',', $aDynaformFields); + + $aRows = $this->getAllByDynUid($DYN_UID, 'active'); + $sCode = ''; + + if( sizeof($aRows) != 0 ) { + + foreach ( $aRows as $aRow ) { + $hashCond = md5($aRow['FCD_UID']); + $sCondition = $this->parseCondition($aRow['FCD_CONDITION']); + $sCondition = addslashes($sCondition); + + $sCode .= "function __condition__$hashCond() { "; + $sCode .= "if( eval(\"{$sCondition}\") ) { "; + + $aFields = explode(',', $aRow['FCD_FIELDS']); + + switch( $aRow['FCD_FUNCTION'] ) { + case 'show': + foreach ( $aFields as $aField ) { + $sCode .= "showRowById('$aField');"; + } + break; + + case 'showOnly': + $sCode .= "hideRowsById(Array($sDynaformFieldsAsStrings));"; + foreach ( $aFields as $aField ) { + $sCode .= "showRowById('$aField');"; + } + break; + + case 'showAll': + $sCode .= "showRowsById(Array($sDynaformFieldsAsStrings));"; + break; + + case 'hide': + foreach ( $aFields as $aField ) { + $sCode .= "hideRowById('$aField');"; + } + break; + + case 'hideOnly': + $sCode .= "showRowsById(Array($sDynaformFieldsAsStrings));"; + foreach ( $aFields as $aField ) { + $sCode .= "hideRowById('$aField');"; + } + break; + + case 'hideAll': + $aDynaFields = array(); + $aEventOwner = explode(',', $aRow['FCD_EVENT_OWNERS'] ); + foreach($aDynaformFields as $sDynaformFields){ + if(! in_array(str_replace("'", "", $sDynaformFields), $aEventOwner) ) { + $aDynaFields[] = $sDynaformFields; + } + } + $sDynaformFieldsAsStrings = implode(',', $aDynaFields); + $sCode .= "hideRowsById(Array($sDynaformFieldsAsStrings));"; + + break; + } + $sCode .= " } "; + $sCode .= "} "; + $aFieldOwners = explode(',', $aRow['FCD_EVENT_OWNERS']); + $aEvents = explode(',', $aRow['FCD_EVENTS']); + if( in_array('onchange', $aEvents) ) { + foreach ( $aFieldOwners as $aField ) { + + //verify the field type + $node = $this->oDynaformHandler->getNode($aField); + $nodeType = $node->getAttribute('type'); + + switch($nodeType){ + case 'checkbox': + $sJSEvent = 'click'; + break; + case 'text': + case 'textarea': + case 'currency': + case 'percentage': + $sJSEvent = 'blur'; + break; + + default: + $sJSEvent = 'change'; + break; + } + $sCode .= "leimnud.event.add(getField('$aField'), '$sJSEvent', function() {"; + $sCode .= " __condition__$hashCond(); "; + $sCode .= "}.extend(getField('$aField')));"; + } + + } + if( in_array('onload', $aEvents) ) { + foreach ( $aFieldOwners as $aField ) { + $sCode .= " __condition__$hashCond(); "; + } + } + } + + + return $sCode; + } else { + return NULL; + } + } + + function parseCondition($sCondition) { + preg_match_all('/@#[a-zA-Z0-9_.]+/', $sCondition, $result); + if ( sizeof($result[0]) > 0 ) { + foreach( $result[0] as $fname ) { + preg_match_all('/(@#[a-zA-Z0-9_]+)\.([@#[a-zA-Z0-9_]+)/', $fname, $result2); + if( isset($result2[2][0]) && $result2[1][0]){ + $sCondition = str_replace($fname, "getField('".str_replace('@#', '', $result2[1][0])."').".$result2[2][0], $sCondition); + } else { + $field = str_replace('@#', '', $fname); + $node = $this->oDynaformHandler->getNode($field); + if(isset($node)) { + $nodeType = $node->getAttribute('type'); + switch($nodeType){ + case 'checkbox': + $sAtt = 'checked'; + break; + default: + $sAtt = 'value'; + } + } else { + $sAtt = 'value'; + } + $sCondition = str_replace($fname, "getField('".$field."').$sAtt", $sCondition); + } + } + } + return $sCondition; + } + + public function create($aData) { + $oConnection = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + try { + // $aData['FCD_UID'] = ''; + if ( isset ( $aData['FCD_UID'] ) && $aData['FCD_UID']== '' ) + unset ( $aData['FCD_UID'] ); + if ( !isset ( $aData['FCD_UID'] ) ) + $aData['FCD_UID'] = G::generateUniqueID(); + + $oFieldCondition = new FieldCondition(); + $oFieldCondition->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oFieldCondition->validate()) { + $oConnection->begin(); + $iResult = $oFieldCondition->save(); + $oConnection->commit(); + return true; + } else { + $sMessage = ''; + $aValidationFailures = $oFieldCondition->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + + public function remove($sUID) { + $oConnection = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + try { + $oConnection->begin(); + $this->setFcdUid($sUID); + $iResult = $this->delete(); + $oConnection->commit(); + return $iResult; + } catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function fieldConditionExists ( $sUid, $aDynaform ) { + try { + $found = false; + $obj = FieldConditionPeer::retrieveByPk( $sUid ); + if( isset($obj) ) { + $aFields = $obj->toArray(BasePeer::TYPE_FIELDNAME); + foreach($aDynaform as $key => $row){ + if($row['DYN_UID'] == $aFields['FCD_DYN_UID']) + $found = true; + } + } + // return( get_class($obj) == 'FieldCondition') ; + return($found); + } + catch (Exception $oError) { + throw($oError); + } + } + + function Exists ( $sUid ) { + try { + $obj = FieldConditionPeer::retrieveByPk( $sUid ); + return( get_class($obj) == 'FieldCondition') ; + } + catch (Exception $oError) { + throw($oError); + } + } + +} // FieldCondition diff --git a/workflow/engine/classes/model/FieldConditionPeer.php b/workflow/engine/classes/model/FieldConditionPeer.php new file mode 100644 index 000000000..4eac2285a --- /dev/null +++ b/workflow/engine/classes/model/FieldConditionPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseFieldConditionPeer.php'; + + // include object class + include_once 'classes/model/FieldCondition.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'FIELD_CONDITION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class FieldConditionPeer extends BaseFieldConditionPeer { + +} // FieldConditionPeer diff --git a/workflow/engine/classes/model/Fields.php b/workflow/engine/classes/model/Fields.php new file mode 100644 index 000000000..de5de596d --- /dev/null +++ b/workflow/engine/classes/model/Fields.php @@ -0,0 +1,119 @@ +<?php + +require_once 'classes/model/om/BaseFields.php'; + + +/** + * Skeleton subclass for representing a row from the 'FIELDS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Fields extends BaseFields { + public function load($sUID) { + try { + $oFields = FieldsPeer::retrieveByPK($sUID); + if (!is_null($oFields)) { + $aFields = $oFields->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function create($aData) { + if (!isset($aData['FLD_UID'])) { + $aData['FLD_UID'] = G::generateUniqueID(); + } + else { + if ($aData['FLD_UID'] == '') { + $aData['FLD_UID'] = G::generateUniqueID(); + } + } + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + try { + $oFields = new Fields(); + $oFields->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oFields->validate()) { + $oConnection->begin(); + $iResult = $oFields->save(); + $oConnection->commit(); + return $aData['FLD_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oFields->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function update($aData) { + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + try { + $oFields = FieldsPeer::retrieveByPK($aData['FLD_UID']); + if (!is_null($oFields)) { + $oFields->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oFields->validate()) { + $oConnection->begin(); + $iResult = $oFields->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oFields->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function remove($sUID) { + $oConnection = Propel::getConnection(FieldsPeer::DATABASE_NAME); + try { + $oFields = FieldsPeer::retrieveByPK($sUID); + if (!is_null($oFields)) { + $oConnection->begin(); + $iResult = $oFields->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } +} // Fields diff --git a/workflow/engine/classes/model/FieldsPeer.php b/workflow/engine/classes/model/FieldsPeer.php new file mode 100644 index 000000000..a3ff314e3 --- /dev/null +++ b/workflow/engine/classes/model/FieldsPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseFieldsPeer.php'; + + // include object class + include_once 'classes/model/Fields.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'FIELDS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class FieldsPeer extends BaseFieldsPeer { + +} // FieldsPeer diff --git a/workflow/engine/classes/model/GroupUser.php b/workflow/engine/classes/model/GroupUser.php new file mode 100644 index 000000000..debff5209 --- /dev/null +++ b/workflow/engine/classes/model/GroupUser.php @@ -0,0 +1,102 @@ +<?php +/** + * GroupUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseGroupUser.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'GROUP_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the input directory. + * + * @package classes.model + */ +class GroupUser extends BaseGroupUser { + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(GroupUserPeer::DATABASE_NAME); + try { + $oGroupUser = new GroupUser(); + $oGroupUser->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oGroupUser->validate()) { + $oConnection->begin(); + $iResult = $oGroupUser->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oGroupUser->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param string $sGrpUid + * @param string $sUserUid + * @return string + **/ + public function remove($sGrpUid, $sUserUid) + { + $oConnection = Propel::getConnection(GroupUserPeer::DATABASE_NAME); + try { + $oGroupUser = GroupUserPeer::retrieveByPK($sGrpUid, $sUserUid); + if (!is_null($oGroupUser)) + { + $oConnection->begin(); + $iResult = $oGroupUser->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + +} // GroupUser \ No newline at end of file diff --git a/workflow/engine/classes/model/GroupUserPeer.php b/workflow/engine/classes/model/GroupUserPeer.php new file mode 100644 index 000000000..cbc0c738c --- /dev/null +++ b/workflow/engine/classes/model/GroupUserPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * GroupUserPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseGroupUserPeer.php'; + + // include object class + include_once 'classes/model/GroupUser.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'GROUP_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class GroupUserPeer extends BaseGroupUserPeer { + +} // GroupUserPeer diff --git a/workflow/engine/classes/model/Groupwf.php b/workflow/engine/classes/model/Groupwf.php new file mode 100644 index 000000000..a9960f90c --- /dev/null +++ b/workflow/engine/classes/model/Groupwf.php @@ -0,0 +1,263 @@ +<?php +/** + * Groupwf.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseGroupwf.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'GROUPWF' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Groupwf extends BaseGroupwf { + /** + * This value goes in the content table + * @var string + */ + protected $grp_title = ''; + + /** + * Get the [grp_title] column value. + * @return string + */ + public function getGrpTitle() + { + if ( $this->getGrpUid() == '' ) { + throw ( new Exception( "Error in getGrpTitle, the GRP_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->grp_title = Content::load ( 'GRP_TITLE', '', $this->getGrpUid(), $lang ); + return $this->grp_title; + } + + /** + * Set the [grp_title] column value. + * + * @param string $v new value + * @return void + */ + public function setGrpTitle($v) + { + if ( $this->getGrpUid() == '' ) { + throw ( new Exception( "Error in setGrpTitle, the GRP_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->grp_title !== $v || $v === '') { + $this->grp_title = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'GRP_TITLE', '', $this->getGrpUid(), $lang, $this->grp_title ); + } + + } // set() + + /** + * Creates the Group + * + * @param array $aData $oData is not necessary + * @return void + */ + + function create ($aData ) { + //$oData is not necessary + $con = Propel::getConnection( GroupwfPeer::DATABASE_NAME ); + try { + if ( isset ( $aData['GRP_UID'] ) ) + $this->setGrpUid ( $aData['GRP_UID'] ); + else + $this->setGrpUid ( G::generateUniqueID() ); + + if ( isset ( $aData['GRP_STATUS'] ) ) + $this->setGrpStatus ( $aData['GRP_STATUS'] ); + else + $this->setGrpStatus ( 'ACTIVE' ); + + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + + if (isset ( $aData['GRP_TITLE'] ) ) + $this->setGrpTitle ( $aData['GRP_TITLE'] ); + else + $this->setGrpTitle ( 'Default Group Title' ); + + $con->commit(); + return $this->getGrpUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + + } + catch (Exception $e) { + $con->rollback(); + throw ($e); + } + } + + /** + * Load the Process row specified in [grp_id] column value. + * + * @param string $ProUid the uid of the Prolication + * @return array $Fields the fields + */ + + function Load ( $ProUid ) { + $con = Propel::getConnection(GroupwfPeer::DATABASE_NAME); + try { + $oPro = GroupwfPeer::retrieveByPk( $ProUid ); + if ( get_class ($oPro) == 'Groupwf' ) { + $aFields = $oPro->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + $aFields['GRP_TITLE'] = $oPro->getGrpTitle(); + $this->setGrpTitle ( $oPro->getGrpTitle() ); + return $aFields; + } + else { + throw(new Exception( "The row '$ProUid' in table Group doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Update the Group row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( GroupwfPeer::DATABASE_NAME ); + try { + $con->begin(); + $oPro = GroupwfPeer::retrieveByPK( $aData['GRP_UID'] ); + if ( get_class ($oPro) == 'Groupwf' ) { + $oPro->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oPro->validate()) { + if ( isset ( $aData['GRP_TITLE'] ) ) + $oPro->setGrpTitle( $aData['GRP_TITLE'] ); + $res = $oPro->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + } + else { + $con->rollback(); + throw(new Exception( "The row '" . $aData['GRP_UID'] . "' in table Group doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Remove the Prolication document registry + * @param array $aData or string $ProUid + * @return string + **/ + public function remove($ProUid) + { + if ( is_array ( $ProUid ) ) { + $ProUid = ( isset ( $ProUid['GRP_UID'] ) ? $ProUid['GRP_UID'] : '' ); + } + try { + $oPro = GroupwfPeer::retrieveByPK( $ProUid ); + if (!is_null($oPro)) + { + Content::removeContent('GRP_TITLE', '', $oPro->getGrpUid()); + Content::removeContent('GRP_DESCRIPTION', '', $oPro->getGrpUid()); + return $oPro->delete(); + } + else { + throw(new Exception( "The row '$ProUid' in table Group doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * verify if row specified in [GrpUid] exists. + * + * @param string $sProUid the uid of the Prolication + */ + + function GroupwfExists ( $GrpUid ) { + $con = Propel::getConnection(GroupwfPeer::DATABASE_NAME); + try { + $oPro = GroupwfPeer::retrieveByPk( $GrpUid ); + if ( get_class ($oPro) == 'Groupwf' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function loadByGroupname ( $Groupname ) { + $c = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( ContentPeer::CON_CATEGORY ); + $c->addSelectColumn( ContentPeer::CON_VALUE ); + + $c->add(ContentPeer::CON_CATEGORY, 'GRP_TITLE'); + $c->add(ContentPeer::CON_VALUE, $Groupname); + $c->add(ContentPeer::CON_LANG, SYS_LANG ); + return $c; + } + +} // Groupwf diff --git a/workflow/engine/classes/model/GroupwfPeer.php b/workflow/engine/classes/model/GroupwfPeer.php new file mode 100644 index 000000000..946da4331 --- /dev/null +++ b/workflow/engine/classes/model/GroupwfPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * GroupwfPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseGroupwfPeer.php'; + + // include object class + include_once 'classes/model/Groupwf.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'GROUPWF' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class GroupwfPeer extends BaseGroupwfPeer { + +} // GroupwfPeer diff --git a/workflow/engine/classes/model/Holiday.php b/workflow/engine/classes/model/Holiday.php new file mode 100644 index 000000000..b339552aa --- /dev/null +++ b/workflow/engine/classes/model/Holiday.php @@ -0,0 +1,42 @@ +<?php +/** + * Holiday.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseHoliday.php'; + + +/** + * Skeleton subclass for representing a row from the 'HOLIDAY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Holiday extends BaseHoliday { + +} // Holiday diff --git a/workflow/engine/classes/model/HolidayPeer.php b/workflow/engine/classes/model/HolidayPeer.php new file mode 100644 index 000000000..dd111ff5d --- /dev/null +++ b/workflow/engine/classes/model/HolidayPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * HolidayPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseHolidayPeer.php'; + + // include object class + include_once 'classes/model/Holiday.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'HOLIDAY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class HolidayPeer extends BaseHolidayPeer { + +} // HolidayPeer diff --git a/workflow/engine/classes/model/InputDocument.php b/workflow/engine/classes/model/InputDocument.php new file mode 100644 index 000000000..1850a143c --- /dev/null +++ b/workflow/engine/classes/model/InputDocument.php @@ -0,0 +1,317 @@ +<?php +/** + * InputDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseInputDocument.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'INPUT_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the input directory. + * + * @package classes.model + */ +class InputDocument extends BaseInputDocument { + + /** + * This value goes in the content table + * @var string + */ + protected $inp_doc_title = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $inp_doc_description = ''; + + /* + * Load the application document registry + * @param string $sAppDocUid + * @return variant + */ + public function load($sInpDocUid) + { + try { + $oInputDocument = InputDocumentPeer::retrieveByPK($sInpDocUid); + if (!is_null($oInputDocument)) + { + $aFields = $oInputDocument->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['INP_DOC_TITLE'] = $oInputDocument->getInpDocTitle(); + $aFields['INP_DOC_DESCRIPTION'] = $oInputDocument->getInpDocDescription(); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function getByUid($sInpDocUid) + { + try { + $oInputDocument = InputDocumentPeer::retrieveByPK($sInpDocUid); + if( is_null($oInputDocument)) + return false; + + $aFields = $oInputDocument->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['INP_DOC_TITLE'] = $oInputDocument->getInpDocTitle(); + $aFields['INP_DOC_DESCRIPTION'] = $oInputDocument->getInpDocDescription(); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + try { + if ( isset ( $aData['INP_DOC_UID'] ) && $aData['INP_DOC_UID']== '' ) + unset ( $aData['INP_DOC_UID'] ); + if ( !isset ( $aData['INP_DOC_UID'] ) ) + $aData['INP_DOC_UID'] = G::generateUniqueID(); + $oInputDocument = new InputDocument(); + $oInputDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oInputDocument->validate()) { + $oConnection->begin(); + if (isset($aData['INP_DOC_TITLE'])) { + $oInputDocument->setInpDocTitle($aData['INP_DOC_TITLE']); + } + if (isset($aData['INP_DOC_DESCRIPTION'])) { + $oInputDocument->setInpDocDescription($aData['INP_DOC_DESCRIPTION']); + } + $iResult = $oInputDocument->save(); + $oConnection->commit(); + return $aData['INP_DOC_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oInputDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application document registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + try { + $oInputDocument = InputDocumentPeer::retrieveByPK($aData['INP_DOC_UID']); + if (!is_null($oInputDocument)) + { + $oInputDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oInputDocument->validate()) { + $oConnection->begin(); + if (isset($aData['INP_DOC_TITLE'])) + { + $oInputDocument->setInpDocTitle($aData['INP_DOC_TITLE']); + } + if (isset($aData['INP_DOC_DESCRIPTION'])) + { + $oInputDocument->setInpDocDescription($aData['INP_DOC_DESCRIPTION']); + } + $iResult = $oInputDocument->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oInputDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param array $aData + * @return string + **/ + public function remove($sInpDocUid) + { + $oConnection = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + try { + $oInputDocument = InputDocumentPeer::retrieveByPK($sInpDocUid); + if (!is_null($oInputDocument)) + { + $oConnection->begin(); + Content::removeContent('INP_DOC_TITLE', '', $oInputDocument->getInpDocUid()); + Content::removeContent('INP_DOC_DESCRIPTION', '', $oInputDocument->getInpDocUid()); + $iResult = $oInputDocument->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Get the [inp_doc_title] column value. + * @return string + */ + public function getInpDocTitle() + { + if ($this->inp_doc_title == '') { + try { + $this->inp_doc_title = Content::load('INP_DOC_TITLE', '', $this->getInpDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->inp_doc_title; + } + + /** + * Set the [inp_doc_title] column value. + * + * @param string $sValue new value + * @return void + */ + public function setInpDocTitle($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->inp_doc_title !== $sValue || $sValue === '') { + try { + $this->inp_doc_title = $sValue; + $iResult = Content::addContent('INP_DOC_TITLE', '', $this->getInpDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->inp_doc_title); + } + catch (Exception $oError) { + $this->inp_doc_title = ''; + throw($oError); + } + } + } + + /** + * Get the [inp_doc_comment] column value. + * @return string + */ + public function getInpDocDescription() + { + if ($this->inp_doc_description == '') { + try { + $this->inp_doc_description = Content::load('INP_DOC_DESCRIPTION', '', $this->getInpDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->inp_doc_description; + } + + /** + * Set the [inp_doc_comment] column value. + * + * @param string $sValue new value + * @return void + */ + public function setInpDocDescription($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->inp_doc_description !== $sValue || $sValue === '') { + try { + $this->inp_doc_description = $sValue; + $iResult = Content::addContent('INP_DOC_DESCRIPTION', '', $this->getInpDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->inp_doc_description); + } + catch (Exception $oError) { + $this->inp_doc_description = ''; + throw($oError); + } + } + } + + /** + * verify if Input row specified in [DynUid] exists. + * + * @param string $sUid the uid of the Prolication + */ + + function InputExists ( $sUid ) { + $con = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + try { + $oObj = InputDocumentPeer::retrieveByPk( $sUid ); + if ( get_class ($oObj) == 'InputDocument' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + +} // InputDocument diff --git a/workflow/engine/classes/model/InputDocumentPeer.php b/workflow/engine/classes/model/InputDocumentPeer.php new file mode 100644 index 000000000..7ec8254a5 --- /dev/null +++ b/workflow/engine/classes/model/InputDocumentPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * InputDocumentPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseInputDocumentPeer.php'; + + // include object class + include_once 'classes/model/InputDocument.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'INPUT_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class InputDocumentPeer extends BaseInputDocumentPeer { + +} // InputDocumentPeer diff --git a/workflow/engine/classes/model/IsoCountry.php b/workflow/engine/classes/model/IsoCountry.php new file mode 100644 index 000000000..d35a21a16 --- /dev/null +++ b/workflow/engine/classes/model/IsoCountry.php @@ -0,0 +1,62 @@ +<?php +/** + * IsoCountry.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseIsoCountry.php'; + + +/** + * Skeleton subclass for representing a row from the 'ISO_COUNTRY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoCountry extends BaseIsoCountry { + function findById($UID){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(IsoCountryPeer::IC_UID); + $oCriteria->addSelectColumn(IsoCountryPeer::IC_NAME); + $oCriteria->add(IsoCountryPeer::IC_UID, $UID); + $oDataset = IsoCountryPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + return $oDataset->getRow(); + } + + function findByIcName($IC_NAME){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(IsoCountryPeer::IC_UID); + $oCriteria->addSelectColumn(IsoCountryPeer::IC_NAME); + $oCriteria->add(IsoCountryPeer::IC_NAME, $IC_NAME); + $oDataset = IsoCountryPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + return $oDataset->getRow(); + } +} // IsoCountry diff --git a/workflow/engine/classes/model/IsoCountryPeer.php b/workflow/engine/classes/model/IsoCountryPeer.php new file mode 100644 index 000000000..3a1fcc135 --- /dev/null +++ b/workflow/engine/classes/model/IsoCountryPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * IsoCountryPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseIsoCountryPeer.php'; + + // include object class + include_once 'classes/model/IsoCountry.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'ISO_COUNTRY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoCountryPeer extends BaseIsoCountryPeer { + +} // IsoCountryPeer diff --git a/workflow/engine/classes/model/IsoLocation.php b/workflow/engine/classes/model/IsoLocation.php new file mode 100644 index 000000000..66d2529e1 --- /dev/null +++ b/workflow/engine/classes/model/IsoLocation.php @@ -0,0 +1,67 @@ +<?php +/** + * IsoLocation.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseIsoLocation.php'; + + +/** + * Skeleton subclass for representing a row from the 'ISO_LOCATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoLocation extends BaseIsoLocation { + + function getAllRowsLike($word) + { + try { + //require_once 'classes/model/IsoLocation.php'; + + $c = new Criteria('workflow'); + $c->addSelectColumn(IsoLocationPeer::IC_UID); + $c->addSelectColumn(IsoLocationPeer::IL_NORMAL_NAME); + $c->add(IsoLocationPeer::IL_NORMAL_NAME, $word."%", Criteria::LIKE); + + $rs = IsoLocationPeer::doSelectRS($c); + //$rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $rows = Array(); + while($rs->next()){ + array_push($rows, $rs->getRow()); + } + + return $rows; + } + catch (Exception $oException) { + throw $oException; + } + } + +} // IsoLocation diff --git a/workflow/engine/classes/model/IsoLocationPeer.php b/workflow/engine/classes/model/IsoLocationPeer.php new file mode 100644 index 000000000..f0910f1af --- /dev/null +++ b/workflow/engine/classes/model/IsoLocationPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * IsoLocationPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseIsoLocationPeer.php'; + + // include object class + include_once 'classes/model/IsoLocation.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'ISO_LOCATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoLocationPeer extends BaseIsoLocationPeer { + +} // IsoLocationPeer diff --git a/workflow/engine/classes/model/IsoSubdivision.php b/workflow/engine/classes/model/IsoSubdivision.php new file mode 100644 index 000000000..12c03527f --- /dev/null +++ b/workflow/engine/classes/model/IsoSubdivision.php @@ -0,0 +1,42 @@ +<?php +/** + * IsoSubdivision.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseIsoSubdivision.php'; + + +/** + * Skeleton subclass for representing a row from the 'ISO_SUBDIVISION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoSubdivision extends BaseIsoSubdivision { + +} // IsoSubdivision diff --git a/workflow/engine/classes/model/IsoSubdivisionPeer.php b/workflow/engine/classes/model/IsoSubdivisionPeer.php new file mode 100644 index 000000000..c7d4afc5b --- /dev/null +++ b/workflow/engine/classes/model/IsoSubdivisionPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * IsoSubdivisionPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseIsoSubdivisionPeer.php'; + + // include object class + include_once 'classes/model/IsoSubdivision.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'ISO_SUBDIVISION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class IsoSubdivisionPeer extends BaseIsoSubdivisionPeer { + +} // IsoSubdivisionPeer diff --git a/workflow/engine/classes/model/Language.php b/workflow/engine/classes/model/Language.php new file mode 100644 index 000000000..64920f085 --- /dev/null +++ b/workflow/engine/classes/model/Language.php @@ -0,0 +1,120 @@ +<?php +/** + * Language.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseLanguage.php'; + + +/** + * Skeleton subclass for representing a row from the 'LANGUAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Language extends BaseLanguage { + function load($sLanUid) { + try { + $oRow = LanguagePeer::retrieveByPK($sLanUid); + if (!is_null($oRow)) { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function update($aFields) { + $oConnection = Propel::getConnection(LanguagePeer::DATABASE_NAME); + try { + $oConnection->begin(); + $this->load($aFields['LAN_ID']); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + if ($this->validate()) { + $iResult = $this->save(); + $oConnection->commit(); + return $iResult; + } + else { + $oConnection->rollback(); + throw(new Exception('Failed Validation in class ' . get_class($this) . '.')); + } + } + catch(Exception $e) { + $oConnection->rollback(); + throw($e); + } + } + //SELECT LAN_ID, LAN_NAME FROM LANGUAGE WHERE LAN_ENABLED = '1' ORDER BY LAN_WEIGHT DESC + function getActiveLanguages(){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(LanguagePeer::LAN_ID); + $oCriteria->addSelectColumn(LanguagePeer::LAN_NAME); + $oCriteria->add(LanguagePeer::LAN_ENABLED , '1'); + $oCriteria->addDescendingOrderByColumn(LanguagePeer::LAN_WEIGHT); + + $oDataset = ContentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $oContent = new Content(); + $rows = Array(); + while ($oDataset->next()) + array_push($rows, $oDataset->getRow()); + + return $rows; + } + + function findById($LAN_ID){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(LanguagePeer::LAN_NAME); + $oCriteria->add(LanguagePeer::LAN_ID, $LAN_ID); + $oDataset = LanguagePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + return $oDataset->getRow(); + } + + function findByLanName($LAN_NAME){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(LanguagePeer::LAN_ID); + $oCriteria->addSelectColumn(LanguagePeer::LAN_NAME); + $oCriteria->add(LanguagePeer::LAN_NAME, $LAN_NAME, Criteria::LIKE); + $oDataset = LanguagePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + return $oDataset->getRow(); + } + +} // Language diff --git a/workflow/engine/classes/model/LanguagePeer.php b/workflow/engine/classes/model/LanguagePeer.php new file mode 100644 index 000000000..66f473f9c --- /dev/null +++ b/workflow/engine/classes/model/LanguagePeer.php @@ -0,0 +1,46 @@ +<?php +/** + * LanguagePeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseLanguagePeer.php'; + + // include object class + include_once 'classes/model/Language.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'LANGUAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LanguagePeer extends BaseLanguagePeer { + +} // LanguagePeer diff --git a/workflow/engine/classes/model/Lexico.php b/workflow/engine/classes/model/Lexico.php new file mode 100644 index 000000000..4a0c12d4c --- /dev/null +++ b/workflow/engine/classes/model/Lexico.php @@ -0,0 +1,42 @@ +<?php +/** + * Lexico.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseLexico.php'; + + +/** + * Skeleton subclass for representing a row from the 'LEXICO' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Lexico extends BaseLexico { + +} // Lexico diff --git a/workflow/engine/classes/model/LexicoPeer.php b/workflow/engine/classes/model/LexicoPeer.php new file mode 100644 index 000000000..930801dbb --- /dev/null +++ b/workflow/engine/classes/model/LexicoPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * LexicoPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseLexicoPeer.php'; + + // include object class + include_once 'classes/model/Lexico.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'LEXICO' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LexicoPeer extends BaseLexicoPeer { + +} // LexicoPeer diff --git a/workflow/engine/classes/model/LogCasesScheduler.php b/workflow/engine/classes/model/LogCasesScheduler.php new file mode 100644 index 000000000..3f54427ef --- /dev/null +++ b/workflow/engine/classes/model/LogCasesScheduler.php @@ -0,0 +1,74 @@ +<?php + +require_once 'classes/model/om/BaseLogCasesScheduler.php'; + + +/** + * Skeleton subclass for representing a row from the 'LOG_CASES_SCHEDULER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LogCasesScheduler extends BaseLogCasesScheduler { + function getAllCriteria() { + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn(LogCasesSchedulerPeer::LOG_CASE_UID); + $c->addSelectColumn(LogCasesSchedulerPeer::PRO_UID); + $c->addSelectColumn(LogCasesSchedulerPeer::TAS_UID); + $c->addSelectColumn(LogCasesSchedulerPeer::USR_NAME); + $c->addSelectColumn(LogCasesSchedulerPeer::EXEC_DATE); + $c->addSelectColumn(LogCasesSchedulerPeer::EXEC_HOUR); + $c->addSelectColumn(LogCasesSchedulerPeer::RESULT); + $c->addSelectColumn(LogCasesSchedulerPeer::SCH_UID); + $c->addSelectColumn(LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS); + $c->addSelectColumn(LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS); + return $c; + } + + function getAll(){ + $oCriteria = $this->getAllCriteria(); + $oDataset = LogCasesSchedulerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRows = Array(); + while( $aRow = $oDataset->getRow() ) { + $aRows[] = $aRow; + $oDataset->next(); + } + /*foreach($aRows as $k => $aRow){ + $oProcess = new Process(); + $aProcessRow = $oProcess->load($aRow['PRO_UID']); + $oTask = new Task(); + $aTaskRow = $oTask->load($aRow['TAS_UID']); + $aRows[$k] = array_merge($aRow, $aProcessRow, $aTaskRow); + }*/ + + return $aRows; + } + function saveLogParameters($params){ + + if ( isset ( $params['LOG_CASE_UID'] ) && $params['LOG_CASE_UID']== '' ) + unset ( $params['LOG_CASE_UID'] ); + if ( !isset ( $params['LOG_CASE_UID'] ) ) + $params['LOG_CASE_UID'] = G::generateUniqueID(); + $this->setLogCaseUid($params['LOG_CASE_UID']); + $this->setProUid($params['PRO_UID']); + $this->setTasUid($params['TAS_UID']); + $this->setSchUid($params['SCH_UID']); + $this->setUsrName($params['USR_NAME']); + $this->setExecDate($params['EXEC_DATE']); + $this->setExecHour($params['EXEC_HOUR']); + $this->setResult($params['RESULT']); + $this->setWsCreateCaseStatus($params['WS_CREATE_CASE_STATUS']); + $this->setWsRouteCaseStatus($params['WS_ROUTE_CASE_STATUS']); + + } + + +} // LogCasesScheduler diff --git a/workflow/engine/classes/model/LogCasesSchedulerPeer.php b/workflow/engine/classes/model/LogCasesSchedulerPeer.php new file mode 100644 index 000000000..0bfc7f5e3 --- /dev/null +++ b/workflow/engine/classes/model/LogCasesSchedulerPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseLogCasesSchedulerPeer.php'; + + // include object class + include_once 'classes/model/LogCasesScheduler.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'LOG_CASES_SCHEDULER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LogCasesSchedulerPeer extends BaseLogCasesSchedulerPeer { + +} // LogCasesSchedulerPeer diff --git a/workflow/engine/classes/model/LoginLog.php b/workflow/engine/classes/model/LoginLog.php new file mode 100644 index 000000000..b9a8d7d1e --- /dev/null +++ b/workflow/engine/classes/model/LoginLog.php @@ -0,0 +1,109 @@ +<?php + +require_once 'classes/model/om/BaseLoginLog.php'; + + +/** + * Skeleton subclass for representing a row from the 'LOGIN_LOG' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LoginLog extends BaseLoginLog { + function create ($aData) + { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + try + { + $this->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + } + else + { + $e=new Exception("Failed Validation in class ".get_class($this)."."); + $e->aValidationFailures=$this->getValidationFailures(); + throw($e); + } + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + public function load($LogUid) + { + try { + $oRow = LoginLogPeer::retrieveByPK( $LogUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception( "The row '" . $LogUid . "' in table LOGIN_LOG doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function update($fields) + { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['LOG_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + function remove($LogUid) + { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->setWlUid($LogUid); + $result=$this->delete(); + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + +} // LoginLog diff --git a/workflow/engine/classes/model/LoginLogPeer.php b/workflow/engine/classes/model/LoginLogPeer.php new file mode 100644 index 000000000..84598bcb2 --- /dev/null +++ b/workflow/engine/classes/model/LoginLogPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseLoginLogPeer.php'; + + // include object class + include_once 'classes/model/LoginLog.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'LOGIN_LOG' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class LoginLogPeer extends BaseLoginLogPeer { + +} // LoginLogPeer diff --git a/workflow/engine/classes/model/ObjectPermission.php b/workflow/engine/classes/model/ObjectPermission.php new file mode 100644 index 000000000..121186bb5 --- /dev/null +++ b/workflow/engine/classes/model/ObjectPermission.php @@ -0,0 +1,135 @@ +<?php + +require_once 'classes/model/om/BaseObjectPermission.php'; + + +/** + * Skeleton subclass for representing a row from the 'OBJECT_PERMISSION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ObjectPermission extends BaseObjectPermission { + + public function load($UID) + { + try { + $oRow = ObjectPermissionPeer::retrieveByPK( $UID ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception( "The row '" . $UsrUid . "' in table USER doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function create ($aData) + { + try + { + $this->fromArray($aData,BasePeer::TYPE_FIELDNAME); + $result=$this->save(); + return $result; + } + catch(Exception $e) + { + throw($e); + } + } + + function Exists ( $Uid ) { + try { + $oPro = ObjectPermissionPeer::retrieveByPk( $Uid ); + if ( get_class ($oPro) == 'ObjectPermission' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function remove($Uid) + { + $con = Propel::getConnection(ObjectPermissionPeer::DATABASE_NAME); + try { + $oObjPer = ObjectPermissionPeer::retrieveByPK($Uid); + if (get_class($oObjPer) == 'ObjectPermission') + { + $con->begin(); + $iResult = $oObjPer->delete(); + $con->commit(); + return $iResult; + } + else { + throw( new Exception( "The row '" . $Uid . "' in table CaseTrackerObject doesn't exist!" )); + } + } + catch (exception $e) { + $con->rollback(); + throw ($e); + } + } + + function update($aFields) { + $oConnection = Propel::getConnection(ObjectPermissionPeer::DATABASE_NAME); + try { + $oConnection->begin(); + $this->load($aFields['OP_UID']); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + if ($this->validate()) { + $iResult = $this->save(); + $oConnection->commit(); + return $iResult; + } + else { + $oConnection->rollback(); + throw(new Exception('Failed Validation in class ' . get_class($this) . '.')); + } + } + catch(Exception $e) { + $oConnection->rollback(); + throw($e); + } + } + + function removeByObject($sType, $sObjUid) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ObjectPermissionPeer::OP_OBJ_TYPE, $sType); + $oCriteria->add(ObjectPermissionPeer::OP_OBJ_UID, $sObjUid); + ObjectPermissionPeer::doDelete($oCriteria); + } + catch(Exception $e) { + throw($e); + } + } + + function loadInfo($sObjUID){ + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ObjectPermissionPeer::OP_OBJ_UID, $sObjUID); + $oDataset = ObjectPermissionPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return($aRow); + } + +} // ObjectPermission diff --git a/workflow/engine/classes/model/ObjectPermissionPeer.php b/workflow/engine/classes/model/ObjectPermissionPeer.php new file mode 100644 index 000000000..a97829918 --- /dev/null +++ b/workflow/engine/classes/model/ObjectPermissionPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseObjectPermissionPeer.php'; + + // include object class + include_once 'classes/model/ObjectPermission.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'OBJECT_PERMISSION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ObjectPermissionPeer extends BaseObjectPermissionPeer { + +} // ObjectPermissionPeer diff --git a/workflow/engine/classes/model/OutputDocument.php b/workflow/engine/classes/model/OutputDocument.php new file mode 100644 index 000000000..df03b5971 --- /dev/null +++ b/workflow/engine/classes/model/OutputDocument.php @@ -0,0 +1,795 @@ +<?php +/** + * OutputDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseOutputDocument.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'OUTPUT_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class OutputDocument extends BaseOutputDocument { + + /** + * This value goes in the content table + * @var string + */ + protected $out_doc_title = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $out_doc_description = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $out_doc_filename = ''; + + /** + * This value goes in the content table + * @var string + */ + protected $out_doc_template = ''; + + + function __construct() { + $javaInput = PATH_C . 'javaBridgePM' . PATH_SEP . 'input' . PATH_SEP; + $javaOutput = PATH_C . 'javaBridgePM' . PATH_SEP . 'output' . PATH_SEP; + G::mk_dir ( $javaInput ); + G::mk_dir ( $javaOutput ); + } + + public function getByUid($sOutDocUid) + { + try { + $oOutputDocument = OutputDocumentPeer::retrieveByPK( $sOutDocUid ); + if( is_null($oOutputDocument) ) + return false; + + $aFields = $oOutputDocument->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['OUT_DOC_TITLE'] = $oOutputDocument->getOutDocTitle(); + $aFields['OUT_DOC_DESCRIPTION'] = $oOutputDocument->getOutDocDescription(); + $aFields['OUT_DOC_FILENAME'] = $oOutputDocument->getOutDocFilename(); + $aFields['OUT_DOC_TEMPLATE'] = $oOutputDocument->getOutDocTemplate(); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + catch (Exception $oError) { + throw($oError); + } + } + + /* + * Load the application document registry + * @param string $sAppDocUid + * @return variant + */ + public function load($sOutDocUid) + { + try { + $oOutputDocument = OutputDocumentPeer::retrieveByPK( $sOutDocUid ); + if (!is_null($oOutputDocument)) + { + $aFields = $oOutputDocument->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['OUT_DOC_TITLE'] = $oOutputDocument->getOutDocTitle(); + $aFields['OUT_DOC_DESCRIPTION'] = $oOutputDocument->getOutDocDescription(); + $aFields['OUT_DOC_FILENAME'] = $oOutputDocument->getOutDocFilename(); + $aFields['OUT_DOC_TEMPLATE'] = $oOutputDocument->getOutDocTemplate(); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + try { + if ( isset ( $aData['OUT_DOC_UID'] ) && $aData['OUT_DOC_UID']== '' ) + unset ( $aData['OUT_DOC_UID'] ); + if ( !isset ( $aData['OUT_DOC_UID'] ) ) + $aData['OUT_DOC_UID'] = G::generateUniqueID(); + if (!isset($aData['OUT_DOC_GENERATE'])) { + $aData['OUT_DOC_GENERATE'] = 'BOTH'; + } + else { + if ($aData['OUT_DOC_GENERATE'] == '') { + $aData['OUT_DOC_GENERATE'] = 'BOTH'; + } + } + $oOutputDocument = new OutputDocument(); + $oOutputDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oOutputDocument->validate()) { + $oConnection->begin(); + if (isset($aData['OUT_DOC_TITLE'])) { + $oOutputDocument->setOutDocTitle($aData['OUT_DOC_TITLE']); + } + if (isset($aData['OUT_DOC_DESCRIPTION'])) { + $oOutputDocument->setOutDocDescription($aData['OUT_DOC_DESCRIPTION']); + } + $oOutputDocument->setOutDocFilename($aData['OUT_DOC_FILENAME']); + if (isset($aData['OUT_DOC_TEMPLATE'])) { + $oOutputDocument->setOutDocTemplate($aData['OUT_DOC_TEMPLATE']); + } + $iResult = $oOutputDocument->save(); + $oConnection->commit(); + return $aData['OUT_DOC_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oOutputDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application document registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + try { + $oOutputDocument = OutputDocumentPeer::retrieveByPK($aData['OUT_DOC_UID']); + if (!is_null($oOutputDocument)) + { + $oOutputDocument->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oOutputDocument->validate()) { + $oConnection->begin(); + if (isset($aData['OUT_DOC_TITLE'])) + { + $oOutputDocument->setOutDocTitle($aData['OUT_DOC_TITLE']); + } + if (isset($aData['OUT_DOC_DESCRIPTION'])) + { + $oOutputDocument->setOutDocDescription($aData['OUT_DOC_DESCRIPTION']); + } + if (isset($aData['OUT_DOC_FILENAME'])) + { + $oOutputDocument->setOutDocFilename($aData['OUT_DOC_FILENAME']); + } + if (isset($aData['OUT_DOC_TEMPLATE'])) + { + $oOutputDocument->setOutDocTemplate($aData['OUT_DOC_TEMPLATE']); + } + $iResult = $oOutputDocument->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oOutputDocument->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param array $aData + * @return string + **/ + public function remove($sOutDocUid) + { + $oConnection = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + try { + $oOutputDocument = OutputDocumentPeer::retrieveByPK($sOutDocUid); + if (!is_null($oOutputDocument)) + { + $oConnection->begin(); + Content::removeContent('OUT_DOC_TITLE', '', $oOutputDocument->getOutDocUid()); + Content::removeContent('OUT_DOC_DESCRIPTION', '', $oOutputDocument->getOutDocUid()); + Content::removeContent('OUT_DOC_FILENAME', '', $oOutputDocument->getOutDocUid()); + Content::removeContent('OUT_DOC_TEMPLATE', '', $oOutputDocument->getOutDocUid()); + $iResult = $oOutputDocument->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Get the [out_doc_title] column value. + * @return string + */ + public function getOutDocTitle() + { + if ($this->out_doc_title == '') { + try { + $this->out_doc_title = Content::load('OUT_DOC_TITLE', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->out_doc_title; + } + + /** + * Set the [out_doc_title] column value. + * + * @param string $sValue new value + * @return void + */ + public function setOutDocTitle($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->out_doc_title !== $sValue || $sValue === '') { + try { + $this->out_doc_title = $sValue; + $iResult = Content::addContent('OUT_DOC_TITLE', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->out_doc_title); + } + catch (Exception $oError) { + $this->out_doc_title = ''; + throw($oError); + } + } + } + + /** + * Get the [out_doc_comment] column value. + * @return string + */ + public function getOutDocDescription() + { + if ($this->out_doc_description == '') { + try { + $this->out_doc_description = Content::load('OUT_DOC_DESCRIPTION', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->out_doc_description; + } + + /** + * Set the [out_doc_comment] column value. + * + * @param string $sValue new value + * @return void + */ + public function setOutDocDescription($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->out_doc_description !== $sValue || $sValue === '') { + try { + $this->out_doc_description = $sValue; + $iResult = Content::addContent('OUT_DOC_DESCRIPTION', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->out_doc_description); + } + catch (Exception $oError) { + $this->out_doc_description = ''; + throw($oError); + } + } + } + + /** + * Get the [out_doc_filename] column value. + * @return string + */ + public function getOutDocFilename() + { + if ($this->out_doc_filename == '') { + try { + $this->out_doc_filename = Content::load('OUT_DOC_FILENAME', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->out_doc_filename; + } + + /** + * Set the [out_doc_filename] column value. + * + * @param string $sValue new value + * @return void + */ + public function setOutDocFilename($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->out_doc_filename !== $sValue || $sValue === '') { + try { + $this->out_doc_filename = $sValue; + $iResult = Content::addContent('OUT_DOC_FILENAME', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->out_doc_filename); + } + catch (Exception $oError) { + $this->out_doc_filename = ''; + throw($oError); + } + } + } + + /** + * Get the [out_doc_template] column value. + * @return string + */ + public function getOutDocTemplate() + { + if ($this->out_doc_template == '') { + try { + $this->out_doc_template = Content::load('OUT_DOC_TEMPLATE', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->out_doc_template; + } + + /** + * Set the [out_doc_template] column value. + * + * @param string $sValue new value + * @return void + */ + public function setOutDocTemplate($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->out_doc_template !== $sValue || $sValue === '') { + try { + $this->out_doc_template = $sValue; + $iResult = Content::addContent('OUT_DOC_TEMPLATE', '', $this->getOutDocUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->out_doc_template); + } + catch (Exception $oError) { + $this->out_doc_template = ''; + throw($oError); + } + } + } + + /* + * Generate the output document + * @param string $sUID + * @param array $aFields + * @param string $sPath + * @return variant + */ + public function generate($sUID, $aFields, $sPath, $sFilename, $sContent, $sLandscape = false, $sTypeDocToGener = 'BOTH', $aProperties = array()) { + if (($sUID != '') && is_array($aFields) && ($sPath != '')) { + $sContent = G::unhtmlentities($sContent); + $iAux = 0; + $iOcurrences = preg_match_all('/\@(?:([\>])([a-zA-Z\_]\w*)|([a-zA-Z\_][\w\-\>\:]*)\(((?:[^\\\\\)]*(?:[\\\\][\w\W])?)*)\))((?:\s*\[[\'"]?\w+[\'"]?\])+)?/', $sContent, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + if ($iOcurrences) { + for($i = 0; $i < $iOcurrences; $i++) { + preg_match_all('/@>' . $aMatch[2][$i][0] . '([\w\W]*)' . '@<' . $aMatch[2][$i][0] . '/', $sContent, $aMatch2, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); + $sGridName = $aMatch[2][$i][0]; + $sStringToRepeat = $aMatch2[1][0][0]; + if (isset($aFields[$sGridName])) { + if (is_array($aFields[$sGridName])) { + $sAux = ''; + foreach ($aFields[$sGridName] as $aRow) { + foreach ($aRow as $sKey => $vValue) { + if (!is_array($vValue)) { + $aRow[$sKey] = nl2br($aRow[$sKey]); + } + } + $sAux .= G::replaceDataField($sStringToRepeat, $aRow); + } + } + } + $sContent = str_replace('@>' . $sGridName . $sStringToRepeat . '@<' . $sGridName, $sAux, $sContent); + } + } + foreach ($aFields as $sKey => $vValue) { + if (!is_array($vValue)) { + $aFields[$sKey] = nl2br($aFields[$sKey]); + } + } + $sContent = G::replaceDataField($sContent, $aFields); + G::verifyPath($sPath, true); + /* Start - Create .doc */ + $oFile = fopen($sPath . $sFilename . '.doc', 'wb'); + $size = array(); + $size["Letter"] = "216mm 279mm"; + $size["Legal"] = "216mm 357mm"; + $size["Executive"] = "184mm 267mm"; + $size["B5"] = "182mm 257mm"; + $size["Folio"] = "216mm 330mm"; + $size["A0Oversize"] = "882mm 1247mm"; + $size["A0"] = "841mm 1189mm"; + $size["A1"] = "594mm 841mm"; + $size["A2"] = "420mm 594mm"; + $size["A3"] = "297mm 420mm"; + $size["A4"] = "210mm 297mm"; + $size["A5"] = "148mm 210mm"; + $size["A6"] = "105mm 148mm"; + $size["A7"] = "74mm 105mm"; + $size["A8"] = "52mm 74mm"; + $size["A9"] = "37mm 52mm"; + $size["A10"] = "26mm 37mm"; + $size["Screenshot640"] = "640mm 480mm"; + $size["Screenshot800"] = "800mm 600mm"; + $size["Screenshot1024"] = "1024mm 768mm"; + + $sizeLandscape["Letter"] = "279mm 216mm"; + $sizeLandscape["Legal"] = "357mm 216mm"; + $sizeLandscape["Executive"] = "267mm 184mm"; + $sizeLandscape["B5"] = "257mm 182mm"; + $sizeLandscape["Folio"] = "330mm 216mm"; + $sizeLandscape["A0Oversize"] = "1247mm 882mm"; + $sizeLandscape["A0"] = "1189mm 841mm"; + $sizeLandscape["A1"] = "841mm 594mm"; + $sizeLandscape["A2"] = "594mm 420mm"; + $sizeLandscape["A3"] = "420mm 297mm"; + $sizeLandscape["A4"] = "297mm 210mm"; + $sizeLandscape["A5"] = "210mm 148mm"; + $sizeLandscape["A6"] = "148mm 105mm"; + $sizeLandscape["A7"] = "105mm 74mm"; + $sizeLandscape["A8"] = "74mm 52mm"; + $sizeLandscape["A9"] = "52mm 37mm"; + $sizeLandscape["A10"] = "37mm 26mm"; + $sizeLandscape["Screenshot640"] = "480mm 640mm"; + $sizeLandscape["Screenshot800"] = "600mm 800mm"; + $sizeLandscape["Screenshot1024"] = "768mm 1024mm"; + + if(!isset($aProperties['media'])) + $aProperties['media'] = 'Letter'; + + if($sLandscape) + $media = $sizeLandscape[$aProperties['media']]; + else + $media = $size[$aProperties['media']]; + + $marginLeft = '15'; + if(isset($aProperties['margins']['left'])) + $marginLeft = $aProperties['margins']['left']; + + $marginRight = '15'; + if(isset($aProperties['margins']['right'])) + $marginRight = $aProperties['margins']['right']; + + $marginTop = '15'; + if(isset($aProperties['margins']['top'])) + $marginTop = $aProperties['margins']['top']; + + $marginBottom = '15'; + if(isset($aProperties['margins']['bottom'])) + $marginBottom = $aProperties['margins']['bottom']; + + fwrite($oFile, '<html xmlns:v="urn:schemas-microsoft-com:vml" + xmlns:o="urn:schemas-microsoft-com:office:office" + xmlns:w="urn:schemas-microsoft-com:office:word" + xmlns="http://www.w3.org/TR/REC-html40"> + <head> + <meta http-equiv=Content-Type content="text/html; charset=utf-8"> + <meta name=ProgId content=Word.Document> + <meta name=Generator content="Microsoft Word 9"> + <meta name=Originator content="Microsoft Word 9"> + <!--[if !mso]> + <style> + v\:* {behavior:url(#default#VML);} + o\:* {behavior:url(#default#VML);} + w\:* {behavior:url(#default#VML);} + .shape {behavior:url(#default#VML);} + </style> + <![endif]--> + <!--[if gte mso 9]><xml> + <w:WordDocument> + <w:View>Print</w:View> + <w:DoNotHyphenateCaps/> + <w:PunctuationKerning/> + <w:DrawingGridHorizontalSpacing>9.35 pt</w:DrawingGridHorizontalSpacing> + <w:DrawingGridVerticalSpacing>9.35 pt</w:DrawingGridVerticalSpacing> + </w:WordDocument> + </xml><![endif]--> + + <style> + <!-- + @page WordSection1 + {size:'.$media.'; + margin-left:'.$marginLeft.'mm; + margin-right:'.$marginRight.'mm; + margin-bottom:'.$marginBottom.'mm; + margin-top:'.$marginTop.'mm; + mso-header-margin:35.4pt; + mso-footer-margin:35.4pt; + mso-paper-source:0;} + div.WordSection1 + {page:WordSection1;} + --> + </style> + </head> + <body> + <div class=WordSection1>'); + fwrite($oFile, $sContent); + fwrite($oFile, "\n</div></body></html>\n\n"); + fclose($oFile); + /* End - Create .doc */ + + if($sTypeDocToGener == 'BOTH' || $sTypeDocToGener == 'PDF'){ + /* Start - Create .pdf */ + $oFile = fopen($sPath . $sFilename . '.html', 'wb'); + fwrite($oFile, $sContent); + fclose($oFile); + + define('PATH_OUTPUT_FILE_DIRECTORY', PATH_HTML . 'files/' . $_SESSION['APPLICATION'] . '/outdocs/'); + G::verifyPath(PATH_OUTPUT_FILE_DIRECTORY, true); + require_once(PATH_THIRDPARTY . 'html2ps_pdf/config.inc.php'); + require_once(PATH_THIRDPARTY . 'html2ps_pdf/pipeline.factory.class.php'); + parse_config_file(PATH_THIRDPARTY . 'html2ps_pdf/html2ps.config'); + $GLOBALS['g_config'] = array('cssmedia' => 'screen', + 'media' => 'Letter', + 'scalepoints' => false, + 'renderimages' => true, + 'renderfields' => true, + 'renderforms' => false, + 'pslevel' => 3, + 'renderlinks' => true, + 'pagewidth' => 800, + 'landscape' => $sLandscape, + 'method' => 'fpdf', + 'margins' => array('left' => 15, 'right' => 15, 'top' => 15, 'bottom' => 15,), + 'encoding' => '', + 'ps2pdf' => false, + 'compress' => false, + 'output' => 2, + 'pdfversion' => '1.3', + 'transparency_workaround' => false, + 'imagequality_workaround' => false, + 'draw_page_border' => isset($_REQUEST['pageborder']), + 'debugbox' => false, + 'html2xhtml' => true, + 'mode' => 'html', + 'smartpagebreak' => true); + $GLOBALS['g_config']= array_merge($GLOBALS['g_config'],$aProperties); + $g_media = Media::predefined($GLOBALS['g_config']['media']); + $g_media->set_landscape($GLOBALS['g_config']['landscape']); + $g_media->set_margins($GLOBALS['g_config']['margins']); + $g_media->set_pixels($GLOBALS['g_config']['pagewidth']); + $pipeline = new Pipeline(); + if (extension_loaded('curl')) + { + require_once(HTML2PS_DIR . 'fetcher.url.curl.class.php'); + $pipeline->fetchers = array(new FetcherURLCurl()); + if (isset($proxy)) { + if ($proxy != '') + { + $pipeline->fetchers[0]->set_proxy($proxy); + } + } + } + else + { + require_once(HTML2PS_DIR . 'fetcher.url.class.php'); + $pipeline->fetchers[] = new FetcherURL(); + } + $pipeline->data_filters[] = new DataFilterDoctype(); + $pipeline->data_filters[] = new DataFilterUTF8($GLOBALS['g_config']['encoding']); + if ($GLOBALS['g_config']['html2xhtml']) + { + $pipeline->data_filters[] = new DataFilterHTML2XHTML(); + } + else + { + $pipeline->data_filters[] = new DataFilterXHTML2XHTML(); + } + $pipeline->parser = new ParserXHTML(); + $pipeline->pre_tree_filters = array(); + $header_html = ''; + $footer_html = ''; + $filter = new PreTreeFilterHeaderFooter($header_html, $footer_html); + $pipeline->pre_tree_filters[] = $filter; + if ($GLOBALS['g_config']['renderfields']) + { + $pipeline->pre_tree_filters[] = new PreTreeFilterHTML2PSFields(); + } + if ($GLOBALS['g_config']['method'] === 'ps') + { + $pipeline->layout_engine = new LayoutEnginePS(); + } + else + { + $pipeline->layout_engine = new LayoutEngineDefault(); + } + $pipeline->post_tree_filters = array(); + if ($GLOBALS['g_config']['pslevel'] == 3) + { + $image_encoder = new PSL3ImageEncoderStream(); + } + else + { + $image_encoder = new PSL2ImageEncoderStream(); + } + switch ($GLOBALS['g_config']['method']) + { + case 'fastps': + if ($GLOBALS['g_config']['pslevel'] == 3) + { + $pipeline->output_driver = new OutputDriverFastPS($image_encoder); + } + else + { + $pipeline->output_driver = new OutputDriverFastPSLevel2($image_encoder); + } + break; + case 'pdflib': + $pipeline->output_driver = new OutputDriverPDFLIB16($GLOBALS['g_config']['pdfversion']); + break; + case 'fpdf': + $pipeline->output_driver = new OutputDriverFPDF(); + break; + case 'png': + $pipeline->output_driver = new OutputDriverPNG(); + break; + case 'pcl': + $pipeline->output_driver = new OutputDriverPCL(); + break; + default: + die('Unknown output method'); + } + if (isset($GLOBALS['g_config']['watermarkhtml'])) { + $watermark_text = $GLOBALS['g_config']['watermarkhtml']; + } + else { + $watermark_text = ''; + } + $pipeline->output_driver->set_watermark($watermark_text); + if ($watermark_text != '') + { + $dispatcher =& $pipeline->getDispatcher(); + } + if ($GLOBALS['g_config']['debugbox']) + { + $pipeline->output_driver->set_debug_boxes(true); + } + if ($GLOBALS['g_config']['draw_page_border']) + { + $pipeline->output_driver->set_show_page_border(true); + } + if ($GLOBALS['g_config']['ps2pdf']) + { + $pipeline->output_filters[] = new OutputFilterPS2PDF($GLOBALS['g_config']['pdfversion']); + } + if ($GLOBALS['g_config']['compress'] && $GLOBALS['g_config']['method'] == 'fastps') + { + $pipeline->output_filters[] = new OutputFilterGZip(); + } + if (!isset($GLOBALS['g_config']['process_mode'])) { + $GLOBALS['g_config']['process_mode'] = ''; + } + if ($GLOBALS['g_config']['process_mode'] == 'batch') + { + $filename = 'batch'; + } + else + { + $filename = $sFilename; + } + switch ($GLOBALS['g_config']['output']) + { + case 0: + $pipeline->destination = new DestinationBrowser($filename); + break; + case 1: + $pipeline->destination = new DestinationDownload($filename); + break; + case 2: + $pipeline->destination = new DestinationFile($filename); + break; + } + copy($sPath . $sFilename . '.html', PATH_OUTPUT_FILE_DIRECTORY . $sFilename . '.html'); + $status = $pipeline->process(( (isset($_SERVER['HTTPS']))&&($_SERVER['HTTPS']=='on') ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . '/files/' . $_SESSION['APPLICATION'] . '/outdocs/' . $sFilename . '.html', $g_media); + + copy(PATH_OUTPUT_FILE_DIRECTORY . $sFilename . '.pdf', $sPath . $sFilename . '.pdf'); + unlink(PATH_OUTPUT_FILE_DIRECTORY . $sFilename . '.pdf'); + unlink(PATH_OUTPUT_FILE_DIRECTORY . $sFilename . '.html'); + + }//end if $sTypeDocToGener + /* End - Create .pdf */ + } + else + { + return PEAR::raiseError(null, + G_ERROR_USER_UID, + null, + null, + 'You tried to call to a generate method without send the Output Document UID, fields to use and the file path!', + 'G_Error', + true); + } + } + + + /** + * verify if Output row specified in [sUid] exists. + * + * @param string $sUid the uid of the Prolication + */ + + function OutputExists ( $sUid ) { + $con = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + try { + $oObj = OutputDocumentPeer::retrieveByPk( $sUid ); + if ( get_class ($oObj) == 'OutputDocument' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } +} // OutputDocument \ No newline at end of file diff --git a/workflow/engine/classes/model/OutputDocumentPeer.php b/workflow/engine/classes/model/OutputDocumentPeer.php new file mode 100644 index 000000000..48767b2d8 --- /dev/null +++ b/workflow/engine/classes/model/OutputDocumentPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * OutputDocumentPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseOutputDocumentPeer.php'; + + // include object class + include_once 'classes/model/OutputDocument.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'OUTPUT_DOCUMENT' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class OutputDocumentPeer extends BaseOutputDocumentPeer { + +} // OutputDocumentPeer diff --git a/workflow/engine/classes/model/Process.php b/workflow/engine/classes/model/Process.php new file mode 100644 index 000000000..1008c8893 --- /dev/null +++ b/workflow/engine/classes/model/Process.php @@ -0,0 +1,610 @@ +<?php +/** + * Process.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseProcess.php'; +require_once 'classes/model/Content.php'; +require_once 'classes/model/ProcessCategory.php'; + + +/** + * Skeleton subclass for representing a row from the 'PROCESS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Process extends BaseProcess { + /** + * This value goes in the content table + * @var string + */ + protected $pro_title = ''; + + /** + * Get the [Pro_title] column value. + * @return string + */ + public function getProTitle() + { + if ( $this->getProUid() == '' ) { + throw ( new Exception( "Error in getProTitle, the PRO_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->pro_title = Content::load ( 'PRO_TITLE', '', $this->getProUid(), $lang ); + return $this->pro_title; + } + + /** + * Set the [Pro_title] column value. + * + * @param string $v new value + * @return void + */ + public function setProTitle($v) + { + if ( $this->getProUid() == '' ) { + throw ( new Exception( "Error in setProTitle, the PRO_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_title !== $v || $v === '') { + $this->pro_title = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'PRO_TITLE', '', $this->getProUid(), $lang, $this->pro_title ); + } + + } // set() + + /** + * This value goes in the content table + * @var string + */ + protected $pro_description = ''; + + /** + * Get the [Pro_description] column value. + * @return string + */ + public function getProDescription() + { + if ( $this->getProUid() == '' ) { + throw ( new Exception( "Error in getProDescription, the PRO_UID can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->pro_description = Content::load ( 'PRO_DESCRIPTION', '', $this->getProUid(), $lang ); + return $this->pro_description; + } + + /** + * Set the [Pro_description] column value. + * + * @param string $v new value + * @return void + */ + public function setProDescription($v) + { + if ( $this->getProUid() == '' ) { + throw ( new Exception( "Error in setProDescription, the PRO_UID can't be blank") ); + } + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_description !== $v || $v === '') { + $this->pro_description = $v; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $res = Content::addContent( 'PRO_DESCRIPTION', '', $this->getProUid(), $lang, $this->pro_description ); + } + + } // set() + + /** + * Creates the Process + * + * @param array $aData Fields with : + * $aData['PRO_UID'] the process id + * $aData['USR_UID'] the userid + $aData['PRO_CATEGORY'] the id category + * @return void + */ + + function create ($aData ) { + if ( !isset ( $aData['USR_UID'] ) ) { + throw ( new PropelException ( 'The process cannot be created. The USR_UID is empty.' ) ); + } + $con = Propel::getConnection( ProcessPeer::DATABASE_NAME ); + try { + do { + $sNewProUid = G::generateUniqueID() ; + } while ( $this->processExists ( $sNewProUid ) ); + + $this->setProUid ( $sNewProUid ); + $this->setProParent ( $sNewProUid ); + $this->setProTime ( 1 ); + $this->setProTimeunit ( 'DAYS' ); + $this->setProStatus ( 'ACTIVE' ); + $this->setProTypeDay ( '' ); + $this->setProType ( 'NORMAL' ); + $this->setProAssignment ( 'FALSE' ); + $this->setProShowMap ( '' ); + $this->setProShowMessage ( '' ); + $this->setProShowDelegate ( '' ); + $this->setProShowDynaform ( '' ); + $this->setProCategory ( $aData['PRO_CATEGORY'] ); + $this->setProSubCategory ( '' ); + $this->setProIndustry ( '' ); + $this->setProCreateDate ('now' ); + $this->setProCreateUser ( $aData['USR_UID'] ); + $this->setProHeight ( 5000 ); + $this->setProWidth ( 10000 ); + $this->setProTitleX ( 0 ); + $this->setProTitleY ( 0 ); + + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + + if (isset ( $aData['PRO_TITLE'] ) ) + $this->setProTitle ( $aData['PRO_TITLE'] ); + else + $this->setProTitle ( 'Default Process Title' ); + + if (isset ( $aData['PRO_DESCRIPTION'] ) ) + $this->setProDescription ( $aData['PRO_DESCRIPTION'] ); + else + $this->setProDescription ( 'Default Process Description' ); + + $con->commit(); + return $this->getProUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + + } + catch (Exception $e) { + $con->rollback(); + throw ($e); + } + } + + /** + * verify if Process row specified in [pro_id] exists. + * + * @param string $sProUid the uid of the Prolication + */ + + function processExists ( $ProUid ) { + $con = Propel::getConnection(ProcessPeer::DATABASE_NAME); + try { + $oPro = ProcessPeer::retrieveByPk( $ProUid ); + if ( get_class($oPro) == 'Process' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + + + /** + * Load the Process row specified in [pro_id] column value. + * + * @param string $ProUid the uid of the Prolication + * @return array $Fields the fields + */ + + function load ( $ProUid , $getAllLang=false) { + + $con = Propel::getConnection(ProcessPeer::DATABASE_NAME); + try { + $oPro = ProcessPeer::retrieveByPk( $ProUid ); + if ( get_class ($oPro) == 'Process' ) { + $aFields = $oPro->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray ($aFields, BasePeer::TYPE_FIELDNAME ); + //optimized to avoid double and multiple execution of the same query +// $aFields['PRO_TITLE'] = $oPro->getProTitle(); +// $aFields['PRO_DESCRIPTION'] = $oPro->getProDescription(); +// $this->pro_title = $aFields['PRO_TITLE']; +// $this->pro_description = $aFields['PRO_DESCRIPTION']; + + + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn(ContentPeer::CON_CATEGORY); + $c->addSelectColumn(ContentPeer::CON_VALUE); + $c->add(ContentPeer::CON_ID, $ProUid ); + if(!$getAllLang) $c->add(ContentPeer::CON_LANG, $lang ); + $rs = ProcessPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + while (is_array($row)) { + switch ( $row['CON_CATEGORY'] ) { + case 'PRO_TITLE' : $aFields['PRO_TITLE'] = $row['CON_VALUE']; + $this->pro_title = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setProTitle($aFields['PRO_TITLE']); + break; + case 'PRO_DESCRIPTION' : $aFields['PRO_DESCRIPTION'] = $row['CON_VALUE']; + $this->pro_description = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setProDescription($aFields['PRO_DESCRIPTION']); + break; + } + $rs->next(); + $row = $rs->getRow(); + } + + + //If the prev script doesn't return anithing try to create the values based on EN + if(!isset($aFields['PRO_TITLE'])){ + $aFields['PRO_TITLE'] = $oPro->getProTitle(); + $this->setProTitle($aFields['PRO_TITLE']); + } + if(!isset($aFields['PRO_DESCRIPTION'])){ + $aFields['PRO_DESCRIPTION'] = $oPro->getProDescription(); + $this->setProDescription($aFields['PRO_DESCRIPTION']); + } + + //the following code is to copy the parent in old process, when the parent was empty. + if ( $oPro->getProParent() == '' ) { + $oPro->setProParent ( $oPro->getProUid() ); + $oPro->save(); + } + + //Get category Name, by default No category + $aFields['PRO_CATEGORY_LABEL']=G::LoadTranslation("ID_PROCESS_NO_CATEGORY"); + if($aFields['PRO_CATEGORY']!=""){ + $oProCat = ProcessCategoryPeer::retrieveByPk( $aFields['PRO_CATEGORY'] ); + if ( get_class ($oProCat) == 'ProcessCategory' ) { + $aFields['PRO_CATEGORY_LABEL']=$oProCat->getCategoryName(); + } + } + + return $aFields; + } + else { + throw( new Exception( "The row '$ProUid' in table Process doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + + function getAll($getAllLang=false) { + $c = new Criteria('workflow'); + + + } + + /** + * Update the Prolication row + * @param array $aData + * @return variant + **/ + + public function update($aData) + { + $con = Propel::getConnection( ProcessPeer::DATABASE_NAME ); + try { + $con->begin(); + $oPro = ProcessPeer::retrieveByPK( $aData['PRO_UID'] ); + if ( get_class ($oPro) == 'Process' ) { + $oPro->fromArray( $aData, BasePeer::TYPE_FIELDNAME ); + if ($oPro->validate()) { + if ( isset ( $aData['PRO_TITLE'] ) ) + $oPro->setProTitle( $aData['PRO_TITLE'] ); + + if ( isset ( $aData['PRO_DESCRIPTION'] ) ) + $oPro->setProDescription( $aData['PRO_DESCRIPTION'] ); + $res = $oPro->save(); + $con->commit(); + return $res; + } + else { + $msg = ''; + foreach($oPro->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new Exception ( 'The row cannot be updated!' . $msg ) ); + } + } + else { + $con->rollback(); + throw( new Exception( "The row '" . $aData['PRO_UID'] ."' in table Process doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * creates an Application row + * @param array $aData + * @return variant + **/ + + public function createRow($aData) + { + $con = Propel::getConnection( ProcessPeer::DATABASE_NAME ); + $con->begin(); + $this->setProUid ( $aData['PRO_UID'] ); + $this->setProParent ( $aData['PRO_PARENT'] ); + $this->setProTime ( $aData['PRO_TIME'] ); + $this->setProTimeunit ( $aData['PRO_TIMEUNIT'] ); + $this->setProStatus ( $aData['PRO_STATUS'] ); + $this->setProTypeDay ( $aData['PRO_TYPE_DAY'] ); + $this->setProType ( $aData['PRO_TYPE'] ); + $this->setProAssignment ( $aData['PRO_ASSIGNMENT'] ); + $this->setProShowMap ( $aData['PRO_SHOW_MAP'] ); + $this->setProShowMessage ( $aData['PRO_SHOW_MESSAGE'] ); + $this->setProShowDelegate ( $aData['PRO_SHOW_DELEGATE'] ); + $this->setProShowDynaform ( $aData['PRO_SHOW_DYNAFORM'] ); + $this->setProCategory ( $aData['PRO_CATEGORY'] ); + $this->setProSubCategory ( $aData['PRO_SUB_CATEGORY'] ); + $this->setProIndustry ( $aData['PRO_INDUSTRY'] ); + $this->setProCreateDate ( $aData['PRO_CREATE_DATE'] ); + $this->setProCreateUser ( $aData['PRO_CREATE_USER'] ); + $this->setProHeight ( $aData['PRO_HEIGHT'] ); + $this->setProWidth ( $aData['PRO_WIDTH'] ); + $this->setProTitleX ( $aData['PRO_TITLE_X'] ); + $this->setProTitleY ( $aData['PRO_TITLE_Y'] ); + if ( $this->validate() ) { + $con->begin(); + $res = $this->save(); + + if (isset ( $aData['PRO_TITLE'] ) ) + $this->setProTitle ( $aData['PRO_TITLE'] ); + else + $this->setProTitle ( 'Default Process Title' ); + + if (isset ( $aData['PRO_DESCRIPTION'] ) ) + $this->setProDescription ( $aData['PRO_DESCRIPTION'] ); + else + $this->setProDescription ( 'Default Process Description' ); + + $con->commit(); + return $this->getProUid(); + } + else { + $msg = ''; + foreach($this->getValidationFailures() as $objValidationFailure) + $msg .= $objValidationFailure->getMessage() . "<br/>"; + + throw ( new PropelException ( 'The row cannot be created!', new PropelException ( $msg ) ) ); + } + + } + + /** + * Remove the Prolication document registry + * @param array $aData or string $ProUid + * @return string + **/ + public function remove($ProUid) + { + if ( is_array ( $ProUid ) ) { + $ProUid = ( isset ( $ProUid['PRO_UID'] ) ? $ProUid['PRO_UID'] : '' ); + } + try { + $oPro = ProcessPeer::retrieveByPK( $ProUid ); + if (!is_null($oPro)) + { + Content::removeContent('PRO_TITLE', '', $oPro->getProUid()); + Content::removeContent('PRO_DESCRIPTION', '', $oPro->getProUid()); + return $oPro->delete(); + } + else { + throw( new Exception( "The row '$ProUid' in table Process doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function exists($ProUid) + { + $oPro = ProcessPeer::retrieveByPk( $ProUid ); + return ( get_class ($oPro) == 'Process' ); + } + + //new functions + function getAllProcessesCount(){ + $c = $this->tmpCriteria; + $c->clearSelectColumns(); + $c->addSelectColumn('COUNT(*)'); + $oDataset = ProcessPeer::doSelectRS($c); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + if( is_array($aRow) ) + return $aRow[0]; + else + return 0; + } + + function getAllProcesses($start, $limit, $category=NULL, $processName=NULL) + { + require_once PATH_RBAC . "model/RbacUsers.php"; + require_once "classes/model/ProcessCategory.php"; + require_once "classes/model/Users.php"; + + $user = new RbacUsers; + $aProcesses = Array(); + $categories = Array(); + $oCriteria = new Criteria('workflow'); + + //$oCriteria->addSelectColumn(ProcessPeer::PRO_UID); + $oCriteria->addSelectColumn(ProcessPeer::TABLE_NAME . '.*'); + $oCriteria->addSelectColumn(UsersPeer::TABLE_NAME . '.*'); + $oCriteria->addSelectColumn(ProcessCategoryPeer::TABLE_NAME . '.*'); + + $oCriteria->add(ProcessPeer::PRO_STATUS, 'DISABLED', Criteria::NOT_EQUAL); + $oCriteria->addJoin(ProcessPeer::PRO_CREATE_USER, UsersPeer::USR_UID); + $oCriteria->addJoin(ProcessPeer::PRO_CATEGORY, ProcessCategoryPeer::CATEGORY_UID, Criteria::LEFT_JOIN); + $oCriteria->addDescendingOrderByColumn(ProcessPeer::PRO_CREATE_DATE); + + if( isset($category) ) + $oCriteria->add(ProcessPeer::PRO_CATEGORY, $category, Criteria::EQUAL); + + /*if($start != '') + $oCriteria->setOffset($start); + if($limit != '') + $oCriteria->setLimit($limit); + */ + + $this->tmpCriteria = $oCriteria; + $oDataset = ProcessPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $casesCnt = $this->getCasesCountInAllProcesses(); + $processes = Array(); + $uids=array(); + while( $oDataset->next() ) { + $processes[] = $oDataset->getRow(); + $uids[] = $processes[sizeof($processes)-1]['PRO_UID']; + } + + $c = new Criteria('workflow'); + //$c->add ( ContentPeer::CON_CATEGORY, 'PRO_TITLE', Criteria::EQUAL ); + $c->add ( ContentPeer::CON_LANG, defined('SYS_LANG')?SYS_LANG:'en', Criteria::EQUAL ); + $c->add ( ContentPeer::CON_ID, $uids, Criteria::IN ); + + $dt = ContentPeer::doSelectRS ($c); + $dt->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $processesDetails = Array(); + while( $dt->next() ) { + $row = $dt->getRow(); + $processesDetails[$row['CON_ID']][$row['CON_CATEGORY']] = $row['CON_VALUE']; + } + + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($obj, 'ENVIRONMENT_SETTINGS',''); + + foreach( $processes as $process ) { + + $proTitle = isset($processesDetails[$process['PRO_UID']]) && isset($processesDetails[$process['PRO_UID']]['PRO_TITLE']) ? $processesDetails[$process['PRO_UID']]['PRO_TITLE']: ''; + $proDescription = isset($processesDetails[$process['PRO_UID']]) && isset($processesDetails[$process['PRO_UID']]['PRO_DESCRIPTION']) ? $processesDetails[$process['PRO_UID']]['PRO_DESCRIPTION']: ''; + + if( isset($processName) && $processName != '' && stripos($proTitle, $processName) === false){ + continue; + } + + $casesCountTotal = 0; + if( isset($casesCnt[$process['PRO_UID']]) ) { + foreach($casesCnt[$process['PRO_UID']] as $item) { + $casesCountTotal += $item; + } + } + + $userOwner = isset($oConf->aConfig['format'])? $oConf->aConfig['format']: ''; + $creationDateMask = isset($oConf->aConfig['dateFormat'])? $oConf->aConfig['dateFormat']: ''; + + if( $userOwner != '' ){ + $userOwner = str_replace('@userName', $process['USR_USERNAME'], $userOwner); + $userOwner = str_replace('@firstName', $process['USR_FIRSTNAME'], $userOwner); + $userOwner = str_replace('@lastName', $process['USR_LASTNAME'], $userOwner); + } else { + $userOwner = $process['USR_FIRSTNAME'].' '.$process['USR_LASTNAME']; + } + + if( $creationDateMask != '' ){ + list($date, $time) = explode(' ', $process['PRO_CREATE_DATE']); + list($y, $m, $d) = explode('-', $date); + list($h, $i, $s) = explode(':', $time); + + $process['PRO_CREATE_DATE'] = date($creationDateMask, mktime($h, $i, $s, $m, $d, $y)); + } + + + $process['PRO_CATEGORY_LABEL'] = trim($process['PRO_CATEGORY']) != ''? $process['CATEGORY_NAME']: G::LoadTranslation('ID_PROCESS_NO_CATEGORY'); + $process['PRO_TITLE'] = $proTitle; + $process['PRO_DESCRIPTION'] = $proDescription; + $process['PRO_DEBUG_LABEL'] = ($process['PRO_DEBUG']=="1")? G::LoadTranslation('ID_ON'): G::LoadTranslation('ID_OFF'); + $process['PRO_STATUS_LABEL'] = $process ['PRO_STATUS'] == 'ACTIVE'? G::LoadTranslation ('ID_ACTIVE'): G::LoadTranslation('ID_INACTIVE'); + $process['PRO_CREATE_USER_LABEL'] = $userOwner; + $process['CASES_COUNT_TO_DO'] = (isset($casesCnt[$process['PRO_UID']]['TO_DO'])? $casesCnt[$process['PRO_UID']]['TO_DO']: 0); + $process['CASES_COUNT_COMPLETED'] = (isset($casesCnt[$process['PRO_UID']]['COMPLETED'])? $casesCnt[$process['PRO_UID']]['COMPLETED']: 0); + $process['CASES_COUNT_DRAFT'] = (isset($casesCnt[$process['PRO_UID']]['DRAFT'])? $casesCnt[$process['PRO_UID']]['DRAFT']: 0); + $process['CASES_COUNT_CANCELLED'] = (isset($casesCnt[$process['PRO_UID']]['CANCELLED'])? $casesCnt[$process['PRO_UID']]['CANCELLED']: 0); + $process['CASES_COUNT'] = $casesCountTotal; + $aProcesses[] = $process; + + } + return $aProcesses; + } + + function getCasesCountInAllProcesses(){ + /*SELECT PRO_UID, APP_STATUS, COUNT( * ) + FROM APPLICATION + GROUP BY PRO_UID, APP_STATUS*/ + require_once 'classes/model/Application.php'; + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(ApplicationPeer::PRO_UID); + $oCriteria->addSelectColumn(ApplicationPeer::APP_STATUS); + $oCriteria->addSelectColumn('COUNT(*) AS CNT'); + $oCriteria->addGroupByColumn(ApplicationPeer::PRO_UID); + $oCriteria->addGroupByColumn(ApplicationPeer::APP_STATUS); + + $oDataset = ProcessPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + + $aProcesses = Array(); + while($oDataset->next()) { + $row = $oDataset->getRow(); + $aProcesses[$row['PRO_UID']][$row['APP_STATUS']] = $row['CNT']; + } + return $aProcesses; + } +} // Process diff --git a/workflow/engine/classes/model/ProcessCategory.php b/workflow/engine/classes/model/ProcessCategory.php new file mode 100644 index 000000000..98c2fbfcb --- /dev/null +++ b/workflow/engine/classes/model/ProcessCategory.php @@ -0,0 +1,57 @@ +<?php + +require_once 'classes/model/om/BaseProcessCategory.php'; + + +/** + * Skeleton subclass for representing a row from the 'PROCESS_CATEGORY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessCategory extends BaseProcessCategory { + function getAll($type='criteria'){ + $c = new Criteria('workflow'); + $c->addSelectColumn(ProcessCategoryPeer::CATEGORY_UID); + $c->addSelectColumn(ProcessCategoryPeer::CATEGORY_NAME); + $dataset = ProcessCategoryPeer::doSelectRS($c); + $dataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + + if( $type == 'array' ){ + $result = Array(); + while ( $dataset->next() ) { + $result[] = $dataset->getRow(); + } + return $result; + } else { + return $c; + } + } + + function loadByCategoryName($sCategoryName) + { + $c = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( ProcessCategoryPeer::CATEGORY_UID ); + $c->addSelectColumn( ProcessCategoryPeer::CATEGORY_NAME); + + $c->add(ProcessCategoryPeer::CATEGORY_NAME, $sCategoryName); + $dataset = ProcessCategoryPeer::doSelectRS($c); + $dataset->next(); + $aRow = $dataset->getRow(); + return $aRow; + } + + +} // ProcessCategory + + + + diff --git a/workflow/engine/classes/model/ProcessCategoryPeer.php b/workflow/engine/classes/model/ProcessCategoryPeer.php new file mode 100644 index 000000000..4da920fcf --- /dev/null +++ b/workflow/engine/classes/model/ProcessCategoryPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseProcessCategoryPeer.php'; + + // include object class + include_once 'classes/model/ProcessCategory.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'PROCESS_CATEGORY' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessCategoryPeer extends BaseProcessCategoryPeer { + +} // ProcessCategoryPeer diff --git a/workflow/engine/classes/model/ProcessOwner.php b/workflow/engine/classes/model/ProcessOwner.php new file mode 100644 index 000000000..3d332516a --- /dev/null +++ b/workflow/engine/classes/model/ProcessOwner.php @@ -0,0 +1,42 @@ +<?php +/** + * ProcessOwner.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseProcessOwner.php'; + + +/** + * Skeleton subclass for representing a row from the 'PROCESS_OWNER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessOwner extends BaseProcessOwner { + +} // ProcessOwner diff --git a/workflow/engine/classes/model/ProcessOwnerPeer.php b/workflow/engine/classes/model/ProcessOwnerPeer.php new file mode 100644 index 000000000..477d4afa6 --- /dev/null +++ b/workflow/engine/classes/model/ProcessOwnerPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * ProcessOwnerPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseProcessOwnerPeer.php'; + + // include object class + include_once 'classes/model/ProcessOwner.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'PROCESS_OWNER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessOwnerPeer extends BaseProcessOwnerPeer { + +} // ProcessOwnerPeer diff --git a/workflow/engine/classes/model/ProcessPeer.php b/workflow/engine/classes/model/ProcessPeer.php new file mode 100644 index 000000000..e771233c8 --- /dev/null +++ b/workflow/engine/classes/model/ProcessPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * ProcessPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseProcessPeer.php'; + + // include object class + include_once 'classes/model/Process.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'PROCESS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessPeer extends BaseProcessPeer { + +} // ProcessPeer diff --git a/workflow/engine/classes/model/ProcessUser.php b/workflow/engine/classes/model/ProcessUser.php new file mode 100644 index 000000000..1357f1135 --- /dev/null +++ b/workflow/engine/classes/model/ProcessUser.php @@ -0,0 +1,96 @@ +<?php + +require_once 'classes/model/om/BaseProcessUser.php'; + + +/** + * Skeleton subclass for representing a row from the 'PROCESS_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessUser extends BaseProcessUser { + public function create($aData) + { + $oConnection = Propel::getConnection(ProcessUserPeer::DATABASE_NAME); + try { + $criteria = new Criteria('workflow'); + $criteria->add(ProcessUserPeer::PU_UID, $aData['PU_UID'] ); + $criteria->add(ProcessUserPeer::PRO_UID, $aData['PRO_UID'] ); + $criteria->add(ProcessUserPeer::USR_UID, $aData['USR_UID'] ); + $criteria->add(ProcessUserPeer::PU_TYPE, $aData['PU_TYPE'] ); + $objects = ProcessUserPeer::doSelect($criteria, $oConnection); + $oConnection->begin(); + foreach($objects as $row) { + $this->remove($row->getTasUid(), $row->getUsrUid(), $row->getTuType(), $row->getTuRelation() ); + } + $oConnection->commit(); + + + $oProcessUser = new ProcessUser(); + $oProcessUser->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oProcessUser->validate()) { + $oConnection->begin(); + $iResult = $oProcessUser->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oProcessUser->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param string $sPuUid + * @param string $sProUid + * @param string $sUserUid + * @return string + **/ + public function remove($sPuUid) + { + $oConnection = Propel::getConnection(ProcessUserPeer::DATABASE_NAME); + try { + $oProcessUser = ProcessUserPeer::retrieveByPK($sPuUid); + if (!is_null($oProcessUser)) + { + $oConnection->begin(); + $iResult = $oProcessUser->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function Exists ( $sUid ) { + try { + $oObj = ProcessUserPeer::retrieveByPk($sUid); + return (get_class($oObj) == 'ProcessUser'); + } + catch (Exception $oError) { + throw($oError); + } + } +} // ProcessUser diff --git a/workflow/engine/classes/model/ProcessUserPeer.php b/workflow/engine/classes/model/ProcessUserPeer.php new file mode 100644 index 000000000..4955f582c --- /dev/null +++ b/workflow/engine/classes/model/ProcessUserPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseProcessUserPeer.php'; + + // include object class + include_once 'classes/model/ProcessUser.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'PROCESS_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ProcessUserPeer extends BaseProcessUserPeer { + +} // ProcessUserPeer diff --git a/workflow/engine/classes/model/ReportTable.php b/workflow/engine/classes/model/ReportTable.php new file mode 100644 index 000000000..3c81974f2 --- /dev/null +++ b/workflow/engine/classes/model/ReportTable.php @@ -0,0 +1,219 @@ +<?php +/** + * ReportTable.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/Content.php'; +require_once 'classes/model/om/BaseReportTable.php'; + + +/** + * Skeleton subclass for representing a row from the 'REPORT_TABLE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ReportTable extends BaseReportTable { + /** + * This value goes in the content table + * @var string + */ + protected $rep_tab_title = ''; + + /** + * Get the rep_tab_title column value. + * @return string + */ + public function getRepTabTitle() { + if ( $this->getRepTabUid() == "" ) { + throw ( new Exception( "Error in getRepTabTitle, the getRepTabUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG' ) ? SYS_LANG : 'en'; + $this->rep_tab_title = Content::load ( 'REP_TAB_TITLE', '', $this->getRepTabUid(), $lang ); + return $this->rep_tab_title; + } + + /** + * Set the rep_tab_title column value. + * + * @param string $v new value + * @return void + */ + public function setRepTabTitle($v) + { + if ( $this->getRepTabUid() == "" ) { + throw ( new Exception( "Error in setRepTabTitle, the setRepTabUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->rep_tab_title !== $v || $v==="") { + $this->rep_tab_title = $v; + $res = Content::addContent( 'REP_TAB_TITLE', '', $this->getRepTabUid(), $lang, $this->rep_tab_title ); + return $res; + } + return 0; + } + + public function load($RepTabUid) + { + try { + $oRow = ReportTablePeer::retrieveByPK( $RepTabUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + $this->setRepTabTitle($aFields['REP_TAB_TITLE']=$this->getRepTabTitle()); + return $aFields; + } + else { + throw( new Exception( "The row '$RepTabUid' in table ReportTable doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + public function create($aData) + { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + try + { + $con->begin(); + if ( isset ( $aData['REP_TAB_UID'] ) && $aData['REP_TAB_UID']== '' ) + unset ( $aData['REP_TAB_UID'] ); + if ( !isset ( $aData['REP_TAB_UID'] ) ) + $this->setRepTabUid(G::generateUniqueID()); + else + $this->setRepTabUid($aData['REP_TAB_UID'] ); + + $this->setProUid($aData['PRO_UID']); + $this->setRepTabName($aData['REP_TAB_NAME']); + $this->setRepTabType($aData['REP_TAB_TYPE']); + if ( !isset ( $aData['REP_TAB_GRID'] ) ) + $this->setRepTabGrid(""); + else + $this->setRepTabGrid( $aData['REP_TAB_GRID'] ); + if ( !isset ( $aData['REP_TAB_CONNECTION'] ) ) + $this->setRepTabConnection("report"); + else + $this->setRepTabConnection( $aData['REP_TAB_CONNECTION'] ); + $this->setRepTabCreateDate(date('Y-m-d H:i:s')); + $this->setRepTabStatus('ACTIVE'); + + if($this->validate()) + { + if ( !isset ( $aData['REP_TAB_TITLE'] ) ) + $this->setRepTabTitle(""); + else + $this->setRepTabTitle( $aData['REP_TAB_TITLE'] ); + + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function update($fields) + { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['REP_TAB_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $contentResult=0; + if (array_key_exists("REP_TAB_TITLE", $fields)) $contentResult+=$this->setRepTabTitle($fields["REP_TAB_TITLE"]); + $result=$this->save(); + $result=($result==0)?($contentResult>0?1:0):$result; + $con->commit(); + return $result; + } + else + { + $con->rollback(); + $validationE=new Exception("Failed Validation in class ".get_class($this)."."); + $validationE->aValidationFailures = $this->getValidationFailures(); + throw($validationE); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function remove($RepTabUid) + { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + try + { + $con->begin(); + $oRepTab = ReportTablePeer::retrieveByPK( $RepTabUid ); + if (!is_null($oRepTab)) { + Content::removeContent( 'REP_TAB_TITLE', '', $this->getRepTabUid()); + $result = $oRepTab->delete(); + $con->commit(); + } + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + function reportTableExists ( $RepTabUid ) { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + try { + $oRepTabUid = ReportTablePeer::retrieveByPk( $RepTabUid ); + if ( get_class ($oRepTabUid) == 'ReportTable' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } +} // ReportTable diff --git a/workflow/engine/classes/model/ReportTablePeer.php b/workflow/engine/classes/model/ReportTablePeer.php new file mode 100644 index 000000000..eb692b441 --- /dev/null +++ b/workflow/engine/classes/model/ReportTablePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseReportTablePeer.php'; + + // include object class + include_once 'classes/model/ReportTable.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'REPORT_TABLE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ReportTablePeer extends BaseReportTablePeer { + +} // ReportTablePeer diff --git a/workflow/engine/classes/model/ReportVar.php b/workflow/engine/classes/model/ReportVar.php new file mode 100644 index 000000000..58988cd29 --- /dev/null +++ b/workflow/engine/classes/model/ReportVar.php @@ -0,0 +1,158 @@ +<?php + +require_once 'classes/model/om/BaseReportVar.php'; + + +/** + * Skeleton subclass for representing a row from the 'REPORT_VAR' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ReportVar extends BaseReportVar { + /* + * Load the report var registry + * @param string $sRepVarUid + * @return variant + */ + public function load($sRepVarUid) + { + try { + $oReportVar = ReportVarPeer::retrieveByPK( $sRepVarUid ); + if (!is_null($oReportVar)) + { + $aFields = $oReportVar->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the report var registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + try { + if ( isset ( $aData['REP_VAR_UID'] ) && $aData['REP_VAR_UID']== '' ) + unset ( $aData['REP_VAR_UID'] ); + if ( !isset ( $aData['REP_VAR_UID'] ) ) + $aData['REP_VAR_UID'] = G::generateUniqueID(); + $oReportVar = new ReportVar(); + $oReportVar->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oReportVar->validate()) { + $oConnection->begin(); + $iResult = $oReportVar->save(); + $oConnection->commit(); + return $aData['REP_VAR_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oReportVar->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the report var registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + try { + $oReportVar = ReportVarPeer::retrieveByPK($aData['REP_VAR_UID']); + if (!is_null($oReportVar)) + { + $oReportVar->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oReportVar->validate()) { + $oConnection->begin(); + $iResult = $oReportVar->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oReportVar->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the report var registry + * @param array $aData + * @return string + **/ + public function remove($sRepVarUid) + { + $oConnection = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + try { + $oReportVar = ReportVarPeer::retrieveByPK($sRepVarUid); + if (!is_null($oReportVar)) + { + $oConnection->begin(); + $iResult = $oReportVar->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function reportVarExists ( $sRepVarUid ) { + $con = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + try { + $oRepVarUid = ReportVarPeer::retrieveByPk( $sRepVarUid ); + if ( get_class ($oRepVarUid) == 'ReportVar' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } +} // ReportVar diff --git a/workflow/engine/classes/model/ReportVarPeer.php b/workflow/engine/classes/model/ReportVarPeer.php new file mode 100644 index 000000000..e4fc9efe5 --- /dev/null +++ b/workflow/engine/classes/model/ReportVarPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseReportVarPeer.php'; + + // include object class + include_once 'classes/model/ReportVar.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'REPORT_VAR' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ReportVarPeer extends BaseReportVarPeer { + +} // ReportVarPeer diff --git a/workflow/engine/classes/model/Route.php b/workflow/engine/classes/model/Route.php new file mode 100644 index 000000000..eba4b0897 --- /dev/null +++ b/workflow/engine/classes/model/Route.php @@ -0,0 +1,181 @@ +<?php +/** + * Route.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseRoute.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'ROUTE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Route extends BaseRoute { + + /* + * Load the application document registry + * @param string $sRouUid + * @return variant + */ + public function load($sRouUid) + { + try { + $oRoute = RoutePeer::retrieveByPK($sRouUid); + if (!is_null($oRoute)) + { + $aFields = $oRoute->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(RoutePeer::DATABASE_NAME); + try { + $sRouteUID = G::generateUniqueID(); + $aData['ROU_UID'] = $sRouteUID; + $oRoute = new Route(); + $oRoute->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oRoute->validate()) { + $oConnection->begin(); + $iResult = $oRoute->save(); + $oConnection->commit(); + return $sRouteUID; + } + else { + $sMessage = ''; + $aValidationFailures = $oRoute->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application document registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(RoutePeer::DATABASE_NAME); + try { + $oRoute = RoutePeer::retrieveByPK($aData['ROU_UID']); + if (!is_null($oRoute)) + { + $oRoute->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oRoute->validate()) { + $oConnection->begin(); + $iResult = $oRoute->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oRoute->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The ROUTE tables cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception( "The row " . $aData['ROU_UID'] . " doesn't exists!" )); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param array $aData + * @return string + **/ + public function remove($sRouUid) + { + $oConnection = Propel::getConnection(RoutePeer::DATABASE_NAME); + try { + $oRoute = RoutePeer::retrieveByPK($sRouUid); + if (!is_null($oRoute)) + { + $oConnection->begin(); + $iResult = $oRoute->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function routeExists ( $sRouUid ) { + $con = Propel::getConnection(RoutePeer::DATABASE_NAME); + try { + $oRouUid = RoutePeer::retrieveByPk( $sRouUid ); + if ( get_class ($oRouUid) == 'Route' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + +} // Route diff --git a/workflow/engine/classes/model/RoutePeer.php b/workflow/engine/classes/model/RoutePeer.php new file mode 100644 index 000000000..0bb31703c --- /dev/null +++ b/workflow/engine/classes/model/RoutePeer.php @@ -0,0 +1,46 @@ +<?php +/** + * RoutePeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseRoutePeer.php'; + + // include object class + include_once 'classes/model/Route.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'ROUTE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class RoutePeer extends BaseRoutePeer { + +} // RoutePeer diff --git a/workflow/engine/classes/model/Session.php b/workflow/engine/classes/model/Session.php new file mode 100644 index 000000000..a31842d37 --- /dev/null +++ b/workflow/engine/classes/model/Session.php @@ -0,0 +1,19 @@ +<?php + +require_once 'classes/model/om/BaseSession.php'; + + +/** + * Skeleton subclass for representing a row from the 'SESSION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Session extends BaseSession { + +} // Session diff --git a/workflow/engine/classes/model/SessionPeer.php b/workflow/engine/classes/model/SessionPeer.php new file mode 100644 index 000000000..27d7d6cfc --- /dev/null +++ b/workflow/engine/classes/model/SessionPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseSessionPeer.php'; + + // include object class + include_once 'classes/model/Session.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'SESSION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SessionPeer extends BaseSessionPeer { + +} // SessionPeer diff --git a/workflow/engine/classes/model/ShadowTable.php b/workflow/engine/classes/model/ShadowTable.php new file mode 100644 index 000000000..6b4a5d083 --- /dev/null +++ b/workflow/engine/classes/model/ShadowTable.php @@ -0,0 +1,87 @@ +<?php + +require_once 'classes/model/om/BaseShadowTable.php'; + + +/** + * Skeleton subclass for representing a row from the 'SHADOW_TABLE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ShadowTable extends BaseShadowTable { + function load($sUID) { + try { + $oShadowTable = ShadowTablePeer::retrieveByPK($sUID); + if (!is_null($oShadowTable)) { + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function create($aData) { + if (!isset($aData['SHD_UID'])) { + $aData['SHD_UID'] = G::generateUniqueID(); + } + else { + if ($aData['SHD_UID'] == '') { + $aData['SHD_UID'] = G::generateUniqueID(); + } + } + $oConnection = Propel::getConnection(ShadowTablePeer::DATABASE_NAME); + try { + $oShadowTable = new ShadowTable(); + $oShadowTable->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oShadowTable->validate()) { + $oConnection->begin(); + $iResult = $oShadowTable->save(); + $oConnection->commit(); + return $aData['SHD_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oShadowTable->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />' . $sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function remove($sUID) { + $oConnection = Propel::getConnection(ShadowTablePeer::DATABASE_NAME); + try { + $oShadowTable = ShadowTablePeer::retrieveByPK($sUID); + if (!is_null($oShadowTable)) { + $oConnection->begin(); + $iResult = $oShadowTable->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } +} // ShadowTable diff --git a/workflow/engine/classes/model/ShadowTablePeer.php b/workflow/engine/classes/model/ShadowTablePeer.php new file mode 100644 index 000000000..7815c9e80 --- /dev/null +++ b/workflow/engine/classes/model/ShadowTablePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseShadowTablePeer.php'; + + // include object class + include_once 'classes/model/ShadowTable.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'SHADOW_TABLE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class ShadowTablePeer extends BaseShadowTablePeer { + +} // ShadowTablePeer diff --git a/workflow/engine/classes/model/Stage.php b/workflow/engine/classes/model/Stage.php new file mode 100644 index 000000000..33c543a3c --- /dev/null +++ b/workflow/engine/classes/model/Stage.php @@ -0,0 +1,196 @@ +<?php + +require_once 'classes/model/Content.php'; +require_once 'classes/model/om/BaseStage.php'; + + +/** + * Skeleton subclass for representing a row from the 'STAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Stage extends BaseStage { + + /** + * This value goes in the content table + * @var string + */ + protected $stg_title = ''; + + /** + * Get the stg_title column value. + * @return string + */ + public function getStgTitle() { + if ( $this->getStgUid() == "" ) { + throw ( new Exception( "Error in getStgTitle, the getStgUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG' ) ? SYS_LANG : 'en'; + $this->stg_title = Content::load ( 'STG_TITLE', '', $this->getStgUid(), $lang ); + return $this->stg_title; + } + + /** + * Set the stg_title column value. + * + * @param string $v new value + * @return void + */ + public function setStgTitle($v) + { + if ( $this->getStgUid() == "" ) { + throw ( new Exception( "Error in setStgTitle, the setStgUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->stg_title !== $v || $v==="") { + $this->stg_title = $v; + $res = Content::addContent( 'STG_TITLE', '', $this->getStgUid(), $lang, $this->stg_title ); + return $res; + } + return 0; + } + + public function load($StgUid) + { + try { + $oRow = StagePeer::retrieveByPK( $StgUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + $this->setStgTitle($aFields['STG_TITLE'] = $this->getStgTitle()); + return $aFields; + } + else { + throw( new Exception( "The row '$StgUid' in table Stage doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) { + $oConnection = Propel::getConnection(StagePeer::DATABASE_NAME); + try { + if ( isset ( $aData['STG_UID'] ) && $aData['STG_UID']== '' ) + unset ( $aData['STG_UID'] ); + if ( !isset ( $aData['STG_UID'] ) ) + $aData['STG_UID'] = G::generateUniqueID(); + $oStage = new Stage(); + $oStage->fromArray($aData, BasePeer::TYPE_FIELDNAME); + $oStage->setStgTitle($aData['STG_TITLE']); + if ($oStage->validate()) { + $oConnection->begin(); + $iResult = $oStage->save(); + $oConnection->commit(); + return $aData['STG_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oStage->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function update($fields) + { + $con = Propel::getConnection(StagePeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['STG_UID']); + $this->fromArray($fields, BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $contentResult=0; + if (array_key_exists("STG_TITLE", $fields)) $contentResult+=$this->setStgTitle($fields["STG_TITLE"]); + $result=$this->save(); + $result=($result==0)?($contentResult>0?1:0):$result; + $con->commit(); + return $result; + } + else + { + $con->rollback(); + $validationE=new Exception("Failed Validation in class ".get_class($this)."."); + $validationE->aValidationFailures = $this->getValidationFailures(); + throw($validationE); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + public function remove($StgUid) + { + $con = Propel::getConnection(StagePeer::DATABASE_NAME); + try + { + $con->begin(); + $oStage = StagePeer::retrieveByPK( $StgUid ); + if (!is_null($oStage)) { + Content::removeContent( 'STG_TITLE', '', $this->getStgUid()); + $result = $oStage->delete(); + $con->commit(); + } + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + function reorderPositions($sProcessUID, $iIndex) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StagePeer::PRO_UID, $sProcessUID); + $oCriteria->add(StagePeer::STG_INDEX, $iIndex, '>'); + $oDataset = StagePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $this->update(array('STG_UID' => $aRow['STG_UID'], + 'PRO_UID' => $aRow['PRO_UID'], + 'STG_POSX' => $aRow['STG_POSX'], + 'STG_POSY' => $aRow['STG_POSY'], + 'STG_INDEX' => $aRow['STG_INDEX'] - 1)); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $Exception; + } + } + + function Exists ( $sUid ) { + try { + $oObj = StagePeer::retrieveByPk($sUid); + return (get_class($oObj) == 'Stage'); + } + catch (Exception $oError) { + throw($oError); + } + } +} // Stage diff --git a/workflow/engine/classes/model/StagePeer.php b/workflow/engine/classes/model/StagePeer.php new file mode 100644 index 000000000..bc51ae8b7 --- /dev/null +++ b/workflow/engine/classes/model/StagePeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseStagePeer.php'; + + // include object class + include_once 'classes/model/Stage.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'STAGE' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StagePeer extends BaseStagePeer { + +} // StagePeer diff --git a/workflow/engine/classes/model/Step.php b/workflow/engine/classes/model/Step.php new file mode 100644 index 000000000..6dc0b1800 --- /dev/null +++ b/workflow/engine/classes/model/Step.php @@ -0,0 +1,402 @@ +<?php +/** + * Step.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseStep.php'; + + +/** + * Skeleton subclass for representing a row from the 'STEP' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Step extends BaseStep { + function create($aData) + { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + try + { + if ( isset ( $aData['STEP_UID'] ) && $aData['STEP_UID']== '' ) + unset ( $aData['STEP_UID'] ); + if ( isset ( $aData['STEP_UID'] ) ) + $sStepUID = $aData['STEP_UID']; + else + $sStepUID = G::generateUniqueID(); + + $con->begin(); + $this->setStepUid($sStepUID); + $this->setProUid($aData['PRO_UID']); + $this->setTasUid($aData['TAS_UID']); + + if (isset ( $aData['STEP_TYPE_OBJ'] )) + $this->setStepTypeObj( $aData['STEP_TYPE_OBJ'] ); + else + $this->setStepTypeObj("DYNAFORM"); + + if (isset ( $aData['STEP_UID_OBJ'] )) + $this->setStepUidObj( $aData['STEP_UID_OBJ'] ); + else + $this->setStepUidObj(""); + + if (isset ( $aData['STEP_CONDITION'] )) + $this->setStepCondition( $aData['STEP_CONDITION'] ); + else + $this->setStepCondition(""); + + if (isset ( $aData['STEP_POSITION'] )) + $this->setStepPosition( $aData['STEP_POSITION'] ); + else + $this->setStepPosition(""); + + if (isset ( $aData['STEP_MODE'] )) + $this->setStepMode( $aData['STEP_MODE'] ); + else + $this->setStepMode(""); + + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $sStepUID; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + public function load($StepUid) + { + try { + $oRow = StepPeer::retrieveByPK( $StepUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw( new Exception( "The row '$StepUid' in table StepUid doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function loadByProcessTaskPosition($sProUid, $sTasUid, $sPosition ) + { + try { + $c = new Criteria('workflow'); + $c->add ( StepPeer::PRO_UID, $sProUid ); + $c->add ( StepPeer::TAS_UID, $sTasUid ); + $c->add ( StepPeer::STEP_POSITION, $sPosition ); + if (StepPeer::doCount($c) > 0) { + $rs = StepPeer::doSelect( $c ); + return $rs[0]; + } + else { + return null; + } + + } + catch (Exception $oError) { + throw($oError); + } + } + + /* + * Load the step information using the Task UID, the type and the object UID + * @param string $sTaskUID + * @param string $sType + * @param string $sUID + * @return variant + */ + public function loadByType($sTasUid, $sType, $sUid ) + { + try { + $c = new Criteria('workflow'); + $c->add ( StepPeer::TAS_UID, $sTasUid ); + $c->add ( StepPeer::STEP_TYPE_OBJ, $sType ); + $c->add ( StepPeer::STEP_UID_OBJ, $sUid ); + $rs = StepPeer::doSelect( $c ); + if (!is_null($rs) && !is_null($rs[0])) + { + return $rs[0]; + } + else { + throw( new Exception( "You tried to call to loadByType method without send the Task UID or Type or Object UID !" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /* + * update the step information using an array with all values + * @param array $fields + * @return variant + */ + function update($fields) + { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['STEP_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function remove($sStepUID) + { + require_once('classes/model/StepTrigger.php'); + $oStepTriggers = new StepTrigger(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepTriggerPeer::STEP_UID , $sStepUID); + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + while($oDataset->next()){ + $aRow = $oDataset->getRow(); + $oStepTriggers->remove($aRow['STEP_UID'], $aRow['TAS_UID'], $aRow['TRI_UID'], $aRow['ST_TYPE']); + } + /*$con = Propel::getConnection(StepPeer::DATABASE_NAME); + try + { + $con->begin(); + //$this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + $this->setStepUid($sStepUID); + $result=$this->delete(); + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + }*/ + $oConnection = Propel::getConnection(StepPeer::DATABASE_NAME); + try { + $oStep = StepPeer::retrieveByPK($sStepUID); + if (!is_null($oStep)) + { + $oConnection->begin(); + $iResult = $oStep->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function getNextPosition($sTaskUID) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('(COUNT(*) + 1) AS POSITION'); + $oCriteria->add(StepPeer::TAS_UID, $sTaskUID); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return (int)$aRow['POSITION']; + } + catch (Exception $oException) { + throw $Exception; + } + } + + function reOrder($sStepUID, $iPosition) { + try { + /*$oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepPeer::STEP_POSITION, StepPeer::STEP_POSITION); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepPeer::STEP_POSITION, $iPosition, '>'); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow'));*/ + $oStep = StepPeer::retrieveByPK($sStepUID); + $sTaskUID = $oStep->getTasUid(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepPeer::TAS_UID, $sTaskUID); + $oCriteria->add(StepPeer::STEP_POSITION, $iPosition, '>'); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $oStep = StepPeer::retrieveByPK($aRow['STEP_UID']); + $oStep->setStepPosition(($aRow['STEP_POSITION']) - 1); + $oStep->save(); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + function up($sStepUID = '', $sTaskUID = '', $iPosition = 0) { + try { + if ($iPosition > 1) { + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepPeer::STEP_POSITION, $iPosition); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepPeer::STEP_POSITION, ($iPosition - 1)); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepPeer::STEP_POSITION, ($iPosition - 1)); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepPeer::STEP_UID, $sStepUID); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + function down($sStepUID = '', $sTaskUID = '', $iPosition = 0) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT(*) AS MAX_POSITION'); + $oCriteria->add(StepPeer::TAS_UID, $sTaskUID); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if ($iPosition < (int)$aRow['MAX_POSITION']) { + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepPeer::STEP_POSITION, $iPosition); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepPeer::STEP_POSITION, ($iPosition + 1)); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepPeer::STEP_POSITION, ($iPosition + 1)); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepPeer::STEP_UID, $sStepUID); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + function removeStep($sType = '', $sObjUID = '') { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepPeer::STEP_TYPE_OBJ, $sType); + $oCriteria->add(StepPeer::STEP_UID_OBJ, $sObjUID); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $this->reOrder($aRow['STEP_UID'], $aRow['STEP_POSITION']); + $this->remove($aRow['STEP_UID']); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + /** + * verify if Step row specified in [sUid] exists. + * + * @param string $sUid the uid of the + */ + + function StepExists ( $sUid ) { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + try { + $oObj = StepPeer::retrieveByPk( $sUid ); + if ( get_class ($oObj) == 'Step' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * verify if a dynaform is assigned some steps + * + * @param string $sproUid the uid of the process + * @param string $sObjUID the uid of the dynaform + */ + function loadInfoAssigDynaform($sproUid,$sObjUID){ + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepPeer::PRO_UID, $sproUid); + $oCriteria->add(StepPeer::STEP_UID_OBJ, $sObjUID); + $oCriteria->add(StepPeer::STEP_TYPE_OBJ, 'DYNAFORM'); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return($aRow); + } + +} // Step diff --git a/workflow/engine/classes/model/StepPeer.php b/workflow/engine/classes/model/StepPeer.php new file mode 100644 index 000000000..9f1292c4e --- /dev/null +++ b/workflow/engine/classes/model/StepPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * StepPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseStepPeer.php'; + + // include object class + include_once 'classes/model/Step.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'STEP' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StepPeer extends BaseStepPeer { + +} // StepPeer diff --git a/workflow/engine/classes/model/StepSupervisor.php b/workflow/engine/classes/model/StepSupervisor.php new file mode 100644 index 000000000..00b1e7af5 --- /dev/null +++ b/workflow/engine/classes/model/StepSupervisor.php @@ -0,0 +1,226 @@ +<?php + +require_once 'classes/model/om/BaseStepSupervisor.php'; + + +/** + * Skeleton subclass for representing a row from the 'STEP_SUPERVISOR' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StepSupervisor extends BaseStepSupervisor { + + public function load($Uid) + { + try { + $oRow = StepSupervisorPeer::retrieveByPK( $Uid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw( new Exception( "The row '$Uid' in table StepSupervisor doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function Exists ( $Uid ) { + try { + $oPro = StepSupervisorPeer::retrieveByPk( $Uid ); + if ( get_class ($oPro) == 'StepSupervisor' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the step supervisor registry + * @param array $aData + * @return boolean + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + try { + if ( isset ( $aData['STEP_UID'] ) && $aData['STEP_UID']== '' ) + unset ( $aData['STEP_UID'] ); + if ( !isset ( $aData['STEP_UID'] ) ) + $aData['STEP_UID'] = G::generateUniqueID(); + $oStepSupervisor = new StepSupervisor(); + $oStepSupervisor->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oStepSupervisor->validate()) { + $oConnection->begin(); + $iResult = $oStepSupervisor->save(); + $oConnection->commit(); + return true; + } + else { + $sMessage = ''; + $aValidationFailures = $oStepSupervisor->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the step supervisor registry + * @param array $aData + * @return integer + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + try { + $oStepSupervisor = StepSupervisorPeer::retrieveByPK($aData['STEP_UID']); + if (!is_null($oStepSupervisor)) + { + $oStepSupervisor->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oStepSupervisor->validate()) { + $oConnection->begin(); + $iResult = $oStepSupervisor->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oStepSupervisor->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the step supervisor registry + * @param string $sStepUID + * @return integer + **/ + public function remove($sStepUID) + { + $oConnection = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + try { + $oConnection->begin(); + $this->setStepUid($sStepUID); + $iResult = $this->delete(); + $oConnection->commit(); + return $iResult; + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Get the next position for a atep + * @param string $sProcessUID + * @return integer + **/ + function getNextPosition($sProcessUID, $sType) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('(COUNT(*) + 1) AS POSITION'); + $oCriteria->add(StepSupervisorPeer::PRO_UID, $sProcessUID); + $oCriteria->add(StepSupervisorPeer::STEP_TYPE_OBJ, $sType); + $oDataset = StepSupervisorPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return (int)$aRow['POSITION']; + } + catch (Exception $oException) { + throw $Exception; + } + } + + /** + * Reorder the steps positions + * @param string $sProcessUID + * @param string $iPosition + **/ + function reorderPositions($sProcessUID, $iPosition, $sType) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepSupervisorPeer::PRO_UID, $sProcessUID); + $oCriteria->add(StepSupervisorPeer::STEP_TYPE_OBJ, $sType); + $oCriteria->add(StepSupervisorPeer::STEP_POSITION, $iPosition, '>'); + $oDataset = StepSupervisorPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next();var_dump(StepSupervisorPeer::doCount($oCriteria)); + while ($aRow = $oDataset->getRow()) {var_dump($aRow);echo "\n"; + $this->update(array('STEP_UID' => $aRow['STEP_UID'], + 'PRO_UID' => $aRow['PRO_UID'], + 'STEP_TYPE_OBJ' => $aRow['STEP_TYPE_OBJ'], + 'STEP_UID_OBJ' => $aRow['STEP_UID_OBJ'], + 'STEP_POSITION' => $aRow['STEP_POSITION'] - 1)); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $Exception; + } + } + + + function removeByObject($sType, $sObjUid) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepSupervisorPeer::STEP_TYPE_OBJ, $sType); + $oCriteria->add(StepSupervisorPeer::STEP_UID_OBJ, $sObjUid); + StepSupervisorPeer::doDelete($oCriteria); + } + catch(Exception $e) { + throw($e); + } + } + +function loadInfo($sObjUID){ + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepSupervisorPeer::STEP_UID_OBJ, $sObjUID); + $oDataset = StepSupervisorPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return($aRow); + + + } + + +} // StepSupervisor diff --git a/workflow/engine/classes/model/StepSupervisorPeer.php b/workflow/engine/classes/model/StepSupervisorPeer.php new file mode 100644 index 000000000..a13becd92 --- /dev/null +++ b/workflow/engine/classes/model/StepSupervisorPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseStepSupervisorPeer.php'; + + // include object class + include_once 'classes/model/StepSupervisor.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'STEP_SUPERVISOR' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StepSupervisorPeer extends BaseStepSupervisorPeer { + +} // StepSupervisorPeer diff --git a/workflow/engine/classes/model/StepTrigger.php b/workflow/engine/classes/model/StepTrigger.php new file mode 100644 index 000000000..112cf4dee --- /dev/null +++ b/workflow/engine/classes/model/StepTrigger.php @@ -0,0 +1,324 @@ +<?php +/** + * StepTrigger.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseStepTrigger.php'; + + +/** + * Skeleton subclass for representing a row from the 'STEP_TRIGGER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StepTrigger extends BaseStepTrigger { + function create($aData) + { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try + { + //delete old StepTrigger Rows, because is not safe insert previous verify old rows. + $criteria = new Criteria(); + $criteria->add(StepTriggerPeer::STEP_UID, $aData['STEP_UID'] ); + $criteria->add(StepTriggerPeer::TAS_UID, $aData['TAS_UID'] ); + $criteria->add(StepTriggerPeer::TRI_UID, $aData['TRI_UID'] ); + $criteria->add(StepTriggerPeer::ST_TYPE, $aData['ST_TYPE'] ); + $objects = StepTriggerPeer::doSelect($criteria, $con); + $con->begin(); + foreach($objects as $row) { + $this->remove($row->getStepUid(), $row->getTasUid(), $row->getTriUid(), $row->getStType() ); + } + $con->commit(); + + $con->begin(); + $this->setStepUid($aData['STEP_UID']); + $this->setTasUid($aData['TAS_UID']); + $this->setTriUid($aData['TRI_UID']); + $this->setStType($aData['ST_TYPE']); + $this->setStCondition(""); + $this->setStPosition(""); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw( new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function load($StepUid, $TasUid, $TriUid, $StType) + { + try { + $oRow = StepTriggerPeer::retrieveByPK( $StepUid, $TasUid, $TriUid, $StType ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception( "The row '$StepUid, $TasUid, $TriUid, $StType' in table StepTrigger doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + function update($fields) + { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['STEP_UID'],$fields['TAS_UID'],$fields['TRI_UID'],$fields['ST_TYPE']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function remove($StepUid, $TasUid, $TriUid, $StType) + { + $oConnection = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try { + $oStepTrigger = StepTriggerPeer::retrieveByPK($StepUid, $TasUid, $TriUid, $StType); + if (!is_null($oStepTrigger)) + { + $oConnection->begin(); + $iResult = $oStepTrigger->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception( "The row '$StepUid, $TasUid, $TriUid, $StType' in table StepTrigger doesn't exist!" )); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function stepTriggerExists ($StepUid, $TasUid, $TriUid, $StType) { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try { + $oObj = StepTriggerPeer::retrieveByPk($StepUid, $TasUid, $TriUid, $StType); + if ( get_class ($oObj) == 'StepTrigger' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function removeTrigger($TriUid) + { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try + { + $criteria = new Criteria(); + //$criteria->add(StepTriggerPeer::STEP_UID, $step_uid); + //$criteria->add(StepTriggerPeer::TAS_UID, $tas_uid); + $criteria->add(StepTriggerPeer::TRI_UID, $TriUid); + //$criteria->add(StepTriggerPeer::ST_TYPE, $st_type); + $objects = StepTriggerPeer::doSelect($criteria, $con); + $con->begin(); + foreach($objects as $v) + { + $this->remove($v->getStepUid,$v->getTasUid,$v->getTriUid,$v->getStType); + } + $con->commit(); + return count($objects); + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function getNextPosition($sStepUID, $sType) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('(COUNT(*) + 1) AS POSITION'); + $oCriteria->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria->add(StepTriggerPeer::ST_TYPE, $sType); + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + return (int)$aRow['POSITION']; + } + catch (Exception $oException) { + throw $oException; + } + } + function reOrder($sStepUID, $sTaskUID, $sType, $iPosition) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria->add(StepTriggerPeer::ST_TYPE, $sType); + $oCriteria->add(StepTriggerPeer::ST_POSITION, $iPosition, '>'); + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $oStep = StepTriggerPeer::retrieveByPK($aRow['STEP_UID'], $aRow['TAS_UID'], $aRow['TRI_UID'], $aRow['ST_TYPE']); + $oStep->setStPosition(($aRow['ST_POSITION']) - 1); + $oStep->save(); + $oDataset->next(); + } + } + catch (Exception $oException) { + throw $oException; + } + } + function up($sStepUID = '', $sTaskUID = '', $sTriggerUID = '', $sType = '', $iPosition = 0) { + try { + if ($iPosition > 1) { + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepTriggerPeer::ST_POSITION, $iPosition); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria2->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepTriggerPeer::ST_TYPE, $sType); + $oCriteria2->add(StepTriggerPeer::ST_POSITION, ($iPosition - 1)); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepTriggerPeer::ST_POSITION, ($iPosition - 1)); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria2->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepTriggerPeer::TRI_UID, $sTriggerUID); + $oCriteria2->add(StepTriggerPeer::ST_TYPE, $sType); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + function down($sStepUID = '', $sTaskUID = '', $sTriggerUID = '', $sType = '', $iPosition = 0) { + try { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT(*) AS MAX_POSITION'); + $oCriteria->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria->add(StepTriggerPeer::ST_TYPE, $sType); + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if ($iPosition < (int)$aRow['MAX_POSITION']) { + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepTriggerPeer::ST_POSITION, $iPosition); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria2->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepTriggerPeer::ST_TYPE, $sType); + $oCriteria2->add(StepTriggerPeer::ST_POSITION, ($iPosition + 1)); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(StepTriggerPeer::ST_POSITION, ($iPosition + 1)); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(StepTriggerPeer::STEP_UID, $sStepUID); + $oCriteria2->add(StepTriggerPeer::TAS_UID, $sTaskUID); + $oCriteria2->add(StepTriggerPeer::TRI_UID, $sTriggerUID); + $oCriteria2->add(StepTriggerPeer::ST_TYPE, $sType); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + } + } + catch (Exception $oException) { + throw $oException; + } + } + + function createRow($aData) + { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->fromArray($aData,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $this->setStepUid($aData['STEP_UID']); + $this->setTasUid($aData['TAS_UID']); + $this->setTriUid($aData['TRI_UID']); + $this->setStType($aData['ST_TYPE']); + $this->setStCondition($aData['ST_CONDITION']); + $this->setStPosition($aData['ST_POSITION']); + + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw( new Exception("Failed Validation in class ".get_class($this).".")); + $e->aValidationFailures=$this->getValidationFailures(); + throw($e); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } +} // StepTrigger diff --git a/workflow/engine/classes/model/StepTriggerPeer.php b/workflow/engine/classes/model/StepTriggerPeer.php new file mode 100644 index 000000000..7d7117e47 --- /dev/null +++ b/workflow/engine/classes/model/StepTriggerPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * StepTriggerPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseStepTriggerPeer.php'; + + // include object class + include_once 'classes/model/StepTrigger.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'STEP_TRIGGER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class StepTriggerPeer extends BaseStepTriggerPeer { + +} // StepTriggerPeer diff --git a/workflow/engine/classes/model/SubApplication.php b/workflow/engine/classes/model/SubApplication.php new file mode 100644 index 000000000..3036308a6 --- /dev/null +++ b/workflow/engine/classes/model/SubApplication.php @@ -0,0 +1,94 @@ +<?php + +require_once 'classes/model/om/BaseSubApplication.php'; + + +/** + * Skeleton subclass for representing a row from the 'SUB_APPLICATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SubApplication extends BaseSubApplication { + + public function load($sAppUID, $sAppParent, $iIndexParent, $iThreadParent) { + try { + $oRow = SubApplicationPeer::retrieveByPK($sAppUID, $sAppParent, $iIndexParent, $iThreadParent); + if (!is_null($oRow)) { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw new Exception("The row '$sAppUID, $sAppParent, $iIndexParent, $iThreadParent' in table SubApplication doesn't exist!"); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) { + $oConnection = Propel::getConnection(SubApplicationPeer::DATABASE_NAME); + try { + $oSubApplication = new SubApplication(); + $oSubApplication->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oSubApplication->validate()) { + $oConnection->begin(); + $iResult = $oSubApplication->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oSubApplication->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function update($aData) { + $oConnection = Propel::getConnection(SubApplicationPeer::DATABASE_NAME); + try { + $oSubApplication = SubApplicationPeer::retrieveByPK($aData['APP_UID'], $aData['APP_PARENT'], $aData['DEL_INDEX_PARENT'], $aData['DEL_THREAD_PARENT']); + if (!is_null($oSubApplication)) { + $oSubApplication->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oSubApplication->validate()) { + $oConnection->begin(); + $iResult = $oSubApplication->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oSubApplication->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exist!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + +} // SubApplication diff --git a/workflow/engine/classes/model/SubApplicationPeer.php b/workflow/engine/classes/model/SubApplicationPeer.php new file mode 100644 index 000000000..f4fd37897 --- /dev/null +++ b/workflow/engine/classes/model/SubApplicationPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseSubApplicationPeer.php'; + + // include object class + include_once 'classes/model/SubApplication.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'SUB_APPLICATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SubApplicationPeer extends BaseSubApplicationPeer { + +} // SubApplicationPeer diff --git a/workflow/engine/classes/model/SubProcess.php b/workflow/engine/classes/model/SubProcess.php new file mode 100644 index 000000000..7616764c5 --- /dev/null +++ b/workflow/engine/classes/model/SubProcess.php @@ -0,0 +1,162 @@ +<?php + +require_once 'classes/model/om/BaseSubProcess.php'; + + +/** + * Skeleton subclass for representing a row from the 'SUB_PROCESS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SubProcess extends BaseSubProcess { + + public function load($SP_UID) + { + try { + $oRow = SubProcessPeer::retrieveByPK( $SP_UID ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw( new Exception( "The row '$SP_UID' in table SubProcess doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) + { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + try + { + $con->begin(); + if ( isset ( $aData['SP_UID'] ) && $aData['SP_UID']== '' ) + unset ( $aData['SP_UID'] ); + if ( !isset ( $aData['SP_UID'] ) ) + $this->setSpUid(G::generateUniqueID()); + else + $this->setSpUid($aData['SP_UID'] ); + + $this->setProUid($aData['PRO_UID']); + + $this->setTasUid($aData['TAS_UID']); + + $this->setProParent($aData['PRO_PARENT']); + + $this->setTasParent($aData['TAS_PARENT']); + + $this->setSpType($aData['SP_TYPE']); + + $this->setSpSynchronous($aData['SP_SYNCHRONOUS']); + + $this->setSpSynchronousType($aData['SP_SYNCHRONOUS_TYPE']); + + $this->setSpSynchronousWait($aData['SP_SYNCHRONOUS_WAIT']); + + $this->setSpVariablesOut($aData['SP_VARIABLES_OUT']); + + $this->setSpVariablesIn($aData['SP_VARIABLES_IN']); + + $this->setSpGridIn($aData['SP_GRID_IN']); + + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function update($fields) + { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['SP_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + $validationE=new Exception("Failed Validation in class ".get_class($this)."."); + $validationE->aValidationFailures = $this->getValidationFailures(); + throw($validationE); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function remove($SP_UID) + { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + try + { + $con->begin(); + $oRepTab = SubProcessPeer::retrieveByPK( $SP_UID ); + if (!is_null($oRepTab)) { + $result = $oRepTab->delete(); + $con->commit(); + } + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + /** + * verify if Trigger row specified in [sUid] exists. + * + * @param string $sUid the uid of the Prolication + */ + + function subProcessExists ( $sUid ) { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + try { + $oObj = SubProcessPeer::retrieveByPk( $sUid ); + if ( get_class ($oObj) == 'SubProcess' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + +} // SubProcess diff --git a/workflow/engine/classes/model/SubProcessPeer.php b/workflow/engine/classes/model/SubProcessPeer.php new file mode 100644 index 000000000..897fdc8bc --- /dev/null +++ b/workflow/engine/classes/model/SubProcessPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseSubProcessPeer.php'; + + // include object class + include_once 'classes/model/SubProcess.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'SUB_PROCESS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SubProcessPeer extends BaseSubProcessPeer { + +} // SubProcessPeer diff --git a/workflow/engine/classes/model/SwimlanesElements.php b/workflow/engine/classes/model/SwimlanesElements.php new file mode 100644 index 000000000..2230a240c --- /dev/null +++ b/workflow/engine/classes/model/SwimlanesElements.php @@ -0,0 +1,235 @@ +<?php +/** + * SwimlanesElements.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseSwimlanesElements.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'SWIMLANES_ELEMENTS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the input directory. + * + * @package classes.model + */ +class SwimlanesElements extends BaseSwimlanesElements { + + /** + * This value goes in the content table + * @var string + */ + protected $swi_text = ''; + + /* + * Load the application document registry + * @param string $sAppDocUid + * @return variant + */ + public function load($sSwiEleUid) + { + try { + $oSwimlanesElements = SwimlanesElementsPeer::retrieveByPK($sSwiEleUid); + if (!is_null($oSwimlanesElements)) + { + $aFields = $oSwimlanesElements->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['SWI_TEXT'] = $oSwimlanesElements->getSwiEleText(); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + try { + $aData['SWI_UID'] = G::generateUniqueID(); + $oSwimlanesElements = new SwimlanesElements(); + $oSwimlanesElements->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oSwimlanesElements->validate()) { + $oConnection->begin(); + if (isset($aData['SWI_TEXT'])) { + $oSwimlanesElements->setSwiEleText($aData['SWI_TEXT']); + } + $iResult = $oSwimlanesElements->save(); + $oConnection->commit(); + return $aData['SWI_UID']; + } + else { + $sMessage = ''; + $aValidationFailures = $oSwimlanesElements->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Update the application document registry + * @param array $aData + * @return string + **/ + public function update($aData) + { + $oConnection = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + try { + $oSwimlanesElements = SwimlanesElementsPeer::retrieveByPK($aData['SWI_UID']); + if (!is_null($oSwimlanesElements)) + { + $oSwimlanesElements->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oSwimlanesElements->validate()) { + $oConnection->begin(); + if (isset($aData['SWI_TEXT'])) + { + $oSwimlanesElements->setSwiEleText($aData['SWI_TEXT']); + } + $iResult = $oSwimlanesElements->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oSwimlanesElements->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param array $aData + * @return string + **/ + public function remove($sSwiEleUid) + { + $oConnection = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + try { + $oSwimlanesElements = SwimlanesElementsPeer::retrieveByPK($sSwiEleUid); + if (!is_null($oSwimlanesElements)) + { + $oConnection->begin(); + Content::removeContent('SWI_TEXT', '', $oSwimlanesElements->getSwiUid()); + $iResult = $oSwimlanesElements->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + +function swimlanesElementsExists ( $sSwiEleUid ) { + $con = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + try { + $oSwiEleUid = SwimlanesElementsPeer::retrieveByPk( $sSwiEleUid ); + if ( get_class ($oSwiEleUid) == 'SwimlanesElements' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * Get the [swi_text] column value. + * @return string + */ + public function getSwiEleText() + { + if ($this->swi_text == '') { + try { + $this->swi_text = Content::load('SWI_TEXT', '', $this->getSwiUid(), (defined('SYS_LANG') ? SYS_LANG : 'en')); + } + catch (Exception $oError) { + throw($oError); + } + } + return $this->swi_text; + } + + /** + * Set the [swi_text] column value. + * + * @param string $sValue new value + * @return void + */ + public function setSwiEleText($sValue) + { + if ($sValue !== null && !is_string($sValue)) { + $sValue = (string)$sValue; + } + if ($this->swi_text !== $sValue || $sValue === '') { + try { + $this->swi_text = $sValue; + $iResult = Content::addContent('SWI_TEXT', '', $this->getSwiUid(), (defined('SYS_LANG') ? SYS_LANG : 'en'), $this->swi_text); + } + catch (Exception $oError) { + $this->swi_text = ''; + throw($oError); + } + } + } + +} // SwimlanesElements \ No newline at end of file diff --git a/workflow/engine/classes/model/SwimlanesElementsPeer.php b/workflow/engine/classes/model/SwimlanesElementsPeer.php new file mode 100644 index 000000000..a8aa43a2f --- /dev/null +++ b/workflow/engine/classes/model/SwimlanesElementsPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * SwimlanesElementsPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseSwimlanesElementsPeer.php'; + + // include object class + include_once 'classes/model/SwimlanesElements.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'SWIMLANES_ELEMENTS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class SwimlanesElementsPeer extends BaseSwimlanesElementsPeer { + +} // SwimlanesElementsPeer diff --git a/workflow/engine/classes/model/Task.php b/workflow/engine/classes/model/Task.php new file mode 100644 index 000000000..350b6fe7c --- /dev/null +++ b/workflow/engine/classes/model/Task.php @@ -0,0 +1,562 @@ +<?php +/** + * Task.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseTask.php'; +require_once 'classes/model/Content.php'; + + +/** + * Skeleton subclass for representing a row from the 'TASK' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Task extends BaseTask { + /** + * This value goes in the content table + * @var string + */ + protected $tas_title = ''; + /** + * Get the tas_title column value. + * @return string + */ + public function getTasTitle() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasTitle, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_title = Content::load ( 'TAS_TITLE', '', $this->getTasUid(), $lang ); + return $this->tas_title; + } + /** + * Set the tas_title column value. + * + * @param string $v new value + * @return void + */ + public function setTasTitle($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasTitle, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_title !== $v || $v==="") { + $this->tas_title = $v; + $res = Content::addContent( 'TAS_TITLE', '', $this->getTasUid(), $lang, $this->tas_title ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tas_description = ''; + /** + * Get the tas_description column value. + * @return string + */ + public function getTasDescription() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasDescription, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_description = Content::load ( 'TAS_DESCRIPTION', '', $this->getTasUid(), $lang ); + return $this->tas_description; + } + /** + * Set the tas_description column value. + * + * @param string $v new value + * @return void + */ + public function setTasDescription($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasDescription, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_description !== $v || $v==="") { + $this->tas_description = $v; + $res = Content::addContent( 'TAS_DESCRIPTION', '', $this->getTasUid(), $lang, $this->tas_description ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tas_def_title = ''; + /** + * Get the tas_def_title column value. + * @return string + */ + public function getTasDefTitle() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasDefTitle, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_def_title = Content::load ( 'TAS_DEF_TITLE', '', $this->getTasUid(), $lang ); + return $this->tas_def_title; + } + /** + * Set the tas_def_title column value. + * + * @param string $v new value + * @return void + */ + public function setTasDefTitle($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasDefTitle, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_def_title !== $v || $v==="") { + $this->tas_def_title = $v; + $res = Content::addContent( 'TAS_DEF_TITLE', '', $this->getTasUid(), $lang, $this->tas_def_title ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tas_def_description = ''; + /** + * Get the tas_def_description column value. + * @return string + */ + public function getTasDefDescription() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasDefDescription, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_def_description = Content::load ( 'TAS_DEF_DESCRIPTION', '', $this->getTasUid(), $lang ); + return $this->tas_def_description; + } + /** + * Set the tas_def_description column value. + * + * @param string $v new value + * @return void + */ + public function setTasDefDescription($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasDefDescription, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_def_description !== $v || $v==="") { + $this->tas_def_description = $v; + $res = Content::addContent( 'TAS_DEF_DESCRIPTION', '', $this->getTasUid(), $lang, $this->tas_def_description ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tas_def_proc_code = ''; + /** + * Get the tas_def_proc_code column value. + * @return string + */ + public function getTasDefProcCode() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasDefProcCode, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_def_proc_code = Content::load ( 'TAS_DEF_PROC_CODE', '', $this->getTasUid(), $lang ); + return $this->tas_def_proc_code; + } + /** + * Set the tas_def_proc_code column value. + * + * @param string $v new value + * @return void + */ + public function setTasDefProcCode($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasDefProcCode, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_def_proc_code !== $v || $v==="") { + $this->tas_def_proc_code = $v; + $res = Content::addContent( 'TAS_DEF_PROC_CODE', '', $this->getTasUid(), $lang, $this->tas_def_proc_code ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tas_def_message = ''; + /** + * Get the tas_def_message column value. + * @return string + */ + public function getTasDefMessage() + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in getTasDefMessage, the getTasUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tas_def_message = Content::load ( 'TAS_DEF_MESSAGE', '', $this->getTasUid(), $lang ); + return $this->tas_def_message; + } + /** + * Set the tas_def_message column value. + * + * @param string $v new value + * @return void + */ + public function setTasDefMessage($v) + { + if ( $this->getTasUid() == "" ) { + throw ( new Exception( "Error in setTasDefMessage, the getTasUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tas_def_message !== $v || $v==="") { + $this->tas_def_message = $v; + $res = Content::addContent( 'TAS_DEF_MESSAGE', '', $this->getTasUid(), $lang, $this->tas_def_message ); + return $res; + } + return 0; + } + + /** + * create a new Task + * + * @param array $aData with new values + * @return void + */ + function create($aData) + { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + try + { + $sTaskUID = G::generateUniqueID(); + $con->begin(); + $this->setProUid($aData['PRO_UID']); + $this->setTasUid($sTaskUID); + $this->setTasType("NORMAL"); + $this->setTasDuration("1"); + $this->setTasDelayType(""); + $this->setTasTemporizer(""); + $this->setTasTypeDay(""); + $this->setTasTimeunit("DAYS"); + $this->setTasAlert("FALSE"); + $this->setTasPriorityVariable("@@SYS_CASE_PRIORITY"); + $this->setTasAssignType("BALANCED"); + $this->setTasAssignVariable("@@SYS_NEXT_USER_TO_BE_ASSIGNED"); + $this->setTasAssignLocation("FALSE"); + $this->setTasAssignLocationAdhoc("FALSE"); + $this->setTasTransferFly("FALSE"); + $this->setTasLastAssigned("0"); + $this->setTasUser("0"); + $this->setTasCanUpload("FALSE"); + $this->setTasViewUpload("FALSE"); + $this->setTasViewAdditionalDocumentation("FALSE"); + $this->setTasCanCancel("FALSE"); + $this->setTasOwnerApp("FALSE"); + $this->setStgUid(""); + $this->setTasCanPause("FALSE"); + $this->setTasCanSendMessage("TRUE"); + $this->setTasCanDeleteDocs("FALSE"); + $this->setTasSelfService("FALSE"); + $this->setTasStart("FALSE"); + $this->setTasToLastUser("FALSE"); + $this->setTasSendLastEmail("TRUE"); + $this->setTasDerivation("NORMAL"); + $this->setTasPosx(""); + $this->setTasPosy(""); + $this->setTasColor(""); + $this->fromArray($aData,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $this->setTasTitle((isset($aData['TAS_TITLE']) ? $aData['TAS_TITLE']: '')); + $this->setTasDescription(""); + $this->setTasDefTitle(""); + $this->setTasDefDescription(""); + $this->setTasDefProcCode(""); + $this->setTasDefMessage(""); + $this->save(); + $con->commit(); + return $sTaskUID; + } + else + { + $con->rollback(); + $e=new Exception("Failed Validation in class ".get_class($this)."."); + $e->aValidationFailures=$this->getValidationFailures(); + throw($e); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + +public function kgetassigType($pro_uid, $tas){ + + $k = new Criteria(); + $k->clearSelectColumns(); + $k->addSelectColumn(TaskPeer::TAS_UID); + $k->addSelectColumn(TaskPeer::TAS_ASSIGN_TYPE); + $k->add(TaskPeer::PRO_UID, $pro_uid ); + $k->add(TaskPeer::TAS_UID, $tas ); + $rs = TaskPeer::doSelectRS($k); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + return $row; + } + + public function load($TasUid) + { + try { + $oRow = TaskPeer::retrieveByPK( $TasUid ); + if ( !is_null($oRow) ) + { + $aFields = $oRow->toArray( BasePeer::TYPE_FIELDNAME ); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + //SELECT CONTENT.CON_CATEGORY, CONTENT.CON_VALUE FROM CONTENT WHERE CONTENT.CON_ID='63515150649b03231c3b020026243292' AND CONTENT.CON_LANG='es' + $c = new Criteria(); + $c->clearSelectColumns(); + $c->addSelectColumn(ContentPeer::CON_CATEGORY); + $c->addSelectColumn(ContentPeer::CON_VALUE); + $c->add(ContentPeer::CON_ID, $TasUid ); + $c->add(ContentPeer::CON_LANG, $lang ); + $rs = TaskPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + + while (is_array($row)) { + switch ( $row['CON_CATEGORY'] ) { + case 'TAS_TITLE' : $aFields['TAS_TITLE'] = $row['CON_VALUE']; + $this->tas_title = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasTitle($aFields['TAS_TITLE']); + break; + case 'TAS_DESCRIPTION' : $aFields['TAS_DESCRIPTION'] = $row['CON_VALUE']; + $this->tas_description = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasDescription($aFields['TAS_DESCRIPTION']); + break; + case 'TAS_DEF_TITLE' : $aFields['TAS_DEF_TITLE'] = $row['CON_VALUE']; + $this->tas_def_title = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasDefTitle($aFields['TAS_DEF_TITLE']); + break; + case 'TAS_DEF_DESCRIPTION' : $aFields['TAS_DEF_DESCRIPTION'] = $row['CON_VALUE']; + $this->tas_def_description = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasDefDescription($aFields['TAS_DEF_DESCRIPTION']); + break; + case 'TAS_DEF_PROC_CODE' : $aFields['TAS_DEF_PROC_CODE'] = $row['CON_VALUE']; + $this->tas_def_proc_code = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasDefProcCode($aFields['TAS_DEF_PROC_CODE']); + break; + case 'TAS_DEF_MESSAGE' : $aFields['TAS_DEF_MESSAGE'] = $row['CON_VALUE']; + $this->tas_def_message = $row['CON_VALUE']; + if ( $row['CON_VALUE'] !== '' ) + $this->setTasDefMessage($aFields["TAS_DEF_MESSAGE"]); + break; + } + $rs->next(); + $row = $rs->getRow(); + } + return $aFields; + } + else { + throw( new Exception( "The row '" . $TasUid . "' in table TASK doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + function update($fields) + { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['TAS_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $contentResult=0; + if (array_key_exists("TAS_TITLE", $fields)) $contentResult+=$this->setTasTitle($fields["TAS_TITLE"]); + if (array_key_exists("TAS_DESCRIPTION", $fields)) $contentResult+=$this->setTasDescription($fields["TAS_DESCRIPTION"]); + if (array_key_exists("TAS_DEF_TITLE", $fields)) $contentResult+=$this->setTasDefTitle($fields["TAS_DEF_TITLE"]); + if (array_key_exists("TAS_DEF_DESCRIPTION", $fields)) $contentResult+=$this->setTasDefDescription($fields["TAS_DEF_DESCRIPTION"]); + if (array_key_exists("TAS_DEF_PROC_CODE", $fields)) $contentResult+=$this->setTasDefProcCode($fields["TAS_DEF_PROC_CODE"]); + if (array_key_exists("TAS_DEF_MESSAGE", $fields)) $contentResult+=$this->setTasDefMessage($fields["TAS_DEF_MESSAGE"]); + if (array_key_exists("TAS_CALENDAR", $fields)) $contentResult+=$this->setTasCalendar($fields['TAS_UID'],$fields["TAS_CALENDAR"]); + $result=$this->save(); + $result=($result==0)?($contentResult>0?1:0):$result; + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function remove($TasUid) + { + $oConnection = Propel::getConnection(TaskPeer::DATABASE_NAME); + try { + $oTask = TaskPeer::retrieveByPK($TasUid); + if (!is_null($oTask)) + { + $oConnection->begin(); + Content::removeContent('TAS_TITLE', '', $oTask->getTasUid()); + Content::removeContent('TAS_DESCRIPTION', '', $oTask->getTasUid()); + Content::removeContent('TAS_DEF_TITLE', '', $oTask->getTasUid()); + Content::removeContent('TAS_DEF_DESCRIPTION', '', $oTask->getTasUid()); + Content::removeContent('TAS_DEF_PROC_CODE', '', $oTask->getTasUid()); + Content::removeContent('TAS_DEF_MESSAGE', '', $oTask->getTasUid()); + $iResult = $oTask->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw( new Exception( "The row '" . $TasUid . "' in table TASK doesn't exist!" )); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * verify if Task row specified in [TasUid] exists. + * + * @param string $sProUid the uid of the Prolication + */ + + function taskExists ( $TasUid ) { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + try { + $oPro = TaskPeer::retrieveByPk( $TasUid ); + if ( get_class ($oPro) == 'Task' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + /** + * create a new Task + * + * @param array $aData with new values + * @return void + */ + function createRow($aData) + { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + try + { + $con->begin(); + + $this->fromArray($aData,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $this->setTasTitle((isset($aData['TAS_TITLE']) ? $aData['TAS_TITLE']: '')); + $this->setTasDescription((isset($aData['TAS_DESCRIPTION']) ? $aData['TAS_DESCRIPTION']: '')); + $this->setTasDefTitle((isset($aData['TAS_DEF_TITLE']) ? $aData['TAS_DEF_TITLE']: '')); + $this->setTasDefDescription((isset($aData['TAS_DEF_DESCRIPTION']) ? $aData['TAS_DEF_DESCRIPTION']: '')); + $this->setTasDefProcCode((isset($aData['TAS_DEF_DESCRIPTION']) ? $aData['TAS_DEF_DESCRIPTION']: '')); + $this->setTasDefMessage((isset($aData['TAS_DEF_MESSAGE']) ? $aData['TAS_DEF_MESSAGE']: '')); + $this->save(); + $con->commit(); + return; + } + else + { + $con->rollback(); + $e=new Exception("Failed Validation in class ".get_class($this)."."); + $e->aValidationFailures=$this->getValidationFailures(); + throw($e); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function setTasCalendar($taskUid,$calendarUid){ + //Save Calendar ID for this process + G::LoadClass("calendar"); + $calendarObj=new Calendar(); + $calendarObj->assignCalendarTo($taskUid,$calendarUid,'TASK'); + } + +} // Task diff --git a/workflow/engine/classes/model/TaskPeer.php b/workflow/engine/classes/model/TaskPeer.php new file mode 100644 index 000000000..83713ca72 --- /dev/null +++ b/workflow/engine/classes/model/TaskPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * TaskPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseTaskPeer.php'; + + // include object class + include_once 'classes/model/Task.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'TASK' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class TaskPeer extends BaseTaskPeer { + +} // TaskPeer diff --git a/workflow/engine/classes/model/TaskUser.php b/workflow/engine/classes/model/TaskUser.php new file mode 100644 index 000000000..d8f71de77 --- /dev/null +++ b/workflow/engine/classes/model/TaskUser.php @@ -0,0 +1,132 @@ +<?php +/** + * TaskUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseTaskUser.php'; +require_once 'classes/model/Content.php'; + +/** + * Skeleton subclass for representing a row from the 'GROUP_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the input directory. + * + * @package classes.model + */ +class TaskUser extends BaseTaskUser { + + /** + * Create the application document registry + * @param array $aData + * @return string + **/ + public function create($aData) + { + $oConnection = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + try { + //delete old TaskUserPeer Rows, because is not safe insert previous verify old rows. + $criteria = new Criteria('workflow'); + $criteria->add(TaskUserPeer::TAS_UID, $aData['TAS_UID'] ); + $criteria->add(TaskUserPeer::USR_UID, $aData['USR_UID'] ); + $criteria->add(TaskUserPeer::TU_TYPE, $aData['TU_TYPE'] ); + $criteria->add(TaskUserPeer::TU_RELATION, $aData['TU_RELATION'] ); + $objects = TaskUserPeer::doSelect($criteria, $oConnection); + $oConnection->begin(); + foreach($objects as $row) { + $this->remove($row->getTasUid(), $row->getUsrUid(), $row->getTuType(), $row->getTuRelation() ); + } + $oConnection->commit(); + + + $oTaskUser = new TaskUser(); + $oTaskUser->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oTaskUser->validate()) { + $oConnection->begin(); + $iResult = $oTaskUser->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oTaskUser->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + /** + * Remove the application document registry + * @param string $sTasUid + * @param string $sUserUid + * @return string + **/ + public function remove($sTasUid, $sUserUid, $iType, $iRelation) + { + $oConnection = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + try { + $oTaskUser = TaskUserPeer::retrieveByPK($sTasUid, $sUserUid, $iType, $iRelation); + if (!is_null($oTaskUser)) + { + $oConnection->begin(); + $iResult = $oTaskUser->delete(); + $oConnection->commit(); + return $iResult; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + function TaskUserExists ($sTasUid, $sUserUid, $iType, $iRelation) { + $con = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + try { + $oTaskUser = TaskUserPeer::retrieveByPk($sTasUid, $sUserUid, $iType, $iRelation); + if ( get_class ($oTaskUser) == 'TaskUser' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + +} // TaskUser \ No newline at end of file diff --git a/workflow/engine/classes/model/TaskUserPeer.php b/workflow/engine/classes/model/TaskUserPeer.php new file mode 100644 index 000000000..bdd85a2c3 --- /dev/null +++ b/workflow/engine/classes/model/TaskUserPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * TaskUserPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseTaskUserPeer.php'; + + // include object class + include_once 'classes/model/TaskUser.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'TASK_USER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class TaskUserPeer extends BaseTaskUserPeer { + +} // TaskUserPeer diff --git a/workflow/engine/classes/model/Translation.php b/workflow/engine/classes/model/Translation.php new file mode 100644 index 000000000..b30a19fb7 --- /dev/null +++ b/workflow/engine/classes/model/Translation.php @@ -0,0 +1,365 @@ +<?php +/** + * Translation.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseTranslation.php'; + + +/** + * Skeleton subclass for representing a row from the 'TRANSLATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Translation extends BaseTranslation { + + public static $meta; + public static $localeSeparator = '-'; + + function getAllCriteria(){ + + //SELECT * from TRANSLATION WHERE TRN_LANG = 'en' order by TRN_CATEGORY, TRN_ID + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TranslationPeer::TRN_ID); + $oCriteria->addSelectColumn(TranslationPeer::TRN_CATEGORY); + $oCriteria->addSelectColumn(TranslationPeer::TRN_LANG); + $oCriteria->addSelectColumn(TranslationPeer::TRN_VALUE); + //$c->add(TranslationPeer::TRN_LANG, 'en'); + + return $oCriteria; + } + + + + /* Load strings from a Database . + * @author Fernando Ontiveros <fernando@colosa.com> + * @parameter $languageId (es|en|...). + */ + + function generateFileTranslation ($languageId = '') { + $translation = Array(); + $translationJS = Array(); + + if ($languageId === '') + $languageId = defined('SYS_LANG') ? SYS_LANG : 'en'; + + $c = new Criteria(); + $c->add(TranslationPeer::TRN_LANG, $languageId ); + $c->addAscendingOrderByColumn ( 'TRN_CATEGORY' ); + $c->addAscendingOrderByColumn ( 'TRN_ID' ); + $tranlations = TranslationPeer::doSelect($c); + + $cacheFile = PATH_LANGUAGECONT . "translation." . $languageId; + $cacheFileJS = PATH_CORE . 'js' . PATH_SEP . 'labels' . PATH_SEP . $languageId.".js"; + + foreach ( $tranlations as $key => $row ) { + if ( $row->getTrnCategory() === 'LABEL' ) { + $translation[ $row->getTrnId() ] = $row->getTrnValue(); + } + if ( $row->getTrnCategory() === 'JAVASCRIPT') { + $translationJS[ $row->getTrnId() ] = $row->getTrnValue(); + } + } + + + $f = fopen( $cacheFile , 'w'); + fwrite( $f , "<?\n" ); + fwrite( $f , '$translation =' . 'unserialize(\'' . addcslashes( serialize ( $translation ), '\\\'' ) . "');\n"); + fwrite( $f , "?>" ); + fclose( $f ); + + $json=new Services_JSON(); + + $f = fopen( $cacheFileJS , 'w'); + fwrite( $f , "var G_STRINGS =". $json->encode( $translationJS ) . ";\n"); + fclose( $f ); + + $res['cacheFile'] = $cacheFile; + $res['cacheFileJS'] = $cacheFileJS; + $res['rows'] = count ( $translation ); + $res['rowsJS'] = count ( $translationJS ); + return $res; + } + + /** + * returns an array with + * codError 0 - no error, < 0 error + * rowsAffected 0,1 the number of rows affected + * message message error. + */ + function addTranslation ( $category, $id, $languageId, $value ) { + //if exists the row in the database propel will update it, otherwise will insert. + $tr = TranslationPeer::retrieveByPK( $category, $id, $languageId ); + if ( ! ( is_object ( $tr ) && get_class ($tr) == 'Translation' ) ) { + $tr = new Translation(); + } + $tr->setTrnCategory( $category ); + $tr->setTrnId( $id ); + $tr->setTrnLang( $languageId); + $tr->setTrnValue( $value ); + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + //to do: uniform coderror structures for all classes + } + + function remove($sCategory, $sId, $sLang) { + $oTranslation = TranslationPeer::retrieveByPK($sCategory, $sId, $sLang); + if ( ( is_object ( $oTranslation ) && get_class ($oTranslation) == 'Translation' ) ) { + $oTranslation->delete(); + } + } + + function addTranslationEnvironment($locale, $headers, $numRecords) + { + $filePath = PATH_LANGUAGECONT . "translations.environments"; + $environments = Array(); + + if( file_exists($filePath) ) { + $environments = unserialize(file_get_contents($filePath)); + } + + $environment['LOCALE'] = $locale; + $environment['HEADERS'] = $headers; + $environment['DATE'] = date('Y-m-d H:i:s'); + $environment['NUM_RECORDS'] = $numRecords; + $environment['LANGUAGE'] = $headers['X-Poedit-Language']; + $environment['COUNTRY'] = $headers['X-Poedit-Country']; + + if( strpos($locale, self::$localeSeparator) !== false ) { + list($environment['LAN_ID'], $environment['IC_UID']) = explode(self::$localeSeparator, strtoupper($locale)); + $environments[$environment['LAN_ID']][$environment['IC_UID']] = $environment; + } else { + $environment['LAN_ID'] = strtoupper($locale); + $environment['IC_UID'] = ''; + $environments[$locale]['__INTERNATIONAL__'] = $environment; + } + + + file_put_contents($filePath, serialize($environments)); + } + + function removeTranslationEnvironment($locale) + { + $filePath = PATH_LANGUAGECONT . "translations.environments"; + if( strpos($locale, self::$localeSeparator) !== false ) { + list($LAN_ID, $IC_UID) = explode('-', strtoupper($locale)); + } else { + $LAN_ID = $locale; + $IC_UID = '__INTERNATIONAL__'; + } + + if( file_exists($filePath) ) { + $environments = unserialize(file_get_contents($filePath)); + if( ! isset($environments[$LAN_ID][$IC_UID]) ) + return NULL; + + unset($environments[$LAN_ID][$IC_UID]); + file_put_contents($filePath, serialize($environments)); + } + } + + function getTranslationEnvironments(){ + $filePath = PATH_LANGUAGECONT . "translations.environments"; + $envs = Array(); + + if( ! file_exists($filePath) ) { + //the transaltions table file doesn't exist, then build it + $translationsPath = PATH_CORE . "content" . PATH_SEP . 'translations' . PATH_SEP; + $basePOFile = $translationsPath . 'english' . PATH_SEP . 'processmaker.en.po'; + + $params = self::getInfoFromPOFile($basePOFile); + self::addTranslationEnvironment($params['LOCALE'], $params['HEADERS'], $params['COUNT']); + + //getting more lanuguage translations + $files = glob($translationsPath . "*.po"); + foreach( $files as $file ){ + $params = self::getInfoFromPOFile($file); + self::addTranslationEnvironment($params['LOCALE'], $params['HEADERS'], $params['COUNT']); + } + } + $envs = unserialize(file_get_contents($filePath)); + + $environments = Array(); + foreach($envs as $LAN_ID => $rec1 ){ + foreach($rec1 as $IC_UID => $rec2 ){ + $environments[] = $rec2; + } + } + + return $environments; + + /*G::LoadSystem('dbMaintenance'); + $o = new DataBaseMaintenance('localhost', 'root', 'atopml2005'); + $o->connect('wf_os'); + $r = $o->query('select * from ISO_COUNTRY'); + foreach($r as $i=>$v){ + $r[$i]['IC_NAME'] = utf8_encode($r[$i]['IC_NAME']); + unset($r[$i]['IC_SORT_ORDER']); + } + $r1 = $o->query('select * from LANGUAGE'); + $r2 = Array(); + foreach($r1 as $i=>$v){ + $r2[$i]['LAN_NAME'] = utf8_encode($r1[$i]['LAN_NAME']); + $r2[$i]['LAN_ID'] = utf8_encode($r1[$i]['LAN_ID']); + } + $s = Array('ISO_COUNTRY'=>$r, 'LANGUAGE'=>$r2); + file_put_contents($translationsPath . 'pmos-translations.meta', serialize($s)); + */ + } + + function getInfoFromPOFile($file){ + G::loadClass('i18n_po'); + $POFile = new i18n_PO($file); + $POFile->readInit(); + $POHeaders = $POFile->getHeaders(); + + if( $POHeaders['X-Poedit-Country'] != '.' ) { + $country = self::getTranslationMetaByCountryName($POHeaders['X-Poedit-Country']); + } else { + $country = '.'; + } + $language = self::getTranslationMetaByLanguageName($POHeaders['X-Poedit-Language']); + + if( $language !== false ) { + if( $country !== false ) { + if( $country != '.') { + $LOCALE = $language['LAN_ID'] . '-' . $country['IC_UID']; + } else if( $country == '.' ) { + //this a trsnlation file with a language international, no country name was set + $LOCALE = $language['LAN_ID']; + } else + throw new Exception('PO File Error: "'.$file.'" has a invalid country definition!'); + } else + throw new Exception('PO File Error: "'.$file.'" has a invalid country definition!'); + } else + throw new Exception('PO File Error: "'.$file.'" has a invalid language definition!'); + + $countItems = 0; + try { + while( $rowTranslation = $POFile->getTranslation() ) { + $countItems++; + } + } catch(Exception $e) { + $countItems = '-'; + } + + return Array('LOCALE'=>$LOCALE, 'HEADERS'=>$POHeaders , 'COUNT'=>$countItems); + } + + function getTranslationEnvironment($locale){ + $filePath = PATH_LANGUAGECONT . "translations.environments"; + $environments = Array(); + + if( ! file_exists($filePath) ) { + throw new Exception("The file $filePath doesn't exist"); + } + + $environments = unserialize(file_get_contents($filePath)); + if( strpos($locale, self::$localeSeparator) !== false ) { + list($LAN_ID, $IC_UID) = explode(self::localeSeparator, strtoupper($locale)); + } else { + $LAN_ID = $locale; + $IC_UID = '__INTERNATIONAL__'; + } + + if( isset($environments[$LAN_ID][$IC_UID]) ) + return $environments[$LAN_ID][$IC_UID]; + else + return false; + } + + function saveTranslationEnvironment($locale, $data){ + $filePath = PATH_LANGUAGECONT . "translations.environments"; + $environments = Array(); + + if( ! file_exists($filePath) ) { + throw new Exception("The file $filePath doesn't exist"); + } + + $environments = unserialize(file_get_contents($filePath)); + if( strpos($locale, self::$localeSeparator) !== false ) { + list($LAN_ID, $IC_UID) = explode(self::localeSeparator, strtoupper($locale)); + } else { + $LAN_ID = $locale; + $IC_UID = '__INTERNATIONAL__'; + } + + $environments[$LAN_ID][$IC_UID] = $data; + file_put_contents($filePath, serialize($environments)); + } + + function getTranslationMeta(){ + $translationsPath = PATH_CORE . "content" . PATH_SEP . 'translations' . PATH_SEP; + $translationsTable = unserialize(file_get_contents($translationsPath . 'pmos-translations.meta')); + return $translationsTable; + } + + function getTranslationMetaByCountryName($IC_NAME){ + $translationsTable = self::getTranslationMeta(); + + foreach ($translationsTable['ISO_COUNTRY'] as $row) { + if( $row['IC_NAME'] == $IC_NAME ) + return $row; + } + return false; + } + + function getTranslationMetaByLanguageName($LAN_NAME){ + $translationsTable = self::getTranslationMeta(); + + foreach ($translationsTable['LANGUAGE'] as $row) { + if( $row['LAN_NAME'] == $LAN_NAME ) + return $row; + } + return false; + } +} // Translation + + + + + + + + + + diff --git a/workflow/engine/classes/model/TranslationPeer.php b/workflow/engine/classes/model/TranslationPeer.php new file mode 100644 index 000000000..3c388bc9e --- /dev/null +++ b/workflow/engine/classes/model/TranslationPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * TranslationPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseTranslationPeer.php'; + + // include object class + include_once 'classes/model/Translation.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'TRANSLATION' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class TranslationPeer extends BaseTranslationPeer { + +} // TranslationPeer diff --git a/workflow/engine/classes/model/Triggers.php b/workflow/engine/classes/model/Triggers.php new file mode 100644 index 000000000..c6cd25685 --- /dev/null +++ b/workflow/engine/classes/model/Triggers.php @@ -0,0 +1,330 @@ +<?php +/** + * Triggers.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/Content.php'; +require_once 'classes/model/om/BaseTriggers.php'; + + +/** + * Skeleton subclass for representing a row from the 'TRIGGER' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Triggers extends BaseTriggers { + /** + * This value goes in the content table + * @var string + */ + protected $tri_title = ''; + /** + * Get the tri_title column value. + * @return string + */ + public function getTriTitle() + { + if ( $this->getTriUid() == "" ) { + throw ( new Exception( "Error in getTriTitle, the getTriUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tri_title = Content::load ( 'TRI_TITLE', '', $this->getTriUid(), $lang ); + return $this->tri_title; + } + /** + * Set the tri_title column value. + * + * @param string $v new value + * @return void + */ + public function setTriTitle($v) + { + if ( $this->getTriUid() == "" ) { + throw ( new Exception( "Error in setTriTitle, the getTriUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tri_title !== $v || $v==="") { + $this->tri_title = $v; + $res = Content::addContent( 'TRI_TITLE', '', $this->getTriUid(), $lang, $this->tri_title ); + return $res; + } + return 0; + } + /** + * This value goes in the content table + * @var string + */ + protected $tri_description = ''; + /** + * Get the tri_description column value. + * @return string + */ + public function getTriDescription() + { + if ( $this->getTriUid() == "" ) { + throw ( new Exception( "Error in getTriDescription, the getTriUid() can't be blank") ); + } + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + $this->tri_description = Content::load ( 'TRI_DESCRIPTION', '', $this->getTriUid(), $lang ); + return $this->tri_description; + } + /** + * Set the tri_description column value. + * + * @param string $v new value + * @return void + */ + public function setTriDescription($v) + { + if ( $this->getTriUid() == "" ) { + throw ( new Exception( "Error in setTriDescription, the getTriUid() can't be blank") ); + } + $v=isset($v)?((string)$v):''; + $lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; + if ($this->tri_description !== $v || $v==="") { + $this->tri_description = $v; + $res = Content::addContent( 'TRI_DESCRIPTION', '', $this->getTriUid(), $lang, $this->tri_description ); + return $res; + } + return 0; + } + public function load($TriUid) + { + try { + $oRow = TriggersPeer::retrieveByPK( $TriUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + $this->setTriTitle($aFields['TRI_TITLE']=$this->getTriTitle()); + $this->setTriDescription($aFields['TRI_DESCRIPTION']=$this->getTriDescription()); + return $aFields; + } + else { + throw( new Exception( "The row '$TriUid' in table TRIGGERS doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + public function create($aData) + { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + try + { + $con->begin(); + if ( isset ( $aData['TRI_UID'] ) && $aData['TRI_UID']== '' ) + unset ( $aData['TRI_UID'] ); + if ( !isset ( $aData['TRI_UID'] ) ) + $this->setTriUid(G::generateUniqueID()); + else + $this->setTriUid($aData['TRI_UID'] ); + + $this->setProUid($aData['PRO_UID']); + $this->setTriType("SCRIPT"); + + if ( !isset ( $aData['TRI_WEBBOT'] ) ) + $this->setTriWebbot(""); + else + $this->setTriWebbot( $aData['TRI_WEBBOT'] ); + + if($this->validate()) + { + if ( !isset ( $aData['TRI_TITLE'] ) ) + $this->setTriTitle(""); + else + $this->setTriTitle( $aData['TRI_TITLE'] ); + + if ( !isset ( $aData['TRI_DESCRIPTION'] ) ) + $this->setTriDescription(""); + else + $this->setTriDescription( $aData['TRI_DESCRIPTION'] ); + + if ( !isset ( $aData['TRI_PARAM'] ) ) + $this->setTriParam(""); + else + $this->setTriParam( $aData['TRI_PARAM'] ); + + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function update($fields) + { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['TRI_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $contentResult=0; + if (array_key_exists("TRI_TITLE", $fields)) $contentResult+=$this->setTriTitle($fields["TRI_TITLE"]); + if (array_key_exists("TRI_DESCRIPTION", $fields)) $contentResult+=$this->setTriDescription($fields["TRI_DESCRIPTION"]); + $result=$this->save(); + $result=($result==0)?($contentResult>0?1:0):$result; + $con->commit(); + return $result; + } + else + { + $con->rollback(); + $validationE=new Exception("Failed Validation in class ".get_class($this)."."); + $validationE->aValidationFailures = $this->getValidationFailures(); + throw($validationE); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function remove($TriUid) + { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + try + { + $result = false; + $con->begin(); + $oTri = TriggersPeer::retrieveByPK( $TriUid ); + if (!is_null($oTri)) { + Content::removeContent( 'TRI_TITLE', '', $this->getTriUid()); + Content::removeContent( 'TRI_DESCRIPTION', '', $this->getTriUid()); + $result = $oTri->delete(); + $con->commit(); + } + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + /** + * verify if Trigger row specified in [sUid] exists. + * + * @param string $sUid the uid of the Prolication + */ + + function TriggerExists ( $sUid ) { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + try { + $oObj = TriggersPeer::retrieveByPk( $sUid ); + if ( get_class ($oObj) == 'Triggers' ) { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + function verifyDependecies($TRI_UID){ + require_once "classes/model/Event.php"; + require_once "classes/model/StepTrigger.php"; + + $oResult = new stdClass(); + $oResult->dependencies = Array(); + + $oCriteria = new Criteria(); + $oCriteria->addSelectColumn(EventPeer::EVN_UID); + $oCriteria->addSelectColumn(EventPeer::TRI_UID); + $oCriteria->add(EventPeer::TRI_UID, $TRI_UID); + + $oDataset = EventPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while( $oDataset->next() ) { + array_push($aRows, $oDataset->getRow()); + } + + $oResult->dependencies['Events'] = Array(); + if(count($aRows) == 0){ + $oResult->code = 0; + } else { + $oResult->code = 1; + foreach($aRows as $row){ + $oTrigger = TriggersPeer::retrieveByPK($row['TRI_UID']); + array_push($oResult->dependencies['Events'], Array('UID'=>($oTrigger->getTriUid()), 'DESCRIPTION'=>($oTrigger->getTriTitle()))); + } + } + + //for tasks dependencies + $oCriteria = new Criteria(); + $oCriteria->addSelectColumn(StepTriggerPeer::TAS_UID); + $oCriteria->addSelectColumn(StepTriggerPeer::TRI_UID); + $oCriteria->add(StepTriggerPeer::TRI_UID, $TRI_UID); + + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aRows = Array(); + while( $oDataset->next() ) { + array_push($aRows, $oDataset->getRow()); + } + + $oResult->dependencies['Tasks'] = Array(); + if($oResult->code == 0 && count($aRows) == 0){ + $oResult->code = 0; + } else if(count($aRows) > 0){ + $oResult->code = 1; + foreach($aRows as $row){ + $oTask = TaskPeer::retrieveByPK($row['TAS_UID']); + array_push($oResult->dependencies['Tasks'], Array('UID'=>($oTask->getTasUid()), 'DESCRIPTION'=>($oTask->getTasTitle()))); + } + } + + return $oResult; + } + +} // Trigger +?> diff --git a/workflow/engine/classes/model/TriggersPeer.php b/workflow/engine/classes/model/TriggersPeer.php new file mode 100644 index 000000000..e10daf78c --- /dev/null +++ b/workflow/engine/classes/model/TriggersPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * TriggersPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseTriggersPeer.php'; + + // include object class + include_once 'classes/model/Triggers.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'TRIGGERS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class TriggersPeer extends BaseTriggersPeer { + +} // TriggersPeer diff --git a/workflow/engine/classes/model/Users.php b/workflow/engine/classes/model/Users.php new file mode 100644 index 000000000..d1639df03 --- /dev/null +++ b/workflow/engine/classes/model/Users.php @@ -0,0 +1,229 @@ +<?php +/** + * Users.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/om/BaseUsers.php'; + + +/** + * Skeleton subclass for representing a row from the 'USERS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class Users extends BaseUsers { + function create ($aData) + { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + try + { + $this->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + } + else + { + $e=new Exception("Failed Validation in class ".get_class($this)."."); + $e->aValidationFailures=$this->getValidationFailures(); + throw($e); + } + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + public function load($UsrUid) + { + try { + $oRow = UsersPeer::retrieveByPK( $UsrUid ); + if (!is_null($oRow)) + { + $aFields = $oRow->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields,BasePeer::TYPE_FIELDNAME); + $this->setNew(false); + return $aFields; + } + else { + throw(new Exception( "The row '" . $UsrUid . "' in table USER doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function loadDetails($UsrUid) + { + try { + $result = array(); + $oUser = UsersPeer::retrieveByPK( $UsrUid ); + if (!is_null($oUser)) { + $result['USR_UID'] = $oUser->getUsrUid(); + $result['USR_USERNAME'] = $oUser->getUsrUsername(); + $result['USR_FULLNAME'] = $oUser->getUsrFirstname() . ' ' . $oUser->getUsrLastname() ; + $result['USR_EMAIL'] = $oUser->getUsrEmail(); + return $result; + } + else { +// return $result; + throw(new Exception( "The row '" . $UsrUid . "' in table USER doesn't exist!" )); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function update($fields) + { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->load($fields['USR_UID']); + $this->fromArray($fields,BasePeer::TYPE_FIELDNAME); + if($this->validate()) + { + $result=$this->save(); + $con->commit(); + return $result; + } + else + { + $con->rollback(); + throw(new Exception("Failed Validation in class ".get_class($this).".")); + } + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + function remove($UsrUid) + { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + try + { + $con->begin(); + $this->setUsrUid($UsrUid); + $result=$this->delete(); + $con->commit(); + return $result; + } + catch(Exception $e) + { + $con->rollback(); + throw($e); + } + } + + function loadByUsername($sUsername) + { + $c = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( UsersPeer::USR_UID ); + $c->addSelectColumn( UsersPeer::USR_USERNAME ); + $c->addSelectColumn( UsersPeer::USR_STATUS ); + + $c->add(UsersPeer::USR_USERNAME, $sUsername); + return $c; + } + + function loadByUsernameInArray($sUsername){ + echo $sUsername; + $c = $this->loadByUsername($sUsername); + $rs = UsersPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + print_r($row); + return $row; + } + + function getAllInformation($UsrUid) + { + if( !isset($UsrUid) or $UsrUid == '' ) { + throw new Exception('$UsrUid is empty.'); + } + try { + + require_once 'classes/model/IsoCountry.php'; + require_once 'classes/model/IsoLocation.php'; + require_once 'classes/model/IsoSubdivision.php'; + require_once 'classes/model/Language.php'; + + $aFields = $this->load($UsrUid); + $c = new Criteria('workflow'); + $c->add(IsoCountryPeer::IC_UID, $aFields['USR_COUNTRY']); + $rs = IsoCountryPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $Crow = $rs->getRow(); + + $c->clearSelectColumns(); + $c->add(IsoSubdivisionPeer::IC_UID, $aFields['USR_COUNTRY']); + $c->add(IsoSubdivisionPeer::IS_UID, $aFields['USR_CITY']); + $rs = IsoSubdivisionPeer::doSelectRS($c); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $Srow = $rs->getRow(); + + $aRet['username'] = $aFields['USR_USERNAME']; + $aRet['firstname'] = $aFields['USR_FIRSTNAME']; + $aRet['lastname'] = $aFields['USR_LASTNAME']; + $aRet['mail'] = $aFields['USR_EMAIL']; + $aRet['status'] = $aFields['USR_STATUS']; + $aRet['address'] = $aFields['USR_ADDRESS']; + $aRet['phone'] = $aFields['USR_PHONE']; + $aRet['fax'] = $aFields['USR_FAX']; + $aRet['cellular'] = $aFields['USR_CELLULAR']; + $aRet['birthday'] = $aFields['USR_BIRTHDAY']; + $aRet['position'] = $aFields['USR_POSITION']; + $aRet['duedate'] = $aFields['USR_DUE_DATE']; + $aRet['country'] = $Crow['IC_NAME']; + $aRet['city'] = $Srow['IS_NAME']; + + + return $aRet; + } + catch (Exception $oException) { + throw $oException; + } + } +} // Users + +?> diff --git a/workflow/engine/classes/model/UsersPeer.php b/workflow/engine/classes/model/UsersPeer.php new file mode 100644 index 000000000..4045e5edc --- /dev/null +++ b/workflow/engine/classes/model/UsersPeer.php @@ -0,0 +1,46 @@ +<?php +/** + * UsersPeer.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + // include base peer class + require_once 'classes/model/om/BaseUsersPeer.php'; + + // include object class + include_once 'classes/model/Users.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'USERS' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class UsersPeer extends BaseUsersPeer { + +} // UsersPeer diff --git a/workflow/engine/classes/model/UsersProperties.php b/workflow/engine/classes/model/UsersProperties.php new file mode 100644 index 000000000..56ee10d96 --- /dev/null +++ b/workflow/engine/classes/model/UsersProperties.php @@ -0,0 +1,271 @@ +<?php + +require_once 'classes/model/om/BaseUsersProperties.php'; + + +/** + * Skeleton subclass for representing a row from the 'USERS_PROPERTIES' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class UsersProperties extends BaseUsersProperties { + function UserPropertyExists($sUserUID) { + try { + $oUserProperty = UsersPropertiesPeer::retrieveByPk($sUserUID); + if (get_class($oUserProperty) == 'UsersProperties') { + return true; + } + else { + return false; + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function load($sUserUID) { + try { + $oUserProperty = UsersPropertiesPeer::retrieveByPK($sUserUID); + if (!is_null($oUserProperty)) { + $aFields = $oUserProperty->toArray(BasePeer::TYPE_FIELDNAME); + $this->fromArray($aFields, BasePeer::TYPE_FIELDNAME); + return $aFields; + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + throw($oError); + } + } + + public function create($aData) { + $oConnection = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME); + try { + $oUserProperty = new UsersProperties(); + $oUserProperty->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oUserProperty->validate()) { + $oConnection->begin(); + $iResult = $oUserProperty->save(); + $oConnection->commit(); + return true; + } + else { + $sMessage = ''; + $aValidationFailures = $oUserProperty->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be created!<br />'.$sMessage)); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function update($aData) { + $oConnection = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME); + try { + $oUserProperty = UsersPropertiesPeer::retrieveByPK($aData['USR_UID']); + if (!is_null($oUserProperty)) { + $oUserProperty->fromArray($aData, BasePeer::TYPE_FIELDNAME); + if ($oUserProperty->validate()) { + $oConnection->begin(); + $iResult = $oUserProperty->save(); + $oConnection->commit(); + return $iResult; + } + else { + $sMessage = ''; + $aValidationFailures = $oUserProperty->getValidationFailures(); + foreach($aValidationFailures as $oValidationFailure) { + $sMessage .= $oValidationFailure->getMessage() . '<br />'; + } + throw(new Exception('The registry cannot be updated!<br />'.$sMessage)); + } + } + else { + throw(new Exception('This row doesn\'t exists!')); + } + } + catch (Exception $oError) { + $oConnection->rollback(); + throw($oError); + } + } + + public function loadOrCreateIfNotExists($sUserUID, $aUserProperty = array()) { + if (!$this->UserPropertyExists($sUserUID)) { + $aUserProperty['USR_UID'] = $sUserUID; + if (!isset($aUserProperty['USR_LAST_UPDATE_DATE'])) { + $aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s'); + } + if (!isset($aUserProperty['USR_LOGGED_NEXT_TIME'])) { + $aUserProperty['USR_LOGGED_NEXT_TIME'] = 0; + } + $this->create($aUserProperty); + } + else { + $aUserProperty = $this->load($sUserUID); + } + return $aUserProperty; + } + + public function validatePassword($sPassword, $sLastUpdate, $iChangePasswordNextTime) { + if (!defined('PPP_MINIMUN_LENGTH')) { + define('PPP_MINIMUN_LENGTH', 5); + } + if (!defined('PPP_MAXIMUN_LENGTH')) { + define('PPP_MAXIMUN_LENGTH', 20); + } + if (!defined('PPP_NUMERICAL_CHARACTER_REQUIRED')) { + define('PPP_NUMERICAL_CHARACTER_REQUIRED', 0); + } + if (!defined('PPP_UPPERCASE_CHARACTER_REQUIRED')) { + define('PPP_UPPERCASE_CHARACTER_REQUIRED', 0); + } + if (!defined('PPP_SPECIAL_CHARACTER_REQUIRED')) { + define('PPP_SPECIAL_CHARACTER_REQUIRED', 0); + } + if (!defined('PPP_EXPIRATION_IN')) { + define('PPP_EXPIRATION_IN', 0); + } + if (!defined('PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN')) { + define('PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN', 0); + } + if (function_exists('mb_strlen')) { + $iLength = mb_strlen($sPassword); + } + else { + $iLength = strlen($sPassword); + } + $aErrors = array(); + if ($iLength < PPP_MINIMUN_LENGTH) { + $aErrors[] = 'ID_PPP_MINIMUN_LENGTH'; + } + if ($iLength > PPP_MAXIMUN_LENGTH) { + $aErrors[] = 'ID_PPP_MAXIMUN_LENGTH'; + } + if (PPP_NUMERICAL_CHARACTER_REQUIRED == 1) { + if (preg_match_all('/[0-9]/', $sPassword, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0) { + $aErrors[] = 'ID_PPP_NUMERICAL_CHARACTER_REQUIRED'; + } + } + if (PPP_UPPERCASE_CHARACTER_REQUIRED == 1) { + if (preg_match_all('/[A-Z]/', $sPassword, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0) { + $aErrors[] = 'ID_PPP_UPPERCASE_CHARACTER_REQUIRED'; + } + } + if (PPP_SPECIAL_CHARACTER_REQUIRED == 1) { + if (preg_match_all('/[��\\!|"@�#$~%�&�\/()=\'?��*+\-_.:,;]/', $sPassword, $aMatch, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0) { + $aErrors[] = 'ID_PPP_SPECIAL_CHARACTER_REQUIRED'; + } + } + if (PPP_EXPIRATION_IN > 0) { + G::LoadClass('dates'); + $oDates = new dates(); + $fDays = $oDates->calculateDuration(date('Y-m-d H:i:s'), $sLastUpdate); + if ($fDays > (PPP_EXPIRATION_IN*24)) { + $aErrors[] = 'ID_PPP_EXPIRATION_IN'; + } + } + if (PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN == 1) { + if ($iChangePasswordNextTime == 1) { + $aErrors[] = 'ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN'; + } + } + return $aErrors; + } + public function redirectTo($sUserUID, $sLanguage = 'en') { + global $RBAC; + //get the plugins, and check if there is redirectLogins + //if yes, then redirect goes according his Role + if ( class_exists('redirectDetail')) { + //to do: complete the validation + if(isset($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'])) + $userRole = $RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE']; + + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $aRedirectLogin = $oPluginRegistry->getRedirectLogins(); + if (isset($aRedirectLogin) && is_array($aRedirectLogin) ) { + foreach ($aRedirectLogin as $key=>$detail) { + if (isset($detail->sPathMethod) && $detail->sRoleCode == $userRole ) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . $detail->sPathMethod; + } + } + } + } + //end plugin + + #New feature by Erik erik@colosa.com> + #get user preferences for default redirect + #verifying if it has any preferences on the configurations table + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'USER_PREFERENCES','','',$_SESSION['USER_LOGGED'],''); + if( sizeof($oConf->aConfig) > 0) { #this user has a configuration record + + //these is for backward compatibility, because now, we dont have user and dashboard menu. + if ( $oConf->aConfig['DEFAULT_MENU'] == 'PM_USERS') $oConf->aConfig['DEFAULT_MENU'] = 'PM_SETUP'; + if ( $oConf->aConfig['DEFAULT_MENU'] == 'PM_DASHBOARD') $oConf->aConfig['DEFAULT_MENU'] = 'PM_SETUP'; + + switch($oConf->aConfig['DEFAULT_MENU']) { + case 'PM_SETUP': + if ($RBAC->userCanAccess('PM_SETUP') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'setup/main'; + } + break; + case 'PM_FACTORY': + if ($RBAC->userCanAccess('PM_FACTORY') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'processes/main'; + } + break; + case 'PM_CASES': + if ($RBAC->userCanAccess('PM_CASES') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'cases/main'; + } + break; + case 'PM_USERS': + if ($RBAC->userCanAccess('PM_USERS') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'setup/main'; + } + break; + case 'PM_DASHBOARD': + if ($RBAC->userCanAccess('PM_DASHBOARD') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'dashboard/dashboard'; + } + break; + } + } + + if ($RBAC->userCanAccess('PM_FACTORY') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'processes/main'; + } + if ($RBAC->userCanAccess('PM_SETUP') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'setup/main'; + } + if ($RBAC->userCanAccess('PM_CASES') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'cases/main'; + } + if ($RBAC->userCanAccess('PM_USERS') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'setup/main'; + } + if ($RBAC->userCanAccess('PM_DASHBOARD') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'dashboard/dashboard'; + } + if ($RBAC->userCanAccess('PM_REPORTS') == 1) { + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'reports/reportsList'; + } + return '/sys' . SYS_SYS . '/' . $sLanguage . '/' . SYS_SKIN . '/' . 'users/myInfo'; + } +} // UsersProperties diff --git a/workflow/engine/classes/model/UsersPropertiesPeer.php b/workflow/engine/classes/model/UsersPropertiesPeer.php new file mode 100644 index 000000000..1ab882c15 --- /dev/null +++ b/workflow/engine/classes/model/UsersPropertiesPeer.php @@ -0,0 +1,23 @@ +<?php + + // include base peer class + require_once 'classes/model/om/BaseUsersPropertiesPeer.php'; + + // include object class + include_once 'classes/model/UsersProperties.php'; + + +/** + * Skeleton subclass for performing query and update operations on the 'USERS_PROPERTIES' table. + * + * + * + * You should add additional methods to this class to meet the + * application requirements. This class will only be generated as + * long as it does not already exist in the output directory. + * + * @package classes.model + */ +class UsersPropertiesPeer extends BaseUsersPropertiesPeer { + +} // UsersPropertiesPeer diff --git a/workflow/engine/classes/model/map/AdditionalTablesMapBuilder.php b/workflow/engine/classes/model/map/AdditionalTablesMapBuilder.php new file mode 100644 index 000000000..b0a4c24ac --- /dev/null +++ b/workflow/engine/classes/model/map/AdditionalTablesMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'ADDITIONAL_TABLES' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AdditionalTablesMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AdditionalTablesMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('ADDITIONAL_TABLES'); + $tMap->setPhpName('AdditionalTables'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('ADD_TAB_UID', 'AddTabUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ADD_TAB_NAME', 'AddTabName', 'string', CreoleTypes::VARCHAR, true, 60); + + $tMap->addColumn('ADD_TAB_CLASS_NAME', 'AddTabClassName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('ADD_TAB_DESCRIPTION', 'AddTabDescription', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('ADD_TAB_SDW_LOG_INSERT', 'AddTabSdwLogInsert', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('ADD_TAB_SDW_LOG_UPDATE', 'AddTabSdwLogUpdate', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('ADD_TAB_SDW_LOG_DELETE', 'AddTabSdwLogDelete', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('ADD_TAB_SDW_LOG_SELECT', 'AddTabSdwLogSelect', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('ADD_TAB_SDW_MAX_LENGTH', 'AddTabSdwMaxLength', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('ADD_TAB_SDW_AUTO_DELETE', 'AddTabSdwAutoDelete', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('ADD_TAB_PLG_UID', 'AddTabPlgUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DBS_UID', 'DbsUid', 'string', CreoleTypes::VARCHAR, false, 32); + + } // doBuild() + +} // AdditionalTablesMapBuilder diff --git a/workflow/engine/classes/model/map/AppCacheViewMapBuilder.php b/workflow/engine/classes/model/map/AppCacheViewMapBuilder.php new file mode 100644 index 000000000..cef0178fd --- /dev/null +++ b/workflow/engine/classes/model/map/AppCacheViewMapBuilder.php @@ -0,0 +1,129 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_CACHE_VIEW' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppCacheViewMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppCacheViewMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_CACHE_VIEW'); + $tMap->setPhpName('AppCacheView'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_NUMBER', 'AppNumber', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_STATUS', 'AppStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PREVIOUS_USR_UID', 'PreviousUsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_DELEGATE_DATE', 'DelDelegateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('DEL_INIT_DATE', 'DelInitDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_TASK_DUE_DATE', 'DelTaskDueDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_FINISH_DATE', 'DelFinishDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_THREAD_STATUS', 'DelThreadStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_THREAD_STATUS', 'AppThreadStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_TITLE', 'AppTitle', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('APP_PRO_TITLE', 'AppProTitle', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('APP_TAS_TITLE', 'AppTasTitle', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('APP_CURRENT_USER', 'AppCurrentUser', 'string', CreoleTypes::VARCHAR, true, 128); + + $tMap->addColumn('APP_DEL_PREVIOUS_USER', 'AppDelPreviousUser', 'string', CreoleTypes::VARCHAR, true, 128); + + $tMap->addColumn('DEL_PRIORITY', 'DelPriority', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_DURATION', 'DelDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_QUEUE_DURATION', 'DelQueueDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_DELAY_DURATION', 'DelDelayDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_STARTED', 'DelStarted', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('DEL_FINISHED', 'DelFinished', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('DEL_DELAYED', 'DelDelayed', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('APP_CREATE_DATE', 'AppCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_FINISH_DATE', 'AppFinishDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('APP_UPDATE_DATE', 'AppUpdateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_OVERDUE_PERCENTAGE', 'AppOverduePercentage', 'double', CreoleTypes::DOUBLE, true, null); + + } // doBuild() + +} // AppCacheViewMapBuilder diff --git a/workflow/engine/classes/model/map/AppDelayMapBuilder.php b/workflow/engine/classes/model/map/AppDelayMapBuilder.php new file mode 100644 index 000000000..14efba5a9 --- /dev/null +++ b/workflow/engine/classes/model/map/AppDelayMapBuilder.php @@ -0,0 +1,97 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_DELAY' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppDelayMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppDelayMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_DELAY'); + $tMap->setPhpName('AppDelay'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_DELAY_UID', 'AppDelayUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_THREAD_INDEX', 'AppThreadIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_DEL_INDEX', 'AppDelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_TYPE', 'AppType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('APP_STATUS', 'AppStatus', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('APP_NEXT_TASK', 'AppNextTask', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('APP_DELEGATION_USER', 'AppDelegationUser', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('APP_ENABLE_ACTION_USER', 'AppEnableActionUser', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_ENABLE_ACTION_DATE', 'AppEnableActionDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_DISABLE_ACTION_USER', 'AppDisableActionUser', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('APP_DISABLE_ACTION_DATE', 'AppDisableActionDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('APP_AUTOMATIC_DISABLED_DATE', 'AppAutomaticDisabledDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + } // doBuild() + +} // AppDelayMapBuilder diff --git a/workflow/engine/classes/model/map/AppDelegationMapBuilder.php b/workflow/engine/classes/model/map/AppDelegationMapBuilder.php new file mode 100644 index 000000000..e28924b3a --- /dev/null +++ b/workflow/engine/classes/model/map/AppDelegationMapBuilder.php @@ -0,0 +1,119 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_DELEGATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppDelegationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppDelegationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_DELEGATION'); + $tMap->setPhpName('AppDelegation'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('DEL_PREVIOUS', 'DelPrevious', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_TYPE', 'DelType', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_THREAD', 'DelThread', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('DEL_THREAD_STATUS', 'DelThreadStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_PRIORITY', 'DelPriority', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_DELEGATE_DATE', 'DelDelegateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('DEL_INIT_DATE', 'DelInitDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_TASK_DUE_DATE', 'DelTaskDueDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_FINISH_DATE', 'DelFinishDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('DEL_DURATION', 'DelDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_QUEUE_DURATION', 'DelQueueDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_DELAY_DURATION', 'DelDelayDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('DEL_STARTED', 'DelStarted', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('DEL_FINISHED', 'DelFinished', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('DEL_DELAYED', 'DelDelayed', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('DEL_DATA', 'DelData', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('APP_OVERDUE_PERCENTAGE', 'AppOverduePercentage', 'double', CreoleTypes::DOUBLE, true, null); + + $tMap->addValidator('DEL_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|PARALLEL', 'Please select a valid status.'); + + $tMap->addValidator('DEL_PRIORITY', 'validValues', 'propel.validator.ValidValuesValidator', '1|2|3|4|5', 'Please select a valid Priority.'); + + $tMap->addValidator('DEL_THREAD_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'CLOSED|OPEN|PAUSED', 'Please select a valid status.'); + + } // doBuild() + +} // AppDelegationMapBuilder diff --git a/workflow/engine/classes/model/map/AppDocumentMapBuilder.php b/workflow/engine/classes/model/map/AppDocumentMapBuilder.php new file mode 100644 index 000000000..86e15bb18 --- /dev/null +++ b/workflow/engine/classes/model/map/AppDocumentMapBuilder.php @@ -0,0 +1,127 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_DOCUMENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppDocumentMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppDocumentMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_DOCUMENT'); + $tMap->setPhpName('AppDocument'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_DOC_UID', 'AppDocUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('DOC_VERSION', 'DocVersion', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('DOC_UID', 'DocUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_DOC_TYPE', 'AppDocType', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_DOC_CREATE_DATE', 'AppDocCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_DOC_INDEX', 'AppDocIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('FOLDER_UID', 'FolderUid', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('APP_DOC_PLUGIN', 'AppDocPlugin', 'string', CreoleTypes::VARCHAR, false, 150); + + $tMap->addColumn('APP_DOC_TAGS', 'AppDocTags', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('APP_DOC_STATUS', 'AppDocStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_DOC_STATUS_DATE', 'AppDocStatusDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addValidator('APP_DOC_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Application Document UID can be no larger than 32 in size'); + + $tMap->addValidator('APP_DOC_UID', 'required', 'propel.validator.RequiredValidator', '', 'Application Document UID is required.'); + + $tMap->addValidator('APP_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Application UID can be no larger than 32 in size'); + + $tMap->addValidator('APP_UID', 'required', 'propel.validator.RequiredValidator', '', 'Application UID is required.'); + + $tMap->addValidator('DEL_INDEX', 'minValue', 'propel.validator.MinValueValidator', '1', 'Delegation Index can be major than 0'); + + $tMap->addValidator('DEL_INDEX', 'required', 'propel.validator.RequiredValidator', '', 'Delegation Index is required.'); + + $tMap->addValidator('DOC_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Document UID can be no larger than 32 in size'); + + $tMap->addValidator('DOC_UID', 'required', 'propel.validator.RequiredValidator', '', 'Document UID (building block) is required.'); + + $tMap->addValidator('USR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'User UID can be no larger than 32 in size'); + + $tMap->addValidator('USR_UID', 'required', 'propel.validator.RequiredValidator', '', 'User UID is required.'); + + $tMap->addValidator('APP_DOC_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'INPUT|OUTPUT|ATTACHED', 'Please select a valid document type.'); + + $tMap->addValidator('APP_DOC_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Application Document Type is required.'); + + $tMap->addValidator('APP_DOC_CREATE_DATE', 'required', 'propel.validator.RequiredValidator', '', 'Application Document Creation Date is required.'); + + $tMap->addValidator('APP_DOC_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|DELETED', 'Please select a valid document status (ACTIVE|DELETED).'); + + $tMap->addValidator('APP_DOC_STATUS', 'required', 'propel.validator.RequiredValidator', '', 'Application Document Status is required.'); + + } // doBuild() + +} // AppDocumentMapBuilder diff --git a/workflow/engine/classes/model/map/AppEventMapBuilder.php b/workflow/engine/classes/model/map/AppEventMapBuilder.php new file mode 100644 index 000000000..190e44eb1 --- /dev/null +++ b/workflow/engine/classes/model/map/AppEventMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_EVENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppEventMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppEventMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_EVENT'); + $tMap->setPhpName('AppEvent'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addPrimaryKey('EVN_UID', 'EvnUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_EVN_ACTION_DATE', 'AppEvnActionDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_EVN_ATTEMPTS', 'AppEvnAttempts', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('APP_EVN_LAST_EXECUTION_DATE', 'AppEvnLastExecutionDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('APP_EVN_STATUS', 'AppEvnStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // AppEventMapBuilder diff --git a/workflow/engine/classes/model/map/AppFolderMapBuilder.php b/workflow/engine/classes/model/map/AppFolderMapBuilder.php new file mode 100644 index 000000000..27b2081e5 --- /dev/null +++ b/workflow/engine/classes/model/map/AppFolderMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_FOLDER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppFolderMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppFolderMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_FOLDER'); + $tMap->setPhpName('AppFolder'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('FOLDER_UID', 'FolderUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('FOLDER_PARENT_UID', 'FolderParentUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('FOLDER_NAME', 'FolderName', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('FOLDER_CREATE_DATE', 'FolderCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('FOLDER_UPDATE_DATE', 'FolderUpdateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + } // doBuild() + +} // AppFolderMapBuilder diff --git a/workflow/engine/classes/model/map/AppHistoryMapBuilder.php b/workflow/engine/classes/model/map/AppHistoryMapBuilder.php new file mode 100644 index 000000000..136bd3324 --- /dev/null +++ b/workflow/engine/classes/model/map/AppHistoryMapBuilder.php @@ -0,0 +1,87 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_HISTORY' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppHistoryMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppHistoryMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_HISTORY'); + $tMap->setPhpName('AppHistory'); + + $tMap->setUseIdGenerator(false); + + $tMap->addColumn('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DYN_UID', 'DynUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_STATUS', 'AppStatus', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('HISTORY_DATE', 'HistoryDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('HISTORY_DATA', 'HistoryData', 'string', CreoleTypes::LONGVARCHAR, true, null); + + } // doBuild() + +} // AppHistoryMapBuilder diff --git a/workflow/engine/classes/model/map/AppMessageMapBuilder.php b/workflow/engine/classes/model/map/AppMessageMapBuilder.php new file mode 100644 index 000000000..de97f3e20 --- /dev/null +++ b/workflow/engine/classes/model/map/AppMessageMapBuilder.php @@ -0,0 +1,101 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_MESSAGE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppMessageMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppMessageMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_MESSAGE'); + $tMap->setPhpName('AppMessage'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_MSG_UID', 'AppMsgUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('MSG_UID', 'MsgUid', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_MSG_TYPE', 'AppMsgType', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('APP_MSG_SUBJECT', 'AppMsgSubject', 'string', CreoleTypes::VARCHAR, true, 150); + + $tMap->addColumn('APP_MSG_FROM', 'AppMsgFrom', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('APP_MSG_TO', 'AppMsgTo', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('APP_MSG_BODY', 'AppMsgBody', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('APP_MSG_DATE', 'AppMsgDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_MSG_CC', 'AppMsgCc', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('APP_MSG_BCC', 'AppMsgBcc', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('APP_MSG_TEMPLATE', 'AppMsgTemplate', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('APP_MSG_STATUS', 'AppMsgStatus', 'string', CreoleTypes::VARCHAR, false, 20); + + $tMap->addColumn('APP_MSG_ATTACH', 'AppMsgAttach', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('APP_MSG_SEND_DATE', 'AppMsgSendDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + } // doBuild() + +} // AppMessageMapBuilder diff --git a/workflow/engine/classes/model/map/AppOwnerMapBuilder.php b/workflow/engine/classes/model/map/AppOwnerMapBuilder.php new file mode 100644 index 000000000..3bbfa2dd2 --- /dev/null +++ b/workflow/engine/classes/model/map/AppOwnerMapBuilder.php @@ -0,0 +1,75 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_OWNER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppOwnerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppOwnerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_OWNER'); + $tMap->setPhpName('AppOwner'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('OWN_UID', 'OwnUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // AppOwnerMapBuilder diff --git a/workflow/engine/classes/model/map/AppSpoolMapBuilder.php b/workflow/engine/classes/model/map/AppSpoolMapBuilder.php new file mode 100644 index 000000000..95d8dfc3d --- /dev/null +++ b/workflow/engine/classes/model/map/AppSpoolMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_SPOOL' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppSpoolMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppSpoolMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_SPOOL'); + $tMap->setPhpName('AppSpool'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('ID', 'Id', 'int', CreoleTypes::SMALLINT, true, 6); + + $tMap->addColumn('SENDER', 'Sender', 'string', CreoleTypes::VARCHAR, true, 96); + + $tMap->addColumn('FILE', 'File', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('NOW', 'Now', 'string', CreoleTypes::VARCHAR, true, 16); + + $tMap->addColumn('STATUS', 'Status', 'string', CreoleTypes::VARCHAR, true, 16); + + } // doBuild() + +} // AppSpoolMapBuilder diff --git a/workflow/engine/classes/model/map/AppThreadMapBuilder.php b/workflow/engine/classes/model/map/AppThreadMapBuilder.php new file mode 100644 index 000000000..347c9a19d --- /dev/null +++ b/workflow/engine/classes/model/map/AppThreadMapBuilder.php @@ -0,0 +1,81 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APP_THREAD' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class AppThreadMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.AppThreadMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APP_THREAD'); + $tMap->setPhpName('AppThread'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('APP_THREAD_INDEX', 'AppThreadIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_THREAD_PARENT', 'AppThreadParent', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_THREAD_STATUS', 'AppThreadStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEL_INDEX', 'DelIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('APP_THREAD_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'CLOSED|OPEN', 'Please select a valid status.'); + + } // doBuild() + +} // AppThreadMapBuilder diff --git a/workflow/engine/classes/model/map/ApplicationMapBuilder.php b/workflow/engine/classes/model/map/ApplicationMapBuilder.php new file mode 100644 index 000000000..9966f46c6 --- /dev/null +++ b/workflow/engine/classes/model/map/ApplicationMapBuilder.php @@ -0,0 +1,103 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'APPLICATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ApplicationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ApplicationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('APPLICATION'); + $tMap->setPhpName('Application'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_NUMBER', 'AppNumber', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('APP_PARENT', 'AppParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_STATUS', 'AppStatus', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_PROC_STATUS', 'AppProcStatus', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('APP_PROC_CODE', 'AppProcCode', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('APP_PARALLEL', 'AppParallel', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_INIT_USER', 'AppInitUser', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_CUR_USER', 'AppCurUser', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_CREATE_DATE', 'AppCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_INIT_DATE', 'AppInitDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_FINISH_DATE', 'AppFinishDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_UPDATE_DATE', 'AppUpdateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('APP_DATA', 'AppData', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('APP_PIN', 'AppPin', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addValidator('APP_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'DRAFT|TO_DO|PAUSED|COMPLETED|CANCELLED', 'Please select a valid status.'); + + } // doBuild() + +} // ApplicationMapBuilder diff --git a/workflow/engine/classes/model/map/CalendarAssignmentsMapBuilder.php b/workflow/engine/classes/model/map/CalendarAssignmentsMapBuilder.php new file mode 100644 index 000000000..f3fbcae38 --- /dev/null +++ b/workflow/engine/classes/model/map/CalendarAssignmentsMapBuilder.php @@ -0,0 +1,75 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CALENDAR_ASSIGNMENTS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CalendarAssignmentsMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CalendarAssignmentsMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CALENDAR_ASSIGNMENTS'); + $tMap->setPhpName('CalendarAssignments'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('OBJECT_UID', 'ObjectUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CALENDAR_UID', 'CalendarUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('OBJECT_TYPE', 'ObjectType', 'string', CreoleTypes::VARCHAR, true, 100); + + } // doBuild() + +} // CalendarAssignmentsMapBuilder diff --git a/workflow/engine/classes/model/map/CalendarBusinessHoursMapBuilder.php b/workflow/engine/classes/model/map/CalendarBusinessHoursMapBuilder.php new file mode 100644 index 000000000..abef4adba --- /dev/null +++ b/workflow/engine/classes/model/map/CalendarBusinessHoursMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CALENDAR_BUSINESS_HOURS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CalendarBusinessHoursMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CalendarBusinessHoursMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CALENDAR_BUSINESS_HOURS'); + $tMap->setPhpName('CalendarBusinessHours'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CALENDAR_UID', 'CalendarUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('CALENDAR_BUSINESS_DAY', 'CalendarBusinessDay', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addPrimaryKey('CALENDAR_BUSINESS_START', 'CalendarBusinessStart', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addPrimaryKey('CALENDAR_BUSINESS_END', 'CalendarBusinessEnd', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addValidator('CALENDAR_BUSINESS_DAY', 'validValues', 'propel.validator.ValidValuesValidator', '0|1|2|3|4|5|6|7', 'Please select a valid Day.'); + + } // doBuild() + +} // CalendarBusinessHoursMapBuilder diff --git a/workflow/engine/classes/model/map/CalendarDefinitionMapBuilder.php b/workflow/engine/classes/model/map/CalendarDefinitionMapBuilder.php new file mode 100644 index 000000000..ac697d333 --- /dev/null +++ b/workflow/engine/classes/model/map/CalendarDefinitionMapBuilder.php @@ -0,0 +1,85 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CALENDAR_DEFINITION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CalendarDefinitionMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CalendarDefinitionMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CALENDAR_DEFINITION'); + $tMap->setPhpName('CalendarDefinition'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CALENDAR_UID', 'CalendarUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CALENDAR_NAME', 'CalendarName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('CALENDAR_CREATE_DATE', 'CalendarCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('CALENDAR_UPDATE_DATE', 'CalendarUpdateDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('CALENDAR_WORK_DAYS', 'CalendarWorkDays', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('CALENDAR_DESCRIPTION', 'CalendarDescription', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('CALENDAR_STATUS', 'CalendarStatus', 'string', CreoleTypes::VARCHAR, true, 8); + + $tMap->addValidator('CALENDAR_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|INACTIVE|DELETED', 'Please select a valid Calendar Status.'); + + } // doBuild() + +} // CalendarDefinitionMapBuilder diff --git a/workflow/engine/classes/model/map/CalendarHolidaysMapBuilder.php b/workflow/engine/classes/model/map/CalendarHolidaysMapBuilder.php new file mode 100644 index 000000000..ecb034c1e --- /dev/null +++ b/workflow/engine/classes/model/map/CalendarHolidaysMapBuilder.php @@ -0,0 +1,77 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CALENDAR_HOLIDAYS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CalendarHolidaysMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CalendarHolidaysMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CALENDAR_HOLIDAYS'); + $tMap->setPhpName('CalendarHolidays'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CALENDAR_UID', 'CalendarUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('CALENDAR_HOLIDAY_NAME', 'CalendarHolidayName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('CALENDAR_HOLIDAY_START', 'CalendarHolidayStart', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('CALENDAR_HOLIDAY_END', 'CalendarHolidayEnd', 'int', CreoleTypes::TIMESTAMP, true, null); + + } // doBuild() + +} // CalendarHolidaysMapBuilder diff --git a/workflow/engine/classes/model/map/CaseSchedulerMapBuilder.php b/workflow/engine/classes/model/map/CaseSchedulerMapBuilder.php new file mode 100644 index 000000000..a0258e636 --- /dev/null +++ b/workflow/engine/classes/model/map/CaseSchedulerMapBuilder.php @@ -0,0 +1,119 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CASE_SCHEDULER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CaseSchedulerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CaseSchedulerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CASE_SCHEDULER'); + $tMap->setPhpName('CaseScheduler'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('SCH_UID', 'SchUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SCH_DEL_USER_NAME', 'SchDelUserName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('SCH_DEL_USER_PASS', 'SchDelUserPass', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('SCH_DEL_USER_UID', 'SchDelUserUid', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('SCH_NAME', 'SchName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SCH_TIME_NEXT_RUN', 'SchTimeNextRun', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('SCH_LAST_RUN_TIME', 'SchLastRunTime', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('SCH_STATE', 'SchState', 'string', CreoleTypes::VARCHAR, true, 15); + + $tMap->addColumn('SCH_LAST_STATE', 'SchLastState', 'string', CreoleTypes::VARCHAR, true, 60); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SCH_OPTION', 'SchOption', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('SCH_START_TIME', 'SchStartTime', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('SCH_START_DATE', 'SchStartDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('SCH_DAYS_PERFORM_TASK', 'SchDaysPerformTask', 'string', CreoleTypes::CHAR, true, 5); + + $tMap->addColumn('SCH_EVERY_DAYS', 'SchEveryDays', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('SCH_WEEK_DAYS', 'SchWeekDays', 'string', CreoleTypes::CHAR, true, 14); + + $tMap->addColumn('SCH_START_DAY', 'SchStartDay', 'string', CreoleTypes::CHAR, true, 6); + + $tMap->addColumn('SCH_MONTHS', 'SchMonths', 'string', CreoleTypes::CHAR, true, 24); + + $tMap->addColumn('SCH_END_DATE', 'SchEndDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('SCH_REPEAT_EVERY', 'SchRepeatEvery', 'string', CreoleTypes::VARCHAR, true, 15); + + $tMap->addColumn('SCH_REPEAT_UNTIL', 'SchRepeatUntil', 'string', CreoleTypes::VARCHAR, true, 15); + + $tMap->addColumn('SCH_REPEAT_STOP_IF_RUNNING', 'SchRepeatStopIfRunning', 'int', CreoleTypes::TINYINT, false, null); + + $tMap->addColumn('CASE_SH_PLUGIN_UID', 'CaseShPluginUid', 'string', CreoleTypes::VARCHAR, false, 100); + + } // doBuild() + +} // CaseSchedulerMapBuilder diff --git a/workflow/engine/classes/model/map/CaseTrackerMapBuilder.php b/workflow/engine/classes/model/map/CaseTrackerMapBuilder.php new file mode 100644 index 000000000..8c7ded414 --- /dev/null +++ b/workflow/engine/classes/model/map/CaseTrackerMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CASE_TRACKER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CaseTrackerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CaseTrackerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CASE_TRACKER'); + $tMap->setPhpName('CaseTracker'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CT_MAP_TYPE', 'CtMapType', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('CT_DERIVATION_HISTORY', 'CtDerivationHistory', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('CT_MESSAGE_HISTORY', 'CtMessageHistory', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('CT_MAP_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NONE|PROCESSMAP|STAGES', 'Please select a valid map type.'); + + $tMap->addValidator('CT_MAP_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Map type is required.'); + + $tMap->addValidator('CT_DERIVATION_HISTORY', 'validValues', 'propel.validator.ValidValuesValidator', '0|1', 'Please select a valid derivation history status.'); + + $tMap->addValidator('CT_DERIVATION_HISTORY', 'required', 'propel.validator.RequiredValidator', '', 'Derivation history status is required.'); + + $tMap->addValidator('CT_MESSAGE_HISTORY', 'validValues', 'propel.validator.ValidValuesValidator', '0|1', 'Please select a valid message history status.'); + + $tMap->addValidator('CT_MESSAGE_HISTORY', 'required', 'propel.validator.RequiredValidator', '', 'Message history status is required.'); + + } // doBuild() + +} // CaseTrackerMapBuilder diff --git a/workflow/engine/classes/model/map/CaseTrackerObjectMapBuilder.php b/workflow/engine/classes/model/map/CaseTrackerObjectMapBuilder.php new file mode 100644 index 000000000..9d605047b --- /dev/null +++ b/workflow/engine/classes/model/map/CaseTrackerObjectMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CASE_TRACKER_OBJECT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class CaseTrackerObjectMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.CaseTrackerObjectMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CASE_TRACKER_OBJECT'); + $tMap->setPhpName('CaseTrackerObject'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CTO_UID', 'CtoUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CTO_TYPE_OBJ', 'CtoTypeObj', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('CTO_UID_OBJ', 'CtoUidObj', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CTO_CONDITION', 'CtoCondition', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('CTO_POSITION', 'CtoPosition', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('CTO_TYPE_OBJ', 'validValues', 'propel.validator.ValidValuesValidator', 'DYNAFORM|INPUT_DOCUMENT|OUTPUT_DOCUMENT|MESSAGE|EXTERNAL', 'Please select a valid value for CTO_TYPE_OBJ.'); + + } // doBuild() + +} // CaseTrackerObjectMapBuilder diff --git a/workflow/engine/classes/model/map/ConfigurationMapBuilder.php b/workflow/engine/classes/model/map/ConfigurationMapBuilder.php new file mode 100644 index 000000000..ea9f954e3 --- /dev/null +++ b/workflow/engine/classes/model/map/ConfigurationMapBuilder.php @@ -0,0 +1,81 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CONFIGURATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ConfigurationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ConfigurationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CONFIGURATION'); + $tMap->setPhpName('Configuration'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CFG_UID', 'CfgUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('OBJ_UID', 'ObjUid', 'string', CreoleTypes::VARCHAR, true, 128); + + $tMap->addColumn('CFG_VALUE', 'CfgValue', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addPrimaryKey('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // ConfigurationMapBuilder diff --git a/workflow/engine/classes/model/map/ContentMapBuilder.php b/workflow/engine/classes/model/map/ContentMapBuilder.php new file mode 100644 index 000000000..fd87082f8 --- /dev/null +++ b/workflow/engine/classes/model/map/ContentMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'CONTENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ContentMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ContentMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('CONTENT'); + $tMap->setPhpName('Content'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CON_CATEGORY', 'ConCategory', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addPrimaryKey('CON_PARENT', 'ConParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('CON_ID', 'ConId', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addPrimaryKey('CON_LANG', 'ConLang', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('CON_VALUE', 'ConValue', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addValidator('CON_LANG', 'maxLength', 'propel.validator.MaxLengthValidator', '5', 'Language can be no larger than 5 in size'); + + $tMap->addValidator('CON_LANG', 'required', 'propel.validator.RequiredValidator', '', 'Language is required.'); + + } // doBuild() + +} // ContentMapBuilder diff --git a/workflow/engine/classes/model/map/DbSourceMapBuilder.php b/workflow/engine/classes/model/map/DbSourceMapBuilder.php new file mode 100644 index 000000000..45a201bf0 --- /dev/null +++ b/workflow/engine/classes/model/map/DbSourceMapBuilder.php @@ -0,0 +1,87 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'DB_SOURCE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class DbSourceMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.DbSourceMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('DB_SOURCE'); + $tMap->setPhpName('DbSource'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('DBS_UID', 'DbsUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DBS_TYPE', 'DbsType', 'string', CreoleTypes::VARCHAR, true, 8); + + $tMap->addColumn('DBS_SERVER', 'DbsServer', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('DBS_DATABASE_NAME', 'DbsDatabaseName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('DBS_USERNAME', 'DbsUsername', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DBS_PASSWORD', 'DbsPassword', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('DBS_PORT', 'DbsPort', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('DBS_ENCODE', 'DbsEncode', 'string', CreoleTypes::VARCHAR, false, 32); + + } // doBuild() + +} // DbSourceMapBuilder diff --git a/workflow/engine/classes/model/map/DepartmentMapBuilder.php b/workflow/engine/classes/model/map/DepartmentMapBuilder.php new file mode 100644 index 000000000..c678f6301 --- /dev/null +++ b/workflow/engine/classes/model/map/DepartmentMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'DEPARTMENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class DepartmentMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.DepartmentMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('DEPARTMENT'); + $tMap->setPhpName('Department'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('DEP_UID', 'DepUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEP_PARENT', 'DepParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEP_MANAGER', 'DepManager', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DEP_LOCATION', 'DepLocation', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('DEP_STATUS', 'DepStatus', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('DEP_REF_CODE', 'DepRefCode', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addColumn('DEP_LDAP_DN', 'DepLdapDn', 'string', CreoleTypes::VARCHAR, true, 255); + + } // doBuild() + +} // DepartmentMapBuilder diff --git a/workflow/engine/classes/model/map/DimTimeCompleteMapBuilder.php b/workflow/engine/classes/model/map/DimTimeCompleteMapBuilder.php new file mode 100644 index 000000000..3e4384f0a --- /dev/null +++ b/workflow/engine/classes/model/map/DimTimeCompleteMapBuilder.php @@ -0,0 +1,85 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'DIM_TIME_COMPLETE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class DimTimeCompleteMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.DimTimeCompleteMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('DIM_TIME_COMPLETE'); + $tMap->setPhpName('DimTimeComplete'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('TIME_ID', 'TimeId', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('MONTH_ID', 'MonthId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('QTR_ID', 'QtrId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('YEAR_ID', 'YearId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('MONTH_NAME', 'MonthName', 'string', CreoleTypes::VARCHAR, true, 3); + + $tMap->addColumn('MONTH_DESC', 'MonthDesc', 'string', CreoleTypes::VARCHAR, true, 9); + + $tMap->addColumn('QTR_NAME', 'QtrName', 'string', CreoleTypes::VARCHAR, true, 4); + + $tMap->addColumn('QTR_DESC', 'QtrDesc', 'string', CreoleTypes::VARCHAR, true, 9); + + } // doBuild() + +} // DimTimeCompleteMapBuilder diff --git a/workflow/engine/classes/model/map/DimTimeDelegateMapBuilder.php b/workflow/engine/classes/model/map/DimTimeDelegateMapBuilder.php new file mode 100644 index 000000000..c06a9bcf1 --- /dev/null +++ b/workflow/engine/classes/model/map/DimTimeDelegateMapBuilder.php @@ -0,0 +1,85 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'DIM_TIME_DELEGATE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class DimTimeDelegateMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.DimTimeDelegateMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('DIM_TIME_DELEGATE'); + $tMap->setPhpName('DimTimeDelegate'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('TIME_ID', 'TimeId', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('MONTH_ID', 'MonthId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('QTR_ID', 'QtrId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('YEAR_ID', 'YearId', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('MONTH_NAME', 'MonthName', 'string', CreoleTypes::VARCHAR, true, 3); + + $tMap->addColumn('MONTH_DESC', 'MonthDesc', 'string', CreoleTypes::VARCHAR, true, 9); + + $tMap->addColumn('QTR_NAME', 'QtrName', 'string', CreoleTypes::VARCHAR, true, 4); + + $tMap->addColumn('QTR_DESC', 'QtrDesc', 'string', CreoleTypes::VARCHAR, true, 9); + + } // doBuild() + +} // DimTimeDelegateMapBuilder diff --git a/workflow/engine/classes/model/map/DynaformMapBuilder.php b/workflow/engine/classes/model/map/DynaformMapBuilder.php new file mode 100644 index 000000000..60c845788 --- /dev/null +++ b/workflow/engine/classes/model/map/DynaformMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'DYNAFORM' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class DynaformMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.DynaformMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('DYNAFORM'); + $tMap->setPhpName('Dynaform'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('DYN_UID', 'DynUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('DYN_TYPE', 'DynType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('DYN_FILENAME', 'DynFilename', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addValidator('DYN_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'xmlform|grid', 'Please select a valid dynaform type.'); + + } // doBuild() + +} // DynaformMapBuilder diff --git a/workflow/engine/classes/model/map/EventMapBuilder.php b/workflow/engine/classes/model/map/EventMapBuilder.php new file mode 100644 index 000000000..10026c5f4 --- /dev/null +++ b/workflow/engine/classes/model/map/EventMapBuilder.php @@ -0,0 +1,99 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'EVENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class EventMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.EventMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('EVENT'); + $tMap->setPhpName('Event'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('EVN_UID', 'EvnUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('EVN_STATUS', 'EvnStatus', 'string', CreoleTypes::VARCHAR, true, 16); + + $tMap->addColumn('EVN_WHEN_OCCURS', 'EvnWhenOccurs', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('EVN_RELATED_TO', 'EvnRelatedTo', 'string', CreoleTypes::VARCHAR, false, 16); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('EVN_TAS_UID_FROM', 'EvnTasUidFrom', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('EVN_TAS_UID_TO', 'EvnTasUidTo', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('EVN_TAS_ESTIMATED_DURATION', 'EvnTasEstimatedDuration', 'double', CreoleTypes::DOUBLE, false, null); + + $tMap->addColumn('EVN_WHEN', 'EvnWhen', 'double', CreoleTypes::DOUBLE, true, null); + + $tMap->addColumn('EVN_MAX_ATTEMPTS', 'EvnMaxAttempts', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('EVN_ACTION', 'EvnAction', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addColumn('EVN_CONDITIONS', 'EvnConditions', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('EVN_ACTION_PARAMETERS', 'EvnActionParameters', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('TRI_UID', 'TriUid', 'string', CreoleTypes::VARCHAR, false, 32); + + } // doBuild() + +} // EventMapBuilder diff --git a/workflow/engine/classes/model/map/FieldConditionMapBuilder.php b/workflow/engine/classes/model/map/FieldConditionMapBuilder.php new file mode 100644 index 000000000..a6722e848 --- /dev/null +++ b/workflow/engine/classes/model/map/FieldConditionMapBuilder.php @@ -0,0 +1,85 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'FIELD_CONDITION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class FieldConditionMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.FieldConditionMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('FIELD_CONDITION'); + $tMap->setPhpName('FieldCondition'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('FCD_UID', 'FcdUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('FCD_FUNCTION', 'FcdFunction', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addColumn('FCD_FIELDS', 'FcdFields', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('FCD_CONDITION', 'FcdCondition', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('FCD_EVENTS', 'FcdEvents', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('FCD_EVENT_OWNERS', 'FcdEventOwners', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('FCD_STATUS', 'FcdStatus', 'string', CreoleTypes::VARCHAR, false, 10); + + $tMap->addColumn('FCD_DYN_UID', 'FcdDynUid', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // FieldConditionMapBuilder diff --git a/workflow/engine/classes/model/map/FieldsMapBuilder.php b/workflow/engine/classes/model/map/FieldsMapBuilder.php new file mode 100644 index 000000000..fef27e3a7 --- /dev/null +++ b/workflow/engine/classes/model/map/FieldsMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'FIELDS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class FieldsMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.FieldsMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('FIELDS'); + $tMap->setPhpName('Fields'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('FLD_UID', 'FldUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ADD_TAB_UID', 'AddTabUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('FLD_INDEX', 'FldIndex', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('FLD_NAME', 'FldName', 'string', CreoleTypes::VARCHAR, true, 60); + + $tMap->addColumn('FLD_DESCRIPTION', 'FldDescription', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('FLD_TYPE', 'FldType', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('FLD_SIZE', 'FldSize', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('FLD_NULL', 'FldNull', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('FLD_AUTO_INCREMENT', 'FldAutoIncrement', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('FLD_KEY', 'FldKey', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('FLD_FOREIGN_KEY', 'FldForeignKey', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('FLD_FOREIGN_KEY_TABLE', 'FldForeignKeyTable', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // FieldsMapBuilder diff --git a/workflow/engine/classes/model/map/GroupUserMapBuilder.php b/workflow/engine/classes/model/map/GroupUserMapBuilder.php new file mode 100644 index 000000000..0c786c5e3 --- /dev/null +++ b/workflow/engine/classes/model/map/GroupUserMapBuilder.php @@ -0,0 +1,81 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'GROUP_USER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class GroupUserMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.GroupUserMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('GROUP_USER'); + $tMap->setPhpName('GroupUser'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('GRP_UID', 'GrpUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addValidator('GRP_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Group UID can be no larger than 32 in size'); + + $tMap->addValidator('GRP_UID', 'required', 'propel.validator.RequiredValidator', '', 'Group UID is required.'); + + $tMap->addValidator('USR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'User UID can be no larger than 32 in size'); + + $tMap->addValidator('USR_UID', 'required', 'propel.validator.RequiredValidator', '', 'User UID is required.'); + + } // doBuild() + +} // GroupUserMapBuilder diff --git a/workflow/engine/classes/model/map/GroupwfMapBuilder.php b/workflow/engine/classes/model/map/GroupwfMapBuilder.php new file mode 100644 index 000000000..adc24ffe7 --- /dev/null +++ b/workflow/engine/classes/model/map/GroupwfMapBuilder.php @@ -0,0 +1,77 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'GROUPWF' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class GroupwfMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.GroupwfMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('GROUPWF'); + $tMap->setPhpName('Groupwf'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('GRP_UID', 'GrpUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('GRP_STATUS', 'GrpStatus', 'string', CreoleTypes::CHAR, true, 8); + + $tMap->addValidator('GRP_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|INACTIVE', 'Please select a valid status.'); + + $tMap->addValidator('GRP_STATUS', 'required', 'propel.validator.RequiredValidator', '', 'Application Document UID is required.'); + + } // doBuild() + +} // GroupwfMapBuilder diff --git a/workflow/engine/classes/model/map/HolidayMapBuilder.php b/workflow/engine/classes/model/map/HolidayMapBuilder.php new file mode 100644 index 000000000..9dbfdd8a0 --- /dev/null +++ b/workflow/engine/classes/model/map/HolidayMapBuilder.php @@ -0,0 +1,75 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'HOLIDAY' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class HolidayMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.HolidayMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('HOLIDAY'); + $tMap->setPhpName('Holiday'); + + $tMap->setUseIdGenerator(true); + + $tMap->addPrimaryKey('HLD_UID', 'HldUid', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('HLD_DATE', 'HldDate', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('HLD_DESCRIPTION', 'HldDescription', 'string', CreoleTypes::VARCHAR, true, 200); + + } // doBuild() + +} // HolidayMapBuilder diff --git a/workflow/engine/classes/model/map/InputDocumentMapBuilder.php b/workflow/engine/classes/model/map/InputDocumentMapBuilder.php new file mode 100644 index 000000000..c3d67b727 --- /dev/null +++ b/workflow/engine/classes/model/map/InputDocumentMapBuilder.php @@ -0,0 +1,105 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'INPUT_DOCUMENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class InputDocumentMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.InputDocumentMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('INPUT_DOCUMENT'); + $tMap->setPhpName('InputDocument'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('INP_DOC_UID', 'InpDocUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('INP_DOC_FORM_NEEDED', 'InpDocFormNeeded', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('INP_DOC_ORIGINAL', 'InpDocOriginal', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('INP_DOC_PUBLISHED', 'InpDocPublished', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('INP_DOC_VERSIONING', 'InpDocVersioning', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('INP_DOC_DESTINATION_PATH', 'InpDocDestinationPath', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('INP_DOC_TAGS', 'InpDocTags', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addValidator('INP_DOC_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Input Document UID can be no larger than 32 in size'); + + $tMap->addValidator('INP_DOC_UID', 'required', 'propel.validator.RequiredValidator', '', 'Input Document UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('INP_DOC_FORM_NEEDED', 'validValues', 'propel.validator.ValidValuesValidator', 'VIRTUAL|REAL|VREAL', 'Please select a valid document format.'); + + $tMap->addValidator('INP_DOC_FORM_NEEDED', 'required', 'propel.validator.RequiredValidator', '', 'Document format is required.'); + + $tMap->addValidator('INP_DOC_ORIGINAL', 'validValues', 'propel.validator.ValidValuesValidator', 'COPY|ORIGINAL|COPYLEGAL|FINAL', 'Please select a valid document format type.'); + + $tMap->addValidator('INP_DOC_ORIGINAL', 'required', 'propel.validator.RequiredValidator', '', 'Document format type is required.'); + + $tMap->addValidator('INP_DOC_PUBLISHED', 'validValues', 'propel.validator.ValidValuesValidator', 'PUBLIC|PRIVATE', 'Please select a valid document access.'); + + $tMap->addValidator('INP_DOC_PUBLISHED', 'required', 'propel.validator.RequiredValidator', '', 'Document access is required.'); + + } // doBuild() + +} // InputDocumentMapBuilder diff --git a/workflow/engine/classes/model/map/IsoCountryMapBuilder.php b/workflow/engine/classes/model/map/IsoCountryMapBuilder.php new file mode 100644 index 000000000..be55ac245 --- /dev/null +++ b/workflow/engine/classes/model/map/IsoCountryMapBuilder.php @@ -0,0 +1,75 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'ISO_COUNTRY' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class IsoCountryMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.IsoCountryMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('ISO_COUNTRY'); + $tMap->setPhpName('IsoCountry'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('IC_UID', 'IcUid', 'string', CreoleTypes::VARCHAR, true, 2); + + $tMap->addColumn('IC_NAME', 'IcName', 'string', CreoleTypes::VARCHAR, false, 255); + + $tMap->addColumn('IC_SORT_ORDER', 'IcSortOrder', 'string', CreoleTypes::VARCHAR, false, 255); + + } // doBuild() + +} // IsoCountryMapBuilder diff --git a/workflow/engine/classes/model/map/IsoLocationMapBuilder.php b/workflow/engine/classes/model/map/IsoLocationMapBuilder.php new file mode 100644 index 000000000..90bb011fa --- /dev/null +++ b/workflow/engine/classes/model/map/IsoLocationMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'ISO_LOCATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class IsoLocationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.IsoLocationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('ISO_LOCATION'); + $tMap->setPhpName('IsoLocation'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('IC_UID', 'IcUid', 'string', CreoleTypes::VARCHAR, true, 2); + + $tMap->addPrimaryKey('IL_UID', 'IlUid', 'string', CreoleTypes::VARCHAR, true, 5); + + $tMap->addColumn('IL_NAME', 'IlName', 'string', CreoleTypes::VARCHAR, false, 255); + + $tMap->addColumn('IL_NORMAL_NAME', 'IlNormalName', 'string', CreoleTypes::VARCHAR, false, 255); + + $tMap->addColumn('IS_UID', 'IsUid', 'string', CreoleTypes::VARCHAR, false, 4); + + } // doBuild() + +} // IsoLocationMapBuilder diff --git a/workflow/engine/classes/model/map/IsoSubdivisionMapBuilder.php b/workflow/engine/classes/model/map/IsoSubdivisionMapBuilder.php new file mode 100644 index 000000000..b91cf52dd --- /dev/null +++ b/workflow/engine/classes/model/map/IsoSubdivisionMapBuilder.php @@ -0,0 +1,75 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'ISO_SUBDIVISION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class IsoSubdivisionMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.IsoSubdivisionMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('ISO_SUBDIVISION'); + $tMap->setPhpName('IsoSubdivision'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('IC_UID', 'IcUid', 'string', CreoleTypes::VARCHAR, true, 2); + + $tMap->addPrimaryKey('IS_UID', 'IsUid', 'string', CreoleTypes::VARCHAR, true, 4); + + $tMap->addColumn('IS_NAME', 'IsName', 'string', CreoleTypes::VARCHAR, true, 255); + + } // doBuild() + +} // IsoSubdivisionMapBuilder diff --git a/workflow/engine/classes/model/map/LanguageMapBuilder.php b/workflow/engine/classes/model/map/LanguageMapBuilder.php new file mode 100644 index 000000000..6ce0e5401 --- /dev/null +++ b/workflow/engine/classes/model/map/LanguageMapBuilder.php @@ -0,0 +1,91 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'LANGUAGE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class LanguageMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.LanguageMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('LANGUAGE'); + $tMap->setPhpName('Language'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('LAN_ID', 'LanId', 'string', CreoleTypes::VARCHAR, true, 4); + + $tMap->addColumn('LAN_NAME', 'LanName', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addColumn('LAN_NATIVE_NAME', 'LanNativeName', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addColumn('LAN_DIRECTION', 'LanDirection', 'string', CreoleTypes::CHAR, true, 1); + + $tMap->addColumn('LAN_WEIGHT', 'LanWeight', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('LAN_ENABLED', 'LanEnabled', 'string', CreoleTypes::CHAR, true, 1); + + $tMap->addColumn('LAN_CALENDAR', 'LanCalendar', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addValidator('LAN_DIRECTION', 'validValues', 'propel.validator.ValidValuesValidator', 'L|R', 'Please select a valid Language Direccion.'); + + $tMap->addValidator('LAN_DIRECTION', 'required', 'propel.validator.RequiredValidator', '', 'Document access is required.'); + + $tMap->addValidator('LAN_ENABLED', 'validValues', 'propel.validator.ValidValuesValidator', '1|0', 'Please select a valid Language Direccion.'); + + $tMap->addValidator('LAN_ENABLED', 'required', 'propel.validator.RequiredValidator', '', 'Document access is required.'); + + } // doBuild() + +} // LanguageMapBuilder diff --git a/workflow/engine/classes/model/map/LexicoMapBuilder.php b/workflow/engine/classes/model/map/LexicoMapBuilder.php new file mode 100644 index 000000000..1537f1288 --- /dev/null +++ b/workflow/engine/classes/model/map/LexicoMapBuilder.php @@ -0,0 +1,77 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'LEXICO' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class LexicoMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.LexicoMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('LEXICO'); + $tMap->setPhpName('Lexico'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('LEX_TOPIC', 'LexTopic', 'string', CreoleTypes::VARCHAR, true, 64); + + $tMap->addPrimaryKey('LEX_KEY', 'LexKey', 'string', CreoleTypes::VARCHAR, true, 128); + + $tMap->addColumn('LEX_VALUE', 'LexValue', 'string', CreoleTypes::VARCHAR, true, 128); + + $tMap->addColumn('LEX_CAPTION', 'LexCaption', 'string', CreoleTypes::VARCHAR, true, 128); + + } // doBuild() + +} // LexicoMapBuilder diff --git a/workflow/engine/classes/model/map/LogCasesSchedulerMapBuilder.php b/workflow/engine/classes/model/map/LogCasesSchedulerMapBuilder.php new file mode 100644 index 000000000..f2bf1a043 --- /dev/null +++ b/workflow/engine/classes/model/map/LogCasesSchedulerMapBuilder.php @@ -0,0 +1,89 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'LOG_CASES_SCHEDULER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class LogCasesSchedulerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.LogCasesSchedulerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('LOG_CASES_SCHEDULER'); + $tMap->setPhpName('LogCasesScheduler'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('LOG_CASE_UID', 'LogCaseUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_NAME', 'UsrName', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('EXEC_DATE', 'ExecDate', 'int', CreoleTypes::DATE, true, null); + + $tMap->addColumn('EXEC_HOUR', 'ExecHour', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('RESULT', 'Result', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SCH_UID', 'SchUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('WS_CREATE_CASE_STATUS', 'WsCreateCaseStatus', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('WS_ROUTE_CASE_STATUS', 'WsRouteCaseStatus', 'string', CreoleTypes::LONGVARCHAR, true, null); + + } // doBuild() + +} // LogCasesSchedulerMapBuilder diff --git a/workflow/engine/classes/model/map/LoginLogMapBuilder.php b/workflow/engine/classes/model/map/LoginLogMapBuilder.php new file mode 100644 index 000000000..d6022ee33 --- /dev/null +++ b/workflow/engine/classes/model/map/LoginLogMapBuilder.php @@ -0,0 +1,85 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'LOGIN_LOG' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class LoginLogMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.LoginLogMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('LOGIN_LOG'); + $tMap->setPhpName('LoginLog'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('LOG_UID', 'LogUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('LOG_STATUS', 'LogStatus', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('LOG_IP', 'LogIp', 'string', CreoleTypes::VARCHAR, true, 15); + + $tMap->addColumn('LOG_SID', 'LogSid', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('LOG_INIT_DATE', 'LogInitDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('LOG_END_DATE', 'LogEndDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('LOG_CLIENT_HOSTNAME', 'LogClientHostname', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // LoginLogMapBuilder diff --git a/workflow/engine/classes/model/map/ObjectPermissionMapBuilder.php b/workflow/engine/classes/model/map/ObjectPermissionMapBuilder.php new file mode 100644 index 000000000..1a24dee95 --- /dev/null +++ b/workflow/engine/classes/model/map/ObjectPermissionMapBuilder.php @@ -0,0 +1,131 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'OBJECT_PERMISSION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ObjectPermissionMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ObjectPermissionMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('OBJECT_PERMISSION'); + $tMap->setPhpName('ObjectPermission'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('OP_UID', 'OpUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('OP_USER_RELATION', 'OpUserRelation', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('OP_TASK_SOURCE', 'OpTaskSource', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('OP_PARTICIPATE', 'OpParticipate', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('OP_OBJ_TYPE', 'OpObjType', 'string', CreoleTypes::VARCHAR, true, 15); + + $tMap->addColumn('OP_OBJ_UID', 'OpObjUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('OP_ACTION', 'OpAction', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('OP_CASE_STATUS', 'OpCaseStatus', 'string', CreoleTypes::VARCHAR, false, 10); + + $tMap->addValidator('OP_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Object permission UID can be no larger than 32 in size'); + + $tMap->addValidator('OP_UID', 'required', 'propel.validator.RequiredValidator', '', 'Object permission UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('TAS_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Task UID can be no larger than 32 in size'); + + $tMap->addValidator('TAS_UID', 'required', 'propel.validator.RequiredValidator', '', 'Task UID is required.'); + + $tMap->addValidator('USR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'User or Group UID can be no larger than 32 in size'); + + $tMap->addValidator('USR_UID', 'required', 'propel.validator.RequiredValidator', '', 'User or Group UID is required.'); + + $tMap->addValidator('OP_USER_RELATION', 'validValues', 'propel.validator.ValidValuesValidator', '1|2', 'Please select a valid relation.'); + + $tMap->addValidator('OP_USER_RELATION', 'required', 'propel.validator.RequiredValidator', '', 'Relation is required.'); + + $tMap->addValidator('OP_TASK_SOURCE', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Source task UID can be no larger than 32 in size'); + + $tMap->addValidator('OP_TASK_SOURCE', 'required', 'propel.validator.RequiredValidator', '', 'Source task is required.'); + + $tMap->addValidator('OP_PARTICIPATE', 'validValues', 'propel.validator.ValidValuesValidator', '0|1', 'Please select a valid participation value.'); + + $tMap->addValidator('OP_PARTICIPATE', 'required', 'propel.validator.RequiredValidator', '', 'Participation is required.'); + + $tMap->addValidator('OP_OBJ_TYPE', 'maxLength', 'propel.validator.MaxLengthValidator', '15', 'Object type can be no larger than 15 in size'); + + $tMap->addValidator('OP_OBJ_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Object type is required.'); + + $tMap->addValidator('OP_OBJ_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Object UID can be no larger than 32 in size'); + + $tMap->addValidator('OP_OBJ_UID', 'required', 'propel.validator.RequiredValidator', '', 'Object UID is required.'); + + $tMap->addValidator('OP_ACTION', 'maxLength', 'propel.validator.MaxLengthValidator', '15', 'Action can be no larger than 15 in size'); + + $tMap->addValidator('OP_ACTION', 'required', 'propel.validator.RequiredValidator', '', 'Action is required.'); + + } // doBuild() + +} // ObjectPermissionMapBuilder diff --git a/workflow/engine/classes/model/map/OutputDocumentMapBuilder.php b/workflow/engine/classes/model/map/OutputDocumentMapBuilder.php new file mode 100644 index 000000000..24f3f75f8 --- /dev/null +++ b/workflow/engine/classes/model/map/OutputDocumentMapBuilder.php @@ -0,0 +1,111 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'OUTPUT_DOCUMENT' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class OutputDocumentMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.OutputDocumentMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('OUTPUT_DOCUMENT'); + $tMap->setPhpName('OutputDocument'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('OUT_DOC_UID', 'OutDocUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('OUT_DOC_LANDSCAPE', 'OutDocLandscape', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('OUT_DOC_MEDIA', 'OutDocMedia', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('OUT_DOC_LEFT_MARGIN', 'OutDocLeftMargin', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('OUT_DOC_RIGHT_MARGIN', 'OutDocRightMargin', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('OUT_DOC_TOP_MARGIN', 'OutDocTopMargin', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('OUT_DOC_BOTTOM_MARGIN', 'OutDocBottomMargin', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('OUT_DOC_GENERATE', 'OutDocGenerate', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('OUT_DOC_TYPE', 'OutDocType', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('OUT_DOC_CURRENT_REVISION', 'OutDocCurrentRevision', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('OUT_DOC_FIELD_MAPPING', 'OutDocFieldMapping', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('OUT_DOC_VERSIONING', 'OutDocVersioning', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('OUT_DOC_DESTINATION_PATH', 'OutDocDestinationPath', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addColumn('OUT_DOC_TAGS', 'OutDocTags', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addValidator('OUT_DOC_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Output Document UID can be no larger than 32 in size'); + + $tMap->addValidator('OUT_DOC_UID', 'required', 'propel.validator.RequiredValidator', '', 'Output Document UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('OUT_DOC_GENERATE', 'validValues', 'propel.validator.ValidValuesValidator', 'BOTH|DOC|PDF', 'Please select a outputdocument.'); + + $tMap->addValidator('OUT_DOC_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'HTML|ITEXT|JRXML|ACROFORM', 'Please select a valid Output Document Type.'); + + } // doBuild() + +} // OutputDocumentMapBuilder diff --git a/workflow/engine/classes/model/map/ProcessCategoryMapBuilder.php b/workflow/engine/classes/model/map/ProcessCategoryMapBuilder.php new file mode 100644 index 000000000..70a5705e6 --- /dev/null +++ b/workflow/engine/classes/model/map/ProcessCategoryMapBuilder.php @@ -0,0 +1,77 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'PROCESS_CATEGORY' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ProcessCategoryMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ProcessCategoryMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('PROCESS_CATEGORY'); + $tMap->setPhpName('ProcessCategory'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('CATEGORY_UID', 'CategoryUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CATEGORY_PARENT', 'CategoryParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('CATEGORY_NAME', 'CategoryName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('CATEGORY_ICON', 'CategoryIcon', 'string', CreoleTypes::VARCHAR, false, 100); + + } // doBuild() + +} // ProcessCategoryMapBuilder diff --git a/workflow/engine/classes/model/map/ProcessMapBuilder.php b/workflow/engine/classes/model/map/ProcessMapBuilder.php new file mode 100644 index 000000000..404ca72e9 --- /dev/null +++ b/workflow/engine/classes/model/map/ProcessMapBuilder.php @@ -0,0 +1,123 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'PROCESS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ProcessMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ProcessMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('PROCESS'); + $tMap->setPhpName('Process'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_PARENT', 'ProParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_TIME', 'ProTime', 'double', CreoleTypes::DOUBLE, true, null); + + $tMap->addColumn('PRO_TIMEUNIT', 'ProTimeunit', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('PRO_STATUS', 'ProStatus', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('PRO_TYPE_DAY', 'ProTypeDay', 'string', CreoleTypes::CHAR, true, 1); + + $tMap->addColumn('PRO_TYPE', 'ProType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('PRO_ASSIGNMENT', 'ProAssignment', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('PRO_SHOW_MAP', 'ProShowMap', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('PRO_SHOW_MESSAGE', 'ProShowMessage', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('PRO_SHOW_DELEGATE', 'ProShowDelegate', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('PRO_SHOW_DYNAFORM', 'ProShowDynaform', 'int', CreoleTypes::TINYINT, true, null); + + $tMap->addColumn('PRO_CATEGORY', 'ProCategory', 'string', CreoleTypes::VARCHAR, true, 48); + + $tMap->addColumn('PRO_SUB_CATEGORY', 'ProSubCategory', 'string', CreoleTypes::VARCHAR, true, 48); + + $tMap->addColumn('PRO_INDUSTRY', 'ProIndustry', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_UPDATE_DATE', 'ProUpdateDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('PRO_CREATE_DATE', 'ProCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('PRO_CREATE_USER', 'ProCreateUser', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_HEIGHT', 'ProHeight', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_WIDTH', 'ProWidth', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_TITLE_X', 'ProTitleX', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_TITLE_Y', 'ProTitleY', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('PRO_DEBUG', 'ProDebug', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('PRO_TIMEUNIT', 'validValues', 'propel.validator.ValidValuesValidator', 'WEEKS|MONTHS|DAYS|HOURS|MINUTES', 'Please select a valid Time Unit.'); + + $tMap->addValidator('PRO_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|INACTIVE|DISABLED', 'Please select a valid Process Status.'); + + $tMap->addValidator('PRO_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL', 'Please select a valid Process Type.'); + + $tMap->addValidator('PRO_ASSIGNMENT', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid Process Assignment'); + + } // doBuild() + +} // ProcessMapBuilder diff --git a/workflow/engine/classes/model/map/ProcessOwnerMapBuilder.php b/workflow/engine/classes/model/map/ProcessOwnerMapBuilder.php new file mode 100644 index 000000000..91b9e794b --- /dev/null +++ b/workflow/engine/classes/model/map/ProcessOwnerMapBuilder.php @@ -0,0 +1,73 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'PROCESS_OWNER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ProcessOwnerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ProcessOwnerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('PROCESS_OWNER'); + $tMap->setPhpName('ProcessOwner'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('OWN_UID', 'OwnUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + } // doBuild() + +} // ProcessOwnerMapBuilder diff --git a/workflow/engine/classes/model/map/ProcessUserMapBuilder.php b/workflow/engine/classes/model/map/ProcessUserMapBuilder.php new file mode 100644 index 000000000..7b4fe6dd4 --- /dev/null +++ b/workflow/engine/classes/model/map/ProcessUserMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'PROCESS_USER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ProcessUserMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ProcessUserMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('PROCESS_USER'); + $tMap->setPhpName('ProcessUser'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('PU_UID', 'PuUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PU_TYPE', 'PuType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addValidator('PU_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process User UID can be no larger than 32 in size'); + + $tMap->addValidator('PU_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process User UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('USR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'User UID can be no larger than 32 in size'); + + $tMap->addValidator('USR_UID', 'required', 'propel.validator.RequiredValidator', '', 'User UID is required.'); + + $tMap->addValidator('PU_TYPE', 'maxLength', 'propel.validator.MaxLengthValidator', '20', 'Value can be no larger than 20 in size'); + + $tMap->addValidator('PU_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Value is required.'); + + } // doBuild() + +} // ProcessUserMapBuilder diff --git a/workflow/engine/classes/model/map/ReportTableMapBuilder.php b/workflow/engine/classes/model/map/ReportTableMapBuilder.php new file mode 100644 index 000000000..266beb838 --- /dev/null +++ b/workflow/engine/classes/model/map/ReportTableMapBuilder.php @@ -0,0 +1,109 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'REPORT_TABLE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ReportTableMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ReportTableMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('REPORT_TABLE'); + $tMap->setPhpName('ReportTable'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('REP_TAB_UID', 'RepTabUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('REP_TAB_NAME', 'RepTabName', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('REP_TAB_TYPE', 'RepTabType', 'string', CreoleTypes::VARCHAR, true, 6); + + $tMap->addColumn('REP_TAB_GRID', 'RepTabGrid', 'string', CreoleTypes::VARCHAR, false, 150); + + $tMap->addColumn('REP_TAB_CONNECTION', 'RepTabConnection', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('REP_TAB_CREATE_DATE', 'RepTabCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('REP_TAB_STATUS', 'RepTabStatus', 'string', CreoleTypes::CHAR, true, 8); + + $tMap->addValidator('REP_TAB_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Report table UID can be no larger than 32 in size'); + + $tMap->addValidator('REP_TAB_UID', 'required', 'propel.validator.RequiredValidator', '', 'Report table UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('REP_TAB_NAME', 'maxLength', 'propel.validator.MaxLengthValidator', '100', 'Report table name can be no larger than 100 in size'); + + $tMap->addValidator('REP_TAB_NAME', 'required', 'propel.validator.RequiredValidator', '', 'Report table name is required.'); + + $tMap->addValidator('REP_TAB_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|GRID', 'Please select a valid type.'); + + $tMap->addValidator('REP_TAB_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Report table type is required.'); + + $tMap->addValidator('REP_TAB_CONNECTION', 'maxLength', 'propel.validator.MaxLengthValidator', '10', 'Report table connection can be no larger than 10 in size'); + + $tMap->addValidator('REP_TAB_CONNECTION', 'required', 'propel.validator.RequiredValidator', '', 'Report table connection is required.'); + + $tMap->addValidator('REP_TAB_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|INACTIVE', 'Please select a valid status.'); + + $tMap->addValidator('REP_TAB_STATUS', 'required', 'propel.validator.RequiredValidator', '', 'Report table status is required.'); + + } // doBuild() + +} // ReportTableMapBuilder diff --git a/workflow/engine/classes/model/map/ReportVarMapBuilder.php b/workflow/engine/classes/model/map/ReportVarMapBuilder.php new file mode 100644 index 000000000..a1fc9eaf8 --- /dev/null +++ b/workflow/engine/classes/model/map/ReportVarMapBuilder.php @@ -0,0 +1,95 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'REPORT_VAR' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ReportVarMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ReportVarMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('REPORT_VAR'); + $tMap->setPhpName('ReportVar'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('REP_VAR_UID', 'RepVarUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('REP_TAB_UID', 'RepTabUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('REP_VAR_NAME', 'RepVarName', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('REP_VAR_TYPE', 'RepVarType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addValidator('REP_VAR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Report variable UID can be no larger than 32 in size'); + + $tMap->addValidator('REP_VAR_UID', 'required', 'propel.validator.RequiredValidator', '', 'Report variable UID is required.'); + + $tMap->addValidator('REP_TAB_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Report table UID can be no larger than 32 in size'); + + $tMap->addValidator('REP_TAB_UID', 'required', 'propel.validator.RequiredValidator', '', 'Report variable UID is required.'); + + $tMap->addValidator('REP_VAR_NAME', 'maxLength', 'propel.validator.MaxLengthValidator', '255', 'Report variable name can be no larger than 255 in size'); + + $tMap->addValidator('REP_VAR_NAME', 'required', 'propel.validator.RequiredValidator', '', 'Report variable name is required.'); + + $tMap->addValidator('REP_VAR_TYPE', 'maxLength', 'propel.validator.MaxLengthValidator', '20', 'Report variable type can be no larger than 20 in size'); + + $tMap->addValidator('REP_VAR_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Report variable type is required.'); + + } // doBuild() + +} // ReportVarMapBuilder diff --git a/workflow/engine/classes/model/map/RouteMapBuilder.php b/workflow/engine/classes/model/map/RouteMapBuilder.php new file mode 100644 index 000000000..e4a154a1f --- /dev/null +++ b/workflow/engine/classes/model/map/RouteMapBuilder.php @@ -0,0 +1,119 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'ROUTE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class RouteMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.RouteMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('ROUTE'); + $tMap->setPhpName('Route'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('ROU_UID', 'RouUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ROU_PARENT', 'RouParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ROU_NEXT_TASK', 'RouNextTask', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ROU_CASE', 'RouCase', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('ROU_TYPE', 'RouType', 'string', CreoleTypes::VARCHAR, true, 25); + + $tMap->addColumn('ROU_CONDITION', 'RouCondition', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('ROU_TO_LAST_USER', 'RouToLastUser', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('ROU_OPTIONAL', 'RouOptional', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('ROU_SEND_EMAIL', 'RouSendEmail', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('ROU_SOURCEANCHOR', 'RouSourceanchor', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('ROU_TARGETANCHOR', 'RouTargetanchor', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addValidator('ROU_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Route UID can be no larger than 32 in size'); + + $tMap->addValidator('ROU_UID', 'required', 'propel.validator.RequiredValidator', '', 'Route UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('TAS_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Task UID can be no larger than 32 in size'); + + $tMap->addValidator('TAS_UID', 'required', 'propel.validator.RequiredValidator', '', 'Task UID is required.'); + + $tMap->addValidator('ROU_NEXT_TASK', 'required', 'propel.validator.RequiredValidator', '', 'Next Task UID is required.'); + + $tMap->addValidator('ROU_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'SEQUENTIAL|EVALUATE|SELECT|PARALLEL|PARALLEL-BY-EVALUATION|SEC-JOIN', 'Please select a valid Route Type.'); + + $tMap->addValidator('ROU_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Route type is required.'); + + $tMap->addValidator('ROU_TO_LAST_USER', 'validValues', 'propel.validator.ValidValuesValidator', 'FALSE|TRUE', 'Please select a valid value for ROU_TO_LAST_USER .'); + + $tMap->addValidator('ROU_OPTIONAL', 'validValues', 'propel.validator.ValidValuesValidator', 'FALSE|TRUE', 'Please select a valid value for ROU_OPTIONAL .'); + + $tMap->addValidator('ROU_SEND_EMAIL', 'validValues', 'propel.validator.ValidValuesValidator', 'FALSE|TRUE', 'Please select a valid value for ROU_SEND_EMAIL.'); + + } // doBuild() + +} // RouteMapBuilder diff --git a/workflow/engine/classes/model/map/SessionMapBuilder.php b/workflow/engine/classes/model/map/SessionMapBuilder.php new file mode 100644 index 000000000..4e26e2104 --- /dev/null +++ b/workflow/engine/classes/model/map/SessionMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'SESSION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class SessionMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.SessionMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('SESSION'); + $tMap->setPhpName('Session'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('SES_UID', 'SesUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SES_STATUS', 'SesStatus', 'string', CreoleTypes::VARCHAR, true, 16); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SES_REMOTE_IP', 'SesRemoteIp', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SES_INIT_DATE', 'SesInitDate', 'string', CreoleTypes::VARCHAR, true, 19); + + $tMap->addColumn('SES_DUE_DATE', 'SesDueDate', 'string', CreoleTypes::VARCHAR, true, 19); + + $tMap->addColumn('SES_END_DATE', 'SesEndDate', 'string', CreoleTypes::VARCHAR, true, 19); + + } // doBuild() + +} // SessionMapBuilder diff --git a/workflow/engine/classes/model/map/ShadowTableMapBuilder.php b/workflow/engine/classes/model/map/ShadowTableMapBuilder.php new file mode 100644 index 000000000..445630f1e --- /dev/null +++ b/workflow/engine/classes/model/map/ShadowTableMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'SHADOW_TABLE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class ShadowTableMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.ShadowTableMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('SHADOW_TABLE'); + $tMap->setPhpName('ShadowTable'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('SHD_UID', 'ShdUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('ADD_TAB_UID', 'AddTabUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SHD_ACTION', 'ShdAction', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('SHD_DETAILS', 'ShdDetails', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SHD_DATE', 'ShdDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + } // doBuild() + +} // ShadowTableMapBuilder diff --git a/workflow/engine/classes/model/map/StageMapBuilder.php b/workflow/engine/classes/model/map/StageMapBuilder.php new file mode 100644 index 000000000..8bbca4f5a --- /dev/null +++ b/workflow/engine/classes/model/map/StageMapBuilder.php @@ -0,0 +1,79 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'STAGE' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class StageMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.StageMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('STAGE'); + $tMap->setPhpName('Stage'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('STG_UID', 'StgUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STG_POSX', 'StgPosx', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('STG_POSY', 'StgPosy', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('STG_INDEX', 'StgIndex', 'int', CreoleTypes::INTEGER, true, null); + + } // doBuild() + +} // StageMapBuilder diff --git a/workflow/engine/classes/model/map/StepMapBuilder.php b/workflow/engine/classes/model/map/StepMapBuilder.php new file mode 100644 index 000000000..2b3d0f25a --- /dev/null +++ b/workflow/engine/classes/model/map/StepMapBuilder.php @@ -0,0 +1,87 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'STEP' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class StepMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.StepMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('STEP'); + $tMap->setPhpName('Step'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('STEP_UID', 'StepUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STEP_TYPE_OBJ', 'StepTypeObj', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('STEP_UID_OBJ', 'StepUidObj', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STEP_CONDITION', 'StepCondition', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('STEP_POSITION', 'StepPosition', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('STEP_MODE', 'StepMode', 'string', CreoleTypes::VARCHAR, false, 10); + + $tMap->addValidator('STEP_TYPE_OBJ', 'validValues', 'propel.validator.ValidValuesValidator', 'DYNAFORM|INPUT_DOCUMENT|MESSAGE|OUTPUT_DOCUMENT|EXTERNAL', 'Please select a valid value for STEP_TYPE_OBJ.'); + + } // doBuild() + +} // StepMapBuilder diff --git a/workflow/engine/classes/model/map/StepSupervisorMapBuilder.php b/workflow/engine/classes/model/map/StepSupervisorMapBuilder.php new file mode 100644 index 000000000..6356b8283 --- /dev/null +++ b/workflow/engine/classes/model/map/StepSupervisorMapBuilder.php @@ -0,0 +1,81 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'STEP_SUPERVISOR' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class StepSupervisorMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.StepSupervisorMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('STEP_SUPERVISOR'); + $tMap->setPhpName('StepSupervisor'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('STEP_UID', 'StepUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STEP_TYPE_OBJ', 'StepTypeObj', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('STEP_UID_OBJ', 'StepUidObj', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STEP_POSITION', 'StepPosition', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('STEP_TYPE_OBJ', 'validValues', 'propel.validator.ValidValuesValidator', 'DYNAFORM|INPUT_DOCUMENT|OUTPUT_DOCUMENT', 'Please select a valid value for STEP_TYPE_OBJ.'); + + } // doBuild() + +} // StepSupervisorMapBuilder diff --git a/workflow/engine/classes/model/map/StepTriggerMapBuilder.php b/workflow/engine/classes/model/map/StepTriggerMapBuilder.php new file mode 100644 index 000000000..c938beb7e --- /dev/null +++ b/workflow/engine/classes/model/map/StepTriggerMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'STEP_TRIGGER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class StepTriggerMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.StepTriggerMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('STEP_TRIGGER'); + $tMap->setPhpName('StepTrigger'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('STEP_UID', 'StepUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('TRI_UID', 'TriUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('ST_TYPE', 'StType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('ST_CONDITION', 'StCondition', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('ST_POSITION', 'StPosition', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('ST_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'BEFORE|AFTER', 'Please select a valid value for Trigger Type ST_TYPE.'); + + } // doBuild() + +} // StepTriggerMapBuilder diff --git a/workflow/engine/classes/model/map/SubApplicationMapBuilder.php b/workflow/engine/classes/model/map/SubApplicationMapBuilder.php new file mode 100644 index 000000000..9370197c8 --- /dev/null +++ b/workflow/engine/classes/model/map/SubApplicationMapBuilder.php @@ -0,0 +1,89 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'SUB_APPLICATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class SubApplicationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.SubApplicationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('SUB_APPLICATION'); + $tMap->setPhpName('SubApplication'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('APP_UID', 'AppUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('APP_PARENT', 'AppParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('DEL_INDEX_PARENT', 'DelIndexParent', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addPrimaryKey('DEL_THREAD_PARENT', 'DelThreadParent', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('SA_STATUS', 'SaStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SA_VALUES_OUT', 'SaValuesOut', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('SA_VALUES_IN', 'SaValuesIn', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('SA_INIT_DATE', 'SaInitDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('SA_FINISH_DATE', 'SaFinishDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addValidator('SA_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|FINISHED|CANCELLED', 'Please select a valid value for SA_STATUS.'); + + } // doBuild() + +} // SubApplicationMapBuilder diff --git a/workflow/engine/classes/model/map/SubProcessMapBuilder.php b/workflow/engine/classes/model/map/SubProcessMapBuilder.php new file mode 100644 index 000000000..9791ba0f3 --- /dev/null +++ b/workflow/engine/classes/model/map/SubProcessMapBuilder.php @@ -0,0 +1,99 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'SUB_PROCESS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class SubProcessMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.SubProcessMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('SUB_PROCESS'); + $tMap->setPhpName('SubProcess'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('SP_UID', 'SpUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_PARENT', 'ProParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_PARENT', 'TasParent', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SP_TYPE', 'SpType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('SP_SYNCHRONOUS', 'SpSynchronous', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('SP_SYNCHRONOUS_TYPE', 'SpSynchronousType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('SP_SYNCHRONOUS_WAIT', 'SpSynchronousWait', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('SP_VARIABLES_OUT', 'SpVariablesOut', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('SP_VARIABLES_IN', 'SpVariablesIn', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('SP_GRID_IN', 'SpGridIn', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addValidator('SP_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'SIMPLE|MULTIPLE', 'Please select a valid value for SP_TYPE.'); + + $tMap->addValidator('SP_SYNCHRONOUS', 'validValues', 'propel.validator.ValidValuesValidator', '1|0', 'Please select a valid value for SP_SYNCHRONOUS.'); + + $tMap->addValidator('SP_SYNCHRONOUS_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'ALL|INSTANCES|TIME', 'Please select a valid value for SP_SYNCHRONOUS_TYPE.'); + + } // doBuild() + +} // SubProcessMapBuilder diff --git a/workflow/engine/classes/model/map/SwimlanesElementsMapBuilder.php b/workflow/engine/classes/model/map/SwimlanesElementsMapBuilder.php new file mode 100644 index 000000000..e4023d96c --- /dev/null +++ b/workflow/engine/classes/model/map/SwimlanesElementsMapBuilder.php @@ -0,0 +1,91 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'SWIMLANES_ELEMENTS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class SwimlanesElementsMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.SwimlanesElementsMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('SWIMLANES_ELEMENTS'); + $tMap->setPhpName('SwimlanesElements'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('SWI_UID', 'SwiUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('SWI_TYPE', 'SwiType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('SWI_X', 'SwiX', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('SWI_Y', 'SwiY', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('SWI_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Swimlane Element UID can be no larger than 32 in size'); + + $tMap->addValidator('SWI_UID', 'required', 'propel.validator.RequiredValidator', '', 'Swimlane Element UID is required.'); + + $tMap->addValidator('PRO_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Process UID can be no larger than 32 in size'); + + $tMap->addValidator('PRO_UID', 'required', 'propel.validator.RequiredValidator', '', 'Process UID is required.'); + + $tMap->addValidator('SWI_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'LINE|TEXT', 'Please select a valid Swimlane Element type.'); + + $tMap->addValidator('SWI_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Swimlane Element type is required.'); + + } // doBuild() + +} // SwimlanesElementsMapBuilder diff --git a/workflow/engine/classes/model/map/TaskMapBuilder.php b/workflow/engine/classes/model/map/TaskMapBuilder.php new file mode 100644 index 000000000..003e47de9 --- /dev/null +++ b/workflow/engine/classes/model/map/TaskMapBuilder.php @@ -0,0 +1,175 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'TASK' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class TaskMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.TaskMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('TASK'); + $tMap->setPhpName('Task'); + + $tMap->setUseIdGenerator(false); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_TYPE', 'TasType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_DURATION', 'TasDuration', 'double', CreoleTypes::DOUBLE, true, null); + + $tMap->addColumn('TAS_DELAY_TYPE', 'TasDelayType', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addColumn('TAS_TEMPORIZER', 'TasTemporizer', 'double', CreoleTypes::DOUBLE, true, null); + + $tMap->addColumn('TAS_TYPE_DAY', 'TasTypeDay', 'string', CreoleTypes::CHAR, true, 1); + + $tMap->addColumn('TAS_TIMEUNIT', 'TasTimeunit', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_ALERT', 'TasAlert', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_PRIORITY_VARIABLE', 'TasPriorityVariable', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('TAS_ASSIGN_TYPE', 'TasAssignType', 'string', CreoleTypes::VARCHAR, true, 30); + + $tMap->addColumn('TAS_ASSIGN_VARIABLE', 'TasAssignVariable', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('TAS_ASSIGN_LOCATION', 'TasAssignLocation', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_ASSIGN_LOCATION_ADHOC', 'TasAssignLocationAdhoc', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_TRANSFER_FLY', 'TasTransferFly', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_LAST_ASSIGNED', 'TasLastAssigned', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_USER', 'TasUser', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_CAN_UPLOAD', 'TasCanUpload', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_VIEW_UPLOAD', 'TasViewUpload', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_VIEW_ADDITIONAL_DOCUMENTATION', 'TasViewAdditionalDocumentation', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_CAN_CANCEL', 'TasCanCancel', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_OWNER_APP', 'TasOwnerApp', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('STG_UID', 'StgUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TAS_CAN_PAUSE', 'TasCanPause', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_CAN_SEND_MESSAGE', 'TasCanSendMessage', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_CAN_DELETE_DOCS', 'TasCanDeleteDocs', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_SELF_SERVICE', 'TasSelfService', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_START', 'TasStart', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_TO_LAST_USER', 'TasToLastUser', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_SEND_LAST_EMAIL', 'TasSendLastEmail', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TAS_DERIVATION', 'TasDerivation', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('TAS_POSX', 'TasPosx', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('TAS_POSY', 'TasPosy', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addColumn('TAS_COLOR', 'TasColor', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addValidator('TAS_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|ADHOC|SUBPROCESS', 'Please select a valid value for TAS_TYPE.'); + + $tMap->addValidator('TAS_TIMEUNIT', 'validValues', 'propel.validator.ValidValuesValidator', 'MINUTES|HOURS|DAYS|WEEKS|MONTHS', 'Please select a valid value for TAS_TIMEUNIT.'); + + $tMap->addValidator('TAS_ALERT', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_ALERT.'); + + $tMap->addValidator('TAS_ASSIGN_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'BALANCED|MANUAL|EVALUATE|REPORT_TO|SELF_SERVICE', 'Please select a valid value for TAS_ASSIGN_TYPE.'); + + $tMap->addValidator('TAS_ASSIGN_LOCATION', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_ASSIGN_LOCATION.'); + + $tMap->addValidator('TAS_ASSIGN_LOCATION_ADHOC', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_ASSIGN_LOCATION_ADHOC.'); + + $tMap->addValidator('TAS_TRANSFER_FLY', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_TRANSFER_FLY.'); + + $tMap->addValidator('TAS_CAN_UPLOAD', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_CAN_UPLOAD.'); + + $tMap->addValidator('TAS_VIEW_UPLOAD', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_VIEW_UPLOAD.'); + + $tMap->addValidator('TAS_VIEW_ADDITIONAL_DOCUMENTATION', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_VIEW_ADDITIONAL_DOCUMENTATION.'); + + $tMap->addValidator('TAS_CAN_CANCEL', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_CAN_CANCEL.'); + + $tMap->addValidator('TAS_CAN_PAUSE', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_CAN_PAUSE.'); + + $tMap->addValidator('TAS_CAN_SEND_MESSAGE', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_CAN_SEND_MESSAGE.'); + + $tMap->addValidator('TAS_CAN_DELETE_DOCS', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|VIEW|FALSE', 'Please select a valid value for TAS_CAN_DELETE_DOCS.'); + + $tMap->addValidator('TAS_SELF_SERVICE', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_SELF_SERVICE.'); + + $tMap->addValidator('TAS_START', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_START.'); + + $tMap->addValidator('TAS_TO_LAST_USER', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_TO_LAST_USER.'); + + $tMap->addValidator('TAS_SEND_LAST_EMAIL', 'validValues', 'propel.validator.ValidValuesValidator', 'TRUE|FALSE', 'Please select a valid value for TAS_SEND_LAST_EMAIL.'); + + $tMap->addValidator('TAS_DERIVATION', 'validValues', 'propel.validator.ValidValuesValidator', 'NORMAL|FAST|AUTOMATIC', 'Please select a valid value for TAS_DERIVATION.'); + + } // doBuild() + +} // TaskMapBuilder diff --git a/workflow/engine/classes/model/map/TaskUserMapBuilder.php b/workflow/engine/classes/model/map/TaskUserMapBuilder.php new file mode 100644 index 000000000..d86598410 --- /dev/null +++ b/workflow/engine/classes/model/map/TaskUserMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'TASK_USER' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class TaskUserMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.TaskUserMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('TASK_USER'); + $tMap->setPhpName('TaskUser'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('TAS_UID', 'TasUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addPrimaryKey('TU_TYPE', 'TuType', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addPrimaryKey('TU_RELATION', 'TuRelation', 'int', CreoleTypes::INTEGER, true, null); + + $tMap->addValidator('TAS_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'Task UID can be no larger than 32 in size'); + + $tMap->addValidator('TAS_UID', 'required', 'propel.validator.RequiredValidator', '', 'Task UID is required.'); + + $tMap->addValidator('USR_UID', 'maxLength', 'propel.validator.MaxLengthValidator', '32', 'User UID can be no larger than 32 in size'); + + $tMap->addValidator('USR_UID', 'required', 'propel.validator.RequiredValidator', '', 'User UID is required.'); + + $tMap->addValidator('TU_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', '1|2', 'Please select a valid type.'); + + $tMap->addValidator('TU_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Type is required.'); + + $tMap->addValidator('TU_RELATION', 'validValues', 'propel.validator.ValidValuesValidator', '1|2', 'Please select a valid relation.'); + + $tMap->addValidator('TU_RELATION', 'required', 'propel.validator.RequiredValidator', '', 'Relation is required.'); + + } // doBuild() + +} // TaskUserMapBuilder diff --git a/workflow/engine/classes/model/map/TranslationMapBuilder.php b/workflow/engine/classes/model/map/TranslationMapBuilder.php new file mode 100644 index 000000000..eceb9466f --- /dev/null +++ b/workflow/engine/classes/model/map/TranslationMapBuilder.php @@ -0,0 +1,93 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'TRANSLATION' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class TranslationMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.TranslationMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('TRANSLATION'); + $tMap->setPhpName('Translation'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('TRN_CATEGORY', 'TrnCategory', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addPrimaryKey('TRN_ID', 'TrnId', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addPrimaryKey('TRN_LANG', 'TrnLang', 'string', CreoleTypes::VARCHAR, true, 10); + + $tMap->addColumn('TRN_VALUE', 'TrnValue', 'string', CreoleTypes::VARCHAR, true, 200); + + $tMap->addValidator('TRN_CATEGORY', 'maxLength', 'propel.validator.MaxLengthValidator', '100', 'Category can be no larger than 100 in size'); + + $tMap->addValidator('TRN_CATEGORY', 'required', 'propel.validator.RequiredValidator', '', 'Category is required.'); + + $tMap->addValidator('TRN_ID', 'maxLength', 'propel.validator.MaxLengthValidator', '100', 'ID can be no larger than 100 in size'); + + $tMap->addValidator('TRN_ID', 'required', 'propel.validator.RequiredValidator', '', 'ID is required.'); + + $tMap->addValidator('TRN_LANG', 'maxLength', 'propel.validator.MaxLengthValidator', '5', 'Language can be no larger than 5 in size'); + + $tMap->addValidator('TRN_LANG', 'required', 'propel.validator.RequiredValidator', '', 'Language is required.'); + + $tMap->addValidator('TRN_VALUE', 'maxLength', 'propel.validator.MaxLengthValidator', '200', 'Value can be no larger than 200 in size'); + + $tMap->addValidator('TRN_VALUE', 'required', 'propel.validator.RequiredValidator', '', 'Value is required.'); + + } // doBuild() + +} // TranslationMapBuilder diff --git a/workflow/engine/classes/model/map/TriggersMapBuilder.php b/workflow/engine/classes/model/map/TriggersMapBuilder.php new file mode 100644 index 000000000..06ddf1f67 --- /dev/null +++ b/workflow/engine/classes/model/map/TriggersMapBuilder.php @@ -0,0 +1,83 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'TRIGGERS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class TriggersMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.TriggersMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('TRIGGERS'); + $tMap->setPhpName('Triggers'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('TRI_UID', 'TriUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('PRO_UID', 'ProUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('TRI_TYPE', 'TriType', 'string', CreoleTypes::VARCHAR, true, 20); + + $tMap->addColumn('TRI_WEBBOT', 'TriWebbot', 'string', CreoleTypes::LONGVARCHAR, true, null); + + $tMap->addColumn('TRI_PARAM', 'TriParam', 'string', CreoleTypes::LONGVARCHAR, false, null); + + $tMap->addValidator('TRI_TYPE', 'validValues', 'propel.validator.ValidValuesValidator', 'WEBBOT|SCRIPT', 'Please select a valid type.'); + + $tMap->addValidator('TRI_TYPE', 'required', 'propel.validator.RequiredValidator', '', 'Type is required.'); + + } // doBuild() + +} // TriggersMapBuilder diff --git a/workflow/engine/classes/model/map/UsersMapBuilder.php b/workflow/engine/classes/model/map/UsersMapBuilder.php new file mode 100644 index 000000000..10598983e --- /dev/null +++ b/workflow/engine/classes/model/map/UsersMapBuilder.php @@ -0,0 +1,123 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'USERS' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class UsersMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.UsersMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('USERS'); + $tMap->setPhpName('Users'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_USERNAME', 'UsrUsername', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('USR_PASSWORD', 'UsrPassword', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_FIRSTNAME', 'UsrFirstname', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addColumn('USR_LASTNAME', 'UsrLastname', 'string', CreoleTypes::VARCHAR, true, 50); + + $tMap->addColumn('USR_EMAIL', 'UsrEmail', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('USR_DUE_DATE', 'UsrDueDate', 'int', CreoleTypes::DATE, true, null); + + $tMap->addColumn('USR_CREATE_DATE', 'UsrCreateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('USR_UPDATE_DATE', 'UsrUpdateDate', 'int', CreoleTypes::TIMESTAMP, true, null); + + $tMap->addColumn('USR_STATUS', 'UsrStatus', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_COUNTRY', 'UsrCountry', 'string', CreoleTypes::VARCHAR, true, 3); + + $tMap->addColumn('USR_CITY', 'UsrCity', 'string', CreoleTypes::VARCHAR, true, 3); + + $tMap->addColumn('USR_LOCATION', 'UsrLocation', 'string', CreoleTypes::VARCHAR, true, 3); + + $tMap->addColumn('USR_ADDRESS', 'UsrAddress', 'string', CreoleTypes::VARCHAR, true, 255); + + $tMap->addColumn('USR_PHONE', 'UsrPhone', 'string', CreoleTypes::VARCHAR, true, 24); + + $tMap->addColumn('USR_FAX', 'UsrFax', 'string', CreoleTypes::VARCHAR, true, 24); + + $tMap->addColumn('USR_CELLULAR', 'UsrCellular', 'string', CreoleTypes::VARCHAR, true, 24); + + $tMap->addColumn('USR_ZIP_CODE', 'UsrZipCode', 'string', CreoleTypes::VARCHAR, true, 16); + + $tMap->addColumn('DEP_UID', 'DepUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_POSITION', 'UsrPosition', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('USR_RESUME', 'UsrResume', 'string', CreoleTypes::VARCHAR, true, 100); + + $tMap->addColumn('USR_BIRTHDAY', 'UsrBirthday', 'int', CreoleTypes::DATE, true, null); + + $tMap->addColumn('USR_ROLE', 'UsrRole', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('USR_REPORTS_TO', 'UsrReportsTo', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addColumn('USR_REPLACED_BY', 'UsrReplacedBy', 'string', CreoleTypes::VARCHAR, false, 32); + + $tMap->addValidator('USR_STATUS', 'validValues', 'propel.validator.ValidValuesValidator', 'ACTIVE|INACTIVE|VACATION|CLOSED', 'Please select a valid type.'); + + $tMap->addValidator('USR_STATUS', 'required', 'propel.validator.RequiredValidator', '', 'Type is required.'); + + } // doBuild() + +} // UsersMapBuilder diff --git a/workflow/engine/classes/model/map/UsersPropertiesMapBuilder.php b/workflow/engine/classes/model/map/UsersPropertiesMapBuilder.php new file mode 100644 index 000000000..20a106862 --- /dev/null +++ b/workflow/engine/classes/model/map/UsersPropertiesMapBuilder.php @@ -0,0 +1,77 @@ +<?php + +require_once 'propel/map/MapBuilder.php'; +include_once 'creole/CreoleTypes.php'; + + +/** + * This class adds structure of 'USERS_PROPERTIES' table to 'workflow' DatabaseMap object. + * + * + * + * These statically-built map classes are used by Propel to do runtime db structure discovery. + * For example, the createSelectSql() method checks the type of a given column used in an + * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive + * (i.e. if it's a text column type). + * + * @package classes.model.map + */ +class UsersPropertiesMapBuilder { + + /** + * The (dot-path) name of this class + */ + const CLASS_NAME = 'classes.model.map.UsersPropertiesMapBuilder'; + + /** + * The database map. + */ + private $dbMap; + + /** + * Tells us if this DatabaseMapBuilder is built so that we + * don't have to re-build it every time. + * + * @return boolean true if this DatabaseMapBuilder is built, false otherwise. + */ + public function isBuilt() + { + return ($this->dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('USERS_PROPERTIES'); + $tMap->setPhpName('UsersProperties'); + + $tMap->setUseIdGenerator(false); + + $tMap->addPrimaryKey('USR_UID', 'UsrUid', 'string', CreoleTypes::VARCHAR, true, 32); + + $tMap->addColumn('USR_LAST_UPDATE_DATE', 'UsrLastUpdateDate', 'int', CreoleTypes::TIMESTAMP, false, null); + + $tMap->addColumn('USR_LOGGED_NEXT_TIME', 'UsrLoggedNextTime', 'int', CreoleTypes::INTEGER, false, null); + + $tMap->addColumn('USR_PASSWORD_HISTORY', 'UsrPasswordHistory', 'string', CreoleTypes::LONGVARCHAR, false, null); + + } // doBuild() + +} // UsersPropertiesMapBuilder diff --git a/workflow/engine/classes/model/om/.directory b/workflow/engine/classes/model/om/.directory new file mode 100644 index 000000000..350296fd0 --- /dev/null +++ b/workflow/engine/classes/model/om/.directory @@ -0,0 +1,4 @@ +[Dolphin] +ShowPreview=false +Timestamp=2010,3,29,12,45,54 +ViewMode=1 diff --git a/workflow/engine/classes/model/om/BaseAdditionalTables.php b/workflow/engine/classes/model/om/BaseAdditionalTables.php new file mode 100644 index 000000000..ce52a4051 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAdditionalTables.php @@ -0,0 +1,1087 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AdditionalTablesPeer.php'; + +/** + * Base class that represents a row from the 'ADDITIONAL_TABLES' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAdditionalTables extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AdditionalTablesPeer + */ + protected static $peer; + + + /** + * The value for the add_tab_uid field. + * @var string + */ + protected $add_tab_uid = ''; + + + /** + * The value for the add_tab_name field. + * @var string + */ + protected $add_tab_name = ''; + + + /** + * The value for the add_tab_class_name field. + * @var string + */ + protected $add_tab_class_name = ''; + + + /** + * The value for the add_tab_description field. + * @var string + */ + protected $add_tab_description; + + + /** + * The value for the add_tab_sdw_log_insert field. + * @var int + */ + protected $add_tab_sdw_log_insert = 1; + + + /** + * The value for the add_tab_sdw_log_update field. + * @var int + */ + protected $add_tab_sdw_log_update = 1; + + + /** + * The value for the add_tab_sdw_log_delete field. + * @var int + */ + protected $add_tab_sdw_log_delete = 1; + + + /** + * The value for the add_tab_sdw_log_select field. + * @var int + */ + protected $add_tab_sdw_log_select = 0; + + + /** + * The value for the add_tab_sdw_max_length field. + * @var int + */ + protected $add_tab_sdw_max_length = -1; + + + /** + * The value for the add_tab_sdw_auto_delete field. + * @var int + */ + protected $add_tab_sdw_auto_delete = 0; + + + /** + * The value for the add_tab_plg_uid field. + * @var string + */ + protected $add_tab_plg_uid = ''; + + + /** + * The value for the dbs_uid field. + * @var string + */ + protected $dbs_uid = '0'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [add_tab_uid] column value. + * + * @return string + */ + public function getAddTabUid() + { + + return $this->add_tab_uid; + } + + /** + * Get the [add_tab_name] column value. + * + * @return string + */ + public function getAddTabName() + { + + return $this->add_tab_name; + } + + /** + * Get the [add_tab_class_name] column value. + * + * @return string + */ + public function getAddTabClassName() + { + + return $this->add_tab_class_name; + } + + /** + * Get the [add_tab_description] column value. + * + * @return string + */ + public function getAddTabDescription() + { + + return $this->add_tab_description; + } + + /** + * Get the [add_tab_sdw_log_insert] column value. + * + * @return int + */ + public function getAddTabSdwLogInsert() + { + + return $this->add_tab_sdw_log_insert; + } + + /** + * Get the [add_tab_sdw_log_update] column value. + * + * @return int + */ + public function getAddTabSdwLogUpdate() + { + + return $this->add_tab_sdw_log_update; + } + + /** + * Get the [add_tab_sdw_log_delete] column value. + * + * @return int + */ + public function getAddTabSdwLogDelete() + { + + return $this->add_tab_sdw_log_delete; + } + + /** + * Get the [add_tab_sdw_log_select] column value. + * + * @return int + */ + public function getAddTabSdwLogSelect() + { + + return $this->add_tab_sdw_log_select; + } + + /** + * Get the [add_tab_sdw_max_length] column value. + * + * @return int + */ + public function getAddTabSdwMaxLength() + { + + return $this->add_tab_sdw_max_length; + } + + /** + * Get the [add_tab_sdw_auto_delete] column value. + * + * @return int + */ + public function getAddTabSdwAutoDelete() + { + + return $this->add_tab_sdw_auto_delete; + } + + /** + * Get the [add_tab_plg_uid] column value. + * + * @return string + */ + public function getAddTabPlgUid() + { + + return $this->add_tab_plg_uid; + } + + /** + * Get the [dbs_uid] column value. + * + * @return string + */ + public function getDbsUid() + { + + return $this->dbs_uid; + } + + /** + * Set the value of [add_tab_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_uid !== $v || $v === '') { + $this->add_tab_uid = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_UID; + } + + } // setAddTabUid() + + /** + * Set the value of [add_tab_name] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_name !== $v || $v === '') { + $this->add_tab_name = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_NAME; + } + + } // setAddTabName() + + /** + * Set the value of [add_tab_class_name] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabClassName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_class_name !== $v || $v === '') { + $this->add_tab_class_name = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_CLASS_NAME; + } + + } // setAddTabClassName() + + /** + * Set the value of [add_tab_description] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabDescription($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_description !== $v) { + $this->add_tab_description = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_DESCRIPTION; + } + + } // setAddTabDescription() + + /** + * Set the value of [add_tab_sdw_log_insert] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwLogInsert($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_log_insert !== $v || $v === 1) { + $this->add_tab_sdw_log_insert = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT; + } + + } // setAddTabSdwLogInsert() + + /** + * Set the value of [add_tab_sdw_log_update] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwLogUpdate($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_log_update !== $v || $v === 1) { + $this->add_tab_sdw_log_update = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE; + } + + } // setAddTabSdwLogUpdate() + + /** + * Set the value of [add_tab_sdw_log_delete] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwLogDelete($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_log_delete !== $v || $v === 1) { + $this->add_tab_sdw_log_delete = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE; + } + + } // setAddTabSdwLogDelete() + + /** + * Set the value of [add_tab_sdw_log_select] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwLogSelect($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_log_select !== $v || $v === 0) { + $this->add_tab_sdw_log_select = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT; + } + + } // setAddTabSdwLogSelect() + + /** + * Set the value of [add_tab_sdw_max_length] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwMaxLength($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_max_length !== $v || $v === -1) { + $this->add_tab_sdw_max_length = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH; + } + + } // setAddTabSdwMaxLength() + + /** + * Set the value of [add_tab_sdw_auto_delete] column. + * + * @param int $v new value + * @return void + */ + public function setAddTabSdwAutoDelete($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->add_tab_sdw_auto_delete !== $v || $v === 0) { + $this->add_tab_sdw_auto_delete = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE; + } + + } // setAddTabSdwAutoDelete() + + /** + * Set the value of [add_tab_plg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabPlgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_plg_uid !== $v || $v === '') { + $this->add_tab_plg_uid = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::ADD_TAB_PLG_UID; + } + + } // setAddTabPlgUid() + + /** + * Set the value of [dbs_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDbsUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_uid !== $v || $v === '0') { + $this->dbs_uid = $v; + $this->modifiedColumns[] = AdditionalTablesPeer::DBS_UID; + } + + } // setDbsUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->add_tab_uid = $rs->getString($startcol + 0); + + $this->add_tab_name = $rs->getString($startcol + 1); + + $this->add_tab_class_name = $rs->getString($startcol + 2); + + $this->add_tab_description = $rs->getString($startcol + 3); + + $this->add_tab_sdw_log_insert = $rs->getInt($startcol + 4); + + $this->add_tab_sdw_log_update = $rs->getInt($startcol + 5); + + $this->add_tab_sdw_log_delete = $rs->getInt($startcol + 6); + + $this->add_tab_sdw_log_select = $rs->getInt($startcol + 7); + + $this->add_tab_sdw_max_length = $rs->getInt($startcol + 8); + + $this->add_tab_sdw_auto_delete = $rs->getInt($startcol + 9); + + $this->add_tab_plg_uid = $rs->getString($startcol + 10); + + $this->dbs_uid = $rs->getString($startcol + 11); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 12; // 12 = AdditionalTablesPeer::NUM_COLUMNS - AdditionalTablesPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AdditionalTables object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AdditionalTablesPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AdditionalTablesPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AdditionalTablesPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AdditionalTablesPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AdditionalTablesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAddTabUid(); + break; + case 1: + return $this->getAddTabName(); + break; + case 2: + return $this->getAddTabClassName(); + break; + case 3: + return $this->getAddTabDescription(); + break; + case 4: + return $this->getAddTabSdwLogInsert(); + break; + case 5: + return $this->getAddTabSdwLogUpdate(); + break; + case 6: + return $this->getAddTabSdwLogDelete(); + break; + case 7: + return $this->getAddTabSdwLogSelect(); + break; + case 8: + return $this->getAddTabSdwMaxLength(); + break; + case 9: + return $this->getAddTabSdwAutoDelete(); + break; + case 10: + return $this->getAddTabPlgUid(); + break; + case 11: + return $this->getDbsUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AdditionalTablesPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAddTabUid(), + $keys[1] => $this->getAddTabName(), + $keys[2] => $this->getAddTabClassName(), + $keys[3] => $this->getAddTabDescription(), + $keys[4] => $this->getAddTabSdwLogInsert(), + $keys[5] => $this->getAddTabSdwLogUpdate(), + $keys[6] => $this->getAddTabSdwLogDelete(), + $keys[7] => $this->getAddTabSdwLogSelect(), + $keys[8] => $this->getAddTabSdwMaxLength(), + $keys[9] => $this->getAddTabSdwAutoDelete(), + $keys[10] => $this->getAddTabPlgUid(), + $keys[11] => $this->getDbsUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AdditionalTablesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAddTabUid($value); + break; + case 1: + $this->setAddTabName($value); + break; + case 2: + $this->setAddTabClassName($value); + break; + case 3: + $this->setAddTabDescription($value); + break; + case 4: + $this->setAddTabSdwLogInsert($value); + break; + case 5: + $this->setAddTabSdwLogUpdate($value); + break; + case 6: + $this->setAddTabSdwLogDelete($value); + break; + case 7: + $this->setAddTabSdwLogSelect($value); + break; + case 8: + $this->setAddTabSdwMaxLength($value); + break; + case 9: + $this->setAddTabSdwAutoDelete($value); + break; + case 10: + $this->setAddTabPlgUid($value); + break; + case 11: + $this->setDbsUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AdditionalTablesPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAddTabUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAddTabName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAddTabClassName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAddTabDescription($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAddTabSdwLogInsert($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAddTabSdwLogUpdate($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAddTabSdwLogDelete($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAddTabSdwLogSelect($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAddTabSdwMaxLength($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAddTabSdwAutoDelete($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setAddTabPlgUid($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setDbsUid($arr[$keys[11]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AdditionalTablesPeer::DATABASE_NAME); + + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_UID)) $criteria->add(AdditionalTablesPeer::ADD_TAB_UID, $this->add_tab_uid); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_NAME)) $criteria->add(AdditionalTablesPeer::ADD_TAB_NAME, $this->add_tab_name); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_CLASS_NAME)) $criteria->add(AdditionalTablesPeer::ADD_TAB_CLASS_NAME, $this->add_tab_class_name); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_DESCRIPTION)) $criteria->add(AdditionalTablesPeer::ADD_TAB_DESCRIPTION, $this->add_tab_description); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT, $this->add_tab_sdw_log_insert); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE, $this->add_tab_sdw_log_update); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE, $this->add_tab_sdw_log_delete); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT, $this->add_tab_sdw_log_select); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH, $this->add_tab_sdw_max_length); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE)) $criteria->add(AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE, $this->add_tab_sdw_auto_delete); + if ($this->isColumnModified(AdditionalTablesPeer::ADD_TAB_PLG_UID)) $criteria->add(AdditionalTablesPeer::ADD_TAB_PLG_UID, $this->add_tab_plg_uid); + if ($this->isColumnModified(AdditionalTablesPeer::DBS_UID)) $criteria->add(AdditionalTablesPeer::DBS_UID, $this->dbs_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AdditionalTablesPeer::DATABASE_NAME); + + $criteria->add(AdditionalTablesPeer::ADD_TAB_UID, $this->add_tab_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getAddTabUid(); + } + + /** + * Generic method to set the primary key (add_tab_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setAddTabUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AdditionalTables (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAddTabName($this->add_tab_name); + + $copyObj->setAddTabClassName($this->add_tab_class_name); + + $copyObj->setAddTabDescription($this->add_tab_description); + + $copyObj->setAddTabSdwLogInsert($this->add_tab_sdw_log_insert); + + $copyObj->setAddTabSdwLogUpdate($this->add_tab_sdw_log_update); + + $copyObj->setAddTabSdwLogDelete($this->add_tab_sdw_log_delete); + + $copyObj->setAddTabSdwLogSelect($this->add_tab_sdw_log_select); + + $copyObj->setAddTabSdwMaxLength($this->add_tab_sdw_max_length); + + $copyObj->setAddTabSdwAutoDelete($this->add_tab_sdw_auto_delete); + + $copyObj->setAddTabPlgUid($this->add_tab_plg_uid); + + $copyObj->setDbsUid($this->dbs_uid); + + + $copyObj->setNew(true); + + $copyObj->setAddTabUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AdditionalTables Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AdditionalTablesPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AdditionalTablesPeer(); + } + return self::$peer; + } + +} // BaseAdditionalTables diff --git a/workflow/engine/classes/model/om/BaseAdditionalTablesPeer.php b/workflow/engine/classes/model/om/BaseAdditionalTablesPeer.php new file mode 100644 index 000000000..6d26dbf1e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAdditionalTablesPeer.php @@ -0,0 +1,620 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AdditionalTablesPeer::getOMClass() +include_once 'classes/model/AdditionalTables.php'; + +/** + * Base static class for performing query and update operations on the 'ADDITIONAL_TABLES' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAdditionalTablesPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'ADDITIONAL_TABLES'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AdditionalTables'; + + /** The total number of columns. */ + const NUM_COLUMNS = 12; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the ADD_TAB_UID field */ + const ADD_TAB_UID = 'ADDITIONAL_TABLES.ADD_TAB_UID'; + + /** the column name for the ADD_TAB_NAME field */ + const ADD_TAB_NAME = 'ADDITIONAL_TABLES.ADD_TAB_NAME'; + + /** the column name for the ADD_TAB_CLASS_NAME field */ + const ADD_TAB_CLASS_NAME = 'ADDITIONAL_TABLES.ADD_TAB_CLASS_NAME'; + + /** the column name for the ADD_TAB_DESCRIPTION field */ + const ADD_TAB_DESCRIPTION = 'ADDITIONAL_TABLES.ADD_TAB_DESCRIPTION'; + + /** the column name for the ADD_TAB_SDW_LOG_INSERT field */ + const ADD_TAB_SDW_LOG_INSERT = 'ADDITIONAL_TABLES.ADD_TAB_SDW_LOG_INSERT'; + + /** the column name for the ADD_TAB_SDW_LOG_UPDATE field */ + const ADD_TAB_SDW_LOG_UPDATE = 'ADDITIONAL_TABLES.ADD_TAB_SDW_LOG_UPDATE'; + + /** the column name for the ADD_TAB_SDW_LOG_DELETE field */ + const ADD_TAB_SDW_LOG_DELETE = 'ADDITIONAL_TABLES.ADD_TAB_SDW_LOG_DELETE'; + + /** the column name for the ADD_TAB_SDW_LOG_SELECT field */ + const ADD_TAB_SDW_LOG_SELECT = 'ADDITIONAL_TABLES.ADD_TAB_SDW_LOG_SELECT'; + + /** the column name for the ADD_TAB_SDW_MAX_LENGTH field */ + const ADD_TAB_SDW_MAX_LENGTH = 'ADDITIONAL_TABLES.ADD_TAB_SDW_MAX_LENGTH'; + + /** the column name for the ADD_TAB_SDW_AUTO_DELETE field */ + const ADD_TAB_SDW_AUTO_DELETE = 'ADDITIONAL_TABLES.ADD_TAB_SDW_AUTO_DELETE'; + + /** the column name for the ADD_TAB_PLG_UID field */ + const ADD_TAB_PLG_UID = 'ADDITIONAL_TABLES.ADD_TAB_PLG_UID'; + + /** the column name for the DBS_UID field */ + const DBS_UID = 'ADDITIONAL_TABLES.DBS_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AddTabUid', 'AddTabName', 'AddTabClassName', 'AddTabDescription', 'AddTabSdwLogInsert', 'AddTabSdwLogUpdate', 'AddTabSdwLogDelete', 'AddTabSdwLogSelect', 'AddTabSdwMaxLength', 'AddTabSdwAutoDelete', 'AddTabPlgUid', 'DbsUid', ), + BasePeer::TYPE_COLNAME => array (AdditionalTablesPeer::ADD_TAB_UID, AdditionalTablesPeer::ADD_TAB_NAME, AdditionalTablesPeer::ADD_TAB_CLASS_NAME, AdditionalTablesPeer::ADD_TAB_DESCRIPTION, AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT, AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE, AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE, AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT, AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH, AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE, AdditionalTablesPeer::ADD_TAB_PLG_UID, AdditionalTablesPeer::DBS_UID, ), + BasePeer::TYPE_FIELDNAME => array ('ADD_TAB_UID', 'ADD_TAB_NAME', 'ADD_TAB_CLASS_NAME', 'ADD_TAB_DESCRIPTION', 'ADD_TAB_SDW_LOG_INSERT', 'ADD_TAB_SDW_LOG_UPDATE', 'ADD_TAB_SDW_LOG_DELETE', 'ADD_TAB_SDW_LOG_SELECT', 'ADD_TAB_SDW_MAX_LENGTH', 'ADD_TAB_SDW_AUTO_DELETE', 'ADD_TAB_PLG_UID', 'DBS_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AddTabUid' => 0, 'AddTabName' => 1, 'AddTabClassName' => 2, 'AddTabDescription' => 3, 'AddTabSdwLogInsert' => 4, 'AddTabSdwLogUpdate' => 5, 'AddTabSdwLogDelete' => 6, 'AddTabSdwLogSelect' => 7, 'AddTabSdwMaxLength' => 8, 'AddTabSdwAutoDelete' => 9, 'AddTabPlgUid' => 10, 'DbsUid' => 11, ), + BasePeer::TYPE_COLNAME => array (AdditionalTablesPeer::ADD_TAB_UID => 0, AdditionalTablesPeer::ADD_TAB_NAME => 1, AdditionalTablesPeer::ADD_TAB_CLASS_NAME => 2, AdditionalTablesPeer::ADD_TAB_DESCRIPTION => 3, AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT => 4, AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE => 5, AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE => 6, AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT => 7, AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH => 8, AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE => 9, AdditionalTablesPeer::ADD_TAB_PLG_UID => 10, AdditionalTablesPeer::DBS_UID => 11, ), + BasePeer::TYPE_FIELDNAME => array ('ADD_TAB_UID' => 0, 'ADD_TAB_NAME' => 1, 'ADD_TAB_CLASS_NAME' => 2, 'ADD_TAB_DESCRIPTION' => 3, 'ADD_TAB_SDW_LOG_INSERT' => 4, 'ADD_TAB_SDW_LOG_UPDATE' => 5, 'ADD_TAB_SDW_LOG_DELETE' => 6, 'ADD_TAB_SDW_LOG_SELECT' => 7, 'ADD_TAB_SDW_MAX_LENGTH' => 8, 'ADD_TAB_SDW_AUTO_DELETE' => 9, 'ADD_TAB_PLG_UID' => 10, 'DBS_UID' => 11, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AdditionalTablesMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AdditionalTablesMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AdditionalTablesPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AdditionalTablesPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AdditionalTablesPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_UID); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_NAME); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_CLASS_NAME); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_DESCRIPTION); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_INSERT); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_UPDATE); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_DELETE); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_LOG_SELECT); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_MAX_LENGTH); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_SDW_AUTO_DELETE); + + $criteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_PLG_UID); + + $criteria->addSelectColumn(AdditionalTablesPeer::DBS_UID); + + } + + const COUNT = 'COUNT(ADDITIONAL_TABLES.ADD_TAB_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT ADDITIONAL_TABLES.ADD_TAB_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AdditionalTablesPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AdditionalTablesPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AdditionalTablesPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AdditionalTables + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AdditionalTablesPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AdditionalTablesPeer::populateObjects(AdditionalTablesPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AdditionalTablesPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AdditionalTablesPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AdditionalTablesPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AdditionalTables or Criteria object. + * + * @param mixed $values Criteria or AdditionalTables object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AdditionalTables object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AdditionalTables or Criteria object. + * + * @param mixed $values Criteria or AdditionalTables object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AdditionalTablesPeer::ADD_TAB_UID); + $selectCriteria->add(AdditionalTablesPeer::ADD_TAB_UID, $criteria->remove(AdditionalTablesPeer::ADD_TAB_UID), $comparison); + + } else { // $values is AdditionalTables object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the ADDITIONAL_TABLES table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AdditionalTablesPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AdditionalTables or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AdditionalTables object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AdditionalTablesPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AdditionalTables) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(AdditionalTablesPeer::ADD_TAB_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AdditionalTables object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AdditionalTables $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AdditionalTables $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AdditionalTablesPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AdditionalTablesPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AdditionalTablesPeer::DATABASE_NAME, AdditionalTablesPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return AdditionalTables + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(AdditionalTablesPeer::DATABASE_NAME); + + $criteria->add(AdditionalTablesPeer::ADD_TAB_UID, $pk); + + + $v = AdditionalTablesPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(AdditionalTablesPeer::ADD_TAB_UID, $pks, Criteria::IN); + $objs = AdditionalTablesPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseAdditionalTablesPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAdditionalTablesPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AdditionalTablesMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AdditionalTablesMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppCacheView.php b/workflow/engine/classes/model/om/BaseAppCacheView.php new file mode 100644 index 000000000..f1b142722 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppCacheView.php @@ -0,0 +1,2183 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppCacheViewPeer.php'; + +/** + * Base class that represents a row from the 'APP_CACHE_VIEW' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppCacheView extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppCacheViewPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the app_number field. + * @var int + */ + protected $app_number = 0; + + + /** + * The value for the app_status field. + * @var string + */ + protected $app_status = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the previous_usr_uid field. + * @var string + */ + protected $previous_usr_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the del_delegate_date field. + * @var int + */ + protected $del_delegate_date; + + + /** + * The value for the del_init_date field. + * @var int + */ + protected $del_init_date; + + + /** + * The value for the del_task_due_date field. + * @var int + */ + protected $del_task_due_date; + + + /** + * The value for the del_finish_date field. + * @var int + */ + protected $del_finish_date; + + + /** + * The value for the del_thread_status field. + * @var string + */ + protected $del_thread_status = 'OPEN'; + + + /** + * The value for the app_thread_status field. + * @var string + */ + protected $app_thread_status = 'OPEN'; + + + /** + * The value for the app_title field. + * @var string + */ + protected $app_title = ''; + + + /** + * The value for the app_pro_title field. + * @var string + */ + protected $app_pro_title = ''; + + + /** + * The value for the app_tas_title field. + * @var string + */ + protected $app_tas_title = ''; + + + /** + * The value for the app_current_user field. + * @var string + */ + protected $app_current_user = ''; + + + /** + * The value for the app_del_previous_user field. + * @var string + */ + protected $app_del_previous_user = ''; + + + /** + * The value for the del_priority field. + * @var string + */ + protected $del_priority = '3'; + + + /** + * The value for the del_duration field. + * @var double + */ + protected $del_duration = 0; + + + /** + * The value for the del_queue_duration field. + * @var double + */ + protected $del_queue_duration = 0; + + + /** + * The value for the del_delay_duration field. + * @var double + */ + protected $del_delay_duration = 0; + + + /** + * The value for the del_started field. + * @var int + */ + protected $del_started = 0; + + + /** + * The value for the del_finished field. + * @var int + */ + protected $del_finished = 0; + + + /** + * The value for the del_delayed field. + * @var int + */ + protected $del_delayed = 0; + + + /** + * The value for the app_create_date field. + * @var int + */ + protected $app_create_date; + + + /** + * The value for the app_finish_date field. + * @var int + */ + protected $app_finish_date; + + + /** + * The value for the app_update_date field. + * @var int + */ + protected $app_update_date; + + + /** + * The value for the app_overdue_percentage field. + * @var double + */ + protected $app_overdue_percentage; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [app_number] column value. + * + * @return int + */ + public function getAppNumber() + { + + return $this->app_number; + } + + /** + * Get the [app_status] column value. + * + * @return string + */ + public function getAppStatus() + { + + return $this->app_status; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [previous_usr_uid] column value. + * + * @return string + */ + public function getPreviousUsrUid() + { + + return $this->previous_usr_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [optionally formatted] [del_delegate_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelDelegateDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_delegate_date === null || $this->del_delegate_date === '') { + return null; + } elseif (!is_int($this->del_delegate_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_delegate_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_delegate_date] as date/time value: " . var_export($this->del_delegate_date, true)); + } + } else { + $ts = $this->del_delegate_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_init_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelInitDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_init_date === null || $this->del_init_date === '') { + return null; + } elseif (!is_int($this->del_init_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_init_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_init_date] as date/time value: " . var_export($this->del_init_date, true)); + } + } else { + $ts = $this->del_init_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_task_due_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelTaskDueDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_task_due_date === null || $this->del_task_due_date === '') { + return null; + } elseif (!is_int($this->del_task_due_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_task_due_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_task_due_date] as date/time value: " . var_export($this->del_task_due_date, true)); + } + } else { + $ts = $this->del_task_due_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_finish_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelFinishDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_finish_date === null || $this->del_finish_date === '') { + return null; + } elseif (!is_int($this->del_finish_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_finish_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_finish_date] as date/time value: " . var_export($this->del_finish_date, true)); + } + } else { + $ts = $this->del_finish_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [del_thread_status] column value. + * + * @return string + */ + public function getDelThreadStatus() + { + + return $this->del_thread_status; + } + + /** + * Get the [app_thread_status] column value. + * + * @return string + */ + public function getAppThreadStatus() + { + + return $this->app_thread_status; + } + + /** + * Get the [app_title] column value. + * + * @return string + */ + public function getAppTitle() + { + + return $this->app_title; + } + + /** + * Get the [app_pro_title] column value. + * + * @return string + */ + public function getAppProTitle() + { + + return $this->app_pro_title; + } + + /** + * Get the [app_tas_title] column value. + * + * @return string + */ + public function getAppTasTitle() + { + + return $this->app_tas_title; + } + + /** + * Get the [app_current_user] column value. + * + * @return string + */ + public function getAppCurrentUser() + { + + return $this->app_current_user; + } + + /** + * Get the [app_del_previous_user] column value. + * + * @return string + */ + public function getAppDelPreviousUser() + { + + return $this->app_del_previous_user; + } + + /** + * Get the [del_priority] column value. + * + * @return string + */ + public function getDelPriority() + { + + return $this->del_priority; + } + + /** + * Get the [del_duration] column value. + * + * @return double + */ + public function getDelDuration() + { + + return $this->del_duration; + } + + /** + * Get the [del_queue_duration] column value. + * + * @return double + */ + public function getDelQueueDuration() + { + + return $this->del_queue_duration; + } + + /** + * Get the [del_delay_duration] column value. + * + * @return double + */ + public function getDelDelayDuration() + { + + return $this->del_delay_duration; + } + + /** + * Get the [del_started] column value. + * + * @return int + */ + public function getDelStarted() + { + + return $this->del_started; + } + + /** + * Get the [del_finished] column value. + * + * @return int + */ + public function getDelFinished() + { + + return $this->del_finished; + } + + /** + * Get the [del_delayed] column value. + * + * @return int + */ + public function getDelDelayed() + { + + return $this->del_delayed; + } + + /** + * Get the [optionally formatted] [app_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_create_date === null || $this->app_create_date === '') { + return null; + } elseif (!is_int($this->app_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_create_date] as date/time value: " . var_export($this->app_create_date, true)); + } + } else { + $ts = $this->app_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_finish_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppFinishDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_finish_date === null || $this->app_finish_date === '') { + return null; + } elseif (!is_int($this->app_finish_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_finish_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_finish_date] as date/time value: " . var_export($this->app_finish_date, true)); + } + } else { + $ts = $this->app_finish_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_update_date === null || $this->app_update_date === '') { + return null; + } elseif (!is_int($this->app_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_update_date] as date/time value: " . var_export($this->app_update_date, true)); + } + } else { + $ts = $this->app_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_overdue_percentage] column value. + * + * @return double + */ + public function getAppOverduePercentage() + { + + return $this->app_overdue_percentage; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [app_number] column. + * + * @param int $v new value + * @return void + */ + public function setAppNumber($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_number !== $v || $v === 0) { + $this->app_number = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_NUMBER; + } + + } // setAppNumber() + + /** + * Set the value of [app_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_status !== $v || $v === '') { + $this->app_status = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_STATUS; + } + + } // setAppStatus() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = AppCacheViewPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [previous_usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setPreviousUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->previous_usr_uid !== $v || $v === '') { + $this->previous_usr_uid = $v; + $this->modifiedColumns[] = AppCacheViewPeer::PREVIOUS_USR_UID; + } + + } // setPreviousUsrUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = AppCacheViewPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = AppCacheViewPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [del_delegate_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelDelegateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_delegate_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_delegate_date !== $ts) { + $this->del_delegate_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_DELEGATE_DATE; + } + + } // setDelDelegateDate() + + /** + * Set the value of [del_init_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelInitDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_init_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_init_date !== $ts) { + $this->del_init_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_INIT_DATE; + } + + } // setDelInitDate() + + /** + * Set the value of [del_task_due_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelTaskDueDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_task_due_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_task_due_date !== $ts) { + $this->del_task_due_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_TASK_DUE_DATE; + } + + } // setDelTaskDueDate() + + /** + * Set the value of [del_finish_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelFinishDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_finish_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_finish_date !== $ts) { + $this->del_finish_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_FINISH_DATE; + } + + } // setDelFinishDate() + + /** + * Set the value of [del_thread_status] column. + * + * @param string $v new value + * @return void + */ + public function setDelThreadStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_thread_status !== $v || $v === 'OPEN') { + $this->del_thread_status = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_THREAD_STATUS; + } + + } // setDelThreadStatus() + + /** + * Set the value of [app_thread_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppThreadStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_thread_status !== $v || $v === 'OPEN') { + $this->app_thread_status = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_THREAD_STATUS; + } + + } // setAppThreadStatus() + + /** + * Set the value of [app_title] column. + * + * @param string $v new value + * @return void + */ + public function setAppTitle($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_title !== $v || $v === '') { + $this->app_title = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_TITLE; + } + + } // setAppTitle() + + /** + * Set the value of [app_pro_title] column. + * + * @param string $v new value + * @return void + */ + public function setAppProTitle($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_pro_title !== $v || $v === '') { + $this->app_pro_title = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_PRO_TITLE; + } + + } // setAppProTitle() + + /** + * Set the value of [app_tas_title] column. + * + * @param string $v new value + * @return void + */ + public function setAppTasTitle($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_tas_title !== $v || $v === '') { + $this->app_tas_title = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_TAS_TITLE; + } + + } // setAppTasTitle() + + /** + * Set the value of [app_current_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppCurrentUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_current_user !== $v || $v === '') { + $this->app_current_user = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_CURRENT_USER; + } + + } // setAppCurrentUser() + + /** + * Set the value of [app_del_previous_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppDelPreviousUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_del_previous_user !== $v || $v === '') { + $this->app_del_previous_user = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_DEL_PREVIOUS_USER; + } + + } // setAppDelPreviousUser() + + /** + * Set the value of [del_priority] column. + * + * @param string $v new value + * @return void + */ + public function setDelPriority($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_priority !== $v || $v === '3') { + $this->del_priority = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_PRIORITY; + } + + } // setDelPriority() + + /** + * Set the value of [del_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelDuration($v) + { + + if ($this->del_duration !== $v || $v === 0) { + $this->del_duration = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_DURATION; + } + + } // setDelDuration() + + /** + * Set the value of [del_queue_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelQueueDuration($v) + { + + if ($this->del_queue_duration !== $v || $v === 0) { + $this->del_queue_duration = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_QUEUE_DURATION; + } + + } // setDelQueueDuration() + + /** + * Set the value of [del_delay_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelDelayDuration($v) + { + + if ($this->del_delay_duration !== $v || $v === 0) { + $this->del_delay_duration = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_DELAY_DURATION; + } + + } // setDelDelayDuration() + + /** + * Set the value of [del_started] column. + * + * @param int $v new value + * @return void + */ + public function setDelStarted($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_started !== $v || $v === 0) { + $this->del_started = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_STARTED; + } + + } // setDelStarted() + + /** + * Set the value of [del_finished] column. + * + * @param int $v new value + * @return void + */ + public function setDelFinished($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_finished !== $v || $v === 0) { + $this->del_finished = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_FINISHED; + } + + } // setDelFinished() + + /** + * Set the value of [del_delayed] column. + * + * @param int $v new value + * @return void + */ + public function setDelDelayed($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_delayed !== $v || $v === 0) { + $this->del_delayed = $v; + $this->modifiedColumns[] = AppCacheViewPeer::DEL_DELAYED; + } + + } // setDelDelayed() + + /** + * Set the value of [app_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_create_date !== $ts) { + $this->app_create_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::APP_CREATE_DATE; + } + + } // setAppCreateDate() + + /** + * Set the value of [app_finish_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppFinishDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_finish_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_finish_date !== $ts) { + $this->app_finish_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::APP_FINISH_DATE; + } + + } // setAppFinishDate() + + /** + * Set the value of [app_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_update_date !== $ts) { + $this->app_update_date = $ts; + $this->modifiedColumns[] = AppCacheViewPeer::APP_UPDATE_DATE; + } + + } // setAppUpdateDate() + + /** + * Set the value of [app_overdue_percentage] column. + * + * @param double $v new value + * @return void + */ + public function setAppOverduePercentage($v) + { + + if ($this->app_overdue_percentage !== $v) { + $this->app_overdue_percentage = $v; + $this->modifiedColumns[] = AppCacheViewPeer::APP_OVERDUE_PERCENTAGE; + } + + } // setAppOverduePercentage() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->del_index = $rs->getInt($startcol + 1); + + $this->app_number = $rs->getInt($startcol + 2); + + $this->app_status = $rs->getString($startcol + 3); + + $this->usr_uid = $rs->getString($startcol + 4); + + $this->previous_usr_uid = $rs->getString($startcol + 5); + + $this->tas_uid = $rs->getString($startcol + 6); + + $this->pro_uid = $rs->getString($startcol + 7); + + $this->del_delegate_date = $rs->getTimestamp($startcol + 8, null); + + $this->del_init_date = $rs->getTimestamp($startcol + 9, null); + + $this->del_task_due_date = $rs->getTimestamp($startcol + 10, null); + + $this->del_finish_date = $rs->getTimestamp($startcol + 11, null); + + $this->del_thread_status = $rs->getString($startcol + 12); + + $this->app_thread_status = $rs->getString($startcol + 13); + + $this->app_title = $rs->getString($startcol + 14); + + $this->app_pro_title = $rs->getString($startcol + 15); + + $this->app_tas_title = $rs->getString($startcol + 16); + + $this->app_current_user = $rs->getString($startcol + 17); + + $this->app_del_previous_user = $rs->getString($startcol + 18); + + $this->del_priority = $rs->getString($startcol + 19); + + $this->del_duration = $rs->getFloat($startcol + 20); + + $this->del_queue_duration = $rs->getFloat($startcol + 21); + + $this->del_delay_duration = $rs->getFloat($startcol + 22); + + $this->del_started = $rs->getInt($startcol + 23); + + $this->del_finished = $rs->getInt($startcol + 24); + + $this->del_delayed = $rs->getInt($startcol + 25); + + $this->app_create_date = $rs->getTimestamp($startcol + 26, null); + + $this->app_finish_date = $rs->getTimestamp($startcol + 27, null); + + $this->app_update_date = $rs->getTimestamp($startcol + 28, null); + + $this->app_overdue_percentage = $rs->getFloat($startcol + 29); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 30; // 30 = AppCacheViewPeer::NUM_COLUMNS - AppCacheViewPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppCacheView object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppCacheViewPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppCacheViewPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppCacheViewPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppCacheViewPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppCacheViewPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppCacheViewPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppCacheViewPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getDelIndex(); + break; + case 2: + return $this->getAppNumber(); + break; + case 3: + return $this->getAppStatus(); + break; + case 4: + return $this->getUsrUid(); + break; + case 5: + return $this->getPreviousUsrUid(); + break; + case 6: + return $this->getTasUid(); + break; + case 7: + return $this->getProUid(); + break; + case 8: + return $this->getDelDelegateDate(); + break; + case 9: + return $this->getDelInitDate(); + break; + case 10: + return $this->getDelTaskDueDate(); + break; + case 11: + return $this->getDelFinishDate(); + break; + case 12: + return $this->getDelThreadStatus(); + break; + case 13: + return $this->getAppThreadStatus(); + break; + case 14: + return $this->getAppTitle(); + break; + case 15: + return $this->getAppProTitle(); + break; + case 16: + return $this->getAppTasTitle(); + break; + case 17: + return $this->getAppCurrentUser(); + break; + case 18: + return $this->getAppDelPreviousUser(); + break; + case 19: + return $this->getDelPriority(); + break; + case 20: + return $this->getDelDuration(); + break; + case 21: + return $this->getDelQueueDuration(); + break; + case 22: + return $this->getDelDelayDuration(); + break; + case 23: + return $this->getDelStarted(); + break; + case 24: + return $this->getDelFinished(); + break; + case 25: + return $this->getDelDelayed(); + break; + case 26: + return $this->getAppCreateDate(); + break; + case 27: + return $this->getAppFinishDate(); + break; + case 28: + return $this->getAppUpdateDate(); + break; + case 29: + return $this->getAppOverduePercentage(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppCacheViewPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getDelIndex(), + $keys[2] => $this->getAppNumber(), + $keys[3] => $this->getAppStatus(), + $keys[4] => $this->getUsrUid(), + $keys[5] => $this->getPreviousUsrUid(), + $keys[6] => $this->getTasUid(), + $keys[7] => $this->getProUid(), + $keys[8] => $this->getDelDelegateDate(), + $keys[9] => $this->getDelInitDate(), + $keys[10] => $this->getDelTaskDueDate(), + $keys[11] => $this->getDelFinishDate(), + $keys[12] => $this->getDelThreadStatus(), + $keys[13] => $this->getAppThreadStatus(), + $keys[14] => $this->getAppTitle(), + $keys[15] => $this->getAppProTitle(), + $keys[16] => $this->getAppTasTitle(), + $keys[17] => $this->getAppCurrentUser(), + $keys[18] => $this->getAppDelPreviousUser(), + $keys[19] => $this->getDelPriority(), + $keys[20] => $this->getDelDuration(), + $keys[21] => $this->getDelQueueDuration(), + $keys[22] => $this->getDelDelayDuration(), + $keys[23] => $this->getDelStarted(), + $keys[24] => $this->getDelFinished(), + $keys[25] => $this->getDelDelayed(), + $keys[26] => $this->getAppCreateDate(), + $keys[27] => $this->getAppFinishDate(), + $keys[28] => $this->getAppUpdateDate(), + $keys[29] => $this->getAppOverduePercentage(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppCacheViewPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setDelIndex($value); + break; + case 2: + $this->setAppNumber($value); + break; + case 3: + $this->setAppStatus($value); + break; + case 4: + $this->setUsrUid($value); + break; + case 5: + $this->setPreviousUsrUid($value); + break; + case 6: + $this->setTasUid($value); + break; + case 7: + $this->setProUid($value); + break; + case 8: + $this->setDelDelegateDate($value); + break; + case 9: + $this->setDelInitDate($value); + break; + case 10: + $this->setDelTaskDueDate($value); + break; + case 11: + $this->setDelFinishDate($value); + break; + case 12: + $this->setDelThreadStatus($value); + break; + case 13: + $this->setAppThreadStatus($value); + break; + case 14: + $this->setAppTitle($value); + break; + case 15: + $this->setAppProTitle($value); + break; + case 16: + $this->setAppTasTitle($value); + break; + case 17: + $this->setAppCurrentUser($value); + break; + case 18: + $this->setAppDelPreviousUser($value); + break; + case 19: + $this->setDelPriority($value); + break; + case 20: + $this->setDelDuration($value); + break; + case 21: + $this->setDelQueueDuration($value); + break; + case 22: + $this->setDelDelayDuration($value); + break; + case 23: + $this->setDelStarted($value); + break; + case 24: + $this->setDelFinished($value); + break; + case 25: + $this->setDelDelayed($value); + break; + case 26: + $this->setAppCreateDate($value); + break; + case 27: + $this->setAppFinishDate($value); + break; + case 28: + $this->setAppUpdateDate($value); + break; + case 29: + $this->setAppOverduePercentage($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppCacheViewPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDelIndex($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppNumber($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAppStatus($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUsrUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setPreviousUsrUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setTasUid($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setProUid($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setDelDelegateDate($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setDelInitDate($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setDelTaskDueDate($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setDelFinishDate($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setDelThreadStatus($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setAppThreadStatus($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setAppTitle($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setAppProTitle($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setAppTasTitle($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setAppCurrentUser($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setAppDelPreviousUser($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setDelPriority($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setDelDuration($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setDelQueueDuration($arr[$keys[21]]); + if (array_key_exists($keys[22], $arr)) $this->setDelDelayDuration($arr[$keys[22]]); + if (array_key_exists($keys[23], $arr)) $this->setDelStarted($arr[$keys[23]]); + if (array_key_exists($keys[24], $arr)) $this->setDelFinished($arr[$keys[24]]); + if (array_key_exists($keys[25], $arr)) $this->setDelDelayed($arr[$keys[25]]); + if (array_key_exists($keys[26], $arr)) $this->setAppCreateDate($arr[$keys[26]]); + if (array_key_exists($keys[27], $arr)) $this->setAppFinishDate($arr[$keys[27]]); + if (array_key_exists($keys[28], $arr)) $this->setAppUpdateDate($arr[$keys[28]]); + if (array_key_exists($keys[29], $arr)) $this->setAppOverduePercentage($arr[$keys[29]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppCacheViewPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppCacheViewPeer::APP_UID)) $criteria->add(AppCacheViewPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppCacheViewPeer::DEL_INDEX)) $criteria->add(AppCacheViewPeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppCacheViewPeer::APP_NUMBER)) $criteria->add(AppCacheViewPeer::APP_NUMBER, $this->app_number); + if ($this->isColumnModified(AppCacheViewPeer::APP_STATUS)) $criteria->add(AppCacheViewPeer::APP_STATUS, $this->app_status); + if ($this->isColumnModified(AppCacheViewPeer::USR_UID)) $criteria->add(AppCacheViewPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(AppCacheViewPeer::PREVIOUS_USR_UID)) $criteria->add(AppCacheViewPeer::PREVIOUS_USR_UID, $this->previous_usr_uid); + if ($this->isColumnModified(AppCacheViewPeer::TAS_UID)) $criteria->add(AppCacheViewPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(AppCacheViewPeer::PRO_UID)) $criteria->add(AppCacheViewPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(AppCacheViewPeer::DEL_DELEGATE_DATE)) $criteria->add(AppCacheViewPeer::DEL_DELEGATE_DATE, $this->del_delegate_date); + if ($this->isColumnModified(AppCacheViewPeer::DEL_INIT_DATE)) $criteria->add(AppCacheViewPeer::DEL_INIT_DATE, $this->del_init_date); + if ($this->isColumnModified(AppCacheViewPeer::DEL_TASK_DUE_DATE)) $criteria->add(AppCacheViewPeer::DEL_TASK_DUE_DATE, $this->del_task_due_date); + if ($this->isColumnModified(AppCacheViewPeer::DEL_FINISH_DATE)) $criteria->add(AppCacheViewPeer::DEL_FINISH_DATE, $this->del_finish_date); + if ($this->isColumnModified(AppCacheViewPeer::DEL_THREAD_STATUS)) $criteria->add(AppCacheViewPeer::DEL_THREAD_STATUS, $this->del_thread_status); + if ($this->isColumnModified(AppCacheViewPeer::APP_THREAD_STATUS)) $criteria->add(AppCacheViewPeer::APP_THREAD_STATUS, $this->app_thread_status); + if ($this->isColumnModified(AppCacheViewPeer::APP_TITLE)) $criteria->add(AppCacheViewPeer::APP_TITLE, $this->app_title); + if ($this->isColumnModified(AppCacheViewPeer::APP_PRO_TITLE)) $criteria->add(AppCacheViewPeer::APP_PRO_TITLE, $this->app_pro_title); + if ($this->isColumnModified(AppCacheViewPeer::APP_TAS_TITLE)) $criteria->add(AppCacheViewPeer::APP_TAS_TITLE, $this->app_tas_title); + if ($this->isColumnModified(AppCacheViewPeer::APP_CURRENT_USER)) $criteria->add(AppCacheViewPeer::APP_CURRENT_USER, $this->app_current_user); + if ($this->isColumnModified(AppCacheViewPeer::APP_DEL_PREVIOUS_USER)) $criteria->add(AppCacheViewPeer::APP_DEL_PREVIOUS_USER, $this->app_del_previous_user); + if ($this->isColumnModified(AppCacheViewPeer::DEL_PRIORITY)) $criteria->add(AppCacheViewPeer::DEL_PRIORITY, $this->del_priority); + if ($this->isColumnModified(AppCacheViewPeer::DEL_DURATION)) $criteria->add(AppCacheViewPeer::DEL_DURATION, $this->del_duration); + if ($this->isColumnModified(AppCacheViewPeer::DEL_QUEUE_DURATION)) $criteria->add(AppCacheViewPeer::DEL_QUEUE_DURATION, $this->del_queue_duration); + if ($this->isColumnModified(AppCacheViewPeer::DEL_DELAY_DURATION)) $criteria->add(AppCacheViewPeer::DEL_DELAY_DURATION, $this->del_delay_duration); + if ($this->isColumnModified(AppCacheViewPeer::DEL_STARTED)) $criteria->add(AppCacheViewPeer::DEL_STARTED, $this->del_started); + if ($this->isColumnModified(AppCacheViewPeer::DEL_FINISHED)) $criteria->add(AppCacheViewPeer::DEL_FINISHED, $this->del_finished); + if ($this->isColumnModified(AppCacheViewPeer::DEL_DELAYED)) $criteria->add(AppCacheViewPeer::DEL_DELAYED, $this->del_delayed); + if ($this->isColumnModified(AppCacheViewPeer::APP_CREATE_DATE)) $criteria->add(AppCacheViewPeer::APP_CREATE_DATE, $this->app_create_date); + if ($this->isColumnModified(AppCacheViewPeer::APP_FINISH_DATE)) $criteria->add(AppCacheViewPeer::APP_FINISH_DATE, $this->app_finish_date); + if ($this->isColumnModified(AppCacheViewPeer::APP_UPDATE_DATE)) $criteria->add(AppCacheViewPeer::APP_UPDATE_DATE, $this->app_update_date); + if ($this->isColumnModified(AppCacheViewPeer::APP_OVERDUE_PERCENTAGE)) $criteria->add(AppCacheViewPeer::APP_OVERDUE_PERCENTAGE, $this->app_overdue_percentage); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppCacheViewPeer::DATABASE_NAME); + + $criteria->add(AppCacheViewPeer::APP_UID, $this->app_uid); + $criteria->add(AppCacheViewPeer::DEL_INDEX, $this->del_index); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getDelIndex(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setDelIndex($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppCacheView (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppNumber($this->app_number); + + $copyObj->setAppStatus($this->app_status); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setPreviousUsrUid($this->previous_usr_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setDelDelegateDate($this->del_delegate_date); + + $copyObj->setDelInitDate($this->del_init_date); + + $copyObj->setDelTaskDueDate($this->del_task_due_date); + + $copyObj->setDelFinishDate($this->del_finish_date); + + $copyObj->setDelThreadStatus($this->del_thread_status); + + $copyObj->setAppThreadStatus($this->app_thread_status); + + $copyObj->setAppTitle($this->app_title); + + $copyObj->setAppProTitle($this->app_pro_title); + + $copyObj->setAppTasTitle($this->app_tas_title); + + $copyObj->setAppCurrentUser($this->app_current_user); + + $copyObj->setAppDelPreviousUser($this->app_del_previous_user); + + $copyObj->setDelPriority($this->del_priority); + + $copyObj->setDelDuration($this->del_duration); + + $copyObj->setDelQueueDuration($this->del_queue_duration); + + $copyObj->setDelDelayDuration($this->del_delay_duration); + + $copyObj->setDelStarted($this->del_started); + + $copyObj->setDelFinished($this->del_finished); + + $copyObj->setDelDelayed($this->del_delayed); + + $copyObj->setAppCreateDate($this->app_create_date); + + $copyObj->setAppFinishDate($this->app_finish_date); + + $copyObj->setAppUpdateDate($this->app_update_date); + + $copyObj->setAppOverduePercentage($this->app_overdue_percentage); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setDelIndex('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppCacheView Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppCacheViewPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppCacheViewPeer(); + } + return self::$peer; + } + +} // BaseAppCacheView diff --git a/workflow/engine/classes/model/om/BaseAppCacheViewPeer.php b/workflow/engine/classes/model/om/BaseAppCacheViewPeer.php new file mode 100644 index 000000000..0938d2404 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppCacheViewPeer.php @@ -0,0 +1,701 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppCacheViewPeer::getOMClass() +include_once 'classes/model/AppCacheView.php'; + +/** + * Base static class for performing query and update operations on the 'APP_CACHE_VIEW' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppCacheViewPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_CACHE_VIEW'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppCacheView'; + + /** The total number of columns. */ + const NUM_COLUMNS = 30; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_CACHE_VIEW.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_CACHE_VIEW.DEL_INDEX'; + + /** the column name for the APP_NUMBER field */ + const APP_NUMBER = 'APP_CACHE_VIEW.APP_NUMBER'; + + /** the column name for the APP_STATUS field */ + const APP_STATUS = 'APP_CACHE_VIEW.APP_STATUS'; + + /** the column name for the USR_UID field */ + const USR_UID = 'APP_CACHE_VIEW.USR_UID'; + + /** the column name for the PREVIOUS_USR_UID field */ + const PREVIOUS_USR_UID = 'APP_CACHE_VIEW.PREVIOUS_USR_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'APP_CACHE_VIEW.TAS_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'APP_CACHE_VIEW.PRO_UID'; + + /** the column name for the DEL_DELEGATE_DATE field */ + const DEL_DELEGATE_DATE = 'APP_CACHE_VIEW.DEL_DELEGATE_DATE'; + + /** the column name for the DEL_INIT_DATE field */ + const DEL_INIT_DATE = 'APP_CACHE_VIEW.DEL_INIT_DATE'; + + /** the column name for the DEL_TASK_DUE_DATE field */ + const DEL_TASK_DUE_DATE = 'APP_CACHE_VIEW.DEL_TASK_DUE_DATE'; + + /** the column name for the DEL_FINISH_DATE field */ + const DEL_FINISH_DATE = 'APP_CACHE_VIEW.DEL_FINISH_DATE'; + + /** the column name for the DEL_THREAD_STATUS field */ + const DEL_THREAD_STATUS = 'APP_CACHE_VIEW.DEL_THREAD_STATUS'; + + /** the column name for the APP_THREAD_STATUS field */ + const APP_THREAD_STATUS = 'APP_CACHE_VIEW.APP_THREAD_STATUS'; + + /** the column name for the APP_TITLE field */ + const APP_TITLE = 'APP_CACHE_VIEW.APP_TITLE'; + + /** the column name for the APP_PRO_TITLE field */ + const APP_PRO_TITLE = 'APP_CACHE_VIEW.APP_PRO_TITLE'; + + /** the column name for the APP_TAS_TITLE field */ + const APP_TAS_TITLE = 'APP_CACHE_VIEW.APP_TAS_TITLE'; + + /** the column name for the APP_CURRENT_USER field */ + const APP_CURRENT_USER = 'APP_CACHE_VIEW.APP_CURRENT_USER'; + + /** the column name for the APP_DEL_PREVIOUS_USER field */ + const APP_DEL_PREVIOUS_USER = 'APP_CACHE_VIEW.APP_DEL_PREVIOUS_USER'; + + /** the column name for the DEL_PRIORITY field */ + const DEL_PRIORITY = 'APP_CACHE_VIEW.DEL_PRIORITY'; + + /** the column name for the DEL_DURATION field */ + const DEL_DURATION = 'APP_CACHE_VIEW.DEL_DURATION'; + + /** the column name for the DEL_QUEUE_DURATION field */ + const DEL_QUEUE_DURATION = 'APP_CACHE_VIEW.DEL_QUEUE_DURATION'; + + /** the column name for the DEL_DELAY_DURATION field */ + const DEL_DELAY_DURATION = 'APP_CACHE_VIEW.DEL_DELAY_DURATION'; + + /** the column name for the DEL_STARTED field */ + const DEL_STARTED = 'APP_CACHE_VIEW.DEL_STARTED'; + + /** the column name for the DEL_FINISHED field */ + const DEL_FINISHED = 'APP_CACHE_VIEW.DEL_FINISHED'; + + /** the column name for the DEL_DELAYED field */ + const DEL_DELAYED = 'APP_CACHE_VIEW.DEL_DELAYED'; + + /** the column name for the APP_CREATE_DATE field */ + const APP_CREATE_DATE = 'APP_CACHE_VIEW.APP_CREATE_DATE'; + + /** the column name for the APP_FINISH_DATE field */ + const APP_FINISH_DATE = 'APP_CACHE_VIEW.APP_FINISH_DATE'; + + /** the column name for the APP_UPDATE_DATE field */ + const APP_UPDATE_DATE = 'APP_CACHE_VIEW.APP_UPDATE_DATE'; + + /** the column name for the APP_OVERDUE_PERCENTAGE field */ + const APP_OVERDUE_PERCENTAGE = 'APP_CACHE_VIEW.APP_OVERDUE_PERCENTAGE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'DelIndex', 'AppNumber', 'AppStatus', 'UsrUid', 'PreviousUsrUid', 'TasUid', 'ProUid', 'DelDelegateDate', 'DelInitDate', 'DelTaskDueDate', 'DelFinishDate', 'DelThreadStatus', 'AppThreadStatus', 'AppTitle', 'AppProTitle', 'AppTasTitle', 'AppCurrentUser', 'AppDelPreviousUser', 'DelPriority', 'DelDuration', 'DelQueueDuration', 'DelDelayDuration', 'DelStarted', 'DelFinished', 'DelDelayed', 'AppCreateDate', 'AppFinishDate', 'AppUpdateDate', 'AppOverduePercentage', ), + BasePeer::TYPE_COLNAME => array (AppCacheViewPeer::APP_UID, AppCacheViewPeer::DEL_INDEX, AppCacheViewPeer::APP_NUMBER, AppCacheViewPeer::APP_STATUS, AppCacheViewPeer::USR_UID, AppCacheViewPeer::PREVIOUS_USR_UID, AppCacheViewPeer::TAS_UID, AppCacheViewPeer::PRO_UID, AppCacheViewPeer::DEL_DELEGATE_DATE, AppCacheViewPeer::DEL_INIT_DATE, AppCacheViewPeer::DEL_TASK_DUE_DATE, AppCacheViewPeer::DEL_FINISH_DATE, AppCacheViewPeer::DEL_THREAD_STATUS, AppCacheViewPeer::APP_THREAD_STATUS, AppCacheViewPeer::APP_TITLE, AppCacheViewPeer::APP_PRO_TITLE, AppCacheViewPeer::APP_TAS_TITLE, AppCacheViewPeer::APP_CURRENT_USER, AppCacheViewPeer::APP_DEL_PREVIOUS_USER, AppCacheViewPeer::DEL_PRIORITY, AppCacheViewPeer::DEL_DURATION, AppCacheViewPeer::DEL_QUEUE_DURATION, AppCacheViewPeer::DEL_DELAY_DURATION, AppCacheViewPeer::DEL_STARTED, AppCacheViewPeer::DEL_FINISHED, AppCacheViewPeer::DEL_DELAYED, AppCacheViewPeer::APP_CREATE_DATE, AppCacheViewPeer::APP_FINISH_DATE, AppCacheViewPeer::APP_UPDATE_DATE, AppCacheViewPeer::APP_OVERDUE_PERCENTAGE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'DEL_INDEX', 'APP_NUMBER', 'APP_STATUS', 'USR_UID', 'PREVIOUS_USR_UID', 'TAS_UID', 'PRO_UID', 'DEL_DELEGATE_DATE', 'DEL_INIT_DATE', 'DEL_TASK_DUE_DATE', 'DEL_FINISH_DATE', 'DEL_THREAD_STATUS', 'APP_THREAD_STATUS', 'APP_TITLE', 'APP_PRO_TITLE', 'APP_TAS_TITLE', 'APP_CURRENT_USER', 'APP_DEL_PREVIOUS_USER', 'DEL_PRIORITY', 'DEL_DURATION', 'DEL_QUEUE_DURATION', 'DEL_DELAY_DURATION', 'DEL_STARTED', 'DEL_FINISHED', 'DEL_DELAYED', 'APP_CREATE_DATE', 'APP_FINISH_DATE', 'APP_UPDATE_DATE', 'APP_OVERDUE_PERCENTAGE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'DelIndex' => 1, 'AppNumber' => 2, 'AppStatus' => 3, 'UsrUid' => 4, 'PreviousUsrUid' => 5, 'TasUid' => 6, 'ProUid' => 7, 'DelDelegateDate' => 8, 'DelInitDate' => 9, 'DelTaskDueDate' => 10, 'DelFinishDate' => 11, 'DelThreadStatus' => 12, 'AppThreadStatus' => 13, 'AppTitle' => 14, 'AppProTitle' => 15, 'AppTasTitle' => 16, 'AppCurrentUser' => 17, 'AppDelPreviousUser' => 18, 'DelPriority' => 19, 'DelDuration' => 20, 'DelQueueDuration' => 21, 'DelDelayDuration' => 22, 'DelStarted' => 23, 'DelFinished' => 24, 'DelDelayed' => 25, 'AppCreateDate' => 26, 'AppFinishDate' => 27, 'AppUpdateDate' => 28, 'AppOverduePercentage' => 29, ), + BasePeer::TYPE_COLNAME => array (AppCacheViewPeer::APP_UID => 0, AppCacheViewPeer::DEL_INDEX => 1, AppCacheViewPeer::APP_NUMBER => 2, AppCacheViewPeer::APP_STATUS => 3, AppCacheViewPeer::USR_UID => 4, AppCacheViewPeer::PREVIOUS_USR_UID => 5, AppCacheViewPeer::TAS_UID => 6, AppCacheViewPeer::PRO_UID => 7, AppCacheViewPeer::DEL_DELEGATE_DATE => 8, AppCacheViewPeer::DEL_INIT_DATE => 9, AppCacheViewPeer::DEL_TASK_DUE_DATE => 10, AppCacheViewPeer::DEL_FINISH_DATE => 11, AppCacheViewPeer::DEL_THREAD_STATUS => 12, AppCacheViewPeer::APP_THREAD_STATUS => 13, AppCacheViewPeer::APP_TITLE => 14, AppCacheViewPeer::APP_PRO_TITLE => 15, AppCacheViewPeer::APP_TAS_TITLE => 16, AppCacheViewPeer::APP_CURRENT_USER => 17, AppCacheViewPeer::APP_DEL_PREVIOUS_USER => 18, AppCacheViewPeer::DEL_PRIORITY => 19, AppCacheViewPeer::DEL_DURATION => 20, AppCacheViewPeer::DEL_QUEUE_DURATION => 21, AppCacheViewPeer::DEL_DELAY_DURATION => 22, AppCacheViewPeer::DEL_STARTED => 23, AppCacheViewPeer::DEL_FINISHED => 24, AppCacheViewPeer::DEL_DELAYED => 25, AppCacheViewPeer::APP_CREATE_DATE => 26, AppCacheViewPeer::APP_FINISH_DATE => 27, AppCacheViewPeer::APP_UPDATE_DATE => 28, AppCacheViewPeer::APP_OVERDUE_PERCENTAGE => 29, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'DEL_INDEX' => 1, 'APP_NUMBER' => 2, 'APP_STATUS' => 3, 'USR_UID' => 4, 'PREVIOUS_USR_UID' => 5, 'TAS_UID' => 6, 'PRO_UID' => 7, 'DEL_DELEGATE_DATE' => 8, 'DEL_INIT_DATE' => 9, 'DEL_TASK_DUE_DATE' => 10, 'DEL_FINISH_DATE' => 11, 'DEL_THREAD_STATUS' => 12, 'APP_THREAD_STATUS' => 13, 'APP_TITLE' => 14, 'APP_PRO_TITLE' => 15, 'APP_TAS_TITLE' => 16, 'APP_CURRENT_USER' => 17, 'APP_DEL_PREVIOUS_USER' => 18, 'DEL_PRIORITY' => 19, 'DEL_DURATION' => 20, 'DEL_QUEUE_DURATION' => 21, 'DEL_DELAY_DURATION' => 22, 'DEL_STARTED' => 23, 'DEL_FINISHED' => 24, 'DEL_DELAYED' => 25, 'APP_CREATE_DATE' => 26, 'APP_FINISH_DATE' => 27, 'APP_UPDATE_DATE' => 28, 'APP_OVERDUE_PERCENTAGE' => 29, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppCacheViewMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppCacheViewMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppCacheViewPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppCacheViewPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppCacheViewPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppCacheViewPeer::APP_UID); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_INDEX); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_NUMBER); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_STATUS); + + $criteria->addSelectColumn(AppCacheViewPeer::USR_UID); + + $criteria->addSelectColumn(AppCacheViewPeer::PREVIOUS_USR_UID); + + $criteria->addSelectColumn(AppCacheViewPeer::TAS_UID); + + $criteria->addSelectColumn(AppCacheViewPeer::PRO_UID); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_DELEGATE_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_INIT_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_TASK_DUE_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_FINISH_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_THREAD_STATUS); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_THREAD_STATUS); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_TITLE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_PRO_TITLE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_TAS_TITLE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_CURRENT_USER); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_DEL_PREVIOUS_USER); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_PRIORITY); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_DURATION); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_QUEUE_DURATION); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_DELAY_DURATION); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_STARTED); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_FINISHED); + + $criteria->addSelectColumn(AppCacheViewPeer::DEL_DELAYED); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_CREATE_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_FINISH_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_UPDATE_DATE); + + $criteria->addSelectColumn(AppCacheViewPeer::APP_OVERDUE_PERCENTAGE); + + } + + const COUNT = 'COUNT(APP_CACHE_VIEW.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_CACHE_VIEW.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppCacheViewPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppCacheViewPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppCacheViewPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppCacheView + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppCacheViewPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppCacheViewPeer::populateObjects(AppCacheViewPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppCacheViewPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppCacheViewPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppCacheViewPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppCacheView or Criteria object. + * + * @param mixed $values Criteria or AppCacheView object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppCacheView object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppCacheView or Criteria object. + * + * @param mixed $values Criteria or AppCacheView object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppCacheViewPeer::APP_UID); + $selectCriteria->add(AppCacheViewPeer::APP_UID, $criteria->remove(AppCacheViewPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(AppCacheViewPeer::DEL_INDEX); + $selectCriteria->add(AppCacheViewPeer::DEL_INDEX, $criteria->remove(AppCacheViewPeer::DEL_INDEX), $comparison); + + } else { // $values is AppCacheView object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_CACHE_VIEW table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppCacheViewPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppCacheView or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppCacheView object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppCacheViewPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppCacheView) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(AppCacheViewPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppCacheViewPeer::DEL_INDEX, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppCacheView object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppCacheView $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppCacheView $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppCacheViewPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppCacheViewPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppCacheViewPeer::DATABASE_NAME, AppCacheViewPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param int $del_index + + * @param Connection $con + * @return AppCacheView + */ + public static function retrieveByPK( $app_uid, $del_index, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppCacheViewPeer::APP_UID, $app_uid); + $criteria->add(AppCacheViewPeer::DEL_INDEX, $del_index); + $v = AppCacheViewPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppCacheViewPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppCacheViewPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppCacheViewMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppCacheViewMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppDelay.php b/workflow/engine/classes/model/om/BaseAppDelay.php new file mode 100644 index 000000000..fc0169aae --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDelay.php @@ -0,0 +1,1259 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppDelayPeer.php'; + +/** + * Base class that represents a row from the 'APP_DELAY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDelay extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppDelayPeer + */ + protected static $peer; + + + /** + * The value for the app_delay_uid field. + * @var string + */ + protected $app_delay_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = '0'; + + + /** + * The value for the app_thread_index field. + * @var int + */ + protected $app_thread_index = 0; + + + /** + * The value for the app_del_index field. + * @var int + */ + protected $app_del_index = 0; + + + /** + * The value for the app_type field. + * @var string + */ + protected $app_type = '0'; + + + /** + * The value for the app_status field. + * @var string + */ + protected $app_status = '0'; + + + /** + * The value for the app_next_task field. + * @var string + */ + protected $app_next_task = '0'; + + + /** + * The value for the app_delegation_user field. + * @var string + */ + protected $app_delegation_user = '0'; + + + /** + * The value for the app_enable_action_user field. + * @var string + */ + protected $app_enable_action_user = '0'; + + + /** + * The value for the app_enable_action_date field. + * @var int + */ + protected $app_enable_action_date; + + + /** + * The value for the app_disable_action_user field. + * @var string + */ + protected $app_disable_action_user = '0'; + + + /** + * The value for the app_disable_action_date field. + * @var int + */ + protected $app_disable_action_date; + + + /** + * The value for the app_automatic_disabled_date field. + * @var int + */ + protected $app_automatic_disabled_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_delay_uid] column value. + * + * @return string + */ + public function getAppDelayUid() + { + + return $this->app_delay_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [app_thread_index] column value. + * + * @return int + */ + public function getAppThreadIndex() + { + + return $this->app_thread_index; + } + + /** + * Get the [app_del_index] column value. + * + * @return int + */ + public function getAppDelIndex() + { + + return $this->app_del_index; + } + + /** + * Get the [app_type] column value. + * + * @return string + */ + public function getAppType() + { + + return $this->app_type; + } + + /** + * Get the [app_status] column value. + * + * @return string + */ + public function getAppStatus() + { + + return $this->app_status; + } + + /** + * Get the [app_next_task] column value. + * + * @return string + */ + public function getAppNextTask() + { + + return $this->app_next_task; + } + + /** + * Get the [app_delegation_user] column value. + * + * @return string + */ + public function getAppDelegationUser() + { + + return $this->app_delegation_user; + } + + /** + * Get the [app_enable_action_user] column value. + * + * @return string + */ + public function getAppEnableActionUser() + { + + return $this->app_enable_action_user; + } + + /** + * Get the [optionally formatted] [app_enable_action_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppEnableActionDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_enable_action_date === null || $this->app_enable_action_date === '') { + return null; + } elseif (!is_int($this->app_enable_action_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_enable_action_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_enable_action_date] as date/time value: " . var_export($this->app_enable_action_date, true)); + } + } else { + $ts = $this->app_enable_action_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_disable_action_user] column value. + * + * @return string + */ + public function getAppDisableActionUser() + { + + return $this->app_disable_action_user; + } + + /** + * Get the [optionally formatted] [app_disable_action_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppDisableActionDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_disable_action_date === null || $this->app_disable_action_date === '') { + return null; + } elseif (!is_int($this->app_disable_action_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_disable_action_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_disable_action_date] as date/time value: " . var_export($this->app_disable_action_date, true)); + } + } else { + $ts = $this->app_disable_action_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_automatic_disabled_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppAutomaticDisabledDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_automatic_disabled_date === null || $this->app_automatic_disabled_date === '') { + return null; + } elseif (!is_int($this->app_automatic_disabled_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_automatic_disabled_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_automatic_disabled_date] as date/time value: " . var_export($this->app_automatic_disabled_date, true)); + } + } else { + $ts = $this->app_automatic_disabled_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [app_delay_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppDelayUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_delay_uid !== $v || $v === '') { + $this->app_delay_uid = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_DELAY_UID; + } + + } // setAppDelayUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = AppDelayPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '0') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [app_thread_index] column. + * + * @param int $v new value + * @return void + */ + public function setAppThreadIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_thread_index !== $v || $v === 0) { + $this->app_thread_index = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_THREAD_INDEX; + } + + } // setAppThreadIndex() + + /** + * Set the value of [app_del_index] column. + * + * @param int $v new value + * @return void + */ + public function setAppDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_del_index !== $v || $v === 0) { + $this->app_del_index = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_DEL_INDEX; + } + + } // setAppDelIndex() + + /** + * Set the value of [app_type] column. + * + * @param string $v new value + * @return void + */ + public function setAppType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_type !== $v || $v === '0') { + $this->app_type = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_TYPE; + } + + } // setAppType() + + /** + * Set the value of [app_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_status !== $v || $v === '0') { + $this->app_status = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_STATUS; + } + + } // setAppStatus() + + /** + * Set the value of [app_next_task] column. + * + * @param string $v new value + * @return void + */ + public function setAppNextTask($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_next_task !== $v || $v === '0') { + $this->app_next_task = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_NEXT_TASK; + } + + } // setAppNextTask() + + /** + * Set the value of [app_delegation_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppDelegationUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_delegation_user !== $v || $v === '0') { + $this->app_delegation_user = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_DELEGATION_USER; + } + + } // setAppDelegationUser() + + /** + * Set the value of [app_enable_action_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppEnableActionUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_enable_action_user !== $v || $v === '0') { + $this->app_enable_action_user = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_ENABLE_ACTION_USER; + } + + } // setAppEnableActionUser() + + /** + * Set the value of [app_enable_action_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppEnableActionDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_enable_action_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_enable_action_date !== $ts) { + $this->app_enable_action_date = $ts; + $this->modifiedColumns[] = AppDelayPeer::APP_ENABLE_ACTION_DATE; + } + + } // setAppEnableActionDate() + + /** + * Set the value of [app_disable_action_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppDisableActionUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_disable_action_user !== $v || $v === '0') { + $this->app_disable_action_user = $v; + $this->modifiedColumns[] = AppDelayPeer::APP_DISABLE_ACTION_USER; + } + + } // setAppDisableActionUser() + + /** + * Set the value of [app_disable_action_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppDisableActionDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_disable_action_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_disable_action_date !== $ts) { + $this->app_disable_action_date = $ts; + $this->modifiedColumns[] = AppDelayPeer::APP_DISABLE_ACTION_DATE; + } + + } // setAppDisableActionDate() + + /** + * Set the value of [app_automatic_disabled_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppAutomaticDisabledDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_automatic_disabled_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_automatic_disabled_date !== $ts) { + $this->app_automatic_disabled_date = $ts; + $this->modifiedColumns[] = AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE; + } + + } // setAppAutomaticDisabledDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_delay_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->app_uid = $rs->getString($startcol + 2); + + $this->app_thread_index = $rs->getInt($startcol + 3); + + $this->app_del_index = $rs->getInt($startcol + 4); + + $this->app_type = $rs->getString($startcol + 5); + + $this->app_status = $rs->getString($startcol + 6); + + $this->app_next_task = $rs->getString($startcol + 7); + + $this->app_delegation_user = $rs->getString($startcol + 8); + + $this->app_enable_action_user = $rs->getString($startcol + 9); + + $this->app_enable_action_date = $rs->getTimestamp($startcol + 10, null); + + $this->app_disable_action_user = $rs->getString($startcol + 11); + + $this->app_disable_action_date = $rs->getTimestamp($startcol + 12, null); + + $this->app_automatic_disabled_date = $rs->getTimestamp($startcol + 13, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 14; // 14 = AppDelayPeer::NUM_COLUMNS - AppDelayPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppDelay object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDelayPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppDelayPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDelayPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppDelayPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppDelayPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppDelayPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDelayPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppDelayUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getAppUid(); + break; + case 3: + return $this->getAppThreadIndex(); + break; + case 4: + return $this->getAppDelIndex(); + break; + case 5: + return $this->getAppType(); + break; + case 6: + return $this->getAppStatus(); + break; + case 7: + return $this->getAppNextTask(); + break; + case 8: + return $this->getAppDelegationUser(); + break; + case 9: + return $this->getAppEnableActionUser(); + break; + case 10: + return $this->getAppEnableActionDate(); + break; + case 11: + return $this->getAppDisableActionUser(); + break; + case 12: + return $this->getAppDisableActionDate(); + break; + case 13: + return $this->getAppAutomaticDisabledDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDelayPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppDelayUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getAppUid(), + $keys[3] => $this->getAppThreadIndex(), + $keys[4] => $this->getAppDelIndex(), + $keys[5] => $this->getAppType(), + $keys[6] => $this->getAppStatus(), + $keys[7] => $this->getAppNextTask(), + $keys[8] => $this->getAppDelegationUser(), + $keys[9] => $this->getAppEnableActionUser(), + $keys[10] => $this->getAppEnableActionDate(), + $keys[11] => $this->getAppDisableActionUser(), + $keys[12] => $this->getAppDisableActionDate(), + $keys[13] => $this->getAppAutomaticDisabledDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDelayPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppDelayUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setAppUid($value); + break; + case 3: + $this->setAppThreadIndex($value); + break; + case 4: + $this->setAppDelIndex($value); + break; + case 5: + $this->setAppType($value); + break; + case 6: + $this->setAppStatus($value); + break; + case 7: + $this->setAppNextTask($value); + break; + case 8: + $this->setAppDelegationUser($value); + break; + case 9: + $this->setAppEnableActionUser($value); + break; + case 10: + $this->setAppEnableActionDate($value); + break; + case 11: + $this->setAppDisableActionUser($value); + break; + case 12: + $this->setAppDisableActionDate($value); + break; + case 13: + $this->setAppAutomaticDisabledDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDelayPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppDelayUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAppThreadIndex($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAppDelIndex($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppType($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppStatus($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAppNextTask($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAppDelegationUser($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAppEnableActionUser($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setAppEnableActionDate($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setAppDisableActionUser($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setAppDisableActionDate($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setAppAutomaticDisabledDate($arr[$keys[13]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppDelayPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppDelayPeer::APP_DELAY_UID)) $criteria->add(AppDelayPeer::APP_DELAY_UID, $this->app_delay_uid); + if ($this->isColumnModified(AppDelayPeer::PRO_UID)) $criteria->add(AppDelayPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(AppDelayPeer::APP_UID)) $criteria->add(AppDelayPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppDelayPeer::APP_THREAD_INDEX)) $criteria->add(AppDelayPeer::APP_THREAD_INDEX, $this->app_thread_index); + if ($this->isColumnModified(AppDelayPeer::APP_DEL_INDEX)) $criteria->add(AppDelayPeer::APP_DEL_INDEX, $this->app_del_index); + if ($this->isColumnModified(AppDelayPeer::APP_TYPE)) $criteria->add(AppDelayPeer::APP_TYPE, $this->app_type); + if ($this->isColumnModified(AppDelayPeer::APP_STATUS)) $criteria->add(AppDelayPeer::APP_STATUS, $this->app_status); + if ($this->isColumnModified(AppDelayPeer::APP_NEXT_TASK)) $criteria->add(AppDelayPeer::APP_NEXT_TASK, $this->app_next_task); + if ($this->isColumnModified(AppDelayPeer::APP_DELEGATION_USER)) $criteria->add(AppDelayPeer::APP_DELEGATION_USER, $this->app_delegation_user); + if ($this->isColumnModified(AppDelayPeer::APP_ENABLE_ACTION_USER)) $criteria->add(AppDelayPeer::APP_ENABLE_ACTION_USER, $this->app_enable_action_user); + if ($this->isColumnModified(AppDelayPeer::APP_ENABLE_ACTION_DATE)) $criteria->add(AppDelayPeer::APP_ENABLE_ACTION_DATE, $this->app_enable_action_date); + if ($this->isColumnModified(AppDelayPeer::APP_DISABLE_ACTION_USER)) $criteria->add(AppDelayPeer::APP_DISABLE_ACTION_USER, $this->app_disable_action_user); + if ($this->isColumnModified(AppDelayPeer::APP_DISABLE_ACTION_DATE)) $criteria->add(AppDelayPeer::APP_DISABLE_ACTION_DATE, $this->app_disable_action_date); + if ($this->isColumnModified(AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE)) $criteria->add(AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE, $this->app_automatic_disabled_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppDelayPeer::DATABASE_NAME); + + $criteria->add(AppDelayPeer::APP_DELAY_UID, $this->app_delay_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getAppDelayUid(); + } + + /** + * Generic method to set the primary key (app_delay_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setAppDelayUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppDelay (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setAppUid($this->app_uid); + + $copyObj->setAppThreadIndex($this->app_thread_index); + + $copyObj->setAppDelIndex($this->app_del_index); + + $copyObj->setAppType($this->app_type); + + $copyObj->setAppStatus($this->app_status); + + $copyObj->setAppNextTask($this->app_next_task); + + $copyObj->setAppDelegationUser($this->app_delegation_user); + + $copyObj->setAppEnableActionUser($this->app_enable_action_user); + + $copyObj->setAppEnableActionDate($this->app_enable_action_date); + + $copyObj->setAppDisableActionUser($this->app_disable_action_user); + + $copyObj->setAppDisableActionDate($this->app_disable_action_date); + + $copyObj->setAppAutomaticDisabledDate($this->app_automatic_disabled_date); + + + $copyObj->setNew(true); + + $copyObj->setAppDelayUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppDelay Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppDelayPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppDelayPeer(); + } + return self::$peer; + } + +} // BaseAppDelay diff --git a/workflow/engine/classes/model/om/BaseAppDelayPeer.php b/workflow/engine/classes/model/om/BaseAppDelayPeer.php new file mode 100644 index 000000000..e6714558f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDelayPeer.php @@ -0,0 +1,630 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppDelayPeer::getOMClass() +include_once 'classes/model/AppDelay.php'; + +/** + * Base static class for performing query and update operations on the 'APP_DELAY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDelayPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_DELAY'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppDelay'; + + /** The total number of columns. */ + const NUM_COLUMNS = 14; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_DELAY_UID field */ + const APP_DELAY_UID = 'APP_DELAY.APP_DELAY_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'APP_DELAY.PRO_UID'; + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_DELAY.APP_UID'; + + /** the column name for the APP_THREAD_INDEX field */ + const APP_THREAD_INDEX = 'APP_DELAY.APP_THREAD_INDEX'; + + /** the column name for the APP_DEL_INDEX field */ + const APP_DEL_INDEX = 'APP_DELAY.APP_DEL_INDEX'; + + /** the column name for the APP_TYPE field */ + const APP_TYPE = 'APP_DELAY.APP_TYPE'; + + /** the column name for the APP_STATUS field */ + const APP_STATUS = 'APP_DELAY.APP_STATUS'; + + /** the column name for the APP_NEXT_TASK field */ + const APP_NEXT_TASK = 'APP_DELAY.APP_NEXT_TASK'; + + /** the column name for the APP_DELEGATION_USER field */ + const APP_DELEGATION_USER = 'APP_DELAY.APP_DELEGATION_USER'; + + /** the column name for the APP_ENABLE_ACTION_USER field */ + const APP_ENABLE_ACTION_USER = 'APP_DELAY.APP_ENABLE_ACTION_USER'; + + /** the column name for the APP_ENABLE_ACTION_DATE field */ + const APP_ENABLE_ACTION_DATE = 'APP_DELAY.APP_ENABLE_ACTION_DATE'; + + /** the column name for the APP_DISABLE_ACTION_USER field */ + const APP_DISABLE_ACTION_USER = 'APP_DELAY.APP_DISABLE_ACTION_USER'; + + /** the column name for the APP_DISABLE_ACTION_DATE field */ + const APP_DISABLE_ACTION_DATE = 'APP_DELAY.APP_DISABLE_ACTION_DATE'; + + /** the column name for the APP_AUTOMATIC_DISABLED_DATE field */ + const APP_AUTOMATIC_DISABLED_DATE = 'APP_DELAY.APP_AUTOMATIC_DISABLED_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppDelayUid', 'ProUid', 'AppUid', 'AppThreadIndex', 'AppDelIndex', 'AppType', 'AppStatus', 'AppNextTask', 'AppDelegationUser', 'AppEnableActionUser', 'AppEnableActionDate', 'AppDisableActionUser', 'AppDisableActionDate', 'AppAutomaticDisabledDate', ), + BasePeer::TYPE_COLNAME => array (AppDelayPeer::APP_DELAY_UID, AppDelayPeer::PRO_UID, AppDelayPeer::APP_UID, AppDelayPeer::APP_THREAD_INDEX, AppDelayPeer::APP_DEL_INDEX, AppDelayPeer::APP_TYPE, AppDelayPeer::APP_STATUS, AppDelayPeer::APP_NEXT_TASK, AppDelayPeer::APP_DELEGATION_USER, AppDelayPeer::APP_ENABLE_ACTION_USER, AppDelayPeer::APP_ENABLE_ACTION_DATE, AppDelayPeer::APP_DISABLE_ACTION_USER, AppDelayPeer::APP_DISABLE_ACTION_DATE, AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_DELAY_UID', 'PRO_UID', 'APP_UID', 'APP_THREAD_INDEX', 'APP_DEL_INDEX', 'APP_TYPE', 'APP_STATUS', 'APP_NEXT_TASK', 'APP_DELEGATION_USER', 'APP_ENABLE_ACTION_USER', 'APP_ENABLE_ACTION_DATE', 'APP_DISABLE_ACTION_USER', 'APP_DISABLE_ACTION_DATE', 'APP_AUTOMATIC_DISABLED_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppDelayUid' => 0, 'ProUid' => 1, 'AppUid' => 2, 'AppThreadIndex' => 3, 'AppDelIndex' => 4, 'AppType' => 5, 'AppStatus' => 6, 'AppNextTask' => 7, 'AppDelegationUser' => 8, 'AppEnableActionUser' => 9, 'AppEnableActionDate' => 10, 'AppDisableActionUser' => 11, 'AppDisableActionDate' => 12, 'AppAutomaticDisabledDate' => 13, ), + BasePeer::TYPE_COLNAME => array (AppDelayPeer::APP_DELAY_UID => 0, AppDelayPeer::PRO_UID => 1, AppDelayPeer::APP_UID => 2, AppDelayPeer::APP_THREAD_INDEX => 3, AppDelayPeer::APP_DEL_INDEX => 4, AppDelayPeer::APP_TYPE => 5, AppDelayPeer::APP_STATUS => 6, AppDelayPeer::APP_NEXT_TASK => 7, AppDelayPeer::APP_DELEGATION_USER => 8, AppDelayPeer::APP_ENABLE_ACTION_USER => 9, AppDelayPeer::APP_ENABLE_ACTION_DATE => 10, AppDelayPeer::APP_DISABLE_ACTION_USER => 11, AppDelayPeer::APP_DISABLE_ACTION_DATE => 12, AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE => 13, ), + BasePeer::TYPE_FIELDNAME => array ('APP_DELAY_UID' => 0, 'PRO_UID' => 1, 'APP_UID' => 2, 'APP_THREAD_INDEX' => 3, 'APP_DEL_INDEX' => 4, 'APP_TYPE' => 5, 'APP_STATUS' => 6, 'APP_NEXT_TASK' => 7, 'APP_DELEGATION_USER' => 8, 'APP_ENABLE_ACTION_USER' => 9, 'APP_ENABLE_ACTION_DATE' => 10, 'APP_DISABLE_ACTION_USER' => 11, 'APP_DISABLE_ACTION_DATE' => 12, 'APP_AUTOMATIC_DISABLED_DATE' => 13, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppDelayMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppDelayMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppDelayPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppDelayPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppDelayPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppDelayPeer::APP_DELAY_UID); + + $criteria->addSelectColumn(AppDelayPeer::PRO_UID); + + $criteria->addSelectColumn(AppDelayPeer::APP_UID); + + $criteria->addSelectColumn(AppDelayPeer::APP_THREAD_INDEX); + + $criteria->addSelectColumn(AppDelayPeer::APP_DEL_INDEX); + + $criteria->addSelectColumn(AppDelayPeer::APP_TYPE); + + $criteria->addSelectColumn(AppDelayPeer::APP_STATUS); + + $criteria->addSelectColumn(AppDelayPeer::APP_NEXT_TASK); + + $criteria->addSelectColumn(AppDelayPeer::APP_DELEGATION_USER); + + $criteria->addSelectColumn(AppDelayPeer::APP_ENABLE_ACTION_USER); + + $criteria->addSelectColumn(AppDelayPeer::APP_ENABLE_ACTION_DATE); + + $criteria->addSelectColumn(AppDelayPeer::APP_DISABLE_ACTION_USER); + + $criteria->addSelectColumn(AppDelayPeer::APP_DISABLE_ACTION_DATE); + + $criteria->addSelectColumn(AppDelayPeer::APP_AUTOMATIC_DISABLED_DATE); + + } + + const COUNT = 'COUNT(APP_DELAY.APP_DELAY_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_DELAY.APP_DELAY_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppDelayPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppDelayPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppDelayPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppDelay + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppDelayPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppDelayPeer::populateObjects(AppDelayPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppDelayPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppDelayPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppDelayPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppDelay or Criteria object. + * + * @param mixed $values Criteria or AppDelay object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppDelay object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppDelay or Criteria object. + * + * @param mixed $values Criteria or AppDelay object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppDelayPeer::APP_DELAY_UID); + $selectCriteria->add(AppDelayPeer::APP_DELAY_UID, $criteria->remove(AppDelayPeer::APP_DELAY_UID), $comparison); + + } else { // $values is AppDelay object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_DELAY table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppDelayPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppDelay or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppDelay object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppDelayPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppDelay) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(AppDelayPeer::APP_DELAY_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppDelay object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppDelay $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppDelay $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppDelayPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppDelayPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppDelayPeer::DATABASE_NAME, AppDelayPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return AppDelay + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(AppDelayPeer::DATABASE_NAME); + + $criteria->add(AppDelayPeer::APP_DELAY_UID, $pk); + + + $v = AppDelayPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(AppDelayPeer::APP_DELAY_UID, $pks, Criteria::IN); + $objs = AppDelayPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseAppDelayPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppDelayPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppDelayMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppDelayMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppDelegation.php b/workflow/engine/classes/model/om/BaseAppDelegation.php new file mode 100644 index 000000000..c13c01a56 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDelegation.php @@ -0,0 +1,1693 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppDelegationPeer.php'; + +/** + * Base class that represents a row from the 'APP_DELEGATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDelegation extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppDelegationPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the del_previous field. + * @var int + */ + protected $del_previous = 0; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the del_type field. + * @var string + */ + protected $del_type = 'NORMAL'; + + + /** + * The value for the del_thread field. + * @var int + */ + protected $del_thread = 0; + + + /** + * The value for the del_thread_status field. + * @var string + */ + protected $del_thread_status = 'OPEN'; + + + /** + * The value for the del_priority field. + * @var string + */ + protected $del_priority = '3'; + + + /** + * The value for the del_delegate_date field. + * @var int + */ + protected $del_delegate_date; + + + /** + * The value for the del_init_date field. + * @var int + */ + protected $del_init_date; + + + /** + * The value for the del_task_due_date field. + * @var int + */ + protected $del_task_due_date; + + + /** + * The value for the del_finish_date field. + * @var int + */ + protected $del_finish_date; + + + /** + * The value for the del_duration field. + * @var double + */ + protected $del_duration = 0; + + + /** + * The value for the del_queue_duration field. + * @var double + */ + protected $del_queue_duration = 0; + + + /** + * The value for the del_delay_duration field. + * @var double + */ + protected $del_delay_duration = 0; + + + /** + * The value for the del_started field. + * @var int + */ + protected $del_started = 0; + + + /** + * The value for the del_finished field. + * @var int + */ + protected $del_finished = 0; + + + /** + * The value for the del_delayed field. + * @var int + */ + protected $del_delayed = 0; + + + /** + * The value for the del_data field. + * @var string + */ + protected $del_data; + + + /** + * The value for the app_overdue_percentage field. + * @var double + */ + protected $app_overdue_percentage = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [del_previous] column value. + * + * @return int + */ + public function getDelPrevious() + { + + return $this->del_previous; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [del_type] column value. + * + * @return string + */ + public function getDelType() + { + + return $this->del_type; + } + + /** + * Get the [del_thread] column value. + * + * @return int + */ + public function getDelThread() + { + + return $this->del_thread; + } + + /** + * Get the [del_thread_status] column value. + * + * @return string + */ + public function getDelThreadStatus() + { + + return $this->del_thread_status; + } + + /** + * Get the [del_priority] column value. + * + * @return string + */ + public function getDelPriority() + { + + return $this->del_priority; + } + + /** + * Get the [optionally formatted] [del_delegate_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelDelegateDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_delegate_date === null || $this->del_delegate_date === '') { + return null; + } elseif (!is_int($this->del_delegate_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_delegate_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_delegate_date] as date/time value: " . var_export($this->del_delegate_date, true)); + } + } else { + $ts = $this->del_delegate_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_init_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelInitDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_init_date === null || $this->del_init_date === '') { + return null; + } elseif (!is_int($this->del_init_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_init_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_init_date] as date/time value: " . var_export($this->del_init_date, true)); + } + } else { + $ts = $this->del_init_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_task_due_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelTaskDueDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_task_due_date === null || $this->del_task_due_date === '') { + return null; + } elseif (!is_int($this->del_task_due_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_task_due_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_task_due_date] as date/time value: " . var_export($this->del_task_due_date, true)); + } + } else { + $ts = $this->del_task_due_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [del_finish_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getDelFinishDate($format = 'Y-m-d H:i:s') + { + + if ($this->del_finish_date === null || $this->del_finish_date === '') { + return null; + } elseif (!is_int($this->del_finish_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->del_finish_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [del_finish_date] as date/time value: " . var_export($this->del_finish_date, true)); + } + } else { + $ts = $this->del_finish_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [del_duration] column value. + * + * @return double + */ + public function getDelDuration() + { + + return $this->del_duration; + } + + /** + * Get the [del_queue_duration] column value. + * + * @return double + */ + public function getDelQueueDuration() + { + + return $this->del_queue_duration; + } + + /** + * Get the [del_delay_duration] column value. + * + * @return double + */ + public function getDelDelayDuration() + { + + return $this->del_delay_duration; + } + + /** + * Get the [del_started] column value. + * + * @return int + */ + public function getDelStarted() + { + + return $this->del_started; + } + + /** + * Get the [del_finished] column value. + * + * @return int + */ + public function getDelFinished() + { + + return $this->del_finished; + } + + /** + * Get the [del_delayed] column value. + * + * @return int + */ + public function getDelDelayed() + { + + return $this->del_delayed; + } + + /** + * Get the [del_data] column value. + * + * @return string + */ + public function getDelData() + { + + return $this->del_data; + } + + /** + * Get the [app_overdue_percentage] column value. + * + * @return double + */ + public function getAppOverduePercentage() + { + + return $this->app_overdue_percentage; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppDelegationPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [del_previous] column. + * + * @param int $v new value + * @return void + */ + public function setDelPrevious($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_previous !== $v || $v === 0) { + $this->del_previous = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_PREVIOUS; + } + + } // setDelPrevious() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = AppDelegationPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = AppDelegationPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = AppDelegationPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [del_type] column. + * + * @param string $v new value + * @return void + */ + public function setDelType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_type !== $v || $v === 'NORMAL') { + $this->del_type = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_TYPE; + } + + } // setDelType() + + /** + * Set the value of [del_thread] column. + * + * @param int $v new value + * @return void + */ + public function setDelThread($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_thread !== $v || $v === 0) { + $this->del_thread = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_THREAD; + } + + } // setDelThread() + + /** + * Set the value of [del_thread_status] column. + * + * @param string $v new value + * @return void + */ + public function setDelThreadStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_thread_status !== $v || $v === 'OPEN') { + $this->del_thread_status = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_THREAD_STATUS; + } + + } // setDelThreadStatus() + + /** + * Set the value of [del_priority] column. + * + * @param string $v new value + * @return void + */ + public function setDelPriority($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_priority !== $v || $v === '3') { + $this->del_priority = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_PRIORITY; + } + + } // setDelPriority() + + /** + * Set the value of [del_delegate_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelDelegateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_delegate_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_delegate_date !== $ts) { + $this->del_delegate_date = $ts; + $this->modifiedColumns[] = AppDelegationPeer::DEL_DELEGATE_DATE; + } + + } // setDelDelegateDate() + + /** + * Set the value of [del_init_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelInitDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_init_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_init_date !== $ts) { + $this->del_init_date = $ts; + $this->modifiedColumns[] = AppDelegationPeer::DEL_INIT_DATE; + } + + } // setDelInitDate() + + /** + * Set the value of [del_task_due_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelTaskDueDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_task_due_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_task_due_date !== $ts) { + $this->del_task_due_date = $ts; + $this->modifiedColumns[] = AppDelegationPeer::DEL_TASK_DUE_DATE; + } + + } // setDelTaskDueDate() + + /** + * Set the value of [del_finish_date] column. + * + * @param int $v new value + * @return void + */ + public function setDelFinishDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [del_finish_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->del_finish_date !== $ts) { + $this->del_finish_date = $ts; + $this->modifiedColumns[] = AppDelegationPeer::DEL_FINISH_DATE; + } + + } // setDelFinishDate() + + /** + * Set the value of [del_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelDuration($v) + { + + if ($this->del_duration !== $v || $v === 0) { + $this->del_duration = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_DURATION; + } + + } // setDelDuration() + + /** + * Set the value of [del_queue_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelQueueDuration($v) + { + + if ($this->del_queue_duration !== $v || $v === 0) { + $this->del_queue_duration = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_QUEUE_DURATION; + } + + } // setDelQueueDuration() + + /** + * Set the value of [del_delay_duration] column. + * + * @param double $v new value + * @return void + */ + public function setDelDelayDuration($v) + { + + if ($this->del_delay_duration !== $v || $v === 0) { + $this->del_delay_duration = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_DELAY_DURATION; + } + + } // setDelDelayDuration() + + /** + * Set the value of [del_started] column. + * + * @param int $v new value + * @return void + */ + public function setDelStarted($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_started !== $v || $v === 0) { + $this->del_started = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_STARTED; + } + + } // setDelStarted() + + /** + * Set the value of [del_finished] column. + * + * @param int $v new value + * @return void + */ + public function setDelFinished($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_finished !== $v || $v === 0) { + $this->del_finished = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_FINISHED; + } + + } // setDelFinished() + + /** + * Set the value of [del_delayed] column. + * + * @param int $v new value + * @return void + */ + public function setDelDelayed($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_delayed !== $v || $v === 0) { + $this->del_delayed = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_DELAYED; + } + + } // setDelDelayed() + + /** + * Set the value of [del_data] column. + * + * @param string $v new value + * @return void + */ + public function setDelData($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->del_data !== $v) { + $this->del_data = $v; + $this->modifiedColumns[] = AppDelegationPeer::DEL_DATA; + } + + } // setDelData() + + /** + * Set the value of [app_overdue_percentage] column. + * + * @param double $v new value + * @return void + */ + public function setAppOverduePercentage($v) + { + + if ($this->app_overdue_percentage !== $v || $v === 0) { + $this->app_overdue_percentage = $v; + $this->modifiedColumns[] = AppDelegationPeer::APP_OVERDUE_PERCENTAGE; + } + + } // setAppOverduePercentage() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->del_index = $rs->getInt($startcol + 1); + + $this->del_previous = $rs->getInt($startcol + 2); + + $this->pro_uid = $rs->getString($startcol + 3); + + $this->tas_uid = $rs->getString($startcol + 4); + + $this->usr_uid = $rs->getString($startcol + 5); + + $this->del_type = $rs->getString($startcol + 6); + + $this->del_thread = $rs->getInt($startcol + 7); + + $this->del_thread_status = $rs->getString($startcol + 8); + + $this->del_priority = $rs->getString($startcol + 9); + + $this->del_delegate_date = $rs->getTimestamp($startcol + 10, null); + + $this->del_init_date = $rs->getTimestamp($startcol + 11, null); + + $this->del_task_due_date = $rs->getTimestamp($startcol + 12, null); + + $this->del_finish_date = $rs->getTimestamp($startcol + 13, null); + + $this->del_duration = $rs->getFloat($startcol + 14); + + $this->del_queue_duration = $rs->getFloat($startcol + 15); + + $this->del_delay_duration = $rs->getFloat($startcol + 16); + + $this->del_started = $rs->getInt($startcol + 17); + + $this->del_finished = $rs->getInt($startcol + 18); + + $this->del_delayed = $rs->getInt($startcol + 19); + + $this->del_data = $rs->getString($startcol + 20); + + $this->app_overdue_percentage = $rs->getFloat($startcol + 21); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 22; // 22 = AppDelegationPeer::NUM_COLUMNS - AppDelegationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppDelegation object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDelegationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppDelegationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDelegationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppDelegationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppDelegationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppDelegationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDelegationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getDelIndex(); + break; + case 2: + return $this->getDelPrevious(); + break; + case 3: + return $this->getProUid(); + break; + case 4: + return $this->getTasUid(); + break; + case 5: + return $this->getUsrUid(); + break; + case 6: + return $this->getDelType(); + break; + case 7: + return $this->getDelThread(); + break; + case 8: + return $this->getDelThreadStatus(); + break; + case 9: + return $this->getDelPriority(); + break; + case 10: + return $this->getDelDelegateDate(); + break; + case 11: + return $this->getDelInitDate(); + break; + case 12: + return $this->getDelTaskDueDate(); + break; + case 13: + return $this->getDelFinishDate(); + break; + case 14: + return $this->getDelDuration(); + break; + case 15: + return $this->getDelQueueDuration(); + break; + case 16: + return $this->getDelDelayDuration(); + break; + case 17: + return $this->getDelStarted(); + break; + case 18: + return $this->getDelFinished(); + break; + case 19: + return $this->getDelDelayed(); + break; + case 20: + return $this->getDelData(); + break; + case 21: + return $this->getAppOverduePercentage(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDelegationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getDelIndex(), + $keys[2] => $this->getDelPrevious(), + $keys[3] => $this->getProUid(), + $keys[4] => $this->getTasUid(), + $keys[5] => $this->getUsrUid(), + $keys[6] => $this->getDelType(), + $keys[7] => $this->getDelThread(), + $keys[8] => $this->getDelThreadStatus(), + $keys[9] => $this->getDelPriority(), + $keys[10] => $this->getDelDelegateDate(), + $keys[11] => $this->getDelInitDate(), + $keys[12] => $this->getDelTaskDueDate(), + $keys[13] => $this->getDelFinishDate(), + $keys[14] => $this->getDelDuration(), + $keys[15] => $this->getDelQueueDuration(), + $keys[16] => $this->getDelDelayDuration(), + $keys[17] => $this->getDelStarted(), + $keys[18] => $this->getDelFinished(), + $keys[19] => $this->getDelDelayed(), + $keys[20] => $this->getDelData(), + $keys[21] => $this->getAppOverduePercentage(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDelegationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setDelIndex($value); + break; + case 2: + $this->setDelPrevious($value); + break; + case 3: + $this->setProUid($value); + break; + case 4: + $this->setTasUid($value); + break; + case 5: + $this->setUsrUid($value); + break; + case 6: + $this->setDelType($value); + break; + case 7: + $this->setDelThread($value); + break; + case 8: + $this->setDelThreadStatus($value); + break; + case 9: + $this->setDelPriority($value); + break; + case 10: + $this->setDelDelegateDate($value); + break; + case 11: + $this->setDelInitDate($value); + break; + case 12: + $this->setDelTaskDueDate($value); + break; + case 13: + $this->setDelFinishDate($value); + break; + case 14: + $this->setDelDuration($value); + break; + case 15: + $this->setDelQueueDuration($value); + break; + case 16: + $this->setDelDelayDuration($value); + break; + case 17: + $this->setDelStarted($value); + break; + case 18: + $this->setDelFinished($value); + break; + case 19: + $this->setDelDelayed($value); + break; + case 20: + $this->setDelData($value); + break; + case 21: + $this->setAppOverduePercentage($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDelegationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDelIndex($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setDelPrevious($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setProUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTasUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUsrUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setDelType($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setDelThread($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setDelThreadStatus($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setDelPriority($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setDelDelegateDate($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setDelInitDate($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setDelTaskDueDate($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setDelFinishDate($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setDelDuration($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setDelQueueDuration($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setDelDelayDuration($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setDelStarted($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setDelFinished($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setDelDelayed($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setDelData($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setAppOverduePercentage($arr[$keys[21]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppDelegationPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppDelegationPeer::APP_UID)) $criteria->add(AppDelegationPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppDelegationPeer::DEL_INDEX)) $criteria->add(AppDelegationPeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppDelegationPeer::DEL_PREVIOUS)) $criteria->add(AppDelegationPeer::DEL_PREVIOUS, $this->del_previous); + if ($this->isColumnModified(AppDelegationPeer::PRO_UID)) $criteria->add(AppDelegationPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(AppDelegationPeer::TAS_UID)) $criteria->add(AppDelegationPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(AppDelegationPeer::USR_UID)) $criteria->add(AppDelegationPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(AppDelegationPeer::DEL_TYPE)) $criteria->add(AppDelegationPeer::DEL_TYPE, $this->del_type); + if ($this->isColumnModified(AppDelegationPeer::DEL_THREAD)) $criteria->add(AppDelegationPeer::DEL_THREAD, $this->del_thread); + if ($this->isColumnModified(AppDelegationPeer::DEL_THREAD_STATUS)) $criteria->add(AppDelegationPeer::DEL_THREAD_STATUS, $this->del_thread_status); + if ($this->isColumnModified(AppDelegationPeer::DEL_PRIORITY)) $criteria->add(AppDelegationPeer::DEL_PRIORITY, $this->del_priority); + if ($this->isColumnModified(AppDelegationPeer::DEL_DELEGATE_DATE)) $criteria->add(AppDelegationPeer::DEL_DELEGATE_DATE, $this->del_delegate_date); + if ($this->isColumnModified(AppDelegationPeer::DEL_INIT_DATE)) $criteria->add(AppDelegationPeer::DEL_INIT_DATE, $this->del_init_date); + if ($this->isColumnModified(AppDelegationPeer::DEL_TASK_DUE_DATE)) $criteria->add(AppDelegationPeer::DEL_TASK_DUE_DATE, $this->del_task_due_date); + if ($this->isColumnModified(AppDelegationPeer::DEL_FINISH_DATE)) $criteria->add(AppDelegationPeer::DEL_FINISH_DATE, $this->del_finish_date); + if ($this->isColumnModified(AppDelegationPeer::DEL_DURATION)) $criteria->add(AppDelegationPeer::DEL_DURATION, $this->del_duration); + if ($this->isColumnModified(AppDelegationPeer::DEL_QUEUE_DURATION)) $criteria->add(AppDelegationPeer::DEL_QUEUE_DURATION, $this->del_queue_duration); + if ($this->isColumnModified(AppDelegationPeer::DEL_DELAY_DURATION)) $criteria->add(AppDelegationPeer::DEL_DELAY_DURATION, $this->del_delay_duration); + if ($this->isColumnModified(AppDelegationPeer::DEL_STARTED)) $criteria->add(AppDelegationPeer::DEL_STARTED, $this->del_started); + if ($this->isColumnModified(AppDelegationPeer::DEL_FINISHED)) $criteria->add(AppDelegationPeer::DEL_FINISHED, $this->del_finished); + if ($this->isColumnModified(AppDelegationPeer::DEL_DELAYED)) $criteria->add(AppDelegationPeer::DEL_DELAYED, $this->del_delayed); + if ($this->isColumnModified(AppDelegationPeer::DEL_DATA)) $criteria->add(AppDelegationPeer::DEL_DATA, $this->del_data); + if ($this->isColumnModified(AppDelegationPeer::APP_OVERDUE_PERCENTAGE)) $criteria->add(AppDelegationPeer::APP_OVERDUE_PERCENTAGE, $this->app_overdue_percentage); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppDelegationPeer::DATABASE_NAME); + + $criteria->add(AppDelegationPeer::APP_UID, $this->app_uid); + $criteria->add(AppDelegationPeer::DEL_INDEX, $this->del_index); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getDelIndex(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setDelIndex($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppDelegation (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setDelPrevious($this->del_previous); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setDelType($this->del_type); + + $copyObj->setDelThread($this->del_thread); + + $copyObj->setDelThreadStatus($this->del_thread_status); + + $copyObj->setDelPriority($this->del_priority); + + $copyObj->setDelDelegateDate($this->del_delegate_date); + + $copyObj->setDelInitDate($this->del_init_date); + + $copyObj->setDelTaskDueDate($this->del_task_due_date); + + $copyObj->setDelFinishDate($this->del_finish_date); + + $copyObj->setDelDuration($this->del_duration); + + $copyObj->setDelQueueDuration($this->del_queue_duration); + + $copyObj->setDelDelayDuration($this->del_delay_duration); + + $copyObj->setDelStarted($this->del_started); + + $copyObj->setDelFinished($this->del_finished); + + $copyObj->setDelDelayed($this->del_delayed); + + $copyObj->setDelData($this->del_data); + + $copyObj->setAppOverduePercentage($this->app_overdue_percentage); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setDelIndex('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppDelegation Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppDelegationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppDelegationPeer(); + } + return self::$peer; + } + +} // BaseAppDelegation diff --git a/workflow/engine/classes/model/om/BaseAppDelegationPeer.php b/workflow/engine/classes/model/om/BaseAppDelegationPeer.php new file mode 100644 index 000000000..7fba5bb68 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDelegationPeer.php @@ -0,0 +1,670 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppDelegationPeer::getOMClass() +include_once 'classes/model/AppDelegation.php'; + +/** + * Base static class for performing query and update operations on the 'APP_DELEGATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDelegationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_DELEGATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppDelegation'; + + /** The total number of columns. */ + const NUM_COLUMNS = 22; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_DELEGATION.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_DELEGATION.DEL_INDEX'; + + /** the column name for the DEL_PREVIOUS field */ + const DEL_PREVIOUS = 'APP_DELEGATION.DEL_PREVIOUS'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'APP_DELEGATION.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'APP_DELEGATION.TAS_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'APP_DELEGATION.USR_UID'; + + /** the column name for the DEL_TYPE field */ + const DEL_TYPE = 'APP_DELEGATION.DEL_TYPE'; + + /** the column name for the DEL_THREAD field */ + const DEL_THREAD = 'APP_DELEGATION.DEL_THREAD'; + + /** the column name for the DEL_THREAD_STATUS field */ + const DEL_THREAD_STATUS = 'APP_DELEGATION.DEL_THREAD_STATUS'; + + /** the column name for the DEL_PRIORITY field */ + const DEL_PRIORITY = 'APP_DELEGATION.DEL_PRIORITY'; + + /** the column name for the DEL_DELEGATE_DATE field */ + const DEL_DELEGATE_DATE = 'APP_DELEGATION.DEL_DELEGATE_DATE'; + + /** the column name for the DEL_INIT_DATE field */ + const DEL_INIT_DATE = 'APP_DELEGATION.DEL_INIT_DATE'; + + /** the column name for the DEL_TASK_DUE_DATE field */ + const DEL_TASK_DUE_DATE = 'APP_DELEGATION.DEL_TASK_DUE_DATE'; + + /** the column name for the DEL_FINISH_DATE field */ + const DEL_FINISH_DATE = 'APP_DELEGATION.DEL_FINISH_DATE'; + + /** the column name for the DEL_DURATION field */ + const DEL_DURATION = 'APP_DELEGATION.DEL_DURATION'; + + /** the column name for the DEL_QUEUE_DURATION field */ + const DEL_QUEUE_DURATION = 'APP_DELEGATION.DEL_QUEUE_DURATION'; + + /** the column name for the DEL_DELAY_DURATION field */ + const DEL_DELAY_DURATION = 'APP_DELEGATION.DEL_DELAY_DURATION'; + + /** the column name for the DEL_STARTED field */ + const DEL_STARTED = 'APP_DELEGATION.DEL_STARTED'; + + /** the column name for the DEL_FINISHED field */ + const DEL_FINISHED = 'APP_DELEGATION.DEL_FINISHED'; + + /** the column name for the DEL_DELAYED field */ + const DEL_DELAYED = 'APP_DELEGATION.DEL_DELAYED'; + + /** the column name for the DEL_DATA field */ + const DEL_DATA = 'APP_DELEGATION.DEL_DATA'; + + /** the column name for the APP_OVERDUE_PERCENTAGE field */ + const APP_OVERDUE_PERCENTAGE = 'APP_DELEGATION.APP_OVERDUE_PERCENTAGE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'DelIndex', 'DelPrevious', 'ProUid', 'TasUid', 'UsrUid', 'DelType', 'DelThread', 'DelThreadStatus', 'DelPriority', 'DelDelegateDate', 'DelInitDate', 'DelTaskDueDate', 'DelFinishDate', 'DelDuration', 'DelQueueDuration', 'DelDelayDuration', 'DelStarted', 'DelFinished', 'DelDelayed', 'DelData', 'AppOverduePercentage', ), + BasePeer::TYPE_COLNAME => array (AppDelegationPeer::APP_UID, AppDelegationPeer::DEL_INDEX, AppDelegationPeer::DEL_PREVIOUS, AppDelegationPeer::PRO_UID, AppDelegationPeer::TAS_UID, AppDelegationPeer::USR_UID, AppDelegationPeer::DEL_TYPE, AppDelegationPeer::DEL_THREAD, AppDelegationPeer::DEL_THREAD_STATUS, AppDelegationPeer::DEL_PRIORITY, AppDelegationPeer::DEL_DELEGATE_DATE, AppDelegationPeer::DEL_INIT_DATE, AppDelegationPeer::DEL_TASK_DUE_DATE, AppDelegationPeer::DEL_FINISH_DATE, AppDelegationPeer::DEL_DURATION, AppDelegationPeer::DEL_QUEUE_DURATION, AppDelegationPeer::DEL_DELAY_DURATION, AppDelegationPeer::DEL_STARTED, AppDelegationPeer::DEL_FINISHED, AppDelegationPeer::DEL_DELAYED, AppDelegationPeer::DEL_DATA, AppDelegationPeer::APP_OVERDUE_PERCENTAGE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'DEL_INDEX', 'DEL_PREVIOUS', 'PRO_UID', 'TAS_UID', 'USR_UID', 'DEL_TYPE', 'DEL_THREAD', 'DEL_THREAD_STATUS', 'DEL_PRIORITY', 'DEL_DELEGATE_DATE', 'DEL_INIT_DATE', 'DEL_TASK_DUE_DATE', 'DEL_FINISH_DATE', 'DEL_DURATION', 'DEL_QUEUE_DURATION', 'DEL_DELAY_DURATION', 'DEL_STARTED', 'DEL_FINISHED', 'DEL_DELAYED', 'DEL_DATA', 'APP_OVERDUE_PERCENTAGE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'DelIndex' => 1, 'DelPrevious' => 2, 'ProUid' => 3, 'TasUid' => 4, 'UsrUid' => 5, 'DelType' => 6, 'DelThread' => 7, 'DelThreadStatus' => 8, 'DelPriority' => 9, 'DelDelegateDate' => 10, 'DelInitDate' => 11, 'DelTaskDueDate' => 12, 'DelFinishDate' => 13, 'DelDuration' => 14, 'DelQueueDuration' => 15, 'DelDelayDuration' => 16, 'DelStarted' => 17, 'DelFinished' => 18, 'DelDelayed' => 19, 'DelData' => 20, 'AppOverduePercentage' => 21, ), + BasePeer::TYPE_COLNAME => array (AppDelegationPeer::APP_UID => 0, AppDelegationPeer::DEL_INDEX => 1, AppDelegationPeer::DEL_PREVIOUS => 2, AppDelegationPeer::PRO_UID => 3, AppDelegationPeer::TAS_UID => 4, AppDelegationPeer::USR_UID => 5, AppDelegationPeer::DEL_TYPE => 6, AppDelegationPeer::DEL_THREAD => 7, AppDelegationPeer::DEL_THREAD_STATUS => 8, AppDelegationPeer::DEL_PRIORITY => 9, AppDelegationPeer::DEL_DELEGATE_DATE => 10, AppDelegationPeer::DEL_INIT_DATE => 11, AppDelegationPeer::DEL_TASK_DUE_DATE => 12, AppDelegationPeer::DEL_FINISH_DATE => 13, AppDelegationPeer::DEL_DURATION => 14, AppDelegationPeer::DEL_QUEUE_DURATION => 15, AppDelegationPeer::DEL_DELAY_DURATION => 16, AppDelegationPeer::DEL_STARTED => 17, AppDelegationPeer::DEL_FINISHED => 18, AppDelegationPeer::DEL_DELAYED => 19, AppDelegationPeer::DEL_DATA => 20, AppDelegationPeer::APP_OVERDUE_PERCENTAGE => 21, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'DEL_INDEX' => 1, 'DEL_PREVIOUS' => 2, 'PRO_UID' => 3, 'TAS_UID' => 4, 'USR_UID' => 5, 'DEL_TYPE' => 6, 'DEL_THREAD' => 7, 'DEL_THREAD_STATUS' => 8, 'DEL_PRIORITY' => 9, 'DEL_DELEGATE_DATE' => 10, 'DEL_INIT_DATE' => 11, 'DEL_TASK_DUE_DATE' => 12, 'DEL_FINISH_DATE' => 13, 'DEL_DURATION' => 14, 'DEL_QUEUE_DURATION' => 15, 'DEL_DELAY_DURATION' => 16, 'DEL_STARTED' => 17, 'DEL_FINISHED' => 18, 'DEL_DELAYED' => 19, 'DEL_DATA' => 20, 'APP_OVERDUE_PERCENTAGE' => 21, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppDelegationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppDelegationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppDelegationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppDelegationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppDelegationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppDelegationPeer::APP_UID); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_PREVIOUS); + + $criteria->addSelectColumn(AppDelegationPeer::PRO_UID); + + $criteria->addSelectColumn(AppDelegationPeer::TAS_UID); + + $criteria->addSelectColumn(AppDelegationPeer::USR_UID); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_TYPE); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_THREAD); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_THREAD_STATUS); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_PRIORITY); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_DELEGATE_DATE); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_DURATION); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_QUEUE_DURATION); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_DELAY_DURATION); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_STARTED); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_FINISHED); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_DELAYED); + + $criteria->addSelectColumn(AppDelegationPeer::DEL_DATA); + + $criteria->addSelectColumn(AppDelegationPeer::APP_OVERDUE_PERCENTAGE); + + } + + const COUNT = 'COUNT(APP_DELEGATION.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_DELEGATION.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppDelegationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppDelegationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppDelegationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppDelegation + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppDelegationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppDelegationPeer::populateObjects(AppDelegationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppDelegationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppDelegationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppDelegationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppDelegation or Criteria object. + * + * @param mixed $values Criteria or AppDelegation object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppDelegation object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppDelegation or Criteria object. + * + * @param mixed $values Criteria or AppDelegation object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppDelegationPeer::APP_UID); + $selectCriteria->add(AppDelegationPeer::APP_UID, $criteria->remove(AppDelegationPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(AppDelegationPeer::DEL_INDEX); + $selectCriteria->add(AppDelegationPeer::DEL_INDEX, $criteria->remove(AppDelegationPeer::DEL_INDEX), $comparison); + + } else { // $values is AppDelegation object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_DELEGATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppDelegationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppDelegation or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppDelegation object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppDelegationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppDelegation) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(AppDelegationPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppDelegationPeer::DEL_INDEX, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppDelegation object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppDelegation $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppDelegation $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppDelegationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppDelegationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(AppDelegationPeer::DEL_TYPE)) + $columns[AppDelegationPeer::DEL_TYPE] = $obj->getDelType(); + + if ($obj->isNew() || $obj->isColumnModified(AppDelegationPeer::DEL_PRIORITY)) + $columns[AppDelegationPeer::DEL_PRIORITY] = $obj->getDelPriority(); + + if ($obj->isNew() || $obj->isColumnModified(AppDelegationPeer::DEL_THREAD_STATUS)) + $columns[AppDelegationPeer::DEL_THREAD_STATUS] = $obj->getDelThreadStatus(); + + } + + return BasePeer::doValidate(AppDelegationPeer::DATABASE_NAME, AppDelegationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param int $del_index + + * @param Connection $con + * @return AppDelegation + */ + public static function retrieveByPK( $app_uid, $del_index, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppDelegationPeer::APP_UID, $app_uid); + $criteria->add(AppDelegationPeer::DEL_INDEX, $del_index); + $v = AppDelegationPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppDelegationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppDelegationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppDelegationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppDelegationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppDocument.php b/workflow/engine/classes/model/om/BaseAppDocument.php new file mode 100644 index 000000000..23814474f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDocument.php @@ -0,0 +1,1249 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppDocumentPeer.php'; + +/** + * Base class that represents a row from the 'APP_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDocument extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppDocumentPeer + */ + protected static $peer; + + + /** + * The value for the app_doc_uid field. + * @var string + */ + protected $app_doc_uid = ''; + + + /** + * The value for the doc_version field. + * @var int + */ + protected $doc_version = 1; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the doc_uid field. + * @var string + */ + protected $doc_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the app_doc_type field. + * @var string + */ + protected $app_doc_type = ''; + + + /** + * The value for the app_doc_create_date field. + * @var int + */ + protected $app_doc_create_date; + + + /** + * The value for the app_doc_index field. + * @var int + */ + protected $app_doc_index; + + + /** + * The value for the folder_uid field. + * @var string + */ + protected $folder_uid = ''; + + + /** + * The value for the app_doc_plugin field. + * @var string + */ + protected $app_doc_plugin = ''; + + + /** + * The value for the app_doc_tags field. + * @var string + */ + protected $app_doc_tags; + + + /** + * The value for the app_doc_status field. + * @var string + */ + protected $app_doc_status = 'ACTIVE'; + + + /** + * The value for the app_doc_status_date field. + * @var int + */ + protected $app_doc_status_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_doc_uid] column value. + * + * @return string + */ + public function getAppDocUid() + { + + return $this->app_doc_uid; + } + + /** + * Get the [doc_version] column value. + * + * @return int + */ + public function getDocVersion() + { + + return $this->doc_version; + } + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [doc_uid] column value. + * + * @return string + */ + public function getDocUid() + { + + return $this->doc_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [app_doc_type] column value. + * + * @return string + */ + public function getAppDocType() + { + + return $this->app_doc_type; + } + + /** + * Get the [optionally formatted] [app_doc_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppDocCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_doc_create_date === null || $this->app_doc_create_date === '') { + return null; + } elseif (!is_int($this->app_doc_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_doc_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_doc_create_date] as date/time value: " . var_export($this->app_doc_create_date, true)); + } + } else { + $ts = $this->app_doc_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_doc_index] column value. + * + * @return int + */ + public function getAppDocIndex() + { + + return $this->app_doc_index; + } + + /** + * Get the [folder_uid] column value. + * + * @return string + */ + public function getFolderUid() + { + + return $this->folder_uid; + } + + /** + * Get the [app_doc_plugin] column value. + * + * @return string + */ + public function getAppDocPlugin() + { + + return $this->app_doc_plugin; + } + + /** + * Get the [app_doc_tags] column value. + * + * @return string + */ + public function getAppDocTags() + { + + return $this->app_doc_tags; + } + + /** + * Get the [app_doc_status] column value. + * + * @return string + */ + public function getAppDocStatus() + { + + return $this->app_doc_status; + } + + /** + * Get the [optionally formatted] [app_doc_status_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppDocStatusDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_doc_status_date === null || $this->app_doc_status_date === '') { + return null; + } elseif (!is_int($this->app_doc_status_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_doc_status_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_doc_status_date] as date/time value: " . var_export($this->app_doc_status_date, true)); + } + } else { + $ts = $this->app_doc_status_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [app_doc_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppDocUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_doc_uid !== $v || $v === '') { + $this->app_doc_uid = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_UID; + } + + } // setAppDocUid() + + /** + * Set the value of [doc_version] column. + * + * @param int $v new value + * @return void + */ + public function setDocVersion($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->doc_version !== $v || $v === 1) { + $this->doc_version = $v; + $this->modifiedColumns[] = AppDocumentPeer::DOC_VERSION; + } + + } // setDocVersion() + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppDocumentPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [doc_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDocUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->doc_uid !== $v || $v === '') { + $this->doc_uid = $v; + $this->modifiedColumns[] = AppDocumentPeer::DOC_UID; + } + + } // setDocUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = AppDocumentPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [app_doc_type] column. + * + * @param string $v new value + * @return void + */ + public function setAppDocType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_doc_type !== $v || $v === '') { + $this->app_doc_type = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_TYPE; + } + + } // setAppDocType() + + /** + * Set the value of [app_doc_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppDocCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_doc_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_doc_create_date !== $ts) { + $this->app_doc_create_date = $ts; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_CREATE_DATE; + } + + } // setAppDocCreateDate() + + /** + * Set the value of [app_doc_index] column. + * + * @param int $v new value + * @return void + */ + public function setAppDocIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_doc_index !== $v) { + $this->app_doc_index = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_INDEX; + } + + } // setAppDocIndex() + + /** + * Set the value of [folder_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFolderUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->folder_uid !== $v || $v === '') { + $this->folder_uid = $v; + $this->modifiedColumns[] = AppDocumentPeer::FOLDER_UID; + } + + } // setFolderUid() + + /** + * Set the value of [app_doc_plugin] column. + * + * @param string $v new value + * @return void + */ + public function setAppDocPlugin($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_doc_plugin !== $v || $v === '') { + $this->app_doc_plugin = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_PLUGIN; + } + + } // setAppDocPlugin() + + /** + * Set the value of [app_doc_tags] column. + * + * @param string $v new value + * @return void + */ + public function setAppDocTags($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_doc_tags !== $v) { + $this->app_doc_tags = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_TAGS; + } + + } // setAppDocTags() + + /** + * Set the value of [app_doc_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppDocStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_doc_status !== $v || $v === 'ACTIVE') { + $this->app_doc_status = $v; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_STATUS; + } + + } // setAppDocStatus() + + /** + * Set the value of [app_doc_status_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppDocStatusDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_doc_status_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_doc_status_date !== $ts) { + $this->app_doc_status_date = $ts; + $this->modifiedColumns[] = AppDocumentPeer::APP_DOC_STATUS_DATE; + } + + } // setAppDocStatusDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_doc_uid = $rs->getString($startcol + 0); + + $this->doc_version = $rs->getInt($startcol + 1); + + $this->app_uid = $rs->getString($startcol + 2); + + $this->del_index = $rs->getInt($startcol + 3); + + $this->doc_uid = $rs->getString($startcol + 4); + + $this->usr_uid = $rs->getString($startcol + 5); + + $this->app_doc_type = $rs->getString($startcol + 6); + + $this->app_doc_create_date = $rs->getTimestamp($startcol + 7, null); + + $this->app_doc_index = $rs->getInt($startcol + 8); + + $this->folder_uid = $rs->getString($startcol + 9); + + $this->app_doc_plugin = $rs->getString($startcol + 10); + + $this->app_doc_tags = $rs->getString($startcol + 11); + + $this->app_doc_status = $rs->getString($startcol + 12); + + $this->app_doc_status_date = $rs->getTimestamp($startcol + 13, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 14; // 14 = AppDocumentPeer::NUM_COLUMNS - AppDocumentPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppDocument object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppDocumentPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppDocumentPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppDocumentPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppDocumentPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppDocUid(); + break; + case 1: + return $this->getDocVersion(); + break; + case 2: + return $this->getAppUid(); + break; + case 3: + return $this->getDelIndex(); + break; + case 4: + return $this->getDocUid(); + break; + case 5: + return $this->getUsrUid(); + break; + case 6: + return $this->getAppDocType(); + break; + case 7: + return $this->getAppDocCreateDate(); + break; + case 8: + return $this->getAppDocIndex(); + break; + case 9: + return $this->getFolderUid(); + break; + case 10: + return $this->getAppDocPlugin(); + break; + case 11: + return $this->getAppDocTags(); + break; + case 12: + return $this->getAppDocStatus(); + break; + case 13: + return $this->getAppDocStatusDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDocumentPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppDocUid(), + $keys[1] => $this->getDocVersion(), + $keys[2] => $this->getAppUid(), + $keys[3] => $this->getDelIndex(), + $keys[4] => $this->getDocUid(), + $keys[5] => $this->getUsrUid(), + $keys[6] => $this->getAppDocType(), + $keys[7] => $this->getAppDocCreateDate(), + $keys[8] => $this->getAppDocIndex(), + $keys[9] => $this->getFolderUid(), + $keys[10] => $this->getAppDocPlugin(), + $keys[11] => $this->getAppDocTags(), + $keys[12] => $this->getAppDocStatus(), + $keys[13] => $this->getAppDocStatusDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppDocUid($value); + break; + case 1: + $this->setDocVersion($value); + break; + case 2: + $this->setAppUid($value); + break; + case 3: + $this->setDelIndex($value); + break; + case 4: + $this->setDocUid($value); + break; + case 5: + $this->setUsrUid($value); + break; + case 6: + $this->setAppDocType($value); + break; + case 7: + $this->setAppDocCreateDate($value); + break; + case 8: + $this->setAppDocIndex($value); + break; + case 9: + $this->setFolderUid($value); + break; + case 10: + $this->setAppDocPlugin($value); + break; + case 11: + $this->setAppDocTags($value); + break; + case 12: + $this->setAppDocStatus($value); + break; + case 13: + $this->setAppDocStatusDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppDocumentPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppDocUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDocVersion($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDelIndex($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setDocUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUsrUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppDocType($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAppDocCreateDate($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAppDocIndex($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setFolderUid($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setAppDocPlugin($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setAppDocTags($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setAppDocStatus($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setAppDocStatusDate($arr[$keys[13]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppDocumentPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_UID)) $criteria->add(AppDocumentPeer::APP_DOC_UID, $this->app_doc_uid); + if ($this->isColumnModified(AppDocumentPeer::DOC_VERSION)) $criteria->add(AppDocumentPeer::DOC_VERSION, $this->doc_version); + if ($this->isColumnModified(AppDocumentPeer::APP_UID)) $criteria->add(AppDocumentPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppDocumentPeer::DEL_INDEX)) $criteria->add(AppDocumentPeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppDocumentPeer::DOC_UID)) $criteria->add(AppDocumentPeer::DOC_UID, $this->doc_uid); + if ($this->isColumnModified(AppDocumentPeer::USR_UID)) $criteria->add(AppDocumentPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_TYPE)) $criteria->add(AppDocumentPeer::APP_DOC_TYPE, $this->app_doc_type); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_CREATE_DATE)) $criteria->add(AppDocumentPeer::APP_DOC_CREATE_DATE, $this->app_doc_create_date); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_INDEX)) $criteria->add(AppDocumentPeer::APP_DOC_INDEX, $this->app_doc_index); + if ($this->isColumnModified(AppDocumentPeer::FOLDER_UID)) $criteria->add(AppDocumentPeer::FOLDER_UID, $this->folder_uid); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_PLUGIN)) $criteria->add(AppDocumentPeer::APP_DOC_PLUGIN, $this->app_doc_plugin); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_TAGS)) $criteria->add(AppDocumentPeer::APP_DOC_TAGS, $this->app_doc_tags); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_STATUS)) $criteria->add(AppDocumentPeer::APP_DOC_STATUS, $this->app_doc_status); + if ($this->isColumnModified(AppDocumentPeer::APP_DOC_STATUS_DATE)) $criteria->add(AppDocumentPeer::APP_DOC_STATUS_DATE, $this->app_doc_status_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppDocumentPeer::DATABASE_NAME); + + $criteria->add(AppDocumentPeer::APP_DOC_UID, $this->app_doc_uid); + $criteria->add(AppDocumentPeer::DOC_VERSION, $this->doc_version); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppDocUid(); + + $pks[1] = $this->getDocVersion(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppDocUid($keys[0]); + + $this->setDocVersion($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppDocument (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppUid($this->app_uid); + + $copyObj->setDelIndex($this->del_index); + + $copyObj->setDocUid($this->doc_uid); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setAppDocType($this->app_doc_type); + + $copyObj->setAppDocCreateDate($this->app_doc_create_date); + + $copyObj->setAppDocIndex($this->app_doc_index); + + $copyObj->setFolderUid($this->folder_uid); + + $copyObj->setAppDocPlugin($this->app_doc_plugin); + + $copyObj->setAppDocTags($this->app_doc_tags); + + $copyObj->setAppDocStatus($this->app_doc_status); + + $copyObj->setAppDocStatusDate($this->app_doc_status_date); + + + $copyObj->setNew(true); + + $copyObj->setAppDocUid(''); // this is a pkey column, so set to default value + + $copyObj->setDocVersion('1'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppDocument Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppDocumentPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppDocumentPeer(); + } + return self::$peer; + } + +} // BaseAppDocument diff --git a/workflow/engine/classes/model/om/BaseAppDocumentPeer.php b/workflow/engine/classes/model/om/BaseAppDocumentPeer.php new file mode 100644 index 000000000..43ceb03d8 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppDocumentPeer.php @@ -0,0 +1,645 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppDocumentPeer::getOMClass() +include_once 'classes/model/AppDocument.php'; + +/** + * Base static class for performing query and update operations on the 'APP_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppDocumentPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_DOCUMENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppDocument'; + + /** The total number of columns. */ + const NUM_COLUMNS = 14; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_DOC_UID field */ + const APP_DOC_UID = 'APP_DOCUMENT.APP_DOC_UID'; + + /** the column name for the DOC_VERSION field */ + const DOC_VERSION = 'APP_DOCUMENT.DOC_VERSION'; + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_DOCUMENT.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_DOCUMENT.DEL_INDEX'; + + /** the column name for the DOC_UID field */ + const DOC_UID = 'APP_DOCUMENT.DOC_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'APP_DOCUMENT.USR_UID'; + + /** the column name for the APP_DOC_TYPE field */ + const APP_DOC_TYPE = 'APP_DOCUMENT.APP_DOC_TYPE'; + + /** the column name for the APP_DOC_CREATE_DATE field */ + const APP_DOC_CREATE_DATE = 'APP_DOCUMENT.APP_DOC_CREATE_DATE'; + + /** the column name for the APP_DOC_INDEX field */ + const APP_DOC_INDEX = 'APP_DOCUMENT.APP_DOC_INDEX'; + + /** the column name for the FOLDER_UID field */ + const FOLDER_UID = 'APP_DOCUMENT.FOLDER_UID'; + + /** the column name for the APP_DOC_PLUGIN field */ + const APP_DOC_PLUGIN = 'APP_DOCUMENT.APP_DOC_PLUGIN'; + + /** the column name for the APP_DOC_TAGS field */ + const APP_DOC_TAGS = 'APP_DOCUMENT.APP_DOC_TAGS'; + + /** the column name for the APP_DOC_STATUS field */ + const APP_DOC_STATUS = 'APP_DOCUMENT.APP_DOC_STATUS'; + + /** the column name for the APP_DOC_STATUS_DATE field */ + const APP_DOC_STATUS_DATE = 'APP_DOCUMENT.APP_DOC_STATUS_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppDocUid', 'DocVersion', 'AppUid', 'DelIndex', 'DocUid', 'UsrUid', 'AppDocType', 'AppDocCreateDate', 'AppDocIndex', 'FolderUid', 'AppDocPlugin', 'AppDocTags', 'AppDocStatus', 'AppDocStatusDate', ), + BasePeer::TYPE_COLNAME => array (AppDocumentPeer::APP_DOC_UID, AppDocumentPeer::DOC_VERSION, AppDocumentPeer::APP_UID, AppDocumentPeer::DEL_INDEX, AppDocumentPeer::DOC_UID, AppDocumentPeer::USR_UID, AppDocumentPeer::APP_DOC_TYPE, AppDocumentPeer::APP_DOC_CREATE_DATE, AppDocumentPeer::APP_DOC_INDEX, AppDocumentPeer::FOLDER_UID, AppDocumentPeer::APP_DOC_PLUGIN, AppDocumentPeer::APP_DOC_TAGS, AppDocumentPeer::APP_DOC_STATUS, AppDocumentPeer::APP_DOC_STATUS_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_DOC_UID', 'DOC_VERSION', 'APP_UID', 'DEL_INDEX', 'DOC_UID', 'USR_UID', 'APP_DOC_TYPE', 'APP_DOC_CREATE_DATE', 'APP_DOC_INDEX', 'FOLDER_UID', 'APP_DOC_PLUGIN', 'APP_DOC_TAGS', 'APP_DOC_STATUS', 'APP_DOC_STATUS_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppDocUid' => 0, 'DocVersion' => 1, 'AppUid' => 2, 'DelIndex' => 3, 'DocUid' => 4, 'UsrUid' => 5, 'AppDocType' => 6, 'AppDocCreateDate' => 7, 'AppDocIndex' => 8, 'FolderUid' => 9, 'AppDocPlugin' => 10, 'AppDocTags' => 11, 'AppDocStatus' => 12, 'AppDocStatusDate' => 13, ), + BasePeer::TYPE_COLNAME => array (AppDocumentPeer::APP_DOC_UID => 0, AppDocumentPeer::DOC_VERSION => 1, AppDocumentPeer::APP_UID => 2, AppDocumentPeer::DEL_INDEX => 3, AppDocumentPeer::DOC_UID => 4, AppDocumentPeer::USR_UID => 5, AppDocumentPeer::APP_DOC_TYPE => 6, AppDocumentPeer::APP_DOC_CREATE_DATE => 7, AppDocumentPeer::APP_DOC_INDEX => 8, AppDocumentPeer::FOLDER_UID => 9, AppDocumentPeer::APP_DOC_PLUGIN => 10, AppDocumentPeer::APP_DOC_TAGS => 11, AppDocumentPeer::APP_DOC_STATUS => 12, AppDocumentPeer::APP_DOC_STATUS_DATE => 13, ), + BasePeer::TYPE_FIELDNAME => array ('APP_DOC_UID' => 0, 'DOC_VERSION' => 1, 'APP_UID' => 2, 'DEL_INDEX' => 3, 'DOC_UID' => 4, 'USR_UID' => 5, 'APP_DOC_TYPE' => 6, 'APP_DOC_CREATE_DATE' => 7, 'APP_DOC_INDEX' => 8, 'FOLDER_UID' => 9, 'APP_DOC_PLUGIN' => 10, 'APP_DOC_TAGS' => 11, 'APP_DOC_STATUS' => 12, 'APP_DOC_STATUS_DATE' => 13, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppDocumentMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppDocumentMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppDocumentPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppDocumentPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppDocumentPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_UID); + + $criteria->addSelectColumn(AppDocumentPeer::DOC_VERSION); + + $criteria->addSelectColumn(AppDocumentPeer::APP_UID); + + $criteria->addSelectColumn(AppDocumentPeer::DEL_INDEX); + + $criteria->addSelectColumn(AppDocumentPeer::DOC_UID); + + $criteria->addSelectColumn(AppDocumentPeer::USR_UID); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_TYPE); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_CREATE_DATE); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_INDEX); + + $criteria->addSelectColumn(AppDocumentPeer::FOLDER_UID); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_PLUGIN); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_TAGS); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_STATUS); + + $criteria->addSelectColumn(AppDocumentPeer::APP_DOC_STATUS_DATE); + + } + + const COUNT = 'COUNT(APP_DOCUMENT.APP_DOC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_DOCUMENT.APP_DOC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppDocumentPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppDocumentPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppDocumentPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppDocument + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppDocumentPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppDocumentPeer::populateObjects(AppDocumentPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppDocumentPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppDocumentPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppDocumentPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppDocument or Criteria object. + * + * @param mixed $values Criteria or AppDocument object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppDocument object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppDocument or Criteria object. + * + * @param mixed $values Criteria or AppDocument object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppDocumentPeer::APP_DOC_UID); + $selectCriteria->add(AppDocumentPeer::APP_DOC_UID, $criteria->remove(AppDocumentPeer::APP_DOC_UID), $comparison); + + $comparison = $criteria->getComparison(AppDocumentPeer::DOC_VERSION); + $selectCriteria->add(AppDocumentPeer::DOC_VERSION, $criteria->remove(AppDocumentPeer::DOC_VERSION), $comparison); + + } else { // $values is AppDocument object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_DOCUMENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppDocumentPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppDocument or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppDocument object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppDocumentPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppDocument) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(AppDocumentPeer::APP_DOC_UID, $vals[0], Criteria::IN); + $criteria->add(AppDocumentPeer::DOC_VERSION, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppDocument object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppDocument $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppDocument $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppDocumentPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppDocumentPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::APP_DOC_UID)) + $columns[AppDocumentPeer::APP_DOC_UID] = $obj->getAppDocUid(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::APP_UID)) + $columns[AppDocumentPeer::APP_UID] = $obj->getAppUid(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::DEL_INDEX)) + $columns[AppDocumentPeer::DEL_INDEX] = $obj->getDelIndex(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::DOC_UID)) + $columns[AppDocumentPeer::DOC_UID] = $obj->getDocUid(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::USR_UID)) + $columns[AppDocumentPeer::USR_UID] = $obj->getUsrUid(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::APP_DOC_TYPE)) + $columns[AppDocumentPeer::APP_DOC_TYPE] = $obj->getAppDocType(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::APP_DOC_CREATE_DATE)) + $columns[AppDocumentPeer::APP_DOC_CREATE_DATE] = $obj->getAppDocCreateDate(); + + if ($obj->isNew() || $obj->isColumnModified(AppDocumentPeer::APP_DOC_STATUS)) + $columns[AppDocumentPeer::APP_DOC_STATUS] = $obj->getAppDocStatus(); + + } + + return BasePeer::doValidate(AppDocumentPeer::DATABASE_NAME, AppDocumentPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_doc_uid + @param int $doc_version + + * @param Connection $con + * @return AppDocument + */ + public static function retrieveByPK( $app_doc_uid, $doc_version, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppDocumentPeer::APP_DOC_UID, $app_doc_uid); + $criteria->add(AppDocumentPeer::DOC_VERSION, $doc_version); + $v = AppDocumentPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppDocumentPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppDocumentPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppDocumentMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppDocumentMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppEvent.php b/workflow/engine/classes/model/om/BaseAppEvent.php new file mode 100644 index 000000000..5d29574bf --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppEvent.php @@ -0,0 +1,883 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppEventPeer.php'; + +/** + * Base class that represents a row from the 'APP_EVENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppEvent extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppEventPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the evn_uid field. + * @var string + */ + protected $evn_uid = ''; + + + /** + * The value for the app_evn_action_date field. + * @var int + */ + protected $app_evn_action_date; + + + /** + * The value for the app_evn_attempts field. + * @var int + */ + protected $app_evn_attempts = 0; + + + /** + * The value for the app_evn_last_execution_date field. + * @var int + */ + protected $app_evn_last_execution_date; + + + /** + * The value for the app_evn_status field. + * @var string + */ + protected $app_evn_status = 'OPEN'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [evn_uid] column value. + * + * @return string + */ + public function getEvnUid() + { + + return $this->evn_uid; + } + + /** + * Get the [optionally formatted] [app_evn_action_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppEvnActionDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_evn_action_date === null || $this->app_evn_action_date === '') { + return null; + } elseif (!is_int($this->app_evn_action_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_evn_action_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_evn_action_date] as date/time value: " . var_export($this->app_evn_action_date, true)); + } + } else { + $ts = $this->app_evn_action_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_evn_attempts] column value. + * + * @return int + */ + public function getAppEvnAttempts() + { + + return $this->app_evn_attempts; + } + + /** + * Get the [optionally formatted] [app_evn_last_execution_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppEvnLastExecutionDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_evn_last_execution_date === null || $this->app_evn_last_execution_date === '') { + return null; + } elseif (!is_int($this->app_evn_last_execution_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_evn_last_execution_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_evn_last_execution_date] as date/time value: " . var_export($this->app_evn_last_execution_date, true)); + } + } else { + $ts = $this->app_evn_last_execution_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_evn_status] column value. + * + * @return string + */ + public function getAppEvnStatus() + { + + return $this->app_evn_status; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppEventPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppEventPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [evn_uid] column. + * + * @param string $v new value + * @return void + */ + public function setEvnUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_uid !== $v || $v === '') { + $this->evn_uid = $v; + $this->modifiedColumns[] = AppEventPeer::EVN_UID; + } + + } // setEvnUid() + + /** + * Set the value of [app_evn_action_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppEvnActionDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_evn_action_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_evn_action_date !== $ts) { + $this->app_evn_action_date = $ts; + $this->modifiedColumns[] = AppEventPeer::APP_EVN_ACTION_DATE; + } + + } // setAppEvnActionDate() + + /** + * Set the value of [app_evn_attempts] column. + * + * @param int $v new value + * @return void + */ + public function setAppEvnAttempts($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_evn_attempts !== $v || $v === 0) { + $this->app_evn_attempts = $v; + $this->modifiedColumns[] = AppEventPeer::APP_EVN_ATTEMPTS; + } + + } // setAppEvnAttempts() + + /** + * Set the value of [app_evn_last_execution_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppEvnLastExecutionDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_evn_last_execution_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_evn_last_execution_date !== $ts) { + $this->app_evn_last_execution_date = $ts; + $this->modifiedColumns[] = AppEventPeer::APP_EVN_LAST_EXECUTION_DATE; + } + + } // setAppEvnLastExecutionDate() + + /** + * Set the value of [app_evn_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppEvnStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_evn_status !== $v || $v === 'OPEN') { + $this->app_evn_status = $v; + $this->modifiedColumns[] = AppEventPeer::APP_EVN_STATUS; + } + + } // setAppEvnStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->del_index = $rs->getInt($startcol + 1); + + $this->evn_uid = $rs->getString($startcol + 2); + + $this->app_evn_action_date = $rs->getTimestamp($startcol + 3, null); + + $this->app_evn_attempts = $rs->getInt($startcol + 4); + + $this->app_evn_last_execution_date = $rs->getTimestamp($startcol + 5, null); + + $this->app_evn_status = $rs->getString($startcol + 6); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = AppEventPeer::NUM_COLUMNS - AppEventPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppEvent object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppEventPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppEventPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppEventPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppEventPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppEventPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppEventPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppEventPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getDelIndex(); + break; + case 2: + return $this->getEvnUid(); + break; + case 3: + return $this->getAppEvnActionDate(); + break; + case 4: + return $this->getAppEvnAttempts(); + break; + case 5: + return $this->getAppEvnLastExecutionDate(); + break; + case 6: + return $this->getAppEvnStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppEventPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getDelIndex(), + $keys[2] => $this->getEvnUid(), + $keys[3] => $this->getAppEvnActionDate(), + $keys[4] => $this->getAppEvnAttempts(), + $keys[5] => $this->getAppEvnLastExecutionDate(), + $keys[6] => $this->getAppEvnStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppEventPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setDelIndex($value); + break; + case 2: + $this->setEvnUid($value); + break; + case 3: + $this->setAppEvnActionDate($value); + break; + case 4: + $this->setAppEvnAttempts($value); + break; + case 5: + $this->setAppEvnLastExecutionDate($value); + break; + case 6: + $this->setAppEvnStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppEventPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDelIndex($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setEvnUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAppEvnActionDate($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAppEvnAttempts($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppEvnLastExecutionDate($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppEvnStatus($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppEventPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppEventPeer::APP_UID)) $criteria->add(AppEventPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppEventPeer::DEL_INDEX)) $criteria->add(AppEventPeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppEventPeer::EVN_UID)) $criteria->add(AppEventPeer::EVN_UID, $this->evn_uid); + if ($this->isColumnModified(AppEventPeer::APP_EVN_ACTION_DATE)) $criteria->add(AppEventPeer::APP_EVN_ACTION_DATE, $this->app_evn_action_date); + if ($this->isColumnModified(AppEventPeer::APP_EVN_ATTEMPTS)) $criteria->add(AppEventPeer::APP_EVN_ATTEMPTS, $this->app_evn_attempts); + if ($this->isColumnModified(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE)) $criteria->add(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE, $this->app_evn_last_execution_date); + if ($this->isColumnModified(AppEventPeer::APP_EVN_STATUS)) $criteria->add(AppEventPeer::APP_EVN_STATUS, $this->app_evn_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppEventPeer::DATABASE_NAME); + + $criteria->add(AppEventPeer::APP_UID, $this->app_uid); + $criteria->add(AppEventPeer::DEL_INDEX, $this->del_index); + $criteria->add(AppEventPeer::EVN_UID, $this->evn_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getDelIndex(); + + $pks[2] = $this->getEvnUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setDelIndex($keys[1]); + + $this->setEvnUid($keys[2]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppEvent (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppEvnActionDate($this->app_evn_action_date); + + $copyObj->setAppEvnAttempts($this->app_evn_attempts); + + $copyObj->setAppEvnLastExecutionDate($this->app_evn_last_execution_date); + + $copyObj->setAppEvnStatus($this->app_evn_status); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setDelIndex('0'); // this is a pkey column, so set to default value + + $copyObj->setEvnUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppEvent Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppEventPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppEventPeer(); + } + return self::$peer; + } + +} // BaseAppEvent diff --git a/workflow/engine/classes/model/om/BaseAppEventPeer.php b/workflow/engine/classes/model/om/BaseAppEventPeer.php new file mode 100644 index 000000000..01fecf5ac --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppEventPeer.php @@ -0,0 +1,593 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppEventPeer::getOMClass() +include_once 'classes/model/AppEvent.php'; + +/** + * Base static class for performing query and update operations on the 'APP_EVENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppEventPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_EVENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppEvent'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_EVENT.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_EVENT.DEL_INDEX'; + + /** the column name for the EVN_UID field */ + const EVN_UID = 'APP_EVENT.EVN_UID'; + + /** the column name for the APP_EVN_ACTION_DATE field */ + const APP_EVN_ACTION_DATE = 'APP_EVENT.APP_EVN_ACTION_DATE'; + + /** the column name for the APP_EVN_ATTEMPTS field */ + const APP_EVN_ATTEMPTS = 'APP_EVENT.APP_EVN_ATTEMPTS'; + + /** the column name for the APP_EVN_LAST_EXECUTION_DATE field */ + const APP_EVN_LAST_EXECUTION_DATE = 'APP_EVENT.APP_EVN_LAST_EXECUTION_DATE'; + + /** the column name for the APP_EVN_STATUS field */ + const APP_EVN_STATUS = 'APP_EVENT.APP_EVN_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'DelIndex', 'EvnUid', 'AppEvnActionDate', 'AppEvnAttempts', 'AppEvnLastExecutionDate', 'AppEvnStatus', ), + BasePeer::TYPE_COLNAME => array (AppEventPeer::APP_UID, AppEventPeer::DEL_INDEX, AppEventPeer::EVN_UID, AppEventPeer::APP_EVN_ACTION_DATE, AppEventPeer::APP_EVN_ATTEMPTS, AppEventPeer::APP_EVN_LAST_EXECUTION_DATE, AppEventPeer::APP_EVN_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'DEL_INDEX', 'EVN_UID', 'APP_EVN_ACTION_DATE', 'APP_EVN_ATTEMPTS', 'APP_EVN_LAST_EXECUTION_DATE', 'APP_EVN_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'DelIndex' => 1, 'EvnUid' => 2, 'AppEvnActionDate' => 3, 'AppEvnAttempts' => 4, 'AppEvnLastExecutionDate' => 5, 'AppEvnStatus' => 6, ), + BasePeer::TYPE_COLNAME => array (AppEventPeer::APP_UID => 0, AppEventPeer::DEL_INDEX => 1, AppEventPeer::EVN_UID => 2, AppEventPeer::APP_EVN_ACTION_DATE => 3, AppEventPeer::APP_EVN_ATTEMPTS => 4, AppEventPeer::APP_EVN_LAST_EXECUTION_DATE => 5, AppEventPeer::APP_EVN_STATUS => 6, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'DEL_INDEX' => 1, 'EVN_UID' => 2, 'APP_EVN_ACTION_DATE' => 3, 'APP_EVN_ATTEMPTS' => 4, 'APP_EVN_LAST_EXECUTION_DATE' => 5, 'APP_EVN_STATUS' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppEventMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppEventMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppEventPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppEventPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppEventPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppEventPeer::APP_UID); + + $criteria->addSelectColumn(AppEventPeer::DEL_INDEX); + + $criteria->addSelectColumn(AppEventPeer::EVN_UID); + + $criteria->addSelectColumn(AppEventPeer::APP_EVN_ACTION_DATE); + + $criteria->addSelectColumn(AppEventPeer::APP_EVN_ATTEMPTS); + + $criteria->addSelectColumn(AppEventPeer::APP_EVN_LAST_EXECUTION_DATE); + + $criteria->addSelectColumn(AppEventPeer::APP_EVN_STATUS); + + } + + const COUNT = 'COUNT(APP_EVENT.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_EVENT.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppEventPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppEventPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppEventPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppEvent + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppEventPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppEventPeer::populateObjects(AppEventPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppEventPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppEventPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppEventPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppEvent or Criteria object. + * + * @param mixed $values Criteria or AppEvent object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppEvent object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppEvent or Criteria object. + * + * @param mixed $values Criteria or AppEvent object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppEventPeer::APP_UID); + $selectCriteria->add(AppEventPeer::APP_UID, $criteria->remove(AppEventPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(AppEventPeer::DEL_INDEX); + $selectCriteria->add(AppEventPeer::DEL_INDEX, $criteria->remove(AppEventPeer::DEL_INDEX), $comparison); + + $comparison = $criteria->getComparison(AppEventPeer::EVN_UID); + $selectCriteria->add(AppEventPeer::EVN_UID, $criteria->remove(AppEventPeer::EVN_UID), $comparison); + + } else { // $values is AppEvent object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_EVENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppEventPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppEvent or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppEvent object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppEventPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppEvent) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + } + + $criteria->add(AppEventPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppEventPeer::DEL_INDEX, $vals[1], Criteria::IN); + $criteria->add(AppEventPeer::EVN_UID, $vals[2], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppEvent object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppEvent $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppEvent $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppEventPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppEventPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppEventPeer::DATABASE_NAME, AppEventPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param int $del_index + @param string $evn_uid + + * @param Connection $con + * @return AppEvent + */ + public static function retrieveByPK( $app_uid, $del_index, $evn_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppEventPeer::APP_UID, $app_uid); + $criteria->add(AppEventPeer::DEL_INDEX, $del_index); + $criteria->add(AppEventPeer::EVN_UID, $evn_uid); + $v = AppEventPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppEventPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppEventPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppEventMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppEventMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppFolder.php b/workflow/engine/classes/model/om/BaseAppFolder.php new file mode 100644 index 000000000..88754f643 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppFolder.php @@ -0,0 +1,760 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppFolderPeer.php'; + +/** + * Base class that represents a row from the 'APP_FOLDER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppFolder extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppFolderPeer + */ + protected static $peer; + + + /** + * The value for the folder_uid field. + * @var string + */ + protected $folder_uid = ''; + + + /** + * The value for the folder_parent_uid field. + * @var string + */ + protected $folder_parent_uid = ''; + + + /** + * The value for the folder_name field. + * @var string + */ + protected $folder_name; + + + /** + * The value for the folder_create_date field. + * @var int + */ + protected $folder_create_date; + + + /** + * The value for the folder_update_date field. + * @var int + */ + protected $folder_update_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [folder_uid] column value. + * + * @return string + */ + public function getFolderUid() + { + + return $this->folder_uid; + } + + /** + * Get the [folder_parent_uid] column value. + * + * @return string + */ + public function getFolderParentUid() + { + + return $this->folder_parent_uid; + } + + /** + * Get the [folder_name] column value. + * + * @return string + */ + public function getFolderName() + { + + return $this->folder_name; + } + + /** + * Get the [optionally formatted] [folder_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getFolderCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->folder_create_date === null || $this->folder_create_date === '') { + return null; + } elseif (!is_int($this->folder_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->folder_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [folder_create_date] as date/time value: " . var_export($this->folder_create_date, true)); + } + } else { + $ts = $this->folder_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [folder_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getFolderUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->folder_update_date === null || $this->folder_update_date === '') { + return null; + } elseif (!is_int($this->folder_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->folder_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [folder_update_date] as date/time value: " . var_export($this->folder_update_date, true)); + } + } else { + $ts = $this->folder_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [folder_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFolderUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->folder_uid !== $v || $v === '') { + $this->folder_uid = $v; + $this->modifiedColumns[] = AppFolderPeer::FOLDER_UID; + } + + } // setFolderUid() + + /** + * Set the value of [folder_parent_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFolderParentUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->folder_parent_uid !== $v || $v === '') { + $this->folder_parent_uid = $v; + $this->modifiedColumns[] = AppFolderPeer::FOLDER_PARENT_UID; + } + + } // setFolderParentUid() + + /** + * Set the value of [folder_name] column. + * + * @param string $v new value + * @return void + */ + public function setFolderName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->folder_name !== $v) { + $this->folder_name = $v; + $this->modifiedColumns[] = AppFolderPeer::FOLDER_NAME; + } + + } // setFolderName() + + /** + * Set the value of [folder_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setFolderCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [folder_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->folder_create_date !== $ts) { + $this->folder_create_date = $ts; + $this->modifiedColumns[] = AppFolderPeer::FOLDER_CREATE_DATE; + } + + } // setFolderCreateDate() + + /** + * Set the value of [folder_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setFolderUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [folder_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->folder_update_date !== $ts) { + $this->folder_update_date = $ts; + $this->modifiedColumns[] = AppFolderPeer::FOLDER_UPDATE_DATE; + } + + } // setFolderUpdateDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->folder_uid = $rs->getString($startcol + 0); + + $this->folder_parent_uid = $rs->getString($startcol + 1); + + $this->folder_name = $rs->getString($startcol + 2); + + $this->folder_create_date = $rs->getTimestamp($startcol + 3, null); + + $this->folder_update_date = $rs->getTimestamp($startcol + 4, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = AppFolderPeer::NUM_COLUMNS - AppFolderPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppFolder object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppFolderPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppFolderPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppFolderPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppFolderPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppFolderPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppFolderPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppFolderPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getFolderUid(); + break; + case 1: + return $this->getFolderParentUid(); + break; + case 2: + return $this->getFolderName(); + break; + case 3: + return $this->getFolderCreateDate(); + break; + case 4: + return $this->getFolderUpdateDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppFolderPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getFolderUid(), + $keys[1] => $this->getFolderParentUid(), + $keys[2] => $this->getFolderName(), + $keys[3] => $this->getFolderCreateDate(), + $keys[4] => $this->getFolderUpdateDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppFolderPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setFolderUid($value); + break; + case 1: + $this->setFolderParentUid($value); + break; + case 2: + $this->setFolderName($value); + break; + case 3: + $this->setFolderCreateDate($value); + break; + case 4: + $this->setFolderUpdateDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppFolderPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setFolderUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setFolderParentUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFolderName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setFolderCreateDate($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setFolderUpdateDate($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppFolderPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppFolderPeer::FOLDER_UID)) $criteria->add(AppFolderPeer::FOLDER_UID, $this->folder_uid); + if ($this->isColumnModified(AppFolderPeer::FOLDER_PARENT_UID)) $criteria->add(AppFolderPeer::FOLDER_PARENT_UID, $this->folder_parent_uid); + if ($this->isColumnModified(AppFolderPeer::FOLDER_NAME)) $criteria->add(AppFolderPeer::FOLDER_NAME, $this->folder_name); + if ($this->isColumnModified(AppFolderPeer::FOLDER_CREATE_DATE)) $criteria->add(AppFolderPeer::FOLDER_CREATE_DATE, $this->folder_create_date); + if ($this->isColumnModified(AppFolderPeer::FOLDER_UPDATE_DATE)) $criteria->add(AppFolderPeer::FOLDER_UPDATE_DATE, $this->folder_update_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppFolderPeer::DATABASE_NAME); + + $criteria->add(AppFolderPeer::FOLDER_UID, $this->folder_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getFolderUid(); + } + + /** + * Generic method to set the primary key (folder_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setFolderUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppFolder (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setFolderParentUid($this->folder_parent_uid); + + $copyObj->setFolderName($this->folder_name); + + $copyObj->setFolderCreateDate($this->folder_create_date); + + $copyObj->setFolderUpdateDate($this->folder_update_date); + + + $copyObj->setNew(true); + + $copyObj->setFolderUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppFolder Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppFolderPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppFolderPeer(); + } + return self::$peer; + } + +} // BaseAppFolder diff --git a/workflow/engine/classes/model/om/BaseAppFolderPeer.php b/workflow/engine/classes/model/om/BaseAppFolderPeer.php new file mode 100644 index 000000000..d21852010 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppFolderPeer.php @@ -0,0 +1,585 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppFolderPeer::getOMClass() +include_once 'classes/model/AppFolder.php'; + +/** + * Base static class for performing query and update operations on the 'APP_FOLDER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppFolderPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_FOLDER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppFolder'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the FOLDER_UID field */ + const FOLDER_UID = 'APP_FOLDER.FOLDER_UID'; + + /** the column name for the FOLDER_PARENT_UID field */ + const FOLDER_PARENT_UID = 'APP_FOLDER.FOLDER_PARENT_UID'; + + /** the column name for the FOLDER_NAME field */ + const FOLDER_NAME = 'APP_FOLDER.FOLDER_NAME'; + + /** the column name for the FOLDER_CREATE_DATE field */ + const FOLDER_CREATE_DATE = 'APP_FOLDER.FOLDER_CREATE_DATE'; + + /** the column name for the FOLDER_UPDATE_DATE field */ + const FOLDER_UPDATE_DATE = 'APP_FOLDER.FOLDER_UPDATE_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('FolderUid', 'FolderParentUid', 'FolderName', 'FolderCreateDate', 'FolderUpdateDate', ), + BasePeer::TYPE_COLNAME => array (AppFolderPeer::FOLDER_UID, AppFolderPeer::FOLDER_PARENT_UID, AppFolderPeer::FOLDER_NAME, AppFolderPeer::FOLDER_CREATE_DATE, AppFolderPeer::FOLDER_UPDATE_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('FOLDER_UID', 'FOLDER_PARENT_UID', 'FOLDER_NAME', 'FOLDER_CREATE_DATE', 'FOLDER_UPDATE_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('FolderUid' => 0, 'FolderParentUid' => 1, 'FolderName' => 2, 'FolderCreateDate' => 3, 'FolderUpdateDate' => 4, ), + BasePeer::TYPE_COLNAME => array (AppFolderPeer::FOLDER_UID => 0, AppFolderPeer::FOLDER_PARENT_UID => 1, AppFolderPeer::FOLDER_NAME => 2, AppFolderPeer::FOLDER_CREATE_DATE => 3, AppFolderPeer::FOLDER_UPDATE_DATE => 4, ), + BasePeer::TYPE_FIELDNAME => array ('FOLDER_UID' => 0, 'FOLDER_PARENT_UID' => 1, 'FOLDER_NAME' => 2, 'FOLDER_CREATE_DATE' => 3, 'FOLDER_UPDATE_DATE' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppFolderMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppFolderMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppFolderPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppFolderPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppFolderPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppFolderPeer::FOLDER_UID); + + $criteria->addSelectColumn(AppFolderPeer::FOLDER_PARENT_UID); + + $criteria->addSelectColumn(AppFolderPeer::FOLDER_NAME); + + $criteria->addSelectColumn(AppFolderPeer::FOLDER_CREATE_DATE); + + $criteria->addSelectColumn(AppFolderPeer::FOLDER_UPDATE_DATE); + + } + + const COUNT = 'COUNT(APP_FOLDER.FOLDER_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_FOLDER.FOLDER_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppFolderPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppFolderPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppFolderPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppFolder + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppFolderPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppFolderPeer::populateObjects(AppFolderPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppFolderPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppFolderPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppFolderPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppFolder or Criteria object. + * + * @param mixed $values Criteria or AppFolder object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppFolder object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppFolder or Criteria object. + * + * @param mixed $values Criteria or AppFolder object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppFolderPeer::FOLDER_UID); + $selectCriteria->add(AppFolderPeer::FOLDER_UID, $criteria->remove(AppFolderPeer::FOLDER_UID), $comparison); + + } else { // $values is AppFolder object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_FOLDER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppFolderPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppFolder or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppFolder object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppFolderPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppFolder) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(AppFolderPeer::FOLDER_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppFolder object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppFolder $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppFolder $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppFolderPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppFolderPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppFolderPeer::DATABASE_NAME, AppFolderPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return AppFolder + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(AppFolderPeer::DATABASE_NAME); + + $criteria->add(AppFolderPeer::FOLDER_UID, $pk); + + + $v = AppFolderPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(AppFolderPeer::FOLDER_UID, $pks, Criteria::IN); + $objs = AppFolderPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseAppFolderPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppFolderPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppFolderMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppFolderMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppHistory.php b/workflow/engine/classes/model/om/BaseAppHistory.php new file mode 100644 index 000000000..377613635 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppHistory.php @@ -0,0 +1,953 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppHistoryPeer.php'; + +/** + * Base class that represents a row from the 'APP_HISTORY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppHistory extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppHistoryPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the dyn_uid field. + * @var string + */ + protected $dyn_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the app_status field. + * @var string + */ + protected $app_status = ''; + + + /** + * The value for the history_date field. + * @var int + */ + protected $history_date; + + + /** + * The value for the history_data field. + * @var string + */ + protected $history_data; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [dyn_uid] column value. + * + * @return string + */ + public function getDynUid() + { + + return $this->dyn_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [app_status] column value. + * + * @return string + */ + public function getAppStatus() + { + + return $this->app_status; + } + + /** + * Get the [optionally formatted] [history_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getHistoryDate($format = 'Y-m-d H:i:s') + { + + if ($this->history_date === null || $this->history_date === '') { + return null; + } elseif (!is_int($this->history_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->history_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [history_date] as date/time value: " . var_export($this->history_date, true)); + } + } else { + $ts = $this->history_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [history_data] column value. + * + * @return string + */ + public function getHistoryData() + { + + return $this->history_data; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppHistoryPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppHistoryPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = AppHistoryPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = AppHistoryPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [dyn_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDynUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_uid !== $v || $v === '') { + $this->dyn_uid = $v; + $this->modifiedColumns[] = AppHistoryPeer::DYN_UID; + } + + } // setDynUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = AppHistoryPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [app_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_status !== $v || $v === '') { + $this->app_status = $v; + $this->modifiedColumns[] = AppHistoryPeer::APP_STATUS; + } + + } // setAppStatus() + + /** + * Set the value of [history_date] column. + * + * @param int $v new value + * @return void + */ + public function setHistoryDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [history_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->history_date !== $ts) { + $this->history_date = $ts; + $this->modifiedColumns[] = AppHistoryPeer::HISTORY_DATE; + } + + } // setHistoryDate() + + /** + * Set the value of [history_data] column. + * + * @param string $v new value + * @return void + */ + public function setHistoryData($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->history_data !== $v) { + $this->history_data = $v; + $this->modifiedColumns[] = AppHistoryPeer::HISTORY_DATA; + } + + } // setHistoryData() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->del_index = $rs->getInt($startcol + 1); + + $this->pro_uid = $rs->getString($startcol + 2); + + $this->tas_uid = $rs->getString($startcol + 3); + + $this->dyn_uid = $rs->getString($startcol + 4); + + $this->usr_uid = $rs->getString($startcol + 5); + + $this->app_status = $rs->getString($startcol + 6); + + $this->history_date = $rs->getTimestamp($startcol + 7, null); + + $this->history_data = $rs->getString($startcol + 8); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 9; // 9 = AppHistoryPeer::NUM_COLUMNS - AppHistoryPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppHistory object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppHistoryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppHistoryPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppHistoryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppHistoryPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppHistoryPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppHistoryPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppHistoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getDelIndex(); + break; + case 2: + return $this->getProUid(); + break; + case 3: + return $this->getTasUid(); + break; + case 4: + return $this->getDynUid(); + break; + case 5: + return $this->getUsrUid(); + break; + case 6: + return $this->getAppStatus(); + break; + case 7: + return $this->getHistoryDate(); + break; + case 8: + return $this->getHistoryData(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppHistoryPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getDelIndex(), + $keys[2] => $this->getProUid(), + $keys[3] => $this->getTasUid(), + $keys[4] => $this->getDynUid(), + $keys[5] => $this->getUsrUid(), + $keys[6] => $this->getAppStatus(), + $keys[7] => $this->getHistoryDate(), + $keys[8] => $this->getHistoryData(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppHistoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setDelIndex($value); + break; + case 2: + $this->setProUid($value); + break; + case 3: + $this->setTasUid($value); + break; + case 4: + $this->setDynUid($value); + break; + case 5: + $this->setUsrUid($value); + break; + case 6: + $this->setAppStatus($value); + break; + case 7: + $this->setHistoryDate($value); + break; + case 8: + $this->setHistoryData($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppHistoryPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDelIndex($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setProUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTasUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setDynUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUsrUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppStatus($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setHistoryDate($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setHistoryData($arr[$keys[8]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppHistoryPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppHistoryPeer::APP_UID)) $criteria->add(AppHistoryPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppHistoryPeer::DEL_INDEX)) $criteria->add(AppHistoryPeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppHistoryPeer::PRO_UID)) $criteria->add(AppHistoryPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(AppHistoryPeer::TAS_UID)) $criteria->add(AppHistoryPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(AppHistoryPeer::DYN_UID)) $criteria->add(AppHistoryPeer::DYN_UID, $this->dyn_uid); + if ($this->isColumnModified(AppHistoryPeer::USR_UID)) $criteria->add(AppHistoryPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(AppHistoryPeer::APP_STATUS)) $criteria->add(AppHistoryPeer::APP_STATUS, $this->app_status); + if ($this->isColumnModified(AppHistoryPeer::HISTORY_DATE)) $criteria->add(AppHistoryPeer::HISTORY_DATE, $this->history_date); + if ($this->isColumnModified(AppHistoryPeer::HISTORY_DATA)) $criteria->add(AppHistoryPeer::HISTORY_DATA, $this->history_data); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppHistoryPeer::DATABASE_NAME); + + + return $criteria; + } + + /** + * Returns NULL since this table doesn't have a primary key. + * This method exists only for BC and is deprecated! + * @return null + */ + public function getPrimaryKey() + { + return null; + } + + /** + * Dummy primary key setter. + * + * This function only exists to preserve backwards compatibility. It is no longer + * needed or required by the Persistent interface. It will be removed in next BC-breaking + * release of Propel. + * + * @deprecated + */ + public function setPrimaryKey($pk) + { + // do nothing, because this object doesn't have any primary keys + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppHistory (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppUid($this->app_uid); + + $copyObj->setDelIndex($this->del_index); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setDynUid($this->dyn_uid); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setAppStatus($this->app_status); + + $copyObj->setHistoryDate($this->history_date); + + $copyObj->setHistoryData($this->history_data); + + + $copyObj->setNew(true); + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppHistory Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppHistoryPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppHistoryPeer(); + } + return self::$peer; + } + +} // BaseAppHistory diff --git a/workflow/engine/classes/model/om/BaseAppHistoryPeer.php b/workflow/engine/classes/model/om/BaseAppHistoryPeer.php new file mode 100644 index 000000000..ae8077936 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppHistoryPeer.php @@ -0,0 +1,567 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppHistoryPeer::getOMClass() +include_once 'classes/model/AppHistory.php'; + +/** + * Base static class for performing query and update operations on the 'APP_HISTORY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppHistoryPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_HISTORY'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppHistory'; + + /** The total number of columns. */ + const NUM_COLUMNS = 9; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_HISTORY.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_HISTORY.DEL_INDEX'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'APP_HISTORY.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'APP_HISTORY.TAS_UID'; + + /** the column name for the DYN_UID field */ + const DYN_UID = 'APP_HISTORY.DYN_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'APP_HISTORY.USR_UID'; + + /** the column name for the APP_STATUS field */ + const APP_STATUS = 'APP_HISTORY.APP_STATUS'; + + /** the column name for the HISTORY_DATE field */ + const HISTORY_DATE = 'APP_HISTORY.HISTORY_DATE'; + + /** the column name for the HISTORY_DATA field */ + const HISTORY_DATA = 'APP_HISTORY.HISTORY_DATA'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'DelIndex', 'ProUid', 'TasUid', 'DynUid', 'UsrUid', 'AppStatus', 'HistoryDate', 'HistoryData', ), + BasePeer::TYPE_COLNAME => array (AppHistoryPeer::APP_UID, AppHistoryPeer::DEL_INDEX, AppHistoryPeer::PRO_UID, AppHistoryPeer::TAS_UID, AppHistoryPeer::DYN_UID, AppHistoryPeer::USR_UID, AppHistoryPeer::APP_STATUS, AppHistoryPeer::HISTORY_DATE, AppHistoryPeer::HISTORY_DATA, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'DEL_INDEX', 'PRO_UID', 'TAS_UID', 'DYN_UID', 'USR_UID', 'APP_STATUS', 'HISTORY_DATE', 'HISTORY_DATA', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'DelIndex' => 1, 'ProUid' => 2, 'TasUid' => 3, 'DynUid' => 4, 'UsrUid' => 5, 'AppStatus' => 6, 'HistoryDate' => 7, 'HistoryData' => 8, ), + BasePeer::TYPE_COLNAME => array (AppHistoryPeer::APP_UID => 0, AppHistoryPeer::DEL_INDEX => 1, AppHistoryPeer::PRO_UID => 2, AppHistoryPeer::TAS_UID => 3, AppHistoryPeer::DYN_UID => 4, AppHistoryPeer::USR_UID => 5, AppHistoryPeer::APP_STATUS => 6, AppHistoryPeer::HISTORY_DATE => 7, AppHistoryPeer::HISTORY_DATA => 8, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'DEL_INDEX' => 1, 'PRO_UID' => 2, 'TAS_UID' => 3, 'DYN_UID' => 4, 'USR_UID' => 5, 'APP_STATUS' => 6, 'HISTORY_DATE' => 7, 'HISTORY_DATA' => 8, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppHistoryMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppHistoryMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppHistoryPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppHistoryPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppHistoryPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppHistoryPeer::APP_UID); + + $criteria->addSelectColumn(AppHistoryPeer::DEL_INDEX); + + $criteria->addSelectColumn(AppHistoryPeer::PRO_UID); + + $criteria->addSelectColumn(AppHistoryPeer::TAS_UID); + + $criteria->addSelectColumn(AppHistoryPeer::DYN_UID); + + $criteria->addSelectColumn(AppHistoryPeer::USR_UID); + + $criteria->addSelectColumn(AppHistoryPeer::APP_STATUS); + + $criteria->addSelectColumn(AppHistoryPeer::HISTORY_DATE); + + $criteria->addSelectColumn(AppHistoryPeer::HISTORY_DATA); + + } + + const COUNT = 'COUNT(*)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT *)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppHistoryPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppHistoryPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppHistoryPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppHistory + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppHistoryPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppHistoryPeer::populateObjects(AppHistoryPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppHistoryPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppHistoryPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppHistoryPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppHistory or Criteria object. + * + * @param mixed $values Criteria or AppHistory object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppHistory object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppHistory or Criteria object. + * + * @param mixed $values Criteria or AppHistory object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + } else { // $values is AppHistory object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_HISTORY table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppHistoryPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppHistory or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppHistory object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppHistoryPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppHistory) { + + $criteria = $values->buildCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + } + + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppHistory object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppHistory $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppHistory $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppHistoryPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppHistoryPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppHistoryPeer::DATABASE_NAME, AppHistoryPeer::TABLE_NAME, $columns); + } + +} // BaseAppHistoryPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppHistoryPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppHistoryMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppHistoryMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppMessage.php b/workflow/engine/classes/model/om/BaseAppMessage.php new file mode 100644 index 000000000..f4f527086 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppMessage.php @@ -0,0 +1,1343 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppMessagePeer.php'; + +/** + * Base class that represents a row from the 'APP_MESSAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppMessage extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppMessagePeer + */ + protected static $peer; + + + /** + * The value for the app_msg_uid field. + * @var string + */ + protected $app_msg_uid; + + + /** + * The value for the msg_uid field. + * @var string + */ + protected $msg_uid; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + + /** + * The value for the app_msg_type field. + * @var string + */ + protected $app_msg_type = ''; + + + /** + * The value for the app_msg_subject field. + * @var string + */ + protected $app_msg_subject = ''; + + + /** + * The value for the app_msg_from field. + * @var string + */ + protected $app_msg_from = ''; + + + /** + * The value for the app_msg_to field. + * @var string + */ + protected $app_msg_to; + + + /** + * The value for the app_msg_body field. + * @var string + */ + protected $app_msg_body; + + + /** + * The value for the app_msg_date field. + * @var int + */ + protected $app_msg_date; + + + /** + * The value for the app_msg_cc field. + * @var string + */ + protected $app_msg_cc; + + + /** + * The value for the app_msg_bcc field. + * @var string + */ + protected $app_msg_bcc; + + + /** + * The value for the app_msg_template field. + * @var string + */ + protected $app_msg_template; + + + /** + * The value for the app_msg_status field. + * @var string + */ + protected $app_msg_status; + + + /** + * The value for the app_msg_attach field. + * @var string + */ + protected $app_msg_attach; + + + /** + * The value for the app_msg_send_date field. + * @var int + */ + protected $app_msg_send_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_msg_uid] column value. + * + * @return string + */ + public function getAppMsgUid() + { + + return $this->app_msg_uid; + } + + /** + * Get the [msg_uid] column value. + * + * @return string + */ + public function getMsgUid() + { + + return $this->msg_uid; + } + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Get the [app_msg_type] column value. + * + * @return string + */ + public function getAppMsgType() + { + + return $this->app_msg_type; + } + + /** + * Get the [app_msg_subject] column value. + * + * @return string + */ + public function getAppMsgSubject() + { + + return $this->app_msg_subject; + } + + /** + * Get the [app_msg_from] column value. + * + * @return string + */ + public function getAppMsgFrom() + { + + return $this->app_msg_from; + } + + /** + * Get the [app_msg_to] column value. + * + * @return string + */ + public function getAppMsgTo() + { + + return $this->app_msg_to; + } + + /** + * Get the [app_msg_body] column value. + * + * @return string + */ + public function getAppMsgBody() + { + + return $this->app_msg_body; + } + + /** + * Get the [optionally formatted] [app_msg_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppMsgDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_msg_date === null || $this->app_msg_date === '') { + return null; + } elseif (!is_int($this->app_msg_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_msg_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_msg_date] as date/time value: " . var_export($this->app_msg_date, true)); + } + } else { + $ts = $this->app_msg_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_msg_cc] column value. + * + * @return string + */ + public function getAppMsgCc() + { + + return $this->app_msg_cc; + } + + /** + * Get the [app_msg_bcc] column value. + * + * @return string + */ + public function getAppMsgBcc() + { + + return $this->app_msg_bcc; + } + + /** + * Get the [app_msg_template] column value. + * + * @return string + */ + public function getAppMsgTemplate() + { + + return $this->app_msg_template; + } + + /** + * Get the [app_msg_status] column value. + * + * @return string + */ + public function getAppMsgStatus() + { + + return $this->app_msg_status; + } + + /** + * Get the [app_msg_attach] column value. + * + * @return string + */ + public function getAppMsgAttach() + { + + return $this->app_msg_attach; + } + + /** + * Get the [optionally formatted] [app_msg_send_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppMsgSendDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_msg_send_date === null || $this->app_msg_send_date === '') { + return null; + } elseif (!is_int($this->app_msg_send_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_msg_send_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_msg_send_date] as date/time value: " . var_export($this->app_msg_send_date, true)); + } + } else { + $ts = $this->app_msg_send_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [app_msg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_uid !== $v) { + $this->app_msg_uid = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_UID; + } + + } // setAppMsgUid() + + /** + * Set the value of [msg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setMsgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->msg_uid !== $v) { + $this->msg_uid = $v; + $this->modifiedColumns[] = AppMessagePeer::MSG_UID; + } + + } // setMsgUid() + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppMessagePeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Set the value of [app_msg_type] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_type !== $v || $v === '') { + $this->app_msg_type = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_TYPE; + } + + } // setAppMsgType() + + /** + * Set the value of [app_msg_subject] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgSubject($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_subject !== $v || $v === '') { + $this->app_msg_subject = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_SUBJECT; + } + + } // setAppMsgSubject() + + /** + * Set the value of [app_msg_from] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgFrom($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_from !== $v || $v === '') { + $this->app_msg_from = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_FROM; + } + + } // setAppMsgFrom() + + /** + * Set the value of [app_msg_to] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgTo($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_to !== $v) { + $this->app_msg_to = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_TO; + } + + } // setAppMsgTo() + + /** + * Set the value of [app_msg_body] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgBody($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_body !== $v) { + $this->app_msg_body = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_BODY; + } + + } // setAppMsgBody() + + /** + * Set the value of [app_msg_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppMsgDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_msg_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_msg_date !== $ts) { + $this->app_msg_date = $ts; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_DATE; + } + + } // setAppMsgDate() + + /** + * Set the value of [app_msg_cc] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgCc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_cc !== $v) { + $this->app_msg_cc = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_CC; + } + + } // setAppMsgCc() + + /** + * Set the value of [app_msg_bcc] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgBcc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_bcc !== $v) { + $this->app_msg_bcc = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_BCC; + } + + } // setAppMsgBcc() + + /** + * Set the value of [app_msg_template] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgTemplate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_template !== $v) { + $this->app_msg_template = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_TEMPLATE; + } + + } // setAppMsgTemplate() + + /** + * Set the value of [app_msg_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_status !== $v) { + $this->app_msg_status = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_STATUS; + } + + } // setAppMsgStatus() + + /** + * Set the value of [app_msg_attach] column. + * + * @param string $v new value + * @return void + */ + public function setAppMsgAttach($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_msg_attach !== $v) { + $this->app_msg_attach = $v; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_ATTACH; + } + + } // setAppMsgAttach() + + /** + * Set the value of [app_msg_send_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppMsgSendDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_msg_send_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_msg_send_date !== $ts) { + $this->app_msg_send_date = $ts; + $this->modifiedColumns[] = AppMessagePeer::APP_MSG_SEND_DATE; + } + + } // setAppMsgSendDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_msg_uid = $rs->getString($startcol + 0); + + $this->msg_uid = $rs->getString($startcol + 1); + + $this->app_uid = $rs->getString($startcol + 2); + + $this->del_index = $rs->getInt($startcol + 3); + + $this->app_msg_type = $rs->getString($startcol + 4); + + $this->app_msg_subject = $rs->getString($startcol + 5); + + $this->app_msg_from = $rs->getString($startcol + 6); + + $this->app_msg_to = $rs->getString($startcol + 7); + + $this->app_msg_body = $rs->getString($startcol + 8); + + $this->app_msg_date = $rs->getTimestamp($startcol + 9, null); + + $this->app_msg_cc = $rs->getString($startcol + 10); + + $this->app_msg_bcc = $rs->getString($startcol + 11); + + $this->app_msg_template = $rs->getString($startcol + 12); + + $this->app_msg_status = $rs->getString($startcol + 13); + + $this->app_msg_attach = $rs->getString($startcol + 14); + + $this->app_msg_send_date = $rs->getTimestamp($startcol + 15, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 16; // 16 = AppMessagePeer::NUM_COLUMNS - AppMessagePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppMessage object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppMessagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppMessagePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppMessagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppMessagePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppMessagePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppMessagePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppMessagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppMsgUid(); + break; + case 1: + return $this->getMsgUid(); + break; + case 2: + return $this->getAppUid(); + break; + case 3: + return $this->getDelIndex(); + break; + case 4: + return $this->getAppMsgType(); + break; + case 5: + return $this->getAppMsgSubject(); + break; + case 6: + return $this->getAppMsgFrom(); + break; + case 7: + return $this->getAppMsgTo(); + break; + case 8: + return $this->getAppMsgBody(); + break; + case 9: + return $this->getAppMsgDate(); + break; + case 10: + return $this->getAppMsgCc(); + break; + case 11: + return $this->getAppMsgBcc(); + break; + case 12: + return $this->getAppMsgTemplate(); + break; + case 13: + return $this->getAppMsgStatus(); + break; + case 14: + return $this->getAppMsgAttach(); + break; + case 15: + return $this->getAppMsgSendDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppMessagePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppMsgUid(), + $keys[1] => $this->getMsgUid(), + $keys[2] => $this->getAppUid(), + $keys[3] => $this->getDelIndex(), + $keys[4] => $this->getAppMsgType(), + $keys[5] => $this->getAppMsgSubject(), + $keys[6] => $this->getAppMsgFrom(), + $keys[7] => $this->getAppMsgTo(), + $keys[8] => $this->getAppMsgBody(), + $keys[9] => $this->getAppMsgDate(), + $keys[10] => $this->getAppMsgCc(), + $keys[11] => $this->getAppMsgBcc(), + $keys[12] => $this->getAppMsgTemplate(), + $keys[13] => $this->getAppMsgStatus(), + $keys[14] => $this->getAppMsgAttach(), + $keys[15] => $this->getAppMsgSendDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppMessagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppMsgUid($value); + break; + case 1: + $this->setMsgUid($value); + break; + case 2: + $this->setAppUid($value); + break; + case 3: + $this->setDelIndex($value); + break; + case 4: + $this->setAppMsgType($value); + break; + case 5: + $this->setAppMsgSubject($value); + break; + case 6: + $this->setAppMsgFrom($value); + break; + case 7: + $this->setAppMsgTo($value); + break; + case 8: + $this->setAppMsgBody($value); + break; + case 9: + $this->setAppMsgDate($value); + break; + case 10: + $this->setAppMsgCc($value); + break; + case 11: + $this->setAppMsgBcc($value); + break; + case 12: + $this->setAppMsgTemplate($value); + break; + case 13: + $this->setAppMsgStatus($value); + break; + case 14: + $this->setAppMsgAttach($value); + break; + case 15: + $this->setAppMsgSendDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppMessagePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppMsgUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setMsgUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDelIndex($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAppMsgType($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppMsgSubject($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppMsgFrom($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAppMsgTo($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAppMsgBody($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAppMsgDate($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setAppMsgCc($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setAppMsgBcc($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setAppMsgTemplate($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setAppMsgStatus($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setAppMsgAttach($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setAppMsgSendDate($arr[$keys[15]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppMessagePeer::DATABASE_NAME); + + if ($this->isColumnModified(AppMessagePeer::APP_MSG_UID)) $criteria->add(AppMessagePeer::APP_MSG_UID, $this->app_msg_uid); + if ($this->isColumnModified(AppMessagePeer::MSG_UID)) $criteria->add(AppMessagePeer::MSG_UID, $this->msg_uid); + if ($this->isColumnModified(AppMessagePeer::APP_UID)) $criteria->add(AppMessagePeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppMessagePeer::DEL_INDEX)) $criteria->add(AppMessagePeer::DEL_INDEX, $this->del_index); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_TYPE)) $criteria->add(AppMessagePeer::APP_MSG_TYPE, $this->app_msg_type); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_SUBJECT)) $criteria->add(AppMessagePeer::APP_MSG_SUBJECT, $this->app_msg_subject); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_FROM)) $criteria->add(AppMessagePeer::APP_MSG_FROM, $this->app_msg_from); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_TO)) $criteria->add(AppMessagePeer::APP_MSG_TO, $this->app_msg_to); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_BODY)) $criteria->add(AppMessagePeer::APP_MSG_BODY, $this->app_msg_body); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_DATE)) $criteria->add(AppMessagePeer::APP_MSG_DATE, $this->app_msg_date); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_CC)) $criteria->add(AppMessagePeer::APP_MSG_CC, $this->app_msg_cc); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_BCC)) $criteria->add(AppMessagePeer::APP_MSG_BCC, $this->app_msg_bcc); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_TEMPLATE)) $criteria->add(AppMessagePeer::APP_MSG_TEMPLATE, $this->app_msg_template); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_STATUS)) $criteria->add(AppMessagePeer::APP_MSG_STATUS, $this->app_msg_status); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_ATTACH)) $criteria->add(AppMessagePeer::APP_MSG_ATTACH, $this->app_msg_attach); + if ($this->isColumnModified(AppMessagePeer::APP_MSG_SEND_DATE)) $criteria->add(AppMessagePeer::APP_MSG_SEND_DATE, $this->app_msg_send_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppMessagePeer::DATABASE_NAME); + + $criteria->add(AppMessagePeer::APP_MSG_UID, $this->app_msg_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getAppMsgUid(); + } + + /** + * Generic method to set the primary key (app_msg_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setAppMsgUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppMessage (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setMsgUid($this->msg_uid); + + $copyObj->setAppUid($this->app_uid); + + $copyObj->setDelIndex($this->del_index); + + $copyObj->setAppMsgType($this->app_msg_type); + + $copyObj->setAppMsgSubject($this->app_msg_subject); + + $copyObj->setAppMsgFrom($this->app_msg_from); + + $copyObj->setAppMsgTo($this->app_msg_to); + + $copyObj->setAppMsgBody($this->app_msg_body); + + $copyObj->setAppMsgDate($this->app_msg_date); + + $copyObj->setAppMsgCc($this->app_msg_cc); + + $copyObj->setAppMsgBcc($this->app_msg_bcc); + + $copyObj->setAppMsgTemplate($this->app_msg_template); + + $copyObj->setAppMsgStatus($this->app_msg_status); + + $copyObj->setAppMsgAttach($this->app_msg_attach); + + $copyObj->setAppMsgSendDate($this->app_msg_send_date); + + + $copyObj->setNew(true); + + $copyObj->setAppMsgUid(NULL); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppMessage Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppMessagePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppMessagePeer(); + } + return self::$peer; + } + +} // BaseAppMessage diff --git a/workflow/engine/classes/model/om/BaseAppMessagePeer.php b/workflow/engine/classes/model/om/BaseAppMessagePeer.php new file mode 100644 index 000000000..300ee2af4 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppMessagePeer.php @@ -0,0 +1,640 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppMessagePeer::getOMClass() +include_once 'classes/model/AppMessage.php'; + +/** + * Base static class for performing query and update operations on the 'APP_MESSAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppMessagePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_MESSAGE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppMessage'; + + /** The total number of columns. */ + const NUM_COLUMNS = 16; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_MSG_UID field */ + const APP_MSG_UID = 'APP_MESSAGE.APP_MSG_UID'; + + /** the column name for the MSG_UID field */ + const MSG_UID = 'APP_MESSAGE.MSG_UID'; + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_MESSAGE.APP_UID'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_MESSAGE.DEL_INDEX'; + + /** the column name for the APP_MSG_TYPE field */ + const APP_MSG_TYPE = 'APP_MESSAGE.APP_MSG_TYPE'; + + /** the column name for the APP_MSG_SUBJECT field */ + const APP_MSG_SUBJECT = 'APP_MESSAGE.APP_MSG_SUBJECT'; + + /** the column name for the APP_MSG_FROM field */ + const APP_MSG_FROM = 'APP_MESSAGE.APP_MSG_FROM'; + + /** the column name for the APP_MSG_TO field */ + const APP_MSG_TO = 'APP_MESSAGE.APP_MSG_TO'; + + /** the column name for the APP_MSG_BODY field */ + const APP_MSG_BODY = 'APP_MESSAGE.APP_MSG_BODY'; + + /** the column name for the APP_MSG_DATE field */ + const APP_MSG_DATE = 'APP_MESSAGE.APP_MSG_DATE'; + + /** the column name for the APP_MSG_CC field */ + const APP_MSG_CC = 'APP_MESSAGE.APP_MSG_CC'; + + /** the column name for the APP_MSG_BCC field */ + const APP_MSG_BCC = 'APP_MESSAGE.APP_MSG_BCC'; + + /** the column name for the APP_MSG_TEMPLATE field */ + const APP_MSG_TEMPLATE = 'APP_MESSAGE.APP_MSG_TEMPLATE'; + + /** the column name for the APP_MSG_STATUS field */ + const APP_MSG_STATUS = 'APP_MESSAGE.APP_MSG_STATUS'; + + /** the column name for the APP_MSG_ATTACH field */ + const APP_MSG_ATTACH = 'APP_MESSAGE.APP_MSG_ATTACH'; + + /** the column name for the APP_MSG_SEND_DATE field */ + const APP_MSG_SEND_DATE = 'APP_MESSAGE.APP_MSG_SEND_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppMsgUid', 'MsgUid', 'AppUid', 'DelIndex', 'AppMsgType', 'AppMsgSubject', 'AppMsgFrom', 'AppMsgTo', 'AppMsgBody', 'AppMsgDate', 'AppMsgCc', 'AppMsgBcc', 'AppMsgTemplate', 'AppMsgStatus', 'AppMsgAttach', 'AppMsgSendDate', ), + BasePeer::TYPE_COLNAME => array (AppMessagePeer::APP_MSG_UID, AppMessagePeer::MSG_UID, AppMessagePeer::APP_UID, AppMessagePeer::DEL_INDEX, AppMessagePeer::APP_MSG_TYPE, AppMessagePeer::APP_MSG_SUBJECT, AppMessagePeer::APP_MSG_FROM, AppMessagePeer::APP_MSG_TO, AppMessagePeer::APP_MSG_BODY, AppMessagePeer::APP_MSG_DATE, AppMessagePeer::APP_MSG_CC, AppMessagePeer::APP_MSG_BCC, AppMessagePeer::APP_MSG_TEMPLATE, AppMessagePeer::APP_MSG_STATUS, AppMessagePeer::APP_MSG_ATTACH, AppMessagePeer::APP_MSG_SEND_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_MSG_UID', 'MSG_UID', 'APP_UID', 'DEL_INDEX', 'APP_MSG_TYPE', 'APP_MSG_SUBJECT', 'APP_MSG_FROM', 'APP_MSG_TO', 'APP_MSG_BODY', 'APP_MSG_DATE', 'APP_MSG_CC', 'APP_MSG_BCC', 'APP_MSG_TEMPLATE', 'APP_MSG_STATUS', 'APP_MSG_ATTACH', 'APP_MSG_SEND_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppMsgUid' => 0, 'MsgUid' => 1, 'AppUid' => 2, 'DelIndex' => 3, 'AppMsgType' => 4, 'AppMsgSubject' => 5, 'AppMsgFrom' => 6, 'AppMsgTo' => 7, 'AppMsgBody' => 8, 'AppMsgDate' => 9, 'AppMsgCc' => 10, 'AppMsgBcc' => 11, 'AppMsgTemplate' => 12, 'AppMsgStatus' => 13, 'AppMsgAttach' => 14, 'AppMsgSendDate' => 15, ), + BasePeer::TYPE_COLNAME => array (AppMessagePeer::APP_MSG_UID => 0, AppMessagePeer::MSG_UID => 1, AppMessagePeer::APP_UID => 2, AppMessagePeer::DEL_INDEX => 3, AppMessagePeer::APP_MSG_TYPE => 4, AppMessagePeer::APP_MSG_SUBJECT => 5, AppMessagePeer::APP_MSG_FROM => 6, AppMessagePeer::APP_MSG_TO => 7, AppMessagePeer::APP_MSG_BODY => 8, AppMessagePeer::APP_MSG_DATE => 9, AppMessagePeer::APP_MSG_CC => 10, AppMessagePeer::APP_MSG_BCC => 11, AppMessagePeer::APP_MSG_TEMPLATE => 12, AppMessagePeer::APP_MSG_STATUS => 13, AppMessagePeer::APP_MSG_ATTACH => 14, AppMessagePeer::APP_MSG_SEND_DATE => 15, ), + BasePeer::TYPE_FIELDNAME => array ('APP_MSG_UID' => 0, 'MSG_UID' => 1, 'APP_UID' => 2, 'DEL_INDEX' => 3, 'APP_MSG_TYPE' => 4, 'APP_MSG_SUBJECT' => 5, 'APP_MSG_FROM' => 6, 'APP_MSG_TO' => 7, 'APP_MSG_BODY' => 8, 'APP_MSG_DATE' => 9, 'APP_MSG_CC' => 10, 'APP_MSG_BCC' => 11, 'APP_MSG_TEMPLATE' => 12, 'APP_MSG_STATUS' => 13, 'APP_MSG_ATTACH' => 14, 'APP_MSG_SEND_DATE' => 15, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppMessageMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppMessageMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppMessagePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppMessagePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppMessagePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_UID); + + $criteria->addSelectColumn(AppMessagePeer::MSG_UID); + + $criteria->addSelectColumn(AppMessagePeer::APP_UID); + + $criteria->addSelectColumn(AppMessagePeer::DEL_INDEX); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_TYPE); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_SUBJECT); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_FROM); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_TO); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_BODY); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_DATE); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_CC); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_BCC); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_TEMPLATE); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_STATUS); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_ATTACH); + + $criteria->addSelectColumn(AppMessagePeer::APP_MSG_SEND_DATE); + + } + + const COUNT = 'COUNT(APP_MESSAGE.APP_MSG_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_MESSAGE.APP_MSG_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppMessagePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppMessagePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppMessagePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppMessage + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppMessagePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppMessagePeer::populateObjects(AppMessagePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppMessagePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppMessagePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppMessagePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppMessage or Criteria object. + * + * @param mixed $values Criteria or AppMessage object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppMessage object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppMessage or Criteria object. + * + * @param mixed $values Criteria or AppMessage object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppMessagePeer::APP_MSG_UID); + $selectCriteria->add(AppMessagePeer::APP_MSG_UID, $criteria->remove(AppMessagePeer::APP_MSG_UID), $comparison); + + } else { // $values is AppMessage object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_MESSAGE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppMessagePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppMessage or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppMessage object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppMessagePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppMessage) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(AppMessagePeer::APP_MSG_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppMessage object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppMessage $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppMessage $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppMessagePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppMessagePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppMessagePeer::DATABASE_NAME, AppMessagePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return AppMessage + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(AppMessagePeer::DATABASE_NAME); + + $criteria->add(AppMessagePeer::APP_MSG_UID, $pk); + + + $v = AppMessagePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(AppMessagePeer::APP_MSG_UID, $pks, Criteria::IN); + $objs = AppMessagePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseAppMessagePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppMessagePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppMessageMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppMessageMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppOwner.php b/workflow/engine/classes/model/om/BaseAppOwner.php new file mode 100644 index 000000000..4f42018ee --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppOwner.php @@ -0,0 +1,627 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppOwnerPeer.php'; + +/** + * Base class that represents a row from the 'APP_OWNER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppOwner extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppOwnerPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the own_uid field. + * @var string + */ + protected $own_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [own_uid] column value. + * + * @return string + */ + public function getOwnUid() + { + + return $this->own_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppOwnerPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [own_uid] column. + * + * @param string $v new value + * @return void + */ + public function setOwnUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->own_uid !== $v || $v === '') { + $this->own_uid = $v; + $this->modifiedColumns[] = AppOwnerPeer::OWN_UID; + } + + } // setOwnUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = AppOwnerPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->own_uid = $rs->getString($startcol + 1); + + $this->usr_uid = $rs->getString($startcol + 2); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 3; // 3 = AppOwnerPeer::NUM_COLUMNS - AppOwnerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppOwner object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppOwnerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppOwnerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppOwnerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppOwnerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppOwnerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppOwnerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppOwnerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getOwnUid(); + break; + case 2: + return $this->getUsrUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppOwnerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getOwnUid(), + $keys[2] => $this->getUsrUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppOwnerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setOwnUid($value); + break; + case 2: + $this->setUsrUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppOwnerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setOwnUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUsrUid($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppOwnerPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppOwnerPeer::APP_UID)) $criteria->add(AppOwnerPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppOwnerPeer::OWN_UID)) $criteria->add(AppOwnerPeer::OWN_UID, $this->own_uid); + if ($this->isColumnModified(AppOwnerPeer::USR_UID)) $criteria->add(AppOwnerPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppOwnerPeer::DATABASE_NAME); + + $criteria->add(AppOwnerPeer::APP_UID, $this->app_uid); + $criteria->add(AppOwnerPeer::OWN_UID, $this->own_uid); + $criteria->add(AppOwnerPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getOwnUid(); + + $pks[2] = $this->getUsrUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setOwnUid($keys[1]); + + $this->setUsrUid($keys[2]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppOwner (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setOwnUid(''); // this is a pkey column, so set to default value + + $copyObj->setUsrUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppOwner Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppOwnerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppOwnerPeer(); + } + return self::$peer; + } + +} // BaseAppOwner diff --git a/workflow/engine/classes/model/om/BaseAppOwnerPeer.php b/workflow/engine/classes/model/om/BaseAppOwnerPeer.php new file mode 100644 index 000000000..f10810420 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppOwnerPeer.php @@ -0,0 +1,573 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppOwnerPeer::getOMClass() +include_once 'classes/model/AppOwner.php'; + +/** + * Base static class for performing query and update operations on the 'APP_OWNER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppOwnerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_OWNER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppOwner'; + + /** The total number of columns. */ + const NUM_COLUMNS = 3; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_OWNER.APP_UID'; + + /** the column name for the OWN_UID field */ + const OWN_UID = 'APP_OWNER.OWN_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'APP_OWNER.USR_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'OwnUid', 'UsrUid', ), + BasePeer::TYPE_COLNAME => array (AppOwnerPeer::APP_UID, AppOwnerPeer::OWN_UID, AppOwnerPeer::USR_UID, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'OWN_UID', 'USR_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'OwnUid' => 1, 'UsrUid' => 2, ), + BasePeer::TYPE_COLNAME => array (AppOwnerPeer::APP_UID => 0, AppOwnerPeer::OWN_UID => 1, AppOwnerPeer::USR_UID => 2, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'OWN_UID' => 1, 'USR_UID' => 2, ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppOwnerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppOwnerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppOwnerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppOwnerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppOwnerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppOwnerPeer::APP_UID); + + $criteria->addSelectColumn(AppOwnerPeer::OWN_UID); + + $criteria->addSelectColumn(AppOwnerPeer::USR_UID); + + } + + const COUNT = 'COUNT(APP_OWNER.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_OWNER.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppOwnerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppOwnerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppOwnerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppOwner + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppOwnerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppOwnerPeer::populateObjects(AppOwnerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppOwnerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppOwnerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppOwnerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppOwner or Criteria object. + * + * @param mixed $values Criteria or AppOwner object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppOwner object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppOwner or Criteria object. + * + * @param mixed $values Criteria or AppOwner object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppOwnerPeer::APP_UID); + $selectCriteria->add(AppOwnerPeer::APP_UID, $criteria->remove(AppOwnerPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(AppOwnerPeer::OWN_UID); + $selectCriteria->add(AppOwnerPeer::OWN_UID, $criteria->remove(AppOwnerPeer::OWN_UID), $comparison); + + $comparison = $criteria->getComparison(AppOwnerPeer::USR_UID); + $selectCriteria->add(AppOwnerPeer::USR_UID, $criteria->remove(AppOwnerPeer::USR_UID), $comparison); + + } else { // $values is AppOwner object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_OWNER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppOwnerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppOwner or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppOwner object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppOwnerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppOwner) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + } + + $criteria->add(AppOwnerPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppOwnerPeer::OWN_UID, $vals[1], Criteria::IN); + $criteria->add(AppOwnerPeer::USR_UID, $vals[2], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppOwner object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppOwner $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppOwner $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppOwnerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppOwnerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppOwnerPeer::DATABASE_NAME, AppOwnerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param string $own_uid + @param string $usr_uid + + * @param Connection $con + * @return AppOwner + */ + public static function retrieveByPK( $app_uid, $own_uid, $usr_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppOwnerPeer::APP_UID, $app_uid); + $criteria->add(AppOwnerPeer::OWN_UID, $own_uid); + $criteria->add(AppOwnerPeer::USR_UID, $usr_uid); + $v = AppOwnerPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppOwnerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppOwnerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppOwnerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppOwnerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppSpool.php b/workflow/engine/classes/model/om/BaseAppSpool.php new file mode 100644 index 000000000..d83e9d029 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppSpool.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppSpoolPeer.php'; + +/** + * Base class that represents a row from the 'APP_SPOOL' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppSpool extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppSpoolPeer + */ + protected static $peer; + + + /** + * The value for the id field. + * @var int + */ + protected $id; + + + /** + * The value for the sender field. + * @var string + */ + protected $sender; + + + /** + * The value for the file field. + * @var string + */ + protected $file; + + + /** + * The value for the now field. + * @var string + */ + protected $now; + + + /** + * The value for the status field. + * @var string + */ + protected $status; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [sender] column value. + * + * @return string + */ + public function getSender() + { + + return $this->sender; + } + + /** + * Get the [file] column value. + * + * @return string + */ + public function getFile() + { + + return $this->file; + } + + /** + * Get the [now] column value. + * + * @return string + */ + public function getNow() + { + + return $this->now; + } + + /** + * Get the [status] column value. + * + * @return string + */ + public function getStatus() + { + + return $this->status; + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return void + */ + public function setId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = AppSpoolPeer::ID; + } + + } // setId() + + /** + * Set the value of [sender] column. + * + * @param string $v new value + * @return void + */ + public function setSender($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sender !== $v) { + $this->sender = $v; + $this->modifiedColumns[] = AppSpoolPeer::SENDER; + } + + } // setSender() + + /** + * Set the value of [file] column. + * + * @param string $v new value + * @return void + */ + public function setFile($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->file !== $v) { + $this->file = $v; + $this->modifiedColumns[] = AppSpoolPeer::FILE; + } + + } // setFile() + + /** + * Set the value of [now] column. + * + * @param string $v new value + * @return void + */ + public function setNow($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->now !== $v) { + $this->now = $v; + $this->modifiedColumns[] = AppSpoolPeer::NOW; + } + + } // setNow() + + /** + * Set the value of [status] column. + * + * @param string $v new value + * @return void + */ + public function setStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->status !== $v) { + $this->status = $v; + $this->modifiedColumns[] = AppSpoolPeer::STATUS; + } + + } // setStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->id = $rs->getInt($startcol + 0); + + $this->sender = $rs->getString($startcol + 1); + + $this->file = $rs->getString($startcol + 2); + + $this->now = $rs->getString($startcol + 3); + + $this->status = $rs->getString($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = AppSpoolPeer::NUM_COLUMNS - AppSpoolPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppSpool object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppSpoolPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppSpoolPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppSpoolPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppSpoolPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppSpoolPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppSpoolPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppSpoolPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getSender(); + break; + case 2: + return $this->getFile(); + break; + case 3: + return $this->getNow(); + break; + case 4: + return $this->getStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppSpoolPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getSender(), + $keys[2] => $this->getFile(), + $keys[3] => $this->getNow(), + $keys[4] => $this->getStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppSpoolPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setSender($value); + break; + case 2: + $this->setFile($value); + break; + case 3: + $this->setNow($value); + break; + case 4: + $this->setStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppSpoolPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setSender($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFile($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setNow($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setStatus($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppSpoolPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppSpoolPeer::ID)) $criteria->add(AppSpoolPeer::ID, $this->id); + if ($this->isColumnModified(AppSpoolPeer::SENDER)) $criteria->add(AppSpoolPeer::SENDER, $this->sender); + if ($this->isColumnModified(AppSpoolPeer::FILE)) $criteria->add(AppSpoolPeer::FILE, $this->file); + if ($this->isColumnModified(AppSpoolPeer::NOW)) $criteria->add(AppSpoolPeer::NOW, $this->now); + if ($this->isColumnModified(AppSpoolPeer::STATUS)) $criteria->add(AppSpoolPeer::STATUS, $this->status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppSpoolPeer::DATABASE_NAME); + + $criteria->add(AppSpoolPeer::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppSpool (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setSender($this->sender); + + $copyObj->setFile($this->file); + + $copyObj->setNow($this->now); + + $copyObj->setStatus($this->status); + + + $copyObj->setNew(true); + + $copyObj->setId(NULL); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppSpool Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppSpoolPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppSpoolPeer(); + } + return self::$peer; + } + +} // BaseAppSpool diff --git a/workflow/engine/classes/model/om/BaseAppSpoolPeer.php b/workflow/engine/classes/model/om/BaseAppSpoolPeer.php new file mode 100644 index 000000000..1fd5e2611 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppSpoolPeer.php @@ -0,0 +1,585 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppSpoolPeer::getOMClass() +include_once 'classes/model/AppSpool.php'; + +/** + * Base static class for performing query and update operations on the 'APP_SPOOL' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppSpoolPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_SPOOL'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppSpool'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the ID field */ + const ID = 'APP_SPOOL.ID'; + + /** the column name for the SENDER field */ + const SENDER = 'APP_SPOOL.SENDER'; + + /** the column name for the FILE field */ + const FILE = 'APP_SPOOL.FILE'; + + /** the column name for the NOW field */ + const NOW = 'APP_SPOOL.NOW'; + + /** the column name for the STATUS field */ + const STATUS = 'APP_SPOOL.STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('Id', 'Sender', 'File', 'Now', 'Status', ), + BasePeer::TYPE_COLNAME => array (AppSpoolPeer::ID, AppSpoolPeer::SENDER, AppSpoolPeer::FILE, AppSpoolPeer::NOW, AppSpoolPeer::STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('id', 'sender', 'file', 'now', 'status', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Sender' => 1, 'File' => 2, 'Now' => 3, 'Status' => 4, ), + BasePeer::TYPE_COLNAME => array (AppSpoolPeer::ID => 0, AppSpoolPeer::SENDER => 1, AppSpoolPeer::FILE => 2, AppSpoolPeer::NOW => 3, AppSpoolPeer::STATUS => 4, ), + BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'sender' => 1, 'file' => 2, 'now' => 3, 'status' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppSpoolMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppSpoolMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppSpoolPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppSpoolPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppSpoolPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppSpoolPeer::ID); + + $criteria->addSelectColumn(AppSpoolPeer::SENDER); + + $criteria->addSelectColumn(AppSpoolPeer::FILE); + + $criteria->addSelectColumn(AppSpoolPeer::NOW); + + $criteria->addSelectColumn(AppSpoolPeer::STATUS); + + } + + const COUNT = 'COUNT(APP_SPOOL.ID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_SPOOL.ID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppSpoolPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppSpoolPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppSpoolPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppSpool + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppSpoolPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppSpoolPeer::populateObjects(AppSpoolPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppSpoolPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppSpoolPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppSpoolPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppSpool or Criteria object. + * + * @param mixed $values Criteria or AppSpool object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppSpool object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppSpool or Criteria object. + * + * @param mixed $values Criteria or AppSpool object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppSpoolPeer::ID); + $selectCriteria->add(AppSpoolPeer::ID, $criteria->remove(AppSpoolPeer::ID), $comparison); + + } else { // $values is AppSpool object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_SPOOL table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppSpoolPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppSpool or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppSpool object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppSpoolPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppSpool) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(AppSpoolPeer::ID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppSpool object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppSpool $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppSpool $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppSpoolPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppSpoolPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(AppSpoolPeer::DATABASE_NAME, AppSpoolPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return AppSpool + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(AppSpoolPeer::DATABASE_NAME); + + $criteria->add(AppSpoolPeer::ID, $pk); + + + $v = AppSpoolPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(AppSpoolPeer::ID, $pks, Criteria::IN); + $objs = AppSpoolPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseAppSpoolPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppSpoolPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppSpoolMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppSpoolMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseAppThread.php b/workflow/engine/classes/model/om/BaseAppThread.php new file mode 100644 index 000000000..aeebfe98f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppThread.php @@ -0,0 +1,728 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/AppThreadPeer.php'; + +/** + * Base class that represents a row from the 'APP_THREAD' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppThread extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var AppThreadPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the app_thread_index field. + * @var int + */ + protected $app_thread_index = 0; + + + /** + * The value for the app_thread_parent field. + * @var int + */ + protected $app_thread_parent = 0; + + + /** + * The value for the app_thread_status field. + * @var string + */ + protected $app_thread_status = 'OPEN'; + + + /** + * The value for the del_index field. + * @var int + */ + protected $del_index = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [app_thread_index] column value. + * + * @return int + */ + public function getAppThreadIndex() + { + + return $this->app_thread_index; + } + + /** + * Get the [app_thread_parent] column value. + * + * @return int + */ + public function getAppThreadParent() + { + + return $this->app_thread_parent; + } + + /** + * Get the [app_thread_status] column value. + * + * @return string + */ + public function getAppThreadStatus() + { + + return $this->app_thread_status; + } + + /** + * Get the [del_index] column value. + * + * @return int + */ + public function getDelIndex() + { + + return $this->del_index; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = AppThreadPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [app_thread_index] column. + * + * @param int $v new value + * @return void + */ + public function setAppThreadIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_thread_index !== $v || $v === 0) { + $this->app_thread_index = $v; + $this->modifiedColumns[] = AppThreadPeer::APP_THREAD_INDEX; + } + + } // setAppThreadIndex() + + /** + * Set the value of [app_thread_parent] column. + * + * @param int $v new value + * @return void + */ + public function setAppThreadParent($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_thread_parent !== $v || $v === 0) { + $this->app_thread_parent = $v; + $this->modifiedColumns[] = AppThreadPeer::APP_THREAD_PARENT; + } + + } // setAppThreadParent() + + /** + * Set the value of [app_thread_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppThreadStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_thread_status !== $v || $v === 'OPEN') { + $this->app_thread_status = $v; + $this->modifiedColumns[] = AppThreadPeer::APP_THREAD_STATUS; + } + + } // setAppThreadStatus() + + /** + * Set the value of [del_index] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index !== $v || $v === 0) { + $this->del_index = $v; + $this->modifiedColumns[] = AppThreadPeer::DEL_INDEX; + } + + } // setDelIndex() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->app_thread_index = $rs->getInt($startcol + 1); + + $this->app_thread_parent = $rs->getInt($startcol + 2); + + $this->app_thread_status = $rs->getString($startcol + 3); + + $this->del_index = $rs->getInt($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = AppThreadPeer::NUM_COLUMNS - AppThreadPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating AppThread object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppThreadPeer::DATABASE_NAME); + } + + try { + $con->begin(); + AppThreadPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(AppThreadPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = AppThreadPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += AppThreadPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = AppThreadPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppThreadPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getAppThreadIndex(); + break; + case 2: + return $this->getAppThreadParent(); + break; + case 3: + return $this->getAppThreadStatus(); + break; + case 4: + return $this->getDelIndex(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppThreadPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getAppThreadIndex(), + $keys[2] => $this->getAppThreadParent(), + $keys[3] => $this->getAppThreadStatus(), + $keys[4] => $this->getDelIndex(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = AppThreadPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setAppThreadIndex($value); + break; + case 2: + $this->setAppThreadParent($value); + break; + case 3: + $this->setAppThreadStatus($value); + break; + case 4: + $this->setDelIndex($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = AppThreadPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAppThreadIndex($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppThreadParent($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAppThreadStatus($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setDelIndex($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AppThreadPeer::DATABASE_NAME); + + if ($this->isColumnModified(AppThreadPeer::APP_UID)) $criteria->add(AppThreadPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(AppThreadPeer::APP_THREAD_INDEX)) $criteria->add(AppThreadPeer::APP_THREAD_INDEX, $this->app_thread_index); + if ($this->isColumnModified(AppThreadPeer::APP_THREAD_PARENT)) $criteria->add(AppThreadPeer::APP_THREAD_PARENT, $this->app_thread_parent); + if ($this->isColumnModified(AppThreadPeer::APP_THREAD_STATUS)) $criteria->add(AppThreadPeer::APP_THREAD_STATUS, $this->app_thread_status); + if ($this->isColumnModified(AppThreadPeer::DEL_INDEX)) $criteria->add(AppThreadPeer::DEL_INDEX, $this->del_index); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AppThreadPeer::DATABASE_NAME); + + $criteria->add(AppThreadPeer::APP_UID, $this->app_uid); + $criteria->add(AppThreadPeer::APP_THREAD_INDEX, $this->app_thread_index); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getAppThreadIndex(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setAppThreadIndex($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of AppThread (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppThreadParent($this->app_thread_parent); + + $copyObj->setAppThreadStatus($this->app_thread_status); + + $copyObj->setDelIndex($this->del_index); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setAppThreadIndex('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return AppThread Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return AppThreadPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new AppThreadPeer(); + } + return self::$peer; + } + +} // BaseAppThread diff --git a/workflow/engine/classes/model/om/BaseAppThreadPeer.php b/workflow/engine/classes/model/om/BaseAppThreadPeer.php new file mode 100644 index 000000000..de9ab78d1 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseAppThreadPeer.php @@ -0,0 +1,579 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by AppThreadPeer::getOMClass() +include_once 'classes/model/AppThread.php'; + +/** + * Base static class for performing query and update operations on the 'APP_THREAD' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseAppThreadPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APP_THREAD'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.AppThread'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APP_THREAD.APP_UID'; + + /** the column name for the APP_THREAD_INDEX field */ + const APP_THREAD_INDEX = 'APP_THREAD.APP_THREAD_INDEX'; + + /** the column name for the APP_THREAD_PARENT field */ + const APP_THREAD_PARENT = 'APP_THREAD.APP_THREAD_PARENT'; + + /** the column name for the APP_THREAD_STATUS field */ + const APP_THREAD_STATUS = 'APP_THREAD.APP_THREAD_STATUS'; + + /** the column name for the DEL_INDEX field */ + const DEL_INDEX = 'APP_THREAD.DEL_INDEX'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'AppThreadIndex', 'AppThreadParent', 'AppThreadStatus', 'DelIndex', ), + BasePeer::TYPE_COLNAME => array (AppThreadPeer::APP_UID, AppThreadPeer::APP_THREAD_INDEX, AppThreadPeer::APP_THREAD_PARENT, AppThreadPeer::APP_THREAD_STATUS, AppThreadPeer::DEL_INDEX, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'APP_THREAD_INDEX', 'APP_THREAD_PARENT', 'APP_THREAD_STATUS', 'DEL_INDEX', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'AppThreadIndex' => 1, 'AppThreadParent' => 2, 'AppThreadStatus' => 3, 'DelIndex' => 4, ), + BasePeer::TYPE_COLNAME => array (AppThreadPeer::APP_UID => 0, AppThreadPeer::APP_THREAD_INDEX => 1, AppThreadPeer::APP_THREAD_PARENT => 2, AppThreadPeer::APP_THREAD_STATUS => 3, AppThreadPeer::DEL_INDEX => 4, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'APP_THREAD_INDEX' => 1, 'APP_THREAD_PARENT' => 2, 'APP_THREAD_STATUS' => 3, 'DEL_INDEX' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/AppThreadMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.AppThreadMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = AppThreadPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. AppThreadPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(AppThreadPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(AppThreadPeer::APP_UID); + + $criteria->addSelectColumn(AppThreadPeer::APP_THREAD_INDEX); + + $criteria->addSelectColumn(AppThreadPeer::APP_THREAD_PARENT); + + $criteria->addSelectColumn(AppThreadPeer::APP_THREAD_STATUS); + + $criteria->addSelectColumn(AppThreadPeer::DEL_INDEX); + + } + + const COUNT = 'COUNT(APP_THREAD.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APP_THREAD.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(AppThreadPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(AppThreadPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = AppThreadPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return AppThread + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = AppThreadPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return AppThreadPeer::populateObjects(AppThreadPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + AppThreadPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = AppThreadPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return AppThreadPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a AppThread or Criteria object. + * + * @param mixed $values Criteria or AppThread object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from AppThread object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a AppThread or Criteria object. + * + * @param mixed $values Criteria or AppThread object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(AppThreadPeer::APP_UID); + $selectCriteria->add(AppThreadPeer::APP_UID, $criteria->remove(AppThreadPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(AppThreadPeer::APP_THREAD_INDEX); + $selectCriteria->add(AppThreadPeer::APP_THREAD_INDEX, $criteria->remove(AppThreadPeer::APP_THREAD_INDEX), $comparison); + + } else { // $values is AppThread object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APP_THREAD table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(AppThreadPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a AppThread or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AppThread object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(AppThreadPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof AppThread) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(AppThreadPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(AppThreadPeer::APP_THREAD_INDEX, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given AppThread object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param AppThread $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(AppThread $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(AppThreadPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(AppThreadPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(AppThreadPeer::APP_THREAD_STATUS)) + $columns[AppThreadPeer::APP_THREAD_STATUS] = $obj->getAppThreadStatus(); + + } + + return BasePeer::doValidate(AppThreadPeer::DATABASE_NAME, AppThreadPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param int $app_thread_index + + * @param Connection $con + * @return AppThread + */ + public static function retrieveByPK( $app_uid, $app_thread_index, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(AppThreadPeer::APP_UID, $app_uid); + $criteria->add(AppThreadPeer::APP_THREAD_INDEX, $app_thread_index); + $v = AppThreadPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseAppThreadPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseAppThreadPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/AppThreadMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.AppThreadMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseApplication.php b/workflow/engine/classes/model/om/BaseApplication.php new file mode 100644 index 000000000..1da604b90 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseApplication.php @@ -0,0 +1,1387 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ApplicationPeer.php'; + +/** + * Base class that represents a row from the 'APPLICATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseApplication extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ApplicationPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the app_number field. + * @var int + */ + protected $app_number = 0; + + + /** + * The value for the app_parent field. + * @var string + */ + protected $app_parent = '0'; + + + /** + * The value for the app_status field. + * @var string + */ + protected $app_status = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the app_proc_status field. + * @var string + */ + protected $app_proc_status = ''; + + + /** + * The value for the app_proc_code field. + * @var string + */ + protected $app_proc_code = ''; + + + /** + * The value for the app_parallel field. + * @var string + */ + protected $app_parallel = 'NO'; + + + /** + * The value for the app_init_user field. + * @var string + */ + protected $app_init_user = ''; + + + /** + * The value for the app_cur_user field. + * @var string + */ + protected $app_cur_user = ''; + + + /** + * The value for the app_create_date field. + * @var int + */ + protected $app_create_date; + + + /** + * The value for the app_init_date field. + * @var int + */ + protected $app_init_date; + + + /** + * The value for the app_finish_date field. + * @var int + */ + protected $app_finish_date; + + + /** + * The value for the app_update_date field. + * @var int + */ + protected $app_update_date; + + + /** + * The value for the app_data field. + * @var string + */ + protected $app_data; + + + /** + * The value for the app_pin field. + * @var string + */ + protected $app_pin = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [app_number] column value. + * + * @return int + */ + public function getAppNumber() + { + + return $this->app_number; + } + + /** + * Get the [app_parent] column value. + * + * @return string + */ + public function getAppParent() + { + + return $this->app_parent; + } + + /** + * Get the [app_status] column value. + * + * @return string + */ + public function getAppStatus() + { + + return $this->app_status; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [app_proc_status] column value. + * + * @return string + */ + public function getAppProcStatus() + { + + return $this->app_proc_status; + } + + /** + * Get the [app_proc_code] column value. + * + * @return string + */ + public function getAppProcCode() + { + + return $this->app_proc_code; + } + + /** + * Get the [app_parallel] column value. + * + * @return string + */ + public function getAppParallel() + { + + return $this->app_parallel; + } + + /** + * Get the [app_init_user] column value. + * + * @return string + */ + public function getAppInitUser() + { + + return $this->app_init_user; + } + + /** + * Get the [app_cur_user] column value. + * + * @return string + */ + public function getAppCurUser() + { + + return $this->app_cur_user; + } + + /** + * Get the [optionally formatted] [app_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_create_date === null || $this->app_create_date === '') { + return null; + } elseif (!is_int($this->app_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_create_date] as date/time value: " . var_export($this->app_create_date, true)); + } + } else { + $ts = $this->app_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_init_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppInitDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_init_date === null || $this->app_init_date === '') { + return null; + } elseif (!is_int($this->app_init_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_init_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_init_date] as date/time value: " . var_export($this->app_init_date, true)); + } + } else { + $ts = $this->app_init_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_finish_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppFinishDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_finish_date === null || $this->app_finish_date === '') { + return null; + } elseif (!is_int($this->app_finish_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_finish_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_finish_date] as date/time value: " . var_export($this->app_finish_date, true)); + } + } else { + $ts = $this->app_finish_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [app_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getAppUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->app_update_date === null || $this->app_update_date === '') { + return null; + } elseif (!is_int($this->app_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->app_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [app_update_date] as date/time value: " . var_export($this->app_update_date, true)); + } + } else { + $ts = $this->app_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [app_data] column value. + * + * @return string + */ + public function getAppData() + { + + return $this->app_data; + } + + /** + * Get the [app_pin] column value. + * + * @return string + */ + public function getAppPin() + { + + return $this->app_pin; + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [app_number] column. + * + * @param int $v new value + * @return void + */ + public function setAppNumber($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->app_number !== $v || $v === 0) { + $this->app_number = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_NUMBER; + } + + } // setAppNumber() + + /** + * Set the value of [app_parent] column. + * + * @param string $v new value + * @return void + */ + public function setAppParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_parent !== $v || $v === '0') { + $this->app_parent = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_PARENT; + } + + } // setAppParent() + + /** + * Set the value of [app_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_status !== $v || $v === '') { + $this->app_status = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_STATUS; + } + + } // setAppStatus() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ApplicationPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [app_proc_status] column. + * + * @param string $v new value + * @return void + */ + public function setAppProcStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_proc_status !== $v || $v === '') { + $this->app_proc_status = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_PROC_STATUS; + } + + } // setAppProcStatus() + + /** + * Set the value of [app_proc_code] column. + * + * @param string $v new value + * @return void + */ + public function setAppProcCode($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_proc_code !== $v || $v === '') { + $this->app_proc_code = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_PROC_CODE; + } + + } // setAppProcCode() + + /** + * Set the value of [app_parallel] column. + * + * @param string $v new value + * @return void + */ + public function setAppParallel($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_parallel !== $v || $v === 'NO') { + $this->app_parallel = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_PARALLEL; + } + + } // setAppParallel() + + /** + * Set the value of [app_init_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppInitUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_init_user !== $v || $v === '') { + $this->app_init_user = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_INIT_USER; + } + + } // setAppInitUser() + + /** + * Set the value of [app_cur_user] column. + * + * @param string $v new value + * @return void + */ + public function setAppCurUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_cur_user !== $v || $v === '') { + $this->app_cur_user = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_CUR_USER; + } + + } // setAppCurUser() + + /** + * Set the value of [app_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_create_date !== $ts) { + $this->app_create_date = $ts; + $this->modifiedColumns[] = ApplicationPeer::APP_CREATE_DATE; + } + + } // setAppCreateDate() + + /** + * Set the value of [app_init_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppInitDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_init_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_init_date !== $ts) { + $this->app_init_date = $ts; + $this->modifiedColumns[] = ApplicationPeer::APP_INIT_DATE; + } + + } // setAppInitDate() + + /** + * Set the value of [app_finish_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppFinishDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_finish_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_finish_date !== $ts) { + $this->app_finish_date = $ts; + $this->modifiedColumns[] = ApplicationPeer::APP_FINISH_DATE; + } + + } // setAppFinishDate() + + /** + * Set the value of [app_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setAppUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [app_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->app_update_date !== $ts) { + $this->app_update_date = $ts; + $this->modifiedColumns[] = ApplicationPeer::APP_UPDATE_DATE; + } + + } // setAppUpdateDate() + + /** + * Set the value of [app_data] column. + * + * @param string $v new value + * @return void + */ + public function setAppData($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_data !== $v) { + $this->app_data = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_DATA; + } + + } // setAppData() + + /** + * Set the value of [app_pin] column. + * + * @param string $v new value + * @return void + */ + public function setAppPin($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_pin !== $v || $v === '') { + $this->app_pin = $v; + $this->modifiedColumns[] = ApplicationPeer::APP_PIN; + } + + } // setAppPin() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->app_number = $rs->getInt($startcol + 1); + + $this->app_parent = $rs->getString($startcol + 2); + + $this->app_status = $rs->getString($startcol + 3); + + $this->pro_uid = $rs->getString($startcol + 4); + + $this->app_proc_status = $rs->getString($startcol + 5); + + $this->app_proc_code = $rs->getString($startcol + 6); + + $this->app_parallel = $rs->getString($startcol + 7); + + $this->app_init_user = $rs->getString($startcol + 8); + + $this->app_cur_user = $rs->getString($startcol + 9); + + $this->app_create_date = $rs->getTimestamp($startcol + 10, null); + + $this->app_init_date = $rs->getTimestamp($startcol + 11, null); + + $this->app_finish_date = $rs->getTimestamp($startcol + 12, null); + + $this->app_update_date = $rs->getTimestamp($startcol + 13, null); + + $this->app_data = $rs->getString($startcol + 14); + + $this->app_pin = $rs->getString($startcol + 15); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 16; // 16 = ApplicationPeer::NUM_COLUMNS - ApplicationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Application object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ApplicationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ApplicationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ApplicationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ApplicationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ApplicationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ApplicationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ApplicationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getAppNumber(); + break; + case 2: + return $this->getAppParent(); + break; + case 3: + return $this->getAppStatus(); + break; + case 4: + return $this->getProUid(); + break; + case 5: + return $this->getAppProcStatus(); + break; + case 6: + return $this->getAppProcCode(); + break; + case 7: + return $this->getAppParallel(); + break; + case 8: + return $this->getAppInitUser(); + break; + case 9: + return $this->getAppCurUser(); + break; + case 10: + return $this->getAppCreateDate(); + break; + case 11: + return $this->getAppInitDate(); + break; + case 12: + return $this->getAppFinishDate(); + break; + case 13: + return $this->getAppUpdateDate(); + break; + case 14: + return $this->getAppData(); + break; + case 15: + return $this->getAppPin(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ApplicationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getAppNumber(), + $keys[2] => $this->getAppParent(), + $keys[3] => $this->getAppStatus(), + $keys[4] => $this->getProUid(), + $keys[5] => $this->getAppProcStatus(), + $keys[6] => $this->getAppProcCode(), + $keys[7] => $this->getAppParallel(), + $keys[8] => $this->getAppInitUser(), + $keys[9] => $this->getAppCurUser(), + $keys[10] => $this->getAppCreateDate(), + $keys[11] => $this->getAppInitDate(), + $keys[12] => $this->getAppFinishDate(), + $keys[13] => $this->getAppUpdateDate(), + $keys[14] => $this->getAppData(), + $keys[15] => $this->getAppPin(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ApplicationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setAppNumber($value); + break; + case 2: + $this->setAppParent($value); + break; + case 3: + $this->setAppStatus($value); + break; + case 4: + $this->setProUid($value); + break; + case 5: + $this->setAppProcStatus($value); + break; + case 6: + $this->setAppProcCode($value); + break; + case 7: + $this->setAppParallel($value); + break; + case 8: + $this->setAppInitUser($value); + break; + case 9: + $this->setAppCurUser($value); + break; + case 10: + $this->setAppCreateDate($value); + break; + case 11: + $this->setAppInitDate($value); + break; + case 12: + $this->setAppFinishDate($value); + break; + case 13: + $this->setAppUpdateDate($value); + break; + case 14: + $this->setAppData($value); + break; + case 15: + $this->setAppPin($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ApplicationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAppNumber($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAppParent($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAppStatus($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setProUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppProcStatus($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAppProcCode($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAppParallel($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAppInitUser($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAppCurUser($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setAppCreateDate($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setAppInitDate($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setAppFinishDate($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setAppUpdateDate($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setAppData($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setAppPin($arr[$keys[15]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ApplicationPeer::DATABASE_NAME); + + if ($this->isColumnModified(ApplicationPeer::APP_UID)) $criteria->add(ApplicationPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(ApplicationPeer::APP_NUMBER)) $criteria->add(ApplicationPeer::APP_NUMBER, $this->app_number); + if ($this->isColumnModified(ApplicationPeer::APP_PARENT)) $criteria->add(ApplicationPeer::APP_PARENT, $this->app_parent); + if ($this->isColumnModified(ApplicationPeer::APP_STATUS)) $criteria->add(ApplicationPeer::APP_STATUS, $this->app_status); + if ($this->isColumnModified(ApplicationPeer::PRO_UID)) $criteria->add(ApplicationPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ApplicationPeer::APP_PROC_STATUS)) $criteria->add(ApplicationPeer::APP_PROC_STATUS, $this->app_proc_status); + if ($this->isColumnModified(ApplicationPeer::APP_PROC_CODE)) $criteria->add(ApplicationPeer::APP_PROC_CODE, $this->app_proc_code); + if ($this->isColumnModified(ApplicationPeer::APP_PARALLEL)) $criteria->add(ApplicationPeer::APP_PARALLEL, $this->app_parallel); + if ($this->isColumnModified(ApplicationPeer::APP_INIT_USER)) $criteria->add(ApplicationPeer::APP_INIT_USER, $this->app_init_user); + if ($this->isColumnModified(ApplicationPeer::APP_CUR_USER)) $criteria->add(ApplicationPeer::APP_CUR_USER, $this->app_cur_user); + if ($this->isColumnModified(ApplicationPeer::APP_CREATE_DATE)) $criteria->add(ApplicationPeer::APP_CREATE_DATE, $this->app_create_date); + if ($this->isColumnModified(ApplicationPeer::APP_INIT_DATE)) $criteria->add(ApplicationPeer::APP_INIT_DATE, $this->app_init_date); + if ($this->isColumnModified(ApplicationPeer::APP_FINISH_DATE)) $criteria->add(ApplicationPeer::APP_FINISH_DATE, $this->app_finish_date); + if ($this->isColumnModified(ApplicationPeer::APP_UPDATE_DATE)) $criteria->add(ApplicationPeer::APP_UPDATE_DATE, $this->app_update_date); + if ($this->isColumnModified(ApplicationPeer::APP_DATA)) $criteria->add(ApplicationPeer::APP_DATA, $this->app_data); + if ($this->isColumnModified(ApplicationPeer::APP_PIN)) $criteria->add(ApplicationPeer::APP_PIN, $this->app_pin); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ApplicationPeer::DATABASE_NAME); + + $criteria->add(ApplicationPeer::APP_UID, $this->app_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getAppUid(); + } + + /** + * Generic method to set the primary key (app_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setAppUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Application (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAppNumber($this->app_number); + + $copyObj->setAppParent($this->app_parent); + + $copyObj->setAppStatus($this->app_status); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setAppProcStatus($this->app_proc_status); + + $copyObj->setAppProcCode($this->app_proc_code); + + $copyObj->setAppParallel($this->app_parallel); + + $copyObj->setAppInitUser($this->app_init_user); + + $copyObj->setAppCurUser($this->app_cur_user); + + $copyObj->setAppCreateDate($this->app_create_date); + + $copyObj->setAppInitDate($this->app_init_date); + + $copyObj->setAppFinishDate($this->app_finish_date); + + $copyObj->setAppUpdateDate($this->app_update_date); + + $copyObj->setAppData($this->app_data); + + $copyObj->setAppPin($this->app_pin); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Application Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ApplicationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ApplicationPeer(); + } + return self::$peer; + } + +} // BaseApplication diff --git a/workflow/engine/classes/model/om/BaseApplicationPeer.php b/workflow/engine/classes/model/om/BaseApplicationPeer.php new file mode 100644 index 000000000..beb4f291c --- /dev/null +++ b/workflow/engine/classes/model/om/BaseApplicationPeer.php @@ -0,0 +1,643 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ApplicationPeer::getOMClass() +include_once 'classes/model/Application.php'; + +/** + * Base static class for performing query and update operations on the 'APPLICATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseApplicationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'APPLICATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Application'; + + /** The total number of columns. */ + const NUM_COLUMNS = 16; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'APPLICATION.APP_UID'; + + /** the column name for the APP_NUMBER field */ + const APP_NUMBER = 'APPLICATION.APP_NUMBER'; + + /** the column name for the APP_PARENT field */ + const APP_PARENT = 'APPLICATION.APP_PARENT'; + + /** the column name for the APP_STATUS field */ + const APP_STATUS = 'APPLICATION.APP_STATUS'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'APPLICATION.PRO_UID'; + + /** the column name for the APP_PROC_STATUS field */ + const APP_PROC_STATUS = 'APPLICATION.APP_PROC_STATUS'; + + /** the column name for the APP_PROC_CODE field */ + const APP_PROC_CODE = 'APPLICATION.APP_PROC_CODE'; + + /** the column name for the APP_PARALLEL field */ + const APP_PARALLEL = 'APPLICATION.APP_PARALLEL'; + + /** the column name for the APP_INIT_USER field */ + const APP_INIT_USER = 'APPLICATION.APP_INIT_USER'; + + /** the column name for the APP_CUR_USER field */ + const APP_CUR_USER = 'APPLICATION.APP_CUR_USER'; + + /** the column name for the APP_CREATE_DATE field */ + const APP_CREATE_DATE = 'APPLICATION.APP_CREATE_DATE'; + + /** the column name for the APP_INIT_DATE field */ + const APP_INIT_DATE = 'APPLICATION.APP_INIT_DATE'; + + /** the column name for the APP_FINISH_DATE field */ + const APP_FINISH_DATE = 'APPLICATION.APP_FINISH_DATE'; + + /** the column name for the APP_UPDATE_DATE field */ + const APP_UPDATE_DATE = 'APPLICATION.APP_UPDATE_DATE'; + + /** the column name for the APP_DATA field */ + const APP_DATA = 'APPLICATION.APP_DATA'; + + /** the column name for the APP_PIN field */ + const APP_PIN = 'APPLICATION.APP_PIN'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'AppNumber', 'AppParent', 'AppStatus', 'ProUid', 'AppProcStatus', 'AppProcCode', 'AppParallel', 'AppInitUser', 'AppCurUser', 'AppCreateDate', 'AppInitDate', 'AppFinishDate', 'AppUpdateDate', 'AppData', 'AppPin', ), + BasePeer::TYPE_COLNAME => array (ApplicationPeer::APP_UID, ApplicationPeer::APP_NUMBER, ApplicationPeer::APP_PARENT, ApplicationPeer::APP_STATUS, ApplicationPeer::PRO_UID, ApplicationPeer::APP_PROC_STATUS, ApplicationPeer::APP_PROC_CODE, ApplicationPeer::APP_PARALLEL, ApplicationPeer::APP_INIT_USER, ApplicationPeer::APP_CUR_USER, ApplicationPeer::APP_CREATE_DATE, ApplicationPeer::APP_INIT_DATE, ApplicationPeer::APP_FINISH_DATE, ApplicationPeer::APP_UPDATE_DATE, ApplicationPeer::APP_DATA, ApplicationPeer::APP_PIN, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'APP_NUMBER', 'APP_PARENT', 'APP_STATUS', 'PRO_UID', 'APP_PROC_STATUS', 'APP_PROC_CODE', 'APP_PARALLEL', 'APP_INIT_USER', 'APP_CUR_USER', 'APP_CREATE_DATE', 'APP_INIT_DATE', 'APP_FINISH_DATE', 'APP_UPDATE_DATE', 'APP_DATA', 'APP_PIN', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'AppNumber' => 1, 'AppParent' => 2, 'AppStatus' => 3, 'ProUid' => 4, 'AppProcStatus' => 5, 'AppProcCode' => 6, 'AppParallel' => 7, 'AppInitUser' => 8, 'AppCurUser' => 9, 'AppCreateDate' => 10, 'AppInitDate' => 11, 'AppFinishDate' => 12, 'AppUpdateDate' => 13, 'AppData' => 14, 'AppPin' => 15, ), + BasePeer::TYPE_COLNAME => array (ApplicationPeer::APP_UID => 0, ApplicationPeer::APP_NUMBER => 1, ApplicationPeer::APP_PARENT => 2, ApplicationPeer::APP_STATUS => 3, ApplicationPeer::PRO_UID => 4, ApplicationPeer::APP_PROC_STATUS => 5, ApplicationPeer::APP_PROC_CODE => 6, ApplicationPeer::APP_PARALLEL => 7, ApplicationPeer::APP_INIT_USER => 8, ApplicationPeer::APP_CUR_USER => 9, ApplicationPeer::APP_CREATE_DATE => 10, ApplicationPeer::APP_INIT_DATE => 11, ApplicationPeer::APP_FINISH_DATE => 12, ApplicationPeer::APP_UPDATE_DATE => 13, ApplicationPeer::APP_DATA => 14, ApplicationPeer::APP_PIN => 15, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'APP_NUMBER' => 1, 'APP_PARENT' => 2, 'APP_STATUS' => 3, 'PRO_UID' => 4, 'APP_PROC_STATUS' => 5, 'APP_PROC_CODE' => 6, 'APP_PARALLEL' => 7, 'APP_INIT_USER' => 8, 'APP_CUR_USER' => 9, 'APP_CREATE_DATE' => 10, 'APP_INIT_DATE' => 11, 'APP_FINISH_DATE' => 12, 'APP_UPDATE_DATE' => 13, 'APP_DATA' => 14, 'APP_PIN' => 15, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ApplicationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ApplicationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ApplicationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ApplicationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ApplicationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ApplicationPeer::APP_UID); + + $criteria->addSelectColumn(ApplicationPeer::APP_NUMBER); + + $criteria->addSelectColumn(ApplicationPeer::APP_PARENT); + + $criteria->addSelectColumn(ApplicationPeer::APP_STATUS); + + $criteria->addSelectColumn(ApplicationPeer::PRO_UID); + + $criteria->addSelectColumn(ApplicationPeer::APP_PROC_STATUS); + + $criteria->addSelectColumn(ApplicationPeer::APP_PROC_CODE); + + $criteria->addSelectColumn(ApplicationPeer::APP_PARALLEL); + + $criteria->addSelectColumn(ApplicationPeer::APP_INIT_USER); + + $criteria->addSelectColumn(ApplicationPeer::APP_CUR_USER); + + $criteria->addSelectColumn(ApplicationPeer::APP_CREATE_DATE); + + $criteria->addSelectColumn(ApplicationPeer::APP_INIT_DATE); + + $criteria->addSelectColumn(ApplicationPeer::APP_FINISH_DATE); + + $criteria->addSelectColumn(ApplicationPeer::APP_UPDATE_DATE); + + $criteria->addSelectColumn(ApplicationPeer::APP_DATA); + + $criteria->addSelectColumn(ApplicationPeer::APP_PIN); + + } + + const COUNT = 'COUNT(APPLICATION.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT APPLICATION.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ApplicationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ApplicationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ApplicationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Application + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ApplicationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ApplicationPeer::populateObjects(ApplicationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ApplicationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ApplicationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ApplicationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Application or Criteria object. + * + * @param mixed $values Criteria or Application object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Application object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Application or Criteria object. + * + * @param mixed $values Criteria or Application object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ApplicationPeer::APP_UID); + $selectCriteria->add(ApplicationPeer::APP_UID, $criteria->remove(ApplicationPeer::APP_UID), $comparison); + + } else { // $values is Application object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the APPLICATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ApplicationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Application or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Application object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ApplicationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Application) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ApplicationPeer::APP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Application object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Application $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Application $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ApplicationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ApplicationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ApplicationPeer::APP_STATUS)) + $columns[ApplicationPeer::APP_STATUS] = $obj->getAppStatus(); + + } + + return BasePeer::doValidate(ApplicationPeer::DATABASE_NAME, ApplicationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Application + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ApplicationPeer::DATABASE_NAME); + + $criteria->add(ApplicationPeer::APP_UID, $pk); + + + $v = ApplicationPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ApplicationPeer::APP_UID, $pks, Criteria::IN); + $objs = ApplicationPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseApplicationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseApplicationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ApplicationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ApplicationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCalendarAssignments.php b/workflow/engine/classes/model/om/BaseCalendarAssignments.php new file mode 100644 index 000000000..83383bd5e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarAssignments.php @@ -0,0 +1,610 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CalendarAssignmentsPeer.php'; + +/** + * Base class that represents a row from the 'CALENDAR_ASSIGNMENTS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarAssignments extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CalendarAssignmentsPeer + */ + protected static $peer; + + + /** + * The value for the object_uid field. + * @var string + */ + protected $object_uid = ''; + + + /** + * The value for the calendar_uid field. + * @var string + */ + protected $calendar_uid = ''; + + + /** + * The value for the object_type field. + * @var string + */ + protected $object_type = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [object_uid] column value. + * + * @return string + */ + public function getObjectUid() + { + + return $this->object_uid; + } + + /** + * Get the [calendar_uid] column value. + * + * @return string + */ + public function getCalendarUid() + { + + return $this->calendar_uid; + } + + /** + * Get the [object_type] column value. + * + * @return string + */ + public function getObjectType() + { + + return $this->object_type; + } + + /** + * Set the value of [object_uid] column. + * + * @param string $v new value + * @return void + */ + public function setObjectUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->object_uid !== $v || $v === '') { + $this->object_uid = $v; + $this->modifiedColumns[] = CalendarAssignmentsPeer::OBJECT_UID; + } + + } // setObjectUid() + + /** + * Set the value of [calendar_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_uid !== $v || $v === '') { + $this->calendar_uid = $v; + $this->modifiedColumns[] = CalendarAssignmentsPeer::CALENDAR_UID; + } + + } // setCalendarUid() + + /** + * Set the value of [object_type] column. + * + * @param string $v new value + * @return void + */ + public function setObjectType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->object_type !== $v || $v === '') { + $this->object_type = $v; + $this->modifiedColumns[] = CalendarAssignmentsPeer::OBJECT_TYPE; + } + + } // setObjectType() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->object_uid = $rs->getString($startcol + 0); + + $this->calendar_uid = $rs->getString($startcol + 1); + + $this->object_type = $rs->getString($startcol + 2); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 3; // 3 = CalendarAssignmentsPeer::NUM_COLUMNS - CalendarAssignmentsPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CalendarAssignments object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarAssignmentsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CalendarAssignmentsPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarAssignmentsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CalendarAssignmentsPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CalendarAssignmentsPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CalendarAssignmentsPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarAssignmentsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getObjectUid(); + break; + case 1: + return $this->getCalendarUid(); + break; + case 2: + return $this->getObjectType(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarAssignmentsPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getObjectUid(), + $keys[1] => $this->getCalendarUid(), + $keys[2] => $this->getObjectType(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarAssignmentsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setObjectUid($value); + break; + case 1: + $this->setCalendarUid($value); + break; + case 2: + $this->setObjectType($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarAssignmentsPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setObjectUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCalendarUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setObjectType($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CalendarAssignmentsPeer::DATABASE_NAME); + + if ($this->isColumnModified(CalendarAssignmentsPeer::OBJECT_UID)) $criteria->add(CalendarAssignmentsPeer::OBJECT_UID, $this->object_uid); + if ($this->isColumnModified(CalendarAssignmentsPeer::CALENDAR_UID)) $criteria->add(CalendarAssignmentsPeer::CALENDAR_UID, $this->calendar_uid); + if ($this->isColumnModified(CalendarAssignmentsPeer::OBJECT_TYPE)) $criteria->add(CalendarAssignmentsPeer::OBJECT_TYPE, $this->object_type); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CalendarAssignmentsPeer::DATABASE_NAME); + + $criteria->add(CalendarAssignmentsPeer::OBJECT_UID, $this->object_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getObjectUid(); + } + + /** + * Generic method to set the primary key (object_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setObjectUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CalendarAssignments (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCalendarUid($this->calendar_uid); + + $copyObj->setObjectType($this->object_type); + + + $copyObj->setNew(true); + + $copyObj->setObjectUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CalendarAssignments Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CalendarAssignmentsPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CalendarAssignmentsPeer(); + } + return self::$peer; + } + +} // BaseCalendarAssignments diff --git a/workflow/engine/classes/model/om/BaseCalendarAssignmentsPeer.php b/workflow/engine/classes/model/om/BaseCalendarAssignmentsPeer.php new file mode 100644 index 000000000..a09ed8d69 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarAssignmentsPeer.php @@ -0,0 +1,575 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CalendarAssignmentsPeer::getOMClass() +include_once 'classes/model/CalendarAssignments.php'; + +/** + * Base static class for performing query and update operations on the 'CALENDAR_ASSIGNMENTS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarAssignmentsPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CALENDAR_ASSIGNMENTS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CalendarAssignments'; + + /** The total number of columns. */ + const NUM_COLUMNS = 3; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the OBJECT_UID field */ + const OBJECT_UID = 'CALENDAR_ASSIGNMENTS.OBJECT_UID'; + + /** the column name for the CALENDAR_UID field */ + const CALENDAR_UID = 'CALENDAR_ASSIGNMENTS.CALENDAR_UID'; + + /** the column name for the OBJECT_TYPE field */ + const OBJECT_TYPE = 'CALENDAR_ASSIGNMENTS.OBJECT_TYPE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ObjectUid', 'CalendarUid', 'ObjectType', ), + BasePeer::TYPE_COLNAME => array (CalendarAssignmentsPeer::OBJECT_UID, CalendarAssignmentsPeer::CALENDAR_UID, CalendarAssignmentsPeer::OBJECT_TYPE, ), + BasePeer::TYPE_FIELDNAME => array ('OBJECT_UID', 'CALENDAR_UID', 'OBJECT_TYPE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ObjectUid' => 0, 'CalendarUid' => 1, 'ObjectType' => 2, ), + BasePeer::TYPE_COLNAME => array (CalendarAssignmentsPeer::OBJECT_UID => 0, CalendarAssignmentsPeer::CALENDAR_UID => 1, CalendarAssignmentsPeer::OBJECT_TYPE => 2, ), + BasePeer::TYPE_FIELDNAME => array ('OBJECT_UID' => 0, 'CALENDAR_UID' => 1, 'OBJECT_TYPE' => 2, ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CalendarAssignmentsMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CalendarAssignmentsMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CalendarAssignmentsPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CalendarAssignmentsPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CalendarAssignmentsPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CalendarAssignmentsPeer::OBJECT_UID); + + $criteria->addSelectColumn(CalendarAssignmentsPeer::CALENDAR_UID); + + $criteria->addSelectColumn(CalendarAssignmentsPeer::OBJECT_TYPE); + + } + + const COUNT = 'COUNT(CALENDAR_ASSIGNMENTS.OBJECT_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CALENDAR_ASSIGNMENTS.OBJECT_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CalendarAssignmentsPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CalendarAssignmentsPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CalendarAssignmentsPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CalendarAssignments + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CalendarAssignmentsPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CalendarAssignmentsPeer::populateObjects(CalendarAssignmentsPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CalendarAssignmentsPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CalendarAssignmentsPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CalendarAssignmentsPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CalendarAssignments or Criteria object. + * + * @param mixed $values Criteria or CalendarAssignments object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CalendarAssignments object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CalendarAssignments or Criteria object. + * + * @param mixed $values Criteria or CalendarAssignments object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CalendarAssignmentsPeer::OBJECT_UID); + $selectCriteria->add(CalendarAssignmentsPeer::OBJECT_UID, $criteria->remove(CalendarAssignmentsPeer::OBJECT_UID), $comparison); + + } else { // $values is CalendarAssignments object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CALENDAR_ASSIGNMENTS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CalendarAssignmentsPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CalendarAssignments or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CalendarAssignments object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CalendarAssignmentsPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CalendarAssignments) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(CalendarAssignmentsPeer::OBJECT_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CalendarAssignments object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CalendarAssignments $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CalendarAssignments $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CalendarAssignmentsPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CalendarAssignmentsPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(CalendarAssignmentsPeer::DATABASE_NAME, CalendarAssignmentsPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return CalendarAssignments + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(CalendarAssignmentsPeer::DATABASE_NAME); + + $criteria->add(CalendarAssignmentsPeer::OBJECT_UID, $pk); + + + $v = CalendarAssignmentsPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(CalendarAssignmentsPeer::OBJECT_UID, $pks, Criteria::IN); + $objs = CalendarAssignmentsPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseCalendarAssignmentsPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCalendarAssignmentsPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CalendarAssignmentsMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CalendarAssignmentsMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCalendarBusinessHours.php b/workflow/engine/classes/model/om/BaseCalendarBusinessHours.php new file mode 100644 index 000000000..7a0249f40 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarBusinessHours.php @@ -0,0 +1,685 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CalendarBusinessHoursPeer.php'; + +/** + * Base class that represents a row from the 'CALENDAR_BUSINESS_HOURS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarBusinessHours extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CalendarBusinessHoursPeer + */ + protected static $peer; + + + /** + * The value for the calendar_uid field. + * @var string + */ + protected $calendar_uid = ''; + + + /** + * The value for the calendar_business_day field. + * @var string + */ + protected $calendar_business_day = ''; + + + /** + * The value for the calendar_business_start field. + * @var string + */ + protected $calendar_business_start = ''; + + + /** + * The value for the calendar_business_end field. + * @var string + */ + protected $calendar_business_end = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [calendar_uid] column value. + * + * @return string + */ + public function getCalendarUid() + { + + return $this->calendar_uid; + } + + /** + * Get the [calendar_business_day] column value. + * + * @return string + */ + public function getCalendarBusinessDay() + { + + return $this->calendar_business_day; + } + + /** + * Get the [calendar_business_start] column value. + * + * @return string + */ + public function getCalendarBusinessStart() + { + + return $this->calendar_business_start; + } + + /** + * Get the [calendar_business_end] column value. + * + * @return string + */ + public function getCalendarBusinessEnd() + { + + return $this->calendar_business_end; + } + + /** + * Set the value of [calendar_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_uid !== $v || $v === '') { + $this->calendar_uid = $v; + $this->modifiedColumns[] = CalendarBusinessHoursPeer::CALENDAR_UID; + } + + } // setCalendarUid() + + /** + * Set the value of [calendar_business_day] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarBusinessDay($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_business_day !== $v || $v === '') { + $this->calendar_business_day = $v; + $this->modifiedColumns[] = CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY; + } + + } // setCalendarBusinessDay() + + /** + * Set the value of [calendar_business_start] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarBusinessStart($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_business_start !== $v || $v === '') { + $this->calendar_business_start = $v; + $this->modifiedColumns[] = CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START; + } + + } // setCalendarBusinessStart() + + /** + * Set the value of [calendar_business_end] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarBusinessEnd($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_business_end !== $v || $v === '') { + $this->calendar_business_end = $v; + $this->modifiedColumns[] = CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END; + } + + } // setCalendarBusinessEnd() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->calendar_uid = $rs->getString($startcol + 0); + + $this->calendar_business_day = $rs->getString($startcol + 1); + + $this->calendar_business_start = $rs->getString($startcol + 2); + + $this->calendar_business_end = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = CalendarBusinessHoursPeer::NUM_COLUMNS - CalendarBusinessHoursPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CalendarBusinessHours object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarBusinessHoursPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CalendarBusinessHoursPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarBusinessHoursPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CalendarBusinessHoursPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CalendarBusinessHoursPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CalendarBusinessHoursPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarBusinessHoursPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCalendarUid(); + break; + case 1: + return $this->getCalendarBusinessDay(); + break; + case 2: + return $this->getCalendarBusinessStart(); + break; + case 3: + return $this->getCalendarBusinessEnd(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarBusinessHoursPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCalendarUid(), + $keys[1] => $this->getCalendarBusinessDay(), + $keys[2] => $this->getCalendarBusinessStart(), + $keys[3] => $this->getCalendarBusinessEnd(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarBusinessHoursPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCalendarUid($value); + break; + case 1: + $this->setCalendarBusinessDay($value); + break; + case 2: + $this->setCalendarBusinessStart($value); + break; + case 3: + $this->setCalendarBusinessEnd($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarBusinessHoursPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCalendarUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCalendarBusinessDay($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCalendarBusinessStart($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCalendarBusinessEnd($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CalendarBusinessHoursPeer::DATABASE_NAME); + + if ($this->isColumnModified(CalendarBusinessHoursPeer::CALENDAR_UID)) $criteria->add(CalendarBusinessHoursPeer::CALENDAR_UID, $this->calendar_uid); + if ($this->isColumnModified(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY)) $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, $this->calendar_business_day); + if ($this->isColumnModified(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START)) $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, $this->calendar_business_start); + if ($this->isColumnModified(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END)) $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, $this->calendar_business_end); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CalendarBusinessHoursPeer::DATABASE_NAME); + + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_UID, $this->calendar_uid); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, $this->calendar_business_day); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, $this->calendar_business_start); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, $this->calendar_business_end); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getCalendarUid(); + + $pks[1] = $this->getCalendarBusinessDay(); + + $pks[2] = $this->getCalendarBusinessStart(); + + $pks[3] = $this->getCalendarBusinessEnd(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setCalendarUid($keys[0]); + + $this->setCalendarBusinessDay($keys[1]); + + $this->setCalendarBusinessStart($keys[2]); + + $this->setCalendarBusinessEnd($keys[3]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CalendarBusinessHours (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + + $copyObj->setNew(true); + + $copyObj->setCalendarUid(''); // this is a pkey column, so set to default value + + $copyObj->setCalendarBusinessDay(''); // this is a pkey column, so set to default value + + $copyObj->setCalendarBusinessStart(''); // this is a pkey column, so set to default value + + $copyObj->setCalendarBusinessEnd(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CalendarBusinessHours Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CalendarBusinessHoursPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CalendarBusinessHoursPeer(); + } + return self::$peer; + } + +} // BaseCalendarBusinessHours diff --git a/workflow/engine/classes/model/om/BaseCalendarBusinessHoursPeer.php b/workflow/engine/classes/model/om/BaseCalendarBusinessHoursPeer.php new file mode 100644 index 000000000..caf20335e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarBusinessHoursPeer.php @@ -0,0 +1,588 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CalendarBusinessHoursPeer::getOMClass() +include_once 'classes/model/CalendarBusinessHours.php'; + +/** + * Base static class for performing query and update operations on the 'CALENDAR_BUSINESS_HOURS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarBusinessHoursPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CALENDAR_BUSINESS_HOURS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CalendarBusinessHours'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CALENDAR_UID field */ + const CALENDAR_UID = 'CALENDAR_BUSINESS_HOURS.CALENDAR_UID'; + + /** the column name for the CALENDAR_BUSINESS_DAY field */ + const CALENDAR_BUSINESS_DAY = 'CALENDAR_BUSINESS_HOURS.CALENDAR_BUSINESS_DAY'; + + /** the column name for the CALENDAR_BUSINESS_START field */ + const CALENDAR_BUSINESS_START = 'CALENDAR_BUSINESS_HOURS.CALENDAR_BUSINESS_START'; + + /** the column name for the CALENDAR_BUSINESS_END field */ + const CALENDAR_BUSINESS_END = 'CALENDAR_BUSINESS_HOURS.CALENDAR_BUSINESS_END'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid', 'CalendarBusinessDay', 'CalendarBusinessStart', 'CalendarBusinessEnd', ), + BasePeer::TYPE_COLNAME => array (CalendarBusinessHoursPeer::CALENDAR_UID, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID', 'CALENDAR_BUSINESS_DAY', 'CALENDAR_BUSINESS_START', 'CALENDAR_BUSINESS_END', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid' => 0, 'CalendarBusinessDay' => 1, 'CalendarBusinessStart' => 2, 'CalendarBusinessEnd' => 3, ), + BasePeer::TYPE_COLNAME => array (CalendarBusinessHoursPeer::CALENDAR_UID => 0, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY => 1, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START => 2, CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END => 3, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID' => 0, 'CALENDAR_BUSINESS_DAY' => 1, 'CALENDAR_BUSINESS_START' => 2, 'CALENDAR_BUSINESS_END' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CalendarBusinessHoursMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CalendarBusinessHoursMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CalendarBusinessHoursPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CalendarBusinessHoursPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CalendarBusinessHoursPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CalendarBusinessHoursPeer::CALENDAR_UID); + + $criteria->addSelectColumn(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY); + + $criteria->addSelectColumn(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START); + + $criteria->addSelectColumn(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END); + + } + + const COUNT = 'COUNT(CALENDAR_BUSINESS_HOURS.CALENDAR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CALENDAR_BUSINESS_HOURS.CALENDAR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CalendarBusinessHoursPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CalendarBusinessHoursPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CalendarBusinessHoursPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CalendarBusinessHours + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CalendarBusinessHoursPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CalendarBusinessHoursPeer::populateObjects(CalendarBusinessHoursPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CalendarBusinessHoursPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CalendarBusinessHoursPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CalendarBusinessHoursPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CalendarBusinessHours or Criteria object. + * + * @param mixed $values Criteria or CalendarBusinessHours object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CalendarBusinessHours object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CalendarBusinessHours or Criteria object. + * + * @param mixed $values Criteria or CalendarBusinessHours object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CalendarBusinessHoursPeer::CALENDAR_UID); + $selectCriteria->add(CalendarBusinessHoursPeer::CALENDAR_UID, $criteria->remove(CalendarBusinessHoursPeer::CALENDAR_UID), $comparison); + + $comparison = $criteria->getComparison(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY); + $selectCriteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, $criteria->remove(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY), $comparison); + + $comparison = $criteria->getComparison(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START); + $selectCriteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, $criteria->remove(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START), $comparison); + + $comparison = $criteria->getComparison(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END); + $selectCriteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, $criteria->remove(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END), $comparison); + + } else { // $values is CalendarBusinessHours object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CALENDAR_BUSINESS_HOURS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CalendarBusinessHoursPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CalendarBusinessHours or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CalendarBusinessHours object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CalendarBusinessHoursPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CalendarBusinessHours) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + } + + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_UID, $vals[0], Criteria::IN); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, $vals[1], Criteria::IN); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, $vals[2], Criteria::IN); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, $vals[3], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CalendarBusinessHours object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CalendarBusinessHours $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CalendarBusinessHours $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CalendarBusinessHoursPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CalendarBusinessHoursPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY)) + $columns[CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY] = $obj->getCalendarBusinessDay(); + + } + + return BasePeer::doValidate(CalendarBusinessHoursPeer::DATABASE_NAME, CalendarBusinessHoursPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $calendar_uid + @param string $calendar_business_day + @param string $calendar_business_start + @param string $calendar_business_end + + * @param Connection $con + * @return CalendarBusinessHours + */ + public static function retrieveByPK( $calendar_uid, $calendar_business_day, $calendar_business_start, $calendar_business_end, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_UID, $calendar_uid); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_DAY, $calendar_business_day); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_START, $calendar_business_start); + $criteria->add(CalendarBusinessHoursPeer::CALENDAR_BUSINESS_END, $calendar_business_end); + $v = CalendarBusinessHoursPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseCalendarBusinessHoursPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCalendarBusinessHoursPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CalendarBusinessHoursMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CalendarBusinessHoursMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCalendarDefinition.php b/workflow/engine/classes/model/om/BaseCalendarDefinition.php new file mode 100644 index 000000000..0804708ce --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarDefinition.php @@ -0,0 +1,866 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CalendarDefinitionPeer.php'; + +/** + * Base class that represents a row from the 'CALENDAR_DEFINITION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarDefinition extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CalendarDefinitionPeer + */ + protected static $peer; + + + /** + * The value for the calendar_uid field. + * @var string + */ + protected $calendar_uid = ''; + + + /** + * The value for the calendar_name field. + * @var string + */ + protected $calendar_name = ''; + + + /** + * The value for the calendar_create_date field. + * @var int + */ + protected $calendar_create_date; + + + /** + * The value for the calendar_update_date field. + * @var int + */ + protected $calendar_update_date; + + + /** + * The value for the calendar_work_days field. + * @var string + */ + protected $calendar_work_days = ''; + + + /** + * The value for the calendar_description field. + * @var string + */ + protected $calendar_description; + + + /** + * The value for the calendar_status field. + * @var string + */ + protected $calendar_status = 'ACTIVE'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [calendar_uid] column value. + * + * @return string + */ + public function getCalendarUid() + { + + return $this->calendar_uid; + } + + /** + * Get the [calendar_name] column value. + * + * @return string + */ + public function getCalendarName() + { + + return $this->calendar_name; + } + + /** + * Get the [optionally formatted] [calendar_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getCalendarCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->calendar_create_date === null || $this->calendar_create_date === '') { + return null; + } elseif (!is_int($this->calendar_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->calendar_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [calendar_create_date] as date/time value: " . var_export($this->calendar_create_date, true)); + } + } else { + $ts = $this->calendar_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [calendar_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getCalendarUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->calendar_update_date === null || $this->calendar_update_date === '') { + return null; + } elseif (!is_int($this->calendar_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->calendar_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [calendar_update_date] as date/time value: " . var_export($this->calendar_update_date, true)); + } + } else { + $ts = $this->calendar_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [calendar_work_days] column value. + * + * @return string + */ + public function getCalendarWorkDays() + { + + return $this->calendar_work_days; + } + + /** + * Get the [calendar_description] column value. + * + * @return string + */ + public function getCalendarDescription() + { + + return $this->calendar_description; + } + + /** + * Get the [calendar_status] column value. + * + * @return string + */ + public function getCalendarStatus() + { + + return $this->calendar_status; + } + + /** + * Set the value of [calendar_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_uid !== $v || $v === '') { + $this->calendar_uid = $v; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_UID; + } + + } // setCalendarUid() + + /** + * Set the value of [calendar_name] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_name !== $v || $v === '') { + $this->calendar_name = $v; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_NAME; + } + + } // setCalendarName() + + /** + * Set the value of [calendar_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setCalendarCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [calendar_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->calendar_create_date !== $ts) { + $this->calendar_create_date = $ts; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_CREATE_DATE; + } + + } // setCalendarCreateDate() + + /** + * Set the value of [calendar_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setCalendarUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [calendar_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->calendar_update_date !== $ts) { + $this->calendar_update_date = $ts; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_UPDATE_DATE; + } + + } // setCalendarUpdateDate() + + /** + * Set the value of [calendar_work_days] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarWorkDays($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_work_days !== $v || $v === '') { + $this->calendar_work_days = $v; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_WORK_DAYS; + } + + } // setCalendarWorkDays() + + /** + * Set the value of [calendar_description] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarDescription($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_description !== $v) { + $this->calendar_description = $v; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_DESCRIPTION; + } + + } // setCalendarDescription() + + /** + * Set the value of [calendar_status] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_status !== $v || $v === 'ACTIVE') { + $this->calendar_status = $v; + $this->modifiedColumns[] = CalendarDefinitionPeer::CALENDAR_STATUS; + } + + } // setCalendarStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->calendar_uid = $rs->getString($startcol + 0); + + $this->calendar_name = $rs->getString($startcol + 1); + + $this->calendar_create_date = $rs->getTimestamp($startcol + 2, null); + + $this->calendar_update_date = $rs->getTimestamp($startcol + 3, null); + + $this->calendar_work_days = $rs->getString($startcol + 4); + + $this->calendar_description = $rs->getString($startcol + 5); + + $this->calendar_status = $rs->getString($startcol + 6); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = CalendarDefinitionPeer::NUM_COLUMNS - CalendarDefinitionPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CalendarDefinition object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarDefinitionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CalendarDefinitionPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarDefinitionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CalendarDefinitionPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CalendarDefinitionPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CalendarDefinitionPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarDefinitionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCalendarUid(); + break; + case 1: + return $this->getCalendarName(); + break; + case 2: + return $this->getCalendarCreateDate(); + break; + case 3: + return $this->getCalendarUpdateDate(); + break; + case 4: + return $this->getCalendarWorkDays(); + break; + case 5: + return $this->getCalendarDescription(); + break; + case 6: + return $this->getCalendarStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarDefinitionPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCalendarUid(), + $keys[1] => $this->getCalendarName(), + $keys[2] => $this->getCalendarCreateDate(), + $keys[3] => $this->getCalendarUpdateDate(), + $keys[4] => $this->getCalendarWorkDays(), + $keys[5] => $this->getCalendarDescription(), + $keys[6] => $this->getCalendarStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarDefinitionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCalendarUid($value); + break; + case 1: + $this->setCalendarName($value); + break; + case 2: + $this->setCalendarCreateDate($value); + break; + case 3: + $this->setCalendarUpdateDate($value); + break; + case 4: + $this->setCalendarWorkDays($value); + break; + case 5: + $this->setCalendarDescription($value); + break; + case 6: + $this->setCalendarStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarDefinitionPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCalendarUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCalendarName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCalendarCreateDate($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCalendarUpdateDate($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCalendarWorkDays($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setCalendarDescription($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setCalendarStatus($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CalendarDefinitionPeer::DATABASE_NAME); + + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_UID)) $criteria->add(CalendarDefinitionPeer::CALENDAR_UID, $this->calendar_uid); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_NAME)) $criteria->add(CalendarDefinitionPeer::CALENDAR_NAME, $this->calendar_name); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_CREATE_DATE)) $criteria->add(CalendarDefinitionPeer::CALENDAR_CREATE_DATE, $this->calendar_create_date); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_UPDATE_DATE)) $criteria->add(CalendarDefinitionPeer::CALENDAR_UPDATE_DATE, $this->calendar_update_date); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_WORK_DAYS)) $criteria->add(CalendarDefinitionPeer::CALENDAR_WORK_DAYS, $this->calendar_work_days); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_DESCRIPTION)) $criteria->add(CalendarDefinitionPeer::CALENDAR_DESCRIPTION, $this->calendar_description); + if ($this->isColumnModified(CalendarDefinitionPeer::CALENDAR_STATUS)) $criteria->add(CalendarDefinitionPeer::CALENDAR_STATUS, $this->calendar_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CalendarDefinitionPeer::DATABASE_NAME); + + $criteria->add(CalendarDefinitionPeer::CALENDAR_UID, $this->calendar_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getCalendarUid(); + } + + /** + * Generic method to set the primary key (calendar_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setCalendarUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CalendarDefinition (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCalendarName($this->calendar_name); + + $copyObj->setCalendarCreateDate($this->calendar_create_date); + + $copyObj->setCalendarUpdateDate($this->calendar_update_date); + + $copyObj->setCalendarWorkDays($this->calendar_work_days); + + $copyObj->setCalendarDescription($this->calendar_description); + + $copyObj->setCalendarStatus($this->calendar_status); + + + $copyObj->setNew(true); + + $copyObj->setCalendarUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CalendarDefinition Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CalendarDefinitionPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CalendarDefinitionPeer(); + } + return self::$peer; + } + +} // BaseCalendarDefinition diff --git a/workflow/engine/classes/model/om/BaseCalendarDefinitionPeer.php b/workflow/engine/classes/model/om/BaseCalendarDefinitionPeer.php new file mode 100644 index 000000000..48ac859d0 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarDefinitionPeer.php @@ -0,0 +1,598 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CalendarDefinitionPeer::getOMClass() +include_once 'classes/model/CalendarDefinition.php'; + +/** + * Base static class for performing query and update operations on the 'CALENDAR_DEFINITION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarDefinitionPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CALENDAR_DEFINITION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CalendarDefinition'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CALENDAR_UID field */ + const CALENDAR_UID = 'CALENDAR_DEFINITION.CALENDAR_UID'; + + /** the column name for the CALENDAR_NAME field */ + const CALENDAR_NAME = 'CALENDAR_DEFINITION.CALENDAR_NAME'; + + /** the column name for the CALENDAR_CREATE_DATE field */ + const CALENDAR_CREATE_DATE = 'CALENDAR_DEFINITION.CALENDAR_CREATE_DATE'; + + /** the column name for the CALENDAR_UPDATE_DATE field */ + const CALENDAR_UPDATE_DATE = 'CALENDAR_DEFINITION.CALENDAR_UPDATE_DATE'; + + /** the column name for the CALENDAR_WORK_DAYS field */ + const CALENDAR_WORK_DAYS = 'CALENDAR_DEFINITION.CALENDAR_WORK_DAYS'; + + /** the column name for the CALENDAR_DESCRIPTION field */ + const CALENDAR_DESCRIPTION = 'CALENDAR_DEFINITION.CALENDAR_DESCRIPTION'; + + /** the column name for the CALENDAR_STATUS field */ + const CALENDAR_STATUS = 'CALENDAR_DEFINITION.CALENDAR_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid', 'CalendarName', 'CalendarCreateDate', 'CalendarUpdateDate', 'CalendarWorkDays', 'CalendarDescription', 'CalendarStatus', ), + BasePeer::TYPE_COLNAME => array (CalendarDefinitionPeer::CALENDAR_UID, CalendarDefinitionPeer::CALENDAR_NAME, CalendarDefinitionPeer::CALENDAR_CREATE_DATE, CalendarDefinitionPeer::CALENDAR_UPDATE_DATE, CalendarDefinitionPeer::CALENDAR_WORK_DAYS, CalendarDefinitionPeer::CALENDAR_DESCRIPTION, CalendarDefinitionPeer::CALENDAR_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID', 'CALENDAR_NAME', 'CALENDAR_CREATE_DATE', 'CALENDAR_UPDATE_DATE', 'CALENDAR_WORK_DAYS', 'CALENDAR_DESCRIPTION', 'CALENDAR_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid' => 0, 'CalendarName' => 1, 'CalendarCreateDate' => 2, 'CalendarUpdateDate' => 3, 'CalendarWorkDays' => 4, 'CalendarDescription' => 5, 'CalendarStatus' => 6, ), + BasePeer::TYPE_COLNAME => array (CalendarDefinitionPeer::CALENDAR_UID => 0, CalendarDefinitionPeer::CALENDAR_NAME => 1, CalendarDefinitionPeer::CALENDAR_CREATE_DATE => 2, CalendarDefinitionPeer::CALENDAR_UPDATE_DATE => 3, CalendarDefinitionPeer::CALENDAR_WORK_DAYS => 4, CalendarDefinitionPeer::CALENDAR_DESCRIPTION => 5, CalendarDefinitionPeer::CALENDAR_STATUS => 6, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID' => 0, 'CALENDAR_NAME' => 1, 'CALENDAR_CREATE_DATE' => 2, 'CALENDAR_UPDATE_DATE' => 3, 'CALENDAR_WORK_DAYS' => 4, 'CALENDAR_DESCRIPTION' => 5, 'CALENDAR_STATUS' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CalendarDefinitionMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CalendarDefinitionMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CalendarDefinitionPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CalendarDefinitionPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CalendarDefinitionPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_UID); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_NAME); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_CREATE_DATE); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_UPDATE_DATE); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_WORK_DAYS); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_DESCRIPTION); + + $criteria->addSelectColumn(CalendarDefinitionPeer::CALENDAR_STATUS); + + } + + const COUNT = 'COUNT(CALENDAR_DEFINITION.CALENDAR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CALENDAR_DEFINITION.CALENDAR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CalendarDefinitionPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CalendarDefinitionPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CalendarDefinitionPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CalendarDefinition + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CalendarDefinitionPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CalendarDefinitionPeer::populateObjects(CalendarDefinitionPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CalendarDefinitionPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CalendarDefinitionPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CalendarDefinitionPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CalendarDefinition or Criteria object. + * + * @param mixed $values Criteria or CalendarDefinition object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CalendarDefinition object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CalendarDefinition or Criteria object. + * + * @param mixed $values Criteria or CalendarDefinition object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CalendarDefinitionPeer::CALENDAR_UID); + $selectCriteria->add(CalendarDefinitionPeer::CALENDAR_UID, $criteria->remove(CalendarDefinitionPeer::CALENDAR_UID), $comparison); + + } else { // $values is CalendarDefinition object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CALENDAR_DEFINITION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CalendarDefinitionPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CalendarDefinition or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CalendarDefinition object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CalendarDefinitionPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CalendarDefinition) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(CalendarDefinitionPeer::CALENDAR_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CalendarDefinition object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CalendarDefinition $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CalendarDefinition $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CalendarDefinitionPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CalendarDefinitionPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(CalendarDefinitionPeer::CALENDAR_STATUS)) + $columns[CalendarDefinitionPeer::CALENDAR_STATUS] = $obj->getCalendarStatus(); + + } + + return BasePeer::doValidate(CalendarDefinitionPeer::DATABASE_NAME, CalendarDefinitionPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return CalendarDefinition + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(CalendarDefinitionPeer::DATABASE_NAME); + + $criteria->add(CalendarDefinitionPeer::CALENDAR_UID, $pk); + + + $v = CalendarDefinitionPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(CalendarDefinitionPeer::CALENDAR_UID, $pks, Criteria::IN); + $objs = CalendarDefinitionPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseCalendarDefinitionPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCalendarDefinitionPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CalendarDefinitionMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CalendarDefinitionMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCalendarHolidays.php b/workflow/engine/classes/model/om/BaseCalendarHolidays.php new file mode 100644 index 000000000..db395478e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarHolidays.php @@ -0,0 +1,719 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CalendarHolidaysPeer.php'; + +/** + * Base class that represents a row from the 'CALENDAR_HOLIDAYS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarHolidays extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CalendarHolidaysPeer + */ + protected static $peer; + + + /** + * The value for the calendar_uid field. + * @var string + */ + protected $calendar_uid = ''; + + + /** + * The value for the calendar_holiday_name field. + * @var string + */ + protected $calendar_holiday_name = ''; + + + /** + * The value for the calendar_holiday_start field. + * @var int + */ + protected $calendar_holiday_start; + + + /** + * The value for the calendar_holiday_end field. + * @var int + */ + protected $calendar_holiday_end; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [calendar_uid] column value. + * + * @return string + */ + public function getCalendarUid() + { + + return $this->calendar_uid; + } + + /** + * Get the [calendar_holiday_name] column value. + * + * @return string + */ + public function getCalendarHolidayName() + { + + return $this->calendar_holiday_name; + } + + /** + * Get the [optionally formatted] [calendar_holiday_start] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getCalendarHolidayStart($format = 'Y-m-d H:i:s') + { + + if ($this->calendar_holiday_start === null || $this->calendar_holiday_start === '') { + return null; + } elseif (!is_int($this->calendar_holiday_start)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->calendar_holiday_start); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [calendar_holiday_start] as date/time value: " . var_export($this->calendar_holiday_start, true)); + } + } else { + $ts = $this->calendar_holiday_start; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [calendar_holiday_end] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getCalendarHolidayEnd($format = 'Y-m-d H:i:s') + { + + if ($this->calendar_holiday_end === null || $this->calendar_holiday_end === '') { + return null; + } elseif (!is_int($this->calendar_holiday_end)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->calendar_holiday_end); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [calendar_holiday_end] as date/time value: " . var_export($this->calendar_holiday_end, true)); + } + } else { + $ts = $this->calendar_holiday_end; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [calendar_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_uid !== $v || $v === '') { + $this->calendar_uid = $v; + $this->modifiedColumns[] = CalendarHolidaysPeer::CALENDAR_UID; + } + + } // setCalendarUid() + + /** + * Set the value of [calendar_holiday_name] column. + * + * @param string $v new value + * @return void + */ + public function setCalendarHolidayName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->calendar_holiday_name !== $v || $v === '') { + $this->calendar_holiday_name = $v; + $this->modifiedColumns[] = CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME; + } + + } // setCalendarHolidayName() + + /** + * Set the value of [calendar_holiday_start] column. + * + * @param int $v new value + * @return void + */ + public function setCalendarHolidayStart($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [calendar_holiday_start] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->calendar_holiday_start !== $ts) { + $this->calendar_holiday_start = $ts; + $this->modifiedColumns[] = CalendarHolidaysPeer::CALENDAR_HOLIDAY_START; + } + + } // setCalendarHolidayStart() + + /** + * Set the value of [calendar_holiday_end] column. + * + * @param int $v new value + * @return void + */ + public function setCalendarHolidayEnd($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [calendar_holiday_end] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->calendar_holiday_end !== $ts) { + $this->calendar_holiday_end = $ts; + $this->modifiedColumns[] = CalendarHolidaysPeer::CALENDAR_HOLIDAY_END; + } + + } // setCalendarHolidayEnd() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->calendar_uid = $rs->getString($startcol + 0); + + $this->calendar_holiday_name = $rs->getString($startcol + 1); + + $this->calendar_holiday_start = $rs->getTimestamp($startcol + 2, null); + + $this->calendar_holiday_end = $rs->getTimestamp($startcol + 3, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = CalendarHolidaysPeer::NUM_COLUMNS - CalendarHolidaysPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CalendarHolidays object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarHolidaysPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CalendarHolidaysPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CalendarHolidaysPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CalendarHolidaysPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CalendarHolidaysPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CalendarHolidaysPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarHolidaysPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCalendarUid(); + break; + case 1: + return $this->getCalendarHolidayName(); + break; + case 2: + return $this->getCalendarHolidayStart(); + break; + case 3: + return $this->getCalendarHolidayEnd(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarHolidaysPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCalendarUid(), + $keys[1] => $this->getCalendarHolidayName(), + $keys[2] => $this->getCalendarHolidayStart(), + $keys[3] => $this->getCalendarHolidayEnd(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CalendarHolidaysPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCalendarUid($value); + break; + case 1: + $this->setCalendarHolidayName($value); + break; + case 2: + $this->setCalendarHolidayStart($value); + break; + case 3: + $this->setCalendarHolidayEnd($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CalendarHolidaysPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCalendarUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCalendarHolidayName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCalendarHolidayStart($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCalendarHolidayEnd($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CalendarHolidaysPeer::DATABASE_NAME); + + if ($this->isColumnModified(CalendarHolidaysPeer::CALENDAR_UID)) $criteria->add(CalendarHolidaysPeer::CALENDAR_UID, $this->calendar_uid); + if ($this->isColumnModified(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME)) $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, $this->calendar_holiday_name); + if ($this->isColumnModified(CalendarHolidaysPeer::CALENDAR_HOLIDAY_START)) $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_START, $this->calendar_holiday_start); + if ($this->isColumnModified(CalendarHolidaysPeer::CALENDAR_HOLIDAY_END)) $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_END, $this->calendar_holiday_end); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CalendarHolidaysPeer::DATABASE_NAME); + + $criteria->add(CalendarHolidaysPeer::CALENDAR_UID, $this->calendar_uid); + $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, $this->calendar_holiday_name); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getCalendarUid(); + + $pks[1] = $this->getCalendarHolidayName(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setCalendarUid($keys[0]); + + $this->setCalendarHolidayName($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CalendarHolidays (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCalendarHolidayStart($this->calendar_holiday_start); + + $copyObj->setCalendarHolidayEnd($this->calendar_holiday_end); + + + $copyObj->setNew(true); + + $copyObj->setCalendarUid(''); // this is a pkey column, so set to default value + + $copyObj->setCalendarHolidayName(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CalendarHolidays Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CalendarHolidaysPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CalendarHolidaysPeer(); + } + return self::$peer; + } + +} // BaseCalendarHolidays diff --git a/workflow/engine/classes/model/om/BaseCalendarHolidaysPeer.php b/workflow/engine/classes/model/om/BaseCalendarHolidaysPeer.php new file mode 100644 index 000000000..bba36f400 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCalendarHolidaysPeer.php @@ -0,0 +1,571 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CalendarHolidaysPeer::getOMClass() +include_once 'classes/model/CalendarHolidays.php'; + +/** + * Base static class for performing query and update operations on the 'CALENDAR_HOLIDAYS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCalendarHolidaysPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CALENDAR_HOLIDAYS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CalendarHolidays'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CALENDAR_UID field */ + const CALENDAR_UID = 'CALENDAR_HOLIDAYS.CALENDAR_UID'; + + /** the column name for the CALENDAR_HOLIDAY_NAME field */ + const CALENDAR_HOLIDAY_NAME = 'CALENDAR_HOLIDAYS.CALENDAR_HOLIDAY_NAME'; + + /** the column name for the CALENDAR_HOLIDAY_START field */ + const CALENDAR_HOLIDAY_START = 'CALENDAR_HOLIDAYS.CALENDAR_HOLIDAY_START'; + + /** the column name for the CALENDAR_HOLIDAY_END field */ + const CALENDAR_HOLIDAY_END = 'CALENDAR_HOLIDAYS.CALENDAR_HOLIDAY_END'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid', 'CalendarHolidayName', 'CalendarHolidayStart', 'CalendarHolidayEnd', ), + BasePeer::TYPE_COLNAME => array (CalendarHolidaysPeer::CALENDAR_UID, CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, CalendarHolidaysPeer::CALENDAR_HOLIDAY_START, CalendarHolidaysPeer::CALENDAR_HOLIDAY_END, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID', 'CALENDAR_HOLIDAY_NAME', 'CALENDAR_HOLIDAY_START', 'CALENDAR_HOLIDAY_END', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CalendarUid' => 0, 'CalendarHolidayName' => 1, 'CalendarHolidayStart' => 2, 'CalendarHolidayEnd' => 3, ), + BasePeer::TYPE_COLNAME => array (CalendarHolidaysPeer::CALENDAR_UID => 0, CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME => 1, CalendarHolidaysPeer::CALENDAR_HOLIDAY_START => 2, CalendarHolidaysPeer::CALENDAR_HOLIDAY_END => 3, ), + BasePeer::TYPE_FIELDNAME => array ('CALENDAR_UID' => 0, 'CALENDAR_HOLIDAY_NAME' => 1, 'CALENDAR_HOLIDAY_START' => 2, 'CALENDAR_HOLIDAY_END' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CalendarHolidaysMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CalendarHolidaysMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CalendarHolidaysPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CalendarHolidaysPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CalendarHolidaysPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CalendarHolidaysPeer::CALENDAR_UID); + + $criteria->addSelectColumn(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME); + + $criteria->addSelectColumn(CalendarHolidaysPeer::CALENDAR_HOLIDAY_START); + + $criteria->addSelectColumn(CalendarHolidaysPeer::CALENDAR_HOLIDAY_END); + + } + + const COUNT = 'COUNT(CALENDAR_HOLIDAYS.CALENDAR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CALENDAR_HOLIDAYS.CALENDAR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CalendarHolidaysPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CalendarHolidaysPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CalendarHolidaysPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CalendarHolidays + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CalendarHolidaysPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CalendarHolidaysPeer::populateObjects(CalendarHolidaysPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CalendarHolidaysPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CalendarHolidaysPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CalendarHolidaysPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CalendarHolidays or Criteria object. + * + * @param mixed $values Criteria or CalendarHolidays object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CalendarHolidays object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CalendarHolidays or Criteria object. + * + * @param mixed $values Criteria or CalendarHolidays object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CalendarHolidaysPeer::CALENDAR_UID); + $selectCriteria->add(CalendarHolidaysPeer::CALENDAR_UID, $criteria->remove(CalendarHolidaysPeer::CALENDAR_UID), $comparison); + + $comparison = $criteria->getComparison(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME); + $selectCriteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, $criteria->remove(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME), $comparison); + + } else { // $values is CalendarHolidays object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CALENDAR_HOLIDAYS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CalendarHolidaysPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CalendarHolidays or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CalendarHolidays object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CalendarHolidaysPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CalendarHolidays) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(CalendarHolidaysPeer::CALENDAR_UID, $vals[0], Criteria::IN); + $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CalendarHolidays object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CalendarHolidays $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CalendarHolidays $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CalendarHolidaysPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CalendarHolidaysPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(CalendarHolidaysPeer::DATABASE_NAME, CalendarHolidaysPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $calendar_uid + @param string $calendar_holiday_name + + * @param Connection $con + * @return CalendarHolidays + */ + public static function retrieveByPK( $calendar_uid, $calendar_holiday_name, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(CalendarHolidaysPeer::CALENDAR_UID, $calendar_uid); + $criteria->add(CalendarHolidaysPeer::CALENDAR_HOLIDAY_NAME, $calendar_holiday_name); + $v = CalendarHolidaysPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseCalendarHolidaysPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCalendarHolidaysPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CalendarHolidaysMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CalendarHolidaysMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCaseScheduler.php b/workflow/engine/classes/model/om/BaseCaseScheduler.php new file mode 100644 index 000000000..a825f6aed --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseScheduler.php @@ -0,0 +1,1886 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CaseSchedulerPeer.php'; + +/** + * Base class that represents a row from the 'CASE_SCHEDULER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseScheduler extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CaseSchedulerPeer + */ + protected static $peer; + + + /** + * The value for the sch_uid field. + * @var string + */ + protected $sch_uid; + + + /** + * The value for the sch_del_user_name field. + * @var string + */ + protected $sch_del_user_name; + + + /** + * The value for the sch_del_user_pass field. + * @var string + */ + protected $sch_del_user_pass; + + + /** + * The value for the sch_del_user_uid field. + * @var string + */ + protected $sch_del_user_uid; + + + /** + * The value for the sch_name field. + * @var string + */ + protected $sch_name; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the sch_time_next_run field. + * @var int + */ + protected $sch_time_next_run; + + + /** + * The value for the sch_last_run_time field. + * @var int + */ + protected $sch_last_run_time; + + + /** + * The value for the sch_state field. + * @var string + */ + protected $sch_state = 'ACTIVE'; + + + /** + * The value for the sch_last_state field. + * @var string + */ + protected $sch_last_state; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid; + + + /** + * The value for the sch_option field. + * @var int + */ + protected $sch_option = 0; + + + /** + * The value for the sch_start_time field. + * @var int + */ + protected $sch_start_time; + + + /** + * The value for the sch_start_date field. + * @var int + */ + protected $sch_start_date; + + + /** + * The value for the sch_days_perform_task field. + * @var string + */ + protected $sch_days_perform_task; + + + /** + * The value for the sch_every_days field. + * @var int + */ + protected $sch_every_days = 0; + + + /** + * The value for the sch_week_days field. + * @var string + */ + protected $sch_week_days = '0|0|0|0|0|0|0'; + + + /** + * The value for the sch_start_day field. + * @var string + */ + protected $sch_start_day; + + + /** + * The value for the sch_months field. + * @var string + */ + protected $sch_months = '0|0|0|0|0|0|0|0|0|0|0|0'; + + + /** + * The value for the sch_end_date field. + * @var int + */ + protected $sch_end_date; + + + /** + * The value for the sch_repeat_every field. + * @var string + */ + protected $sch_repeat_every; + + + /** + * The value for the sch_repeat_until field. + * @var string + */ + protected $sch_repeat_until; + + + /** + * The value for the sch_repeat_stop_if_running field. + * @var int + */ + protected $sch_repeat_stop_if_running = 0; + + + /** + * The value for the case_sh_plugin_uid field. + * @var string + */ + protected $case_sh_plugin_uid; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [sch_uid] column value. + * + * @return string + */ + public function getSchUid() + { + + return $this->sch_uid; + } + + /** + * Get the [sch_del_user_name] column value. + * + * @return string + */ + public function getSchDelUserName() + { + + return $this->sch_del_user_name; + } + + /** + * Get the [sch_del_user_pass] column value. + * + * @return string + */ + public function getSchDelUserPass() + { + + return $this->sch_del_user_pass; + } + + /** + * Get the [sch_del_user_uid] column value. + * + * @return string + */ + public function getSchDelUserUid() + { + + return $this->sch_del_user_uid; + } + + /** + * Get the [sch_name] column value. + * + * @return string + */ + public function getSchName() + { + + return $this->sch_name; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [optionally formatted] [sch_time_next_run] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSchTimeNextRun($format = 'Y-m-d H:i:s') + { + + if ($this->sch_time_next_run === null || $this->sch_time_next_run === '') { + return null; + } elseif (!is_int($this->sch_time_next_run)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sch_time_next_run); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sch_time_next_run] as date/time value: " . var_export($this->sch_time_next_run, true)); + } + } else { + $ts = $this->sch_time_next_run; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [sch_last_run_time] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSchLastRunTime($format = 'Y-m-d H:i:s') + { + + if ($this->sch_last_run_time === null || $this->sch_last_run_time === '') { + return null; + } elseif (!is_int($this->sch_last_run_time)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sch_last_run_time); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sch_last_run_time] as date/time value: " . var_export($this->sch_last_run_time, true)); + } + } else { + $ts = $this->sch_last_run_time; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [sch_state] column value. + * + * @return string + */ + public function getSchState() + { + + return $this->sch_state; + } + + /** + * Get the [sch_last_state] column value. + * + * @return string + */ + public function getSchLastState() + { + + return $this->sch_last_state; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [sch_option] column value. + * + * @return int + */ + public function getSchOption() + { + + return $this->sch_option; + } + + /** + * Get the [optionally formatted] [sch_start_time] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSchStartTime($format = 'Y-m-d H:i:s') + { + + if ($this->sch_start_time === null || $this->sch_start_time === '') { + return null; + } elseif (!is_int($this->sch_start_time)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sch_start_time); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sch_start_time] as date/time value: " . var_export($this->sch_start_time, true)); + } + } else { + $ts = $this->sch_start_time; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [sch_start_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSchStartDate($format = 'Y-m-d H:i:s') + { + + if ($this->sch_start_date === null || $this->sch_start_date === '') { + return null; + } elseif (!is_int($this->sch_start_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sch_start_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sch_start_date] as date/time value: " . var_export($this->sch_start_date, true)); + } + } else { + $ts = $this->sch_start_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [sch_days_perform_task] column value. + * + * @return string + */ + public function getSchDaysPerformTask() + { + + return $this->sch_days_perform_task; + } + + /** + * Get the [sch_every_days] column value. + * + * @return int + */ + public function getSchEveryDays() + { + + return $this->sch_every_days; + } + + /** + * Get the [sch_week_days] column value. + * + * @return string + */ + public function getSchWeekDays() + { + + return $this->sch_week_days; + } + + /** + * Get the [sch_start_day] column value. + * + * @return string + */ + public function getSchStartDay() + { + + return $this->sch_start_day; + } + + /** + * Get the [sch_months] column value. + * + * @return string + */ + public function getSchMonths() + { + + return $this->sch_months; + } + + /** + * Get the [optionally formatted] [sch_end_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSchEndDate($format = 'Y-m-d H:i:s') + { + + if ($this->sch_end_date === null || $this->sch_end_date === '') { + return null; + } elseif (!is_int($this->sch_end_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sch_end_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sch_end_date] as date/time value: " . var_export($this->sch_end_date, true)); + } + } else { + $ts = $this->sch_end_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [sch_repeat_every] column value. + * + * @return string + */ + public function getSchRepeatEvery() + { + + return $this->sch_repeat_every; + } + + /** + * Get the [sch_repeat_until] column value. + * + * @return string + */ + public function getSchRepeatUntil() + { + + return $this->sch_repeat_until; + } + + /** + * Get the [sch_repeat_stop_if_running] column value. + * + * @return int + */ + public function getSchRepeatStopIfRunning() + { + + return $this->sch_repeat_stop_if_running; + } + + /** + * Get the [case_sh_plugin_uid] column value. + * + * @return string + */ + public function getCaseShPluginUid() + { + + return $this->case_sh_plugin_uid; + } + + /** + * Set the value of [sch_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSchUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_uid !== $v) { + $this->sch_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_UID; + } + + } // setSchUid() + + /** + * Set the value of [sch_del_user_name] column. + * + * @param string $v new value + * @return void + */ + public function setSchDelUserName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_del_user_name !== $v) { + $this->sch_del_user_name = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_DEL_USER_NAME; + } + + } // setSchDelUserName() + + /** + * Set the value of [sch_del_user_pass] column. + * + * @param string $v new value + * @return void + */ + public function setSchDelUserPass($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_del_user_pass !== $v) { + $this->sch_del_user_pass = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_DEL_USER_PASS; + } + + } // setSchDelUserPass() + + /** + * Set the value of [sch_del_user_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSchDelUserUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_del_user_uid !== $v) { + $this->sch_del_user_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_DEL_USER_UID; + } + + } // setSchDelUserUid() + + /** + * Set the value of [sch_name] column. + * + * @param string $v new value + * @return void + */ + public function setSchName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_name !== $v) { + $this->sch_name = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_NAME; + } + + } // setSchName() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [sch_time_next_run] column. + * + * @param int $v new value + * @return void + */ + public function setSchTimeNextRun($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sch_time_next_run] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sch_time_next_run !== $ts) { + $this->sch_time_next_run = $ts; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_TIME_NEXT_RUN; + } + + } // setSchTimeNextRun() + + /** + * Set the value of [sch_last_run_time] column. + * + * @param int $v new value + * @return void + */ + public function setSchLastRunTime($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sch_last_run_time] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sch_last_run_time !== $ts) { + $this->sch_last_run_time = $ts; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_LAST_RUN_TIME; + } + + } // setSchLastRunTime() + + /** + * Set the value of [sch_state] column. + * + * @param string $v new value + * @return void + */ + public function setSchState($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_state !== $v || $v === 'ACTIVE') { + $this->sch_state = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_STATE; + } + + } // setSchState() + + /** + * Set the value of [sch_last_state] column. + * + * @param string $v new value + * @return void + */ + public function setSchLastState($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_last_state !== $v) { + $this->sch_last_state = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_LAST_STATE; + } + + } // setSchLastState() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v) { + $this->usr_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [sch_option] column. + * + * @param int $v new value + * @return void + */ + public function setSchOption($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->sch_option !== $v || $v === 0) { + $this->sch_option = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_OPTION; + } + + } // setSchOption() + + /** + * Set the value of [sch_start_time] column. + * + * @param int $v new value + * @return void + */ + public function setSchStartTime($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sch_start_time] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sch_start_time !== $ts) { + $this->sch_start_time = $ts; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_START_TIME; + } + + } // setSchStartTime() + + /** + * Set the value of [sch_start_date] column. + * + * @param int $v new value + * @return void + */ + public function setSchStartDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sch_start_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sch_start_date !== $ts) { + $this->sch_start_date = $ts; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_START_DATE; + } + + } // setSchStartDate() + + /** + * Set the value of [sch_days_perform_task] column. + * + * @param string $v new value + * @return void + */ + public function setSchDaysPerformTask($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_days_perform_task !== $v) { + $this->sch_days_perform_task = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK; + } + + } // setSchDaysPerformTask() + + /** + * Set the value of [sch_every_days] column. + * + * @param int $v new value + * @return void + */ + public function setSchEveryDays($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->sch_every_days !== $v || $v === 0) { + $this->sch_every_days = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_EVERY_DAYS; + } + + } // setSchEveryDays() + + /** + * Set the value of [sch_week_days] column. + * + * @param string $v new value + * @return void + */ + public function setSchWeekDays($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_week_days !== $v || $v === '0|0|0|0|0|0|0') { + $this->sch_week_days = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_WEEK_DAYS; + } + + } // setSchWeekDays() + + /** + * Set the value of [sch_start_day] column. + * + * @param string $v new value + * @return void + */ + public function setSchStartDay($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_start_day !== $v) { + $this->sch_start_day = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_START_DAY; + } + + } // setSchStartDay() + + /** + * Set the value of [sch_months] column. + * + * @param string $v new value + * @return void + */ + public function setSchMonths($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_months !== $v || $v === '0|0|0|0|0|0|0|0|0|0|0|0') { + $this->sch_months = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_MONTHS; + } + + } // setSchMonths() + + /** + * Set the value of [sch_end_date] column. + * + * @param int $v new value + * @return void + */ + public function setSchEndDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sch_end_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sch_end_date !== $ts) { + $this->sch_end_date = $ts; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_END_DATE; + } + + } // setSchEndDate() + + /** + * Set the value of [sch_repeat_every] column. + * + * @param string $v new value + * @return void + */ + public function setSchRepeatEvery($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_repeat_every !== $v) { + $this->sch_repeat_every = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_REPEAT_EVERY; + } + + } // setSchRepeatEvery() + + /** + * Set the value of [sch_repeat_until] column. + * + * @param string $v new value + * @return void + */ + public function setSchRepeatUntil($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_repeat_until !== $v) { + $this->sch_repeat_until = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_REPEAT_UNTIL; + } + + } // setSchRepeatUntil() + + /** + * Set the value of [sch_repeat_stop_if_running] column. + * + * @param int $v new value + * @return void + */ + public function setSchRepeatStopIfRunning($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->sch_repeat_stop_if_running !== $v || $v === 0) { + $this->sch_repeat_stop_if_running = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING; + } + + } // setSchRepeatStopIfRunning() + + /** + * Set the value of [case_sh_plugin_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCaseShPluginUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->case_sh_plugin_uid !== $v) { + $this->case_sh_plugin_uid = $v; + $this->modifiedColumns[] = CaseSchedulerPeer::CASE_SH_PLUGIN_UID; + } + + } // setCaseShPluginUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->sch_uid = $rs->getString($startcol + 0); + + $this->sch_del_user_name = $rs->getString($startcol + 1); + + $this->sch_del_user_pass = $rs->getString($startcol + 2); + + $this->sch_del_user_uid = $rs->getString($startcol + 3); + + $this->sch_name = $rs->getString($startcol + 4); + + $this->pro_uid = $rs->getString($startcol + 5); + + $this->tas_uid = $rs->getString($startcol + 6); + + $this->sch_time_next_run = $rs->getTimestamp($startcol + 7, null); + + $this->sch_last_run_time = $rs->getTimestamp($startcol + 8, null); + + $this->sch_state = $rs->getString($startcol + 9); + + $this->sch_last_state = $rs->getString($startcol + 10); + + $this->usr_uid = $rs->getString($startcol + 11); + + $this->sch_option = $rs->getInt($startcol + 12); + + $this->sch_start_time = $rs->getTimestamp($startcol + 13, null); + + $this->sch_start_date = $rs->getTimestamp($startcol + 14, null); + + $this->sch_days_perform_task = $rs->getString($startcol + 15); + + $this->sch_every_days = $rs->getInt($startcol + 16); + + $this->sch_week_days = $rs->getString($startcol + 17); + + $this->sch_start_day = $rs->getString($startcol + 18); + + $this->sch_months = $rs->getString($startcol + 19); + + $this->sch_end_date = $rs->getTimestamp($startcol + 20, null); + + $this->sch_repeat_every = $rs->getString($startcol + 21); + + $this->sch_repeat_until = $rs->getString($startcol + 22); + + $this->sch_repeat_stop_if_running = $rs->getInt($startcol + 23); + + $this->case_sh_plugin_uid = $rs->getString($startcol + 24); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 25; // 25 = CaseSchedulerPeer::NUM_COLUMNS - CaseSchedulerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CaseScheduler object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseSchedulerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CaseSchedulerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseSchedulerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CaseSchedulerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CaseSchedulerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CaseSchedulerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseSchedulerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getSchUid(); + break; + case 1: + return $this->getSchDelUserName(); + break; + case 2: + return $this->getSchDelUserPass(); + break; + case 3: + return $this->getSchDelUserUid(); + break; + case 4: + return $this->getSchName(); + break; + case 5: + return $this->getProUid(); + break; + case 6: + return $this->getTasUid(); + break; + case 7: + return $this->getSchTimeNextRun(); + break; + case 8: + return $this->getSchLastRunTime(); + break; + case 9: + return $this->getSchState(); + break; + case 10: + return $this->getSchLastState(); + break; + case 11: + return $this->getUsrUid(); + break; + case 12: + return $this->getSchOption(); + break; + case 13: + return $this->getSchStartTime(); + break; + case 14: + return $this->getSchStartDate(); + break; + case 15: + return $this->getSchDaysPerformTask(); + break; + case 16: + return $this->getSchEveryDays(); + break; + case 17: + return $this->getSchWeekDays(); + break; + case 18: + return $this->getSchStartDay(); + break; + case 19: + return $this->getSchMonths(); + break; + case 20: + return $this->getSchEndDate(); + break; + case 21: + return $this->getSchRepeatEvery(); + break; + case 22: + return $this->getSchRepeatUntil(); + break; + case 23: + return $this->getSchRepeatStopIfRunning(); + break; + case 24: + return $this->getCaseShPluginUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseSchedulerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getSchUid(), + $keys[1] => $this->getSchDelUserName(), + $keys[2] => $this->getSchDelUserPass(), + $keys[3] => $this->getSchDelUserUid(), + $keys[4] => $this->getSchName(), + $keys[5] => $this->getProUid(), + $keys[6] => $this->getTasUid(), + $keys[7] => $this->getSchTimeNextRun(), + $keys[8] => $this->getSchLastRunTime(), + $keys[9] => $this->getSchState(), + $keys[10] => $this->getSchLastState(), + $keys[11] => $this->getUsrUid(), + $keys[12] => $this->getSchOption(), + $keys[13] => $this->getSchStartTime(), + $keys[14] => $this->getSchStartDate(), + $keys[15] => $this->getSchDaysPerformTask(), + $keys[16] => $this->getSchEveryDays(), + $keys[17] => $this->getSchWeekDays(), + $keys[18] => $this->getSchStartDay(), + $keys[19] => $this->getSchMonths(), + $keys[20] => $this->getSchEndDate(), + $keys[21] => $this->getSchRepeatEvery(), + $keys[22] => $this->getSchRepeatUntil(), + $keys[23] => $this->getSchRepeatStopIfRunning(), + $keys[24] => $this->getCaseShPluginUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseSchedulerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setSchUid($value); + break; + case 1: + $this->setSchDelUserName($value); + break; + case 2: + $this->setSchDelUserPass($value); + break; + case 3: + $this->setSchDelUserUid($value); + break; + case 4: + $this->setSchName($value); + break; + case 5: + $this->setProUid($value); + break; + case 6: + $this->setTasUid($value); + break; + case 7: + $this->setSchTimeNextRun($value); + break; + case 8: + $this->setSchLastRunTime($value); + break; + case 9: + $this->setSchState($value); + break; + case 10: + $this->setSchLastState($value); + break; + case 11: + $this->setUsrUid($value); + break; + case 12: + $this->setSchOption($value); + break; + case 13: + $this->setSchStartTime($value); + break; + case 14: + $this->setSchStartDate($value); + break; + case 15: + $this->setSchDaysPerformTask($value); + break; + case 16: + $this->setSchEveryDays($value); + break; + case 17: + $this->setSchWeekDays($value); + break; + case 18: + $this->setSchStartDay($value); + break; + case 19: + $this->setSchMonths($value); + break; + case 20: + $this->setSchEndDate($value); + break; + case 21: + $this->setSchRepeatEvery($value); + break; + case 22: + $this->setSchRepeatUntil($value); + break; + case 23: + $this->setSchRepeatStopIfRunning($value); + break; + case 24: + $this->setCaseShPluginUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseSchedulerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setSchUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setSchDelUserName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setSchDelUserPass($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setSchDelUserUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setSchName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setProUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setTasUid($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setSchTimeNextRun($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setSchLastRunTime($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setSchState($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setSchLastState($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setUsrUid($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setSchOption($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setSchStartTime($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setSchStartDate($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setSchDaysPerformTask($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setSchEveryDays($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setSchWeekDays($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setSchStartDay($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setSchMonths($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setSchEndDate($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setSchRepeatEvery($arr[$keys[21]]); + if (array_key_exists($keys[22], $arr)) $this->setSchRepeatUntil($arr[$keys[22]]); + if (array_key_exists($keys[23], $arr)) $this->setSchRepeatStopIfRunning($arr[$keys[23]]); + if (array_key_exists($keys[24], $arr)) $this->setCaseShPluginUid($arr[$keys[24]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CaseSchedulerPeer::DATABASE_NAME); + + if ($this->isColumnModified(CaseSchedulerPeer::SCH_UID)) $criteria->add(CaseSchedulerPeer::SCH_UID, $this->sch_uid); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_DEL_USER_NAME)) $criteria->add(CaseSchedulerPeer::SCH_DEL_USER_NAME, $this->sch_del_user_name); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_DEL_USER_PASS)) $criteria->add(CaseSchedulerPeer::SCH_DEL_USER_PASS, $this->sch_del_user_pass); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_DEL_USER_UID)) $criteria->add(CaseSchedulerPeer::SCH_DEL_USER_UID, $this->sch_del_user_uid); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_NAME)) $criteria->add(CaseSchedulerPeer::SCH_NAME, $this->sch_name); + if ($this->isColumnModified(CaseSchedulerPeer::PRO_UID)) $criteria->add(CaseSchedulerPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(CaseSchedulerPeer::TAS_UID)) $criteria->add(CaseSchedulerPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_TIME_NEXT_RUN)) $criteria->add(CaseSchedulerPeer::SCH_TIME_NEXT_RUN, $this->sch_time_next_run); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_LAST_RUN_TIME)) $criteria->add(CaseSchedulerPeer::SCH_LAST_RUN_TIME, $this->sch_last_run_time); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_STATE)) $criteria->add(CaseSchedulerPeer::SCH_STATE, $this->sch_state); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_LAST_STATE)) $criteria->add(CaseSchedulerPeer::SCH_LAST_STATE, $this->sch_last_state); + if ($this->isColumnModified(CaseSchedulerPeer::USR_UID)) $criteria->add(CaseSchedulerPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_OPTION)) $criteria->add(CaseSchedulerPeer::SCH_OPTION, $this->sch_option); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_START_TIME)) $criteria->add(CaseSchedulerPeer::SCH_START_TIME, $this->sch_start_time); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_START_DATE)) $criteria->add(CaseSchedulerPeer::SCH_START_DATE, $this->sch_start_date); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK)) $criteria->add(CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK, $this->sch_days_perform_task); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_EVERY_DAYS)) $criteria->add(CaseSchedulerPeer::SCH_EVERY_DAYS, $this->sch_every_days); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_WEEK_DAYS)) $criteria->add(CaseSchedulerPeer::SCH_WEEK_DAYS, $this->sch_week_days); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_START_DAY)) $criteria->add(CaseSchedulerPeer::SCH_START_DAY, $this->sch_start_day); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_MONTHS)) $criteria->add(CaseSchedulerPeer::SCH_MONTHS, $this->sch_months); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_END_DATE)) $criteria->add(CaseSchedulerPeer::SCH_END_DATE, $this->sch_end_date); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_REPEAT_EVERY)) $criteria->add(CaseSchedulerPeer::SCH_REPEAT_EVERY, $this->sch_repeat_every); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_REPEAT_UNTIL)) $criteria->add(CaseSchedulerPeer::SCH_REPEAT_UNTIL, $this->sch_repeat_until); + if ($this->isColumnModified(CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING)) $criteria->add(CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING, $this->sch_repeat_stop_if_running); + if ($this->isColumnModified(CaseSchedulerPeer::CASE_SH_PLUGIN_UID)) $criteria->add(CaseSchedulerPeer::CASE_SH_PLUGIN_UID, $this->case_sh_plugin_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CaseSchedulerPeer::DATABASE_NAME); + + $criteria->add(CaseSchedulerPeer::SCH_UID, $this->sch_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getSchUid(); + } + + /** + * Generic method to set the primary key (sch_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setSchUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CaseScheduler (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setSchDelUserName($this->sch_del_user_name); + + $copyObj->setSchDelUserPass($this->sch_del_user_pass); + + $copyObj->setSchDelUserUid($this->sch_del_user_uid); + + $copyObj->setSchName($this->sch_name); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setSchTimeNextRun($this->sch_time_next_run); + + $copyObj->setSchLastRunTime($this->sch_last_run_time); + + $copyObj->setSchState($this->sch_state); + + $copyObj->setSchLastState($this->sch_last_state); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setSchOption($this->sch_option); + + $copyObj->setSchStartTime($this->sch_start_time); + + $copyObj->setSchStartDate($this->sch_start_date); + + $copyObj->setSchDaysPerformTask($this->sch_days_perform_task); + + $copyObj->setSchEveryDays($this->sch_every_days); + + $copyObj->setSchWeekDays($this->sch_week_days); + + $copyObj->setSchStartDay($this->sch_start_day); + + $copyObj->setSchMonths($this->sch_months); + + $copyObj->setSchEndDate($this->sch_end_date); + + $copyObj->setSchRepeatEvery($this->sch_repeat_every); + + $copyObj->setSchRepeatUntil($this->sch_repeat_until); + + $copyObj->setSchRepeatStopIfRunning($this->sch_repeat_stop_if_running); + + $copyObj->setCaseShPluginUid($this->case_sh_plugin_uid); + + + $copyObj->setNew(true); + + $copyObj->setSchUid(NULL); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CaseScheduler Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CaseSchedulerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CaseSchedulerPeer(); + } + return self::$peer; + } + +} // BaseCaseScheduler diff --git a/workflow/engine/classes/model/om/BaseCaseSchedulerPeer.php b/workflow/engine/classes/model/om/BaseCaseSchedulerPeer.php new file mode 100644 index 000000000..5cdbf7651 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseSchedulerPeer.php @@ -0,0 +1,685 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CaseSchedulerPeer::getOMClass() +include_once 'classes/model/CaseScheduler.php'; + +/** + * Base static class for performing query and update operations on the 'CASE_SCHEDULER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseSchedulerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CASE_SCHEDULER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CaseScheduler'; + + /** The total number of columns. */ + const NUM_COLUMNS = 25; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the SCH_UID field */ + const SCH_UID = 'CASE_SCHEDULER.SCH_UID'; + + /** the column name for the SCH_DEL_USER_NAME field */ + const SCH_DEL_USER_NAME = 'CASE_SCHEDULER.SCH_DEL_USER_NAME'; + + /** the column name for the SCH_DEL_USER_PASS field */ + const SCH_DEL_USER_PASS = 'CASE_SCHEDULER.SCH_DEL_USER_PASS'; + + /** the column name for the SCH_DEL_USER_UID field */ + const SCH_DEL_USER_UID = 'CASE_SCHEDULER.SCH_DEL_USER_UID'; + + /** the column name for the SCH_NAME field */ + const SCH_NAME = 'CASE_SCHEDULER.SCH_NAME'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'CASE_SCHEDULER.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'CASE_SCHEDULER.TAS_UID'; + + /** the column name for the SCH_TIME_NEXT_RUN field */ + const SCH_TIME_NEXT_RUN = 'CASE_SCHEDULER.SCH_TIME_NEXT_RUN'; + + /** the column name for the SCH_LAST_RUN_TIME field */ + const SCH_LAST_RUN_TIME = 'CASE_SCHEDULER.SCH_LAST_RUN_TIME'; + + /** the column name for the SCH_STATE field */ + const SCH_STATE = 'CASE_SCHEDULER.SCH_STATE'; + + /** the column name for the SCH_LAST_STATE field */ + const SCH_LAST_STATE = 'CASE_SCHEDULER.SCH_LAST_STATE'; + + /** the column name for the USR_UID field */ + const USR_UID = 'CASE_SCHEDULER.USR_UID'; + + /** the column name for the SCH_OPTION field */ + const SCH_OPTION = 'CASE_SCHEDULER.SCH_OPTION'; + + /** the column name for the SCH_START_TIME field */ + const SCH_START_TIME = 'CASE_SCHEDULER.SCH_START_TIME'; + + /** the column name for the SCH_START_DATE field */ + const SCH_START_DATE = 'CASE_SCHEDULER.SCH_START_DATE'; + + /** the column name for the SCH_DAYS_PERFORM_TASK field */ + const SCH_DAYS_PERFORM_TASK = 'CASE_SCHEDULER.SCH_DAYS_PERFORM_TASK'; + + /** the column name for the SCH_EVERY_DAYS field */ + const SCH_EVERY_DAYS = 'CASE_SCHEDULER.SCH_EVERY_DAYS'; + + /** the column name for the SCH_WEEK_DAYS field */ + const SCH_WEEK_DAYS = 'CASE_SCHEDULER.SCH_WEEK_DAYS'; + + /** the column name for the SCH_START_DAY field */ + const SCH_START_DAY = 'CASE_SCHEDULER.SCH_START_DAY'; + + /** the column name for the SCH_MONTHS field */ + const SCH_MONTHS = 'CASE_SCHEDULER.SCH_MONTHS'; + + /** the column name for the SCH_END_DATE field */ + const SCH_END_DATE = 'CASE_SCHEDULER.SCH_END_DATE'; + + /** the column name for the SCH_REPEAT_EVERY field */ + const SCH_REPEAT_EVERY = 'CASE_SCHEDULER.SCH_REPEAT_EVERY'; + + /** the column name for the SCH_REPEAT_UNTIL field */ + const SCH_REPEAT_UNTIL = 'CASE_SCHEDULER.SCH_REPEAT_UNTIL'; + + /** the column name for the SCH_REPEAT_STOP_IF_RUNNING field */ + const SCH_REPEAT_STOP_IF_RUNNING = 'CASE_SCHEDULER.SCH_REPEAT_STOP_IF_RUNNING'; + + /** the column name for the CASE_SH_PLUGIN_UID field */ + const CASE_SH_PLUGIN_UID = 'CASE_SCHEDULER.CASE_SH_PLUGIN_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('SchUid', 'SchDelUserName', 'SchDelUserPass', 'SchDelUserUid', 'SchName', 'ProUid', 'TasUid', 'SchTimeNextRun', 'SchLastRunTime', 'SchState', 'SchLastState', 'UsrUid', 'SchOption', 'SchStartTime', 'SchStartDate', 'SchDaysPerformTask', 'SchEveryDays', 'SchWeekDays', 'SchStartDay', 'SchMonths', 'SchEndDate', 'SchRepeatEvery', 'SchRepeatUntil', 'SchRepeatStopIfRunning', 'CaseShPluginUid', ), + BasePeer::TYPE_COLNAME => array (CaseSchedulerPeer::SCH_UID, CaseSchedulerPeer::SCH_DEL_USER_NAME, CaseSchedulerPeer::SCH_DEL_USER_PASS, CaseSchedulerPeer::SCH_DEL_USER_UID, CaseSchedulerPeer::SCH_NAME, CaseSchedulerPeer::PRO_UID, CaseSchedulerPeer::TAS_UID, CaseSchedulerPeer::SCH_TIME_NEXT_RUN, CaseSchedulerPeer::SCH_LAST_RUN_TIME, CaseSchedulerPeer::SCH_STATE, CaseSchedulerPeer::SCH_LAST_STATE, CaseSchedulerPeer::USR_UID, CaseSchedulerPeer::SCH_OPTION, CaseSchedulerPeer::SCH_START_TIME, CaseSchedulerPeer::SCH_START_DATE, CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK, CaseSchedulerPeer::SCH_EVERY_DAYS, CaseSchedulerPeer::SCH_WEEK_DAYS, CaseSchedulerPeer::SCH_START_DAY, CaseSchedulerPeer::SCH_MONTHS, CaseSchedulerPeer::SCH_END_DATE, CaseSchedulerPeer::SCH_REPEAT_EVERY, CaseSchedulerPeer::SCH_REPEAT_UNTIL, CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING, CaseSchedulerPeer::CASE_SH_PLUGIN_UID, ), + BasePeer::TYPE_FIELDNAME => array ('SCH_UID', 'SCH_DEL_USER_NAME', 'SCH_DEL_USER_PASS', 'SCH_DEL_USER_UID', 'SCH_NAME', 'PRO_UID', 'TAS_UID', 'SCH_TIME_NEXT_RUN', 'SCH_LAST_RUN_TIME', 'SCH_STATE', 'SCH_LAST_STATE', 'USR_UID', 'SCH_OPTION', 'SCH_START_TIME', 'SCH_START_DATE', 'SCH_DAYS_PERFORM_TASK', 'SCH_EVERY_DAYS', 'SCH_WEEK_DAYS', 'SCH_START_DAY', 'SCH_MONTHS', 'SCH_END_DATE', 'SCH_REPEAT_EVERY', 'SCH_REPEAT_UNTIL', 'SCH_REPEAT_STOP_IF_RUNNING', 'CASE_SH_PLUGIN_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('SchUid' => 0, 'SchDelUserName' => 1, 'SchDelUserPass' => 2, 'SchDelUserUid' => 3, 'SchName' => 4, 'ProUid' => 5, 'TasUid' => 6, 'SchTimeNextRun' => 7, 'SchLastRunTime' => 8, 'SchState' => 9, 'SchLastState' => 10, 'UsrUid' => 11, 'SchOption' => 12, 'SchStartTime' => 13, 'SchStartDate' => 14, 'SchDaysPerformTask' => 15, 'SchEveryDays' => 16, 'SchWeekDays' => 17, 'SchStartDay' => 18, 'SchMonths' => 19, 'SchEndDate' => 20, 'SchRepeatEvery' => 21, 'SchRepeatUntil' => 22, 'SchRepeatStopIfRunning' => 23, 'CaseShPluginUid' => 24, ), + BasePeer::TYPE_COLNAME => array (CaseSchedulerPeer::SCH_UID => 0, CaseSchedulerPeer::SCH_DEL_USER_NAME => 1, CaseSchedulerPeer::SCH_DEL_USER_PASS => 2, CaseSchedulerPeer::SCH_DEL_USER_UID => 3, CaseSchedulerPeer::SCH_NAME => 4, CaseSchedulerPeer::PRO_UID => 5, CaseSchedulerPeer::TAS_UID => 6, CaseSchedulerPeer::SCH_TIME_NEXT_RUN => 7, CaseSchedulerPeer::SCH_LAST_RUN_TIME => 8, CaseSchedulerPeer::SCH_STATE => 9, CaseSchedulerPeer::SCH_LAST_STATE => 10, CaseSchedulerPeer::USR_UID => 11, CaseSchedulerPeer::SCH_OPTION => 12, CaseSchedulerPeer::SCH_START_TIME => 13, CaseSchedulerPeer::SCH_START_DATE => 14, CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK => 15, CaseSchedulerPeer::SCH_EVERY_DAYS => 16, CaseSchedulerPeer::SCH_WEEK_DAYS => 17, CaseSchedulerPeer::SCH_START_DAY => 18, CaseSchedulerPeer::SCH_MONTHS => 19, CaseSchedulerPeer::SCH_END_DATE => 20, CaseSchedulerPeer::SCH_REPEAT_EVERY => 21, CaseSchedulerPeer::SCH_REPEAT_UNTIL => 22, CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING => 23, CaseSchedulerPeer::CASE_SH_PLUGIN_UID => 24, ), + BasePeer::TYPE_FIELDNAME => array ('SCH_UID' => 0, 'SCH_DEL_USER_NAME' => 1, 'SCH_DEL_USER_PASS' => 2, 'SCH_DEL_USER_UID' => 3, 'SCH_NAME' => 4, 'PRO_UID' => 5, 'TAS_UID' => 6, 'SCH_TIME_NEXT_RUN' => 7, 'SCH_LAST_RUN_TIME' => 8, 'SCH_STATE' => 9, 'SCH_LAST_STATE' => 10, 'USR_UID' => 11, 'SCH_OPTION' => 12, 'SCH_START_TIME' => 13, 'SCH_START_DATE' => 14, 'SCH_DAYS_PERFORM_TASK' => 15, 'SCH_EVERY_DAYS' => 16, 'SCH_WEEK_DAYS' => 17, 'SCH_START_DAY' => 18, 'SCH_MONTHS' => 19, 'SCH_END_DATE' => 20, 'SCH_REPEAT_EVERY' => 21, 'SCH_REPEAT_UNTIL' => 22, 'SCH_REPEAT_STOP_IF_RUNNING' => 23, 'CASE_SH_PLUGIN_UID' => 24, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CaseSchedulerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CaseSchedulerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CaseSchedulerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CaseSchedulerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CaseSchedulerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_UID); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_DEL_USER_NAME); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_DEL_USER_PASS); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_DEL_USER_UID); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_NAME); + + $criteria->addSelectColumn(CaseSchedulerPeer::PRO_UID); + + $criteria->addSelectColumn(CaseSchedulerPeer::TAS_UID); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_TIME_NEXT_RUN); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_LAST_RUN_TIME); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_STATE); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_LAST_STATE); + + $criteria->addSelectColumn(CaseSchedulerPeer::USR_UID); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_OPTION); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_START_TIME); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_START_DATE); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_DAYS_PERFORM_TASK); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_EVERY_DAYS); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_WEEK_DAYS); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_START_DAY); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_MONTHS); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_END_DATE); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_REPEAT_EVERY); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_REPEAT_UNTIL); + + $criteria->addSelectColumn(CaseSchedulerPeer::SCH_REPEAT_STOP_IF_RUNNING); + + $criteria->addSelectColumn(CaseSchedulerPeer::CASE_SH_PLUGIN_UID); + + } + + const COUNT = 'COUNT(CASE_SCHEDULER.SCH_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CASE_SCHEDULER.SCH_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CaseSchedulerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CaseSchedulerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CaseSchedulerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CaseScheduler + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CaseSchedulerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CaseSchedulerPeer::populateObjects(CaseSchedulerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CaseSchedulerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CaseSchedulerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CaseSchedulerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CaseScheduler or Criteria object. + * + * @param mixed $values Criteria or CaseScheduler object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CaseScheduler object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CaseScheduler or Criteria object. + * + * @param mixed $values Criteria or CaseScheduler object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CaseSchedulerPeer::SCH_UID); + $selectCriteria->add(CaseSchedulerPeer::SCH_UID, $criteria->remove(CaseSchedulerPeer::SCH_UID), $comparison); + + } else { // $values is CaseScheduler object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CASE_SCHEDULER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CaseSchedulerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CaseScheduler or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CaseScheduler object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CaseSchedulerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CaseScheduler) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(CaseSchedulerPeer::SCH_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CaseScheduler object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CaseScheduler $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CaseScheduler $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CaseSchedulerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CaseSchedulerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(CaseSchedulerPeer::DATABASE_NAME, CaseSchedulerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return CaseScheduler + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(CaseSchedulerPeer::DATABASE_NAME); + + $criteria->add(CaseSchedulerPeer::SCH_UID, $pk); + + + $v = CaseSchedulerPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(CaseSchedulerPeer::SCH_UID, $pks, Criteria::IN); + $objs = CaseSchedulerPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseCaseSchedulerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCaseSchedulerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CaseSchedulerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CaseSchedulerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCaseTracker.php b/workflow/engine/classes/model/om/BaseCaseTracker.php new file mode 100644 index 000000000..a51bb1f6b --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseTracker.php @@ -0,0 +1,663 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CaseTrackerPeer.php'; + +/** + * Base class that represents a row from the 'CASE_TRACKER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseTracker extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CaseTrackerPeer + */ + protected static $peer; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the ct_map_type field. + * @var string + */ + protected $ct_map_type = '0'; + + + /** + * The value for the ct_derivation_history field. + * @var int + */ + protected $ct_derivation_history = 0; + + + /** + * The value for the ct_message_history field. + * @var int + */ + protected $ct_message_history = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [ct_map_type] column value. + * + * @return string + */ + public function getCtMapType() + { + + return $this->ct_map_type; + } + + /** + * Get the [ct_derivation_history] column value. + * + * @return int + */ + public function getCtDerivationHistory() + { + + return $this->ct_derivation_history; + } + + /** + * Get the [ct_message_history] column value. + * + * @return int + */ + public function getCtMessageHistory() + { + + return $this->ct_message_history; + } + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = CaseTrackerPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [ct_map_type] column. + * + * @param string $v new value + * @return void + */ + public function setCtMapType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ct_map_type !== $v || $v === '0') { + $this->ct_map_type = $v; + $this->modifiedColumns[] = CaseTrackerPeer::CT_MAP_TYPE; + } + + } // setCtMapType() + + /** + * Set the value of [ct_derivation_history] column. + * + * @param int $v new value + * @return void + */ + public function setCtDerivationHistory($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->ct_derivation_history !== $v || $v === 0) { + $this->ct_derivation_history = $v; + $this->modifiedColumns[] = CaseTrackerPeer::CT_DERIVATION_HISTORY; + } + + } // setCtDerivationHistory() + + /** + * Set the value of [ct_message_history] column. + * + * @param int $v new value + * @return void + */ + public function setCtMessageHistory($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->ct_message_history !== $v || $v === 0) { + $this->ct_message_history = $v; + $this->modifiedColumns[] = CaseTrackerPeer::CT_MESSAGE_HISTORY; + } + + } // setCtMessageHistory() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->pro_uid = $rs->getString($startcol + 0); + + $this->ct_map_type = $rs->getString($startcol + 1); + + $this->ct_derivation_history = $rs->getInt($startcol + 2); + + $this->ct_message_history = $rs->getInt($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = CaseTrackerPeer::NUM_COLUMNS - CaseTrackerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CaseTracker object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CaseTrackerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CaseTrackerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CaseTrackerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CaseTrackerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseTrackerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getProUid(); + break; + case 1: + return $this->getCtMapType(); + break; + case 2: + return $this->getCtDerivationHistory(); + break; + case 3: + return $this->getCtMessageHistory(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseTrackerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getProUid(), + $keys[1] => $this->getCtMapType(), + $keys[2] => $this->getCtDerivationHistory(), + $keys[3] => $this->getCtMessageHistory(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseTrackerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setProUid($value); + break; + case 1: + $this->setCtMapType($value); + break; + case 2: + $this->setCtDerivationHistory($value); + break; + case 3: + $this->setCtMessageHistory($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseTrackerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setProUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCtMapType($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCtDerivationHistory($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCtMessageHistory($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CaseTrackerPeer::DATABASE_NAME); + + if ($this->isColumnModified(CaseTrackerPeer::PRO_UID)) $criteria->add(CaseTrackerPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(CaseTrackerPeer::CT_MAP_TYPE)) $criteria->add(CaseTrackerPeer::CT_MAP_TYPE, $this->ct_map_type); + if ($this->isColumnModified(CaseTrackerPeer::CT_DERIVATION_HISTORY)) $criteria->add(CaseTrackerPeer::CT_DERIVATION_HISTORY, $this->ct_derivation_history); + if ($this->isColumnModified(CaseTrackerPeer::CT_MESSAGE_HISTORY)) $criteria->add(CaseTrackerPeer::CT_MESSAGE_HISTORY, $this->ct_message_history); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CaseTrackerPeer::DATABASE_NAME); + + $criteria->add(CaseTrackerPeer::PRO_UID, $this->pro_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getProUid(); + } + + /** + * Generic method to set the primary key (pro_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setProUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CaseTracker (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCtMapType($this->ct_map_type); + + $copyObj->setCtDerivationHistory($this->ct_derivation_history); + + $copyObj->setCtMessageHistory($this->ct_message_history); + + + $copyObj->setNew(true); + + $copyObj->setProUid('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CaseTracker Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CaseTrackerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CaseTrackerPeer(); + } + return self::$peer; + } + +} // BaseCaseTracker diff --git a/workflow/engine/classes/model/om/BaseCaseTrackerObject.php b/workflow/engine/classes/model/om/BaseCaseTrackerObject.php new file mode 100644 index 000000000..b05139a82 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseTrackerObject.php @@ -0,0 +1,769 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/CaseTrackerObjectPeer.php'; + +/** + * Base class that represents a row from the 'CASE_TRACKER_OBJECT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseTrackerObject extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var CaseTrackerObjectPeer + */ + protected static $peer; + + + /** + * The value for the cto_uid field. + * @var string + */ + protected $cto_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the cto_type_obj field. + * @var string + */ + protected $cto_type_obj = 'DYNAFORM'; + + + /** + * The value for the cto_uid_obj field. + * @var string + */ + protected $cto_uid_obj = '0'; + + + /** + * The value for the cto_condition field. + * @var string + */ + protected $cto_condition; + + + /** + * The value for the cto_position field. + * @var int + */ + protected $cto_position = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [cto_uid] column value. + * + * @return string + */ + public function getCtoUid() + { + + return $this->cto_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [cto_type_obj] column value. + * + * @return string + */ + public function getCtoTypeObj() + { + + return $this->cto_type_obj; + } + + /** + * Get the [cto_uid_obj] column value. + * + * @return string + */ + public function getCtoUidObj() + { + + return $this->cto_uid_obj; + } + + /** + * Get the [cto_condition] column value. + * + * @return string + */ + public function getCtoCondition() + { + + return $this->cto_condition; + } + + /** + * Get the [cto_position] column value. + * + * @return int + */ + public function getCtoPosition() + { + + return $this->cto_position; + } + + /** + * Set the value of [cto_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCtoUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cto_uid !== $v || $v === '') { + $this->cto_uid = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::CTO_UID; + } + + } // setCtoUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [cto_type_obj] column. + * + * @param string $v new value + * @return void + */ + public function setCtoTypeObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cto_type_obj !== $v || $v === 'DYNAFORM') { + $this->cto_type_obj = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::CTO_TYPE_OBJ; + } + + } // setCtoTypeObj() + + /** + * Set the value of [cto_uid_obj] column. + * + * @param string $v new value + * @return void + */ + public function setCtoUidObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cto_uid_obj !== $v || $v === '0') { + $this->cto_uid_obj = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::CTO_UID_OBJ; + } + + } // setCtoUidObj() + + /** + * Set the value of [cto_condition] column. + * + * @param string $v new value + * @return void + */ + public function setCtoCondition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cto_condition !== $v) { + $this->cto_condition = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::CTO_CONDITION; + } + + } // setCtoCondition() + + /** + * Set the value of [cto_position] column. + * + * @param int $v new value + * @return void + */ + public function setCtoPosition($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->cto_position !== $v || $v === 0) { + $this->cto_position = $v; + $this->modifiedColumns[] = CaseTrackerObjectPeer::CTO_POSITION; + } + + } // setCtoPosition() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->cto_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->cto_type_obj = $rs->getString($startcol + 2); + + $this->cto_uid_obj = $rs->getString($startcol + 3); + + $this->cto_condition = $rs->getString($startcol + 4); + + $this->cto_position = $rs->getInt($startcol + 5); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 6; // 6 = CaseTrackerObjectPeer::NUM_COLUMNS - CaseTrackerObjectPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating CaseTrackerObject object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + } + + try { + $con->begin(); + CaseTrackerObjectPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = CaseTrackerObjectPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += CaseTrackerObjectPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = CaseTrackerObjectPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseTrackerObjectPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCtoUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getCtoTypeObj(); + break; + case 3: + return $this->getCtoUidObj(); + break; + case 4: + return $this->getCtoCondition(); + break; + case 5: + return $this->getCtoPosition(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseTrackerObjectPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCtoUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getCtoTypeObj(), + $keys[3] => $this->getCtoUidObj(), + $keys[4] => $this->getCtoCondition(), + $keys[5] => $this->getCtoPosition(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = CaseTrackerObjectPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCtoUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setCtoTypeObj($value); + break; + case 3: + $this->setCtoUidObj($value); + break; + case 4: + $this->setCtoCondition($value); + break; + case 5: + $this->setCtoPosition($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = CaseTrackerObjectPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCtoUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCtoTypeObj($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCtoUidObj($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCtoCondition($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setCtoPosition($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(CaseTrackerObjectPeer::DATABASE_NAME); + + if ($this->isColumnModified(CaseTrackerObjectPeer::CTO_UID)) $criteria->add(CaseTrackerObjectPeer::CTO_UID, $this->cto_uid); + if ($this->isColumnModified(CaseTrackerObjectPeer::PRO_UID)) $criteria->add(CaseTrackerObjectPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(CaseTrackerObjectPeer::CTO_TYPE_OBJ)) $criteria->add(CaseTrackerObjectPeer::CTO_TYPE_OBJ, $this->cto_type_obj); + if ($this->isColumnModified(CaseTrackerObjectPeer::CTO_UID_OBJ)) $criteria->add(CaseTrackerObjectPeer::CTO_UID_OBJ, $this->cto_uid_obj); + if ($this->isColumnModified(CaseTrackerObjectPeer::CTO_CONDITION)) $criteria->add(CaseTrackerObjectPeer::CTO_CONDITION, $this->cto_condition); + if ($this->isColumnModified(CaseTrackerObjectPeer::CTO_POSITION)) $criteria->add(CaseTrackerObjectPeer::CTO_POSITION, $this->cto_position); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(CaseTrackerObjectPeer::DATABASE_NAME); + + $criteria->add(CaseTrackerObjectPeer::CTO_UID, $this->cto_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getCtoUid(); + } + + /** + * Generic method to set the primary key (cto_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setCtoUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of CaseTrackerObject (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setCtoTypeObj($this->cto_type_obj); + + $copyObj->setCtoUidObj($this->cto_uid_obj); + + $copyObj->setCtoCondition($this->cto_condition); + + $copyObj->setCtoPosition($this->cto_position); + + + $copyObj->setNew(true); + + $copyObj->setCtoUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return CaseTrackerObject Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return CaseTrackerObjectPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new CaseTrackerObjectPeer(); + } + return self::$peer; + } + +} // BaseCaseTrackerObject diff --git a/workflow/engine/classes/model/om/BaseCaseTrackerObjectPeer.php b/workflow/engine/classes/model/om/BaseCaseTrackerObjectPeer.php new file mode 100644 index 000000000..24a681821 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseTrackerObjectPeer.php @@ -0,0 +1,593 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CaseTrackerObjectPeer::getOMClass() +include_once 'classes/model/CaseTrackerObject.php'; + +/** + * Base static class for performing query and update operations on the 'CASE_TRACKER_OBJECT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseTrackerObjectPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CASE_TRACKER_OBJECT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CaseTrackerObject'; + + /** The total number of columns. */ + const NUM_COLUMNS = 6; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CTO_UID field */ + const CTO_UID = 'CASE_TRACKER_OBJECT.CTO_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'CASE_TRACKER_OBJECT.PRO_UID'; + + /** the column name for the CTO_TYPE_OBJ field */ + const CTO_TYPE_OBJ = 'CASE_TRACKER_OBJECT.CTO_TYPE_OBJ'; + + /** the column name for the CTO_UID_OBJ field */ + const CTO_UID_OBJ = 'CASE_TRACKER_OBJECT.CTO_UID_OBJ'; + + /** the column name for the CTO_CONDITION field */ + const CTO_CONDITION = 'CASE_TRACKER_OBJECT.CTO_CONDITION'; + + /** the column name for the CTO_POSITION field */ + const CTO_POSITION = 'CASE_TRACKER_OBJECT.CTO_POSITION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CtoUid', 'ProUid', 'CtoTypeObj', 'CtoUidObj', 'CtoCondition', 'CtoPosition', ), + BasePeer::TYPE_COLNAME => array (CaseTrackerObjectPeer::CTO_UID, CaseTrackerObjectPeer::PRO_UID, CaseTrackerObjectPeer::CTO_TYPE_OBJ, CaseTrackerObjectPeer::CTO_UID_OBJ, CaseTrackerObjectPeer::CTO_CONDITION, CaseTrackerObjectPeer::CTO_POSITION, ), + BasePeer::TYPE_FIELDNAME => array ('CTO_UID', 'PRO_UID', 'CTO_TYPE_OBJ', 'CTO_UID_OBJ', 'CTO_CONDITION', 'CTO_POSITION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CtoUid' => 0, 'ProUid' => 1, 'CtoTypeObj' => 2, 'CtoUidObj' => 3, 'CtoCondition' => 4, 'CtoPosition' => 5, ), + BasePeer::TYPE_COLNAME => array (CaseTrackerObjectPeer::CTO_UID => 0, CaseTrackerObjectPeer::PRO_UID => 1, CaseTrackerObjectPeer::CTO_TYPE_OBJ => 2, CaseTrackerObjectPeer::CTO_UID_OBJ => 3, CaseTrackerObjectPeer::CTO_CONDITION => 4, CaseTrackerObjectPeer::CTO_POSITION => 5, ), + BasePeer::TYPE_FIELDNAME => array ('CTO_UID' => 0, 'PRO_UID' => 1, 'CTO_TYPE_OBJ' => 2, 'CTO_UID_OBJ' => 3, 'CTO_CONDITION' => 4, 'CTO_POSITION' => 5, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CaseTrackerObjectMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CaseTrackerObjectMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CaseTrackerObjectPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CaseTrackerObjectPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CaseTrackerObjectPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CaseTrackerObjectPeer::CTO_UID); + + $criteria->addSelectColumn(CaseTrackerObjectPeer::PRO_UID); + + $criteria->addSelectColumn(CaseTrackerObjectPeer::CTO_TYPE_OBJ); + + $criteria->addSelectColumn(CaseTrackerObjectPeer::CTO_UID_OBJ); + + $criteria->addSelectColumn(CaseTrackerObjectPeer::CTO_CONDITION); + + $criteria->addSelectColumn(CaseTrackerObjectPeer::CTO_POSITION); + + } + + const COUNT = 'COUNT(CASE_TRACKER_OBJECT.CTO_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CASE_TRACKER_OBJECT.CTO_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CaseTrackerObjectPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CaseTrackerObjectPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CaseTrackerObjectPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CaseTrackerObject + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CaseTrackerObjectPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CaseTrackerObjectPeer::populateObjects(CaseTrackerObjectPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CaseTrackerObjectPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CaseTrackerObjectPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CaseTrackerObjectPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CaseTrackerObject or Criteria object. + * + * @param mixed $values Criteria or CaseTrackerObject object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CaseTrackerObject object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CaseTrackerObject or Criteria object. + * + * @param mixed $values Criteria or CaseTrackerObject object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CaseTrackerObjectPeer::CTO_UID); + $selectCriteria->add(CaseTrackerObjectPeer::CTO_UID, $criteria->remove(CaseTrackerObjectPeer::CTO_UID), $comparison); + + } else { // $values is CaseTrackerObject object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CASE_TRACKER_OBJECT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CaseTrackerObjectPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CaseTrackerObject or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CaseTrackerObject object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CaseTrackerObjectPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CaseTrackerObject) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(CaseTrackerObjectPeer::CTO_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CaseTrackerObject object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CaseTrackerObject $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CaseTrackerObject $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CaseTrackerObjectPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CaseTrackerObjectPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(CaseTrackerObjectPeer::CTO_TYPE_OBJ)) + $columns[CaseTrackerObjectPeer::CTO_TYPE_OBJ] = $obj->getCtoTypeObj(); + + } + + return BasePeer::doValidate(CaseTrackerObjectPeer::DATABASE_NAME, CaseTrackerObjectPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return CaseTrackerObject + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(CaseTrackerObjectPeer::DATABASE_NAME); + + $criteria->add(CaseTrackerObjectPeer::CTO_UID, $pk); + + + $v = CaseTrackerObjectPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(CaseTrackerObjectPeer::CTO_UID, $pks, Criteria::IN); + $objs = CaseTrackerObjectPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseCaseTrackerObjectPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCaseTrackerObjectPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CaseTrackerObjectMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CaseTrackerObjectMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseCaseTrackerPeer.php b/workflow/engine/classes/model/om/BaseCaseTrackerPeer.php new file mode 100644 index 000000000..f6804e87c --- /dev/null +++ b/workflow/engine/classes/model/om/BaseCaseTrackerPeer.php @@ -0,0 +1,592 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by CaseTrackerPeer::getOMClass() +include_once 'classes/model/CaseTracker.php'; + +/** + * Base static class for performing query and update operations on the 'CASE_TRACKER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseCaseTrackerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CASE_TRACKER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.CaseTracker'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the PRO_UID field */ + const PRO_UID = 'CASE_TRACKER.PRO_UID'; + + /** the column name for the CT_MAP_TYPE field */ + const CT_MAP_TYPE = 'CASE_TRACKER.CT_MAP_TYPE'; + + /** the column name for the CT_DERIVATION_HISTORY field */ + const CT_DERIVATION_HISTORY = 'CASE_TRACKER.CT_DERIVATION_HISTORY'; + + /** the column name for the CT_MESSAGE_HISTORY field */ + const CT_MESSAGE_HISTORY = 'CASE_TRACKER.CT_MESSAGE_HISTORY'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid', 'CtMapType', 'CtDerivationHistory', 'CtMessageHistory', ), + BasePeer::TYPE_COLNAME => array (CaseTrackerPeer::PRO_UID, CaseTrackerPeer::CT_MAP_TYPE, CaseTrackerPeer::CT_DERIVATION_HISTORY, CaseTrackerPeer::CT_MESSAGE_HISTORY, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID', 'CT_MAP_TYPE', 'CT_DERIVATION_HISTORY', 'CT_MESSAGE_HISTORY', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid' => 0, 'CtMapType' => 1, 'CtDerivationHistory' => 2, 'CtMessageHistory' => 3, ), + BasePeer::TYPE_COLNAME => array (CaseTrackerPeer::PRO_UID => 0, CaseTrackerPeer::CT_MAP_TYPE => 1, CaseTrackerPeer::CT_DERIVATION_HISTORY => 2, CaseTrackerPeer::CT_MESSAGE_HISTORY => 3, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID' => 0, 'CT_MAP_TYPE' => 1, 'CT_DERIVATION_HISTORY' => 2, 'CT_MESSAGE_HISTORY' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/CaseTrackerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.CaseTrackerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = CaseTrackerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. CaseTrackerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(CaseTrackerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(CaseTrackerPeer::PRO_UID); + + $criteria->addSelectColumn(CaseTrackerPeer::CT_MAP_TYPE); + + $criteria->addSelectColumn(CaseTrackerPeer::CT_DERIVATION_HISTORY); + + $criteria->addSelectColumn(CaseTrackerPeer::CT_MESSAGE_HISTORY); + + } + + const COUNT = 'COUNT(CASE_TRACKER.PRO_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CASE_TRACKER.PRO_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(CaseTrackerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(CaseTrackerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = CaseTrackerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return CaseTracker + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = CaseTrackerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return CaseTrackerPeer::populateObjects(CaseTrackerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + CaseTrackerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = CaseTrackerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return CaseTrackerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a CaseTracker or Criteria object. + * + * @param mixed $values Criteria or CaseTracker object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from CaseTracker object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a CaseTracker or Criteria object. + * + * @param mixed $values Criteria or CaseTracker object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(CaseTrackerPeer::PRO_UID); + $selectCriteria->add(CaseTrackerPeer::PRO_UID, $criteria->remove(CaseTrackerPeer::PRO_UID), $comparison); + + } else { // $values is CaseTracker object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CASE_TRACKER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(CaseTrackerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a CaseTracker or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or CaseTracker object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(CaseTrackerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof CaseTracker) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(CaseTrackerPeer::PRO_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given CaseTracker object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param CaseTracker $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(CaseTracker $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(CaseTrackerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(CaseTrackerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(CaseTrackerPeer::PRO_UID)) + $columns[CaseTrackerPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(CaseTrackerPeer::CT_MAP_TYPE)) + $columns[CaseTrackerPeer::CT_MAP_TYPE] = $obj->getCtMapType(); + + if ($obj->isNew() || $obj->isColumnModified(CaseTrackerPeer::CT_DERIVATION_HISTORY)) + $columns[CaseTrackerPeer::CT_DERIVATION_HISTORY] = $obj->getCtDerivationHistory(); + + if ($obj->isNew() || $obj->isColumnModified(CaseTrackerPeer::CT_MESSAGE_HISTORY)) + $columns[CaseTrackerPeer::CT_MESSAGE_HISTORY] = $obj->getCtMessageHistory(); + + } + + return BasePeer::doValidate(CaseTrackerPeer::DATABASE_NAME, CaseTrackerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return CaseTracker + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(CaseTrackerPeer::DATABASE_NAME); + + $criteria->add(CaseTrackerPeer::PRO_UID, $pk); + + + $v = CaseTrackerPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(CaseTrackerPeer::PRO_UID, $pks, Criteria::IN); + $objs = CaseTrackerPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseCaseTrackerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseCaseTrackerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/CaseTrackerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.CaseTrackerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseConfiguration.php b/workflow/engine/classes/model/om/BaseConfiguration.php new file mode 100644 index 000000000..e9597eacc --- /dev/null +++ b/workflow/engine/classes/model/om/BaseConfiguration.php @@ -0,0 +1,796 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ConfigurationPeer.php'; + +/** + * Base class that represents a row from the 'CONFIGURATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseConfiguration extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ConfigurationPeer + */ + protected static $peer; + + + /** + * The value for the cfg_uid field. + * @var string + */ + protected $cfg_uid = ''; + + + /** + * The value for the obj_uid field. + * @var string + */ + protected $obj_uid = ''; + + + /** + * The value for the cfg_value field. + * @var string + */ + protected $cfg_value; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [cfg_uid] column value. + * + * @return string + */ + public function getCfgUid() + { + + return $this->cfg_uid; + } + + /** + * Get the [obj_uid] column value. + * + * @return string + */ + public function getObjUid() + { + + return $this->obj_uid; + } + + /** + * Get the [cfg_value] column value. + * + * @return string + */ + public function getCfgValue() + { + + return $this->cfg_value; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Set the value of [cfg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCfgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cfg_uid !== $v || $v === '') { + $this->cfg_uid = $v; + $this->modifiedColumns[] = ConfigurationPeer::CFG_UID; + } + + } // setCfgUid() + + /** + * Set the value of [obj_uid] column. + * + * @param string $v new value + * @return void + */ + public function setObjUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->obj_uid !== $v || $v === '') { + $this->obj_uid = $v; + $this->modifiedColumns[] = ConfigurationPeer::OBJ_UID; + } + + } // setObjUid() + + /** + * Set the value of [cfg_value] column. + * + * @param string $v new value + * @return void + */ + public function setCfgValue($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->cfg_value !== $v) { + $this->cfg_value = $v; + $this->modifiedColumns[] = ConfigurationPeer::CFG_VALUE; + } + + } // setCfgValue() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ConfigurationPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = ConfigurationPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = ConfigurationPeer::APP_UID; + } + + } // setAppUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->cfg_uid = $rs->getString($startcol + 0); + + $this->obj_uid = $rs->getString($startcol + 1); + + $this->cfg_value = $rs->getString($startcol + 2); + + $this->pro_uid = $rs->getString($startcol + 3); + + $this->usr_uid = $rs->getString($startcol + 4); + + $this->app_uid = $rs->getString($startcol + 5); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 6; // 6 = ConfigurationPeer::NUM_COLUMNS - ConfigurationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Configuration object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ConfigurationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ConfigurationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ConfigurationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ConfigurationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ConfigurationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCfgUid(); + break; + case 1: + return $this->getObjUid(); + break; + case 2: + return $this->getCfgValue(); + break; + case 3: + return $this->getProUid(); + break; + case 4: + return $this->getUsrUid(); + break; + case 5: + return $this->getAppUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ConfigurationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCfgUid(), + $keys[1] => $this->getObjUid(), + $keys[2] => $this->getCfgValue(), + $keys[3] => $this->getProUid(), + $keys[4] => $this->getUsrUid(), + $keys[5] => $this->getAppUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ConfigurationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCfgUid($value); + break; + case 1: + $this->setObjUid($value); + break; + case 2: + $this->setCfgValue($value); + break; + case 3: + $this->setProUid($value); + break; + case 4: + $this->setUsrUid($value); + break; + case 5: + $this->setAppUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ConfigurationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCfgUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setObjUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCfgValue($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setProUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUsrUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppUid($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ConfigurationPeer::DATABASE_NAME); + + if ($this->isColumnModified(ConfigurationPeer::CFG_UID)) $criteria->add(ConfigurationPeer::CFG_UID, $this->cfg_uid); + if ($this->isColumnModified(ConfigurationPeer::OBJ_UID)) $criteria->add(ConfigurationPeer::OBJ_UID, $this->obj_uid); + if ($this->isColumnModified(ConfigurationPeer::CFG_VALUE)) $criteria->add(ConfigurationPeer::CFG_VALUE, $this->cfg_value); + if ($this->isColumnModified(ConfigurationPeer::PRO_UID)) $criteria->add(ConfigurationPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ConfigurationPeer::USR_UID)) $criteria->add(ConfigurationPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(ConfigurationPeer::APP_UID)) $criteria->add(ConfigurationPeer::APP_UID, $this->app_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ConfigurationPeer::DATABASE_NAME); + + $criteria->add(ConfigurationPeer::CFG_UID, $this->cfg_uid); + $criteria->add(ConfigurationPeer::OBJ_UID, $this->obj_uid); + $criteria->add(ConfigurationPeer::PRO_UID, $this->pro_uid); + $criteria->add(ConfigurationPeer::USR_UID, $this->usr_uid); + $criteria->add(ConfigurationPeer::APP_UID, $this->app_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getCfgUid(); + + $pks[1] = $this->getObjUid(); + + $pks[2] = $this->getProUid(); + + $pks[3] = $this->getUsrUid(); + + $pks[4] = $this->getAppUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setCfgUid($keys[0]); + + $this->setObjUid($keys[1]); + + $this->setProUid($keys[2]); + + $this->setUsrUid($keys[3]); + + $this->setAppUid($keys[4]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Configuration (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCfgValue($this->cfg_value); + + + $copyObj->setNew(true); + + $copyObj->setCfgUid(''); // this is a pkey column, so set to default value + + $copyObj->setObjUid(''); // this is a pkey column, so set to default value + + $copyObj->setProUid(''); // this is a pkey column, so set to default value + + $copyObj->setUsrUid(''); // this is a pkey column, so set to default value + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Configuration Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ConfigurationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ConfigurationPeer(); + } + return self::$peer; + } + +} // BaseConfiguration diff --git a/workflow/engine/classes/model/om/BaseConfigurationPeer.php b/workflow/engine/classes/model/om/BaseConfigurationPeer.php new file mode 100644 index 000000000..87bc1892e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseConfigurationPeer.php @@ -0,0 +1,602 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ConfigurationPeer::getOMClass() +include_once 'classes/model/Configuration.php'; + +/** + * Base static class for performing query and update operations on the 'CONFIGURATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseConfigurationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CONFIGURATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Configuration'; + + /** The total number of columns. */ + const NUM_COLUMNS = 6; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CFG_UID field */ + const CFG_UID = 'CONFIGURATION.CFG_UID'; + + /** the column name for the OBJ_UID field */ + const OBJ_UID = 'CONFIGURATION.OBJ_UID'; + + /** the column name for the CFG_VALUE field */ + const CFG_VALUE = 'CONFIGURATION.CFG_VALUE'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'CONFIGURATION.PRO_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'CONFIGURATION.USR_UID'; + + /** the column name for the APP_UID field */ + const APP_UID = 'CONFIGURATION.APP_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CfgUid', 'ObjUid', 'CfgValue', 'ProUid', 'UsrUid', 'AppUid', ), + BasePeer::TYPE_COLNAME => array (ConfigurationPeer::CFG_UID, ConfigurationPeer::OBJ_UID, ConfigurationPeer::CFG_VALUE, ConfigurationPeer::PRO_UID, ConfigurationPeer::USR_UID, ConfigurationPeer::APP_UID, ), + BasePeer::TYPE_FIELDNAME => array ('CFG_UID', 'OBJ_UID', 'CFG_VALUE', 'PRO_UID', 'USR_UID', 'APP_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CfgUid' => 0, 'ObjUid' => 1, 'CfgValue' => 2, 'ProUid' => 3, 'UsrUid' => 4, 'AppUid' => 5, ), + BasePeer::TYPE_COLNAME => array (ConfigurationPeer::CFG_UID => 0, ConfigurationPeer::OBJ_UID => 1, ConfigurationPeer::CFG_VALUE => 2, ConfigurationPeer::PRO_UID => 3, ConfigurationPeer::USR_UID => 4, ConfigurationPeer::APP_UID => 5, ), + BasePeer::TYPE_FIELDNAME => array ('CFG_UID' => 0, 'OBJ_UID' => 1, 'CFG_VALUE' => 2, 'PRO_UID' => 3, 'USR_UID' => 4, 'APP_UID' => 5, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ConfigurationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ConfigurationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ConfigurationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ConfigurationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ConfigurationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ConfigurationPeer::CFG_UID); + + $criteria->addSelectColumn(ConfigurationPeer::OBJ_UID); + + $criteria->addSelectColumn(ConfigurationPeer::CFG_VALUE); + + $criteria->addSelectColumn(ConfigurationPeer::PRO_UID); + + $criteria->addSelectColumn(ConfigurationPeer::USR_UID); + + $criteria->addSelectColumn(ConfigurationPeer::APP_UID); + + } + + const COUNT = 'COUNT(CONFIGURATION.CFG_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CONFIGURATION.CFG_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ConfigurationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ConfigurationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ConfigurationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Configuration + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ConfigurationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ConfigurationPeer::populateObjects(ConfigurationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ConfigurationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ConfigurationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ConfigurationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Configuration or Criteria object. + * + * @param mixed $values Criteria or Configuration object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Configuration object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Configuration or Criteria object. + * + * @param mixed $values Criteria or Configuration object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ConfigurationPeer::CFG_UID); + $selectCriteria->add(ConfigurationPeer::CFG_UID, $criteria->remove(ConfigurationPeer::CFG_UID), $comparison); + + $comparison = $criteria->getComparison(ConfigurationPeer::OBJ_UID); + $selectCriteria->add(ConfigurationPeer::OBJ_UID, $criteria->remove(ConfigurationPeer::OBJ_UID), $comparison); + + $comparison = $criteria->getComparison(ConfigurationPeer::PRO_UID); + $selectCriteria->add(ConfigurationPeer::PRO_UID, $criteria->remove(ConfigurationPeer::PRO_UID), $comparison); + + $comparison = $criteria->getComparison(ConfigurationPeer::USR_UID); + $selectCriteria->add(ConfigurationPeer::USR_UID, $criteria->remove(ConfigurationPeer::USR_UID), $comparison); + + $comparison = $criteria->getComparison(ConfigurationPeer::APP_UID); + $selectCriteria->add(ConfigurationPeer::APP_UID, $criteria->remove(ConfigurationPeer::APP_UID), $comparison); + + } else { // $values is Configuration object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CONFIGURATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ConfigurationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Configuration or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Configuration object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ConfigurationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Configuration) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + $vals[4][] = $value[4]; + } + + $criteria->add(ConfigurationPeer::CFG_UID, $vals[0], Criteria::IN); + $criteria->add(ConfigurationPeer::OBJ_UID, $vals[1], Criteria::IN); + $criteria->add(ConfigurationPeer::PRO_UID, $vals[2], Criteria::IN); + $criteria->add(ConfigurationPeer::USR_UID, $vals[3], Criteria::IN); + $criteria->add(ConfigurationPeer::APP_UID, $vals[4], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Configuration object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Configuration $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Configuration $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ConfigurationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ConfigurationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(ConfigurationPeer::DATABASE_NAME, ConfigurationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $cfg_uid + @param string $obj_uid + @param string $pro_uid + @param string $usr_uid + @param string $app_uid + + * @param Connection $con + * @return Configuration + */ + public static function retrieveByPK( $cfg_uid, $obj_uid, $pro_uid, $usr_uid, $app_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(ConfigurationPeer::CFG_UID, $cfg_uid); + $criteria->add(ConfigurationPeer::OBJ_UID, $obj_uid); + $criteria->add(ConfigurationPeer::PRO_UID, $pro_uid); + $criteria->add(ConfigurationPeer::USR_UID, $usr_uid); + $criteria->add(ConfigurationPeer::APP_UID, $app_uid); + $v = ConfigurationPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseConfigurationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseConfigurationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ConfigurationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ConfigurationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseContent.php b/workflow/engine/classes/model/om/BaseContent.php new file mode 100644 index 000000000..f7d4aa493 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseContent.php @@ -0,0 +1,738 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ContentPeer.php'; + +/** + * Base class that represents a row from the 'CONTENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseContent extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ContentPeer + */ + protected static $peer; + + + /** + * The value for the con_category field. + * @var string + */ + protected $con_category = ''; + + + /** + * The value for the con_parent field. + * @var string + */ + protected $con_parent = ''; + + + /** + * The value for the con_id field. + * @var string + */ + protected $con_id = ''; + + + /** + * The value for the con_lang field. + * @var string + */ + protected $con_lang = ''; + + + /** + * The value for the con_value field. + * @var string + */ + protected $con_value; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [con_category] column value. + * + * @return string + */ + public function getConCategory() + { + + return $this->con_category; + } + + /** + * Get the [con_parent] column value. + * + * @return string + */ + public function getConParent() + { + + return $this->con_parent; + } + + /** + * Get the [con_id] column value. + * + * @return string + */ + public function getConId() + { + + return $this->con_id; + } + + /** + * Get the [con_lang] column value. + * + * @return string + */ + public function getConLang() + { + + return $this->con_lang; + } + + /** + * Get the [con_value] column value. + * + * @return string + */ + public function getConValue() + { + + return $this->con_value; + } + + /** + * Set the value of [con_category] column. + * + * @param string $v new value + * @return void + */ + public function setConCategory($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->con_category !== $v || $v === '') { + $this->con_category = $v; + $this->modifiedColumns[] = ContentPeer::CON_CATEGORY; + } + + } // setConCategory() + + /** + * Set the value of [con_parent] column. + * + * @param string $v new value + * @return void + */ + public function setConParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->con_parent !== $v || $v === '') { + $this->con_parent = $v; + $this->modifiedColumns[] = ContentPeer::CON_PARENT; + } + + } // setConParent() + + /** + * Set the value of [con_id] column. + * + * @param string $v new value + * @return void + */ + public function setConId($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->con_id !== $v || $v === '') { + $this->con_id = $v; + $this->modifiedColumns[] = ContentPeer::CON_ID; + } + + } // setConId() + + /** + * Set the value of [con_lang] column. + * + * @param string $v new value + * @return void + */ + public function setConLang($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->con_lang !== $v || $v === '') { + $this->con_lang = $v; + $this->modifiedColumns[] = ContentPeer::CON_LANG; + } + + } // setConLang() + + /** + * Set the value of [con_value] column. + * + * @param string $v new value + * @return void + */ + public function setConValue($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->con_value !== $v) { + $this->con_value = $v; + $this->modifiedColumns[] = ContentPeer::CON_VALUE; + } + + } // setConValue() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->con_category = $rs->getString($startcol + 0); + + $this->con_parent = $rs->getString($startcol + 1); + + $this->con_id = $rs->getString($startcol + 2); + + $this->con_lang = $rs->getString($startcol + 3); + + $this->con_value = $rs->getString($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = ContentPeer::NUM_COLUMNS - ContentPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Content object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ContentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ContentPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ContentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ContentPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ContentPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ContentPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ContentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getConCategory(); + break; + case 1: + return $this->getConParent(); + break; + case 2: + return $this->getConId(); + break; + case 3: + return $this->getConLang(); + break; + case 4: + return $this->getConValue(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ContentPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getConCategory(), + $keys[1] => $this->getConParent(), + $keys[2] => $this->getConId(), + $keys[3] => $this->getConLang(), + $keys[4] => $this->getConValue(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ContentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setConCategory($value); + break; + case 1: + $this->setConParent($value); + break; + case 2: + $this->setConId($value); + break; + case 3: + $this->setConLang($value); + break; + case 4: + $this->setConValue($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ContentPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setConCategory($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setConParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setConId($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setConLang($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setConValue($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ContentPeer::DATABASE_NAME); + + if ($this->isColumnModified(ContentPeer::CON_CATEGORY)) $criteria->add(ContentPeer::CON_CATEGORY, $this->con_category); + if ($this->isColumnModified(ContentPeer::CON_PARENT)) $criteria->add(ContentPeer::CON_PARENT, $this->con_parent); + if ($this->isColumnModified(ContentPeer::CON_ID)) $criteria->add(ContentPeer::CON_ID, $this->con_id); + if ($this->isColumnModified(ContentPeer::CON_LANG)) $criteria->add(ContentPeer::CON_LANG, $this->con_lang); + if ($this->isColumnModified(ContentPeer::CON_VALUE)) $criteria->add(ContentPeer::CON_VALUE, $this->con_value); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ContentPeer::DATABASE_NAME); + + $criteria->add(ContentPeer::CON_CATEGORY, $this->con_category); + $criteria->add(ContentPeer::CON_PARENT, $this->con_parent); + $criteria->add(ContentPeer::CON_ID, $this->con_id); + $criteria->add(ContentPeer::CON_LANG, $this->con_lang); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getConCategory(); + + $pks[1] = $this->getConParent(); + + $pks[2] = $this->getConId(); + + $pks[3] = $this->getConLang(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setConCategory($keys[0]); + + $this->setConParent($keys[1]); + + $this->setConId($keys[2]); + + $this->setConLang($keys[3]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Content (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setConValue($this->con_value); + + + $copyObj->setNew(true); + + $copyObj->setConCategory(''); // this is a pkey column, so set to default value + + $copyObj->setConParent(''); // this is a pkey column, so set to default value + + $copyObj->setConId(''); // this is a pkey column, so set to default value + + $copyObj->setConLang(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Content Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ContentPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ContentPeer(); + } + return self::$peer; + } + +} // BaseContent diff --git a/workflow/engine/classes/model/om/BaseContentPeer.php b/workflow/engine/classes/model/om/BaseContentPeer.php new file mode 100644 index 000000000..e87127971 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseContentPeer.php @@ -0,0 +1,593 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ContentPeer::getOMClass() +include_once 'classes/model/Content.php'; + +/** + * Base static class for performing query and update operations on the 'CONTENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseContentPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'CONTENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Content'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CON_CATEGORY field */ + const CON_CATEGORY = 'CONTENT.CON_CATEGORY'; + + /** the column name for the CON_PARENT field */ + const CON_PARENT = 'CONTENT.CON_PARENT'; + + /** the column name for the CON_ID field */ + const CON_ID = 'CONTENT.CON_ID'; + + /** the column name for the CON_LANG field */ + const CON_LANG = 'CONTENT.CON_LANG'; + + /** the column name for the CON_VALUE field */ + const CON_VALUE = 'CONTENT.CON_VALUE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ConCategory', 'ConParent', 'ConId', 'ConLang', 'ConValue', ), + BasePeer::TYPE_COLNAME => array (ContentPeer::CON_CATEGORY, ContentPeer::CON_PARENT, ContentPeer::CON_ID, ContentPeer::CON_LANG, ContentPeer::CON_VALUE, ), + BasePeer::TYPE_FIELDNAME => array ('CON_CATEGORY', 'CON_PARENT', 'CON_ID', 'CON_LANG', 'CON_VALUE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ConCategory' => 0, 'ConParent' => 1, 'ConId' => 2, 'ConLang' => 3, 'ConValue' => 4, ), + BasePeer::TYPE_COLNAME => array (ContentPeer::CON_CATEGORY => 0, ContentPeer::CON_PARENT => 1, ContentPeer::CON_ID => 2, ContentPeer::CON_LANG => 3, ContentPeer::CON_VALUE => 4, ), + BasePeer::TYPE_FIELDNAME => array ('CON_CATEGORY' => 0, 'CON_PARENT' => 1, 'CON_ID' => 2, 'CON_LANG' => 3, 'CON_VALUE' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ContentMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ContentMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ContentPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ContentPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ContentPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ContentPeer::CON_CATEGORY); + + $criteria->addSelectColumn(ContentPeer::CON_PARENT); + + $criteria->addSelectColumn(ContentPeer::CON_ID); + + $criteria->addSelectColumn(ContentPeer::CON_LANG); + + $criteria->addSelectColumn(ContentPeer::CON_VALUE); + + } + + const COUNT = 'COUNT(CONTENT.CON_CATEGORY)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT CONTENT.CON_CATEGORY)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ContentPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ContentPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ContentPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Content + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ContentPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ContentPeer::populateObjects(ContentPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ContentPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ContentPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ContentPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Content or Criteria object. + * + * @param mixed $values Criteria or Content object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Content object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Content or Criteria object. + * + * @param mixed $values Criteria or Content object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ContentPeer::CON_CATEGORY); + $selectCriteria->add(ContentPeer::CON_CATEGORY, $criteria->remove(ContentPeer::CON_CATEGORY), $comparison); + + $comparison = $criteria->getComparison(ContentPeer::CON_PARENT); + $selectCriteria->add(ContentPeer::CON_PARENT, $criteria->remove(ContentPeer::CON_PARENT), $comparison); + + $comparison = $criteria->getComparison(ContentPeer::CON_ID); + $selectCriteria->add(ContentPeer::CON_ID, $criteria->remove(ContentPeer::CON_ID), $comparison); + + $comparison = $criteria->getComparison(ContentPeer::CON_LANG); + $selectCriteria->add(ContentPeer::CON_LANG, $criteria->remove(ContentPeer::CON_LANG), $comparison); + + } else { // $values is Content object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the CONTENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ContentPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Content or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Content object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ContentPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Content) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + } + + $criteria->add(ContentPeer::CON_CATEGORY, $vals[0], Criteria::IN); + $criteria->add(ContentPeer::CON_PARENT, $vals[1], Criteria::IN); + $criteria->add(ContentPeer::CON_ID, $vals[2], Criteria::IN); + $criteria->add(ContentPeer::CON_LANG, $vals[3], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Content object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Content $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Content $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ContentPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ContentPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ContentPeer::CON_LANG)) + $columns[ContentPeer::CON_LANG] = $obj->getConLang(); + + } + + return BasePeer::doValidate(ContentPeer::DATABASE_NAME, ContentPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $con_category + @param string $con_parent + @param string $con_id + @param string $con_lang + + * @param Connection $con + * @return Content + */ + public static function retrieveByPK( $con_category, $con_parent, $con_id, $con_lang, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(ContentPeer::CON_CATEGORY, $con_category); + $criteria->add(ContentPeer::CON_PARENT, $con_parent); + $criteria->add(ContentPeer::CON_ID, $con_id); + $criteria->add(ContentPeer::CON_LANG, $con_lang); + $v = ContentPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseContentPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseContentPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ContentMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ContentMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseDbSource.php b/workflow/engine/classes/model/om/BaseDbSource.php new file mode 100644 index 000000000..5f44296a6 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDbSource.php @@ -0,0 +1,928 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/DbSourcePeer.php'; + +/** + * Base class that represents a row from the 'DB_SOURCE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDbSource extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var DbSourcePeer + */ + protected static $peer; + + + /** + * The value for the dbs_uid field. + * @var string + */ + protected $dbs_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the dbs_type field. + * @var string + */ + protected $dbs_type = '0'; + + + /** + * The value for the dbs_server field. + * @var string + */ + protected $dbs_server = '0'; + + + /** + * The value for the dbs_database_name field. + * @var string + */ + protected $dbs_database_name = '0'; + + + /** + * The value for the dbs_username field. + * @var string + */ + protected $dbs_username = '0'; + + + /** + * The value for the dbs_password field. + * @var string + */ + protected $dbs_password = ''; + + + /** + * The value for the dbs_port field. + * @var int + */ + protected $dbs_port = 0; + + + /** + * The value for the dbs_encode field. + * @var string + */ + protected $dbs_encode = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [dbs_uid] column value. + * + * @return string + */ + public function getDbsUid() + { + + return $this->dbs_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [dbs_type] column value. + * + * @return string + */ + public function getDbsType() + { + + return $this->dbs_type; + } + + /** + * Get the [dbs_server] column value. + * + * @return string + */ + public function getDbsServer() + { + + return $this->dbs_server; + } + + /** + * Get the [dbs_database_name] column value. + * + * @return string + */ + public function getDbsDatabaseName() + { + + return $this->dbs_database_name; + } + + /** + * Get the [dbs_username] column value. + * + * @return string + */ + public function getDbsUsername() + { + + return $this->dbs_username; + } + + /** + * Get the [dbs_password] column value. + * + * @return string + */ + public function getDbsPassword() + { + + return $this->dbs_password; + } + + /** + * Get the [dbs_port] column value. + * + * @return int + */ + public function getDbsPort() + { + + return $this->dbs_port; + } + + /** + * Get the [dbs_encode] column value. + * + * @return string + */ + public function getDbsEncode() + { + + return $this->dbs_encode; + } + + /** + * Set the value of [dbs_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDbsUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_uid !== $v || $v === '') { + $this->dbs_uid = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_UID; + } + + } // setDbsUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = DbSourcePeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [dbs_type] column. + * + * @param string $v new value + * @return void + */ + public function setDbsType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_type !== $v || $v === '0') { + $this->dbs_type = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_TYPE; + } + + } // setDbsType() + + /** + * Set the value of [dbs_server] column. + * + * @param string $v new value + * @return void + */ + public function setDbsServer($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_server !== $v || $v === '0') { + $this->dbs_server = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_SERVER; + } + + } // setDbsServer() + + /** + * Set the value of [dbs_database_name] column. + * + * @param string $v new value + * @return void + */ + public function setDbsDatabaseName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_database_name !== $v || $v === '0') { + $this->dbs_database_name = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_DATABASE_NAME; + } + + } // setDbsDatabaseName() + + /** + * Set the value of [dbs_username] column. + * + * @param string $v new value + * @return void + */ + public function setDbsUsername($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_username !== $v || $v === '0') { + $this->dbs_username = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_USERNAME; + } + + } // setDbsUsername() + + /** + * Set the value of [dbs_password] column. + * + * @param string $v new value + * @return void + */ + public function setDbsPassword($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_password !== $v || $v === '') { + $this->dbs_password = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_PASSWORD; + } + + } // setDbsPassword() + + /** + * Set the value of [dbs_port] column. + * + * @param int $v new value + * @return void + */ + public function setDbsPort($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->dbs_port !== $v || $v === 0) { + $this->dbs_port = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_PORT; + } + + } // setDbsPort() + + /** + * Set the value of [dbs_encode] column. + * + * @param string $v new value + * @return void + */ + public function setDbsEncode($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dbs_encode !== $v || $v === '') { + $this->dbs_encode = $v; + $this->modifiedColumns[] = DbSourcePeer::DBS_ENCODE; + } + + } // setDbsEncode() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->dbs_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->dbs_type = $rs->getString($startcol + 2); + + $this->dbs_server = $rs->getString($startcol + 3); + + $this->dbs_database_name = $rs->getString($startcol + 4); + + $this->dbs_username = $rs->getString($startcol + 5); + + $this->dbs_password = $rs->getString($startcol + 6); + + $this->dbs_port = $rs->getInt($startcol + 7); + + $this->dbs_encode = $rs->getString($startcol + 8); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 9; // 9 = DbSourcePeer::NUM_COLUMNS - DbSourcePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating DbSource object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + } + + try { + $con->begin(); + DbSourcePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = DbSourcePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += DbSourcePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = DbSourcePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DbSourcePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getDbsUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getDbsType(); + break; + case 3: + return $this->getDbsServer(); + break; + case 4: + return $this->getDbsDatabaseName(); + break; + case 5: + return $this->getDbsUsername(); + break; + case 6: + return $this->getDbsPassword(); + break; + case 7: + return $this->getDbsPort(); + break; + case 8: + return $this->getDbsEncode(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DbSourcePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getDbsUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getDbsType(), + $keys[3] => $this->getDbsServer(), + $keys[4] => $this->getDbsDatabaseName(), + $keys[5] => $this->getDbsUsername(), + $keys[6] => $this->getDbsPassword(), + $keys[7] => $this->getDbsPort(), + $keys[8] => $this->getDbsEncode(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DbSourcePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setDbsUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setDbsType($value); + break; + case 3: + $this->setDbsServer($value); + break; + case 4: + $this->setDbsDatabaseName($value); + break; + case 5: + $this->setDbsUsername($value); + break; + case 6: + $this->setDbsPassword($value); + break; + case 7: + $this->setDbsPort($value); + break; + case 8: + $this->setDbsEncode($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DbSourcePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setDbsUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setDbsType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDbsServer($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setDbsDatabaseName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setDbsUsername($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setDbsPassword($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setDbsPort($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setDbsEncode($arr[$keys[8]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(DbSourcePeer::DATABASE_NAME); + + if ($this->isColumnModified(DbSourcePeer::DBS_UID)) $criteria->add(DbSourcePeer::DBS_UID, $this->dbs_uid); + if ($this->isColumnModified(DbSourcePeer::PRO_UID)) $criteria->add(DbSourcePeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(DbSourcePeer::DBS_TYPE)) $criteria->add(DbSourcePeer::DBS_TYPE, $this->dbs_type); + if ($this->isColumnModified(DbSourcePeer::DBS_SERVER)) $criteria->add(DbSourcePeer::DBS_SERVER, $this->dbs_server); + if ($this->isColumnModified(DbSourcePeer::DBS_DATABASE_NAME)) $criteria->add(DbSourcePeer::DBS_DATABASE_NAME, $this->dbs_database_name); + if ($this->isColumnModified(DbSourcePeer::DBS_USERNAME)) $criteria->add(DbSourcePeer::DBS_USERNAME, $this->dbs_username); + if ($this->isColumnModified(DbSourcePeer::DBS_PASSWORD)) $criteria->add(DbSourcePeer::DBS_PASSWORD, $this->dbs_password); + if ($this->isColumnModified(DbSourcePeer::DBS_PORT)) $criteria->add(DbSourcePeer::DBS_PORT, $this->dbs_port); + if ($this->isColumnModified(DbSourcePeer::DBS_ENCODE)) $criteria->add(DbSourcePeer::DBS_ENCODE, $this->dbs_encode); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(DbSourcePeer::DATABASE_NAME); + + $criteria->add(DbSourcePeer::DBS_UID, $this->dbs_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getDbsUid(); + } + + /** + * Generic method to set the primary key (dbs_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setDbsUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of DbSource (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setDbsType($this->dbs_type); + + $copyObj->setDbsServer($this->dbs_server); + + $copyObj->setDbsDatabaseName($this->dbs_database_name); + + $copyObj->setDbsUsername($this->dbs_username); + + $copyObj->setDbsPassword($this->dbs_password); + + $copyObj->setDbsPort($this->dbs_port); + + $copyObj->setDbsEncode($this->dbs_encode); + + + $copyObj->setNew(true); + + $copyObj->setDbsUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return DbSource Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return DbSourcePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new DbSourcePeer(); + } + return self::$peer; + } + +} // BaseDbSource diff --git a/workflow/engine/classes/model/om/BaseDbSourcePeer.php b/workflow/engine/classes/model/om/BaseDbSourcePeer.php new file mode 100644 index 000000000..98ed4e963 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDbSourcePeer.php @@ -0,0 +1,605 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by DbSourcePeer::getOMClass() +include_once 'classes/model/DbSource.php'; + +/** + * Base static class for performing query and update operations on the 'DB_SOURCE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDbSourcePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'DB_SOURCE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.DbSource'; + + /** The total number of columns. */ + const NUM_COLUMNS = 9; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the DBS_UID field */ + const DBS_UID = 'DB_SOURCE.DBS_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'DB_SOURCE.PRO_UID'; + + /** the column name for the DBS_TYPE field */ + const DBS_TYPE = 'DB_SOURCE.DBS_TYPE'; + + /** the column name for the DBS_SERVER field */ + const DBS_SERVER = 'DB_SOURCE.DBS_SERVER'; + + /** the column name for the DBS_DATABASE_NAME field */ + const DBS_DATABASE_NAME = 'DB_SOURCE.DBS_DATABASE_NAME'; + + /** the column name for the DBS_USERNAME field */ + const DBS_USERNAME = 'DB_SOURCE.DBS_USERNAME'; + + /** the column name for the DBS_PASSWORD field */ + const DBS_PASSWORD = 'DB_SOURCE.DBS_PASSWORD'; + + /** the column name for the DBS_PORT field */ + const DBS_PORT = 'DB_SOURCE.DBS_PORT'; + + /** the column name for the DBS_ENCODE field */ + const DBS_ENCODE = 'DB_SOURCE.DBS_ENCODE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('DbsUid', 'ProUid', 'DbsType', 'DbsServer', 'DbsDatabaseName', 'DbsUsername', 'DbsPassword', 'DbsPort', 'DbsEncode', ), + BasePeer::TYPE_COLNAME => array (DbSourcePeer::DBS_UID, DbSourcePeer::PRO_UID, DbSourcePeer::DBS_TYPE, DbSourcePeer::DBS_SERVER, DbSourcePeer::DBS_DATABASE_NAME, DbSourcePeer::DBS_USERNAME, DbSourcePeer::DBS_PASSWORD, DbSourcePeer::DBS_PORT, DbSourcePeer::DBS_ENCODE, ), + BasePeer::TYPE_FIELDNAME => array ('DBS_UID', 'PRO_UID', 'DBS_TYPE', 'DBS_SERVER', 'DBS_DATABASE_NAME', 'DBS_USERNAME', 'DBS_PASSWORD', 'DBS_PORT', 'DBS_ENCODE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('DbsUid' => 0, 'ProUid' => 1, 'DbsType' => 2, 'DbsServer' => 3, 'DbsDatabaseName' => 4, 'DbsUsername' => 5, 'DbsPassword' => 6, 'DbsPort' => 7, 'DbsEncode' => 8, ), + BasePeer::TYPE_COLNAME => array (DbSourcePeer::DBS_UID => 0, DbSourcePeer::PRO_UID => 1, DbSourcePeer::DBS_TYPE => 2, DbSourcePeer::DBS_SERVER => 3, DbSourcePeer::DBS_DATABASE_NAME => 4, DbSourcePeer::DBS_USERNAME => 5, DbSourcePeer::DBS_PASSWORD => 6, DbSourcePeer::DBS_PORT => 7, DbSourcePeer::DBS_ENCODE => 8, ), + BasePeer::TYPE_FIELDNAME => array ('DBS_UID' => 0, 'PRO_UID' => 1, 'DBS_TYPE' => 2, 'DBS_SERVER' => 3, 'DBS_DATABASE_NAME' => 4, 'DBS_USERNAME' => 5, 'DBS_PASSWORD' => 6, 'DBS_PORT' => 7, 'DBS_ENCODE' => 8, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/DbSourceMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.DbSourceMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = DbSourcePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. DbSourcePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(DbSourcePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(DbSourcePeer::DBS_UID); + + $criteria->addSelectColumn(DbSourcePeer::PRO_UID); + + $criteria->addSelectColumn(DbSourcePeer::DBS_TYPE); + + $criteria->addSelectColumn(DbSourcePeer::DBS_SERVER); + + $criteria->addSelectColumn(DbSourcePeer::DBS_DATABASE_NAME); + + $criteria->addSelectColumn(DbSourcePeer::DBS_USERNAME); + + $criteria->addSelectColumn(DbSourcePeer::DBS_PASSWORD); + + $criteria->addSelectColumn(DbSourcePeer::DBS_PORT); + + $criteria->addSelectColumn(DbSourcePeer::DBS_ENCODE); + + } + + const COUNT = 'COUNT(DB_SOURCE.DBS_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT DB_SOURCE.DBS_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(DbSourcePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(DbSourcePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = DbSourcePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return DbSource + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = DbSourcePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return DbSourcePeer::populateObjects(DbSourcePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + DbSourcePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = DbSourcePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return DbSourcePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a DbSource or Criteria object. + * + * @param mixed $values Criteria or DbSource object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from DbSource object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a DbSource or Criteria object. + * + * @param mixed $values Criteria or DbSource object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(DbSourcePeer::DBS_UID); + $selectCriteria->add(DbSourcePeer::DBS_UID, $criteria->remove(DbSourcePeer::DBS_UID), $comparison); + + } else { // $values is DbSource object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the DB_SOURCE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(DbSourcePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a DbSource or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or DbSource object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(DbSourcePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof DbSource) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(DbSourcePeer::DBS_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given DbSource object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param DbSource $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(DbSource $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(DbSourcePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(DbSourcePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(DbSourcePeer::DATABASE_NAME, DbSourcePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return DbSource + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(DbSourcePeer::DATABASE_NAME); + + $criteria->add(DbSourcePeer::DBS_UID, $pk); + + + $v = DbSourcePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(DbSourcePeer::DBS_UID, $pks, Criteria::IN); + $objs = DbSourcePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseDbSourcePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseDbSourcePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/DbSourceMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.DbSourceMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseDepartment.php b/workflow/engine/classes/model/om/BaseDepartment.php new file mode 100644 index 000000000..5a1ec3327 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDepartment.php @@ -0,0 +1,822 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/DepartmentPeer.php'; + +/** + * Base class that represents a row from the 'DEPARTMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDepartment extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var DepartmentPeer + */ + protected static $peer; + + + /** + * The value for the dep_uid field. + * @var string + */ + protected $dep_uid = ''; + + + /** + * The value for the dep_parent field. + * @var string + */ + protected $dep_parent = ''; + + + /** + * The value for the dep_manager field. + * @var string + */ + protected $dep_manager = ''; + + + /** + * The value for the dep_location field. + * @var int + */ + protected $dep_location = 0; + + + /** + * The value for the dep_status field. + * @var string + */ + protected $dep_status = 'ACTIVE'; + + + /** + * The value for the dep_ref_code field. + * @var string + */ + protected $dep_ref_code = ''; + + + /** + * The value for the dep_ldap_dn field. + * @var string + */ + protected $dep_ldap_dn = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [dep_uid] column value. + * + * @return string + */ + public function getDepUid() + { + + return $this->dep_uid; + } + + /** + * Get the [dep_parent] column value. + * + * @return string + */ + public function getDepParent() + { + + return $this->dep_parent; + } + + /** + * Get the [dep_manager] column value. + * + * @return string + */ + public function getDepManager() + { + + return $this->dep_manager; + } + + /** + * Get the [dep_location] column value. + * + * @return int + */ + public function getDepLocation() + { + + return $this->dep_location; + } + + /** + * Get the [dep_status] column value. + * + * @return string + */ + public function getDepStatus() + { + + return $this->dep_status; + } + + /** + * Get the [dep_ref_code] column value. + * + * @return string + */ + public function getDepRefCode() + { + + return $this->dep_ref_code; + } + + /** + * Get the [dep_ldap_dn] column value. + * + * @return string + */ + public function getDepLdapDn() + { + + return $this->dep_ldap_dn; + } + + /** + * Set the value of [dep_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDepUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_uid !== $v || $v === '') { + $this->dep_uid = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_UID; + } + + } // setDepUid() + + /** + * Set the value of [dep_parent] column. + * + * @param string $v new value + * @return void + */ + public function setDepParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_parent !== $v || $v === '') { + $this->dep_parent = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_PARENT; + } + + } // setDepParent() + + /** + * Set the value of [dep_manager] column. + * + * @param string $v new value + * @return void + */ + public function setDepManager($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_manager !== $v || $v === '') { + $this->dep_manager = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_MANAGER; + } + + } // setDepManager() + + /** + * Set the value of [dep_location] column. + * + * @param int $v new value + * @return void + */ + public function setDepLocation($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->dep_location !== $v || $v === 0) { + $this->dep_location = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_LOCATION; + } + + } // setDepLocation() + + /** + * Set the value of [dep_status] column. + * + * @param string $v new value + * @return void + */ + public function setDepStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_status !== $v || $v === 'ACTIVE') { + $this->dep_status = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_STATUS; + } + + } // setDepStatus() + + /** + * Set the value of [dep_ref_code] column. + * + * @param string $v new value + * @return void + */ + public function setDepRefCode($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_ref_code !== $v || $v === '') { + $this->dep_ref_code = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_REF_CODE; + } + + } // setDepRefCode() + + /** + * Set the value of [dep_ldap_dn] column. + * + * @param string $v new value + * @return void + */ + public function setDepLdapDn($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_ldap_dn !== $v || $v === '') { + $this->dep_ldap_dn = $v; + $this->modifiedColumns[] = DepartmentPeer::DEP_LDAP_DN; + } + + } // setDepLdapDn() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->dep_uid = $rs->getString($startcol + 0); + + $this->dep_parent = $rs->getString($startcol + 1); + + $this->dep_manager = $rs->getString($startcol + 2); + + $this->dep_location = $rs->getInt($startcol + 3); + + $this->dep_status = $rs->getString($startcol + 4); + + $this->dep_ref_code = $rs->getString($startcol + 5); + + $this->dep_ldap_dn = $rs->getString($startcol + 6); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = DepartmentPeer::NUM_COLUMNS - DepartmentPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Department object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + DepartmentPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = DepartmentPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += DepartmentPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = DepartmentPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DepartmentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getDepUid(); + break; + case 1: + return $this->getDepParent(); + break; + case 2: + return $this->getDepManager(); + break; + case 3: + return $this->getDepLocation(); + break; + case 4: + return $this->getDepStatus(); + break; + case 5: + return $this->getDepRefCode(); + break; + case 6: + return $this->getDepLdapDn(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DepartmentPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getDepUid(), + $keys[1] => $this->getDepParent(), + $keys[2] => $this->getDepManager(), + $keys[3] => $this->getDepLocation(), + $keys[4] => $this->getDepStatus(), + $keys[5] => $this->getDepRefCode(), + $keys[6] => $this->getDepLdapDn(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DepartmentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setDepUid($value); + break; + case 1: + $this->setDepParent($value); + break; + case 2: + $this->setDepManager($value); + break; + case 3: + $this->setDepLocation($value); + break; + case 4: + $this->setDepStatus($value); + break; + case 5: + $this->setDepRefCode($value); + break; + case 6: + $this->setDepLdapDn($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DepartmentPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setDepUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setDepParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setDepManager($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDepLocation($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setDepStatus($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setDepRefCode($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setDepLdapDn($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(DepartmentPeer::DATABASE_NAME); + + if ($this->isColumnModified(DepartmentPeer::DEP_UID)) $criteria->add(DepartmentPeer::DEP_UID, $this->dep_uid); + if ($this->isColumnModified(DepartmentPeer::DEP_PARENT)) $criteria->add(DepartmentPeer::DEP_PARENT, $this->dep_parent); + if ($this->isColumnModified(DepartmentPeer::DEP_MANAGER)) $criteria->add(DepartmentPeer::DEP_MANAGER, $this->dep_manager); + if ($this->isColumnModified(DepartmentPeer::DEP_LOCATION)) $criteria->add(DepartmentPeer::DEP_LOCATION, $this->dep_location); + if ($this->isColumnModified(DepartmentPeer::DEP_STATUS)) $criteria->add(DepartmentPeer::DEP_STATUS, $this->dep_status); + if ($this->isColumnModified(DepartmentPeer::DEP_REF_CODE)) $criteria->add(DepartmentPeer::DEP_REF_CODE, $this->dep_ref_code); + if ($this->isColumnModified(DepartmentPeer::DEP_LDAP_DN)) $criteria->add(DepartmentPeer::DEP_LDAP_DN, $this->dep_ldap_dn); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(DepartmentPeer::DATABASE_NAME); + + $criteria->add(DepartmentPeer::DEP_UID, $this->dep_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getDepUid(); + } + + /** + * Generic method to set the primary key (dep_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setDepUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Department (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setDepParent($this->dep_parent); + + $copyObj->setDepManager($this->dep_manager); + + $copyObj->setDepLocation($this->dep_location); + + $copyObj->setDepStatus($this->dep_status); + + $copyObj->setDepRefCode($this->dep_ref_code); + + $copyObj->setDepLdapDn($this->dep_ldap_dn); + + + $copyObj->setNew(true); + + $copyObj->setDepUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Department Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return DepartmentPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new DepartmentPeer(); + } + return self::$peer; + } + +} // BaseDepartment diff --git a/workflow/engine/classes/model/om/BaseDepartmentPeer.php b/workflow/engine/classes/model/om/BaseDepartmentPeer.php new file mode 100644 index 000000000..83668059e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDepartmentPeer.php @@ -0,0 +1,595 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by DepartmentPeer::getOMClass() +include_once 'classes/model/Department.php'; + +/** + * Base static class for performing query and update operations on the 'DEPARTMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDepartmentPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'DEPARTMENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Department'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the DEP_UID field */ + const DEP_UID = 'DEPARTMENT.DEP_UID'; + + /** the column name for the DEP_PARENT field */ + const DEP_PARENT = 'DEPARTMENT.DEP_PARENT'; + + /** the column name for the DEP_MANAGER field */ + const DEP_MANAGER = 'DEPARTMENT.DEP_MANAGER'; + + /** the column name for the DEP_LOCATION field */ + const DEP_LOCATION = 'DEPARTMENT.DEP_LOCATION'; + + /** the column name for the DEP_STATUS field */ + const DEP_STATUS = 'DEPARTMENT.DEP_STATUS'; + + /** the column name for the DEP_REF_CODE field */ + const DEP_REF_CODE = 'DEPARTMENT.DEP_REF_CODE'; + + /** the column name for the DEP_LDAP_DN field */ + const DEP_LDAP_DN = 'DEPARTMENT.DEP_LDAP_DN'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('DepUid', 'DepParent', 'DepManager', 'DepLocation', 'DepStatus', 'DepRefCode', 'DepLdapDn', ), + BasePeer::TYPE_COLNAME => array (DepartmentPeer::DEP_UID, DepartmentPeer::DEP_PARENT, DepartmentPeer::DEP_MANAGER, DepartmentPeer::DEP_LOCATION, DepartmentPeer::DEP_STATUS, DepartmentPeer::DEP_REF_CODE, DepartmentPeer::DEP_LDAP_DN, ), + BasePeer::TYPE_FIELDNAME => array ('DEP_UID', 'DEP_PARENT', 'DEP_MANAGER', 'DEP_LOCATION', 'DEP_STATUS', 'DEP_REF_CODE', 'DEP_LDAP_DN', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('DepUid' => 0, 'DepParent' => 1, 'DepManager' => 2, 'DepLocation' => 3, 'DepStatus' => 4, 'DepRefCode' => 5, 'DepLdapDn' => 6, ), + BasePeer::TYPE_COLNAME => array (DepartmentPeer::DEP_UID => 0, DepartmentPeer::DEP_PARENT => 1, DepartmentPeer::DEP_MANAGER => 2, DepartmentPeer::DEP_LOCATION => 3, DepartmentPeer::DEP_STATUS => 4, DepartmentPeer::DEP_REF_CODE => 5, DepartmentPeer::DEP_LDAP_DN => 6, ), + BasePeer::TYPE_FIELDNAME => array ('DEP_UID' => 0, 'DEP_PARENT' => 1, 'DEP_MANAGER' => 2, 'DEP_LOCATION' => 3, 'DEP_STATUS' => 4, 'DEP_REF_CODE' => 5, 'DEP_LDAP_DN' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/DepartmentMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.DepartmentMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = DepartmentPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. DepartmentPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(DepartmentPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(DepartmentPeer::DEP_UID); + + $criteria->addSelectColumn(DepartmentPeer::DEP_PARENT); + + $criteria->addSelectColumn(DepartmentPeer::DEP_MANAGER); + + $criteria->addSelectColumn(DepartmentPeer::DEP_LOCATION); + + $criteria->addSelectColumn(DepartmentPeer::DEP_STATUS); + + $criteria->addSelectColumn(DepartmentPeer::DEP_REF_CODE); + + $criteria->addSelectColumn(DepartmentPeer::DEP_LDAP_DN); + + } + + const COUNT = 'COUNT(DEPARTMENT.DEP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT DEPARTMENT.DEP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(DepartmentPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(DepartmentPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = DepartmentPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Department + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = DepartmentPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return DepartmentPeer::populateObjects(DepartmentPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + DepartmentPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = DepartmentPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return DepartmentPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Department or Criteria object. + * + * @param mixed $values Criteria or Department object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Department object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Department or Criteria object. + * + * @param mixed $values Criteria or Department object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(DepartmentPeer::DEP_UID); + $selectCriteria->add(DepartmentPeer::DEP_UID, $criteria->remove(DepartmentPeer::DEP_UID), $comparison); + + } else { // $values is Department object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the DEPARTMENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(DepartmentPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Department or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Department object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(DepartmentPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Department) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(DepartmentPeer::DEP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Department object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Department $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Department $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(DepartmentPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(DepartmentPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(DepartmentPeer::DATABASE_NAME, DepartmentPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Department + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(DepartmentPeer::DATABASE_NAME); + + $criteria->add(DepartmentPeer::DEP_UID, $pk); + + + $v = DepartmentPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(DepartmentPeer::DEP_UID, $pks, Criteria::IN); + $objs = DepartmentPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseDepartmentPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseDepartmentPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/DepartmentMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.DepartmentMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseDimTimeComplete.php b/workflow/engine/classes/model/om/BaseDimTimeComplete.php new file mode 100644 index 000000000..1c566fccc --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDimTimeComplete.php @@ -0,0 +1,875 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/DimTimeCompletePeer.php'; + +/** + * Base class that represents a row from the 'DIM_TIME_COMPLETE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDimTimeComplete extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var DimTimeCompletePeer + */ + protected static $peer; + + + /** + * The value for the time_id field. + * @var string + */ + protected $time_id = ''; + + + /** + * The value for the month_id field. + * @var int + */ + protected $month_id = 0; + + + /** + * The value for the qtr_id field. + * @var int + */ + protected $qtr_id = 0; + + + /** + * The value for the year_id field. + * @var int + */ + protected $year_id = 0; + + + /** + * The value for the month_name field. + * @var string + */ + protected $month_name = '0'; + + + /** + * The value for the month_desc field. + * @var string + */ + protected $month_desc = ''; + + + /** + * The value for the qtr_name field. + * @var string + */ + protected $qtr_name = ''; + + + /** + * The value for the qtr_desc field. + * @var string + */ + protected $qtr_desc = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [time_id] column value. + * + * @return string + */ + public function getTimeId() + { + + return $this->time_id; + } + + /** + * Get the [month_id] column value. + * + * @return int + */ + public function getMonthId() + { + + return $this->month_id; + } + + /** + * Get the [qtr_id] column value. + * + * @return int + */ + public function getQtrId() + { + + return $this->qtr_id; + } + + /** + * Get the [year_id] column value. + * + * @return int + */ + public function getYearId() + { + + return $this->year_id; + } + + /** + * Get the [month_name] column value. + * + * @return string + */ + public function getMonthName() + { + + return $this->month_name; + } + + /** + * Get the [month_desc] column value. + * + * @return string + */ + public function getMonthDesc() + { + + return $this->month_desc; + } + + /** + * Get the [qtr_name] column value. + * + * @return string + */ + public function getQtrName() + { + + return $this->qtr_name; + } + + /** + * Get the [qtr_desc] column value. + * + * @return string + */ + public function getQtrDesc() + { + + return $this->qtr_desc; + } + + /** + * Set the value of [time_id] column. + * + * @param string $v new value + * @return void + */ + public function setTimeId($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->time_id !== $v || $v === '') { + $this->time_id = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::TIME_ID; + } + + } // setTimeId() + + /** + * Set the value of [month_id] column. + * + * @param int $v new value + * @return void + */ + public function setMonthId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->month_id !== $v || $v === 0) { + $this->month_id = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::MONTH_ID; + } + + } // setMonthId() + + /** + * Set the value of [qtr_id] column. + * + * @param int $v new value + * @return void + */ + public function setQtrId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->qtr_id !== $v || $v === 0) { + $this->qtr_id = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::QTR_ID; + } + + } // setQtrId() + + /** + * Set the value of [year_id] column. + * + * @param int $v new value + * @return void + */ + public function setYearId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->year_id !== $v || $v === 0) { + $this->year_id = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::YEAR_ID; + } + + } // setYearId() + + /** + * Set the value of [month_name] column. + * + * @param string $v new value + * @return void + */ + public function setMonthName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->month_name !== $v || $v === '0') { + $this->month_name = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::MONTH_NAME; + } + + } // setMonthName() + + /** + * Set the value of [month_desc] column. + * + * @param string $v new value + * @return void + */ + public function setMonthDesc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->month_desc !== $v || $v === '') { + $this->month_desc = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::MONTH_DESC; + } + + } // setMonthDesc() + + /** + * Set the value of [qtr_name] column. + * + * @param string $v new value + * @return void + */ + public function setQtrName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->qtr_name !== $v || $v === '') { + $this->qtr_name = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::QTR_NAME; + } + + } // setQtrName() + + /** + * Set the value of [qtr_desc] column. + * + * @param string $v new value + * @return void + */ + public function setQtrDesc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->qtr_desc !== $v || $v === '') { + $this->qtr_desc = $v; + $this->modifiedColumns[] = DimTimeCompletePeer::QTR_DESC; + } + + } // setQtrDesc() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->time_id = $rs->getString($startcol + 0); + + $this->month_id = $rs->getInt($startcol + 1); + + $this->qtr_id = $rs->getInt($startcol + 2); + + $this->year_id = $rs->getInt($startcol + 3); + + $this->month_name = $rs->getString($startcol + 4); + + $this->month_desc = $rs->getString($startcol + 5); + + $this->qtr_name = $rs->getString($startcol + 6); + + $this->qtr_desc = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = DimTimeCompletePeer::NUM_COLUMNS - DimTimeCompletePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating DimTimeComplete object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DimTimeCompletePeer::DATABASE_NAME); + } + + try { + $con->begin(); + DimTimeCompletePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DimTimeCompletePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = DimTimeCompletePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += DimTimeCompletePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = DimTimeCompletePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DimTimeCompletePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getTimeId(); + break; + case 1: + return $this->getMonthId(); + break; + case 2: + return $this->getQtrId(); + break; + case 3: + return $this->getYearId(); + break; + case 4: + return $this->getMonthName(); + break; + case 5: + return $this->getMonthDesc(); + break; + case 6: + return $this->getQtrName(); + break; + case 7: + return $this->getQtrDesc(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DimTimeCompletePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getTimeId(), + $keys[1] => $this->getMonthId(), + $keys[2] => $this->getQtrId(), + $keys[3] => $this->getYearId(), + $keys[4] => $this->getMonthName(), + $keys[5] => $this->getMonthDesc(), + $keys[6] => $this->getQtrName(), + $keys[7] => $this->getQtrDesc(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DimTimeCompletePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setTimeId($value); + break; + case 1: + $this->setMonthId($value); + break; + case 2: + $this->setQtrId($value); + break; + case 3: + $this->setYearId($value); + break; + case 4: + $this->setMonthName($value); + break; + case 5: + $this->setMonthDesc($value); + break; + case 6: + $this->setQtrName($value); + break; + case 7: + $this->setQtrDesc($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DimTimeCompletePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setTimeId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setMonthId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setQtrId($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setYearId($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setMonthName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setMonthDesc($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setQtrName($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setQtrDesc($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(DimTimeCompletePeer::DATABASE_NAME); + + if ($this->isColumnModified(DimTimeCompletePeer::TIME_ID)) $criteria->add(DimTimeCompletePeer::TIME_ID, $this->time_id); + if ($this->isColumnModified(DimTimeCompletePeer::MONTH_ID)) $criteria->add(DimTimeCompletePeer::MONTH_ID, $this->month_id); + if ($this->isColumnModified(DimTimeCompletePeer::QTR_ID)) $criteria->add(DimTimeCompletePeer::QTR_ID, $this->qtr_id); + if ($this->isColumnModified(DimTimeCompletePeer::YEAR_ID)) $criteria->add(DimTimeCompletePeer::YEAR_ID, $this->year_id); + if ($this->isColumnModified(DimTimeCompletePeer::MONTH_NAME)) $criteria->add(DimTimeCompletePeer::MONTH_NAME, $this->month_name); + if ($this->isColumnModified(DimTimeCompletePeer::MONTH_DESC)) $criteria->add(DimTimeCompletePeer::MONTH_DESC, $this->month_desc); + if ($this->isColumnModified(DimTimeCompletePeer::QTR_NAME)) $criteria->add(DimTimeCompletePeer::QTR_NAME, $this->qtr_name); + if ($this->isColumnModified(DimTimeCompletePeer::QTR_DESC)) $criteria->add(DimTimeCompletePeer::QTR_DESC, $this->qtr_desc); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(DimTimeCompletePeer::DATABASE_NAME); + + $criteria->add(DimTimeCompletePeer::TIME_ID, $this->time_id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getTimeId(); + } + + /** + * Generic method to set the primary key (time_id column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setTimeId($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of DimTimeComplete (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setMonthId($this->month_id); + + $copyObj->setQtrId($this->qtr_id); + + $copyObj->setYearId($this->year_id); + + $copyObj->setMonthName($this->month_name); + + $copyObj->setMonthDesc($this->month_desc); + + $copyObj->setQtrName($this->qtr_name); + + $copyObj->setQtrDesc($this->qtr_desc); + + + $copyObj->setNew(true); + + $copyObj->setTimeId(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return DimTimeComplete Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return DimTimeCompletePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new DimTimeCompletePeer(); + } + return self::$peer; + } + +} // BaseDimTimeComplete diff --git a/workflow/engine/classes/model/om/BaseDimTimeCompletePeer.php b/workflow/engine/classes/model/om/BaseDimTimeCompletePeer.php new file mode 100644 index 000000000..5c2cadd60 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDimTimeCompletePeer.php @@ -0,0 +1,600 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by DimTimeCompletePeer::getOMClass() +include_once 'classes/model/DimTimeComplete.php'; + +/** + * Base static class for performing query and update operations on the 'DIM_TIME_COMPLETE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDimTimeCompletePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'DIM_TIME_COMPLETE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.DimTimeComplete'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the TIME_ID field */ + const TIME_ID = 'DIM_TIME_COMPLETE.TIME_ID'; + + /** the column name for the MONTH_ID field */ + const MONTH_ID = 'DIM_TIME_COMPLETE.MONTH_ID'; + + /** the column name for the QTR_ID field */ + const QTR_ID = 'DIM_TIME_COMPLETE.QTR_ID'; + + /** the column name for the YEAR_ID field */ + const YEAR_ID = 'DIM_TIME_COMPLETE.YEAR_ID'; + + /** the column name for the MONTH_NAME field */ + const MONTH_NAME = 'DIM_TIME_COMPLETE.MONTH_NAME'; + + /** the column name for the MONTH_DESC field */ + const MONTH_DESC = 'DIM_TIME_COMPLETE.MONTH_DESC'; + + /** the column name for the QTR_NAME field */ + const QTR_NAME = 'DIM_TIME_COMPLETE.QTR_NAME'; + + /** the column name for the QTR_DESC field */ + const QTR_DESC = 'DIM_TIME_COMPLETE.QTR_DESC'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('TimeId', 'MonthId', 'QtrId', 'YearId', 'MonthName', 'MonthDesc', 'QtrName', 'QtrDesc', ), + BasePeer::TYPE_COLNAME => array (DimTimeCompletePeer::TIME_ID, DimTimeCompletePeer::MONTH_ID, DimTimeCompletePeer::QTR_ID, DimTimeCompletePeer::YEAR_ID, DimTimeCompletePeer::MONTH_NAME, DimTimeCompletePeer::MONTH_DESC, DimTimeCompletePeer::QTR_NAME, DimTimeCompletePeer::QTR_DESC, ), + BasePeer::TYPE_FIELDNAME => array ('TIME_ID', 'MONTH_ID', 'QTR_ID', 'YEAR_ID', 'MONTH_NAME', 'MONTH_DESC', 'QTR_NAME', 'QTR_DESC', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('TimeId' => 0, 'MonthId' => 1, 'QtrId' => 2, 'YearId' => 3, 'MonthName' => 4, 'MonthDesc' => 5, 'QtrName' => 6, 'QtrDesc' => 7, ), + BasePeer::TYPE_COLNAME => array (DimTimeCompletePeer::TIME_ID => 0, DimTimeCompletePeer::MONTH_ID => 1, DimTimeCompletePeer::QTR_ID => 2, DimTimeCompletePeer::YEAR_ID => 3, DimTimeCompletePeer::MONTH_NAME => 4, DimTimeCompletePeer::MONTH_DESC => 5, DimTimeCompletePeer::QTR_NAME => 6, DimTimeCompletePeer::QTR_DESC => 7, ), + BasePeer::TYPE_FIELDNAME => array ('TIME_ID' => 0, 'MONTH_ID' => 1, 'QTR_ID' => 2, 'YEAR_ID' => 3, 'MONTH_NAME' => 4, 'MONTH_DESC' => 5, 'QTR_NAME' => 6, 'QTR_DESC' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/DimTimeCompleteMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.DimTimeCompleteMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = DimTimeCompletePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. DimTimeCompletePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(DimTimeCompletePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(DimTimeCompletePeer::TIME_ID); + + $criteria->addSelectColumn(DimTimeCompletePeer::MONTH_ID); + + $criteria->addSelectColumn(DimTimeCompletePeer::QTR_ID); + + $criteria->addSelectColumn(DimTimeCompletePeer::YEAR_ID); + + $criteria->addSelectColumn(DimTimeCompletePeer::MONTH_NAME); + + $criteria->addSelectColumn(DimTimeCompletePeer::MONTH_DESC); + + $criteria->addSelectColumn(DimTimeCompletePeer::QTR_NAME); + + $criteria->addSelectColumn(DimTimeCompletePeer::QTR_DESC); + + } + + const COUNT = 'COUNT(DIM_TIME_COMPLETE.TIME_ID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT DIM_TIME_COMPLETE.TIME_ID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(DimTimeCompletePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(DimTimeCompletePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = DimTimeCompletePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return DimTimeComplete + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = DimTimeCompletePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return DimTimeCompletePeer::populateObjects(DimTimeCompletePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + DimTimeCompletePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = DimTimeCompletePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return DimTimeCompletePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a DimTimeComplete or Criteria object. + * + * @param mixed $values Criteria or DimTimeComplete object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from DimTimeComplete object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a DimTimeComplete or Criteria object. + * + * @param mixed $values Criteria or DimTimeComplete object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(DimTimeCompletePeer::TIME_ID); + $selectCriteria->add(DimTimeCompletePeer::TIME_ID, $criteria->remove(DimTimeCompletePeer::TIME_ID), $comparison); + + } else { // $values is DimTimeComplete object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the DIM_TIME_COMPLETE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(DimTimeCompletePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a DimTimeComplete or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or DimTimeComplete object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(DimTimeCompletePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof DimTimeComplete) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(DimTimeCompletePeer::TIME_ID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given DimTimeComplete object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param DimTimeComplete $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(DimTimeComplete $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(DimTimeCompletePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(DimTimeCompletePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(DimTimeCompletePeer::DATABASE_NAME, DimTimeCompletePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return DimTimeComplete + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(DimTimeCompletePeer::DATABASE_NAME); + + $criteria->add(DimTimeCompletePeer::TIME_ID, $pk); + + + $v = DimTimeCompletePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(DimTimeCompletePeer::TIME_ID, $pks, Criteria::IN); + $objs = DimTimeCompletePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseDimTimeCompletePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseDimTimeCompletePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/DimTimeCompleteMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.DimTimeCompleteMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseDimTimeDelegate.php b/workflow/engine/classes/model/om/BaseDimTimeDelegate.php new file mode 100644 index 000000000..27c1b1f06 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDimTimeDelegate.php @@ -0,0 +1,875 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/DimTimeDelegatePeer.php'; + +/** + * Base class that represents a row from the 'DIM_TIME_DELEGATE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDimTimeDelegate extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var DimTimeDelegatePeer + */ + protected static $peer; + + + /** + * The value for the time_id field. + * @var string + */ + protected $time_id = ''; + + + /** + * The value for the month_id field. + * @var int + */ + protected $month_id = 0; + + + /** + * The value for the qtr_id field. + * @var int + */ + protected $qtr_id = 0; + + + /** + * The value for the year_id field. + * @var int + */ + protected $year_id = 0; + + + /** + * The value for the month_name field. + * @var string + */ + protected $month_name = '0'; + + + /** + * The value for the month_desc field. + * @var string + */ + protected $month_desc = ''; + + + /** + * The value for the qtr_name field. + * @var string + */ + protected $qtr_name = ''; + + + /** + * The value for the qtr_desc field. + * @var string + */ + protected $qtr_desc = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [time_id] column value. + * + * @return string + */ + public function getTimeId() + { + + return $this->time_id; + } + + /** + * Get the [month_id] column value. + * + * @return int + */ + public function getMonthId() + { + + return $this->month_id; + } + + /** + * Get the [qtr_id] column value. + * + * @return int + */ + public function getQtrId() + { + + return $this->qtr_id; + } + + /** + * Get the [year_id] column value. + * + * @return int + */ + public function getYearId() + { + + return $this->year_id; + } + + /** + * Get the [month_name] column value. + * + * @return string + */ + public function getMonthName() + { + + return $this->month_name; + } + + /** + * Get the [month_desc] column value. + * + * @return string + */ + public function getMonthDesc() + { + + return $this->month_desc; + } + + /** + * Get the [qtr_name] column value. + * + * @return string + */ + public function getQtrName() + { + + return $this->qtr_name; + } + + /** + * Get the [qtr_desc] column value. + * + * @return string + */ + public function getQtrDesc() + { + + return $this->qtr_desc; + } + + /** + * Set the value of [time_id] column. + * + * @param string $v new value + * @return void + */ + public function setTimeId($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->time_id !== $v || $v === '') { + $this->time_id = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::TIME_ID; + } + + } // setTimeId() + + /** + * Set the value of [month_id] column. + * + * @param int $v new value + * @return void + */ + public function setMonthId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->month_id !== $v || $v === 0) { + $this->month_id = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::MONTH_ID; + } + + } // setMonthId() + + /** + * Set the value of [qtr_id] column. + * + * @param int $v new value + * @return void + */ + public function setQtrId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->qtr_id !== $v || $v === 0) { + $this->qtr_id = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::QTR_ID; + } + + } // setQtrId() + + /** + * Set the value of [year_id] column. + * + * @param int $v new value + * @return void + */ + public function setYearId($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->year_id !== $v || $v === 0) { + $this->year_id = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::YEAR_ID; + } + + } // setYearId() + + /** + * Set the value of [month_name] column. + * + * @param string $v new value + * @return void + */ + public function setMonthName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->month_name !== $v || $v === '0') { + $this->month_name = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::MONTH_NAME; + } + + } // setMonthName() + + /** + * Set the value of [month_desc] column. + * + * @param string $v new value + * @return void + */ + public function setMonthDesc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->month_desc !== $v || $v === '') { + $this->month_desc = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::MONTH_DESC; + } + + } // setMonthDesc() + + /** + * Set the value of [qtr_name] column. + * + * @param string $v new value + * @return void + */ + public function setQtrName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->qtr_name !== $v || $v === '') { + $this->qtr_name = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::QTR_NAME; + } + + } // setQtrName() + + /** + * Set the value of [qtr_desc] column. + * + * @param string $v new value + * @return void + */ + public function setQtrDesc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->qtr_desc !== $v || $v === '') { + $this->qtr_desc = $v; + $this->modifiedColumns[] = DimTimeDelegatePeer::QTR_DESC; + } + + } // setQtrDesc() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->time_id = $rs->getString($startcol + 0); + + $this->month_id = $rs->getInt($startcol + 1); + + $this->qtr_id = $rs->getInt($startcol + 2); + + $this->year_id = $rs->getInt($startcol + 3); + + $this->month_name = $rs->getString($startcol + 4); + + $this->month_desc = $rs->getString($startcol + 5); + + $this->qtr_name = $rs->getString($startcol + 6); + + $this->qtr_desc = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = DimTimeDelegatePeer::NUM_COLUMNS - DimTimeDelegatePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating DimTimeDelegate object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DimTimeDelegatePeer::DATABASE_NAME); + } + + try { + $con->begin(); + DimTimeDelegatePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DimTimeDelegatePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = DimTimeDelegatePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += DimTimeDelegatePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = DimTimeDelegatePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DimTimeDelegatePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getTimeId(); + break; + case 1: + return $this->getMonthId(); + break; + case 2: + return $this->getQtrId(); + break; + case 3: + return $this->getYearId(); + break; + case 4: + return $this->getMonthName(); + break; + case 5: + return $this->getMonthDesc(); + break; + case 6: + return $this->getQtrName(); + break; + case 7: + return $this->getQtrDesc(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DimTimeDelegatePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getTimeId(), + $keys[1] => $this->getMonthId(), + $keys[2] => $this->getQtrId(), + $keys[3] => $this->getYearId(), + $keys[4] => $this->getMonthName(), + $keys[5] => $this->getMonthDesc(), + $keys[6] => $this->getQtrName(), + $keys[7] => $this->getQtrDesc(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DimTimeDelegatePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setTimeId($value); + break; + case 1: + $this->setMonthId($value); + break; + case 2: + $this->setQtrId($value); + break; + case 3: + $this->setYearId($value); + break; + case 4: + $this->setMonthName($value); + break; + case 5: + $this->setMonthDesc($value); + break; + case 6: + $this->setQtrName($value); + break; + case 7: + $this->setQtrDesc($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DimTimeDelegatePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setTimeId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setMonthId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setQtrId($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setYearId($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setMonthName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setMonthDesc($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setQtrName($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setQtrDesc($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(DimTimeDelegatePeer::DATABASE_NAME); + + if ($this->isColumnModified(DimTimeDelegatePeer::TIME_ID)) $criteria->add(DimTimeDelegatePeer::TIME_ID, $this->time_id); + if ($this->isColumnModified(DimTimeDelegatePeer::MONTH_ID)) $criteria->add(DimTimeDelegatePeer::MONTH_ID, $this->month_id); + if ($this->isColumnModified(DimTimeDelegatePeer::QTR_ID)) $criteria->add(DimTimeDelegatePeer::QTR_ID, $this->qtr_id); + if ($this->isColumnModified(DimTimeDelegatePeer::YEAR_ID)) $criteria->add(DimTimeDelegatePeer::YEAR_ID, $this->year_id); + if ($this->isColumnModified(DimTimeDelegatePeer::MONTH_NAME)) $criteria->add(DimTimeDelegatePeer::MONTH_NAME, $this->month_name); + if ($this->isColumnModified(DimTimeDelegatePeer::MONTH_DESC)) $criteria->add(DimTimeDelegatePeer::MONTH_DESC, $this->month_desc); + if ($this->isColumnModified(DimTimeDelegatePeer::QTR_NAME)) $criteria->add(DimTimeDelegatePeer::QTR_NAME, $this->qtr_name); + if ($this->isColumnModified(DimTimeDelegatePeer::QTR_DESC)) $criteria->add(DimTimeDelegatePeer::QTR_DESC, $this->qtr_desc); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(DimTimeDelegatePeer::DATABASE_NAME); + + $criteria->add(DimTimeDelegatePeer::TIME_ID, $this->time_id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getTimeId(); + } + + /** + * Generic method to set the primary key (time_id column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setTimeId($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of DimTimeDelegate (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setMonthId($this->month_id); + + $copyObj->setQtrId($this->qtr_id); + + $copyObj->setYearId($this->year_id); + + $copyObj->setMonthName($this->month_name); + + $copyObj->setMonthDesc($this->month_desc); + + $copyObj->setQtrName($this->qtr_name); + + $copyObj->setQtrDesc($this->qtr_desc); + + + $copyObj->setNew(true); + + $copyObj->setTimeId(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return DimTimeDelegate Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return DimTimeDelegatePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new DimTimeDelegatePeer(); + } + return self::$peer; + } + +} // BaseDimTimeDelegate diff --git a/workflow/engine/classes/model/om/BaseDimTimeDelegatePeer.php b/workflow/engine/classes/model/om/BaseDimTimeDelegatePeer.php new file mode 100644 index 000000000..7113039d2 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDimTimeDelegatePeer.php @@ -0,0 +1,600 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by DimTimeDelegatePeer::getOMClass() +include_once 'classes/model/DimTimeDelegate.php'; + +/** + * Base static class for performing query and update operations on the 'DIM_TIME_DELEGATE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDimTimeDelegatePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'DIM_TIME_DELEGATE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.DimTimeDelegate'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the TIME_ID field */ + const TIME_ID = 'DIM_TIME_DELEGATE.TIME_ID'; + + /** the column name for the MONTH_ID field */ + const MONTH_ID = 'DIM_TIME_DELEGATE.MONTH_ID'; + + /** the column name for the QTR_ID field */ + const QTR_ID = 'DIM_TIME_DELEGATE.QTR_ID'; + + /** the column name for the YEAR_ID field */ + const YEAR_ID = 'DIM_TIME_DELEGATE.YEAR_ID'; + + /** the column name for the MONTH_NAME field */ + const MONTH_NAME = 'DIM_TIME_DELEGATE.MONTH_NAME'; + + /** the column name for the MONTH_DESC field */ + const MONTH_DESC = 'DIM_TIME_DELEGATE.MONTH_DESC'; + + /** the column name for the QTR_NAME field */ + const QTR_NAME = 'DIM_TIME_DELEGATE.QTR_NAME'; + + /** the column name for the QTR_DESC field */ + const QTR_DESC = 'DIM_TIME_DELEGATE.QTR_DESC'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('TimeId', 'MonthId', 'QtrId', 'YearId', 'MonthName', 'MonthDesc', 'QtrName', 'QtrDesc', ), + BasePeer::TYPE_COLNAME => array (DimTimeDelegatePeer::TIME_ID, DimTimeDelegatePeer::MONTH_ID, DimTimeDelegatePeer::QTR_ID, DimTimeDelegatePeer::YEAR_ID, DimTimeDelegatePeer::MONTH_NAME, DimTimeDelegatePeer::MONTH_DESC, DimTimeDelegatePeer::QTR_NAME, DimTimeDelegatePeer::QTR_DESC, ), + BasePeer::TYPE_FIELDNAME => array ('TIME_ID', 'MONTH_ID', 'QTR_ID', 'YEAR_ID', 'MONTH_NAME', 'MONTH_DESC', 'QTR_NAME', 'QTR_DESC', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('TimeId' => 0, 'MonthId' => 1, 'QtrId' => 2, 'YearId' => 3, 'MonthName' => 4, 'MonthDesc' => 5, 'QtrName' => 6, 'QtrDesc' => 7, ), + BasePeer::TYPE_COLNAME => array (DimTimeDelegatePeer::TIME_ID => 0, DimTimeDelegatePeer::MONTH_ID => 1, DimTimeDelegatePeer::QTR_ID => 2, DimTimeDelegatePeer::YEAR_ID => 3, DimTimeDelegatePeer::MONTH_NAME => 4, DimTimeDelegatePeer::MONTH_DESC => 5, DimTimeDelegatePeer::QTR_NAME => 6, DimTimeDelegatePeer::QTR_DESC => 7, ), + BasePeer::TYPE_FIELDNAME => array ('TIME_ID' => 0, 'MONTH_ID' => 1, 'QTR_ID' => 2, 'YEAR_ID' => 3, 'MONTH_NAME' => 4, 'MONTH_DESC' => 5, 'QTR_NAME' => 6, 'QTR_DESC' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/DimTimeDelegateMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.DimTimeDelegateMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = DimTimeDelegatePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. DimTimeDelegatePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(DimTimeDelegatePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(DimTimeDelegatePeer::TIME_ID); + + $criteria->addSelectColumn(DimTimeDelegatePeer::MONTH_ID); + + $criteria->addSelectColumn(DimTimeDelegatePeer::QTR_ID); + + $criteria->addSelectColumn(DimTimeDelegatePeer::YEAR_ID); + + $criteria->addSelectColumn(DimTimeDelegatePeer::MONTH_NAME); + + $criteria->addSelectColumn(DimTimeDelegatePeer::MONTH_DESC); + + $criteria->addSelectColumn(DimTimeDelegatePeer::QTR_NAME); + + $criteria->addSelectColumn(DimTimeDelegatePeer::QTR_DESC); + + } + + const COUNT = 'COUNT(DIM_TIME_DELEGATE.TIME_ID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT DIM_TIME_DELEGATE.TIME_ID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(DimTimeDelegatePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(DimTimeDelegatePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = DimTimeDelegatePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return DimTimeDelegate + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = DimTimeDelegatePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return DimTimeDelegatePeer::populateObjects(DimTimeDelegatePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + DimTimeDelegatePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = DimTimeDelegatePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return DimTimeDelegatePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a DimTimeDelegate or Criteria object. + * + * @param mixed $values Criteria or DimTimeDelegate object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from DimTimeDelegate object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a DimTimeDelegate or Criteria object. + * + * @param mixed $values Criteria or DimTimeDelegate object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(DimTimeDelegatePeer::TIME_ID); + $selectCriteria->add(DimTimeDelegatePeer::TIME_ID, $criteria->remove(DimTimeDelegatePeer::TIME_ID), $comparison); + + } else { // $values is DimTimeDelegate object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the DIM_TIME_DELEGATE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(DimTimeDelegatePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a DimTimeDelegate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or DimTimeDelegate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(DimTimeDelegatePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof DimTimeDelegate) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(DimTimeDelegatePeer::TIME_ID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given DimTimeDelegate object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param DimTimeDelegate $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(DimTimeDelegate $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(DimTimeDelegatePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(DimTimeDelegatePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(DimTimeDelegatePeer::DATABASE_NAME, DimTimeDelegatePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return DimTimeDelegate + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(DimTimeDelegatePeer::DATABASE_NAME); + + $criteria->add(DimTimeDelegatePeer::TIME_ID, $pk); + + + $v = DimTimeDelegatePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(DimTimeDelegatePeer::TIME_ID, $pks, Criteria::IN); + $objs = DimTimeDelegatePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseDimTimeDelegatePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseDimTimeDelegatePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/DimTimeDelegateMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.DimTimeDelegateMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseDynaform.php b/workflow/engine/classes/model/om/BaseDynaform.php new file mode 100644 index 000000000..e4d4ea809 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDynaform.php @@ -0,0 +1,663 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/DynaformPeer.php'; + +/** + * Base class that represents a row from the 'DYNAFORM' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDynaform extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var DynaformPeer + */ + protected static $peer; + + + /** + * The value for the dyn_uid field. + * @var string + */ + protected $dyn_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the dyn_type field. + * @var string + */ + protected $dyn_type = 'xmlform'; + + + /** + * The value for the dyn_filename field. + * @var string + */ + protected $dyn_filename = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [dyn_uid] column value. + * + * @return string + */ + public function getDynUid() + { + + return $this->dyn_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [dyn_type] column value. + * + * @return string + */ + public function getDynType() + { + + return $this->dyn_type; + } + + /** + * Get the [dyn_filename] column value. + * + * @return string + */ + public function getDynFilename() + { + + return $this->dyn_filename; + } + + /** + * Set the value of [dyn_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDynUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_uid !== $v || $v === '') { + $this->dyn_uid = $v; + $this->modifiedColumns[] = DynaformPeer::DYN_UID; + } + + } // setDynUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = DynaformPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [dyn_type] column. + * + * @param string $v new value + * @return void + */ + public function setDynType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_type !== $v || $v === 'xmlform') { + $this->dyn_type = $v; + $this->modifiedColumns[] = DynaformPeer::DYN_TYPE; + } + + } // setDynType() + + /** + * Set the value of [dyn_filename] column. + * + * @param string $v new value + * @return void + */ + public function setDynFilename($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dyn_filename !== $v || $v === '') { + $this->dyn_filename = $v; + $this->modifiedColumns[] = DynaformPeer::DYN_FILENAME; + } + + } // setDynFilename() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->dyn_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->dyn_type = $rs->getString($startcol + 2); + + $this->dyn_filename = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = DynaformPeer::NUM_COLUMNS - DynaformPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Dynaform object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DynaformPeer::DATABASE_NAME); + } + + try { + $con->begin(); + DynaformPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(DynaformPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = DynaformPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += DynaformPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = DynaformPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DynaformPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getDynUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getDynType(); + break; + case 3: + return $this->getDynFilename(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DynaformPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getDynUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getDynType(), + $keys[3] => $this->getDynFilename(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = DynaformPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setDynUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setDynType($value); + break; + case 3: + $this->setDynFilename($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = DynaformPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setDynUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setDynType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDynFilename($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(DynaformPeer::DATABASE_NAME); + + if ($this->isColumnModified(DynaformPeer::DYN_UID)) $criteria->add(DynaformPeer::DYN_UID, $this->dyn_uid); + if ($this->isColumnModified(DynaformPeer::PRO_UID)) $criteria->add(DynaformPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(DynaformPeer::DYN_TYPE)) $criteria->add(DynaformPeer::DYN_TYPE, $this->dyn_type); + if ($this->isColumnModified(DynaformPeer::DYN_FILENAME)) $criteria->add(DynaformPeer::DYN_FILENAME, $this->dyn_filename); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(DynaformPeer::DATABASE_NAME); + + $criteria->add(DynaformPeer::DYN_UID, $this->dyn_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getDynUid(); + } + + /** + * Generic method to set the primary key (dyn_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setDynUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Dynaform (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setDynType($this->dyn_type); + + $copyObj->setDynFilename($this->dyn_filename); + + + $copyObj->setNew(true); + + $copyObj->setDynUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Dynaform Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return DynaformPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new DynaformPeer(); + } + return self::$peer; + } + +} // BaseDynaform diff --git a/workflow/engine/classes/model/om/BaseDynaformPeer.php b/workflow/engine/classes/model/om/BaseDynaformPeer.php new file mode 100644 index 000000000..c37006d40 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseDynaformPeer.php @@ -0,0 +1,583 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by DynaformPeer::getOMClass() +include_once 'classes/model/Dynaform.php'; + +/** + * Base static class for performing query and update operations on the 'DYNAFORM' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseDynaformPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'DYNAFORM'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Dynaform'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the DYN_UID field */ + const DYN_UID = 'DYNAFORM.DYN_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'DYNAFORM.PRO_UID'; + + /** the column name for the DYN_TYPE field */ + const DYN_TYPE = 'DYNAFORM.DYN_TYPE'; + + /** the column name for the DYN_FILENAME field */ + const DYN_FILENAME = 'DYNAFORM.DYN_FILENAME'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('DynUid', 'ProUid', 'DynType', 'DynFilename', ), + BasePeer::TYPE_COLNAME => array (DynaformPeer::DYN_UID, DynaformPeer::PRO_UID, DynaformPeer::DYN_TYPE, DynaformPeer::DYN_FILENAME, ), + BasePeer::TYPE_FIELDNAME => array ('DYN_UID', 'PRO_UID', 'DYN_TYPE', 'DYN_FILENAME', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('DynUid' => 0, 'ProUid' => 1, 'DynType' => 2, 'DynFilename' => 3, ), + BasePeer::TYPE_COLNAME => array (DynaformPeer::DYN_UID => 0, DynaformPeer::PRO_UID => 1, DynaformPeer::DYN_TYPE => 2, DynaformPeer::DYN_FILENAME => 3, ), + BasePeer::TYPE_FIELDNAME => array ('DYN_UID' => 0, 'PRO_UID' => 1, 'DYN_TYPE' => 2, 'DYN_FILENAME' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/DynaformMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.DynaformMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = DynaformPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. DynaformPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(DynaformPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(DynaformPeer::DYN_UID); + + $criteria->addSelectColumn(DynaformPeer::PRO_UID); + + $criteria->addSelectColumn(DynaformPeer::DYN_TYPE); + + $criteria->addSelectColumn(DynaformPeer::DYN_FILENAME); + + } + + const COUNT = 'COUNT(DYNAFORM.DYN_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT DYNAFORM.DYN_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(DynaformPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(DynaformPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = DynaformPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Dynaform + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = DynaformPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return DynaformPeer::populateObjects(DynaformPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + DynaformPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = DynaformPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return DynaformPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Dynaform or Criteria object. + * + * @param mixed $values Criteria or Dynaform object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Dynaform object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Dynaform or Criteria object. + * + * @param mixed $values Criteria or Dynaform object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(DynaformPeer::DYN_UID); + $selectCriteria->add(DynaformPeer::DYN_UID, $criteria->remove(DynaformPeer::DYN_UID), $comparison); + + } else { // $values is Dynaform object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the DYNAFORM table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(DynaformPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Dynaform or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Dynaform object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(DynaformPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Dynaform) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(DynaformPeer::DYN_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Dynaform object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Dynaform $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Dynaform $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(DynaformPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(DynaformPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(DynaformPeer::DYN_TYPE)) + $columns[DynaformPeer::DYN_TYPE] = $obj->getDynType(); + + } + + return BasePeer::doValidate(DynaformPeer::DATABASE_NAME, DynaformPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Dynaform + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(DynaformPeer::DATABASE_NAME); + + $criteria->add(DynaformPeer::DYN_UID, $pk); + + + $v = DynaformPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(DynaformPeer::DYN_UID, $pks, Criteria::IN); + $objs = DynaformPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseDynaformPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseDynaformPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/DynaformMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.DynaformMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseEvent.php b/workflow/engine/classes/model/om/BaseEvent.php new file mode 100644 index 000000000..2b2067faf --- /dev/null +++ b/workflow/engine/classes/model/om/BaseEvent.php @@ -0,0 +1,1234 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/EventPeer.php'; + +/** + * Base class that represents a row from the 'EVENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseEvent extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var EventPeer + */ + protected static $peer; + + + /** + * The value for the evn_uid field. + * @var string + */ + protected $evn_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the evn_status field. + * @var string + */ + protected $evn_status = 'OPEN'; + + + /** + * The value for the evn_when_occurs field. + * @var string + */ + protected $evn_when_occurs = 'SINGLE'; + + + /** + * The value for the evn_related_to field. + * @var string + */ + protected $evn_related_to = 'SINGLE'; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the evn_tas_uid_from field. + * @var string + */ + protected $evn_tas_uid_from = ''; + + + /** + * The value for the evn_tas_uid_to field. + * @var string + */ + protected $evn_tas_uid_to = ''; + + + /** + * The value for the evn_tas_estimated_duration field. + * @var double + */ + protected $evn_tas_estimated_duration = 0; + + + /** + * The value for the evn_when field. + * @var double + */ + protected $evn_when = 0; + + + /** + * The value for the evn_max_attempts field. + * @var int + */ + protected $evn_max_attempts = 3; + + + /** + * The value for the evn_action field. + * @var string + */ + protected $evn_action = ''; + + + /** + * The value for the evn_conditions field. + * @var string + */ + protected $evn_conditions; + + + /** + * The value for the evn_action_parameters field. + * @var string + */ + protected $evn_action_parameters; + + + /** + * The value for the tri_uid field. + * @var string + */ + protected $tri_uid = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [evn_uid] column value. + * + * @return string + */ + public function getEvnUid() + { + + return $this->evn_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [evn_status] column value. + * + * @return string + */ + public function getEvnStatus() + { + + return $this->evn_status; + } + + /** + * Get the [evn_when_occurs] column value. + * + * @return string + */ + public function getEvnWhenOccurs() + { + + return $this->evn_when_occurs; + } + + /** + * Get the [evn_related_to] column value. + * + * @return string + */ + public function getEvnRelatedTo() + { + + return $this->evn_related_to; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [evn_tas_uid_from] column value. + * + * @return string + */ + public function getEvnTasUidFrom() + { + + return $this->evn_tas_uid_from; + } + + /** + * Get the [evn_tas_uid_to] column value. + * + * @return string + */ + public function getEvnTasUidTo() + { + + return $this->evn_tas_uid_to; + } + + /** + * Get the [evn_tas_estimated_duration] column value. + * + * @return double + */ + public function getEvnTasEstimatedDuration() + { + + return $this->evn_tas_estimated_duration; + } + + /** + * Get the [evn_when] column value. + * + * @return double + */ + public function getEvnWhen() + { + + return $this->evn_when; + } + + /** + * Get the [evn_max_attempts] column value. + * + * @return int + */ + public function getEvnMaxAttempts() + { + + return $this->evn_max_attempts; + } + + /** + * Get the [evn_action] column value. + * + * @return string + */ + public function getEvnAction() + { + + return $this->evn_action; + } + + /** + * Get the [evn_conditions] column value. + * + * @return string + */ + public function getEvnConditions() + { + + return $this->evn_conditions; + } + + /** + * Get the [evn_action_parameters] column value. + * + * @return string + */ + public function getEvnActionParameters() + { + + return $this->evn_action_parameters; + } + + /** + * Get the [tri_uid] column value. + * + * @return string + */ + public function getTriUid() + { + + return $this->tri_uid; + } + + /** + * Set the value of [evn_uid] column. + * + * @param string $v new value + * @return void + */ + public function setEvnUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_uid !== $v || $v === '') { + $this->evn_uid = $v; + $this->modifiedColumns[] = EventPeer::EVN_UID; + } + + } // setEvnUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = EventPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [evn_status] column. + * + * @param string $v new value + * @return void + */ + public function setEvnStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_status !== $v || $v === 'OPEN') { + $this->evn_status = $v; + $this->modifiedColumns[] = EventPeer::EVN_STATUS; + } + + } // setEvnStatus() + + /** + * Set the value of [evn_when_occurs] column. + * + * @param string $v new value + * @return void + */ + public function setEvnWhenOccurs($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_when_occurs !== $v || $v === 'SINGLE') { + $this->evn_when_occurs = $v; + $this->modifiedColumns[] = EventPeer::EVN_WHEN_OCCURS; + } + + } // setEvnWhenOccurs() + + /** + * Set the value of [evn_related_to] column. + * + * @param string $v new value + * @return void + */ + public function setEvnRelatedTo($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_related_to !== $v || $v === 'SINGLE') { + $this->evn_related_to = $v; + $this->modifiedColumns[] = EventPeer::EVN_RELATED_TO; + } + + } // setEvnRelatedTo() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = EventPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [evn_tas_uid_from] column. + * + * @param string $v new value + * @return void + */ + public function setEvnTasUidFrom($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_tas_uid_from !== $v || $v === '') { + $this->evn_tas_uid_from = $v; + $this->modifiedColumns[] = EventPeer::EVN_TAS_UID_FROM; + } + + } // setEvnTasUidFrom() + + /** + * Set the value of [evn_tas_uid_to] column. + * + * @param string $v new value + * @return void + */ + public function setEvnTasUidTo($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_tas_uid_to !== $v || $v === '') { + $this->evn_tas_uid_to = $v; + $this->modifiedColumns[] = EventPeer::EVN_TAS_UID_TO; + } + + } // setEvnTasUidTo() + + /** + * Set the value of [evn_tas_estimated_duration] column. + * + * @param double $v new value + * @return void + */ + public function setEvnTasEstimatedDuration($v) + { + + if ($this->evn_tas_estimated_duration !== $v || $v === 0) { + $this->evn_tas_estimated_duration = $v; + $this->modifiedColumns[] = EventPeer::EVN_TAS_ESTIMATED_DURATION; + } + + } // setEvnTasEstimatedDuration() + + /** + * Set the value of [evn_when] column. + * + * @param double $v new value + * @return void + */ + public function setEvnWhen($v) + { + + if ($this->evn_when !== $v || $v === 0) { + $this->evn_when = $v; + $this->modifiedColumns[] = EventPeer::EVN_WHEN; + } + + } // setEvnWhen() + + /** + * Set the value of [evn_max_attempts] column. + * + * @param int $v new value + * @return void + */ + public function setEvnMaxAttempts($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->evn_max_attempts !== $v || $v === 3) { + $this->evn_max_attempts = $v; + $this->modifiedColumns[] = EventPeer::EVN_MAX_ATTEMPTS; + } + + } // setEvnMaxAttempts() + + /** + * Set the value of [evn_action] column. + * + * @param string $v new value + * @return void + */ + public function setEvnAction($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_action !== $v || $v === '') { + $this->evn_action = $v; + $this->modifiedColumns[] = EventPeer::EVN_ACTION; + } + + } // setEvnAction() + + /** + * Set the value of [evn_conditions] column. + * + * @param string $v new value + * @return void + */ + public function setEvnConditions($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_conditions !== $v) { + $this->evn_conditions = $v; + $this->modifiedColumns[] = EventPeer::EVN_CONDITIONS; + } + + } // setEvnConditions() + + /** + * Set the value of [evn_action_parameters] column. + * + * @param string $v new value + * @return void + */ + public function setEvnActionParameters($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->evn_action_parameters !== $v) { + $this->evn_action_parameters = $v; + $this->modifiedColumns[] = EventPeer::EVN_ACTION_PARAMETERS; + } + + } // setEvnActionParameters() + + /** + * Set the value of [tri_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTriUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_uid !== $v || $v === '') { + $this->tri_uid = $v; + $this->modifiedColumns[] = EventPeer::TRI_UID; + } + + } // setTriUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->evn_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->evn_status = $rs->getString($startcol + 2); + + $this->evn_when_occurs = $rs->getString($startcol + 3); + + $this->evn_related_to = $rs->getString($startcol + 4); + + $this->tas_uid = $rs->getString($startcol + 5); + + $this->evn_tas_uid_from = $rs->getString($startcol + 6); + + $this->evn_tas_uid_to = $rs->getString($startcol + 7); + + $this->evn_tas_estimated_duration = $rs->getFloat($startcol + 8); + + $this->evn_when = $rs->getFloat($startcol + 9); + + $this->evn_max_attempts = $rs->getInt($startcol + 10); + + $this->evn_action = $rs->getString($startcol + 11); + + $this->evn_conditions = $rs->getString($startcol + 12); + + $this->evn_action_parameters = $rs->getString($startcol + 13); + + $this->tri_uid = $rs->getString($startcol + 14); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 15; // 15 = EventPeer::NUM_COLUMNS - EventPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Event object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(EventPeer::DATABASE_NAME); + } + + try { + $con->begin(); + EventPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(EventPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = EventPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += EventPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = EventPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = EventPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getEvnUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getEvnStatus(); + break; + case 3: + return $this->getEvnWhenOccurs(); + break; + case 4: + return $this->getEvnRelatedTo(); + break; + case 5: + return $this->getTasUid(); + break; + case 6: + return $this->getEvnTasUidFrom(); + break; + case 7: + return $this->getEvnTasUidTo(); + break; + case 8: + return $this->getEvnTasEstimatedDuration(); + break; + case 9: + return $this->getEvnWhen(); + break; + case 10: + return $this->getEvnMaxAttempts(); + break; + case 11: + return $this->getEvnAction(); + break; + case 12: + return $this->getEvnConditions(); + break; + case 13: + return $this->getEvnActionParameters(); + break; + case 14: + return $this->getTriUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = EventPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getEvnUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getEvnStatus(), + $keys[3] => $this->getEvnWhenOccurs(), + $keys[4] => $this->getEvnRelatedTo(), + $keys[5] => $this->getTasUid(), + $keys[6] => $this->getEvnTasUidFrom(), + $keys[7] => $this->getEvnTasUidTo(), + $keys[8] => $this->getEvnTasEstimatedDuration(), + $keys[9] => $this->getEvnWhen(), + $keys[10] => $this->getEvnMaxAttempts(), + $keys[11] => $this->getEvnAction(), + $keys[12] => $this->getEvnConditions(), + $keys[13] => $this->getEvnActionParameters(), + $keys[14] => $this->getTriUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = EventPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setEvnUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setEvnStatus($value); + break; + case 3: + $this->setEvnWhenOccurs($value); + break; + case 4: + $this->setEvnRelatedTo($value); + break; + case 5: + $this->setTasUid($value); + break; + case 6: + $this->setEvnTasUidFrom($value); + break; + case 7: + $this->setEvnTasUidTo($value); + break; + case 8: + $this->setEvnTasEstimatedDuration($value); + break; + case 9: + $this->setEvnWhen($value); + break; + case 10: + $this->setEvnMaxAttempts($value); + break; + case 11: + $this->setEvnAction($value); + break; + case 12: + $this->setEvnConditions($value); + break; + case 13: + $this->setEvnActionParameters($value); + break; + case 14: + $this->setTriUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = EventPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setEvnUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setEvnStatus($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setEvnWhenOccurs($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setEvnRelatedTo($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setTasUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setEvnTasUidFrom($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setEvnTasUidTo($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setEvnTasEstimatedDuration($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setEvnWhen($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setEvnMaxAttempts($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setEvnAction($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setEvnConditions($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setEvnActionParameters($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setTriUid($arr[$keys[14]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(EventPeer::DATABASE_NAME); + + if ($this->isColumnModified(EventPeer::EVN_UID)) $criteria->add(EventPeer::EVN_UID, $this->evn_uid); + if ($this->isColumnModified(EventPeer::PRO_UID)) $criteria->add(EventPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(EventPeer::EVN_STATUS)) $criteria->add(EventPeer::EVN_STATUS, $this->evn_status); + if ($this->isColumnModified(EventPeer::EVN_WHEN_OCCURS)) $criteria->add(EventPeer::EVN_WHEN_OCCURS, $this->evn_when_occurs); + if ($this->isColumnModified(EventPeer::EVN_RELATED_TO)) $criteria->add(EventPeer::EVN_RELATED_TO, $this->evn_related_to); + if ($this->isColumnModified(EventPeer::TAS_UID)) $criteria->add(EventPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(EventPeer::EVN_TAS_UID_FROM)) $criteria->add(EventPeer::EVN_TAS_UID_FROM, $this->evn_tas_uid_from); + if ($this->isColumnModified(EventPeer::EVN_TAS_UID_TO)) $criteria->add(EventPeer::EVN_TAS_UID_TO, $this->evn_tas_uid_to); + if ($this->isColumnModified(EventPeer::EVN_TAS_ESTIMATED_DURATION)) $criteria->add(EventPeer::EVN_TAS_ESTIMATED_DURATION, $this->evn_tas_estimated_duration); + if ($this->isColumnModified(EventPeer::EVN_WHEN)) $criteria->add(EventPeer::EVN_WHEN, $this->evn_when); + if ($this->isColumnModified(EventPeer::EVN_MAX_ATTEMPTS)) $criteria->add(EventPeer::EVN_MAX_ATTEMPTS, $this->evn_max_attempts); + if ($this->isColumnModified(EventPeer::EVN_ACTION)) $criteria->add(EventPeer::EVN_ACTION, $this->evn_action); + if ($this->isColumnModified(EventPeer::EVN_CONDITIONS)) $criteria->add(EventPeer::EVN_CONDITIONS, $this->evn_conditions); + if ($this->isColumnModified(EventPeer::EVN_ACTION_PARAMETERS)) $criteria->add(EventPeer::EVN_ACTION_PARAMETERS, $this->evn_action_parameters); + if ($this->isColumnModified(EventPeer::TRI_UID)) $criteria->add(EventPeer::TRI_UID, $this->tri_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(EventPeer::DATABASE_NAME); + + $criteria->add(EventPeer::EVN_UID, $this->evn_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getEvnUid(); + } + + /** + * Generic method to set the primary key (evn_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setEvnUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Event (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setEvnStatus($this->evn_status); + + $copyObj->setEvnWhenOccurs($this->evn_when_occurs); + + $copyObj->setEvnRelatedTo($this->evn_related_to); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setEvnTasUidFrom($this->evn_tas_uid_from); + + $copyObj->setEvnTasUidTo($this->evn_tas_uid_to); + + $copyObj->setEvnTasEstimatedDuration($this->evn_tas_estimated_duration); + + $copyObj->setEvnWhen($this->evn_when); + + $copyObj->setEvnMaxAttempts($this->evn_max_attempts); + + $copyObj->setEvnAction($this->evn_action); + + $copyObj->setEvnConditions($this->evn_conditions); + + $copyObj->setEvnActionParameters($this->evn_action_parameters); + + $copyObj->setTriUid($this->tri_uid); + + + $copyObj->setNew(true); + + $copyObj->setEvnUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Event Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return EventPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new EventPeer(); + } + return self::$peer; + } + +} // BaseEvent diff --git a/workflow/engine/classes/model/om/BaseEventPeer.php b/workflow/engine/classes/model/om/BaseEventPeer.php new file mode 100644 index 000000000..d1d7ad7e6 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseEventPeer.php @@ -0,0 +1,635 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by EventPeer::getOMClass() +include_once 'classes/model/Event.php'; + +/** + * Base static class for performing query and update operations on the 'EVENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseEventPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'EVENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Event'; + + /** The total number of columns. */ + const NUM_COLUMNS = 15; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the EVN_UID field */ + const EVN_UID = 'EVENT.EVN_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'EVENT.PRO_UID'; + + /** the column name for the EVN_STATUS field */ + const EVN_STATUS = 'EVENT.EVN_STATUS'; + + /** the column name for the EVN_WHEN_OCCURS field */ + const EVN_WHEN_OCCURS = 'EVENT.EVN_WHEN_OCCURS'; + + /** the column name for the EVN_RELATED_TO field */ + const EVN_RELATED_TO = 'EVENT.EVN_RELATED_TO'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'EVENT.TAS_UID'; + + /** the column name for the EVN_TAS_UID_FROM field */ + const EVN_TAS_UID_FROM = 'EVENT.EVN_TAS_UID_FROM'; + + /** the column name for the EVN_TAS_UID_TO field */ + const EVN_TAS_UID_TO = 'EVENT.EVN_TAS_UID_TO'; + + /** the column name for the EVN_TAS_ESTIMATED_DURATION field */ + const EVN_TAS_ESTIMATED_DURATION = 'EVENT.EVN_TAS_ESTIMATED_DURATION'; + + /** the column name for the EVN_WHEN field */ + const EVN_WHEN = 'EVENT.EVN_WHEN'; + + /** the column name for the EVN_MAX_ATTEMPTS field */ + const EVN_MAX_ATTEMPTS = 'EVENT.EVN_MAX_ATTEMPTS'; + + /** the column name for the EVN_ACTION field */ + const EVN_ACTION = 'EVENT.EVN_ACTION'; + + /** the column name for the EVN_CONDITIONS field */ + const EVN_CONDITIONS = 'EVENT.EVN_CONDITIONS'; + + /** the column name for the EVN_ACTION_PARAMETERS field */ + const EVN_ACTION_PARAMETERS = 'EVENT.EVN_ACTION_PARAMETERS'; + + /** the column name for the TRI_UID field */ + const TRI_UID = 'EVENT.TRI_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('EvnUid', 'ProUid', 'EvnStatus', 'EvnWhenOccurs', 'EvnRelatedTo', 'TasUid', 'EvnTasUidFrom', 'EvnTasUidTo', 'EvnTasEstimatedDuration', 'EvnWhen', 'EvnMaxAttempts', 'EvnAction', 'EvnConditions', 'EvnActionParameters', 'TriUid', ), + BasePeer::TYPE_COLNAME => array (EventPeer::EVN_UID, EventPeer::PRO_UID, EventPeer::EVN_STATUS, EventPeer::EVN_WHEN_OCCURS, EventPeer::EVN_RELATED_TO, EventPeer::TAS_UID, EventPeer::EVN_TAS_UID_FROM, EventPeer::EVN_TAS_UID_TO, EventPeer::EVN_TAS_ESTIMATED_DURATION, EventPeer::EVN_WHEN, EventPeer::EVN_MAX_ATTEMPTS, EventPeer::EVN_ACTION, EventPeer::EVN_CONDITIONS, EventPeer::EVN_ACTION_PARAMETERS, EventPeer::TRI_UID, ), + BasePeer::TYPE_FIELDNAME => array ('EVN_UID', 'PRO_UID', 'EVN_STATUS', 'EVN_WHEN_OCCURS', 'EVN_RELATED_TO', 'TAS_UID', 'EVN_TAS_UID_FROM', 'EVN_TAS_UID_TO', 'EVN_TAS_ESTIMATED_DURATION', 'EVN_WHEN', 'EVN_MAX_ATTEMPTS', 'EVN_ACTION', 'EVN_CONDITIONS', 'EVN_ACTION_PARAMETERS', 'TRI_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('EvnUid' => 0, 'ProUid' => 1, 'EvnStatus' => 2, 'EvnWhenOccurs' => 3, 'EvnRelatedTo' => 4, 'TasUid' => 5, 'EvnTasUidFrom' => 6, 'EvnTasUidTo' => 7, 'EvnTasEstimatedDuration' => 8, 'EvnWhen' => 9, 'EvnMaxAttempts' => 10, 'EvnAction' => 11, 'EvnConditions' => 12, 'EvnActionParameters' => 13, 'TriUid' => 14, ), + BasePeer::TYPE_COLNAME => array (EventPeer::EVN_UID => 0, EventPeer::PRO_UID => 1, EventPeer::EVN_STATUS => 2, EventPeer::EVN_WHEN_OCCURS => 3, EventPeer::EVN_RELATED_TO => 4, EventPeer::TAS_UID => 5, EventPeer::EVN_TAS_UID_FROM => 6, EventPeer::EVN_TAS_UID_TO => 7, EventPeer::EVN_TAS_ESTIMATED_DURATION => 8, EventPeer::EVN_WHEN => 9, EventPeer::EVN_MAX_ATTEMPTS => 10, EventPeer::EVN_ACTION => 11, EventPeer::EVN_CONDITIONS => 12, EventPeer::EVN_ACTION_PARAMETERS => 13, EventPeer::TRI_UID => 14, ), + BasePeer::TYPE_FIELDNAME => array ('EVN_UID' => 0, 'PRO_UID' => 1, 'EVN_STATUS' => 2, 'EVN_WHEN_OCCURS' => 3, 'EVN_RELATED_TO' => 4, 'TAS_UID' => 5, 'EVN_TAS_UID_FROM' => 6, 'EVN_TAS_UID_TO' => 7, 'EVN_TAS_ESTIMATED_DURATION' => 8, 'EVN_WHEN' => 9, 'EVN_MAX_ATTEMPTS' => 10, 'EVN_ACTION' => 11, 'EVN_CONDITIONS' => 12, 'EVN_ACTION_PARAMETERS' => 13, 'TRI_UID' => 14, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/EventMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.EventMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = EventPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. EventPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(EventPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(EventPeer::EVN_UID); + + $criteria->addSelectColumn(EventPeer::PRO_UID); + + $criteria->addSelectColumn(EventPeer::EVN_STATUS); + + $criteria->addSelectColumn(EventPeer::EVN_WHEN_OCCURS); + + $criteria->addSelectColumn(EventPeer::EVN_RELATED_TO); + + $criteria->addSelectColumn(EventPeer::TAS_UID); + + $criteria->addSelectColumn(EventPeer::EVN_TAS_UID_FROM); + + $criteria->addSelectColumn(EventPeer::EVN_TAS_UID_TO); + + $criteria->addSelectColumn(EventPeer::EVN_TAS_ESTIMATED_DURATION); + + $criteria->addSelectColumn(EventPeer::EVN_WHEN); + + $criteria->addSelectColumn(EventPeer::EVN_MAX_ATTEMPTS); + + $criteria->addSelectColumn(EventPeer::EVN_ACTION); + + $criteria->addSelectColumn(EventPeer::EVN_CONDITIONS); + + $criteria->addSelectColumn(EventPeer::EVN_ACTION_PARAMETERS); + + $criteria->addSelectColumn(EventPeer::TRI_UID); + + } + + const COUNT = 'COUNT(EVENT.EVN_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT EVENT.EVN_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(EventPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(EventPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = EventPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Event + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = EventPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return EventPeer::populateObjects(EventPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + EventPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = EventPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return EventPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Event or Criteria object. + * + * @param mixed $values Criteria or Event object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Event object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Event or Criteria object. + * + * @param mixed $values Criteria or Event object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(EventPeer::EVN_UID); + $selectCriteria->add(EventPeer::EVN_UID, $criteria->remove(EventPeer::EVN_UID), $comparison); + + } else { // $values is Event object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the EVENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(EventPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Event or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Event object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(EventPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Event) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(EventPeer::EVN_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Event object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Event $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Event $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(EventPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(EventPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(EventPeer::DATABASE_NAME, EventPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Event + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(EventPeer::DATABASE_NAME); + + $criteria->add(EventPeer::EVN_UID, $pk); + + + $v = EventPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(EventPeer::EVN_UID, $pks, Criteria::IN); + $objs = EventPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseEventPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseEventPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/EventMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.EventMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseFieldCondition.php b/workflow/engine/classes/model/om/BaseFieldCondition.php new file mode 100644 index 000000000..f5ee49fe1 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseFieldCondition.php @@ -0,0 +1,875 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/FieldConditionPeer.php'; + +/** + * Base class that represents a row from the 'FIELD_CONDITION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseFieldCondition extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var FieldConditionPeer + */ + protected static $peer; + + + /** + * The value for the fcd_uid field. + * @var string + */ + protected $fcd_uid = ''; + + + /** + * The value for the fcd_function field. + * @var string + */ + protected $fcd_function; + + + /** + * The value for the fcd_fields field. + * @var string + */ + protected $fcd_fields; + + + /** + * The value for the fcd_condition field. + * @var string + */ + protected $fcd_condition; + + + /** + * The value for the fcd_events field. + * @var string + */ + protected $fcd_events; + + + /** + * The value for the fcd_event_owners field. + * @var string + */ + protected $fcd_event_owners; + + + /** + * The value for the fcd_status field. + * @var string + */ + protected $fcd_status; + + + /** + * The value for the fcd_dyn_uid field. + * @var string + */ + protected $fcd_dyn_uid; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [fcd_uid] column value. + * + * @return string + */ + public function getFcdUid() + { + + return $this->fcd_uid; + } + + /** + * Get the [fcd_function] column value. + * + * @return string + */ + public function getFcdFunction() + { + + return $this->fcd_function; + } + + /** + * Get the [fcd_fields] column value. + * + * @return string + */ + public function getFcdFields() + { + + return $this->fcd_fields; + } + + /** + * Get the [fcd_condition] column value. + * + * @return string + */ + public function getFcdCondition() + { + + return $this->fcd_condition; + } + + /** + * Get the [fcd_events] column value. + * + * @return string + */ + public function getFcdEvents() + { + + return $this->fcd_events; + } + + /** + * Get the [fcd_event_owners] column value. + * + * @return string + */ + public function getFcdEventOwners() + { + + return $this->fcd_event_owners; + } + + /** + * Get the [fcd_status] column value. + * + * @return string + */ + public function getFcdStatus() + { + + return $this->fcd_status; + } + + /** + * Get the [fcd_dyn_uid] column value. + * + * @return string + */ + public function getFcdDynUid() + { + + return $this->fcd_dyn_uid; + } + + /** + * Set the value of [fcd_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFcdUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_uid !== $v || $v === '') { + $this->fcd_uid = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_UID; + } + + } // setFcdUid() + + /** + * Set the value of [fcd_function] column. + * + * @param string $v new value + * @return void + */ + public function setFcdFunction($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_function !== $v) { + $this->fcd_function = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_FUNCTION; + } + + } // setFcdFunction() + + /** + * Set the value of [fcd_fields] column. + * + * @param string $v new value + * @return void + */ + public function setFcdFields($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_fields !== $v) { + $this->fcd_fields = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_FIELDS; + } + + } // setFcdFields() + + /** + * Set the value of [fcd_condition] column. + * + * @param string $v new value + * @return void + */ + public function setFcdCondition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_condition !== $v) { + $this->fcd_condition = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_CONDITION; + } + + } // setFcdCondition() + + /** + * Set the value of [fcd_events] column. + * + * @param string $v new value + * @return void + */ + public function setFcdEvents($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_events !== $v) { + $this->fcd_events = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_EVENTS; + } + + } // setFcdEvents() + + /** + * Set the value of [fcd_event_owners] column. + * + * @param string $v new value + * @return void + */ + public function setFcdEventOwners($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_event_owners !== $v) { + $this->fcd_event_owners = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_EVENT_OWNERS; + } + + } // setFcdEventOwners() + + /** + * Set the value of [fcd_status] column. + * + * @param string $v new value + * @return void + */ + public function setFcdStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_status !== $v) { + $this->fcd_status = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_STATUS; + } + + } // setFcdStatus() + + /** + * Set the value of [fcd_dyn_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFcdDynUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fcd_dyn_uid !== $v) { + $this->fcd_dyn_uid = $v; + $this->modifiedColumns[] = FieldConditionPeer::FCD_DYN_UID; + } + + } // setFcdDynUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->fcd_uid = $rs->getString($startcol + 0); + + $this->fcd_function = $rs->getString($startcol + 1); + + $this->fcd_fields = $rs->getString($startcol + 2); + + $this->fcd_condition = $rs->getString($startcol + 3); + + $this->fcd_events = $rs->getString($startcol + 4); + + $this->fcd_event_owners = $rs->getString($startcol + 5); + + $this->fcd_status = $rs->getString($startcol + 6); + + $this->fcd_dyn_uid = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = FieldConditionPeer::NUM_COLUMNS - FieldConditionPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating FieldCondition object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + FieldConditionPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = FieldConditionPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += FieldConditionPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = FieldConditionPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = FieldConditionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getFcdUid(); + break; + case 1: + return $this->getFcdFunction(); + break; + case 2: + return $this->getFcdFields(); + break; + case 3: + return $this->getFcdCondition(); + break; + case 4: + return $this->getFcdEvents(); + break; + case 5: + return $this->getFcdEventOwners(); + break; + case 6: + return $this->getFcdStatus(); + break; + case 7: + return $this->getFcdDynUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = FieldConditionPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getFcdUid(), + $keys[1] => $this->getFcdFunction(), + $keys[2] => $this->getFcdFields(), + $keys[3] => $this->getFcdCondition(), + $keys[4] => $this->getFcdEvents(), + $keys[5] => $this->getFcdEventOwners(), + $keys[6] => $this->getFcdStatus(), + $keys[7] => $this->getFcdDynUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = FieldConditionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setFcdUid($value); + break; + case 1: + $this->setFcdFunction($value); + break; + case 2: + $this->setFcdFields($value); + break; + case 3: + $this->setFcdCondition($value); + break; + case 4: + $this->setFcdEvents($value); + break; + case 5: + $this->setFcdEventOwners($value); + break; + case 6: + $this->setFcdStatus($value); + break; + case 7: + $this->setFcdDynUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = FieldConditionPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setFcdUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setFcdFunction($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFcdFields($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setFcdCondition($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setFcdEvents($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setFcdEventOwners($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setFcdStatus($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setFcdDynUid($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(FieldConditionPeer::DATABASE_NAME); + + if ($this->isColumnModified(FieldConditionPeer::FCD_UID)) $criteria->add(FieldConditionPeer::FCD_UID, $this->fcd_uid); + if ($this->isColumnModified(FieldConditionPeer::FCD_FUNCTION)) $criteria->add(FieldConditionPeer::FCD_FUNCTION, $this->fcd_function); + if ($this->isColumnModified(FieldConditionPeer::FCD_FIELDS)) $criteria->add(FieldConditionPeer::FCD_FIELDS, $this->fcd_fields); + if ($this->isColumnModified(FieldConditionPeer::FCD_CONDITION)) $criteria->add(FieldConditionPeer::FCD_CONDITION, $this->fcd_condition); + if ($this->isColumnModified(FieldConditionPeer::FCD_EVENTS)) $criteria->add(FieldConditionPeer::FCD_EVENTS, $this->fcd_events); + if ($this->isColumnModified(FieldConditionPeer::FCD_EVENT_OWNERS)) $criteria->add(FieldConditionPeer::FCD_EVENT_OWNERS, $this->fcd_event_owners); + if ($this->isColumnModified(FieldConditionPeer::FCD_STATUS)) $criteria->add(FieldConditionPeer::FCD_STATUS, $this->fcd_status); + if ($this->isColumnModified(FieldConditionPeer::FCD_DYN_UID)) $criteria->add(FieldConditionPeer::FCD_DYN_UID, $this->fcd_dyn_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(FieldConditionPeer::DATABASE_NAME); + + $criteria->add(FieldConditionPeer::FCD_UID, $this->fcd_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getFcdUid(); + } + + /** + * Generic method to set the primary key (fcd_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setFcdUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of FieldCondition (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setFcdFunction($this->fcd_function); + + $copyObj->setFcdFields($this->fcd_fields); + + $copyObj->setFcdCondition($this->fcd_condition); + + $copyObj->setFcdEvents($this->fcd_events); + + $copyObj->setFcdEventOwners($this->fcd_event_owners); + + $copyObj->setFcdStatus($this->fcd_status); + + $copyObj->setFcdDynUid($this->fcd_dyn_uid); + + + $copyObj->setNew(true); + + $copyObj->setFcdUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return FieldCondition Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return FieldConditionPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new FieldConditionPeer(); + } + return self::$peer; + } + +} // BaseFieldCondition diff --git a/workflow/engine/classes/model/om/BaseFieldConditionPeer.php b/workflow/engine/classes/model/om/BaseFieldConditionPeer.php new file mode 100644 index 000000000..851e99636 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseFieldConditionPeer.php @@ -0,0 +1,600 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by FieldConditionPeer::getOMClass() +include_once 'classes/model/FieldCondition.php'; + +/** + * Base static class for performing query and update operations on the 'FIELD_CONDITION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseFieldConditionPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'FIELD_CONDITION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.FieldCondition'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the FCD_UID field */ + const FCD_UID = 'FIELD_CONDITION.FCD_UID'; + + /** the column name for the FCD_FUNCTION field */ + const FCD_FUNCTION = 'FIELD_CONDITION.FCD_FUNCTION'; + + /** the column name for the FCD_FIELDS field */ + const FCD_FIELDS = 'FIELD_CONDITION.FCD_FIELDS'; + + /** the column name for the FCD_CONDITION field */ + const FCD_CONDITION = 'FIELD_CONDITION.FCD_CONDITION'; + + /** the column name for the FCD_EVENTS field */ + const FCD_EVENTS = 'FIELD_CONDITION.FCD_EVENTS'; + + /** the column name for the FCD_EVENT_OWNERS field */ + const FCD_EVENT_OWNERS = 'FIELD_CONDITION.FCD_EVENT_OWNERS'; + + /** the column name for the FCD_STATUS field */ + const FCD_STATUS = 'FIELD_CONDITION.FCD_STATUS'; + + /** the column name for the FCD_DYN_UID field */ + const FCD_DYN_UID = 'FIELD_CONDITION.FCD_DYN_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('FcdUid', 'FcdFunction', 'FcdFields', 'FcdCondition', 'FcdEvents', 'FcdEventOwners', 'FcdStatus', 'FcdDynUid', ), + BasePeer::TYPE_COLNAME => array (FieldConditionPeer::FCD_UID, FieldConditionPeer::FCD_FUNCTION, FieldConditionPeer::FCD_FIELDS, FieldConditionPeer::FCD_CONDITION, FieldConditionPeer::FCD_EVENTS, FieldConditionPeer::FCD_EVENT_OWNERS, FieldConditionPeer::FCD_STATUS, FieldConditionPeer::FCD_DYN_UID, ), + BasePeer::TYPE_FIELDNAME => array ('FCD_UID', 'FCD_FUNCTION', 'FCD_FIELDS', 'FCD_CONDITION', 'FCD_EVENTS', 'FCD_EVENT_OWNERS', 'FCD_STATUS', 'FCD_DYN_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('FcdUid' => 0, 'FcdFunction' => 1, 'FcdFields' => 2, 'FcdCondition' => 3, 'FcdEvents' => 4, 'FcdEventOwners' => 5, 'FcdStatus' => 6, 'FcdDynUid' => 7, ), + BasePeer::TYPE_COLNAME => array (FieldConditionPeer::FCD_UID => 0, FieldConditionPeer::FCD_FUNCTION => 1, FieldConditionPeer::FCD_FIELDS => 2, FieldConditionPeer::FCD_CONDITION => 3, FieldConditionPeer::FCD_EVENTS => 4, FieldConditionPeer::FCD_EVENT_OWNERS => 5, FieldConditionPeer::FCD_STATUS => 6, FieldConditionPeer::FCD_DYN_UID => 7, ), + BasePeer::TYPE_FIELDNAME => array ('FCD_UID' => 0, 'FCD_FUNCTION' => 1, 'FCD_FIELDS' => 2, 'FCD_CONDITION' => 3, 'FCD_EVENTS' => 4, 'FCD_EVENT_OWNERS' => 5, 'FCD_STATUS' => 6, 'FCD_DYN_UID' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/FieldConditionMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.FieldConditionMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = FieldConditionPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. FieldConditionPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(FieldConditionPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(FieldConditionPeer::FCD_UID); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_FUNCTION); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_FIELDS); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_CONDITION); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_EVENTS); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_EVENT_OWNERS); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_STATUS); + + $criteria->addSelectColumn(FieldConditionPeer::FCD_DYN_UID); + + } + + const COUNT = 'COUNT(FIELD_CONDITION.FCD_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT FIELD_CONDITION.FCD_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(FieldConditionPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(FieldConditionPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = FieldConditionPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return FieldCondition + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = FieldConditionPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return FieldConditionPeer::populateObjects(FieldConditionPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + FieldConditionPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = FieldConditionPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return FieldConditionPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a FieldCondition or Criteria object. + * + * @param mixed $values Criteria or FieldCondition object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from FieldCondition object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a FieldCondition or Criteria object. + * + * @param mixed $values Criteria or FieldCondition object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(FieldConditionPeer::FCD_UID); + $selectCriteria->add(FieldConditionPeer::FCD_UID, $criteria->remove(FieldConditionPeer::FCD_UID), $comparison); + + } else { // $values is FieldCondition object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the FIELD_CONDITION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(FieldConditionPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a FieldCondition or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or FieldCondition object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(FieldConditionPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof FieldCondition) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(FieldConditionPeer::FCD_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given FieldCondition object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param FieldCondition $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(FieldCondition $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(FieldConditionPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(FieldConditionPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(FieldConditionPeer::DATABASE_NAME, FieldConditionPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return FieldCondition + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(FieldConditionPeer::DATABASE_NAME); + + $criteria->add(FieldConditionPeer::FCD_UID, $pk); + + + $v = FieldConditionPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(FieldConditionPeer::FCD_UID, $pks, Criteria::IN); + $objs = FieldConditionPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseFieldConditionPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseFieldConditionPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/FieldConditionMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.FieldConditionMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseFields.php b/workflow/engine/classes/model/om/BaseFields.php new file mode 100644 index 000000000..2ed76b76f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseFields.php @@ -0,0 +1,1087 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/FieldsPeer.php'; + +/** + * Base class that represents a row from the 'FIELDS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseFields extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var FieldsPeer + */ + protected static $peer; + + + /** + * The value for the fld_uid field. + * @var string + */ + protected $fld_uid = ''; + + + /** + * The value for the add_tab_uid field. + * @var string + */ + protected $add_tab_uid = ''; + + + /** + * The value for the fld_index field. + * @var int + */ + protected $fld_index = 1; + + + /** + * The value for the fld_name field. + * @var string + */ + protected $fld_name = ''; + + + /** + * The value for the fld_description field. + * @var string + */ + protected $fld_description; + + + /** + * The value for the fld_type field. + * @var string + */ + protected $fld_type = ''; + + + /** + * The value for the fld_size field. + * @var int + */ + protected $fld_size = 1; + + + /** + * The value for the fld_null field. + * @var int + */ + protected $fld_null = 1; + + + /** + * The value for the fld_auto_increment field. + * @var int + */ + protected $fld_auto_increment = 0; + + + /** + * The value for the fld_key field. + * @var int + */ + protected $fld_key = 0; + + + /** + * The value for the fld_foreign_key field. + * @var int + */ + protected $fld_foreign_key = 0; + + + /** + * The value for the fld_foreign_key_table field. + * @var string + */ + protected $fld_foreign_key_table = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [fld_uid] column value. + * + * @return string + */ + public function getFldUid() + { + + return $this->fld_uid; + } + + /** + * Get the [add_tab_uid] column value. + * + * @return string + */ + public function getAddTabUid() + { + + return $this->add_tab_uid; + } + + /** + * Get the [fld_index] column value. + * + * @return int + */ + public function getFldIndex() + { + + return $this->fld_index; + } + + /** + * Get the [fld_name] column value. + * + * @return string + */ + public function getFldName() + { + + return $this->fld_name; + } + + /** + * Get the [fld_description] column value. + * + * @return string + */ + public function getFldDescription() + { + + return $this->fld_description; + } + + /** + * Get the [fld_type] column value. + * + * @return string + */ + public function getFldType() + { + + return $this->fld_type; + } + + /** + * Get the [fld_size] column value. + * + * @return int + */ + public function getFldSize() + { + + return $this->fld_size; + } + + /** + * Get the [fld_null] column value. + * + * @return int + */ + public function getFldNull() + { + + return $this->fld_null; + } + + /** + * Get the [fld_auto_increment] column value. + * + * @return int + */ + public function getFldAutoIncrement() + { + + return $this->fld_auto_increment; + } + + /** + * Get the [fld_key] column value. + * + * @return int + */ + public function getFldKey() + { + + return $this->fld_key; + } + + /** + * Get the [fld_foreign_key] column value. + * + * @return int + */ + public function getFldForeignKey() + { + + return $this->fld_foreign_key; + } + + /** + * Get the [fld_foreign_key_table] column value. + * + * @return string + */ + public function getFldForeignKeyTable() + { + + return $this->fld_foreign_key_table; + } + + /** + * Set the value of [fld_uid] column. + * + * @param string $v new value + * @return void + */ + public function setFldUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fld_uid !== $v || $v === '') { + $this->fld_uid = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_UID; + } + + } // setFldUid() + + /** + * Set the value of [add_tab_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_uid !== $v || $v === '') { + $this->add_tab_uid = $v; + $this->modifiedColumns[] = FieldsPeer::ADD_TAB_UID; + } + + } // setAddTabUid() + + /** + * Set the value of [fld_index] column. + * + * @param int $v new value + * @return void + */ + public function setFldIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_index !== $v || $v === 1) { + $this->fld_index = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_INDEX; + } + + } // setFldIndex() + + /** + * Set the value of [fld_name] column. + * + * @param string $v new value + * @return void + */ + public function setFldName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fld_name !== $v || $v === '') { + $this->fld_name = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_NAME; + } + + } // setFldName() + + /** + * Set the value of [fld_description] column. + * + * @param string $v new value + * @return void + */ + public function setFldDescription($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fld_description !== $v) { + $this->fld_description = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_DESCRIPTION; + } + + } // setFldDescription() + + /** + * Set the value of [fld_type] column. + * + * @param string $v new value + * @return void + */ + public function setFldType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fld_type !== $v || $v === '') { + $this->fld_type = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_TYPE; + } + + } // setFldType() + + /** + * Set the value of [fld_size] column. + * + * @param int $v new value + * @return void + */ + public function setFldSize($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_size !== $v || $v === 1) { + $this->fld_size = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_SIZE; + } + + } // setFldSize() + + /** + * Set the value of [fld_null] column. + * + * @param int $v new value + * @return void + */ + public function setFldNull($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_null !== $v || $v === 1) { + $this->fld_null = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_NULL; + } + + } // setFldNull() + + /** + * Set the value of [fld_auto_increment] column. + * + * @param int $v new value + * @return void + */ + public function setFldAutoIncrement($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_auto_increment !== $v || $v === 0) { + $this->fld_auto_increment = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_AUTO_INCREMENT; + } + + } // setFldAutoIncrement() + + /** + * Set the value of [fld_key] column. + * + * @param int $v new value + * @return void + */ + public function setFldKey($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_key !== $v || $v === 0) { + $this->fld_key = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_KEY; + } + + } // setFldKey() + + /** + * Set the value of [fld_foreign_key] column. + * + * @param int $v new value + * @return void + */ + public function setFldForeignKey($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->fld_foreign_key !== $v || $v === 0) { + $this->fld_foreign_key = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_FOREIGN_KEY; + } + + } // setFldForeignKey() + + /** + * Set the value of [fld_foreign_key_table] column. + * + * @param string $v new value + * @return void + */ + public function setFldForeignKeyTable($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->fld_foreign_key_table !== $v || $v === '') { + $this->fld_foreign_key_table = $v; + $this->modifiedColumns[] = FieldsPeer::FLD_FOREIGN_KEY_TABLE; + } + + } // setFldForeignKeyTable() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->fld_uid = $rs->getString($startcol + 0); + + $this->add_tab_uid = $rs->getString($startcol + 1); + + $this->fld_index = $rs->getInt($startcol + 2); + + $this->fld_name = $rs->getString($startcol + 3); + + $this->fld_description = $rs->getString($startcol + 4); + + $this->fld_type = $rs->getString($startcol + 5); + + $this->fld_size = $rs->getInt($startcol + 6); + + $this->fld_null = $rs->getInt($startcol + 7); + + $this->fld_auto_increment = $rs->getInt($startcol + 8); + + $this->fld_key = $rs->getInt($startcol + 9); + + $this->fld_foreign_key = $rs->getInt($startcol + 10); + + $this->fld_foreign_key_table = $rs->getString($startcol + 11); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 12; // 12 = FieldsPeer::NUM_COLUMNS - FieldsPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Fields object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(FieldsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + FieldsPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(FieldsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = FieldsPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += FieldsPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = FieldsPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = FieldsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getFldUid(); + break; + case 1: + return $this->getAddTabUid(); + break; + case 2: + return $this->getFldIndex(); + break; + case 3: + return $this->getFldName(); + break; + case 4: + return $this->getFldDescription(); + break; + case 5: + return $this->getFldType(); + break; + case 6: + return $this->getFldSize(); + break; + case 7: + return $this->getFldNull(); + break; + case 8: + return $this->getFldAutoIncrement(); + break; + case 9: + return $this->getFldKey(); + break; + case 10: + return $this->getFldForeignKey(); + break; + case 11: + return $this->getFldForeignKeyTable(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = FieldsPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getFldUid(), + $keys[1] => $this->getAddTabUid(), + $keys[2] => $this->getFldIndex(), + $keys[3] => $this->getFldName(), + $keys[4] => $this->getFldDescription(), + $keys[5] => $this->getFldType(), + $keys[6] => $this->getFldSize(), + $keys[7] => $this->getFldNull(), + $keys[8] => $this->getFldAutoIncrement(), + $keys[9] => $this->getFldKey(), + $keys[10] => $this->getFldForeignKey(), + $keys[11] => $this->getFldForeignKeyTable(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = FieldsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setFldUid($value); + break; + case 1: + $this->setAddTabUid($value); + break; + case 2: + $this->setFldIndex($value); + break; + case 3: + $this->setFldName($value); + break; + case 4: + $this->setFldDescription($value); + break; + case 5: + $this->setFldType($value); + break; + case 6: + $this->setFldSize($value); + break; + case 7: + $this->setFldNull($value); + break; + case 8: + $this->setFldAutoIncrement($value); + break; + case 9: + $this->setFldKey($value); + break; + case 10: + $this->setFldForeignKey($value); + break; + case 11: + $this->setFldForeignKeyTable($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = FieldsPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setFldUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAddTabUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFldIndex($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setFldName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setFldDescription($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setFldType($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setFldSize($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setFldNull($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setFldAutoIncrement($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setFldKey($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setFldForeignKey($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setFldForeignKeyTable($arr[$keys[11]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(FieldsPeer::DATABASE_NAME); + + if ($this->isColumnModified(FieldsPeer::FLD_UID)) $criteria->add(FieldsPeer::FLD_UID, $this->fld_uid); + if ($this->isColumnModified(FieldsPeer::ADD_TAB_UID)) $criteria->add(FieldsPeer::ADD_TAB_UID, $this->add_tab_uid); + if ($this->isColumnModified(FieldsPeer::FLD_INDEX)) $criteria->add(FieldsPeer::FLD_INDEX, $this->fld_index); + if ($this->isColumnModified(FieldsPeer::FLD_NAME)) $criteria->add(FieldsPeer::FLD_NAME, $this->fld_name); + if ($this->isColumnModified(FieldsPeer::FLD_DESCRIPTION)) $criteria->add(FieldsPeer::FLD_DESCRIPTION, $this->fld_description); + if ($this->isColumnModified(FieldsPeer::FLD_TYPE)) $criteria->add(FieldsPeer::FLD_TYPE, $this->fld_type); + if ($this->isColumnModified(FieldsPeer::FLD_SIZE)) $criteria->add(FieldsPeer::FLD_SIZE, $this->fld_size); + if ($this->isColumnModified(FieldsPeer::FLD_NULL)) $criteria->add(FieldsPeer::FLD_NULL, $this->fld_null); + if ($this->isColumnModified(FieldsPeer::FLD_AUTO_INCREMENT)) $criteria->add(FieldsPeer::FLD_AUTO_INCREMENT, $this->fld_auto_increment); + if ($this->isColumnModified(FieldsPeer::FLD_KEY)) $criteria->add(FieldsPeer::FLD_KEY, $this->fld_key); + if ($this->isColumnModified(FieldsPeer::FLD_FOREIGN_KEY)) $criteria->add(FieldsPeer::FLD_FOREIGN_KEY, $this->fld_foreign_key); + if ($this->isColumnModified(FieldsPeer::FLD_FOREIGN_KEY_TABLE)) $criteria->add(FieldsPeer::FLD_FOREIGN_KEY_TABLE, $this->fld_foreign_key_table); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(FieldsPeer::DATABASE_NAME); + + $criteria->add(FieldsPeer::FLD_UID, $this->fld_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getFldUid(); + } + + /** + * Generic method to set the primary key (fld_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setFldUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Fields (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAddTabUid($this->add_tab_uid); + + $copyObj->setFldIndex($this->fld_index); + + $copyObj->setFldName($this->fld_name); + + $copyObj->setFldDescription($this->fld_description); + + $copyObj->setFldType($this->fld_type); + + $copyObj->setFldSize($this->fld_size); + + $copyObj->setFldNull($this->fld_null); + + $copyObj->setFldAutoIncrement($this->fld_auto_increment); + + $copyObj->setFldKey($this->fld_key); + + $copyObj->setFldForeignKey($this->fld_foreign_key); + + $copyObj->setFldForeignKeyTable($this->fld_foreign_key_table); + + + $copyObj->setNew(true); + + $copyObj->setFldUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Fields Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return FieldsPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new FieldsPeer(); + } + return self::$peer; + } + +} // BaseFields diff --git a/workflow/engine/classes/model/om/BaseFieldsPeer.php b/workflow/engine/classes/model/om/BaseFieldsPeer.php new file mode 100644 index 000000000..5b90751cc --- /dev/null +++ b/workflow/engine/classes/model/om/BaseFieldsPeer.php @@ -0,0 +1,620 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by FieldsPeer::getOMClass() +include_once 'classes/model/Fields.php'; + +/** + * Base static class for performing query and update operations on the 'FIELDS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseFieldsPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'FIELDS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Fields'; + + /** The total number of columns. */ + const NUM_COLUMNS = 12; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the FLD_UID field */ + const FLD_UID = 'FIELDS.FLD_UID'; + + /** the column name for the ADD_TAB_UID field */ + const ADD_TAB_UID = 'FIELDS.ADD_TAB_UID'; + + /** the column name for the FLD_INDEX field */ + const FLD_INDEX = 'FIELDS.FLD_INDEX'; + + /** the column name for the FLD_NAME field */ + const FLD_NAME = 'FIELDS.FLD_NAME'; + + /** the column name for the FLD_DESCRIPTION field */ + const FLD_DESCRIPTION = 'FIELDS.FLD_DESCRIPTION'; + + /** the column name for the FLD_TYPE field */ + const FLD_TYPE = 'FIELDS.FLD_TYPE'; + + /** the column name for the FLD_SIZE field */ + const FLD_SIZE = 'FIELDS.FLD_SIZE'; + + /** the column name for the FLD_NULL field */ + const FLD_NULL = 'FIELDS.FLD_NULL'; + + /** the column name for the FLD_AUTO_INCREMENT field */ + const FLD_AUTO_INCREMENT = 'FIELDS.FLD_AUTO_INCREMENT'; + + /** the column name for the FLD_KEY field */ + const FLD_KEY = 'FIELDS.FLD_KEY'; + + /** the column name for the FLD_FOREIGN_KEY field */ + const FLD_FOREIGN_KEY = 'FIELDS.FLD_FOREIGN_KEY'; + + /** the column name for the FLD_FOREIGN_KEY_TABLE field */ + const FLD_FOREIGN_KEY_TABLE = 'FIELDS.FLD_FOREIGN_KEY_TABLE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('FldUid', 'AddTabUid', 'FldIndex', 'FldName', 'FldDescription', 'FldType', 'FldSize', 'FldNull', 'FldAutoIncrement', 'FldKey', 'FldForeignKey', 'FldForeignKeyTable', ), + BasePeer::TYPE_COLNAME => array (FieldsPeer::FLD_UID, FieldsPeer::ADD_TAB_UID, FieldsPeer::FLD_INDEX, FieldsPeer::FLD_NAME, FieldsPeer::FLD_DESCRIPTION, FieldsPeer::FLD_TYPE, FieldsPeer::FLD_SIZE, FieldsPeer::FLD_NULL, FieldsPeer::FLD_AUTO_INCREMENT, FieldsPeer::FLD_KEY, FieldsPeer::FLD_FOREIGN_KEY, FieldsPeer::FLD_FOREIGN_KEY_TABLE, ), + BasePeer::TYPE_FIELDNAME => array ('FLD_UID', 'ADD_TAB_UID', 'FLD_INDEX', 'FLD_NAME', 'FLD_DESCRIPTION', 'FLD_TYPE', 'FLD_SIZE', 'FLD_NULL', 'FLD_AUTO_INCREMENT', 'FLD_KEY', 'FLD_FOREIGN_KEY', 'FLD_FOREIGN_KEY_TABLE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('FldUid' => 0, 'AddTabUid' => 1, 'FldIndex' => 2, 'FldName' => 3, 'FldDescription' => 4, 'FldType' => 5, 'FldSize' => 6, 'FldNull' => 7, 'FldAutoIncrement' => 8, 'FldKey' => 9, 'FldForeignKey' => 10, 'FldForeignKeyTable' => 11, ), + BasePeer::TYPE_COLNAME => array (FieldsPeer::FLD_UID => 0, FieldsPeer::ADD_TAB_UID => 1, FieldsPeer::FLD_INDEX => 2, FieldsPeer::FLD_NAME => 3, FieldsPeer::FLD_DESCRIPTION => 4, FieldsPeer::FLD_TYPE => 5, FieldsPeer::FLD_SIZE => 6, FieldsPeer::FLD_NULL => 7, FieldsPeer::FLD_AUTO_INCREMENT => 8, FieldsPeer::FLD_KEY => 9, FieldsPeer::FLD_FOREIGN_KEY => 10, FieldsPeer::FLD_FOREIGN_KEY_TABLE => 11, ), + BasePeer::TYPE_FIELDNAME => array ('FLD_UID' => 0, 'ADD_TAB_UID' => 1, 'FLD_INDEX' => 2, 'FLD_NAME' => 3, 'FLD_DESCRIPTION' => 4, 'FLD_TYPE' => 5, 'FLD_SIZE' => 6, 'FLD_NULL' => 7, 'FLD_AUTO_INCREMENT' => 8, 'FLD_KEY' => 9, 'FLD_FOREIGN_KEY' => 10, 'FLD_FOREIGN_KEY_TABLE' => 11, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/FieldsMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.FieldsMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = FieldsPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. FieldsPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(FieldsPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(FieldsPeer::FLD_UID); + + $criteria->addSelectColumn(FieldsPeer::ADD_TAB_UID); + + $criteria->addSelectColumn(FieldsPeer::FLD_INDEX); + + $criteria->addSelectColumn(FieldsPeer::FLD_NAME); + + $criteria->addSelectColumn(FieldsPeer::FLD_DESCRIPTION); + + $criteria->addSelectColumn(FieldsPeer::FLD_TYPE); + + $criteria->addSelectColumn(FieldsPeer::FLD_SIZE); + + $criteria->addSelectColumn(FieldsPeer::FLD_NULL); + + $criteria->addSelectColumn(FieldsPeer::FLD_AUTO_INCREMENT); + + $criteria->addSelectColumn(FieldsPeer::FLD_KEY); + + $criteria->addSelectColumn(FieldsPeer::FLD_FOREIGN_KEY); + + $criteria->addSelectColumn(FieldsPeer::FLD_FOREIGN_KEY_TABLE); + + } + + const COUNT = 'COUNT(FIELDS.FLD_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT FIELDS.FLD_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(FieldsPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(FieldsPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = FieldsPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Fields + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = FieldsPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return FieldsPeer::populateObjects(FieldsPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + FieldsPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = FieldsPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return FieldsPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Fields or Criteria object. + * + * @param mixed $values Criteria or Fields object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Fields object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Fields or Criteria object. + * + * @param mixed $values Criteria or Fields object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(FieldsPeer::FLD_UID); + $selectCriteria->add(FieldsPeer::FLD_UID, $criteria->remove(FieldsPeer::FLD_UID), $comparison); + + } else { // $values is Fields object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the FIELDS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(FieldsPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Fields or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Fields object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(FieldsPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Fields) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(FieldsPeer::FLD_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Fields object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Fields $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Fields $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(FieldsPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(FieldsPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(FieldsPeer::DATABASE_NAME, FieldsPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Fields + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(FieldsPeer::DATABASE_NAME); + + $criteria->add(FieldsPeer::FLD_UID, $pk); + + + $v = FieldsPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(FieldsPeer::FLD_UID, $pks, Criteria::IN); + $objs = FieldsPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseFieldsPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseFieldsPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/FieldsMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.FieldsMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseGroupUser.php b/workflow/engine/classes/model/om/BaseGroupUser.php new file mode 100644 index 000000000..47e37f5c0 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseGroupUser.php @@ -0,0 +1,569 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/GroupUserPeer.php'; + +/** + * Base class that represents a row from the 'GROUP_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseGroupUser extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var GroupUserPeer + */ + protected static $peer; + + + /** + * The value for the grp_uid field. + * @var string + */ + protected $grp_uid = '0'; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = '0'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [grp_uid] column value. + * + * @return string + */ + public function getGrpUid() + { + + return $this->grp_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Set the value of [grp_uid] column. + * + * @param string $v new value + * @return void + */ + public function setGrpUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->grp_uid !== $v || $v === '0') { + $this->grp_uid = $v; + $this->modifiedColumns[] = GroupUserPeer::GRP_UID; + } + + } // setGrpUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '0') { + $this->usr_uid = $v; + $this->modifiedColumns[] = GroupUserPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->grp_uid = $rs->getString($startcol + 0); + + $this->usr_uid = $rs->getString($startcol + 1); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 2; // 2 = GroupUserPeer::NUM_COLUMNS - GroupUserPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating GroupUser object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(GroupUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + GroupUserPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(GroupUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = GroupUserPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += GroupUserPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = GroupUserPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = GroupUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getGrpUid(); + break; + case 1: + return $this->getUsrUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = GroupUserPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getGrpUid(), + $keys[1] => $this->getUsrUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = GroupUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setGrpUid($value); + break; + case 1: + $this->setUsrUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = GroupUserPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setGrpUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setUsrUid($arr[$keys[1]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(GroupUserPeer::DATABASE_NAME); + + if ($this->isColumnModified(GroupUserPeer::GRP_UID)) $criteria->add(GroupUserPeer::GRP_UID, $this->grp_uid); + if ($this->isColumnModified(GroupUserPeer::USR_UID)) $criteria->add(GroupUserPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(GroupUserPeer::DATABASE_NAME); + + $criteria->add(GroupUserPeer::GRP_UID, $this->grp_uid); + $criteria->add(GroupUserPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getGrpUid(); + + $pks[1] = $this->getUsrUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setGrpUid($keys[0]); + + $this->setUsrUid($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of GroupUser (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + + $copyObj->setNew(true); + + $copyObj->setGrpUid('0'); // this is a pkey column, so set to default value + + $copyObj->setUsrUid('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return GroupUser Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return GroupUserPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new GroupUserPeer(); + } + return self::$peer; + } + +} // BaseGroupUser diff --git a/workflow/engine/classes/model/om/BaseGroupUserPeer.php b/workflow/engine/classes/model/om/BaseGroupUserPeer.php new file mode 100644 index 000000000..c97cd233f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseGroupUserPeer.php @@ -0,0 +1,567 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by GroupUserPeer::getOMClass() +include_once 'classes/model/GroupUser.php'; + +/** + * Base static class for performing query and update operations on the 'GROUP_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseGroupUserPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'GROUP_USER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.GroupUser'; + + /** The total number of columns. */ + const NUM_COLUMNS = 2; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the GRP_UID field */ + const GRP_UID = 'GROUP_USER.GRP_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'GROUP_USER.USR_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('GrpUid', 'UsrUid', ), + BasePeer::TYPE_COLNAME => array (GroupUserPeer::GRP_UID, GroupUserPeer::USR_UID, ), + BasePeer::TYPE_FIELDNAME => array ('GRP_UID', 'USR_UID', ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('GrpUid' => 0, 'UsrUid' => 1, ), + BasePeer::TYPE_COLNAME => array (GroupUserPeer::GRP_UID => 0, GroupUserPeer::USR_UID => 1, ), + BasePeer::TYPE_FIELDNAME => array ('GRP_UID' => 0, 'USR_UID' => 1, ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/GroupUserMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.GroupUserMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = GroupUserPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. GroupUserPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(GroupUserPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(GroupUserPeer::GRP_UID); + + $criteria->addSelectColumn(GroupUserPeer::USR_UID); + + } + + const COUNT = 'COUNT(GROUP_USER.GRP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT GROUP_USER.GRP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(GroupUserPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(GroupUserPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = GroupUserPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return GroupUser + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = GroupUserPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return GroupUserPeer::populateObjects(GroupUserPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + GroupUserPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = GroupUserPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return GroupUserPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a GroupUser or Criteria object. + * + * @param mixed $values Criteria or GroupUser object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from GroupUser object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a GroupUser or Criteria object. + * + * @param mixed $values Criteria or GroupUser object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(GroupUserPeer::GRP_UID); + $selectCriteria->add(GroupUserPeer::GRP_UID, $criteria->remove(GroupUserPeer::GRP_UID), $comparison); + + $comparison = $criteria->getComparison(GroupUserPeer::USR_UID); + $selectCriteria->add(GroupUserPeer::USR_UID, $criteria->remove(GroupUserPeer::USR_UID), $comparison); + + } else { // $values is GroupUser object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the GROUP_USER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(GroupUserPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a GroupUser or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or GroupUser object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(GroupUserPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof GroupUser) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(GroupUserPeer::GRP_UID, $vals[0], Criteria::IN); + $criteria->add(GroupUserPeer::USR_UID, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given GroupUser object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param GroupUser $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(GroupUser $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(GroupUserPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(GroupUserPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(GroupUserPeer::GRP_UID)) + $columns[GroupUserPeer::GRP_UID] = $obj->getGrpUid(); + + if ($obj->isNew() || $obj->isColumnModified(GroupUserPeer::USR_UID)) + $columns[GroupUserPeer::USR_UID] = $obj->getUsrUid(); + + } + + return BasePeer::doValidate(GroupUserPeer::DATABASE_NAME, GroupUserPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $grp_uid + @param string $usr_uid + + * @param Connection $con + * @return GroupUser + */ + public static function retrieveByPK( $grp_uid, $usr_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(GroupUserPeer::GRP_UID, $grp_uid); + $criteria->add(GroupUserPeer::USR_UID, $usr_uid); + $v = GroupUserPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseGroupUserPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseGroupUserPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/GroupUserMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.GroupUserMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseGroupwf.php b/workflow/engine/classes/model/om/BaseGroupwf.php new file mode 100644 index 000000000..8f5956fc1 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseGroupwf.php @@ -0,0 +1,557 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/GroupwfPeer.php'; + +/** + * Base class that represents a row from the 'GROUPWF' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseGroupwf extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var GroupwfPeer + */ + protected static $peer; + + + /** + * The value for the grp_uid field. + * @var string + */ + protected $grp_uid = ''; + + + /** + * The value for the grp_status field. + * @var string + */ + protected $grp_status = 'ACTIVE'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [grp_uid] column value. + * + * @return string + */ + public function getGrpUid() + { + + return $this->grp_uid; + } + + /** + * Get the [grp_status] column value. + * + * @return string + */ + public function getGrpStatus() + { + + return $this->grp_status; + } + + /** + * Set the value of [grp_uid] column. + * + * @param string $v new value + * @return void + */ + public function setGrpUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->grp_uid !== $v || $v === '') { + $this->grp_uid = $v; + $this->modifiedColumns[] = GroupwfPeer::GRP_UID; + } + + } // setGrpUid() + + /** + * Set the value of [grp_status] column. + * + * @param string $v new value + * @return void + */ + public function setGrpStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->grp_status !== $v || $v === 'ACTIVE') { + $this->grp_status = $v; + $this->modifiedColumns[] = GroupwfPeer::GRP_STATUS; + } + + } // setGrpStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->grp_uid = $rs->getString($startcol + 0); + + $this->grp_status = $rs->getString($startcol + 1); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 2; // 2 = GroupwfPeer::NUM_COLUMNS - GroupwfPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Groupwf object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(GroupwfPeer::DATABASE_NAME); + } + + try { + $con->begin(); + GroupwfPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(GroupwfPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = GroupwfPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += GroupwfPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = GroupwfPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = GroupwfPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getGrpUid(); + break; + case 1: + return $this->getGrpStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = GroupwfPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getGrpUid(), + $keys[1] => $this->getGrpStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = GroupwfPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setGrpUid($value); + break; + case 1: + $this->setGrpStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = GroupwfPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setGrpUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setGrpStatus($arr[$keys[1]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(GroupwfPeer::DATABASE_NAME); + + if ($this->isColumnModified(GroupwfPeer::GRP_UID)) $criteria->add(GroupwfPeer::GRP_UID, $this->grp_uid); + if ($this->isColumnModified(GroupwfPeer::GRP_STATUS)) $criteria->add(GroupwfPeer::GRP_STATUS, $this->grp_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(GroupwfPeer::DATABASE_NAME); + + $criteria->add(GroupwfPeer::GRP_UID, $this->grp_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getGrpUid(); + } + + /** + * Generic method to set the primary key (grp_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setGrpUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Groupwf (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setGrpStatus($this->grp_status); + + + $copyObj->setNew(true); + + $copyObj->setGrpUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Groupwf Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return GroupwfPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new GroupwfPeer(); + } + return self::$peer; + } + +} // BaseGroupwf diff --git a/workflow/engine/classes/model/om/BaseGroupwfPeer.php b/workflow/engine/classes/model/om/BaseGroupwfPeer.php new file mode 100644 index 000000000..378f21520 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseGroupwfPeer.php @@ -0,0 +1,573 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by GroupwfPeer::getOMClass() +include_once 'classes/model/Groupwf.php'; + +/** + * Base static class for performing query and update operations on the 'GROUPWF' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseGroupwfPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'GROUPWF'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Groupwf'; + + /** The total number of columns. */ + const NUM_COLUMNS = 2; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the GRP_UID field */ + const GRP_UID = 'GROUPWF.GRP_UID'; + + /** the column name for the GRP_STATUS field */ + const GRP_STATUS = 'GROUPWF.GRP_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('GrpUid', 'GrpStatus', ), + BasePeer::TYPE_COLNAME => array (GroupwfPeer::GRP_UID, GroupwfPeer::GRP_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('GRP_UID', 'GRP_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('GrpUid' => 0, 'GrpStatus' => 1, ), + BasePeer::TYPE_COLNAME => array (GroupwfPeer::GRP_UID => 0, GroupwfPeer::GRP_STATUS => 1, ), + BasePeer::TYPE_FIELDNAME => array ('GRP_UID' => 0, 'GRP_STATUS' => 1, ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/GroupwfMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.GroupwfMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = GroupwfPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. GroupwfPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(GroupwfPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(GroupwfPeer::GRP_UID); + + $criteria->addSelectColumn(GroupwfPeer::GRP_STATUS); + + } + + const COUNT = 'COUNT(GROUPWF.GRP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT GROUPWF.GRP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(GroupwfPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(GroupwfPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = GroupwfPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Groupwf + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = GroupwfPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return GroupwfPeer::populateObjects(GroupwfPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + GroupwfPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = GroupwfPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return GroupwfPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Groupwf or Criteria object. + * + * @param mixed $values Criteria or Groupwf object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Groupwf object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Groupwf or Criteria object. + * + * @param mixed $values Criteria or Groupwf object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(GroupwfPeer::GRP_UID); + $selectCriteria->add(GroupwfPeer::GRP_UID, $criteria->remove(GroupwfPeer::GRP_UID), $comparison); + + } else { // $values is Groupwf object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the GROUPWF table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(GroupwfPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Groupwf or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Groupwf object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(GroupwfPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Groupwf) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(GroupwfPeer::GRP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Groupwf object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Groupwf $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Groupwf $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(GroupwfPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(GroupwfPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(GroupwfPeer::GRP_STATUS)) + $columns[GroupwfPeer::GRP_STATUS] = $obj->getGrpStatus(); + + } + + return BasePeer::doValidate(GroupwfPeer::DATABASE_NAME, GroupwfPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Groupwf + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(GroupwfPeer::DATABASE_NAME); + + $criteria->add(GroupwfPeer::GRP_UID, $pk); + + + $v = GroupwfPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(GroupwfPeer::GRP_UID, $pks, Criteria::IN); + $objs = GroupwfPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseGroupwfPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseGroupwfPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/GroupwfMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.GroupwfMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseHoliday.php b/workflow/engine/classes/model/om/BaseHoliday.php new file mode 100644 index 000000000..38e57b0ce --- /dev/null +++ b/workflow/engine/classes/model/om/BaseHoliday.php @@ -0,0 +1,612 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/HolidayPeer.php'; + +/** + * Base class that represents a row from the 'HOLIDAY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseHoliday extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var HolidayPeer + */ + protected static $peer; + + + /** + * The value for the hld_uid field. + * @var int + */ + protected $hld_uid; + + + /** + * The value for the hld_date field. + * @var string + */ + protected $hld_date = '0000-00-00'; + + + /** + * The value for the hld_description field. + * @var string + */ + protected $hld_description = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [hld_uid] column value. + * + * @return int + */ + public function getHldUid() + { + + return $this->hld_uid; + } + + /** + * Get the [hld_date] column value. + * + * @return string + */ + public function getHldDate() + { + + return $this->hld_date; + } + + /** + * Get the [hld_description] column value. + * + * @return string + */ + public function getHldDescription() + { + + return $this->hld_description; + } + + /** + * Set the value of [hld_uid] column. + * + * @param int $v new value + * @return void + */ + public function setHldUid($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->hld_uid !== $v) { + $this->hld_uid = $v; + $this->modifiedColumns[] = HolidayPeer::HLD_UID; + } + + } // setHldUid() + + /** + * Set the value of [hld_date] column. + * + * @param string $v new value + * @return void + */ + public function setHldDate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->hld_date !== $v || $v === '0000-00-00') { + $this->hld_date = $v; + $this->modifiedColumns[] = HolidayPeer::HLD_DATE; + } + + } // setHldDate() + + /** + * Set the value of [hld_description] column. + * + * @param string $v new value + * @return void + */ + public function setHldDescription($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->hld_description !== $v || $v === '') { + $this->hld_description = $v; + $this->modifiedColumns[] = HolidayPeer::HLD_DESCRIPTION; + } + + } // setHldDescription() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->hld_uid = $rs->getInt($startcol + 0); + + $this->hld_date = $rs->getString($startcol + 1); + + $this->hld_description = $rs->getString($startcol + 2); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 3; // 3 = HolidayPeer::NUM_COLUMNS - HolidayPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Holiday object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(HolidayPeer::DATABASE_NAME); + } + + try { + $con->begin(); + HolidayPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(HolidayPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = HolidayPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setHldUid($pk); //[IMV] update autoincrement primary key + + $this->setNew(false); + } else { + $affectedRows += HolidayPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = HolidayPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = HolidayPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getHldUid(); + break; + case 1: + return $this->getHldDate(); + break; + case 2: + return $this->getHldDescription(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = HolidayPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getHldUid(), + $keys[1] => $this->getHldDate(), + $keys[2] => $this->getHldDescription(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = HolidayPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setHldUid($value); + break; + case 1: + $this->setHldDate($value); + break; + case 2: + $this->setHldDescription($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = HolidayPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setHldUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setHldDate($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setHldDescription($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(HolidayPeer::DATABASE_NAME); + + if ($this->isColumnModified(HolidayPeer::HLD_UID)) $criteria->add(HolidayPeer::HLD_UID, $this->hld_uid); + if ($this->isColumnModified(HolidayPeer::HLD_DATE)) $criteria->add(HolidayPeer::HLD_DATE, $this->hld_date); + if ($this->isColumnModified(HolidayPeer::HLD_DESCRIPTION)) $criteria->add(HolidayPeer::HLD_DESCRIPTION, $this->hld_description); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(HolidayPeer::DATABASE_NAME); + + $criteria->add(HolidayPeer::HLD_UID, $this->hld_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getHldUid(); + } + + /** + * Generic method to set the primary key (hld_uid column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setHldUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Holiday (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setHldDate($this->hld_date); + + $copyObj->setHldDescription($this->hld_description); + + + $copyObj->setNew(true); + + $copyObj->setHldUid(NULL); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Holiday Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return HolidayPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new HolidayPeer(); + } + return self::$peer; + } + +} // BaseHoliday diff --git a/workflow/engine/classes/model/om/BaseHolidayPeer.php b/workflow/engine/classes/model/om/BaseHolidayPeer.php new file mode 100644 index 000000000..122bd33ad --- /dev/null +++ b/workflow/engine/classes/model/om/BaseHolidayPeer.php @@ -0,0 +1,577 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by HolidayPeer::getOMClass() +include_once 'classes/model/Holiday.php'; + +/** + * Base static class for performing query and update operations on the 'HOLIDAY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseHolidayPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'HOLIDAY'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Holiday'; + + /** The total number of columns. */ + const NUM_COLUMNS = 3; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the HLD_UID field */ + const HLD_UID = 'HOLIDAY.HLD_UID'; + + /** the column name for the HLD_DATE field */ + const HLD_DATE = 'HOLIDAY.HLD_DATE'; + + /** the column name for the HLD_DESCRIPTION field */ + const HLD_DESCRIPTION = 'HOLIDAY.HLD_DESCRIPTION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('HldUid', 'HldDate', 'HldDescription', ), + BasePeer::TYPE_COLNAME => array (HolidayPeer::HLD_UID, HolidayPeer::HLD_DATE, HolidayPeer::HLD_DESCRIPTION, ), + BasePeer::TYPE_FIELDNAME => array ('HLD_UID', 'HLD_DATE', 'HLD_DESCRIPTION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('HldUid' => 0, 'HldDate' => 1, 'HldDescription' => 2, ), + BasePeer::TYPE_COLNAME => array (HolidayPeer::HLD_UID => 0, HolidayPeer::HLD_DATE => 1, HolidayPeer::HLD_DESCRIPTION => 2, ), + BasePeer::TYPE_FIELDNAME => array ('HLD_UID' => 0, 'HLD_DATE' => 1, 'HLD_DESCRIPTION' => 2, ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/HolidayMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.HolidayMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = HolidayPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. HolidayPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(HolidayPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(HolidayPeer::HLD_UID); + + $criteria->addSelectColumn(HolidayPeer::HLD_DATE); + + $criteria->addSelectColumn(HolidayPeer::HLD_DESCRIPTION); + + } + + const COUNT = 'COUNT(HOLIDAY.HLD_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT HOLIDAY.HLD_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(HolidayPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(HolidayPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = HolidayPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Holiday + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = HolidayPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return HolidayPeer::populateObjects(HolidayPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + HolidayPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = HolidayPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return HolidayPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Holiday or Criteria object. + * + * @param mixed $values Criteria or Holiday object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Holiday object + } + + $criteria->remove(HolidayPeer::HLD_UID); // remove pkey col since this table uses auto-increment + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Holiday or Criteria object. + * + * @param mixed $values Criteria or Holiday object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(HolidayPeer::HLD_UID); + $selectCriteria->add(HolidayPeer::HLD_UID, $criteria->remove(HolidayPeer::HLD_UID), $comparison); + + } else { // $values is Holiday object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the HOLIDAY table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(HolidayPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Holiday or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Holiday object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(HolidayPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Holiday) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(HolidayPeer::HLD_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Holiday object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Holiday $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Holiday $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(HolidayPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(HolidayPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(HolidayPeer::DATABASE_NAME, HolidayPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Holiday + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(HolidayPeer::DATABASE_NAME); + + $criteria->add(HolidayPeer::HLD_UID, $pk); + + + $v = HolidayPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(HolidayPeer::HLD_UID, $pks, Criteria::IN); + $objs = HolidayPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseHolidayPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseHolidayPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/HolidayMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.HolidayMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseInputDocument.php b/workflow/engine/classes/model/om/BaseInputDocument.php new file mode 100644 index 000000000..22dc3ede5 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseInputDocument.php @@ -0,0 +1,875 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/InputDocumentPeer.php'; + +/** + * Base class that represents a row from the 'INPUT_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseInputDocument extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var InputDocumentPeer + */ + protected static $peer; + + + /** + * The value for the inp_doc_uid field. + * @var string + */ + protected $inp_doc_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the inp_doc_form_needed field. + * @var string + */ + protected $inp_doc_form_needed = 'REAL'; + + + /** + * The value for the inp_doc_original field. + * @var string + */ + protected $inp_doc_original = 'COPY'; + + + /** + * The value for the inp_doc_published field. + * @var string + */ + protected $inp_doc_published = 'PRIVATE'; + + + /** + * The value for the inp_doc_versioning field. + * @var int + */ + protected $inp_doc_versioning = 0; + + + /** + * The value for the inp_doc_destination_path field. + * @var string + */ + protected $inp_doc_destination_path; + + + /** + * The value for the inp_doc_tags field. + * @var string + */ + protected $inp_doc_tags; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [inp_doc_uid] column value. + * + * @return string + */ + public function getInpDocUid() + { + + return $this->inp_doc_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [inp_doc_form_needed] column value. + * + * @return string + */ + public function getInpDocFormNeeded() + { + + return $this->inp_doc_form_needed; + } + + /** + * Get the [inp_doc_original] column value. + * + * @return string + */ + public function getInpDocOriginal() + { + + return $this->inp_doc_original; + } + + /** + * Get the [inp_doc_published] column value. + * + * @return string + */ + public function getInpDocPublished() + { + + return $this->inp_doc_published; + } + + /** + * Get the [inp_doc_versioning] column value. + * + * @return int + */ + public function getInpDocVersioning() + { + + return $this->inp_doc_versioning; + } + + /** + * Get the [inp_doc_destination_path] column value. + * + * @return string + */ + public function getInpDocDestinationPath() + { + + return $this->inp_doc_destination_path; + } + + /** + * Get the [inp_doc_tags] column value. + * + * @return string + */ + public function getInpDocTags() + { + + return $this->inp_doc_tags; + } + + /** + * Set the value of [inp_doc_uid] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_uid !== $v || $v === '') { + $this->inp_doc_uid = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_UID; + } + + } // setInpDocUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = InputDocumentPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [inp_doc_form_needed] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocFormNeeded($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_form_needed !== $v || $v === 'REAL') { + $this->inp_doc_form_needed = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_FORM_NEEDED; + } + + } // setInpDocFormNeeded() + + /** + * Set the value of [inp_doc_original] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocOriginal($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_original !== $v || $v === 'COPY') { + $this->inp_doc_original = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_ORIGINAL; + } + + } // setInpDocOriginal() + + /** + * Set the value of [inp_doc_published] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocPublished($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_published !== $v || $v === 'PRIVATE') { + $this->inp_doc_published = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_PUBLISHED; + } + + } // setInpDocPublished() + + /** + * Set the value of [inp_doc_versioning] column. + * + * @param int $v new value + * @return void + */ + public function setInpDocVersioning($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->inp_doc_versioning !== $v || $v === 0) { + $this->inp_doc_versioning = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_VERSIONING; + } + + } // setInpDocVersioning() + + /** + * Set the value of [inp_doc_destination_path] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocDestinationPath($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_destination_path !== $v) { + $this->inp_doc_destination_path = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_DESTINATION_PATH; + } + + } // setInpDocDestinationPath() + + /** + * Set the value of [inp_doc_tags] column. + * + * @param string $v new value + * @return void + */ + public function setInpDocTags($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->inp_doc_tags !== $v) { + $this->inp_doc_tags = $v; + $this->modifiedColumns[] = InputDocumentPeer::INP_DOC_TAGS; + } + + } // setInpDocTags() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->inp_doc_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->inp_doc_form_needed = $rs->getString($startcol + 2); + + $this->inp_doc_original = $rs->getString($startcol + 3); + + $this->inp_doc_published = $rs->getString($startcol + 4); + + $this->inp_doc_versioning = $rs->getInt($startcol + 5); + + $this->inp_doc_destination_path = $rs->getString($startcol + 6); + + $this->inp_doc_tags = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = InputDocumentPeer::NUM_COLUMNS - InputDocumentPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating InputDocument object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + InputDocumentPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = InputDocumentPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += InputDocumentPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = InputDocumentPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = InputDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getInpDocUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getInpDocFormNeeded(); + break; + case 3: + return $this->getInpDocOriginal(); + break; + case 4: + return $this->getInpDocPublished(); + break; + case 5: + return $this->getInpDocVersioning(); + break; + case 6: + return $this->getInpDocDestinationPath(); + break; + case 7: + return $this->getInpDocTags(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = InputDocumentPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getInpDocUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getInpDocFormNeeded(), + $keys[3] => $this->getInpDocOriginal(), + $keys[4] => $this->getInpDocPublished(), + $keys[5] => $this->getInpDocVersioning(), + $keys[6] => $this->getInpDocDestinationPath(), + $keys[7] => $this->getInpDocTags(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = InputDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setInpDocUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setInpDocFormNeeded($value); + break; + case 3: + $this->setInpDocOriginal($value); + break; + case 4: + $this->setInpDocPublished($value); + break; + case 5: + $this->setInpDocVersioning($value); + break; + case 6: + $this->setInpDocDestinationPath($value); + break; + case 7: + $this->setInpDocTags($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = InputDocumentPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setInpDocUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setInpDocFormNeeded($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setInpDocOriginal($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setInpDocPublished($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setInpDocVersioning($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setInpDocDestinationPath($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setInpDocTags($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(InputDocumentPeer::DATABASE_NAME); + + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_UID)) $criteria->add(InputDocumentPeer::INP_DOC_UID, $this->inp_doc_uid); + if ($this->isColumnModified(InputDocumentPeer::PRO_UID)) $criteria->add(InputDocumentPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_FORM_NEEDED)) $criteria->add(InputDocumentPeer::INP_DOC_FORM_NEEDED, $this->inp_doc_form_needed); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_ORIGINAL)) $criteria->add(InputDocumentPeer::INP_DOC_ORIGINAL, $this->inp_doc_original); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_PUBLISHED)) $criteria->add(InputDocumentPeer::INP_DOC_PUBLISHED, $this->inp_doc_published); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_VERSIONING)) $criteria->add(InputDocumentPeer::INP_DOC_VERSIONING, $this->inp_doc_versioning); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_DESTINATION_PATH)) $criteria->add(InputDocumentPeer::INP_DOC_DESTINATION_PATH, $this->inp_doc_destination_path); + if ($this->isColumnModified(InputDocumentPeer::INP_DOC_TAGS)) $criteria->add(InputDocumentPeer::INP_DOC_TAGS, $this->inp_doc_tags); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(InputDocumentPeer::DATABASE_NAME); + + $criteria->add(InputDocumentPeer::INP_DOC_UID, $this->inp_doc_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getInpDocUid(); + } + + /** + * Generic method to set the primary key (inp_doc_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setInpDocUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of InputDocument (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setInpDocFormNeeded($this->inp_doc_form_needed); + + $copyObj->setInpDocOriginal($this->inp_doc_original); + + $copyObj->setInpDocPublished($this->inp_doc_published); + + $copyObj->setInpDocVersioning($this->inp_doc_versioning); + + $copyObj->setInpDocDestinationPath($this->inp_doc_destination_path); + + $copyObj->setInpDocTags($this->inp_doc_tags); + + + $copyObj->setNew(true); + + $copyObj->setInpDocUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return InputDocument Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return InputDocumentPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new InputDocumentPeer(); + } + return self::$peer; + } + +} // BaseInputDocument diff --git a/workflow/engine/classes/model/om/BaseInputDocumentPeer.php b/workflow/engine/classes/model/om/BaseInputDocumentPeer.php new file mode 100644 index 000000000..eb24c97df --- /dev/null +++ b/workflow/engine/classes/model/om/BaseInputDocumentPeer.php @@ -0,0 +1,615 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by InputDocumentPeer::getOMClass() +include_once 'classes/model/InputDocument.php'; + +/** + * Base static class for performing query and update operations on the 'INPUT_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseInputDocumentPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'INPUT_DOCUMENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.InputDocument'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the INP_DOC_UID field */ + const INP_DOC_UID = 'INPUT_DOCUMENT.INP_DOC_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'INPUT_DOCUMENT.PRO_UID'; + + /** the column name for the INP_DOC_FORM_NEEDED field */ + const INP_DOC_FORM_NEEDED = 'INPUT_DOCUMENT.INP_DOC_FORM_NEEDED'; + + /** the column name for the INP_DOC_ORIGINAL field */ + const INP_DOC_ORIGINAL = 'INPUT_DOCUMENT.INP_DOC_ORIGINAL'; + + /** the column name for the INP_DOC_PUBLISHED field */ + const INP_DOC_PUBLISHED = 'INPUT_DOCUMENT.INP_DOC_PUBLISHED'; + + /** the column name for the INP_DOC_VERSIONING field */ + const INP_DOC_VERSIONING = 'INPUT_DOCUMENT.INP_DOC_VERSIONING'; + + /** the column name for the INP_DOC_DESTINATION_PATH field */ + const INP_DOC_DESTINATION_PATH = 'INPUT_DOCUMENT.INP_DOC_DESTINATION_PATH'; + + /** the column name for the INP_DOC_TAGS field */ + const INP_DOC_TAGS = 'INPUT_DOCUMENT.INP_DOC_TAGS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('InpDocUid', 'ProUid', 'InpDocFormNeeded', 'InpDocOriginal', 'InpDocPublished', 'InpDocVersioning', 'InpDocDestinationPath', 'InpDocTags', ), + BasePeer::TYPE_COLNAME => array (InputDocumentPeer::INP_DOC_UID, InputDocumentPeer::PRO_UID, InputDocumentPeer::INP_DOC_FORM_NEEDED, InputDocumentPeer::INP_DOC_ORIGINAL, InputDocumentPeer::INP_DOC_PUBLISHED, InputDocumentPeer::INP_DOC_VERSIONING, InputDocumentPeer::INP_DOC_DESTINATION_PATH, InputDocumentPeer::INP_DOC_TAGS, ), + BasePeer::TYPE_FIELDNAME => array ('INP_DOC_UID', 'PRO_UID', 'INP_DOC_FORM_NEEDED', 'INP_DOC_ORIGINAL', 'INP_DOC_PUBLISHED', 'INP_DOC_VERSIONING', 'INP_DOC_DESTINATION_PATH', 'INP_DOC_TAGS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('InpDocUid' => 0, 'ProUid' => 1, 'InpDocFormNeeded' => 2, 'InpDocOriginal' => 3, 'InpDocPublished' => 4, 'InpDocVersioning' => 5, 'InpDocDestinationPath' => 6, 'InpDocTags' => 7, ), + BasePeer::TYPE_COLNAME => array (InputDocumentPeer::INP_DOC_UID => 0, InputDocumentPeer::PRO_UID => 1, InputDocumentPeer::INP_DOC_FORM_NEEDED => 2, InputDocumentPeer::INP_DOC_ORIGINAL => 3, InputDocumentPeer::INP_DOC_PUBLISHED => 4, InputDocumentPeer::INP_DOC_VERSIONING => 5, InputDocumentPeer::INP_DOC_DESTINATION_PATH => 6, InputDocumentPeer::INP_DOC_TAGS => 7, ), + BasePeer::TYPE_FIELDNAME => array ('INP_DOC_UID' => 0, 'PRO_UID' => 1, 'INP_DOC_FORM_NEEDED' => 2, 'INP_DOC_ORIGINAL' => 3, 'INP_DOC_PUBLISHED' => 4, 'INP_DOC_VERSIONING' => 5, 'INP_DOC_DESTINATION_PATH' => 6, 'INP_DOC_TAGS' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/InputDocumentMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.InputDocumentMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = InputDocumentPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. InputDocumentPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(InputDocumentPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_UID); + + $criteria->addSelectColumn(InputDocumentPeer::PRO_UID); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_FORM_NEEDED); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_ORIGINAL); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_PUBLISHED); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_VERSIONING); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_DESTINATION_PATH); + + $criteria->addSelectColumn(InputDocumentPeer::INP_DOC_TAGS); + + } + + const COUNT = 'COUNT(INPUT_DOCUMENT.INP_DOC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT INPUT_DOCUMENT.INP_DOC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(InputDocumentPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(InputDocumentPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = InputDocumentPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return InputDocument + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = InputDocumentPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return InputDocumentPeer::populateObjects(InputDocumentPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + InputDocumentPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = InputDocumentPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return InputDocumentPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a InputDocument or Criteria object. + * + * @param mixed $values Criteria or InputDocument object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from InputDocument object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a InputDocument or Criteria object. + * + * @param mixed $values Criteria or InputDocument object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(InputDocumentPeer::INP_DOC_UID); + $selectCriteria->add(InputDocumentPeer::INP_DOC_UID, $criteria->remove(InputDocumentPeer::INP_DOC_UID), $comparison); + + } else { // $values is InputDocument object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the INPUT_DOCUMENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(InputDocumentPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a InputDocument or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or InputDocument object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(InputDocumentPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof InputDocument) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(InputDocumentPeer::INP_DOC_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given InputDocument object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param InputDocument $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(InputDocument $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(InputDocumentPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(InputDocumentPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(InputDocumentPeer::INP_DOC_UID)) + $columns[InputDocumentPeer::INP_DOC_UID] = $obj->getInpDocUid(); + + if ($obj->isNew() || $obj->isColumnModified(InputDocumentPeer::PRO_UID)) + $columns[InputDocumentPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(InputDocumentPeer::INP_DOC_FORM_NEEDED)) + $columns[InputDocumentPeer::INP_DOC_FORM_NEEDED] = $obj->getInpDocFormNeeded(); + + if ($obj->isNew() || $obj->isColumnModified(InputDocumentPeer::INP_DOC_ORIGINAL)) + $columns[InputDocumentPeer::INP_DOC_ORIGINAL] = $obj->getInpDocOriginal(); + + if ($obj->isNew() || $obj->isColumnModified(InputDocumentPeer::INP_DOC_PUBLISHED)) + $columns[InputDocumentPeer::INP_DOC_PUBLISHED] = $obj->getInpDocPublished(); + + } + + return BasePeer::doValidate(InputDocumentPeer::DATABASE_NAME, InputDocumentPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return InputDocument + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(InputDocumentPeer::DATABASE_NAME); + + $criteria->add(InputDocumentPeer::INP_DOC_UID, $pk); + + + $v = InputDocumentPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(InputDocumentPeer::INP_DOC_UID, $pks, Criteria::IN); + $objs = InputDocumentPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseInputDocumentPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseInputDocumentPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/InputDocumentMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.InputDocumentMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseIsoCountry.php b/workflow/engine/classes/model/om/BaseIsoCountry.php new file mode 100644 index 000000000..259f7be47 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoCountry.php @@ -0,0 +1,610 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/IsoCountryPeer.php'; + +/** + * Base class that represents a row from the 'ISO_COUNTRY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoCountry extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var IsoCountryPeer + */ + protected static $peer; + + + /** + * The value for the ic_uid field. + * @var string + */ + protected $ic_uid = ''; + + + /** + * The value for the ic_name field. + * @var string + */ + protected $ic_name; + + + /** + * The value for the ic_sort_order field. + * @var string + */ + protected $ic_sort_order; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [ic_uid] column value. + * + * @return string + */ + public function getIcUid() + { + + return $this->ic_uid; + } + + /** + * Get the [ic_name] column value. + * + * @return string + */ + public function getIcName() + { + + return $this->ic_name; + } + + /** + * Get the [ic_sort_order] column value. + * + * @return string + */ + public function getIcSortOrder() + { + + return $this->ic_sort_order; + } + + /** + * Set the value of [ic_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIcUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ic_uid !== $v || $v === '') { + $this->ic_uid = $v; + $this->modifiedColumns[] = IsoCountryPeer::IC_UID; + } + + } // setIcUid() + + /** + * Set the value of [ic_name] column. + * + * @param string $v new value + * @return void + */ + public function setIcName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ic_name !== $v) { + $this->ic_name = $v; + $this->modifiedColumns[] = IsoCountryPeer::IC_NAME; + } + + } // setIcName() + + /** + * Set the value of [ic_sort_order] column. + * + * @param string $v new value + * @return void + */ + public function setIcSortOrder($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ic_sort_order !== $v) { + $this->ic_sort_order = $v; + $this->modifiedColumns[] = IsoCountryPeer::IC_SORT_ORDER; + } + + } // setIcSortOrder() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->ic_uid = $rs->getString($startcol + 0); + + $this->ic_name = $rs->getString($startcol + 1); + + $this->ic_sort_order = $rs->getString($startcol + 2); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 3; // 3 = IsoCountryPeer::NUM_COLUMNS - IsoCountryPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating IsoCountry object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoCountryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + IsoCountryPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoCountryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = IsoCountryPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += IsoCountryPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = IsoCountryPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoCountryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getIcUid(); + break; + case 1: + return $this->getIcName(); + break; + case 2: + return $this->getIcSortOrder(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoCountryPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getIcUid(), + $keys[1] => $this->getIcName(), + $keys[2] => $this->getIcSortOrder(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoCountryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setIcUid($value); + break; + case 1: + $this->setIcName($value); + break; + case 2: + $this->setIcSortOrder($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoCountryPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setIcUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setIcName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setIcSortOrder($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(IsoCountryPeer::DATABASE_NAME); + + if ($this->isColumnModified(IsoCountryPeer::IC_UID)) $criteria->add(IsoCountryPeer::IC_UID, $this->ic_uid); + if ($this->isColumnModified(IsoCountryPeer::IC_NAME)) $criteria->add(IsoCountryPeer::IC_NAME, $this->ic_name); + if ($this->isColumnModified(IsoCountryPeer::IC_SORT_ORDER)) $criteria->add(IsoCountryPeer::IC_SORT_ORDER, $this->ic_sort_order); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(IsoCountryPeer::DATABASE_NAME); + + $criteria->add(IsoCountryPeer::IC_UID, $this->ic_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getIcUid(); + } + + /** + * Generic method to set the primary key (ic_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setIcUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of IsoCountry (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setIcName($this->ic_name); + + $copyObj->setIcSortOrder($this->ic_sort_order); + + + $copyObj->setNew(true); + + $copyObj->setIcUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return IsoCountry Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return IsoCountryPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new IsoCountryPeer(); + } + return self::$peer; + } + +} // BaseIsoCountry diff --git a/workflow/engine/classes/model/om/BaseIsoCountryPeer.php b/workflow/engine/classes/model/om/BaseIsoCountryPeer.php new file mode 100644 index 000000000..c12a877a5 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoCountryPeer.php @@ -0,0 +1,575 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by IsoCountryPeer::getOMClass() +include_once 'classes/model/IsoCountry.php'; + +/** + * Base static class for performing query and update operations on the 'ISO_COUNTRY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoCountryPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'ISO_COUNTRY'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.IsoCountry'; + + /** The total number of columns. */ + const NUM_COLUMNS = 3; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the IC_UID field */ + const IC_UID = 'ISO_COUNTRY.IC_UID'; + + /** the column name for the IC_NAME field */ + const IC_NAME = 'ISO_COUNTRY.IC_NAME'; + + /** the column name for the IC_SORT_ORDER field */ + const IC_SORT_ORDER = 'ISO_COUNTRY.IC_SORT_ORDER'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid', 'IcName', 'IcSortOrder', ), + BasePeer::TYPE_COLNAME => array (IsoCountryPeer::IC_UID, IsoCountryPeer::IC_NAME, IsoCountryPeer::IC_SORT_ORDER, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID', 'IC_NAME', 'IC_SORT_ORDER', ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid' => 0, 'IcName' => 1, 'IcSortOrder' => 2, ), + BasePeer::TYPE_COLNAME => array (IsoCountryPeer::IC_UID => 0, IsoCountryPeer::IC_NAME => 1, IsoCountryPeer::IC_SORT_ORDER => 2, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID' => 0, 'IC_NAME' => 1, 'IC_SORT_ORDER' => 2, ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/IsoCountryMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.IsoCountryMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = IsoCountryPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. IsoCountryPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(IsoCountryPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(IsoCountryPeer::IC_UID); + + $criteria->addSelectColumn(IsoCountryPeer::IC_NAME); + + $criteria->addSelectColumn(IsoCountryPeer::IC_SORT_ORDER); + + } + + const COUNT = 'COUNT(ISO_COUNTRY.IC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT ISO_COUNTRY.IC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(IsoCountryPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(IsoCountryPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = IsoCountryPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return IsoCountry + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = IsoCountryPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return IsoCountryPeer::populateObjects(IsoCountryPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + IsoCountryPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = IsoCountryPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return IsoCountryPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a IsoCountry or Criteria object. + * + * @param mixed $values Criteria or IsoCountry object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from IsoCountry object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a IsoCountry or Criteria object. + * + * @param mixed $values Criteria or IsoCountry object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(IsoCountryPeer::IC_UID); + $selectCriteria->add(IsoCountryPeer::IC_UID, $criteria->remove(IsoCountryPeer::IC_UID), $comparison); + + } else { // $values is IsoCountry object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the ISO_COUNTRY table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(IsoCountryPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a IsoCountry or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or IsoCountry object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(IsoCountryPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof IsoCountry) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(IsoCountryPeer::IC_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given IsoCountry object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param IsoCountry $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(IsoCountry $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(IsoCountryPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(IsoCountryPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(IsoCountryPeer::DATABASE_NAME, IsoCountryPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return IsoCountry + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(IsoCountryPeer::DATABASE_NAME); + + $criteria->add(IsoCountryPeer::IC_UID, $pk); + + + $v = IsoCountryPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(IsoCountryPeer::IC_UID, $pks, Criteria::IN); + $objs = IsoCountryPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseIsoCountryPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseIsoCountryPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/IsoCountryMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.IsoCountryMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseIsoLocation.php b/workflow/engine/classes/model/om/BaseIsoLocation.php new file mode 100644 index 000000000..4834df144 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoLocation.php @@ -0,0 +1,728 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/IsoLocationPeer.php'; + +/** + * Base class that represents a row from the 'ISO_LOCATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoLocation extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var IsoLocationPeer + */ + protected static $peer; + + + /** + * The value for the ic_uid field. + * @var string + */ + protected $ic_uid = ''; + + + /** + * The value for the il_uid field. + * @var string + */ + protected $il_uid = ''; + + + /** + * The value for the il_name field. + * @var string + */ + protected $il_name; + + + /** + * The value for the il_normal_name field. + * @var string + */ + protected $il_normal_name; + + + /** + * The value for the is_uid field. + * @var string + */ + protected $is_uid; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [ic_uid] column value. + * + * @return string + */ + public function getIcUid() + { + + return $this->ic_uid; + } + + /** + * Get the [il_uid] column value. + * + * @return string + */ + public function getIlUid() + { + + return $this->il_uid; + } + + /** + * Get the [il_name] column value. + * + * @return string + */ + public function getIlName() + { + + return $this->il_name; + } + + /** + * Get the [il_normal_name] column value. + * + * @return string + */ + public function getIlNormalName() + { + + return $this->il_normal_name; + } + + /** + * Get the [is_uid] column value. + * + * @return string + */ + public function getIsUid() + { + + return $this->is_uid; + } + + /** + * Set the value of [ic_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIcUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ic_uid !== $v || $v === '') { + $this->ic_uid = $v; + $this->modifiedColumns[] = IsoLocationPeer::IC_UID; + } + + } // setIcUid() + + /** + * Set the value of [il_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIlUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->il_uid !== $v || $v === '') { + $this->il_uid = $v; + $this->modifiedColumns[] = IsoLocationPeer::IL_UID; + } + + } // setIlUid() + + /** + * Set the value of [il_name] column. + * + * @param string $v new value + * @return void + */ + public function setIlName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->il_name !== $v) { + $this->il_name = $v; + $this->modifiedColumns[] = IsoLocationPeer::IL_NAME; + } + + } // setIlName() + + /** + * Set the value of [il_normal_name] column. + * + * @param string $v new value + * @return void + */ + public function setIlNormalName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->il_normal_name !== $v) { + $this->il_normal_name = $v; + $this->modifiedColumns[] = IsoLocationPeer::IL_NORMAL_NAME; + } + + } // setIlNormalName() + + /** + * Set the value of [is_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIsUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->is_uid !== $v) { + $this->is_uid = $v; + $this->modifiedColumns[] = IsoLocationPeer::IS_UID; + } + + } // setIsUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->ic_uid = $rs->getString($startcol + 0); + + $this->il_uid = $rs->getString($startcol + 1); + + $this->il_name = $rs->getString($startcol + 2); + + $this->il_normal_name = $rs->getString($startcol + 3); + + $this->is_uid = $rs->getString($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = IsoLocationPeer::NUM_COLUMNS - IsoLocationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating IsoLocation object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoLocationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + IsoLocationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoLocationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = IsoLocationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += IsoLocationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = IsoLocationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoLocationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getIcUid(); + break; + case 1: + return $this->getIlUid(); + break; + case 2: + return $this->getIlName(); + break; + case 3: + return $this->getIlNormalName(); + break; + case 4: + return $this->getIsUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoLocationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getIcUid(), + $keys[1] => $this->getIlUid(), + $keys[2] => $this->getIlName(), + $keys[3] => $this->getIlNormalName(), + $keys[4] => $this->getIsUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoLocationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setIcUid($value); + break; + case 1: + $this->setIlUid($value); + break; + case 2: + $this->setIlName($value); + break; + case 3: + $this->setIlNormalName($value); + break; + case 4: + $this->setIsUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoLocationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setIcUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setIlUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setIlName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setIlNormalName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setIsUid($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(IsoLocationPeer::DATABASE_NAME); + + if ($this->isColumnModified(IsoLocationPeer::IC_UID)) $criteria->add(IsoLocationPeer::IC_UID, $this->ic_uid); + if ($this->isColumnModified(IsoLocationPeer::IL_UID)) $criteria->add(IsoLocationPeer::IL_UID, $this->il_uid); + if ($this->isColumnModified(IsoLocationPeer::IL_NAME)) $criteria->add(IsoLocationPeer::IL_NAME, $this->il_name); + if ($this->isColumnModified(IsoLocationPeer::IL_NORMAL_NAME)) $criteria->add(IsoLocationPeer::IL_NORMAL_NAME, $this->il_normal_name); + if ($this->isColumnModified(IsoLocationPeer::IS_UID)) $criteria->add(IsoLocationPeer::IS_UID, $this->is_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(IsoLocationPeer::DATABASE_NAME); + + $criteria->add(IsoLocationPeer::IC_UID, $this->ic_uid); + $criteria->add(IsoLocationPeer::IL_UID, $this->il_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getIcUid(); + + $pks[1] = $this->getIlUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setIcUid($keys[0]); + + $this->setIlUid($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of IsoLocation (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setIlName($this->il_name); + + $copyObj->setIlNormalName($this->il_normal_name); + + $copyObj->setIsUid($this->is_uid); + + + $copyObj->setNew(true); + + $copyObj->setIcUid(''); // this is a pkey column, so set to default value + + $copyObj->setIlUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return IsoLocation Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return IsoLocationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new IsoLocationPeer(); + } + return self::$peer; + } + +} // BaseIsoLocation diff --git a/workflow/engine/classes/model/om/BaseIsoLocationPeer.php b/workflow/engine/classes/model/om/BaseIsoLocationPeer.php new file mode 100644 index 000000000..c51e5926e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoLocationPeer.php @@ -0,0 +1,576 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by IsoLocationPeer::getOMClass() +include_once 'classes/model/IsoLocation.php'; + +/** + * Base static class for performing query and update operations on the 'ISO_LOCATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoLocationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'ISO_LOCATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.IsoLocation'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the IC_UID field */ + const IC_UID = 'ISO_LOCATION.IC_UID'; + + /** the column name for the IL_UID field */ + const IL_UID = 'ISO_LOCATION.IL_UID'; + + /** the column name for the IL_NAME field */ + const IL_NAME = 'ISO_LOCATION.IL_NAME'; + + /** the column name for the IL_NORMAL_NAME field */ + const IL_NORMAL_NAME = 'ISO_LOCATION.IL_NORMAL_NAME'; + + /** the column name for the IS_UID field */ + const IS_UID = 'ISO_LOCATION.IS_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid', 'IlUid', 'IlName', 'IlNormalName', 'IsUid', ), + BasePeer::TYPE_COLNAME => array (IsoLocationPeer::IC_UID, IsoLocationPeer::IL_UID, IsoLocationPeer::IL_NAME, IsoLocationPeer::IL_NORMAL_NAME, IsoLocationPeer::IS_UID, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID', 'IL_UID', 'IL_NAME', 'IL_NORMAL_NAME', 'IS_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid' => 0, 'IlUid' => 1, 'IlName' => 2, 'IlNormalName' => 3, 'IsUid' => 4, ), + BasePeer::TYPE_COLNAME => array (IsoLocationPeer::IC_UID => 0, IsoLocationPeer::IL_UID => 1, IsoLocationPeer::IL_NAME => 2, IsoLocationPeer::IL_NORMAL_NAME => 3, IsoLocationPeer::IS_UID => 4, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID' => 0, 'IL_UID' => 1, 'IL_NAME' => 2, 'IL_NORMAL_NAME' => 3, 'IS_UID' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/IsoLocationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.IsoLocationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = IsoLocationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. IsoLocationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(IsoLocationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(IsoLocationPeer::IC_UID); + + $criteria->addSelectColumn(IsoLocationPeer::IL_UID); + + $criteria->addSelectColumn(IsoLocationPeer::IL_NAME); + + $criteria->addSelectColumn(IsoLocationPeer::IL_NORMAL_NAME); + + $criteria->addSelectColumn(IsoLocationPeer::IS_UID); + + } + + const COUNT = 'COUNT(ISO_LOCATION.IC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT ISO_LOCATION.IC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(IsoLocationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(IsoLocationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = IsoLocationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return IsoLocation + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = IsoLocationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return IsoLocationPeer::populateObjects(IsoLocationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + IsoLocationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = IsoLocationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return IsoLocationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a IsoLocation or Criteria object. + * + * @param mixed $values Criteria or IsoLocation object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from IsoLocation object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a IsoLocation or Criteria object. + * + * @param mixed $values Criteria or IsoLocation object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(IsoLocationPeer::IC_UID); + $selectCriteria->add(IsoLocationPeer::IC_UID, $criteria->remove(IsoLocationPeer::IC_UID), $comparison); + + $comparison = $criteria->getComparison(IsoLocationPeer::IL_UID); + $selectCriteria->add(IsoLocationPeer::IL_UID, $criteria->remove(IsoLocationPeer::IL_UID), $comparison); + + } else { // $values is IsoLocation object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the ISO_LOCATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(IsoLocationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a IsoLocation or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or IsoLocation object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(IsoLocationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof IsoLocation) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(IsoLocationPeer::IC_UID, $vals[0], Criteria::IN); + $criteria->add(IsoLocationPeer::IL_UID, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given IsoLocation object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param IsoLocation $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(IsoLocation $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(IsoLocationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(IsoLocationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(IsoLocationPeer::DATABASE_NAME, IsoLocationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $ic_uid + @param string $il_uid + + * @param Connection $con + * @return IsoLocation + */ + public static function retrieveByPK( $ic_uid, $il_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(IsoLocationPeer::IC_UID, $ic_uid); + $criteria->add(IsoLocationPeer::IL_UID, $il_uid); + $v = IsoLocationPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseIsoLocationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseIsoLocationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/IsoLocationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.IsoLocationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseIsoSubdivision.php b/workflow/engine/classes/model/om/BaseIsoSubdivision.php new file mode 100644 index 000000000..0a7a7ae7c --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoSubdivision.php @@ -0,0 +1,622 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/IsoSubdivisionPeer.php'; + +/** + * Base class that represents a row from the 'ISO_SUBDIVISION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoSubdivision extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var IsoSubdivisionPeer + */ + protected static $peer; + + + /** + * The value for the ic_uid field. + * @var string + */ + protected $ic_uid = ''; + + + /** + * The value for the is_uid field. + * @var string + */ + protected $is_uid = ''; + + + /** + * The value for the is_name field. + * @var string + */ + protected $is_name = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [ic_uid] column value. + * + * @return string + */ + public function getIcUid() + { + + return $this->ic_uid; + } + + /** + * Get the [is_uid] column value. + * + * @return string + */ + public function getIsUid() + { + + return $this->is_uid; + } + + /** + * Get the [is_name] column value. + * + * @return string + */ + public function getIsName() + { + + return $this->is_name; + } + + /** + * Set the value of [ic_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIcUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ic_uid !== $v || $v === '') { + $this->ic_uid = $v; + $this->modifiedColumns[] = IsoSubdivisionPeer::IC_UID; + } + + } // setIcUid() + + /** + * Set the value of [is_uid] column. + * + * @param string $v new value + * @return void + */ + public function setIsUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->is_uid !== $v || $v === '') { + $this->is_uid = $v; + $this->modifiedColumns[] = IsoSubdivisionPeer::IS_UID; + } + + } // setIsUid() + + /** + * Set the value of [is_name] column. + * + * @param string $v new value + * @return void + */ + public function setIsName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->is_name !== $v || $v === '') { + $this->is_name = $v; + $this->modifiedColumns[] = IsoSubdivisionPeer::IS_NAME; + } + + } // setIsName() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->ic_uid = $rs->getString($startcol + 0); + + $this->is_uid = $rs->getString($startcol + 1); + + $this->is_name = $rs->getString($startcol + 2); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 3; // 3 = IsoSubdivisionPeer::NUM_COLUMNS - IsoSubdivisionPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating IsoSubdivision object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoSubdivisionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + IsoSubdivisionPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(IsoSubdivisionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = IsoSubdivisionPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += IsoSubdivisionPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = IsoSubdivisionPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoSubdivisionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getIcUid(); + break; + case 1: + return $this->getIsUid(); + break; + case 2: + return $this->getIsName(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoSubdivisionPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getIcUid(), + $keys[1] => $this->getIsUid(), + $keys[2] => $this->getIsName(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = IsoSubdivisionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setIcUid($value); + break; + case 1: + $this->setIsUid($value); + break; + case 2: + $this->setIsName($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = IsoSubdivisionPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setIcUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setIsUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setIsName($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(IsoSubdivisionPeer::DATABASE_NAME); + + if ($this->isColumnModified(IsoSubdivisionPeer::IC_UID)) $criteria->add(IsoSubdivisionPeer::IC_UID, $this->ic_uid); + if ($this->isColumnModified(IsoSubdivisionPeer::IS_UID)) $criteria->add(IsoSubdivisionPeer::IS_UID, $this->is_uid); + if ($this->isColumnModified(IsoSubdivisionPeer::IS_NAME)) $criteria->add(IsoSubdivisionPeer::IS_NAME, $this->is_name); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(IsoSubdivisionPeer::DATABASE_NAME); + + $criteria->add(IsoSubdivisionPeer::IC_UID, $this->ic_uid); + $criteria->add(IsoSubdivisionPeer::IS_UID, $this->is_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getIcUid(); + + $pks[1] = $this->getIsUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setIcUid($keys[0]); + + $this->setIsUid($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of IsoSubdivision (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setIsName($this->is_name); + + + $copyObj->setNew(true); + + $copyObj->setIcUid(''); // this is a pkey column, so set to default value + + $copyObj->setIsUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return IsoSubdivision Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return IsoSubdivisionPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new IsoSubdivisionPeer(); + } + return self::$peer; + } + +} // BaseIsoSubdivision diff --git a/workflow/engine/classes/model/om/BaseIsoSubdivisionPeer.php b/workflow/engine/classes/model/om/BaseIsoSubdivisionPeer.php new file mode 100644 index 000000000..7ba31229f --- /dev/null +++ b/workflow/engine/classes/model/om/BaseIsoSubdivisionPeer.php @@ -0,0 +1,566 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by IsoSubdivisionPeer::getOMClass() +include_once 'classes/model/IsoSubdivision.php'; + +/** + * Base static class for performing query and update operations on the 'ISO_SUBDIVISION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseIsoSubdivisionPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'ISO_SUBDIVISION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.IsoSubdivision'; + + /** The total number of columns. */ + const NUM_COLUMNS = 3; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the IC_UID field */ + const IC_UID = 'ISO_SUBDIVISION.IC_UID'; + + /** the column name for the IS_UID field */ + const IS_UID = 'ISO_SUBDIVISION.IS_UID'; + + /** the column name for the IS_NAME field */ + const IS_NAME = 'ISO_SUBDIVISION.IS_NAME'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid', 'IsUid', 'IsName', ), + BasePeer::TYPE_COLNAME => array (IsoSubdivisionPeer::IC_UID, IsoSubdivisionPeer::IS_UID, IsoSubdivisionPeer::IS_NAME, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID', 'IS_UID', 'IS_NAME', ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('IcUid' => 0, 'IsUid' => 1, 'IsName' => 2, ), + BasePeer::TYPE_COLNAME => array (IsoSubdivisionPeer::IC_UID => 0, IsoSubdivisionPeer::IS_UID => 1, IsoSubdivisionPeer::IS_NAME => 2, ), + BasePeer::TYPE_FIELDNAME => array ('IC_UID' => 0, 'IS_UID' => 1, 'IS_NAME' => 2, ), + BasePeer::TYPE_NUM => array (0, 1, 2, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/IsoSubdivisionMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.IsoSubdivisionMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = IsoSubdivisionPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. IsoSubdivisionPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(IsoSubdivisionPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(IsoSubdivisionPeer::IC_UID); + + $criteria->addSelectColumn(IsoSubdivisionPeer::IS_UID); + + $criteria->addSelectColumn(IsoSubdivisionPeer::IS_NAME); + + } + + const COUNT = 'COUNT(ISO_SUBDIVISION.IC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT ISO_SUBDIVISION.IC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(IsoSubdivisionPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(IsoSubdivisionPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = IsoSubdivisionPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return IsoSubdivision + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = IsoSubdivisionPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return IsoSubdivisionPeer::populateObjects(IsoSubdivisionPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + IsoSubdivisionPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = IsoSubdivisionPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return IsoSubdivisionPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a IsoSubdivision or Criteria object. + * + * @param mixed $values Criteria or IsoSubdivision object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from IsoSubdivision object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a IsoSubdivision or Criteria object. + * + * @param mixed $values Criteria or IsoSubdivision object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(IsoSubdivisionPeer::IC_UID); + $selectCriteria->add(IsoSubdivisionPeer::IC_UID, $criteria->remove(IsoSubdivisionPeer::IC_UID), $comparison); + + $comparison = $criteria->getComparison(IsoSubdivisionPeer::IS_UID); + $selectCriteria->add(IsoSubdivisionPeer::IS_UID, $criteria->remove(IsoSubdivisionPeer::IS_UID), $comparison); + + } else { // $values is IsoSubdivision object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the ISO_SUBDIVISION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(IsoSubdivisionPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a IsoSubdivision or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or IsoSubdivision object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(IsoSubdivisionPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof IsoSubdivision) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(IsoSubdivisionPeer::IC_UID, $vals[0], Criteria::IN); + $criteria->add(IsoSubdivisionPeer::IS_UID, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given IsoSubdivision object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param IsoSubdivision $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(IsoSubdivision $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(IsoSubdivisionPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(IsoSubdivisionPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(IsoSubdivisionPeer::DATABASE_NAME, IsoSubdivisionPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $ic_uid + @param string $is_uid + + * @param Connection $con + * @return IsoSubdivision + */ + public static function retrieveByPK( $ic_uid, $is_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(IsoSubdivisionPeer::IC_UID, $ic_uid); + $criteria->add(IsoSubdivisionPeer::IS_UID, $is_uid); + $v = IsoSubdivisionPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseIsoSubdivisionPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseIsoSubdivisionPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/IsoSubdivisionMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.IsoSubdivisionMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseLanguage.php b/workflow/engine/classes/model/om/BaseLanguage.php new file mode 100644 index 000000000..02d569a03 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLanguage.php @@ -0,0 +1,822 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/LanguagePeer.php'; + +/** + * Base class that represents a row from the 'LANGUAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLanguage extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var LanguagePeer + */ + protected static $peer; + + + /** + * The value for the lan_id field. + * @var string + */ + protected $lan_id = ''; + + + /** + * The value for the lan_name field. + * @var string + */ + protected $lan_name = ''; + + + /** + * The value for the lan_native_name field. + * @var string + */ + protected $lan_native_name = ''; + + + /** + * The value for the lan_direction field. + * @var string + */ + protected $lan_direction = 'L'; + + + /** + * The value for the lan_weight field. + * @var int + */ + protected $lan_weight = 0; + + + /** + * The value for the lan_enabled field. + * @var string + */ + protected $lan_enabled = '1'; + + + /** + * The value for the lan_calendar field. + * @var string + */ + protected $lan_calendar = 'GREGORIAN'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [lan_id] column value. + * + * @return string + */ + public function getLanId() + { + + return $this->lan_id; + } + + /** + * Get the [lan_name] column value. + * + * @return string + */ + public function getLanName() + { + + return $this->lan_name; + } + + /** + * Get the [lan_native_name] column value. + * + * @return string + */ + public function getLanNativeName() + { + + return $this->lan_native_name; + } + + /** + * Get the [lan_direction] column value. + * + * @return string + */ + public function getLanDirection() + { + + return $this->lan_direction; + } + + /** + * Get the [lan_weight] column value. + * + * @return int + */ + public function getLanWeight() + { + + return $this->lan_weight; + } + + /** + * Get the [lan_enabled] column value. + * + * @return string + */ + public function getLanEnabled() + { + + return $this->lan_enabled; + } + + /** + * Get the [lan_calendar] column value. + * + * @return string + */ + public function getLanCalendar() + { + + return $this->lan_calendar; + } + + /** + * Set the value of [lan_id] column. + * + * @param string $v new value + * @return void + */ + public function setLanId($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_id !== $v || $v === '') { + $this->lan_id = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_ID; + } + + } // setLanId() + + /** + * Set the value of [lan_name] column. + * + * @param string $v new value + * @return void + */ + public function setLanName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_name !== $v || $v === '') { + $this->lan_name = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_NAME; + } + + } // setLanName() + + /** + * Set the value of [lan_native_name] column. + * + * @param string $v new value + * @return void + */ + public function setLanNativeName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_native_name !== $v || $v === '') { + $this->lan_native_name = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_NATIVE_NAME; + } + + } // setLanNativeName() + + /** + * Set the value of [lan_direction] column. + * + * @param string $v new value + * @return void + */ + public function setLanDirection($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_direction !== $v || $v === 'L') { + $this->lan_direction = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_DIRECTION; + } + + } // setLanDirection() + + /** + * Set the value of [lan_weight] column. + * + * @param int $v new value + * @return void + */ + public function setLanWeight($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->lan_weight !== $v || $v === 0) { + $this->lan_weight = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_WEIGHT; + } + + } // setLanWeight() + + /** + * Set the value of [lan_enabled] column. + * + * @param string $v new value + * @return void + */ + public function setLanEnabled($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_enabled !== $v || $v === '1') { + $this->lan_enabled = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_ENABLED; + } + + } // setLanEnabled() + + /** + * Set the value of [lan_calendar] column. + * + * @param string $v new value + * @return void + */ + public function setLanCalendar($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lan_calendar !== $v || $v === 'GREGORIAN') { + $this->lan_calendar = $v; + $this->modifiedColumns[] = LanguagePeer::LAN_CALENDAR; + } + + } // setLanCalendar() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->lan_id = $rs->getString($startcol + 0); + + $this->lan_name = $rs->getString($startcol + 1); + + $this->lan_native_name = $rs->getString($startcol + 2); + + $this->lan_direction = $rs->getString($startcol + 3); + + $this->lan_weight = $rs->getInt($startcol + 4); + + $this->lan_enabled = $rs->getString($startcol + 5); + + $this->lan_calendar = $rs->getString($startcol + 6); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = LanguagePeer::NUM_COLUMNS - LanguagePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Language object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LanguagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + LanguagePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LanguagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = LanguagePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += LanguagePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = LanguagePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LanguagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getLanId(); + break; + case 1: + return $this->getLanName(); + break; + case 2: + return $this->getLanNativeName(); + break; + case 3: + return $this->getLanDirection(); + break; + case 4: + return $this->getLanWeight(); + break; + case 5: + return $this->getLanEnabled(); + break; + case 6: + return $this->getLanCalendar(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LanguagePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getLanId(), + $keys[1] => $this->getLanName(), + $keys[2] => $this->getLanNativeName(), + $keys[3] => $this->getLanDirection(), + $keys[4] => $this->getLanWeight(), + $keys[5] => $this->getLanEnabled(), + $keys[6] => $this->getLanCalendar(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LanguagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setLanId($value); + break; + case 1: + $this->setLanName($value); + break; + case 2: + $this->setLanNativeName($value); + break; + case 3: + $this->setLanDirection($value); + break; + case 4: + $this->setLanWeight($value); + break; + case 5: + $this->setLanEnabled($value); + break; + case 6: + $this->setLanCalendar($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LanguagePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setLanId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setLanName($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setLanNativeName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setLanDirection($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setLanWeight($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setLanEnabled($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setLanCalendar($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(LanguagePeer::DATABASE_NAME); + + if ($this->isColumnModified(LanguagePeer::LAN_ID)) $criteria->add(LanguagePeer::LAN_ID, $this->lan_id); + if ($this->isColumnModified(LanguagePeer::LAN_NAME)) $criteria->add(LanguagePeer::LAN_NAME, $this->lan_name); + if ($this->isColumnModified(LanguagePeer::LAN_NATIVE_NAME)) $criteria->add(LanguagePeer::LAN_NATIVE_NAME, $this->lan_native_name); + if ($this->isColumnModified(LanguagePeer::LAN_DIRECTION)) $criteria->add(LanguagePeer::LAN_DIRECTION, $this->lan_direction); + if ($this->isColumnModified(LanguagePeer::LAN_WEIGHT)) $criteria->add(LanguagePeer::LAN_WEIGHT, $this->lan_weight); + if ($this->isColumnModified(LanguagePeer::LAN_ENABLED)) $criteria->add(LanguagePeer::LAN_ENABLED, $this->lan_enabled); + if ($this->isColumnModified(LanguagePeer::LAN_CALENDAR)) $criteria->add(LanguagePeer::LAN_CALENDAR, $this->lan_calendar); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(LanguagePeer::DATABASE_NAME); + + $criteria->add(LanguagePeer::LAN_ID, $this->lan_id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getLanId(); + } + + /** + * Generic method to set the primary key (lan_id column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setLanId($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Language (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setLanName($this->lan_name); + + $copyObj->setLanNativeName($this->lan_native_name); + + $copyObj->setLanDirection($this->lan_direction); + + $copyObj->setLanWeight($this->lan_weight); + + $copyObj->setLanEnabled($this->lan_enabled); + + $copyObj->setLanCalendar($this->lan_calendar); + + + $copyObj->setNew(true); + + $copyObj->setLanId(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Language Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return LanguagePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new LanguagePeer(); + } + return self::$peer; + } + +} // BaseLanguage diff --git a/workflow/engine/classes/model/om/BaseLanguagePeer.php b/workflow/engine/classes/model/om/BaseLanguagePeer.php new file mode 100644 index 000000000..be40029eb --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLanguagePeer.php @@ -0,0 +1,601 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by LanguagePeer::getOMClass() +include_once 'classes/model/Language.php'; + +/** + * Base static class for performing query and update operations on the 'LANGUAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLanguagePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'LANGUAGE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Language'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the LAN_ID field */ + const LAN_ID = 'LANGUAGE.LAN_ID'; + + /** the column name for the LAN_NAME field */ + const LAN_NAME = 'LANGUAGE.LAN_NAME'; + + /** the column name for the LAN_NATIVE_NAME field */ + const LAN_NATIVE_NAME = 'LANGUAGE.LAN_NATIVE_NAME'; + + /** the column name for the LAN_DIRECTION field */ + const LAN_DIRECTION = 'LANGUAGE.LAN_DIRECTION'; + + /** the column name for the LAN_WEIGHT field */ + const LAN_WEIGHT = 'LANGUAGE.LAN_WEIGHT'; + + /** the column name for the LAN_ENABLED field */ + const LAN_ENABLED = 'LANGUAGE.LAN_ENABLED'; + + /** the column name for the LAN_CALENDAR field */ + const LAN_CALENDAR = 'LANGUAGE.LAN_CALENDAR'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('LanId', 'LanName', 'LanNativeName', 'LanDirection', 'LanWeight', 'LanEnabled', 'LanCalendar', ), + BasePeer::TYPE_COLNAME => array (LanguagePeer::LAN_ID, LanguagePeer::LAN_NAME, LanguagePeer::LAN_NATIVE_NAME, LanguagePeer::LAN_DIRECTION, LanguagePeer::LAN_WEIGHT, LanguagePeer::LAN_ENABLED, LanguagePeer::LAN_CALENDAR, ), + BasePeer::TYPE_FIELDNAME => array ('LAN_ID', 'LAN_NAME', 'LAN_NATIVE_NAME', 'LAN_DIRECTION', 'LAN_WEIGHT', 'LAN_ENABLED', 'LAN_CALENDAR', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('LanId' => 0, 'LanName' => 1, 'LanNativeName' => 2, 'LanDirection' => 3, 'LanWeight' => 4, 'LanEnabled' => 5, 'LanCalendar' => 6, ), + BasePeer::TYPE_COLNAME => array (LanguagePeer::LAN_ID => 0, LanguagePeer::LAN_NAME => 1, LanguagePeer::LAN_NATIVE_NAME => 2, LanguagePeer::LAN_DIRECTION => 3, LanguagePeer::LAN_WEIGHT => 4, LanguagePeer::LAN_ENABLED => 5, LanguagePeer::LAN_CALENDAR => 6, ), + BasePeer::TYPE_FIELDNAME => array ('LAN_ID' => 0, 'LAN_NAME' => 1, 'LAN_NATIVE_NAME' => 2, 'LAN_DIRECTION' => 3, 'LAN_WEIGHT' => 4, 'LAN_ENABLED' => 5, 'LAN_CALENDAR' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/LanguageMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.LanguageMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = LanguagePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. LanguagePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(LanguagePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(LanguagePeer::LAN_ID); + + $criteria->addSelectColumn(LanguagePeer::LAN_NAME); + + $criteria->addSelectColumn(LanguagePeer::LAN_NATIVE_NAME); + + $criteria->addSelectColumn(LanguagePeer::LAN_DIRECTION); + + $criteria->addSelectColumn(LanguagePeer::LAN_WEIGHT); + + $criteria->addSelectColumn(LanguagePeer::LAN_ENABLED); + + $criteria->addSelectColumn(LanguagePeer::LAN_CALENDAR); + + } + + const COUNT = 'COUNT(LANGUAGE.LAN_ID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT LANGUAGE.LAN_ID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(LanguagePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(LanguagePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = LanguagePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Language + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = LanguagePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return LanguagePeer::populateObjects(LanguagePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + LanguagePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = LanguagePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return LanguagePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Language or Criteria object. + * + * @param mixed $values Criteria or Language object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Language object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Language or Criteria object. + * + * @param mixed $values Criteria or Language object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(LanguagePeer::LAN_ID); + $selectCriteria->add(LanguagePeer::LAN_ID, $criteria->remove(LanguagePeer::LAN_ID), $comparison); + + } else { // $values is Language object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the LANGUAGE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(LanguagePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Language or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Language object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(LanguagePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Language) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(LanguagePeer::LAN_ID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Language object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Language $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Language $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(LanguagePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(LanguagePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(LanguagePeer::LAN_DIRECTION)) + $columns[LanguagePeer::LAN_DIRECTION] = $obj->getLanDirection(); + + if ($obj->isNew() || $obj->isColumnModified(LanguagePeer::LAN_ENABLED)) + $columns[LanguagePeer::LAN_ENABLED] = $obj->getLanEnabled(); + + } + + return BasePeer::doValidate(LanguagePeer::DATABASE_NAME, LanguagePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Language + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(LanguagePeer::DATABASE_NAME); + + $criteria->add(LanguagePeer::LAN_ID, $pk); + + + $v = LanguagePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(LanguagePeer::LAN_ID, $pks, Criteria::IN); + $objs = LanguagePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseLanguagePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseLanguagePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/LanguageMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.LanguageMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseLexico.php b/workflow/engine/classes/model/om/BaseLexico.php new file mode 100644 index 000000000..38b97c6ec --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLexico.php @@ -0,0 +1,675 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/LexicoPeer.php'; + +/** + * Base class that represents a row from the 'LEXICO' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLexico extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var LexicoPeer + */ + protected static $peer; + + + /** + * The value for the lex_topic field. + * @var string + */ + protected $lex_topic = ''; + + + /** + * The value for the lex_key field. + * @var string + */ + protected $lex_key = ''; + + + /** + * The value for the lex_value field. + * @var string + */ + protected $lex_value = ''; + + + /** + * The value for the lex_caption field. + * @var string + */ + protected $lex_caption = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [lex_topic] column value. + * + * @return string + */ + public function getLexTopic() + { + + return $this->lex_topic; + } + + /** + * Get the [lex_key] column value. + * + * @return string + */ + public function getLexKey() + { + + return $this->lex_key; + } + + /** + * Get the [lex_value] column value. + * + * @return string + */ + public function getLexValue() + { + + return $this->lex_value; + } + + /** + * Get the [lex_caption] column value. + * + * @return string + */ + public function getLexCaption() + { + + return $this->lex_caption; + } + + /** + * Set the value of [lex_topic] column. + * + * @param string $v new value + * @return void + */ + public function setLexTopic($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lex_topic !== $v || $v === '') { + $this->lex_topic = $v; + $this->modifiedColumns[] = LexicoPeer::LEX_TOPIC; + } + + } // setLexTopic() + + /** + * Set the value of [lex_key] column. + * + * @param string $v new value + * @return void + */ + public function setLexKey($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lex_key !== $v || $v === '') { + $this->lex_key = $v; + $this->modifiedColumns[] = LexicoPeer::LEX_KEY; + } + + } // setLexKey() + + /** + * Set the value of [lex_value] column. + * + * @param string $v new value + * @return void + */ + public function setLexValue($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lex_value !== $v || $v === '') { + $this->lex_value = $v; + $this->modifiedColumns[] = LexicoPeer::LEX_VALUE; + } + + } // setLexValue() + + /** + * Set the value of [lex_caption] column. + * + * @param string $v new value + * @return void + */ + public function setLexCaption($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->lex_caption !== $v || $v === '') { + $this->lex_caption = $v; + $this->modifiedColumns[] = LexicoPeer::LEX_CAPTION; + } + + } // setLexCaption() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->lex_topic = $rs->getString($startcol + 0); + + $this->lex_key = $rs->getString($startcol + 1); + + $this->lex_value = $rs->getString($startcol + 2); + + $this->lex_caption = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = LexicoPeer::NUM_COLUMNS - LexicoPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Lexico object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LexicoPeer::DATABASE_NAME); + } + + try { + $con->begin(); + LexicoPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LexicoPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = LexicoPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += LexicoPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = LexicoPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LexicoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getLexTopic(); + break; + case 1: + return $this->getLexKey(); + break; + case 2: + return $this->getLexValue(); + break; + case 3: + return $this->getLexCaption(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LexicoPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getLexTopic(), + $keys[1] => $this->getLexKey(), + $keys[2] => $this->getLexValue(), + $keys[3] => $this->getLexCaption(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LexicoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setLexTopic($value); + break; + case 1: + $this->setLexKey($value); + break; + case 2: + $this->setLexValue($value); + break; + case 3: + $this->setLexCaption($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LexicoPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setLexTopic($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setLexKey($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setLexValue($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setLexCaption($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(LexicoPeer::DATABASE_NAME); + + if ($this->isColumnModified(LexicoPeer::LEX_TOPIC)) $criteria->add(LexicoPeer::LEX_TOPIC, $this->lex_topic); + if ($this->isColumnModified(LexicoPeer::LEX_KEY)) $criteria->add(LexicoPeer::LEX_KEY, $this->lex_key); + if ($this->isColumnModified(LexicoPeer::LEX_VALUE)) $criteria->add(LexicoPeer::LEX_VALUE, $this->lex_value); + if ($this->isColumnModified(LexicoPeer::LEX_CAPTION)) $criteria->add(LexicoPeer::LEX_CAPTION, $this->lex_caption); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(LexicoPeer::DATABASE_NAME); + + $criteria->add(LexicoPeer::LEX_TOPIC, $this->lex_topic); + $criteria->add(LexicoPeer::LEX_KEY, $this->lex_key); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getLexTopic(); + + $pks[1] = $this->getLexKey(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setLexTopic($keys[0]); + + $this->setLexKey($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Lexico (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setLexValue($this->lex_value); + + $copyObj->setLexCaption($this->lex_caption); + + + $copyObj->setNew(true); + + $copyObj->setLexTopic(''); // this is a pkey column, so set to default value + + $copyObj->setLexKey(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Lexico Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return LexicoPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new LexicoPeer(); + } + return self::$peer; + } + +} // BaseLexico diff --git a/workflow/engine/classes/model/om/BaseLexicoPeer.php b/workflow/engine/classes/model/om/BaseLexicoPeer.php new file mode 100644 index 000000000..4c8e1de45 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLexicoPeer.php @@ -0,0 +1,571 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by LexicoPeer::getOMClass() +include_once 'classes/model/Lexico.php'; + +/** + * Base static class for performing query and update operations on the 'LEXICO' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLexicoPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'LEXICO'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Lexico'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the LEX_TOPIC field */ + const LEX_TOPIC = 'LEXICO.LEX_TOPIC'; + + /** the column name for the LEX_KEY field */ + const LEX_KEY = 'LEXICO.LEX_KEY'; + + /** the column name for the LEX_VALUE field */ + const LEX_VALUE = 'LEXICO.LEX_VALUE'; + + /** the column name for the LEX_CAPTION field */ + const LEX_CAPTION = 'LEXICO.LEX_CAPTION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('LexTopic', 'LexKey', 'LexValue', 'LexCaption', ), + BasePeer::TYPE_COLNAME => array (LexicoPeer::LEX_TOPIC, LexicoPeer::LEX_KEY, LexicoPeer::LEX_VALUE, LexicoPeer::LEX_CAPTION, ), + BasePeer::TYPE_FIELDNAME => array ('LEX_TOPIC', 'LEX_KEY', 'LEX_VALUE', 'LEX_CAPTION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('LexTopic' => 0, 'LexKey' => 1, 'LexValue' => 2, 'LexCaption' => 3, ), + BasePeer::TYPE_COLNAME => array (LexicoPeer::LEX_TOPIC => 0, LexicoPeer::LEX_KEY => 1, LexicoPeer::LEX_VALUE => 2, LexicoPeer::LEX_CAPTION => 3, ), + BasePeer::TYPE_FIELDNAME => array ('LEX_TOPIC' => 0, 'LEX_KEY' => 1, 'LEX_VALUE' => 2, 'LEX_CAPTION' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/LexicoMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.LexicoMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = LexicoPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. LexicoPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(LexicoPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(LexicoPeer::LEX_TOPIC); + + $criteria->addSelectColumn(LexicoPeer::LEX_KEY); + + $criteria->addSelectColumn(LexicoPeer::LEX_VALUE); + + $criteria->addSelectColumn(LexicoPeer::LEX_CAPTION); + + } + + const COUNT = 'COUNT(LEXICO.LEX_TOPIC)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT LEXICO.LEX_TOPIC)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(LexicoPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(LexicoPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = LexicoPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Lexico + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = LexicoPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return LexicoPeer::populateObjects(LexicoPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + LexicoPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = LexicoPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return LexicoPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Lexico or Criteria object. + * + * @param mixed $values Criteria or Lexico object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Lexico object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Lexico or Criteria object. + * + * @param mixed $values Criteria or Lexico object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(LexicoPeer::LEX_TOPIC); + $selectCriteria->add(LexicoPeer::LEX_TOPIC, $criteria->remove(LexicoPeer::LEX_TOPIC), $comparison); + + $comparison = $criteria->getComparison(LexicoPeer::LEX_KEY); + $selectCriteria->add(LexicoPeer::LEX_KEY, $criteria->remove(LexicoPeer::LEX_KEY), $comparison); + + } else { // $values is Lexico object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the LEXICO table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(LexicoPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Lexico or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Lexico object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(LexicoPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Lexico) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(LexicoPeer::LEX_TOPIC, $vals[0], Criteria::IN); + $criteria->add(LexicoPeer::LEX_KEY, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Lexico object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Lexico $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Lexico $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(LexicoPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(LexicoPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(LexicoPeer::DATABASE_NAME, LexicoPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $lex_topic + @param string $lex_key + + * @param Connection $con + * @return Lexico + */ + public static function retrieveByPK( $lex_topic, $lex_key, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(LexicoPeer::LEX_TOPIC, $lex_topic); + $criteria->add(LexicoPeer::LEX_KEY, $lex_key); + $v = LexicoPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseLexicoPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseLexicoPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/LexicoMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.LexicoMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseLogCasesScheduler.php b/workflow/engine/classes/model/om/BaseLogCasesScheduler.php new file mode 100644 index 000000000..93c1fc630 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLogCasesScheduler.php @@ -0,0 +1,1003 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/LogCasesSchedulerPeer.php'; + +/** + * Base class that represents a row from the 'LOG_CASES_SCHEDULER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLogCasesScheduler extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var LogCasesSchedulerPeer + */ + protected static $peer; + + + /** + * The value for the log_case_uid field. + * @var string + */ + protected $log_case_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the usr_name field. + * @var string + */ + protected $usr_name = ''; + + + /** + * The value for the exec_date field. + * @var int + */ + protected $exec_date; + + + /** + * The value for the exec_hour field. + * @var string + */ + protected $exec_hour = '12:00'; + + + /** + * The value for the result field. + * @var string + */ + protected $result = 'SUCCESS'; + + + /** + * The value for the sch_uid field. + * @var string + */ + protected $sch_uid = 'OPEN'; + + + /** + * The value for the ws_create_case_status field. + * @var string + */ + protected $ws_create_case_status; + + + /** + * The value for the ws_route_case_status field. + * @var string + */ + protected $ws_route_case_status; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [log_case_uid] column value. + * + * @return string + */ + public function getLogCaseUid() + { + + return $this->log_case_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [usr_name] column value. + * + * @return string + */ + public function getUsrName() + { + + return $this->usr_name; + } + + /** + * Get the [optionally formatted] [exec_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getExecDate($format = 'Y-m-d') + { + + if ($this->exec_date === null || $this->exec_date === '') { + return null; + } elseif (!is_int($this->exec_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->exec_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [exec_date] as date/time value: " . var_export($this->exec_date, true)); + } + } else { + $ts = $this->exec_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [exec_hour] column value. + * + * @return string + */ + public function getExecHour() + { + + return $this->exec_hour; + } + + /** + * Get the [result] column value. + * + * @return string + */ + public function getResult() + { + + return $this->result; + } + + /** + * Get the [sch_uid] column value. + * + * @return string + */ + public function getSchUid() + { + + return $this->sch_uid; + } + + /** + * Get the [ws_create_case_status] column value. + * + * @return string + */ + public function getWsCreateCaseStatus() + { + + return $this->ws_create_case_status; + } + + /** + * Get the [ws_route_case_status] column value. + * + * @return string + */ + public function getWsRouteCaseStatus() + { + + return $this->ws_route_case_status; + } + + /** + * Set the value of [log_case_uid] column. + * + * @param string $v new value + * @return void + */ + public function setLogCaseUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_case_uid !== $v || $v === '') { + $this->log_case_uid = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::LOG_CASE_UID; + } + + } // setLogCaseUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [usr_name] column. + * + * @param string $v new value + * @return void + */ + public function setUsrName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_name !== $v || $v === '') { + $this->usr_name = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::USR_NAME; + } + + } // setUsrName() + + /** + * Set the value of [exec_date] column. + * + * @param int $v new value + * @return void + */ + public function setExecDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [exec_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->exec_date !== $ts) { + $this->exec_date = $ts; + $this->modifiedColumns[] = LogCasesSchedulerPeer::EXEC_DATE; + } + + } // setExecDate() + + /** + * Set the value of [exec_hour] column. + * + * @param string $v new value + * @return void + */ + public function setExecHour($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->exec_hour !== $v || $v === '12:00') { + $this->exec_hour = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::EXEC_HOUR; + } + + } // setExecHour() + + /** + * Set the value of [result] column. + * + * @param string $v new value + * @return void + */ + public function setResult($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->result !== $v || $v === 'SUCCESS') { + $this->result = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::RESULT; + } + + } // setResult() + + /** + * Set the value of [sch_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSchUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sch_uid !== $v || $v === 'OPEN') { + $this->sch_uid = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::SCH_UID; + } + + } // setSchUid() + + /** + * Set the value of [ws_create_case_status] column. + * + * @param string $v new value + * @return void + */ + public function setWsCreateCaseStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ws_create_case_status !== $v) { + $this->ws_create_case_status = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS; + } + + } // setWsCreateCaseStatus() + + /** + * Set the value of [ws_route_case_status] column. + * + * @param string $v new value + * @return void + */ + public function setWsRouteCaseStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ws_route_case_status !== $v) { + $this->ws_route_case_status = $v; + $this->modifiedColumns[] = LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS; + } + + } // setWsRouteCaseStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->log_case_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->tas_uid = $rs->getString($startcol + 2); + + $this->usr_name = $rs->getString($startcol + 3); + + $this->exec_date = $rs->getDate($startcol + 4, null); + + $this->exec_hour = $rs->getString($startcol + 5); + + $this->result = $rs->getString($startcol + 6); + + $this->sch_uid = $rs->getString($startcol + 7); + + $this->ws_create_case_status = $rs->getString($startcol + 8); + + $this->ws_route_case_status = $rs->getString($startcol + 9); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 10; // 10 = LogCasesSchedulerPeer::NUM_COLUMNS - LogCasesSchedulerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating LogCasesScheduler object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LogCasesSchedulerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + LogCasesSchedulerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LogCasesSchedulerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = LogCasesSchedulerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += LogCasesSchedulerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = LogCasesSchedulerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LogCasesSchedulerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getLogCaseUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getTasUid(); + break; + case 3: + return $this->getUsrName(); + break; + case 4: + return $this->getExecDate(); + break; + case 5: + return $this->getExecHour(); + break; + case 6: + return $this->getResult(); + break; + case 7: + return $this->getSchUid(); + break; + case 8: + return $this->getWsCreateCaseStatus(); + break; + case 9: + return $this->getWsRouteCaseStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LogCasesSchedulerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getLogCaseUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getTasUid(), + $keys[3] => $this->getUsrName(), + $keys[4] => $this->getExecDate(), + $keys[5] => $this->getExecHour(), + $keys[6] => $this->getResult(), + $keys[7] => $this->getSchUid(), + $keys[8] => $this->getWsCreateCaseStatus(), + $keys[9] => $this->getWsRouteCaseStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LogCasesSchedulerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setLogCaseUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setTasUid($value); + break; + case 3: + $this->setUsrName($value); + break; + case 4: + $this->setExecDate($value); + break; + case 5: + $this->setExecHour($value); + break; + case 6: + $this->setResult($value); + break; + case 7: + $this->setSchUid($value); + break; + case 8: + $this->setWsCreateCaseStatus($value); + break; + case 9: + $this->setWsRouteCaseStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LogCasesSchedulerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setLogCaseUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTasUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setUsrName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setExecDate($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setExecHour($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setResult($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setSchUid($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setWsCreateCaseStatus($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setWsRouteCaseStatus($arr[$keys[9]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(LogCasesSchedulerPeer::DATABASE_NAME); + + if ($this->isColumnModified(LogCasesSchedulerPeer::LOG_CASE_UID)) $criteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, $this->log_case_uid); + if ($this->isColumnModified(LogCasesSchedulerPeer::PRO_UID)) $criteria->add(LogCasesSchedulerPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(LogCasesSchedulerPeer::TAS_UID)) $criteria->add(LogCasesSchedulerPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(LogCasesSchedulerPeer::USR_NAME)) $criteria->add(LogCasesSchedulerPeer::USR_NAME, $this->usr_name); + if ($this->isColumnModified(LogCasesSchedulerPeer::EXEC_DATE)) $criteria->add(LogCasesSchedulerPeer::EXEC_DATE, $this->exec_date); + if ($this->isColumnModified(LogCasesSchedulerPeer::EXEC_HOUR)) $criteria->add(LogCasesSchedulerPeer::EXEC_HOUR, $this->exec_hour); + if ($this->isColumnModified(LogCasesSchedulerPeer::RESULT)) $criteria->add(LogCasesSchedulerPeer::RESULT, $this->result); + if ($this->isColumnModified(LogCasesSchedulerPeer::SCH_UID)) $criteria->add(LogCasesSchedulerPeer::SCH_UID, $this->sch_uid); + if ($this->isColumnModified(LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS)) $criteria->add(LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS, $this->ws_create_case_status); + if ($this->isColumnModified(LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS)) $criteria->add(LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS, $this->ws_route_case_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(LogCasesSchedulerPeer::DATABASE_NAME); + + $criteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, $this->log_case_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getLogCaseUid(); + } + + /** + * Generic method to set the primary key (log_case_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setLogCaseUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of LogCasesScheduler (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setUsrName($this->usr_name); + + $copyObj->setExecDate($this->exec_date); + + $copyObj->setExecHour($this->exec_hour); + + $copyObj->setResult($this->result); + + $copyObj->setSchUid($this->sch_uid); + + $copyObj->setWsCreateCaseStatus($this->ws_create_case_status); + + $copyObj->setWsRouteCaseStatus($this->ws_route_case_status); + + + $copyObj->setNew(true); + + $copyObj->setLogCaseUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return LogCasesScheduler Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return LogCasesSchedulerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new LogCasesSchedulerPeer(); + } + return self::$peer; + } + +} // BaseLogCasesScheduler diff --git a/workflow/engine/classes/model/om/BaseLogCasesSchedulerPeer.php b/workflow/engine/classes/model/om/BaseLogCasesSchedulerPeer.php new file mode 100644 index 000000000..2b186a5f0 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLogCasesSchedulerPeer.php @@ -0,0 +1,610 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by LogCasesSchedulerPeer::getOMClass() +include_once 'classes/model/LogCasesScheduler.php'; + +/** + * Base static class for performing query and update operations on the 'LOG_CASES_SCHEDULER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLogCasesSchedulerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'LOG_CASES_SCHEDULER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.LogCasesScheduler'; + + /** The total number of columns. */ + const NUM_COLUMNS = 10; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the LOG_CASE_UID field */ + const LOG_CASE_UID = 'LOG_CASES_SCHEDULER.LOG_CASE_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'LOG_CASES_SCHEDULER.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'LOG_CASES_SCHEDULER.TAS_UID'; + + /** the column name for the USR_NAME field */ + const USR_NAME = 'LOG_CASES_SCHEDULER.USR_NAME'; + + /** the column name for the EXEC_DATE field */ + const EXEC_DATE = 'LOG_CASES_SCHEDULER.EXEC_DATE'; + + /** the column name for the EXEC_HOUR field */ + const EXEC_HOUR = 'LOG_CASES_SCHEDULER.EXEC_HOUR'; + + /** the column name for the RESULT field */ + const RESULT = 'LOG_CASES_SCHEDULER.RESULT'; + + /** the column name for the SCH_UID field */ + const SCH_UID = 'LOG_CASES_SCHEDULER.SCH_UID'; + + /** the column name for the WS_CREATE_CASE_STATUS field */ + const WS_CREATE_CASE_STATUS = 'LOG_CASES_SCHEDULER.WS_CREATE_CASE_STATUS'; + + /** the column name for the WS_ROUTE_CASE_STATUS field */ + const WS_ROUTE_CASE_STATUS = 'LOG_CASES_SCHEDULER.WS_ROUTE_CASE_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('LogCaseUid', 'ProUid', 'TasUid', 'UsrName', 'ExecDate', 'ExecHour', 'Result', 'SchUid', 'WsCreateCaseStatus', 'WsRouteCaseStatus', ), + BasePeer::TYPE_COLNAME => array (LogCasesSchedulerPeer::LOG_CASE_UID, LogCasesSchedulerPeer::PRO_UID, LogCasesSchedulerPeer::TAS_UID, LogCasesSchedulerPeer::USR_NAME, LogCasesSchedulerPeer::EXEC_DATE, LogCasesSchedulerPeer::EXEC_HOUR, LogCasesSchedulerPeer::RESULT, LogCasesSchedulerPeer::SCH_UID, LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS, LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('LOG_CASE_UID', 'PRO_UID', 'TAS_UID', 'USR_NAME', 'EXEC_DATE', 'EXEC_HOUR', 'RESULT', 'SCH_UID', 'WS_CREATE_CASE_STATUS', 'WS_ROUTE_CASE_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('LogCaseUid' => 0, 'ProUid' => 1, 'TasUid' => 2, 'UsrName' => 3, 'ExecDate' => 4, 'ExecHour' => 5, 'Result' => 6, 'SchUid' => 7, 'WsCreateCaseStatus' => 8, 'WsRouteCaseStatus' => 9, ), + BasePeer::TYPE_COLNAME => array (LogCasesSchedulerPeer::LOG_CASE_UID => 0, LogCasesSchedulerPeer::PRO_UID => 1, LogCasesSchedulerPeer::TAS_UID => 2, LogCasesSchedulerPeer::USR_NAME => 3, LogCasesSchedulerPeer::EXEC_DATE => 4, LogCasesSchedulerPeer::EXEC_HOUR => 5, LogCasesSchedulerPeer::RESULT => 6, LogCasesSchedulerPeer::SCH_UID => 7, LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS => 8, LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS => 9, ), + BasePeer::TYPE_FIELDNAME => array ('LOG_CASE_UID' => 0, 'PRO_UID' => 1, 'TAS_UID' => 2, 'USR_NAME' => 3, 'EXEC_DATE' => 4, 'EXEC_HOUR' => 5, 'RESULT' => 6, 'SCH_UID' => 7, 'WS_CREATE_CASE_STATUS' => 8, 'WS_ROUTE_CASE_STATUS' => 9, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/LogCasesSchedulerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.LogCasesSchedulerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = LogCasesSchedulerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. LogCasesSchedulerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(LogCasesSchedulerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(LogCasesSchedulerPeer::LOG_CASE_UID); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::PRO_UID); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::TAS_UID); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::USR_NAME); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::EXEC_DATE); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::EXEC_HOUR); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::RESULT); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::SCH_UID); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::WS_CREATE_CASE_STATUS); + + $criteria->addSelectColumn(LogCasesSchedulerPeer::WS_ROUTE_CASE_STATUS); + + } + + const COUNT = 'COUNT(LOG_CASES_SCHEDULER.LOG_CASE_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT LOG_CASES_SCHEDULER.LOG_CASE_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(LogCasesSchedulerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(LogCasesSchedulerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = LogCasesSchedulerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return LogCasesScheduler + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = LogCasesSchedulerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return LogCasesSchedulerPeer::populateObjects(LogCasesSchedulerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + LogCasesSchedulerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = LogCasesSchedulerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return LogCasesSchedulerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a LogCasesScheduler or Criteria object. + * + * @param mixed $values Criteria or LogCasesScheduler object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from LogCasesScheduler object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a LogCasesScheduler or Criteria object. + * + * @param mixed $values Criteria or LogCasesScheduler object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(LogCasesSchedulerPeer::LOG_CASE_UID); + $selectCriteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, $criteria->remove(LogCasesSchedulerPeer::LOG_CASE_UID), $comparison); + + } else { // $values is LogCasesScheduler object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the LOG_CASES_SCHEDULER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(LogCasesSchedulerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a LogCasesScheduler or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or LogCasesScheduler object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(LogCasesSchedulerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof LogCasesScheduler) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given LogCasesScheduler object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param LogCasesScheduler $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(LogCasesScheduler $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(LogCasesSchedulerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(LogCasesSchedulerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(LogCasesSchedulerPeer::DATABASE_NAME, LogCasesSchedulerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return LogCasesScheduler + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(LogCasesSchedulerPeer::DATABASE_NAME); + + $criteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, $pk); + + + $v = LogCasesSchedulerPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(LogCasesSchedulerPeer::LOG_CASE_UID, $pks, Criteria::IN); + $objs = LogCasesSchedulerPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseLogCasesSchedulerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseLogCasesSchedulerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/LogCasesSchedulerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.LogCasesSchedulerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseLoginLog.php b/workflow/engine/classes/model/om/BaseLoginLog.php new file mode 100644 index 000000000..6e19343d5 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLoginLog.php @@ -0,0 +1,919 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/LoginLogPeer.php'; + +/** + * Base class that represents a row from the 'LOGIN_LOG' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLoginLog extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var LoginLogPeer + */ + protected static $peer; + + + /** + * The value for the log_uid field. + * @var string + */ + protected $log_uid = ''; + + + /** + * The value for the log_status field. + * @var string + */ + protected $log_status = ''; + + + /** + * The value for the log_ip field. + * @var string + */ + protected $log_ip = ''; + + + /** + * The value for the log_sid field. + * @var string + */ + protected $log_sid = ''; + + + /** + * The value for the log_init_date field. + * @var int + */ + protected $log_init_date; + + + /** + * The value for the log_end_date field. + * @var int + */ + protected $log_end_date; + + + /** + * The value for the log_client_hostname field. + * @var string + */ + protected $log_client_hostname = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [log_uid] column value. + * + * @return string + */ + public function getLogUid() + { + + return $this->log_uid; + } + + /** + * Get the [log_status] column value. + * + * @return string + */ + public function getLogStatus() + { + + return $this->log_status; + } + + /** + * Get the [log_ip] column value. + * + * @return string + */ + public function getLogIp() + { + + return $this->log_ip; + } + + /** + * Get the [log_sid] column value. + * + * @return string + */ + public function getLogSid() + { + + return $this->log_sid; + } + + /** + * Get the [optionally formatted] [log_init_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getLogInitDate($format = 'Y-m-d H:i:s') + { + + if ($this->log_init_date === null || $this->log_init_date === '') { + return null; + } elseif (!is_int($this->log_init_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->log_init_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [log_init_date] as date/time value: " . var_export($this->log_init_date, true)); + } + } else { + $ts = $this->log_init_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [log_end_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getLogEndDate($format = 'Y-m-d H:i:s') + { + + if ($this->log_end_date === null || $this->log_end_date === '') { + return null; + } elseif (!is_int($this->log_end_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->log_end_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [log_end_date] as date/time value: " . var_export($this->log_end_date, true)); + } + } else { + $ts = $this->log_end_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [log_client_hostname] column value. + * + * @return string + */ + public function getLogClientHostname() + { + + return $this->log_client_hostname; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Set the value of [log_uid] column. + * + * @param string $v new value + * @return void + */ + public function setLogUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_uid !== $v || $v === '') { + $this->log_uid = $v; + $this->modifiedColumns[] = LoginLogPeer::LOG_UID; + } + + } // setLogUid() + + /** + * Set the value of [log_status] column. + * + * @param string $v new value + * @return void + */ + public function setLogStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_status !== $v || $v === '') { + $this->log_status = $v; + $this->modifiedColumns[] = LoginLogPeer::LOG_STATUS; + } + + } // setLogStatus() + + /** + * Set the value of [log_ip] column. + * + * @param string $v new value + * @return void + */ + public function setLogIp($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_ip !== $v || $v === '') { + $this->log_ip = $v; + $this->modifiedColumns[] = LoginLogPeer::LOG_IP; + } + + } // setLogIp() + + /** + * Set the value of [log_sid] column. + * + * @param string $v new value + * @return void + */ + public function setLogSid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_sid !== $v || $v === '') { + $this->log_sid = $v; + $this->modifiedColumns[] = LoginLogPeer::LOG_SID; + } + + } // setLogSid() + + /** + * Set the value of [log_init_date] column. + * + * @param int $v new value + * @return void + */ + public function setLogInitDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [log_init_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->log_init_date !== $ts) { + $this->log_init_date = $ts; + $this->modifiedColumns[] = LoginLogPeer::LOG_INIT_DATE; + } + + } // setLogInitDate() + + /** + * Set the value of [log_end_date] column. + * + * @param int $v new value + * @return void + */ + public function setLogEndDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [log_end_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->log_end_date !== $ts) { + $this->log_end_date = $ts; + $this->modifiedColumns[] = LoginLogPeer::LOG_END_DATE; + } + + } // setLogEndDate() + + /** + * Set the value of [log_client_hostname] column. + * + * @param string $v new value + * @return void + */ + public function setLogClientHostname($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->log_client_hostname !== $v || $v === '') { + $this->log_client_hostname = $v; + $this->modifiedColumns[] = LoginLogPeer::LOG_CLIENT_HOSTNAME; + } + + } // setLogClientHostname() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = LoginLogPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->log_uid = $rs->getString($startcol + 0); + + $this->log_status = $rs->getString($startcol + 1); + + $this->log_ip = $rs->getString($startcol + 2); + + $this->log_sid = $rs->getString($startcol + 3); + + $this->log_init_date = $rs->getTimestamp($startcol + 4, null); + + $this->log_end_date = $rs->getTimestamp($startcol + 5, null); + + $this->log_client_hostname = $rs->getString($startcol + 6); + + $this->usr_uid = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = LoginLogPeer::NUM_COLUMNS - LoginLogPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating LoginLog object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + } + + try { + $con->begin(); + LoginLogPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = LoginLogPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += LoginLogPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = LoginLogPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LoginLogPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getLogUid(); + break; + case 1: + return $this->getLogStatus(); + break; + case 2: + return $this->getLogIp(); + break; + case 3: + return $this->getLogSid(); + break; + case 4: + return $this->getLogInitDate(); + break; + case 5: + return $this->getLogEndDate(); + break; + case 6: + return $this->getLogClientHostname(); + break; + case 7: + return $this->getUsrUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LoginLogPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getLogUid(), + $keys[1] => $this->getLogStatus(), + $keys[2] => $this->getLogIp(), + $keys[3] => $this->getLogSid(), + $keys[4] => $this->getLogInitDate(), + $keys[5] => $this->getLogEndDate(), + $keys[6] => $this->getLogClientHostname(), + $keys[7] => $this->getUsrUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = LoginLogPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setLogUid($value); + break; + case 1: + $this->setLogStatus($value); + break; + case 2: + $this->setLogIp($value); + break; + case 3: + $this->setLogSid($value); + break; + case 4: + $this->setLogInitDate($value); + break; + case 5: + $this->setLogEndDate($value); + break; + case 6: + $this->setLogClientHostname($value); + break; + case 7: + $this->setUsrUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = LoginLogPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setLogUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setLogStatus($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setLogIp($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setLogSid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setLogInitDate($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setLogEndDate($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setLogClientHostname($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUsrUid($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(LoginLogPeer::DATABASE_NAME); + + if ($this->isColumnModified(LoginLogPeer::LOG_UID)) $criteria->add(LoginLogPeer::LOG_UID, $this->log_uid); + if ($this->isColumnModified(LoginLogPeer::LOG_STATUS)) $criteria->add(LoginLogPeer::LOG_STATUS, $this->log_status); + if ($this->isColumnModified(LoginLogPeer::LOG_IP)) $criteria->add(LoginLogPeer::LOG_IP, $this->log_ip); + if ($this->isColumnModified(LoginLogPeer::LOG_SID)) $criteria->add(LoginLogPeer::LOG_SID, $this->log_sid); + if ($this->isColumnModified(LoginLogPeer::LOG_INIT_DATE)) $criteria->add(LoginLogPeer::LOG_INIT_DATE, $this->log_init_date); + if ($this->isColumnModified(LoginLogPeer::LOG_END_DATE)) $criteria->add(LoginLogPeer::LOG_END_DATE, $this->log_end_date); + if ($this->isColumnModified(LoginLogPeer::LOG_CLIENT_HOSTNAME)) $criteria->add(LoginLogPeer::LOG_CLIENT_HOSTNAME, $this->log_client_hostname); + if ($this->isColumnModified(LoginLogPeer::USR_UID)) $criteria->add(LoginLogPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(LoginLogPeer::DATABASE_NAME); + + $criteria->add(LoginLogPeer::LOG_UID, $this->log_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getLogUid(); + } + + /** + * Generic method to set the primary key (log_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setLogUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of LoginLog (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setLogStatus($this->log_status); + + $copyObj->setLogIp($this->log_ip); + + $copyObj->setLogSid($this->log_sid); + + $copyObj->setLogInitDate($this->log_init_date); + + $copyObj->setLogEndDate($this->log_end_date); + + $copyObj->setLogClientHostname($this->log_client_hostname); + + $copyObj->setUsrUid($this->usr_uid); + + + $copyObj->setNew(true); + + $copyObj->setLogUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return LoginLog Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return LoginLogPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new LoginLogPeer(); + } + return self::$peer; + } + +} // BaseLoginLog diff --git a/workflow/engine/classes/model/om/BaseLoginLogPeer.php b/workflow/engine/classes/model/om/BaseLoginLogPeer.php new file mode 100644 index 000000000..ccc83fb35 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseLoginLogPeer.php @@ -0,0 +1,600 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by LoginLogPeer::getOMClass() +include_once 'classes/model/LoginLog.php'; + +/** + * Base static class for performing query and update operations on the 'LOGIN_LOG' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseLoginLogPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'LOGIN_LOG'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.LoginLog'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the LOG_UID field */ + const LOG_UID = 'LOGIN_LOG.LOG_UID'; + + /** the column name for the LOG_STATUS field */ + const LOG_STATUS = 'LOGIN_LOG.LOG_STATUS'; + + /** the column name for the LOG_IP field */ + const LOG_IP = 'LOGIN_LOG.LOG_IP'; + + /** the column name for the LOG_SID field */ + const LOG_SID = 'LOGIN_LOG.LOG_SID'; + + /** the column name for the LOG_INIT_DATE field */ + const LOG_INIT_DATE = 'LOGIN_LOG.LOG_INIT_DATE'; + + /** the column name for the LOG_END_DATE field */ + const LOG_END_DATE = 'LOGIN_LOG.LOG_END_DATE'; + + /** the column name for the LOG_CLIENT_HOSTNAME field */ + const LOG_CLIENT_HOSTNAME = 'LOGIN_LOG.LOG_CLIENT_HOSTNAME'; + + /** the column name for the USR_UID field */ + const USR_UID = 'LOGIN_LOG.USR_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('LogUid', 'LogStatus', 'LogIp', 'LogSid', 'LogInitDate', 'LogEndDate', 'LogClientHostname', 'UsrUid', ), + BasePeer::TYPE_COLNAME => array (LoginLogPeer::LOG_UID, LoginLogPeer::LOG_STATUS, LoginLogPeer::LOG_IP, LoginLogPeer::LOG_SID, LoginLogPeer::LOG_INIT_DATE, LoginLogPeer::LOG_END_DATE, LoginLogPeer::LOG_CLIENT_HOSTNAME, LoginLogPeer::USR_UID, ), + BasePeer::TYPE_FIELDNAME => array ('LOG_UID', 'LOG_STATUS', 'LOG_IP', 'LOG_SID', 'LOG_INIT_DATE', 'LOG_END_DATE', 'LOG_CLIENT_HOSTNAME', 'USR_UID', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('LogUid' => 0, 'LogStatus' => 1, 'LogIp' => 2, 'LogSid' => 3, 'LogInitDate' => 4, 'LogEndDate' => 5, 'LogClientHostname' => 6, 'UsrUid' => 7, ), + BasePeer::TYPE_COLNAME => array (LoginLogPeer::LOG_UID => 0, LoginLogPeer::LOG_STATUS => 1, LoginLogPeer::LOG_IP => 2, LoginLogPeer::LOG_SID => 3, LoginLogPeer::LOG_INIT_DATE => 4, LoginLogPeer::LOG_END_DATE => 5, LoginLogPeer::LOG_CLIENT_HOSTNAME => 6, LoginLogPeer::USR_UID => 7, ), + BasePeer::TYPE_FIELDNAME => array ('LOG_UID' => 0, 'LOG_STATUS' => 1, 'LOG_IP' => 2, 'LOG_SID' => 3, 'LOG_INIT_DATE' => 4, 'LOG_END_DATE' => 5, 'LOG_CLIENT_HOSTNAME' => 6, 'USR_UID' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/LoginLogMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.LoginLogMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = LoginLogPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. LoginLogPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(LoginLogPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(LoginLogPeer::LOG_UID); + + $criteria->addSelectColumn(LoginLogPeer::LOG_STATUS); + + $criteria->addSelectColumn(LoginLogPeer::LOG_IP); + + $criteria->addSelectColumn(LoginLogPeer::LOG_SID); + + $criteria->addSelectColumn(LoginLogPeer::LOG_INIT_DATE); + + $criteria->addSelectColumn(LoginLogPeer::LOG_END_DATE); + + $criteria->addSelectColumn(LoginLogPeer::LOG_CLIENT_HOSTNAME); + + $criteria->addSelectColumn(LoginLogPeer::USR_UID); + + } + + const COUNT = 'COUNT(LOGIN_LOG.LOG_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT LOGIN_LOG.LOG_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(LoginLogPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(LoginLogPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = LoginLogPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return LoginLog + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = LoginLogPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return LoginLogPeer::populateObjects(LoginLogPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + LoginLogPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = LoginLogPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return LoginLogPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a LoginLog or Criteria object. + * + * @param mixed $values Criteria or LoginLog object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from LoginLog object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a LoginLog or Criteria object. + * + * @param mixed $values Criteria or LoginLog object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(LoginLogPeer::LOG_UID); + $selectCriteria->add(LoginLogPeer::LOG_UID, $criteria->remove(LoginLogPeer::LOG_UID), $comparison); + + } else { // $values is LoginLog object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the LOGIN_LOG table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(LoginLogPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a LoginLog or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or LoginLog object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(LoginLogPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof LoginLog) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(LoginLogPeer::LOG_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given LoginLog object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param LoginLog $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(LoginLog $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(LoginLogPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(LoginLogPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(LoginLogPeer::DATABASE_NAME, LoginLogPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return LoginLog + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(LoginLogPeer::DATABASE_NAME); + + $criteria->add(LoginLogPeer::LOG_UID, $pk); + + + $v = LoginLogPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(LoginLogPeer::LOG_UID, $pks, Criteria::IN); + $objs = LoginLogPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseLoginLogPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseLoginLogPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/LoginLogMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.LoginLogMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseObjectPermission.php b/workflow/engine/classes/model/om/BaseObjectPermission.php new file mode 100644 index 000000000..b70d789da --- /dev/null +++ b/workflow/engine/classes/model/om/BaseObjectPermission.php @@ -0,0 +1,1034 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ObjectPermissionPeer.php'; + +/** + * Base class that represents a row from the 'OBJECT_PERMISSION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseObjectPermission extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ObjectPermissionPeer + */ + protected static $peer; + + + /** + * The value for the op_uid field. + * @var string + */ + protected $op_uid = '0'; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = '0'; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = '0'; + + + /** + * The value for the op_user_relation field. + * @var int + */ + protected $op_user_relation = 0; + + + /** + * The value for the op_task_source field. + * @var string + */ + protected $op_task_source = '0'; + + + /** + * The value for the op_participate field. + * @var int + */ + protected $op_participate = 0; + + + /** + * The value for the op_obj_type field. + * @var string + */ + protected $op_obj_type = '0'; + + + /** + * The value for the op_obj_uid field. + * @var string + */ + protected $op_obj_uid = '0'; + + + /** + * The value for the op_action field. + * @var string + */ + protected $op_action = '0'; + + + /** + * The value for the op_case_status field. + * @var string + */ + protected $op_case_status = '0'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [op_uid] column value. + * + * @return string + */ + public function getOpUid() + { + + return $this->op_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [op_user_relation] column value. + * + * @return int + */ + public function getOpUserRelation() + { + + return $this->op_user_relation; + } + + /** + * Get the [op_task_source] column value. + * + * @return string + */ + public function getOpTaskSource() + { + + return $this->op_task_source; + } + + /** + * Get the [op_participate] column value. + * + * @return int + */ + public function getOpParticipate() + { + + return $this->op_participate; + } + + /** + * Get the [op_obj_type] column value. + * + * @return string + */ + public function getOpObjType() + { + + return $this->op_obj_type; + } + + /** + * Get the [op_obj_uid] column value. + * + * @return string + */ + public function getOpObjUid() + { + + return $this->op_obj_uid; + } + + /** + * Get the [op_action] column value. + * + * @return string + */ + public function getOpAction() + { + + return $this->op_action; + } + + /** + * Get the [op_case_status] column value. + * + * @return string + */ + public function getOpCaseStatus() + { + + return $this->op_case_status; + } + + /** + * Set the value of [op_uid] column. + * + * @param string $v new value + * @return void + */ + public function setOpUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_uid !== $v || $v === '0') { + $this->op_uid = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_UID; + } + + } // setOpUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '0') { + $this->tas_uid = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '0') { + $this->usr_uid = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [op_user_relation] column. + * + * @param int $v new value + * @return void + */ + public function setOpUserRelation($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->op_user_relation !== $v || $v === 0) { + $this->op_user_relation = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_USER_RELATION; + } + + } // setOpUserRelation() + + /** + * Set the value of [op_task_source] column. + * + * @param string $v new value + * @return void + */ + public function setOpTaskSource($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_task_source !== $v || $v === '0') { + $this->op_task_source = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_TASK_SOURCE; + } + + } // setOpTaskSource() + + /** + * Set the value of [op_participate] column. + * + * @param int $v new value + * @return void + */ + public function setOpParticipate($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->op_participate !== $v || $v === 0) { + $this->op_participate = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_PARTICIPATE; + } + + } // setOpParticipate() + + /** + * Set the value of [op_obj_type] column. + * + * @param string $v new value + * @return void + */ + public function setOpObjType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_obj_type !== $v || $v === '0') { + $this->op_obj_type = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_OBJ_TYPE; + } + + } // setOpObjType() + + /** + * Set the value of [op_obj_uid] column. + * + * @param string $v new value + * @return void + */ + public function setOpObjUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_obj_uid !== $v || $v === '0') { + $this->op_obj_uid = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_OBJ_UID; + } + + } // setOpObjUid() + + /** + * Set the value of [op_action] column. + * + * @param string $v new value + * @return void + */ + public function setOpAction($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_action !== $v || $v === '0') { + $this->op_action = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_ACTION; + } + + } // setOpAction() + + /** + * Set the value of [op_case_status] column. + * + * @param string $v new value + * @return void + */ + public function setOpCaseStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->op_case_status !== $v || $v === '0') { + $this->op_case_status = $v; + $this->modifiedColumns[] = ObjectPermissionPeer::OP_CASE_STATUS; + } + + } // setOpCaseStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->op_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->tas_uid = $rs->getString($startcol + 2); + + $this->usr_uid = $rs->getString($startcol + 3); + + $this->op_user_relation = $rs->getInt($startcol + 4); + + $this->op_task_source = $rs->getString($startcol + 5); + + $this->op_participate = $rs->getInt($startcol + 6); + + $this->op_obj_type = $rs->getString($startcol + 7); + + $this->op_obj_uid = $rs->getString($startcol + 8); + + $this->op_action = $rs->getString($startcol + 9); + + $this->op_case_status = $rs->getString($startcol + 10); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 11; // 11 = ObjectPermissionPeer::NUM_COLUMNS - ObjectPermissionPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ObjectPermission object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ObjectPermissionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ObjectPermissionPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ObjectPermissionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ObjectPermissionPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ObjectPermissionPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ObjectPermissionPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ObjectPermissionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getOpUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getTasUid(); + break; + case 3: + return $this->getUsrUid(); + break; + case 4: + return $this->getOpUserRelation(); + break; + case 5: + return $this->getOpTaskSource(); + break; + case 6: + return $this->getOpParticipate(); + break; + case 7: + return $this->getOpObjType(); + break; + case 8: + return $this->getOpObjUid(); + break; + case 9: + return $this->getOpAction(); + break; + case 10: + return $this->getOpCaseStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ObjectPermissionPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getOpUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getTasUid(), + $keys[3] => $this->getUsrUid(), + $keys[4] => $this->getOpUserRelation(), + $keys[5] => $this->getOpTaskSource(), + $keys[6] => $this->getOpParticipate(), + $keys[7] => $this->getOpObjType(), + $keys[8] => $this->getOpObjUid(), + $keys[9] => $this->getOpAction(), + $keys[10] => $this->getOpCaseStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ObjectPermissionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setOpUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setTasUid($value); + break; + case 3: + $this->setUsrUid($value); + break; + case 4: + $this->setOpUserRelation($value); + break; + case 5: + $this->setOpTaskSource($value); + break; + case 6: + $this->setOpParticipate($value); + break; + case 7: + $this->setOpObjType($value); + break; + case 8: + $this->setOpObjUid($value); + break; + case 9: + $this->setOpAction($value); + break; + case 10: + $this->setOpCaseStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ObjectPermissionPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setOpUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTasUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setUsrUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setOpUserRelation($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setOpTaskSource($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setOpParticipate($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setOpObjType($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setOpObjUid($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setOpAction($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setOpCaseStatus($arr[$keys[10]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ObjectPermissionPeer::DATABASE_NAME); + + if ($this->isColumnModified(ObjectPermissionPeer::OP_UID)) $criteria->add(ObjectPermissionPeer::OP_UID, $this->op_uid); + if ($this->isColumnModified(ObjectPermissionPeer::PRO_UID)) $criteria->add(ObjectPermissionPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ObjectPermissionPeer::TAS_UID)) $criteria->add(ObjectPermissionPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(ObjectPermissionPeer::USR_UID)) $criteria->add(ObjectPermissionPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(ObjectPermissionPeer::OP_USER_RELATION)) $criteria->add(ObjectPermissionPeer::OP_USER_RELATION, $this->op_user_relation); + if ($this->isColumnModified(ObjectPermissionPeer::OP_TASK_SOURCE)) $criteria->add(ObjectPermissionPeer::OP_TASK_SOURCE, $this->op_task_source); + if ($this->isColumnModified(ObjectPermissionPeer::OP_PARTICIPATE)) $criteria->add(ObjectPermissionPeer::OP_PARTICIPATE, $this->op_participate); + if ($this->isColumnModified(ObjectPermissionPeer::OP_OBJ_TYPE)) $criteria->add(ObjectPermissionPeer::OP_OBJ_TYPE, $this->op_obj_type); + if ($this->isColumnModified(ObjectPermissionPeer::OP_OBJ_UID)) $criteria->add(ObjectPermissionPeer::OP_OBJ_UID, $this->op_obj_uid); + if ($this->isColumnModified(ObjectPermissionPeer::OP_ACTION)) $criteria->add(ObjectPermissionPeer::OP_ACTION, $this->op_action); + if ($this->isColumnModified(ObjectPermissionPeer::OP_CASE_STATUS)) $criteria->add(ObjectPermissionPeer::OP_CASE_STATUS, $this->op_case_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ObjectPermissionPeer::DATABASE_NAME); + + $criteria->add(ObjectPermissionPeer::OP_UID, $this->op_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getOpUid(); + } + + /** + * Generic method to set the primary key (op_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setOpUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ObjectPermission (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setOpUserRelation($this->op_user_relation); + + $copyObj->setOpTaskSource($this->op_task_source); + + $copyObj->setOpParticipate($this->op_participate); + + $copyObj->setOpObjType($this->op_obj_type); + + $copyObj->setOpObjUid($this->op_obj_uid); + + $copyObj->setOpAction($this->op_action); + + $copyObj->setOpCaseStatus($this->op_case_status); + + + $copyObj->setNew(true); + + $copyObj->setOpUid('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ObjectPermission Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ObjectPermissionPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ObjectPermissionPeer(); + } + return self::$peer; + } + +} // BaseObjectPermission diff --git a/workflow/engine/classes/model/om/BaseObjectPermissionPeer.php b/workflow/engine/classes/model/om/BaseObjectPermissionPeer.php new file mode 100644 index 000000000..9300b553a --- /dev/null +++ b/workflow/engine/classes/model/om/BaseObjectPermissionPeer.php @@ -0,0 +1,645 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ObjectPermissionPeer::getOMClass() +include_once 'classes/model/ObjectPermission.php'; + +/** + * Base static class for performing query and update operations on the 'OBJECT_PERMISSION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseObjectPermissionPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'OBJECT_PERMISSION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ObjectPermission'; + + /** The total number of columns. */ + const NUM_COLUMNS = 11; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the OP_UID field */ + const OP_UID = 'OBJECT_PERMISSION.OP_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'OBJECT_PERMISSION.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'OBJECT_PERMISSION.TAS_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'OBJECT_PERMISSION.USR_UID'; + + /** the column name for the OP_USER_RELATION field */ + const OP_USER_RELATION = 'OBJECT_PERMISSION.OP_USER_RELATION'; + + /** the column name for the OP_TASK_SOURCE field */ + const OP_TASK_SOURCE = 'OBJECT_PERMISSION.OP_TASK_SOURCE'; + + /** the column name for the OP_PARTICIPATE field */ + const OP_PARTICIPATE = 'OBJECT_PERMISSION.OP_PARTICIPATE'; + + /** the column name for the OP_OBJ_TYPE field */ + const OP_OBJ_TYPE = 'OBJECT_PERMISSION.OP_OBJ_TYPE'; + + /** the column name for the OP_OBJ_UID field */ + const OP_OBJ_UID = 'OBJECT_PERMISSION.OP_OBJ_UID'; + + /** the column name for the OP_ACTION field */ + const OP_ACTION = 'OBJECT_PERMISSION.OP_ACTION'; + + /** the column name for the OP_CASE_STATUS field */ + const OP_CASE_STATUS = 'OBJECT_PERMISSION.OP_CASE_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('OpUid', 'ProUid', 'TasUid', 'UsrUid', 'OpUserRelation', 'OpTaskSource', 'OpParticipate', 'OpObjType', 'OpObjUid', 'OpAction', 'OpCaseStatus', ), + BasePeer::TYPE_COLNAME => array (ObjectPermissionPeer::OP_UID, ObjectPermissionPeer::PRO_UID, ObjectPermissionPeer::TAS_UID, ObjectPermissionPeer::USR_UID, ObjectPermissionPeer::OP_USER_RELATION, ObjectPermissionPeer::OP_TASK_SOURCE, ObjectPermissionPeer::OP_PARTICIPATE, ObjectPermissionPeer::OP_OBJ_TYPE, ObjectPermissionPeer::OP_OBJ_UID, ObjectPermissionPeer::OP_ACTION, ObjectPermissionPeer::OP_CASE_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('OP_UID', 'PRO_UID', 'TAS_UID', 'USR_UID', 'OP_USER_RELATION', 'OP_TASK_SOURCE', 'OP_PARTICIPATE', 'OP_OBJ_TYPE', 'OP_OBJ_UID', 'OP_ACTION', 'OP_CASE_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('OpUid' => 0, 'ProUid' => 1, 'TasUid' => 2, 'UsrUid' => 3, 'OpUserRelation' => 4, 'OpTaskSource' => 5, 'OpParticipate' => 6, 'OpObjType' => 7, 'OpObjUid' => 8, 'OpAction' => 9, 'OpCaseStatus' => 10, ), + BasePeer::TYPE_COLNAME => array (ObjectPermissionPeer::OP_UID => 0, ObjectPermissionPeer::PRO_UID => 1, ObjectPermissionPeer::TAS_UID => 2, ObjectPermissionPeer::USR_UID => 3, ObjectPermissionPeer::OP_USER_RELATION => 4, ObjectPermissionPeer::OP_TASK_SOURCE => 5, ObjectPermissionPeer::OP_PARTICIPATE => 6, ObjectPermissionPeer::OP_OBJ_TYPE => 7, ObjectPermissionPeer::OP_OBJ_UID => 8, ObjectPermissionPeer::OP_ACTION => 9, ObjectPermissionPeer::OP_CASE_STATUS => 10, ), + BasePeer::TYPE_FIELDNAME => array ('OP_UID' => 0, 'PRO_UID' => 1, 'TAS_UID' => 2, 'USR_UID' => 3, 'OP_USER_RELATION' => 4, 'OP_TASK_SOURCE' => 5, 'OP_PARTICIPATE' => 6, 'OP_OBJ_TYPE' => 7, 'OP_OBJ_UID' => 8, 'OP_ACTION' => 9, 'OP_CASE_STATUS' => 10, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ObjectPermissionMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ObjectPermissionMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ObjectPermissionPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ObjectPermissionPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ObjectPermissionPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_UID); + + $criteria->addSelectColumn(ObjectPermissionPeer::PRO_UID); + + $criteria->addSelectColumn(ObjectPermissionPeer::TAS_UID); + + $criteria->addSelectColumn(ObjectPermissionPeer::USR_UID); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_USER_RELATION); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_TASK_SOURCE); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_PARTICIPATE); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_OBJ_TYPE); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_OBJ_UID); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_ACTION); + + $criteria->addSelectColumn(ObjectPermissionPeer::OP_CASE_STATUS); + + } + + const COUNT = 'COUNT(OBJECT_PERMISSION.OP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT OBJECT_PERMISSION.OP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ObjectPermissionPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ObjectPermissionPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ObjectPermissionPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ObjectPermission + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ObjectPermissionPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ObjectPermissionPeer::populateObjects(ObjectPermissionPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ObjectPermissionPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ObjectPermissionPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ObjectPermissionPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ObjectPermission or Criteria object. + * + * @param mixed $values Criteria or ObjectPermission object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ObjectPermission object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ObjectPermission or Criteria object. + * + * @param mixed $values Criteria or ObjectPermission object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ObjectPermissionPeer::OP_UID); + $selectCriteria->add(ObjectPermissionPeer::OP_UID, $criteria->remove(ObjectPermissionPeer::OP_UID), $comparison); + + } else { // $values is ObjectPermission object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the OBJECT_PERMISSION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ObjectPermissionPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ObjectPermission or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ObjectPermission object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ObjectPermissionPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ObjectPermission) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ObjectPermissionPeer::OP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ObjectPermission object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ObjectPermission $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ObjectPermission $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ObjectPermissionPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ObjectPermissionPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_UID)) + $columns[ObjectPermissionPeer::OP_UID] = $obj->getOpUid(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::PRO_UID)) + $columns[ObjectPermissionPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::TAS_UID)) + $columns[ObjectPermissionPeer::TAS_UID] = $obj->getTasUid(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::USR_UID)) + $columns[ObjectPermissionPeer::USR_UID] = $obj->getUsrUid(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_USER_RELATION)) + $columns[ObjectPermissionPeer::OP_USER_RELATION] = $obj->getOpUserRelation(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_TASK_SOURCE)) + $columns[ObjectPermissionPeer::OP_TASK_SOURCE] = $obj->getOpTaskSource(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_PARTICIPATE)) + $columns[ObjectPermissionPeer::OP_PARTICIPATE] = $obj->getOpParticipate(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_OBJ_TYPE)) + $columns[ObjectPermissionPeer::OP_OBJ_TYPE] = $obj->getOpObjType(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_OBJ_UID)) + $columns[ObjectPermissionPeer::OP_OBJ_UID] = $obj->getOpObjUid(); + + if ($obj->isNew() || $obj->isColumnModified(ObjectPermissionPeer::OP_ACTION)) + $columns[ObjectPermissionPeer::OP_ACTION] = $obj->getOpAction(); + + } + + return BasePeer::doValidate(ObjectPermissionPeer::DATABASE_NAME, ObjectPermissionPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ObjectPermission + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ObjectPermissionPeer::DATABASE_NAME); + + $criteria->add(ObjectPermissionPeer::OP_UID, $pk); + + + $v = ObjectPermissionPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ObjectPermissionPeer::OP_UID, $pks, Criteria::IN); + $objs = ObjectPermissionPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseObjectPermissionPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseObjectPermissionPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ObjectPermissionMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ObjectPermissionMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseOutputDocument.php b/workflow/engine/classes/model/om/BaseOutputDocument.php new file mode 100644 index 000000000..783d54723 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseOutputDocument.php @@ -0,0 +1,1246 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/OutputDocumentPeer.php'; + +/** + * Base class that represents a row from the 'OUTPUT_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseOutputDocument extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var OutputDocumentPeer + */ + protected static $peer; + + + /** + * The value for the out_doc_uid field. + * @var string + */ + protected $out_doc_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the out_doc_landscape field. + * @var int + */ + protected $out_doc_landscape = 0; + + + /** + * The value for the out_doc_media field. + * @var string + */ + protected $out_doc_media = 'Letter'; + + + /** + * The value for the out_doc_left_margin field. + * @var int + */ + protected $out_doc_left_margin = 30; + + + /** + * The value for the out_doc_right_margin field. + * @var int + */ + protected $out_doc_right_margin = 15; + + + /** + * The value for the out_doc_top_margin field. + * @var int + */ + protected $out_doc_top_margin = 15; + + + /** + * The value for the out_doc_bottom_margin field. + * @var int + */ + protected $out_doc_bottom_margin = 15; + + + /** + * The value for the out_doc_generate field. + * @var string + */ + protected $out_doc_generate = 'BOTH'; + + + /** + * The value for the out_doc_type field. + * @var string + */ + protected $out_doc_type = 'HTML'; + + + /** + * The value for the out_doc_current_revision field. + * @var int + */ + protected $out_doc_current_revision = 0; + + + /** + * The value for the out_doc_field_mapping field. + * @var string + */ + protected $out_doc_field_mapping; + + + /** + * The value for the out_doc_versioning field. + * @var int + */ + protected $out_doc_versioning = 0; + + + /** + * The value for the out_doc_destination_path field. + * @var string + */ + protected $out_doc_destination_path; + + + /** + * The value for the out_doc_tags field. + * @var string + */ + protected $out_doc_tags; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [out_doc_uid] column value. + * + * @return string + */ + public function getOutDocUid() + { + + return $this->out_doc_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [out_doc_landscape] column value. + * + * @return int + */ + public function getOutDocLandscape() + { + + return $this->out_doc_landscape; + } + + /** + * Get the [out_doc_media] column value. + * + * @return string + */ + public function getOutDocMedia() + { + + return $this->out_doc_media; + } + + /** + * Get the [out_doc_left_margin] column value. + * + * @return int + */ + public function getOutDocLeftMargin() + { + + return $this->out_doc_left_margin; + } + + /** + * Get the [out_doc_right_margin] column value. + * + * @return int + */ + public function getOutDocRightMargin() + { + + return $this->out_doc_right_margin; + } + + /** + * Get the [out_doc_top_margin] column value. + * + * @return int + */ + public function getOutDocTopMargin() + { + + return $this->out_doc_top_margin; + } + + /** + * Get the [out_doc_bottom_margin] column value. + * + * @return int + */ + public function getOutDocBottomMargin() + { + + return $this->out_doc_bottom_margin; + } + + /** + * Get the [out_doc_generate] column value. + * + * @return string + */ + public function getOutDocGenerate() + { + + return $this->out_doc_generate; + } + + /** + * Get the [out_doc_type] column value. + * + * @return string + */ + public function getOutDocType() + { + + return $this->out_doc_type; + } + + /** + * Get the [out_doc_current_revision] column value. + * + * @return int + */ + public function getOutDocCurrentRevision() + { + + return $this->out_doc_current_revision; + } + + /** + * Get the [out_doc_field_mapping] column value. + * + * @return string + */ + public function getOutDocFieldMapping() + { + + return $this->out_doc_field_mapping; + } + + /** + * Get the [out_doc_versioning] column value. + * + * @return int + */ + public function getOutDocVersioning() + { + + return $this->out_doc_versioning; + } + + /** + * Get the [out_doc_destination_path] column value. + * + * @return string + */ + public function getOutDocDestinationPath() + { + + return $this->out_doc_destination_path; + } + + /** + * Get the [out_doc_tags] column value. + * + * @return string + */ + public function getOutDocTags() + { + + return $this->out_doc_tags; + } + + /** + * Set the value of [out_doc_uid] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_uid !== $v || $v === '') { + $this->out_doc_uid = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_UID; + } + + } // setOutDocUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = OutputDocumentPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [out_doc_landscape] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocLandscape($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_landscape !== $v || $v === 0) { + $this->out_doc_landscape = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_LANDSCAPE; + } + + } // setOutDocLandscape() + + /** + * Set the value of [out_doc_media] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocMedia($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_media !== $v || $v === 'Letter') { + $this->out_doc_media = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_MEDIA; + } + + } // setOutDocMedia() + + /** + * Set the value of [out_doc_left_margin] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocLeftMargin($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_left_margin !== $v || $v === 30) { + $this->out_doc_left_margin = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_LEFT_MARGIN; + } + + } // setOutDocLeftMargin() + + /** + * Set the value of [out_doc_right_margin] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocRightMargin($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_right_margin !== $v || $v === 15) { + $this->out_doc_right_margin = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN; + } + + } // setOutDocRightMargin() + + /** + * Set the value of [out_doc_top_margin] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocTopMargin($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_top_margin !== $v || $v === 15) { + $this->out_doc_top_margin = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_TOP_MARGIN; + } + + } // setOutDocTopMargin() + + /** + * Set the value of [out_doc_bottom_margin] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocBottomMargin($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_bottom_margin !== $v || $v === 15) { + $this->out_doc_bottom_margin = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN; + } + + } // setOutDocBottomMargin() + + /** + * Set the value of [out_doc_generate] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocGenerate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_generate !== $v || $v === 'BOTH') { + $this->out_doc_generate = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_GENERATE; + } + + } // setOutDocGenerate() + + /** + * Set the value of [out_doc_type] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_type !== $v || $v === 'HTML') { + $this->out_doc_type = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_TYPE; + } + + } // setOutDocType() + + /** + * Set the value of [out_doc_current_revision] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocCurrentRevision($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_current_revision !== $v || $v === 0) { + $this->out_doc_current_revision = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_CURRENT_REVISION; + } + + } // setOutDocCurrentRevision() + + /** + * Set the value of [out_doc_field_mapping] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocFieldMapping($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_field_mapping !== $v) { + $this->out_doc_field_mapping = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_FIELD_MAPPING; + } + + } // setOutDocFieldMapping() + + /** + * Set the value of [out_doc_versioning] column. + * + * @param int $v new value + * @return void + */ + public function setOutDocVersioning($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->out_doc_versioning !== $v || $v === 0) { + $this->out_doc_versioning = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_VERSIONING; + } + + } // setOutDocVersioning() + + /** + * Set the value of [out_doc_destination_path] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocDestinationPath($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_destination_path !== $v) { + $this->out_doc_destination_path = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_DESTINATION_PATH; + } + + } // setOutDocDestinationPath() + + /** + * Set the value of [out_doc_tags] column. + * + * @param string $v new value + * @return void + */ + public function setOutDocTags($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->out_doc_tags !== $v) { + $this->out_doc_tags = $v; + $this->modifiedColumns[] = OutputDocumentPeer::OUT_DOC_TAGS; + } + + } // setOutDocTags() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->out_doc_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->out_doc_landscape = $rs->getInt($startcol + 2); + + $this->out_doc_media = $rs->getString($startcol + 3); + + $this->out_doc_left_margin = $rs->getInt($startcol + 4); + + $this->out_doc_right_margin = $rs->getInt($startcol + 5); + + $this->out_doc_top_margin = $rs->getInt($startcol + 6); + + $this->out_doc_bottom_margin = $rs->getInt($startcol + 7); + + $this->out_doc_generate = $rs->getString($startcol + 8); + + $this->out_doc_type = $rs->getString($startcol + 9); + + $this->out_doc_current_revision = $rs->getInt($startcol + 10); + + $this->out_doc_field_mapping = $rs->getString($startcol + 11); + + $this->out_doc_versioning = $rs->getInt($startcol + 12); + + $this->out_doc_destination_path = $rs->getString($startcol + 13); + + $this->out_doc_tags = $rs->getString($startcol + 14); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 15; // 15 = OutputDocumentPeer::NUM_COLUMNS - OutputDocumentPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating OutputDocument object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + OutputDocumentPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = OutputDocumentPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += OutputDocumentPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = OutputDocumentPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = OutputDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getOutDocUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getOutDocLandscape(); + break; + case 3: + return $this->getOutDocMedia(); + break; + case 4: + return $this->getOutDocLeftMargin(); + break; + case 5: + return $this->getOutDocRightMargin(); + break; + case 6: + return $this->getOutDocTopMargin(); + break; + case 7: + return $this->getOutDocBottomMargin(); + break; + case 8: + return $this->getOutDocGenerate(); + break; + case 9: + return $this->getOutDocType(); + break; + case 10: + return $this->getOutDocCurrentRevision(); + break; + case 11: + return $this->getOutDocFieldMapping(); + break; + case 12: + return $this->getOutDocVersioning(); + break; + case 13: + return $this->getOutDocDestinationPath(); + break; + case 14: + return $this->getOutDocTags(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = OutputDocumentPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getOutDocUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getOutDocLandscape(), + $keys[3] => $this->getOutDocMedia(), + $keys[4] => $this->getOutDocLeftMargin(), + $keys[5] => $this->getOutDocRightMargin(), + $keys[6] => $this->getOutDocTopMargin(), + $keys[7] => $this->getOutDocBottomMargin(), + $keys[8] => $this->getOutDocGenerate(), + $keys[9] => $this->getOutDocType(), + $keys[10] => $this->getOutDocCurrentRevision(), + $keys[11] => $this->getOutDocFieldMapping(), + $keys[12] => $this->getOutDocVersioning(), + $keys[13] => $this->getOutDocDestinationPath(), + $keys[14] => $this->getOutDocTags(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = OutputDocumentPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setOutDocUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setOutDocLandscape($value); + break; + case 3: + $this->setOutDocMedia($value); + break; + case 4: + $this->setOutDocLeftMargin($value); + break; + case 5: + $this->setOutDocRightMargin($value); + break; + case 6: + $this->setOutDocTopMargin($value); + break; + case 7: + $this->setOutDocBottomMargin($value); + break; + case 8: + $this->setOutDocGenerate($value); + break; + case 9: + $this->setOutDocType($value); + break; + case 10: + $this->setOutDocCurrentRevision($value); + break; + case 11: + $this->setOutDocFieldMapping($value); + break; + case 12: + $this->setOutDocVersioning($value); + break; + case 13: + $this->setOutDocDestinationPath($value); + break; + case 14: + $this->setOutDocTags($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = OutputDocumentPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setOutDocUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setOutDocLandscape($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setOutDocMedia($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setOutDocLeftMargin($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setOutDocRightMargin($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setOutDocTopMargin($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setOutDocBottomMargin($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setOutDocGenerate($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setOutDocType($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setOutDocCurrentRevision($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setOutDocFieldMapping($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setOutDocVersioning($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setOutDocDestinationPath($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setOutDocTags($arr[$keys[14]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(OutputDocumentPeer::DATABASE_NAME); + + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_UID)) $criteria->add(OutputDocumentPeer::OUT_DOC_UID, $this->out_doc_uid); + if ($this->isColumnModified(OutputDocumentPeer::PRO_UID)) $criteria->add(OutputDocumentPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_LANDSCAPE)) $criteria->add(OutputDocumentPeer::OUT_DOC_LANDSCAPE, $this->out_doc_landscape); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_MEDIA)) $criteria->add(OutputDocumentPeer::OUT_DOC_MEDIA, $this->out_doc_media); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_LEFT_MARGIN)) $criteria->add(OutputDocumentPeer::OUT_DOC_LEFT_MARGIN, $this->out_doc_left_margin); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN)) $criteria->add(OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN, $this->out_doc_right_margin); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_TOP_MARGIN)) $criteria->add(OutputDocumentPeer::OUT_DOC_TOP_MARGIN, $this->out_doc_top_margin); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN)) $criteria->add(OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN, $this->out_doc_bottom_margin); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_GENERATE)) $criteria->add(OutputDocumentPeer::OUT_DOC_GENERATE, $this->out_doc_generate); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_TYPE)) $criteria->add(OutputDocumentPeer::OUT_DOC_TYPE, $this->out_doc_type); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_CURRENT_REVISION)) $criteria->add(OutputDocumentPeer::OUT_DOC_CURRENT_REVISION, $this->out_doc_current_revision); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_FIELD_MAPPING)) $criteria->add(OutputDocumentPeer::OUT_DOC_FIELD_MAPPING, $this->out_doc_field_mapping); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_VERSIONING)) $criteria->add(OutputDocumentPeer::OUT_DOC_VERSIONING, $this->out_doc_versioning); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_DESTINATION_PATH)) $criteria->add(OutputDocumentPeer::OUT_DOC_DESTINATION_PATH, $this->out_doc_destination_path); + if ($this->isColumnModified(OutputDocumentPeer::OUT_DOC_TAGS)) $criteria->add(OutputDocumentPeer::OUT_DOC_TAGS, $this->out_doc_tags); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(OutputDocumentPeer::DATABASE_NAME); + + $criteria->add(OutputDocumentPeer::OUT_DOC_UID, $this->out_doc_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getOutDocUid(); + } + + /** + * Generic method to set the primary key (out_doc_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setOutDocUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of OutputDocument (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setOutDocLandscape($this->out_doc_landscape); + + $copyObj->setOutDocMedia($this->out_doc_media); + + $copyObj->setOutDocLeftMargin($this->out_doc_left_margin); + + $copyObj->setOutDocRightMargin($this->out_doc_right_margin); + + $copyObj->setOutDocTopMargin($this->out_doc_top_margin); + + $copyObj->setOutDocBottomMargin($this->out_doc_bottom_margin); + + $copyObj->setOutDocGenerate($this->out_doc_generate); + + $copyObj->setOutDocType($this->out_doc_type); + + $copyObj->setOutDocCurrentRevision($this->out_doc_current_revision); + + $copyObj->setOutDocFieldMapping($this->out_doc_field_mapping); + + $copyObj->setOutDocVersioning($this->out_doc_versioning); + + $copyObj->setOutDocDestinationPath($this->out_doc_destination_path); + + $copyObj->setOutDocTags($this->out_doc_tags); + + + $copyObj->setNew(true); + + $copyObj->setOutDocUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return OutputDocument Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return OutputDocumentPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new OutputDocumentPeer(); + } + return self::$peer; + } + +} // BaseOutputDocument diff --git a/workflow/engine/classes/model/om/BaseOutputDocumentPeer.php b/workflow/engine/classes/model/om/BaseOutputDocumentPeer.php new file mode 100644 index 000000000..faa0f00c4 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseOutputDocumentPeer.php @@ -0,0 +1,647 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by OutputDocumentPeer::getOMClass() +include_once 'classes/model/OutputDocument.php'; + +/** + * Base static class for performing query and update operations on the 'OUTPUT_DOCUMENT' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseOutputDocumentPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'OUTPUT_DOCUMENT'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.OutputDocument'; + + /** The total number of columns. */ + const NUM_COLUMNS = 15; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the OUT_DOC_UID field */ + const OUT_DOC_UID = 'OUTPUT_DOCUMENT.OUT_DOC_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'OUTPUT_DOCUMENT.PRO_UID'; + + /** the column name for the OUT_DOC_LANDSCAPE field */ + const OUT_DOC_LANDSCAPE = 'OUTPUT_DOCUMENT.OUT_DOC_LANDSCAPE'; + + /** the column name for the OUT_DOC_MEDIA field */ + const OUT_DOC_MEDIA = 'OUTPUT_DOCUMENT.OUT_DOC_MEDIA'; + + /** the column name for the OUT_DOC_LEFT_MARGIN field */ + const OUT_DOC_LEFT_MARGIN = 'OUTPUT_DOCUMENT.OUT_DOC_LEFT_MARGIN'; + + /** the column name for the OUT_DOC_RIGHT_MARGIN field */ + const OUT_DOC_RIGHT_MARGIN = 'OUTPUT_DOCUMENT.OUT_DOC_RIGHT_MARGIN'; + + /** the column name for the OUT_DOC_TOP_MARGIN field */ + const OUT_DOC_TOP_MARGIN = 'OUTPUT_DOCUMENT.OUT_DOC_TOP_MARGIN'; + + /** the column name for the OUT_DOC_BOTTOM_MARGIN field */ + const OUT_DOC_BOTTOM_MARGIN = 'OUTPUT_DOCUMENT.OUT_DOC_BOTTOM_MARGIN'; + + /** the column name for the OUT_DOC_GENERATE field */ + const OUT_DOC_GENERATE = 'OUTPUT_DOCUMENT.OUT_DOC_GENERATE'; + + /** the column name for the OUT_DOC_TYPE field */ + const OUT_DOC_TYPE = 'OUTPUT_DOCUMENT.OUT_DOC_TYPE'; + + /** the column name for the OUT_DOC_CURRENT_REVISION field */ + const OUT_DOC_CURRENT_REVISION = 'OUTPUT_DOCUMENT.OUT_DOC_CURRENT_REVISION'; + + /** the column name for the OUT_DOC_FIELD_MAPPING field */ + const OUT_DOC_FIELD_MAPPING = 'OUTPUT_DOCUMENT.OUT_DOC_FIELD_MAPPING'; + + /** the column name for the OUT_DOC_VERSIONING field */ + const OUT_DOC_VERSIONING = 'OUTPUT_DOCUMENT.OUT_DOC_VERSIONING'; + + /** the column name for the OUT_DOC_DESTINATION_PATH field */ + const OUT_DOC_DESTINATION_PATH = 'OUTPUT_DOCUMENT.OUT_DOC_DESTINATION_PATH'; + + /** the column name for the OUT_DOC_TAGS field */ + const OUT_DOC_TAGS = 'OUTPUT_DOCUMENT.OUT_DOC_TAGS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('OutDocUid', 'ProUid', 'OutDocLandscape', 'OutDocMedia', 'OutDocLeftMargin', 'OutDocRightMargin', 'OutDocTopMargin', 'OutDocBottomMargin', 'OutDocGenerate', 'OutDocType', 'OutDocCurrentRevision', 'OutDocFieldMapping', 'OutDocVersioning', 'OutDocDestinationPath', 'OutDocTags', ), + BasePeer::TYPE_COLNAME => array (OutputDocumentPeer::OUT_DOC_UID, OutputDocumentPeer::PRO_UID, OutputDocumentPeer::OUT_DOC_LANDSCAPE, OutputDocumentPeer::OUT_DOC_MEDIA, OutputDocumentPeer::OUT_DOC_LEFT_MARGIN, OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN, OutputDocumentPeer::OUT_DOC_TOP_MARGIN, OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN, OutputDocumentPeer::OUT_DOC_GENERATE, OutputDocumentPeer::OUT_DOC_TYPE, OutputDocumentPeer::OUT_DOC_CURRENT_REVISION, OutputDocumentPeer::OUT_DOC_FIELD_MAPPING, OutputDocumentPeer::OUT_DOC_VERSIONING, OutputDocumentPeer::OUT_DOC_DESTINATION_PATH, OutputDocumentPeer::OUT_DOC_TAGS, ), + BasePeer::TYPE_FIELDNAME => array ('OUT_DOC_UID', 'PRO_UID', 'OUT_DOC_LANDSCAPE', 'OUT_DOC_MEDIA', 'OUT_DOC_LEFT_MARGIN', 'OUT_DOC_RIGHT_MARGIN', 'OUT_DOC_TOP_MARGIN', 'OUT_DOC_BOTTOM_MARGIN', 'OUT_DOC_GENERATE', 'OUT_DOC_TYPE', 'OUT_DOC_CURRENT_REVISION', 'OUT_DOC_FIELD_MAPPING', 'OUT_DOC_VERSIONING', 'OUT_DOC_DESTINATION_PATH', 'OUT_DOC_TAGS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('OutDocUid' => 0, 'ProUid' => 1, 'OutDocLandscape' => 2, 'OutDocMedia' => 3, 'OutDocLeftMargin' => 4, 'OutDocRightMargin' => 5, 'OutDocTopMargin' => 6, 'OutDocBottomMargin' => 7, 'OutDocGenerate' => 8, 'OutDocType' => 9, 'OutDocCurrentRevision' => 10, 'OutDocFieldMapping' => 11, 'OutDocVersioning' => 12, 'OutDocDestinationPath' => 13, 'OutDocTags' => 14, ), + BasePeer::TYPE_COLNAME => array (OutputDocumentPeer::OUT_DOC_UID => 0, OutputDocumentPeer::PRO_UID => 1, OutputDocumentPeer::OUT_DOC_LANDSCAPE => 2, OutputDocumentPeer::OUT_DOC_MEDIA => 3, OutputDocumentPeer::OUT_DOC_LEFT_MARGIN => 4, OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN => 5, OutputDocumentPeer::OUT_DOC_TOP_MARGIN => 6, OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN => 7, OutputDocumentPeer::OUT_DOC_GENERATE => 8, OutputDocumentPeer::OUT_DOC_TYPE => 9, OutputDocumentPeer::OUT_DOC_CURRENT_REVISION => 10, OutputDocumentPeer::OUT_DOC_FIELD_MAPPING => 11, OutputDocumentPeer::OUT_DOC_VERSIONING => 12, OutputDocumentPeer::OUT_DOC_DESTINATION_PATH => 13, OutputDocumentPeer::OUT_DOC_TAGS => 14, ), + BasePeer::TYPE_FIELDNAME => array ('OUT_DOC_UID' => 0, 'PRO_UID' => 1, 'OUT_DOC_LANDSCAPE' => 2, 'OUT_DOC_MEDIA' => 3, 'OUT_DOC_LEFT_MARGIN' => 4, 'OUT_DOC_RIGHT_MARGIN' => 5, 'OUT_DOC_TOP_MARGIN' => 6, 'OUT_DOC_BOTTOM_MARGIN' => 7, 'OUT_DOC_GENERATE' => 8, 'OUT_DOC_TYPE' => 9, 'OUT_DOC_CURRENT_REVISION' => 10, 'OUT_DOC_FIELD_MAPPING' => 11, 'OUT_DOC_VERSIONING' => 12, 'OUT_DOC_DESTINATION_PATH' => 13, 'OUT_DOC_TAGS' => 14, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/OutputDocumentMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.OutputDocumentMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = OutputDocumentPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. OutputDocumentPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(OutputDocumentPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_UID); + + $criteria->addSelectColumn(OutputDocumentPeer::PRO_UID); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_LANDSCAPE); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_MEDIA); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_LEFT_MARGIN); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_RIGHT_MARGIN); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_TOP_MARGIN); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_BOTTOM_MARGIN); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_GENERATE); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_TYPE); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_CURRENT_REVISION); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_FIELD_MAPPING); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_VERSIONING); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_DESTINATION_PATH); + + $criteria->addSelectColumn(OutputDocumentPeer::OUT_DOC_TAGS); + + } + + const COUNT = 'COUNT(OUTPUT_DOCUMENT.OUT_DOC_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT OUTPUT_DOCUMENT.OUT_DOC_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(OutputDocumentPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(OutputDocumentPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = OutputDocumentPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return OutputDocument + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = OutputDocumentPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return OutputDocumentPeer::populateObjects(OutputDocumentPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + OutputDocumentPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = OutputDocumentPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return OutputDocumentPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a OutputDocument or Criteria object. + * + * @param mixed $values Criteria or OutputDocument object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from OutputDocument object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a OutputDocument or Criteria object. + * + * @param mixed $values Criteria or OutputDocument object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(OutputDocumentPeer::OUT_DOC_UID); + $selectCriteria->add(OutputDocumentPeer::OUT_DOC_UID, $criteria->remove(OutputDocumentPeer::OUT_DOC_UID), $comparison); + + } else { // $values is OutputDocument object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the OUTPUT_DOCUMENT table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(OutputDocumentPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a OutputDocument or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or OutputDocument object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(OutputDocumentPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof OutputDocument) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(OutputDocumentPeer::OUT_DOC_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given OutputDocument object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param OutputDocument $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(OutputDocument $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(OutputDocumentPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(OutputDocumentPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(OutputDocumentPeer::OUT_DOC_UID)) + $columns[OutputDocumentPeer::OUT_DOC_UID] = $obj->getOutDocUid(); + + if ($obj->isNew() || $obj->isColumnModified(OutputDocumentPeer::PRO_UID)) + $columns[OutputDocumentPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(OutputDocumentPeer::OUT_DOC_GENERATE)) + $columns[OutputDocumentPeer::OUT_DOC_GENERATE] = $obj->getOutDocGenerate(); + + if ($obj->isNew() || $obj->isColumnModified(OutputDocumentPeer::OUT_DOC_TYPE)) + $columns[OutputDocumentPeer::OUT_DOC_TYPE] = $obj->getOutDocType(); + + } + + return BasePeer::doValidate(OutputDocumentPeer::DATABASE_NAME, OutputDocumentPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return OutputDocument + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(OutputDocumentPeer::DATABASE_NAME); + + $criteria->add(OutputDocumentPeer::OUT_DOC_UID, $pk); + + + $v = OutputDocumentPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(OutputDocumentPeer::OUT_DOC_UID, $pks, Criteria::IN); + $objs = OutputDocumentPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseOutputDocumentPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseOutputDocumentPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/OutputDocumentMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.OutputDocumentMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseProcess.php b/workflow/engine/classes/model/om/BaseProcess.php new file mode 100644 index 000000000..4a1bb67eb --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcess.php @@ -0,0 +1,1708 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ProcessPeer.php'; + +/** + * Base class that represents a row from the 'PROCESS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcess extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ProcessPeer + */ + protected static $peer; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the pro_parent field. + * @var string + */ + protected $pro_parent = '0'; + + + /** + * The value for the pro_time field. + * @var double + */ + protected $pro_time = 1; + + + /** + * The value for the pro_timeunit field. + * @var string + */ + protected $pro_timeunit = 'DAYS'; + + + /** + * The value for the pro_status field. + * @var string + */ + protected $pro_status = 'ACTIVE'; + + + /** + * The value for the pro_type_day field. + * @var string + */ + protected $pro_type_day = '0'; + + + /** + * The value for the pro_type field. + * @var string + */ + protected $pro_type = 'NORMAL'; + + + /** + * The value for the pro_assignment field. + * @var string + */ + protected $pro_assignment = 'FALSE'; + + + /** + * The value for the pro_show_map field. + * @var int + */ + protected $pro_show_map = 1; + + + /** + * The value for the pro_show_message field. + * @var int + */ + protected $pro_show_message = 1; + + + /** + * The value for the pro_show_delegate field. + * @var int + */ + protected $pro_show_delegate = 1; + + + /** + * The value for the pro_show_dynaform field. + * @var int + */ + protected $pro_show_dynaform = 0; + + + /** + * The value for the pro_category field. + * @var string + */ + protected $pro_category = ''; + + + /** + * The value for the pro_sub_category field. + * @var string + */ + protected $pro_sub_category = ''; + + + /** + * The value for the pro_industry field. + * @var int + */ + protected $pro_industry = 1; + + + /** + * The value for the pro_update_date field. + * @var int + */ + protected $pro_update_date; + + + /** + * The value for the pro_create_date field. + * @var int + */ + protected $pro_create_date; + + + /** + * The value for the pro_create_user field. + * @var string + */ + protected $pro_create_user = ''; + + + /** + * The value for the pro_height field. + * @var int + */ + protected $pro_height = 5000; + + + /** + * The value for the pro_width field. + * @var int + */ + protected $pro_width = 10000; + + + /** + * The value for the pro_title_x field. + * @var int + */ + protected $pro_title_x = 0; + + + /** + * The value for the pro_title_y field. + * @var int + */ + protected $pro_title_y = 6; + + + /** + * The value for the pro_debug field. + * @var int + */ + protected $pro_debug = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [pro_parent] column value. + * + * @return string + */ + public function getProParent() + { + + return $this->pro_parent; + } + + /** + * Get the [pro_time] column value. + * + * @return double + */ + public function getProTime() + { + + return $this->pro_time; + } + + /** + * Get the [pro_timeunit] column value. + * + * @return string + */ + public function getProTimeunit() + { + + return $this->pro_timeunit; + } + + /** + * Get the [pro_status] column value. + * + * @return string + */ + public function getProStatus() + { + + return $this->pro_status; + } + + /** + * Get the [pro_type_day] column value. + * + * @return string + */ + public function getProTypeDay() + { + + return $this->pro_type_day; + } + + /** + * Get the [pro_type] column value. + * + * @return string + */ + public function getProType() + { + + return $this->pro_type; + } + + /** + * Get the [pro_assignment] column value. + * + * @return string + */ + public function getProAssignment() + { + + return $this->pro_assignment; + } + + /** + * Get the [pro_show_map] column value. + * + * @return int + */ + public function getProShowMap() + { + + return $this->pro_show_map; + } + + /** + * Get the [pro_show_message] column value. + * + * @return int + */ + public function getProShowMessage() + { + + return $this->pro_show_message; + } + + /** + * Get the [pro_show_delegate] column value. + * + * @return int + */ + public function getProShowDelegate() + { + + return $this->pro_show_delegate; + } + + /** + * Get the [pro_show_dynaform] column value. + * + * @return int + */ + public function getProShowDynaform() + { + + return $this->pro_show_dynaform; + } + + /** + * Get the [pro_category] column value. + * + * @return string + */ + public function getProCategory() + { + + return $this->pro_category; + } + + /** + * Get the [pro_sub_category] column value. + * + * @return string + */ + public function getProSubCategory() + { + + return $this->pro_sub_category; + } + + /** + * Get the [pro_industry] column value. + * + * @return int + */ + public function getProIndustry() + { + + return $this->pro_industry; + } + + /** + * Get the [optionally formatted] [pro_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getProUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->pro_update_date === null || $this->pro_update_date === '') { + return null; + } elseif (!is_int($this->pro_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->pro_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [pro_update_date] as date/time value: " . var_export($this->pro_update_date, true)); + } + } else { + $ts = $this->pro_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [pro_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getProCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->pro_create_date === null || $this->pro_create_date === '') { + return null; + } elseif (!is_int($this->pro_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->pro_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [pro_create_date] as date/time value: " . var_export($this->pro_create_date, true)); + } + } else { + $ts = $this->pro_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [pro_create_user] column value. + * + * @return string + */ + public function getProCreateUser() + { + + return $this->pro_create_user; + } + + /** + * Get the [pro_height] column value. + * + * @return int + */ + public function getProHeight() + { + + return $this->pro_height; + } + + /** + * Get the [pro_width] column value. + * + * @return int + */ + public function getProWidth() + { + + return $this->pro_width; + } + + /** + * Get the [pro_title_x] column value. + * + * @return int + */ + public function getProTitleX() + { + + return $this->pro_title_x; + } + + /** + * Get the [pro_title_y] column value. + * + * @return int + */ + public function getProTitleY() + { + + return $this->pro_title_y; + } + + /** + * Get the [pro_debug] column value. + * + * @return int + */ + public function getProDebug() + { + + return $this->pro_debug; + } + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [pro_parent] column. + * + * @param string $v new value + * @return void + */ + public function setProParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_parent !== $v || $v === '0') { + $this->pro_parent = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_PARENT; + } + + } // setProParent() + + /** + * Set the value of [pro_time] column. + * + * @param double $v new value + * @return void + */ + public function setProTime($v) + { + + if ($this->pro_time !== $v || $v === 1) { + $this->pro_time = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TIME; + } + + } // setProTime() + + /** + * Set the value of [pro_timeunit] column. + * + * @param string $v new value + * @return void + */ + public function setProTimeunit($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_timeunit !== $v || $v === 'DAYS') { + $this->pro_timeunit = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TIMEUNIT; + } + + } // setProTimeunit() + + /** + * Set the value of [pro_status] column. + * + * @param string $v new value + * @return void + */ + public function setProStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_status !== $v || $v === 'ACTIVE') { + $this->pro_status = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_STATUS; + } + + } // setProStatus() + + /** + * Set the value of [pro_type_day] column. + * + * @param string $v new value + * @return void + */ + public function setProTypeDay($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_type_day !== $v || $v === '0') { + $this->pro_type_day = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TYPE_DAY; + } + + } // setProTypeDay() + + /** + * Set the value of [pro_type] column. + * + * @param string $v new value + * @return void + */ + public function setProType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_type !== $v || $v === 'NORMAL') { + $this->pro_type = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TYPE; + } + + } // setProType() + + /** + * Set the value of [pro_assignment] column. + * + * @param string $v new value + * @return void + */ + public function setProAssignment($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_assignment !== $v || $v === 'FALSE') { + $this->pro_assignment = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_ASSIGNMENT; + } + + } // setProAssignment() + + /** + * Set the value of [pro_show_map] column. + * + * @param int $v new value + * @return void + */ + public function setProShowMap($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_show_map !== $v || $v === 1) { + $this->pro_show_map = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_SHOW_MAP; + } + + } // setProShowMap() + + /** + * Set the value of [pro_show_message] column. + * + * @param int $v new value + * @return void + */ + public function setProShowMessage($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_show_message !== $v || $v === 1) { + $this->pro_show_message = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_SHOW_MESSAGE; + } + + } // setProShowMessage() + + /** + * Set the value of [pro_show_delegate] column. + * + * @param int $v new value + * @return void + */ + public function setProShowDelegate($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_show_delegate !== $v || $v === 1) { + $this->pro_show_delegate = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_SHOW_DELEGATE; + } + + } // setProShowDelegate() + + /** + * Set the value of [pro_show_dynaform] column. + * + * @param int $v new value + * @return void + */ + public function setProShowDynaform($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_show_dynaform !== $v || $v === 0) { + $this->pro_show_dynaform = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_SHOW_DYNAFORM; + } + + } // setProShowDynaform() + + /** + * Set the value of [pro_category] column. + * + * @param string $v new value + * @return void + */ + public function setProCategory($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_category !== $v || $v === '') { + $this->pro_category = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_CATEGORY; + } + + } // setProCategory() + + /** + * Set the value of [pro_sub_category] column. + * + * @param string $v new value + * @return void + */ + public function setProSubCategory($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_sub_category !== $v || $v === '') { + $this->pro_sub_category = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_SUB_CATEGORY; + } + + } // setProSubCategory() + + /** + * Set the value of [pro_industry] column. + * + * @param int $v new value + * @return void + */ + public function setProIndustry($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_industry !== $v || $v === 1) { + $this->pro_industry = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_INDUSTRY; + } + + } // setProIndustry() + + /** + * Set the value of [pro_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setProUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [pro_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->pro_update_date !== $ts) { + $this->pro_update_date = $ts; + $this->modifiedColumns[] = ProcessPeer::PRO_UPDATE_DATE; + } + + } // setProUpdateDate() + + /** + * Set the value of [pro_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setProCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [pro_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->pro_create_date !== $ts) { + $this->pro_create_date = $ts; + $this->modifiedColumns[] = ProcessPeer::PRO_CREATE_DATE; + } + + } // setProCreateDate() + + /** + * Set the value of [pro_create_user] column. + * + * @param string $v new value + * @return void + */ + public function setProCreateUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_create_user !== $v || $v === '') { + $this->pro_create_user = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_CREATE_USER; + } + + } // setProCreateUser() + + /** + * Set the value of [pro_height] column. + * + * @param int $v new value + * @return void + */ + public function setProHeight($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_height !== $v || $v === 5000) { + $this->pro_height = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_HEIGHT; + } + + } // setProHeight() + + /** + * Set the value of [pro_width] column. + * + * @param int $v new value + * @return void + */ + public function setProWidth($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_width !== $v || $v === 10000) { + $this->pro_width = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_WIDTH; + } + + } // setProWidth() + + /** + * Set the value of [pro_title_x] column. + * + * @param int $v new value + * @return void + */ + public function setProTitleX($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_title_x !== $v || $v === 0) { + $this->pro_title_x = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TITLE_X; + } + + } // setProTitleX() + + /** + * Set the value of [pro_title_y] column. + * + * @param int $v new value + * @return void + */ + public function setProTitleY($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_title_y !== $v || $v === 6) { + $this->pro_title_y = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_TITLE_Y; + } + + } // setProTitleY() + + /** + * Set the value of [pro_debug] column. + * + * @param int $v new value + * @return void + */ + public function setProDebug($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->pro_debug !== $v || $v === 0) { + $this->pro_debug = $v; + $this->modifiedColumns[] = ProcessPeer::PRO_DEBUG; + } + + } // setProDebug() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->pro_uid = $rs->getString($startcol + 0); + + $this->pro_parent = $rs->getString($startcol + 1); + + $this->pro_time = $rs->getFloat($startcol + 2); + + $this->pro_timeunit = $rs->getString($startcol + 3); + + $this->pro_status = $rs->getString($startcol + 4); + + $this->pro_type_day = $rs->getString($startcol + 5); + + $this->pro_type = $rs->getString($startcol + 6); + + $this->pro_assignment = $rs->getString($startcol + 7); + + $this->pro_show_map = $rs->getInt($startcol + 8); + + $this->pro_show_message = $rs->getInt($startcol + 9); + + $this->pro_show_delegate = $rs->getInt($startcol + 10); + + $this->pro_show_dynaform = $rs->getInt($startcol + 11); + + $this->pro_category = $rs->getString($startcol + 12); + + $this->pro_sub_category = $rs->getString($startcol + 13); + + $this->pro_industry = $rs->getInt($startcol + 14); + + $this->pro_update_date = $rs->getTimestamp($startcol + 15, null); + + $this->pro_create_date = $rs->getTimestamp($startcol + 16, null); + + $this->pro_create_user = $rs->getString($startcol + 17); + + $this->pro_height = $rs->getInt($startcol + 18); + + $this->pro_width = $rs->getInt($startcol + 19); + + $this->pro_title_x = $rs->getInt($startcol + 20); + + $this->pro_title_y = $rs->getInt($startcol + 21); + + $this->pro_debug = $rs->getInt($startcol + 22); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 23; // 23 = ProcessPeer::NUM_COLUMNS - ProcessPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Process object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ProcessPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ProcessPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ProcessPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ProcessPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getProUid(); + break; + case 1: + return $this->getProParent(); + break; + case 2: + return $this->getProTime(); + break; + case 3: + return $this->getProTimeunit(); + break; + case 4: + return $this->getProStatus(); + break; + case 5: + return $this->getProTypeDay(); + break; + case 6: + return $this->getProType(); + break; + case 7: + return $this->getProAssignment(); + break; + case 8: + return $this->getProShowMap(); + break; + case 9: + return $this->getProShowMessage(); + break; + case 10: + return $this->getProShowDelegate(); + break; + case 11: + return $this->getProShowDynaform(); + break; + case 12: + return $this->getProCategory(); + break; + case 13: + return $this->getProSubCategory(); + break; + case 14: + return $this->getProIndustry(); + break; + case 15: + return $this->getProUpdateDate(); + break; + case 16: + return $this->getProCreateDate(); + break; + case 17: + return $this->getProCreateUser(); + break; + case 18: + return $this->getProHeight(); + break; + case 19: + return $this->getProWidth(); + break; + case 20: + return $this->getProTitleX(); + break; + case 21: + return $this->getProTitleY(); + break; + case 22: + return $this->getProDebug(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getProUid(), + $keys[1] => $this->getProParent(), + $keys[2] => $this->getProTime(), + $keys[3] => $this->getProTimeunit(), + $keys[4] => $this->getProStatus(), + $keys[5] => $this->getProTypeDay(), + $keys[6] => $this->getProType(), + $keys[7] => $this->getProAssignment(), + $keys[8] => $this->getProShowMap(), + $keys[9] => $this->getProShowMessage(), + $keys[10] => $this->getProShowDelegate(), + $keys[11] => $this->getProShowDynaform(), + $keys[12] => $this->getProCategory(), + $keys[13] => $this->getProSubCategory(), + $keys[14] => $this->getProIndustry(), + $keys[15] => $this->getProUpdateDate(), + $keys[16] => $this->getProCreateDate(), + $keys[17] => $this->getProCreateUser(), + $keys[18] => $this->getProHeight(), + $keys[19] => $this->getProWidth(), + $keys[20] => $this->getProTitleX(), + $keys[21] => $this->getProTitleY(), + $keys[22] => $this->getProDebug(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setProUid($value); + break; + case 1: + $this->setProParent($value); + break; + case 2: + $this->setProTime($value); + break; + case 3: + $this->setProTimeunit($value); + break; + case 4: + $this->setProStatus($value); + break; + case 5: + $this->setProTypeDay($value); + break; + case 6: + $this->setProType($value); + break; + case 7: + $this->setProAssignment($value); + break; + case 8: + $this->setProShowMap($value); + break; + case 9: + $this->setProShowMessage($value); + break; + case 10: + $this->setProShowDelegate($value); + break; + case 11: + $this->setProShowDynaform($value); + break; + case 12: + $this->setProCategory($value); + break; + case 13: + $this->setProSubCategory($value); + break; + case 14: + $this->setProIndustry($value); + break; + case 15: + $this->setProUpdateDate($value); + break; + case 16: + $this->setProCreateDate($value); + break; + case 17: + $this->setProCreateUser($value); + break; + case 18: + $this->setProHeight($value); + break; + case 19: + $this->setProWidth($value); + break; + case 20: + $this->setProTitleX($value); + break; + case 21: + $this->setProTitleY($value); + break; + case 22: + $this->setProDebug($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setProUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setProTime($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setProTimeunit($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setProStatus($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setProTypeDay($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setProType($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setProAssignment($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setProShowMap($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setProShowMessage($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setProShowDelegate($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setProShowDynaform($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setProCategory($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setProSubCategory($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setProIndustry($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setProUpdateDate($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setProCreateDate($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setProCreateUser($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setProHeight($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setProWidth($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setProTitleX($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setProTitleY($arr[$keys[21]]); + if (array_key_exists($keys[22], $arr)) $this->setProDebug($arr[$keys[22]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProcessPeer::DATABASE_NAME); + + if ($this->isColumnModified(ProcessPeer::PRO_UID)) $criteria->add(ProcessPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ProcessPeer::PRO_PARENT)) $criteria->add(ProcessPeer::PRO_PARENT, $this->pro_parent); + if ($this->isColumnModified(ProcessPeer::PRO_TIME)) $criteria->add(ProcessPeer::PRO_TIME, $this->pro_time); + if ($this->isColumnModified(ProcessPeer::PRO_TIMEUNIT)) $criteria->add(ProcessPeer::PRO_TIMEUNIT, $this->pro_timeunit); + if ($this->isColumnModified(ProcessPeer::PRO_STATUS)) $criteria->add(ProcessPeer::PRO_STATUS, $this->pro_status); + if ($this->isColumnModified(ProcessPeer::PRO_TYPE_DAY)) $criteria->add(ProcessPeer::PRO_TYPE_DAY, $this->pro_type_day); + if ($this->isColumnModified(ProcessPeer::PRO_TYPE)) $criteria->add(ProcessPeer::PRO_TYPE, $this->pro_type); + if ($this->isColumnModified(ProcessPeer::PRO_ASSIGNMENT)) $criteria->add(ProcessPeer::PRO_ASSIGNMENT, $this->pro_assignment); + if ($this->isColumnModified(ProcessPeer::PRO_SHOW_MAP)) $criteria->add(ProcessPeer::PRO_SHOW_MAP, $this->pro_show_map); + if ($this->isColumnModified(ProcessPeer::PRO_SHOW_MESSAGE)) $criteria->add(ProcessPeer::PRO_SHOW_MESSAGE, $this->pro_show_message); + if ($this->isColumnModified(ProcessPeer::PRO_SHOW_DELEGATE)) $criteria->add(ProcessPeer::PRO_SHOW_DELEGATE, $this->pro_show_delegate); + if ($this->isColumnModified(ProcessPeer::PRO_SHOW_DYNAFORM)) $criteria->add(ProcessPeer::PRO_SHOW_DYNAFORM, $this->pro_show_dynaform); + if ($this->isColumnModified(ProcessPeer::PRO_CATEGORY)) $criteria->add(ProcessPeer::PRO_CATEGORY, $this->pro_category); + if ($this->isColumnModified(ProcessPeer::PRO_SUB_CATEGORY)) $criteria->add(ProcessPeer::PRO_SUB_CATEGORY, $this->pro_sub_category); + if ($this->isColumnModified(ProcessPeer::PRO_INDUSTRY)) $criteria->add(ProcessPeer::PRO_INDUSTRY, $this->pro_industry); + if ($this->isColumnModified(ProcessPeer::PRO_UPDATE_DATE)) $criteria->add(ProcessPeer::PRO_UPDATE_DATE, $this->pro_update_date); + if ($this->isColumnModified(ProcessPeer::PRO_CREATE_DATE)) $criteria->add(ProcessPeer::PRO_CREATE_DATE, $this->pro_create_date); + if ($this->isColumnModified(ProcessPeer::PRO_CREATE_USER)) $criteria->add(ProcessPeer::PRO_CREATE_USER, $this->pro_create_user); + if ($this->isColumnModified(ProcessPeer::PRO_HEIGHT)) $criteria->add(ProcessPeer::PRO_HEIGHT, $this->pro_height); + if ($this->isColumnModified(ProcessPeer::PRO_WIDTH)) $criteria->add(ProcessPeer::PRO_WIDTH, $this->pro_width); + if ($this->isColumnModified(ProcessPeer::PRO_TITLE_X)) $criteria->add(ProcessPeer::PRO_TITLE_X, $this->pro_title_x); + if ($this->isColumnModified(ProcessPeer::PRO_TITLE_Y)) $criteria->add(ProcessPeer::PRO_TITLE_Y, $this->pro_title_y); + if ($this->isColumnModified(ProcessPeer::PRO_DEBUG)) $criteria->add(ProcessPeer::PRO_DEBUG, $this->pro_debug); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProcessPeer::DATABASE_NAME); + + $criteria->add(ProcessPeer::PRO_UID, $this->pro_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getProUid(); + } + + /** + * Generic method to set the primary key (pro_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setProUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Process (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProParent($this->pro_parent); + + $copyObj->setProTime($this->pro_time); + + $copyObj->setProTimeunit($this->pro_timeunit); + + $copyObj->setProStatus($this->pro_status); + + $copyObj->setProTypeDay($this->pro_type_day); + + $copyObj->setProType($this->pro_type); + + $copyObj->setProAssignment($this->pro_assignment); + + $copyObj->setProShowMap($this->pro_show_map); + + $copyObj->setProShowMessage($this->pro_show_message); + + $copyObj->setProShowDelegate($this->pro_show_delegate); + + $copyObj->setProShowDynaform($this->pro_show_dynaform); + + $copyObj->setProCategory($this->pro_category); + + $copyObj->setProSubCategory($this->pro_sub_category); + + $copyObj->setProIndustry($this->pro_industry); + + $copyObj->setProUpdateDate($this->pro_update_date); + + $copyObj->setProCreateDate($this->pro_create_date); + + $copyObj->setProCreateUser($this->pro_create_user); + + $copyObj->setProHeight($this->pro_height); + + $copyObj->setProWidth($this->pro_width); + + $copyObj->setProTitleX($this->pro_title_x); + + $copyObj->setProTitleY($this->pro_title_y); + + $copyObj->setProDebug($this->pro_debug); + + + $copyObj->setNew(true); + + $copyObj->setProUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Process Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ProcessPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ProcessPeer(); + } + return self::$peer; + } + +} // BaseProcess diff --git a/workflow/engine/classes/model/om/BaseProcessCategory.php b/workflow/engine/classes/model/om/BaseProcessCategory.php new file mode 100644 index 000000000..c3d420d10 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessCategory.php @@ -0,0 +1,663 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ProcessCategoryPeer.php'; + +/** + * Base class that represents a row from the 'PROCESS_CATEGORY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessCategory extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ProcessCategoryPeer + */ + protected static $peer; + + + /** + * The value for the category_uid field. + * @var string + */ + protected $category_uid = ''; + + + /** + * The value for the category_parent field. + * @var string + */ + protected $category_parent = '0'; + + + /** + * The value for the category_name field. + * @var string + */ + protected $category_name = ''; + + + /** + * The value for the category_icon field. + * @var string + */ + protected $category_icon = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [category_uid] column value. + * + * @return string + */ + public function getCategoryUid() + { + + return $this->category_uid; + } + + /** + * Get the [category_parent] column value. + * + * @return string + */ + public function getCategoryParent() + { + + return $this->category_parent; + } + + /** + * Get the [category_name] column value. + * + * @return string + */ + public function getCategoryName() + { + + return $this->category_name; + } + + /** + * Get the [category_icon] column value. + * + * @return string + */ + public function getCategoryIcon() + { + + return $this->category_icon; + } + + /** + * Set the value of [category_uid] column. + * + * @param string $v new value + * @return void + */ + public function setCategoryUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->category_uid !== $v || $v === '') { + $this->category_uid = $v; + $this->modifiedColumns[] = ProcessCategoryPeer::CATEGORY_UID; + } + + } // setCategoryUid() + + /** + * Set the value of [category_parent] column. + * + * @param string $v new value + * @return void + */ + public function setCategoryParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->category_parent !== $v || $v === '0') { + $this->category_parent = $v; + $this->modifiedColumns[] = ProcessCategoryPeer::CATEGORY_PARENT; + } + + } // setCategoryParent() + + /** + * Set the value of [category_name] column. + * + * @param string $v new value + * @return void + */ + public function setCategoryName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->category_name !== $v || $v === '') { + $this->category_name = $v; + $this->modifiedColumns[] = ProcessCategoryPeer::CATEGORY_NAME; + } + + } // setCategoryName() + + /** + * Set the value of [category_icon] column. + * + * @param string $v new value + * @return void + */ + public function setCategoryIcon($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->category_icon !== $v || $v === '') { + $this->category_icon = $v; + $this->modifiedColumns[] = ProcessCategoryPeer::CATEGORY_ICON; + } + + } // setCategoryIcon() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->category_uid = $rs->getString($startcol + 0); + + $this->category_parent = $rs->getString($startcol + 1); + + $this->category_name = $rs->getString($startcol + 2); + + $this->category_icon = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = ProcessCategoryPeer::NUM_COLUMNS - ProcessCategoryPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ProcessCategory object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessCategoryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ProcessCategoryPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessCategoryPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ProcessCategoryPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ProcessCategoryPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ProcessCategoryPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessCategoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getCategoryUid(); + break; + case 1: + return $this->getCategoryParent(); + break; + case 2: + return $this->getCategoryName(); + break; + case 3: + return $this->getCategoryIcon(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessCategoryPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getCategoryUid(), + $keys[1] => $this->getCategoryParent(), + $keys[2] => $this->getCategoryName(), + $keys[3] => $this->getCategoryIcon(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessCategoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setCategoryUid($value); + break; + case 1: + $this->setCategoryParent($value); + break; + case 2: + $this->setCategoryName($value); + break; + case 3: + $this->setCategoryIcon($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessCategoryPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setCategoryUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCategoryParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setCategoryName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCategoryIcon($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProcessCategoryPeer::DATABASE_NAME); + + if ($this->isColumnModified(ProcessCategoryPeer::CATEGORY_UID)) $criteria->add(ProcessCategoryPeer::CATEGORY_UID, $this->category_uid); + if ($this->isColumnModified(ProcessCategoryPeer::CATEGORY_PARENT)) $criteria->add(ProcessCategoryPeer::CATEGORY_PARENT, $this->category_parent); + if ($this->isColumnModified(ProcessCategoryPeer::CATEGORY_NAME)) $criteria->add(ProcessCategoryPeer::CATEGORY_NAME, $this->category_name); + if ($this->isColumnModified(ProcessCategoryPeer::CATEGORY_ICON)) $criteria->add(ProcessCategoryPeer::CATEGORY_ICON, $this->category_icon); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProcessCategoryPeer::DATABASE_NAME); + + $criteria->add(ProcessCategoryPeer::CATEGORY_UID, $this->category_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getCategoryUid(); + } + + /** + * Generic method to set the primary key (category_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setCategoryUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ProcessCategory (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setCategoryParent($this->category_parent); + + $copyObj->setCategoryName($this->category_name); + + $copyObj->setCategoryIcon($this->category_icon); + + + $copyObj->setNew(true); + + $copyObj->setCategoryUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ProcessCategory Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ProcessCategoryPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ProcessCategoryPeer(); + } + return self::$peer; + } + +} // BaseProcessCategory diff --git a/workflow/engine/classes/model/om/BaseProcessCategoryPeer.php b/workflow/engine/classes/model/om/BaseProcessCategoryPeer.php new file mode 100644 index 000000000..27f861d35 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessCategoryPeer.php @@ -0,0 +1,580 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ProcessCategoryPeer::getOMClass() +include_once 'classes/model/ProcessCategory.php'; + +/** + * Base static class for performing query and update operations on the 'PROCESS_CATEGORY' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessCategoryPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'PROCESS_CATEGORY'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ProcessCategory'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the CATEGORY_UID field */ + const CATEGORY_UID = 'PROCESS_CATEGORY.CATEGORY_UID'; + + /** the column name for the CATEGORY_PARENT field */ + const CATEGORY_PARENT = 'PROCESS_CATEGORY.CATEGORY_PARENT'; + + /** the column name for the CATEGORY_NAME field */ + const CATEGORY_NAME = 'PROCESS_CATEGORY.CATEGORY_NAME'; + + /** the column name for the CATEGORY_ICON field */ + const CATEGORY_ICON = 'PROCESS_CATEGORY.CATEGORY_ICON'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('CategoryUid', 'CategoryParent', 'CategoryName', 'CategoryIcon', ), + BasePeer::TYPE_COLNAME => array (ProcessCategoryPeer::CATEGORY_UID, ProcessCategoryPeer::CATEGORY_PARENT, ProcessCategoryPeer::CATEGORY_NAME, ProcessCategoryPeer::CATEGORY_ICON, ), + BasePeer::TYPE_FIELDNAME => array ('CATEGORY_UID', 'CATEGORY_PARENT', 'CATEGORY_NAME', 'CATEGORY_ICON', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('CategoryUid' => 0, 'CategoryParent' => 1, 'CategoryName' => 2, 'CategoryIcon' => 3, ), + BasePeer::TYPE_COLNAME => array (ProcessCategoryPeer::CATEGORY_UID => 0, ProcessCategoryPeer::CATEGORY_PARENT => 1, ProcessCategoryPeer::CATEGORY_NAME => 2, ProcessCategoryPeer::CATEGORY_ICON => 3, ), + BasePeer::TYPE_FIELDNAME => array ('CATEGORY_UID' => 0, 'CATEGORY_PARENT' => 1, 'CATEGORY_NAME' => 2, 'CATEGORY_ICON' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ProcessCategoryMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ProcessCategoryMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ProcessCategoryPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ProcessCategoryPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ProcessCategoryPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ProcessCategoryPeer::CATEGORY_UID); + + $criteria->addSelectColumn(ProcessCategoryPeer::CATEGORY_PARENT); + + $criteria->addSelectColumn(ProcessCategoryPeer::CATEGORY_NAME); + + $criteria->addSelectColumn(ProcessCategoryPeer::CATEGORY_ICON); + + } + + const COUNT = 'COUNT(PROCESS_CATEGORY.CATEGORY_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT PROCESS_CATEGORY.CATEGORY_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ProcessCategoryPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ProcessCategoryPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ProcessCategoryPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ProcessCategory + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ProcessCategoryPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ProcessCategoryPeer::populateObjects(ProcessCategoryPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ProcessCategoryPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ProcessCategoryPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ProcessCategoryPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ProcessCategory or Criteria object. + * + * @param mixed $values Criteria or ProcessCategory object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ProcessCategory object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ProcessCategory or Criteria object. + * + * @param mixed $values Criteria or ProcessCategory object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ProcessCategoryPeer::CATEGORY_UID); + $selectCriteria->add(ProcessCategoryPeer::CATEGORY_UID, $criteria->remove(ProcessCategoryPeer::CATEGORY_UID), $comparison); + + } else { // $values is ProcessCategory object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the PROCESS_CATEGORY table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ProcessCategoryPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ProcessCategory or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProcessCategory object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ProcessCategoryPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ProcessCategory) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ProcessCategoryPeer::CATEGORY_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ProcessCategory object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ProcessCategory $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ProcessCategory $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ProcessCategoryPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ProcessCategoryPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(ProcessCategoryPeer::DATABASE_NAME, ProcessCategoryPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ProcessCategory + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ProcessCategoryPeer::DATABASE_NAME); + + $criteria->add(ProcessCategoryPeer::CATEGORY_UID, $pk); + + + $v = ProcessCategoryPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ProcessCategoryPeer::CATEGORY_UID, $pks, Criteria::IN); + $objs = ProcessCategoryPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseProcessCategoryPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseProcessCategoryPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ProcessCategoryMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ProcessCategoryMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseProcessOwner.php b/workflow/engine/classes/model/om/BaseProcessOwner.php new file mode 100644 index 000000000..ee0231ea8 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessOwner.php @@ -0,0 +1,569 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ProcessOwnerPeer.php'; + +/** + * Base class that represents a row from the 'PROCESS_OWNER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessOwner extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ProcessOwnerPeer + */ + protected static $peer; + + + /** + * The value for the own_uid field. + * @var string + */ + protected $own_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [own_uid] column value. + * + * @return string + */ + public function getOwnUid() + { + + return $this->own_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Set the value of [own_uid] column. + * + * @param string $v new value + * @return void + */ + public function setOwnUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->own_uid !== $v || $v === '') { + $this->own_uid = $v; + $this->modifiedColumns[] = ProcessOwnerPeer::OWN_UID; + } + + } // setOwnUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ProcessOwnerPeer::PRO_UID; + } + + } // setProUid() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->own_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 2; // 2 = ProcessOwnerPeer::NUM_COLUMNS - ProcessOwnerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ProcessOwner object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessOwnerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ProcessOwnerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessOwnerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ProcessOwnerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ProcessOwnerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ProcessOwnerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessOwnerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getOwnUid(); + break; + case 1: + return $this->getProUid(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessOwnerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getOwnUid(), + $keys[1] => $this->getProUid(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessOwnerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setOwnUid($value); + break; + case 1: + $this->setProUid($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessOwnerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setOwnUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProcessOwnerPeer::DATABASE_NAME); + + if ($this->isColumnModified(ProcessOwnerPeer::OWN_UID)) $criteria->add(ProcessOwnerPeer::OWN_UID, $this->own_uid); + if ($this->isColumnModified(ProcessOwnerPeer::PRO_UID)) $criteria->add(ProcessOwnerPeer::PRO_UID, $this->pro_uid); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProcessOwnerPeer::DATABASE_NAME); + + $criteria->add(ProcessOwnerPeer::OWN_UID, $this->own_uid); + $criteria->add(ProcessOwnerPeer::PRO_UID, $this->pro_uid); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getOwnUid(); + + $pks[1] = $this->getProUid(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setOwnUid($keys[0]); + + $this->setProUid($keys[1]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ProcessOwner (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + + $copyObj->setNew(true); + + $copyObj->setOwnUid(''); // this is a pkey column, so set to default value + + $copyObj->setProUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ProcessOwner Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ProcessOwnerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ProcessOwnerPeer(); + } + return self::$peer; + } + +} // BaseProcessOwner diff --git a/workflow/engine/classes/model/om/BaseProcessOwnerPeer.php b/workflow/engine/classes/model/om/BaseProcessOwnerPeer.php new file mode 100644 index 000000000..095a3bda4 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessOwnerPeer.php @@ -0,0 +1,561 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ProcessOwnerPeer::getOMClass() +include_once 'classes/model/ProcessOwner.php'; + +/** + * Base static class for performing query and update operations on the 'PROCESS_OWNER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessOwnerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'PROCESS_OWNER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ProcessOwner'; + + /** The total number of columns. */ + const NUM_COLUMNS = 2; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the OWN_UID field */ + const OWN_UID = 'PROCESS_OWNER.OWN_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'PROCESS_OWNER.PRO_UID'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('OwnUid', 'ProUid', ), + BasePeer::TYPE_COLNAME => array (ProcessOwnerPeer::OWN_UID, ProcessOwnerPeer::PRO_UID, ), + BasePeer::TYPE_FIELDNAME => array ('OWN_UID', 'PRO_UID', ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('OwnUid' => 0, 'ProUid' => 1, ), + BasePeer::TYPE_COLNAME => array (ProcessOwnerPeer::OWN_UID => 0, ProcessOwnerPeer::PRO_UID => 1, ), + BasePeer::TYPE_FIELDNAME => array ('OWN_UID' => 0, 'PRO_UID' => 1, ), + BasePeer::TYPE_NUM => array (0, 1, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ProcessOwnerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ProcessOwnerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ProcessOwnerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ProcessOwnerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ProcessOwnerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ProcessOwnerPeer::OWN_UID); + + $criteria->addSelectColumn(ProcessOwnerPeer::PRO_UID); + + } + + const COUNT = 'COUNT(PROCESS_OWNER.OWN_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT PROCESS_OWNER.OWN_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ProcessOwnerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ProcessOwnerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ProcessOwnerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ProcessOwner + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ProcessOwnerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ProcessOwnerPeer::populateObjects(ProcessOwnerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ProcessOwnerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ProcessOwnerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ProcessOwnerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ProcessOwner or Criteria object. + * + * @param mixed $values Criteria or ProcessOwner object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ProcessOwner object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ProcessOwner or Criteria object. + * + * @param mixed $values Criteria or ProcessOwner object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ProcessOwnerPeer::OWN_UID); + $selectCriteria->add(ProcessOwnerPeer::OWN_UID, $criteria->remove(ProcessOwnerPeer::OWN_UID), $comparison); + + $comparison = $criteria->getComparison(ProcessOwnerPeer::PRO_UID); + $selectCriteria->add(ProcessOwnerPeer::PRO_UID, $criteria->remove(ProcessOwnerPeer::PRO_UID), $comparison); + + } else { // $values is ProcessOwner object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the PROCESS_OWNER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ProcessOwnerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ProcessOwner or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProcessOwner object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ProcessOwnerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ProcessOwner) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + } + + $criteria->add(ProcessOwnerPeer::OWN_UID, $vals[0], Criteria::IN); + $criteria->add(ProcessOwnerPeer::PRO_UID, $vals[1], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ProcessOwner object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ProcessOwner $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ProcessOwner $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ProcessOwnerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ProcessOwnerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(ProcessOwnerPeer::DATABASE_NAME, ProcessOwnerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $own_uid + @param string $pro_uid + + * @param Connection $con + * @return ProcessOwner + */ + public static function retrieveByPK( $own_uid, $pro_uid, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(ProcessOwnerPeer::OWN_UID, $own_uid); + $criteria->add(ProcessOwnerPeer::PRO_UID, $pro_uid); + $v = ProcessOwnerPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseProcessOwnerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseProcessOwnerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ProcessOwnerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ProcessOwnerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseProcessPeer.php b/workflow/engine/classes/model/om/BaseProcessPeer.php new file mode 100644 index 000000000..dae2f8c19 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessPeer.php @@ -0,0 +1,687 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ProcessPeer::getOMClass() +include_once 'classes/model/Process.php'; + +/** + * Base static class for performing query and update operations on the 'PROCESS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'PROCESS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Process'; + + /** The total number of columns. */ + const NUM_COLUMNS = 23; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the PRO_UID field */ + const PRO_UID = 'PROCESS.PRO_UID'; + + /** the column name for the PRO_PARENT field */ + const PRO_PARENT = 'PROCESS.PRO_PARENT'; + + /** the column name for the PRO_TIME field */ + const PRO_TIME = 'PROCESS.PRO_TIME'; + + /** the column name for the PRO_TIMEUNIT field */ + const PRO_TIMEUNIT = 'PROCESS.PRO_TIMEUNIT'; + + /** the column name for the PRO_STATUS field */ + const PRO_STATUS = 'PROCESS.PRO_STATUS'; + + /** the column name for the PRO_TYPE_DAY field */ + const PRO_TYPE_DAY = 'PROCESS.PRO_TYPE_DAY'; + + /** the column name for the PRO_TYPE field */ + const PRO_TYPE = 'PROCESS.PRO_TYPE'; + + /** the column name for the PRO_ASSIGNMENT field */ + const PRO_ASSIGNMENT = 'PROCESS.PRO_ASSIGNMENT'; + + /** the column name for the PRO_SHOW_MAP field */ + const PRO_SHOW_MAP = 'PROCESS.PRO_SHOW_MAP'; + + /** the column name for the PRO_SHOW_MESSAGE field */ + const PRO_SHOW_MESSAGE = 'PROCESS.PRO_SHOW_MESSAGE'; + + /** the column name for the PRO_SHOW_DELEGATE field */ + const PRO_SHOW_DELEGATE = 'PROCESS.PRO_SHOW_DELEGATE'; + + /** the column name for the PRO_SHOW_DYNAFORM field */ + const PRO_SHOW_DYNAFORM = 'PROCESS.PRO_SHOW_DYNAFORM'; + + /** the column name for the PRO_CATEGORY field */ + const PRO_CATEGORY = 'PROCESS.PRO_CATEGORY'; + + /** the column name for the PRO_SUB_CATEGORY field */ + const PRO_SUB_CATEGORY = 'PROCESS.PRO_SUB_CATEGORY'; + + /** the column name for the PRO_INDUSTRY field */ + const PRO_INDUSTRY = 'PROCESS.PRO_INDUSTRY'; + + /** the column name for the PRO_UPDATE_DATE field */ + const PRO_UPDATE_DATE = 'PROCESS.PRO_UPDATE_DATE'; + + /** the column name for the PRO_CREATE_DATE field */ + const PRO_CREATE_DATE = 'PROCESS.PRO_CREATE_DATE'; + + /** the column name for the PRO_CREATE_USER field */ + const PRO_CREATE_USER = 'PROCESS.PRO_CREATE_USER'; + + /** the column name for the PRO_HEIGHT field */ + const PRO_HEIGHT = 'PROCESS.PRO_HEIGHT'; + + /** the column name for the PRO_WIDTH field */ + const PRO_WIDTH = 'PROCESS.PRO_WIDTH'; + + /** the column name for the PRO_TITLE_X field */ + const PRO_TITLE_X = 'PROCESS.PRO_TITLE_X'; + + /** the column name for the PRO_TITLE_Y field */ + const PRO_TITLE_Y = 'PROCESS.PRO_TITLE_Y'; + + /** the column name for the PRO_DEBUG field */ + const PRO_DEBUG = 'PROCESS.PRO_DEBUG'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid', 'ProParent', 'ProTime', 'ProTimeunit', 'ProStatus', 'ProTypeDay', 'ProType', 'ProAssignment', 'ProShowMap', 'ProShowMessage', 'ProShowDelegate', 'ProShowDynaform', 'ProCategory', 'ProSubCategory', 'ProIndustry', 'ProUpdateDate', 'ProCreateDate', 'ProCreateUser', 'ProHeight', 'ProWidth', 'ProTitleX', 'ProTitleY', 'ProDebug', ), + BasePeer::TYPE_COLNAME => array (ProcessPeer::PRO_UID, ProcessPeer::PRO_PARENT, ProcessPeer::PRO_TIME, ProcessPeer::PRO_TIMEUNIT, ProcessPeer::PRO_STATUS, ProcessPeer::PRO_TYPE_DAY, ProcessPeer::PRO_TYPE, ProcessPeer::PRO_ASSIGNMENT, ProcessPeer::PRO_SHOW_MAP, ProcessPeer::PRO_SHOW_MESSAGE, ProcessPeer::PRO_SHOW_DELEGATE, ProcessPeer::PRO_SHOW_DYNAFORM, ProcessPeer::PRO_CATEGORY, ProcessPeer::PRO_SUB_CATEGORY, ProcessPeer::PRO_INDUSTRY, ProcessPeer::PRO_UPDATE_DATE, ProcessPeer::PRO_CREATE_DATE, ProcessPeer::PRO_CREATE_USER, ProcessPeer::PRO_HEIGHT, ProcessPeer::PRO_WIDTH, ProcessPeer::PRO_TITLE_X, ProcessPeer::PRO_TITLE_Y, ProcessPeer::PRO_DEBUG, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID', 'PRO_PARENT', 'PRO_TIME', 'PRO_TIMEUNIT', 'PRO_STATUS', 'PRO_TYPE_DAY', 'PRO_TYPE', 'PRO_ASSIGNMENT', 'PRO_SHOW_MAP', 'PRO_SHOW_MESSAGE', 'PRO_SHOW_DELEGATE', 'PRO_SHOW_DYNAFORM', 'PRO_CATEGORY', 'PRO_SUB_CATEGORY', 'PRO_INDUSTRY', 'PRO_UPDATE_DATE', 'PRO_CREATE_DATE', 'PRO_CREATE_USER', 'PRO_HEIGHT', 'PRO_WIDTH', 'PRO_TITLE_X', 'PRO_TITLE_Y', 'PRO_DEBUG', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid' => 0, 'ProParent' => 1, 'ProTime' => 2, 'ProTimeunit' => 3, 'ProStatus' => 4, 'ProTypeDay' => 5, 'ProType' => 6, 'ProAssignment' => 7, 'ProShowMap' => 8, 'ProShowMessage' => 9, 'ProShowDelegate' => 10, 'ProShowDynaform' => 11, 'ProCategory' => 12, 'ProSubCategory' => 13, 'ProIndustry' => 14, 'ProUpdateDate' => 15, 'ProCreateDate' => 16, 'ProCreateUser' => 17, 'ProHeight' => 18, 'ProWidth' => 19, 'ProTitleX' => 20, 'ProTitleY' => 21, 'ProDebug' => 22, ), + BasePeer::TYPE_COLNAME => array (ProcessPeer::PRO_UID => 0, ProcessPeer::PRO_PARENT => 1, ProcessPeer::PRO_TIME => 2, ProcessPeer::PRO_TIMEUNIT => 3, ProcessPeer::PRO_STATUS => 4, ProcessPeer::PRO_TYPE_DAY => 5, ProcessPeer::PRO_TYPE => 6, ProcessPeer::PRO_ASSIGNMENT => 7, ProcessPeer::PRO_SHOW_MAP => 8, ProcessPeer::PRO_SHOW_MESSAGE => 9, ProcessPeer::PRO_SHOW_DELEGATE => 10, ProcessPeer::PRO_SHOW_DYNAFORM => 11, ProcessPeer::PRO_CATEGORY => 12, ProcessPeer::PRO_SUB_CATEGORY => 13, ProcessPeer::PRO_INDUSTRY => 14, ProcessPeer::PRO_UPDATE_DATE => 15, ProcessPeer::PRO_CREATE_DATE => 16, ProcessPeer::PRO_CREATE_USER => 17, ProcessPeer::PRO_HEIGHT => 18, ProcessPeer::PRO_WIDTH => 19, ProcessPeer::PRO_TITLE_X => 20, ProcessPeer::PRO_TITLE_Y => 21, ProcessPeer::PRO_DEBUG => 22, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID' => 0, 'PRO_PARENT' => 1, 'PRO_TIME' => 2, 'PRO_TIMEUNIT' => 3, 'PRO_STATUS' => 4, 'PRO_TYPE_DAY' => 5, 'PRO_TYPE' => 6, 'PRO_ASSIGNMENT' => 7, 'PRO_SHOW_MAP' => 8, 'PRO_SHOW_MESSAGE' => 9, 'PRO_SHOW_DELEGATE' => 10, 'PRO_SHOW_DYNAFORM' => 11, 'PRO_CATEGORY' => 12, 'PRO_SUB_CATEGORY' => 13, 'PRO_INDUSTRY' => 14, 'PRO_UPDATE_DATE' => 15, 'PRO_CREATE_DATE' => 16, 'PRO_CREATE_USER' => 17, 'PRO_HEIGHT' => 18, 'PRO_WIDTH' => 19, 'PRO_TITLE_X' => 20, 'PRO_TITLE_Y' => 21, 'PRO_DEBUG' => 22, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ProcessMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ProcessMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ProcessPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ProcessPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ProcessPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ProcessPeer::PRO_UID); + + $criteria->addSelectColumn(ProcessPeer::PRO_PARENT); + + $criteria->addSelectColumn(ProcessPeer::PRO_TIME); + + $criteria->addSelectColumn(ProcessPeer::PRO_TIMEUNIT); + + $criteria->addSelectColumn(ProcessPeer::PRO_STATUS); + + $criteria->addSelectColumn(ProcessPeer::PRO_TYPE_DAY); + + $criteria->addSelectColumn(ProcessPeer::PRO_TYPE); + + $criteria->addSelectColumn(ProcessPeer::PRO_ASSIGNMENT); + + $criteria->addSelectColumn(ProcessPeer::PRO_SHOW_MAP); + + $criteria->addSelectColumn(ProcessPeer::PRO_SHOW_MESSAGE); + + $criteria->addSelectColumn(ProcessPeer::PRO_SHOW_DELEGATE); + + $criteria->addSelectColumn(ProcessPeer::PRO_SHOW_DYNAFORM); + + $criteria->addSelectColumn(ProcessPeer::PRO_CATEGORY); + + $criteria->addSelectColumn(ProcessPeer::PRO_SUB_CATEGORY); + + $criteria->addSelectColumn(ProcessPeer::PRO_INDUSTRY); + + $criteria->addSelectColumn(ProcessPeer::PRO_UPDATE_DATE); + + $criteria->addSelectColumn(ProcessPeer::PRO_CREATE_DATE); + + $criteria->addSelectColumn(ProcessPeer::PRO_CREATE_USER); + + $criteria->addSelectColumn(ProcessPeer::PRO_HEIGHT); + + $criteria->addSelectColumn(ProcessPeer::PRO_WIDTH); + + $criteria->addSelectColumn(ProcessPeer::PRO_TITLE_X); + + $criteria->addSelectColumn(ProcessPeer::PRO_TITLE_Y); + + $criteria->addSelectColumn(ProcessPeer::PRO_DEBUG); + + } + + const COUNT = 'COUNT(PROCESS.PRO_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT PROCESS.PRO_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ProcessPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ProcessPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ProcessPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Process + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ProcessPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ProcessPeer::populateObjects(ProcessPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ProcessPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ProcessPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ProcessPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Process or Criteria object. + * + * @param mixed $values Criteria or Process object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Process object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Process or Criteria object. + * + * @param mixed $values Criteria or Process object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ProcessPeer::PRO_UID); + $selectCriteria->add(ProcessPeer::PRO_UID, $criteria->remove(ProcessPeer::PRO_UID), $comparison); + + } else { // $values is Process object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the PROCESS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ProcessPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Process or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Process object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ProcessPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Process) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ProcessPeer::PRO_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Process object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Process $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Process $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ProcessPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ProcessPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ProcessPeer::PRO_TIMEUNIT)) + $columns[ProcessPeer::PRO_TIMEUNIT] = $obj->getProTimeunit(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessPeer::PRO_STATUS)) + $columns[ProcessPeer::PRO_STATUS] = $obj->getProStatus(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessPeer::PRO_TYPE)) + $columns[ProcessPeer::PRO_TYPE] = $obj->getProType(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessPeer::PRO_ASSIGNMENT)) + $columns[ProcessPeer::PRO_ASSIGNMENT] = $obj->getProAssignment(); + + } + + return BasePeer::doValidate(ProcessPeer::DATABASE_NAME, ProcessPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Process + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ProcessPeer::DATABASE_NAME); + + $criteria->add(ProcessPeer::PRO_UID, $pk); + + + $v = ProcessPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ProcessPeer::PRO_UID, $pks, Criteria::IN); + $objs = ProcessPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseProcessPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseProcessPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ProcessMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ProcessMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseProcessUser.php b/workflow/engine/classes/model/om/BaseProcessUser.php new file mode 100644 index 000000000..b5ebfd8ea --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessUser.php @@ -0,0 +1,663 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ProcessUserPeer.php'; + +/** + * Base class that represents a row from the 'PROCESS_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessUser extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ProcessUserPeer + */ + protected static $peer; + + + /** + * The value for the pu_uid field. + * @var string + */ + protected $pu_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the pu_type field. + * @var string + */ + protected $pu_type = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [pu_uid] column value. + * + * @return string + */ + public function getPuUid() + { + + return $this->pu_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [pu_type] column value. + * + * @return string + */ + public function getPuType() + { + + return $this->pu_type; + } + + /** + * Set the value of [pu_uid] column. + * + * @param string $v new value + * @return void + */ + public function setPuUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pu_uid !== $v || $v === '') { + $this->pu_uid = $v; + $this->modifiedColumns[] = ProcessUserPeer::PU_UID; + } + + } // setPuUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ProcessUserPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = ProcessUserPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [pu_type] column. + * + * @param string $v new value + * @return void + */ + public function setPuType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pu_type !== $v || $v === '') { + $this->pu_type = $v; + $this->modifiedColumns[] = ProcessUserPeer::PU_TYPE; + } + + } // setPuType() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->pu_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->usr_uid = $rs->getString($startcol + 2); + + $this->pu_type = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = ProcessUserPeer::NUM_COLUMNS - ProcessUserPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ProcessUser object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ProcessUserPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ProcessUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ProcessUserPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ProcessUserPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ProcessUserPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getPuUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getUsrUid(); + break; + case 3: + return $this->getPuType(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessUserPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getPuUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getUsrUid(), + $keys[3] => $this->getPuType(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ProcessUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setPuUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setUsrUid($value); + break; + case 3: + $this->setPuType($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ProcessUserPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setPuUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUsrUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setPuType($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProcessUserPeer::DATABASE_NAME); + + if ($this->isColumnModified(ProcessUserPeer::PU_UID)) $criteria->add(ProcessUserPeer::PU_UID, $this->pu_uid); + if ($this->isColumnModified(ProcessUserPeer::PRO_UID)) $criteria->add(ProcessUserPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ProcessUserPeer::USR_UID)) $criteria->add(ProcessUserPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(ProcessUserPeer::PU_TYPE)) $criteria->add(ProcessUserPeer::PU_TYPE, $this->pu_type); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProcessUserPeer::DATABASE_NAME); + + $criteria->add(ProcessUserPeer::PU_UID, $this->pu_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getPuUid(); + } + + /** + * Generic method to set the primary key (pu_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setPuUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ProcessUser (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setPuType($this->pu_type); + + + $copyObj->setNew(true); + + $copyObj->setPuUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ProcessUser Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ProcessUserPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ProcessUserPeer(); + } + return self::$peer; + } + +} // BaseProcessUser diff --git a/workflow/engine/classes/model/om/BaseProcessUserPeer.php b/workflow/engine/classes/model/om/BaseProcessUserPeer.php new file mode 100644 index 000000000..cb3bfabc8 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseProcessUserPeer.php @@ -0,0 +1,592 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ProcessUserPeer::getOMClass() +include_once 'classes/model/ProcessUser.php'; + +/** + * Base static class for performing query and update operations on the 'PROCESS_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseProcessUserPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'PROCESS_USER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ProcessUser'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the PU_UID field */ + const PU_UID = 'PROCESS_USER.PU_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'PROCESS_USER.PRO_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'PROCESS_USER.USR_UID'; + + /** the column name for the PU_TYPE field */ + const PU_TYPE = 'PROCESS_USER.PU_TYPE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('PuUid', 'ProUid', 'UsrUid', 'PuType', ), + BasePeer::TYPE_COLNAME => array (ProcessUserPeer::PU_UID, ProcessUserPeer::PRO_UID, ProcessUserPeer::USR_UID, ProcessUserPeer::PU_TYPE, ), + BasePeer::TYPE_FIELDNAME => array ('PU_UID', 'PRO_UID', 'USR_UID', 'PU_TYPE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('PuUid' => 0, 'ProUid' => 1, 'UsrUid' => 2, 'PuType' => 3, ), + BasePeer::TYPE_COLNAME => array (ProcessUserPeer::PU_UID => 0, ProcessUserPeer::PRO_UID => 1, ProcessUserPeer::USR_UID => 2, ProcessUserPeer::PU_TYPE => 3, ), + BasePeer::TYPE_FIELDNAME => array ('PU_UID' => 0, 'PRO_UID' => 1, 'USR_UID' => 2, 'PU_TYPE' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ProcessUserMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ProcessUserMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ProcessUserPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ProcessUserPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ProcessUserPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ProcessUserPeer::PU_UID); + + $criteria->addSelectColumn(ProcessUserPeer::PRO_UID); + + $criteria->addSelectColumn(ProcessUserPeer::USR_UID); + + $criteria->addSelectColumn(ProcessUserPeer::PU_TYPE); + + } + + const COUNT = 'COUNT(PROCESS_USER.PU_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT PROCESS_USER.PU_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ProcessUserPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ProcessUserPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ProcessUserPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ProcessUser + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ProcessUserPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ProcessUserPeer::populateObjects(ProcessUserPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ProcessUserPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ProcessUserPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ProcessUserPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ProcessUser or Criteria object. + * + * @param mixed $values Criteria or ProcessUser object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ProcessUser object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ProcessUser or Criteria object. + * + * @param mixed $values Criteria or ProcessUser object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ProcessUserPeer::PU_UID); + $selectCriteria->add(ProcessUserPeer::PU_UID, $criteria->remove(ProcessUserPeer::PU_UID), $comparison); + + } else { // $values is ProcessUser object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the PROCESS_USER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ProcessUserPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ProcessUser or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProcessUser object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ProcessUserPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ProcessUser) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ProcessUserPeer::PU_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ProcessUser object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ProcessUser $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ProcessUser $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ProcessUserPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ProcessUserPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ProcessUserPeer::PU_UID)) + $columns[ProcessUserPeer::PU_UID] = $obj->getPuUid(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessUserPeer::PRO_UID)) + $columns[ProcessUserPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessUserPeer::USR_UID)) + $columns[ProcessUserPeer::USR_UID] = $obj->getUsrUid(); + + if ($obj->isNew() || $obj->isColumnModified(ProcessUserPeer::PU_TYPE)) + $columns[ProcessUserPeer::PU_TYPE] = $obj->getPuType(); + + } + + return BasePeer::doValidate(ProcessUserPeer::DATABASE_NAME, ProcessUserPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ProcessUser + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ProcessUserPeer::DATABASE_NAME); + + $criteria->add(ProcessUserPeer::PU_UID, $pk); + + + $v = ProcessUserPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ProcessUserPeer::PU_UID, $pks, Criteria::IN); + $objs = ProcessUserPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseProcessUserPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseProcessUserPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ProcessUserMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ProcessUserMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseReportTable.php b/workflow/engine/classes/model/om/BaseReportTable.php new file mode 100644 index 000000000..73ad8571e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseReportTable.php @@ -0,0 +1,897 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ReportTablePeer.php'; + +/** + * Base class that represents a row from the 'REPORT_TABLE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseReportTable extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ReportTablePeer + */ + protected static $peer; + + + /** + * The value for the rep_tab_uid field. + * @var string + */ + protected $rep_tab_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the rep_tab_name field. + * @var string + */ + protected $rep_tab_name = ''; + + + /** + * The value for the rep_tab_type field. + * @var string + */ + protected $rep_tab_type = ''; + + + /** + * The value for the rep_tab_grid field. + * @var string + */ + protected $rep_tab_grid = ''; + + + /** + * The value for the rep_tab_connection field. + * @var string + */ + protected $rep_tab_connection = ''; + + + /** + * The value for the rep_tab_create_date field. + * @var int + */ + protected $rep_tab_create_date; + + + /** + * The value for the rep_tab_status field. + * @var string + */ + protected $rep_tab_status = 'ACTIVE'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [rep_tab_uid] column value. + * + * @return string + */ + public function getRepTabUid() + { + + return $this->rep_tab_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [rep_tab_name] column value. + * + * @return string + */ + public function getRepTabName() + { + + return $this->rep_tab_name; + } + + /** + * Get the [rep_tab_type] column value. + * + * @return string + */ + public function getRepTabType() + { + + return $this->rep_tab_type; + } + + /** + * Get the [rep_tab_grid] column value. + * + * @return string + */ + public function getRepTabGrid() + { + + return $this->rep_tab_grid; + } + + /** + * Get the [rep_tab_connection] column value. + * + * @return string + */ + public function getRepTabConnection() + { + + return $this->rep_tab_connection; + } + + /** + * Get the [optionally formatted] [rep_tab_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getRepTabCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->rep_tab_create_date === null || $this->rep_tab_create_date === '') { + return null; + } elseif (!is_int($this->rep_tab_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->rep_tab_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [rep_tab_create_date] as date/time value: " . var_export($this->rep_tab_create_date, true)); + } + } else { + $ts = $this->rep_tab_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [rep_tab_status] column value. + * + * @return string + */ + public function getRepTabStatus() + { + + return $this->rep_tab_status; + } + + /** + * Set the value of [rep_tab_uid] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_uid !== $v || $v === '') { + $this->rep_tab_uid = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_UID; + } + + } // setRepTabUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ReportTablePeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [rep_tab_name] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_name !== $v || $v === '') { + $this->rep_tab_name = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_NAME; + } + + } // setRepTabName() + + /** + * Set the value of [rep_tab_type] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_type !== $v || $v === '') { + $this->rep_tab_type = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_TYPE; + } + + } // setRepTabType() + + /** + * Set the value of [rep_tab_grid] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabGrid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_grid !== $v || $v === '') { + $this->rep_tab_grid = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_GRID; + } + + } // setRepTabGrid() + + /** + * Set the value of [rep_tab_connection] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabConnection($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_connection !== $v || $v === '') { + $this->rep_tab_connection = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_CONNECTION; + } + + } // setRepTabConnection() + + /** + * Set the value of [rep_tab_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setRepTabCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [rep_tab_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->rep_tab_create_date !== $ts) { + $this->rep_tab_create_date = $ts; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_CREATE_DATE; + } + + } // setRepTabCreateDate() + + /** + * Set the value of [rep_tab_status] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_status !== $v || $v === 'ACTIVE') { + $this->rep_tab_status = $v; + $this->modifiedColumns[] = ReportTablePeer::REP_TAB_STATUS; + } + + } // setRepTabStatus() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->rep_tab_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->rep_tab_name = $rs->getString($startcol + 2); + + $this->rep_tab_type = $rs->getString($startcol + 3); + + $this->rep_tab_grid = $rs->getString($startcol + 4); + + $this->rep_tab_connection = $rs->getString($startcol + 5); + + $this->rep_tab_create_date = $rs->getTimestamp($startcol + 6, null); + + $this->rep_tab_status = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = ReportTablePeer::NUM_COLUMNS - ReportTablePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ReportTable object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + } + + try { + $con->begin(); + ReportTablePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ReportTablePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ReportTablePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ReportTablePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ReportTablePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getRepTabUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getRepTabName(); + break; + case 3: + return $this->getRepTabType(); + break; + case 4: + return $this->getRepTabGrid(); + break; + case 5: + return $this->getRepTabConnection(); + break; + case 6: + return $this->getRepTabCreateDate(); + break; + case 7: + return $this->getRepTabStatus(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ReportTablePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getRepTabUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getRepTabName(), + $keys[3] => $this->getRepTabType(), + $keys[4] => $this->getRepTabGrid(), + $keys[5] => $this->getRepTabConnection(), + $keys[6] => $this->getRepTabCreateDate(), + $keys[7] => $this->getRepTabStatus(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ReportTablePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setRepTabUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setRepTabName($value); + break; + case 3: + $this->setRepTabType($value); + break; + case 4: + $this->setRepTabGrid($value); + break; + case 5: + $this->setRepTabConnection($value); + break; + case 6: + $this->setRepTabCreateDate($value); + break; + case 7: + $this->setRepTabStatus($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ReportTablePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setRepTabUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setRepTabName($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setRepTabType($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setRepTabGrid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setRepTabConnection($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setRepTabCreateDate($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setRepTabStatus($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ReportTablePeer::DATABASE_NAME); + + if ($this->isColumnModified(ReportTablePeer::REP_TAB_UID)) $criteria->add(ReportTablePeer::REP_TAB_UID, $this->rep_tab_uid); + if ($this->isColumnModified(ReportTablePeer::PRO_UID)) $criteria->add(ReportTablePeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_NAME)) $criteria->add(ReportTablePeer::REP_TAB_NAME, $this->rep_tab_name); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_TYPE)) $criteria->add(ReportTablePeer::REP_TAB_TYPE, $this->rep_tab_type); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_GRID)) $criteria->add(ReportTablePeer::REP_TAB_GRID, $this->rep_tab_grid); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_CONNECTION)) $criteria->add(ReportTablePeer::REP_TAB_CONNECTION, $this->rep_tab_connection); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_CREATE_DATE)) $criteria->add(ReportTablePeer::REP_TAB_CREATE_DATE, $this->rep_tab_create_date); + if ($this->isColumnModified(ReportTablePeer::REP_TAB_STATUS)) $criteria->add(ReportTablePeer::REP_TAB_STATUS, $this->rep_tab_status); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ReportTablePeer::DATABASE_NAME); + + $criteria->add(ReportTablePeer::REP_TAB_UID, $this->rep_tab_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getRepTabUid(); + } + + /** + * Generic method to set the primary key (rep_tab_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setRepTabUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ReportTable (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setRepTabName($this->rep_tab_name); + + $copyObj->setRepTabType($this->rep_tab_type); + + $copyObj->setRepTabGrid($this->rep_tab_grid); + + $copyObj->setRepTabConnection($this->rep_tab_connection); + + $copyObj->setRepTabCreateDate($this->rep_tab_create_date); + + $copyObj->setRepTabStatus($this->rep_tab_status); + + + $copyObj->setNew(true); + + $copyObj->setRepTabUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ReportTable Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ReportTablePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ReportTablePeer(); + } + return self::$peer; + } + +} // BaseReportTable diff --git a/workflow/engine/classes/model/om/BaseReportTablePeer.php b/workflow/engine/classes/model/om/BaseReportTablePeer.php new file mode 100644 index 000000000..50a4896b6 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseReportTablePeer.php @@ -0,0 +1,618 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ReportTablePeer::getOMClass() +include_once 'classes/model/ReportTable.php'; + +/** + * Base static class for performing query and update operations on the 'REPORT_TABLE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseReportTablePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'REPORT_TABLE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ReportTable'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the REP_TAB_UID field */ + const REP_TAB_UID = 'REPORT_TABLE.REP_TAB_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'REPORT_TABLE.PRO_UID'; + + /** the column name for the REP_TAB_NAME field */ + const REP_TAB_NAME = 'REPORT_TABLE.REP_TAB_NAME'; + + /** the column name for the REP_TAB_TYPE field */ + const REP_TAB_TYPE = 'REPORT_TABLE.REP_TAB_TYPE'; + + /** the column name for the REP_TAB_GRID field */ + const REP_TAB_GRID = 'REPORT_TABLE.REP_TAB_GRID'; + + /** the column name for the REP_TAB_CONNECTION field */ + const REP_TAB_CONNECTION = 'REPORT_TABLE.REP_TAB_CONNECTION'; + + /** the column name for the REP_TAB_CREATE_DATE field */ + const REP_TAB_CREATE_DATE = 'REPORT_TABLE.REP_TAB_CREATE_DATE'; + + /** the column name for the REP_TAB_STATUS field */ + const REP_TAB_STATUS = 'REPORT_TABLE.REP_TAB_STATUS'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('RepTabUid', 'ProUid', 'RepTabName', 'RepTabType', 'RepTabGrid', 'RepTabConnection', 'RepTabCreateDate', 'RepTabStatus', ), + BasePeer::TYPE_COLNAME => array (ReportTablePeer::REP_TAB_UID, ReportTablePeer::PRO_UID, ReportTablePeer::REP_TAB_NAME, ReportTablePeer::REP_TAB_TYPE, ReportTablePeer::REP_TAB_GRID, ReportTablePeer::REP_TAB_CONNECTION, ReportTablePeer::REP_TAB_CREATE_DATE, ReportTablePeer::REP_TAB_STATUS, ), + BasePeer::TYPE_FIELDNAME => array ('REP_TAB_UID', 'PRO_UID', 'REP_TAB_NAME', 'REP_TAB_TYPE', 'REP_TAB_GRID', 'REP_TAB_CONNECTION', 'REP_TAB_CREATE_DATE', 'REP_TAB_STATUS', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('RepTabUid' => 0, 'ProUid' => 1, 'RepTabName' => 2, 'RepTabType' => 3, 'RepTabGrid' => 4, 'RepTabConnection' => 5, 'RepTabCreateDate' => 6, 'RepTabStatus' => 7, ), + BasePeer::TYPE_COLNAME => array (ReportTablePeer::REP_TAB_UID => 0, ReportTablePeer::PRO_UID => 1, ReportTablePeer::REP_TAB_NAME => 2, ReportTablePeer::REP_TAB_TYPE => 3, ReportTablePeer::REP_TAB_GRID => 4, ReportTablePeer::REP_TAB_CONNECTION => 5, ReportTablePeer::REP_TAB_CREATE_DATE => 6, ReportTablePeer::REP_TAB_STATUS => 7, ), + BasePeer::TYPE_FIELDNAME => array ('REP_TAB_UID' => 0, 'PRO_UID' => 1, 'REP_TAB_NAME' => 2, 'REP_TAB_TYPE' => 3, 'REP_TAB_GRID' => 4, 'REP_TAB_CONNECTION' => 5, 'REP_TAB_CREATE_DATE' => 6, 'REP_TAB_STATUS' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ReportTableMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ReportTableMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ReportTablePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ReportTablePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ReportTablePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_UID); + + $criteria->addSelectColumn(ReportTablePeer::PRO_UID); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_NAME); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_TYPE); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_GRID); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_CONNECTION); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_CREATE_DATE); + + $criteria->addSelectColumn(ReportTablePeer::REP_TAB_STATUS); + + } + + const COUNT = 'COUNT(REPORT_TABLE.REP_TAB_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT REPORT_TABLE.REP_TAB_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ReportTablePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ReportTablePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ReportTablePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ReportTable + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ReportTablePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ReportTablePeer::populateObjects(ReportTablePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ReportTablePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ReportTablePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ReportTablePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ReportTable or Criteria object. + * + * @param mixed $values Criteria or ReportTable object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ReportTable object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ReportTable or Criteria object. + * + * @param mixed $values Criteria or ReportTable object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ReportTablePeer::REP_TAB_UID); + $selectCriteria->add(ReportTablePeer::REP_TAB_UID, $criteria->remove(ReportTablePeer::REP_TAB_UID), $comparison); + + } else { // $values is ReportTable object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the REPORT_TABLE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ReportTablePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ReportTable or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ReportTable object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ReportTablePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ReportTable) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ReportTablePeer::REP_TAB_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ReportTable object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ReportTable $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ReportTable $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ReportTablePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ReportTablePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::REP_TAB_UID)) + $columns[ReportTablePeer::REP_TAB_UID] = $obj->getRepTabUid(); + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::PRO_UID)) + $columns[ReportTablePeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::REP_TAB_NAME)) + $columns[ReportTablePeer::REP_TAB_NAME] = $obj->getRepTabName(); + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::REP_TAB_TYPE)) + $columns[ReportTablePeer::REP_TAB_TYPE] = $obj->getRepTabType(); + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::REP_TAB_CONNECTION)) + $columns[ReportTablePeer::REP_TAB_CONNECTION] = $obj->getRepTabConnection(); + + if ($obj->isNew() || $obj->isColumnModified(ReportTablePeer::REP_TAB_STATUS)) + $columns[ReportTablePeer::REP_TAB_STATUS] = $obj->getRepTabStatus(); + + } + + return BasePeer::doValidate(ReportTablePeer::DATABASE_NAME, ReportTablePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ReportTable + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ReportTablePeer::DATABASE_NAME); + + $criteria->add(ReportTablePeer::REP_TAB_UID, $pk); + + + $v = ReportTablePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ReportTablePeer::REP_TAB_UID, $pks, Criteria::IN); + $objs = ReportTablePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseReportTablePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseReportTablePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ReportTableMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ReportTableMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseReportVar.php b/workflow/engine/classes/model/om/BaseReportVar.php new file mode 100644 index 000000000..2bd463b5a --- /dev/null +++ b/workflow/engine/classes/model/om/BaseReportVar.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ReportVarPeer.php'; + +/** + * Base class that represents a row from the 'REPORT_VAR' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseReportVar extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ReportVarPeer + */ + protected static $peer; + + + /** + * The value for the rep_var_uid field. + * @var string + */ + protected $rep_var_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the rep_tab_uid field. + * @var string + */ + protected $rep_tab_uid = ''; + + + /** + * The value for the rep_var_name field. + * @var string + */ + protected $rep_var_name = ''; + + + /** + * The value for the rep_var_type field. + * @var string + */ + protected $rep_var_type = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [rep_var_uid] column value. + * + * @return string + */ + public function getRepVarUid() + { + + return $this->rep_var_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [rep_tab_uid] column value. + * + * @return string + */ + public function getRepTabUid() + { + + return $this->rep_tab_uid; + } + + /** + * Get the [rep_var_name] column value. + * + * @return string + */ + public function getRepVarName() + { + + return $this->rep_var_name; + } + + /** + * Get the [rep_var_type] column value. + * + * @return string + */ + public function getRepVarType() + { + + return $this->rep_var_type; + } + + /** + * Set the value of [rep_var_uid] column. + * + * @param string $v new value + * @return void + */ + public function setRepVarUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_var_uid !== $v || $v === '') { + $this->rep_var_uid = $v; + $this->modifiedColumns[] = ReportVarPeer::REP_VAR_UID; + } + + } // setRepVarUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = ReportVarPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [rep_tab_uid] column. + * + * @param string $v new value + * @return void + */ + public function setRepTabUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_tab_uid !== $v || $v === '') { + $this->rep_tab_uid = $v; + $this->modifiedColumns[] = ReportVarPeer::REP_TAB_UID; + } + + } // setRepTabUid() + + /** + * Set the value of [rep_var_name] column. + * + * @param string $v new value + * @return void + */ + public function setRepVarName($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_var_name !== $v || $v === '') { + $this->rep_var_name = $v; + $this->modifiedColumns[] = ReportVarPeer::REP_VAR_NAME; + } + + } // setRepVarName() + + /** + * Set the value of [rep_var_type] column. + * + * @param string $v new value + * @return void + */ + public function setRepVarType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rep_var_type !== $v || $v === '') { + $this->rep_var_type = $v; + $this->modifiedColumns[] = ReportVarPeer::REP_VAR_TYPE; + } + + } // setRepVarType() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->rep_var_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->rep_tab_uid = $rs->getString($startcol + 2); + + $this->rep_var_name = $rs->getString($startcol + 3); + + $this->rep_var_type = $rs->getString($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = ReportVarPeer::NUM_COLUMNS - ReportVarPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ReportVar object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + } + + try { + $con->begin(); + ReportVarPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ReportVarPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ReportVarPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ReportVarPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ReportVarPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getRepVarUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getRepTabUid(); + break; + case 3: + return $this->getRepVarName(); + break; + case 4: + return $this->getRepVarType(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ReportVarPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getRepVarUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getRepTabUid(), + $keys[3] => $this->getRepVarName(), + $keys[4] => $this->getRepVarType(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ReportVarPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setRepVarUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setRepTabUid($value); + break; + case 3: + $this->setRepVarName($value); + break; + case 4: + $this->setRepVarType($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ReportVarPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setRepVarUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setRepTabUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setRepVarName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setRepVarType($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ReportVarPeer::DATABASE_NAME); + + if ($this->isColumnModified(ReportVarPeer::REP_VAR_UID)) $criteria->add(ReportVarPeer::REP_VAR_UID, $this->rep_var_uid); + if ($this->isColumnModified(ReportVarPeer::PRO_UID)) $criteria->add(ReportVarPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(ReportVarPeer::REP_TAB_UID)) $criteria->add(ReportVarPeer::REP_TAB_UID, $this->rep_tab_uid); + if ($this->isColumnModified(ReportVarPeer::REP_VAR_NAME)) $criteria->add(ReportVarPeer::REP_VAR_NAME, $this->rep_var_name); + if ($this->isColumnModified(ReportVarPeer::REP_VAR_TYPE)) $criteria->add(ReportVarPeer::REP_VAR_TYPE, $this->rep_var_type); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ReportVarPeer::DATABASE_NAME); + + $criteria->add(ReportVarPeer::REP_VAR_UID, $this->rep_var_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getRepVarUid(); + } + + /** + * Generic method to set the primary key (rep_var_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setRepVarUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ReportVar (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setRepTabUid($this->rep_tab_uid); + + $copyObj->setRepVarName($this->rep_var_name); + + $copyObj->setRepVarType($this->rep_var_type); + + + $copyObj->setNew(true); + + $copyObj->setRepVarUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ReportVar Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ReportVarPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ReportVarPeer(); + } + return self::$peer; + } + +} // BaseReportVar diff --git a/workflow/engine/classes/model/om/BaseReportVarPeer.php b/workflow/engine/classes/model/om/BaseReportVarPeer.php new file mode 100644 index 000000000..2cd281c6b --- /dev/null +++ b/workflow/engine/classes/model/om/BaseReportVarPeer.php @@ -0,0 +1,597 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ReportVarPeer::getOMClass() +include_once 'classes/model/ReportVar.php'; + +/** + * Base static class for performing query and update operations on the 'REPORT_VAR' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseReportVarPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'REPORT_VAR'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ReportVar'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the REP_VAR_UID field */ + const REP_VAR_UID = 'REPORT_VAR.REP_VAR_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'REPORT_VAR.PRO_UID'; + + /** the column name for the REP_TAB_UID field */ + const REP_TAB_UID = 'REPORT_VAR.REP_TAB_UID'; + + /** the column name for the REP_VAR_NAME field */ + const REP_VAR_NAME = 'REPORT_VAR.REP_VAR_NAME'; + + /** the column name for the REP_VAR_TYPE field */ + const REP_VAR_TYPE = 'REPORT_VAR.REP_VAR_TYPE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('RepVarUid', 'ProUid', 'RepTabUid', 'RepVarName', 'RepVarType', ), + BasePeer::TYPE_COLNAME => array (ReportVarPeer::REP_VAR_UID, ReportVarPeer::PRO_UID, ReportVarPeer::REP_TAB_UID, ReportVarPeer::REP_VAR_NAME, ReportVarPeer::REP_VAR_TYPE, ), + BasePeer::TYPE_FIELDNAME => array ('REP_VAR_UID', 'PRO_UID', 'REP_TAB_UID', 'REP_VAR_NAME', 'REP_VAR_TYPE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('RepVarUid' => 0, 'ProUid' => 1, 'RepTabUid' => 2, 'RepVarName' => 3, 'RepVarType' => 4, ), + BasePeer::TYPE_COLNAME => array (ReportVarPeer::REP_VAR_UID => 0, ReportVarPeer::PRO_UID => 1, ReportVarPeer::REP_TAB_UID => 2, ReportVarPeer::REP_VAR_NAME => 3, ReportVarPeer::REP_VAR_TYPE => 4, ), + BasePeer::TYPE_FIELDNAME => array ('REP_VAR_UID' => 0, 'PRO_UID' => 1, 'REP_TAB_UID' => 2, 'REP_VAR_NAME' => 3, 'REP_VAR_TYPE' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ReportVarMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ReportVarMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ReportVarPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ReportVarPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ReportVarPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ReportVarPeer::REP_VAR_UID); + + $criteria->addSelectColumn(ReportVarPeer::PRO_UID); + + $criteria->addSelectColumn(ReportVarPeer::REP_TAB_UID); + + $criteria->addSelectColumn(ReportVarPeer::REP_VAR_NAME); + + $criteria->addSelectColumn(ReportVarPeer::REP_VAR_TYPE); + + } + + const COUNT = 'COUNT(REPORT_VAR.REP_VAR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT REPORT_VAR.REP_VAR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ReportVarPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ReportVarPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ReportVarPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ReportVar + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ReportVarPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ReportVarPeer::populateObjects(ReportVarPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ReportVarPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ReportVarPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ReportVarPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ReportVar or Criteria object. + * + * @param mixed $values Criteria or ReportVar object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ReportVar object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ReportVar or Criteria object. + * + * @param mixed $values Criteria or ReportVar object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ReportVarPeer::REP_VAR_UID); + $selectCriteria->add(ReportVarPeer::REP_VAR_UID, $criteria->remove(ReportVarPeer::REP_VAR_UID), $comparison); + + } else { // $values is ReportVar object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the REPORT_VAR table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ReportVarPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ReportVar or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ReportVar object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ReportVarPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ReportVar) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ReportVarPeer::REP_VAR_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ReportVar object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ReportVar $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ReportVar $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ReportVarPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ReportVarPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(ReportVarPeer::REP_VAR_UID)) + $columns[ReportVarPeer::REP_VAR_UID] = $obj->getRepVarUid(); + + if ($obj->isNew() || $obj->isColumnModified(ReportVarPeer::REP_TAB_UID)) + $columns[ReportVarPeer::REP_TAB_UID] = $obj->getRepTabUid(); + + if ($obj->isNew() || $obj->isColumnModified(ReportVarPeer::REP_VAR_NAME)) + $columns[ReportVarPeer::REP_VAR_NAME] = $obj->getRepVarName(); + + if ($obj->isNew() || $obj->isColumnModified(ReportVarPeer::REP_VAR_TYPE)) + $columns[ReportVarPeer::REP_VAR_TYPE] = $obj->getRepVarType(); + + } + + return BasePeer::doValidate(ReportVarPeer::DATABASE_NAME, ReportVarPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ReportVar + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ReportVarPeer::DATABASE_NAME); + + $criteria->add(ReportVarPeer::REP_VAR_UID, $pk); + + + $v = ReportVarPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ReportVarPeer::REP_VAR_UID, $pks, Criteria::IN); + $objs = ReportVarPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseReportVarPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseReportVarPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ReportVarMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ReportVarMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseRoute.php b/workflow/engine/classes/model/om/BaseRoute.php new file mode 100644 index 000000000..2686efc23 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseRoute.php @@ -0,0 +1,1140 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/RoutePeer.php'; + +/** + * Base class that represents a row from the 'ROUTE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseRoute extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var RoutePeer + */ + protected static $peer; + + + /** + * The value for the rou_uid field. + * @var string + */ + protected $rou_uid = ''; + + + /** + * The value for the rou_parent field. + * @var string + */ + protected $rou_parent = '0'; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the rou_next_task field. + * @var string + */ + protected $rou_next_task = '0'; + + + /** + * The value for the rou_case field. + * @var int + */ + protected $rou_case = 0; + + + /** + * The value for the rou_type field. + * @var string + */ + protected $rou_type = 'SEQUENTIAL'; + + + /** + * The value for the rou_condition field. + * @var string + */ + protected $rou_condition = ''; + + + /** + * The value for the rou_to_last_user field. + * @var string + */ + protected $rou_to_last_user = 'FALSE'; + + + /** + * The value for the rou_optional field. + * @var string + */ + protected $rou_optional = 'FALSE'; + + + /** + * The value for the rou_send_email field. + * @var string + */ + protected $rou_send_email = 'TRUE'; + + + /** + * The value for the rou_sourceanchor field. + * @var int + */ + protected $rou_sourceanchor = 1; + + + /** + * The value for the rou_targetanchor field. + * @var int + */ + protected $rou_targetanchor = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [rou_uid] column value. + * + * @return string + */ + public function getRouUid() + { + + return $this->rou_uid; + } + + /** + * Get the [rou_parent] column value. + * + * @return string + */ + public function getRouParent() + { + + return $this->rou_parent; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [rou_next_task] column value. + * + * @return string + */ + public function getRouNextTask() + { + + return $this->rou_next_task; + } + + /** + * Get the [rou_case] column value. + * + * @return int + */ + public function getRouCase() + { + + return $this->rou_case; + } + + /** + * Get the [rou_type] column value. + * + * @return string + */ + public function getRouType() + { + + return $this->rou_type; + } + + /** + * Get the [rou_condition] column value. + * + * @return string + */ + public function getRouCondition() + { + + return $this->rou_condition; + } + + /** + * Get the [rou_to_last_user] column value. + * + * @return string + */ + public function getRouToLastUser() + { + + return $this->rou_to_last_user; + } + + /** + * Get the [rou_optional] column value. + * + * @return string + */ + public function getRouOptional() + { + + return $this->rou_optional; + } + + /** + * Get the [rou_send_email] column value. + * + * @return string + */ + public function getRouSendEmail() + { + + return $this->rou_send_email; + } + + /** + * Get the [rou_sourceanchor] column value. + * + * @return int + */ + public function getRouSourceanchor() + { + + return $this->rou_sourceanchor; + } + + /** + * Get the [rou_targetanchor] column value. + * + * @return int + */ + public function getRouTargetanchor() + { + + return $this->rou_targetanchor; + } + + /** + * Set the value of [rou_uid] column. + * + * @param string $v new value + * @return void + */ + public function setRouUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_uid !== $v || $v === '') { + $this->rou_uid = $v; + $this->modifiedColumns[] = RoutePeer::ROU_UID; + } + + } // setRouUid() + + /** + * Set the value of [rou_parent] column. + * + * @param string $v new value + * @return void + */ + public function setRouParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_parent !== $v || $v === '0') { + $this->rou_parent = $v; + $this->modifiedColumns[] = RoutePeer::ROU_PARENT; + } + + } // setRouParent() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = RoutePeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = RoutePeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [rou_next_task] column. + * + * @param string $v new value + * @return void + */ + public function setRouNextTask($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_next_task !== $v || $v === '0') { + $this->rou_next_task = $v; + $this->modifiedColumns[] = RoutePeer::ROU_NEXT_TASK; + } + + } // setRouNextTask() + + /** + * Set the value of [rou_case] column. + * + * @param int $v new value + * @return void + */ + public function setRouCase($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->rou_case !== $v || $v === 0) { + $this->rou_case = $v; + $this->modifiedColumns[] = RoutePeer::ROU_CASE; + } + + } // setRouCase() + + /** + * Set the value of [rou_type] column. + * + * @param string $v new value + * @return void + */ + public function setRouType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_type !== $v || $v === 'SEQUENTIAL') { + $this->rou_type = $v; + $this->modifiedColumns[] = RoutePeer::ROU_TYPE; + } + + } // setRouType() + + /** + * Set the value of [rou_condition] column. + * + * @param string $v new value + * @return void + */ + public function setRouCondition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_condition !== $v || $v === '') { + $this->rou_condition = $v; + $this->modifiedColumns[] = RoutePeer::ROU_CONDITION; + } + + } // setRouCondition() + + /** + * Set the value of [rou_to_last_user] column. + * + * @param string $v new value + * @return void + */ + public function setRouToLastUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_to_last_user !== $v || $v === 'FALSE') { + $this->rou_to_last_user = $v; + $this->modifiedColumns[] = RoutePeer::ROU_TO_LAST_USER; + } + + } // setRouToLastUser() + + /** + * Set the value of [rou_optional] column. + * + * @param string $v new value + * @return void + */ + public function setRouOptional($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_optional !== $v || $v === 'FALSE') { + $this->rou_optional = $v; + $this->modifiedColumns[] = RoutePeer::ROU_OPTIONAL; + } + + } // setRouOptional() + + /** + * Set the value of [rou_send_email] column. + * + * @param string $v new value + * @return void + */ + public function setRouSendEmail($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->rou_send_email !== $v || $v === 'TRUE') { + $this->rou_send_email = $v; + $this->modifiedColumns[] = RoutePeer::ROU_SEND_EMAIL; + } + + } // setRouSendEmail() + + /** + * Set the value of [rou_sourceanchor] column. + * + * @param int $v new value + * @return void + */ + public function setRouSourceanchor($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->rou_sourceanchor !== $v || $v === 1) { + $this->rou_sourceanchor = $v; + $this->modifiedColumns[] = RoutePeer::ROU_SOURCEANCHOR; + } + + } // setRouSourceanchor() + + /** + * Set the value of [rou_targetanchor] column. + * + * @param int $v new value + * @return void + */ + public function setRouTargetanchor($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->rou_targetanchor !== $v || $v === 0) { + $this->rou_targetanchor = $v; + $this->modifiedColumns[] = RoutePeer::ROU_TARGETANCHOR; + } + + } // setRouTargetanchor() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->rou_uid = $rs->getString($startcol + 0); + + $this->rou_parent = $rs->getString($startcol + 1); + + $this->pro_uid = $rs->getString($startcol + 2); + + $this->tas_uid = $rs->getString($startcol + 3); + + $this->rou_next_task = $rs->getString($startcol + 4); + + $this->rou_case = $rs->getInt($startcol + 5); + + $this->rou_type = $rs->getString($startcol + 6); + + $this->rou_condition = $rs->getString($startcol + 7); + + $this->rou_to_last_user = $rs->getString($startcol + 8); + + $this->rou_optional = $rs->getString($startcol + 9); + + $this->rou_send_email = $rs->getString($startcol + 10); + + $this->rou_sourceanchor = $rs->getInt($startcol + 11); + + $this->rou_targetanchor = $rs->getInt($startcol + 12); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 13; // 13 = RoutePeer::NUM_COLUMNS - RoutePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Route object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(RoutePeer::DATABASE_NAME); + } + + try { + $con->begin(); + RoutePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(RoutePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = RoutePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += RoutePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = RoutePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = RoutePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getRouUid(); + break; + case 1: + return $this->getRouParent(); + break; + case 2: + return $this->getProUid(); + break; + case 3: + return $this->getTasUid(); + break; + case 4: + return $this->getRouNextTask(); + break; + case 5: + return $this->getRouCase(); + break; + case 6: + return $this->getRouType(); + break; + case 7: + return $this->getRouCondition(); + break; + case 8: + return $this->getRouToLastUser(); + break; + case 9: + return $this->getRouOptional(); + break; + case 10: + return $this->getRouSendEmail(); + break; + case 11: + return $this->getRouSourceanchor(); + break; + case 12: + return $this->getRouTargetanchor(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = RoutePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getRouUid(), + $keys[1] => $this->getRouParent(), + $keys[2] => $this->getProUid(), + $keys[3] => $this->getTasUid(), + $keys[4] => $this->getRouNextTask(), + $keys[5] => $this->getRouCase(), + $keys[6] => $this->getRouType(), + $keys[7] => $this->getRouCondition(), + $keys[8] => $this->getRouToLastUser(), + $keys[9] => $this->getRouOptional(), + $keys[10] => $this->getRouSendEmail(), + $keys[11] => $this->getRouSourceanchor(), + $keys[12] => $this->getRouTargetanchor(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = RoutePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setRouUid($value); + break; + case 1: + $this->setRouParent($value); + break; + case 2: + $this->setProUid($value); + break; + case 3: + $this->setTasUid($value); + break; + case 4: + $this->setRouNextTask($value); + break; + case 5: + $this->setRouCase($value); + break; + case 6: + $this->setRouType($value); + break; + case 7: + $this->setRouCondition($value); + break; + case 8: + $this->setRouToLastUser($value); + break; + case 9: + $this->setRouOptional($value); + break; + case 10: + $this->setRouSendEmail($value); + break; + case 11: + $this->setRouSourceanchor($value); + break; + case 12: + $this->setRouTargetanchor($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = RoutePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setRouUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setRouParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setProUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTasUid($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setRouNextTask($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setRouCase($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setRouType($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setRouCondition($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setRouToLastUser($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setRouOptional($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setRouSendEmail($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setRouSourceanchor($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setRouTargetanchor($arr[$keys[12]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(RoutePeer::DATABASE_NAME); + + if ($this->isColumnModified(RoutePeer::ROU_UID)) $criteria->add(RoutePeer::ROU_UID, $this->rou_uid); + if ($this->isColumnModified(RoutePeer::ROU_PARENT)) $criteria->add(RoutePeer::ROU_PARENT, $this->rou_parent); + if ($this->isColumnModified(RoutePeer::PRO_UID)) $criteria->add(RoutePeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(RoutePeer::TAS_UID)) $criteria->add(RoutePeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(RoutePeer::ROU_NEXT_TASK)) $criteria->add(RoutePeer::ROU_NEXT_TASK, $this->rou_next_task); + if ($this->isColumnModified(RoutePeer::ROU_CASE)) $criteria->add(RoutePeer::ROU_CASE, $this->rou_case); + if ($this->isColumnModified(RoutePeer::ROU_TYPE)) $criteria->add(RoutePeer::ROU_TYPE, $this->rou_type); + if ($this->isColumnModified(RoutePeer::ROU_CONDITION)) $criteria->add(RoutePeer::ROU_CONDITION, $this->rou_condition); + if ($this->isColumnModified(RoutePeer::ROU_TO_LAST_USER)) $criteria->add(RoutePeer::ROU_TO_LAST_USER, $this->rou_to_last_user); + if ($this->isColumnModified(RoutePeer::ROU_OPTIONAL)) $criteria->add(RoutePeer::ROU_OPTIONAL, $this->rou_optional); + if ($this->isColumnModified(RoutePeer::ROU_SEND_EMAIL)) $criteria->add(RoutePeer::ROU_SEND_EMAIL, $this->rou_send_email); + if ($this->isColumnModified(RoutePeer::ROU_SOURCEANCHOR)) $criteria->add(RoutePeer::ROU_SOURCEANCHOR, $this->rou_sourceanchor); + if ($this->isColumnModified(RoutePeer::ROU_TARGETANCHOR)) $criteria->add(RoutePeer::ROU_TARGETANCHOR, $this->rou_targetanchor); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(RoutePeer::DATABASE_NAME); + + $criteria->add(RoutePeer::ROU_UID, $this->rou_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getRouUid(); + } + + /** + * Generic method to set the primary key (rou_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setRouUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Route (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setRouParent($this->rou_parent); + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setRouNextTask($this->rou_next_task); + + $copyObj->setRouCase($this->rou_case); + + $copyObj->setRouType($this->rou_type); + + $copyObj->setRouCondition($this->rou_condition); + + $copyObj->setRouToLastUser($this->rou_to_last_user); + + $copyObj->setRouOptional($this->rou_optional); + + $copyObj->setRouSendEmail($this->rou_send_email); + + $copyObj->setRouSourceanchor($this->rou_sourceanchor); + + $copyObj->setRouTargetanchor($this->rou_targetanchor); + + + $copyObj->setNew(true); + + $copyObj->setRouUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Route Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return RoutePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new RoutePeer(); + } + return self::$peer; + } + +} // BaseRoute diff --git a/workflow/engine/classes/model/om/BaseRoutePeer.php b/workflow/engine/classes/model/om/BaseRoutePeer.php new file mode 100644 index 000000000..7d4c24ddb --- /dev/null +++ b/workflow/engine/classes/model/om/BaseRoutePeer.php @@ -0,0 +1,649 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by RoutePeer::getOMClass() +include_once 'classes/model/Route.php'; + +/** + * Base static class for performing query and update operations on the 'ROUTE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseRoutePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'ROUTE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Route'; + + /** The total number of columns. */ + const NUM_COLUMNS = 13; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the ROU_UID field */ + const ROU_UID = 'ROUTE.ROU_UID'; + + /** the column name for the ROU_PARENT field */ + const ROU_PARENT = 'ROUTE.ROU_PARENT'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'ROUTE.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'ROUTE.TAS_UID'; + + /** the column name for the ROU_NEXT_TASK field */ + const ROU_NEXT_TASK = 'ROUTE.ROU_NEXT_TASK'; + + /** the column name for the ROU_CASE field */ + const ROU_CASE = 'ROUTE.ROU_CASE'; + + /** the column name for the ROU_TYPE field */ + const ROU_TYPE = 'ROUTE.ROU_TYPE'; + + /** the column name for the ROU_CONDITION field */ + const ROU_CONDITION = 'ROUTE.ROU_CONDITION'; + + /** the column name for the ROU_TO_LAST_USER field */ + const ROU_TO_LAST_USER = 'ROUTE.ROU_TO_LAST_USER'; + + /** the column name for the ROU_OPTIONAL field */ + const ROU_OPTIONAL = 'ROUTE.ROU_OPTIONAL'; + + /** the column name for the ROU_SEND_EMAIL field */ + const ROU_SEND_EMAIL = 'ROUTE.ROU_SEND_EMAIL'; + + /** the column name for the ROU_SOURCEANCHOR field */ + const ROU_SOURCEANCHOR = 'ROUTE.ROU_SOURCEANCHOR'; + + /** the column name for the ROU_TARGETANCHOR field */ + const ROU_TARGETANCHOR = 'ROUTE.ROU_TARGETANCHOR'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('RouUid', 'RouParent', 'ProUid', 'TasUid', 'RouNextTask', 'RouCase', 'RouType', 'RouCondition', 'RouToLastUser', 'RouOptional', 'RouSendEmail', 'RouSourceanchor', 'RouTargetanchor', ), + BasePeer::TYPE_COLNAME => array (RoutePeer::ROU_UID, RoutePeer::ROU_PARENT, RoutePeer::PRO_UID, RoutePeer::TAS_UID, RoutePeer::ROU_NEXT_TASK, RoutePeer::ROU_CASE, RoutePeer::ROU_TYPE, RoutePeer::ROU_CONDITION, RoutePeer::ROU_TO_LAST_USER, RoutePeer::ROU_OPTIONAL, RoutePeer::ROU_SEND_EMAIL, RoutePeer::ROU_SOURCEANCHOR, RoutePeer::ROU_TARGETANCHOR, ), + BasePeer::TYPE_FIELDNAME => array ('ROU_UID', 'ROU_PARENT', 'PRO_UID', 'TAS_UID', 'ROU_NEXT_TASK', 'ROU_CASE', 'ROU_TYPE', 'ROU_CONDITION', 'ROU_TO_LAST_USER', 'ROU_OPTIONAL', 'ROU_SEND_EMAIL', 'ROU_SOURCEANCHOR', 'ROU_TARGETANCHOR', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('RouUid' => 0, 'RouParent' => 1, 'ProUid' => 2, 'TasUid' => 3, 'RouNextTask' => 4, 'RouCase' => 5, 'RouType' => 6, 'RouCondition' => 7, 'RouToLastUser' => 8, 'RouOptional' => 9, 'RouSendEmail' => 10, 'RouSourceanchor' => 11, 'RouTargetanchor' => 12, ), + BasePeer::TYPE_COLNAME => array (RoutePeer::ROU_UID => 0, RoutePeer::ROU_PARENT => 1, RoutePeer::PRO_UID => 2, RoutePeer::TAS_UID => 3, RoutePeer::ROU_NEXT_TASK => 4, RoutePeer::ROU_CASE => 5, RoutePeer::ROU_TYPE => 6, RoutePeer::ROU_CONDITION => 7, RoutePeer::ROU_TO_LAST_USER => 8, RoutePeer::ROU_OPTIONAL => 9, RoutePeer::ROU_SEND_EMAIL => 10, RoutePeer::ROU_SOURCEANCHOR => 11, RoutePeer::ROU_TARGETANCHOR => 12, ), + BasePeer::TYPE_FIELDNAME => array ('ROU_UID' => 0, 'ROU_PARENT' => 1, 'PRO_UID' => 2, 'TAS_UID' => 3, 'ROU_NEXT_TASK' => 4, 'ROU_CASE' => 5, 'ROU_TYPE' => 6, 'ROU_CONDITION' => 7, 'ROU_TO_LAST_USER' => 8, 'ROU_OPTIONAL' => 9, 'ROU_SEND_EMAIL' => 10, 'ROU_SOURCEANCHOR' => 11, 'ROU_TARGETANCHOR' => 12, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/RouteMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.RouteMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = RoutePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. RoutePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(RoutePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(RoutePeer::ROU_UID); + + $criteria->addSelectColumn(RoutePeer::ROU_PARENT); + + $criteria->addSelectColumn(RoutePeer::PRO_UID); + + $criteria->addSelectColumn(RoutePeer::TAS_UID); + + $criteria->addSelectColumn(RoutePeer::ROU_NEXT_TASK); + + $criteria->addSelectColumn(RoutePeer::ROU_CASE); + + $criteria->addSelectColumn(RoutePeer::ROU_TYPE); + + $criteria->addSelectColumn(RoutePeer::ROU_CONDITION); + + $criteria->addSelectColumn(RoutePeer::ROU_TO_LAST_USER); + + $criteria->addSelectColumn(RoutePeer::ROU_OPTIONAL); + + $criteria->addSelectColumn(RoutePeer::ROU_SEND_EMAIL); + + $criteria->addSelectColumn(RoutePeer::ROU_SOURCEANCHOR); + + $criteria->addSelectColumn(RoutePeer::ROU_TARGETANCHOR); + + } + + const COUNT = 'COUNT(ROUTE.ROU_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT ROUTE.ROU_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(RoutePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(RoutePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = RoutePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Route + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = RoutePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return RoutePeer::populateObjects(RoutePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + RoutePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = RoutePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return RoutePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Route or Criteria object. + * + * @param mixed $values Criteria or Route object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Route object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Route or Criteria object. + * + * @param mixed $values Criteria or Route object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(RoutePeer::ROU_UID); + $selectCriteria->add(RoutePeer::ROU_UID, $criteria->remove(RoutePeer::ROU_UID), $comparison); + + } else { // $values is Route object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the ROUTE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(RoutePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Route or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Route object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(RoutePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Route) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(RoutePeer::ROU_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Route object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Route $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Route $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(RoutePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(RoutePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_UID)) + $columns[RoutePeer::ROU_UID] = $obj->getRouUid(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::PRO_UID)) + $columns[RoutePeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::TAS_UID)) + $columns[RoutePeer::TAS_UID] = $obj->getTasUid(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_NEXT_TASK)) + $columns[RoutePeer::ROU_NEXT_TASK] = $obj->getRouNextTask(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_TYPE)) + $columns[RoutePeer::ROU_TYPE] = $obj->getRouType(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_TO_LAST_USER)) + $columns[RoutePeer::ROU_TO_LAST_USER] = $obj->getRouToLastUser(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_OPTIONAL)) + $columns[RoutePeer::ROU_OPTIONAL] = $obj->getRouOptional(); + + if ($obj->isNew() || $obj->isColumnModified(RoutePeer::ROU_SEND_EMAIL)) + $columns[RoutePeer::ROU_SEND_EMAIL] = $obj->getRouSendEmail(); + + } + + return BasePeer::doValidate(RoutePeer::DATABASE_NAME, RoutePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Route + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(RoutePeer::DATABASE_NAME); + + $criteria->add(RoutePeer::ROU_UID, $pk); + + + $v = RoutePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(RoutePeer::ROU_UID, $pks, Criteria::IN); + $objs = RoutePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseRoutePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseRoutePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/RouteMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.RouteMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseSession.php b/workflow/engine/classes/model/om/BaseSession.php new file mode 100644 index 000000000..d8a587cb6 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSession.php @@ -0,0 +1,822 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/SessionPeer.php'; + +/** + * Base class that represents a row from the 'SESSION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSession extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var SessionPeer + */ + protected static $peer; + + + /** + * The value for the ses_uid field. + * @var string + */ + protected $ses_uid = ''; + + + /** + * The value for the ses_status field. + * @var string + */ + protected $ses_status = 'ACTIVE'; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = 'ACTIVE'; + + + /** + * The value for the ses_remote_ip field. + * @var string + */ + protected $ses_remote_ip = '0.0.0.0'; + + + /** + * The value for the ses_init_date field. + * @var string + */ + protected $ses_init_date = ''; + + + /** + * The value for the ses_due_date field. + * @var string + */ + protected $ses_due_date = ''; + + + /** + * The value for the ses_end_date field. + * @var string + */ + protected $ses_end_date = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [ses_uid] column value. + * + * @return string + */ + public function getSesUid() + { + + return $this->ses_uid; + } + + /** + * Get the [ses_status] column value. + * + * @return string + */ + public function getSesStatus() + { + + return $this->ses_status; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [ses_remote_ip] column value. + * + * @return string + */ + public function getSesRemoteIp() + { + + return $this->ses_remote_ip; + } + + /** + * Get the [ses_init_date] column value. + * + * @return string + */ + public function getSesInitDate() + { + + return $this->ses_init_date; + } + + /** + * Get the [ses_due_date] column value. + * + * @return string + */ + public function getSesDueDate() + { + + return $this->ses_due_date; + } + + /** + * Get the [ses_end_date] column value. + * + * @return string + */ + public function getSesEndDate() + { + + return $this->ses_end_date; + } + + /** + * Set the value of [ses_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSesUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_uid !== $v || $v === '') { + $this->ses_uid = $v; + $this->modifiedColumns[] = SessionPeer::SES_UID; + } + + } // setSesUid() + + /** + * Set the value of [ses_status] column. + * + * @param string $v new value + * @return void + */ + public function setSesStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_status !== $v || $v === 'ACTIVE') { + $this->ses_status = $v; + $this->modifiedColumns[] = SessionPeer::SES_STATUS; + } + + } // setSesStatus() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === 'ACTIVE') { + $this->usr_uid = $v; + $this->modifiedColumns[] = SessionPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [ses_remote_ip] column. + * + * @param string $v new value + * @return void + */ + public function setSesRemoteIp($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_remote_ip !== $v || $v === '0.0.0.0') { + $this->ses_remote_ip = $v; + $this->modifiedColumns[] = SessionPeer::SES_REMOTE_IP; + } + + } // setSesRemoteIp() + + /** + * Set the value of [ses_init_date] column. + * + * @param string $v new value + * @return void + */ + public function setSesInitDate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_init_date !== $v || $v === '') { + $this->ses_init_date = $v; + $this->modifiedColumns[] = SessionPeer::SES_INIT_DATE; + } + + } // setSesInitDate() + + /** + * Set the value of [ses_due_date] column. + * + * @param string $v new value + * @return void + */ + public function setSesDueDate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_due_date !== $v || $v === '') { + $this->ses_due_date = $v; + $this->modifiedColumns[] = SessionPeer::SES_DUE_DATE; + } + + } // setSesDueDate() + + /** + * Set the value of [ses_end_date] column. + * + * @param string $v new value + * @return void + */ + public function setSesEndDate($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->ses_end_date !== $v || $v === '') { + $this->ses_end_date = $v; + $this->modifiedColumns[] = SessionPeer::SES_END_DATE; + } + + } // setSesEndDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->ses_uid = $rs->getString($startcol + 0); + + $this->ses_status = $rs->getString($startcol + 1); + + $this->usr_uid = $rs->getString($startcol + 2); + + $this->ses_remote_ip = $rs->getString($startcol + 3); + + $this->ses_init_date = $rs->getString($startcol + 4); + + $this->ses_due_date = $rs->getString($startcol + 5); + + $this->ses_end_date = $rs->getString($startcol + 6); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = SessionPeer::NUM_COLUMNS - SessionPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Session object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SessionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + SessionPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SessionPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = SessionPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += SessionPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = SessionPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SessionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getSesUid(); + break; + case 1: + return $this->getSesStatus(); + break; + case 2: + return $this->getUsrUid(); + break; + case 3: + return $this->getSesRemoteIp(); + break; + case 4: + return $this->getSesInitDate(); + break; + case 5: + return $this->getSesDueDate(); + break; + case 6: + return $this->getSesEndDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SessionPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getSesUid(), + $keys[1] => $this->getSesStatus(), + $keys[2] => $this->getUsrUid(), + $keys[3] => $this->getSesRemoteIp(), + $keys[4] => $this->getSesInitDate(), + $keys[5] => $this->getSesDueDate(), + $keys[6] => $this->getSesEndDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SessionPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setSesUid($value); + break; + case 1: + $this->setSesStatus($value); + break; + case 2: + $this->setUsrUid($value); + break; + case 3: + $this->setSesRemoteIp($value); + break; + case 4: + $this->setSesInitDate($value); + break; + case 5: + $this->setSesDueDate($value); + break; + case 6: + $this->setSesEndDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SessionPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setSesUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setSesStatus($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUsrUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setSesRemoteIp($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setSesInitDate($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setSesDueDate($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setSesEndDate($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(SessionPeer::DATABASE_NAME); + + if ($this->isColumnModified(SessionPeer::SES_UID)) $criteria->add(SessionPeer::SES_UID, $this->ses_uid); + if ($this->isColumnModified(SessionPeer::SES_STATUS)) $criteria->add(SessionPeer::SES_STATUS, $this->ses_status); + if ($this->isColumnModified(SessionPeer::USR_UID)) $criteria->add(SessionPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(SessionPeer::SES_REMOTE_IP)) $criteria->add(SessionPeer::SES_REMOTE_IP, $this->ses_remote_ip); + if ($this->isColumnModified(SessionPeer::SES_INIT_DATE)) $criteria->add(SessionPeer::SES_INIT_DATE, $this->ses_init_date); + if ($this->isColumnModified(SessionPeer::SES_DUE_DATE)) $criteria->add(SessionPeer::SES_DUE_DATE, $this->ses_due_date); + if ($this->isColumnModified(SessionPeer::SES_END_DATE)) $criteria->add(SessionPeer::SES_END_DATE, $this->ses_end_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(SessionPeer::DATABASE_NAME); + + $criteria->add(SessionPeer::SES_UID, $this->ses_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getSesUid(); + } + + /** + * Generic method to set the primary key (ses_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setSesUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Session (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setSesStatus($this->ses_status); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setSesRemoteIp($this->ses_remote_ip); + + $copyObj->setSesInitDate($this->ses_init_date); + + $copyObj->setSesDueDate($this->ses_due_date); + + $copyObj->setSesEndDate($this->ses_end_date); + + + $copyObj->setNew(true); + + $copyObj->setSesUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Session Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return SessionPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new SessionPeer(); + } + return self::$peer; + } + +} // BaseSession diff --git a/workflow/engine/classes/model/om/BaseSessionPeer.php b/workflow/engine/classes/model/om/BaseSessionPeer.php new file mode 100644 index 000000000..b89c81af0 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSessionPeer.php @@ -0,0 +1,595 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by SessionPeer::getOMClass() +include_once 'classes/model/Session.php'; + +/** + * Base static class for performing query and update operations on the 'SESSION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSessionPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'SESSION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Session'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the SES_UID field */ + const SES_UID = 'SESSION.SES_UID'; + + /** the column name for the SES_STATUS field */ + const SES_STATUS = 'SESSION.SES_STATUS'; + + /** the column name for the USR_UID field */ + const USR_UID = 'SESSION.USR_UID'; + + /** the column name for the SES_REMOTE_IP field */ + const SES_REMOTE_IP = 'SESSION.SES_REMOTE_IP'; + + /** the column name for the SES_INIT_DATE field */ + const SES_INIT_DATE = 'SESSION.SES_INIT_DATE'; + + /** the column name for the SES_DUE_DATE field */ + const SES_DUE_DATE = 'SESSION.SES_DUE_DATE'; + + /** the column name for the SES_END_DATE field */ + const SES_END_DATE = 'SESSION.SES_END_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('SesUid', 'SesStatus', 'UsrUid', 'SesRemoteIp', 'SesInitDate', 'SesDueDate', 'SesEndDate', ), + BasePeer::TYPE_COLNAME => array (SessionPeer::SES_UID, SessionPeer::SES_STATUS, SessionPeer::USR_UID, SessionPeer::SES_REMOTE_IP, SessionPeer::SES_INIT_DATE, SessionPeer::SES_DUE_DATE, SessionPeer::SES_END_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('SES_UID', 'SES_STATUS', 'USR_UID', 'SES_REMOTE_IP', 'SES_INIT_DATE', 'SES_DUE_DATE', 'SES_END_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('SesUid' => 0, 'SesStatus' => 1, 'UsrUid' => 2, 'SesRemoteIp' => 3, 'SesInitDate' => 4, 'SesDueDate' => 5, 'SesEndDate' => 6, ), + BasePeer::TYPE_COLNAME => array (SessionPeer::SES_UID => 0, SessionPeer::SES_STATUS => 1, SessionPeer::USR_UID => 2, SessionPeer::SES_REMOTE_IP => 3, SessionPeer::SES_INIT_DATE => 4, SessionPeer::SES_DUE_DATE => 5, SessionPeer::SES_END_DATE => 6, ), + BasePeer::TYPE_FIELDNAME => array ('SES_UID' => 0, 'SES_STATUS' => 1, 'USR_UID' => 2, 'SES_REMOTE_IP' => 3, 'SES_INIT_DATE' => 4, 'SES_DUE_DATE' => 5, 'SES_END_DATE' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/SessionMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.SessionMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = SessionPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. SessionPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(SessionPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(SessionPeer::SES_UID); + + $criteria->addSelectColumn(SessionPeer::SES_STATUS); + + $criteria->addSelectColumn(SessionPeer::USR_UID); + + $criteria->addSelectColumn(SessionPeer::SES_REMOTE_IP); + + $criteria->addSelectColumn(SessionPeer::SES_INIT_DATE); + + $criteria->addSelectColumn(SessionPeer::SES_DUE_DATE); + + $criteria->addSelectColumn(SessionPeer::SES_END_DATE); + + } + + const COUNT = 'COUNT(SESSION.SES_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT SESSION.SES_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(SessionPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(SessionPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = SessionPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Session + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = SessionPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return SessionPeer::populateObjects(SessionPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + SessionPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = SessionPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return SessionPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Session or Criteria object. + * + * @param mixed $values Criteria or Session object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Session object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Session or Criteria object. + * + * @param mixed $values Criteria or Session object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(SessionPeer::SES_UID); + $selectCriteria->add(SessionPeer::SES_UID, $criteria->remove(SessionPeer::SES_UID), $comparison); + + } else { // $values is Session object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the SESSION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(SessionPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Session or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Session object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(SessionPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Session) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(SessionPeer::SES_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Session object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Session $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Session $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(SessionPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(SessionPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(SessionPeer::DATABASE_NAME, SessionPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Session + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(SessionPeer::DATABASE_NAME); + + $criteria->add(SessionPeer::SES_UID, $pk); + + + $v = SessionPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(SessionPeer::SES_UID, $pks, Criteria::IN); + $objs = SessionPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseSessionPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseSessionPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/SessionMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.SessionMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseShadowTable.php b/workflow/engine/classes/model/om/BaseShadowTable.php new file mode 100644 index 000000000..4916343a4 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseShadowTable.php @@ -0,0 +1,844 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/ShadowTablePeer.php'; + +/** + * Base class that represents a row from the 'SHADOW_TABLE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseShadowTable extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var ShadowTablePeer + */ + protected static $peer; + + + /** + * The value for the shd_uid field. + * @var string + */ + protected $shd_uid = ''; + + + /** + * The value for the add_tab_uid field. + * @var string + */ + protected $add_tab_uid = ''; + + + /** + * The value for the shd_action field. + * @var string + */ + protected $shd_action = ''; + + + /** + * The value for the shd_details field. + * @var string + */ + protected $shd_details; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the shd_date field. + * @var int + */ + protected $shd_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [shd_uid] column value. + * + * @return string + */ + public function getShdUid() + { + + return $this->shd_uid; + } + + /** + * Get the [add_tab_uid] column value. + * + * @return string + */ + public function getAddTabUid() + { + + return $this->add_tab_uid; + } + + /** + * Get the [shd_action] column value. + * + * @return string + */ + public function getShdAction() + { + + return $this->shd_action; + } + + /** + * Get the [shd_details] column value. + * + * @return string + */ + public function getShdDetails() + { + + return $this->shd_details; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [optionally formatted] [shd_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getShdDate($format = 'Y-m-d H:i:s') + { + + if ($this->shd_date === null || $this->shd_date === '') { + return null; + } elseif (!is_int($this->shd_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->shd_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [shd_date] as date/time value: " . var_export($this->shd_date, true)); + } + } else { + $ts = $this->shd_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [shd_uid] column. + * + * @param string $v new value + * @return void + */ + public function setShdUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->shd_uid !== $v || $v === '') { + $this->shd_uid = $v; + $this->modifiedColumns[] = ShadowTablePeer::SHD_UID; + } + + } // setShdUid() + + /** + * Set the value of [add_tab_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAddTabUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->add_tab_uid !== $v || $v === '') { + $this->add_tab_uid = $v; + $this->modifiedColumns[] = ShadowTablePeer::ADD_TAB_UID; + } + + } // setAddTabUid() + + /** + * Set the value of [shd_action] column. + * + * @param string $v new value + * @return void + */ + public function setShdAction($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->shd_action !== $v || $v === '') { + $this->shd_action = $v; + $this->modifiedColumns[] = ShadowTablePeer::SHD_ACTION; + } + + } // setShdAction() + + /** + * Set the value of [shd_details] column. + * + * @param string $v new value + * @return void + */ + public function setShdDetails($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->shd_details !== $v) { + $this->shd_details = $v; + $this->modifiedColumns[] = ShadowTablePeer::SHD_DETAILS; + } + + } // setShdDetails() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = ShadowTablePeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = ShadowTablePeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [shd_date] column. + * + * @param int $v new value + * @return void + */ + public function setShdDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [shd_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->shd_date !== $ts) { + $this->shd_date = $ts; + $this->modifiedColumns[] = ShadowTablePeer::SHD_DATE; + } + + } // setShdDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->shd_uid = $rs->getString($startcol + 0); + + $this->add_tab_uid = $rs->getString($startcol + 1); + + $this->shd_action = $rs->getString($startcol + 2); + + $this->shd_details = $rs->getString($startcol + 3); + + $this->usr_uid = $rs->getString($startcol + 4); + + $this->app_uid = $rs->getString($startcol + 5); + + $this->shd_date = $rs->getTimestamp($startcol + 6, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 7; // 7 = ShadowTablePeer::NUM_COLUMNS - ShadowTablePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating ShadowTable object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ShadowTablePeer::DATABASE_NAME); + } + + try { + $con->begin(); + ShadowTablePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(ShadowTablePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = ShadowTablePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += ShadowTablePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = ShadowTablePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ShadowTablePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getShdUid(); + break; + case 1: + return $this->getAddTabUid(); + break; + case 2: + return $this->getShdAction(); + break; + case 3: + return $this->getShdDetails(); + break; + case 4: + return $this->getUsrUid(); + break; + case 5: + return $this->getAppUid(); + break; + case 6: + return $this->getShdDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ShadowTablePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getShdUid(), + $keys[1] => $this->getAddTabUid(), + $keys[2] => $this->getShdAction(), + $keys[3] => $this->getShdDetails(), + $keys[4] => $this->getUsrUid(), + $keys[5] => $this->getAppUid(), + $keys[6] => $this->getShdDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = ShadowTablePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setShdUid($value); + break; + case 1: + $this->setAddTabUid($value); + break; + case 2: + $this->setShdAction($value); + break; + case 3: + $this->setShdDetails($value); + break; + case 4: + $this->setUsrUid($value); + break; + case 5: + $this->setAppUid($value); + break; + case 6: + $this->setShdDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = ShadowTablePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setShdUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAddTabUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setShdAction($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setShdDetails($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUsrUid($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAppUid($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setShdDate($arr[$keys[6]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ShadowTablePeer::DATABASE_NAME); + + if ($this->isColumnModified(ShadowTablePeer::SHD_UID)) $criteria->add(ShadowTablePeer::SHD_UID, $this->shd_uid); + if ($this->isColumnModified(ShadowTablePeer::ADD_TAB_UID)) $criteria->add(ShadowTablePeer::ADD_TAB_UID, $this->add_tab_uid); + if ($this->isColumnModified(ShadowTablePeer::SHD_ACTION)) $criteria->add(ShadowTablePeer::SHD_ACTION, $this->shd_action); + if ($this->isColumnModified(ShadowTablePeer::SHD_DETAILS)) $criteria->add(ShadowTablePeer::SHD_DETAILS, $this->shd_details); + if ($this->isColumnModified(ShadowTablePeer::USR_UID)) $criteria->add(ShadowTablePeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(ShadowTablePeer::APP_UID)) $criteria->add(ShadowTablePeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(ShadowTablePeer::SHD_DATE)) $criteria->add(ShadowTablePeer::SHD_DATE, $this->shd_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ShadowTablePeer::DATABASE_NAME); + + $criteria->add(ShadowTablePeer::SHD_UID, $this->shd_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getShdUid(); + } + + /** + * Generic method to set the primary key (shd_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setShdUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of ShadowTable (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setAddTabUid($this->add_tab_uid); + + $copyObj->setShdAction($this->shd_action); + + $copyObj->setShdDetails($this->shd_details); + + $copyObj->setUsrUid($this->usr_uid); + + $copyObj->setAppUid($this->app_uid); + + $copyObj->setShdDate($this->shd_date); + + + $copyObj->setNew(true); + + $copyObj->setShdUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return ShadowTable Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return ShadowTablePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new ShadowTablePeer(); + } + return self::$peer; + } + +} // BaseShadowTable diff --git a/workflow/engine/classes/model/om/BaseShadowTablePeer.php b/workflow/engine/classes/model/om/BaseShadowTablePeer.php new file mode 100644 index 000000000..3097a8306 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseShadowTablePeer.php @@ -0,0 +1,595 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by ShadowTablePeer::getOMClass() +include_once 'classes/model/ShadowTable.php'; + +/** + * Base static class for performing query and update operations on the 'SHADOW_TABLE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseShadowTablePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'SHADOW_TABLE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.ShadowTable'; + + /** The total number of columns. */ + const NUM_COLUMNS = 7; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the SHD_UID field */ + const SHD_UID = 'SHADOW_TABLE.SHD_UID'; + + /** the column name for the ADD_TAB_UID field */ + const ADD_TAB_UID = 'SHADOW_TABLE.ADD_TAB_UID'; + + /** the column name for the SHD_ACTION field */ + const SHD_ACTION = 'SHADOW_TABLE.SHD_ACTION'; + + /** the column name for the SHD_DETAILS field */ + const SHD_DETAILS = 'SHADOW_TABLE.SHD_DETAILS'; + + /** the column name for the USR_UID field */ + const USR_UID = 'SHADOW_TABLE.USR_UID'; + + /** the column name for the APP_UID field */ + const APP_UID = 'SHADOW_TABLE.APP_UID'; + + /** the column name for the SHD_DATE field */ + const SHD_DATE = 'SHADOW_TABLE.SHD_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ShdUid', 'AddTabUid', 'ShdAction', 'ShdDetails', 'UsrUid', 'AppUid', 'ShdDate', ), + BasePeer::TYPE_COLNAME => array (ShadowTablePeer::SHD_UID, ShadowTablePeer::ADD_TAB_UID, ShadowTablePeer::SHD_ACTION, ShadowTablePeer::SHD_DETAILS, ShadowTablePeer::USR_UID, ShadowTablePeer::APP_UID, ShadowTablePeer::SHD_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('SHD_UID', 'ADD_TAB_UID', 'SHD_ACTION', 'SHD_DETAILS', 'USR_UID', 'APP_UID', 'SHD_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ShdUid' => 0, 'AddTabUid' => 1, 'ShdAction' => 2, 'ShdDetails' => 3, 'UsrUid' => 4, 'AppUid' => 5, 'ShdDate' => 6, ), + BasePeer::TYPE_COLNAME => array (ShadowTablePeer::SHD_UID => 0, ShadowTablePeer::ADD_TAB_UID => 1, ShadowTablePeer::SHD_ACTION => 2, ShadowTablePeer::SHD_DETAILS => 3, ShadowTablePeer::USR_UID => 4, ShadowTablePeer::APP_UID => 5, ShadowTablePeer::SHD_DATE => 6, ), + BasePeer::TYPE_FIELDNAME => array ('SHD_UID' => 0, 'ADD_TAB_UID' => 1, 'SHD_ACTION' => 2, 'SHD_DETAILS' => 3, 'USR_UID' => 4, 'APP_UID' => 5, 'SHD_DATE' => 6, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/ShadowTableMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.ShadowTableMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = ShadowTablePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. ShadowTablePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(ShadowTablePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(ShadowTablePeer::SHD_UID); + + $criteria->addSelectColumn(ShadowTablePeer::ADD_TAB_UID); + + $criteria->addSelectColumn(ShadowTablePeer::SHD_ACTION); + + $criteria->addSelectColumn(ShadowTablePeer::SHD_DETAILS); + + $criteria->addSelectColumn(ShadowTablePeer::USR_UID); + + $criteria->addSelectColumn(ShadowTablePeer::APP_UID); + + $criteria->addSelectColumn(ShadowTablePeer::SHD_DATE); + + } + + const COUNT = 'COUNT(SHADOW_TABLE.SHD_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT SHADOW_TABLE.SHD_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(ShadowTablePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(ShadowTablePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = ShadowTablePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return ShadowTable + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = ShadowTablePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return ShadowTablePeer::populateObjects(ShadowTablePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + ShadowTablePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = ShadowTablePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return ShadowTablePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a ShadowTable or Criteria object. + * + * @param mixed $values Criteria or ShadowTable object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from ShadowTable object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a ShadowTable or Criteria object. + * + * @param mixed $values Criteria or ShadowTable object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(ShadowTablePeer::SHD_UID); + $selectCriteria->add(ShadowTablePeer::SHD_UID, $criteria->remove(ShadowTablePeer::SHD_UID), $comparison); + + } else { // $values is ShadowTable object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the SHADOW_TABLE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(ShadowTablePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a ShadowTable or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ShadowTable object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(ShadowTablePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof ShadowTable) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(ShadowTablePeer::SHD_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given ShadowTable object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param ShadowTable $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(ShadowTable $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(ShadowTablePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(ShadowTablePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(ShadowTablePeer::DATABASE_NAME, ShadowTablePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return ShadowTable + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(ShadowTablePeer::DATABASE_NAME); + + $criteria->add(ShadowTablePeer::SHD_UID, $pk); + + + $v = ShadowTablePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(ShadowTablePeer::SHD_UID, $pks, Criteria::IN); + $objs = ShadowTablePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseShadowTablePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseShadowTablePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/ShadowTableMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.ShadowTableMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseStage.php b/workflow/engine/classes/model/om/BaseStage.php new file mode 100644 index 000000000..e00e62ef1 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStage.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/StagePeer.php'; + +/** + * Base class that represents a row from the 'STAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStage extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var StagePeer + */ + protected static $peer; + + + /** + * The value for the stg_uid field. + * @var string + */ + protected $stg_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the stg_posx field. + * @var int + */ + protected $stg_posx = 0; + + + /** + * The value for the stg_posy field. + * @var int + */ + protected $stg_posy = 0; + + + /** + * The value for the stg_index field. + * @var int + */ + protected $stg_index = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [stg_uid] column value. + * + * @return string + */ + public function getStgUid() + { + + return $this->stg_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [stg_posx] column value. + * + * @return int + */ + public function getStgPosx() + { + + return $this->stg_posx; + } + + /** + * Get the [stg_posy] column value. + * + * @return int + */ + public function getStgPosy() + { + + return $this->stg_posy; + } + + /** + * Get the [stg_index] column value. + * + * @return int + */ + public function getStgIndex() + { + + return $this->stg_index; + } + + /** + * Set the value of [stg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setStgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->stg_uid !== $v || $v === '') { + $this->stg_uid = $v; + $this->modifiedColumns[] = StagePeer::STG_UID; + } + + } // setStgUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = StagePeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [stg_posx] column. + * + * @param int $v new value + * @return void + */ + public function setStgPosx($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->stg_posx !== $v || $v === 0) { + $this->stg_posx = $v; + $this->modifiedColumns[] = StagePeer::STG_POSX; + } + + } // setStgPosx() + + /** + * Set the value of [stg_posy] column. + * + * @param int $v new value + * @return void + */ + public function setStgPosy($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->stg_posy !== $v || $v === 0) { + $this->stg_posy = $v; + $this->modifiedColumns[] = StagePeer::STG_POSY; + } + + } // setStgPosy() + + /** + * Set the value of [stg_index] column. + * + * @param int $v new value + * @return void + */ + public function setStgIndex($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->stg_index !== $v || $v === 0) { + $this->stg_index = $v; + $this->modifiedColumns[] = StagePeer::STG_INDEX; + } + + } // setStgIndex() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->stg_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->stg_posx = $rs->getInt($startcol + 2); + + $this->stg_posy = $rs->getInt($startcol + 3); + + $this->stg_index = $rs->getInt($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = StagePeer::NUM_COLUMNS - StagePeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Stage object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + StagePeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StagePeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = StagePeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += StagePeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = StagePeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getStgUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getStgPosx(); + break; + case 3: + return $this->getStgPosy(); + break; + case 4: + return $this->getStgIndex(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StagePeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getStgUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getStgPosx(), + $keys[3] => $this->getStgPosy(), + $keys[4] => $this->getStgIndex(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StagePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setStgUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setStgPosx($value); + break; + case 3: + $this->setStgPosy($value); + break; + case 4: + $this->setStgIndex($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StagePeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setStgUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setStgPosx($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setStgPosy($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setStgIndex($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(StagePeer::DATABASE_NAME); + + if ($this->isColumnModified(StagePeer::STG_UID)) $criteria->add(StagePeer::STG_UID, $this->stg_uid); + if ($this->isColumnModified(StagePeer::PRO_UID)) $criteria->add(StagePeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(StagePeer::STG_POSX)) $criteria->add(StagePeer::STG_POSX, $this->stg_posx); + if ($this->isColumnModified(StagePeer::STG_POSY)) $criteria->add(StagePeer::STG_POSY, $this->stg_posy); + if ($this->isColumnModified(StagePeer::STG_INDEX)) $criteria->add(StagePeer::STG_INDEX, $this->stg_index); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(StagePeer::DATABASE_NAME); + + $criteria->add(StagePeer::STG_UID, $this->stg_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getStgUid(); + } + + /** + * Generic method to set the primary key (stg_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setStgUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Stage (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setStgPosx($this->stg_posx); + + $copyObj->setStgPosy($this->stg_posy); + + $copyObj->setStgIndex($this->stg_index); + + + $copyObj->setNew(true); + + $copyObj->setStgUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Stage Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return StagePeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new StagePeer(); + } + return self::$peer; + } + +} // BaseStage diff --git a/workflow/engine/classes/model/om/BaseStagePeer.php b/workflow/engine/classes/model/om/BaseStagePeer.php new file mode 100644 index 000000000..ad40fd42d --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStagePeer.php @@ -0,0 +1,585 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by StagePeer::getOMClass() +include_once 'classes/model/Stage.php'; + +/** + * Base static class for performing query and update operations on the 'STAGE' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStagePeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'STAGE'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Stage'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the STG_UID field */ + const STG_UID = 'STAGE.STG_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'STAGE.PRO_UID'; + + /** the column name for the STG_POSX field */ + const STG_POSX = 'STAGE.STG_POSX'; + + /** the column name for the STG_POSY field */ + const STG_POSY = 'STAGE.STG_POSY'; + + /** the column name for the STG_INDEX field */ + const STG_INDEX = 'STAGE.STG_INDEX'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('StgUid', 'ProUid', 'StgPosx', 'StgPosy', 'StgIndex', ), + BasePeer::TYPE_COLNAME => array (StagePeer::STG_UID, StagePeer::PRO_UID, StagePeer::STG_POSX, StagePeer::STG_POSY, StagePeer::STG_INDEX, ), + BasePeer::TYPE_FIELDNAME => array ('STG_UID', 'PRO_UID', 'STG_POSX', 'STG_POSY', 'STG_INDEX', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('StgUid' => 0, 'ProUid' => 1, 'StgPosx' => 2, 'StgPosy' => 3, 'StgIndex' => 4, ), + BasePeer::TYPE_COLNAME => array (StagePeer::STG_UID => 0, StagePeer::PRO_UID => 1, StagePeer::STG_POSX => 2, StagePeer::STG_POSY => 3, StagePeer::STG_INDEX => 4, ), + BasePeer::TYPE_FIELDNAME => array ('STG_UID' => 0, 'PRO_UID' => 1, 'STG_POSX' => 2, 'STG_POSY' => 3, 'STG_INDEX' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/StageMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.StageMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = StagePeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. StagePeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(StagePeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(StagePeer::STG_UID); + + $criteria->addSelectColumn(StagePeer::PRO_UID); + + $criteria->addSelectColumn(StagePeer::STG_POSX); + + $criteria->addSelectColumn(StagePeer::STG_POSY); + + $criteria->addSelectColumn(StagePeer::STG_INDEX); + + } + + const COUNT = 'COUNT(STAGE.STG_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT STAGE.STG_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(StagePeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(StagePeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = StagePeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Stage + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = StagePeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return StagePeer::populateObjects(StagePeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + StagePeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = StagePeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return StagePeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Stage or Criteria object. + * + * @param mixed $values Criteria or Stage object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Stage object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Stage or Criteria object. + * + * @param mixed $values Criteria or Stage object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(StagePeer::STG_UID); + $selectCriteria->add(StagePeer::STG_UID, $criteria->remove(StagePeer::STG_UID), $comparison); + + } else { // $values is Stage object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the STAGE table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(StagePeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Stage or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Stage object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(StagePeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Stage) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(StagePeer::STG_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Stage object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Stage $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Stage $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(StagePeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(StagePeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(StagePeer::DATABASE_NAME, StagePeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Stage + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(StagePeer::DATABASE_NAME); + + $criteria->add(StagePeer::STG_UID, $pk); + + + $v = StagePeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(StagePeer::STG_UID, $pks, Criteria::IN); + $objs = StagePeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseStagePeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseStagePeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/StageMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.StageMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseStep.php b/workflow/engine/classes/model/om/BaseStep.php new file mode 100644 index 000000000..3ee452d7c --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStep.php @@ -0,0 +1,875 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/StepPeer.php'; + +/** + * Base class that represents a row from the 'STEP' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStep extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var StepPeer + */ + protected static $peer; + + + /** + * The value for the step_uid field. + * @var string + */ + protected $step_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = '0'; + + + /** + * The value for the step_type_obj field. + * @var string + */ + protected $step_type_obj = 'DYNAFORM'; + + + /** + * The value for the step_uid_obj field. + * @var string + */ + protected $step_uid_obj = '0'; + + + /** + * The value for the step_condition field. + * @var string + */ + protected $step_condition; + + + /** + * The value for the step_position field. + * @var int + */ + protected $step_position = 0; + + + /** + * The value for the step_mode field. + * @var string + */ + protected $step_mode = 'EDIT'; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [step_uid] column value. + * + * @return string + */ + public function getStepUid() + { + + return $this->step_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [step_type_obj] column value. + * + * @return string + */ + public function getStepTypeObj() + { + + return $this->step_type_obj; + } + + /** + * Get the [step_uid_obj] column value. + * + * @return string + */ + public function getStepUidObj() + { + + return $this->step_uid_obj; + } + + /** + * Get the [step_condition] column value. + * + * @return string + */ + public function getStepCondition() + { + + return $this->step_condition; + } + + /** + * Get the [step_position] column value. + * + * @return int + */ + public function getStepPosition() + { + + return $this->step_position; + } + + /** + * Get the [step_mode] column value. + * + * @return string + */ + public function getStepMode() + { + + return $this->step_mode; + } + + /** + * Set the value of [step_uid] column. + * + * @param string $v new value + * @return void + */ + public function setStepUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_uid !== $v || $v === '') { + $this->step_uid = $v; + $this->modifiedColumns[] = StepPeer::STEP_UID; + } + + } // setStepUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = StepPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '0') { + $this->tas_uid = $v; + $this->modifiedColumns[] = StepPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [step_type_obj] column. + * + * @param string $v new value + * @return void + */ + public function setStepTypeObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_type_obj !== $v || $v === 'DYNAFORM') { + $this->step_type_obj = $v; + $this->modifiedColumns[] = StepPeer::STEP_TYPE_OBJ; + } + + } // setStepTypeObj() + + /** + * Set the value of [step_uid_obj] column. + * + * @param string $v new value + * @return void + */ + public function setStepUidObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_uid_obj !== $v || $v === '0') { + $this->step_uid_obj = $v; + $this->modifiedColumns[] = StepPeer::STEP_UID_OBJ; + } + + } // setStepUidObj() + + /** + * Set the value of [step_condition] column. + * + * @param string $v new value + * @return void + */ + public function setStepCondition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_condition !== $v) { + $this->step_condition = $v; + $this->modifiedColumns[] = StepPeer::STEP_CONDITION; + } + + } // setStepCondition() + + /** + * Set the value of [step_position] column. + * + * @param int $v new value + * @return void + */ + public function setStepPosition($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->step_position !== $v || $v === 0) { + $this->step_position = $v; + $this->modifiedColumns[] = StepPeer::STEP_POSITION; + } + + } // setStepPosition() + + /** + * Set the value of [step_mode] column. + * + * @param string $v new value + * @return void + */ + public function setStepMode($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_mode !== $v || $v === 'EDIT') { + $this->step_mode = $v; + $this->modifiedColumns[] = StepPeer::STEP_MODE; + } + + } // setStepMode() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->step_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->tas_uid = $rs->getString($startcol + 2); + + $this->step_type_obj = $rs->getString($startcol + 3); + + $this->step_uid_obj = $rs->getString($startcol + 4); + + $this->step_condition = $rs->getString($startcol + 5); + + $this->step_position = $rs->getInt($startcol + 6); + + $this->step_mode = $rs->getString($startcol + 7); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 8; // 8 = StepPeer::NUM_COLUMNS - StepPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Step object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + } + + try { + $con->begin(); + StepPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = StepPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += StepPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = StepPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getStepUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getTasUid(); + break; + case 3: + return $this->getStepTypeObj(); + break; + case 4: + return $this->getStepUidObj(); + break; + case 5: + return $this->getStepCondition(); + break; + case 6: + return $this->getStepPosition(); + break; + case 7: + return $this->getStepMode(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getStepUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getTasUid(), + $keys[3] => $this->getStepTypeObj(), + $keys[4] => $this->getStepUidObj(), + $keys[5] => $this->getStepCondition(), + $keys[6] => $this->getStepPosition(), + $keys[7] => $this->getStepMode(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setStepUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setTasUid($value); + break; + case 3: + $this->setStepTypeObj($value); + break; + case 4: + $this->setStepUidObj($value); + break; + case 5: + $this->setStepCondition($value); + break; + case 6: + $this->setStepPosition($value); + break; + case 7: + $this->setStepMode($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setStepUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTasUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setStepTypeObj($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setStepUidObj($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setStepCondition($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setStepPosition($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setStepMode($arr[$keys[7]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(StepPeer::DATABASE_NAME); + + if ($this->isColumnModified(StepPeer::STEP_UID)) $criteria->add(StepPeer::STEP_UID, $this->step_uid); + if ($this->isColumnModified(StepPeer::PRO_UID)) $criteria->add(StepPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(StepPeer::TAS_UID)) $criteria->add(StepPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(StepPeer::STEP_TYPE_OBJ)) $criteria->add(StepPeer::STEP_TYPE_OBJ, $this->step_type_obj); + if ($this->isColumnModified(StepPeer::STEP_UID_OBJ)) $criteria->add(StepPeer::STEP_UID_OBJ, $this->step_uid_obj); + if ($this->isColumnModified(StepPeer::STEP_CONDITION)) $criteria->add(StepPeer::STEP_CONDITION, $this->step_condition); + if ($this->isColumnModified(StepPeer::STEP_POSITION)) $criteria->add(StepPeer::STEP_POSITION, $this->step_position); + if ($this->isColumnModified(StepPeer::STEP_MODE)) $criteria->add(StepPeer::STEP_MODE, $this->step_mode); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(StepPeer::DATABASE_NAME); + + $criteria->add(StepPeer::STEP_UID, $this->step_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getStepUid(); + } + + /** + * Generic method to set the primary key (step_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setStepUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Step (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setStepTypeObj($this->step_type_obj); + + $copyObj->setStepUidObj($this->step_uid_obj); + + $copyObj->setStepCondition($this->step_condition); + + $copyObj->setStepPosition($this->step_position); + + $copyObj->setStepMode($this->step_mode); + + + $copyObj->setNew(true); + + $copyObj->setStepUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Step Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return StepPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new StepPeer(); + } + return self::$peer; + } + +} // BaseStep diff --git a/workflow/engine/classes/model/om/BaseStepPeer.php b/workflow/engine/classes/model/om/BaseStepPeer.php new file mode 100644 index 000000000..31c93a195 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStepPeer.php @@ -0,0 +1,603 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by StepPeer::getOMClass() +include_once 'classes/model/Step.php'; + +/** + * Base static class for performing query and update operations on the 'STEP' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStepPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'STEP'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Step'; + + /** The total number of columns. */ + const NUM_COLUMNS = 8; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the STEP_UID field */ + const STEP_UID = 'STEP.STEP_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'STEP.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'STEP.TAS_UID'; + + /** the column name for the STEP_TYPE_OBJ field */ + const STEP_TYPE_OBJ = 'STEP.STEP_TYPE_OBJ'; + + /** the column name for the STEP_UID_OBJ field */ + const STEP_UID_OBJ = 'STEP.STEP_UID_OBJ'; + + /** the column name for the STEP_CONDITION field */ + const STEP_CONDITION = 'STEP.STEP_CONDITION'; + + /** the column name for the STEP_POSITION field */ + const STEP_POSITION = 'STEP.STEP_POSITION'; + + /** the column name for the STEP_MODE field */ + const STEP_MODE = 'STEP.STEP_MODE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid', 'ProUid', 'TasUid', 'StepTypeObj', 'StepUidObj', 'StepCondition', 'StepPosition', 'StepMode', ), + BasePeer::TYPE_COLNAME => array (StepPeer::STEP_UID, StepPeer::PRO_UID, StepPeer::TAS_UID, StepPeer::STEP_TYPE_OBJ, StepPeer::STEP_UID_OBJ, StepPeer::STEP_CONDITION, StepPeer::STEP_POSITION, StepPeer::STEP_MODE, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID', 'PRO_UID', 'TAS_UID', 'STEP_TYPE_OBJ', 'STEP_UID_OBJ', 'STEP_CONDITION', 'STEP_POSITION', 'STEP_MODE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid' => 0, 'ProUid' => 1, 'TasUid' => 2, 'StepTypeObj' => 3, 'StepUidObj' => 4, 'StepCondition' => 5, 'StepPosition' => 6, 'StepMode' => 7, ), + BasePeer::TYPE_COLNAME => array (StepPeer::STEP_UID => 0, StepPeer::PRO_UID => 1, StepPeer::TAS_UID => 2, StepPeer::STEP_TYPE_OBJ => 3, StepPeer::STEP_UID_OBJ => 4, StepPeer::STEP_CONDITION => 5, StepPeer::STEP_POSITION => 6, StepPeer::STEP_MODE => 7, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID' => 0, 'PRO_UID' => 1, 'TAS_UID' => 2, 'STEP_TYPE_OBJ' => 3, 'STEP_UID_OBJ' => 4, 'STEP_CONDITION' => 5, 'STEP_POSITION' => 6, 'STEP_MODE' => 7, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/StepMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.StepMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = StepPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. StepPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(StepPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(StepPeer::STEP_UID); + + $criteria->addSelectColumn(StepPeer::PRO_UID); + + $criteria->addSelectColumn(StepPeer::TAS_UID); + + $criteria->addSelectColumn(StepPeer::STEP_TYPE_OBJ); + + $criteria->addSelectColumn(StepPeer::STEP_UID_OBJ); + + $criteria->addSelectColumn(StepPeer::STEP_CONDITION); + + $criteria->addSelectColumn(StepPeer::STEP_POSITION); + + $criteria->addSelectColumn(StepPeer::STEP_MODE); + + } + + const COUNT = 'COUNT(STEP.STEP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT STEP.STEP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(StepPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(StepPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = StepPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Step + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = StepPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return StepPeer::populateObjects(StepPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + StepPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = StepPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return StepPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Step or Criteria object. + * + * @param mixed $values Criteria or Step object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Step object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Step or Criteria object. + * + * @param mixed $values Criteria or Step object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(StepPeer::STEP_UID); + $selectCriteria->add(StepPeer::STEP_UID, $criteria->remove(StepPeer::STEP_UID), $comparison); + + } else { // $values is Step object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the STEP table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(StepPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Step or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Step object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(StepPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Step) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(StepPeer::STEP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Step object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Step $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Step $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(StepPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(StepPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(StepPeer::STEP_TYPE_OBJ)) + $columns[StepPeer::STEP_TYPE_OBJ] = $obj->getStepTypeObj(); + + } + + return BasePeer::doValidate(StepPeer::DATABASE_NAME, StepPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Step + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(StepPeer::DATABASE_NAME); + + $criteria->add(StepPeer::STEP_UID, $pk); + + + $v = StepPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(StepPeer::STEP_UID, $pks, Criteria::IN); + $objs = StepPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseStepPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseStepPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/StepMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.StepMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseStepSupervisor.php b/workflow/engine/classes/model/om/BaseStepSupervisor.php new file mode 100644 index 000000000..d8b121122 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStepSupervisor.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/StepSupervisorPeer.php'; + +/** + * Base class that represents a row from the 'STEP_SUPERVISOR' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStepSupervisor extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var StepSupervisorPeer + */ + protected static $peer; + + + /** + * The value for the step_uid field. + * @var string + */ + protected $step_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = '0'; + + + /** + * The value for the step_type_obj field. + * @var string + */ + protected $step_type_obj = 'DYNAFORM'; + + + /** + * The value for the step_uid_obj field. + * @var string + */ + protected $step_uid_obj = '0'; + + + /** + * The value for the step_position field. + * @var int + */ + protected $step_position = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [step_uid] column value. + * + * @return string + */ + public function getStepUid() + { + + return $this->step_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [step_type_obj] column value. + * + * @return string + */ + public function getStepTypeObj() + { + + return $this->step_type_obj; + } + + /** + * Get the [step_uid_obj] column value. + * + * @return string + */ + public function getStepUidObj() + { + + return $this->step_uid_obj; + } + + /** + * Get the [step_position] column value. + * + * @return int + */ + public function getStepPosition() + { + + return $this->step_position; + } + + /** + * Set the value of [step_uid] column. + * + * @param string $v new value + * @return void + */ + public function setStepUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_uid !== $v || $v === '') { + $this->step_uid = $v; + $this->modifiedColumns[] = StepSupervisorPeer::STEP_UID; + } + + } // setStepUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '0') { + $this->pro_uid = $v; + $this->modifiedColumns[] = StepSupervisorPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [step_type_obj] column. + * + * @param string $v new value + * @return void + */ + public function setStepTypeObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_type_obj !== $v || $v === 'DYNAFORM') { + $this->step_type_obj = $v; + $this->modifiedColumns[] = StepSupervisorPeer::STEP_TYPE_OBJ; + } + + } // setStepTypeObj() + + /** + * Set the value of [step_uid_obj] column. + * + * @param string $v new value + * @return void + */ + public function setStepUidObj($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_uid_obj !== $v || $v === '0') { + $this->step_uid_obj = $v; + $this->modifiedColumns[] = StepSupervisorPeer::STEP_UID_OBJ; + } + + } // setStepUidObj() + + /** + * Set the value of [step_position] column. + * + * @param int $v new value + * @return void + */ + public function setStepPosition($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->step_position !== $v || $v === 0) { + $this->step_position = $v; + $this->modifiedColumns[] = StepSupervisorPeer::STEP_POSITION; + } + + } // setStepPosition() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->step_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->step_type_obj = $rs->getString($startcol + 2); + + $this->step_uid_obj = $rs->getString($startcol + 3); + + $this->step_position = $rs->getInt($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = StepSupervisorPeer::NUM_COLUMNS - StepSupervisorPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating StepSupervisor object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + } + + try { + $con->begin(); + StepSupervisorPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = StepSupervisorPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += StepSupervisorPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = StepSupervisorPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepSupervisorPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getStepUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getStepTypeObj(); + break; + case 3: + return $this->getStepUidObj(); + break; + case 4: + return $this->getStepPosition(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepSupervisorPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getStepUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getStepTypeObj(), + $keys[3] => $this->getStepUidObj(), + $keys[4] => $this->getStepPosition(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepSupervisorPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setStepUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setStepTypeObj($value); + break; + case 3: + $this->setStepUidObj($value); + break; + case 4: + $this->setStepPosition($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepSupervisorPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setStepUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setStepTypeObj($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setStepUidObj($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setStepPosition($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(StepSupervisorPeer::DATABASE_NAME); + + if ($this->isColumnModified(StepSupervisorPeer::STEP_UID)) $criteria->add(StepSupervisorPeer::STEP_UID, $this->step_uid); + if ($this->isColumnModified(StepSupervisorPeer::PRO_UID)) $criteria->add(StepSupervisorPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(StepSupervisorPeer::STEP_TYPE_OBJ)) $criteria->add(StepSupervisorPeer::STEP_TYPE_OBJ, $this->step_type_obj); + if ($this->isColumnModified(StepSupervisorPeer::STEP_UID_OBJ)) $criteria->add(StepSupervisorPeer::STEP_UID_OBJ, $this->step_uid_obj); + if ($this->isColumnModified(StepSupervisorPeer::STEP_POSITION)) $criteria->add(StepSupervisorPeer::STEP_POSITION, $this->step_position); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(StepSupervisorPeer::DATABASE_NAME); + + $criteria->add(StepSupervisorPeer::STEP_UID, $this->step_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getStepUid(); + } + + /** + * Generic method to set the primary key (step_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setStepUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of StepSupervisor (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setStepTypeObj($this->step_type_obj); + + $copyObj->setStepUidObj($this->step_uid_obj); + + $copyObj->setStepPosition($this->step_position); + + + $copyObj->setNew(true); + + $copyObj->setStepUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return StepSupervisor Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return StepSupervisorPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new StepSupervisorPeer(); + } + return self::$peer; + } + +} // BaseStepSupervisor diff --git a/workflow/engine/classes/model/om/BaseStepSupervisorPeer.php b/workflow/engine/classes/model/om/BaseStepSupervisorPeer.php new file mode 100644 index 000000000..46134dc02 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStepSupervisorPeer.php @@ -0,0 +1,588 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by StepSupervisorPeer::getOMClass() +include_once 'classes/model/StepSupervisor.php'; + +/** + * Base static class for performing query and update operations on the 'STEP_SUPERVISOR' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStepSupervisorPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'STEP_SUPERVISOR'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.StepSupervisor'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the STEP_UID field */ + const STEP_UID = 'STEP_SUPERVISOR.STEP_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'STEP_SUPERVISOR.PRO_UID'; + + /** the column name for the STEP_TYPE_OBJ field */ + const STEP_TYPE_OBJ = 'STEP_SUPERVISOR.STEP_TYPE_OBJ'; + + /** the column name for the STEP_UID_OBJ field */ + const STEP_UID_OBJ = 'STEP_SUPERVISOR.STEP_UID_OBJ'; + + /** the column name for the STEP_POSITION field */ + const STEP_POSITION = 'STEP_SUPERVISOR.STEP_POSITION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid', 'ProUid', 'StepTypeObj', 'StepUidObj', 'StepPosition', ), + BasePeer::TYPE_COLNAME => array (StepSupervisorPeer::STEP_UID, StepSupervisorPeer::PRO_UID, StepSupervisorPeer::STEP_TYPE_OBJ, StepSupervisorPeer::STEP_UID_OBJ, StepSupervisorPeer::STEP_POSITION, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID', 'PRO_UID', 'STEP_TYPE_OBJ', 'STEP_UID_OBJ', 'STEP_POSITION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid' => 0, 'ProUid' => 1, 'StepTypeObj' => 2, 'StepUidObj' => 3, 'StepPosition' => 4, ), + BasePeer::TYPE_COLNAME => array (StepSupervisorPeer::STEP_UID => 0, StepSupervisorPeer::PRO_UID => 1, StepSupervisorPeer::STEP_TYPE_OBJ => 2, StepSupervisorPeer::STEP_UID_OBJ => 3, StepSupervisorPeer::STEP_POSITION => 4, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID' => 0, 'PRO_UID' => 1, 'STEP_TYPE_OBJ' => 2, 'STEP_UID_OBJ' => 3, 'STEP_POSITION' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/StepSupervisorMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.StepSupervisorMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = StepSupervisorPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. StepSupervisorPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(StepSupervisorPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(StepSupervisorPeer::STEP_UID); + + $criteria->addSelectColumn(StepSupervisorPeer::PRO_UID); + + $criteria->addSelectColumn(StepSupervisorPeer::STEP_TYPE_OBJ); + + $criteria->addSelectColumn(StepSupervisorPeer::STEP_UID_OBJ); + + $criteria->addSelectColumn(StepSupervisorPeer::STEP_POSITION); + + } + + const COUNT = 'COUNT(STEP_SUPERVISOR.STEP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT STEP_SUPERVISOR.STEP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(StepSupervisorPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(StepSupervisorPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = StepSupervisorPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return StepSupervisor + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = StepSupervisorPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return StepSupervisorPeer::populateObjects(StepSupervisorPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + StepSupervisorPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = StepSupervisorPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return StepSupervisorPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a StepSupervisor or Criteria object. + * + * @param mixed $values Criteria or StepSupervisor object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from StepSupervisor object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a StepSupervisor or Criteria object. + * + * @param mixed $values Criteria or StepSupervisor object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(StepSupervisorPeer::STEP_UID); + $selectCriteria->add(StepSupervisorPeer::STEP_UID, $criteria->remove(StepSupervisorPeer::STEP_UID), $comparison); + + } else { // $values is StepSupervisor object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the STEP_SUPERVISOR table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(StepSupervisorPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a StepSupervisor or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or StepSupervisor object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(StepSupervisorPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof StepSupervisor) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(StepSupervisorPeer::STEP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given StepSupervisor object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param StepSupervisor $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(StepSupervisor $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(StepSupervisorPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(StepSupervisorPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(StepSupervisorPeer::STEP_TYPE_OBJ)) + $columns[StepSupervisorPeer::STEP_TYPE_OBJ] = $obj->getStepTypeObj(); + + } + + return BasePeer::doValidate(StepSupervisorPeer::DATABASE_NAME, StepSupervisorPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return StepSupervisor + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(StepSupervisorPeer::DATABASE_NAME); + + $criteria->add(StepSupervisorPeer::STEP_UID, $pk); + + + $v = StepSupervisorPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(StepSupervisorPeer::STEP_UID, $pks, Criteria::IN); + $objs = StepSupervisorPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseStepSupervisorPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseStepSupervisorPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/StepSupervisorMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.StepSupervisorMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseStepTrigger.php b/workflow/engine/classes/model/om/BaseStepTrigger.php new file mode 100644 index 000000000..4cfbf5e4c --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStepTrigger.php @@ -0,0 +1,791 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/StepTriggerPeer.php'; + +/** + * Base class that represents a row from the 'STEP_TRIGGER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStepTrigger extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var StepTriggerPeer + */ + protected static $peer; + + + /** + * The value for the step_uid field. + * @var string + */ + protected $step_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the tri_uid field. + * @var string + */ + protected $tri_uid = ''; + + + /** + * The value for the st_type field. + * @var string + */ + protected $st_type = ''; + + + /** + * The value for the st_condition field. + * @var string + */ + protected $st_condition = ''; + + + /** + * The value for the st_position field. + * @var int + */ + protected $st_position = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [step_uid] column value. + * + * @return string + */ + public function getStepUid() + { + + return $this->step_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [tri_uid] column value. + * + * @return string + */ + public function getTriUid() + { + + return $this->tri_uid; + } + + /** + * Get the [st_type] column value. + * + * @return string + */ + public function getStType() + { + + return $this->st_type; + } + + /** + * Get the [st_condition] column value. + * + * @return string + */ + public function getStCondition() + { + + return $this->st_condition; + } + + /** + * Get the [st_position] column value. + * + * @return int + */ + public function getStPosition() + { + + return $this->st_position; + } + + /** + * Set the value of [step_uid] column. + * + * @param string $v new value + * @return void + */ + public function setStepUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->step_uid !== $v || $v === '') { + $this->step_uid = $v; + $this->modifiedColumns[] = StepTriggerPeer::STEP_UID; + } + + } // setStepUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = StepTriggerPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [tri_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTriUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_uid !== $v || $v === '') { + $this->tri_uid = $v; + $this->modifiedColumns[] = StepTriggerPeer::TRI_UID; + } + + } // setTriUid() + + /** + * Set the value of [st_type] column. + * + * @param string $v new value + * @return void + */ + public function setStType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->st_type !== $v || $v === '') { + $this->st_type = $v; + $this->modifiedColumns[] = StepTriggerPeer::ST_TYPE; + } + + } // setStType() + + /** + * Set the value of [st_condition] column. + * + * @param string $v new value + * @return void + */ + public function setStCondition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->st_condition !== $v || $v === '') { + $this->st_condition = $v; + $this->modifiedColumns[] = StepTriggerPeer::ST_CONDITION; + } + + } // setStCondition() + + /** + * Set the value of [st_position] column. + * + * @param int $v new value + * @return void + */ + public function setStPosition($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->st_position !== $v || $v === 0) { + $this->st_position = $v; + $this->modifiedColumns[] = StepTriggerPeer::ST_POSITION; + } + + } // setStPosition() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->step_uid = $rs->getString($startcol + 0); + + $this->tas_uid = $rs->getString($startcol + 1); + + $this->tri_uid = $rs->getString($startcol + 2); + + $this->st_type = $rs->getString($startcol + 3); + + $this->st_condition = $rs->getString($startcol + 4); + + $this->st_position = $rs->getInt($startcol + 5); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 6; // 6 = StepTriggerPeer::NUM_COLUMNS - StepTriggerPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating StepTrigger object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + StepTriggerPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = StepTriggerPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += StepTriggerPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = StepTriggerPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepTriggerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getStepUid(); + break; + case 1: + return $this->getTasUid(); + break; + case 2: + return $this->getTriUid(); + break; + case 3: + return $this->getStType(); + break; + case 4: + return $this->getStCondition(); + break; + case 5: + return $this->getStPosition(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepTriggerPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getStepUid(), + $keys[1] => $this->getTasUid(), + $keys[2] => $this->getTriUid(), + $keys[3] => $this->getStType(), + $keys[4] => $this->getStCondition(), + $keys[5] => $this->getStPosition(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = StepTriggerPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setStepUid($value); + break; + case 1: + $this->setTasUid($value); + break; + case 2: + $this->setTriUid($value); + break; + case 3: + $this->setStType($value); + break; + case 4: + $this->setStCondition($value); + break; + case 5: + $this->setStPosition($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = StepTriggerPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setStepUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setTasUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTriUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setStType($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setStCondition($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setStPosition($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(StepTriggerPeer::DATABASE_NAME); + + if ($this->isColumnModified(StepTriggerPeer::STEP_UID)) $criteria->add(StepTriggerPeer::STEP_UID, $this->step_uid); + if ($this->isColumnModified(StepTriggerPeer::TAS_UID)) $criteria->add(StepTriggerPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(StepTriggerPeer::TRI_UID)) $criteria->add(StepTriggerPeer::TRI_UID, $this->tri_uid); + if ($this->isColumnModified(StepTriggerPeer::ST_TYPE)) $criteria->add(StepTriggerPeer::ST_TYPE, $this->st_type); + if ($this->isColumnModified(StepTriggerPeer::ST_CONDITION)) $criteria->add(StepTriggerPeer::ST_CONDITION, $this->st_condition); + if ($this->isColumnModified(StepTriggerPeer::ST_POSITION)) $criteria->add(StepTriggerPeer::ST_POSITION, $this->st_position); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(StepTriggerPeer::DATABASE_NAME); + + $criteria->add(StepTriggerPeer::STEP_UID, $this->step_uid); + $criteria->add(StepTriggerPeer::TAS_UID, $this->tas_uid); + $criteria->add(StepTriggerPeer::TRI_UID, $this->tri_uid); + $criteria->add(StepTriggerPeer::ST_TYPE, $this->st_type); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getStepUid(); + + $pks[1] = $this->getTasUid(); + + $pks[2] = $this->getTriUid(); + + $pks[3] = $this->getStType(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setStepUid($keys[0]); + + $this->setTasUid($keys[1]); + + $this->setTriUid($keys[2]); + + $this->setStType($keys[3]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of StepTrigger (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setStCondition($this->st_condition); + + $copyObj->setStPosition($this->st_position); + + + $copyObj->setNew(true); + + $copyObj->setStepUid(''); // this is a pkey column, so set to default value + + $copyObj->setTasUid(''); // this is a pkey column, so set to default value + + $copyObj->setTriUid(''); // this is a pkey column, so set to default value + + $copyObj->setStType(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return StepTrigger Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return StepTriggerPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new StepTriggerPeer(); + } + return self::$peer; + } + +} // BaseStepTrigger diff --git a/workflow/engine/classes/model/om/BaseStepTriggerPeer.php b/workflow/engine/classes/model/om/BaseStepTriggerPeer.php new file mode 100644 index 000000000..759a36600 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseStepTriggerPeer.php @@ -0,0 +1,598 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by StepTriggerPeer::getOMClass() +include_once 'classes/model/StepTrigger.php'; + +/** + * Base static class for performing query and update operations on the 'STEP_TRIGGER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseStepTriggerPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'STEP_TRIGGER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.StepTrigger'; + + /** The total number of columns. */ + const NUM_COLUMNS = 6; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the STEP_UID field */ + const STEP_UID = 'STEP_TRIGGER.STEP_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'STEP_TRIGGER.TAS_UID'; + + /** the column name for the TRI_UID field */ + const TRI_UID = 'STEP_TRIGGER.TRI_UID'; + + /** the column name for the ST_TYPE field */ + const ST_TYPE = 'STEP_TRIGGER.ST_TYPE'; + + /** the column name for the ST_CONDITION field */ + const ST_CONDITION = 'STEP_TRIGGER.ST_CONDITION'; + + /** the column name for the ST_POSITION field */ + const ST_POSITION = 'STEP_TRIGGER.ST_POSITION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid', 'TasUid', 'TriUid', 'StType', 'StCondition', 'StPosition', ), + BasePeer::TYPE_COLNAME => array (StepTriggerPeer::STEP_UID, StepTriggerPeer::TAS_UID, StepTriggerPeer::TRI_UID, StepTriggerPeer::ST_TYPE, StepTriggerPeer::ST_CONDITION, StepTriggerPeer::ST_POSITION, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID', 'TAS_UID', 'TRI_UID', 'ST_TYPE', 'ST_CONDITION', 'ST_POSITION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('StepUid' => 0, 'TasUid' => 1, 'TriUid' => 2, 'StType' => 3, 'StCondition' => 4, 'StPosition' => 5, ), + BasePeer::TYPE_COLNAME => array (StepTriggerPeer::STEP_UID => 0, StepTriggerPeer::TAS_UID => 1, StepTriggerPeer::TRI_UID => 2, StepTriggerPeer::ST_TYPE => 3, StepTriggerPeer::ST_CONDITION => 4, StepTriggerPeer::ST_POSITION => 5, ), + BasePeer::TYPE_FIELDNAME => array ('STEP_UID' => 0, 'TAS_UID' => 1, 'TRI_UID' => 2, 'ST_TYPE' => 3, 'ST_CONDITION' => 4, 'ST_POSITION' => 5, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/StepTriggerMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.StepTriggerMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = StepTriggerPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. StepTriggerPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(StepTriggerPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(StepTriggerPeer::STEP_UID); + + $criteria->addSelectColumn(StepTriggerPeer::TAS_UID); + + $criteria->addSelectColumn(StepTriggerPeer::TRI_UID); + + $criteria->addSelectColumn(StepTriggerPeer::ST_TYPE); + + $criteria->addSelectColumn(StepTriggerPeer::ST_CONDITION); + + $criteria->addSelectColumn(StepTriggerPeer::ST_POSITION); + + } + + const COUNT = 'COUNT(STEP_TRIGGER.STEP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT STEP_TRIGGER.STEP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(StepTriggerPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(StepTriggerPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = StepTriggerPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return StepTrigger + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = StepTriggerPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return StepTriggerPeer::populateObjects(StepTriggerPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + StepTriggerPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = StepTriggerPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return StepTriggerPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a StepTrigger or Criteria object. + * + * @param mixed $values Criteria or StepTrigger object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from StepTrigger object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a StepTrigger or Criteria object. + * + * @param mixed $values Criteria or StepTrigger object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(StepTriggerPeer::STEP_UID); + $selectCriteria->add(StepTriggerPeer::STEP_UID, $criteria->remove(StepTriggerPeer::STEP_UID), $comparison); + + $comparison = $criteria->getComparison(StepTriggerPeer::TAS_UID); + $selectCriteria->add(StepTriggerPeer::TAS_UID, $criteria->remove(StepTriggerPeer::TAS_UID), $comparison); + + $comparison = $criteria->getComparison(StepTriggerPeer::TRI_UID); + $selectCriteria->add(StepTriggerPeer::TRI_UID, $criteria->remove(StepTriggerPeer::TRI_UID), $comparison); + + $comparison = $criteria->getComparison(StepTriggerPeer::ST_TYPE); + $selectCriteria->add(StepTriggerPeer::ST_TYPE, $criteria->remove(StepTriggerPeer::ST_TYPE), $comparison); + + } else { // $values is StepTrigger object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the STEP_TRIGGER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(StepTriggerPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a StepTrigger or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or StepTrigger object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(StepTriggerPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof StepTrigger) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + } + + $criteria->add(StepTriggerPeer::STEP_UID, $vals[0], Criteria::IN); + $criteria->add(StepTriggerPeer::TAS_UID, $vals[1], Criteria::IN); + $criteria->add(StepTriggerPeer::TRI_UID, $vals[2], Criteria::IN); + $criteria->add(StepTriggerPeer::ST_TYPE, $vals[3], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given StepTrigger object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param StepTrigger $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(StepTrigger $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(StepTriggerPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(StepTriggerPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(StepTriggerPeer::ST_TYPE)) + $columns[StepTriggerPeer::ST_TYPE] = $obj->getStType(); + + } + + return BasePeer::doValidate(StepTriggerPeer::DATABASE_NAME, StepTriggerPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $step_uid + @param string $tas_uid + @param string $tri_uid + @param string $st_type + + * @param Connection $con + * @return StepTrigger + */ + public static function retrieveByPK( $step_uid, $tas_uid, $tri_uid, $st_type, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(StepTriggerPeer::STEP_UID, $step_uid); + $criteria->add(StepTriggerPeer::TAS_UID, $tas_uid); + $criteria->add(StepTriggerPeer::TRI_UID, $tri_uid); + $criteria->add(StepTriggerPeer::ST_TYPE, $st_type); + $v = StepTriggerPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseStepTriggerPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseStepTriggerPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/StepTriggerMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.StepTriggerMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseSubApplication.php b/workflow/engine/classes/model/om/BaseSubApplication.php new file mode 100644 index 000000000..8a5b1bb35 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSubApplication.php @@ -0,0 +1,994 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/SubApplicationPeer.php'; + +/** + * Base class that represents a row from the 'SUB_APPLICATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSubApplication extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var SubApplicationPeer + */ + protected static $peer; + + + /** + * The value for the app_uid field. + * @var string + */ + protected $app_uid = ''; + + + /** + * The value for the app_parent field. + * @var string + */ + protected $app_parent = ''; + + + /** + * The value for the del_index_parent field. + * @var int + */ + protected $del_index_parent = 0; + + + /** + * The value for the del_thread_parent field. + * @var int + */ + protected $del_thread_parent = 0; + + + /** + * The value for the sa_status field. + * @var string + */ + protected $sa_status = ''; + + + /** + * The value for the sa_values_out field. + * @var string + */ + protected $sa_values_out; + + + /** + * The value for the sa_values_in field. + * @var string + */ + protected $sa_values_in; + + + /** + * The value for the sa_init_date field. + * @var int + */ + protected $sa_init_date; + + + /** + * The value for the sa_finish_date field. + * @var int + */ + protected $sa_finish_date; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [app_uid] column value. + * + * @return string + */ + public function getAppUid() + { + + return $this->app_uid; + } + + /** + * Get the [app_parent] column value. + * + * @return string + */ + public function getAppParent() + { + + return $this->app_parent; + } + + /** + * Get the [del_index_parent] column value. + * + * @return int + */ + public function getDelIndexParent() + { + + return $this->del_index_parent; + } + + /** + * Get the [del_thread_parent] column value. + * + * @return int + */ + public function getDelThreadParent() + { + + return $this->del_thread_parent; + } + + /** + * Get the [sa_status] column value. + * + * @return string + */ + public function getSaStatus() + { + + return $this->sa_status; + } + + /** + * Get the [sa_values_out] column value. + * + * @return string + */ + public function getSaValuesOut() + { + + return $this->sa_values_out; + } + + /** + * Get the [sa_values_in] column value. + * + * @return string + */ + public function getSaValuesIn() + { + + return $this->sa_values_in; + } + + /** + * Get the [optionally formatted] [sa_init_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSaInitDate($format = 'Y-m-d H:i:s') + { + + if ($this->sa_init_date === null || $this->sa_init_date === '') { + return null; + } elseif (!is_int($this->sa_init_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sa_init_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sa_init_date] as date/time value: " . var_export($this->sa_init_date, true)); + } + } else { + $ts = $this->sa_init_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [sa_finish_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getSaFinishDate($format = 'Y-m-d H:i:s') + { + + if ($this->sa_finish_date === null || $this->sa_finish_date === '') { + return null; + } elseif (!is_int($this->sa_finish_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->sa_finish_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [sa_finish_date] as date/time value: " . var_export($this->sa_finish_date, true)); + } + } else { + $ts = $this->sa_finish_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Set the value of [app_uid] column. + * + * @param string $v new value + * @return void + */ + public function setAppUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_uid !== $v || $v === '') { + $this->app_uid = $v; + $this->modifiedColumns[] = SubApplicationPeer::APP_UID; + } + + } // setAppUid() + + /** + * Set the value of [app_parent] column. + * + * @param string $v new value + * @return void + */ + public function setAppParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->app_parent !== $v || $v === '') { + $this->app_parent = $v; + $this->modifiedColumns[] = SubApplicationPeer::APP_PARENT; + } + + } // setAppParent() + + /** + * Set the value of [del_index_parent] column. + * + * @param int $v new value + * @return void + */ + public function setDelIndexParent($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_index_parent !== $v || $v === 0) { + $this->del_index_parent = $v; + $this->modifiedColumns[] = SubApplicationPeer::DEL_INDEX_PARENT; + } + + } // setDelIndexParent() + + /** + * Set the value of [del_thread_parent] column. + * + * @param int $v new value + * @return void + */ + public function setDelThreadParent($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->del_thread_parent !== $v || $v === 0) { + $this->del_thread_parent = $v; + $this->modifiedColumns[] = SubApplicationPeer::DEL_THREAD_PARENT; + } + + } // setDelThreadParent() + + /** + * Set the value of [sa_status] column. + * + * @param string $v new value + * @return void + */ + public function setSaStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sa_status !== $v || $v === '') { + $this->sa_status = $v; + $this->modifiedColumns[] = SubApplicationPeer::SA_STATUS; + } + + } // setSaStatus() + + /** + * Set the value of [sa_values_out] column. + * + * @param string $v new value + * @return void + */ + public function setSaValuesOut($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sa_values_out !== $v) { + $this->sa_values_out = $v; + $this->modifiedColumns[] = SubApplicationPeer::SA_VALUES_OUT; + } + + } // setSaValuesOut() + + /** + * Set the value of [sa_values_in] column. + * + * @param string $v new value + * @return void + */ + public function setSaValuesIn($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sa_values_in !== $v) { + $this->sa_values_in = $v; + $this->modifiedColumns[] = SubApplicationPeer::SA_VALUES_IN; + } + + } // setSaValuesIn() + + /** + * Set the value of [sa_init_date] column. + * + * @param int $v new value + * @return void + */ + public function setSaInitDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sa_init_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sa_init_date !== $ts) { + $this->sa_init_date = $ts; + $this->modifiedColumns[] = SubApplicationPeer::SA_INIT_DATE; + } + + } // setSaInitDate() + + /** + * Set the value of [sa_finish_date] column. + * + * @param int $v new value + * @return void + */ + public function setSaFinishDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [sa_finish_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->sa_finish_date !== $ts) { + $this->sa_finish_date = $ts; + $this->modifiedColumns[] = SubApplicationPeer::SA_FINISH_DATE; + } + + } // setSaFinishDate() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->app_uid = $rs->getString($startcol + 0); + + $this->app_parent = $rs->getString($startcol + 1); + + $this->del_index_parent = $rs->getInt($startcol + 2); + + $this->del_thread_parent = $rs->getInt($startcol + 3); + + $this->sa_status = $rs->getString($startcol + 4); + + $this->sa_values_out = $rs->getString($startcol + 5); + + $this->sa_values_in = $rs->getString($startcol + 6); + + $this->sa_init_date = $rs->getTimestamp($startcol + 7, null); + + $this->sa_finish_date = $rs->getTimestamp($startcol + 8, null); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 9; // 9 = SubApplicationPeer::NUM_COLUMNS - SubApplicationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating SubApplication object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SubApplicationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + SubApplicationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SubApplicationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = SubApplicationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += SubApplicationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = SubApplicationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SubApplicationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getAppUid(); + break; + case 1: + return $this->getAppParent(); + break; + case 2: + return $this->getDelIndexParent(); + break; + case 3: + return $this->getDelThreadParent(); + break; + case 4: + return $this->getSaStatus(); + break; + case 5: + return $this->getSaValuesOut(); + break; + case 6: + return $this->getSaValuesIn(); + break; + case 7: + return $this->getSaInitDate(); + break; + case 8: + return $this->getSaFinishDate(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SubApplicationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getAppUid(), + $keys[1] => $this->getAppParent(), + $keys[2] => $this->getDelIndexParent(), + $keys[3] => $this->getDelThreadParent(), + $keys[4] => $this->getSaStatus(), + $keys[5] => $this->getSaValuesOut(), + $keys[6] => $this->getSaValuesIn(), + $keys[7] => $this->getSaInitDate(), + $keys[8] => $this->getSaFinishDate(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SubApplicationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setAppUid($value); + break; + case 1: + $this->setAppParent($value); + break; + case 2: + $this->setDelIndexParent($value); + break; + case 3: + $this->setDelThreadParent($value); + break; + case 4: + $this->setSaStatus($value); + break; + case 5: + $this->setSaValuesOut($value); + break; + case 6: + $this->setSaValuesIn($value); + break; + case 7: + $this->setSaInitDate($value); + break; + case 8: + $this->setSaFinishDate($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SubApplicationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setAppUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAppParent($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setDelIndexParent($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDelThreadParent($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setSaStatus($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setSaValuesOut($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setSaValuesIn($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setSaInitDate($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setSaFinishDate($arr[$keys[8]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(SubApplicationPeer::DATABASE_NAME); + + if ($this->isColumnModified(SubApplicationPeer::APP_UID)) $criteria->add(SubApplicationPeer::APP_UID, $this->app_uid); + if ($this->isColumnModified(SubApplicationPeer::APP_PARENT)) $criteria->add(SubApplicationPeer::APP_PARENT, $this->app_parent); + if ($this->isColumnModified(SubApplicationPeer::DEL_INDEX_PARENT)) $criteria->add(SubApplicationPeer::DEL_INDEX_PARENT, $this->del_index_parent); + if ($this->isColumnModified(SubApplicationPeer::DEL_THREAD_PARENT)) $criteria->add(SubApplicationPeer::DEL_THREAD_PARENT, $this->del_thread_parent); + if ($this->isColumnModified(SubApplicationPeer::SA_STATUS)) $criteria->add(SubApplicationPeer::SA_STATUS, $this->sa_status); + if ($this->isColumnModified(SubApplicationPeer::SA_VALUES_OUT)) $criteria->add(SubApplicationPeer::SA_VALUES_OUT, $this->sa_values_out); + if ($this->isColumnModified(SubApplicationPeer::SA_VALUES_IN)) $criteria->add(SubApplicationPeer::SA_VALUES_IN, $this->sa_values_in); + if ($this->isColumnModified(SubApplicationPeer::SA_INIT_DATE)) $criteria->add(SubApplicationPeer::SA_INIT_DATE, $this->sa_init_date); + if ($this->isColumnModified(SubApplicationPeer::SA_FINISH_DATE)) $criteria->add(SubApplicationPeer::SA_FINISH_DATE, $this->sa_finish_date); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(SubApplicationPeer::DATABASE_NAME); + + $criteria->add(SubApplicationPeer::APP_UID, $this->app_uid); + $criteria->add(SubApplicationPeer::APP_PARENT, $this->app_parent); + $criteria->add(SubApplicationPeer::DEL_INDEX_PARENT, $this->del_index_parent); + $criteria->add(SubApplicationPeer::DEL_THREAD_PARENT, $this->del_thread_parent); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getAppUid(); + + $pks[1] = $this->getAppParent(); + + $pks[2] = $this->getDelIndexParent(); + + $pks[3] = $this->getDelThreadParent(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setAppUid($keys[0]); + + $this->setAppParent($keys[1]); + + $this->setDelIndexParent($keys[2]); + + $this->setDelThreadParent($keys[3]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of SubApplication (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setSaStatus($this->sa_status); + + $copyObj->setSaValuesOut($this->sa_values_out); + + $copyObj->setSaValuesIn($this->sa_values_in); + + $copyObj->setSaInitDate($this->sa_init_date); + + $copyObj->setSaFinishDate($this->sa_finish_date); + + + $copyObj->setNew(true); + + $copyObj->setAppUid(''); // this is a pkey column, so set to default value + + $copyObj->setAppParent(''); // this is a pkey column, so set to default value + + $copyObj->setDelIndexParent('0'); // this is a pkey column, so set to default value + + $copyObj->setDelThreadParent('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return SubApplication Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return SubApplicationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new SubApplicationPeer(); + } + return self::$peer; + } + +} // BaseSubApplication diff --git a/workflow/engine/classes/model/om/BaseSubApplicationPeer.php b/workflow/engine/classes/model/om/BaseSubApplicationPeer.php new file mode 100644 index 000000000..c92496852 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSubApplicationPeer.php @@ -0,0 +1,613 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by SubApplicationPeer::getOMClass() +include_once 'classes/model/SubApplication.php'; + +/** + * Base static class for performing query and update operations on the 'SUB_APPLICATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSubApplicationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'SUB_APPLICATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.SubApplication'; + + /** The total number of columns. */ + const NUM_COLUMNS = 9; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the APP_UID field */ + const APP_UID = 'SUB_APPLICATION.APP_UID'; + + /** the column name for the APP_PARENT field */ + const APP_PARENT = 'SUB_APPLICATION.APP_PARENT'; + + /** the column name for the DEL_INDEX_PARENT field */ + const DEL_INDEX_PARENT = 'SUB_APPLICATION.DEL_INDEX_PARENT'; + + /** the column name for the DEL_THREAD_PARENT field */ + const DEL_THREAD_PARENT = 'SUB_APPLICATION.DEL_THREAD_PARENT'; + + /** the column name for the SA_STATUS field */ + const SA_STATUS = 'SUB_APPLICATION.SA_STATUS'; + + /** the column name for the SA_VALUES_OUT field */ + const SA_VALUES_OUT = 'SUB_APPLICATION.SA_VALUES_OUT'; + + /** the column name for the SA_VALUES_IN field */ + const SA_VALUES_IN = 'SUB_APPLICATION.SA_VALUES_IN'; + + /** the column name for the SA_INIT_DATE field */ + const SA_INIT_DATE = 'SUB_APPLICATION.SA_INIT_DATE'; + + /** the column name for the SA_FINISH_DATE field */ + const SA_FINISH_DATE = 'SUB_APPLICATION.SA_FINISH_DATE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid', 'AppParent', 'DelIndexParent', 'DelThreadParent', 'SaStatus', 'SaValuesOut', 'SaValuesIn', 'SaInitDate', 'SaFinishDate', ), + BasePeer::TYPE_COLNAME => array (SubApplicationPeer::APP_UID, SubApplicationPeer::APP_PARENT, SubApplicationPeer::DEL_INDEX_PARENT, SubApplicationPeer::DEL_THREAD_PARENT, SubApplicationPeer::SA_STATUS, SubApplicationPeer::SA_VALUES_OUT, SubApplicationPeer::SA_VALUES_IN, SubApplicationPeer::SA_INIT_DATE, SubApplicationPeer::SA_FINISH_DATE, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID', 'APP_PARENT', 'DEL_INDEX_PARENT', 'DEL_THREAD_PARENT', 'SA_STATUS', 'SA_VALUES_OUT', 'SA_VALUES_IN', 'SA_INIT_DATE', 'SA_FINISH_DATE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('AppUid' => 0, 'AppParent' => 1, 'DelIndexParent' => 2, 'DelThreadParent' => 3, 'SaStatus' => 4, 'SaValuesOut' => 5, 'SaValuesIn' => 6, 'SaInitDate' => 7, 'SaFinishDate' => 8, ), + BasePeer::TYPE_COLNAME => array (SubApplicationPeer::APP_UID => 0, SubApplicationPeer::APP_PARENT => 1, SubApplicationPeer::DEL_INDEX_PARENT => 2, SubApplicationPeer::DEL_THREAD_PARENT => 3, SubApplicationPeer::SA_STATUS => 4, SubApplicationPeer::SA_VALUES_OUT => 5, SubApplicationPeer::SA_VALUES_IN => 6, SubApplicationPeer::SA_INIT_DATE => 7, SubApplicationPeer::SA_FINISH_DATE => 8, ), + BasePeer::TYPE_FIELDNAME => array ('APP_UID' => 0, 'APP_PARENT' => 1, 'DEL_INDEX_PARENT' => 2, 'DEL_THREAD_PARENT' => 3, 'SA_STATUS' => 4, 'SA_VALUES_OUT' => 5, 'SA_VALUES_IN' => 6, 'SA_INIT_DATE' => 7, 'SA_FINISH_DATE' => 8, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/SubApplicationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.SubApplicationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = SubApplicationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. SubApplicationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(SubApplicationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(SubApplicationPeer::APP_UID); + + $criteria->addSelectColumn(SubApplicationPeer::APP_PARENT); + + $criteria->addSelectColumn(SubApplicationPeer::DEL_INDEX_PARENT); + + $criteria->addSelectColumn(SubApplicationPeer::DEL_THREAD_PARENT); + + $criteria->addSelectColumn(SubApplicationPeer::SA_STATUS); + + $criteria->addSelectColumn(SubApplicationPeer::SA_VALUES_OUT); + + $criteria->addSelectColumn(SubApplicationPeer::SA_VALUES_IN); + + $criteria->addSelectColumn(SubApplicationPeer::SA_INIT_DATE); + + $criteria->addSelectColumn(SubApplicationPeer::SA_FINISH_DATE); + + } + + const COUNT = 'COUNT(SUB_APPLICATION.APP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT SUB_APPLICATION.APP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(SubApplicationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(SubApplicationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = SubApplicationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return SubApplication + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = SubApplicationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return SubApplicationPeer::populateObjects(SubApplicationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + SubApplicationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = SubApplicationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return SubApplicationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a SubApplication or Criteria object. + * + * @param mixed $values Criteria or SubApplication object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from SubApplication object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a SubApplication or Criteria object. + * + * @param mixed $values Criteria or SubApplication object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(SubApplicationPeer::APP_UID); + $selectCriteria->add(SubApplicationPeer::APP_UID, $criteria->remove(SubApplicationPeer::APP_UID), $comparison); + + $comparison = $criteria->getComparison(SubApplicationPeer::APP_PARENT); + $selectCriteria->add(SubApplicationPeer::APP_PARENT, $criteria->remove(SubApplicationPeer::APP_PARENT), $comparison); + + $comparison = $criteria->getComparison(SubApplicationPeer::DEL_INDEX_PARENT); + $selectCriteria->add(SubApplicationPeer::DEL_INDEX_PARENT, $criteria->remove(SubApplicationPeer::DEL_INDEX_PARENT), $comparison); + + $comparison = $criteria->getComparison(SubApplicationPeer::DEL_THREAD_PARENT); + $selectCriteria->add(SubApplicationPeer::DEL_THREAD_PARENT, $criteria->remove(SubApplicationPeer::DEL_THREAD_PARENT), $comparison); + + } else { // $values is SubApplication object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the SUB_APPLICATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(SubApplicationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a SubApplication or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or SubApplication object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(SubApplicationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof SubApplication) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + } + + $criteria->add(SubApplicationPeer::APP_UID, $vals[0], Criteria::IN); + $criteria->add(SubApplicationPeer::APP_PARENT, $vals[1], Criteria::IN); + $criteria->add(SubApplicationPeer::DEL_INDEX_PARENT, $vals[2], Criteria::IN); + $criteria->add(SubApplicationPeer::DEL_THREAD_PARENT, $vals[3], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given SubApplication object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param SubApplication $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(SubApplication $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(SubApplicationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(SubApplicationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(SubApplicationPeer::SA_STATUS)) + $columns[SubApplicationPeer::SA_STATUS] = $obj->getSaStatus(); + + } + + return BasePeer::doValidate(SubApplicationPeer::DATABASE_NAME, SubApplicationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $app_uid + @param string $app_parent + @param int $del_index_parent + @param int $del_thread_parent + + * @param Connection $con + * @return SubApplication + */ + public static function retrieveByPK( $app_uid, $app_parent, $del_index_parent, $del_thread_parent, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(SubApplicationPeer::APP_UID, $app_uid); + $criteria->add(SubApplicationPeer::APP_PARENT, $app_parent); + $criteria->add(SubApplicationPeer::DEL_INDEX_PARENT, $del_index_parent); + $criteria->add(SubApplicationPeer::DEL_THREAD_PARENT, $del_thread_parent); + $v = SubApplicationPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseSubApplicationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseSubApplicationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/SubApplicationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.SubApplicationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseSubProcess.php b/workflow/engine/classes/model/om/BaseSubProcess.php new file mode 100644 index 000000000..53c22782e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSubProcess.php @@ -0,0 +1,1087 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/SubProcessPeer.php'; + +/** + * Base class that represents a row from the 'SUB_PROCESS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSubProcess extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var SubProcessPeer + */ + protected static $peer; + + + /** + * The value for the sp_uid field. + * @var string + */ + protected $sp_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the pro_parent field. + * @var string + */ + protected $pro_parent = ''; + + + /** + * The value for the tas_parent field. + * @var string + */ + protected $tas_parent = ''; + + + /** + * The value for the sp_type field. + * @var string + */ + protected $sp_type = ''; + + + /** + * The value for the sp_synchronous field. + * @var int + */ + protected $sp_synchronous = 0; + + + /** + * The value for the sp_synchronous_type field. + * @var string + */ + protected $sp_synchronous_type = ''; + + + /** + * The value for the sp_synchronous_wait field. + * @var int + */ + protected $sp_synchronous_wait = 0; + + + /** + * The value for the sp_variables_out field. + * @var string + */ + protected $sp_variables_out; + + + /** + * The value for the sp_variables_in field. + * @var string + */ + protected $sp_variables_in; + + + /** + * The value for the sp_grid_in field. + * @var string + */ + protected $sp_grid_in = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [sp_uid] column value. + * + * @return string + */ + public function getSpUid() + { + + return $this->sp_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [pro_parent] column value. + * + * @return string + */ + public function getProParent() + { + + return $this->pro_parent; + } + + /** + * Get the [tas_parent] column value. + * + * @return string + */ + public function getTasParent() + { + + return $this->tas_parent; + } + + /** + * Get the [sp_type] column value. + * + * @return string + */ + public function getSpType() + { + + return $this->sp_type; + } + + /** + * Get the [sp_synchronous] column value. + * + * @return int + */ + public function getSpSynchronous() + { + + return $this->sp_synchronous; + } + + /** + * Get the [sp_synchronous_type] column value. + * + * @return string + */ + public function getSpSynchronousType() + { + + return $this->sp_synchronous_type; + } + + /** + * Get the [sp_synchronous_wait] column value. + * + * @return int + */ + public function getSpSynchronousWait() + { + + return $this->sp_synchronous_wait; + } + + /** + * Get the [sp_variables_out] column value. + * + * @return string + */ + public function getSpVariablesOut() + { + + return $this->sp_variables_out; + } + + /** + * Get the [sp_variables_in] column value. + * + * @return string + */ + public function getSpVariablesIn() + { + + return $this->sp_variables_in; + } + + /** + * Get the [sp_grid_in] column value. + * + * @return string + */ + public function getSpGridIn() + { + + return $this->sp_grid_in; + } + + /** + * Set the value of [sp_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSpUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_uid !== $v || $v === '') { + $this->sp_uid = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_UID; + } + + } // setSpUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = SubProcessPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = SubProcessPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [pro_parent] column. + * + * @param string $v new value + * @return void + */ + public function setProParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_parent !== $v || $v === '') { + $this->pro_parent = $v; + $this->modifiedColumns[] = SubProcessPeer::PRO_PARENT; + } + + } // setProParent() + + /** + * Set the value of [tas_parent] column. + * + * @param string $v new value + * @return void + */ + public function setTasParent($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_parent !== $v || $v === '') { + $this->tas_parent = $v; + $this->modifiedColumns[] = SubProcessPeer::TAS_PARENT; + } + + } // setTasParent() + + /** + * Set the value of [sp_type] column. + * + * @param string $v new value + * @return void + */ + public function setSpType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_type !== $v || $v === '') { + $this->sp_type = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_TYPE; + } + + } // setSpType() + + /** + * Set the value of [sp_synchronous] column. + * + * @param int $v new value + * @return void + */ + public function setSpSynchronous($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->sp_synchronous !== $v || $v === 0) { + $this->sp_synchronous = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_SYNCHRONOUS; + } + + } // setSpSynchronous() + + /** + * Set the value of [sp_synchronous_type] column. + * + * @param string $v new value + * @return void + */ + public function setSpSynchronousType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_synchronous_type !== $v || $v === '') { + $this->sp_synchronous_type = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_SYNCHRONOUS_TYPE; + } + + } // setSpSynchronousType() + + /** + * Set the value of [sp_synchronous_wait] column. + * + * @param int $v new value + * @return void + */ + public function setSpSynchronousWait($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->sp_synchronous_wait !== $v || $v === 0) { + $this->sp_synchronous_wait = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_SYNCHRONOUS_WAIT; + } + + } // setSpSynchronousWait() + + /** + * Set the value of [sp_variables_out] column. + * + * @param string $v new value + * @return void + */ + public function setSpVariablesOut($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_variables_out !== $v) { + $this->sp_variables_out = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_VARIABLES_OUT; + } + + } // setSpVariablesOut() + + /** + * Set the value of [sp_variables_in] column. + * + * @param string $v new value + * @return void + */ + public function setSpVariablesIn($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_variables_in !== $v) { + $this->sp_variables_in = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_VARIABLES_IN; + } + + } // setSpVariablesIn() + + /** + * Set the value of [sp_grid_in] column. + * + * @param string $v new value + * @return void + */ + public function setSpGridIn($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->sp_grid_in !== $v || $v === '') { + $this->sp_grid_in = $v; + $this->modifiedColumns[] = SubProcessPeer::SP_GRID_IN; + } + + } // setSpGridIn() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->sp_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->tas_uid = $rs->getString($startcol + 2); + + $this->pro_parent = $rs->getString($startcol + 3); + + $this->tas_parent = $rs->getString($startcol + 4); + + $this->sp_type = $rs->getString($startcol + 5); + + $this->sp_synchronous = $rs->getInt($startcol + 6); + + $this->sp_synchronous_type = $rs->getString($startcol + 7); + + $this->sp_synchronous_wait = $rs->getInt($startcol + 8); + + $this->sp_variables_out = $rs->getString($startcol + 9); + + $this->sp_variables_in = $rs->getString($startcol + 10); + + $this->sp_grid_in = $rs->getString($startcol + 11); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 12; // 12 = SubProcessPeer::NUM_COLUMNS - SubProcessPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating SubProcess object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + } + + try { + $con->begin(); + SubProcessPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = SubProcessPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += SubProcessPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = SubProcessPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SubProcessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getSpUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getTasUid(); + break; + case 3: + return $this->getProParent(); + break; + case 4: + return $this->getTasParent(); + break; + case 5: + return $this->getSpType(); + break; + case 6: + return $this->getSpSynchronous(); + break; + case 7: + return $this->getSpSynchronousType(); + break; + case 8: + return $this->getSpSynchronousWait(); + break; + case 9: + return $this->getSpVariablesOut(); + break; + case 10: + return $this->getSpVariablesIn(); + break; + case 11: + return $this->getSpGridIn(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SubProcessPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getSpUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getTasUid(), + $keys[3] => $this->getProParent(), + $keys[4] => $this->getTasParent(), + $keys[5] => $this->getSpType(), + $keys[6] => $this->getSpSynchronous(), + $keys[7] => $this->getSpSynchronousType(), + $keys[8] => $this->getSpSynchronousWait(), + $keys[9] => $this->getSpVariablesOut(), + $keys[10] => $this->getSpVariablesIn(), + $keys[11] => $this->getSpGridIn(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SubProcessPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setSpUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setTasUid($value); + break; + case 3: + $this->setProParent($value); + break; + case 4: + $this->setTasParent($value); + break; + case 5: + $this->setSpType($value); + break; + case 6: + $this->setSpSynchronous($value); + break; + case 7: + $this->setSpSynchronousType($value); + break; + case 8: + $this->setSpSynchronousWait($value); + break; + case 9: + $this->setSpVariablesOut($value); + break; + case 10: + $this->setSpVariablesIn($value); + break; + case 11: + $this->setSpGridIn($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SubProcessPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setSpUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTasUid($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setProParent($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTasParent($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setSpType($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setSpSynchronous($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setSpSynchronousType($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setSpSynchronousWait($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setSpVariablesOut($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setSpVariablesIn($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setSpGridIn($arr[$keys[11]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(SubProcessPeer::DATABASE_NAME); + + if ($this->isColumnModified(SubProcessPeer::SP_UID)) $criteria->add(SubProcessPeer::SP_UID, $this->sp_uid); + if ($this->isColumnModified(SubProcessPeer::PRO_UID)) $criteria->add(SubProcessPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(SubProcessPeer::TAS_UID)) $criteria->add(SubProcessPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(SubProcessPeer::PRO_PARENT)) $criteria->add(SubProcessPeer::PRO_PARENT, $this->pro_parent); + if ($this->isColumnModified(SubProcessPeer::TAS_PARENT)) $criteria->add(SubProcessPeer::TAS_PARENT, $this->tas_parent); + if ($this->isColumnModified(SubProcessPeer::SP_TYPE)) $criteria->add(SubProcessPeer::SP_TYPE, $this->sp_type); + if ($this->isColumnModified(SubProcessPeer::SP_SYNCHRONOUS)) $criteria->add(SubProcessPeer::SP_SYNCHRONOUS, $this->sp_synchronous); + if ($this->isColumnModified(SubProcessPeer::SP_SYNCHRONOUS_TYPE)) $criteria->add(SubProcessPeer::SP_SYNCHRONOUS_TYPE, $this->sp_synchronous_type); + if ($this->isColumnModified(SubProcessPeer::SP_SYNCHRONOUS_WAIT)) $criteria->add(SubProcessPeer::SP_SYNCHRONOUS_WAIT, $this->sp_synchronous_wait); + if ($this->isColumnModified(SubProcessPeer::SP_VARIABLES_OUT)) $criteria->add(SubProcessPeer::SP_VARIABLES_OUT, $this->sp_variables_out); + if ($this->isColumnModified(SubProcessPeer::SP_VARIABLES_IN)) $criteria->add(SubProcessPeer::SP_VARIABLES_IN, $this->sp_variables_in); + if ($this->isColumnModified(SubProcessPeer::SP_GRID_IN)) $criteria->add(SubProcessPeer::SP_GRID_IN, $this->sp_grid_in); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(SubProcessPeer::DATABASE_NAME); + + $criteria->add(SubProcessPeer::SP_UID, $this->sp_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getSpUid(); + } + + /** + * Generic method to set the primary key (sp_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setSpUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of SubProcess (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasUid($this->tas_uid); + + $copyObj->setProParent($this->pro_parent); + + $copyObj->setTasParent($this->tas_parent); + + $copyObj->setSpType($this->sp_type); + + $copyObj->setSpSynchronous($this->sp_synchronous); + + $copyObj->setSpSynchronousType($this->sp_synchronous_type); + + $copyObj->setSpSynchronousWait($this->sp_synchronous_wait); + + $copyObj->setSpVariablesOut($this->sp_variables_out); + + $copyObj->setSpVariablesIn($this->sp_variables_in); + + $copyObj->setSpGridIn($this->sp_grid_in); + + + $copyObj->setNew(true); + + $copyObj->setSpUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return SubProcess Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return SubProcessPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new SubProcessPeer(); + } + return self::$peer; + } + +} // BaseSubProcess diff --git a/workflow/engine/classes/model/om/BaseSubProcessPeer.php b/workflow/engine/classes/model/om/BaseSubProcessPeer.php new file mode 100644 index 000000000..619b5ca16 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSubProcessPeer.php @@ -0,0 +1,629 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by SubProcessPeer::getOMClass() +include_once 'classes/model/SubProcess.php'; + +/** + * Base static class for performing query and update operations on the 'SUB_PROCESS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSubProcessPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'SUB_PROCESS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.SubProcess'; + + /** The total number of columns. */ + const NUM_COLUMNS = 12; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the SP_UID field */ + const SP_UID = 'SUB_PROCESS.SP_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'SUB_PROCESS.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'SUB_PROCESS.TAS_UID'; + + /** the column name for the PRO_PARENT field */ + const PRO_PARENT = 'SUB_PROCESS.PRO_PARENT'; + + /** the column name for the TAS_PARENT field */ + const TAS_PARENT = 'SUB_PROCESS.TAS_PARENT'; + + /** the column name for the SP_TYPE field */ + const SP_TYPE = 'SUB_PROCESS.SP_TYPE'; + + /** the column name for the SP_SYNCHRONOUS field */ + const SP_SYNCHRONOUS = 'SUB_PROCESS.SP_SYNCHRONOUS'; + + /** the column name for the SP_SYNCHRONOUS_TYPE field */ + const SP_SYNCHRONOUS_TYPE = 'SUB_PROCESS.SP_SYNCHRONOUS_TYPE'; + + /** the column name for the SP_SYNCHRONOUS_WAIT field */ + const SP_SYNCHRONOUS_WAIT = 'SUB_PROCESS.SP_SYNCHRONOUS_WAIT'; + + /** the column name for the SP_VARIABLES_OUT field */ + const SP_VARIABLES_OUT = 'SUB_PROCESS.SP_VARIABLES_OUT'; + + /** the column name for the SP_VARIABLES_IN field */ + const SP_VARIABLES_IN = 'SUB_PROCESS.SP_VARIABLES_IN'; + + /** the column name for the SP_GRID_IN field */ + const SP_GRID_IN = 'SUB_PROCESS.SP_GRID_IN'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('SpUid', 'ProUid', 'TasUid', 'ProParent', 'TasParent', 'SpType', 'SpSynchronous', 'SpSynchronousType', 'SpSynchronousWait', 'SpVariablesOut', 'SpVariablesIn', 'SpGridIn', ), + BasePeer::TYPE_COLNAME => array (SubProcessPeer::SP_UID, SubProcessPeer::PRO_UID, SubProcessPeer::TAS_UID, SubProcessPeer::PRO_PARENT, SubProcessPeer::TAS_PARENT, SubProcessPeer::SP_TYPE, SubProcessPeer::SP_SYNCHRONOUS, SubProcessPeer::SP_SYNCHRONOUS_TYPE, SubProcessPeer::SP_SYNCHRONOUS_WAIT, SubProcessPeer::SP_VARIABLES_OUT, SubProcessPeer::SP_VARIABLES_IN, SubProcessPeer::SP_GRID_IN, ), + BasePeer::TYPE_FIELDNAME => array ('SP_UID', 'PRO_UID', 'TAS_UID', 'PRO_PARENT', 'TAS_PARENT', 'SP_TYPE', 'SP_SYNCHRONOUS', 'SP_SYNCHRONOUS_TYPE', 'SP_SYNCHRONOUS_WAIT', 'SP_VARIABLES_OUT', 'SP_VARIABLES_IN', 'SP_GRID_IN', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('SpUid' => 0, 'ProUid' => 1, 'TasUid' => 2, 'ProParent' => 3, 'TasParent' => 4, 'SpType' => 5, 'SpSynchronous' => 6, 'SpSynchronousType' => 7, 'SpSynchronousWait' => 8, 'SpVariablesOut' => 9, 'SpVariablesIn' => 10, 'SpGridIn' => 11, ), + BasePeer::TYPE_COLNAME => array (SubProcessPeer::SP_UID => 0, SubProcessPeer::PRO_UID => 1, SubProcessPeer::TAS_UID => 2, SubProcessPeer::PRO_PARENT => 3, SubProcessPeer::TAS_PARENT => 4, SubProcessPeer::SP_TYPE => 5, SubProcessPeer::SP_SYNCHRONOUS => 6, SubProcessPeer::SP_SYNCHRONOUS_TYPE => 7, SubProcessPeer::SP_SYNCHRONOUS_WAIT => 8, SubProcessPeer::SP_VARIABLES_OUT => 9, SubProcessPeer::SP_VARIABLES_IN => 10, SubProcessPeer::SP_GRID_IN => 11, ), + BasePeer::TYPE_FIELDNAME => array ('SP_UID' => 0, 'PRO_UID' => 1, 'TAS_UID' => 2, 'PRO_PARENT' => 3, 'TAS_PARENT' => 4, 'SP_TYPE' => 5, 'SP_SYNCHRONOUS' => 6, 'SP_SYNCHRONOUS_TYPE' => 7, 'SP_SYNCHRONOUS_WAIT' => 8, 'SP_VARIABLES_OUT' => 9, 'SP_VARIABLES_IN' => 10, 'SP_GRID_IN' => 11, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/SubProcessMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.SubProcessMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = SubProcessPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. SubProcessPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(SubProcessPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(SubProcessPeer::SP_UID); + + $criteria->addSelectColumn(SubProcessPeer::PRO_UID); + + $criteria->addSelectColumn(SubProcessPeer::TAS_UID); + + $criteria->addSelectColumn(SubProcessPeer::PRO_PARENT); + + $criteria->addSelectColumn(SubProcessPeer::TAS_PARENT); + + $criteria->addSelectColumn(SubProcessPeer::SP_TYPE); + + $criteria->addSelectColumn(SubProcessPeer::SP_SYNCHRONOUS); + + $criteria->addSelectColumn(SubProcessPeer::SP_SYNCHRONOUS_TYPE); + + $criteria->addSelectColumn(SubProcessPeer::SP_SYNCHRONOUS_WAIT); + + $criteria->addSelectColumn(SubProcessPeer::SP_VARIABLES_OUT); + + $criteria->addSelectColumn(SubProcessPeer::SP_VARIABLES_IN); + + $criteria->addSelectColumn(SubProcessPeer::SP_GRID_IN); + + } + + const COUNT = 'COUNT(SUB_PROCESS.SP_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT SUB_PROCESS.SP_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(SubProcessPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(SubProcessPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = SubProcessPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return SubProcess + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = SubProcessPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return SubProcessPeer::populateObjects(SubProcessPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + SubProcessPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = SubProcessPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return SubProcessPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a SubProcess or Criteria object. + * + * @param mixed $values Criteria or SubProcess object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from SubProcess object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a SubProcess or Criteria object. + * + * @param mixed $values Criteria or SubProcess object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(SubProcessPeer::SP_UID); + $selectCriteria->add(SubProcessPeer::SP_UID, $criteria->remove(SubProcessPeer::SP_UID), $comparison); + + } else { // $values is SubProcess object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the SUB_PROCESS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(SubProcessPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a SubProcess or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or SubProcess object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(SubProcessPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof SubProcess) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(SubProcessPeer::SP_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given SubProcess object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param SubProcess $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(SubProcess $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(SubProcessPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(SubProcessPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(SubProcessPeer::SP_TYPE)) + $columns[SubProcessPeer::SP_TYPE] = $obj->getSpType(); + + if ($obj->isNew() || $obj->isColumnModified(SubProcessPeer::SP_SYNCHRONOUS)) + $columns[SubProcessPeer::SP_SYNCHRONOUS] = $obj->getSpSynchronous(); + + if ($obj->isNew() || $obj->isColumnModified(SubProcessPeer::SP_SYNCHRONOUS_TYPE)) + $columns[SubProcessPeer::SP_SYNCHRONOUS_TYPE] = $obj->getSpSynchronousType(); + + } + + return BasePeer::doValidate(SubProcessPeer::DATABASE_NAME, SubProcessPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return SubProcess + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(SubProcessPeer::DATABASE_NAME); + + $criteria->add(SubProcessPeer::SP_UID, $pk); + + + $v = SubProcessPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(SubProcessPeer::SP_UID, $pks, Criteria::IN); + $objs = SubProcessPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseSubProcessPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseSubProcessPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/SubProcessMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.SubProcessMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseSwimlanesElements.php b/workflow/engine/classes/model/om/BaseSwimlanesElements.php new file mode 100644 index 000000000..45bce5cce --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSwimlanesElements.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/SwimlanesElementsPeer.php'; + +/** + * Base class that represents a row from the 'SWIMLANES_ELEMENTS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSwimlanesElements extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var SwimlanesElementsPeer + */ + protected static $peer; + + + /** + * The value for the swi_uid field. + * @var string + */ + protected $swi_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the swi_type field. + * @var string + */ + protected $swi_type = 'LINE'; + + + /** + * The value for the swi_x field. + * @var int + */ + protected $swi_x = 0; + + + /** + * The value for the swi_y field. + * @var int + */ + protected $swi_y = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [swi_uid] column value. + * + * @return string + */ + public function getSwiUid() + { + + return $this->swi_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [swi_type] column value. + * + * @return string + */ + public function getSwiType() + { + + return $this->swi_type; + } + + /** + * Get the [swi_x] column value. + * + * @return int + */ + public function getSwiX() + { + + return $this->swi_x; + } + + /** + * Get the [swi_y] column value. + * + * @return int + */ + public function getSwiY() + { + + return $this->swi_y; + } + + /** + * Set the value of [swi_uid] column. + * + * @param string $v new value + * @return void + */ + public function setSwiUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->swi_uid !== $v || $v === '') { + $this->swi_uid = $v; + $this->modifiedColumns[] = SwimlanesElementsPeer::SWI_UID; + } + + } // setSwiUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = SwimlanesElementsPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [swi_type] column. + * + * @param string $v new value + * @return void + */ + public function setSwiType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->swi_type !== $v || $v === 'LINE') { + $this->swi_type = $v; + $this->modifiedColumns[] = SwimlanesElementsPeer::SWI_TYPE; + } + + } // setSwiType() + + /** + * Set the value of [swi_x] column. + * + * @param int $v new value + * @return void + */ + public function setSwiX($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->swi_x !== $v || $v === 0) { + $this->swi_x = $v; + $this->modifiedColumns[] = SwimlanesElementsPeer::SWI_X; + } + + } // setSwiX() + + /** + * Set the value of [swi_y] column. + * + * @param int $v new value + * @return void + */ + public function setSwiY($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->swi_y !== $v || $v === 0) { + $this->swi_y = $v; + $this->modifiedColumns[] = SwimlanesElementsPeer::SWI_Y; + } + + } // setSwiY() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->swi_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->swi_type = $rs->getString($startcol + 2); + + $this->swi_x = $rs->getInt($startcol + 3); + + $this->swi_y = $rs->getInt($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = SwimlanesElementsPeer::NUM_COLUMNS - SwimlanesElementsPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating SwimlanesElements object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + SwimlanesElementsPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = SwimlanesElementsPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += SwimlanesElementsPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = SwimlanesElementsPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SwimlanesElementsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getSwiUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getSwiType(); + break; + case 3: + return $this->getSwiX(); + break; + case 4: + return $this->getSwiY(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SwimlanesElementsPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getSwiUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getSwiType(), + $keys[3] => $this->getSwiX(), + $keys[4] => $this->getSwiY(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = SwimlanesElementsPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setSwiUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setSwiType($value); + break; + case 3: + $this->setSwiX($value); + break; + case 4: + $this->setSwiY($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = SwimlanesElementsPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setSwiUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setSwiType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setSwiX($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setSwiY($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(SwimlanesElementsPeer::DATABASE_NAME); + + if ($this->isColumnModified(SwimlanesElementsPeer::SWI_UID)) $criteria->add(SwimlanesElementsPeer::SWI_UID, $this->swi_uid); + if ($this->isColumnModified(SwimlanesElementsPeer::PRO_UID)) $criteria->add(SwimlanesElementsPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(SwimlanesElementsPeer::SWI_TYPE)) $criteria->add(SwimlanesElementsPeer::SWI_TYPE, $this->swi_type); + if ($this->isColumnModified(SwimlanesElementsPeer::SWI_X)) $criteria->add(SwimlanesElementsPeer::SWI_X, $this->swi_x); + if ($this->isColumnModified(SwimlanesElementsPeer::SWI_Y)) $criteria->add(SwimlanesElementsPeer::SWI_Y, $this->swi_y); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(SwimlanesElementsPeer::DATABASE_NAME); + + $criteria->add(SwimlanesElementsPeer::SWI_UID, $this->swi_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getSwiUid(); + } + + /** + * Generic method to set the primary key (swi_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setSwiUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of SwimlanesElements (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setSwiType($this->swi_type); + + $copyObj->setSwiX($this->swi_x); + + $copyObj->setSwiY($this->swi_y); + + + $copyObj->setNew(true); + + $copyObj->setSwiUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return SwimlanesElements Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return SwimlanesElementsPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new SwimlanesElementsPeer(); + } + return self::$peer; + } + +} // BaseSwimlanesElements diff --git a/workflow/engine/classes/model/om/BaseSwimlanesElementsPeer.php b/workflow/engine/classes/model/om/BaseSwimlanesElementsPeer.php new file mode 100644 index 000000000..f6d11d9cc --- /dev/null +++ b/workflow/engine/classes/model/om/BaseSwimlanesElementsPeer.php @@ -0,0 +1,594 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by SwimlanesElementsPeer::getOMClass() +include_once 'classes/model/SwimlanesElements.php'; + +/** + * Base static class for performing query and update operations on the 'SWIMLANES_ELEMENTS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseSwimlanesElementsPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'SWIMLANES_ELEMENTS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.SwimlanesElements'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the SWI_UID field */ + const SWI_UID = 'SWIMLANES_ELEMENTS.SWI_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'SWIMLANES_ELEMENTS.PRO_UID'; + + /** the column name for the SWI_TYPE field */ + const SWI_TYPE = 'SWIMLANES_ELEMENTS.SWI_TYPE'; + + /** the column name for the SWI_X field */ + const SWI_X = 'SWIMLANES_ELEMENTS.SWI_X'; + + /** the column name for the SWI_Y field */ + const SWI_Y = 'SWIMLANES_ELEMENTS.SWI_Y'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('SwiUid', 'ProUid', 'SwiType', 'SwiX', 'SwiY', ), + BasePeer::TYPE_COLNAME => array (SwimlanesElementsPeer::SWI_UID, SwimlanesElementsPeer::PRO_UID, SwimlanesElementsPeer::SWI_TYPE, SwimlanesElementsPeer::SWI_X, SwimlanesElementsPeer::SWI_Y, ), + BasePeer::TYPE_FIELDNAME => array ('SWI_UID', 'PRO_UID', 'SWI_TYPE', 'SWI_X', 'SWI_Y', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('SwiUid' => 0, 'ProUid' => 1, 'SwiType' => 2, 'SwiX' => 3, 'SwiY' => 4, ), + BasePeer::TYPE_COLNAME => array (SwimlanesElementsPeer::SWI_UID => 0, SwimlanesElementsPeer::PRO_UID => 1, SwimlanesElementsPeer::SWI_TYPE => 2, SwimlanesElementsPeer::SWI_X => 3, SwimlanesElementsPeer::SWI_Y => 4, ), + BasePeer::TYPE_FIELDNAME => array ('SWI_UID' => 0, 'PRO_UID' => 1, 'SWI_TYPE' => 2, 'SWI_X' => 3, 'SWI_Y' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/SwimlanesElementsMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.SwimlanesElementsMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = SwimlanesElementsPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. SwimlanesElementsPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(SwimlanesElementsPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(SwimlanesElementsPeer::SWI_UID); + + $criteria->addSelectColumn(SwimlanesElementsPeer::PRO_UID); + + $criteria->addSelectColumn(SwimlanesElementsPeer::SWI_TYPE); + + $criteria->addSelectColumn(SwimlanesElementsPeer::SWI_X); + + $criteria->addSelectColumn(SwimlanesElementsPeer::SWI_Y); + + } + + const COUNT = 'COUNT(SWIMLANES_ELEMENTS.SWI_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT SWIMLANES_ELEMENTS.SWI_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(SwimlanesElementsPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(SwimlanesElementsPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = SwimlanesElementsPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return SwimlanesElements + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = SwimlanesElementsPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return SwimlanesElementsPeer::populateObjects(SwimlanesElementsPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + SwimlanesElementsPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = SwimlanesElementsPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return SwimlanesElementsPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a SwimlanesElements or Criteria object. + * + * @param mixed $values Criteria or SwimlanesElements object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from SwimlanesElements object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a SwimlanesElements or Criteria object. + * + * @param mixed $values Criteria or SwimlanesElements object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(SwimlanesElementsPeer::SWI_UID); + $selectCriteria->add(SwimlanesElementsPeer::SWI_UID, $criteria->remove(SwimlanesElementsPeer::SWI_UID), $comparison); + + } else { // $values is SwimlanesElements object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the SWIMLANES_ELEMENTS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(SwimlanesElementsPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a SwimlanesElements or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or SwimlanesElements object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(SwimlanesElementsPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof SwimlanesElements) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(SwimlanesElementsPeer::SWI_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given SwimlanesElements object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param SwimlanesElements $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(SwimlanesElements $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(SwimlanesElementsPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(SwimlanesElementsPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(SwimlanesElementsPeer::SWI_UID)) + $columns[SwimlanesElementsPeer::SWI_UID] = $obj->getSwiUid(); + + if ($obj->isNew() || $obj->isColumnModified(SwimlanesElementsPeer::PRO_UID)) + $columns[SwimlanesElementsPeer::PRO_UID] = $obj->getProUid(); + + if ($obj->isNew() || $obj->isColumnModified(SwimlanesElementsPeer::SWI_TYPE)) + $columns[SwimlanesElementsPeer::SWI_TYPE] = $obj->getSwiType(); + + } + + return BasePeer::doValidate(SwimlanesElementsPeer::DATABASE_NAME, SwimlanesElementsPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return SwimlanesElements + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(SwimlanesElementsPeer::DATABASE_NAME); + + $criteria->add(SwimlanesElementsPeer::SWI_UID, $pk); + + + $v = SwimlanesElementsPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(SwimlanesElementsPeer::SWI_UID, $pks, Criteria::IN); + $objs = SwimlanesElementsPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseSwimlanesElementsPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseSwimlanesElementsPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/SwimlanesElementsMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.SwimlanesElementsMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseTask.php b/workflow/engine/classes/model/om/BaseTask.php new file mode 100644 index 000000000..4f0103e3e --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTask.php @@ -0,0 +1,2241 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/TaskPeer.php'; + +/** + * Base class that represents a row from the 'TASK' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTask extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var TaskPeer + */ + protected static $peer; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the tas_type field. + * @var string + */ + protected $tas_type = 'NORMAL'; + + + /** + * The value for the tas_duration field. + * @var double + */ + protected $tas_duration = 0; + + + /** + * The value for the tas_delay_type field. + * @var string + */ + protected $tas_delay_type = ''; + + + /** + * The value for the tas_temporizer field. + * @var double + */ + protected $tas_temporizer = 0; + + + /** + * The value for the tas_type_day field. + * @var string + */ + protected $tas_type_day = '1'; + + + /** + * The value for the tas_timeunit field. + * @var string + */ + protected $tas_timeunit = 'DAYS'; + + + /** + * The value for the tas_alert field. + * @var string + */ + protected $tas_alert = 'FALSE'; + + + /** + * The value for the tas_priority_variable field. + * @var string + */ + protected $tas_priority_variable = ''; + + + /** + * The value for the tas_assign_type field. + * @var string + */ + protected $tas_assign_type = 'BALANCED'; + + + /** + * The value for the tas_assign_variable field. + * @var string + */ + protected $tas_assign_variable = '@@SYS_NEXT_USER_TO_BE_ASSIGNED'; + + + /** + * The value for the tas_assign_location field. + * @var string + */ + protected $tas_assign_location = 'FALSE'; + + + /** + * The value for the tas_assign_location_adhoc field. + * @var string + */ + protected $tas_assign_location_adhoc = 'FALSE'; + + + /** + * The value for the tas_transfer_fly field. + * @var string + */ + protected $tas_transfer_fly = 'FALSE'; + + + /** + * The value for the tas_last_assigned field. + * @var string + */ + protected $tas_last_assigned = '0'; + + + /** + * The value for the tas_user field. + * @var string + */ + protected $tas_user = '0'; + + + /** + * The value for the tas_can_upload field. + * @var string + */ + protected $tas_can_upload = 'FALSE'; + + + /** + * The value for the tas_view_upload field. + * @var string + */ + protected $tas_view_upload = 'FALSE'; + + + /** + * The value for the tas_view_additional_documentation field. + * @var string + */ + protected $tas_view_additional_documentation = 'FALSE'; + + + /** + * The value for the tas_can_cancel field. + * @var string + */ + protected $tas_can_cancel = 'FALSE'; + + + /** + * The value for the tas_owner_app field. + * @var string + */ + protected $tas_owner_app = ''; + + + /** + * The value for the stg_uid field. + * @var string + */ + protected $stg_uid = ''; + + + /** + * The value for the tas_can_pause field. + * @var string + */ + protected $tas_can_pause = 'FALSE'; + + + /** + * The value for the tas_can_send_message field. + * @var string + */ + protected $tas_can_send_message = 'TRUE'; + + + /** + * The value for the tas_can_delete_docs field. + * @var string + */ + protected $tas_can_delete_docs = 'FALSE'; + + + /** + * The value for the tas_self_service field. + * @var string + */ + protected $tas_self_service = 'FALSE'; + + + /** + * The value for the tas_start field. + * @var string + */ + protected $tas_start = 'FALSE'; + + + /** + * The value for the tas_to_last_user field. + * @var string + */ + protected $tas_to_last_user = 'FALSE'; + + + /** + * The value for the tas_send_last_email field. + * @var string + */ + protected $tas_send_last_email = 'TRUE'; + + + /** + * The value for the tas_derivation field. + * @var string + */ + protected $tas_derivation = 'NORMAL'; + + + /** + * The value for the tas_posx field. + * @var int + */ + protected $tas_posx = 0; + + + /** + * The value for the tas_posy field. + * @var int + */ + protected $tas_posy = 0; + + + /** + * The value for the tas_color field. + * @var string + */ + protected $tas_color = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [tas_type] column value. + * + * @return string + */ + public function getTasType() + { + + return $this->tas_type; + } + + /** + * Get the [tas_duration] column value. + * + * @return double + */ + public function getTasDuration() + { + + return $this->tas_duration; + } + + /** + * Get the [tas_delay_type] column value. + * + * @return string + */ + public function getTasDelayType() + { + + return $this->tas_delay_type; + } + + /** + * Get the [tas_temporizer] column value. + * + * @return double + */ + public function getTasTemporizer() + { + + return $this->tas_temporizer; + } + + /** + * Get the [tas_type_day] column value. + * + * @return string + */ + public function getTasTypeDay() + { + + return $this->tas_type_day; + } + + /** + * Get the [tas_timeunit] column value. + * + * @return string + */ + public function getTasTimeunit() + { + + return $this->tas_timeunit; + } + + /** + * Get the [tas_alert] column value. + * + * @return string + */ + public function getTasAlert() + { + + return $this->tas_alert; + } + + /** + * Get the [tas_priority_variable] column value. + * + * @return string + */ + public function getTasPriorityVariable() + { + + return $this->tas_priority_variable; + } + + /** + * Get the [tas_assign_type] column value. + * + * @return string + */ + public function getTasAssignType() + { + + return $this->tas_assign_type; + } + + /** + * Get the [tas_assign_variable] column value. + * + * @return string + */ + public function getTasAssignVariable() + { + + return $this->tas_assign_variable; + } + + /** + * Get the [tas_assign_location] column value. + * + * @return string + */ + public function getTasAssignLocation() + { + + return $this->tas_assign_location; + } + + /** + * Get the [tas_assign_location_adhoc] column value. + * + * @return string + */ + public function getTasAssignLocationAdhoc() + { + + return $this->tas_assign_location_adhoc; + } + + /** + * Get the [tas_transfer_fly] column value. + * + * @return string + */ + public function getTasTransferFly() + { + + return $this->tas_transfer_fly; + } + + /** + * Get the [tas_last_assigned] column value. + * + * @return string + */ + public function getTasLastAssigned() + { + + return $this->tas_last_assigned; + } + + /** + * Get the [tas_user] column value. + * + * @return string + */ + public function getTasUser() + { + + return $this->tas_user; + } + + /** + * Get the [tas_can_upload] column value. + * + * @return string + */ + public function getTasCanUpload() + { + + return $this->tas_can_upload; + } + + /** + * Get the [tas_view_upload] column value. + * + * @return string + */ + public function getTasViewUpload() + { + + return $this->tas_view_upload; + } + + /** + * Get the [tas_view_additional_documentation] column value. + * + * @return string + */ + public function getTasViewAdditionalDocumentation() + { + + return $this->tas_view_additional_documentation; + } + + /** + * Get the [tas_can_cancel] column value. + * + * @return string + */ + public function getTasCanCancel() + { + + return $this->tas_can_cancel; + } + + /** + * Get the [tas_owner_app] column value. + * + * @return string + */ + public function getTasOwnerApp() + { + + return $this->tas_owner_app; + } + + /** + * Get the [stg_uid] column value. + * + * @return string + */ + public function getStgUid() + { + + return $this->stg_uid; + } + + /** + * Get the [tas_can_pause] column value. + * + * @return string + */ + public function getTasCanPause() + { + + return $this->tas_can_pause; + } + + /** + * Get the [tas_can_send_message] column value. + * + * @return string + */ + public function getTasCanSendMessage() + { + + return $this->tas_can_send_message; + } + + /** + * Get the [tas_can_delete_docs] column value. + * + * @return string + */ + public function getTasCanDeleteDocs() + { + + return $this->tas_can_delete_docs; + } + + /** + * Get the [tas_self_service] column value. + * + * @return string + */ + public function getTasSelfService() + { + + return $this->tas_self_service; + } + + /** + * Get the [tas_start] column value. + * + * @return string + */ + public function getTasStart() + { + + return $this->tas_start; + } + + /** + * Get the [tas_to_last_user] column value. + * + * @return string + */ + public function getTasToLastUser() + { + + return $this->tas_to_last_user; + } + + /** + * Get the [tas_send_last_email] column value. + * + * @return string + */ + public function getTasSendLastEmail() + { + + return $this->tas_send_last_email; + } + + /** + * Get the [tas_derivation] column value. + * + * @return string + */ + public function getTasDerivation() + { + + return $this->tas_derivation; + } + + /** + * Get the [tas_posx] column value. + * + * @return int + */ + public function getTasPosx() + { + + return $this->tas_posx; + } + + /** + * Get the [tas_posy] column value. + * + * @return int + */ + public function getTasPosy() + { + + return $this->tas_posy; + } + + /** + * Get the [tas_color] column value. + * + * @return string + */ + public function getTasColor() + { + + return $this->tas_color; + } + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = TaskPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = TaskPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [tas_type] column. + * + * @param string $v new value + * @return void + */ + public function setTasType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_type !== $v || $v === 'NORMAL') { + $this->tas_type = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TYPE; + } + + } // setTasType() + + /** + * Set the value of [tas_duration] column. + * + * @param double $v new value + * @return void + */ + public function setTasDuration($v) + { + + if ($this->tas_duration !== $v || $v === 0) { + $this->tas_duration = $v; + $this->modifiedColumns[] = TaskPeer::TAS_DURATION; + } + + } // setTasDuration() + + /** + * Set the value of [tas_delay_type] column. + * + * @param string $v new value + * @return void + */ + public function setTasDelayType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_delay_type !== $v || $v === '') { + $this->tas_delay_type = $v; + $this->modifiedColumns[] = TaskPeer::TAS_DELAY_TYPE; + } + + } // setTasDelayType() + + /** + * Set the value of [tas_temporizer] column. + * + * @param double $v new value + * @return void + */ + public function setTasTemporizer($v) + { + + if ($this->tas_temporizer !== $v || $v === 0) { + $this->tas_temporizer = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TEMPORIZER; + } + + } // setTasTemporizer() + + /** + * Set the value of [tas_type_day] column. + * + * @param string $v new value + * @return void + */ + public function setTasTypeDay($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_type_day !== $v || $v === '1') { + $this->tas_type_day = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TYPE_DAY; + } + + } // setTasTypeDay() + + /** + * Set the value of [tas_timeunit] column. + * + * @param string $v new value + * @return void + */ + public function setTasTimeunit($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_timeunit !== $v || $v === 'DAYS') { + $this->tas_timeunit = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TIMEUNIT; + } + + } // setTasTimeunit() + + /** + * Set the value of [tas_alert] column. + * + * @param string $v new value + * @return void + */ + public function setTasAlert($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_alert !== $v || $v === 'FALSE') { + $this->tas_alert = $v; + $this->modifiedColumns[] = TaskPeer::TAS_ALERT; + } + + } // setTasAlert() + + /** + * Set the value of [tas_priority_variable] column. + * + * @param string $v new value + * @return void + */ + public function setTasPriorityVariable($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_priority_variable !== $v || $v === '') { + $this->tas_priority_variable = $v; + $this->modifiedColumns[] = TaskPeer::TAS_PRIORITY_VARIABLE; + } + + } // setTasPriorityVariable() + + /** + * Set the value of [tas_assign_type] column. + * + * @param string $v new value + * @return void + */ + public function setTasAssignType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_assign_type !== $v || $v === 'BALANCED') { + $this->tas_assign_type = $v; + $this->modifiedColumns[] = TaskPeer::TAS_ASSIGN_TYPE; + } + + } // setTasAssignType() + + /** + * Set the value of [tas_assign_variable] column. + * + * @param string $v new value + * @return void + */ + public function setTasAssignVariable($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_assign_variable !== $v || $v === '@@SYS_NEXT_USER_TO_BE_ASSIGNED') { + $this->tas_assign_variable = $v; + $this->modifiedColumns[] = TaskPeer::TAS_ASSIGN_VARIABLE; + } + + } // setTasAssignVariable() + + /** + * Set the value of [tas_assign_location] column. + * + * @param string $v new value + * @return void + */ + public function setTasAssignLocation($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_assign_location !== $v || $v === 'FALSE') { + $this->tas_assign_location = $v; + $this->modifiedColumns[] = TaskPeer::TAS_ASSIGN_LOCATION; + } + + } // setTasAssignLocation() + + /** + * Set the value of [tas_assign_location_adhoc] column. + * + * @param string $v new value + * @return void + */ + public function setTasAssignLocationAdhoc($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_assign_location_adhoc !== $v || $v === 'FALSE') { + $this->tas_assign_location_adhoc = $v; + $this->modifiedColumns[] = TaskPeer::TAS_ASSIGN_LOCATION_ADHOC; + } + + } // setTasAssignLocationAdhoc() + + /** + * Set the value of [tas_transfer_fly] column. + * + * @param string $v new value + * @return void + */ + public function setTasTransferFly($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_transfer_fly !== $v || $v === 'FALSE') { + $this->tas_transfer_fly = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TRANSFER_FLY; + } + + } // setTasTransferFly() + + /** + * Set the value of [tas_last_assigned] column. + * + * @param string $v new value + * @return void + */ + public function setTasLastAssigned($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_last_assigned !== $v || $v === '0') { + $this->tas_last_assigned = $v; + $this->modifiedColumns[] = TaskPeer::TAS_LAST_ASSIGNED; + } + + } // setTasLastAssigned() + + /** + * Set the value of [tas_user] column. + * + * @param string $v new value + * @return void + */ + public function setTasUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_user !== $v || $v === '0') { + $this->tas_user = $v; + $this->modifiedColumns[] = TaskPeer::TAS_USER; + } + + } // setTasUser() + + /** + * Set the value of [tas_can_upload] column. + * + * @param string $v new value + * @return void + */ + public function setTasCanUpload($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_can_upload !== $v || $v === 'FALSE') { + $this->tas_can_upload = $v; + $this->modifiedColumns[] = TaskPeer::TAS_CAN_UPLOAD; + } + + } // setTasCanUpload() + + /** + * Set the value of [tas_view_upload] column. + * + * @param string $v new value + * @return void + */ + public function setTasViewUpload($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_view_upload !== $v || $v === 'FALSE') { + $this->tas_view_upload = $v; + $this->modifiedColumns[] = TaskPeer::TAS_VIEW_UPLOAD; + } + + } // setTasViewUpload() + + /** + * Set the value of [tas_view_additional_documentation] column. + * + * @param string $v new value + * @return void + */ + public function setTasViewAdditionalDocumentation($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_view_additional_documentation !== $v || $v === 'FALSE') { + $this->tas_view_additional_documentation = $v; + $this->modifiedColumns[] = TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION; + } + + } // setTasViewAdditionalDocumentation() + + /** + * Set the value of [tas_can_cancel] column. + * + * @param string $v new value + * @return void + */ + public function setTasCanCancel($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_can_cancel !== $v || $v === 'FALSE') { + $this->tas_can_cancel = $v; + $this->modifiedColumns[] = TaskPeer::TAS_CAN_CANCEL; + } + + } // setTasCanCancel() + + /** + * Set the value of [tas_owner_app] column. + * + * @param string $v new value + * @return void + */ + public function setTasOwnerApp($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_owner_app !== $v || $v === '') { + $this->tas_owner_app = $v; + $this->modifiedColumns[] = TaskPeer::TAS_OWNER_APP; + } + + } // setTasOwnerApp() + + /** + * Set the value of [stg_uid] column. + * + * @param string $v new value + * @return void + */ + public function setStgUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->stg_uid !== $v || $v === '') { + $this->stg_uid = $v; + $this->modifiedColumns[] = TaskPeer::STG_UID; + } + + } // setStgUid() + + /** + * Set the value of [tas_can_pause] column. + * + * @param string $v new value + * @return void + */ + public function setTasCanPause($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_can_pause !== $v || $v === 'FALSE') { + $this->tas_can_pause = $v; + $this->modifiedColumns[] = TaskPeer::TAS_CAN_PAUSE; + } + + } // setTasCanPause() + + /** + * Set the value of [tas_can_send_message] column. + * + * @param string $v new value + * @return void + */ + public function setTasCanSendMessage($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_can_send_message !== $v || $v === 'TRUE') { + $this->tas_can_send_message = $v; + $this->modifiedColumns[] = TaskPeer::TAS_CAN_SEND_MESSAGE; + } + + } // setTasCanSendMessage() + + /** + * Set the value of [tas_can_delete_docs] column. + * + * @param string $v new value + * @return void + */ + public function setTasCanDeleteDocs($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_can_delete_docs !== $v || $v === 'FALSE') { + $this->tas_can_delete_docs = $v; + $this->modifiedColumns[] = TaskPeer::TAS_CAN_DELETE_DOCS; + } + + } // setTasCanDeleteDocs() + + /** + * Set the value of [tas_self_service] column. + * + * @param string $v new value + * @return void + */ + public function setTasSelfService($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_self_service !== $v || $v === 'FALSE') { + $this->tas_self_service = $v; + $this->modifiedColumns[] = TaskPeer::TAS_SELF_SERVICE; + } + + } // setTasSelfService() + + /** + * Set the value of [tas_start] column. + * + * @param string $v new value + * @return void + */ + public function setTasStart($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_start !== $v || $v === 'FALSE') { + $this->tas_start = $v; + $this->modifiedColumns[] = TaskPeer::TAS_START; + } + + } // setTasStart() + + /** + * Set the value of [tas_to_last_user] column. + * + * @param string $v new value + * @return void + */ + public function setTasToLastUser($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_to_last_user !== $v || $v === 'FALSE') { + $this->tas_to_last_user = $v; + $this->modifiedColumns[] = TaskPeer::TAS_TO_LAST_USER; + } + + } // setTasToLastUser() + + /** + * Set the value of [tas_send_last_email] column. + * + * @param string $v new value + * @return void + */ + public function setTasSendLastEmail($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_send_last_email !== $v || $v === 'TRUE') { + $this->tas_send_last_email = $v; + $this->modifiedColumns[] = TaskPeer::TAS_SEND_LAST_EMAIL; + } + + } // setTasSendLastEmail() + + /** + * Set the value of [tas_derivation] column. + * + * @param string $v new value + * @return void + */ + public function setTasDerivation($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_derivation !== $v || $v === 'NORMAL') { + $this->tas_derivation = $v; + $this->modifiedColumns[] = TaskPeer::TAS_DERIVATION; + } + + } // setTasDerivation() + + /** + * Set the value of [tas_posx] column. + * + * @param int $v new value + * @return void + */ + public function setTasPosx($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->tas_posx !== $v || $v === 0) { + $this->tas_posx = $v; + $this->modifiedColumns[] = TaskPeer::TAS_POSX; + } + + } // setTasPosx() + + /** + * Set the value of [tas_posy] column. + * + * @param int $v new value + * @return void + */ + public function setTasPosy($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->tas_posy !== $v || $v === 0) { + $this->tas_posy = $v; + $this->modifiedColumns[] = TaskPeer::TAS_POSY; + } + + } // setTasPosy() + + /** + * Set the value of [tas_color] column. + * + * @param string $v new value + * @return void + */ + public function setTasColor($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_color !== $v || $v === '') { + $this->tas_color = $v; + $this->modifiedColumns[] = TaskPeer::TAS_COLOR; + } + + } // setTasColor() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->pro_uid = $rs->getString($startcol + 0); + + $this->tas_uid = $rs->getString($startcol + 1); + + $this->tas_type = $rs->getString($startcol + 2); + + $this->tas_duration = $rs->getFloat($startcol + 3); + + $this->tas_delay_type = $rs->getString($startcol + 4); + + $this->tas_temporizer = $rs->getFloat($startcol + 5); + + $this->tas_type_day = $rs->getString($startcol + 6); + + $this->tas_timeunit = $rs->getString($startcol + 7); + + $this->tas_alert = $rs->getString($startcol + 8); + + $this->tas_priority_variable = $rs->getString($startcol + 9); + + $this->tas_assign_type = $rs->getString($startcol + 10); + + $this->tas_assign_variable = $rs->getString($startcol + 11); + + $this->tas_assign_location = $rs->getString($startcol + 12); + + $this->tas_assign_location_adhoc = $rs->getString($startcol + 13); + + $this->tas_transfer_fly = $rs->getString($startcol + 14); + + $this->tas_last_assigned = $rs->getString($startcol + 15); + + $this->tas_user = $rs->getString($startcol + 16); + + $this->tas_can_upload = $rs->getString($startcol + 17); + + $this->tas_view_upload = $rs->getString($startcol + 18); + + $this->tas_view_additional_documentation = $rs->getString($startcol + 19); + + $this->tas_can_cancel = $rs->getString($startcol + 20); + + $this->tas_owner_app = $rs->getString($startcol + 21); + + $this->stg_uid = $rs->getString($startcol + 22); + + $this->tas_can_pause = $rs->getString($startcol + 23); + + $this->tas_can_send_message = $rs->getString($startcol + 24); + + $this->tas_can_delete_docs = $rs->getString($startcol + 25); + + $this->tas_self_service = $rs->getString($startcol + 26); + + $this->tas_start = $rs->getString($startcol + 27); + + $this->tas_to_last_user = $rs->getString($startcol + 28); + + $this->tas_send_last_email = $rs->getString($startcol + 29); + + $this->tas_derivation = $rs->getString($startcol + 30); + + $this->tas_posx = $rs->getInt($startcol + 31); + + $this->tas_posy = $rs->getInt($startcol + 32); + + $this->tas_color = $rs->getString($startcol + 33); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 34; // 34 = TaskPeer::NUM_COLUMNS - TaskPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Task object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + } + + try { + $con->begin(); + TaskPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = TaskPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += TaskPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = TaskPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TaskPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getProUid(); + break; + case 1: + return $this->getTasUid(); + break; + case 2: + return $this->getTasType(); + break; + case 3: + return $this->getTasDuration(); + break; + case 4: + return $this->getTasDelayType(); + break; + case 5: + return $this->getTasTemporizer(); + break; + case 6: + return $this->getTasTypeDay(); + break; + case 7: + return $this->getTasTimeunit(); + break; + case 8: + return $this->getTasAlert(); + break; + case 9: + return $this->getTasPriorityVariable(); + break; + case 10: + return $this->getTasAssignType(); + break; + case 11: + return $this->getTasAssignVariable(); + break; + case 12: + return $this->getTasAssignLocation(); + break; + case 13: + return $this->getTasAssignLocationAdhoc(); + break; + case 14: + return $this->getTasTransferFly(); + break; + case 15: + return $this->getTasLastAssigned(); + break; + case 16: + return $this->getTasUser(); + break; + case 17: + return $this->getTasCanUpload(); + break; + case 18: + return $this->getTasViewUpload(); + break; + case 19: + return $this->getTasViewAdditionalDocumentation(); + break; + case 20: + return $this->getTasCanCancel(); + break; + case 21: + return $this->getTasOwnerApp(); + break; + case 22: + return $this->getStgUid(); + break; + case 23: + return $this->getTasCanPause(); + break; + case 24: + return $this->getTasCanSendMessage(); + break; + case 25: + return $this->getTasCanDeleteDocs(); + break; + case 26: + return $this->getTasSelfService(); + break; + case 27: + return $this->getTasStart(); + break; + case 28: + return $this->getTasToLastUser(); + break; + case 29: + return $this->getTasSendLastEmail(); + break; + case 30: + return $this->getTasDerivation(); + break; + case 31: + return $this->getTasPosx(); + break; + case 32: + return $this->getTasPosy(); + break; + case 33: + return $this->getTasColor(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TaskPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getProUid(), + $keys[1] => $this->getTasUid(), + $keys[2] => $this->getTasType(), + $keys[3] => $this->getTasDuration(), + $keys[4] => $this->getTasDelayType(), + $keys[5] => $this->getTasTemporizer(), + $keys[6] => $this->getTasTypeDay(), + $keys[7] => $this->getTasTimeunit(), + $keys[8] => $this->getTasAlert(), + $keys[9] => $this->getTasPriorityVariable(), + $keys[10] => $this->getTasAssignType(), + $keys[11] => $this->getTasAssignVariable(), + $keys[12] => $this->getTasAssignLocation(), + $keys[13] => $this->getTasAssignLocationAdhoc(), + $keys[14] => $this->getTasTransferFly(), + $keys[15] => $this->getTasLastAssigned(), + $keys[16] => $this->getTasUser(), + $keys[17] => $this->getTasCanUpload(), + $keys[18] => $this->getTasViewUpload(), + $keys[19] => $this->getTasViewAdditionalDocumentation(), + $keys[20] => $this->getTasCanCancel(), + $keys[21] => $this->getTasOwnerApp(), + $keys[22] => $this->getStgUid(), + $keys[23] => $this->getTasCanPause(), + $keys[24] => $this->getTasCanSendMessage(), + $keys[25] => $this->getTasCanDeleteDocs(), + $keys[26] => $this->getTasSelfService(), + $keys[27] => $this->getTasStart(), + $keys[28] => $this->getTasToLastUser(), + $keys[29] => $this->getTasSendLastEmail(), + $keys[30] => $this->getTasDerivation(), + $keys[31] => $this->getTasPosx(), + $keys[32] => $this->getTasPosy(), + $keys[33] => $this->getTasColor(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TaskPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setProUid($value); + break; + case 1: + $this->setTasUid($value); + break; + case 2: + $this->setTasType($value); + break; + case 3: + $this->setTasDuration($value); + break; + case 4: + $this->setTasDelayType($value); + break; + case 5: + $this->setTasTemporizer($value); + break; + case 6: + $this->setTasTypeDay($value); + break; + case 7: + $this->setTasTimeunit($value); + break; + case 8: + $this->setTasAlert($value); + break; + case 9: + $this->setTasPriorityVariable($value); + break; + case 10: + $this->setTasAssignType($value); + break; + case 11: + $this->setTasAssignVariable($value); + break; + case 12: + $this->setTasAssignLocation($value); + break; + case 13: + $this->setTasAssignLocationAdhoc($value); + break; + case 14: + $this->setTasTransferFly($value); + break; + case 15: + $this->setTasLastAssigned($value); + break; + case 16: + $this->setTasUser($value); + break; + case 17: + $this->setTasCanUpload($value); + break; + case 18: + $this->setTasViewUpload($value); + break; + case 19: + $this->setTasViewAdditionalDocumentation($value); + break; + case 20: + $this->setTasCanCancel($value); + break; + case 21: + $this->setTasOwnerApp($value); + break; + case 22: + $this->setStgUid($value); + break; + case 23: + $this->setTasCanPause($value); + break; + case 24: + $this->setTasCanSendMessage($value); + break; + case 25: + $this->setTasCanDeleteDocs($value); + break; + case 26: + $this->setTasSelfService($value); + break; + case 27: + $this->setTasStart($value); + break; + case 28: + $this->setTasToLastUser($value); + break; + case 29: + $this->setTasSendLastEmail($value); + break; + case 30: + $this->setTasDerivation($value); + break; + case 31: + $this->setTasPosx($value); + break; + case 32: + $this->setTasPosy($value); + break; + case 33: + $this->setTasColor($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TaskPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setProUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setTasUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTasType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTasDuration($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTasDelayType($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setTasTemporizer($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setTasTypeDay($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setTasTimeunit($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setTasAlert($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setTasPriorityVariable($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setTasAssignType($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setTasAssignVariable($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setTasAssignLocation($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setTasAssignLocationAdhoc($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setTasTransferFly($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setTasLastAssigned($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setTasUser($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setTasCanUpload($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setTasViewUpload($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setTasViewAdditionalDocumentation($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setTasCanCancel($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setTasOwnerApp($arr[$keys[21]]); + if (array_key_exists($keys[22], $arr)) $this->setStgUid($arr[$keys[22]]); + if (array_key_exists($keys[23], $arr)) $this->setTasCanPause($arr[$keys[23]]); + if (array_key_exists($keys[24], $arr)) $this->setTasCanSendMessage($arr[$keys[24]]); + if (array_key_exists($keys[25], $arr)) $this->setTasCanDeleteDocs($arr[$keys[25]]); + if (array_key_exists($keys[26], $arr)) $this->setTasSelfService($arr[$keys[26]]); + if (array_key_exists($keys[27], $arr)) $this->setTasStart($arr[$keys[27]]); + if (array_key_exists($keys[28], $arr)) $this->setTasToLastUser($arr[$keys[28]]); + if (array_key_exists($keys[29], $arr)) $this->setTasSendLastEmail($arr[$keys[29]]); + if (array_key_exists($keys[30], $arr)) $this->setTasDerivation($arr[$keys[30]]); + if (array_key_exists($keys[31], $arr)) $this->setTasPosx($arr[$keys[31]]); + if (array_key_exists($keys[32], $arr)) $this->setTasPosy($arr[$keys[32]]); + if (array_key_exists($keys[33], $arr)) $this->setTasColor($arr[$keys[33]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TaskPeer::DATABASE_NAME); + + if ($this->isColumnModified(TaskPeer::PRO_UID)) $criteria->add(TaskPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(TaskPeer::TAS_UID)) $criteria->add(TaskPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(TaskPeer::TAS_TYPE)) $criteria->add(TaskPeer::TAS_TYPE, $this->tas_type); + if ($this->isColumnModified(TaskPeer::TAS_DURATION)) $criteria->add(TaskPeer::TAS_DURATION, $this->tas_duration); + if ($this->isColumnModified(TaskPeer::TAS_DELAY_TYPE)) $criteria->add(TaskPeer::TAS_DELAY_TYPE, $this->tas_delay_type); + if ($this->isColumnModified(TaskPeer::TAS_TEMPORIZER)) $criteria->add(TaskPeer::TAS_TEMPORIZER, $this->tas_temporizer); + if ($this->isColumnModified(TaskPeer::TAS_TYPE_DAY)) $criteria->add(TaskPeer::TAS_TYPE_DAY, $this->tas_type_day); + if ($this->isColumnModified(TaskPeer::TAS_TIMEUNIT)) $criteria->add(TaskPeer::TAS_TIMEUNIT, $this->tas_timeunit); + if ($this->isColumnModified(TaskPeer::TAS_ALERT)) $criteria->add(TaskPeer::TAS_ALERT, $this->tas_alert); + if ($this->isColumnModified(TaskPeer::TAS_PRIORITY_VARIABLE)) $criteria->add(TaskPeer::TAS_PRIORITY_VARIABLE, $this->tas_priority_variable); + if ($this->isColumnModified(TaskPeer::TAS_ASSIGN_TYPE)) $criteria->add(TaskPeer::TAS_ASSIGN_TYPE, $this->tas_assign_type); + if ($this->isColumnModified(TaskPeer::TAS_ASSIGN_VARIABLE)) $criteria->add(TaskPeer::TAS_ASSIGN_VARIABLE, $this->tas_assign_variable); + if ($this->isColumnModified(TaskPeer::TAS_ASSIGN_LOCATION)) $criteria->add(TaskPeer::TAS_ASSIGN_LOCATION, $this->tas_assign_location); + if ($this->isColumnModified(TaskPeer::TAS_ASSIGN_LOCATION_ADHOC)) $criteria->add(TaskPeer::TAS_ASSIGN_LOCATION_ADHOC, $this->tas_assign_location_adhoc); + if ($this->isColumnModified(TaskPeer::TAS_TRANSFER_FLY)) $criteria->add(TaskPeer::TAS_TRANSFER_FLY, $this->tas_transfer_fly); + if ($this->isColumnModified(TaskPeer::TAS_LAST_ASSIGNED)) $criteria->add(TaskPeer::TAS_LAST_ASSIGNED, $this->tas_last_assigned); + if ($this->isColumnModified(TaskPeer::TAS_USER)) $criteria->add(TaskPeer::TAS_USER, $this->tas_user); + if ($this->isColumnModified(TaskPeer::TAS_CAN_UPLOAD)) $criteria->add(TaskPeer::TAS_CAN_UPLOAD, $this->tas_can_upload); + if ($this->isColumnModified(TaskPeer::TAS_VIEW_UPLOAD)) $criteria->add(TaskPeer::TAS_VIEW_UPLOAD, $this->tas_view_upload); + if ($this->isColumnModified(TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION)) $criteria->add(TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION, $this->tas_view_additional_documentation); + if ($this->isColumnModified(TaskPeer::TAS_CAN_CANCEL)) $criteria->add(TaskPeer::TAS_CAN_CANCEL, $this->tas_can_cancel); + if ($this->isColumnModified(TaskPeer::TAS_OWNER_APP)) $criteria->add(TaskPeer::TAS_OWNER_APP, $this->tas_owner_app); + if ($this->isColumnModified(TaskPeer::STG_UID)) $criteria->add(TaskPeer::STG_UID, $this->stg_uid); + if ($this->isColumnModified(TaskPeer::TAS_CAN_PAUSE)) $criteria->add(TaskPeer::TAS_CAN_PAUSE, $this->tas_can_pause); + if ($this->isColumnModified(TaskPeer::TAS_CAN_SEND_MESSAGE)) $criteria->add(TaskPeer::TAS_CAN_SEND_MESSAGE, $this->tas_can_send_message); + if ($this->isColumnModified(TaskPeer::TAS_CAN_DELETE_DOCS)) $criteria->add(TaskPeer::TAS_CAN_DELETE_DOCS, $this->tas_can_delete_docs); + if ($this->isColumnModified(TaskPeer::TAS_SELF_SERVICE)) $criteria->add(TaskPeer::TAS_SELF_SERVICE, $this->tas_self_service); + if ($this->isColumnModified(TaskPeer::TAS_START)) $criteria->add(TaskPeer::TAS_START, $this->tas_start); + if ($this->isColumnModified(TaskPeer::TAS_TO_LAST_USER)) $criteria->add(TaskPeer::TAS_TO_LAST_USER, $this->tas_to_last_user); + if ($this->isColumnModified(TaskPeer::TAS_SEND_LAST_EMAIL)) $criteria->add(TaskPeer::TAS_SEND_LAST_EMAIL, $this->tas_send_last_email); + if ($this->isColumnModified(TaskPeer::TAS_DERIVATION)) $criteria->add(TaskPeer::TAS_DERIVATION, $this->tas_derivation); + if ($this->isColumnModified(TaskPeer::TAS_POSX)) $criteria->add(TaskPeer::TAS_POSX, $this->tas_posx); + if ($this->isColumnModified(TaskPeer::TAS_POSY)) $criteria->add(TaskPeer::TAS_POSY, $this->tas_posy); + if ($this->isColumnModified(TaskPeer::TAS_COLOR)) $criteria->add(TaskPeer::TAS_COLOR, $this->tas_color); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TaskPeer::DATABASE_NAME); + + $criteria->add(TaskPeer::TAS_UID, $this->tas_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getTasUid(); + } + + /** + * Generic method to set the primary key (tas_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setTasUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Task (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTasType($this->tas_type); + + $copyObj->setTasDuration($this->tas_duration); + + $copyObj->setTasDelayType($this->tas_delay_type); + + $copyObj->setTasTemporizer($this->tas_temporizer); + + $copyObj->setTasTypeDay($this->tas_type_day); + + $copyObj->setTasTimeunit($this->tas_timeunit); + + $copyObj->setTasAlert($this->tas_alert); + + $copyObj->setTasPriorityVariable($this->tas_priority_variable); + + $copyObj->setTasAssignType($this->tas_assign_type); + + $copyObj->setTasAssignVariable($this->tas_assign_variable); + + $copyObj->setTasAssignLocation($this->tas_assign_location); + + $copyObj->setTasAssignLocationAdhoc($this->tas_assign_location_adhoc); + + $copyObj->setTasTransferFly($this->tas_transfer_fly); + + $copyObj->setTasLastAssigned($this->tas_last_assigned); + + $copyObj->setTasUser($this->tas_user); + + $copyObj->setTasCanUpload($this->tas_can_upload); + + $copyObj->setTasViewUpload($this->tas_view_upload); + + $copyObj->setTasViewAdditionalDocumentation($this->tas_view_additional_documentation); + + $copyObj->setTasCanCancel($this->tas_can_cancel); + + $copyObj->setTasOwnerApp($this->tas_owner_app); + + $copyObj->setStgUid($this->stg_uid); + + $copyObj->setTasCanPause($this->tas_can_pause); + + $copyObj->setTasCanSendMessage($this->tas_can_send_message); + + $copyObj->setTasCanDeleteDocs($this->tas_can_delete_docs); + + $copyObj->setTasSelfService($this->tas_self_service); + + $copyObj->setTasStart($this->tas_start); + + $copyObj->setTasToLastUser($this->tas_to_last_user); + + $copyObj->setTasSendLastEmail($this->tas_send_last_email); + + $copyObj->setTasDerivation($this->tas_derivation); + + $copyObj->setTasPosx($this->tas_posx); + + $copyObj->setTasPosy($this->tas_posy); + + $copyObj->setTasColor($this->tas_color); + + + $copyObj->setNew(true); + + $copyObj->setTasUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Task Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return TaskPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new TaskPeer(); + } + return self::$peer; + } + +} // BaseTask diff --git a/workflow/engine/classes/model/om/BaseTaskPeer.php b/workflow/engine/classes/model/om/BaseTaskPeer.php new file mode 100644 index 000000000..562bcb6bc --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTaskPeer.php @@ -0,0 +1,787 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by TaskPeer::getOMClass() +include_once 'classes/model/Task.php'; + +/** + * Base static class for performing query and update operations on the 'TASK' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTaskPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'TASK'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Task'; + + /** The total number of columns. */ + const NUM_COLUMNS = 34; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the PRO_UID field */ + const PRO_UID = 'TASK.PRO_UID'; + + /** the column name for the TAS_UID field */ + const TAS_UID = 'TASK.TAS_UID'; + + /** the column name for the TAS_TYPE field */ + const TAS_TYPE = 'TASK.TAS_TYPE'; + + /** the column name for the TAS_DURATION field */ + const TAS_DURATION = 'TASK.TAS_DURATION'; + + /** the column name for the TAS_DELAY_TYPE field */ + const TAS_DELAY_TYPE = 'TASK.TAS_DELAY_TYPE'; + + /** the column name for the TAS_TEMPORIZER field */ + const TAS_TEMPORIZER = 'TASK.TAS_TEMPORIZER'; + + /** the column name for the TAS_TYPE_DAY field */ + const TAS_TYPE_DAY = 'TASK.TAS_TYPE_DAY'; + + /** the column name for the TAS_TIMEUNIT field */ + const TAS_TIMEUNIT = 'TASK.TAS_TIMEUNIT'; + + /** the column name for the TAS_ALERT field */ + const TAS_ALERT = 'TASK.TAS_ALERT'; + + /** the column name for the TAS_PRIORITY_VARIABLE field */ + const TAS_PRIORITY_VARIABLE = 'TASK.TAS_PRIORITY_VARIABLE'; + + /** the column name for the TAS_ASSIGN_TYPE field */ + const TAS_ASSIGN_TYPE = 'TASK.TAS_ASSIGN_TYPE'; + + /** the column name for the TAS_ASSIGN_VARIABLE field */ + const TAS_ASSIGN_VARIABLE = 'TASK.TAS_ASSIGN_VARIABLE'; + + /** the column name for the TAS_ASSIGN_LOCATION field */ + const TAS_ASSIGN_LOCATION = 'TASK.TAS_ASSIGN_LOCATION'; + + /** the column name for the TAS_ASSIGN_LOCATION_ADHOC field */ + const TAS_ASSIGN_LOCATION_ADHOC = 'TASK.TAS_ASSIGN_LOCATION_ADHOC'; + + /** the column name for the TAS_TRANSFER_FLY field */ + const TAS_TRANSFER_FLY = 'TASK.TAS_TRANSFER_FLY'; + + /** the column name for the TAS_LAST_ASSIGNED field */ + const TAS_LAST_ASSIGNED = 'TASK.TAS_LAST_ASSIGNED'; + + /** the column name for the TAS_USER field */ + const TAS_USER = 'TASK.TAS_USER'; + + /** the column name for the TAS_CAN_UPLOAD field */ + const TAS_CAN_UPLOAD = 'TASK.TAS_CAN_UPLOAD'; + + /** the column name for the TAS_VIEW_UPLOAD field */ + const TAS_VIEW_UPLOAD = 'TASK.TAS_VIEW_UPLOAD'; + + /** the column name for the TAS_VIEW_ADDITIONAL_DOCUMENTATION field */ + const TAS_VIEW_ADDITIONAL_DOCUMENTATION = 'TASK.TAS_VIEW_ADDITIONAL_DOCUMENTATION'; + + /** the column name for the TAS_CAN_CANCEL field */ + const TAS_CAN_CANCEL = 'TASK.TAS_CAN_CANCEL'; + + /** the column name for the TAS_OWNER_APP field */ + const TAS_OWNER_APP = 'TASK.TAS_OWNER_APP'; + + /** the column name for the STG_UID field */ + const STG_UID = 'TASK.STG_UID'; + + /** the column name for the TAS_CAN_PAUSE field */ + const TAS_CAN_PAUSE = 'TASK.TAS_CAN_PAUSE'; + + /** the column name for the TAS_CAN_SEND_MESSAGE field */ + const TAS_CAN_SEND_MESSAGE = 'TASK.TAS_CAN_SEND_MESSAGE'; + + /** the column name for the TAS_CAN_DELETE_DOCS field */ + const TAS_CAN_DELETE_DOCS = 'TASK.TAS_CAN_DELETE_DOCS'; + + /** the column name for the TAS_SELF_SERVICE field */ + const TAS_SELF_SERVICE = 'TASK.TAS_SELF_SERVICE'; + + /** the column name for the TAS_START field */ + const TAS_START = 'TASK.TAS_START'; + + /** the column name for the TAS_TO_LAST_USER field */ + const TAS_TO_LAST_USER = 'TASK.TAS_TO_LAST_USER'; + + /** the column name for the TAS_SEND_LAST_EMAIL field */ + const TAS_SEND_LAST_EMAIL = 'TASK.TAS_SEND_LAST_EMAIL'; + + /** the column name for the TAS_DERIVATION field */ + const TAS_DERIVATION = 'TASK.TAS_DERIVATION'; + + /** the column name for the TAS_POSX field */ + const TAS_POSX = 'TASK.TAS_POSX'; + + /** the column name for the TAS_POSY field */ + const TAS_POSY = 'TASK.TAS_POSY'; + + /** the column name for the TAS_COLOR field */ + const TAS_COLOR = 'TASK.TAS_COLOR'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid', 'TasUid', 'TasType', 'TasDuration', 'TasDelayType', 'TasTemporizer', 'TasTypeDay', 'TasTimeunit', 'TasAlert', 'TasPriorityVariable', 'TasAssignType', 'TasAssignVariable', 'TasAssignLocation', 'TasAssignLocationAdhoc', 'TasTransferFly', 'TasLastAssigned', 'TasUser', 'TasCanUpload', 'TasViewUpload', 'TasViewAdditionalDocumentation', 'TasCanCancel', 'TasOwnerApp', 'StgUid', 'TasCanPause', 'TasCanSendMessage', 'TasCanDeleteDocs', 'TasSelfService', 'TasStart', 'TasToLastUser', 'TasSendLastEmail', 'TasDerivation', 'TasPosx', 'TasPosy', 'TasColor', ), + BasePeer::TYPE_COLNAME => array (TaskPeer::PRO_UID, TaskPeer::TAS_UID, TaskPeer::TAS_TYPE, TaskPeer::TAS_DURATION, TaskPeer::TAS_DELAY_TYPE, TaskPeer::TAS_TEMPORIZER, TaskPeer::TAS_TYPE_DAY, TaskPeer::TAS_TIMEUNIT, TaskPeer::TAS_ALERT, TaskPeer::TAS_PRIORITY_VARIABLE, TaskPeer::TAS_ASSIGN_TYPE, TaskPeer::TAS_ASSIGN_VARIABLE, TaskPeer::TAS_ASSIGN_LOCATION, TaskPeer::TAS_ASSIGN_LOCATION_ADHOC, TaskPeer::TAS_TRANSFER_FLY, TaskPeer::TAS_LAST_ASSIGNED, TaskPeer::TAS_USER, TaskPeer::TAS_CAN_UPLOAD, TaskPeer::TAS_VIEW_UPLOAD, TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION, TaskPeer::TAS_CAN_CANCEL, TaskPeer::TAS_OWNER_APP, TaskPeer::STG_UID, TaskPeer::TAS_CAN_PAUSE, TaskPeer::TAS_CAN_SEND_MESSAGE, TaskPeer::TAS_CAN_DELETE_DOCS, TaskPeer::TAS_SELF_SERVICE, TaskPeer::TAS_START, TaskPeer::TAS_TO_LAST_USER, TaskPeer::TAS_SEND_LAST_EMAIL, TaskPeer::TAS_DERIVATION, TaskPeer::TAS_POSX, TaskPeer::TAS_POSY, TaskPeer::TAS_COLOR, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID', 'TAS_UID', 'TAS_TYPE', 'TAS_DURATION', 'TAS_DELAY_TYPE', 'TAS_TEMPORIZER', 'TAS_TYPE_DAY', 'TAS_TIMEUNIT', 'TAS_ALERT', 'TAS_PRIORITY_VARIABLE', 'TAS_ASSIGN_TYPE', 'TAS_ASSIGN_VARIABLE', 'TAS_ASSIGN_LOCATION', 'TAS_ASSIGN_LOCATION_ADHOC', 'TAS_TRANSFER_FLY', 'TAS_LAST_ASSIGNED', 'TAS_USER', 'TAS_CAN_UPLOAD', 'TAS_VIEW_UPLOAD', 'TAS_VIEW_ADDITIONAL_DOCUMENTATION', 'TAS_CAN_CANCEL', 'TAS_OWNER_APP', 'STG_UID', 'TAS_CAN_PAUSE', 'TAS_CAN_SEND_MESSAGE', 'TAS_CAN_DELETE_DOCS', 'TAS_SELF_SERVICE', 'TAS_START', 'TAS_TO_LAST_USER', 'TAS_SEND_LAST_EMAIL', 'TAS_DERIVATION', 'TAS_POSX', 'TAS_POSY', 'TAS_COLOR', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('ProUid' => 0, 'TasUid' => 1, 'TasType' => 2, 'TasDuration' => 3, 'TasDelayType' => 4, 'TasTemporizer' => 5, 'TasTypeDay' => 6, 'TasTimeunit' => 7, 'TasAlert' => 8, 'TasPriorityVariable' => 9, 'TasAssignType' => 10, 'TasAssignVariable' => 11, 'TasAssignLocation' => 12, 'TasAssignLocationAdhoc' => 13, 'TasTransferFly' => 14, 'TasLastAssigned' => 15, 'TasUser' => 16, 'TasCanUpload' => 17, 'TasViewUpload' => 18, 'TasViewAdditionalDocumentation' => 19, 'TasCanCancel' => 20, 'TasOwnerApp' => 21, 'StgUid' => 22, 'TasCanPause' => 23, 'TasCanSendMessage' => 24, 'TasCanDeleteDocs' => 25, 'TasSelfService' => 26, 'TasStart' => 27, 'TasToLastUser' => 28, 'TasSendLastEmail' => 29, 'TasDerivation' => 30, 'TasPosx' => 31, 'TasPosy' => 32, 'TasColor' => 33, ), + BasePeer::TYPE_COLNAME => array (TaskPeer::PRO_UID => 0, TaskPeer::TAS_UID => 1, TaskPeer::TAS_TYPE => 2, TaskPeer::TAS_DURATION => 3, TaskPeer::TAS_DELAY_TYPE => 4, TaskPeer::TAS_TEMPORIZER => 5, TaskPeer::TAS_TYPE_DAY => 6, TaskPeer::TAS_TIMEUNIT => 7, TaskPeer::TAS_ALERT => 8, TaskPeer::TAS_PRIORITY_VARIABLE => 9, TaskPeer::TAS_ASSIGN_TYPE => 10, TaskPeer::TAS_ASSIGN_VARIABLE => 11, TaskPeer::TAS_ASSIGN_LOCATION => 12, TaskPeer::TAS_ASSIGN_LOCATION_ADHOC => 13, TaskPeer::TAS_TRANSFER_FLY => 14, TaskPeer::TAS_LAST_ASSIGNED => 15, TaskPeer::TAS_USER => 16, TaskPeer::TAS_CAN_UPLOAD => 17, TaskPeer::TAS_VIEW_UPLOAD => 18, TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION => 19, TaskPeer::TAS_CAN_CANCEL => 20, TaskPeer::TAS_OWNER_APP => 21, TaskPeer::STG_UID => 22, TaskPeer::TAS_CAN_PAUSE => 23, TaskPeer::TAS_CAN_SEND_MESSAGE => 24, TaskPeer::TAS_CAN_DELETE_DOCS => 25, TaskPeer::TAS_SELF_SERVICE => 26, TaskPeer::TAS_START => 27, TaskPeer::TAS_TO_LAST_USER => 28, TaskPeer::TAS_SEND_LAST_EMAIL => 29, TaskPeer::TAS_DERIVATION => 30, TaskPeer::TAS_POSX => 31, TaskPeer::TAS_POSY => 32, TaskPeer::TAS_COLOR => 33, ), + BasePeer::TYPE_FIELDNAME => array ('PRO_UID' => 0, 'TAS_UID' => 1, 'TAS_TYPE' => 2, 'TAS_DURATION' => 3, 'TAS_DELAY_TYPE' => 4, 'TAS_TEMPORIZER' => 5, 'TAS_TYPE_DAY' => 6, 'TAS_TIMEUNIT' => 7, 'TAS_ALERT' => 8, 'TAS_PRIORITY_VARIABLE' => 9, 'TAS_ASSIGN_TYPE' => 10, 'TAS_ASSIGN_VARIABLE' => 11, 'TAS_ASSIGN_LOCATION' => 12, 'TAS_ASSIGN_LOCATION_ADHOC' => 13, 'TAS_TRANSFER_FLY' => 14, 'TAS_LAST_ASSIGNED' => 15, 'TAS_USER' => 16, 'TAS_CAN_UPLOAD' => 17, 'TAS_VIEW_UPLOAD' => 18, 'TAS_VIEW_ADDITIONAL_DOCUMENTATION' => 19, 'TAS_CAN_CANCEL' => 20, 'TAS_OWNER_APP' => 21, 'STG_UID' => 22, 'TAS_CAN_PAUSE' => 23, 'TAS_CAN_SEND_MESSAGE' => 24, 'TAS_CAN_DELETE_DOCS' => 25, 'TAS_SELF_SERVICE' => 26, 'TAS_START' => 27, 'TAS_TO_LAST_USER' => 28, 'TAS_SEND_LAST_EMAIL' => 29, 'TAS_DERIVATION' => 30, 'TAS_POSX' => 31, 'TAS_POSY' => 32, 'TAS_COLOR' => 33, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/TaskMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.TaskMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = TaskPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. TaskPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(TaskPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(TaskPeer::PRO_UID); + + $criteria->addSelectColumn(TaskPeer::TAS_UID); + + $criteria->addSelectColumn(TaskPeer::TAS_TYPE); + + $criteria->addSelectColumn(TaskPeer::TAS_DURATION); + + $criteria->addSelectColumn(TaskPeer::TAS_DELAY_TYPE); + + $criteria->addSelectColumn(TaskPeer::TAS_TEMPORIZER); + + $criteria->addSelectColumn(TaskPeer::TAS_TYPE_DAY); + + $criteria->addSelectColumn(TaskPeer::TAS_TIMEUNIT); + + $criteria->addSelectColumn(TaskPeer::TAS_ALERT); + + $criteria->addSelectColumn(TaskPeer::TAS_PRIORITY_VARIABLE); + + $criteria->addSelectColumn(TaskPeer::TAS_ASSIGN_TYPE); + + $criteria->addSelectColumn(TaskPeer::TAS_ASSIGN_VARIABLE); + + $criteria->addSelectColumn(TaskPeer::TAS_ASSIGN_LOCATION); + + $criteria->addSelectColumn(TaskPeer::TAS_ASSIGN_LOCATION_ADHOC); + + $criteria->addSelectColumn(TaskPeer::TAS_TRANSFER_FLY); + + $criteria->addSelectColumn(TaskPeer::TAS_LAST_ASSIGNED); + + $criteria->addSelectColumn(TaskPeer::TAS_USER); + + $criteria->addSelectColumn(TaskPeer::TAS_CAN_UPLOAD); + + $criteria->addSelectColumn(TaskPeer::TAS_VIEW_UPLOAD); + + $criteria->addSelectColumn(TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION); + + $criteria->addSelectColumn(TaskPeer::TAS_CAN_CANCEL); + + $criteria->addSelectColumn(TaskPeer::TAS_OWNER_APP); + + $criteria->addSelectColumn(TaskPeer::STG_UID); + + $criteria->addSelectColumn(TaskPeer::TAS_CAN_PAUSE); + + $criteria->addSelectColumn(TaskPeer::TAS_CAN_SEND_MESSAGE); + + $criteria->addSelectColumn(TaskPeer::TAS_CAN_DELETE_DOCS); + + $criteria->addSelectColumn(TaskPeer::TAS_SELF_SERVICE); + + $criteria->addSelectColumn(TaskPeer::TAS_START); + + $criteria->addSelectColumn(TaskPeer::TAS_TO_LAST_USER); + + $criteria->addSelectColumn(TaskPeer::TAS_SEND_LAST_EMAIL); + + $criteria->addSelectColumn(TaskPeer::TAS_DERIVATION); + + $criteria->addSelectColumn(TaskPeer::TAS_POSX); + + $criteria->addSelectColumn(TaskPeer::TAS_POSY); + + $criteria->addSelectColumn(TaskPeer::TAS_COLOR); + + } + + const COUNT = 'COUNT(TASK.TAS_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT TASK.TAS_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(TaskPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(TaskPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = TaskPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Task + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = TaskPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return TaskPeer::populateObjects(TaskPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + TaskPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = TaskPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return TaskPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Task or Criteria object. + * + * @param mixed $values Criteria or Task object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Task object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Task or Criteria object. + * + * @param mixed $values Criteria or Task object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(TaskPeer::TAS_UID); + $selectCriteria->add(TaskPeer::TAS_UID, $criteria->remove(TaskPeer::TAS_UID), $comparison); + + } else { // $values is Task object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the TASK table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(TaskPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Task or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Task object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(TaskPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Task) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(TaskPeer::TAS_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Task object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Task $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Task $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(TaskPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(TaskPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_TYPE)) + $columns[TaskPeer::TAS_TYPE] = $obj->getTasType(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_TIMEUNIT)) + $columns[TaskPeer::TAS_TIMEUNIT] = $obj->getTasTimeunit(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_ALERT)) + $columns[TaskPeer::TAS_ALERT] = $obj->getTasAlert(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_ASSIGN_TYPE)) + $columns[TaskPeer::TAS_ASSIGN_TYPE] = $obj->getTasAssignType(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_ASSIGN_LOCATION)) + $columns[TaskPeer::TAS_ASSIGN_LOCATION] = $obj->getTasAssignLocation(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_ASSIGN_LOCATION_ADHOC)) + $columns[TaskPeer::TAS_ASSIGN_LOCATION_ADHOC] = $obj->getTasAssignLocationAdhoc(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_TRANSFER_FLY)) + $columns[TaskPeer::TAS_TRANSFER_FLY] = $obj->getTasTransferFly(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_CAN_UPLOAD)) + $columns[TaskPeer::TAS_CAN_UPLOAD] = $obj->getTasCanUpload(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_VIEW_UPLOAD)) + $columns[TaskPeer::TAS_VIEW_UPLOAD] = $obj->getTasViewUpload(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION)) + $columns[TaskPeer::TAS_VIEW_ADDITIONAL_DOCUMENTATION] = $obj->getTasViewAdditionalDocumentation(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_CAN_CANCEL)) + $columns[TaskPeer::TAS_CAN_CANCEL] = $obj->getTasCanCancel(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_CAN_PAUSE)) + $columns[TaskPeer::TAS_CAN_PAUSE] = $obj->getTasCanPause(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_CAN_SEND_MESSAGE)) + $columns[TaskPeer::TAS_CAN_SEND_MESSAGE] = $obj->getTasCanSendMessage(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_CAN_DELETE_DOCS)) + $columns[TaskPeer::TAS_CAN_DELETE_DOCS] = $obj->getTasCanDeleteDocs(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_SELF_SERVICE)) + $columns[TaskPeer::TAS_SELF_SERVICE] = $obj->getTasSelfService(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_START)) + $columns[TaskPeer::TAS_START] = $obj->getTasStart(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_TO_LAST_USER)) + $columns[TaskPeer::TAS_TO_LAST_USER] = $obj->getTasToLastUser(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_SEND_LAST_EMAIL)) + $columns[TaskPeer::TAS_SEND_LAST_EMAIL] = $obj->getTasSendLastEmail(); + + if ($obj->isNew() || $obj->isColumnModified(TaskPeer::TAS_DERIVATION)) + $columns[TaskPeer::TAS_DERIVATION] = $obj->getTasDerivation(); + + } + + return BasePeer::doValidate(TaskPeer::DATABASE_NAME, TaskPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Task + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(TaskPeer::DATABASE_NAME); + + $criteria->add(TaskPeer::TAS_UID, $pk); + + + $v = TaskPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(TaskPeer::TAS_UID, $pks, Criteria::IN); + $objs = TaskPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseTaskPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseTaskPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/TaskMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.TaskMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseTaskUser.php b/workflow/engine/classes/model/om/BaseTaskUser.php new file mode 100644 index 000000000..387aa7172 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTaskUser.php @@ -0,0 +1,685 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/TaskUserPeer.php'; + +/** + * Base class that represents a row from the 'TASK_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTaskUser extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var TaskUserPeer + */ + protected static $peer; + + + /** + * The value for the tas_uid field. + * @var string + */ + protected $tas_uid = ''; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the tu_type field. + * @var int + */ + protected $tu_type = 1; + + + /** + * The value for the tu_relation field. + * @var int + */ + protected $tu_relation = 0; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [tas_uid] column value. + * + * @return string + */ + public function getTasUid() + { + + return $this->tas_uid; + } + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [tu_type] column value. + * + * @return int + */ + public function getTuType() + { + + return $this->tu_type; + } + + /** + * Get the [tu_relation] column value. + * + * @return int + */ + public function getTuRelation() + { + + return $this->tu_relation; + } + + /** + * Set the value of [tas_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTasUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tas_uid !== $v || $v === '') { + $this->tas_uid = $v; + $this->modifiedColumns[] = TaskUserPeer::TAS_UID; + } + + } // setTasUid() + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = TaskUserPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [tu_type] column. + * + * @param int $v new value + * @return void + */ + public function setTuType($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->tu_type !== $v || $v === 1) { + $this->tu_type = $v; + $this->modifiedColumns[] = TaskUserPeer::TU_TYPE; + } + + } // setTuType() + + /** + * Set the value of [tu_relation] column. + * + * @param int $v new value + * @return void + */ + public function setTuRelation($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->tu_relation !== $v || $v === 0) { + $this->tu_relation = $v; + $this->modifiedColumns[] = TaskUserPeer::TU_RELATION; + } + + } // setTuRelation() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->tas_uid = $rs->getString($startcol + 0); + + $this->usr_uid = $rs->getString($startcol + 1); + + $this->tu_type = $rs->getInt($startcol + 2); + + $this->tu_relation = $rs->getInt($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = TaskUserPeer::NUM_COLUMNS - TaskUserPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating TaskUser object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + TaskUserPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = TaskUserPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += TaskUserPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = TaskUserPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TaskUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getTasUid(); + break; + case 1: + return $this->getUsrUid(); + break; + case 2: + return $this->getTuType(); + break; + case 3: + return $this->getTuRelation(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TaskUserPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getTasUid(), + $keys[1] => $this->getUsrUid(), + $keys[2] => $this->getTuType(), + $keys[3] => $this->getTuRelation(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TaskUserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setTasUid($value); + break; + case 1: + $this->setUsrUid($value); + break; + case 2: + $this->setTuType($value); + break; + case 3: + $this->setTuRelation($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TaskUserPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setTasUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setUsrUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTuType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTuRelation($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TaskUserPeer::DATABASE_NAME); + + if ($this->isColumnModified(TaskUserPeer::TAS_UID)) $criteria->add(TaskUserPeer::TAS_UID, $this->tas_uid); + if ($this->isColumnModified(TaskUserPeer::USR_UID)) $criteria->add(TaskUserPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(TaskUserPeer::TU_TYPE)) $criteria->add(TaskUserPeer::TU_TYPE, $this->tu_type); + if ($this->isColumnModified(TaskUserPeer::TU_RELATION)) $criteria->add(TaskUserPeer::TU_RELATION, $this->tu_relation); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TaskUserPeer::DATABASE_NAME); + + $criteria->add(TaskUserPeer::TAS_UID, $this->tas_uid); + $criteria->add(TaskUserPeer::USR_UID, $this->usr_uid); + $criteria->add(TaskUserPeer::TU_TYPE, $this->tu_type); + $criteria->add(TaskUserPeer::TU_RELATION, $this->tu_relation); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getTasUid(); + + $pks[1] = $this->getUsrUid(); + + $pks[2] = $this->getTuType(); + + $pks[3] = $this->getTuRelation(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setTasUid($keys[0]); + + $this->setUsrUid($keys[1]); + + $this->setTuType($keys[2]); + + $this->setTuRelation($keys[3]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of TaskUser (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + + $copyObj->setNew(true); + + $copyObj->setTasUid(''); // this is a pkey column, so set to default value + + $copyObj->setUsrUid(''); // this is a pkey column, so set to default value + + $copyObj->setTuType('1'); // this is a pkey column, so set to default value + + $copyObj->setTuRelation('0'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return TaskUser Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return TaskUserPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new TaskUserPeer(); + } + return self::$peer; + } + +} // BaseTaskUser diff --git a/workflow/engine/classes/model/om/BaseTaskUserPeer.php b/workflow/engine/classes/model/om/BaseTaskUserPeer.php new file mode 100644 index 000000000..a4e6dc954 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTaskUserPeer.php @@ -0,0 +1,597 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by TaskUserPeer::getOMClass() +include_once 'classes/model/TaskUser.php'; + +/** + * Base static class for performing query and update operations on the 'TASK_USER' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTaskUserPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'TASK_USER'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.TaskUser'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the TAS_UID field */ + const TAS_UID = 'TASK_USER.TAS_UID'; + + /** the column name for the USR_UID field */ + const USR_UID = 'TASK_USER.USR_UID'; + + /** the column name for the TU_TYPE field */ + const TU_TYPE = 'TASK_USER.TU_TYPE'; + + /** the column name for the TU_RELATION field */ + const TU_RELATION = 'TASK_USER.TU_RELATION'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('TasUid', 'UsrUid', 'TuType', 'TuRelation', ), + BasePeer::TYPE_COLNAME => array (TaskUserPeer::TAS_UID, TaskUserPeer::USR_UID, TaskUserPeer::TU_TYPE, TaskUserPeer::TU_RELATION, ), + BasePeer::TYPE_FIELDNAME => array ('TAS_UID', 'USR_UID', 'TU_TYPE', 'TU_RELATION', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('TasUid' => 0, 'UsrUid' => 1, 'TuType' => 2, 'TuRelation' => 3, ), + BasePeer::TYPE_COLNAME => array (TaskUserPeer::TAS_UID => 0, TaskUserPeer::USR_UID => 1, TaskUserPeer::TU_TYPE => 2, TaskUserPeer::TU_RELATION => 3, ), + BasePeer::TYPE_FIELDNAME => array ('TAS_UID' => 0, 'USR_UID' => 1, 'TU_TYPE' => 2, 'TU_RELATION' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/TaskUserMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.TaskUserMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = TaskUserPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. TaskUserPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(TaskUserPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(TaskUserPeer::TAS_UID); + + $criteria->addSelectColumn(TaskUserPeer::USR_UID); + + $criteria->addSelectColumn(TaskUserPeer::TU_TYPE); + + $criteria->addSelectColumn(TaskUserPeer::TU_RELATION); + + } + + const COUNT = 'COUNT(TASK_USER.TAS_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT TASK_USER.TAS_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(TaskUserPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(TaskUserPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = TaskUserPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return TaskUser + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = TaskUserPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return TaskUserPeer::populateObjects(TaskUserPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + TaskUserPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = TaskUserPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return TaskUserPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a TaskUser or Criteria object. + * + * @param mixed $values Criteria or TaskUser object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from TaskUser object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a TaskUser or Criteria object. + * + * @param mixed $values Criteria or TaskUser object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(TaskUserPeer::TAS_UID); + $selectCriteria->add(TaskUserPeer::TAS_UID, $criteria->remove(TaskUserPeer::TAS_UID), $comparison); + + $comparison = $criteria->getComparison(TaskUserPeer::USR_UID); + $selectCriteria->add(TaskUserPeer::USR_UID, $criteria->remove(TaskUserPeer::USR_UID), $comparison); + + $comparison = $criteria->getComparison(TaskUserPeer::TU_TYPE); + $selectCriteria->add(TaskUserPeer::TU_TYPE, $criteria->remove(TaskUserPeer::TU_TYPE), $comparison); + + $comparison = $criteria->getComparison(TaskUserPeer::TU_RELATION); + $selectCriteria->add(TaskUserPeer::TU_RELATION, $criteria->remove(TaskUserPeer::TU_RELATION), $comparison); + + } else { // $values is TaskUser object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the TASK_USER table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(TaskUserPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a TaskUser or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or TaskUser object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(TaskUserPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof TaskUser) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + $vals[3][] = $value[3]; + } + + $criteria->add(TaskUserPeer::TAS_UID, $vals[0], Criteria::IN); + $criteria->add(TaskUserPeer::USR_UID, $vals[1], Criteria::IN); + $criteria->add(TaskUserPeer::TU_TYPE, $vals[2], Criteria::IN); + $criteria->add(TaskUserPeer::TU_RELATION, $vals[3], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given TaskUser object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param TaskUser $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(TaskUser $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(TaskUserPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(TaskUserPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(TaskUserPeer::TAS_UID)) + $columns[TaskUserPeer::TAS_UID] = $obj->getTasUid(); + + if ($obj->isNew() || $obj->isColumnModified(TaskUserPeer::USR_UID)) + $columns[TaskUserPeer::USR_UID] = $obj->getUsrUid(); + + if ($obj->isNew() || $obj->isColumnModified(TaskUserPeer::TU_TYPE)) + $columns[TaskUserPeer::TU_TYPE] = $obj->getTuType(); + + if ($obj->isNew() || $obj->isColumnModified(TaskUserPeer::TU_RELATION)) + $columns[TaskUserPeer::TU_RELATION] = $obj->getTuRelation(); + + } + + return BasePeer::doValidate(TaskUserPeer::DATABASE_NAME, TaskUserPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $tas_uid + @param string $usr_uid + @param int $tu_type + @param int $tu_relation + + * @param Connection $con + * @return TaskUser + */ + public static function retrieveByPK( $tas_uid, $usr_uid, $tu_type, $tu_relation, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(TaskUserPeer::TAS_UID, $tas_uid); + $criteria->add(TaskUserPeer::USR_UID, $usr_uid); + $criteria->add(TaskUserPeer::TU_TYPE, $tu_type); + $criteria->add(TaskUserPeer::TU_RELATION, $tu_relation); + $v = TaskUserPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseTaskUserPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseTaskUserPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/TaskUserMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.TaskUserMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseTranslation.php b/workflow/engine/classes/model/om/BaseTranslation.php new file mode 100644 index 000000000..a2ac59625 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTranslation.php @@ -0,0 +1,680 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/TranslationPeer.php'; + +/** + * Base class that represents a row from the 'TRANSLATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTranslation extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var TranslationPeer + */ + protected static $peer; + + + /** + * The value for the trn_category field. + * @var string + */ + protected $trn_category = ''; + + + /** + * The value for the trn_id field. + * @var string + */ + protected $trn_id = ''; + + + /** + * The value for the trn_lang field. + * @var string + */ + protected $trn_lang = 'en'; + + + /** + * The value for the trn_value field. + * @var string + */ + protected $trn_value = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [trn_category] column value. + * + * @return string + */ + public function getTrnCategory() + { + + return $this->trn_category; + } + + /** + * Get the [trn_id] column value. + * + * @return string + */ + public function getTrnId() + { + + return $this->trn_id; + } + + /** + * Get the [trn_lang] column value. + * + * @return string + */ + public function getTrnLang() + { + + return $this->trn_lang; + } + + /** + * Get the [trn_value] column value. + * + * @return string + */ + public function getTrnValue() + { + + return $this->trn_value; + } + + /** + * Set the value of [trn_category] column. + * + * @param string $v new value + * @return void + */ + public function setTrnCategory($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->trn_category !== $v || $v === '') { + $this->trn_category = $v; + $this->modifiedColumns[] = TranslationPeer::TRN_CATEGORY; + } + + } // setTrnCategory() + + /** + * Set the value of [trn_id] column. + * + * @param string $v new value + * @return void + */ + public function setTrnId($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->trn_id !== $v || $v === '') { + $this->trn_id = $v; + $this->modifiedColumns[] = TranslationPeer::TRN_ID; + } + + } // setTrnId() + + /** + * Set the value of [trn_lang] column. + * + * @param string $v new value + * @return void + */ + public function setTrnLang($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->trn_lang !== $v || $v === 'en') { + $this->trn_lang = $v; + $this->modifiedColumns[] = TranslationPeer::TRN_LANG; + } + + } // setTrnLang() + + /** + * Set the value of [trn_value] column. + * + * @param string $v new value + * @return void + */ + public function setTrnValue($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->trn_value !== $v || $v === '') { + $this->trn_value = $v; + $this->modifiedColumns[] = TranslationPeer::TRN_VALUE; + } + + } // setTrnValue() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->trn_category = $rs->getString($startcol + 0); + + $this->trn_id = $rs->getString($startcol + 1); + + $this->trn_lang = $rs->getString($startcol + 2); + + $this->trn_value = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = TranslationPeer::NUM_COLUMNS - TranslationPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Translation object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TranslationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + TranslationPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TranslationPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = TranslationPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += TranslationPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = TranslationPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TranslationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getTrnCategory(); + break; + case 1: + return $this->getTrnId(); + break; + case 2: + return $this->getTrnLang(); + break; + case 3: + return $this->getTrnValue(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TranslationPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getTrnCategory(), + $keys[1] => $this->getTrnId(), + $keys[2] => $this->getTrnLang(), + $keys[3] => $this->getTrnValue(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TranslationPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setTrnCategory($value); + break; + case 1: + $this->setTrnId($value); + break; + case 2: + $this->setTrnLang($value); + break; + case 3: + $this->setTrnValue($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TranslationPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setTrnCategory($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setTrnId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTrnLang($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTrnValue($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TranslationPeer::DATABASE_NAME); + + if ($this->isColumnModified(TranslationPeer::TRN_CATEGORY)) $criteria->add(TranslationPeer::TRN_CATEGORY, $this->trn_category); + if ($this->isColumnModified(TranslationPeer::TRN_ID)) $criteria->add(TranslationPeer::TRN_ID, $this->trn_id); + if ($this->isColumnModified(TranslationPeer::TRN_LANG)) $criteria->add(TranslationPeer::TRN_LANG, $this->trn_lang); + if ($this->isColumnModified(TranslationPeer::TRN_VALUE)) $criteria->add(TranslationPeer::TRN_VALUE, $this->trn_value); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TranslationPeer::DATABASE_NAME); + + $criteria->add(TranslationPeer::TRN_CATEGORY, $this->trn_category); + $criteria->add(TranslationPeer::TRN_ID, $this->trn_id); + $criteria->add(TranslationPeer::TRN_LANG, $this->trn_lang); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + + $pks[0] = $this->getTrnCategory(); + + $pks[1] = $this->getTrnId(); + + $pks[2] = $this->getTrnLang(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + + $this->setTrnCategory($keys[0]); + + $this->setTrnId($keys[1]); + + $this->setTrnLang($keys[2]); + + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Translation (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setTrnValue($this->trn_value); + + + $copyObj->setNew(true); + + $copyObj->setTrnCategory(''); // this is a pkey column, so set to default value + + $copyObj->setTrnId(''); // this is a pkey column, so set to default value + + $copyObj->setTrnLang('en'); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Translation Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return TranslationPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new TranslationPeer(); + } + return self::$peer; + } + +} // BaseTranslation diff --git a/workflow/engine/classes/model/om/BaseTranslationPeer.php b/workflow/engine/classes/model/om/BaseTranslationPeer.php new file mode 100644 index 000000000..1b68a99b1 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTranslationPeer.php @@ -0,0 +1,590 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by TranslationPeer::getOMClass() +include_once 'classes/model/Translation.php'; + +/** + * Base static class for performing query and update operations on the 'TRANSLATION' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTranslationPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'TRANSLATION'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Translation'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the TRN_CATEGORY field */ + const TRN_CATEGORY = 'TRANSLATION.TRN_CATEGORY'; + + /** the column name for the TRN_ID field */ + const TRN_ID = 'TRANSLATION.TRN_ID'; + + /** the column name for the TRN_LANG field */ + const TRN_LANG = 'TRANSLATION.TRN_LANG'; + + /** the column name for the TRN_VALUE field */ + const TRN_VALUE = 'TRANSLATION.TRN_VALUE'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('TrnCategory', 'TrnId', 'TrnLang', 'TrnValue', ), + BasePeer::TYPE_COLNAME => array (TranslationPeer::TRN_CATEGORY, TranslationPeer::TRN_ID, TranslationPeer::TRN_LANG, TranslationPeer::TRN_VALUE, ), + BasePeer::TYPE_FIELDNAME => array ('TRN_CATEGORY', 'TRN_ID', 'TRN_LANG', 'TRN_VALUE', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('TrnCategory' => 0, 'TrnId' => 1, 'TrnLang' => 2, 'TrnValue' => 3, ), + BasePeer::TYPE_COLNAME => array (TranslationPeer::TRN_CATEGORY => 0, TranslationPeer::TRN_ID => 1, TranslationPeer::TRN_LANG => 2, TranslationPeer::TRN_VALUE => 3, ), + BasePeer::TYPE_FIELDNAME => array ('TRN_CATEGORY' => 0, 'TRN_ID' => 1, 'TRN_LANG' => 2, 'TRN_VALUE' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/TranslationMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.TranslationMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = TranslationPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. TranslationPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(TranslationPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(TranslationPeer::TRN_CATEGORY); + + $criteria->addSelectColumn(TranslationPeer::TRN_ID); + + $criteria->addSelectColumn(TranslationPeer::TRN_LANG); + + $criteria->addSelectColumn(TranslationPeer::TRN_VALUE); + + } + + const COUNT = 'COUNT(TRANSLATION.TRN_CATEGORY)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT TRANSLATION.TRN_CATEGORY)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(TranslationPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(TranslationPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = TranslationPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Translation + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = TranslationPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return TranslationPeer::populateObjects(TranslationPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + TranslationPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = TranslationPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return TranslationPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Translation or Criteria object. + * + * @param mixed $values Criteria or Translation object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Translation object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Translation or Criteria object. + * + * @param mixed $values Criteria or Translation object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(TranslationPeer::TRN_CATEGORY); + $selectCriteria->add(TranslationPeer::TRN_CATEGORY, $criteria->remove(TranslationPeer::TRN_CATEGORY), $comparison); + + $comparison = $criteria->getComparison(TranslationPeer::TRN_ID); + $selectCriteria->add(TranslationPeer::TRN_ID, $criteria->remove(TranslationPeer::TRN_ID), $comparison); + + $comparison = $criteria->getComparison(TranslationPeer::TRN_LANG); + $selectCriteria->add(TranslationPeer::TRN_LANG, $criteria->remove(TranslationPeer::TRN_LANG), $comparison); + + } else { // $values is Translation object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the TRANSLATION table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(TranslationPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Translation or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Translation object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(TranslationPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Translation) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey + // values + if(count($values) == count($values, COUNT_RECURSIVE)) + { + // array is not multi-dimensional + $values = array($values); + } + $vals = array(); + foreach($values as $value) + { + + $vals[0][] = $value[0]; + $vals[1][] = $value[1]; + $vals[2][] = $value[2]; + } + + $criteria->add(TranslationPeer::TRN_CATEGORY, $vals[0], Criteria::IN); + $criteria->add(TranslationPeer::TRN_ID, $vals[1], Criteria::IN); + $criteria->add(TranslationPeer::TRN_LANG, $vals[2], Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Translation object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Translation $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Translation $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(TranslationPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(TranslationPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(TranslationPeer::TRN_CATEGORY)) + $columns[TranslationPeer::TRN_CATEGORY] = $obj->getTrnCategory(); + + if ($obj->isNew() || $obj->isColumnModified(TranslationPeer::TRN_ID)) + $columns[TranslationPeer::TRN_ID] = $obj->getTrnId(); + + if ($obj->isNew() || $obj->isColumnModified(TranslationPeer::TRN_LANG)) + $columns[TranslationPeer::TRN_LANG] = $obj->getTrnLang(); + + if ($obj->isNew() || $obj->isColumnModified(TranslationPeer::TRN_VALUE)) + $columns[TranslationPeer::TRN_VALUE] = $obj->getTrnValue(); + + } + + return BasePeer::doValidate(TranslationPeer::DATABASE_NAME, TranslationPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve object using using composite pkey values. + * @param string $trn_category + @param string $trn_id + @param string $trn_lang + + * @param Connection $con + * @return Translation + */ + public static function retrieveByPK( $trn_category, $trn_id, $trn_lang, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + $criteria->add(TranslationPeer::TRN_CATEGORY, $trn_category); + $criteria->add(TranslationPeer::TRN_ID, $trn_id); + $criteria->add(TranslationPeer::TRN_LANG, $trn_lang); + $v = TranslationPeer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } +} // BaseTranslationPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseTranslationPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/TranslationMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.TranslationMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseTriggers.php b/workflow/engine/classes/model/om/BaseTriggers.php new file mode 100644 index 000000000..3ffce39d0 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTriggers.php @@ -0,0 +1,716 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/TriggersPeer.php'; + +/** + * Base class that represents a row from the 'TRIGGERS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTriggers extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var TriggersPeer + */ + protected static $peer; + + + /** + * The value for the tri_uid field. + * @var string + */ + protected $tri_uid = ''; + + + /** + * The value for the pro_uid field. + * @var string + */ + protected $pro_uid = ''; + + + /** + * The value for the tri_type field. + * @var string + */ + protected $tri_type = 'SCRIPT'; + + + /** + * The value for the tri_webbot field. + * @var string + */ + protected $tri_webbot; + + + /** + * The value for the tri_param field. + * @var string + */ + protected $tri_param; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [tri_uid] column value. + * + * @return string + */ + public function getTriUid() + { + + return $this->tri_uid; + } + + /** + * Get the [pro_uid] column value. + * + * @return string + */ + public function getProUid() + { + + return $this->pro_uid; + } + + /** + * Get the [tri_type] column value. + * + * @return string + */ + public function getTriType() + { + + return $this->tri_type; + } + + /** + * Get the [tri_webbot] column value. + * + * @return string + */ + public function getTriWebbot() + { + + return $this->tri_webbot; + } + + /** + * Get the [tri_param] column value. + * + * @return string + */ + public function getTriParam() + { + + return $this->tri_param; + } + + /** + * Set the value of [tri_uid] column. + * + * @param string $v new value + * @return void + */ + public function setTriUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_uid !== $v || $v === '') { + $this->tri_uid = $v; + $this->modifiedColumns[] = TriggersPeer::TRI_UID; + } + + } // setTriUid() + + /** + * Set the value of [pro_uid] column. + * + * @param string $v new value + * @return void + */ + public function setProUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->pro_uid !== $v || $v === '') { + $this->pro_uid = $v; + $this->modifiedColumns[] = TriggersPeer::PRO_UID; + } + + } // setProUid() + + /** + * Set the value of [tri_type] column. + * + * @param string $v new value + * @return void + */ + public function setTriType($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_type !== $v || $v === 'SCRIPT') { + $this->tri_type = $v; + $this->modifiedColumns[] = TriggersPeer::TRI_TYPE; + } + + } // setTriType() + + /** + * Set the value of [tri_webbot] column. + * + * @param string $v new value + * @return void + */ + public function setTriWebbot($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_webbot !== $v) { + $this->tri_webbot = $v; + $this->modifiedColumns[] = TriggersPeer::TRI_WEBBOT; + } + + } // setTriWebbot() + + /** + * Set the value of [tri_param] column. + * + * @param string $v new value + * @return void + */ + public function setTriParam($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->tri_param !== $v) { + $this->tri_param = $v; + $this->modifiedColumns[] = TriggersPeer::TRI_PARAM; + } + + } // setTriParam() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->tri_uid = $rs->getString($startcol + 0); + + $this->pro_uid = $rs->getString($startcol + 1); + + $this->tri_type = $rs->getString($startcol + 2); + + $this->tri_webbot = $rs->getString($startcol + 3); + + $this->tri_param = $rs->getString($startcol + 4); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 5; // 5 = TriggersPeer::NUM_COLUMNS - TriggersPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Triggers object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + } + + try { + $con->begin(); + TriggersPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = TriggersPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += TriggersPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = TriggersPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TriggersPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getTriUid(); + break; + case 1: + return $this->getProUid(); + break; + case 2: + return $this->getTriType(); + break; + case 3: + return $this->getTriWebbot(); + break; + case 4: + return $this->getTriParam(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TriggersPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getTriUid(), + $keys[1] => $this->getProUid(), + $keys[2] => $this->getTriType(), + $keys[3] => $this->getTriWebbot(), + $keys[4] => $this->getTriParam(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = TriggersPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setTriUid($value); + break; + case 1: + $this->setProUid($value); + break; + case 2: + $this->setTriType($value); + break; + case 3: + $this->setTriWebbot($value); + break; + case 4: + $this->setTriParam($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = TriggersPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setTriUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProUid($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTriType($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setTriWebbot($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTriParam($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TriggersPeer::DATABASE_NAME); + + if ($this->isColumnModified(TriggersPeer::TRI_UID)) $criteria->add(TriggersPeer::TRI_UID, $this->tri_uid); + if ($this->isColumnModified(TriggersPeer::PRO_UID)) $criteria->add(TriggersPeer::PRO_UID, $this->pro_uid); + if ($this->isColumnModified(TriggersPeer::TRI_TYPE)) $criteria->add(TriggersPeer::TRI_TYPE, $this->tri_type); + if ($this->isColumnModified(TriggersPeer::TRI_WEBBOT)) $criteria->add(TriggersPeer::TRI_WEBBOT, $this->tri_webbot); + if ($this->isColumnModified(TriggersPeer::TRI_PARAM)) $criteria->add(TriggersPeer::TRI_PARAM, $this->tri_param); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TriggersPeer::DATABASE_NAME); + + $criteria->add(TriggersPeer::TRI_UID, $this->tri_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getTriUid(); + } + + /** + * Generic method to set the primary key (tri_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setTriUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Triggers (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setProUid($this->pro_uid); + + $copyObj->setTriType($this->tri_type); + + $copyObj->setTriWebbot($this->tri_webbot); + + $copyObj->setTriParam($this->tri_param); + + + $copyObj->setNew(true); + + $copyObj->setTriUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Triggers Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return TriggersPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new TriggersPeer(); + } + return self::$peer; + } + +} // BaseTriggers diff --git a/workflow/engine/classes/model/om/BaseTriggersPeer.php b/workflow/engine/classes/model/om/BaseTriggersPeer.php new file mode 100644 index 000000000..2b67e3462 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseTriggersPeer.php @@ -0,0 +1,588 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by TriggersPeer::getOMClass() +include_once 'classes/model/Triggers.php'; + +/** + * Base static class for performing query and update operations on the 'TRIGGERS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseTriggersPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'TRIGGERS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Triggers'; + + /** The total number of columns. */ + const NUM_COLUMNS = 5; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the TRI_UID field */ + const TRI_UID = 'TRIGGERS.TRI_UID'; + + /** the column name for the PRO_UID field */ + const PRO_UID = 'TRIGGERS.PRO_UID'; + + /** the column name for the TRI_TYPE field */ + const TRI_TYPE = 'TRIGGERS.TRI_TYPE'; + + /** the column name for the TRI_WEBBOT field */ + const TRI_WEBBOT = 'TRIGGERS.TRI_WEBBOT'; + + /** the column name for the TRI_PARAM field */ + const TRI_PARAM = 'TRIGGERS.TRI_PARAM'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('TriUid', 'ProUid', 'TriType', 'TriWebbot', 'TriParam', ), + BasePeer::TYPE_COLNAME => array (TriggersPeer::TRI_UID, TriggersPeer::PRO_UID, TriggersPeer::TRI_TYPE, TriggersPeer::TRI_WEBBOT, TriggersPeer::TRI_PARAM, ), + BasePeer::TYPE_FIELDNAME => array ('TRI_UID', 'PRO_UID', 'TRI_TYPE', 'TRI_WEBBOT', 'TRI_PARAM', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('TriUid' => 0, 'ProUid' => 1, 'TriType' => 2, 'TriWebbot' => 3, 'TriParam' => 4, ), + BasePeer::TYPE_COLNAME => array (TriggersPeer::TRI_UID => 0, TriggersPeer::PRO_UID => 1, TriggersPeer::TRI_TYPE => 2, TriggersPeer::TRI_WEBBOT => 3, TriggersPeer::TRI_PARAM => 4, ), + BasePeer::TYPE_FIELDNAME => array ('TRI_UID' => 0, 'PRO_UID' => 1, 'TRI_TYPE' => 2, 'TRI_WEBBOT' => 3, 'TRI_PARAM' => 4, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/TriggersMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.TriggersMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = TriggersPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. TriggersPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(TriggersPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(TriggersPeer::TRI_UID); + + $criteria->addSelectColumn(TriggersPeer::PRO_UID); + + $criteria->addSelectColumn(TriggersPeer::TRI_TYPE); + + $criteria->addSelectColumn(TriggersPeer::TRI_WEBBOT); + + $criteria->addSelectColumn(TriggersPeer::TRI_PARAM); + + } + + const COUNT = 'COUNT(TRIGGERS.TRI_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT TRIGGERS.TRI_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(TriggersPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(TriggersPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = TriggersPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Triggers + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = TriggersPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return TriggersPeer::populateObjects(TriggersPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + TriggersPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = TriggersPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return TriggersPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Triggers or Criteria object. + * + * @param mixed $values Criteria or Triggers object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Triggers object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Triggers or Criteria object. + * + * @param mixed $values Criteria or Triggers object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(TriggersPeer::TRI_UID); + $selectCriteria->add(TriggersPeer::TRI_UID, $criteria->remove(TriggersPeer::TRI_UID), $comparison); + + } else { // $values is Triggers object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the TRIGGERS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(TriggersPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Triggers or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Triggers object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(TriggersPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Triggers) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(TriggersPeer::TRI_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Triggers object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Triggers $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Triggers $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(TriggersPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(TriggersPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(TriggersPeer::TRI_TYPE)) + $columns[TriggersPeer::TRI_TYPE] = $obj->getTriType(); + + } + + return BasePeer::doValidate(TriggersPeer::DATABASE_NAME, TriggersPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Triggers + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(TriggersPeer::DATABASE_NAME); + + $criteria->add(TriggersPeer::TRI_UID, $pk); + + + $v = TriggersPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(TriggersPeer::TRI_UID, $pks, Criteria::IN); + $objs = TriggersPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseTriggersPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseTriggersPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/TriggersMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.TriggersMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseUsers.php b/workflow/engine/classes/model/om/BaseUsers.php new file mode 100644 index 000000000..f000af237 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseUsers.php @@ -0,0 +1,1864 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/UsersPeer.php'; + +/** + * Base class that represents a row from the 'USERS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseUsers extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var UsersPeer + */ + protected static $peer; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the usr_username field. + * @var string + */ + protected $usr_username = ''; + + + /** + * The value for the usr_password field. + * @var string + */ + protected $usr_password = ''; + + + /** + * The value for the usr_firstname field. + * @var string + */ + protected $usr_firstname = ''; + + + /** + * The value for the usr_lastname field. + * @var string + */ + protected $usr_lastname = ''; + + + /** + * The value for the usr_email field. + * @var string + */ + protected $usr_email = ''; + + + /** + * The value for the usr_due_date field. + * @var int + */ + protected $usr_due_date; + + + /** + * The value for the usr_create_date field. + * @var int + */ + protected $usr_create_date; + + + /** + * The value for the usr_update_date field. + * @var int + */ + protected $usr_update_date; + + + /** + * The value for the usr_status field. + * @var string + */ + protected $usr_status = 'ACTIVE'; + + + /** + * The value for the usr_country field. + * @var string + */ + protected $usr_country = ''; + + + /** + * The value for the usr_city field. + * @var string + */ + protected $usr_city = ''; + + + /** + * The value for the usr_location field. + * @var string + */ + protected $usr_location = ''; + + + /** + * The value for the usr_address field. + * @var string + */ + protected $usr_address = ''; + + + /** + * The value for the usr_phone field. + * @var string + */ + protected $usr_phone = ''; + + + /** + * The value for the usr_fax field. + * @var string + */ + protected $usr_fax = ''; + + + /** + * The value for the usr_cellular field. + * @var string + */ + protected $usr_cellular = ''; + + + /** + * The value for the usr_zip_code field. + * @var string + */ + protected $usr_zip_code = ''; + + + /** + * The value for the dep_uid field. + * @var string + */ + protected $dep_uid = ''; + + + /** + * The value for the usr_position field. + * @var string + */ + protected $usr_position = ''; + + + /** + * The value for the usr_resume field. + * @var string + */ + protected $usr_resume = ''; + + + /** + * The value for the usr_birthday field. + * @var int + */ + protected $usr_birthday; + + + /** + * The value for the usr_role field. + * @var string + */ + protected $usr_role = 'PROCESSMAKER_ADMIN'; + + + /** + * The value for the usr_reports_to field. + * @var string + */ + protected $usr_reports_to = ''; + + + /** + * The value for the usr_replaced_by field. + * @var string + */ + protected $usr_replaced_by = ''; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [usr_username] column value. + * + * @return string + */ + public function getUsrUsername() + { + + return $this->usr_username; + } + + /** + * Get the [usr_password] column value. + * + * @return string + */ + public function getUsrPassword() + { + + return $this->usr_password; + } + + /** + * Get the [usr_firstname] column value. + * + * @return string + */ + public function getUsrFirstname() + { + + return $this->usr_firstname; + } + + /** + * Get the [usr_lastname] column value. + * + * @return string + */ + public function getUsrLastname() + { + + return $this->usr_lastname; + } + + /** + * Get the [usr_email] column value. + * + * @return string + */ + public function getUsrEmail() + { + + return $this->usr_email; + } + + /** + * Get the [optionally formatted] [usr_due_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getUsrDueDate($format = 'Y-m-d') + { + + if ($this->usr_due_date === null || $this->usr_due_date === '') { + return null; + } elseif (!is_int($this->usr_due_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->usr_due_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [usr_due_date] as date/time value: " . var_export($this->usr_due_date, true)); + } + } else { + $ts = $this->usr_due_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [usr_create_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getUsrCreateDate($format = 'Y-m-d H:i:s') + { + + if ($this->usr_create_date === null || $this->usr_create_date === '') { + return null; + } elseif (!is_int($this->usr_create_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->usr_create_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [usr_create_date] as date/time value: " . var_export($this->usr_create_date, true)); + } + } else { + $ts = $this->usr_create_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [optionally formatted] [usr_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getUsrUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->usr_update_date === null || $this->usr_update_date === '') { + return null; + } elseif (!is_int($this->usr_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->usr_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [usr_update_date] as date/time value: " . var_export($this->usr_update_date, true)); + } + } else { + $ts = $this->usr_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [usr_status] column value. + * + * @return string + */ + public function getUsrStatus() + { + + return $this->usr_status; + } + + /** + * Get the [usr_country] column value. + * + * @return string + */ + public function getUsrCountry() + { + + return $this->usr_country; + } + + /** + * Get the [usr_city] column value. + * + * @return string + */ + public function getUsrCity() + { + + return $this->usr_city; + } + + /** + * Get the [usr_location] column value. + * + * @return string + */ + public function getUsrLocation() + { + + return $this->usr_location; + } + + /** + * Get the [usr_address] column value. + * + * @return string + */ + public function getUsrAddress() + { + + return $this->usr_address; + } + + /** + * Get the [usr_phone] column value. + * + * @return string + */ + public function getUsrPhone() + { + + return $this->usr_phone; + } + + /** + * Get the [usr_fax] column value. + * + * @return string + */ + public function getUsrFax() + { + + return $this->usr_fax; + } + + /** + * Get the [usr_cellular] column value. + * + * @return string + */ + public function getUsrCellular() + { + + return $this->usr_cellular; + } + + /** + * Get the [usr_zip_code] column value. + * + * @return string + */ + public function getUsrZipCode() + { + + return $this->usr_zip_code; + } + + /** + * Get the [dep_uid] column value. + * + * @return string + */ + public function getDepUid() + { + + return $this->dep_uid; + } + + /** + * Get the [usr_position] column value. + * + * @return string + */ + public function getUsrPosition() + { + + return $this->usr_position; + } + + /** + * Get the [usr_resume] column value. + * + * @return string + */ + public function getUsrResume() + { + + return $this->usr_resume; + } + + /** + * Get the [optionally formatted] [usr_birthday] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getUsrBirthday($format = 'Y-m-d') + { + + if ($this->usr_birthday === null || $this->usr_birthday === '') { + return null; + } elseif (!is_int($this->usr_birthday)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->usr_birthday); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [usr_birthday] as date/time value: " . var_export($this->usr_birthday, true)); + } + } else { + $ts = $this->usr_birthday; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [usr_role] column value. + * + * @return string + */ + public function getUsrRole() + { + + return $this->usr_role; + } + + /** + * Get the [usr_reports_to] column value. + * + * @return string + */ + public function getUsrReportsTo() + { + + return $this->usr_reports_to; + } + + /** + * Get the [usr_replaced_by] column value. + * + * @return string + */ + public function getUsrReplacedBy() + { + + return $this->usr_replaced_by; + } + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = UsersPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [usr_username] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUsername($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_username !== $v || $v === '') { + $this->usr_username = $v; + $this->modifiedColumns[] = UsersPeer::USR_USERNAME; + } + + } // setUsrUsername() + + /** + * Set the value of [usr_password] column. + * + * @param string $v new value + * @return void + */ + public function setUsrPassword($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_password !== $v || $v === '') { + $this->usr_password = $v; + $this->modifiedColumns[] = UsersPeer::USR_PASSWORD; + } + + } // setUsrPassword() + + /** + * Set the value of [usr_firstname] column. + * + * @param string $v new value + * @return void + */ + public function setUsrFirstname($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_firstname !== $v || $v === '') { + $this->usr_firstname = $v; + $this->modifiedColumns[] = UsersPeer::USR_FIRSTNAME; + } + + } // setUsrFirstname() + + /** + * Set the value of [usr_lastname] column. + * + * @param string $v new value + * @return void + */ + public function setUsrLastname($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_lastname !== $v || $v === '') { + $this->usr_lastname = $v; + $this->modifiedColumns[] = UsersPeer::USR_LASTNAME; + } + + } // setUsrLastname() + + /** + * Set the value of [usr_email] column. + * + * @param string $v new value + * @return void + */ + public function setUsrEmail($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_email !== $v || $v === '') { + $this->usr_email = $v; + $this->modifiedColumns[] = UsersPeer::USR_EMAIL; + } + + } // setUsrEmail() + + /** + * Set the value of [usr_due_date] column. + * + * @param int $v new value + * @return void + */ + public function setUsrDueDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [usr_due_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->usr_due_date !== $ts) { + $this->usr_due_date = $ts; + $this->modifiedColumns[] = UsersPeer::USR_DUE_DATE; + } + + } // setUsrDueDate() + + /** + * Set the value of [usr_create_date] column. + * + * @param int $v new value + * @return void + */ + public function setUsrCreateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [usr_create_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->usr_create_date !== $ts) { + $this->usr_create_date = $ts; + $this->modifiedColumns[] = UsersPeer::USR_CREATE_DATE; + } + + } // setUsrCreateDate() + + /** + * Set the value of [usr_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setUsrUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [usr_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->usr_update_date !== $ts) { + $this->usr_update_date = $ts; + $this->modifiedColumns[] = UsersPeer::USR_UPDATE_DATE; + } + + } // setUsrUpdateDate() + + /** + * Set the value of [usr_status] column. + * + * @param string $v new value + * @return void + */ + public function setUsrStatus($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_status !== $v || $v === 'ACTIVE') { + $this->usr_status = $v; + $this->modifiedColumns[] = UsersPeer::USR_STATUS; + } + + } // setUsrStatus() + + /** + * Set the value of [usr_country] column. + * + * @param string $v new value + * @return void + */ + public function setUsrCountry($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_country !== $v || $v === '') { + $this->usr_country = $v; + $this->modifiedColumns[] = UsersPeer::USR_COUNTRY; + } + + } // setUsrCountry() + + /** + * Set the value of [usr_city] column. + * + * @param string $v new value + * @return void + */ + public function setUsrCity($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_city !== $v || $v === '') { + $this->usr_city = $v; + $this->modifiedColumns[] = UsersPeer::USR_CITY; + } + + } // setUsrCity() + + /** + * Set the value of [usr_location] column. + * + * @param string $v new value + * @return void + */ + public function setUsrLocation($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_location !== $v || $v === '') { + $this->usr_location = $v; + $this->modifiedColumns[] = UsersPeer::USR_LOCATION; + } + + } // setUsrLocation() + + /** + * Set the value of [usr_address] column. + * + * @param string $v new value + * @return void + */ + public function setUsrAddress($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_address !== $v || $v === '') { + $this->usr_address = $v; + $this->modifiedColumns[] = UsersPeer::USR_ADDRESS; + } + + } // setUsrAddress() + + /** + * Set the value of [usr_phone] column. + * + * @param string $v new value + * @return void + */ + public function setUsrPhone($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_phone !== $v || $v === '') { + $this->usr_phone = $v; + $this->modifiedColumns[] = UsersPeer::USR_PHONE; + } + + } // setUsrPhone() + + /** + * Set the value of [usr_fax] column. + * + * @param string $v new value + * @return void + */ + public function setUsrFax($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_fax !== $v || $v === '') { + $this->usr_fax = $v; + $this->modifiedColumns[] = UsersPeer::USR_FAX; + } + + } // setUsrFax() + + /** + * Set the value of [usr_cellular] column. + * + * @param string $v new value + * @return void + */ + public function setUsrCellular($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_cellular !== $v || $v === '') { + $this->usr_cellular = $v; + $this->modifiedColumns[] = UsersPeer::USR_CELLULAR; + } + + } // setUsrCellular() + + /** + * Set the value of [usr_zip_code] column. + * + * @param string $v new value + * @return void + */ + public function setUsrZipCode($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_zip_code !== $v || $v === '') { + $this->usr_zip_code = $v; + $this->modifiedColumns[] = UsersPeer::USR_ZIP_CODE; + } + + } // setUsrZipCode() + + /** + * Set the value of [dep_uid] column. + * + * @param string $v new value + * @return void + */ + public function setDepUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->dep_uid !== $v || $v === '') { + $this->dep_uid = $v; + $this->modifiedColumns[] = UsersPeer::DEP_UID; + } + + } // setDepUid() + + /** + * Set the value of [usr_position] column. + * + * @param string $v new value + * @return void + */ + public function setUsrPosition($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_position !== $v || $v === '') { + $this->usr_position = $v; + $this->modifiedColumns[] = UsersPeer::USR_POSITION; + } + + } // setUsrPosition() + + /** + * Set the value of [usr_resume] column. + * + * @param string $v new value + * @return void + */ + public function setUsrResume($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_resume !== $v || $v === '') { + $this->usr_resume = $v; + $this->modifiedColumns[] = UsersPeer::USR_RESUME; + } + + } // setUsrResume() + + /** + * Set the value of [usr_birthday] column. + * + * @param int $v new value + * @return void + */ + public function setUsrBirthday($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [usr_birthday] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->usr_birthday !== $ts) { + $this->usr_birthday = $ts; + $this->modifiedColumns[] = UsersPeer::USR_BIRTHDAY; + } + + } // setUsrBirthday() + + /** + * Set the value of [usr_role] column. + * + * @param string $v new value + * @return void + */ + public function setUsrRole($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_role !== $v || $v === 'PROCESSMAKER_ADMIN') { + $this->usr_role = $v; + $this->modifiedColumns[] = UsersPeer::USR_ROLE; + } + + } // setUsrRole() + + /** + * Set the value of [usr_reports_to] column. + * + * @param string $v new value + * @return void + */ + public function setUsrReportsTo($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_reports_to !== $v || $v === '') { + $this->usr_reports_to = $v; + $this->modifiedColumns[] = UsersPeer::USR_REPORTS_TO; + } + + } // setUsrReportsTo() + + /** + * Set the value of [usr_replaced_by] column. + * + * @param string $v new value + * @return void + */ + public function setUsrReplacedBy($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_replaced_by !== $v || $v === '') { + $this->usr_replaced_by = $v; + $this->modifiedColumns[] = UsersPeer::USR_REPLACED_BY; + } + + } // setUsrReplacedBy() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->usr_uid = $rs->getString($startcol + 0); + + $this->usr_username = $rs->getString($startcol + 1); + + $this->usr_password = $rs->getString($startcol + 2); + + $this->usr_firstname = $rs->getString($startcol + 3); + + $this->usr_lastname = $rs->getString($startcol + 4); + + $this->usr_email = $rs->getString($startcol + 5); + + $this->usr_due_date = $rs->getDate($startcol + 6, null); + + $this->usr_create_date = $rs->getTimestamp($startcol + 7, null); + + $this->usr_update_date = $rs->getTimestamp($startcol + 8, null); + + $this->usr_status = $rs->getString($startcol + 9); + + $this->usr_country = $rs->getString($startcol + 10); + + $this->usr_city = $rs->getString($startcol + 11); + + $this->usr_location = $rs->getString($startcol + 12); + + $this->usr_address = $rs->getString($startcol + 13); + + $this->usr_phone = $rs->getString($startcol + 14); + + $this->usr_fax = $rs->getString($startcol + 15); + + $this->usr_cellular = $rs->getString($startcol + 16); + + $this->usr_zip_code = $rs->getString($startcol + 17); + + $this->dep_uid = $rs->getString($startcol + 18); + + $this->usr_position = $rs->getString($startcol + 19); + + $this->usr_resume = $rs->getString($startcol + 20); + + $this->usr_birthday = $rs->getDate($startcol + 21, null); + + $this->usr_role = $rs->getString($startcol + 22); + + $this->usr_reports_to = $rs->getString($startcol + 23); + + $this->usr_replaced_by = $rs->getString($startcol + 24); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 25; // 25 = UsersPeer::NUM_COLUMNS - UsersPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating Users object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + } + + try { + $con->begin(); + UsersPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = UsersPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += UsersPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = UsersPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = UsersPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getUsrUid(); + break; + case 1: + return $this->getUsrUsername(); + break; + case 2: + return $this->getUsrPassword(); + break; + case 3: + return $this->getUsrFirstname(); + break; + case 4: + return $this->getUsrLastname(); + break; + case 5: + return $this->getUsrEmail(); + break; + case 6: + return $this->getUsrDueDate(); + break; + case 7: + return $this->getUsrCreateDate(); + break; + case 8: + return $this->getUsrUpdateDate(); + break; + case 9: + return $this->getUsrStatus(); + break; + case 10: + return $this->getUsrCountry(); + break; + case 11: + return $this->getUsrCity(); + break; + case 12: + return $this->getUsrLocation(); + break; + case 13: + return $this->getUsrAddress(); + break; + case 14: + return $this->getUsrPhone(); + break; + case 15: + return $this->getUsrFax(); + break; + case 16: + return $this->getUsrCellular(); + break; + case 17: + return $this->getUsrZipCode(); + break; + case 18: + return $this->getDepUid(); + break; + case 19: + return $this->getUsrPosition(); + break; + case 20: + return $this->getUsrResume(); + break; + case 21: + return $this->getUsrBirthday(); + break; + case 22: + return $this->getUsrRole(); + break; + case 23: + return $this->getUsrReportsTo(); + break; + case 24: + return $this->getUsrReplacedBy(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = UsersPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getUsrUid(), + $keys[1] => $this->getUsrUsername(), + $keys[2] => $this->getUsrPassword(), + $keys[3] => $this->getUsrFirstname(), + $keys[4] => $this->getUsrLastname(), + $keys[5] => $this->getUsrEmail(), + $keys[6] => $this->getUsrDueDate(), + $keys[7] => $this->getUsrCreateDate(), + $keys[8] => $this->getUsrUpdateDate(), + $keys[9] => $this->getUsrStatus(), + $keys[10] => $this->getUsrCountry(), + $keys[11] => $this->getUsrCity(), + $keys[12] => $this->getUsrLocation(), + $keys[13] => $this->getUsrAddress(), + $keys[14] => $this->getUsrPhone(), + $keys[15] => $this->getUsrFax(), + $keys[16] => $this->getUsrCellular(), + $keys[17] => $this->getUsrZipCode(), + $keys[18] => $this->getDepUid(), + $keys[19] => $this->getUsrPosition(), + $keys[20] => $this->getUsrResume(), + $keys[21] => $this->getUsrBirthday(), + $keys[22] => $this->getUsrRole(), + $keys[23] => $this->getUsrReportsTo(), + $keys[24] => $this->getUsrReplacedBy(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = UsersPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setUsrUid($value); + break; + case 1: + $this->setUsrUsername($value); + break; + case 2: + $this->setUsrPassword($value); + break; + case 3: + $this->setUsrFirstname($value); + break; + case 4: + $this->setUsrLastname($value); + break; + case 5: + $this->setUsrEmail($value); + break; + case 6: + $this->setUsrDueDate($value); + break; + case 7: + $this->setUsrCreateDate($value); + break; + case 8: + $this->setUsrUpdateDate($value); + break; + case 9: + $this->setUsrStatus($value); + break; + case 10: + $this->setUsrCountry($value); + break; + case 11: + $this->setUsrCity($value); + break; + case 12: + $this->setUsrLocation($value); + break; + case 13: + $this->setUsrAddress($value); + break; + case 14: + $this->setUsrPhone($value); + break; + case 15: + $this->setUsrFax($value); + break; + case 16: + $this->setUsrCellular($value); + break; + case 17: + $this->setUsrZipCode($value); + break; + case 18: + $this->setDepUid($value); + break; + case 19: + $this->setUsrPosition($value); + break; + case 20: + $this->setUsrResume($value); + break; + case 21: + $this->setUsrBirthday($value); + break; + case 22: + $this->setUsrRole($value); + break; + case 23: + $this->setUsrReportsTo($value); + break; + case 24: + $this->setUsrReplacedBy($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = UsersPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setUsrUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setUsrUsername($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUsrPassword($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setUsrFirstname($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUsrLastname($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUsrEmail($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setUsrDueDate($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUsrCreateDate($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUsrUpdateDate($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setUsrStatus($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setUsrCountry($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setUsrCity($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setUsrLocation($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setUsrAddress($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setUsrPhone($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setUsrFax($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setUsrCellular($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setUsrZipCode($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setDepUid($arr[$keys[18]]); + if (array_key_exists($keys[19], $arr)) $this->setUsrPosition($arr[$keys[19]]); + if (array_key_exists($keys[20], $arr)) $this->setUsrResume($arr[$keys[20]]); + if (array_key_exists($keys[21], $arr)) $this->setUsrBirthday($arr[$keys[21]]); + if (array_key_exists($keys[22], $arr)) $this->setUsrRole($arr[$keys[22]]); + if (array_key_exists($keys[23], $arr)) $this->setUsrReportsTo($arr[$keys[23]]); + if (array_key_exists($keys[24], $arr)) $this->setUsrReplacedBy($arr[$keys[24]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(UsersPeer::DATABASE_NAME); + + if ($this->isColumnModified(UsersPeer::USR_UID)) $criteria->add(UsersPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(UsersPeer::USR_USERNAME)) $criteria->add(UsersPeer::USR_USERNAME, $this->usr_username); + if ($this->isColumnModified(UsersPeer::USR_PASSWORD)) $criteria->add(UsersPeer::USR_PASSWORD, $this->usr_password); + if ($this->isColumnModified(UsersPeer::USR_FIRSTNAME)) $criteria->add(UsersPeer::USR_FIRSTNAME, $this->usr_firstname); + if ($this->isColumnModified(UsersPeer::USR_LASTNAME)) $criteria->add(UsersPeer::USR_LASTNAME, $this->usr_lastname); + if ($this->isColumnModified(UsersPeer::USR_EMAIL)) $criteria->add(UsersPeer::USR_EMAIL, $this->usr_email); + if ($this->isColumnModified(UsersPeer::USR_DUE_DATE)) $criteria->add(UsersPeer::USR_DUE_DATE, $this->usr_due_date); + if ($this->isColumnModified(UsersPeer::USR_CREATE_DATE)) $criteria->add(UsersPeer::USR_CREATE_DATE, $this->usr_create_date); + if ($this->isColumnModified(UsersPeer::USR_UPDATE_DATE)) $criteria->add(UsersPeer::USR_UPDATE_DATE, $this->usr_update_date); + if ($this->isColumnModified(UsersPeer::USR_STATUS)) $criteria->add(UsersPeer::USR_STATUS, $this->usr_status); + if ($this->isColumnModified(UsersPeer::USR_COUNTRY)) $criteria->add(UsersPeer::USR_COUNTRY, $this->usr_country); + if ($this->isColumnModified(UsersPeer::USR_CITY)) $criteria->add(UsersPeer::USR_CITY, $this->usr_city); + if ($this->isColumnModified(UsersPeer::USR_LOCATION)) $criteria->add(UsersPeer::USR_LOCATION, $this->usr_location); + if ($this->isColumnModified(UsersPeer::USR_ADDRESS)) $criteria->add(UsersPeer::USR_ADDRESS, $this->usr_address); + if ($this->isColumnModified(UsersPeer::USR_PHONE)) $criteria->add(UsersPeer::USR_PHONE, $this->usr_phone); + if ($this->isColumnModified(UsersPeer::USR_FAX)) $criteria->add(UsersPeer::USR_FAX, $this->usr_fax); + if ($this->isColumnModified(UsersPeer::USR_CELLULAR)) $criteria->add(UsersPeer::USR_CELLULAR, $this->usr_cellular); + if ($this->isColumnModified(UsersPeer::USR_ZIP_CODE)) $criteria->add(UsersPeer::USR_ZIP_CODE, $this->usr_zip_code); + if ($this->isColumnModified(UsersPeer::DEP_UID)) $criteria->add(UsersPeer::DEP_UID, $this->dep_uid); + if ($this->isColumnModified(UsersPeer::USR_POSITION)) $criteria->add(UsersPeer::USR_POSITION, $this->usr_position); + if ($this->isColumnModified(UsersPeer::USR_RESUME)) $criteria->add(UsersPeer::USR_RESUME, $this->usr_resume); + if ($this->isColumnModified(UsersPeer::USR_BIRTHDAY)) $criteria->add(UsersPeer::USR_BIRTHDAY, $this->usr_birthday); + if ($this->isColumnModified(UsersPeer::USR_ROLE)) $criteria->add(UsersPeer::USR_ROLE, $this->usr_role); + if ($this->isColumnModified(UsersPeer::USR_REPORTS_TO)) $criteria->add(UsersPeer::USR_REPORTS_TO, $this->usr_reports_to); + if ($this->isColumnModified(UsersPeer::USR_REPLACED_BY)) $criteria->add(UsersPeer::USR_REPLACED_BY, $this->usr_replaced_by); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(UsersPeer::DATABASE_NAME); + + $criteria->add(UsersPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getUsrUid(); + } + + /** + * Generic method to set the primary key (usr_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setUsrUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of Users (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setUsrUsername($this->usr_username); + + $copyObj->setUsrPassword($this->usr_password); + + $copyObj->setUsrFirstname($this->usr_firstname); + + $copyObj->setUsrLastname($this->usr_lastname); + + $copyObj->setUsrEmail($this->usr_email); + + $copyObj->setUsrDueDate($this->usr_due_date); + + $copyObj->setUsrCreateDate($this->usr_create_date); + + $copyObj->setUsrUpdateDate($this->usr_update_date); + + $copyObj->setUsrStatus($this->usr_status); + + $copyObj->setUsrCountry($this->usr_country); + + $copyObj->setUsrCity($this->usr_city); + + $copyObj->setUsrLocation($this->usr_location); + + $copyObj->setUsrAddress($this->usr_address); + + $copyObj->setUsrPhone($this->usr_phone); + + $copyObj->setUsrFax($this->usr_fax); + + $copyObj->setUsrCellular($this->usr_cellular); + + $copyObj->setUsrZipCode($this->usr_zip_code); + + $copyObj->setDepUid($this->dep_uid); + + $copyObj->setUsrPosition($this->usr_position); + + $copyObj->setUsrResume($this->usr_resume); + + $copyObj->setUsrBirthday($this->usr_birthday); + + $copyObj->setUsrRole($this->usr_role); + + $copyObj->setUsrReportsTo($this->usr_reports_to); + + $copyObj->setUsrReplacedBy($this->usr_replaced_by); + + + $copyObj->setNew(true); + + $copyObj->setUsrUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return Users Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return UsersPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new UsersPeer(); + } + return self::$peer; + } + +} // BaseUsers diff --git a/workflow/engine/classes/model/om/BaseUsersPeer.php b/workflow/engine/classes/model/om/BaseUsersPeer.php new file mode 100644 index 000000000..3b4cf8d72 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseUsersPeer.php @@ -0,0 +1,688 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by UsersPeer::getOMClass() +include_once 'classes/model/Users.php'; + +/** + * Base static class for performing query and update operations on the 'USERS' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseUsersPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'USERS'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.Users'; + + /** The total number of columns. */ + const NUM_COLUMNS = 25; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the USR_UID field */ + const USR_UID = 'USERS.USR_UID'; + + /** the column name for the USR_USERNAME field */ + const USR_USERNAME = 'USERS.USR_USERNAME'; + + /** the column name for the USR_PASSWORD field */ + const USR_PASSWORD = 'USERS.USR_PASSWORD'; + + /** the column name for the USR_FIRSTNAME field */ + const USR_FIRSTNAME = 'USERS.USR_FIRSTNAME'; + + /** the column name for the USR_LASTNAME field */ + const USR_LASTNAME = 'USERS.USR_LASTNAME'; + + /** the column name for the USR_EMAIL field */ + const USR_EMAIL = 'USERS.USR_EMAIL'; + + /** the column name for the USR_DUE_DATE field */ + const USR_DUE_DATE = 'USERS.USR_DUE_DATE'; + + /** the column name for the USR_CREATE_DATE field */ + const USR_CREATE_DATE = 'USERS.USR_CREATE_DATE'; + + /** the column name for the USR_UPDATE_DATE field */ + const USR_UPDATE_DATE = 'USERS.USR_UPDATE_DATE'; + + /** the column name for the USR_STATUS field */ + const USR_STATUS = 'USERS.USR_STATUS'; + + /** the column name for the USR_COUNTRY field */ + const USR_COUNTRY = 'USERS.USR_COUNTRY'; + + /** the column name for the USR_CITY field */ + const USR_CITY = 'USERS.USR_CITY'; + + /** the column name for the USR_LOCATION field */ + const USR_LOCATION = 'USERS.USR_LOCATION'; + + /** the column name for the USR_ADDRESS field */ + const USR_ADDRESS = 'USERS.USR_ADDRESS'; + + /** the column name for the USR_PHONE field */ + const USR_PHONE = 'USERS.USR_PHONE'; + + /** the column name for the USR_FAX field */ + const USR_FAX = 'USERS.USR_FAX'; + + /** the column name for the USR_CELLULAR field */ + const USR_CELLULAR = 'USERS.USR_CELLULAR'; + + /** the column name for the USR_ZIP_CODE field */ + const USR_ZIP_CODE = 'USERS.USR_ZIP_CODE'; + + /** the column name for the DEP_UID field */ + const DEP_UID = 'USERS.DEP_UID'; + + /** the column name for the USR_POSITION field */ + const USR_POSITION = 'USERS.USR_POSITION'; + + /** the column name for the USR_RESUME field */ + const USR_RESUME = 'USERS.USR_RESUME'; + + /** the column name for the USR_BIRTHDAY field */ + const USR_BIRTHDAY = 'USERS.USR_BIRTHDAY'; + + /** the column name for the USR_ROLE field */ + const USR_ROLE = 'USERS.USR_ROLE'; + + /** the column name for the USR_REPORTS_TO field */ + const USR_REPORTS_TO = 'USERS.USR_REPORTS_TO'; + + /** the column name for the USR_REPLACED_BY field */ + const USR_REPLACED_BY = 'USERS.USR_REPLACED_BY'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('UsrUid', 'UsrUsername', 'UsrPassword', 'UsrFirstname', 'UsrLastname', 'UsrEmail', 'UsrDueDate', 'UsrCreateDate', 'UsrUpdateDate', 'UsrStatus', 'UsrCountry', 'UsrCity', 'UsrLocation', 'UsrAddress', 'UsrPhone', 'UsrFax', 'UsrCellular', 'UsrZipCode', 'DepUid', 'UsrPosition', 'UsrResume', 'UsrBirthday', 'UsrRole', 'UsrReportsTo', 'UsrReplacedBy', ), + BasePeer::TYPE_COLNAME => array (UsersPeer::USR_UID, UsersPeer::USR_USERNAME, UsersPeer::USR_PASSWORD, UsersPeer::USR_FIRSTNAME, UsersPeer::USR_LASTNAME, UsersPeer::USR_EMAIL, UsersPeer::USR_DUE_DATE, UsersPeer::USR_CREATE_DATE, UsersPeer::USR_UPDATE_DATE, UsersPeer::USR_STATUS, UsersPeer::USR_COUNTRY, UsersPeer::USR_CITY, UsersPeer::USR_LOCATION, UsersPeer::USR_ADDRESS, UsersPeer::USR_PHONE, UsersPeer::USR_FAX, UsersPeer::USR_CELLULAR, UsersPeer::USR_ZIP_CODE, UsersPeer::DEP_UID, UsersPeer::USR_POSITION, UsersPeer::USR_RESUME, UsersPeer::USR_BIRTHDAY, UsersPeer::USR_ROLE, UsersPeer::USR_REPORTS_TO, UsersPeer::USR_REPLACED_BY, ), + BasePeer::TYPE_FIELDNAME => array ('USR_UID', 'USR_USERNAME', 'USR_PASSWORD', 'USR_FIRSTNAME', 'USR_LASTNAME', 'USR_EMAIL', 'USR_DUE_DATE', 'USR_CREATE_DATE', 'USR_UPDATE_DATE', 'USR_STATUS', 'USR_COUNTRY', 'USR_CITY', 'USR_LOCATION', 'USR_ADDRESS', 'USR_PHONE', 'USR_FAX', 'USR_CELLULAR', 'USR_ZIP_CODE', 'DEP_UID', 'USR_POSITION', 'USR_RESUME', 'USR_BIRTHDAY', 'USR_ROLE', 'USR_REPORTS_TO', 'USR_REPLACED_BY', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('UsrUid' => 0, 'UsrUsername' => 1, 'UsrPassword' => 2, 'UsrFirstname' => 3, 'UsrLastname' => 4, 'UsrEmail' => 5, 'UsrDueDate' => 6, 'UsrCreateDate' => 7, 'UsrUpdateDate' => 8, 'UsrStatus' => 9, 'UsrCountry' => 10, 'UsrCity' => 11, 'UsrLocation' => 12, 'UsrAddress' => 13, 'UsrPhone' => 14, 'UsrFax' => 15, 'UsrCellular' => 16, 'UsrZipCode' => 17, 'DepUid' => 18, 'UsrPosition' => 19, 'UsrResume' => 20, 'UsrBirthday' => 21, 'UsrRole' => 22, 'UsrReportsTo' => 23, 'UsrReplacedBy' => 24, ), + BasePeer::TYPE_COLNAME => array (UsersPeer::USR_UID => 0, UsersPeer::USR_USERNAME => 1, UsersPeer::USR_PASSWORD => 2, UsersPeer::USR_FIRSTNAME => 3, UsersPeer::USR_LASTNAME => 4, UsersPeer::USR_EMAIL => 5, UsersPeer::USR_DUE_DATE => 6, UsersPeer::USR_CREATE_DATE => 7, UsersPeer::USR_UPDATE_DATE => 8, UsersPeer::USR_STATUS => 9, UsersPeer::USR_COUNTRY => 10, UsersPeer::USR_CITY => 11, UsersPeer::USR_LOCATION => 12, UsersPeer::USR_ADDRESS => 13, UsersPeer::USR_PHONE => 14, UsersPeer::USR_FAX => 15, UsersPeer::USR_CELLULAR => 16, UsersPeer::USR_ZIP_CODE => 17, UsersPeer::DEP_UID => 18, UsersPeer::USR_POSITION => 19, UsersPeer::USR_RESUME => 20, UsersPeer::USR_BIRTHDAY => 21, UsersPeer::USR_ROLE => 22, UsersPeer::USR_REPORTS_TO => 23, UsersPeer::USR_REPLACED_BY => 24, ), + BasePeer::TYPE_FIELDNAME => array ('USR_UID' => 0, 'USR_USERNAME' => 1, 'USR_PASSWORD' => 2, 'USR_FIRSTNAME' => 3, 'USR_LASTNAME' => 4, 'USR_EMAIL' => 5, 'USR_DUE_DATE' => 6, 'USR_CREATE_DATE' => 7, 'USR_UPDATE_DATE' => 8, 'USR_STATUS' => 9, 'USR_COUNTRY' => 10, 'USR_CITY' => 11, 'USR_LOCATION' => 12, 'USR_ADDRESS' => 13, 'USR_PHONE' => 14, 'USR_FAX' => 15, 'USR_CELLULAR' => 16, 'USR_ZIP_CODE' => 17, 'DEP_UID' => 18, 'USR_POSITION' => 19, 'USR_RESUME' => 20, 'USR_BIRTHDAY' => 21, 'USR_ROLE' => 22, 'USR_REPORTS_TO' => 23, 'USR_REPLACED_BY' => 24, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/UsersMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.UsersMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = UsersPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. UsersPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(UsersPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(UsersPeer::USR_UID); + + $criteria->addSelectColumn(UsersPeer::USR_USERNAME); + + $criteria->addSelectColumn(UsersPeer::USR_PASSWORD); + + $criteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + + $criteria->addSelectColumn(UsersPeer::USR_LASTNAME); + + $criteria->addSelectColumn(UsersPeer::USR_EMAIL); + + $criteria->addSelectColumn(UsersPeer::USR_DUE_DATE); + + $criteria->addSelectColumn(UsersPeer::USR_CREATE_DATE); + + $criteria->addSelectColumn(UsersPeer::USR_UPDATE_DATE); + + $criteria->addSelectColumn(UsersPeer::USR_STATUS); + + $criteria->addSelectColumn(UsersPeer::USR_COUNTRY); + + $criteria->addSelectColumn(UsersPeer::USR_CITY); + + $criteria->addSelectColumn(UsersPeer::USR_LOCATION); + + $criteria->addSelectColumn(UsersPeer::USR_ADDRESS); + + $criteria->addSelectColumn(UsersPeer::USR_PHONE); + + $criteria->addSelectColumn(UsersPeer::USR_FAX); + + $criteria->addSelectColumn(UsersPeer::USR_CELLULAR); + + $criteria->addSelectColumn(UsersPeer::USR_ZIP_CODE); + + $criteria->addSelectColumn(UsersPeer::DEP_UID); + + $criteria->addSelectColumn(UsersPeer::USR_POSITION); + + $criteria->addSelectColumn(UsersPeer::USR_RESUME); + + $criteria->addSelectColumn(UsersPeer::USR_BIRTHDAY); + + $criteria->addSelectColumn(UsersPeer::USR_ROLE); + + $criteria->addSelectColumn(UsersPeer::USR_REPORTS_TO); + + $criteria->addSelectColumn(UsersPeer::USR_REPLACED_BY); + + } + + const COUNT = 'COUNT(USERS.USR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT USERS.USR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(UsersPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(UsersPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = UsersPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return Users + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = UsersPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return UsersPeer::populateObjects(UsersPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + UsersPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = UsersPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return UsersPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a Users or Criteria object. + * + * @param mixed $values Criteria or Users object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from Users object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a Users or Criteria object. + * + * @param mixed $values Criteria or Users object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(UsersPeer::USR_UID); + $selectCriteria->add(UsersPeer::USR_UID, $criteria->remove(UsersPeer::USR_UID), $comparison); + + } else { // $values is Users object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the USERS table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(UsersPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a Users or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Users object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(UsersPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof Users) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(UsersPeer::USR_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given Users object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param Users $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(Users $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(UsersPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(UsersPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + if ($obj->isNew() || $obj->isColumnModified(UsersPeer::USR_STATUS)) + $columns[UsersPeer::USR_STATUS] = $obj->getUsrStatus(); + + } + + return BasePeer::doValidate(UsersPeer::DATABASE_NAME, UsersPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return Users + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(UsersPeer::DATABASE_NAME); + + $criteria->add(UsersPeer::USR_UID, $pk); + + + $v = UsersPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(UsersPeer::USR_UID, $pks, Criteria::IN); + $objs = UsersPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseUsersPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseUsersPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/UsersMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.UsersMapBuilder'); +} diff --git a/workflow/engine/classes/model/om/BaseUsersProperties.php b/workflow/engine/classes/model/om/BaseUsersProperties.php new file mode 100644 index 000000000..8d0543395 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseUsersProperties.php @@ -0,0 +1,685 @@ +<?php + +require_once 'propel/om/BaseObject.php'; + +require_once 'propel/om/Persistent.php'; + + +include_once 'propel/util/Criteria.php'; + +include_once 'classes/model/UsersPropertiesPeer.php'; + +/** + * Base class that represents a row from the 'USERS_PROPERTIES' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseUsersProperties extends BaseObject implements Persistent { + + + /** + * The Peer class. + * Instance provides a convenient way of calling static methods on a class + * that calling code may not be able to identify. + * @var UsersPropertiesPeer + */ + protected static $peer; + + + /** + * The value for the usr_uid field. + * @var string + */ + protected $usr_uid = ''; + + + /** + * The value for the usr_last_update_date field. + * @var int + */ + protected $usr_last_update_date; + + + /** + * The value for the usr_logged_next_time field. + * @var int + */ + protected $usr_logged_next_time = 0; + + + /** + * The value for the usr_password_history field. + * @var string + */ + protected $usr_password_history; + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + /** + * Get the [usr_uid] column value. + * + * @return string + */ + public function getUsrUid() + { + + return $this->usr_uid; + } + + /** + * Get the [optionally formatted] [usr_last_update_date] column value. + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the integer unix timestamp will be returned. + * @return mixed Formatted date/time value as string or integer unix timestamp (if format is NULL). + * @throws PropelException - if unable to convert the date/time to timestamp. + */ + public function getUsrLastUpdateDate($format = 'Y-m-d H:i:s') + { + + if ($this->usr_last_update_date === null || $this->usr_last_update_date === '') { + return null; + } elseif (!is_int($this->usr_last_update_date)) { + // a non-timestamp value was set externally, so we convert it + $ts = strtotime($this->usr_last_update_date); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse value of [usr_last_update_date] as date/time value: " . var_export($this->usr_last_update_date, true)); + } + } else { + $ts = $this->usr_last_update_date; + } + if ($format === null) { + return $ts; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $ts); + } else { + return date($format, $ts); + } + } + + /** + * Get the [usr_logged_next_time] column value. + * + * @return int + */ + public function getUsrLoggedNextTime() + { + + return $this->usr_logged_next_time; + } + + /** + * Get the [usr_password_history] column value. + * + * @return string + */ + public function getUsrPasswordHistory() + { + + return $this->usr_password_history; + } + + /** + * Set the value of [usr_uid] column. + * + * @param string $v new value + * @return void + */ + public function setUsrUid($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_uid !== $v || $v === '') { + $this->usr_uid = $v; + $this->modifiedColumns[] = UsersPropertiesPeer::USR_UID; + } + + } // setUsrUid() + + /** + * Set the value of [usr_last_update_date] column. + * + * @param int $v new value + * @return void + */ + public function setUsrLastUpdateDate($v) + { + + if ($v !== null && !is_int($v)) { + $ts = strtotime($v); + if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE + throw new PropelException("Unable to parse date/time value for [usr_last_update_date] from input: " . var_export($v, true)); + } + } else { + $ts = $v; + } + if ($this->usr_last_update_date !== $ts) { + $this->usr_last_update_date = $ts; + $this->modifiedColumns[] = UsersPropertiesPeer::USR_LAST_UPDATE_DATE; + } + + } // setUsrLastUpdateDate() + + /** + * Set the value of [usr_logged_next_time] column. + * + * @param int $v new value + * @return void + */ + public function setUsrLoggedNextTime($v) + { + + // Since the native PHP type for this column is integer, + // we will cast the input value to an int (if it is not). + if ($v !== null && !is_int($v) && is_numeric($v)) { + $v = (int) $v; + } + + if ($this->usr_logged_next_time !== $v || $v === 0) { + $this->usr_logged_next_time = $v; + $this->modifiedColumns[] = UsersPropertiesPeer::USR_LOGGED_NEXT_TIME; + } + + } // setUsrLoggedNextTime() + + /** + * Set the value of [usr_password_history] column. + * + * @param string $v new value + * @return void + */ + public function setUsrPasswordHistory($v) + { + + // Since the native PHP type for this column is string, + // we will cast the input to a string (if it is not). + if ($v !== null && !is_string($v)) { + $v = (string) $v; + } + + if ($this->usr_password_history !== $v) { + $this->usr_password_history = $v; + $this->modifiedColumns[] = UsersPropertiesPeer::USR_PASSWORD_HISTORY; + } + + } // setUsrPasswordHistory() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->usr_uid = $rs->getString($startcol + 0); + + $this->usr_last_update_date = $rs->getTimestamp($startcol + 1, null); + + $this->usr_logged_next_time = $rs->getInt($startcol + 2); + + $this->usr_password_history = $rs->getString($startcol + 3); + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + 4; // 4 = UsersPropertiesPeer::NUM_COLUMNS - UsersPropertiesPeer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating UsersProperties object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME); + } + + try { + $con->begin(); + UsersPropertiesPeer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = UsersPropertiesPeer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + } else { + $affectedRows += UsersPropertiesPeer::doUpdate($this, $con); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then <code>true</code> is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = UsersPropertiesPeer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = UsersPropertiesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + case 0: + return $this->getUsrUid(); + break; + case 1: + return $this->getUsrLastUpdateDate(); + break; + case 2: + return $this->getUsrLoggedNextTime(); + break; + case 3: + return $this->getUsrPasswordHistory(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = UsersPropertiesPeer::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getUsrUid(), + $keys[1] => $this->getUsrLastUpdateDate(), + $keys[2] => $this->getUsrLoggedNextTime(), + $keys[3] => $this->getUsrPasswordHistory(), + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = UsersPropertiesPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + case 0: + $this->setUsrUid($value); + break; + case 1: + $this->setUsrLastUpdateDate($value); + break; + case 2: + $this->setUsrLoggedNextTime($value); + break; + case 3: + $this->setUsrPasswordHistory($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = UsersPropertiesPeer::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setUsrUid($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setUsrLastUpdateDate($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUsrLoggedNextTime($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setUsrPasswordHistory($arr[$keys[3]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(UsersPropertiesPeer::DATABASE_NAME); + + if ($this->isColumnModified(UsersPropertiesPeer::USR_UID)) $criteria->add(UsersPropertiesPeer::USR_UID, $this->usr_uid); + if ($this->isColumnModified(UsersPropertiesPeer::USR_LAST_UPDATE_DATE)) $criteria->add(UsersPropertiesPeer::USR_LAST_UPDATE_DATE, $this->usr_last_update_date); + if ($this->isColumnModified(UsersPropertiesPeer::USR_LOGGED_NEXT_TIME)) $criteria->add(UsersPropertiesPeer::USR_LOGGED_NEXT_TIME, $this->usr_logged_next_time); + if ($this->isColumnModified(UsersPropertiesPeer::USR_PASSWORD_HISTORY)) $criteria->add(UsersPropertiesPeer::USR_PASSWORD_HISTORY, $this->usr_password_history); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(UsersPropertiesPeer::DATABASE_NAME); + + $criteria->add(UsersPropertiesPeer::USR_UID, $this->usr_uid); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + return $this->getUsrUid(); + } + + /** + * Generic method to set the primary key (usr_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setUsrUid($key); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of UsersProperties (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->setUsrLastUpdateDate($this->usr_last_update_date); + + $copyObj->setUsrLoggedNextTime($this->usr_logged_next_time); + + $copyObj->setUsrPasswordHistory($this->usr_password_history); + + + $copyObj->setNew(true); + + $copyObj->setUsrUid(''); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return UsersProperties Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return UsersPropertiesPeer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new UsersPropertiesPeer(); + } + return self::$peer; + } + +} // BaseUsersProperties diff --git a/workflow/engine/classes/model/om/BaseUsersPropertiesPeer.php b/workflow/engine/classes/model/om/BaseUsersPropertiesPeer.php new file mode 100644 index 000000000..6f77d1b12 --- /dev/null +++ b/workflow/engine/classes/model/om/BaseUsersPropertiesPeer.php @@ -0,0 +1,580 @@ +<?php + +require_once 'propel/util/BasePeer.php'; +// The object class -- needed for instanceof checks in this class. +// actual class may be a subclass -- as returned by UsersPropertiesPeer::getOMClass() +include_once 'classes/model/UsersProperties.php'; + +/** + * Base static class for performing query and update operations on the 'USERS_PROPERTIES' table. + * + * + * + * @package classes.model.om + */ +abstract class BaseUsersPropertiesPeer { + + /** the default database name for this class */ + const DATABASE_NAME = 'workflow'; + + /** the table name for this class */ + const TABLE_NAME = 'USERS_PROPERTIES'; + + /** A class that can be returned by this peer. */ + const CLASS_DEFAULT = 'classes.model.UsersProperties'; + + /** The total number of columns. */ + const NUM_COLUMNS = 4; + + /** The number of lazy-loaded columns. */ + const NUM_LAZY_LOAD_COLUMNS = 0; + + + /** the column name for the USR_UID field */ + const USR_UID = 'USERS_PROPERTIES.USR_UID'; + + /** the column name for the USR_LAST_UPDATE_DATE field */ + const USR_LAST_UPDATE_DATE = 'USERS_PROPERTIES.USR_LAST_UPDATE_DATE'; + + /** the column name for the USR_LOGGED_NEXT_TIME field */ + const USR_LOGGED_NEXT_TIME = 'USERS_PROPERTIES.USR_LOGGED_NEXT_TIME'; + + /** the column name for the USR_PASSWORD_HISTORY field */ + const USR_PASSWORD_HISTORY = 'USERS_PROPERTIES.USR_PASSWORD_HISTORY'; + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ('UsrUid', 'UsrLastUpdateDate', 'UsrLoggedNextTime', 'UsrPasswordHistory', ), + BasePeer::TYPE_COLNAME => array (UsersPropertiesPeer::USR_UID, UsersPropertiesPeer::USR_LAST_UPDATE_DATE, UsersPropertiesPeer::USR_LOGGED_NEXT_TIME, UsersPropertiesPeer::USR_PASSWORD_HISTORY, ), + BasePeer::TYPE_FIELDNAME => array ('USR_UID', 'USR_LAST_UPDATE_DATE', 'USR_LOGGED_NEXT_TIME', 'USR_PASSWORD_HISTORY', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ('UsrUid' => 0, 'UsrLastUpdateDate' => 1, 'UsrLoggedNextTime' => 2, 'UsrPasswordHistory' => 3, ), + BasePeer::TYPE_COLNAME => array (UsersPropertiesPeer::USR_UID => 0, UsersPropertiesPeer::USR_LAST_UPDATE_DATE => 1, UsersPropertiesPeer::USR_LOGGED_NEXT_TIME => 2, UsersPropertiesPeer::USR_PASSWORD_HISTORY => 3, ), + BasePeer::TYPE_FIELDNAME => array ('USR_UID' => 0, 'USR_LAST_UPDATE_DATE' => 1, 'USR_LOGGED_NEXT_TIME' => 2, 'USR_PASSWORD_HISTORY' => 3, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, ) + ); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once 'classes/model/map/UsersPropertiesMapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.UsersPropertiesMapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = UsersPropertiesPeer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * <code> + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * </code> + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. UsersPropertiesPeer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace(UsersPropertiesPeer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn(UsersPropertiesPeer::USR_UID); + + $criteria->addSelectColumn(UsersPropertiesPeer::USR_LAST_UPDATE_DATE); + + $criteria->addSelectColumn(UsersPropertiesPeer::USR_LOGGED_NEXT_TIME); + + $criteria->addSelectColumn(UsersPropertiesPeer::USR_PASSWORD_HISTORY); + + } + + const COUNT = 'COUNT(USERS_PROPERTIES.USR_UID)'; + const COUNT_DISTINCT = 'COUNT(DISTINCT USERS_PROPERTIES.USR_UID)'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn(UsersPropertiesPeer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn(UsersPropertiesPeer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = UsersPropertiesPeer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return UsersProperties + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = UsersPropertiesPeer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return UsersPropertiesPeer::populateObjects(UsersPropertiesPeer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + UsersPropertiesPeer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = UsersPropertiesPeer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return UsersPropertiesPeer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a UsersProperties or Criteria object. + * + * @param mixed $values Criteria or UsersProperties object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from UsersProperties object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a UsersProperties or Criteria object. + * + * @param mixed $values Criteria or UsersProperties object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison(UsersPropertiesPeer::USR_UID); + $selectCriteria->add(UsersPropertiesPeer::USR_UID, $criteria->remove(UsersPropertiesPeer::USR_UID), $comparison); + + } else { // $values is UsersProperties object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the USERS_PROPERTIES table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll(UsersPropertiesPeer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a UsersProperties or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or UsersProperties object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof UsersProperties) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + $criteria->add(UsersPropertiesPeer::USR_UID, (array) $values, Criteria::IN); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given UsersProperties object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param UsersProperties $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate(UsersProperties $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap(UsersPropertiesPeer::DATABASE_NAME); + $tableMap = $dbMap->getTable(UsersPropertiesPeer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate(UsersPropertiesPeer::DATABASE_NAME, UsersPropertiesPeer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return UsersProperties + */ + public static function retrieveByPK($pk, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $criteria = new Criteria(UsersPropertiesPeer::DATABASE_NAME); + + $criteria->add(UsersPropertiesPeer::USR_UID, $pk); + + + $v = UsersPropertiesPeer::doSelect($criteria, $con); + + return !empty($v) > 0 ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function retrieveByPKs($pks, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $objs = null; + if (empty($pks)) { + $objs = array(); + } else { + $criteria = new Criteria(); + $criteria->add(UsersPropertiesPeer::USR_UID, $pks, Criteria::IN); + $objs = UsersPropertiesPeer::doSelect($criteria, $con); + } + return $objs; + } + +} // BaseUsersPropertiesPeer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + BaseUsersPropertiesPeer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once 'classes/model/map/UsersPropertiesMapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.UsersPropertiesMapBuilder'); +} diff --git a/workflow/engine/classes/triggers/class.pmSugarFunctions.php b/workflow/engine/classes/triggers/class.pmSugarFunctions.php new file mode 100644 index 000000000..831a8d8b2 --- /dev/null +++ b/workflow/engine/classes/triggers/class.pmSugarFunctions.php @@ -0,0 +1,345 @@ +<?php +/** + * class.pmSugar.pmFunctions.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * * + */ + +//////////////////////////////////////////////////// +// pmSugar PM Functions +// +// Copyright (C) 2007 COLOSA +// +// License: LGPL, see LICENSE +//////////////////////////////////////////////////// + + +/** + * SugarCRM + * @class pmSugar + * @name Sugar CRM Triggers + * @icon /images/triggers/icon_SugarCRM.gif + * @className class.pmSugar.pmFunctions.php + */ + +function sugarLogin($sugarSoap, $user, $password) { + $client = new SoapClient ( $sugarSoap, array ('trace' => 1 ) ); + $auth_array = array ('user_auth' => array ('user_name' => $user, 'password' => md5 ( $password ), 'version' => '1.0' ) ); + $login_results = $client->__SoapCall ( 'login', $auth_array ); + + $session_id = $login_results->id; + $user_guid = $client->__SoapCall ( 'get_user_id', array ($session_id ) ); + return $session_id; +} + +function objectToArray($object) { + if (! is_object ( $object ) && ! is_array ( $object )) { + return $object; + } + if (is_object ( $object )) { + $object = get_object_vars ( $object ); + } + return array_map ( "objectToArray", $object ); +} +/** + * @method + * + * Gets SugarCRM entries from the indicated module. + * + * @name GetSugarEntries + * @label Get SugarCRM Entries + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $module | Module + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarEntries | Sugar Entries (array or object) + * + */ + +function GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $sessionId = sugarLogin ( $sugarSoap, $user, $password ); + $client = new SoapClient ( $sugarSoap, array ('trace' => 1 ) ); + $request_array = array ('session' => $sessionId, 'module_name' => $module, 'query' => $query, 'order_by' => $orderBy ); + $sugarEntriesO = $client->__SoapCall ( 'get_entry_list', $request_array ); + + switch($resultType){ + case 'array':$sugarEntries = objectToArray ( $sugarEntriesO );break; + case 'object':$sugarEntries = $sugarEntries ;break; + default: $sugarEntries = objectToArray ( $sugarEntries ); + } + + return $sugarEntries; + +} +/** + * @method + * + * Gets SugarCRM entries from the Calls module + * + * @name GetSugarCalls + * @label Gets SugarCRM entries from the Calls module + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarCalls | Sugar Calls (array or object) + * + */ + +function GetSugarCalls($sugarSoap, $user, $password, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $module="Calls"; + return GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType); +} +/** + * @method + * + * Gets SugarCRM entries from the Leads module. + * + * @name GetSugarLeads + * @label Gets SugarCRM entries from the Leads module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarLeads | Sugar Leads (array or object) + * + */ + +function GetSugarLeads($sugarSoap, $user, $password, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $module="Leads"; + return GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType); +} +/** + * @method + * + * Gets SugarCRM entries from the Contacts module. + * + * @name GetSugarContacts + * @label Gets SugarCRM entries from the Contacts module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarContacts | Sugar Contacts (array or object) + * + */ + +function GetSugarContacts($sugarSoap, $user, $password, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $module="Contacts"; + return GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType); +} +/** + * @method + * + * Gets SugarCRM entries from the Opportunities module. + * + * @name GetSugarOpportunities + * @label Gets SugarCRM entries from the Opportunities module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarAccount | Sugar Opportunities (array or object) + * + */ + +function GetSugarOpportunities($sugarSoap, $user, $password, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $module="Opportunities"; + return GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType); +} + +/** + * @method + * + * Gets SugarCRM entries from the Account module. + * + * @name GetSugarAccount + * @label Gets SugarCRM entries from the Account module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $query | Query + * @param string | $orderBy | Order By + * @param string | $selectedFields | Selected Fields + * @param string | $maxResults=50 | Max Results + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarAccount | Sugar Opportunities (array or object) + * + */ + +function GetSugarAccount($sugarSoap, $user, $password, $query, $orderBy, $selectedFields, $maxResults, $resultType="array") { + $module="Accounts"; + return GetSugarEntries($sugarSoap, $user, $password, $module, $query, $orderBy, $selectedFields, $maxResults, $resultType); +} + + +/** + * @method + * + * Creates SugarCRM entries from the Account module. + * + * @name CreateSugarAccount + * + * @label Creates SugarCRM entries from the Account module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $name | name + * @param string | $value | value + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarAccount | Sugar Opportunities (array or object) + * + */ +function CreateSugarAccount($sugarSoap, $user, $password, $name , $value, $resultType="array") { + + $module = "Accounts"; + $sessionId = sugarLogin ( $sugarSoap, $user, $password ); + $client = new SoapClient ( $sugarSoap, array ('trace' => 1 ) ); + $request_array = array ('session' => $sessionId, 'module_name' => $module, 'name_value_list' => array( + array("name" => 'name', "value" => $value ) + ) ); + $sugarEntriesO = $client->__SoapCall ( 'set_entry', $request_array ); + $account_id = $sugarEntriesO ->id; + + switch($resultType){ + case 'array':$sugarEntries = objectToArray ( $sugarEntriesO );break; + case 'object':$sugarEntries = $sugarEntries ;break; + default: $sugarEntries = objectToArray ( $sugarEntries ); + } + return $sugarEntries; +} + +/** + * @method + * + * Creates SugarCRM entries from the Account module + * + * @name CreateSugarContact + * + * @label Creates SugarCRM entries from the Account module + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $first_name | First Name + * @param string | $last_name | Last Name + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarContact | Sugar Opportunities (array or object) + * + */ +function CreateSugarContact($sugarSoap, $user, $password, + $first_name, $last_name, + $resultType="array") { + + $module = "Contacts"; + $aValue = array( + array("name" => 'id', "value" => G::generateUniqueID()), + array("name" => 'first_name', "value" => $first_name), + array("name" => 'last_name', "value" => $last_name), + ); + + $sessionId = sugarLogin ( $sugarSoap, $user, $password ); + $client = new SoapClient ( $sugarSoap, array ('trace' => 1 ) ); + + $request_array = array ('session' => $sessionId, 'module_name' => $module, 'name_value_list' => $aValue ); + + $sugarEntriesO = $client->__SoapCall ( 'set_entry', $request_array ); + + switch($resultType){ + case 'array':$sugarEntries = objectToArray ( $sugarEntriesO ); break; + case 'object':$sugarEntries = $sugarEntries; break; + default: $sugarEntries = objectToArray ( $sugarEntries ); + } + return $sugarEntries; +} + + +/** + * @method + * + * Creates SugarCRM entries from the Opportunities module. + * + * @name CreateSugarOpportunity + + * @label Creates SugarCRM entries from the Opportunities module. + * + * @param string | $sugarSoap | Sugar SOAP URL | http://www.example.com/sugar/soap.php?wsdl + * @param string | $user | User + * @param string | $password | Password + * @param string | $name | Name + * @param string | $account_name | Account Name + * @param string | $amount | Amount + * @param string | $date_closed | Date Closed + * @param string | $sales_stage | Prospecting, Qualification, Needs Analysis, Value Proposition, Id. Decision Makers, Perception Analysis, Proposal/Price Quote, Negotiation/Review, Closed Won, Closed Lost + * @param string | $resultType=array | Result type (array or object) + * + * @return array/object | $sugarOpportunity | Sugar Opportunities (array or object) + * + */ +function CreateSugarOpportunity($sugarSoap, $user, $password, + $name, $account_name, $amount, $date_closed, $sales_stage, + $resultType="array") { + + $module = "Opportunities"; + + $aValue = array( + array("name" => 'id', "value" => G::generateUniqueID()), + array("name" => 'name', "value" => $name), + array("name" => 'account_name', "value" => $account_name), + array("name" => 'amount', "value" => $amount), + array("name" => 'date_closed', "value" => $date_closed), + array("name" => 'sales_stage', "value" => $sales_stage) + ); + + $sessionId = sugarLogin ( $sugarSoap, $user, $password ); + $client = new SoapClient ( $sugarSoap, array ('trace' => 1 ) ); + + $request_array = array ('session' => $sessionId, 'module_name' => $module, 'name_value_list' => $aValue ); + + $sugarEntriesO = $client->__SoapCall ( 'set_entry', $request_array ); + + switch($resultType){ + case 'array':$sugarEntries = objectToArray ( $sugarEntriesO ); break; + case 'object':$sugarEntries = $sugarEntries; break; + default: $sugarEntries = objectToArray ( $sugarEntries ); + } + return $sugarEntries; +} \ No newline at end of file diff --git a/workflow/engine/classes/triggers/class.pmTalendFunctions.php b/workflow/engine/classes/triggers/class.pmTalendFunctions.php new file mode 100644 index 000000000..98fa19d5f --- /dev/null +++ b/workflow/engine/classes/triggers/class.pmTalendFunctions.php @@ -0,0 +1,67 @@ +<?php +/** + * class.pmTalend.pmFunctions.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * * + */ + +//////////////////////////////////////////////////// +// pmTalend PM Functions +// +// Copyright (C) 2007 COLOSA +// +// License: LGPL, see LICENSE +//////////////////////////////////////////////////// + +/** + * Talend ETL Integration + * @class pmTalend + * @name Talend ETL Integration + * @icon /images/triggers/TalendOpenStudio.gif + * @className class.pmTalend.pmFunctions.php + */ + + + +/** + * @method + * + * Executes a Talend Web Service.. + * + * @name executeTalendWebservice + * @label Executes a Talend Web Service. + * + * @param string | $wsdl | Talend Web Service (including ?WSDL) + * @param array(array(n1 v1) array(n2 v2) array(nN vN)) | $params | Array of params. Pairs of param Name Value + * @param string | $message | Message to be displayed + * @return array | $return | Talend Array + * + */ +function executeTalendWebservice($wsdl,$params=array(), $message){ + $client = new SoapClient($wsdl,array('trace' => 1)); + $params[0]=""; + foreach($params as $paramO){ + $params[]="--context_param".$paramO[0]."=".$paramO[1]; + } + $result = $client->__SoapCall('runJob', array($params)); + + /* + $params[1]="--context_param nb_line=".@=Quantity; + + $result = $client->__SoapCall('runJob', array($params)); + foreach ($result->item as $keyItem => $item){ + $gridRow=$keyItem+1; + @=USERSINFO[$gridRow]['NAME']=$item->item[1]; + @=USERSINFO[$gridRow]['LASTNAME']=$item->item[2]; + @=USERSINFO[$gridRow]['DATE']=$item->item[0]; + @=USERSINFO[$gridRow]['STREET']=$item->item[3]; + @=USERSINFO[$gridRow]['CITY']=$item->item[4]; + @=USERSINFO[$gridRow]['STATE']=$item->item[5]; + @=USERSINFO[$gridRow]['STATEID']=$item->item[6]; + + } + */ + G::SendMessageText( "<font color='blue'>Information from Talend ETL webservice</font><font color='darkgray'><br>".$wsdl."</font>", "INFO"); +} \ No newline at end of file diff --git a/workflow/engine/config/databases.php b/workflow/engine/config/databases.php new file mode 100644 index 000000000..934e73c44 --- /dev/null +++ b/workflow/engine/config/databases.php @@ -0,0 +1,84 @@ +<?php +/** + * databases.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + global $G_ENVIRONMENTS; + if(defined("G_ENVIRONMENT")){ //If we don't have G_ENVIRONMENT defined the only enable dbArray +//var_dump($G_ENVIRONMENTS[G_ENVIRONMENT]);die; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_ENVIRONMENT ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + die(); + } + require_once ( $dbfile ); + } + else { + //when this file is called from sysGeneric, the $G_ENVIRONMENTS DOES NOT EXIST, BUT DB_HOST is defined + if ( !defined ( 'DB_HOST' ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + die(); + } + + } + //to do: enable for other databases + $dbType = DB_ADAPTER; + + $dsn = DB_ADAPTER . '://' . DB_USER . ':' . DB_PASS . '@' . DB_HOST . '/' . DB_NAME; + + //to do: enable a mechanism to select RBAC Database + $dsnRbac = DB_ADAPTER . '://' . DB_RBAC_USER . ':' . DB_RBAC_PASS . '@' . DB_RBAC_HOST . '/' . DB_RBAC_NAME; + + //to do: enable a mechanism to select report Database + $dsnReport = DB_ADAPTER . '://' . DB_REPORT_USER . ':' . DB_REPORT_PASS . '@' . DB_REPORT_HOST . '/' . DB_REPORT_NAME; + + switch (DB_ADAPTER) { + case 'mysql': + $dsn .= '?encoding=utf8'; + $dsnRbac .= '?encoding=utf8'; + $dsnReport .= '?encoding=utf8'; + break; + case 'mssql': + //$dsn .= '?sendStringAsUnicode=false'; + //$dsnRbac .= '?sendStringAsUnicode=false'; + //$dsnReport .= '?sendStringAsUnicode=false'; + break; + default: + break; + } + + $pro ['datasources']['workflow']['connection'] = $dsn; + $pro ['datasources']['workflow']['adapter'] = DB_ADAPTER; + + $pro ['datasources']['rbac']['connection'] = $dsnRbac; + $pro ['datasources']['rbac']['adapter'] = DB_ADAPTER; + + $pro ['datasources']['rp']['connection'] = $dsnReport; + $pro ['datasources']['rp']['adapter'] = DB_ADAPTER; +} + $pro ['datasources']['dbarray']['connection'] = 'dbarray://user:pass@localhost/pm_os'; + $pro ['datasources']['dbarray']['adapter'] = 'dbarray'; + + return $pro; +?> diff --git a/workflow/engine/config/environments.php b/workflow/engine/config/environments.php new file mode 100644 index 000000000..6e49e9a13 --- /dev/null +++ b/workflow/engine/config/environments.php @@ -0,0 +1,45 @@ +<?php +/** + * environments.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $G_ENVIRONMENTS = array ( + G_PRO_ENV => array ( + 'dbfile' => PATH_DB . 'production' . PATH_SEP . 'db.php' , + 'cache' => 1, + 'debug' => 0, + ) , + G_DEV_ENV => array ( + 'dbfile' => PATH_DB . 'workflow' . PATH_SEP . 'db.php', + 'datasource' => 'workflow', + 'cache' => 0, + 'debug' => 1, + ) , + G_TEST_ENV => array ( + 'dbfile' => PATH_DB . 'test' . PATH_SEP . 'db.php' , + 'cache' => 0, + 'debug' => 0, + ) , + ); + +?> diff --git a/workflow/engine/config/paths.php b/workflow/engine/config/paths.php new file mode 100644 index 000000000..a021c7b55 --- /dev/null +++ b/workflow/engine/config/paths.php @@ -0,0 +1,141 @@ +<?php +/** + * paths.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +//***************** System Directories & Paths ************************** + +//***************** RBAC Paths ************************** + define( 'PATH_RBAC_HOME', PATH_TRUNK . 'rbac' . PATH_SEP ); + +//***************** GULLIVER Paths ************************** + define( 'PATH_GULLIVER_HOME', PATH_TRUNK . 'gulliver' . PATH_SEP ); + define( 'PATH_GULLIVER', PATH_GULLIVER_HOME . 'system' . PATH_SEP ); //gulliver system classes + define( 'PATH_GULLIVER_BIN', PATH_GULLIVER_HOME . 'bin' . PATH_SEP ); //gulliver bin classes + define( 'PATH_TEMPLATE', PATH_GULLIVER_HOME . 'templates' . PATH_SEP ); + define( 'PATH_THIRDPARTY', PATH_GULLIVER_HOME . 'thirdparty' . PATH_SEP ); + + define( 'PATH_RBAC', PATH_RBAC_HOME . 'engine' . PATH_SEP . 'classes' . PATH_SEP ); //to enable rbac version 2 + define( 'PATH_RBAC_CORE', PATH_RBAC_HOME . 'engine' . PATH_SEP ); + + define( 'PATH_HTML', PATH_HOME . 'public_html' . PATH_SEP ); + +//***************** PM Paths CORE ************************** + define( 'PATH_CORE', PATH_HOME . 'engine' . PATH_SEP ); + define( 'PATH_SKINS', PATH_CORE . 'skins' . PATH_SEP ); + define( 'PATH_METHODS', PATH_CORE . 'methods' . PATH_SEP ); + define( 'PATH_XMLFORM', PATH_CORE . 'xmlform' . PATH_SEP ); + define( 'PATH_PLUGINS', PATH_CORE . 'plugins' . PATH_SEP ); + define( 'PATH_HTMLMAIL', PATH_CORE . 'html_templates' . PATH_SEP ); + define( 'PATH_TPL', PATH_CORE . 'templates' . PATH_SEP ); + define( 'PATH_TEST', PATH_CORE . 'test' . PATH_SEP ); + define( 'PATH_FIXTURES', PATH_TEST . 'fixtures' . PATH_SEP ); + define( 'PATH_RTFDOCS' , PATH_CORE . 'rtf_templates' . PATH_SEP ); + define( 'PATH_DYNACONT', PATH_CORE . 'content' . PATH_SEP . 'dynaform' . PATH_SEP ); + define( 'PATH_LANGUAGECONT',PATH_CORE . 'content' . PATH_SEP . 'languages' . PATH_SEP ); + define( 'SYS_UPLOAD_PATH', PATH_HOME . "public_html/files/" ); + define( 'PATH_UPLOAD', PATH_HTML . 'files' . PATH_SEP); + define( 'PATH_WORKFLOW_MYSQL_DATA', PATH_CORE . 'data' . PATH_SEP.'mysql'.PATH_SEP); + define( 'PATH_RBAC_MYSQL_DATA', PATH_RBAC_CORE . 'data' . PATH_SEP.'mysql'.PATH_SEP); + + define( 'FILE_PATHS_INSTALLED', PATH_CORE . 'config' . PATH_SEP . 'paths_installed.php' ); + +//************ include Gulliver Class ************** + require_once( PATH_GULLIVER . PATH_SEP . 'class.g.php'); + +//************ the Smarty Directories ************** + + if(file_exists(FILE_PATHS_INSTALLED)) { + //parsing for old definitions in the compiled path constant + $tmp = file_get_contents(FILE_PATHS_INSTALLED); + if( strpos($tmp, 'PATH_OUTTRUNK') !== false ){ + @file_put_contents(FILE_PATHS_INSTALLED, str_replace('PATH_OUTTRUNK', 'PATH_DATA', $tmp)); + } + + require_once ( FILE_PATHS_INSTALLED ); + + // TODO: This path defines where to save temporal data, similar to $_SESSION. + define( 'PATH_TEMPORAL', PATH_C . 'dynEditor/'); + + define( 'PATH_DB', PATH_DATA . 'sites' . PATH_SEP ); + define( 'PATH_SMARTY_C', PATH_C . 'smarty' . PATH_SEP . 'c' ); + define( 'PATH_SMARTY_CACHE', PATH_C . 'smarty' . PATH_SEP . 'cache' ); + if (!is_dir(PATH_SMARTY_C)) G::mk_dir(PATH_SMARTY_C); + if (!is_dir(PATH_SMARTY_CACHE)) G::mk_dir(PATH_SMARTY_CACHE); + } +//***************** set include path *********************** + set_include_path( + PATH_CORE . PATH_SEPARATOR . + PATH_THIRDPARTY . PATH_SEPARATOR . + PATH_THIRDPARTY . 'pear'. PATH_SEPARATOR . + PATH_RBAC_CORE . PATH_SEPARATOR . + get_include_path() + ); + +//******************* some global definitions, before it was the defines.php file ******** + +//***************** URL KEY ********************************************* + define("URL_KEY", 'c0l0s40pt1mu59r1m3' ); + +//************ Other definitions ************** + //web service timeout + define( 'TIMEOUT_RESPONSE', 100 ); + //to login like workflow system + define( 'APPLICATION_CODE', 'ProcessMaker' ); + + define ( 'MAIN_POFILE', 'processmaker'); + define ( 'PO_SYSTEM_VERSION', 'PM 4.0.1'); + +///************TimeZone Set***************// + if(!defined('TIME_ZONE')) { + define('TIME_ZONE', 'America/La_Paz'); + } + if (function_exists('date_default_timezone_set')) { + date_default_timezone_set(TIME_ZONE); + } + + $G_CONTENT = NULL; + $G_MESSAGE = ""; + $G_MESSAGE_TYPE = "info"; + $G_MENU_SELECTED = -1; + $G_MAIN_MENU = "default"; + + //remove this, when migrate to Propel +// define ( 'PEAR_DATABASE', 'mysql'); +// define ( 'ENABLE_ENCRYPT', 'no' ); +// define('DB_ERROR_BACKTRACE', TRUE); + +//************ Environment definitions ************** + define ( 'G_PRO_ENV', 'PRODUCTION' ); + define ( 'G_DEV_ENV', 'DEVELOPMENT' ); + define ( 'G_TEST_ENV', 'TEST' ); + +//********* Number of files per folder at PATH_UPLOAD (cases documents) ***** + define( 'APPLICATION_DOCUMENTS_PER_FOLDER', 1000 ); + +//********* Server of ProcessMaker Library ***** + define ( 'PML_SERVER' , 'http://library.processmaker.com' ); + define ( 'PML_WSDL_URL' , PML_SERVER . '/syspmLibrary/en/green/services/wsdl'); + define ( 'PML_UPLOAD_URL', PML_SERVER . '/syspmLibrary/en/green/services/uploadProcess'); + define ( 'PML_DOWNLOAD_URL', PML_SERVER . '/syspmLibrary/en/green/services/download'); + diff --git a/workflow/engine/config/propel.ini b/workflow/engine/config/propel.ini new file mode 100644 index 000000000..336883fa0 --- /dev/null +++ b/workflow/engine/config/propel.ini @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = mssql +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/wf_os + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/sql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/workflow/engine/config/propel.mssql.ini b/workflow/engine/config/propel.mssql.ini new file mode 100644 index 000000000..0e9207237 --- /dev/null +++ b/workflow/engine/config/propel.mssql.ini @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = mssql +propel.database.createUrl = mssql://root@localhost/ +propel.database.url = mssql://root@localhost/wf_os + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/mssql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/workflow/engine/config/propel.mysql.ini b/workflow/engine/config/propel.mysql.ini new file mode 100644 index 000000000..35123d0c5 --- /dev/null +++ b/workflow/engine/config/propel.mysql.ini @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = mysql +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/base_workflow + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/mysql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/workflow/engine/config/propel.oracle.ini b/workflow/engine/config/propel.oracle.ini new file mode 100644 index 000000000..1726d60bc --- /dev/null +++ b/workflow/engine/config/propel.oracle.ini @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = oracle +propel.database.createUrl = oracle://root@localhost/ +propel.database.url = oracle://root@localhost/wf_os + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/oracle +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/workflow/engine/config/propel.pgsql.ini b/workflow/engine/config/propel.pgsql.ini new file mode 100644 index 000000000..070fc8c14 --- /dev/null +++ b/workflow/engine/config/propel.pgsql.ini @@ -0,0 +1,45 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = opensource +propel.database = pgsql +propel.database.createUrl = pgsql://root@localhost/ +propel.database.url = pgsql://root@localhost/wf_os + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}config +propel.phpconf.dir = ${propel.output.dir}config +propel.sql.dir = ${propel.output.dir}data/pgsql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schema +propel.datadump.mapper.from = *schema.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false +propel.disableIdentifierQuoting=true diff --git a/workflow/engine/config/properties.ini b/workflow/engine/config/properties.ini new file mode 100644 index 000000000..86efbe478 --- /dev/null +++ b/workflow/engine/config/properties.ini @@ -0,0 +1,2 @@ +[gulliver] + name=opensource diff --git a/workflow/engine/config/rbac.ini b/workflow/engine/config/rbac.ini new file mode 100644 index 000000000..4e15fac7d --- /dev/null +++ b/workflow/engine/config/rbac.ini @@ -0,0 +1,44 @@ +propel.targetPackage = classes.model +propel.packageObjectModel = true +propel.project = RBAC +propel.database = mysql +propel.database.createUrl = mysql://root@localhost/ +propel.database.url = mysql://root@localhost/rbac_os + +propel.addGenericAccessors = true +propel.addGenericMutators = true +propel.addTimeStamp = false + +propel.schema.validate = false + +; directories +propel.home = . +propel.output.dir = . +propel.schema.dir = ${propel.output.dir}config +propel.conf.dir = ${propel.output.dir}/config +propel.phpconf.dir = ${propel.output.dir}/config +propel.sql.dir = ${propel.output.dir}/data/sql +propel.runtime.conf.file = runtime-conf.xml +propel.php.dir = ${propel.output.dir} +propel.default.schema.basename = schemaRBAC +propel.datadump.mapper.from = *schemaRBAC.xml +propel.datadump.mapper.to = *data.xml + +; builder settings +;_propel.builder.peer.class = addon.propel.builder.SfPeerBuilder +;propel.builder.object.class = addon.propel.builder.SfObjectBuilder + +;propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder +;propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder +;propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder +;propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder +propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder +propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder +propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder +propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder +propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder + +propel.builder.addIncludes = false +propel.builder.addComments = false + +propel.builder.addBehaviors = false diff --git a/workflow/engine/config/schema.xml b/workflow/engine/config/schema.xml new file mode 100644 index 000000000..1707ce2ce --- /dev/null +++ b/workflow/engine/config/schema.xml @@ -0,0 +1,7753 @@ +<?xml version="1.0" encoding="utf-8"?> +<database name="workflow"> + <table name="APPLICATION"> + <vendor type="mysql"> + <parameter name="Name" value="APPLICATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="The application"/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value="UID to Application"/> + </vendor> + </column> + <column name="APP_NUMBER" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_NUMBER"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PARENT" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_STATUS" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_STATUS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PROC_STATUS" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_PROC_STATUS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PROC_CODE" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_PROC_CODE"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PARALLEL" type="VARCHAR" size="32" required="true" default="NO"> + <vendor type="mysql"> + <parameter name="Field" value="APP_PARALLEL"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="NO"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_INIT_USER" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_INIT_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_CUR_USER" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_CUR_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_INIT_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_INIT_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_FINISH_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_FINISH_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UPDATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DATA" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DATA"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PIN" type="VARCHAR" size="32" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_PIN"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="APP_STATUS"> + <rule name="validValues" value="DRAFT|TO_DO|PAUSED|COMPLETED|CANCELLED" message="Please select a valid status." /> + </validator> + <index name="indexApp"> + <index-column name="PRO_UID"/> + <index-column name="APP_STATUS"/> + <index-column name="APP_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="APPLICATION"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexApp"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="APP_DELEGATION"> + <vendor type="mysql"> + <parameter name="Name" value="APP_DELEGATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Delegation a task to user"/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_PREVIOUS" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_PREVIOUS"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_TYPE" type="VARCHAR" size="32" required="true" default="NORMAL"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_TYPE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="NORMAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_THREAD" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_THREAD"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_THREAD_STATUS" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_THREAD_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_PRIORITY" type="VARCHAR" size="32" required="true" default="3"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_PRIORITY"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="3"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELEGATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELEGATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INIT_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_INIT_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_TASK_DUE_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_TASK_DUE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_FINISH_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_FINISH_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_QUEUE_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_QUEUE_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELAY_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELAY_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_STARTED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_STARTED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_FINISHED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_FINISHED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELAYED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELAYED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DATA" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DATA"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_OVERDUE_PERCENTAGE" type="DOUBLE" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_OVERDUE_PERCENTAGE"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <validator column="DEL_TYPE"> + <rule name="validValues" value="NORMAL|PARALLEL" message="Please select a valid status." /> + </validator> + <validator column="DEL_PRIORITY"> + <rule name="validValues" value="1|2|3|4|5" message="Please select a valid Priority." /> + </validator> + <validator column="DEL_THREAD_STATUS"> + <rule name="validValues" value="CLOSED|OPEN|PAUSED" message="Please select a valid status." /> + </validator> + </table> + <table name="APP_DOCUMENT"> + <vendor type="mysql"> + <parameter name="Name" value="APP_DOCUMENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="26"/> + <parameter name="Avg_row_length" value="69"/> + <parameter name="Data_length" value="2016"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="208"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 13:18:54"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Documents in an Application"/> + </vendor> + <column name="APP_DOC_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DOC_VERSION" type="INTEGER" required="true" primaryKey="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="DOC_VERSION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DOC_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DOC_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_TYPE" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_TYPE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_INDEX" type="INTEGER" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FOLDER_UID" type="VARCHAR" size="32" default="" > + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_PLUGIN" type="VARCHAR" size="150" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_PLUGIN"/> + <parameter name="Type" value="varchar(150)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_TAGS" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_TAGS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_STATUS" type="VARCHAR" size="32" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DOC_STATUS_DATE" type="TIMESTAMP" > + <vendor type="mysql"> + <parameter name="Field" value="APP_DOC_STATUS_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="APP_DOC_UID"> + <rule name="maxLength" value="32" message="Application Document UID can be no larger than ${value} in size" /> + <rule name="required" message="Application Document UID is required." /> + </validator> + <validator column="APP_UID"> + <rule name="maxLength" value="32" message="Application UID can be no larger than ${value} in size" /> + <rule name="required" message="Application UID is required." /> + </validator> + <validator column="DEL_INDEX"> + <rule name="minValue" value="1" message="Delegation Index can be major than 0" /> + <rule name="required" message="Delegation Index is required." /> + </validator> + <validator column="DOC_UID"> + <rule name="maxLength" value="32" message="Document UID can be no larger than ${value} in size" /> + <rule name="required" message="Document UID (building block) is required." /> + </validator> + <validator column="USR_UID"> + <rule name="maxLength" value="32" message="User UID can be no larger than ${value} in size" /> + <rule name="required" message="User UID is required." /> + </validator> + <validator column="APP_DOC_TYPE"> + <rule name="validValues" value="INPUT|OUTPUT|ATTACHED" message="Please select a valid document type." /> + <rule name="required" message="Application Document Type is required." /> + </validator> + <validator column="APP_DOC_CREATE_DATE"> + <rule name="required" message="Application Document Creation Date is required." /> + </validator> + <validator column="APP_DOC_STATUS"> + <rule name="validValues" value="ACTIVE|DELETED" message="Please select a valid document status (ACTIVE|DELETED)." /> + <rule name="required" message="Application Document Status is required." /> + </validator> + </table> + <table name="APP_MESSAGE" idMethod="native" > + <vendor type="mysql"> + <parameter name="Name" value="APP_MESSAGE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:21:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Messages in an Application"/> + </vendor> + <column name="APP_MSG_UID" type="VARCHAR" size="32" required="true" primaryKey="true" > + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="MSG_UID" type="VARCHAR" size="32"> + <vendor type="mysql"> + <parameter name="Field" value="MSG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_TYPE" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_TYPE"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_SUBJECT" type="VARCHAR" size="150" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_SUBJECT"/> + <parameter name="Type" value="varchar(150)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_FROM" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_FROM"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_TO" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_TO"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_BODY" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_BODY"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_CC" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_CC"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_BCC" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_BCC"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_TEMPLATE" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_TEMPLATE"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_STATUS" type="VARCHAR" size="20"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_STATUS"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_ATTACH" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_ATTACH"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_MSG_SEND_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_MSG_SEND_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="APP_OWNER"> + <vendor type="mysql"> + <parameter name="Name" value="APP_OWNER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:21:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OWN_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OWN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="CONFIGURATION"> + <vendor type="mysql"> + <parameter name="Name" value="CONFIGURATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="11"/> + <parameter name="Avg_row_length" value="615"/> + <parameter name="Data_length" value="6768"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-09 11:48:16"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Stores the users, processes and/or applications configuratio"/> + </vendor> + <column name="CFG_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CFG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OBJ_UID" type="VARCHAR" size="128" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OBJ_UID"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CFG_VALUE" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="CFG_VALUE"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="CONTENT"> + <vendor type="mysql"> + <parameter name="Name" value="CONTENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="373"/> + <parameter name="Avg_row_length" value="74"/> + <parameter name="Data_length" value="27748"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="16384"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="CON_CATEGORY" type="VARCHAR" size="30" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CON_CATEGORY"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CON_PARENT" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CON_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CON_ID" type="VARCHAR" size="100" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CON_ID"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CON_LANG" type="VARCHAR" size="10" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CON_LANG"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CON_VALUE" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="CON_VALUE"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="CON_LANG"> + <rule name="maxLength" value="5" message="Language can be no larger than ${value} in size" /> + <rule name="required" message="Language is required." /> + </validator> + <index name="indexUid"> + <index-column name="CON_ID"/> + <index-column name="CON_CATEGORY"/> + <index-column name="CON_LANG"/> + <vendor type="mysql"> + <parameter name="Table" value="CONTENT"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexUid"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="CONTENT"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="DEPARTMENT"> + <vendor type="mysql"> + <parameter name="Name" value="DEPARTMENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="13"/> + <parameter name="Avg_row_length" value="20"/> + <parameter name="Data_length" value="260"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="3072"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-05 17:31:33"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Departments"/> + </vendor> + <column name="DEP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_PARENT" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="MUL"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_MANAGER" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_MANAGER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_LOCATION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEP_LOCATION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_STATUS" type="VARCHAR" size="10" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="DEP_STATUS"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_REF_CODE" type="VARCHAR" size="50" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_REF_CODE"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_LDAP_DN" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_LDAP_DN"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="DEP_BYPARENT"> + <index-column name="DEP_PARENT"/> + <vendor type="mysql"> + <parameter name="Table" value="DEPARTMENT"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="DEP_BYPARENT"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="DEP_PARENT"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + <index name="BY_DEP_LDAP_DN"> + <index-column name="DEP_LDAP_DN"/> + <vendor type="mysql"> + <parameter name="Table" value="DEPARTMENT"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="BY_DEP_LDAP_DN"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="DEP_LDAP_DN"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="DYNAFORM"> + <vendor type="mysql"> + <parameter name="Name" value="DYNAFORM"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="19"/> + <parameter name="Avg_row_length" value="68"/> + <parameter name="Data_length" value="1292"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-05 13:42:41"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Forms required"/> + </vendor> + <column name="DYN_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DYN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DYN_TYPE" type="VARCHAR" size="20" required="true" default="xmlform"> + <vendor type="mysql"> + <parameter name="Field" value="DYN_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="xmlform"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DYN_FILENAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DYN_FILENAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="DYN_TYPE"> + <rule name="validValues" value="xmlform|grid" message="Please select a valid dynaform type." /> + </validator> + </table> + <table name="GROUPWF"> + <vendor type="mysql"> + <parameter name="Name" value="GROUPWF"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="4"/> + <parameter name="Avg_row_length" value="36"/> + <parameter name="Data_length" value="144"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 05:23:30"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="GRP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="GRP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="GRP_STATUS" type="CHAR" size="8" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="GRP_STATUS"/> + <parameter name="Type" value="char(8)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="GRP_STATUS"> + <rule name="validValues" value="ACTIVE|INACTIVE" message="Please select a valid status." /> + <rule name="required" message="Application Document UID is required." /> + </validator> + </table> + <table name="GROUP_USER"> + <vendor type="mysql"> + <parameter name="Name" value="GROUP_USER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="4"/> + <parameter name="Avg_row_length" value="48"/> + <parameter name="Data_length" value="192"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 05:23:39"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="GRP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="GRP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="GRP_UID"> + <rule name="maxLength" value="32" message="Group UID can be no larger than ${value} in size" /> + <rule name="required" message="Group UID is required." /> + </validator> + <validator column="USR_UID"> + <rule name="maxLength" value="32" message="User UID can be no larger than ${value} in size" /> + <rule name="required" message="User UID is required." /> + </validator> + </table> + <table name="HOLIDAY" idMethod="native"> + <vendor type="mysql"> + <parameter name="Name" value="HOLIDAY"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value="1"/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:21:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="HLD_UID" type="INTEGER" required="true" autoIncrement="true" primaryKey="true"> + <vendor type="mysql"> + <parameter name="Field" value="HLD_UID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value="auto_increment"/> + </vendor> + </column> + <column name="HLD_DATE" type="VARCHAR" size="10" required="true" default="0000-00-00"> + <vendor type="mysql"> + <parameter name="Field" value="HLD_DATE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0000-00-00"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="HLD_DESCRIPTION" type="VARCHAR" size="200" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="HLD_DESCRIPTION"/> + <parameter name="Type" value="varchar(200)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="INPUT_DOCUMENT"> + <vendor type="mysql"> + <parameter name="Name" value="INPUT_DOCUMENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="6"/> + <parameter name="Avg_row_length" value="56"/> + <parameter name="Data_length" value="336"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 08:00:36"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Documentation required"/> + </vendor> + <column name="INP_DOC_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_FORM_NEEDED" type="VARCHAR" size="20" required="true" default="REAL"> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_FORM_NEEDED"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="REAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_ORIGINAL" type="VARCHAR" size="20" required="true" default="COPY"> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_ORIGINAL"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="COPY"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_PUBLISHED" type="VARCHAR" size="20" required="true" default="PRIVATE"> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_PUBLISHED"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="PRIVATE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_VERSIONING" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_VERSIONING"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_DESTINATION_PATH" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_DESTINATION_PATH"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="INP_DOC_TAGS" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="INP_DOC_TAGS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="INP_DOC_UID"> + <rule name="maxLength" value="32" message="Input Document UID can be no larger than ${value} in size" /> + <rule name="required" message="Input Document UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="INP_DOC_FORM_NEEDED"> + <rule name="validValues" value="VIRTUAL|REAL|VREAL" message="Please select a valid document format." /> + <rule name="required" message="Document format is required." /> + </validator> + <validator column="INP_DOC_ORIGINAL"> + <rule name="validValues" value="COPY|ORIGINAL|COPYLEGAL|FINAL" message="Please select a valid document format type." /> + <rule name="required" message="Document format type is required." /> + </validator> + <validator column="INP_DOC_PUBLISHED"> + <rule name="validValues" value="PUBLIC|PRIVATE" message="Please select a valid document access." /> + <rule name="required" message="Document access is required." /> + </validator> + </table> + <table name="ISO_COUNTRY"> + <vendor type="mysql"> + <parameter name="Name" value="ISO_COUNTRY"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="243"/> + <parameter name="Avg_row_length" value="26"/> + <parameter name="Data_length" value="6424"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:53:28"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="IC_UID" type="VARCHAR" size="2" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IC_UID"/> + <parameter name="Type" value="varchar(2)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IC_NAME" type="VARCHAR" size="255"> + <vendor type="mysql"> + <parameter name="Field" value="IC_NAME"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IC_SORT_ORDER" type="VARCHAR" size="255"> + <vendor type="mysql"> + <parameter name="Field" value="IC_SORT_ORDER"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="ISO_LOCATION"> + <vendor type="mysql"> + <parameter name="Name" value="ISO_LOCATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="54672"/> + <parameter name="Avg_row_length" value="35"/> + <parameter name="Data_length" value="1954904"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="478208"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:54:30"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="IC_UID" type="VARCHAR" size="2" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IC_UID"/> + <parameter name="Type" value="varchar(2)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IL_UID" type="VARCHAR" size="5" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IL_UID"/> + <parameter name="Type" value="varchar(5)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IL_NAME" type="VARCHAR" size="255"> + <vendor type="mysql"> + <parameter name="Field" value="IL_NAME"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IL_NORMAL_NAME" type="VARCHAR" size="255"> + <vendor type="mysql"> + <parameter name="Field" value="IL_NORMAL_NAME"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IS_UID" type="VARCHAR" size="4"> + <vendor type="mysql"> + <parameter name="Field" value="IS_UID"/> + <parameter name="Type" value="varchar(4)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="ISO_SUBDIVISION"> + <vendor type="mysql"> + <parameter name="Name" value="ISO_SUBDIVISION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="971"/> + <parameter name="Avg_row_length" value="24"/> + <parameter name="Data_length" value="24028"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="11264"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:54:31"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="IC_UID" type="VARCHAR" size="2" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IC_UID"/> + <parameter name="Type" value="varchar(2)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IS_UID" type="VARCHAR" size="4" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IS_UID"/> + <parameter name="Type" value="varchar(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="IS_NAME" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="IS_NAME"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="LANGUAGE"> + <vendor type="mysql"> + <parameter name="Name" value="LANGUAGE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="136"/> + <parameter name="Avg_row_length" value="37"/> + <parameter name="Data_length" value="5096"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:31:47"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="LAN_ID" type="VARCHAR" size="4" required="true" default="" primaryKey="true"> + <vendor type="mysql"> + <parameter name="Field" value="LAN_ID"/> + <parameter name="Type" value="varchar(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_NAME" type="VARCHAR" size="30" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LAN_NAME"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_NATIVE_NAME" type="VARCHAR" size="30" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LAN_NATIVE_NAME"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_DIRECTION" type="CHAR" size="1" required="true" default="L"> + <vendor type="mysql"> + <parameter name="Field" value="LAN_DIRECTION"/> + <parameter name="Type" value="char(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="L"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_WEIGHT" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="LAN_WEIGHT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_ENABLED" type="CHAR" size="1" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="LAN_ENABLED"/> + <parameter name="Type" value="char(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LAN_CALENDAR" type="VARCHAR" size="30" required="true" default="GREGORIAN"> + <vendor type="mysql"> + <parameter name="Field" value="LAN_CALENDAR"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="GREGORIAN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="LAN_DIRECTION"> + <rule name="validValues" value="L|R" message="Please select a valid Language Direccion." /> + <rule name="required" message="Document access is required." /> + </validator> + <validator column="LAN_ENABLED"> + <rule name="validValues" value="1|0" message="Please select a valid Language Direccion." /> + <rule name="required" message="Document access is required." /> + </validator> + </table> + <table name="LEXICO"> + <vendor type="mysql"> + <parameter name="Name" value="LEXICO"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:21:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="LEXICOS, una tabla que contiene tablas"/> + </vendor> + <column name="LEX_TOPIC" type="VARCHAR" size="64" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LEX_TOPIC"/> + <parameter name="Type" value="varchar(64)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LEX_KEY" type="VARCHAR" size="128" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LEX_KEY"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LEX_VALUE" type="VARCHAR" size="128" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LEX_VALUE"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LEX_CAPTION" type="VARCHAR" size="128" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LEX_CAPTION"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="OUTPUT_DOCUMENT"> + <vendor type="mysql"> + <parameter name="Name" value="OUTPUT_DOCUMENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="4"/> + <parameter name="Avg_row_length" value="36"/> + <parameter name="Data_length" value="144"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 08:01:52"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="OUT_DOC_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_LANDSCAPE" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_LANDSCAPE"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_MEDIA" type="VARCHAR" size="10" required="true" default="Letter"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_MEDIA"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="Letter"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_LEFT_MARGIN" type="INTEGER" default="30"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_LEFT_MARGIN"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_RIGHT_MARGIN" type="INTEGER" default="15"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_RIGHT_MARGIN"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_TOP_MARGIN" type="INTEGER" default="15"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_TOP_MARGIN"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_BOTTOM_MARGIN" type="INTEGER" default="15"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_BOTTOM_MARGIN"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_GENERATE" type="VARCHAR" size="10" required="true" default="BOTH"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_GENERATE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="BOTH"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_TYPE" type="VARCHAR" size="32" required="true" default="HTML"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_TYPE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="HTML"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_CURRENT_REVISION" type="INTEGER" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_CURRENT_REVISION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_FIELD_MAPPING" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_FIELD_MAPPING"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_VERSIONING" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_VERSIONING"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_DESTINATION_PATH" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_DESTINATION_PATH"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OUT_DOC_TAGS" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="OUT_DOC_TAGS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="OUT_DOC_UID"> + <rule name="maxLength" value="32" message="Output Document UID can be no larger than ${value} in size" /> + <rule name="required" message="Output Document UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="OUT_DOC_GENERATE"> + <rule name="validValues" value="BOTH|DOC|PDF" message="Please select a outputdocument." /> + </validator> + <validator column="OUT_DOC_TYPE"> + <rule name="validValues" value="HTML|ITEXT|JRXML|ACROFORM" message="Please select a valid Output Document Type." /> + </validator> + </table> + <table name="PROCESS"> + <vendor type="mysql"> + <parameter name="Name" value="PROCESS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="2"/> + <parameter name="Avg_row_length" value="68"/> + <parameter name="Data_length" value="328"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="192"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 10:38:26"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Store process Information"/> + </vendor> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_PARENT" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TIME" type="DOUBLE" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TIME"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TIMEUNIT" type="VARCHAR" size="20" required="true" null="yes" default="DAYS"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TIMEUNIT"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="DAYS"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_STATUS" type="VARCHAR" size="20" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_STATUS"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TYPE_DAY" type="CHAR" size="1" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TYPE_DAY"/> + <parameter name="Type" value="char(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TYPE" type="VARCHAR" size="20" required="true" default="NORMAL"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="NORMAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_ASSIGNMENT" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_ASSIGNMENT"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_SHOW_MAP" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_SHOW_MAP"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_SHOW_MESSAGE" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_SHOW_MESSAGE"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_SHOW_DELEGATE" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_SHOW_DELEGATE"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_SHOW_DYNAFORM" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_SHOW_DYNAFORM"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_CATEGORY" type="VARCHAR" size="48" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_CATEGORY"/> + <parameter name="Type" value="varchar(48)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_SUB_CATEGORY" type="VARCHAR" size="48" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_SUB_CATEGORY"/> + <parameter name="Type" value="varchar(48)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_INDUSTRY" type="INTEGER" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_INDUSTRY"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UPDATE_DATE" type="TIMESTAMP" required='false' > + <vendor type="mysql"> + <parameter name="Field" value="PRO_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_CREATE_USER" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_CREATE_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_HEIGHT" type="INTEGER" required="true" default="5000"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_HEIGHT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="5000"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_WIDTH" type="INTEGER" required="true" default="10000"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_WIDTH"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="10000"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TITLE_X" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TITLE_X"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_TITLE_Y" type="INTEGER" required="true" default="6"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_TITLE_Y"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="6"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_DEBUG" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_DEBUG"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="PRO_TIMEUNIT"> + <rule name="validValues" value="WEEKS|MONTHS|DAYS|HOURS|MINUTES" message="Please select a valid Time Unit." /> + </validator> + <validator column="PRO_STATUS"> + <rule name="validValues" value="ACTIVE|INACTIVE|DISABLED" message="Please select a valid Process Status." /> + </validator> + <validator column="PRO_TYPE"> + <rule name="validValues" value="NORMAL" message="Please select a valid Process Type." /> + </validator> + <validator column="PRO_ASSIGNMENT"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid Process Assignment" /> + </validator> + </table> + <table name="PROCESS_OWNER"> + <vendor type="mysql"> + <parameter name="Name" value="PROCESS_OWNER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-04 11:21:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="OWN_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OWN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="REPORT_TABLE"> + <vendor type="mysql"> + <parameter name="Name" value="REPORT_TABLE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-03-17 16:46:20"/> + <parameter name="Update_time" value="2008-03-17 16:46:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="REP_TAB_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_NAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_TYPE" type="VARCHAR" size="6" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_TYPE"/> + <parameter name="Type" value="varchar(6)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_GRID" type="VARCHAR" size="150" required="false" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_GRID"/> + <parameter name="Type" value="varchar(150)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_CONNECTION" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_CONNECTION"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_STATUS" type="CHAR" size="8" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_STATUS"/> + <parameter name="Type" value="char(8)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="REP_TAB_UID"> + <rule name="maxLength" value="32" message="Report table UID can be no larger than ${value} in size" /> + <rule name="required" message="Report table UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="REP_TAB_NAME"> + <rule name="maxLength" value="100" message="Report table name can be no larger than ${value} in size" /> + <rule name="required" message="Report table name is required." /> + </validator> + <validator column="REP_TAB_TYPE"> + <rule name="validValues" value="NORMAL|GRID" message="Please select a valid type." /> + <rule name="required" message="Report table type is required." /> + </validator> + <validator column="REP_TAB_CONNECTION"> + <rule name="maxLength" value="10" message="Report table connection can be no larger than ${value} in size" /> + <rule name="required" message="Report table connection is required." /> + </validator> + <!--<validator column="REP_TAB_CREATE_DATE"> + <rule name="required" message="Report table creation date is required." /> + </validator>--> + <validator column="REP_TAB_STATUS"> + <rule name="validValues" value="ACTIVE|INACTIVE" message="Please select a valid status." /> + <rule name="required" message="Report table status is required." /> + </validator> + </table> + <table name="REPORT_VAR"> + <vendor type="mysql"> + <parameter name="Name" value="REPORT_VAR"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-03-17 16:48:30"/> + <parameter name="Update_time" value="2008-03-17 16:48:30"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="REP_VAR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_VAR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_TAB_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_TAB_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_VAR_NAME" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_VAR_NAME"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="REP_VAR_TYPE" type="VARCHAR" size="20" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="REP_VAR_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="REP_VAR_UID"> + <rule name="maxLength" value="32" message="Report variable UID can be no larger than ${value} in size" /> + <rule name="required" message="Report variable UID is required." /> + </validator> + <validator column="REP_TAB_UID"> + <rule name="maxLength" value="32" message="Report table UID can be no larger than ${value} in size" /> + <rule name="required" message="Report variable UID is required." /> + </validator> + <validator column="REP_VAR_NAME"> + <rule name="maxLength" value="255" message="Report variable name can be no larger than ${value} in size" /> + <rule name="required" message="Report variable name is required." /> + </validator> + <validator column="REP_VAR_TYPE"> + <rule name="maxLength" value="20" message="Report variable type can be no larger than ${value} in size" /> + <rule name="required" message="Report variable type is required." /> + </validator> + </table> + <table name="ROUTE"> + <vendor type="mysql"> + <parameter name="Name" value="ROUTE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="14"/> + <parameter name="Avg_row_length" value="117"/> + <parameter name="Data_length" value="1644"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 07:57:41"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Differents flows for a flow in business process"/> + </vendor> + <column name="ROU_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ROU_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_PARENT" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_NEXT_TASK" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_NEXT_TASK"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_CASE" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_CASE"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_TYPE" type="VARCHAR" size="25" required="true" default="SEQUENTIAL"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_TYPE"/> + <parameter name="Type" value="varchar(25)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="SEQUENTIAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_CONDITION" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ROU_CONDITION"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_TO_LAST_USER" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_TO_LAST_USER"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_OPTIONAL" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_OPTIONAL"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_SEND_EMAIL" type="VARCHAR" size="20" required="true" default="TRUE"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_SEND_EMAIL"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="TRUE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_SOURCEANCHOR" type="INTEGER" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_SOURCEANCHOR"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ROU_TARGETANCHOR" type="INTEGER" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ROU_TARGETANCHOR"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="ROU_UID"> + <rule name="maxLength" value="32" message="Route UID can be no larger than ${value} in size" /> + <rule name="required" message="Route UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="TAS_UID"> + <rule name="maxLength" value="32" message="Task UID can be no larger than ${value} in size" /> + <rule name="required" message="Task UID is required." /> + </validator> + <validator column="ROU_NEXT_TASK"> + <rule name="required" message="Next Task UID is required." /> + </validator> + <validator column="ROU_TYPE"> + <rule name="validValues" value="SEQUENTIAL|EVALUATE|SELECT|PARALLEL|PARALLEL-BY-EVALUATION|SEC-JOIN" message="Please select a valid Route Type." /> + <rule name="required" message="Route type is required." /> + </validator> + <validator column="ROU_TO_LAST_USER"> + <rule name="validValues" value="FALSE|TRUE" message="Please select a valid value for ROU_TO_LAST_USER ." /> + </validator> + <validator column="ROU_OPTIONAL"> + <rule name="validValues" value="FALSE|TRUE" message="Please select a valid value for ROU_OPTIONAL ." /> + </validator> + <validator column="ROU_SEND_EMAIL"> + <rule name="validValues" value="FALSE|TRUE" message="Please select a valid value for ROU_SEND_EMAIL." /> + </validator> + </table> + <table name="STEP"> + <vendor type="mysql"> + <parameter name="Name" value="STEP"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="18"/> + <parameter name="Avg_row_length" value="106"/> + <parameter name="Data_length" value="1956"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="40"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 09:05:02"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="STEP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="STEP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_TYPE_OBJ" type="VARCHAR" size="20" required="true" default="DYNAFORM"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_TYPE_OBJ"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="DYNAFORM"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_UID_OBJ" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_UID_OBJ"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_CONDITION" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_CONDITION"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_POSITION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_POSITION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_MODE" type="VARCHAR" size="10" required="false" default="EDIT"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_MODE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="EDIT"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="STEP_TYPE_OBJ"> + <rule name="validValues" value="DYNAFORM|INPUT_DOCUMENT|MESSAGE|OUTPUT_DOCUMENT|EXTERNAL" message="Please select a valid value for STEP_TYPE_OBJ." /> + </validator> + </table> + <table name="STEP_TRIGGER"> + <vendor type="mysql"> + <parameter name="Name" value="STEP_TRIGGER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="19"/> + <parameter name="Avg_row_length" value="66"/> + <parameter name="Data_length" value="1268"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="3072"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 15:20:26"/> + <parameter name="Update_time" value="2007-12-07 09:55:06"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="STEP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="STEP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRI_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRI_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ST_TYPE" type="VARCHAR" size="20" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ST_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ST_CONDITION" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ST_CONDITION"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ST_POSITION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ST_POSITION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="ST_TYPE"> + <rule name="validValues" value="BEFORE|AFTER" message="Please select a valid value for Trigger Type ST_TYPE." /> + </validator> + </table> + <table name="SWIMLANES_ELEMENTS"> + <vendor type="mysql"> + <parameter name="Name" value="SWIMLANES_ELEMENTS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="10"/> + <parameter name="Avg_row_length" value="43"/> + <parameter name="Data_length" value="436"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 10:38:35"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="SWI_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SWI_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SWI_TYPE" type="VARCHAR" size="20" required="true" default="LINE"> + <vendor type="mysql"> + <parameter name="Field" value="SWI_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="LINE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SWI_X" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SWI_X"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SWI_Y" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SWI_Y"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="SWI_UID"> + <rule name="maxLength" value="32" message="Swimlane Element UID can be no larger than ${value} in size" /> + <rule name="required" message="Swimlane Element UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="SWI_TYPE"> + <rule name="validValues" value="LINE|TEXT" message="Please select a valid Swimlane Element type." /> + <rule name="required" message="Swimlane Element type is required." /> + </validator> + </table> + <table name="TASK"> + <vendor type="mysql"> + <parameter name="Name" value="TASK"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="11"/> + <parameter name="Avg_row_length" value="220"/> + <parameter name="Data_length" value="2428"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 08:12:21"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Task of workflow"/> + </vendor> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TYPE" type="VARCHAR" size="20" required="true" default="NORMAL"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="NORMAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_DURATION" type="DOUBLE" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_DELAY_TYPE" type="VARCHAR" size="30" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_DELAY_TYPE"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TEMPORIZER" type="DOUBLE" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TEMPORIZER"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TYPE_DAY" type="CHAR" size="1" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TYPE_DAY"/> + <parameter name="Type" value="char(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TIMEUNIT" type="VARCHAR" size="20" required="true" default="DAYS"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TIMEUNIT"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="DAYS"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_ALERT" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_ALERT"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_PRIORITY_VARIABLE" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_PRIORITY_VARIABLE"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_ASSIGN_TYPE" type="VARCHAR" size="30" required="true" default="BALANCED"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_ASSIGN_TYPE"/> + <parameter name="Type" value="varchar(30)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="BALANCED"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_ASSIGN_VARIABLE" type="VARCHAR" size="100" required="true" default="@@SYS_NEXT_USER_TO_BE_ASSIGNED"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_ASSIGN_VARIABLE"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="@@SYS_NEXT_USER_TO_BE_ASSIGNED"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_ASSIGN_LOCATION" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_ASSIGN_LOCATION"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_ASSIGN_LOCATION_ADHOC" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_ASSIGN_LOCATION_ADHOC"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TRANSFER_FLY" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TRANSFER_FLY"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_LAST_ASSIGNED" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_LAST_ASSIGNED"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_USER" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_CAN_UPLOAD" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_CAN_UPLOAD"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_VIEW_UPLOAD" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_VIEW_UPLOAD"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_VIEW_ADDITIONAL_DOCUMENTATION" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_VIEW_ADDITIONAL_DOCUMENTATION"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_CAN_CANCEL" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_CAN_CANCEL"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_OWNER_APP" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_OWNER_APP"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STG_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="STG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_CAN_PAUSE" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_CAN_PAUSE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_CAN_SEND_MESSAGE" type="VARCHAR" size="20" required="true" default="TRUE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_CAN_SEND_MESSAGE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="TRUE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_CAN_DELETE_DOCS" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_CAN_DELETE_DOCS"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_SELF_SERVICE" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_SELF_SERVICE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_START" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_START"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_TO_LAST_USER" type="VARCHAR" size="20" required="true" default="FALSE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_TO_LAST_USER"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="FALSE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_SEND_LAST_EMAIL" type="VARCHAR" size="20" required="true" default="TRUE"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_SEND_LAST_EMAIL"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="TRUE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_DERIVATION" type="VARCHAR" size="100" required="true" default="NORMAL"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_DERIVATION"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="NORMAL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_POSX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_POSX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_POSY" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_POSY"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_COLOR" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_COLOR"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="TAS_TYPE"> + <rule name="validValues" value="NORMAL|ADHOC|SUBPROCESS" message="Please select a valid value for TAS_TYPE." /> + </validator> + <validator column="TAS_TIMEUNIT"> + <rule name="validValues" value="MINUTES|HOURS|DAYS|WEEKS|MONTHS" message="Please select a valid value for TAS_TIMEUNIT." /> + </validator> + <validator column="TAS_ALERT"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_ALERT." /> + </validator> + <validator column="TAS_ASSIGN_TYPE"> + <rule name="validValues" value="BALANCED|MANUAL|EVALUATE|REPORT_TO|SELF_SERVICE" message="Please select a valid value for TAS_ASSIGN_TYPE." /> + </validator> + <validator column="TAS_ASSIGN_LOCATION"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_ASSIGN_LOCATION." /> + </validator> + <validator column="TAS_ASSIGN_LOCATION_ADHOC"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_ASSIGN_LOCATION_ADHOC." /> + </validator> + <validator column="TAS_TRANSFER_FLY"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_TRANSFER_FLY." /> + </validator> + <validator column="TAS_CAN_UPLOAD"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_CAN_UPLOAD." /> + </validator> + <validator column="TAS_VIEW_UPLOAD"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_VIEW_UPLOAD." /> + </validator> + <validator column="TAS_VIEW_ADDITIONAL_DOCUMENTATION"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_VIEW_ADDITIONAL_DOCUMENTATION." /> + </validator> + <validator column="TAS_CAN_CANCEL"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_CAN_CANCEL." /> + </validator> + <validator column="TAS_CAN_PAUSE"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_CAN_PAUSE." /> + </validator> + <validator column="TAS_CAN_SEND_MESSAGE"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_CAN_SEND_MESSAGE." /> + </validator> + <validator column="TAS_CAN_DELETE_DOCS"> + <rule name="validValues" value="TRUE|VIEW|FALSE" message="Please select a valid value for TAS_CAN_DELETE_DOCS." /> + </validator> + <validator column="TAS_SELF_SERVICE"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_SELF_SERVICE." /> + </validator> + <validator column="TAS_START"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_START." /> + </validator> + <validator column="TAS_TO_LAST_USER"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_TO_LAST_USER." /> + </validator> + <validator column="TAS_SEND_LAST_EMAIL"> + <rule name="validValues" value="TRUE|FALSE" message="Please select a valid value for TAS_SEND_LAST_EMAIL." /> + </validator> + <validator column="TAS_DERIVATION"> + <rule name="validValues" value="NORMAL|FAST|AUTOMATIC" message="Please select a valid value for TAS_DERIVATION." /> + </validator> + </table> + <table name="TASK_USER"> + <vendor type="mysql"> + <parameter name="Name" value="TASK_USER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="10"/> + <parameter name="Avg_row_length" value="47"/> + <parameter name="Data_length" value="472"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-05 13:41:58"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TU_TYPE" type="INTEGER" required="true" primaryKey="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="TU_TYPE"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TU_RELATION" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TU_RELATION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="TAS_UID"> + <rule name="maxLength" value="32" message="Task UID can be no larger than ${value} in size" /> + <rule name="required" message="Task UID is required." /> + </validator> + <validator column="USR_UID"> + <rule name="maxLength" value="32" message="User UID can be no larger than ${value} in size" /> + <rule name="required" message="User UID is required." /> + </validator> + <validator column="TU_TYPE"> + <rule name="validValues" value="1|2" message="Please select a valid type." /> + <rule name="required" message="Type is required." /> + </validator> + <validator column="TU_RELATION"> + <rule name="validValues" value="1|2" message="Please select a valid relation." /> + <rule name="required" message="Relation is required." /> + </validator> + </table> + <table name="TRANSLATION"> + <vendor type="mysql"> + <parameter name="Name" value="TRANSLATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="121"/> + <parameter name="Avg_row_length" value="46"/> + <parameter name="Data_length" value="5572"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="4096"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-09 13:22:56"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="TRN_CATEGORY" type="VARCHAR" size="100" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRN_CATEGORY"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRN_ID" type="VARCHAR" size="100" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRN_ID"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRN_LANG" type="VARCHAR" size="10" required="true" primaryKey="true" default="en"> + <vendor type="mysql"> + <parameter name="Field" value="TRN_LANG"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="en"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRN_VALUE" type="VARCHAR" size="200" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRN_VALUE"/> + <parameter name="Type" value="varchar(200)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="TRN_CATEGORY"> + <rule name="maxLength" value="100" message="Category can be no larger than ${value} in size" /> + <rule name="required" message="Category is required." /> + </validator> + <validator column="TRN_ID"> + <rule name="maxLength" value="100" message="ID can be no larger than ${value} in size" /> + <rule name="required" message="ID is required." /> + </validator> + <validator column="TRN_LANG"> + <rule name="maxLength" value="5" message="Language can be no larger than ${value} in size" /> + <rule name="required" message="Language is required." /> + </validator> + <validator column="TRN_VALUE"> + <rule name="maxLength" value="200" message="Value can be no larger than ${value} in size" /> + <rule name="required" message="Value is required." /> + </validator> + </table> + <table name="TRIGGERS"> + <vendor type="mysql"> + <parameter name="Name" value="TRIGGERS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="17"/> + <parameter name="Avg_row_length" value="164"/> + <parameter name="Data_length" value="2792"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:21:20"/> + <parameter name="Update_time" value="2007-12-06 14:52:20"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="TRI_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRI_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRI_TYPE" type="VARCHAR" size="20" required="true" default="SCRIPT"> + <vendor type="mysql"> + <parameter name="Field" value="TRI_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="SCRIPT"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRI_WEBBOT" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="TRI_WEBBOT"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRI_PARAM" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="TRI_PARAM"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="TRI_TYPE"> + <rule name="validValues" value="WEBBOT|SCRIPT" message="Please select a valid type." /> + <rule name="required" message="Type is required." /> + </validator> + </table> + <table name="USERS"> + <vendor type="mysql"> + <parameter name="Name" value="USERS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="9"/> + <parameter name="Avg_row_length" value="158"/> + <parameter name="Data_length" value="1428"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-04 11:47:46"/> + <parameter name="Update_time" value="2007-12-05 17:36:55"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Users"/> + </vendor> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_USERNAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_USERNAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_PASSWORD" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_PASSWORD"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_FIRSTNAME" type="VARCHAR" size="50" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_FIRSTNAME"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_LASTNAME" type="VARCHAR" size="50" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_LASTNAME"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_EMAIL" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_EMAIL"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_DUE_DATE" type="DATE" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="USR_DUE_DATE"/> + <parameter name="Type" value="date"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="USR_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UPDATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="USR_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_STATUS" type="VARCHAR" size="32" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="USR_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_COUNTRY" type="VARCHAR" size="3" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_COUNTRY"/> + <parameter name="Type" value="varchar(3)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_CITY" type="VARCHAR" size="3" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_CITY"/> + <parameter name="Type" value="varchar(3)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_LOCATION" type="VARCHAR" size="3" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_LOCATION"/> + <parameter name="Type" value="varchar(3)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_ADDRESS" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_ADDRESS"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_PHONE" type="VARCHAR" size="24" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_PHONE"/> + <parameter name="Type" value="varchar(24)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_FAX" type="VARCHAR" size="24" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_FAX"/> + <parameter name="Type" value="varchar(24)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_CELLULAR" type="VARCHAR" size="24" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_CELLULAR"/> + <parameter name="Type" value="varchar(24)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_ZIP_CODE" type="VARCHAR" size="16" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_ZIP_CODE"/> + <parameter name="Type" value="varchar(16)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEP_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DEP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_POSITION" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_POSITION"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_RESUME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_RESUME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_BIRTHDAY" type="DATE" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="USR_BIRTHDAY"/> + <parameter name="Type" value="date"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_ROLE" type="VARCHAR" size="32" default="PROCESSMAKER_ADMIN"> + <vendor type="mysql"> + <parameter name="Field" value="USR_ROLE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="PROCESSMAKER_ADMIN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="USR_REPORTS_TO" type="VARCHAR" size="32" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_REPORTS_TO"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="USR_REPLACED_BY" type="VARCHAR" size="32" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_REPLACED_BY"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="USR_STATUS"> + <rule name="validValues" value="ACTIVE|INACTIVE|VACATION|CLOSED" message="Please select a valid type." /> + <rule name="required" message="Type is required." /> + </validator> + </table> + + <table name="APP_THREAD"> + <vendor type="mysql"> + <parameter name="Name" value="APP_THREAD"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="APP_THREAD"/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_THREAD_INDEX" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_THREAD_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_THREAD_PARENT" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_THREAD_PARENT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_THREAD_STATUS" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="APP_THREAD_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <validator column="APP_THREAD_STATUS"> + <rule name="validValues" value="CLOSED|OPEN" message="Please select a valid status." /> + </validator> + </table> + <table name="APP_DELAY"> + <vendor type="mysql"> + <parameter name="Name" value="APP_DELAY"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-04-25 10:30:00"/> + <parameter name="Update_time" value="2008-04-25 10:30:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="APP_DELAY"/> + </vendor> + <column name="APP_DELAY_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_DELAY_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_THREAD_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_THREAD_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DEL_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_TYPE" type="VARCHAR" size="20" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_STATUS" type="VARCHAR" size="20" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_STATUS"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_NEXT_TASK" type="VARCHAR" size="32" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_NEXT_TASK"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DELEGATION_USER" type="VARCHAR" size="32" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DELEGATION_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_ENABLE_ACTION_USER" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_ENABLE_ACTION_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_ENABLE_ACTION_DATE" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="APP_ENABLE_ACTION_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DISABLE_ACTION_USER" type="VARCHAR" size="32" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_DISABLE_ACTION_USER"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DISABLE_ACTION_DATE" type="TIMESTAMP" > + <vendor type="mysql"> + <parameter name="Field" value="APP_DISABLE_ACTION_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_AUTOMATIC_DISABLED_DATE" type="TIMESTAMP" > + <vendor type="mysql"> + <parameter name="Field" value="APP_AUTOMATIC_DISABLED_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexAppDelay"> + <index-column name="PRO_UID"/> + <index-column name="APP_UID"/> + <index-column name="APP_THREAD_INDEX"/> + <index-column name="APP_DEL_INDEX"/> + <index-column name="APP_NEXT_TASK"/> + <index-column name="APP_DELEGATION_USER"/> + <index-column name="APP_DISABLE_ACTION_USER"/> + <vendor type="mysql"> + <parameter name="Table" value="APP_DELAY"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexAppDelay"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="PROCESS_USER"> + <vendor type="mysql"> + <parameter name="Name" value="PROCESS_USER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="10"/> + <parameter name="Avg_row_length" value="47"/> + <parameter name="Data_length" value="472"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-15-05 12:00:00"/> + <parameter name="Update_time" value="2008-15-05 12:00:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="PU_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PU_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PU_TYPE" type="VARCHAR" size="20" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PU_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="PU_UID"> + <rule name="maxLength" value="32" message="Process User UID can be no larger than ${value} in size" /> + <rule name="required" message="Process User UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="USR_UID"> + <rule name="maxLength" value="32" message="User UID can be no larger than ${value} in size" /> + <rule name="required" message="User UID is required." /> + </validator> + <validator column="PU_TYPE"> + <rule name="maxLength" value="20" message="Value can be no larger than ${value} in size" /> + <rule name="required" message="Value is required." /> + </validator> + </table> + <table name="SESSION"> + <vendor type="mysql"> + <parameter name="Name" value="SESSION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-04-25 10:30:00"/> + <parameter name="Update_time" value="2008-04-25 10:30:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="SESSION"/> + </vendor> + <column name="SES_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SES_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SES_STATUS" type="VARCHAR" size="16" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="SES_STATUS"/> + <parameter name="Type" value="varchar(16)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SES_REMOTE_IP" type="VARCHAR" size="32" required="true" default="0.0.0.0"> + <vendor type="mysql"> + <parameter name="Field" value="SES_REMOTE_IP"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0.0.0.0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SES_INIT_DATE" type="VARCHAR" size="19" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SES_INIT_DATE"/> + <parameter name="Type" value="varchar(19)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SES_DUE_DATE" type="VARCHAR" size="19" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SES_DUE_DATE"/> + <parameter name="Type" value="varchar(19)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SES_END_DATE" type="VARCHAR" size="19" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SES_END_DATE"/> + <parameter name="Type" value="varchar(19)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexSession"> + <index-column name="SES_UID"/> + </index> + </table> + <table name="DB_SOURCE"> + <vendor type="mysql"> + <parameter name="Name" value="DB_SOURCE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-05-06 10:30:00"/> + <parameter name="Update_time" value="2008-05-06 10:30:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="DB_SOURCE"/> + </vendor> + <column name="DBS_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DBS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_TYPE" type="VARCHAR" size="8" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_TYPE"/> + <parameter name="Type" value="varchar(8)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_SERVER" type="VARCHAR" size="100" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_SERVER"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_DATABASE_NAME" type="VARCHAR" size="100" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_DATABASE_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_USERNAME" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_USERNAME"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_PASSWORD" type="VARCHAR" size="32" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DBS_PASSWORD"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_PORT" type="INTEGER" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_PORT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_ENCODE" type="VARCHAR" size="32" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DBS_ENCODE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexDBSource"> + <index-column name="PRO_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="DB_SOURCE"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexDBSource"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="STEP_SUPERVISOR"> + <vendor type="mysql"> + <parameter name="Name" value="STEP_SUPERVISOR"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-05-16 17:50:00"/> + <parameter name="Update_time" value="2008-05-16 17:50:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="STEP_SUPERVISOR"/> + </vendor> + <column name="STEP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="STEP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_TYPE_OBJ" type="VARCHAR" size="20" required="true" default="DYNAFORM"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_TYPE_OBJ"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="DYNAFORM"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_UID_OBJ" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_UID_OBJ"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STEP_POSITION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STEP_POSITION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="STEP_TYPE_OBJ"> + <rule name="validValues" value="DYNAFORM|INPUT_DOCUMENT|OUTPUT_DOCUMENT" message="Please select a valid value for STEP_TYPE_OBJ." /> + </validator> + <index name="indexStepSupervisor"> + <index-column name="PRO_UID"/> + <index-column name="STEP_TYPE_OBJ"/> + <index-column name="STEP_UID_OBJ"/> + <vendor type="mysql"> + <parameter name="Table" value="STEP_SUPERVISOR"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexStepSupervisor"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="OBJECT_PERMISSION"> + <vendor type="mysql"> + <parameter name="Name" value="OBJECT_PERMISSION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-08-01 11:10:00"/> + <parameter name="Update_time" value="2008-08-01 11:10:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="OBJECT_PERMISSION"/> + </vendor> + <column name="OP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_USER_RELATION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_USER_RELATION"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_TASK_SOURCE" type="VARCHAR" size="32" required="" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_TASK_SOURCE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_PARTICIPATE" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_PARTICIPATE"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_OBJ_TYPE" type="VARCHAR" size="15" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_OBJ_TYPE"/> + <parameter name="Type" value="varchar(15)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ANY"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_OBJ_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_OBJ_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_ACTION" type="VARCHAR" size="10" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_ACTION"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="VIEW"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="OP_CASE_STATUS" type="VARCHAR" size="10" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="OP_CASE_STATUS"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="OP_UID"> + <rule name="maxLength" value="32" message="Object permission UID can be no larger than ${value} in size" /> + <rule name="required" message="Object permission UID is required." /> + </validator> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="TAS_UID"> + <rule name="maxLength" value="32" message="Task UID can be no larger than ${value} in size" /> + <rule name="required" message="Task UID is required." /> + </validator> + <validator column="USR_UID"> + <rule name="maxLength" value="32" message="User or Group UID can be no larger than ${value} in size" /> + <rule name="required" message="User or Group UID is required." /> + </validator> + <validator column="OP_USER_RELATION"> + <rule name="validValues" value="1|2" message="Please select a valid relation." /> + <rule name="required" message="Relation is required." /> + </validator> + <validator column="OP_TASK_SOURCE"> + <rule name="maxLength" value="32" message="Source task UID can be no larger than ${value} in size" /> + <rule name="required" message="Source task is required." /> + </validator> + <validator column="OP_PARTICIPATE"> + <rule name="validValues" value="0|1" message="Please select a valid participation value." /> + <rule name="required" message="Participation is required." /> + </validator> + <validator column="OP_OBJ_TYPE"> + <rule name="maxLength" value="15" message="Object type can be no larger than ${value} in size" /> + <rule name="required" message="Object type is required." /> + </validator> + <validator column="OP_OBJ_UID"> + <rule name="maxLength" value="32" message="Object UID can be no larger than ${value} in size" /> + <rule name="required" message="Object UID is required." /> + </validator> + <validator column="OP_ACTION"> + <rule name="maxLength" value="15" message="Action can be no larger than ${value} in size" /> + <rule name="required" message="Action is required." /> + </validator> + <index name="indexObjctPermission"> + <index-column name="PRO_UID"/> + <index-column name="TAS_UID"/> + <index-column name="USR_UID"/> + <index-column name="OP_TASK_SOURCE"/> + <index-column name="OP_OBJ_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="OBJECT_PERMISSION"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexObjctPermission"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="CASE_TRACKER"> + <vendor type="mysql"> + <parameter name="Name" value="CASE_TRACKER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="0"/> + <parameter name="Avg_row_length" value="0"/> + <parameter name="Data_length" value="0"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="1024"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-08-15 12:15:00"/> + <parameter name="Update_time" value="2008-08-15 12:15:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="CASE_TRACKER"/> + </vendor> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CT_MAP_TYPE" type="VARCHAR" size="10" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CT_MAP_TYPE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="PROCESSMAP"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CT_DERIVATION_HISTORY" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CT_DERIVATION_HISTORY"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CT_MESSAGE_HISTORY" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CT_MESSAGE_HISTORY"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="PRO_UID"> + <rule name="maxLength" value="32" message="Process UID can be no larger than ${value} in size" /> + <rule name="required" message="Process UID is required." /> + </validator> + <validator column="CT_MAP_TYPE"> + <rule name="validValues" value="NONE|PROCESSMAP|STAGES" message="Please select a valid map type." /> + <rule name="required" message="Map type is required." /> + </validator> + <validator column="CT_DERIVATION_HISTORY"> + <rule name="validValues" value="0|1" message="Please select a valid derivation history status." /> + <rule name="required" message="Derivation history status is required." /> + </validator> + <validator column="CT_MESSAGE_HISTORY"> + <rule name="validValues" value="0|1" message="Please select a valid message history status." /> + <rule name="required" message="Message history status is required." /> + </validator> + </table> + <table name="CASE_TRACKER_OBJECT"> + <vendor type="mysql"> + <parameter name="Name" value="CASE_TRACKER_OBJECT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="18"/> + <parameter name="Avg_row_length" value="106"/> + <parameter name="Data_length" value="1956"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="2048"/> + <parameter name="Data_free" value="40"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-15-04 12:50:00"/> + <parameter name="Update_time" value="2008-15-06 12:50:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="CTO_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CTO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CTO_TYPE_OBJ" type="VARCHAR" size="20" required="true" default="DYNAFORM"> + <vendor type="mysql"> + <parameter name="Field" value="CTO_TYPE_OBJ"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="DYNAFORM"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CTO_UID_OBJ" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CTO_UID_OBJ"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CTO_CONDITION" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="CTO_CONDITION"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CTO_POSITION" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CTO_POSITION"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="CTO_TYPE_OBJ"> + <rule name="validValues" value="DYNAFORM|INPUT_DOCUMENT|OUTPUT_DOCUMENT|MESSAGE|EXTERNAL" message="Please select a valid value for CTO_TYPE_OBJ." /> + </validator> + <index name="indexCaseTrackerObject"> + <index-column name="PRO_UID"/> + <index-column name="CTO_UID_OBJ"/> + <vendor type="mysql"> + <parameter name="Table" value="CASE_TRACKER_OBJECT"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexCaseTrackerObject"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="STAGE"> + <vendor type="mysql"> + <parameter name="Name" value="STAGE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-08-12 15:08:22"/> + <parameter name="Update_time" value="2008-08-12 15:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="STG_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="STG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STG_POSX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STG_POSX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STG_POSY" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STG_POSY"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="STG_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="STG_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="SUB_PROCESS"> + <vendor type="mysql"> + <parameter name="Name" value="SUB_PROCESS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-09-18 19:18:00"/> + <parameter name="Update_time" value="2008-09-18 19:18:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="SP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_PARENT" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_PARENT" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_TYPE" type="VARCHAR" size="20" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SP_TYPE"/> + <parameter name="Type" value="varchar(20)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_SYNCHRONOUS" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SP_SYNCHRONOUS"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_SYNCHRONOUS_TYPE" type="VARCHAR" size="20" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SP_SYNCHRONOUS_TYPE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ALL"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_SYNCHRONOUS_WAIT" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SP_SYNCHRONOUS_WAIT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_VARIABLES_OUT" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SP_VARIABLES_OUT"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_VARIABLES_IN" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SP_VARIABLES_IN"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SP_GRID_IN" type="VARCHAR" size="50" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SP_GRID_IN"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="SP_TYPE"> + <rule name="validValues" value="SIMPLE|MULTIPLE" message="Please select a valid value for SP_TYPE." /> + </validator> + <validator column="SP_SYNCHRONOUS"> + <rule name="validValues" value="1|0" message="Please select a valid value for SP_SYNCHRONOUS." /> + </validator> + <validator column="SP_SYNCHRONOUS_TYPE"> + <rule name="validValues" value="ALL|INSTANCES|TIME" message="Please select a valid value for SP_SYNCHRONOUS_TYPE." /> + </validator> + <index name="indexSubProcess"> + <index-column name="PRO_UID"/> + <index-column name="PRO_PARENT"/> + <vendor type="mysql"> + <parameter name="Table" value="SUB_PROCESS"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexSubProcess"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="PRO_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <table name="SUB_APPLICATION"> + <vendor type="mysql"> + <parameter name="Name" value="SUB_APPLICATION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-09-18 19:18:00"/> + <parameter name="Update_time" value="2008-09-18 19:18:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PARENT" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX_PARENT" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX_PARENT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_THREAD_PARENT" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_THREAD_PARENT"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SA_STATUS" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SA_STATUS"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SA_VALUES_OUT" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SA_VALUES_OUT"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SA_VALUES_IN" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SA_VALUES_IN"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SA_INIT_DATE" type="TIMESTAMP" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="SA_INIT_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SA_FINISH_DATE" type="TIMESTAMP" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="SA_FINISH_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="SA_STATUS"> + <rule name="validValues" value="ACTIVE|FINISHED|CANCELLED" message="Please select a valid value for SA_STATUS." /> + </validator> + </table> + <table name="LOGIN_LOG"> + <vendor type="mysql"> + <parameter name="Name" value="LOGIN_LOG"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2008-09-18 19:18:00"/> + <parameter name="Update_time" value="2008-09-18 19:18:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="LOG_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LOG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_STATUS" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LOG_STATUS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_IP" type="VARCHAR" size="15" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LOG_IP"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_SID" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LOG_SID"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_INIT_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="LOG_INIT_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_END_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="LOG_END_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="LOG_CLIENT_HOSTNAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="LOG_CLIENT_HOSTNAME"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="USERS_PROPERTIES"> + <vendor type="mysql"> + <parameter name="Name" value="USERS_PROPERTIES"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-02-16 16:13:00"/> + <parameter name="Update_time" value="2009-02-16 16:13:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="USR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_LAST_UPDATE_DATE" type="TIMESTAMP"> + <vendor type="mysql"> + <parameter name="Field" value="USR_LAST_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_LOGGED_NEXT_TIME" type="INTEGER" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="USR_LOGGED_NEXT_TIME"/> + <parameter name="Type" value="int(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_PASSWORD_HISTORY" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="USR_PASSWORD_HISTORY"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="ADDITIONAL_TABLES"> + <vendor type="mysql"> + <parameter name="Name" value="ADDITIONAL_TABLES"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-05-07 16:15:00"/> + <parameter name="Update_time" value="2009-05-07 16:15:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="ADD_TAB_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_NAME" type="VARCHAR" size="60" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_NAME"/> + <parameter name="Type" value="varchar(60)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_CLASS_NAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_CLASS_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_DESCRIPTION" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_DESCRIPTION"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_LOG_INSERT" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_LOG_INSERT"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_LOG_UPDATE" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_LOG_UPDATE"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_LOG_DELETE" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_LOG_DELETE"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_LOG_SELECT" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_LOG_SELECT"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_MAX_LENGTH" type="INTEGER" required="true" default="-1"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_MAX_LENGTH"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="-1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_SDW_AUTO_DELETE" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_SDW_AUTO_DELETE"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_PLG_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_PLG_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DBS_UID" type="VARCHAR" size="32" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DBS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="FIELDS"> + <vendor type="mysql"> + <parameter name="Name" value="FIELDS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-05-07 16:15:00"/> + <parameter name="Update_time" value="2009-05-07 16:15:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="FLD_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FLD_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_INDEX" type="INTEGER" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_NAME" type="VARCHAR" size="60" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FLD_NAME"/> + <parameter name="Type" value="varchar(60)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_DESCRIPTION" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_DESCRIPTION"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_TYPE" type="VARCHAR" size="10" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FLD_TYPE"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_SIZE" type="INTEGER" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_SIZE"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_NULL" type="TINYINT" required="true" default="1"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_NULL"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="1"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_AUTO_INCREMENT" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_AUTO_INCREMENT"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_KEY" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_KEY"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_FOREIGN_KEY" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="FLD_FOREIGN_KEY"/> + <parameter name="Type" value="tinyint(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FLD_FOREIGN_KEY_TABLE" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FLD_FOREIGN_KEY_TABLE"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="SHADOW_TABLE"> + <vendor type="mysql"> + <parameter name="Name" value="SHADOW_TABLE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-07-30 16:55:00"/> + <parameter name="Update_time" value="2009-07-30 16:55:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="SHD_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SHD_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="ADD_TAB_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="ADD_TAB_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SHD_ACTION" type="VARCHAR" size="10" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="SHD_ACTION"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SHD_DETAILS" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SHD_DETAILS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SHD_DATE" type="TIMESTAMP" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="SHD_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexShadowTable"> + <index-column name="SHD_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="SHD_UID"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexShadowTable"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="SHD_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + <!--.--> + + <table name="EVENT"> + <vendor type="mysql"> + <parameter name="Name" value="EVENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-08-26 16:20:00"/> + <parameter name="Update_time" value="2009-08-26 16:20:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="EVN_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="EVN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_STATUS" type="VARCHAR" size="16" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_STATUS"/> + <parameter name="Type" value="varchar(16)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_WHEN_OCCURS" type="VARCHAR" size="32" required="false" default="SINGLE"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_WHEN_OCCURS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="AFTER_TIME"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_RELATED_TO" type="VARCHAR" size="16" required="false" default="SINGLE"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_RELATED_TO"/> + <parameter name="Type" value="varchar(16)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="SINGLE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_TAS_UID_FROM" type="VARCHAR" size="32" required="false" default=""> + <vendor type="mysql"> + <parameter name="Field" value="EVN_TAS_UID_FROM"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_TAS_UID_TO" type="VARCHAR" size="32" required="false" default=""> + <vendor type="mysql"> + <parameter name="Field" value="EVN_TAS_UID_TO"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_TAS_ESTIMATED_DURATION" type="DOUBLE" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_TAS_ESTIMATED_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_WHEN" type="DOUBLE" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_WHEN"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_MAX_ATTEMPTS" type="TINYINT" required="true" default="3"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_MAX_ATTEMPTS"/> + <parameter name="Type" value="tinyint(2)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="3"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_ACTION" type="VARCHAR" size="50" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="EVN_ACTION"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_CONDITIONS" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_CONDITIONS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_ACTION_PARAMETERS" type="LONGVARCHAR" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="EVN_ACTION_PARAMETERS"/> + <parameter name="Type" value="text"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TRI_UID" type="VARCHAR" size="32" required="false" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TRI_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexEventTable"> + <index-column name="EVN_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="EVN_UID"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexEventTable"/> + <parameter name="Seq_in_index" value="1"/> + <parameter name="Column_name" value="EVN_UID"/> + <parameter name="Collation" value="A"/> + <parameter name="Cardinality" value=""/> + <parameter name="Sub_part" value=""/> + <parameter name="Packed" value=""/> + <parameter name="Null" value=""/> + <parameter name="Index_type" value="BTREE"/> + <parameter name="Comment" value=""/> + </vendor> + </index> + </table> + + <table name="APP_EVENT"> + <vendor type="mysql"> + <parameter name="Name" value="APP_EVENT"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2009-08-26 16:20:00"/> + <parameter name="Update_time" value="2009-08-26 16:20:00"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value=""/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EVN_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="EVN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_EVN_ACTION_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_EVN_ACTION_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_EVN_ATTEMPTS" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_EVN_ATTEMPTS"/> + <parameter name="Type" value="tinyint(2)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_EVN_LAST_EXECUTION_DATE" type="TIMESTAMP" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="APP_EVN_LAST_EXECUTION_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_EVN_STATUS" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="APP_EVN_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + + + <table name="APP_CACHE_VIEW"> + <vendor type="mysql"> + <parameter name="Name" value="APP_CACHE_VIEW"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Delegation a task to user"/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" primaryKey="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_NUMBER" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="APP_NUMBER"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_STATUS" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PREVIOUS_USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PREVIOUS_USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELEGATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELEGATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INIT_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_INIT_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_TASK_DUE_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_TASK_DUE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_FINISH_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="DEL_FINISH_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_THREAD_STATUS" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_THREAD_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_THREAD_STATUS" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="APP_THREAD_STATUS"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_TITLE" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_TITLE"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_PRO_TITLE" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_PRO_TITLE"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_TAS_TITLE" type="VARCHAR" size="255" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_TAS_TITLE"/> + <parameter name="Type" value="varchar(255)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_CURRENT_USER" type="VARCHAR" size="128" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_CURRENT_USER"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_DEL_PREVIOUS_USER" type="VARCHAR" size="128" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_DEL_PREVIOUS_USER"/> + <parameter name="Type" value="varchar(128)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_PRIORITY" type="VARCHAR" size="32" required="true" default="3"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_PRIORITY"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="3"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_QUEUE_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_QUEUE_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELAY_DURATION" type="DOUBLE" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELAY_DURATION"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_STARTED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_STARTED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_FINISHED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_FINISHED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_DELAYED" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_DELAYED"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_FINISH_DATE" type="TIMESTAMP" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="APP_FINISH_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_UPDATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_OVERDUE_PERCENTAGE" type="DOUBLE" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="APP_OVERDUE_PERCENTAGE"/> + <parameter name="Type" value="double"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <index name="indexAppNumber"> + <index-column name="APP_NUMBER"/> + <vendor type="mysql"> + <parameter name="Table" value="APP_CACHE_VIEW"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexAppNumber"/> + <parameter name="Seq_in_index" value="1"/> + </vendor> + </index> + <index name="indexAppUser"> + <index-column name="USR_UID"/> + <index-column name="APP_STATUS"/> + <vendor type="mysql"> + <parameter name="Table" value="APP_CACHE_VIEW"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexAppUser"/> + <parameter name="Seq_in_index" value="1"/> + </vendor> + </index> + </table> + + <table name="DIM_TIME_DELEGATE"> + <vendor type="mysql"> + <parameter name="Name" value="DIM_TIME_DELEGATE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="The application"/> + </vendor> + <column name="TIME_ID" type="VARCHAR" size="10" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TIME_ID"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value="UID to Application"/> + </vendor> + </column> + <column name="MONTH_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="QTR_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="YEAR_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="YEAR_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="MONTH_NAME" type="VARCHAR" size="3" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_NAME"/> + <parameter name="Type" value="varchar(3)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="MONTH_DESC" type="VARCHAR" size="9" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_DESC"/> + <parameter name="Type" value="varchar(9)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_NAME" type="VARCHAR" size="4" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="QTR_NAME"/> + <parameter name="Type" value="varchar(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_DESC" type="VARCHAR" size="9" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="QTR_DESC"/> + <parameter name="Type" value="varchar(9)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="DIM_TIME_COMPLETE"> + <vendor type="mysql"> + <parameter name="Name" value="DIM_TIME_COMPLETE"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="The application"/> + </vendor> + <column name="TIME_ID" type="VARCHAR" size="10" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TIME_ID"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value="UID to Application"/> + </vendor> + </column> + <column name="MONTH_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="QTR_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="YEAR_ID" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="YEAR_ID"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="MONTH_NAME" type="VARCHAR" size="3" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_NAME"/> + <parameter name="Type" value="varchar(3)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="MONTH_DESC" type="VARCHAR" size="9" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="MONTH_DESC"/> + <parameter name="Type" value="varchar(9)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_NAME" type="VARCHAR" size="4" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="QTR_NAME"/> + <parameter name="Type" value="varchar(4)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="QTR_DESC" type="VARCHAR" size="9" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="QTR_DESC"/> + <parameter name="Type" value="varchar(9)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + + <table name="APP_HISTORY"> + <vendor type="mysql"> + <parameter name="Name" value="APP_HISTORY"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="History table for Dynaforms"/> + </vendor> + <column name="APP_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DEL_INDEX" type="INTEGER" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="DEL_INDEX"/> + <parameter name="Type" value="int(11)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="DYN_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="DYN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="APP_STATUS" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="APP_STATUS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="HISTORY_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="HISTORY_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="HISTORY_DATA" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="HISTORY_DATA"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <index name="indexAppHistory"> + <index-column name="APP_UID"/> + <index-column name="TAS_UID"/> + <index-column name="USR_UID"/> + <vendor type="mysql"> + <parameter name="Table" value="APP_HISTORY"/> + <parameter name="Non_unique" value="1"/> + <parameter name="Key_name" value="indexAppHistory"/> + <parameter name="Seq_in_index" value="1"/> + </vendor> + </index> + </table> + <table name="APP_FOLDER"> + <vendor type="mysql"> + <parameter name="Name" value="APP_FOLDER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Folder System PM Documents"/> + </vendor> + <column name="FOLDER_UID" type="VARCHAR" size="32" required="true" default="" primaryKey="true"> + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FOLDER_PARENT_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_PARENT_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FOLDER_NAME" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_NAME"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FOLDER_CREATE_DATE" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FOLDER_UPDATE_DATE" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="FOLDER_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + </table> + + <table name="FIELD_CONDITION"> + <vendor type="mysql"> + <parameter name="Name" value="FIELD_CONDITION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="88"/> + <parameter name="Avg_row_length" value="311"/> + <parameter name="Data_length" value="27984"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="7168"/> + <parameter name="Data_free" value="564"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2010-05-11 15:08:22"/> + <parameter name="Update_time" value="2010-05-11 15:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Conditions store to show or hide dynaform fields.."/> + </vendor> + <column name="FCD_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="FCD_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_FUNCTION" type="VARCHAR" size="50" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_FUNCTION"/> + <parameter name="Type" value="varchar(50)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_FIELDS" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_FIELDS"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_CONDITION" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_CONDITION"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_EVENTS" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_EVENTS"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_EVENT_OWNERS" type="LONGVARCHAR" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_EVENT_OWNERS"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_STATUS" type="VARCHAR" size="10" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_STATUS"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="FCD_DYN_UID" type="VARCHAR" size="32" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="FCD_DYN_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + + <table name="LOG_CASES_SCHEDULER" > + <vendor type="mysql"> + <parameter name="Name" value="LOG_CASES_SCHEDULER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Cases Launched with Case Scheduler"/> + </vendor> + + <column name="LOG_CASE_UID" size="32" required="true" primaryKey="true" default="" > + <vendor type="mysql"> + <parameter name="Field" value="LOG_CASE_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_NAME" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="USR_NAME"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EXEC_DATE" type="DATE" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="EXEC_DATE"/> + <parameter name="Type" value="date"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="EXEC_HOUR" type="VARCHAR" size="32" required="true" default="12:00" > + <vendor type="mysql"> + <parameter name="Field" value="EXEC_HOUR"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="RESULT" type="VARCHAR" size="32" required="true" default="SUCCESS"> + <vendor type="mysql"> + <parameter name="Field" value="RESULT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="SUCCESS"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_UID" type="VARCHAR" size="32" required="true" default="OPEN"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="OPEN"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="WS_CREATE_CASE_STATUS" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="WS_CREATE_CASE_STATUS"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="WS_ROUTE_CASE_STATUS" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="WS_ROUTE_CASE_STATUS"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + </table> + + + <table name="CASE_SCHEDULER" > + <vendor type="mysql"> + <parameter name="Name" value="CASE_SCHEDULER"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Conditions store to show or hide dynaform fields.."/> + </vendor> + <column name="SCH_UID" type="VARCHAR" size="32" required="true" primaryKey="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_DEL_USER_NAME" type="VARCHAR" size="100" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_DEL_USER_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_DEL_USER_PASS" type="VARCHAR" size="100" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_DEL_USER_PASS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_DEL_USER_UID" type="VARCHAR" size="100" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_DEL_USER_UID"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_NAME" type="VARCHAR" size="100" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> +<!-- + <column name="SCH_PROGRAM" type="VARCHAR" size="100" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_PROGRAM"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> +//--> + <column name="PRO_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="PRO_UID"/> + <parameter name="Type" value="varchar(32)" /> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="TAS_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="TAS_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_TIME_NEXT_RUN" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_TIME_NEXT_RUN"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_LAST_RUN_TIME" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_LAST_RUN_TIME"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="SCH_STATE" type="VARCHAR" size="15" required="true" default="ACTIVE" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_STATE"/> + <parameter name="Type" value="varchar(15)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_LAST_STATE" type="VARCHAR" size="60" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_LAST_STATE"/> + <parameter name="Type" value="varchar(60)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="USR_UID" type="VARCHAR" size="32" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="USR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_OPTION" type="TINYINT" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_OPTION"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_START_TIME" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_START_TIME"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_START_DATE" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_START_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_DAYS_PERFORM_TASK" type="CHAR" size="5" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_DAYS_PERFORM_TASK"/> + <parameter name="Type" value="char(5)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_EVERY_DAYS" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_EVERY_DAYS"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_WEEK_DAYS" type="CHAR" size="14" required="true" default="0|0|0|0|0|0|0"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_WEEK_DAYS"/> + <parameter name="Type" value="char(14)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0|0|0|0|0|0|0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_START_DAY" type="CHAR" size="6" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_START_DAY"/> + <parameter name="Type" value="char(6)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_MONTHS" type="CHAR" size="24" required="true" default="0|0|0|0|0|0|0|0|0|0|0|0"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_MONTHS"/> + <parameter name="Type" value="char(24)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0|0|0|0|0|0|0|0|0|0|0|0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_END_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="SCH_END_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_REPEAT_EVERY" type="VARCHAR" size="15" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_REPEAT_EVERY"/> + <parameter name="Type" value="varchar(15)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_REPEAT_UNTIL" type="VARCHAR" size="15" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_REPEAT_UNTIL"/> + <parameter name="Type" value="varchar(15)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="SCH_REPEAT_STOP_IF_RUNNING" type="TINYINT" required="false" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="SCH_REPEAT_STOP_IF_RUNNING"/> + <parameter name="Type" value="tinyint(1)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CASE_SH_PLUGIN_UID" type="VARCHAR" size="100" required="false"> + <vendor type="mysql"> + <parameter name="Field" value="CASE_SH_PLUGIN_UID"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + </table> + + <table name="CALENDAR_DEFINITION"> + <vendor type="mysql"> + <parameter name="Name" value="CALENDAR_DEFINITION"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Calendar Definition used by PM"/> + </vendor> + <column name="CALENDAR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_NAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="CALENDAR_CREATE_DATE" type="TIMESTAMP" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_CREATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <!-- <parameter name="Default" value="0000-00-00 00:00:00"/> --> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_UPDATE_DATE" type="TIMESTAMP" required="false" > + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_UPDATE_DATE"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="YES"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_WORK_DAYS" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_WORK_DAYS"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_DESCRIPTION" type="LONGVARCHAR" required="true"> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_DESCRIPTION"/> + <parameter name="Type" value="mediumtext"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_STATUS" type="VARCHAR" size="8" required="true" default="ACTIVE"> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_STATUS"/> + <parameter name="Type" value="varchar(8)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="ACTIVE"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <validator column="CALENDAR_STATUS"> + <rule name="validValues" value="ACTIVE|INACTIVE|DELETED" message="Please select a valid Calendar Status." /> + </validator> +</table> + +<table name="CALENDAR_BUSINESS_HOURS"> + <vendor type="mysql"> + <parameter name="Name" value="CALENDAR_BUSINESS_HOURS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Calendar Business Hours"/> + </vendor> + <column name="CALENDAR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_BUSINESS_DAY" type="VARCHAR" size="10" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_BUSINESS_DAY"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_BUSINESS_START" type="VARCHAR" size="10" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_BUSINESS_START"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_BUSINESS_END" type="VARCHAR" size="10" primaryKey="true" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_BUSINESS_END"/> + <parameter name="Type" value="varchar(10)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <validator column="CALENDAR_BUSINESS_DAY"> + <rule name="validValues" value="0|1|2|3|4|5|6|7" message="Please select a valid Day." /> + </validator> + </table> +<table name="CALENDAR_HOLIDAYS"> + <vendor type="mysql"> + <parameter name="Name" value="CALENDAR_HOLIDAYS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Calendar Holidays"/> + </vendor> + <column name="CALENDAR_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_HOLIDAY_NAME" type="VARCHAR" size="100" primaryKey="true" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_HOLIDAY_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_HOLIDAY_START" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_HOLIDAY_START"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_HOLIDAY_END" type="TIMESTAMP" required="true" > + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_HOLIDAY_END"/> + <parameter name="Type" value="datetime"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + </table> + <table name="CALENDAR_ASSIGNMENTS"> + <vendor type="mysql"> + <parameter name="Name" value="CALENDAR_ASSIGNMENTS"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Calendar Holidays"/> + </vendor> + <column name="OBJECT_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OBJECT_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CALENDAR_UID" type="VARCHAR" size="32" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CALENDAR_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="OBJECT_TYPE" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="OBJECT_TYPE"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + </table> + <table name="PROCESS_CATEGORY"> + <vendor type="mysql"> + <parameter name="Name" value="PROCESS_CATEGORY"/> + <parameter name="Engine" value="MyISAM"/> + <parameter name="Version" value="10"/> + <parameter name="Row_format" value="Dynamic"/> + <parameter name="Rows" value="129"/> + <parameter name="Avg_row_length" value="115"/> + <parameter name="Data_length" value="14860"/> + <parameter name="Max_data_length" value="281474976710655"/> + <parameter name="Index_length" value="5120"/> + <parameter name="Data_free" value="0"/> + <parameter name="Auto_increment" value=""/> + <parameter name="Create_time" value="2007-12-06 07:22:27"/> + <parameter name="Update_time" value="2007-12-09 14:08:22"/> + <parameter name="Check_time" value=""/> + <parameter name="Collation" value="utf8_general_ci"/> + <parameter name="Checksum" value=""/> + <parameter name="Create_options" value=""/> + <parameter name="Comment" value="Calendar Holidays"/> + </vendor> + <column name="CATEGORY_UID" type="VARCHAR" size="32" required="true" primaryKey="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CATEGORY_UID"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value="PRI"/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CATEGORY_PARENT" type="VARCHAR" size="32" required="true" default="0"> + <vendor type="mysql"> + <parameter name="Field" value="CATEGORY_PARENT"/> + <parameter name="Type" value="varchar(32)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value="0"/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + <column name="CATEGORY_NAME" type="VARCHAR" size="100" required="true" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CATEGORY_NAME"/> + <parameter name="Type" value="varchar(100)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + <column name="CATEGORY_ICON" type="VARCHAR" size="100" default=""> + <vendor type="mysql"> + <parameter name="Field" value="CATEGORY_ICON"/> + <parameter name="Type" value="varchar(200)"/> + <parameter name="Null" value="NO"/> + <parameter name="Key" value=""/> + <parameter name="Default" value=""/> + <parameter name="Extra" value=""/> + </vendor> + </column> + + </table> +</database> \ No newline at end of file diff --git a/workflow/engine/content/languages/en.js b/workflow/engine/content/languages/en.js new file mode 100644 index 000000000..923a863f9 --- /dev/null +++ b/workflow/engine/content/languages/en.js @@ -0,0 +1,3 @@ +translationJS ={"test":"ghsd","new":"Alert!!!!","new23":"Alert's","EDIT_PROCESS":"<u>E<\/u>dit process"}; + +var translationJS = 'abc'; diff --git a/workflow/engine/content/translations/english/processmaker.en.po b/workflow/engine/content/translations/english/processmaker.en.po new file mode 100644 index 000000000..17fc8f415 --- /dev/null +++ b/workflow/engine/content/translations/english/processmaker.en.po @@ -0,0 +1,27441 @@ +msgid "" +msgstr "" +"Project-Id-Version: PM 4.0.1\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2010-12-01 11:55+0100\n" +"Last-Translator: \n" +"Language-Team: Colosa Developers Team <developers@colosa.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer_Encoding: 8bit\n" +"X-Poedit-Language: English\n" +"X-Poedit-Country: \n" +"X-Poedit-SourceCharset: utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# TRANSLATION +# LABEL/LOGIN +#: LABEL/LOGIN +msgid "Login" +msgstr "Login" + +# TRANSLATION +# LABEL/CASES +#: LABEL/CASES +msgid "Cases" +msgstr "Cases" + +# TRANSLATION +# LABEL/ID_USER_HAVENT_RIGHTS_PAGE +#: LABEL/ID_USER_HAVENT_RIGHTS_PAGE +msgid "User does not have rights on this page." +msgstr "User does not have rights on this page." + +# TRANSLATION +# LABEL/ID_WRONG_PASS +#: LABEL/ID_WRONG_PASS +msgid "Wrong password" +msgstr "Wrong password" + +# TRANSLATION +# LABEL/ABOUT +#: LABEL/ABOUT +msgid "About" +msgstr "About" + +# TRANSLATION +# LABEL/ID_PROCESSMAP_MESSAGES +#: LABEL/ID_PROCESSMAP_MESSAGES +msgid "Messages" +msgstr "Messages" + +# TRANSLATION +# JAVASCRIPT/demo +#: JAVASCRIPT/demo +msgid "test javaScript" +msgstr "test javaScript" + +# TRANSLATION +# LABEL/ID_AVAILABLE_TRIGGERS +#: LABEL/ID_AVAILABLE_TRIGGERS +msgid "Available Triggers" +msgstr "Available Triggers" + +# TRANSLATION +# LABEL/ID_LOGOUT +#: LABEL/ID_LOGOUT +msgid "Logout" +msgstr "Logout" + +# TRANSLATION +# LABEL/ID_MY_ACCOUNT +#: LABEL/ID_MY_ACCOUNT +msgid "My account" +msgstr "My account" + +# TRANSLATION +# LABEL/ID_USERS +#: LABEL/ID_USERS +msgid "Users" +msgstr "Users" + +# TRANSLATION +# LABEL/ID_CASES +#: LABEL/ID_CASES +msgid "[LABEL/ID_CASES] Cases" +msgstr "Cases" + +# TRANSLATION +# LABEL/ID_APPLICATIONS +#: LABEL/ID_APPLICATIONS +msgid "Processes" +msgstr "Processes" + +# TRANSLATION +# LABEL/ID_RULES_AND_USER_GROUPS +#: LABEL/ID_RULES_AND_USER_GROUPS +msgid "Rules and user groups" +msgstr "Rules and user groups" + +# TRANSLATION +# LABEL/ID_ADD_USER_OF_TASK +#: LABEL/ID_ADD_USER_OF_TASK +msgid "Last executor of the task" +msgstr "Last executor of the task" + +# TRANSLATION +# LABEL/ID_END_OF_PROCESS +#: LABEL/ID_END_OF_PROCESS +msgid "End of process" +msgstr "End of process" + +# TRANSLATION +# LABEL/ID_TAREA_COLGANTE +#: LABEL/ID_TAREA_COLGANTE +msgid "Leaf task" +msgstr "Leaf task" + +# TRANSLATION +# LABEL/ID_OUTPUT_DOCUMENTS +#: LABEL/ID_OUTPUT_DOCUMENTS +msgid "Output Documents" +msgstr "Output Documents" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_OUTDOC +#: LABEL/ID_MSG_CONFIRM_DELETE_OUTDOC +msgid "Do you want to delete this output document ?" +msgstr "Do you want to delete this output document ?" + +# TRANSLATION +# LABEL/ID_NO_RECORDS_FOUND +#: LABEL/ID_NO_RECORDS_FOUND +msgid "No records found" +msgstr "No records found" + +# TRANSLATION +# LABEL/ID_DYNAFORMS +#: LABEL/ID_DYNAFORMS +msgid "DynaForms" +msgstr "DynaForms" + +# TRANSLATION +# LABEL/ID_DYNAFORM_EDITOR +#: LABEL/ID_DYNAFORM_EDITOR +msgid "DynaForm Editor" +msgstr "DynaForm Editor" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_RESET_TEMPLATE +#: LABEL/ID_MSG_CONFIRM_RESET_TEMPLATE +msgid "Are you sure you want to restore the default template ?" +msgstr "Are you sure you want to restore the default template ?" + +# TRANSLATION +# LABEL/ID_ADD_FIELD +#: LABEL/ID_ADD_FIELD +msgid "Add field" +msgstr "Add field" + +# TRANSLATION +# LABEL/ID_EDIT_FIELD +#: LABEL/ID_EDIT_FIELD +msgid "Edit Field" +msgstr "Edit Field" + +# TRANSLATION +# LABEL/ID_DELETE_FIELD_SURE +#: LABEL/ID_DELETE_FIELD_SURE +msgid "Are you sure you want to delete this field?" +msgstr "Are you sure you want to delete this field?" + +# TRANSLATION +# LABEL/ID_EDIT +#: LABEL/ID_EDIT +msgid "Edit" +msgstr "Edit" + +# TRANSLATION +# LABEL/ID_DELETE +#: LABEL/ID_DELETE +msgid "Delete" +msgstr "Delete" + +# TRANSLATION +# LABEL/ID_UP +#: LABEL/ID_UP +msgid "Up" +msgstr "Up" + +# TRANSLATION +# LABEL/ID_DOWN +#: LABEL/ID_DOWN +msgid "Down" +msgstr "Down" + +# TRANSLATION +# LABEL/ID_PAGE +#: LABEL/ID_PAGE +msgid "Page" +msgstr "Page" + +# TRANSLATION +# LABEL/ID_NEW_DYNAFORM +#: LABEL/ID_NEW_DYNAFORM +msgid "New dynaform" +msgstr "New dynaform" + +# TRANSLATION +# LABEL/ID_EDIT_DYNAFORM +#: LABEL/ID_EDIT_DYNAFORM +msgid "Edit DynaForm" +msgstr "Edit DynaForm" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_DYNAFORM +#: LABEL/ID_MSG_CONFIRM_DELETE_DYNAFORM +msgid "Do you want to delete this DynaForm ?" +msgstr "Do you want to delete this DynaForm ?" + +# TRANSLATION +# LABEL/ID_ADD_MESSAGE +#: LABEL/ID_ADD_MESSAGE +msgid "Add message" +msgstr "Add message" + +# TRANSLATION +# LABEL/ID_MESSAGES +#: LABEL/ID_MESSAGES +msgid "[LABEL/ID_MESSAGES] Messages" +msgstr "Messages" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_MESSAGE +#: LABEL/ID_MSG_CONFIRM_DELETE_MESSAGE +msgid "Do you want to delete this message?" +msgstr "Do you want to delete this message?" + +# TRANSLATION +# LABEL/ID_ACTIVE +#: LABEL/ID_ACTIVE +msgid "Active" +msgstr "Active" + +# TRANSLATION +# LABEL/ID_INACTIVE +#: LABEL/ID_INACTIVE +msgid "Inactive" +msgstr "Inactive" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_PROCESS +#: LABEL/ID_MSG_CONFIRM_DELETE_PROCESS +msgid "Do you want to delete this process ?" +msgstr "Do you want to delete this process ?" + +# TRANSLATION +# LABEL/ID_VIEW +#: LABEL/ID_VIEW +msgid "View" +msgstr "View" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_USER +#: LABEL/ID_MSG_CONFIRM_DELETE_USER +msgid "Do you want to delete this user ?" +msgstr "Do you want to delete this user ?" + +# TRANSLATION +# LABEL/ID_USERS_LIST +#: LABEL/ID_USERS_LIST +msgid "[LABEL/ID_USERS_LIST] Users" +msgstr "Users" + +# TRANSLATION +# LABEL/ID_GROUP_USERS +#: LABEL/ID_GROUP_USERS +msgid "Groups" +msgstr "Groups" + +# TRANSLATION +# LABEL/ID_USER_REGISTERED +#: LABEL/ID_USER_REGISTERED +msgid "User name already exists" +msgstr "User name already exists" + +# TRANSLATION +# LABEL/ID_MSG_ERROR_USR_USERNAME +#: LABEL/ID_MSG_ERROR_USR_USERNAME +msgid "User name required!" +msgstr "User name required!" + +# TRANSLATION +# LABEL/ID_MSG_ERROR_DUE_DATE +#: LABEL/ID_MSG_ERROR_DUE_DATE +msgid "Due date required!" +msgstr "Due date required!" + +# TRANSLATION +# LABEL/ID_NEW_PASS_SAME_OLD_PASS +#: LABEL/ID_NEW_PASS_SAME_OLD_PASS +msgid "The confirm Password fields must be the same!" +msgstr "The confirm Password fields must be the same!" + +# TRANSLATION +# LABEL/ID_NEW_INPUTDOCS +#: LABEL/ID_NEW_INPUTDOCS +msgid "New input document" +msgstr "New input document" + +# TRANSLATION +# LABEL/ID_EDIT_INPUTDOCS +#: LABEL/ID_EDIT_INPUTDOCS +msgid "Edit input document" +msgstr "Edit input document" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_DOCUMENT +#: LABEL/ID_MSG_CONFIRM_DELETE_DOCUMENT +msgid "Do you want to delete this document ?" +msgstr "Do you want to delete this document ?" + +# TRANSLATION +# LABEL/ID_NEW_TRIGGERS +#: LABEL/ID_NEW_TRIGGERS +msgid "New Trigger" +msgstr "New Trigger" + +# TRANSLATION +# LABEL/ID_EDIT_TRIGGERS +#: LABEL/ID_EDIT_TRIGGERS +msgid "Edit Trigger" +msgstr "Edit Trigger" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_TRIGGER +#: LABEL/ID_MSG_CONFIRM_DELETE_TRIGGER +msgid "Do you want to delete this trigger?" +msgstr "Do you want to delete this trigger?" + +# TRANSLATION +# LABEL/ID_GROUP +#: LABEL/ID_GROUP +msgid "Group" +msgstr "Group" + +# TRANSLATION +# LABEL/ID_DE_ASSIGN +#: LABEL/ID_DE_ASSIGN +msgid "Remove" +msgstr "Remove" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DEASIGN_USER_MESSAGE +#: LABEL/ID_MSG_CONFIRM_DEASIGN_USER_MESSAGE +msgid "Are you sure you want to remove this user?" +msgstr "Are you sure you want to remove this user?" + +# TRANSLATION +# LABEL/ID_MSG_ERROR_PRO_TITLE +#: LABEL/ID_MSG_ERROR_PRO_TITLE +msgid "Process title required!" +msgstr "Process title required!" + +# TRANSLATION +# LABEL/ID_TASK +#: LABEL/ID_TASK +msgid "Task" +msgstr "Task" + +# TRANSLATION +# LABEL/ID_CONDITION +#: LABEL/ID_CONDITION +msgid "Condition" +msgstr "Condition" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT +#: LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT +msgid "Are you sure you want to delete this webbot?" +msgstr "Are you sure you want to delete this webbot?" + +# TRANSLATION +# LABEL/ID_DYNAFORM_EDITOR_SAVE_CHANGES +#: LABEL/ID_DYNAFORM_EDITOR_SAVE_CHANGES +msgid "Do you want to save changes?" +msgstr "Do you want to save changes?" + +# TRANSLATION +# LABEL/ID_REQUEST_DOCUMENTS +#: LABEL/ID_REQUEST_DOCUMENTS +msgid "Input Documents" +msgstr "Input Documents" + +# TRANSLATION +# LABEL/ID_WEBBOT +#: LABEL/ID_WEBBOT +msgid "Webbots" +msgstr "Webbots" + +# TRANSLATION +# LABEL/ID_ADD +#: LABEL/ID_ADD +msgid "Add" +msgstr "Add" + +# TRANSLATION +# LABEL/ID_USER_HAVENT_RIGHTS_SYSTEM +#: LABEL/ID_USER_HAVENT_RIGHTS_SYSTEM +msgid "User does not have access to the system" +msgstr "User does not have access to the system" + +# TRANSLATION +# LABEL/ID_START_CASE +#: LABEL/ID_START_CASE +msgid "New" +msgstr "New" + +# TRANSLATION +# LABEL/ID_NEW_GROUP +#: LABEL/ID_NEW_GROUP +msgid "[LABEL/ID_NEW_GROUP] New" +msgstr "New" + +# TRANSLATION +# LABEL/ID_MEMBERS +#: LABEL/ID_MEMBERS +msgid "Members" +msgstr "Members" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_GROUP +#: LABEL/ID_MSG_CONFIRM_DELETE_GROUP +msgid "Do you want to delete this group ?" +msgstr "Do you want to delete this group ?" + +# TRANSLATION +# APP_STATUS/DRAFT +#: APP_STATUS/DRAFT +msgid "Draft" +msgstr "Draft" + +# TRANSLATION +# LABEL/ID_INCORRECT_EMAIL +#: LABEL/ID_INCORRECT_EMAIL +msgid "Your E-mail address is not valid." +msgstr "Your E-mail address is not valid." + +# TRANSLATION +# LABEL/ID_USER_NOT_REGISTERED +#: LABEL/ID_USER_NOT_REGISTERED +msgid "User not registered!" +msgstr "User not registered!" + +# TRANSLATION +# LABEL/ID_USER_INACTIVE +#: LABEL/ID_USER_INACTIVE +msgid "User inactive!" +msgstr "User inactive!" + +# TRANSLATION +# LABEL/ID_CANNOT_CHANGE_STATUS_ADMIN_USER +#: LABEL/ID_CANNOT_CHANGE_STATUS_ADMIN_USER +msgid "Can't change the status of administrator!" +msgstr "Can't change the status of administrator!" + +# TRANSLATION +# LABEL/ID_CANNOT_DELETE_ADMIN_USER +#: LABEL/ID_CANNOT_DELETE_ADMIN_USER +msgid "Can't delete the administrator!" +msgstr "Can't delete the administrator!" + +# TRANSLATION +# LABEL/ID_ASSIGN +#: LABEL/ID_ASSIGN +msgid "Assign" +msgstr "Assign" + +# TRANSLATION +# LABEL/ID_ASSIGN_SCREEN +#: LABEL/ID_ASSIGN_SCREEN +msgid "Assign Screen" +msgstr "Assign Screen" + +# TRANSLATION +# LABEL/ID_ASSIGN_TASK +#: LABEL/ID_ASSIGN_TASK +msgid "Assign Task" +msgstr "Assign Task" + +# TRANSLATION +# LABEL/ID_UPLOAD +#: LABEL/ID_UPLOAD +msgid "Upload" +msgstr "Upload" + +# TRANSLATION +# LABEL/ID_GENERATE +#: LABEL/ID_GENERATE +msgid "Generate" +msgstr "Generate" + +# TRANSLATION +# LABEL/ID_CONFIRM_DELETE_ELEMENT +#: LABEL/ID_CONFIRM_DELETE_ELEMENT +msgid "Do you want to delete this element?" +msgstr "Do you want to delete this element?" + +# TRANSLATION +# DASHBOARD/7 +#: DASHBOARD/7 +msgid "Approval of consolidated tasks" +msgstr "Approval of consolidated tasks" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TRIGGERS +#: JAVASCRIPT/ID_PROCESSMAP_TRIGGERS +msgid "Triggers" +msgstr "Triggers" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_OUTPUT_DOCUMENTS +#: JAVASCRIPT/ID_PROCESSMAP_OUTPUT_DOCUMENTS +msgid "[JAVASCRIPT/ID_PROCESSMAP_OUTPUT_DOCUMENTS] Output Documents" +msgstr "Output Documents" + +# TRANSLATION +# LABEL/DRAFT +#: LABEL/DRAFT +msgid "[LABEL/DRAFT] Draft" +msgstr "Draft" + +# TRANSLATION +# DEL_PRIORITY/0 +#: DEL_PRIORITY/0 +msgid "Low" +msgstr "Low" + +# TRANSLATION +# DEL_PRIORITY/1 +#: DEL_PRIORITY/1 +msgid "Medium" +msgstr "Medium" + +# TRANSLATION +# DEL_PRIORITY/2 +#: DEL_PRIORITY/2 +msgid "High" +msgstr "High" + +# TRANSLATION +# LABEL/ID_PROCESSMAP_DYNAFORMS +#: LABEL/ID_PROCESSMAP_DYNAFORMS +msgid "[LABEL/ID_PROCESSMAP_DYNAFORMS] DynaForms" +msgstr "DynaForms" + +# TRANSLATION +# LABEL/ID_ATTACH +#: LABEL/ID_ATTACH +msgid "Attach" +msgstr "Attach" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_CASES +#: LABEL/ID_MSG_CONFIRM_DELETE_CASES +msgid "Are you sure you want to delete all selected cases?" +msgstr "Are you sure you want to delete all selected cases?" + +# TRANSLATION +# LABEL/ID_ALL +#: LABEL/ID_ALL +msgid "All" +msgstr "All" + +# TRANSLATION +# LABEL/ID_CANCELLED +#: LABEL/ID_CANCELLED +msgid "Canceled" +msgstr "Canceled" + +# TRANSLATION +# LABEL/ID_FINISHED +#: LABEL/ID_FINISHED +msgid "Finished" +msgstr "Finished" + +# TRANSLATION +# LABEL/ID_PAUSED +#: LABEL/ID_PAUSED +msgid "Paused" +msgstr "Paused" + +# TRANSLATION +# LABEL/ID_DERIVED +#: LABEL/ID_DERIVED +msgid "Sent" +msgstr "Sent" + +# TRANSLATION +# LABEL/ID_NOT_SENT +#: LABEL/ID_NOT_SENT +msgid "Not sent" +msgstr "Not sent" + +# TRANSLATION +# LABEL/ID_DRAFT +#: LABEL/ID_DRAFT +msgid "[LABEL/ID_DRAFT] Draft" +msgstr "Draft" + +# TRANSLATION +# LABEL/ID_COMPLETED +#: LABEL/ID_COMPLETED +msgid "Completed" +msgstr "Completed" + +# TRANSLATION +# LABEL/ID_TO_DO +#: LABEL/ID_TO_DO +msgid "To do" +msgstr "To do" + +# TRANSLATION +# LABEL/ID_PLEASE_ENTER_COMMENTS +#: LABEL/ID_PLEASE_ENTER_COMMENTS +msgid "Please enter comments!" +msgstr "Please enter comments!" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_FILE +#: LABEL/ID_PLEASE_SELECT_FILE +msgid "Please select the file to attach!" +msgstr "Please select the file to attach!" + +# TRANSLATION +# LABEL/ID_PROPERTIES +#: LABEL/ID_PROPERTIES +msgid "Properties" +msgstr "Properties" + +# TRANSLATION +# LABEL/ID_EMPTY +#: LABEL/ID_EMPTY +msgid "empty" +msgstr "empty" + +# TRANSLATION +# LABEL/ID_SELECT +#: LABEL/ID_SELECT +msgid "Select" +msgstr "Select" + +# TRANSLATION +# LABEL/ID_SEARCH +#: LABEL/ID_SEARCH +msgid "Search" +msgstr "Search" + +# TRANSLATION +# LABEL/ID_REQUIRED_FIELD +#: LABEL/ID_REQUIRED_FIELD +msgid "Required Field" +msgstr "Required Field" + +# TRANSLATION +# LABEL/ID_TRIGGERS +#: LABEL/ID_TRIGGERS +msgid "[LABEL/ID_TRIGGERS] Triggers" +msgstr "Triggers" + +# TRANSLATION +# LABEL/ID_OPEN +#: LABEL/ID_OPEN +msgid "Open" +msgstr "Open" + +# TRANSLATION +# LABEL/ID_STEPS +#: LABEL/ID_STEPS +msgid "Steps" +msgstr "Steps" + +# TRANSLATION +# LABEL/ID_INFORMATION +#: LABEL/ID_INFORMATION +msgid "Information" +msgstr "Information" + +# TRANSLATION +# LABEL/ID_ACTIONS +#: LABEL/ID_ACTIONS +msgid "Actions" +msgstr "Actions" + +# TRANSLATION +# LABEL/ID_PROCESS_INFORMATION +#: LABEL/ID_PROCESS_INFORMATION +msgid "Process Information" +msgstr "Process Information" + +# TRANSLATION +# LABEL/ID_TASK_INFORMATION +#: LABEL/ID_TASK_INFORMATION +msgid "Task Information" +msgstr "Task Information" + +# TRANSLATION +# LABEL/ID_CANCEL_CASE +#: LABEL/ID_CANCEL_CASE +msgid "Cancel Case" +msgstr "Cancel Case" + +# TRANSLATION +# LABEL/ID_YOU_ARE_FIRST_STEP +#: LABEL/ID_YOU_ARE_FIRST_STEP +msgid "You are in the first step!" +msgstr "You are in the first step!" + +# TRANSLATION +# JAVASCRIPT/EDIT_PROCESS +#: JAVASCRIPT/EDIT_PROCESS +msgid "Edit process" +msgstr "Edit process" + +# TRANSLATION +# JAVASCRIPT/curriculum +#: JAVASCRIPT/curriculum +msgid "Resume" +msgstr "Resume" + +# TRANSLATION +# JAVASCRIPT/ID_OPEN_SEARCH +#: JAVASCRIPT/ID_OPEN_SEARCH +msgid "Advanced Search" +msgstr "Advanced Search" + +# TRANSLATION +# JAVASCRIPT/ID_CLOSE_SEARCH +#: JAVASCRIPT/ID_CLOSE_SEARCH +msgid "Close Search" +msgstr "Close Search" + +# TRANSLATION +# JAVASCRIPT/ID_URL_OF_LINK +#: JAVASCRIPT/ID_URL_OF_LINK +msgid "Enter the URL for the link" +msgstr "Enter the URL for the link" + +# TRANSLATION +# JAVASCRIPT/ID_FONT_COLOR +#: JAVASCRIPT/ID_FONT_COLOR +msgid "Change text color" +msgstr "Change text color" + +# TRANSLATION +# JAVASCRIPT/ID_HILITE_COLOR +#: JAVASCRIPT/ID_HILITE_COLOR +msgid "Highlight Color" +msgstr "Highlight Color" + +# TRANSLATION +# JAVASCRIPT/ID_INSERT_HTML +#: JAVASCRIPT/ID_INSERT_HTML +msgid "Insert HTML code" +msgstr "Insert HTML code" + +# TRANSLATION +# JAVASCRIPT/ID_IMAGE_URI +#: JAVASCRIPT/ID_IMAGE_URI +msgid "Image URI" +msgstr "Image URI" + +# TRANSLATION +# JAVASCRIPT/ID_FONT_NAME +#: JAVASCRIPT/ID_FONT_NAME +msgid "Font Name" +msgstr "Font Name" + +# TRANSLATION +# JAVASCRIPT/ID_FONT_SIZE +#: JAVASCRIPT/ID_FONT_SIZE +msgid "Font Size" +msgstr "Font Size" + +# TRANSLATION +# JAVASCRIPT/ID_BACKGROUND_COLOR +#: JAVASCRIPT/ID_BACKGROUND_COLOR +msgid "Background color" +msgstr "Background color" + +# TRANSLATION +# JAVASCRIPT/ID_WHICH_BLOCK +#: JAVASCRIPT/ID_WHICH_BLOCK +msgid "Block" +msgstr "Block" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_SEQUENTIAL +#: JAVASCRIPT/ID_PROCESSMAP_SEQUENTIAL +msgid "Sequential" +msgstr "Sequential" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_SELECTION +#: JAVASCRIPT/ID_PROCESSMAP_SELECTION +msgid "Selection" +msgstr "Selection" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EVALUATION +#: JAVASCRIPT/ID_PROCESSMAP_EVALUATION +msgid "Evaluation" +msgstr "Evaluation" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PARALLEL_FORK +#: JAVASCRIPT/ID_PROCESSMAP_PARALLEL_FORK +msgid "Parallel (fork)" +msgstr "Parallel (fork)" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PARALLEL_EVALUATION_FORK +#: JAVASCRIPT/ID_PROCESSMAP_PARALLEL_EVALUATION_FORK +msgid "Parallel by Evaluation (fork)" +msgstr "Parallel by Evaluation (fork)" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PARALLEL_JOIN +#: JAVASCRIPT/ID_PROCESSMAP_PARALLEL_JOIN +msgid "Parallel (join)" +msgstr "Parallel (join)" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_INPUT_DOCUMENTS +#: JAVASCRIPT/ID_PROCESSMAP_INPUT_DOCUMENTS +msgid "[JAVASCRIPT/ID_PROCESSMAP_INPUT_DOCUMENTS] Input Documents" +msgstr "Input Documents" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_LOADING +#: JAVASCRIPT/ID_PROCESSMAP_LOADING +msgid "Loading......" +msgstr "Loading......" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EDIT_PROCESS +#: JAVASCRIPT/ID_PROCESSMAP_EDIT_PROCESS +msgid "[JAVASCRIPT/ID_PROCESSMAP_EDIT_PROCESS] Edit process" +msgstr "Edit process" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_ADD_TASK +#: JAVASCRIPT/ID_PROCESSMAP_ADD_TASK +msgid "Add task" +msgstr "Add task" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_ADD_TEXT +#: JAVASCRIPT/ID_PROCESSMAP_ADD_TEXT +msgid "Add text" +msgstr "Add text" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_HORIZONTAL_LINE +#: JAVASCRIPT/ID_PROCESSMAP_HORIZONTAL_LINE +msgid "Horizontal line" +msgstr "Horizontal line" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_VERTICAL_LINE +#: JAVASCRIPT/ID_PROCESSMAP_VERTICAL_LINE +msgid "Vertical line" +msgstr "Vertical line" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_ALL_LINES +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_ALL_LINES +msgid "Delete all lines" +msgstr "Delete all lines" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_ALL_LINES +#: JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_ALL_LINES +msgid "Do you want to delete the guide lines?" +msgstr "Do you want to delete the guide lines?" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PROMPT_RENAME_TEXT +#: JAVASCRIPT/ID_PROCESSMAP_PROMPT_RENAME_TEXT +msgid "Rename to:" +msgstr "Rename to:" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_STEPS +#: JAVASCRIPT/ID_PROCESSMAP_STEPS +msgid "[JAVASCRIPT/ID_PROCESSMAP_STEPS] Steps" +msgstr "Steps" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_STEPS +#: JAVASCRIPT/ID_PROCESSMAP_TASK_STEPS +msgid "Steps of:" +msgstr "Steps of:" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONDITIONS +#: JAVASCRIPT/ID_PROCESSMAP_CONDITIONS +msgid "Conditions" +msgstr "Conditions" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_USERS_AND_GROUPS +#: JAVASCRIPT/ID_PROCESSMAP_USERS_AND_GROUPS +msgid "Users & User Groups" +msgstr "Users & User Groups" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_PATTERNS +#: JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_PATTERNS +msgid "Routing rule" +msgstr "Routing rule" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_TASK +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_TASK +msgid "Delete task" +msgstr "Delete task" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_TASK +#: JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_TASK +msgid "Do you want to delete the task:" +msgstr "Do you want to delete the task:" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PROPERTIES +#: JAVASCRIPT/ID_PROCESSMAP_PROPERTIES +msgid "[JAVASCRIPT/ID_PROCESSMAP_PROPERTIES] Properties" +msgstr "Properties" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK +#: JAVASCRIPT/ID_PROCESSMAP_TASK +msgid "[JAVASCRIPT/ID_PROCESSMAP_TASK] Task" +msgstr "Task" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_SUBMIT +#: JAVASCRIPT/ID_PROCESSMAP_SUBMIT +msgid "Save" +msgstr "Save" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CANCEL +#: JAVASCRIPT/ID_PROCESSMAP_CANCEL +msgid "Cancel" +msgstr "Cancel" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_DEFINITION +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_DEFINITION +msgid "Definition" +msgstr "Definition" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_ASSIGNMENTS +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_ASSIGNMENTS +msgid "Designation rules" +msgstr "Designation rules" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_TIMING +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_TIMING +msgid "Timing control" +msgstr "Timing control" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_PERMISSIONS +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_PERMISSIONS +msgid "Permissions" +msgstr "Permissions" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_LABELS +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_LABELS +msgid "Case Labels" +msgstr "Case Labels" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_GUIDE +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_GUIDE +msgid "Delete line" +msgstr "Delete line" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EDIT_TEXT +#: JAVASCRIPT/ID_PROCESSMAP_EDIT_TEXT +msgid "Edit text" +msgstr "Edit text" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_TEXT +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_TEXT +msgid "Delete text" +msgstr "Delete text" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EDIT_TEXT_CHANGE_TO +#: JAVASCRIPT/ID_PROCESSMAP_EDIT_TEXT_CHANGE_TO +msgid "Change to:" +msgstr "Change to:" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONFIRM_WORKFLOW_PATTERN_CHANGE +#: JAVASCRIPT/ID_PROCESSMAP_CONFIRM_WORKFLOW_PATTERN_CHANGE +msgid "Are you sure you want to change the routing rule?" +msgstr "Are you sure you want to change the routing rule?" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_NEW_TASK +#: JAVASCRIPT/ID_PROCESSMAP_NEW_TASK +msgid "New task" +msgstr "New task" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TEXT +#: JAVASCRIPT/ID_PROCESSMAP_TEXT +msgid "Text:" +msgstr "Text:" + +# TRANSLATION +# LABEL/ID_NEW_STEP +#: LABEL/ID_NEW_STEP +msgid "New Step" +msgstr "New Step" + +# TRANSLATION +# JAVASCRIPT/ID_SAVED +#: JAVASCRIPT/ID_SAVED +msgid "DynaForm is now saved" +msgstr "DynaForm is now saved" + +# TRANSLATION +# JAVASCRIPT/ID_EXIT_WITHOUT_SAVING +#: JAVASCRIPT/ID_EXIT_WITHOUT_SAVING +msgid "Exit without saving?" +msgstr "Exit without saving?" + +# TRANSLATION +# LABEL/ID_GROUP_CHART +#: LABEL/ID_GROUP_CHART +msgid "Group Chart" +msgstr "Group Chart" + +# TRANSLATION +# LABEL/ID_WITHOUT_RESUME +#: LABEL/ID_WITHOUT_RESUME +msgid "Without resume!" +msgstr "Without resume!" + +# TRANSLATION +# LABEL/ID_NO_RESUME +#: LABEL/ID_NO_RESUME +msgid "The user doesn't have a resume." +msgstr "The user doesn't have a resume." + +# TRANSLATION +# LABEL/ID_NO_DERIVATION_RULE +#: LABEL/ID_NO_DERIVATION_RULE +msgid "Process definition error: All conditions in parallel evaluation routing rule evaluated to false, so workflow has stopped. Please change the definition of the parallel evaluation routing rule." +msgstr "Process definition error: All conditions in parallel evaluation routing rule evaluated to false, so workflow has stopped. Please change the definition of the parallel evaluation routing rule." + +# TRANSLATION +# LABEL/ID_NO_USERS +#: LABEL/ID_NO_USERS +msgid "The task doesn't have any users." +msgstr "The task doesn't have any users." + +# TRANSLATION +# LABEL/ID_CANCEL +#: LABEL/ID_CANCEL +msgid "[LABEL/ID_CANCEL] Cancel" +msgstr "Cancel" + +# TRANSLATION +# LABEL/ID_PROCESS_MAP +#: LABEL/ID_PROCESS_MAP +msgid "Process Map" +msgstr "Process Map" + +# TRANSLATION +# LABEL/ID_BEFORE_ASSIGNMENT +#: LABEL/ID_BEFORE_ASSIGNMENT +msgid "Before Assignment" +msgstr "Before Assignment" + +# TRANSLATION +# LABEL/ID_BEFORE_DERIVATION +#: LABEL/ID_BEFORE_DERIVATION +msgid "Before Derivation" +msgstr "Before Derivation" + +# TRANSLATION +# LABEL/ID_AFTER_DERIVATION +#: LABEL/ID_AFTER_DERIVATION +msgid "After Derivation" +msgstr "After Derivation" + +# TRANSLATION +# LABEL/ID_BEFORE +#: LABEL/ID_BEFORE +msgid "Before" +msgstr "Before" + +# TRANSLATION +# LABEL/ID_AFTER +#: LABEL/ID_AFTER +msgid "After" +msgstr "After" + +# TRANSLATION +# JAVASCRIPT/ID_TRANSFER_HISTORY +#: JAVASCRIPT/ID_TRANSFER_HISTORY +msgid "Transfer History" +msgstr "Transfer History" + +# TRANSLATION +# LABEL/ID_TRANSFER_HISTORY +#: LABEL/ID_TRANSFER_HISTORY +msgid "[LABEL/ID_TRANSFER_HISTORY] Transfer History" +msgstr "Transfer History" + +# TRANSLATION +# LABEL/ID_ENABLED +#: LABEL/ID_ENABLED +msgid "Enabled" +msgstr "Enabled" + +# TRANSLATION +# JAVASCRIPT/ID_NO_DERIVATIONS_DEFINED +#: JAVASCRIPT/ID_NO_DERIVATIONS_DEFINED +msgid "No derivations were defined." +msgstr "No derivations were defined." + +# TRANSLATION +# LABEL/ID_ROWS +#: LABEL/ID_ROWS +msgid "Rows" +msgstr "Rows" + +# TRANSLATION +# LABEL/ID_MEMBER +#: LABEL/ID_MEMBER +msgid "Member" +msgstr "Member" + +# TRANSLATION +# LABEL/ID_USER +#: LABEL/ID_USER +msgid "User" +msgstr "User" + +# TRANSLATION +# LABEL/ID_FILE_TOO_BIG +#: LABEL/ID_FILE_TOO_BIG +msgid "The file is too big to upload!" +msgstr "The file is too big to upload!" + +# TRANSLATION +# LABEL/ID_EDIT_CONDITIONS_OF_STEP +#: LABEL/ID_EDIT_CONDITIONS_OF_STEP +msgid "Edit step conditions" +msgstr "Edit step conditions" + +# TRANSLATION +# LABEL/ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING +#: LABEL/ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING +msgid "Save changes to the routing rules before closing?" +msgstr "Save changes to the routing rules before closing?" + +# TRANSLATION +# JAVASCRIPT/ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING +#: JAVASCRIPT/ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING +msgid "[JAVASCRIPT/ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING] Save changes to the routing rules before closing?" +msgstr "Save changes to the routing rules before closing?" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_DELETE_PATTERNS +#: JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_DELETE_PATTERNS +msgid "Delete Routing rule" +msgstr "Delete Routing rule" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_CONFIRM_DELETE_PATTERNS +#: JAVASCRIPT/ID_PROCESSMAP_WORKFLOW_CONFIRM_DELETE_PATTERNS +msgid "Are you sure you want to delete the routing rules?" +msgstr "Are you sure you want to delete the routing rules?" + +# TRANSLATION +# JAVASCRIPT/ID_END_OF_PROCESS +#: JAVASCRIPT/ID_END_OF_PROCESS +msgid "[JAVASCRIPT/ID_END_OF_PROCESS] End of process" +msgstr "End of process" + +# TRANSLATION +# JAVASCRIPT/ACCEPT +#: JAVASCRIPT/ACCEPT +msgid "Accept" +msgstr "Accept" + +# TRANSLATION +# JAVASCRIPT/CANCEL +#: JAVASCRIPT/CANCEL +msgid "[JAVASCRIPT/CANCEL] Cancel" +msgstr "Cancel" + +# TRANSLATION +# LABEL/ID_GROUP_INACTIVE +#: LABEL/ID_GROUP_INACTIVE +msgid "Group inactive" +msgstr "Group inactive" + +# TRANSLATION +# LABEL/ID_JUMP +#: LABEL/ID_JUMP +msgid "Jump" +msgstr "Jump" + +# TRANSLATION +# LABEL/ID_CASE_HISTORY +#: LABEL/ID_CASE_HISTORY +msgid "Case History" +msgstr "Case History" + +# TRANSLATION +# JAVASCRIPT/ID_CASE_HISTORY +#: JAVASCRIPT/ID_CASE_HISTORY +msgid "[JAVASCRIPT/ID_CASE_HISTORY] Case History" +msgstr "Case History" + +# TRANSLATION +# JAVASCRIPT/ID_COLOR_LEYENDS +#: JAVASCRIPT/ID_COLOR_LEYENDS +msgid "Key" +msgstr "Key" + +# TRANSLATION +# LABEL/ID_PREVIEW +#: LABEL/ID_PREVIEW +msgid "Preview" +msgstr "Preview" + +# TRANSLATION +# LABEL/ID_XML +#: LABEL/ID_XML +msgid "XML" +msgstr "XML" + +# TRANSLATION +# LABEL/ID_HTML +#: LABEL/ID_HTML +msgid "HTML" +msgstr "HTML" + +# TRANSLATION +# LABEL/ID_FIELDS_LIST +#: LABEL/ID_FIELDS_LIST +msgid "Fields handler" +msgstr "Fields handler" + +# TRANSLATION +# LABEL/ID_JAVASCRIPTS +#: LABEL/ID_JAVASCRIPTS +msgid "JavaScripts" +msgstr "JavaScripts" + +# TRANSLATION +# LABEL/ID_TASK_IN_PROGRESS +#: LABEL/ID_TASK_IN_PROGRESS +msgid "Task in Progress" +msgstr "Task in Progress" + +# TRANSLATION +# LABEL/ID_COMPLETED_TASK +#: LABEL/ID_COMPLETED_TASK +msgid "Completed Task" +msgstr "Completed Task" + +# TRANSLATION +# LABEL/ID_PENDING_TASK +#: LABEL/ID_PENDING_TASK +msgid "Pending Task / Not Executed" +msgstr "Pending Task / Not Executed" + +# TRANSLATION +# LABEL/ID_PARALLEL_TASK +#: LABEL/ID_PARALLEL_TASK +msgid "Parallel Task" +msgstr "Parallel Task" + +# TRANSLATION +# JAVASCRIPT/ID_CLICK_VIEW_MORE_INFO +#: JAVASCRIPT/ID_CLICK_VIEW_MORE_INFO +msgid "Click here to view more info" +msgstr "Click here to view more info" + +# TRANSLATION +# LABEL/TO_DO +#: LABEL/TO_DO +msgid "To Do" +msgstr "To Do" + +# TRANSLATION +# LABEL/PAUSED +#: LABEL/PAUSED +msgid "Pause" +msgstr "Pause" + +# TRANSLATION +# LABEL/COMPLETED +#: LABEL/COMPLETED +msgid "[LABEL/COMPLETED] Completed" +msgstr "Completed" + +# TRANSLATION +# LABEL/CANCELLED +#: LABEL/CANCELLED +msgid "[LABEL/CANCELLED] Canceled" +msgstr "Canceled" + +# TRANSLATION +# LABEL/ID_NOT_FINISHED +#: LABEL/ID_NOT_FINISHED +msgid "Not finished" +msgstr "Not finished" + +# TRANSLATION +# LABEL/ID_HOUR +#: LABEL/ID_HOUR +msgid "Hour" +msgstr "Hour" + +# TRANSLATION +# LABEL/ID_HOURS +#: LABEL/ID_HOURS +msgid "Hours" +msgstr "Hours" + +# TRANSLATION +# LABEL/ID_MINUTE +#: LABEL/ID_MINUTE +msgid "Minute" +msgstr "Minute" + +# TRANSLATION +# LABEL/ID_MINUTES +#: LABEL/ID_MINUTES +msgid "Minutes" +msgstr "Minutes" + +# TRANSLATION +# LABEL/ID_SECOND +#: LABEL/ID_SECOND +msgid "Second" +msgstr "Second" + +# TRANSLATION +# LABEL/ID_SECONDS +#: LABEL/ID_SECONDS +msgid "Seconds" +msgstr "Seconds" + +# TRANSLATION +# LABEL/ID_NONE +#: LABEL/ID_NONE +msgid "None" +msgstr "None" + +# TRANSLATION +# LABEL/ID_CASE_NOT_YET_STARTED +#: LABEL/ID_CASE_NOT_YET_STARTED +msgid "Case not yet started" +msgstr "Case not yet started" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_CANCEL_CASE +#: JAVASCRIPT/ID_CONFIRM_CANCEL_CASE +msgid "Are you sure you want to cancel this case?" +msgstr "Are you sure you want to cancel this case?" + +# TRANSLATION +# LABEL/ID_SETUP +#: LABEL/ID_SETUP +msgid "Admin" +msgstr "Admin" + +# TRANSLATION +# LABEL/ID_PREVIOUS_STEP +#: LABEL/ID_PREVIOUS_STEP +msgid "Previous Step" +msgstr "Previous Step" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_REMOVE_USER +#: LABEL/ID_MSG_CONFIRM_REMOVE_USER +msgid "[LABEL/ID_MSG_CONFIRM_REMOVE_USER] Are you sure you want to remove this user?" +msgstr "Are you sure you want to remove this user?" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DEASIGN_USER_GROUP_MESSAGE +#: LABEL/ID_MSG_CONFIRM_DEASIGN_USER_GROUP_MESSAGE +msgid "Are you sure you want to remove this user or group?" +msgstr "Are you sure you want to remove this user or group?" + +# TRANSLATION +# LABEL/ID_DASHBOARD +#: LABEL/ID_DASHBOARD +msgid "DASHBOARD" +msgstr "DASHBOARD" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_REMOVE_TRIGGER +#: LABEL/ID_MSG_CONFIRM_REMOVE_TRIGGER +msgid "Are you sure you want to remove this trigger?" +msgstr "Are you sure you want to remove this trigger?" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_TRIGGER +#: JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_TRIGGER +msgid "[JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_TRIGGER] Are you sure you want to remove this trigger?" +msgstr "Are you sure you want to remove this trigger?" + +# TRANSLATION +# LABEL/ID_NEW +#: LABEL/ID_NEW +msgid "[LABEL/ID_NEW] New" +msgstr "New" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_REMOVE_TRIGGER +#: JAVASCRIPT/ID_CONFIRM_REMOVE_TRIGGER +msgid "[JAVASCRIPT/ID_CONFIRM_REMOVE_TRIGGER] Are you sure you want to remove this trigger?" +msgstr "Are you sure you want to remove this trigger?" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EXPORT_PROCESS +#: JAVASCRIPT/ID_PROCESSMAP_EXPORT_PROCESS +msgid "Export Process" +msgstr "Export Process" + +# TRANSLATION +# JAVASCRIPT/ID_INVALID_EMAIL +#: JAVASCRIPT/ID_INVALID_EMAIL +msgid "The E-mail address is not valid." +msgstr "The E-mail address is not valid." + +# TRANSLATION +# LABEL/ID_NOT_WORKSPACE +#: LABEL/ID_NOT_WORKSPACE +msgid "You have specified an unavailable workspace." +msgstr "You have specified an unavailable workspace." + +# TRANSLATION +# LABEL/ID_REPORT_TABLES +#: LABEL/ID_REPORT_TABLES +msgid "Report Tables" +msgstr "Report Tables" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_REPORT_TABLES +#: JAVASCRIPT/ID_PROCESSMAP_REPORT_TABLES +msgid "[JAVASCRIPT/ID_PROCESSMAP_REPORT_TABLES] Report Tables" +msgstr "Report Tables" + +# TRANSLATION +# LABEL/ID_NEW_REPORT_TABLE +#: LABEL/ID_NEW_REPORT_TABLE +msgid "New Report Table" +msgstr "New Report Table" + +# TRANSLATION +# LABEL/ID_EDIT_REPORT_TABLE +#: LABEL/ID_EDIT_REPORT_TABLE +msgid "Edit Report Table" +msgstr "Edit Report Table" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_REPORT_TABLE +#: LABEL/ID_MSG_CONFIRM_DELETE_REPORT_TABLE +msgid "Do you want to delete this report table?" +msgstr "Do you want to delete this report table?" + +# TRANSLATION +# LABEL/ID_PLEASE_ENTER_REQUIRED_FIELDS +#: LABEL/ID_PLEASE_ENTER_REQUIRED_FIELDS +msgid "Please enter the required fields" +msgstr "Please enter the required fields" + +# TRANSLATION +# LABEL/ID_TABLE_ALREADY_EXISTS +#: LABEL/ID_TABLE_ALREADY_EXISTS +msgid "Table already exists" +msgstr "Table already exists" + +# TRANSLATION +# LABEL/ID_LANGUAGES +#: LABEL/ID_LANGUAGES +msgid "Language" +msgstr "Language" + +# TRANSLATION +# LABEL/ID_EXPORT +#: LABEL/ID_EXPORT +msgid "Export" +msgstr "Export" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_REMOVE_LANGUAGE +#: LABEL/ID_MSG_CONFIRM_REMOVE_LANGUAGE +msgid "Are you sure you want to remove this language?" +msgstr "Are you sure you want to remove this language?" + +# TRANSLATION +# LABEL/ID_MSG_CANNOT_REMOVE_LANGUAGE +#: LABEL/ID_MSG_CANNOT_REMOVE_LANGUAGE +msgid "You cannot delete the default language" +msgstr "You cannot delete the default language" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_PO_FILE +#: LABEL/ID_PLEASE_SELECT_PO_FILE +msgid "Please select a .po file" +msgstr "Please select a .po file" + +# TRANSLATION +# LABEL/ID_EMAIL +#: LABEL/ID_EMAIL +msgid "Email" +msgstr "Email" + +# TRANSLATION +# LABEL/ID_REPORT3 +#: LABEL/ID_REPORT3 +msgid "Number of cases per month" +msgstr "Number of cases per month" + +# TRANSLATION +# JAVASCRIPT/ID_ROLES_CAN_NOT_DELETE +#: JAVASCRIPT/ID_ROLES_CAN_NOT_DELETE +msgid "This role cannot be deleted while it still has some assigned users." +msgstr "This role cannot be deleted while it still has some assigned users." + +# TRANSLATION +# LABEL/ID_PERMISSIONS +#: LABEL/ID_PERMISSIONS +msgid "[LABEL/ID_PERMISSIONS] Permissions" +msgstr "Permissions" + +# TRANSLATION +# LABEL/ID_MESSAGE_SUBJECT_DERIVATION +#: LABEL/ID_MESSAGE_SUBJECT_DERIVATION +msgid "Notification for task assignment" +msgstr "Notification for task assignment" + +# TRANSLATION +# LABEL/ID_PERMITIONS +#: LABEL/ID_PERMITIONS +msgid "[LABEL/ID_PERMITIONS] Permissions" +msgstr "Permissions" + +# TRANSLATION +# LABEL/ID_ASSIGN_ROLE +#: LABEL/ID_ASSIGN_ROLE +msgid "Assign user" +msgstr "Assign user" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_DELETE_SUPERVISOR_PROCESSUSER +#: JAVASCRIPT/ID_MSG_CONFIRM_DELETE_SUPERVISOR_PROCESSUSER +msgid "Do you want to delete this supervisor?" +msgstr "Do you want to delete this supervisor?" + +# TRANSLATION +# LABEL/ID_REMOVE +#: LABEL/ID_REMOVE +msgid "[LABEL/ID_REMOVE] Remove" +msgstr "Remove" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM +#: JAVASCRIPT/ID_MSG_CONFIRM +msgid "Are you sure?" +msgstr "Are you sure?" + +# TRANSLATION +# JAVASCRIPT/ID_ROLES_MSG2 +#: JAVASCRIPT/ID_ROLES_MSG2 +msgid "Role already exists! Please choose another." +msgstr "Role already exists! Please choose another." + +# TRANSLATION +# LABEL/ID_FOLDERS +#: LABEL/ID_FOLDERS +msgid "Documents" +msgstr "Documents" + +# TRANSLATION +# JAVASCRIPT/ID_ROLES_MSG1 +#: JAVASCRIPT/ID_ROLES_MSG1 +msgid "You must specify a role code!" +msgstr "You must specify a role code!" + +# TRANSLATION +# JAVASCRIPT/ID_REMOVE_ROLE +#: JAVASCRIPT/ID_REMOVE_ROLE +msgid "Are you sure you want to delete this role?" +msgstr "Are you sure you want to delete this role?" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_SUPERVISOR_DYNAFORM +#: LABEL/ID_MSG_CONFIRM_DELETE_SUPERVISOR_DYNAFORM +msgid "Do you want to remove this DynaForm?" +msgstr "Do you want to remove this DynaForm?" + +# TRANSLATION +# LABEL/VIEW_ROLE_USERS +#: LABEL/VIEW_ROLE_USERS +msgid "[LABEL/VIEW_ROLE_USERS] Users" +msgstr "Users" + +# TRANSLATION +# LABEL/ID_ROLES +#: LABEL/ID_ROLES +msgid "Roles" +msgstr "Roles" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_NOTIFICATIONS +#: JAVASCRIPT/ID_PROCESSMAP_TASK_PROPERTIES_NOTIFICATIONS +msgid "Notifications" +msgstr "Notifications" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_DYNAFORMS +#: JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_DYNAFORMS +msgid "[JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_DYNAFORMS] DynaForms" +msgstr "DynaForms" + +# TRANSLATION +# JAVASCRIPT/ID_ASSIGN_DYNAFORM +#: JAVASCRIPT/ID_ASSIGN_DYNAFORM +msgid "Assign DynaForm" +msgstr "Assign DynaForm" + +# TRANSLATION +# LABEL/ID_TO_REVISE +#: LABEL/ID_TO_REVISE +msgid "Review" +msgstr "Review" + +# TRANSLATION +# LABEL/ID_MESS_ENGINE_TYPE_3 +#: LABEL/ID_MESS_ENGINE_TYPE_3 +msgid "SMTP (OpenMail)" +msgstr "SMTP (OpenMail)" + +# TRANSLATION +# LABEL/ID_MESS_TEST_MESSAGE_ERROR_PHP_MAIL +#: LABEL/ID_MESS_TEST_MESSAGE_ERROR_PHP_MAIL +msgid "Test message send failed, error:" +msgstr "Test message send failed, error:" + +# TRANSLATION +# LABEL/ID_MESS_TEST_MESSAGE_SENDED +#: LABEL/ID_MESS_TEST_MESSAGE_SENDED +msgid "Test message sent successfully" +msgstr "Test message sent successfully" + +# TRANSLATION +# LABEL/ID_MESS_ENGINE_TYPE_2 +#: LABEL/ID_MESS_ENGINE_TYPE_2 +msgid "SMTP (PHPMailer)" +msgstr "SMTP (PHPMailer)" + +# TRANSLATION +# LABEL/ID_MESS_ENGINE_TYPE_1 +#: LABEL/ID_MESS_ENGINE_TYPE_1 +msgid "Mail (PHP)" +msgstr "Mail (PHP)" + +# TRANSLATION +# LABEL/ID_MESS_TEST_BODY +#: LABEL/ID_MESS_TEST_BODY +msgid "ProcessMaker Test Email" +msgstr "ProcessMaker Test Email" + +# TRANSLATION +# LABEL/ID_MESS_TEST_SUBJECT +#: LABEL/ID_MESS_TEST_SUBJECT +msgid "Test Email" +msgstr "Test Email" + +# TRANSLATION +# JAVASCRIPT/ID_MESS_TEST_FROM_EMAIL +#: JAVASCRIPT/ID_MESS_TEST_FROM_EMAIL +msgid "The 'From Email' field is required" +msgstr "The 'From Email' field is required" + +# TRANSLATION +# JAVASCRIPT/ID_MESS_TEST_TO +#: JAVASCRIPT/ID_MESS_TEST_TO +msgid "The 'To' field is required" +msgstr "The 'To' field is required" + +# TRANSLATION +# LABEL/ID_MESS_SEND_MAX_REQUIRED +#: LABEL/ID_MESS_SEND_MAX_REQUIRED +msgid "The maximum number of attempts to send mail is a required field." +msgstr "The maximum number of attempts to send mail is a required field." + +# TRANSLATION +# JAVASCRIPT/ID_MESS_EXECUTE_EVERY_REQUIRED +#: JAVASCRIPT/ID_MESS_EXECUTE_EVERY_REQUIRED +msgid "The 'Execute Every' field is required" +msgstr "The 'Execute Every' field is required" + +# TRANSLATION +# JAVASCRIPT/ID_MESS_ACCOUNT_REQUIRED +#: JAVASCRIPT/ID_MESS_ACCOUNT_REQUIRED +msgid "The email account is required" +msgstr "The email account is required" + +# TRANSLATION +# JAVASCRIPT/ID_DBS_EDIT +#: JAVASCRIPT/ID_DBS_EDIT +msgid "Edit the current Database Source" +msgstr "Edit the current Database Source" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PROCESS_SUPERVISORS +#: JAVASCRIPT/ID_PROCESSMAP_PROCESS_SUPERVISORS +msgid "Supervisors" +msgstr "Supervisors" + +# TRANSLATION +# JAVASCRIPT/ID_MESS_SERVER_REQUIRED +#: JAVASCRIPT/ID_MESS_SERVER_REQUIRED +msgid "The email server is required" +msgstr "The email server is required" + +# TRANSLATION +# LABEL/ID_DBS_EDIT +#: LABEL/ID_DBS_EDIT +msgid "[LABEL/ID_DBS_EDIT] Edit the current Database Source" +msgstr "Edit the current Database Source" + +# TRANSLATION +# JAVASCRIPT/ID_DBS_NEW +#: JAVASCRIPT/ID_DBS_NEW +msgid "Add new Database Source" +msgstr "Add new Database Source" + +# TRANSLATION +# JAVASCRIPT/ID_DBS_LIST +#: JAVASCRIPT/ID_DBS_LIST +msgid "Databases Source List" +msgstr "Databases Source List" + +# TRANSLATION +# LABEL/ID_CHANGES_SAVED +#: LABEL/ID_CHANGES_SAVED +msgid "Changes saved" +msgstr "Changes saved" + +# TRANSLATION +# LABEL/ID_EMAILS +#: LABEL/ID_EMAILS +msgid "EMAILS" +msgstr "EMAILS" + +# TRANSLATION +# LABEL/ID_REPORT2 +#: LABEL/ID_REPORT2 +msgid "Number of cases per process" +msgstr "Number of cases per process" + +# TRANSLATION +# LABEL/ID_REPORT1 +#: LABEL/ID_REPORT1 +msgid "Case duration by process and task" +msgstr "Case duration by process and task" + +# TRANSLATION +# LABEL/ID_IUD +#: LABEL/ID_IUD +msgid "#" +msgstr "#" + +# TRANSLATION +# LABEL/ID_REPORTS +#: LABEL/ID_REPORTS +msgid "Reports" +msgstr "Reports" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_DBS +#: JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_DBS +msgid "Are you sure you want to remove this DB Connection?" +msgstr "Are you sure you want to remove this DB Connection?" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG6 +#: JAVASCRIPT/DBCONNECTIONS_MSG6 +msgid "You must specify a user!" +msgstr "You must specify a user!" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG7 +#: JAVASCRIPT/DBCONNECTIONS_MSG7 +msgid "Loading test, please wait!..." +msgstr "Loading test, please wait!..." + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG5 +#: JAVASCRIPT/DBCONNECTIONS_MSG5 +msgid "You must specify a data base name!" +msgstr "You must specify a data base name!" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG4 +#: JAVASCRIPT/DBCONNECTIONS_MSG4 +msgid "Please specify a database server!" +msgstr "Please specify a database server!" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG3 +#: JAVASCRIPT/DBCONNECTIONS_MSG3 +msgid "Testing" +msgstr "Testing" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG2 +#: JAVASCRIPT/DBCONNECTIONS_MSG2 +msgid "Failed" +msgstr "Failed" + +# TRANSLATION +# LABEL/DBCONNECTIOS_MSG2 +#: LABEL/DBCONNECTIOS_MSG2 +msgid "FAILED" +msgstr "FAILED" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSG1 +#: JAVASCRIPT/DBCONNECTIONS_MSG1 +msgid "DONE" +msgstr "DONE" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIOS_MSG1 +#: JAVASCRIPT/DBCONNECTIOS_MSG1 +msgid "[JAVASCRIPT/DBCONNECTIOS_MSG1] DONE" +msgstr "DONE" + +# TRANSLATION +# JAVASCRIPT/ID_NEW_DBC +#: JAVASCRIPT/ID_NEW_DBC +msgid "New Database Connection" +msgstr "New Database Connection" + +# TRANSLATION +# LABEL/ID_EDIT_DBC +#: LABEL/ID_EDIT_DBC +msgid "Edit Database Connection" +msgstr "Edit Database Connection" + +# TRANSLATION +# LABEL/ID_DB_CONNECTIONS +#: LABEL/ID_DB_CONNECTIONS +msgid "Database Connections" +msgstr "Database Connections" + +# TRANSLATION +# LABEL/ID_PRIORITY_N +#: LABEL/ID_PRIORITY_N +msgid "NORMAL" +msgstr "NORMAL" + +# TRANSLATION +# LABEL/ID_PRIORITY_L +#: LABEL/ID_PRIORITY_L +msgid "LOW" +msgstr "LOW" + +# TRANSLATION +# LABEL/ID_PRIORITY_VL +#: LABEL/ID_PRIORITY_VL +msgid "VERY LOW" +msgstr "VERY LOW" + +# TRANSLATION +# LABEL/ID_PRIORITY_H +#: LABEL/ID_PRIORITY_H +msgid "HIGH" +msgstr "HIGH" + +# TRANSLATION +# LABEL/ID_GENERAL +#: LABEL/ID_GENERAL +msgid "General" +msgstr "General" + +# TRANSLATION +# LABEL/ID_REASSIGN +#: LABEL/ID_REASSIGN +msgid "Reassign" +msgstr "Reassign" + +# TRANSLATION +# LABEL/ID_PRIORITY_VH +#: LABEL/ID_PRIORITY_VH +msgid "VERY HIGH" +msgstr "VERY HIGH" + +# TRANSLATION +# LABEL/ID_GROUPS +#: LABEL/ID_GROUPS +msgid "[LABEL/ID_GROUPS] Groups" +msgstr "Groups" + +# TRANSLATION +# LABEL/ID_CONFIRM_DELETE_CASE +#: LABEL/ID_CONFIRM_DELETE_CASE +msgid "Are you sure you want to delete this case?" +msgstr "Are you sure you want to delete this case?" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_DELETE_CASE +#: JAVASCRIPT/ID_CONFIRM_DELETE_CASE +msgid "[JAVASCRIPT/ID_CONFIRM_DELETE_CASE] Are you sure you want to delete this case?" +msgstr "Are you sure you want to delete this case?" + +# TRANSLATION +# LABEL/ID_ACTIVATE +#: LABEL/ID_ACTIVATE +msgid "Activate" +msgstr "Activate" + +# TRANSLATION +# LABEL/ID_DEACTIVATE +#: LABEL/ID_DEACTIVATE +msgid "Deactivate" +msgstr "Deactivate" + +# TRANSLATION +# LABEL/ID_CASECANCEL +#: LABEL/ID_CASECANCEL +msgid "No actions available for this case." +msgstr "No actions available for this case." + +# TRANSLATION +# LABEL/ID_UNPAUSE +#: LABEL/ID_UNPAUSE +msgid "Unpause" +msgstr "Unpause" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_PAUSE_CASE +#: JAVASCRIPT/ID_CONFIRM_PAUSE_CASE +msgid "Are you sure you want to pause this case?" +msgstr "Are you sure you want to pause this case?" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_USERGROUP +#: JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_USERGROUP +msgid "Are you sure you want to remove this user group?" +msgstr "Are you sure you want to remove this user group?" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_REMOVE_USERGROUP +#: LABEL/ID_MSG_CONFIRM_REMOVE_USERGROUP +msgid "[LABEL/ID_MSG_CONFIRM_REMOVE_USERGROUP] Are you sure you want to remove this user group?" +msgstr "Are you sure you want to remove this user group?" + +# TRANSLATION +# LABEL/ID_MSG_ASSIGN_DONE +#: LABEL/ID_MSG_ASSIGN_DONE +msgid "User successfully assigned to group" +msgstr "User successfully assigned to group" + +# TRANSLATION +# LABEL/ID_ASSIGN_GROUP +#: LABEL/ID_ASSIGN_GROUP +msgid "Assign group" +msgstr "Assign group" + +# TRANSLATION +# LABEL/ID_BACK_TO_GROUP_LIST +#: LABEL/ID_BACK_TO_GROUP_LIST +msgid "Back to user groups" +msgstr "Back to user groups" + +# TRANSLATION +# LABEL/ID_ASSIGN_GROUP_TO +#: LABEL/ID_ASSIGN_GROUP_TO +msgid "Assign group to" +msgstr "Assign group to" + +# TRANSLATION +# LABEL/ID_PAUSED_CASE +#: LABEL/ID_PAUSED_CASE +msgid "[LABEL/ID_PAUSED_CASE] Pause" +msgstr "Pause" + +# TRANSLATION +# LABEL/ID_VIEW_USER_GROUP +#: LABEL/ID_VIEW_USER_GROUP +msgid "[LABEL/ID_VIEW_USER_GROUP] Groups" +msgstr "Groups" + +# TRANSLATION +# LABEL/ID_EDIT_VIEW_USER_GROUP +#: LABEL/ID_EDIT_VIEW_USER_GROUP +msgid "View user groups" +msgstr "View user groups" + +# TRANSLATION +# JAVASCRIPT/ID_MSJ +#: JAVASCRIPT/ID_MSJ +msgid "Group name already exists!" +msgstr "Group name already exists!" + +# TRANSLATION +# LABEL/ID_REACTIVATE +#: LABEL/ID_REACTIVATE +msgid "Reactivate" +msgstr "Reactivate" + +# TRANSLATION +# LABEL/ID_USER_GROUPS +#: LABEL/ID_USER_GROUPS +msgid "Groups for" +msgstr "Groups for" + +# TRANSLATION +# LABEL/ID_FUNCTION +#: LABEL/ID_FUNCTION +msgid "@function() It evaluates the value, then executes a PHP function" +msgstr "@function() It evaluates the value, then executes a PHP function" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_REACTIVATE_CASES +#: JAVASCRIPT/ID_MSG_CONFIRM_REACTIVATE_CASES +msgid "Are you sure you want to reactivate this case?" +msgstr "Are you sure you want to reactivate this case?" + +# TRANSLATION +# LABEL/ID_CONFIRM_REACTIVATE_CASE +#: LABEL/ID_CONFIRM_REACTIVATE_CASE +msgid "[LABEL/ID_CONFIRM_REACTIVATE_CASE] Are you sure you want to reactivate this case?" +msgstr "Are you sure you want to reactivate this case?" + +# TRANSLATION +# LABEL/ID_ESCSJS +#: LABEL/ID_ESCSJS +msgid "@@ It replaces the value in single quotation marks to use it in JavaScript sentences." +msgstr "@@ It replaces the value in single quotation marks to use it in JavaScript sentences." + +# TRANSLATION +# LABEL/ID_ESCJS +#: LABEL/ID_ESCJS +msgid "@@ It replaces the value in quotation marks to use it in JavaScript sentences" +msgstr "@@ It replaces the value in quotation marks to use it in JavaScript sentences" + +# TRANSLATION +# LABEL/ID_ESC +#: LABEL/ID_ESC +msgid "@@ Replace the value in quotes" +msgstr "@@ Replace the value in quotes" + +# TRANSLATION +# LABEL/ID_NONEC +#: LABEL/ID_NONEC +msgid "@# Replace the value with no change" +msgstr "@# Replace the value with no change" + +# TRANSLATION +# LABEL/ID_EURL +#: LABEL/ID_EURL +msgid "@% It replaces the value for the assignment with a GET variable in the URL" +msgstr "@% It replaces the value for the assignment with a GET variable in the URL" + +# TRANSLATION +# LABEL/ID_EVAL +#: LABEL/ID_EVAL +msgid "@! It evaluates the value, then replaces it" +msgstr "@! It evaluates the value, then replaces it" + +# TRANSLATION +# LABEL/ID_NCAMBIO +#: LABEL/ID_NCAMBIO +msgid "@#, Replaces the value without any change." +msgstr "@#, Replaces the value without any change." + +# TRANSLATION +# LABEL/ID_DOCLICK +#: LABEL/ID_DOCLICK +msgid "Double click to insert" +msgstr "Double click to insert" + +# TRANSLATION +# LABEL/ID_CASE_IS_CURRENTLY_WITH_ANOTHER_USER +#: LABEL/ID_CASE_IS_CURRENTLY_WITH_ANOTHER_USER +msgid "The case is currently opened by another user" +msgstr "The case is currently opened by another user" + +# TRANSLATION +# LABEL/ID_IN +#: LABEL/ID_IN +msgid "in" +msgstr "in" + +# TRANSLATION +# LABEL/ID_CASE_DOES_NOT_EXISTS +#: LABEL/ID_CASE_DOES_NOT_EXISTS +msgid "This case does not exist" +msgstr "This case does not exist" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_UPGRADE_FILE +#: LABEL/ID_PLEASE_SELECT_UPGRADE_FILE +msgid "Please select the upgrade file" +msgstr "Please select the upgrade file" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_MAX_X_FIELDS +#: LABEL/ID_PLEASE_SELECT_MAX_X_FIELDS +msgid "Please select 80 fields at most" +msgstr "Please select 80 fields at most" + +# TRANSLATION +# LABEL/ID_UPGRADE_READY +#: LABEL/ID_UPGRADE_READY +msgid "System upgraded from revision" +msgstr "System upgraded from revision" + +# TRANSLATION +# LABEL/ID_UPGRADE +#: LABEL/ID_UPGRADE +msgid "Upgrade System" +msgstr "Upgrade System" + +# TRANSLATION +# LABEL/ID_UPLOADED_DOCUMENTS +#: LABEL/ID_UPLOADED_DOCUMENTS +msgid "Uploaded Documents" +msgstr "Uploaded Documents" + +# TRANSLATION +# JAVASCRIPT/ID_TASK_INFORMATION +#: JAVASCRIPT/ID_TASK_INFORMATION +msgid "[JAVASCRIPT/ID_TASK_INFORMATION] Task Information" +msgstr "Task Information" + +# TRANSLATION +# JAVASCRIPT/ID_UPLOADED_DOCUMENTS +#: JAVASCRIPT/ID_UPLOADED_DOCUMENTS +msgid "[JAVASCRIPT/ID_UPLOADED_DOCUMENTS] Uploaded Documents" +msgstr "Uploaded Documents" + +# TRANSLATION +# LABEL/ID_GENERATED_DOCUMENTS +#: LABEL/ID_GENERATED_DOCUMENTS +msgid "Generated Documents" +msgstr "Generated Documents" + +# TRANSLATION +# JAVASCRIPT/ID_GENERATED_DOCUMENTS +#: JAVASCRIPT/ID_GENERATED_DOCUMENTS +msgid "[JAVASCRIPT/ID_GENERATED_DOCUMENTS] Generated Documents" +msgstr "Generated Documents" + +# TRANSLATION +# LABEL/ID_REPORT4 +#: LABEL/ID_REPORT4 +msgid "Number of cases per starting user" +msgstr "Number of cases per starting user" + +# TRANSLATION +# LABEL/ID_REPORT5 +#: LABEL/ID_REPORT5 +msgid "Number of cases per executing user" +msgstr "Number of cases per executing user" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC +#: JAVASCRIPT/ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC +msgid "Users & User Groups (Ad hoc)" +msgstr "Users & User Groups (Ad hoc)" + +# TRANSLATION +# LABEL/ID_SETUP_WEBSERVICES +#: LABEL/ID_SETUP_WEBSERVICES +msgid "Setup" +msgstr "Setup" + +# TRANSLATION +# LABEL/ID_WEB_SERVICES +#: LABEL/ID_WEB_SERVICES +msgid "Web Services Test" +msgstr "Web Services Test" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESS_INFORMATION +#: JAVASCRIPT/ID_PROCESS_INFORMATION +msgid "[JAVASCRIPT/ID_PROCESS_INFORMATION] Process Information" +msgstr "Process Information" + +# TRANSLATION +# JAVASCRIPT/ID_INFORMATION +#: JAVASCRIPT/ID_INFORMATION +msgid "[JAVASCRIPT/ID_INFORMATION] Information" +msgstr "Information" + +# TRANSLATION +# JAVASCRIPT/ID_ACTIONS +#: JAVASCRIPT/ID_ACTIONS +msgid "[JAVASCRIPT/ID_ACTIONS] Actions" +msgstr "Actions" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESS_MAP +#: JAVASCRIPT/ID_PROCESS_MAP +msgid "[JAVASCRIPT/ID_PROCESS_MAP] Process Map" +msgstr "Process Map" + +# TRANSLATION +# JAVASCRIPT/ID_ADHOC_ASSIGNMENT +#: JAVASCRIPT/ID_ADHOC_ASSIGNMENT +msgid "Ad Hoc Assignment" +msgstr "Ad Hoc Assignment" + +# TRANSLATION +# LABEL/ID_ADHOC_ASSIGNMENT +#: LABEL/ID_ADHOC_ASSIGNMENT +msgid "Adhoc Assignment" +msgstr "Adhoc Assignment" + +# TRANSLATION +# JAVASCRIPT/ID_DYNAFORMS +#: JAVASCRIPT/ID_DYNAFORMS +msgid "[JAVASCRIPT/ID_DYNAFORMS] DynaForms" +msgstr "DynaForms" + +# TRANSLATION +# LABEL/ID_TEST +#: LABEL/ID_TEST +msgid "Test" +msgstr "Test" + +# TRANSLATION +# LABEL/ID_MONTH_1 +#: LABEL/ID_MONTH_1 +msgid "January" +msgstr "January" + +# TRANSLATION +# LABEL/ID_MONTH_2 +#: LABEL/ID_MONTH_2 +msgid "February" +msgstr "February" + +# TRANSLATION +# LABEL/ID_MONTH_3 +#: LABEL/ID_MONTH_3 +msgid "March" +msgstr "March" + +# TRANSLATION +# LABEL/ID_MONTH_4 +#: LABEL/ID_MONTH_4 +msgid "April" +msgstr "April" + +# TRANSLATION +# LABEL/ID_MONTH_5 +#: LABEL/ID_MONTH_5 +msgid "May" +msgstr "May" + +# TRANSLATION +# LABEL/ID_MONTH_6 +#: LABEL/ID_MONTH_6 +msgid "June" +msgstr "June" + +# TRANSLATION +# LABEL/ID_MONTH_7 +#: LABEL/ID_MONTH_7 +msgid "July" +msgstr "July" + +# TRANSLATION +# LABEL/ID_MONTH_8 +#: LABEL/ID_MONTH_8 +msgid "August" +msgstr "August" + +# TRANSLATION +# LABEL/ID_MONTH_9 +#: LABEL/ID_MONTH_9 +msgid "September" +msgstr "September" + +# TRANSLATION +# LABEL/ID_MONTH_10 +#: LABEL/ID_MONTH_10 +msgid "October" +msgstr "October" + +# TRANSLATION +# LABEL/ID_MONTH_11 +#: LABEL/ID_MONTH_11 +msgid "November" +msgstr "November" + +# TRANSLATION +# LABEL/ID_MONTH_12 +#: LABEL/ID_MONTH_12 +msgid "December" +msgstr "December" + +# TRANSLATION +# LABEL/ID_TO_STRING +#: LABEL/ID_TO_STRING +msgid "Replace the value in quotes" +msgstr "Replace the value in quotes" + +# TRANSLATION +# LABEL/ID_TO_FLOAT +#: LABEL/ID_TO_FLOAT +msgid "Replace the value converted to float" +msgstr "Replace the value converted to float" + +# TRANSLATION +# LABEL/ID_TO_INTEGER +#: LABEL/ID_TO_INTEGER +msgid "Replace the value converted to integer" +msgstr "Replace the value converted to integer" + +# TRANSLATION +# LABEL/ID_TO_URL +#: LABEL/ID_TO_URL +msgid "Replace the value with URL encoding" +msgstr "Replace the value with URL encoding" + +# TRANSLATION +# LABEL/ID_SQL_ESCAPE +#: LABEL/ID_SQL_ESCAPE +msgid "Replace the value for use in SQL sentences" +msgstr "Replace the value for use in SQL sentences" + +# TRANSLATION +# LABEL/ID_REPLACE_WITHOUT_CHANGES +#: LABEL/ID_REPLACE_WITHOUT_CHANGES +msgid "Replace the value without changes" +msgstr "Replace the value without changes" + +# TRANSLATION +# JAVASCRIPT/ID_REMOVE +#: JAVASCRIPT/ID_REMOVE +msgid "[JAVASCRIPT/ID_REMOVE] Remove" +msgstr "Remove" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_REMOVE_DASHBOARD +#: JAVASCRIPT/ID_CONFIRM_REMOVE_DASHBOARD +msgid "Are you sure you want to remove this dashboard?" +msgstr "Are you sure you want to remove this dashboard?" + +# TRANSLATION +# LABEL/ID_MSG_NORESULTS_USERGROUP +#: LABEL/ID_MSG_NORESULTS_USERGROUP +msgid "This user is not assigned to a group" +msgstr "This user is not assigned to a group" + +# TRANSLATION +# LABEL/ID_WSDL +#: LABEL/ID_WSDL +msgid "The Server Host or Workspace is blank" +msgstr "The Server Host or Workspace is blank" + +# TRANSLATION +# JAVASCRIPT/ID_OBJECT_PERMISSIONS +#: JAVASCRIPT/ID_OBJECT_PERMISSIONS +msgid "Process Permissions" +msgstr "Process Permissions" + +# TRANSLATION +# LABEL/ID_YES +#: LABEL/ID_YES +msgid "Yes" +msgstr "Yes" + +# TRANSLATION +# LABEL/ID_NO +#: LABEL/ID_NO +msgid "No" +msgstr "No" + +# TRANSLATION +# LABEL/ID_ANY_TASK +#: LABEL/ID_ANY_TASK +msgid "All Tasks" +msgstr "All Tasks" + +# TRANSLATION +# LABEL/ID_REGENERATE +#: LABEL/ID_REGENERATE +msgid "Regenerate" +msgstr "Regenerate" + +# TRANSLATION +# LABEL/ID_BLOCK +#: LABEL/ID_BLOCK +msgid "[LABEL/ID_BLOCK] Block" +msgstr "Block" + +# TRANSLATION +# LABEL/ID_ANY +#: LABEL/ID_ANY +msgid "Any" +msgstr "Any" + +# TRANSLATION +# LABEL/ID_DISABLED +#: LABEL/ID_DISABLED +msgid "Disabled" +msgstr "Disabled" + +# TRANSLATION +# LABEL/ID_DYNAFORM +#: LABEL/ID_DYNAFORM +msgid "DynaForm" +msgstr "DynaForm" + +# TRANSLATION +# LABEL/ID_INPUT_DOCUMENT +#: LABEL/ID_INPUT_DOCUMENT +msgid "Input Document" +msgstr "Input Document" + +# TRANSLATION +# LABEL/ID_OUTPUT_DOCUMENT +#: LABEL/ID_OUTPUT_DOCUMENT +msgid "Output Document" +msgstr "Output Document" + +# TRANSLATION +# JAVASCRIPT/ID_PLEASE_SELECT_OTHER_OBJECT_TYPE +#: JAVASCRIPT/ID_PLEASE_SELECT_OTHER_OBJECT_TYPE +msgid "Please select other object type" +msgstr "Please select other object type" + +# TRANSLATION +# JAVASCRIPT/ID_REQUIRED_FIELDS +#: JAVASCRIPT/ID_REQUIRED_FIELDS +msgid "The following fields are required" +msgstr "The following fields are required" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_DELETE_OBJECT_PERMISSION +#: JAVASCRIPT/ID_MSG_CONFIRM_DELETE_OBJECT_PERMISSION +msgid "Do you want to delete this permission ?" +msgstr "Do you want to delete this permission ?" + +# TRANSLATION +# JAVASCRIPT/ID_WEB_ENTRY +#: JAVASCRIPT/ID_WEB_ENTRY +msgid "Web Entry" +msgstr "Web Entry" + +# TRANSLATION +# JAVASCRIPT/ID_CASE_TRACKER +#: JAVASCRIPT/ID_CASE_TRACKER +msgid "Case Tracker" +msgstr "Case Tracker" + +# TRANSLATION +# JAVASCRIPT/ID_CASE_TRACKER_OBJECTS +#: JAVASCRIPT/ID_CASE_TRACKER_OBJECTS +msgid "Objects" +msgstr "Objects" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_CASE_TRACKER_OBJECT +#: LABEL/ID_MSG_CONFIRM_DELETE_CASE_TRACKER_OBJECT +msgid "Do you want to delete this object?" +msgstr "Do you want to delete this object?" + +# TRANSLATION +# LABEL/ID_CASE_NOT_EXISTS +#: LABEL/ID_CASE_NOT_EXISTS +msgid "The case not exist" +msgstr "The case not exist" + +# TRANSLATION +# LABEL/ID_PIN_INVALID +#: LABEL/ID_PIN_INVALID +msgid "The PIN is invalid" +msgstr "The PIN is invalid" + +# TRANSLATION +# LABEL/ID_MAP +#: LABEL/ID_MAP +msgid "Where is my Case?" +msgstr "Where is my Case?" + +# TRANSLATION +# LABEL/ID_DYNADOC +#: LABEL/ID_DYNADOC +msgid "My Case Forms and Documents" +msgstr "My Case Forms and Documents" + +# TRANSLATION +# LABEL/ID_HISTORY +#: LABEL/ID_HISTORY +msgid "My Case History" +msgstr "My Case History" + +# TRANSLATION +# JAVASCRIPT/ID_FILEGENERATED +#: JAVASCRIPT/ID_FILEGENERATED +msgid "Filename generated, is required!" +msgstr "Filename generated, is required!" + +# TRANSLATION +# JAVASCRIPT/ID_WEBENTRY +#: JAVASCRIPT/ID_WEBENTRY +msgid "In order to use the Web Entry Feature, you must first create a S" +msgstr "In order to use the Web Entry Feature, you must first create a S" + +# TRANSLATION +# LABEL/ID_DOWNLOAD +#: LABEL/ID_DOWNLOAD +msgid "Download" +msgstr "Download" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_DELETE_DIRECTORY +#: JAVASCRIPT/ID_MSG_CONFIRM_DELETE_DIRECTORY +msgid "Do you want to delete this directory and delete all its contents?" +msgstr "Do you want to delete this directory and delete all its contents?" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_DELETE_FILE +#: JAVASCRIPT/ID_MSG_CONFIRM_DELETE_FILE +msgid "Do you want to delete this file?" +msgstr "Do you want to delete this file?" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_FILES_TO_UPLOAD +#: LABEL/ID_PLEASE_SELECT_FILES_TO_UPLOAD +msgid "Please select the files to upload" +msgstr "Please select the files to upload" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESS_FILES_MANAGER +#: JAVASCRIPT/ID_PROCESS_FILES_MANAGER +msgid "Process Files Manager" +msgstr "Process Files Manager" + +# TRANSLATION +# LABEL/ID_WORKSPACE +#: LABEL/ID_WORKSPACE +msgid "Workspace" +msgstr "Workspace" + +# TRANSLATION +# LABEL/ID_SITE +#: LABEL/ID_SITE +msgid "Site" +msgstr "Site" + +# TRANSLATION +# LABEL/ID_CASE +#: LABEL/ID_CASE +msgid "Case" +msgstr "Case" + +# TRANSLATION +# LABEL/ID_TITLE +#: LABEL/ID_TITLE +msgid "Title" +msgstr "Title" + +# TRANSLATION +# LABEL/ID_FINISH_WITH_OPTION +#: LABEL/ID_FINISH_WITH_OPTION +msgid "Finish with option" +msgstr "Finish with option" + +# TRANSLATION +# LABEL/ID_CONTINUE_WITH_OPTION +#: LABEL/ID_CONTINUE_WITH_OPTION +msgid "Continue with option" +msgstr "Continue with option" + +# TRANSLATION +# LABEL/ID_CONTINUE +#: LABEL/ID_CONTINUE +msgid "Continue" +msgstr "Continue" + +# TRANSLATION +# LABEL/ID_OPTION +#: LABEL/ID_OPTION +msgid "Option" +msgstr "Option" + +# TRANSLATION +# LABEL/ID_LAST_EMPLOYEE +#: LABEL/ID_LAST_EMPLOYEE +msgid "Last Employee" +msgstr "Last Employee" + +# TRANSLATION +# LABEL/ID_EMPLOYEE +#: LABEL/ID_EMPLOYEE +msgid "Employee" +msgstr "Employee" + +# TRANSLATION +# LABEL/ID_SESSION +#: LABEL/ID_SESSION +msgid "Session" +msgstr "Session" + +# TRANSLATION +# LABEL/ID_NEXT_TASK +#: LABEL/ID_NEXT_TASK +msgid "Next Task" +msgstr "Next Task" + +# TRANSLATION +# LABEL/ID_PERMISSIONS_FOR_THE_ROL +#: LABEL/ID_PERMISSIONS_FOR_THE_ROL +msgid "Permissions for the role" +msgstr "Permissions for the role" + +# TRANSLATION +# LABEL/ID_BACK_TO_USERS_LIST +#: LABEL/ID_BACK_TO_USERS_LIST +msgid "Back to Users List" +msgstr "Back to Users List" + +# TRANSLATION +# LABEL/ID_ASSIGN_THE_ROLE +#: LABEL/ID_ASSIGN_THE_ROLE +msgid "Assign the role" +msgstr "Assign the role" + +# TRANSLATION +# LABEL/ID_USER_WITH_ROLE +#: LABEL/ID_USER_WITH_ROLE +msgid "Users with role" +msgstr "Users with role" + +# TRANSLATION +# JAVASCRIPT/ID_EDIT_STAGES_MAP +#: JAVASCRIPT/ID_EDIT_STAGES_MAP +msgid "Edit Stages Map" +msgstr "Edit Stages Map" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_ADD_STAGE +#: JAVASCRIPT/ID_PROCESSMAP_ADD_STAGE +msgid "Add Stage" +msgstr "Add Stage" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_STAGE +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_STAGE +msgid "Delete Stage" +msgstr "Delete Stage" + +# TRANSLATION +# LABEL/ID_HISTORY_MESSAGES +#: LABEL/ID_HISTORY_MESSAGES +msgid "My History Messages" +msgstr "My History Messages" + +# TRANSLATION +# LABEL/ID_STAGE +#: LABEL/ID_STAGE +msgid "Stage" +msgstr "Stage" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_STAGE +#: JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_STAGE +msgid "Do you want to delete the stage:" +msgstr "Do you want to delete the stage:" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_EDIT +#: JAVASCRIPT/ID_PROCESSMAP_EDIT +msgid "[JAVASCRIPT/ID_PROCESSMAP_EDIT] Edit" +msgstr "Edit" + +# TRANSLATION +# LABEL/ID_HISTORY_MESSAGE_CASE +#: LABEL/ID_HISTORY_MESSAGE_CASE +msgid "Messages History" +msgstr "Messages History" + +# TRANSLATION +# JAVASCRIPT/ID_HISTORY_MESSAGE_CASE +#: JAVASCRIPT/ID_HISTORY_MESSAGE_CASE +msgid "[JAVASCRIPT/ID_HISTORY_MESSAGE_CASE] Messages History" +msgstr "Messages History" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASKS_ASSIGNED +#: JAVASCRIPT/ID_PROCESSMAP_TASKS_ASSIGNED +msgid "Tasks Assigned" +msgstr "Tasks Assigned" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_TASKS_ASSIGNED_FOR +#: JAVASCRIPT/ID_PROCESSMAP_TASKS_ASSIGNED_FOR +msgid "Tasks Assigned For" +msgstr "Tasks Assigned For" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_TASK +#: JAVASCRIPT/ID_MSG_CONFIRM_REMOVE_TASK +msgid "Do you want to remove this task?" +msgstr "Do you want to remove this task?" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_ADD_SUBPROCESS +#: JAVASCRIPT/ID_PROCESSMAP_ADD_SUBPROCESS +msgid "Add Sub-Process" +msgstr "Add Sub-Process" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_SUBPROCESS +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_SUBPROCESS +msgid "Delete Sub-Process" +msgstr "Delete Sub-Process" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_SUBPROCESS +#: JAVASCRIPT/ID_PROCESSMAP_CONFIRM_DELETE_SUBPROCESS +msgid "Do you want to delete the Sub-Process:" +msgstr "Do you want to delete the Sub-Process:" + +# TRANSLATION +# JAVASCRIPT/ID_CASE_TRACKER_PROPERTIES +#: JAVASCRIPT/ID_CASE_TRACKER_PROPERTIES +msgid "[JAVASCRIPT/ID_CASE_TRACKER_PROPERTIES] Properties" +msgstr "Properties" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_PSUPERVISORS +#: JAVASCRIPT/ID_PROCESSMAP_PSUPERVISORS +msgid "Process Supervisors" +msgstr "Process Supervisors" + +# TRANSLATION +# LABEL/INVALID_FILE +#: LABEL/INVALID_FILE +msgid "Invalid file!" +msgstr "Invalid file!" + +# TRANSLATION +# LABEL/ID_GET_EXTERNAL_FILE +#: LABEL/ID_GET_EXTERNAL_FILE +msgid "Get" +msgstr "Get" + +# TRANSLATION +# LABEL/ID_FIELD_NAME +#: LABEL/ID_FIELD_NAME +msgid "Field Name" +msgstr "Field Name" + +# TRANSLATION +# LABEL/ID_PREV_VALUES +#: LABEL/ID_PREV_VALUES +msgid "Previous Values" +msgstr "Previous Values" + +# TRANSLATION +# LABEL/ID_CURRENT_VALUES +#: LABEL/ID_CURRENT_VALUES +msgid "Current Values" +msgstr "Current Values" + +# TRANSLATION +# LABEL/ID_FIELDS_CHANGED_NUMBER +#: LABEL/ID_FIELDS_CHANGED_NUMBER +msgid "Fields changed" +msgstr "Fields changed" + +# TRANSLATION +# LABEL/ID_DATA +#: LABEL/ID_DATA +msgid "Data" +msgstr "Data" + +# TRANSLATION +# LABEL/ID_SAVE_CHANGES +#: LABEL/ID_SAVE_CHANGES +msgid "Save Changes" +msgstr "Save Changes" + +# TRANSLATION +# LABEL/ID_CLASS_ALREADY_EXISTS +#: LABEL/ID_CLASS_ALREADY_EXISTS +msgid "Class already exists" +msgstr "Class already exists" + +# TRANSLATION +# LABEL/ID_FIELD_KEY_TABLE +#: LABEL/ID_FIELD_KEY_TABLE +msgid "Please select one or more fields to be primary keys." +msgstr "Please select one or more fields to be primary keys." + +# TRANSLATION +# LABEL/ID_FIELD_FOREIGN_TABLE +#: LABEL/ID_FIELD_FOREIGN_TABLE +msgid "Field \\"table\\" is required" +msgstr "Field \\"table\\" is required" + +# TRANSLATION +# LABEL/ID_FIELD_NAME_REQUIRED +#: LABEL/ID_FIELD_NAME_REQUIRED +msgid "Field name is required" +msgstr "Field name is required" + +# TRANSLATION +# LABEL/ID_FIELD_SIZE_REQUIRED +#: LABEL/ID_FIELD_SIZE_REQUIRED +msgid "Field size is required" +msgstr "Field size is required" + +# TRANSLATION +# JAVASCRIPT/DYNAFIELD_ALREADY_EXIST +#: JAVASCRIPT/DYNAFIELD_ALREADY_EXIST +msgid "The field name already exists!" +msgstr "The field name already exists!" + +# TRANSLATION +# LABEL/ID_DYNAFORM_HISTORY +#: LABEL/ID_DYNAFORM_HISTORY +msgid "Change Log" +msgstr "Change Log" + +# TRANSLATION +# LABEL/ID_CASEDEMO +#: LABEL/ID_CASEDEMO +msgid "Case Demo" +msgstr "Case Demo" + +# TRANSLATION +# LABEL/ID_NEED_REGISTER +#: LABEL/ID_NEED_REGISTER +msgid "You need to be registered to download this process. Register NOW!" +msgstr "You need to be registered to download this process. Register NOW!" + +# TRANSLATION +# JAVASCRIPT/ID_INCORRECT_USER_OR_PASS +#: JAVASCRIPT/ID_INCORRECT_USER_OR_PASS +msgid "Incorrect username or password" +msgstr "Incorrect username or password" + +# TRANSLATION +# LABEL/ID_CASESREASSIGN +#: LABEL/ID_CASESREASSIGN +msgid "You still have cases to reassign." +msgstr "You still have cases to reassign." + +# TRANSLATION +# LABEL/ID_TO_REASSIGN +#: LABEL/ID_TO_REASSIGN +msgid "[LABEL/ID_TO_REASSIGN] Reassign" +msgstr "Reassign" + +# TRANSLATION +# LABEL/ID_SELF_SERVICE +#: LABEL/ID_SELF_SERVICE +msgid "Self Service" +msgstr "Self Service" + +# TRANSLATION +# LABEL/ID_TAKE +#: LABEL/ID_TAKE +msgid "Take" +msgstr "Take" + +# TRANSLATION +# LABEL/ID_STAGES +#: LABEL/ID_STAGES +msgid "Stages" +msgstr "Stages" + +# TRANSLATION +# LABEL/ID_STATUS +#: LABEL/ID_STATUS +msgid "Status" +msgstr "Status" + +# TRANSLATION +# LABEL/ID_REASSIGN_TO +#: LABEL/ID_REASSIGN_TO +msgid "[LABEL/ID_REASSIGN_TO] Reassign" +msgstr "Reassign" + +# TRANSLATION +# LABEL/ID_NO_REASSIGN +#: LABEL/ID_NO_REASSIGN +msgid "Do not reassign" +msgstr "Do not reassign" + +# TRANSLATION +# LABEL/ID_PROCESS +#: LABEL/ID_PROCESS +msgid "Process" +msgstr "Process" + +# TRANSLATION +# LABEL/ID_REASSIGN_CASES +#: LABEL/ID_REASSIGN_CASES +msgid "Reassign Cases" +msgstr "Reassign Cases" + +# TRANSLATION +# LABEL/ID_ALERT_MESSAGE +#: LABEL/ID_ALERT_MESSAGE +msgid "Alert Message" +msgstr "Alert Message" + +# TRANSLATION +# LABEL/ID_MSG_ERROR_USR_LASTNAME +#: LABEL/ID_MSG_ERROR_USR_LASTNAME +msgid "Last name is required" +msgstr "Last name is required" + +# TRANSLATION +# LABEL/ID_MSG_ERROR_USR_FIRSTNAME +#: LABEL/ID_MSG_ERROR_USR_FIRSTNAME +msgid "First name is required" +msgstr "First name is required" + +# TRANSLATION +# LABEL/ID_STARTED_CASES +#: LABEL/ID_STARTED_CASES +msgid "My Started Cases" +msgstr "My Started Cases" + +# TRANSLATION +# LABEL/ID_LOGGED +#: LABEL/ID_LOGGED +msgid "Logged on" +msgstr "Logged on" + +# TRANSLATION +# LABEL/ID_OPTIONS +#: LABEL/ID_OPTIONS +msgid "Options" +msgstr "Options" + +# TRANSLATION +# LABEL/ID_SKINS +#: LABEL/ID_SKINS +msgid "Skins" +msgstr "Skins" + +# TRANSLATION +# LABEL/ID_ERROR_INSERT_LINE +#: LABEL/ID_ERROR_INSERT_LINE +msgid "Error trying to insert the line" +msgstr "Error trying to insert the line" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_PAUSE_CASE_ALERT +#: JAVASCRIPT/ID_CONFIRM_PAUSE_CASE_ALERT +msgid "You should specify an unpause date." +msgstr "You should specify an unpause date." + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_ALERT1 +#: JAVASCRIPT/CONDITIONAL_ALERT1 +msgid "Some fields have not been filled." +msgstr "Some fields have not been filled." + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_NOFIELDS_IN_CONDITION +#: JAVASCRIPT/CONDITIONAL_NOFIELDS_IN_CONDITION +msgid "No records found for conditions setup" +msgstr "No records found for conditions setup" + +# TRANSLATION +# LABEL/IMPORT_LANGUAGE_ERR_NO_WRITABLE +#: LABEL/IMPORT_LANGUAGE_ERR_NO_WRITABLE +msgid "The XML forms directory is not writable" +msgstr "The XML forms directory is not writable" + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_ALERT2 +#: JAVASCRIPT/CONDITIONAL_ALERT2 +msgid "You should select at least one event (OnChange or OnLoad )" +msgstr "You should select at least one event (OnChange or OnLoad )" + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_TITLE +#: JAVASCRIPT/CONDITIONAL_TITLE +msgid "CONDITIONAL SHOW/HIDE EDITOR" +msgstr "CONDITIONAL SHOW/HIDE EDITOR" + +# TRANSLATION +# LABEL/ID_DISB_WORKSPACE +#: LABEL/ID_DISB_WORKSPACE +msgid "This site is disabled" +msgstr "This site is disabled" + +# TRANSLATION +# LABEL/ID_WORKSPACES +#: LABEL/ID_WORKSPACES +msgid "WORKSPACES" +msgstr "WORKSPACES" + +# TRANSLATION +# LABEL/ID_MORE_INFO +#: LABEL/ID_MORE_INFO +msgid "More Info" +msgstr "More Info" + +# TRANSLATION +# LABEL/ID_CASE_ALREADY_DERIVATED +#: LABEL/ID_CASE_ALREADY_DERIVATED +msgid "Case already routed" +msgstr "Case already routed" + +# TRANSLATION +# JAVASCRIPT/EVENT_EMAILEXISTS +#: JAVASCRIPT/EVENT_EMAILEXISTS +msgid "The user or group is already in the list!" +msgstr "The user or group is already in the list!" + +# TRANSLATION +# LABEL/ID_PENDING +#: LABEL/ID_PENDING +msgid "Pending" +msgstr "Pending" + +# TRANSLATION +# JAVASCRIPT/USERS_DELETE_WITH_HISTORY +#: JAVASCRIPT/USERS_DELETE_WITH_HISTORY +msgid "The user has some completed or canceled tasks (which may be useful for historical records). Do you want to delete this user anyway?" +msgstr "The user has some completed or canceled tasks (which may be useful for historical records). Do you want to delete this user anyway?" + +# TRANSLATION +# LABEL/ID_MSG_REMOVE_PLUGIN +#: LABEL/ID_MSG_REMOVE_PLUGIN +msgid "Are you sure that you want to remove this plugin?" +msgstr "Are you sure that you want to remove this plugin?" + +# TRANSLATION +# JAVASCRIPT/USERS_REASSIGN +#: JAVASCRIPT/USERS_REASSIGN +msgid "This user cannot be deleted because he/she still has some pending tasks. <br/><br/>Do you want to reassign these tasks to another user now?" +msgstr "This user cannot be deleted because he/she still has some pending tasks. <br/><br/>Do you want to reassign these tasks to another user now?" + +# TRANSLATION +# LABEL/LOGIN_VERIFY_MSG +#: LABEL/LOGIN_VERIFY_MSG +msgid "Verifying..." +msgstr "Verifying..." + +# TRANSLATION +# LABEL/ID_ACTION +#: LABEL/ID_ACTION +msgid "Action" +msgstr "Action" + +# TRANSLATION +# LABEL/ID_EDIT_ACTION +#: LABEL/ID_EDIT_ACTION +msgid "Edit Action" +msgstr "Edit Action" + +# TRANSLATION +# LABEL/ID_PROCESSING +#: LABEL/ID_PROCESSING +msgid "Processing ..." +msgstr "Processing ..." + +# TRANSLATION +# LABEL/ID_FIELD_CANNOT_BE_PRIMARY_KEY +#: LABEL/ID_FIELD_CANNOT_BE_PRIMARY_KEY +msgid "The type of field 'TEXT' can't be a primary key" +msgstr "The type of field 'TEXT' can't be a primary key" + +# TRANSLATION +# LABEL/ID_DYNAFORM_HASNOSUBMITBTN +#: LABEL/ID_DYNAFORM_HASNOSUBMITBTN +msgid "Warning: This DynaForm does not include a [Submit] or [Button] field to save any entered data." +msgstr "Warning: This DynaForm does not include a [Submit] or [Button] field to save any entered data." + +# TRANSLATION +# LABEL/ID_UPLOAD_VALID_CSV_FILE +#: LABEL/ID_UPLOAD_VALID_CSV_FILE +msgid "Please upload a valid CSV file" +msgstr "Please upload a valid CSV file" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_DELETE_GRID_ITEM +#: JAVASCRIPT/ID_MSG_DELETE_GRID_ITEM +msgid "Are you sure you want to delete this row?" +msgstr "Are you sure you want to delete this row?" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_NODELETE_GRID_ITEM +#: JAVASCRIPT/ID_MSG_NODELETE_GRID_ITEM +msgid "Can't delete the first row!" +msgstr "Can't delete the first row!" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_GROUPS_ADDCONFIRM +#: JAVASCRIPT/ID_MSG_GROUPS_ADDCONFIRM +msgid "At least one user must be selected." +msgstr "At least one user must be selected." + +# TRANSLATION +# LABEL/ID_DEBUG +#: LABEL/ID_DEBUG +msgid "Debugger" +msgstr "Debugger" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_EVENT +#: LABEL/ID_MSG_CONFIRM_DELETE_EVENT +msgid "Do you want to delete this event?" +msgstr "Do you want to delete this event?" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_CONFIRM_RESENDMSG +#: JAVASCRIPT/ID_MSG_CONFIRM_RESENDMSG +msgid "Are you sure that you want to resend this message?" +msgstr "Are you sure that you want to resend this message?" + +# TRANSLATION +# LABEL/ID_RESEND +#: LABEL/ID_RESEND +msgid "Resend" +msgstr "Resend" + +# TRANSLATION +# LABEL/ID_EDIT_EVENT +#: LABEL/ID_EDIT_EVENT +msgid "Edit Event" +msgstr "Edit Event" + +# TRANSLATION +# LABEL/ID_NEW_EVENT +#: LABEL/ID_NEW_EVENT +msgid "New Event" +msgstr "New Event" + +# TRANSLATION +# JAVASCRIPT/ID_EVENTS +#: JAVASCRIPT/ID_EVENTS +msgid "Events" +msgstr "Events" + +# TRANSLATION +# LABEL/ID_TO +#: LABEL/ID_TO +msgid "To" +msgstr "To" + +# TRANSLATION +# LABEL/ID_LINE +#: LABEL/ID_LINE +msgid "Line" +msgstr "Line" + +# TRANSLATION +# JAVASCRIPT/ID_REQUIRED +#: JAVASCRIPT/ID_REQUIRED +msgid "The condition is required" +msgstr "The condition is required" + +# TRANSLATION +# LABEL/ID_DUPLICATE_ENTRY_PRIMARY_KEY +#: LABEL/ID_DUPLICATE_ENTRY_PRIMARY_KEY +msgid "Duplicate entry for primary key" +msgstr "Duplicate entry for primary key" + +# TRANSLATION +# LABEL/ID_ADDITIONAL_TABLES +#: LABEL/ID_ADDITIONAL_TABLES +msgid "PM Tables" +msgstr "PM Tables" + +# TRANSLATION +# LABEL/ID_REQUEST_SENT +#: LABEL/ID_REQUEST_SENT +msgid "Request sent." +msgstr "Request sent." + +# TRANSLATION +# LABEL/ID_DYNAFORM_SAVE_CHANGES +#: LABEL/ID_DYNAFORM_SAVE_CHANGES +msgid "[LABEL/ID_DYNAFORM_SAVE_CHANGES] Do you want to save changes?" +msgstr "Do you want to save changes?" + +# TRANSLATION +# LABEL/ID_IMPORT_USERS +#: LABEL/ID_IMPORT_USERS +msgid "Import Users" +msgstr "Import Users" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_STEP +#: LABEL/ID_MSG_CONFIRM_DELETE_STEP +msgid "Are you sure you want to eliminate this step from the task?" +msgstr "Are you sure you want to eliminate this step from the task?" + +# TRANSLATION +# LABEL/ID_AUTHENTICATION +#: LABEL/ID_AUTHENTICATION +msgid "Authentication" +msgstr "Authentication" + +# TRANSLATION +# LABEL/ID_AUTHENTICATION_SOURCE_INVALID +#: LABEL/ID_AUTHENTICATION_SOURCE_INVALID +msgid "Authentication Source for this user is invalid" +msgstr "Authentication Source for this user is invalid" + +# TRANSLATION +# LABEL/ID_USER_INACTIVE_BY_DATE +#: LABEL/ID_USER_INACTIVE_BY_DATE +msgid "User not allowed access past due date" +msgstr "User not allowed access past due date" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_AUTH_SOURCE +#: LABEL/ID_MSG_CONFIRM_DELETE_AUTH_SOURCE +msgid "Do you want to delete this authentication source?" +msgstr "Do you want to delete this authentication source?" + +# TRANSLATION +# LABEL/ID_ERROR_OBJECT_NOT_EXISTS +#: LABEL/ID_ERROR_OBJECT_NOT_EXISTS +msgid "Error: Object does not exist." +msgstr "Error: Object does not exist." + +# TRANSLATION +# LABEL/ID_AUTH_SOURCES +#: LABEL/ID_AUTH_SOURCES +msgid "Authentication Sources" +msgstr "Authentication Sources" + +# TRANSLATION +# JAVASCRIPT/ID_ROLES_MSG +#: JAVASCRIPT/ID_ROLES_MSG +msgid "You cannot modify this role." +msgstr "You cannot modify this role." + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_INPUTS +#: JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_INPUTS +msgid "[JAVASCRIPT/ID_PROCESSMAP_SUPERVISORS_INPUTS] Input Documents" +msgstr "Input Documents" + +# TRANSLATION +# JAVASCRIPT/ID_ASSIGN_INPUT_DOCUMENT +#: JAVASCRIPT/ID_ASSIGN_INPUT_DOCUMENT +msgid "Assign Input Document" +msgstr "Assign Input Document" + +# TRANSLATION +# LABEL/ID_NOT_DERIVATED +#: LABEL/ID_NOT_DERIVATED +msgid "The case couldn't be routed. Consult the system administrator" +msgstr "The case couldn't be routed. Consult the system administrator" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_SUPERVISOR_INPUT +#: LABEL/ID_MSG_CONFIRM_DELETE_SUPERVISOR_INPUT +msgid "Do you want to remove this Input Document?" +msgstr "Do you want to remove this Input Document?" + +# TRANSLATION +# LABEL/ID_ADVANCEDSEARCH +#: LABEL/ID_ADVANCEDSEARCH +msgid "[LABEL/ID_ADVANCEDSEARCH] Advanced Search" +msgstr "Advanced Search" + +# TRANSLATION +# LABEL/ID_POLICY_ALERT +#: LABEL/ID_POLICY_ALERT +msgid "Your password does not meet the following password policies" +msgstr "Your password does not meet the following password policies" + +# TRANSLATION +# LABEL/ID_PLEASE_CHANGE_PASSWORD_POLICY +#: LABEL/ID_PLEASE_CHANGE_PASSWORD_POLICY +msgid "Please change your password to one that complies with these policies." +msgstr "Please change your password to one that complies with these policies." + +# TRANSLATION +# LABEL/ID_PPP_MINIMUN_LENGTH +#: LABEL/ID_PPP_MINIMUN_LENGTH +msgid "Minimum length" +msgstr "Minimum length" + +# TRANSLATION +# LABEL/ID_PPP_MAXIMUN_LENGTH +#: LABEL/ID_PPP_MAXIMUN_LENGTH +msgid "Maximum length" +msgstr "Maximum length" + +# TRANSLATION +# LABEL/ID_PPP_NUMERICAL_CHARACTER_REQUIRED +#: LABEL/ID_PPP_NUMERICAL_CHARACTER_REQUIRED +msgid "Numerical Character is required" +msgstr "Numerical Character is required" + +# TRANSLATION +# LABEL/ID_PPP_UPPERCASE_CHARACTER_REQUIRED +#: LABEL/ID_PPP_UPPERCASE_CHARACTER_REQUIRED +msgid "Uppercase Character is required" +msgstr "Uppercase Character is required" + +# TRANSLATION +# LABEL/ID_PPP_SPECIAL_CHARACTER_REQUIRED +#: LABEL/ID_PPP_SPECIAL_CHARACTER_REQUIRED +msgid "Special Character is required" +msgstr "Special Character is required" + +# TRANSLATION +# LABEL/ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN +#: LABEL/ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN +msgid "User must change his password after next login" +msgstr "User must change his password after next login" + +# TRANSLATION +# LABEL/ID_PPP_EXPIRATION_IN +#: LABEL/ID_PPP_EXPIRATION_IN +msgid "Password Expiration in" +msgstr "Password Expiration in" + +# TRANSLATION +# LABEL/ID_DAYS +#: LABEL/ID_DAYS +msgid "Days" +msgstr "Days" + +# TRANSLATION +# LABEL/ID_ACCOUNT +#: LABEL/ID_ACCOUNT +msgid "Account" +msgstr "Account" + +# TRANSLATION +# LABEL/ID_ACCOUNT_DISABLED_CONTACT_ADMIN +#: LABEL/ID_ACCOUNT_DISABLED_CONTACT_ADMIN +msgid "disabled, please contact with the system administrator" +msgstr "disabled, please contact with the system administrator" + +# TRANSLATION +# LABEL/ID_WORKSPACE_USING +#: LABEL/ID_WORKSPACE_USING +msgid "Using workspace" +msgstr "Using workspace" + +# TRANSLATION +# JAVASCRIPT/ID_REASSIGN_BYUSER_CONFIRM +#: JAVASCRIPT/ID_REASSIGN_BYUSER_CONFIRM +msgid "Are you sure that you want to reassign the cases?" +msgstr "Are you sure that you want to reassign the cases?" + +# TRANSLATION +# JAVASCRIPT/ID_REASSIGN_BYUSER +#: JAVASCRIPT/ID_REASSIGN_BYUSER +msgid "At least one item from the list must be selected." +msgstr "At least one item from the list must be selected." + +# TRANSLATION +# JAVASCRIPT/ID_MSG_RESSIGN_BYUSER_PANEL +#: JAVASCRIPT/ID_MSG_RESSIGN_BYUSER_PANEL +msgid "Users selection interface" +msgstr "Users selection interface" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_RESSIGN_B +#: JAVASCRIPT/ID_MSG_RESSIGN_B +msgid "[JAVASCRIPT/ID_MSG_RESSIGN_B] At least one item from the list must be selected." +msgstr "At least one item from the list must be selected." + +# TRANSLATION +# LABEL/ID_DETAILS_WEBSERVICES +#: LABEL/ID_DETAILS_WEBSERVICES +msgid "Details" +msgstr "Details" + +# TRANSLATION +# LABEL/ID_ERROR_STREAMING_FILE +#: LABEL/ID_ERROR_STREAMING_FILE +msgid "doesn't exist. It should be saved by a plugin to a different place. Please review the configuration" +msgstr "doesn't exist. It should be saved by a plugin to a different place. Please review the configuration" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_UNKNOWN +#: LABEL/ID_UPLOAD_ERR_UNKNOWN +msgid "Unknown upload error" +msgstr "Unknown upload error" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_EXTENSION +#: LABEL/ID_UPLOAD_ERR_EXTENSION +msgid "File upload stopped by extension" +msgstr "File upload stopped by extension" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_CANT_WRITE +#: LABEL/ID_UPLOAD_ERR_CANT_WRITE +msgid "Failed to write file to disk" +msgstr "Failed to write file to disk" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_NO_TMP_DIR +#: LABEL/ID_UPLOAD_ERR_NO_TMP_DIR +msgid "Missing a temporary folder" +msgstr "Missing a temporary folder" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_NO_FILE +#: LABEL/ID_UPLOAD_ERR_NO_FILE +msgid "No file was uploaded" +msgstr "No file was uploaded" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_PARTIAL +#: LABEL/ID_UPLOAD_ERR_PARTIAL +msgid "The uploaded file was only partially uploaded" +msgstr "The uploaded file was only partially uploaded" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_FORM_SIZE +#: LABEL/ID_UPLOAD_ERR_FORM_SIZE +msgid "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" +msgstr "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" + +# TRANSLATION +# LABEL/ID_UPLOAD_ERR_INI_SIZE +#: LABEL/ID_UPLOAD_ERR_INI_SIZE +msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini" +msgstr "The uploaded file exceeds the upload_max_filesize directive in php.ini" + +# TRANSLATION +# LABEL/ID_NOT_PROCESS_RELATED +#: LABEL/ID_NOT_PROCESS_RELATED +msgid "Not from a Process" +msgstr "Not from a Process" + +# TRANSLATION +# LABEL/ID_EXTERNAL_FILE +#: LABEL/ID_EXTERNAL_FILE +msgid "External" +msgstr "External" + +# TRANSLATION +# LABEL/ID_INFO +#: LABEL/ID_INFO +msgid "Info" +msgstr "Info" + +# TRANSLATION +# LABEL/ID_CONFIRM_DELETE_INPUT_AND_HISTORY +#: LABEL/ID_CONFIRM_DELETE_INPUT_AND_HISTORY +msgid "This action will delete the current document and all its versions" +msgstr "This action will delete the current document and all its versions" + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_DELETE_INPUT_AND_HISTORY +#: JAVASCRIPT/ID_CONFIRM_DELETE_INPUT_AND_HISTORY +msgid "This will delete the current document and its past versions." +msgstr "This will delete the current document and its past versions." + +# TRANSLATION +# LABEL/ID_SETUP_MAILCONF_TITLE +#: LABEL/ID_SETUP_MAILCONF_TITLE +msgid "Test SMTP Connection" +msgstr "Test SMTP Connection" + +# TRANSLATION +# LABEL/DBCONNECTIONS_TITLE +#: LABEL/DBCONNECTIONS_TITLE +msgid "Testing database server configuration" +msgstr "Testing database server configuration" + +# TRANSLATION +# LABEL/ID_DBCNN_TITLE +#: LABEL/ID_DBCNN_TITLE +msgid "Checking server configuration" +msgstr "Checking server configuration" + +# TRANSLATION +# LABEL/ID_NOT_IN_FOLDER +#: LABEL/ID_NOT_IN_FOLDER +msgid "Not in folder" +msgstr "Not in folder" + +# TRANSLATION +# LABEL/ID_NEW_FOLDER +#: LABEL/ID_NEW_FOLDER +msgid "New Folder" +msgstr "New Folder" + +# TRANSLATION +# LABEL/ID_NEXT_STEP +#: LABEL/ID_NEXT_STEP +msgid "Next Step" +msgstr "Next Step" + +# TRANSLATION +# LABEL/ID_PM_FOLDER +#: LABEL/ID_PM_FOLDER +msgid "ProcessMaker Folder" +msgstr "ProcessMaker Folder" + +# TRANSLATION +# JAVASCRIPT/ID_INPUT_DOCUMENT_HISTORY +#: JAVASCRIPT/ID_INPUT_DOCUMENT_HISTORY +msgid "Input Document History" +msgstr "Input Document History" + +# TRANSLATION +# JAVASCRIPT/ID_UPLOAD_REPLACE_INPUT +#: JAVASCRIPT/ID_UPLOAD_REPLACE_INPUT +msgid "Replace Input Document" +msgstr "Replace Input Document" + +# TRANSLATION +# JAVASCRIPT/ID_UPLOAD_NEW_INPUT_VERSION +#: JAVASCRIPT/ID_UPLOAD_NEW_INPUT_VERSION +msgid "Upload New Input Document Version" +msgstr "Upload New Input Document Version" + +# TRANSLATION +# LABEL/ID_VERSION_HISTORY +#: LABEL/ID_VERSION_HISTORY +msgid "Version History" +msgstr "Version History" + +# TRANSLATION +# JAVASCRIPT/ID_UPLOAD_NEW_INPUT +#: JAVASCRIPT/ID_UPLOAD_NEW_INPUT +msgid "Upload New Input Document" +msgstr "Upload New Input Document" + +# TRANSLATION +# LABEL/ID_NEW_VERSION +#: LABEL/ID_NEW_VERSION +msgid "New Version" +msgstr "New Version" + +# TRANSLATION +# JAVASCRIPT/ID_ROLES_MSG3 +#: JAVASCRIPT/ID_ROLES_MSG3 +msgid "You must specify a role name!" +msgstr "You must specify a role name!" + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_DELETE_LINE +#: JAVASCRIPT/ID_PROCESSMAP_DELETE_LINE +msgid "[JAVASCRIPT/ID_PROCESSMAP_DELETE_LINE] Delete line" +msgstr "Delete line" + +# TRANSLATION +# LABEL/ID_FIELD_HANDLER_HELP1 +#: LABEL/ID_FIELD_HANDLER_HELP1 +msgid "About the feature" +msgstr "About the feature" + +# TRANSLATION +# LABEL/ID_FIELD_HANDLER_HELP2 +#: LABEL/ID_FIELD_HANDLER_HELP2 +msgid "Drag & Drop to move and reorder the fields." +msgstr "Drag & Drop to move and reorder the fields." + +# TRANSLATION +# LABEL/ID_FIELD_HANDLER_HELP3 +#: LABEL/ID_FIELD_HANDLER_HELP3 +msgid "Bring the mouse pointer near tool icon and the corresponding options (Edit, Delete) will be shown." +msgstr "Bring the mouse pointer near tool icon and the corresponding options (Edit, Delete) will be shown." + +# TRANSLATION +# JAVASCRIPT/ID_CONFIRM_WEBENTRY_DELETE +#: JAVASCRIPT/ID_CONFIRM_WEBENTRY_DELETE +msgid "Are you sure you want to delete this web entry?" +msgstr "Are you sure you want to delete this web entry?" + +# TRANSLATION +# LABEL/ID_CHANGE_VIEW +#: LABEL/ID_CHANGE_VIEW +msgid "Change view" +msgstr "Change view" + +# TRANSLATION +# LABEL/ID_REMOVE_FIELD +#: LABEL/ID_REMOVE_FIELD +msgid "Remove field" +msgstr "Remove field" + +# TRANSLATION +# LABEL/ID_VISIBLE +#: LABEL/ID_VISIBLE +msgid "Visible" +msgstr "Visible" + +# TRANSLATION +# LABEL/ID_TYPE +#: LABEL/ID_TYPE +msgid "Type" +msgstr "Type" + +# TRANSLATION +# LABEL/ID_LABEL +#: LABEL/ID_LABEL +msgid "Label" +msgstr "Label" + +# TRANSLATION +# LABEL/ID_NAME +#: LABEL/ID_NAME +msgid "Name" +msgstr "Name" + +# TRANSLATION +# LABEL/WEBEN_ONLY_BALANCED +#: LABEL/WEBEN_ONLY_BALANCED +msgid "Web Entry only works with tasks which have Cyclical Assignment.<br/> Please change the Assignment Rules" +msgstr "Web Entry only works with tasks which have Cyclical Assignment.<br/> Please change the Assignment Rules" + +# TRANSLATION +# LABEL/ID_DETAIL +#: LABEL/ID_DETAIL +msgid "Detail" +msgstr "Detail" + +# TRANSLATION +# LABEL/HTML_FILES +#: LABEL/HTML_FILES +msgid "You can open only files with the .html extension" +msgstr "You can open only files with the .html extension" + +# TRANSLATION +# JAVASCRIPT/WEBEN_ONLY_BALANCEDJS +#: JAVASCRIPT/WEBEN_ONLY_BALANCEDJS +msgid "Web Entry only works with tasks which have Cyclical Assignment. Please change the Assignment Rules" +msgstr "Web Entry only works with tasks which have Cyclical Assignment. Please change the Assignment Rules" + +# TRANSLATION +# JAVASCRIPT/HTML_FILES +#: JAVASCRIPT/HTML_FILES +msgid "Make sure your uploaded file has extension html or txt" +msgstr "Make sure your uploaded file has extension html or txt" + +# TRANSLATION +# LABEL/ID_SEARCH_RESULT +#: LABEL/ID_SEARCH_RESULT +msgid "Search results" +msgstr "Search results" + +# TRANSLATION +# JAVASCRIPT/ID_MSG_REMOVE_PLUGIN +#: JAVASCRIPT/ID_MSG_REMOVE_PLUGIN +msgid "[JAVASCRIPT/ID_MSG_REMOVE_PLUGIN] Are you sure that you want to remove this plugin?" +msgstr "Are you sure that you want to remove this plugin?" + +# TRANSLATION +# LABEL/ID_MSG_REMOVE_PLUGIN_SUCCESS +#: LABEL/ID_MSG_REMOVE_PLUGIN_SUCCESS +msgid "Plugin successfully removed!" +msgstr "Plugin successfully removed!" + +# TRANSLATION +# LABEL/CANT_DEL_LANGUAGE +#: LABEL/CANT_DEL_LANGUAGE +msgid "This language cannot be deleted because it is currently being used." +msgstr "This language cannot be deleted because it is currently being used." + +# TRANSLATION +# JAVASCRIPT/ID_ADD +#: JAVASCRIPT/ID_ADD +msgid "[JAVASCRIPT/ID_ADD] Add" +msgstr "Add" + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_ALERT3 +#: JAVASCRIPT/CONDITIONAL_ALERT3 +msgid "You have not tested the condition, do you want save anyway?" +msgstr "You have not tested the condition, do you want save anyway?" + +# TRANSLATION +# JAVASCRIPT/CONDITIONAL_ALERT4 +#: JAVASCRIPT/CONDITIONAL_ALERT4 +msgid "You have an error in the condition, do you want save anyway?" +msgstr "You have an error in the condition, do you want save anyway?" + +# TRANSLATION +# LABEL/ID_ERROR +#: LABEL/ID_ERROR +msgid "ERROR" +msgstr "ERROR" + +# TRANSLATION +# LABEL/ID_REQUIRED_FIELDS_ERROR +#: LABEL/ID_REQUIRED_FIELDS_ERROR +msgid "Some required fields were not filled" +msgstr "Some required fields were not filled" + +# TRANSLATION +# LABEL/IMPORT_LANGUAGE_SUCCESS +#: LABEL/IMPORT_LANGUAGE_SUCCESS +msgid "The translation file was successfully imported." +msgstr "The translation file was successfully imported." + +# TRANSLATION +# JAVASCRIPT/ID_PROCESSMAP_REPORT_TO +#: JAVASCRIPT/ID_PROCESSMAP_REPORT_TO +msgid "Report to" +msgstr "Report to" + +# TRANSLATION +# LABEL/UID_UNDEFINED_USER +#: LABEL/UID_UNDEFINED_USER +msgid "Undefined user" +msgstr "Undefined user" + +# TRANSLATION +# LABEL/ID_DEPARTAMENT_USERS +#: LABEL/ID_DEPARTAMENT_USERS +msgid "Departments" +msgstr "Departments" + +# TRANSLATION +# LABEL/ID_DEPARTMENTS_USERS +#: LABEL/ID_DEPARTMENTS_USERS +msgid "[LABEL/ID_DEPARTMENTS_USERS] Departments" +msgstr "Departments" + +# TRANSLATION +# LABEL/ID_NEW_DEPARTMENT +#: LABEL/ID_NEW_DEPARTMENT +msgid "[LABEL/ID_NEW_DEPARTMENT] New" +msgstr "New" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_DEPARTMENT +#: LABEL/ID_MSG_CONFIRM_DELETE_DEPARTMENT +msgid "Do you want to delete this department?" +msgstr "Do you want to delete this department?" + +# TRANSLATION +# JAVASCRIPT/ID_MSJ_DEPTO +#: JAVASCRIPT/ID_MSJ_DEPTO +msgid "Department name already exists!" +msgstr "Department name already exists!" + +# TRANSLATION +# LABEL/ID_MSJ_REPORSTO +#: LABEL/ID_MSJ_REPORSTO +msgid "The current user does not have a valid Reports To user. Please contact the administrator." +msgstr "The current user does not have a valid Reports To user. Please contact the administrator." + +# TRANSLATION +# LABEL/ID_REMOVE_LOGO +#: LABEL/ID_REMOVE_LOGO +msgid "Are you sure you want to delete this Logo?" +msgstr "Are you sure you want to delete this Logo?" + +# TRANSLATION +# LABEL/ID_REPLACED_LOGO +#: LABEL/ID_REPLACED_LOGO +msgid "The logo was replaced" +msgstr "The logo was replaced" + +# TRANSLATION +# JAVASCRIPT/ID_REMOVE_LOGO +#: JAVASCRIPT/ID_REMOVE_LOGO +msgid "[JAVASCRIPT/ID_REMOVE_LOGO] Are you sure you want to delete this Logo?" +msgstr "Are you sure you want to delete this Logo?" + +# TRANSLATION +# LABEL/ID_LOGO +#: LABEL/ID_LOGO +msgid "Logo" +msgstr "Logo" + +# TRANSLATION +# LABEL/ID_INBOX +#: LABEL/ID_INBOX +msgid "Inbox" +msgstr "Inbox" + +# TRANSLATION +# LABEL/ID_OUTBOX +#: LABEL/ID_OUTBOX +msgid "Outbox" +msgstr "Outbox" + +# TRANSLATION +# LABEL/ID_CASES_MENU_FOLDERS +#: LABEL/ID_CASES_MENU_FOLDERS +msgid "Folders" +msgstr "Folders" + +# TRANSLATION +# LABEL/ID_CASES_MENU_SEARCH +#: LABEL/ID_CASES_MENU_SEARCH +msgid "[LABEL/ID_CASES_MENU_SEARCH] Search" +msgstr "Search" + +# TRANSLATION +# LABEL/ID_CASES_MENU_ADMIN +#: LABEL/ID_CASES_MENU_ADMIN +msgid "Process Supervisor" +msgstr "Process Supervisor" + +# TRANSLATION +# LABEL/ID_SENT +#: LABEL/ID_SENT +msgid "Participated" +msgstr "Participated" + +# TRANSLATION +# LABEL/ID_CALENDAR +#: LABEL/ID_CALENDAR +msgid "Calendar" +msgstr "Calendar" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_CASE_SCHEDULER +#: LABEL/ID_MSG_CONFIRM_DELETE_CASE_SCHEDULER +msgid "Are you sure you want to delete this scheduled case?" +msgstr "Are you sure you want to delete this scheduled case?" + +# TRANSLATION +# LABEL/ID_SCHEDULER_LIST +#: LABEL/ID_SCHEDULER_LIST +msgid "New cases scheduler" +msgstr "New cases scheduler" + +# TRANSLATION +# LABEL/ID_SCHEDULER_LOG +#: LABEL/ID_SCHEDULER_LOG +msgid "Cases Scheduler Logs" +msgstr "Cases Scheduler Logs" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_IDOCUMENT +#: LABEL/ID_MSG_CONFIRM_DELETE_IDOCUMENT +msgid "This object is being used in some steps. Are you sure you want to delete it?" +msgstr "This object is being used in some steps. Are you sure you want to delete it?" + +# TRANSLATION +# JAVASCRIPT/ID_FIELD_FOREIGN_TABLE +#: JAVASCRIPT/ID_FIELD_FOREIGN_TABLE +msgid "[JAVASCRIPT/ID_FIELD_FOREIGN_TABLE] Field \\"table\\" is required" +msgstr "Field \\"table\\" is required" + +# TRANSLATION +# JAVASCRIPT/ID_ASSIGN_RULES +#: JAVASCRIPT/ID_ASSIGN_RULES +msgid "Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn't be used with subprocesses" +msgstr "Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn't be used with subprocesses" + +# TRANSLATION +# LABEL/ID_FIELD_INVALID +#: LABEL/ID_FIELD_INVALID +msgid "Field Invalid" +msgstr "Field Invalid" + +# TRANSLATION +# LABEL/ID_WARNING +#: LABEL/ID_WARNING +msgid "WARNING" +msgstr "WARNING" + +# TRANSLATION +# LABEL/ID_SAVED +#: LABEL/ID_SAVED +msgid "Saved" +msgstr "Saved" + +# TRANSLATION +# LABEL/ID_ASSIGN_RULES +#: LABEL/ID_ASSIGN_RULES +msgid "Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn't be used with subprocesses" +msgstr "Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn't be used with subprocesses" + +# TRANSLATION +# LABEL/ID_SELECT_OPTION_TABLE +#: LABEL/ID_SELECT_OPTION_TABLE +msgid "Select a option to export schema or data from the selected table(s)." +msgstr "Select a option to export schema or data from the selected table(s)." + +# TRANSLATION +# LABEL/ID_SELECT_TABLE +#: LABEL/ID_SELECT_TABLE +msgid "Please select a table to export." +msgstr "Please select a table to export." + +# TRANSLATION +# LABEL/ID_TASK_WAS_ASSIGNED_TO_USER +#: LABEL/ID_TASK_WAS_ASSIGNED_TO_USER +msgid "Manual assignment shouldn't be used with subprocesses.<br>The task \\"{0}\\" from case {1} was assigned to user <b>{2}</b> ( {3} {4} )" +msgstr "Manual assignment shouldn't be used with subprocesses.<br>The task \\"{0}\\" from case {1} was assigned to user <b>{2}</b> ( {3} {4} )" + +# TRANSLATION +# LABEL/ID_USER_ONVACATION +#: LABEL/ID_USER_ONVACATION +msgid "User on vacation! Contact to your System Administrator if you want to login. please" +msgstr "User on vacation! Contact to your System Administrator if you want to login. please" + +# TRANSLATION +# LABEL/PASSWORD_HISTORY +#: LABEL/PASSWORD_HISTORY +msgid "Password history" +msgstr "Password history" + +# TRANSLATION +# JAVASCRIPT/ID_EMAIL_REQUIRED +#: JAVASCRIPT/ID_EMAIL_REQUIRED +msgid "The mail to is required, or uncheck the send a test mail" +msgstr "The mail to is required, or uncheck the send a test mail" + +# TRANSLATION +# JAVASCRIPT/ID_PASSWORD_REQUIRED +#: JAVASCRIPT/ID_PASSWORD_REQUIRED +msgid "The password is required, or uncheck the option Require Authentification" +msgstr "The password is required, or uncheck the option Require Authentification" + +# TRANSLATION +# JAVASCRIPT/ID_SERVER_REQUIRED +#: JAVASCRIPT/ID_SERVER_REQUIRED +msgid "You must specify a server!" +msgstr "You must specify a server!" + +# TRANSLATION +# JAVASCRIPT/ID_FILL_SERVER +#: JAVASCRIPT/ID_FILL_SERVER +msgid "[JAVASCRIPT/ID_FILL_SERVER] You must specify a server!" +msgstr "You must specify a server!" + +# TRANSLATION +# LABEL/ID_CONDITIONS_EDITOR +#: LABEL/ID_CONDITIONS_EDITOR +msgid "Conditions editor" +msgstr "Conditions editor" + +# TRANSLATION +# LABEL/ID_SELECT_FILE_PMT_IMPORT +#: LABEL/ID_SELECT_FILE_PMT_IMPORT +msgid "Please select a .pmt file" +msgstr "Please select a .pmt file" + +# TRANSLATION +# LABEL/ID_SELECT_FILE_PM_IMPORT +#: LABEL/ID_SELECT_FILE_PM_IMPORT +msgid "Please select a .pm file" +msgstr "Please select a .pm file" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_PLUGIN +#: LABEL/ID_PLEASE_SELECT_PLUGIN +msgid "Please select the plugin" +msgstr "Please select the plugin" + +# TRANSLATION +# LABEL/ID_NO_FIELD_FOUND +#: LABEL/ID_NO_FIELD_FOUND +msgid "No fields found!" +msgstr "No fields found!" + +# TRANSLATION +# LABEL/ID_UNASSIGNED +#: LABEL/ID_UNASSIGNED +msgid "Unassigned" +msgstr "Unassigned" + +# TRANSLATION +# LABEL/ID_CLAIM +#: LABEL/ID_CLAIM +msgid "Claim" +msgstr "Claim" + +# TRANSLATION +# LABEL/ID_TABLE_INVALID_SYNTAX +#: LABEL/ID_TABLE_INVALID_SYNTAX +msgid "Invalid syntax" +msgstr "Invalid syntax" + +# TRANSLATION +# LABEL/ID_NO_PERMISSION_NO_PARTICIPATED +#: LABEL/ID_NO_PERMISSION_NO_PARTICIPATED +msgid "You do not have permission to see this case or you have not participated in it." +msgstr "You do not have permission to see this case or you have not participated in it." + +# TRANSLATION +# JAVASCRIPT/ID_EMPTY_NODENAME +#: JAVASCRIPT/ID_EMPTY_NODENAME +msgid "The field name contains spaces or it's empty!" +msgstr "The field name contains spaces or it's empty!" + +# TRANSLATION +# JAVASCRIPT/ID_SUGGEST_NEW_ENTRIES_ALERT +#: JAVASCRIPT/ID_SUGGEST_NEW_ENTRIES_ALERT +msgid "You should set all options for new entries." +msgstr "You should set all options for new entries." + +# TRANSLATION +# LABEL/ID_ISNT_LICENSE +#: LABEL/ID_ISNT_LICENSE +msgid "This isn't the correct license." +msgstr "This isn't the correct license." + +# TRANSLATION +# JAVASCRIPT/ID_TABLE_RESERVED_WORDS +#: JAVASCRIPT/ID_TABLE_RESERVED_WORDS +msgid "This table name is reserved. Please set another for" +msgstr "This table name is reserved. Please set another for" + +# TRANSLATION +# LABEL/ID_START_NEW_CASE +#: LABEL/ID_START_NEW_CASE +msgid "Start a new case" +msgstr "Start a new case" + +# TRANSLATION +# LABEL/ID_PROCESS_NOCATEGORY +#: LABEL/ID_PROCESS_NOCATEGORY +msgid "No Category" +msgstr "No Category" + +# TRANSLATION +# LABEL/ID_PLEASE_SELECT_LOGO +#: LABEL/ID_PLEASE_SELECT_LOGO +msgid "Please Select Logo" +msgstr "Please Select Logo" + +# TRANSLATION +# LABEL/ID_TASK_NO_STEPS +#: LABEL/ID_TASK_NO_STEPS +msgid "The task doesn't have any steps" +msgstr "The task doesn't have any steps" + +# TRANSLATION +# JAVASCRIPT/ID_FIELDS_RESERVED_WORDS +#: JAVASCRIPT/ID_FIELDS_RESERVED_WORDS +msgid "The following fields cannot have these names because they are reserved words" +msgstr "The following fields cannot have these names because they are reserved words" + +# TRANSLATION +# LABEL/ID_PROCESS_CATEGORY +#: LABEL/ID_PROCESS_CATEGORY +msgid "Process category" +msgstr "Process category" + +# TRANSLATION +# JAVASCRIPT/ID_GROUP +#: JAVASCRIPT/ID_GROUP +msgid "[JAVASCRIPT/ID_GROUP] Group" +msgstr "Group" + +# TRANSLATION +# JAVASCRIPT/ID_DEPARTMENT +#: JAVASCRIPT/ID_DEPARTMENT +msgid "Department" +msgstr "Department" + +# TRANSLATION +# LABEL/ID_BACK_PERMISSIONS_LIST +#: LABEL/ID_BACK_PERMISSIONS_LIST +msgid "Back to permissions list" +msgstr "Back to permissions list" + +# TRANSLATION +# LABEL/ID_REASSIGNMENT +#: LABEL/ID_REASSIGNMENT +msgid "REASSIGNMENT" +msgstr "REASSIGNMENT" + +# TRANSLATION +# LABEL/ID_FILL_PRIMARY_KEYS +#: LABEL/ID_FILL_PRIMARY_KEYS +msgid "Please fill all the primary key fields" +msgstr "Please fill all the primary key fields" + +# TRANSLATION +# LABEL/ID_TRIGGER_SOURCE_LINK +#: LABEL/ID_TRIGGER_SOURCE_LINK +msgid "Edit Source Code" +msgstr "Edit Source Code" + +# TRANSLATION +# JAVASCRIPT/ID_ASSIGN_SUPERVISOR +#: JAVASCRIPT/ID_ASSIGN_SUPERVISOR +msgid "Assign Process Supervisor" +msgstr "Assign Process Supervisor" + +# TRANSLATION +# LABEL/ADD_USERS_TO_DEPARTMENT +#: LABEL/ADD_USERS_TO_DEPARTMENT +msgid "Add users to department" +msgstr "Add users to department" + +# TRANSLATION +# JAVASCRIPT/ID_RESET +#: JAVASCRIPT/ID_RESET +msgid "Reset" +msgstr "Reset" + +# TRANSLATION +# JAVASCRIPT/ID_CREATE +#: JAVASCRIPT/ID_CREATE +msgid "Create" +msgstr "Create" + +# TRANSLATION +# JAVASCRIPT/ID_DISABLE_WORKSPACE_CONFIRM +#: JAVASCRIPT/ID_DISABLE_WORKSPACE_CONFIRM +msgid "Do you want to disable the selected workspace?" +msgstr "Do you want to disable the selected workspace?" + +# TRANSLATION +# JAVASCRIPT/ID_ENABLE_WORKSPACE_CONFIRM +#: JAVASCRIPT/ID_ENABLE_WORKSPACE_CONFIRM +msgid "Do you want enable the selected workspace?" +msgstr "Do you want enable the selected workspace?" + +# TRANSLATION +# LABEL/ID_ENABLE_WORKSPACE +#: LABEL/ID_ENABLE_WORKSPACE +msgid "Enable Workspace" +msgstr "Enable Workspace" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_ALERT +#: JAVASCRIPT/DBCONNECTIONS_ALERT +msgid "You forgot to fill a required field!" +msgstr "You forgot to fill a required field!" + +# TRANSLATION +# LABEL/ID_DISABLE_WORKSPACE +#: LABEL/ID_DISABLE_WORKSPACE +msgid "Disable Workspace" +msgstr "Disable Workspace" + +# TRANSLATION +# JAVASCRIPT/NEW_SITE_SUCCESS_CONFIRMNOTE +#: JAVASCRIPT/NEW_SITE_SUCCESS_CONFIRMNOTE +msgid "Note.- If you open the new site your current session will be closed." +msgstr "Note.- If you open the new site your current session will be closed." + +# TRANSLATION +# JAVASCRIPT/NEW_SITE_SUCCESS_CONFIRM +#: JAVASCRIPT/NEW_SITE_SUCCESS_CONFIRM +msgid "Do you want open the new site?" +msgstr "Do you want open the new site?" + +# TRANSLATION +# JAVASCRIPT/NEW_SITE_SUCCESS +#: JAVASCRIPT/NEW_SITE_SUCCESS +msgid "Your new site was successfully created with name:" +msgstr "Your new site was successfully created with name:" + +# TRANSLATION +# LABEL/DBCONNECTIONS_MSGR +#: LABEL/DBCONNECTIONS_MSGR +msgid "Server Response" +msgstr "Server Response" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSGR +#: JAVASCRIPT/DBCONNECTIONS_MSGR +msgid "[JAVASCRIPT/DBCONNECTIONS_MSGR] Server Response" +msgstr "Server Response" + +# TRANSLATION +# LABEL/ID_CUSTOM_TRIGGER_DESCRIPTION +#: LABEL/ID_CUSTOM_TRIGGER_DESCRIPTION +msgid "Custom Trigger" +msgstr "Custom Trigger" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSGA +#: JAVASCRIPT/DBCONNECTIONS_MSGA +msgid "Database Connections Test was aborted" +msgstr "Database Connections Test was aborted" + +# TRANSLATION +# LABEL/ID_CUSTOM_TRIGGER +#: LABEL/ID_CUSTOM_TRIGGER +msgid "[LABEL/ID_CUSTOM_TRIGGER] Custom Trigger" +msgstr "Custom Trigger" + +# TRANSLATION +# LABEL/ID_TRIGGERS_VALIDATION_ERR3 +#: LABEL/ID_TRIGGERS_VALIDATION_ERR3 +msgid "* The {Object} {Description} depends." +msgstr "* The {Object} {Description} depends." + +# TRANSLATION +# LABEL/ID_TRIGGERS_VALIDATION_ERR2 +#: LABEL/ID_TRIGGERS_VALIDATION_ERR2 +msgid "({N}) Dependencies were found for this trigger in {Object} objects" +msgstr "({N}) Dependencies were found for this trigger in {Object} objects" + +# TRANSLATION +# LABEL/ID_TRIGGERS_VALIDATION +#: LABEL/ID_TRIGGERS_VALIDATION +msgid "No Dependencies were found for this trigger in {Object} definitions" +msgstr "No Dependencies were found for this trigger in {Object} definitions" + +# TRANSLATION +# JAVASCRIPT/ID_TRIGGERS_VALIDATE_EERR1 +#: JAVASCRIPT/ID_TRIGGERS_VALIDATE_EERR1 +msgid "This trigger can't be deleted due to dependencies." +msgstr "This trigger can't be deleted due to dependencies." + +# TRANSLATION +# LABEL/ID_CONTACT_ADMIN +#: LABEL/ID_CONTACT_ADMIN +msgid "Please contact your system administrator" +msgstr "Please contact your system administrator" + +# TRANSLATION +# LABEL/ID_USER_ON_VACATIONS +#: LABEL/ID_USER_ON_VACATIONS +msgid "User on vacation was replaced" +msgstr "User on vacation was replaced" + +# TRANSLATION +# LABEL/ID_PROCESS_DEF_PROBLEM +#: LABEL/ID_PROCESS_DEF_PROBLEM +msgid "There is a problem in the process definition and/or an exception error ocurred." +msgstr "There is a problem in the process definition and/or an exception error ocurred." + +# TRANSLATION +# LABEL/ID_COPY_OF +#: LABEL/ID_COPY_OF +msgid "Copy of" +msgstr "Copy of" + +# TRANSLATION +# LABEL/ID_COPY +#: LABEL/ID_COPY +msgid "Copy" +msgstr "Copy" + +# TRANSLATION +# LABEL/ID_LOADING +#: LABEL/ID_LOADING +msgid "Loading, please wait..." +msgstr "Loading, please wait..." + +# TRANSLATION +# LABEL/ID_CLEAR_CACHE +#: LABEL/ID_CLEAR_CACHE +msgid "Clear Cache" +msgstr "Clear Cache" + +# TRANSLATION +# LABEL/ID_RESTORE_LOGO +#: LABEL/ID_RESTORE_LOGO +msgid "Restore the default logo" +msgstr "Restore the default logo" + +# TRANSLATION +# JAVASCRIPT/ID_APPLY_LOGO +#: JAVASCRIPT/ID_APPLY_LOGO +msgid "Do you want to apply the selected Logo?" +msgstr "Do you want to apply the selected Logo?" + +# TRANSLATION +# LABEL/ID_CLEAR_CACHE_CONFIRM1 +#: LABEL/ID_CLEAR_CACHE_CONFIRM1 +msgid "Clear all cache files now?" +msgstr "Clear all cache files now?" + +# TRANSLATION +# LABEL/ID_SELFSERVICE +#: LABEL/ID_SELFSERVICE +msgid "[LABEL/ID_SELFSERVICE] Self Service" +msgstr "Self Service" + +# TRANSLATION +# LABEL/ID_PROCESSES +#: LABEL/ID_PROCESSES +msgid "[LABEL/ID_PROCESSES] Processes" +msgstr "Processes" + +# TRANSLATION +# LABEL/ID_ENTER_SEARCH_TERM +#: LABEL/ID_ENTER_SEARCH_TERM +msgid "Enter search term" +msgstr "Enter search term" + +# TRANSLATION +# LABEL/ID_DETAILS +#: LABEL/ID_DETAILS +msgid "[LABEL/ID_DETAILS] Details" +msgstr "Details" + +# TRANSLATION +# LABEL/ID_METHOD +#: LABEL/ID_METHOD +msgid "Method" +msgstr "Method" + +# TRANSLATION +# JAVASCRIPT/ID_FIELD_DUPLICATE +#: JAVASCRIPT/ID_FIELD_DUPLICATE +msgid "Duplicate Field" +msgstr "Duplicate Field" + +# TRANSLATION +# LABEL/ID_DESCRIPTION +#: LABEL/ID_DESCRIPTION +msgid "Description" +msgstr "Description" + +# TRANSLATION +# LABEL/ID_PARAMETERS +#: LABEL/ID_PARAMETERS +msgid "Parameters" +msgstr "Parameters" + +# TRANSLATION +# LABEL/ID_TRIGGER_RETURN_TITLE +#: LABEL/ID_TRIGGER_RETURN_TITLE +msgid "Return value" +msgstr "Return value" + +# TRANSLATION +# LABEL/ID_TRIGGER_RETURN_LABEL +#: LABEL/ID_TRIGGER_RETURN_LABEL +msgid "Variable to hold return value" +msgstr "Variable to hold return value" + +# TRANSLATION +# LABEL/ID_SAVE +#: LABEL/ID_SAVE +msgid "[LABEL/ID_SAVE] Save" +msgstr "Save" + +# TRANSLATION +# LABEL/ID_LOG_CASE_SCHEDULER +#: LABEL/ID_LOG_CASE_SCHEDULER +msgid "Case Scheduler Log" +msgstr "Case Scheduler Log" + +# TRANSLATION +# LABEL/ID_CASE_SCHEDULER +#: LABEL/ID_CASE_SCHEDULER +msgid "Cases Scheduler" +msgstr "Cases Scheduler" + +# TRANSLATION +# LABEL/ID_NEW_CASE +#: LABEL/ID_NEW_CASE +msgid "New case" +msgstr "New case" + +# TRANSLATION +# LABEL/OPEN_NEW_WS +#: LABEL/OPEN_NEW_WS +msgid "Open new site" +msgstr "Open new site" + +# TRANSLATION +# JAVASCRIPT/ERROR_NEW_WS +#: JAVASCRIPT/ERROR_NEW_WS +msgid "You have some mistakes, please try again" +msgstr "You have some mistakes, please try again" + +# TRANSLATION +# JAVASCRIPT/ID_ASSIGN_CASE_TO_USER +#: JAVASCRIPT/ID_ASSIGN_CASE_TO_USER +msgid "You have to select one employee. Select one from the dropdown list please." +msgstr "You have to select one employee. Select one from the dropdown list please." + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSGT +#: JAVASCRIPT/DBCONNECTIONS_MSGT +msgid "The test has" +msgstr "The test has" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_MSGS +#: JAVASCRIPT/DBCONNECTIONS_MSGS +msgid "Successful" +msgstr "Successful" + +# TRANSLATION +# JAVASCRIPT/DBCONNECTIONS_TEST +#: JAVASCRIPT/DBCONNECTIONS_TEST +msgid "TESTING SERVER CONNECTION" +msgstr "TESTING SERVER CONNECTION" + +# TRANSLATION +# LABEL/ID_DBC_CHECK +#: LABEL/ID_DBC_CHECK +msgid "Checking server parameters" +msgstr "Checking server parameters" + +# TRANSLATION +# LABEL/ID_HOST_NAME +#: LABEL/ID_HOST_NAME +msgid "Resolving Host Name" +msgstr "Resolving Host Name" + +# TRANSLATION +# LABEL/ID_CHECK_PORT +#: LABEL/ID_CHECK_PORT +msgid "Checking port" +msgstr "Checking port" + +# TRANSLATION +# LABEL/ID_CONNECT_HOST +#: LABEL/ID_CONNECT_HOST +msgid "Trying to connect to host" +msgstr "Trying to connect to host" + +# TRANSLATION +# LABEL/ID_OPEN_DB +#: LABEL/ID_OPEN_DB +msgid "Trying to open database" +msgstr "Trying to open database" + +# TRANSLATION +# LABEL/ID_SERVICE +#: LABEL/ID_SERVICE +msgid "Service" +msgstr "Service" + +# TRANSLATION +# JAVASCRIPT/ID_ABORT +#: JAVASCRIPT/ID_ABORT +msgid "Abort" +msgstr "Abort" + +# TRANSLATION +# LABEL/ID_UNASSIGNED_USERS +#: LABEL/ID_UNASSIGNED_USERS +msgid "Unassigned Users" +msgstr "Unassigned Users" + +# TRANSLATION +# LABEL/CHECK_ALL +#: LABEL/CHECK_ALL +msgid "Check All" +msgstr "Check All" + +# TRANSLATION +# LABEL/UNCHECK_ALL +#: LABEL/UNCHECK_ALL +msgid "Uncheck All" +msgstr "Uncheck All" + +# TRANSLATION +# JAVASCRIPT/ID_EVENT_MULTIPLE +#: JAVASCRIPT/ID_EVENT_MULTIPLE +msgid "Multiple Event" +msgstr "Multiple Event" + +# TRANSLATION +# JAVASCRIPT/ID_EVENT_MESSAGE +#: JAVASCRIPT/ID_EVENT_MESSAGE +msgid "Message Event" +msgstr "Message Event" + +# TRANSLATION +# JAVASCRIPT/ID_EVENT_CONDITIONAL +#: JAVASCRIPT/ID_EVENT_CONDITIONAL +msgid "Conditional Event" +msgstr "Conditional Event" + +# TRANSLATION +# LABEL/ID_CASES_START_PAGE +#: LABEL/ID_CASES_START_PAGE +msgid "Home" +msgstr "Home" + +# TRANSLATION +# LABEL/ID_PROCESS_NO_CATEGORY +#: LABEL/ID_PROCESS_NO_CATEGORY +msgid "[LABEL/ID_PROCESS_NO_CATEGORY] No Category" +msgstr "No Category" + +# TRANSLATION +# LABEL/ID_USER_TO_REASSIGN +#: LABEL/ID_USER_TO_REASSIGN +msgid "Reassign to:" +msgstr "Reassign to:" + +# TRANSLATION +# LABEL/ID_REASSIGN_USERS +#: LABEL/ID_REASSIGN_USERS +msgid "User Reassignment" +msgstr "User Reassignment" + +# TRANSLATION +# LABEL/ID_CASES_LIST_SETUP +#: LABEL/ID_CASES_LIST_SETUP +msgid "Cases Lists" +msgstr "Cases Lists" + +# TRANSLATION +# LABEL/ID_APPCACHE_SETUP +#: LABEL/ID_APPCACHE_SETUP +msgid "Cases List Cache Builder" +msgstr "Cases List Cache Builder " + +# TRANSLATION +# LABEL/ID_CLEAR_CACHE_MSG1 +#: LABEL/ID_CLEAR_CACHE_MSG1 +msgid "All cache data was deleted" +msgstr "All cache data was deleted" + +# TRANSLATION +# LABEL/ID_CLEAR_CACHE_MSG2 +#: LABEL/ID_CLEAR_CACHE_MSG2 +msgid "The cache directory is empty" +msgstr "The cache directory is empty" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_UID +#: LABEL/ID_CASESLIST_APP_UID +msgid "Case Id" +msgstr "Case Id" + +# TRANSLATION +# LABEL/ID_CASESLIST_DEL_INDEX +#: LABEL/ID_CASESLIST_DEL_INDEX +msgid "Case Index" +msgstr "Case Index" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_NUMBER +#: LABEL/ID_CASESLIST_APP_NUMBER +msgid "[LABEL/ID_CASESLIST_APP_NUMBER] #" +msgstr "#" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_STATUS +#: LABEL/ID_CASESLIST_APP_STATUS +msgid "[LABEL/ID_CASESLIST_APP_STATUS] Status" +msgstr "Status" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_TITLE +#: LABEL/ID_CASESLIST_APP_TITLE +msgid "[LABEL/ID_CASESLIST_APP_TITLE] Case" +msgstr "Case" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_PRO_TITLE +#: LABEL/ID_CASESLIST_APP_PRO_TITLE +msgid "[LABEL/ID_CASESLIST_APP_PRO_TITLE] Process" +msgstr "Process" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_TAS_TITLE +#: LABEL/ID_CASESLIST_APP_TAS_TITLE +msgid "[LABEL/ID_CASESLIST_APP_TAS_TITLE] Task" +msgstr "Task" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_DEL_PREVIOUS_USER +#: LABEL/ID_CASESLIST_APP_DEL_PREVIOUS_USER +msgid "Sent by" +msgstr "Sent by" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_CURRENT_USER +#: LABEL/ID_CASESLIST_APP_CURRENT_USER +msgid "Current User" +msgstr "Current User" + +# TRANSLATION +# LABEL/ID_CASESLIST_DEL_TASK_DUE_DATE +#: LABEL/ID_CASESLIST_DEL_TASK_DUE_DATE +msgid "Due Date" +msgstr "Due Date" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_UPDATE_DATE +#: LABEL/ID_CASESLIST_APP_UPDATE_DATE +msgid "Last Modify" +msgstr "Last Modify" + +# TRANSLATION +# LABEL/ID_CASESLIST_DEL_PRIORITY +#: LABEL/ID_CASESLIST_DEL_PRIORITY +msgid "Priority" +msgstr "Priority" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_FINISH_DATE +#: LABEL/ID_CASESLIST_APP_FINISH_DATE +msgid "Finish Date" +msgstr "Finish Date" + +# TRANSLATION +# LABEL/ID_MAINTENANCE +#: LABEL/ID_MAINTENANCE +msgid "Maintenance" +msgstr "Maintenance" + +# TRANSLATION +# LABEL/ID_SETTINGS +#: LABEL/ID_SETTINGS +msgid "Settings" +msgstr "Settings" + +# TRANSLATION +# LABEL/ID_TOOLS +#: LABEL/ID_TOOLS +msgid "Tools" +msgstr "Tools" + +# TRANSLATION +# LABEL/ID_CASES_LIST_GRID_LOADING +#: LABEL/ID_CASES_LIST_GRID_LOADING +msgid "Loading Cases List, please wait..." +msgstr "Loading Cases List, please wait..." + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_THREAD_INDEX +#: LABEL/ID_CASESLIST_APP_THREAD_INDEX +msgid "Thread Index" +msgstr "Thread Index" + +# TRANSLATION +# LABEL/ID_CASESLIST_APP_DEL_INDEX +#: LABEL/ID_CASESLIST_APP_DEL_INDEX +msgid "Del Index" +msgstr "Del Index" + +# TRANSLATION +# LABEL/ID_TRIGGERS_VALIDATE_EERR1 +#: LABEL/ID_TRIGGERS_VALIDATE_EERR1 +msgid "[LABEL/ID_TRIGGERS_VALIDATE_EERR1] * The {Object} {Description} depends." +msgstr "* The {Object} {Description} depends." + +# TRANSLATION +# LABEL/ID_CASES_STATUS_TO_DO +#: LABEL/ID_CASES_STATUS_TO_DO +msgid "[LABEL/ID_CASES_STATUS_TO_DO] To Do" +msgstr "To Do" + +# TRANSLATION +# JAVASCRIPT/ID_DONT_SAVE_XMLFORM +#: JAVASCRIPT/ID_DONT_SAVE_XMLFORM +msgid "This form has not a submit action. Do you want to continue anyway?" +msgstr "This form has not a submit action. Do you want to continue anyway?" + +# TRANSLATION +# LABEL/ID_CASES_STATUS_COMPLETED +#: LABEL/ID_CASES_STATUS_COMPLETED +msgid "[LABEL/ID_CASES_STATUS_COMPLETED] Completed" +msgstr "Completed" + +# TRANSLATION +# LABEL/ID_CASES_STATUS_DRAFT +#: LABEL/ID_CASES_STATUS_DRAFT +msgid "[LABEL/ID_CASES_STATUS_DRAFT] Draft" +msgstr "Draft" + +# TRANSLATION +# LABEL/ID_PM_ENV_SETTINGS_TITLE +#: LABEL/ID_PM_ENV_SETTINGS_TITLE +msgid "Processmaker Environment Settings" +msgstr "Processmaker Environment Settings" + +# TRANSLATION +# LABEL/ID_PM_ENV_SETTINGS_USERFIELDSET_TITLE +#: LABEL/ID_PM_ENV_SETTINGS_USERFIELDSET_TITLE +msgid "Display Information Settings" +msgstr "Display Information Settings" + +# TRANSLATION +# LABEL/IS_USER_NAME_DISPLAY_FORMAT +#: LABEL/IS_USER_NAME_DISPLAY_FORMAT +msgid "User Name Display Format" +msgstr "User Name Display Format" + +# TRANSLATION +# LABEL/ID_SAVE_SETTINGS +#: LABEL/ID_SAVE_SETTINGS +msgid "Save Settings" +msgstr "Save Settings" + +# TRANSLATION +# LABEL/ID_SAVING_ENVIRONMENT_SETTINGS +#: LABEL/ID_SAVING_ENVIRONMENT_SETTINGS +msgid "Saving Environment Settings" +msgstr "Saving Environment Settings" + +# TRANSLATION +# LABEL/ID_ENVIRONMENT_SETTINGS_MSG_1 +#: LABEL/ID_ENVIRONMENT_SETTINGS_MSG_1 +msgid "You should to select a format from the list." +msgstr "You should to select a format from the list." + +# TRANSLATION +# LABEL/ID_ENVIRONMENT_SETTINGS +#: LABEL/ID_ENVIRONMENT_SETTINGS +msgid "Environment" +msgstr "Environment" + +# TRANSLATION +# LABEL/ID_LANG_INSTALL_UPDATE +#: LABEL/ID_LANG_INSTALL_UPDATE +msgid "Install / Update" +msgstr "Install / Update" + +# TRANSLATION +# LABEL/ID_LAN_LANGUAGE +#: LABEL/ID_LAN_LANGUAGE +msgid "[LABEL/ID_LAN_LANGUAGE] Language" +msgstr "Language" + +# TRANSLATION +# LABEL/ID_LAN_COUNTRY +#: LABEL/ID_LAN_COUNTRY +msgid "Country" +msgstr "Country" + +# TRANSLATION +# LABEL/ID_LAN_UPDATE_DATE +#: LABEL/ID_LAN_UPDATE_DATE +msgid "Update Date" +msgstr "Update Date" + +# TRANSLATION +# LABEL/ID_LAN_REV_DATE +#: LABEL/ID_LAN_REV_DATE +msgid "Revision Date" +msgstr "Revision Date" + +# TRANSLATION +# LABEL/ID_LAN_VERSION +#: LABEL/ID_LAN_VERSION +msgid "Version" +msgstr "Version" + +# TRANSLATION +# LABEL/ID_LAN_UPLOAD_TITLE +#: LABEL/ID_LAN_UPLOAD_TITLE +msgid "Upload translation file" +msgstr "Upload translation file" + +# TRANSLATION +# LABEL/ID_LAN_FILE +#: LABEL/ID_LAN_FILE +msgid "File" +msgstr "File" + +# TRANSLATION +# LABEL/ID_LAN_FILE_WATER_LABEL +#: LABEL/ID_LAN_FILE_WATER_LABEL +msgid "Select a translation file" +msgstr "Select a translation file" + +# TRANSLATION +# LABEL/ID_REFRESH_LABEL +#: LABEL/ID_REFRESH_LABEL +msgid "Refresh" +msgstr "Refresh" + +# TRANSLATION +# LABEL/ID_REFRESH_MESSAGE +#: LABEL/ID_REFRESH_MESSAGE +msgid "You clicked Ctrl + F5" +msgstr "You clicked Ctrl + F5" + +# TRANSLATION +# LABEL/ID_OPT_READ +#: LABEL/ID_OPT_READ +msgid "Read" +msgstr "Read" + +# TRANSLATION +# LABEL/ID_OPT_UNREAD +#: LABEL/ID_OPT_UNREAD +msgid "Unread" +msgstr "Unread" + +# TRANSLATION +# LABEL/ID_OPT_ALL +#: LABEL/ID_OPT_ALL +msgid "[LABEL/ID_OPT_ALL] All" +msgstr "All" + +# TRANSLATION +# LABEL/ID_OPT_STARTED +#: LABEL/ID_OPT_STARTED +msgid "Started by Me" +msgstr "Started by Me" + +# TRANSLATION +# LABEL/ID_OPT_COMPLETED +#: LABEL/ID_OPT_COMPLETED +msgid "Completed by Me" +msgstr "Completed by Me" + +# TRANSLATION +# LABEL/ID_EMPTY_PROCESSES +#: LABEL/ID_EMPTY_PROCESSES +msgid "Select a Process..." +msgstr "Select a Process..." + +# TRANSLATION +# LABEL/ID_EMPTY_SEARCH +#: LABEL/ID_EMPTY_SEARCH +msgid "Search ..." +msgstr "Search ..." + +# TRANSLATION +# LABEL/ID_EMPTY_CASE +#: LABEL/ID_EMPTY_CASE +msgid "Search Case..." +msgstr "Search Case..." + +# TRANSLATION +# LABEL/ID_OPT_JUMP +#: LABEL/ID_OPT_JUMP +msgid "Jump To" +msgstr "Jump To" + +# TRANSLATION +# LABEL/ID_DISPLAY_ITEMS +#: LABEL/ID_DISPLAY_ITEMS +msgid "Display Items {0} - {1} of {2}" +msgstr "Display Items {0} - {1} of {2}" + +# TRANSLATION +# LABEL/ID_DISPLAY_EMPTY +#: LABEL/ID_DISPLAY_EMPTY +msgid "Displaying Empty" +msgstr "Displaying Empty" + +# TRANSLATION +# LABEL/ID_EMPTY_PMTABLE +#: LABEL/ID_EMPTY_PMTABLE +msgid "Select a PM Table..." +msgstr "Select a PM Table..." + +# TRANSLATION +# LABEL/ID_HEADER_NUMBER +#: LABEL/ID_HEADER_NUMBER +msgid "[LABEL/ID_HEADER_NUMBER] #" +msgstr "#" + +# TRANSLATION +# LABEL/ID_HEADER_FIELD_NAME +#: LABEL/ID_HEADER_FIELD_NAME +msgid "[LABEL/ID_HEADER_FIELD_NAME] Field Name" +msgstr "Field Name" + +# TRANSLATION +# LABEL/ID_HEADER_FIELD_TYPE +#: LABEL/ID_HEADER_FIELD_TYPE +msgid "Field Type" +msgstr "Field Type" + +# TRANSLATION +# LABEL/ID_HEADER_LABEL +#: LABEL/ID_HEADER_LABEL +msgid "[LABEL/ID_HEADER_LABEL] Label" +msgstr "Label" + +# TRANSLATION +# LABEL/ID_HEADER_WIDTH +#: LABEL/ID_HEADER_WIDTH +msgid "Width" +msgstr "Width" + +# TRANSLATION +# LABEL/ID_HEADER_ALIGN +#: LABEL/ID_HEADER_ALIGN +msgid "Align" +msgstr "Align" + +# TRANSLATION +# LABEL/ID_SELECTED_FIELD +#: LABEL/ID_SELECTED_FIELD +msgid "selected field" +msgstr "selected field" + +# TRANSLATION +# LABEL/ID_AVAILABLE_FIELDS +#: LABEL/ID_AVAILABLE_FIELDS +msgid "Available Fields" +msgstr "Available Fields" + +# TRANSLATION +# LABEL/ID_CASES_LIST_FIELDS +#: LABEL/ID_CASES_LIST_FIELDS +msgid "Cases List Fields" +msgstr "Cases List Fields" + +# TRANSLATION +# LABEL/ID_TITLE_INBOX +#: LABEL/ID_TITLE_INBOX +msgid "[LABEL/ID_TITLE_INBOX] Inbox" +msgstr "Inbox" + +# TRANSLATION +# LABEL/ID_TITLE_DRAFT +#: LABEL/ID_TITLE_DRAFT +msgid "[LABEL/ID_TITLE_DRAFT] Draft" +msgstr "Draft" + +# TRANSLATION +# LABEL/ID_TITLE_PARTICIPATED +#: LABEL/ID_TITLE_PARTICIPATED +msgid "[LABEL/ID_TITLE_PARTICIPATED] Participated" +msgstr "Participated" + +# TRANSLATION +# LABEL/ID_TITLE_UNASSIGNED +#: LABEL/ID_TITLE_UNASSIGNED +msgid "[LABEL/ID_TITLE_UNASSIGNED] Unassigned" +msgstr "Unassigned" + +# TRANSLATION +# LABEL/ID_TITLE_PAUSED +#: LABEL/ID_TITLE_PAUSED +msgid "[LABEL/ID_TITLE_PAUSED] Paused" +msgstr "Paused" + +# TRANSLATION +# LABEL/ID_TITLE_COMPLETED +#: LABEL/ID_TITLE_COMPLETED +msgid "[LABEL/ID_TITLE_COMPLETED] Completed" +msgstr "Completed" + +# TRANSLATION +# LABEL/ID_TITLE_CANCELLED +#: LABEL/ID_TITLE_CANCELLED +msgid "Cancelled" +msgstr "Cancelled" + +# TRANSLATION +# LABEL/ID_PM_TABLE +#: LABEL/ID_PM_TABLE +msgid "PM Table" +msgstr "PM Table" + +# TRANSLATION +# LABEL/ID_ROWS_PER_PAGE +#: LABEL/ID_ROWS_PER_PAGE +msgid "Rows per Page" +msgstr "Rows per Page" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT +#: LABEL/ID_DATE_FORMAT +msgid "Date Format" +msgstr "Date Format" + +# TRANSLATION +# LABEL/ID_RESET +#: LABEL/ID_RESET +msgid "[LABEL/ID_RESET] Reset" +msgstr "Reset" + +# TRANSLATION +# LABEL/ID_APPLY_CHANGES +#: LABEL/ID_APPLY_CHANGES +msgid "Apply changes" +msgstr "Apply changes" + +# TRANSLATION +# LABEL/ID_INTERNATIONAL +#: LABEL/ID_INTERNATIONAL +msgid "International" +msgstr "International" + +# TRANSLATION +# LABEL/ID_BREAK_DW_PROCESS +#: LABEL/ID_BREAK_DW_PROCESS +msgid "were lost by a connection problem." +msgstr "were lost by a connection problem." + +# TRANSLATION +# LABEL/ID_CATEGORY +#: LABEL/ID_CATEGORY +msgid "Category" +msgstr "Category" + +# TRANSLATION +# LABEL/ID_BROWSE_LIBRARY +#: LABEL/ID_BROWSE_LIBRARY +msgid "Browse Library" +msgstr "Browse Library" + +# TRANSLATION +# LABEL/ID_IMPORT +#: LABEL/ID_IMPORT +msgid "Import" +msgstr "Import" + +# TRANSLATION +# LABEL/ID_PRO_TITLE +#: LABEL/ID_PRO_TITLE +msgid "Process Title" +msgstr "Process Title" + +# TRANSLATION +# LABEL/ID_DISPLAY_OF +#: LABEL/ID_DISPLAY_OF +msgid "of" +msgstr "of" + +# TRANSLATION +# LABEL/ID_DELETE_LANGUAGE_WARNING +#: LABEL/ID_DELETE_LANGUAGE_WARNING +msgid "To delete a language you should select a item from the list first." +msgstr "To delete a language you should select a item from the list first." + +# TRANSLATION +# LABEL/ID_DELETE_LANGUAGE_CONFIRM +#: LABEL/ID_DELETE_LANGUAGE_CONFIRM +msgid "Do you want remove the language \"{0}\" ?" +msgstr "Do you want remove the language \"{0}\" ?" + +# TRANSLATION +# LABEL/ID_DELETE_LANGUAGE +#: LABEL/ID_DELETE_LANGUAGE +msgid "[LABEL/ID_DELETE_LANGUAGE] Remove" +msgstr "Remove" + +# TRANSLATION +# LABEL/ID_LANGUAGE_DELETED_SUCCESSFULLY +#: LABEL/ID_LANGUAGE_DELETED_SUCCESSFULLY +msgid "Language deleted successfully!" +msgstr "Language deleted successfully!" + +# TRANSLATION +# LABEL/ID_LANGUAGE_CANT_DELETE +#: LABEL/ID_LANGUAGE_CANT_DELETE +msgid "There is {0} cases started with this language, delete action canceled!" +msgstr "There is {0} cases started with this language, delete action canceled!" + +# TRANSLATION +# LABEL/ID_TOTAL_CASES +#: LABEL/ID_TOTAL_CASES +msgid "Total Cases" +msgstr "Total Cases" + +# TRANSLATION +# LABEL/ID_HEARTBEAT_CONFIG +#: LABEL/ID_HEARTBEAT_CONFIG +msgid "Heart Beat" +msgstr "Heart Beat" + +# TRANSLATION +# LABEL/ID_PM_HEARTBEAT_SETTINGS_TITLE +#: LABEL/ID_PM_HEARTBEAT_SETTINGS_TITLE +msgid "Heart Beat Configuration" +msgstr "Heart Beat Configuration" + +# TRANSLATION +# LABEL/ID_SETTINGS_HEARTBEAT_TITLE +#: LABEL/ID_SETTINGS_HEARTBEAT_TITLE +msgid "Display Setting" +msgstr "Display Setting" + +# TRANSLATION +# LABEL/ID_HEARTBEAT_DISPLAY +#: LABEL/ID_HEARTBEAT_DISPLAY +msgid "[LABEL/ID_HEARTBEAT_DISPLAY] Heart Beat" +msgstr "Heart Beat" + +# TRANSLATION +# JAVASCRIPT/ID_MAIL_SUCESSFULLY +#: JAVASCRIPT/ID_MAIL_SUCESSFULLY +msgid "[JAVASCRIPT/ID_MAIL_SUCESSFULLY] Test message sent successfully" +msgstr "Test message sent successfully" + +# TRANSLATION +# JAVASCRIPT/ID_MAIL_FAILED +#: JAVASCRIPT/ID_MAIL_FAILED +msgid "The test failure, you must configure your\r\nserver to send messages" +msgstr "The test failure, you must configure your\r\nserver to send messages" + +# TRANSLATION +# LABEL/ID_CACHE_DIR_ISNOT_WRITABLE +#: LABEL/ID_CACHE_DIR_ISNOT_WRITABLE +msgid "The cache directory is not writable, change permissions please!" +msgstr "The cache directory is not writable, change permissions please!" + +# TRANSLATION +# LABEL/ID_CACHE_DELETED_SUCCESS +#: LABEL/ID_CACHE_DELETED_SUCCESS +msgid "All cache data was deleted successfully" +msgstr "All cache data was deleted successfully" + +# TRANSLATION +# JAVASCRIPT/ID_EMAIL_INVALID +#: JAVASCRIPT/ID_EMAIL_INVALID +msgid "The mail is invalid" +msgstr "The mail is invalid" + +# TRANSLATION +# LABEL/MSG_CONDITION_NOT_DEFINED +#: LABEL/MSG_CONDITION_NOT_DEFINED +msgid "Condition variable not defined" +msgstr "Condition variable not defined" + +# TRANSLATION +# JAVASCRIPT/ID_RSTDATAFIELD +#: JAVASCRIPT/ID_RSTDATAFIELD +msgid "Reset Data Field" +msgstr "Reset Data Field" + +# TRANSLATION +# LABEL/ID_OPEN_IN_:POPUP +#: LABEL/ID_OPEN_IN_:POPUP +msgid "Open in a popup" +msgstr "Open in a popup" + +# TRANSLATION +# LABEL/ID_DEATACH +#: LABEL/ID_DEATACH +msgid "Deatach" +msgstr "Deatach" + +# TRANSLATION +# LABEL/ID_PRO_USER +#: LABEL/ID_PRO_USER +msgid "User Owner" +msgstr "User Owner" + +# TRANSLATION +# LABEL/ID_SYSTEM +#: LABEL/ID_SYSTEM +msgid "System" +msgstr "System" + +# TRANSLATION +# LABEL/ID_VARIABLES +#: LABEL/ID_VARIABLES +msgid "Variables" +msgstr "Variables" + +# TRANSLATION +# LABEL/ID_OPEN_CASE +#: LABEL/ID_OPEN_CASE +msgid "Open Case" +msgstr "Open Case" + +# TRANSLATION +# LABEL/ID_CASES_STATUS_CANCELLED +#: LABEL/ID_CASES_STATUS_CANCELLED +msgid "[LABEL/ID_CASES_STATUS_CANCELLED] Cancelled" +msgstr "Cancelled" + +# TRANSLATION +# LABEL/ID_CASES_STATUS_PAUSED +#: LABEL/ID_CASES_STATUS_PAUSED +msgid "[LABEL/ID_CASES_STATUS_PAUSED] Paused" +msgstr "Paused" + +# TRANSLATION +# LABEL/ID_ALL_PROCESS +#: LABEL/ID_ALL_PROCESS +msgid "All Processes" +msgstr "All Processes" + +# TRANSLATION +# LABEL/ID_ALL_USERS +#: LABEL/ID_ALL_USERS +msgid "All Users" +msgstr "All Users" + +# TRANSLATION +# LABEL/ID_ALL_STATUS +#: LABEL/ID_ALL_STATUS +msgid "All Status" +msgstr "All Status" + +# TRANSLATION +# LABEL/ID_CONFIRM +#: LABEL/ID_CONFIRM +msgid "Confirm" +msgstr "Confirm" + +# TRANSLATION +# LABEL/ID_CONFIRM_UNPAUSE_CASE +#: LABEL/ID_CONFIRM_UNPAUSE_CASE +msgid "Are you sure you want to unpause this case?" +msgstr "Are you sure you want to unpause this case?" + +# TRANSLATION +# LABEL/ID_PRO_DESCRIPTION +#: LABEL/ID_PRO_DESCRIPTION +msgid "Process Description" +msgstr "Process Description" + +# TRANSLATION +# LABEL/ID_PRO_DEBUG +#: LABEL/ID_PRO_DEBUG +msgid "Debug" +msgstr "Debug" + +# TRANSLATION +# LABEL/ID_PRO_CREATE_DATE +#: LABEL/ID_PRO_CREATE_DATE +msgid "Create Date" +msgstr "Create Date" + +# TRANSLATION +# LABEL/ID_ON +#: LABEL/ID_ON +msgid "On" +msgstr "On" + +# TRANSLATION +# LABEL/ID_OFF +#: LABEL/ID_OFF +msgid "Off" +msgstr "Off" + +# TRANSLATION +# LABEL/ID_NO_SELECTION_WARNING +#: LABEL/ID_NO_SELECTION_WARNING +msgid "Select a item from the list please." +msgstr "Select a item from the list please." + +# TRANSLATION +# JAVASCRIPT/ID_REQUIRED_NAME_TRIGGERS +#: JAVASCRIPT/ID_REQUIRED_NAME_TRIGGERS +msgid "You forgot the title of the trigger" +msgstr "You forgot the title of the trigger" + +# TRANSLATION +# JAVASCRIPT/ID_EXIST_PROCESS +#: JAVASCRIPT/ID_EXIST_PROCESS +msgid "There is a process with the same name. this process will not save" +msgstr "There is a process with the same name. this process will not save" + +# TRANSLATION +# JAVASCRIPT/ID_EXIST_DYNAFORM +#: JAVASCRIPT/ID_EXIST_DYNAFORM +msgid "There is a Dynaform with the same name in this process. It is not saving" +msgstr "There is a Dynaform with the same name in this process. It is not saving " + +# TRANSLATION +# LABEL/ID_CLASS_TABLE_DOESNT_EXIST +#: LABEL/ID_CLASS_TABLE_DOESNT_EXIST +msgid "This Class Table doesn't exists!" +msgstr "This Class Table doesn't exists! " + +# TRANSLATION +# JAVASCRIPT/ID_EXIST_INPUTDOCUMENT +#: JAVASCRIPT/ID_EXIST_INPUTDOCUMENT +msgid "There is an Input Document with the same name in this process. It is not saving" +msgstr "There is an Input Document with the same name in this process. It is not saving " + +# TRANSLATION +# JAVASCRIPT/ID_EXIST_OUTPUTDOCUMENT +#: JAVASCRIPT/ID_EXIST_OUTPUTDOCUMENT +msgid "There is an Output Document with the same name in this process. It is not saving" +msgstr "There is an Output Document with the same name in this process. It is not saving " + +# TRANSLATION +# LABEL/ID_DELEGATE_DATE_FROM +#: LABEL/ID_DELEGATE_DATE_FROM +msgid "Delegated date from" +msgstr "Delegated date from" + +# TRANSLATION +# JAVASCRIPT/ID_DUPLICATE_CATEGORY_NAME +#: JAVASCRIPT/ID_DUPLICATE_CATEGORY_NAME +msgid "Duplicate category name." +msgstr "Duplicate category name." + +# TRANSLATION +# LABEL/ID_DELEGATE_DATE_TO +#: LABEL/ID_DELEGATE_DATE_TO +msgid "to" +msgstr "to" + +# TRANSLATION +# LABEL/ID_FILTER_BY_DELEGATED_DATE +#: LABEL/ID_FILTER_BY_DELEGATED_DATE +msgid "Filter" +msgstr "Filter" + +# TRANSLATION +# LABEL/ID_PM_ENV_SETTINGS_REGIONFIELDSET_TITLE +#: LABEL/ID_PM_ENV_SETTINGS_REGIONFIELDSET_TITLE +msgid "Regional Settings" +msgstr "Regional Settings" + +# TRANSLATION +# LABEL/ID_GLOBAL_DATE_MASK +#: LABEL/ID_GLOBAL_DATE_MASK +msgid "Global date mask" +msgstr "Global date mask" + +# TRANSLATION +# LABEL/ID_SAVED_SUCCESSFULLY +#: LABEL/ID_SAVED_SUCCESSFULLY +msgid "Saved Successfully" +msgstr "Saved Successfully" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_CONFIGURATION +#: LABEL/PENTAHO_LABEL_CONFIGURATION +msgid "Configuration" +msgstr "Configuration" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_DATASOURCE +#: LABEL/PENTAHO_LABEL_DATASOURCE +msgid "Datasource Name" +msgstr "Datasource Name" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_DB_EXISTS +#: LABEL/PENTAHO_LABEL_DB_EXISTS +msgid "Datasource already exist" +msgstr "Datasource already exist" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_DB_SUCCESS +#: LABEL/PENTAHO_LABEL_DB_SUCCESS +msgid "Datasource created successfully" +msgstr "Datasource created successfully" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_DRIVER_CLASS +#: LABEL/PENTAHO_LABEL_DRIVER_CLASS +msgid "Driver Class" +msgstr "Driver Class" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_JNDI_CONNECTION +#: LABEL/PENTAHO_LABEL_JNDI_CONNECTION +msgid "JNDI Connection" +msgstr "JNDI Connection" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_JNDI_INFORMATION +#: LABEL/PENTAHO_LABEL_JNDI_INFORMATION +msgid "JNDI Information" +msgstr "JNDI Information" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_PASSWORD +#: LABEL/PENTAHO_LABEL_PASSWORD +msgid "Password" +msgstr "Password" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_REBUILD +#: LABEL/PENTAHO_LABEL_REBUILD +msgid "Rebuild" +msgstr "Rebuild" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_ROLES_MANAGER +#: LABEL/PENTAHO_LABEL_ROLES_MANAGER +msgid "Roles Manager" +msgstr "Roles Manager" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_SERVER +#: LABEL/PENTAHO_LABEL_SERVER +msgid "Pentaho Server (URL)" +msgstr "Pentaho Server (URL)" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_SHOW_JNDI_INFORMATION +#: LABEL/PENTAHO_LABEL_SHOW_JNDI_INFORMATION +msgid "Show Jndi Info" +msgstr "Show Jndi Info" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_SYNC +#: LABEL/PENTAHO_LABEL_SYNC +msgid "Sync to Pentaho Solution" +msgstr "Sync to Pentaho Solution" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_TABLE_ALREADY_SYNCH +#: LABEL/PENTAHO_LABEL_TABLE_ALREADY_SYNCH +msgid "Workspace already synchronized with Pentaho Solution" +msgstr "Workspace already synchronized with Pentaho Solution" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_TABLE_SUCCESS +#: LABEL/PENTAHO_LABEL_TABLE_SUCCESS +msgid "Table APP_CACHE_VIEW and triggers are installed successfully" +msgstr "Table APP_CACHE_VIEW and triggers are installed successfully" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_TABLE_SYNCHED +#: LABEL/PENTAHO_LABEL_TABLE_SYNCHED +msgid "Workspace synchronized with Pentaho Solution" +msgstr "Workspace synchronized with Pentaho Solution" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_TABLE_TRIGGERS +#: LABEL/PENTAHO_LABEL_TABLE_TRIGGERS +msgid "Database tables and triggers" +msgstr "Database tables and triggers" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_URL +#: LABEL/PENTAHO_LABEL_URL +msgid "URL" +msgstr "URL" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_USER_CONSOLE +#: LABEL/PENTAHO_LABEL_USER_CONSOLE +msgid "Pentaho User Console" +msgstr "Pentaho User Console" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_USER_CREATE +#: LABEL/PENTAHO_LABEL_USER_CREATE +msgid "Create user in Pentaho" +msgstr "Create user in Pentaho" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_USER_CREATED +#: LABEL/PENTAHO_LABEL_USER_CREATED +msgid "User created successfully" +msgstr "User created successfully" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_USER_EXIST +#: LABEL/PENTAHO_LABEL_USER_EXIST +msgid "User already exist" +msgstr "User already exist" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_USER_NAME +#: LABEL/PENTAHO_LABEL_USER_NAME +msgid "User Name" +msgstr "User Name" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_WS_SYNCHED +#: LABEL/PENTAHO_LABEL_WS_SYNCHED +msgid "[LABEL/PENTAHO_LABEL_WS_SYNCHED] Workspace synchronized with Pentaho Solution" +msgstr "Workspace synchronized with Pentaho Solution" + +# TRANSLATION +# LABEL/PENTAHO_LABEL_WS_USER_PASSWORD +#: LABEL/PENTAHO_LABEL_WS_USER_PASSWORD +msgid "Pentaho Workspace User and Password" +msgstr "Pentaho Workspace User and Password" + +# TRANSLATION +# LABEL/PENTAHO_TABLES_TRIGGERS +#: LABEL/PENTAHO_TABLES_TRIGGERS +msgid "[LABEL/PENTAHO_TABLES_TRIGGERS] Database tables and triggers" +msgstr "Database tables and triggers" + +# TRANSLATION +# JAVASCRIPT/ID_EXIST_TRIGGERS +#: JAVASCRIPT/ID_EXIST_TRIGGERS +msgid "There is a triggers with the same name in this process." +msgstr "There is a triggers with the same name in this process." + +# TRANSLATION +# LABEL/ID_SELECT_ONE_AT_LEAST +#: LABEL/ID_SELECT_ONE_AT_LEAST +msgid "Select at least one item from the list" +msgstr "Select at least one item from the list" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_CANCEL_CASE +#: LABEL/ID_MSG_CONFIRM_CANCEL_CASE +msgid "[LABEL/ID_MSG_CONFIRM_CANCEL_CASE] Are you sure you want to cancel this case?" +msgstr "Are you sure you want to cancel this case?" + +# TRANSLATION +# LABEL/ID_PAUSE_CASE_TO_DATE +#: LABEL/ID_PAUSE_CASE_TO_DATE +msgid "Do you want to pause the case to date:" +msgstr "Do you want to pause the case to date: " + +# TRANSLATION +# LABEL/ID_DELETING_ELEMENTS +#: LABEL/ID_DELETING_ELEMENTS +msgid "Deleting elements, please wait..." +msgstr "Deleting elements, please wait..." + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_DELETE_CASE +#: LABEL/ID_MSG_CONFIRM_DELETE_CASE +msgid "[LABEL/ID_MSG_CONFIRM_DELETE_CASE] Are you sure you want to delete this case?" +msgstr "Are you sure you want to delete this case?" + +# TRANSLATION +# LABEL/ID_MSG_CONFIRM_CANCEL_CASES +#: LABEL/ID_MSG_CONFIRM_CANCEL_CASES +msgid "Are you sure you want to cancel all selected cases?" +msgstr "Are you sure you want to cancel all selected cases?" + +# TRANSLATION +# LABEL/ID_PAUSE_CASE +#: LABEL/ID_PAUSE_CASE +msgid "Pause Case" +msgstr "Pause Case" + +# TRANSLATION +# LABEL/ID_PAUSE +#: LABEL/ID_PAUSE +msgid "[LABEL/ID_PAUSE] Pause" +msgstr "Pause" + +# TRANSLATION +# LABEL/ID_UNPAUSE_CASE +#: LABEL/ID_UNPAUSE_CASE +msgid "[LABEL/ID_UNPAUSE_CASE] Unpause" +msgstr "Unpause" + +# TRANSLATION +# LABEL/ID_OPEN_IN_POPUP +#: LABEL/ID_OPEN_IN_POPUP +msgid "[LABEL/ID_OPEN_IN_POPUP] Open in a popup" +msgstr "Open in a popup" + +# TRANSLATION +# JAVASCRIPT/ID_DYNAFORM_ASSIGN +#: JAVASCRIPT/ID_DYNAFORM_ASSIGN +msgid "You can not delete this dynaform. This is assigned in some step." +msgstr "You can not delete this dynaform. This is assigned in some step." + +# TRANSLATION +# JAVASCRIPT/ID_REQ_TITLE +#: JAVASCRIPT/ID_REQ_TITLE +msgid "You forgot to fill the Title field!" +msgstr "You forgot to fill the Title field!" + +# TRANSLATION +# LABEL/ID_PROCESS_DELETE_LABEL +#: LABEL/ID_PROCESS_DELETE_LABEL +msgid "Do you want to delete the selected process?" +msgstr "Do you want to delete the selected process?" + +# TRANSLATION +# LABEL/ID_PROCESS_DELETE_ALL_LABEL +#: LABEL/ID_PROCESS_DELETE_ALL_LABEL +msgid "Do you want to delete all selected processes?" +msgstr "Do you want to delete all selected processes?" + +# TRANSLATION +# LABEL/ID_PROCESS_CANT_DELETE +#: LABEL/ID_PROCESS_CANT_DELETE +msgid "You can't delete the process \"{0}\" because has {1} cases." +msgstr "You can't delete the process \"{0}\" because has {1} cases." + +# TRANSLATION +# LABEL/ID_FILE +#: LABEL/ID_FILE +msgid "[LABEL/ID_FILE] File" +msgstr "File" + +# TRANSLATION +# LABEL/ID_OUT_PUT_DOC_UPLOAD_TITLE +#: LABEL/ID_OUT_PUT_DOC_UPLOAD_TITLE +msgid "Upload Output Document Template File" +msgstr "Upload Output Document Template File" + +# TRANSLATION +# LABEL/ID_UPLOADING_FILE +#: LABEL/ID_UPLOADING_FILE +msgid "Uploading file..." +msgstr "Uploading file..." + +# TRANSLATION +# JAVASCRIPT/ID_CLASS_TABLE_DOESNT_EXIST +#: JAVASCRIPT/ID_CLASS_TABLE_DOESNT_EXIST +msgid "This table class does not exist" +msgstr "This table class does not exist" + +# TRANSLATION +# LABEL/ID_LOAD_FROM_FILE +#: LABEL/ID_LOAD_FROM_FILE +msgid "Load from file" +msgstr "Load from file" + +# TRANSLATION +# LABEL/ID_SELECT_TEMPLATE_FILE +#: LABEL/ID_SELECT_TEMPLATE_FILE +msgid "Select a template file" +msgstr "Select a template file" + +# TRANSLATION +# LABEL/ID_CASES_DATE_MASK +#: LABEL/ID_CASES_DATE_MASK +msgid "[LABEL/ID_CASES_DATE_MASK] Date Format" +msgstr "Date Format" + +# TRANSLATION +# LABEL/ID_CASES_ROW_NUMBER +#: LABEL/ID_CASES_ROW_NUMBER +msgid "Number of Rows per Page" +msgstr "Number of Rows per Page" + +# TRANSLATION +# LABEL/ID_GLOBAL_DATE_FORMAT +#: LABEL/ID_GLOBAL_DATE_FORMAT +msgid "Global Date Format" +msgstr "Global Date Format" + +# TRANSLATION +# LABEL/ID_PM_ENV_SETTINGS_CASESLIST_TITLE +#: LABEL/ID_PM_ENV_SETTINGS_CASESLIST_TITLE +msgid "Cases Lists Settings" +msgstr "Cases Lists Settings" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_1 +#: LABEL/ID_DATE_FORMAT_1 +msgid "Y-m-d H:i:s .... (2010-11-17 10:25:07)" +msgstr " Y-m-d H:i:s .... (2010-11-17 10:25:07)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_2 +#: LABEL/ID_DATE_FORMAT_2 +msgid "d/m/Y .... (17/11/2010)" +msgstr " d/m/Y .... (17/11/2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_3 +#: LABEL/ID_DATE_FORMAT_3 +msgid "m/d/Y .... (11/17/2010)" +msgstr " m/d/Y .... (11/17/2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_4 +#: LABEL/ID_DATE_FORMAT_4 +msgid "Y/d/m .... (2010/17/11)" +msgstr " Y/d/m .... (2010/17/11)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_5 +#: LABEL/ID_DATE_FORMAT_5 +msgid "Y/m/d .... (2010/11/17)" +msgstr " Y/m/d .... (2010/11/17)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_6 +#: LABEL/ID_DATE_FORMAT_6 +msgid "F j, Y, g:i a ....(November 17, 2010, 10:45 am)" +msgstr " F j, Y, g:i a ....(November 17, 2010, 10:45 am)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_7 +#: LABEL/ID_DATE_FORMAT_7 +msgid "m.d.y .... (11.17.10)" +msgstr " m.d.y .... (11.17.10)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_8 +#: LABEL/ID_DATE_FORMAT_8 +msgid "j, n, Y .... (17,11,2010)" +msgstr " j, n, Y .... (17,11,2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_9 +#: LABEL/ID_DATE_FORMAT_9 +msgid "D M j G:i:s T Y .... (Thu Nov 17 10:48:18 BOT 2010)" +msgstr " D M j G:i:s T Y .... (Thu Nov 17 10:48:18 BOT 2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_10 +#: LABEL/ID_DATE_FORMAT_10 +msgid "D d M, Y .... (Thu 17 Nov, 2010)" +msgstr " D d M, Y .... (Thu 17 Nov, 2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_11 +#: LABEL/ID_DATE_FORMAT_11 +msgid "D M, Y .... (Thu Nov, 2010)" +msgstr " D M, Y .... (Thu Nov, 2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_12 +#: LABEL/ID_DATE_FORMAT_12 +msgid "d M, Y .... (17 Nov, 2010)" +msgstr " d M, Y .... (17 Nov, 2010)" + +# TRANSLATION +# LABEL/ID_DATE_FORMAT_13 +#: LABEL/ID_DATE_FORMAT_13 +msgid "d m, Y .... (17 11, 2010)" +msgstr " d m, Y .... (17 11, 2010)" + +# TRANSLATION +# LABEL/ID_STEP_LIST +#: LABEL/ID_STEP_LIST +msgid "Step List" +msgstr "Step List" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_1 +#: LABEL/ID_USERNAME_FORMAT_1 +msgid "@firstName @lastName .... (John Cooper)" +msgstr " @firstName @lastName .... (John Cooper)" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_2 +#: LABEL/ID_USERNAME_FORMAT_2 +msgid "@firstName @lastName (@userName) .... (John Cooper (JohnLCooper))" +msgstr " @firstName @lastName (@userName) .... (John Cooper (JohnLCooper))" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_3 +#: LABEL/ID_USERNAME_FORMAT_3 +msgid "@userName .... (JohnLCooper)" +msgstr " @userName .... (JohnLCooper)" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_4 +#: LABEL/ID_USERNAME_FORMAT_4 +msgid "@userName (@firstName @lastName) .... (JohnLCooper (John Cooper))" +msgstr " @userName (@firstName @lastName) .... (JohnLCooper (John Cooper))" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_5 +#: LABEL/ID_USERNAME_FORMAT_5 +msgid "@lastName @firstName .... (Cooper John)" +msgstr " @lastName @firstName .... (Cooper John)" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_6 +#: LABEL/ID_USERNAME_FORMAT_6 +msgid "@lastName, @firstName .... (Cooper, John)" +msgstr " @lastName, @firstName .... (Cooper, John)" + +# TRANSLATION +# LABEL/ID_USERNAME_FORMAT_7 +#: LABEL/ID_USERNAME_FORMAT_7 +msgid "@lastName, @firstName (@userName) .... (Cooper, John (JohnLCooper))" +msgstr " @lastName, @firstName (@userName) .... (Cooper, John (JohnLCooper))" + +# TRANSLATION +# LABEL/ID_EMPTY_USERS +#: LABEL/ID_EMPTY_USERS +msgid "Select a User..." +msgstr "Select a User..." + +# TRANSLATION +# LABEL/ID_DUPLICATE_CATEGORY_NAME +#: LABEL/ID_DUPLICATE_CATEGORY_NAME +msgid "[LABEL/ID_DUPLICATE_CATEGORY_NAME] Duplicate category name." +msgstr "Duplicate category name." + +# TRANSLATION +# LABEL/ID_INVALID_FILE +#: LABEL/ID_INVALID_FILE +msgid "Invalid FIle" +msgstr "Invalid FIle" + +# TRANSLATION +# LABEL/ID_CONFIGURE +#: LABEL/ID_CONFIGURE +msgid "Configure" +msgstr "Configure" + +# TRANSLATION +# LABEL/ID_VERSION +#: LABEL/ID_VERSION +msgid "[LABEL/ID_VERSION] Version" +msgstr "Version" + +# additionalTables/additionalTablesData.xml?ADD_TAB_NAME +# additionalTables/additionalTablesData.xml +#: text - ADD_TAB_NAME +msgid "[additionalTables/additionalTablesData.xml?ADD_TAB_NAME] Name" +msgstr "Name" + +# additionalTables/additionalTablesData.xml?ADD_TAB_DESCRIPTION +# additionalTables/additionalTablesData.xml +#: text - ADD_TAB_DESCRIPTION +msgid "[additionalTables/additionalTablesData.xml?ADD_TAB_DESCRIPTION] Description" +msgstr "Description" + +# additionalTables/additionalTablesData.xml?EDIT +# additionalTables/additionalTablesData.xml +#: link - EDIT +msgid "" +msgstr "" + +# additionalTables/additionalTablesData.xml?DATA +# additionalTables/additionalTablesData.xml +#: link - DATA +msgid "[additionalTables/additionalTablesData.xml?DATA]" +msgstr "" + +# additionalTables/additionalTablesData.xml?DELETE +# additionalTables/additionalTablesData.xml +#: link - DELETE +msgid "[additionalTables/additionalTablesData.xml?DELETE]" +msgstr "" + +# additionalTables/additionalTablesDataImportForm.xml?TITLE +# additionalTables/additionalTablesDataImportForm.xml +#: title - TITLE +msgid "Import Data from CSV file" +msgstr "Import Data from CSV file" + +# additionalTables/additionalTablesDataImportForm.xml?CSV_FILE +# additionalTables/additionalTablesDataImportForm.xml +#: file - CSV_FILE +msgid "CSV File" +msgstr "CSV File" + +# additionalTables/additionalTablesDataImportForm.xml?CSV_DELIMITER +# additionalTables/additionalTablesDataImportForm.xml +#: dropdown - CSV_DELIMITER +msgid "Delimited by" +msgstr "Delimited by" + +# additionalTables/additionalTablesDataImportForm.xml?CSV_DELIMITER-; +# additionalTables/additionalTablesDataImportForm.xml +#: dropdown - CSV_DELIMITER - ; +msgid "[additionalTables/additionalTablesDataImportForm.xml?CSV_DELIMITER-;]" +msgstr "SemiColon (;)" + +# additionalTables/additionalTablesDataImportForm.xml?CSV_DELIMITER-, +# additionalTables/additionalTablesDataImportForm.xml +#: dropdown - CSV_DELIMITER - , +msgid "[additionalTables/additionalTablesDataImportForm.xml?CSV_DELIMITER-,]" +msgstr "Comma (,)" + +# additionalTables/additionalTablesDataImportForm.xml?btnSave +# additionalTables/additionalTablesDataImportForm.xml +#: submit - btnSave +msgid "[additionalTables/additionalTablesDataImportForm.xml?btnSave] Save" +msgstr "Save" + +# additionalTables/additionalTablesDataImportForm.xml?BTN_CANCEL +# additionalTables/additionalTablesDataImportForm.xml +#: button - BTN_CANCEL +msgid "[additionalTables/additionalTablesDataImportForm.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# additionalTables/additionalTablesEdit.xml?TITLE1 +# additionalTables/additionalTablesEdit.xml +#: title - TITLE1 +msgid "Table Information" +msgstr "Table Information" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_NAME +# additionalTables/additionalTablesEdit.xml +#: text - ADD_TAB_NAME +msgid "Table Name" +msgstr "Table Name" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_DESCRIPTION +# additionalTables/additionalTablesEdit.xml +#: textarea - ADD_TAB_DESCRIPTION +msgid "[additionalTables/additionalTablesEdit.xml?ADD_TAB_DESCRIPTION] Description" +msgstr "Description" + +# additionalTables/additionalTablesEdit.xml?TITLE2 +# additionalTables/additionalTablesEdit.xml +#: title - TITLE2 +msgid "Log Configuration" +msgstr "Log Configuration" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_SDW_LOG_INSERT +# additionalTables/additionalTablesEdit.xml +#: checkbox - ADD_TAB_SDW_LOG_INSERT +msgid "Save log for insert actions" +msgstr "Save log for insert actions" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_SDW_LOG_UPDATE +# additionalTables/additionalTablesEdit.xml +#: checkbox - ADD_TAB_SDW_LOG_UPDATE +msgid "Save log for update actions" +msgstr "Save log for update actions" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_SDW_LOG_DELETE +# additionalTables/additionalTablesEdit.xml +#: checkbox - ADD_TAB_SDW_LOG_DELETE +msgid "Save log for delete actions" +msgstr "Save log for delete actions" + +# additionalTables/additionalTablesEdit.xml?ADD_TAB_SDW_AUTO_DELETE +# additionalTables/additionalTablesEdit.xml +#: checkbox - ADD_TAB_SDW_AUTO_DELETE +msgid "Delete related log when table is deleted" +msgstr "Delete related log when table is deleted" + +# additionalTables/additionalTablesEdit.xml?TITLE3 +# additionalTables/additionalTablesEdit.xml +#: title - TITLE3 +msgid "Fields" +msgstr "Fields" + +# additionalTables/additionalTablesEdit.xml?btnSave +# additionalTables/additionalTablesEdit.xml +#: button - btnSave +msgid "[additionalTables/additionalTablesEdit.xml?btnSave] Save" +msgstr "Save" + +# additionalTables/additionalTablesEdit.xml?BTN_CANCEL +# additionalTables/additionalTablesEdit.xml +#: button - BTN_CANCEL +msgid "[additionalTables/additionalTablesEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# additionalTables/additionalTablesExportList.xml?ADD_TAB_UID +# additionalTables/additionalTablesExportList.xml +#: checkboxtable - ADD_TAB_UID +msgid "[additionalTables/additionalTablesExportList.xml?ADD_TAB_UID]" +msgstr "" + +# additionalTables/additionalTablesExportList.xml?ADD_TAB_NAME +# additionalTables/additionalTablesExportList.xml +#: text - ADD_TAB_NAME +msgid "[additionalTables/additionalTablesExportList.xml?ADD_TAB_NAME] Name" +msgstr "Name" + +# additionalTables/additionalTablesExportList.xml?ADD_TAB_DESCRIPTION +# additionalTables/additionalTablesExportList.xml +#: text - ADD_TAB_DESCRIPTION +msgid "[additionalTables/additionalTablesExportList.xml?ADD_TAB_DESCRIPTION] Description" +msgstr "Description" + +# additionalTables/additionalTablesExportList.xml?ADD_SCHEMA +# additionalTables/additionalTablesExportList.xml +#: checkboxpt - ADD_SCHEMA +msgid "Schema " +msgstr "Schema " + +# additionalTables/additionalTablesExportList.xml?ADD_DATA +# additionalTables/additionalTablesExportList.xml +#: checkboxpt - ADD_DATA +msgid "Data " +msgstr "Data " + +# additionalTables/additionalTablesFields.xml?FLD_UID +# additionalTables/additionalTablesFields.xml +#: text - FLD_UID +msgid "[additionalTables/additionalTablesFields.xml?FLD_UID]" +msgstr "" + +# additionalTables/additionalTablesFields.xml?FLD_NAME +# additionalTables/additionalTablesFields.xml +#: text - FLD_NAME +msgid "[additionalTables/additionalTablesFields.xml?FLD_NAME] Field Name" +msgstr "Field Name" + +# additionalTables/additionalTablesFields.xml?FLD_DESCRIPTION +# additionalTables/additionalTablesFields.xml +#: text - FLD_DESCRIPTION +msgid "Field Label" +msgstr "Field Label" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE] Type" +msgstr "Type" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE-VARCHAR +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE - VARCHAR +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE-VARCHAR]" +msgstr "VARCHAR" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE-TEXT +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE - TEXT +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE-TEXT]" +msgstr "TEXT" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE-DATE +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE - DATE +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE-DATE]" +msgstr "DATE" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE-INT +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE - INT +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE-INT]" +msgstr "INT" + +# additionalTables/additionalTablesFields.xml?FLD_TYPE-FLOAT +# additionalTables/additionalTablesFields.xml +#: dropdown - FLD_TYPE - FLOAT +msgid "[additionalTables/additionalTablesFields.xml?FLD_TYPE-FLOAT]" +msgstr "FLOAT" + +# additionalTables/additionalTablesFields.xml?FLD_SIZE +# additionalTables/additionalTablesFields.xml +#: text - FLD_SIZE +msgid "Size" +msgstr "Size" + +# additionalTables/additionalTablesFields.xml?FLD_NULL +# additionalTables/additionalTablesFields.xml +#: checkbox - FLD_NULL +msgid "Null" +msgstr "Null" + +# additionalTables/additionalTablesFields.xml?FLD_KEY +# additionalTables/additionalTablesFields.xml +#: checkbox - FLD_KEY +msgid "Primary Key" +msgstr "Primary Key" + +# additionalTables/additionalTablesFields2.xml?FLD_UID +# additionalTables/additionalTablesFields2.xml +#: text - FLD_UID +msgid "[additionalTables/additionalTablesFields2.xml?FLD_UID]" +msgstr "" + +# additionalTables/additionalTablesFields2.xml?FLD_NAME +# additionalTables/additionalTablesFields2.xml +#: text - FLD_NAME +msgid "[additionalTables/additionalTablesFields2.xml?FLD_NAME] Field Name" +msgstr "Field Name" + +# additionalTables/additionalTablesFields2.xml?FLD_DESCRIPTION +# additionalTables/additionalTablesFields2.xml +#: text - FLD_DESCRIPTION +msgid "[additionalTables/additionalTablesFields2.xml?FLD_DESCRIPTION] Field Label" +msgstr "Field Label" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE] Type" +msgstr "Type" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE-VARCHAR +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE - VARCHAR +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE-VARCHAR]" +msgstr "VARCHAR" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE-TEXT +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE - TEXT +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE-TEXT]" +msgstr "TEXT" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE-DATE +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE - DATE +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE-DATE]" +msgstr "DATE" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE-INT +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE - INT +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE-INT]" +msgstr "INT" + +# additionalTables/additionalTablesFields2.xml?FLD_TYPE-FLOAT +# additionalTables/additionalTablesFields2.xml +#: dropdown - FLD_TYPE - FLOAT +msgid "[additionalTables/additionalTablesFields2.xml?FLD_TYPE-FLOAT]" +msgstr "FLOAT" + +# additionalTables/additionalTablesFields2.xml?FLD_SIZE +# additionalTables/additionalTablesFields2.xml +#: text - FLD_SIZE +msgid "[additionalTables/additionalTablesFields2.xml?FLD_SIZE] Size" +msgstr "Size" + +# additionalTables/additionalTablesFields2.xml?FLD_NULL +# additionalTables/additionalTablesFields2.xml +#: checkbox - FLD_NULL +msgid "[additionalTables/additionalTablesFields2.xml?FLD_NULL] Null" +msgstr "Null" + +# additionalTables/additionalTablesFields2.xml?FLD_KEY +# additionalTables/additionalTablesFields2.xml +#: checkbox - FLD_KEY +msgid "[additionalTables/additionalTablesFields2.xml?FLD_KEY] Primary Key" +msgstr "Primary Key" + +# additionalTables/additionalTablesFields2.xml?FLD_UP_LINK +# additionalTables/additionalTablesFields2.xml +#: link - FLD_UP_LINK +msgid "[additionalTables/additionalTablesFields2.xml?FLD_UP_LINK]" +msgstr "" + +# additionalTables/additionalTablesFields2.xml?FLD_DOWN_LINK +# additionalTables/additionalTablesFields2.xml +#: link - FLD_DOWN_LINK +msgid "[additionalTables/additionalTablesFields2.xml?FLD_DOWN_LINK]" +msgstr "" + +# additionalTables/additionalTablesList.xml?ADD_TAB_NAME +# additionalTables/additionalTablesList.xml +#: text - ADD_TAB_NAME +msgid "[additionalTables/additionalTablesList.xml?ADD_TAB_NAME] Name" +msgstr "Name" + +# additionalTables/additionalTablesList.xml?ADD_TAB_DESCRIPTION +# additionalTables/additionalTablesList.xml +#: text - ADD_TAB_DESCRIPTION +msgid "[additionalTables/additionalTablesList.xml?ADD_TAB_DESCRIPTION] Description" +msgstr "Description" + +# additionalTables/additionalTablesList.xml?EDIT +# additionalTables/additionalTablesList.xml +#: link - EDIT +msgid "[additionalTables/additionalTablesList.xml?EDIT]" +msgstr "" + +# additionalTables/additionalTablesList.xml?DATA +# additionalTables/additionalTablesList.xml +#: link - DATA +msgid "[additionalTables/additionalTablesList.xml?DATA]" +msgstr "" + +# additionalTables/additionalTablesList.xml?DELETE +# additionalTables/additionalTablesList.xml +#: link - DELETE +msgid "[additionalTables/additionalTablesList.xml?DELETE]" +msgstr "" + +# additionalTables/additionalTablesNew.xml?TITLE1 +# additionalTables/additionalTablesNew.xml +#: title - TITLE1 +msgid "[additionalTables/additionalTablesNew.xml?TITLE1] Table Information" +msgstr "Table Information" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_NAME +# additionalTables/additionalTablesNew.xml +#: text - ADD_TAB_NAME +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_NAME] Table Name" +msgstr "Table Name" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_DESCRIPTION +# additionalTables/additionalTablesNew.xml +#: textarea - ADD_TAB_DESCRIPTION +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_DESCRIPTION] Description" +msgstr "Description" + +# additionalTables/additionalTablesNew.xml?TITLE2 +# additionalTables/additionalTablesNew.xml +#: title - TITLE2 +msgid "Log configuration" +msgstr "Log configuration" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_INSERT +# additionalTables/additionalTablesNew.xml +#: checkbox - ADD_TAB_SDW_LOG_INSERT +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_INSERT] Save log for insert actions" +msgstr "Save log for insert actions" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_UPDATE +# additionalTables/additionalTablesNew.xml +#: checkbox - ADD_TAB_SDW_LOG_UPDATE +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_UPDATE] Save log for update actions" +msgstr "Save log for update actions" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_DELETE +# additionalTables/additionalTablesNew.xml +#: checkbox - ADD_TAB_SDW_LOG_DELETE +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_LOG_DELETE] Save log for delete actions" +msgstr "Save log for delete actions" + +# additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_AUTO_DELETE +# additionalTables/additionalTablesNew.xml +#: checkbox - ADD_TAB_SDW_AUTO_DELETE +msgid "[additionalTables/additionalTablesNew.xml?ADD_TAB_SDW_AUTO_DELETE] Delete related log when table is deleted" +msgstr "Delete related log when table is deleted" + +# additionalTables/additionalTablesNew.xml?TITLE3 +# additionalTables/additionalTablesNew.xml +#: title - TITLE3 +msgid "[additionalTables/additionalTablesNew.xml?TITLE3] Fields" +msgstr "Fields" + +# additionalTables/additionalTablesNew.xml?btnSave +# additionalTables/additionalTablesNew.xml +#: button - btnSave +msgid "[additionalTables/additionalTablesNew.xml?btnSave] Save" +msgstr "Save" + +# additionalTables/additionalTablesNew.xml?BTN_CANCEL +# additionalTables/additionalTablesNew.xml +#: button - BTN_CANCEL +msgid "[additionalTables/additionalTablesNew.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# additionalTables/additionalTablesOptions.xml?MNU_ADD +# additionalTables/additionalTablesOptions.xml +#: link - MNU_ADD +msgid "[additionalTables/additionalTablesOptions.xml?MNU_ADD] New" +msgstr "New" + +# additionalTables/additionalTablesOptions.xml?MNU_IMPORT +# additionalTables/additionalTablesOptions.xml +#: link - MNU_IMPORT +msgid "[additionalTables/additionalTablesOptions.xml?MNU_IMPORT] Import" +msgstr "Import" + +# additionalTables/additionalTablesOptions.xml?MNU_EXPORT +# additionalTables/additionalTablesOptions.xml +#: link - MNU_EXPORT +msgid "[additionalTables/additionalTablesOptions.xml?MNU_EXPORT] Export" +msgstr "Export" + +# additionalTables/additionalTablesTitle.xml?TITLE +# additionalTables/additionalTablesTitle.xml +#: title - TITLE +msgid "@#ADD_TAB_NAME" +msgstr "@#ADD_TAB_NAME" + +# additionalTables/additionalTablesToImport.xml?TITLE1 +# additionalTables/additionalTablesToImport.xml +#: title - TITLE1 +msgid "Import PMTables" +msgstr "Import PMTables" + +# additionalTables/additionalTablesToImport.xml?MAX_FILE_SIZE +# additionalTables/additionalTablesToImport.xml +#: edit - MAX_FILE_SIZE +msgid "Max upload file size in bytes" +msgstr "Max upload file size in bytes" + +# additionalTables/additionalTablesToImport.xml?FILENAME +# additionalTables/additionalTablesToImport.xml +#: file - FILENAME +msgid "[additionalTables/additionalTablesToImport.xml?FILENAME] File" +msgstr "File" + +# additionalTables/additionalTablesToImport.xml?OVERWRITE +# additionalTables/additionalTablesToImport.xml +#: checkbox - OVERWRITE +msgid "Overwrite if exists" +msgstr "Overwrite if exists" + +# additionalTables/additionalTablesToImport.xml?SAVE +# additionalTables/additionalTablesToImport.xml +#: button - SAVE +msgid "[additionalTables/additionalTablesToImport.xml?SAVE] Import" +msgstr "Import" + +# additionalTables/additionalTablesToImport.xml?BTN_CANCEL +# additionalTables/additionalTablesToImport.xml +#: button - BTN_CANCEL +msgid "[additionalTables/additionalTablesToImport.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# additionalTables/doExport.xml?TITLE +# additionalTables/doExport.xml +#: title - TITLE +msgid "Processmaker Tables export" +msgstr "Processmaker Tables export" + +# additionalTables/doExport.xml?FILENAME_LABEL +# additionalTables/doExport.xml +#: link - FILENAME_LABEL +msgid "[additionalTables/doExport.xml?FILENAME_LABEL] File" +msgstr "File" + +# additionalTables/doExport.xml?SIZE +# additionalTables/doExport.xml +#: caption - SIZE +msgid "File size" +msgstr "File size" + +# additionalTables/doExport.xml?META +# additionalTables/doExport.xml +#: caption - META +msgid "Sumary" +msgstr "Sumary" + +# appFolder/appFolder.xml?title1 +# appFolder/appFolder.xml +#: title - title1 +msgid "AppFolder form" +msgstr "AppFolder form" + +# appFolder/appFolder.xml?FOLDER_UID +# appFolder/appFolder.xml +#: text - FOLDER_UID +msgid "Er Uid" +msgstr "Er Uid" + +# appFolder/appFolder.xml?FOLDER_PARENT_UID +# appFolder/appFolder.xml +#: text - FOLDER_PARENT_UID +msgid "Er Parent Uid" +msgstr "Er Parent Uid" + +# appFolder/appFolder.xml?FOLDER_NAME +# appFolder/appFolder.xml +#: textarea - FOLDER_NAME +msgid "Er Name" +msgstr "Er Name" + +# appFolder/appFolder.xml?FOLDER_CREATE_DATE +# appFolder/appFolder.xml +#: date - FOLDER_CREATE_DATE +msgid "Er Create Date" +msgstr "Er Create Date" + +# appFolder/appFolder.xml?FOLDER_UPDATE_DATE +# appFolder/appFolder.xml +#: date - FOLDER_UPDATE_DATE +msgid "Er Update Date" +msgstr "Er Update Date" + +# appFolder/appFolder.xml?BTN_SUBMIT +# appFolder/appFolder.xml +#: submit - BTN_SUBMIT +msgid "save" +msgstr "save" + +# appFolder/appFolderDelete.xml?title1 +# appFolder/appFolderDelete.xml +#: title - title1 +msgid "Delete AppFolder" +msgstr "Delete AppFolder" + +# appFolder/appFolderDelete.xml?LABEL_FOLDER_UID +# appFolder/appFolderDelete.xml +#: caption - LABEL_FOLDER_UID +msgid "[appFolder/appFolderDelete.xml?LABEL_FOLDER_UID] Er Uid" +msgstr "Er Uid" + +# appFolder/appFolderDelete.xml?BTN_SUBMIT +# appFolder/appFolderDelete.xml +#: submit - BTN_SUBMIT +msgid "delete" +msgstr "delete" + +# appFolder/appFolderDocsListOptions.xml?MNU_NEW +# appFolder/appFolderDocsListOptions.xml +#: link - MNU_NEW +msgid "@#labelFolderAddFolder" +msgstr "@#labelFolderAddFolder" + +# appFolder/appFolderDocsListOptions.xml?MNU_NEW1 +# appFolder/appFolderDocsListOptions.xml +#: link - MNU_NEW1 +msgid "@#labelFolderAddFile" +msgstr "@#labelFolderAddFile" + +# appFolder/appFolderDocsListOptions.xml?PAGED_TABLE_FAST_SEARCH +# appFolder/appFolderDocsListOptions.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[appFolder/appFolderDocsListOptions.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# appFolder/appFolderDocsListSearchOptions.xml?PAGED_TABLE_FAST_SEARCH +# appFolder/appFolderDocsListSearchOptions.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[appFolder/appFolderDocsListSearchOptions.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# appFolder/appFolderDocumentInfo.xml?PRO_TITLE +# appFolder/appFolderDocumentInfo.xml +#: caption - PRO_TITLE +msgid "[appFolder/appFolderDocumentInfo.xml?PRO_TITLE] Process" +msgstr "Process" + +# appFolder/appFolderDocumentInfo.xml?APP_TITLE +# appFolder/appFolderDocumentInfo.xml +#: caption - APP_TITLE +msgid "Case Title" +msgstr "Case Title" + +# appFolder/appFolderDocumentInfo.xml?APP_DOC_FILENAME +# appFolder/appFolderDocumentInfo.xml +#: caption - APP_DOC_FILENAME +msgid "File Name" +msgstr "File Name" + +# appFolder/appFolderDocumentInfo.xml?DOC_VERSION +# appFolder/appFolderDocumentInfo.xml +#: caption - DOC_VERSION +msgid "[appFolder/appFolderDocumentInfo.xml?DOC_VERSION] Version" +msgstr "Version" + +# appFolder/appFolderDocumentInfo.xml?APP_DOC_TYPE +# appFolder/appFolderDocumentInfo.xml +#: caption - APP_DOC_TYPE +msgid "[appFolder/appFolderDocumentInfo.xml?APP_DOC_TYPE] Type" +msgstr "Type" + +# appFolder/appFolderDocumentInfo.xml?USR_USERNAME +# appFolder/appFolderDocumentInfo.xml +#: caption - USR_USERNAME +msgid "Creator" +msgstr "Creator" + +# appFolder/appFolderDocumentInfo.xml?APP_DOC_CREATE_DATE +# appFolder/appFolderDocumentInfo.xml +#: caption - APP_DOC_CREATE_DATE +msgid "Created" +msgstr "Created" + +# appFolder/appFolderDocumentList.xml?APP_DOC_FILENAME +# appFolder/appFolderDocumentList.xml +#: text - APP_DOC_FILENAME +msgid "[appFolder/appFolderDocumentList.xml?APP_DOC_FILENAME] File Name" +msgstr "File Name" + +# appFolder/appFolderDocumentList.xml?DOC_VERSION +# appFolder/appFolderDocumentList.xml +#: text - DOC_VERSION +msgid "[appFolder/appFolderDocumentList.xml?DOC_VERSION] Version" +msgstr "Version" + +# appFolder/appFolderDocumentList.xml?USR_USERNAME +# appFolder/appFolderDocumentList.xml +#: text - USR_USERNAME +msgid "[appFolder/appFolderDocumentList.xml?USR_USERNAME] Creator" +msgstr "Creator" + +# appFolder/appFolderDocumentList.xml?APP_DOC_CREATE_DATE +# appFolder/appFolderDocumentList.xml +#: text - APP_DOC_CREATE_DATE +msgid "[appFolder/appFolderDocumentList.xml?APP_DOC_CREATE_DATE] Created" +msgstr "Created" + +# appFolder/appFolderDocumentList.xml?random +# appFolder/appFolderDocumentList.xml +#: text - random +msgid "[appFolder/appFolderDocumentList.xml?random]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?info +# appFolder/appFolderDocumentList.xml +#: link - info +msgid "[appFolder/appFolderDocumentList.xml?info]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?open +# appFolder/appFolderDocumentList.xml +#: link - open +msgid "[appFolder/appFolderDocumentList.xml?open]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?detefile +# appFolder/appFolderDocumentList.xml +#: link - detefile +msgid "[appFolder/appFolderDocumentList.xml?detefile]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?open1 +# appFolder/appFolderDocumentList.xml +#: link - open1 +msgid "[appFolder/appFolderDocumentList.xml?open1]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?newVersion +# appFolder/appFolderDocumentList.xml +#: link - newVersion +msgid "[appFolder/appFolderDocumentList.xml?newVersion]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?versionHistory +# appFolder/appFolderDocumentList.xml +#: link - versionHistory +msgid "[appFolder/appFolderDocumentList.xml?versionHistory]" +msgstr "" + +# appFolder/appFolderDocumentList.xml?APP_DOC_UID_VERSION +# appFolder/appFolderDocumentList.xml +#: checkboxtable - APP_DOC_UID_VERSION +msgid "[appFolder/appFolderDocumentList.xml?APP_DOC_UID_VERSION]" +msgstr "" + +# appFolder/appFolderDocumentListHeader.xml?FOLDER_UID +# appFolder/appFolderDocumentListHeader.xml +#: dropdown - FOLDER_UID +msgid "Move selected to:" +msgstr "Move selected to:" + +# appFolder/appFolderDocumentListHeader.xml?FOLDER_UID-'' +# appFolder/appFolderDocumentListHeader.xml +#: dropdown - FOLDER_UID - '' +msgid "[appFolder/appFolderDocumentListHeader.xml?FOLDER_UID-'']" +msgstr "" + +# appFolder/appFolderDocumentListHeader.xml?BTN_SUBMIT +# appFolder/appFolderDocumentListHeader.xml +#: submit - BTN_SUBMIT +msgid "Move" +msgstr "Move" + +# appFolder/appFolderDocumentListHistory.xml?APP_DOC_FILENAME +# appFolder/appFolderDocumentListHistory.xml +#: text - APP_DOC_FILENAME +msgid "[appFolder/appFolderDocumentListHistory.xml?APP_DOC_FILENAME] File Name" +msgstr "File Name" + +# appFolder/appFolderDocumentListHistory.xml?DOC_VERSION +# appFolder/appFolderDocumentListHistory.xml +#: text - DOC_VERSION +msgid "[appFolder/appFolderDocumentListHistory.xml?DOC_VERSION] Version" +msgstr "Version" + +# appFolder/appFolderDocumentListHistory.xml?USR_USERNAME +# appFolder/appFolderDocumentListHistory.xml +#: text - USR_USERNAME +msgid "[appFolder/appFolderDocumentListHistory.xml?USR_USERNAME] Creator" +msgstr "Creator" + +# appFolder/appFolderDocumentListHistory.xml?APP_DOC_CREATE_DATE +# appFolder/appFolderDocumentListHistory.xml +#: text - APP_DOC_CREATE_DATE +msgid "[appFolder/appFolderDocumentListHistory.xml?APP_DOC_CREATE_DATE] Created" +msgstr "Created" + +# appFolder/appFolderDocumentListHistory.xml?random +# appFolder/appFolderDocumentListHistory.xml +#: text - random +msgid "[appFolder/appFolderDocumentListHistory.xml?random]" +msgstr "" + +# appFolder/appFolderDocumentListHistory.xml?info +# appFolder/appFolderDocumentListHistory.xml +#: link - info +msgid "[appFolder/appFolderDocumentListHistory.xml?info]" +msgstr "" + +# appFolder/appFolderDocumentListHistory.xml?open +# appFolder/appFolderDocumentListHistory.xml +#: link - open +msgid "[appFolder/appFolderDocumentListHistory.xml?open]" +msgstr "" + +# appFolder/appFolderDocumentListHistory.xml?open1 +# appFolder/appFolderDocumentListHistory.xml +#: link - open1 +msgid "[appFolder/appFolderDocumentListHistory.xml?open1]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?APP_DOC_FILENAME +# appFolder/appFolderDocumentListSearch.xml +#: text - APP_DOC_FILENAME +msgid "[appFolder/appFolderDocumentListSearch.xml?APP_DOC_FILENAME] File Name" +msgstr "File Name" + +# appFolder/appFolderDocumentListSearch.xml?DOC_VERSION +# appFolder/appFolderDocumentListSearch.xml +#: text - DOC_VERSION +msgid "[appFolder/appFolderDocumentListSearch.xml?DOC_VERSION] Version" +msgstr "Version" + +# appFolder/appFolderDocumentListSearch.xml?USR_USERNAME +# appFolder/appFolderDocumentListSearch.xml +#: text - USR_USERNAME +msgid "[appFolder/appFolderDocumentListSearch.xml?USR_USERNAME] Creator" +msgstr "Creator" + +# appFolder/appFolderDocumentListSearch.xml?APP_DOC_CREATE_DATE +# appFolder/appFolderDocumentListSearch.xml +#: text - APP_DOC_CREATE_DATE +msgid "[appFolder/appFolderDocumentListSearch.xml?APP_DOC_CREATE_DATE] Created" +msgstr "Created" + +# appFolder/appFolderDocumentListSearch.xml?random +# appFolder/appFolderDocumentListSearch.xml +#: text - random +msgid "[appFolder/appFolderDocumentListSearch.xml?random]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?info +# appFolder/appFolderDocumentListSearch.xml +#: link - info +msgid "[appFolder/appFolderDocumentListSearch.xml?info]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?open +# appFolder/appFolderDocumentListSearch.xml +#: link - open +msgid "[appFolder/appFolderDocumentListSearch.xml?open]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?open1 +# appFolder/appFolderDocumentListSearch.xml +#: link - open1 +msgid "[appFolder/appFolderDocumentListSearch.xml?open1]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?newVersion +# appFolder/appFolderDocumentListSearch.xml +#: link - newVersion +msgid "[appFolder/appFolderDocumentListSearch.xml?newVersion]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?versionHistory +# appFolder/appFolderDocumentListSearch.xml +#: link - versionHistory +msgid "[appFolder/appFolderDocumentListSearch.xml?versionHistory]" +msgstr "" + +# appFolder/appFolderDocumentListSearch.xml?APP_DOC_UID_VERSION +# appFolder/appFolderDocumentListSearch.xml +#: checkboxtable - APP_DOC_UID_VERSION +msgid "[appFolder/appFolderDocumentListSearch.xml?APP_DOC_UID_VERSION]" +msgstr "" + +# appFolder/appFolderEdit.xml?title1 +# appFolder/appFolderEdit.xml +#: title - title1 +msgid "[appFolder/appFolderEdit.xml?title1] New Folder" +msgstr "New Folder" + +# appFolder/appFolderEdit.xml?FOLDER_PATH +# appFolder/appFolderEdit.xml +#: caption - FOLDER_PATH +msgid "Path" +msgstr "Path" + +# appFolder/appFolderEdit.xml?FOLDER_NAME +# appFolder/appFolderEdit.xml +#: text - FOLDER_NAME +msgid "Folder Name" +msgstr "Folder Name" + +# appFolder/appFolderEdit.xml?BTN_CANCEL +# appFolder/appFolderEdit.xml +#: button - BTN_CANCEL +msgid "[appFolder/appFolderEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# appFolder/appFolderEdit.xml?BTN_SUBMIT +# appFolder/appFolderEdit.xml +#: submit - BTN_SUBMIT +msgid "[appFolder/appFolderEdit.xml?BTN_SUBMIT] Save" +msgstr "Save" + +# appFolder/appFolderList.xml?FOLDER_PARENT_UID +# appFolder/appFolderList.xml +#: text - FOLDER_PARENT_UID +msgid "[appFolder/appFolderList.xml?FOLDER_PARENT_UID] Er Parent Uid" +msgstr "Er Parent Uid" + +# appFolder/appFolderList.xml?FOLDER_CREATE_DATE +# appFolder/appFolderList.xml +#: text - FOLDER_CREATE_DATE +msgid "[appFolder/appFolderList.xml?FOLDER_CREATE_DATE] Er Create Date" +msgstr "Er Create Date" + +# appFolder/appFolderList.xml?FOLDER_UPDATE_DATE +# appFolder/appFolderList.xml +#: text - FOLDER_UPDATE_DATE +msgid "[appFolder/appFolderList.xml?FOLDER_UPDATE_DATE] Er Update Date" +msgstr "Er Update Date" + +# appFolder/appFolderList.xml?LINK +# appFolder/appFolderList.xml +#: link - LINK +msgid "[appFolder/appFolderList.xml?LINK] Edit" +msgstr "Edit" + +# appFolder/appFolderList.xml?LINK2 +# appFolder/appFolderList.xml +#: link - LINK2 +msgid "[appFolder/appFolderList.xml?LINK2] Delete" +msgstr "Delete" + +# appFolder/appFolderOptions.xml?MNU_NEW +# appFolder/appFolderOptions.xml +#: link - MNU_NEW +msgid "[appFolder/appFolderOptions.xml?MNU_NEW] New" +msgstr "New" + +# authSources/authSources_List.xml?AUTH_SOURCE_NAME +# authSources/authSources_List.xml +#: text - AUTH_SOURCE_NAME +msgid "[authSources/authSources_List.xml?AUTH_SOURCE_NAME] Name" +msgstr "Name" + +# authSources/authSources_List.xml?AUTH_SOURCE_PROVIDER +# authSources/authSources_List.xml +#: text - AUTH_SOURCE_PROVIDER +msgid "Provider" +msgstr "Provider" + +# authSources/authSources_List.xml?AUTH_SOURCE_SERVER_NAME +# authSources/authSources_List.xml +#: text - AUTH_SOURCE_SERVER_NAME +msgid "Server Name" +msgstr "Server Name" + +# authSources/authSources_List.xml?AUTH_SOURCE_PORT +# authSources/authSources_List.xml +#: text - AUTH_SOURCE_PORT +msgid "Port" +msgstr "Port" + +# authSources/authSources_List.xml?EDIT +# authSources/authSources_List.xml +#: link - EDIT +msgid "[authSources/authSources_List.xml?EDIT]" +msgstr "" + +# authSources/authSources_List.xml?DELETE +# authSources/authSources_List.xml +#: link - DELETE +msgid "[authSources/authSources_List.xml?DELETE]" +msgstr "" + +# authSources/authSources_List.xml?IMPORT_USERS +# authSources/authSources_List.xml +#: link - IMPORT_USERS +msgid "[authSources/authSources_List.xml?IMPORT_USERS]" +msgstr "" + +# authSources/authSources_Options.xml?MNU_ADD +# authSources/authSources_Options.xml +#: link - MNU_ADD +msgid "[authSources/authSources_Options.xml?MNU_ADD] New" +msgstr "New" + +# authSources/authSources_SearchUsers.xml?TITLE +# authSources/authSources_SearchUsers.xml +#: title - TITLE +msgid "Search for user" +msgstr "Search for user" + +# authSources/authSources_SearchUsers.xml?KEYWORD +# authSources/authSources_SearchUsers.xml +#: text - KEYWORD +msgid "Keyword" +msgstr "Keyword" + +# authSources/authSources_SearchUsers.xml?btnSearch +# authSources/authSources_SearchUsers.xml +#: button - btnSearch +msgid "[authSources/authSources_SearchUsers.xml?btnSearch] Search" +msgstr "Search" + +# authSources/authSources_SearchUsers.xml?btnImport +# authSources/authSources_SearchUsers.xml +#: button - btnImport +msgid "[authSources/authSources_SearchUsers.xml?btnImport] Import" +msgstr "Import" + +# authSources/authSources_SearchUsers.xml?BTN_CANCEL +# authSources/authSources_SearchUsers.xml +#: button - BTN_CANCEL +msgid "[authSources/authSources_SearchUsers.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# authSources/authSources_SelectType.xml?TITLE +# authSources/authSources_SelectType.xml +#: title - TITLE +msgid "Available Authentication Source Types" +msgstr "Available Authentication Source Types" + +# authSources/authSources_SelectType.xml?AUTH_SOURCE_PROVIDER +# authSources/authSources_SelectType.xml +#: dropdown - AUTH_SOURCE_PROVIDER +msgid "[authSources/authSources_SelectType.xml?AUTH_SOURCE_PROVIDER] Provider" +msgstr "Provider" + +# authSources/authSources_SelectType.xml?btnContinue +# authSources/authSources_SelectType.xml +#: submit - btnContinue +msgid "[authSources/authSources_SelectType.xml?btnContinue] Continue" +msgstr "Continue" + +# authSources/authSources_SelectType.xml?BTN_CANCEL +# authSources/authSources_SelectType.xml +#: button - BTN_CANCEL +msgid "[authSources/authSources_SelectType.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# authSources/ldapEdit.xml?TITLE +# authSources/ldapEdit.xml +#: title - TITLE +msgid "Authentication Source Information" +msgstr "Authentication Source Information" + +# authSources/ldapEdit.xml?AUTH_SOURCE_NAME +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_NAME +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_NAME] Name" +msgstr "Name" + +# authSources/ldapEdit.xml?LDAP_TYPE +# authSources/ldapEdit.xml +#: dropdown - LDAP_TYPE +msgid "[authSources/ldapEdit.xml?LDAP_TYPE] Type" +msgstr "Type" + +# authSources/ldapEdit.xml?LDAP_TYPE-ldap +# authSources/ldapEdit.xml +#: dropdown - LDAP_TYPE - ldap +msgid "[authSources/ldapEdit.xml?LDAP_TYPE-ldap]" +msgstr "LDAP" + +# authSources/ldapEdit.xml?LDAP_TYPE-ad +# authSources/ldapEdit.xml +#: dropdown - LDAP_TYPE - ad +msgid "[authSources/ldapEdit.xml?LDAP_TYPE-ad]" +msgstr "Active Directory" + +# authSources/ldapEdit.xml?AUTH_SOURCE_SERVER_NAME +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_SERVER_NAME +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_SERVER_NAME] Server Name" +msgstr "Server Name" + +# authSources/ldapEdit.xml?AUTH_SOURCE_PORT +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_PORT +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_PORT] Port" +msgstr "Port" + +# authSources/ldapEdit.xml?AUTH_SOURCE_ENABLED_TLS +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_ENABLED_TLS +msgid "Enabled TLS" +msgstr "Enabled TLS" + +# authSources/ldapEdit.xml?AUTH_SOURCE_ENABLED_TLS-'' +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_ENABLED_TLS - '' +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_ENABLED_TLS-'']" +msgstr "No" + +# authSources/ldapEdit.xml?AUTH_SOURCE_ENABLED_TLS-1 +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_ENABLED_TLS - 1 +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_ENABLED_TLS-1]" +msgstr "Yes" + +# authSources/ldapEdit.xml?AUTH_SOURCE_VERSION +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_VERSION +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_VERSION] Version" +msgstr "Version" + +# authSources/ldapEdit.xml?AUTH_SOURCE_VERSION-2 +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_VERSION - 2 +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_VERSION-2]" +msgstr "2" + +# authSources/ldapEdit.xml?AUTH_SOURCE_VERSION-3 +# authSources/ldapEdit.xml +#: dropdown - AUTH_SOURCE_VERSION - 3 +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_VERSION-3]" +msgstr "3" + +# authSources/ldapEdit.xml?AUTH_SOURCE_BASE_DN +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_BASE_DN +msgid "Base DN" +msgstr "Base DN" + +# authSources/ldapEdit.xml?AUTH_ANONYMOUS +# authSources/ldapEdit.xml +#: dropdown - AUTH_ANONYMOUS +msgid "Anonymous" +msgstr "Anonymous" + +# authSources/ldapEdit.xml?AUTH_ANONYMOUS-'' +# authSources/ldapEdit.xml +#: dropdown - AUTH_ANONYMOUS - '' +msgid "[authSources/ldapEdit.xml?AUTH_ANONYMOUS-'']" +msgstr "No" + +# authSources/ldapEdit.xml?AUTH_ANONYMOUS-1 +# authSources/ldapEdit.xml +#: dropdown - AUTH_ANONYMOUS - 1 +msgid "[authSources/ldapEdit.xml?AUTH_ANONYMOUS-1]" +msgstr "Yes" + +# authSources/ldapEdit.xml?AUTH_SOURCE_SEARCH_USER +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_SEARCH_USER +msgid "Search User" +msgstr "Search User" + +# authSources/ldapEdit.xml?AUTH_SOURCE_PASSWORD +# authSources/ldapEdit.xml +#: password - AUTH_SOURCE_PASSWORD +msgid "[authSources/ldapEdit.xml?AUTH_SOURCE_PASSWORD] Password" +msgstr "Password" + +# authSources/ldapEdit.xml?AUTH_SOURCE_IDENTIFIER_FOR_USER +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_IDENTIFIER_FOR_USER +msgid "Identifier for a imported user" +msgstr "Identifier for a imported user" + +# authSources/ldapEdit.xml?AUTH_SOURCE_OBJECT_CLASSES +# authSources/ldapEdit.xml +#: textarea - AUTH_SOURCE_OBJECT_CLASSES +msgid "Object Classes" +msgstr "Object Classes" + +# authSources/ldapEdit.xml?AUTH_SOURCE_ADDITIONAL_FILTER +# authSources/ldapEdit.xml +#: text - AUTH_SOURCE_ADDITIONAL_FILTER +msgid "Additional Filter" +msgstr "Additional Filter" + +# authSources/ldapEdit.xml?AUTH_SOURCE_ATTRIBUTES +# authSources/ldapEdit.xml +#: textarea - AUTH_SOURCE_ATTRIBUTES +msgid "Attributes" +msgstr "Attributes" + +# authSources/ldapEdit.xml?btnSave +# authSources/ldapEdit.xml +#: submit - btnSave +msgid "[authSources/ldapEdit.xml?btnSave] Save" +msgstr "Save" + +# authSources/ldapEdit.xml?BTN_CANCEL +# authSources/ldapEdit.xml +#: button - BTN_CANCEL +msgid "[authSources/ldapEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# authSources/ldapSearchResults.xml?Checkbox +# authSources/ldapSearchResults.xml +#: text - Checkbox +msgid "<span onclick=\"selectAll();\">[SELECT-ALL]</span>" +msgstr "<span onclick=\"selectAll();\">[SELECT-ALL]</span>" + +# authSources/ldapSearchResults.xml?FullName +# authSources/ldapSearchResults.xml +#: text - FullName +msgid "[authSources/ldapSearchResults.xml?FullName] Name" +msgstr "Name" + +# authSources/ldapSearchResults.xml?Email +# authSources/ldapSearchResults.xml +#: text - Email +msgid "E-Mail" +msgstr "E-Mail" + +# authSources/ldapSearchResults.xml?DistinguishedName +# authSources/ldapSearchResults.xml +#: text - DistinguishedName +msgid "Distinguished Name" +msgstr "Distinguished Name" + +# cases/casesDemo.xml?uid +# cases/casesDemo.xml +#: text - uid +msgid "[cases/casesDemo.xml?uid] #" +msgstr "#" + +# cases/casesDemo.xml?name +# cases/casesDemo.xml +#: text - name +msgid "name" +msgstr "name" + +# cases/casesDemo.xml?age +# cases/casesDemo.xml +#: text - age +msgid "[cases/casesDemo.xml?age] Task" +msgstr "Task" + +# cases/casesDemo.xml?balance +# cases/casesDemo.xml +#: text - balance +msgid "balance" +msgstr "balance" + +# cases/cases_AllDynaformsList.xml?DYN_TITLE +# cases/cases_AllDynaformsList.xml +#: text - DYN_TITLE +msgid "[cases/cases_AllDynaformsList.xml?DYN_TITLE] Title" +msgstr "Title" + +# cases/cases_AllDynaformsList.xml?VIEW +# cases/cases_AllDynaformsList.xml +#: link - VIEW +msgid "[cases/cases_AllDynaformsList.xml?VIEW]" +msgstr "" + +# cases/cases_AllDynaformsList.xml?DINAFORM_HISTORY +# cases/cases_AllDynaformsList.xml +#: link - DINAFORM_HISTORY +msgid "[cases/cases_AllDynaformsList.xml?DINAFORM_HISTORY]" +msgstr "" + +# cases/cases_AllInputdocsList.xml?TITLE +# cases/cases_AllInputdocsList.xml +#: text - TITLE +msgid "Filename" +msgstr "Filename" + +# cases/cases_AllInputdocsList.xml?APP_DOC_COMMENT +# cases/cases_AllInputdocsList.xml +#: text - APP_DOC_COMMENT +msgid "Comments" +msgstr "Comments" + +# cases/cases_AllInputdocsList.xml?TYPE +# cases/cases_AllInputdocsList.xml +#: dropdown - TYPE +msgid "[cases/cases_AllInputdocsList.xml?TYPE] Type" +msgstr "Type" + +# cases/cases_AllInputdocsList.xml?TYPE-INPUT +# cases/cases_AllInputdocsList.xml +#: dropdown - TYPE - INPUT +msgid "[cases/cases_AllInputdocsList.xml?TYPE-INPUT]" +msgstr "Input Document" + +# cases/cases_AllInputdocsList.xml?TYPE-ATTACHED +# cases/cases_AllInputdocsList.xml +#: dropdown - TYPE - ATTACHED +msgid "[cases/cases_AllInputdocsList.xml?TYPE-ATTACHED]" +msgstr "Attached in form" + +# cases/cases_AllInputdocsList.xml?DOC_VERSION +# cases/cases_AllInputdocsList.xml +#: text - DOC_VERSION +msgid "[cases/cases_AllInputdocsList.xml?DOC_VERSION] Version" +msgstr "Version" + +# cases/cases_AllInputdocsList.xml?ORIGIN +# cases/cases_AllInputdocsList.xml +#: text - ORIGIN +msgid "Origin Task" +msgstr "Origin Task" + +# cases/cases_AllInputdocsList.xml?CREATED_BY +# cases/cases_AllInputdocsList.xml +#: text - CREATED_BY +msgid "Created By" +msgstr "Created By" + +# cases/cases_AllInputdocsList.xml?CREATE_DATE +# cases/cases_AllInputdocsList.xml +#: text - CREATE_DATE +msgid "[cases/cases_AllInputdocsList.xml?CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_AllInputdocsList.xml?DELETE +# cases/cases_AllInputdocsList.xml +#: link - DELETE +msgid "[cases/cases_AllInputdocsList.xml?DELETE]" +msgstr "" + +# cases/cases_AllInputdocsList.xml?DOWNLOAD +# cases/cases_AllInputdocsList.xml +#: link - DOWNLOAD +msgid "[cases/cases_AllInputdocsList.xml?DOWNLOAD]" +msgstr "" + +# cases/cases_AllOutputdocsList.xml?TITLE +# cases/cases_AllOutputdocsList.xml +#: text - TITLE +msgid "[cases/cases_AllOutputdocsList.xml?TITLE] Title" +msgstr "Title" + +# cases/cases_AllOutputdocsList.xml?OUTDOCTITLE +# cases/cases_AllOutputdocsList.xml +#: text - OUTDOCTITLE +msgid "[cases/cases_AllOutputdocsList.xml?OUTDOCTITLE] Output Document" +msgstr "Output Document" + +# cases/cases_AllOutputdocsList.xml?ORIGIN +# cases/cases_AllOutputdocsList.xml +#: text - ORIGIN +msgid "[cases/cases_AllOutputdocsList.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_AllOutputdocsList.xml?CREATED_BY +# cases/cases_AllOutputdocsList.xml +#: text - CREATED_BY +msgid "[cases/cases_AllOutputdocsList.xml?CREATED_BY] Created By" +msgstr "Created By" + +# cases/cases_AllOutputdocsList.xml?CREATE_DATE +# cases/cases_AllOutputdocsList.xml +#: text - CREATE_DATE +msgid "[cases/cases_AllOutputdocsList.xml?CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_AllOutputdocsList.xml?DELETE +# cases/cases_AllOutputdocsList.xml +#: link - DELETE +msgid "[cases/cases_AllOutputdocsList.xml?DELETE]" +msgstr "" + +# cases/cases_AllOutputdocsList.xml?DOWNLOAD_DOC +# cases/cases_AllOutputdocsList.xml +#: link - DOWNLOAD_DOC +msgid "[cases/cases_AllOutputdocsList.xml?DOWNLOAD_DOC] Download" +msgstr "Download" + +# cases/cases_AllOutputdocsList.xml?DOWNLOAD_PDF +# cases/cases_AllOutputdocsList.xml +#: link - DOWNLOAD_PDF +msgid "[cases/cases_AllOutputdocsList.xml?DOWNLOAD_PDF]" +msgstr "" + +# cases/cases_AttachInputDocument1.xml?TITLE1 +# cases/cases_AttachInputDocument1.xml +#: title - TITLE1 +msgid "Attach Input document" +msgstr "Attach Input document" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_TITLE +# cases/cases_AttachInputDocument1.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_DESCRIPTION +# cases/cases_AttachInputDocument1.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "Document Type" +msgstr "Document Type" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "Format" +msgstr "Format" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_AttachInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_AttachInputDocument1.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_AttachInputDocument1.xml?APP_DOC_FILENAME +# cases/cases_AttachInputDocument1.xml +#: file - APP_DOC_FILENAME +msgid "[cases/cases_AttachInputDocument1.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_AttachInputDocument1.xml?APP_DOC_COMMENT +# cases/cases_AttachInputDocument1.xml +#: textarea - APP_DOC_COMMENT +msgid "[cases/cases_AttachInputDocument1.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_AttachInputDocument1.xml?MORE +# cases/cases_AttachInputDocument1.xml +#: checkbox - MORE +msgid "Upload Multiple Input Documents" +msgstr "Upload Multiple Input Documents" + +# cases/cases_AttachInputDocument1.xml?SAVE +# cases/cases_AttachInputDocument1.xml +#: button - SAVE +msgid "[cases/cases_AttachInputDocument1.xml?SAVE] Save" +msgstr "Save" + +# cases/cases_AttachInputDocument2.xml?TITLE1 +# cases/cases_AttachInputDocument2.xml +#: title - TITLE1 +msgid "New Input document" +msgstr "New Input document" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_TITLE +# cases/cases_AttachInputDocument2.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_DESCRIPTION +# cases/cases_AttachInputDocument2.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_AttachInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_AttachInputDocument2.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_AttachInputDocument2.xml?APP_DOC_COMMENT +# cases/cases_AttachInputDocument2.xml +#: textarea - APP_DOC_COMMENT +msgid "[cases/cases_AttachInputDocument2.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_AttachInputDocument2.xml?MORE +# cases/cases_AttachInputDocument2.xml +#: checkbox - MORE +msgid "[cases/cases_AttachInputDocument2.xml?MORE] Upload Multiple Input Documents" +msgstr "Upload Multiple Input Documents" + +# cases/cases_AttachInputDocument2.xml?SAVE +# cases/cases_AttachInputDocument2.xml +#: button - SAVE +msgid "[cases/cases_AttachInputDocument2.xml?SAVE] Save" +msgstr "Save" + +# cases/cases_AttachInputDocument3.xml?TITLE1 +# cases/cases_AttachInputDocument3.xml +#: title - TITLE1 +msgid "[cases/cases_AttachInputDocument3.xml?TITLE1] Attach Input document" +msgstr "Attach Input document" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_TITLE +# cases/cases_AttachInputDocument3.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_DESCRIPTION +# cases/cases_AttachInputDocument3.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_AttachInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_AttachInputDocument3.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_AttachInputDocument3.xml?APP_DOC_FILENAME +# cases/cases_AttachInputDocument3.xml +#: file - APP_DOC_FILENAME +msgid "[cases/cases_AttachInputDocument3.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_AttachInputDocument3.xml?APP_DOC_COMMENT +# cases/cases_AttachInputDocument3.xml +#: textarea - APP_DOC_COMMENT +msgid "[cases/cases_AttachInputDocument3.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_AttachInputDocument3.xml?MORE +# cases/cases_AttachInputDocument3.xml +#: checkbox - MORE +msgid "[cases/cases_AttachInputDocument3.xml?MORE] Upload Multiple Input Documents" +msgstr "Upload Multiple Input Documents" + +# cases/cases_AttachInputDocument3.xml?SAVE +# cases/cases_AttachInputDocument3.xml +#: button - SAVE +msgid "[cases/cases_AttachInputDocument3.xml?SAVE] Save" +msgstr "Save" + +# cases/cases_AttachInputDocumentGeneral.xml?APP_DOC_FILENAME +# cases/cases_AttachInputDocumentGeneral.xml +#: file - APP_DOC_FILENAME +msgid "[cases/cases_AttachInputDocumentGeneral.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_AttachInputDocumentGeneral.xml?APP_DOC_COMMENT +# cases/cases_AttachInputDocumentGeneral.xml +#: textarea - APP_DOC_COMMENT +msgid "[cases/cases_AttachInputDocumentGeneral.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_AttachInputDocumentGeneral.xml?BTN_CANCEL +# cases/cases_AttachInputDocumentGeneral.xml +#: button - BTN_CANCEL +msgid "[cases/cases_AttachInputDocumentGeneral.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# cases/cases_AttachInputDocumentGeneral.xml?SAVE +# cases/cases_AttachInputDocumentGeneral.xml +#: button - SAVE +msgid "[cases/cases_AttachInputDocumentGeneral.xml?SAVE] Save" +msgstr "Save" + +# cases/cases_CannotInitiateCase.xml?TITLE +# cases/cases_CannotInitiateCase.xml +#: title - TITLE +msgid "[cases/cases_CannotInitiateCase.xml?TITLE] Start a new case" +msgstr "Start a new case" + +# cases/cases_CannotInitiateCase.xml?DESCRIPTION +# cases/cases_CannotInitiateCase.xml +#: label - DESCRIPTION +msgid "You cannot initiate a new case." +msgstr "You cannot initiate a new case." + +# cases/cases_CatchSelfService.xml?TITLE1 +# cases/cases_CatchSelfService.xml +#: title - TITLE1 +msgid "Claim Case" +msgstr "Claim Case" + +# cases/cases_CatchSelfService.xml?PRO_TITLE +# cases/cases_CatchSelfService.xml +#: text - PRO_TITLE +msgid "[cases/cases_CatchSelfService.xml?PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_CatchSelfService.xml?STATUS +# cases/cases_CatchSelfService.xml +#: text - STATUS +msgid "Case Status" +msgstr "Case Status" + +# cases/cases_CatchSelfService.xml?TITLE +# cases/cases_CatchSelfService.xml +#: text - TITLE +msgid "[cases/cases_CatchSelfService.xml?TITLE] Case Title" +msgstr "Case Title" + +# cases/cases_CatchSelfService.xml?APP_NUMBER +# cases/cases_CatchSelfService.xml +#: text - APP_NUMBER +msgid "Case Number" +msgstr "Case Number" + +# cases/cases_CatchSelfService.xml?APP_UID +# cases/cases_CatchSelfService.xml +#: text - APP_UID +msgid "Case Uid" +msgstr "Case Uid" + +# cases/cases_CatchSelfService.xml?TAS_TITLE +# cases/cases_CatchSelfService.xml +#: text - TAS_TITLE +msgid "[cases/cases_CatchSelfService.xml?TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_CatchSelfService.xml?DEL_DELEGATE_DATE +# cases/cases_CatchSelfService.xml +#: text - DEL_DELEGATE_DATE +msgid "Task Delegate Date" +msgstr "Task Delegate Date" + +# cases/cases_CatchSelfService.xml?DEL_TASK_DUE_DATE +# cases/cases_CatchSelfService.xml +#: text - DEL_TASK_DUE_DATE +msgid "Task Due Date" +msgstr "Task Due Date" + +# cases/cases_CatchSelfService.xml?PREVIOUS_TASK +# cases/cases_CatchSelfService.xml +#: text - PREVIOUS_TASK +msgid "Previous Task" +msgstr "Previous Task" + +# cases/cases_CatchSelfService.xml?PREVIOUS_USER +# cases/cases_CatchSelfService.xml +#: text - PREVIOUS_USER +msgid "Previous User" +msgstr "Previous User" + +# cases/cases_CatchSelfService.xml?BTN_CATCH +# cases/cases_CatchSelfService.xml +#: submit - BTN_CATCH +msgid "Claim this case" +msgstr "Claim this case" + +# cases/cases_CatchSelfService.xml?BTN_CANCEL +# cases/cases_CatchSelfService.xml +#: button - BTN_CANCEL +msgid "[cases/cases_CatchSelfService.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# cases/cases_DynaformHistory.xml?DYN_UID +# cases/cases_DynaformHistory.xml +#: text - DYN_UID +msgid "Dynaform" +msgstr "Dynaform" + +# cases/cases_DynaformHistory.xml?DYN_TITLE +# cases/cases_DynaformHistory.xml +#: text - DYN_TITLE +msgid "[cases/cases_DynaformHistory.xml?DYN_TITLE] Dynaform" +msgstr "Dynaform" + +# cases/cases_DynaformHistory.xml?HISTORY_DATE +# cases/cases_DynaformHistory.xml +#: date - HISTORY_DATE +msgid "[cases/cases_DynaformHistory.xml?HISTORY_DATE] Update Date" +msgstr "Update Date" + +# cases/cases_DynaformHistory.xml?USR_NAME +# cases/cases_DynaformHistory.xml +#: text - USR_NAME +msgid "[cases/cases_DynaformHistory.xml?USR_NAME] User" +msgstr "User" + +# cases/cases_DynaformHistory.xml?FIELDS +# cases/cases_DynaformHistory.xml +#: text - FIELDS +msgid "[cases/cases_DynaformHistory.xml?FIELDS] Fields" +msgstr "Fields" + +# cases/cases_InputdocsList.xml?TITLE +# cases/cases_InputdocsList.xml +#: text - TITLE +msgid "[cases/cases_InputdocsList.xml?TITLE] Title" +msgstr "Title" + +# cases/cases_InputdocsList.xml?DOC_VERSION_LABEL +# cases/cases_InputdocsList.xml +#: text - DOC_VERSION_LABEL +msgid "[cases/cases_InputdocsList.xml?DOC_VERSION_LABEL] Version" +msgstr "Version" + +# cases/cases_InputdocsList.xml?CREATOR +# cases/cases_InputdocsList.xml +#: text - CREATOR +msgid "[cases/cases_InputdocsList.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_InputdocsList.xml?COMMENT +# cases/cases_InputdocsList.xml +#: text - COMMENT +msgid "Comment" +msgstr "Comment" + +# cases/cases_InputdocsList.xml?APP_DOC_CREATE_DATE +# cases/cases_InputdocsList.xml +#: date - APP_DOC_CREATE_DATE +msgid "Created Date" +msgstr "Created Date" + +# cases/cases_InputdocsList.xml?DOWNLOAD +# cases/cases_InputdocsList.xml +#: link - DOWNLOAD +msgid "[cases/cases_InputdocsList.xml?DOWNLOAD]" +msgstr "" + +# cases/cases_InputdocsList.xml?NEWVERSION +# cases/cases_InputdocsList.xml +#: link - NEWVERSION +msgid "[cases/cases_InputdocsList.xml?NEWVERSION]" +msgstr "" + +# cases/cases_InputdocsList.xml?VERSION_HISTORY +# cases/cases_InputdocsList.xml +#: link - VERSION_HISTORY +msgid "[cases/cases_InputdocsList.xml?VERSION_HISTORY]" +msgstr "" + +# cases/cases_InputdocsList.xml?DELETE +# cases/cases_InputdocsList.xml +#: link - DELETE +msgid "[cases/cases_InputdocsList.xml?DELETE]" +msgstr "" + +# cases/cases_InputdocsListHistory.xml?TITLE +# cases/cases_InputdocsListHistory.xml +#: text - TITLE +msgid "[cases/cases_InputdocsListHistory.xml?TITLE] Title" +msgstr "Title" + +# cases/cases_InputdocsListHistory.xml?DOC_VERSION_LABEL +# cases/cases_InputdocsListHistory.xml +#: text - DOC_VERSION_LABEL +msgid "[cases/cases_InputdocsListHistory.xml?DOC_VERSION_LABEL] Version" +msgstr "Version" + +# cases/cases_InputdocsListHistory.xml?CREATOR +# cases/cases_InputdocsListHistory.xml +#: text - CREATOR +msgid "[cases/cases_InputdocsListHistory.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_InputdocsListHistory.xml?APP_DOC_CREATE_DATE +# cases/cases_InputdocsListHistory.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_InputdocsListHistory.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_InputdocsListHistory.xml?DOWNLOAD +# cases/cases_InputdocsListHistory.xml +#: link - DOWNLOAD +msgid "[cases/cases_InputdocsListHistory.xml?DOWNLOAD]" +msgstr "" + +# cases/cases_InputdocsListToRevise.xml?TITLE +# cases/cases_InputdocsListToRevise.xml +#: text - TITLE +msgid "[cases/cases_InputdocsListToRevise.xml?TITLE] Type" +msgstr "Type" + +# cases/cases_InputdocsListToRevise.xml?TYPE +# cases/cases_InputdocsListToRevise.xml +#: text - TYPE +msgid "[cases/cases_InputdocsListToRevise.xml?TYPE] Type" +msgstr "Type" + +# cases/cases_InputdocsListToRevise.xml?CREATE_DATE +# cases/cases_InputdocsListToRevise.xml +#: text - CREATE_DATE +msgid "[cases/cases_InputdocsListToRevise.xml?CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_InputdocsListToRevise.xml?VIEW +# cases/cases_InputdocsListToRevise.xml +#: link - VIEW +msgid "[cases/cases_InputdocsListToRevise.xml?VIEW]" +msgstr "" + +# cases/cases_List.xml?APP_NUMBER +# cases/cases_List.xml +#: text - APP_NUMBER +msgid "[cases/cases_List.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_List.xml?APP_TITLE +# cases/cases_List.xml +#: text - APP_TITLE +msgid "[cases/cases_List.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_List.xml?APP_TAS_TITLE +# cases/cases_List.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_List.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_List.xml?APP_PRO_TITLE +# cases/cases_List.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_List.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_List.xml?APP_DEL_PREVIOUS_USER +# cases/cases_List.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_List.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_List.xml?APP_DEL_TASK_DUE_DATE +# cases/cases_List.xml +#: text - APP_DEL_TASK_DUE_DATE +msgid "[cases/cases_List.xml?APP_DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_List.xml?APP_UPDATE_DATE +# cases/cases_List.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_List.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_List.xml?DEL_FINISH_DATE +# cases/cases_List.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_List.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_List.xml?DEL_INIT_DATE +# cases/cases_List.xml +#: text - DEL_INIT_DATE +msgid "Start Date" +msgstr "Start Date" + +# cases/cases_List.xml?OPEN +# cases/cases_List.xml +#: link - OPEN +msgid "[cases/cases_List.xml?OPEN]" +msgstr "" + +# cases/cases_List.xml?DELETE +# cases/cases_List.xml +#: link - DELETE +msgid "[cases/cases_List.xml?DELETE]" +msgstr "" + +# cases/cases_List.xml?SEARCH +# cases/cases_List.xml +#: button - SEARCH +msgid "Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListAll.xml?APP_NUMBER +# cases/cases_ListAll.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListAll.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListAll.xml?APP_TITLE +# cases/cases_ListAll.xml +#: text - APP_TITLE +msgid "[cases/cases_ListAll.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListAll.xml?APP_TAS_TITLE +# cases/cases_ListAll.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListAll.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListAll.xml?APP_PRO_TITLE +# cases/cases_ListAll.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListAll.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListAll.xml?APP_CURRENT_USER +# cases/cases_ListAll.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListAll.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListAll.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListAll.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListAll.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListAll.xml?DEL_TASK_DUE_DATE +# cases/cases_ListAll.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListAll.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListAll.xml?APP_UPDATE_DATE +# cases/cases_ListAll.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListAll.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListAll.xml?DEL_INIT_DATE +# cases/cases_ListAll.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListAll.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListAll.xml?DEL_FINISH_DATE +# cases/cases_ListAll.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListAll.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListAll.xml?APP_STATUS +# cases/cases_ListAll.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListAll.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListAll.xml?APP_STATUS-DRAFT +# cases/cases_ListAll.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListAll.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListAll.xml?APP_STATUS-TO_DO +# cases/cases_ListAll.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListAll.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListAll.xml?APP_STATUS-CANCELLED +# cases/cases_ListAll.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListAll.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListAll.xml?APP_STATUS-COMPLETED +# cases/cases_ListAll.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListAll.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListAll.xml?OPEN +# cases/cases_ListAll.xml +#: link - OPEN +msgid "[cases/cases_ListAll.xml?OPEN]" +msgstr "" + +# cases/cases_ListAll.xml?SEARCH +# cases/cases_ListAll.xml +#: button - SEARCH +msgid "[cases/cases_ListAll.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListAllDelete.xml?APP_NUMBER +# cases/cases_ListAllDelete.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListAllDelete.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListAllDelete.xml?APP_TITLE +# cases/cases_ListAllDelete.xml +#: text - APP_TITLE +msgid "[cases/cases_ListAllDelete.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListAllDelete.xml?APP_TAS_TITLE +# cases/cases_ListAllDelete.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListAllDelete.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListAllDelete.xml?APP_PRO_TITLE +# cases/cases_ListAllDelete.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListAllDelete.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListAllDelete.xml?APP_CURRENT_USER +# cases/cases_ListAllDelete.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListAllDelete.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListAllDelete.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListAllDelete.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListAllDelete.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListAllDelete.xml?DEL_TASK_DUE_DATE +# cases/cases_ListAllDelete.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListAllDelete.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListAllDelete.xml?APP_UPDATE_DATE +# cases/cases_ListAllDelete.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListAllDelete.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListAllDelete.xml?DEL_INIT_DATE +# cases/cases_ListAllDelete.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListAllDelete.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListAllDelete.xml?DEL_FINISH_DATE +# cases/cases_ListAllDelete.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListAllDelete.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListAllDelete.xml?APP_STATUS +# cases/cases_ListAllDelete.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListAllDelete.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListAllDelete.xml?APP_STATUS-DRAFT +# cases/cases_ListAllDelete.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListAllDelete.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListAllDelete.xml?APP_STATUS-TO_DO +# cases/cases_ListAllDelete.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListAllDelete.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListAllDelete.xml?APP_STATUS-CANCELLED +# cases/cases_ListAllDelete.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListAllDelete.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListAllDelete.xml?APP_STATUS-COMPLETED +# cases/cases_ListAllDelete.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListAllDelete.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListAllDelete.xml?OPEN +# cases/cases_ListAllDelete.xml +#: link - OPEN +msgid "[cases/cases_ListAllDelete.xml?OPEN]" +msgstr "" + +# cases/cases_ListAllDelete.xml?DELETE +# cases/cases_ListAllDelete.xml +#: link - DELETE +msgid "[cases/cases_ListAllDelete.xml?DELETE]" +msgstr "" + +# cases/cases_ListAllDelete.xml?SEARCH +# cases/cases_ListAllDelete.xml +#: button - SEARCH +msgid "[cases/cases_ListAllDelete.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListAll_Reassign.xml?APP_NUMBER +# cases/cases_ListAll_Reassign.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListAll_Reassign.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListAll_Reassign.xml?APP_TITLE +# cases/cases_ListAll_Reassign.xml +#: text - APP_TITLE +msgid "[cases/cases_ListAll_Reassign.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListAll_Reassign.xml?APP_TAS_TITLE +# cases/cases_ListAll_Reassign.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListAll_Reassign.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListAll_Reassign.xml?APP_PRO_TITLE +# cases/cases_ListAll_Reassign.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListAll_Reassign.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListAll_Reassign.xml?APP_CURRENT_USER +# cases/cases_ListAll_Reassign.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListAll_Reassign.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListAll_Reassign.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListAll_Reassign.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListAll_Reassign.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListAll_Reassign.xml?DEL_TASK_DUE_DATE +# cases/cases_ListAll_Reassign.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListAll_Reassign.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListAll_Reassign.xml?APP_UPDATE_DATE +# cases/cases_ListAll_Reassign.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListAll_Reassign.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListAll_Reassign.xml?DEL_INIT_DATE +# cases/cases_ListAll_Reassign.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListAll_Reassign.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListAll_Reassign.xml?DEL_FINISH_DATE +# cases/cases_ListAll_Reassign.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListAll_Reassign.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListAll_Reassign.xml?APP_STATUS +# cases/cases_ListAll_Reassign.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListAll_Reassign.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListAll_Reassign.xml?APP_STATUS-DRAFT +# cases/cases_ListAll_Reassign.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListAll_Reassign.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListAll_Reassign.xml?APP_STATUS-TO_DO +# cases/cases_ListAll_Reassign.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListAll_Reassign.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListAll_Reassign.xml?APP_STATUS-CANCELLED +# cases/cases_ListAll_Reassign.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListAll_Reassign.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListAll_Reassign.xml?APP_STATUS-COMPLETED +# cases/cases_ListAll_Reassign.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListAll_Reassign.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListAll_Reassign.xml?OPEN +# cases/cases_ListAll_Reassign.xml +#: link - OPEN +msgid "[cases/cases_ListAll_Reassign.xml?OPEN]" +msgstr "" + +# cases/cases_ListAll_Reassign.xml?REASSIGN +# cases/cases_ListAll_Reassign.xml +#: link - REASSIGN +msgid "[cases/cases_ListAll_Reassign.xml?REASSIGN]" +msgstr "" + +# cases/cases_ListAll_Reassign.xml?SEARCH +# cases/cases_ListAll_Reassign.xml +#: button - SEARCH +msgid "[cases/cases_ListAll_Reassign.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListCancelled.xml?APP_NUMBER +# cases/cases_ListCancelled.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListCancelled.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListCancelled.xml?APP_TITLE +# cases/cases_ListCancelled.xml +#: text - APP_TITLE +msgid "[cases/cases_ListCancelled.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListCancelled.xml?APP_TAS_TITLE +# cases/cases_ListCancelled.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListCancelled.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListCancelled.xml?APP_PRO_TITLE +# cases/cases_ListCancelled.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListCancelled.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListCancelled.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListCancelled.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListCancelled.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListCancelled.xml?DEL_TASK_DUE_DATE +# cases/cases_ListCancelled.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListCancelled.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListCancelled.xml?APP_UPDATE_DATE +# cases/cases_ListCancelled.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListCancelled.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListCancelled.xml?DEL_INIT_DATE +# cases/cases_ListCancelled.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListCancelled.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListCancelled.xml?DEL_FINISH_DATE +# cases/cases_ListCancelled.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListCancelled.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListCancelled.xml?VIEW +# cases/cases_ListCancelled.xml +#: link - VIEW +msgid "[cases/cases_ListCancelled.xml?VIEW]" +msgstr "" + +# cases/cases_ListCancelled.xml?CANCEL +# cases/cases_ListCancelled.xml +#: link - CANCEL +msgid "[cases/cases_ListCancelled.xml?CANCEL]" +msgstr "" + +# cases/cases_ListCancelled.xml?REACTIVATE +# cases/cases_ListCancelled.xml +#: link - REACTIVATE +msgid "[cases/cases_ListCancelled.xml?REACTIVATE]" +msgstr "" + +# cases/cases_ListCancelled.xml?SEARCH +# cases/cases_ListCancelled.xml +#: button - SEARCH +msgid "[cases/cases_ListCancelled.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListCompleted.xml?APP_NUMBER +# cases/cases_ListCompleted.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListCompleted.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListCompleted.xml?APP_TITLE +# cases/cases_ListCompleted.xml +#: text - APP_TITLE +msgid "[cases/cases_ListCompleted.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListCompleted.xml?APP_TAS_TITLE +# cases/cases_ListCompleted.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListCompleted.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListCompleted.xml?APP_PRO_TITLE +# cases/cases_ListCompleted.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListCompleted.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListCompleted.xml?APP_CURRENT_USER +# cases/cases_ListCompleted.xml +#: text - APP_CURRENT_USER +msgid "Completed by user" +msgstr "Completed by user" + +# cases/cases_ListCompleted.xml?DEL_TASK_DUE_DATE +# cases/cases_ListCompleted.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListCompleted.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListCompleted.xml?APP_UPDATE_DATE +# cases/cases_ListCompleted.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListCompleted.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListCompleted.xml?DEL_INIT_DATE +# cases/cases_ListCompleted.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListCompleted.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListCompleted.xml?DEL_FINISH_DATE +# cases/cases_ListCompleted.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListCompleted.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListCompleted.xml?VIEW +# cases/cases_ListCompleted.xml +#: link - VIEW +msgid "[cases/cases_ListCompleted.xml?VIEW]" +msgstr "" + +# cases/cases_ListCompleted.xml?DELETE +# cases/cases_ListCompleted.xml +#: link - DELETE +msgid "[cases/cases_ListCompleted.xml?DELETE]" +msgstr "" + +# cases/cases_ListCompleted.xml?SEARCH +# cases/cases_ListCompleted.xml +#: button - SEARCH +msgid "[cases/cases_ListCompleted.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListDraft.xml?APP_NUMBER +# cases/cases_ListDraft.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListDraft.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListDraft.xml?APP_TITLE +# cases/cases_ListDraft.xml +#: text - APP_TITLE +msgid "[cases/cases_ListDraft.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListDraft.xml?APP_TAS_TITLE +# cases/cases_ListDraft.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListDraft.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListDraft.xml?APP_PRO_TITLE +# cases/cases_ListDraft.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListDraft.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListDraft.xml?DEL_TASK_DUE_DATE +# cases/cases_ListDraft.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListDraft.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListDraft.xml?APP_UPDATE_DATE +# cases/cases_ListDraft.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListDraft.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListDraft.xml?DEL_INIT_DATE +# cases/cases_ListDraft.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListDraft.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListDraft.xml?OPEN +# cases/cases_ListDraft.xml +#: link - OPEN +msgid "[cases/cases_ListDraft.xml?OPEN]" +msgstr "" + +# cases/cases_ListDraft.xml?DELETE +# cases/cases_ListDraft.xml +#: link - DELETE +msgid "[cases/cases_ListDraft.xml?DELETE]" +msgstr "" + +# cases/cases_ListDraft.xml?SEARCH +# cases/cases_ListDraft.xml +#: button - SEARCH +msgid "[cases/cases_ListDraft.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListOnHold.xml?APP_NUMBER +# cases/cases_ListOnHold.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListOnHold.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListOnHold.xml?APP_TITLE +# cases/cases_ListOnHold.xml +#: text - APP_TITLE +msgid "[cases/cases_ListOnHold.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListOnHold.xml?APP_TAS_TITLE +# cases/cases_ListOnHold.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListOnHold.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListOnHold.xml?APP_PRO_TITLE +# cases/cases_ListOnHold.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListOnHold.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListOnHold.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListOnHold.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListOnHold.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListOnHold.xml?APP_UPDATE_DATE +# cases/cases_ListOnHold.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListOnHold.xml?APP_UPDATE_DATE]" +msgstr "" + +# cases/cases_ListOnHold.xml?DEL_TASK_DUE_DATE +# cases/cases_ListOnHold.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListOnHold.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListOnHold.xml?DEL_INIT_DATE +# cases/cases_ListOnHold.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListOnHold.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListOnHold.xml?DEL_FINISH_DATE +# cases/cases_ListOnHold.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListOnHold.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListOnHold.xml?VIEW +# cases/cases_ListOnHold.xml +#: link - VIEW +msgid "[cases/cases_ListOnHold.xml?VIEW]" +msgstr "" + +# cases/cases_ListOnHold.xml?UNPAUSE +# cases/cases_ListOnHold.xml +#: link - UNPAUSE +msgid "[cases/cases_ListOnHold.xml?UNPAUSE]" +msgstr "" + +# cases/cases_ListOnHold.xml?SEARCH +# cases/cases_ListOnHold.xml +#: button - SEARCH +msgid "[cases/cases_ListOnHold.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListSelfService.xml?APP_NUMBER +# cases/cases_ListSelfService.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListSelfService.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListSelfService.xml?APP_TITLE +# cases/cases_ListSelfService.xml +#: text - APP_TITLE +msgid "[cases/cases_ListSelfService.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListSelfService.xml?APP_TAS_TITLE +# cases/cases_ListSelfService.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListSelfService.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListSelfService.xml?APP_PRO_TITLE +# cases/cases_ListSelfService.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListSelfService.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListSelfService.xml?APP_CURRENT_USER +# cases/cases_ListSelfService.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListSelfService.xml?APP_CURRENT_USER] Completed by user" +msgstr "Completed by user" + +# cases/cases_ListSelfService.xml?DEL_TASK_DUE_DATE +# cases/cases_ListSelfService.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListSelfService.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListSelfService.xml?APP_UPDATE_DATE +# cases/cases_ListSelfService.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListSelfService.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListSelfService.xml?DEL_INIT_DATE +# cases/cases_ListSelfService.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListSelfService.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListSelfService.xml?DEL_FINISH_DATE +# cases/cases_ListSelfService.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListSelfService.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListSelfService.xml?VIEW +# cases/cases_ListSelfService.xml +#: link - VIEW +msgid "[cases/cases_ListSelfService.xml?VIEW]" +msgstr "" + +# cases/cases_ListSelfService.xml?DELETE +# cases/cases_ListSelfService.xml +#: link - DELETE +msgid "[cases/cases_ListSelfService.xml?DELETE]" +msgstr "" + +# cases/cases_ListSelfService.xml?SEARCH +# cases/cases_ListSelfService.xml +#: button - SEARCH +msgid "[cases/cases_ListSelfService.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListSent.xml?APP_NUMBER +# cases/cases_ListSent.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListSent.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListSent.xml?APP_TITLE +# cases/cases_ListSent.xml +#: text - APP_TITLE +msgid "[cases/cases_ListSent.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListSent.xml?APP_TAS_TITLE +# cases/cases_ListSent.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListSent.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListSent.xml?APP_PRO_TITLE +# cases/cases_ListSent.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListSent.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListSent.xml?APP_CURRENT_USER +# cases/cases_ListSent.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListSent.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListSent.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListSent.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListSent.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListSent.xml?DEL_TASK_DUE_DATE +# cases/cases_ListSent.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListSent.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListSent.xml?APP_UPDATE_DATE +# cases/cases_ListSent.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListSent.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListSent.xml?DEL_INIT_DATE +# cases/cases_ListSent.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListSent.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListSent.xml?DEL_FINISH_DATE +# cases/cases_ListSent.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListSent.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListSent.xml?APP_STATUS +# cases/cases_ListSent.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListSent.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListSent.xml?APP_STATUS-DRAFT +# cases/cases_ListSent.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListSent.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListSent.xml?APP_STATUS-TO_DO +# cases/cases_ListSent.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListSent.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListSent.xml?APP_STATUS-CANCELLED +# cases/cases_ListSent.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListSent.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListSent.xml?APP_STATUS-COMPLETED +# cases/cases_ListSent.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListSent.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListSent.xml?OPEN +# cases/cases_ListSent.xml +#: link - OPEN +msgid "[cases/cases_ListSent.xml?OPEN]" +msgstr "" + +# cases/cases_ListSent.xml?SEARCH +# cases/cases_ListSent.xml +#: button - SEARCH +msgid "[cases/cases_ListSent.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListStarted.xml?APP_NUMBER +# cases/cases_ListStarted.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListStarted.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListStarted.xml?APP_TITLE +# cases/cases_ListStarted.xml +#: text - APP_TITLE +msgid "[cases/cases_ListStarted.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListStarted.xml?APP_TAS_TITLE +# cases/cases_ListStarted.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListStarted.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListStarted.xml?APP_PRO_TITLE +# cases/cases_ListStarted.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListStarted.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListStarted.xml?APP_CURRENT_USER +# cases/cases_ListStarted.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListStarted.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListStarted.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListStarted.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListStarted.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListStarted.xml?DEL_TASK_DUE_DATE +# cases/cases_ListStarted.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListStarted.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListStarted.xml?APP_UPDATE_DATE +# cases/cases_ListStarted.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListStarted.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListStarted.xml?DEL_INIT_DATE +# cases/cases_ListStarted.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListStarted.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListStarted.xml?DEL_FINISH_DATE +# cases/cases_ListStarted.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_ListStarted.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_ListStarted.xml?APP_STATUS +# cases/cases_ListStarted.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListStarted.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListStarted.xml?APP_STATUS-DRAFT +# cases/cases_ListStarted.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListStarted.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListStarted.xml?APP_STATUS-TO_DO +# cases/cases_ListStarted.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListStarted.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListStarted.xml?APP_STATUS-CANCELLED +# cases/cases_ListStarted.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListStarted.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListStarted.xml?APP_STATUS-COMPLETED +# cases/cases_ListStarted.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListStarted.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListStarted.xml?OPEN +# cases/cases_ListStarted.xml +#: link - OPEN +msgid "[cases/cases_ListStarted.xml?OPEN]" +msgstr "" + +# cases/cases_ListStarted.xml?SEARCH +# cases/cases_ListStarted.xml +#: button - SEARCH +msgid "[cases/cases_ListStarted.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListToRevise.xml?APP_NUMBER +# cases/cases_ListToRevise.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListToRevise.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListToRevise.xml?APP_TITLE +# cases/cases_ListToRevise.xml +#: text - APP_TITLE +msgid "[cases/cases_ListToRevise.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListToRevise.xml?APP_TAS_TITLE +# cases/cases_ListToRevise.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListToRevise.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListToRevise.xml?APP_PRO_TITLE +# cases/cases_ListToRevise.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListToRevise.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListToRevise.xml?APP_CURRENT_USER +# cases/cases_ListToRevise.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_ListToRevise.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_ListToRevise.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListToRevise.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListToRevise.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListToRevise.xml?DEL_TASK_DUE_DATE +# cases/cases_ListToRevise.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListToRevise.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListToRevise.xml?APP_UPDATE_DATE +# cases/cases_ListToRevise.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListToRevise.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY] Priority" +msgstr "Priority" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY-1 +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY - 1 +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY-1]" +msgstr "Very High" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY-2 +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY - 2 +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY-2]" +msgstr "High" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY-3 +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY - 3 +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY-3]" +msgstr "Normal" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY-4 +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY - 4 +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY-4]" +msgstr "Low" + +# cases/cases_ListToRevise.xml?DEL_PRIORITY-5 +# cases/cases_ListToRevise.xml +#: dropdown - DEL_PRIORITY - 5 +msgid "[cases/cases_ListToRevise.xml?DEL_PRIORITY-5]" +msgstr "Very Low" + +# cases/cases_ListToRevise.xml?DEL_INIT_DATE +# cases/cases_ListToRevise.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListToRevise.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListToRevise.xml?APP_STATUS +# cases/cases_ListToRevise.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ListToRevise.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ListToRevise.xml?APP_STATUS-DRAFT +# cases/cases_ListToRevise.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ListToRevise.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_ListToRevise.xml?APP_STATUS-TO_DO +# cases/cases_ListToRevise.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ListToRevise.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_ListToRevise.xml?APP_STATUS-CANCELLED +# cases/cases_ListToRevise.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_ListToRevise.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_ListToRevise.xml?APP_STATUS-COMPLETED +# cases/cases_ListToRevise.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_ListToRevise.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_ListToRevise.xml?EDIT +# cases/cases_ListToRevise.xml +#: link - EDIT +msgid "[cases/cases_ListToRevise.xml?EDIT]" +msgstr "" + +# cases/cases_ListToRevise.xml?CANCEL +# cases/cases_ListToRevise.xml +#: link - CANCEL +msgid "[cases/cases_ListToRevise.xml?CANCEL]" +msgstr "" + +# cases/cases_ListToRevise.xml?DELETE +# cases/cases_ListToRevise.xml +#: link - DELETE +msgid "[cases/cases_ListToRevise.xml?DELETE]" +msgstr "" + +# cases/cases_ListToRevise.xml?SEARCH +# cases/cases_ListToRevise.xml +#: button - SEARCH +msgid "[cases/cases_ListToRevise.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListTodo.xml?APP_NUMBER +# cases/cases_ListTodo.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListTodo.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListTodo.xml?APP_TITLE +# cases/cases_ListTodo.xml +#: text - APP_TITLE +msgid "[cases/cases_ListTodo.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListTodo.xml?APP_TAS_TITLE +# cases/cases_ListTodo.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListTodo.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListTodo.xml?APP_PRO_TITLE +# cases/cases_ListTodo.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListTodo.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListTodo.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListTodo.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListTodo.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListTodo.xml?DEL_TASK_DUE_DATE +# cases/cases_ListTodo.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListTodo.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListTodo.xml?APP_UPDATE_DATE +# cases/cases_ListTodo.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListTodo.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListTodo.xml?DEL_PRIORITY +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY] Priority" +msgstr "Priority" + +# cases/cases_ListTodo.xml?DEL_PRIORITY-1 +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY - 1 +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY-1]" +msgstr "Very High" + +# cases/cases_ListTodo.xml?DEL_PRIORITY-2 +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY - 2 +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY-2]" +msgstr "High" + +# cases/cases_ListTodo.xml?DEL_PRIORITY-3 +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY - 3 +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY-3]" +msgstr "Normal" + +# cases/cases_ListTodo.xml?DEL_PRIORITY-4 +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY - 4 +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY-4]" +msgstr "Low" + +# cases/cases_ListTodo.xml?DEL_PRIORITY-5 +# cases/cases_ListTodo.xml +#: dropdown - DEL_PRIORITY - 5 +msgid "[cases/cases_ListTodo.xml?DEL_PRIORITY-5]" +msgstr "Very Low" + +# cases/cases_ListTodo.xml?DEL_INIT_DATE +# cases/cases_ListTodo.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListTodo.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListTodo.xml?OPEN +# cases/cases_ListTodo.xml +#: link - OPEN +msgid "[cases/cases_ListTodo.xml?OPEN]" +msgstr "" + +# cases/cases_ListTodo.xml?SEARCH +# cases/cases_ListTodo.xml +#: button - SEARCH +msgid "[cases/cases_ListTodo.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_ListTodoNew.xml?APP_NUMBER +# cases/cases_ListTodoNew.xml +#: text - APP_NUMBER +msgid "[cases/cases_ListTodoNew.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_ListTodoNew.xml?APP_TITLE +# cases/cases_ListTodoNew.xml +#: text - APP_TITLE +msgid "[cases/cases_ListTodoNew.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_ListTodoNew.xml?APP_TAS_TITLE +# cases/cases_ListTodoNew.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ListTodoNew.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ListTodoNew.xml?APP_PRO_TITLE +# cases/cases_ListTodoNew.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ListTodoNew.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ListTodoNew.xml?APP_DEL_PREVIOUS_USER +# cases/cases_ListTodoNew.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_ListTodoNew.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_ListTodoNew.xml?DEL_TASK_DUE_DATE +# cases/cases_ListTodoNew.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ListTodoNew.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_ListTodoNew.xml?APP_UPDATE_DATE +# cases/cases_ListTodoNew.xml +#: text - APP_UPDATE_DATE +msgid "[cases/cases_ListTodoNew.xml?APP_UPDATE_DATE] Last Modify" +msgstr "Last Modify" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY] Priority" +msgstr "Priority" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY-1 +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY - 1 +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY-1]" +msgstr "Very High" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY-2 +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY - 2 +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY-2]" +msgstr "High" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY-3 +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY - 3 +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY-3]" +msgstr "Normal" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY-4 +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY - 4 +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY-4]" +msgstr "Low" + +# cases/cases_ListTodoNew.xml?DEL_PRIORITY-5 +# cases/cases_ListTodoNew.xml +#: dropdown - DEL_PRIORITY - 5 +msgid "[cases/cases_ListTodoNew.xml?DEL_PRIORITY-5]" +msgstr "Very Low" + +# cases/cases_ListTodoNew.xml?DEL_INIT_DATE +# cases/cases_ListTodoNew.xml +#: text - DEL_INIT_DATE +msgid "[cases/cases_ListTodoNew.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_ListTodoNew.xml?OPEN +# cases/cases_ListTodoNew.xml +#: link - OPEN +msgid "[cases/cases_ListTodoNew.xml?OPEN]" +msgstr "" + +# cases/cases_ListTodoNew.xml?SEARCH +# cases/cases_ListTodoNew.xml +#: button - SEARCH +msgid "[cases/cases_ListTodoNew.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_Messages.xml?APP_MSG_TYPE +# cases/cases_Messages.xml +#: text - APP_MSG_TYPE +msgid "[cases/cases_Messages.xml?APP_MSG_TYPE] Type" +msgstr "Type" + +# cases/cases_Messages.xml?APP_MSG_DATE +# cases/cases_Messages.xml +#: text - APP_MSG_DATE +msgid "Date" +msgstr "Date" + +# cases/cases_Messages.xml?APP_MSG_SUBJECT +# cases/cases_Messages.xml +#: text - APP_MSG_SUBJECT +msgid "Subject" +msgstr "Subject" + +# cases/cases_Messages.xml?APP_MSG_FROM +# cases/cases_Messages.xml +#: text - APP_MSG_FROM +msgid "From" +msgstr "From" + +# cases/cases_Messages.xml?APP_MSG_TO +# cases/cases_Messages.xml +#: text - APP_MSG_TO +msgid "[cases/cases_Messages.xml?APP_MSG_TO] To" +msgstr "To" + +# cases/cases_Messages.xml?APP_MSG_STATUS +# cases/cases_Messages.xml +#: text - APP_MSG_STATUS +msgid "[cases/cases_Messages.xml?APP_MSG_STATUS] Status" +msgstr "Status" + +# cases/cases_Messages.xml?VIEW +# cases/cases_Messages.xml +#: link - VIEW +msgid "[cases/cases_Messages.xml?VIEW]" +msgstr "" + +# cases/cases_Messages.xml?RESEND +# cases/cases_Messages.xml +#: link - RESEND +msgid "[cases/cases_Messages.xml?RESEND]" +msgstr "" + +# cases/cases_MessagesView.xml?title +# cases/cases_MessagesView.xml +#: title - title +msgid "MESSAGE" +msgstr "MESSAGE" + +# cases/cases_MessagesView.xml?APP_MSG_SUBJECT +# cases/cases_MessagesView.xml +#: text - APP_MSG_SUBJECT +msgid "SUBJECT" +msgstr "SUBJECT" + +# cases/cases_MessagesView.xml?APP_MSG_FROM +# cases/cases_MessagesView.xml +#: text - APP_MSG_FROM +msgid "FROM" +msgstr "FROM" + +# cases/cases_MessagesView.xml?APP_MSG_TO +# cases/cases_MessagesView.xml +#: text - APP_MSG_TO +msgid "TO" +msgstr "TO" + +# cases/cases_MessagesView.xml?APP_MSG_DATE +# cases/cases_MessagesView.xml +#: text - APP_MSG_DATE +msgid "DATE" +msgstr "DATE" + +# cases/cases_MessagesView.xml?APP_MSG_BODY +# cases/cases_MessagesView.xml +#: html - APP_MSG_BODY +msgid "[cases/cases_MessagesView.xml?APP_MSG_BODY]" +msgstr "" + +# cases/cases_New.xml?TITLE +# cases/cases_New.xml +#: title - TITLE +msgid "[cases/cases_New.xml?TITLE] Start a new case" +msgstr "Start a new case" + +# cases/cases_New.xml?DESCRIPTION +# cases/cases_New.xml +#: link - DESCRIPTION +msgid "[cases/cases_New.xml?DESCRIPTION]" +msgstr "" + +# cases/cases_New.xml?TAS_UID +# cases/cases_New.xml +#: dropdown - TAS_UID +msgid "[cases/cases_New.xml?TAS_UID] Process" +msgstr "Process" + +# cases/cases_New.xml?START +# cases/cases_New.xml +#: submit - START +msgid "Start" +msgstr "Start" + +# cases/cases_NewRadioGroup.xml?TITLE +# cases/cases_NewRadioGroup.xml +#: title - TITLE +msgid "[cases/cases_NewRadioGroup.xml?TITLE] Start a new case" +msgstr "Start a new case" + +# cases/cases_NewRadioGroup.xml?DESCRIPTION +# cases/cases_NewRadioGroup.xml +#: link - DESCRIPTION +msgid "[cases/cases_NewRadioGroup.xml?DESCRIPTION]" +msgstr "" + +# cases/cases_NewRadioGroup.xml?TAS_UID +# cases/cases_NewRadioGroup.xml +#: radiogroup - TAS_UID +msgid "[cases/cases_NewRadioGroup.xml?TAS_UID]" +msgstr "" + +# cases/cases_NewRadioGroup.xml?START +# cases/cases_NewRadioGroup.xml +#: submit - START +msgid "[cases/cases_NewRadioGroup.xml?START] Start" +msgstr "Start" + +# cases/cases_Options.xml?PROCESS_FILTER +# cases/cases_Options.xml +#: dropdown - PROCESS_FILTER +msgid "[cases/cases_Options.xml?PROCESS_FILTER] Process" +msgstr "Process" + +# cases/cases_Options.xml?PROCESS_FILTER-0 +# cases/cases_Options.xml +#: dropdown - PROCESS_FILTER - 0 +msgid "[cases/cases_Options.xml?PROCESS_FILTER-0]" +msgstr "All" + +# cases/cases_Options.xml?PAGED_TABLE_FAST_SEARCH +# cases/cases_Options.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[cases/cases_Options.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# cases/cases_Options.xml?PAGED_TABLE_JUMP +# cases/cases_Options.xml +#: text - PAGED_TABLE_JUMP +msgid "[cases/cases_Options.xml?PAGED_TABLE_JUMP]" +msgstr "" + +# cases/cases_OptionsSent.xml?PROCESS_FILTER +# cases/cases_OptionsSent.xml +#: dropdown - PROCESS_FILTER +msgid "[cases/cases_OptionsSent.xml?PROCESS_FILTER] Process" +msgstr "Process" + +# cases/cases_OptionsSent.xml?PROCESS_FILTER-0 +# cases/cases_OptionsSent.xml +#: dropdown - PROCESS_FILTER - 0 +msgid "[cases/cases_OptionsSent.xml?PROCESS_FILTER-0]" +msgstr "All" + +# cases/cases_OptionsSent.xml?APP_STATUS_FILTER +# cases/cases_OptionsSent.xml +#: dropdown - APP_STATUS_FILTER +msgid "[cases/cases_OptionsSent.xml?APP_STATUS_FILTER] Status" +msgstr "Status" + +# cases/cases_OptionsSent.xml?APP_STATUS_FILTER-ALL +# cases/cases_OptionsSent.xml +#: dropdown - APP_STATUS_FILTER - ALL +msgid "[cases/cases_OptionsSent.xml?APP_STATUS_FILTER-ALL]" +msgstr "All" + +# cases/cases_OptionsSent.xml?APP_STATUS_FILTER-TO_DO +# cases/cases_OptionsSent.xml +#: dropdown - APP_STATUS_FILTER - TO_DO +msgid "[cases/cases_OptionsSent.xml?APP_STATUS_FILTER-TO_DO]" +msgstr "To Do" + +# cases/cases_OptionsSent.xml?APP_STATUS_FILTER-CANCELLED +# cases/cases_OptionsSent.xml +#: dropdown - APP_STATUS_FILTER - CANCELLED +msgid "[cases/cases_OptionsSent.xml?APP_STATUS_FILTER-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_OptionsSent.xml?APP_STATUS_FILTER-COMPLETED +# cases/cases_OptionsSent.xml +#: dropdown - APP_STATUS_FILTER - COMPLETED +msgid "[cases/cases_OptionsSent.xml?APP_STATUS_FILTER-COMPLETED]" +msgstr "Completed" + +# cases/cases_OptionsSent.xml?MINE +# cases/cases_OptionsSent.xml +#: link - MINE +msgid "Started by me" +msgstr "Started by me" + +# cases/cases_OptionsSent.xml?READ_FILTER +# cases/cases_OptionsSent.xml +#: link - READ_FILTER +msgid "[cases/cases_OptionsSent.xml?READ_FILTER] Read" +msgstr "Read" + +# cases/cases_OptionsSent.xml?UNREAD_FILTER +# cases/cases_OptionsSent.xml +#: link - UNREAD_FILTER +msgid "[cases/cases_OptionsSent.xml?UNREAD_FILTER] Unread" +msgstr "Unread" + +# cases/cases_OptionsSent.xml?ALL_FILTER +# cases/cases_OptionsSent.xml +#: link - ALL_FILTER +msgid "[cases/cases_OptionsSent.xml?ALL_FILTER] All" +msgstr "All" + +# cases/cases_OptionsSent.xml?PAGED_TABLE_FAST_SEARCH +# cases/cases_OptionsSent.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[cases/cases_OptionsSent.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# cases/cases_OptionsSent.xml?PAGED_TABLE_JUMP +# cases/cases_OptionsSent.xml +#: text - PAGED_TABLE_JUMP +msgid "[cases/cases_OptionsSent.xml?PAGED_TABLE_JUMP]" +msgstr "" + +# cases/cases_OptionsToDo.xml?PROCESS_FILTER +# cases/cases_OptionsToDo.xml +#: dropdown - PROCESS_FILTER +msgid "[cases/cases_OptionsToDo.xml?PROCESS_FILTER] Process" +msgstr "Process" + +# cases/cases_OptionsToDo.xml?PROCESS_FILTER-0 +# cases/cases_OptionsToDo.xml +#: dropdown - PROCESS_FILTER - 0 +msgid "[cases/cases_OptionsToDo.xml?PROCESS_FILTER-0]" +msgstr "All" + +# cases/cases_OptionsToDo.xml?READ_FILTER +# cases/cases_OptionsToDo.xml +#: link - READ_FILTER +msgid "[cases/cases_OptionsToDo.xml?READ_FILTER] Read" +msgstr "Read" + +# cases/cases_OptionsToDo.xml?UNREAD_FILTER +# cases/cases_OptionsToDo.xml +#: link - UNREAD_FILTER +msgid "[cases/cases_OptionsToDo.xml?UNREAD_FILTER] Unread" +msgstr "Unread" + +# cases/cases_OptionsToDo.xml?ALL_FILTER +# cases/cases_OptionsToDo.xml +#: link - ALL_FILTER +msgid "[cases/cases_OptionsToDo.xml?ALL_FILTER] All" +msgstr "All" + +# cases/cases_OptionsToDo.xml?PAGED_TABLE_FAST_SEARCH +# cases/cases_OptionsToDo.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[cases/cases_OptionsToDo.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# cases/cases_OptionsToDo.xml?PAGED_TABLE_JUMP +# cases/cases_OptionsToDo.xml +#: text - PAGED_TABLE_JUMP +msgid "[cases/cases_OptionsToDo.xml?PAGED_TABLE_JUMP]" +msgstr "" + +# cases/cases_OutputdocsListToRevise.xml?TITLE +# cases/cases_OutputdocsListToRevise.xml +#: text - TITLE +msgid "[cases/cases_OutputdocsListToRevise.xml?TITLE] Title" +msgstr "Title" + +# cases/cases_OutputdocsListToRevise.xml?APP_DOC_CREATE_DATE +# cases/cases_OutputdocsListToRevise.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_OutputdocsListToRevise.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_OutputdocsListToRevise.xml?VIEW +# cases/cases_OutputdocsListToRevise.xml +#: link - VIEW +msgid "[cases/cases_OutputdocsListToRevise.xml?VIEW]" +msgstr "" + +# cases/cases_ProcessInformation.xml?PRO_TITLE +# cases/cases_ProcessInformation.xml +#: text - PRO_TITLE +msgid "[cases/cases_ProcessInformation.xml?PRO_TITLE] Title" +msgstr "Title" + +# cases/cases_ProcessInformation.xml?PRO_DESCRIPTION +# cases/cases_ProcessInformation.xml +#: textarea - PRO_DESCRIPTION +msgid "[cases/cases_ProcessInformation.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ProcessInformation.xml?PRO_AUTHOR +# cases/cases_ProcessInformation.xml +#: text - PRO_AUTHOR +msgid "Author" +msgstr "Author" + +# cases/cases_ProcessInformation.xml?PRO_CREATE_DATE +# cases/cases_ProcessInformation.xml +#: date - PRO_CREATE_DATE +msgid "[cases/cases_ProcessInformation.xml?PRO_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_Reassign.xml?TITLE +# cases/cases_Reassign.xml +#: title - TITLE +msgid "Finish Reassigned" +msgstr "Finish Reassigned" + +# cases/cases_Reassign.xml?APP_NUMBER +# cases/cases_Reassign.xml +#: text - APP_NUMBER +msgid "Case #" +msgstr "Case #" + +# cases/cases_Reassign.xml?USERS +# cases/cases_Reassign.xml +#: text - USERS +msgid "Reassigned to" +msgstr "Reassigned to" + +# cases/cases_Reassign.xml?BACK +# cases/cases_Reassign.xml +#: button - BACK +msgid "BACK" +msgstr "BACK" + +# cases/cases_ReassignBy.xml?title +# cases/cases_ReassignBy.xml +#: subtitle - title +msgid "<center>Reassignment of Cases</center>" +msgstr "<center>Reassignment of Cases</center>" + +# cases/cases_ReassignBy.xml?REASSIGN_BY +# cases/cases_ReassignBy.xml +#: radiogroup - REASSIGN_BY +msgid "Reassign By" +msgstr "Reassign By" + +# cases/cases_ReassignBy.xml?REASSIGN_BY-1 +# cases/cases_ReassignBy.xml +#: radiogroup - REASSIGN_BY - 1 +msgid "[cases/cases_ReassignBy.xml?REASSIGN_BY-1]" +msgstr "Case" + +# cases/cases_ReassignBy.xml?REASSIGN_BY-2 +# cases/cases_ReassignBy.xml +#: radiogroup - REASSIGN_BY - 2 +msgid "[cases/cases_ReassignBy.xml?REASSIGN_BY-2]" +msgstr "User" + +# cases/cases_ReassignBy.xml?REASSIGN_USER +# cases/cases_ReassignBy.xml +#: dropdown - REASSIGN_USER +msgid "[cases/cases_ReassignBy.xml?REASSIGN_USER]" +msgstr "" + +# cases/cases_ReassignBy.xml?REASSIGN_USER-'' +# cases/cases_ReassignBy.xml +#: dropdown - REASSIGN_USER - '' +msgid "[cases/cases_ReassignBy.xml?REASSIGN_USER-'']" +msgstr " - Select - " + +# cases/cases_ReassignShowInfo.xml?TITLE +# cases/cases_ReassignShowInfo.xml +#: subtitle - TITLE +msgid "<center>Reassigned Cases Resume</center>" +msgstr "<center>Reassigned Cases Resume</center>" + +# cases/cases_ReassignShowInfo.xml?MESSAGE +# cases/cases_ReassignShowInfo.xml +#: text - MESSAGE +msgid "[cases/cases_ReassignShowInfo.xml?MESSAGE]" +msgstr "" + +# cases/cases_ReassignShowInfo.xml?BACK +# cases/cases_ReassignShowInfo.xml +#: button - BACK +msgid "[cases/cases_ReassignShowInfo.xml?BACK] BACK" +msgstr "BACK" + +# cases/cases_ReassignUsers.xml?REASSIGN_USER +# cases/cases_ReassignUsers.xml +#: dropdown - REASSIGN_USER +msgid "[cases/cases_ReassignUsers.xml?REASSIGN_USER] User" +msgstr "User" + +# cases/cases_ReassignUsers.xml?REASSIGN_USER-'' +# cases/cases_ReassignUsers.xml +#: dropdown - REASSIGN_USER - '' +msgid "[cases/cases_ReassignUsers.xml?REASSIGN_USER-'']" +msgstr " - Select - " + +# cases/cases_Resume.xml?TITLE1 +# cases/cases_Resume.xml +#: title - TITLE1 +msgid "Case Properties" +msgstr "Case Properties" + +# cases/cases_Resume.xml?PRO_TITLE +# cases/cases_Resume.xml +#: text - PRO_TITLE +msgid "[cases/cases_Resume.xml?PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_Resume.xml?STATUS +# cases/cases_Resume.xml +#: text - STATUS +msgid "[cases/cases_Resume.xml?STATUS] Case Status" +msgstr "Case Status" + +# cases/cases_Resume.xml?TITLE +# cases/cases_Resume.xml +#: text - TITLE +msgid "[cases/cases_Resume.xml?TITLE] Case Title" +msgstr "Case Title" + +# cases/cases_Resume.xml?APP_NUMBER +# cases/cases_Resume.xml +#: text - APP_NUMBER +msgid "[cases/cases_Resume.xml?APP_NUMBER] Case Number" +msgstr "Case Number" + +# cases/cases_Resume.xml?APP_UID +# cases/cases_Resume.xml +#: text - APP_UID +msgid "[cases/cases_Resume.xml?APP_UID] Case Uid" +msgstr "Case Uid" + +# cases/cases_Resume.xml?CREATOR +# cases/cases_Resume.xml +#: text - CREATOR +msgid "[cases/cases_Resume.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_Resume.xml?CREATE_DATE +# cases/cases_Resume.xml +#: text - CREATE_DATE +msgid "[cases/cases_Resume.xml?CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_Resume.xml?UPDATE_DATE +# cases/cases_Resume.xml +#: text - UPDATE_DATE +msgid "Last Update" +msgstr "Last Update" + +# cases/cases_Resume.xml?TITLE2 +# cases/cases_Resume.xml +#: title - TITLE2 +msgid "Current Task Properties" +msgstr "Current Task Properties" + +# cases/cases_Resume.xml?TAS_TITLE +# cases/cases_Resume.xml +#: text - TAS_TITLE +msgid "[cases/cases_Resume.xml?TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_Resume.xml?CURRENT_USER +# cases/cases_Resume.xml +#: text - CURRENT_USER +msgid "[cases/cases_Resume.xml?CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_Resume.xml?DEL_DELEGATE_DATE +# cases/cases_Resume.xml +#: text - DEL_DELEGATE_DATE +msgid "[cases/cases_Resume.xml?DEL_DELEGATE_DATE] Task Delegate Date" +msgstr "Task Delegate Date" + +# cases/cases_Resume.xml?DEL_INIT_DATE +# cases/cases_Resume.xml +#: text - DEL_INIT_DATE +msgid "Task Init Date" +msgstr "Task Init Date" + +# cases/cases_Resume.xml?DEL_TASK_DUE_DATE +# cases/cases_Resume.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_Resume.xml?DEL_TASK_DUE_DATE] Task Due Date" +msgstr "Task Due Date" + +# cases/cases_Resume.xml?DEL_FINISH_DATE +# cases/cases_Resume.xml +#: text - DEL_FINISH_DATE +msgid "[cases/cases_Resume.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_Scheduler_Edit.xml?GENERAL_INF +# cases/cases_Scheduler_Edit.xml +#: title - GENERAL_INF +msgid "General Information" +msgstr "General Information" + +# cases/cases_Scheduler_Edit.xml?PROPERTIES_INF +# cases/cases_Scheduler_Edit.xml +#: subtitle - PROPERTIES_INF +msgid "Please insert a valid processmaker user name and password." +msgstr "Please insert a valid processmaker user name and password." + +# cases/cases_Scheduler_Edit.xml?SCH_USER_NAME +# cases/cases_Scheduler_Edit.xml +#: text - SCH_USER_NAME +msgid "[cases/cases_Scheduler_Edit.xml?SCH_USER_NAME] User Name" +msgstr "User Name" + +# cases/cases_Scheduler_Edit.xml?SCH_USER_PASSWORD +# cases/cases_Scheduler_Edit.xml +#: password - SCH_USER_PASSWORD +msgid "[cases/cases_Scheduler_Edit.xml?SCH_USER_PASSWORD] Password" +msgstr "Password" + +# cases/cases_Scheduler_Edit.xml?TEST_CONNECTION +# cases/cases_Scheduler_Edit.xml +#: button - TEST_CONNECTION +msgid "Test User" +msgstr "Test User" + +# cases/cases_Scheduler_Edit.xml?EDIT_USER +# cases/cases_Scheduler_Edit.xml +#: button - EDIT_USER +msgid "Edit User" +msgstr "Edit User" + +# cases/cases_Scheduler_Edit.xml?PERFORM_TASK +# cases/cases_Scheduler_Edit.xml +#: subtitle - PERFORM_TASK +msgid "[cases/cases_Scheduler_Edit.xml?PERFORM_TASK] Properties" +msgstr "Properties" + +# cases/cases_Scheduler_Edit.xml?SCH_NAME +# cases/cases_Scheduler_Edit.xml +#: text - SCH_NAME +msgid "[cases/cases_Scheduler_Edit.xml?SCH_NAME] Description" +msgstr "Description" + +# cases/cases_Scheduler_Edit.xml?PRO_UID +# cases/cases_Scheduler_Edit.xml +#: dropdown - PRO_UID +msgid "[cases/cases_Scheduler_Edit.xml?PRO_UID] Process" +msgstr "Process" + +# cases/cases_Scheduler_Edit.xml?TAS_UID +# cases/cases_Scheduler_Edit.xml +#: dropdown - TAS_UID +msgid "[cases/cases_Scheduler_Edit.xml?TAS_UID] Task" +msgstr "Task" + +# cases/cases_Scheduler_Edit.xml?SCH_OPTION_VIEW +# cases/cases_Scheduler_Edit.xml +#: text - SCH_OPTION_VIEW +msgid "Perform this task" +msgstr "Perform this task" + +# cases/cases_Scheduler_Edit.xml?SELECT_TIME_DAY +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_TIME_DAY +msgid "Select the time and day you want this task to start." +msgstr "Select the time and day you want this task to start." + +# cases/cases_Scheduler_Edit.xml?SCH_START_TIME +# cases/cases_Scheduler_Edit.xml +#: text - SCH_START_TIME +msgid "Execution time" +msgstr "Execution time" + +# cases/cases_Scheduler_Edit.xml?SELECT_DATE +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_DATE +msgid "Select date" +msgstr "Select date" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DATE +# cases/cases_Scheduler_Edit.xml +#: date - SCH_START_DATE +msgid "Start date" +msgstr "Start date" + +# cases/cases_Scheduler_Edit.xml?SELECT_1 +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_1 +msgid "Daily" +msgstr "Daily" + +# cases/cases_Scheduler_Edit.xml?SELECT_2 +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_2 +msgid "Weekly" +msgstr "Weekly" + +# cases/cases_Scheduler_Edit.xml?SCH_EVERY_DAYS +# cases/cases_Scheduler_Edit.xml +#: text - SCH_EVERY_DAYS +msgid "Every" +msgstr "Every" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS +msgid "Select the day(s) of the week below" +msgstr "Select the day(s) of the week below" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-1 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-1]" +msgstr "Monday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-2 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-2]" +msgstr "Tuesday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-3 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS - 3 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-3]" +msgstr "Wednesday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-4 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS - 4 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS-4]" +msgstr "Thursday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS_2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-5 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 5 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-5]" +msgstr "Friday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-6 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 6 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-6]" +msgstr "Saturday" + +# cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-7 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 7 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_WEEK_DAYS_2-7]" +msgstr "Sunday" + +# cases/cases_Scheduler_Edit.xml?SELECT_3 +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_3 +msgid "Monthly" +msgstr "Monthly" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY +# cases/cases_Scheduler_Edit.xml +#: radiogroup - SCH_START_DAY +msgid "Day" +msgstr "Day" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY-1 +# cases/cases_Scheduler_Edit.xml +#: radiogroup - SCH_START_DAY - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY-1]" +msgstr "Day" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY-2 +# cases/cases_Scheduler_Edit.xml +#: radiogroup - SCH_START_DAY - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY-2]" +msgstr "The" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_1 +# cases/cases_Scheduler_Edit.xml +#: text - SCH_START_DAY_OPT_1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_1]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-1 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-1]" +msgstr "First" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-2 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-2]" +msgstr "Second" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-3 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 3 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-3]" +msgstr "Third" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-4 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 4 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-4]" +msgstr "Fourth" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-5 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 5 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_WEEKS-5]" +msgstr "Last" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-1 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-1]" +msgstr "Monday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-2 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-2]" +msgstr "Tuesday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-3 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 3 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-3]" +msgstr "Wednesday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-4 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 4 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-4]" +msgstr "Thursday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-5 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 5 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-5]" +msgstr "Friday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-6 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 6 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-6]" +msgstr "Saturday" + +# cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-7 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 7 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-7]" +msgstr "Sunday" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS +msgid "Of the month(s)" +msgstr "Of the month(s)" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS-1 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS-1]" +msgstr "Jan" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS-2 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS-2]" +msgstr "Feb" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS-3 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS - 3 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS-3]" +msgstr "Mar" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS-4 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS - 4 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS-4]" +msgstr "Apr" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-5 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_2 - 5 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-5]" +msgstr "May" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-6 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_2 - 6 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-6]" +msgstr "Jun" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-7 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_2 - 7 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-7]" +msgstr "Jul" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-8 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_2 - 8 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_2-8]" +msgstr "Aug" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_3 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-9 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_3 - 9 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-9]" +msgstr "Sep" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-10 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_3 - 10 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-10]" +msgstr "Oct" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-11 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_3 - 11 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-11]" +msgstr "Nov" + +# cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-12 +# cases/cases_Scheduler_Edit.xml +#: checkgroup - SCH_MONTHS_3 - 12 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_MONTHS_3-12]" +msgstr "Dec" + +# cases/cases_Scheduler_Edit.xml?ADVANCED_4 +# cases/cases_Scheduler_Edit.xml +#: subtitle - ADVANCED_4 +msgid "Advanced Options" +msgstr "Advanced Options" + +# cases/cases_Scheduler_Edit.xml?SCH_END_DATE_CHK +# cases/cases_Scheduler_Edit.xml +#: checkbox - SCH_END_DATE_CHK +msgid "End Date" +msgstr "End Date" + +# cases/cases_Scheduler_Edit.xml?SCH_END_DATE +# cases/cases_Scheduler_Edit.xml +#: date - SCH_END_DATE +msgid "[cases/cases_Scheduler_Edit.xml?SCH_END_DATE]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_REPEAT_TASK_CHK +# cases/cases_Scheduler_Edit.xml +#: checkbox - SCH_REPEAT_TASK_CHK +msgid "Repeat Task" +msgstr "Repeat Task" + +# cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY +# cases/cases_Scheduler_Edit.xml +#: text - SCH_REPEAT_EVERY +msgid "[cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY] Every" +msgstr "Every" + +# cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_REPEAT_EVERY_OPT +msgid "[cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT]" +msgstr "" + +# cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT-1 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_REPEAT_EVERY_OPT - 1 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT-1]" +msgstr "Minutes" + +# cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT-2 +# cases/cases_Scheduler_Edit.xml +#: dropdown - SCH_REPEAT_EVERY_OPT - 2 +msgid "[cases/cases_Scheduler_Edit.xml?SCH_REPEAT_EVERY_OPT-2]" +msgstr "Hours" + +# cases/cases_Scheduler_Edit.xml?SELECT_PLUGIN +# cases/cases_Scheduler_Edit.xml +#: subtitle - SELECT_PLUGIN +msgid "Start a case based on following registered Plugin." +msgstr "Start a case based on following registered Plugin." + +# cases/cases_Scheduler_Edit.xml?UPDATE +# cases/cases_Scheduler_Edit.xml +#: submit - UPDATE +msgid "Update" +msgstr "Update" + +# cases/cases_Scheduler_List.xml?SCH_NAME +# cases/cases_Scheduler_List.xml +#: text - SCH_NAME +msgid "[cases/cases_Scheduler_List.xml?SCH_NAME] Name" +msgstr "Name" + +# cases/cases_Scheduler_List.xml?PRO_TITLE +# cases/cases_Scheduler_List.xml +#: text - PRO_TITLE +msgid "[cases/cases_Scheduler_List.xml?PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_Scheduler_List.xml?TAS_TITLE +# cases/cases_Scheduler_List.xml +#: text - TAS_TITLE +msgid "[cases/cases_Scheduler_List.xml?TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_Scheduler_List.xml?SCH_TIME_NEXT_RUN +# cases/cases_Scheduler_List.xml +#: text - SCH_TIME_NEXT_RUN +msgid "Time next run" +msgstr "Time next run" + +# cases/cases_Scheduler_List.xml?SCH_LAST_RUN_TIME +# cases/cases_Scheduler_List.xml +#: text - SCH_LAST_RUN_TIME +msgid "Last run time" +msgstr "Last run time" + +# cases/cases_Scheduler_List.xml?SCH_STATUS_LNK +# cases/cases_Scheduler_List.xml +#: link - SCH_STATUS_LNK +msgid "[cases/cases_Scheduler_List.xml?SCH_STATUS_LNK]" +msgstr "" + +# cases/cases_Scheduler_List.xml?ROL_VIEW +# cases/cases_Scheduler_List.xml +#: link - ROL_VIEW +msgid "[cases/cases_Scheduler_List.xml?ROL_VIEW]" +msgstr "" + +# cases/cases_Scheduler_List.xml?DELETE +# cases/cases_Scheduler_List.xml +#: link - DELETE +msgid "[cases/cases_Scheduler_List.xml?DELETE]" +msgstr "" + +# cases/cases_Scheduler_Log.xml?EXEC_DATE +# cases/cases_Scheduler_Log.xml +#: text - EXEC_DATE +msgid "[cases/cases_Scheduler_Log.xml?EXEC_DATE] Date" +msgstr "Date" + +# cases/cases_Scheduler_Log.xml?EXEC_HOUR +# cases/cases_Scheduler_Log.xml +#: text - EXEC_HOUR +msgid "Time" +msgstr "Time" + +# cases/cases_Scheduler_Log.xml?USR_NAME +# cases/cases_Scheduler_Log.xml +#: text - USR_NAME +msgid "[cases/cases_Scheduler_Log.xml?USR_NAME] User" +msgstr "User" + +# cases/cases_Scheduler_Log.xml?RESULT +# cases/cases_Scheduler_Log.xml +#: text - RESULT +msgid "Result" +msgstr "Result" + +# cases/cases_Scheduler_Log.xml?WS_CREATE_CASE_STATUS +# cases/cases_Scheduler_Log.xml +#: text - WS_CREATE_CASE_STATUS +msgid "Created Case Status" +msgstr "Created Case Status" + +# cases/cases_Scheduler_Log.xml?WS_ROUTE_CASE_STATUS +# cases/cases_Scheduler_Log.xml +#: text - WS_ROUTE_CASE_STATUS +msgid "Routed Case Status" +msgstr "Routed Case Status" + +# cases/cases_Scheduler_Log.xml?VIEW +# cases/cases_Scheduler_Log.xml +#: link - VIEW +msgid "[cases/cases_Scheduler_Log.xml?VIEW] View" +msgstr "View" + +# cases/cases_Scheduler_Log_Detail.xml?SCH_UID +# cases/cases_Scheduler_Log_Detail.xml +#: text - SCH_UID +msgid "Scheduled Task ID" +msgstr "Scheduled Task ID" + +# cases/cases_Scheduler_Log_Detail.xml?TAS_UID +# cases/cases_Scheduler_Log_Detail.xml +#: text - TAS_UID +msgid "Task ID" +msgstr "Task ID" + +# cases/cases_Scheduler_Log_Detail.xml?PRO_UID +# cases/cases_Scheduler_Log_Detail.xml +#: text - PRO_UID +msgid "Process Id" +msgstr "Process Id" + +# cases/cases_Scheduler_Log_Detail.xml?USR_NAME +# cases/cases_Scheduler_Log_Detail.xml +#: text - USR_NAME +msgid "[cases/cases_Scheduler_Log_Detail.xml?USR_NAME] User" +msgstr "User" + +# cases/cases_Scheduler_Log_Detail.xml?EXEC_DATE +# cases/cases_Scheduler_Log_Detail.xml +#: text - EXEC_DATE +msgid "Execution Date" +msgstr "Execution Date" + +# cases/cases_Scheduler_Log_Detail.xml?EXEC_HOUR +# cases/cases_Scheduler_Log_Detail.xml +#: text - EXEC_HOUR +msgid "Execution Hour" +msgstr "Execution Hour" + +# cases/cases_Scheduler_Log_Detail.xml?RESULT +# cases/cases_Scheduler_Log_Detail.xml +#: text - RESULT +msgid "Execution Status" +msgstr "Execution Status" + +# cases/cases_Scheduler_Log_Detail.xml?WS_CREATE_CASE_STATUS +# cases/cases_Scheduler_Log_Detail.xml +#: text - WS_CREATE_CASE_STATUS +msgid "[cases/cases_Scheduler_Log_Detail.xml?WS_CREATE_CASE_STATUS] Created Case Status" +msgstr "Created Case Status" + +# cases/cases_Scheduler_Log_Detail.xml?WS_ROUTE_CASE_STATUS +# cases/cases_Scheduler_Log_Detail.xml +#: text - WS_ROUTE_CASE_STATUS +msgid "[cases/cases_Scheduler_Log_Detail.xml?WS_ROUTE_CASE_STATUS] Routed Case Status" +msgstr "Routed Case Status" + +# cases/cases_Scheduler_Log_Detail.xml?VIEW +# cases/cases_Scheduler_Log_Detail.xml +#: link - VIEW +msgid "Back to List" +msgstr "Back to List" + +# cases/cases_Scheduler_New.xml?GENERAL_INF +# cases/cases_Scheduler_New.xml +#: title - GENERAL_INF +msgid "[cases/cases_Scheduler_New.xml?GENERAL_INF] General Information" +msgstr "General Information" + +# cases/cases_Scheduler_New.xml?PROPERTIES_INF +# cases/cases_Scheduler_New.xml +#: subtitle - PROPERTIES_INF +msgid "Please insert a valid processmaker user name and password, in order to assign the case to their respective owner" +msgstr "Please insert a valid processmaker user name and password, in order to assign the case to their respective owner" + +# cases/cases_Scheduler_New.xml?SCH_USER_NAME +# cases/cases_Scheduler_New.xml +#: text - SCH_USER_NAME +msgid "[cases/cases_Scheduler_New.xml?SCH_USER_NAME] User Name" +msgstr "User Name" + +# cases/cases_Scheduler_New.xml?SCH_USER_PASSWORD +# cases/cases_Scheduler_New.xml +#: password - SCH_USER_PASSWORD +msgid "[cases/cases_Scheduler_New.xml?SCH_USER_PASSWORD] Password" +msgstr "Password" + +# cases/cases_Scheduler_New.xml?TEST_CONNECTION +# cases/cases_Scheduler_New.xml +#: button - TEST_CONNECTION +msgid "[cases/cases_Scheduler_New.xml?TEST_CONNECTION] Test User" +msgstr "Test User" + +# cases/cases_Scheduler_New.xml?EDIT_USER +# cases/cases_Scheduler_New.xml +#: button - EDIT_USER +msgid "[cases/cases_Scheduler_New.xml?EDIT_USER] Edit User" +msgstr "Edit User" + +# cases/cases_Scheduler_New.xml?PERFORM_TASK +# cases/cases_Scheduler_New.xml +#: subtitle - PERFORM_TASK +msgid "[cases/cases_Scheduler_New.xml?PERFORM_TASK] Properties" +msgstr "Properties" + +# cases/cases_Scheduler_New.xml?TAS_UID +# cases/cases_Scheduler_New.xml +#: dropdown - TAS_UID +msgid "[cases/cases_Scheduler_New.xml?TAS_UID] Task" +msgstr "Task" + +# cases/cases_Scheduler_New.xml?SCH_NAME +# cases/cases_Scheduler_New.xml +#: text - SCH_NAME +msgid "[cases/cases_Scheduler_New.xml?SCH_NAME] Description" +msgstr "Description" + +# cases/cases_Scheduler_New.xml?SCH_OPTION +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION] Perform this task" +msgstr "Perform this task" + +# cases/cases_Scheduler_New.xml?SCH_OPTION-0 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION - 0 +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION-0]" +msgstr "-Select-" + +# cases/cases_Scheduler_New.xml?SCH_OPTION-1 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION-1]" +msgstr "Daily" + +# cases/cases_Scheduler_New.xml?SCH_OPTION-2 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION-2]" +msgstr "Weekly" + +# cases/cases_Scheduler_New.xml?SCH_OPTION-3 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION - 3 +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION-3]" +msgstr "Monthly" + +# cases/cases_Scheduler_New.xml?SCH_OPTION-4 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_OPTION - 4 +msgid "[cases/cases_Scheduler_New.xml?SCH_OPTION-4]" +msgstr "One time only" + +# cases/cases_Scheduler_New.xml?SELECT_TIME_DAY +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_TIME_DAY +msgid "[cases/cases_Scheduler_New.xml?SELECT_TIME_DAY] Select the time and day you want this task to start." +msgstr "Select the time and day you want this task to start." + +# cases/cases_Scheduler_New.xml?SCH_START_TIME +# cases/cases_Scheduler_New.xml +#: text - SCH_START_TIME +msgid "[cases/cases_Scheduler_New.xml?SCH_START_TIME] Execution time" +msgstr "Execution time" + +# cases/cases_Scheduler_New.xml?SELECT_DATE +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_DATE +msgid "[cases/cases_Scheduler_New.xml?SELECT_DATE] Select date" +msgstr "Select date" + +# cases/cases_Scheduler_New.xml?SCH_START_DATE +# cases/cases_Scheduler_New.xml +#: date - SCH_START_DATE +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DATE] Start date" +msgstr "Start date" + +# cases/cases_Scheduler_New.xml?SELECT_1 +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_1 +msgid "[cases/cases_Scheduler_New.xml?SELECT_1] Daily" +msgstr "Daily" + +# cases/cases_Scheduler_New.xml?SELECT_2 +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_2 +msgid "[cases/cases_Scheduler_New.xml?SELECT_2] Weekly" +msgstr "Weekly" + +# cases/cases_Scheduler_New.xml?SCH_EVERY_DAYS +# cases/cases_Scheduler_New.xml +#: text - SCH_EVERY_DAYS +msgid "[cases/cases_Scheduler_New.xml?SCH_EVERY_DAYS] Every" +msgstr "Every" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS] Select the day(s) of the week below" +msgstr "Select the day(s) of the week below" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-1 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-1]" +msgstr "Monday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-2 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-2]" +msgstr "Tuesday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-3 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS - 3 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-3]" +msgstr "Wednesday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-4 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS - 4 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS-4]" +msgstr "Thursday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS_2 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-5 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 5 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-5]" +msgstr "Friday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-6 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 6 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-6]" +msgstr "Saturday" + +# cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-7 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_WEEK_DAYS_2 - 7 +msgid "[cases/cases_Scheduler_New.xml?SCH_WEEK_DAYS_2-7]" +msgstr "Sunday" + +# cases/cases_Scheduler_New.xml?SELECT_3 +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_3 +msgid "[cases/cases_Scheduler_New.xml?SELECT_3] Monthly" +msgstr "Monthly" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY +# cases/cases_Scheduler_New.xml +#: radiogroup - SCH_START_DAY +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY-1 +# cases/cases_Scheduler_New.xml +#: radiogroup - SCH_START_DAY - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY-1]" +msgstr "Day of month" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY-2 +# cases/cases_Scheduler_New.xml +#: radiogroup - SCH_START_DAY - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY-2]" +msgstr "The day " + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_1 +# cases/cases_Scheduler_New.xml +#: text - SCH_START_DAY_OPT_1 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_1]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-1 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-1]" +msgstr "First" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-2 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-2]" +msgstr "Second" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-3 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 3 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-3]" +msgstr "Third" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-4 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 4 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-4]" +msgstr "Fourth" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-5 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_WEEKS - 5 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_WEEKS-5]" +msgstr "Last" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-1 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-1]" +msgstr "Monday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-2 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-2]" +msgstr "Tuesday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-3 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 3 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-3]" +msgstr "Wednesday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-4 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 4 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-4]" +msgstr "Thursday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-5 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 5 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-5]" +msgstr "Friday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-6 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 6 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-6]" +msgstr "Saturday" + +# cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-7 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_START_DAY_OPT_2_DAYS_WEEK - 7 +msgid "[cases/cases_Scheduler_New.xml?SCH_START_DAY_OPT_2_DAYS_WEEK-7]" +msgstr "Sunday" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS] Of the month(s)" +msgstr "Of the month(s)" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS-1 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS-1]" +msgstr "Jan" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS-2 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS-2]" +msgstr "Feb" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS-3 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS - 3 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS-3]" +msgstr "Mar" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS-4 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS - 4 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS-4]" +msgstr "Apr" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_2 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_2 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_2]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_2-5 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_2 - 5 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_2-5]" +msgstr "May" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_2-6 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_2 - 6 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_2-6]" +msgstr "Jun" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_2-7 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_2 - 7 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_2-7]" +msgstr "Jul" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_2-8 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_2 - 8 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_2-8]" +msgstr "Aug" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_3 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_3 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_3]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_3-9 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_3 - 9 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_3-9]" +msgstr "Sep" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_3-10 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_3 - 10 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_3-10]" +msgstr "Oct" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_3-11 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_3 - 11 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_3-11]" +msgstr "Nov" + +# cases/cases_Scheduler_New.xml?SCH_MONTHS_3-12 +# cases/cases_Scheduler_New.xml +#: checkgroup - SCH_MONTHS_3 - 12 +msgid "[cases/cases_Scheduler_New.xml?SCH_MONTHS_3-12]" +msgstr "Dec" + +# cases/cases_Scheduler_New.xml?SCH_END_DATE +# cases/cases_Scheduler_New.xml +#: date - SCH_END_DATE +msgid "[cases/cases_Scheduler_New.xml?SCH_END_DATE]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_REPEAT_TASK_CHK +# cases/cases_Scheduler_New.xml +#: checkbox - SCH_REPEAT_TASK_CHK +msgid "[cases/cases_Scheduler_New.xml?SCH_REPEAT_TASK_CHK] Repeat Task" +msgstr "Repeat Task" + +# cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY +# cases/cases_Scheduler_New.xml +#: text - SCH_REPEAT_EVERY +msgid "[cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY] Every" +msgstr "Every" + +# cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_REPEAT_EVERY_OPT +msgid "[cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT]" +msgstr "" + +# cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT-1 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_REPEAT_EVERY_OPT - 1 +msgid "[cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT-1]" +msgstr "Minutes" + +# cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT-2 +# cases/cases_Scheduler_New.xml +#: dropdown - SCH_REPEAT_EVERY_OPT - 2 +msgid "[cases/cases_Scheduler_New.xml?SCH_REPEAT_EVERY_OPT-2]" +msgstr "Hours" + +# cases/cases_Scheduler_New.xml?SELECT_PLUGIN +# cases/cases_Scheduler_New.xml +#: subtitle - SELECT_PLUGIN +msgid "[cases/cases_Scheduler_New.xml?SELECT_PLUGIN] Start a case based on following registered Plugin." +msgstr "Start a case based on following registered Plugin." + +# cases/cases_Scheduler_New.xml?SAVE +# cases/cases_Scheduler_New.xml +#: submit - SAVE +msgid "[cases/cases_Scheduler_New.xml?SAVE] Save" +msgstr "Save" + +# cases/cases_Scheduler_NewOptions.xml?MNU +# cases/cases_Scheduler_NewOptions.xml +#: link - MNU +msgid "Back to list" +msgstr "Back to list" + +# cases/cases_Scheduler_Options.xml?MNU_ADD +# cases/cases_Scheduler_Options.xml +#: link - MNU_ADD +msgid "[cases/cases_Scheduler_Options.xml?MNU_ADD] New" +msgstr "New" + +# cases/cases_Scheduler_Options.xml?PAGED_TABLE_FAST_SEARCH +# cases/cases_Scheduler_Options.xml +#: fastsearch - PAGED_TABLE_FAST_SEARCH +msgid "[cases/cases_Scheduler_Options.xml?PAGED_TABLE_FAST_SEARCH]" +msgstr "" + +# cases/cases_TaskDetails.xml?TASK +# cases/cases_TaskDetails.xml +#: text - TASK +msgid "[cases/cases_TaskDetails.xml?TASK] Title" +msgstr "Title" + +# cases/cases_TaskDetails.xml?USER +# cases/cases_TaskDetails.xml +#: text - USER +msgid "[cases/cases_TaskDetails.xml?USER] User" +msgstr "User" + +# cases/cases_TaskDetails.xml?INIT_DATE +# cases/cases_TaskDetails.xml +#: date - INIT_DATE +msgid "Init Date" +msgstr "Init Date" + +# cases/cases_TaskDetails.xml?DUE_DATE +# cases/cases_TaskDetails.xml +#: date - DUE_DATE +msgid "Due date" +msgstr "Due date" + +# cases/cases_TaskDetails.xml?FINISH +# cases/cases_TaskDetails.xml +#: text - FINISH +msgid "Finish date" +msgstr "Finish date" + +# cases/cases_TaskDetails.xml?DURATION +# cases/cases_TaskDetails.xml +#: text - DURATION +msgid "Duration" +msgstr "Duration" + +# cases/cases_TaskInformation.xml?TAS_TITLE +# cases/cases_TaskInformation.xml +#: text - TAS_TITLE +msgid "[cases/cases_TaskInformation.xml?TAS_TITLE] Title" +msgstr "Title" + +# cases/cases_TaskInformation.xml?TAS_DESCRIPTION +# cases/cases_TaskInformation.xml +#: textarea - TAS_DESCRIPTION +msgid "[cases/cases_TaskInformation.xml?TAS_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_TaskInformation.xml?INIT_DATE +# cases/cases_TaskInformation.xml +#: date - INIT_DATE +msgid "[cases/cases_TaskInformation.xml?INIT_DATE] Init Date" +msgstr "Init Date" + +# cases/cases_TaskInformation.xml?DUE_DATE +# cases/cases_TaskInformation.xml +#: date - DUE_DATE +msgid "[cases/cases_TaskInformation.xml?DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_TaskInformation.xml?FINISH +# cases/cases_TaskInformation.xml +#: text - FINISH +msgid "[cases/cases_TaskInformation.xml?FINISH] Finish date" +msgstr "Finish date" + +# cases/cases_TaskInformation.xml?DURATION +# cases/cases_TaskInformation.xml +#: text - DURATION +msgid "[cases/cases_TaskInformation.xml?DURATION] Duration" +msgstr "Duration" + +# cases/cases_ToReassignByUserList.xml?APP_UID +# cases/cases_ToReassignByUserList.xml +#: checkboxtable - APP_UID +msgid "[cases/cases_ToReassignByUserList.xml?APP_UID]" +msgstr "" + +# cases/cases_ToReassignByUserList.xml?APP_NUMBER +# cases/cases_ToReassignByUserList.xml +#: text - APP_NUMBER +msgid "[cases/cases_ToReassignByUserList.xml?APP_NUMBER] Case #" +msgstr "Case #" + +# cases/cases_ToReassignByUserList.xml?APP_TAS_TITLE +# cases/cases_ToReassignByUserList.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ToReassignByUserList.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ToReassignByUserList.xml?APP_PRO_TITLE +# cases/cases_ToReassignByUserList.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ToReassignByUserList.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY] Priority" +msgstr "Priority" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-1 +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY - 1 +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-1]" +msgstr "Very High" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-2 +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY - 2 +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-2]" +msgstr "High" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-3 +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY - 3 +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-3]" +msgstr "Normal" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-4 +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY - 4 +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-4]" +msgstr "Low" + +# cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-5 +# cases/cases_ToReassignByUserList.xml +#: dropdown - DEL_PRIORITY - 5 +msgid "[cases/cases_ToReassignByUserList.xml?DEL_PRIORITY-5]" +msgstr "Very Low" + +# cases/cases_ToReassignByUserList.xml?DEL_INIT_DATE +# cases/cases_ToReassignByUserList.xml +#: text - DEL_INIT_DATE +msgid "Init. date" +msgstr "Init. date" + +# cases/cases_ToReassignByUserList.xml?DEL_TASK_DUE_DATE +# cases/cases_ToReassignByUserList.xml +#: text - DEL_TASK_DUE_DATE +msgid "[cases/cases_ToReassignByUserList.xml?DEL_TASK_DUE_DATE] Due date" +msgstr "Due date" + +# cases/cases_ToReassignByUserList.xml?APP_STATUS +# cases/cases_ToReassignByUserList.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ToReassignByUserList.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ToReassignByUserList.xml?APP_STATUS-TO_DO +# cases/cases_ToReassignByUserList.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ToReassignByUserList.xml?APP_STATUS-TO_DO]" +msgstr "TODO" + +# cases/cases_ToReassignByUserList.xml?APP_STATUS-DRAFT +# cases/cases_ToReassignByUserList.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ToReassignByUserList.xml?APP_STATUS-DRAFT]" +msgstr "DRAFT" + +# cases/cases_ToReassignByUserList2.xml?APP_NUMBER +# cases/cases_ToReassignByUserList2.xml +#: text - APP_NUMBER +msgid "[cases/cases_ToReassignByUserList2.xml?APP_NUMBER] Case #" +msgstr "Case #" + +# cases/cases_ToReassignByUserList2.xml?APP_TAS_TITLE +# cases/cases_ToReassignByUserList2.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_ToReassignByUserList2.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_ToReassignByUserList2.xml?APP_PRO_TITLE +# cases/cases_ToReassignByUserList2.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_ToReassignByUserList2.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_ToReassignByUserList2.xml?APP_STATUS +# cases/cases_ToReassignByUserList2.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_ToReassignByUserList2.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_ToReassignByUserList2.xml?APP_STATUS-TO_DO +# cases/cases_ToReassignByUserList2.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_ToReassignByUserList2.xml?APP_STATUS-TO_DO]" +msgstr "TODO" + +# cases/cases_ToReassignByUserList2.xml?APP_STATUS-DRAFT +# cases/cases_ToReassignByUserList2.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_ToReassignByUserList2.xml?APP_STATUS-DRAFT]" +msgstr "DRAFT" + +# cases/cases_ToReassignByUserList2.xml?USERS +# cases/cases_ToReassignByUserList2.xml +#: dropdownpt - USERS +msgid "Reassign to" +msgstr "Reassign to" + +# cases/cases_ToReviseInputdocsList.xml?TITLE +# cases/cases_ToReviseInputdocsList.xml +#: text - TITLE +msgid "[cases/cases_ToReviseInputdocsList.xml?TITLE] Title" +msgstr "Title" + +# cases/cases_ToReviseInputdocsList.xml?DOC_VERSION_LABEL +# cases/cases_ToReviseInputdocsList.xml +#: text - DOC_VERSION_LABEL +msgid "[cases/cases_ToReviseInputdocsList.xml?DOC_VERSION_LABEL] Version" +msgstr "Version" + +# cases/cases_ToReviseInputdocsList.xml?CREATOR +# cases/cases_ToReviseInputdocsList.xml +#: text - CREATOR +msgid "[cases/cases_ToReviseInputdocsList.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ToReviseInputdocsList.xml?COMMENT +# cases/cases_ToReviseInputdocsList.xml +#: text - COMMENT +msgid "[cases/cases_ToReviseInputdocsList.xml?COMMENT] Comment" +msgstr "Comment" + +# cases/cases_ToReviseInputdocsList.xml?APP_DOC_CREATE_DATE +# cases/cases_ToReviseInputdocsList.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ToReviseInputdocsList.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ToReviseInputdocsList.xml?DOWNLOAD +# cases/cases_ToReviseInputdocsList.xml +#: link - DOWNLOAD +msgid "[cases/cases_ToReviseInputdocsList.xml?DOWNLOAD]" +msgstr "" + +# cases/cases_ToReviseInputdocsList.xml?NEWVERSION +# cases/cases_ToReviseInputdocsList.xml +#: link - NEWVERSION +msgid "[cases/cases_ToReviseInputdocsList.xml?NEWVERSION]" +msgstr "" + +# cases/cases_ToReviseInputdocsList.xml?VERSION_HISTORY +# cases/cases_ToReviseInputdocsList.xml +#: link - VERSION_HISTORY +msgid "[cases/cases_ToReviseInputdocsList.xml?VERSION_HISTORY]" +msgstr "" + +# cases/cases_ToReviseInputdocsList.xml?DELETE +# cases/cases_ToReviseInputdocsList.xml +#: link - DELETE +msgid "[cases/cases_ToReviseInputdocsList.xml?DELETE]" +msgstr "" + +# cases/cases_TransferHistory.xml?TAS_TITLE +# cases/cases_TransferHistory.xml +#: text - TAS_TITLE +msgid "[cases/cases_TransferHistory.xml?TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_TransferHistory.xml?USR_NAME +# cases/cases_TransferHistory.xml +#: text - USR_NAME +msgid "Delegated User" +msgstr "Delegated User" + +# cases/cases_TransferHistory.xml?DEL_DELEGATE_DATE +# cases/cases_TransferHistory.xml +#: date - DEL_DELEGATE_DATE +msgid "Task Transfer Date" +msgstr "Task Transfer Date" + +# cases/cases_TransferHistory.xml?DEL_INIT_DATE +# cases/cases_TransferHistory.xml +#: date - DEL_INIT_DATE +msgid "[cases/cases_TransferHistory.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_TransferHistory.xml?DEL_FINISH_DATE +# cases/cases_TransferHistory.xml +#: date - DEL_FINISH_DATE +msgid "[cases/cases_TransferHistory.xml?DEL_FINISH_DATE] End Date" +msgstr "End Date" + +# cases/cases_TransferHistory.xml?APP_TYPE +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE +msgid "[cases/cases_TransferHistory.xml?APP_TYPE] Action" +msgstr "Action" + +# cases/cases_TransferHistory.xml?APP_TYPE-PAUSE +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE - PAUSE +msgid "[cases/cases_TransferHistory.xml?APP_TYPE-PAUSE]" +msgstr "Paused" + +# cases/cases_TransferHistory.xml?APP_TYPE-CANCEL +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE - CANCEL +msgid "[cases/cases_TransferHistory.xml?APP_TYPE-CANCEL]" +msgstr "Cancelled" + +# cases/cases_TransferHistory.xml?APP_TYPE-IN_PROGRESS +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE - IN_PROGRESS +msgid "[cases/cases_TransferHistory.xml?APP_TYPE-IN_PROGRESS]" +msgstr "In Progress" + +# cases/cases_TransferHistory.xml?APP_TYPE-'' +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE - '' +msgid "[cases/cases_TransferHistory.xml?APP_TYPE-'']" +msgstr "Derivated" + +# cases/cases_TransferHistory.xml?APP_TYPE-REASSIGN +# cases/cases_TransferHistory.xml +#: dropdown - APP_TYPE - REASSIGN +msgid "[cases/cases_TransferHistory.xml?APP_TYPE-REASSIGN]" +msgstr "Reassigned" + +# cases/cases_TransferHistory.xml?APP_ENABLE_ACTION_DATE +# cases/cases_TransferHistory.xml +#: text - APP_ENABLE_ACTION_DATE +msgid "Enable Action" +msgstr "Enable Action" + +# cases/cases_TransferHistory.xml?APP_DISABLE_ACTION_DATE +# cases/cases_TransferHistory.xml +#: text - APP_DISABLE_ACTION_DATE +msgid "Disable Action" +msgstr "Disable Action" + +# cases/cases_TransferHistory.xml?CASE_HISTORY +# cases/cases_TransferHistory.xml +#: link - CASE_HISTORY +msgid "[cases/cases_TransferHistory.xml?CASE_HISTORY]" +msgstr "" + +# cases/cases_UnpauseDateInput.xml?title1 +# cases/cases_UnpauseDateInput.xml +#: title - title1 +msgid "Pause on: @#TIME_STAMP<br/>" +msgstr "Pause on: @#TIME_STAMP<br/>" + +# cases/cases_UnpauseDateInput.xml?unpause_date +# cases/cases_UnpauseDateInput.xml +#: date - unpause_date +msgid "Unpause date" +msgstr "Unpause date" + +# cases/cases_UnpauseDateInput.xml?pause_exec +# cases/cases_UnpauseDateInput.xml +#: button - pause_exec +msgid "[cases/cases_UnpauseDateInput.xml?pause_exec] Pause" +msgstr "Pause" + +# cases/cases_ViewAnyInputDocument.xml?FILENAME +# cases/cases_ViewAnyInputDocument.xml +#: caption - FILENAME +msgid "[cases/cases_ViewAnyInputDocument.xml?FILENAME] Filename" +msgstr "Filename" + +# cases/cases_ViewAnyInputDocument.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewAnyInputDocument.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewAnyInputDocument.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewAnyInputDocument.xml?CREATOR +# cases/cases_ViewAnyInputDocument.xml +#: text - CREATOR +msgid "[cases/cases_ViewAnyInputDocument.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewAnyInputDocument.xml?ORIGIN +# cases/cases_ViewAnyInputDocument.xml +#: text - ORIGIN +msgid "[cases/cases_ViewAnyInputDocument.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_ViewAnyInputDocument.xml?APP_DOC_FILENAME +# cases/cases_ViewAnyInputDocument.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewAnyInputDocument.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_TITLE +# cases/cases_ViewAnyInputDocument1.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewAnyInputDocument1.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewAnyInputDocument1.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewAnyInputDocument1.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewAnyInputDocument1.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewAnyInputDocument1.xml?CREATOR +# cases/cases_ViewAnyInputDocument1.xml +#: text - CREATOR +msgid "[cases/cases_ViewAnyInputDocument1.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewAnyInputDocument1.xml?ORIGIN +# cases/cases_ViewAnyInputDocument1.xml +#: text - ORIGIN +msgid "[cases/cases_ViewAnyInputDocument1.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_ViewAnyInputDocument1.xml?APP_DOC_FILENAME +# cases/cases_ViewAnyInputDocument1.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewAnyInputDocument1.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_TITLE +# cases/cases_ViewAnyInputDocument2.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewAnyInputDocument2.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewAnyInputDocument2.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewAnyInputDocument2.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewAnyInputDocument2.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewAnyInputDocument2.xml?CREATOR +# cases/cases_ViewAnyInputDocument2.xml +#: text - CREATOR +msgid "[cases/cases_ViewAnyInputDocument2.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewAnyInputDocument2.xml?ORIGIN +# cases/cases_ViewAnyInputDocument2.xml +#: text - ORIGIN +msgid "[cases/cases_ViewAnyInputDocument2.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_ViewAnyInputDocument2.xml?APP_DOC_COMMENT +# cases/cases_ViewAnyInputDocument2.xml +#: caption - APP_DOC_COMMENT +msgid "[cases/cases_ViewAnyInputDocument2.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_TITLE +# cases/cases_ViewAnyInputDocument3.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewAnyInputDocument3.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewAnyInputDocument3.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewAnyInputDocument3.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewAnyInputDocument3.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewAnyInputDocument3.xml?CREATOR +# cases/cases_ViewAnyInputDocument3.xml +#: text - CREATOR +msgid "[cases/cases_ViewAnyInputDocument3.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewAnyInputDocument3.xml?ORIGIN +# cases/cases_ViewAnyInputDocument3.xml +#: text - ORIGIN +msgid "[cases/cases_ViewAnyInputDocument3.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_ViewAnyInputDocument3.xml?APP_DOC_COMMENT +# cases/cases_ViewAnyInputDocument3.xml +#: caption - APP_DOC_COMMENT +msgid "[cases/cases_ViewAnyInputDocument3.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_ViewAnyInputDocument3.xml?APP_DOC_FILENAME +# cases/cases_ViewAnyInputDocument3.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewAnyInputDocument3.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewAnyOutputDocument.xml?OUT_DOC_TITLE +# cases/cases_ViewAnyOutputDocument.xml +#: caption - OUT_DOC_TITLE +msgid "Output document" +msgstr "Output document" + +# cases/cases_ViewAnyOutputDocument.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewAnyOutputDocument.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewAnyOutputDocument.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_ViewAnyOutputDocument.xml?APP_DOC_FILENAME1 +# cases/cases_ViewAnyOutputDocument.xml +#: link - APP_DOC_FILENAME1 +msgid "File (.doc)" +msgstr "File (.doc)" + +# cases/cases_ViewAnyOutputDocument.xml?APP_DOC_FILENAME2 +# cases/cases_ViewAnyOutputDocument.xml +#: link - APP_DOC_FILENAME2 +msgid "File (.pdf)" +msgstr "File (.pdf)" + +# cases/cases_ViewAnyOutputDocument.xml?CREATOR +# cases/cases_ViewAnyOutputDocument.xml +#: text - CREATOR +msgid "[cases/cases_ViewAnyOutputDocument.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewAnyOutputDocument.xml?ORIGIN +# cases/cases_ViewAnyOutputDocument.xml +#: text - ORIGIN +msgid "[cases/cases_ViewAnyOutputDocument.xml?ORIGIN] Origin Task" +msgstr "Origin Task" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_TITLE +# cases/cases_ViewInputDocument1.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewInputDocument1.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewInputDocument1.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewInputDocument1.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewInputDocument1.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewInputDocument1.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewInputDocument1.xml?CREATOR +# cases/cases_ViewInputDocument1.xml +#: text - CREATOR +msgid "[cases/cases_ViewInputDocument1.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewInputDocument1.xml?APP_DOC_FILENAME +# cases/cases_ViewInputDocument1.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewInputDocument1.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewInputDocument1.xml?BACK +# cases/cases_ViewInputDocument1.xml +#: button - BACK +msgid "Back" +msgstr "Back" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_TITLE +# cases/cases_ViewInputDocument2.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewInputDocument2.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewInputDocument2.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewInputDocument2.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewInputDocument2.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewInputDocument2.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewInputDocument2.xml?CREATOR +# cases/cases_ViewInputDocument2.xml +#: text - CREATOR +msgid "[cases/cases_ViewInputDocument2.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewInputDocument2.xml?APP_DOC_COMMENT +# cases/cases_ViewInputDocument2.xml +#: caption - APP_DOC_COMMENT +msgid "[cases/cases_ViewInputDocument2.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_ViewInputDocument2.xml?BACK +# cases/cases_ViewInputDocument2.xml +#: button - BACK +msgid "[cases/cases_ViewInputDocument2.xml?BACK] Back" +msgstr "Back" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_TITLE +# cases/cases_ViewInputDocument3.xml +#: caption - INP_DOC_TITLE +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_DESCRIPTION +# cases/cases_ViewInputDocument3.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewInputDocument3.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewInputDocument3.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewInputDocument3.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewInputDocument3.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewInputDocument3.xml?CREATOR +# cases/cases_ViewInputDocument3.xml +#: text - CREATOR +msgid "[cases/cases_ViewInputDocument3.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewInputDocument3.xml?APP_DOC_COMMENT +# cases/cases_ViewInputDocument3.xml +#: caption - APP_DOC_COMMENT +msgid "[cases/cases_ViewInputDocument3.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# cases/cases_ViewInputDocument3.xml?APP_DOC_FILENAME +# cases/cases_ViewInputDocument3.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewInputDocument3.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewInputDocument3.xml?BACK +# cases/cases_ViewInputDocument3.xml +#: button - BACK +msgid "[cases/cases_ViewInputDocument3.xml?BACK] Back" +msgstr "Back" + +# cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_TITLE +# cases/cases_ViewInputDocumentToRevise.xml +#: caption - APP_DOC_TITLE +msgid "[cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_TITLE] Title" +msgstr "Title" + +# cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_COMMENT +# cases/cases_ViewInputDocumentToRevise.xml +#: caption - APP_DOC_COMMENT +msgid "[cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_COMMENT] Comment" +msgstr "Comment" + +# cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_TYPE +# cases/cases_ViewInputDocumentToRevise.xml +#: text - APP_DOC_TYPE +msgid "[cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_TYPE] Type" +msgstr "Type" + +# cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL +# cases/cases_ViewInputDocumentToRevise.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-ORIGINAL +# cases/cases_ViewInputDocumentToRevise.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-COPYLEGAL +# cases/cases_ViewInputDocumentToRevise.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-COPY +# cases/cases_ViewInputDocumentToRevise.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[cases/cases_ViewInputDocumentToRevise.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewInputDocumentToRevise.xml +#: date - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# cases/cases_ViewInputDocumentToRevise.xml?CREATOR +# cases/cases_ViewInputDocumentToRevise.xml +#: text - CREATOR +msgid "[cases/cases_ViewInputDocumentToRevise.xml?CREATOR] Creator" +msgstr "Creator" + +# cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_FILENAME +# cases/cases_ViewInputDocumentToRevise.xml +#: link - APP_DOC_FILENAME +msgid "[cases/cases_ViewInputDocumentToRevise.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# cases/cases_ViewInputDocumentToRevise.xml?BACK +# cases/cases_ViewInputDocumentToRevise.xml +#: button - BACK +msgid "[cases/cases_ViewInputDocumentToRevise.xml?BACK] Back" +msgstr "Back" + +# cases/cases_ViewOutputDocument1.xml?OUT_DOC_TITLE +# cases/cases_ViewOutputDocument1.xml +#: caption - OUT_DOC_TITLE +msgid "[cases/cases_ViewOutputDocument1.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# cases/cases_ViewOutputDocument1.xml?OUT_DOC_DESCRIPTION +# cases/cases_ViewOutputDocument1.xml +#: caption - OUT_DOC_DESCRIPTION +msgid "[cases/cases_ViewOutputDocument1.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewOutputDocument1.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewOutputDocument1.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewOutputDocument1.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_ViewOutputDocument1.xml?APP_DOC_FILENAME1 +# cases/cases_ViewOutputDocument1.xml +#: link - APP_DOC_FILENAME1 +msgid "[cases/cases_ViewOutputDocument1.xml?APP_DOC_FILENAME1] File (.doc)" +msgstr "File (.doc)" + +# cases/cases_ViewOutputDocument1.xml?APP_DOC_FILENAME2 +# cases/cases_ViewOutputDocument1.xml +#: link - APP_DOC_FILENAME2 +msgid "[cases/cases_ViewOutputDocument1.xml?APP_DOC_FILENAME2] File (.pdf)" +msgstr "File (.pdf)" + +# cases/cases_ViewOutputDocument1.xml?NEXT_STEP +# cases/cases_ViewOutputDocument1.xml +#: button - NEXT_STEP +msgid "Next step" +msgstr "Next step" + +# cases/cases_ViewOutputDocument2.xml?OUT_DOC_TITLE +# cases/cases_ViewOutputDocument2.xml +#: caption - OUT_DOC_TITLE +msgid "[cases/cases_ViewOutputDocument2.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# cases/cases_ViewOutputDocument2.xml?OUT_DOC_DESCRIPTION +# cases/cases_ViewOutputDocument2.xml +#: caption - OUT_DOC_DESCRIPTION +msgid "[cases/cases_ViewOutputDocument2.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewOutputDocument2.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewOutputDocument2.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewOutputDocument2.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_ViewOutputDocument2.xml?APP_DOC_FILENAME1 +# cases/cases_ViewOutputDocument2.xml +#: link - APP_DOC_FILENAME1 +msgid "[cases/cases_ViewOutputDocument2.xml?APP_DOC_FILENAME1] File (.doc)" +msgstr "File (.doc)" + +# cases/cases_ViewOutputDocument2.xml?NEXT_STEP +# cases/cases_ViewOutputDocument2.xml +#: button - NEXT_STEP +msgid "[cases/cases_ViewOutputDocument2.xml?NEXT_STEP] Next step" +msgstr "Next step" + +# cases/cases_ViewOutputDocument3.xml?OUT_DOC_TITLE +# cases/cases_ViewOutputDocument3.xml +#: caption - OUT_DOC_TITLE +msgid "[cases/cases_ViewOutputDocument3.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# cases/cases_ViewOutputDocument3.xml?OUT_DOC_DESCRIPTION +# cases/cases_ViewOutputDocument3.xml +#: caption - OUT_DOC_DESCRIPTION +msgid "[cases/cases_ViewOutputDocument3.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewOutputDocument3.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewOutputDocument3.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewOutputDocument3.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_ViewOutputDocument3.xml?APP_DOC_FILENAME2 +# cases/cases_ViewOutputDocument3.xml +#: link - APP_DOC_FILENAME2 +msgid "[cases/cases_ViewOutputDocument3.xml?APP_DOC_FILENAME2] File (.pdf)" +msgstr "File (.pdf)" + +# cases/cases_ViewOutputDocument3.xml?NEXT_STEP +# cases/cases_ViewOutputDocument3.xml +#: button - NEXT_STEP +msgid "[cases/cases_ViewOutputDocument3.xml?NEXT_STEP] Next step" +msgstr "Next step" + +# cases/cases_ViewOutputDocumentToRevise.xml?OUT_DOC_TITLE +# cases/cases_ViewOutputDocumentToRevise.xml +#: caption - OUT_DOC_TITLE +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# cases/cases_ViewOutputDocumentToRevise.xml?OUT_DOC_DESCRIPTION +# cases/cases_ViewOutputDocumentToRevise.xml +#: caption - OUT_DOC_DESCRIPTION +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_CREATE_DATE +# cases/cases_ViewOutputDocumentToRevise.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_FILENAME1 +# cases/cases_ViewOutputDocumentToRevise.xml +#: link - APP_DOC_FILENAME1 +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_FILENAME1] File (.doc)" +msgstr "File (.doc)" + +# cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_FILENAME2 +# cases/cases_ViewOutputDocumentToRevise.xml +#: link - APP_DOC_FILENAME2 +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?APP_DOC_FILENAME2] File (.pdf)" +msgstr "File (.pdf)" + +# cases/cases_ViewOutputDocumentToRevise.xml?BACK +# cases/cases_ViewOutputDocumentToRevise.xml +#: button - BACK +msgid "[cases/cases_ViewOutputDocumentToRevise.xml?BACK] Back" +msgstr "Back" + +# cases/cases_advancedSearch.xml?APP_NUMBER +# cases/cases_advancedSearch.xml +#: text - APP_NUMBER +msgid "[cases/cases_advancedSearch.xml?APP_NUMBER] #" +msgstr "#" + +# cases/cases_advancedSearch.xml?APP_TITLE +# cases/cases_advancedSearch.xml +#: text - APP_TITLE +msgid "[cases/cases_advancedSearch.xml?APP_TITLE] Case" +msgstr "Case" + +# cases/cases_advancedSearch.xml?APP_TAS_TITLE +# cases/cases_advancedSearch.xml +#: text - APP_TAS_TITLE +msgid "[cases/cases_advancedSearch.xml?APP_TAS_TITLE] Task" +msgstr "Task" + +# cases/cases_advancedSearch.xml?APP_PRO_TITLE +# cases/cases_advancedSearch.xml +#: text - APP_PRO_TITLE +msgid "[cases/cases_advancedSearch.xml?APP_PRO_TITLE] Process" +msgstr "Process" + +# cases/cases_advancedSearch.xml?APP_CURRENT_USER +# cases/cases_advancedSearch.xml +#: text - APP_CURRENT_USER +msgid "[cases/cases_advancedSearch.xml?APP_CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_advancedSearch.xml?APP_DEL_PREVIOUS_USER +# cases/cases_advancedSearch.xml +#: text - APP_DEL_PREVIOUS_USER +msgid "[cases/cases_advancedSearch.xml?APP_DEL_PREVIOUS_USER] Sent by" +msgstr "Sent by" + +# cases/cases_advancedSearch.xml?DEL_TASK_DUE_DATE +# cases/cases_advancedSearch.xml +#: date - DEL_TASK_DUE_DATE +msgid "[cases/cases_advancedSearch.xml?DEL_TASK_DUE_DATE] Due Date" +msgstr "Due Date" + +# cases/cases_advancedSearch.xml?APP_UPDATE_DATE +# cases/cases_advancedSearch.xml +#: date - APP_UPDATE_DATE +msgid "Last Modification" +msgstr "Last Modification" + +# cases/cases_advancedSearch.xml?DEL_INIT_DATE +# cases/cases_advancedSearch.xml +#: date - DEL_INIT_DATE +msgid "[cases/cases_advancedSearch.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# cases/cases_advancedSearch.xml?DEL_FINISH_DATE +# cases/cases_advancedSearch.xml +#: date - DEL_FINISH_DATE +msgid "[cases/cases_advancedSearch.xml?DEL_FINISH_DATE] Finish Date" +msgstr "Finish Date" + +# cases/cases_advancedSearch.xml?APP_STATUS +# cases/cases_advancedSearch.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_advancedSearch.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_advancedSearch.xml?APP_STATUS-DRAFT +# cases/cases_advancedSearch.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_advancedSearch.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_advancedSearch.xml?APP_STATUS-TO_DO +# cases/cases_advancedSearch.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_advancedSearch.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_advancedSearch.xml?APP_STATUS-CANCELLED +# cases/cases_advancedSearch.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_advancedSearch.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_advancedSearch.xml?APP_STATUS-COMPLETED +# cases/cases_advancedSearch.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_advancedSearch.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_advancedSearch.xml?OPEN +# cases/cases_advancedSearch.xml +#: link - OPEN +msgid "[cases/cases_advancedSearch.xml?OPEN]" +msgstr "" + +# cases/cases_advancedSearch.xml?SEARCH +# cases/cases_advancedSearch.xml +#: button - SEARCH +msgid "[cases/cases_advancedSearch.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# cases/cases_advancedSearchFilter.xml?CASE_NUMBER +# cases/cases_advancedSearchFilter.xml +#: text - CASE_NUMBER +msgid "[cases/cases_advancedSearchFilter.xml?CASE_NUMBER] Case Number" +msgstr "Case Number" + +# cases/cases_advancedSearchFilter.xml?PROCESS +# cases/cases_advancedSearchFilter.xml +#: dropdown - PROCESS +msgid "[cases/cases_advancedSearchFilter.xml?PROCESS] Process" +msgstr "Process" + +# cases/cases_advancedSearchFilter.xml?PROCESS-'' +# cases/cases_advancedSearchFilter.xml +#: dropdown - PROCESS - '' +msgid "[cases/cases_advancedSearchFilter.xml?PROCESS-'']" +msgstr "All" + +# cases/cases_advancedSearchFilter.xml?TASKS +# cases/cases_advancedSearchFilter.xml +#: dropdown - TASKS +msgid "Tasks" +msgstr "Tasks" + +# cases/cases_advancedSearchFilter.xml?TASKS-'' +# cases/cases_advancedSearchFilter.xml +#: dropdown - TASKS - '' +msgid "[cases/cases_advancedSearchFilter.xml?TASKS-'']" +msgstr "All" + +# cases/cases_advancedSearchFilter.xml?CURRENT_USER +# cases/cases_advancedSearchFilter.xml +#: dropdown - CURRENT_USER +msgid "[cases/cases_advancedSearchFilter.xml?CURRENT_USER] Current User" +msgstr "Current User" + +# cases/cases_advancedSearchFilter.xml?CURRENT_USER-'' +# cases/cases_advancedSearchFilter.xml +#: dropdown - CURRENT_USER - '' +msgid "[cases/cases_advancedSearchFilter.xml?CURRENT_USER-'']" +msgstr "All" + +# cases/cases_advancedSearchFilter.xml?SENT_BY +# cases/cases_advancedSearchFilter.xml +#: dropdown - SENT_BY +msgid "[cases/cases_advancedSearchFilter.xml?SENT_BY] Sent by" +msgstr "Sent by" + +# cases/cases_advancedSearchFilter.xml?SENT_BY-'' +# cases/cases_advancedSearchFilter.xml +#: dropdown - SENT_BY - '' +msgid "[cases/cases_advancedSearchFilter.xml?SENT_BY-'']" +msgstr "All" + +# cases/cases_advancedSearchFilter.xml?LAST_MODIFICATION_F +# cases/cases_advancedSearchFilter.xml +#: date - LAST_MODIFICATION_F +msgid "[cases/cases_advancedSearchFilter.xml?LAST_MODIFICATION_F] From" +msgstr "From" + +# cases/cases_advancedSearchFilter.xml?LAST_MODIFICATION_T +# cases/cases_advancedSearchFilter.xml +#: date - LAST_MODIFICATION_T +msgid "[cases/cases_advancedSearchFilter.xml?LAST_MODIFICATION_T] To" +msgstr "To" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS] Status" +msgstr "Status" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS-'' +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS - '' +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS-'']" +msgstr "All" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS-DRAFT +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS - DRAFT +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS-DRAFT]" +msgstr "Draft" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS-TO_DO +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS - TO_DO +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS-TO_DO]" +msgstr "To Do" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS-CANCELLED +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS - CANCELLED +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS-CANCELLED]" +msgstr "Cancelled" + +# cases/cases_advancedSearchFilter.xml?APP_STATUS-COMPLETED +# cases/cases_advancedSearchFilter.xml +#: dropdown - APP_STATUS - COMPLETED +msgid "[cases/cases_advancedSearchFilter.xml?APP_STATUS-COMPLETED]" +msgstr "Completed" + +# cases/cases_advancedSearchFilter.xml?FILTER +# cases/cases_advancedSearchFilter.xml +#: submit - FILTER +msgid "[cases/cases_advancedSearchFilter.xml?FILTER] Filter" +msgstr "Filter" + +# dashboard/dashboard_AvailableDashboards.xml?TITLE +# dashboard/dashboard_AvailableDashboards.xml +#: title - TITLE +msgid "Add availables reports or charts" +msgstr "Add availables reports or charts" + +# dashboard/dashboard_AvailableDashboards.xml?DASHBOARD +# dashboard/dashboard_AvailableDashboards.xml +#: dropdown - DASHBOARD +msgid "Chart or Report" +msgstr "Chart or Report" + +# dashboard/dashboard_AvailableDashboards.xml?BTN_CANCEL +# dashboard/dashboard_AvailableDashboards.xml +#: button - BTN_CANCEL +msgid "[dashboard/dashboard_AvailableDashboards.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dashboard/dashboard_AvailableDashboards.xml?ADD +# dashboard/dashboard_AvailableDashboards.xml +#: button - ADD +msgid "[dashboard/dashboard_AvailableDashboards.xml?ADD] Add" +msgstr "Add" + +# dashboard/dashboard_NoAvailableDashboards.xml?TITLE +# dashboard/dashboard_NoAvailableDashboards.xml +#: title - TITLE +msgid "No availables reports or charts" +msgstr "No availables reports or charts" + +# dashboard/dashboard_NoAvailableDashboards.xml?CLOSE +# dashboard/dashboard_NoAvailableDashboards.xml +#: button - CLOSE +msgid "Close" +msgstr "Close" + +# dbConnections/dbConnections.xml?DBS_TYPE +# dbConnections/dbConnections.xml +#: text - DBS_TYPE +msgid "[dbConnections/dbConnections.xml?DBS_TYPE] Type" +msgstr "Type" + +# dbConnections/dbConnections.xml?DBS_SERVER +# dbConnections/dbConnections.xml +#: text - DBS_SERVER +msgid "Server" +msgstr "Server" + +# dbConnections/dbConnections.xml?DBS_DATABASE_NAME +# dbConnections/dbConnections.xml +#: text - DBS_DATABASE_NAME +msgid "Database Name" +msgstr "Database Name" + +# dbConnections/dbConnections.xml?DBS_DESCRIPTION +# dbConnections/dbConnections.xml +#: text - DBS_DESCRIPTION +msgid "[dbConnections/dbConnections.xml?DBS_DESCRIPTION] Description" +msgstr "Description" + +# dbConnections/dbConnections.xml?DBS_EDIT +# dbConnections/dbConnections.xml +#: link - DBS_EDIT +msgid "[dbConnections/dbConnections.xml?DBS_EDIT] Edit" +msgstr "Edit" + +# dbConnections/dbConnections.xml?DBS_DELETE +# dbConnections/dbConnections.xml +#: link - DBS_DELETE +msgid "[dbConnections/dbConnections.xml?DBS_DELETE] Delete" +msgstr "Delete" + +# dbConnections/dbConnections.xml?GET_UID +# dbConnections/dbConnections.xml +#: link - GET_UID +msgid "[dbConnections/dbConnections.xml?GET_UID]" +msgstr "" + +# dbConnections/dbConnections_Edit.xml?DBS_UID +# dbConnections/dbConnections_Edit.xml +#: text - DBS_UID +msgid "UID" +msgstr "UID" + +# dbConnections/dbConnections_Edit.xml?DBS_TYPE +# dbConnections/dbConnections_Edit.xml +#: dropdown - DBS_TYPE +msgid "Engine" +msgstr "Engine" + +# dbConnections/dbConnections_Edit.xml?DBS_TYPE-'' +# dbConnections/dbConnections_Edit.xml +#: dropdown - DBS_TYPE - '' +msgid "[dbConnections/dbConnections_Edit.xml?DBS_TYPE-'']" +msgstr "..." + +# dbConnections/dbConnections_Edit.xml?DBS_ENCODE +# dbConnections/dbConnections_Edit.xml +#: dropdown - DBS_ENCODE +msgid "Encode" +msgstr "Encode" + +# dbConnections/dbConnections_Edit.xml?DBS_ENCODE-'' +# dbConnections/dbConnections_Edit.xml +#: dropdown - DBS_ENCODE - '' +msgid "[dbConnections/dbConnections_Edit.xml?DBS_ENCODE-'']" +msgstr "..." + +# dbConnections/dbConnections_Edit.xml?DBS_SERVER +# dbConnections/dbConnections_Edit.xml +#: text - DBS_SERVER +msgid "[dbConnections/dbConnections_Edit.xml?DBS_SERVER] Server" +msgstr "Server" + +# dbConnections/dbConnections_Edit.xml?DBS_DATABASE_NAME +# dbConnections/dbConnections_Edit.xml +#: text - DBS_DATABASE_NAME +msgid "[dbConnections/dbConnections_Edit.xml?DBS_DATABASE_NAME] Database Name" +msgstr "Database Name" + +# dbConnections/dbConnections_Edit.xml?DBS_USERNAME +# dbConnections/dbConnections_Edit.xml +#: text - DBS_USERNAME +msgid "Username" +msgstr "Username" + +# dbConnections/dbConnections_Edit.xml?DBS_PASSWORD +# dbConnections/dbConnections_Edit.xml +#: password - DBS_PASSWORD +msgid "[dbConnections/dbConnections_Edit.xml?DBS_PASSWORD] Password" +msgstr "Password" + +# dbConnections/dbConnections_Edit.xml?DBS_PORT +# dbConnections/dbConnections_Edit.xml +#: text - DBS_PORT +msgid "[dbConnections/dbConnections_Edit.xml?DBS_PORT] Port" +msgstr "Port" + +# dbConnections/dbConnections_Edit.xml?DBS_DESCRIPTION +# dbConnections/dbConnections_Edit.xml +#: textarea - DBS_DESCRIPTION +msgid "[dbConnections/dbConnections_Edit.xml?DBS_DESCRIPTION] Description" +msgstr "Description" + +# dbConnections/dbConnections_Edit.xml?TEST +# dbConnections/dbConnections_Edit.xml +#: button - TEST +msgid "Test Connection" +msgstr "Test Connection" + +# dbConnections/dbConnections_Edit.xml?CREATE +# dbConnections/dbConnections_Edit.xml +#: button - CREATE +msgid "[dbConnections/dbConnections_Edit.xml?CREATE] Save" +msgstr "Save" + +# dbConnections/dbConnections_Edit.xml?BTN_CANCEL +# dbConnections/dbConnections_Edit.xml +#: button - BTN_CANCEL +msgid "[dbConnections/dbConnections_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dbConnections/dbConnections_New.xml?DBS_TYPE +# dbConnections/dbConnections_New.xml +#: dropdown - DBS_TYPE +msgid "[dbConnections/dbConnections_New.xml?DBS_TYPE] Engine" +msgstr "Engine" + +# dbConnections/dbConnections_New.xml?DBS_TYPE-'' +# dbConnections/dbConnections_New.xml +#: dropdown - DBS_TYPE - '' +msgid "[dbConnections/dbConnections_New.xml?DBS_TYPE-'']" +msgstr "Select..." + +# dbConnections/dbConnections_New.xml?DBS_ENCODE +# dbConnections/dbConnections_New.xml +#: dropdown - DBS_ENCODE +msgid "[dbConnections/dbConnections_New.xml?DBS_ENCODE] Encode" +msgstr "Encode" + +# dbConnections/dbConnections_New.xml?DBS_ENCODE-'' +# dbConnections/dbConnections_New.xml +#: dropdown - DBS_ENCODE - '' +msgid "[dbConnections/dbConnections_New.xml?DBS_ENCODE-'']" +msgstr "..." + +# dbConnections/dbConnections_New.xml?DBS_SERVER +# dbConnections/dbConnections_New.xml +#: text - DBS_SERVER +msgid "[dbConnections/dbConnections_New.xml?DBS_SERVER] Server" +msgstr "Server" + +# dbConnections/dbConnections_New.xml?DBS_DATABASE_NAME +# dbConnections/dbConnections_New.xml +#: text - DBS_DATABASE_NAME +msgid "[dbConnections/dbConnections_New.xml?DBS_DATABASE_NAME] Database Name" +msgstr "Database Name" + +# dbConnections/dbConnections_New.xml?DBS_USERNAME +# dbConnections/dbConnections_New.xml +#: text - DBS_USERNAME +msgid "[dbConnections/dbConnections_New.xml?DBS_USERNAME] Username" +msgstr "Username" + +# dbConnections/dbConnections_New.xml?DBS_PASSWORD +# dbConnections/dbConnections_New.xml +#: password - DBS_PASSWORD +msgid "[dbConnections/dbConnections_New.xml?DBS_PASSWORD] Password" +msgstr "Password" + +# dbConnections/dbConnections_New.xml?DBS_PORT +# dbConnections/dbConnections_New.xml +#: text - DBS_PORT +msgid "[dbConnections/dbConnections_New.xml?DBS_PORT] Port" +msgstr "Port" + +# dbConnections/dbConnections_New.xml?DBS_DESCRIPTION +# dbConnections/dbConnections_New.xml +#: textarea - DBS_DESCRIPTION +msgid "[dbConnections/dbConnections_New.xml?DBS_DESCRIPTION] Description" +msgstr "Description" + +# dbConnections/dbConnections_New.xml?TEST +# dbConnections/dbConnections_New.xml +#: button - TEST +msgid "[dbConnections/dbConnections_New.xml?TEST] Test Connection" +msgstr "Test Connection" + +# dbConnections/dbConnections_New.xml?CREATE +# dbConnections/dbConnections_New.xml +#: button - CREATE +msgid "[dbConnections/dbConnections_New.xml?CREATE] Create" +msgstr "Create" + +# dbConnections/dbConnections_New.xml?BTN_CANCEL +# dbConnections/dbConnections_New.xml +#: button - BTN_CANCEL +msgid "[dbConnections/dbConnections_New.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dbConnections/dbConnections_Options.xml?MNU_ADD +# dbConnections/dbConnections_Options.xml +#: link - MNU_ADD +msgid "[dbConnections/dbConnections_Options.xml?MNU_ADD] New" +msgstr "New" + +# departments/departments_AddUnAssignedUsers.xml?USR_FIRSTNAME +# departments/departments_AddUnAssignedUsers.xml +#: text - USR_FIRSTNAME +msgid "Firstname" +msgstr "Firstname" + +# departments/departments_AddUnAssignedUsers.xml?USR_LASTNAME +# departments/departments_AddUnAssignedUsers.xml +#: text - USR_LASTNAME +msgid "Lastname" +msgstr "Lastname" + +# departments/departments_AvailableUsers.xml?USR_UID +# departments/departments_AvailableUsers.xml +#: checkboxtable - USR_UID +msgid "[departments/departments_AvailableUsers.xml?USR_UID]" +msgstr "" + +# departments/departments_AvailableUsers.xml?USR_FIRSTNAME +# departments/departments_AvailableUsers.xml +#: text - USR_FIRSTNAME +msgid "[departments/departments_AvailableUsers.xml?USR_FIRSTNAME] Firstname" +msgstr "Firstname" + +# departments/departments_AvailableUsers.xml?USR_LASTNAME +# departments/departments_AvailableUsers.xml +#: text - USR_LASTNAME +msgid "[departments/departments_AvailableUsers.xml?USR_LASTNAME] Lastname" +msgstr "Lastname" + +# departments/departments_Edit.xml?title +# departments/departments_Edit.xml +#: title - title +msgid "Department Information" +msgstr "Department Information" + +# departments/departments_Edit.xml?DEPO_TITLE +# departments/departments_Edit.xml +#: text - DEPO_TITLE +msgid "[departments/departments_Edit.xml?DEPO_TITLE] Name" +msgstr "Name" + +# departments/departments_Edit.xml?DEP_STATUS +# departments/departments_Edit.xml +#: dropdown - DEP_STATUS +msgid "[departments/departments_Edit.xml?DEP_STATUS] Status" +msgstr "Status" + +# departments/departments_Edit.xml?DEP_STATUS-ACTIVE +# departments/departments_Edit.xml +#: dropdown - DEP_STATUS - ACTIVE +msgid "[departments/departments_Edit.xml?DEP_STATUS-ACTIVE]" +msgstr "Active" + +# departments/departments_Edit.xml?DEP_STATUS-INACTIVE +# departments/departments_Edit.xml +#: dropdown - DEP_STATUS - INACTIVE +msgid "[departments/departments_Edit.xml?DEP_STATUS-INACTIVE]" +msgstr "Inactive" + +# departments/departments_Edit.xml?DEP_MANAGER +# departments/departments_Edit.xml +#: dropdown - DEP_MANAGER +msgid "Manager/Supervisor" +msgstr "Manager/Supervisor" + +# departments/departments_Edit.xml?button +# departments/departments_Edit.xml +#: button - button +msgid "[departments/departments_Edit.xml?button] Save" +msgstr "Save" + +# departments/departments_New.xml?title +# departments/departments_New.xml +#: title - title +msgid "[departments/departments_New.xml?title] Department Information" +msgstr "Department Information" + +# departments/departments_New.xml?DEP_TITLE +# departments/departments_New.xml +#: text - DEP_TITLE +msgid "Department Name" +msgstr "Department Name" + +# departments/departments_New.xml?BTN_CANCEL +# departments/departments_New.xml +#: button - BTN_CANCEL +msgid "[departments/departments_New.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# departments/departments_New.xml?button +# departments/departments_New.xml +#: button - button +msgid "[departments/departments_New.xml?button] Save" +msgstr "Save" + +# departments/departments_Options.xml?MNU_ADD_EMPLOYE +# departments/departments_Options.xml +#: link - MNU_ADD_EMPLOYE +msgid "[departments/departments_Options.xml?MNU_ADD_EMPLOYE] Assign user" +msgstr "Assign user" + +# departments/departments_SubNew.xml?title +# departments/departments_SubNew.xml +#: title - title +msgid "[departments/departments_SubNew.xml?title] Department Information" +msgstr "Department Information" + +# departments/departments_SubNew.xml?DEP_PARENT_NAME +# departments/departments_SubNew.xml +#: text - DEP_PARENT_NAME +msgid "Parent Department" +msgstr "Parent Department" + +# departments/departments_SubNew.xml?DEP_TITLE +# departments/departments_SubNew.xml +#: text - DEP_TITLE +msgid "[departments/departments_SubNew.xml?DEP_TITLE] Department Name" +msgstr "Department Name" + +# departments/departments_SubNew.xml?BTN_CANCEL +# departments/departments_SubNew.xml +#: button - BTN_CANCEL +msgid "[departments/departments_SubNew.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# departments/departments_SubNew.xml?button +# departments/departments_SubNew.xml +#: button - button +msgid "[departments/departments_SubNew.xml?button] Save" +msgstr "Save" + +# departments/departments_UsersList.xml?USR_USERNAME +# departments/departments_UsersList.xml +#: text - USR_USERNAME +msgid "[departments/departments_UsersList.xml?USR_USERNAME] Username" +msgstr "Username" + +# departments/departments_UsersList.xml?USR_FULLNAME +# departments/departments_UsersList.xml +#: text - USR_FULLNAME +msgid "[departments/departments_UsersList.xml?USR_FULLNAME] User" +msgstr "User" + +# departments/departments_UsersList.xml?USR_MANAGER +# departments/departments_UsersList.xml +#: text - USR_MANAGER +msgid "Manager" +msgstr "Manager" + +# departments/departments_UsersList.xml?USR_REPORTS_NAME +# departments/departments_UsersList.xml +#: text - USR_REPORTS_NAME +msgid "Reports To" +msgstr "Reports To" + +# departments/departments_UsersList.xml?DELETE +# departments/departments_UsersList.xml +#: link - DELETE +msgid "[departments/departments_UsersList.xml?DELETE]" +msgstr "" + +# dynaforms/datemask.xml?mask +# dynaforms/datemask.xml +#: title - mask +msgid "Options Mask" +msgstr "Options Mask" + +# dynaforms/datemask.xml?option1 +# dynaforms/datemask.xml +#: subtitle - option1 +msgid "%a — abbreviated weekday name<br> %A — full weekday name<br> %b — abbreviated month name<br> %B — full month name<br> %C — the century number<br> %d — the day of the month (range 01 to 31)<br> %e — the day of the month (range 1 to 31)<br> %H — hour, range 00 to 23 (24h format)<br> %I — hour, range 01 to 12 (12h format)<br> %j — day of the year (range 001 to 366)<br> %k — hour, range 0 to 23 (24h format)<br> %l — hour, range 1 to 12 (12h format)<br> %m — month, range 01 to 12<br> %o — month, range 1 to 12<br> %M — minute, range 00 to 59<br> %n — a newline character<br> %p — PM or AM<br> %P — pm or am<br> %s — UNIX time (number of seconds since 1970-01-01)<br> %S — seconds, range 00 to 59<br> %t — a tab character<br> %W — week number<br> %u — the day of the week (range 1 to 7, 1 = MON)<br> %w — the day of the week (range 0 to 6, 0 = SUN)<br> %y — year without the century (range 00 to 99)<br> %Y — year with the century<br> %% — a literal '%' character" +msgstr "%a — abbreviated weekday name<br> %A — full weekday name<br> %b — abbreviated month name<br> %B — full month name<br> %C — the century number<br> %d — the day of the month (range 01 to 31)<br> %e — the day of the month (range 1 to 31)<br> %H — hour, range 00 to 23 (24h format)<br> %I — hour, range 01 to 12 (12h format)<br> %j — day of the year (range 001 to 366)<br> %k — hour, range 0 to 23 (24h format)<br> %l — hour, range 1 to 12 (12h format)<br> %m — month, range 01 to 12<br> %o — month, range 1 to 12<br> %M — minute, range 00 to 59<br> %n — a newline character<br> %p — PM or AM<br> %P — pm or am<br> %s — UNIX time (number of seconds since 1970-01-01)<br> %S — seconds, range 00 to 59<br> %t — a tab character<br> %W — week number<br> %u — the day of the week (range 1 to 7, 1 = MON)<br> %w — the day of the week (range 0 to 6, 0 = SUN)<br> %y — year without the century (range 00 to 99)<br> %Y — year with the century<br> %% — a literal '%' character" + +# dynaforms/dynaform_Fields.xml?XMLNODE_NAME +# dynaforms/dynaform_Fields.xml +#: text - XMLNODE_NAME +msgid "Field" +msgstr "Field" + +# dynaforms/dynaform_Fields.xml?TYPE +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE +msgid "[dynaforms/dynaform_Fields.xml?TYPE] Type" +msgstr "Type" + +# dynaforms/dynaform_Fields.xml?TYPE-title +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - title +msgid "[dynaforms/dynaform_Fields.xml?TYPE-title]" +msgstr "Title" + +# dynaforms/dynaform_Fields.xml?TYPE-subtitle +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - subtitle +msgid "[dynaforms/dynaform_Fields.xml?TYPE-subtitle]" +msgstr "Subtitle" + +# dynaforms/dynaform_Fields.xml?TYPE-text +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - text +msgid "[dynaforms/dynaform_Fields.xml?TYPE-text]" +msgstr "text" + +# dynaforms/dynaform_Fields.xml?TYPE-password +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - password +msgid "[dynaforms/dynaform_Fields.xml?TYPE-password]" +msgstr "Password" + +# dynaforms/dynaform_Fields.xml?TYPE-textarea +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - textarea +msgid "[dynaforms/dynaform_Fields.xml?TYPE-textarea]" +msgstr "Text Area" + +# dynaforms/dynaform_Fields.xml?TYPE-currency +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - currency +msgid "[dynaforms/dynaform_Fields.xml?TYPE-currency]" +msgstr "Currency" + +# dynaforms/dynaform_Fields.xml?TYPE-percentage +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - percentage +msgid "[dynaforms/dynaform_Fields.xml?TYPE-percentage]" +msgstr "Percentage" + +# dynaforms/dynaform_Fields.xml?TYPE-date +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - date +msgid "[dynaforms/dynaform_Fields.xml?TYPE-date]" +msgstr "date" + +# dynaforms/dynaform_Fields.xml?TYPE-yesno +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - yesno +msgid "[dynaforms/dynaform_Fields.xml?TYPE-yesno]" +msgstr "Yes/No" + +# dynaforms/dynaform_Fields.xml?TYPE-link +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - link +msgid "[dynaforms/dynaform_Fields.xml?TYPE-link]" +msgstr "link" + +# dynaforms/dynaform_Fields.xml?TYPE-file +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - file +msgid "[dynaforms/dynaform_Fields.xml?TYPE-file]" +msgstr "file" + +# dynaforms/dynaform_Fields.xml?TYPE-checkbox +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - checkbox +msgid "[dynaforms/dynaform_Fields.xml?TYPE-checkbox]" +msgstr "Check Box" + +# dynaforms/dynaform_Fields.xml?TYPE-button +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - button +msgid "[dynaforms/dynaform_Fields.xml?TYPE-button]" +msgstr "Button" + +# dynaforms/dynaform_Fields.xml?TYPE-reset +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - reset +msgid "[dynaforms/dynaform_Fields.xml?TYPE-reset]" +msgstr "Reset" + +# dynaforms/dynaform_Fields.xml?TYPE-submit +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - submit +msgid "[dynaforms/dynaform_Fields.xml?TYPE-submit]" +msgstr "Submit" + +# dynaforms/dynaform_Fields.xml?TYPE-hidden +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - hidden +msgid "[dynaforms/dynaform_Fields.xml?TYPE-hidden]" +msgstr "Hidden" + +# dynaforms/dynaform_Fields.xml?TYPE-dropdown +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - dropdown +msgid "[dynaforms/dynaform_Fields.xml?TYPE-dropdown]" +msgstr "Dropdown" + +# dynaforms/dynaform_Fields.xml?TYPE-listbox +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - listbox +msgid "[dynaforms/dynaform_Fields.xml?TYPE-listbox]" +msgstr "List Box" + +# dynaforms/dynaform_Fields.xml?TYPE-radiogroup +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - radiogroup +msgid "[dynaforms/dynaform_Fields.xml?TYPE-radiogroup]" +msgstr "Radio Group" + +# dynaforms/dynaform_Fields.xml?TYPE-checkgroup +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - checkgroup +msgid "[dynaforms/dynaform_Fields.xml?TYPE-checkgroup]" +msgstr "Check Group" + +# dynaforms/dynaform_Fields.xml?TYPE-grid +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - grid +msgid "[dynaforms/dynaform_Fields.xml?TYPE-grid]" +msgstr "grid" + +# dynaforms/dynaform_Fields.xml?TYPE-javascript +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - javascript +msgid "[dynaforms/dynaform_Fields.xml?TYPE-javascript]" +msgstr "Java Script" + +# dynaforms/dynaform_Fields.xml?TYPE-private +# dynaforms/dynaform_Fields.xml +#: dropdown - TYPE - private +msgid "[dynaforms/dynaform_Fields.xml?TYPE-private]" +msgstr "Private" + +# dynaforms/dynaform_Fields.xml?SEARCH +# dynaforms/dynaform_Fields.xml +#: button - SEARCH +msgid "[dynaforms/dynaform_Fields.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/dynaforms_AssignVariables.xml?SAVE_FROM_PMTABLE +# dynaforms/dynaforms_AssignVariables.xml +#: button - SAVE_FROM_PMTABLE +msgid "[dynaforms/dynaforms_AssignVariables.xml?SAVE_FROM_PMTABLE] Save" +msgstr "Save" + +# dynaforms/dynaforms_AssignVariables.xml?SAVE_AND_OPEN_FROM_PMTABLE +# dynaforms/dynaforms_AssignVariables.xml +#: button - SAVE_AND_OPEN_FROM_PMTABLE +msgid "Save & Open" +msgstr "Save & Open" + +# dynaforms/dynaforms_AssignVariablesGrid.xml?FLD_NAME +# dynaforms/dynaforms_AssignVariablesGrid.xml +#: text - FLD_NAME +msgid "[dynaforms/dynaforms_AssignVariablesGrid.xml?FLD_NAME] Primary Key" +msgstr "Primary Key" + +# dynaforms/dynaforms_AssignVariablesGrid.xml?PRO_VARIABLE +# dynaforms/dynaforms_AssignVariablesGrid.xml +#: textpm - PRO_VARIABLE +msgid "[dynaforms/dynaforms_AssignVariablesGrid.xml?PRO_VARIABLE] Variables" +msgstr "Variables" + +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?DYN_TITLE +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?DYN_TITLE] Title" +msgstr "Title" + +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?ASSIGN +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml +#: link - ASSIGN +msgid "[dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?ASSIGN]" +msgstr "" + +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?SEARCH +# dynaforms/dynaforms_AvailableSupervisorDynaforms.xml +#: button - SEARCH +msgid "[dynaforms/dynaforms_AvailableSupervisorDynaforms.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/dynaforms_ChoseType.xml?TITLE +# dynaforms/dynaforms_ChoseType.xml +#: title - TITLE +msgid "Please select the Dynaform Type" +msgstr "Please select the Dynaform Type" + +# dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE +# dynaforms/dynaforms_ChoseType.xml +#: radiogroup - DYN_SOURCE +msgid "[dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE] Type" +msgstr "Type" + +# dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE-normal +# dynaforms/dynaforms_ChoseType.xml +#: radiogroup - DYN_SOURCE - normal +msgid "[dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE-normal]" +msgstr "Blank Dynaform" + +# dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE-pmtable +# dynaforms/dynaforms_ChoseType.xml +#: radiogroup - DYN_SOURCE - pmtable +msgid "[dynaforms/dynaforms_ChoseType.xml?DYN_SOURCE-pmtable]" +msgstr " PM Table Dynaform" + +# dynaforms/dynaforms_ChoseType.xml?BTN_CANCEL +# dynaforms/dynaforms_ChoseType.xml +#: button - BTN_CANCEL +msgid "[dynaforms/dynaforms_ChoseType.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/dynaforms_ChoseType.xml?ACCEPT +# dynaforms/dynaforms_ChoseType.xml +#: button - ACCEPT +msgid "[dynaforms/dynaforms_ChoseType.xml?ACCEPT] Select" +msgstr "Select" + +# dynaforms/dynaforms_ConditionalShowHide.xml?tit1 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: title - tit1 +msgid "Conditions Editor" +msgstr "Conditions Editor" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION +msgid "Function" +msgstr "Function" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-show +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - show +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-show]" +msgstr "Show" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-showOnly +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - showOnly +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-showOnly]" +msgstr "Show only" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-showAll +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - showAll +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-showAll]" +msgstr "Show all" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hide +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - hide +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hide]" +msgstr "Hide" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hideOnly +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - hideOnly +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hideOnly]" +msgstr "Hide only" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hideAll +# dynaforms/dynaforms_ConditionalShowHide.xml +#: dropdown - FCD_FUNCTION - hideAll +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_FUNCTION-hideAll]" +msgstr "Hide all" + +# dynaforms/dynaforms_ConditionalShowHide.xml?fields +# dynaforms/dynaforms_ConditionalShowHide.xml +#: listbox - fields +msgid "Applying the function fields" +msgstr "Applying the function fields" + +# dynaforms/dynaforms_ConditionalShowHide.xml?fields_selected +# dynaforms/dynaforms_ConditionalShowHide.xml +#: listbox - fields_selected +msgid "Selected fields" +msgstr "Selected fields" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_CONDITION +# dynaforms/dynaforms_ConditionalShowHide.xml +#: textarea - FCD_CONDITION +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_CONDITION] Condition" +msgstr "Condition" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op1 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op1 +msgid "/" +msgstr "/" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op2 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op2 +msgid "(" +msgstr "(" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op3 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op3 +msgid ")" +msgstr ")" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op4 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op4 +msgid "AND" +msgstr "AND" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op5 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op5 +msgid "*" +msgstr "*" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op6 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op6 +msgid "<" +msgstr "<" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op7 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op7 +msgid ">" +msgstr ">" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op8 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op8 +msgid "OR" +msgstr "OR" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op9 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op9 +msgid "-" +msgstr "-" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op10 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op10 +msgid "<=" +msgstr "<=" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op11 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op11 +msgid ">=" +msgstr ">=" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op12 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op12 +msgid "NOT" +msgstr "NOT" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op13 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op13 +msgid "+" +msgstr "+" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op14 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op14 +msgid "==" +msgstr "==" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op15 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op15 +msgid "!=" +msgstr "!=" + +# dynaforms/dynaforms_ConditionalShowHide.xml?op16 +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - op16 +msgid "@#" +msgstr "@#" + +# dynaforms/dynaforms_ConditionalShowHide.xml?eventOnload +# dynaforms/dynaforms_ConditionalShowHide.xml +#: checkbox - eventOnload +msgid "On load event" +msgstr "On load event" + +# dynaforms/dynaforms_ConditionalShowHide.xml?eventOnchange +# dynaforms/dynaforms_ConditionalShowHide.xml +#: checkbox - eventOnchange +msgid "On change event" +msgstr "On change event" + +# dynaforms/dynaforms_ConditionalShowHide.xml?event_owner +# dynaforms/dynaforms_ConditionalShowHide.xml +#: listbox - event_owner +msgid "Field event owner" +msgstr "Field event owner" + +# dynaforms/dynaforms_ConditionalShowHide.xml?event_owner_selected +# dynaforms/dynaforms_ConditionalShowHide.xml +#: listbox - event_owner_selected +msgid "Selected field event owner" +msgstr "Selected field event owner" + +# dynaforms/dynaforms_ConditionalShowHide.xml?FCD_STATUS +# dynaforms/dynaforms_ConditionalShowHide.xml +#: checkbox - FCD_STATUS +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?FCD_STATUS] Enabled" +msgstr "Enabled" + +# dynaforms/dynaforms_ConditionalShowHide.xml?test_condition +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - test_condition +msgid "Test condition" +msgstr "Test condition" + +# dynaforms/dynaforms_ConditionalShowHide.xml?BTN_CANCEL +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - BTN_CANCEL +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/dynaforms_ConditionalShowHide.xml?save_condition +# dynaforms/dynaforms_ConditionalShowHide.xml +#: button - save_condition +msgid "[dynaforms/dynaforms_ConditionalShowHide.xml?save_condition] Save" +msgstr "Save" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_NRO +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_NRO +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_NRO] #" +msgstr "#" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_FUNCTION +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_FUNCTION +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_FUNCTION] Function" +msgstr "Function" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_FIELDS +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_FIELDS +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_FIELDS] Fields" +msgstr "Fields" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_CONDITION +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_CONDITION +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_CONDITION] Condition" +msgstr "Condition" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_EVENTS +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_EVENTS +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_EVENTS] Events" +msgstr "Events" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_EVENT_OWNERS +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: text - FCD_EVENT_OWNERS +msgid "Event Owner" +msgstr "Event Owner" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: dropdown - FCD_STATUS +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS] Enabled" +msgstr "Enabled" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS-1 +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: dropdown - FCD_STATUS - 1 +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS-1]" +msgstr "yes" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS-'' +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: dropdown - FCD_STATUS - '' +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?FCD_STATUS-'']" +msgstr "no" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?USR_VIEW +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: link - USR_VIEW +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?USR_VIEW] Edit" +msgstr "Edit" + +# dynaforms/dynaforms_ConditionalShowHideList.xml?USR_DELETE +# dynaforms/dynaforms_ConditionalShowHideList.xml +#: link - USR_DELETE +msgid "[dynaforms/dynaforms_ConditionalShowHideList.xml?USR_DELETE] Delete" +msgstr "Delete" + +# dynaforms/dynaforms_ConditionalShowHideOptions.xml?MNU_NEW +# dynaforms/dynaforms_ConditionalShowHideOptions.xml +#: link - MNU_NEW +msgid "[dynaforms/dynaforms_ConditionalShowHideOptions.xml?MNU_NEW] New" +msgstr "New" + +# dynaforms/dynaforms_ConditionalShowHideTest.xml?title1 +# dynaforms/dynaforms_ConditionalShowHideTest.xml +#: title - title1 +msgid "Test values for DynaForm fields" +msgstr "Test values for DynaForm fields" + +# dynaforms/dynaforms_ConditionalShowHideTest.xml?save +# dynaforms/dynaforms_ConditionalShowHideTest.xml +#: button - save +msgid "Save values" +msgstr "Save values" + +# dynaforms/dynaforms_ConditionalShowHideTestGrid.xml?dynafield +# dynaforms/dynaforms_ConditionalShowHideTestGrid.xml +#: label - dynafield +msgid "Field name" +msgstr "Field name" + +# dynaforms/dynaforms_ConditionalShowHideTestGrid.xml?dynavalue +# dynaforms/dynaforms_ConditionalShowHideTestGrid.xml +#: text - dynavalue +msgid "Value" +msgstr "Value" + +# dynaforms/dynaforms_Edit.xml?TITLE +# dynaforms/dynaforms_Edit.xml +#: title - TITLE +msgid "Dynaform Information" +msgstr "Dynaform Information" + +# dynaforms/dynaforms_Edit.xml?ADD_TABLE +# dynaforms/dynaforms_Edit.xml +#: dropdown - ADD_TABLE +msgid "Create from a PM Table" +msgstr "Create from a PM Table" + +# dynaforms/dynaforms_Edit.xml?DYN_TITLE +# dynaforms/dynaforms_Edit.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_Edit.xml?DYN_TITLE] Title" +msgstr "Title" + +# dynaforms/dynaforms_Edit.xml?DYN_TYPE +# dynaforms/dynaforms_Edit.xml +#: dropdown - DYN_TYPE +msgid "[dynaforms/dynaforms_Edit.xml?DYN_TYPE] Type" +msgstr "Type" + +# dynaforms/dynaforms_Edit.xml?DYN_TYPE-xmlform +# dynaforms/dynaforms_Edit.xml +#: dropdown - DYN_TYPE - xmlform +msgid "[dynaforms/dynaforms_Edit.xml?DYN_TYPE-xmlform]" +msgstr "Normal" + +# dynaforms/dynaforms_Edit.xml?DYN_TYPE-grid +# dynaforms/dynaforms_Edit.xml +#: dropdown - DYN_TYPE - grid +msgid "[dynaforms/dynaforms_Edit.xml?DYN_TYPE-grid]" +msgstr "Grid" + +# dynaforms/dynaforms_Edit.xml?DYN_DESCRIPTION +# dynaforms/dynaforms_Edit.xml +#: textarea - DYN_DESCRIPTION +msgid "[dynaforms/dynaforms_Edit.xml?DYN_DESCRIPTION] Description" +msgstr "Description" + +# dynaforms/dynaforms_Edit.xml?CONTINUE +# dynaforms/dynaforms_Edit.xml +#: button - CONTINUE +msgid "[dynaforms/dynaforms_Edit.xml?CONTINUE] Save" +msgstr "Save" + +# dynaforms/dynaforms_Edit.xml?SAVE_DYNAFORM +# dynaforms/dynaforms_Edit.xml +#: button - SAVE_DYNAFORM +msgid "[dynaforms/dynaforms_Edit.xml?SAVE_DYNAFORM] Save" +msgstr "Save" + +# dynaforms/dynaforms_Edit.xml?SAVE_OPEN +# dynaforms/dynaforms_Edit.xml +#: button - SAVE_OPEN +msgid "[dynaforms/dynaforms_Edit.xml?SAVE_OPEN] Save & Open" +msgstr "Save & Open" + +# dynaforms/dynaforms_Edit.xml?BTN_CANCEL +# dynaforms/dynaforms_Edit.xml +#: button - BTN_CANCEL +msgid "[dynaforms/dynaforms_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/dynaforms_Editor.xml?title +# dynaforms/dynaforms_Editor.xml +#: title - title +msgid "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"background-color:transparent\"> <tr> <td class='FormTitle'>Preview</td> <td align=\"right\"></td> </tr> </table>" +msgstr "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"background-color:transparent\"> <tr> <td class='FormTitle'>Preview</td> <td align=\"right\"></td> </tr> </table>" + +# dynaforms/dynaforms_HtmlEditor.xml?HTML +# dynaforms/dynaforms_HtmlEditor.xml +#: html - HTML +msgid "HTML View" +msgstr "HTML View" + +# dynaforms/dynaforms_HtmlEditor.xml?PME_HTML_ENABLETEMPLATE +# dynaforms/dynaforms_HtmlEditor.xml +#: checkbox - PME_HTML_ENABLETEMPLATE +msgid "Enable HTML Editing" +msgstr "Enable HTML Editing" + +# dynaforms/dynaforms_HtmlEditor.xml?PME_RESTORE_HTML +# dynaforms/dynaforms_HtmlEditor.xml +#: button - PME_RESTORE_HTML +msgid "Restore Original HTML" +msgstr "Restore Original HTML" + +# dynaforms/dynaforms_HtmlEditor.xml?PME_REFRESH_VIEW +# dynaforms/dynaforms_HtmlEditor.xml +#: button - PME_REFRESH_VIEW +msgid "Refresh View" +msgstr "Refresh View" + +# dynaforms/dynaforms_HtmlEditor.xml?HTML2 +# dynaforms/dynaforms_HtmlEditor.xml +#: textarea - HTML2 +msgid "HTML Code" +msgstr "HTML Code" + +# dynaforms/dynaforms_JSEditor.xml?JS_TITLE +# dynaforms/dynaforms_JSEditor.xml +#: title - JS_TITLE +msgid "There is no javascript code" +msgstr "There is no javascript code" + +# dynaforms/dynaforms_JSEditor.xml?JS_LIST +# dynaforms/dynaforms_JSEditor.xml +#: dropdown - JS_LIST +msgid "Section" +msgstr "Section" + +# dynaforms/dynaforms_JSEditor.xml?JS +# dynaforms/dynaforms_JSEditor.xml +#: textarea - JS +msgid "Code" +msgstr "Code" + +# dynaforms/dynaforms_List.xml?DYN_TITLE +# dynaforms/dynaforms_List.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_List.xml?DYN_TITLE] Dynaform" +msgstr "Dynaform" + +# dynaforms/dynaforms_List.xml?DYN_TYPE +# dynaforms/dynaforms_List.xml +#: dropdown - DYN_TYPE +msgid "[dynaforms/dynaforms_List.xml?DYN_TYPE] Type" +msgstr "Type" + +# dynaforms/dynaforms_List.xml?DYN_TYPE-1 +# dynaforms/dynaforms_List.xml +#: dropdown - DYN_TYPE - 1 +msgid "[dynaforms/dynaforms_List.xml?DYN_TYPE-1]" +msgstr "Master form" + +# dynaforms/dynaforms_List.xml?DYN_TYPE-2 +# dynaforms/dynaforms_List.xml +#: dropdown - DYN_TYPE - 2 +msgid "[dynaforms/dynaforms_List.xml?DYN_TYPE-2]" +msgstr "Grid" + +# dynaforms/dynaforms_List.xml?DYN_DESCRIPTION +# dynaforms/dynaforms_List.xml +#: textarea - DYN_DESCRIPTION +msgid "[dynaforms/dynaforms_List.xml?DYN_DESCRIPTION] Description" +msgstr "Description" + +# dynaforms/dynaforms_List.xml?PROPERTIES +# dynaforms/dynaforms_List.xml +#: link - PROPERTIES +msgid "[dynaforms/dynaforms_List.xml?PROPERTIES]" +msgstr "" + +# dynaforms/dynaforms_List.xml?EDIT +# dynaforms/dynaforms_List.xml +#: link - EDIT +msgid "[dynaforms/dynaforms_List.xml?EDIT]" +msgstr "" + +# dynaforms/dynaforms_List.xml?DELETE +# dynaforms/dynaforms_List.xml +#: link - DELETE +msgid "[dynaforms/dynaforms_List.xml?DELETE]" +msgstr "" + +# dynaforms/dynaforms_List.xml?SEARCH +# dynaforms/dynaforms_List.xml +#: button - SEARCH +msgid "[dynaforms/dynaforms_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/dynaforms_Options.xml?MNU_ADD +# dynaforms/dynaforms_Options.xml +#: link - MNU_ADD +msgid "[dynaforms/dynaforms_Options.xml?MNU_ADD] New" +msgstr "New" + +# dynaforms/dynaforms_Properties.xml?PME_PROPERTIES_TITLE +# dynaforms/dynaforms_Properties.xml +#: title - PME_PROPERTIES_TITLE +msgid "[dynaforms/dynaforms_Properties.xml?PME_PROPERTIES_TITLE] Properties" +msgstr "Properties" + +# dynaforms/dynaforms_Properties.xml?DYN_TITLE +# dynaforms/dynaforms_Properties.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_Properties.xml?DYN_TITLE] Dynaform" +msgstr "Dynaform" + +# dynaforms/dynaforms_Properties.xml?DYN_TYPE +# dynaforms/dynaforms_Properties.xml +#: dropdown - DYN_TYPE +msgid "[dynaforms/dynaforms_Properties.xml?DYN_TYPE] Type" +msgstr "Type" + +# dynaforms/dynaforms_Properties.xml?DYN_TYPE-xmlform +# dynaforms/dynaforms_Properties.xml +#: dropdown - DYN_TYPE - xmlform +msgid "[dynaforms/dynaforms_Properties.xml?DYN_TYPE-xmlform]" +msgstr "Master Form" + +# dynaforms/dynaforms_Properties.xml?DYN_TYPE-grid +# dynaforms/dynaforms_Properties.xml +#: dropdown - DYN_TYPE - grid +msgid "[dynaforms/dynaforms_Properties.xml?DYN_TYPE-grid]" +msgstr "Grid" + +# dynaforms/dynaforms_Properties.xml?DYN_DESCRIPTION +# dynaforms/dynaforms_Properties.xml +#: textarea - DYN_DESCRIPTION +msgid "[dynaforms/dynaforms_Properties.xml?DYN_DESCRIPTION] Description" +msgstr "Description" + +# dynaforms/dynaforms_Properties.xml?SUBTITLE +# dynaforms/dynaforms_Properties.xml +#: subtitle - SUBTITLE +msgid "Others" +msgstr "Others" + +# dynaforms/dynaforms_Properties.xml?WIDTH +# dynaforms/dynaforms_Properties.xml +#: text - WIDTH +msgid "[dynaforms/dynaforms_Properties.xml?WIDTH] Width" +msgstr "Width" + +# dynaforms/dynaforms_Properties.xml?MODE +# dynaforms/dynaforms_Properties.xml +#: dropdown - MODE +msgid "Mode" +msgstr "Mode" + +# dynaforms/dynaforms_Properties.xml?MODE-edit +# dynaforms/dynaforms_Properties.xml +#: dropdown - MODE - edit +msgid "[dynaforms/dynaforms_Properties.xml?MODE-edit]" +msgstr "Edit" + +# dynaforms/dynaforms_Properties.xml?MODE-view +# dynaforms/dynaforms_Properties.xml +#: dropdown - MODE - view +msgid "[dynaforms/dynaforms_Properties.xml?MODE-view]" +msgstr "View" + +# dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE +# dynaforms/dynaforms_Properties.xml +#: dropdown - NEXTSTEPSAVE +msgid "Next Step Link" +msgstr "Next Step Link" + +# dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-'' +# dynaforms/dynaforms_Properties.xml +#: dropdown - NEXTSTEPSAVE - '' +msgid "[dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-'']" +msgstr "No save & Continue" + +# dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-save +# dynaforms/dynaforms_Properties.xml +#: dropdown - NEXTSTEPSAVE - save +msgid "[dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-save]" +msgstr "Save & Continue" + +# dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-prompt +# dynaforms/dynaforms_Properties.xml +#: dropdown - NEXTSTEPSAVE - prompt +msgid "[dynaforms/dynaforms_Properties.xml?NEXTSTEPSAVE-prompt]" +msgstr "Show prompt" + +# dynaforms/dynaforms_Properties.xml?PRINTDYNAFORM +# dynaforms/dynaforms_Properties.xml +#: checkbox - PRINTDYNAFORM +msgid "Show print dynaform button" +msgstr "Show print dynaform button" + +# dynaforms/dynaforms_Properties.xml?PME_PROP_APPLY +# dynaforms/dynaforms_Properties.xml +#: button - PME_PROP_APPLY +msgid "Apply" +msgstr "Apply" + +# dynaforms/dynaforms_Properties.xml?PME_PROP_REVERT +# dynaforms/dynaforms_Properties.xml +#: button - PME_PROP_REVERT +msgid "Revert" +msgstr "Revert" + +# dynaforms/dynaforms_Saveas.xml?TITLE +# dynaforms/dynaforms_Saveas.xml +#: title - TITLE +msgid "[dynaforms/dynaforms_Saveas.xml?TITLE] Dynaform Information" +msgstr "Dynaform Information" + +# dynaforms/dynaforms_Saveas.xml?DYN_TITLENEW +# dynaforms/dynaforms_Saveas.xml +#: text - DYN_TITLENEW +msgid "[dynaforms/dynaforms_Saveas.xml?DYN_TITLENEW] Title" +msgstr "Title" + +# dynaforms/dynaforms_Saveas.xml?DYN_DESCRIPTIONNEW +# dynaforms/dynaforms_Saveas.xml +#: textarea - DYN_DESCRIPTIONNEW +msgid "[dynaforms/dynaforms_Saveas.xml?DYN_DESCRIPTIONNEW] Description" +msgstr "Description" + +# dynaforms/dynaforms_Saveas.xml?BTN_CANCEL +# dynaforms/dynaforms_Saveas.xml +#: button - BTN_CANCEL +msgid "[dynaforms/dynaforms_Saveas.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/dynaforms_Saveas.xml?ACCEPT +# dynaforms/dynaforms_Saveas.xml +#: button - ACCEPT +msgid "[dynaforms/dynaforms_Saveas.xml?ACCEPT] Save" +msgstr "Save" + +# dynaforms/dynaforms_ShortList.xml?DYN_TITLE +# dynaforms/dynaforms_ShortList.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_ShortList.xml?DYN_TITLE] Title" +msgstr "Title" + +# dynaforms/dynaforms_ShortList.xml?DYN_TYPE +# dynaforms/dynaforms_ShortList.xml +#: dropdown - DYN_TYPE +msgid "[dynaforms/dynaforms_ShortList.xml?DYN_TYPE] Type" +msgstr "Type" + +# dynaforms/dynaforms_ShortList.xml?DYN_TYPE-xmlform +# dynaforms/dynaforms_ShortList.xml +#: dropdown - DYN_TYPE - xmlform +msgid "[dynaforms/dynaforms_ShortList.xml?DYN_TYPE-xmlform]" +msgstr "Normal" + +# dynaforms/dynaforms_ShortList.xml?DYN_TYPE-grid +# dynaforms/dynaforms_ShortList.xml +#: dropdown - DYN_TYPE - grid +msgid "[dynaforms/dynaforms_ShortList.xml?DYN_TYPE-grid]" +msgstr "Grid" + +# dynaforms/dynaforms_ShortList.xml?EDIT +# dynaforms/dynaforms_ShortList.xml +#: link - EDIT +msgid "[dynaforms/dynaforms_ShortList.xml?EDIT]" +msgstr "" + +# dynaforms/dynaforms_ShortList.xml?DELETE +# dynaforms/dynaforms_ShortList.xml +#: link - DELETE +msgid "[dynaforms/dynaforms_ShortList.xml?DELETE]" +msgstr "" + +# dynaforms/dynaforms_ShortList.xml?GET_UID +# dynaforms/dynaforms_ShortList.xml +#: link - GET_UID +msgid "[dynaforms/dynaforms_ShortList.xml?GET_UID]" +msgstr "" + +# dynaforms/dynaforms_ShortList.xml?SEARCH +# dynaforms/dynaforms_ShortList.xml +#: button - SEARCH +msgid "[dynaforms/dynaforms_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/dynaforms_Supervisor.xml?DYN_TITLE +# dynaforms/dynaforms_Supervisor.xml +#: text - DYN_TITLE +msgid "[dynaforms/dynaforms_Supervisor.xml?DYN_TITLE] Title" +msgstr "Title" + +# dynaforms/dynaforms_Supervisor.xml?REMOVE +# dynaforms/dynaforms_Supervisor.xml +#: link - REMOVE +msgid "[dynaforms/dynaforms_Supervisor.xml?REMOVE]" +msgstr "" + +# dynaforms/dynaforms_Supervisor.xml?SEARCH +# dynaforms/dynaforms_Supervisor.xml +#: button - SEARCH +msgid "[dynaforms/dynaforms_Supervisor.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/dynaforms_SupervisorOptions.xml?MNU_ASSIGN +# dynaforms/dynaforms_SupervisorOptions.xml +#: link - MNU_ASSIGN +msgid "[dynaforms/dynaforms_SupervisorOptions.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# dynaforms/dynaforms_WebEntry.xml?subtitle1 +# dynaforms/dynaforms_WebEntry.xml +#: subtitle - subtitle1 +msgid "[dynaforms/dynaforms_WebEntry.xml?subtitle1] Properties" +msgstr "Properties" + +# dynaforms/dynaforms_WebEntry.xml?TASKS +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - TASKS +msgid "Initial Task" +msgstr "Initial Task" + +# dynaforms/dynaforms_WebEntry.xml?DYNAFORM +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - DYNAFORM +msgid "Initial Dynaform" +msgstr "Initial Dynaform" + +# dynaforms/dynaforms_WebEntry.xml?WE_TYPE +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_TYPE +msgid "[dynaforms/dynaforms_WebEntry.xml?WE_TYPE] Method" +msgstr "Method" + +# dynaforms/dynaforms_WebEntry.xml?WE_TYPE-WS +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_TYPE - WS +msgid "[dynaforms/dynaforms_WebEntry.xml?WE_TYPE-WS]" +msgstr "PHP pages with Web Services" + +# dynaforms/dynaforms_WebEntry.xml?WE_TYPE-SINGLE +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_TYPE - SINGLE +msgid "[dynaforms/dynaforms_WebEntry.xml?WE_TYPE-SINGLE]" +msgstr "Single HTML " + +# dynaforms/dynaforms_WebEntry.xml?WE_USR +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_USR +msgid "Input Documents Access" +msgstr "Input Documents Access" + +# dynaforms/dynaforms_WebEntry.xml?WE_USR-1 +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_USR - 1 +msgid "[dynaforms/dynaforms_WebEntry.xml?WE_USR-1]" +msgstr "No Restriction" + +# dynaforms/dynaforms_WebEntry.xml?WE_USR-2 +# dynaforms/dynaforms_WebEntry.xml +#: dropdown - WE_USR - 2 +msgid "[dynaforms/dynaforms_WebEntry.xml?WE_USR-2]" +msgstr "Restricted to process permissions" + +# dynaforms/dynaforms_WebEntry.xml?subtitle2 +# dynaforms/dynaforms_WebEntry.xml +#: subtitle - subtitle2 +msgid "PHP & Web Service options" +msgstr "PHP & Web Service options" + +# dynaforms/dynaforms_WebEntry.xml?WS_USER +# dynaforms/dynaforms_WebEntry.xml +#: text - WS_USER +msgid "Web Service User" +msgstr "Web Service User" + +# dynaforms/dynaforms_WebEntry.xml?WS_PASS +# dynaforms/dynaforms_WebEntry.xml +#: password - WS_PASS +msgid "Web Service Passsword" +msgstr "Web Service Passsword" + +# dynaforms/dynaforms_WebEntry.xml?WS_ROUNDROBIN +# dynaforms/dynaforms_WebEntry.xml +#: yesno - WS_ROUNDROBIN +msgid "Cyclical Assignment" +msgstr "Cyclical Assignment" + +# dynaforms/dynaforms_WebEntry.xml?TEST +# dynaforms/dynaforms_WebEntry.xml +#: button - TEST +msgid "Test Configuration" +msgstr "Test Configuration" + +# dynaforms/dynaforms_WebEntry.xml?SEARCH +# dynaforms/dynaforms_WebEntry.xml +#: button - SEARCH +msgid "Generate Web Entry Page" +msgstr "Generate Web Entry Page" + +# dynaforms/dynaforms_WebEntryList.xml?W_LINK +# dynaforms/dynaforms_WebEntryList.xml +#: text - W_LINK +msgid "[dynaforms/dynaforms_WebEntryList.xml?W_LINK]" +msgstr "" + +# dynaforms/dynaforms_WebEntryList.xml?W_DELETE +# dynaforms/dynaforms_WebEntryList.xml +#: link - W_DELETE +msgid "[dynaforms/dynaforms_WebEntryList.xml?W_DELETE] Delete" +msgstr "Delete" + +# dynaforms/dynaforms_WebEntryOptions.xml?MNU_ASSIGN +# dynaforms/dynaforms_WebEntryOptions.xml +#: link - MNU_ASSIGN +msgid "[dynaforms/dynaforms_WebEntryOptions.xml?MNU_ASSIGN] New" +msgstr "New" + +# dynaforms/dynaforms_XmlEditor.xml?XML +# dynaforms/dynaforms_XmlEditor.xml +#: textarea - XML +msgid "[dynaforms/dynaforms_XmlEditor.xml?XML] XML" +msgstr "XML" + +# dynaforms/dynaforms_vars.xml?vars +# dynaforms/dynaforms_vars.xml +#: listbox - vars +msgid "[dynaforms/dynaforms_vars.xml?vars]" +msgstr "" + +# dynaforms/fields_Edit.xml?XMLNODE_NAME +# dynaforms/fields_Edit.xml +#: text - XMLNODE_NAME +msgid "[dynaforms/fields_Edit.xml?XMLNODE_NAME] Field name" +msgstr "Field name" + +# dynaforms/fields_Edit.xml?TYPE +# dynaforms/fields_Edit.xml +#: dropdown - TYPE +msgid "[dynaforms/fields_Edit.xml?TYPE] Type" +msgstr "Type" + +# dynaforms/fields_Edit.xml?TYPE-title +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - title +msgid "[dynaforms/fields_Edit.xml?TYPE-title]" +msgstr "Title" + +# dynaforms/fields_Edit.xml?TYPE-subtitle +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - subtitle +msgid "[dynaforms/fields_Edit.xml?TYPE-subtitle]" +msgstr "Subtitle" + +# dynaforms/fields_Edit.xml?TYPE-text +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - text +msgid "[dynaforms/fields_Edit.xml?TYPE-text]" +msgstr "Text" + +# dynaforms/fields_Edit.xml?TYPE-password +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - password +msgid "[dynaforms/fields_Edit.xml?TYPE-password]" +msgstr "Password" + +# dynaforms/fields_Edit.xml?TYPE-textarea +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - textarea +msgid "[dynaforms/fields_Edit.xml?TYPE-textarea]" +msgstr "Text Area" + +# dynaforms/fields_Edit.xml?TYPE-currency +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - currency +msgid "[dynaforms/fields_Edit.xml?TYPE-currency]" +msgstr "Currency" + +# dynaforms/fields_Edit.xml?TYPE-percentage +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - percentage +msgid "[dynaforms/fields_Edit.xml?TYPE-percentage]" +msgstr "Percentage" + +# dynaforms/fields_Edit.xml?TYPE-date +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - date +msgid "[dynaforms/fields_Edit.xml?TYPE-date]" +msgstr "date" + +# dynaforms/fields_Edit.xml?TYPE-yesno +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - yesno +msgid "[dynaforms/fields_Edit.xml?TYPE-yesno]" +msgstr "Yes/No" + +# dynaforms/fields_Edit.xml?TYPE-link +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - link +msgid "[dynaforms/fields_Edit.xml?TYPE-link]" +msgstr "link" + +# dynaforms/fields_Edit.xml?TYPE-file +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - file +msgid "[dynaforms/fields_Edit.xml?TYPE-file]" +msgstr "file" + +# dynaforms/fields_Edit.xml?TYPE-checkbox +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - checkbox +msgid "[dynaforms/fields_Edit.xml?TYPE-checkbox]" +msgstr "Check Box" + +# dynaforms/fields_Edit.xml?TYPE-button +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - button +msgid "[dynaforms/fields_Edit.xml?TYPE-button]" +msgstr "Button" + +# dynaforms/fields_Edit.xml?TYPE-reset +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - reset +msgid "[dynaforms/fields_Edit.xml?TYPE-reset]" +msgstr "Reset" + +# dynaforms/fields_Edit.xml?TYPE-submit +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - submit +msgid "[dynaforms/fields_Edit.xml?TYPE-submit]" +msgstr "Submit" + +# dynaforms/fields_Edit.xml?TYPE-hidden +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - hidden +msgid "[dynaforms/fields_Edit.xml?TYPE-hidden]" +msgstr "Hidden" + +# dynaforms/fields_Edit.xml?TYPE-dropdown +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - dropdown +msgid "[dynaforms/fields_Edit.xml?TYPE-dropdown]" +msgstr "Dropdown" + +# dynaforms/fields_Edit.xml?TYPE-listbox +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - listbox +msgid "[dynaforms/fields_Edit.xml?TYPE-listbox]" +msgstr "List Box" + +# dynaforms/fields_Edit.xml?TYPE-radiogroup +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - radiogroup +msgid "[dynaforms/fields_Edit.xml?TYPE-radiogroup]" +msgstr "Radio Group" + +# dynaforms/fields_Edit.xml?TYPE-checkgroup +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - checkgroup +msgid "[dynaforms/fields_Edit.xml?TYPE-checkgroup]" +msgstr "Check Group" + +# dynaforms/fields_Edit.xml?TYPE-grid +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - grid +msgid "[dynaforms/fields_Edit.xml?TYPE-grid]" +msgstr "grid" + +# dynaforms/fields_Edit.xml?TYPE-javascript +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - javascript +msgid "[dynaforms/fields_Edit.xml?TYPE-javascript]" +msgstr "Java Script" + +# dynaforms/fields_Edit.xml?TYPE-private +# dynaforms/fields_Edit.xml +#: dropdown - TYPE - private +msgid "[dynaforms/fields_Edit.xml?TYPE-private]" +msgstr "Private" + +# dynaforms/fields_Edit.xml?DEFAULTVALUE +# dynaforms/fields_Edit.xml +#: text - DEFAULTVALUE +msgid "Default value" +msgstr "Default value" + +# dynaforms/fields_Edit.xml?LABEL +# dynaforms/fields_Edit.xml +#: text - LABEL +msgid "[dynaforms/fields_Edit.xml?LABEL] Label" +msgstr "Label" + +# dynaforms/fields_Edit.xml?ACCEPT +# dynaforms/fields_Edit.xml +#: button - ACCEPT +msgid "[dynaforms/fields_Edit.xml?ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields_List.xml?XMLNODE_NAME +# dynaforms/fields_List.xml +#: text - XMLNODE_NAME +msgid "[dynaforms/fields_List.xml?XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields_List.xml?TYPE +# dynaforms/fields_List.xml +#: dropdown - TYPE +msgid "[dynaforms/fields_List.xml?TYPE] Type" +msgstr "Type" + +# dynaforms/fields_List.xml?TYPE-title +# dynaforms/fields_List.xml +#: dropdown - TYPE - title +msgid "[dynaforms/fields_List.xml?TYPE-title]" +msgstr "Title" + +# dynaforms/fields_List.xml?TYPE-subtitle +# dynaforms/fields_List.xml +#: dropdown - TYPE - subtitle +msgid "[dynaforms/fields_List.xml?TYPE-subtitle]" +msgstr "Subtitle" + +# dynaforms/fields_List.xml?TYPE-text +# dynaforms/fields_List.xml +#: dropdown - TYPE - text +msgid "[dynaforms/fields_List.xml?TYPE-text]" +msgstr "Text" + +# dynaforms/fields_List.xml?TYPE-password +# dynaforms/fields_List.xml +#: dropdown - TYPE - password +msgid "[dynaforms/fields_List.xml?TYPE-password]" +msgstr "Password" + +# dynaforms/fields_List.xml?TYPE-textarea +# dynaforms/fields_List.xml +#: dropdown - TYPE - textarea +msgid "[dynaforms/fields_List.xml?TYPE-textarea]" +msgstr "Textarea" + +# dynaforms/fields_List.xml?TYPE-currency +# dynaforms/fields_List.xml +#: dropdown - TYPE - currency +msgid "[dynaforms/fields_List.xml?TYPE-currency]" +msgstr "Currency" + +# dynaforms/fields_List.xml?TYPE-percentage +# dynaforms/fields_List.xml +#: dropdown - TYPE - percentage +msgid "[dynaforms/fields_List.xml?TYPE-percentage]" +msgstr "Percentage" + +# dynaforms/fields_List.xml?TYPE-date +# dynaforms/fields_List.xml +#: dropdown - TYPE - date +msgid "[dynaforms/fields_List.xml?TYPE-date]" +msgstr "Date" + +# dynaforms/fields_List.xml?TYPE-yesno +# dynaforms/fields_List.xml +#: dropdown - TYPE - yesno +msgid "[dynaforms/fields_List.xml?TYPE-yesno]" +msgstr "Yes/No" + +# dynaforms/fields_List.xml?TYPE-link +# dynaforms/fields_List.xml +#: dropdown - TYPE - link +msgid "[dynaforms/fields_List.xml?TYPE-link]" +msgstr "Link" + +# dynaforms/fields_List.xml?TYPE-file +# dynaforms/fields_List.xml +#: dropdown - TYPE - file +msgid "[dynaforms/fields_List.xml?TYPE-file]" +msgstr "File" + +# dynaforms/fields_List.xml?TYPE-checkbox +# dynaforms/fields_List.xml +#: dropdown - TYPE - checkbox +msgid "[dynaforms/fields_List.xml?TYPE-checkbox]" +msgstr "Checkbox" + +# dynaforms/fields_List.xml?TYPE-button +# dynaforms/fields_List.xml +#: dropdown - TYPE - button +msgid "[dynaforms/fields_List.xml?TYPE-button]" +msgstr "Button" + +# dynaforms/fields_List.xml?TYPE-reset +# dynaforms/fields_List.xml +#: dropdown - TYPE - reset +msgid "[dynaforms/fields_List.xml?TYPE-reset]" +msgstr "Reset" + +# dynaforms/fields_List.xml?TYPE-submit +# dynaforms/fields_List.xml +#: dropdown - TYPE - submit +msgid "[dynaforms/fields_List.xml?TYPE-submit]" +msgstr "Submit" + +# dynaforms/fields_List.xml?TYPE-hidden +# dynaforms/fields_List.xml +#: dropdown - TYPE - hidden +msgid "[dynaforms/fields_List.xml?TYPE-hidden]" +msgstr "Hidden" + +# dynaforms/fields_List.xml?TYPE-dropdown +# dynaforms/fields_List.xml +#: dropdown - TYPE - dropdown +msgid "[dynaforms/fields_List.xml?TYPE-dropdown]" +msgstr "Dropdown" + +# dynaforms/fields_List.xml?TYPE-listbox +# dynaforms/fields_List.xml +#: dropdown - TYPE - listbox +msgid "[dynaforms/fields_List.xml?TYPE-listbox]" +msgstr "Listbox" + +# dynaforms/fields_List.xml?TYPE-radiogroup +# dynaforms/fields_List.xml +#: dropdown - TYPE - radiogroup +msgid "[dynaforms/fields_List.xml?TYPE-radiogroup]" +msgstr "Radios Group" + +# dynaforms/fields_List.xml?TYPE-checkgroup +# dynaforms/fields_List.xml +#: dropdown - TYPE - checkgroup +msgid "[dynaforms/fields_List.xml?TYPE-checkgroup]" +msgstr "Checkboxes Group" + +# dynaforms/fields_List.xml?TYPE-grid +# dynaforms/fields_List.xml +#: dropdown - TYPE - grid +msgid "[dynaforms/fields_List.xml?TYPE-grid]" +msgstr "Grid" + +# dynaforms/fields_List.xml?TYPE-javascript +# dynaforms/fields_List.xml +#: dropdown - TYPE - javascript +msgid "[dynaforms/fields_List.xml?TYPE-javascript]" +msgstr "Javascript Code" + +# dynaforms/fields_List.xml?TYPE-private +# dynaforms/fields_List.xml +#: dropdown - TYPE - private +msgid "[dynaforms/fields_List.xml?TYPE-private]" +msgstr "Private" + +# dynaforms/fields_List.xml?EDIT +# dynaforms/fields_List.xml +#: link - EDIT +msgid "[dynaforms/fields_List.xml?EDIT]" +msgstr "" + +# dynaforms/fields_List.xml?DELETE +# dynaforms/fields_List.xml +#: link - DELETE +msgid "[dynaforms/fields_List.xml?DELETE]" +msgstr "" + +# dynaforms/fields_List.xml?UP1 +# dynaforms/fields_List.xml +#: link - UP1 +msgid "[dynaforms/fields_List.xml?UP1]" +msgstr "" + +# dynaforms/fields_List.xml?DOWN1 +# dynaforms/fields_List.xml +#: link - DOWN1 +msgid "[dynaforms/fields_List.xml?DOWN1]" +msgstr "" + +# dynaforms/fields_List.xml?SEARCH +# dynaforms/fields_List.xml +#: button - SEARCH +msgid "[dynaforms/fields_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# dynaforms/fields_ShortList.xml?XMLNODE_NAME +# dynaforms/fields_ShortList.xml +#: text - XMLNODE_NAME +msgid "[dynaforms/fields_ShortList.xml?XMLNODE_NAME] Field name" +msgstr "Field name" + +# dynaforms/fields_ShortList.xml?EDIT +# dynaforms/fields_ShortList.xml +#: link - EDIT +msgid "[dynaforms/fields_ShortList.xml?EDIT]" +msgstr "" + +# dynaforms/fields_ShortList.xml?DELETE +# dynaforms/fields_ShortList.xml +#: link - DELETE +msgid "[dynaforms/fields_ShortList.xml?DELETE]" +msgstr "" + +# dynaforms/fields_ShortList.xml?SEARCH +# dynaforms/fields_ShortList.xml +#: button - SEARCH +msgid "[dynaforms/fields_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# events/appEventsList.xml?TAS_TITLE +# events/appEventsList.xml +#: text - TAS_TITLE +msgid "[events/appEventsList.xml?TAS_TITLE] Task" +msgstr "Task" + +# events/appEventsList.xml?APP_TITLE +# events/appEventsList.xml +#: text - APP_TITLE +msgid "[events/appEventsList.xml?APP_TITLE] Case Title" +msgstr "Case Title" + +# events/appEventsList.xml?APP_EVN_ACTION_DATE +# events/appEventsList.xml +#: text - APP_EVN_ACTION_DATE +msgid "Action date" +msgstr "Action date" + +# events/appEventsList.xml?EVN_DESCRIPTION +# events/appEventsList.xml +#: text - EVN_DESCRIPTION +msgid "Event Description" +msgstr "Event Description" + +# events/appEventsList.xml?EVN_ACTION +# events/appEventsList.xml +#: dropdown - EVN_ACTION +msgid "Event type" +msgstr "Event type" + +# events/appEventsList.xml?EVN_ACTION-SEND_MESSAGE +# events/appEventsList.xml +#: dropdown - EVN_ACTION - SEND_MESSAGE +msgid "[events/appEventsList.xml?EVN_ACTION-SEND_MESSAGE]" +msgstr "Message" + +# events/appEventsList.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER +# events/appEventsList.xml +#: dropdown - EVN_ACTION - EXECUTE_CONDITIONAL_TRIGGER +msgid "[events/appEventsList.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER]" +msgstr "Conditional" + +# events/appEventsList.xml?EVN_ACTION-EXECUTE_TRIGGER +# events/appEventsList.xml +#: dropdown - EVN_ACTION - EXECUTE_TRIGGER +msgid "[events/appEventsList.xml?EVN_ACTION-EXECUTE_TRIGGER]" +msgstr "Multiple" + +# events/appEventsListCompleted.xml?APP_TITLE +# events/appEventsListCompleted.xml +#: text - APP_TITLE +msgid "[events/appEventsListCompleted.xml?APP_TITLE] Case Title" +msgstr "Case Title" + +# events/appEventsListCompleted.xml?APP_EVN_ACTION_DATE +# events/appEventsListCompleted.xml +#: text - APP_EVN_ACTION_DATE +msgid "[events/appEventsListCompleted.xml?APP_EVN_ACTION_DATE] Action date" +msgstr "Action date" + +# events/appEventsListCompleted.xml?APP_EVN_LAST_EXECUTION_DATE +# events/appEventsListCompleted.xml +#: text - APP_EVN_LAST_EXECUTION_DATE +msgid "Last Execution" +msgstr "Last Execution" + +# events/appEventsListCompleted.xml?EVN_DESCRIPTION +# events/appEventsListCompleted.xml +#: text - EVN_DESCRIPTION +msgid "[events/appEventsListCompleted.xml?EVN_DESCRIPTION] Event Description" +msgstr "Event Description" + +# events/appEventsListCompleted.xml?EVN_ACTION +# events/appEventsListCompleted.xml +#: dropdown - EVN_ACTION +msgid "[events/appEventsListCompleted.xml?EVN_ACTION] Event type" +msgstr "Event type" + +# events/appEventsListCompleted.xml?EVN_ACTION-SEND_MESSAGE +# events/appEventsListCompleted.xml +#: dropdown - EVN_ACTION - SEND_MESSAGE +msgid "[events/appEventsListCompleted.xml?EVN_ACTION-SEND_MESSAGE]" +msgstr "Message" + +# events/appEventsListCompleted.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER +# events/appEventsListCompleted.xml +#: dropdown - EVN_ACTION - EXECUTE_CONDITIONAL_TRIGGER +msgid "[events/appEventsListCompleted.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER]" +msgstr "Conditional" + +# events/appEventsListCompleted.xml?EVN_ACTION-EXECUTE_TRIGGER +# events/appEventsListCompleted.xml +#: dropdown - EVN_ACTION - EXECUTE_TRIGGER +msgid "[events/appEventsListCompleted.xml?EVN_ACTION-EXECUTE_TRIGGER]" +msgstr "Multiple" + +# events/dynavarsList.xml?name +# events/dynavarsList.xml +#: text - name +msgid "Var. name" +msgstr "Var. name" + +# events/dynavarsList.xml?dynaform +# events/dynavarsList.xml +#: text - dynaform +msgid "[events/dynavarsList.xml?dynaform] Dynaform" +msgstr "Dynaform" + +# events/dynavarsList.xml?sel +# events/dynavarsList.xml +#: link - sel +msgid "[events/dynavarsList.xml?sel]" +msgstr "" + +# events/eventsEdit.xml?TITLE +# events/eventsEdit.xml +#: title - TITLE +msgid "[events/eventsEdit.xml?TITLE]" +msgstr "" + +# events/eventsEdit.xml?NOTE +# events/eventsEdit.xml +#: subtitle - NOTE +msgid "Events execution is related to the due date of the cases or the estimated duration if you select \"Multiple Tasks\"" +msgstr "Events execution is related to the due date of the cases or the estimated duration if you select \"Multiple Tasks\"" + +# events/eventsEdit.xml?EVN_DESCRIPTION +# events/eventsEdit.xml +#: text - EVN_DESCRIPTION +msgid "[events/eventsEdit.xml?EVN_DESCRIPTION] Description" +msgstr "Description" + +# events/eventsEdit.xml?EVN_STATUS +# events/eventsEdit.xml +#: dropdown - EVN_STATUS +msgid "[events/eventsEdit.xml?EVN_STATUS] Status" +msgstr "Status" + +# events/eventsEdit.xml?EVN_STATUS-ACTIVE +# events/eventsEdit.xml +#: dropdown - EVN_STATUS - ACTIVE +msgid "[events/eventsEdit.xml?EVN_STATUS-ACTIVE]" +msgstr "Active" + +# events/eventsEdit.xml?EVN_STATUS-INACTIVE +# events/eventsEdit.xml +#: dropdown - EVN_STATUS - INACTIVE +msgid "[events/eventsEdit.xml?EVN_STATUS-INACTIVE]" +msgstr "Inactive" + +# events/eventsEdit.xml?SUBTITLE1 +# events/eventsEdit.xml +#: subtitle - SUBTITLE1 +msgid "Behaviour" +msgstr "Behaviour" + +# events/eventsEdit.xml?EVN_WHEN_OCCURS +# events/eventsEdit.xml +#: dropdown - EVN_WHEN_OCCURS +msgid "[events/eventsEdit.xml?EVN_WHEN_OCCURS] Execution time" +msgstr "Execution time" + +# events/eventsEdit.xml?EVN_WHEN_OCCURS-AFTER_TIME +# events/eventsEdit.xml +#: dropdown - EVN_WHEN_OCCURS - AFTER_TIME +msgid "[events/eventsEdit.xml?EVN_WHEN_OCCURS-AFTER_TIME]" +msgstr "After interval ends" + +# events/eventsEdit.xml?EVN_WHEN_OCCURS-TASK_STARTED +# events/eventsEdit.xml +#: dropdown - EVN_WHEN_OCCURS - TASK_STARTED +msgid "[events/eventsEdit.xml?EVN_WHEN_OCCURS-TASK_STARTED]" +msgstr "After interval starts" + +# events/eventsEdit.xml?EVN_RELATED_TO +# events/eventsEdit.xml +#: dropdown - EVN_RELATED_TO +msgid "[events/eventsEdit.xml?EVN_RELATED_TO] Type" +msgstr "Type" + +# events/eventsEdit.xml?EVN_RELATED_TO-SINGLE +# events/eventsEdit.xml +#: dropdown - EVN_RELATED_TO - SINGLE +msgid "[events/eventsEdit.xml?EVN_RELATED_TO-SINGLE]" +msgstr "Single Task" + +# events/eventsEdit.xml?EVN_RELATED_TO-MULTIPLE +# events/eventsEdit.xml +#: dropdown - EVN_RELATED_TO - MULTIPLE +msgid "[events/eventsEdit.xml?EVN_RELATED_TO-MULTIPLE]" +msgstr "Multiple Tasks" + +# events/eventsEdit.xml?TAS_UID +# events/eventsEdit.xml +#: dropdown - TAS_UID +msgid "The time starts with task" +msgstr "The time starts with task" + +# events/eventsEdit.xml?EVN_TAS_UID_FROM +# events/eventsEdit.xml +#: dropdown - EVN_TAS_UID_FROM +msgid "The time starts from task" +msgstr "The time starts from task" + +# events/eventsEdit.xml?EVN_TAS_UID_TO +# events/eventsEdit.xml +#: dropdown - EVN_TAS_UID_TO +msgid "[events/eventsEdit.xml?EVN_TAS_UID_TO] To" +msgstr "To" + +# events/eventsEdit.xml?EVN_TAS_ESTIMATED_DURATION +# events/eventsEdit.xml +#: text - EVN_TAS_ESTIMATED_DURATION +msgid "Estimated Task duration" +msgstr "Estimated Task duration" + +# events/eventsEdit.xml?EVN_WHEN +# events/eventsEdit.xml +#: text - EVN_WHEN +msgid "days" +msgstr "days" + +# events/eventsEdit.xml?TITLE2 +# events/eventsEdit.xml +#: title - TITLE2 +msgid "[events/eventsEdit.xml?TITLE2] Action" +msgstr "Action" + +# events/eventsEdit.xml?EVN_CONDITIONS +# events/eventsEdit.xml +#: textarea - EVN_CONDITIONS +msgid "[events/eventsEdit.xml?EVN_CONDITIONS] Condition" +msgstr "Condition" + +# events/eventsEdit.xml?EVN_ACTION +# events/eventsEdit.xml +#: dropdown - EVN_ACTION +msgid "Execute trigger" +msgstr "Execute trigger" + +# events/eventsEdit.xml?EVN_ACTION-SEND_MESSAGE +# events/eventsEdit.xml +#: dropdown - EVN_ACTION - SEND_MESSAGE +msgid "[events/eventsEdit.xml?EVN_ACTION-SEND_MESSAGE]" +msgstr "Message" + +# events/eventsEdit.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER +# events/eventsEdit.xml +#: dropdown - EVN_ACTION - EXECUTE_CONDITIONAL_TRIGGER +msgid "[events/eventsEdit.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER]" +msgstr "Conditional" + +# events/eventsEdit.xml?EVN_ACTION-EXECUTE_TRIGGER +# events/eventsEdit.xml +#: dropdown - EVN_ACTION - EXECUTE_TRIGGER +msgid "[events/eventsEdit.xml?EVN_ACTION-EXECUTE_TRIGGER]" +msgstr "Multiple" + +# events/eventsEdit.xml?TRI_UID +# events/eventsEdit.xml +#: dropdown - TRI_UID +msgid "[events/eventsEdit.xml?TRI_UID]" +msgstr "" + +# events/eventsEdit.xml?TITLE3 +# events/eventsEdit.xml +#: title - TITLE3 +msgid "Event scheduled graph" +msgstr "Event scheduled graph" + +# events/eventsEdit.xml?BTN_CANCEL +# events/eventsEdit.xml +#: button - BTN_CANCEL +msgid "[events/eventsEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# events/eventsEdit.xml?CONTINUE +# events/eventsEdit.xml +#: button - CONTINUE +msgid "[events/eventsEdit.xml?CONTINUE] Save" +msgstr "Save" + +# events/eventsEditAction.xml?EVN_MESSAGE_SUBJECT +# events/eventsEditAction.xml +#: text - EVN_MESSAGE_SUBJECT +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_SUBJECT] Subject" +msgstr "Subject" + +# events/eventsEditAction.xml?title1 +# events/eventsEditAction.xml +#: title - title1 +msgid "Send to" +msgstr "Send to" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_TO_SIMPLEADD +# events/eventsEditAction.xml +#: text - EVN_MESSAGE_TO_TO_SIMPLEADD +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_TO_TO_SIMPLEADD]" +msgstr "" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_TO +# events/eventsEditAction.xml +#: listbox - EVN_MESSAGE_TO_TO +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_TO_TO] TO" +msgstr "TO" + +# events/eventsEditAction.xml?title2 +# events/eventsEditAction.xml +#: title - title2 +msgid "Carbon Copy" +msgstr "Carbon Copy" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_CC_SIMPLEADD +# events/eventsEditAction.xml +#: text - EVN_MESSAGE_TO_CC_SIMPLEADD +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_TO_CC_SIMPLEADD]" +msgstr "" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_CC +# events/eventsEditAction.xml +#: listbox - EVN_MESSAGE_TO_CC +msgid "CC" +msgstr "CC" + +# events/eventsEditAction.xml?title3 +# events/eventsEditAction.xml +#: title - title3 +msgid "Blind Carbon Copy" +msgstr "Blind Carbon Copy" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_BCC_SIMPLEADD +# events/eventsEditAction.xml +#: text - EVN_MESSAGE_TO_BCC_SIMPLEADD +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_TO_BCC_SIMPLEADD]" +msgstr "" + +# events/eventsEditAction.xml?EVN_MESSAGE_TO_BCC +# events/eventsEditAction.xml +#: listbox - EVN_MESSAGE_TO_BCC +msgid "BCC" +msgstr "BCC" + +# events/eventsEditAction.xml?EVN_MESSAGE_TEMPLATE +# events/eventsEditAction.xml +#: dropdown - EVN_MESSAGE_TEMPLATE +msgid "E-Mail Template" +msgstr "E-Mail Template" + +# events/eventsEditAction.xml?EVN_MESSAGE_TEMPLATE-alert_message.html +# events/eventsEditAction.xml +#: dropdown - EVN_MESSAGE_TEMPLATE - alert_message.html +msgid "[events/eventsEditAction.xml?EVN_MESSAGE_TEMPLATE-alert_message.html]" +msgstr "-- Default --" + +# events/eventsEditAction.xml?TRI_UID +# events/eventsEditAction.xml +#: dropdown - TRI_UID +msgid "Trigger" +msgstr "Trigger" + +# events/eventsEditAction.xml?TRI_UID-'' +# events/eventsEditAction.xml +#: dropdown - TRI_UID - '' +msgid "[events/eventsEditAction.xml?TRI_UID-'']" +msgstr "-- Select --" + +# events/eventsEditAction.xml?BTN_CANCEL +# events/eventsEditAction.xml +#: button - BTN_CANCEL +msgid "[events/eventsEditAction.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# events/eventsEditAction.xml?SAVE +# events/eventsEditAction.xml +#: button - SAVE +msgid "[events/eventsEditAction.xml?SAVE] Save" +msgstr "Save" + +# events/eventsNew.xml?TITLE +# events/eventsNew.xml +#: title - TITLE +msgid "[events/eventsNew.xml?TITLE]" +msgstr "" + +# events/eventsNew.xml?NOTE +# events/eventsNew.xml +#: subtitle - NOTE +msgid "[events/eventsNew.xml?NOTE] Events execution is related to the due date of the cases or the estimated duration if you select \"Multiple Tasks\"" +msgstr "Events execution is related to the due date of the cases or the estimated duration if you select \"Multiple Tasks\"" + +# events/eventsNew.xml?EVN_DESCRIPTION +# events/eventsNew.xml +#: text - EVN_DESCRIPTION +msgid "[events/eventsNew.xml?EVN_DESCRIPTION] Description" +msgstr "Description" + +# events/eventsNew.xml?EVN_STATUS +# events/eventsNew.xml +#: dropdown - EVN_STATUS +msgid "[events/eventsNew.xml?EVN_STATUS] Status" +msgstr "Status" + +# events/eventsNew.xml?EVN_STATUS-ACTIVE +# events/eventsNew.xml +#: dropdown - EVN_STATUS - ACTIVE +msgid "[events/eventsNew.xml?EVN_STATUS-ACTIVE]" +msgstr "Active" + +# events/eventsNew.xml?EVN_STATUS-INACTIVE +# events/eventsNew.xml +#: dropdown - EVN_STATUS - INACTIVE +msgid "[events/eventsNew.xml?EVN_STATUS-INACTIVE]" +msgstr "Inactive" + +# events/eventsNew.xml?SUBTITLE1 +# events/eventsNew.xml +#: subtitle - SUBTITLE1 +msgid "[events/eventsNew.xml?SUBTITLE1] Behaviour" +msgstr "Behaviour" + +# events/eventsNew.xml?EVN_WHEN_OCCURS +# events/eventsNew.xml +#: dropdown - EVN_WHEN_OCCURS +msgid "[events/eventsNew.xml?EVN_WHEN_OCCURS] Execution time" +msgstr "Execution time" + +# events/eventsNew.xml?EVN_WHEN_OCCURS-AFTER_TIME +# events/eventsNew.xml +#: dropdown - EVN_WHEN_OCCURS - AFTER_TIME +msgid "[events/eventsNew.xml?EVN_WHEN_OCCURS-AFTER_TIME]" +msgstr "After interval ends" + +# events/eventsNew.xml?EVN_WHEN_OCCURS-TASK_STARTED +# events/eventsNew.xml +#: dropdown - EVN_WHEN_OCCURS - TASK_STARTED +msgid "[events/eventsNew.xml?EVN_WHEN_OCCURS-TASK_STARTED]" +msgstr "After interval starts" + +# events/eventsNew.xml?EVN_RELATED_TO +# events/eventsNew.xml +#: dropdown - EVN_RELATED_TO +msgid "[events/eventsNew.xml?EVN_RELATED_TO] Type" +msgstr "Type" + +# events/eventsNew.xml?EVN_RELATED_TO-SINGLE +# events/eventsNew.xml +#: dropdown - EVN_RELATED_TO - SINGLE +msgid "[events/eventsNew.xml?EVN_RELATED_TO-SINGLE]" +msgstr "Single Task" + +# events/eventsNew.xml?EVN_RELATED_TO-MULTIPLE +# events/eventsNew.xml +#: dropdown - EVN_RELATED_TO - MULTIPLE +msgid "[events/eventsNew.xml?EVN_RELATED_TO-MULTIPLE]" +msgstr "Multiple Tasks" + +# events/eventsNew.xml?TAS_UID +# events/eventsNew.xml +#: dropdown - TAS_UID +msgid "[events/eventsNew.xml?TAS_UID] The time starts with task" +msgstr "The time starts with task" + +# events/eventsNew.xml?EVN_TAS_UID_FROM +# events/eventsNew.xml +#: dropdown - EVN_TAS_UID_FROM +msgid "[events/eventsNew.xml?EVN_TAS_UID_FROM] The time starts from task" +msgstr "The time starts from task" + +# events/eventsNew.xml?EVN_TAS_UID_TO +# events/eventsNew.xml +#: dropdown - EVN_TAS_UID_TO +msgid "[events/eventsNew.xml?EVN_TAS_UID_TO] To" +msgstr "To" + +# events/eventsNew.xml?EVN_TAS_ESTIMATED_DURATION +# events/eventsNew.xml +#: text - EVN_TAS_ESTIMATED_DURATION +msgid "[events/eventsNew.xml?EVN_TAS_ESTIMATED_DURATION] Estimated Task duration" +msgstr "Estimated Task duration" + +# events/eventsNew.xml?EVN_WHEN +# events/eventsNew.xml +#: text - EVN_WHEN +msgid "[events/eventsNew.xml?EVN_WHEN] days" +msgstr "days" + +# events/eventsNew.xml?TITLE2 +# events/eventsNew.xml +#: title - TITLE2 +msgid "[events/eventsNew.xml?TITLE2] Action" +msgstr "Action" + +# events/eventsNew.xml?EVN_CONDITIONS +# events/eventsNew.xml +#: textarea - EVN_CONDITIONS +msgid "[events/eventsNew.xml?EVN_CONDITIONS] Condition" +msgstr "Condition" + +# events/eventsNew.xml?EVN_ACTION +# events/eventsNew.xml +#: dropdown - EVN_ACTION +msgid "[events/eventsNew.xml?EVN_ACTION] Execute trigger" +msgstr "Execute trigger" + +# events/eventsNew.xml?EVN_ACTION-SEND_MESSAGE +# events/eventsNew.xml +#: dropdown - EVN_ACTION - SEND_MESSAGE +msgid "[events/eventsNew.xml?EVN_ACTION-SEND_MESSAGE]" +msgstr "Message" + +# events/eventsNew.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER +# events/eventsNew.xml +#: dropdown - EVN_ACTION - EXECUTE_CONDITIONAL_TRIGGER +msgid "[events/eventsNew.xml?EVN_ACTION-EXECUTE_CONDITIONAL_TRIGGER]" +msgstr "Conditional" + +# events/eventsNew.xml?EVN_ACTION-EXECUTE_TRIGGER +# events/eventsNew.xml +#: dropdown - EVN_ACTION - EXECUTE_TRIGGER +msgid "[events/eventsNew.xml?EVN_ACTION-EXECUTE_TRIGGER]" +msgstr "Multiple" + +# events/eventsNew.xml?TRI_UID +# events/eventsNew.xml +#: dropdown - TRI_UID +msgid "[events/eventsNew.xml?TRI_UID]" +msgstr "" + +# events/eventsNew.xml?TRI_UID-'' +# events/eventsNew.xml +#: dropdown - TRI_UID - '' +msgid "[events/eventsNew.xml?TRI_UID-'']" +msgstr "" + +# events/eventsNew.xml?TITLE3 +# events/eventsNew.xml +#: title - TITLE3 +msgid "[events/eventsNew.xml?TITLE3] Event scheduled graph" +msgstr "Event scheduled graph" + +# events/eventsNew.xml?BTN_CANCEL +# events/eventsNew.xml +#: button - BTN_CANCEL +msgid "[events/eventsNew.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# events/eventsNew.xml?CONTINUE +# events/eventsNew.xml +#: button - CONTINUE +msgid "[events/eventsNew.xml?CONTINUE] Continue" +msgstr "Continue" + +# events/eventsOptions.xml?MNU_ADD +# events/eventsOptions.xml +#: link - MNU_ADD +msgid "[events/eventsOptions.xml?MNU_ADD] New" +msgstr "New" + +# events/eventsOptions.xml?MNU_PENDING +# events/eventsOptions.xml +#: link - MNU_PENDING +msgid "[events/eventsOptions.xml?MNU_PENDING] Pending" +msgstr "Pending" + +# events/eventsOptions.xml?MNU_COMPLETED +# events/eventsOptions.xml +#: link - MNU_COMPLETED +msgid "[events/eventsOptions.xml?MNU_COMPLETED] Completed" +msgstr "Completed" + +# events/eventsShortList.xml?EVN_DESCRIPTION +# events/eventsShortList.xml +#: text - EVN_DESCRIPTION +msgid "[events/eventsShortList.xml?EVN_DESCRIPTION] Description" +msgstr "Description" + +# events/eventsShortList.xml?EVN_WHEN_OCCURS +# events/eventsShortList.xml +#: dropdown - EVN_WHEN_OCCURS +msgid "When occurs" +msgstr "When occurs" + +# events/eventsShortList.xml?EVN_WHEN_OCCURS-AFTER_TIME +# events/eventsShortList.xml +#: dropdown - EVN_WHEN_OCCURS - AFTER_TIME +msgid "[events/eventsShortList.xml?EVN_WHEN_OCCURS-AFTER_TIME]" +msgstr "After time elapses" + +# events/eventsShortList.xml?EVN_WHEN_OCCURS-TASK_STARTED +# events/eventsShortList.xml +#: dropdown - EVN_WHEN_OCCURS - TASK_STARTED +msgid "[events/eventsShortList.xml?EVN_WHEN_OCCURS-TASK_STARTED]" +msgstr "After task started" + +# events/eventsShortList.xml?EVN_RELATED_TO +# events/eventsShortList.xml +#: dropdown - EVN_RELATED_TO +msgid "[events/eventsShortList.xml?EVN_RELATED_TO] Type" +msgstr "Type" + +# events/eventsShortList.xml?EVN_RELATED_TO-SINGLE +# events/eventsShortList.xml +#: dropdown - EVN_RELATED_TO - SINGLE +msgid "[events/eventsShortList.xml?EVN_RELATED_TO-SINGLE]" +msgstr "Single" + +# events/eventsShortList.xml?EVN_RELATED_TO-MULTIPLE +# events/eventsShortList.xml +#: dropdown - EVN_RELATED_TO - MULTIPLE +msgid "[events/eventsShortList.xml?EVN_RELATED_TO-MULTIPLE]" +msgstr "Multiple" + +# events/eventsShortList.xml?EVN_STATUS +# events/eventsShortList.xml +#: dropdown - EVN_STATUS +msgid "[events/eventsShortList.xml?EVN_STATUS] Status" +msgstr "Status" + +# events/eventsShortList.xml?EVN_STATUS-ACTIVE +# events/eventsShortList.xml +#: dropdown - EVN_STATUS - ACTIVE +msgid "[events/eventsShortList.xml?EVN_STATUS-ACTIVE]" +msgstr "Active" + +# events/eventsShortList.xml?EVN_STATUS-INACTIVE +# events/eventsShortList.xml +#: dropdown - EVN_STATUS - INACTIVE +msgid "[events/eventsShortList.xml?EVN_STATUS-INACTIVE]" +msgstr "Inactive" + +# events/eventsShortList.xml?EDIT_EVENT +# events/eventsShortList.xml +#: link - EDIT_EVENT +msgid "[events/eventsShortList.xml?EDIT_EVENT]" +msgstr "" + +# events/eventsShortList.xml?EDIT_ACTION +# events/eventsShortList.xml +#: link - EDIT_ACTION +msgid "[events/eventsShortList.xml?EDIT_ACTION]" +msgstr "" + +# events/eventsShortList.xml?DELETE +# events/eventsShortList.xml +#: link - DELETE +msgid "[events/eventsShortList.xml?DELETE]" +msgstr "" + +# events/groupmailList.xml?GROUP_TITLE +# events/groupmailList.xml +#: text - GROUP_TITLE +msgid "Group name" +msgstr "Group name" + +# events/groupmailList.xml?sel +# events/groupmailList.xml +#: link - sel +msgid "[events/groupmailList.xml?sel]" +msgstr "" + +# events/usermailList.xml?USR_FULLNAME +# events/usermailList.xml +#: text - USR_FULLNAME +msgid "Fullname" +msgstr "Fullname" + +# events/usermailList.xml?USR_EMAIL +# events/usermailList.xml +#: text - USR_EMAIL +msgid "email" +msgstr "email" + +# events/usermailList.xml?sel +# events/usermailList.xml +#: link - sel +msgid "[events/usermailList.xml?sel]" +msgstr "" + +# groups/groups_AddUser.xml?title +# groups/groups_AddUser.xml +#: title - title +msgid "[groups/groups_AddUser.xml?title] User" +msgstr "User" + +# groups/groups_AddUser.xml?USR_UID +# groups/groups_AddUser.xml +#: dropdown - USR_UID +msgid "[groups/groups_AddUser.xml?USR_UID] User" +msgstr "User" + +# groups/groups_AddUser.xml?button +# groups/groups_AddUser.xml +#: button - button +msgid "[groups/groups_AddUser.xml?button] Accept" +msgstr "Accept" + +# groups/groups_AvailableUsers.xml?USR_UID +# groups/groups_AvailableUsers.xml +#: checkboxtable - USR_UID +msgid "[groups/groups_AvailableUsers.xml?USR_UID]" +msgstr "" + +# groups/groups_AvailableUsers.xml?USR_FIRSTNAME +# groups/groups_AvailableUsers.xml +#: text - USR_FIRSTNAME +msgid "[groups/groups_AvailableUsers.xml?USR_FIRSTNAME] Firstname" +msgstr "Firstname" + +# groups/groups_AvailableUsers.xml?USR_LASTNAME +# groups/groups_AvailableUsers.xml +#: text - USR_LASTNAME +msgid "[groups/groups_AvailableUsers.xml?USR_LASTNAME] Lastname" +msgstr "Lastname" + +# groups/groups_Edit.xml?title +# groups/groups_Edit.xml +#: title - title +msgid "Group Information" +msgstr "Group Information" + +# groups/groups_Edit.xml?GRP_TITLE +# groups/groups_Edit.xml +#: text - GRP_TITLE +msgid "[groups/groups_Edit.xml?GRP_TITLE] Name" +msgstr "Name" + +# groups/groups_Edit.xml?GRP_STATUS +# groups/groups_Edit.xml +#: dropdown - GRP_STATUS +msgid "[groups/groups_Edit.xml?GRP_STATUS] Status" +msgstr "Status" + +# groups/groups_Edit.xml?GRP_STATUS-ACTIVE +# groups/groups_Edit.xml +#: dropdown - GRP_STATUS - ACTIVE +msgid "[groups/groups_Edit.xml?GRP_STATUS-ACTIVE]" +msgstr "Active" + +# groups/groups_Edit.xml?GRP_STATUS-INACTIVE +# groups/groups_Edit.xml +#: dropdown - GRP_STATUS - INACTIVE +msgid "[groups/groups_Edit.xml?GRP_STATUS-INACTIVE]" +msgstr "Inactive" + +# groups/groups_Edit.xml?BTN_CANCEL +# groups/groups_Edit.xml +#: button - BTN_CANCEL +msgid "[groups/groups_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# groups/groups_Edit.xml?button +# groups/groups_Edit.xml +#: button - button +msgid "[groups/groups_Edit.xml?button] Save" +msgstr "Save" + +# groups/groups_List.xml?title +# groups/groups_List.xml +#: title - title +msgid "Group properties" +msgstr "Group properties" + +# groups/groups_List.xml?GROUP_TITLE +# groups/groups_List.xml +#: text - GROUP_TITLE +msgid "[groups/groups_List.xml?GROUP_TITLE] Group" +msgstr "Group" + +# groups/groups_List.xml?GROUP_STATUS +# groups/groups_List.xml +#: dropdown - GROUP_STATUS +msgid "[groups/groups_List.xml?GROUP_STATUS] Status" +msgstr "Status" + +# groups/groups_List.xml?GROUP_STATUS-ACTIVE +# groups/groups_List.xml +#: dropdown - GROUP_STATUS - ACTIVE +msgid "[groups/groups_List.xml?GROUP_STATUS-ACTIVE]" +msgstr "Active" + +# groups/groups_List.xml?GROUP_STATUS-INACTIVE +# groups/groups_List.xml +#: dropdown - GROUP_STATUS - INACTIVE +msgid "[groups/groups_List.xml?GROUP_STATUS-INACTIVE]" +msgstr "Inactive" + +# groups/groups_List.xml?GROUP_STATUS-VACATION +# groups/groups_List.xml +#: dropdown - GROUP_STATUS - VACATION +msgid "[groups/groups_List.xml?GROUP_STATUS-VACATION]" +msgstr "Vacation" + +# groups/groups_List.xml?GROUP_STATUS-CLOSED +# groups/groups_List.xml +#: dropdown - GROUP_STATUS - CLOSED +msgid "[groups/groups_List.xml?GROUP_STATUS-CLOSED]" +msgstr "Closed" + +# groups/groups_List.xml?button +# groups/groups_List.xml +#: button - button +msgid "[groups/groups_List.xml?button] Accept" +msgstr "Accept" + +# groups/groups_Options.xml?MNU_ADD_EMPLOYE +# groups/groups_Options.xml +#: link - MNU_ADD_EMPLOYE +msgid "[groups/groups_Options.xml?MNU_ADD_EMPLOYE] Assign" +msgstr "Assign" + +# groups/groups_Search.xml?USR_USERNAME +# groups/groups_Search.xml +#: text - USR_USERNAME +msgid "User name" +msgstr "User name" + +# groups/groups_Search.xml?SEARCH +# groups/groups_Search.xml +#: button - SEARCH +msgid "[groups/groups_Search.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# groups/groups_SelectUsers.xml?BTN_SUBMIT +# groups/groups_SelectUsers.xml +#: button - BTN_SUBMIT +msgid "[groups/groups_SelectUsers.xml?BTN_SUBMIT] Assign" +msgstr "Assign" + +# groups/groups_UsersList.xml?USR_USERNAME +# groups/groups_UsersList.xml +#: text - USR_USERNAME +msgid "[groups/groups_UsersList.xml?USR_USERNAME] Username" +msgstr "Username" + +# groups/groups_UsersList.xml?USR_FIRSTNAME +# groups/groups_UsersList.xml +#: text - USR_FIRSTNAME +msgid "First Name" +msgstr "First Name" + +# groups/groups_UsersList.xml?USR_LASTNAME +# groups/groups_UsersList.xml +#: text - USR_LASTNAME +msgid "Last Name" +msgstr "Last Name" + +# groups/groups_UsersList.xml?DELETE +# groups/groups_UsersList.xml +#: link - DELETE +msgid "[groups/groups_UsersList.xml?DELETE]" +msgstr "" + +# groups/groups_UsersListTitle.xml?GRP_LABEL +# groups/groups_UsersListTitle.xml +#: title - GRP_LABEL +msgid "@#GRP_NAME" +msgstr "@#GRP_NAME" + +# gulliver/dynaforms_Options.xml?DYN_BACKWARD +# gulliver/dynaforms_Options.xml +#: link - DYN_BACKWARD +msgid "@#PREVIOUS_STEP_LABEL" +msgstr "@#PREVIOUS_STEP_LABEL" + +# gulliver/dynaforms_Options.xml?DYN_FORWARD +# gulliver/dynaforms_Options.xml +#: link - DYN_FORWARD +msgid "[gulliver/dynaforms_Options.xml?DYN_FORWARD] Next Step" +msgstr "Next Step" + +# gulliver/dynaforms_OptionsPrint.xml?MNUP +# gulliver/dynaforms_OptionsPrint.xml +#: print - MNUP +msgid "Print form" +msgstr "Print form" + +# gulliver/dynaforms_OptionsPrint.xml?DYN_BACKWARD +# gulliver/dynaforms_OptionsPrint.xml +#: link - DYN_BACKWARD +msgid "[gulliver/dynaforms_OptionsPrint.xml?DYN_BACKWARD] @#PREVIOUS_STEP_LABEL" +msgstr "@#PREVIOUS_STEP_LABEL" + +# gulliver/dynaforms_OptionsPrint.xml?DYN_FORWARD +# gulliver/dynaforms_OptionsPrint.xml +#: link - DYN_FORWARD +msgid "[gulliver/dynaforms_OptionsPrint.xml?DYN_FORWARD] Next Step" +msgstr "Next Step" + +# inputdocs/inputdocs_AvailableSupervisorInputs.xml?INP_DOC_TITLE +# inputdocs/inputdocs_AvailableSupervisorInputs.xml +#: text - INP_DOC_TITLE +msgid "[inputdocs/inputdocs_AvailableSupervisorInputs.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# inputdocs/inputdocs_AvailableSupervisorInputs.xml?ASSIGN +# inputdocs/inputdocs_AvailableSupervisorInputs.xml +#: link - ASSIGN +msgid "[inputdocs/inputdocs_AvailableSupervisorInputs.xml?ASSIGN]" +msgstr "" + +# inputdocs/inputdocs_AvailableSupervisorInputs.xml?SEARCH +# inputdocs/inputdocs_AvailableSupervisorInputs.xml +#: button - SEARCH +msgid "[inputdocs/inputdocs_AvailableSupervisorInputs.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# inputdocs/inputdocs_Edit.xml?TITLE +# inputdocs/inputdocs_Edit.xml +#: title - TITLE +msgid "Input Document Information" +msgstr "Input Document Information" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_TITLE +# inputdocs/inputdocs_Edit.xml +#: text - INP_DOC_TITLE +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-REAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-VREAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-ORIGINAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-COPYLEGAL +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-COPY +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_DESCRIPTION +# inputdocs/inputdocs_Edit.xml +#: textarea - INP_DOC_DESCRIPTION +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_VERSIONING +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_VERSIONING +msgid "Enable Versioning" +msgstr "Enable Versioning" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_VERSIONING-'' +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_VERSIONING - '' +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_VERSIONING-'']" +msgstr "NO" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_VERSIONING-1 +# inputdocs/inputdocs_Edit.xml +#: dropdown - INP_DOC_VERSIONING - 1 +msgid "[inputdocs/inputdocs_Edit.xml?INP_DOC_VERSIONING-1]" +msgstr "YES" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_DESTINATION_PATH +# inputdocs/inputdocs_Edit.xml +#: textpm - INP_DOC_DESTINATION_PATH +msgid "Destination Path" +msgstr "Destination Path" + +# inputdocs/inputdocs_Edit.xml?INP_DOC_TAGS +# inputdocs/inputdocs_Edit.xml +#: textpm - INP_DOC_TAGS +msgid "Tags" +msgstr "Tags" + +# inputdocs/inputdocs_Edit.xml?BTN_CANCEL +# inputdocs/inputdocs_Edit.xml +#: button - BTN_CANCEL +msgid "[inputdocs/inputdocs_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# inputdocs/inputdocs_Edit.xml?ACCEPT +# inputdocs/inputdocs_Edit.xml +#: button - ACCEPT +msgid "[inputdocs/inputdocs_Edit.xml?ACCEPT] Save" +msgstr "Save" + +# inputdocs/inputdocs_List.xml?INP_DOC_TITLE +# inputdocs/inputdocs_List.xml +#: text - INP_DOC_TITLE +msgid "Input document" +msgstr "Input document" + +# inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED] Type" +msgstr "Type" + +# inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-REAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Real" + +# inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Virtual" + +# inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-VREAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "VReal" + +# inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "Original" +msgstr "Original" + +# inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-COPY +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-ORIGINAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-COPYLEGAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal copy" + +# inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-FINAL +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_ORIGINAL - FINAL +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_ORIGINAL-FINAL]" +msgstr "Final" + +# inputdocs/inputdocs_List.xml?INP_DOC_PUBLISHED +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_PUBLISHED +msgid "Access type" +msgstr "Access type" + +# inputdocs/inputdocs_List.xml?INP_DOC_PUBLISHED-PRIVATE +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_PUBLISHED - PRIVATE +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_PUBLISHED-PRIVATE]" +msgstr "Private" + +# inputdocs/inputdocs_List.xml?INP_DOC_PUBLISHED-PUBLIC +# inputdocs/inputdocs_List.xml +#: dropdown - INP_DOC_PUBLISHED - PUBLIC +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_PUBLISHED-PUBLIC]" +msgstr "Public" + +# inputdocs/inputdocs_List.xml?INP_DOC_DESCRIPTION +# inputdocs/inputdocs_List.xml +#: textarea - INP_DOC_DESCRIPTION +msgid "[inputdocs/inputdocs_List.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# inputdocs/inputdocs_List.xml?EDIT +# inputdocs/inputdocs_List.xml +#: link - EDIT +msgid "[inputdocs/inputdocs_List.xml?EDIT]" +msgstr "" + +# inputdocs/inputdocs_List.xml?DELETE +# inputdocs/inputdocs_List.xml +#: link - DELETE +msgid "[inputdocs/inputdocs_List.xml?DELETE]" +msgstr "" + +# inputdocs/inputdocs_List.xml?SEARCH +# inputdocs/inputdocs_List.xml +#: button - SEARCH +msgid "[inputdocs/inputdocs_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# inputdocs/inputdocs_Options.xml?MNU_ADD +# inputdocs/inputdocs_Options.xml +#: link - MNU_ADD +msgid "[inputdocs/inputdocs_Options.xml?MNU_ADD] New" +msgstr "New" + +# inputdocs/inputdocs_ShortList.xml?INP_DOC_TITLE +# inputdocs/inputdocs_ShortList.xml +#: text - INP_DOC_TITLE +msgid "[inputdocs/inputdocs_ShortList.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# inputdocs/inputdocs_ShortList.xml?EDIT +# inputdocs/inputdocs_ShortList.xml +#: link - EDIT +msgid "[inputdocs/inputdocs_ShortList.xml?EDIT]" +msgstr "" + +# inputdocs/inputdocs_ShortList.xml?DELETE +# inputdocs/inputdocs_ShortList.xml +#: link - DELETE +msgid "[inputdocs/inputdocs_ShortList.xml?DELETE]" +msgstr "" + +# inputdocs/inputdocs_ShortList.xml?GET_UID +# inputdocs/inputdocs_ShortList.xml +#: link - GET_UID +msgid "[inputdocs/inputdocs_ShortList.xml?GET_UID]" +msgstr "" + +# inputdocs/inputdocs_ShortList.xml?SEARCH +# inputdocs/inputdocs_ShortList.xml +#: button - SEARCH +msgid "[inputdocs/inputdocs_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# inputdocs/inputdocs_Supervisor.xml?INP_DOC_TITLE +# inputdocs/inputdocs_Supervisor.xml +#: text - INP_DOC_TITLE +msgid "[inputdocs/inputdocs_Supervisor.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# inputdocs/inputdocs_Supervisor.xml?REMOVE +# inputdocs/inputdocs_Supervisor.xml +#: link - REMOVE +msgid "[inputdocs/inputdocs_Supervisor.xml?REMOVE]" +msgstr "" + +# inputdocs/inputdocs_Supervisor.xml?SEARCH +# inputdocs/inputdocs_Supervisor.xml +#: button - SEARCH +msgid "[inputdocs/inputdocs_Supervisor.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# inputdocs/inputdocs_SupervisorOptions.xml?MNU_ASSIGN +# inputdocs/inputdocs_SupervisorOptions.xml +#: link - MNU_ASSIGN +msgid "[inputdocs/inputdocs_SupervisorOptions.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# login/changePassword.xml?THETITLE +# login/changePassword.xml +#: title - THETITLE +msgid "Change password" +msgstr "Change password" + +# login/changePassword.xml?THEDESCRIPTION +# login/changePassword.xml +#: title - THEDESCRIPTION +msgid "@#DESCRIPTION" +msgstr "@#DESCRIPTION" + +# login/changePassword.xml?USR_PASSWORD +# login/changePassword.xml +#: password - USR_PASSWORD +msgid "[login/changePassword.xml?USR_PASSWORD] Password" +msgstr "Password" + +# login/changePassword.xml?USR_PASSWORD_CONFIRM +# login/changePassword.xml +#: password - USR_PASSWORD_CONFIRM +msgid "Re-Type Password" +msgstr "Re-Type Password" + +# login/changePassword.xml?btnSave +# login/changePassword.xml +#: button - btnSave +msgid "[login/changePassword.xml?btnSave] Save" +msgstr "Save" + +# login/dbInfo.xml?DYNA_HEADER +# login/dbInfo.xml +#: title - DYNA_HEADER +msgid "System Information" +msgstr "System Information" + +# login/dbInfo.xml?FLUID +# login/dbInfo.xml +#: caption - FLUID +msgid "ProcessMaker" +msgstr "ProcessMaker" + +# login/dbInfo.xml?SYSTEM +# login/dbInfo.xml +#: caption - SYSTEM +msgid "Operating System" +msgstr "Operating System" + +# login/dbInfo.xml?SERVER_SOFTWARE +# login/dbInfo.xml +#: caption - SERVER_SOFTWARE +msgid "Web Server" +msgstr "Web Server" + +# login/dbInfo.xml?SERVER_NAME +# login/dbInfo.xml +#: caption - SERVER_NAME +msgid "[login/dbInfo.xml?SERVER_NAME] Server Name" +msgstr "Server Name" + +# login/dbInfo.xml?SERVER_ADDR +# login/dbInfo.xml +#: caption - SERVER_ADDR +msgid "Server IP Address" +msgstr "Server IP Address" + +# login/dbInfo.xml?PHP +# login/dbInfo.xml +#: caption - PHP +msgid "PHP version" +msgstr "PHP version" + +# login/dbInfo.xml?DATABASE +# login/dbInfo.xml +#: caption - DATABASE +msgid "Database" +msgstr "Database" + +# login/dbInfo.xml?DATABASE_SERVER +# login/dbInfo.xml +#: caption - DATABASE_SERVER +msgid "Database Server IP Address" +msgstr "Database Server IP Address" + +# login/dbInfo.xml?DATABASE_NAME +# login/dbInfo.xml +#: caption - DATABASE_NAME +msgid "[login/dbInfo.xml?DATABASE_NAME] Database Name" +msgstr "Database Name" + +# login/dbInfo.xml?AVAILABLE_DB +# login/dbInfo.xml +#: caption - AVAILABLE_DB +msgid "Available Databases" +msgstr "Available Databases" + +# login/dbInfo.xml?HTTP_USER_AGENT +# login/dbInfo.xml +#: caption - HTTP_USER_AGENT +msgid "User's Browser" +msgstr "User's Browser" + +# login/dbInfo.xml?IP +# login/dbInfo.xml +#: caption - IP +msgid "User's Ip Address" +msgstr "User's Ip Address" + +# login/login.xml?TITLE +# login/login.xml +#: title - TITLE +msgid "[login/login.xml?TITLE] Login" +msgstr "Login" + +# login/login.xml?USR_USERNAME +# login/login.xml +#: text - USR_USERNAME +msgid "[login/login.xml?USR_USERNAME] User" +msgstr "User" + +# login/login.xml?USR_PASSWORD +# login/login.xml +#: password - USR_PASSWORD +msgid "[login/login.xml?USR_PASSWORD] Password" +msgstr "Password" + +# login/login.xml?USER_LANG +# login/login.xml +#: dropdown - USER_LANG +msgid "[login/login.xml?USER_LANG] Language" +msgstr "Language" + +# login/login.xml?BSUBMIT +# login/login.xml +#: submit - BSUBMIT +msgid "[login/login.xml?BSUBMIT] Login" +msgstr "Login" + +# login/newSite.xml?NEW_WORKSPACE +# login/newSite.xml +#: title - NEW_WORKSPACE +msgid "New Workspace" +msgstr "New Workspace" + +# login/newSite.xml?NW_TITLE +# login/newSite.xml +#: text - NW_TITLE +msgid "[login/newSite.xml?NW_TITLE] Name" +msgstr "Name" + +# login/newSite.xml?DB +# login/newSite.xml +#: subtitle - DB +msgid "Database Options" +msgstr "Database Options" + +# login/newSite.xml?AO_DB_WF +# login/newSite.xml +#: text - AO_DB_WF +msgid "Workflow Database:" +msgstr "Workflow Database:" + +# login/newSite.xml?AO_DB_RB +# login/newSite.xml +#: text - AO_DB_RB +msgid "Rbac Database:" +msgstr "Rbac Database:" + +# login/newSite.xml?AO_DB_RP +# login/newSite.xml +#: text - AO_DB_RP +msgid "Report Database:" +msgstr "Report Database:" + +# login/newSite.xml?AO_DB_DROP +# login/newSite.xml +#: checkbox - AO_DB_DROP +msgid "Drop database if exists" +msgstr "Drop database if exists" + +# login/newSite.xml?WS +# login/newSite.xml +#: subtitle - WS +msgid "Workspace Administrator" +msgstr "Workspace Administrator" + +# login/newSite.xml?NW_USERNAME +# login/newSite.xml +#: text - NW_USERNAME +msgid "Username:" +msgstr "Username:" + +# login/newSite.xml?NW_PASSWORD +# login/newSite.xml +#: password - NW_PASSWORD +msgid "Password (admin):" +msgstr "Password (admin):" + +# login/newSite.xml?NW_PASSWORD2 +# login/newSite.xml +#: password - NW_PASSWORD2 +msgid "Re-type Password:" +msgstr "Re-type Password:" + +# login/newSite.xml?NW_SUB +# login/newSite.xml +#: submit - NW_SUB +msgid "[login/newSite.xml?NW_SUB] Test" +msgstr "Test" + +# login/noViewPage.xml?title +# login/noViewPage.xml +#: title - title +msgid "You don't have permission" +msgstr "You don't have permission" + +# login/noViewPage.xml?subtitle1 +# login/noViewPage.xml +#: subtitle - subtitle1 +msgid "The account you are logged in under does not have enough security privileges to view this page" +msgstr "The account you are logged in under does not have enough security privileges to view this page" + +# login/noViewPage.xml?subtitle2 +# login/noViewPage.xml +#: subtitle - subtitle2 +msgid "Please press back button to continue working with this system." +msgstr "Please press back button to continue working with this system." + +# login/nologin.xml?subtitle +# login/nologin.xml +#: subtitle - subtitle +msgid "[login/nologin.xml?subtitle]" +msgstr "" + +# login/nologin.xml?BSUBMIT +# login/nologin.xml +#: submit - BSUBMIT +msgid "[login/nologin.xml?BSUBMIT] Login" +msgstr "Login" + +# login/showInfo.xml?TITLE +# login/showInfo.xml +#: title - TITLE +msgid "[login/showInfo.xml?TITLE] Information" +msgstr "Information" + +# login/showInfo.xml?MESSAGE +# login/showInfo.xml +#: text - MESSAGE +msgid "[login/showInfo.xml?MESSAGE]" +msgstr "" + +# login/showInfoUpdate.xml?THETITLE1 +# login/showInfoUpdate.xml +#: title - THETITLE1 +msgid "[login/showInfoUpdate.xml?THETITLE1] Information" +msgstr "Information" + +# login/showInfoUpdate.xml?THEMESSAGE1 +# login/showInfoUpdate.xml +#: text - THEMESSAGE1 +msgid "[login/showInfoUpdate.xml?THEMESSAGE1]" +msgstr "" + +# login/showInfoUpdate.xml?THETITLE2 +# login/showInfoUpdate.xml +#: title - THETITLE2 +msgid "Affected Files" +msgstr "Affected Files" + +# login/showInfoUpdate.xml?THEMESSAGE2 +# login/showInfoUpdate.xml +#: textarea - THEMESSAGE2 +msgid "[login/showInfoUpdate.xml?THEMESSAGE2]" +msgstr "" + +# login/showInfoUpdate.xml?THETITLE4 +# login/showInfoUpdate.xml +#: title - THETITLE4 +msgid "Errors" +msgstr "Errors" + +# login/showInfoUpdate.xml?THEMESSAGE4 +# login/showInfoUpdate.xml +#: textarea - THEMESSAGE4 +msgid "[login/showInfoUpdate.xml?THEMESSAGE4]" +msgstr "" + +# login/showInfoUpdate.xml?THETITLE3 +# login/showInfoUpdate.xml +#: title - THETITLE3 +msgid "Environments Updated" +msgstr "Environments Updated" + +# login/showInfoUpdate.xml?SUBTITLE4 +# login/showInfoUpdate.xml +#: subtitle - SUBTITLE4 +msgid "[login/showInfoUpdate.xml?SUBTITLE4]" +msgstr "" + +# login/showInfoUpdate.xml?THEMESSAGE3 +# login/showInfoUpdate.xml +#: text - THEMESSAGE3 +msgid "[login/showInfoUpdate.xml?THEMESSAGE3]" +msgstr "" + +# login/showMessage.xml?TITLE +# login/showMessage.xml +#: title - TITLE +msgid "Error" +msgstr "Error" + +# login/showMessage.xml?MESSAGE +# login/showMessage.xml +#: caption - MESSAGE +msgid "[login/showMessage.xml?MESSAGE]" +msgstr "" + +# login/sysLogin.xml?TITLE +# login/sysLogin.xml +#: title - TITLE +msgid "[login/sysLogin.xml?TITLE] Login" +msgstr "Login" + +# login/sysLogin.xml?USR_USERNAME +# login/sysLogin.xml +#: text - USR_USERNAME +msgid "[login/sysLogin.xml?USR_USERNAME] User" +msgstr "User" + +# login/sysLogin.xml?USR_PASSWORD +# login/sysLogin.xml +#: password - USR_PASSWORD +msgid "[login/sysLogin.xml?USR_PASSWORD] Password" +msgstr "Password" + +# login/sysLogin.xml?USER_ENV +# login/sysLogin.xml +#: dropdown - USER_ENV +msgid "[login/sysLogin.xml?USER_ENV] Workspace" +msgstr "Workspace" + +# login/sysLogin.xml?USER_LANG +# login/sysLogin.xml +#: dropdown - USER_LANG +msgid "[login/sysLogin.xml?USER_LANG] Language" +msgstr "Language" + +# login/sysLogin.xml?BSUBMIT +# login/sysLogin.xml +#: submit - BSUBMIT +msgid "[login/sysLogin.xml?BSUBMIT] Login" +msgstr "Login" + +# login/sysLoginNoWS.xml?TITLE +# login/sysLoginNoWS.xml +#: title - TITLE +msgid "[login/sysLoginNoWS.xml?TITLE] Login" +msgstr "Login" + +# login/sysLoginNoWS.xml?USR_USERNAME +# login/sysLoginNoWS.xml +#: text - USR_USERNAME +msgid "[login/sysLoginNoWS.xml?USR_USERNAME] User" +msgstr "User" + +# login/sysLoginNoWS.xml?USR_PASSWORD +# login/sysLoginNoWS.xml +#: password - USR_PASSWORD +msgid "[login/sysLoginNoWS.xml?USR_PASSWORD] Password" +msgstr "Password" + +# login/sysLoginNoWS.xml?USER_ENV +# login/sysLoginNoWS.xml +#: text - USER_ENV +msgid "[login/sysLoginNoWS.xml?USER_ENV] Workspace" +msgstr "Workspace" + +# login/sysLoginNoWS.xml?USER_LANG +# login/sysLoginNoWS.xml +#: dropdown - USER_LANG +msgid "[login/sysLoginNoWS.xml?USER_LANG] Language" +msgstr "Language" + +# login/sysLoginNoWS.xml?BSUBMIT +# login/sysLoginNoWS.xml +#: submit - BSUBMIT +msgid "[login/sysLoginNoWS.xml?BSUBMIT] Login" +msgstr "Login" + +# messages/messages_Edit.xml?MESS_TITLE +# messages/messages_Edit.xml +#: text - MESS_TITLE +msgid "Message Title" +msgstr "Message Title" + +# messages/messages_Edit.xml?MESS_TYPE +# messages/messages_Edit.xml +#: dropdown - MESS_TYPE +msgid "Send as" +msgstr "Send as" + +# messages/messages_Edit.xml?MESS_TYPE-HTML +# messages/messages_Edit.xml +#: dropdown - MESS_TYPE - HTML +msgid "[messages/messages_Edit.xml?MESS_TYPE-HTML]" +msgstr "HTML" + +# messages/messages_Edit.xml?MESS_TYPE-TEXT +# messages/messages_Edit.xml +#: dropdown - MESS_TYPE - TEXT +msgid "[messages/messages_Edit.xml?MESS_TYPE-TEXT]" +msgstr "Plain text" + +# messages/messages_Edit.xml?MESS_TYPE-SMS +# messages/messages_Edit.xml +#: dropdown - MESS_TYPE - SMS +msgid "[messages/messages_Edit.xml?MESS_TYPE-SMS]" +msgstr "SMS" + +# messages/messages_Edit.xml?MESS_DESCRIPTION +# messages/messages_Edit.xml +#: textarea - MESS_DESCRIPTION +msgid "Content" +msgstr "Content" + +# messages/messages_Edit.xml?ACCEPT +# messages/messages_Edit.xml +#: button - ACCEPT +msgid "[messages/messages_Edit.xml?ACCEPT] Save" +msgstr "Save" + +# messages/messages_List.xml?fMESS_TITLE +# messages/messages_List.xml +#: text - fMESS_TITLE +msgid "[messages/messages_List.xml?fMESS_TITLE] Output document" +msgstr "Output document" + +# messages/messages_List.xml?MESS_TYPE +# messages/messages_List.xml +#: dropdown - MESS_TYPE +msgid "[messages/messages_List.xml?MESS_TYPE] Type" +msgstr "Type" + +# messages/messages_List.xml?MESS_TYPE-HTML +# messages/messages_List.xml +#: dropdown - MESS_TYPE - HTML +msgid "[messages/messages_List.xml?MESS_TYPE-HTML]" +msgstr "HTML" + +# messages/messages_List.xml?MESS_TYPE-TEXT +# messages/messages_List.xml +#: dropdown - MESS_TYPE - TEXT +msgid "[messages/messages_List.xml?MESS_TYPE-TEXT]" +msgstr "Plain text" + +# messages/messages_List.xml?MESS_TYPE-SMS +# messages/messages_List.xml +#: dropdown - MESS_TYPE - SMS +msgid "[messages/messages_List.xml?MESS_TYPE-SMS]" +msgstr "SMS" + +# messages/messages_List.xml?fMESS_DESCRIPTION +# messages/messages_List.xml +#: textarea - fMESS_DESCRIPTION +msgid "[messages/messages_List.xml?fMESS_DESCRIPTION] Content" +msgstr "Content" + +# messages/messages_List.xml?EDIT +# messages/messages_List.xml +#: link - EDIT +msgid "[messages/messages_List.xml?EDIT]" +msgstr "" + +# messages/messages_List.xml?DELETE +# messages/messages_List.xml +#: link - DELETE +msgid "[messages/messages_List.xml?DELETE]" +msgstr "" + +# messages/messages_List.xml?SEARCH +# messages/messages_List.xml +#: button - SEARCH +msgid "[messages/messages_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# messages/messages_Options.xml?MNU_ADD +# messages/messages_Options.xml +#: link - MNU_ADD +msgid "[messages/messages_Options.xml?MNU_ADD] New" +msgstr "New" + +# messages/messages_ShortList.xml?MESS_TITLE +# messages/messages_ShortList.xml +#: text - MESS_TITLE +msgid "[messages/messages_ShortList.xml?MESS_TITLE] Output document" +msgstr "Output document" + +# messages/messages_ShortList.xml?EDIT +# messages/messages_ShortList.xml +#: link - EDIT +msgid "[messages/messages_ShortList.xml?EDIT]" +msgstr "" + +# messages/messages_ShortList.xml?DELETE +# messages/messages_ShortList.xml +#: link - DELETE +msgid "[messages/messages_ShortList.xml?DELETE]" +msgstr "" + +# messages/messages_ShortList.xml?SEARCH +# messages/messages_ShortList.xml +#: button - SEARCH +msgid "[messages/messages_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# outputdocs/outputdocsDynaformList.xml?DYN_UID +# outputdocs/outputdocsDynaformList.xml +#: dropdown - DYN_UID +msgid "[outputdocs/outputdocsDynaformList.xml?DYN_UID] Dynaform" +msgstr "Dynaform" + +# outputdocs/outputdocsDynaformList.xml?DYN_TYPE +# outputdocs/outputdocsDynaformList.xml +#: dropdown - DYN_TYPE +msgid "Template" +msgstr "Template" + +# outputdocs/outputdocsDynaformList.xml?DYN_TYPE-1 +# outputdocs/outputdocsDynaformList.xml +#: dropdown - DYN_TYPE - 1 +msgid "[outputdocs/outputdocsDynaformList.xml?DYN_TYPE-1]" +msgstr "Classic Template" + +# outputdocs/outputdocsDynaformList.xml?DYN_TYPE-2 +# outputdocs/outputdocsDynaformList.xml +#: dropdown - DYN_TYPE - 2 +msgid "[outputdocs/outputdocsDynaformList.xml?DYN_TYPE-2]" +msgstr "Tabular Template" + +# outputdocs/outputdocsDynaformList.xml?ACCEPT +# outputdocs/outputdocsDynaformList.xml +#: button - ACCEPT +msgid "[outputdocs/outputdocsDynaformList.xml?ACCEPT] Save" +msgstr "Save" + +# outputdocs/outputdocsUploadFile.xml?TITLE1 +# outputdocs/outputdocsUploadFile.xml +#: title - TITLE1 +msgid "[outputdocs/outputdocsUploadFile.xml?TITLE1] Download" +msgstr "Download" + +# outputdocs/outputdocsUploadFile.xml?OUT_DOC_LINK +# outputdocs/outputdocsUploadFile.xml +#: link - OUT_DOC_LINK +msgid "Click in the link to download current file" +msgstr "Click in the link to download current file" + +# outputdocs/outputdocsUploadFile.xml?TITLE2 +# outputdocs/outputdocsUploadFile.xml +#: title - TITLE2 +msgid "[outputdocs/outputdocsUploadFile.xml?TITLE2] Upload" +msgstr "Upload" + +# outputdocs/outputdocsUploadFile.xml?OUT_DOC_FILE +# outputdocs/outputdocsUploadFile.xml +#: file - OUT_DOC_FILE +msgid "Upload a modified file" +msgstr "Upload a modified file" + +# outputdocs/outputdocsUploadFile.xml?BTN +# outputdocs/outputdocsUploadFile.xml +#: submit - BTN +msgid "upload" +msgstr "upload" + +# outputdocs/outputdocs_Edit.xml?INSERT_VARIABLE +# outputdocs/outputdocs_Edit.xml +#: button - INSERT_VARIABLE +msgid "[outputdocs/outputdocs_Edit.xml?INSERT_VARIABLE] @#" +msgstr "@#" + +# outputdocs/outputdocs_Edit.xml?OUT_DOC_TEMPLATE +# outputdocs/outputdocs_Edit.xml +#: html - OUT_DOC_TEMPLATE +msgid "[outputdocs/outputdocs_Edit.xml?OUT_DOC_TEMPLATE]" +msgstr "" + +# outputdocs/outputdocs_Edit.xml?ACCEPT +# outputdocs/outputdocs_Edit.xml +#: button - ACCEPT +msgid "[outputdocs/outputdocs_Edit.xml?ACCEPT] Save" +msgstr "Save" + +# outputdocs/outputdocs_Edit.xml?BTN_CANCEL +# outputdocs/outputdocs_Edit.xml +#: button - BTN_CANCEL +msgid "[outputdocs/outputdocs_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# outputdocs/outputdocs_List.xml?OUT_DOC_TITLE +# outputdocs/outputdocs_List.xml +#: text - OUT_DOC_TITLE +msgid "[outputdocs/outputdocs_List.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# outputdocs/outputdocs_List.xml?OUT_DOC_FILENAME +# outputdocs/outputdocs_List.xml +#: text - OUT_DOC_FILENAME +msgid "[outputdocs/outputdocs_List.xml?OUT_DOC_FILENAME] Filename" +msgstr "Filename" + +# outputdocs/outputdocs_List.xml?OUT_DOC_DESCRIPTION +# outputdocs/outputdocs_List.xml +#: textarea - OUT_DOC_DESCRIPTION +msgid "[outputdocs/outputdocs_List.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# outputdocs/outputdocs_List.xml?EDIT +# outputdocs/outputdocs_List.xml +#: link - EDIT +msgid "[outputdocs/outputdocs_List.xml?EDIT]" +msgstr "" + +# outputdocs/outputdocs_List.xml?DELETE +# outputdocs/outputdocs_List.xml +#: link - DELETE +msgid "[outputdocs/outputdocs_List.xml?DELETE]" +msgstr "" + +# outputdocs/outputdocs_List.xml?SEARCH +# outputdocs/outputdocs_List.xml +#: button - SEARCH +msgid "[outputdocs/outputdocs_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# outputdocs/outputdocs_New.xml?TITLE +# outputdocs/outputdocs_New.xml +#: title - TITLE +msgid "Output Document Information" +msgstr "Output Document Information" + +# outputdocs/outputdocs_New.xml?OUT_DOC_TYPE +# outputdocs/outputdocs_New.xml +#: radiogroup - OUT_DOC_TYPE +msgid "Type of Output Document" +msgstr "Type of Output Document" + +# outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-HTML +# outputdocs/outputdocs_New.xml +#: radiogroup - OUT_DOC_TYPE - HTML +msgid "[outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-HTML]" +msgstr "HTML" + +# outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-JRXML +# outputdocs/outputdocs_New.xml +#: radiogroup - OUT_DOC_TYPE - JRXML +msgid "[outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-JRXML]" +msgstr "Dynaform to PDF" + +# outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-ACROFORM +# outputdocs/outputdocs_New.xml +#: radiogroup - OUT_DOC_TYPE - ACROFORM +msgid "[outputdocs/outputdocs_New.xml?OUT_DOC_TYPE-ACROFORM]" +msgstr "Fill Adobe Acroform" + +# outputdocs/outputdocs_New.xml?DYN_UID +# outputdocs/outputdocs_New.xml +#: dropdown - DYN_UID +msgid "[outputdocs/outputdocs_New.xml?DYN_UID] Dynaform" +msgstr "Dynaform" + +# outputdocs/outputdocs_New.xml?OUT_DOC_TITLE +# outputdocs/outputdocs_New.xml +#: text - OUT_DOC_TITLE +msgid "[outputdocs/outputdocs_New.xml?OUT_DOC_TITLE] Title" +msgstr "Title" + +# outputdocs/outputdocs_New.xml?OUT_DOC_FILENAME +# outputdocs/outputdocs_New.xml +#: textpm - OUT_DOC_FILENAME +msgid "Filename generated" +msgstr "Filename generated" + +# outputdocs/outputdocs_New.xml?OUT_DOC_DESCRIPTION +# outputdocs/outputdocs_New.xml +#: textarea - OUT_DOC_DESCRIPTION +msgid "[outputdocs/outputdocs_New.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# outputdocs/outputdocs_New.xml?DYN_TYPE +# outputdocs/outputdocs_New.xml +#: dropdown - DYN_TYPE +msgid "[outputdocs/outputdocs_New.xml?DYN_TYPE] Template" +msgstr "Template" + +# outputdocs/outputdocs_New.xml?DYN_TYPE-1 +# outputdocs/outputdocs_New.xml +#: dropdown - DYN_TYPE - 1 +msgid "[outputdocs/outputdocs_New.xml?DYN_TYPE-1]" +msgstr "Classic Template" + +# outputdocs/outputdocs_New.xml?DYN_TYPE-2 +# outputdocs/outputdocs_New.xml +#: dropdown - DYN_TYPE - 2 +msgid "[outputdocs/outputdocs_New.xml?DYN_TYPE-2]" +msgstr "Tabular Template" + +# outputdocs/outputdocs_New.xml?ACCEPT +# outputdocs/outputdocs_New.xml +#: button - ACCEPT +msgid "[outputdocs/outputdocs_New.xml?ACCEPT] Save" +msgstr "Save" + +# outputdocs/outputdocs_New.xml?ACCEPT2 +# outputdocs/outputdocs_New.xml +#: submit - ACCEPT2 +msgid "Save submit" +msgstr "Save submit" + +# outputdocs/outputdocs_Options.xml?MNU_ADD +# outputdocs/outputdocs_Options.xml +#: link - MNU_ADD +msgid "[outputdocs/outputdocs_Options.xml?MNU_ADD] New" +msgstr "New" + +# outputdocs/outputdocs_Properties.xml?TITLE +# outputdocs/outputdocs_Properties.xml +#: title - TITLE +msgid "[outputdocs/outputdocs_Properties.xml?TITLE] Output Document Information" +msgstr "Output Document Information" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_TITLE +# outputdocs/outputdocs_Properties.xml +#: text - OUT_DOC_TITLE +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_TITLE] Title" +msgstr "Title" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_FILENAME +# outputdocs/outputdocs_Properties.xml +#: textpm - OUT_DOC_FILENAME +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_FILENAME] Filename generated" +msgstr "Filename generated" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_DESCRIPTION +# outputdocs/outputdocs_Properties.xml +#: textarea - OUT_DOC_DESCRIPTION +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_DESCRIPTION] Description" +msgstr "Description" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_LANDSCAPE +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_LANDSCAPE +msgid "Orientation" +msgstr "Orientation" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_LANDSCAPE-'' +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_LANDSCAPE - '' +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_LANDSCAPE-'']" +msgstr "Portrait" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_LANDSCAPE-1 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_LANDSCAPE - 1 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_LANDSCAPE-1]" +msgstr "Landscape" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_GENERATE +msgid "Output Document to Generate" +msgstr "Output Document to Generate" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-BOTH +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_GENERATE - BOTH +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-BOTH]" +msgstr "BOTH" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-DOC +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_GENERATE - DOC +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-DOC]" +msgstr "DOC" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-PDF +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_GENERATE - PDF +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_GENERATE-PDF]" +msgstr "PDF" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_VERSIONING +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING] Enable Versioning" +msgstr "Enable Versioning" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING-'' +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_VERSIONING - '' +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING-'']" +msgstr "NO" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING-1 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_VERSIONING - 1 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_VERSIONING-1]" +msgstr "YES" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA +msgid "Media" +msgstr "Media" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Letter +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Letter +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Letter]" +msgstr "Letter" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Legal +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Legal +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Legal]" +msgstr "Legal" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Executive +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Executive +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Executive]" +msgstr "Executive" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-B5 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - B5 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-B5]" +msgstr "B5" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Folio +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Folio +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Folio]" +msgstr "Folio" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A0Oversize +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A0Oversize +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A0Oversize]" +msgstr "A0Oversize" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A0 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A0 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A0]" +msgstr "A0" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A1 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A1 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A1]" +msgstr "A1" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A2 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A2 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A2]" +msgstr "A2" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A3 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A3 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A3]" +msgstr "A3" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A4 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A4 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A4]" +msgstr "A4" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A5 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A5 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A5]" +msgstr "A5" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A6 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A6 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A6]" +msgstr "A6" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A7 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A7 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A7]" +msgstr "A7" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A8 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A8 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A8]" +msgstr "A8" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A9 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A9 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A9]" +msgstr "A9" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A10 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - A10 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-A10]" +msgstr "A10" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot640 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Screenshot640 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot640]" +msgstr "Screenshot640" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot800 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Screenshot800 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot800]" +msgstr "Screenshot800" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot1024 +# outputdocs/outputdocs_Properties.xml +#: dropdown - OUT_DOC_MEDIA - Screenshot1024 +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_MEDIA-Screenshot1024]" +msgstr "Screenshot1024" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_LEFT_MARGIN +# outputdocs/outputdocs_Properties.xml +#: text - OUT_DOC_LEFT_MARGIN +msgid "Left Margin" +msgstr "Left Margin" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_RIGHT_MARGIN +# outputdocs/outputdocs_Properties.xml +#: text - OUT_DOC_RIGHT_MARGIN +msgid "Right Margin" +msgstr "Right Margin" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_TOP_MARGIN +# outputdocs/outputdocs_Properties.xml +#: text - OUT_DOC_TOP_MARGIN +msgid "Top Margin" +msgstr "Top Margin" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_BOTTOM_MARGIN +# outputdocs/outputdocs_Properties.xml +#: text - OUT_DOC_BOTTOM_MARGIN +msgid "Bottom Margin" +msgstr "Bottom Margin" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_DESTINATION_PATH +# outputdocs/outputdocs_Properties.xml +#: textpm - OUT_DOC_DESTINATION_PATH +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_DESTINATION_PATH] Destination Path" +msgstr "Destination Path" + +# outputdocs/outputdocs_Properties.xml?OUT_DOC_TAGS +# outputdocs/outputdocs_Properties.xml +#: textpm - OUT_DOC_TAGS +msgid "[outputdocs/outputdocs_Properties.xml?OUT_DOC_TAGS] Tags" +msgstr "Tags" + +# outputdocs/outputdocs_Properties.xml?BTN_CANCEL +# outputdocs/outputdocs_Properties.xml +#: button - BTN_CANCEL +msgid "[outputdocs/outputdocs_Properties.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# outputdocs/outputdocs_Properties.xml?ACCEPT +# outputdocs/outputdocs_Properties.xml +#: button - ACCEPT +msgid "[outputdocs/outputdocs_Properties.xml?ACCEPT] Save" +msgstr "Save" + +# outputdocs/outputdocs_ShortList.xml?OUT_DOC_TITLE +# outputdocs/outputdocs_ShortList.xml +#: text - OUT_DOC_TITLE +msgid "[outputdocs/outputdocs_ShortList.xml?OUT_DOC_TITLE] Title" +msgstr "Title" + +# outputdocs/outputdocs_ShortList.xml?OUT_DOC_TYPE +# outputdocs/outputdocs_ShortList.xml +#: text - OUT_DOC_TYPE +msgid "[outputdocs/outputdocs_ShortList.xml?OUT_DOC_TYPE] Type" +msgstr "Type" + +# outputdocs/outputdocs_ShortList.xml?EDIT +# outputdocs/outputdocs_ShortList.xml +#: link - EDIT +msgid "[outputdocs/outputdocs_ShortList.xml?EDIT]" +msgstr "" + +# outputdocs/outputdocs_ShortList.xml?PROPERTIES +# outputdocs/outputdocs_ShortList.xml +#: link - PROPERTIES +msgid "[outputdocs/outputdocs_ShortList.xml?PROPERTIES]" +msgstr "" + +# outputdocs/outputdocs_ShortList.xml?DELETE +# outputdocs/outputdocs_ShortList.xml +#: link - DELETE +msgid "[outputdocs/outputdocs_ShortList.xml?DELETE]" +msgstr "" + +# outputdocs/outputdocs_ShortList.xml?GET_UID +# outputdocs/outputdocs_ShortList.xml +#: link - GET_UID +msgid "[outputdocs/outputdocs_ShortList.xml?GET_UID]" +msgstr "" + +# outputdocs/outputdocs_ShortList.xml?SEARCH +# outputdocs/outputdocs_ShortList.xml +#: button - SEARCH +msgid "[outputdocs/outputdocs_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# patterns/patterns_Current.xml?TITLE +# patterns/patterns_Current.xml +#: title - TITLE +msgid "Workflow Pattern" +msgstr "Workflow Pattern" + +# patterns/patterns_Current.xml?ROU_TYPE +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE +msgid "[patterns/patterns_Current.xml?ROU_TYPE] Type" +msgstr "Type" + +# patterns/patterns_Current.xml?ROU_TYPE-'' +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - '' +msgid "[patterns/patterns_Current.xml?ROU_TYPE-'']" +msgstr "- Select - " + +# patterns/patterns_Current.xml?ROU_TYPE-SEQUENTIAL +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - SEQUENTIAL +msgid "[patterns/patterns_Current.xml?ROU_TYPE-SEQUENTIAL]" +msgstr "Sequential" + +# patterns/patterns_Current.xml?ROU_TYPE-SELECT +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - SELECT +msgid "[patterns/patterns_Current.xml?ROU_TYPE-SELECT]" +msgstr "Selection" + +# patterns/patterns_Current.xml?ROU_TYPE-EVALUATE +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - EVALUATE +msgid "[patterns/patterns_Current.xml?ROU_TYPE-EVALUATE]" +msgstr "Evaluation" + +# patterns/patterns_Current.xml?ROU_TYPE-PARALLEL +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - PARALLEL +msgid "[patterns/patterns_Current.xml?ROU_TYPE-PARALLEL]" +msgstr "Parallel (fork)" + +# patterns/patterns_Current.xml?ROU_TYPE-PARALLEL-BY-EVALUATION +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - PARALLEL-BY-EVALUATION +msgid "[patterns/patterns_Current.xml?ROU_TYPE-PARALLEL-BY-EVALUATION]" +msgstr "Parallel by evaluation (fork)" + +# patterns/patterns_Current.xml?ROU_TYPE-SEC-JOIN +# patterns/patterns_Current.xml +#: dropdown - ROU_TYPE - SEC-JOIN +msgid "[patterns/patterns_Current.xml?ROU_TYPE-SEC-JOIN]" +msgstr "Parallel (join)" + +# patterns/patterns_Current.xml?ROU_NEXT_TASK +# patterns/patterns_Current.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_Current.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_Current.xml?ROU_NEXT_TASK--1 +# patterns/patterns_Current.xml +#: dropdown - ROU_NEXT_TASK - -1 +msgid "[patterns/patterns_Current.xml?ROU_NEXT_TASK--1]" +msgstr "End of process" + +# patterns/patterns_Current.xml?ROU_NEXT_TASK--2 +# patterns/patterns_Current.xml +#: dropdown - ROU_NEXT_TASK - -2 +msgid "[patterns/patterns_Current.xml?ROU_NEXT_TASK--2]" +msgstr "Leaf task" + +# patterns/patterns_Current.xml?ROU_TO_LAST_USER +# patterns/patterns_Current.xml +#: dropdown - ROU_TO_LAST_USER +msgid "Selection of executant" +msgstr "Selection of executant" + +# patterns/patterns_Current.xml?ROU_TO_LAST_USER-FALSE +# patterns/patterns_Current.xml +#: dropdown - ROU_TO_LAST_USER - FALSE +msgid "[patterns/patterns_Current.xml?ROU_TO_LAST_USER-FALSE]" +msgstr "Rules and user groups" + +# patterns/patterns_Current.xml?ROU_TO_LAST_USER-TRUE +# patterns/patterns_Current.xml +#: dropdown - ROU_TO_LAST_USER - TRUE +msgid "[patterns/patterns_Current.xml?ROU_TO_LAST_USER-TRUE]" +msgstr "Last executant of the task" + +# patterns/patterns_Current.xml?SAVE +# patterns/patterns_Current.xml +#: button - SAVE +msgid "[patterns/patterns_Current.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_Evaluate.xml?TITLE +# patterns/patterns_Evaluate.xml +#: title - TITLE +msgid "[patterns/patterns_Evaluate.xml?TITLE] Evaluation" +msgstr "Evaluation" + +# patterns/patterns_Evaluate.xml?BTN_CANCEL +# patterns/patterns_Evaluate.xml +#: button - BTN_CANCEL +msgid "[patterns/patterns_Evaluate.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# patterns/patterns_Evaluate.xml?SAVE +# patterns/patterns_Evaluate.xml +#: button - SAVE +msgid "[patterns/patterns_Evaluate.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_GridEvaluateType.xml?ROU_NEXT_TASK +# patterns/patterns_GridEvaluateType.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_GridEvaluateType.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_GridEvaluateType.xml?ROU_NEXT_TASK--1 +# patterns/patterns_GridEvaluateType.xml +#: dropdown - ROU_NEXT_TASK - -1 +msgid "[patterns/patterns_GridEvaluateType.xml?ROU_NEXT_TASK--1]" +msgstr "End of process" + +# patterns/patterns_GridEvaluateType.xml?ROU_CONDITION +# patterns/patterns_GridEvaluateType.xml +#: textpm - ROU_CONDITION +msgid "[patterns/patterns_GridEvaluateType.xml?ROU_CONDITION] Condition" +msgstr "Condition" + +# patterns/patterns_GridParallelByEvaluationType.xml?ROU_NEXT_TASK +# patterns/patterns_GridParallelByEvaluationType.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_GridParallelByEvaluationType.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_GridParallelByEvaluationType.xml?ROU_CONDITION +# patterns/patterns_GridParallelByEvaluationType.xml +#: textpm - ROU_CONDITION +msgid "[patterns/patterns_GridParallelByEvaluationType.xml?ROU_CONDITION] Condition" +msgstr "Condition" + +# patterns/patterns_GridParallelType.xml?ROU_NEXT_TASK +# patterns/patterns_GridParallelType.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_GridParallelType.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_GridSelectType.xml?ROU_NEXT_TASK +# patterns/patterns_GridSelectType.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_GridSelectType.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_GridSelectType.xml?ROU_NEXT_TASK--1 +# patterns/patterns_GridSelectType.xml +#: dropdown - ROU_NEXT_TASK - -1 +msgid "[patterns/patterns_GridSelectType.xml?ROU_NEXT_TASK--1]" +msgstr "End of process" + +# patterns/patterns_GridSelectType.xml?ROU_CONDITION +# patterns/patterns_GridSelectType.xml +#: text - ROU_CONDITION +msgid "[patterns/patterns_GridSelectType.xml?ROU_CONDITION] Description" +msgstr "Description" + +# patterns/patterns_Parallel.xml?TITLE +# patterns/patterns_Parallel.xml +#: title - TITLE +msgid "Parallel" +msgstr "Parallel" + +# patterns/patterns_Parallel.xml?BTN_CANCEL +# patterns/patterns_Parallel.xml +#: button - BTN_CANCEL +msgid "[patterns/patterns_Parallel.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# patterns/patterns_Parallel.xml?SAVE +# patterns/patterns_Parallel.xml +#: button - SAVE +msgid "[patterns/patterns_Parallel.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_ParallelByEvaluation.xml?TITLE +# patterns/patterns_ParallelByEvaluation.xml +#: title - TITLE +msgid "Parallel By Evaluation" +msgstr "Parallel By Evaluation" + +# patterns/patterns_ParallelByEvaluation.xml?BTN_CANCEL +# patterns/patterns_ParallelByEvaluation.xml +#: button - BTN_CANCEL +msgid "[patterns/patterns_ParallelByEvaluation.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# patterns/patterns_ParallelByEvaluation.xml?SAVE +# patterns/patterns_ParallelByEvaluation.xml +#: button - SAVE +msgid "[patterns/patterns_ParallelByEvaluation.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_ParallelJoin.xml?TITLE +# patterns/patterns_ParallelJoin.xml +#: title - TITLE +msgid "Parallel Join" +msgstr "Parallel Join" + +# patterns/patterns_ParallelJoin.xml?ROU_NEXT_TASK +# patterns/patterns_ParallelJoin.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_ParallelJoin.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_ParallelJoin.xml?ROU_NEXT_TASK--1 +# patterns/patterns_ParallelJoin.xml +#: dropdown - ROU_NEXT_TASK - -1 +msgid "[patterns/patterns_ParallelJoin.xml?ROU_NEXT_TASK--1]" +msgstr "End of process" + +# patterns/patterns_ParallelJoin.xml?SAVE +# patterns/patterns_ParallelJoin.xml +#: button - SAVE +msgid "[patterns/patterns_ParallelJoin.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_Select.xml?TITLE +# patterns/patterns_Select.xml +#: title - TITLE +msgid "[patterns/patterns_Select.xml?TITLE] Selection" +msgstr "Selection" + +# patterns/patterns_Select.xml?BTN_CANCEL +# patterns/patterns_Select.xml +#: button - BTN_CANCEL +msgid "[patterns/patterns_Select.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# patterns/patterns_Select.xml?SAVE +# patterns/patterns_Select.xml +#: button - SAVE +msgid "[patterns/patterns_Select.xml?SAVE] Save" +msgstr "Save" + +# patterns/patterns_Sequential.xml?TITLE +# patterns/patterns_Sequential.xml +#: title - TITLE +msgid "[patterns/patterns_Sequential.xml?TITLE] Sequential" +msgstr "Sequential" + +# patterns/patterns_Sequential.xml?ROU_NEXT_TASK +# patterns/patterns_Sequential.xml +#: dropdown - ROU_NEXT_TASK +msgid "[patterns/patterns_Sequential.xml?ROU_NEXT_TASK] Next Task" +msgstr "Next Task" + +# patterns/patterns_Sequential.xml?ROU_NEXT_TASK--1 +# patterns/patterns_Sequential.xml +#: dropdown - ROU_NEXT_TASK - -1 +msgid "[patterns/patterns_Sequential.xml?ROU_NEXT_TASK--1]" +msgstr "End of process" + +# patterns/patterns_Sequential.xml?BTN_CANCEL +# patterns/patterns_Sequential.xml +#: button - BTN_CANCEL +msgid "[patterns/patterns_Sequential.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# patterns/patterns_Sequential.xml?SAVE +# patterns/patterns_Sequential.xml +#: button - SAVE +msgid "[patterns/patterns_Sequential.xml?SAVE] Save" +msgstr "Save" + +# processCategory/processCategory.xml?title1 +# processCategory/processCategory.xml +#: title - title1 +msgid "ProcessCategory form" +msgstr "ProcessCategory form" + +# processCategory/processCategory.xml?CATEGORY_UID +# processCategory/processCategory.xml +#: text - CATEGORY_UID +msgid "Gory Uid" +msgstr "Gory Uid" + +# processCategory/processCategory.xml?CATEGORY_PARENT +# processCategory/processCategory.xml +#: text - CATEGORY_PARENT +msgid "Gory Parent" +msgstr "Gory Parent" + +# processCategory/processCategory.xml?CATEGORY_NAME +# processCategory/processCategory.xml +#: text - CATEGORY_NAME +msgid "Gory Name" +msgstr "Gory Name" + +# processCategory/processCategory.xml?CATEGORY_ICON +# processCategory/processCategory.xml +#: text - CATEGORY_ICON +msgid "Gory Icon" +msgstr "Gory Icon" + +# processCategory/processCategory.xml?BTN_SUBMIT +# processCategory/processCategory.xml +#: submit - BTN_SUBMIT +msgid "[processCategory/processCategory.xml?BTN_SUBMIT] save" +msgstr "save" + +# processCategory/processCategoryDelete.xml?title1 +# processCategory/processCategoryDelete.xml +#: title - title1 +msgid "Delete Process Category" +msgstr "Delete Process Category" + +# processCategory/processCategoryDelete.xml?LABEL_CATEGORY_NAME +# processCategory/processCategoryDelete.xml +#: caption - LABEL_CATEGORY_NAME +msgid "Category Name" +msgstr "Category Name" + +# processCategory/processCategoryDelete.xml?BTN_SUBMIT +# processCategory/processCategoryDelete.xml +#: submit - BTN_SUBMIT +msgid "[processCategory/processCategoryDelete.xml?BTN_SUBMIT] delete" +msgstr "delete" + +# processCategory/processCategoryDelete.xml?BTN_CANCEL +# processCategory/processCategoryDelete.xml +#: button - BTN_CANCEL +msgid "[processCategory/processCategoryDelete.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processCategory/processCategoryEdit.xml?title1 +# processCategory/processCategoryEdit.xml +#: title - title1 +msgid "Process Category form" +msgstr "Process Category form" + +# processCategory/processCategoryEdit.xml?CATEGORY_NAME +# processCategory/processCategoryEdit.xml +#: text - CATEGORY_NAME +msgid "[processCategory/processCategoryEdit.xml?CATEGORY_NAME] Category Name" +msgstr "Category Name" + +# processCategory/processCategoryEdit.xml?BTN_SUBMIT +# processCategory/processCategoryEdit.xml +#: button - BTN_SUBMIT +msgid "[processCategory/processCategoryEdit.xml?BTN_SUBMIT] save" +msgstr "save" + +# processCategory/processCategoryEdit.xml?BTN_CANCEL +# processCategory/processCategoryEdit.xml +#: button - BTN_CANCEL +msgid "[processCategory/processCategoryEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processCategory/processCategoryList.xml?CATEGORY_NAME +# processCategory/processCategoryList.xml +#: text - CATEGORY_NAME +msgid "[processCategory/processCategoryList.xml?CATEGORY_NAME] Category Name" +msgstr "Category Name" + +# processCategory/processCategoryList.xml?LINK +# processCategory/processCategoryList.xml +#: link - LINK +msgid "[processCategory/processCategoryList.xml?LINK]" +msgstr "" + +# processCategory/processCategoryList.xml?LINK2 +# processCategory/processCategoryList.xml +#: link - LINK2 +msgid "[processCategory/processCategoryList.xml?LINK2]" +msgstr "" + +# processCategory/processCategoryOptions.xml?MNU_NEW +# processCategory/processCategoryOptions.xml +#: link - MNU_NEW +msgid "[processCategory/processCategoryOptions.xml?MNU_NEW] New" +msgstr "New" + +# processes/objectpmView.xml?thetitle +# processes/objectpmView.xml +#: title - thetitle +msgid "Process Properties" +msgstr "Process Properties" + +# processes/objectpmView.xml?title +# processes/objectpmView.xml +#: text - title +msgid "[processes/objectpmView.xml?title] Title" +msgstr "Title" + +# processes/objectpmView.xml?version +# processes/objectpmView.xml +#: text - version +msgid "[processes/objectpmView.xml?version] Version" +msgstr "Version" + +# processes/objectpmView.xml?pm_version +# processes/objectpmView.xml +#: text - pm_version +msgid "P.M. rev. required" +msgstr "P.M. rev. required" + +# processes/objectpmView.xml?category +# processes/objectpmView.xml +#: text - category +msgid "[processes/objectpmView.xml?category] Category" +msgstr "Category" + +# processes/objectpmView.xml?rating +# processes/objectpmView.xml +#: text - rating +msgid "Rating" +msgstr "Rating" + +# processes/objectpmView.xml?downloads +# processes/objectpmView.xml +#: text - downloads +msgid "Downloads" +msgstr "Downloads" + +# processes/objectpmView.xml?subscriptions +# processes/objectpmView.xml +#: text - subscriptions +msgid "Subscriptions" +msgstr "Subscriptions" + +# processes/objectpmView.xml?username +# processes/objectpmView.xml +#: text - username +msgid "[processes/objectpmView.xml?username] Author" +msgstr "Author" + +# processes/objectpmView.xml?privacy +# processes/objectpmView.xml +#: dropdown - privacy +msgid "Privacy" +msgstr "Privacy" + +# processes/objectpmView.xml?privacy-FREE +# processes/objectpmView.xml +#: dropdown - privacy - FREE +msgid "[processes/objectpmView.xml?privacy-FREE]" +msgstr "Free Download" + +# processes/objectpmView.xml?privacy-PUBLIC +# processes/objectpmView.xml +#: dropdown - privacy - PUBLIC +msgid "[processes/objectpmView.xml?privacy-PUBLIC]" +msgstr "Public" + +# processes/objectpmView.xml?privacy-PRIVATE +# processes/objectpmView.xml +#: dropdown - privacy - PRIVATE +msgid "[processes/objectpmView.xml?privacy-PRIVATE]" +msgstr "Private" + +# processes/objectpmView.xml?privacy-COLOSA +# processes/objectpmView.xml +#: dropdown - privacy - COLOSA +msgid "[processes/objectpmView.xml?privacy-COLOSA]" +msgstr "Colosa" + +# processes/objectpmView.xml?createDate +# processes/objectpmView.xml +#: text - createDate +msgid "[processes/objectpmView.xml?createDate] Create Date" +msgstr "Create Date" + +# processes/objectpmView.xml?updateDate +# processes/objectpmView.xml +#: text - updateDate +msgid "[processes/objectpmView.xml?updateDate] Update Date" +msgstr "Update Date" + +# processes/objectpmView.xml?description +# processes/objectpmView.xml +#: text - description +msgid "[processes/objectpmView.xml?description] Description" +msgstr "Description" + +# processes/objectpmView.xml?subinstallSteps +# processes/objectpmView.xml +#: subtitle - subinstallSteps +msgid "Install Steps" +msgstr "Install Steps" + +# processes/objectpmView.xml?installSteps +# processes/objectpmView.xml +#: text - installSteps +msgid "[processes/objectpmView.xml?installSteps]" +msgstr "" + +# processes/objectpmView.xml?link +# processes/objectpmView.xml +#: link - link +msgid "link" +msgstr "" + +# processes/processes_Assignuser.xml?MNU_ASSIGN +# processes/processes_Assignuser.xml +#: link - MNU_ASSIGN +msgid "[processes/processes_Assignuser.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# processes/processes_DeleteCases.xml?title1 +# processes/processes_DeleteCases.xml +#: title - title1 +msgid "Process: @#PRO_TITLE" +msgstr "Process: @#PRO_TITLE" + +# processes/processes_DeleteCases.xml?MESSAGE +# processes/processes_DeleteCases.xml +#: title - MESSAGE +msgid "Are you sure that you want to delete this process?" +msgstr "Are you sure that you want to delete this process?" + +# processes/processes_DeleteCases.xml?TO_DO +# processes/processes_DeleteCases.xml +#: text - TO_DO +msgid "[processes/processes_DeleteCases.xml?TO_DO] To Do" +msgstr "To Do" + +# processes/processes_DeleteCases.xml?COMPLETED +# processes/processes_DeleteCases.xml +#: text - COMPLETED +msgid "[processes/processes_DeleteCases.xml?COMPLETED] Completed" +msgstr "Completed" + +# processes/processes_DeleteCases.xml?DRAFT +# processes/processes_DeleteCases.xml +#: text - DRAFT +msgid "[processes/processes_DeleteCases.xml?DRAFT] Draft" +msgstr "Draft" + +# processes/processes_DeleteCases.xml?CANCELLED +# processes/processes_DeleteCases.xml +#: text - CANCELLED +msgid "[processes/processes_DeleteCases.xml?CANCELLED] Cancelled" +msgstr "Cancelled" + +# processes/processes_DirectoriesList.xml?DIRECTORY +# processes/processes_DirectoriesList.xml +#: text - DIRECTORY +msgid "[processes/processes_DirectoriesList.xml?DIRECTORY]" +msgstr "" + +# processes/processes_Edit.xml?TITLE1 +# processes/processes_Edit.xml +#: title - TITLE1 +msgid "[processes/processes_Edit.xml?TITLE1] Process Information" +msgstr "Process Information" + +# processes/processes_Edit.xml?PRO_TITLE +# processes/processes_Edit.xml +#: text - PRO_TITLE +msgid "[processes/processes_Edit.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_Edit.xml?PRO_DESCRIPTION +# processes/processes_Edit.xml +#: textarea - PRO_DESCRIPTION +msgid "[processes/processes_Edit.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_Edit.xml?PRO_CALENDAR +# processes/processes_Edit.xml +#: dropdown - PRO_CALENDAR +msgid "[processes/processes_Edit.xml?PRO_CALENDAR] Calendar" +msgstr "Calendar" + +# processes/processes_Edit.xml?PRO_CALENDAR-'' +# processes/processes_Edit.xml +#: dropdown - PRO_CALENDAR - '' +msgid "[processes/processes_Edit.xml?PRO_CALENDAR-'']" +msgstr "- None -" + +# processes/processes_Edit.xml?PRO_CATEGORY +# processes/processes_Edit.xml +#: dropdown - PRO_CATEGORY +msgid "Process Category" +msgstr "Process Category" + +# processes/processes_Edit.xml?PRO_CATEGORY-'' +# processes/processes_Edit.xml +#: dropdown - PRO_CATEGORY - '' +msgid "[processes/processes_Edit.xml?PRO_CATEGORY-'']" +msgstr "- None -" + +# processes/processes_Edit.xml?PRO_DEBUG +# processes/processes_Edit.xml +#: checkbox - PRO_DEBUG +msgid "[processes/processes_Edit.xml?PRO_DEBUG] Debug" +msgstr "Debug" + +# processes/processes_Edit.xml?BTN_CANCEL +# processes/processes_Edit.xml +#: button - BTN_CANCEL +msgid "[processes/processes_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_Edit.xml?SUBMIT +# processes/processes_Edit.xml +#: button - SUBMIT +msgid "[processes/processes_Edit.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_EditObjectPermission.xml?TITLE +# processes/processes_EditObjectPermission.xml +#: title - TITLE +msgid "Edit Specific Permission" +msgstr "Edit Specific Permission" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS +msgid "Status Case" +msgstr "Status Case" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-ALL +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS - ALL +msgid "[processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-ALL]" +msgstr "ALL" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-DRAFT +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS - DRAFT +msgid "[processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-DRAFT]" +msgstr "DRAFT" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-TO_DO +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS - TO_DO +msgid "[processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-TO_DO]" +msgstr "TO_DO" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-PAUSED +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS - PAUSED +msgid "[processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-PAUSED]" +msgstr "PAUSED" + +# processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-COMPLETED +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_CASE_STATUS - COMPLETED +msgid "[processes/processes_EditObjectPermission.xml?OP_CASE_STATUS-COMPLETED]" +msgstr "COMPLETED" + +# processes/processes_EditObjectPermission.xml?TAS_UID +# processes/processes_EditObjectPermission.xml +#: dropdown - TAS_UID +msgid "Target Task" +msgstr "Target Task" + +# processes/processes_EditObjectPermission.xml?TAS_UID-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - TAS_UID - '' +msgid "[processes/processes_EditObjectPermission.xml?TAS_UID-'']" +msgstr "All Tasks" + +# processes/processes_EditObjectPermission.xml?GROUP_USER +# processes/processes_EditObjectPermission.xml +#: dropdown - GROUP_USER +msgid "Group or User" +msgstr "Group or User" + +# processes/processes_EditObjectPermission.xml?OP_TASK_SOURCE +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_TASK_SOURCE +msgid "[processes/processes_EditObjectPermission.xml?OP_TASK_SOURCE] Origin Task" +msgstr "Origin Task" + +# processes/processes_EditObjectPermission.xml?OP_TASK_SOURCE-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_TASK_SOURCE - '' +msgid "[processes/processes_EditObjectPermission.xml?OP_TASK_SOURCE-'']" +msgstr "All Tasks" + +# processes/processes_EditObjectPermission.xml?OP_PARTICIPATE +# processes/processes_EditObjectPermission.xml +#: yesno - OP_PARTICIPATE +msgid "Participation required?" +msgstr "Participation required?" + +# processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_OBJ_TYPE +msgid "[processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE] Type" +msgstr "Type" + +# processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-ANY +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - ANY +msgid "[processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-ANY]" +msgstr "All" + +# processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-DYNAFORM +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - DYNAFORM +msgid "[processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-DYNAFORM]" +msgstr "Dynaform" + +# processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-INPUT +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - INPUT +msgid "[processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-INPUT]" +msgstr "Input Document" + +# processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-OUTPUT +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - OUTPUT +msgid "[processes/processes_EditObjectPermission.xml?OP_OBJ_TYPE-OUTPUT]" +msgstr "Output Document" + +# processes/processes_EditObjectPermission.xml?ALL +# processes/processes_EditObjectPermission.xml +#: dropdown - ALL +msgid "Object" +msgstr "Object" + +# processes/processes_EditObjectPermission.xml?ALL-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - ALL - '' +msgid "[processes/processes_EditObjectPermission.xml?ALL-'']" +msgstr "All" + +# processes/processes_EditObjectPermission.xml?DYNAFORMS +# processes/processes_EditObjectPermission.xml +#: dropdown - DYNAFORMS +msgid "[processes/processes_EditObjectPermission.xml?DYNAFORMS] DynaForm" +msgstr "DynaForm" + +# processes/processes_EditObjectPermission.xml?DYNAFORMS-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - DYNAFORMS - '' +msgid "[processes/processes_EditObjectPermission.xml?DYNAFORMS-'']" +msgstr "All" + +# processes/processes_EditObjectPermission.xml?INPUTS +# processes/processes_EditObjectPermission.xml +#: dropdown - INPUTS +msgid "[processes/processes_EditObjectPermission.xml?INPUTS] Input Document" +msgstr "Input Document" + +# processes/processes_EditObjectPermission.xml?INPUTS-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - INPUTS - '' +msgid "[processes/processes_EditObjectPermission.xml?INPUTS-'']" +msgstr "All" + +# processes/processes_EditObjectPermission.xml?OUTPUTS +# processes/processes_EditObjectPermission.xml +#: dropdown - OUTPUTS +msgid "[processes/processes_EditObjectPermission.xml?OUTPUTS] Output Document" +msgstr "Output Document" + +# processes/processes_EditObjectPermission.xml?OUTPUTS-'' +# processes/processes_EditObjectPermission.xml +#: dropdown - OUTPUTS - '' +msgid "[processes/processes_EditObjectPermission.xml?OUTPUTS-'']" +msgstr "All" + +# processes/processes_EditObjectPermission.xml?OP_ACTION +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_ACTION +msgid "Permission" +msgstr "Permission" + +# processes/processes_EditObjectPermission.xml?OP_ACTION-VIEW +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_ACTION - VIEW +msgid "[processes/processes_EditObjectPermission.xml?OP_ACTION-VIEW]" +msgstr "View" + +# processes/processes_EditObjectPermission.xml?OP_ACTION-BLOCK +# processes/processes_EditObjectPermission.xml +#: dropdown - OP_ACTION - BLOCK +msgid "[processes/processes_EditObjectPermission.xml?OP_ACTION-BLOCK]" +msgstr "Block" + +# processes/processes_EditObjectPermission.xml?CREATE +# processes/processes_EditObjectPermission.xml +#: button - CREATE +msgid "[processes/processes_EditObjectPermission.xml?CREATE] Save" +msgstr "Save" + +# processes/processes_Export.xml?TITLE +# processes/processes_Export.xml +#: title - TITLE +msgid "processes Info" +msgstr "processes Info" + +# processes/processes_Export.xml?PRO_TITLE +# processes/processes_Export.xml +#: caption - PRO_TITLE +msgid "[processes/processes_Export.xml?PRO_TITLE] Process Title" +msgstr "Process Title" + +# processes/processes_Export.xml?PRO_DESCRIPTION +# processes/processes_Export.xml +#: caption - PRO_DESCRIPTION +msgid "[processes/processes_Export.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_Export.xml?SIZE +# processes/processes_Export.xml +#: caption - SIZE +msgid "Size in bytes" +msgstr "Size in bytes" + +# processes/processes_Export.xml?FILENAME_LABEL +# processes/processes_Export.xml +#: link - FILENAME_LABEL +msgid "[processes/processes_Export.xml?FILENAME_LABEL] File" +msgstr "File" + +# processes/processes_FileEdit.xml?TITLE +# processes/processes_FileEdit.xml +#: title - TITLE +msgid "<div align=\"center\">Edit @#filename email template</div>" +msgstr "<div align=\"center\">Edit @#filename email template</div>" + +# processes/processes_FileEdit.xml?fcontent +# processes/processes_FileEdit.xml +#: html - fcontent +msgid "[processes/processes_FileEdit.xml?fcontent]" +msgstr "" + +# processes/processes_FileEdit.xml?ACCEPT +# processes/processes_FileEdit.xml +#: button - ACCEPT +msgid "[processes/processes_FileEdit.xml?ACCEPT] Save" +msgstr "Save" + +# processes/processes_FileEdit.xml?BTN_CANCEL +# processes/processes_FileEdit.xml +#: button - BTN_CANCEL +msgid "[processes/processes_FileEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_FileEditCreateEmpty.xml?emptyfilename +# processes/processes_FileEditCreateEmpty.xml +#: text - emptyfilename +msgid "[processes/processes_FileEditCreateEmpty.xml?emptyfilename] Filename" +msgstr "Filename" + +# processes/processes_FileEditCreateEmpty.xml?ACCEPT +# processes/processes_FileEditCreateEmpty.xml +#: button - ACCEPT +msgid "[processes/processes_FileEditCreateEmpty.xml?ACCEPT] Create" +msgstr "Create" + +# processes/processes_FilesList.xml?PATH +# processes/processes_FilesList.xml +#: text - PATH +msgid "[processes/processes_FilesList.xml?PATH]" +msgstr "" + +# processes/processes_FilesList.xml?EDIT +# processes/processes_FilesList.xml +#: link - EDIT +msgid "[processes/processes_FilesList.xml?EDIT]" +msgstr "" + +# processes/processes_FilesList.xml?DOWNLOAD +# processes/processes_FilesList.xml +#: link - DOWNLOAD +msgid "[processes/processes_FilesList.xml?DOWNLOAD]" +msgstr "" + +# processes/processes_FilesList.xml?DELETE +# processes/processes_FilesList.xml +#: link - DELETE +msgid "[processes/processes_FilesList.xml?DELETE]" +msgstr "" + +# processes/processes_FilesOptions.xml?MNU_NEWEMPTY +# processes/processes_FilesOptions.xml +#: link - MNU_NEWEMPTY +msgid "[processes/processes_FilesOptions.xml?MNU_NEWEMPTY] New" +msgstr "New" + +# processes/processes_FilesOptions.xml?MNU_UPLOAD +# processes/processes_FilesOptions.xml +#: link - MNU_UPLOAD +msgid "[processes/processes_FilesOptions.xml?MNU_UPLOAD] Upload" +msgstr "Upload" + +# processes/processes_Import.xml?TITLE1 +# processes/processes_Import.xml +#: title - TITLE1 +msgid "Import Process" +msgstr "Import Process" + +# processes/processes_Import.xml?PROCESS_FILENAME +# processes/processes_Import.xml +#: file - PROCESS_FILENAME +msgid "[processes/processes_Import.xml?PROCESS_FILENAME] File" +msgstr "File" + +# processes/processes_Import.xml?SAVE +# processes/processes_Import.xml +#: button - SAVE +msgid "[processes/processes_Import.xml?SAVE] Import" +msgstr "Import" + +# processes/processes_Import.xml?BTN_CANCEL +# processes/processes_Import.xml +#: button - BTN_CANCEL +msgid "[processes/processes_Import.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_ImportExisting.xml?title +# processes/processes_ImportExisting.xml +#: title - title +msgid "<div align=\"center\">Importing Existing Process</div>" +msgstr "<div align=\"center\">Importing Existing Process</div>" + +# processes/processes_ImportExisting.xml?TITLE1 +# processes/processes_ImportExisting.xml +#: subtitle - TITLE1 +msgid "The process you are trying to import already exists. Please select one of the following options to continue:" +msgstr "The process you are trying to import already exists. Please select one of the following options to continue:" + +# processes/processes_ImportExisting.xml?IMPORT_OPTION +# processes/processes_ImportExisting.xml +#: radiogroup - IMPORT_OPTION +msgid "[processes/processes_ImportExisting.xml?IMPORT_OPTION]" +msgstr "" + +# processes/processes_ImportExisting.xml?IMPORT_OPTION-1 +# processes/processes_ImportExisting.xml +#: radiogroup - IMPORT_OPTION - 1 +msgid "[processes/processes_ImportExisting.xml?IMPORT_OPTION-1]" +msgstr "Update the current process, overwriting all tasks and steps" + +# processes/processes_ImportExisting.xml?IMPORT_OPTION-2 +# processes/processes_ImportExisting.xml +#: radiogroup - IMPORT_OPTION - 2 +msgid "[processes/processes_ImportExisting.xml?IMPORT_OPTION-2]" +msgstr "Disable the current process and create a new version of the process" + +# processes/processes_ImportExisting.xml?IMPORT_OPTION-3 +# processes/processes_ImportExisting.xml +#: radiogroup - IMPORT_OPTION - 3 +msgid "[processes/processes_ImportExisting.xml?IMPORT_OPTION-3]" +msgstr "Create a completely new process without changing the current process" + +# processes/processes_ImportExisting.xml?SUBMIT +# processes/processes_ImportExisting.xml +#: submit - SUBMIT +msgid "[processes/processes_ImportExisting.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_ImportExisting.xml?BTN_CANCEL +# processes/processes_ImportExisting.xml +#: button - BTN_CANCEL +msgid "[processes/processes_ImportExisting.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_ImportSucessful.xml?title +# processes/processes_ImportSucessful.xml +#: title - title +msgid "Process sucessfully imported" +msgstr "Process sucessfully imported" + +# processes/processes_ImportSucessful.xml?pro_title +# processes/processes_ImportSucessful.xml +#: caption - pro_title +msgid "[processes/processes_ImportSucessful.xml?pro_title] Process Title" +msgstr "Process Title" + +# processes/processes_ImportSucessful.xml?version +# processes/processes_ImportSucessful.xml +#: caption - version +msgid "[processes/processes_ImportSucessful.xml?version] Version" +msgstr "Version" + +# processes/processes_ImportSucessful.xml?category +# processes/processes_ImportSucessful.xml +#: caption - category +msgid "[processes/processes_ImportSucessful.xml?category] Category" +msgstr "Category" + +# processes/processes_ImportSucessful.xml?PRO_UID +# processes/processes_ImportSucessful.xml +#: caption - PRO_UID +msgid "Process Uid" +msgstr "Process Uid" + +# processes/processes_ImportSucessful.xml?TITLE1 +# processes/processes_ImportSucessful.xml +#: subtitle - TITLE1 +msgid "Please follow these instructions to complete installation" +msgstr "Please follow these instructions to complete installation" + +# processes/processes_ImportSucessful.xml?installSteps +# processes/processes_ImportSucessful.xml +#: caption - installSteps +msgid "[processes/processes_ImportSucessful.xml?installSteps]" +msgstr "" + +# processes/processes_ImportSucessful.xml?SUBMIT +# processes/processes_ImportSucessful.xml +#: submit - SUBMIT +msgid "[processes/processes_ImportSucessful.xml?SUBMIT] Continue" +msgstr "Continue" + +# processes/processes_List.xml?PRO_CATEGORY_LABEL +# processes/processes_List.xml +#: text - PRO_CATEGORY_LABEL +msgid "[processes/processes_List.xml?PRO_CATEGORY_LABEL] Category" +msgstr "Category" + +# processes/processes_List.xml?PRO_TITLE +# processes/processes_List.xml +#: text - PRO_TITLE +msgid "[processes/processes_List.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_List.xml?PRO_DESCRIPTION +# processes/processes_List.xml +#: text - PRO_DESCRIPTION +msgid "[processes/processes_List.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_List.xml?PRO_EDIT +# processes/processes_List.xml +#: link - PRO_EDIT +msgid "[processes/processes_List.xml?PRO_EDIT]" +msgstr "" + +# processes/processes_List.xml?PRO_DELETE +# processes/processes_List.xml +#: link - PRO_DELETE +msgid "[processes/processes_List.xml?PRO_DELETE]" +msgstr "" + +# processes/processes_List.xml?PRO_STATUS +# processes/processes_List.xml +#: link - PRO_STATUS +msgid "[processes/processes_List.xml?PRO_STATUS]" +msgstr "" + +# processes/processes_ListPublic.xml?title +# processes/processes_ListPublic.xml +#: text - title +msgid "[processes/processes_ListPublic.xml?title] Title" +msgstr "Title" + +# processes/processes_ListPublic.xml?category +# processes/processes_ListPublic.xml +#: text - category +msgid "[processes/processes_ListPublic.xml?category] Category" +msgstr "Category" + +# processes/processes_ListPublic.xml?version +# processes/processes_ListPublic.xml +#: text - version +msgid "[processes/processes_ListPublic.xml?version] Version" +msgstr "Version" + +# processes/processes_ListPublic.xml?downloads +# processes/processes_ListPublic.xml +#: text - downloads +msgid "[processes/processes_ListPublic.xml?downloads] Downloads" +msgstr "Downloads" + +# processes/processes_ListPublic.xml?rating +# processes/processes_ListPublic.xml +#: text - rating +msgid "[processes/processes_ListPublic.xml?rating] Rating" +msgstr "Rating" + +# processes/processes_ListPublic.xml?subscriptions +# processes/processes_ListPublic.xml +#: text - subscriptions +msgid "[processes/processes_ListPublic.xml?subscriptions] Subscriptions" +msgstr "Subscriptions" + +# processes/processes_ListPublic.xml?user +# processes/processes_ListPublic.xml +#: text - user +msgid "[processes/processes_ListPublic.xml?user] Author" +msgstr "Author" + +# processes/processes_ListPublic.xml?updateDate +# processes/processes_ListPublic.xml +#: text - updateDate +msgid "[processes/processes_ListPublic.xml?updateDate] Update Date" +msgstr "Update Date" + +# processes/processes_ListPublic.xml?LINK +# processes/processes_ListPublic.xml +#: link - LINK +msgid "[processes/processes_ListPublic.xml?LINK]" +msgstr "" + +# processes/processes_New.xml?TITLE1 +# processes/processes_New.xml +#: title - TITLE1 +msgid "[processes/processes_New.xml?TITLE1] Process Information" +msgstr "Process Information" + +# processes/processes_New.xml?PRO_TITLE +# processes/processes_New.xml +#: text - PRO_TITLE +msgid "[processes/processes_New.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_New.xml?PRO_DESCRIPTION +# processes/processes_New.xml +#: textarea - PRO_DESCRIPTION +msgid "[processes/processes_New.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_New.xml?PRO_TEMPLATE +# processes/processes_New.xml +#: radiogroup - PRO_TEMPLATE +msgid "[processes/processes_New.xml?PRO_TEMPLATE] Template" +msgstr "Template" + +# processes/processes_New.xml?SUBMIT +# processes/processes_New.xml +#: button - SUBMIT +msgid "[processes/processes_New.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_NewObjectPermission.xml?TITLE +# processes/processes_NewObjectPermission.xml +#: title - TITLE +msgid "New Specific Permission" +msgstr "New Specific Permission" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS] Status Case" +msgstr "Status Case" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-ALL +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS - ALL +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-ALL]" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-DRAFT +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS - DRAFT +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-DRAFT]" +msgstr "DRAFT" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-TO_DO +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS - TO_DO +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-TO_DO]" +msgstr "TO DO" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-PAUSED +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS - PAUSED +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-PAUSED]" +msgstr "PAUSED" + +# processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-COMPLETED +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_CASE_STATUS - COMPLETED +msgid "[processes/processes_NewObjectPermission.xml?OP_CASE_STATUS-COMPLETED]" +msgstr "COMPLETED" + +# processes/processes_NewObjectPermission.xml?TAS_UID +# processes/processes_NewObjectPermission.xml +#: dropdown - TAS_UID +msgid "[processes/processes_NewObjectPermission.xml?TAS_UID] Target Task" +msgstr "Target Task" + +# processes/processes_NewObjectPermission.xml?TAS_UID-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - TAS_UID - '' +msgid "[processes/processes_NewObjectPermission.xml?TAS_UID-'']" +msgstr "All Tasks" + +# processes/processes_NewObjectPermission.xml?GROUP_USER +# processes/processes_NewObjectPermission.xml +#: dropdown - GROUP_USER +msgid "[processes/processes_NewObjectPermission.xml?GROUP_USER] Group or User" +msgstr "Group or User" + +# processes/processes_NewObjectPermission.xml?OP_TASK_SOURCE +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_TASK_SOURCE +msgid "[processes/processes_NewObjectPermission.xml?OP_TASK_SOURCE] Origin Task" +msgstr "Origin Task" + +# processes/processes_NewObjectPermission.xml?OP_TASK_SOURCE-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_TASK_SOURCE - '' +msgid "[processes/processes_NewObjectPermission.xml?OP_TASK_SOURCE-'']" +msgstr "All Tasks" + +# processes/processes_NewObjectPermission.xml?OP_PARTICIPATE +# processes/processes_NewObjectPermission.xml +#: yesno - OP_PARTICIPATE +msgid "[processes/processes_NewObjectPermission.xml?OP_PARTICIPATE] Participation required?" +msgstr "Participation required?" + +# processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_OBJ_TYPE +msgid "[processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE] Type" +msgstr "Type" + +# processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-ANY +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - ANY +msgid "[processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-ANY]" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-DYNAFORM +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - DYNAFORM +msgid "[processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-DYNAFORM]" +msgstr "Dynaform" + +# processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-INPUT +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - INPUT +msgid "[processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-INPUT]" +msgstr "Input Document" + +# processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-OUTPUT +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_OBJ_TYPE - OUTPUT +msgid "[processes/processes_NewObjectPermission.xml?OP_OBJ_TYPE-OUTPUT]" +msgstr "Output Document" + +# processes/processes_NewObjectPermission.xml?ALL +# processes/processes_NewObjectPermission.xml +#: dropdown - ALL +msgid "[processes/processes_NewObjectPermission.xml?ALL] Object" +msgstr "Object" + +# processes/processes_NewObjectPermission.xml?ALL-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - ALL - '' +msgid "[processes/processes_NewObjectPermission.xml?ALL-'']" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?DYNAFORMS +# processes/processes_NewObjectPermission.xml +#: dropdown - DYNAFORMS +msgid "[processes/processes_NewObjectPermission.xml?DYNAFORMS] DynaForm" +msgstr "DynaForm" + +# processes/processes_NewObjectPermission.xml?DYNAFORMS-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - DYNAFORMS - '' +msgid "[processes/processes_NewObjectPermission.xml?DYNAFORMS-'']" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?INPUTS +# processes/processes_NewObjectPermission.xml +#: dropdown - INPUTS +msgid "[processes/processes_NewObjectPermission.xml?INPUTS] Input Document" +msgstr "Input Document" + +# processes/processes_NewObjectPermission.xml?INPUTS-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - INPUTS - '' +msgid "[processes/processes_NewObjectPermission.xml?INPUTS-'']" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?OUTPUTS +# processes/processes_NewObjectPermission.xml +#: dropdown - OUTPUTS +msgid "[processes/processes_NewObjectPermission.xml?OUTPUTS] Output Document" +msgstr "Output Document" + +# processes/processes_NewObjectPermission.xml?OUTPUTS-'' +# processes/processes_NewObjectPermission.xml +#: dropdown - OUTPUTS - '' +msgid "[processes/processes_NewObjectPermission.xml?OUTPUTS-'']" +msgstr "All" + +# processes/processes_NewObjectPermission.xml?OP_ACTION +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_ACTION +msgid "[processes/processes_NewObjectPermission.xml?OP_ACTION] Permission" +msgstr "Permission" + +# processes/processes_NewObjectPermission.xml?OP_ACTION-VIEW +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_ACTION - VIEW +msgid "[processes/processes_NewObjectPermission.xml?OP_ACTION-VIEW]" +msgstr "View" + +# processes/processes_NewObjectPermission.xml?OP_ACTION-BLOCK +# processes/processes_NewObjectPermission.xml +#: dropdown - OP_ACTION - BLOCK +msgid "[processes/processes_NewObjectPermission.xml?OP_ACTION-BLOCK]" +msgstr "Block" + +# processes/processes_NewObjectPermission.xml?BTN_CANCEL +# processes/processes_NewObjectPermission.xml +#: button - BTN_CANCEL +msgid "[processes/processes_NewObjectPermission.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_NewObjectPermission.xml?CREATE +# processes/processes_NewObjectPermission.xml +#: button - CREATE +msgid "[processes/processes_NewObjectPermission.xml?CREATE] Create" +msgstr "Create" + +# processes/processes_NewOptions.xml?MNU +# processes/processes_NewOptions.xml +#: link - MNU +msgid "[processes/processes_NewOptions.xml?MNU] Back to list" +msgstr "Back to list" + +# processes/processes_NewSimple.xml?TITLE1 +# processes/processes_NewSimple.xml +#: title - TITLE1 +msgid "[processes/processes_NewSimple.xml?TITLE1] Process Information" +msgstr "Process Information" + +# processes/processes_NewSimple.xml?PRO_TITLE +# processes/processes_NewSimple.xml +#: text - PRO_TITLE +msgid "[processes/processes_NewSimple.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_NewSimple.xml?PRO_DESCRIPTION +# processes/processes_NewSimple.xml +#: textarea - PRO_DESCRIPTION +msgid "[processes/processes_NewSimple.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_NewSimple.xml?PRO_CATEGORY +# processes/processes_NewSimple.xml +#: dropdown - PRO_CATEGORY +msgid "[processes/processes_NewSimple.xml?PRO_CATEGORY] Process Category" +msgstr "Process Category" + +# processes/processes_NewSimple.xml?PRO_CATEGORY-'' +# processes/processes_NewSimple.xml +#: dropdown - PRO_CATEGORY - '' +msgid "[processes/processes_NewSimple.xml?PRO_CATEGORY-'']" +msgstr "- None -" + +# processes/processes_NewSimple.xml?SUBMIT +# processes/processes_NewSimple.xml +#: button - SUBMIT +msgid "[processes/processes_NewSimple.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_NewSimple.xml?BTN_CANCEL +# processes/processes_NewSimple.xml +#: button - BTN_CANCEL +msgid "[processes/processes_NewSimple.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_ObjectsPermissionsList.xml?TASK_TARGET +# processes/processes_ObjectsPermissionsList.xml +#: text - TASK_TARGET +msgid "[processes/processes_ObjectsPermissionsList.xml?TASK_TARGET] Target Task" +msgstr "Target Task" + +# processes/processes_ObjectsPermissionsList.xml?GROUP_USER +# processes/processes_ObjectsPermissionsList.xml +#: text - GROUP_USER +msgid "[processes/processes_ObjectsPermissionsList.xml?GROUP_USER] Group or User" +msgstr "Group or User" + +# processes/processes_ObjectsPermissionsList.xml?TASK_SOURCE +# processes/processes_ObjectsPermissionsList.xml +#: text - TASK_SOURCE +msgid "[processes/processes_ObjectsPermissionsList.xml?TASK_SOURCE] Origin Task" +msgstr "Origin Task" + +# processes/processes_ObjectsPermissionsList.xml?PARTICIPATED +# processes/processes_ObjectsPermissionsList.xml +#: text - PARTICIPATED +msgid "Participation" +msgstr "Participation" + +# processes/processes_ObjectsPermissionsList.xml?OBJECT_TYPE +# processes/processes_ObjectsPermissionsList.xml +#: text - OBJECT_TYPE +msgid "[processes/processes_ObjectsPermissionsList.xml?OBJECT_TYPE] Type" +msgstr "Type" + +# processes/processes_ObjectsPermissionsList.xml?OBJECT +# processes/processes_ObjectsPermissionsList.xml +#: text - OBJECT +msgid "[processes/processes_ObjectsPermissionsList.xml?OBJECT] Object" +msgstr "Object" + +# processes/processes_ObjectsPermissionsList.xml?ACTION +# processes/processes_ObjectsPermissionsList.xml +#: text - ACTION +msgid "[processes/processes_ObjectsPermissionsList.xml?ACTION] Permission" +msgstr "Permission" + +# processes/processes_ObjectsPermissionsList.xml?OP_CASE_STATUS +# processes/processes_ObjectsPermissionsList.xml +#: text - OP_CASE_STATUS +msgid "[processes/processes_ObjectsPermissionsList.xml?OP_CASE_STATUS] Status" +msgstr "Status" + +# processes/processes_ObjectsPermissionsList.xml?EDIT +# processes/processes_ObjectsPermissionsList.xml +#: link - EDIT +msgid "[processes/processes_ObjectsPermissionsList.xml?EDIT] Edit" +msgstr "Edit" + +# processes/processes_ObjectsPermissionsList.xml?DELETE +# processes/processes_ObjectsPermissionsList.xml +#: link - DELETE +msgid "[processes/processes_ObjectsPermissionsList.xml?DELETE] Delete" +msgstr "Delete" + +# processes/processes_ObjectsPermissionsOptions.xml?MNU_ADD +# processes/processes_ObjectsPermissionsOptions.xml +#: link - MNU_ADD +msgid "[processes/processes_ObjectsPermissionsOptions.xml?MNU_ADD] New" +msgstr "New" + +# processes/processes_Options.xml?MNU_ADD +# processes/processes_Options.xml +#: link - MNU_ADD +msgid "[processes/processes_Options.xml?MNU_ADD] New" +msgstr "New" + +# processes/processes_Options.xml?MNU_IMPORT +# processes/processes_Options.xml +#: link - MNU_IMPORT +msgid "[processes/processes_Options.xml?MNU_IMPORT] Import" +msgstr "Import" + +# processes/processes_Options.xml?MNU_LIBRARY +# processes/processes_Options.xml +#: link - MNU_LIBRARY +msgid "[processes/processes_Options.xml?MNU_LIBRARY] Browse Library" +msgstr "Browse Library" + +# processes/processes_Properties.xml?TITLE1 +# processes/processes_Properties.xml +#: title - TITLE1 +msgid "[processes/processes_Properties.xml?TITLE1] Process Information" +msgstr "Process Information" + +# processes/processes_Properties.xml?PRO_TITLE +# processes/processes_Properties.xml +#: text - PRO_TITLE +msgid "[processes/processes_Properties.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_Properties.xml?PRO_DESCRIPTION +# processes/processes_Properties.xml +#: textarea - PRO_DESCRIPTION +msgid "[processes/processes_Properties.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_Properties.xml?SUBMIT +# processes/processes_Properties.xml +#: button - SUBMIT +msgid "[processes/processes_Properties.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_Search.xml?PRO_UID +# processes/processes_Search.xml +#: text - PRO_UID +msgid "[processes/processes_Search.xml?PRO_UID] UID" +msgstr "UID" + +# processes/processes_Search.xml?PRO_TITLE +# processes/processes_Search.xml +#: text - PRO_TITLE +msgid "[processes/processes_Search.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_Search.xml?PRO_DESCRIPTION +# processes/processes_Search.xml +#: text - PRO_DESCRIPTION +msgid "[processes/processes_Search.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_Search.xml?search +# processes/processes_Search.xml +#: button - search +msgid "[processes/processes_Search.xml?search] Apply Filter" +msgstr "Apply Filter" + +# processes/processes_UploadFilesForm.xml?TITLE1 +# processes/processes_UploadFilesForm.xml +#: title - TITLE1 +msgid "Upload Files" +msgstr "Upload Files" + +# processes/processes_UploadFilesForm.xml?FILENAME1 +# processes/processes_UploadFilesForm.xml +#: file - FILENAME1 +msgid "File 1" +msgstr "File 1" + +# processes/processes_UploadFilesForm.xml?FILENAME2 +# processes/processes_UploadFilesForm.xml +#: file - FILENAME2 +msgid "File 2" +msgstr "File 2" + +# processes/processes_UploadFilesForm.xml?FILENAME3 +# processes/processes_UploadFilesForm.xml +#: file - FILENAME3 +msgid "File 3" +msgstr "File 3" + +# processes/processes_UploadFilesForm.xml?FILENAME4 +# processes/processes_UploadFilesForm.xml +#: file - FILENAME4 +msgid "File 4" +msgstr "File 4" + +# processes/processes_UploadFilesForm.xml?FILENAME5 +# processes/processes_UploadFilesForm.xml +#: file - FILENAME5 +msgid "File 5" +msgstr "File 5" + +# processes/processes_UploadFilesForm.xml?UPLOAD +# processes/processes_UploadFilesForm.xml +#: button - UPLOAD +msgid "[processes/processes_UploadFilesForm.xml?UPLOAD] Upload" +msgstr "Upload" + +# processes/processes_User.xml?USR_FIRSTNAME +# processes/processes_User.xml +#: text - USR_FIRSTNAME +msgid "First name" +msgstr "First name" + +# processes/processes_User.xml?USR_LASTNAME +# processes/processes_User.xml +#: text - USR_LASTNAME +msgid "Last name" +msgstr "Last name" + +# processes/processes_User.xml?REMOVE +# processes/processes_User.xml +#: link - REMOVE +msgid "[processes/processes_User.xml?REMOVE]" +msgstr "" + +# processes/processes_ValidatingGroups.xml?title +# processes/processes_ValidatingGroups.xml +#: title - title +msgid "<div align=\"center\">Importing Groups</div>" +msgstr "<div align=\"center\">Importing Groups</div>" + +# processes/processes_ValidatingGroups.xml?TITLE1 +# processes/processes_ValidatingGroups.xml +#: subtitle - TITLE1 +msgid "Some of the groups that are you trying to import, already exists. Please select one of the following options to continue:" +msgstr "Some of the groups that are you trying to import, already exists. Please select one of the following options to continue:" + +# processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION +# processes/processes_ValidatingGroups.xml +#: radiogroup - GROUP_IMPORT_OPTION +msgid "[processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION]" +msgstr "" + +# processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION-rename +# processes/processes_ValidatingGroups.xml +#: radiogroup - GROUP_IMPORT_OPTION - rename +msgid "[processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION-rename]" +msgstr "Rename the imported groups" + +# processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION-merge +# processes/processes_ValidatingGroups.xml +#: radiogroup - GROUP_IMPORT_OPTION - merge +msgid "[processes/processes_ValidatingGroups.xml?GROUP_IMPORT_OPTION-merge]" +msgstr "Merge the imported groups, with the preexistent local groups (no changes will be made to the local groups)" + +# processes/processes_ValidatingGroups.xml?SUBMIT +# processes/processes_ValidatingGroups.xml +#: submit - SUBMIT +msgid "[processes/processes_ValidatingGroups.xml?SUBMIT] Save" +msgstr "Save" + +# processes/processes_View.xml?TITLE1 +# processes/processes_View.xml +#: title - TITLE1 +msgid "[processes/processes_View.xml?TITLE1] Process Information" +msgstr "Process Information" + +# processes/processes_View.xml?PRO_TITLE +# processes/processes_View.xml +#: text - PRO_TITLE +msgid "[processes/processes_View.xml?PRO_TITLE] Title" +msgstr "Title" + +# processes/processes_View.xml?PRO_DESCRIPTION +# processes/processes_View.xml +#: textarea - PRO_DESCRIPTION +msgid "[processes/processes_View.xml?PRO_DESCRIPTION] Description" +msgstr "Description" + +# processes/processes_ViewOptions.xml?MNU +# processes/processes_ViewOptions.xml +#: link - MNU +msgid "[processes/processes_ViewOptions.xml?MNU] Back to list" +msgstr "Back to list" + +# processes/processes_availableProcessesUser.xml?USR_FIRSTNAME +# processes/processes_availableProcessesUser.xml +#: text - USR_FIRSTNAME +msgid "[processes/processes_availableProcessesUser.xml?USR_FIRSTNAME] First name" +msgstr "First name" + +# processes/processes_availableProcessesUser.xml?USR_LASTNAME +# processes/processes_availableProcessesUser.xml +#: text - USR_LASTNAME +msgid "[processes/processes_availableProcessesUser.xml?USR_LASTNAME] Last name" +msgstr "Last name" + +# processes/processes_availableProcessesUser.xml?ASSIGN +# processes/processes_availableProcessesUser.xml +#: link - ASSIGN +msgid "[processes/processes_availableProcessesUser.xml?ASSIGN]" +msgstr "" + +# processes/processes_subProcess.xml?TITLE1 +# processes/processes_subProcess.xml +#: title - TITLE1 +msgid "Sub-Process" +msgstr "Sub-Process" + +# processes/processes_subProcess.xml?SPROCESS_NAME +# processes/processes_subProcess.xml +#: text - SPROCESS_NAME +msgid "SubProcess name" +msgstr "SubProcess name" + +# processes/processes_subProcess.xml?TASKS +# processes/processes_subProcess.xml +#: dropdown - TASKS +msgid "[processes/processes_subProcess.xml?TASKS] Process" +msgstr "Process" + +# processes/processes_subProcess.xml?TASKS-'' +# processes/processes_subProcess.xml +#: dropdown - TASKS - '' +msgid "[processes/processes_subProcess.xml?TASKS-'']" +msgstr "Select a process" + +# processes/processes_subProcess.xml?PROCESSES +# processes/processes_subProcess.xml +#: dropdown - PROCESSES +msgid "[processes/processes_subProcess.xml?PROCESSES]" +msgstr "" + +# processes/processes_subProcess.xml?PROCESSES-'' +# processes/processes_subProcess.xml +#: dropdown - PROCESSES - '' +msgid "[processes/processes_subProcess.xml?PROCESSES-'']" +msgstr "" + +# processes/processes_subProcess.xml?SP_SYNCHRONOUS +# processes/processes_subProcess.xml +#: dropdown - SP_SYNCHRONOUS +msgid "[processes/processes_subProcess.xml?SP_SYNCHRONOUS] Type" +msgstr "Type" + +# processes/processes_subProcess.xml?SP_SYNCHRONOUS-'' +# processes/processes_subProcess.xml +#: dropdown - SP_SYNCHRONOUS - '' +msgid "[processes/processes_subProcess.xml?SP_SYNCHRONOUS-'']" +msgstr "Asynchronous" + +# processes/processes_subProcess.xml?SP_SYNCHRONOUS-1 +# processes/processes_subProcess.xml +#: dropdown - SP_SYNCHRONOUS - 1 +msgid "[processes/processes_subProcess.xml?SP_SYNCHRONOUS-1]" +msgstr "Synchronous" + +# processes/processes_subProcess.xml?SUBTITLE1 +# processes/processes_subProcess.xml +#: subtitle - SUBTITLE1 +msgid "Variables Out" +msgstr "Variables Out" + +# processes/processes_subProcess.xml?SUBTITLE2 +# processes/processes_subProcess.xml +#: subtitle - SUBTITLE2 +msgid "Variables In" +msgstr "Variables In" + +# processes/processes_subProcess.xml?BTN_CANCEL +# processes/processes_subProcess.xml +#: button - BTN_CANCEL +msgid "[processes/processes_subProcess.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# processes/processes_subProcess.xml?SAVE +# processes/processes_subProcess.xml +#: button - SAVE +msgid "[processes/processes_subProcess.xml?SAVE] Save" +msgstr "Save" + +# processes/processes_subProcess_In.xml?VAR_IN1 +# processes/processes_subProcess_In.xml +#: textpm - VAR_IN1 +msgid "Origin" +msgstr "Origin" + +# processes/processes_subProcess_In.xml?VAR_IN2 +# processes/processes_subProcess_In.xml +#: textpm - VAR_IN2 +msgid "Target" +msgstr "Target" + +# processes/processes_subProcess_Out.xml?VAR_OUT1 +# processes/processes_subProcess_Out.xml +#: textpm - VAR_OUT1 +msgid "[processes/processes_subProcess_Out.xml?VAR_OUT1] Origin" +msgstr "Origin" + +# processes/processes_subProcess_Out.xml?VAR_OUT2 +# processes/processes_subProcess_Out.xml +#: textpm - VAR_OUT2 +msgid "[processes/processes_subProcess_Out.xml?VAR_OUT2] Target" +msgstr "Target" + +# processes/processes_viewreassignCase.xml?USR_FIRSTNAME +# processes/processes_viewreassignCase.xml +#: text - USR_FIRSTNAME +msgid "[processes/processes_viewreassignCase.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# processes/processes_viewreassignCase.xml?USR_LASTNAME +# processes/processes_viewreassignCase.xml +#: text - USR_LASTNAME +msgid "[processes/processes_viewreassignCase.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# processes/processes_viewreassignCase.xml?ASSIGN +# processes/processes_viewreassignCase.xml +#: link - ASSIGN +msgid "[processes/processes_viewreassignCase.xml?ASSIGN]" +msgstr "" + +# processes/registerPML.xml?TITLE +# processes/registerPML.xml +#: title - TITLE +msgid "Login into ProcessMaker Library" +msgstr "Login into ProcessMaker Library" + +# processes/registerPML.xml?PML_USER +# processes/registerPML.xml +#: text - PML_USER +msgid "Username (or Live Workspace)" +msgstr "Username (or Live Workspace)" + +# processes/registerPML.xml?PML_PASSWORD +# processes/registerPML.xml +#: password - PML_PASSWORD +msgid "[processes/registerPML.xml?PML_PASSWORD] Password" +msgstr "Password" + +# processes/registerPML.xml?PML_LOGIN +# processes/registerPML.xml +#: button - PML_LOGIN +msgid "[processes/registerPML.xml?PML_LOGIN] Login" +msgstr "Login" + +# processes/registerPML.xml?link2 +# processes/registerPML.xml +#: link - link2 +msgid "[processes/registerPML.xml?link2]" +msgstr "" + +# reportTables/reportTables_Edit.xml?TITLE +# reportTables/reportTables_Edit.xml +#: title - TITLE +msgid "Report Table Information" +msgstr "Report Table Information" + +# reportTables/reportTables_Edit.xml?REP_TAB_TITLE +# reportTables/reportTables_Edit.xml +#: text - REP_TAB_TITLE +msgid "[reportTables/reportTables_Edit.xml?REP_TAB_TITLE] Title" +msgstr "Title" + +# reportTables/reportTables_Edit.xml?REP_TAB_NAME +# reportTables/reportTables_Edit.xml +#: text - REP_TAB_NAME +msgid "[reportTables/reportTables_Edit.xml?REP_TAB_NAME] Table Name" +msgstr "Table Name" + +# reportTables/reportTables_Edit.xml?REP_TAB_TYPE +# reportTables/reportTables_Edit.xml +#: dropdown - REP_TAB_TYPE +msgid "[reportTables/reportTables_Edit.xml?REP_TAB_TYPE] Type" +msgstr "Type" + +# reportTables/reportTables_Edit.xml?REP_TAB_TYPE-NORMAL +# reportTables/reportTables_Edit.xml +#: dropdown - REP_TAB_TYPE - NORMAL +msgid "[reportTables/reportTables_Edit.xml?REP_TAB_TYPE-NORMAL]" +msgstr "Global" + +# reportTables/reportTables_Edit.xml?REP_TAB_TYPE-GRID +# reportTables/reportTables_Edit.xml +#: dropdown - REP_TAB_TYPE - GRID +msgid "[reportTables/reportTables_Edit.xml?REP_TAB_TYPE-GRID]" +msgstr "Grid" + +# reportTables/reportTables_Edit.xml?REP_TAB_GRID +# reportTables/reportTables_Edit.xml +#: dropdown - REP_TAB_GRID +msgid "Grid Fields" +msgstr "Grid Fields" + +# reportTables/reportTables_Edit.xml?FIELDS +# reportTables/reportTables_Edit.xml +#: listbox - FIELDS +msgid "[reportTables/reportTables_Edit.xml?FIELDS] Fields" +msgstr "Fields" + +# reportTables/reportTables_Edit.xml?BTN_CANCEL +# reportTables/reportTables_Edit.xml +#: button - BTN_CANCEL +msgid "[reportTables/reportTables_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# reportTables/reportTables_Edit.xml?SAVE +# reportTables/reportTables_Edit.xml +#: button - SAVE +msgid "[reportTables/reportTables_Edit.xml?SAVE] Save" +msgstr "Save" + +# reportTables/reportTables_Options.xml?MNU_ADD +# reportTables/reportTables_Options.xml +#: link - MNU_ADD +msgid "[reportTables/reportTables_Options.xml?MNU_ADD] New" +msgstr "New" + +# reportTables/reportTables_ShortList.xml?REP_TAB_TITLE +# reportTables/reportTables_ShortList.xml +#: text - REP_TAB_TITLE +msgid "[reportTables/reportTables_ShortList.xml?REP_TAB_TITLE] Title" +msgstr "Title" + +# reportTables/reportTables_ShortList.xml?EDIT +# reportTables/reportTables_ShortList.xml +#: link - EDIT +msgid "[reportTables/reportTables_ShortList.xml?EDIT]" +msgstr "" + +# reportTables/reportTables_ShortList.xml?DELETE +# reportTables/reportTables_ShortList.xml +#: link - DELETE +msgid "[reportTables/reportTables_ShortList.xml?DELETE]" +msgstr "" + +# reportTables/reportTables_ShortList.xml?SEARCH +# reportTables/reportTables_ShortList.xml +#: button - SEARCH +msgid "[reportTables/reportTables_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# reports/report1.xml?PRO_TITLE +# reports/report1.xml +#: text - PRO_TITLE +msgid "[reports/report1.xml?PRO_TITLE] Processes" +msgstr "Processes" + +# reports/report1.xml?CANTCASES +# reports/report1.xml +#: text - CANTCASES +msgid "[reports/report1.xml?CANTCASES] Cases" +msgstr "Cases" + +# reports/report1.xml?MIN +# reports/report1.xml +#: hours - MIN +msgid "Best Completion Time" +msgstr "Best Completion Time" + +# reports/report1.xml?MAX +# reports/report1.xml +#: hours - MAX +msgid "Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/report1.xml?TOTALDUR +# reports/report1.xml +#: hours - TOTALDUR +msgid "Total Duration (Hours)" +msgstr "Total Duration (Hours)" + +# reports/report1.xml?PROMEDIO +# reports/report1.xml +#: text - PROMEDIO +msgid "Average (Hours)" +msgstr "Average (Hours)" + +# reports/report1.xml?RPT_VIEW +# reports/report1.xml +#: link - RPT_VIEW +msgid "Detaills" +msgstr "Detaills" + +# reports/report1_back.xml?backs +# reports/report1_back.xml +#: link - backs +msgid "[reports/report1_back.xml?backs] Back" +msgstr "Back" + +# reports/report1_dashboard.xml?PRO_TITLE +# reports/report1_dashboard.xml +#: text - PRO_TITLE +msgid "[reports/report1_dashboard.xml?PRO_TITLE] Processes" +msgstr "Processes" + +# reports/report1_dashboard.xml?CANTCASES +# reports/report1_dashboard.xml +#: text - CANTCASES +msgid "[reports/report1_dashboard.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report1_dashboard.xml?MAX +# reports/report1_dashboard.xml +#: hours - MAX +msgid "Slowest Time" +msgstr "Slowest Time" + +# reports/report1_dashboard.xml?TOTALDUR +# reports/report1_dashboard.xml +#: hours - TOTALDUR +msgid "Total Duration" +msgstr "Total Duration" + +# reports/report1_dashboard.xml?PROMEDIO +# reports/report1_dashboard.xml +#: hours - PROMEDIO +msgid "Average" +msgstr "Average" + +# reports/report1_search.xml?FROM +# reports/report1_search.xml +#: date - FROM +msgid "[reports/report1_search.xml?FROM] FROM" +msgstr "FROM" + +# reports/report1_search.xml?TO +# reports/report1_search.xml +#: date - TO +msgid "[reports/report1_search.xml?TO] TO" +msgstr "TO" + +# reports/report1_search.xml?STARTEDBY +# reports/report1_search.xml +#: dropdown - STARTEDBY +msgid "STARTED BY" +msgstr "STARTED BY" + +# reports/report1_search.xml?STARTEDBY-'' +# reports/report1_search.xml +#: dropdown - STARTEDBY - '' +msgid "[reports/report1_search.xml?STARTEDBY-'']" +msgstr "All" + +# reports/report1_search.xml?FILTER +# reports/report1_search.xml +#: submit - FILTER +msgid "[reports/report1_search.xml?FILTER] Filter" +msgstr "Filter" + +# reports/report2.xml?PRO_TITLE +# reports/report2.xml +#: text - PRO_TITLE +msgid "[reports/report2.xml?PRO_TITLE] Processes" +msgstr "Processes" + +# reports/report2.xml?CANTCASES +# reports/report2.xml +#: text - CANTCASES +msgid "[reports/report2.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report2.xml?MIN +# reports/report2.xml +#: hours - MIN +msgid "[reports/report2.xml?MIN] Best Completion Time" +msgstr "Best Completion Time" + +# reports/report2.xml?MAX +# reports/report2.xml +#: hours - MAX +msgid "[reports/report2.xml?MAX] Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/report2.xml?CASELASTMONTH +# reports/report2.xml +#: text - CASELASTMONTH +msgid "Cases last month" +msgstr "Cases last month" + +# reports/report2.xml?CASELASTDAY +# reports/report2.xml +#: text - CASELASTDAY +msgid "Cases last day" +msgstr "Cases last day" + +# reports/report2_dashboard.xml?PRO_TITLE +# reports/report2_dashboard.xml +#: text - PRO_TITLE +msgid "[reports/report2_dashboard.xml?PRO_TITLE] Processes" +msgstr "Processes" + +# reports/report2_dashboard.xml?CANTCASES +# reports/report2_dashboard.xml +#: text - CANTCASES +msgid "[reports/report2_dashboard.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report2_dashboard.xml?MAX +# reports/report2_dashboard.xml +#: hours - MAX +msgid "[reports/report2_dashboard.xml?MAX] Slowest Time" +msgstr "Slowest Time" + +# reports/report2_dashboard.xml?CASELASTMONTH +# reports/report2_dashboard.xml +#: text - CASELASTMONTH +msgid "Last month" +msgstr "Last month" + +# reports/report2_dashboard.xml?CASELASTDAY +# reports/report2_dashboard.xml +#: text - CASELASTDAY +msgid "Last day" +msgstr "Last day" + +# reports/report3.xml?FECHA +# reports/report3.xml +#: text - FECHA +msgid "[reports/report3.xml?FECHA] Date" +msgstr "Date" + +# reports/report3.xml?CANTCASES +# reports/report3.xml +#: text - CANTCASES +msgid "[reports/report3.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report3.xml?MIN +# reports/report3.xml +#: hours - MIN +msgid "[reports/report3.xml?MIN] Best Completion Time" +msgstr "Best Completion Time" + +# reports/report3.xml?MAX +# reports/report3.xml +#: hours - MAX +msgid "[reports/report3.xml?MAX] Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/report3.xml?TOTALDUR +# reports/report3.xml +#: hours - TOTALDUR +msgid "[reports/report3.xml?TOTALDUR] Total Duration (Hours)" +msgstr "Total Duration (Hours)" + +# reports/report3.xml?PROMEDIO +# reports/report3.xml +#: hours - PROMEDIO +msgid "[reports/report3.xml?PROMEDIO] Average (Hours)" +msgstr "Average (Hours)" + +# reports/report3_dashboard.xml?FECHA +# reports/report3_dashboard.xml +#: text - FECHA +msgid "[reports/report3_dashboard.xml?FECHA] Date" +msgstr "Date" + +# reports/report3_dashboard.xml?CANTCASES +# reports/report3_dashboard.xml +#: text - CANTCASES +msgid "[reports/report3_dashboard.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report3_dashboard.xml?MAX +# reports/report3_dashboard.xml +#: hours - MAX +msgid "[reports/report3_dashboard.xml?MAX] Slowest Time" +msgstr "Slowest Time" + +# reports/report3_dashboard.xml?TOTALDUR +# reports/report3_dashboard.xml +#: hours - TOTALDUR +msgid "[reports/report3_dashboard.xml?TOTALDUR] Total Duration" +msgstr "Total Duration" + +# reports/report3_dashboard.xml?PROMEDIO +# reports/report3_dashboard.xml +#: hours - PROMEDIO +msgid "[reports/report3_dashboard.xml?PROMEDIO] Average" +msgstr "Average" + +# reports/report4.xml?USER +# reports/report4.xml +#: text - USER +msgid "[reports/report4.xml?USER] User" +msgstr "User" + +# reports/report4.xml?CANTCASES +# reports/report4.xml +#: text - CANTCASES +msgid "[reports/report4.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report4.xml?MIN +# reports/report4.xml +#: hours - MIN +msgid "[reports/report4.xml?MIN] Best Completion Time" +msgstr "Best Completion Time" + +# reports/report4.xml?MAX +# reports/report4.xml +#: hours - MAX +msgid "[reports/report4.xml?MAX] Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/report4.xml?TOTALDUR +# reports/report4.xml +#: hours - TOTALDUR +msgid "[reports/report4.xml?TOTALDUR] Total Duration (Hours)" +msgstr "Total Duration (Hours)" + +# reports/report4.xml?PROMEDIO +# reports/report4.xml +#: hours - PROMEDIO +msgid "[reports/report4.xml?PROMEDIO] Average (Hours)" +msgstr "Average (Hours)" + +# reports/report4_dashboard.xml?USER +# reports/report4_dashboard.xml +#: text - USER +msgid "[reports/report4_dashboard.xml?USER] User" +msgstr "User" + +# reports/report4_dashboard.xml?CANTCASES +# reports/report4_dashboard.xml +#: text - CANTCASES +msgid "[reports/report4_dashboard.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report4_dashboard.xml?MAX +# reports/report4_dashboard.xml +#: hours - MAX +msgid "[reports/report4_dashboard.xml?MAX] Slowest Time" +msgstr "Slowest Time" + +# reports/report4_dashboard.xml?TOTALDUR +# reports/report4_dashboard.xml +#: hours - TOTALDUR +msgid "[reports/report4_dashboard.xml?TOTALDUR] Total Duration" +msgstr "Total Duration" + +# reports/report4_dashboard.xml?PROMEDIO +# reports/report4_dashboard.xml +#: hours - PROMEDIO +msgid "[reports/report4_dashboard.xml?PROMEDIO] Average" +msgstr "Average" + +# reports/report5.xml?USER +# reports/report5.xml +#: text - USER +msgid "[reports/report5.xml?USER] User" +msgstr "User" + +# reports/report5.xml?CANTCASES +# reports/report5.xml +#: text - CANTCASES +msgid "[reports/report5.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report5.xml?MIN +# reports/report5.xml +#: hours - MIN +msgid "[reports/report5.xml?MIN] Best Completion Time" +msgstr "Best Completion Time" + +# reports/report5.xml?MAX +# reports/report5.xml +#: hours - MAX +msgid "[reports/report5.xml?MAX] Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/report5.xml?TOTALDUR +# reports/report5.xml +#: hours - TOTALDUR +msgid "[reports/report5.xml?TOTALDUR] Total Duration (Hours)" +msgstr "Total Duration (Hours)" + +# reports/report5.xml?PROMEDIO +# reports/report5.xml +#: hours - PROMEDIO +msgid "[reports/report5.xml?PROMEDIO] Average (Hours)" +msgstr "Average (Hours)" + +# reports/report5_dashboard.xml?USER +# reports/report5_dashboard.xml +#: text - USER +msgid "[reports/report5_dashboard.xml?USER] User" +msgstr "User" + +# reports/report5_dashboard.xml?CANTCASES +# reports/report5_dashboard.xml +#: text - CANTCASES +msgid "[reports/report5_dashboard.xml?CANTCASES] Total Cases" +msgstr "Total Cases" + +# reports/report5_dashboard.xml?MAX +# reports/report5_dashboard.xml +#: hours - MAX +msgid "[reports/report5_dashboard.xml?MAX] Slowest Time" +msgstr "Slowest Time" + +# reports/report5_dashboard.xml?TOTALDUR +# reports/report5_dashboard.xml +#: hours - TOTALDUR +msgid "[reports/report5_dashboard.xml?TOTALDUR] Total Duration" +msgstr "Total Duration" + +# reports/report5_dashboard.xml?PROMEDIO +# reports/report5_dashboard.xml +#: hours - PROMEDIO +msgid "[reports/report5_dashboard.xml?PROMEDIO] Average" +msgstr "Average" + +# reports/report_filter.xml?PROCESS +# reports/report_filter.xml +#: dropdown - PROCESS +msgid "[reports/report_filter.xml?PROCESS] Process" +msgstr "Process" + +# reports/report_filter.xml?PROCESS-'' +# reports/report_filter.xml +#: dropdown - PROCESS - '' +msgid "[reports/report_filter.xml?PROCESS-'']" +msgstr "All" + +# reports/report_filter.xml?TASKS +# reports/report_filter.xml +#: dropdown - TASKS +msgid "[reports/report_filter.xml?TASKS] Tasks" +msgstr "Tasks" + +# reports/report_filter.xml?TASKS-'' +# reports/report_filter.xml +#: dropdown - TASKS - '' +msgid "[reports/report_filter.xml?TASKS-'']" +msgstr "All" + +# reports/report_filter.xml?FILTER +# reports/report_filter.xml +#: submit - FILTER +msgid "[reports/report_filter.xml?FILTER] Filter" +msgstr "Filter" + +# reports/reportsList.xml?RPT_NUMBER +# reports/reportsList.xml +#: text - RPT_NUMBER +msgid "[reports/reportsList.xml?RPT_NUMBER] #" +msgstr "#" + +# reports/reportsList.xml?RPT_TITLE +# reports/reportsList.xml +#: text - RPT_TITLE +msgid "[reports/reportsList.xml?RPT_TITLE] Reports" +msgstr "Reports" + +# reports/reportsList.xml?RPT_VIEW +# reports/reportsList.xml +#: link - RPT_VIEW +msgid "[reports/reportsList.xml?RPT_VIEW]" +msgstr "" + +# reports/reports_Description.xml?TAS_TITLE +# reports/reports_Description.xml +#: text - TAS_TITLE +msgid "[reports/reports_Description.xml?TAS_TITLE] Task" +msgstr "Task" + +# reports/reports_Description.xml?MIN +# reports/reports_Description.xml +#: hours - MIN +msgid "[reports/reports_Description.xml?MIN] Best Completion Time" +msgstr "Best Completion Time" + +# reports/reports_Description.xml?MAX +# reports/reports_Description.xml +#: hours - MAX +msgid "[reports/reports_Description.xml?MAX] Slowest Completion Time" +msgstr "Slowest Completion Time" + +# reports/reports_Description.xml?TOTALDUR +# reports/reports_Description.xml +#: hours - TOTALDUR +msgid "[reports/reports_Description.xml?TOTALDUR] Total Duration (Hours)" +msgstr "Total Duration (Hours)" + +# reports/reports_Description.xml?PROMEDIO +# reports/reports_Description.xml +#: hours - PROMEDIO +msgid "[reports/reports_Description.xml?PROMEDIO] Average (Hours)" +msgstr "Average (Hours)" + +# reports/reports_Description_search.xml?FROM_DES +# reports/reports_Description_search.xml +#: date - FROM_DES +msgid "[reports/reports_Description_search.xml?FROM_DES] FROM" +msgstr "FROM" + +# reports/reports_Description_search.xml?TO_DES +# reports/reports_Description_search.xml +#: date - TO_DES +msgid "[reports/reports_Description_search.xml?TO_DES] TO" +msgstr "TO" + +# reports/reports_Description_search.xml?STARTEDBY_DES +# reports/reports_Description_search.xml +#: dropdown - STARTEDBY_DES +msgid "[reports/reports_Description_search.xml?STARTEDBY_DES] STARTED BY" +msgstr "STARTED BY" + +# reports/reports_Description_search.xml?STARTEDBY_DES-'' +# reports/reports_Description_search.xml +#: dropdown - STARTEDBY_DES - '' +msgid "[reports/reports_Description_search.xml?STARTEDBY_DES-'']" +msgstr "" + +# reports/reports_Description_search.xml?FILTER +# reports/reports_Description_search.xml +#: button - FILTER +msgid "[reports/reports_Description_search.xml?FILTER] Filter" +msgstr "Filter" + +# reports/rpt_filters.xml?FROM +# reports/rpt_filters.xml +#: date - FROM +msgid "Initial date" +msgstr "Initial date" + +# reports/rpt_filters.xml?TO +# reports/rpt_filters.xml +#: date - TO +msgid "End date" +msgstr "End date" + +# reports/rpt_filters.xml?FILTER +# reports/rpt_filters.xml +#: submit - FILTER +msgid "[reports/rpt_filters.xml?FILTER] Filter" +msgstr "Filter" + +# roles/roles_Edit.xml?title +# roles/roles_Edit.xml +#: title - title +msgid "Edit role" +msgstr "Edit role" + +# roles/roles_Edit.xml?ROL_CODE +# roles/roles_Edit.xml +#: text - ROL_CODE +msgid "Role Code" +msgstr "Role Code" + +# roles/roles_Edit.xml?ROL_NAME +# roles/roles_Edit.xml +#: text - ROL_NAME +msgid "Role Name" +msgstr "Role Name" + +# roles/roles_Edit.xml?ROL_STATUS +# roles/roles_Edit.xml +#: dropdown - ROL_STATUS +msgid "[roles/roles_Edit.xml?ROL_STATUS] Status" +msgstr "Status" + +# roles/roles_Edit.xml?ROL_STATUS-1 +# roles/roles_Edit.xml +#: dropdown - ROL_STATUS - 1 +msgid "[roles/roles_Edit.xml?ROL_STATUS-1]" +msgstr "Active" + +# roles/roles_Edit.xml?ROL_STATUS-'' +# roles/roles_Edit.xml +#: dropdown - ROL_STATUS - '' +msgid "[roles/roles_Edit.xml?ROL_STATUS-'']" +msgstr "Inactive" + +# roles/roles_Edit.xml?BTN_CANCEL +# roles/roles_Edit.xml +#: button - BTN_CANCEL +msgid "[roles/roles_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# roles/roles_Edit.xml?CREATE +# roles/roles_Edit.xml +#: button - CREATE +msgid "[roles/roles_Edit.xml?CREATE] Update" +msgstr "Update" + +# roles/roles_List.xml?ROL_CODE +# roles/roles_List.xml +#: text - ROL_CODE +msgid "[roles/roles_List.xml?ROL_CODE] Code" +msgstr "Code" + +# roles/roles_List.xml?ROL_NAME +# roles/roles_List.xml +#: text - ROL_NAME +msgid "[roles/roles_List.xml?ROL_NAME] Name" +msgstr "Name" + +# roles/roles_List.xml?ROL_CREATE_DATE +# roles/roles_List.xml +#: text - ROL_CREATE_DATE +msgid "Create date" +msgstr "Create date" + +# roles/roles_List.xml?ROL_UPDATE_DATE +# roles/roles_List.xml +#: text - ROL_UPDATE_DATE +msgid "Update date" +msgstr "Update date" + +# roles/roles_List.xml?ROL_VIEW +# roles/roles_List.xml +#: link - ROL_VIEW +msgid "[roles/roles_List.xml?ROL_VIEW]" +msgstr "" + +# roles/roles_List.xml?ROL_PERMITIONS +# roles/roles_List.xml +#: link - ROL_PERMITIONS +msgid "[roles/roles_List.xml?ROL_PERMITIONS]" +msgstr "" + +# roles/roles_List.xml?VIEW_INTO_GROUP +# roles/roles_List.xml +#: link - VIEW_INTO_GROUP +msgid "[roles/roles_List.xml?VIEW_INTO_GROUP]" +msgstr "" + +# roles/roles_List.xml?ROL_DELETE +# roles/roles_List.xml +#: link - ROL_DELETE +msgid "[roles/roles_List.xml?ROL_DELETE]" +msgstr "" + +# roles/roles_New.xml?title +# roles/roles_New.xml +#: title - title +msgid "Create a new Role" +msgstr "Create a new Role" + +# roles/roles_New.xml?ROL_CODE +# roles/roles_New.xml +#: text - ROL_CODE +msgid "[roles/roles_New.xml?ROL_CODE] Role Code" +msgstr "Role Code" + +# roles/roles_New.xml?ROL_NAME +# roles/roles_New.xml +#: text - ROL_NAME +msgid "[roles/roles_New.xml?ROL_NAME] Role Name" +msgstr "Role Name" + +# roles/roles_New.xml?ROL_STATUS +# roles/roles_New.xml +#: dropdown - ROL_STATUS +msgid "[roles/roles_New.xml?ROL_STATUS] Status" +msgstr "Status" + +# roles/roles_New.xml?ROL_STATUS-1 +# roles/roles_New.xml +#: dropdown - ROL_STATUS - 1 +msgid "[roles/roles_New.xml?ROL_STATUS-1]" +msgstr "Active" + +# roles/roles_New.xml?ROL_STATUS-'' +# roles/roles_New.xml +#: dropdown - ROL_STATUS - '' +msgid "[roles/roles_New.xml?ROL_STATUS-'']" +msgstr "Inactive" + +# roles/roles_New.xml?BTN_CANCEL +# roles/roles_New.xml +#: button - BTN_CANCEL +msgid "[roles/roles_New.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# roles/roles_New.xml?CREATE +# roles/roles_New.xml +#: button - CREATE +msgid "[roles/roles_New.xml?CREATE] Create" +msgstr "Create" + +# roles/roles_Options.xml?MNU_ADD +# roles/roles_Options.xml +#: link - MNU_ADD +msgid "[roles/roles_Options.xml?MNU_ADD] New" +msgstr "New" + +# setup/calendarEdit.xml?DEFINITION_TITLE +# setup/calendarEdit.xml +#: title - DEFINITION_TITLE +msgid "Calendar Definition" +msgstr "Calendar Definition" + +# setup/calendarEdit.xml?CALENDAR_NAME +# setup/calendarEdit.xml +#: text - CALENDAR_NAME +msgid "[setup/calendarEdit.xml?CALENDAR_NAME] Name" +msgstr "Name" + +# setup/calendarEdit.xml?CALENDAR_DESCRIPTION +# setup/calendarEdit.xml +#: textarea - CALENDAR_DESCRIPTION +msgid "[setup/calendarEdit.xml?CALENDAR_DESCRIPTION] Description" +msgstr "Description" + +# setup/calendarEdit.xml?CALENDAR_STATUS +# setup/calendarEdit.xml +#: checkbox - CALENDAR_STATUS +msgid "[setup/calendarEdit.xml?CALENDAR_STATUS] Active" +msgstr "Active" + +# setup/calendarEdit.xml?WorkDays +# setup/calendarEdit.xml +#: title - WorkDays +msgid "Work Days" +msgstr "Work Days" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS]" +msgstr "" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-0 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 0 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-0]" +msgstr "SUN" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-1 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 1 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-1]" +msgstr "MON" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-2 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 2 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-2]" +msgstr "TUE" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-3 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 3 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-3]" +msgstr "WED" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-4 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 4 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-4]" +msgstr "THU" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-5 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 5 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-5]" +msgstr "FRI" + +# setup/calendarEdit.xml?CALENDAR_WORK_DAYS-6 +# setup/calendarEdit.xml +#: checkgroup - CALENDAR_WORK_DAYS - 6 +msgid "[setup/calendarEdit.xml?CALENDAR_WORK_DAYS-6]" +msgstr "SAT" + +# setup/calendarEdit.xml?BUSINESS_DAY_TITLE +# setup/calendarEdit.xml +#: title - BUSINESS_DAY_TITLE +msgid "Work Hours" +msgstr "Work Hours" + +# setup/calendarEdit.xml?HOLIDAY_LABEL +# setup/calendarEdit.xml +#: title - HOLIDAY_LABEL +msgid "Holidays" +msgstr "Holidays" + +# setup/calendarEdit.xml?SUBMIT +# setup/calendarEdit.xml +#: submit - SUBMIT +msgid "[setup/calendarEdit.xml?SUBMIT] Save" +msgstr "Save" + +# setup/calendarEdit.xml?SUBMIT2 +# setup/calendarEdit.xml +#: button - SUBMIT2 +msgid "[setup/calendarEdit.xml?SUBMIT2] Save" +msgstr "Save" + +# setup/calendarEdit.xml?BTN_CANCEL +# setup/calendarEdit.xml +#: button - BTN_CANCEL +msgid "[setup/calendarEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# setup/calendarEdit.xml?HOLIDAY_STATUS +# setup/calendarEdit.xml +#: checkbox - HOLIDAY_STATUS +msgid "[setup/calendarEdit.xml?HOLIDAY_STATUS] Active" +msgstr "Active" + +# setup/calendarEdit.xml?BUSINESS_DAY_STATUS +# setup/calendarEdit.xml +#: checkbox - BUSINESS_DAY_STATUS +msgid "[setup/calendarEdit.xml?BUSINESS_DAY_STATUS] Active" +msgstr "Active" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY] Day" +msgstr "Day" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-7 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 7 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-7]" +msgstr "- ALL -" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-0 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 0 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-0]" +msgstr "SUN" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-1 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 1 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-1]" +msgstr "MON" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-2 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 2 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-2]" +msgstr "TUE" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-3 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 3 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-3]" +msgstr "WED" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-4 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 4 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-4]" +msgstr "THU" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-5 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 5 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-5]" +msgstr "FRI" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-6 +# setup/calendarEdit_BusinessHours.xml +#: dropdown - CALENDAR_BUSINESS_DAY - 6 +msgid "[setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_DAY-6]" +msgstr "SAT" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_START +# setup/calendarEdit_BusinessHours.xml +#: text - CALENDAR_BUSINESS_START +msgid "Start (hh:mm)" +msgstr "Start (hh:mm)" + +# setup/calendarEdit_BusinessHours.xml?CALENDAR_BUSINESS_END +# setup/calendarEdit_BusinessHours.xml +#: text - CALENDAR_BUSINESS_END +msgid "End (hh:mm)" +msgstr "End (hh:mm)" + +# setup/calendarEdit_Holidays.xml?CALENDAR_HOLIDAY_NAME +# setup/calendarEdit_Holidays.xml +#: text - CALENDAR_HOLIDAY_NAME +msgid "[setup/calendarEdit_Holidays.xml?CALENDAR_HOLIDAY_NAME] Name" +msgstr "Name" + +# setup/calendarEdit_Holidays.xml?CALENDAR_HOLIDAY_START +# setup/calendarEdit_Holidays.xml +#: date - CALENDAR_HOLIDAY_START +msgid "Start Date (Recurrent \"Y-m-d\")" +msgstr "Start Date (Recurrent \"Y-m-d\")" + +# setup/calendarEdit_Holidays.xml?CALENDAR_HOLIDAY_END +# setup/calendarEdit_Holidays.xml +#: date - CALENDAR_HOLIDAY_END +msgid "End Date (Recurrent \"Y-m-d\")" +msgstr "End Date (Recurrent \"Y-m-d\")" + +# setup/calendarList.xml?CALENDAR_NAME +# setup/calendarList.xml +#: text - CALENDAR_NAME +msgid "[setup/calendarList.xml?CALENDAR_NAME] Name" +msgstr "Name" + +# setup/calendarList.xml?CALENDAR_DESCRIPTION +# setup/calendarList.xml +#: text - CALENDAR_DESCRIPTION +msgid "[setup/calendarList.xml?CALENDAR_DESCRIPTION] Description" +msgstr "Description" + +# setup/calendarList.xml?CALENDAR_STATUS +# setup/calendarList.xml +#: text - CALENDAR_STATUS +msgid "[setup/calendarList.xml?CALENDAR_STATUS] Status" +msgstr "Status" + +# setup/calendarList.xml?LINK +# setup/calendarList.xml +#: link - LINK +msgid "[setup/calendarList.xml?LINK]" +msgstr "" + +# setup/calendarList.xml?LINK1 +# setup/calendarList.xml +#: link - LINK1 +msgid "[setup/calendarList.xml?LINK1]" +msgstr "" + +# setup/calendarList.xml?LINK2 +# setup/calendarList.xml +#: link - LINK2 +msgid "[setup/calendarList.xml?LINK2]" +msgstr "" + +# setup/calendarList_Options.xml?MNU_NEW +# setup/calendarList_Options.xml +#: link - MNU_NEW +msgid "[setup/calendarList_Options.xml?MNU_NEW] New" +msgstr "New" + +# setup/emailSetupTest.xml?TITLE1 +# setup/emailSetupTest.xml +#: title - TITLE1 +msgid "Mail System Test Page" +msgstr "Mail System Test Page" + +# setup/emailSetupTest.xml?domain +# setup/emailSetupTest.xml +#: text - domain +msgid "Domain" +msgstr "Domain" + +# setup/emailSetupTest.xml?to_email +# setup/emailSetupTest.xml +#: text - to_email +msgid "To:" +msgstr "To:" + +# setup/emailSetupTest.xml?from_name +# setup/emailSetupTest.xml +#: text - from_name +msgid "From Name:" +msgstr "From Name:" + +# setup/emailSetupTest.xml?from_email +# setup/emailSetupTest.xml +#: text - from_email +msgid "From Email:" +msgstr "From Email:" + +# setup/emailSetupTest.xml?subject +# setup/emailSetupTest.xml +#: text - subject +msgid "Subject:" +msgstr "Subject:" + +# setup/emailSetupTest.xml?body +# setup/emailSetupTest.xml +#: textarea - body +msgid "[setup/emailSetupTest.xml?body] File" +msgstr "File" + +# setup/emailSetupTest.xml?BTN_SUBMIT +# setup/emailSetupTest.xml +#: submit - BTN_SUBMIT +msgid "Send Email" +msgstr "Send Email" + +# setup/emails.xml?THETITLE +# setup/emails.xml +#: title - THETITLE +msgid "[setup/emails.xml?THETITLE] Configuration" +msgstr "Configuration" + +# setup/emails.xml?MESS_ENABLED +# setup/emails.xml +#: checkbox - MESS_ENABLED +msgid "Enable Email Notifications" +msgstr "Enable Email Notifications" + +# setup/emails.xml?MESS_ENGINE +# setup/emails.xml +#: dropdown - MESS_ENGINE +msgid "Email Engine" +msgstr "Email Engine" + +# setup/emails.xml?MESS_SERVER +# setup/emails.xml +#: text - MESS_SERVER +msgid "[setup/emails.xml?MESS_SERVER] Server" +msgstr "Server" + +# setup/emails.xml?MESS_PORT +# setup/emails.xml +#: text - MESS_PORT +msgid "[setup/emails.xml?MESS_PORT] Port" +msgstr "Port" + +# setup/emails.xml?MESS_RAUTH +# setup/emails.xml +#: checkbox - MESS_RAUTH +msgid "Require authentification" +msgstr "Require authentification" + +# setup/emails.xml?MESS_ACCOUNT +# setup/emails.xml +#: text - MESS_ACCOUNT +msgid "Account From" +msgstr "Account From" + +# setup/emails.xml?MESS_PASSWORD +# setup/emails.xml +#: password - MESS_PASSWORD +msgid "[setup/emails.xml?MESS_PASSWORD] Password" +msgstr "Password" + +# setup/emails.xml?MESS_TEST_MAIL +# setup/emails.xml +#: checkbox - MESS_TEST_MAIL +msgid "Send a test mail" +msgstr "Send a test mail" + +# setup/emails.xml?MESS_TEST_MAIL_TO +# setup/emails.xml +#: text - MESS_TEST_MAIL_TO +msgid "Mail to" +msgstr "Mail to" + +# setup/emails.xml?MESS_BACKGROUND +# setup/emails.xml +#: checkbox - MESS_BACKGROUND +msgid "Run in the background" +msgstr "Run in the background" + +# setup/emails.xml?MESS_EXECUTE_EVERY +# setup/emails.xml +#: text - MESS_EXECUTE_EVERY +msgid "Execute every (in minutes)" +msgstr "Execute every (in minutes)" + +# setup/emails.xml?MESS_SEND_MAX +# setup/emails.xml +#: text - MESS_SEND_MAX +msgid "Maximun number of mails sended by attempt" +msgstr "Maximun number of mails sended by attempt" + +# setup/emails.xml?MESS_TRY_SEND_INMEDIATLY +# setup/emails.xml +#: checkbox - MESS_TRY_SEND_INMEDIATLY +msgid "Try send mails inmediatly" +msgstr "Try send mails inmediatly" + +# setup/emails.xml?TEST +# setup/emails.xml +#: button - TEST +msgid "[setup/emails.xml?TEST] Test" +msgstr "Test" + +# setup/emails.xml?SAVE_CHANGES +# setup/emails.xml +#: button - SAVE_CHANGES +msgid "[setup/emails.xml?SAVE_CHANGES] Save Changes" +msgstr "Save Changes" + +# setup/emails.xml?SAVE_CHANGES2 +# setup/emails.xml +#: button - SAVE_CHANGES2 +msgid "[setup/emails.xml?SAVE_CHANGES2] Save Changes" +msgstr "Save Changes" + +# setup/emails_Sended.xml?MESSAGE +# setup/emails_Sended.xml +#: title - MESSAGE +msgid "@#MESSAGE_VALUE" +msgstr "@#MESSAGE_VALUE" + +# setup/emails_Sended.xml?ClOSE +# setup/emails_Sended.xml +#: button - ClOSE +msgid "[setup/emails_Sended.xml?ClOSE] Close" +msgstr "Close" + +# setup/emails_TestForm.xml?THETITLE +# setup/emails_TestForm.xml +#: title - THETITLE +msgid "Mail Configuration Test Page" +msgstr "Mail Configuration Test Page" + +# setup/emails_TestForm.xml?FROM_NAME +# setup/emails_TestForm.xml +#: text - FROM_NAME +msgid "[setup/emails_TestForm.xml?FROM_NAME] From Name:" +msgstr "From Name:" + +# setup/emails_TestForm.xml?FROM_EMAIL +# setup/emails_TestForm.xml +#: text - FROM_EMAIL +msgid "[setup/emails_TestForm.xml?FROM_EMAIL] From Email:" +msgstr "From Email:" + +# setup/emails_TestForm.xml?TO +# setup/emails_TestForm.xml +#: text - TO +msgid "[setup/emails_TestForm.xml?TO] To:" +msgstr "To:" + +# setup/emails_TestForm.xml?SEND +# setup/emails_TestForm.xml +#: button - SEND +msgid "[setup/emails_TestForm.xml?SEND] Send Email" +msgstr "Send Email" + +# setup/holiday.xml?TITLES +# setup/holiday.xml +#: title - TITLES +msgid "Holiday" +msgstr "Holiday" + +# setup/holiday.xml?DATE +# setup/holiday.xml +#: date - DATE +msgid "[setup/holiday.xml?DATE] Date" +msgstr "Date" + +# setup/holiday.xml?DESCRIPTION +# setup/holiday.xml +#: text - DESCRIPTION +msgid "[setup/holiday.xml?DESCRIPTION] Description" +msgstr "Description" + +# setup/holiday.xml?BSUBMIT +# setup/holiday.xml +#: button - BSUBMIT +msgid "[setup/holiday.xml?BSUBMIT] Accept" +msgstr "Accept" + +# setup/holidayList.xml?UID +# setup/holidayList.xml +#: link - UID +msgid "[setup/holidayList.xml?UID] UID" +msgstr "UID" + +# setup/holidayList.xml?DATE +# setup/holidayList.xml +#: text - DATE +msgid "[setup/holidayList.xml?DATE] Date" +msgstr "Date" + +# setup/holidayList.xml?DESCRIPTION +# setup/holidayList.xml +#: text - DESCRIPTION +msgid "[setup/holidayList.xml?DESCRIPTION] Description" +msgstr "Description" + +# setup/holidayList.xml?DELETE +# setup/holidayList.xml +#: link - DELETE +msgid "[setup/holidayList.xml?DELETE] Delete" +msgstr "Delete" + +# setup/holidayListMenu.xml?MNU_NEW +# setup/holidayListMenu.xml +#: link - MNU_NEW +msgid "[setup/holidayListMenu.xml?MNU_NEW] New" +msgstr "New" + +# setup/language.xml?TITLE +# setup/language.xml +#: title - TITLE +msgid "[setup/language.xml?TITLE] Language" +msgstr "Language" + +# setup/language.xml?LEX_VALUE +# setup/language.xml +#: dropdown - LEX_VALUE +msgid "[setup/language.xml?LEX_VALUE] Language" +msgstr "Language" + +# setup/language.xml?BSUBMIT +# setup/language.xml +#: button - BSUBMIT +msgid "[setup/language.xml?BSUBMIT] Add" +msgstr "Add" + +# setup/language_table.xml?TITLE +# setup/language_table.xml +#: title - TITLE +msgid "[setup/language_table.xml?TITLE] Language" +msgstr "Language" + +# setup/language_table.xml?LEX_VALUE +# setup/language_table.xml +#: dropdown - LEX_VALUE +msgid "[setup/language_table.xml?LEX_VALUE] Language" +msgstr "Language" + +# setup/language_table.xml?BSUBMIT +# setup/language_table.xml +#: button - BSUBMIT +msgid "[setup/language_table.xml?BSUBMIT] Add" +msgstr "Add" + +# setup/languages.xml?LAN_ID +# setup/languages.xml +#: text - LAN_ID +msgid "[setup/languages.xml?LAN_ID] Code" +msgstr "Code" + +# setup/languages.xml?LAN_NAME +# setup/languages.xml +#: text - LAN_NAME +msgid "[setup/languages.xml?LAN_NAME] Language" +msgstr "Language" + +# setup/languages.xml?LAN_EXPORT +# setup/languages.xml +#: link - LAN_EXPORT +msgid "[setup/languages.xml?LAN_EXPORT]" +msgstr "" + +# setup/languages.xml?LAN_DELETE +# setup/languages.xml +#: link - LAN_DELETE +msgid "[setup/languages.xml?LAN_DELETE]" +msgstr "" + +# setup/languages_ImportForm.xml?TITLE1 +# setup/languages_ImportForm.xml +#: title - TITLE1 +msgid "Import or Update Language" +msgstr "Import or Update Language" + +# setup/languages_ImportForm.xml?LANGUAGE_FILENAME +# setup/languages_ImportForm.xml +#: file - LANGUAGE_FILENAME +msgid "[setup/languages_ImportForm.xml?LANGUAGE_FILENAME] File" +msgstr "File" + +# setup/languages_ImportForm.xml?IMPORT +# setup/languages_ImportForm.xml +#: button - IMPORT +msgid "[setup/languages_ImportForm.xml?IMPORT] Import" +msgstr "Import" + +# setup/languages_ImportForm.xml?BTN_CANCEL +# setup/languages_ImportForm.xml +#: button - BTN_CANCEL +msgid "[setup/languages_ImportForm.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# setup/languages_Options.xml?MNU_IMPORT +# setup/languages_Options.xml +#: link - MNU_IMPORT +msgid "Import / Update" +msgstr "Import / Update" + +# setup/location.xml?DESCRIPTION +# setup/location.xml +#: text - DESCRIPTION +msgid "Region" +msgstr "Region" + +# setup/location.xml?BSUBMIT +# setup/location.xml +#: button - BSUBMIT +msgid "[setup/location.xml?BSUBMIT] Add" +msgstr "Add" + +# setup/location.xml?TITLE +# setup/location.xml +#: title - TITLE +msgid "[setup/location.xml?TITLE] Region" +msgstr "Region" + +# setup/location.xml?USR_COUNTRY +# setup/location.xml +#: dropdown - USR_COUNTRY +msgid "COUNTRIES" +msgstr "COUNTRIES" + +# setup/location.xml?USR_CITY +# setup/location.xml +#: dropdown - USR_CITY +msgid "CITY" +msgstr "CITY" + +# setup/location.xml?ADD_CITY +# setup/location.xml +#: button - ADD_CITY +msgid "Add city" +msgstr "Add city" + +# setup/location.xml?USR_SUBMIT +# setup/location.xml +#: submit - USR_SUBMIT +msgid "ACCEPT" +msgstr "ACCEPT" + +# setup/mail.xml?TITLE6171 +# setup/mail.xml +#: title - TITLE6171 +msgid "Email Settings" +msgstr "Email Settings" + +# setup/mail.xml?MAILER +# setup/mail.xml +#: dropdown - MAILER +msgid "[setup/mail.xml?MAILER] Method" +msgstr "Method" + +# setup/mail.xml?MAILER-mail +# setup/mail.xml +#: dropdown - MAILER - mail +msgid "[setup/mail.xml?MAILER-mail]" +msgstr "sendmail" + +# setup/mail.xml?MAILER-smtp +# setup/mail.xml +#: dropdown - MAILER - smtp +msgid "[setup/mail.xml?MAILER-smtp]" +msgstr "SMTP" + +# setup/mail.xml?HOST +# setup/mail.xml +#: text - HOST +msgid "[setup/mail.xml?HOST] Server" +msgstr "Server" + +# setup/mail.xml?PORT +# setup/mail.xml +#: text - PORT +msgid "[setup/mail.xml?PORT] Port" +msgstr "Port" + +# setup/mail.xml?TIMEOUT +# setup/mail.xml +#: text - TIMEOUT +msgid "Timeout" +msgstr "Timeout" + +# setup/mail.xml?SMTPAUTH +# setup/mail.xml +#: yesno - SMTPAUTH +msgid "Requires Authentication" +msgstr "Requires Authentication" + +# setup/mail.xml?USERNAME +# setup/mail.xml +#: text - USERNAME +msgid "Email Account" +msgstr "Email Account" + +# setup/mail.xml?PASSWORD +# setup/mail.xml +#: password - PASSWORD +msgid "[setup/mail.xml?PASSWORD] Password" +msgstr "Password" + +# setup/mail.xml?BSUBMIT +# setup/mail.xml +#: submit - BSUBMIT +msgid "[setup/mail.xml?BSUBMIT] Save" +msgstr "Save" + +# setup/mail.xml?BTEST +# setup/mail.xml +#: button - BTEST +msgid "[setup/mail.xml?BTEST] Test" +msgstr "Test" + +# setup/mailTest.xml?TITLE6171 +# setup/mailTest.xml +#: title - TITLE6171 +msgid "[setup/mailTest.xml?TITLE6171] Test Email" +msgstr "Test Email" + +# setup/mailTest.xml?TEST_EMAIL +# setup/mailTest.xml +#: text - TEST_EMAIL +msgid "Send to :" +msgstr "Send to :" + +# setup/mailTest.xml?BTEST +# setup/mailTest.xml +#: button - BTEST +msgid "[setup/mailTest.xml?BTEST] Test" +msgstr "Test" + +# setup/noProcesses.xml?MESSAGE +# setup/noProcesses.xml +#: subtitle - MESSAGE +msgid "No processes available for this environment" +msgstr "No processes available for this environment" + +# setup/pluginImport.xml?TITLE1 +# setup/pluginImport.xml +#: title - TITLE1 +msgid "Import Plugin" +msgstr "Import Plugin" + +# setup/pluginImport.xml?MAX_FILE_SIZE +# setup/pluginImport.xml +#: edit - MAX_FILE_SIZE +msgid "[setup/pluginImport.xml?MAX_FILE_SIZE] Max upload file size in bytes" +msgstr "Max upload file size in bytes" + +# setup/pluginImport.xml?PLUGIN_FILENAME +# setup/pluginImport.xml +#: file - PLUGIN_FILENAME +msgid "[setup/pluginImport.xml?PLUGIN_FILENAME] File" +msgstr "File" + +# setup/pluginImport.xml?SAVE +# setup/pluginImport.xml +#: button - SAVE +msgid "[setup/pluginImport.xml?SAVE] Import" +msgstr "Import" + +# setup/pluginImport.xml?BTN_CANCEL +# setup/pluginImport.xml +#: button - BTN_CANCEL +msgid "[setup/pluginImport.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# setup/pluginList.xml?id +# setup/pluginList.xml +#: text - id +msgid "[setup/pluginList.xml?id] #" +msgstr "#" + +# setup/pluginList.xml?title +# setup/pluginList.xml +#: text - title +msgid "Name (File)" +msgstr "Name (File)" + +# setup/pluginList.xml?description +# setup/pluginList.xml +#: text - description +msgid "[setup/pluginList.xml?description] Description" +msgstr "Description" + +# setup/pluginList.xml?version +# setup/pluginList.xml +#: text - version +msgid "[setup/pluginList.xml?version] Version" +msgstr "Version" + +# setup/pluginList.xml?enabled +# setup/pluginList.xml +#: link - enabled +msgid "[setup/pluginList.xml?enabled]" +msgstr "" + +# setup/pluginList.xml?remove +# setup/pluginList.xml +#: link - remove +msgid "[setup/pluginList.xml?remove]" +msgstr "" + +# setup/pluginList.xml?linkEditValue +# setup/pluginList.xml +#: link - linkEditValue +msgid "[setup/pluginList.xml?linkEditValue]" +msgstr "" + +# setup/plugin_ListOptions.xml?MNU_IMPORT +# setup/plugin_ListOptions.xml +#: link - MNU_IMPORT +msgid "[setup/plugin_ListOptions.xml?MNU_IMPORT] Import" +msgstr "Import" + +# setup/processHeartBeatConfig.xml?HB_TITLE +# setup/processHeartBeatConfig.xml +#: title - HB_TITLE +msgid "Processmaker Heartbeat" +msgstr "Processmaker Heartbeat" + +# setup/processHeartBeatConfig.xml?HB_OPTION +# setup/processHeartBeatConfig.xml +#: dropdown - HB_OPTION +msgid "Enable Heartbeat" +msgstr "Enable Heartbeat" + +# setup/processHeartBeatConfig.xml?HB_OPTION-0 +# setup/processHeartBeatConfig.xml +#: dropdown - HB_OPTION - 0 +msgid "[setup/processHeartBeatConfig.xml?HB_OPTION-0]" +msgstr "No" + +# setup/processHeartBeatConfig.xml?HB_OPTION-1 +# setup/processHeartBeatConfig.xml +#: dropdown - HB_OPTION - 1 +msgid "[setup/processHeartBeatConfig.xml?HB_OPTION-1]" +msgstr "Yes" + +# setup/processHeartBeatConfig.xml?HB_SAVE +# setup/processHeartBeatConfig.xml +#: button - HB_SAVE +msgid "[setup/processHeartBeatConfig.xml?HB_SAVE] save" +msgstr "save" + +# setup/processHeartBeatConfig.xml?HB_LINKINFO +# setup/processHeartBeatConfig.xml +#: link - HB_LINKINFO +msgid "[setup/processHeartBeatConfig.xml?HB_LINKINFO]" +msgstr "" + +# setup/showMessage.xml?TITLE +# setup/showMessage.xml +#: title - TITLE +msgid "[setup/showMessage.xml?TITLE] Error" +msgstr "Error" + +# setup/showMessage.xml?MESSAGE +# setup/showMessage.xml +#: caption - MESSAGE +msgid "you can't delete it is in use." +msgstr "you can't delete it is in use." + +# setup/skinsList.xml?id +# setup/skinsList.xml +#: text - id +msgid "[setup/skinsList.xml?id] #" +msgstr "#" + +# setup/skinsList.xml?name +# setup/skinsList.xml +#: text - name +msgid "[setup/skinsList.xml?name] Name (File)" +msgstr "Name (File)" + +# setup/skinsList.xml?description +# setup/skinsList.xml +#: text - description +msgid "[setup/skinsList.xml?description] Description" +msgstr "Description" + +# setup/skinsList.xml?version +# setup/skinsList.xml +#: text - version +msgid "[setup/skinsList.xml?version] Version" +msgstr "Version" + +# setup/skinsList.xml?linkPackValue +# setup/skinsList.xml +#: link - linkPackValue +msgid "[setup/skinsList.xml?linkPackValue]" +msgstr "" + +# setup/skinsListOptions.xml?MNU_NEW +# setup/skinsListOptions.xml +#: link - MNU_NEW +msgid "[setup/skinsListOptions.xml?MNU_NEW] New" +msgstr "New" + +# setup/skinsNew.xml?TITLE1 +# setup/skinsNew.xml +#: title - TITLE1 +msgid "New Skin" +msgstr "New Skin" + +# setup/skinsNew.xml?NAME +# setup/skinsNew.xml +#: text - NAME +msgid "Skin Name" +msgstr "Skin Name" + +# setup/skinsNew.xml?DESCRIPTION +# setup/skinsNew.xml +#: textarea - DESCRIPTION +msgid "[setup/skinsNew.xml?DESCRIPTION] Description" +msgstr "Description" + +# setup/skinsNew.xml?SAVE +# setup/skinsNew.xml +#: button - SAVE +msgid "[setup/skinsNew.xml?SAVE] Continue" +msgstr "Continue" + +# setup/skinsNew.xml?BTN_CANCEL +# setup/skinsNew.xml +#: button - BTN_CANCEL +msgid "[setup/skinsNew.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# setup/upgrade.xml?TITLE1 +# setup/upgrade.xml +#: title - TITLE1 +msgid "[setup/upgrade.xml?TITLE1] Upgrade System" +msgstr "Upgrade System" + +# setup/upgrade.xml?PM_VERSION +# setup/upgrade.xml +#: edit - PM_VERSION +msgid "Current Version" +msgstr "Current Version" + +# setup/upgrade.xml?MAX_FILE_SIZE +# setup/upgrade.xml +#: edit - MAX_FILE_SIZE +msgid "[setup/upgrade.xml?MAX_FILE_SIZE] Max upload file size in bytes" +msgstr "Max upload file size in bytes" + +# setup/upgrade.xml?UPGRADE_FILENAME +# setup/upgrade.xml +#: file - UPGRADE_FILENAME +msgid "[setup/upgrade.xml?UPGRADE_FILENAME] File" +msgstr "File" + +# setup/upgrade.xml?UPGRADE +# setup/upgrade.xml +#: button - UPGRADE +msgid "Upgrade" +msgstr "Upgrade" + +# setup/uplogo.xml?TITLE1 +# setup/uplogo.xml +#: title - TITLE1 +msgid "Upload your logo" +msgstr "Upload your logo" + +# setup/uplogo.xml?MAX_FILE_SIZE +# setup/uplogo.xml +#: edit - MAX_FILE_SIZE +msgid "[setup/uplogo.xml?MAX_FILE_SIZE] Max upload file size in bytes" +msgstr "Max upload file size in bytes" + +# setup/uplogo.xml?LOGO_FILENAME +# setup/uplogo.xml +#: file - LOGO_FILENAME +msgid "[setup/uplogo.xml?LOGO_FILENAME] File" +msgstr "File" + +# setup/uplogo.xml?LOGO_SAVE +# setup/uplogo.xml +#: button - LOGO_SAVE +msgid "[setup/uplogo.xml?LOGO_SAVE] Upload" +msgstr "Upload" + +# setup/uplogoList.xml?id +# setup/uplogoList.xml +#: text - id +msgid "No." +msgstr "No." + +# setup/uplogoList.xml?LOG0_IMACE +# setup/uplogoList.xml +#: text - LOG0_IMACE +msgid "imagen" +msgstr "imagen" + +# setup/uplogoList.xml?LOG0_NAME +# setup/uplogoList.xml +#: text - LOG0_NAME +msgid "[setup/uplogoList.xml?LOG0_NAME] name" +msgstr "name" + +# setup/uplogoList.xml?LOG0_SIZE +# setup/uplogoList.xml +#: text - LOG0_SIZE +msgid "size" +msgstr "size" + +# setup/uplogoList.xml?LOG0_DESCRIPTION +# setup/uplogoList.xml +#: text - LOG0_DESCRIPTION +msgid "[setup/uplogoList.xml?LOG0_DESCRIPTION] Description" +msgstr "Description" + +# setup/uplogoList.xml?LOGO_SELECTED +# setup/uplogoList.xml +#: text - LOGO_SELECTED +msgid "[setup/uplogoList.xml?LOGO_SELECTED]" +msgstr "" + +# setup/uplogoList.xml?DELETE_LOGO +# setup/uplogoList.xml +#: link - DELETE_LOGO +msgid "[setup/uplogoList.xml?DELETE_LOGO]" +msgstr "" + +# setup/webServicesDetails.xml?title2 +# setup/webServicesDetails.xml +#: title - title2 +msgid "WSDL Server Details" +msgstr "WSDL Server Details" + +# setup/webServicesDetails.xml?WS_HOST +# setup/webServicesDetails.xml +#: text - WS_HOST +msgid "[setup/webServicesDetails.xml?WS_HOST] Server" +msgstr "Server" + +# setup/webServicesDetails.xml?WS_PORT +# setup/webServicesDetails.xml +#: text - WS_PORT +msgid "[setup/webServicesDetails.xml?WS_PORT] Port" +msgstr "Port" + +# setup/webServicesDetails.xml?WSDL +# setup/webServicesDetails.xml +#: text - WSDL +msgid "WSDL URI" +msgstr "WSDL URI" + +# setup/webServicesDetails.xml?WS_WORKSPACE +# setup/webServicesDetails.xml +#: text - WS_WORKSPACE +msgid "[setup/webServicesDetails.xml?WS_WORKSPACE] Workspace" +msgstr "Workspace" + +# setup/webServicesDetails.xml?WSID +# setup/webServicesDetails.xml +#: text - WSID +msgid "Session ID" +msgstr "Session ID" + +# setup/webServicesSetup.xml?title2 +# setup/webServicesSetup.xml +#: title - title2 +msgid "Client Setup" +msgstr "Client Setup" + +# setup/webServicesSetup.xml?WS_PROTOCOL +# setup/webServicesSetup.xml +#: dropdown - WS_PROTOCOL +msgid "Protocol" +msgstr "Protocol" + +# setup/webServicesSetup.xml?WS_HOST +# setup/webServicesSetup.xml +#: text - WS_HOST +msgid "Server Host" +msgstr "Server Host" + +# setup/webServicesSetup.xml?WS_WORKSPACE +# setup/webServicesSetup.xml +#: text - WS_WORKSPACE +msgid "[setup/webServicesSetup.xml?WS_WORKSPACE] Workspace" +msgstr "Workspace" + +# setup/webServicesSetup.xml?WS_PORT +# setup/webServicesSetup.xml +#: text - WS_PORT +msgid "[setup/webServicesSetup.xml?WS_PORT] Port" +msgstr "Port" + +# setup/webServicesSetup.xml?button +# setup/webServicesSetup.xml +#: submit - button +msgid "[setup/webServicesSetup.xml?button] Save" +msgstr "Save" + +# setup/webServicesSetup.xml?BTN_CANCEL +# setup/webServicesSetup.xml +#: button - BTN_CANCEL +msgid "[setup/webServicesSetup.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# setup/weekend.xml?TITLE9592 +# setup/weekend.xml +#: title - TITLE9592 +msgid "Weekend days" +msgstr "Weekend days" + +# setup/weekend.xml?MONDAY +# setup/weekend.xml +#: checkbox - MONDAY +msgid "Monday" +msgstr "Monday" + +# setup/weekend.xml?TUESDAY +# setup/weekend.xml +#: checkbox - TUESDAY +msgid "Tuesday" +msgstr "Tuesday" + +# setup/weekend.xml?WEDNESDAY +# setup/weekend.xml +#: checkbox - WEDNESDAY +msgid "Wednesday" +msgstr "Wednesday" + +# setup/weekend.xml?THURSDAY +# setup/weekend.xml +#: checkbox - THURSDAY +msgid "Thursday" +msgstr "Thursday" + +# setup/weekend.xml?FRIDAY +# setup/weekend.xml +#: checkbox - FRIDAY +msgid "Friday" +msgstr "Friday" + +# setup/weekend.xml?SATURDAY +# setup/weekend.xml +#: checkbox - SATURDAY +msgid "Saturday" +msgstr "Saturday" + +# setup/weekend.xml?SUNDAY +# setup/weekend.xml +#: checkbox - SUNDAY +msgid "Sunday" +msgstr "Sunday" + +# setup/weekend.xml?BSUBMIT +# setup/weekend.xml +#: button - BSUBMIT +msgid "[setup/weekend.xml?BSUBMIT] Accept" +msgstr "Accept" + +# setup/workPeriod.xml?TITLE9592 +# setup/workPeriod.xml +#: title - TITLE9592 +msgid "[setup/workPeriod.xml?TITLE9592] Weekend days" +msgstr "Weekend days" + +# setup/workPeriod.xml?SUNDAY +# setup/workPeriod.xml +#: checkbox - SUNDAY +msgid "[setup/workPeriod.xml?SUNDAY] Sunday" +msgstr "Sunday" + +# setup/workPeriod.xml?MONDAY +# setup/workPeriod.xml +#: checkbox - MONDAY +msgid "[setup/workPeriod.xml?MONDAY] Monday" +msgstr "Monday" + +# setup/workPeriod.xml?TUESDAY +# setup/workPeriod.xml +#: checkbox - TUESDAY +msgid "[setup/workPeriod.xml?TUESDAY] Tuesday" +msgstr "Tuesday" + +# setup/workPeriod.xml?WEDNESDAY +# setup/workPeriod.xml +#: checkbox - WEDNESDAY +msgid "[setup/workPeriod.xml?WEDNESDAY] Wednesday" +msgstr "Wednesday" + +# setup/workPeriod.xml?THURSDAY +# setup/workPeriod.xml +#: checkbox - THURSDAY +msgid "[setup/workPeriod.xml?THURSDAY] Thursday" +msgstr "Thursday" + +# setup/workPeriod.xml?FRIDAY +# setup/workPeriod.xml +#: checkbox - FRIDAY +msgid "[setup/workPeriod.xml?FRIDAY] Friday" +msgstr "Friday" + +# setup/workPeriod.xml?SATURDAY +# setup/workPeriod.xml +#: checkbox - SATURDAY +msgid "[setup/workPeriod.xml?SATURDAY] Saturday" +msgstr "Saturday" + +# setup/workPeriod.xml?titulo +# setup/workPeriod.xml +#: title - titulo +msgid "First Period" +msgstr "First Period" + +# setup/workPeriod.xml?initPeriod1 +# setup/workPeriod.xml +#: dropdown - initPeriod1 +msgid "Start time" +msgstr "Start time" + +# setup/workPeriod.xml?initPeriod1-'' +# setup/workPeriod.xml +#: dropdown - initPeriod1 - '' +msgid "[setup/workPeriod.xml?initPeriod1-'']" +msgstr "00:00 a.m" + +# setup/workPeriod.xml?initPeriod1-30 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 30 +msgid "[setup/workPeriod.xml?initPeriod1-30]" +msgstr "00:30 a.m" + +# setup/workPeriod.xml?initPeriod1-60 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 60 +msgid "[setup/workPeriod.xml?initPeriod1-60]" +msgstr "01:00 a.m" + +# setup/workPeriod.xml?initPeriod1-90 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 90 +msgid "[setup/workPeriod.xml?initPeriod1-90]" +msgstr "01:30 a.m" + +# setup/workPeriod.xml?initPeriod1-120 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 120 +msgid "[setup/workPeriod.xml?initPeriod1-120]" +msgstr "02:00 a.m" + +# setup/workPeriod.xml?initPeriod1-150 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 150 +msgid "[setup/workPeriod.xml?initPeriod1-150]" +msgstr "02:30 a.m" + +# setup/workPeriod.xml?initPeriod1-180 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 180 +msgid "[setup/workPeriod.xml?initPeriod1-180]" +msgstr "03:00 a.m" + +# setup/workPeriod.xml?initPeriod1-210 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 210 +msgid "[setup/workPeriod.xml?initPeriod1-210]" +msgstr "03:30 a.m" + +# setup/workPeriod.xml?initPeriod1-240 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 240 +msgid "[setup/workPeriod.xml?initPeriod1-240]" +msgstr "04:00 a.m" + +# setup/workPeriod.xml?initPeriod1-270 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 270 +msgid "[setup/workPeriod.xml?initPeriod1-270]" +msgstr "04:30 a.m" + +# setup/workPeriod.xml?initPeriod1-300 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 300 +msgid "[setup/workPeriod.xml?initPeriod1-300]" +msgstr "05:00 a.m" + +# setup/workPeriod.xml?initPeriod1-330 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 330 +msgid "[setup/workPeriod.xml?initPeriod1-330]" +msgstr "05:30 a.m" + +# setup/workPeriod.xml?initPeriod1-360 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 360 +msgid "[setup/workPeriod.xml?initPeriod1-360]" +msgstr "06:00 a.m" + +# setup/workPeriod.xml?initPeriod1-390 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 390 +msgid "[setup/workPeriod.xml?initPeriod1-390]" +msgstr "06:30 a.m" + +# setup/workPeriod.xml?initPeriod1-420 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 420 +msgid "[setup/workPeriod.xml?initPeriod1-420]" +msgstr "07:00 a.m" + +# setup/workPeriod.xml?initPeriod1-450 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 450 +msgid "[setup/workPeriod.xml?initPeriod1-450]" +msgstr "07:30 a.m" + +# setup/workPeriod.xml?initPeriod1-480 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 480 +msgid "[setup/workPeriod.xml?initPeriod1-480]" +msgstr "08:00 a.m" + +# setup/workPeriod.xml?initPeriod1-510 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 510 +msgid "[setup/workPeriod.xml?initPeriod1-510]" +msgstr "08:30 a.m" + +# setup/workPeriod.xml?initPeriod1-540 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 540 +msgid "[setup/workPeriod.xml?initPeriod1-540]" +msgstr "09:00 a.m" + +# setup/workPeriod.xml?initPeriod1-570 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 570 +msgid "[setup/workPeriod.xml?initPeriod1-570]" +msgstr "09:30 a.m" + +# setup/workPeriod.xml?initPeriod1-600 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 600 +msgid "[setup/workPeriod.xml?initPeriod1-600]" +msgstr "10:00 a.m" + +# setup/workPeriod.xml?initPeriod1-630 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 630 +msgid "[setup/workPeriod.xml?initPeriod1-630]" +msgstr "10:30 a.m" + +# setup/workPeriod.xml?initPeriod1-660 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 660 +msgid "[setup/workPeriod.xml?initPeriod1-660]" +msgstr "11:00 a.m" + +# setup/workPeriod.xml?initPeriod1-690 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 690 +msgid "[setup/workPeriod.xml?initPeriod1-690]" +msgstr "11:30 a.m" + +# setup/workPeriod.xml?initPeriod1-720 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 720 +msgid "[setup/workPeriod.xml?initPeriod1-720]" +msgstr "12:00 p.m" + +# setup/workPeriod.xml?initPeriod1-750 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 750 +msgid "[setup/workPeriod.xml?initPeriod1-750]" +msgstr "12:30 p.m" + +# setup/workPeriod.xml?initPeriod1-780 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 780 +msgid "[setup/workPeriod.xml?initPeriod1-780]" +msgstr "13:00 p.m" + +# setup/workPeriod.xml?initPeriod1-810 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 810 +msgid "[setup/workPeriod.xml?initPeriod1-810]" +msgstr "13:30 p.m" + +# setup/workPeriod.xml?initPeriod1-840 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 840 +msgid "[setup/workPeriod.xml?initPeriod1-840]" +msgstr "14:00 p.m" + +# setup/workPeriod.xml?initPeriod1-870 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 870 +msgid "[setup/workPeriod.xml?initPeriod1-870]" +msgstr "14:30 p.m" + +# setup/workPeriod.xml?initPeriod1-900 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 900 +msgid "[setup/workPeriod.xml?initPeriod1-900]" +msgstr "15:00 p.m" + +# setup/workPeriod.xml?initPeriod1-930 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 930 +msgid "[setup/workPeriod.xml?initPeriod1-930]" +msgstr "15:30 p.m" + +# setup/workPeriod.xml?initPeriod1-960 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 960 +msgid "[setup/workPeriod.xml?initPeriod1-960]" +msgstr "16:00 p.m" + +# setup/workPeriod.xml?initPeriod1-990 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 990 +msgid "[setup/workPeriod.xml?initPeriod1-990]" +msgstr "16:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1020 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1020 +msgid "[setup/workPeriod.xml?initPeriod1-1020]" +msgstr "17:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1050 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1050 +msgid "[setup/workPeriod.xml?initPeriod1-1050]" +msgstr "17:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1080 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1080 +msgid "[setup/workPeriod.xml?initPeriod1-1080]" +msgstr "18:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1110 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1110 +msgid "[setup/workPeriod.xml?initPeriod1-1110]" +msgstr "18:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1140 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1140 +msgid "[setup/workPeriod.xml?initPeriod1-1140]" +msgstr "19:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1170 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1170 +msgid "[setup/workPeriod.xml?initPeriod1-1170]" +msgstr "19:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1200 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1200 +msgid "[setup/workPeriod.xml?initPeriod1-1200]" +msgstr "20:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1230 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1230 +msgid "[setup/workPeriod.xml?initPeriod1-1230]" +msgstr "20:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1260 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1260 +msgid "[setup/workPeriod.xml?initPeriod1-1260]" +msgstr "21:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1290 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1290 +msgid "[setup/workPeriod.xml?initPeriod1-1290]" +msgstr "21:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1320 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1320 +msgid "[setup/workPeriod.xml?initPeriod1-1320]" +msgstr "22:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1350 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1350 +msgid "[setup/workPeriod.xml?initPeriod1-1350]" +msgstr "22:30 p.m" + +# setup/workPeriod.xml?initPeriod1-1380 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1380 +msgid "[setup/workPeriod.xml?initPeriod1-1380]" +msgstr "23:00 p.m" + +# setup/workPeriod.xml?initPeriod1-1410 +# setup/workPeriod.xml +#: dropdown - initPeriod1 - 1410 +msgid "[setup/workPeriod.xml?initPeriod1-1410]" +msgstr "23:30 p.m" + +# setup/workPeriod.xml?endPeriod1 +# setup/workPeriod.xml +#: dropdown - endPeriod1 +msgid "End time" +msgstr "End time" + +# setup/workPeriod.xml?endPeriod1-'' +# setup/workPeriod.xml +#: dropdown - endPeriod1 - '' +msgid "[setup/workPeriod.xml?endPeriod1-'']" +msgstr "00:00 a.m" + +# setup/workPeriod.xml?endPeriod1-30 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 30 +msgid "[setup/workPeriod.xml?endPeriod1-30]" +msgstr "00:30 a.m" + +# setup/workPeriod.xml?endPeriod1-60 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 60 +msgid "[setup/workPeriod.xml?endPeriod1-60]" +msgstr "01:00 a.m" + +# setup/workPeriod.xml?endPeriod1-90 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 90 +msgid "[setup/workPeriod.xml?endPeriod1-90]" +msgstr "01:30 a.m" + +# setup/workPeriod.xml?endPeriod1-120 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 120 +msgid "[setup/workPeriod.xml?endPeriod1-120]" +msgstr "02:00 a.m" + +# setup/workPeriod.xml?endPeriod1-150 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 150 +msgid "[setup/workPeriod.xml?endPeriod1-150]" +msgstr "02:30 a.m" + +# setup/workPeriod.xml?endPeriod1-180 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 180 +msgid "[setup/workPeriod.xml?endPeriod1-180]" +msgstr "03:00 a.m" + +# setup/workPeriod.xml?endPeriod1-210 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 210 +msgid "[setup/workPeriod.xml?endPeriod1-210]" +msgstr "03:30 a.m" + +# setup/workPeriod.xml?endPeriod1-240 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 240 +msgid "[setup/workPeriod.xml?endPeriod1-240]" +msgstr "04:00 a.m" + +# setup/workPeriod.xml?endPeriod1-270 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 270 +msgid "[setup/workPeriod.xml?endPeriod1-270]" +msgstr "04:30 a.m" + +# setup/workPeriod.xml?endPeriod1-300 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 300 +msgid "[setup/workPeriod.xml?endPeriod1-300]" +msgstr "05:00 a.m" + +# setup/workPeriod.xml?endPeriod1-330 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 330 +msgid "[setup/workPeriod.xml?endPeriod1-330]" +msgstr "05:30 a.m" + +# setup/workPeriod.xml?endPeriod1-360 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 360 +msgid "[setup/workPeriod.xml?endPeriod1-360]" +msgstr "06:00 a.m" + +# setup/workPeriod.xml?endPeriod1-390 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 390 +msgid "[setup/workPeriod.xml?endPeriod1-390]" +msgstr "06:30 a.m" + +# setup/workPeriod.xml?endPeriod1-420 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 420 +msgid "[setup/workPeriod.xml?endPeriod1-420]" +msgstr "07:00 a.m" + +# setup/workPeriod.xml?endPeriod1-450 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 450 +msgid "[setup/workPeriod.xml?endPeriod1-450]" +msgstr "07:30 a.m" + +# setup/workPeriod.xml?endPeriod1-480 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 480 +msgid "[setup/workPeriod.xml?endPeriod1-480]" +msgstr "08:00 a.m" + +# setup/workPeriod.xml?endPeriod1-510 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 510 +msgid "[setup/workPeriod.xml?endPeriod1-510]" +msgstr "08:30 a.m" + +# setup/workPeriod.xml?endPeriod1-540 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 540 +msgid "[setup/workPeriod.xml?endPeriod1-540]" +msgstr "09:00 a.m" + +# setup/workPeriod.xml?endPeriod1-570 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 570 +msgid "[setup/workPeriod.xml?endPeriod1-570]" +msgstr "09:30 a.m" + +# setup/workPeriod.xml?endPeriod1-600 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 600 +msgid "[setup/workPeriod.xml?endPeriod1-600]" +msgstr "10:00 a.m" + +# setup/workPeriod.xml?endPeriod1-630 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 630 +msgid "[setup/workPeriod.xml?endPeriod1-630]" +msgstr "10:30 a.m" + +# setup/workPeriod.xml?endPeriod1-660 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 660 +msgid "[setup/workPeriod.xml?endPeriod1-660]" +msgstr "11:00 a.m" + +# setup/workPeriod.xml?endPeriod1-690 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 690 +msgid "[setup/workPeriod.xml?endPeriod1-690]" +msgstr "11:30 a.m" + +# setup/workPeriod.xml?endPeriod1-720 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 720 +msgid "[setup/workPeriod.xml?endPeriod1-720]" +msgstr "12:00 p.m" + +# setup/workPeriod.xml?endPeriod1-750 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 750 +msgid "[setup/workPeriod.xml?endPeriod1-750]" +msgstr "12:30 p.m" + +# setup/workPeriod.xml?endPeriod1-780 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 780 +msgid "[setup/workPeriod.xml?endPeriod1-780]" +msgstr "13:00 p.m" + +# setup/workPeriod.xml?endPeriod1-810 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 810 +msgid "[setup/workPeriod.xml?endPeriod1-810]" +msgstr "13:30 p.m" + +# setup/workPeriod.xml?endPeriod1-840 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 840 +msgid "[setup/workPeriod.xml?endPeriod1-840]" +msgstr "14:00 p.m" + +# setup/workPeriod.xml?endPeriod1-870 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 870 +msgid "[setup/workPeriod.xml?endPeriod1-870]" +msgstr "14:30 p.m" + +# setup/workPeriod.xml?endPeriod1-900 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 900 +msgid "[setup/workPeriod.xml?endPeriod1-900]" +msgstr "15:00 p.m" + +# setup/workPeriod.xml?endPeriod1-930 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 930 +msgid "[setup/workPeriod.xml?endPeriod1-930]" +msgstr "15:30 p.m" + +# setup/workPeriod.xml?endPeriod1-960 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 960 +msgid "[setup/workPeriod.xml?endPeriod1-960]" +msgstr "16:00 p.m" + +# setup/workPeriod.xml?endPeriod1-990 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 990 +msgid "[setup/workPeriod.xml?endPeriod1-990]" +msgstr "16:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1020 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1020 +msgid "[setup/workPeriod.xml?endPeriod1-1020]" +msgstr "17:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1050 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1050 +msgid "[setup/workPeriod.xml?endPeriod1-1050]" +msgstr "17:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1080 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1080 +msgid "[setup/workPeriod.xml?endPeriod1-1080]" +msgstr "18:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1110 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1110 +msgid "[setup/workPeriod.xml?endPeriod1-1110]" +msgstr "18:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1140 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1140 +msgid "[setup/workPeriod.xml?endPeriod1-1140]" +msgstr "19:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1170 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1170 +msgid "[setup/workPeriod.xml?endPeriod1-1170]" +msgstr "19:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1200 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1200 +msgid "[setup/workPeriod.xml?endPeriod1-1200]" +msgstr "20:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1230 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1230 +msgid "[setup/workPeriod.xml?endPeriod1-1230]" +msgstr "20:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1260 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1260 +msgid "[setup/workPeriod.xml?endPeriod1-1260]" +msgstr "21:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1290 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1290 +msgid "[setup/workPeriod.xml?endPeriod1-1290]" +msgstr "21:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1320 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1320 +msgid "[setup/workPeriod.xml?endPeriod1-1320]" +msgstr "22:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1350 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1350 +msgid "[setup/workPeriod.xml?endPeriod1-1350]" +msgstr "22:30 p.m" + +# setup/workPeriod.xml?endPeriod1-1380 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1380 +msgid "[setup/workPeriod.xml?endPeriod1-1380]" +msgstr "23:00 p.m" + +# setup/workPeriod.xml?endPeriod1-1410 +# setup/workPeriod.xml +#: dropdown - endPeriod1 - 1410 +msgid "[setup/workPeriod.xml?endPeriod1-1410]" +msgstr "23:30 p.m" + +# setup/workPeriod.xml?titulo2 +# setup/workPeriod.xml +#: title - titulo2 +msgid "Second period" +msgstr "Second period" + +# setup/workPeriod.xml?initPeriod2 +# setup/workPeriod.xml +#: dropdown - initPeriod2 +msgid "[setup/workPeriod.xml?initPeriod2] Start time" +msgstr "Start time" + +# setup/workPeriod.xml?initPeriod2-'' +# setup/workPeriod.xml +#: dropdown - initPeriod2 - '' +msgid "[setup/workPeriod.xml?initPeriod2-'']" +msgstr "00:00 a.m" + +# setup/workPeriod.xml?initPeriod2-30 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 30 +msgid "[setup/workPeriod.xml?initPeriod2-30]" +msgstr "00:30 a.m" + +# setup/workPeriod.xml?initPeriod2-60 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 60 +msgid "[setup/workPeriod.xml?initPeriod2-60]" +msgstr "01:00 a.m" + +# setup/workPeriod.xml?initPeriod2-90 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 90 +msgid "[setup/workPeriod.xml?initPeriod2-90]" +msgstr "01:30 a.m" + +# setup/workPeriod.xml?initPeriod2-120 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 120 +msgid "[setup/workPeriod.xml?initPeriod2-120]" +msgstr "02:00 a.m" + +# setup/workPeriod.xml?initPeriod2-150 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 150 +msgid "[setup/workPeriod.xml?initPeriod2-150]" +msgstr "02:30 a.m" + +# setup/workPeriod.xml?initPeriod2-180 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 180 +msgid "[setup/workPeriod.xml?initPeriod2-180]" +msgstr "03:00 a.m" + +# setup/workPeriod.xml?initPeriod2-210 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 210 +msgid "[setup/workPeriod.xml?initPeriod2-210]" +msgstr "03:30 a.m" + +# setup/workPeriod.xml?initPeriod2-240 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 240 +msgid "[setup/workPeriod.xml?initPeriod2-240]" +msgstr "04:00 a.m" + +# setup/workPeriod.xml?initPeriod2-270 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 270 +msgid "[setup/workPeriod.xml?initPeriod2-270]" +msgstr "04:30 a.m" + +# setup/workPeriod.xml?initPeriod2-300 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 300 +msgid "[setup/workPeriod.xml?initPeriod2-300]" +msgstr "05:00 a.m" + +# setup/workPeriod.xml?initPeriod2-330 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 330 +msgid "[setup/workPeriod.xml?initPeriod2-330]" +msgstr "05:30 a.m" + +# setup/workPeriod.xml?initPeriod2-360 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 360 +msgid "[setup/workPeriod.xml?initPeriod2-360]" +msgstr "06:00 a.m" + +# setup/workPeriod.xml?initPeriod2-390 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 390 +msgid "[setup/workPeriod.xml?initPeriod2-390]" +msgstr "06:30 a.m" + +# setup/workPeriod.xml?initPeriod2-420 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 420 +msgid "[setup/workPeriod.xml?initPeriod2-420]" +msgstr "07:00 a.m" + +# setup/workPeriod.xml?initPeriod2-450 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 450 +msgid "[setup/workPeriod.xml?initPeriod2-450]" +msgstr "07:30 a.m" + +# setup/workPeriod.xml?initPeriod2-480 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 480 +msgid "[setup/workPeriod.xml?initPeriod2-480]" +msgstr "08:00 a.m" + +# setup/workPeriod.xml?initPeriod2-510 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 510 +msgid "[setup/workPeriod.xml?initPeriod2-510]" +msgstr "08:30 a.m" + +# setup/workPeriod.xml?initPeriod2-540 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 540 +msgid "[setup/workPeriod.xml?initPeriod2-540]" +msgstr "09:00 a.m" + +# setup/workPeriod.xml?initPeriod2-570 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 570 +msgid "[setup/workPeriod.xml?initPeriod2-570]" +msgstr "09:30 a.m" + +# setup/workPeriod.xml?initPeriod2-600 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 600 +msgid "[setup/workPeriod.xml?initPeriod2-600]" +msgstr "10:00 a.m" + +# setup/workPeriod.xml?initPeriod2-630 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 630 +msgid "[setup/workPeriod.xml?initPeriod2-630]" +msgstr "10:30 a.m" + +# setup/workPeriod.xml?initPeriod2-660 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 660 +msgid "[setup/workPeriod.xml?initPeriod2-660]" +msgstr "11:00 a.m" + +# setup/workPeriod.xml?initPeriod2-690 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 690 +msgid "[setup/workPeriod.xml?initPeriod2-690]" +msgstr "11:30 a.m" + +# setup/workPeriod.xml?initPeriod2-720 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 720 +msgid "[setup/workPeriod.xml?initPeriod2-720]" +msgstr "12:00 p.m" + +# setup/workPeriod.xml?initPeriod2-750 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 750 +msgid "[setup/workPeriod.xml?initPeriod2-750]" +msgstr "12:30 p.m" + +# setup/workPeriod.xml?initPeriod2-780 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 780 +msgid "[setup/workPeriod.xml?initPeriod2-780]" +msgstr "13:00 p.m" + +# setup/workPeriod.xml?initPeriod2-810 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 810 +msgid "[setup/workPeriod.xml?initPeriod2-810]" +msgstr "13:30 p.m" + +# setup/workPeriod.xml?initPeriod2-840 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 840 +msgid "[setup/workPeriod.xml?initPeriod2-840]" +msgstr "14:00 p.m" + +# setup/workPeriod.xml?initPeriod2-870 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 870 +msgid "[setup/workPeriod.xml?initPeriod2-870]" +msgstr "14:30 p.m" + +# setup/workPeriod.xml?initPeriod2-900 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 900 +msgid "[setup/workPeriod.xml?initPeriod2-900]" +msgstr "15:00 p.m" + +# setup/workPeriod.xml?initPeriod2-930 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 930 +msgid "[setup/workPeriod.xml?initPeriod2-930]" +msgstr "15:30 p.m" + +# setup/workPeriod.xml?initPeriod2-960 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 960 +msgid "[setup/workPeriod.xml?initPeriod2-960]" +msgstr "16:00 p.m" + +# setup/workPeriod.xml?initPeriod2-990 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 990 +msgid "[setup/workPeriod.xml?initPeriod2-990]" +msgstr "16:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1020 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1020 +msgid "[setup/workPeriod.xml?initPeriod2-1020]" +msgstr "17:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1050 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1050 +msgid "[setup/workPeriod.xml?initPeriod2-1050]" +msgstr "17:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1080 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1080 +msgid "[setup/workPeriod.xml?initPeriod2-1080]" +msgstr "18:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1110 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1110 +msgid "[setup/workPeriod.xml?initPeriod2-1110]" +msgstr "18:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1140 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1140 +msgid "[setup/workPeriod.xml?initPeriod2-1140]" +msgstr "19:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1170 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1170 +msgid "[setup/workPeriod.xml?initPeriod2-1170]" +msgstr "19:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1200 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1200 +msgid "[setup/workPeriod.xml?initPeriod2-1200]" +msgstr "20:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1230 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1230 +msgid "[setup/workPeriod.xml?initPeriod2-1230]" +msgstr "20:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1260 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1260 +msgid "[setup/workPeriod.xml?initPeriod2-1260]" +msgstr "21:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1290 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1290 +msgid "[setup/workPeriod.xml?initPeriod2-1290]" +msgstr "21:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1320 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1320 +msgid "[setup/workPeriod.xml?initPeriod2-1320]" +msgstr "22:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1350 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1350 +msgid "[setup/workPeriod.xml?initPeriod2-1350]" +msgstr "22:30 p.m" + +# setup/workPeriod.xml?initPeriod2-1380 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1380 +msgid "[setup/workPeriod.xml?initPeriod2-1380]" +msgstr "23:00 p.m" + +# setup/workPeriod.xml?initPeriod2-1410 +# setup/workPeriod.xml +#: dropdown - initPeriod2 - 1410 +msgid "[setup/workPeriod.xml?initPeriod2-1410]" +msgstr "23:30 p.m" + +# setup/workPeriod.xml?endPeriod2 +# setup/workPeriod.xml +#: dropdown - endPeriod2 +msgid "[setup/workPeriod.xml?endPeriod2] End time" +msgstr "End time" + +# setup/workPeriod.xml?endPeriod2-'' +# setup/workPeriod.xml +#: dropdown - endPeriod2 - '' +msgid "[setup/workPeriod.xml?endPeriod2-'']" +msgstr "00:00 a.m" + +# setup/workPeriod.xml?endPeriod2-30 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 30 +msgid "[setup/workPeriod.xml?endPeriod2-30]" +msgstr "00:30 a.m" + +# setup/workPeriod.xml?endPeriod2-60 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 60 +msgid "[setup/workPeriod.xml?endPeriod2-60]" +msgstr "01:00 a.m" + +# setup/workPeriod.xml?endPeriod2-90 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 90 +msgid "[setup/workPeriod.xml?endPeriod2-90]" +msgstr "01:30 a.m" + +# setup/workPeriod.xml?endPeriod2-120 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 120 +msgid "[setup/workPeriod.xml?endPeriod2-120]" +msgstr "02:00 a.m" + +# setup/workPeriod.xml?endPeriod2-150 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 150 +msgid "[setup/workPeriod.xml?endPeriod2-150]" +msgstr "02:30 a.m" + +# setup/workPeriod.xml?endPeriod2-180 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 180 +msgid "[setup/workPeriod.xml?endPeriod2-180]" +msgstr "03:00 a.m" + +# setup/workPeriod.xml?endPeriod2-210 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 210 +msgid "[setup/workPeriod.xml?endPeriod2-210]" +msgstr "03:30 a.m" + +# setup/workPeriod.xml?endPeriod2-240 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 240 +msgid "[setup/workPeriod.xml?endPeriod2-240]" +msgstr "04:00 a.m" + +# setup/workPeriod.xml?endPeriod2-270 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 270 +msgid "[setup/workPeriod.xml?endPeriod2-270]" +msgstr "04:30 a.m" + +# setup/workPeriod.xml?endPeriod2-300 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 300 +msgid "[setup/workPeriod.xml?endPeriod2-300]" +msgstr "05:00 a.m" + +# setup/workPeriod.xml?endPeriod2-330 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 330 +msgid "[setup/workPeriod.xml?endPeriod2-330]" +msgstr "05:30 a.m" + +# setup/workPeriod.xml?endPeriod2-360 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 360 +msgid "[setup/workPeriod.xml?endPeriod2-360]" +msgstr "06:00 a.m" + +# setup/workPeriod.xml?endPeriod2-390 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 390 +msgid "[setup/workPeriod.xml?endPeriod2-390]" +msgstr "06:30 a.m" + +# setup/workPeriod.xml?endPeriod2-420 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 420 +msgid "[setup/workPeriod.xml?endPeriod2-420]" +msgstr "07:00 a.m" + +# setup/workPeriod.xml?endPeriod2-450 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 450 +msgid "[setup/workPeriod.xml?endPeriod2-450]" +msgstr "07:30 a.m" + +# setup/workPeriod.xml?endPeriod2-480 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 480 +msgid "[setup/workPeriod.xml?endPeriod2-480]" +msgstr "08:00 a.m" + +# setup/workPeriod.xml?endPeriod2-510 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 510 +msgid "[setup/workPeriod.xml?endPeriod2-510]" +msgstr "08:30 a.m" + +# setup/workPeriod.xml?endPeriod2-540 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 540 +msgid "[setup/workPeriod.xml?endPeriod2-540]" +msgstr "09:00 a.m" + +# setup/workPeriod.xml?endPeriod2-570 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 570 +msgid "[setup/workPeriod.xml?endPeriod2-570]" +msgstr "09:30 a.m" + +# setup/workPeriod.xml?endPeriod2-600 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 600 +msgid "[setup/workPeriod.xml?endPeriod2-600]" +msgstr "10:00 a.m" + +# setup/workPeriod.xml?endPeriod2-630 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 630 +msgid "[setup/workPeriod.xml?endPeriod2-630]" +msgstr "10:30 a.m" + +# setup/workPeriod.xml?endPeriod2-660 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 660 +msgid "[setup/workPeriod.xml?endPeriod2-660]" +msgstr "11:00 a.m" + +# setup/workPeriod.xml?endPeriod2-690 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 690 +msgid "[setup/workPeriod.xml?endPeriod2-690]" +msgstr "11:30 a.m" + +# setup/workPeriod.xml?endPeriod2-720 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 720 +msgid "[setup/workPeriod.xml?endPeriod2-720]" +msgstr "12:00 p.m" + +# setup/workPeriod.xml?endPeriod2-750 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 750 +msgid "[setup/workPeriod.xml?endPeriod2-750]" +msgstr "12:30 p.m" + +# setup/workPeriod.xml?endPeriod2-780 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 780 +msgid "[setup/workPeriod.xml?endPeriod2-780]" +msgstr "13:00 p.m" + +# setup/workPeriod.xml?endPeriod2-810 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 810 +msgid "[setup/workPeriod.xml?endPeriod2-810]" +msgstr "13:30 p.m" + +# setup/workPeriod.xml?endPeriod2-840 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 840 +msgid "[setup/workPeriod.xml?endPeriod2-840]" +msgstr "14:00 p.m" + +# setup/workPeriod.xml?endPeriod2-870 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 870 +msgid "[setup/workPeriod.xml?endPeriod2-870]" +msgstr "14:30 p.m" + +# setup/workPeriod.xml?endPeriod2-900 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 900 +msgid "[setup/workPeriod.xml?endPeriod2-900]" +msgstr "15:00 p.m" + +# setup/workPeriod.xml?endPeriod2-930 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 930 +msgid "[setup/workPeriod.xml?endPeriod2-930]" +msgstr "15:30 p.m" + +# setup/workPeriod.xml?endPeriod2-960 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 960 +msgid "[setup/workPeriod.xml?endPeriod2-960]" +msgstr "16:00 p.m" + +# setup/workPeriod.xml?endPeriod2-990 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 990 +msgid "[setup/workPeriod.xml?endPeriod2-990]" +msgstr "16:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1020 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1020 +msgid "[setup/workPeriod.xml?endPeriod2-1020]" +msgstr "17:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1050 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1050 +msgid "[setup/workPeriod.xml?endPeriod2-1050]" +msgstr "17:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1080 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1080 +msgid "[setup/workPeriod.xml?endPeriod2-1080]" +msgstr "18:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1110 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1110 +msgid "[setup/workPeriod.xml?endPeriod2-1110]" +msgstr "18:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1140 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1140 +msgid "[setup/workPeriod.xml?endPeriod2-1140]" +msgstr "19:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1170 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1170 +msgid "[setup/workPeriod.xml?endPeriod2-1170]" +msgstr "19:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1200 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1200 +msgid "[setup/workPeriod.xml?endPeriod2-1200]" +msgstr "20:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1230 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1230 +msgid "[setup/workPeriod.xml?endPeriod2-1230]" +msgstr "20:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1260 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1260 +msgid "[setup/workPeriod.xml?endPeriod2-1260]" +msgstr "21:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1290 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1290 +msgid "[setup/workPeriod.xml?endPeriod2-1290]" +msgstr "21:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1320 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1320 +msgid "[setup/workPeriod.xml?endPeriod2-1320]" +msgstr "22:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1350 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1350 +msgid "[setup/workPeriod.xml?endPeriod2-1350]" +msgstr "22:30 p.m" + +# setup/workPeriod.xml?endPeriod2-1380 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1380 +msgid "[setup/workPeriod.xml?endPeriod2-1380]" +msgstr "23:00 p.m" + +# setup/workPeriod.xml?endPeriod2-1410 +# setup/workPeriod.xml +#: dropdown - endPeriod2 - 1410 +msgid "[setup/workPeriod.xml?endPeriod2-1410]" +msgstr "23:30 p.m" + +# setup/workPeriod.xml?BSUBMIT +# setup/workPeriod.xml +#: submit - BSUBMIT +msgid "[setup/workPeriod.xml?BSUBMIT] Accept" +msgstr "Accept" + +# setup/wsAssignUserToGroup.xml?SESSION_ID +# setup/wsAssignUserToGroup.xml +#: text - SESSION_ID +msgid "Session Id" +msgstr "Session Id" + +# setup/wsAssignUserToGroup.xml?USER_ID +# setup/wsAssignUserToGroup.xml +#: dropdown - USER_ID +msgid "User ID" +msgstr "User ID" + +# setup/wsAssignUserToGroup.xml?GROUP_ID +# setup/wsAssignUserToGroup.xml +#: dropdown - GROUP_ID +msgid "Group ID" +msgstr "Group ID" + +# setup/wsAssignUserToGroup.xml?ACTIONB +# setup/wsAssignUserToGroup.xml +#: button - ACTIONB +msgid "AssignUserToGroup" +msgstr "AssignUserToGroup" + +# setup/wsCaseList.xml?SESSION_ID +# setup/wsCaseList.xml +#: text - SESSION_ID +msgid "[setup/wsCaseList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsCaseList.xml?ACTIONB +# setup/wsCaseList.xml +#: button - ACTIONB +msgid "CaseList" +msgstr "CaseList" + +# setup/wsCreateUser.xml?SESSION_ID +# setup/wsCreateUser.xml +#: text - SESSION_ID +msgid "[setup/wsCreateUser.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsCreateUser.xml?USER_ID +# setup/wsCreateUser.xml +#: text - USER_ID +msgid "[setup/wsCreateUser.xml?USER_ID] User ID" +msgstr "User ID" + +# setup/wsCreateUser.xml?PASSWORD +# setup/wsCreateUser.xml +#: password - PASSWORD +msgid "[setup/wsCreateUser.xml?PASSWORD] Password" +msgstr "Password" + +# setup/wsCreateUser.xml?FIRST_NAME +# setup/wsCreateUser.xml +#: text - FIRST_NAME +msgid "[setup/wsCreateUser.xml?FIRST_NAME] First Name" +msgstr "First Name" + +# setup/wsCreateUser.xml?LAST_NAME +# setup/wsCreateUser.xml +#: text - LAST_NAME +msgid "[setup/wsCreateUser.xml?LAST_NAME] Last Name" +msgstr "Last Name" + +# setup/wsCreateUser.xml?EMAIL +# setup/wsCreateUser.xml +#: text - EMAIL +msgid "[setup/wsCreateUser.xml?EMAIL] Email" +msgstr "Email" + +# setup/wsCreateUser.xml?ROLE +# setup/wsCreateUser.xml +#: dropdown - ROLE +msgid "Role" +msgstr "Role" + +# setup/wsCreateUser.xml?ACTIONB +# setup/wsCreateUser.xml +#: button - ACTIONB +msgid "CreateUser" +msgstr "CreateUser" + +# setup/wsDerivateCase.xml?SESSION_ID +# setup/wsDerivateCase.xml +#: text - SESSION_ID +msgid "[setup/wsDerivateCase.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsDerivateCase.xml?CASE_ID +# setup/wsDerivateCase.xml +#: dropdown - CASE_ID +msgid "Case ID" +msgstr "Case ID" + +# setup/wsDerivateCase.xml?DEL_INDEX +# setup/wsDerivateCase.xml +#: dropdown - DEL_INDEX +msgid "Task Case(delindex)" +msgstr "Task Case(delindex)" + +# setup/wsDerivateCase.xml?DEL_INDEX-'' +# setup/wsDerivateCase.xml +#: dropdown - DEL_INDEX - '' +msgid "[setup/wsDerivateCase.xml?DEL_INDEX-'']" +msgstr "Default" + +# setup/wsDerivateCase.xml?ACTIONB +# setup/wsDerivateCase.xml +#: button - ACTIONB +msgid "DerivateCase" +msgstr "DerivateCase" + +# setup/wsGroupList.xml?SESSION_ID +# setup/wsGroupList.xml +#: text - SESSION_ID +msgid "[setup/wsGroupList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsGroupList.xml?ACTIONB +# setup/wsGroupList.xml +#: button - ACTIONB +msgid "GroupList" +msgstr "GroupList" + +# setup/wsInputDocumentList.xml?SESSION_ID +# setup/wsInputDocumentList.xml +#: text - SESSION_ID +msgid "[setup/wsInputDocumentList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsInputDocumentList.xml?CASE_ID +# setup/wsInputDocumentList.xml +#: dropdown - CASE_ID +msgid "[setup/wsInputDocumentList.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsInputDocumentList.xml?ACTIONB +# setup/wsInputDocumentList.xml +#: button - ACTIONB +msgid "InputDocumentList" +msgstr "InputDocumentList" + +# setup/wsInputDocumentProcessList.xml?SESSION_ID +# setup/wsInputDocumentProcessList.xml +#: text - SESSION_ID +msgid "[setup/wsInputDocumentProcessList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsInputDocumentProcessList.xml?PROCESS_ID +# setup/wsInputDocumentProcessList.xml +#: dropdown - PROCESS_ID +msgid "Process ID" +msgstr "Process ID" + +# setup/wsInputDocumentProcessList.xml?ACTIONB +# setup/wsInputDocumentProcessList.xml +#: button - ACTIONB +msgid "InputDocumentProcessList" +msgstr "InputDocumentProcessList" + +# setup/wsLogin.xml?title +# setup/wsLogin.xml +#: title - title +msgid "Login to WSDL Server" +msgstr "Login to WSDL Server" + +# setup/wsLogin.xml?USER_ID +# setup/wsLogin.xml +#: text - USER_ID +msgid "[setup/wsLogin.xml?USER_ID] User ID" +msgstr "User ID" + +# setup/wsLogin.xml?PASSWORD +# setup/wsLogin.xml +#: password - PASSWORD +msgid "[setup/wsLogin.xml?PASSWORD] Password" +msgstr "Password" + +# setup/wsLogin.xml?ACTIONB +# setup/wsLogin.xml +#: button - ACTIONB +msgid "[setup/wsLogin.xml?ACTIONB] Login" +msgstr "Login" + +# setup/wsMessage.xml?MESSAGE +# setup/wsMessage.xml +#: title - MESSAGE +msgid "You do not have enabled the SOAP extension" +msgstr "You do not have enabled the SOAP extension" + +# setup/wsNewCase.xml?SESSION_ID +# setup/wsNewCase.xml +#: text - SESSION_ID +msgid "[setup/wsNewCase.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsNewCase.xml?PROCESS_ID +# setup/wsNewCase.xml +#: dropdown - PROCESS_ID +msgid "[setup/wsNewCase.xml?PROCESS_ID] Process ID" +msgstr "Process ID" + +# setup/wsNewCase.xml?TASK_ID +# setup/wsNewCase.xml +#: dropdown - TASK_ID +msgid "[setup/wsNewCase.xml?TASK_ID] Task ID" +msgstr "Task ID" + +# setup/wsNewCase.xml?TASK_ID-'' +# setup/wsNewCase.xml +#: dropdown - TASK_ID - '' +msgid "[setup/wsNewCase.xml?TASK_ID-'']" +msgstr "Default" + +# setup/wsNewCase.xml?ACTIONB +# setup/wsNewCase.xml +#: button - ACTIONB +msgid "NewCase" +msgstr "NewCase" + +# setup/wsNewCaseImpersonate.xml?SESSION_ID +# setup/wsNewCaseImpersonate.xml +#: text - SESSION_ID +msgid "[setup/wsNewCaseImpersonate.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsNewCaseImpersonate.xml?PROCESS_ID +# setup/wsNewCaseImpersonate.xml +#: dropdown - PROCESS_ID +msgid "[setup/wsNewCaseImpersonate.xml?PROCESS_ID] Process ID" +msgstr "Process ID" + +# setup/wsNewCaseImpersonate.xml?USER_ID +# setup/wsNewCaseImpersonate.xml +#: dropdown - USER_ID +msgid "[setup/wsNewCaseImpersonate.xml?USER_ID] User ID" +msgstr "User ID" + +# setup/wsNewCaseImpersonate.xml?ACTIONB +# setup/wsNewCaseImpersonate.xml +#: button - ACTIONB +msgid "NewCaseImpersonate" +msgstr "NewCaseImpersonate" + +# setup/wsOutputDocumentList.xml?SESSION_ID +# setup/wsOutputDocumentList.xml +#: text - SESSION_ID +msgid "[setup/wsOutputDocumentList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsOutputDocumentList.xml?CASE_ID +# setup/wsOutputDocumentList.xml +#: dropdown - CASE_ID +msgid "[setup/wsOutputDocumentList.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsOutputDocumentList.xml?ACTIONB +# setup/wsOutputDocumentList.xml +#: button - ACTIONB +msgid "OutputDocumentList" +msgstr "OutputDocumentList" + +# setup/wsProcessList.xml?SESSION_ID +# setup/wsProcessList.xml +#: text - SESSION_ID +msgid "[setup/wsProcessList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsProcessList.xml?ACTIONB +# setup/wsProcessList.xml +#: button - ACTIONB +msgid "ProcessList" +msgstr "ProcessList" + +# setup/wsReassignCase.xml?SESSION_ID +# setup/wsReassignCase.xml +#: text - SESSION_ID +msgid "[setup/wsReassignCase.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsReassignCase.xml?CASE_ID +# setup/wsReassignCase.xml +#: dropdown - CASE_ID +msgid "[setup/wsReassignCase.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsReassignCase.xml?DEL_INDEX +# setup/wsReassignCase.xml +#: dropdown - DEL_INDEX +msgid "Delindex" +msgstr "Delindex" + +# setup/wsReassignCase.xml?DEL_INDEX-'' +# setup/wsReassignCase.xml +#: dropdown - DEL_INDEX - '' +msgid "[setup/wsReassignCase.xml?DEL_INDEX-'']" +msgstr "Default" + +# setup/wsReassignCase.xml?USERIDSOURCE +# setup/wsReassignCase.xml +#: dropdown - USERIDSOURCE +msgid "User Source" +msgstr "User Source" + +# setup/wsReassignCase.xml?USERIDTARGET +# setup/wsReassignCase.xml +#: dropdown - USERIDTARGET +msgid "User Target" +msgstr "User Target" + +# setup/wsReassignCase.xml?ACTIONB +# setup/wsReassignCase.xml +#: button - ACTIONB +msgid "ReassignCase" +msgstr "ReassignCase" + +# setup/wsRemoveDocument.xml?SESSION_ID +# setup/wsRemoveDocument.xml +#: text - SESSION_ID +msgid "[setup/wsRemoveDocument.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsRemoveDocument.xml?APP_DOC_UID +# setup/wsRemoveDocument.xml +#: dropdown - APP_DOC_UID +msgid "Document ID" +msgstr "Document ID" + +# setup/wsRemoveDocument.xml?ACTIONB +# setup/wsRemoveDocument.xml +#: button - ACTIONB +msgid "RemoveDocument" +msgstr "RemoveDocument" + +# setup/wsRoleList.xml?SESSION_ID +# setup/wsRoleList.xml +#: text - SESSION_ID +msgid "[setup/wsRoleList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsRoleList.xml?ACTIONB +# setup/wsRoleList.xml +#: button - ACTIONB +msgid "RoleList" +msgstr "RoleList" + +# setup/wsSendFiles.xml?SESSION_ID +# setup/wsSendFiles.xml +#: text - SESSION_ID +msgid "[setup/wsSendFiles.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsSendFiles.xml?UPLOAD_FILE +# setup/wsSendFiles.xml +#: title - UPLOAD_FILE +msgid "Send your file to the server" +msgstr "Send your file to the server" + +# setup/wsSendFiles.xml?UPLOAD_OPTION +# setup/wsSendFiles.xml +#: dropdown - UPLOAD_OPTION +msgid "Upload Option" +msgstr "Upload Option" + +# setup/wsSendFiles.xml?UPLOAD_OPTION-'' +# setup/wsSendFiles.xml +#: dropdown - UPLOAD_OPTION - '' +msgid "[setup/wsSendFiles.xml?UPLOAD_OPTION-'']" +msgstr "Attached File" + +# setup/wsSendFiles.xml?UPLOAD_OPTION-1 +# setup/wsSendFiles.xml +#: dropdown - UPLOAD_OPTION - 1 +msgid "[setup/wsSendFiles.xml?UPLOAD_OPTION-1]" +msgstr "Input Document" + +# setup/wsSendFiles.xml?INPUT_DOCUMENT +# setup/wsSendFiles.xml +#: dropdown - INPUT_DOCUMENT +msgid "[setup/wsSendFiles.xml?INPUT_DOCUMENT] Input Document" +msgstr "Input Document" + +# setup/wsSendFiles.xml?FILE_TO_UPLOAD +# setup/wsSendFiles.xml +#: file - FILE_TO_UPLOAD +msgid "File to Send" +msgstr "File to Send" + +# setup/wsSendFiles.xml?SEND_FILE +# setup/wsSendFiles.xml +#: submit - SEND_FILE +msgid "Sending" +msgstr "Sending" + +# setup/wsSendMessage.xml?SESSION_ID +# setup/wsSendMessage.xml +#: text - SESSION_ID +msgid "[setup/wsSendMessage.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsSendMessage.xml?CASE_ID +# setup/wsSendMessage.xml +#: dropdown - CASE_ID +msgid "[setup/wsSendMessage.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsSendMessage.xml?FROM +# setup/wsSendMessage.xml +#: text - FROM +msgid "[setup/wsSendMessage.xml?FROM] From" +msgstr "From" + +# setup/wsSendMessage.xml?TO_EMAIL +# setup/wsSendMessage.xml +#: text - TO_EMAIL +msgid "[setup/wsSendMessage.xml?TO_EMAIL] TO" +msgstr "TO" + +# setup/wsSendMessage.xml?CC_EMAIL +# setup/wsSendMessage.xml +#: text - CC_EMAIL +msgid "[setup/wsSendMessage.xml?CC_EMAIL] CC" +msgstr "CC" + +# setup/wsSendMessage.xml?BCC_MAIL +# setup/wsSendMessage.xml +#: text - BCC_MAIL +msgid "[setup/wsSendMessage.xml?BCC_MAIL] BCC" +msgstr "BCC" + +# setup/wsSendMessage.xml?SUBJECT +# setup/wsSendMessage.xml +#: text - SUBJECT +msgid "[setup/wsSendMessage.xml?SUBJECT] Subject" +msgstr "Subject" + +# setup/wsSendMessage.xml?MESSAGE +# setup/wsSendMessage.xml +#: textarea - MESSAGE +msgid "Message" +msgstr "Message" + +# setup/wsSendMessage.xml?ACTIONB +# setup/wsSendMessage.xml +#: button - ACTIONB +msgid "SendMessage" +msgstr "SendMessage" + +# setup/wsSendVariables.xml?SESSION_ID +# setup/wsSendVariables.xml +#: text - SESSION_ID +msgid "[setup/wsSendVariables.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsSendVariables.xml?CASE_ID +# setup/wsSendVariables.xml +#: dropdown - CASE_ID +msgid "[setup/wsSendVariables.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsSendVariables.xml?NAME1 +# setup/wsSendVariables.xml +#: text - NAME1 +msgid "Name 1" +msgstr "Name 1" + +# setup/wsSendVariables.xml?VALUE1 +# setup/wsSendVariables.xml +#: text - VALUE1 +msgid "Value 1" +msgstr "Value 1" + +# setup/wsSendVariables.xml?NAME2 +# setup/wsSendVariables.xml +#: text - NAME2 +msgid "Name 2" +msgstr "Name 2" + +# setup/wsSendVariables.xml?VALUE2 +# setup/wsSendVariables.xml +#: text - VALUE2 +msgid "Value 2" +msgstr "Value 2" + +# setup/wsSendVariables.xml?ACTIONB +# setup/wsSendVariables.xml +#: button - ACTIONB +msgid "SendVariables" +msgstr "SendVariables" + +# setup/wsShowResult.xml?status_code +# setup/wsShowResult.xml +#: text - status_code +msgid "Status Code" +msgstr "Status Code" + +# setup/wsShowResult.xml?message +# setup/wsShowResult.xml +#: textarea - message +msgid "[setup/wsShowResult.xml?message] Message" +msgstr "Message" + +# setup/wsShowResult.xml?time_stamp +# setup/wsShowResult.xml +#: text - time_stamp +msgid "Time Stamp" +msgstr "Time Stamp" + +# setup/wsTaskCase.xml?SESSION_ID +# setup/wsTaskCase.xml +#: text - SESSION_ID +msgid "[setup/wsTaskCase.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsTaskCase.xml?CASE_ID +# setup/wsTaskCase.xml +#: dropdown - CASE_ID +msgid "[setup/wsTaskCase.xml?CASE_ID] Case ID" +msgstr "Case ID" + +# setup/wsTaskCase.xml?ACTIONB +# setup/wsTaskCase.xml +#: button - ACTIONB +msgid "TaskCase" +msgstr "TaskCase" + +# setup/wsTaskList.xml?SESSION_ID +# setup/wsTaskList.xml +#: text - SESSION_ID +msgid "[setup/wsTaskList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsTaskList.xml?ACTIONB +# setup/wsTaskList.xml +#: button - ACTIONB +msgid "TaskList" +msgstr "TaskList" + +# setup/wsTriggerList.xml?SESSION_ID +# setup/wsTriggerList.xml +#: text - SESSION_ID +msgid "[setup/wsTriggerList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsTriggerList.xml?ACTIONB +# setup/wsTriggerList.xml +#: button - ACTIONB +msgid "TriggerList" +msgstr "TriggerList" + +# setup/wsUserList.xml?SESSION_ID +# setup/wsUserList.xml +#: text - SESSION_ID +msgid "[setup/wsUserList.xml?SESSION_ID] Session Id" +msgstr "Session Id" + +# setup/wsUserList.xml?ACTIONB +# setup/wsUserList.xml +#: button - ACTIONB +msgid "UserList" +msgstr "UserList" + +# setup/wsVariablesGrid.xml?NAME +# setup/wsVariablesGrid.xml +#: text - NAME +msgid "[setup/wsVariablesGrid.xml?NAME] Name" +msgstr "Name" + +# setup/wsVariablesGrid.xml?VALUE +# setup/wsVariablesGrid.xml +#: text - VALUE +msgid "[setup/wsVariablesGrid.xml?VALUE] Value" +msgstr "Value" + +# setup/wsrCaseList.xml?guid +# setup/wsrCaseList.xml +#: text - guid +msgid "GUID" +msgstr "GUID" + +# setup/wsrCaseList.xml?name +# setup/wsrCaseList.xml +#: text - name +msgid "[setup/wsrCaseList.xml?name] Case Title" +msgstr "Case Title" + +# setup/wsrCaseList.xml?status +# setup/wsrCaseList.xml +#: text - status +msgid "[setup/wsrCaseList.xml?status] Status" +msgstr "Status" + +# setup/wsrCaseList.xml?delIndex +# setup/wsrCaseList.xml +#: text - delIndex +msgid "[setup/wsrCaseList.xml?delIndex] Del Index" +msgstr "Del Index" + +# setup/wsrGroupList.xml?guid +# setup/wsrGroupList.xml +#: text - guid +msgid "[setup/wsrGroupList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrGroupList.xml?name +# setup/wsrGroupList.xml +#: text - name +msgid "Group Title" +msgstr "Group Title" + +# setup/wsrInputDocumentList.xml?document +# setup/wsrInputDocumentList.xml +#: link - document +msgid "[setup/wsrInputDocumentList.xml?document]" +msgstr "" + +# setup/wsrInputDocumentList.xml?filename +# setup/wsrInputDocumentList.xml +#: text - filename +msgid "[setup/wsrInputDocumentList.xml?filename] Filename" +msgstr "Filename" + +# setup/wsrInputDocumentList.xml?docId +# setup/wsrInputDocumentList.xml +#: text - docId +msgid "Document GUID" +msgstr "Document GUID" + +# setup/wsrInputDocumentList.xml?version +# setup/wsrInputDocumentList.xml +#: text - version +msgid "version" +msgstr "version" + +# setup/wsrInputDocumentList.xml?createDate +# setup/wsrInputDocumentList.xml +#: text - createDate +msgid "create Date" +msgstr "create Date" + +# setup/wsrInputDocumentList.xml?createBy +# setup/wsrInputDocumentList.xml +#: text - createBy +msgid "created by" +msgstr "created by" + +# setup/wsrInputDocumentList.xml?type +# setup/wsrInputDocumentList.xml +#: text - type +msgid "type" +msgstr "type" + +# setup/wsrInputDocumentProcessList.xml?guid +# setup/wsrInputDocumentProcessList.xml +#: text - guid +msgid "InputDocument GUID" +msgstr "InputDocument GUID" + +# setup/wsrInputDocumentProcessList.xml?name +# setup/wsrInputDocumentProcessList.xml +#: text - name +msgid "[setup/wsrInputDocumentProcessList.xml?name] Name" +msgstr "Name" + +# setup/wsrInputDocumentProcessList.xml?description +# setup/wsrInputDocumentProcessList.xml +#: text - description +msgid "description" +msgstr "description" + +# setup/wsrOutputDocumentList.xml?document +# setup/wsrOutputDocumentList.xml +#: link - document +msgid "[setup/wsrOutputDocumentList.xml?document]" +msgstr "" + +# setup/wsrOutputDocumentList.xml?filename +# setup/wsrOutputDocumentList.xml +#: text - filename +msgid "[setup/wsrOutputDocumentList.xml?filename] Filename" +msgstr "Filename" + +# setup/wsrOutputDocumentList.xml?docId +# setup/wsrOutputDocumentList.xml +#: text - docId +msgid "[setup/wsrOutputDocumentList.xml?docId] Document GUID" +msgstr "Document GUID" + +# setup/wsrOutputDocumentList.xml?version +# setup/wsrOutputDocumentList.xml +#: text - version +msgid "[setup/wsrOutputDocumentList.xml?version] version" +msgstr "version" + +# setup/wsrOutputDocumentList.xml?createDate +# setup/wsrOutputDocumentList.xml +#: text - createDate +msgid "[setup/wsrOutputDocumentList.xml?createDate] create Date" +msgstr "create Date" + +# setup/wsrOutputDocumentList.xml?createBy +# setup/wsrOutputDocumentList.xml +#: text - createBy +msgid "[setup/wsrOutputDocumentList.xml?createBy] created by" +msgstr "created by" + +# setup/wsrOutputDocumentList.xml?type +# setup/wsrOutputDocumentList.xml +#: text - type +msgid "[setup/wsrOutputDocumentList.xml?type] type" +msgstr "type" + +# setup/wsrProcessList.xml?guid +# setup/wsrProcessList.xml +#: text - guid +msgid "[setup/wsrProcessList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrProcessList.xml?name +# setup/wsrProcessList.xml +#: text - name +msgid "[setup/wsrProcessList.xml?name] Process Title" +msgstr "Process Title" + +# setup/wsrRoleList.xml?guid +# setup/wsrRoleList.xml +#: text - guid +msgid "[setup/wsrRoleList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrRoleList.xml?name +# setup/wsrRoleList.xml +#: text - name +msgid "Role Title" +msgstr "Role Title" + +# setup/wsrTaskCase.xml?guid +# setup/wsrTaskCase.xml +#: text - guid +msgid "[setup/wsrTaskCase.xml?guid] Del Index" +msgstr "Del Index" + +# setup/wsrTaskCase.xml?name +# setup/wsrTaskCase.xml +#: text - name +msgid "Task Title" +msgstr "Task Title" + +# setup/wsrTaskList.xml?guid +# setup/wsrTaskList.xml +#: text - guid +msgid "[setup/wsrTaskList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrTaskList.xml?name +# setup/wsrTaskList.xml +#: text - name +msgid "[setup/wsrTaskList.xml?name] Task Title" +msgstr "Task Title" + +# setup/wsrTriggerList.xml?guid +# setup/wsrTriggerList.xml +#: text - guid +msgid "[setup/wsrTriggerList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrTriggerList.xml?name +# setup/wsrTriggerList.xml +#: text - name +msgid "[setup/wsrTriggerList.xml?name] Task Title" +msgstr "Task Title" + +# setup/wsrTriggerList.xml?processId +# setup/wsrTriggerList.xml +#: text - processId +msgid "Process GUID/Title" +msgstr "Process GUID/Title" + +# setup/wsrUserList.xml?guid +# setup/wsrUserList.xml +#: text - guid +msgid "[setup/wsrUserList.xml?guid] GUID" +msgstr "GUID" + +# setup/wsrUserList.xml?name +# setup/wsrUserList.xml +#: text - name +msgid "[setup/wsrUserList.xml?name] User" +msgstr "User" + +# steps/conditions_Edit.xml?STEP_CONDITION +# steps/conditions_Edit.xml +#: textareapm - STEP_CONDITION +msgid "[steps/conditions_Edit.xml?STEP_CONDITION] Condition" +msgstr "Condition" + +# steps/conditions_Edit.xml?ACCEPT +# steps/conditions_Edit.xml +#: button - ACCEPT +msgid "[steps/conditions_Edit.xml?ACCEPT] Save" +msgstr "Save" + +# steps/conditions_List.xml?STEP_TITLE +# steps/conditions_List.xml +#: text - STEP_TITLE +msgid "[steps/conditions_List.xml?STEP_TITLE] Title" +msgstr "Title" + +# steps/conditions_List.xml?STEP_CONDITION +# steps/conditions_List.xml +#: text - STEP_CONDITION +msgid "[steps/conditions_List.xml?STEP_CONDITION] Condition" +msgstr "Condition" + +# steps/conditions_List.xml?EDIT +# steps/conditions_List.xml +#: link - EDIT +msgid "[steps/conditions_List.xml?EDIT]" +msgstr "" + +# steps/conditions_List.xml?SEARCH +# steps/conditions_List.xml +#: button - SEARCH +msgid "[steps/conditions_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# steps/steps_List.xml?STEP_TITLE +# steps/steps_List.xml +#: text - STEP_TITLE +msgid "[steps/steps_List.xml?STEP_TITLE] Title" +msgstr "Title" + +# steps/steps_List.xml?STEP_TYPE_OBJ +# steps/steps_List.xml +#: dropdown - STEP_TYPE_OBJ +msgid "[steps/steps_List.xml?STEP_TYPE_OBJ] Type" +msgstr "Type" + +# steps/steps_List.xml?STEP_TYPE_OBJ-DYNAFORM +# steps/steps_List.xml +#: dropdown - STEP_TYPE_OBJ - DYNAFORM +msgid "[steps/steps_List.xml?STEP_TYPE_OBJ-DYNAFORM]" +msgstr "Dynaform" + +# steps/steps_List.xml?STEP_TYPE_OBJ-INPUT_DOCUMENT +# steps/steps_List.xml +#: dropdown - STEP_TYPE_OBJ - INPUT_DOCUMENT +msgid "[steps/steps_List.xml?STEP_TYPE_OBJ-INPUT_DOCUMENT]" +msgstr "Input Document" + +# steps/steps_List.xml?STEP_TYPE_OBJ-OUTPUT_DOCUMENT +# steps/steps_List.xml +#: dropdown - STEP_TYPE_OBJ - OUTPUT_DOCUMENT +msgid "[steps/steps_List.xml?STEP_TYPE_OBJ-OUTPUT_DOCUMENT]" +msgstr "Output Document" + +# steps/steps_List.xml?STEP_TYPE_OBJ-EXTERNAL +# steps/steps_List.xml +#: dropdown - STEP_TYPE_OBJ - EXTERNAL +msgid "[steps/steps_List.xml?STEP_TYPE_OBJ-EXTERNAL]" +msgstr "External Step" + +# steps/steps_List.xml?linkEditValue +# steps/steps_List.xml +#: link - linkEditValue +msgid "[steps/steps_List.xml?linkEditValue]" +msgstr "" + +# steps/steps_List.xml?DELETE +# steps/steps_List.xml +#: link - DELETE +msgid "[steps/steps_List.xml?DELETE]" +msgstr "" + +# steps/steps_List.xml?UP +# steps/steps_List.xml +#: link - UP +msgid "[steps/steps_List.xml?UP]" +msgstr "" + +# steps/steps_List.xml?DOWN +# steps/steps_List.xml +#: link - DOWN +msgid "[steps/steps_List.xml?DOWN]" +msgstr "" + +# steps/steps_List.xml?SEARCH +# steps/steps_List.xml +#: button - SEARCH +msgid "[steps/steps_List.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# steps/steps_Options.xml?MNU_ADD +# steps/steps_Options.xml +#: link - MNU_ADD +msgid "[steps/steps_Options.xml?MNU_ADD] New" +msgstr "New" + +# steps/steps_availableBB.xml?STEP_TITLE +# steps/steps_availableBB.xml +#: text - STEP_TITLE +msgid "[steps/steps_availableBB.xml?STEP_TITLE] Title" +msgstr "Title" + +# steps/steps_availableBB.xml?STEP_TYPE_OBJ +# steps/steps_availableBB.xml +#: dropdown - STEP_TYPE_OBJ +msgid "[steps/steps_availableBB.xml?STEP_TYPE_OBJ] Type" +msgstr "Type" + +# steps/steps_availableBB.xml?STEP_TYPE_OBJ-DYNAFORM +# steps/steps_availableBB.xml +#: dropdown - STEP_TYPE_OBJ - DYNAFORM +msgid "[steps/steps_availableBB.xml?STEP_TYPE_OBJ-DYNAFORM]" +msgstr "Dynaform" + +# steps/steps_availableBB.xml?STEP_TYPE_OBJ-OUTPUT_DOCUMENT +# steps/steps_availableBB.xml +#: dropdown - STEP_TYPE_OBJ - OUTPUT_DOCUMENT +msgid "[steps/steps_availableBB.xml?STEP_TYPE_OBJ-OUTPUT_DOCUMENT]" +msgstr "Output Document" + +# steps/steps_availableBB.xml?STEP_TYPE_OBJ-INPUT_DOCUMENT +# steps/steps_availableBB.xml +#: dropdown - STEP_TYPE_OBJ - INPUT_DOCUMENT +msgid "[steps/steps_availableBB.xml?STEP_TYPE_OBJ-INPUT_DOCUMENT]" +msgstr "Documentation" + +# steps/steps_availableBB.xml?STEP_TYPE_OBJ-EXTERNAL +# steps/steps_availableBB.xml +#: dropdown - STEP_TYPE_OBJ - EXTERNAL +msgid "[steps/steps_availableBB.xml?STEP_TYPE_OBJ-EXTERNAL]" +msgstr "External Step" + +# steps/steps_availableBB.xml?STEP_MODE +# steps/steps_availableBB.xml +#: text - STEP_MODE +msgid "[steps/steps_availableBB.xml?STEP_MODE] Mode" +msgstr "Mode" + +# steps/steps_availableBB.xml?ASSIGN +# steps/steps_availableBB.xml +#: link - ASSIGN +msgid "[steps/steps_availableBB.xml?ASSIGN]" +msgstr "" + +# steps/triggersAfter_List.xml?TRI_TITLE +# steps/triggersAfter_List.xml +#: text - TRI_TITLE +msgid "[steps/triggersAfter_List.xml?TRI_TITLE] Title" +msgstr "Title" + +# steps/triggersAfter_List.xml?CONDITION +# steps/triggersAfter_List.xml +#: link - CONDITION +msgid "[steps/triggersAfter_List.xml?CONDITION]" +msgstr "" + +# steps/triggersAfter_List.xml?UP +# steps/triggersAfter_List.xml +#: link - UP +msgid "[steps/triggersAfter_List.xml?UP]" +msgstr "" + +# steps/triggersAfter_List.xml?DOWN +# steps/triggersAfter_List.xml +#: link - DOWN +msgid "[steps/triggersAfter_List.xml?DOWN]" +msgstr "" + +# steps/triggersAfter_List.xml?DELETE +# steps/triggersAfter_List.xml +#: link - DELETE +msgid "[steps/triggersAfter_List.xml?DELETE]" +msgstr "" + +# steps/triggersAfter_Options.xml?MNU_ADD +# steps/triggersAfter_Options.xml +#: link - MNU_ADD +msgid "[steps/triggersAfter_Options.xml?MNU_ADD] Add" +msgstr "Add" + +# steps/triggersBefore_List.xml?TRI_TITLE +# steps/triggersBefore_List.xml +#: text - TRI_TITLE +msgid "[steps/triggersBefore_List.xml?TRI_TITLE] Title" +msgstr "Title" + +# steps/triggersBefore_List.xml?CONDITION +# steps/triggersBefore_List.xml +#: link - CONDITION +msgid "[steps/triggersBefore_List.xml?CONDITION]" +msgstr "" + +# steps/triggersBefore_List.xml?UP +# steps/triggersBefore_List.xml +#: link - UP +msgid "[steps/triggersBefore_List.xml?UP]" +msgstr "" + +# steps/triggersBefore_List.xml?DOWN +# steps/triggersBefore_List.xml +#: link - DOWN +msgid "[steps/triggersBefore_List.xml?DOWN]" +msgstr "" + +# steps/triggersBefore_List.xml?DELETE +# steps/triggersBefore_List.xml +#: link - DELETE +msgid "[steps/triggersBefore_List.xml?DELETE]" +msgstr "" + +# steps/triggersBefore_Options.xml?MNU_ADD +# steps/triggersBefore_Options.xml +#: link - MNU_ADD +msgid "[steps/triggersBefore_Options.xml?MNU_ADD] Add" +msgstr "Add" + +# steps/triggersCondition_Edit.xml?ST_CONDITION +# steps/triggersCondition_Edit.xml +#: textareapm - ST_CONDITION +msgid "[steps/triggersCondition_Edit.xml?ST_CONDITION] Condition" +msgstr "Condition" + +# steps/triggersCondition_Edit.xml?SAVE +# steps/triggersCondition_Edit.xml +#: button - SAVE +msgid "[steps/triggersCondition_Edit.xml?SAVE] Save" +msgstr "Save" + +# steps/triggers_Assign.xml?TITLE +# steps/triggers_Assign.xml +#: title - TITLE +msgid "[steps/triggers_Assign.xml?TITLE] Available Triggers" +msgstr "Available Triggers" + +# steps/triggers_Assign.xml?TRI_UID +# steps/triggers_Assign.xml +#: dropdown - TRI_UID +msgid "[steps/triggers_Assign.xml?TRI_UID] Triggers" +msgstr "Triggers" + +# steps/triggers_Assign.xml?ST_CONDITION +# steps/triggers_Assign.xml +#: textareapm - ST_CONDITION +msgid "[steps/triggers_Assign.xml?ST_CONDITION] Condition" +msgstr "Condition" + +# steps/triggers_Assign.xml?ASSIGN +# steps/triggers_Assign.xml +#: button - ASSIGN +msgid "[steps/triggers_Assign.xml?ASSIGN] Assign" +msgstr "Assign" + +# steps/triggers_NoAssign.xml?MESSAGE +# steps/triggers_NoAssign.xml +#: subtitle - MESSAGE +msgid "All the triggers available were assigned!" +msgstr "All the triggers available were assigned!" + +# steps/triggers_NoAssign.xml?ClOSE +# steps/triggers_NoAssign.xml +#: button - ClOSE +msgid "[steps/triggers_NoAssign.xml?ClOSE] Close" +msgstr "Close" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE +msgid "Case to be assigned by" +msgstr "Case to be assigned by" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-BALANCED +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE - BALANCED +msgid "[tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-BALANCED]" +msgstr "Cyclical Assignment" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-MANUAL +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE - MANUAL +msgid "[tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-MANUAL]" +msgstr "Manual Assignment" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-EVALUATE +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE - EVALUATE +msgid "[tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-EVALUATE]" +msgstr "Value Based Assignment" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-REPORT_TO +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE - REPORT_TO +msgid "[tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-REPORT_TO]" +msgstr "Reports to" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-SELF_SERVICE +# tasks/tasks_AssignmentRules.xml +#: radiogroup - TAS_ASSIGN_TYPE - SELF_SERVICE +msgid "[tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_TYPE-SELF_SERVICE]" +msgstr "Self Service" + +# tasks/tasks_AssignmentRules.xml?TAS_ASSIGN_VARIABLE +# tasks/tasks_AssignmentRules.xml +#: textpm - TAS_ASSIGN_VARIABLE +msgid "Variable for Value Based Assignment" +msgstr "Variable for Value Based Assignment" + +# tasks/tasks_Definition.xml?TAS_TITLE +# tasks/tasks_Definition.xml +#: text - TAS_TITLE +msgid "[tasks/tasks_Definition.xml?TAS_TITLE] Title" +msgstr "Title" + +# tasks/tasks_Definition.xml?TAS_DESCRIPTION +# tasks/tasks_Definition.xml +#: textarea - TAS_DESCRIPTION +msgid "[tasks/tasks_Definition.xml?TAS_DESCRIPTION] Description" +msgstr "Description" + +# tasks/tasks_Definition.xml?TAS_PRIORITY_VARIABLE +# tasks/tasks_Definition.xml +#: textpm - TAS_PRIORITY_VARIABLE +msgid "Variable for Case priority" +msgstr "Variable for Case priority" + +# tasks/tasks_Definition.xml?TAS_START +# tasks/tasks_Definition.xml +#: checkbox - TAS_START +msgid "Starting task" +msgstr "Starting task" + +# tasks/tasks_Labels.xml?TAS_DEF_TITLE +# tasks/tasks_Labels.xml +#: textareapm - TAS_DEF_TITLE +msgid "[tasks/tasks_Labels.xml?TAS_DEF_TITLE] Case Title" +msgstr "Case Title" + +# tasks/tasks_Labels.xml?TAS_DEF_DESCRIPTION +# tasks/tasks_Labels.xml +#: textareapm - TAS_DEF_DESCRIPTION +msgid "Case Description" +msgstr "Case Description" + +# tasks/tasks_Notifications.xml?SEND_EMAIL +# tasks/tasks_Notifications.xml +#: checkbox - SEND_EMAIL +msgid "After routing notify the next assigned user(s)." +msgstr "After routing notify the next assigned user(s)." + +# tasks/tasks_Notifications.xml?TAS_DEF_MESSAGE +# tasks/tasks_Notifications.xml +#: textareapm - TAS_DEF_MESSAGE +msgid "[tasks/tasks_Notifications.xml?TAS_DEF_MESSAGE] Message" +msgstr "Message" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP +msgid "Set task performer as" +msgstr "Set task performer as" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-'' +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - '' +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-'']" +msgstr "(No ownership changes)" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-1 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 1 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-1]" +msgstr "First case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-2 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 2 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-2]" +msgstr "Second case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-3 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 3 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-3]" +msgstr "Third case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-4 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 4 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-4]" +msgstr "Fourth case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-5 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 5 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-5]" +msgstr "Fifth case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-6 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 6 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-6]" +msgstr "Sixth case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-7 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 7 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-7]" +msgstr "Seventh case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-8 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 8 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-8]" +msgstr "Eighth case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-9 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 9 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-9]" +msgstr "Ninth case owner" + +# tasks/tasks_Owner.xml?TAS_OWNER_APP-10 +# tasks/tasks_Owner.xml +#: dropdown - TAS_OWNER_APP - 10 +msgid "[tasks/tasks_Owner.xml?TAS_OWNER_APP-10]" +msgstr "Tenth case owner" + +# tasks/tasks_Permissions.xml?TAS_SUBTITLE1 +# tasks/tasks_Permissions.xml +#: subtitle - TAS_SUBTITLE1 +msgid "Exceptions Handling" +msgstr "Exceptions Handling" + +# tasks/tasks_Permissions.xml?TAS_TYPE +# tasks/tasks_Permissions.xml +#: checkbox - TAS_TYPE +msgid "Allow arbitrary transfer (Ad hoc)" +msgstr "Allow arbitrary transfer (Ad hoc)" + +# tasks/tasks_TimingControl.xml?TAS_DURATION +# tasks/tasks_TimingControl.xml +#: text - TAS_DURATION +msgid "Task duration" +msgstr "Task duration" + +# tasks/tasks_TimingControl.xml?TAS_TIMEUNIT +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TIMEUNIT +msgid "Time unit" +msgstr "Time unit" + +# tasks/tasks_TimingControl.xml?TAS_TIMEUNIT-HOURS +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TIMEUNIT - HOURS +msgid "[tasks/tasks_TimingControl.xml?TAS_TIMEUNIT-HOURS]" +msgstr "Hours" + +# tasks/tasks_TimingControl.xml?TAS_TIMEUNIT-DAYS +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TIMEUNIT - DAYS +msgid "[tasks/tasks_TimingControl.xml?TAS_TIMEUNIT-DAYS]" +msgstr "Days" + +# tasks/tasks_TimingControl.xml?TAS_TYPE_DAY +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TYPE_DAY +msgid "Count days by" +msgstr "Count days by" + +# tasks/tasks_TimingControl.xml?TAS_TYPE_DAY-1 +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TYPE_DAY - 1 +msgid "[tasks/tasks_TimingControl.xml?TAS_TYPE_DAY-1]" +msgstr "Work Days" + +# tasks/tasks_TimingControl.xml?TAS_TYPE_DAY-2 +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_TYPE_DAY - 2 +msgid "[tasks/tasks_TimingControl.xml?TAS_TYPE_DAY-2]" +msgstr "Calendar Days" + +# tasks/tasks_TimingControl.xml?TAS_CALENDAR +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_CALENDAR +msgid "[tasks/tasks_TimingControl.xml?TAS_CALENDAR] Calendar" +msgstr "Calendar" + +# tasks/tasks_TimingControl.xml?TAS_CALENDAR-'' +# tasks/tasks_TimingControl.xml +#: dropdown - TAS_CALENDAR - '' +msgid "[tasks/tasks_TimingControl.xml?TAS_CALENDAR-'']" +msgstr "- None -" + +# tools/translationAdd.xml?titles +# tools/translationAdd.xml +#: title - titles +msgid "Insert Translation" +msgstr "Insert Translation" + +# tools/translationAdd.xml?trn_category +# tools/translationAdd.xml +#: dropdown - trn_category +msgid "category" +msgstr "category" + +# tools/translationAdd.xml?trn_category-LABEL +# tools/translationAdd.xml +#: dropdown - trn_category - LABEL +msgid "[tools/translationAdd.xml?trn_category-LABEL]" +msgstr "Label" + +# tools/translationAdd.xml?trn_category-JAVASCRIPT +# tools/translationAdd.xml +#: dropdown - trn_category - JAVASCRIPT +msgid "[tools/translationAdd.xml?trn_category-JAVASCRIPT]" +msgstr "Javascript" + +# tools/translationAdd.xml?trn_id +# tools/translationAdd.xml +#: text - trn_id +msgid "Id" +msgstr "Id" + +# tools/translationAdd.xml?trn_value +# tools/translationAdd.xml +#: textarea - trn_value +msgid "value" +msgstr "value" + +# tools/translationAdd.xml?rowsJS +# tools/translationAdd.xml +#: submit - rowsJS +msgid "[tools/translationAdd.xml?rowsJS] save" +msgstr "save" + +# tools/translationsList.xml?TRN_CATEGORY +# tools/translationsList.xml +#: text - TRN_CATEGORY +msgid "[tools/translationsList.xml?TRN_CATEGORY] Category" +msgstr "Category" + +# tools/translationsList.xml?TRN_ID +# tools/translationsList.xml +#: text - TRN_ID +msgid "[tools/translationsList.xml?TRN_ID] Id" +msgstr "Id" + +# tools/translationsList.xml?TRN_VALUE +# tools/translationsList.xml +#: text - TRN_VALUE +msgid "[tools/translationsList.xml?TRN_VALUE] Value" +msgstr "Value" + +# tools/translationsList.xml?LINK +# tools/translationsList.xml +#: link - LINK +msgid "[tools/translationsList.xml?LINK] Edit" +msgstr "Edit" + +# tools/translationsList.xml?LINK2 +# tools/translationsList.xml +#: link - LINK2 +msgid "[tools/translationsList.xml?LINK2] Delete" +msgstr "Delete" + +# tools/updateTranslation.xml?titles +# tools/updateTranslation.xml +#: title - titles +msgid "UpdateTranslation" +msgstr "UpdateTranslation" + +# tools/updateTranslation.xml?cacheFile +# tools/updateTranslation.xml +#: text - cacheFile +msgid "file" +msgstr "file" + +# tools/updateTranslation.xml?rows +# tools/updateTranslation.xml +#: text - rows +msgid "rows" +msgstr "rows" + +# tools/updateTranslation.xml?titles2 +# tools/updateTranslation.xml +#: title - titles2 +msgid "JavaScript Update Translation" +msgstr "JavaScript Update Translation" + +# tools/updateTranslation.xml?cacheFileJS +# tools/updateTranslation.xml +#: text - cacheFileJS +msgid "[tools/updateTranslation.xml?cacheFileJS] file" +msgstr "file" + +# tools/updateTranslation.xml?rowsJS +# tools/updateTranslation.xml +#: text - rowsJS +msgid "[tools/updateTranslation.xml?rowsJS] rows" +msgstr "rows" + +# tracker/login.xml?TITLE +# tracker/login.xml +#: title - TITLE +msgid "CASE TRACKER" +msgstr "CASE TRACKER" + +# tracker/login.xml?CASE +# tracker/login.xml +#: text - CASE +msgid "Case Code" +msgstr "Case Code" + +# tracker/login.xml?PIN +# tracker/login.xml +#: password - PIN +msgid "Pin" +msgstr "Pin" + +# tracker/login.xml?BSUBMIT +# tracker/login.xml +#: submit - BSUBMIT +msgid "Enter" +msgstr "Enter" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TITLE +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: text - OBJECT_TITLE +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TITLE] Title" +msgstr "Title" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: dropdown - OBJECT_TYPE +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE] Type" +msgstr "Type" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-DYNAFORM +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: dropdown - OBJECT_TYPE - DYNAFORM +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-DYNAFORM]" +msgstr "Dynaform" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-INPUT_DOCUMENT +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: dropdown - OBJECT_TYPE - INPUT_DOCUMENT +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-INPUT_DOCUMENT]" +msgstr "Input Document" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-OUTPUT_DOCUMENT +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: dropdown - OBJECT_TYPE - OUTPUT_DOCUMENT +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?OBJECT_TYPE-OUTPUT_DOCUMENT]" +msgstr "Output Document" + +# tracker/tracker_AvailableCaseTrackerObjects.xml?ASSIGN +# tracker/tracker_AvailableCaseTrackerObjects.xml +#: link - ASSIGN +msgid "[tracker/tracker_AvailableCaseTrackerObjects.xml?ASSIGN]" +msgstr "" + +# tracker/tracker_AvailableStageTasks.xml?TAS_TITLE +# tracker/tracker_AvailableStageTasks.xml +#: text - TAS_TITLE +msgid "[tracker/tracker_AvailableStageTasks.xml?TAS_TITLE] Title" +msgstr "Title" + +# tracker/tracker_AvailableStageTasks.xml?ASSIGN +# tracker/tracker_AvailableStageTasks.xml +#: link - ASSIGN +msgid "[tracker/tracker_AvailableStageTasks.xml?ASSIGN]" +msgstr "" + +# tracker/tracker_ConditionsEdit.xml?CTO_CONDITION +# tracker/tracker_ConditionsEdit.xml +#: textareapm - CTO_CONDITION +msgid "[tracker/tracker_ConditionsEdit.xml?CTO_CONDITION] Condition" +msgstr "Condition" + +# tracker/tracker_ConditionsEdit.xml?SAVE +# tracker/tracker_ConditionsEdit.xml +#: button - SAVE +msgid "[tracker/tracker_ConditionsEdit.xml?SAVE] Save" +msgstr "Save" + +# tracker/tracker_Configuration.xml?CT_MAP_TYPE +# tracker/tracker_Configuration.xml +#: dropdown - CT_MAP_TYPE +msgid "Map type" +msgstr "Map type" + +# tracker/tracker_Configuration.xml?CT_MAP_TYPE-NONE +# tracker/tracker_Configuration.xml +#: dropdown - CT_MAP_TYPE - NONE +msgid "[tracker/tracker_Configuration.xml?CT_MAP_TYPE-NONE]" +msgstr "None" + +# tracker/tracker_Configuration.xml?CT_MAP_TYPE-PROCESSMAP +# tracker/tracker_Configuration.xml +#: dropdown - CT_MAP_TYPE - PROCESSMAP +msgid "[tracker/tracker_Configuration.xml?CT_MAP_TYPE-PROCESSMAP]" +msgstr "Process Map" + +# tracker/tracker_Configuration.xml?CT_MAP_TYPE-STAGES +# tracker/tracker_Configuration.xml +#: dropdown - CT_MAP_TYPE - STAGES +msgid "[tracker/tracker_Configuration.xml?CT_MAP_TYPE-STAGES]" +msgstr "Stages Map" + +# tracker/tracker_Configuration.xml?CT_STAGES_MAP_EDIT +# tracker/tracker_Configuration.xml +#: link - CT_STAGES_MAP_EDIT +msgid "[tracker/tracker_Configuration.xml?CT_STAGES_MAP_EDIT] Edit" +msgstr "Edit" + +# tracker/tracker_Configuration.xml?CT_DERIVATION_HISTORY +# tracker/tracker_Configuration.xml +#: checkbox - CT_DERIVATION_HISTORY +msgid "Derivation History" +msgstr "Derivation History" + +# tracker/tracker_Configuration.xml?CT_MESSAGE_HISTORY +# tracker/tracker_Configuration.xml +#: checkbox - CT_MESSAGE_HISTORY +msgid "[tracker/tracker_Configuration.xml?CT_MESSAGE_HISTORY] Messages History" +msgstr "Messages History" + +# tracker/tracker_Configuration.xml?BTN_CANCEL +# tracker/tracker_Configuration.xml +#: button - BTN_CANCEL +msgid "[tracker/tracker_Configuration.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# tracker/tracker_Configuration.xml?SAVE +# tracker/tracker_Configuration.xml +#: button - SAVE +msgid "[tracker/tracker_Configuration.xml?SAVE] Save" +msgstr "Save" + +# tracker/tracker_DynaDocs.xml?CTO_TITLE +# tracker/tracker_DynaDocs.xml +#: text - CTO_TITLE +msgid "[tracker/tracker_DynaDocs.xml?CTO_TITLE] Title" +msgstr "Title" + +# tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ +# tracker/tracker_DynaDocs.xml +#: dropdown - CTO_TYPE_OBJ +msgid "[tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ] Type" +msgstr "Type" + +# tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-DYNAFORM +# tracker/tracker_DynaDocs.xml +#: dropdown - CTO_TYPE_OBJ - DYNAFORM +msgid "[tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-DYNAFORM]" +msgstr "Form" + +# tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-INPUT_DOCUMENT +# tracker/tracker_DynaDocs.xml +#: dropdown - CTO_TYPE_OBJ - INPUT_DOCUMENT +msgid "[tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-INPUT_DOCUMENT]" +msgstr "Document" + +# tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-OUTPUT_DOCUMENT +# tracker/tracker_DynaDocs.xml +#: dropdown - CTO_TYPE_OBJ - OUTPUT_DOCUMENT +msgid "[tracker/tracker_DynaDocs.xml?CTO_TYPE_OBJ-OUTPUT_DOCUMENT]" +msgstr "Document" + +# tracker/tracker_DynaDocs.xml?CTO_VIEW +# tracker/tracker_DynaDocs.xml +#: link - CTO_VIEW +msgid "[tracker/tracker_DynaDocs.xml?CTO_VIEW]" +msgstr "" + +# tracker/tracker_Inputdocs.xml?TITLE +# tracker/tracker_Inputdocs.xml +#: text - TITLE +msgid "Filename/Comments" +msgstr "Filename/Comments" + +# tracker/tracker_Inputdocs.xml?VIEW +# tracker/tracker_Inputdocs.xml +#: link - VIEW +msgid "[tracker/tracker_Inputdocs.xml?VIEW]" +msgstr "" + +# tracker/tracker_Messages.xml?APP_MSG_DATE +# tracker/tracker_Messages.xml +#: text - APP_MSG_DATE +msgid "[tracker/tracker_Messages.xml?APP_MSG_DATE] DATE" +msgstr "DATE" + +# tracker/tracker_Messages.xml?APP_MSG_SUBJECT +# tracker/tracker_Messages.xml +#: text - APP_MSG_SUBJECT +msgid "[tracker/tracker_Messages.xml?APP_MSG_SUBJECT] SUBJECT" +msgstr "SUBJECT" + +# tracker/tracker_Messages.xml?APP_MSG_FROM +# tracker/tracker_Messages.xml +#: text - APP_MSG_FROM +msgid "[tracker/tracker_Messages.xml?APP_MSG_FROM] FROM" +msgstr "FROM" + +# tracker/tracker_Messages.xml?APP_MSG_TO +# tracker/tracker_Messages.xml +#: text - APP_MSG_TO +msgid "[tracker/tracker_Messages.xml?APP_MSG_TO] TO" +msgstr "TO" + +# tracker/tracker_Messages.xml?VIEW +# tracker/tracker_Messages.xml +#: link - VIEW +msgid "[tracker/tracker_Messages.xml?VIEW]" +msgstr "" + +# tracker/tracker_MessagesView.xml?title +# tracker/tracker_MessagesView.xml +#: title - title +msgid "[tracker/tracker_MessagesView.xml?title] MESSAGE" +msgstr "MESSAGE" + +# tracker/tracker_MessagesView.xml?APP_MSG_SUBJECT +# tracker/tracker_MessagesView.xml +#: text - APP_MSG_SUBJECT +msgid "[tracker/tracker_MessagesView.xml?APP_MSG_SUBJECT] SUBJECT" +msgstr "SUBJECT" + +# tracker/tracker_MessagesView.xml?APP_MSG_FROM +# tracker/tracker_MessagesView.xml +#: text - APP_MSG_FROM +msgid "[tracker/tracker_MessagesView.xml?APP_MSG_FROM] FROM" +msgstr "FROM" + +# tracker/tracker_MessagesView.xml?APP_MSG_TO +# tracker/tracker_MessagesView.xml +#: text - APP_MSG_TO +msgid "[tracker/tracker_MessagesView.xml?APP_MSG_TO] TO" +msgstr "TO" + +# tracker/tracker_MessagesView.xml?APP_MSG_DATE +# tracker/tracker_MessagesView.xml +#: text - APP_MSG_DATE +msgid "[tracker/tracker_MessagesView.xml?APP_MSG_DATE] DATE" +msgstr "DATE" + +# tracker/tracker_MessagesView.xml?APP_MSG_BODY +# tracker/tracker_MessagesView.xml +#: text - APP_MSG_BODY +msgid "[tracker/tracker_MessagesView.xml?APP_MSG_BODY]" +msgstr "" + +# tracker/tracker_No.xml?MESSAGE +# tracker/tracker_No.xml +#: title - MESSAGE +msgid "It is not possible to see information related to this case. Please contact the System Administrator." +msgstr "It is not possible to see information related to this case. Please contact the System Administrator." + +# tracker/tracker_Outputdocs.xml?TITLE +# tracker/tracker_Outputdocs.xml +#: text - TITLE +msgid "[tracker/tracker_Outputdocs.xml?TITLE] Title" +msgstr "Title" + +# tracker/tracker_Outputdocs.xml?VIEW +# tracker/tracker_Outputdocs.xml +#: link - VIEW +msgid "[tracker/tracker_Outputdocs.xml?VIEW]" +msgstr "" + +# tracker/tracker_StageEdit.xml?TITLE1 +# tracker/tracker_StageEdit.xml +#: title - TITLE1 +msgid "Stage Information" +msgstr "Stage Information" + +# tracker/tracker_StageEdit.xml?STG_TITLE +# tracker/tracker_StageEdit.xml +#: text - STG_TITLE +msgid "[tracker/tracker_StageEdit.xml?STG_TITLE] Title" +msgstr "Title" + +# tracker/tracker_StageEdit.xml?SAVE +# tracker/tracker_StageEdit.xml +#: button - SAVE +msgid "[tracker/tracker_StageEdit.xml?SAVE] Save" +msgstr "Save" + +# tracker/tracker_StageTasks.xml?TAS_TITLE +# tracker/tracker_StageTasks.xml +#: text - TAS_TITLE +msgid "[tracker/tracker_StageTasks.xml?TAS_TITLE] Title" +msgstr "Title" + +# tracker/tracker_StageTasks.xml?REMOVE +# tracker/tracker_StageTasks.xml +#: link - REMOVE +msgid "[tracker/tracker_StageTasks.xml?REMOVE]" +msgstr "" + +# tracker/tracker_TasksOptions.xml?MNU_ASSIGN +# tracker/tracker_TasksOptions.xml +#: link - MNU_ASSIGN +msgid "[tracker/tracker_TasksOptions.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# tracker/tracker_TransferHistory.xml?TAS_TITLE +# tracker/tracker_TransferHistory.xml +#: text - TAS_TITLE +msgid "[tracker/tracker_TransferHistory.xml?TAS_TITLE] Task" +msgstr "Task" + +# tracker/tracker_TransferHistory.xml?USR_NAME +# tracker/tracker_TransferHistory.xml +#: text - USR_NAME +msgid "[tracker/tracker_TransferHistory.xml?USR_NAME] Delegated User" +msgstr "Delegated User" + +# tracker/tracker_TransferHistory.xml?DEL_DELEGATE_DATE +# tracker/tracker_TransferHistory.xml +#: date - DEL_DELEGATE_DATE +msgid "[tracker/tracker_TransferHistory.xml?DEL_DELEGATE_DATE] Task Transfer Date" +msgstr "Task Transfer Date" + +# tracker/tracker_TransferHistory.xml?DEL_INIT_DATE +# tracker/tracker_TransferHistory.xml +#: date - DEL_INIT_DATE +msgid "[tracker/tracker_TransferHistory.xml?DEL_INIT_DATE] Start Date" +msgstr "Start Date" + +# tracker/tracker_TransferHistory.xml?DEL_FINISH_DATE +# tracker/tracker_TransferHistory.xml +#: date - DEL_FINISH_DATE +msgid "[tracker/tracker_TransferHistory.xml?DEL_FINISH_DATE] End Date" +msgstr "End Date" + +# tracker/tracker_TransferHistory.xml?APP_TYPE +# tracker/tracker_TransferHistory.xml +#: dropdown - APP_TYPE +msgid "[tracker/tracker_TransferHistory.xml?APP_TYPE] Action" +msgstr "Action" + +# tracker/tracker_TransferHistory.xml?APP_TYPE-PAUSE +# tracker/tracker_TransferHistory.xml +#: dropdown - APP_TYPE - PAUSE +msgid "[tracker/tracker_TransferHistory.xml?APP_TYPE-PAUSE]" +msgstr "Paused" + +# tracker/tracker_TransferHistory.xml?APP_TYPE-CANCEL +# tracker/tracker_TransferHistory.xml +#: dropdown - APP_TYPE - CANCEL +msgid "[tracker/tracker_TransferHistory.xml?APP_TYPE-CANCEL]" +msgstr "Cancelled" + +# tracker/tracker_TransferHistory.xml?APP_TYPE-'' +# tracker/tracker_TransferHistory.xml +#: dropdown - APP_TYPE - '' +msgid "[tracker/tracker_TransferHistory.xml?APP_TYPE-'']" +msgstr "Derivated" + +# tracker/tracker_ViewAnyInputDocument.xml?FILENAME +# tracker/tracker_ViewAnyInputDocument.xml +#: caption - FILENAME +msgid "[tracker/tracker_ViewAnyInputDocument.xml?FILENAME] Filename" +msgstr "Filename" + +# tracker/tracker_ViewAnyInputDocument.xml?APP_DOC_CREATE_DATE +# tracker/tracker_ViewAnyInputDocument.xml +#: date - APP_DOC_CREATE_DATE +msgid "[tracker/tracker_ViewAnyInputDocument.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# tracker/tracker_ViewAnyInputDocument.xml?APP_DOC_FILENAME +# tracker/tracker_ViewAnyInputDocument.xml +#: link - APP_DOC_FILENAME +msgid "[tracker/tracker_ViewAnyInputDocument.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_TITLE +# tracker/tracker_ViewAnyInputDocument1.xml +#: caption - INP_DOC_TITLE +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_DESCRIPTION +# tracker/tracker_ViewAnyInputDocument1.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPY +# tracker/tracker_ViewAnyInputDocument1.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# tracker/tracker_ViewAnyInputDocument1.xml?APP_DOC_CREATE_DATE +# tracker/tracker_ViewAnyInputDocument1.xml +#: date - APP_DOC_CREATE_DATE +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# tracker/tracker_ViewAnyInputDocument1.xml?APP_DOC_FILENAME +# tracker/tracker_ViewAnyInputDocument1.xml +#: link - APP_DOC_FILENAME +msgid "[tracker/tracker_ViewAnyInputDocument1.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_TITLE +# tracker/tracker_ViewAnyInputDocument2.xml +#: caption - INP_DOC_TITLE +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_DESCRIPTION +# tracker/tracker_ViewAnyInputDocument2.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPY +# tracker/tracker_ViewAnyInputDocument2.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# tracker/tracker_ViewAnyInputDocument2.xml?APP_DOC_CREATE_DATE +# tracker/tracker_ViewAnyInputDocument2.xml +#: date - APP_DOC_CREATE_DATE +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# tracker/tracker_ViewAnyInputDocument2.xml?APP_DOC_COMMENT +# tracker/tracker_ViewAnyInputDocument2.xml +#: caption - APP_DOC_COMMENT +msgid "[tracker/tracker_ViewAnyInputDocument2.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_TITLE +# tracker/tracker_ViewAnyInputDocument3.xml +#: caption - INP_DOC_TITLE +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_TITLE] Title" +msgstr "Title" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_DESCRIPTION +# tracker/tracker_ViewAnyInputDocument3.xml +#: caption - INP_DOC_DESCRIPTION +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_DESCRIPTION] Description" +msgstr "Description" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED] Document Type" +msgstr "Document Type" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VIRTUAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VIRTUAL]" +msgstr "Digital" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - REAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-REAL]" +msgstr "Printed" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_FORM_NEEDED - VREAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_FORM_NEEDED-VREAL]" +msgstr "Digital/Printed" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL] Format" +msgstr "Format" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - ORIGINAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-ORIGINAL]" +msgstr "Original" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPYLEGAL +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPYLEGAL]" +msgstr "Legal Copy" + +# tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPY +# tracker/tracker_ViewAnyInputDocument3.xml +#: dropdown - INP_DOC_ORIGINAL - COPY +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?INP_DOC_ORIGINAL-COPY]" +msgstr "Copy" + +# tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_CREATE_DATE +# tracker/tracker_ViewAnyInputDocument3.xml +#: date - APP_DOC_CREATE_DATE +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_CREATE_DATE] Created Date" +msgstr "Created Date" + +# tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_COMMENT +# tracker/tracker_ViewAnyInputDocument3.xml +#: caption - APP_DOC_COMMENT +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_COMMENT] Comments" +msgstr "Comments" + +# tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_FILENAME +# tracker/tracker_ViewAnyInputDocument3.xml +#: link - APP_DOC_FILENAME +msgid "[tracker/tracker_ViewAnyInputDocument3.xml?APP_DOC_FILENAME] File" +msgstr "File" + +# tracker/tracker_ViewAnyOutputDocument.xml?OUT_DOC_TITLE +# tracker/tracker_ViewAnyOutputDocument.xml +#: caption - OUT_DOC_TITLE +msgid "[tracker/tracker_ViewAnyOutputDocument.xml?OUT_DOC_TITLE] Output document" +msgstr "Output document" + +# tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_CREATE_DATE +# tracker/tracker_ViewAnyOutputDocument.xml +#: caption - APP_DOC_CREATE_DATE +msgid "[tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_CREATE_DATE] Create Date" +msgstr "Create Date" + +# tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_FILENAME1 +# tracker/tracker_ViewAnyOutputDocument.xml +#: link - APP_DOC_FILENAME1 +msgid "[tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_FILENAME1] File (.doc)" +msgstr "File (.doc)" + +# tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_FILENAME2 +# tracker/tracker_ViewAnyOutputDocument.xml +#: link - APP_DOC_FILENAME2 +msgid "[tracker/tracker_ViewAnyOutputDocument.xml?APP_DOC_FILENAME2] File (.pdf)" +msgstr "File (.pdf)" + +# tracker/tracker_back.xml?backs +# tracker/tracker_back.xml +#: link - backs +msgid "[tracker/tracker_back.xml?backs] Back" +msgstr "Back" + +# tracker/tracker_objectsList.xml?CTO_TITLE +# tracker/tracker_objectsList.xml +#: text - CTO_TITLE +msgid "[tracker/tracker_objectsList.xml?CTO_TITLE] Title" +msgstr "Title" + +# tracker/tracker_objectsList.xml?CTO_TYPE_OBJ +# tracker/tracker_objectsList.xml +#: text - CTO_TYPE_OBJ +msgid "[tracker/tracker_objectsList.xml?CTO_TYPE_OBJ] Type" +msgstr "Type" + +# tracker/tracker_objectsList.xml?CONDITION +# tracker/tracker_objectsList.xml +#: link - CONDITION +msgid "[tracker/tracker_objectsList.xml?CONDITION]" +msgstr "" + +# tracker/tracker_objectsList.xml?UP +# tracker/tracker_objectsList.xml +#: link - UP +msgid "[tracker/tracker_objectsList.xml?UP]" +msgstr "" + +# tracker/tracker_objectsList.xml?DOWN +# tracker/tracker_objectsList.xml +#: link - DOWN +msgid "[tracker/tracker_objectsList.xml?DOWN]" +msgstr "" + +# tracker/tracker_objectsList.xml?REMOVE +# tracker/tracker_objectsList.xml +#: link - REMOVE +msgid "[tracker/tracker_objectsList.xml?REMOVE]" +msgstr "" + +# tracker/tracker_objectsOptions.xml?MNU_ASSIGN +# tracker/tracker_objectsOptions.xml +#: link - MNU_ASSIGN +msgid "[tracker/tracker_objectsOptions.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# triggers/dynavars.xml?variable_label +# triggers/dynavars.xml +#: text - variable_label +msgid "Variable" +msgstr "Variable" + +# triggers/dynavars.xml?label +# triggers/dynavars.xml +#: text - label +msgid "[triggers/dynavars.xml?label] Label" +msgstr "Label" + +# triggers/triggersCustom.xml?TITLE +# triggers/triggersCustom.xml +#: title - TITLE +msgid "Trigger Information" +msgstr "Trigger Information" + +# triggers/triggersCustom.xml?TRI_TITLE +# triggers/triggersCustom.xml +#: text - TRI_TITLE +msgid "[triggers/triggersCustom.xml?TRI_TITLE] Title" +msgstr "Title" + +# triggers/triggersCustom.xml?TRI_DESCRIPTION +# triggers/triggersCustom.xml +#: textarea - TRI_DESCRIPTION +msgid "[triggers/triggersCustom.xml?TRI_DESCRIPTION] Description" +msgstr "Description" + +# triggers/triggersCustom.xml?TRI_WEBBOT +# triggers/triggersCustom.xml +#: textareapm - TRI_WEBBOT +msgid "[triggers/triggersCustom.xml?TRI_WEBBOT]" +msgstr "" + +# triggers/triggersCustom.xml?SAVE +# triggers/triggersCustom.xml +#: button - SAVE +msgid "[triggers/triggersCustom.xml?SAVE] Save" +msgstr "Save" + +# triggers/triggersCustom.xml?BTN_CANCEL +# triggers/triggersCustom.xml +#: button - BTN_CANCEL +msgid "[triggers/triggersCustom.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# triggers/triggersNarrowEdit.xml?TITLE +# triggers/triggersNarrowEdit.xml +#: title - TITLE +msgid "Trigger Script" +msgstr "Trigger Script" + +# triggers/triggersNarrowEdit.xml?TRI_WEBBOT +# triggers/triggersNarrowEdit.xml +#: textareapm - TRI_WEBBOT +msgid "[triggers/triggersNarrowEdit.xml?TRI_WEBBOT]" +msgstr "" + +# triggers/triggersNarrowEdit.xml?BTN_CANCEL +# triggers/triggersNarrowEdit.xml +#: button - BTN_CANCEL +msgid "[triggers/triggersNarrowEdit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# triggers/triggersNarrowEdit.xml?SAVE +# triggers/triggersNarrowEdit.xml +#: button - SAVE +msgid "[triggers/triggersNarrowEdit.xml?SAVE] Save" +msgstr "Save" + +# triggers/triggersProperties.xml?TITLE +# triggers/triggersProperties.xml +#: title - TITLE +msgid "[triggers/triggersProperties.xml?TITLE] Trigger Information" +msgstr "Trigger Information" + +# triggers/triggersProperties.xml?TRI_TITLE +# triggers/triggersProperties.xml +#: text - TRI_TITLE +msgid "[triggers/triggersProperties.xml?TRI_TITLE] Title" +msgstr "Title" + +# triggers/triggersProperties.xml?TRI_DESCRIPTION +# triggers/triggersProperties.xml +#: textarea - TRI_DESCRIPTION +msgid "[triggers/triggersProperties.xml?TRI_DESCRIPTION] Description" +msgstr "Description" + +# triggers/triggersProperties.xml?BTN_CANCEL +# triggers/triggersProperties.xml +#: button - BTN_CANCEL +msgid "[triggers/triggersProperties.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# triggers/triggersProperties.xml?SAVE +# triggers/triggersProperties.xml +#: button - SAVE +msgid "[triggers/triggersProperties.xml?SAVE] Save" +msgstr "Save" + +# triggers/triggers_Edit.xml?TRI_WEBBOT +# triggers/triggers_Edit.xml +#: textareapm - TRI_WEBBOT +msgid "[triggers/triggers_Edit.xml?TRI_WEBBOT]" +msgstr "" + +# triggers/triggers_Edit.xml?BTN_CANCEL +# triggers/triggers_Edit.xml +#: button - BTN_CANCEL +msgid "[triggers/triggers_Edit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# triggers/triggers_Edit.xml?SAVE +# triggers/triggers_Edit.xml +#: button - SAVE +msgid "[triggers/triggers_Edit.xml?SAVE] Save" +msgstr "Save" + +# triggers/triggers_Options.xml?MNU_ADD +# triggers/triggers_Options.xml +#: link - MNU_ADD +msgid "[triggers/triggers_Options.xml?MNU_ADD] New" +msgstr "New" + +# triggers/triggers_ShortList.xml?TRI_TITLE +# triggers/triggers_ShortList.xml +#: text - TRI_TITLE +msgid "[triggers/triggers_ShortList.xml?TRI_TITLE] Title" +msgstr "Title" + +# triggers/triggers_ShortList.xml?EDIT +# triggers/triggers_ShortList.xml +#: link - EDIT +msgid "[triggers/triggers_ShortList.xml?EDIT]" +msgstr "" + +# triggers/triggers_ShortList.xml?PROPERTIES +# triggers/triggers_ShortList.xml +#: link - PROPERTIES +msgid "[triggers/triggers_ShortList.xml?PROPERTIES]" +msgstr "" + +# triggers/triggers_ShortList.xml?DELETE +# triggers/triggers_ShortList.xml +#: link - DELETE +msgid "[triggers/triggers_ShortList.xml?DELETE]" +msgstr "" + +# triggers/triggers_ShortList.xml?GET_UID +# triggers/triggers_ShortList.xml +#: link - GET_UID +msgid "[triggers/triggers_ShortList.xml?GET_UID]" +msgstr "" + +# triggers/triggers_ShortList.xml?SEARCH +# triggers/triggers_ShortList.xml +#: button - SEARCH +msgid "[triggers/triggers_ShortList.xml?SEARCH] Apply Filter" +msgstr "Apply Filter" + +# triggers/wizardOptions.xml?NAME +# triggers/wizardOptions.xml +#: text - NAME +msgid "Param Name" +msgstr "Param Name" + +# triggers/wizardOptions.xml?VALUE +# triggers/wizardOptions.xml +#: text - VALUE +msgid "Param Value" +msgstr "Param Value" + +# users/myInfo.xml?TITLEADD +# users/myInfo.xml +#: title - TITLEADD +msgid "Profile" +msgstr "Profile" + +# users/myInfo.xml?USR_PHOTO +# users/myInfo.xml +#: file - USR_PHOTO +msgid "Photo" +msgstr "Photo" + +# users/myInfo.xml?USR_RESUME +# users/myInfo.xml +#: file - USR_RESUME +msgid "[users/myInfo.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/myInfo.xml?TITLE9689 +# users/myInfo.xml +#: title - TITLE9689 +msgid "Personal Information" +msgstr "Personal Information" + +# users/myInfo.xml?USR_FIRSTNAME +# users/myInfo.xml +#: text - USR_FIRSTNAME +msgid "[users/myInfo.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/myInfo.xml?USR_LASTNAME +# users/myInfo.xml +#: text - USR_LASTNAME +msgid "[users/myInfo.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/myInfo.xml?USR_USERNAME +# users/myInfo.xml +#: text - USR_USERNAME +msgid "[users/myInfo.xml?USR_USERNAME] User ID" +msgstr "User ID" + +# users/myInfo.xml?USR_EMAIL +# users/myInfo.xml +#: text - USR_EMAIL +msgid "[users/myInfo.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/myInfo.xml?USR_ADDRESS +# users/myInfo.xml +#: textarea - USR_ADDRESS +msgid "Address" +msgstr "Address" + +# users/myInfo.xml?USR_ZIP_CODE +# users/myInfo.xml +#: text - USR_ZIP_CODE +msgid "Zip Code" +msgstr "Zip Code" + +# users/myInfo.xml?USR_COUNTRY +# users/myInfo.xml +#: dropdown - USR_COUNTRY +msgid "[users/myInfo.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/myInfo.xml?USR_COUNTRY-'' +# users/myInfo.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/myInfo.xml?USR_COUNTRY-'']" +msgstr "" + +# users/myInfo.xml?USR_CITY +# users/myInfo.xml +#: dropdown - USR_CITY +msgid "State or Region" +msgstr "State or Region" + +# users/myInfo.xml?USR_LOCATION +# users/myInfo.xml +#: dropdown - USR_LOCATION +msgid "Location" +msgstr "Location" + +# users/myInfo.xml?USR_PHONE +# users/myInfo.xml +#: text - USR_PHONE +msgid "Phone" +msgstr "Phone" + +# users/myInfo.xml?USR_POSITION +# users/myInfo.xml +#: text - USR_POSITION +msgid "Position" +msgstr "Position" + +# users/myInfo.xml?USR_DUE_DATE +# users/myInfo.xml +#: text - USR_DUE_DATE +msgid "Expiration Date" +msgstr "Expiration Date" + +# users/myInfo.xml?USR_STATUS +# users/myInfo.xml +#: dropdown - USR_STATUS +msgid "[users/myInfo.xml?USR_STATUS] Status" +msgstr "Status" + +# users/myInfo.xml?USR_STATUS-ACTIVE +# users/myInfo.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/myInfo.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/myInfo.xml?USR_STATUS-INACTIVE +# users/myInfo.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/myInfo.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/myInfo.xml?USR_STATUS-VACATION +# users/myInfo.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/myInfo.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/myInfo.xml?USR_ROLE +# users/myInfo.xml +#: dropdown - USR_ROLE +msgid "[users/myInfo.xml?USR_ROLE] Role" +msgstr "Role" + +# users/myInfo.xml?USR_REPORTS_TO +# users/myInfo.xml +#: caption - USR_REPORTS_TO +msgid "Reports to" +msgstr "Reports to" + +# users/myInfo.xml?USR_DEPARTMENT +# users/myInfo.xml +#: caption - USR_DEPARTMENT +msgid "[users/myInfo.xml?USR_DEPARTMENT] Department" +msgstr "Department" + +# users/myInfo.xml?TITLECHP +# users/myInfo.xml +#: title - TITLECHP +msgid "Change Password" +msgstr "Change Password" + +# users/myInfo.xml?USR_NEW_PASS +# users/myInfo.xml +#: password - USR_NEW_PASS +msgid "New Password" +msgstr "New Password" + +# users/myInfo.xml?USR_CNF_PASS +# users/myInfo.xml +#: password - USR_CNF_PASS +msgid "Confirm Password" +msgstr "Confirm Password" + +# users/myInfo.xml?TITLEPREF +# users/myInfo.xml +#: title - TITLEPREF +msgid "Preferences" +msgstr "Preferences" + +# users/myInfo.xml?PREF_DEFAULT_MENUSELECTED +# users/myInfo.xml +#: dropdown - PREF_DEFAULT_MENUSELECTED +msgid "Default Main Menu Option" +msgstr "Default Main Menu Option" + +# users/myInfo.xml?PREF_DEFAULT_CASES_MENUSELECTED +# users/myInfo.xml +#: dropdown - PREF_DEFAULT_CASES_MENUSELECTED +msgid "Default Cases Menu Option" +msgstr "Default Cases Menu Option" + +# users/myInfo.xml?SUBMIT3 +# users/myInfo.xml +#: button - SUBMIT3 +msgid "[users/myInfo.xml?SUBMIT3] Save" +msgstr "Save" + +# users/myInfo2.xml?TITLEADD +# users/myInfo2.xml +#: title - TITLEADD +msgid "[users/myInfo2.xml?TITLEADD] Profile" +msgstr "Profile" + +# users/myInfo2.xml?USR_PHOTO +# users/myInfo2.xml +#: image - USR_PHOTO +msgid "[users/myInfo2.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/myInfo2.xml?USR_RESUME +# users/myInfo2.xml +#: link - USR_RESUME +msgid "[users/myInfo2.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/myInfo2.xml?TITLE9689 +# users/myInfo2.xml +#: title - TITLE9689 +msgid "[users/myInfo2.xml?TITLE9689] Personal Information" +msgstr "Personal Information" + +# users/myInfo2.xml?USR_FIRSTNAME +# users/myInfo2.xml +#: text - USR_FIRSTNAME +msgid "[users/myInfo2.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/myInfo2.xml?USR_LASTNAME +# users/myInfo2.xml +#: text - USR_LASTNAME +msgid "[users/myInfo2.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/myInfo2.xml?USR_USERNAME +# users/myInfo2.xml +#: text - USR_USERNAME +msgid "[users/myInfo2.xml?USR_USERNAME] User ID" +msgstr "User ID" + +# users/myInfo2.xml?USR_EMAIL +# users/myInfo2.xml +#: text - USR_EMAIL +msgid "[users/myInfo2.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/myInfo2.xml?USR_ADDRESS +# users/myInfo2.xml +#: textarea - USR_ADDRESS +msgid "[users/myInfo2.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/myInfo2.xml?USR_ZIP_CODE +# users/myInfo2.xml +#: text - USR_ZIP_CODE +msgid "[users/myInfo2.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/myInfo2.xml?USR_COUNTRY +# users/myInfo2.xml +#: dropdown - USR_COUNTRY +msgid "[users/myInfo2.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/myInfo2.xml?USR_COUNTRY-'' +# users/myInfo2.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/myInfo2.xml?USR_COUNTRY-'']" +msgstr "" + +# users/myInfo2.xml?USR_CITY +# users/myInfo2.xml +#: dropdown - USR_CITY +msgid "[users/myInfo2.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/myInfo2.xml?USR_LOCATION +# users/myInfo2.xml +#: dropdown - USR_LOCATION +msgid "[users/myInfo2.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/myInfo2.xml?USR_PHONE +# users/myInfo2.xml +#: text - USR_PHONE +msgid "[users/myInfo2.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/myInfo2.xml?USR_POSITION +# users/myInfo2.xml +#: text - USR_POSITION +msgid "[users/myInfo2.xml?USR_POSITION] Position" +msgstr "Position" + +# users/myInfo2.xml?USR_DUE_DATE +# users/myInfo2.xml +#: text - USR_DUE_DATE +msgid "[users/myInfo2.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/myInfo2.xml?USR_STATUS +# users/myInfo2.xml +#: dropdown - USR_STATUS +msgid "[users/myInfo2.xml?USR_STATUS] Status" +msgstr "Status" + +# users/myInfo2.xml?USR_STATUS-ACTIVE +# users/myInfo2.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/myInfo2.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/myInfo2.xml?USR_STATUS-INACTIVE +# users/myInfo2.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/myInfo2.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/myInfo2.xml?USR_STATUS-VACATION +# users/myInfo2.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/myInfo2.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/myInfo2.xml?USR_ROLE +# users/myInfo2.xml +#: dropdown - USR_ROLE +msgid "[users/myInfo2.xml?USR_ROLE] Role" +msgstr "Role" + +# users/myInfo2.xml?USR_REPORTS_TO +# users/myInfo2.xml +#: caption - USR_REPORTS_TO +msgid "[users/myInfo2.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/myInfo2.xml?USR_DEPARTMENT +# users/myInfo2.xml +#: caption - USR_DEPARTMENT +msgid "[users/myInfo2.xml?USR_DEPARTMENT] Department" +msgstr "Department" + +# users/myInfo2.xml?TITLECHP +# users/myInfo2.xml +#: title - TITLECHP +msgid "[users/myInfo2.xml?TITLECHP] Change Password" +msgstr "Change Password" + +# users/myInfo2.xml?USR_NEW_PASS +# users/myInfo2.xml +#: password - USR_NEW_PASS +msgid "[users/myInfo2.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/myInfo2.xml?USR_CNF_PASS +# users/myInfo2.xml +#: password - USR_CNF_PASS +msgid "[users/myInfo2.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/myInfo2.xml?TITLEPREF +# users/myInfo2.xml +#: title - TITLEPREF +msgid "[users/myInfo2.xml?TITLEPREF] Preferences" +msgstr "Preferences" + +# users/myInfo2.xml?PREF_DEFAULT_LANG +# users/myInfo2.xml +#: dropdown - PREF_DEFAULT_LANG +msgid "Default languaje" +msgstr "Default languaje" + +# users/myInfo2.xml?PREF_DEFAULT_MENUSELECTED +# users/myInfo2.xml +#: dropdown - PREF_DEFAULT_MENUSELECTED +msgid "Default menu option" +msgstr "Default menu option" + +# users/myInfo2.xml?SUBMIT3 +# users/myInfo2.xml +#: button - SUBMIT3 +msgid "[users/myInfo2.xml?SUBMIT3] Save" +msgstr "Save" + +# users/myInfoOptions.xml?MNU_EDIT +# users/myInfoOptions.xml +#: link - MNU_EDIT +msgid "[users/myInfoOptions.xml?MNU_EDIT] Edit" +msgstr "Edit" + +# users/myInfoOptionsView.xml?MNU_EDIT +# users/myInfoOptionsView.xml +#: link - MNU_EDIT +msgid "[users/myInfoOptionsView.xml?MNU_EDIT] Cancel" +msgstr "Cancel" + +# users/myInfoView.xml?TITLEADD +# users/myInfoView.xml +#: title - TITLEADD +msgid "[users/myInfoView.xml?TITLEADD] Profile" +msgstr "Profile" + +# users/myInfoView.xml?USR_PHOTO +# users/myInfoView.xml +#: image - USR_PHOTO +msgid "[users/myInfoView.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/myInfoView.xml?USR_RESUME +# users/myInfoView.xml +#: link - USR_RESUME +msgid "[users/myInfoView.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/myInfoView.xml?TITLE9689 +# users/myInfoView.xml +#: title - TITLE9689 +msgid "[users/myInfoView.xml?TITLE9689] Personal Information" +msgstr "Personal Information" + +# users/myInfoView.xml?USR_FIRSTNAME +# users/myInfoView.xml +#: text - USR_FIRSTNAME +msgid "[users/myInfoView.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/myInfoView.xml?USR_LASTNAME +# users/myInfoView.xml +#: text - USR_LASTNAME +msgid "[users/myInfoView.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/myInfoView.xml?USR_USERNAME +# users/myInfoView.xml +#: text - USR_USERNAME +msgid "[users/myInfoView.xml?USR_USERNAME] User ID" +msgstr "User ID" + +# users/myInfoView.xml?USR_EMAIL +# users/myInfoView.xml +#: text - USR_EMAIL +msgid "[users/myInfoView.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/myInfoView.xml?USR_ADDRESS +# users/myInfoView.xml +#: textarea - USR_ADDRESS +msgid "[users/myInfoView.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/myInfoView.xml?USR_ZIP_CODE +# users/myInfoView.xml +#: text - USR_ZIP_CODE +msgid "[users/myInfoView.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/myInfoView.xml?USR_COUNTRY +# users/myInfoView.xml +#: dropdown - USR_COUNTRY +msgid "[users/myInfoView.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/myInfoView.xml?USR_COUNTRY-'' +# users/myInfoView.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/myInfoView.xml?USR_COUNTRY-'']" +msgstr "" + +# users/myInfoView.xml?USR_CITY +# users/myInfoView.xml +#: dropdown - USR_CITY +msgid "[users/myInfoView.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/myInfoView.xml?USR_LOCATION +# users/myInfoView.xml +#: dropdown - USR_LOCATION +msgid "[users/myInfoView.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/myInfoView.xml?USR_PHONE +# users/myInfoView.xml +#: text - USR_PHONE +msgid "[users/myInfoView.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/myInfoView.xml?USR_POSITION +# users/myInfoView.xml +#: text - USR_POSITION +msgid "[users/myInfoView.xml?USR_POSITION] Position" +msgstr "Position" + +# users/myInfoView.xml?USR_DUE_DATE +# users/myInfoView.xml +#: date - USR_DUE_DATE +msgid "[users/myInfoView.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/myInfoView.xml?USR_STATUS +# users/myInfoView.xml +#: dropdown - USR_STATUS +msgid "[users/myInfoView.xml?USR_STATUS] Status" +msgstr "Status" + +# users/myInfoView.xml?USR_STATUS-ACTIVE +# users/myInfoView.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/myInfoView.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/myInfoView.xml?USR_STATUS-INACTIVE +# users/myInfoView.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/myInfoView.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/myInfoView.xml?USR_STATUS-VACATION +# users/myInfoView.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/myInfoView.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/myInfoView.xml?USR_ROLE +# users/myInfoView.xml +#: dropdown - USR_ROLE +msgid "[users/myInfoView.xml?USR_ROLE] Role" +msgstr "Role" + +# users/myInfoView.xml?USR_REPORTS_TO +# users/myInfoView.xml +#: caption - USR_REPORTS_TO +msgid "[users/myInfoView.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/myInfoView.xml?USR_DEPARTMENT +# users/myInfoView.xml +#: caption - USR_DEPARTMENT +msgid "[users/myInfoView.xml?USR_DEPARTMENT] Department" +msgstr "Department" + +# users/myInfoView.xml?TITLECHP +# users/myInfoView.xml +#: title - TITLECHP +msgid "[users/myInfoView.xml?TITLECHP] Change Password" +msgstr "Change Password" + +# users/myInfoView.xml?USR_NEW_PASS +# users/myInfoView.xml +#: password - USR_NEW_PASS +msgid "[users/myInfoView.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/myInfoView.xml?USR_CNF_PASS +# users/myInfoView.xml +#: password - USR_CNF_PASS +msgid "[users/myInfoView.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/myInfoView.xml?TITLEPREF +# users/myInfoView.xml +#: title - TITLEPREF +msgid "[users/myInfoView.xml?TITLEPREF] Preferences" +msgstr "Preferences" + +# users/myInfoView.xml?PREF_DEFAULT_MENUSELECTED +# users/myInfoView.xml +#: dropdown - PREF_DEFAULT_MENUSELECTED +msgid "[users/myInfoView.xml?PREF_DEFAULT_MENUSELECTED] Default Main Menu Option" +msgstr "Default Main Menu Option" + +# users/myInfoView.xml?PREF_DEFAULT_CASES_MENUSELECTED +# users/myInfoView.xml +#: dropdown - PREF_DEFAULT_CASES_MENUSELECTED +msgid "[users/myInfoView.xml?PREF_DEFAULT_CASES_MENUSELECTED] Default Cases Menu Option" +msgstr "Default Cases Menu Option" + +# users/myInfoView.xml?SUBMIT3 +# users/myInfoView.xml +#: button - SUBMIT3 +msgid "[users/myInfoView.xml?SUBMIT3] Save" +msgstr "Save" + +# users/myInfoView2.xml?TITLEADD +# users/myInfoView2.xml +#: title - TITLEADD +msgid "[users/myInfoView2.xml?TITLEADD] Profile" +msgstr "Profile" + +# users/myInfoView2.xml?USR_PHOTO +# users/myInfoView2.xml +#: image - USR_PHOTO +msgid "[users/myInfoView2.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/myInfoView2.xml?USR_RESUME +# users/myInfoView2.xml +#: link - USR_RESUME +msgid "[users/myInfoView2.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/myInfoView2.xml?TITLE9689 +# users/myInfoView2.xml +#: title - TITLE9689 +msgid "[users/myInfoView2.xml?TITLE9689] Personal Information" +msgstr "Personal Information" + +# users/myInfoView2.xml?USR_FIRSTNAME +# users/myInfoView2.xml +#: text - USR_FIRSTNAME +msgid "[users/myInfoView2.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/myInfoView2.xml?USR_LASTNAME +# users/myInfoView2.xml +#: text - USR_LASTNAME +msgid "[users/myInfoView2.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/myInfoView2.xml?USR_USERNAME +# users/myInfoView2.xml +#: text - USR_USERNAME +msgid "[users/myInfoView2.xml?USR_USERNAME] User ID" +msgstr "User ID" + +# users/myInfoView2.xml?USR_EMAIL +# users/myInfoView2.xml +#: text - USR_EMAIL +msgid "[users/myInfoView2.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/myInfoView2.xml?USR_ADDRESS +# users/myInfoView2.xml +#: textarea - USR_ADDRESS +msgid "[users/myInfoView2.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/myInfoView2.xml?USR_ZIP_CODE +# users/myInfoView2.xml +#: text - USR_ZIP_CODE +msgid "[users/myInfoView2.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/myInfoView2.xml?USR_COUNTRY +# users/myInfoView2.xml +#: dropdown - USR_COUNTRY +msgid "[users/myInfoView2.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/myInfoView2.xml?USR_COUNTRY-'' +# users/myInfoView2.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/myInfoView2.xml?USR_COUNTRY-'']" +msgstr "" + +# users/myInfoView2.xml?USR_CITY +# users/myInfoView2.xml +#: dropdown - USR_CITY +msgid "[users/myInfoView2.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/myInfoView2.xml?USR_LOCATION +# users/myInfoView2.xml +#: dropdown - USR_LOCATION +msgid "[users/myInfoView2.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/myInfoView2.xml?USR_PHONE +# users/myInfoView2.xml +#: text - USR_PHONE +msgid "[users/myInfoView2.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/myInfoView2.xml?USR_POSITION +# users/myInfoView2.xml +#: text - USR_POSITION +msgid "[users/myInfoView2.xml?USR_POSITION] Position" +msgstr "Position" + +# users/myInfoView2.xml?USR_DUE_DATE +# users/myInfoView2.xml +#: date - USR_DUE_DATE +msgid "[users/myInfoView2.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/myInfoView2.xml?USR_STATUS +# users/myInfoView2.xml +#: dropdown - USR_STATUS +msgid "[users/myInfoView2.xml?USR_STATUS] Status" +msgstr "Status" + +# users/myInfoView2.xml?USR_STATUS-ACTIVE +# users/myInfoView2.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/myInfoView2.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/myInfoView2.xml?USR_STATUS-INACTIVE +# users/myInfoView2.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/myInfoView2.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/myInfoView2.xml?USR_STATUS-VACATION +# users/myInfoView2.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/myInfoView2.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/myInfoView2.xml?USR_ROLE +# users/myInfoView2.xml +#: dropdown - USR_ROLE +msgid "[users/myInfoView2.xml?USR_ROLE] Role" +msgstr "Role" + +# users/myInfoView2.xml?USR_REPORTS_TO +# users/myInfoView2.xml +#: caption - USR_REPORTS_TO +msgid "[users/myInfoView2.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/myInfoView2.xml?USR_DEPARTMENT +# users/myInfoView2.xml +#: caption - USR_DEPARTMENT +msgid "[users/myInfoView2.xml?USR_DEPARTMENT] Department" +msgstr "Department" + +# users/myInfoView2.xml?TITLECHP +# users/myInfoView2.xml +#: title - TITLECHP +msgid "[users/myInfoView2.xml?TITLECHP] Change Password" +msgstr "Change Password" + +# users/myInfoView2.xml?USR_NEW_PASS +# users/myInfoView2.xml +#: password - USR_NEW_PASS +msgid "[users/myInfoView2.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/myInfoView2.xml?USR_CNF_PASS +# users/myInfoView2.xml +#: password - USR_CNF_PASS +msgid "[users/myInfoView2.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/myInfoView2.xml?TITLEPREF +# users/myInfoView2.xml +#: title - TITLEPREF +msgid "[users/myInfoView2.xml?TITLEPREF] Preferences" +msgstr "Preferences" + +# users/myInfoView2.xml?PREF_DEFAULT_LANG +# users/myInfoView2.xml +#: dropdown - PREF_DEFAULT_LANG +msgid "[users/myInfoView2.xml?PREF_DEFAULT_LANG] Default languaje" +msgstr "Default languaje" + +# users/myInfoView2.xml?PREF_DEFAULT_MENUSELECTED +# users/myInfoView2.xml +#: dropdown - PREF_DEFAULT_MENUSELECTED +msgid "[users/myInfoView2.xml?PREF_DEFAULT_MENUSELECTED] Default menu option" +msgstr "Default menu option" + +# users/myInfoView2.xml?PREF_DEFAULT_CASES_MENUSELECTED +# users/myInfoView2.xml +#: dropdown - PREF_DEFAULT_CASES_MENUSELECTED +msgid "Default Cases menu option" +msgstr "Default Cases menu option" + +# users/myInfoView2.xml?SUBMIT3 +# users/myInfoView2.xml +#: button - SUBMIT3 +msgid "[users/myInfoView2.xml?SUBMIT3] Save" +msgstr "Save" + +# users/users_AuthSource.xml?TITLE +# users/users_AuthSource.xml +#: title - TITLE +msgid "Authentication Source Assignment" +msgstr "Authentication Source Assignment" + +# users/users_AuthSource.xml?UID_AUTH_SOURCE +# users/users_AuthSource.xml +#: dropdown - UID_AUTH_SOURCE +msgid "Authentication Source" +msgstr "Authentication Source" + +# users/users_AuthSource.xml?UID_AUTH_SOURCE-MYSQL +# users/users_AuthSource.xml +#: dropdown - UID_AUTH_SOURCE - MYSQL +msgid "[users/users_AuthSource.xml?UID_AUTH_SOURCE-MYSQL]" +msgstr "ProcessMaker" + +# users/users_AuthSource.xml?USR_AUTH_USER_DN +# users/users_AuthSource.xml +#: text - USR_AUTH_USER_DN +msgid "DN" +msgstr "DN" + +# users/users_AuthSource.xml?BTN_CANCEL +# users/users_AuthSource.xml +#: button - BTN_CANCEL +msgid "[users/users_AuthSource.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# users/users_AuthSource.xml?btnSave +# users/users_AuthSource.xml +#: submit - btnSave +msgid "[users/users_AuthSource.xml?btnSave] Save" +msgstr "Save" + +# users/users_AvailableUsers.xml?LABEL +# users/users_AvailableUsers.xml +#: text - LABEL +msgid "User or Group" +msgstr "User or Group" + +# users/users_AvailableUsers.xml?ASSIGN +# users/users_AvailableUsers.xml +#: link - ASSIGN +msgid "[users/users_AvailableUsers.xml?ASSIGN]" +msgstr "" + +# users/users_DeleteAssign.xml?MESSAGE +# users/users_DeleteAssign.xml +#: title - MESSAGE +msgid "<center>User cases summary</center>" +msgstr "<center>User cases summary</center>" + +# users/users_DeleteAssign.xml?TO_DO +# users/users_DeleteAssign.xml +#: text - TO_DO +msgid "[users/users_DeleteAssign.xml?TO_DO] To Do" +msgstr "To Do" + +# users/users_DeleteAssign.xml?DRAFT +# users/users_DeleteAssign.xml +#: text - DRAFT +msgid "[users/users_DeleteAssign.xml?DRAFT] Draft" +msgstr "Draft" + +# users/users_DeleteAssign.xml?COMPLETED +# users/users_DeleteAssign.xml +#: text - COMPLETED +msgid "[users/users_DeleteAssign.xml?COMPLETED] Completed" +msgstr "Completed" + +# users/users_DeleteAssign.xml?CANCELLED +# users/users_DeleteAssign.xml +#: text - CANCELLED +msgid "[users/users_DeleteAssign.xml?CANCELLED] Cancelled" +msgstr "Cancelled" + +# users/users_Edit.xml?TITLE3 +# users/users_Edit.xml +#: title - TITLE3 +msgid "[users/users_Edit.xml?TITLE3] Profile" +msgstr "Profile" + +# users/users_Edit.xml?USR_PHOTO +# users/users_Edit.xml +#: file - USR_PHOTO +msgid "[users/users_Edit.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/users_Edit.xml?USR_RESUME +# users/users_Edit.xml +#: file - USR_RESUME +msgid "[users/users_Edit.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/users_Edit.xml?TITLE1 +# users/users_Edit.xml +#: title - TITLE1 +msgid "[users/users_Edit.xml?TITLE1] Personal Information" +msgstr "Personal Information" + +# users/users_Edit.xml?USR_FIRSTNAME +# users/users_Edit.xml +#: text - USR_FIRSTNAME +msgid "[users/users_Edit.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/users_Edit.xml?USR_LASTNAME +# users/users_Edit.xml +#: text - USR_LASTNAME +msgid "[users/users_Edit.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/users_Edit.xml?USR_USERNAME +# users/users_Edit.xml +#: text - USR_USERNAME +msgid "User ID (*)" +msgstr "User ID (*)" + +# users/users_Edit.xml?USR_EMAIL +# users/users_Edit.xml +#: text - USR_EMAIL +msgid "[users/users_Edit.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/users_Edit.xml?USR_ADDRESS +# users/users_Edit.xml +#: textarea - USR_ADDRESS +msgid "[users/users_Edit.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/users_Edit.xml?USR_ZIP_CODE +# users/users_Edit.xml +#: text - USR_ZIP_CODE +msgid "[users/users_Edit.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/users_Edit.xml?USR_COUNTRY +# users/users_Edit.xml +#: dropdown - USR_COUNTRY +msgid "[users/users_Edit.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/users_Edit.xml?USR_COUNTRY-'' +# users/users_Edit.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/users_Edit.xml?USR_COUNTRY-'']" +msgstr "" + +# users/users_Edit.xml?USR_CITY +# users/users_Edit.xml +#: dropdown - USR_CITY +msgid "[users/users_Edit.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/users_Edit.xml?USR_LOCATION +# users/users_Edit.xml +#: dropdown - USR_LOCATION +msgid "[users/users_Edit.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/users_Edit.xml?USR_PHONE +# users/users_Edit.xml +#: text - USR_PHONE +msgid "[users/users_Edit.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/users_Edit.xml?USR_POSITION +# users/users_Edit.xml +#: text - USR_POSITION +msgid "[users/users_Edit.xml?USR_POSITION] Position" +msgstr "Position" + +# users/users_Edit.xml?USR_REPORTS_TO +# users/users_Edit.xml +#: dropdown - USR_REPORTS_TO +msgid "[users/users_Edit.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/users_Edit.xml?USR_REPORTS_TO-'' +# users/users_Edit.xml +#: dropdown - USR_REPORTS_TO - '' +msgid "[users/users_Edit.xml?USR_REPORTS_TO-'']" +msgstr "" + +# users/users_Edit.xml?USR_REPLACED_BY +# users/users_Edit.xml +#: dropdown - USR_REPLACED_BY +msgid "Replaced by" +msgstr "Replaced by" + +# users/users_Edit.xml?USR_REPLACED_BY-'' +# users/users_Edit.xml +#: dropdown - USR_REPLACED_BY - '' +msgid "[users/users_Edit.xml?USR_REPLACED_BY-'']" +msgstr "" + +# users/users_Edit.xml?USR_DUE_DATE +# users/users_Edit.xml +#: date - USR_DUE_DATE +msgid "[users/users_Edit.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/users_Edit.xml?USR_CALENDAR +# users/users_Edit.xml +#: dropdown - USR_CALENDAR +msgid "[users/users_Edit.xml?USR_CALENDAR] Calendar" +msgstr "Calendar" + +# users/users_Edit.xml?USR_CALENDAR-'' +# users/users_Edit.xml +#: dropdown - USR_CALENDAR - '' +msgid "[users/users_Edit.xml?USR_CALENDAR-'']" +msgstr "- None -" + +# users/users_Edit.xml?USR_STATUS +# users/users_Edit.xml +#: dropdown - USR_STATUS +msgid "[users/users_Edit.xml?USR_STATUS] Status" +msgstr "Status" + +# users/users_Edit.xml?USR_STATUS-ACTIVE +# users/users_Edit.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/users_Edit.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/users_Edit.xml?USR_STATUS-INACTIVE +# users/users_Edit.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/users_Edit.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/users_Edit.xml?USR_STATUS-VACATION +# users/users_Edit.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/users_Edit.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/users_Edit.xml?USR_ROLE +# users/users_Edit.xml +#: dropdown - USR_ROLE +msgid "[users/users_Edit.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_Edit.xml?TITLE2 +# users/users_Edit.xml +#: title - TITLE2 +msgid "[users/users_Edit.xml?TITLE2] Change Password" +msgstr "Change Password" + +# users/users_Edit.xml?USR_NEW_PASS +# users/users_Edit.xml +#: password - USR_NEW_PASS +msgid "[users/users_Edit.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/users_Edit.xml?USR_CNF_PASS +# users/users_Edit.xml +#: password - USR_CNF_PASS +msgid "[users/users_Edit.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/users_Edit.xml?SUBMIT +# users/users_Edit.xml +#: button - SUBMIT +msgid "[users/users_Edit.xml?SUBMIT] Save" +msgstr "Save" + +# users/users_EditAdmin.xml?TITLE1 +# users/users_EditAdmin.xml +#: title - TITLE1 +msgid "[users/users_EditAdmin.xml?TITLE1] Personal Information" +msgstr "Personal Information" + +# users/users_EditAdmin.xml?USR_FIRSTNAME +# users/users_EditAdmin.xml +#: text - USR_FIRSTNAME +msgid "[users/users_EditAdmin.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/users_EditAdmin.xml?USR_LASTNAME +# users/users_EditAdmin.xml +#: text - USR_LASTNAME +msgid "[users/users_EditAdmin.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/users_EditAdmin.xml?USR_USERNAME +# users/users_EditAdmin.xml +#: text - USR_USERNAME +msgid "[users/users_EditAdmin.xml?USR_USERNAME] User ID (*)" +msgstr "User ID (*)" + +# users/users_EditAdmin.xml?USR_EMAIL +# users/users_EditAdmin.xml +#: text - USR_EMAIL +msgid "[users/users_EditAdmin.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/users_EditAdmin.xml?USR_ADDRESS +# users/users_EditAdmin.xml +#: textarea - USR_ADDRESS +msgid "[users/users_EditAdmin.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/users_EditAdmin.xml?USR_ZIP_CODE +# users/users_EditAdmin.xml +#: text - USR_ZIP_CODE +msgid "[users/users_EditAdmin.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/users_EditAdmin.xml?USR_COUNTRY +# users/users_EditAdmin.xml +#: dropdown - USR_COUNTRY +msgid "[users/users_EditAdmin.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/users_EditAdmin.xml?USR_COUNTRY-'' +# users/users_EditAdmin.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/users_EditAdmin.xml?USR_COUNTRY-'']" +msgstr "" + +# users/users_EditAdmin.xml?USR_CITY +# users/users_EditAdmin.xml +#: dropdown - USR_CITY +msgid "[users/users_EditAdmin.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/users_EditAdmin.xml?USR_LOCATION +# users/users_EditAdmin.xml +#: dropdown - USR_LOCATION +msgid "[users/users_EditAdmin.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/users_EditAdmin.xml?USR_PHONE +# users/users_EditAdmin.xml +#: text - USR_PHONE +msgid "[users/users_EditAdmin.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/users_EditAdmin.xml?USR_POSITION +# users/users_EditAdmin.xml +#: text - USR_POSITION +msgid "[users/users_EditAdmin.xml?USR_POSITION] Position" +msgstr "Position" + +# users/users_EditAdmin.xml?USR_REPORTS_TO +# users/users_EditAdmin.xml +#: dropdown - USR_REPORTS_TO +msgid "[users/users_EditAdmin.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/users_EditAdmin.xml?USR_REPORTS_TO-'' +# users/users_EditAdmin.xml +#: dropdown - USR_REPORTS_TO - '' +msgid "[users/users_EditAdmin.xml?USR_REPORTS_TO-'']" +msgstr "" + +# users/users_EditAdmin.xml?USR_REPLACED_BY +# users/users_EditAdmin.xml +#: dropdown - USR_REPLACED_BY +msgid "[users/users_EditAdmin.xml?USR_REPLACED_BY] Replaced by" +msgstr "Replaced by" + +# users/users_EditAdmin.xml?USR_REPLACED_BY-'' +# users/users_EditAdmin.xml +#: dropdown - USR_REPLACED_BY - '' +msgid "[users/users_EditAdmin.xml?USR_REPLACED_BY-'']" +msgstr "" + +# users/users_EditAdmin.xml?USR_DUE_DATE +# users/users_EditAdmin.xml +#: date - USR_DUE_DATE +msgid "[users/users_EditAdmin.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/users_EditAdmin.xml?USR_STATUS +# users/users_EditAdmin.xml +#: dropdown - USR_STATUS +msgid "[users/users_EditAdmin.xml?USR_STATUS] Status" +msgstr "Status" + +# users/users_EditAdmin.xml?USR_STATUS-ACTIVE +# users/users_EditAdmin.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/users_EditAdmin.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/users_EditAdmin.xml?USR_STATUS-INACTIVE +# users/users_EditAdmin.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/users_EditAdmin.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/users_EditAdmin.xml?USR_STATUS-VACATION +# users/users_EditAdmin.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/users_EditAdmin.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/users_EditAdmin.xml?USR_ROLE +# users/users_EditAdmin.xml +#: dropdown - USR_ROLE +msgid "[users/users_EditAdmin.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_EditAdmin.xml?TITLE2 +# users/users_EditAdmin.xml +#: title - TITLE2 +msgid "[users/users_EditAdmin.xml?TITLE2] Change Password" +msgstr "Change Password" + +# users/users_EditAdmin.xml?USR_NEW_PASS +# users/users_EditAdmin.xml +#: password - USR_NEW_PASS +msgid "[users/users_EditAdmin.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/users_EditAdmin.xml?USR_CNF_PASS +# users/users_EditAdmin.xml +#: password - USR_CNF_PASS +msgid "[users/users_EditAdmin.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/users_EditAdmin.xml?TITLE3 +# users/users_EditAdmin.xml +#: title - TITLE3 +msgid "Additional Information" +msgstr "Additional Information" + +# users/users_EditAdmin.xml?USR_PHOTO +# users/users_EditAdmin.xml +#: file - USR_PHOTO +msgid "[users/users_EditAdmin.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/users_EditAdmin.xml?USR_RESUME +# users/users_EditAdmin.xml +#: file - USR_RESUME +msgid "[users/users_EditAdmin.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/users_EditAdmin.xml?SUBMIT +# users/users_EditAdmin.xml +#: button - SUBMIT +msgid "[users/users_EditAdmin.xml?SUBMIT] Save" +msgstr "Save" + +# users/users_EditOptions.xml?MNU1 +# users/users_EditOptions.xml +#: link - MNU1 +msgid "[users/users_EditOptions.xml?MNU1] Back to list" +msgstr "Back to list" + +# users/users_EditRT.xml?TITLE3 +# users/users_EditRT.xml +#: title - TITLE3 +msgid "[users/users_EditRT.xml?TITLE3] Profile" +msgstr "Profile" + +# users/users_EditRT.xml?USR_PHOTO_SHOW +# users/users_EditRT.xml +#: image - USR_PHOTO_SHOW +msgid "[users/users_EditRT.xml?USR_PHOTO_SHOW]" +msgstr "" + +# users/users_EditRT.xml?USR_PHOTO +# users/users_EditRT.xml +#: file - USR_PHOTO +msgid "[users/users_EditRT.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/users_EditRT.xml?USR_RESUME +# users/users_EditRT.xml +#: file - USR_RESUME +msgid "[users/users_EditRT.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/users_EditRT.xml?TITLE1 +# users/users_EditRT.xml +#: title - TITLE1 +msgid "[users/users_EditRT.xml?TITLE1] Personal Information" +msgstr "Personal Information" + +# users/users_EditRT.xml?USR_FIRSTNAME +# users/users_EditRT.xml +#: text - USR_FIRSTNAME +msgid "[users/users_EditRT.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/users_EditRT.xml?USR_LASTNAME +# users/users_EditRT.xml +#: text - USR_LASTNAME +msgid "[users/users_EditRT.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/users_EditRT.xml?USR_USERNAME +# users/users_EditRT.xml +#: text - USR_USERNAME +msgid "[users/users_EditRT.xml?USR_USERNAME] User ID (*)" +msgstr "User ID (*)" + +# users/users_EditRT.xml?USR_EMAIL +# users/users_EditRT.xml +#: text - USR_EMAIL +msgid "[users/users_EditRT.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/users_EditRT.xml?USR_ADDRESS +# users/users_EditRT.xml +#: textarea - USR_ADDRESS +msgid "[users/users_EditRT.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/users_EditRT.xml?USR_ZIP_CODE +# users/users_EditRT.xml +#: text - USR_ZIP_CODE +msgid "[users/users_EditRT.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/users_EditRT.xml?USR_COUNTRY +# users/users_EditRT.xml +#: dropdown - USR_COUNTRY +msgid "[users/users_EditRT.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/users_EditRT.xml?USR_COUNTRY-'' +# users/users_EditRT.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/users_EditRT.xml?USR_COUNTRY-'']" +msgstr "" + +# users/users_EditRT.xml?USR_CITY +# users/users_EditRT.xml +#: dropdown - USR_CITY +msgid "[users/users_EditRT.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/users_EditRT.xml?USR_LOCATION +# users/users_EditRT.xml +#: dropdown - USR_LOCATION +msgid "[users/users_EditRT.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/users_EditRT.xml?USR_PHONE +# users/users_EditRT.xml +#: text - USR_PHONE +msgid "[users/users_EditRT.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/users_EditRT.xml?USR_POSITION +# users/users_EditRT.xml +#: text - USR_POSITION +msgid "[users/users_EditRT.xml?USR_POSITION] Position" +msgstr "Position" + +# users/users_EditRT.xml?USR_REPORTS_TO +# users/users_EditRT.xml +#: caption - USR_REPORTS_TO +msgid "[users/users_EditRT.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/users_EditRT.xml?USR_DEPARTMENT +# users/users_EditRT.xml +#: caption - USR_DEPARTMENT +msgid "[users/users_EditRT.xml?USR_DEPARTMENT] Department" +msgstr "Department" + +# users/users_EditRT.xml?USR_REPLACED_BY +# users/users_EditRT.xml +#: dropdown - USR_REPLACED_BY +msgid "[users/users_EditRT.xml?USR_REPLACED_BY] Replaced by" +msgstr "Replaced by" + +# users/users_EditRT.xml?USR_REPLACED_BY-'' +# users/users_EditRT.xml +#: dropdown - USR_REPLACED_BY - '' +msgid "[users/users_EditRT.xml?USR_REPLACED_BY-'']" +msgstr "" + +# users/users_EditRT.xml?USR_DUE_DATE +# users/users_EditRT.xml +#: date - USR_DUE_DATE +msgid "[users/users_EditRT.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/users_EditRT.xml?USR_CALENDAR +# users/users_EditRT.xml +#: dropdown - USR_CALENDAR +msgid "[users/users_EditRT.xml?USR_CALENDAR] Calendar" +msgstr "Calendar" + +# users/users_EditRT.xml?USR_CALENDAR-'' +# users/users_EditRT.xml +#: dropdown - USR_CALENDAR - '' +msgid "[users/users_EditRT.xml?USR_CALENDAR-'']" +msgstr "- None -" + +# users/users_EditRT.xml?USR_STATUS +# users/users_EditRT.xml +#: dropdown - USR_STATUS +msgid "[users/users_EditRT.xml?USR_STATUS] Status" +msgstr "Status" + +# users/users_EditRT.xml?USR_STATUS-ACTIVE +# users/users_EditRT.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/users_EditRT.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/users_EditRT.xml?USR_STATUS-INACTIVE +# users/users_EditRT.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/users_EditRT.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/users_EditRT.xml?USR_STATUS-VACATION +# users/users_EditRT.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/users_EditRT.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/users_EditRT.xml?USR_ROLE +# users/users_EditRT.xml +#: dropdown - USR_ROLE +msgid "[users/users_EditRT.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_EditRT.xml?TITLE2 +# users/users_EditRT.xml +#: title - TITLE2 +msgid "[users/users_EditRT.xml?TITLE2] Change Password" +msgstr "Change Password" + +# users/users_EditRT.xml?USR_NEW_PASS +# users/users_EditRT.xml +#: password - USR_NEW_PASS +msgid "[users/users_EditRT.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/users_EditRT.xml?USR_CNF_PASS +# users/users_EditRT.xml +#: password - USR_CNF_PASS +msgid "[users/users_EditRT.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/users_EditRT.xml?SUBMIT +# users/users_EditRT.xml +#: button - SUBMIT +msgid "[users/users_EditRT.xml?SUBMIT] Save" +msgstr "Save" + +# users/users_EditRT.xml?BTN_CANCEL +# users/users_EditRT.xml +#: button - BTN_CANCEL +msgid "[users/users_EditRT.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# users/users_List.xml?USR_COMPLETENAME +# users/users_List.xml +#: text - USR_COMPLETENAME +msgid "Full Name" +msgstr "Full Name" + +# users/users_List.xml?USR_USERNAME +# users/users_List.xml +#: text - USR_USERNAME +msgid "[users/users_List.xml?USR_USERNAME] Username" +msgstr "Username" + +# users/users_List.xml?USR_EMAIL +# users/users_List.xml +#: text - USR_EMAIL +msgid "[users/users_List.xml?USR_EMAIL] E-Mail" +msgstr "E-Mail" + +# users/users_List.xml?USR_ROLE +# users/users_List.xml +#: text - USR_ROLE +msgid "[users/users_List.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_List.xml?USR_DUE_DATE +# users/users_List.xml +#: text - USR_DUE_DATE +msgid "[users/users_List.xml?USR_DUE_DATE] Due Date" +msgstr "Due Date" + +# users/users_List.xml?USR_EDIT +# users/users_List.xml +#: link - USR_EDIT +msgid "[users/users_List.xml?USR_EDIT]" +msgstr "" + +# users/users_List.xml?USR_GROUP +# users/users_List.xml +#: link - USR_GROUP +msgid "[users/users_List.xml?USR_GROUP]" +msgstr "" + +# users/users_List.xml?USR_AUTH +# users/users_List.xml +#: link - USR_AUTH +msgid "[users/users_List.xml?USR_AUTH]" +msgstr "" + +# users/users_List.xml?USR_REASSIGN +# users/users_List.xml +#: link - USR_REASSIGN +msgid "[users/users_List.xml?USR_REASSIGN]" +msgstr "" + +# users/users_List.xml?USR_DELETE +# users/users_List.xml +#: link - USR_DELETE +msgid "[users/users_List.xml?USR_DELETE]" +msgstr "" + +# users/users_New.xml?TITLE3 +# users/users_New.xml +#: title - TITLE3 +msgid "[users/users_New.xml?TITLE3] Profile" +msgstr "Profile" + +# users/users_New.xml?USR_PHOTO +# users/users_New.xml +#: file - USR_PHOTO +msgid "[users/users_New.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/users_New.xml?USR_RESUME +# users/users_New.xml +#: file - USR_RESUME +msgid "[users/users_New.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/users_New.xml?TITLE1 +# users/users_New.xml +#: title - TITLE1 +msgid "[users/users_New.xml?TITLE1] Personal Information" +msgstr "Personal Information" + +# users/users_New.xml?USR_FIRSTNAME +# users/users_New.xml +#: text - USR_FIRSTNAME +msgid "[users/users_New.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/users_New.xml?USR_LASTNAME +# users/users_New.xml +#: text - USR_LASTNAME +msgid "[users/users_New.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/users_New.xml?USR_USERNAME +# users/users_New.xml +#: text - USR_USERNAME +msgid "[users/users_New.xml?USR_USERNAME] User ID (*)" +msgstr "User ID (*)" + +# users/users_New.xml?USR_EMAIL +# users/users_New.xml +#: text - USR_EMAIL +msgid "[users/users_New.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/users_New.xml?USR_ADDRESS +# users/users_New.xml +#: textarea - USR_ADDRESS +msgid "[users/users_New.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/users_New.xml?USR_ZIP_CODE +# users/users_New.xml +#: text - USR_ZIP_CODE +msgid "[users/users_New.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/users_New.xml?USR_COUNTRY +# users/users_New.xml +#: dropdown - USR_COUNTRY +msgid "[users/users_New.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/users_New.xml?USR_COUNTRY-'' +# users/users_New.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/users_New.xml?USR_COUNTRY-'']" +msgstr "" + +# users/users_New.xml?USR_CITY +# users/users_New.xml +#: dropdown - USR_CITY +msgid "[users/users_New.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/users_New.xml?USR_LOCATION +# users/users_New.xml +#: dropdown - USR_LOCATION +msgid "[users/users_New.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/users_New.xml?USR_PHONE +# users/users_New.xml +#: text - USR_PHONE +msgid "[users/users_New.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/users_New.xml?USR_POSITION +# users/users_New.xml +#: text - USR_POSITION +msgid "[users/users_New.xml?USR_POSITION] Position" +msgstr "Position" + +# users/users_New.xml?USR_REPORTS_TO +# users/users_New.xml +#: dropdown - USR_REPORTS_TO +msgid "[users/users_New.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/users_New.xml?USR_REPORTS_TO-'' +# users/users_New.xml +#: dropdown - USR_REPORTS_TO - '' +msgid "[users/users_New.xml?USR_REPORTS_TO-'']" +msgstr "" + +# users/users_New.xml?USR_REPLACED_BY +# users/users_New.xml +#: dropdown - USR_REPLACED_BY +msgid "[users/users_New.xml?USR_REPLACED_BY] Replaced by" +msgstr "Replaced by" + +# users/users_New.xml?USR_REPLACED_BY-'' +# users/users_New.xml +#: dropdown - USR_REPLACED_BY - '' +msgid "[users/users_New.xml?USR_REPLACED_BY-'']" +msgstr "" + +# users/users_New.xml?USR_DUE_DATE +# users/users_New.xml +#: date - USR_DUE_DATE +msgid "[users/users_New.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/users_New.xml?USR_CALENDAR +# users/users_New.xml +#: dropdown - USR_CALENDAR +msgid "[users/users_New.xml?USR_CALENDAR] Calendar" +msgstr "Calendar" + +# users/users_New.xml?USR_CALENDAR-'' +# users/users_New.xml +#: dropdown - USR_CALENDAR - '' +msgid "[users/users_New.xml?USR_CALENDAR-'']" +msgstr "- None -" + +# users/users_New.xml?USR_STATUS +# users/users_New.xml +#: dropdown - USR_STATUS +msgid "[users/users_New.xml?USR_STATUS] Status" +msgstr "Status" + +# users/users_New.xml?USR_STATUS-ACTIVE +# users/users_New.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/users_New.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/users_New.xml?USR_STATUS-INACTIVE +# users/users_New.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/users_New.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/users_New.xml?USR_STATUS-VACATION +# users/users_New.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/users_New.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/users_New.xml?USR_ROLE +# users/users_New.xml +#: dropdown - USR_ROLE +msgid "[users/users_New.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_New.xml?TITLE2 +# users/users_New.xml +#: title - TITLE2 +msgid "[users/users_New.xml?TITLE2] Change Password" +msgstr "Change Password" + +# users/users_New.xml?USR_NEW_PASS +# users/users_New.xml +#: password - USR_NEW_PASS +msgid "[users/users_New.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/users_New.xml?USR_CNF_PASS +# users/users_New.xml +#: password - USR_CNF_PASS +msgid "[users/users_New.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/users_New.xml?SUBMIT +# users/users_New.xml +#: button - SUBMIT +msgid "[users/users_New.xml?SUBMIT] Save" +msgstr "Save" + +# users/users_New.xml?BTN_CANCEL +# users/users_New.xml +#: button - BTN_CANCEL +msgid "[users/users_New.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# users/users_NewOptions.xml?MNU +# users/users_NewOptions.xml +#: link - MNU +msgid "[users/users_NewOptions.xml?MNU] Back to list" +msgstr "Back to list" + +# users/users_Options.xml?MNU_ADD +# users/users_Options.xml +#: link - MNU_ADD +msgid "[users/users_Options.xml?MNU_ADD] New" +msgstr "New" + +# users/users_ReassignCases.xml?PROCESS +# users/users_ReassignCases.xml +#: text - PROCESS +msgid "[users/users_ReassignCases.xml?PROCESS] Process" +msgstr "Process" + +# users/users_ReassignCases.xml?CANTITY +# users/users_ReassignCases.xml +#: text - CANTITY +msgid "No. of cases" +msgstr "No. of cases" + +# users/users_ReassignCases.xml?USERS +# users/users_ReassignCases.xml +#: text - USERS +msgid "[users/users_ReassignCases.xml?USERS] Reassign to" +msgstr "Reassign to" + +# users/users_ReassignSelectSubType.xml?TITLE1 +# users/users_ReassignSelectSubType.xml +#: title - TITLE1 +msgid "Select the type grouping of the cases" +msgstr "Select the type grouping of the cases" + +# users/users_ReassignSelectSubType.xml?TYPE +# users/users_ReassignSelectSubType.xml +#: dropdown - TYPE +msgid "Reassign Type" +msgstr "Reassign Type" + +# users/users_ReassignSelectSubType.xml?TYPE-ANY_USER +# users/users_ReassignSelectSubType.xml +#: dropdown - TYPE - ANY_USER +msgid "[users/users_ReassignSelectSubType.xml?TYPE-ANY_USER]" +msgstr "Any user" + +# users/users_ReassignSelectSubType.xml?SUB_TYPE +# users/users_ReassignSelectSubType.xml +#: dropdown - SUB_TYPE +msgid "Group Cases By" +msgstr "Group Cases By" + +# users/users_ReassignSelectSubType.xml?SUB_TYPE-PROCESS +# users/users_ReassignSelectSubType.xml +#: dropdown - SUB_TYPE - PROCESS +msgid "[users/users_ReassignSelectSubType.xml?SUB_TYPE-PROCESS]" +msgstr "Process" + +# users/users_ReassignSelectSubType.xml?BTN_CANCEL +# users/users_ReassignSelectSubType.xml +#: button - BTN_CANCEL +msgid "[users/users_ReassignSelectSubType.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# users/users_ReassignSelectSubType.xml?CONTINUE +# users/users_ReassignSelectSubType.xml +#: button - CONTINUE +msgid "[users/users_ReassignSelectSubType.xml?CONTINUE] Continue" +msgstr "Continue" + +# users/users_ReassignSelectType.xml?TITLE1 +# users/users_ReassignSelectType.xml +#: title - TITLE1 +msgid "Select the reassign type" +msgstr "Select the reassign type" + +# users/users_ReassignSelectType.xml?TYPE +# users/users_ReassignSelectType.xml +#: dropdown - TYPE +msgid "[users/users_ReassignSelectType.xml?TYPE] Type" +msgstr "Type" + +# users/users_ReassignSelectType.xml?TYPE-ANY_USER +# users/users_ReassignSelectType.xml +#: dropdown - TYPE - ANY_USER +msgid "[users/users_ReassignSelectType.xml?TYPE-ANY_USER]" +msgstr "Any user" + +# users/users_ReassignSelectType.xml?BTN_CANCEL +# users/users_ReassignSelectType.xml +#: button - BTN_CANCEL +msgid "[users/users_ReassignSelectType.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# users/users_ReassignSelectType.xml?CONTINUE +# users/users_ReassignSelectType.xml +#: button - CONTINUE +msgid "[users/users_ReassignSelectType.xml?CONTINUE] Continue" +msgstr "Continue" + +# users/users_ReassignShowInfo.xml?TITLE +# users/users_ReassignShowInfo.xml +#: title - TITLE +msgid "[users/users_ReassignShowInfo.xml?TITLE] Information" +msgstr "Information" + +# users/users_ReassignShowInfo.xml?EVA +# users/users_ReassignShowInfo.xml +#: text - EVA +msgid "[users/users_ReassignShowInfo.xml?EVA]" +msgstr "" + +# users/users_ReassignShowInfo.xml?MESSAGE +# users/users_ReassignShowInfo.xml +#: text - MESSAGE +msgid "[users/users_ReassignShowInfo.xml?MESSAGE]" +msgstr "" + +# users/users_ReassignShowInfo.xml?DELETE +# users/users_ReassignShowInfo.xml +#: button - DELETE +msgid "[users/users_ReassignShowInfo.xml?DELETE] Delete" +msgstr "Delete" + +# users/users_Search.xml?USR_COMPLETENAME +# users/users_Search.xml +#: text - USR_COMPLETENAME +msgid "Full name" +msgstr "Full name" + +# users/users_Search.xml?search +# users/users_Search.xml +#: button - search +msgid "[users/users_Search.xml?search] Apply Filter" +msgstr "Apply Filter" + +# users/users_ShortList.xml?LABEL +# users/users_ShortList.xml +#: text - LABEL +msgid "[users/users_ShortList.xml?LABEL] Group or User" +msgstr "Group or User" + +# users/users_ShortList.xml?OF_TO_ASSIGN +# users/users_ShortList.xml +#: link - OF_TO_ASSIGN +msgid "[users/users_ShortList.xml?OF_TO_ASSIGN]" +msgstr "" + +# users/users_ShortList2.xml?LABEL +# users/users_ShortList2.xml +#: text - LABEL +msgid "[users/users_ShortList2.xml?LABEL] Group or User" +msgstr "Group or User" + +# users/users_ShortList2.xml?OF_TO_ASSIGN +# users/users_ShortList2.xml +#: link - OF_TO_ASSIGN +msgid "[users/users_ShortList2.xml?OF_TO_ASSIGN]" +msgstr "" + +# users/users_ShortListAdhoc.xml?LABEL +# users/users_ShortListAdhoc.xml +#: text - LABEL +msgid "[users/users_ShortListAdhoc.xml?LABEL] Group or User" +msgstr "Group or User" + +# users/users_ShortListAdhoc.xml?OF_TO_ASSIGN +# users/users_ShortListAdhoc.xml +#: link - OF_TO_ASSIGN +msgid "[users/users_ShortListAdhoc.xml?OF_TO_ASSIGN]" +msgstr "" + +# users/users_ShortOptions.xml?MNU_ASSIGN +# users/users_ShortOptions.xml +#: link - MNU_ASSIGN +msgid "[users/users_ShortOptions.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# users/users_ShortOptions.xml?MNU_CHANGE +# users/users_ShortOptions.xml +#: link - MNU_CHANGE +msgid "View Users for \"Adhoc\"" +msgstr "View Users for \"Adhoc\"" + +# users/users_ShortOptions2.xml?MNU_ASSIGN +# users/users_ShortOptions2.xml +#: link - MNU_ASSIGN +msgid "[users/users_ShortOptions2.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# users/users_ShortOptionsAdhoc.xml?MNU_ASSIGN +# users/users_ShortOptionsAdhoc.xml +#: link - MNU_ASSIGN +msgid "[users/users_ShortOptionsAdhoc.xml?MNU_ASSIGN] Assign" +msgstr "Assign" + +# users/users_View.xml?TITLEADD +# users/users_View.xml +#: title - TITLEADD +msgid "[users/users_View.xml?TITLEADD] Profile" +msgstr "Profile" + +# users/users_View.xml?USR_PHOTO +# users/users_View.xml +#: image - USR_PHOTO +msgid "[users/users_View.xml?USR_PHOTO] Photo" +msgstr "Photo" + +# users/users_View.xml?USR_RESUME +# users/users_View.xml +#: link - USR_RESUME +msgid "[users/users_View.xml?USR_RESUME] Resume" +msgstr "Resume" + +# users/users_View.xml?TITLE9689 +# users/users_View.xml +#: title - TITLE9689 +msgid "[users/users_View.xml?TITLE9689] Personal Information" +msgstr "Personal Information" + +# users/users_View.xml?USR_FIRSTNAME +# users/users_View.xml +#: text - USR_FIRSTNAME +msgid "[users/users_View.xml?USR_FIRSTNAME] First Name" +msgstr "First Name" + +# users/users_View.xml?USR_LASTNAME +# users/users_View.xml +#: text - USR_LASTNAME +msgid "[users/users_View.xml?USR_LASTNAME] Last Name" +msgstr "Last Name" + +# users/users_View.xml?USR_USERNAME +# users/users_View.xml +#: text - USR_USERNAME +msgid "[users/users_View.xml?USR_USERNAME] User ID" +msgstr "User ID" + +# users/users_View.xml?USR_EMAIL +# users/users_View.xml +#: text - USR_EMAIL +msgid "[users/users_View.xml?USR_EMAIL] Email" +msgstr "Email" + +# users/users_View.xml?USR_ADDRESS +# users/users_View.xml +#: text - USR_ADDRESS +msgid "[users/users_View.xml?USR_ADDRESS] Address" +msgstr "Address" + +# users/users_View.xml?USR_ZIP_CODE +# users/users_View.xml +#: text - USR_ZIP_CODE +msgid "[users/users_View.xml?USR_ZIP_CODE] Zip Code" +msgstr "Zip Code" + +# users/users_View.xml?USR_COUNTRY +# users/users_View.xml +#: dropdown - USR_COUNTRY +msgid "[users/users_View.xml?USR_COUNTRY] Country" +msgstr "Country" + +# users/users_View.xml?USR_COUNTRY-'' +# users/users_View.xml +#: dropdown - USR_COUNTRY - '' +msgid "[users/users_View.xml?USR_COUNTRY-'']" +msgstr "" + +# users/users_View.xml?USR_CITY +# users/users_View.xml +#: dropdown - USR_CITY +msgid "[users/users_View.xml?USR_CITY] State or Region" +msgstr "State or Region" + +# users/users_View.xml?USR_LOCATION +# users/users_View.xml +#: dropdown - USR_LOCATION +msgid "[users/users_View.xml?USR_LOCATION] Location" +msgstr "Location" + +# users/users_View.xml?USR_PHONE +# users/users_View.xml +#: text - USR_PHONE +msgid "[users/users_View.xml?USR_PHONE] Phone" +msgstr "Phone" + +# users/users_View.xml?USR_POSITION +# users/users_View.xml +#: text - USR_POSITION +msgid "[users/users_View.xml?USR_POSITION] Position" +msgstr "Position" + +# users/users_View.xml?USR_REPORTS_TO +# users/users_View.xml +#: dropdown - USR_REPORTS_TO +msgid "[users/users_View.xml?USR_REPORTS_TO] Reports to" +msgstr "Reports to" + +# users/users_View.xml?USR_REPORTS_TO-'' +# users/users_View.xml +#: dropdown - USR_REPORTS_TO - '' +msgid "[users/users_View.xml?USR_REPORTS_TO-'']" +msgstr "" + +# users/users_View.xml?USR_REPLACED_BY +# users/users_View.xml +#: dropdown - USR_REPLACED_BY +msgid "[users/users_View.xml?USR_REPLACED_BY] Replaced by" +msgstr "Replaced by" + +# users/users_View.xml?USR_REPLACED_BY-'' +# users/users_View.xml +#: dropdown - USR_REPLACED_BY - '' +msgid "[users/users_View.xml?USR_REPLACED_BY-'']" +msgstr "" + +# users/users_View.xml?USR_DUE_DATE +# users/users_View.xml +#: date - USR_DUE_DATE +msgid "[users/users_View.xml?USR_DUE_DATE] Expiration Date" +msgstr "Expiration Date" + +# users/users_View.xml?USR_STATUS +# users/users_View.xml +#: dropdown - USR_STATUS +msgid "[users/users_View.xml?USR_STATUS] Status" +msgstr "Status" + +# users/users_View.xml?USR_STATUS-ACTIVE +# users/users_View.xml +#: dropdown - USR_STATUS - ACTIVE +msgid "[users/users_View.xml?USR_STATUS-ACTIVE]" +msgstr "ACTIVE" + +# users/users_View.xml?USR_STATUS-INACTIVE +# users/users_View.xml +#: dropdown - USR_STATUS - INACTIVE +msgid "[users/users_View.xml?USR_STATUS-INACTIVE]" +msgstr "INACTIVE" + +# users/users_View.xml?USR_STATUS-VACATION +# users/users_View.xml +#: dropdown - USR_STATUS - VACATION +msgid "[users/users_View.xml?USR_STATUS-VACATION]" +msgstr "ON VACATION" + +# users/users_View.xml?USR_ROLE +# users/users_View.xml +#: dropdown - USR_ROLE +msgid "[users/users_View.xml?USR_ROLE] Role" +msgstr "Role" + +# users/users_View.xml?TITLECHP +# users/users_View.xml +#: title - TITLECHP +msgid "[users/users_View.xml?TITLECHP] Change Password" +msgstr "Change Password" + +# users/users_View.xml?USR_NEW_PASS +# users/users_View.xml +#: password - USR_NEW_PASS +msgid "[users/users_View.xml?USR_NEW_PASS] New Password" +msgstr "New Password" + +# users/users_View.xml?USR_CNF_PASS +# users/users_View.xml +#: password - USR_CNF_PASS +msgid "[users/users_View.xml?USR_CNF_PASS] Confirm Password" +msgstr "Confirm Password" + +# users/users_ViewOptions.xml?MNU1 +# users/users_ViewOptions.xml +#: link - MNU1 +msgid "[users/users_ViewOptions.xml?MNU1] Back to list" +msgstr "Back to list" + +# users/users_ViewOptions.xml?MNU2 +# users/users_ViewOptions.xml +#: link - MNU2 +msgid "[users/users_ViewOptions.xml?MNU2] Edit" +msgstr "Edit" + +# dynaforms/fields/_options.xml?NAME +# dynaforms/fields/_options.xml +#: text - NAME +msgid "[dynaforms/fields/_options.xml?NAME] Value" +msgstr "Value" + +# dynaforms/fields/_options.xml?LABEL +# dynaforms/fields/_options.xml +#: text - LABEL +msgid "[dynaforms/fields/_options.xml?LABEL] Label" +msgstr "Label" + +# dynaforms/fields/button.xml?PME_TITLE +# dynaforms/fields/button.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/button.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/button.xml?PME_XMLNODE_NAME +# dynaforms/fields/button.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/button.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/button.xml?PME_LABEL +# dynaforms/fields/button.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/button.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/button.xml?PME_ONCLICK +# dynaforms/fields/button.xml +#: text - PME_ONCLICK +msgid "JavaScript to Execute" +msgstr "JavaScript to Execute" + +# dynaforms/fields/button.xml?BTN_CANCEL +# dynaforms/fields/button.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/button.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/button.xml?PME_ACCEPT +# dynaforms/fields/button.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/button.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/checkbox.xml?PME_TITLE +# dynaforms/fields/checkbox.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/checkbox.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/checkbox.xml?PME_XMLNODE_NAME +# dynaforms/fields/checkbox.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/checkbox.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/checkbox.xml?PME_LABEL +# dynaforms/fields/checkbox.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/checkbox.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/checkbox.xml?PME_SUBTITLE3 +# dynaforms/fields/checkbox.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/checkbox.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/checkbox.xml?PME_VALUE +# dynaforms/fields/checkbox.xml +#: text - PME_VALUE +msgid "[dynaforms/fields/checkbox.xml?PME_VALUE] Value" +msgstr "Value" + +# dynaforms/fields/checkbox.xml?PME_FALSEVALUE +# dynaforms/fields/checkbox.xml +#: text - PME_FALSEVALUE +msgid "Value if not checked" +msgstr "Value if not checked" + +# dynaforms/fields/checkbox.xml?PME_DEFAULTVALUE +# dynaforms/fields/checkbox.xml +#: checkbox - PME_DEFAULTVALUE +msgid "Default Value" +msgstr "Default Value" + +# dynaforms/fields/checkbox.xml?PME_READONLY +# dynaforms/fields/checkbox.xml +#: checkbox - PME_READONLY +msgid "Read Only" +msgstr "Read Only" + +# dynaforms/fields/checkbox.xml?PME_HINT +# dynaforms/fields/checkbox.xml +#: textarea - PME_HINT +msgid "Hint" +msgstr "Hint" + +# dynaforms/fields/checkbox.xml?PME_SUBTITLE +# dynaforms/fields/checkbox.xml +#: title - PME_SUBTITLE +msgid "Appearance" +msgstr "Appearance" + +# dynaforms/fields/checkbox.xml?PME_LABELONRIGHT +# dynaforms/fields/checkbox.xml +#: checkbox - PME_LABELONRIGHT +msgid "Label on the right side" +msgstr "Label on the right side" + +# dynaforms/fields/checkbox.xml?PME_ENABLEHTML +# dynaforms/fields/checkbox.xml +#: checkbox - PME_ENABLEHTML +msgid "Enable Html" +msgstr "Enable Html" + +# dynaforms/fields/checkbox.xml?BTN_CANCEL +# dynaforms/fields/checkbox.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/checkbox.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/checkbox.xml?PME_ACCEPT +# dynaforms/fields/checkbox.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/checkbox.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/checkgroup.xml?PME_TITLE +# dynaforms/fields/checkgroup.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/checkgroup.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/checkgroup.xml?PME_XMLNODE_NAME +# dynaforms/fields/checkgroup.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/checkgroup.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/checkgroup.xml?PME_LABEL +# dynaforms/fields/checkgroup.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/checkgroup.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/checkgroup.xml?PME_SUBTITLE3 +# dynaforms/fields/checkgroup.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/checkgroup.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/checkgroup.xml?PME_DEFAULTVALUE +# dynaforms/fields/checkgroup.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/checkgroup.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/checkgroup.xml?PME_HINT +# dynaforms/fields/checkgroup.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/checkgroup.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/checkgroup.xml?PME_SUBTITLE +# dynaforms/fields/checkgroup.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/checkgroup.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/checkgroup.xml?PME_MODE +# dynaforms/fields/checkgroup.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/checkgroup.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/checkgroup.xml?PME_MODE-edit +# dynaforms/fields/checkgroup.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/checkgroup.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/checkgroup.xml?PME_MODE-view +# dynaforms/fields/checkgroup.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/checkgroup.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/checkgroup.xml?PME_SUBTITLE2 +# dynaforms/fields/checkgroup.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/checkgroup.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/checkgroup.xml?PME_SQLCONNECTION +# dynaforms/fields/checkgroup.xml +#: dropdown - PME_SQLCONNECTION +msgid "Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/checkgroup.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/checkgroup.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/checkgroup.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/checkgroup.xml?PME_XMLNODE_VALUE +# dynaforms/fields/checkgroup.xml +#: textarea - PME_XMLNODE_VALUE +msgid "Sql" +msgstr "Sql" + +# dynaforms/fields/checkgroup.xml?BTN_CANCEL +# dynaforms/fields/checkgroup.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/checkgroup.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/checkgroup.xml?PME_ACCEPT +# dynaforms/fields/checkgroup.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/checkgroup.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/currency.xml?PME_TITLE +# dynaforms/fields/currency.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/currency.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/currency.xml?PME_XMLNODE_NAME +# dynaforms/fields/currency.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/currency.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/currency.xml?PME_LABEL +# dynaforms/fields/currency.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/currency.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/currency.xml?PME_SUBTITLE3 +# dynaforms/fields/currency.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/currency.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/currency.xml?PME_MAXLENGTH +# dynaforms/fields/currency.xml +#: text - PME_MAXLENGTH +msgid "Max. Length" +msgstr "Max. Length" + +# dynaforms/fields/currency.xml?PME_CURRENCY +# dynaforms/fields/currency.xml +#: text - PME_CURRENCY +msgid "Currency" +msgstr "Currency" + +# dynaforms/fields/currency.xml?PME_VALIDATE +# dynaforms/fields/currency.xml +#: dropdown - PME_VALIDATE +msgid "Validate" +msgstr "Validate" + +# dynaforms/fields/currency.xml?PME_VALIDATE-Int +# dynaforms/fields/currency.xml +#: dropdown - PME_VALIDATE - Int +msgid "[dynaforms/fields/currency.xml?PME_VALIDATE-Int]" +msgstr "Integer" + +# dynaforms/fields/currency.xml?PME_VALIDATE-Real +# dynaforms/fields/currency.xml +#: dropdown - PME_VALIDATE - Real +msgid "[dynaforms/fields/currency.xml?PME_VALIDATE-Real]" +msgstr "Real Number" + +# dynaforms/fields/currency.xml?PME_MASK +# dynaforms/fields/currency.xml +#: text - PME_MASK +msgid "Mask" +msgstr "Mask" + +# dynaforms/fields/currency.xml?PME_REQUIRED +# dynaforms/fields/currency.xml +#: checkbox - PME_REQUIRED +msgid "Required" +msgstr "Required" + +# dynaforms/fields/currency.xml?PME_READONLY +# dynaforms/fields/currency.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/currency.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/currency.xml?PME_DEFAULTVALUE +# dynaforms/fields/currency.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/currency.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/currency.xml?PME_HINT +# dynaforms/fields/currency.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/currency.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/currency.xml?PME_SUBTITLE +# dynaforms/fields/currency.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/currency.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/currency.xml?PME_SIZE +# dynaforms/fields/currency.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/currency.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/currency.xml?PME_MODE +# dynaforms/fields/currency.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/currency.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/currency.xml?PME_MODE-edit +# dynaforms/fields/currency.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/currency.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/currency.xml?PME_MODE-view +# dynaforms/fields/currency.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/currency.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/currency.xml?PME_SUBTITLE_OP +# dynaforms/fields/currency.xml +#: title - PME_SUBTITLE_OP +msgid "Operations" +msgstr "Operations" + +# dynaforms/fields/currency.xml?PME_FORMULA +# dynaforms/fields/currency.xml +#: text - PME_FORMULA +msgid "Formula" +msgstr "Formula" + +# dynaforms/fields/currency.xml?PME_FUNCTION +# dynaforms/fields/currency.xml +#: dropdown - PME_FUNCTION +msgid "[dynaforms/fields/currency.xml?PME_FUNCTION] Function" +msgstr "Function" + +# dynaforms/fields/currency.xml?PME_FUNCTION-'' +# dynaforms/fields/currency.xml +#: dropdown - PME_FUNCTION - '' +msgid "[dynaforms/fields/currency.xml?PME_FUNCTION-'']" +msgstr "None" + +# dynaforms/fields/currency.xml?PME_FUNCTION-sum +# dynaforms/fields/currency.xml +#: dropdown - PME_FUNCTION - sum +msgid "[dynaforms/fields/currency.xml?PME_FUNCTION-sum]" +msgstr "SUM" + +# dynaforms/fields/currency.xml?PME_FUNCTION-avg +# dynaforms/fields/currency.xml +#: dropdown - PME_FUNCTION - avg +msgid "[dynaforms/fields/currency.xml?PME_FUNCTION-avg]" +msgstr "AVG" + +# dynaforms/fields/currency.xml?PME_SUBTITLE2 +# dynaforms/fields/currency.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/currency.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/currency.xml?PME_SQLCONNECTION +# dynaforms/fields/currency.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/currency.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/currency.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/currency.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/currency.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/currency.xml?PME_XMLNODE_VALUE +# dynaforms/fields/currency.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/currency.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/currency.xml?BTN_CANCEL +# dynaforms/fields/currency.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/currency.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/currency.xml?PME_ACCEPT +# dynaforms/fields/currency.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/currency.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/date.xml?PME_TITLE +# dynaforms/fields/date.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/date.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/date.xml?PME_XMLNODE_NAME +# dynaforms/fields/date.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/date.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/date.xml?PME_LABEL +# dynaforms/fields/date.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/date.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/date.xml?PME_RELATIVEDATE +# dynaforms/fields/date.xml +#: dropdown - PME_RELATIVEDATE +msgid "Type of date range" +msgstr "Type of date range" + +# dynaforms/fields/date.xml?PME_RELATIVEDATE-1 +# dynaforms/fields/date.xml +#: dropdown - PME_RELATIVEDATE - 1 +msgid "[dynaforms/fields/date.xml?PME_RELATIVEDATE-1]" +msgstr "Relative Dates" + +# dynaforms/fields/date.xml?PME_RELATIVEDATE-'' +# dynaforms/fields/date.xml +#: dropdown - PME_RELATIVEDATE - '' +msgid "[dynaforms/fields/date.xml?PME_RELATIVEDATE-'']" +msgstr "Static Dates" + +# dynaforms/fields/date.xml?PME_SUBTITLE3 +# dynaforms/fields/date.xml +#: title - PME_SUBTITLE3 +msgid "Start and End Dates" +msgstr "Start and End Dates" + +# dynaforms/fields/date.xml?PME_STARTDATE +# dynaforms/fields/date.xml +#: date - PME_STARTDATE +msgid "[dynaforms/fields/date.xml?PME_STARTDATE] Start Date" +msgstr "Start Date" + +# dynaforms/fields/date.xml?PME_ENDDATE +# dynaforms/fields/date.xml +#: date - PME_ENDDATE +msgid "[dynaforms/fields/date.xml?PME_ENDDATE] End Date" +msgstr "End Date" + +# dynaforms/fields/date.xml?PME_SUBTITLE3a +# dynaforms/fields/date.xml +#: title - PME_SUBTITLE3a +msgid "Relative Start and End Dates" +msgstr "Relative Start and End Dates" + +# dynaforms/fields/date.xml?PMED_AFTERBEFORE_DESC +# dynaforms/fields/date.xml +#: subtitle - PMED_AFTERBEFORE_DESC +msgid "<b>Data Codes:</b> A number followed by a letter to indicate the unit of time (d=day m=month y=year).<br/>Use negative numbers for past dates and positive numbers for future dates<br /> \t<b>NOTE.</b> When these relative dates are set have the priority, leave empty to use <i>Start and End dates</i>." +msgstr "<b>Data Codes:</b> A number followed by a letter to indicate the unit of time (d=day m=month y=year).<br/>Use negative numbers for past dates and positive numbers for future dates<br /> \t<b>NOTE.</b> When these relative dates are set have the priority, leave empty to use <i>Start and End dates</i>." + +# dynaforms/fields/date.xml?PME_BEFOREDATE +# dynaforms/fields/date.xml +#: text - PME_BEFOREDATE +msgid "Start Relative Date" +msgstr "Start Relative Date" + +# dynaforms/fields/date.xml?PME_AFTERDATE +# dynaforms/fields/date.xml +#: text - PME_AFTERDATE +msgid "End Relative Date" +msgstr "End Relative Date" + +# dynaforms/fields/date.xml?PME_SUBTITLE3x +# dynaforms/fields/date.xml +#: subtitle - PME_SUBTITLE3x +msgid "<b>Mask: </b>%Y=Year, %y=year (the two last digits at year), %m=Month, %d=Day" +msgstr "<b>Mask: </b>%Y=Year, %y=year (the two last digits at year), %m=Month, %d=Day" + +# dynaforms/fields/date.xml?PME_SUBTITLE3xl +# dynaforms/fields/date.xml +#: link - PME_SUBTITLE3xl +msgid "+Masks" +msgstr "+Masks" + +# dynaforms/fields/date.xml?PME_MASK +# dynaforms/fields/date.xml +#: text - PME_MASK +msgid "[dynaforms/fields/date.xml?PME_MASK] Mask" +msgstr "Mask" + +# dynaforms/fields/date.xml?PME_SUBTITLE3b +# dynaforms/fields/date.xml +#: title - PME_SUBTITLE3b +msgid "[dynaforms/fields/date.xml?PME_SUBTITLE3b] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/date.xml?PME_EDITABLE +# dynaforms/fields/date.xml +#: checkbox - PME_EDITABLE +msgid "Editable" +msgstr "Editable" + +# dynaforms/fields/date.xml?PME_REQUIRED +# dynaforms/fields/date.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/date.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/date.xml?PME_READONLY +# dynaforms/fields/date.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/date.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/date.xml?PME_SHOWTIME +# dynaforms/fields/date.xml +#: checkbox - PME_SHOWTIME +msgid "Show time" +msgstr "Show time" + +# dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL +# dynaforms/fields/date.xml +#: dropdown - PME_DEFAULTVALUE_SEL +msgid "Default" +msgstr "Default" + +# dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-empty +# dynaforms/fields/date.xml +#: dropdown - PME_DEFAULTVALUE_SEL - empty +msgid "[dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-empty]" +msgstr "Empty" + +# dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-today +# dynaforms/fields/date.xml +#: dropdown - PME_DEFAULTVALUE_SEL - today +msgid "[dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-today]" +msgstr "Today" + +# dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-val +# dynaforms/fields/date.xml +#: dropdown - PME_DEFAULTVALUE_SEL - val +msgid "[dynaforms/fields/date.xml?PME_DEFAULTVALUE_SEL-val]" +msgstr "Value" + +# dynaforms/fields/date.xml?PME_DEFAULTVALUE +# dynaforms/fields/date.xml +#: date - PME_DEFAULTVALUE +msgid "[dynaforms/fields/date.xml?PME_DEFAULTVALUE]" +msgstr "" + +# dynaforms/fields/date.xml?PME_HINT +# dynaforms/fields/date.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/date.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/date.xml?PME_SUBTITLE +# dynaforms/fields/date.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/date.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/date.xml?PME_SIZE +# dynaforms/fields/date.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/date.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/date.xml?PME_MODE +# dynaforms/fields/date.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/date.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/date.xml?PME_MODE-edit +# dynaforms/fields/date.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/date.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/date.xml?PME_MODE-view +# dynaforms/fields/date.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/date.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/date.xml?BTN_CANCEL +# dynaforms/fields/date.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/date.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/date.xml?PME_ACCEPT +# dynaforms/fields/date.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/date.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/dropdown.xml?PME_TITLE +# dynaforms/fields/dropdown.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/dropdown.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/dropdown.xml?PME_XMLNODE_NAME +# dynaforms/fields/dropdown.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/dropdown.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/dropdown.xml?PME_LABEL +# dynaforms/fields/dropdown.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/dropdown.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/dropdown.xml?PME_SUBTITLE3 +# dynaforms/fields/dropdown.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/dropdown.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/dropdown.xml?PME_REQUIRED +# dynaforms/fields/dropdown.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/dropdown.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/dropdown.xml?PME_READONLY +# dynaforms/fields/dropdown.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/dropdown.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/dropdown.xml?PME_DEPENDENTFIELDS +# dynaforms/fields/dropdown.xml +#: listbox - PME_DEPENDENTFIELDS +msgid "Dependent Fields" +msgstr "Dependent Fields" + +# dynaforms/fields/dropdown.xml?PME_DEPENDENTFIELDS-'' +# dynaforms/fields/dropdown.xml +#: listbox - PME_DEPENDENTFIELDS - '' +msgid "[dynaforms/fields/dropdown.xml?PME_DEPENDENTFIELDS-'']" +msgstr "(none)" + +# dynaforms/fields/dropdown.xml?PME_DEFAULTVALUE +# dynaforms/fields/dropdown.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/dropdown.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/dropdown.xml?PME_SAVELABEL +# dynaforms/fields/dropdown.xml +#: checkbox - PME_SAVELABEL +msgid "Save label of selected value in variable" +msgstr "Save label of selected value in variable" + +# dynaforms/fields/dropdown.xml?PME_HINT +# dynaforms/fields/dropdown.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/dropdown.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/dropdown.xml?PME_SUBTITLE +# dynaforms/fields/dropdown.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/dropdown.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/dropdown.xml?PME_MODE +# dynaforms/fields/dropdown.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/dropdown.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/dropdown.xml?PME_MODE-edit +# dynaforms/fields/dropdown.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/dropdown.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/dropdown.xml?PME_MODE-view +# dynaforms/fields/dropdown.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/dropdown.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/dropdown.xml?PME_SUBTITLE2 +# dynaforms/fields/dropdown.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/dropdown.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/dropdown.xml?PME_SQLCONNECTION +# dynaforms/fields/dropdown.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/dropdown.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/dropdown.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/dropdown.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/dropdown.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/dropdown.xml?PME_XMLNODE_VALUE +# dynaforms/fields/dropdown.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/dropdown.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/dropdown.xml?BTN_CANCEL +# dynaforms/fields/dropdown.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/dropdown.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/dropdown.xml?PME_ACCEPT +# dynaforms/fields/dropdown.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/dropdown.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/file.xml?PME_TITLE +# dynaforms/fields/file.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/file.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/file.xml?PME_XMLNODE_NAME +# dynaforms/fields/file.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/file.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/file.xml?PME_LABEL +# dynaforms/fields/file.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/file.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/file.xml?PME_INPUT +# dynaforms/fields/file.xml +#: dropdown - PME_INPUT +msgid "Input" +msgstr "Input" + +# dynaforms/fields/file.xml?PME_INPUT-'' +# dynaforms/fields/file.xml +#: dropdown - PME_INPUT - '' +msgid "[dynaforms/fields/file.xml?PME_INPUT-'']" +msgstr "None" + +# dynaforms/fields/file.xml?PME_SUBTITLE3b +# dynaforms/fields/file.xml +#: title - PME_SUBTITLE3b +msgid "[dynaforms/fields/file.xml?PME_SUBTITLE3b] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/file.xml?PME_REQUIRED +# dynaforms/fields/file.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/file.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/file.xml?PME_HINT +# dynaforms/fields/file.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/file.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/file.xml?BTN_CANCEL +# dynaforms/fields/file.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/file.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/file.xml?PME_ACCEPT +# dynaforms/fields/file.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/file.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/grid.xml?PME_TITLE +# dynaforms/fields/grid.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/grid.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/grid.xml?PME_XMLNODE_NAME +# dynaforms/fields/grid.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/grid.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/grid.xml?PME_XMLGRID +# dynaforms/fields/grid.xml +#: dropdown - PME_XMLGRID +msgid "Grid" +msgstr "Grid" + +# dynaforms/fields/grid.xml?PME_ADDROW +# dynaforms/fields/grid.xml +#: checkbox - PME_ADDROW +msgid "Add new rows" +msgstr "Add new rows" + +# dynaforms/fields/grid.xml?PME_DELETEROW +# dynaforms/fields/grid.xml +#: checkbox - PME_DELETEROW +msgid "Delete rows" +msgstr "Delete rows" + +# dynaforms/fields/grid.xml?BTN_CANCEL +# dynaforms/fields/grid.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/grid.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/grid.xml?PME_ACCEPT +# dynaforms/fields/grid.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/grid.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/hidden.xml?PME_TITLE +# dynaforms/fields/hidden.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/hidden.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/hidden.xml?PME_XMLNODE_NAME +# dynaforms/fields/hidden.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/hidden.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/hidden.xml?PME_DEFAULTVALUE +# dynaforms/fields/hidden.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/hidden.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/hidden.xml?PME_MODE +# dynaforms/fields/hidden.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/hidden.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/hidden.xml?PME_MODE-edit +# dynaforms/fields/hidden.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/hidden.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/hidden.xml?PME_MODE-view +# dynaforms/fields/hidden.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/hidden.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/hidden.xml?PME_SUBTITLE2 +# dynaforms/fields/hidden.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/hidden.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/hidden.xml?PME_SQLCONNECTION +# dynaforms/fields/hidden.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/hidden.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/hidden.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/hidden.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/hidden.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/hidden.xml?PME_XMLNODE_VALUE +# dynaforms/fields/hidden.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/hidden.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/hidden.xml?BTN_CANCEL +# dynaforms/fields/hidden.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/hidden.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/hidden.xml?PME_ACCEPT +# dynaforms/fields/hidden.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/hidden.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/javascript.xml?PME_TITLE +# dynaforms/fields/javascript.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/javascript.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/javascript.xml?PME_XMLNODE_NAME +# dynaforms/fields/javascript.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/javascript.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/javascript.xml?PME_CODE +# dynaforms/fields/javascript.xml +#: textarea - PME_CODE +msgid "[dynaforms/fields/javascript.xml?PME_CODE] Code" +msgstr "Code" + +# dynaforms/fields/javascript.xml?BTN_CANCEL +# dynaforms/fields/javascript.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/javascript.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/javascript.xml?PME_ACCEPT +# dynaforms/fields/javascript.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/javascript.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/link.xml?PME_TITLE +# dynaforms/fields/link.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/link.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/link.xml?PME_XMLNODE_NAME +# dynaforms/fields/link.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/link.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/link.xml?PME_LABEL +# dynaforms/fields/link.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/link.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/link.xml?PME_SUBTITLE3 +# dynaforms/fields/link.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/link.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/link.xml?PME_LINK +# dynaforms/fields/link.xml +#: text - PME_LINK +msgid "Link" +msgstr "Link" + +# dynaforms/fields/link.xml?PME_TARGET_SEL +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL] Target" +msgstr "Target" + +# dynaforms/fields/link.xml?PME_TARGET_SEL-_blank +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL - _blank +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL-_blank]" +msgstr "Blank" + +# dynaforms/fields/link.xml?PME_TARGET_SEL-_self +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL - _self +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL-_self]" +msgstr "Self" + +# dynaforms/fields/link.xml?PME_TARGET_SEL-_parent +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL - _parent +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL-_parent]" +msgstr "Parent" + +# dynaforms/fields/link.xml?PME_TARGET_SEL-_top +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL - _top +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL-_top]" +msgstr "Top" + +# dynaforms/fields/link.xml?PME_TARGET_SEL-'' +# dynaforms/fields/link.xml +#: dropdown - PME_TARGET_SEL - '' +msgid "[dynaforms/fields/link.xml?PME_TARGET_SEL-'']" +msgstr "Framename" + +# dynaforms/fields/link.xml?PME_TARGET +# dynaforms/fields/link.xml +#: text - PME_TARGET +msgid "[dynaforms/fields/link.xml?PME_TARGET]" +msgstr "" + +# dynaforms/fields/link.xml?PME_VALUE +# dynaforms/fields/link.xml +#: text - PME_VALUE +msgid "[dynaforms/fields/link.xml?PME_VALUE] Value" +msgstr "Value" + +# dynaforms/fields/link.xml?PME_HINT +# dynaforms/fields/link.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/link.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/link.xml?BTN_CANCEL +# dynaforms/fields/link.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/link.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/link.xml?PME_ACCEPT +# dynaforms/fields/link.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/link.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/listbox.xml?PME_TITLE +# dynaforms/fields/listbox.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/listbox.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/listbox.xml?PME_XMLNODE_NAME +# dynaforms/fields/listbox.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/listbox.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/listbox.xml?PME_LABEL +# dynaforms/fields/listbox.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/listbox.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/listbox.xml?PME_SUBTITLE3 +# dynaforms/fields/listbox.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/listbox.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/listbox.xml?PME_REQUIRED +# dynaforms/fields/listbox.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/listbox.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/listbox.xml?PME_DEFAULTVALUE +# dynaforms/fields/listbox.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/listbox.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/listbox.xml?PME_HINT +# dynaforms/fields/listbox.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/listbox.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/listbox.xml?PME_SUBTITLE +# dynaforms/fields/listbox.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/listbox.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/listbox.xml?PME_SIZE +# dynaforms/fields/listbox.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/listbox.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/listbox.xml?PME_MODE +# dynaforms/fields/listbox.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/listbox.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/listbox.xml?PME_MODE-edit +# dynaforms/fields/listbox.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/listbox.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/listbox.xml?PME_MODE-view +# dynaforms/fields/listbox.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/listbox.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/listbox.xml?PME_SUBTITLE2 +# dynaforms/fields/listbox.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/listbox.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/listbox.xml?PME_SQLCONNECTION +# dynaforms/fields/listbox.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/listbox.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/listbox.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/listbox.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/listbox.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/listbox.xml?PME_XMLNODE_VALUE +# dynaforms/fields/listbox.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/listbox.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/listbox.xml?BTN_CANCEL +# dynaforms/fields/listbox.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/listbox.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/listbox.xml?PME_ACCEPT +# dynaforms/fields/listbox.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/listbox.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/password.xml?PME_TITLE +# dynaforms/fields/password.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/password.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/password.xml?PME_XMLNODE_NAME +# dynaforms/fields/password.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/password.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/password.xml?PME_LABEL +# dynaforms/fields/password.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/password.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/password.xml?PME_SUBTITLE3 +# dynaforms/fields/password.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/password.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/password.xml?PME_MAXLENGTH +# dynaforms/fields/password.xml +#: text - PME_MAXLENGTH +msgid "[dynaforms/fields/password.xml?PME_MAXLENGTH] Max. Length" +msgstr "Max. Length" + +# dynaforms/fields/password.xml?PME_REQUIRED +# dynaforms/fields/password.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/password.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/password.xml?PME_AUTOCOMPLETE +# dynaforms/fields/password.xml +#: checkbox - PME_AUTOCOMPLETE +msgid "Autocomplete" +msgstr "Autocomplete" + +# dynaforms/fields/password.xml?PME_READONLY +# dynaforms/fields/password.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/password.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/password.xml?PME_HINT +# dynaforms/fields/password.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/password.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/password.xml?PME_SUBTITLE +# dynaforms/fields/password.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/password.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/password.xml?PME_SIZE +# dynaforms/fields/password.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/password.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/password.xml?PME_MODE +# dynaforms/fields/password.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/password.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/password.xml?PME_MODE-edit +# dynaforms/fields/password.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/password.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/password.xml?PME_MODE-view +# dynaforms/fields/password.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/password.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/password.xml?BTN_CANCEL +# dynaforms/fields/password.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/password.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/password.xml?PME_ACCEPT +# dynaforms/fields/password.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/password.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/percentage.xml?PME_TITLE +# dynaforms/fields/percentage.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/percentage.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/percentage.xml?PME_XMLNODE_NAME +# dynaforms/fields/percentage.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/percentage.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/percentage.xml?PME_LABEL +# dynaforms/fields/percentage.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/percentage.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/percentage.xml?PME_SUBTITLE3 +# dynaforms/fields/percentage.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/percentage.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/percentage.xml?PME_MAXLENGTH +# dynaforms/fields/percentage.xml +#: text - PME_MAXLENGTH +msgid "[dynaforms/fields/percentage.xml?PME_MAXLENGTH] Max. Length" +msgstr "Max. Length" + +# dynaforms/fields/percentage.xml?PME_VALIDATE +# dynaforms/fields/percentage.xml +#: dropdown - PME_VALIDATE +msgid "[dynaforms/fields/percentage.xml?PME_VALIDATE] Validate" +msgstr "Validate" + +# dynaforms/fields/percentage.xml?PME_VALIDATE-Int +# dynaforms/fields/percentage.xml +#: dropdown - PME_VALIDATE - Int +msgid "[dynaforms/fields/percentage.xml?PME_VALIDATE-Int]" +msgstr "Integer " + +# dynaforms/fields/percentage.xml?PME_VALIDATE-Real +# dynaforms/fields/percentage.xml +#: dropdown - PME_VALIDATE - Real +msgid "[dynaforms/fields/percentage.xml?PME_VALIDATE-Real]" +msgstr "Real Number" + +# dynaforms/fields/percentage.xml?PME_MASK +# dynaforms/fields/percentage.xml +#: text - PME_MASK +msgid "[dynaforms/fields/percentage.xml?PME_MASK] Mask" +msgstr "Mask" + +# dynaforms/fields/percentage.xml?PME_REQUIRED +# dynaforms/fields/percentage.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/percentage.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/percentage.xml?PME_READONLY +# dynaforms/fields/percentage.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/percentage.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/percentage.xml?PME_DEFAULTVALUE +# dynaforms/fields/percentage.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/percentage.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/percentage.xml?PME_HINT +# dynaforms/fields/percentage.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/percentage.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/percentage.xml?PME_SUBTITLE +# dynaforms/fields/percentage.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/percentage.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/percentage.xml?PME_SIZE +# dynaforms/fields/percentage.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/percentage.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/percentage.xml?PME_MODE +# dynaforms/fields/percentage.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/percentage.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/percentage.xml?PME_MODE-edit +# dynaforms/fields/percentage.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/percentage.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/percentage.xml?PME_MODE-view +# dynaforms/fields/percentage.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/percentage.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/percentage.xml?PME_SUBTITLE_OP +# dynaforms/fields/percentage.xml +#: title - PME_SUBTITLE_OP +msgid "[dynaforms/fields/percentage.xml?PME_SUBTITLE_OP] Operations" +msgstr "Operations" + +# dynaforms/fields/percentage.xml?PME_FORMULA +# dynaforms/fields/percentage.xml +#: text - PME_FORMULA +msgid "[dynaforms/fields/percentage.xml?PME_FORMULA] Formula" +msgstr "Formula" + +# dynaforms/fields/percentage.xml?PME_FUNCTION +# dynaforms/fields/percentage.xml +#: dropdown - PME_FUNCTION +msgid "[dynaforms/fields/percentage.xml?PME_FUNCTION] Function" +msgstr "Function" + +# dynaforms/fields/percentage.xml?PME_FUNCTION-'' +# dynaforms/fields/percentage.xml +#: dropdown - PME_FUNCTION - '' +msgid "[dynaforms/fields/percentage.xml?PME_FUNCTION-'']" +msgstr "None" + +# dynaforms/fields/percentage.xml?PME_FUNCTION-sum +# dynaforms/fields/percentage.xml +#: dropdown - PME_FUNCTION - sum +msgid "[dynaforms/fields/percentage.xml?PME_FUNCTION-sum]" +msgstr "SUM" + +# dynaforms/fields/percentage.xml?PME_FUNCTION-avg +# dynaforms/fields/percentage.xml +#: dropdown - PME_FUNCTION - avg +msgid "[dynaforms/fields/percentage.xml?PME_FUNCTION-avg]" +msgstr "AVG" + +# dynaforms/fields/percentage.xml?PME_SUBTITLE2 +# dynaforms/fields/percentage.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/percentage.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/percentage.xml?PME_SQLCONNECTION +# dynaforms/fields/percentage.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/percentage.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/percentage.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/percentage.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/percentage.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/percentage.xml?PME_XMLNODE_VALUE +# dynaforms/fields/percentage.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/percentage.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/percentage.xml?BTN_CANCEL +# dynaforms/fields/percentage.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/percentage.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/percentage.xml?PME_ACCEPT +# dynaforms/fields/percentage.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/percentage.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/radiogroup.xml?PME_TITLE +# dynaforms/fields/radiogroup.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/radiogroup.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/radiogroup.xml?PME_XMLNODE_NAME +# dynaforms/fields/radiogroup.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/radiogroup.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/radiogroup.xml?PME_LABEL +# dynaforms/fields/radiogroup.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/radiogroup.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/radiogroup.xml?PME_SUBTITLE3 +# dynaforms/fields/radiogroup.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/radiogroup.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/radiogroup.xml?PME_REQUIRED +# dynaforms/fields/radiogroup.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/radiogroup.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/radiogroup.xml?PME_DEFAULTVALUE +# dynaforms/fields/radiogroup.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/radiogroup.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/radiogroup.xml?PME_HINT +# dynaforms/fields/radiogroup.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/radiogroup.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/radiogroup.xml?PME_SUBTITLE +# dynaforms/fields/radiogroup.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/radiogroup.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/radiogroup.xml?PME_MODE +# dynaforms/fields/radiogroup.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/radiogroup.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/radiogroup.xml?PME_MODE-edit +# dynaforms/fields/radiogroup.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/radiogroup.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/radiogroup.xml?PME_MODE-view +# dynaforms/fields/radiogroup.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/radiogroup.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/radiogroup.xml?PME_SUBTITLE2 +# dynaforms/fields/radiogroup.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/radiogroup.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/radiogroup.xml?PME_SQLCONNECTION +# dynaforms/fields/radiogroup.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/radiogroup.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/radiogroup.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/radiogroup.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/radiogroup.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/radiogroup.xml?PME_XMLNODE_VALUE +# dynaforms/fields/radiogroup.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/radiogroup.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/radiogroup.xml?BTN_CANCEL +# dynaforms/fields/radiogroup.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/radiogroup.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/radiogroup.xml?PME_ACCEPT +# dynaforms/fields/radiogroup.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/radiogroup.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/radiogroupview.xml?XMLNODE_NAME +# dynaforms/fields/radiogroupview.xml +#: text - XMLNODE_NAME +msgid "[dynaforms/fields/radiogroupview.xml?XMLNODE_NAME] Field name" +msgstr "Field name" + +# dynaforms/fields/radiogroupview.xml?LABEL +# dynaforms/fields/radiogroupview.xml +#: text - LABEL +msgid "[dynaforms/fields/radiogroupview.xml?LABEL] Label" +msgstr "Label" + +# dynaforms/fields/radiogroupview.xml?REQUIRED +# dynaforms/fields/radiogroupview.xml +#: checkbox - REQUIRED +msgid "[dynaforms/fields/radiogroupview.xml?REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/radiogroupview.xml?DEFAULTVALUE +# dynaforms/fields/radiogroupview.xml +#: text - DEFAULTVALUE +msgid "[dynaforms/fields/radiogroupview.xml?DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/radiogroupview.xml?SUBTITLE +# dynaforms/fields/radiogroupview.xml +#: title - SUBTITLE +msgid "[dynaforms/fields/radiogroupview.xml?SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/radiogroupview.xml?ENABLEHTML +# dynaforms/fields/radiogroupview.xml +#: checkbox - ENABLEHTML +msgid "EnableHtml" +msgstr "EnableHtml" + +# dynaforms/fields/radiogroupview.xml?ACCEPT +# dynaforms/fields/radiogroupview.xml +#: button - ACCEPT +msgid "[dynaforms/fields/radiogroupview.xml?ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/reset.xml?PME_TITLE +# dynaforms/fields/reset.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/reset.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/reset.xml?PME_XMLNODE_NAME +# dynaforms/fields/reset.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/reset.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/reset.xml?PME_LABEL +# dynaforms/fields/reset.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/reset.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/reset.xml?BTN_CANCEL +# dynaforms/fields/reset.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/reset.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/reset.xml?PME_ACCEPT +# dynaforms/fields/reset.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/reset.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/submit.xml?PME_TITLE +# dynaforms/fields/submit.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/submit.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/submit.xml?PME_XMLNODE_NAME +# dynaforms/fields/submit.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/submit.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/submit.xml?PME_LABEL +# dynaforms/fields/submit.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/submit.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/submit.xml?PME_ONCLICK +# dynaforms/fields/submit.xml +#: text - PME_ONCLICK +msgid "Javascript to Execute On Click" +msgstr "Javascript to Execute On Click" + +# dynaforms/fields/submit.xml?BTN_CANCEL +# dynaforms/fields/submit.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/submit.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/submit.xml?PME_ACCEPT +# dynaforms/fields/submit.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/submit.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/subtitle.xml?PME_TITLE +# dynaforms/fields/subtitle.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/subtitle.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/subtitle.xml?PME_XMLNODE_NAME +# dynaforms/fields/subtitle.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/subtitle.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/subtitle.xml?PME_LABEL +# dynaforms/fields/subtitle.xml +#: textarea - PME_LABEL +msgid "[dynaforms/fields/subtitle.xml?PME_LABEL] Content" +msgstr "Content" + +# dynaforms/fields/subtitle.xml?PME_SUBTITLE +# dynaforms/fields/subtitle.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/subtitle.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/subtitle.xml?PME_ENABLEHTML +# dynaforms/fields/subtitle.xml +#: checkbox - PME_ENABLEHTML +msgid "[dynaforms/fields/subtitle.xml?PME_ENABLEHTML] Enable Html" +msgstr "Enable Html" + +# dynaforms/fields/subtitle.xml?BTN_CANCEL +# dynaforms/fields/subtitle.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/subtitle.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/subtitle.xml?PME_ACCEPT +# dynaforms/fields/subtitle.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/subtitle.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/suggest.xml?PME_TITLE +# dynaforms/fields/suggest.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/suggest.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/suggest.xml?PME_XMLNODE_NAME +# dynaforms/fields/suggest.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/suggest.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/suggest.xml?PME_LABEL +# dynaforms/fields/suggest.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/suggest.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/suggest.xml?PME_SUBTITLE3 +# dynaforms/fields/suggest.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/suggest.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/suggest.xml?PME_REQUIRED +# dynaforms/fields/suggest.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/suggest.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/suggest.xml?PME_DEFAULTVALUE +# dynaforms/fields/suggest.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/suggest.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/suggest.xml?PME_HINT +# dynaforms/fields/suggest.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/suggest.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/suggest.xml?PME_SUBTITLE +# dynaforms/fields/suggest.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/suggest.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/suggest.xml?PME_SIZE +# dynaforms/fields/suggest.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/suggest.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/suggest.xml?PME_MODE +# dynaforms/fields/suggest.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/suggest.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/suggest.xml?PME_MODE-edit +# dynaforms/fields/suggest.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/suggest.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/suggest.xml?PME_MODE-view +# dynaforms/fields/suggest.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/suggest.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/suggest.xml?PME_SUBTITLE2 +# dynaforms/fields/suggest.xml +#: title - PME_SUBTITLE2 +msgid "Autosuggest behaviour" +msgstr "Autosuggest behaviour" + +# dynaforms/fields/suggest.xml?PME_SQLCONNECTION +# dynaforms/fields/suggest.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/suggest.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/suggest.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/suggest.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/suggest.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/suggest.xml?PME_XMLNODE_VALUE +# dynaforms/fields/suggest.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/suggest.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/suggest.xml?PME_MAXRESULTS +# dynaforms/fields/suggest.xml +#: text - PME_MAXRESULTS +msgid "Max Results" +msgstr "Max Results" + +# dynaforms/fields/suggest.xml?PME_SHOWNORESULTS +# dynaforms/fields/suggest.xml +#: checkbox - PME_SHOWNORESULTS +msgid "Show no results message" +msgstr "Show no results message" + +# dynaforms/fields/suggest.xml?PME_SAVELABEL +# dynaforms/fields/suggest.xml +#: dropdown - PME_SAVELABEL +msgid "Save on dynaform" +msgstr "Save on dynaform" + +# dynaforms/fields/suggest.xml?PME_SAVELABEL-0 +# dynaforms/fields/suggest.xml +#: dropdown - PME_SAVELABEL - 0 +msgid "[dynaforms/fields/suggest.xml?PME_SAVELABEL-0]" +msgstr "Id" + +# dynaforms/fields/suggest.xml?PME_SAVELABEL-1 +# dynaforms/fields/suggest.xml +#: dropdown - PME_SAVELABEL - 1 +msgid "[dynaforms/fields/suggest.xml?PME_SAVELABEL-1]" +msgstr "Value" + +# dynaforms/fields/suggest.xml?PME_STORE_NEW_ENTRY +# dynaforms/fields/suggest.xml +#: checkbox - PME_STORE_NEW_ENTRY +msgid "Store new entry" +msgstr "Store new entry" + +# dynaforms/fields/suggest.xml?PME_TABLE +# dynaforms/fields/suggest.xml +#: dropdown - PME_TABLE +msgid "Table" +msgstr "Table" + +# dynaforms/fields/suggest.xml?PME_PRIMARY_KEY +# dynaforms/fields/suggest.xml +#: dropdown - PME_PRIMARY_KEY +msgid "[dynaforms/fields/suggest.xml?PME_PRIMARY_KEY] Primary Key" +msgstr "Primary Key" + +# dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE +# dynaforms/fields/suggest.xml +#: dropdown - PME_PRIMARY_KEY_TYPE +msgid "[dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE] Type" +msgstr "Type" + +# dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-0 +# dynaforms/fields/suggest.xml +#: dropdown - PME_PRIMARY_KEY_TYPE - 0 +msgid "[dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-0]" +msgstr "" + +# dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-int +# dynaforms/fields/suggest.xml +#: dropdown - PME_PRIMARY_KEY_TYPE - int +msgid "[dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-int]" +msgstr "Integer" + +# dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-varchar +# dynaforms/fields/suggest.xml +#: dropdown - PME_PRIMARY_KEY_TYPE - varchar +msgid "[dynaforms/fields/suggest.xml?PME_PRIMARY_KEY_TYPE-varchar]" +msgstr "Varchar" + +# dynaforms/fields/suggest.xml?BTN_CANCEL +# dynaforms/fields/suggest.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/suggest.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/suggest.xml?PME_ACCEPT +# dynaforms/fields/suggest.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/suggest.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/text.xml?PME_TITLE +# dynaforms/fields/text.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/text.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/text.xml?PME_XMLNODE_NAME +# dynaforms/fields/text.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/text.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/text.xml?PME_LABEL +# dynaforms/fields/text.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/text.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/text.xml?PME_SUBTITLE3 +# dynaforms/fields/text.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/text.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/text.xml?PME_MAXLENGTH +# dynaforms/fields/text.xml +#: text - PME_MAXLENGTH +msgid "[dynaforms/fields/text.xml?PME_MAXLENGTH] Max. Length" +msgstr "Max. Length" + +# dynaforms/fields/text.xml?PME_VALIDATE +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE +msgid "[dynaforms/fields/text.xml?PME_VALIDATE] Validate" +msgstr "Validate" + +# dynaforms/fields/text.xml?PME_VALIDATE-Any +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Any +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Any]" +msgstr "Any" + +# dynaforms/fields/text.xml?PME_VALIDATE-Alpha +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Alpha +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Alpha]" +msgstr "Alphabetic" + +# dynaforms/fields/text.xml?PME_VALIDATE-AlphaNum +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - AlphaNum +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-AlphaNum]" +msgstr "Alphanumeric" + +# dynaforms/fields/text.xml?PME_VALIDATE-Int +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Int +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Int]" +msgstr "Integer" + +# dynaforms/fields/text.xml?PME_VALIDATE-Real +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Real +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Real]" +msgstr "Real Number" + +# dynaforms/fields/text.xml?PME_VALIDATE-Email +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Email +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Email]" +msgstr "Email" + +# dynaforms/fields/text.xml?PME_VALIDATE-Login +# dynaforms/fields/text.xml +#: dropdown - PME_VALIDATE - Login +msgid "[dynaforms/fields/text.xml?PME_VALIDATE-Login]" +msgstr "Login" + +# dynaforms/fields/text.xml?PME_MASK +# dynaforms/fields/text.xml +#: text - PME_MASK +msgid "[dynaforms/fields/text.xml?PME_MASK] Mask" +msgstr "Mask" + +# dynaforms/fields/text.xml?PME_STRTO +# dynaforms/fields/text.xml +#: dropdown - PME_STRTO +msgid "Text transform to" +msgstr "Text transform to" + +# dynaforms/fields/text.xml?PME_STRTO-'' +# dynaforms/fields/text.xml +#: dropdown - PME_STRTO - '' +msgid "[dynaforms/fields/text.xml?PME_STRTO-'']" +msgstr "" + +# dynaforms/fields/text.xml?PME_STRTO-UPPER +# dynaforms/fields/text.xml +#: dropdown - PME_STRTO - UPPER +msgid "[dynaforms/fields/text.xml?PME_STRTO-UPPER]" +msgstr "UPPER" + +# dynaforms/fields/text.xml?PME_STRTO-LOWER +# dynaforms/fields/text.xml +#: dropdown - PME_STRTO - LOWER +msgid "[dynaforms/fields/text.xml?PME_STRTO-LOWER]" +msgstr "LOWER" + +# dynaforms/fields/text.xml?PME_REQUIRED +# dynaforms/fields/text.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/text.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/text.xml?PME_READONLY +# dynaforms/fields/text.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/text.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/text.xml?PME_DEPENDENTFIELDS +# dynaforms/fields/text.xml +#: listbox - PME_DEPENDENTFIELDS +msgid "[dynaforms/fields/text.xml?PME_DEPENDENTFIELDS] Dependent Fields" +msgstr "Dependent Fields" + +# dynaforms/fields/text.xml?PME_DEPENDENTFIELDS-'' +# dynaforms/fields/text.xml +#: listbox - PME_DEPENDENTFIELDS - '' +msgid "[dynaforms/fields/text.xml?PME_DEPENDENTFIELDS-'']" +msgstr "(none)" + +# dynaforms/fields/text.xml?PME_DEFAULTVALUE +# dynaforms/fields/text.xml +#: text - PME_DEFAULTVALUE +msgid "[dynaforms/fields/text.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/text.xml?PME_HINT +# dynaforms/fields/text.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/text.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/text.xml?PME_SUBTITLE +# dynaforms/fields/text.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/text.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/text.xml?PME_SIZE +# dynaforms/fields/text.xml +#: text - PME_SIZE +msgid "[dynaforms/fields/text.xml?PME_SIZE] Size" +msgstr "Size" + +# dynaforms/fields/text.xml?PME_MODE +# dynaforms/fields/text.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/text.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/text.xml?PME_MODE-edit +# dynaforms/fields/text.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/text.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/text.xml?PME_MODE-view +# dynaforms/fields/text.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/text.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/text.xml?PME_SUBTITLE_OP +# dynaforms/fields/text.xml +#: title - PME_SUBTITLE_OP +msgid "[dynaforms/fields/text.xml?PME_SUBTITLE_OP] Operations" +msgstr "Operations" + +# dynaforms/fields/text.xml?PME_FORMULA +# dynaforms/fields/text.xml +#: text - PME_FORMULA +msgid "[dynaforms/fields/text.xml?PME_FORMULA] Formula" +msgstr "Formula" + +# dynaforms/fields/text.xml?PME_FUNCTION +# dynaforms/fields/text.xml +#: dropdown - PME_FUNCTION +msgid "[dynaforms/fields/text.xml?PME_FUNCTION] Function" +msgstr "Function" + +# dynaforms/fields/text.xml?PME_FUNCTION-'' +# dynaforms/fields/text.xml +#: dropdown - PME_FUNCTION - '' +msgid "[dynaforms/fields/text.xml?PME_FUNCTION-'']" +msgstr "None" + +# dynaforms/fields/text.xml?PME_FUNCTION-sum +# dynaforms/fields/text.xml +#: dropdown - PME_FUNCTION - sum +msgid "[dynaforms/fields/text.xml?PME_FUNCTION-sum]" +msgstr "SUM" + +# dynaforms/fields/text.xml?PME_FUNCTION-avg +# dynaforms/fields/text.xml +#: dropdown - PME_FUNCTION - avg +msgid "[dynaforms/fields/text.xml?PME_FUNCTION-avg]" +msgstr "AVG" + +# dynaforms/fields/text.xml?PME_SUBTITLE2 +# dynaforms/fields/text.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/text.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/text.xml?PME_SQLCONNECTION +# dynaforms/fields/text.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/text.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/text.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/text.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/text.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/text.xml?PME_XMLNODE_VALUE +# dynaforms/fields/text.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/text.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/text.xml?BTN_CANCEL +# dynaforms/fields/text.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/text.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/text.xml?PME_ACCEPT +# dynaforms/fields/text.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/text.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/textarea.xml?PME_TITLE +# dynaforms/fields/textarea.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/textarea.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/textarea.xml?PME_XMLNODE_NAME +# dynaforms/fields/textarea.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/textarea.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/textarea.xml?PME_LABEL +# dynaforms/fields/textarea.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/textarea.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/textarea.xml?PME_SUBTITLE3 +# dynaforms/fields/textarea.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/textarea.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/textarea.xml?PME_REQUIRED +# dynaforms/fields/textarea.xml +#: checkbox - PME_REQUIRED +msgid "[dynaforms/fields/textarea.xml?PME_REQUIRED] Required" +msgstr "Required" + +# dynaforms/fields/textarea.xml?PME_READONLY +# dynaforms/fields/textarea.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/textarea.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/textarea.xml?PME_DEFAULTVALUE +# dynaforms/fields/textarea.xml +#: textarea - PME_DEFAULTVALUE +msgid "[dynaforms/fields/textarea.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/textarea.xml?PME_HINT +# dynaforms/fields/textarea.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/textarea.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/textarea.xml?PME_SUBTITLE +# dynaforms/fields/textarea.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/textarea.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/textarea.xml?PME_ROWS +# dynaforms/fields/textarea.xml +#: text - PME_ROWS +msgid "[dynaforms/fields/textarea.xml?PME_ROWS] Rows" +msgstr "Rows" + +# dynaforms/fields/textarea.xml?PME_COLS +# dynaforms/fields/textarea.xml +#: text - PME_COLS +msgid "Columns" +msgstr "Columns" + +# dynaforms/fields/textarea.xml?PME_MODE +# dynaforms/fields/textarea.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/textarea.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/textarea.xml?PME_MODE-edit +# dynaforms/fields/textarea.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/textarea.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/textarea.xml?PME_MODE-view +# dynaforms/fields/textarea.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/textarea.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/textarea.xml?PME_SUBTITLE2 +# dynaforms/fields/textarea.xml +#: title - PME_SUBTITLE2 +msgid "[dynaforms/fields/textarea.xml?PME_SUBTITLE2] Data" +msgstr "Data" + +# dynaforms/fields/textarea.xml?PME_SQLCONNECTION +# dynaforms/fields/textarea.xml +#: dropdown - PME_SQLCONNECTION +msgid "[dynaforms/fields/textarea.xml?PME_SQLCONNECTION] Sql Connection" +msgstr "Sql Connection" + +# dynaforms/fields/textarea.xml?PME_SQLCONNECTION-'' +# dynaforms/fields/textarea.xml +#: dropdown - PME_SQLCONNECTION - '' +msgid "[dynaforms/fields/textarea.xml?PME_SQLCONNECTION-'']" +msgstr "(none)" + +# dynaforms/fields/textarea.xml?PME_XMLNODE_VALUE +# dynaforms/fields/textarea.xml +#: textarea - PME_XMLNODE_VALUE +msgid "[dynaforms/fields/textarea.xml?PME_XMLNODE_VALUE] Sql" +msgstr "Sql" + +# dynaforms/fields/textarea.xml?BTN_CANCEL +# dynaforms/fields/textarea.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/textarea.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/textarea.xml?PME_ACCEPT +# dynaforms/fields/textarea.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/textarea.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/title.xml?PME_TITLE +# dynaforms/fields/title.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/title.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/title.xml?PME_XMLNODE_NAME +# dynaforms/fields/title.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/title.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/title.xml?PME_LABEL +# dynaforms/fields/title.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/title.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/title.xml?PME_SUBTITLE +# dynaforms/fields/title.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/title.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/title.xml?PME_ENABLEHTML +# dynaforms/fields/title.xml +#: checkbox - PME_ENABLEHTML +msgid "[dynaforms/fields/title.xml?PME_ENABLEHTML] Enable Html" +msgstr "Enable Html" + +# dynaforms/fields/title.xml?BTN_CANCEL +# dynaforms/fields/title.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/title.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/title.xml?PME_ACCEPT +# dynaforms/fields/title.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/title.xml?PME_ACCEPT] Save" +msgstr "Save" + +# dynaforms/fields/yesno.xml?PME_TITLE +# dynaforms/fields/yesno.xml +#: title - PME_TITLE +msgid "[dynaforms/fields/yesno.xml?PME_TITLE] Properties" +msgstr "Properties" + +# dynaforms/fields/yesno.xml?PME_XMLNODE_NAME +# dynaforms/fields/yesno.xml +#: text - PME_XMLNODE_NAME +msgid "[dynaforms/fields/yesno.xml?PME_XMLNODE_NAME] Field Name" +msgstr "Field Name" + +# dynaforms/fields/yesno.xml?PME_LABEL +# dynaforms/fields/yesno.xml +#: text - PME_LABEL +msgid "[dynaforms/fields/yesno.xml?PME_LABEL] Label" +msgstr "Label" + +# dynaforms/fields/yesno.xml?PME_SUBTITLE3 +# dynaforms/fields/yesno.xml +#: title - PME_SUBTITLE3 +msgid "[dynaforms/fields/yesno.xml?PME_SUBTITLE3] Behaviour" +msgstr "Behaviour" + +# dynaforms/fields/yesno.xml?PME_READONLY +# dynaforms/fields/yesno.xml +#: checkbox - PME_READONLY +msgid "[dynaforms/fields/yesno.xml?PME_READONLY] Read Only" +msgstr "Read Only" + +# dynaforms/fields/yesno.xml?PME_DEFAULTVALUE +# dynaforms/fields/yesno.xml +#: dropdown - PME_DEFAULTVALUE +msgid "[dynaforms/fields/yesno.xml?PME_DEFAULTVALUE] Default Value" +msgstr "Default Value" + +# dynaforms/fields/yesno.xml?PME_DEFAULTVALUE-1 +# dynaforms/fields/yesno.xml +#: dropdown - PME_DEFAULTVALUE - 1 +msgid "[dynaforms/fields/yesno.xml?PME_DEFAULTVALUE-1]" +msgstr "Yes" + +# dynaforms/fields/yesno.xml?PME_DEFAULTVALUE-'' +# dynaforms/fields/yesno.xml +#: dropdown - PME_DEFAULTVALUE - '' +msgid "[dynaforms/fields/yesno.xml?PME_DEFAULTVALUE-'']" +msgstr "No" + +# dynaforms/fields/yesno.xml?PME_HINT +# dynaforms/fields/yesno.xml +#: textarea - PME_HINT +msgid "[dynaforms/fields/yesno.xml?PME_HINT] Hint" +msgstr "Hint" + +# dynaforms/fields/yesno.xml?PME_SUBTITLE +# dynaforms/fields/yesno.xml +#: title - PME_SUBTITLE +msgid "[dynaforms/fields/yesno.xml?PME_SUBTITLE] Appearance" +msgstr "Appearance" + +# dynaforms/fields/yesno.xml?PME_MODE +# dynaforms/fields/yesno.xml +#: dropdown - PME_MODE +msgid "[dynaforms/fields/yesno.xml?PME_MODE] Mode" +msgstr "Mode" + +# dynaforms/fields/yesno.xml?PME_MODE-edit +# dynaforms/fields/yesno.xml +#: dropdown - PME_MODE - edit +msgid "[dynaforms/fields/yesno.xml?PME_MODE-edit]" +msgstr "Edit" + +# dynaforms/fields/yesno.xml?PME_MODE-view +# dynaforms/fields/yesno.xml +#: dropdown - PME_MODE - view +msgid "[dynaforms/fields/yesno.xml?PME_MODE-view]" +msgstr "View" + +# dynaforms/fields/yesno.xml?BTN_CANCEL +# dynaforms/fields/yesno.xml +#: button - BTN_CANCEL +msgid "[dynaforms/fields/yesno.xml?BTN_CANCEL] Cancel" +msgstr "Cancel" + +# dynaforms/fields/yesno.xml?PME_ACCEPT +# dynaforms/fields/yesno.xml +#: button - PME_ACCEPT +msgid "[dynaforms/fields/yesno.xml?PME_ACCEPT] Save" +msgstr "Save" + diff --git a/workflow/engine/content/translations/pmos-translations.meta b/workflow/engine/content/translations/pmos-translations.meta new file mode 100644 index 000000000..f636c2d3e --- /dev/null +++ b/workflow/engine/content/translations/pmos-translations.meta @@ -0,0 +1 @@ +a:2:{s:11:"ISO_COUNTRY";a:243:{i:0;a:2:{s:6:"IC_UID";s:2:"AD";s:7:"IC_NAME";s:7:"Andorra";}i:1;a:2:{s:6:"IC_UID";s:2:"AE";s:7:"IC_NAME";s:20:"United Arab Emirates";}i:2;a:2:{s:6:"IC_UID";s:2:"AF";s:7:"IC_NAME";s:11:"Afghanistan";}i:3;a:2:{s:6:"IC_UID";s:2:"AG";s:7:"IC_NAME";s:19:"Antigua and Barbuda";}i:4;a:2:{s:6:"IC_UID";s:2:"AI";s:7:"IC_NAME";s:8:"Anguilla";}i:5;a:2:{s:6:"IC_UID";s:2:"AL";s:7:"IC_NAME";s:7:"Albania";}i:6;a:2:{s:6:"IC_UID";s:2:"AM";s:7:"IC_NAME";s:7:"Armenia";}i:7;a:2:{s:6:"IC_UID";s:2:"AN";s:7:"IC_NAME";s:20:"Netherlands Antilles";}i:8;a:2:{s:6:"IC_UID";s:2:"AO";s:7:"IC_NAME";s:6:"Angola";}i:9;a:2:{s:6:"IC_UID";s:2:"AQ";s:7:"IC_NAME";s:10:"Antarctica";}i:10;a:2:{s:6:"IC_UID";s:2:"AR";s:7:"IC_NAME";s:9:"Argentina";}i:11;a:2:{s:6:"IC_UID";s:2:"AS";s:7:"IC_NAME";s:14:"American Samoa";}i:12;a:2:{s:6:"IC_UID";s:2:"AT";s:7:"IC_NAME";s:7:"Austria";}i:13;a:2:{s:6:"IC_UID";s:2:"AU";s:7:"IC_NAME";s:9:"Australia";}i:14;a:2:{s:6:"IC_UID";s:2:"AW";s:7:"IC_NAME";s:5:"Aruba";}i:15;a:2:{s:6:"IC_UID";s:2:"AZ";s:7:"IC_NAME";s:10:"Azerbaijan";}i:16;a:2:{s:6:"IC_UID";s:2:"BA";s:7:"IC_NAME";s:22:"Bosnia and Herzegovina";}i:17;a:2:{s:6:"IC_UID";s:2:"BB";s:7:"IC_NAME";s:8:"Barbados";}i:18;a:2:{s:6:"IC_UID";s:2:"BD";s:7:"IC_NAME";s:10:"Bangladesh";}i:19;a:2:{s:6:"IC_UID";s:2:"BE";s:7:"IC_NAME";s:7:"Belgium";}i:20;a:2:{s:6:"IC_UID";s:2:"BF";s:7:"IC_NAME";s:12:"Burkina Faso";}i:21;a:2:{s:6:"IC_UID";s:2:"BG";s:7:"IC_NAME";s:8:"Bulgaria";}i:22;a:2:{s:6:"IC_UID";s:2:"BH";s:7:"IC_NAME";s:7:"Bahrain";}i:23;a:2:{s:6:"IC_UID";s:2:"BI";s:7:"IC_NAME";s:7:"Burundi";}i:24;a:2:{s:6:"IC_UID";s:2:"BJ";s:7:"IC_NAME";s:5:"Benin";}i:25;a:2:{s:6:"IC_UID";s:2:"BM";s:7:"IC_NAME";s:7:"Bermuda";}i:26;a:2:{s:6:"IC_UID";s:2:"BN";s:7:"IC_NAME";s:17:"Brunei Darussalam";}i:27;a:2:{s:6:"IC_UID";s:2:"BO";s:7:"IC_NAME";s:7:"Bolivia";}i:28;a:2:{s:6:"IC_UID";s:2:"BR";s:7:"IC_NAME";s:6:"Brazil";}i:29;a:2:{s:6:"IC_UID";s:2:"BS";s:7:"IC_NAME";s:7:"Bahamas";}i:30;a:2:{s:6:"IC_UID";s:2:"BT";s:7:"IC_NAME";s:6:"Bhutan";}i:31;a:2:{s:6:"IC_UID";s:2:"BW";s:7:"IC_NAME";s:8:"Botswana";}i:32;a:2:{s:6:"IC_UID";s:2:"BY";s:7:"IC_NAME";s:7:"Belarus";}i:33;a:2:{s:6:"IC_UID";s:2:"BZ";s:7:"IC_NAME";s:6:"Belize";}i:34;a:2:{s:6:"IC_UID";s:2:"CA";s:7:"IC_NAME";s:6:"Canada";}i:35;a:2:{s:6:"IC_UID";s:2:"CC";s:7:"IC_NAME";s:23:"Cocos (Keeling) Islands";}i:36;a:2:{s:6:"IC_UID";s:2:"CD";s:7:"IC_NAME";s:37:"Congo, The Democratic Republic of the";}i:37;a:2:{s:6:"IC_UID";s:2:"CF";s:7:"IC_NAME";s:24:"Central African Republic";}i:38;a:2:{s:6:"IC_UID";s:2:"CG";s:7:"IC_NAME";s:5:"Congo";}i:39;a:2:{s:6:"IC_UID";s:2:"CH";s:7:"IC_NAME";s:11:"Switzerland";}i:40;a:2:{s:6:"IC_UID";s:2:"CI";s:7:"IC_NAME";s:15:"Côte-d' lvoire";}i:41;a:2:{s:6:"IC_UID";s:2:"CK";s:7:"IC_NAME";s:12:"Cook Islands";}i:42;a:2:{s:6:"IC_UID";s:2:"CL";s:7:"IC_NAME";s:5:"Chile";}i:43;a:2:{s:6:"IC_UID";s:2:"CM";s:7:"IC_NAME";s:8:"Cameroon";}i:44;a:2:{s:6:"IC_UID";s:2:"CN";s:7:"IC_NAME";s:5:"China";}i:45;a:2:{s:6:"IC_UID";s:2:"CO";s:7:"IC_NAME";s:8:"Colombia";}i:46;a:2:{s:6:"IC_UID";s:2:"CR";s:7:"IC_NAME";s:10:"Costa Rica";}i:47;a:2:{s:6:"IC_UID";s:2:"CS";s:7:"IC_NAME";s:21:"Serbia and Montenegro";}i:48;a:2:{s:6:"IC_UID";s:2:"CU";s:7:"IC_NAME";s:4:"Cuba";}i:49;a:2:{s:6:"IC_UID";s:2:"CV";s:7:"IC_NAME";s:10:"Cape Verde";}i:50;a:2:{s:6:"IC_UID";s:2:"CX";s:7:"IC_NAME";s:16:"Christmas Island";}i:51;a:2:{s:6:"IC_UID";s:2:"CY";s:7:"IC_NAME";s:6:"Cyprus";}i:52;a:2:{s:6:"IC_UID";s:2:"CZ";s:7:"IC_NAME";s:14:"Czech Republic";}i:53;a:2:{s:6:"IC_UID";s:2:"DE";s:7:"IC_NAME";s:7:"Germany";}i:54;a:2:{s:6:"IC_UID";s:2:"DJ";s:7:"IC_NAME";s:8:"Djibouti";}i:55;a:2:{s:6:"IC_UID";s:2:"DK";s:7:"IC_NAME";s:7:"Denmark";}i:56;a:2:{s:6:"IC_UID";s:2:"DM";s:7:"IC_NAME";s:8:"Dominica";}i:57;a:2:{s:6:"IC_UID";s:2:"DO";s:7:"IC_NAME";s:18:"Dominican Republic";}i:58;a:2:{s:6:"IC_UID";s:2:"DZ";s:7:"IC_NAME";s:7:"Algeria";}i:59;a:2:{s:6:"IC_UID";s:2:"EC";s:7:"IC_NAME";s:7:"Ecuador";}i:60;a:2:{s:6:"IC_UID";s:2:"EE";s:7:"IC_NAME";s:7:"Estonia";}i:61;a:2:{s:6:"IC_UID";s:2:"EG";s:7:"IC_NAME";s:5:"Egypt";}i:62;a:2:{s:6:"IC_UID";s:2:"EH";s:7:"IC_NAME";s:14:"Western Sahara";}i:63;a:2:{s:6:"IC_UID";s:2:"ER";s:7:"IC_NAME";s:7:"Eritrea";}i:64;a:2:{s:6:"IC_UID";s:2:"ES";s:7:"IC_NAME";s:5:"Spain";}i:65;a:2:{s:6:"IC_UID";s:2:"ET";s:7:"IC_NAME";s:8:"Ethiopia";}i:66;a:2:{s:6:"IC_UID";s:2:"FI";s:7:"IC_NAME";s:7:"Finland";}i:67;a:2:{s:6:"IC_UID";s:2:"FJ";s:7:"IC_NAME";s:4:"Fiji";}i:68;a:2:{s:6:"IC_UID";s:2:"FK";s:7:"IC_NAME";s:27:"Falkland Islands (Malvinas)";}i:69;a:2:{s:6:"IC_UID";s:2:"FM";s:7:"IC_NAME";s:31:"Micronesia, Federated States of";}i:70;a:2:{s:6:"IC_UID";s:2:"FO";s:7:"IC_NAME";s:13:"Faroe Islands";}i:71;a:2:{s:6:"IC_UID";s:2:"FR";s:7:"IC_NAME";s:6:"France";}i:72;a:2:{s:6:"IC_UID";s:2:"GA";s:7:"IC_NAME";s:5:"Gabon";}i:73;a:2:{s:6:"IC_UID";s:2:"GB";s:7:"IC_NAME";s:14:"United Kingdom";}i:74;a:2:{s:6:"IC_UID";s:2:"GD";s:7:"IC_NAME";s:7:"Grenada";}i:75;a:2:{s:6:"IC_UID";s:2:"GE";s:7:"IC_NAME";s:7:"Georgia";}i:76;a:2:{s:6:"IC_UID";s:2:"GF";s:7:"IC_NAME";s:13:"French Guiana";}i:77;a:2:{s:6:"IC_UID";s:2:"GG";s:7:"IC_NAME";s:8:"Guernsey";}i:78;a:2:{s:6:"IC_UID";s:2:"GH";s:7:"IC_NAME";s:5:"Ghana";}i:79;a:2:{s:6:"IC_UID";s:2:"GI";s:7:"IC_NAME";s:9:"Gibraltar";}i:80;a:2:{s:6:"IC_UID";s:2:"GL";s:7:"IC_NAME";s:9:"Greenland";}i:81;a:2:{s:6:"IC_UID";s:2:"GM";s:7:"IC_NAME";s:6:"Gambia";}i:82;a:2:{s:6:"IC_UID";s:2:"GN";s:7:"IC_NAME";s:6:"Guinea";}i:83;a:2:{s:6:"IC_UID";s:2:"GP";s:7:"IC_NAME";s:10:"Guadeloupe";}i:84;a:2:{s:6:"IC_UID";s:2:"GQ";s:7:"IC_NAME";s:17:"Equatorial Guinea";}i:85;a:2:{s:6:"IC_UID";s:2:"GR";s:7:"IC_NAME";s:6:"Greece";}i:86;a:2:{s:6:"IC_UID";s:2:"GS";s:7:"IC_NAME";s:44:"South Georgia and the South Sandwich Islands";}i:87;a:2:{s:6:"IC_UID";s:2:"GT";s:7:"IC_NAME";s:9:"Guatemala";}i:88;a:2:{s:6:"IC_UID";s:2:"GU";s:7:"IC_NAME";s:4:"Guam";}i:89;a:2:{s:6:"IC_UID";s:2:"GW";s:7:"IC_NAME";s:13:"Guinea-Bissau";}i:90;a:2:{s:6:"IC_UID";s:2:"GY";s:7:"IC_NAME";s:6:"Guyana";}i:91;a:2:{s:6:"IC_UID";s:2:"HK";s:7:"IC_NAME";s:9:"Hong Kong";}i:92;a:2:{s:6:"IC_UID";s:2:"HM";s:7:"IC_NAME";s:33:"Heard Island and McDonald Islands";}i:93;a:2:{s:6:"IC_UID";s:2:"HN";s:7:"IC_NAME";s:8:"Honduras";}i:94;a:2:{s:6:"IC_UID";s:2:"HR";s:7:"IC_NAME";s:7:"Croatia";}i:95;a:2:{s:6:"IC_UID";s:2:"HT";s:7:"IC_NAME";s:5:"Haiti";}i:96;a:2:{s:6:"IC_UID";s:2:"HU";s:7:"IC_NAME";s:7:"Hungary";}i:97;a:2:{s:6:"IC_UID";s:2:"ID";s:7:"IC_NAME";s:9:"Indonesia";}i:98;a:2:{s:6:"IC_UID";s:2:"IE";s:7:"IC_NAME";s:7:"Ireland";}i:99;a:2:{s:6:"IC_UID";s:2:"IL";s:7:"IC_NAME";s:6:"Israel";}i:100;a:2:{s:6:"IC_UID";s:2:"IM";s:7:"IC_NAME";s:11:"Isle of Man";}i:101;a:2:{s:6:"IC_UID";s:2:"IN";s:7:"IC_NAME";s:5:"India";}i:102;a:2:{s:6:"IC_UID";s:2:"IO";s:7:"IC_NAME";s:30:"British Indian Ocean Territory";}i:103;a:2:{s:6:"IC_UID";s:2:"IQ";s:7:"IC_NAME";s:4:"Iraq";}i:104;a:2:{s:6:"IC_UID";s:2:"IR";s:7:"IC_NAME";s:25:"Iran, Islamic Republic of";}i:105;a:2:{s:6:"IC_UID";s:2:"IS";s:7:"IC_NAME";s:7:"Iceland";}i:106;a:2:{s:6:"IC_UID";s:2:"IT";s:7:"IC_NAME";s:5:"Italy";}i:107;a:2:{s:6:"IC_UID";s:2:"JE";s:7:"IC_NAME";s:6:"Jersey";}i:108;a:2:{s:6:"IC_UID";s:2:"JM";s:7:"IC_NAME";s:7:"Jamaica";}i:109;a:2:{s:6:"IC_UID";s:2:"JO";s:7:"IC_NAME";s:6:"Jordan";}i:110;a:2:{s:6:"IC_UID";s:2:"JP";s:7:"IC_NAME";s:5:"Japan";}i:111;a:2:{s:6:"IC_UID";s:2:"KE";s:7:"IC_NAME";s:5:"Kenya";}i:112;a:2:{s:6:"IC_UID";s:2:"KG";s:7:"IC_NAME";s:10:"Kyrgyzstan";}i:113;a:2:{s:6:"IC_UID";s:2:"KH";s:7:"IC_NAME";s:8:"Cambodia";}i:114;a:2:{s:6:"IC_UID";s:2:"KI";s:7:"IC_NAME";s:8:"Kiribati";}i:115;a:2:{s:6:"IC_UID";s:2:"KM";s:7:"IC_NAME";s:7:"Comoros";}i:116;a:2:{s:6:"IC_UID";s:2:"KN";s:7:"IC_NAME";s:21:"Saint Kitts and Nevis";}i:117;a:2:{s:6:"IC_UID";s:2:"KP";s:7:"IC_NAME";s:38:"Korea, Democratic People's Republic of";}i:118;a:2:{s:6:"IC_UID";s:2:"KR";s:7:"IC_NAME";s:18:"Korea, Republic of";}i:119;a:2:{s:6:"IC_UID";s:2:"KW";s:7:"IC_NAME";s:6:"Kuwait";}i:120;a:2:{s:6:"IC_UID";s:2:"KY";s:7:"IC_NAME";s:14:"Cayman Islands";}i:121;a:2:{s:6:"IC_UID";s:2:"KZ";s:7:"IC_NAME";s:10:"Kazakhstan";}i:122;a:2:{s:6:"IC_UID";s:2:"LA";s:7:"IC_NAME";s:32:"Lao People's Democratic Republic";}i:123;a:2:{s:6:"IC_UID";s:2:"LB";s:7:"IC_NAME";s:7:"Lebanon";}i:124;a:2:{s:6:"IC_UID";s:2:"LC";s:7:"IC_NAME";s:11:"Saint Lucia";}i:125;a:2:{s:6:"IC_UID";s:2:"LI";s:7:"IC_NAME";s:13:"Liechtenstein";}i:126;a:2:{s:6:"IC_UID";s:2:"LK";s:7:"IC_NAME";s:9:"Sri Lanka";}i:127;a:2:{s:6:"IC_UID";s:2:"LR";s:7:"IC_NAME";s:7:"Liberia";}i:128;a:2:{s:6:"IC_UID";s:2:"LS";s:7:"IC_NAME";s:7:"Lesotho";}i:129;a:2:{s:6:"IC_UID";s:2:"LT";s:7:"IC_NAME";s:9:"Lithuania";}i:130;a:2:{s:6:"IC_UID";s:2:"LU";s:7:"IC_NAME";s:10:"Luxembourg";}i:131;a:2:{s:6:"IC_UID";s:2:"LV";s:7:"IC_NAME";s:6:"Latvia";}i:132;a:2:{s:6:"IC_UID";s:2:"LY";s:7:"IC_NAME";s:22:"Libyan Arab Jamahiriya";}i:133;a:2:{s:6:"IC_UID";s:2:"MA";s:7:"IC_NAME";s:7:"Morocco";}i:134;a:2:{s:6:"IC_UID";s:2:"MC";s:7:"IC_NAME";s:6:"Monaco";}i:135;a:2:{s:6:"IC_UID";s:2:"MD";s:7:"IC_NAME";s:20:"Moldova, Republic of";}i:136;a:2:{s:6:"IC_UID";s:2:"ME";s:7:"IC_NAME";s:10:"Montenegro";}i:137;a:2:{s:6:"IC_UID";s:2:"MG";s:7:"IC_NAME";s:10:"Madagascar";}i:138;a:2:{s:6:"IC_UID";s:2:"MH";s:7:"IC_NAME";s:16:"Marshall Islands";}i:139;a:2:{s:6:"IC_UID";s:2:"MK";s:7:"IC_NAME";s:42:"Macedonia, The former Yugoslav Republic of";}i:140;a:2:{s:6:"IC_UID";s:2:"ML";s:7:"IC_NAME";s:4:"Mali";}i:141;a:2:{s:6:"IC_UID";s:2:"MM";s:7:"IC_NAME";s:7:"Myanmar";}i:142;a:2:{s:6:"IC_UID";s:2:"MN";s:7:"IC_NAME";s:8:"Mongolia";}i:143;a:2:{s:6:"IC_UID";s:2:"MO";s:7:"IC_NAME";s:5:"Macao";}i:144;a:2:{s:6:"IC_UID";s:2:"MP";s:7:"IC_NAME";s:24:"Northern Mariana Islands";}i:145;a:2:{s:6:"IC_UID";s:2:"MQ";s:7:"IC_NAME";s:10:"Martinique";}i:146;a:2:{s:6:"IC_UID";s:2:"MR";s:7:"IC_NAME";s:10:"Mauritania";}i:147;a:2:{s:6:"IC_UID";s:2:"MS";s:7:"IC_NAME";s:10:"Montserrat";}i:148;a:2:{s:6:"IC_UID";s:2:"MT";s:7:"IC_NAME";s:5:"Malta";}i:149;a:2:{s:6:"IC_UID";s:2:"MU";s:7:"IC_NAME";s:9:"Mauritius";}i:150;a:2:{s:6:"IC_UID";s:2:"MV";s:7:"IC_NAME";s:8:"Maldives";}i:151;a:2:{s:6:"IC_UID";s:2:"MW";s:7:"IC_NAME";s:6:"Malawi";}i:152;a:2:{s:6:"IC_UID";s:2:"MX";s:7:"IC_NAME";s:6:"Mexico";}i:153;a:2:{s:6:"IC_UID";s:2:"MY";s:7:"IC_NAME";s:8:"Malaysia";}i:154;a:2:{s:6:"IC_UID";s:2:"MZ";s:7:"IC_NAME";s:10:"Mozambique";}i:155;a:2:{s:6:"IC_UID";s:2:"NA";s:7:"IC_NAME";s:7:"Namibia";}i:156;a:2:{s:6:"IC_UID";s:2:"NC";s:7:"IC_NAME";s:13:"New Caledonia";}i:157;a:2:{s:6:"IC_UID";s:2:"NE";s:7:"IC_NAME";s:5:"Niger";}i:158;a:2:{s:6:"IC_UID";s:2:"NF";s:7:"IC_NAME";s:14:"Norfolk Island";}i:159;a:2:{s:6:"IC_UID";s:2:"NG";s:7:"IC_NAME";s:7:"Nigeria";}i:160;a:2:{s:6:"IC_UID";s:2:"NI";s:7:"IC_NAME";s:9:"Nicaragua";}i:161;a:2:{s:6:"IC_UID";s:2:"NL";s:7:"IC_NAME";s:11:"Netherlands";}i:162;a:2:{s:6:"IC_UID";s:2:"NO";s:7:"IC_NAME";s:6:"Norway";}i:163;a:2:{s:6:"IC_UID";s:2:"NP";s:7:"IC_NAME";s:5:"Nepal";}i:164;a:2:{s:6:"IC_UID";s:2:"NR";s:7:"IC_NAME";s:5:"Nauru";}i:165;a:2:{s:6:"IC_UID";s:2:"NU";s:7:"IC_NAME";s:4:"Niue";}i:166;a:2:{s:6:"IC_UID";s:2:"NZ";s:7:"IC_NAME";s:11:"New Zealand";}i:167;a:2:{s:6:"IC_UID";s:2:"OM";s:7:"IC_NAME";s:4:"Oman";}i:168;a:2:{s:6:"IC_UID";s:2:"PA";s:7:"IC_NAME";s:6:"Panama";}i:169;a:2:{s:6:"IC_UID";s:2:"PE";s:7:"IC_NAME";s:4:"Peru";}i:170;a:2:{s:6:"IC_UID";s:2:"PF";s:7:"IC_NAME";s:16:"French Polynesia";}i:171;a:2:{s:6:"IC_UID";s:2:"PG";s:7:"IC_NAME";s:16:"Papua New Guinea";}i:172;a:2:{s:6:"IC_UID";s:2:"PH";s:7:"IC_NAME";s:11:"Philippines";}i:173;a:2:{s:6:"IC_UID";s:2:"PK";s:7:"IC_NAME";s:8:"Pakistan";}i:174;a:2:{s:6:"IC_UID";s:2:"PL";s:7:"IC_NAME";s:6:"Poland";}i:175;a:2:{s:6:"IC_UID";s:2:"PM";s:7:"IC_NAME";s:25:"Saint Pierre and Miquelon";}i:176;a:2:{s:6:"IC_UID";s:2:"PN";s:7:"IC_NAME";s:8:"Pitcairn";}i:177;a:2:{s:6:"IC_UID";s:2:"PR";s:7:"IC_NAME";s:11:"Puerto Rico";}i:178;a:2:{s:6:"IC_UID";s:2:"PT";s:7:"IC_NAME";s:8:"Portugal";}i:179;a:2:{s:6:"IC_UID";s:2:"PW";s:7:"IC_NAME";s:5:"Palau";}i:180;a:2:{s:6:"IC_UID";s:2:"PY";s:7:"IC_NAME";s:8:"Paraguay";}i:181;a:2:{s:6:"IC_UID";s:2:"QA";s:7:"IC_NAME";s:5:"Qatar";}i:182;a:2:{s:6:"IC_UID";s:2:"RE";s:7:"IC_NAME";s:7:"Reunion";}i:183;a:2:{s:6:"IC_UID";s:2:"RO";s:7:"IC_NAME";s:7:"Romania";}i:184;a:2:{s:6:"IC_UID";s:2:"RS";s:7:"IC_NAME";s:6:"Serbia";}i:185;a:2:{s:6:"IC_UID";s:2:"RU";s:7:"IC_NAME";s:18:"Russian Federation";}i:186;a:2:{s:6:"IC_UID";s:2:"RW";s:7:"IC_NAME";s:6:"Rwanda";}i:187;a:2:{s:6:"IC_UID";s:2:"SA";s:7:"IC_NAME";s:12:"Saudi Arabia";}i:188;a:2:{s:6:"IC_UID";s:2:"SB";s:7:"IC_NAME";s:15:"Solomon Islands";}i:189;a:2:{s:6:"IC_UID";s:2:"SC";s:7:"IC_NAME";s:10:"Seychelles";}i:190;a:2:{s:6:"IC_UID";s:2:"SD";s:7:"IC_NAME";s:5:"Sudan";}i:191;a:2:{s:6:"IC_UID";s:2:"SE";s:7:"IC_NAME";s:6:"Sweden";}i:192;a:2:{s:6:"IC_UID";s:2:"SG";s:7:"IC_NAME";s:9:"Singapore";}i:193;a:2:{s:6:"IC_UID";s:2:"SH";s:7:"IC_NAME";s:12:"Saint Helena";}i:194;a:2:{s:6:"IC_UID";s:2:"SI";s:7:"IC_NAME";s:8:"Slovenia";}i:195;a:2:{s:6:"IC_UID";s:2:"SJ";s:7:"IC_NAME";s:22:"Svalbard and Jan Mayen";}i:196;a:2:{s:6:"IC_UID";s:2:"SK";s:7:"IC_NAME";s:8:"Slovakia";}i:197;a:2:{s:6:"IC_UID";s:2:"SL";s:7:"IC_NAME";s:12:"Sierra Leone";}i:198;a:2:{s:6:"IC_UID";s:2:"SM";s:7:"IC_NAME";s:10:"San Marino";}i:199;a:2:{s:6:"IC_UID";s:2:"SN";s:7:"IC_NAME";s:7:"Senegal";}i:200;a:2:{s:6:"IC_UID";s:2:"SO";s:7:"IC_NAME";s:7:"Somalia";}i:201;a:2:{s:6:"IC_UID";s:2:"SR";s:7:"IC_NAME";s:8:"Suriname";}i:202;a:2:{s:6:"IC_UID";s:2:"ST";s:7:"IC_NAME";s:21:"Sao Tome and Principe";}i:203;a:2:{s:6:"IC_UID";s:2:"SV";s:7:"IC_NAME";s:11:"El Salvador";}i:204;a:2:{s:6:"IC_UID";s:2:"SY";s:7:"IC_NAME";s:20:"Syrian Arab Republic";}i:205;a:2:{s:6:"IC_UID";s:2:"SZ";s:7:"IC_NAME";s:9:"Swaziland";}i:206;a:2:{s:6:"IC_UID";s:2:"TC";s:7:"IC_NAME";s:24:"Turks and Caicos Islands";}i:207;a:2:{s:6:"IC_UID";s:2:"TD";s:7:"IC_NAME";s:4:"Chad";}i:208;a:2:{s:6:"IC_UID";s:2:"TF";s:7:"IC_NAME";s:27:"French Southern Territories";}i:209;a:2:{s:6:"IC_UID";s:2:"TG";s:7:"IC_NAME";s:4:"Togo";}i:210;a:2:{s:6:"IC_UID";s:2:"TH";s:7:"IC_NAME";s:8:"Thailand";}i:211;a:2:{s:6:"IC_UID";s:2:"TJ";s:7:"IC_NAME";s:10:"Tajikistan";}i:212;a:2:{s:6:"IC_UID";s:2:"TK";s:7:"IC_NAME";s:7:"Tokelau";}i:213;a:2:{s:6:"IC_UID";s:2:"TL";s:7:"IC_NAME";s:11:"Timor-Leste";}i:214;a:2:{s:6:"IC_UID";s:2:"TM";s:7:"IC_NAME";s:12:"Turkmenistan";}i:215;a:2:{s:6:"IC_UID";s:2:"TN";s:7:"IC_NAME";s:7:"Tunisia";}i:216;a:2:{s:6:"IC_UID";s:2:"TO";s:7:"IC_NAME";s:5:"Tonga";}i:217;a:2:{s:6:"IC_UID";s:2:"TR";s:7:"IC_NAME";s:6:"Turkey";}i:218;a:2:{s:6:"IC_UID";s:2:"TT";s:7:"IC_NAME";s:19:"Trinidad and Tobago";}i:219;a:2:{s:6:"IC_UID";s:2:"TV";s:7:"IC_NAME";s:6:"Tuvalu";}i:220;a:2:{s:6:"IC_UID";s:2:"TW";s:7:"IC_NAME";s:25:"Taiwan, Province of China";}i:221;a:2:{s:6:"IC_UID";s:2:"TZ";s:7:"IC_NAME";s:28:"Tanzania, United Republic of";}i:222;a:2:{s:6:"IC_UID";s:2:"UA";s:7:"IC_NAME";s:7:"Ukraine";}i:223;a:2:{s:6:"IC_UID";s:2:"UG";s:7:"IC_NAME";s:6:"Uganda";}i:224;a:2:{s:6:"IC_UID";s:2:"UM";s:7:"IC_NAME";s:36:"United States Minor Outlying Islands";}i:225;a:2:{s:6:"IC_UID";s:2:"US";s:7:"IC_NAME";s:13:"United States";}i:226;a:2:{s:6:"IC_UID";s:2:"UY";s:7:"IC_NAME";s:7:"Uruguay";}i:227;a:2:{s:6:"IC_UID";s:2:"UZ";s:7:"IC_NAME";s:10:"Uzbekistan";}i:228;a:2:{s:6:"IC_UID";s:2:"VA";s:7:"IC_NAME";s:29:"Holy See (Vatican City State)";}i:229;a:2:{s:6:"IC_UID";s:2:"VC";s:7:"IC_NAME";s:32:"Saint Vincent and the Grenadines";}i:230;a:2:{s:6:"IC_UID";s:2:"VE";s:7:"IC_NAME";s:9:"Venezuela";}i:231;a:2:{s:6:"IC_UID";s:2:"VG";s:7:"IC_NAME";s:23:"Virgin Islands, British";}i:232;a:2:{s:6:"IC_UID";s:2:"VI";s:7:"IC_NAME";s:20:"Virgin Islands, U.S.";}i:233;a:2:{s:6:"IC_UID";s:2:"VN";s:7:"IC_NAME";s:8:"Viet Nam";}i:234;a:2:{s:6:"IC_UID";s:2:"VU";s:7:"IC_NAME";s:7:"Vanuatu";}i:235;a:2:{s:6:"IC_UID";s:2:"WF";s:7:"IC_NAME";s:17:"Wallis and Futuna";}i:236;a:2:{s:6:"IC_UID";s:2:"WS";s:7:"IC_NAME";s:5:"Samoa";}i:237;a:2:{s:6:"IC_UID";s:2:"XZ";s:7:"IC_NAME";s:37:"Installations in International Waters";}i:238;a:2:{s:6:"IC_UID";s:2:"YE";s:7:"IC_NAME";s:5:"Yemen";}i:239;a:2:{s:6:"IC_UID";s:2:"YT";s:7:"IC_NAME";s:7:"Mayotte";}i:240;a:2:{s:6:"IC_UID";s:2:"ZA";s:7:"IC_NAME";s:12:"South Africa";}i:241;a:2:{s:6:"IC_UID";s:2:"ZM";s:7:"IC_NAME";s:6:"Zambia";}i:242;a:2:{s:6:"IC_UID";s:2:"ZW";s:7:"IC_NAME";s:8:"Zimbabwe";}}s:8:"LANGUAGE";a:136:{i:0;a:2:{s:8:"LAN_NAME";s:4:"Afar";s:6:"LAN_ID";s:2:"aa";}i:1;a:2:{s:8:"LAN_NAME";s:9:"Abkhazian";s:6:"LAN_ID";s:2:"ab";}i:2;a:2:{s:8:"LAN_NAME";s:9:"Afrikaans";s:6:"LAN_ID";s:2:"af";}i:3;a:2:{s:8:"LAN_NAME";s:7:"Amharic";s:6:"LAN_ID";s:2:"am";}i:4;a:2:{s:8:"LAN_NAME";s:6:"Arabic";s:6:"LAN_ID";s:2:"ar";}i:5;a:2:{s:8:"LAN_NAME";s:8:"Assamese";s:6:"LAN_ID";s:2:"as";}i:6;a:2:{s:8:"LAN_NAME";s:6:"Aymara";s:6:"LAN_ID";s:2:"ay";}i:7;a:2:{s:8:"LAN_NAME";s:11:"Azerbaijani";s:6:"LAN_ID";s:2:"az";}i:8;a:2:{s:8:"LAN_NAME";s:7:"Bashkir";s:6:"LAN_ID";s:2:"ba";}i:9;a:2:{s:8:"LAN_NAME";s:12:"Byelorussian";s:6:"LAN_ID";s:2:"be";}i:10;a:2:{s:8:"LAN_NAME";s:9:"Bulgarian";s:6:"LAN_ID";s:2:"bg";}i:11;a:2:{s:8:"LAN_NAME";s:6:"Bihari";s:6:"LAN_ID";s:2:"bh";}i:12;a:2:{s:8:"LAN_NAME";s:7:"Bislama";s:6:"LAN_ID";s:2:"bi";}i:13;a:2:{s:8:"LAN_NAME";s:7:"Bengali";s:6:"LAN_ID";s:2:"bn";}i:14;a:2:{s:8:"LAN_NAME";s:7:"Tibetan";s:6:"LAN_ID";s:2:"bo";}i:15;a:2:{s:8:"LAN_NAME";s:6:"Breton";s:6:"LAN_ID";s:2:"br";}i:16;a:2:{s:8:"LAN_NAME";s:7:"Catalan";s:6:"LAN_ID";s:2:"ca";}i:17;a:2:{s:8:"LAN_NAME";s:8:"Corsican";s:6:"LAN_ID";s:2:"co";}i:18;a:2:{s:8:"LAN_NAME";s:5:"Czech";s:6:"LAN_ID";s:2:"cs";}i:19;a:2:{s:8:"LAN_NAME";s:5:"Welsh";s:6:"LAN_ID";s:2:"cy";}i:20;a:2:{s:8:"LAN_NAME";s:6:"Danish";s:6:"LAN_ID";s:2:"da";}i:21;a:2:{s:8:"LAN_NAME";s:6:"German";s:6:"LAN_ID";s:2:"de";}i:22;a:2:{s:8:"LAN_NAME";s:7:"Bhutani";s:6:"LAN_ID";s:2:"dz";}i:23;a:2:{s:8:"LAN_NAME";s:5:"Greek";s:6:"LAN_ID";s:2:"el";}i:24;a:2:{s:8:"LAN_NAME";s:7:"English";s:6:"LAN_ID";s:2:"en";}i:25;a:2:{s:8:"LAN_NAME";s:9:"Esperanto";s:6:"LAN_ID";s:2:"eo";}i:26;a:2:{s:8:"LAN_NAME";s:7:"Spanish";s:6:"LAN_ID";s:2:"es";}i:27;a:2:{s:8:"LAN_NAME";s:8:"Estonian";s:6:"LAN_ID";s:2:"et";}i:28;a:2:{s:8:"LAN_NAME";s:6:"Basque";s:6:"LAN_ID";s:2:"eu";}i:29;a:2:{s:8:"LAN_NAME";s:7:"Persian";s:6:"LAN_ID";s:2:"fa";}i:30;a:2:{s:8:"LAN_NAME";s:7:"Finnish";s:6:"LAN_ID";s:2:"fi";}i:31;a:2:{s:8:"LAN_NAME";s:4:"Fiji";s:6:"LAN_ID";s:2:"fj";}i:32;a:2:{s:8:"LAN_NAME";s:8:"Faeroese";s:6:"LAN_ID";s:2:"fo";}i:33;a:2:{s:8:"LAN_NAME";s:6:"French";s:6:"LAN_ID";s:2:"fr";}i:34;a:2:{s:8:"LAN_NAME";s:7:"Frisian";s:6:"LAN_ID";s:2:"fy";}i:35;a:2:{s:8:"LAN_NAME";s:5:"Irish";s:6:"LAN_ID";s:2:"ga";}i:36;a:2:{s:8:"LAN_NAME";s:6:"Gaelic";s:6:"LAN_ID";s:2:"gd";}i:37;a:2:{s:8:"LAN_NAME";s:8:"Galician";s:6:"LAN_ID";s:2:"gl";}i:38;a:2:{s:8:"LAN_NAME";s:7:"Guarani";s:6:"LAN_ID";s:2:"gn";}i:39;a:2:{s:8:"LAN_NAME";s:8:"Gujarati";s:6:"LAN_ID";s:2:"gu";}i:40;a:2:{s:8:"LAN_NAME";s:5:"Hausa";s:6:"LAN_ID";s:2:"ha";}i:41;a:2:{s:8:"LAN_NAME";s:5:"Hindi";s:6:"LAN_ID";s:2:"hi";}i:42;a:2:{s:8:"LAN_NAME";s:8:"Croatian";s:6:"LAN_ID";s:2:"hr";}i:43;a:2:{s:8:"LAN_NAME";s:9:"Hungarian";s:6:"LAN_ID";s:2:"hu";}i:44;a:2:{s:8:"LAN_NAME";s:8:"Armenian";s:6:"LAN_ID";s:2:"hy";}i:45;a:2:{s:8:"LAN_NAME";s:11:"Interlingua";s:6:"LAN_ID";s:2:"ia";}i:46;a:2:{s:8:"LAN_NAME";s:11:"Interlingue";s:6:"LAN_ID";s:2:"ie";}i:47;a:2:{s:8:"LAN_NAME";s:7:"Inupiak";s:6:"LAN_ID";s:2:"ik";}i:48;a:2:{s:8:"LAN_NAME";s:10:"Indonesian";s:6:"LAN_ID";s:2:"in";}i:49;a:2:{s:8:"LAN_NAME";s:9:"Icelandic";s:6:"LAN_ID";s:2:"is";}i:50;a:2:{s:8:"LAN_NAME";s:7:"Italian";s:6:"LAN_ID";s:2:"it";}i:51;a:2:{s:8:"LAN_NAME";s:6:"Hebrew";s:6:"LAN_ID";s:2:"he";}i:52;a:2:{s:8:"LAN_NAME";s:8:"Japanese";s:6:"LAN_ID";s:2:"ja";}i:53;a:2:{s:8:"LAN_NAME";s:7:"Yiddish";s:6:"LAN_ID";s:2:"ji";}i:54;a:2:{s:8:"LAN_NAME";s:8:"Javanese";s:6:"LAN_ID";s:2:"jw";}i:55;a:2:{s:8:"LAN_NAME";s:8:"Georgian";s:6:"LAN_ID";s:2:"ka";}i:56;a:2:{s:8:"LAN_NAME";s:6:"Kazakh";s:6:"LAN_ID";s:2:"kk";}i:57;a:2:{s:8:"LAN_NAME";s:11:"Greenlandic";s:6:"LAN_ID";s:2:"kl";}i:58;a:2:{s:8:"LAN_NAME";s:9:"Cambodian";s:6:"LAN_ID";s:2:"km";}i:59;a:2:{s:8:"LAN_NAME";s:7:"Kannada";s:6:"LAN_ID";s:2:"kn";}i:60;a:2:{s:8:"LAN_NAME";s:6:"Korean";s:6:"LAN_ID";s:2:"ko";}i:61;a:2:{s:8:"LAN_NAME";s:8:"Kashmiri";s:6:"LAN_ID";s:2:"ks";}i:62;a:2:{s:8:"LAN_NAME";s:7:"Kurdish";s:6:"LAN_ID";s:2:"ku";}i:63;a:2:{s:8:"LAN_NAME";s:7:"Kirghiz";s:6:"LAN_ID";s:2:"ky";}i:64;a:2:{s:8:"LAN_NAME";s:5:"Latin";s:6:"LAN_ID";s:2:"la";}i:65;a:2:{s:8:"LAN_NAME";s:7:"Lingala";s:6:"LAN_ID";s:2:"ln";}i:66;a:2:{s:8:"LAN_NAME";s:8:"Laothian";s:6:"LAN_ID";s:2:"lo";}i:67;a:2:{s:8:"LAN_NAME";s:10:"Lithuanian";s:6:"LAN_ID";s:2:"lt";}i:68;a:2:{s:8:"LAN_NAME";s:7:"Latvian";s:6:"LAN_ID";s:2:"lv";}i:69;a:2:{s:8:"LAN_NAME";s:8:"Malagasy";s:6:"LAN_ID";s:2:"mg";}i:70;a:2:{s:8:"LAN_NAME";s:5:"Maori";s:6:"LAN_ID";s:2:"mi";}i:71;a:2:{s:8:"LAN_NAME";s:10:"Macedonian";s:6:"LAN_ID";s:2:"mk";}i:72;a:2:{s:8:"LAN_NAME";s:9:"Malayalam";s:6:"LAN_ID";s:2:"ml";}i:73;a:2:{s:8:"LAN_NAME";s:9:"Mongolian";s:6:"LAN_ID";s:2:"mn";}i:74;a:2:{s:8:"LAN_NAME";s:9:"Moldavian";s:6:"LAN_ID";s:2:"mo";}i:75;a:2:{s:8:"LAN_NAME";s:7:"Marathi";s:6:"LAN_ID";s:2:"mr";}i:76;a:2:{s:8:"LAN_NAME";s:5:"Malay";s:6:"LAN_ID";s:2:"ms";}i:77;a:2:{s:8:"LAN_NAME";s:7:"Maltese";s:6:"LAN_ID";s:2:"mt";}i:78;a:2:{s:8:"LAN_NAME";s:7:"Burmese";s:6:"LAN_ID";s:2:"my";}i:79;a:2:{s:8:"LAN_NAME";s:5:"Nauru";s:6:"LAN_ID";s:2:"na";}i:80;a:2:{s:8:"LAN_NAME";s:6:"Nepali";s:6:"LAN_ID";s:2:"ne";}i:81;a:2:{s:8:"LAN_NAME";s:5:"Dutch";s:6:"LAN_ID";s:2:"nl";}i:82;a:2:{s:8:"LAN_NAME";s:9:"Norwegian";s:6:"LAN_ID";s:2:"no";}i:83;a:2:{s:8:"LAN_NAME";s:7:"Occitan";s:6:"LAN_ID";s:2:"oc";}i:84;a:2:{s:8:"LAN_NAME";s:5:"Oromo";s:6:"LAN_ID";s:2:"om";}i:85;a:2:{s:8:"LAN_NAME";s:5:"Oriya";s:6:"LAN_ID";s:2:"or";}i:86;a:2:{s:8:"LAN_NAME";s:7:"Punjabi";s:6:"LAN_ID";s:2:"pa";}i:87;a:2:{s:8:"LAN_NAME";s:6:"Polish";s:6:"LAN_ID";s:2:"pl";}i:88;a:2:{s:8:"LAN_NAME";s:6:"Pashto";s:6:"LAN_ID";s:2:"ps";}i:89;a:2:{s:8:"LAN_NAME";s:10:"Portuguese";s:6:"LAN_ID";s:2:"pt";}i:90;a:2:{s:8:"LAN_NAME";s:7:"Quechua";s:6:"LAN_ID";s:2:"qu";}i:91;a:2:{s:8:"LAN_NAME";s:14:"Rhaeto-Romance";s:6:"LAN_ID";s:2:"rm";}i:92;a:2:{s:8:"LAN_NAME";s:7:"Kirundi";s:6:"LAN_ID";s:2:"rn";}i:93;a:2:{s:8:"LAN_NAME";s:8:"Romanian";s:6:"LAN_ID";s:2:"ro";}i:94;a:2:{s:8:"LAN_NAME";s:7:"Russian";s:6:"LAN_ID";s:2:"ru";}i:95;a:2:{s:8:"LAN_NAME";s:11:"Kinyarwanda";s:6:"LAN_ID";s:2:"rw";}i:96;a:2:{s:8:"LAN_NAME";s:8:"Sanskrit";s:6:"LAN_ID";s:2:"sa";}i:97;a:2:{s:8:"LAN_NAME";s:6:"Sindhi";s:6:"LAN_ID";s:2:"sd";}i:98;a:2:{s:8:"LAN_NAME";s:6:"Sangro";s:6:"LAN_ID";s:2:"sg";}i:99;a:2:{s:8:"LAN_NAME";s:14:"Serbo-Croatian";s:6:"LAN_ID";s:2:"sh";}i:100;a:2:{s:8:"LAN_NAME";s:10:"Singhalese";s:6:"LAN_ID";s:2:"si";}i:101;a:2:{s:8:"LAN_NAME";s:6:"Slovak";s:6:"LAN_ID";s:2:"sk";}i:102;a:2:{s:8:"LAN_NAME";s:9:"Slovenian";s:6:"LAN_ID";s:2:"sl";}i:103;a:2:{s:8:"LAN_NAME";s:6:"Samoan";s:6:"LAN_ID";s:2:"sm";}i:104;a:2:{s:8:"LAN_NAME";s:5:"Shona";s:6:"LAN_ID";s:2:"sn";}i:105;a:2:{s:8:"LAN_NAME";s:6:"Somali";s:6:"LAN_ID";s:2:"so";}i:106;a:2:{s:8:"LAN_NAME";s:8:"Albanian";s:6:"LAN_ID";s:2:"sq";}i:107;a:2:{s:8:"LAN_NAME";s:7:"Serbian";s:6:"LAN_ID";s:2:"sr";}i:108;a:2:{s:8:"LAN_NAME";s:7:"Siswati";s:6:"LAN_ID";s:2:"ss";}i:109;a:2:{s:8:"LAN_NAME";s:7:"Sesotho";s:6:"LAN_ID";s:2:"st";}i:110;a:2:{s:8:"LAN_NAME";s:8:"Sudanese";s:6:"LAN_ID";s:2:"su";}i:111;a:2:{s:8:"LAN_NAME";s:7:"Swedish";s:6:"LAN_ID";s:2:"sv";}i:112;a:2:{s:8:"LAN_NAME";s:7:"Swahili";s:6:"LAN_ID";s:2:"sw";}i:113;a:2:{s:8:"LAN_NAME";s:5:"Tamil";s:6:"LAN_ID";s:2:"ta";}i:114;a:2:{s:8:"LAN_NAME";s:6:"Tegulu";s:6:"LAN_ID";s:2:"te";}i:115;a:2:{s:8:"LAN_NAME";s:5:"Tajik";s:6:"LAN_ID";s:2:"tg";}i:116;a:2:{s:8:"LAN_NAME";s:4:"Thai";s:6:"LAN_ID";s:2:"th";}i:117;a:2:{s:8:"LAN_NAME";s:8:"Tigrinya";s:6:"LAN_ID";s:2:"ti";}i:118;a:2:{s:8:"LAN_NAME";s:7:"Turkmen";s:6:"LAN_ID";s:2:"tk";}i:119;a:2:{s:8:"LAN_NAME";s:7:"Tagalog";s:6:"LAN_ID";s:2:"tl";}i:120;a:2:{s:8:"LAN_NAME";s:8:"Setswana";s:6:"LAN_ID";s:2:"tn";}i:121;a:2:{s:8:"LAN_NAME";s:5:"Tonga";s:6:"LAN_ID";s:2:"to";}i:122;a:2:{s:8:"LAN_NAME";s:7:"Turkish";s:6:"LAN_ID";s:2:"tr";}i:123;a:2:{s:8:"LAN_NAME";s:6:"Tsonga";s:6:"LAN_ID";s:2:"ts";}i:124;a:2:{s:8:"LAN_NAME";s:5:"Tatar";s:6:"LAN_ID";s:2:"tt";}i:125;a:2:{s:8:"LAN_NAME";s:3:"Twi";s:6:"LAN_ID";s:2:"tw";}i:126;a:2:{s:8:"LAN_NAME";s:9:"Ukrainian";s:6:"LAN_ID";s:2:"uk";}i:127;a:2:{s:8:"LAN_NAME";s:4:"Urdu";s:6:"LAN_ID";s:2:"ur";}i:128;a:2:{s:8:"LAN_NAME";s:5:"Uzbek";s:6:"LAN_ID";s:2:"uz";}i:129;a:2:{s:8:"LAN_NAME";s:10:"Vietnamese";s:6:"LAN_ID";s:2:"vi";}i:130;a:2:{s:8:"LAN_NAME";s:7:"Volapuk";s:6:"LAN_ID";s:2:"vo";}i:131;a:2:{s:8:"LAN_NAME";s:5:"Wolof";s:6:"LAN_ID";s:2:"wo";}i:132;a:2:{s:8:"LAN_NAME";s:5:"Xhosa";s:6:"LAN_ID";s:2:"xh";}i:133;a:2:{s:8:"LAN_NAME";s:6:"Yoruba";s:6:"LAN_ID";s:2:"yo";}i:134;a:2:{s:8:"LAN_NAME";s:7:"Chinese";s:6:"LAN_ID";s:2:"zh";}i:135;a:2:{s:8:"LAN_NAME";s:4:"Zulu";s:6:"LAN_ID";s:2:"zu";}}} \ No newline at end of file diff --git a/workflow/engine/data/mssql/schema.sql b/workflow/engine/data/mssql/schema.sql new file mode 100644 index 000000000..5a0eefc8a --- /dev/null +++ b/workflow/engine/data/mssql/schema.sql @@ -0,0 +1,1409 @@ + +/* ---------------------------------------------------------------------- */ +/* APPLICATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'APPLICATION') +BEGIN + DECLARE @reftable_1 nvarchar(60), @constraintname_1 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'APPLICATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_1, @constraintname_1 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_1+' drop constraint '+@constraintname_1) + FETCH NEXT from refcursor into @reftable_1, @constraintname_1 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [APPLICATION] +END + + +CREATE TABLE [APPLICATION] +( + [APP_UID] VARCHAR(32) default '' NOT NULL, + [APP_NUMBER] INT default 0 NOT NULL, + [APP_PARENT] VARCHAR(32) default '0' NOT NULL, + [APP_STATUS] VARCHAR(100) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [APP_PROC_STATUS] VARCHAR(100) default '' NOT NULL, + [APP_PROC_CODE] VARCHAR(100) default '' NOT NULL, + [APP_PARALLEL] VARCHAR(32) default 'NO' NOT NULL, + [APP_INIT_USER] VARCHAR(32) default '' NOT NULL, + [APP_CUR_USER] VARCHAR(32) default '' NOT NULL, + [APP_CREATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [APP_INIT_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [APP_FINISH_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [APP_UPDATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [APP_DATA] TEXT NOT NULL, + CONSTRAINT APPLICATION_PK PRIMARY KEY ([APP_UID]) +); + +CREATE INDEX [indexApp] ON [APPLICATION] ([PRO_UID],[APP_UID]); + +/* ---------------------------------------------------------------------- */ +/* APP_DELEGATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'APP_DELEGATION') +BEGIN + DECLARE @reftable_2 nvarchar(60), @constraintname_2 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'APP_DELEGATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_2, @constraintname_2 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_2+' drop constraint '+@constraintname_2) + FETCH NEXT from refcursor into @reftable_2, @constraintname_2 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [APP_DELEGATION] +END + + +CREATE TABLE [APP_DELEGATION] +( + [APP_UID] VARCHAR(32) default '' NOT NULL, + [DEL_INDEX] INT default 0 NOT NULL, + [DEL_PREVIOUS] INT default 0 NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [TAS_UID] VARCHAR(32) default '' NOT NULL, + [USR_UID] VARCHAR(32) default '' NOT NULL, + [DEL_TYPE] VARCHAR(32) default 'NORMAL' NOT NULL, + [DEL_THREAD] INT default 0 NOT NULL, + [DEL_THREAD_STATUS] VARCHAR(32) default 'OPEN' NOT NULL, + [DEL_PRIORITY] VARCHAR(32) default '0' NOT NULL, + [DEL_DELEGATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [DEL_INIT_DATE] DATETIME NOT NULL, + [DEL_TASK_DUE_DATE] DATETIME default '' NOT NULL, + [DEL_FINISH_DATE] DATETIME NULL, + CONSTRAINT APP_DELEGATION_PK PRIMARY KEY ([APP_UID],[DEL_INDEX]) +); + +/* ---------------------------------------------------------------------- */ +/* APP_DOCUMENT */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'APP_DOCUMENT') +BEGIN + DECLARE @reftable_3 nvarchar(60), @constraintname_3 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'APP_DOCUMENT' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_3, @constraintname_3 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_3+' drop constraint '+@constraintname_3) + FETCH NEXT from refcursor into @reftable_3, @constraintname_3 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [APP_DOCUMENT] +END + + +CREATE TABLE [APP_DOCUMENT] +( + [APP_DOC_UID] VARCHAR(32) default '' NOT NULL, + [APP_UID] VARCHAR(32) default '' NOT NULL, + [DEL_INDEX] INT default 0 NOT NULL, + [DOC_UID] VARCHAR(32) default '' NOT NULL, + [USR_UID] VARCHAR(32) default '' NOT NULL, + [APP_DOC_TYPE] VARCHAR(32) default '' NOT NULL, + [APP_DOC_CREATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + CONSTRAINT APP_DOCUMENT_PK PRIMARY KEY ([APP_DOC_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* APP_MESSAGE */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'APP_MESSAGE') +BEGIN + DECLARE @reftable_4 nvarchar(60), @constraintname_4 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'APP_MESSAGE' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_4, @constraintname_4 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_4+' drop constraint '+@constraintname_4) + FETCH NEXT from refcursor into @reftable_4, @constraintname_4 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [APP_MESSAGE] +END + + +CREATE TABLE [APP_MESSAGE] +( + [APP_MSG_UID] VARCHAR(32) default '' NOT NULL, + [MSG_UID] VARCHAR(32) NULL, + [APP_UID] VARCHAR(32) default '' NOT NULL, + [DEL_INDEX] INT default 0 NOT NULL, + [APP_MSG_TYPE] VARCHAR(100) default 'CUSTOM_MESSAGE' NOT NULL, + [APP_MSG_SUBJECT] VARCHAR(150) default '' NOT NULL, + [APP_MSG_FROM] VARCHAR(100) default '' NOT NULL, + [APP_MSG_TO] TEXT NOT NULL, + [APP_MSG_BODY] TEXT NOT NULL, + [APP_MSG_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [APP_MSG_CC] TEXT NULL, + [APP_MSG_BCC] TEXT NULL, + [APP_MSG_ATTACH] TEXT NULL, + CONSTRAINT APP_MESSAGE_PK PRIMARY KEY ([APP_MSG_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* APP_OWNER */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'APP_OWNER') +BEGIN + DECLARE @reftable_5 nvarchar(60), @constraintname_5 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'APP_OWNER' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_5, @constraintname_5 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_5+' drop constraint '+@constraintname_5) + FETCH NEXT from refcursor into @reftable_5, @constraintname_5 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [APP_OWNER] +END + + +CREATE TABLE [APP_OWNER] +( + [APP_UID] VARCHAR(32) default '' NOT NULL, + [OWN_UID] VARCHAR(32) default '' NOT NULL, + [USR_UID] VARCHAR(32) default '' NOT NULL, + CONSTRAINT APP_OWNER_PK PRIMARY KEY ([APP_UID],[OWN_UID],[USR_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* CONFIGURATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'CONFIGURATION') +BEGIN + DECLARE @reftable_6 nvarchar(60), @constraintname_6 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'CONFIGURATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_6, @constraintname_6 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_6+' drop constraint '+@constraintname_6) + FETCH NEXT from refcursor into @reftable_6, @constraintname_6 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [CONFIGURATION] +END + + +CREATE TABLE [CONFIGURATION] +( + [CFG_UID] VARCHAR(32) default '' NOT NULL, + [OBJ_UID] VARCHAR(128) default '' NOT NULL, + [CFG_VALUE] TEXT NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [USR_UID] VARCHAR(32) default '' NOT NULL, + [APP_UID] VARCHAR(32) default '' NOT NULL, + CONSTRAINT CONFIGURATION_PK PRIMARY KEY ([CFG_UID],[OBJ_UID],[PRO_UID],[USR_UID],[APP_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* CONTENT */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'CONTENT') +BEGIN + DECLARE @reftable_7 nvarchar(60), @constraintname_7 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'CONTENT' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_7, @constraintname_7 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_7+' drop constraint '+@constraintname_7) + FETCH NEXT from refcursor into @reftable_7, @constraintname_7 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [CONTENT] +END + + +CREATE TABLE [CONTENT] +( + [CON_CATEGORY] VARCHAR(30) default '' NOT NULL, + [CON_PARENT] VARCHAR(32) default '' NOT NULL, + [CON_ID] VARCHAR(100) default '' NOT NULL, + [CON_LANG] VARCHAR(10) default '' NOT NULL, + [CON_VALUE] TEXT NOT NULL, + CONSTRAINT CONTENT_PK PRIMARY KEY ([CON_CATEGORY],[CON_PARENT],[CON_ID],[CON_LANG]) +); + +/* ---------------------------------------------------------------------- */ +/* DEPARTMENT */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'DEPARTMENT') +BEGIN + DECLARE @reftable_8 nvarchar(60), @constraintname_8 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'DEPARTMENT' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_8, @constraintname_8 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_8+' drop constraint '+@constraintname_8) + FETCH NEXT from refcursor into @reftable_8, @constraintname_8 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [DEPARTMENT] +END + + +CREATE TABLE [DEPARTMENT] +( + [DEP_UID] VARCHAR(32) default '' NOT NULL, + [DEP_PARENT] VARCHAR(32) default '' NOT NULL, + [DEP_MANAGER] VARCHAR(32) default '' NOT NULL, + [DEP_LOCATION] INT default 0 NOT NULL, + [DEP_STATUS] CHAR(1) default 'A' NOT NULL, + [DEP_TYPE] VARCHAR(5) default 'INTER' NOT NULL, + [DEP_REF_CODE] VARCHAR(10) default '' NOT NULL, + CONSTRAINT DEPARTMENT_PK PRIMARY KEY ([DEP_UID]) +); + +CREATE INDEX [DEP_BYPARENT] ON [DEPARTMENT] ([DEP_PARENT]); + +/* ---------------------------------------------------------------------- */ +/* DYNAFORM */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'DYNAFORM') +BEGIN + DECLARE @reftable_9 nvarchar(60), @constraintname_9 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'DYNAFORM' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_9, @constraintname_9 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_9+' drop constraint '+@constraintname_9) + FETCH NEXT from refcursor into @reftable_9, @constraintname_9 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [DYNAFORM] +END + + +CREATE TABLE [DYNAFORM] +( + [DYN_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '0' NOT NULL, + [DYN_TYPE] VARCHAR(20) default 'xmlform' NOT NULL, + [DYN_FILENAME] VARCHAR(100) default '' NOT NULL, + CONSTRAINT DYNAFORM_PK PRIMARY KEY ([DYN_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* GROUPWF */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'GROUPWF') +BEGIN + DECLARE @reftable_10 nvarchar(60), @constraintname_10 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'GROUPWF' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_10, @constraintname_10 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_10+' drop constraint '+@constraintname_10) + FETCH NEXT from refcursor into @reftable_10, @constraintname_10 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [GROUPWF] +END + + +CREATE TABLE [GROUPWF] +( + [GRP_UID] VARCHAR(32) default '' NOT NULL, + [GRP_STATUS] CHAR(8) default 'ACTIVE' NOT NULL, + CONSTRAINT GROUPWF_PK PRIMARY KEY ([GRP_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* GROUP_USER */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'GROUP_USER') +BEGIN + DECLARE @reftable_11 nvarchar(60), @constraintname_11 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'GROUP_USER' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_11, @constraintname_11 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_11+' drop constraint '+@constraintname_11) + FETCH NEXT from refcursor into @reftable_11, @constraintname_11 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [GROUP_USER] +END + + +CREATE TABLE [GROUP_USER] +( + [GRP_UID] VARCHAR(32) default '0' NOT NULL, + [USR_UID] VARCHAR(32) default '0' NOT NULL, + CONSTRAINT GROUP_USER_PK PRIMARY KEY ([GRP_UID],[USR_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* HOLIDAY */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'HOLIDAY') +BEGIN + DECLARE @reftable_12 nvarchar(60), @constraintname_12 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'HOLIDAY' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_12, @constraintname_12 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_12+' drop constraint '+@constraintname_12) + FETCH NEXT from refcursor into @reftable_12, @constraintname_12 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [HOLIDAY] +END + + +CREATE TABLE [HOLIDAY] +( + [HLD_UID] INT NOT NULL IDENTITY, + [HLD_DATE] VARCHAR(10) default '0000-00-00' NOT NULL, + [HLD_DESCRIPTION] VARCHAR(200) default '' NOT NULL, + CONSTRAINT HOLIDAY_PK PRIMARY KEY ([HLD_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* INPUT_DOCUMENT */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'INPUT_DOCUMENT') +BEGIN + DECLARE @reftable_13 nvarchar(60), @constraintname_13 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'INPUT_DOCUMENT' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_13, @constraintname_13 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_13+' drop constraint '+@constraintname_13) + FETCH NEXT from refcursor into @reftable_13, @constraintname_13 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [INPUT_DOCUMENT] +END + + +CREATE TABLE [INPUT_DOCUMENT] +( + [INP_DOC_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '0' NOT NULL, + [INP_DOC_FORM_NEEDED] VARCHAR(20) default 'REAL' NOT NULL, + [INP_DOC_ORIGINAL] VARCHAR(20) default 'COPY' NOT NULL, + [INP_DOC_PUBLISHED] VARCHAR(20) default 'PRIVATE' NOT NULL, + CONSTRAINT INPUT_DOCUMENT_PK PRIMARY KEY ([INP_DOC_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* ISO_COUNTRY */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'ISO_COUNTRY') +BEGIN + DECLARE @reftable_14 nvarchar(60), @constraintname_14 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'ISO_COUNTRY' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_14, @constraintname_14 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_14+' drop constraint '+@constraintname_14) + FETCH NEXT from refcursor into @reftable_14, @constraintname_14 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [ISO_COUNTRY] +END + + +CREATE TABLE [ISO_COUNTRY] +( + [IC_UID] VARCHAR(2) default '' NOT NULL, + [IC_NAME] VARCHAR(255) NULL, + [IC_SORT_ORDER] VARCHAR(255) NULL, + CONSTRAINT ISO_COUNTRY_PK PRIMARY KEY ([IC_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* ISO_LOCATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'ISO_LOCATION') +BEGIN + DECLARE @reftable_15 nvarchar(60), @constraintname_15 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'ISO_LOCATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_15, @constraintname_15 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_15+' drop constraint '+@constraintname_15) + FETCH NEXT from refcursor into @reftable_15, @constraintname_15 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [ISO_LOCATION] +END + + +CREATE TABLE [ISO_LOCATION] +( + [IC_UID] VARCHAR(2) default '' NOT NULL, + [IL_UID] VARCHAR(5) default '' NOT NULL, + [IL_NAME] VARCHAR(255) NULL, + [IL_NORMAL_NAME] VARCHAR(255) NULL, + [IS_UID] VARCHAR(4) NULL, + CONSTRAINT ISO_LOCATION_PK PRIMARY KEY ([IC_UID],[IL_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* ISO_SUBDIVISION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'ISO_SUBDIVISION') +BEGIN + DECLARE @reftable_16 nvarchar(60), @constraintname_16 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'ISO_SUBDIVISION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_16, @constraintname_16 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_16+' drop constraint '+@constraintname_16) + FETCH NEXT from refcursor into @reftable_16, @constraintname_16 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [ISO_SUBDIVISION] +END + + +CREATE TABLE [ISO_SUBDIVISION] +( + [IC_UID] VARCHAR(2) default '' NOT NULL, + [IS_UID] VARCHAR(4) default '' NOT NULL, + [IS_NAME] VARCHAR(255) default '' NOT NULL, + CONSTRAINT ISO_SUBDIVISION_PK PRIMARY KEY ([IC_UID],[IS_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* KT_APPLICATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'KT_APPLICATION') +BEGIN + DECLARE @reftable_17 nvarchar(60), @constraintname_17 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'KT_APPLICATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_17, @constraintname_17 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_17+' drop constraint '+@constraintname_17) + FETCH NEXT from refcursor into @reftable_17, @constraintname_17 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [KT_APPLICATION] +END + + +CREATE TABLE [KT_APPLICATION] +( + [APP_UID] VARCHAR(32) default '' NOT NULL, + [KT_FOLDER_ID] INT default 0 NOT NULL, + [KT_PARENT_ID] INT default 0 NOT NULL, + [KT_FOLDER_NAME] VARCHAR(100) default '' NOT NULL, + [KT_FULL_PATH] VARCHAR(255) default '' NOT NULL, + [KT_CREATE_USER] VARCHAR(32) default '' NOT NULL, + [KT_CREATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [KT_UPDATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + CONSTRAINT KT_APPLICATION_PK PRIMARY KEY ([APP_UID]) +); + +CREATE INDEX [indexApp] ON [KT_APPLICATION] ([KT_FOLDER_ID]); + +/* ---------------------------------------------------------------------- */ +/* KT_PROCESS */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'KT_PROCESS') +BEGIN + DECLARE @reftable_18 nvarchar(60), @constraintname_18 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'KT_PROCESS' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_18, @constraintname_18 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_18+' drop constraint '+@constraintname_18) + FETCH NEXT from refcursor into @reftable_18, @constraintname_18 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [KT_PROCESS] +END + + +CREATE TABLE [KT_PROCESS] +( + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [KT_FOLDER_ID] INT default 0 NOT NULL, + [KT_PARENT_ID] INT default 0 NOT NULL, + [KT_FOLDER_NAME] VARCHAR(100) default '' NOT NULL, + [KT_FULL_PATH] VARCHAR(255) default '' NOT NULL, + [KT_CREATE_USER] VARCHAR(32) default '' NOT NULL, + [KT_CREATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [KT_UPDATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + CONSTRAINT KT_PROCESS_PK PRIMARY KEY ([PRO_UID]) +); + +CREATE INDEX [indexApp] ON [KT_PROCESS] ([KT_FOLDER_ID]); + +/* ---------------------------------------------------------------------- */ +/* LANGUAGE */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'LANGUAGE') +BEGIN + DECLARE @reftable_19 nvarchar(60), @constraintname_19 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'LANGUAGE' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_19, @constraintname_19 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_19+' drop constraint '+@constraintname_19) + FETCH NEXT from refcursor into @reftable_19, @constraintname_19 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [LANGUAGE] +END + + +CREATE TABLE [LANGUAGE] +( + [LAN_ID] VARCHAR(4) default '' NOT NULL, + [LAN_NAME] VARCHAR(30) default '' NOT NULL, + [LAN_NATIVE_NAME] VARCHAR(30) default '' NOT NULL, + [LAN_DIRECTION] CHAR(1) default 'L' NOT NULL, + [LAN_WEIGHT] INT default 0 NOT NULL, + [LAN_ENABLED] CHAR(1) default '1' NOT NULL, + [LAN_CALENDAR] VARCHAR(30) default 'GREGORIAN' NOT NULL +); + +/* ---------------------------------------------------------------------- */ +/* LEXICO */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'LEXICO') +BEGIN + DECLARE @reftable_20 nvarchar(60), @constraintname_20 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'LEXICO' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_20, @constraintname_20 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_20+' drop constraint '+@constraintname_20) + FETCH NEXT from refcursor into @reftable_20, @constraintname_20 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [LEXICO] +END + + +CREATE TABLE [LEXICO] +( + [LEX_TOPIC] VARCHAR(64) default '' NOT NULL, + [LEX_KEY] VARCHAR(128) default '' NOT NULL, + [LEX_VALUE] VARCHAR(128) default '' NOT NULL, + [LEX_CAPTION] VARCHAR(128) default '' NOT NULL, + CONSTRAINT LEXICO_PK PRIMARY KEY ([LEX_TOPIC],[LEX_KEY]) +); + +/* ---------------------------------------------------------------------- */ +/* OUTPUT_DOCUMENT */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'OUTPUT_DOCUMENT') +BEGIN + DECLARE @reftable_21 nvarchar(60), @constraintname_21 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'OUTPUT_DOCUMENT' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_21, @constraintname_21 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_21+' drop constraint '+@constraintname_21) + FETCH NEXT from refcursor into @reftable_21, @constraintname_21 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [OUTPUT_DOCUMENT] +END + + +CREATE TABLE [OUTPUT_DOCUMENT] +( + [OUT_DOC_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + CONSTRAINT OUTPUT_DOCUMENT_PK PRIMARY KEY ([OUT_DOC_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* PROCESS */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'PROCESS') +BEGIN + DECLARE @reftable_22 nvarchar(60), @constraintname_22 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'PROCESS' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_22, @constraintname_22 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_22+' drop constraint '+@constraintname_22) + FETCH NEXT from refcursor into @reftable_22, @constraintname_22 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [PROCESS] +END + + +CREATE TABLE [PROCESS] +( + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [PRO_PARENT] VARCHAR(32) default '0' NOT NULL, + [PRO_TIME] FLOAT default 1 NOT NULL, + [PRO_TIMEUNIT] VARCHAR(20) default 'DAYS' NOT NULL, + [PRO_STATUS] VARCHAR(20) default 'ACTIVE' NOT NULL, + [PRO_TYPE_DAY] CHAR(1) default '0' NOT NULL, + [PRO_TYPE] VARCHAR(20) default 'NORMAL' NOT NULL, + [PRO_ASSIGNMENT] VARCHAR(20) default 'FALSE' NOT NULL, + [PRO_SHOW_MAP] TINYINT default 1 NOT NULL, + [PRO_SHOW_MESSAGE] TINYINT default 1 NOT NULL, + [PRO_SHOW_DELEGATE] TINYINT default 1 NOT NULL, + [PRO_SHOW_DYNAFORM] TINYINT default 0 NOT NULL, + [PRO_CATEGORY] VARCHAR(48) default '' NOT NULL, + [PRO_SUB_CATEGORY] VARCHAR(48) default '' NOT NULL, + [PRO_INDUSTRY] INT default 1 NOT NULL, + [PRO_UPDATE_DATE] DATETIME default '' NULL, + [PRO_CREATE_DATE] DATETIME default '' NOT NULL, + [PRO_CREATE_USER] VARCHAR(32) default '' NOT NULL, + [PRO_HEIGHT] INT default 5000 NOT NULL, + [PRO_WIDTH] INT default 10000 NOT NULL, + [PRO_TITLE_X] INT default 0 NOT NULL, + [PRO_TITLE_Y] INT default 6 NOT NULL, + CONSTRAINT PROCESS_PK PRIMARY KEY ([PRO_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* PROCESS_OWNER */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'PROCESS_OWNER') +BEGIN + DECLARE @reftable_23 nvarchar(60), @constraintname_23 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'PROCESS_OWNER' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_23, @constraintname_23 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_23+' drop constraint '+@constraintname_23) + FETCH NEXT from refcursor into @reftable_23, @constraintname_23 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [PROCESS_OWNER] +END + + +CREATE TABLE [PROCESS_OWNER] +( + [OWN_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + CONSTRAINT PROCESS_OWNER_PK PRIMARY KEY ([OWN_UID],[PRO_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* ROUTE */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'ROUTE') +BEGIN + DECLARE @reftable_24 nvarchar(60), @constraintname_24 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'ROUTE' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_24, @constraintname_24 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_24+' drop constraint '+@constraintname_24) + FETCH NEXT from refcursor into @reftable_24, @constraintname_24 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [ROUTE] +END + + +CREATE TABLE [ROUTE] +( + [ROU_UID] VARCHAR(32) default '' NOT NULL, + [ROU_PARENT] VARCHAR(32) default '0' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [TAS_UID] VARCHAR(32) default '' NOT NULL, + [ROU_NEXT_TASK] VARCHAR(32) default '0' NOT NULL, + [ROU_CASE] INT default 0 NOT NULL, + [ROU_TYPE] VARCHAR(25) default 'SEQUENTIAL' NOT NULL, + [ROU_CONDITION] VARCHAR(255) default '' NOT NULL, + [ROU_TO_LAST_USER] VARCHAR(20) default 'FALSE' NOT NULL, + [ROU_OPTIONAL] VARCHAR(20) default 'FALSE' NOT NULL, + [ROU_SEND_EMAIL] VARCHAR(20) default 'TRUE' NOT NULL, + [ROU_SOURCEANCHOR] INT default 1 NULL, + [ROU_TARGETANCHOR] INT default 0 NULL, + CONSTRAINT ROUTE_PK PRIMARY KEY ([ROU_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* STEP */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'STEP') +BEGIN + DECLARE @reftable_25 nvarchar(60), @constraintname_25 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'STEP' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_25, @constraintname_25 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_25+' drop constraint '+@constraintname_25) + FETCH NEXT from refcursor into @reftable_25, @constraintname_25 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [STEP] +END + + +CREATE TABLE [STEP] +( + [STEP_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '0' NOT NULL, + [TAS_UID] VARCHAR(32) default '0' NOT NULL, + [STEP_TYPE_OBJ] VARCHAR(20) default 'DYNAFORM' NOT NULL, + [STEP_UID_OBJ] VARCHAR(32) default '0' NOT NULL, + [STEP_CONDITION] TEXT NOT NULL, + [STEP_POSITION] INT default 0 NOT NULL, + CONSTRAINT STEP_PK PRIMARY KEY ([STEP_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* STEP_TRIGGER */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'STEP_TRIGGER') +BEGIN + DECLARE @reftable_26 nvarchar(60), @constraintname_26 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'STEP_TRIGGER' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_26, @constraintname_26 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_26+' drop constraint '+@constraintname_26) + FETCH NEXT from refcursor into @reftable_26, @constraintname_26 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [STEP_TRIGGER] +END + + +CREATE TABLE [STEP_TRIGGER] +( + [STEP_UID] VARCHAR(32) default '' NOT NULL, + [TAS_UID] VARCHAR(32) default '' NOT NULL, + [TRI_UID] VARCHAR(32) default '' NOT NULL, + [ST_TYPE] VARCHAR(20) default '' NOT NULL, + [ST_CONDITION] VARCHAR(255) default '' NOT NULL, + [ST_POSITION] INT default 0 NOT NULL, + CONSTRAINT STEP_TRIGGER_PK PRIMARY KEY ([STEP_UID],[TAS_UID],[TRI_UID],[ST_TYPE]) +); + +/* ---------------------------------------------------------------------- */ +/* SWIMLANES_ELEMENTS */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'SWIMLANES_ELEMENTS') +BEGIN + DECLARE @reftable_27 nvarchar(60), @constraintname_27 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'SWIMLANES_ELEMENTS' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_27, @constraintname_27 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_27+' drop constraint '+@constraintname_27) + FETCH NEXT from refcursor into @reftable_27, @constraintname_27 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [SWIMLANES_ELEMENTS] +END + + +CREATE TABLE [SWIMLANES_ELEMENTS] +( + [SWI_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [SWI_TYPE] VARCHAR(20) default 'LINE' NOT NULL, + [SWI_X] INT default 0 NOT NULL, + [SWI_Y] INT default 0 NOT NULL, + CONSTRAINT SWIMLANES_ELEMENTS_PK PRIMARY KEY ([SWI_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* TASK */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'TASK') +BEGIN + DECLARE @reftable_28 nvarchar(60), @constraintname_28 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'TASK' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_28, @constraintname_28 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_28+' drop constraint '+@constraintname_28) + FETCH NEXT from refcursor into @reftable_28, @constraintname_28 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [TASK] +END + + +CREATE TABLE [TASK] +( + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [TAS_UID] VARCHAR(32) default '' NOT NULL, + [TAS_TYPE] VARCHAR(20) default 'NORMAL' NOT NULL, + [TAS_DURATION] FLOAT default 0 NOT NULL, + [TAS_DELAY_TYPE] VARCHAR(30) default '' NOT NULL, + [TAS_TEMPORIZER] FLOAT default 0 NOT NULL, + [TAS_TYPE_DAY] CHAR(1) default '1' NOT NULL, + [TAS_TIMEUNIT] VARCHAR(20) default 'DAYS' NOT NULL, + [TAS_ALERT] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_PRIORITY_VARIABLE] VARCHAR(100) default '' NOT NULL, + [TAS_ASSIGN_TYPE] VARCHAR(30) default 'BALANCED' NOT NULL, + [TAS_ASSIGN_VARIABLE] VARCHAR(100) default '@@SYS_NEXT_USER_TO_BE_ASSIGNED' NOT NULL, + [TAS_ASSIGN_LOCATION] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_ASSIGN_LOCATION_ADHOC] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_TRANSFER_FLY] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_LAST_ASSIGNED] VARCHAR(32) default '0' NOT NULL, + [TAS_USER] VARCHAR(32) default '0' NOT NULL, + [TAS_CAN_UPLOAD] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_VIEW_UPLOAD] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_VIEW_ADDITIONAL_DOCUMENTATION] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_CAN_CANCEL] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_OWNER_APP] VARCHAR(32) default '' NOT NULL, + [STG_UID] VARCHAR(32) default '' NOT NULL, + [TAS_CAN_PAUSE] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_CAN_SEND_MESSAGE] VARCHAR(20) default 'TRUE' NOT NULL, + [TAS_CAN_DELETE_DOCS] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_SELF_SERVICE] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_START] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_TO_LAST_USER] VARCHAR(20) default 'FALSE' NOT NULL, + [TAS_SEND_LAST_EMAIL] VARCHAR(20) default 'TRUE' NOT NULL, + [TAS_DERIVATION] VARCHAR(100) default 'NORMAL' NOT NULL, + [TAS_POSX] INT default 0 NOT NULL, + [TAS_POSY] INT default 0 NOT NULL, + [TAS_COLOR] VARCHAR(32) default '' NOT NULL, + CONSTRAINT TASK_PK PRIMARY KEY ([TAS_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* TASK_USER */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'TASK_USER') +BEGIN + DECLARE @reftable_29 nvarchar(60), @constraintname_29 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'TASK_USER' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_29, @constraintname_29 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_29+' drop constraint '+@constraintname_29) + FETCH NEXT from refcursor into @reftable_29, @constraintname_29 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [TASK_USER] +END + + +CREATE TABLE [TASK_USER] +( + [TAS_UID] VARCHAR(32) default '' NOT NULL, + [USR_UID] VARCHAR(32) default '' NOT NULL, + [TU_TYPE] INT default 1 NOT NULL, + [TU_RELATION] INT default 0 NOT NULL, + CONSTRAINT TASK_USER_PK PRIMARY KEY ([TAS_UID],[USR_UID],[TU_TYPE],[TU_RELATION]) +); + +/* ---------------------------------------------------------------------- */ +/* TRANSLATION */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'TRANSLATION') +BEGIN + DECLARE @reftable_30 nvarchar(60), @constraintname_30 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'TRANSLATION' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_30, @constraintname_30 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_30+' drop constraint '+@constraintname_30) + FETCH NEXT from refcursor into @reftable_30, @constraintname_30 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [TRANSLATION] +END + + +CREATE TABLE [TRANSLATION] +( + [TRN_CATEGORY] VARCHAR(100) default '' NOT NULL, + [TRN_ID] VARCHAR(100) default '' NOT NULL, + [TRN_LANG] VARCHAR(10) default 'en' NOT NULL, + [TRN_VALUE] VARCHAR(200) default '' NOT NULL, + CONSTRAINT TRANSLATION_PK PRIMARY KEY ([TRN_CATEGORY],[TRN_ID],[TRN_LANG]) +); + +/* ---------------------------------------------------------------------- */ +/* TRIGGERS */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'TRIGGERS') +BEGIN + DECLARE @reftable_31 nvarchar(60), @constraintname_31 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'TRIGGERS' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_31, @constraintname_31 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_31+' drop constraint '+@constraintname_31) + FETCH NEXT from refcursor into @reftable_31, @constraintname_31 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [TRIGGERS] +END + + +CREATE TABLE [TRIGGERS] +( + [TRI_UID] VARCHAR(32) default '' NOT NULL, + [PRO_UID] VARCHAR(32) default '' NOT NULL, + [TRI_TYPE] VARCHAR(20) default 'SCRIPT' NOT NULL, + [TRI_WEBBOT] TEXT NOT NULL, + CONSTRAINT TRIGGERS_PK PRIMARY KEY ([TRI_UID]) +); + +/* ---------------------------------------------------------------------- */ +/* USERS */ +/* ---------------------------------------------------------------------- */ + + +IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'USERS') +BEGIN + DECLARE @reftable_32 nvarchar(60), @constraintname_32 nvarchar(60) + DECLARE refcursor CURSOR FOR + select reftables.name tablename, cons.name constraintname + from sysobjects tables, + sysobjects reftables, + sysobjects cons, + sysreferences ref + where tables.id = ref.rkeyid + and cons.id = ref.constid + and reftables.id = ref.fkeyid + and tables.name = 'USERS' + OPEN refcursor + FETCH NEXT from refcursor into @reftable_32, @constraintname_32 + while @@FETCH_STATUS = 0 + BEGIN + exec ('alter table '+@reftable_32+' drop constraint '+@constraintname_32) + FETCH NEXT from refcursor into @reftable_32, @constraintname_32 + END + CLOSE refcursor + DEALLOCATE refcursor + DROP TABLE [USERS] +END + + +CREATE TABLE [USERS] +( + [USR_UID] VARCHAR(32) default '' NOT NULL, + [USR_USERNAME] VARCHAR(100) default '' NOT NULL, + [USR_PASSWORD] VARCHAR(32) default '' NOT NULL, + [USR_FIRSTNAME] VARCHAR(50) default '' NOT NULL, + [USR_LASTNAME] VARCHAR(50) default '' NOT NULL, + [USR_EMAIL] VARCHAR(100) default '' NOT NULL, + [USR_DUE_DATE] DATETIME default '0000-00-00' NOT NULL, + [USR_CREATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [USR_UPDATE_DATE] DATETIME default '0000-00-00 00:00:00' NOT NULL, + [USR_STATUS] INT default 1 NOT NULL, + [USR_COUNTRY] VARCHAR(3) default '' NOT NULL, + [USR_CITY] VARCHAR(3) default '' NOT NULL, + [USR_LOCATION] VARCHAR(3) default '' NOT NULL, + [USR_ADDRESS] VARCHAR(255) default '' NOT NULL, + [USR_PHONE] VARCHAR(24) default '' NOT NULL, + [USR_FAX] VARCHAR(24) default '' NOT NULL, + [USR_CELLULAR] VARCHAR(24) default '' NOT NULL, + [USR_ZIP_CODE] VARCHAR(16) default '' NOT NULL, + [USR_DEPARTMENT] INT default 0 NOT NULL, + [USR_POSITION] VARCHAR(100) default '' NOT NULL, + [USR_RESUME] VARCHAR(100) default '' NOT NULL, + [USR_BIRTHDAY] DATETIME default '0000-00-00' NOT NULL, + [USR_ROLE] VARCHAR(32) default 'PROCESSMAKER_ADMIN' NULL, + CONSTRAINT USERS_PK PRIMARY KEY ([USR_UID]) +); diff --git a/workflow/engine/data/mssql/sqldb.map b/workflow/engine/data/mssql/sqldb.map new file mode 100644 index 000000000..fc15b9e86 --- /dev/null +++ b/workflow/engine/data/mssql/sqldb.map @@ -0,0 +1,2 @@ +# Sqlfile -> Database map +schema.sql=workflow diff --git a/workflow/engine/data/mysql/create-db.sql b/workflow/engine/data/mysql/create-db.sql new file mode 100644 index 000000000..3b4cdf4be --- /dev/null +++ b/workflow/engine/data/mysql/create-db.sql @@ -0,0 +1,2 @@ +drop database if exists workflow; +create database workflow; diff --git a/workflow/engine/data/mysql/insert.sql b/workflow/engine/data/mysql/insert.sql new file mode 100755 index 000000000..b7bea2ad9 --- /dev/null +++ b/workflow/engine/data/mysql/insert.sql @@ -0,0 +1,9 @@ +INSERT INTO `CONTENT` VALUES ('ROL_NAME','','00000000000000000000000000000002','en','System Administrator'),('ROL_NAME','','00000000000000000000000000000003','en','Operator'); +INSERT INTO `ISO_COUNTRY` VALUES ('AD','Andorra','\r'),('AE','United Arab Emirates','\r'),('AF','Afghanistan','\r'),('AG','Antigua and Barbuda','\r'),('AI','Anguilla','\r'),('AL','Albania','Albanian sorting order: a-c, ç, d, dh, e, ë, f-g, gj, h-l, ll, m-n, nj, o-r, rr, s, sh, t, th, u-x, xh, y-z, zh\r'),('AM','Armenia','\r'),('AN','Netherlands Antilles','\r'),('AO','Angola','\r'),('AQ','Antarctica','\r'),('AR','Argentina','Spanish sorting order: a-c, ch, d-l, ll, m-n, ñ, o-z\r'),('AS','American Samoa','\r'),('AT','Austria','\r'),('AU','Australia','\r'),('AW','Aruba','\r'),('AZ','Azerbaijan','\r'),('BA','Bosnia and Herzegovina','\r'),('BB','Barbados','\r'),('BD','Bangladesh','\r'),('BE','Belgium','\r'),('BF','Burkina Faso','\r'),('BG','Bulgaria','\r'),('BH','Bahrain','\r'),('BI','Burundi','\r'),('BJ','Benin','\r'),('BM','Bermuda','\r'),('BN','Brunei Darussalam','\r'),('BO','Bolivia','Spanish sorting order: a-c, ch, d-l, ll, m-n, ñ, o-z\r'),('BR','Brazil','\r'),('BS','Bahamas',NULL),('BT','Bhutan',NULL),('BW','Botswana',NULL),('BY','Belarus',NULL),('BZ','Belize',NULL),('CA','Canada',NULL),('CC','Cocos (Keeling) Islands',NULL),('CD','Congo, The Democratic Republic of the',NULL),('CF','Central African Republic',NULL),('CG','Congo',NULL),('CH','Switzerland',NULL),('CI','Côte-d\' lvoire',NULL),('CK','Cook Islands',NULL),('CL','Chile',NULL),('CM','Cameroon',NULL),('CN','China',NULL),('CO','Colombia','Spanish sorting order: a-c, ch, d-l, ll, m-n, ñ, o-z\r'),('CR','Costa Rica','\r'),('CS','Serbia and Montenegro',NULL),('CU','Cuba','\r'),('CV','Cape Verde','\r'),('CX','Christmas Island','\r'),('CY','Cyprus','\r'),('CZ','Czech Republic','\r'),('DE','Germany','\r'),('DJ','Djibouti','\r'),('DK','Denmark','a-z, æ,ø,Ã¥\r'),('DM','Dominica','\r'),('DO','Dominican Republic','\r'),('DZ','Algeria','\r'),('EC','Ecuador','\r'),('EE','Estonia','Estonian sorting order: a-s, s, z, z,t-v,õ, ä, ö, ü\r'),('EG','Egypt','\r'),('EH','Western Sahara','\r'),('ER','Eritrea','\r'),('ES','Spain','\r'),('ET','Ethiopia','\r'),('FI','Finland','Finnish and Swedish sorting order: a-z, Ã¥ , ä, ö\r'),('FJ','Fiji','\r'),('FK','Falkland Islands (Malvinas)','\r'),('FM','Micronesia, Federated States of','\r'),('FO','Faroe Islands','\r'),('FR','France','\r'),('GA','Gabon','\r'),('GB','United Kingdom','\r'),('GD','Grenada','\r'),('GE','Georgia','\r'),('GF','French Guiana','\r'),('GG','Guernsey',NULL),('GH','Ghana','\r'),('GI','Gibraltar',NULL),('GL','Greenland',NULL),('GM','Gambia',NULL),('GN','Guinea',NULL),('GP','Guadeloupe',NULL),('GQ','Equatorial Guinea',NULL),('GR','Greece',NULL),('GS','South Georgia and the South Sandwich Islands',NULL),('GT','Guatemala',NULL),('GU','Guam',NULL),('GW','Guinea-Bissau',NULL),('GY','Guyana',NULL),('HK','Hong Kong',NULL),('HM','Heard Island and McDonald Islands',NULL),('HN','Honduras',NULL),('HR','Croatia',NULL),('HT','Haiti',NULL),('HU','Hungary',NULL),('ID','Indonesia',NULL),('IE','Ireland',NULL),('IL','Israel',NULL),('IM','Isle of Man',NULL),('IN','India',NULL),('IO','British Indian Ocean Territory',NULL),('IQ','Iraq',NULL),('IR','Iran, Islamic Republic of',NULL),('IS','Iceland',NULL),('IT','Italy',NULL),('JE','Jersey',NULL),('JM','Jamaica',NULL),('JO','Jordan',NULL),('JP','Japan',NULL),('KE','Kenya',NULL),('KG','Kyrgyzstan',NULL),('KH','Cambodia',NULL),('KI','Kiribati',NULL),('KM','Comoros',NULL),('KN','Saint Kitts and Nevis',NULL),('KP','Korea, Democratic People\'s Republic of',NULL),('KR','Korea, Republic of',NULL),('KW','Kuwait',NULL),('KY','Cayman Islands',NULL),('KZ','Kazakhstan',NULL),('LA','Lao People\'s Democratic Republic',NULL),('LB','Lebanon',NULL),('LC','Saint Lucia',NULL),('LI','Liechtenstein',NULL),('LK','Sri Lanka',NULL),('LR','Liberia',NULL),('LS','Lesotho',NULL),('LT','Lithuania',NULL),('LU','Luxembourg',NULL),('LV','Latvia','Latvian sorting order: a, ?, b-c, ?, ch, d, dz, e, ?, f-g, g?, h-I, ?, ie, j-k, ?, l, ?, m-n, ?, o, ?, p-r, ?, s, Å¡, t, u, ?, v, z, ž\r'),('LY','Libyan Arab Jamahiriya','\r'),('MA','Morocco','\r'),('MC','Monaco','\r'),('MD','Moldova, Republic of','\r'),('ME','Montenegro',NULL),('MG','Madagascar','\r'),('MH','Marshall Islands','\r'),('MK','Macedonia, The former Yugoslav Republic of','Macedonian sorting order: a-c, ?, d-s, Å¡, t-z, ž\r'),('ML','Mali','\r'),('MM','Myanmar','\r'),('MN','Mongolia','\r'),('MO','Macao','\r'),('MP','Northern Mariana Islands','\r'),('MQ','Martinique','\r'),('MR','Mauritania','\r'),('MS','Montserrat','\r'),('MT','Malta','\r'),('MU','Mauritius','\r'),('MV','Maldives','\r'),('MW','Malawi','\r'),('MX','Mexico','Spanish sorting order: a-c, ch, d-l, ll, m-n, ñ, o-z\r'),('MY','Malaysia','\r'),('MZ','Mozambique','\r'),('NA','Namibia','\r'),('NC','New Caledonia','\r'),('NE','Niger','\r'),('NF','Norfolk Island','\r'),('NG','Nigeria','\r'),('NI','Nicaragua','\r'),('NL','Netherlands','\r'),('NO','Norway','Norwegian sorting order: a-z, æ, ø, Ã¥\r'),('NP','Nepal',NULL),('NR','Nauru',NULL),('NU','Niue',NULL),('NZ','New Zealand',NULL),('OM','Oman',NULL),('PA','Panama',NULL),('PE','Peru',NULL),('PF','French Polynesia',NULL),('PG','Papua New Guinea',NULL),('PH','Philippines',NULL),('PK','Pakistan',NULL),('PL','Poland',NULL),('PM','Saint Pierre and Miquelon',NULL),('PN','Pitcairn',NULL),('PR','Puerto Rico',NULL),('PT','Portugal',NULL),('PW','Palau','\r'),('PY','Paraguay','\r'),('QA','Qatar','\r'),('RE','Reunion',''),('RO','Romania','\r'),('RS','Serbia',NULL),('RU','Russian Federation','\r'),('RW','Rwanda','\r'),('SA','Saudi Arabia','\r'),('SB','Solomon Islands','\r'),('SC','Seychelles','\r'),('SD','Sudan','\r'),('SE','Sweden','a-z, Ã¥, ä, ö\r'),('SG','Singapore','\r'),('SH','Saint Helena','\r'),('SI','Slovenia','\r'),('SJ','Svalbard and Jan Mayen','\r'),('SK','Slovakia','\r'),('SL','Sierra Leone','\r'),('SM','San Marino','\r'),('SN','Senegal',NULL),('SO','Somalia',NULL),('SR','Suriname',NULL),('ST','Sao Tome and Principe',NULL),('SV','El Salvador',NULL),('SY','Syrian Arab Republic',NULL),('SZ','Swaziland',NULL),('TC','Turks and Caicos Islands',NULL),('TD','Chad',NULL),('TF','French Southern Territories',NULL),('TG','Togo',NULL),('TH','Thailand',NULL),('TJ','Tajikistan',NULL),('TK','Tokelau',NULL),('TL','Timor-Leste','\r'),('TM','Turkmenistan','\r'),('TN','Tunisia','\r'),('TO','Tonga','\r'),('TR','Turkey','Tuskish sorting order: a-c, ç, d-g, g, h,I, I-o, ö, p-s, s, t-u, ü, v-z\r'),('TT','Trinidad and Tobago','\r'),('TV','Tuvalu','\r'),('TW','Taiwan, Province of China','\r'),('TZ','Tanzania, United Republic of','\r'),('UA','Ukraine','\r'),('UG','Uganda','\r'),('UM','United States Minor Outlying Islands','\r'),('US','United States','\r'),('UY','Uruguay','\r'),('UZ','Uzbekistan','\r'),('VA','Holy See (Vatican City State)','\r'),('VC','Saint Vincent and the Grenadines',NULL),('VE','Venezuela',NULL),('VG','Virgin Islands, British',NULL),('VI','Virgin Islands, U.S.',NULL),('VN','Viet Nam',NULL),('VU','Vanuatu',NULL),('WF','Wallis and Futuna',NULL),('WS','Samoa',NULL),('XZ','Installations in International Waters',NULL),('YE','Yemen',NULL),('YT','Mayotte',NULL),('ZA','South Africa',NULL),('ZM','Zambia',NULL),('ZW','Zimbabwe',NULL); +INSERT INTO `ISO_LOCATION` VALUES ('AD','','','',''),('AD','ALV','Andorra la Vella','Andorra la Vella',''),('AD','CAN','Canillo','Canillo',''),('AD','ENC','Encamp','Encamp',''),('AD','ESC','Escaldes-Engordany','Escaldes-Engordany',''),('AD','FMO','La Farga de Moles','La Farga de Moles',''),('AD','LMA','La Massana','La Massana',''),('AD','ORD','Ordino','Ordino',''),('AD','PAS','Pas de la Casa','Pas de la Casa',''),('AD','SCO','Santa Coloma','Santa Coloma',''),('AD','SJL','Sant Julia','Sant Julia',''),('AE','','','',''),('AE','AAN','Al Ain','Al Ain',''),('AE','ABU','Abu al Bukhoosh','Abu al Bukhoosh',''),('AE','AJM','Ajman','Ajman',''),('AE','AMU','Abu Musa','Abu Musa',''),('AE','ARZ','Arzanah Island','Arzanah Island',''),('AE','AUH','Abu Dhabi','Abu Dhabi',''),('AE','DAS','Das Island','Das Island',''),('AE','DBP','Dibba','Dibba',''),('AE','DHF','Al Dhafra','Al Dhafra',''),('AE','DUY','Ras Zubbaya (Ras Dubayyah)','Ras Zubbaya (Ras Dubayyah)',''),('AE','DXB','Dubai','Dubai',''),('AE','FAT','Fateh Terminal','Fateh Terminal',''),('AE','FJR','Al Fujayrah','Al Fujayrah',''),('AE','FMZ','Musafa','Musafa',''),('AE','HAM','Al Hamriyah','Al Hamriyah',''),('AE','IND','Indooroodilly','Indooroodilly',''),('AE','JEA','Jebel Ali','Jebel Ali',''),('AE','JED','Jebel Dhanna','Jebel Dhanna',''),('AE','JYH','Jumayrah','Jumayrah',''),('AE','KHA','Khalidia','Khalidia',''),('AE','KLB','Kalba','Kalba',''),('AE','KLF','Khor al Fakkan','Khor al Fakkan',''),('AE','MAS','Masfut','Masfut',''),('AE','MBS','Mubarras Island','Mubarras Island',''),('AE','MKH','Mina Khalid','Mina Khalid',''),('AE','MSA','Mina Saqr','Mina Saqr',''),('AE','MUB','Mubarek Terminal','Mubarek Terminal',''),('AE','MZD','Mina Zayed/Abu Dhabi','Mina Zayed/Abu Dhabi',''),('AE','NHD','Minhad','Minhad',''),('AE','PRA','Port Rashid','Port Rashid',''),('AE','QIW','Umm al Qaiwain','Umm al Qaiwain',''),('AE','RKT','Ras al Khaimah','Ras al Khaimah',''),('AE','RUW','Ar Ruways','Ar Ruways',''),('AE','SHJ','Sharjah','Sharjah',''),('AE','UEZ','Suez','Suez',''),('AE','ULR','Umm Al Nar','Umm Al Nar',''),('AE','ZUR','Zirku Island','Zirku Island',''),('AF','','','',''),('AF','BAG','Bagram','Bagram',''),('AF','BIN','Bamian','Bamian',''),('AF','BST','Bost','Bost',''),('AF','CCN','Chakcharan','Chakcharan',''),('AF','DAZ','Darwaz','Darwaz',''),('AF','FAH','Farah','Farah',''),('AF','FBD','Faizabad','Faizabad',''),('AF','GRG','Gardez','Gardez',''),('AF','GZI','Ghazni','Ghazni',''),('AF','HEA','Herat','Herat',''),('AF','HRT','Hairatan','Hairatan',''),('AF','IMZ','Nimroz','Nimroz',''),('AF','ISQ','Eslam Qal\'eh','Eslam Qal\'eh',''),('AF','JAA','Jalalabad','Jalalabad',''),('AF','KBL','Kabul','Kabul',''),('AF','KDH','Kandahar','Kandahar',''),('AF','KHO','Khowst','Khowst',''),('AF','KHT','Khost','Khost',''),('AF','KUR','Kuran-O-Munjan','Kuran-O-Munjan',''),('AF','KWH','Khwahan','Khwahan',''),('AF','LQN','Qala Nau','Qala Nau',''),('AF','MAS','Mashad','Mashad',''),('AF','MMZ','Maimana','Maimana',''),('AF','MZR','Mazar-i-Sharif','Mazar-i-Sharif',''),('AF','QLT','Qalat','Qalat',''),('AF','SBF','Sardeh Band','Sardeh Band',''),('AF','SGA','Sheghnan','Sheghnan',''),('AF','TGH','Torghundi','Torghundi',''),('AF','TII','Tirinkot','Tirinkot',''),('AF','TQN','Taluqan','Taluqan',''),('AF','UND','Kunduz','Kunduz',''),('AF','URN','Urgoon','Urgoon',''),('AF','URZ','Uruzgan','Uruzgan',''),('AF','ZAJ','Zaranj','Zaranj',''),('AG','','','',''),('AG','ANU','Antigua','Antigua',''),('AG','BBQ','Barbuda','Barbuda',''),('AG','SJO','St John\'s','St John\'s',''),('AI','','','',''),('AI','AXA','Anguilla','Anguilla',''),('AI','BLP','Blowing Point','Blowing Point',''),('AI','CRH','Crocus Hill','Crocus Hill',''),('AI','FOR','The Forest','The Forest',''),('AI','RBY','Road Bay','Road Bay',''),('AI','ROA','The Road','The Road',''),('AI','VAL','The Valley','The Valley',''),('AI','WLL','Wall Blake','Wall Blake',''),('AL','','','',''),('AL','DRZ','Durres','Durres',''),('AL','KRC','Korce','Korce',''),('AL','SAR','Sarande','Sarande',''),('AL','SHG','Shengjin','Shengjin',''),('AL','TEN','Tenes','Tenes',''),('AL','TIA','Tirana','Tirana',''),('AL','VOA','Vlora','Vlora',''),('AM','','','',''),('AM','ABO','Abovyan','Abovyan',''),('AM','AHU','Akhuryan','Akhuryan',''),('AM','ARA','Ararat','Ararat',''),('AM','EVN','Yerevan','Yerevan',''),('AM','EZN','Ecmiadzin','Ecmiadzin',''),('AM','LWN','Gyumri','Gyumri',''),('AM','VZR','Vanadzor','Vanadzor',''),('AN','','','',''),('AN','BON','Bonaire','Bonaire',''),('AN','BOT','The Bottom','The Bottom',''),('AN','BUB','Bullenbaai','Bullenbaai',''),('AN','CRB','Caracas Baai, Curacao','Caracas Baai, Curacao',''),('AN','CUR','Curacao','Curacao',''),('AN','EMM','Emmastad','Emmastad',''),('AN','EUX','Sint Eustatius','Sint Eustatius',''),('AN','FUI','Fuikbaai, Curacao','Fuikbaai, Curacao',''),('AN','GES','Gallis Bay, St.Marten','Gallis Bay, St.Marten',''),('AN','KRA','Kralendijk, Bonaire','Kralendijk, Bonaire',''),('AN','OTB','Otrobanda','Otrobanda',''),('AN','PHI','Philipsburg','Philipsburg',''),('AN','PUN','Punda','Punda',''),('AN','RIN','Dorp Rincon, Bonaire','Dorp Rincon, Bonaire',''),('AN','SAB','Saba','Saba',''),('AN','SMB','Sint Michielsbaai','Sint Michielsbaai',''),('AN','STR','Santa Rosa, Curacao','Santa Rosa, Curacao',''),('AN','SXM','Sint-Maarten Apt','Sint-Maarten Apt',''),('AN','WIL','Willemstad, Curacao','Willemstad, Curacao',''),('AO','','','',''),('AO','ANL','Andulo','Andulo',''),('AO','ARZ','N\'Zeto','N\'Zeto',''),('AO','AZZ','Ambriz','Ambriz',''),('AO','BDD','Barra do Dande','Barra do Dande',''),('AO','BDT','Baia dos Tigres','Baia dos Tigres',''),('AO','BUG','Benguela','Benguela',''),('AO','CAB','Cabinda','Cabinda',''),('AO','CAV','Cazombo','Cazombo',''),('AO','CBT','Catumbela','Catumbela',''),('AO','CEO','Waku Kungo','Waku Kungo',''),('AO','CFF','Cafunfo','Cafunfo',''),('AO','CNZ','Cangamba','Cangamba',''),('AO','CTI','Cuito Cuanavale','Cuito Cuanavale',''),('AO','DAL','Dalia','Dalia',''),('AO','DGR','Dombe Grande','Dombe Grande',''),('AO','DRC','Dirico','Dirico',''),('AO','DUE','Dundo','Dundo',''),('AO','GGC','Lumbala','Lumbala',''),('AO','GXG','Negage','Negage',''),('AO','JMB','Jamba','Jamba',''),('AO','KNP','Capanda','Capanda',''),('AO','LAA','Landana (Cacongo)','Landana (Cacongo)',''),('AO','LAD','Luanda','Luanda',''),('AO','LBZ','Lukapa','Lukapa',''),('AO','LIE','Lieura','Lieura',''),('AO','LOB','Lobito','Lobito',''),('AO','LUC','Lucira','Lucira',''),('AO','LUO','Luena','Luena',''),('AO','LZM','Luzamba','Luzamba',''),('AO','MAL','Malongo','Malongo',''),('AO','MEG','Malange','Malange',''),('AO','MLO','Malembo','Malembo',''),('AO','MSZ','Namibe','Namibe',''),('AO','NDD','Sumbe','Sumbe',''),('AO','NDF','N\'dalatando','N\'dalatando',''),('AO','NGV','Ondjiva','Ondjiva',''),('AO','NOV','Huambo','Huambo',''),('AO','NRQ','N\'Riquinha','N\'Riquinha',''),('AO','NZA','Nzagi','Nzagi',''),('AO','PAT','Palanca Terminal','Palanca Terminal',''),('AO','PBN','Porto Amboim','Porto Amboim',''),('AO','PGI','Chitato','Chitato',''),('AO','PLE','Porto Alexandre (Tombua)','Porto Alexandre (Tombua)',''),('AO','SDD','Lubango','Lubango',''),('AO','SOQ','Soyo-Quinfuquena Terminal','Soyo-Quinfuquena Terminal',''),('AO','SPP','Menongue','Menongue',''),('AO','SSY','M\'banza Congo','M\'banza Congo',''),('AO','SVP','Kuito','Kuito',''),('AO','SZA','Soyo','Soyo',''),('AO','TAK','Takula Terminal','Takula Terminal',''),('AO','UAL','Luau','Luau',''),('AO','UGO','Uige','Uige',''),('AO','VHC','Saurimo','Saurimo',''),('AO','VPE','Ongiva','Ongiva',''),('AO','XGN','Xangongo','Xangongo',''),('AQ','','','',''),('AQ','ABA','Aboa','Aboa',''),('AQ','AMS','Amundsen-Scott','Amundsen-Scott',''),('AQ','APT','Arturo Prat','Arturo Prat',''),('AQ','ARC','Arctowski','Arctowski',''),('AQ','ART','Artigas','Artigas',''),('AQ','BEL','Belgrano II','Belgrano II',''),('AQ','BHN','Bellingshausen','Bellingshausen',''),('AQ','CAS','Casey','Casey',''),('AQ','CFZ','Comandante Ferraz','Comandante Ferraz',''),('AQ','CON','Concordia','Concordia',''),('AQ','DAV','Davis','Davis',''),('AQ','DDU','Dumont d\'Urveille','Dumont d\'Urveille',''),('AQ','DMF','Dome Fuji','Dome Fuji',''),('AQ','DRZ','Druzhnaya 4','Druzhnaya 4',''),('AQ','ESC','Escudero','Escudero',''),('AQ','ESP','Esperanza','Esperanza',''),('AQ','GDC','Gabriel de Castilla','Gabriel de Castilla',''),('AQ','GWL','Great Wall','Great Wall',''),('AQ','HLY','Halley','Halley',''),('AQ','JCP','Juan Carlos Primero','Juan Carlos Primero',''),('AQ','JUB','Jubany','Jubany',''),('AQ','KHN','Kohnen','Kohnen',''),('AQ','KSG','King Sejong','King Sejong',''),('AQ','LAW','Law Base','Law Base',''),('AQ','MAW','Mawson','Mawson',''),('AQ','MCM','McMurdo','McMurdo',''),('AQ','MIR','Mirny','Mirny',''),('AQ','MRB','Marambio','Marambio',''),('AQ','MTR','Maitri','Maitri',''),('AQ','MZU','Mario Zucchelli','Mario Zucchelli',''),('AQ','NEU','Neumayer','Neumayer',''),('AQ','NOV','Novolazarevskaya','Novolazarevskaya',''),('AQ','OHG','General Bernardo O\'higgins','General Bernardo O\'higgins',''),('AQ','ORC','Orcadas','Orcadas',''),('AQ','PLM','Palmer','Palmer',''),('AQ','PRO','Progress','Progress',''),('AQ','ROT','Rothera','Rothera',''),('AQ','SBA','Scott Base','Scott Base',''),('AQ','SGN','Signy','Signy',''),('AQ','SMT','San Martin','San Martin',''),('AQ','SNA','SANAE IV','SANAE IV',''),('AQ','SYW','Syowa','Syowa',''),('AQ','TNM','Teniente R. Marsh','Teniente R. Marsh',''),('AQ','TOR','Tor','Tor',''),('AQ','TRL','Troll','Troll',''),('AQ','VKY','Vernadsky','Vernadsky',''),('AQ','VOS','Vostok','Vostok',''),('AQ','WSA','Wasa','Wasa',''),('AQ','ZGN','Zhongshan','Zhongshan',''),('AR','','','',''),('AR','ACF','Arrecifes','Arrecifes','B'),('AR','AEP','Jorge Newbury Apt/Buenos Aires','Jorge Newbury Apt/Buenos Aires','B'),('AR','AFA','San Rafael','San Rafael','M'),('AR','ALI','Alberti','Alberti','B'),('AR','ALL','Allen','Allen','R'),('AR','ANA','Anatuya','Anatuya','G'),('AR','AND','Andalgala','Andalgala','K'),('AR','AOL','Paso de los Libres','Paso de los Libres','W'),('AR','APZ','Zapala','Zapala','Q'),('AR','ARR','Alto Rio Senguerr','Alto Rio Senguerr','U'),('AR','ATU','Atucha','Atucha','B'),('AR','AVD','Acevedo','Acevedo','B'),('AR','AZU','Azul','Azul','B'),('AR','BCA','Balcarce','Balcarce','B'),('AR','BGO','Bragado','Bragado','B'),('AR','BHI','Bahia Blanca','Bahia Blanca','B'),('AR','BQS','Barranqueras','Barranqueras','H'),('AR','BRC','San Carlos de Bariloche','San Carlos de Bariloche','R'),('AR','BUE','Buenos Aires','Buenos Aires','C'),('AR','CCO','Chacabuco','Chacabuco','B'),('AR','CCP','Conception','Conception','T'),('AR','CCT','Colonia Catriel','Colonia Catriel','R'),('AR','CFY','Cafayate','Cafayate','A'),('AR','CHA','Chajari','Chajari','E'),('AR','CLC','Caleta Cordoba','Caleta Cordoba','X'),('AR','CLX','Clorinda','Clorinda','F'),('AR','CMP','Campana','Campana','B'),('AR','CNQ','Corrientes','Corrientes','W'),('AR','CNT','Charata','Charata','H'),('AR','COC','Concordia','Concordia','E'),('AR','COL','Colon','Colon','E'),('AR','COR','Cordoba','Cordoba','X'),('AR','COU','Concepcion del Uruguay','Concepcion del Uruguay','E'),('AR','CPA','Cipoletti','Cipoletti','R'),('AR','CPC','San Martin de los Andes','San Martin de los Andes','Q'),('AR','CPG','Carmen de Patagones','Carmen de Patagones','B'),('AR','CRD','Comodoro Rivadavia','Comodoro Rivadavia','U'),('AR','CRR','Ceres','Ceres','S'),('AR','CTC','Catamarca','Catamarca','K'),('AR','CUA','Cuatreros/Bahia Blanca','Cuatreros/Bahia Blanca','B'),('AR','CUT','Cutral-Co','Cutral-Co','Q'),('AR','CVH','Caviahue','Caviahue','Q'),('AR','CVI','Caleta Olivia','Caleta Olivia','Z'),('AR','CVY','Chivilcoy','Chivilcoy','B'),('AR','DME','Diamante','Diamante','R'),('AR','EHL','El Bolson','El Bolson','R'),('AR','EJO','Nueve de Julio','Nueve de Julio','B'),('AR','ELB','El Bolson','El Bolson','K'),('AR','ELO','Eldorado','Eldorado','N'),('AR','EMX','El Maiten','El Maiten','U'),('AR','EQS','Esquel','Esquel','U'),('AR','EZE','Ezeisa Apt/Buenos Aires','Ezeisa Apt/Buenos Aires','B'),('AR','FMA','Formosa','Formosa','P'),('AR','FRT','Frontera','Frontera','X'),('AR','GGS','Gobernador Gregores','Gobernador Gregores','Z'),('AR','GHU','Gualeguaychu','Gualeguaychu','E'),('AR','GNR','General Roca','General Roca','R'),('AR','GPO','General Pico','General Pico','L'),('AR','GVA','General Alvear','General Alvear','M'),('AR','HIC','Hickmann','Hickmann','A'),('AR','HOS','Chos Malal','Chos Malal','Q'),('AR','HUG','Hughes','Hughes','S'),('AR','IBY','Ibicuy','Ibicuy','E'),('AR','IGB','Ingeniero Jacobacci','Ingeniero Jacobacci','R'),('AR','IGR','Iguazu','Iguazu','N'),('AR','ING','Lago Argentino','Lago Argentino','Z'),('AR','INW','Ingeniero White/Bahia Blanca','Ingeniero White/Bahia Blanca','B'),('AR','IRJ','La Rioja','La Rioja','F'),('AR','JNI','Junin','Junin','B'),('AR','JSM','Jose de San Martin','Jose de San Martin','U'),('AR','JUJ','Jujuy','Jujuy','Y'),('AR','LCM','La Cumbre','La Cumbre','X'),('AR','LCP','Loncopue','Loncopue','Q'),('AR','LGS','Malargue','Malargue','M'),('AR','LHS','Las Heras','Las Heras','Z'),('AR','LLS','Las Lomitas','Las Lomitas','P'),('AR','LMD','Los Menucos','Los Menucos','R'),('AR','LPG','La Plata','La Plata','B'),('AR','LPS','Las Palmas','Las Palmas','B'),('AR','LQU','La Quiaca','La Quiaca','Y'),('AR','LUJ','Lujan','Lujan','B'),('AR','LUQ','San Luis','San Luis','D'),('AR','MAR','Martinez','Martinez','B'),('AR','MCS','Monte Caseros','Monte Caseros','W'),('AR','MDQ','Mar del Plata','Mar del Plata','B'),('AR','MDX','Mercedes','Mercedes','W'),('AR','MDZ','Mendoza','Mendoza','M'),('AR','MED','Medanitos','Medanitos','K'),('AR','MJR','Miramar','Miramar','B'),('AR','MQD','Maquinchao','Maquinchao','R'),('AR','MQO','Monte Quemado','Monte Quemado','G'),('AR','NEC','Necochea','Necochea','B'),('AR','NOG','Nogoya','Nogoya','E'),('AR','NQN','Neuquen','Neuquen','Q'),('AR','OBA','Obera','Obera','N'),('AR','OES','San Antonio Oeste','San Antonio Oeste','R'),('AR','OLN','Colonia Sarmiento','Colonia Sarmiento','U'),('AR','ORA','Oran','Oran','A'),('AR','OVI','Olavarria','Olavarria','B'),('AR','OYA','Goya','Goya','W'),('AR','OYO','Tres Arroyos','Tres Arroyos','B'),('AR','PBG','Puerto Belgrano/Bahia Blanca','Puerto Belgrano/Bahia Blanca','B'),('AR','PCO','Punta Colorada','Punta Colorada',''),('AR','PCY','Pilcomayo','Pilcomayo','P'),('AR','PDC','Pampa del Castillo','Pampa del Castillo','U'),('AR','PEH','Pehuajo','Pehuajo','B'),('AR','PGO','Pergamino','Pergamino','B'),('AR','PGV','Puerto Galvan/Bahia Blanca','Puerto Galvan/Bahia Blanca','B'),('AR','PLO','Punta Loyola','Punta Loyola',''),('AR','PLR','Pilar','Pilar','B'),('AR','PMQ','Perito Moreno','Perito Moreno','Z'),('AR','PMY','Puerto Madryn','Puerto Madryn','U'),('AR','PNL','Puerto Nacional/Bahia Blanca','Puerto Nacional/Bahia Blanca','B'),('AR','POC','Pocitos','Pocitos','A'),('AR','PQU','Punta Quilla','Punta Quilla',''),('AR','PRA','Parana','Parana','E'),('AR','PRQ','Presidente Roque Saenz Pena','Presidente Roque Saenz Pena','H'),('AR','PRS','Puerto Rosales/Bahia Blanca','Puerto Rosales/Bahia Blanca','B'),('AR','PSS','Posadas','Posadas','N'),('AR','PUB','Puerto Borghi','Puerto Borghi',''),('AR','PUD','Puerto Deseado','Puerto Deseado','Z'),('AR','QBR','Quebracho/San Lorenzo','Quebracho/San Lorenzo','S'),('AR','QLV','Olivos','Olivos','B'),('AR','QPQ','Pinamar','Pinamar','B'),('AR','QQN','Quequen','Quequen','B'),('AR','RAF','Rafaela','Rafaela','S'),('AR','RAM','Ramallo','Ramallo','B'),('AR','RCQ','Reconquista','Reconquista','S'),('AR','RCU','Rio Cuarto','Rio Cuarto','X'),('AR','RDS','Rincon De Los Sauces','Rincon De Los Sauces','Q'),('AR','REL','Trelew','Trelew','U'),('AR','RES','Resistencia','Resistencia','H'),('AR','RFO','Rosario de la Frontera','Rosario de la Frontera','A'),('AR','RGA','Rio Grande','Rio Grande','V'),('AR','RGL','Rio Gallegos','Rio Gallegos','Z'),('AR','RHD','Rio Hondo','Rio Hondo','G'),('AR','RLA','Recalde','Recalde','B'),('AR','ROC','Puerto Ingeniero M. Rocca','Puerto Ingeniero M. Rocca','B'),('AR','ROS','Rosario','Rosario','S'),('AR','ROY','Rio Mayo','Rio Mayo','U'),('AR','RSA','Santa Rosa','Santa Rosa','L'),('AR','RTO','Rio Tercero','Rio Tercero','X'),('AR','RWO','Rawson','Rawson','U'),('AR','RYO','Rio Turbio','Rio Turbio','Z'),('AR','RZA','Santa Cruz','Santa Cruz','Z'),('AR','SAE','San Antonio Este','San Antonio Este','R'),('AR','SAG','San Andres de Giles','San Andres de Giles','B'),('AR','SDE','Santiago del Estero','Santiago del Estero','G'),('AR','SFE','San Fernando','San Fernando','B'),('AR','SFN','Santa Fe','Santa Fe','S'),('AR','SFO','San Francisco','San Francisco','X'),('AR','SGV','Sierra Grande','Sierra Grande','R'),('AR','SJO','San Justo','San Justo','B'),('AR','SLA','Salta','Salta','A'),('AR','SLO','San Lorenzo','San Lorenzo','L'),('AR','SMC','San Miguel de Tucuman','San Miguel de Tucuman','T'),('AR','SMT','San Mateo','San Mateo','G'),('AR','SNS','San Nicolas de los Arroyos','San Nicolas de los Arroyos','B'),('AR','SPD','San Pedro','San Pedro','E'),('AR','SSA','San Salvador','San Salvador','E'),('AR','SSJ','San Salvador de Jujuy','San Salvador de Jujuy','Y'),('AR','SSN','San Sebastian','San Sebastian','V'),('AR','SST','Santa Teresita','Santa Teresita','B'),('AR','SZQ','Saenz Pena','Saenz Pena','B'),('AR','TDL','Tandil','Tandil','B'),('AR','TTG','Tartagal','Tartagal','A'),('AR','TUC','Tucuman','Tucuman','T'),('AR','UAQ','San Juan','San Juan','J'),('AR','ULA','San Julian','San Julian','Z'),('AR','USH','Ushuaia','Ushuaia','V'),('AR','UZU','Curuzu Cuatia','Curuzu Cuatia','W'),('AR','VCF','Valcheta','Valcheta','R'),('AR','VCN','Villa Constitucion','Villa Constitucion','S'),('AR','VDM','Viedma','Viedma','R'),('AR','VDR','Villa Dolores','Villa Dolores','X'),('AR','VGS','General Villegas','General Villegas','B'),('AR','VLG','Villa Gesell','Villa Gesell','B'),('AR','VME','Villa Mercedes','Villa Mercedes','D'),('AR','VRE','Villa Regina','Villa Regina','R'),('AR','XMV','Pichanal','Pichanal','A'),('AR','XMX','Ledesma','Ledesma','Y'),('AR','XOS','Mosconi','Mosconi','A'),('AR','XPD','San Pedro','San Pedro','Y'),('AR','ZAE','Zarate','Zarate','B'),('AR','ZAI','Embarcacion','Embarcacion','A'),('AS','','','',''),('AS','ACC','Yucca','Yucca',''),('AS','FTI','Fitiuta','Fitiuta',''),('AS','OFU','Ofu','Ofu',''),('AS','PPG','Pago Pago','Pago Pago',''),('AS','TAV','Tau','Tau',''),('AT','','','',''),('AT','ABG','Himberg','Himberg',''),('AT','ACH','Aich','Aich',''),('AT','ADU','Andau','Andau',''),('AT','AED','St Aegyd am Neuwalde','St Aegyd am Neuwalde',''),('AT','AFR','Afritz','Afritz',''),('AT','AHN','Antiesenhofen','Antiesenhofen',''),('AT','AHO','Althofen','Althofen',''),('AT','AIG','Aigen im Muhlkreis','Aigen im Muhlkreis',''),('AT','AKV','Alkoven','Alkoven',''),('AT','ALK','Altenmarkt im Pongau','Altenmarkt im Pongau',''),('AT','ALT','Althofen','Althofen',''),('AT','ALZ','Aurolzmunster','Aurolzmunster',''),('AT','AMK','Altenmarkt','Altenmarkt',''),('AT','AMU','Altmuenster','Altmuenster',''),('AT','ANF','Anif','Anif',''),('AT','ANS','Ansfelden','Ansfelden',''),('AT','ANT','St Anton','St Anton',''),('AT','AOT','Arnoldstein','Arnoldstein',''),('AT','ARG','Anthering','Anthering',''),('AT','ARV','Sankt Andra','Sankt Andra',''),('AT','ASC','Aschach an der Donau','Aschach an der Donau',''),('AT','ASP','Aspern','Aspern',''),('AT','ATG','Altlengbach','Altlengbach',''),('AT','ATH','Altach','Altach',''),('AT','ATN','Asten','Asten',''),('AT','ATP','Attnang-Puchheim','Attnang-Puchheim',''),('AT','ATT','Amstetten','Amstetten',''),('AT','AUE','Bad Aussee','Bad Aussee',''),('AT','AWD','Abwinden','Abwinden',''),('AT','AWG','Adlwang','Adlwang',''),('AT','AWH','Altenworth','Altenworth',''),('AT','BAG','Brunn am Gebirge','Brunn am Gebirge',''),('AT','BBG','Bleiburg','Bleiburg',''),('AT','BBH','Barnbach','Barnbach',''),('AT','BBN','Breitenbrunn','Breitenbrunn',''),('AT','BDH','Haring','Haring',''),('AT','BDN','Baden','Baden',''),('AT','BES','Bergheim/Salzburg','Bergheim/Salzburg',''),('AT','BFI','Bad Fischau','Bad Fischau',''),('AT','BFL','Bad Leonfelden','Bad Leonfelden',''),('AT','BFS','Bischofshofen','Bischofshofen',''),('AT','BGC','Bad Gleichenberg','Bad Gleichenberg',''),('AT','BGT','Baumgartenberg','Baumgartenberg',''),('AT','BHL','Bad Hall','Bad Hall',''),('AT','BIE','Biedermannsdorf','Biedermannsdorf',''),('AT','BIS','Bisamberg/Wien','Bisamberg/Wien',''),('AT','BKL','Bruck an der Leitha','Bruck an der Leitha',''),('AT','BKZ','Bad Kreuzen','Bad Kreuzen',''),('AT','BLU','Bludenz','Bludenz',''),('AT','BMF','Bad Mitterndorf','Bad Mitterndorf',''),('AT','BNF','Berndorf','Berndorf',''),('AT','BOE','Bohlerwenk','Bohlerwenk',''),('AT','BRA','Braunau am Inn','Braunau am Inn',''),('AT','BRB','Barenbach','Barenbach',''),('AT','BRD','Brand','Brand',''),('AT','BRG','Bruck an der Glocknerstrasse','Bruck an der Glocknerstrasse',''),('AT','BRL','Bruckl','Bruckl',''),('AT','BRN','Brunn','Brunn',''),('AT','BRU','Bruck an der Mur','Bruck an der Mur',''),('AT','BRZ','Bregenz','Bregenz',''),('AT','BSL','Bad Sankt Leonhard im Lavanttal','Bad Sankt Leonhard im Lavanttal',''),('AT','BTU','Breitenau','Breitenau',''),('AT','BVL','Bad Voslau','Bad Voslau',''),('AT','BXG','Brixlegg','Brixlegg',''),('AT','DER','Gedersdorf','Gedersdorf',''),('AT','DEU','Deutschlandsberg','Deutschlandsberg',''),('AT','DOR','Dornbirn','Dornbirn',''),('AT','DRF','Dorf','Dorf',''),('AT','DSZ','Deutsch Schutzen','Deutsch Schutzen',''),('AT','DUE','Durnstein','Durnstein',''),('AT','DWA','Deutsch Wagram','Deutsch Wagram',''),('AT','EBE','Ebergassing','Ebergassing',''),('AT','EBN','Eben','Eben',''),('AT','EBR','Ebreichsdorf','Ebreichsdorf',''),('AT','EEZ','Eisenerz','Eisenerz',''),('AT','EFR','Eferding','Eferding',''),('AT','EGT','Eggendorf im Traunkreis','Eggendorf im Traunkreis',''),('AT','EHR','Ehrenhausen','Ehrenhausen',''),('AT','EIT','Eisenstadt','Eisenstadt',''),('AT','ENA','Enns','Enns',''),('AT','ENO','Ennsdorf','Ennsdorf',''),('AT','EPD','Erpersdorf','Erpersdorf',''),('AT','ERL','Erl','Erl',''),('AT','ERP','Erpfendorf','Erpfendorf',''),('AT','ESN','Eppenstein','Eppenstein',''),('AT','ETL','Ebenthal','Ebenthal',''),('AT','EUG','Eugendorf','Eugendorf',''),('AT','EUH','Eurenhausen','Eurenhausen',''),('AT','FBG','Frankenburg','Frankenburg',''),('AT','FDU','Feistritz an der Drau','Feistritz an der Drau',''),('AT','FED','Feldbach','Feldbach',''),('AT','FEO','Ferndorf','Ferndorf',''),('AT','FGN','Fugen','Fugen',''),('AT','FHR','Fehring','Fehring',''),('AT','FIS','Fischamend Dorf','Fischamend Dorf',''),('AT','FIT','Feistritz im Rosental','Feistritz im Rosental',''),('AT','FKI','Feldkirchen im Karnten','Feldkirchen im Karnten',''),('AT','FKN','Frauenkirchen','Frauenkirchen',''),('AT','FKT','Feldkirch','Feldkirch',''),('AT','FLH','Ferlach','Ferlach',''),('AT','FLT','Frohnleiten','Frohnleiten',''),('AT','FNZ','Fernitz','Fernitz',''),('AT','FOH','Fohnsdorf','Fohnsdorf',''),('AT','FPS','Fulpmes','Fulpmes',''),('AT','FRE','Fresing','Fresing',''),('AT','FRI','Fritzens','Fritzens',''),('AT','FRN','Frankenmarkt','Frankenmarkt',''),('AT','FRT','Frastanz','Frastanz',''),('AT','FSA','Fussach','Fussach',''),('AT','FSD','Freistadt','Freistadt',''),('AT','FST','Feistritz','Feistritz',''),('AT','FSU','Faistenau','Faistenau',''),('AT','FTH','Furth bei Gottweig','Furth bei Gottweig',''),('AT','FUF','Furstenfeld','Furstenfeld',''),('AT','FUR','Furnitz','Furnitz',''),('AT','GAL','Galtur','Galtur',''),('AT','GAN','Garsten','Garsten',''),('AT','GBF','Grossebersdorf','Grossebersdorf',''),('AT','GDF','Gerasdorf','Gerasdorf',''),('AT','GDN','Gmunden','Gmunden',''),('AT','GER','Gerersdorf bei Gussing','Gerersdorf bei Gussing',''),('AT','GFS','Greifenstein','Greifenstein',''),('AT','GHF','Grosshoflein','Grosshoflein',''),('AT','GIE','Grieskirchen','Grieskirchen',''),('AT','GKN','Gratkorn','Gratkorn',''),('AT','GLA','Glanegg','Glanegg',''),('AT','GLZ','Glanz','Glanz',''),('AT','GMU','Gmund','Gmund',''),('AT','GNF','Ganserndorf','Ganserndorf',''),('AT','GNR','Geinberg','Geinberg',''),('AT','GNZ','Granz','Granz',''),('AT','GOE','Gotzis','Gotzis',''),('AT','GPF','Grosspetersdorf','Grosspetersdorf',''),('AT','GPK','Gumpoldskirchen','Gumpoldskirchen',''),('AT','GRA','Grafenstein','Grafenstein',''),('AT','GRG','Grodig','Grodig',''),('AT','GRI','Griffen','Griffen',''),('AT','GRL','Gramatneusiedl','Gramatneusiedl',''),('AT','GRN','Grein','Grein',''),('AT','GRO','Grossenzersdorf/Wien','Grossenzersdorf/Wien',''),('AT','GRU','Gross St Florian','Gross St Florian',''),('AT','GRZ','Graz','Graz',''),('AT','GSD','Gleisdorf','Gleisdorf',''),('AT','GSF','Gaspoltshofen','Gaspoltshofen',''),('AT','GSN','Gutenstein','Gutenstein',''),('AT','GSS','Gussing','Gussing',''),('AT','GTN','Gresten','Gresten',''),('AT','GUK','Gunskirchen','Gunskirchen',''),('AT','GUN','Guntramsdorf','Guntramsdorf',''),('AT','GZR','Gross Gerungs','Gross Gerungs',''),('AT','HAB','Haibach','Haibach',''),('AT','HAD','Haid','Haid',''),('AT','HAG','Haag','Haag',''),('AT','HAL','Hall','Hall',''),('AT','HAU','Hohenau an der March','Hohenau an der March',''),('AT','HEC','Heidenreichstein','Heidenreichstein',''),('AT','HEL','Helfenberg','Helfenberg',''),('AT','HEO','Henndorf am Wallersee','Henndorf am Wallersee',''),('AT','HER','Herzogenburg','Herzogenburg',''),('AT','HFS','Heinfels','Heinfels',''),('AT','HGB','Hagenbrunn','Hagenbrunn',''),('AT','HHN','Haidershofen','Haidershofen',''),('AT','HIA','Hainburg','Hainburg',''),('AT','HIR','Hirschegg','Hirschegg',''),('AT','HIT','Hall in Tirol','Hall in Tirol',''),('AT','HLB','Hollersbach','Hollersbach',''),('AT','HLL','Hallein','Hallein',''),('AT','HME','Hausmenning','Hausmenning',''),('AT','HMG','Hermagor','Hermagor',''),('AT','HOH','Hohenems','Hohenems',''),('AT','HOL','Hollabrunn','Hollabrunn',''),('AT','HON','Hohenruppersdorf','Hohenruppersdorf',''),('AT','HOR','Horn','Horn',''),('AT','HOT','Horitschon','Horitschon',''),('AT','HRD','Hard','Hard',''),('AT','HRH','Horsching','Horsching',''),('AT','HSN','Hansenhutte','Hansenhutte',''),('AT','HST','Hochst','Hochst',''),('AT','HTA','Hartberg','Hartberg',''),('AT','HTE','Hirtenberg','Hirtenberg',''),('AT','ICH','Bad Ischl','Bad Ischl',''),('AT','ILL','Illmitz','Illmitz',''),('AT','ILZ','Ilz','Ilz',''),('AT','INN','Innsbruck','Innsbruck',''),('AT','ITT','Itterdorfl','Itterdorfl',''),('AT','JDB','Judenberg','Judenberg',''),('AT','JDF','Jennersdorf','Jennersdorf',''),('AT','JDN','Judenburg','Judenburg',''),('AT','JEN','Jenbach','Jenbach',''),('AT','JGE','Jagerberg','Jagerberg',''),('AT','JOA','St Johann im Pongau','St Johann im Pongau',''),('AT','JOC','Joching','Joching',''),('AT','JOH','St Johann in Tirol','St Johann in Tirol',''),('AT','JOS','Jois','Jois',''),('AT','JUN','Jungholz','Jungholz',''),('AT','KAB','Kaltenbach','Kaltenbach',''),('AT','KAR','Karlsdorf','Karlsdorf',''),('AT','KBG','Korneuburg','Korneuburg',''),('AT','KBW','Kirchberg am Wagram','Kirchberg am Wagram',''),('AT','KDF','Kalsdorf','Kalsdorf',''),('AT','KDM','Kraubath an der Mur','Kraubath an der Mur',''),('AT','KEF','Koflach','Koflach',''),('AT','KEU','Kotschach-Mauthen','Kotschach-Mauthen',''),('AT','KFB','Kapfenberg','Kapfenberg',''),('AT','KFD','Knittelfeld','Knittelfeld',''),('AT','KFH','Koflach','Koflach',''),('AT','KFS','Kufstein','Kufstein',''),('AT','KGI','Kopfing im Innkreis','Kopfing im Innkreis',''),('AT','KHS','Kleinharras','Kleinharras',''),('AT','KIE','Kienberg','Kienberg',''),('AT','KIN','Kindberg','Kindberg',''),('AT','KLA','Klaus','Klaus',''),('AT','KLD','Krollendorf','Krollendorf',''),('AT','KLU','Klagenfurt','Klagenfurt',''),('AT','KMB','Krummnussbaum','Krummnussbaum',''),('AT','KMG','Kemating','Kemating',''),('AT','KMS','Kremsmunster','Kremsmunster',''),('AT','KNB','Kennelbach','Kennelbach',''),('AT','KNR','Kottingbrunn','Kottingbrunn',''),('AT','KPL','Kappl','Kappl',''),('AT','KRE','Krems','Krems',''),('AT','KRL','Kirchbichl','Kirchbichl',''),('AT','KRO','Krobotek','Krobotek',''),('AT','KRS','Kramsach','Kramsach',''),('AT','KSE','Kittsee','Kittsee',''),('AT','KTT','Kematen in Tirol','Kematen in Tirol',''),('AT','KTU','Klosterneuburg','Klosterneuburg',''),('AT','KUC','Kuchl','Kuchl',''),('AT','KUD','Kuhnsdorf','Kuhnsdorf',''),('AT','KUN','Kundl','Kundl',''),('AT','KYB','Kematen Ybbs','Kematen Ybbs',''),('AT','LAA','Laa an der Thaya','Laa an der Thaya',''),('AT','LAG','Langenlois','Langenlois',''),('AT','LAM','Oberlamm','Oberlamm',''),('AT','LAN','Landeck','Landeck',''),('AT','LBD','Leobersdorf','Leobersdorf',''),('AT','LBN','Leoben','Leoben',''),('AT','LCU','Lochau','Lochau',''),('AT','LDG','Leonding','Leonding',''),('AT','LEB','Lebring','Lebring',''),('AT','LEI','Leibnitz','Leibnitz',''),('AT','LEN','Lend','Lend',''),('AT','LEO','Leobendorf','Leobendorf',''),('AT','LEZ','Lienz','Lienz',''),('AT','LFD','Langenfeld','Langenfeld',''),('AT','LGU','Lengau','Lengau',''),('AT','LIB','Lieboch','Lieboch',''),('AT','LKI','Laakirchen','Laakirchen',''),('AT','LLF','Lilienfeld','Lilienfeld',''),('AT','LMB','Lambach','Lambach',''),('AT','LMU','Sankt Lorenzen im Murztal','Sankt Lorenzen im Murztal',''),('AT','LNH','Lannach','Lannach',''),('AT','LNZ','Linz','Linz',''),('AT','LOB','Lohnsburg','Lohnsburg',''),('AT','LOE','Lobendorf','Lobendorf',''),('AT','LOI','Loimersdorf','Loimersdorf',''),('AT','LSD','Loosdorf','Loosdorf',''),('AT','LSN','Langenstein','Langenstein',''),('AT','LTG','Lichtenberg','Lichtenberg',''),('AT','LTH','Leutasch','Leutasch',''),('AT','LTN','Lustenau','Lustenau',''),('AT','LUT','Lauterach','Lauterach',''),('AT','LXE','Laxenburg','Laxenburg',''),('AT','LZD','Langenzersdorf','Langenzersdorf',''),('AT','LZG','Lenzing','Lenzing',''),('AT','LZN','Liezen','Liezen',''),('AT','MAR','Marktl','Marktl',''),('AT','MAT','Mattersburg','Mattersburg',''),('AT','MAU','Mauthausen','Mauthausen',''),('AT','MBR','Matrei am Brenner','Matrei am Brenner',''),('AT','MCD','Micheldorf in Oberosterreich','Micheldorf in Oberosterreich',''),('AT','MDF','Mollersdorf, Tull an der Donau','Mollersdorf, Tull an der Donau',''),('AT','MDO','Mariasdorf','Mariasdorf',''),('AT','MDR','Mader','Mader',''),('AT','MEL','Melk','Melk',''),('AT','MER','Merchtrenk','Merchtrenk',''),('AT','MGN','Meggenhofen','Meggenhofen',''),('AT','MHE','Munichreith','Munichreith',''),('AT','MHF','Monchhof','Monchhof',''),('AT','MHK','Mauerkirchen','Mauerkirchen',''),('AT','MIF','Micheldorf in Karnten','Micheldorf in Karnten',''),('AT','MIK','Miklauzhof','Miklauzhof',''),('AT','MIS','Mistelbach','Mistelbach',''),('AT','MIT','Mittelberg','Mittelberg',''),('AT','MIX','Mixnitz','Mixnitz',''),('AT','MKC','Mitterkirchen','Mitterkirchen',''),('AT','MLS','Mittersill','Mittersill',''),('AT','MNO','Mullendorf','Mullendorf',''),('AT','MOE','Modling','Modling',''),('AT','MON','Mondsee','Mondsee',''),('AT','MRC','Marchtrenk','Marchtrenk',''),('AT','MRZ','Marz','Marz',''),('AT','MSB','Mettersdorf Am Sassbach','Mettersdorf Am Sassbach',''),('AT','MSD','Messendorf','Messendorf',''),('AT','MTF','Mauterndorf','Mauterndorf',''),('AT','MTH','Mattighofen','Mattighofen',''),('AT','MTI','Sankt Martin im Innkreis','Sankt Martin im Innkreis',''),('AT','MUE','Munchendorf','Munchendorf',''),('AT','MZZ','Murzzuschlag','Murzzuschlag',''),('AT','NBA','Nussbach','Nussbach',''),('AT','NEC','Neckenmarkt','Neckenmarkt',''),('AT','NEH','Neulengbach','Neulengbach',''),('AT','NEK','Neuhofen an der Krems','Neuhofen an der Krems',''),('AT','NEL','Neudorfl','Neudorfl',''),('AT','NES','Neusiedl','Neusiedl',''),('AT','NEU','Neubau','Neubau',''),('AT','NEZ','Nenzing','Nenzing',''),('AT','NFN','Neufelden','Neufelden',''),('AT','NHR','Neumarkt im Hausruckkreis','Neumarkt im Hausruckkreis',''),('AT','NKD','Niklasdorf','Niklasdorf',''),('AT','NKN','Neunkirchen','Neunkirchen',''),('AT','NSD','Nussdorf','Nussdorf',''),('AT','NSL','Niedernsill','Niedernsill',''),('AT','NTA','Neutal','Neutal',''),('AT','NUA','Neudau','Neudau',''),('AT','NUF','Neufeld an der Leitha','Neufeld an der Leitha',''),('AT','NUZ','Nuziders','Nuziders',''),('AT','NWK','Niederwaldkirchen','Niederwaldkirchen',''),('AT','OAL','Oneal','Oneal',''),('AT','OBE','Oberpullendorf','Oberpullendorf',''),('AT','OBG','Obergrafendorf','Obergrafendorf',''),('AT','OBH','Oberstrahlbach','Oberstrahlbach',''),('AT','OBR','Oberndorf bei Salzburg','Oberndorf bei Salzburg',''),('AT','OBW','Oberweis','Oberweis',''),('AT','OCW','Winkel','Winkel',''),('AT','OED','Oed','Oed',''),('AT','OHD','Obdach','Obdach',''),('AT','OLL','Molln','Molln',''),('AT','OLS','Ohlsdorf','Ohlsdorf',''),('AT','ORI','Oftering','Oftering',''),('AT','OSH','Ottensheim','Ottensheim',''),('AT','OSZ','Oberschutzen','Oberschutzen',''),('AT','OWD','Oberwaltersdorf','Oberwaltersdorf',''),('AT','OWT','Oberwart','Oberwart',''),('AT','PAM','Pamhagen','Pamhagen',''),('AT','PBU','Persenbeug','Persenbeug',''),('AT','PDF','Parndorf','Parndorf',''),('AT','PEB','Pettenbach','Pettenbach',''),('AT','PER','Perg','Perg',''),('AT','PFD','Pinkafeld','Pinkafeld',''),('AT','PGG','Pinggau','Pinggau',''),('AT','PGN','Pregarten','Pregarten',''),('AT','PGO','Poggersdorf','Poggersdorf',''),('AT','PHG','Pasching','Pasching',''),('AT','PKG','Pucking','Pucking',''),('AT','PLL','Pill','Pill',''),('AT','PNT','Pernitz','Pernitz',''),('AT','POE','Pochlarn','Pochlarn',''),('AT','POF','Pinsdorf','Pinsdorf',''),('AT','POG','Poggstall','Poggstall',''),('AT','POY','Poysdorf','Poysdorf',''),('AT','PRA','Pramet','Pramet',''),('AT','PRH','Pernhofen','Pernhofen',''),('AT','PRM','Pram','Pram',''),('AT','PTF','Perchtoldsdorf','Perchtoldsdorf',''),('AT','PUF','Purkersdorf','Purkersdorf',''),('AT','PUR','Purgstall','Purgstall',''),('AT','PWE','Pichl bei Wels','Pichl bei Wels',''),('AT','QXZ','Worgl','Worgl',''),('AT','RAA','Raasdorf','Raasdorf',''),('AT','RAB','Raab','Raab',''),('AT','RAD','Radstadt','Radstadt',''),('AT','RAS','Rastenfeld','Rastenfeld',''),('AT','RBA','Raaba','Raaba',''),('AT','RBG','Riegersburg','Riegersburg',''),('AT','RDF','Rohrendorf bei Krems','Rohrendorf bei Krems',''),('AT','RDN','Radenthein','Radenthein',''),('AT','RDW','Ratsch an der Weinstrasse','Ratsch an der Weinstrasse',''),('AT','RFD','Radfeld','Radfeld',''),('AT','RHN','Ranshofen','Ranshofen',''),('AT','RIE','Ried','Ried',''),('AT','RIK','Ried im Innkreis','Ried im Innkreis',''),('AT','RKL','Rankweil','Rankweil',''),('AT','RNA','Rosenau','Rosenau',''),('AT','ROI','Roitham','Roitham',''),('AT','RRA','Sankt Ruprecht an der Raab','Sankt Ruprecht an der Raab',''),('AT','RSD','Reichersdorf','Reichersdorf',''),('AT','RSU','Rosenburg','Rosenburg',''),('AT','RTE','Reutte','Reutte',''),('AT','RTM','Rotenturm an der Pinka','Rotenturm an der Pinka',''),('AT','RTT','Rottenmann','Rottenmann',''),('AT','RTZ','Retz','Retz',''),('AT','RUM','Rum','Rum',''),('AT','RUS','Rust','Rust',''),('AT','RWL','Rekawinkel','Rekawinkel',''),('AT','RXG','Randegg','Randegg',''),('AT','RZL','Riezlern','Riezlern',''),('AT','SAR','Stift Ardagger','Stift Ardagger',''),('AT','SBB','Scheibbs','Scheibbs',''),('AT','SCH','Schwertberg','Schwertberg',''),('AT','SCW','Schwarzach','Schwarzach',''),('AT','SCZ','Schwaz','Schwaz',''),('AT','SDG','Scharding','Scharding',''),('AT','SEE','Seefeld in Tirol','Seefeld in Tirol',''),('AT','SEF','Seefeld-Kadolz','Seefeld-Kadolz',''),('AT','SEI','Seibersdorf','Seibersdorf',''),('AT','SEN','Steinabrunn','Steinabrunn',''),('AT','SER','Steyr','Steyr',''),('AT','SET','Seitenstetten Markt','Seitenstetten Markt',''),('AT','SFS','St Stefan im Lavanttal','St Stefan im Lavanttal',''),('AT','SGF','Sankt Georgen am Steinfelden','Sankt Georgen am Steinfelden',''),('AT','SGN','Schneegattern','Schneegattern',''),('AT','SGS','Sankt Georgen bei Salzburg','Sankt Georgen bei Salzburg',''),('AT','SHT','Schwechat','Schwechat',''),('AT','SIF','Siegendorf','Siegendorf',''),('AT','SIG','Schwarzau im Gebirge','Schwarzau im Gebirge',''),('AT','SIN','Sillian','Sillian',''),('AT','SIR','Seekirchen','Seekirchen',''),('AT','SJB','St Jakob Breitenau','St Jakob Breitenau',''),('AT','SKN','Sinabelkirchen','Sinabelkirchen',''),('AT','SLL','Sollenau','Sollenau',''),('AT','SLV','St Paul im Levanttal','St Paul im Levanttal',''),('AT','SMA','Sankt Marien','Sankt Marien',''),('AT','SMI','St Michael in Obersteiermark','St Michael in Obersteiermark',''),('AT','SML','St Michael ob Bleiburg','St Michael ob Bleiburg',''),('AT','SMN','St Martin bei Linz','St Martin bei Linz',''),('AT','SNG','Soding','Soding',''),('AT','SOL','Soll','Soll',''),('AT','SOS','Sooss','Sooss',''),('AT','SPI','Spittal an der Drau','Spittal an der Drau',''),('AT','SPZ','Spitz','Spitz',''),('AT','SRM','Schrems','Schrems',''),('AT','SSB','Seiersberg','Seiersberg',''),('AT','SST','Schwanenstadt','Schwanenstadt',''),('AT','STA','Stainach','Stainach',''),('AT','STB','Stegersbach','Stegersbach',''),('AT','STC','Stockerau','Stockerau',''),('AT','STD','Steeg','Steeg',''),('AT','STE','Steinfeld','Steinfeld',''),('AT','STG','Sankt Gertraud','Sankt Gertraud',''),('AT','STM','Stams','Stams',''),('AT','STP','Sankt Polten','Sankt Polten',''),('AT','STS','St Stefan','St Stefan',''),('AT','STV','St Valentin','St Valentin',''),('AT','STZ','Stainz','Stainz',''),('AT','SUB','Suben','Suben',''),('AT','SUN','Sattledt','Sattledt',''),('AT','SUP','Steinbrunn','Steinbrunn',''),('AT','SVG','St Veit an der Glan','St Veit an der Glan',''),('AT','SVO','St Veit an der Golsen','St Veit an der Golsen',''),('AT','SVT','St Paul','St Paul',''),('AT','SYM','Steyrermuhl','Steyrermuhl',''),('AT','SZG','Salzburg','Salzburg',''),('AT','TBE','Trieben','Trieben',''),('AT','TBH','Treibach','Treibach',''),('AT','TDW','Trausdorf an der Wulka','Trausdorf an der Wulka',''),('AT','TEC','Tenneck','Tenneck',''),('AT','TEF','Teesdorf','Teesdorf',''),('AT','TEL','Telfs','Telfs',''),('AT','TEU','Teufenbach','Teufenbach',''),('AT','TEX','Texing','Texing',''),('AT','TFN','Treffen','Treffen',''),('AT','TGU','Thalgau','Thalgau',''),('AT','THF','Theresienfeld','Theresienfeld',''),('AT','THR','Thaur','Thaur',''),('AT','THS','Theiss','Theiss',''),('AT','TKP','Taufkirchen an der Pram','Taufkirchen an der Pram',''),('AT','TLN','Tulln','Tulln',''),('AT','TMR','Traismauer','Traismauer',''),('AT','TNQ','Traun','Traun',''),('AT','TNZ','Ternitz','Ternitz',''),('AT','TOL','Thorl','Thorl',''),('AT','TRW','Tribuswinkel','Tribuswinkel',''),('AT','TSK','Traiskirchen','Traiskirchen',''),('AT','TUE','Turnitz','Turnitz',''),('AT','UBG','Unternberg','Unternberg',''),('AT','UER','Auersthal','Auersthal',''),('AT','UHR','Uher/Wien','Uher/Wien',''),('AT','ULB','Unterloiben','Unterloiben',''),('AT','ULF','Ulmerfeld','Ulmerfeld',''),('AT','UNA','Unterach','Unterach',''),('AT','UNZ','Unzmarkt','Unzmarkt',''),('AT','UPS','Unterpremstatten','Unterpremstatten',''),('AT','URB','Unterradlberg','Unterradlberg',''),('AT','UTD','Uttendorf','Uttendorf',''),('AT','VDD','Vienna Danubepier Hov','Vienna Danubepier Hov',''),('AT','VIE','Wien','Wien',''),('AT','VLH','Villach','Villach',''),('AT','VMP','Vomp','Vomp',''),('AT','VOC','Vocklabruck','Vocklabruck',''),('AT','VOE','Vols','Vols',''),('AT','VOF','Vosendorf','Vosendorf',''),('AT','VOK','Vocklamarkt','Vocklamarkt',''),('AT','VOR','Vorarlberg','Vorarlberg',''),('AT','VOT','Volkermarkt','Volkermarkt',''),('AT','VTB','Voitsberg','Voitsberg',''),('AT','WAF','Waidhofen an der Ybbs','Waidhofen an der Ybbs',''),('AT','WAI','Waidhofen an der Thaya','Waidhofen an der Thaya',''),('AT','WAL','Wals','Wals',''),('AT','WAR','Warth','Warth',''),('AT','WBG','Wieselburg','Wieselburg',''),('AT','WBH','Weilbach','Weilbach',''),('AT','WBU','Wilhelmsburg','Wilhelmsburg',''),('AT','WCE','Walchsee','Walchsee',''),('AT','WDO','Wildon','Wildon',''),('AT','WEE','Weissenbach an der Triesting','Weissenbach an der Triesting',''),('AT','WEI','Weissenbach','Weissenbach',''),('AT','WER','Werndorf','Werndorf',''),('AT','WEZ','Weiz','Weiz',''),('AT','WFT','Wolfurt','Wolfurt',''),('AT','WIH','Wildshut','Wildshut',''),('AT','WLR','Wolfurt','Wolfurt',''),('AT','WLZ','Wulzeshofen','Wulzeshofen',''),('AT','WMP','Wimpassing','Wimpassing',''),('AT','WNF','Wiener Neudorf','Wiener Neudorf',''),('AT','WNK','Weissenkirchen im Attergau','Weissenkirchen im Attergau',''),('AT','WNR','Wiener Neustadt','Wiener Neustadt',''),('AT','WOF','Wolfsberg (Karnten)','Wolfsberg (Karnten)',''),('AT','WOL','Wolfpassing','Wolfpassing',''),('AT','WOS','Wosendorf','Wosendorf',''),('AT','WRT','Wartberg','Wartberg',''),('AT','WSD','Wollersdorf','Wollersdorf',''),('AT','WSE','Wallsee','Wallsee',''),('AT','WSK','Weisskirchen an der Traun','Weisskirchen an der Traun',''),('AT','WSL','Wels','Wels',''),('AT','WSS','Weissenstein','Weissenstein',''),('AT','WTG','Weitenegg','Weitenegg',''),('AT','WTN','Wattens','Wattens',''),('AT','YBB','Ybbs an der Donau','Ybbs an der Donau',''),('AT','ZAM','Zams','Zams',''),('AT','ZAS','Zell am See','Zell am See',''),('AT','ZEN','Maria Lanzendorf','Maria Lanzendorf',''),('AT','ZEZ','Zell am Ziller','Zell am Ziller',''),('AT','ZIE','Ziersdorf','Ziersdorf',''),('AT','ZIP','Zipf','Zipf',''),('AT','ZIR','Zirl','Zirl',''),('AT','ZIS','Zistersdorf','Zistersdorf',''),('AT','ZNH','Siezenheim','Siezenheim',''),('AT','ZRS','Zurs','Zurs',''),('AT','ZTG','Zettling','Zettling',''),('AT','ZTW','Zeltweg','Zeltweg',''),('AT','ZWD','Zwentendorf','Zwentendorf',''),('AT','ZWT','Zwettl','Zwettl',''),('AU','','','',''),('AU','AAB','Arrabury','Arrabury','QL'),('AU','ABG','Abingdon','Abingdon','QL'),('AU','ABH','Alpha','Alpha','QL'),('AU','ABL','Amberley','Amberley','QL'),('AU','ABM','Bamaga','Bamaga','QL'),('AU','ABP','Abbot Point','Abbot Point','QL'),('AU','ABX','Albury','Albury','NS'),('AU','ACA','Acacia Ridge','Acacia Ridge','QL'),('AU','ACO','Ascot','Ascot','WA'),('AU','ADA','Adelaide Apt','Adelaide Apt','SA'),('AU','ADL','Adelaide','Adelaide','SA'),('AU','ADO','Andamooka','Andamooka','SA'),('AU','AGS','Augusta','Augusta','WA'),('AU','AGW','Agnew','Agnew','QL'),('AU','AGY','Argyle Downs','Argyle Downs','WA'),('AU','AIR','Airlie Terminal','Airlie Terminal','WA'),('AU','ALH','Albany','Albany','WA'),('AU','ALI','Australind','Australind','WA'),('AU','ALO','Adelong','Adelong','NS'),('AU','ALT','Altona','Altona',''),('AU','ALX','Alexandria','Alexandria','NS'),('AU','AMT','Amata','Amata','NT'),('AU','AMX','Ammaroo','Ammaroo','NT'),('AU','AND','Andrews','Andrews','QL'),('AU','ANZ','Angus Downs','Angus Downs','NT'),('AU','APK','Albion Park','Albion Park','NS'),('AU','ARC','Arncliffe','Arncliffe','NS'),('AU','ARD','Ardrossan','Ardrossan','SA'),('AU','ARL','Arundel','Arundel','QL'),('AU','ARM','Armidale','Armidale','NS'),('AU','ARY','Ararat','Ararat','VI'),('AU','ASC','Ashgrove/Brisbane','Ashgrove/Brisbane','QL'),('AU','ASP','Alice Springs','Alice Springs','NT'),('AU','ATA','Ardlethan','Ardlethan','NS'),('AU','ATO','Altona North','Altona North','VI'),('AU','AUD','Augustus Downs','Augustus Downs','QL'),('AU','AUU','Aurukun Mission','Aurukun Mission','QL'),('AU','AVG','Auvergne','Auvergne','NT'),('AU','AVI','Alstonville','Alstonville','NS'),('AU','AVV','Avalon','Avalon','VI'),('AU','AWN','Alton Downs','Alton Downs','SA'),('AU','AWP','Austral Downs','Austral Downs','NT'),('AU','AXC','Aramac','Aramac','QL'),('AU','AXL','Alexandria','Alexandria','NT'),('AU','AYD','Alroy Downs','Alroy Downs','NT'),('AU','AYL','Anthony Lagoon','Anthony Lagoon','NT'),('AU','AYQ','Ayers Rock','Ayers Rock','NT'),('AU','AYR','Ayr','Ayr','QL'),('AU','BAH','Ballast Head','Ballast Head','SA'),('AU','BAK','Bakers Creek','Bakers Creek','QL'),('AU','BBE','Big Bell','Big Bell','WA'),('AU','BBG','Bing Bong','Bing Bong','NT'),('AU','BBR','Binna Burra','Binna Burra','NS'),('AU','BBU','Bibbenluke','Bibbenluke','NS'),('AU','BCB','Bencubbin','Bencubbin','WA'),('AU','BCH','Beachport','Beachport','SA'),('AU','BCI','Barcaldine','Barcaldine','QL'),('AU','BCK','Bolwarra','Bolwarra','QL'),('AU','BCO','Blacktown','Blacktown','NS'),('AU','BCZ','Bickerton Island','Bickerton Island','NT'),('AU','BDA','Bulahdelah','Bulahdelah','NS'),('AU','BDB','Bundaberg','Bundaberg','QL'),('AU','BDD','Badu Island','Badu Island','QL'),('AU','BDE','Brendale','Brendale','QL'),('AU','BDG','Bendigo','Bendigo','VI'),('AU','BDM','Bundamba','Bundamba','QL'),('AU','BDS','Beaudesert','Beaudesert','QL'),('AU','BDW','Bedford Downs','Bedford Downs','WA'),('AU','BEE','Beagle Bay','Beagle Bay','WA'),('AU','BEL','Bell Bay','Bell Bay','TS'),('AU','BEO','Belmont','Belmont','NS'),('AU','BER','Berri','Berri','SA'),('AU','BEU','Bedourie','Bedourie','QL'),('AU','BEV','Bonnie Vale','Bonnie Vale','WA'),('AU','BFC','Bloomfield','Bloomfield','QL'),('AU','BGA','Bungwahl','Bungwahl','NS'),('AU','BGB','Burringbar','Burringbar','NS'),('AU','BGT','Bridgetown','Bridgetown','WA'),('AU','BGW','Bangalow','Bangalow','NS'),('AU','BGY','Blighty','Blighty','NS'),('AU','BHQ','Broken Hill','Broken Hill','NS'),('AU','BHS','Bathurst','Bathurst','NS'),('AU','BHT','Brighton Downs','Brighton Downs','QL'),('AU','BIP','Bulimba','Bulimba','QL'),('AU','BIW','Billiluna','Billiluna','WA'),('AU','BJU','Burren Junction','Burren Junction','NS'),('AU','BKH','Baulkham Hills','Baulkham Hills','NS'),('AU','BKL','Brooklyn','Brooklyn','VI'),('AU','BKO','Beckom','Beckom','NS'),('AU','BKP','Barkly Downs','Barkly Downs','QL'),('AU','BKQ','Blackall','Blackall','QL'),('AU','BKT','Brookton','Brookton','WA'),('AU','BLA','Bibra Lake','Bibra Lake','WA'),('AU','BLG','Beenleigh','Beenleigh','QL'),('AU','BLH','Burleigh Heads','Burleigh Heads','QL'),('AU','BLN','Benalla','Benalla','VI'),('AU','BLO','Biloela','Biloela','QL'),('AU','BLS','Bollon','Bollon','QL'),('AU','BLT','Blackwater','Blackwater','QL'),('AU','BLW','Bungalow','Bungalow','QL'),('AU','BMA','Bombala','Bombala','NS'),('AU','BMD','Broadmeadows','Broadmeadows','NS'),('AU','BME','Broome','Broome','WA'),('AU','BMK','Bemboka','Bemboka','NS'),('AU','BMP','Brampton','Brampton','QL'),('AU','BMU','Bendick Murrell','Bendick Murrell','NS'),('AU','BMW','Broadmeadows','Broadmeadows','VI'),('AU','BND','Bundall','Bundall','QL'),('AU','BNE','Brisbane','Brisbane','QL'),('AU','BNG','Binalong','Binalong','NS'),('AU','BNK','Ballina','Ballina','NS'),('AU','BNY','Blayney','Blayney','NS'),('AU','BOO','Booby Island','Booby Island','QL'),('AU','BOX','Borroloola','Borroloola','NT'),('AU','BQA','Ballarat','Ballarat','VI'),('AU','BQL','Boulia','Boulia','QL'),('AU','BQW','Balgo Hills','Balgo Hills','WA'),('AU','BRA','Brisbane Apt','Brisbane Apt','QL'),('AU','BRD','Berridale','Berridale','NS'),('AU','BRG','Berrigan','Berrigan','NS'),('AU','BRI','Brigalow','Brigalow','NS'),('AU','BRJ','Bright','Bright','VI'),('AU','BRK','Bourke','Bourke','NS'),('AU','BRL','Barellan','Barellan','NS'),('AU','BRT','Bathurst Island','Bathurst Island','NT'),('AU','BRU','Brunswich','Brunswich','VI'),('AU','BSJ','Bairnsdale','Bairnsdale','VI'),('AU','BTB','Botany Bay','Botany Bay','NS'),('AU','BTD','Brunette Downs','Brunette Downs','NT'),('AU','BTO','Batlow','Batlow','NS'),('AU','BTT','Balcatta','Balcatta','WA'),('AU','BTX','Betoota','Betoota','QL'),('AU','BUC','Burketown','Burketown','QL'),('AU','BUL','Bulli','Bulli','NS'),('AU','BUS','Busselton','Busselton','WA'),('AU','BUV','Buffalo Venture','Buffalo Venture','NT'),('AU','BUY','Bunbury','Bunbury','WA'),('AU','BVE','Brookvale/Sidney','Brookvale/Sidney','NS'),('AU','BVI','Birdsville','Birdsville','QL'),('AU','BVL','Brookville','Brookville','VI'),('AU','BVS','Beverley','Beverley','SA'),('AU','BVW','Batavia Downs','Batavia Downs','QL'),('AU','BVZ','Beverley Springs','Beverley Springs','WA'),('AU','BWA','Bowral','Bowral','NS'),('AU','BWB','Barrow Island','Barrow Island','WA'),('AU','BWG','Bowning','Bowning','NS'),('AU','BWI','Bulwer','Bulwer','QL'),('AU','BWL','Balgowlah','Balgowlah','NS'),('AU','BWQ','Brewarrina','Brewarrina','NS'),('AU','BWT','Burnie','Burnie','TS'),('AU','BWU','Bankstown','Bankstown','NS'),('AU','BXT','Baxter','Baxter','VI'),('AU','BYA','Binya','Binya','NS'),('AU','BYB','Boyup Brook','Boyup Brook','WA'),('AU','BYP','Beauty Point','Beauty Point','TS'),('AU','BYS','Bayswater','Bayswater','VI'),('AU','BYU','Boyanup','Boyanup','WA'),('AU','BYX','Baniyala','Baniyala','NT'),('AU','BZD','Balranald','Balranald','NS'),('AU','BZP','Bizant','Bizant','QL'),('AU','CAD','Carrum Downs','Carrum Downs','VI'),('AU','CAH','Cannon Hill','Cannon Hill','QL'),('AU','CAL','Caloundra Head','Caloundra Head','QL'),('AU','CAZ','Cobar','Cobar','NS'),('AU','CBA','Corio Bay','Corio Bay','VI'),('AU','CBC','Cherrabun','Cherrabun','WA'),('AU','CBG','Coburg','Coburg','VI'),('AU','CBI','Cape Barren Island','Cape Barren Island','TS'),('AU','CBN','Campbelltown','Campbelltown','NS'),('AU','CBR','Canberra','Canberra','CT'),('AU','CBU','Cullen Bullen','Cullen Bullen','NS'),('AU','CBX','Condobolin','Condobolin','NS'),('AU','CBY','Canobie','Canobie','QL'),('AU','CCL','Chinchilla','Chinchilla','QL'),('AU','CCU','Cape Cuvier','Cape Cuvier','WA'),('AU','CCW','Cowell','Cowell','SA'),('AU','CDA','Cooinda','Cooinda','NT'),('AU','CDI','Cunderdin','Cunderdin','WA'),('AU','CDQ','Croydon','Croydon','QL'),('AU','CDU','Camden','Camden','NS'),('AU','CED','Ceduna','Ceduna','SA'),('AU','CES','Cessnock','Cessnock','NS'),('AU','CFH','Clifton Hills','Clifton Hills','SA'),('AU','CFI','Camfield','Camfield','NT'),('AU','CFL','Campbellfield','Campbellfield','VI'),('AU','CFP','Carpentaria Downs','Carpentaria Downs','QL'),('AU','CFS','Coffs Harbour','Coffs Harbour','NS'),('AU','CGA','Coolgardie','Coolgardie','WA'),('AU','CGV','Caiguna','Caiguna','WA'),('AU','CHA','Chatswood','Chatswood','NS'),('AU','CHB','Catherine Hill Bay','Catherine Hill Bay','NS'),('AU','CHD','Chadstone/Melbourne','Chadstone/Melbourne','VI'),('AU','CHL','Cheltenham/Melbourne','Cheltenham/Melbourne','VI'),('AU','CHN','Chipping Norton','Chipping Norton','NS'),('AU','CHU','Chullora','Chullora','NS'),('AU','CHV','Challis Venture (oil terminal)','Challis Venture (oil terminal)','NT'),('AU','CIA','Camellia','Camellia','NS'),('AU','CIE','Collie','Collie','WA'),('AU','CKI','Croker Island','Croker Island','NT'),('AU','CLA','Coolamon','Coolamon','NS'),('AU','CLB','Coolabah','Coolabah','NS'),('AU','CLC','Culcairn','Culcairn','NS'),('AU','CLH','Coolah','Coolah','NS'),('AU','CLL','Collan Islands','Collan Islands','WA'),('AU','CLN','Cape Leeuwin','Cape Leeuwin','WA'),('AU','CLP','Clovelly Park','Clovelly Park','SA'),('AU','CLR','Clarence River','Clarence River','NS'),('AU','CLT','Cape Lambert','Cape Lambert','WA'),('AU','CLU','Clunes','Clunes','NS'),('AU','CLY','Clayton/Melbourne','Clayton/Melbourne','VI'),('AU','CMA','Cunnamulla','Cunnamulla','QL'),('AU','CMD','Cootamundra','Cootamundra','NS'),('AU','CML','Camooweal','Camooweal','QL'),('AU','CMQ','Clermont','Clermont','QL'),('AU','CNB','Coonamble','Coonamble','NS'),('AU','CNC','Coconut Island','Coconut Island','QL'),('AU','CNJ','Cloncurry','Cloncurry','QL'),('AU','CNN','Canning Vale/Perth','Canning Vale/Perth','WA'),('AU','CNS','Cairns','Cairns','QL'),('AU','COB','Coolibah','Coolibah','NT'),('AU','COJ','Coonabarabran','Coonabarabran','NS'),('AU','COM','Cooma','Cooma','NS'),('AU','COO','Coomera','Coomera','QL'),('AU','COP','Cossack Pioneer (oil terminal)','Cossack Pioneer (oil terminal)','WA'),('AU','COY','Coolawanyah','Coolawanyah','WA'),('AU','CPD','Coober Pedy','Coober Pedy','SA'),('AU','CPL','Capel','Capel','WA'),('AU','CPN','Cape Preston','Cape Preston','WA'),('AU','CPS','Coopers Plains','Coopers Plains','QL'),('AU','CQP','Cape Flattery','Cape Flattery','QL'),('AU','CRB','Collarenebri','Collarenebri','NS'),('AU','CRG','Caringbah','Caringbah','NS'),('AU','CRH','Cherribah','Cherribah','QL'),('AU','CRJ','Coorabie','Coorabie','SA'),('AU','CRS','Coral Sea','Coral Sea',''),('AU','CRY','Carlton Hill','Carlton Hill','WA'),('AU','CSD','Cresswell Downs','Cresswell Downs','NT'),('AU','CSI','Casino','Casino','NS'),('AU','CTB','Cataby','Cataby','WA'),('AU','CTH','Thevenard Island','Thevenard Island','WA'),('AU','CTL','Charleville','Charleville','QL'),('AU','CTN','Cooktown','Cooktown','QL'),('AU','CTR','Cattle Creek','Cattle Creek','NT'),('AU','CUD','Caloundra','Caloundra','QL'),('AU','CUG','Cudal','Cudal','NS'),('AU','CUQ','Coen','Coen','QL'),('AU','CUY','Cue','Cue','WA'),('AU','CVC','Cleve','Cleve','SA'),('AU','CVN','Cleveland','Cleveland','QL'),('AU','CVQ','Carnarvon','Carnarvon','WA'),('AU','CWI','Chatsworth Island','Chatsworth Island','NS'),('AU','CWR','Cowarie','Cowarie','SA'),('AU','CWT','Cowra','Cowra','NS'),('AU','CWW','Corowa','Corowa','NS'),('AU','CXQ','Christmas Creek','Christmas Creek','WA'),('AU','CXT','Charters Towers','Charters Towers','QL'),('AU','CYG','Corryong','Corryong','VI'),('AU','CZY','Cluny','Cluny','QL'),('AU','DAA','Darra','Darra','QL'),('AU','DAJ','Dauan Island','Dauan Island','QL'),('AU','DAM','Dampier','Dampier','WA'),('AU','DBO','Dubbo','Dubbo','NS'),('AU','DBY','Dalby','Dalby','QL'),('AU','DCR','Doncaster','Doncaster','VI'),('AU','DDI','Daydream Is','Daydream Is','QL'),('AU','DDK','Doodlakine','Doodlakine','WA'),('AU','DDN','Delta Downs','Delta Downs','QL'),('AU','DDO','Dunedoo','Dunedoo','NS'),('AU','DFP','Drumduff','Drumduff','QL'),('AU','DGE','Mudgee','Mudgee','NS'),('AU','DGO','Dungog','Dungog','NS'),('AU','DGY','Dingley Village','Dingley Village','VI'),('AU','DHD','Durham Downs','Durham Downs','QL'),('AU','DHL','Daisy Hill','Daisy Hill','QL'),('AU','DIT','Dalrymple Islet','Dalrymple Islet',''),('AU','DKI','Dunk Island','Dunk Island','QL'),('AU','DKV','Docker River','Docker River','NT'),('AU','DLK','Dulkaninna','Dulkaninna','SA'),('AU','DLV','Delissaville','Delissaville','NT'),('AU','DMA','Denmark','Denmark','WA'),('AU','DMD','Doomadgee','Doomadgee','QL'),('AU','DNB','Dunbar','Dunbar','QL'),('AU','DND','Dandenong','Dandenong','VI'),('AU','DNM','Denham','Denham','WA'),('AU','DNQ','Deniliquin','Deniliquin','NS'),('AU','DOX','Dongara','Dongara','WA'),('AU','DPO','Devonport','Devonport','TS'),('AU','DRB','Derby','Derby','WA'),('AU','DRD','Dorunda Station','Dorunda Station','QL'),('AU','DRE','Drummoyne/Sydney','Drummoyne/Sydney',''),('AU','DRN','Dirranbandi','Dirranbandi','QL'),('AU','DRR','Durrie','Durrie','QL'),('AU','DRW','Darwin','Darwin','NT'),('AU','DSB','Dunsborough','Dunsborough','WA'),('AU','DTO','Dapto','Dapto','NS'),('AU','DTP','Darlington Point','Darlington Point','NS'),('AU','DVP','Davenport Downs','Davenport Downs','QL'),('AU','DVR','Daly River','Daly River','NT'),('AU','DXD','Dixie','Dixie','QL'),('AU','DYA','Dysart','Dysart','QL'),('AU','DYM','Diamantina Lakes','Diamantina Lakes','QL'),('AU','DYW','Daly Waters','Daly Waters','NT'),('AU','EAB','Eneabba','Eneabba','WA'),('AU','EBH','Edinburgh','Edinburgh','SA'),('AU','EBO','Euabalong','Euabalong','NS'),('AU','ECH','Echuca','Echuca','VI'),('AU','EDB','Edithburgh','Edithburgh','SA'),('AU','EDD','Erldunda','Erldunda','NT'),('AU','EDR','Edward River','Edward River','QL'),('AU','EDW','Edwardstown','Edwardstown','SA'),('AU','EIH','Einasleigh','Einasleigh','QL'),('AU','EJB','East Jindabyne','East Jindabyne','NS'),('AU','EKD','Elkedra','Elkedra','NT'),('AU','ELC','Elcho Island','Elcho Island','NT'),('AU','ELE','Electrona','Electrona','TS'),('AU','ELF','Eagle Farm','Eagle Farm','QL'),('AU','ELW','Elsternwick','Elsternwick','VI'),('AU','ELZ','Elizabeth','Elizabeth','SA'),('AU','EMD','Emerald','Emerald','QL'),('AU','ENB','Eneabba West','Eneabba West','WA'),('AU','EPR','Esperance','Esperance','WA'),('AU','ERB','Ernabella','Ernabella','SA'),('AU','ETD','Etadunna','Etadunna','SA'),('AU','EUC','Eucla','Eucla','WA'),('AU','EVD','Eva Downs','Eva Downs','NT'),('AU','EVH','Evans Head','Evans Head','NS'),('AU','EXM','Exmouth Gulf','Exmouth Gulf','WA'),('AU','FBN','Fairbarn','Fairbarn','CT'),('AU','FCY','Footscray','Footscray','VI'),('AU','FFD','Fairfield','Fairfield','NS'),('AU','FIK','Finke','Finke','NT'),('AU','FIS','Fisherman Islands','Fisherman Islands','QL'),('AU','FIT','Fitzroy','Fitzroy','VI'),('AU','FLC','Falls Creek','Falls Creek','VI'),('AU','FLS','Flinders Island','Flinders Island','TS'),('AU','FLY','Finley','Finley','NS'),('AU','FOS','Forrest','Forrest','WA'),('AU','FOT','Forster','Forster','NS'),('AU','FRB','Forbes','Forbes','NS'),('AU','FRE','Fremantle','Fremantle','WA'),('AU','FSL','Fossil Downs','Fossil Downs','WA'),('AU','FTN','Fullerton','Fullerton','NS'),('AU','FYW','Fyshwick','Fyshwick','CT'),('AU','GAH','Gayndah','Gayndah','QL'),('AU','GBL','Goulburn Island','Goulburn Island','NT'),('AU','GBP','Gamboola','Gamboola','QL'),('AU','GBT','Garbutt Station','Garbutt Station','QL'),('AU','GBV','Gibb River','Gibb River','WA'),('AU','GCE','Gloucester','Gloucester','NS'),('AU','GDA','Gundagai','Gundagai','NS'),('AU','GDD','Gordon Downs','Gordon Downs','WA'),('AU','GDF','Guildford','Guildford','NS'),('AU','GEE','George Town','George Town','TS'),('AU','GET','Geraldton','Geraldton','WA'),('AU','GEX','Geelong','Geelong','VI'),('AU','GFE','Grenfell','Grenfell','NS'),('AU','GFF','Griffith','Griffith','NS'),('AU','GFN','Grafton','Grafton','NS'),('AU','GGD','Gregory Downs','Gregory Downs','QL'),('AU','GGO','Grong Grong','Grong Grong','NS'),('AU','GIC','Boigu Island','Boigu Island','QL'),('AU','GIL','Gillman','Gillman','SA'),('AU','GKL','Great Keppel Island','Great Keppel Island','QL'),('AU','GLG','Glengyle','Glengyle','QL'),('AU','GLI','Glen Innes','Glen Innes','NS'),('AU','GLL','Glebe Island','Glebe Island','NS'),('AU','GLM','Glenormiston','Glenormiston','QL'),('AU','GLO','Galong','Galong','NS'),('AU','GLT','Gladstone','Gladstone','QL'),('AU','GLY','Goldsworthy','Goldsworthy','WA'),('AU','GMA','Ganmain','Ganmain','NS'),('AU','GNI','Gingin','Gingin','WA'),('AU','GNU','Greenough','Greenough','WA'),('AU','GOI','Goode Is','Goode Is','QL'),('AU','GOO','Goondiwindi','Goondiwindi','QL'),('AU','GOS','Gosford','Gosford','NS'),('AU','GOV','Gove','Gove','NT'),('AU','GPN','Garden Point','Garden Point','NT'),('AU','GRA','Grassy','Grassy','TS'),('AU','GRH','Greenhead','Greenhead','WA'),('AU','GRV','Griffin Venture (oil terminal)','Griffin Venture (oil terminal)','WA'),('AU','GSC','Gascoyne Junction','Gascoyne Junction','WA'),('AU','GSN','Mount Gunson','Mount Gunson','SA'),('AU','GTE','Groote Eylandt','Groote Eylandt','NT'),('AU','GTS','Granites','Granites','NT'),('AU','GTT','Georgetown','Georgetown','QL'),('AU','GUG','Geebung','Geebung','QL'),('AU','GUH','Gunnedah','Gunnedah','NS'),('AU','GUL','Goulburn','Goulburn','NS'),('AU','GUN','Gunning','Gunning','NS'),('AU','GVP','Greenvale','Greenvale','QL'),('AU','GWG','Gnowangerup','Gnowangerup','WA'),('AU','GYL','Argyle','Argyle','WA'),('AU','GYP','Gympie','Gympie','QL'),('AU','HAB','Haberfield','Haberfield','NS'),('AU','HAP','Long Island','Long Island','QL'),('AU','HAS','Hastings','Hastings','VI'),('AU','HAT','Heathlands','Heathlands','QL'),('AU','HBA','Hobart','Hobart','TS'),('AU','HBS','Homebush/Sydney','Homebush/Sydney','NS'),('AU','HCQ','Halls Creek','Halls Creek','WA'),('AU','HDN','Harden','Harden','NS'),('AU','HGD','Hughenden','Hughenden','QL'),('AU','HHT','Highett/Melbourne','Highett/Melbourne','VI'),('AU','HID','Horn Island','Horn Island','QL'),('AU','HIG','Highbury','Highbury','QL'),('AU','HIH','Hook Island','Hook Island','QL'),('AU','HIP','Headingly','Headingly','QL'),('AU','HIS','Hayman Island','Hayman Island','QL'),('AU','HLL','Hillside','Hillside','WA'),('AU','HLM','Hallam','Hallam','VI'),('AU','HLS','St Helens','St Helens','TS'),('AU','HLT','Hamilton','Hamilton','VI'),('AU','HLV','Helenvale','Helenvale','QL'),('AU','HMG','Hermannsburg','Hermannsburg','NT'),('AU','HNK','Hinchinbrook Island','Hinchinbrook Island','QL'),('AU','HOK','Hooker Creek','Hooker Creek','NT'),('AU','HOT','Hope Tun','Hope Tun','WA'),('AU','HOY','Hornsby','Hornsby','NS'),('AU','HPE','Hope Vale','Hope Vale','QL'),('AU','HPN','Hampton','Hampton','NS'),('AU','HPO','Hastings Point','Hastings Point','NS'),('AU','HPT','Haypoint','Haypoint','QL'),('AU','HRN','Heron Island','Heron Island','QL'),('AU','HRY','Henbury','Henbury','NT'),('AU','HSM','Horsham','Horsham','VI'),('AU','HTE','Hawthorn','Hawthorn','VI'),('AU','HTI','Hamilton Island','Hamilton Island','QL'),('AU','HTU','Hopetoun','Hopetoun','VI'),('AU','HTY','Henty','Henty','NS'),('AU','HUB','Humbert River','Humbert River','NT'),('AU','HVB','Hervey Bay','Hervey Bay','QL'),('AU','HVY','Harvey','Harvey','WA'),('AU','HWK','Hawker','Hawker','SA'),('AU','HWN','Hawks Nest','Hawks Nest','NS'),('AU','HWO','Howlong','Howlong','NS'),('AU','HXX','Hay','Hay','NS'),('AU','HYD','Hyden','Hyden','WA'),('AU','HYI','Hardy Island','Hardy Island','NT'),('AU','IDK','Indulkana','Indulkana','SA'),('AU','IFF','Iffley','Iffley','QL'),('AU','IFL','Innisfail','Innisfail','QL'),('AU','IGH','Ingham','Ingham','QL'),('AU','IHO','Ivanhoe','Ivanhoe','NS'),('AU','IKP','Inkerman','Inkerman','QL'),('AU','INJ','Injune','Injune','QL'),('AU','INM','Innamincka','Innamincka','SA'),('AU','IPS','Ipswich','Ipswich','QL'),('AU','IRG','Lockhart River','Lockhart River','QL'),('AU','ISA','Mount Isa','Mount Isa','QL'),('AU','ISI','Isisford','Isisford','QL'),('AU','IVR','Inverell','Inverell','NS'),('AU','IVW','Inverway','Inverway','NT'),('AU','JAB','Jabiru','Jabiru','NT'),('AU','JAD','Jandakot','Jandakot','WA'),('AU','JCK','Julia Creek','Julia Creek','QL'),('AU','JDE','Jerilderie','Jerilderie','NS'),('AU','JEB','Jervis Bay','Jervis Bay','NS'),('AU','JHQ','Shute Harbour','Shute Harbour','QL'),('AU','JNE','Junee','Junee','NS'),('AU','JOV','Jabiru Venture (oil terminal)','Jabiru Venture (oil terminal)','NT'),('AU','JUN','Jundah','Jundah','QL'),('AU','JUR','Jurien Bay','Jurien Bay','WA'),('AU','KAH','Melbourne City Heliport','Melbourne City Heliport','VI'),('AU','KAX','Kalbarri','Kalbarri','WA'),('AU','KBB','Kirkimbie','Kirkimbie','NT'),('AU','KBD','Kimberley Downs','Kimberley Downs','WA'),('AU','KBG','Koolyanbobbing','Koolyanbobbing','WA'),('AU','KBI','Kellerberrin','Kellerberrin','WA'),('AU','KBJ','Kings Canyon','Kings Canyon','NT'),('AU','KBY','Streaky Bay','Streaky Bay','SA'),('AU','KCE','Collinsville','Collinsville','QL'),('AU','KCS','Kings Creek Station','Kings Creek Station','NT'),('AU','KDA','Kendall','Kendall','NS'),('AU','KDB','Kambalda','Kambalda','WA'),('AU','KDS','Kamaran Downs','Kamaran Downs','QL'),('AU','KFG','Kalkurung','Kalkurung','NT'),('AU','KGA','Kembla','Kembla','NS'),('AU','KGC','Kingscote','Kingscote','SA'),('AU','KGG','Kingsgrove','Kingsgrove','NS'),('AU','KGI','Kalgoorlie','Kalgoorlie','WA'),('AU','KGR','Kulgera','Kulgera','NT'),('AU','KGY','Kingaroy','Kingaroy','QL'),('AU','KIB','King Bay','King Bay','WA'),('AU','KIT','Kingston','Kingston','SA'),('AU','KKP','Koolburra','Koolburra','QL'),('AU','KKQ','Kurri Kurri','Kurri Kurri','NS'),('AU','KLP','Klein Point','Klein Point','WA'),('AU','KML','Kamileroi','Kamileroi','QL'),('AU','KNI','Katanning','Katanning','WA'),('AU','KNS','King Is','King Is','TS'),('AU','KNX','Kununurra','Kununurra','WA'),('AU','KOH','Koolatah','Koolatah','QL'),('AU','KOI','Koolan Island','Koolan Island','WA'),('AU','KPK','Kings Park','Kings Park','NS'),('AU','KPP','Kalpowar','Kalpowar','QL'),('AU','KPS','Kempsey','Kempsey','NS'),('AU','KQB','Koonibba','Koonibba','SA'),('AU','KRA','Kerang','Kerang','VI'),('AU','KRB','Karumba','Karumba','QL'),('AU','KRD','Kurundi','Kurundi','NT'),('AU','KSV','Springvale','Springvale','QL'),('AU','KTA','Karratha','Karratha','WA'),('AU','KTB','Katoomba','Katoomba','NS'),('AU','KTR','Katherine','Katherine','NT'),('AU','KUG','Kubin Island','Kubin Island','QL'),('AU','KUP','Kunda Park','Kunda Park','QL'),('AU','KUR','Kurnell','Kurnell','NS'),('AU','KWA','Koorawatha','Koorawatha','NS'),('AU','KWI','Kwinana','Kwinana','WA'),('AU','KWM','Kowanyama','Kowanyama','QL'),('AU','KWR','Koo-Wee-Rup','Koo-Wee-Rup','VI'),('AU','KYB','Yangoonabie','Yangoonabie','SA'),('AU','KYF','Yeelirrie','Yeelirrie','WA'),('AU','KYI','Yalata Mission','Yalata Mission','SA'),('AU','LAB','Lady Barron','Lady Barron','TS'),('AU','LAM','Lamplough','Lamplough','VI'),('AU','LCG','Lake Cargelligo','Lake Cargelligo','NS'),('AU','LCN','Balcanoona','Balcanoona','SA'),('AU','LDB','Lidcombe','Lidcombe','NS'),('AU','LDC','Lindeman Island','Lindeman Island','QL'),('AU','LDH','Lord Howe Is','Lord Howe Is','NS'),('AU','LDW','Lansdowne','Lansdowne','WA'),('AU','LEA','Learmonth','Learmonth','WA'),('AU','LEL','Lake Evella','Lake Evella','NT'),('AU','LER','Leinster','Leinster','WA'),('AU','LFP','Lakefield','Lakefield','QL'),('AU','LGA','Leongatha','Leongatha','VI'),('AU','LGF','Longford','Longford','VI'),('AU','LGH','Leigh Creek','Leigh Creek','SA'),('AU','LGT','Legendre Terminal','Legendre Terminal','WA'),('AU','LHG','Lightning Ridge','Lightning Ridge','NS'),('AU','LHI','Laurel Hill','Laurel Hill','NS'),('AU','LHM','Lyneham','Lyneham','CT'),('AU','LIB','Limbunya','Limbunya','NT'),('AU','LIV','Liverpool','Liverpool','NS'),('AU','LKA','Lockhart','Lockhart','NS'),('AU','LKD','Lakeland Downs','Lakeland Downs','QL'),('AU','LLG','Chillagoe','Chillagoe','QL'),('AU','LLL','Lissadell','Lissadell','WA'),('AU','LLP','Linda Downs','Linda Downs','QL'),('AU','LNC','Lane Cove','Lane Cove','NS'),('AU','LNH','Lake Nash','Lake Nash','NT'),('AU','LNO','Leonora','Leonora','WA'),('AU','LOA','Lorraine','Lorraine','QL'),('AU','LOC','Lock','Lock','SA'),('AU','LOW','Lisarow','Lisarow','NS'),('AU','LRE','Longreach','Longreach','QL'),('AU','LRI','Little River','Little River','VI'),('AU','LSD','Lonsdale','Lonsdale','SA'),('AU','LST','Launceston','Launceston','TS'),('AU','LSY','Lismore','Lismore','NS'),('AU','LTB','Latrobe','Latrobe','TS'),('AU','LTG','Lithgow','Lithgow','NS'),('AU','LTP','Lyndhurst','Lyndhurst','QL'),('AU','LTV','Lotusvale','Lotusvale','QL'),('AU','LUC','Lucinda','Lucinda','QL'),('AU','LUN','Lurnea/Sydney','Lurnea/Sydney','NS'),('AU','LUT','Laura Station','Laura Station','QL'),('AU','LUU','Laura','Laura','QL'),('AU','LVO','Laverton','Laverton','WA'),('AU','LWH','Lawn Hill','Lawn Hill','QL'),('AU','LYD','Lilydale','Lilydale','VI'),('AU','LYT','Lady Elliot Island','Lady Elliot Island','QL'),('AU','LZR','Lizard Island','Lizard Island','QL'),('AU','MAR','Marrickville','Marrickville','NS'),('AU','MAS','Mascot','Mascot','NS'),('AU','MBA','Mt Barker','Mt Barker','WA'),('AU','MBB','Marble Bar','Marble Bar','WA'),('AU','MBF','Mount Buffalo','Mount Buffalo','VI'),('AU','MBH','Maryborough','Maryborough','QL'),('AU','MBM','Murrumbateman','Murrumbateman','NS'),('AU','MBN','Mt Barnett','Mt Barnett','WA'),('AU','MBU','Mukinbudin','Mukinbudin','WA'),('AU','MBW','Moorabbin','Moorabbin','VI'),('AU','MCV','Mcarthur River','Mcarthur River','NT'),('AU','MCY','Maroochydore Apt/Sunshine Coast','Maroochydore Apt/Sunshine Coast','QL'),('AU','MDA','Merinda','Merinda','QL'),('AU','MDO','Maidstone','Maidstone','VI'),('AU','MDU','Mandurah','Mandurah','WA'),('AU','MEB','Essendon Apt/Melbourne','Essendon Apt/Melbourne','VI'),('AU','MEL','Melbourne','Melbourne','VI'),('AU','MET','Moreton','Moreton','QL'),('AU','MFL','Mount Full Stop','Mount Full Stop','QL'),('AU','MFP','Manners Creek','Manners Creek','NT'),('AU','MGB','Mount Gambier','Mount Gambier','SA'),('AU','MGO','Mittagong','Mittagong','NS'),('AU','MGR','Margaret River','Margaret River','WA'),('AU','MGT','Milingimbi','Milingimbi','NT'),('AU','MGV','Margaret River Station','Margaret River Station','WA'),('AU','MHA','Mathoura','Mathoura','NS'),('AU','MHC','Macmahon Camp 4','Macmahon Camp 4','SA'),('AU','MHE','Muchea','Muchea','WA'),('AU','MHO','Mount House','Mount House','WA'),('AU','MHU','Mount Hotham','Mount Hotham','VI'),('AU','MIB','Milner Bay','Milner Bay','NT'),('AU','MIH','Mitchell Plateau','Mitchell Plateau','WA'),('AU','MIM','Merimbula','Merimbula','NS'),('AU','MIN','Minnipa','Minnipa','SA'),('AU','MIT','Mitcham','Mitcham','VI'),('AU','MIY','Mittiebah','Mittiebah','NT'),('AU','MIZ','Mainoru','Mainoru','NT'),('AU','MJK','Monkey Mia','Monkey Mia','WA'),('AU','MJP','Manjimup','Manjimup','WA'),('AU','MKR','Meekatharra','Meekatharra','WA'),('AU','MKV','Mt Cavenagh','Mt Cavenagh','NT'),('AU','MKY','Mackay','Mackay','QL'),('AU','MLA','Michelago','Michelago','NS'),('AU','MLI','Melville Island','Melville Island','NT'),('AU','MLR','Millicent','Millicent','SA'),('AU','MLV','Merluna','Merluna','QL'),('AU','MLY','Morley','Morley','WA'),('AU','MMA','Mt Magnet','Mt Magnet','WA'),('AU','MMG','Mount Magnet','Mount Magnet','WA'),('AU','MMM','Middlemount','Middlemount','QL'),('AU','MNE','Mungeranie','Mungeranie','SA'),('AU','MNG','Maningrida','Maningrida','NT'),('AU','MNQ','Monto','Monto','QL'),('AU','MNV','Mountain Valley','Mountain Valley','NT'),('AU','MNW','Macdonald Downs','Macdonald Downs','NT'),('AU','MOA','Moama','Moama','NS'),('AU','MOK','Moorook','Moorook','SA'),('AU','MOO','Moomba','Moomba','SA'),('AU','MOR','Morwell','Morwell','VI'),('AU','MOU','Mourilyan','Mourilyan','QL'),('AU','MOV','Moranbah','Moranbah','QL'),('AU','MOW','Mowbray Heights','Mowbray Heights','TS'),('AU','MQA','Mandora','Mandora','WA'),('AU','MQE','Marqua','Marqua','NT'),('AU','MQI','Macquarie Island','Macquarie Island','TS'),('AU','MQL','Mildura','Mildura','VI'),('AU','MRA','Moora','Moora','WA'),('AU','MRB','Moorebank/Sydney','Moorebank/Sydney','NS'),('AU','MRD','Merredin','Merredin','WA'),('AU','MRG','Mareeba','Mareeba','QL'),('AU','MRI','Murarrie','Murarrie','QL'),('AU','MRL','Miners Lake','Miners Lake','QL'),('AU','MRP','Marla','Marla','SA'),('AU','MRS','Melrose','Melrose','SA'),('AU','MRT','Moroak','Moroak','NT'),('AU','MRZ','Moree','Moree','NS'),('AU','MSA','Mosman','Mosman','NS'),('AU','MSF','Mount Swan','Mount Swan','NT'),('AU','MTA','Muttama','Muttama','NS'),('AU','MTD','Mt Sandford','Mt Sandford','NT'),('AU','MTL','Maitland','Maitland','NS'),('AU','MTO','Matong','Matong','NS'),('AU','MTQ','Mitchell','Mitchell','QL'),('AU','MTW','Mt Waverly','Mt Waverly','VI'),('AU','MUL','Mulgrave','Mulgrave','VI'),('AU','MUP','Mulga Park','Mulga Park','NT'),('AU','MUQ','Muccan','Muccan','WA'),('AU','MVA','Moss Vale','Moss Vale','NS'),('AU','MVH','Macksville','Macksville','NS'),('AU','MVK','Mulka','Mulka','SA'),('AU','MVU','Musgrave','Musgrave','QL'),('AU','MWA','Mulwala','Mulwala','NS'),('AU','MWB','Morawa','Morawa','WA'),('AU','MWT','Moolawatana','Moolawatana','SA'),('AU','MWY','Miranda Downs','Miranda Downs','QL'),('AU','MXD','Marion Downs','Marion Downs','QL'),('AU','MXQ','Mitchell River','Mitchell River','QL'),('AU','MXU','Mullewa','Mullewa','WA'),('AU','MYA','Moruya','Moruya','NS'),('AU','MYF','Mayfield','Mayfield','NS'),('AU','MYI','Murray Island','Murray Island','QL'),('AU','MYO','Myroodah','Myroodah','WA'),('AU','NAA','Narrabri','Narrabri','NS'),('AU','NAC','Naracoorte','Naracoorte','SA'),('AU','NAR','Narracoopa','Narracoopa','TS'),('AU','NBE','Narembeen','Narembeen','WA'),('AU','NBH','Nambucca Heads','Nambucca Heads','NS'),('AU','NBP','Noble Park','Noble Park','VI'),('AU','NBR','Nambour','Nambour','QL'),('AU','NBW','North Balwyn','North Balwyn','VI'),('AU','NDS','Sandstone','Sandstone','WA'),('AU','NGA','Young','Young','NS'),('AU','NGH','Nganhurra','Nganhurra','WA'),('AU','NGT','Northgate','Northgate','QL'),('AU','NHA','Northam','Northam','WA'),('AU','NIF','Nifty','Nifty','WA'),('AU','NKB','Noonkanbah','Noonkanbah','WA'),('AU','NLF','Darnley Island','Darnley Island','QL'),('AU','NLL','Nullagine','Nullagine','WA'),('AU','NLS','Nicholson','Nicholson','WA'),('AU','NMP','New Moon','New Moon','QL'),('AU','NMR','Nappa Merry','Nappa Merry','QL'),('AU','NNU','Nannup','Nannup','WA'),('AU','NOA','Nowra','Nowra','NS'),('AU','NOO','Nuriootpa','Nuriootpa','SA'),('AU','NOR','Norwood','Norwood','SA'),('AU','NPP','Napperby','Napperby','NT'),('AU','NRA','Narrandera','Narrandera','NS'),('AU','NRE','North Ryde','North Ryde','NS'),('AU','NRG','Narrogin','Narrogin','WA'),('AU','NRN','Nerong','Nerong','NS'),('AU','NRY','Newry','Newry','NT'),('AU','NSA','Noosa','Noosa','QL'),('AU','NSD','Newstead','Newstead','QL'),('AU','NSM','Norseman','Norseman','WA'),('AU','NSO','Scone','Scone','NS'),('AU','NSV','Noosaville','Noosaville','QL'),('AU','NTA','Nimmitabel','Nimmitabel','NS'),('AU','NTE','Northern Endeavour','Northern Endeavour','NT'),('AU','NTH','Notting Hill','Notting Hill','VI'),('AU','NTL','Newcastle','Newcastle','NS'),('AU','NTN','Normanton','Normanton','QL'),('AU','NUB','Numbulwar','Numbulwar','NT'),('AU','NUR','Nullarbor','Nullarbor','SA'),('AU','NWM','Newman','Newman','WA'),('AU','NYN','Nyngan','Nyngan','NS'),('AU','OAG','Orange','Orange','NS'),('AU','OBA','Oban','Oban','QL'),('AU','ODD','Oodnadatta','Oodnadatta','SA'),('AU','ODL','Cordillo Downs','Cordillo Downs','SA'),('AU','ODR','Ord River','Ord River','WA'),('AU','OKB','Orchid Beach','Orchid Beach','QL'),('AU','OKR','Yorke Island','Yorke Island','QL'),('AU','OKY','Oakey','Oakey','QL'),('AU','OLH','Oakleigh','Oakleigh','VI'),('AU','OLP','Olympic Dam','Olympic Dam','SA'),('AU','ONG','Mornington','Mornington','QL'),('AU','ONR','Monkira','Monkira','QL'),('AU','ONS','Onslow','Onslow','WA'),('AU','OOD','Riverwood','Riverwood','NS'),('AU','OOL','Gold Coast Apt/Coolangatta','Gold Coast Apt/Coolangatta','QL'),('AU','OOR','Mooraberree','Mooraberree','QL'),('AU','OPI','Oenpelli','Oenpelli','NT'),('AU','ORR','Yorketown','Yorketown','SA'),('AU','ORS','Orpheus Island Resort','Orpheus Island Resort','QL'),('AU','OSB','Osborne Island','Osborne Island','WA'),('AU','OSP','Osborne Park','Osborne Park','WA'),('AU','OTO','Ottoway','Ottoway','SA'),('AU','OXO','Orientos','Orientos','QL'),('AU','OXY','Morney','Morney','QL'),('AU','OYN','Ouyen','Ouyen','VI'),('AU','PAE','Port Adelaide','Port Adelaide','SA'),('AU','PAU','Port Arthur','Port Arthur','TS'),('AU','PBE','Pemberton','Pemberton','WA'),('AU','PBO','Paraburdoo','Paraburdoo','WA'),('AU','PBT','Port Botany','Port Botany','NS'),('AU','PBU','Pambula','Pambula','NS'),('AU','PBY','Port Bonython','Port Bonython','SA'),('AU','PCE','Pearce','Pearce','WA'),('AU','PCT','Port Curtis','Port Curtis','QL'),('AU','PDA','Pindar','Pindar','WA'),('AU','PDE','Pandie Pandie','Pandie Pandie','SA'),('AU','PDI','Port Denison','Port Denison','WA'),('AU','PDN','Parndana','Parndana','SA'),('AU','PEA','Penneshaw','Penneshaw','SA'),('AU','PEL','Pelican Point','Pelican Point','SA'),('AU','PEP','Peppimenarti','Peppimenarti','NT'),('AU','PER','Perth','Perth','WA'),('AU','PEX','Exmouth','Exmouth','WA'),('AU','PEY','Penong','Penong','SA'),('AU','PGI','Port Giles','Port Giles','SA'),('AU','PGY','Pingelly','Pingelly','WA'),('AU','PHE','Port Hedland','Port Hedland','WA'),('AU','PHI','Peak Hill','Peak Hill','NS'),('AU','PHJ','Port Hunter','Port Hunter','NS'),('AU','PHP','Point Henry Pier/Melbourne','Point Henry Pier/Melbourne','VI'),('AU','PHU','Port Huon','Port Huon','TS'),('AU','PIA','Pialba','Pialba','QL'),('AU','PJA','Pinjarra','Pinjarra','WA'),('AU','PJK','Port Jackson','Port Jackson','NS'),('AU','PKE','Parkes','Parkes','NS'),('AU','PKL','Port Kembla','Port Kembla','NS'),('AU','PKT','Port Keats','Port Keats','NT'),('AU','PLA','Port Latta','Port Latta','TS'),('AU','PLO','Port Lincoln','Port Lincoln','SA'),('AU','PMK','Palm Island','Palm Island','QL'),('AU','PNA','Pinkenba','Pinkenba','QL'),('AU','POR','Port Melbourne','Port Melbourne','VI'),('AU','PPI','Port Pirie','Port Pirie','SA'),('AU','PPP','Proserpine','Proserpine','QL'),('AU','PQQ','Port Macquarie','Port Macquarie','NS'),('AU','PRB','Proper Bay','Proper Bay','SA'),('AU','PRC','Price','Price','SA'),('AU','PRD','Pardoo','Pardoo','WA'),('AU','PRH','Penrith','Penrith','NS'),('AU','PRM','Parramatta','Parramatta','NS'),('AU','PSM','Point Samson','Point Samson','WA'),('AU','PST','Port Stanvac','Port Stanvac','SA'),('AU','PSY','Port Stanley','Port Stanley','TS'),('AU','PTD','Port Dalrymple','Port Dalrymple','QL'),('AU','PTE','Port Stephens','Port Stephens','NS'),('AU','PTI','Port Douglas','Port Douglas','QL'),('AU','PTJ','Portland','Portland','VI'),('AU','PTL','Port Alma','Port Alma','QL'),('AU','PUG','Port Augusta','Port Augusta','SA'),('AU','PWI','Point Wilson','Point Wilson','VI'),('AU','PWL','Port Walcott','Port Walcott','WA'),('AU','PWR','Port Warrender','Port Warrender','WA'),('AU','QBY','Queanbeyan','Queanbeyan','NS'),('AU','QDI','Quairading','Quairading','WA'),('AU','QDN','Eden','Eden','NS'),('AU','QEL','Wellington','Wellington','NS'),('AU','RAB','Rapid Bay','Rapid Bay','SA'),('AU','RAM','Ramingining','Ramingining','NT'),('AU','RAV','Ravensthorpe','Ravensthorpe','WA'),('AU','RBC','Robinvale','Robinvale','VI'),('AU','RBS','Orbost','Orbost','VI'),('AU','RBU','Roebourne','Roebourne','WA'),('AU','RBY','Rosebery/Sydney','Rosebery/Sydney','NS'),('AU','RCE','Redcliffe','Redcliffe','WA'),('AU','RCH','Richmond','Richmond','NS'),('AU','RCM','Richmond','Richmond','QL'),('AU','RCN','American River','American River','SA'),('AU','RDA','Rockhampton Downs','Rockhampton Downs','NT'),('AU','RDN','Risdon','Risdon','TS'),('AU','REV','Revesby','Revesby','NS'),('AU','RHL','Roy Hill','Roy Hill','WA'),('AU','RHM','Richmond','Richmond','VI'),('AU','RKY','Rokeby','Rokeby','QL'),('AU','RLP','Rosella Plains','Rosella Plains','QL'),('AU','RMA','Roma','Roma','QL'),('AU','RMK','Renmark','Renmark','SA'),('AU','RMR','Murrey','Murrey','SA'),('AU','ROC','The Rock','The Rock','NS'),('AU','ROH','Robinhood','Robinhood','QL'),('AU','ROK','Rockhampton','Rockhampton','QL'),('AU','ROS','Rose Hill','Rose Hill','NS'),('AU','RPB','Roper Bar','Roper Bar','NT'),('AU','RPM','Ngukurr','Ngukurr','NT'),('AU','RPV','Roper Valley','Roper Valley','NT'),('AU','RRE','Marree','Marree','SA'),('AU','RRV','Robinson River','Robinson River','NT'),('AU','RSB','Roseberth','Roseberth','QL'),('AU','RSE','Au-Rose Bay','Au-Rose Bay','NS'),('AU','RTO','Robertson','Robertson','NS'),('AU','RTP','Rutland Plains','Rutland Plains','QL'),('AU','RTS','Rottnest Island','Rottnest Island','WA'),('AU','RTY','Merty','Merty','SA'),('AU','RVV','Riverina','Riverina','WA'),('AU','RWE','Rowville','Rowville','VI'),('AU','RYC','Reedy Creek','Reedy Creek','QL'),('AU','RYK','Regency Park','Regency Park','SA'),('AU','RYM','Rydalmere','Rydalmere','NS'),('AU','RYP','Rocky Point','Rocky Point','WA'),('AU','SBI','Stockinbingal','Stockinbingal','NS'),('AU','SBR','Saibai Island','Saibai Island','QL'),('AU','SBY','Salisbury/Brisbane','Salisbury/Brisbane','QL'),('AU','SCG','Spring Creek','Spring Creek','QL'),('AU','SCY','Scoresby','Scoresby','VI'),('AU','SFF','Stafford','Stafford','QL'),('AU','SFI','Strathfield','Strathfield','NS'),('AU','SFP','Surfers Paradise','Surfers Paradise','QL'),('AU','SGD','South Guilford','South Guilford','WA'),('AU','SGO','St George','St George','QL'),('AU','SGP','Shay Gap','Shay Gap','WA'),('AU','SHB','Shark Bay','Shark Bay','WA'),('AU','SHI','Spring Hill','Spring Hill','NS'),('AU','SHQ','Southport','Southport','QL'),('AU','SHT','Shepparton','Shepparton','VI'),('AU','SHU','Smith Point','Smith Point','NT'),('AU','SIO','Smithton','Smithton','TS'),('AU','SIX','Singleton','Singleton','NS'),('AU','SKA','Skardon River','Skardon River','QL'),('AU','SKV','Skua Venture (oil terminal)','Skua Venture (oil terminal)','NT'),('AU','SMD','Smithfield','Smithfield','NS'),('AU','SMT','Saladin Marine Terminal','Saladin Marine Terminal','WA'),('AU','SNB','Snake Bay','Snake Bay','NT'),('AU','SNH','Stanthorpe','Stanthorpe','QL'),('AU','SOI','South Molle Island','South Molle Island','QL'),('AU','SOM','Somerton','Somerton','VI'),('AU','SPB','Spring Bay','Spring Bay','TS'),('AU','SPO','Spreyton','Spreyton','TS'),('AU','SQC','Southern Cross','Southern Cross','WA'),('AU','SQP','Starcke','Starcke','QL'),('AU','SRM','Sandringham','Sandringham','QL'),('AU','SRN','Strahan','Strahan','TS'),('AU','SRR','Stradbroke Island','Stradbroke Island','QL'),('AU','SSE','Sunshine/Melbourne','Sunshine/Melbourne','VI'),('AU','SSK','Sturt Creek','Sturt Creek','WA'),('AU','SSP','Silver Plains','Silver Plains','QL'),('AU','STA','Stanley','Stanley','TS'),('AU','STF','Stephen Island','Stephen Island','QL'),('AU','STG','Stage Platform','Stage Platform','WA'),('AU','STH','Strathmore','Strathmore','QL'),('AU','STM','Saint Marys','Saint Marys','NS'),('AU','STP','St Peters','St Peters','NS'),('AU','STR','South Trees','South Trees','QL'),('AU','SUH','Surry Hills','Surry Hills','NS'),('AU','SUM','Summertown','Summertown','SA'),('AU','SVM','St Paul\'s Mission','St Paul\'s Mission','QL'),('AU','SWB','Shaw River','Shaw River','WA'),('AU','SWC','Stawell','Stawell','VI'),('AU','SWH','Swan Hill','Swan Hill','VI'),('AU','SWO','South Windsor','South Windsor','NS'),('AU','SWR','South West Rocks','South West Rocks','NS'),('AU','SXE','Sale','Sale','VI'),('AU','SYD','Sydney','Sydney','NS'),('AU','SYU','Sue Island','Sue Island','QL'),('AU','TAM','Tambourine','Tambourine','QL'),('AU','TAN','Tangalooma','Tangalooma','QL'),('AU','TAQ','Tarcoola','Tarcoola','SA'),('AU','TBB','Tumbarumba','Tumbarumba','NS'),('AU','TBC','Toowoomba City','Toowoomba City','QL'),('AU','TBK','Timber Creek','Timber Creek','NT'),('AU','TBL','Tableland','Tableland','WA'),('AU','TCA','Tennant Creek','Tennant Creek','NT'),('AU','TCW','Tocumwal','Tocumwal','NS'),('AU','TDA','Toodyay','Toodyay','WA'),('AU','TDR','Theodore','Theodore','QL'),('AU','TEF','Telfer','Telfer','WA'),('AU','TEM','Temora','Temora','NS'),('AU','TGE','Tullibigeal','Tullibigeal','NS'),('AU','TGN','Traralgon','Traralgon','VI'),('AU','TGO','Tarago','Tarago','NS'),('AU','TGY','Tomingley','Tomingley','NS'),('AU','THE','Thevenard','Thevenard','SA'),('AU','THG','Thangool','Thangool','QL'),('AU','THO','Thomastown','Thomastown','VI'),('AU','THS','Tweed Heads South','Tweed Heads South','NS'),('AU','TIN','Tindal','Tindal','NT'),('AU','TIS','Thursday Island','Thursday Island','QL'),('AU','TKY','Turkey Creek','Turkey Creek','WA'),('AU','TME','Tullamarine','Tullamarine','VI'),('AU','TMW','Tamworth','Tamworth','NS'),('AU','TOB','Towford Bay','Towford Bay',''),('AU','TOJ','Tongala','Tongala','VI'),('AU','TOT','Tottenham','Tottenham','NS'),('AU','TPR','Tom Price','Tom Price','WA'),('AU','TPT','Timber Point','Timber Point',''),('AU','TRB','Trial Bay','Trial Bay','NS'),('AU','TRO','Taree','Taree','NS'),('AU','TSV','Townsville','Townsville','QL'),('AU','TUM','Tumut','Tumut','NS'),('AU','TUV','Tuerong','Tuerong','VI'),('AU','TWB','Toowoomba','Toowoomba','QL'),('AU','TWH','Tanawha','Tanawha','QL'),('AU','TWN','Tewantin','Tewantin','QL'),('AU','TWP','Torwood','Torwood','QL'),('AU','TXR','Tanbar','Tanbar','QL'),('AU','TYB','Tibooburra','Tibooburra','NS'),('AU','TYG','Thylungra','Thylungra','QL'),('AU','TYP','Tobermorey','Tobermorey','NT'),('AU','UBB','Mabuiag Island','Mabuiag Island','QL'),('AU','UBU','Kalumburu','Kalumburu','WA'),('AU','UDA','Undarra','Undarra','QL'),('AU','UEE','Queenstown','Queenstown','TS'),('AU','UGI','Ungarie','Ungarie','NS'),('AU','UIR','Quirindi','Quirindi','NS'),('AU','ULA','Ulladulla','Ulladulla','NS'),('AU','ULP','Quilpie','Quilpie','QL'),('AU','ULV','Ulverstone','Ulverstone','TS'),('AU','UMR','Woomera','Woomera','SA'),('AU','UNA','Urana','Urana','NS'),('AU','URN','Urangan','Urangan','QL'),('AU','USL','Useless Loop','Useless Loop','WA'),('AU','UTB','Muttaburra','Muttaburra','QL'),('AU','UTD','Nutwood Downs','Nutwood Downs','NT'),('AU','VAR','Varanus Island','Varanus Island','WA'),('AU','VCD','Victoria River Downs','Victoria River Downs','NT'),('AU','VIW','Villawood/Sydney','Villawood/Sydney','NS'),('AU','VNR','Vanrook','Vanrook','QL'),('AU','VRG','Virginia','Virginia','SA'),('AU','WAB','Warabrook','Warabrook','NS'),('AU','WAD','Wandandian','Wandandian','NS'),('AU','WAL','Wallaroo','Wallaroo','SA'),('AU','WAN','Waverney','Waverney','QL'),('AU','WAU','Wauchope','Wauchope','NS'),('AU','WAV','Wave Hill','Wave Hill','NT'),('AU','WAZ','Warwick','Warwick','QL'),('AU','WBT','Woollybutt (Oil facility)','Woollybutt (Oil facility)','WA'),('AU','WBY','Willoughby','Willoughby','NS'),('AU','WCL','Wacol','Wacol','QL'),('AU','WDB','Wallendbeen','Wallendbeen','NS'),('AU','WDG','Wondalga','Wondalga','NS'),('AU','WDI','Wondai','Wondai','QL'),('AU','WEH','Wetherhill','Wetherhill','NS'),('AU','WEI','Weipa','Weipa','QL'),('AU','WEL','Welshpool','Welshpool','WA'),('AU','WEP','Westernport','Westernport','VI'),('AU','WEW','Wee Waa','Wee Waa','NS'),('AU','WFO','West Footscray','West Footscray','VI'),('AU','WGA','Wagga Wagga','Wagga Wagga','NS'),('AU','WGB','Woolloongabba','Woolloongabba','QL'),('AU','WGE','Walgett','Walgett','NS'),('AU','WGI','Wagin','Wagin','WA'),('AU','WGR','Wangara','Wangara','WA'),('AU','WGT','Wangaratta','Wangaratta','VI'),('AU','WHI','Winston Hills','Winston Hills','NS'),('AU','WHL','Welshpool','Welshpool','VI'),('AU','WIN','Winton','Winton','QL'),('AU','WIO','Wilcannia','Wilcannia','NS'),('AU','WIT','Wittenoom','Wittenoom','WA'),('AU','WKB','Warracknabeal','Warracknabeal','VI'),('AU','WKM','Wyalkatchem','Wyalkatchem','WA'),('AU','WKY','Wakerley','Wakerley','QL'),('AU','WLA','Wallal','Wallal','WA'),('AU','WLC','Walcha','Walcha','NS'),('AU','WLG','Wallangarra','Wallangarra','QL'),('AU','WLI','Williams','Williams','WA'),('AU','WLL','Wollogorang','Wollogorang','QL'),('AU','WLM','Williamtown','Williamtown','NS'),('AU','WLO','Waterloo','Waterloo','NT'),('AU','WLR','Wollongbar','Wollongbar','NS'),('AU','WLS','Wallis','Wallis',''),('AU','WMB','Warrnambool','Warrnambool','VI'),('AU','WME','Mount Keith','Mount Keith','WA'),('AU','WNB','Withnell Bay','Withnell Bay','WA'),('AU','WND','Windarra','Windarra','WA'),('AU','WNN','Winnellie','Winnellie','NT'),('AU','WNR','Windorah','Windorah','QL'),('AU','WNT','Wandoo Terminal','Wandoo Terminal','WA'),('AU','WNY','Wynyard','Wynyard','TS'),('AU','WOD','Wodonga','Wodonga','VI'),('AU','WOG','Woodgreen','Woodgreen','NT'),('AU','WOL','Wollongong','Wollongong','NS'),('AU','WON','Wondoola','Wondoola','QL'),('AU','WOT','Wonthaggi','Wonthaggi','VI'),('AU','WPA','Wetherill Park','Wetherill Park','NS'),('AU','WPK','Wrotham Park','Wrotham Park','QL'),('AU','WPO','Walpole','Walpole','WA'),('AU','WRB','Werribee','Werribee','VI'),('AU','WRW','Warrawagine','Warrawagine','WA'),('AU','WSN','Warners Bay','Warners Bay','NS'),('AU','WSO','Windsor','Windsor','NS'),('AU','WSY','Airlie Beach','Airlie Beach','QL'),('AU','WTO','Whitton','Whitton','NS'),('AU','WUA','Wolumla','Wolumla','NS'),('AU','WUD','Wudinna','Wudinna','SA'),('AU','WUN','Wiluna','Wiluna','WA'),('AU','WVA','Willowdale','Willowdale','NS'),('AU','WWI','Woodie Woodie','Woodie Woodie','WA'),('AU','WWY','West Wyalong','West Wyalong','NS'),('AU','WYA','Whyalla','Whyalla','SA'),('AU','WYD','Wyndham','Wyndham','NS'),('AU','WYL','Wyalong','Wyalong','NS'),('AU','WYN','Wyndham','Wyndham','WA'),('AU','WYO','Wyong','Wyong','NS'),('AU','XCO','Colac','Colac','VI'),('AU','XMC','Mallacoota','Mallacoota','VI'),('AU','XML','Minlaton','Minlaton','SA'),('AU','XMY','Yam Island','Yam Island','QL'),('AU','XTG','Thargomindah','Thargomindah','QL'),('AU','XTO','Taroom','Taroom','QL'),('AU','XTR','Tara','Tara','QL'),('AU','YAM','Yampi','Yampi','WA'),('AU','YAN','Yagoona','Yagoona','NS'),('AU','YAR','Yarra Glen','Yarra Glen','VI'),('AU','YBA','Yamba','Yamba','NS'),('AU','YDA','Yenda','Yenda','NS'),('AU','YGU','Yallingup','Yallingup','WA'),('AU','YLG','Yalgoo','Yalgoo','WA'),('AU','YLO','Yarloop','Yarloop','WA'),('AU','YOR','York','York','WA'),('AU','YRG','Yering','Yering','VI'),('AU','YRV','Yarraville/Melbourne','Yarraville/Melbourne','VI'),('AU','YSS','Yass','Yass','NS'),('AU','YUE','Yuendumu','Yuendumu','NT'),('AU','YWO','Yarrawonga','Yarrawonga','NS'),('AU','ZBO','Bowen','Bowen','QL'),('AU','ZGL','South Galway','South Galway','QL'),('AU','ZVG','Springvale','Springvale','WA'),('AW','','','',''),('AW','AUA','Aruba','Aruba',''),('AW','BAR','Barcadera','Barcadera',''),('AW','BUS','Bushiribana','Bushiribana',''),('AW','DEU','Druif','Druif',''),('AW','ORJ','Oranjestad','Oranjestad',''),('AW','SNL','Sint Nicolaas','Sint Nicolaas',''),('AZ','','','',''),('AZ','BAK','Baku','Baku',''),('AZ','DJU','Djulfa','Djulfa',''),('AZ','KHA','Khanlar','Khanlar',''),('AZ','KVD','Gyandzha','Gyandzha',''),('AZ','MGC','Mingechaur','Mingechaur',''),('AZ','NAJ','Naxcivan','Naxcivan',''),('AZ','SUM','Sumgait','Sumgait',''),('BA','','','',''),('BA','BBR','Bosanski Brod (Srpski Brod)','Bosanski Brod (Srpski Brod)',''),('BA','BHC','Bihac','Bihac',''),('BA','BJA','Bijeljina','Bijeljina',''),('BA','BKO','Brcko','Brcko',''),('BA','BNX','Banja Luka','Banja Luka',''),('BA','BZJ','Blazuj, Sarajevo','Blazuj, Sarajevo',''),('BA','DBJ','Doboj','Doboj',''),('BA','DOV','Donji Vakuf','Donji Vakuf',''),('BA','DVA','Derventa','Derventa',''),('BA','GDA','Gradiska','Gradiska',''),('BA','HRE','Hresa','Hresa',''),('BA','KJC','Konjic','Konjic',''),('BA','KJK','Kiseljak','Kiseljak',''),('BA','KLJ','Kljuc','Kljuc',''),('BA','KSA','Kalesija','Kalesija',''),('BA','KSO','Kresevo','Kresevo',''),('BA','LBS','Ljubuski','Ljubuski',''),('BA','LTI','Laktasi','Laktasi',''),('BA','LVO','Livno','Livno',''),('BA','MAG','Maglaj','Maglaj',''),('BA','MGE','Medugorje','Medugorje',''),('BA','MGR','Mrkonji Grad','Mrkonji Grad',''),('BA','MOD','Modrica','Modrica',''),('BA','MZI','Matuzici','Matuzici',''),('BA','OMO','Mostar','Mostar',''),('BA','PDR','Prijedor','Prijedor',''),('BA','PER','Perduhovo Selo','Perduhovo Selo',''),('BA','PJR','Prnjavor','Prnjavor',''),('BA','PSE','Posusje','Posusje',''),('BA','RAJ','Rajlovac','Rajlovac',''),('BA','SIB','Siroki Brijeg','Siroki Brijeg',''),('BA','SIC','Srebrenica','Srebrenica',''),('BA','SJA','Stijena','Stijena',''),('BA','SJJ','Sarajevo','Sarajevo',''),('BA','SKV','Sekovici','Sekovici',''),('BA','SOR','Srpsko Orasje','Srpsko Orasje',''),('BA','TIH','Tihaljina','Tihaljina',''),('BA','TLC','Teslic','Teslic',''),('BA','TSJ','Tesanj','Tesanj',''),('BA','TZL','Tuzla','Tuzla',''),('BA','VIS','Visoko','Visoko',''),('BA','VIT','Vitez','Vitez',''),('BA','ZAV','Zavidovici','Zavidovici',''),('BA','ZCA','Zenica','Zenica',''),('BA','ZEP','Zepce','Zepce',''),('BA','ZNK','Zvornik','Zvornik',''),('BB','','','',''),('BB','BGI','Bridgetown','Bridgetown',''),('BD','','','',''),('BD','AKH','Akhaura','Akhaura',''),('BD','BZL','Barisal','Barisal',''),('BD','CGP','Chittagong','Chittagong',''),('BD','CHL','Chalna','Chalna',''),('BD','CLA','Comilla','Comilla',''),('BD','CXB','Cox\'s Bazar','Cox\'s Bazar',''),('BD','DAC','Dhaka','Dhaka',''),('BD','IRD','Ishurdi','Ishurdi',''),('BD','JSR','Jessore','Jessore',''),('BD','KAM','Kamalapur/Dhaka','Kamalapur/Dhaka',''),('BD','KHL','Khulna','Khulna',''),('BD','LAK','Laksham','Laksham',''),('BD','MGL','Mongla','Mongla',''),('BD','MON','Monella','Monella',''),('BD','MYM','Mymensingh','Mymensingh',''),('BD','NAR','Narayanganj','Narayanganj',''),('BD','PAN','Pabna','Pabna',''),('BD','PAR','Parbatipur','Parbatipur',''),('BD','RAU','Rangpur','Rangpur',''),('BD','RJH','Rajshahi','Rajshahi',''),('BD','SAJ','Sirajganj','Sirajganj',''),('BD','SDW','Sandwip','Sandwip',''),('BD','SPD','Saidpur','Saidpur',''),('BD','TKR','Thakurgaon','Thakurgaon',''),('BD','ZHM','Shamshernagar','Shamshernagar',''),('BD','ZYL','Sylhet','Sylhet',''),('BE','','','',''),('BE','AAB','Aalst','Aalst','VOV'),('BE','AAL','Aalter','Aalter','VOV'),('BE','AAR','Aartselaar','Aartselaar','VAN'),('BE','AAS','Aarschot','Aarschot','VBR'),('BE','AAT','Athus','Athus','WLX'),('BE','ABC','Bernissart','Bernissart','WHT'),('BE','ABE','Arbre','Arbre','WHT'),('BE','ABK','Albertkanaal ports','Albertkanaal ports',''),('BE','ABO','Averbode','Averbode','VBR'),('BE','ABR','Assebroek','Assebroek','VWV'),('BE','ABY','Ambly','Ambly','WLX'),('BE','ACE','Achet','Achet','WNA'),('BE','ACH','Achouffe','Achouffe','WLX'),('BE','ACS','Archennes','Archennes','WBR'),('BE','ADI','Audregnies','Audregnies','WHT'),('BE','ADK','Adinkerke','Adinkerke','VWV'),('BE','ADO','Ardooie','Ardooie','VWV'),('BE','ADU','Anderlues','Anderlues','WHT'),('BE','AEJ','Arendonk','Arendonk','VAN'),('BE','AEL','Alleur','Alleur','WLG'),('BE','AES','Asse','Asse','VBR'),('BE','AFF','Affligem','Affligem','VBR'),('BE','AFN','Afsnee','Afsnee','VOV'),('BE','AGE','Adegem','Adegem','VOV'),('BE','AGI','Agimont','Agimont','WNA'),('BE','AGT','Argenteau','Argenteau','WLG'),('BE','AHE','Antheit','Antheit','WLG'),('BE','AHO','Attenhoven','Attenhoven','VBR'),('BE','AIS','Anthisnes','Anthisnes','WLG'),('BE','AKN','Alken','Alken','VLI'),('BE','ALB','Aalbeke','Aalbeke','VWV'),('BE','ALI','Anlier','Anlier','WLX'),('BE','AME','Ambleve','Ambleve','WLG'),('BE','AMO','Andrimont','Andrimont','WLG'),('BE','AMY','Amay','Amay','WLG'),('BE','ANB','Angleur','Angleur','WLG'),('BE','AND','Andenne','Andenne','WNA'),('BE','ANE','Assenede','Assenede','VOV'),('BE','ANH','Anhee','Anhee','WNA'),('BE','ANL','Anderlecht/Brussel (Bruxelles)','Anderlecht/Brussel (Bruxelles)','BRU'),('BE','ANR','Antwerpen','Antwerpen','VAN'),('BE','ANS','Ans','Ans','WLG'),('BE','APE','Aiseau-Presles','Aiseau-Presles','WHT'),('BE','APL','Appels','Appels','VOV'),('BE','APS','Ampsin','Ampsin','WLG'),('BE','APT','Appelterre-Eichem','Appelterre-Eichem','VOV'),('BE','AQE','Arquennes','Arquennes','WHT'),('BE','ARE','Attre','Attre','WHT'),('BE','ARL','Arlon','Arlon','WLX'),('BE','ARO','Attenrode','Attenrode','VBR'),('BE','ARS','Aarsele','Aarsele','VWV'),('BE','ART','Aartrijke','Aartrijke','VWV'),('BE','ASB','Alsemberg','Alsemberg','VBR'),('BE','ASE','Aspelare','Aspelare','VOV'),('BE','ASN','Assesse','Assesse','WNA'),('BE','ASP','Asper','Asper','VOV'),('BE','ASR','Anseremme','Anseremme','WNA'),('BE','ASS','As','As','VLI'),('BE','AST','Astene','Astene','VOV'),('BE','ATE','Attert','Attert','WLX'),('BE','ATH','Ath','Ath','WHT'),('BE','ATO','Antoing','Antoing','WHT'),('BE','AUB','Aubechies','Aubechies','WHT'),('BE','AUG','Aubange','Aubange','WLX'),('BE','AUL','Aubel','Aubel','WLG'),('BE','AVE','Annevoie','Annevoie','WNA'),('BE','AVL','Avelgem','Avelgem','VWV'),('BE','AVR','Alveringem','Alveringem','VWV'),('BE','AVS','Auvelais','Auvelais','WNA'),('BE','AWS','Awans','Awans','WLG'),('BE','AYW','Aywaille','Aywaille','WLG'),('BE','AZM','Anzegem','Anzegem','VWV'),('BE','BAK','Brakel','Brakel','VOV'),('BE','BAL','Baal','Baal','VBR'),('BE','BAN','Ben-Ahin','Ben-Ahin','WLG'),('BE','BAR','Berlaar','Berlaar','VAN'),('BE','BAS','Baulers','Baulers','WBR'),('BE','BAT','Battel','Battel','VAN'),('BE','BAV','Bavikhove','Bavikhove','VWV'),('BE','BAX','Baileux','Baileux','WHT'),('BE','BAY','Barry','Barry','WHT'),('BE','BAZ','Bazel','Bazel','VOV'),('BE','BBG','Blankenberge','Blankenberge','VWV'),('BE','BBX','Basse-Bodeux','Basse-Bodeux','WLG'),('BE','BBY','Bombaye','Bombaye','WLG'),('BE','BCE','Biercee','Biercee','WHT'),('BE','BCI','Binche','Binche','WHT'),('BE','BCM','Berchem','Berchem','VOV'),('BE','BCN','Barchon','Barchon','WLG'),('BE','BCO','Braine-le-Comte','Braine-le-Comte','WHT'),('BE','BCR','Bellecourt','Bellecourt','WHT'),('BE','BCS','Beclers','Beclers','WHT'),('BE','BCT','Boechout','Boechout','VAN'),('BE','BDE','Baardegem','Baardegem','VOV'),('BE','BDH','Bois-d\'Haine','Bois-d\'Haine','WHT'),('BE','BDI','Blandain','Blandain','WHT'),('BE','BDU','Baudour','Baudour','WHT'),('BE','BEA','Beaumont','Beaumont','WHT'),('BE','BEE','Beersel','Beersel','VBR'),('BE','BEH','Beho','Beho','WLX'),('BE','BEI','Beigem','Beigem','VBR'),('BE','BEL','Beveren Leie','Beveren Leie','VWV'),('BE','BEM','Bellem','Bellem','VOV'),('BE','BEN','Bende','Bende','WLX'),('BE','BER','Beerse','Beerse','VAN'),('BE','BES','Basecles','Basecles','WHT'),('BE','BET','Bettincourt','Bettincourt','WLG'),('BE','BEV','Beveren','Beveren','VWV'),('BE','BEZ','Beez','Beez','WNA'),('BE','BFE','Braffe','Braffe','WHT'),('BE','BFY','Beaufays','Beaufays','WLG'),('BE','BGA','Belgrade','Belgrade','WNA'),('BE','BGE','Bellegem','Bellegem','VWV'),('BE','BGH','Butgenbach','Butgenbach','WLG'),('BE','BGI','Baugnies','Baugnies','WHT'),('BE','BGK','Balgerhoek','Balgerhoek','VOV'),('BE','BGN','Briegden','Briegden','VLI'),('BE','BGS','Brugge (Bruges)','Brugge (Bruges)','VWV'),('BE','BGU','Burg-Reuland','Burg-Reuland','WLG'),('BE','BGY','Begijnendijk','Begijnendijk','VBR'),('BE','BHA','Bienne-lez-Happart','Bienne-lez-Happart','WHT'),('BE','BHE','Boekhoute','Boekhoute','VOV'),('BE','BHH','Bovekerke','Bovekerke','VWV'),('BE','BHO','Baarle-Hertog','Baarle-Hertog','VAN'),('BE','BHR','Bleharies','Bleharies','WHT'),('BE','BHU','Buggenhout','Buggenhout','VOV'),('BE','BIE','Bierges','Bierges','WBR'),('BE','BIM','Blaimont','Blaimont','WNA'),('BE','BIR','Bredene','Bredene','VWV'),('BE','BIV','Bievre','Bievre','WNA'),('BE','BIZ','Beveren-aan-den-Ijzer','Beveren-aan-den-Ijzer','VWV'),('BE','BKE','Bierbeek','Bierbeek','VBR'),('BE','BKM','Binkom','Binkom','VBR'),('BE','BKO','Bekkevoort','Bekkevoort','VBR'),('BE','BLA','Braine-l\'Alleud','Braine-l\'Alleud','WBR'),('BE','BLC','Braine-le-Chateau','Braine-le-Chateau','WBR'),('BE','BLD','Blanden','Blanden','VBR'),('BE','BLE','Balen','Balen','VAN'),('BE','BLI','Bellingen','Bellingen','VBR'),('BE','BLN','Baelen','Baelen','WLG'),('BE','BLO','Beloeil','Beloeil','WHT'),('BE','BLS','Bourlers','Bourlers','WHT'),('BE','BLT','Blaton','Blaton','WHT'),('BE','BLX','Borlon','Borlon','WLX'),('BE','BLZ','Bilzen','Bilzen','VLI'),('BE','BMA','Bomal','Bomal','WLX'),('BE','BMB','Boortmeerbeek','Boortmeerbeek','VBR'),('BE','BMI','Brasmenil','Brasmenil','WHT'),('BE','BNA','Brunehault','Brunehault','WHT'),('BE','BND','Bande','Bande','WLX'),('BE','BNI','Bonheiden','Bonheiden','VAN'),('BE','BNO','Boninne','Boninne','WNA'),('BE','BNU','Berneau','Berneau','WLG'),('BE','BNY','Blegny','Blegny','WLG'),('BE','BOA','Bas-Oha','Bas-Oha','WLG'),('BE','BOC','Bocholt','Bocholt','VLI'),('BE','BOG','Borgloon','Borgloon','VLI'),('BE','BOH','Bohan','Bohan','WNA'),('BE','BOL','Bolland','Bolland','WLG'),('BE','BOM','Boom','Boom','VAN'),('BE','BON','Bornem','Bornem','VAN'),('BE','BOO','Boorsem','Boorsem','VLI'),('BE','BOR','Borgerhout','Borgerhout','VAN'),('BE','BOS','Booischot','Booischot','VAN'),('BE','BOT','Boussoit','Boussoit','WHT'),('BE','BOU','Bousval','Bousval','WBR'),('BE','BOV','Les-Bons-Villers','Les-Bons-Villers','WHT'),('BE','BPC','Berchem','Berchem','VAN'),('BE','BQY','Blicquy','Blicquy','WHT'),('BE','BRA','Brasschaat','Brasschaat','VAN'),('BE','BRC','Brecht','Brecht','VAN'),('BE','BRD','Burdinne','Burdinne','WLG'),('BE','BRE','Bree','Bree','VLI'),('BE','BRG','Brugelette','Brugelette','WHT'),('BE','BRI','Bossiere','Bossiere','WNA'),('BE','BRK','Borsbeke','Borsbeke','VOV'),('BE','BRL','Berlare','Berlare','VOV'),('BE','BRM','Beernem','Beernem','VWV'),('BE','BRN','Breendonk','Breendonk','VAN'),('BE','BRO','Borlo','Borlo','VLI'),('BE','BRS','Braives','Braives','WLG'),('BE','BRT','Berendrecht','Berendrecht','VAN'),('BE','BRU','Bruxelles (Brussel)','Bruxelles (Brussel)','BRU'),('BE','BRY','Bruyelle','Bruyelle','WHT'),('BE','BSA','Sint-Agatha-Berchem (Berchem-Sainte-Agathe)','Sint-Agatha-Berchem (Berchem-Sainte-Agathe)','BRU'),('BE','BSB','Borsbeek','Borsbeek','VAN'),('BE','BSE','Bissegem','Bissegem','VWV'),('BE','BSG','Bastogne','Bastogne','WLX'),('BE','BSI','Labuissiere','Labuissiere','WHT'),('BE','BSL','Belsele','Belsele','VOV'),('BE','BSN','Bilstain','Bilstain','WLG'),('BE','BSO','Bon-Secours','Bon-Secours','WHT'),('BE','BSR','Baasrode','Baasrode','VOV'),('BE','BSS','Boussu','Boussu','WHT'),('BE','BST','Bierset','Bierset','WLG'),('BE','BSU','Bossuit','Bossuit','VWV'),('BE','BSV','Bassevelde','Bassevelde','VOV'),('BE','BSX','Bressoux','Bressoux','WLG'),('BE','BTC','Battice','Battice','WLG'),('BE','BTE','Beert','Beert','VBR'),('BE','BTK','Borchtlombeek','Borchtlombeek','VBR'),('BE','BTM','Bertem','Bertem','VBR'),('BE','BTO','Bertogne','Bertogne','WLX'),('BE','BTS','Bassenge (Bitsingen)','Bassenge (Bitsingen)','WLG'),('BE','BTX','Bertrix','Bertrix','WLX'),('BE','BTY','Bothey','Bothey','WNA'),('BE','BUD','Burcht','Burcht','VAN'),('BE','BUG','Bouge','Bouge','WNA'),('BE','BUL','Bullange','Bullange','WLG'),('BE','BUM','Boutersem','Boutersem','VBR'),('BE','BUN','Biesme-sous-Thuin','Biesme-sous-Thuin','WHT'),('BE','BUO','Bouillon','Bouillon','WLX'),('BE','BUR','Beauraing','Beauraing','WNA'),('BE','BUS','Buissenal','Buissenal','WHT'),('BE','BUV','Buvingen','Buvingen','VLI'),('BE','BUY','Bury','Bury','WHT'),('BE','BUZ','Buizingen','Buizingen','VBR'),('BE','BVA','Bornival','Bornival','WBR'),('BE','BVC','Beauvechain','Beauvechain','WBR'),('BE','BVD','Beervelde','Beervelde','VOV'),('BE','BVE','Bever','Bever','VBR'),('BE','BVG','Bavegem','Bavegem','VOV'),('BE','BVI','Bouvignies','Bouvignies','WHT'),('BE','BVM','Bouvignes-sur-Meuse','Bouvignes-sur-Meuse','WNA'),('BE','BVO','Beverlo','Beverlo','VLI'),('BE','BVS','Bovesse','Bovesse','WNA'),('BE','BVU','Buvrinnes','Buvrinnes','WHT'),('BE','BVX','Bellevaux','Bellevaux','WLX'),('BE','BVY','Bovigny','Bovigny','WLX'),('BE','BWA','Bas-Warneton','Bas-Warneton','WHT'),('BE','BWE','Bouwel','Bouwel','VAN'),('BE','BWN','Warneton','Warneton','WHT'),('BE','BWS','Beveren-Waas','Beveren-Waas','VOV'),('BE','BWZ','Beauwelz','Beauwelz','WHT'),('BE','BYE','Beyne-Heusay','Beyne-Heusay','WLG'),('BE','BYR','Brye','Brye','WHT'),('BE','BZE','Berzee','Berzee','WNA'),('BE','BZG','Boezinge','Boezinge','VWV'),('BE','BZI','Bizet','Bizet','WHT'),('BE','BZO','Buzenol','Buzenol','WLX'),('BE','CAD','Cerfontaine','Cerfontaine','WNA'),('BE','CAL','Callenelle','Callenelle','WHT'),('BE','CAR','Chastre','Chastre','WBR'),('BE','CAS','Casteau','Casteau','WHT'),('BE','CAX','Charneux','Charneux','WLG'),('BE','CBF','Chiny','Chiny','WLX'),('BE','CBI','Corbion','Corbion','WLX'),('BE','CBQ','Clabecq','Clabecq','WBR'),('BE','CCA','Corroy-le-Chateau','Corroy-le-Chateau','WNA'),('BE','CCS','Courcelles','Courcelles','WHT'),('BE','CEL','Celles','Celles','WNA'),('BE','CET','Court-Saint-Etienne','Court-Saint-Etienne','WBR'),('BE','CEX','Cerexhe-Heuseux','Cerexhe-Heuseux','WLG'),('BE','CFA','Colfontaine','Colfontaine','WHT'),('BE','CFO','Chaudfontaine','Chaudfontaine','WLG'),('BE','CGE','Cognelee','Cognelee','WNA'),('BE','CGX','Chaumont-Gistoux','Chaumont-Gistoux','WBR'),('BE','CHA','Chatelet','Chatelet','WHT'),('BE','CHE','Chenee','Chenee','WLG'),('BE','CHI','Chievres','Chievres','WHT'),('BE','CHM','Chimay','Chimay','WHT'),('BE','CHO','Chapelle-lez-Herlaimont','Chapelle-lez-Herlaimont','WHT'),('BE','CLA','Clavier','Clavier','WLG'),('BE','CLE','Celles','Celles','WHT'),('BE','CLM','Clermont','Clermont','WNA'),('BE','CLN','Calonne','Calonne','WHT'),('BE','CLO','Chapelle-a-Oie','Chapelle-a-Oie','WHT'),('BE','CLY','Chanly','Chanly','WLX'),('BE','CME','Chantemelle','Chantemelle','WLX'),('BE','CMS','Comines','Comines','WAL'),('BE','CNO','Chaussee-Notre-Dame-Louvignies','Chaussee-Notre-Dame-Louvignies','WHT'),('BE','CNR','Carnieres','Carnieres','WHT'),('BE','CNX','Chaineux','Chaineux','WLG'),('BE','CNY','Ciney','Ciney','WNA'),('BE','COH','Couthuin','Couthuin','WLG'),('BE','COM','Comines','Comines','WHT'),('BE','COU','Couillet','Couillet','WHT'),('BE','CPE','Chassepierre','Chassepierre','WLX'),('BE','CPI','Champion','Champion','WNA'),('BE','CPN','Comblain-au-Pont','Comblain-au-Pont','WLG'),('BE','CPO','Champlon','Champlon','WLX'),('BE','CPY','Ciply','Ciply','WHT'),('BE','CQR','Chokier','Chokier','WLG'),('BE','CRA','Cheratte','Cheratte','WLG'),('BE','CRB','Corbais','Corbais','WBR'),('BE','CRE','Courriere','Courriere','WNA'),('BE','CRI','Cherain','Cherain','WLX'),('BE','CRL','Charleroi','Charleroi','WHT'),('BE','CRO','Crombach','Crombach','WLG'),('BE','CRQ','Chercq','Chercq','WHT'),('BE','CRU','Crupet','Crupet','WNA'),('BE','CRY','Ceroux-Mousty','Ceroux-Mousty','WBR'),('BE','CSI','Crisnee','Crisnee','WLG'),('BE','CTA','Chertal','Chertal','WLG'),('BE','CTL','Chatelineau','Chatelineau','WHT'),('BE','CUS','Cuesmes','Cuesmes','WHT'),('BE','CUT','Custinne','Custinne','WNA'),('BE','CUV','Couvin','Couvin','WNA'),('BE','CWA','Chapelle-a-Wattines','Chapelle-a-Wattines','WHT'),('BE','DAL','Dalhem','Dalhem','WLG'),('BE','DAV','Dave','Dave','WNA'),('BE','DAX','Daussoulx','Daussoulx','WNA'),('BE','DBK','Dilbeek','Dilbeek','VBR'),('BE','DCE','Donceel','Donceel','WLG'),('BE','DDR','Dendermonde','Dendermonde','VOV'),('BE','DEG','Deurne','Deurne','VAN'),('BE','DEK','De Klinge','De Klinge','VOV'),('BE','DEL','Doel','Doel','VOV'),('BE','DES','Destelbergen','Destelbergen','VOV'),('BE','DEU','Deurle','Deurle','VOV'),('BE','DEZ','Deinze','Deinze','VOV'),('BE','DGB','Diegem','Diegem','VBR'),('BE','DGN','Drongen','Drongen','VOV'),('BE','DGU','Dergneau','Dergneau','WHT'),('BE','DGX','Dadizele','Dadizele','VWV'),('BE','DHA','De Haan','De Haan','VWV'),('BE','DIA','Dinant','Dinant','WNA'),('BE','DIE','Diest','Diest','VBR'),('BE','DIK','Diksmuide','Diksmuide','VWV'),('BE','DIO','Dion','Dion','WNA'),('BE','DIS','Dison','Dison','WLG'),('BE','DJK','Deerlijk','Deerlijk','VWV'),('BE','DKN','Daknam','Daknam','VOV'),('BE','DLS','Dilsen','Dilsen','VLI'),('BE','DMM','Damme','Damme','VWV'),('BE','DNB','Denderbelle','Denderbelle','VOV'),('BE','DOE','Doornzele','Doornzele','VOV'),('BE','DOH','Dohan','Dohan','WLX'),('BE','DOI','Doische','Doische','WNA'),('BE','DON','Donk','Donk','VLI'),('BE','DOU','Dour','Dour','WHT'),('BE','DPA','De Panne','De Panne','VWV'),('BE','DPE','De Pinte','De Pinte','VOV'),('BE','DPK','Diepenbeek','Diepenbeek','VLI'),('BE','DPY','Dampremy','Dampremy','WHT'),('BE','DRA','Dranouter','Dranouter','VWV'),('BE','DRB','Drogenbos','Drogenbos','VBR'),('BE','DRI','Darion','Darion','WLG'),('BE','DRW','Denderleeuw','Denderleeuw','VOV'),('BE','DSE','Dessel','Dessel','VAN'),('BE','DSI','Donstiennes','Donstiennes','WHT'),('BE','DSL','Desselgem','Desselgem','VWV'),('BE','DSO','Dilsen-Stokkem','Dilsen-Stokkem','VLI'),('BE','DTE','Dentergem','Dentergem','VWV'),('BE','DTO','Desteldonk','Desteldonk','VOV'),('BE','DTS','Dottignies','Dottignies','WHT'),('BE','DUD','Dudzele','Dudzele','VWV'),('BE','DUF','Duffel','Duffel','VAN'),('BE','DUR','Duras','Duras','VLI'),('BE','DUY','Durbuy','Durbuy','WLX'),('BE','DVI','Daverdisse','Daverdisse','WLX'),('BE','DWP','Dworp','Dworp','VBR'),('BE','DXN','Deux-Acren','Deux-Acren','WHT'),('BE','EAM','Ename','Ename','VOV'),('BE','EBI','Ermeton-sur-Biert','Ermeton-sur-Biert','WNA'),('BE','EBM','Emblem','Emblem','VAN'),('BE','EBR','Everberg','Everberg','VBR'),('BE','EBU','Embourg','Embourg','WLG'),('BE','EBZ','Eigenbilzen','Eigenbilzen','VLI'),('BE','ECH','Mechelen','Mechelen','VAN'),('BE','EEE','Elversele','Elversele','VOV'),('BE','EEK','Eeklo','Eeklo','VOV'),('BE','EEZ','Erezee','Erezee','WLX'),('BE','EFS','Escanaffles','Escanaffles','WHT'),('BE','EGI','Enghien','Enghien','WHT'),('BE','EGM','Edegem','Edegem','VAN'),('BE','EHT','Eindhout','Eindhout','VAN'),('BE','EIN','Eine','Eine','VOV'),('BE','EKE','Ekeren','Ekeren','VAN'),('BE','EKL','Eksel','Eksel','VLI'),('BE','EKS','Eksaarde','Eksaarde','VOV'),('BE','ELA','Ecaussinnes-Lalaing','Ecaussinnes-Lalaing','WHT'),('BE','ELI','Elingen','Elingen','VBR'),('BE','ELS','Melsen','Melsen','VOV'),('BE','EMP','Estaimpuis','Estaimpuis','WHT'),('BE','ENG','Engis','Engis','WLG'),('BE','ENU','Erneuville','Erneuville','WLX'),('BE','EPC','Esplechin','Esplechin','WHT'),('BE','EPG','Eppegem','Eppegem','VBR'),('BE','EPI','Emptinne','Emptinne','WNA'),('BE','EPN','Erpion','Erpion','WHT'),('BE','EPO','Epinois','Epinois','WHT'),('BE','EPT','Erpent','Erpent','WNA'),('BE','EQE','Eke','Eke','VOV'),('BE','EQM','Esquelmes','Esquelmes','WHT'),('BE','ERE','Ertvelde','Ertvelde','VOV'),('BE','ERM','Erembodegem','Erembodegem','VOV'),('BE','ERP','Erpe-Mere','Erpe-Mere','VOV'),('BE','ESA','Ellignies-Sainte-Anne','Ellignies-Sainte-Anne','WHT'),('BE','ESB','Elsenborn','Elsenborn','WLG'),('BE','ESD','Eisden','Eisden','VLI'),('BE','ESE','Ixelles (Elsene)/Brussel (Bruxelles)','Ixelles (Elsene)/Brussel (Bruxelles)','BRU'),('BE','ESI','Ecaussinnes-d\'Enghien','Ecaussinnes-d\'Enghien','WHT'),('BE','ESK','Erps-Kwerps','Erps-Kwerps','VBR'),('BE','ESS','Essen','Essen','VAN'),('BE','ESX','Esneux','Esneux','WLG'),('BE','ETE','Etterbeek','Etterbeek','BRU'),('BE','ETI','Estinnes','Estinnes','WHT'),('BE','ETL','Etalle','Etalle','WLX'),('BE','EUP','Eupen','Eupen','WLG'),('BE','EVE','Elverdinge','Elverdinge','VWV'),('BE','EVG','Evegnee-Tignee','Evegnee-Tignee','WLG'),('BE','EVM','Evergem','Evergem','VOV'),('BE','EVR','Evere/Brussel (Bruxelles)','Evere/Brussel (Bruxelles)','BRU'),('BE','EWI','Elewijt','Elewijt','VBR'),('BE','EYT','Eynatten','Eynatten','WLG'),('BE','EZE','Eghezee','Eghezee','WNA'),('BE','EZS','Ellezelles','Ellezelles','WHT'),('BE','FAL','Falaen','Falaen','WNA'),('BE','FAV','Frasnes-lez-Anvaing','Frasnes-lez-Anvaing','WHT'),('BE','FBQ','Flobecq','Flobecq','WHT'),('BE','FBU','Frasnes-lez-Buissenal','Frasnes-lez-Buissenal','WHT'),('BE','FCA','Focant','Focant','WNA'),('BE','FCS','Farciennes','Farciennes','WHT'),('BE','FDA','Froid-Chapelle','Froid-Chapelle','WHT'),('BE','FEQ','Fontaine-l\'Eveque','Fontaine-l\'Eveque','WHT'),('BE','FER','Feneur','Feneur','WLG'),('BE','FES','Frameries','Frameries','WHT'),('BE','FEY','Feluy','Feluy','WHT'),('BE','FFO','Froidfontaine','Froidfontaine','WNA'),('BE','FFX','Floriffoux','Floriffoux','WNA'),('BE','FHC','Fexhe-le-Haut-Clocher','Fexhe-le-Haut-Clocher','WLG'),('BE','FIL','Filot','Filot','WLG'),('BE','FIM','Froidmont','Froidmont','WHT'),('BE','FIS','Forrieres','Forrieres','WLX'),('BE','FLE','Fleurus','Fleurus','WHT'),('BE','FLH','Flemalle-Haute','Flemalle-Haute','WLG'),('BE','FLN','Flone','Flone','WLG'),('BE','FLO','Floreffe','Floreffe','WNA'),('BE','FLR','Florennes','Florennes','WNA'),('BE','FLU','Flenu','Flenu','WHT'),('BE','FMA','Flemalle','Flemalle','WLG'),('BE','FME','Faimes','Faimes','WLG'),('BE','FMI','Flamierge','Flamierge','WLX'),('BE','FMO','Framont','Framont','WLX'),('BE','FMR','Forchies-la-Marche','Forchies-la-Marche','WHT'),('BE','FNO','Fernelmont','Fernelmont','WNA'),('BE','FNR','Franiere','Franiere','WNA'),('BE','FNX','Furnaux','Furnaux','WNA'),('BE','FNY','Fontenoy','Fontenoy','WHT'),('BE','FOG','Forges','Forges','WHT'),('BE','FOR','Floree','Floree','WNA'),('BE','FPI','Forge-Philippe','Forge-Philippe','WHT'),('BE','FRC','Francorchamps','Francorchamps','WLG'),('BE','FRE','Ferrieres','Ferrieres','WLG'),('BE','FRI','Florenville','Florenville','WLX'),('BE','FRM','Fortem','Fortem','VWV'),('BE','FRO','Fleron','Fleron','WLG'),('BE','FSV','Fosses-la-Ville','Fosses-la-Ville','WNA'),('BE','FUX','Familleureux','Familleureux','WHT'),('BE','FVI','Fauvillers','Fauvillers','WLX'),('BE','FVT','Fontaine-Valmont','Fontaine-Valmont','WHT'),('BE','FWI','Flawinne','Flawinne','WNA'),('BE','FXI','Fexhe-Slins','Fexhe-Slins','WLG'),('BE','FYD','Foy-Notre-Dame','Foy-Notre-Dame','WNA'),('BE','FYE','Froyennes','Froyennes','WHT'),('BE','FYS','Fays-les-Veneurs','Fays-les-Veneurs','WLX'),('BE','GAG','Gages','Gages','WHT'),('BE','GAX','Gallaix','Gallaix','WHT'),('BE','GBA','Glabais','Glabais','WBR'),('BE','GBB','Grobbendonk','Grobbendonk','VAN'),('BE','GBE','Geetbets','Geetbets','VBR'),('BE','GBG','Grote-Brogel','Grote-Brogel','VLI'),('BE','GBH','Genenbos','Genenbos','VLI'),('BE','GBJ','Groot-Bijgaarden','Groot-Bijgaarden','VBR'),('BE','GBK','Glabbeek','Glabbeek','VBR'),('BE','GBQ','Gibecq','Gibecq','WHT'),('BE','GBU','Gentbrugge','Gentbrugge','VOV'),('BE','GDE','Godsheide','Godsheide','VLI'),('BE','GDI','Grandglise','Grandglise','WHT'),('BE','GDN','Godinne','Godinne','WNA'),('BE','GDO','Goe','Goe','WLG'),('BE','GDU','Grez-Doiceau','Grez-Doiceau','WBR'),('BE','GEA','Geraardsbergen','Geraardsbergen','VOV'),('BE','GED','Gedinne','Gedinne','WNA'),('BE','GEE','Geer','Geer','WLG'),('BE','GEL','Geel','Geel','VAN'),('BE','GEM','Gembloux','Gembloux','WNA'),('BE','GEV','Genval','Genval','WBR'),('BE','GGI','Ghislenghien','Ghislenghien','WHT'),('BE','GGM','Grembergen','Grembergen','VOV'),('BE','GGO','Guigoven','Guigoven','VLI'),('BE','GHE','Grace-Hollogne','Grace-Hollogne','WLG'),('BE','GHI','St Ghislain','St Ghislain','WHT'),('BE','GHL','Ghlin','Ghlin','WHT'),('BE','GHO','Ganshoren','Ganshoren','BRU'),('BE','GHX','Grand-Halleux','Grand-Halleux','WLX'),('BE','GHY','Ghoy','Ghoy','WHT'),('BE','GIS','Gistel','Gistel','VWV'),('BE','GIT','Gits','Gits','VWV'),('BE','GKO','Gijverinkhove','Gijverinkhove','VWV'),('BE','GLA','La Glanerie','La Glanerie','WHT'),('BE','GLE','Grand-Leez','Grand-Leez','WNA'),('BE','GLK','Gellik','Gellik','VLI'),('BE','GLO','Gingelom','Gingelom','VLI'),('BE','GLY','Gilly','Gilly','WHT'),('BE','GMA','Galmaarden','Galmaarden','VBR'),('BE','GME','Grimminge','Grimminge','VOV'),('BE','GMI','Gemmenich','Gemmenich','WLG'),('BE','GNA','Genappe','Genappe','WBR'),('BE','GNE','Gent (Ghent)','Gent (Ghent)','VOV'),('BE','GNK','Genk','Genk','VLI'),('BE','GOK','Gooik','Gooik','VBR'),('BE','GON','Goesnes','Goesnes','WNA'),('BE','GOS','Gosselies','Gosselies','WHT'),('BE','GPI','Gerpinnes','Gerpinnes','WHT'),('BE','GPO','Gouy-lez-Pieton','Gouy-lez-Pieton','WHT'),('BE','GRA','Gaurain-Ramecroix','Gaurain-Ramecroix','WHT'),('BE','GRB','Grimbergen','Grimbergen','VBR'),('BE','GRE','Gorsem','Gorsem','VLI'),('BE','GRI','Gerin','Gerin','WNA'),('BE','GRU','Grune','Grune','WLX'),('BE','GRY','Givry','Givry','WHT'),('BE','GSE','Gelbressee','Gelbressee','WNA'),('BE','GSM','St Georges-Sur-Meuse','St Georges-Sur-Meuse','WLG'),('BE','GTX','Goutroux','Goutroux','WHT'),('BE','GUG','Gullegem','Gullegem','VWV'),('BE','GUR','Gourdinne','Gourdinne','WNA'),('BE','GVD','Geluveld','Geluveld','VWV'),('BE','GVE','Gesves','Gesves','WNA'),('BE','GVI','Grivegnee','Grivegnee','WLG'),('BE','GVO','\'s Gravenvoeren','\'s Gravenvoeren','VLI'),('BE','GVR','Gavere','Gavere','VOV'),('BE','GVY','Gouvy','Gouvy','WLX'),('BE','GWE','\'s-Gravenwezel','\'s-Gravenwezel','VAN'),('BE','GZE','Gozee','Gozee','WHT'),('BE','GZM','Gijzegem','Gijzegem','VOV'),('BE','HAC','Haacht','Haacht','VBR'),('BE','HAD','Haasrode','Haasrode','VBR'),('BE','HAH','Hamont-Achel','Hamont-Achel','VLI'),('BE','HAL','Hamont','Hamont','VLI'),('BE','HAM','Hamsehoeven','Hamsehoeven','VLI'),('BE','HAQ','Hal','Hal','VLI'),('BE','HAR','Haren','Haren','BRU'),('BE','HAT','Haaltert','Haaltert','VOV'),('BE','HBE','Hansbeke','Hansbeke','VOV'),('BE','HBK','Hoelbeek','Hoelbeek','VLI'),('BE','HBN','Hoboken','Hoboken','VAN'),('BE','HBO','Herbeumont','Herbeumont','WLX'),('BE','HBU','Hombourg','Hombourg','WLG'),('BE','HCA','Henri-Chapelle','Henri-Chapelle','WLG'),('BE','HCI','Helecine','Helecine','WBR'),('BE','HCL','Hechtel','Hechtel','VLI'),('BE','HCS','Harchies','Harchies','WHT'),('BE','HCT','Haccourt','Haccourt','WLG'),('BE','HDE','Hoeleden','Hoeleden','VBR'),('BE','HDG','Huldenberg','Huldenberg','VBR'),('BE','HDK','Heindonk','Heindonk','VAN'),('BE','HDO','Houdemont','Houdemont','WLX'),('BE','HDY','Hody','Hody','WLG'),('BE','HEB','Herent','Herent','VBR'),('BE','HEE','Heer','Heer','WNA'),('BE','HEI','Heist','Heist','VWV'),('BE','HEJ','Harelbeke','Harelbeke','VWV'),('BE','HEK','Hechtel-Eksel','Hechtel-Eksel','VLI'),('BE','HEN','Herne','Herne','VBR'),('BE','HEP','Heppen','Heppen','VLI'),('BE','HER','Herentals','Herentals','VAN'),('BE','HES','Herselt','Herselt','VAN'),('BE','HET','Herent','Herent','VLI'),('BE','HEU','Heule','Heule','VWV'),('BE','HEX','Hemiksem','Hemiksem','VAN'),('BE','HEZ','Herzele','Herzele','VOV'),('BE','HFA','Houffalize','Houffalize','WLX'),('BE','HFB','Halle','Halle','VBR'),('BE','HFE','Heffen','Heffen','VAN'),('BE','HGA','Houdeng-Aimeries','Houdeng-Aimeries','WHT'),('BE','HGD','Hoegaarden','Hoegaarden','VBR'),('BE','HGE','Hingene','Hingene','VAN'),('BE','HGG','Houdeng-Goegnies','Houdeng-Goegnies','WHT'),('BE','HGU','Hognoul','Hognoul','WLG'),('BE','HHE','Houthalen-Helchteren','Houthalen-Helchteren','VLI'),('BE','HHG','Hooglede','Hooglede','VWV'),('BE','HHN','Ham-sur-Heure-Nalinnes','Ham-sur-Heure-Nalinnes','WHT'),('BE','HHT','Hulshout','Hulshout','VAN'),('BE','HHU','Houthulst','Houthulst','VWV'),('BE','HIT','Haut-Ittre','Haut-Ittre','WBR'),('BE','HIV','Hives','Hives','WLX'),('BE','HKA','Herk-de-Stad','Herk-de-Stad','VLI'),('BE','HKM','Hekelgem','Hekelgem','VOV'),('BE','HKN','Helkijn','Helkijn','VWV'),('BE','HLA','Halen','Halen','VLI'),('BE','HLE','Hemelveerdegem','Hemelveerdegem','VOV'),('BE','HLN','Habay-la-Neuve','Habay-la-Neuve','WLX'),('BE','HLO','Haillot','Haillot','WNA'),('BE','HLU','Halluin','Halluin','VWV'),('BE','HLX','Halleux','Halleux','WLX'),('BE','HMA','Halma','Halma','WLX'),('BE','HMB','Ham-sur-Sambre','Ham-sur-Sambre','WNA'),('BE','HME','Hamme','Hamme','VOV'),('BE','HMH','Hermalle-sous-Huy','Hermalle-sous-Huy','WLG'),('BE','HMI','Hamois','Hamois','WNA'),('BE','HMM','Hamme','Hamme','VOV'),('BE','HMO','Hamoir','Hamoir','WLG'),('BE','HNA','Handzame','Handzame','VWV'),('BE','HNE','Havinnes','Havinnes','WHT'),('BE','HNI','Herinnes','Herinnes','WHT'),('BE','HNO','Heron','Heron','WLG'),('BE','HNS','Hensies','Hensies','WHT'),('BE','HNU','Hannut','Hannut','WLG'),('BE','HOA','Houtain-le-Val','Houtain-le-Val','WBR'),('BE','HOD','Hodeige','Hodeige','WLG'),('BE','HOE','Hoeselt','Hoeselt','VLI'),('BE','HOF','Hofstade','Hofstade','VBR'),('BE','HOI','Hoeilaart','Hoeilaart','VBR'),('BE','HOK','Hollebeke','Hollebeke','VWV'),('BE','HOL','Hollain','Hollain','WHT'),('BE','HON','Honnelles','Honnelles','WHT'),('BE','HOO','Hoogstraten','Hoogstraten','VAN'),('BE','HOR','Horebeke','Horebeke','VOV'),('BE','HOT','Hotton','Hotton','WLX'),('BE','HOU','Hour','Hour','WNA'),('BE','HOV','Hove','Hove','VAN'),('BE','HPA','Heppenbach','Heppenbach','WLG'),('BE','HPD','Hastiere-par-dela','Hastiere-par-dela','WNA'),('BE','HPG','Heist-op-den-Berg','Heist-op-den-Berg','VAN'),('BE','HQI','Hacquegnies','Hacquegnies','WHT'),('BE','HRA','Hergenrath','Hergenrath','WLG'),('BE','HRE','Havre','Havre','WHT'),('BE','HRI','Harmignies','Harmignies','WHT'),('BE','HRO','Herenthout','Herenthout','VAN'),('BE','HRP','Hourpes','Hourpes','WHT'),('BE','HRQ','Herquegies','Herquegies','WHT'),('BE','HRS','Herstal','Herstal','WLG'),('BE','HRU','Hornu','Hornu','WHT'),('BE','HRV','Herve','Herve','WLG'),('BE','HRY','Habergy','Habergy','WLX'),('BE','HSA','Hermalle-sous-Argenteau','Hermalle-sous-Argenteau','WLG'),('BE','HSD','Hofstade','Hofstade','VOV'),('BE','HSE','Heers','Heers','VLI'),('BE','HSK','Holsbeek','Holsbeek','VBR'),('BE','HSL','St Huibrechts-Lille','St Huibrechts-Lille','VLI'),('BE','HSM','Houtain-Saint-Simeon','Houtain-Saint-Simeon','WLG'),('BE','HSP','Haine-Saint-Pierre','Haine-Saint-Pierre','WHT'),('BE','HSS','Hasselt','Hasselt','VLI'),('BE','HSX','Herseaux','Herseaux','WHT'),('BE','HSY','Heusy','Heusy','WLG'),('BE','HTH','Houthalen','Houthalen','VLI'),('BE','HTI','Hertain','Hertain','WHT'),('BE','HTJ','Hautrage','Hautrage','WHT'),('BE','HTM','Hermeton-sur-Meuse','Hermeton-sur-Meuse','WNA'),('BE','HTN','Houtaing','Houtaing','WHT'),('BE','HTP','Herstappe','Herstappe','VLI'),('BE','HTS','Heestert','Heestert','VWV'),('BE','HTV','Houtvenne','Houtvenne','VAN'),('BE','HUL','Hulste','Hulste','VWV'),('BE','HUM','Humbeek','Humbeek','VBR'),('BE','HUN','Hun','Hun','WNA'),('BE','HUR','Heure-le-Romain','Heure-le-Romain','WLG'),('BE','HUS','Housse','Housse','WLG'),('BE','HUT','Houthem','Houthem','WHT'),('BE','HUX','Houx','Houx','WNA'),('BE','HUY','Huy','Huy','WLG'),('BE','HVA','Havelange','Havelange','WNA'),('BE','HVB','Heverlee','Heverlee','VBR'),('BE','HVE','Hever','Hever','VBR'),('BE','HVG','Harveng','Harveng','WHT'),('BE','HVL','Heuvelland','Heuvelland','VWV'),('BE','HVN','Havenne','Havenne','WNA'),('BE','HVY','Havay','Havay','WHT'),('BE','HWA','Howardries','Howardries','WHT'),('BE','HYB','Herdersem','Herdersem','VOV'),('BE','HYD','Heyd','Heyd','WLX'),('BE','HYE','Houyet','Houyet','WNA'),('BE','HYO','Hyon','Hyon','WHT'),('BE','HYV','Habay-la-Vieille','Habay-la-Vieille','WLX'),('BE','HZI','Huizingen','Huizingen','VBR'),('BE','HZO','Heusden-Zolder','Heusden-Zolder','VLI'),('BE','HZY','Halanzy','Halanzy','WLX'),('BE','IBE','Itterbeek','Itterbeek','VBR'),('BE','ICO','Incourt','Incourt','WBR'),('BE','IDE','Iddergem','Iddergem','VOV'),('BE','IDG','Idegem','Idegem','VOV'),('BE','IGE','Ingelmunster','Ingelmunster','VWV'),('BE','IGM','Ingooigem','Ingooigem','VWV'),('BE','IHE','Ichtegem','Ichtegem','VWV'),('BE','IPR','Ieper','Ieper','VWV'),('BE','ISE','Isnes','Isnes','WNA'),('BE','ISR','Isieres','Isieres','WHT'),('BE','ITE','Itegem','Itegem','VAN'),('BE','ITR','Itter (Ittre)','Itter (Ittre)','WBR'),('BE','IWE','Irchonwelz','Irchonwelz','WHT'),('BE','IZE','Izenberge','Izenberge','VWV'),('BE','IZG','Izegem','Izegem','VWV'),('BE','IZI','Izier','Izier','WLX'),('BE','JAK','Jupille-sur-Meuse','Jupille-sur-Meuse','WLG'),('BE','JAM','Jambes','Jambes','WNA'),('BE','JAV','Java','Java','WLG'),('BE','JBE','Jabbeke','Jabbeke','VWV'),('BE','JBI','Jurbise','Jurbise','WHT'),('BE','JDO','Jodoigne','Jodoigne','WBR'),('BE','JEM','Jemeppe','Jemeppe','WLG'),('BE','JET','Jette/Brussel (Bruxelles)','Jette/Brussel (Bruxelles)','BRU'),('BE','JHY','Jalhay','Jalhay','WLG'),('BE','JKP','Sint-Jacobs-Kapelle','Sint-Jacobs-Kapelle','VWV'),('BE','JLE','Jallet','Jallet','WNA'),('BE','JME','Jemappes','Jemappes','WHT'),('BE','JPE','Juprelle','Juprelle','WLG'),('BE','JPS','Jemeppe-sur-Sambre','Jemeppe-sur-Sambre','WNA'),('BE','JSE','Juseret','Juseret','WLX'),('BE','JUM','Jumet','Jumet','WHT'),('BE','KAI','Kain','Kain','WHT'),('BE','KAN','Kanne (Canne)','Kanne (Canne)','VLI'),('BE','KAO','Keerbergen','Keerbergen','VBR'),('BE','KAS','Kaster','Kaster','VWV'),('BE','KBB','Kobbegem','Kobbegem','VBR'),('BE','KBE','Krombeke','Krombeke','VWV'),('BE','KCT','Kachtem','Kachtem','VWV'),('BE','KDE','Kieldrecht','Kieldrecht','VOV'),('BE','KEE','Koekelare','Koekelare','VWV'),('BE','KEK','Kruibeke','Kruibeke','VOV'),('BE','KES','Kessel','Kessel','VAN'),('BE','KET','Kermt','Kermt','VLI'),('BE','KGV','Kaggevinne','Kaggevinne','VBR'),('BE','KHI','Knokke-Heist','Knokke-Heist','VWV'),('BE','KHM','Kruishoutem','Kruishoutem','VOV'),('BE','KHN','Kerkhove','Kerkhove','VWV'),('BE','KHO','Kerkhoven','Kerkhoven','VLI'),('BE','KJK','Kortrijk','Kortrijk','VWV'),('BE','KKE','Kerksken','Kerksken','VOV'),('BE','KKR','Kaaskerke','Kaaskerke','VWV'),('BE','KKS','Koksijde','Koksijde','VWV'),('BE','KKT','Koningshooikt','Koningshooikt','VAN'),('BE','KLE','Kaulille','Kaulille','VLI'),('BE','KME','Kemmel','Kemmel','VWV'),('BE','KMH','Kampenhout','Kampenhout','VBR'),('BE','KMO','Kersbeek-Miskom','Kersbeek-Miskom','VBR'),('BE','KMZ','Kemzeke','Kemzeke',''),('BE','KNA','Kortenaken','Kortenaken','VBR'),('BE','KNO','Knokke/Het Zoute','Knokke/Het Zoute','VWV'),('BE','KNS','Knesselaere','Knesselaere','VOV'),('BE','KOE','Koekelberg/Brussel (Bruxelles)','Koekelberg/Brussel (Bruxelles)','BRU'),('BE','KOI','Kooigem','Kooigem','VWV'),('BE','KON','Kontich','Kontich','VAN'),('BE','KOO','Koolskamp','Koolskamp','VWV'),('BE','KOS','Koersel','Koersel','VLI'),('BE','KOU','Kallo','Kallo','VOV'),('BE','KPB','Kapelle-op-den-Bos','Kapelle-op-den-Bos','VBR'),('BE','KPN','Kapellen','Kapellen','VAN'),('BE','KRA','Kraainem','Kraainem','VBR'),('BE','KRI','Kaprijke','Kaprijke','VOV'),('BE','KRN','Kuringen','Kuringen','VLI'),('BE','KRO','Kinrooi','Kinrooi','VLI'),('BE','KSE','Kasterlee','Kasterlee','VAN'),('BE','KSN','Kessenich','Kessenich','VLI'),('BE','KSO','Kessel-Lo','Kessel-Lo','VBR'),('BE','KSR','Kluisbergen','Kluisbergen','VOV'),('BE','KST','Kester','Kester','VBR'),('BE','KTB','Kortenberg','Kortenberg','VBR'),('BE','KTE','Kettenis','Kettenis','WLG'),('BE','KTK','Kortemark','Kortemark','VWV'),('BE','KTM','Kortessem','Kortessem','VLI'),('BE','KTT','Kalmthout','Kalmthout','VAN'),('BE','KUU','Kuurne','Kuurne','VWV'),('BE','KVE','Klein Veerle','Klein Veerle','VAN'),('BE','KWA','Kwaadmechelen','Kwaadmechelen','VLI'),('BE','LAA','Laarne','Laarne','VOV'),('BE','LAD','Landen','Landen','VBR'),('BE','LAK','Langemark','Langemark','VWV'),('BE','LAM','Lamain','Lamain','WHT'),('BE','LAN','Lanaken','Lanaken','VLI'),('BE','LAP','La Calamine','La Calamine','WLG'),('BE','LAS','Lasne','Lasne','WBR'),('BE','LAW','Lauwe','Lauwe','VWV'),('BE','LBE','Lembeek','Lembeek','VBR'),('BE','LBK','Lubbeek','Lubbeek','VBR'),('BE','LBN','Libin','Libin','WLX'),('BE','LBO','La Bouverie','La Bouverie','WHT'),('BE','LBS','Lobbes','Lobbes','WHT'),('BE','LBU','Les Bulles','Les Bulles','WLX'),('BE','LBY','La Bruyere','La Bruyere','WNA'),('BE','LCA','l\'Escailliere','l\'Escailliere','WHT'),('BE','LCE','Lincent','Lincent','WLG'),('BE','LCI','Liberchies','Liberchies','WHT'),('BE','LCU','Lacuisine','Lacuisine','WLX'),('BE','LDI','Lesdain','Lesdain','WHT'),('BE','LDK','Liedekerke','Liedekerke','VBR'),('BE','LDO','Langdorp','Langdorp','VBR'),('BE','LDS','Landelies','Landelies','WHT'),('BE','LEB','Lebbeke','Lebbeke','VOV'),('BE','LED','Lede','Lede','VOV'),('BE','LEG','Ledegem','Ledegem','VWV'),('BE','LER','Liers','Liers','WLG'),('BE','LES','Lessines','Lessines','WHT'),('BE','LEU','Leuven','Leuven','VBR'),('BE','LFA','Leefdaal','Leefdaal','VBR'),('BE','LFE','Leffinge','Leffinge','VWV'),('BE','LFG','Longueville','Longueville','WBR'),('BE','LGA','Longchamps','Longchamps','WLX'),('BE','LGB','Langerbrugge','Langerbrugge','VOV'),('BE','LGG','Liege','Liege','WLG'),('BE','LGI','Leglise','Leglise','WLX'),('BE','LGL','Langelede','Langelede','VOV'),('BE','LGM','Landegem','Landegem','VOV'),('BE','LGN','Ligne','Ligne','WHT'),('BE','LGO','Langerlo','Langerlo','VLI'),('BE','LGY','Ligney','Ligney','WLG'),('BE','LHA','Lichtaart','Lichtaart','VAN'),('BE','LHK','Liefkenshoek','Liefkenshoek','VOV'),('BE','LHL','La Hulpe','La Hulpe','WBR'),('BE','LHO','Letterhoutem','Letterhoutem','VOV'),('BE','LHT','Leuze-en-Hainaut','Leuze-en-Hainaut','WHT'),('BE','LIB','Libramont-Chevigny','Libramont-Chevigny','WLX'),('BE','LIC','Lichtervelde','Lichtervelde','VWV'),('BE','LIE','Lier','Lier','VAN'),('BE','LIK','Lennik','Lennik','VBR'),('BE','LIL','Lillo','Lillo','VAN'),('BE','LIM','Limbourg','Limbourg','WLG'),('BE','LIN','Linter','Linter','VBR'),('BE','LIR','Sint-Martens-Lierde','Sint-Martens-Lierde','VOV'),('BE','LIX','Lixhe','Lixhe','WLG'),('BE','LKE','Lembeke','Lembeke','VOV'),('BE','LKK','Linkebeek','Linkebeek','VBR'),('BE','LKO','Loker','Loker','VWV'),('BE','LLE','Lille','Lille','VAN'),('BE','LLN','Louvain-la-Neuve','Louvain-la-Neuve','WBR'),('BE','LLO','La Louviere','La Louviere','WHT'),('BE','LME','Limelette','Limelette','WBR'),('BE','LML','Lommel','Lommel','VLI'),('BE','LND','Lendelede','Lendelede','VWV'),('BE','LNE','Laneffe','Laneffe','WNA'),('BE','LNI','Lint','Lint','VAN'),('BE','LNK','Lanklaar','Lanklaar','VLI'),('BE','LNS','Lens','Lens','WHT'),('BE','LNX','Lierneux','Lierneux','WLG'),('BE','LNY','Lanaye (Ternaaien)','Lanaye (Ternaaien)','WLG'),('BE','LNZ','Londerzeel','Londerzeel','VBR'),('BE','LOC','Loncin','Loncin','WLG'),('BE','LOD','Lodelinsart','Lodelinsart','WHT'),('BE','LOH','Lochristi','Lochristi','VOV'),('BE','LOK','Lokeren','Lokeren','VOV'),('BE','LOP','Lompret','Lompret','WHT'),('BE','LOT','Lot','Lot','VBR'),('BE','LOY','Loyers','Loyers','WNA'),('BE','LOZ','Lozen','Lozen','VLI'),('BE','LPE','Loupoigne','Loupoigne','WBR'),('BE','LPG','Leopoldsburg','Leopoldsburg','VLI'),('BE','LPI','Laplaigne','Laplaigne','WHT'),('BE','LPM','Loppem','Loppem','VWV'),('BE','LPO','Langemark-Poelkapelle','Langemark-Poelkapelle','VWV'),('BE','LPT','La Plante','La Plante','WNA'),('BE','LPZ','Lomprez','Lomprez','WLX'),('BE','LQA','Lanquesaint','Lanquesaint','WHT'),('BE','LRE','Leernes','Leernes','WHT'),('BE','LRG','Ledeberg','Ledeberg','VOV'),('BE','LRI','Lo-Reninge','Lo-Reninge','VWV'),('BE','LRM','Larum','Larum','VAN'),('BE','LRZ','Berloz','Berloz','WLG'),('BE','LSE','Leisele','Leisele','VWV'),('BE','LSG','Lissewege','Lissewege','VWV'),('BE','LSI','Lombardsijde','Lombardsijde','VWV'),('BE','LSN','Lasne-Chapelle-Saint-Lambert','Lasne-Chapelle-Saint-Lambert','WBR'),('BE','LSO','Lisogne','Lisogne','WNA'),('BE','LST','Leest','Leest','VAN'),('BE','LSY','Lesterny','Lesterny','WLX'),('BE','LTA','Leval-Trahegnies','Leval-Trahegnies','WHT'),('BE','LTI','Latinne','Latinne','WLG'),('BE','LTO','Latour','Latour','WLX'),('BE','LTZ','Lontzen','Lontzen','WLG'),('BE','LUE','Ligneuville','Ligneuville','WLG'),('BE','LUI','Lustin','Lustin','WNA'),('BE','LUM','Lummen','Lummen','VLI'),('BE','LUT','Luttre','Luttre','WHT'),('BE','LUV','Louveigne','Louveigne','WLG'),('BE','LUZ','Ladeuze','Ladeuze','WHT'),('BE','LVA','Lavacherie','Lavacherie','WLX'),('BE','LVM','Lives-sur-Meuse','Lives-sur-Meuse','WNA'),('BE','LVO','Lovendegem','Lovendegem','VOV'),('BE','LVW','Onze-Lieve-Vrouw-Waver','Onze-Lieve-Vrouw-Waver','VAN'),('BE','LWE','Lommersweiler','Lommersweiler','WLG'),('BE','LWI','Lillois-Witterzee','Lillois-Witterzee','WBR'),('BE','MAC','Machelen','Machelen','VBR'),('BE','MAF','Maffe','Maffe','WNA'),('BE','MAK','Maarkedal','Maarkedal','VOV'),('BE','MAL','Malle','Malle','VAN'),('BE','MAN','Manage','Manage','WHT'),('BE','MAP','Marchienne-au-Pont','Marchienne-au-Pont','WHT'),('BE','MAR','Marke','Marke','VWV'),('BE','MAZ','Mazy','Mazy','WNA'),('BE','MBA','Mielen-boven-Aalst','Mielen-boven-Aalst','VLI'),('BE','MBE','Meerbeke','Meerbeke','VOV'),('BE','MBI','Montroeul-au-Bois','Montroeul-au-Bois','WHT'),('BE','MBK','Melsbroek','Melsbroek','VBR'),('BE','MBL','Munsterbilzen','Munsterbilzen','VLI'),('BE','MBO','Mabompre','Mabompre','WLX'),('BE','MBU','Masbourg','Masbourg','WLX'),('BE','MBW','Malmedy','Malmedy','WLG'),('BE','MBY','Maubray','Maubray','WHT'),('BE','MCA','Merbes-le-Chateau','Merbes-le-Chateau','WHT'),('BE','MCE','Miecret','Miecret','WNA'),('BE','MCI','Marchin','Marchin','WLG'),('BE','MCL','Marcinelle','Marcinelle','WHT'),('BE','MCN','Machelen','Machelen','VOV'),('BE','MCO','Macon','Macon','WHT'),('BE','MCQ','Macquenoise','Macquenoise','WHT'),('BE','MCT','Mourcourt','Mourcourt','WHT'),('BE','MCX','Micheroux','Micheroux','WLG'),('BE','MDE','Meldert','Meldert','VOV'),('BE','MDL','Mont-de-L\'Enclus','Mont-de-L\'Enclus','WHT'),('BE','MDO','Mendonk','Mendonk','VOV'),('BE','MDV','Meix-devant-Virton','Meix-devant-Virton','WLX'),('BE','MEA','Mean','Mean','WNA'),('BE','MEB','Meslin-l\'Eveque','Meslin-l\'Eveque','WHT'),('BE','MEC','Merchtem','Merchtem','VBR'),('BE','MEE','Meer','Meer','VAN'),('BE','MEF','Marche-en-Famenne','Marche-en-Famenne','WLX'),('BE','MEG','Meilegem','Meilegem','VOV'),('BE','MEH','Meerhout','Meerhout','VAN'),('BE','MEI','Melin','Melin','WBR'),('BE','MEL','Melle','Melle','VOV'),('BE','MEM','Mollem','Mollem','VBR'),('BE','MEN','Menen','Menen','VWV'),('BE','MER','Mere','Mere','VOV'),('BE','MES','Messancy','Messancy','WLX'),('BE','MEU','Meulebeke','Meulebeke','VWV'),('BE','MEW','Moerbeke-Waas','Moerbeke-Waas','VOV'),('BE','MFF','Maffle','Maffle','WHT'),('BE','MGE','Magnee','Magnee','WLG'),('BE','MGL','Mevergnies-lez-Lens','Mevergnies-lez-Lens','WHT'),('BE','MGM','Meigem','Meigem','VOV'),('BE','MGN','Moignelee','Moignelee','WNA'),('BE','MGS','Montignies-sur-Sambre','Montignies-sur-Sambre','WHT'),('BE','MGU','Meeuwen-Gruitrode','Meeuwen-Gruitrode','VLI'),('BE','MHI','Mohiville','Mohiville','WNA'),('BE','MHN','Massenhoven','Massenhoven','VAN'),('BE','MHO','Minderhout','Minderhout','VAN'),('BE','MHY','Manhay','Manhay','WLX'),('BE','MID','Middelburg','Middelburg','VOV'),('BE','MIK','Middelkerke','Middelkerke','VWV'),('BE','MIL','Milmort','Milmort','WLG'),('BE','MIR','Monceau-Imbrechies','Monceau-Imbrechies','WHT'),('BE','MIS','Meise','Meise','VBR'),('BE','MKE','Mannekensvere','Mannekensvere','VWV'),('BE','MKI','Meensel-Kiezegem','Meensel-Kiezegem','VBR'),('BE','MLD','Marche-les-Dames','Marche-les-Dames','WNA'),('BE','MLE','Melsele','Melsele','VOV'),('BE','MLG','Maldegem','Maldegem','VOV'),('BE','MLN','Malonne','Malonne','WNA'),('BE','MLO','Mol','Mol','VAN'),('BE','MLR','Meerle','Meerle','VAN'),('BE','MLS','Melles','Melles','WHT'),('BE','MLT','Mellet','Mellet','WHT'),('BE','MLW','Morlanwelz-Mariemont','Morlanwelz-Mariemont','WHT'),('BE','MLX','Moulbaix','Moulbaix','WHT'),('BE','MLY','Marly','Marly','VBR'),('BE','MMA','Mont-sur-Marchienne','Mont-sur-Marchienne','WHT'),('BE','MMN','Maasmechelen','Maasmechelen','VLI'),('BE','MND','Molenstede','Molenstede','VBR'),('BE','MNE','Martouzin-Neuville','Martouzin-Neuville','WNA'),('BE','MNL','Melen','Melen','WLG'),('BE','MNO','Moen','Moen','VWV'),('BE','MNT','Mont','Mont','WLX'),('BE','MOB','Montleban','Montleban','WLX'),('BE','MOD','Modave','Modave','WLG'),('BE','MOE','Moelingen','Moelingen','VLI'),('BE','MOL','Moorsel','Moorsel','VOV'),('BE','MOM','Momignies','Momignies','WHT'),('BE','MON','Montignies-le-Tilleul','Montignies-le-Tilleul','WHT'),('BE','MOO','Moorsele','Moorsele','VWV'),('BE','MOR','Mortsel','Mortsel','VAN'),('BE','MOS','Moeskroen (Mouscron)','Moeskroen (Mouscron)','WHT'),('BE','MOT','Montzen','Montzen','WLG'),('BE','MPS','Merksplas','Merksplas','VAN'),('BE','MQS','Mons','Mons','WHT'),('BE','MRB','Moerbrugge','Moerbrugge','VWV'),('BE','MRD','Merendree','Merendree','VOV'),('BE','MRE','Meerbeek','Meerbeek','VBR'),('BE','MRG','Maurage','Maurage','WHT'),('BE','MRI','Mariakerke','Mariakerke','VOV'),('BE','MRK','Merksem','Merksem','VAN'),('BE','MRL','Merelbeke','Merelbeke','VOV'),('BE','MRM','Merkem','Merkem','VWV'),('BE','MRO','Mornimont','Mornimont','WNA'),('BE','MRQ','Marquain','Marquain','WHT'),('BE','MRS','Moorslede','Moorslede','VWV'),('BE','MSA','Mont-Saint-Aubert','Mont-Saint-Aubert','WHT'),('BE','MSD','Martenslinde','Martenslinde','VLI'),('BE','MSE','Mesen','Mesen','VWV'),('BE','MSG','Mont-Sainte-Aldegonde','Mont-Sainte-Aldegonde','WHT'),('BE','MSI','Monsin','Monsin','WLG'),('BE','MSJ','Molenbeek-Saint-Jean (Sint-Jans-Molenbeek)/Brussel (Bruxelles)','Molenbeek-Saint-Jean (Sint-Jans-Molenbeek)/Brussel (Bruxelles)','BRU'),('BE','MSK','Maaseik','Maaseik','VLI'),('BE','MSL','Musson','Musson','WLX'),('BE','MSN','Maissin','Maissin','WLX'),('BE','MSO','Messelbroek','Messelbroek','VBR'),('BE','MSP','Mespelare','Mespelare','VOV'),('BE','MSR','Maisieres','Maisieres','WHT'),('BE','MSS','Monceau-sur-Sambre','Monceau-sur-Sambre','WHT'),('BE','MSU','Mont-Saint-Guibert','Mont-Saint-Guibert','WBR'),('BE','MTA','Martelange','Martelange','WLX'),('BE','MTE','Mettet','Mettet','WNA'),('BE','MTX','Mortroux','Mortroux','WLG'),('BE','MUI','Muizen','Muizen','VAN'),('BE','MUL','Maulde','Maulde','WHT'),('BE','MUN','Muno','Muno','WLX'),('BE','MUS','Moustier','Moustier','WHT'),('BE','MUX','Meux','Meux','WNA'),('BE','MVA','Mainvault','Mainvault','WHT'),('BE','MVI','Mesvin','Mesvin','WHT'),('BE','MWE','Molenbeek-Wersbeek','Molenbeek-Wersbeek','VBR'),('BE','MZK','Moerzeke','Moerzeke','VOV'),('BE','MZT','Maizeret','Maizeret','WNA'),('BE','NAM','Namur','Namur','WNA'),('BE','NAS','Naast','Naast','WHT'),('BE','NBA','Nimy','Nimy','WHT'),('BE','NBL','Nederboelare','Nederboelare','VOV'),('BE','NCA','Neufchateau','Neufchateau','WLG'),('BE','NCO','Neuville-en-Condroz','Neuville-en-Condroz','WLG'),('BE','NCU','Neufchateau','Neufchateau','WLX'),('BE','NDI','Nandrin','Nandrin','WLG'),('BE','NED','Nederokkerzeel','Nederokkerzeel','VBR'),('BE','NEG','Neigem','Neigem','VOV'),('BE','NES','Nessonvaux','Nessonvaux','WLG'),('BE','NEU','Neufvilles','Neufvilles','WHT'),('BE','NFE','Neffe','Neffe','WNA'),('BE','NFO','Noirefontaine','Noirefontaine','WLX'),('BE','NHA','Neerharen','Neerharen','VLI'),('BE','NHR','Nederzwalm-Hermelgem','Nederzwalm-Hermelgem','VOV'),('BE','NHY','Neuville-sous-Huy','Neuville-sous-Huy','WLG'),('BE','NIE','Nieuwpoort','Nieuwpoort','VWV'),('BE','NIL','Niel','Niel','VAN'),('BE','NIV','Nivelles','Nivelles','WBR'),('BE','NLA','Neerlanden','Neerlanden','VBR'),('BE','NMA','Neufmaison','Neufmaison','WHT'),('BE','NMC','Nameche','Nameche','WNA'),('BE','NMO','Neu-Moresnet','Neu-Moresnet','WLG'),('BE','NNE','Naninne','Naninne','WNA'),('BE','NNV','Ninove','Ninove','VOV'),('BE','NOK','Nokere','Nokere','VOV'),('BE','NPE','Neupre','Neupre','WLG'),('BE','NRO','Nieuwrode','Nieuwrode','VBR'),('BE','NRP','Neerpelt','Neerpelt','VLI'),('BE','NRT','Neeroeteren','Neeroeteren','VLI'),('BE','NRY','Renory','Renory','WLG'),('BE','NSG','Nossegem','Nossegem','VBR'),('BE','NSO','Nassogne','Nassogne','WLX'),('BE','NTE','Natoye','Natoye','WNA'),('BE','NUK','Nukerke','Nukerke','VOV'),('BE','NVE','Nouvelles','Nouvelles','WHT'),('BE','NVH','Neder-Over-Heembeek','Neder-Over-Heembeek','VBR'),('BE','NVL','Nevele','Nevele','VOV'),('BE','NVN','Noeveren','Noeveren','VAN'),('BE','NVX','Nollevaux','Nollevaux','WLX'),('BE','NWE','Nieuwerkerken','Nieuwerkerken','VOV'),('BE','NWK','Nieuwerkerken','Nieuwerkerken','VLI'),('BE','NWO','Nieuwenhove','Nieuwenhove','VOV'),('BE','NYL','Nijlen','Nijlen','VAN'),('BE','NZH','Nazareth','Nazareth','VOV'),('BE','OAY','Onhaye','Onhaye','WNA'),('BE','OBC','Broechem','Broechem','VAN'),('BE','OBG','Oudenburg','Oudenburg','VWV'),('BE','OBI','Obigies','Obigies','WHT'),('BE','OBL','Zoersel','Zoersel','VAN'),('BE','OBR','Obourg','Obourg','WHT'),('BE','OBT','Ombret-Rawsa','Ombret-Rawsa','WLG'),('BE','ODE','Auderghem (Oudergem)/Brussel (Bruxelles)','Auderghem (Oudergem)/Brussel (Bruxelles)','BRU'),('BE','OEL','Oelegem','Oelegem','VAN'),('BE','OEV','Oevel','Oevel','VAN'),('BE','OGA','Outgaarden','Outgaarden','VBR'),('BE','OGE','Ormeignies','Ormeignies','WHT'),('BE','OGI','Oeudeghien','Oeudeghien','WHT'),('BE','OGS','Ollignies','Ollignies','WHT'),('BE','OGY','Ogy','Ogy','WHT'),('BE','OHE','Oud-Heverlee','Oud-Heverlee','VBR'),('BE','OHN','Ophoven','Ophoven','VLI'),('BE','OHY','Ohey','Ohey','WNA'),('BE','OIJ','Opwijk','Opwijk','VBR'),('BE','OJA','Orp-Jauche','Orp-Jauche','WBR'),('BE','OKG','Okegem','Okegem','VOV'),('BE','OKO','Oosteeklo','Oosteeklo','VOV'),('BE','OKP','Oostkamp','Oostkamp','VWV'),('BE','OLE','Overboelare','Overboelare','VOV'),('BE','OLM','Olmen','Olmen','VAN'),('BE','OLN','Olen','Olen','VAN'),('BE','OLS','Olsene','Olsene','VOV'),('BE','OMA','Omal','Omal','WLG'),('BE','ONE','Olne','Olne','WLG'),('BE','OOG','Ooigem','Ooigem','VWV'),('BE','OOS','Oostakker','Oostakker','VOV'),('BE','OPG','Opglabbeek','Opglabbeek','VLI'),('BE','OPI','Opitter','Opitter','VLI'),('BE','OPO','Opont','Opont','WLX'),('BE','OPY','Oupeye','Oupeye','WLG'),('BE','OQC','Oisquercq','Oisquercq','WBR'),('BE','ORQ','Orcq','Orcq','WHT'),('BE','ORR','Orroir','Orroir','WHT'),('BE','OSG','Oeselgem','Oeselgem','VWV'),('BE','OSH','Oostham','Oostham','VLI'),('BE','OSI','Ophain-Bois-Seigneur-Isaac','Ophain-Bois-Seigneur-Isaac','WBR'),('BE','OSL','Oostmalle','Oostmalle','VAN'),('BE','OSR','Oostrozebeke','Oostrozebeke','VWV'),('BE','OST','Oostende (Ostend)','Oostende (Ostend)','VWV'),('BE','OSV','Oostvleteren','Oostvleteren','VWV'),('BE','OTG','Otegem','Otegem','VWV'),('BE','OTH','Oud-Turnhout','Oud-Turnhout','VAN'),('BE','OTI','Ottignies-Louvain-la Neuve','Ottignies-Louvain-la Neuve','WBR'),('BE','OTK','Oostkerke','Oostkerke','VWV'),('BE','OTL','Oosterlo','Oosterlo','VAN'),('BE','OTO','Ortho','Ortho','WLX'),('BE','OTS','Ostiches','Ostiches','WHT'),('BE','OTY','Outrijve','Outrijve','VWV'),('BE','OUD','Oudenaarde','Oudenaarde','VOV'),('BE','OUF','Ouffet','Ouffet','WLG'),('BE','OUG','Ougree','Ougree','WLG'),('BE','OUT','Outer','Outer','VOV'),('BE','OVE','Overpelt','Overpelt','VLI'),('BE','OVR','Overijse','Overijse','VBR'),('BE','OWI','Oostwinkel','Oostwinkel','VOV'),('BE','OYE','Oreye','Oreye','WLG'),('BE','OZE','Oosterzele','Oosterzele','VOV'),('BE','OZL','Onkerzele','Onkerzele','VOV'),('BE','PAL','Paal','Paal','VLI'),('BE','PAS','Passendale','Passendale','VWV'),('BE','PBE','Pellenberg','Pellenberg','VBR'),('BE','PBI','Plombieres','Plombieres','WLG'),('BE','PCL','Pont-a-Celles','Pont-a-Celles','WHT'),('BE','PCQ','Pecq','Pecq','WHT'),('BE','PEE','Peer','Peer','VLI'),('BE','PEI','Peisegem','Peisegem','VBR'),('BE','PEP','Pepinster','Pepinster','WLG'),('BE','PER','Perk','Perk','VBR'),('BE','PES','Peronnes','Peronnes','WHT'),('BE','PFE','Profondeville','Profondeville','WNA'),('BE','PFV','Paifve','Paifve','WLG'),('BE','PGE','Petegem','Petegem','VOV'),('BE','PGI','Papignies','Papignies','WHT'),('BE','PHI','Philippeville','Philippeville','WNA'),('BE','PIN','Pepingen','Pepingen','VBR'),('BE','PKH','Pollinkhove','Pollinkhove','VWV'),('BE','PLB','Peronnes/Binche','Peronnes/Binche','WHT'),('BE','PLE','Pulle','Pulle','VAN'),('BE','PLI','Paliseul','Paliseul','WLX'),('BE','PLO','Pont-de-Loup','Pont-de-Loup','WHT'),('BE','PLY','Petit-Lanaye','Petit-Lanaye','WLG'),('BE','PME','Pommeroeul','Pommeroeul','WHT'),('BE','PML','Pamel','Pamel','VBR'),('BE','POL','Pollare','Pollare','VOV'),('BE','POP','Poperinge','Poperinge','VWV'),('BE','PPE','Poppel','Poppel','VAN'),('BE','PPX','Pipaix','Pipaix','WHT'),('BE','PRI','Parike','Parike','VOV'),('BE','PRN','Petit-Roeulx-lez-Nivelles','Petit-Roeulx-lez-Nivelles','WHT'),('BE','PRO','Pondrome','Pondrome','WNA'),('BE','PRV','Proven','Proven','VWV'),('BE','PRW','Perwez','Perwez','WNA'),('BE','PSE','Ploegsteert','Ploegsteert','WHT'),('BE','PST','Postel','Postel','VAN'),('BE','PSU','Poulseur','Poulseur','WLG'),('BE','PTI','Petit-Thier','Petit-Thier','WLX'),('BE','PTP','Pijp Tabak','Pijp Tabak','VAN'),('BE','PTR','Petit-Rechain','Petit-Rechain','WLG'),('BE','PTS','Pottes','Pottes','WHT'),('BE','PTT','Pittem','Pittem','VWV'),('BE','PUL','Pulderbos','Pulderbos','VAN'),('BE','PUT','Putte','Putte','VAN'),('BE','PUU','Puurs','Puurs','VAN'),('BE','PVX','Plainevaux','Plainevaux','WLG'),('BE','PWE','Perwez','Perwez','WBR'),('BE','PWZ','Peruwelz','Peruwelz','WHT'),('BE','QAR','Quartes','Quartes','WHT'),('BE','QCA','Quevaucamps','Quevaucamps','WHT'),('BE','QRO','Quaregnon','Quaregnon','WHT'),('BE','QUE','Quenast','Quenast','WBR'),('BE','QVA','Quievrain','Quievrain','WHT'),('BE','QVY','Quevy','Quevy','WHT'),('BE','RAE','Raeren','Raeren','WLG'),('BE','RAG','Ragnies','Ragnies','WHT'),('BE','RAR','La Roche-en-Ardenne','La Roche-en-Ardenne','WLX'),('BE','RAS','Ranst','Ranst','VAN'),('BE','RBA','Rotselaar','Rotselaar','VBR'),('BE','RBE','Roesbrugge','Roesbrugge','VWV'),('BE','RBQ','Rebecq','Rebecq','WBR'),('BE','RBX','Rebaix','Rebaix','WHT'),('BE','RCI','Ramegnies-Chin','Ramegnies-Chin','WHT'),('BE','RCL','Richelle','Richelle','WLG'),('BE','RCO','Rachecourt','Rachecourt','WLX'),('BE','RCT','Roucourt','Roucourt','WHT'),('BE','RCU','Remicourt','Remicourt','WLG'),('BE','RDA','Remersdaal','Remersdaal','VLI'),('BE','RDL','Roosdaal','Roosdaal','VBR'),('BE','REC','Recogne','Recogne','WLX'),('BE','REK','Rekkem','Rekkem','VOV'),('BE','REM','Rekem','Rekem','VLI'),('BE','REN','Rendeux','Rendeux','WLX'),('BE','REQ','Erquelinnes','Erquelinnes','WHT'),('BE','RET','Reet','Reet','VAN'),('BE','RGE','Reninge','Reninge','VWV'),('BE','RGM','Relegem','Relegem','VBR'),('BE','RGS','Ramegnies','Ramegnies','WHT'),('BE','RGY','Rongy','Rongy','WHT'),('BE','RHA','Roesbrugge-Haringe','Roesbrugge-Haringe','VWV'),('BE','RIE','Rieme','Rieme','VOV'),('BE','RIJ','Rijkevorsel','Rijkevorsel','VAN'),('BE','RIN','Beringen','Beringen','VLI'),('BE','RIS','Riemst','Riemst','VLI'),('BE','RIX','Rixensart','Rixensart','WBR'),('BE','RKE','Runkelen','Runkelen','VLI'),('BE','RKM','Rekkem','Rekkem','VWV'),('BE','RKP','Ramskapelle','Ramskapelle','VWV'),('BE','RLA','Rillaar','Rillaar','VBR'),('BE','RLE','Ronsele','Ronsele','VOV'),('BE','RLS','Rulles','Rulles','WLX'),('BE','RMI','Ramillies','Ramillies','WBR'),('BE','RML','Rumillies','Rumillies','WHT'),('BE','RMS','Rumes','Rumes','WHT'),('BE','RMU','Rummen','Rummen','VBR'),('BE','RNM','Rijmenam','Rijmenam','VAN'),('BE','ROC','Rochefort','Rochefort','WNA'),('BE','ROE','Roeselare','Roeselare','VWV'),('BE','ROG','Rognee','Rognee','WNA'),('BE','ROL','Rollegem','Rollegem','VWV'),('BE','ROM','Romsee','Romsee','WLG'),('BE','RON','Ronse','Ronse','VOV'),('BE','ROS','Roselies','Roselies','WHT'),('BE','ROT','Rotem','Rotem','VLI'),('BE','ROU','Le Roeulx','Le Roeulx','WHT'),('BE','ROX','Roux','Roux','WHT'),('BE','RPM','Rupelmonde','Rupelmonde','VOV'),('BE','RQS','Ronquieres','Ronquieres','WHT'),('BE','RRA','Rocherath','Rocherath','WLG'),('BE','RSA','Ransart','Ransart','WHT'),('BE','RSE','Ressegem','Ressegem','VOV'),('BE','RSI','Rosieres','Rosieres','WBR'),('BE','RSL','Ruiselede','Ruiselede','VWV'),('BE','RSX','Ressaix','Ressaix','WHT'),('BE','RTE','Retinne','Retinne','WLG'),('BE','RTI','Retie','Retie','VAN'),('BE','RUE','Ruien','Ruien','VOV'),('BE','RUI','Ruisbroek','Ruisbroek','VBR'),('BE','RUM','Rumbeke','Rumbeke','VWV'),('BE','RUS','Rumst','Rumst','VAN'),('BE','RUV','Ruddervoorde','Ruddervoorde','VWV'),('BE','RVE','Riviere','Riviere','WNA'),('BE','RVS','Ravels','Ravels','VAN'),('BE','RVY','Rouvroy','Rouvroy','WLX'),('BE','RZE','Riezes','Riezes','WHT'),('BE','SAM','St Amand','St Amand','WHT'),('BE','SAN','St Andries','St Andries','VWV'),('BE','SAR','Samree','Samree','WLX'),('BE','SAS','St Amands','St Amands','VAN'),('BE','SAT','Stave','Stave','WNA'),('BE','SAV','Sambreville','Sambreville','WNA'),('BE','SBE','Steenbrugge','Steenbrugge','VWV'),('BE','SBF','Sombreffe','Sombreffe','WNA'),('BE','SBG','Stambruges','Stambruges','WHT'),('BE','SBK','Schaarbeek (Schaerbeek)/Brussel (Bruxelles)','Schaarbeek (Schaerbeek)/Brussel (Bruxelles)','BRU'),('BE','SBU','Sars-la-Buissiere','Sars-la-Buissiere','WHT'),('BE','SCE','Schilde','Schilde','VAN'),('BE','SCH','Schaarbeek','Schaarbeek','VOV'),('BE','SCT','Schoten','Schoten','VAN'),('BE','SCY','Scy','Scy','WNA'),('BE','SDA','Schepdaal','Schepdaal','VBR'),('BE','SDE','St Denis','St Denis','WNA'),('BE','SDI','St Denis','St Denis','WHT'),('BE','SDP','Steendorp','Steendorp','VOV'),('BE','SDT','Soudromont','Soudromont','WHT'),('BE','SDW','Sint-Denijs-Westrem','Sint-Denijs-Westrem','VOV'),('BE','SDY','St Denijs','St Denijs','VWV'),('BE','SDZ','Saint-Vincent','Saint-Vincent','WLX'),('BE','SEN','Seneffe','Seneffe','WHT'),('BE','SES','Seilles','Seilles','WNA'),('BE','SEV','Sint-Eloois-Vijve','Sint-Eloois-Vijve','VWV'),('BE','SFY','Sint-Amandsberg','Sint-Amandsberg','VOV'),('BE','SGI','Saint-Gilles (Sint-Gillis)/Brussel (Bruxelles)','Saint-Gilles (Sint-Gillis)/Brussel (Bruxelles)','BRU'),('BE','SGM','Stasegem','Stasegem','VWV'),('BE','SGR','Sint-Genesius-Rode (Rhode-Saint-Genese)','Sint-Genesius-Rode (Rhode-Saint-Genese)','VBR'),('BE','SGS','St Georges','St Georges','WLG'),('BE','SGW','St Gillis-Waas','St Gillis-Waas','VOV'),('BE','SGX','Sclaigneaux','Sclaigneaux','WNA'),('BE','SHB','Schellebelle','Schellebelle','VOV'),('BE','SHE','Schendelbeke','Schendelbeke','VOV'),('BE','SHL','Schelle','Schelle','VAN'),('BE','SHO','Schalkhoven','Schalkhoven','VLI'),('BE','SHR','Schelderode','Schelderode','VOV'),('BE','SHU','St Hubert','St Hubert','WLX'),('BE','SII','St Lievens-Esse','St Lievens-Esse','VOV'),('BE','SIP','Sippenaeken','Sippenaeken','WLG'),('BE','SIV','Saive','Saive','WLG'),('BE','SIY','Silly','Silly','WHT'),('BE','SJE','St Jan-in-Eremo','St Jan-in-Eremo','VOV'),('BE','SJG','Sint-Job-in-\'t-Goor','Sint-Job-in-\'t-Goor','VAN'),('BE','SJN','Saint-Josse-ten-Noode (Sint-Joost-ten-Node)','Saint-Josse-ten-Noode (Sint-Joost-ten-Node)','BRU'),('BE','SJO','St Jozef Olen','St Jozef Olen','VAN'),('BE','SJR','St Joris','St Joris','VWV'),('BE','SJW','St Joris-Weert','St Joris-Weert','VBR'),('BE','SKE','Steenkerke','Steenkerke','VWV'),('BE','SKI','Schriek','Schriek','VAN'),('BE','SKK','Steenokkerzeel','Steenokkerzeel','VBR'),('BE','SKL','St Katherina-Lombeek','St Katherina-Lombeek','VBR'),('BE','SKM','Serskamp','Serskamp','VOV'),('BE','SKR','Stokrooie','Stokrooie','VLI'),('BE','SKU','St Kruis','St Kruis','VWV'),('BE','SKW','St Kruis-Winkel','St Kruis-Winkel','VOV'),('BE','SLA','Selange','Selange','WLX'),('BE','SLE','Sleidinge','Sleidinge','VOV'),('BE','SLG','St Leger','St Leger','WLX'),('BE','SLH','St Lievens-Houtem','St Lievens-Houtem','VOV'),('BE','SLI','Bois-de-Lessines','Bois-de-Lessines','WHT'),('BE','SLJ','Sas-Slijkens','Sas-Slijkens','VWV'),('BE','SLK','Spalbeek','Spalbeek','VLI'),('BE','SLN','St Lenaarts','St Lenaarts','VAN'),('BE','SLO','Sorinne-la-Longue','Sorinne-la-Longue','WNA'),('BE','SLS','Salles','Salles','WHT'),('BE','SLT','Stavelot','Stavelot','WLG'),('BE','SLU','St Laureins','St Laureins','VOV'),('BE','SLW','Sint-Lambrechts-Woluwe (Woluwe-Saint-Lambert)/Brussel (Bruxelles)','Sint-Lambrechts-Woluwe (Woluwe-Saint-Lambert)/Brussel (Bruxelles)','BRU'),('BE','SLY','Sclayn','Sclayn','WNA'),('BE','SMA','St Mard','St Mard','WLX'),('BE','SMC','Saint-Marc','Saint-Marc','WNA'),('BE','SME','St Michiels','St Michiels','VWV'),('BE','SMI','St Martens-Lierde','St Martens-Lierde','VOV'),('BE','SML','St Martens-Latem','St Martens-Latem','VOV'),('BE','SMM','Smeermaas','Smeermaas','VLI'),('BE','SMO','Sprimont','Sprimont','WLG'),('BE','SMR','St Margriete','St Margriete','VOV'),('BE','SNA','Sinaai','Sinaai','VOV'),('BE','SNE','Schoonaarde','Schoonaarde','VOV'),('BE','SNK','St Niklaas','St Niklaas','VOV'),('BE','SNO','St Nicolas','St Nicolas','WLG'),('BE','SOB','Schoenberg','Schoenberg','WLG'),('BE','SOD','Ste-Ode','Ste-Ode','WLX'),('BE','SOG','Seloignes','Seloignes','WHT'),('BE','SOI','Soignies','Soignies','WHT'),('BE','SOM','Sommiere','Sommiere','WNA'),('BE','SON','Soiron','Soiron','WLG'),('BE','SOR','Schore','Schore','VWV'),('BE','SOU','Soumagne','Soumagne','WLG'),('BE','SOV','Strombeek-Bever','Strombeek-Bever','VBR'),('BE','SPA','Spa','Spa','WLG'),('BE','SPE','Scheepsdale','Scheepsdale','VWV'),('BE','SPH','Sterpenich','Sterpenich','WLX'),('BE','SPI','Espierres (Spiere)','Espierres (Spiere)','VWV'),('BE','SPK','Sint-Pieters-Kapelle','Sint-Pieters-Kapelle','VBR'),('BE','SPL','St Pieers-Leeuw','St Pieers-Leeuw','VBR'),('BE','SPO','Sint-Pieters-Woluwe (Woluwe-Saint-Pierre)/Brussel (Bruxelles)','Sint-Pieters-Woluwe (Woluwe-Saint-Pierre)/Brussel (Bruxelles)','BRU'),('BE','SPS','Spiennes','Spiennes','WHT'),('BE','SPT','St Pieters-Leeuw','St Pieters-Leeuw','VBR'),('BE','SPU','Scherpenheuvel-Zichem','Scherpenheuvel-Zichem','VBR'),('BE','SPV','Sint-Pieters-Voeren','Sint-Pieters-Voeren','VLI'),('BE','SRA','Sirault','Sirault','WHT'),('BE','SRB','Sterrebeek','Sterrebeek','VBR'),('BE','SRE','Souvret','Souvret','WHT'),('BE','SRI','Schorisse','Schorisse','VOV'),('BE','SRN','Sorinnes','Sorinnes','WNA'),('BE','SRY','St Remy','St Remy','WLG'),('BE','SSA','St Sauveur','St Sauveur','WHT'),('BE','SSB','Solre-sur-Sambre','Solre-sur-Sambre','WHT'),('BE','SSI','St Servais','St Servais','WNA'),('BE','SSK','Snaaskerke','Snaaskerke','VWV'),('BE','SSL','St Katelijne-Waver','St Katelijne-Waver','VAN'),('BE','SSN','Sclessin','Sclessin','WLG'),('BE','SSO','Samson','Samson','WNA'),('BE','SSU','Sensenruth','Sensenruth','WLX'),('BE','SSY','St Symphorien','St Symphorien','WHT'),('BE','STA','Stabroek','Stabroek','VAN'),('BE','STB','Strepy-Bracquegnies','Strepy-Bracquegnies','WHT'),('BE','STD','Staden','Staden','VWV'),('BE','STE','Stree','Stree','WHT'),('BE','STI','Schaltin','Schaltin','WNA'),('BE','STK','Stekene','Stekene','VOV'),('BE','STM','Stembert','Stembert','WLG'),('BE','STN','Sautin','Sautin','WHT'),('BE','STR','St Truiden','St Truiden','VLI'),('BE','STS','Saintes','Saintes','WBR'),('BE','STT','Statte','Statte','WLG'),('BE','STU','Stoumont','Stoumont','WLG'),('BE','STV','Sint-Baafs-Vijve','Sint-Baafs-Vijve','VWV'),('BE','STW','St Stevens-Woluwe','St Stevens-Woluwe','VBR'),('BE','SUA','Suarlee','Suarlee','WNA'),('BE','SUZ','Somme-Leuze','Somme-Leuze','WNA'),('BE','SVE','Stavele','Stavele','VWV'),('BE','SVG','Ruisbroek','Ruisbroek','VAN'),('BE','SVH','St Vith','St Vith','WLG'),('BE','SVI','Serville','Serville','WNA'),('BE','SVN','Stevensvennen','Stevensvennen','VLI'),('BE','SVO','Smeerebbe-Vloerzegem','Smeerebbe-Vloerzegem','VOV'),('BE','SVR','Stevoort','Stevoort','VLI'),('BE','SXY','Suxy','Suxy','WLX'),('BE','SYP','Slijpe','Slijpe','VWV'),('BE','SYR','Sivry-Rance','Sivry-Rance','WHT'),('BE','SZE','Somzee','Somzee','WNA'),('BE','SZI','Salzinnes','Salzinnes','WNA'),('BE','TAP','Theux','Theux','WLG'),('BE','TBE','Tournebride','Tournebride','VLI'),('BE','TBZ','Tubize','Tubize','WBR'),('BE','TCI','Tarcienne','Tarcienne','WNA'),('BE','TCL','Thimister-Clermont','Thimister-Clermont','WLG'),('BE','TDK','Terdonk','Terdonk','VOV'),('BE','TEN','Tervuren','Tervuren','VBR'),('BE','TER','Ternat','Ternat','VBR'),('BE','TES','Tessenderlo','Tessenderlo','VLI'),('BE','TET','Tertre','Tertre','WHT'),('BE','TEU','Teuven','Teuven','VLI'),('BE','TFN','Teralfene','Teralfene','VBR'),('BE','TGE','Tergnee','Tergnee','WHT'),('BE','TGL','Tongerlo','Tongerlo','VLI'),('BE','TGN','Terhagen','Terhagen','VAN'),('BE','THE','Thieu','Thieu','WHT'),('BE','THG','Tihange','Tihange','WLG'),('BE','THI','Thines','Thines','WBR'),('BE','THL','Thulin','Thulin','WHT'),('BE','THO','Thommen','Thommen','WLG'),('BE','THU','Thuin','Thuin','WHT'),('BE','THY','Thy-le-Chateau','Thy-le-Chateau','WNA'),('BE','TIE','Tienen','Tienen','VBR'),('BE','TIG','Tiegem','Tiegem','VWV'),('BE','TIL','Tielrode','Tielrode','VOV'),('BE','TIS','Tisselt','Tisselt','VAN'),('BE','TLA','Thieulain','Thieulain','WHT'),('BE','TLI','Tellin','Tellin','WLX'),('BE','TLK','Tildonk','Tildonk','VBR'),('BE','TLO','Tinlot','Tinlot','WLG'),('BE','TLR','Tilleur','Tilleur','WLG'),('BE','TLS','Tailles','Tailles','WLX'),('BE','TLT','Tielt','Tielt','VWV'),('BE','TMA','Thumaide','Thumaide','WHT'),('BE','TMO','Tremelo','Tremelo','VBR'),('BE','TMS','Tamines','Tamines','WNA'),('BE','TND','Tongre-Notre-Dame','Tongre-Notre-Dame','WHT'),('BE','TOH','Tohogne','Tohogne','WLX'),('BE','TON','Tongeren','Tongeren','VLI'),('BE','TPO','Trois-Ponts','Trois-Ponts','WLG'),('BE','TPU','Templeuve','Templeuve','WHT'),('BE','TPX','Temploux','Temploux','WNA'),('BE','TRE','Termes','Termes','WLX'),('BE','TRI','Tourinne','Tourinne','WLG'),('BE','TRN','Doornik (Tournai)','Doornik (Tournai)','WHT'),('BE','TRO','Trooz','Trooz','WLG'),('BE','TRT','Torhout','Torhout','VWV'),('BE','TSE','Temse','Temse','VOV'),('BE','TSI','Thieusies','Thieusies','WHT'),('BE','TTI','Taintignies','Taintignies','WHT'),('BE','TTL','Tielt','Tielt','VBR'),('BE','TTT','Testelt','Testelt','VBR'),('BE','TTY','Tintigny','Tintigny','WLX'),('BE','TUG','Thimougies','Thimougies','WHT'),('BE','TUL','Thuillies','Thuillies','WHT'),('BE','TUP','Tourpes','Tourpes','WHT'),('BE','TUR','Turnhout','Turnhout','VAN'),('BE','TVI','Tavier','Tavier','WLG'),('BE','TVL','Tenneville','Tenneville','WLX'),('BE','TVY','Tavigny','Tavigny','WLX'),('BE','TWI','Tielt-Winge','Tielt-Winge','VBR'),('BE','TYS','Thynes','Thynes','WNA'),('BE','TZI','Trazegnies','Trazegnies','WHT'),('BE','UCI','Ucimont','Ucimont','WLX'),('BE','UIT','Uitbergen','Uitbergen','VOV'),('BE','UKE','Uccle (Ukkel)/Brussel (Bruxelles)','Uccle (Ukkel)/Brussel (Bruxelles)','BRU'),('BE','UKO','Uikhoven','Uikhoven','VLI'),('BE','ULB','Ulbeek','Ulbeek','VLI'),('BE','VAT','Villers-aux-Tours','Villers-aux-Tours','WLG'),('BE','VBE','Vaalbeek','Vaalbeek','VBR'),('BE','VBG','Verbrande Brug','Verbrande Brug','VBR'),('BE','VBK','Verrebroek','Verrebroek','VOV'),('BE','VBO','Villers-le-Bouillet','Villers-le-Bouillet','WLG'),('BE','VCE','Vance','Vance','WLX'),('BE','VDE','Vremde','Vremde','VAN'),('BE','VDI','Vedrin','Vedrin','WNA'),('BE','VDO','Vinderhoute','Vinderhoute','VOV'),('BE','VEA','Velaine-sur-Sambre','Velaine-sur-Sambre','WNA'),('BE','VEL','Veerle','Veerle','VAN'),('BE','VER','Verviers','Verviers','WLG'),('BE','VEU','Veurne','Veurne','VWV'),('BE','VGA','Vieux-Genappe','Vieux-Genappe','WBR'),('BE','VGL','Virginal-Samme','Virginal-Samme','WBR'),('BE','VHN','Vroenhoven','Vroenhoven','VLI'),('BE','VIC','Vichte','Vichte','VWV'),('BE','VIL','Vilvoorde','Vilvoorde','VBR'),('BE','VIR','Virton','Virton','WLX'),('BE','VIS','Vise','Vise','WLG'),('BE','VIV','Vivegnis','Vivegnis','WLG'),('BE','VIY','Vivy','Vivy','WLX'),('BE','VLA','Verlaine','Verlaine','WLG'),('BE','VLE','Vleteren','Vleteren','VWV'),('BE','VLI','Voroux-lez-Liers','Voroux-lez-Liers','WLG'),('BE','VLL','Vollezele','Vollezele','VBR'),('BE','VLM','Velm','Velm','VLI'),('BE','VLO','Villerot','Villerot','WHT'),('BE','VLV','Villers-la-Ville','Villers-la-Ville','WBR'),('BE','VLX','Vaulx','Vaulx','WHT'),('BE','VMA','Vliermaal','Vliermaal','VLI'),('BE','VME','Voormezele','Voormezele','VWV'),('BE','VMI','Vlamertinge','Vlamertinge','VWV'),('BE','VMO','Vliermaalroot','Vliermaalroot','VLI'),('BE','VMT','Vinalmont','Vinalmont','WLG'),('BE','VNO','Villers-Notre-Dame','Villers-Notre-Dame','WHT'),('BE','VOE','Voeren','Voeren','VLI'),('BE','VOL','Vorselaar','Vorselaar','VAN'),('BE','VOR','Vosselaar','Vosselaar','VAN'),('BE','VOS','Forest (Vorst)/Brussel (Bruxelles)','Forest (Vorst)/Brussel (Bruxelles)','BRU'),('BE','VPO','Ville-Pommeroeul','Ville-Pommeroeul','WHT'),('BE','VRD','Varendonk','Varendonk','VAN'),('BE','VRE','Virelles','Virelles','WHT'),('BE','VRO','Viroinval','Viroinval','WNA'),('BE','VSA','Villers-Saint-Amand','Villers-Saint-Amand','WHT'),('BE','VSB','Val St-Lambert','Val St-Lambert','WLG'),('BE','VSC','Vaux-sous-Chevremont','Vaux-sous-Chevremont','WLG'),('BE','VSE','Vlissegem','Vlissegem','VWV'),('BE','VSG','Villers-Sainte-Gertrude','Villers-Sainte-Gertrude','WLX'),('BE','VSH','Ville-sur-Haine','Ville-sur-Haine','WHT'),('BE','VSI','Villers-Saint-Ghislain','Villers-Saint-Ghislain','WHT'),('BE','VSL','Viersel','Viersel','VAN'),('BE','VSM','Vielsalm','Vielsalm','WLX'),('BE','VSN','Vrasene','Vrasene','VOV'),('BE','VSO','Vresse-sur-Semois','Vresse-sur-Semois','WNA'),('BE','VSS','Villers-Saint-Simeon','Villers-Saint-Simeon','WLG'),('BE','VSU','Vaux-sur-Sure','Vaux-sur-Sure','WLX'),('BE','VVI','Viesville','Viesville','WHT'),('BE','VVO','Villers-devant-Orval','Villers-devant-Orval','WLX'),('BE','VWZ','Veldwezelt','Veldwezelt','VLI'),('BE','VZB','Vlezenbeek','Vlezenbeek','VBR'),('BE','VZI','Vezin','Vezin','WNA'),('BE','VZO','Vezon','Vezon','WHT'),('BE','WAA','Waasmunster','Waasmunster','VOV'),('BE','WAB','Wauthier-Braine','Wauthier-Braine','WBR'),('BE','WAK','Wakken','Wakken','VWV'),('BE','WAL','Waterloo','Waterloo','WBR'),('BE','WAM','Waarmaarde','Waarmaarde','VWV'),('BE','WAN','Wanze','Wanze','WLG'),('BE','WAR','Waregem','Waregem','VWV'),('BE','WAY','Ways','Ways','WBR'),('BE','WBE','Wachtebeke','Wachtebeke','VOV'),('BE','WBK','Wambeek','Wambeek','VBR'),('BE','WBQ','Wannebecq','Wannebecq','WHT'),('BE','WBU','Wanfercee-Baulet','Wanfercee-Baulet','WHT'),('BE','WBV','Watermaal-Bosvoorde (Watermael-Boitsfort)/Brussel (Bruxelles)','Watermaal-Bosvoorde (Watermael-Boitsfort)/Brussel (Bruxelles)','BRU'),('BE','WCE','Werchter','Werchter','VBR'),('BE','WCG','Warcoing','Warcoing','WHT'),('BE','WCO','Walcourt','Walcourt','WNA'),('BE','WDE','Waudrez','Waudrez','WHT'),('BE','WDG','Wondelgem','Wondelgem','VOV'),('BE','WDN','Wilderen','Wilderen','VLI'),('BE','WED','Weelde','Weelde','VAN'),('BE','WEE','Wingene','Wingene','VWV'),('BE','WEK','Wilskerke','Wilskerke','VWV'),('BE','WEL','Wellen','Wellen','VLI'),('BE','WEN','Wezeren','Wezeren','VBR'),('BE','WER','Wervik','Wervik','VWV'),('BE','WES','Westerlo','Westerlo','VAN'),('BE','WET','Wetteren','Wetteren','VOV'),('BE','WEV','Wevelgem','Wevelgem','VWV'),('BE','WGE','Wagnelee','Wagnelee','WHT'),('BE','WGH','Wihogne','Wihogne','WLG'),('BE','WGL','Wijgmaal','Wijgmaal','VBR'),('BE','WHA','Walhain','Walhain','WBR'),('BE','WHI','Warchin','Warchin','WHT'),('BE','WHO','Walshoutem','Walshoutem','VBR'),('BE','WHR','Walhorn','Walhorn','WLG'),('BE','WHZ','Wechelderzande','Wechelderzande','VAN'),('BE','WIB','Wibrin','Wibrin','WLX'),('BE','WID','Wierde','Wierde','WNA'),('BE','WIE','Wieze','Wieze','VOV'),('BE','WIH','Wichelen','Wichelen','VOV'),('BE','WIK','Wielsbeke','Wielsbeke','VWV'),('BE','WIL','Wilrijk','Wilrijk','VAN'),('BE','WIM','Waimes','Waimes','WLG'),('BE','WIN','Wellin','Wellin','WLX'),('BE','WIP','Wepion','Wepion','WNA'),('BE','WIR','Wiers','Wiers','WHT'),('BE','WIS','Wiesme','Wiesme','WNA'),('BE','WJG','Wijnegem','Wijnegem','VAN'),('BE','WKD','Welkenraedt','Welkenraedt','WLG'),('BE','WKE','Waarbeke','Waarbeke','VOV'),('BE','WKO','Wezembeek-Oppem','Wezembeek-Oppem','VBR'),('BE','WLB','Willebroek','Willebroek','VAN'),('BE','WLE','Wannegem-Lede','Wannegem-Lede','VOV'),('BE','WLI','Wadelincourt','Wadelincourt','WHT'),('BE','WLL','Welle','Welle','VOV'),('BE','WLM','Walem','Walem','VAN'),('BE','WLN','Weillen','Weillen','WNA'),('BE','WLP','Wulpen','Wulpen','VWV'),('BE','WLT','Waulsort','Waulsort','WNA'),('BE','WMA','Willemeau','Willemeau','WHT'),('BE','WME','Westmalle','Westmalle','VAN'),('BE','WML','Wemmel','Wemmel','VBR'),('BE','WMM','Wommelgem','Wommelgem','VAN'),('BE','WMO','Waasmont','Waasmont','VBR'),('BE','WNA','Warnant','Warnant','WNA'),('BE','WND','Wandre','Wandre','WLG'),('BE','WNI','Wanlin','Wanlin','WNA'),('BE','WNZ','Wegnez','Wegnez','WLG'),('BE','WOM','Wortegem','Wortegem','VOV'),('BE','WOR','Wortel','Wortel','VAN'),('BE','WOU','Waterland-Oudeman','Waterland-Oudeman','VOV'),('BE','WOV','Wolvertem','Wolvertem','VBR'),('BE','WPE','Wortegem-Petegem','Wortegem-Petegem','VOV'),('BE','WPU','Willaupuis','Willaupuis','WHT'),('BE','WRD','Weerde','Weerde','VBR'),('BE','WRE','Waremme','Waremme','WLG'),('BE','WRL','Waarloos','Waarloos','VAN'),('BE','WRO','Waanrode','Waanrode','VBR'),('BE','WSA','Warsage','Warsage','WLG'),('BE','WSB','Westmeerbeek','Westmeerbeek','VAN'),('BE','WSE','Walsbets','Walsbets','VBR'),('BE','WSI','Wasseiges','Wasseiges','WLG'),('BE','WSL','Wilsele','Wilsele','VBR'),('BE','WSM','Westrem','Westrem','VOV'),('BE','WSO','Waarschoot','Waarschoot','VOV'),('BE','WST','Westrozebeke','Westrozebeke','VWV'),('BE','WSU','Westouter','Westouter','VWV'),('BE','WTE','Westende','Westende','VWV'),('BE','WTH','Wintham','Wintham','VAN'),('BE','WTI','Wimmertingen','Wimmertingen','VLI'),('BE','WTO','Wintershoven','Wintershoven','VLI'),('BE','WTU','Watou','Watou','VWV'),('BE','WUB','Wasmes-Audemez-Briffoeil','Wasmes-Audemez-Briffoeil','WHT'),('BE','WUU','Wuustwezel','Wuustwezel','VAN'),('BE','WUV','Wulvergem','Wulvergem','VWV'),('BE','WVI','Watervliet','Watervliet','VOV'),('BE','WVO','Wiekevorst','Wiekevorst','VAN'),('BE','WVR','Wavre','Wavre','WBR'),('BE','WYT','Wijtschate','Wijtschate','VWV'),('BE','WZE','Wezemaal','Wezemaal','VBR'),('BE','WZL','Wezel','Wezel','VAN'),('BE','XDA','Xhendremael','Xhendremael','WLG'),('BE','XDE','Xhendelesse','Xhendelesse','WLG'),('BE','YRT','Ivoz-Ramet','Ivoz-Ramet','WLG'),('BE','YVO','Yvoir','Yvoir','WNA'),('BE','YZO','Laakdal','Laakdal','VLI'),('BE','ZAN','Zandhoven','Zandhoven','VAN'),('BE','ZAV','Zaventem','Zaventem','VBR'),('BE','ZBR','Zandbergen','Zandbergen','VOV'),('BE','ZED','Zedelgem','Zedelgem','VWV'),('BE','ZEE','Zeebrugge','Zeebrugge','VWV'),('BE','ZEL','Zelzate','Zelzate','VOV'),('BE','ZER','Seraing','Seraing','WLG'),('BE','ZET','Zemst','Zemst','VBR'),('BE','ZGM','Zingem','Zingem','VOV'),('BE','ZHV','Zonhoven','Zonhoven','VLI'),('BE','ZIB','Zillebeke','Zillebeke','VWV'),('BE','ZIC','Zichem','Zichem','VBR'),('BE','ZKE','Zuienkerke','Zuienkerke','VWV'),('BE','ZLE','Zele','Zele','VOV'),('BE','ZLL','Zellik','Zellik','VBR'),('BE','ZOB','Zonnebeke','Zonnebeke','VWV'),('BE','ZOD','Zolder','Zolder','VLI'),('BE','ZOT','Zottegem','Zottegem','VOV'),('BE','ZOU','Zoutleeuw','Zoutleeuw','VBR'),('BE','ZRM','Zomergem','Zomergem','VOV'),('BE','ZRN','Zarren','Zarren','VWV'),('BE','ZSO','Zuidschote','Zuidschote','VWV'),('BE','ZTL','Zutendaal','Zutendaal','VLI'),('BE','ZUL','Zulte','Zulte','VOV'),('BE','ZUN','Zuen (Zuun)','Zuen (Zuun)','VBR'),('BE','ZVD','Zandvoorde','Zandvoorde','VWV'),('BE','ZVT','Zandvliet','Zandvliet','VAN'),('BE','ZWA','Zwalm','Zwalm','VOV'),('BE','ZWE','Zwevegem','Zwevegem','VWV'),('BE','ZWL','Zwijndrecht','Zwijndrecht','VAN'),('BE','ZWN','Zwijnaarde','Zwijnaarde','VOV'),('BF','','','',''),('BF','ABD','Aribinda','Aribinda',''),('BF','ARL','Arly','Arly',''),('BF','BER','Beregadougou','Beregadougou',''),('BF','BNR','Banfora','Banfora',''),('BF','BOG','Bogande','Bogande',''),('BF','BOU','Boulsa','Boulsa',''),('BF','BOY','Bobo-Dioulasso','Bobo-Dioulasso',''),('BF','DBG','Diebougou','Diebougou',''),('BF','DGU','Dedougou','Dedougou',''),('BF','DIP','Diapaga','Diapaga',''),('BF','DJI','Djibo','Djibo',''),('BF','DOR','Dori','Dori',''),('BF','FNG','Fada-Ngourma','Fada-Ngourma',''),('BF','GAO','Gaoua','Gaoua',''),('BF','GOG','Gorom-Gorom','Gorom-Gorom',''),('BF','KAN','Kantchari','Kantchari',''),('BF','KAY','Kaya','Kaya',''),('BF','KOR','Kourouma','Kourouma',''),('BF','KOS','Kossodo','Kossodo',''),('BF','KOU','Koudougou','Koudougou',''),('BF','LEO','Leo','Leo',''),('BF','NOU','Nouna','Nouna',''),('BF','OUA','Ouagadougou','Ouagadougou',''),('BF','OUG','Ouahigouya','Ouahigouya',''),('BF','PAM','Pama','Pama',''),('BF','POU','Poura','Poura',''),('BF','PUP','Po','Po',''),('BF','SAP','Sapone','Sapone',''),('BF','SEB','Sebba','Sebba',''),('BF','TEG','Tenkodogo','Tenkodogo',''),('BF','TMQ','Tambao','Tambao',''),('BF','TUQ','Tougan','Tougan',''),('BF','ZAB','Zabre','Zabre',''),('BF','ZIG','Ziga','Ziga',''),('BG','','','',''),('BG','AKH','Akhtopol','Akhtopol',''),('BG','AND','Asenovgrad','Asenovgrad',''),('BG','BAL','Balchik','Balchik',''),('BG','BAO','Bansko','Bansko',''),('BG','BLN','Blagoevgrad','Blagoevgrad',''),('BG','BOJ','Burgas','Burgas',''),('BG','BRE','Bregovo','Bregovo',''),('BG','BRF','Botevgrad','Botevgrad',''),('BG','BRK','Berkovitza','Berkovitza',''),('BG','BRV','Borovo','Borovo',''),('BG','BSL','Byala Slatina','Byala Slatina',''),('BG','BVO','Banevo','Banevo',''),('BG','CHR','Chakalarevo','Chakalarevo',''),('BG','CPA','Chepelare','Chepelare',''),('BG','CPW','Chirpan','Chirpan',''),('BG','DBS','Debelec','Debelec',''),('BG','DKC','Dolna Oryakhovitsa','Dolna Oryakhovitsa',''),('BG','DKO','Durankulak','Durankulak',''),('BG','DLC','Delchevo','Delchevo',''),('BG','DLV','Dulovo','Dulovo',''),('BG','DMN','Dragoman','Dragoman',''),('BG','DNJ','Devnya','Devnya',''),('BG','DNV','Dryanovo','Dryanovo',''),('BG','DOD','Dobrich','Dobrich',''),('BG','DSP','Dospat','Dospat',''),('BG','DTG','Dimitrovgrad','Dimitrovgrad',''),('BG','DUP','Dupnica','Dupnica',''),('BG','EHO','Elkhovo','Elkhovo',''),('BG','EPE','Elin Pelin','Elin Pelin',''),('BG','ETS','Etropole','Etropole',''),('BG','GAV','Gabrovo','Gabrovo',''),('BG','GDU','Gotse Delchev','Gotse Delchev',''),('BG','GJE','Gyueshevo','Gyueshevo',''),('BG','GOZ','Gorna Oryakhovitsa','Gorna Oryakhovitsa',''),('BG','HKV','Haskovo','Haskovo',''),('BG','HMI','Kharmanli','Kharmanli',''),('BG','IHT','Ikhtiman','Ikhtiman',''),('BG','IOV','Iovkovo','Iovkovo',''),('BG','IPR','Isperikh','Isperikh',''),('BG','IVL','Ivailovgrad','Ivailovgrad',''),('BG','JAK','Rakitovo','Rakitovo',''),('BG','JAM','Jambol','Jambol',''),('BG','KAL','Kalotina','Kalotina',''),('BG','KAN','Kapitan-Andreevo','Kapitan-Andreevo',''),('BG','KAR','Kardam','Kardam',''),('BG','KBT','Karnobat','Karnobat',''),('BG','KDG','Kurdzhali','Kurdzhali',''),('BG','KHK','Khan Krum','Khan Krum',''),('BG','KHO','Khaskovo','Khaskovo',''),('BG','KJG','Kjustendil','Kjustendil',''),('BG','KOL','Kulata','Kulata',''),('BG','KOS','Kostenets','Kostenets',''),('BG','KPH','Kaspichan','Kaspichan',''),('BG','KRH','Krushari','Krushari',''),('BG','KRM','Kardzali','Kardzali',''),('BG','KVN','Kavarna','Kavarna',''),('BG','KVO','Karlovo','Karlovo',''),('BG','KYS','Kyustendil','Kyustendil',''),('BG','KZN','Kazanluk','Kazanluk',''),('BG','LKI','Laki','Laki',''),('BG','LKS','Lyaskovets','Lyaskovets',''),('BG','LMC','Lyubimets','Lyubimets',''),('BG','LOM','Lom','Lom',''),('BG','LSD','Levski','Levski',''),('BG','LVP','Lovech','Lovech',''),('BG','MEL','Melnik','Melnik',''),('BG','MIC','Michurin','Michurin',''),('BG','MIZ','Miziya','Miziya',''),('BG','MOT','Momchilgrad','Momchilgrad',''),('BG','MTI','Malko Tarnovo','Malko Tarnovo',''),('BG','MUC','Musachevo','Musachevo',''),('BG','NES','Nessebar','Nessebar',''),('BG','NIS','Novi Isar','Novi Isar',''),('BG','NPO','Nikopol','Nikopol',''),('BG','NPZ','Novi Pazar','Novi Pazar',''),('BG','NZG','Nova Zagora','Nova Zagora',''),('BG','OKH','Oryakhovo','Oryakhovo',''),('BG','OLT','Oltomantsi','Oltomantsi',''),('BG','OMU','Omurtag','Omurtag',''),('BG','OPK','Opaka','Opaka',''),('BG','ORE','Orehovo','Orehovo',''),('BG','OZA','Montana','Montana',''),('BG','OZD','Samovodene','Samovodene',''),('BG','PDA','Provadiya','Provadiya',''),('BG','PDV','Plovdiv','Plovdiv',''),('BG','PEC','Peshtera','Peshtera',''),('BG','PEG','Petrich','Petrich',''),('BG','PIR','Pirdop','Pirdop',''),('BG','PIV','Pavlikeni','Pavlikeni',''),('BG','PNZ','Pernik','Pernik',''),('BG','POK','Popovo','Popovo',''),('BG','POR','Pomorie','Pomorie',''),('BG','PRS','Perushtitsa','Perushtitsa',''),('BG','PSC','Preslav','Preslav',''),('BG','PVL','Pavel','Pavel',''),('BG','PVN','Pleven','Pleven',''),('BG','PZA','Pazardzhik','Pazardzhik',''),('BG','RAZ','Razlog','Razlog',''),('BG','RDI','Radomir','Radomir',''),('BG','RDU','Ruse','Ruse',''),('BG','RDV','Radnevo','Radnevo',''),('BG','RGL','Razgrad','Razgrad',''),('BG','ROU','Ruse','Ruse',''),('BG','SAM','Samokov','Samokov',''),('BG','SBP','Sopot','Sopot',''),('BG','SDM','Sandanski','Sandanski',''),('BG','SDV','Stanke Dimitrov','Stanke Dimitrov',''),('BG','SLI','Stanke Lisitchkovo','Stanke Lisitchkovo',''),('BG','SLP','Sliven','Sliven',''),('BG','SLS','Silistra','Silistra',''),('BG','SLU','Sevlievo','Sevlievo',''),('BG','SML','Smolyan','Smolyan',''),('BG','SMN','Shumen','Shumen',''),('BG','SNA','Surnitsa','Surnitsa',''),('BG','SOF','Sofia','Sofia',''),('BG','SOM','Somovit','Somovit',''),('BG','SOZ','Sozopol','Sozopol',''),('BG','SUW','Shumen','Shumen',''),('BG','SUZ','Suhindol','Suhindol',''),('BG','SVG','Svoge','Svoge',''),('BG','SVI','Svistov','Svistov',''),('BG','SWG','Svilengrad','Svilengrad',''),('BG','SWQ','Slavyantsi','Slavyantsi',''),('BG','SZR','Stara Zagora','Stara Zagora',''),('BG','TGA','Topolovgrad','Topolovgrad',''),('BG','TGV','Targoviste','Targoviste',''),('BG','TJM','Trojan','Trojan',''),('BG','TOL','Tolbuhin','Tolbuhin',''),('BG','TRA','Tryavna','Tryavna',''),('BG','TRP','Tutrakan','Tutrakan',''),('BG','TRY','Troyan','Troyan',''),('BG','TTV','Teteven','Teteven',''),('BG','VAR','Varna','Varna',''),('BG','VAZ','Varna-Zapad','Varna-Zapad',''),('BG','VID','Vidin','Vidin',''),('BG','VLE','Velingrad','Velingrad',''),('BG','VNT','Venets','Venets',''),('BG','VRE','Vraca','Vraca',''),('BG','VTC','Vrska Cuka','Vrska Cuka',''),('BG','VTT','Veliko Tarnovo','Veliko Tarnovo',''),('BG','YAM','Yambol','Yambol',''),('BG','ZLA','Zlatarevo','Zlatarevo',''),('BG','ZLH','Zlatograd','Zlatograd',''),('BH','','','',''),('BH','BAH','Bahrain','Bahrain',''),('BH','JUF','Al Jufayr','Al Jufayr',''),('BH','MAN','Manama','Manama',''),('BH','MIN','Mina Sulman','Mina Sulman',''),('BH','RAS','Al Mutae','Al Mutae',''),('BH','SIT','Sitra','Sitra',''),('BI','','','',''),('BI','BBZ','Bubanza','Bubanza',''),('BI','BJM','Bujumbura','Bujumbura',''),('BI','BRR','Bururi','Bururi',''),('BI','CBK','Cibitoke','Cibitoke',''),('BI','GID','Gitega','Gitega',''),('BI','KRE','Kirundo','Kirundo',''),('BI','MYG','Muyinga','Muyinga',''),('BI','NGZ','Ngozi','Ngozi',''),('BJ','','','',''),('BJ','AGT','Agbanta','Agbanta',''),('BJ','BOH','Bohicon','Bohicon',''),('BJ','COO','Cotonou','Cotonou',''),('BJ','DJA','Djougou','Djougou',''),('BJ','GLA','Glazoue','Glazoue',''),('BJ','KDC','Kandi','Kandi',''),('BJ','NAE','Natitingou','Natitingou',''),('BJ','PKO','Parakou','Parakou',''),('BJ','PTN','Porto-Novo','Porto-Novo',''),('BJ','SEM','Seme Terminal','Seme Terminal',''),('BJ','SVF','Save','Save',''),('BJ','TAN','Tanguieta','Tanguieta',''),('BM','','','',''),('BM','BDA','Hamilton','Hamilton',''),('BM','FPT','Freeport','Freeport',''),('BM','HBI','Harbour Island','Harbour Island',''),('BM','SGE','Saint George','Saint George',''),('BN','','','',''),('BN','BWN','Bandar Seri Begawan','Bandar Seri Begawan',''),('BN','KUB','Kuala Belait','Kuala Belait',''),('BN','LUM','Lumut','Lumut',''),('BN','MUA','Muara','Muara',''),('BN','SER','Seria','Seria',''),('BN','TAS','Tanjong Salirong','Tanjong Salirong',''),('BO','','','',''),('BO','APB','Apolo','Apolo','L'),('BO','ASC','Ascension','Ascension','S'),('BO','BJO','Bermejo','Bermejo','T'),('BO','BVK','Huacaraje','Huacaraje','B'),('BO','BVL','Baures','Baures','B'),('BO','BYC','Yacuiba','Yacuiba','T'),('BO','CAM','Camiri','Camiri','S'),('BO','CBB','Cochabamba','Cochabamba','C'),('BO','CEP','Concepcion','Concepcion','S'),('BO','CIJ','Cobija','Cobija','N'),('BO','GUQ','Guaqui','Guaqui','L'),('BO','GYA','Guayaramerin','Guayaramerin','B'),('BO','LPB','La Paz','La Paz','L'),('BO','MGD','Magdalena','Magdalena','B'),('BO','ORU','Oruro','Oruro','O'),('BO','PBU','Puerto Busch','Puerto Busch','S'),('BO','POI','Potosi','Potosi','P'),('BO','PSZ','Puerto Suarez','Puerto Suarez','S'),('BO','PUR','Puerto Rico','Puerto Rico','N'),('BO','QJR','Puerto Quijarro','Puerto Quijarro','S'),('BO','RBO','Robore','Robore','S'),('BO','RBQ','Rurrenabaque','Rurrenabaque','B'),('BO','REY','Reyes','Reyes','B'),('BO','RIB','Riberalta','Riberalta','B'),('BO','SBL','Santa Ana','Santa Ana','B'),('BO','SJB','San Joaquin','San Joaquin','B'),('BO','SJS','San Jose','San Jose','S'),('BO','SJV','San Javier','San Javier','S'),('BO','SNG','San Ignacio de Velasco','San Ignacio de Velasco','S'),('BO','SNM','San Ignacio de Moxo','San Ignacio de Moxo','B'),('BO','SRB','Santa Rosa','Santa Rosa',''),('BO','SRD','San Ramon','San Ramon','B'),('BO','SRE','Sucre','Sucre','H'),('BO','SRJ','San Borja','San Borja','B'),('BO','SRZ','Santa Cruz','Santa Cruz','L'),('BO','TDD','Trinidad','Trinidad','B'),('BO','TJA','Tarija','Tarija','T'),('BO','VAH','Vallegrande','Vallegrande','S'),('BO','VLM','Villamontes','Villamontes','T'),('BO','VVI','Viru Viru','Viru Viru','H'),('BR','','','',''),('BR','AAA','Aracuai','Aracuai','MG'),('BR','AAG','Arapoti','Arapoti','PR'),('BR','AAI','Arraias','Arraias','TO'),('BR','AAN','Andradina','Andradina','SP'),('BR','AAX','Araxa','Araxa','MG'),('BR','ABA','Atibaia','Atibaia','SP'),('BR','ABI','Americo Brasiliense','Americo Brasiliense','SP'),('BR','ABO','Agua Boa','Agua Boa','MG'),('BR','ABT','Abaete','Abaete','MG'),('BR','ABZ','Armacao de Buzios','Armacao de Buzios','RJ'),('BR','ACA','Araucaria','Araucaria','PR'),('BR','ACB','Arraial do Cabo','Arraial do Cabo','RJ'),('BR','ACD','Assis Chateaubriand','Assis Chateaubriand','PR'),('BR','ACL','Acailandia','Acailandia','MA'),('BR','ACN','Acreuna','Acreuna','GO'),('BR','ACP','Americo de Campos','Americo de Campos','SP'),('BR','ACR','Acari','Acari','RN'),('BR','ACS','Antonio Carlos','Antonio Carlos','SC'),('BR','ACT','Alcantara','Alcantara','MA'),('BR','ACU','Acarau','Acarau','CE'),('BR','ACZ','Aracruz','Aracruz','ES'),('BR','ADI','Afogados da Ingazeira','Afogados da Ingazeira','PE'),('BR','ADJ','Arraial','Arraial','BA'),('BR','ADL','Abelardo Luz','Abelardo Luz','SC'),('BR','ADO','Areado','Areado','MG'),('BR','ADR','Angra dos Reis','Angra dos Reis','RJ'),('BR','AEI','Areia','Areia','PB'),('BR','AFC','Afonso Claudio','Afonso Claudio','ES'),('BR','AFL','Alta Floresta','Alta Floresta','MT'),('BR','AFM','Auriflama','Auriflama','SP'),('BR','AFO','Alta Floresta do Oeste','Alta Floresta do Oeste','RO'),('BR','AFU','Afua','Afua','PA'),('BR','AGC','Agua Clara','Agua Clara','MS'),('BR','AGD','Agudos','Agudos','SP'),('BR','AGI','Aparecida de Goiania','Aparecida de Goiania','GO'),('BR','AGL','Aguas de Lindoia','Aguas de Lindoia','SP'),('BR','AGO','Agudo','Agudo','RS'),('BR','AGR','Alto Garcas','Alto Garcas','MT'),('BR','AGS','Alagoinhas','Alagoinhas',''),('BR','AGT','Angatuba','Angatuba','SP'),('BR','AGU','Aguai','Aguai','SP'),('BR','AGZ','Araguapaz','Araguapaz','GO'),('BR','AHI','Anchieta','Anchieta','ES'),('BR','AIA','Andira','Andira','PR'),('BR','AIC','Angelica','Angelica','MS'),('BR','AIF','Assis','Assis','SP'),('BR','AIP','Araripina','Araripina','PE'),('BR','AIR','Aripuana','Aripuana','MT'),('BR','AJE','Santo Antonio de Jesus','Santo Antonio de Jesus','BA'),('BR','AJO','Antonio Joao','Antonio Joao','MS'),('BR','AJU','Aracaju','Aracaju','SE'),('BR','ALC','Alcobaca','Alcobaca','BA'),('BR','ALF','Alfenas','Alfenas','MG'),('BR','ALG','Alegre','Alegre','ES'),('BR','ALI','Acailandia','Acailandia','MG'),('BR','ALM','Abreu e Lima','Abreu e Lima','PE'),('BR','ALO','Aloandia','Aloandia','GO'),('BR','ALP','Alpinopolis','Alpinopolis','MG'),('BR','ALQ','Alegrete','Alegrete','RS'),('BR','ALT','Alenquer','Alenquer','PA'),('BR','ALU','Alumar','Alumar','MA'),('BR','AMA','Araruama','Araruama','RJ'),('BR','AMB','Amambai','Amambai','MS'),('BR','AME','Americana','Americana','SP'),('BR','AMH','Alvares Machado','Alvares Machado','SP'),('BR','AMI','Arroio do Meio','Arroio do Meio','RS'),('BR','AMJ','Almenara','Almenara','MG'),('BR','AMM','Almeirim','Almeirim','PA'),('BR','AMO','Aluminio','Aluminio','SP'),('BR','AMP','Amparo','Amparo','SP'),('BR','AMR','Aguas Mornas','Aguas Mornas','SC'),('BR','AMS','Aimores','Aimores','MG'),('BR','AMT','Adamantina','Adamantina','SP'),('BR','ANA','Ananindeua','Ananindeua','PA'),('BR','ANC','Anicuns','Anicuns','GO'),('BR','ANG','Artur Nogueira','Artur Nogueira','SP'),('BR','ANI','Analandia','Analandia','SP'),('BR','ANT','Antonina','Antonina','PR'),('BR','AOS','Arcos','Arcos','MG'),('BR','APA','Apiai','Apiai','SP'),('BR','APB','Alem Paraiba','Alem Paraiba','MG'),('BR','APE','Arembepe','Arembepe','BA'),('BR','APG','Alto Paraiso de Goias','Alto Paraiso de Goias','GO'),('BR','API','Aparecida','Aparecida','SP'),('BR','APL','Arenapolis','Arenapolis','MT'),('BR','APN','Alto Parana','Alto Parana','PR'),('BR','APO','Altinopolis','Altinopolis','SP'),('BR','APQ','Arapiraca','Arapiraca','AL'),('BR','APS','Anapolis','Anapolis','GO'),('BR','APU','Apucarana','Apucarana','PR'),('BR','APX','Arapongas','Arapongas','PR'),('BR','APY','Alto Parnaiba','Alto Parnaiba','MA'),('BR','AQA','Araraquara','Araraquara','SP'),('BR','AQD','Aquidauana','Aquidauana','MS'),('BR','AQI','Alto Piquiri','Alto Piquiri','PR'),('BR','AQM','Ariquemes','Ariquemes','RO'),('BR','AQR','Aquiraz','Aquiraz','CE'),('BR','ARA','Araras','Araras','SP'),('BR','ARB','Aratu','Aratu','BA'),('BR','ARC','Aiuruoca','Aiuruoca','MG'),('BR','ARD','Andradas','Andradas','MG'),('BR','ARE','Areia Branca','Areia Branca','RN'),('BR','ARG','Araguacu','Araguacu','TO'),('BR','ARH','Ariranha','Ariranha','SP'),('BR','ARI','Andarai','Andarai','BA'),('BR','ARJ','Amaraji','Amaraji','PE'),('BR','ARK','Aracas','Aracas','BA'),('BR','ARL','Areal','Areal','RJ'),('BR','ARM','Aracariguama','Aracariguama','SP'),('BR','ARN','Ararangua','Ararangua','SC'),('BR','ARO','Agrolandia','Agrolandia','SC'),('BR','ARP','Arapora','Arapora','MG'),('BR','ARR','Araguari','Araguari','MG'),('BR','ARS','Aragarcas','Aragarcas','GO'),('BR','ARU','Aracatuba','Aracatuba','SP'),('BR','ARV','Arcoverde','Arcoverde','PE'),('BR','ASB','Aguas de Santa Barbara','Aguas de Santa Barbara','SP'),('BR','ASG','Astorga','Astorga','PR'),('BR','ASI','Assai','Assai','PR'),('BR','ASO','Aguas de Sao Pedro','Aguas de Sao Pedro','SP'),('BR','ASP','Aguas da Prata','Aguas da Prata','SP'),('BR','ASR','Aracoiaba da Serra','Aracoiaba da Serra','SP'),('BR','ASU','Assu','Assu','RN'),('BR','ATB','Abaetetuba','Abaetetuba','PA'),('BR','ATC','Anastacio','Anastacio','MS'),('BR','ATD','Aparecida do Taboado','Aparecida do Taboado','MS'),('BR','ATG','Alto Araguaia','Alto Araguaia','MT'),('BR','ATI','Irati','Irati','PR'),('BR','ATL','Ataleia','Ataleia','MG'),('BR','ATM','Altamira','Altamira','PA'),('BR','ATN','Araputanga','Araputanga','MT'),('BR','ATO','Altonia','Altonia','PR'),('BR','ATQ','Alto Taquari','Alto Taquari','MT'),('BR','ATS','Alterosa','Alterosa','MG'),('BR','ATU','Catu','Catu','BA'),('BR','AUA','Apiuna','Apiuna','SC'),('BR','AUB','Itauba','Itauba','MT'),('BR','AUJ','Aruja','Aruja','SP'),('BR','AUN','Aruana','Aruana','GO'),('BR','AUX','Araguaina','Araguaina','TO'),('BR','AVA','Avare','Avare','SP'),('BR','AVB','Atilio Vivacqua','Atilio Vivacqua','ES'),('BR','AVN','Alvorada do Norte','Alvorada do Norte','GO'),('BR','AVR','Alvorada','Alvorada','RS'),('BR','AXE','Xanxere','Xanxere','SC'),('BR','AXN','Alexania','Alexania','GO'),('BR','BAR','Barra dos Coqueiros','Barra dos Coqueiros','SE'),('BR','BAT','Barretos','Barretos','SP'),('BR','BAU','Bauru','Bauru','SP'),('BR','BAY','Bayeux','Bayeux','PB'),('BR','BAZ','Barbelos','Barbelos','AM'),('BR','BBA','Bacabal','Bacabal','MA'),('BR','BBD','Bueno Brandao','Bueno Brandao','MG'),('BR','BBG','Barra do Bugres','Barra do Bugres','MT'),('BR','BBI','Beberibe','Beberibe','CE'),('BR','BBM','Borborema','Borborema','SP'),('BR','BBN','Breu Branco','Breu Branco','PA'),('BR','BBO','Barra Bonita','Barra Bonita','SP'),('BR','BBS','Bombinhas','Bombinhas','SC'),('BR','BCG','Barao de Cotigipe','Barao de Cotigipe','RS'),('BR','BCI','Barao de Cocais','Barao de Cocais','MG'),('BR','BCL','Brasilia Ceilandia','Brasilia Ceilandia','DF'),('BR','BCN','Barbacena','Barbacena','MG'),('BR','BCP','Bernardino de Campos','Bernardino de Campos','SP'),('BR','BDA','Santa Barbara do Para','Santa Barbara do Para','PR'),('BR','BDC','Barra do Corda','Barra do Corda','MA'),('BR','BDP','Bom Despacho','Bom Despacho','MG'),('BR','BDW','Brodowski','Brodowski','SP'),('BR','BEL','Belem','Belem','PA'),('BR','BFO','Baia Formosa','Baia Formosa','RN'),('BR','BGA','Barra Grande','Barra Grande','BA'),('BR','BGC','Biguacu','Biguacu','SC'),('BR','BGR','Brasilia Guara','Brasilia Guara','DF'),('BR','BGU','Bataguassu','Bataguassu','MS'),('BR','BGV','Bento Goncalves','Bento Goncalves','RS'),('BR','BGX','Bage','Bage','RS'),('BR','BHO','Brumadinho','Brumadinho','MG'),('BR','BHZ','Belo Horizonte','Belo Horizonte','MG'),('BR','BIA','Ibia','Ibia','MG'),('BR','BIR','Bariri','Bariri','SP'),('BR','BJA','Sao Borja','Sao Borja','RS'),('BR','BJB','Belo Jardim','Belo Jardim','PE'),('BR','BJG','Bom Jardim de Goias','Bom Jardim de Goias','GO'),('BR','BJI','Bom Jesus de Itabapoana','Bom Jesus de Itabapoana','RJ'),('BR','BJO','Bom Jesus dos Perdoes','Bom Jesus dos Perdoes','SP'),('BR','BJP','Braganca Paulista','Braganca Paulista','SP'),('BR','BJS','Bom Jesus de Goias','Bom Jesus de Goias','GO'),('BR','BLA','Bilac','Bilac','SP'),('BR','BLO','Beija-Flor','Beija-Flor','MG'),('BR','BMI','Brasilandia de Minas','Brasilandia de Minas','MG'),('BR','BMS','Brumado','Brumado','BA'),('BR','BNA','Bananal','Bananal','SP'),('BR','BNB','Brasilia - Nucleo Band','Brasilia - Nucleo Band','DF'),('BR','BNC','Braganca','Braganca','PA'),('BR','BND','Bandeirantes','Bandeirantes','PR'),('BR','BNO','Bonito','Bonito','PE'),('BR','BNT','Braco do Norte','Braco do Norte','SC'),('BR','BNU','Blumenau','Blumenau','SC'),('BR','BNV','Benedito Novo','Benedito Novo','SC'),('BR','BOC','Bocaina','Bocaina','SP'),('BR','BOR','Balneario do Rincao','Balneario do Rincao','SC'),('BR','BOS','Brotas','Brotas','SP'),('BR','BOV','Bocaiuva','Bocaiuva','MG'),('BR','BPG','Barra do Garcas','Barra do Garcas','MT'),('BR','BPI','Baependi','Baependi','MG'),('BR','BPP','Bom Principio','Bom Principio','RS'),('BR','BPS','Porto Seguro','Porto Seguro','BA'),('BR','BPT','Brasilia Planaltina','Brasilia Planaltina','DF'),('BR','BQA','Bodoquena','Bodoquena','MS'),('BR','BQQ','Barra','Barra','BA'),('BR','BQU','Boquim','Boquim','SE'),('BR','BRA','Barreiras','Barreiras','BA'),('BR','BRB','Barreirinhas','Barreirinhas','MA'),('BR','BRC','Barracao','Barracao','PR'),('BR','BRE','Boraceia','Boraceia','SP'),('BR','BRH','Barrinha','Barrinha','SP'),('BR','BRI','Barueri','Barueri','SP'),('BR','BRM','Buerarema','Buerarema','BA'),('BR','BRN','Brauna','Brauna','SP'),('BR','BRO','Barra do Ribeiro','Barra do Ribeiro','RS'),('BR','BRS','Barreiros','Barreiros','PE'),('BR','BRX','Belford Roxo','Belford Roxo','RJ'),('BR','BSA','Barbosa','Barbosa','SP'),('BR','BSB','Brasilia','Brasilia','DF'),('BR','BSC','Bom Sucesso','Bom Sucesso','MG'),('BR','BSD','Brasilia Sobradinho','Brasilia Sobradinho','DF'),('BR','BSE','Boa Esperanca','Boa Esperanca','MG'),('BR','BSM','Barra de Sao Miguel','Barra de Sao Miguel','AL'),('BR','BSO','Barroso','Barroso','MG'),('BR','BSS','Balsas','Balsas','MA'),('BR','BST','Boa Vista','Boa Vista','PE'),('BR','BSU','Boa Esperanca do Sul','Boa Esperanca do Sul','SP'),('BR','BTA','Batatais','Batatais','SP'),('BR','BTB','Porto Trombetas','Porto Trombetas','PA'),('BR','BTG','Bertioga','Bertioga','SP'),('BR','BTI','Betim','Betim','MG'),('BR','BTM','Buritama','Buritama','SP'),('BR','BTN','Britania','Britania','GO'),('BR','BTO','Barra de Santo Antonio','Barra de Santo Antonio','AL'),('BR','BTS','Bastos','Bastos','SP'),('BR','BTT','Brasilia Taguatinga','Brasilia Taguatinga','DF'),('BR','BTU','Baturite','Baturite','CE'),('BR','BTV','Boituva','Boituva','SP'),('BR','BUR','Buri','Buri','SP'),('BR','BUT','Buritis','Buritis','MG'),('BR','BVA','Barra Velha','Barra Velha','SC'),('BR','BVB','Boa Vista','Boa Vista','RR'),('BR','BVG','Boa Viagem','Boa Viagem','PE'),('BR','BVH','Vilhena','Vilhena','RO'),('BR','BVI','Benevides','Benevides','PA'),('BR','BVM','Belmonte','Belmonte','AC'),('BR','BVP','Bela Vista do Paraiso','Bela Vista do Paraiso','PR'),('BR','BVS','Breves','Breves','PA'),('BR','BVT','Bela Vista','Bela Vista','MS'),('BR','BYO','Bonito','Bonito','MS'),('BR','BZC','Buzios','Buzios','RJ'),('BR','BZE','Bezerros','Bezerros','PE'),('BR','CAA','Camapua','Camapua','MS'),('BR','CAB','Cabo','Cabo','PE'),('BR','CAC','Cascavel','Cascavel','PR'),('BR','CAD','Caninde','Caninde','CE'),('BR','CAF','Carauari','Carauari','AM'),('BR','CAG','Cha de Alegria','Cha de Alegria','PE'),('BR','CAI','Cassia','Cassia','MG'),('BR','CAM','Campina do Monte Alegre','Campina do Monte Alegre','SP'),('BR','CAN','Carbonita','Carbonita','MG'),('BR','CAP','Cacapava','Cacapava','SP'),('BR','CAR','Carambei','Carambei','SP'),('BR','CAS','Caieiras','Caieiras','SP'),('BR','CAT','Crato','Crato','CE'),('BR','CAU','Caruaru','Caruaru','PE'),('BR','CAW','Campos','Campos','RJ'),('BR','CBA','Caioba','Caioba','PR'),('BR','CBB','Carlos Barbosa','Carlos Barbosa','RS'),('BR','CBE','Cambe','Cambe','PR'),('BR','CBI','Caibi','Caibi','SC'),('BR','CBN','Capao Bonito','Capao Bonito','SP'),('BR','CBQ','Cambuquira','Cambuquira','MG'),('BR','CBR','Cambara','Cambara','PR'),('BR','CBS','Campos Belos','Campos Belos','GO'),('BR','CBU','Camboriu','Camboriu','SC'),('BR','CBW','Campo Mourao','Campo Mourao','PR'),('BR','CBX','Capivari de Baixo','Capivari de Baixo','SC'),('BR','CCA','Camacan','Camacan','BA'),('BR','CCB','Conceicao do Ibitipoca','Conceicao do Ibitipoca','MG'),('BR','CCC','Conceicao de Castelo','Conceicao de Castelo','ES'),('BR','CCE','Cabeceiras','Cabeceiras','GO'),('BR','CCG','Carlos Chagas','Carlos Chagas','MG'),('BR','CCH','Catole do Rocha','Catole do Rocha','PB'),('BR','CCI','Concordia','Concordia','SC'),('BR','CCL','Cacule','Cacule','BA'),('BR','CCM','Criciuma','Criciuma','SC'),('BR','CCN','Capao da Canoa','Capao da Canoa','RS'),('BR','CCO','Caconde','Caconde','SP'),('BR','CCQ','Cachoeira','Cachoeira','BA'),('BR','CCR','Conceicao dos Ouros','Conceicao dos Ouros','MG'),('BR','CCS','Conchas','Conchas','SP'),('BR','CCU','Cacu','Cacu','GO'),('BR','CCV','Cascavel','Cascavel','CE'),('BR','CCX','Caceres','Caceres','MT'),('BR','CDA','Codajas','Codajas','AM'),('BR','CDI','Cachoeiro de Itapemirim','Cachoeiro de Itapemirim','ES'),('BR','CDJ','Conceicao do Araguaia','Conceicao do Araguaia','PA'),('BR','CDL','Candelaria','Candelaria','RS'),('BR','CDM','Cachoeiras de Macacu','Cachoeiras de Macacu','RJ'),('BR','CDO','Cabedelo','Cabedelo','PB'),('BR','CDR','Cardoso','Cardoso','SP'),('BR','CDS','Cabo de Santo Agostinho','Cabo de Santo Agostinho','MS'),('BR','CDT','Candiota','Candiota','RS'),('BR','CDU','Candido Rodrigues','Candido Rodrigues','SP'),('BR','CDV','Catanduva','Catanduva','SP'),('BR','CEC','Conceicao do Coite','Conceicao do Coite','BA'),('BR','CED','Cedral','Cedral','SP'),('BR','CEL','Centralina','Centralina','MG'),('BR','CEO','Castelo','Castelo','ES'),('BR','CES','Ceres','Ceres','GO'),('BR','CEU','Careacu','Careacu','MG'),('BR','CFA','Caninde do Sao Francisco','Caninde do Sao Francisco','SE'),('BR','CFB','Coronel Fabriciano','Coronel Fabriciano','MG'),('BR','CFC','Cacador','Cacador','SC'),('BR','CFL','Cafelandia','Cafelandia','SP'),('BR','CFM','Campo Formoso','Campo Formoso','BA'),('BR','CFO','Confreza','Confreza','MT'),('BR','CGA','Caponga','Caponga','CE'),('BR','CGB','Cuiaba','Cuiaba','MT'),('BR','CGD','Cha Grande','Cha Grande','PE'),('BR','CGE','Contagem','Contagem','MG'),('BR','CGH','Congonhas Apt/Sao Paulo','Congonhas Apt/Sao Paulo','SP'),('BR','CGI','Corumba de Goias','Corumba de Goias','GO'),('BR','CGM','Chapada dos Guimaraes','Chapada dos Guimaraes','MT'),('BR','CGR','Campo Grande','Campo Grande','MS'),('BR','CGS','Conceicao das Alagoas','Conceicao das Alagoas','MG'),('BR','CGU','Caraguatatuba','Caraguatatuba','SP'),('BR','CGZ','Campos dos Goitacazes','Campos dos Goitacazes','RJ'),('BR','CHA','Cachoeirinha','Cachoeirinha','RS'),('BR','CHL','Conchal','Conchal','SP'),('BR','CHN','Coelho Neto','Coelho Neto','MA'),('BR','CHO','Castilho','Castilho','SP'),('BR','CHS','Canoinhas','Canoinhas','SC'),('BR','CIA','Claudia','Claudia','MT'),('BR','CIC','Caico','Caico','RN'),('BR','CIG','Caratinga','Caratinga','MG'),('BR','CIH','Carneirinho','Carneirinho','MG'),('BR','CII','Cariacica','Cariacica','ES'),('BR','CIN','Carpina','Carpina','PE'),('BR','CIO','Cipo','Cipo','BA'),('BR','CIR','Cairu','Cairu','BA'),('BR','CIS','Candeias','Candeias','BA'),('BR','CIU','Carapicuiba','Carapicuiba','SP'),('BR','CIZ','Coari','Coari','AM'),('BR','CJA','Cajati','Cajati','PR'),('BR','CJC','Conceicao de Jacuipe','Conceicao de Jacuipe','BA'),('BR','CJI','Cajati','Cajati','SP'),('BR','CJM','Cajamar','Cajamar','SP'),('BR','CJO','Cajobi','Cajobi','SP'),('BR','CJS','Cerejeiras','Cerejeiras','RO'),('BR','CJU','Cajuru','Cajuru','SP'),('BR','CJZ','Cajazeiras','Cajazeiras','CE'),('BR','CKO','Cornelio Procopio','Cornelio Procopio','PR'),('BR','CKS','Carajas','Carajas','PA'),('BR','CLA','Caldas','Caldas','MG'),('BR','CLB','Colombia','Colombia','SP'),('BR','CLD','Colider','Colider','MT'),('BR','CLE','Cesario Lange','Cesario Lange','SP'),('BR','CLG','Cerro Largo','Cerro Largo','RS'),('BR','CLH','Capelinha','Capelinha','MG'),('BR','CLI','Claudio','Claudio','MG'),('BR','CLL','Cocal do Sul','Cocal do Sul','SC'),('BR','CLM','Colmeia','Colmeia','TO'),('BR','CLN','Carolina','Carolina','MA'),('BR','CLO','Campo Largo','Campo Largo','PR'),('BR','CLP','Campo Limpo Paulista','Campo Limpo Paulista','SP'),('BR','CLT','Capela do Alto','Capela do Alto','SP'),('BR','CLV','Caldas Novas','Caldas Novas','GO'),('BR','CMA','Cardeal Mota','Cardeal Mota','MG'),('BR','CMB','Cambuci','Cambuci','RJ'),('BR','CMC','Camocim','Camocim','CE'),('BR','CMD','Conceicao do Mato Dentro','Conceicao do Mato Dentro','MG'),('BR','CME','Camaragibe','Camaragibe','PE'),('BR','CMG','Corumba','Corumba','MS'),('BR','CMI','Cambui','Cambui','MG'),('BR','CML','Coromandel','Coromandel','MG'),('BR','CMM','Cosmorama','Cosmorama','SP'),('BR','CMN','Candido Mendes','Candido Mendes','MA'),('BR','CMO','Comodoro','Comodoro','MT'),('BR','CMP','Santana Do Araguaia','Santana Do Araguaia','PA'),('BR','CMS','Cambara do Sul','Cambara do Sul','RS'),('BR','CMT','Candido Mota','Candido Mota','SP'),('BR','CMU','Camanducaia','Camanducaia','MG'),('BR','CNA','Colina','Colina','SP'),('BR','CNB','Conceicao da Barra','Conceicao da Barra','ES'),('BR','CNC','Carrancas','Carrancas','MG'),('BR','CND','Carandai','Carandai','MG'),('BR','CNE','Carapina da Serra','Carapina da Serra','ES'),('BR','CNF','Confins International','Confins International','MG'),('BR','CNG','Carangola','Carangola','MG'),('BR','CNI','Cananeia','Cananeia','SP'),('BR','CNN','Canarana','Canarana','MT'),('BR','CNO','Cianorte','Cianorte','PR'),('BR','CNP','Campo Novo do Parecis','Campo Novo do Parecis','MT'),('BR','CNR','Canitar','Canitar','SP'),('BR','CNS','Campos Novos','Campos Novos','SC'),('BR','CNT','Corrente','Corrente','PI'),('BR','CNV','Canavieiras','Canavieiras','BA'),('BR','COA','Cotia','Cotia','SP'),('BR','COL','Colombo','Colombo','PR'),('BR','COM','Campo Maior','Campo Maior','PI'),('BR','COO','Codo','Codo','MA'),('BR','COP','Carmo do Paranaiba','Carmo do Paranaiba','MG'),('BR','COT','Cotriguacu','Cotriguacu','MT'),('BR','COV','Carmo do Rio Verde','Carmo do Rio Verde','GO'),('BR','COX','Coxim','Coxim','MS'),('BR','CPA','Caapora','Caapora','PB'),('BR','CPB','Campo Belo','Campo Belo','MG'),('BR','CPC','Capitao Poco','Capitao Poco','PA'),('BR','CPD','Chapada','Chapada','RS'),('BR','CPE','Capao do Leao','Capao do Leao','RS'),('BR','CPH','Campanha','Campanha','MG'),('BR','CPI','Capivari','Capivari','SP'),('BR','CPJ','Correio Pinto','Correio Pinto','SC'),('BR','CPL','Chapadao do Sul','Chapadao do Sul','MS'),('BR','CPM','Capanema','Capanema','PA'),('BR','CPN','Campos Novos','Campos Novos','SP'),('BR','CPO','Campinapolis','Campinapolis','MT'),('BR','CPP','Capinopolis','Capinopolis','MG'),('BR','CPQ','Campinas','Campinas','SP'),('BR','CPS','Cachoeira Paulista','Cachoeira Paulista','SP'),('BR','CPT','Capetinga','Capetinga','MG'),('BR','CPU','Cururupu','Cururupu','MA'),('BR','CPV','Campina Grande','Campina Grande','PB'),('BR','CPZ','Capinzal','Capinzal','SC'),('BR','CQA','Camaqua','Camaqua','RS'),('BR','CQD','Charqueadas','Charqueadas','RS'),('BR','CQO','Cerquilho','Cerquilho','SP'),('BR','CQR','Cerqueira Cesar','Cerqueira Cesar','SP'),('BR','CQS','Costa Marques','Costa Marques','RO'),('BR','CQU','Canoa Quebrada','Canoa Quebrada','CE'),('BR','CRA','Corupa','Corupa','SC'),('BR','CRC','Coaraci','Coaraci','BA'),('BR','CRD','Carmo do Rio Claro','Carmo do Rio Claro','MG'),('BR','CRE','Cordeiro','Cordeiro','RJ'),('BR','CRI','Cidreira','Cidreira','RS'),('BR','CRM','Carambei','Carambei','PR'),('BR','CRN','Curitibanos','Curitibanos','SC'),('BR','CRO','Colorado','Colorado','PR'),('BR','CRP','Caarapo','Caarapo','MS'),('BR','CRQ','Caravelas','Caravelas','BA'),('BR','CRR','Canto do Buriti','Canto do Buriti','PI'),('BR','CRS','Cordeiropolis','Cordeiropolis','SP'),('BR','CRT','Corinto','Corinto','MG'),('BR','CRU','Cabreuva','Cabreuva','SP'),('BR','CRV','Caraiva','Caraiva','BA'),('BR','CRX','Crixas','Crixas','GO'),('BR','CRZ','Cruzilia','Cruzilia','MG'),('BR','CSA','Cabo de Santo Agostinho','Cabo de Santo Agostinho','PE'),('BR','CSC','Cansancao','Cansancao','BA'),('BR','CSD','Casimiro de Abreu','Casimiro de Abreu','RJ'),('BR','CSE','Castelandia','Castelandia','GO'),('BR','CSG','Casa Grande','Casa Grande','MG'),('BR','CSI','Porto de Sauipe','Porto de Sauipe','BA'),('BR','CSL','Cacapava do Sul','Cacapava do Sul','RS'),('BR','CSM','Cardoso Moreira','Cardoso Moreira','RJ'),('BR','CSN','Casa Branca','Casa Branca','SP'),('BR','CSO','Cordisburgo','Cordisburgo','MG'),('BR','CSP','Cosmopolis','Cosmopolis','SP'),('BR','CSR','Costa Rica','Costa Rica','MS'),('BR','CSS','Cassilandia','Cassilandia','MS'),('BR','CST','Cristalina','Cristalina','GO'),('BR','CSW','Colorado do Oeste','Colorado do Oeste','RO'),('BR','CTA','Clementina','Clementina','SP'),('BR','CTE','Caete','Caete','MG'),('BR','CTG','Cantagalo','Cantagalo','RJ'),('BR','CTH','Castanhal','Castanhal','PR'),('BR','CTI','Caetite','Caetite','BA'),('BR','CTL','Capitolio','Capitolio','MG'),('BR','CTN','Colatina','Colatina','ES'),('BR','CTO','Caetanopolis','Caetanopolis','MG'),('BR','CTP','Carutapera','Carutapera','MA'),('BR','CTQ','Santa Vitoria','Santa Vitoria','RS'),('BR','CTR','Castro','Castro','PR'),('BR','CTS','Colinas de Tocantins','Colinas de Tocantins','TO'),('BR','CTT','Canabarro Teutonia','Canabarro Teutonia','RS'),('BR','CTU','Crateus','Crateus','CE'),('BR','CTV','Catanduvas','Catanduvas','SC'),('BR','CUC','Caucaia','Caucaia','CE'),('BR','CUH','Cunha','Cunha','SP'),('BR','CUI','Chui','Chui','RS'),('BR','CUO','Cubatao','Cubatao','SP'),('BR','CUP','Coruripe','Coruripe','AL'),('BR','CVA','Chavantes','Chavantes','SP'),('BR','CVD','Campos Verdes','Campos Verdes','GO'),('BR','CVE','Campo Verde','Campo Verde','MT'),('BR','CVH','Cravinhos','Cravinhos','SP'),('BR','CVI','Clevelandia','Clevelandia','PR'),('BR','CVL','Curvelo','Curvelo','MG'),('BR','CVO','Conservatoria','Conservatoria','RJ'),('BR','CVR','Campina Verde','Campina Verde','MG'),('BR','CWB','Curitiba','Curitiba','PR'),('BR','CXJ','Caxias do Sul','Caxias do Sul','RS'),('BR','CXS','Caxias','Caxias','MA'),('BR','CXU','Caxambu','Caxambu','MG'),('BR','CZA','Cruz das Almas','Cruz das Almas','BA'),('BR','CZB','Cruz Alta','Cruz Alta','RS'),('BR','CZH','Jacarezinho','Jacarezinho','PR'),('BR','CZI','Cruzeiro','Cruzeiro','SP'),('BR','CZO','Cruzeiro do Oeste','Cruzeiro do Oeste',''),('BR','CZR','Cezarina','Cezarina','GO'),('BR','CZS','Cruzeiro do Sul','Cruzeiro do Sul','AC'),('BR','DCA','Dionisio Cerqueira','Dionisio Cerqueira','SC'),('BR','DCO','Descalvado','Descalvado','SP'),('BR','DCP','Dolcinopolis','Dolcinopolis','SP'),('BR','DCS','Dois Corregos','Dois Corregos','SP'),('BR','DDI','Dores do Indaia','Dores do Indaia','MG'),('BR','DEU','Dom Eliseu','Dom Eliseu','PA'),('BR','DGU','Delmiro Gouveia','Delmiro Gouveia','AL'),('BR','DIA','Dias d\'Avila','Dias d\'Avila','BA'),('BR','DID','Diadema','Diadema','SP'),('BR','DIQ','Divinopolis','Divinopolis','MG'),('BR','DIS','Dois Irmaos','Dois Irmaos','RS'),('BR','DLJ','Divino das Laranjeiras','Divino das Laranjeiras','MG'),('BR','DMA','Delfim Moreira','Delfim Moreira','MG'),('BR','DMC','Doutor Mauricio Cardoso','Doutor Mauricio Cardoso','RS'),('BR','DMS','Domingos Martins','Domingos Martins','ES'),('BR','DMT','Diamantino','Diamantino','MT'),('BR','DNO','Dianopolis','Dianopolis','TO'),('BR','DOU','Dourados','Dourados','MS'),('BR','DPO','Delfinopolis','Delfinopolis','MG'),('BR','DSU','Santa Cruz do Sul','Santa Cruz do Sul','RS'),('BR','DTA','Diamantina','Diamantina','MG'),('BR','DTI','Duartina','Duartina','SP'),('BR','DUO','Dourado','Dourado','SP'),('BR','DVD','Divinolandia','Divinolandia','SP'),('BR','DVO','Divino','Divino','ES'),('BR','DVS','Dois Vizinhos','Dois Vizinhos','PR'),('BR','EBR','Engenheiro Beltrao','Engenheiro Beltrao','PR'),('BR','ECH','Engenheiro Coelho','Engenheiro Coelho','SP'),('BR','ECO','Encantado','Encantado','RS'),('BR','ECU','Euclides da Cunha','Euclides da Cunha','BA'),('BR','EFU','Elias Fausto','Elias Fausto','SP'),('BR','EGI','Estiva Gerbi','Estiva Gerbi','SP'),('BR','EGU','Embu-Guacu','Embu-Guacu','SP'),('BR','ELO','Eldorado','Eldorado','SP'),('BR','EMA','Esmeraldas','Esmeraldas','MG'),('BR','EMB','Embu','Embu','SP'),('BR','EOS','Estrela do Oeste','Estrela do Oeste','SP'),('BR','EOT','Espigao do Oeste','Espigao do Oeste','RO'),('BR','EPA','Engenheiro Passos','Engenheiro Passos','RJ'),('BR','EPF','Engenheiro Paulo de Frontin','Engenheiro Paulo de Frontin','RJ'),('BR','EPI','Espirito Santo do Pinhal','Espirito Santo do Pinhal','SP'),('BR','EPO','Eunapolis','Eunapolis','BA'),('BR','EPU','Espumoso','Espumoso','RS'),('BR','ERA','Eldorado','Eldorado','MS'),('BR','ERM','Erechim','Erechim','RS'),('BR','ERN','Eirunepe','Eirunepe','AM'),('BR','ERS','Entre Rios','Entre Rios','BA'),('BR','ESD','Escada','Escada','PE'),('BR','ESI','Espinosa','Espinosa','MG'),('BR','ESO','Eusebio','Eusebio','CE'),('BR','EST','Estancia','Estancia','SE'),('BR','ESZ','Espera Feliz','Espera Feliz','MG'),('BR','ETA','Estrela','Estrela','RS'),('BR','ETI','Esperantina','Esperantina','PI'),('BR','ETO','Esteio','Esteio','RS'),('BR','ETR','Estreito','Estreito','MA'),('BR','EUB','Embauba','Embauba','SP'),('BR','EVH','Estancia Velha','Estancia Velha','RS'),('BR','EXA','Extrema','Extrema','MG'),('BR','EXZ','Extremoz','Extremoz','RN'),('BR','EZI','Euzebio','Euzebio','CE'),('BR','FAG','Formoso do Araguaia','Formoso do Araguaia','TO'),('BR','FBE','Francisco Beltrao','Francisco Beltrao','PR'),('BR','FCU','Flores da Cunha','Flores da Cunha','RS'),('BR','FDA','Fundao','Fundao','ES'),('BR','FEC','Feira de Santana','Feira de Santana','BA'),('BR','FEJ','Feijo','Feijo','AC'),('BR','FEN','Fernando de Noronha','Fernando de Noronha','PE'),('BR','FGO','Fraiburgo','Fraiburgo','SC'),('BR','FGU','Figueira','Figueira','PR'),('BR','FIP','Itabapoana','Itabapoana','RJ'),('BR','FLB','Floriano','Floriano','PI'),('BR','FLN','Florianopolis','Florianopolis','SC'),('BR','FLO','Florai','Florai','PR'),('BR','FMI','Formiga','Formiga','MG'),('BR','FMO','Formosa','Formosa','GO'),('BR','FMS','Fortaleza de Minas','Fortaleza de Minas','MG'),('BR','FNA','Fazenda Nova','Fazenda Nova','PE'),('BR','FNO','Forno','Forno','RJ'),('BR','FOR','Fortaleza','Fortaleza','CE'),('BR','FPA','Farroupilha','Farroupilha','RS'),('BR','FPE','Fernando Prestes','Fernando Prestes','SP'),('BR','FPO','Fernandopolis','Fernandopolis','SP'),('BR','FPS','Florida Paulista','Florida Paulista','SP'),('BR','FRC','Franca','Franca','SP'),('BR','FRG','Fazenda Rio Grande','Fazenda Rio Grande','PR'),('BR','FRO','Franco da Rocha','Franco da Rocha','SP'),('BR','FRU','Frutal','Frutal','MG'),('BR','FSA','Florestal','Florestal','MG'),('BR','FSU','Fatima do Sul','Fatima do Sul','MS'),('BR','FTO','Francisco Morato','Francisco Morato','SP'),('BR','FTU','Fartura','Fartura','SP'),('BR','FVA','Ferraz de Vasconcelos','Ferraz de Vasconcelos','SP'),('BR','FWP','Frederico Westphalen','Frederico Westphalen','RS'),('BR','GAB','Guaimbe','Guaimbe','SP'),('BR','GAI','Guaraci','Guaraci','SP'),('BR','GAM','Guararema','Guararema','SP'),('BR','GAP','Guapo','Guapo','GO'),('BR','GAR','Guara','Guara','SP'),('BR','GBA','Guarabira','Guarabira','PB'),('BR','GBI','Garibaldi','Garibaldi','RS'),('BR','GCA','Garca','Garca','SP'),('BR','GCE','Campo Grande','Campo Grande','RJ'),('BR','GCR','Governador Celso Ramos','Governador Celso Ramos','SC'),('BR','GCS','Goncalves','Goncalves','MG'),('BR','GCU','Guacui','Guacui','ES'),('BR','GCV','Gravatai','Gravatai','RS'),('BR','GDO','Gloria de Dourados','Gloria de Dourados','MS'),('BR','GDP','Guadalupe','Guadalupe','PI'),('BR','GDU','Gandu','Gandu','BA'),('BR','GEB','Gebig','Gebig','RJ'),('BR','GEL','Santo Angelo','Santo Angelo','RS'),('BR','GEM','Guarda do Embau','Guarda do Embau','SC'),('BR','GHA','Glorinha','Glorinha','RS'),('BR','GHE','Guanhaes','Guanhaes','MG'),('BR','GHU','Garanhuns','Garanhuns','PE'),('BR','GIA','Goiania','Goiania','PE'),('BR','GIB','Guaiba','Guaiba','RS'),('BR','GIG','Rio De Janeiro-Internacional Apt','Rio De Janeiro-Internacional Apt','RJ'),('BR','GIR','Guaira','Guaira','SP'),('BR','GIS','Goias','Goias','GO'),('BR','GJA','Grajau','Grajau','MA'),('BR','GJM','Guajara-Mirim','Guajara-Mirim','RO'),('BR','GJU','Guarajuba','Guarajuba','BA'),('BR','GLA','Galia','Galia','SP'),('BR','GLE','Gameleira','Gameleira','PE'),('BR','GMO','Guarda-Mor','Guarda-Mor','MG'),('BR','GMS','Guimaraes','Guimaraes','MA'),('BR','GNI','Goianesia','Goianesia','GO'),('BR','GNM','Guanambi','Guanambi','BA'),('BR','GNO','Guaraciaba do Norte','Guaraciaba do Norte','CE'),('BR','GNR','Guaranta do Norte','Guaranta do Norte','MT'),('BR','GOB','Guabirotuba','Guabirotuba','PR'),('BR','GOE','Goioere','Goioere','PR'),('BR','GPA','Garopaba','Garopaba','SC'),('BR','GPB','Guarapuava','Guarapuava','PR'),('BR','GPC','Guapiacu','Guapiacu','SP'),('BR','GPE','Guape','Guape','MG'),('BR','GPI','Guapiara','Guapiara','SP'),('BR','GPM','Guapimirim','Guapimirim','RJ'),('BR','GPO','Goianapolis','Goianapolis','GO'),('BR','GPR','Grao Para','Grao Para','SC'),('BR','GPU','Genipabu','Genipabu','RN'),('BR','GQE','Guaraquecaba','Guaraquecaba','PR'),('BR','GRA','Girua','Girua','RS'),('BR','GRB','Guariba','Guariba','SP'),('BR','GRE','Guararapes','Guararapes','SP'),('BR','GRI','Guaracai','Guaracai','SP'),('BR','GRM','Guaramirim','Guaramirim','SC'),('BR','GRP','Gurupi','Gurupi','GO'),('BR','GRQ','Guarai','Guarai','TO'),('BR','GRU','Guarulhos Apt/Sao Paulo','Guarulhos Apt/Sao Paulo','SP'),('BR','GSA','Gaspar','Gaspar','SC'),('BR','GSI','S.Goncalo Sapucai','S.Goncalo Sapucai','MG'),('BR','GSO','General Salgado','General Salgado','SP'),('BR','GSS','Grossos','Grossos','RN'),('BR','GSU','Rio Grande do Sul','Rio Grande do Sul','PR'),('BR','GTA','Goiatuba','Goiatuba','GO'),('BR','GTB','Guaratuba','Guaratuba','PR'),('BR','GTI','Guiratinga','Guiratinga','MT'),('BR','GTU','Getulina','Getulina','SP'),('BR','GUA','Guamare','Guamare','RN'),('BR','GUJ','Guaratingueta','Guaratingueta','SP'),('BR','GUP','Guapore','Guapore','RS'),('BR','GUR','Guaruja','Guaruja','SP'),('BR','GUU','Gurupi','Gurupi','TO'),('BR','GVA','Getulio Vargas','Getulio Vargas','RS'),('BR','GVL','Gravatal','Gravatal','SC'),('BR','GVR','Governador Valadares','Governador Valadares','MG'),('BR','GVT','Gravata','Gravata','PE'),('BR','GXP','Guaxupe','Guaxupe','MG'),('BR','GYN','Goiania','Goiania','GO'),('BR','GZO','Guzolandia','Guzolandia','SP'),('BR','HLA','Herculandia','Herculandia','SP'),('BR','HLI','Hidrolandia','Hidrolandia','GO'),('BR','HLR','Holambra','Holambra','SP'),('BR','HMA','Humaita','Humaita','AM'),('BR','HRZ','Horizontina','Horizontina','RS'),('BR','HTL','Hortolandia','Hortolandia','SP'),('BR','HZO','Horizonte','Horizonte','CE'),('BR','IAA','Iraja','Iraja','RJ'),('BR','IAB','Itabera','Itabera','SP'),('BR','IAC','Igarape-Acu','Igarape-Acu','PA'),('BR','IAE','Itambe','Itambe','PR'),('BR','IAG','Itaguara','Itaguara','MG'),('BR','IAI','Itai','Itai','SP'),('BR','IAJ','Itajuba','Itajuba','MG'),('BR','IAM','Iretama','Iretama','PR'),('BR','IAN','Itauna','Itauna','MG'),('BR','IAO','Itapora','Itapora','MS'),('BR','IAP','Itirapina','Itirapina','SP'),('BR','IAR','Itaberai','Itaberai','GO'),('BR','IAT','Itatinga','Itatinga','SP'),('BR','IAV','Itapeva','Itapeva','SP'),('BR','IBA','Itaberaba','Itaberaba','BA'),('BR','IBB','Imbituba','Imbituba','SC'),('BR','IBC','Ibate','Ibate','SP'),('BR','IBE','Ilhabela','Ilhabela','SP'),('BR','IBI','Ibati','Ibati','PR'),('BR','IBN','Itabatan','Itabatan','BA'),('BR','IBO','Ibo','Ibo','BA'),('BR','IBP','Ilha de Boipeba','Ilha de Boipeba','BA'),('BR','IBR','Ibira','Ibira','SP'),('BR','IBT','Ibotirama','Ibotirama','BA'),('BR','IBU','Ibiuna','Ibiuna','SP'),('BR','ICA','Iaciara','Iaciara','GO'),('BR','ICC','Itapecerica','Itapecerica','MG'),('BR','ICD','Ilha de Comandatuba','Ilha de Comandatuba','BA'),('BR','ICE','Inocencia','Inocencia','MS'),('BR','ICI','Iacri','Iacri','SP'),('BR','ICM','Icem','Icem','SP'),('BR','ICN','Iconha','Iconha','ES'),('BR','ICO','Ilha Comprida','Ilha Comprida','SP'),('BR','ICR','Icara','Icara','SC'),('BR','ICS','Ilha do Cardoso','Ilha do Cardoso','SP'),('BR','ICU','Ibiracu','Ibiracu','ES'),('BR','IDA','Indaial','Indaial','SC'),('BR','IDO','Santa Isabel do Morro','Santa Isabel do Morro','TO'),('BR','IDU','Indaiatuba','Indaiatuba','SP'),('BR','IEB','Itapebi','Itapebi','BA'),('BR','IEM','Itapema','Itapema','SC'),('BR','IEP','Iepe','Iepe','SP'),('BR','IEV','Itapevi','Itapevi','SP'),('BR','IGA','Igaracu','Igaracu','PE'),('BR','IGB','Igarape','Igarape','MG'),('BR','IGC','Ipanguacu','Ipanguacu','RN'),('BR','IGE','Ilha Grande','Ilha Grande','RJ'),('BR','IGI','Itaguai','Itaguai','RJ'),('BR','IGJ','Igrejinha','Igrejinha','RS'),('BR','IGM','Iguatemi','Iguatemi','MS'),('BR','IGO','Ilha do Governador','Ilha do Governador','RJ'),('BR','IGP','Iguape','Iguape','SP'),('BR','IGR','Imigrante','Imigrante','RS'),('BR','IGT','Igaratinga','Igaratinga','MG'),('BR','IGU','Foz do Iguacu','Foz do Iguacu','PR'),('BR','IGV','Iguarapava','Iguarapava','SP'),('BR','IHA','Itanhandu','Itanhandu','MG'),('BR','IHM','Ivinhema','Ivinhema','MS'),('BR','IHS','Inhumas','Inhumas','GO'),('BR','IHU','Inhauma','Inhauma','MG'),('BR','IIA','Itatiba','Itatiba','SP'),('BR','IIC','Itaparica','Itaparica','BA'),('BR','IIG','Itapetininga','Itapetininga','SP'),('BR','III','Itariri','Itariri','SP'),('BR','IIP','Itapipoca','Itapipoca','CE'),('BR','IIR','Itabira','Itabira','MG'),('BR','IJA','Ijaci','Ijaci','MG'),('BR','IJB','Itajobi','Itajobi','SP'),('BR','IJP','Itajuipe','Itajuipe','BA'),('BR','IJU','Ijui','Ijui','RS'),('BR','ILB','Ilha Solteira','Ilha Solteira','MS'),('BR','ILS','Itapolis','Itapolis','SP'),('BR','IMA','Ibirama','Ibirama','SC'),('BR','IMB','Imbe','Imbe','RS'),('BR','IMC','Itamaraca','Itamaraca','PE'),('BR','IME','Ilha do Mel','Ilha do Mel','PR'),('BR','IMI','Icaraima','Icaraima','PR'),('BR','IMJ','Ilha de Marajo','Ilha de Marajo','PA'),('BR','IMM','Itapecuru-Mirim','Itapecuru-Mirim','MA'),('BR','IMN','Itamarati de Minas','Itamarati de Minas','MG'),('BR','IMP','Imperatriz','Imperatriz','MA'),('BR','IMT','Itamonte','Itamonte','MG'),('BR','INA','Indiana','Indiana','SP'),('BR','ING','Ibitinga','Ibitinga','SP'),('BR','INU','Itaunas','Itaunas','ES'),('BR','INX','Itabaiana','Itabaiana','SE'),('BR','IOA','Itapoa','Itapoa','SC'),('BR','IOC','Itaocara','Itaocara','RJ'),('BR','IOG','Itaporanga','Itaporanga','SP'),('BR','IOI','Itaborai','Itaborai','RJ'),('BR','IOR','Ivaipora','Ivaipora','PR'),('BR','IOS','Ilheus','Ilheus','BA'),('BR','IOT','Ipora do Oeste','Ipora do Oeste','SC'),('BR','IPA','Ibipora','Ibipora','PR'),('BR','IPB','Itambe de Pernambuco','Itambe de Pernambuco','PE'),('BR','IPE','Ipeuna','Ipeuna','SP'),('BR','IPG','Ipiranga','Ipiranga','AM'),('BR','IPI','Itapagipe','Itapagipe','MG'),('BR','IPL','Itaiopolis','Itaiopolis','SC'),('BR','IPM','Ipanema','Ipanema','MG'),('BR','IPN','Ipatinga','Ipatinga','MG'),('BR','IPO','Ipojuca','Ipojuca','PE'),('BR','IPP','Ilha do Papagaio','Ilha do Papagaio','SC'),('BR','IPR','Ipora','Ipora','GO'),('BR','IPS','Iracemapolis','Iracemapolis','SP'),('BR','IPU','Ipiau','Ipiau','BA'),('BR','IPV','Itupeva','Itupeva','SP'),('BR','IQI','Itaqui','Itaqui','MA'),('BR','IQU','Itaquaquecetuba','Itaquaquecetuba','SP'),('BR','IRA','Iturama','Iturama','MG'),('BR','IRC','Itacuruca','Itacuruca','RJ'),('BR','IRE','Irece','Irece','BA'),('BR','IRG','Iporanga','Iporanga','SP'),('BR','IRI','Ibicarai','Ibicarai','BA'),('BR','IRJ','Itamaraju','Itamaraju','BA'),('BR','IRM','Ibirarema','Ibirarema','SP'),('BR','IRN','Itapiranga','Itapiranga','SC'),('BR','IRO','Itabirito','Itabirito','MG'),('BR','IRP','Igarapava','Igarapava','SP'),('BR','IRR','Iriri','Iriri','ES'),('BR','IRT','Ibirite','Ibirite','MG'),('BR','IRU','Ibiruba','Ibiruba','RS'),('BR','ISA','Ilha Solteira','Ilha Solteira','SP'),('BR','ISI','Imbassai','Imbassai','BA'),('BR','ISM','Itapissuma','Itapissuma','PE'),('BR','ISO','Itauna Do Sul','Itauna Do Sul','PR'),('BR','ISR','Itapecerica da Serra','Itapecerica da Serra','SP'),('BR','ITA','Itacoatiara','Itacoatiara','AM'),('BR','ITB','Itaituba','Itaituba','PA'),('BR','ITC','Itacare','Itacare','BA'),('BR','ITD','Ituporanga','Ituporanga','SC'),('BR','ITE','Itubera','Itubera','BA'),('BR','ITG','Itapetinga','Itapetinga','BA'),('BR','ITH','Itanhaem','Itanhaem','SP'),('BR','ITI','Itambacuri','Itambacuri','MG'),('BR','ITJ','Itajai','Itajai','SC'),('BR','ITM','Iguatama','Iguatama','MG'),('BR','ITN','Itabuna','Itabuna','BA'),('BR','ITO','Itororo','Itororo','BA'),('BR','ITP','Itaperuna','Itaperuna','RJ'),('BR','ITQ','Itaqui','Itaqui','RS'),('BR','ITR','Itumbiara','Itumbiara','GO'),('BR','ITT','Itatiaia','Itatiaia','RJ'),('BR','ITU','Itu','Itu','SP'),('BR','ITV','Itaipava','Itaipava','RJ'),('BR','ITZ','Itapemirim','Itapemirim','ES'),('BR','IUB','Ituiutaba','Ituiutaba','MG'),('BR','IUG','Itapuranga','Itapuranga','GO'),('BR','IUM','Itau de Minas','Itau de Minas','MG'),('BR','IVA','Ituverava','Ituverava','SP'),('BR','IVT','Ivate','Ivate','PR'),('BR','IVU','Ibitiuva','Ibitiuva','SP'),('BR','JAA','Jaguaruana','Jaguaruana','CE'),('BR','JAB','Jaboatao','Jaboatao','PE'),('BR','JAC','Jacinto','Jacinto','MG'),('BR','JAE','Jardim Alegre','Jardim Alegre','PR'),('BR','JAG','Jaguarao','Jaguarao','RS'),('BR','JAR','Jaru','Jaru','RO'),('BR','JAU','Jau','Jau','SP'),('BR','JBC','Jaboticabal','Jaboticabal','SP'),('BR','JBE','Jambeiro','Jambeiro','SP'),('BR','JBF','Jose Bonifacio','Jose Bonifacio','SP'),('BR','JBU','Jurubatuba','Jurubatuba','SP'),('BR','JCA','Jacaraipe','Jacaraipe','ES'),('BR','JCB','Joacaba','Joacaba','SC'),('BR','JCD','Jacunda','Jacunda','PA'),('BR','JCE','Jacarei','Jacarei','SP'),('BR','JCI','Jaciara','Jaciara','MT'),('BR','JCM','Jacobina','Jacobina','BA'),('BR','JCO','Jericoacoara','Jericoacoara','CE'),('BR','JCR','Jacareacanga','Jacareacanga','PA'),('BR','JCS','Julio de Castilhos','Julio de Castilhos','RS'),('BR','JCU','Jacuma','Jacuma','PB'),('BR','JDA','Jandaia','Jandaia','GO'),('BR','JDF','Juiz de Fora','Juiz de Fora','MG'),('BR','JDI','Jandira','Jandira','SP'),('BR','JDM','Jardim','Jardim','MS'),('BR','JDO','Juazeiro do Norte','Juazeiro do Norte','CE'),('BR','JEQ','Jequie','Jequie','BA'),('BR','JGA','Jaguaquara','Jaguaquara','BA'),('BR','JGD','Jangada','Jangada','MT'),('BR','JGI','Jaguarari','Jaguarari','PE'),('BR','JGN','Jaguariuna','Jaguariuna','SP'),('BR','JGR','Jaguare','Jaguare','SP'),('BR','JGU','Jaboatao dos Guararapes','Jaboatao dos Guararapes','PE'),('BR','JIA','Juina','Juina','MT'),('BR','JLS','Jales','Jales','SP'),('BR','JMV','Joao Monlevade','Joao Monlevade','MG'),('BR','JNA','Januaria','Januaria','MG'),('BR','JNI','Joao Neiva','Joao Neiva','ES'),('BR','JNU','Janauba','Janauba','MG'),('BR','JOI','Joinville','Joinville','SC'),('BR','JOP','Joanopolis','Joanopolis','SP'),('BR','JPA','Joao Pessoa','Joao Pessoa','PB'),('BR','JPG','Jaracupiranga','Jaracupiranga','SP'),('BR','JPH','Joao Pinheiro','Joao Pinheiro','MG'),('BR','JPI','Jacupiranga','Jacupiranga','SP'),('BR','JPO','Jalapao','Jalapao','TO'),('BR','JPR','Ji-Parana','Ji-Parana','RO'),('BR','JPS','Jardinopolis','Jardinopolis','SP'),('BR','JPU','Jacarepagua','Jacarepagua','RJ'),('BR','JQA','Jequitinhonha','Jequitinhonha','MG'),('BR','JQB','Juquitiba','Juquitiba','SP'),('BR','JQI','Jiquirica','Jiquirica','BA'),('BR','JQU','Juquia','Juquia','SP'),('BR','JRA','Jaguarari','Jaguarari','BA'),('BR','JRI','Jarinu','Jarinu','SP'),('BR','JRN','Juruena','Juruena','MT'),('BR','JRO','Junqueiropolis','Junqueiropolis','SP'),('BR','JRP','Sao Jose do Rio Pardo','Sao Jose do Rio Pardo','SP'),('BR','JRU','Jaragua','Jaragua','GO'),('BR','JRV','Jaguariaiva','Jaguariaiva','PR'),('BR','JSA','Jussara','Jussara','GO'),('BR','JSU','Jandaia do Sul','Jandaia do Sul','PR'),('BR','JTI','Jatai','Jatai','GO'),('BR','JTU','Jacutinga','Jacutinga','MG'),('BR','JUA','Juara','Juara','MT'),('BR','JUN','Jundiai','Jundiai','SP'),('BR','JZO','Juazeiro','Juazeiro','BA'),('BR','LAJ','Lages','Lages','SC'),('BR','LAN','Luis Antonio','Luis Antonio','SP'),('BR','LAP','Lapa','Lapa','PR'),('BR','LAR','Lavras','Lavras','MG'),('BR','LAS','Lavras do Sul','Lavras do Sul','RS'),('BR','LAV','Lavinia','Lavinia','SP'),('BR','LAW','Lavras Novas','Lavras Novas','MG'),('BR','LAX','Lavrinhas','Lavrinhas','SP'),('BR','LAZ','Bom Jesus da Lapa','Bom Jesus da Lapa','BA'),('BR','LBA','Lambari','Lambari','MG'),('BR','LBR','Labrea','Labrea','AM'),('BR','LCB','Pontes e Lacerda','Pontes e Lacerda','MT'),('BR','LCI','Luis Correia','Luis Correia','PI'),('BR','LCU','Lagoa da Confusao','Lagoa da Confusao','TO'),('BR','LDB','Londrina','Londrina','PR'),('BR','LDF','Lauro de Freitas','Lauro de Freitas','BA'),('BR','LDM','Luis Eduardo Magalhaes','Luis Eduardo Magalhaes','BA'),('BR','LEM','Leme','Leme','SP'),('BR','LEN','Lencois','Lencois','BA'),('BR','LEP','Leopoldina','Leopoldina','MG'),('BR','LER','Lebon Regis','Lebon Regis','SC'),('BR','LFA','Lafaete','Lafaete','MG'),('BR','LGO','Lagarto','Lagarto','SE'),('BR','LIC','Lindolfo Collor','Lindolfo Collor','RS'),('BR','LIM','Limoeiro','Limoeiro','PE'),('BR','LIN','Lindoia','Lindoia','SP'),('BR','LIP','Lins','Lins','SP'),('BR','LJI','Laranjal do Jari','Laranjal do Jari','AP'),('BR','LJO','Lajeado','Lajeado','TO'),('BR','LJS','Laranjeiras','Laranjeiras','SE'),('BR','LMR','Limeira','Limeira','SP'),('BR','LMU','Lauro Muller','Lauro Muller','SC'),('BR','LNH','Linhares','Linhares','ES'),('BR','LOD','Loanda','Loanda','PR'),('BR','LOI','Lontras','Lontras','SC'),('BR','LOR','Lorena','Lorena','AM'),('BR','LOU','Lourdes','Lourdes','SP'),('BR','LOZ','Louveira','Louveira',''),('BR','LPA','Lagoa da Prata','Lagoa da Prata','MG'),('BR','LPU','Laranjal Paulista','Laranjal Paulista','SP'),('BR','LRA','Lorena','Lorena','SP'),('BR','LRV','Lucas do Rio Verde','Lucas do Rio Verde','MT'),('BR','LSA','Lagoa Santa','Lagoa Santa','GO'),('BR','LSN','Lagoa Santa','Lagoa Santa','MG'),('BR','LST','Lagoa Santa','Lagoa Santa','MS'),('BR','LSU','Laranjeiras do Sul','Laranjeiras do Sul','PR'),('BR','LUC','Lucelia','Lucelia','SP'),('BR','LVB','Livramento','Livramento','RS'),('BR','LVE','Lagoa Vermelha','Lagoa Vermelha','RS'),('BR','LZA','Luziania','Luziania','GO'),('BR','LZI','Luiziania','Luiziania','SP'),('BR','MAB','Maraba','Maraba','PA'),('BR','MAD','Madre-de-Deus','Madre-de-Deus','MA'),('BR','MAG','Mage','Mage','RJ'),('BR','MAL','Mallet','Mallet','PR'),('BR','MAM','Monte Alegre de Minas','Monte Alegre de Minas','MG'),('BR','MAO','Manaus','Manaus','AM'),('BR','MAP','Monte Azul Paulista','Monte Azul Paulista','SP'),('BR','MAR','Maragogipe','Maragogipe','BA'),('BR','MAS','Monte Alegre do Sul','Monte Alegre do Sul','SP'),('BR','MAT','Matao','Matao','SP'),('BR','MAU','Marau','Marau','RS'),('BR','MAV','Marialva','Marialva','PR'),('BR','MAY','Antonio Prado','Antonio Prado','RS'),('BR','MAZ','Monte Aprazivel','Monte Aprazivel','SP'),('BR','MBA','Matias Barbosa','Matias Barbosa','MG'),('BR','MBK','Matupa','Matupa','MT'),('BR','MBU','Mombuca','Mombuca','SP'),('BR','MBZ','Maues','Maues','AM'),('BR','MCA','Machado','Machado','MG'),('BR','MCE','Monte Carmelo','Monte Carmelo','MG'),('BR','MCG','Montes Claros de Goias','Montes Claros de Goias','GO'),('BR','MCI','Maracai','Maracai','SP'),('BR','MCL','Marcelandia','Marcelandia','MT'),('BR','MCM','Miracema','Miracema','RJ'),('BR','MCN','Maracanau','Maracanau','CE'),('BR','MCO','Martinho Campos','Martinho Campos','MG'),('BR','MCP','Macapa','Macapa','AP'),('BR','MCR','Mal Candido Rondon','Mal Candido Rondon','PR'),('BR','MCT','Miracatu','Miracatu','SP'),('BR','MCU','Macau','Macau','RN'),('BR','MCZ','Maceio','Maceio','AL'),('BR','MDA','Medianeira','Medianeira','PR'),('BR','MDC','Mendonca','Mendonca','SP'),('BR','MDD','Madre de Deus','Madre de Deus',''),('BR','MDE','Marechal Deodoro','Marechal Deodoro','AL'),('BR','MDI','Mandaguari','Mandaguari','PR'),('BR','MDN','Medina','Medina','MG'),('BR','MDO','Mirandopolis','Mirandopolis','SP'),('BR','MDS','Mendes','Mendes','RJ'),('BR','MEA','Macae','Macae','RJ'),('BR','MEU','Monte Dourado','Monte Dourado','PA'),('BR','MFA','Maria Farinha','Maria Farinha','PE'),('BR','MFO','Marechal Floriano','Marechal Floriano','ES'),('BR','MGC','Mandaguacu','Mandaguacu','PR'),('BR','MGE','Maranguape','Maranguape','CE'),('BR','MGF','Maringa','Maringa','PR'),('BR','MGG','Mogi Guacu','Mogi Guacu','SP'),('BR','MGO','Maragogi','Maragogi','AL'),('BR','MGU','Munguba','Munguba',''),('BR','MHA','Malhador','Malhador','SE'),('BR','MHI','Manhumirim','Manhumirim','MG'),('BR','MHO','Morrinhos','Morrinhos','GO'),('BR','MHS','Maravilhas','Maravilhas','MG'),('BR','MHU','Manhuacu','Manhuacu','MG'),('BR','MHZ','Munhoz','Munhoz','MG'),('BR','MIA','Mirai','Mirai','MG'),('BR','MIG','S Miguel do Iguacu','S Miguel do Iguacu','PR'),('BR','MII','Marilia','Marilia','SP'),('BR','MIR','Mirassol','Mirassol','SP'),('BR','MJU','Maracaju','Maracaju','MS'),('BR','MLA','Matelandia','Matelandia','PR'),('BR','MLO','Monteiro Lobato','Monteiro Lobato','SP'),('BR','MMA','Mormaco','Mormaco','RS'),('BR','MME','Monteiro','Monteiro','PB'),('BR','MMI','Mogi Mirim','Mogi Mirim','SP'),('BR','MMO','Mimoso','Mimoso','ES'),('BR','MNA','Mantena','Mantena','MG'),('BR','MNG','Monte Negro','Monte Negro','SP'),('BR','MNH','Montanha','Montanha','ES'),('BR','MNI','Manduri','Manduri','SP'),('BR','MNO','Medeiros Neto','Medeiros Neto','BA'),('BR','MNS','Mineiros','Mineiros','GO'),('BR','MNU','Mongagua','Mongagua','SP'),('BR','MNV','Mundo Novo','Mundo Novo','MS'),('BR','MNX','Manicore','Manicore','AM'),('BR','MOA','Morro Agudo','Morro Agudo','SP'),('BR','MOC','Montes Claros','Montes Claros','MG'),('BR','MOO','Mococa','Mococa','SP'),('BR','MOS','Mimoso do Oeste','Mimoso do Oeste','BA'),('BR','MPE','Miguel Pereira','Miguel Pereira','RJ'),('BR','MPI','Miguelopolis','Miguelopolis','SP'),('BR','MPL','Monsenhor Paulo','Monsenhor Paulo','MG'),('BR','MPM','Mirante do Paranapanema','Mirante do Paranapanema','SP'),('BR','MPO','Martinopolis','Martinopolis','SP'),('BR','MPR','Manacapuru','Manacapuru','AM'),('BR','MPU','Mamanguape','Mamanguape','PB'),('BR','MQE','Mairinque','Mairinque','SP'),('BR','MQH','Minacu','Minacu','GO'),('BR','MQI','Maquine','Maquine','RS'),('BR','MQR','Mosqueiro','Mosqueiro','PA'),('BR','MQU','Mesquita','Mesquita','RJ'),('BR','MRA','Marcelino Ramos','Marcelino Ramos','RS'),('BR','MRC','Marica','Marica','RJ'),('BR','MRD','Miranda','Miranda','MS'),('BR','MRE','Moreno','Moreno','PE'),('BR','MRG','Morungaba','Morungaba','SP'),('BR','MRI','Mariana','Mariana','MG'),('BR','MRO','Mae do Rio','Mae do Rio','PA'),('BR','MRS','Morretes','Morretes','PR'),('BR','MRU','Meruoca','Meruoca','CE'),('BR','MSA','Massaranduba','Massaranduba','SC'),('BR','MSE','Mangue Seco','Mangue Seco','BA'),('BR','MSI','Monte Siao','Monte Siao','MG'),('BR','MSJ','Mata de Sao Joao','Mata de Sao Joao','BA'),('BR','MSO','Mirassol do Oeste','Mirassol do Oeste','MT'),('BR','MSP','Morro de Sao Paulo','Morro de Sao Paulo','BA'),('BR','MSR','Maua da Serra','Maua da Serra','PR'),('BR','MTA','Mata','Mata','RS'),('BR','MTD','Mostardas','Mostardas','RS'),('BR','MTE','Monte Alegre','Monte Alegre','PA'),('BR','MTG','Mato Grosso','Mato Grosso','MT'),('BR','MTL','Mateus Leme','Mateus Leme','MG'),('BR','MTM','Monte Mor','Monte Mor','SP'),('BR','MTN','Miracema do Tocantins','Miracema do Tocantins','TO'),('BR','MTO','Matinhos','Matinhos','PR'),('BR','MTS','Montes','Montes','MG'),('BR','MTT','Monte Alto','Monte Alto','SP'),('BR','MTU','Macatuba','Macatuba','SP'),('BR','MTZ','Marataizes','Marataizes','ES'),('BR','MUA','Maua','Maua','SP'),('BR','MUN','Mundai','Mundai','BA'),('BR','MUR','Muriae','Muriae','MG'),('BR','MVA','Maravilha','Maravilha','SC'),('BR','MVE','Monte Verde','Monte Verde','MG'),('BR','MVF','Mossoro','Mossoro','RN'),('BR','MVG','Mundo Novo de Goias','Mundo Novo de Goias','GO'),('BR','MVS','Mucuri','Mucuri','BA'),('BR','MXA','Maximiliano de Almeida','Maximiliano de Almeida','RS'),('BR','MZA','Mozarlandia','Mozarlandia','GO'),('BR','MZI','Muzambinho','Muzambinho','MG'),('BR','MZS','Matozinhos','Matozinhos','MG'),('BR','NAC','Nova Apar Campinas','Nova Apar Campinas','SP'),('BR','NAD','Nova Andradina','Nova Andradina','MS'),('BR','NAI','Nova Almeida','Nova Almeida','ES'),('BR','NAT','Natal','Natal','RN'),('BR','NBA','Nova Bassano','Nova Bassano','RS'),('BR','NBE','Nobres','Nobres','MT'),('BR','NBV','Cana Brava','Cana Brava','MG'),('BR','NCA','Nova Caiaponia','Nova Caiaponia','GO'),('BR','NEC','Nova Esperanca','Nova Esperanca','PR'),('BR','NER','Nova Era','Nova Era','MG'),('BR','NEU','Nova Europa','Nova Europa','SP'),('BR','NFO','Nizia Floresta','Nizia Floresta','RN'),('BR','NFU','Nova Friburgo','Nova Friburgo','RJ'),('BR','NGA','Nova Granada','Nova Granada','SP'),('BR','NGO','Nova Gloria','Nova Gloria','GO'),('BR','NHA','Nhandeara','Nhandeara','SP'),('BR','NHO','Novo Horizonte','Novo Horizonte','SP'),('BR','NIU','Nova Iguacu','Nova Iguacu','RJ'),('BR','NLI','Nova Lima','Nova Lima','MG'),('BR','NLO','Nova Londrina','Nova Londrina','PR'),('BR','NMU','Nova Mutum','Nova Mutum','MT'),('BR','NNU','Nanuque','Nanuque','MG'),('BR','NOD','Nova Odessa','Nova Odessa','SP'),('BR','NOK','Nova Xavantina','Nova Xavantina','MT'),('BR','NPA','Nova Prata','Nova Prata','RS'),('BR','NPE','Nova Petropolis','Nova Petropolis','RS'),('BR','NPO','Nilopolis','Nilopolis','RJ'),('BR','NPT','Nova Ponte','Nova Ponte','MG'),('BR','NPU','Nazare Paulista','Nazare Paulista','SP'),('BR','NQL','Niquelandia','Niquelandia','GO'),('BR','NSA','Nova Serrana','Nova Serrana','MG'),('BR','NSJ','Novo Sao Joaquim','Novo Sao Joaquim','MT'),('BR','NSR','Nova Santa Rita','Nova Santa Rita','RS'),('BR','NSS','Nossa Senhora do Socorro','Nossa Senhora do Socorro','SE'),('BR','NTM','Miracema do Norte','Miracema do Norte','TO'),('BR','NTO','Nortolandia','Nortolandia','MT'),('BR','NTQ','Nao Me Toque','Nao Me Toque','RS'),('BR','NTR','Niteroi','Niteroi','RJ'),('BR','NUR','Nova Aurora','Nova Aurora','PR'),('BR','NVC','Nova Venecia','Nova Venecia','ES'),('BR','NVI','Navirai','Navirai','MS'),('BR','NVO','Nova Vicosa','Nova Vicosa','BA'),('BR','NVP','Novo Aripuana','Novo Aripuana','AM'),('BR','NVT','Navegantes','Navegantes','SC'),('BR','NZA','Nazare','Nazare','BA'),('BR','OAL','Cacoal','Cacoal','RO'),('BR','OBI','Obidos','Obidos','PA'),('BR','OBR','Ouro Branco','Ouro Branco','MG'),('BR','OCA','Otacilio Costa','Otacilio Costa','SC'),('BR','OCZ','Osvaldo Cruz','Osvaldo Cruz','SP'),('BR','ODI','Ocidental','Ocidental','GO'),('BR','OFI','Ouro Fino','Ouro Fino','MG'),('BR','OLA','Olinda','Olinda','PE'),('BR','OLI','Olimpia','Olimpia','SP'),('BR','OLS','Orleans','Orleans','SC'),('BR','ONO','Ourilandia do Norte','Ourilandia do Norte','PA'),('BR','OPE','Ouro Preto do Oeste','Ouro Preto do Oeste','RO'),('BR','OPO','Ouro Preto','Ouro Preto','MG'),('BR','OPS','Sinop','Sinop','MT'),('BR','ORE','Ouroeste','Ouroeste','SP'),('BR','ORI','Oriente','Oriente','SP'),('BR','ORL','Orlandia','Orlandia','SP'),('BR','ORX','Oriximina','Oriximina','PA'),('BR','OSO','Osorio','Osorio','RS'),('BR','OUS','Ourinhos','Ourinhos','SP'),('BR','OUT','Outeiro','Outeiro','PA'),('BR','OVA','Oliveira','Oliveira','MG'),('BR','OVD','Ouro Verde','Ouro Verde','SP'),('BR','OYK','Oiapoque','Oiapoque','AP'),('BR','PAA','Prata','Prata','MG'),('BR','PAC','Pariquera-Acu','Pariquera-Acu','SP'),('BR','PAE','Palmares Paulista','Palmares Paulista','SP'),('BR','PAF','Pati dos Alferes','Pati dos Alferes','RJ'),('BR','PAG','Pitangui','Pitangui','MG'),('BR','PAL','Paulista','Paulista','PE'),('BR','PAO','Portao','Portao','RS'),('BR','PAP','Papagaios','Papagaios','MG'),('BR','PAR','Para','Para','PA'),('BR','PAT','Parati','Parati','RJ'),('BR','PAV','Paulo Afonso','Paulo Afonso','BA'),('BR','PBA','Pereira Barreto','Pereira Barreto','SP'),('BR','PBB','Paranaiba','Paranaiba','MS'),('BR','PBE','Padre Bernardo','Padre Bernardo','GO'),('BR','PBI','Praia da Baleia','Praia da Baleia','CE'),('BR','PBJ','Pirapora do Bom Jesus','Pirapora do Bom Jesus','SP'),('BR','PBO','Porto Belo','Porto Belo','SC'),('BR','PBQ','Pimenta Bueno','Pimenta Bueno','RO'),('BR','PBR','Presidente Bernardes','Presidente Bernardes','SP'),('BR','PBU','Paraibuna','Paraibuna','SP'),('BR','PBV','Porto dos Gauchos','Porto dos Gauchos','MT'),('BR','PBX','Porto Alegre do Nort','Porto Alegre do Nort','MT'),('BR','PCA','Pedro Canario','Pedro Canario','ES'),('BR','PCF','Poco Fundo','Poco Fundo','MG'),('BR','PCI','Piracaia','Piracaia','SP'),('BR','PCJ','Pacajus','Pacajus','CE'),('BR','PCL','Portocel','Portocel','ES'),('BR','PCN','Pocone','Pocone','MT'),('BR','PCO','Patrocinio','Patrocinio','MG'),('BR','PCS','Picos','Picos','PI'),('BR','PCT','Paracatu','Paracatu','MG'),('BR','PCU','Pacaembu','Pacaembu','SP'),('BR','PDA','Pedreiras','Pedreiras','MA'),('BR','PDD','Piedade','Piedade','MG'),('BR','PDF','Prado','Prado','BA'),('BR','PDI','Pedreira','Pedreira','SP'),('BR','PDO','Penedo','Penedo','RJ'),('BR','PDR','Presidente Dutra','Presidente Dutra','MA'),('BR','PDS','Perdoes','Perdoes','MG'),('BR','PEC','Pecem','Pecem','CE'),('BR','PEL','Pimentel','Pimentel','MA'),('BR','PEN','Pedras Negras','Pedras Negras','RO'),('BR','PEO','Presidente Epitacio','Presidente Epitacio','SP'),('BR','PER','Pereiras','Pereiras','SP'),('BR','PES','Peres','Peres','GO'),('BR','PET','Pelotas','Pelotas','RS'),('BR','PFA','Paulo de Faria','Paulo de Faria','SP'),('BR','PFB','Passo Fundo','Passo Fundo','RS'),('BR','PFC','Praia do Frances','Praia do Frances','AL'),('BR','PFR','Praia do Forte','Praia do Forte','BA'),('BR','PFU','Presidente Figueiredo','Presidente Figueiredo','AM'),('BR','PFX','Ponta do Felix/Antonina','Ponta do Felix/Antonina','PR'),('BR','PGA','Pitangueiras','Pitangueiras','SP'),('BR','PGG','Progresso','Progresso','PA'),('BR','PGL','Presidente Getulio','Presidente Getulio','SC'),('BR','PGO','Paragominas','Paragominas','PA'),('BR','PGR','Praia Grande','Praia Grande','SP'),('BR','PGS','Porto de Galinhas','Porto de Galinhas','PE'),('BR','PGU','Pedregulho','Pedregulho','SP'),('BR','PGZ','Ponta Grossa','Ponta Grossa','PR'),('BR','PHA','Penha','Penha','SC'),('BR','PHB','Parnaiba','Parnaiba','PI'),('BR','PHI','Pinheiro','Pinheiro','MA'),('BR','PHO','Palhoca','Palhoca','SC'),('BR','PHS','Pinhais','Pinhais','RS'),('BR','PIA','Piratini','Piratini','RS'),('BR','PIB','Pirauba','Pirauba','MG'),('BR','PIE','Piedade','Piedade','SP'),('BR','PIG','Pitinga','Pitinga','AM'),('BR','PIH','Pinhais','Pinhais','PR'),('BR','PIL','Primavera do Leste','Primavera do Leste','MT'),('BR','PIN','Parintins','Parintins','AM'),('BR','PIO','Praia do Rosa','Praia do Rosa','SC'),('BR','PIP','Piripiri','Piripiri','PI'),('BR','PIR','Pirai','Pirai','RJ'),('BR','PIS','Palmeira dos Indios','Palmeira dos Indios','AL'),('BR','PIT','Piacatu','Piacatu','SP'),('BR','PIV','Pirapora','Pirapora','MG'),('BR','PJA','Piraju','Piraju','SP'),('BR','PJC','Pojuca','Pojuca','BA'),('BR','PJR','Pirajui','Pirajui','SP'),('BR','PJU','Piracanjuba','Piracanjuba','GO'),('BR','PLA','Palotina','Palotina','PR'),('BR','PLE','Pedro Leopoldo','Pedro Leopoldo','MG'),('BR','PLI','Pontalina','Pontalina','GO'),('BR','PLL','Ponta Pelada','Ponta Pelada','AM'),('BR','PLN','Planura','Planura','MG'),('BR','PLO','Palmitos','Palmitos','SC'),('BR','PLS','Pirenopolis','Pirenopolis','GO'),('BR','PLT','Planalto','Planalto','RS'),('BR','PLU','Pampulha','Pampulha','MG'),('BR','PMA','Ponta da Madeira','Ponta da Madeira',''),('BR','PMB','Praia de Tambaba','Praia de Tambaba','PB'),('BR','PMC','Presidente Medici','Presidente Medici','RO'),('BR','PME','Palmeira das Missoes','Palmeira das Missoes','RS'),('BR','PMG','Ponta Pora','Ponta Pora','MS'),('BR','PMH','Porto Murtinho','Porto Murtinho','MS'),('BR','PMI','Palmeira','Palmeira','PR'),('BR','PML','Palmital','Palmital','SP'),('BR','PMM','Parnamirim','Parnamirim','RN'),('BR','PMN','Para de Minas','Para de Minas','MG'),('BR','PMO','Promissao','Promissao','SP'),('BR','PMR','Palmeiras','Palmeiras','BA'),('BR','PMS','Palmares','Palmares','PE'),('BR','PMT','Pimenta','Pimenta','MG'),('BR','PMU','Pitimbu','Pitimbu','PB'),('BR','PMV','Primavera','Primavera','SP'),('BR','PMW','Palmas','Palmas','TO'),('BR','PNA','Panorama','Panorama','SP'),('BR','PNB','Porto Nacional','Porto Nacional','TO'),('BR','PNC','Porciuncula','Porciuncula','RJ'),('BR','PND','Pindorama','Pindorama','SP'),('BR','PNE','Penedo','Penedo','AL'),('BR','PNG','Paranagua','Paranagua','PR'),('BR','PNH','Piranhas','Piranhas','GO'),('BR','PNI','Panambi','Panambi','RS'),('BR','PNL','Pantanal','Pantanal','MS'),('BR','PNM','Pindamonhangaba','Pindamonhangaba','SP'),('BR','PNN','Parana','Parana','TO'),('BR','PNO','Paranoa','Paranoa','DF'),('BR','PNP','Penapolis','Penapolis','SP'),('BR','PNS','Pederneiras','Pederneiras','SP'),('BR','PNT','Pantanal','Pantanal','MT'),('BR','PNU','Paranauna','Paranauna','GO'),('BR','PNV','Ponte Nova','Ponte Nova','MG'),('BR','PNZ','Petrolina','Petrolina','PE'),('BR','POA','Porto Alegre','Porto Alegre','RS'),('BR','POC','Pocoes','Pocoes','BA'),('BR','POD','Potirendaba','Potirendaba','SP'),('BR','POJ','Patos De Minas','Patos De Minas','MG'),('BR','POM','Pomerode','Pomerode','SC'),('BR','POO','Pocos de Caldas','Pocos de Caldas','MG'),('BR','POP','Ponta Pora','Ponta Pora','MG'),('BR','POS','Palmeira do Oeste','Palmeira do Oeste','SP'),('BR','POT','Porecatu','Porecatu','PR'),('BR','POU','Ponta Ubu','Ponta Ubu','ES'),('BR','PPA','Pompeia','Pompeia','SP'),('BR','PPB','Presidente Prudente','Presidente Prudente','SP'),('BR','PPE','Paraopeba','Paraopeba','MG'),('BR','PPI','Paraguacu Paulista','Paraguacu Paulista','SP'),('BR','PPL','Pradopolis','Pradopolis','SP'),('BR','PPM','Paranapanema','Paranapanema','SP'),('BR','PPO','Palmeiropolis','Palmeiropolis','TO'),('BR','PPP','Praia da Pipa','Praia da Pipa','RN'),('BR','PPR','Palmas Parana','Palmas Parana','PR'),('BR','PPS','Patrocinio Paulista','Patrocinio Paulista','SP'),('BR','PPT','Pedrinhas Paulista','Pedrinhas Paulista','SP'),('BR','PPU','Parapua','Parapua','SP'),('BR','PPY','Pouso Alegre','Pouso Alegre','MG'),('BR','PQA','Piraquara','Piraquara','PR'),('BR','PQE','Pesqueira','Pesqueira','PE'),('BR','PQO','Passa Quatro','Passa Quatro','MG'),('BR','PQZ','Poa','Poa','SP'),('BR','PRA','Irapuru','Irapuru','SP'),('BR','PRB','Piratuba','Piratuba','SC'),('BR','PRC','Pinheiro Machado','Pinheiro Machado','RS'),('BR','PRE','Parobe','Parobe','RS'),('BR','PRG','Pirangi','Pirangi','SP'),('BR','PRI','Paraiso','Paraiso','SP'),('BR','PRL','Perola','Perola','PR'),('BR','PRM','Praia Mole','Praia Mole','ES'),('BR','PRN','Parauna','Parauna','GO'),('BR','PRO','Paraisopolis','Paraisopolis','MG'),('BR','PRP','Propria','Propria','SE'),('BR','PRR','Picarras','Picarras','SC'),('BR','PRS','Parauapebas','Parauapebas','PA'),('BR','PRT','Paranaita','Paranaita','MT'),('BR','PRU','Paracuru','Paracuru','CE'),('BR','PSA','Santana de Parnaiba','Santana de Parnaiba','SP'),('BR','PSI','Palestina','Palestina','SP'),('BR','PSL','Pilar do Sul','Pilar do Sul','SP'),('BR','PSO','Pimenteiras do Oeste','Pimenteiras do Oeste','RO'),('BR','PSR','Pires do Rio','Pires do Rio','GO'),('BR','PSS','Posse','Posse','GO'),('BR','PST','Pouso Alto','Pouso Alto','MG'),('BR','PSU','Paraiba do Sul','Paraiba do Sul','RJ'),('BR','PSW','Passos','Passos','MG'),('BR','PTA','Pirapetinga','Pirapetinga','MG'),('BR','PTB','Pirituba','Pirituba','SP'),('BR','PTC','Porto Franco','Porto Franco','MA'),('BR','PTD','Posto da Mata','Posto da Mata','BA'),('BR','PTE','Porto Real','Porto Real','RJ'),('BR','PTF','Porto Ferreira','Porto Ferreira','SP'),('BR','PTG','Paranatinga','Paranatinga','MT'),('BR','PTH','Porteirinha','Porteirinha','MG'),('BR','PTI','Paraiso do Tocantins','Paraiso do Tocantins','TO'),('BR','PTL','Pontal','Pontal','SP'),('BR','PTM','Porto do Mangue','Porto do Mangue','CE'),('BR','PTN','Patolina','Patolina','PR'),('BR','PTO','Pato Branco','Pato Branco','PR'),('BR','PTQ','Porto de Moz','Porto de Moz','PA'),('BR','PTR','Porto Rico','Porto Rico','PR'),('BR','PTS','Patos','Patos','PB'),('BR','PTU','Pacatuba','Pacatuba','CE'),('BR','PTZ','Porto Feliz','Porto Feliz','SP'),('BR','PUA','Ipua','Ipua','SP'),('BR','PUB','Peruibe','Peruibe','SP'),('BR','PUC','Paraguacu','Paraguacu','MG'),('BR','PUH','Piumhi','Piumhi','MG'),('BR','PUI','Paulinia','Paulinia','SP'),('BR','PUL','Paraiso do Sul','Paraiso do Sul','RS'),('BR','PUM','Piuma','Piuma','ES'),('BR','PUN','Porto Uniao','Porto Uniao','SC'),('BR','PUO','Prudentopolis','Prudentopolis','PR'),('BR','PVA','Pavao','Pavao','MG'),('BR','PVE','Presidente Venceslau','Presidente Venceslau','SP'),('BR','PVH','Porto Velho','Porto Velho','RO'),('BR','PVI','Paranavai','Paranavai','PR'),('BR','PVU','Pavuna','Pavuna','RJ'),('BR','PXA','Peixoto de Azevedo','Peixoto de Azevedo','MT'),('BR','PXI','Porto Xavier','Porto Xavier','RS'),('BR','PZI','Pinhalzinho','Pinhalzinho','SP'),('BR','PZO','Pirapozinho','Pirapozinho','SP'),('BR','PZS','Perdizes','Perdizes','MG'),('BR','QAB','Brusque','Brusque','SC'),('BR','QAH','Alcantara','Alcantara','RJ'),('BR','QAU','Bebedouro','Bebedouro','SP'),('BR','QAV','Benjamin Constant','Benjamin Constant','AM'),('BR','QBA','Quatro Barras','Quatro Barras','PR'),('BR','QBD','Barra do Pirai','Barra do Pirai','RJ'),('BR','QBN','Barra Mansa','Barra Mansa','RJ'),('BR','QBX','Sobral','Sobral','CE'),('BR','QCC','Camacari','Camacari','BA'),('BR','QCD','Campo Bom','Campo Bom','RS'),('BR','QCF','Birigui','Birigui','SP'),('BR','QCG','Cataguases','Cataguases','MG'),('BR','QCJ','Botucatu','Botucatu','SP'),('BR','QCK','Cabo Frio','Cabo Frio','RJ'),('BR','QCN','Canela','Canela','RS'),('BR','QCP','Currais Novos','Currais Novos','RN'),('BR','QCV','Guarulhos','Guarulhos','SP'),('BR','QCX','Sao Caetano do Sul','Sao Caetano do Sul','SP'),('BR','QDA','Charqueada','Charqueada','SP'),('BR','QDB','Cachoeira do Sul','Cachoeira do Sul','RS'),('BR','QDC','Dracena','Dracena','SP'),('BR','QDF','Conselheiro Lafaiete','Conselheiro Lafaiete','MG'),('BR','QDL','Guarapari','Guarapari','ES'),('BR','QDO','Icoaraci','Icoaraci','PA'),('BR','QDP','Dom Pedrito','Dom Pedrito','RS'),('BR','QDQ','Duque de Caxias','Duque de Caxias','RJ'),('BR','QGA','Guaira','Guaira','PR'),('BR','QGC','Lencois Paulista','Lencois Paulista','SP'),('BR','QGF','Montenegro','Montenegro','RS'),('BR','QHB','Piracicaba','Piracicaba','SP'),('BR','QHE','Sao Bento do Sul','Sao Bento do Sul','SC'),('BR','QHF','Sao Sebastiao do Cai','Sao Sebastiao do Cai','RS'),('BR','QHG','Sete Lagoas','Sete Lagoas','MG'),('BR','QHL','Castanhal','Castanhal','PA'),('BR','QHT','Teresopolis','Teresopolis','RJ'),('BR','QHV','Novo Hamburgo','Novo Hamburgo','RS'),('BR','QID','Tres Coracoes','Tres Coracoes','MG'),('BR','QIG','Iguatu','Iguatu','CE'),('BR','QIH','Tres Rios','Tres Rios','RJ'),('BR','QJA','Jaragua do Sul','Jaragua do Sul','SC'),('BR','QJO','Campos do Jordao','Campos do Jordao','SP'),('BR','QLB','Lajeado','Lajeado','RS'),('BR','QLL','Sao Leopoldo','Sao Leopoldo','RS'),('BR','QLU','Queluz','Queluz','SP'),('BR','QMA','Queimados','Queimados','RJ'),('BR','QMC','Mairipora','Mairipora','SP'),('BR','QMF','Mafra','Mafra','SC'),('BR','QMI','Mogi das Cruzes','Mogi das Cruzes','SP'),('BR','QMO','Quixeramobim','Quixeramobim','CE'),('BR','QNE','Rio Negrinho','Rio Negrinho','SC'),('BR','QNS','Canoas','Canoas','RS'),('BR','QOC','Osasco','Osasco','SP'),('BR','QPE','Petropolis','Petropolis','RJ'),('BR','QPO','Quirinopolis','Quirinopolis','GO'),('BR','QPS','Pirassununga','Pirassununga','SP'),('BR','QRA','Quarai','Quarai','RS'),('BR','QRO','Quatro Rodas','Quatro Rodas','PR'),('BR','QRP','Gramado','Gramado','RS'),('BR','QRU','Rio do Sul','Rio do Sul','SC'),('BR','QRZ','Resende','Resende','RJ'),('BR','QSB','Sao Bernardo do Campo','Sao Bernardo do Campo','SP'),('BR','QSC','Sao Carlos','Sao Carlos','SP'),('BR','QSD','Sao Goncalo','Sao Goncalo','RJ'),('BR','QSE','Santo Andre','Santo Andre','SP'),('BR','QSJ','Sao Joao del Rei','Sao Joao del Rei','MG'),('BR','QTA','Quata','Quata','SP'),('BR','QTS','Quatis','Quatis','RJ'),('BR','QVB','Uniao da Vitoria','Uniao da Vitoria','PR'),('BR','QVR','Volta Redonda','Volta Redonda','RJ'),('BR','QXA','Quixada','Quixada','CE'),('BR','RAC','Rio Acima','Rio Acima','MG'),('BR','RAI','Irai','Irai','RS'),('BR','RAO','Ribeirao Preto','Ribeirao Preto','SP'),('BR','RBA','Rio Brilhante','Rio Brilhante','MS'),('BR','RBB','Borba','Borba','AM'),('BR','RBI','Ribeirao Bonito','Ribeirao Bonito','SP'),('BR','RBO','Rio Bonito','Rio Bonito','RJ'),('BR','RBR','Rio Branco','Rio Branco','AC'),('BR','RCA','Rancharia','Rancharia','SP'),('BR','RCL','Rio Claro','Rio Claro','SP'),('BR','RCN','Rio das Contas','Rio das Contas','BA'),('BR','RCO','Rincao','Rincao','SP'),('BR','RCR','Ribeirao Cascalheira','Ribeirao Cascalheira','MT'),('BR','RCS','Rio Casca','Rio Casca','MG'),('BR','RDC','Redencao','Redencao','PA'),('BR','REC','Recife','Recife','PE'),('BR','REO','Redencao','Redencao','CE'),('BR','RFA','Rafard','Rafard','SP'),('BR','RFI','Rifaina','Rifaina','SP'),('BR','RFJ','Regente Feijo','Regente Feijo','SP'),('BR','RFO','Rio do Fogo','Rio do Fogo','RN'),('BR','RGA','Ribeirao Grande','Ribeirao Grande','SP'),('BR','RGI','Registro','Registro','SP'),('BR','RGS','Rio Grande da Serra','Rio Grande da Serra','SP'),('BR','RGT','Porangatu','Porangatu','GO'),('BR','RGV','Vargem Alta','Vargem Alta','ES'),('BR','RIA','Santa Maria','Santa Maria','RS'),('BR','RIG','Rio Grande','Rio Grande','RS'),('BR','RIO','Rio de Janeiro','Rio de Janeiro','RJ'),('BR','RIV','Rosario do Ivai','Rosario do Ivai','PR'),('BR','RJO','Rio de Janeiro Gig','Rio de Janeiro Gig','RJ'),('BR','RJS','Rio de Janeiro Sdu','Rio de Janeiro Sdu','RJ'),('BR','RLA','Riolandia','Riolandia','SP'),('BR','RLO','Rio Largo','Rio Largo','AL'),('BR','RMA','Remanso','Remanso','BA'),('BR','RMI','Rio Maria','Rio Maria','PA'),('BR','RMO','Carmo','Carmo','RJ'),('BR','RMU','Rolim de Moura','Rolim de Moura','RO'),('BR','RNB','Rural Paranaiba','Rural Paranaiba','MG'),('BR','RNO','Rio Negro','Rio Negro','PR'),('BR','RNV','Ribeirao das Neves','Ribeirao das Neves','MG'),('BR','ROL','Rolandia','Rolandia','PR'),('BR','ROO','Rondonopolis','Rondonopolis','MT'),('BR','ROS','Rosana','Rosana','SP'),('BR','RPA','Rio Paranaiba','Rio Paranaiba','MG'),('BR','RPB','Rio Pomba','Rio Pomba','MG'),('BR','RPE','Rio das Pedras','Rio das Pedras','SP'),('BR','RPI','Ribeirao Pires','Ribeirao Pires','SP'),('BR','RPM','Ribeira do Pombal','Ribeira do Pombal','BA'),('BR','RPO','Raposo','Raposo','RJ'),('BR','RPR','Rondon do Para','Rondon do Para','PA'),('BR','RPS','Rinopolis','Rinopolis','SP'),('BR','RQE','Rio Quente','Rio Quente','GO'),('BR','RRN','Serra Norte','Serra Norte','PA'),('BR','RRP','Ribas do Rio Pardo','Ribas do Rio Pardo','MS'),('BR','RSE','Reserva','Reserva','PR'),('BR','RSG','Serra Pelada','Serra Pelada','PA'),('BR','RSO','Rosario do Sul','Rosario do Sul','RS'),('BR','RSU','Ribeirao do Sul','Ribeirao do Sul','SP'),('BR','RTA','Rio das Ostras','Rio das Ostras','RJ'),('BR','RUB','Rubiataba','Rubiataba','GO'),('BR','RVD','Rio Verde','Rio Verde','GO'),('BR','RVO','Ribeirao Vermelho','Ribeirao Vermelho','MG'),('BR','RYB','Ruy Barbosa','Ruy Barbosa','BA'),('BR','RZA','Realeza','Realeza','PR'),('BR','SAA','Salinas','Salinas','MG'),('BR','SAB','Sabara','Sabara','MG'),('BR','SAD','Salvador do Sul','Salvador do Sul','RS'),('BR','SAE','Sape','Sape','PB'),('BR','SAF','Salto de Pirapora','Salto de Pirapora','SP'),('BR','SAG','Santo Agostinho','Santo Agostinho','PE'),('BR','SAJ','Santo Antonio de Jesus','Santo Antonio de Jesus','BA'),('BR','SAL','Salto Grande','Salto Grande','SP'),('BR','SAM','Santo Amaro','Santo Amaro','BA'),('BR','SAN','Santana','Santana','AM'),('BR','SAO','Sao Paulo','Sao Paulo','SP'),('BR','SAP','Sapiranga','Sapiranga','RS'),('BR','SAR','Santo Andre','Santo Andre','BA'),('BR','SAS','Santo Antonio da Posse','Santo Antonio da Posse','SP'),('BR','SAT','Salto','Salto','SP'),('BR','SAV','Santo Antonio Leverger','Santo Antonio Leverger','MT'),('BR','SAZ','Sao Goncalo do Amarante','Sao Goncalo do Amarante','RN'),('BR','SBD','Santa Barbara d\'Oeste','Santa Barbara d\'Oeste','SP'),('BR','SBE','Sao Benedito','Sao Benedito','CE'),('BR','SBH','Selbach','Selbach','RS'),('BR','SBI','Sombrio','Sombrio','SC'),('BR','SBJ','Sao Mateus','Sao Mateus','ES'),('BR','SBL','Sobralia','Sobralia','MG'),('BR','SBR','Santa Branca','Santa Branca','SP'),('BR','SBS','Sao Bento do Sapucai','Sao Bento do Sapucai','SP'),('BR','SBT','Sao Bento','Sao Bento','PB'),('BR','SBU','Sinimbu','Sinimbu','SC'),('BR','SCA','Casca','Casca','RS'),('BR','SCE','Serafina Correa','Serafina Correa','RS'),('BR','SCL','Sao Carlos','Sao Carlos','SC'),('BR','SCN','Serra da Canastra','Serra da Canastra','MG'),('BR','SCO','Santo Cristo','Santo Cristo','RJ'),('BR','SCS','Santa Clara do Sul','Santa Clara do Sul','RS'),('BR','SCT','Santo Cristo','Santo Cristo','RS'),('BR','SCU','Sao Pedro do Suacui','Sao Pedro do Suacui','MG'),('BR','SCV','Sao Cristovao','Sao Cristovao','SE'),('BR','SDA','Soledade','Soledade','RS'),('BR','SDC','Seropedica','Seropedica','RJ'),('BR','SDE','Schroeder','Schroeder','SC'),('BR','SDI','Sao Pedro do Ivai','Sao Pedro do Ivai','PR'),('BR','SDO','Santos Dumont','Santos Dumont','MG'),('BR','SDS','Sao Pedro do Sul','Sao Pedro do Sul','RS'),('BR','SDT','Sao Pedro do Turvo','Sao Pedro do Turvo','SP'),('BR','SDU','Santos Dumont Apt/Rio de Janeiro','Santos Dumont Apt/Rio de Janeiro','RJ'),('BR','SEI','Senhor do Bonfim','Senhor do Bonfim','BA'),('BR','SEO','Serro','Serro','MG'),('BR','SER','Serra','Serra','ES'),('BR','SEV','Serra da Capivara','Serra da Capivara','PI'),('BR','SFA','Sao Francisco de Assis','Sao Francisco de Assis','RS'),('BR','SFG','Sao Felix do Xingu','Sao Felix do Xingu','PA'),('BR','SFI','Sao Fidelis','Sao Fidelis','RJ'),('BR','SFK','Soure','Soure','PA'),('BR','SFN','Sao Francisco do Conde','Sao Francisco do Conde','BA'),('BR','SFO','Sao Francisco','Sao Francisco','ES'),('BR','SFP','Sao Francisco de Paula','Sao Francisco de Paula','MG'),('BR','SFR','Sao Francisco','Sao Francisco','MA'),('BR','SFS','Sao Francisco do Sul','Sao Francisco do Sul','SC'),('BR','SFV','Santa Fe do Sul','Santa Fe do Sul','SP'),('BR','SFX','Sao Felix','Sao Felix','BA'),('BR','SGA','Sao Gabriel','Sao Gabriel','RS'),('BR','SGC','Sao Goncalo dos Campos','Sao Goncalo dos Campos','BA'),('BR','SGE','Sao Goncalo do Amarante','Sao Goncalo do Amarante','CE'),('BR','SGI','Sergipe','Sergipe','SE'),('BR','SGL','Sao Geraldo','Sao Geraldo','MG'),('BR','SGO','Santiago','Santiago','RS'),('BR','SGP','Sao Gabriel da Palha','Sao Gabriel da Palha','ES'),('BR','SGR','Santa Gertrudes','Santa Gertrudes','SP'),('BR','SGS','Sao Gabriel do Oeste','Sao Gabriel do Oeste','MS'),('BR','SGT','Sao Gotardo','Sao Gotardo','MG'),('BR','SGU','Salgueiro','Salgueiro','PE'),('BR','SHA','Serrinha','Serrinha','BA'),('BR','SHG','Santa Helena de Goias','Santa Helena de Goias','GO'),('BR','SIA','Serrania','Serrania','MG'),('BR','SIB','Santa Isabel','Santa Isabel','SP'),('BR','SII','Santa Isabel do Ivai','Santa Isabel do Ivai','PR'),('BR','SIN','Santa Ines','Santa Ines','MA'),('BR','SIO','Serra do Cipo','Serra do Cipo','MG'),('BR','SIP','Santa Izabel do Para','Santa Izabel do Para','PA'),('BR','SIV','Silves','Silves','AM'),('BR','SJA','Sao Joao da Alianca','Sao Joao da Alianca','GO'),('BR','SJB','Sao Joaquim da Barra','Sao Joaquim da Barra','SP'),('BR','SJC','Sao Joao do Caiua','Sao Joao do Caiua','PR'),('BR','SJD','Sao Jose do Cedro','Sao Jose do Cedro','SC'),('BR','SJE','Sao Jose','Sao Jose','SC'),('BR','SJI','Sao Jose do Barreiro','Sao Jose do Barreiro','SP'),('BR','SJK','Sao Jose dos Campos','Sao Jose dos Campos','SP'),('BR','SJL','Sao Gabriel da Cachoeira','Sao Gabriel da Cachoeira','AM'),('BR','SJM','Sao Joao do Meriti','Sao Joao do Meriti','RJ'),('BR','SJN','Sao Joao Nepomucemo','Sao Joao Nepomucemo','MG'),('BR','SJO','Sao Jeronimo','Sao Jeronimo','RS'),('BR','SJP','Sao Jose do Rio Preto','Sao Jose do Rio Preto','SP'),('BR','SJQ','Sao Joaquim','Sao Joaquim','SC'),('BR','SJR','Sao Jose do Rio Claro','Sao Jose do Rio Claro','MT'),('BR','SJS','Sao Jose dos Pinhais','Sao Jose dos Pinhais','PR'),('BR','SJT','Sao Jose dos Ausentes','Sao Jose dos Ausentes','RS'),('BR','SJV','Sao Joao da Boa Vista','Sao Joao da Boa Vista','SP'),('BR','SLA','Santa Luzia','Santa Luzia','MG'),('BR','SLD','Sidrolandia','Sidrolandia','MS'),('BR','SLE','Sap Leopoldo','Sap Leopoldo','RS'),('BR','SLG','Sao Ludgero','Sao Ludgero','SC'),('BR','SLI','Santana do Livramento','Santana do Livramento','RS'),('BR','SLM','Sao Lourenco da Mata','Sao Lourenco da Mata','PE'),('BR','SLO','Sao Lourenco','Sao Lourenco','MG'),('BR','SLP','Sao Luis do Paraitinga','Sao Luis do Paraitinga','SP'),('BR','SLS','Sao Lourenco da Serra','Sao Lourenco da Serra','SP'),('BR','SLT','Sao Lourenco do Oeste','Sao Lourenco do Oeste','SC'),('BR','SLV','Salvaterra','Salvaterra','PA'),('BR','SLZ','Sao Luis','Sao Luis','MA'),('BR','SMA','Santa Maria Boa Vista','Santa Maria Boa Vista','PE'),('BR','SMB','Sao Luis de Montes Belos','Sao Luis de Montes Belos','GO'),('BR','SMC','Sao Marcos','Sao Marcos','RS'),('BR','SME','Sumare','Sumare','SP'),('BR','SMG','Sao Miguel do Gostoso','Sao Miguel do Gostoso','RN'),('BR','SMI','Sao Miguel das Missoes','Sao Miguel das Missoes','RS'),('BR','SMJ','Sao Miguel Arcanjo','Sao Miguel Arcanjo','SP'),('BR','SML','Sao Manuel','Sao Manuel','SP'),('BR','SMM','Santa Maria Madalena','Santa Maria Madalena','RJ'),('BR','SMN','Santa Mariana','Santa Mariana','PR'),('BR','SMO','Sacramento','Sacramento','MG'),('BR','SMP','Sao Miguel dos Campos','Sao Miguel dos Campos','AL'),('BR','SMR','Sao Miguel dos Touros','Sao Miguel dos Touros','RN'),('BR','SMS','Sao Mateus do Sul','Sao Mateus do Sul','PR'),('BR','SMT','Sao Miguel do Oeste','Sao Miguel do Oeste','SC'),('BR','SMU','Sud Mennucci','Sud Mennucci','SP'),('BR','SMV','Santa Maria da Vitoria','Santa Maria da Vitoria','BA'),('BR','SNA','Serrana','Serrana','SP'),('BR','SNB','Sana','Sana','RJ'),('BR','SNC','Sanclerlandia','Sanclerlandia','GO'),('BR','SND','Sarandi','Sarandi','RS'),('BR','SNE','Sirinhaem','Sirinhaem','PE'),('BR','SNF','Santa Cruz do Capibaribe','Santa Cruz do Capibaribe','PE'),('BR','SNG','Serra Negra','Serra Negra','SP'),('BR','SNH','Santa Helena','Santa Helena','PR'),('BR','SNI','Sarandi','Sarandi','PR'),('BR','SNL','Santa Adelia','Santa Adelia','SP'),('BR','SNO','Serranopolis','Serranopolis','GO'),('BR','SNP','Santana do Paraiso','Santana do Paraiso','MG'),('BR','SNQ','Santa Cruz do Rio Pardo','Santa Cruz do Rio Pardo','SP'),('BR','SNR','Santa Barbara','Santa Barbara','MG'),('BR','SNS','Sertanopolis','Sertanopolis','PR'),('BR','SNT','Santa Barbara do Para','Santa Barbara do Para','PA'),('BR','SNU','Sananduva','Sananduva','RS'),('BR','SNV','Santa Carmem','Santa Carmem','MT'),('BR','SNW','Santa Cruz Cabralia','Santa Cruz Cabralia','BA'),('BR','SNY','Santa Cruz das Palmeiras','Santa Cruz das Palmeiras','SP'),('BR','SNZ','Santa Cruz','Santa Cruz','RN'),('BR','SOA','Sonora','Sonora','MS'),('BR','SOB','Sobradinho','Sobradinho','AL'),('BR','SOC','Socorro','Socorro','SP'),('BR','SOD','Sorocaba','Sorocaba','SP'),('BR','SOI','Senhora de Oliveira','Senhora de Oliveira','MG'),('BR','SOO','Sorriso','Sorriso','MT'),('BR','SOP','Simao Pereira','Simao Pereira','MG'),('BR','SOR','Sooretama','Sooretama','ES'),('BR','SOS','Sao Simao','Sao Simao','SP'),('BR','SOU','Sousa','Sousa','PB'),('BR','SOV','Sales Oliveira','Sales Oliveira','SP'),('BR','SPA','S.Sebastiao do Passe','S.Sebastiao do Passe','BA'),('BR','SPB','Port of Itaguai','Port of Itaguai','RJ'),('BR','SPC','Sao Paulo Cgh','Sao Paulo Cgh','SP'),('BR','SPD','Sao Pedro','Sao Pedro','SP'),('BR','SPE','Sao Pedro Alcantara','Sao Pedro Alcantara','SC'),('BR','SPG','Sao Paulo Gru','Sao Paulo Gru','SP'),('BR','SPL','Santo Antonio do Pinhal','Santo Antonio do Pinhal','SP'),('BR','SPN','Santo Antonio da Platina','Santo Antonio da Platina','PR'),('BR','SPO','Salesopolis','Salesopolis','SP'),('BR','SPT','Sao Miguel Paulista','Sao Miguel Paulista','SP'),('BR','SPU','Santo Antonio da Patrulha','Santo Antonio da Patrulha','RS'),('BR','SPV','Sao Paulo de Olivenca','Sao Paulo de Olivenca','AM'),('BR','SPZ','Sapezal','Sapezal','MT'),('BR','SQA','Sao Roque do Canaa','Sao Roque do Canaa','ES'),('BR','SQC','Sao Jose Quatro Marcos','Sao Jose Quatro Marcos','MT'),('BR','SQM','Sao Miguel do Araguaia','Sao Miguel do Araguaia','GO'),('BR','SQN','Sao Roque de Minas','Sao Roque de Minas','MG'),('BR','SQR','Saquarema','Saquarema','RJ'),('BR','SQY','Sao Lourenco do Sul','Sao Lourenco do Sul','RS'),('BR','SRA','Santa Rosa','Santa Rosa','RS'),('BR','SRB','Surubim','Surubim','PE'),('BR','SRC','Santana do Riacho','Santana do Riacho','MG'),('BR','SRG','Santa Rita do Araguaia','Santa Rita do Araguaia','GO'),('BR','SRH','Sobradinho','Sobradinho','DF'),('BR','SRI','Sarapui','Sarapui','SP'),('BR','SRL','Sao Pedro da Aldeia','Sao Pedro da Aldeia','RJ'),('BR','SRM','Santo Amaro da Imperatriz','Santo Amaro da Imperatriz','SC'),('BR','SRN','Sao Raimundo Nonato','Sao Raimundo Nonato','PI'),('BR','SRO','Santa Rita do Oeste','Santa Rita do Oeste','SP'),('BR','SRP','Sao Francisco de Paula','Sao Francisco de Paula','RS'),('BR','SRQ','Sao Roque','Sao Roque','SP'),('BR','SRR','Santa Rita','Santa Rita','PB'),('BR','SRS','Santa Rita do Passa Quatro','Santa Rita do Passa Quatro','SP'),('BR','SRT','Sao Jose do Vale Rio Preto','Sao Jose do Vale Rio Preto','RJ'),('BR','SRU','Santa Rosa do Sul','Santa Rosa do Sul','SC'),('BR','SRV','Santa Rosa de Viterbo','Santa Rosa de Viterbo','SP'),('BR','SRW','Santa Rita do Sapucai','Santa Rita do Sapucai','MG'),('BR','SSA','Salvador','Salvador','BA'),('BR','SSE','Sao Sepe','Sao Sepe','RS'),('BR','SSF','Simoes Filho','Simoes Filho','BA'),('BR','SSG','Sao Sebastiao da Grama','Sao Sebastiao da Grama','SP'),('BR','SSI','Sao Simao','Sao Simao','GO'),('BR','SSL','Sao Jose da Lapa','Sao Jose da Lapa','MG'),('BR','SSM','Sao Jose de Mipibo','Sao Jose de Mipibo','RN'),('BR','SSO','Sao Sebastiao','Sao Sebastiao','SP'),('BR','SSP','Sao Sebastiao do Paraiso','Sao Sebastiao do Paraiso','MG'),('BR','SSR','Sao Sebastiao do Paraiso','Sao Sebastiao do Paraiso','SP'),('BR','SST','Serra do Salitre','Serra do Salitre','MG'),('BR','SSZ','Santos','Santos','SP'),('BR','STA','Santo Antonio de Padua','Santo Antonio de Padua','RJ'),('BR','STB','Santana','Santana','AP'),('BR','STC','Sitio do Conde','Sitio do Conde','BA'),('BR','STD','Serra Talhada','Serra Talhada','PE'),('BR','STE','Santa Teresa','Santa Teresa','ES'),('BR','STG','Santa Terezinha de Goias','Santa Terezinha de Goias','GO'),('BR','STJ','Santo Antonio do Jardim','Santo Antonio do Jardim','SP'),('BR','STL','Sao Tome das Letras','Sao Tome das Letras','MG'),('BR','STM','Santarem','Santarem','PA'),('BR','STN','Santo Antonio do Monte','Santo Antonio do Monte','MG'),('BR','STP','Santo Antonio do Amparo','Santo Antonio do Amparo','MG'),('BR','STZ','Santa Terezinha','Santa Terezinha','MT'),('BR','SUA','Suape','Suape','PE'),('BR','SUM','Sao Miguel Milagres','Sao Miguel Milagres','AL'),('BR','SUN','Santo Anastacio','Santo Anastacio','SP'),('BR','SUP','Sauipe','Sauipe','BA'),('BR','SUS','Sapucaia do Sul','Sapucaia do Sul','RS'),('BR','SVA','Saranduva','Saranduva','RS'),('BR','SVE','Severinia','Severinia','SP'),('BR','SVI','Santa Vitoria','Santa Vitoria','MG'),('BR','SVL','Silvianopolis','Silvianopolis','MG'),('BR','SVP','Santa Vitoria do Palmar','Santa Vitoria do Palmar','ES'),('BR','SVT','Sao Vicente','Sao Vicente','SP'),('BR','SWM','Suia-Missu','Suia-Missu','MT'),('BR','SXO','Sao Felix Do Araguaia','Sao Felix Do Araguaia','MT'),('BR','SXV','Sao Francisco Xavier','Sao Francisco Xavier','SP'),('BR','SZG','Sao Luiz Gonzaga','Sao Luiz Gonzaga','RS'),('BR','SZN','Suzano','Suzano','SP'),('BR','SZO','Sertaozinho','Sertaozinho','SP'),('BR','TAC','Tome-Acu','Tome-Acu','PA'),('BR','TAI','Taio','Taio','SC'),('BR','TAP','Tapes','Tapes','RS'),('BR','TAR','Terra de Areia','Terra de Areia','RS'),('BR','TAT','Tatui','Tatui','SP'),('BR','TAU','Taua','Taua','CE'),('BR','TBA','Taubate','Taubate','SP'),('BR','TBE','Taiobeiras','Taiobeiras','MG'),('BR','TBO','Tamboara','Tamboara','PR'),('BR','TBS','Tibau do Sul','Tibau do Sul','RN'),('BR','TBT','Tabatinga','Tabatinga','AM'),('BR','TBU','Tambau','Tambau','SP'),('BR','TCI','Tupaciguara','Tupaciguara','MG'),('BR','TCO','Trancoso','Trancoso','BA'),('BR','TCT','Tocantins','Tocantins','MG'),('BR','TCU','Tracunhaem','Tracunhaem','PE'),('BR','TDE','Tiradentes','Tiradentes','MG'),('BR','TEC','Telemaco Borba','Telemaco Borba','PR'),('BR','TET','Termisa Terminal','Termisa Terminal',''),('BR','TEU','Teutonia','Teutonia','RS'),('BR','TFF','Tefe','Tefe','AM'),('BR','TFL','Teofilo Otoni','Teofilo Otoni','MG'),('BR','TFO','Triunfo','Triunfo','PE'),('BR','TGA','Pitanga','Pitanga','PR'),('BR','TGI','Tibagi','Tibagi','PR'),('BR','TGN','Tiangua','Tiangua','CE'),('BR','TGQ','Tangara da Serra','Tangara da Serra','MT'),('BR','TGR','Tangara','Tangara','SC'),('BR','TGU','Taguatinga','Taguatinga','DF'),('BR','THA','Torrinha','Torrinha','SP'),('BR','THE','Teresina','Teresina','PI'),('BR','TIE','Tiete','Tiete','SP'),('BR','TIM','Timon','Timon','MA'),('BR','TIN','Trindade','Trindade','GO'),('BR','TIP','Tupi Paulista','Tupi Paulista','SP'),('BR','TJA','Tijucas','Tijucas','SC'),('BR','TJS','Tijuca do Sul','Tijuca do Sul','PR'),('BR','TLA','Tres Lagoas','Tres Lagoas','MG'),('BR','TLG','Tres Lagoas','Tres Lagoas','MS'),('BR','TLZ','Catalao','Catalao','GO'),('BR','TMA','Tamandare','Tamandare','PE'),('BR','TMB','Timbauba','Timbauba','PE'),('BR','TME','Tremembe','Tremembe','SP'),('BR','TMI','Tres de Maio','Tres de Maio','RS'),('BR','TMO','Timbo','Timbo','SC'),('BR','TMR','Tres Marias','Tres Marias','MG'),('BR','TMS','Tombos','Tombos','MG'),('BR','TMT','Trombetas','Trombetas','PA'),('BR','TNA','Tanabi','Tanabi','SP'),('BR','TNE','Tancredo Neves','Tancredo Neves','PA'),('BR','TNO','Tabuleiro do Norte','Tabuleiro do Norte','CE'),('BR','TOS','Touros','Touros','RN'),('BR','TOW','Toledo','Toledo','PR'),('BR','TPA','Tapirai','Tapirai','SP'),('BR','TPC','Tupancireta','Tupancireta','RS'),('BR','TPI','Itapira','Itapira','SP'),('BR','TPJ','Tapejara','Tapejara','PR'),('BR','TPO','Tenente Portela','Tenente Portela','RS'),('BR','TPS','Tres Passos','Tres Passos','RS'),('BR','TPU','Tabapua','Tabapua','SP'),('BR','TQA','Taquaritinga','Taquaritinga','SP'),('BR','TQB','Taquarituba','Taquarituba','SP'),('BR','TQN','Taquaritinga do Norte','Taquaritinga do Norte','PE'),('BR','TQU','Taquara','Taquara','RS'),('BR','TRA','Itarare','Itarare','SP'),('BR','TRB','Terra Boa','Terra Boa','PR'),('BR','TRE','Terenos','Terenos','MS'),('BR','TRF','Triunfo','Triunfo','RS'),('BR','TRI','Trairi','Trairi','CE'),('BR','TRM','Tramandai','Tramandai','RS'),('BR','TRP','Tres Pontas','Tres Pontas','MG'),('BR','TRQ','Tarauaca','Tarauaca','AC'),('BR','TRR','Tres Ranchos','Tres Ranchos','GO'),('BR','TRU','Taruma','Taruma','SP'),('BR','TRX','Terra Roxa','Terra Roxa','SP'),('BR','TSA','Taboao da Serra','Taboao da Serra','SP'),('BR','TSL','Catas Altas','Catas Altas','MG'),('BR','TSO','Teodoro Sampaio','Teodoro Sampaio','SP'),('BR','TSQ','Torres','Torres','RS'),('BR','TTA','Tapiratiba','Tapiratiba','SP'),('BR','TTO','Timoteo','Timoteo','MG'),('BR','TUB','Tubarao','Tubarao','SC'),('BR','TUP','Tupa','Tupa','SP'),('BR','TUR','Tucurui','Tucurui','PA'),('BR','TUT','Tutoia','Tutoia','MA'),('BR','TUV','Taiuva','Taiuva','SP'),('BR','TUZ','Tucuma','Tucuma','PA'),('BR','TVO','Turvo','Turvo','SC'),('BR','TVU','Tucuruvi','Tucuruvi','PA'),('BR','TXF','Teixeira de Freitas','Teixeira de Freitas','BA'),('BR','TZT','Treze Tilias','Treze Tilias','SC'),('BR','UAU','Uaua','Uaua','BA'),('BR','UBA','Uberaba','Uberaba','MG'),('BR','UBC','Urubici','Urubici','SC'),('BR','UBI','Ubirata','Ubirata','PR'),('BR','UBJ','Ubajara','Ubajara','CE'),('BR','UBQ','Uba','Uba','MG'),('BR','UBT','Ubatuba','Ubatuba','SP'),('BR','UCH','Uchoa','Uchoa','SP'),('BR','UDI','Uberlandia','Uberlandia','MG'),('BR','UMU','Umuarama','Umuarama','PR'),('BR','UNA','Una','Una','BA'),('BR','UNI','Unai','Unai','MG'),('BR','UPA','Uniao dos Palmares','Uniao dos Palmares','AL'),('BR','UPE','Urupes','Urupes','SP'),('BR','URB','Urubupunga','Urubupunga','SP'),('BR','URG','Uruguaiana','Uruguaiana','RS'),('BR','URU','Uruacu','Uruacu','GO'),('BR','USS','Urussanga','Urussanga','SC'),('BR','UTA','Ubaitaba','Ubaitaba','BA'),('BR','UTB','Ubata','Ubata','BA'),('BR','VAG','Varginha','Varginha','MG'),('BR','VAH','Valinhos','Valinhos','SP'),('BR','VAJ','Vitoria do Jari','Vitoria do Jari','AP'),('BR','VAL','Valenca','Valenca','BA'),('BR','VAS','Vassouras','Vassouras','RJ'),('BR','VCA','Vacaria','Vacaria','RS'),('BR','VCE','Venancio Aires','Venancio Aires','RS'),('BR','VCO','Conde','Conde','PA'),('BR','VCP','Viracopos Apt/Sao Paolo','Viracopos Apt/Sao Paolo','SP'),('BR','VDC','Vitoria da Conquista','Vitoria da Conquista','BA'),('BR','VDO','Viradouro','Viradouro','SP'),('BR','VDS','Vitoria de Santo Antao','Vitoria de Santo Antao','PE'),('BR','VER','Vera','Vera','MT'),('BR','VGA','Vargem Grande','Vargem Grande','RJ'),('BR','VGL','Virgem da Lapa','Virgem da Lapa','MG'),('BR','VGO','Valparaiso de Goias','Valparaiso de Goias','GO'),('BR','VGP','Vargem Grande Paulista','Vargem Grande Paulista','SP'),('BR','VGR','Varzea Grande','Varzea Grande','MT'),('BR','VGS','Vargem Grande do Sul','Vargem Grande do Sul','SP'),('BR','VIA','Videira','Videira','SC'),('BR','VIC','Vila do Conde','Vila do Conde','PB'),('BR','VIH','Vilhena','Vilhena','RR'),('BR','VIN','Vinhedo','Vinhedo','SP'),('BR','VIS','Vicosa','Vicosa','MG'),('BR','VIX','Vitoria','Vitoria','ES'),('BR','VJO','Varjota','Varjota','CE'),('BR','VLA','Valenca','Valenca','RJ'),('BR','VLC','Vila do Conde','Vila do Conde','PA'),('BR','VLI','Vila Livieira','Vila Livieira','SP'),('BR','VLP','Vila Rica','Vila Rica','MT'),('BR','VMA','Viamao','Viamao','RS'),('BR','VMG','Rio Verde de Mato Grosso','Rio Verde de Mato Grosso','MS'),('BR','VMU','Visconce de Maua','Visconce de Maua','RJ'),('BR','VNA','Viana','Viana','ES'),('BR','VNI','Venda Nova do Imigrante','Venda Nova do Imigrante','ES'),('BR','VOP','Veranopolis','Veranopolis','RS'),('BR','VOT','Votuporanga','Votuporanga','SP'),('BR','VPA','Valparaizo','Valparaizo','GO'),('BR','VPM','Varzea da Palma','Varzea da Palma','MG'),('BR','VPO','Valparaiso','Valparaiso','SP'),('BR','VPS','Vianopolis','Vianopolis','GO'),('BR','VPU','Varzea Paulista','Varzea Paulista','SP'),('BR','VRB','Visconde do Rio Branco','Visconde do Rio Branco','MG'),('BR','VRC','Vera Cruz','Vera Cruz','SP'),('BR','VSA','Vespasiano','Vespasiano','MG'),('BR','VSN','Vitoria de Santo Antao','Vitoria de Santo Antao','RS'),('BR','VSO','Vale do Sol','Vale do Sol','RS'),('BR','VTM','Votorantim','Votorantim','SP'),('BR','VVE','Vila Velha','Vila Velha','ES'),('BR','VZA','Vazante','Vazante','MG'),('BR','VZY','Velizy','Velizy','PA'),('BR','WBZ','Wenceslau Braz','Wenceslau Braz','PR'),('BR','XAP','Chapeco','Chapeco','SC'),('BR','XAX','Xaxim','Xaxim','SC'),('BR','XGA','Xangrila','Xangrila','RS'),('BR','XIG','Xinguara','Xinguara','PA'),('BR','XQI','Xique-Xique','Xique-Xique','BA'),('BR','XTA','Ita','Ita','SC'),('BR','ZHO','Carazinho','Carazinho','RS'),('BR','ZMD','Sena Madureira','Sena Madureira','AC'),('BS','','','',''),('BS','ASD','Andros Town, Andros Island','Andros Town, Andros Island',''),('BS','ATC','Arthur\'s Town, Cat Island','Arthur\'s Town, Cat Island',''),('BS','AXP','Spring Point','Spring Point',''),('BS','BIM','Bimini','Bimini',''),('BS','CAT','Cat Island','Cat Island',''),('BS','CCZ','Chub Cay, Berry Islands','Chub Cay, Berry Islands',''),('BS','CEL','Cape Eleuthera','Cape Eleuthera',''),('BS','CLP','Clifton Point','Clifton Point',''),('BS','COX','Congo Town','Congo Town',''),('BS','CRI','Crooked Island','Crooked Island',''),('BS','CXY','Cat Cays','Cat Cays',''),('BS','DCT','Duncan Town','Duncan Town',''),('BS','ELE','Eleuthera Island','Eleuthera Island',''),('BS','ELH','North Eleuthera','North Eleuthera',''),('BS','EXU','Great Exuma Island','Great Exuma Island',''),('BS','FPO','Freeport, Grand Bahama','Freeport, Grand Bahama',''),('BS','GBI','Grand Bahama','Grand Bahama',''),('BS','GGT','George Town, Great Exuma I.','George Town, Great Exuma I.',''),('BS','GHB','Governors Harbour, Eleuthera','Governors Harbour, Eleuthera',''),('BS','GHC','Great Harbour Cay','Great Harbour Cay',''),('BS','GOC','Gorda Cay','Gorda Cay',''),('BS','GTC','Green Turtle Cay','Green Turtle Cay',''),('BS','HBI','Harbour Island','Harbour Island',''),('BS','HMC','Little San Salvador','Little San Salvador',''),('BS','IGA','Inagua','Inagua',''),('BS','LGI','Deadmans Cay','Deadmans Cay',''),('BS','MAT','Matthew Town','Matthew Town',''),('BS','MHH','Marsh Harbour','Marsh Harbour',''),('BS','MYG','Mayaguana Island','Mayaguana Island',''),('BS','NAS','Nassau','Nassau',''),('BS','NET','New Bight','New Bight',''),('BS','NMC','Norman\'s Cay','Norman\'s Cay',''),('BS','OCE','Ocean Cay','Ocean Cay',''),('BS','PID','Paradise Island','Paradise Island',''),('BS','PPO','Powell Point','Powell Point',''),('BS','PWN','Pitts Town','Pitts Town',''),('BS','RCY','Rum Cay','Rum Cay',''),('BS','RSD','Rock Sound','Rock Sound',''),('BS','SAQ','San Andros','San Andros',''),('BS','SML','Stella Maris','Stella Maris',''),('BS','SRP','South Riding Point','South Riding Point',''),('BS','SWL','Spanish Wells','Spanish Wells',''),('BS','TBI','The Bight','The Bight',''),('BS','TCB','Treasure Cay, Great Abaco I.','Treasure Cay, Great Abaco I.',''),('BS','TYM','Staniel Cay','Staniel Cay',''),('BS','TZN','South Andros','South Andros',''),('BS','WKR','Walker\'s Cay','Walker\'s Cay',''),('BS','WTD','West End','West End',''),('BS','WZY','Seaplane Base','Seaplane Base',''),('BS','ZSA','San Salvador Island','San Salvador Island',''),('BT','','','',''),('BT','PBH','Paro','Paro',''),('BT','PHU','Phuntsholing','Phuntsholing',''),('BT','THI','Thimbu','Thimbu',''),('BW','','','',''),('BW','BBK','Kasane','Kasane',''),('BW','FRW','Francistown','Francistown',''),('BW','GBE','Gaborone','Gaborone',''),('BW','GNZ','Ghanzi','Ghanzi',''),('BW','HUK','Hukuntsi','Hukuntsi',''),('BW','JWA','Jwaneng','Jwaneng',''),('BW','KHW','Khwai River Lodge','Khwai River Lodge',''),('BW','LET','Letlhakane','Letlhakane',''),('BW','LOQ','Lobatse','Lobatse',''),('BW','MAH','Mahalapye','Mahalapye',''),('BW','MUB','Maun','Maun',''),('BW','ORP','Orapa','Orapa',''),('BW','PAL','Palapye','Palapye',''),('BW','PKW','Selebi-Phikwe','Selebi-Phikwe',''),('BW','RSA','Ramotswa','Ramotswa',''),('BW','SER','Serowe','Serowe',''),('BW','SUN','Sunnyside','Sunnyside',''),('BW','SVT','Savuti','Savuti',''),('BW','SWX','Shakawe','Shakawe',''),('BW','SXN','Suapan','Suapan',''),('BW','TBY','Tsabong','Tsabong',''),('BW','TLD','Tuli Lodge','Tuli Lodge',''),('BY','','','',''),('BY','BAR','Barysaw','Barysaw',''),('BY','BMO','Bol\'shiye Motykaly','Bol\'shiye Motykaly',''),('BY','BNV','Baranovichi','Baranovichi',''),('BY','BOB','Bobruysk','Bobruysk',''),('BY','BQT','Brest','Brest',''),('BY','BZA','Berezovka','Berezovka',''),('BY','DZK','Dzerzhinsk','Dzerzhinsk',''),('BY','GAT','Gatovo','Gatovo',''),('BY','GME','Gomel','Gomel',''),('BY','GNA','Grodna','Grodna',''),('BY','KBY','Kobryn','Kobryn',''),('BY','KHO','Khoyniki','Khoyniki',''),('BY','KLK','Kletsk','Kletsk',''),('BY','KNV','Kokhanovo','Kokhanovo',''),('BY','KOP','Koptevka','Koptevka',''),('BY','KYC','Kostyukovichi','Kostyukovichi',''),('BY','LNY','Luninyets','Luninyets',''),('BY','MAZ','Mazyr','Mazyr',''),('BY','MSQ','Minsk','Minsk',''),('BY','MVQ','Mogilev','Mogilev',''),('BY','MZY','Maladzyechna','Maladzyechna',''),('BY','NPK','Navapolatsk','Navapolatsk',''),('BY','PIK','Pinsk','Pinsk',''),('BY','POK','Polock','Polock',''),('BY','RYA','Rechytsa','Rechytsa',''),('BY','SGA','Smorgon','Smorgon',''),('BY','SMV','Smolevichi','Smolevichi',''),('BY','SNM','Slonim','Slonim',''),('BY','SVS','Svisloch','Svisloch',''),('BY','VAW','Vawkavysk','Vawkavysk',''),('BY','VTB','Vitebsk','Vitebsk',''),('BY','ZHO','Zhlobin','Zhlobin',''),('BZ','','','',''),('BZ','BAR','Barranco','Barranco',''),('BZ','BGK','Big Creek','Big Creek',''),('BZ','BMP','Belmopan','Belmopan',''),('BZ','BZE','Belize City','Belize City',''),('BZ','COL','Colinto','Colinto',''),('BZ','CZH','Corozal','Corozal',''),('BZ','DGA','Dangriga','Dangriga',''),('BZ','MDB','Melinda','Melinda',''),('BZ','ORZ','Orange Walk','Orange Walk',''),('BZ','PND','Punta Gorda','Punta Gorda',''),('BZ','SPR','San Pedro','San Pedro',''),('BZ','SVK','Silver Creek','Silver Creek',''),('CA','','','',''),('CA','AAL','Alert Bay','Alert Bay','BC'),('CA','ABB','Abbotsford','Abbotsford','BC'),('CA','ABE','Abercrombie','Abercrombie','NS'),('CA','ABT','Alberta','Alberta','ON'),('CA','ABV','Abram-Village','Abram-Village','PE'),('CA','ACL','Ayer\'s Cliff','Ayer\'s Cliff','QC'),('CA','ACO','Aulds Cove','Aulds Cove','NS'),('CA','ACT','Acton','Acton','ON'),('CA','ACV','Acton Vale','Acton Vale','QC'),('CA','ADE','Aldergrove','Aldergrove','BC'),('CA','ADH','Ardath','Ardath','SK'),('CA','ADM','St Augustin-Deux-Montagnes','St Augustin-Deux-Montagnes','QC'),('CA','ADP','Ste Anne-des-Plaines','Ste Anne-des-Plaines','QC'),('CA','AEO','Ma-Ma-O Beach','Ma-Ma-O Beach','AB'),('CA','AGI','Agincourt','Agincourt','ON'),('CA','AGU','Aguathuna','Aguathuna','NL'),('CA','AHN','Acheson','Acheson','AB'),('CA','AIR','Airdrie','Airdrie','AB'),('CA','AJU','Anjou','Anjou','QC'),('CA','AJX','Ajax','Ajax','ON'),('CA','ALF','Alfred','Alfred','ON'),('CA','ALH','Alhambra','Alhambra','AB'),('CA','ALI','Alix','Alix','AB'),('CA','ALK','Adlavik','Adlavik','NL'),('CA','ALN','Allan','Allan','SK'),('CA','ALO','L\'Anse-au-Loup','L\'Anse-au-Loup','NL'),('CA','ALT','Alton','Alton','ON'),('CA','AMA','Alliston','Alliston','ON'),('CA','AMH','Amherstburg','Amherstburg','ON'),('CA','AMN','Amherst','Amherst','NS'),('CA','ANB','Andys Bay','Andys Bay','BC'),('CA','ANC','Ancaster','Ancaster','ON'),('CA','ANI','Annacis Island','Annacis Island','BC'),('CA','ANP','Arnprior','Arnprior','ON'),('CA','ANT','Antigonish','Antigonish','NS'),('CA','ANZ','Anzac','Anzac','AB'),('CA','APT','St Agapit','St Agapit','QC'),('CA','ARB','Arctic Bay','Arctic Bay','NU'),('CA','ARC','Arnold\'s Cove','Arnold\'s Cove','NL'),('CA','ARG','Arborg','Arborg','MB'),('CA','ARI','Arichat','Arichat','NS'),('CA','ARM','Armstrong','Armstrong','BC'),('CA','ART','Arthabaska','Arthabaska','QC'),('CA','ARU','Arundel','Arundel','QC'),('CA','ARX','Ariss','Ariss','ON'),('CA','ASB','Asbestos','Asbestos','QC'),('CA','ASO','Alvinston','Alvinston','ON'),('CA','ATB','Athabasca','Athabasca','AB'),('CA','ATH','Arthur','Arthur','ON'),('CA','ATL','Atlin','Atlin','BC'),('CA','ATO','Alberton','Alberton','PE'),('CA','AUL','Aulac','Aulac','NB'),('CA','AUQ','Austin','Austin','QC'),('CA','AUR','Aurora','Aurora','ON'),('CA','AUX','Pointe-aux-Outardes','Pointe-aux-Outardes','QC'),('CA','AVL','Avonlea','Avonlea','SK'),('CA','AVM','Angusville','Angusville','MB'),('CA','AVO','Avondale','Avondale','NL'),('CA','AVY','Acadia Valley','Acadia Valley','AB'),('CA','AWD','Atwood','Atwood','ON'),('CA','AXO','Altona','Altona','MB'),('CA','AYD','Aylesford','Aylesford','NS'),('CA','AYH','Aylsham','Aylsham','SK'),('CA','AYL','Aylmer','Aylmer','ON'),('CA','AYM','Aylmer','Aylmer','QC'),('CA','AYR','Ayr','Ayr','ON'),('CA','AYY','Albany','Albany','PE'),('CA','BAA','Bala','Bala','ON'),('CA','BAD','Baddeck','Baddeck','NS'),('CA','BAF','Banff','Banff','AB'),('CA','BAL','Balmertown','Balmertown','ON'),('CA','BAM','Bamberton','Bamberton','BC'),('CA','BAN','Barrington','Barrington','NS'),('CA','BAR','Barrie','Barrie','ON'),('CA','BAS','Bayside','Bayside','ON'),('CA','BAT','Bathurst','Bathurst','NB'),('CA','BAW','Batawa','Batawa','ON'),('CA','BAY','Bayside (St Roberts)','Bayside (St Roberts)','NB'),('CA','BAZ','St-Jean-Baptiste','St-Jean-Baptiste','QC'),('CA','BBA','Breadalbane','Breadalbane','PE'),('CA','BBB','Blubber Bay','Blubber Bay','BC'),('CA','BBD','Boisbriand','Boisbriand','QC'),('CA','BBN','Bernard','Bernard','NU'),('CA','BBU','Bay Bulls','Bay Bulls','NL'),('CA','BBY','Blind Bay','Blind Bay','BC'),('CA','BCF','Beaconsfield','Beaconsfield','QC'),('CA','BCK','Brockville','Brockville','ON'),('CA','BCL','Bon Conseil','Bon Conseil','QC'),('CA','BCO','Baie Comeau','Baie Comeau','QC'),('CA','BCV','Beale Cove','Beale Cove','BC'),('CA','BDE','Baden','Baden','ON'),('CA','BDF','Bedford','Bedford','NS'),('CA','BDR','Bald Rock','Bald Rock','NS'),('CA','BDT','Burdett','Burdett','AB'),('CA','BDU','Baie d\'Urfe','Baie d\'Urfe','QC'),('CA','BDV','Bay de Verde','Bay de Verde','NL'),('CA','BEA','Beaver Cove','Beaver Cove','BC'),('CA','BEC','Becancour','Becancour','QC'),('CA','BED','Bedford','Bedford','QC'),('CA','BEH','Beaver Harbour','Beaver Harbour','NB'),('CA','BEI','Bear Island','Bear Island','NB'),('CA','BEL','Belledune','Belledune','NB'),('CA','BEN','Beeton','Beeton','ON'),('CA','BEQ','Bedeque','Bedeque','PE'),('CA','BER','Berthierville','Berthierville','QC'),('CA','BET','Beaumont','Beaumont','AB'),('CA','BEU','Beauceville','Beauceville','QC'),('CA','BFD','Brookfeild','Brookfeild','NS'),('CA','BFI','Bois-des-Filion','Bois-des-Filion','QC'),('CA','BFR','Beresford','Beresford','NB'),('CA','BFT','Bluffton','Bluffton','AB'),('CA','BFW','St Boniface','St Boniface','MB'),('CA','BGH','Brighton','Brighton','ON'),('CA','BGT','Bagotville','Bagotville','QC'),('CA','BHA','Beauharnois','Beauharnois','QC'),('CA','BHI','Birds Hill','Birds Hill','MB'),('CA','BHM','Blenheim','Blenheim','ON'),('CA','BIR','Biggar','Biggar','SK'),('CA','BIX','Saint Brieux','Saint Brieux','SK'),('CA','BJO','Baie-Johan-Beetz','Baie-Johan-Beetz','QC'),('CA','BKF','Blackfalds','Blackfalds','AB'),('CA','BKI','Blackie','Blackie','AB'),('CA','BKL','Black Lake','Black Lake','QC'),('CA','BKN','Brooklyn','Brooklyn','NS'),('CA','BKS','Brooks','Brooks','AB'),('CA','BKV','Blackville','Blackville','NB'),('CA','BLA','Blainville','Blainville','QC'),('CA','BLC','Bella Coola','Bella Coola','BC'),('CA','BLE','Bridge Lake','Bridge Lake','BC'),('CA','BLH','Blacks Harbour','Blacks Harbour','NB'),('CA','BLJ','St-Bruno-du-Lac-St-Jean','St-Bruno-du-Lac-St-Jean','QC'),('CA','BLL','Beloeil','Beloeil','QC'),('CA','BLM','Belmond','Belmond','ON'),('CA','BLO','Beaverlodge','Beaverlodge','AB'),('CA','BLR','Blind River','Blind River','ON'),('CA','BLS','Balckstock','Balckstock','ON'),('CA','BLT','Bolton','Bolton','ON'),('CA','BLV','Belleville','Belleville','ON'),('CA','BMI','Bloomfield','Bloomfield','ON'),('CA','BMN','Blumenort','Blumenort','MB'),('CA','BMT','Blue Mountain','Blue Mountain','ON'),('CA','BMV','Beamsville','Beamsville','ON'),('CA','BOB','Bobcaygeon','Bobcaygeon','ON'),('CA','BOE','Bonnyville','Bonnyville','AB'),('CA','BOI','Boiestown','Boiestown','NB'),('CA','BON','Burton','Burton','BC'),('CA','BOR','Borden','Borden','PE'),('CA','BOU','Boucherville','Boucherville','QC'),('CA','BOW','Bowden','Bowden','AB'),('CA','BPF','Bishop\'s Falls','Bishop\'s Falls','NL'),('CA','BPL','Belle Plaine','Belle Plaine','SK'),('CA','BPO','Beach Point','Beach Point','PE'),('CA','BPT','Beauport','Beauport','QC'),('CA','BRA','Bradford','Bradford','ON'),('CA','BRB','Bracebridge','Bracebridge','ON'),('CA','BRD','Brentwood Bay','Brentwood Bay','BC'),('CA','BRH','Barrhead','Barrhead','AB'),('CA','BRI','Britannia Beach','Britannia Beach','BC'),('CA','BRJ','Brownsburg-Chatham','Brownsburg-Chatham','QC'),('CA','BRK','Brooklin','Brooklin','ON'),('CA','BRL','Burlington','Burlington','ON'),('CA','BRM','Bramalea','Bramalea','ON'),('CA','BRN','Brantford','Brantford','ON'),('CA','BRO','Brossard','Brossard','QC'),('CA','BRP','Brampton','Brampton',''),('CA','BRR','Barriere','Barriere','BC'),('CA','BRS','Barrs Corner','Barrs Corner','NS'),('CA','BRT','Broughton Is','Broughton Is','NU'),('CA','BRV','Iles de Boucherville','Iles de Boucherville','QC'),('CA','BRW','Bridgewater','Bridgewater','NS'),('CA','BSA','Baie-Sainte-Anne','Baie-Sainte-Anne','NB'),('CA','BSC','Benoit\'s Cove','Benoit\'s Cove','NL'),('CA','BSJ','Beausejour','Beausejour','MB'),('CA','BSM','Berthier-sur-Mer','Berthier-sur-Mer','QC'),('CA','BSN','Batiscan','Batiscan','QC'),('CA','BSS','Boissevain','Boissevain','MB'),('CA','BST','Bayside, Charlotte','Bayside, Charlotte','NB'),('CA','BSU','Breslau','Breslau','ON'),('CA','BTA','Belfountain','Belfountain','ON'),('CA','BTF','Butterfly Bay','Butterfly Bay','BC'),('CA','BTH','Bath','Bath','ON'),('CA','BTN','Bridgetown','Bridgetown','NS'),('CA','BTT','Britt','Britt','ON'),('CA','BTV','Bromptonville','Bromptonville','QC'),('CA','BTY','Bethany','Bethany','ON'),('CA','BUB','Burnaby','Burnaby','BC'),('CA','BUC','Buckingham','Buckingham','QC'),('CA','BUD','Burford','Burford','ON'),('CA','BUE','Bouctouche','Bouctouche','NB'),('CA','BUI','Burin','Burin','NL'),('CA','BUO','Burgeo','Burgeo','NL'),('CA','BUR','Burgessville','Burgessville','ON'),('CA','BUS','Burnside','Burnside','NL'),('CA','BUZ','Port Burwell','Port Burwell','ON'),('CA','BVE','Baie Verte','Baie Verte','NL'),('CA','BWD','Botwood','Botwood','NL'),('CA','BWI','Bow Island','Bow Island','AB'),('CA','BWK','Berwick','Berwick','NS'),('CA','BWV','Bowmanville','Bowmanville','ON'),('CA','BYL','Bayfield','Bayfield','ON'),('CA','BYR','Bay Roberts','Bay Roberts','NL'),('CA','BYT','Bay Tree','Bay Tree','AB'),('CA','CAD','Caledonia','Caledonia','ON'),('CA','CAE','Camrose','Camrose','AB'),('CA','CAG','Canning','Canning','NS'),('CA','CAH','Canso','Canso','NS'),('CA','CAL','Calgary','Calgary','AB'),('CA','CAM','Campbell River','Campbell River','BC'),('CA','CAN','Candiac','Candiac','SK'),('CA','CAP','Cap-Pele','Cap-Pele','NB'),('CA','CAQ','Caraquet','Caraquet','NB'),('CA','CAR','Carcon City/Toronto','Carcon City/Toronto','ON'),('CA','CAS','Cambridge Station','Cambridge Station','NS'),('CA','CAT','Catalina','Catalina','NL'),('CA','CAV','Cavendish','Cavendish','PE'),('CA','CAY','Canyon Creek','Canyon Creek','AB'),('CA','CBC','Come By Chance','Come By Chance','NL'),('CA','CBE','Crystal Beach','Crystal Beach','ON'),('CA','CBF','Campbellford','Campbellford','ON'),('CA','CBG','Cobourg','Cobourg','ON'),('CA','CBH','Clarke\'s Beach','Clarke\'s Beach','NL'),('CA','CBI','Churchbridge','Churchbridge','SK'),('CA','CBK','Corner Brook','Corner Brook','NL'),('CA','CBL','Chamberlains','Chamberlains','NL'),('CA','CBN','Carbon','Carbon','AB'),('CA','CBO','Cabano','Cabano','QC'),('CA','CBV','Campbellville','Campbellville','ON'),('CA','CBY','Carberry','Carberry','MB'),('CA','CCB','Cowichan Bay','Cowichan Bay','BC'),('CA','CCF','Campbell Croft','Campbell Croft','ON'),('CA','CCH','Cochrane','Cochrane','AB'),('CA','CCI','Crystal City','Crystal City','MB'),('CA','CCM','Sainte-Cecile-De-Milton','Sainte-Cecile-De-Milton','QC'),('CA','CDA','Caledon','Caledon','ON'),('CA','CDB','Coldbrook','Coldbrook','NS'),('CA','CDC','Candiac','Candiac','QC'),('CA','CDG','Cardigan','Cardigan','PE'),('CA','CDN','Cardinal','Cardinal','ON'),('CA','CDO','Cape Dorset','Cape Dorset','NU'),('CA','CDS','Cardston','Cardston','AB'),('CA','CEN','Centreville','Centreville','NB'),('CA','CFQ','Creston','Creston','BC'),('CA','CGN','Carignan','Carignan','QC'),('CA','CGY','Chateauguay','Chateauguay','QC'),('CA','CHA','Charlottetown','Charlottetown','PE'),('CA','CHE','Cherryville','Cherryville','BC'),('CA','CHG','Charlesbourg','Charlesbourg','QC'),('CA','CHI','Chicoutimi','Chicoutimi','QC'),('CA','CHL','Cobble Hill','Cobble Hill','BC'),('CA','CHM','Chemainus','Chemainus','BC'),('CA','CHN','Chatham','Chatham','NB'),('CA','CHO','Chomedey','Chomedey','QC'),('CA','CHP','Chippawa','Chippawa','ON'),('CA','CHR','Chandler','Chandler','QC'),('CA','CHS','Cohasset','Cohasset','NS'),('CA','CHT','Cheticamp','Cheticamp','NS'),('CA','CHV','Churchill','Churchill','MB'),('CA','CHY','Chambly','Chambly','QC'),('CA','CIL','Change Islands','Change Islands','NL'),('CA','CJH','Chilko Lake','Chilko Lake','BC'),('CA','CKS','Cookshire','Cookshire','QC'),('CA','CLA','Clarenceville','Clarenceville','QC'),('CA','CLB','Colborne','Colborne','ON'),('CA','CLC','Clarke City','Clarke City','QC'),('CA','CLD','Carseland','Carseland','AB'),('CA','CLE','Clarenville','Clarenville','NL'),('CA','CLH','Clark\'s Harbour','Clark\'s Harbour','NS'),('CA','CLI','Clinton','Clinton','ON'),('CA','CLM','Claremont','Claremont','ON'),('CA','CLP','Clam Point','Clam Point','NS'),('CA','CLR','Clyde River','Clyde River','NU'),('CA','CLS','Carlisle','Carlisle','ON'),('CA','CLT','Carleton','Carleton','QC'),('CA','CMB','Chambord','Chambord','QC'),('CA','CME','Cap-de-la-Madeleine','Cap-de-la-Madeleine','QC'),('CA','CMN','Carman','Carman','MB'),('CA','CMO','Creemore','Creemore','ON'),('CA','CMP','Compton','Compton','QC'),('CA','CMR','Calmar','Calmar','AB'),('CA','CMS','Cap-aux-Meules','Cap-aux-Meules','QC'),('CA','CMV','Carmanville','Carmanville','NL'),('CA','CNA','Canora','Canora','SK'),('CA','CNC','Concord','Concord','ON'),('CA','CNM','Canmore','Canmore','AB'),('CA','CNN','Conklin','Conklin','AB'),('CA','CNT','Cannington','Cannington','ON'),('CA','CNY','Cluny','Cluny','AB'),('CA','COA','Coaticook','Coaticook','QC'),('CA','COC','Contrecoeur','Contrecoeur','QC'),('CA','COE','Cocagne','Cocagne','NB'),('CA','COH','Country Harbour','Country Harbour','NS'),('CA','COL','Collingwood','Collingwood','ON'),('CA','COM','Campbellton','Campbellton','NB'),('CA','COO','Coombs','Coombs','BC'),('CA','COP','Coppermine','Coppermine','NU'),('CA','COQ','Coquitlam','Coquitlam','BC'),('CA','COR','Corunna','Corunna','ON'),('CA','COU','Courtenay','Courtenay','BC'),('CA','COW','Cowansville','Cowansville','QC'),('CA','COX','Comox','Comox','BC'),('CA','COY','Colonsay','Colonsay','SK'),('CA','CPB','Campobello','Campobello','NB'),('CA','CPN','Chipman','Chipman','NB'),('CA','CPS','Cupids','Cupids','NL'),('CA','CPT','Canaport','Canaport','NB'),('CA','CPY','Cape Ray','Cape Ray','NL'),('CA','CRB','Carbonear','Carbonear','NL'),('CA','CRD','Crapaud','Crapaud','PE'),('CA','CRL','Prince Edward Island','Prince Edward Island','PE'),('CA','CRM','Creemore','Creemore','QC'),('CA','CRN','Caroline','Caroline','AB'),('CA','CRO','Crofton','Crofton','BC'),('CA','CRP','Carp','Carp','ON'),('CA','CRR','Courtright','Courtright','ON'),('CA','CRT','Cartier','Cartier','ON'),('CA','CRY','Charny','Charny','QC'),('CA','CSC','Cote Ste Catherine','Cote Ste Catherine','QC'),('CA','CSD','Cassidy','Cassidy','BC'),('CA','CSF','Crossfield','Crossfield','AB'),('CA','CSN','Clarkson','Clarkson','ON'),('CA','CSP','Clementsport','Clementsport','NS'),('CA','CSS','Casselman','Casselman','ON'),('CA','CST','Chester','Chester','NS'),('CA','CSU','Cote-St-Luc','Cote-St-Luc','QC'),('CA','CTI','Carstairs','Carstairs','AB'),('CA','CTM','Chatham','Chatham','ON'),('CA','CTO','Cape Tormentine','Cape Tormentine','NB'),('CA','CTS','Coutts','Coutts','AB'),('CA','CTT','Castleton','Castleton','ON'),('CA','CVA','Cleveland','Cleveland','NS'),('CA','CVL','Chesterville','Chesterville','ON'),('CA','CWI','Cornwallis Is','Cornwallis Is','NU'),('CA','CWK','Chilliwack','Chilliwack','BC'),('CA','CWL','Cornwall','Cornwall','ON'),('CA','CYP','Coley\'s Point','Coley\'s Point','NL'),('CA','CYR','Saint-Cyrille','Saint-Cyrille','QC'),('CA','DAC','Dacre','Dacre','ON'),('CA','DAR','Dartmouth','Dartmouth','NS'),('CA','DAS','Great Bear Lake','Great Bear Lake','NT'),('CA','DBL','Debolt','Debolt','AB'),('CA','DBT','Deschambault','Deschambault','QC'),('CA','DCN','Duncan Bay','Duncan Bay','BC'),('CA','DDN','Dundurn','Dundurn','SK'),('CA','DDO','Dollard-des-Ormeaux','Dollard-des-Ormeaux','QC'),('CA','DEB','Deception Bay','Deception Bay','QC'),('CA','DEL','Delta','Delta','BC'),('CA','DET','Debert Station','Debert Station','NS'),('CA','DFL','Duffield','Duffield','AB'),('CA','DGF','Douglas Lake','Douglas Lake','BC'),('CA','DHQ','Dunman','Dunman','ON'),('CA','DHR','Dorchester','Dorchester','NB'),('CA','DHS','Dalhousie','Dalhousie','NB'),('CA','DIC','Diamond City','Diamond City','AB'),('CA','DID','Didsbury','Didsbury','AB'),('CA','DIG','Digby','Digby','NS'),('CA','DIL','Dildo','Dildo','NL'),('CA','DLI','Delhi','Delhi','ON'),('CA','DLN','Dublin','Dublin','ON'),('CA','DLS','Delson/Quebec','Delson/Quebec','QC'),('CA','DNR','St Denis-sur-Richelieu','St Denis-sur-Richelieu','QC'),('CA','DOA','Doaktown','Doaktown','NB'),('CA','DOM','Don Mills','Don Mills','ON'),('CA','DON','Vaudreuil-Dorion','Vaudreuil-Dorion','QC'),('CA','DOR','Dorval','Dorval','QC'),('CA','DPP','Dieppe','Dieppe','NB'),('CA','DRD','Dresden','Dresden','ON'),('CA','DRM','Drumheller','Drumheller','AB'),('CA','DRU','Drummondville','Drummondville','QC'),('CA','DRY','Dryden','Dryden','ON'),('CA','DSR','Deseronto','Deseronto','ON'),('CA','DUD','Dundas','Dundas','ON'),('CA','DUN','Verdun','Verdun','QC'),('CA','DUQ','Duncan/Quam','Duncan/Quam','BC'),('CA','DUR','Durham','Durham','ON'),('CA','DVL','Danville','Danville','QC'),('CA','DVW','Downsview','Downsview','ON'),('CA','DWL','Dingwall','Dingwall','NS'),('CA','DWO','Dashwood','Dashwood','ON'),('CA','DYV','Daveluyville','Daveluyville','QC'),('CA','EAS','East York','East York','ON'),('CA','EBU','Embrun','Embrun','ON'),('CA','ECO','Economy','Economy','NS'),('CA','EDC','Edwards Cove','Edwards Cove','NL'),('CA','EDI','Grande-Digue','Grande-Digue','NB'),('CA','EDM','Edmonton','Edmonton','AB'),('CA','EDN','Edmundston','Edmundston','NB'),('CA','EDS','Edson','Edson','AB'),('CA','EGF','Englefeld','Englefeld','SK'),('CA','EGN','Elgin','Elgin','NB'),('CA','EKE','East Kemptville','East Kemptville','NS'),('CA','EKO','Erickson','Erickson','BC'),('CA','EKV','Eckville','Eckville','AB'),('CA','ELE','Elmsdale','Elmsdale','NS'),('CA','ELI','Elie','Elie','MB'),('CA','ELL','Ellerslie/Edmonton','Ellerslie/Edmonton','AB'),('CA','ELM','Elmira','Elmira','ON'),('CA','ELO','Elora','Elora','ON'),('CA','EMB','Embro','Embro','ON'),('CA','EMD','Elmwood','Elmwood','ON'),('CA','EMP','Empress','Empress','AB'),('CA','EMR','Elmira','Elmira','PE'),('CA','END','Endako','Endako','BC'),('CA','ENE','Erieau','Erieau','ON'),('CA','ENF','Enfield','Enfield','NS'),('CA','ENG','Engelwood','Engelwood','BC'),('CA','ENT','Entwistle','Entwistle','AB'),('CA','ENY','Enderby','Enderby','BC'),('CA','EPA','Espanola','Espanola','ON'),('CA','ERI','Erin','Erin','ON'),('CA','ESP','West Saint Paul','West Saint Paul','MB'),('CA','ESQ','Esquimalt','Esquimalt','BC'),('CA','ESS','Essex','Essex','ON'),('CA','EST','Estevan','Estevan','SK'),('CA','ETC','Etobicoke','Etobicoke','ON'),('CA','EVV','Elmvale','Elmvale','ON'),('CA','EXS','Exshaw','Exshaw','AB'),('CA','EXX','Exeter','Exeter','ON'),('CA','EYL','Haileybury','Haileybury','ON'),('CA','EYV','Emeryville','Emeryville','ON'),('CA','EZT','Elizabethtown','Elizabethtown','ON'),('CA','FAH','Falmouth','Falmouth','NS'),('CA','FAL','Fort Albany','Fort Albany','ON'),('CA','FAP','Father Point','Father Point','QC'),('CA','FAR','Farnham','Farnham','QC'),('CA','FBG','Forestburg','Forestburg','AB'),('CA','FCB','Falconbridge','Falconbridge','ON'),('CA','FCM','Kuujjuaq','Kuujjuaq','QC'),('CA','FCO','Fort Coulonge','Fort Coulonge','QC'),('CA','FCX','St Francois Xavier','St Francois Xavier','MB'),('CA','FER','Fort Erie','Fort Erie','ON'),('CA','FFE','Feversham','Feversham','ON'),('CA','FFS','Fort Frances','Fort Frances','ON'),('CA','FGH','Frelighsburg','Frelighsburg','QC'),('CA','FGS','Fergus','Fergus',''),('CA','FIB','Fisher Branch','Fisher Branch','MB'),('CA','FKN','Fort Franklin','Fort Franklin','NT'),('CA','FKO','Frankford','Frankford','ON'),('CA','FLC','St-Faustin','St-Faustin','QC'),('CA','FLK','Fox Lake','Fox Lake','AB'),('CA','FLV','Florenceville','Florenceville','NB'),('CA','FMA','Fort MacKay','Fort MacKay','AB'),('CA','FMC','Fort Macleod','Fort Macleod','AB'),('CA','FME','Fermeuse','Fermeuse','NL'),('CA','FNE','Fort Nelson','Fort Nelson','BC'),('CA','FNV','Ferme-Neuve','Ferme-Neuve','QC'),('CA','FOG','Fogo','Fogo','NL'),('CA','FOR','Fortune','Fortune','NL'),('CA','FOX','Foxley River','Foxley River','PE'),('CA','FPR','Fort Providence','Fort Providence','NT'),('CA','FRA','Fraser Mills','Fraser Mills','BC'),('CA','FRE','Fredericton','Fredericton','NB'),('CA','FRL','Francois Lake','Francois Lake','BC'),('CA','FRM','Fraser','Fraser','BC'),('CA','FRN','Farnham','Farnham','ON'),('CA','FRO','Frontier','Frontier','SK'),('CA','FRR','Fraser River','Fraser River','BC'),('CA','FRT','Freelton','Freelton','ON'),('CA','FRV','Forestville','Forestville','QC'),('CA','FSI','Fort Simpson','Fort Simpson','NT'),('CA','FSJ','Fort St John','Fort St John','BC'),('CA','FSK','Fort Saskatchewan','Fort Saskatchewan','AB'),('CA','FSM','Fort Smith','Fort Smith','NT'),('CA','FVE','Fort Vermilion','Fort Vermilion','AB'),('CA','FVL','Fabreville','Fabreville','QC'),('CA','FWC','Fenwick','Fenwick','ON'),('CA','FWL','Fort William','Fort William','ON'),('CA','FXO','Foxboro','Foxboro','ON'),('CA','GAE','Grande Anse','Grande Anse','NB'),('CA','GAL','Cambridge (ex Galt)','Cambridge (ex Galt)','ON'),('CA','GAN','Gander','Gander','NL'),('CA','GAT','Gatineau','Gatineau','QC'),('CA','GAX','Gaspereaux','Gaspereaux','PE'),('CA','GBT','Godbout','Godbout','QC'),('CA','GCA','Gros Cacouna','Gros Cacouna','QC'),('CA','GCR','Gloucester','Gloucester','ON'),('CA','GDE','Grand-Mere','Grand-Mere','QC'),('CA','GDN','Golden','Golden','BC'),('CA','GDU','Sangudo','Sangudo','AB'),('CA','GDV','Gardenville','Gardenville','ON'),('CA','GDW','Goodwood','Goodwood','ON'),('CA','GEO','Georgetown','Georgetown','PE'),('CA','GFA','Grand Falls-Windsor','Grand Falls-Windsor','NL'),('CA','GGS','Ganges','Ganges','BC'),('CA','GGW','Georgetown','Georgetown','ON'),('CA','GHU','Glen Huron','Glen Huron','ON'),('CA','GJI','Grand Bend','Grand Bend','ON'),('CA','GLB','Glace Bay','Glace Bay','NS'),('CA','GLD','Gerald','Gerald','SK'),('CA','GLE','Glencoe','Glencoe','ON'),('CA','GLK','Grassy Lake','Grassy Lake','AB'),('CA','GLL','Gull Lake','Gull Lake','SK'),('CA','GLP','Guelph','Guelph','ON'),('CA','GLT','Galt','Galt','ON'),('CA','GMA','Grand Manan','Grand Manan','NB'),('CA','GMO','Glen Morris','Glen Morris','ON'),('CA','GMY','Gormley','Gormley','ON'),('CA','GNF','Grenfell','Grenfell','SK'),('CA','GOH','Goderich','Goderich','ON'),('CA','GOL','Gold River','Gold River','NS'),('CA','GOO','Goose Bay','Goose Bay','NL'),('CA','GOR','Gold River','Gold River','BC'),('CA','GPE','Gaspe','Gaspe','QC'),('CA','GRA','Granby','Granby','QC'),('CA','GRB','Grand Bank','Grand Bank','NL'),('CA','GRE','Greenfield Park','Greenfield Park','QC'),('CA','GRF','Grand Falls','Grand Falls','NB'),('CA','GRI','Grimsby','Grimsby','ON'),('CA','GRM','Grand-Mere','Grand-Mere','QC'),('CA','GRN','Granton','Granton','NS'),('CA','GRO','Grouse Mountain','Grouse Mountain','BC'),('CA','GRS','Grindstone','Grindstone','QC'),('CA','GRV','Grand Valley','Grand Valley','ON'),('CA','GRZ','Grenville','Grenville','QC'),('CA','GSL','Taltheilei Narrows','Taltheilei Narrows','NT'),('CA','GTD','Grand Toys Dorval','Grand Toys Dorval','QC'),('CA','GUU','St Guillaume','St Guillaume','QC'),('CA','GVI','Grand View','Grand View','MB'),('CA','GVN','Glovertown','Glovertown','NL'),('CA','GXI','Girouxville','Girouxville','AB'),('CA','GYB','Guysborough','Guysborough','NS'),('CA','HAB','Hall Beach','Hall Beach','NU'),('CA','HAG','Hague','Hague','SK'),('CA','HAL','Halifax','Halifax','NS'),('CA','HAM','Hamilton','Hamilton','ON'),('CA','HAR','Harriet','Harriet','BC'),('CA','HAT','Hatch Point','Hatch Point','BC'),('CA','HAV','Havelock','Havelock','NB'),('CA','HAW','Hawkesbury','Hawkesbury','ON'),('CA','HBR','Harbour Breton','Harbour Breton','NL'),('CA','HBT','Haliburton','Haliburton','ON'),('CA','HBV','Hebbville','Hebbville','NS'),('CA','HCK','Hatchet Lake','Hatchet Lake','NS'),('CA','HCT','Harcourt','Harcourt','ON'),('CA','HDN','Huntingdon','Huntingdon','QC'),('CA','HEB','Hebertville','Hebertville','QC'),('CA','HEL','Hensall','Hensall','ON'),('CA','HGS','Hagersville','Hagersville','ON'),('CA','HGT','Hartington','Hartington','ON'),('CA','HIB','Hibernia','Hibernia','NS'),('CA','HIL','Hillsborough','Hillsborough','NB'),('CA','HJU','Haines Junction','Haines Junction','YT'),('CA','HKS','Hickson','Hickson','ON'),('CA','HLL','Holland Landing','Holland Landing','ON'),('CA','HMC','Harmac','Harmac','BC'),('CA','HMP','Hampden','Hampden','NL'),('CA','HNT','Hinton','Hinton','AB'),('CA','HOD','Holyrood','Holyrood','NL'),('CA','HOK','Shoal Lake','Shoal Lake','MB'),('CA','HOP','Hopedale','Hopedale','NL'),('CA','HOR','Hornby','Hornby','ON'),('CA','HPT','Hantsport','Hantsport','NS'),('CA','HRE','Harbour Grace','Harbour Grace','NL'),('CA','HRF','Horsefly','Horsefly','BC'),('CA','HRI','High River','High River','AB'),('CA','HRR','Harriston','Harriston','ON'),('CA','HRV','Harvey Station','Harvey Station','NB'),('CA','HRW','Harrow','Harrow','ON'),('CA','HSP','Havre St Pierre','Havre St Pierre','QC'),('CA','HTD','Hartland','Hartland','NB'),('CA','HUD','Hudson','Hudson','QC'),('CA','HUL','Hull','Hull','QC'),('CA','HUN','Huntsville','Huntsville','ON'),('CA','HUP','Huron Park','Huron Park','ON'),('CA','HUR','Hunter River','Hunter River','PE'),('CA','HVR','Hanover','Hanover','ON'),('CA','HWS','Howe Sound','Howe Sound','BC'),('CA','HYY','Harley','Harley','ON'),('CA','IBV','Iberville','Iberville','QC'),('CA','ICA','Irricana','Irricana','AB'),('CA','IGE','Inglewood','Inglewood','ON'),('CA','IGL','Igloolik','Igloolik','NU'),('CA','IGS','Ingersoll','Ingersoll','ON'),('CA','IHD','Indian Head','Indian Head','SK'),('CA','IKP','Innerkip','Innerkip','ON'),('CA','ILF','Ilford','Ilford','MB'),('CA','ING','Ingonish','Ingonish','NS'),('CA','INN','Innisfail','Innisfail','AB'),('CA','INT','Saint-Narcisse','Saint-Narcisse','QC'),('CA','IOC','Ioco','Ioco','BC'),('CA','ION','Iona','Iona','NS'),('CA','IPE','Ile Perrot','Ile Perrot','QC'),('CA','IQF','Iroquois Falls','Iroquois Falls','ON'),('CA','IQL','Iqaluit','Iqaluit','NU'),('CA','IRM','Irma','Irma','AB'),('CA','IRQ','Iroquois','Iroquois','ON'),('CA','ISI','Ingleside','Ingleside','ON'),('CA','ISL','Island Lake','Island Lake','MB'),('CA','IUM','Summit Lake','Summit Lake','BC'),('CA','IVN','Irvine','Irvine','AB'),('CA','IVS','Inverness','Inverness','NS'),('CA','IWO','Inwood','Inwood','ON'),('CA','IXC','Ile Aux Coudres','Ile Aux Coudres','QC'),('CA','JAV','Jacksonville','Jacksonville','NB'),('CA','JDS','St Joseph-de-Sorel','St Joseph-de-Sorel','QC'),('CA','JED','Jedway','Jedway','BC'),('CA','JEI','Jervis Inlet','Jervis Inlet','BC'),('CA','JEJ','Head of Jeddore','Head of Jeddore','NS'),('CA','JOF','Joffre','Joffre','AB'),('CA','JOL','Joliette','Joliette','QC'),('CA','JON','Jonquiere','Jonquiere','QC'),('CA','JPH','St Joseph','St Joseph','MB'),('CA','JPR','Jasper','Jasper','AB'),('CA','JST','Jordan Station','Jordan Station','ON'),('CA','KAC','Kincardine','Kincardine','ON'),('CA','KAN','Kanata','Kanata','ON'),('CA','KBD','Kent Bridge','Kent Bridge',''),('CA','KBG','Kleinburg','Kleinburg','ON'),('CA','KEA','Keoma','Keoma','AB'),('CA','KER','Inkerman','Inkerman','NB'),('CA','KES','Kelsey','Kelsey','MB'),('CA','KFS','Kingsey Falls','Kingsey Falls','QC'),('CA','KGK','Kedgwick','Kedgwick','NB'),('CA','KGN','Kingston','Kingston','NS'),('CA','KHO','Key Harbour','Key Harbour','ON'),('CA','KIF','Kingfisher Lake','Kingfisher Lake','ON'),('CA','KIK','Kirkland','Kirkland','QC'),('CA','KIN','Kingston','Kingston','ON'),('CA','KLY','Killarney','Killarney','ON'),('CA','KMK','Komoka','Komoka','ON'),('CA','KML','Kamloops','Kamloops','BC'),('CA','KNN','Knowlton','Knowlton','QC'),('CA','KNV','Knights Inlet','Knights Inlet','BC'),('CA','KNY','Kinoosao','Kinoosao','SK'),('CA','KOV','Kovik Bay','Kovik Bay','QC'),('CA','KRV','Oak Bluff','Oak Bluff','MB'),('CA','KSN','Kensington','Kensington','PE'),('CA','KST','Kinistino','Kinistino','SK'),('CA','KTB','Kettleby','Kettleby','ON'),('CA','KTC','Kitchener','Kitchener','ON'),('CA','KTL','Kentville','Kentville','NS'),('CA','KTM','Kitimat','Kitimat','BC'),('CA','KTO','Kintore','Kintore','ON'),('CA','KVL','Kingsville','Kingsville','ON'),('CA','KWI','King William Is','King William Is','NU'),('CA','KWK','Keswick','Keswick','ON'),('CA','KWL','Kelowna','Kelowna','BC'),('CA','KWN','Keewatin','Keewatin','ON'),('CA','LAC','Lachine/Montreal','Lachine/Montreal','QC'),('CA','LAD','Ladysmith','Ladysmith','BC'),('CA','LAG','L\'Ange-Gardien','L\'Ange-Gardien','QC'),('CA','LAH','Lake Harbour','Lake Harbour','NU'),('CA','LAL','L\'ancienne-Lorette','L\'ancienne-Lorette','QC'),('CA','LAM','La Malbaie','La Malbaie','QC'),('CA','LAN','L\'Assomption','L\'Assomption','QC'),('CA','LAS','LaSalle (La Salle)','LaSalle (La Salle)','QC'),('CA','LAT','Latchford','Latchford','ON'),('CA','LAU','Laurentides','Laurentides','QC'),('CA','LAV','Laval','Laval','QC'),('CA','LAW','Lakeview','Lakeview','ON'),('CA','LAZ','Lazo','Lazo','BC'),('CA','LBA','La Baie','La Baie','QC'),('CA','LBK','Little Brook','Little Brook','NS'),('CA','LBR','Labrador City','Labrador City','NL'),('CA','LCH','Lachute','Lachute','QC'),('CA','LCI','Les Cedres','Les Cedres','QC'),('CA','LCM','Lacombe','Lacombe','AB'),('CA','LCO','Lacolle','Lacolle','QC'),('CA','LCP','Lockeport','Lockeport','NS'),('CA','LCR','La Crete','La Crete','AB'),('CA','LCV','Lower Cove','Lower Cove',''),('CA','LDB','Lac du Bonnet','Lac du Bonnet','MB'),('CA','LDC','Leduc','Leduc','AB'),('CA','LDE','Leaskdale','Leaskdale','ON'),('CA','LDI','Linden','Linden','AB'),('CA','LDN','Ladner','Ladner','BC'),('CA','LDS','Lansdowne','Lansdowne','ON'),('CA','LEG','Le Gardeur','Le Gardeur','QC'),('CA','LEN','Lennoxville','Lennoxville','QC'),('CA','LEP','Lepreau','Lepreau','NB'),('CA','LEV','Levis','Levis','QC'),('CA','LGE','La Guadeloupe','La Guadeloupe','QC'),('CA','LGL','Legal','Legal','AB'),('CA','LGN','Lingan','Lingan','NS'),('CA','LGT','Langton','Langton','ON'),('CA','LHA','La Have','La Have','NS'),('CA','LIC','Little Current','Little Current','ON'),('CA','LIL','Lac-des-Iles','Lac-des-Iles','QC'),('CA','LIN','Little Narrows','Little Narrows','NS'),('CA','LIS','Delisle','Delisle','SK'),('CA','LIV','Liverpool','Liverpool','NS'),('CA','LKF','Lakefield','Lakefield','ON'),('CA','LKI','Lakeside','Lakeside','ON'),('CA','LKP','Lockport','Lockport','MB'),('CA','LLI','Lake Louise','Lake Louise','AB'),('CA','LMD','Lomond','Lomond','NL'),('CA','LME','Lac-Megantic','Lac-Megantic','QC'),('CA','LMN','Leamington','Leamington','ON'),('CA','LND','Lindsay','Lindsay','ON'),('CA','LNG','Langley','Langley','BC'),('CA','LNP','Longue-Pointe','Longue-Pointe','QC'),('CA','LNV','Lorneville','Lorneville','ON'),('CA','LOB','Lobo','Lobo','ON'),('CA','LOD','London','London','ON'),('CA','LOH','Long Harbour','Long Harbour','NL'),('CA','LOM','Lomond','Lomond','AB'),('CA','LON','Longueuil','Longueuil','QC'),('CA','LOO','Lillooet','Lillooet','BC'),('CA','LOP','Long Pond','Long Pond','NL'),('CA','LOR','L\'Orignal','L\'Orignal','ON'),('CA','LOT','Lotbiniere','Lotbiniere','QC'),('CA','LOU','Louisbourg','Louisbourg','NS'),('CA','LPE','La Prairie','La Prairie','QC'),('CA','LPO','La Pocatiere','La Pocatiere','QC'),('CA','LPT','La Patrie','La Patrie','QC'),('CA','LQE','Lameque','Lameque','NB'),('CA','LRA','Leaf Rapids','Leaf Rapids','MB'),('CA','LRI','Lanoraie','Lanoraie','QC'),('CA','LRQ','Laurie River','Laurie River','MB'),('CA','LRS','Leross','Leross','SK'),('CA','LSA','Laurier-Station','Laurier-Station','QC'),('CA','LSO','Little Shemogue','Little Shemogue','NB'),('CA','LST','Long Sault','Long Sault','ON'),('CA','LSV','Louiseville','Louiseville','QC'),('CA','LTB','Lethbridge','Lethbridge','AB'),('CA','LTW','Listowel','Listowel','ON'),('CA','LUN','Lunenburg','Lunenburg','NS'),('CA','LUU','Lucan','Lucan','ON'),('CA','LUY','Lumby','Lumby','BC'),('CA','LVH','Laverlochere','Laverlochere','QC'),('CA','LVL','Loretteville','Loretteville','QC'),('CA','LVY','Lively','Lively','ON'),('CA','LWB','Lowbanks','Lowbanks','ON'),('CA','LWH','Lower Woods Harbour','Lower Woods Harbour','NS'),('CA','LWP','Lewisporte','Lewisporte','NL'),('CA','LZN','Lauzon','Lauzon','QC'),('CA','MAD','Madoc','Madoc','ON'),('CA','MAG','Magog','Magog','QC'),('CA','MAI','Maisonnette Point','Maisonnette Point','NB'),('CA','MAL','Malton','Malton','ON'),('CA','MAM','Mamramcook','Mamramcook','NB'),('CA','MAN','Mansonville','Mansonville','QC'),('CA','MAP','Maple','Maple','ON'),('CA','MAR','Marathon','Marathon','ON'),('CA','MAS','Masson','Masson','QC'),('CA','MAY','Mayerthorpe','Mayerthorpe','AB'),('CA','MBE','Moonbeam','Moonbeam','ON'),('CA','MBL','Mont Tremblant','Mont Tremblant','QC'),('CA','MBO','Montebello','Montebello','QC'),('CA','MBR','Main Brook','Main Brook','NL'),('CA','MBY','Mount Brydges','Mount Brydges','ON'),('CA','MCE','Miscouche','Miscouche','PE'),('CA','MCM','McMasterville','McMasterville','QC'),('CA','MCN','McLean','McLean','SK'),('CA','MCR','Maple Creek','Maple Creek','SK'),('CA','MCY','Mccreary','Mccreary','MB'),('CA','MDB','Meldrum Bay','Meldrum Bay','ON'),('CA','MDL','Middleton','Middleton','NS'),('CA','MDP','Middleton','Middleton','PE'),('CA','MDT','Midhurst','Midhurst','ON'),('CA','MEB','Menzies Bay','Menzies Bay','BC'),('CA','MED','Meductic','Meductic','NB'),('CA','MEG','Mount Elgin','Mount Elgin','ON'),('CA','MER','Mercier','Mercier','QC'),('CA','MET','Meteghan','Meteghan','NS'),('CA','MGD','Magdalen Is','Magdalen Is','QC'),('CA','MGN','Montmagny','Montmagny','QC'),('CA','MGU','Montague','Montague','PE'),('CA','MHB','Mahone Bay','Mahone Bay','NS'),('CA','MHL','Mitchell','Mitchell','ON'),('CA','MHO','Mount Hope','Mount Hope','ON'),('CA','MHP','St-Mathieu-du-Parc','St-Mathieu-du-Parc','QC'),('CA','MHS','150 Mile House','150 Mile House','BC'),('CA','MIB','Mission City','Mission City','BC'),('CA','MID','Midland','Midland','ON'),('CA','MIH','Michipicoten','Michipicoten','ON'),('CA','MIL','Milton','Milton','ON'),('CA','MIM','Miminegash','Miminegash','PE'),('CA','MIN','Minden','Minden','ON'),('CA','MIO','Milton','Milton','NS'),('CA','MIR','Miramichi','Miramichi','NB'),('CA','MIS','Mississauga','Mississauga','ON'),('CA','MKD','Markdale','Markdale','ON'),('CA','MKH','Markham','Markham','ON'),('CA','MLA','Mont-Laurier','Mont-Laurier','QC'),('CA','MLG','Millgrove','Millgrove','ON'),('CA','MLL','Manilla','Manilla','ON'),('CA','MLN','Milner Ridge','Milner Ridge','MB'),('CA','MMA','Marmora','Marmora','ON'),('CA','MNE','Matane','Matane','QC'),('CA','MNK','Monkland','Monkland','ON'),('CA','MNT','Moncton','Moncton','NB'),('CA','MNW','Magnetawan','Magnetawan','ON'),('CA','MOB','Morrisburg','Morrisburg','ON'),('CA','MOL','Mont-Louis','Mont-Louis','QC'),('CA','MON','Monkton','Monkton','ON'),('CA','MOO','Moose Factory','Moose Factory','ON'),('CA','MOP','Morell','Morell','PE'),('CA','MOR','Morden','Morden','MB'),('CA','MOS','Mount Stewart','Mount Stewart','PE'),('CA','MOU','Moosonee','Moosonee','ON'),('CA','MPE','Mount Pearl','Mount Pearl','NL'),('CA','MPS','Mount Pleasant','Mount Pleasant','ON'),('CA','MQE','Malpeque Bay','Malpeque Bay','PE'),('CA','MQT','Marquette','Marquette','MB'),('CA','MRB','Mirabel','Mirabel','QC'),('CA','MRF','Moorefield','Moorefield','ON'),('CA','MRI','Maple Ridge','Maple Ridge','BC'),('CA','MRL','Mont-Royal','Mont-Royal','QC'),('CA','MRN','Montreal-Nord','Montreal-Nord','QC'),('CA','MRO','Mont Rolland','Mont Rolland','QC'),('CA','MRS','Morris','Morris','MB'),('CA','MRT','St Martin','St Martin',''),('CA','MRV','Morinville','Morinville','AB'),('CA','MSA','Muskrat Dam','Muskrat Dam','ON'),('CA','MSC','Mascouche','Mascouche','QC'),('CA','MSG','Mont-Saint-Gregoire','Mont-Saint-Gregoire','QC'),('CA','MSH','Mont St Hilaire','Mont St Hilaire','QC'),('CA','MSS','Masset','Masset','BC'),('CA','MST','Mistassini','Mistassini','QC'),('CA','MSU','Manseau','Manseau','QC'),('CA','MSV','Minesville','Minesville','NS'),('CA','MTC','Metcalfe','Metcalfe','ON'),('CA','MTF','Mount Forest','Mount Forest','ON'),('CA','MTH','Mitchell','Mitchell','MB'),('CA','MTN','Marystown','Marystown','NL'),('CA','MTR','Montreal','Montreal','QC'),('CA','MUH','Murray Harbour','Murray Harbour','PE'),('CA','MUL','Mulgrave','Mulgrave','NS'),('CA','MUR','Murray River','Murray River','PE'),('CA','MVE','Murdochville','Murdochville','QC'),('CA','MVI','Millville','Millville','NS'),('CA','MVL','Marieville','Marieville','QC'),('CA','MWA','Madawaska','Madawaska','ON'),('CA','MYR','Myrtle','Myrtle','MB'),('CA','NAC','Nackawic','Nackawic','NB'),('CA','NAF','North Arm Fraser','North Arm Fraser','BC'),('CA','NAI','Nain','Nain','NL'),('CA','NAN','Nanticoke','Nanticoke','ON'),('CA','NAP','Napierville','Napierville','QC'),('CA','NBC','Notre-Dame-du-Bon-Conseil','Notre-Dame-du-Bon-Conseil','QC'),('CA','NBF','Nobleford','Nobleford','AB'),('CA','NBH','Newburgh','Newburgh','ON'),('CA','NBM','New Bothwell','New Bothwell','MB'),('CA','NCT','Newcastle','Newcastle','NB'),('CA','NDK','New Denmark','New Denmark','NB'),('CA','NDM','Mont-Carmel','Mont-Carmel','QC'),('CA','NDN','Napadogan','Napadogan','NB'),('CA','NEA','New Annan','New Annan','PE'),('CA','NEE','Neepawa','Neepawa','MB'),('CA','NEP','Neptune','Neptune','SK'),('CA','NGL','New Glasgow','New Glasgow','NS'),('CA','NGY','New Germany','New Germany','NS'),('CA','NHM','New Hamburg','New Hamburg','ON'),('CA','NHU','New Harbour','New Harbour','NL'),('CA','NIA','Niagara Falls','Niagara Falls','ON'),('CA','NIM','Nimpkish','Nimpkish','BC'),('CA','NIU','Nisku','Nisku','AB'),('CA','NLI','New Liskeard','New Liskeard','ON'),('CA','NLS','Nelson','Nelson','BC'),('CA','NLT','Nicolet','Nicolet','QC'),('CA','NMA','New Minas','New Minas','NS'),('CA','NMI','Nelson-Miramichi','Nelson-Miramichi','NB'),('CA','NMN','Normandin','Normandin','QC'),('CA','NMP','Nampa','Nampa','AB'),('CA','NNE','Nanoose Bay','Nanoose Bay','BC'),('CA','NNO','Nanaimo','Nanaimo','BC'),('CA','NOB','Nobleton','Nobleton','ON'),('CA','NOJ','Saint-Nicolas','Saint-Nicolas','QC'),('CA','NOL','Niagara-on-the-Lake','Niagara-on-the-Lake','ON'),('CA','NOR','North Bay','North Bay','ON'),('CA','NPA','Napanee','Napanee','ON'),('CA','NPH','Nephton','Nephton','ON'),('CA','NPL','Nimpo Lake','Nimpo Lake','BC'),('CA','NPN','Nepean','Nepean','ON'),('CA','NPU','Nepeau','Nepeau','ON'),('CA','NPW','Nipawin','Nipawin','SK'),('CA','NRC','New Richmond','New Richmond','QC'),('CA','NRN','Noranda','Noranda','QC'),('CA','NRU','North Rustico','North Rustico','PE'),('CA','NSC','St Charles','St Charles','ON'),('CA','NSK','Nisku/Edmonton','Nisku/Edmonton','AB'),('CA','NSY','North Sydney','North Sydney','NS'),('CA','NVA','Norval','Norval','ON'),('CA','NVK','Nanisivik','Nanisivik','NU'),('CA','NVL','Niverville','Niverville','MB'),('CA','NWA','New Waterford','New Waterford','NS'),('CA','NWC','Norwich (Ontario)','Norwich (Ontario)','ON'),('CA','NWE','New Westminster','New Westminster','BC'),('CA','NWM','Newmarket','Newmarket','ON'),('CA','NWP','Argentia','Argentia','NL'),('CA','NWT','Newcastle','Newcastle','ON'),('CA','NYK','North York','North York','ON'),('CA','OAJ','Oakville','Oakville','MB'),('CA','OAK','Oakville','Oakville','ON'),('CA','OCH','Locusthill','Locusthill','ON'),('CA','ODE','Odessa','Odessa','ON'),('CA','ODS','Olds','Olds','AB'),('CA','OFA','Ocean Falls','Ocean Falls','BC'),('CA','OFL','Okanagan Falls','Okanagan Falls','BC'),('CA','OLE','O\'Leary','O\'Leary','PE'),('CA','OLS','Orleans','Orleans','ON'),('CA','OOK','Outlook','Outlook','SK'),('CA','OPE','Port Hope','Port Hope','ON'),('CA','OPH','Ompah','Ompah','ON'),('CA','OPL','Old Perlican','Old Perlican','NL'),('CA','ORA','Orangeville','Orangeville','ON'),('CA','ORI','Orillia','Orillia','ON'),('CA','ORM','Ormstown','Ormstown','QC'),('CA','ORO','Oromocto','Oromocto','NB'),('CA','ORT','Northbrook','Northbrook','ON'),('CA','OSH','Oshawa','Oshawa','ON'),('CA','OTM','Outremont','Outremont','QC'),('CA','OTT','Ottawa','Ottawa','ON'),('CA','OVR','Oliver','Oliver','BC'),('CA','OWN','Brownsburg','Brownsburg','QC'),('CA','OWS','Owen Sound','Owen Sound','ON'),('CA','OXF','Oxford','Oxford','NS'),('CA','PAB','Port Alberni','Port Alberni','BC'),('CA','PAC','Port Alice','Port Alice','BC'),('CA','PAE','Parksville','Parksville','BC'),('CA','PAF','Port-Alfred','Port-Alfred','QC'),('CA','PAN','Perth-Andover','Perth-Andover','NB'),('CA','PAO','Paris','Paris','ON'),('CA','PAP','Port au Port','Port au Port','NL'),('CA','PAQ','Pointe-aux-Basques','Pointe-aux-Basques','QC'),('CA','PAR','Parrsboro','Parrsboro','NS'),('CA','PAS','Paspebiac','Paspebiac','QC'),('CA','PBG','St-Patrice-de-Beaurivage','St-Patrice-de-Beaurivage','QC'),('CA','PBH','Peterborough','Peterborough','ON'),('CA','PBI','Port Bickerton','Port Bickerton','NS'),('CA','PBQ','Channel-Port aux Basques','Channel-Port aux Basques','NL'),('CA','PCA','Port-Cartier','Port-Cartier','QC'),('CA','PCD','Petitcodiac','Petitcodiac','NB'),('CA','PCE','Princeville','Princeville','QC'),('CA','PCK','Pickering','Pickering','ON'),('CA','PCO','Port Colborne','Port Colborne','ON'),('CA','PCP','Porcupine','Porcupine','ON'),('CA','PCR','Port Credit','Port Credit','ON'),('CA','PCT','Princeton','Princeton','BC'),('CA','PCU','Pain Court','Pain Court','ON'),('CA','PDI','Pond Inlet','Pond Inlet','NU'),('CA','PDV','Port Dover','Port Dover','ON'),('CA','PED','Point Edward','Point Edward','NS'),('CA','PEH','Pender Harbour','Pender Harbour','BC'),('CA','PEL','Port Elgin','Port Elgin','NB'),('CA','PEM','Pembroke','Pembroke','ON'),('CA','PEN','Pennfield Ridge','Pennfield Ridge','NB'),('CA','PER','Perth','Perth','ON'),('CA','PET','Petrolia','Petrolia','ON'),('CA','PEW','Point Edward','Point Edward','ON'),('CA','PFT','Pointe-Fortune','Pointe-Fortune','QC'),('CA','PGA','Port George','Port George','NS'),('CA','PGR','Petit-de-Grat','Petit-de-Grat','NS'),('CA','PHA','Port Hastings','Port Hastings','NS'),('CA','PHL','Philipsburg','Philipsburg','QC'),('CA','PHM','Pohenegamook','Pohenegamook','QC'),('CA','PHW','Port Hawkesbury','Port Hawkesbury','NS'),('CA','PHY','Port Hardy','Port Hardy','BC'),('CA','PIC','Picton','Picton','ON'),('CA','PIE','Pierrefonds','Pierrefonds','QC'),('CA','PIF','Pine Falls','Pine Falls','MB'),('CA','PIM','Pitt Meadows','Pitt Meadows','BC'),('CA','PIN','Pintendre','Pintendre','QC'),('CA','PIR','Pine River','Pine River','MB'),('CA','PIW','Pikwitonei','Pikwitonei','MB'),('CA','PKA','Ponoka','Ponoka','AB'),('CA','PKH','Parkhill','Parkhill','ON'),('CA','PKL','Parkland','Parkland','AB'),('CA','PLA','Plattsville','Plattsville','ON'),('CA','PLC','Plum Coulee','Plum Coulee','MB'),('CA','PLE','Plessisville','Plessisville','QC'),('CA','PLN','Plantagenet','Plantagenet','ON'),('CA','PLP','Portage La Prairie','Portage La Prairie','MB'),('CA','PLR','Plaster Rock','Plaster Rock','NB'),('CA','PLV','Palgrave','Palgrave','ON'),('CA','PMA','Port McNeill','Port McNeill','BC'),('CA','PME','Port-Menier','Port-Menier','QC'),('CA','PML','Port Mellon','Port Mellon','BC'),('CA','PMN','Port Mouton','Port Mouton','NS'),('CA','PMO','Port Moody/Vancouver','Port Moody/Vancouver','BC'),('CA','PMW','Port Medway','Port Medway','NS'),('CA','PNB','Penobsquis','Penobsquis','NB'),('CA','PNE','Port Nelson','Port Nelson','MB'),('CA','PNH','Penhold','Penhold','AB'),('CA','PNN','Port Nelson','Port Nelson','NL'),('CA','PNT','Pangnirtung','Pangnirtung','NU'),('CA','POA','Port Arthur','Port Arthur','ON'),('CA','POH','Poplar Hill','Poplar Hill','ON'),('CA','POI','Pointe-Claire','Pointe-Claire','QC'),('CA','POP','Pointe-au-Pic','Pointe-au-Pic','QC'),('CA','POR','Portage','Portage','PE'),('CA','POW','Powell River','Powell River','BC'),('CA','PPC','Pointe au Pic','Pointe au Pic','QC'),('CA','PPL','Porcupine Plain','Porcupine Plain','SK'),('CA','PPO','Pipestone','Pipestone','MB'),('CA','PPR','Preeceville','Preeceville','SK'),('CA','PPT','Prospect','Prospect','NS'),('CA','PRA','Prince Albert','Prince Albert','SK'),('CA','PRB','Port Robinson','Port Robinson','ON'),('CA','PRE','Prescott','Prescott','ON'),('CA','PRG','Prince George','Prince George','BC'),('CA','PRI','Paradise','Paradise','NL'),('CA','PRO','Petit Rocher','Petit Rocher','NB'),('CA','PRP','Port Perry','Port Perry','ON'),('CA','PRR','Prince Rupert','Prince Rupert','BC'),('CA','PRS','Parry Sound','Parry Sound','ON'),('CA','PRT','Princeton','Princeton','ON'),('CA','PRW','Prince William','Prince William','NB'),('CA','PSA','Pointe-Sapin','Pointe-Sapin','NB'),('CA','PSD','Pasadena','Pasadena','NL'),('CA','PSI','Port Simpson','Port Simpson','BC'),('CA','PSO','Pierson','Pierson','MB'),('CA','PST','Port Stanley','Port Stanley','ON'),('CA','PSX','Port Saxon','Port Saxon','NS'),('CA','PTA','Tahsis','Tahsis','BC'),('CA','PTB','Patricia Bay','Patricia Bay','BC'),('CA','PTC','Port Coquitlam','Port Coquitlam','BC'),('CA','PTE','Port Edward','Port Edward','BC'),('CA','PTM','Port Maitland','Port Maitland','NS'),('CA','PTN','Portneuf','Portneuf','QC'),('CA','PTO','Pictou','Pictou','NS'),('CA','PTQ','Pont-Rouge','Pont-Rouge','QC'),('CA','PTU','Point Tupper','Point Tupper','NS'),('CA','PUB','Pubnico','Pubnico','NS'),('CA','PUG','Pugwash','Pugwash','NS'),('CA','PUT','Putnam','Putnam','ON'),('CA','PWE','Port Weller','Port Weller','ON'),('CA','PWI','Port Williams','Port Williams','NS'),('CA','PWS','Powassan','Powassan','ON'),('CA','PXN','Parson','Parson','BC'),('CA','PXT','Pointe-aux-Trembles','Pointe-aux-Trembles','QC'),('CA','QSN','Quesnel','Quesnel','BC'),('CA','QTS','Quatsino','Quatsino','BC'),('CA','QUA','Qu\'Appelle','Qu\'Appelle','SK'),('CA','QUB','Qualicum Beach','Qualicum Beach','BC'),('CA','QUE','Quebec','Quebec','QC'),('CA','RAE','Rae','Rae','NT'),('CA','RAJ','Ralston','Ralston','AB'),('CA','RAM','Ramea','Ramea','NL'),('CA','RBC','Richmond','Richmond','BC'),('CA','RBD','Riviere-Beaudette','Riviere-Beaudette','QC'),('CA','RBI','Roblin','Roblin','ON'),('CA','RBT','Richibucto','Richibucto','NB'),('CA','RCF','Redcliff','Redcliff','AB'),('CA','RCH','Richmond','Richmond','QC'),('CA','RDE','Red Deer','Red Deer','AB'),('CA','RDL','Riviere-du-Loup','Riviere-du-Loup','QC'),('CA','RDN','Rodney','Rodney','ON'),('CA','RDO','Radisson','Radisson','SK'),('CA','REB','Resolute Bay','Resolute Bay','NU'),('CA','REG','Regina','Regina','SK'),('CA','REP','Repentigny','Repentigny','QC'),('CA','REX','Rexdale/Toronto','Rexdale/Toronto','ON'),('CA','RGD','Rigaud','Rigaud','QC'),('CA','RHI','Richmond Hill','Richmond Hill','ON'),('CA','RIC','Richelieu','Richelieu','QC'),('CA','RIE','La Presentation','La Presentation','QC'),('CA','RIM','Rimouski','Rimouski','QC'),('CA','RIV','Riverport','Riverport','NS'),('CA','RIY','Rimbey','Rimbey','AB'),('CA','RLA','Red Lake','Red Lake','ON'),('CA','RLL','Russell','Russell','MB'),('CA','RMD','Richmond','Richmond','ON'),('CA','RMI','Saint-Remi','Saint-Remi','QC'),('CA','RNF','Renfrew','Renfrew','ON'),('CA','RNO','Rosenort','Rosenort','MB'),('CA','ROB','Roblin','Roblin','MB'),('CA','ROD','Roddickton','Roddickton','NL'),('CA','ROF','Rock Forest','Rock Forest','QC'),('CA','ROK','Rockland','Rockland','ON'),('CA','ROS','Rosemere','Rosemere','QC'),('CA','ROU','Rougemont','Rougemont','QC'),('CA','ROX','Roxboro','Roxboro','QC'),('CA','RPC','Rapid City','Rapid City','MB'),('CA','RPO','Rossport','Rossport','ON'),('CA','RQQ','Rockton','Rockton','ON'),('CA','RRM','Riviere-Matawin','Riviere-Matawin','QC'),('CA','RRO','Richardson','Richardson','SK'),('CA','RRQ','Sainte-Rose','Sainte-Rose','QC'),('CA','RSN','Robertson','Robertson','PE'),('CA','RSO','Rosedale','Rosedale','BC'),('CA','RST','Restoule','Restoule','ON'),('CA','RSV','Robertsonville','Robertsonville','QC'),('CA','RSZ','Rothesay','Rothesay','NB'),('CA','RTO','Sarto','Sarto','MB'),('CA','RTW','Ridgetown','Ridgetown','ON'),('CA','RUI','Rupert Inlet','Rupert Inlet','BC'),('CA','RUS','Ruskin','Ruskin','BC'),('CA','RUV','Ruthven','Ruthven','ON'),('CA','RVI','Rocanville','Rocanville','SK'),('CA','RWM','Redwood Meadow','Redwood Meadow','AB'),('CA','RWN','Rawdon','Rawdon','QC'),('CA','RXN','Rexton','Rexton','NB'),('CA','SAB','Ste Anne-de-Bellevue','Ste Anne-de-Bellevue','QC'),('CA','SAC','Sackville','Sackville','NB'),('CA','SAD','St Andrews','St Andrews','NB'),('CA','SAE','St Andre-Est','St Andre-Est','QC'),('CA','SAH','Ste Agathe','Ste Agathe','MB'),('CA','SAI','St Aime','St Aime','QC'),('CA','SAJ','St Jean-Baptiste','St Jean-Baptiste','MB'),('CA','SAK','Saskatoon','Saskatoon','SK'),('CA','SAL','Salford','Salford','ON'),('CA','SAM','Ste Agathe-des-Monts','Ste Agathe-des-Monts','QC'),('CA','SAN','St Augustin-de-Desmaures','St Augustin-de-Desmaures','QC'),('CA','SAO','St Antoine','St Antoine','QC'),('CA','SAP','St Apollinaire','St Apollinaire','QC'),('CA','SAR','Sardis','Sardis','BC'),('CA','SAS','Ste Anne des Chenes','Ste Anne des Chenes','MB'),('CA','SAT','St Anthony','St Anthony','NL'),('CA','SAU','St Augustin','St Augustin','QC'),('CA','SAV','Savona','Savona','BC'),('CA','SAY','Sayabec','Sayabec','QC'),('CA','SBA','St Basile','St Basile','QC'),('CA','SBB','Seba Beach','Seba Beach','AB'),('CA','SBE','Sherbrooke','Sherbrooke','NS'),('CA','SBF','South Brookfield','South Brookfield','NS'),('CA','SBI','St Sebastien','St Sebastien','QC'),('CA','SBO','St Bruno de Montarville','St Bruno de Montarville','QC'),('CA','SBR','Sherbrooke','Sherbrooke','QC'),('CA','SBS','Sainte-Brigitte-des-Saults','Sainte-Brigitte-des-Saults','QC'),('CA','SBT','St Albert','St Albert','AB'),('CA','SBU','Shelburne','Shelburne','NS'),('CA','SCA','St Catharines','St Catharines','ON'),('CA','SCB','Scarborough','Scarborough','ON'),('CA','SCC','Scoudouc','Scoudouc','NB'),('CA','SCE','Shubenacadie','Shubenacadie','NS'),('CA','SCH','St Chrysostome','St Chrysostome','QC'),('CA','SCI','St-Come-Liniere','St-Come-Liniere','QC'),('CA','SCL','Ste Claire','Ste Claire','QC'),('CA','SCM','St Come','St Come','QC'),('CA','SCO','Ste Clothilde','Ste Clothilde','QC'),('CA','SCR','Strathclair','Strathclair','MB'),('CA','SCS','St Cesaire','St Cesaire','QC'),('CA','SCT','Ste-Catherine','Ste-Catherine','QC'),('CA','SCU','St Claude','St Claude','MB'),('CA','SCX','Ste Croix','Ste Croix','QC'),('CA','SDA','St Damase','St Damase','QC'),('CA','SDB','St Damien-de-Buckland','St Damien-de-Buckland','QC'),('CA','SDE','Ste-Adele','Ste-Adele','QC'),('CA','SDM','Ste Anne-des-Monts','Ste Anne-des-Monts','QC'),('CA','SDR','Sundre','Sundre','AB'),('CA','SDY','Sidney','Sidney','BC'),('CA','SEB','Seven Islands Bay','Seven Islands Bay','NL'),('CA','SED','Sedgewick','Sedgewick','AB'),('CA','SEH','Sexsmith','Sexsmith','AB'),('CA','SEI','Sept-Iles','Sept-Iles','QC'),('CA','SEL','Selkirk','Selkirk','MB'),('CA','SEM','Seldom','Seldom','NL'),('CA','SEP','St Ephrem-de-Beauce','St Ephrem-de-Beauce','QC'),('CA','SER','Stettler','Stettler','AB'),('CA','SEU','St Eustache','St Eustache','QC'),('CA','SEZ','St Elzear/La Nouvelle-Beau','St Elzear/La Nouvelle-Beau','QC'),('CA','SFC','St-Sebastien','St-Sebastien','QC'),('CA','SFE','St Felicien','St Felicien','QC'),('CA','SFH','Seaforth','Seaforth',''),('CA','SFM','Sheffield Mills','Sheffield Mills','NS'),('CA','SFO','Ste Foy','Ste Foy','QC'),('CA','SFR','St-Francois-du-Lac','St-Francois-du-Lac','QC'),('CA','SFV','Stouffville','Stouffville','ON'),('CA','SFX','St-Felix-de-Valois','St-Felix-de-Valois','QC'),('CA','SGA','St Gabriel','St Gabriel','QC'),('CA','SGB','St Georges/Beauce-Sartigan','St Georges/Beauce-Sartigan','QC'),('CA','SGD','St-Germain-de-Grantham','St-Germain-de-Grantham','QC'),('CA','SGE','St George','St George','NB'),('CA','SGG','St Georges','St Georges','QC'),('CA','SGH','Shag Harbour','Shag Harbour','NS'),('CA','SGN','Saint-Germain-de-Grantham','Saint-Germain-de-Grantham','QC'),('CA','SHA','Shawinigan','Shawinigan','QC'),('CA','SHB','Schreiber','Schreiber','ON'),('CA','SHE','Shediac','Shediac','NB'),('CA','SHH','Sheet Harbour','Sheet Harbour','NS'),('CA','SHI','St Hilaire','St Hilaire','QC'),('CA','SHK','Sherkston','Sherkston','ON'),('CA','SHL','Shallows Lake','Shallows Lake','ON'),('CA','SHM','Schumacher','Schumacher','ON'),('CA','SHN','St Henri','St Henri','QC'),('CA','SHO','Saint-Hippolyte','Saint-Hippolyte','QC'),('CA','SHP','Shippegan','Shippegan','NB'),('CA','SHR','Sherrington','Sherrington','QC'),('CA','SHS','St Honore-de-Shenley','St Honore-de-Shenley','QC'),('CA','SHU','Saint-Hubert','Saint-Hubert','QC'),('CA','SHY','St Hyacinthe','St Hyacinthe','QC'),('CA','SIC','Simcoe','Simcoe','ON'),('CA','SIM','Imperial','Imperial','SK'),('CA','SJA','Fort St James','Fort St James','BC'),('CA','SJB','St John','St John','NB'),('CA','SJC','Saint-Jean-Chrysostome','Saint-Jean-Chrysostome','QC'),('CA','SJD','St Jeanile-d\'Orleans','St Jeanile-d\'Orleans','QC'),('CA','SJE','St Jerome','St Jerome','QC'),('CA','SJF','St John\'s','St John\'s','NL'),('CA','SJH','St Joseph\'s','St Joseph\'s','NL'),('CA','SJJ','Saint Jacques','Saint Jacques','NB'),('CA','SJL','St Joseph-du-Lac','St Joseph-du-Lac','QC'),('CA','SJN','Ste Justine-de-Newton','Ste Justine-de-Newton','QC'),('CA','SJQ','St Jacques le Mineur','St Jacques le Mineur','QC'),('CA','SJR','St Jean-sur-Richelieu','St Jean-sur-Richelieu','QC'),('CA','SJS','Saint Jacobs','Saint Jacobs','ON'),('CA','SJU','Ste Julienne','Ste Julienne','QC'),('CA','SJV','Saint-Janvier','Saint-Janvier','QC'),('CA','SKI','Charlotte (Skidegate)','Charlotte (Skidegate)','BC'),('CA','SKP','Shakespeare Island','Shakespeare Island','ON'),('CA','SLA','Saint-Laurent','Saint-Laurent','QC'),('CA','SLB','Shelburne','Shelburne','ON'),('CA','SLE','St Leonard','St Leonard','QC'),('CA','SLG','Stirling','Stirling','ON'),('CA','SLK','Split Lake','Split Lake','MB'),('CA','SLL','Stittsville','Stittsville','ON'),('CA','SLN','St Clements','St Clements','ON'),('CA','SLT','St Lambert','St Lambert','QC'),('CA','SLU','St Luc','St Luc','QC'),('CA','SLV','Saulnierville','Saulnierville','NS'),('CA','SLW','St Lawrence','St Lawrence','NL'),('CA','SLY','Sedley','Sedley','SK'),('CA','SLZ','St Lazare-de-Vaudreuil','St Lazare-de-Vaudreuil','QC'),('CA','SMA','Ste Madeleine','Ste Madeleine','QC'),('CA','SMB','Ste Marie','Ste Marie','QC'),('CA','SMC','St Marc-des-Carrieres','St Marc-des-Carrieres','QC'),('CA','SMF','Smiths Falls','Smiths Falls','ON'),('CA','SMH','St Mathieu-d\'Harricana','St Mathieu-d\'Harricana','QC'),('CA','SMI','Sydney Mines','Sydney Mines','NS'),('CA','SML','Ste Marthe-sur-le-Lac','Ste Marthe-sur-le-Lac','QC'),('CA','SMQ','St Michel-des-Saints','St Michel-des-Saints','QC'),('CA','SMS','St Marys','St Marys','NL'),('CA','SMV','Smithville','Smithville','ON'),('CA','SMY','St Marys','St Marys','ON'),('CA','SNI','Sarnia','Sarnia','ON'),('CA','SNP','Stanstead Plain','Stanstead Plain','QC'),('CA','SNT','Saint-Charles-Borromee','Saint-Charles-Borromee','QC'),('CA','SOE','Strathmore','Strathmore','AB'),('CA','SOH','Southport','Southport','MB'),('CA','SOM','Sombra','Sombra','ON'),('CA','SOO','Sooke','Sooke','BC'),('CA','SOR','Sorel','Sorel','QC'),('CA','SOU','Souris','Souris','PE'),('CA','SOY','Southey','Southey','SK'),('CA','SPA','Saint-Pascal','Saint-Pascal','QC'),('CA','SPB','Saint-Paul-d\'Abbotsford','Saint-Paul-d\'Abbotsford','QC'),('CA','SPD','Springdale','Springdale','NL'),('CA','SPE','Sprague','Sprague','MB'),('CA','SPG','Spruce Grove','Spruce Grove','AB'),('CA','SPI','Saint-Pierre','Saint-Pierre','QC'),('CA','SPK','Sun Peaks','Sun Peaks','BC'),('CA','SPL','St Paul','St Paul','AB'),('CA','SPN','Spaniards Bay','Spaniards Bay','NL'),('CA','SPO','Springhill','Springhill','NS'),('CA','SPP','St Perpetue','St Perpetue','QC'),('CA','SPR','Spragge','Spragge','ON'),('CA','SPT','Saint-Esprit','Saint-Esprit','QC'),('CA','SPV','Spencerville','Spencerville','ON'),('CA','SPW','Sparwood','Sparwood','BC'),('CA','SQA','Squamish','Squamish','BC'),('CA','SQE','Saint Quentin','Saint Quentin','NB'),('CA','SRC','Star City','Star City','SK'),('CA','SRD','St-Raymond','St-Raymond','QC'),('CA','SRE','Ste Rosalie','Ste Rosalie','QC'),('CA','SRH','St-Roch','St-Roch','QC'),('CA','SRI','Sable River','Sable River','NS'),('CA','SRL','Sainte-Rosalie','Sainte-Rosalie','QC'),('CA','SRM','St Remi','St Remi','QC'),('CA','SRO','St Romuald-d\'Etchemin','St Romuald-d\'Etchemin','QC'),('CA','SRR','Sorrento','Sorrento','BC'),('CA','SRT','South River','South River','ON'),('CA','SRV','Sydney River','Sydney River','NS'),('CA','SSA','St Sauveur-des-Monts','St Sauveur-des-Monts','QC'),('CA','SSB','Saint Simon-de-Bagot','Saint Simon-de-Bagot','QC'),('CA','SSE','St Simeon','St Simeon','QC'),('CA','SSF','Sarsfield','Sarsfield','ON'),('CA','SSL','St Sebastien/Le Haut-Richelieu','St Sebastien/Le Haut-Richelieu','QC'),('CA','SSM','Sault Ste Marie','Sault Ste Marie','ON'),('CA','SSN','Stanbridge Station','Stanbridge Station','QC'),('CA','SSP','Sandspit','Sandspit','BC'),('CA','SSQ','La Sarre','La Sarre','QC'),('CA','SSV','Saint Sylvere','Saint Sylvere','QC'),('CA','STA','Ste-Anne','Ste-Anne','NB'),('CA','STB','Steinbach','Steinbach','MB'),('CA','STC','Stoney Creek','Stoney Creek','ON'),('CA','STE','Sainte-Therese','Sainte-Therese','QC'),('CA','STG','St George','St George','ON'),('CA','STH','St Thomas','St Thomas','ON'),('CA','STI','St-Pie','St-Pie','QC'),('CA','STJ','St Julie','St Julie','QC'),('CA','STL','St Antoine-des-Laurentides','St Antoine-des-Laurentides','QC'),('CA','STM','Ste Martine','Ste Martine','QC'),('CA','STN','Stellarton','Stellarton','NS'),('CA','STO','Saint-Timothee','Saint-Timothee','QC'),('CA','STP','St Prime','St Prime','QC'),('CA','STQ','Ste Therese','Ste Therese','QC'),('CA','STR','Stratford','Stratford','ON'),('CA','STS','St Stephen','St Stephen','NB'),('CA','STT','Strathroy','Strathroy','ON'),('CA','STV','Stephenville','Stephenville','NL'),('CA','STW','Stewart','Stewart','BC'),('CA','STX','St Constant','St Constant','QC'),('CA','STY','Stayner','Stayner','ON'),('CA','SUB','St Ubald','St Ubald','QC'),('CA','SUC','Success','Success','SK'),('CA','SUD','Sudbury','Sudbury','ON'),('CA','SUM','Summerside','Summerside','PE'),('CA','SUR','Summer Beaver','Summer Beaver','ON'),('CA','SUS','Sussex','Sussex','NB'),('CA','SUY','Surrey','Surrey','BC'),('CA','SUZ','Summerland','Summerland','BC'),('CA','SVA','Saint-Vallier','Saint-Vallier','QC'),('CA','SVE','Ste Veronique','Ste Veronique','QC'),('CA','SVI','Streetsville','Streetsville','ON'),('CA','SVL','St Vallier','St Vallier','ON'),('CA','SVQ','Saint-Valerien','Saint-Valerien','QC'),('CA','SVS','Stevensville','Stevensville','ON'),('CA','SWD','Sherwood','Sherwood','PE'),('CA','SWE','Stewiacke','Stewiacke','NS'),('CA','SWL','Snow Lake','Snow Lake','MB'),('CA','SWP','Sherwood Park','Sherwood Park','AB'),('CA','SWT','Silver Water','Silver Water','ON'),('CA','SXC','St Clet','St Clet','QC'),('CA','SXO','Saanichton Bay','Saanichton Bay','BC'),('CA','SYD','Sydney','Sydney','NS'),('CA','SYF','Silva Bay','Silva Bay','BC'),('CA','SYL','Sylvan Lake','Sylvan Lake','AB'),('CA','SYM','Stony Mountain','Stony Mountain','MB'),('CA','SYP','Stony Plain','Stony Plain','AB'),('CA','SYQ','Sillery','Sillery','QC'),('CA','SYT','Stoney Point, Essex','Stoney Point, Essex','ON'),('CA','SYW','Sayward','Sayward','BC'),('CA','SZF','Schanzenfeld','Schanzenfeld','MB'),('CA','TAB','Tabusintac','Tabusintac','NB'),('CA','TAD','Tadoussac','Tadoussac','QC'),('CA','TAH','Tagish','Tagish','YT'),('CA','TAL','Talbotville','Talbotville','ON'),('CA','TAR','Tara','Tara','ON'),('CA','TAS','Tasu','Tasu','BC'),('CA','TAV','Tavistock','Tavistock','ON'),('CA','TBA','Talbotville Royal','Talbotville Royal','ON'),('CA','TBG','Tillsonburg','Tillsonburg','ON'),('CA','TBN','Terrebonne','Terrebonne','QC'),('CA','TBR','Taber','Taber','AB'),('CA','TCG','Temiscaming','Temiscaming','QC'),('CA','TCH','Taschereau','Taschereau','QC'),('CA','TDS','Tracadie-Sheila','Tracadie-Sheila','NS'),('CA','TEC','Tecumseh','Tecumseh','ON'),('CA','TEU','Teulon','Teulon','MB'),('CA','TEX','Texada Island','Texada Island','BC'),('CA','TFI','Tofield','Tofield','AB'),('CA','TGU','Tatamagouche','Tatamagouche','NS'),('CA','TGY','Tigerlily','Tigerlily','AB'),('CA','THA','Thamesford','Thamesford','ON'),('CA','THD','Thorold','Thorold','ON'),('CA','THE','Thetford Mines','Thetford Mines','QC'),('CA','THF','Thedford','Thedford','ON'),('CA','THH','Three Hills','Three Hills','AB'),('CA','THI','Two Hills','Two Hills','AB'),('CA','THL','Thornhill','Thornhill','ON'),('CA','THU','Thunder Bay','Thunder Bay','ON'),('CA','THY','Thorsby','Thorsby','AB'),('CA','TIG','Tignish','Tignish','PE'),('CA','TIL','Inverlake','Inverlake','AB'),('CA','TIN','Hastings','Hastings','ON'),('CA','TIV','Tiverton','Tiverton','NS'),('CA','TIY','Tilbury','Tilbury','ON'),('CA','TLB','Tilbury Is','Tilbury Is','BC'),('CA','TMR','Town Mount Royal','Town Mount Royal','QC'),('CA','TND','Thorndale','Thorndale','ON'),('CA','TNS','Tungsten','Tungsten','NT'),('CA','TOQ','Toquart Bay','Toquart Bay','BC'),('CA','TOR','Toronto','Toronto','ON'),('CA','TOT','Tottenham','Tottenham','ON'),('CA','TPS','Trepassey','Trepassey','NL'),('CA','TRA','Tracadie','Tracadie','NB'),('CA','TRB','Trinity Bay','Trinity Bay','NL'),('CA','TRC','Tracy','Tracy','QC'),('CA','TRE','Crabtree','Crabtree','QC'),('CA','TRI','Triton','Triton',''),('CA','TRL','Trail','Trail','BC'),('CA','TRN','Trenton','Trenton','NS'),('CA','TRO','Trochu','Trochu','AB'),('CA','TRP','Trois-Pistoles','Trois-Pistoles','QC'),('CA','TRR','Trois-Rivieres (Three Rivers)','Trois-Rivieres (Three Rivers)','QC'),('CA','TRU','Truro','Truro','NS'),('CA','TRY','Troy','Troy','ON'),('CA','TSQ','Matsqui','Matsqui','BC'),('CA','TTC','Trenton','Trenton','ON'),('CA','TTI','Tolstoi','Tolstoi','MB'),('CA','TTR','Trout River','Trout River','NL'),('CA','TUC','Tucks','Tucks','BC'),('CA','TUK','Tuktoyaktuk','Tuktoyaktuk','NT'),('CA','TUS','Tusket','Tusket','NS'),('CA','TUX','Tumbler Ridge','Tumbler Ridge','BC'),('CA','TVT','Tiverton','Tiverton','ON'),('CA','TWE','Tweed','Tweed','ON'),('CA','TWI','Twillingate','Twillingate','NL'),('CA','TYR','Harty','Harty','ON'),('CA','UNV','Unionville','Unionville','ON'),('CA','UPO','Upper Musquodoboit','Upper Musquodoboit','NS'),('CA','UPT','Upton','Upton','QC'),('CA','UTP','Utopia','Utopia','ON'),('CA','UTT','Sutton','Sutton','ON'),('CA','UXB','Uxbridge','Uxbridge','ON'),('CA','VAC','North Vancouver','North Vancouver','BC'),('CA','VAE','Vanier','Vanier','QC'),('CA','VAL','Vallee-Jonction','Vallee-Jonction','QC'),('CA','VAN','Vancouver','Vancouver','BC'),('CA','VAR','Varennes','Varennes','QC'),('CA','VAU','Vaudreuil','Vaudreuil','QC'),('CA','VBA','Vibank','Vibank','SK'),('CA','VCA','Vulcan','Vulcan','AB'),('CA','VCH','Vercheres','Vercheres','QC'),('CA','VCT','Valcourt','Valcourt','QC'),('CA','VEB','Vernon Bridge','Vernon Bridge','PE'),('CA','VEG','Vegreville','Vegreville','AB'),('CA','VER','Vernon','Vernon','BC'),('CA','VGN','Vaughan','Vaughan','ON'),('CA','VIC','Victoria','Victoria','BC'),('CA','VIJ','Ville-Marie','Ville-Marie','QC'),('CA','VIN','Vineland Station','Vineland Station','ON'),('CA','VKH','Vankleek Hill','Vankleek Hill','ON'),('CA','VLF','Valleyfield','Valleyfield','QC'),('CA','VMT','Vimont','Vimont','QC'),('CA','VND','Vananda','Vananda','BC'),('CA','VNR','Vanier','Vanier','ON'),('CA','VON','Vonda','Vonda','SK'),('CA','VRA','Veteran','Veteran','AB'),('CA','VRD','Virden','Virden','MB'),('CA','VRG','Virgil','Virgil','ON'),('CA','VSC','Vanscoy','Vanscoy','SK'),('CA','VST','Ville Saint Laurent','Ville Saint Laurent','QC'),('CA','VVL','Victoriaville','Victoriaville','QC'),('CA','VXL','Vauxhall','Vauxhall','AB'),('CA','VYD','Valleyfield','Valleyfield','NL'),('CA','VYV','Valleyview','Valleyview','AB'),('CA','WAI','Watson Is','Watson Is','BC'),('CA','WAK','Wakefield','Wakefield','QC'),('CA','WAL','Wallaceburg','Wallaceburg','ON'),('CA','WAO','Waterloo','Waterloo','QC'),('CA','WAR','Fort Ware','Fort Ware','BC'),('CA','WAS','Waskatenau','Waskatenau','AB'),('CA','WAT','Watson Lake','Watson Lake','YT'),('CA','WAW','Wawanesa','Wawanesa','MB'),('CA','WBG','Warburg ','Warburg ','AB'),('CA','WBK','Westbank','Westbank','BC'),('CA','WBN','Winterburn','Winterburn','AB'),('CA','WBO','Wimborne','Wimborne','AB'),('CA','WDB','Woodbridge','Woodbridge','ON'),('CA','WDI','Wardsville','Wardsville','ON'),('CA','WDR','Windsor','Windsor','NS'),('CA','WDS','Woodstock','Woodstock','NB'),('CA','WED','Wedgeport','Wedgeport','NS'),('CA','WEK','Westlock','Westlock','AB'),('CA','WEL','Welland','Welland','ON'),('CA','WEN','Wellington','Wellington','ON'),('CA','WEP','Welshpool','Welshpool','NB'),('CA','WES','Weston','Weston','ON'),('CA','WET','Wetaskiwin','Wetaskiwin','AB'),('CA','WEV','Westville','Westville','NS'),('CA','WEY','Weymouth','Weymouth','NS'),('CA','WFD','Winfield','Winfield','BC'),('CA','WFF','Waterford','Waterford','ON'),('CA','WHC','Windham Centre','Windham Centre','ON'),('CA','WHE','Wheatley','Wheatley','ON'),('CA','WHF','Whitefish','Whitefish','ON'),('CA','WHH','Whiffen Head','Whiffen Head',''),('CA','WHI','Whitby','Whitby','ON'),('CA','WHL','West Hill','West Hill','ON'),('CA','WHR','White Rock','White Rock','BC'),('CA','WIC','Wickham West','Wickham West','QC'),('CA','WIH','Winchester','Winchester','ON'),('CA','WIL','Willowdale','Willowdale','ON'),('CA','WIN','Winona','Winona','ON'),('CA','WLO','West Lorne','West Lorne','ON'),('CA','WLS','Wallenstein','Wallenstein','ON'),('CA','WLY','Wellesley','Wellesley','ON'),('CA','WND','Windsor','Windsor','ON'),('CA','WNH','Wanham','Wanham','AB'),('CA','WNK','Winkler','Winkler','MB'),('CA','WNN','Wunnummin Lake','Wunnummin Lake','ON'),('CA','WNP','Winnipeg','Winnipeg','MB'),('CA','WNR','Warner','Warner','AB'),('CA','WOI','Wood Island','Wood Island','PE'),('CA','WOO','Woodfibre','Woodfibre','BC'),('CA','WOV','Wolfville','Wolfville','NS'),('CA','WPC','Pincher Creek','Pincher Creek','AB'),('CA','WPL','Powell Lake','Powell Lake','BC'),('CA','WPU','West Pubnico','West Pubnico','NS'),('CA','WSK','Woodstock','Woodstock','ON'),('CA','WSO','Westerose','Westerose','AB'),('CA','WSR','Windsor','Windsor','QC'),('CA','WTC','Whitecourt','Whitecourt','AB'),('CA','WTF','Watford','Watford','ON'),('CA','WTL','Waterloo','Waterloo','ON'),('CA','WTM','Wrentham','Wrentham','AB'),('CA','WTN','Walton','Walton','NS'),('CA','WTR','Waterdown','Waterdown','ON'),('CA','WTW','Whitewood','Whitewood','SK'),('CA','WVE','Waterville','Waterville','NS'),('CA','WVL','Waterville','Waterville','QC'),('CA','WVR','West Vancouver','West Vancouver','BC'),('CA','WVY','Waverley','Waverley','NS'),('CA','WWB','Weyburn','Weyburn','SK'),('CA','WWI','Wainwright','Wainwright','AB'),('CA','WWK','Warwick','Warwick','QC'),('CA','WWO','Wildwood','Wildwood','AB'),('CA','WYN','Wynyard','Wynyard','SK'),('CA','WYO','Wyoming','Wyoming','ON'),('CA','WYV','Wesleyville','Wesleyville','NL'),('CA','XBW','Killineq','Killineq','QC'),('CA','XFL','Florence','Florence','ON'),('CA','XFS','Alexandria','Alexandria','ON'),('CA','XGR','Kangiqsualujjuaq','Kangiqsualujjuaq','QC'),('CA','XGY','Grimsby','Grimsby','ON'),('CA','XIO','St Mary\'s','St Mary\'s','ON'),('CA','XJH','Saint-Joseph-de-Beauce','Saint-Joseph-de-Beauce','QC'),('CA','XKS','Kasabonika','Kasabonika','ON'),('CA','XKV','Sackville','Sackville','NS'),('CA','XLF','Leaf Bay','Leaf Bay','QC'),('CA','XSI','South Indian Lake','South Indian Lake','MB'),('CA','XSY','Mossley','Mossley','ON'),('CA','XTL','Tadoule Lake','Tadoule Lake','MB'),('CA','YAC','Cat Lake','Cat Lake','ON'),('CA','YAD','Moose Lake','Moose Lake','MB'),('CA','YAE','Alta Lake','Alta Lake','BC'),('CA','YAF','Asbestos Hill','Asbestos Hill','QC'),('CA','YAH','Lagrande 4','Lagrande 4','QC'),('CA','YAJ','Lyall Harbour','Lyall Harbour','BC'),('CA','YAQ','Maple Bay','Maple Bay','BC'),('CA','YAR','Lagrande 3','Lagrande 3','QC'),('CA','YAT','Attawapiskat','Attawapiskat','ON'),('CA','YAU','Kattiniq/Donaldson Lake','Kattiniq/Donaldson Lake','QC'),('CA','YAV','Miners Bay','Miners Bay','BC'),('CA','YAW','Shearwater','Shearwater','NS'),('CA','YAX','Angling Lake','Angling Lake','ON'),('CA','YAZ','Tofino','Tofino','BC'),('CA','YBE','Uranium City','Uranium City','SK'),('CA','YBG','Bagotville Apt','Bagotville Apt','QC'),('CA','YBH','Bull Harbour','Bull Harbour','BC'),('CA','YBI','Black Tickle','Black Tickle','NL'),('CA','YBM','Bronson Creek','Bronson Creek','BC'),('CA','YBN','Borden','Borden','ON'),('CA','YBO','Bobquinn Lake','Bobquinn Lake','BC'),('CA','YBQ','Telegraph Harbour','Telegraph Harbour','BC'),('CA','YBR','Brandon','Brandon','MB'),('CA','YBT','Brochet','Brochet','MB'),('CA','YBX','Blanc-Sablon','Blanc-Sablon','QC'),('CA','YCB','Cambridge Bay','Cambridge Bay','NU'),('CA','YCE','Centralia','Centralia','ON'),('CA','YCF','Cortes Bay','Cortes Bay','BC'),('CA','YCG','Castlegar','Castlegar','BC'),('CA','YCI','Caribou Island','Caribou Island','ON'),('CA','YCJ','Cape St James','Cape St James','BC'),('CA','YCK','Colville Lake','Colville Lake','NT'),('CA','YCL','Charlo','Charlo','NB'),('CA','YCN','Cochrane','Cochrane','ON'),('CA','YCP','Co-Op Point','Co-Op Point','MB'),('CA','YCQ','Chetwynd','Chetwynd','BC'),('CA','YCR','Cross Lake','Cross Lake','MB'),('CA','YCS','Chesterfield Inlet','Chesterfield Inlet','NU'),('CA','YCT','Coronation','Coronation','AB'),('CA','YCV','Cartierville','Cartierville','QC'),('CA','YCX','Gagetown','Gagetown','NB'),('CA','YCZ','Fairmount Springs','Fairmount Springs','BC'),('CA','YDA','Dawson City','Dawson City','YT'),('CA','YDB','Burwash Landings','Burwash Landings','YT'),('CA','YDC','Drayton Valley','Drayton Valley','AB'),('CA','YDE','Paradise River','Paradise River','NL'),('CA','YDF','Deer Lake','Deer Lake','NL'),('CA','YDH','Daniels Harbour','Daniels Harbour','NL'),('CA','YDI','Davis Inlet','Davis Inlet','NL'),('CA','YDJ','Hatchet Lake','Hatchet Lake','SK'),('CA','YDK','Main Duck Island','Main Duck Island','ON'),('CA','YDL','Dease Lake','Dease Lake','BC'),('CA','YDN','Dauphin','Dauphin','MB'),('CA','YDO','Dolbeau','Dolbeau','QC'),('CA','YDQ','Dawson Creek','Dawson Creek','BC'),('CA','YDR','Broadview','Broadview','SK'),('CA','YDS','Desolation Sound','Desolation Sound','BC'),('CA','YDU','Kasba Lake','Kasba Lake','NT'),('CA','YDV','Bloodvein','Bloodvein','MB'),('CA','YDW','Obre Lake','Obre Lake','NT'),('CA','YDX','Doc Creek','Doc Creek','BC'),('CA','YEG','Edmonton Int Apt','Edmonton Int Apt','AB'),('CA','YEK','Arviat','Arviat','NU'),('CA','YEL','Elliot Lake','Elliot Lake','ON'),('CA','YEM','Manitowaning','Manitowaning','ON'),('CA','YEP','Estevan Point','Estevan Point','BC'),('CA','YER','Fort Severn','Fort Severn','ON'),('CA','YEV','Inuvik','Inuvik','NT'),('CA','YEY','Amos','Amos','QC'),('CA','YFB','Frobisher Bay Apt','Frobisher Bay Apt','NT'),('CA','YFG','Fontanges','Fontanges','QC'),('CA','YFH','Fort Hope','Fort Hope','ON'),('CA','YFJ','Snare Lake','Snare Lake','NT'),('CA','YFL','Fort Reliance','Fort Reliance','NT'),('CA','YFO','Flin Flon','Flin Flon','MB'),('CA','YFR','Fort Resolution','Fort Resolution','NT'),('CA','YFX','Fox Harbour (St Lewis)','Fox Harbour (St Lewis)','NL'),('CA','YGA','Gagnon','Gagnon','QC'),('CA','YGB','Gillies Bay','Gillies Bay','BC'),('CA','YGC','Grande Cache','Grande Cache','AB'),('CA','YGE','Gorge Harbor','Gorge Harbor','BC'),('CA','YGH','Fort Good Hope','Fort Good Hope','NT'),('CA','YGL','La Grande','La Grande','QC'),('CA','YGM','Gimli','Gimli','MB'),('CA','YGN','Greenway Sound','Greenway Sound','BC'),('CA','YGO','Gods Narrows','Gods Narrows','MB'),('CA','YGQ','Geraldton','Geraldton','ON'),('CA','YGR','Iles de la Madeleine','Iles de la Madeleine','QC'),('CA','YGS','Germansen','Germansen','BC'),('CA','YGX','Gillam','Gillam','MB'),('CA','YGZ','Grise Fiord','Grise Fiord','NU'),('CA','YHB','Hudson Bay','Hudson Bay','SK'),('CA','YHC','Hakai Pass','Hakai Pass','BC'),('CA','YHE','Hope','Hope','BC'),('CA','YHF','Hearst','Hearst','ON'),('CA','YHI','Holman','Holman','NT'),('CA','YHK','Gjoa Haven','Gjoa Haven','NU'),('CA','YHM','Hamilton Apt','Hamilton Apt','ON'),('CA','YHN','Hornepayne','Hornepayne','ON'),('CA','YHR','Chevery','Chevery','QC'),('CA','YHS','Sechelt','Sechelt','BC'),('CA','YHY','Hay River','Hay River','NT'),('CA','YHZ','Halifax Apt','Halifax Apt','NS'),('CA','YIB','Atikokan','Atikokan','ON'),('CA','YIF','Pakuashipi','Pakuashipi','QC'),('CA','YIK','Ivujivik','Ivujivik','QC'),('CA','YIV','Island Lk/Garden Hill','Island Lk/Garden Hill','MB'),('CA','YJF','Fort Liard','Fort Liard','NT'),('CA','YJN','St Jean','St Jean','QC'),('CA','YJO','Johnny Mountain','Johnny Mountain','BC'),('CA','YKC','Collins Bay','Collins Bay','SK'),('CA','YKE','Knee Lake','Knee Lake','MB'),('CA','YKG','Kangirsuk','Kangirsuk','QC'),('CA','YKI','Kennosao Lake','Kennosao Lake','MB'),('CA','YKJ','Key Lake','Key Lake','SK'),('CA','YKK','Kitkatla','Kitkatla','BC'),('CA','YKL','Schefferville','Schefferville','QC'),('CA','YKQ','Waskaganish','Waskaganish','QC'),('CA','YKT','Klemtu','Klemtu','BC'),('CA','YKU','Chisasibi','Chisasibi','QC'),('CA','YKX','Kirkland Lake','Kirkland Lake','ON'),('CA','YKY','Kindersley','Kindersley','SK'),('CA','YLA','Langara','Langara','BC'),('CA','YLB','Lac Biche','Lac Biche','AB'),('CA','YLC','Kimmirut/Lake Harbour','Kimmirut/Lake Harbour','NT'),('CA','YLD','Chapleau','Chapleau','ON'),('CA','YLE','Wha Ti/Lac La Martre','Wha Ti/Lac La Martre','NT'),('CA','YLF','Laforges','Laforges','QC'),('CA','YLH','Lansdowne House','Lansdowne House','ON'),('CA','YLJ','Meadow Lake','Meadow Lake','SK'),('CA','YLL','Lloydminster','Lloydminster','AB'),('CA','YLM','Clinton Creek','Clinton Creek','YT'),('CA','YLP','Mingan','Mingan','QC'),('CA','YLQ','La Tuque','La Tuque','QC'),('CA','YLS','Lebel-sur-Quevillon','Lebel-sur-Quevillon','QC'),('CA','YLX','Long Point','Long Point','ON'),('CA','YLY','Lytton','Lytton','BC'),('CA','YMA','Mayo','Mayo','YT'),('CA','YMB','Merritt','Merritt','BC'),('CA','YMC','Maricourt Airstrip','Maricourt Airstrip','QC'),('CA','YMD','Mould Bay','Mould Bay','NT'),('CA','YMF','Montagne Harbor','Montagne Harbor','BC'),('CA','YMG','Manitouwadge','Manitouwadge','ON'),('CA','YMH','Mary\'s Harbour','Mary\'s Harbour','NL'),('CA','YMI','Minaki','Minaki','ON'),('CA','YMJ','Moose Jaw','Moose Jaw','SK'),('CA','YML','Murray Bay','Murray Bay','QC'),('CA','YMM','Fort McMurray','Fort McMurray','AB'),('CA','YMN','Makkovik','Makkovik','NL'),('CA','YMR','Merry Island','Merry Island','BC'),('CA','YMT','Chibougamau','Chibougamau','QC'),('CA','YMW','Maniwaki','Maniwaki','QC'),('CA','YMX','Mirabel Apt/Montreal','Mirabel Apt/Montreal','QC'),('CA','YNA','Natashquan','Natashquan','QC'),('CA','YNC','Wemindji','Wemindji','QC'),('CA','YNE','Norway House','Norway House','MB'),('CA','YNH','Hudson Hope','Hudson Hope','BC'),('CA','YNI','Nitchequon','Nitchequon','QC'),('CA','YNK','Nootka Sound','Nootka Sound','BC'),('CA','YNM','Matagami','Matagami','QC'),('CA','YNO','North Spirit Lake','North Spirit Lake','ON'),('CA','YNR','Arnes','Arnes','MB'),('CA','YNS','Nemiscau','Nemiscau','QC'),('CA','YOC','Old Crow','Old Crow','YT'),('CA','YOD','Cold Lake','Cold Lake','AB'),('CA','YOE','Falher','Falher','AB'),('CA','YOG','Ogoki','Ogoki','ON'),('CA','YOH','Oxford House','Oxford House','MB'),('CA','YOJ','High Level','High Level','AB'),('CA','YOW','Ottawa Apt','Ottawa Apt','ON'),('CA','YOY','Valcartier','Valcartier','QC'),('CA','YPC','Paulatuk','Paulatuk','NT'),('CA','YPE','Peace River','Peace River','AB'),('CA','YPH','Inukjuak','Inukjuak','QC'),('CA','YPJ','Aupauluk','Aupauluk','QC'),('CA','YPL','Pickle Lake','Pickle Lake','ON'),('CA','YPM','Pikangikum','Pikangikum','ON'),('CA','YPO','Peawanuck','Peawanuck','ON'),('CA','YPP','Pine Point','Pine Point','NT'),('CA','YPY','Fort Chipewyan','Fort Chipewyan','AB'),('CA','YPZ','Burns Lake','Burns Lake','BC'),('CA','YQA','Muskoka','Muskoka','ON'),('CA','YQB','Quebec Apt','Quebec Apt','QC'),('CA','YQD','The Pas','The Pas','MB'),('CA','YQE','Kimberley','Kimberley','BC'),('CA','YQF','Red Deer','Red Deer','AB'),('CA','YQH','Watson Lake Apt','Watson Lake Apt','BC'),('CA','YQK','Kenora','Kenora','ON'),('CA','YQN','Nakina','Nakina','ON'),('CA','YQR','Regina Apt','Regina Apt','SK'),('CA','YQU','Grande Prairie','Grande Prairie','AB'),('CA','YQV','Yorkton','Yorkton','SK'),('CA','YQW','North Battleford','North Battleford','SK'),('CA','YRD','Dean River','Dean River','BC'),('CA','YRF','Cartwright','Cartwright','NL'),('CA','YRG','Rigolet','Rigolet','NL'),('CA','YRH','Yarmouth','Yarmouth','NS'),('CA','YRJ','Roberval','Roberval','QC'),('CA','YRK','York','York','ON'),('CA','YRM','Rocky Mountain House','Rocky Mountain House','AB'),('CA','YRN','Rivers Inlet','Rivers Inlet','BC'),('CA','YRR','Stuart Island','Stuart Island','BC'),('CA','YRV','Revelstoke','Revelstoke','BC'),('CA','YRW','Yarrow','Yarrow','BC'),('CA','YSA','Sable Island','Sable Island','NS'),('CA','YSD','Suffield','Suffield','AB'),('CA','YSF','Stony Rapids','Stony Rapids','SK'),('CA','YSG','Lutselke/Snowdrift','Lutselke/Snowdrift','NT'),('CA','YSH','Smith Falls','Smith Falls','ON'),('CA','YSI','Sans Souci','Sans Souci','ON'),('CA','YSJ','St John Apt','St John Apt','NB'),('CA','YSK','Sanikiluaq','Sanikiluaq','NU'),('CA','YSL','St Leonard','St Leonard','NB'),('CA','YSN','Salmon Arm','Salmon Arm','BC'),('CA','YSQ','Spring Island','Spring Island','BC'),('CA','YSS','Slate Island','Slate Island','ON'),('CA','YST','Ste Therese Point','Ste Therese Point','MB'),('CA','YSV','Saglek','Saglek','NL'),('CA','YSW','Salluit','Salluit','QC'),('CA','YSX','Shearwater','Shearwater','BC'),('CA','YSY','Sachs Harbour','Sachs Harbour','NT'),('CA','YSZ','Squirrel Cove','Squirrel Cove','BC'),('CA','YTB','Hartley Bay','Hartley Bay','BC'),('CA','YTC','Sturdee','Sturdee','BC'),('CA','YTD','Thicket Portage','Thicket Portage','MB'),('CA','YTF','Alma','Alma','QC'),('CA','YTG','Sullivan Bay','Sullivan Bay','BC'),('CA','YTH','Thompson','Thompson','MB'),('CA','YTI','Triple Island','Triple Island','BC'),('CA','YTJ','Terrace Bay','Terrace Bay','ON'),('CA','YTK','Tulugak','Tulugak','QC'),('CA','YTN','Riviere-au-Tonnerre','Riviere-au-Tonnerre','QC'),('CA','YTO','Guildwood Apt/Toronto','Guildwood Apt/Toronto','ON'),('CA','YTQ','Tasiujaq','Tasiujaq','QC'),('CA','YTS','Timmins','Timmins','ON'),('CA','YTT','Tisdale','Tisdale','SK'),('CA','YTX','Telegraph Creek','Telegraph Creek','BC'),('CA','YUF','Pelly Bay','Pelly Bay','NT'),('CA','YUL','Montreal-Dorval Apt','Montreal-Dorval Apt','QC'),('CA','YUY','Rouyn-Noranda','Rouyn-Noranda','QC'),('CA','YVB','Bonaventure','Bonaventure','QC'),('CA','YVC','La Ronge','La Ronge','SK'),('CA','YVG','Vermilion','Vermilion','AB'),('CA','YVO','Val-d\'Or','Val-d\'Or','QC'),('CA','YVQ','Norman Wells','Norman Wells','NT'),('CA','YVR','Vancouver Apt','Vancouver Apt','BC'),('CA','YVT','Buffalo Narrows','Buffalo Narrows','SK'),('CA','YVV','Wiarton','Wiarton','ON'),('CA','YVZ','Deer Lake','Deer Lake','ON'),('CA','YWA','Petawawa','Petawawa','ON'),('CA','YWB','Kangiqsujuaq','Kangiqsujuaq','QC'),('CA','YWG','Winnipeg Apt','Winnipeg Apt','MB'),('CA','YWJ','Deline','Deline','NT'),('CA','YWK','Wabush','Wabush','NL'),('CA','YWL','Williams Lake','Williams Lake','BC'),('CA','YWM','Williams Harbour','Williams Harbour','NL'),('CA','YWN','Winisk','Winisk','ON'),('CA','YWP','Webequie','Webequie','ON'),('CA','YWR','White River','White River','ON'),('CA','YWS','Whistler','Whistler','BC'),('CA','YWY','Wrigley','Wrigley','NT'),('CA','YXC','Cranbrook','Cranbrook','BC'),('CA','YXF','Snake River','Snake River','YT'),('CA','YXH','Medicine Hat','Medicine Hat','AB'),('CA','YXI','Killaloe','Killaloe','ON'),('CA','YXL','Sioux Lookout','Sioux Lookout','ON'),('CA','YXN','Whale Cove','Whale Cove','NU'),('CA','YXR','Earlton','Earlton','ON'),('CA','YXT','Terrace','Terrace','BC'),('CA','YXY','Whitehorse','Whitehorse','YT'),('CA','YXZ','Wawa','Wawa','ON'),('CA','YYC','Calgary Apt','Calgary Apt','AB'),('CA','YYD','Smithers','Smithers','BC'),('CA','YYF','Penticton','Penticton','BC'),('CA','YYH','Taloyoak','Taloyoak','NU'),('CA','YYI','Rivers','Rivers','MB'),('CA','YYL','Lynn Lake','Lynn Lake','MB'),('CA','YYM','Cowley','Cowley','AB'),('CA','YYN','Swift Current','Swift Current','SK'),('CA','YYT','St Johns Apt','St Johns Apt','NL'),('CA','YYU','Kapuskasing','Kapuskasing','ON'),('CA','YYY','Mont Joli','Mont Joli','QC'),('CA','YYZ','Lester B. Pearson International/Toronto','Lester B. Pearson International/Toronto','ON'),('CA','YZA','Ashcroft','Ashcroft','BC'),('CA','YZE','Gore Bay','Gore Bay','ON'),('CA','YZF','Yellowknife','Yellowknife','NT'),('CA','YZH','Slave Lake','Slave Lake','AB'),('CA','YZM','Buchans','Buchans','NL'),('CA','YZS','Coral Harbour','Coral Harbour','NU'),('CA','YZW','Teslin','Teslin','YT'),('CA','YZX','Greenwood','Greenwood','NS'),('CA','ZAC','York Landing','York Landing','MB'),('CA','ZBM','Bromont','Bromont','QC'),('CA','ZCR','St-Charles-sur-Richelieu','St-Charles-sur-Richelieu','QC'),('CA','ZEB','Zeballos','Zeballos','BC'),('CA','ZEM','East Main','East Main','QC'),('CA','ZFA','Faro','Faro','YT'),('CA','ZFB','Old Fort Bay','Old Fort Bay','QC'),('CA','ZFD','Fond du Lac','Fond du Lac','SK'),('CA','ZFL','South Trout Lake','South Trout Lake','ON'),('CA','ZFM','Fort McPherson','Fort McPherson','NT'),('CA','ZFN','Tulita/Fort Norman','Tulita/Fort Norman','NT'),('CA','ZFT','Forest','Forest','ON'),('CA','ZFW','Fairview','Fairview','AB'),('CA','ZGF','Grand Forks','Grand Forks','BC'),('CA','ZGI','Gods River','Gods River','MB'),('CA','ZGR','Little Grand Rapids','Little Grand Rapids','MB'),('CA','ZGS','Gethsemani','Gethsemani','QC'),('CA','ZHP','High Prairie','High Prairie','AB'),('CA','ZJG','Jenpeg','Jenpeg','MB'),('CA','ZJN','Swan River','Swan River','MB'),('CA','ZKE','Kaschechewan','Kaschechewan','ON'),('CA','ZKG','Kegaska','Kegaska','QC'),('CA','ZLT','La Tabatiere','La Tabatiere','QC'),('CA','ZNG','Negginan','Negginan','MB'),('CA','ZNU','Namu','Namu','BC'),('CA','ZPB','Sachigo Lake','Sachigo Lake','ON'),('CA','ZPO','Pine House','Pine House','SK'),('CA','ZRJ','Round Lake','Round Lake','ON'),('CA','ZSJ','Sandy Lake','Sandy Lake','ON'),('CA','ZSP','St Paul','St Paul','QC'),('CA','ZTB','Tete-a-la-Baleine','Tete-a-la-Baleine','QC'),('CA','ZTI','Saint Tite','Saint Tite','QC'),('CA','ZTM','Shamattawa','Shamattawa','MB'),('CA','ZUC','Ignace','Ignace','ON'),('CA','ZUM','Churchill Falls','Churchill Falls','NL'),('CA','ZWL','Wollaston Lake','Wollaston Lake','SK'),('CA','ZYE','Yamachiche','Yamachiche','QC'),('CC','','','',''),('CC','CCK','Cocos Islands','Cocos Islands',''),('CD','','','',''),('CD','ANG','Ango-Ango','Ango-Ango',''),('CD','BAN','Basongo','Basongo',''),('CD','BDT','Gbadolite','Gbadolite',''),('CD','BDV','Moba','Moba',''),('CD','BKY','Bukavu','Bukavu',''),('CD','BMB','Bumba','Bumba',''),('CD','BNB','Boende','Boende',''),('CD','BNC','Beni','Beni',''),('CD','BNW','Banana','Banana',''),('CD','BOA','Boma','Boma',''),('CD','BSU','Basankusu','Basankusu',''),('CD','BUT','Butembo','Butembo',''),('CD','BUX','Bunia','Bunia',''),('CD','BZU','Buta','Buta',''),('CD','DIC','Dili','Dili',''),('CD','FBM','Lubumbashi','Lubumbashi',''),('CD','FDU','Bandundu','Bandundu',''),('CD','FIH','Kinshasa','Kinshasa',''),('CD','FKI','Kisangani','Kisangani',''),('CD','FMI','Kalemie','Kalemie',''),('CD','GDJ','Gandajika','Gandajika',''),('CD','GMA','Gemena','Gemena',''),('CD','GOM','Goma','Goma',''),('CD','IDF','Idiofa','Idiofa',''),('CD','IKL','Ikela','Ikela',''),('CD','INO','Inongo','Inongo',''),('CD','IRP','Isiro','Isiro',''),('CD','KAP','Kapanga','Kapanga',''),('CD','KAS','Kasumbalesa','Kasumbalesa',''),('CD','KBN','Kabinda','Kabinda',''),('CD','KBO','Kabalo','Kabalo',''),('CD','KEC','Kasenga','Kasenga',''),('CD','KGA','Kananga','Kananga',''),('CD','KGN','Kasongo-Lunda','Kasongo-Lunda',''),('CD','KIL','Kilwa','Kilwa',''),('CD','KKW','Kikwit','Kikwit',''),('CD','KLI','Kota Koli','Kota Koli',''),('CD','KLY','Kalima','Kalima',''),('CD','KMN','Kamina','Kamina',''),('CD','KND','Kindu','Kindu',''),('CD','KNM','Kaniama','Kaniama',''),('CD','KOO','Kongolo','Kongolo',''),('CD','KPU','Kipushi','Kipushi',''),('CD','KRZ','Kiri','Kiri',''),('CD','KWZ','Kolwezi','Kolwezi',''),('CD','LBO','Lusambo','Lusambo',''),('CD','LIE','Libenge','Libenge',''),('CD','LIQ','Lisala','Lisala',''),('CD','LJA','Lodja','Lodja',''),('CD','LUS','Lusanga','Lusanga',''),('CD','LZA','Luiza','Luiza',''),('CD','LZI','Luozi','Luozi',''),('CD','MAT','Matadi','Matadi',''),('CD','MDK','Mbandaka','Mbandaka',''),('CD','MEW','Mweka','Mweka',''),('CD','MJM','Mbuji-Mayi','Mbuji-Mayi',''),('CD','MKL','Makala','Makala',''),('CD','MNB','Moanda','Moanda',''),('CD','MNO','Manono','Manono',''),('CD','MSM','Masi-Manimba','Masi-Manimba',''),('CD','NIO','Nioki','Nioki',''),('CD','NKL','Nkolo','Nkolo',''),('CD','NLO','N\'dolo','N\'dolo',''),('CD','PFR','Ilebo','Ilebo',''),('CD','PUN','Punia','Punia',''),('CD','PWO','Pweto','Pweto',''),('CD','TSH','Tshikapa','Tshikapa',''),('CD','UVI','Uvira','Uvira',''),('CD','YAN','Yangambi','Yangambi',''),('CF','','','',''),('CF','AIG','Yalinga','Yalinga',''),('CF','ALI','Alindao','Alindao',''),('CF','BAB','Baboua','Baboua',''),('CF','BAO','Baoro','Baoro',''),('CF','BBT','Berberati','Berberati',''),('CF','BBY','Bambari','Bambari',''),('CF','BCF','Bouca','Bouca',''),('CF','BEM','Bossembele','Bossembele',''),('CF','BGF','Bangui','Bangui',''),('CF','BGU','Bangassou','Bangassou',''),('CF','BIV','Bria','Bria',''),('CF','BMF','Bakouma','Bakouma',''),('CF','BOC','Bocaranga','Bocaranga',''),('CF','BOD','Boda','Boda',''),('CF','BOG','Bogoto','Bogoto',''),('CF','BOP','Bouar','Bouar',''),('CF','BOZ','Bozoum','Bozoum',''),('CF','BSN','Bossangoa','Bossangoa',''),('CF','BTG','Batangafo','Batangafo',''),('CF','CRF','Carnot','Carnot',''),('CF','DEK','Dekoa','Dekoa',''),('CF','GDA','Gounda','Gounda',''),('CF','GDI','Gordil','Gordil',''),('CF','GRI','Grimari','Grimari',''),('CF','IMO','Zemio','Zemio',''),('CF','IRO','Birao','Birao',''),('CF','KAB','Kaga Bandoro','Kaga Bandoro',''),('CF','KEM','Kembe','Kembe',''),('CF','KOL','Koumala','Koumala',''),('CF','KWD','Kawadjia','Kawadjia',''),('CF','MKI','M\'Baiki','M\'Baiki',''),('CF','MOB','Mobaye','Mobaye',''),('CF','MON','Mongoumba','Mongoumba',''),('CF','NDL','Ndele','Ndele',''),('CF','NOL','Nola','Nola',''),('CF','OBO','Obo','Obo',''),('CF','ODA','Ouadda','Ouadda',''),('CF','ODJ','Ouanda Djalle','Ouanda Djalle',''),('CF','PAO','Paoua','Paoua',''),('CF','RFA','Rafai','Rafai',''),('CF','SIB','Sibut','Sibut',''),('CG','','','',''),('CG','ANJ','Zanaga','Zanaga',''),('CG','BOE','Boundji','Boundji',''),('CG','BTB','Betou','Betou',''),('CG','BZV','Brazzaville','Brazzaville',''),('CG','DIS','Loubomo','Loubomo',''),('CG','DJE','Djeno Terminal','Djeno Terminal',''),('CG','DJM','Djambala','Djambala',''),('CG','EPN','Epena','Epena',''),('CG','EWO','Ewo','Ewo',''),('CG','GMM','Gamboma','Gamboma',''),('CG','ION','Impfondo','Impfondo',''),('CG','KEE','Kelle','Kelle',''),('CG','KMK','Makabana','Makabana',''),('CG','KNJ','Kindamba','Kindamba',''),('CG','LCO','Lague','Lague',''),('CG','LKC','Lekana','Lekana',''),('CG','MBI','Mbinda','Mbinda',''),('CG','MKJ','Makoua','Makoua',''),('CG','MOS','Mossaka','Mossaka',''),('CG','MSX','Mossendjo','Mossendjo',''),('CG','MUY','Mouyondzi','Mouyondzi',''),('CG','NKO','N\'Kossa Terminal','N\'Kossa Terminal',''),('CG','NKY','Nkayi','Nkayi',''),('CG','OKG','Okoyo','Okoyo',''),('CG','OUE','Ouesso','Ouesso',''),('CG','OYO','Oyo','Oyo',''),('CG','PNR','Pointe Noire','Pointe Noire',''),('CG','SOE','Souanke','Souanke',''),('CH','','','',''),('CH','AAB','Aarburg','Aarburg','AG'),('CH','AAR','Aarau','Aarau','AG'),('CH','ABD','Arbedo','Arbedo','TI'),('CH','ABG','Aarberg','Aarberg','BE'),('CH','ADL','Adelboden','Adelboden','BE'),('CH','ADO','Ardon','Ardon','VS'),('CH','AES','Aesch','Aesch','BL'),('CH','AFT','Affoltern am Albis','Affoltern am Albis','ZH'),('CH','AGT','Augst','Augst','BL'),('CH','AHF','Altishofen','Altishofen','LU'),('CH','AIG','Aigle','Aigle','VD'),('CH','AIR','Airolo','Airolo','TI'),('CH','ALT','Altendorf','Altendorf','SZ'),('CH','APP','Appenzell','Appenzell','AI'),('CH','ARB','Altdorf','Altdorf',''),('CH','ARH','Arth','Arth','SZ'),('CH','ARL','Arolla','Arolla','VS'),('CH','ARS','Arosa','Arosa','GR'),('CH','ASC','Ascona','Ascona','TI'),('CH','ASN','Altstatten','Altstatten','SG'),('CH','ASW','Allschwil','Allschwil','BL'),('CH','ATR','Altenrhein','Altenrhein','SG'),('CH','ATT','Pratteln','Pratteln','BL'),('CH','AUS','Au','Au','SG'),('CH','AVE','Avenches','Avenches','VD'),('CH','AWL','Amriswil','Amriswil','TG'),('CH','BAB','Bachenbulach','Bachenbulach','ZH'),('CH','BAD','Baden','Baden','AG'),('CH','BAL','Balgach','Balgach','SG'),('CH','BAR','Baar','Baar','ZG'),('CH','BBL','Bremblens','Bremblens','VD'),('CH','BBN','Biberstein','Biberstein','AG'),('CH','BCU','Boncourt','Boncourt','JU'),('CH','BCZ','Bischofszell','Bischofszell','TG'),('CH','BDF','Birmensdorf','Birmensdorf','ZH'),('CH','BDY','Boudry','Boudry','NE'),('CH','BEG','Bissegg','Bissegg','TG'),('CH','BEL','Bellach','Bellach','SO'),('CH','BER','Beringen','Beringen','SH'),('CH','BEX','Bex','Bex','VD'),('CH','BFL','Birsfelden','Birsfelden','BL'),('CH','BGF','Burgdorf','Burgdorf','BE'),('CH','BGG','Brugg','Brugg','AG'),('CH','BGN','Bargen','Bargen','SH'),('CH','BGZ','Breganzona','Breganzona','TI'),('CH','BIA','Biasca','Biasca','TI'),('CH','BIB','Biberist','Biberist','SO'),('CH','BIE','Biel','Biel','BE'),('CH','BIL','Billens','Billens','FR'),('CH','BIO','Bioggio','Bioggio','TI'),('CH','BIZ','Binz','Binz','ZH'),('CH','BKD','Batterkinden','Batterkinden','BE'),('CH','BKN','Benken','Benken','SG'),('CH','BLA','Balerna','Balerna','TI'),('CH','BLE','Bleienbach','Bleienbach','BE'),('CH','BLN','Buchslen','Buchslen','FR'),('CH','BLP','Belp','Belp','BE'),('CH','BLT','Bilten','Bilten','GL'),('CH','BMG','Bremgarten','Bremgarten',''),('CH','BNX','Bernex','Bernex','GE'),('CH','BOD','Bodio','Bodio','TI'),('CH','BOS','Boswil','Boswil','AG'),('CH','BOV','Boveresse','Boveresse','NE'),('CH','BRI','Brig','Brig','VS'),('CH','BRN','Bern','Bern','BE'),('CH','BRO','Bronschhofen','Bronschhofen','SG'),('CH','BRR','Birr','Birr','AG'),('CH','BRU','Brunnen','Brunnen','SZ'),('CH','BRZ','Bad Ragaz','Bad Ragaz','SG'),('CH','BSG','Bisingen','Bisingen',''),('CH','BSL','Basel','Basel','BS'),('CH','BSS','Boussens','Boussens','VD'),('CH','BST','Balsthal','Balsthal','SO'),('CH','BSU','Busswil','Busswil','BE'),('CH','BTL','Bruttisellen','Bruttisellen','ZH'),('CH','BUA','Bulach','Bulach','ZH'),('CH','BUB','Bubendorf','Bubendorf','BL'),('CH','BUC','Buchs','Buchs','SG'),('CH','BUL','Bulle','Bulle','FR'),('CH','BUR','Bursinel','Bursinel','VD'),('CH','BVX','Bevaix','Bevaix','NE'),('CH','BWI','Balterswil','Balterswil','TG'),('CH','BZA','Bellinzona','Bellinzona','TI'),('CH','BZG','Butzberg','Butzberg','BE'),('CH','CAD','Cadenazzo','Cadenazzo','TI'),('CH','CAS','Castasegna','Castasegna','GR'),('CH','CDY','Crans','Crans',''),('CH','CHI','Chiasso','Chiasso','TI'),('CH','CHO','Chateau-d\'Oex','Chateau-d\'Oex','VD'),('CH','CHP','Champery','Champery','VS'),('CH','CHR','Chur','Chur','GR'),('CH','CHT','Thorishaus','Thorishaus','BE'),('CH','CHX','Choex','Choex','VS'),('CH','COL','Collombey','Collombey','VS'),('CH','CON','Concise','Concise','VD'),('CH','CPA','Champagne','Champagne','VD'),('CH','CPS','Chippis','Chippis','VS'),('CH','CRE','Le Cret','Le Cret','FR'),('CH','CRG','Carouge','Carouge','GE'),('CH','CRI','Crissier','Crissier','VD'),('CH','CRT','Cortaillod','Cortaillod','NE'),('CH','CTY','Courtelary','Courtelary','BE'),('CH','CUG','Cugy','Cugy','VD'),('CH','CVY','Chavornay','Chavornay','VD'),('CH','DAE','Dagmersellen','Dagmersellen','LU'),('CH','DDR','Domdidier','Domdidier','FR'),('CH','DEL','Delemont','Delemont','JU'),('CH','DGI','Duggingen','Duggingen','BE'),('CH','DGS','Degersheim','Degersheim','SG'),('CH','DIE','Dietikon','Dietikon','ZH'),('CH','DIG','Dudingen','Dudingen','FR'),('CH','DIN','Dulliken','Dulliken','SO'),('CH','DIS','Disentis/Muster','Disentis/Muster','GR'),('CH','DLD','Dielsdorf','Dielsdorf','ZH'),('CH','DLK','Dietlikon','Dietlikon','ZH'),('CH','DLS','Daillens','Daillens','VD'),('CH','DMT','Domat','Domat','GR'),('CH','DNK','Daniken','Daniken','SO'),('CH','DON','Dallikon','Dallikon','ZH'),('CH','DOR','Dornach','Dornach','SO'),('CH','DOT','Dottingen','Dottingen','AG'),('CH','DOZ','Dozwil','Dozwil','TG'),('CH','DPS','Diepoldsau','Diepoldsau','SG'),('CH','DPZ','Davos Platz','Davos Platz','GR'),('CH','DRD','Derendingen','Derendingen','SO'),('CH','DRF','Dubendorf','Dubendorf','ZH'),('CH','DTG','Detligen','Detligen','BE'),('CH','DTK','Dintikon','Dintikon','ZH'),('CH','DTZ','Dotzigen','Dotzigen','BE'),('CH','DWL','Dattwil','Dattwil','AG'),('CH','EBC','Emmenbrucke','Emmenbrucke','LU'),('CH','EBH','Embrach','Embrach','ZH'),('CH','ECH','Echandens','Echandens','VD'),('CH','ECL','Eclepens','Eclepens','VD'),('CH','EDB','Edlibach','Edlibach','ZG'),('CH','EDG','Endingen','Endingen','AG'),('CH','EGL','Egliswil','Egliswil','AG'),('CH','EHK','Eschlikon','Eschlikon','TG'),('CH','EIK','Eiken','Eiken','AG'),('CH','EIN','Ebikon','Ebikon','LU'),('CH','EKO','Eschlikon','Eschlikon','ZH'),('CH','ELB','Estavayer-le-Gibloux','Estavayer-le-Gibloux','FR'),('CH','ELL','Estavayer-le-Lac','Estavayer-le-Lac','FR'),('CH','ELS','Ecublens','Ecublens','FR'),('CH','EMM','Emmen','Emmen','LU'),('CH','ENG','Engelberg','Engelberg','OW'),('CH','ENT','Entlebuch','Entlebuch','LU'),('CH','EPS','Epesses','Epesses','VD'),('CH','ERL','Erlinsbach','Erlinsbach','AG'),('CH','ESD','Einsiedeln','Einsiedeln','SZ'),('CH','ETO','Etoy','Etoy','VD'),('CH','ETT','Ettingen','Ettingen','BL'),('CH','FAH','Flaach','Flaach','ZH'),('CH','FBH','Freienbach','Freienbach','SZ'),('CH','FCH','Forch','Forch','ZH'),('CH','FCK','Frick','Frick','AG'),('CH','FEH','Feldbach','Feldbach','TG'),('CH','FEY','Fey','Fey','VD'),('CH','FHY','Fahy','Fahy','JU'),('CH','FKD','Frenkendorf','Frenkendorf','BL'),('CH','FLI','Fleurier','Fleurier','NE'),('CH','FLJ','Flurlingen','Flurlingen','ZH'),('CH','FLN','Fluelen','Fluelen','UR'),('CH','FLU','Flums','Flums','SG'),('CH','FLW','Flawil','Flawil','SG'),('CH','FLY','Fully','Fully','VS'),('CH','FRB','Fribourg','Fribourg','FR'),('CH','FRF','Fullinsdorf','Fullinsdorf','BL'),('CH','FRN','Frauenfeld','Frauenfeld','TG'),('CH','FSG','Feusisberg','Feusisberg','SZ'),('CH','FTF','Fehraltorf','Fehraltorf','ZH'),('CH','FTN','Frutigen','Frutigen','BE'),('CH','FWG','Fahrwangen','Fahrwangen','AG'),('CH','GAN','Gansingen','Gansingen','AG'),('CH','GBS','Giubiasco','Giubiasco','TI'),('CH','GDN','Grandson','Grandson','VD'),('CH','GDW','Geroldswil','Geroldswil','ZH'),('CH','GFG','Gerlafingen','Gerlafingen','SO'),('CH','GFN','Glattfelden','Glattfelden','ZH'),('CH','GFR','Grafenried','Grafenried','BE'),('CH','GKR','Gelterkinden','Gelterkinden','BL'),('CH','GLA','Glarus','Glarus','GL'),('CH','GLD','Goldach','Goldach','SG'),('CH','GNE','Grone','Grone','VS'),('CH','GNI','Granichen','Granichen','AG'),('CH','GOL','Goldau','Goldau','SZ'),('CH','GON','Gondo','Gondo','VS'),('CH','GOS','Gossau','Gossau','ZH'),('CH','GPM','Granges-pres-Marnand','Granges-pres-Marnand','VD'),('CH','GRI','Grindelwald','Grindelwald','BE'),('CH','GRN','Grenchen','Grenchen','SO'),('CH','GSR','Genestrerio','Genestrerio','TI'),('CH','GST','Gstaad','Gstaad','BE'),('CH','GSZ','Givisiez','Givisiez','FR'),('CH','GTG','Glattbrugg','Glattbrugg','ZH'),('CH','GVA','Geneve','Geneve','GE'),('CH','GWF','Eglisau','Eglisau','ZH'),('CH','GWT','Gwatt','Gwatt','BE'),('CH','HAU','Hausen bei Brugg','Hausen bei Brugg','AG'),('CH','HBG','Herrliberg','Herrliberg','ZH'),('CH','HEE','Heerbrugg','Heerbrugg','SG'),('CH','HEI','Heiden','Heiden','AR'),('CH','HGA','Hegnau','Hegnau','ZH'),('CH','HGD','Hagendorf','Hagendorf','SO'),('CH','HKN','Harkingen','Harkingen','SO'),('CH','HNW','Hinwil','Hinwil','ZH'),('CH','HOC','Hochdorf','Hochdorf','LU'),('CH','HOE','Horgen','Horgen','ZH'),('CH','HOH','Hohenrain','Hohenrain','LU'),('CH','HRI','Hori','Hori','ZH'),('CH','HRU','Hasle-Ruegsau','Hasle-Ruegsau','BE'),('CH','HRZ','Herzogenbuchsee','Herzogenbuchsee','BE'),('CH','HSA','Herisau','Herisau','AR'),('CH','HSN','Holstein','Holstein','BL'),('CH','HTT','Huttikon','Huttikon','ZH'),('CH','HUN','Hunenberg','Hunenberg','ZG'),('CH','HWL','Huttwil','Huttwil','BE'),('CH','HZW','Hunzenschwil','Hunzenschwil','AG'),('CH','ILZ','Ilanz','Ilanz','GR'),('CH','INS','Ins','Ins','BE'),('CH','INT','Interlaken','Interlaken','BE'),('CH','IPS','Ipsach','Ipsach','BE'),('CH','ISL','Islikon','Islikon','TG'),('CH','JGT','Jegenstorf','Jegenstorf','BE'),('CH','JNE','Jonen','Jonen','AG'),('CH','JON','Jona','Jona','SG'),('CH','JSY','Jussy','Jussy','GE'),('CH','KAI','Kaisten','Kaisten','AG'),('CH','KAN','Kandersteg','Kandersteg','BE'),('CH','KBO','Kleinbosingen','Kleinbosingen','FR'),('CH','KCO','Kirchdorf','Kirchdorf','BE'),('CH','KEH','Kemptthal','Kemptthal','ZH'),('CH','KER','Kerns','Kerns','OW'),('CH','KEZ','Kerzers','Kerzers','FR'),('CH','KFO','Kaufdorf','Kaufdorf','BE'),('CH','KGT','Kaiseraugst','Kaiseraugst','AG'),('CH','KHB','Kirchberg','Kirchberg','BE'),('CH','KHH','Kusnacht','Kusnacht','ZH'),('CH','KIE','Kiesen','Kiesen','BE'),('CH','KLR','Kirchleerau','Kirchleerau','AG'),('CH','KLS','Klosters','Klosters','GR'),('CH','KNA','Knonau','Knonau','ZH'),('CH','KNN','Kunten','Kunten','AG'),('CH','KOL','Kolliken','Kolliken','AG'),('CH','KON','Konolfingen','Konolfingen','BE'),('CH','KRG','Kirchberg','Kirchberg','SG'),('CH','KRS','Kriens','Kriens','LU'),('CH','KRZ','Kreuzlingen','Kreuzlingen','TG'),('CH','KSN','Kriessern','Kriessern','SG'),('CH','KSO','Kestenholz','Kestenholz','SO'),('CH','KTN','Kloten','Kloten','ZH'),('CH','LAF','Laufenburg','Laufenburg','AG'),('CH','LAN','Langenthal','Langenthal','BE'),('CH','LAU','Lausanne','Lausanne','VD'),('CH','LBG','Lenzburg','Lenzburg','AG'),('CH','LBN','Lamboing','Lamboing','BE'),('CH','LBT','Leibstadt','Leibstadt','AG'),('CH','LCA','Le Chable','Le Chable','VS'),('CH','LCF','La Chaux-de-Fonds','La Chaux-de-Fonds','NE'),('CH','LCR','La Croix-de-Rozon','La Croix-de-Rozon','GE'),('CH','LDO','Le Landeron','Le Landeron','NE'),('CH','LEN','Koblenz','Koblenz','AG'),('CH','LES','Les Acacias','Les Acacias','GE'),('CH','LEU','Leuk','Leuk','VS'),('CH','LFN','Laufen','Laufen','BL'),('CH','LGE','Leuggern','Leuggern','AG'),('CH','LGN','Lungern','Lungern','OW'),('CH','LGS','Le Grand-Saconnex','Le Grand-Saconnex','GE'),('CH','LGU','Langnau','Langnau','BE'),('CH','LHN','Lachen','Lachen','SZ'),('CH','LIT','Littau','Littau','LU'),('CH','LIU','Lindau','Lindau','ZH'),('CH','LLU','Le Lieu','Le Lieu','VD'),('CH','LNG','Lengnau','Lengnau','BE'),('CH','LNZ','Lenzerheide','Lenzerheide','GR'),('CH','LOE','Lamone','Lamone','TI'),('CH','LON','Locarno','Locarno','TI'),('CH','LOT','Lotzwil','Lotzwil','BE'),('CH','LPN','Laupen','Laupen','ZH'),('CH','LQU','Landquart','Landquart','GR'),('CH','LSA','Lyssach','Lyssach','BE'),('CH','LSG','Lichtensteig','Lichtensteig','SG'),('CH','LTL','Liestal','Liestal','BL'),('CH','LUG','Lugano','Lugano','TI'),('CH','LVA','Le Vaud','Le Vaud','VD'),('CH','LVR','Les Verrieres','Les Verrieres','NE'),('CH','LYS','Lyss','Lyss','BE'),('CH','LZN','Luzern','Luzern','LU'),('CH','MAE','Marwil','Marwil','TG'),('CH','MAR','Marstetten','Marstetten','TG'),('CH','MAT','Matran','Matran','FR'),('CH','MBB','Muri bei Bern','Muri bei Bern','BE'),('CH','MDL','Madetswil','Madetswil','ZH'),('CH','MEI','Meiringen','Meiringen','BE'),('CH','MEN','Mendrisio','Mendrisio','TI'),('CH','MET','Mettmenstetten','Mettmenstetten','ZH'),('CH','MEY','Meyrin','Meyrin','GE'),('CH','MEZ','Mezzovico','Mezzovico','TI'),('CH','MGW','Magenwil','Magenwil','AG'),('CH','MGY','Martigny','Martigny','VS'),('CH','MHL','Mohlin','Mohlin','AG'),('CH','MIO','Minusio','Minusio','TI'),('CH','MIS','Mies','Mies','VD'),('CH','MIT','Mitlodi','Mitlodi','GL'),('CH','MNB','Munchenbuchsee','Munchenbuchsee','BE'),('CH','MNN','Manno','Manno','TI'),('CH','MNT','Montreux','Montreux','VD'),('CH','MOL','Mollis','Mollis','GL'),('CH','MON','Monthey','Monthey','VS'),('CH','MOS','Morges','Morges','VD'),('CH','MOU','Moudon','Moudon','VD'),('CH','MPF','Mumpf','Mumpf','AG'),('CH','MRG','Murgenthal','Murgenthal','AG'),('CH','MRL','Marly','Marly','FR'),('CH','MRO','Maroggia','Maroggia','TI'),('CH','MSD','Merenschwand','Merenschwand','AG'),('CH','MSN','Munsingen','Munsingen','BE'),('CH','MSR','Mustair','Mustair','GR'),('CH','MTN','Murten','Murten','FR'),('CH','MTR','Moutier','Moutier','BE'),('CH','MUN','Munchenstein','Munchenstein','BL'),('CH','MUR','Muri','Muri','AG'),('CH','MUS','Munchenstein','Munchenstein','BL'),('CH','MUT','Muttenz','Muttenz','BL'),('CH','MWI','Munchwilen','Munchwilen','TG'),('CH','MZI','Matzingen','Matzingen','TG'),('CH','MZN','Menzingen','Menzingen','ZG'),('CH','MZU','Menznau','Menznau','LU'),('CH','NBB','Nussbaumen bei Baden','Nussbaumen bei Baden','AG'),('CH','NBK','Nebikon','Nebikon','LU'),('CH','NDZ','Nendaz','Nendaz','VS'),('CH','NEF','Nafels','Nafels','GL'),('CH','NES','Nesslau','Nesslau','SG'),('CH','NEU','Neuendorf','Neuendorf','SO'),('CH','NGG','Neuenegg','Neuenegg','BE'),('CH','NHI','Niederhasli','Niederhasli','ZH'),('CH','NKN','Nanikon','Nanikon','ZH'),('CH','NLZ','Niederlenz','Niederlenz','AG'),('CH','NOR','Noranco','Noranco','TI'),('CH','NOZ','Novazzano','Novazzano','TI'),('CH','NRL','Niederuzwil','Niederuzwil','SG'),('CH','NTT','Niederglatt','Niederglatt',''),('CH','NUN','Niederurnen','Niederurnen','GL'),('CH','NWG','Niederweningen','Niederweningen','ZH'),('CH','NWT','Niederwichtrach','Niederwichtrach','BE'),('CH','NYO','Nyon','Nyon','VD'),('CH','NYZ','Neyruz','Neyruz','FR'),('CH','OBA','Ospizio Bernina','Ospizio Bernina','GR'),('CH','OBB','Oberbuchsiten','Oberbuchsiten','SO'),('CH','OBE','Oberuzwil','Oberuzwil','SG'),('CH','OBK','Oberkirch','Oberkirch','LU'),('CH','OBM','Oberkulm','Oberkulm','AG'),('CH','OBP','Oberbipp','Oberbipp','BE'),('CH','OBU','Oberburg','Oberburg','BE'),('CH','ODB','Oberried am Brienzersee','Oberried am Brienzersee','BE'),('CH','ODI','Oberdiessbach','Oberdiessbach','BE'),('CH','OEH','Oulens-sous-Echallens','Oulens-sous-Echallens','VD'),('CH','OFE','Oberentfelden','Oberentfelden','AG'),('CH','OFN','Opfikon','Opfikon','ZH'),('CH','OFT','Oftringen','Oftringen','AG'),('CH','OGI','Oberageri','Oberageri','ZG'),('CH','OLT','Olten','Olten','SO'),('CH','OMD','Ostermundigen','Ostermundigen','BE'),('CH','ORA','Oberaach','Oberaach','TG'),('CH','ORD','Oberrohrdorf','Oberrohrdorf','AG'),('CH','ORE','Orbe','Orbe','VD'),('CH','ORG','Oberglatt','Oberglatt','ZH'),('CH','ORN','Oberrieden','Oberrieden','ZH'),('CH','ORT','Oberriet','Oberriet','SG'),('CH','OSN','Oensingen','Oensingen','SO'),('CH','PEN','Penthaz','Penthaz','VD'),('CH','PFA','Pfaffikon','Pfaffikon','ZH'),('CH','PFN','Plaffeien','Plaffeien','FR'),('CH','PGS','Prangins','Prangins','VD'),('CH','PHZ','Penthalaz','Penthalaz','VD'),('CH','PLO','Plan-les-Ouates','Plan-les-Ouates','GE'),('CH','PLY','Pully','Pully','VD'),('CH','PRL','Pieterlen','Pieterlen','BE'),('CH','PRS','Preverenges','Preverenges','VD'),('CH','PRY','Porrentruy','Porrentruy','JU'),('CH','PTR','Pontresina','Pontresina','GR'),('CH','PYE','Payerne','Payerne','VD'),('CH','QBA','Bauma','Bauma','ZH'),('CH','QGL','St Gallen','St Gallen','SG'),('CH','QNC','Neuchatel','Neuchatel','NE'),('CH','QUA','Quartino','Quartino','TI'),('CH','RAM','Ramsen','Ramsen','SH'),('CH','RBG','Reichenburg','Reichenburg','SZ'),('CH','RCH','Reinach','Reinach','BL'),('CH','RCT','Rancate','Rancate','TI'),('CH','REI','Reiden','Reiden','LU'),('CH','REN','Reinach','Reinach','AG'),('CH','RFD','Rheinfelden','Rheinfelden','AG'),('CH','RFZ','Rafz','Rafz','ZH'),('CH','RGF','Regensdorf','Regensdorf','ZH'),('CH','RGW','Roggwil','Roggwil','BE'),('CH','RHI','Rickenbach','Rickenbach','TG'),('CH','RHN','Riehen','Riehen','BS'),('CH','RHW','Renens','Renens','VD'),('CH','RIC','Richterswil','Richterswil','ZH'),('CH','RKB','Rickenbach-Attikon','Rickenbach-Attikon','ZH'),('CH','RMA','Rumlang','Rumlang','ZH'),('CH','RMF','Remaufens','Remaufens','FR'),('CH','RMH','Romanshorn','Romanshorn','TG'),('CH','RNB','Reichenbach','Reichenbach','BE'),('CH','RNK','Rheineck','Rheineck','SG'),('CH','ROL','Rolle','Rolle','VD'),('CH','ROM','Romont','Romont','FR'),('CH','ROO','Root','Root','LU'),('CH','ROT','Rothenburg','Rothenburg','LU'),('CH','RPP','Rupperswil','Rupperswil','AG'),('CH','RRC','Rorschach','Rorschach','SG'),('CH','RRN','Raron','Raron','VS'),('CH','RTB','Ruti bei Buren','Ruti bei Buren','BE'),('CH','RTI','Ruti','Ruti',''),('CH','RTR','Rothrist','Rothrist','AG'),('CH','RUE','Ruegsauschachen','Ruegsauschachen','BE'),('CH','RUI','Ruti','Ruti','ZH'),('CH','RWL','Roggliswil','Roggliswil','LU'),('CH','SAA','Saanen','Saanen','BE'),('CH','SAB','St Blaise','St Blaise','NE'),('CH','SAF','Safenwil','Safenwil','AG'),('CH','SAN','Stans','Stans','NW'),('CH','SAR','Sargans','Sargans','SG'),('CH','SAT','Satigny','Satigny','GE'),('CH','SBB','Schubelbach','Schubelbach','SZ'),('CH','SBD','Sant\'Abbondio','Sant\'Abbondio','TI'),('CH','SBG','Steffisburg','Steffisburg','BE'),('CH','SBH','Schupbach','Schupbach','BE'),('CH','SBL','Schonbuhl','Schonbuhl','BE'),('CH','SBO','Stabio','Stabio','TI'),('CH','SCG','Scherzingen','Scherzingen','TG'),('CH','SCH','Schaffhausen','Schaffhausen','SH'),('CH','SCR','Speicher','Speicher','AR'),('CH','SCU','Scuol','Scuol','GR'),('CH','SCX','Sainte Croix','Sainte Croix','VD'),('CH','SCZ','Schwyz','Schwyz','SZ'),('CH','SFA','Stafa','Stafa','ZH'),('CH','SFE','Saas-Fee','Saas-Fee','VS'),('CH','SFN','Schupfen','Schupfen','BE'),('CH','SGE','Sulgen','Sulgen','TG'),('CH','SGI','Schindellegi','Schindellegi','SZ'),('CH','SGN','La Sagne','La Sagne','NE'),('CH','SHB','Schonengrund','Schonengrund','AR'),('CH','SHG','Sihlbrugg Dorf','Sihlbrugg Dorf','ZG'),('CH','SHH','Schachen','Schachen','LU'),('CH','SHR','Schlieren','Schlieren','ZH'),('CH','SIN','Sins','Sins','AG'),('CH','SIR','Sion','Sion','VS'),('CH','SIS','Sisseln','Sisseln','AG'),('CH','SMA','St Maurice','St Maurice','VS'),('CH','SMK','Schmerikon','Schmerikon','SG'),('CH','SMR','Steinmaur','Steinmaur','ZH'),('CH','SMV','St Moritz','St Moritz','GR'),('CH','SMW','Sumiswald','Sumiswald','BE'),('CH','SND','Sennwald','Sennwald','SG'),('CH','SNH','Sirnach','Sirnach','TG'),('CH','SNN','Sarnen','Sarnen','OW'),('CH','SOM','Someo','Someo','TI'),('CH','SOO','Solothurn','Solothurn','SO'),('CH','SPA','Sempach','Sempach','LU'),('CH','SPB','Spreitenbach','Spreitenbach','AG'),('CH','SPF','Schupfheim','Schupfheim','LU'),('CH','SPR','Saint-Prex','Saint-Prex','VD'),('CH','SPY','Le Sepey','Le Sepey','VD'),('CH','SPZ','Spiez','Spiez','BE'),('CH','SRR','Sierre','Sierre','VS'),('CH','SSH','Sissach','Sissach','BL'),('CH','SSS','Sisseln AG','Sisseln AG','BL'),('CH','STB','Steinebrunn','Steinebrunn','TG'),('CH','STE','Steinach','Steinach','SG'),('CH','STG','Steg','Steg','ZH'),('CH','STI','Steinhausen','Steinhausen','ZG'),('CH','STM','St Margrethen','St Margrethen','SG'),('CH','STN','Stein','Stein','AG'),('CH','STO','Stoos','Stoos','SZ'),('CH','STT','Stetten','Stetten','AG'),('CH','STU','Studen','Studen','BE'),('CH','SUN','St-Ursanne','St-Ursanne','JU'),('CH','SUR','Sursee','Sursee','LU'),('CH','SVN','Sevelen','Sevelen','SG'),('CH','SWB','Schwerzenbach','Schwerzenbach','ZH'),('CH','SWD','Schonenwerd','Schonenwerd','SO'),('CH','SWN','Seewen','Seewen','SZ'),('CH','SXN','Saxon','Saxon','VS'),('CH','SZB','Schwarzenburg','Schwarzenburg','BE'),('CH','TAF','Tafers','Tafers','FR'),('CH','TEN','Tenero','Tenero','TI'),('CH','TFN','Teufen','Teufen','SG'),('CH','TGI','Turgi','Turgi','AG'),('CH','THA','Thayngen','Thayngen','SH'),('CH','THI','Thalheim','Thalheim','AG'),('CH','THL','Thal','Thal','SG'),('CH','THS','Thusis','Thusis','GR'),('CH','THU','Thun','Thun','BE'),('CH','TNG','Triengen','Triengen','LU'),('CH','TOF','Toffen','Toffen','BE'),('CH','TRS','Trimmis','Trimmis','GR'),('CH','TRT','Troistorrents','Troistorrents','VS'),('CH','TRX','Trelex','Trelex','VD'),('CH','TSD','Trasadingen','Trasadingen','SH'),('CH','TVR','Taverne','Taverne','TI'),('CH','TVS','Tavannes','Tavannes','BE'),('CH','TWG','Tagelswangen','Tagelswangen','ZH'),('CH','TWL','Thalwil','Thalwil','ZH'),('CH','TWN','Tagerwilen','Tagerwilen','TG'),('CH','UGA','Untersiggenthal','Untersiggenthal','AG'),('CH','UGN','Uesslingen','Uesslingen','TG'),('CH','UKN','Uitikon','Uitikon','ZH'),('CH','UKS','Uetikon am See','Uetikon am See','ZH'),('CH','URD','Urdorf','Urdorf','ZH'),('CH','USR','Uster','Uster','ZH'),('CH','UTR','Unterageri','Unterageri','ZG'),('CH','UZN','Uznach','Uznach','SG'),('CH','UZW','Uzwil','Uzwil','SG'),('CH','VAL','Vallorbe','Vallorbe','VD'),('CH','VEN','Vendlincourt','Vendlincourt','JU'),('CH','VER','Verbier','Verbier','VS'),('CH','VFN','Vauffelin','Vauffelin','BE'),('CH','VHS','Vucherens','Vucherens','VD'),('CH','VIL','Villars-sur-Ollon','Villars-sur-Ollon','VD'),('CH','VIS','Visp','Visp','VS'),('CH','VKI','Volketswil','Volketswil','ZH'),('CH','VLA','Vilars','Vilars','NE'),('CH','VMG','Villmergen','Villmergen','AG'),('CH','VNR','Vernier','Vernier','GE'),('CH','VSC','Villars-Sainte-Croix','Villars-Sainte-Croix','VD'),('CH','VSG','Villars-sur-Glane','Villars-sur-Glane','FR'),('CH','VVY','Vouvry','Vouvry','VS'),('CH','WAL','Waltenschwil','Waltenschwil','AG'),('CH','WAT','Wattwil','Wattwil','SG'),('CH','WDW','Wadenswil','Wadenswil','ZH'),('CH','WFL','Weinfelden','Weinfelden','TG'),('CH','WFW','Wolfwil','Wolfwil','SO'),('CH','WGI','Wangi','Wangi','TG'),('CH','WGN','Wangen','Wangen',''),('CH','WHL','Wohlen','Wohlen','AG'),('CH','WHN','Wolhusen','Wolhusen','LU'),('CH','WIL','Wil','Wil','SG'),('CH','WIN','Winterthur','Winterthur','ZH'),('CH','WLN','Wallisellen','Wallisellen','ZH'),('CH','WLO','Wurenlos','Wurenlos','AG'),('CH','WLU','Wollerau','Wollerau','SZ'),('CH','WMM','Wimmis','Wimmis','BE'),('CH','WNG','Wengen','Wengen','BE'),('CH','WNU','Widnau','Widnau','SG'),('CH','WQL','Wil','Wil','AG'),('CH','WSI','Wettswil','Wettswil','ZH'),('CH','WSU','Willisau','Willisau','LU'),('CH','WTG','Wettingen','Wettingen','AG'),('CH','WZK','Wetzikon','Wetzikon','ZH'),('CH','YFL','Fluh','Fluh','SO'),('CH','YHM','Courtaman','Courtaman','FR'),('CH','YLB','Yverdon-les-Bains','Yverdon-les-Bains','VD'),('CH','ZAZ','Zaziwil','Zaziwil','BE'),('CH','ZDD','Arbon','Arbon','TG'),('CH','ZEL','Zell','Zell','ZH'),('CH','ZER','Zermatt','Zermatt','VS'),('CH','ZHH','Gossau','Gossau','SG'),('CH','ZIM','Zweisimmen','Zweisimmen','BE'),('CH','ZJA','Le Locle','Le Locle',''),('CH','ZJW','Rapperswil','Rapperswil','SG'),('CH','ZKN','Zumikon','Zumikon','ZH'),('CH','ZKZ','Vevey','Vevey','VD'),('CH','ZLK','Zollikofen','Zollikofen','BE'),('CH','ZLL','Zofingen','Zofingen','AG'),('CH','ZLM','Zug','Zug','ZG'),('CH','ZRH','Zurich','Zurich','ZH'),('CH','ZWI','Zetzwil','Zetzwil','AG'),('CH','ZZL','Zell','Zell','LU'),('CI','','','',''),('CI','ABJ','Abidjan','Abidjan',''),('CI','ADZ','Adzope','Adzope',''),('CI','AGB','Agboville','Agboville',''),('CI','ASK','Yamoussoukro','Yamoussoukro',''),('CI','ASS','Assinie','Assinie',''),('CI','BDK','Bondoukou','Bondoukou',''),('CI','BON','Bonoua','Bonoua',''),('CI','BYK','Bouake','Bouake',''),('CI','DAB','Dabou','Dabou',''),('CI','DJO','Daloa','Daloa',''),('CI','FEK','Ferkessedougou','Ferkessedougou',''),('CI','FRE','Fresco','Fresco',''),('CI','GBA','Gbabam','Gbabam',''),('CI','GGN','Gagnoa','Gagnoa',''),('CI','GGO','Guiglo','Guiglo',''),('CI','GLU','Grand Lahou','Grand Lahou',''),('CI','HGO','Korhogo','Korhogo',''),('CI','JAC','Jacqueville','Jacqueville',''),('CI','KEO','Odienne','Odienne',''),('CI','KOS','Kosagi','Kosagi',''),('CI','MJC','Man','Man',''),('CI','NKL','Nakala','Nakala',''),('CI','OGO','Abengourou','Abengourou',''),('CI','PBT','Port-Bouet','Port-Bouet',''),('CI','SGL','Seguela','Seguela',''),('CI','SPY','San-Pedro','San-Pedro',''),('CI','TIA','Tiassale','Tiassale',''),('CI','TXU','Tabou','Tabou',''),('CI','ZSS','Sassandra','Sassandra',''),('CK','','','',''),('CK','AIT','Aitutaki','Aitutaki',''),('CK','AIU','Atiu','Atiu',''),('CK','ARU','Arutunga','Arutunga',''),('CK','AVA','Avarua','Avarua',''),('CK','MGS','Mangaia','Mangaia',''),('CK','MOI','Mitiaro Island','Mitiaro Island',''),('CK','MUK','Mauke Island','Mauke Island',''),('CK','RAR','Rarotonga','Rarotonga',''),('CL','','','',''),('CL','ABB','Alto Bio Bio','Alto Bio Bio','BI'),('CL','ACH','Achao','Achao','LL'),('CL','ADC','Alto del Carmen','Alto del Carmen','AT'),('CL','ALG','Algarrobo','Algarrobo','VS'),('CL','ALH','Alhue','Alhue','RM'),('CL','AND','Andacollo','Andacollo','CO'),('CL','ANF','Antofagasta','Antofagasta','AN'),('CL','ANG','Angol','Angol','AR'),('CL','ANT','Antuco','Antuco','BI'),('CL','ARA','Arauco','Arauco','BI'),('CL','ARI','Arica','Arica','TA'),('CL','AYA','Ayacara','Ayacara','LL'),('CL','BAG','Bahia San Gregorio','Bahia San Gregorio','MA'),('CL','BAR','Barquito','Barquito','AT'),('CL','BBA','Balmaceda','Balmaceda','AI'),('CL','BUI','Buin','Buin','RM'),('CL','BUL','Bulnes','Bulnes','BI'),('CL','CAA','Calderilla','Calderilla','AT'),('CL','CAB','Cabrero','Cabrero','BI'),('CL','CAL','Caleta Patillos','Caleta Patillos','TA'),('CL','CAM','Camarones','Camarones','TA'),('CL','CAN','Canela','Canela','CO'),('CL','CAR','Carahue','Carahue','AR'),('CL','CAS','Casablanca','Casablanca','VS'),('CL','CAT','Catemu','Catemu','VS'),('CL','CAU','Cauquenes','Cauquenes','ML'),('CL','CBB','Combarbala','Combarbala','CO'),('CL','CBC','Calbuco','Calbuco','LL'),('CL','CBD','Cabildo','Cabildo','VS'),('CL','CBG','Chimbarongo','Chimbarongo','LI'),('CL','CBQ','Cobquecura','Cobquecura','BI'),('CL','CCA','Chacao','Chacao','LL'),('CL','CCH','Chile Chico','Chile Chico','AI'),('CL','CCN','Curacautin','Curacautin','AR'),('CL','CCP','Concepcion','Concepcion','BI'),('CL','CDT','Calera de Tango','Calera de Tango','RM'),('CL','CDV','Curaco de Velez','Curaco de Velez','LL'),('CL','CGN','Cartagena','Cartagena','VS'),('CL','CGR','Cruz Grande','Cruz Grande','CO'),('CL','CHA','Chanco','Chanco','ML'),('CL','CHB','Chacabuco','Chacabuco','AI'),('CL','CHE','Chepica','Chepica','LI'),('CL','CHI','Chiguayante','Chiguayante','BI'),('CL','CHL','Cholchol','Cholchol','AR'),('CL','CHO','Chonchi','Chonchi','LL'),('CL','CHR','Cabo de Hornos','Cabo de Hornos','MA'),('CL','CHU','Chuquicamata','Chuquicamata','AN'),('CL','CHV','Chillan Viejo','Chillan Viejo','BI'),('CL','CIS','Puerto Cisnes','Puerto Cisnes','AI'),('CL','CJC','Calama','Calama','AN'),('CL','CLD','Caldera','Caldera','AT'),('CL','CLI','Conchali','Conchali','RM'),('CL','CLL','Calle Larga','Calle Larga','VS'),('CL','CLN','Colina','Colina','RM'),('CL','CLR','Caleta Clarencia','Caleta Clarencia','MA'),('CL','CMA','Camina','Camina','TA'),('CL','CMO','Cochamo','Cochamo','LL'),('CL','CNE','Colchane','Colchane','TA'),('CL','CNL','Coronel','Coronel','BI'),('CL','CNR','Chanaral','Chanaral','AT'),('CL','CNV','Cerro Navia','Cerro Navia','RM'),('CL','CNX','Cabo Negro','Cabo Negro','MA'),('CL','COB','Colbun','Colbun','ML'),('CL','COC','Cochrane','Cochrane','AI'),('CL','COD','Codegua','Codegua','LI'),('CL','COE','Coelemu','Coelemu','BI'),('CL','COI','Coihueco','Coihueco','BI'),('CL','COL','Caleta Coloso','Caleta Coloso','AN'),('CL','CON','Concon','Concon','VS'),('CL','COO','Coinco','Coinco','LI'),('CL','CPI','Collipulli','Collipulli','AR'),('CL','CPO','Copiapo','Copiapo','AT'),('CL','CQQ','Coquimbo','Coquimbo','CO'),('CL','CRE','Curarrehue','Curarrehue','AR'),('CL','CRH','Carahue','Carahue','LL'),('CL','CRN','Curanilahue','Curanilahue','BI'),('CL','CRR','Corral','Corral','LL'),('CL','CRT','Curepto','Curepto','ML'),('CL','CRV','Curacavi','Curacavi','RM'),('CL','CST','Constitucion','Constitucion','ML'),('CL','CTC','Coltauco','Coltauco','LI'),('CL','CTE','Canete','Canete','BI'),('CL','CTM','Contulmo','Contulmo','BI'),('CL','CUN','Cunco','Cunco','AR'),('CL','CUR','Curico','Curico','ML'),('CL','CXQ','Coyhaique','Coyhaique','AI'),('CL','DCH','Dalcahue','Dalcahue','LL'),('CL','DDA','Diego de Almagro','Diego de Almagro','AT'),('CL','DOH','Donihue','Donihue','LI'),('CL','ECT','Estacion Central','Estacion Central','RM'),('CL','EDE','Puerto Eden','Puerto Eden','MA'),('CL','ELB','El Bosque','El Bosque','RM'),('CL','ELC','El Carmen','El Carmen','BI'),('CL','ELM','El Monte','El Monte','RM'),('CL','ELQ','El Quisco','El Quisco','VS'),('CL','ELT','El Tabo','El Tabo','VS'),('CL','EMP','Empedrado','Empedrado','ML'),('CL','ERC','Ercilla','Ercilla','AR'),('CL','ESR','El Salvador','El Salvador','AT'),('CL','FFU','Futaleufu','Futaleufu','LL'),('CL','FLO','Florida','Florida','BI'),('CL','FRE','Freire','Freire','AR'),('CL','FRN','Freirina','Freirina','AT'),('CL','FRS','Fresia','Fresia','LL'),('CL','FRT','Frutillar','Frutillar','LL'),('CL','FUT','Futrono','Futrono','LL'),('CL','GAL','Galvarino','Galvarino','AR'),('CL','GIO','Gatico','Gatico','AN'),('CL','GLG','General Lagos','General Lagos','TA'),('CL','GOR','Gorbea','Gorbea','AR'),('CL','GRA','Graneros','Graneros','LI'),('CL','GUA','Guaitecas','Guaitecas','AI'),('CL','GUR','Isla Guarello','Isla Guarello','MA'),('CL','GYC','Guayacan','Guayacan','CO'),('CL','HIJ','Hijuelas','Hijuelas','VS'),('CL','HLE','Hualane','Hualane','ML'),('CL','HPN','Hualpen','Hualpen','BI'),('CL','HPO','Huachipato','Huachipato','BI'),('CL','HQI','Hualqui','Hualqui','BI'),('CL','HSO','Huasco','Huasco','AT'),('CL','HUA','Huara','Huara','TA'),('CL','HUE','Huechuraba','Huechuraba','RM'),('CL','HUH','Hualaihue','Hualaihue','LL'),('CL','IDM','Isla de Maipo','Isla de Maipo','RM'),('CL','ILL','Illapel','Illapel','CO'),('CL','IND','Independencia','Independencia','RM'),('CL','IPC','Isla de Pascua','Isla de Pascua','VS'),('CL','IQQ','Iquique','Iquique','TA'),('CL','ISG','Isla Guarello','Isla Guarello',''),('CL','JFZ','Juan Fernandez','Juan Fernandez','VS'),('CL','KNA','Vina del Mar','Vina del Mar','VS'),('CL','LAH','La Higuera','La Higuera','CO'),('CL','LAJ','La Laja','La Laja','BI'),('CL','LAL','Los Alamos','Los Alamos','BI'),('CL','LAM','Lampa','Lampa','RM'),('CL','LAN','Lanco','Lanco','LL'),('CL','LAU','Lautaro','Lautaro','AR'),('CL','LBA','Lo Barnechea','Lo Barnechea','RM'),('CL','LBL','Laguna Blanca','Laguna Blanca','MA'),('CL','LCB','Las Cabras','Las Cabras','LI'),('CL','LCI','La Cisterna','La Cisterna','RM'),('CL','LCL','La Calera','La Calera','VS'),('CL','LCO','Las Condes','Las Condes','RM'),('CL','LCZ','La Cruz','La Cruz','VS'),('CL','LEB','Lebu','Lebu','BI'),('CL','LEJ','Lo Espejo','Lo Espejo','RM'),('CL','LES','La Estrella','La Estrella','LI'),('CL','LFL','La Florida','La Florida','RM'),('CL','LGJ','La Granja','La Granja','RM'),('CL','LIA','Llanquihue','Llanquihue','LL'),('CL','LIC','Licanten','Licanten','ML'),('CL','LIG','La Ligua','La Ligua','VS'),('CL','LIM','Limache','Limache','VS'),('CL','LIN','Linares','Linares','ML'),('CL','LIT','Litueche','Litueche','LI'),('CL','LLA','Llaillay','Llaillay','VS'),('CL','LLG','Los Lagos','Los Lagos','LL'),('CL','LLI','Llico','Llico','BI'),('CL','LMU','Los Muermos','Los Muermos','LL'),('CL','LNC','Loncoche','Loncoche','AR'),('CL','LND','Los Andes','Los Andes','VS'),('CL','LOL','Lolol','Lolol','LI'),('CL','LON','Longavi','Longavi','ML'),('CL','LOS','Los Vilos','Los Vilos','CO'),('CL','LPI','La Pintana','La Pintana','RM'),('CL','LPR','Lo Prado','Lo Prado','RM'),('CL','LQN','Lirquen','Lirquen','BI'),('CL','LQY','Lonquimay','Lonquimay','AR'),('CL','LSA','Los Sauces','Los Sauces','AR'),('CL','LSC','La Serena','La Serena','CO'),('CL','LSQ','Los Angeles','Los Angeles','BI'),('CL','LTA','Lota','Lota','BI'),('CL','LUM','Lumaco','Lumaco','AR'),('CL','LUN','La Union','La Union','LL'),('CL','LVD','Lago Verde','Lago Verde','AI'),('CL','LVT','Los Vientos','Los Vientos','AN'),('CL','MAC','Macul','Macul','RM'),('CL','MAE','Maria Elena','Maria Elena','AN'),('CL','MAF','Mafil','Mafil','LL'),('CL','MAI','Maipu','Maipu','RM'),('CL','MAL','Malloa','Malloa','LI'),('CL','MAR','Marchihue','Marchihue','LI'),('CL','MAU','Maule','Maule','ML'),('CL','MCI','Machali','Machali','LI'),('CL','MEL','Melipilla','Melipilla','RM'),('CL','MIC','Michilla','Michilla','AN'),('CL','MJS','Mejillones','Mejillones','AN'),('CL','MLI','Melinka','Melinka','LL'),('CL','MLL','Maullin','Maullin','LL'),('CL','MLP','Melipeuco','Melipeuco','AR'),('CL','MOL','Molina','Molina','ML'),('CL','MOS','San Francisco de Mostazal','San Francisco de Mostazal','LI'),('CL','MPI','Maria Pinto','Maria Pinto','RM'),('CL','MRQ','Mariquina','Mariquina','LL'),('CL','MTP','Monte Patria','Monte Patria','CO'),('CL','MUL','Mulchen','Mulchen','BI'),('CL','NAC','Nacimiento','Nacimiento','BI'),('CL','NAN','Nancahua','Nancahua','LI'),('CL','NAV','Navidad','Navidad','LI'),('CL','NBL','Niebla','Niebla','LL'),('CL','NEG','Negrete','Negrete','BI'),('CL','NIM','Nueva Imperial','Nueva Imperial','AR'),('CL','NIN','Ninhue','Ninhue','BI'),('CL','NOG','Nogales','Nogales','VS'),('CL','NQN','Niquen','Niquen','BI'),('CL','NUN','Nunoa','Nunoa','RM'),('CL','OHI','O\'Higgins','O\'Higgins','AI'),('CL','OLI','Olivar','Olivar','LI'),('CL','OLL','Ollague','Ollague','AN'),('CL','OLM','Olmue','Olmue','VS'),('CL','OVL','Ovalle','Ovalle','CO'),('CL','PAC','Pedro Aguirre Cerda','Pedro Aguirre Cerda','RM'),('CL','PAG','Puerto Angamos','Puerto Angamos','AN'),('CL','PAI','Paiguano','Paiguano','CO'),('CL','PAL','Palena','Palena','LL'),('CL','PAN','Panguipulli','Panguipulli','LL'),('CL','PAO','Paillaco','Paillaco','LL'),('CL','PAP','Papudo','Papudo','VS'),('CL','PAQ','Placilla - Valparaiso','Placilla - Valparaiso','VS'),('CL','PAR','Paredones','Paredones','LI'),('CL','PAT','Puerto Patache','Puerto Patache','TA'),('CL','PCH','Puerto Chacabuco','Puerto Chacabuco','AI'),('CL','PCI','Puchuncavi','Puchuncavi','VS'),('CL','PDH','Pichidegua','Pichidegua','LI'),('CL','PEL','Pelarco','Pelarco','ML'),('CL','PEM','Pemuco','Pemuco','BI'),('CL','PEN','Pencahue','Pencahue','ML'),('CL','PEO','Penco','Penco','BI'),('CL','PER','Peralillo','Peralillo','LI'),('CL','PET','Petorca','Petorca','VS'),('CL','PEU','Peumo','Peumo','LI'),('CL','PFL','Penaflor','Penaflor','RM'),('CL','PGA','Pargua','Pargua','LL'),('CL','PHU','Padre Hurtado','Padre Hurtado','RM'),('CL','PIC','Pica','Pica','TA'),('CL','PIN','Pinto','Pinto','BI'),('CL','PIR','Pirque','Pirque','RM'),('CL','PIS','Pisagua','Pisagua','TA'),('CL','PIT','Pitrufquen','Pitrufquen','AR'),('CL','PLA','Placilla','Placilla','LI'),('CL','PLC','Padre Las Casas','Padre Las Casas','AR'),('CL','PLH','Pelluhue','Pelluhue','ML'),('CL','PLL','Placilla','Placilla','VS'),('CL','PLM','Pichilemu','Pichilemu','LI'),('CL','PLN','Penalolen','Penalolen','RM'),('CL','PMA','Palmilla','Palmilla','LI'),('CL','PMC','Puerto Montt','Puerto Montt','LL'),('CL','PNE','Paine','Paine','RM'),('CL','PNG','Puente Negro','Puente Negro','LI'),('CL','PNT','Puerto Natales','Puerto Natales','MA'),('CL','POC','Puerto Octay','Puerto Octay','LL'),('CL','POR','Portezuelo','Portezuelo','BI'),('CL','POS','Posesion','Posesion','CO'),('CL','POZ','Pozo Almonte','Pozo Almonte','TA'),('CL','PPY','Puerto Percy','Puerto Percy','MA'),('CL','PQC','Perquenco','Perquenco','AR'),('CL','PQD','Puqueldon','Puqueldon','LL'),('CL','PQH','Panquehue','Panquehue','VS'),('CL','PRI','Primavera','Primavera','MA'),('CL','PRL','Parral','Parral','ML'),('CL','PRO','Providencia','Providencia','RM'),('CL','PRQ','Purranque','Purranque','LL'),('CL','PTA','Puente Alto','Puente Alto','RM'),('CL','PTC','Punta Chungo','Punta Chungo','CO'),('CL','PTE','Quellon (Puerto Quellon)','Quellon (Puerto Quellon)','LL'),('CL','PTI','Patillos','Patillos',''),('CL','PTO','Putaendo','Putaendo','VS'),('CL','PUD','Pudahuel','Pudahuel','RM'),('CL','PUM','Pumanque','Pumanque','LI'),('CL','PUN','Punitaqui','Punitaqui','CO'),('CL','PUQ','Punta Arenas','Punta Arenas','MA'),('CL','PUR','Puren','Puren','AR'),('CL','PUT','Putre','Putre','TA'),('CL','PVS','Puerto Varas','Puerto Varas','LL'),('CL','PYH','Puyehue','Puyehue','LL'),('CL','QCO','Quinchao','Quinchao','LL'),('CL','QDT','Quinta de Tilcoco','Quinta de Tilcoco','LI'),('CL','QIL','Quilpue','Quilpue','VS'),('CL','QIN','Quillon','Quillon','BI'),('CL','QLA','Quilaco','Quilaco','BI'),('CL','QLN','Queilen','Queilen','LL'),('CL','QLO','Quilleco','Quilleco','BI'),('CL','QMC','Quemchi','Quemchi','LL'),('CL','QNO','Quinta Normal','Quinta Normal','RM'),('CL','QRC','Rancagua','Rancagua','LI'),('CL','QRH','Quirihue','Quirihue','BI'),('CL','QTA','Quillota','Quillota','VS'),('CL','QTV','Quintero','Quintero','VS'),('CL','QUI','Quilicura','Quilicura','RM'),('CL','QUV','Quellon Viejo','Quellon Viejo','LL'),('CL','RAF','Rauco','Rauco','LL'),('CL','RAN','Ranquil','Ranquil','BI'),('CL','RAU','Rauco','Rauco','ML'),('CL','RBU','Rio Bueno','Rio Bueno','LL'),('CL','RCL','Rio Claro','Rio Claro','ML'),('CL','REC','Recoleta','Recoleta','RM'),('CL','REI','La Reina','La Reina','RM'),('CL','REN','Renca','Renca','RM'),('CL','REQ','Requinoa','Requinoa','LI'),('CL','RET','Retiro','Retiro','ML'),('CL','RGO','Rengo','Rengo','LI'),('CL','RHU','Hurtado','Hurtado','CO'),('CL','RIB','Rio Ibanez','Rio Ibanez','AI'),('CL','RIN','Rinconada de Los Andes','Rinconada de Los Andes','VS'),('CL','RNC','Lago Ranco','Lago Ranco','LL'),('CL','RNE','Rio Negro','Rio Negro','LL'),('CL','RNO','Renaico','Renaico','AR'),('CL','ROM','Romeral','Romeral','ML'),('CL','RSD','Rocas de Santo Domingo','Rocas de Santo Domingo','VS'),('CL','RVE','Rio Verde','Rio Verde','MA'),('CL','SAA','Saavedra','Saavedra','AR'),('CL','SAF','Sagrada Familia','Sagrada Familia','ML'),('CL','SAI','San Antonio','San Antonio','VS'),('CL','SAL','Salamanca','Salamanca','CO'),('CL','SBA','Santa Barbara','Santa Barbara','BI'),('CL','SBD','San Bernardo','San Bernardo','RM'),('CL','SCL','Santiago','Santiago','RM'),('CL','SCR','San Carlos','San Carlos','BI'),('CL','SCT','San Clemente','San Clemente','ML'),('CL','SCZ','Santa Cruz','Santa Cruz','LI'),('CL','SDO','Santo Domingo','Santo Domingo','VS'),('CL','SES','San Esteban','San Esteban','VS'),('CL','SFD','San Fernando','San Fernando','LI'),('CL','SFN','San Fabian','San Fabian','BI'),('CL','SFP','San Felipe','San Felipe','VS'),('CL','SGR','San Gregorio','San Gregorio','MA'),('CL','SIG','Sierra Gorda','Sierra Gorda','AN'),('CL','SIN','San Ignacio','San Ignacio','BI'),('CL','SJC','San Juan de la Costa','San Juan de la Costa','LL'),('CL','SJM','San Jose de Maipo','San Jose de Maipo','RM'),('CL','SJQ','San Joaquin','San Joaquin','RM'),('CL','SJU','Santa Juana','Santa Juana','BI'),('CL','SJV','San Javier','San Javier','ML'),('CL','SMA','Santa Maria','Santa Maria','VS'),('CL','SMG','San Miguel','San Miguel','RM'),('CL','SNI','San Nicolas','San Nicolas','BI'),('CL','SPA','San Pedro de Atacama','San Pedro de Atacama','AN'),('CL','SPB','San Pablo','San Pablo','LL'),('CL','SPE','San Pedro','San Pedro','RM'),('CL','SPP','San Pedro de la Paz','San Pedro de la Paz','BI'),('CL','SRA','San Rafael','San Rafael','ML'),('CL','SRM','San Ramon','San Ramon','RM'),('CL','SRO','San Rosendo','San Rosendo','BI'),('CL','SVE','San Vicente','San Vicente','BI'),('CL','SVT','San Vicente','San Vicente','LI'),('CL','TAL','Talcahuano','Talcahuano','BI'),('CL','TAM','Tierra Amarilla','Tierra Amarilla','AT'),('CL','TDP','Torres del Paine','Torres del Paine','MA'),('CL','TEN','Teno','Teno','ML'),('CL','TEO','Teodoro Schmidt','Teodoro Schmidt','AR'),('CL','TIL','Tiltil','Tiltil','RM'),('CL','TIM','Timaukel','Timaukel','MA'),('CL','TIR','Tirua','Tirua','BI'),('CL','TLG','Talagante','Talagante','RM'),('CL','TLX','Talca','Talca','ML'),('CL','TOL','Tolten','Tolten','AR'),('CL','TOM','Tome','Tome','BI'),('CL','TON','Tongoy','Tongoy','CO'),('CL','TOQ','Tocopilla','Tocopilla','AN'),('CL','TOR','Tortel','Tortel','AI'),('CL','TPT','Tres Puentes','Tres Puentes','MA'),('CL','TRA','Traiguen','Traiguen','AR'),('CL','TRE','Treguaco','Treguaco','BI'),('CL','TTC','Taltal','Taltal','AN'),('CL','TUC','Tucapel','Tucapel','BI'),('CL','ULC','Los Cerrillos Apt/Santiago','Los Cerrillos Apt/Santiago','RM'),('CL','VAG','Villa Alegre','Villa Alegre','ML'),('CL','VAP','Valparaiso','Valparaiso','VS'),('CL','VCN','Vilcun','Vilcun','AR'),('CL','VCQ','Vichuquen','Vichuquen','ML'),('CL','VEN','Ventanas','Ventanas','AT'),('CL','VIA','Villa Alemana','Villa Alemana','VS'),('CL','VIC','Vicuna','Vicuna','CO'),('CL','VIL','Villarrica','Villarrica','AR'),('CL','VIT','Vitacura','Vitacura','RM'),('CL','VLR','Vallenar','Vallenar','AT'),('CL','VNT','Ventanas','Ventanas','VS'),('CL','WCA','Castro','Castro','LL'),('CL','WCH','Chaiten','Chaiten','LL'),('CL','WPA','Puerto Aisen','Puerto Aisen','AI'),('CL','WPU','Puerto Williams','Puerto Williams','MA'),('CL','YAI','Chillan','Chillan','BI'),('CL','YBU','Yerbas Buenas','Yerbas Buenas','ML'),('CL','YUM','Yumbel','Yumbel','BI'),('CL','YUN','Yungay','Yungay','BI'),('CL','ZAL','Valdivia','Valdivia','LL'),('CL','ZAP','Zapallar','Zapallar','VS'),('CL','ZCO','Temuco','Temuco','AR'),('CL','ZIC','Victoria','Victoria','AR'),('CL','ZOS','Osorno','Osorno','LL'),('CL','ZUD','Ancud','Ancud','LL'),('CM','','','',''),('CM','BEL','Belabo','Belabo',''),('CM','BFX','Bafoussam','Bafoussam',''),('CM','BLC','Bali','Bali',''),('CM','BUA','Buea','Buea',''),('CM','CMO','Campo','Campo',''),('CM','DLA','Douala','Douala',''),('CM','DSC','Dschang','Dschang',''),('CM','EBT','Ebome Terminal','Ebome Terminal',''),('CM','EDA','Edea','Edea',''),('CM','GOU','Garoua','Garoua',''),('CM','KBI','Kribi','Kribi',''),('CM','KOB','Koutaba','Koutaba',''),('CM','KOL','Kole Terminal','Kole Terminal',''),('CM','LIM','Limbe','Limbe',''),('CM','LIT','Limboh Terminal','Limboh Terminal',''),('CM','MBA','Mbalmayo','Mbalmayo',''),('CM','MMF','Mamfe','Mamfe',''),('CM','MOU','Moudi Terminal','Moudi Terminal',''),('CM','MVR','Maroua','Maroua',''),('CM','NGE','Ngaoundere','Ngaoundere',''),('CM','NKS','Nkongsamba','Nkongsamba',''),('CM','OUR','Batouri','Batouri',''),('CM','TKC','Tiko','Tiko',''),('CM','VCC','Victoria','Victoria',''),('CM','YAO','Yaounde','Yaounde',''),('CN','','','',''),('CN','AIN','Huaiyin','Huaiyin','32'),('CN','AKL','Alatawshankou','Alatawshankou','65'),('CN','ALI','Dali','Dali','44'),('CN','ANN','Anning','Anning','53'),('CN','ANQ','Anqiu','Anqiu','37'),('CN','ANS','Anshun','Anshun','52'),('CN','AQG','Anqing','Anqing','34'),('CN','ART','Arhaxat','Arhaxat','15'),('CN','ASN','Anshan','Anshan','21'),('CN','BAD','Baoding','Baoding','13'),('CN','BAI','Baicheng','Baicheng','22'),('CN','BAO','Baoshanmatou','Baoshanmatou','31'),('CN','BAS','Basuo','Basuo','46'),('CN','BAV','Baotou','Baotou','15'),('CN','BAY','Bayuquan','Bayuquan','21'),('CN','BCA','Binchuan','Binchuan','53'),('CN','BEI','Beilun','Beilun','33'),('CN','BEN','Benxi','Benxi','21'),('CN','BFU','Bengbu','Bengbu','34'),('CN','BGG','Bagong','Bagong','52'),('CN','BHY','Beihai','Beihai','45'),('CN','BIN','Binzhou','Binzhou','37'),('CN','BJO','Beijiao','Beijiao','35'),('CN','BJS','Beijing','Beijing','11'),('CN','BJX','Baoji','Baoji','61'),('CN','BLU','Beiliu','Beiliu','14'),('CN','BON','Bao\'an','Bao\'an','44'),('CN','BOO','Boluo','Boluo','44'),('CN','BUJ','Buji','Buji','44'),('CN','BUR','Burang','Burang','54'),('CN','CAN','Guangzhou','Guangzhou','44'),('CN','CAW','Chaiwan','Chaiwan','32'),('CN','CDE','Changde','Changde','43'),('CN','CDO','Changdao','Changdao','37'),('CN','CGB','Changbai','Changbai','22'),('CN','CGO','Zhengzhou','Zhengzhou','41'),('CN','CGP','Ch\'ang-peng','Ch\'ang-peng','31'),('CN','CGQ','Changchun','Changchun','22'),('CN','CGS','Chenghai Laiwu','Chenghai Laiwu','37'),('CN','CGU','Changshu','Changshu','32'),('CN','CHA','Changle','Changle','35'),('CN','CHE','Chengao','Chengao','35'),('CN','CHG','Chenghai','Chenghai','44'),('CN','CHN','Chang\'an','Chang\'an','61'),('CN','CHO','Chang on','Chang on','44'),('CN','CHU','Chaohu','Chaohu','34'),('CN','CHX','Chengxi','Chengxi',''),('CN','CHZ','Chuzhou','Chuzhou','34'),('CN','CIX','Cixi','Cixi','33'),('CN','CJG','Caojing','Caojing','31'),('CN','CKA','Chikan','Chikan','44'),('CN','CKG','Chongqing','Chongqing','51'),('CN','CLJ','Chenglingji','Chenglingji','43'),('CN','CMG','Chongming','Chongming',''),('CN','CNA','Changsha','Changsha','44'),('CN','CNG','Chengde','Chengde','13'),('CN','CNH','Conghua','Conghua','44'),('CN','COZ','Chaozhou','Chaozhou','44'),('CN','CPG','Changping','Changping','44'),('CN','CSH','Chashan','Chashan','44'),('CN','CSX','Changsha','Changsha','43'),('CN','CTU','Chengdu','Chengdu','51'),('CN','CUN','Chencun','Chencun','44'),('CN','CUZ','Chuzhuangsi','Chuzhuangsi','34'),('CN','CWN','Chiwan','Chiwan','44'),('CN','CYG','Chaoyang','Chaoyang',''),('CN','CZU','Cangzhou','Cangzhou','13'),('CN','CZX','Changzhou','Changzhou','32'),('CN','DAA','Dagang','Dagang','32'),('CN','DAI','Dai Ming','Dai Ming',''),('CN','DAL','Dali','Dali','61'),('CN','DAN','Daan','Daan','22'),('CN','DAT','Datong','Datong','14'),('CN','DAX','Daxian','Daxian','51'),('CN','DAY','Daya Wan','Daya Wan','44'),('CN','DAZ','Daze','Daze','44'),('CN','DDG','Dandong','Dandong','21'),('CN','DEF','Defeng','Defeng','52'),('CN','DEQ','Deqing','Deqing','44'),('CN','DEY','Deyang','Deyang','51'),('CN','DEZ','Dezhou','Dezhou','37'),('CN','DFG','Dongfeng','Dongfeng','22'),('CN','DGG','Dongguan','Dongguan','44'),('CN','DGN','Dongyuan','Dongyuan','11'),('CN','DGY','Dongying','Dongying','37'),('CN','DHA','Dehua','Dehua','52'),('CN','DHU','Danzhou','Danzhou','45'),('CN','DJG','Dongjiang','Dongjiang','45'),('CN','DJO','Daojiao','Daojiao','44'),('CN','DJT','Dongjiaotou','Dongjiaotou','44'),('CN','DKG','Dongkeng','Dongkeng','36'),('CN','DLC','Dalian','Dalian','21'),('CN','DLG','Dalang','Dalang','44'),('CN','DLN','Dalingshan','Dalingshan','44'),('CN','DNB','Dianbai','Dianbai',''),('CN','DNG','Donghai','Donghai','44'),('CN','DNS','Danshui','Danshui','44'),('CN','DNZ','Danzao','Danzao','44'),('CN','DOG','Donggang','Donggang','21'),('CN','DON','Dongning','Dongning','23'),('CN','DOU','Doumen','Doumen','44'),('CN','DOX','Dongxing','Dongxing','45'),('CN','DPG','Dapeng','Dapeng','44'),('CN','DQG','Daqing','Daqing','23'),('CN','DSN','Dongshan','Dongshan','35'),('CN','DTG','Datian','Datian','35'),('CN','ENP','Enping','Enping','44'),('CN','EZH','Ezhou','Ezhou','42'),('CN','FAN','Fangcheng','Fangcheng','45'),('CN','FEN','Fenggang','Fenggang','44'),('CN','FGG','Fengguang','Fengguang','22'),('CN','FGN','Fangcun','Fangcun',''),('CN','FLG','Fuling','Fuling','50'),('CN','FNG','Fuyong','Fuyong','44'),('CN','FOC','Fuzhou','Fuzhou','35'),('CN','FOS','Foshan','Foshan','44'),('CN','FSN','Fushun','Fushun','21'),('CN','FUG','Fuqing','Fuqing',''),('CN','FUJ','Fujin','Fujin','23'),('CN','FUT','Futian','Futian','44'),('CN','FUX','Fuxin','Fuxin','21'),('CN','FUY','Fuyuan','Fuyuan','23'),('CN','FYG','Fuyong','Fuyong','53'),('CN','GAL','Galolan','Galolan','36'),('CN','GAO','Gaogang','Gaogang','32'),('CN','GAS','Gaosha','Gaosha','44'),('CN','GAY','Gaoyao','Gaoyao','44'),('CN','GBP','Gongbei','Gongbei','44'),('CN','GBU','Gaobu','Gaobu','44'),('CN','GCE','Guicheng','Guicheng','45'),('CN','GCH','Guancheng','Guancheng','33'),('CN','GGY','Gongyi','Gongyi','44'),('CN','GHI','Guanghai','Guanghai','44'),('CN','GIR','Gyirong','Gyirong','54'),('CN','GJG','Gujing','Gujing','44'),('CN','GLN','Gaolan','Gaolan','62'),('CN','GNA','Guang\'ao','Guang\'ao','44'),('CN','GNL','Guanlin','Guanlin','41'),('CN','GNY','Guan yao','Guan yao','44'),('CN','GOG','Gongming','Gongming','44'),('CN','GOM','Gaoming','Gaoming','44'),('CN','GQD','Ganqmod','Ganqmod','15'),('CN','GSA','Cangshan','Cangshan','37'),('CN','GTE','Yingde','Yingde','44'),('CN','GTG','Gaotang','Gaotang','37'),('CN','GUA','Guangdong','Guangdong','44'),('CN','GUG','Guigang','Guigang','45'),('CN','GUN','Guanlan','Guanlan','44'),('CN','GZE','Guzhen','Guzhen','44'),('CN','GZH','Guzhen','Guzhen','34'),('CN','GZU','Guizhou','Guizhou','44'),('CN','HAF','Haifeng','Haifeng',''),('CN','HAG','Haicheng','Haicheng','21'),('CN','HAI','Haian','Haian',''),('CN','HAK','Haikou','Haikou','46'),('CN','HAN','Hanjiang','Hanjiang','35'),('CN','HBI','Huaibei','Huaibei','34'),('CN','HCG','Hecheng','Hecheng','44'),('CN','HCN','Huachuan','Huachuan','23'),('CN','HDU','Huadu','Huadu','44'),('CN','HDX','Handan','Handan','13'),('CN','HEB','Hebei','Hebei','13'),('CN','HEK','Heihe','Heihe','23'),('CN','HET','Hohhot','Hohhot','15'),('CN','HEY','Heyuan','Heyuan','44'),('CN','HFE','Hefei','Hefei','34'),('CN','HGE','Huangge','Huangge','44'),('CN','HGH','Hangzhou','Hangzhou','33'),('CN','HGJ','Huangjiang','Huangjiang','45'),('CN','HGQ','Huangqi','Huangqi','35'),('CN','HHA','Huanghua','Huanghua','13'),('CN','HHU','Heshun','Heshun','44'),('CN','HIN','Haining','Haining','33'),('CN','HKM','Hekou','Hekou','53'),('CN','HKN','Haikang','Haikang',''),('CN','HLD','Hailar','Hailar','15'),('CN','HLI','Huilai','Huilai','13'),('CN','HME','Haimen','Haimen','33'),('CN','HMN','Humen','Humen','44'),('CN','HNG','Henggang','Henggang','44'),('CN','HNI','Hengli','Hengli','44'),('CN','HNK','Hankou','Hankou',''),('CN','HNY','Hengyang','Hengyang','43'),('CN','HOP','Huangpu Old Port','Huangpu Old Port','44'),('CN','HOU','Houjie','Houjie','44'),('CN','HRB','Harbin','Harbin','23'),('CN','HRS','Horgos','Horgos','65'),('CN','HSC','Shaoguan','Shaoguan','44'),('CN','HSH','Huangshan','Huangshan','34'),('CN','HSI','Huangshi','Huangshi','42'),('CN','HSN','Heshan','Heshan','44'),('CN','HST','Heishantou','Heishantou','15'),('CN','HSZ','Hongshanzui','Hongshanzui','65'),('CN','HUA','Huangpu','Huangpu','44'),('CN','HUC','Hunchun','Hunchun','22'),('CN','HUD','Hua Du','Hua Du','44'),('CN','HUG','Huanggang','Huanggang','44'),('CN','HUI','Huizhou','Huizhou','44'),('CN','HUL','Hulin','Hulin','23'),('CN','HUM','Huma','Huma','23'),('CN','HUN','Huangpu New Port','Huangpu New Port','44'),('CN','HUW','Huidong','Huidong','51'),('CN','HYN','Huangyan','Huangyan','33'),('CN','HZH','Huzhou','Huzhou','33'),('CN','HZU','Houzhu','Houzhu','35'),('CN','JAN','Ji\'an','Ji\'an','36'),('CN','JAY','Jiayin','Jiayin','23'),('CN','JDZ','Jingdezhen','Jingdezhen','36'),('CN','JEM','Jeminay','Jeminay','65'),('CN','JGU','Jinguzhou','Jinguzhou','44'),('CN','JGY','Jiangyin','Jiangyin','35'),('CN','JGZ','Jingzhou','Jingzhou','42'),('CN','JHA','Jinhua','Jinhua','33'),('CN','JHG','Jinghong','Jinghong','53'),('CN','JIA','Jiangyin','Jiangyin','32'),('CN','JIG','Jiading','Jiading','31'),('CN','JIH','Jing\'an','Jing\'an','36'),('CN','JII','Jining','Jining','43'),('CN','JIL','Jilin','Jilin','22'),('CN','JIN','Jingtang (Tangshan)','Jingtang (Tangshan)','13'),('CN','JIS','Jiangshan','Jiangshan','45'),('CN','JIU','Jiujiang','Jiujiang','36'),('CN','JIX','Jiaxing','Jiaxing','33'),('CN','JIZ','Jiazi','Jiazi','44'),('CN','JJG','Jiujiang','Jiujiang','44'),('CN','JJN','Jinjiang','Jinjiang','35'),('CN','JKU','Jiangkou','Jiangkou','35'),('CN','JMN','Jiangmen','Jiangmen','44'),('CN','JMO','Jimo','Jimo','37'),('CN','JMU','Jiamusi','Jiamusi','23'),('CN','JND','Jiangdu','Jiangdu','32'),('CN','JNG','Jining','Jining','37'),('CN','JNI','Jinjing','Jinjing','35'),('CN','JNZ','Jinzhou','Jinzhou','21'),('CN','JQI','Jinqiao','Jinqiao','31'),('CN','JSA','Jiashan','Jiashan','22'),('CN','JSH','Jinshuihe','Jinshuihe','53'),('CN','JXI','Jiexi','Jiexi',''),('CN','JXN','Jiao Xin','Jiao Xin','44'),('CN','JYG','Jieyang','Jieyang',''),('CN','JZH','Jiaozhou','Jiaozhou','37'),('CN','JZO','Jiaozuo','Jiaozuo','41'),('CN','JZU','Jiuzhou','Jiuzhou','44'),('CN','KAI','Kaikou','Kaikou',''),('CN','KAP','Kaiping','Kaiping','44'),('CN','KFG','Kaifeng','Kaifeng','41'),('CN','KHG','Kashi','Kashi','65'),('CN','KHN','Nanchang','Nanchang','36'),('CN','KJP','Kunjirap','Kunjirap','65'),('CN','KMG','Kunming','Kunming','53'),('CN','KNC','Ji\'an','Ji\'an','22'),('CN','KPN','Kaiping','Kaiping','13'),('CN','KQI','Kangqiao','Kangqiao','61'),('CN','KRY','Karamay','Karamay','65'),('CN','KST','Kaishantun','Kaishantun','22'),('CN','KUS','Kunshan','Kunshan','32'),('CN','KWE','Guiyang','Guiyang','52'),('CN','KWL','Guilin','Guilin','45'),('CN','KYG','Kuiyong','Kuiyong','44'),('CN','LAI','Laizhou','Laizhou','37'),('CN','LAN','Lanshi','Lanshi','44'),('CN','LBU','Liaobu','Liaobu','44'),('CN','LCN','Luocun','Luocun','44'),('CN','LES','Leshan','Leshan','51'),('CN','LEZ','Lezhu','Lezhu','44'),('CN','LFG','Langfang','Langfang','13'),('CN','LFN','Lufeng','Lufeng','44'),('CN','LGG','Longgang','Longgang','44'),('CN','LGH','Longhua','Longhua','44'),('CN','LGI','Longhai','Longhai','43'),('CN','LGN','Lingcheng','Lingcheng','45'),('CN','LGU','Longguan','Longguan','13'),('CN','LHA','Longhua','Longhua','50'),('CN','LHG','Liancheng','Liancheng','44'),('CN','LHU','Lihu','Lihu','44'),('CN','LHW','Lanzhou','Lanzhou','62'),('CN','LIA','Liaoyang','Liaoyang','21'),('CN','LIH','Lianhuashan','Lianhuashan','44'),('CN','LIN','Linjiang','Linjiang','22'),('CN','LIS','Lishui','Lishui','33'),('CN','LKU','Longkou','Longkou','37'),('CN','LLI','Liling','Liling','43'),('CN','LLJ','Longjiang','Longjiang','44'),('CN','LNH','Linhai','Linhai','33'),('CN','LNJ','Lianjiang','Lianjiang','36'),('CN','LPI','Leping','Leping','44'),('CN','LSH','Lushun','Lushun','21'),('CN','LSI','Lanshi','Lanshi','43'),('CN','LSN','Lanshan','Lanshan','37'),('CN','LUB','Luobei','Luobei','23'),('CN','LUD','Liudu','Liudu','44'),('CN','LUH','Lu-hua Shan','Lu-hua Shan','33'),('CN','LUI','Lisui','Lisui','11'),('CN','LUN','Lu\'an','Lu\'an','34'),('CN','LUU','Leliu','Leliu','44'),('CN','LWU','Laiwu','Laiwu','37'),('CN','LXA','Lhasa','Lhasa','54'),('CN','LXI','Lanxi','Lanxi',''),('CN','LYA','Luoyang','Luoyang','41'),('CN','LYG','Lianyungang','Lianyungang','32'),('CN','LYI','Linyi','Linyi','37'),('CN','LYM','Laoyemiao','Laoyemiao','65'),('CN','LZH','Liuzhou','Liuzhou','45'),('CN','LZU','Luzhou','Luzhou','51'),('CN','MAA','Maanshan','Maanshan','34'),('CN','MAJ','Majistan/Zhoushan','Majistan/Zhoushan','33'),('CN','MAW','Mawei','Mawei','35'),('CN','MCH','Machong','Machong','44'),('CN','MDU','Midu','Midu','53'),('CN','MEI','Meilin','Meilin','35'),('CN','MEZ','Meizhou','Meizhou','44'),('CN','MFG','Mafang','Mafang','44'),('CN','MHN','Mohan','Mohan','53'),('CN','MIA','Miaotou','Miaotou','44'),('CN','MIS','Mishan','Mishan','23'),('CN','MJS','Maji Shan','Maji Shan','33'),('CN','MLX','Manzhouli','Manzhouli','15'),('CN','MMI','Maoming','Maoming','44'),('CN','MOH','Mohe','Mohe','23'),('CN','MSW','Miaoshanwei','Miaoshanwei','32'),('CN','MWN','Mawan','Mawan','44'),('CN','MYG','Mianyang','Mianyang','51'),('CN','MYO','Mayong','Mayong','44'),('CN','MZS','Mazong Shan','Mazong Shan','62'),('CN','NAH','Nanhai','Nanhai','44'),('CN','NAN','Nanao','Nanao','44'),('CN','NAP','Nanping','Nanping','22'),('CN','NAT','Natong','Natong','45'),('CN','NBA','Nanbian','Nanbian','44'),('CN','NDG','Qiqihar','Qiqihar','23'),('CN','NEG','Neigang','Neigang','44'),('CN','NGB','Ningbo','Ningbo','33'),('CN','NGG','Nangang','Nangang','44'),('CN','NIA','Ning\'an','Ning\'an','23'),('CN','NIN','Ninghai','Ninghai','33'),('CN','NJG','Nanjing','Nanjing','35'),('CN','NKG','Nanjing','Nanjing','32'),('CN','NLG','Nanling','Nanling','34'),('CN','NNG','Nanning','Nanning','45'),('CN','NNY','Nanyang','Nanyang','41'),('CN','NSA','Nansha','Nansha','44'),('CN','NTG','Nantong','Nantong','32'),('CN','NTU','Nantou','Nantou','44'),('CN','NWI','Nanwei','Nanwei','44'),('CN','NZA','Nanzhuang','Nanzhuang','41'),('CN','NZU','Nanzhuang','Nanzhuang','13'),('CN','PDG','Pudong/Shanghai','Pudong/Shanghai','31'),('CN','PGU','Pingzhou','Pingzhou','44'),('CN','PGW','Ping wu','Ping wu',''),('CN','PHU','Pinghu','Pinghu','44'),('CN','PIG','Pingxiang','Pingxiang','36'),('CN','PII','Pinghai','Pinghai','44'),('CN','PIN','Pingxiang','Pingxiang','45'),('CN','PLA','Penglai','Penglai','37'),('CN','PND','Pingdi','Pingdi','52'),('CN','PNG','Puning','Puning',''),('CN','PNH','Pinghu','Pinghu','52'),('CN','PNS','Pingshan','Pingshan','44'),('CN','PNU','Pinghu','Pinghu','33'),('CN','PNY','Shiqiao (Panyu)','Shiqiao (Panyu)','44'),('CN','POJ','Poji','Poji','44'),('CN','PUT','Putian','Putian','35'),('CN','PVG','Shanghai Pu Dong Apt','Shanghai Pu Dong Apt','31'),('CN','QAW','Qianwan','Qianwan','37'),('CN','QIA','Qianxi','Qianxi','13'),('CN','QIN','Qingxi','Qingxi','44'),('CN','QLN','Qinglan','Qinglan','46'),('CN','QSA','Qisha','Qisha','45'),('CN','QSE','Qingshuihe, Shenzhen','Qingshuihe, Shenzhen','44'),('CN','QSN','Qianshan, Zhuhai','Qianshan, Zhuhai','44'),('CN','QTU','Qiaotou','Qiaotou','63'),('CN','QUZ','Quzhou','Quzhou','33'),('CN','QXI','Quxi','Quxi','44'),('CN','QYG','Quanyang','Quanyang','22'),('CN','QYN','Qingyuan','Qingyuan','44'),('CN','QZH','Qinzhou','Qinzhou','45'),('CN','QZJ','Quanzhou','Quanzhou','35'),('CN','RIW','Riwo','Riwo','54'),('CN','RLC','Erenhot','Erenhot','15'),('CN','RNG','Rongcheng','Rongcheng','13'),('CN','RNH','Renhe','Renhe','50'),('CN','ROH','Raohe','Raohe','23'),('CN','ROQ','Rongqi','Rongqi','44'),('CN','RPG','Raoping','Raoping','44'),('CN','RUI','Ruili','Ruili','53'),('CN','RZH','Rizhao','Rizhao','37'),('CN','SAE','Shahe','Shahe','11'),('CN','SAG','Songgang','Songgang','44'),('CN','SAH','Sanhe','Sanhe','22'),('CN','SAU','Sanbu','Sanbu','62'),('CN','SBM','San beiman','San beiman',''),('CN','SBU','Sanbu','Sanbu','44'),('CN','SDG','Shuidong','Shuidong','44'),('CN','SDU','Shadui','Shadui','44'),('CN','SFE','Suifenhe','Suifenhe','23'),('CN','SGG','Suijiang','Suijiang','53'),('CN','SHA','Shanghai','Shanghai','31'),('CN','SHD','Shidao','Shidao','37'),('CN','SHE','Shenyang','Shenyang','21'),('CN','SHG','Sanshan','Sanshan','44'),('CN','SHH','Shanhaiguan','Shanhaiguan',''),('CN','SHI','Shishi','Shishi','35'),('CN','SHJ','Shajing','Shajing','44'),('CN','SHK','Shekou','Shekou','44'),('CN','SHL','Shilong','Shilong','44'),('CN','SHN','Shiwan','Shiwan','43'),('CN','SHO','Shajiao','Shajiao','44'),('CN','SHP','Qinhuangdao','Qinhuangdao','13'),('CN','SHQ','Shangqiu','Shangqiu','41'),('CN','SHS','Shashi','Shashi','42'),('CN','SHT','Shating','Shating','44'),('CN','SHU','Shihu','Shihu','35'),('CN','SHW','Honghai','Honghai','46'),('CN','SHX','Shaxi','Shaxi','32'),('CN','SHZ','Shizilu','Shizilu','37'),('CN','SIA','Xi An','Xi An','61'),('CN','SIH','Sihui','Sihui','44'),('CN','SIN','Shatian','Shatian','44'),('CN','SJE','Shijie','Shijie','44'),('CN','SJQ','Sanshui','Sanshui','44'),('CN','SJW','Shijiazhuang','Shijiazhuang','13'),('CN','SKO','Shuikou','Shuikou','45'),('CN','SLO','Shilou','Shilou','44'),('CN','SNG','Songjiang','Songjiang',''),('CN','SNI','Shanshi','Shanshi','23'),('CN','SNL','Sanyuanli/Guangzhou','Sanyuanli/Guangzhou','44'),('CN','SNS','Sheung Shui','Sheung Shui','91'),('CN','SNU','Sanshu','Sanshu','32'),('CN','SNW','Shenwan','Shenwan','44'),('CN','SON','Songxia','Songxia','35'),('CN','SPI','Shipai','Shipai','34'),('CN','SQU','Shiqiao','Shiqiao','45'),('CN','SRG','Sanrong','Sanrong','44'),('CN','SSH','Sanshan (Nanhai)','Sanshan (Nanhai)',''),('CN','SSI','Shanshui','Shanshui','14'),('CN','STB','Shitoubu','Shitoubu','45'),('CN','STJ','Shatoujiao','Shatoujiao','44'),('CN','STO','Shatou','Shatou','44'),('CN','SUB','Shuibu','Shuibu','44'),('CN','SUD','Shunde','Shunde','44'),('CN','SUI','Suigang Huangpu','Suigang Huangpu',''),('CN','SUW','Sunwu','Sunwu','23'),('CN','SWA','Shantou','Shantou','44'),('CN','SWE','Shanwei','Shanwei','44'),('CN','SWI','Shiwei','Shiwei','15'),('CN','SWN','Shawan','Shawan','44'),('CN','SXG','Shaoxing Xian','Shaoxing Xian','33'),('CN','SXJ','Shanshan','Shanshan','65'),('CN','SYA','Sheyang','Sheyang','32'),('CN','SYM','Simao','Simao','53'),('CN','SYN','Shiyan','Shiyan','44'),('CN','SYX','Sanya','Sanya','46'),('CN','SZH','Suzhou','Suzhou','32'),('CN','SZU','Sanzhou','Sanzhou','44'),('CN','SZX','Shenzhen','Shenzhen','44'),('CN','TAG','Taicang','Taicang','32'),('CN','TAI','Tai\'an','Tai\'an','37'),('CN','TAO','Qingdao','Qingdao','37'),('CN','TAP','Taiping','Taiping','44'),('CN','TAS','Tangshan','Tangshan','13'),('CN','TAX','Taixing','Taixing','32'),('CN','TAY','Taiyang','Taiyang','33'),('CN','TBO','Tianbao','Tianbao','53'),('CN','TGH','Tonghua','Tonghua','22'),('CN','TGL','Tongliao','Tongliao','15'),('CN','TGU','Tanggu','Tanggu','12'),('CN','THE','Taihe','Taihe','34'),('CN','THG','Taicheng (Taishan)','Taicheng (Taishan)','44'),('CN','TJG','Taijiang','Taijiang','35'),('CN','TKK','Taykexkin','Taykexkin','65'),('CN','TLI','Tieli','Tieli','23'),('CN','TME','Tumen','Tumen','22'),('CN','TNA','Jinan','Jinan','37'),('CN','TNG','Tongjia','Tongjia','36'),('CN','TOJ','Tongjiang','Tongjiang','23'),('CN','TOL','Tongling','Tongling','34'),('CN','TON','Tonglu','Tonglu','33'),('CN','TRT','Turugart','Turugart','65'),('CN','TSH','Taishan','Taishan',''),('CN','TSI','Jingjiang','Jingjiang','32'),('CN','TSN','Tianjin','Tianjin','12'),('CN','TXA','Tangxia','Tangxia','44'),('CN','TXG','Tianjinxingang','Tianjinxingang','12'),('CN','TXJ','Tongxiang (Wutong)','Tongxiang (Wutong)','33'),('CN','TYN','Taiyuan','Taiyuan','14'),('CN','TZO','Taizhou','Taizhou','32'),('CN','ULT','Ulastai','Ulastai','65'),('CN','URC','Urumqi','Urumqi','65'),('CN','UYN','Yulin','Yulin','46'),('CN','WAF','Wafangdian','Wafangdian','21'),('CN','WAI','Waihai','Waihai','44'),('CN','WAN','Wanding','Wanding','53'),('CN','WAZ','Wanzai','Wanzai','44'),('CN','WEI','Weihai','Weihai','37'),('CN','WEN','Wenlin','Wenlin','33'),('CN','WFG','Weifang','Weifang','37'),('CN','WGI','Wangqi','Wangqi','22'),('CN','WGQ','Waigaoqiao','Waigaoqiao',''),('CN','WHI','Wuhu','Wuhu','34'),('CN','WHU','Wuchuan','Wuchuan','44'),('CN','WJD','Wenjindu','Wenjindu','44'),('CN','WJN','Wujin','Wujin','42'),('CN','WNG','Wanning','Wanning','46'),('CN','WNZ','Wenzhou','Wenzhou','33'),('CN','WSH','Wenshan','Wenshan','53'),('CN','WTU','Weitou','Weitou','35'),('CN','WUC','Wu Chong Kou','Wu Chong Kou','44'),('CN','WUH','Wuhan','Wuhan','42'),('CN','WUJ','Wujiang','Wujiang','32'),('CN','WUS','Wusong','Wusong','31'),('CN','WUX','Wuxi','Wuxi','32'),('CN','WUZ','Wuzhou','Wuzhou','45'),('CN','WYS','Wuyishan','Wuyishan','35'),('CN','XAB','Xinfeng','Xinfeng','44'),('CN','XAN','Xinan','Xinan','44'),('CN','XFN','Xiangfan','Xiangfan','42'),('CN','XGD','Xingdong','Xingdong','23'),('CN','XGG','Xingang','Xingang','12'),('CN','XGN','Xiaogan','Xiaogan','42'),('CN','XGT','Xingtan','Xingtan','44'),('CN','XGZ','Xiangzhou','Xiangzhou',''),('CN','XHA','Xiashan','Xiashan','44'),('CN','XHO','Xiaohudao','Xiaohudao','44'),('CN','XIL','Xiaolan','Xiaolan','44'),('CN','XIN','Xinhui','Xinhui','44'),('CN','XIQ','Xiqiao','Xiqiao','44'),('CN','XIS','Xiaoshan','Xiaoshan','33'),('CN','XIT','Xintang','Xintang','44'),('CN','XIU','Xiuyu','Xiuyu','35'),('CN','XIX','Xi xiang','Xi xiang',''),('CN','XLU','Xiluzhen','Xiluzhen','44'),('CN','XMN','Xiamen','Xiamen','35'),('CN','XNA','Xinsha','Xinsha','44'),('CN','XNG','Xinjiang','Xinjiang','44'),('CN','XNJ','Xinji','Xinji','13'),('CN','XNN','Xining','Xining','63'),('CN','XNU','Xiniu','Xiniu','44'),('CN','XNY','Xinyuan','Xinyuan','91'),('CN','XOT','Xiaotang','Xiaotang','44'),('CN','XSA','Guangzhou','Guangzhou','43'),('CN','XSH','Xinshi','Xinshi','42'),('CN','XSN','Xiangshan','Xiangshan','33'),('CN','XTA','Xiangtan','Xiangtan','43'),('CN','XTG','Xiaotang','Xiaotang','21'),('CN','XTN','Xiantan','Xiantan','51'),('CN','XUA','Xia Hua','Xia Hua','44'),('CN','XUK','Xunke','Xunke','23'),('CN','XUZ','Xuzhou','Xuzhou','32'),('CN','XXG','Xingxiang','Xingxiang','41'),('CN','XXN','Xixiang','Xixiang','61'),('CN','XYG','Xiuying','Xiuying','46'),('CN','XYU','Xianyou','Xianyou','35'),('CN','XZO','Xinzao','Xinzao','44'),('CN','YAN','Yangshan','Yangshan','33'),('CN','YBU','Yanbu','Yanbu','44'),('CN','YCG','Yancheng','Yancheng','32'),('CN','YCN','Yangchun','Yangchun','44'),('CN','YDZ','Yadong','Yadong','54'),('CN','YGG','Yangjiang','Yangjiang','36'),('CN','YGJ','Yongji','Yongji','14'),('CN','YHU','Yishui','Yishui','37'),('CN','YIC','Yichang','Yichang','13'),('CN','YIH','Yinchuan','Yinchuan','64'),('CN','YIK','Yingkou','Yingkou','21'),('CN','YIN','Yining','Yining','65'),('CN','YIW','Yiwu','Yiwu','33'),('CN','YIX','Yixing','Yixing','32'),('CN','YIZ','Yizheng','Yizheng','32'),('CN','YJI','Yangjiang','Yangjiang','44'),('CN','YLG','Yanliang','Yanliang','61'),('CN','YNF','Yunfu','Yunfu',''),('CN','YNJ','Yanji','Yanji','22'),('CN','YNT','Yantai','Yantai','37'),('CN','YON','Yongtai','Yongtai','44'),('CN','YOU','Yuyao','Yuyao','33'),('CN','YPG','Yangpu','Yangpu','46'),('CN','YQS','Beijiao','Beijiao','44'),('CN','YTN','Yantian','Yantian','44'),('CN','YUE','Yueqing','Yueqing','33'),('CN','YUL','Yulin','Yulin','45'),('CN','YUN','Yuncheng','Yuncheng','14'),('CN','YUY','Yueyang','Yueyang','43'),('CN','YUZ','Yuzhou','Yuzhou','51'),('CN','YYG','Youyiguan','Youyiguan','45'),('CN','YZG','Yangzhong','Yangzhong','32'),('CN','YZH','Yangzhou','Yangzhou','32'),('CN','YZO','Yongzhou','Yongzhou','43'),('CN','YZU','Yuzhu','Yuzhu','44'),('CN','ZAP','Zhapu','Zhapu','33'),('CN','ZCH','Zhucheng','Zhucheng','37'),('CN','ZDO','Zhaodong','Zhaodong','23'),('CN','ZEQ','Zhuengadabuqi','Zhuengadabuqi','15'),('CN','ZGA','Zhongshan','Zhongshan','45'),('CN','ZGG','Zigong','Zigong','51'),('CN','ZGH','Zhangcha','Zhangcha','14'),('CN','ZGS','Zhangshan','Zhangshan','32'),('CN','ZGU','Zhangmutou','Zhangmutou','44'),('CN','ZHA','Zhanjiang','Zhanjiang','44'),('CN','ZHC','Zhongcun','Zhongcun','61'),('CN','ZHE','Zhenjiang','Zhenjiang','32'),('CN','ZHG','Zhaogang','Zhaogang','34'),('CN','ZHH','Zhenhai','Zhenhai','33'),('CN','ZHI','Zhijiang','Zhijiang','43'),('CN','ZHU','Zhumadian','Zhumadian','41'),('CN','ZHZ','Zhuozhou','Zhuozhou','13'),('CN','ZIB','Zibo','Zibo','37'),('CN','ZJA','Zhangjiakou','Zhangjiakou','13'),('CN','ZJB','Zhangjiabian','Zhangjiabian','44'),('CN','ZJG','Zhangjiagang','Zhangjiagang','32'),('CN','ZJI','Zhangjian','Zhangjian','61'),('CN','ZLN','Zhongluotan','Zhongluotan','44'),('CN','ZLO','Zhuliao','Zhuliao','44'),('CN','ZMU','Zham','Zham','54'),('CN','ZNG','Zengcheng','Zengcheng','44'),('CN','ZOS','Zhoushan','Zhoushan','33'),('CN','ZQG','Zhaoqing','Zhaoqing','44'),('CN','ZSN','Zhongshan','Zhongshan','44'),('CN','ZTZ','Zhoutuozi','Zhoutuozi','21'),('CN','ZUH','Zhuhai','Zhuhai','44'),('CN','ZUU','Zhuzhou','Zhuzhou','43'),('CN','ZZU','Zhangzhou','Zhangzhou','35'),('CO','','','',''),('CO','ACM','Arica','Arica',''),('CO','ADZ','San Andres Island','San Andres Island',''),('CO','AGD','Agrado','Agrado',''),('CO','AND','Andalucia','Andalucia',''),('CO','APO','Apartado','Apartado',''),('CO','ASR','Astrea','Astrea',''),('CO','AUC','Arauca','Arauca',''),('CO','AXM','Armenia','Armenia',''),('CO','AYA','Ayapel','Ayapel',''),('CO','BAQ','Barranquilla','Barranquilla',''),('CO','BET','Betania','Betania',''),('CO','BGA','Bucaramanga','Bucaramanga',''),('CO','BOG','Bogota','Bogota',''),('CO','BUG','Buga','Buga',''),('CO','BUN','Buenaventura','Buenaventura',''),('CO','CAP','Cachipay','Cachipay',''),('CO','CIE','Cienaga','Cienaga',''),('CO','CLO','Cali','Cali',''),('CO','CRC','Cartago','Cartago',''),('CO','CTG','Cartagena','Cartagena',''),('CO','CUC','Cucuta','Cucuta',''),('CO','CVE','Covenas','Covenas',''),('CO','DAB','Dabeiba','Dabeiba',''),('CO','DUR','Durania','Durania',''),('CO','EBG','El Bagre','El Bagre',''),('CO','EBQ','El Bosque','El Bosque',''),('CO','EES','El Espino','El Espino',''),('CO','EJA','Barrancabermeja','Barrancabermeja',''),('CO','FLA','Florencia','Florencia',''),('CO','FUN','Fundacion','Fundacion',''),('CO','GAM','Gamarra','Gamarra',''),('CO','GAR','Garagoa','Garagoa',''),('CO','GAZ','Garzon','Garzon',''),('CO','GUA','Guaduas','Guaduas',''),('CO','GUP','Guapi','Guapi',''),('CO','IGO','Chigorodo','Chigorodo',''),('CO','LAD','La Dorada','La Dorada',''),('CO','LEJ','Lejanias','Lejanias',''),('CO','LET','Leticia','Leticia',''),('CO','MAC','Macedonia','Macedonia',''),('CO','MAM','Mamonal','Mamonal',''),('CO','MAT','Matanza','Matanza',''),('CO','MAU','Manaure','Manaure',''),('CO','MDE','Medellin','Medellin',''),('CO','MOL','Monte Libano','Monte Libano',''),('CO','MTR','Monteria','Monteria',''),('CO','MZL','Manizales','Manizales',''),('CO','NOB','Nobsa','Nobsa',''),('CO','NVA','Neiva','Neiva',''),('CO','OIB','Oiba','Oiba',''),('CO','PBE','Puerto Berrio','Puerto Berrio',''),('CO','PBO','Puerto Bolivar','Puerto Bolivar',''),('CO','PCR','Puerto Carreno','Puerto Carreno',''),('CO','PEI','Pereira','Pereira',''),('CO','PGA','Puerto Gaitan','Puerto Gaitan',''),('CO','PLL','Puerto Lleras','Puerto Lleras',''),('CO','PNM','Puerto Limon','Puerto Limon',''),('CO','POC','Pozos Colorados','Pozos Colorados',''),('CO','PPN','Popayan','Popayan',''),('CO','PPR','Puerto Prodeco','Puerto Prodeco',''),('CO','PSB','Simon Bolivar','Simon Bolivar',''),('CO','PSO','Pasto','Pasto',''),('CO','PUC','Puerto Colombia','Puerto Colombia',''),('CO','PUG','Puerto Gaitan','Puerto Gaitan',''),('CO','PUL','Puerto Limon','Puerto Limon',''),('CO','PUU','Puerto Asis','Puerto Asis',''),('CO','RCH','Riohacha','Riohacha',''),('CO','SAG','San Gil','San Gil',''),('CO','SAM','Samaca','Samaca',''),('CO','SAR','Santa Rosa','Santa Rosa',''),('CO','SAV','Savanilla','Savanilla',''),('CO','SIN','Since','Since',''),('CO','SMR','Santa Marta','Santa Marta',''),('CO','SRV','Saravena','Saravena',''),('CO','STF','Santa Fee','Santa Fee',''),('CO','TAM','Tame','Tame',''),('CO','TCO','Tumaco','Tumaco',''),('CO','TLU','Tolu','Tolu',''),('CO','TRB','Turbo','Turbo',''),('CO','TUE','Moniquira','Moniquira',''),('CO','UIB','Quibdo','Quibdo',''),('CO','UMB','Umbita','Umbita',''),('CO','VPZ','Villapinzon','Villapinzon',''),('CO','VUP','Valledupar','Valledupar',''),('CO','YMB','Yumbo','Yumbo',''),('CR','','','',''),('CR','ABA','Abangaritos','Abangaritos','P'),('CR','AGU','Aguas Zarcas','Aguas Zarcas','L'),('CR','AJU','Alajuela','Alajuela','A'),('CR','ALI','Alajuelita','Alajuelita','SJ'),('CR','ANA','Santa Ana','Santa Ana','SJ'),('CR','ATM','Altamira','Altamira','A'),('CR','AZA','Aguas Zarcas','Aguas Zarcas','A'),('CR','BAG','Bagaces','Bagaces','G'),('CR','BAR','Barranca','Barranca','P'),('CR','BBD','Barbudal','Barbudal','G'),('CR','BNC','Barranca','Barranca','A'),('CR','CAB','Cabo Blanco','Cabo Blanco','P'),('CR','CAI','Caimital','Caimital','G'),('CR','CAL','Caldera','Caldera','P'),('CR','CAP','Capulin','Capulin','P'),('CR','CAR','Cartago','Cartago','C'),('CR','CDN','Ciudad Neily','Ciudad Neily','G'),('CR','CHA','Chachagua','Chachagua','A'),('CR','CIR','Ciruelas','Ciruelas','A'),('CR','COM','Chomes','Chomes','P'),('CR','CPL','Guapiles','Guapiles','L'),('CR','CYL','Coyol','Coyol','A'),('CR','ESC','Escazu','Escazu','SJ'),('CR','ESP','Esparza','Esparza','P'),('CR','FIL','Filadelfia','Filadelfia','G'),('CR','FPN','Fraijanes','Fraijanes','A'),('CR','GDA','Guardia','Guardia','G'),('CR','GDP','Golfo de Papagayo','Golfo de Papagayo','G'),('CR','GLF','Golfito','Golfito','P'),('CR','GMI','Grecia','Grecia','A'),('CR','GUA','Guatuso','Guatuso','C'),('CR','GUC','Guacimo','Guacimo','L'),('CR','HER','Heredia','Heredia','H'),('CR','JAC','Jaco','Jaco','P'),('CR','JIC','Jicaral','Jicaral','P'),('CR','JIM','Jimenez','Jimenez','L'),('CR','LAF','La Fortuna','La Fortuna','A'),('CR','LIO','Puerto Limon','Puerto Limon','L'),('CR','LIR','Liberia','Liberia','G'),('CR','LLC','La Lucha','La Lucha','P'),('CR','LSL','Los Chiles','Los Chiles','A'),('CR','MOB','Moin','Moin','L'),('CR','MUE','Muelle de San Carlos','Muelle de San Carlos','A'),('CR','NAN','Nandayure','Nandayure','G'),('CR','NAR','Naranjo','Naranjo','SJ'),('CR','NCT','Nicoya','Nicoya','G'),('CR','ORO','Orotina','Orotina','A'),('CR','PAL','Palmares','Palmares','SJ'),('CR','PAM','Palmares','Palmares','A'),('CR','PAN','Palmar Norte','Palmar Norte','P'),('CR','PAR','Parrita','Parrita','P'),('CR','PAS','Puntarenas','Puntarenas','P'),('CR','PIL','Pilas de Canjel','Pilas de Canjel','G'),('CR','PIT','Pital','Pital','P'),('CR','PMZ','Palmar','Palmar','P'),('CR','POC','Pocora','Pocora','L'),('CR','PUM','Punta Morales','Punta Morales','P'),('CR','QPS','Quepos','Quepos',''),('CR','RCD','Rio Cuarto','Rio Cuarto','A'),('CR','RIO','Rio Frio','Rio Frio','P'),('CR','SAM','Samara','Samara','G'),('CR','SAN','San Ignacio de Acosta','San Ignacio de Acosta','SJ'),('CR','SCS','San Carlos','San Carlos','SJ'),('CR','SIS','San Isidro','San Isidro','SJ'),('CR','SJO','San Jose','San Jose','SJ'),('CR','SLN','Salinas','Salinas','P'),('CR','SOR','San Ramon','San Ramon',''),('CR','SPI','Sarapiqui','Sarapiqui','H'),('CR','SQR','Siquirres','Siquirres','L'),('CR','SRG','San Rafael Guatuso','San Rafael Guatuso','A'),('CR','SRI','Sarchi','Sarchi','A'),('CR','SSP','San Pedro de Poas','San Pedro de Poas','A'),('CR','TIG','La Tigra','La Tigra','P'),('CR','TRE','Tres Rios','Tres Rios','C'),('CR','TUR','Turrialba','Turrialba','C'),('CR','UJA','Ujarras','Ujarras','A'),('CR','UPA','Upala','Upala','A'),('CR','VDT','Puerto Viejo','Puerto Viejo','L'),('CR','XQP','Quepos (Puerto Quepos)','Quepos (Puerto Quepos)',''),('CS','','','',''),('CS','ADA','Ada','Ada','SR'),('CS','APT','Apatin','Apatin','SR'),('CS','ARJ','Arilje','Arilje','SR'),('CS','BAR','Bar','Bar','CG'),('CS','BCN','Beocin','Beocin','SR'),('CS','BEC','Becej','Becej','SR'),('CS','BEG','Belgrade (Beograd)','Belgrade (Beograd)','SR'),('CS','BIJ','Bijela','Bijela','CG'),('CS','BOR','Bor','Bor','SR'),('CS','BPA','Backa Palanka','Backa Palanka','SR'),('CS','BTO','Backa Topola','Backa Topola','SR'),('CS','BUD','Budva','Budva','CG'),('CS','BUJ','Bujanovac','Bujanovac','SR'),('CS','BVO','Bogojevo','Bogojevo','SR'),('CS','BZD','Bezdam','Bezdam','SR'),('CS','CAC','Cacak','Cacak','SR'),('CS','CBO','Camp Bondsteel','Camp Bondsteel','KM'),('CS','CMI','Camp Montieth','Camp Montieth','KM'),('CS','CRG','Curug','Curug','VO'),('CS','CUP','Cuprija','Cuprija','SR'),('CS','CVC','Cerevic','Cerevic','SR'),('CS','DIM','Dimitrovgrad','Dimitrovgrad','SR'),('CS','DZC','Drazevac','Drazevac','SR'),('CS','GMI','Gornji Milanovac','Gornji Milanovac','SR'),('CS','GRU','Gruza','Gruza','SR'),('CS','HNO','Hercegnovi','Hercegnovi','CG'),('CS','INI','Nis','Nis','SR'),('CS','IVA','Ivanjica','Ivanjica','SR'),('CS','IVG','Berane (Yvangrad)','Berane (Yvangrad)','CG'),('CS','JAG','Jagodina','Jagodina','SR'),('CS','KAY','Kikinda','Kikinda','SR'),('CS','KGV','Kragujevac','Kragujevac','SR'),('CS','KJA','Kanjiza','Kanjiza','SR'),('CS','KMA','Kursumlija','Kursumlija','SR'),('CS','KNC','Knic','Knic','SR'),('CS','KOT','Kotor','Kotor','CG'),('CS','KPJ','Fushe Kosove (Kosovo Polje)','Fushe Kosove (Kosovo Polje)','KM'),('CS','KRA','Kraljevo','Kraljevo','SR'),('CS','KRU','Krusevac','Krusevac','SR'),('CS','KTC','Kostolac','Kostolac','SR'),('CS','KVC','Knjazevac','Knjazevac','SR'),('CS','LBE','Lebane','Lebane','SR'),('CS','LOZ','Loznica','Loznica','SR'),('CS','LPO','Lapovo','Lapovo','SR'),('CS','LTE','Lestane','Lestane','SR'),('CS','LVC','Leskovac','Leskovac','SR'),('CS','MJI','Mrcajevci','Mrcajevci','SR'),('CS','MLI','Melenci','Melenci','SR'),('CS','MNC','Mladenovac','Mladenovac','SR'),('CS','MSA','Merosina','Merosina','SR'),('CS','NEG','Negotin','Negotin','SR'),('CS','NIK','Niksic','Niksic','CG'),('CS','NOS','Novo Selo','Novo Selo','KM'),('CS','NSL','Novi Slankamen','Novi Slankamen','SR'),('CS','NVP','Novi Pazar','Novi Pazar','SR'),('CS','NVS','Novi Sad','Novi Sad','SR'),('CS','ONC','Obrenovac','Obrenovac','SR'),('CS','PCN','Parain','Parain','SR'),('CS','PHO','Prahovo','Prahovo','SR'),('CS','PIR','Pirot','Pirot','SR'),('CS','PLC','Palic','Palic','SR'),('CS','POZ','Pozega','Pozega','SR'),('CS','PRI','Prijepolje','Prijepolje','SR'),('CS','PRN','Pristina','Pristina','SR'),('CS','PRO','Prokuplje','Prokuplje','SR'),('CS','PRZ','Prizren','Prizren','SR'),('CS','PYJ','Pancevo','Pancevo','SR'),('CS','RPJ','Ripanj','Ripanj','SR'),('CS','RUM','Ruma','Ruma','SR'),('CS','SAB','Sabac','Sabac','SR'),('CS','SCA','Sremcica','Sremcica','SR'),('CS','SEV','Sevojno','Sevojno','SR'),('CS','SID','Sid','Sid','SR'),('CS','SKA','Sremski Karlovci','Sremski Karlovci','SR'),('CS','SMO','Smederevo','Smederevo','SR'),('CS','SNC','Svilajnac','Svilajnac','SR'),('CS','SOM','Sombor','Sombor','SR'),('CS','SPA','Stara Pazova','Stara Pazova','SR'),('CS','SRG','Sirig','Sirig','SR'),('CS','SRM','Sremska Mitrovica','Sremska Mitrovica','SR'),('CS','STZ','Strezimirovci','Strezimirovci','SR'),('CS','SUB','Subotica','Subotica','SR'),('CS','TGD','Podgorica','Podgorica','CG'),('CS','TIV','Tivat','Tivat','CG'),('CS','TJV','Tresnjevac','Tresnjevac','SR'),('CS','ULC','Ulcinj','Ulcinj','CG'),('CS','UZC','Uzice','Uzice','SR'),('CS','VGS','Veliko Gradiste','Veliko Gradiste','SR'),('CS','VLA','Vlasotince','Vlasotince','SR'),('CS','VLJ','Valjevo','Valjevo','SR'),('CS','VRA','Vranje','Vranje','SR'),('CS','VRS','Vrsac','Vrsac','SR'),('CS','ZAJ','Zajecar','Zajecar','SR'),('CS','ZBK','Zabljak','Zabljak','CG'),('CS','ZEL','Zelenika','Zelenika','CG'),('CS','ZEM','Zemun','Zemun','SR'),('CS','ZRN','Zrenjanin','Zrenjanin','SR'),('CS','ZZP','Pozarevac','Pozarevac','SR'),('CU','','','',''),('CU','ANT','Antilla','Antilla',''),('CU','BAN','Banes','Banes',''),('CU','BCA','Baracoa','Baracoa',''),('CU','BHO','Bahia Honda','Bahia Honda',''),('CU','BOG','Boca Grande','Boca Grande',''),('CU','BOQ','Boqueron','Boqueron',''),('CU','BUF','Bufadero','Bufadero',''),('CU','BYM','Bayamo','Bayamo',''),('CU','CAB','Cabanas','Cabanas',''),('CU','CAI','Caibarien','Caibarien',''),('CU','CAR','Cardenas','Cardenas',''),('CU','CAS','Casilda','Casilda',''),('CU','CEI','Ceiba Hueca','Ceiba Hueca',''),('CU','CFG','Cienfuegos','Cienfuegos',''),('CU','CMW','Camaguey','Camaguey',''),('CU','GAO','Los Canos Apt/Guantanamo','Los Canos Apt/Guantanamo',''),('CU','GER','Nueva Gerona','Nueva Gerona',''),('CU','GIB','Gibara','Gibara',''),('CU','GUB','Guantanamo Bay','Guantanamo Bay',''),('CU','GYB','Guayabal','Guayabal',''),('CU','HAV','La Habana','La Habana',''),('CU','HOG','Holguin','Holguin',''),('CU','ICR','Nicaro','Nicaro',''),('CU','IDS','Isabela de Sagua','Isabela de Sagua',''),('CU','JUC','Jucaro','Jucaro',''),('CU','MAR','Mariel','Mariel',''),('CU','MEL','Media Luna','Media Luna',''),('CU','MNT','Manati','Manati',''),('CU','MOA','Moa','Moa',''),('CU','MZO','Manzanillo','Manzanillo',''),('CU','NBW','Guantanamo Nas Apt','Guantanamo Nas Apt',''),('CU','NIQ','Niquero','Niquero',''),('CU','NVT','Nuevitas','Nuevitas',''),('CU','PAL','Palo Alto','Palo Alto',''),('CU','PAS','Pastelillo','Pastelillo',''),('CU','PIL','Pilon','Pilon',''),('CU','PPA','Puerto Padre','Puerto Padre',''),('CU','PTA','Puerto Tarafa','Puerto Tarafa',''),('CU','QCO','Colon','Colon',''),('CU','QMA','Matanzas','Matanzas',''),('CU','RSL','Rio Sagua la Grande','Rio Sagua la Grande',''),('CU','SCS','Santa Cruz del Sur','Santa Cruz del Sur',''),('CU','SCU','Santiago de Cuba','Santiago de Cuba',''),('CU','SDT','Sagua de Tanamo','Sagua de Tanamo',''),('CU','SNU','Santa Clara','Santa Clara',''),('CU','TAN','Tanamo','Tanamo',''),('CU','TDZ','Tunas de Zaza','Tunas de Zaza',''),('CU','TND','Trinidad','Trinidad',''),('CU','VIT','Vita','Vita',''),('CU','VRA','Varadero','Varadero',''),('CU','VTU','Las Tunas','Las Tunas',''),('CV','','','',''),('CV','MIN','Mindelo','Mindelo',''),('CV','MMO','Maio','Maio',''),('CV','MTI','Mosteiros','Mosteiros',''),('CV','PAL','Palmeira','Palmeira',''),('CV','PLM','Pedra de Lume','Pedra de Lume',''),('CV','POI','Porto Ingles','Porto Ingles',''),('CV','PON','Porto Novo','Porto Novo',''),('CV','POP','Porto Preguica','Porto Preguica',''),('CV','RAI','Praia','Praia',''),('CV','SAM','Santa Maria','Santa Maria',''),('CV','SAR','Sal Rei','Sal Rei',''),('CV','SFL','Sao Filipe','Sao Filipe',''),('CV','SID','Ilha do Sal','Ilha do Sal',''),('CV','SNE','Sao Nicolau','Sao Nicolau',''),('CV','TAR','Tarrafal','Tarrafal',''),('CV','VXE','Sao Vicente','Sao Vicente',''),('CX','','','',''),('CX','FFC','Flying Fish Cove','Flying Fish Cove',''),('CX','XCH','Christmas Island','Christmas Island',''),('CY','','','',''),('CY','AKT','Akrotiri','Akrotiri',''),('CY','AYI','Ayia Napa','Ayia Napa',''),('CY','DHK','Dhekelia','Dhekelia',''),('CY','ECN','Ercan','Ercan',''),('CY','EPK','Episkopi','Episkopi',''),('CY','FMG','Famagusta','Famagusta',''),('CY','KAL','Kalecik','Kalecik',''),('CY','KAR','Karavostassi','Karavostassi',''),('CY','KPO','Kofinou','Kofinou',''),('CY','KYR','Kyrenia','Kyrenia',''),('CY','LAT','Latchi','Latchi',''),('CY','LCA','Larnaca','Larnaca',''),('CY','LMS','Limassol','Limassol',''),('CY','MOI','Moni Anchorage','Moni Anchorage',''),('CY','MPB','Morphou Bay','Morphou Bay',''),('CY','NIC','Nicosia','Nicosia',''),('CY','PFO','Paphos','Paphos',''),('CY','VAS','Vasilikos','Vasilikos',''),('CY','ZER','Xeros','Xeros',''),('CY','ZYY','Zyyi','Zyyi',''),('CZ','','','',''),('CZ','AMV','Adamov','Adamov',''),('CZ','ANA','Plana','Plana',''),('CZ','ASA','As','As',''),('CZ','BAJ','Bakov nad Jizerou','Bakov nad Jizerou',''),('CZ','BAN','Banov','Banov',''),('CZ','BBE','Dolni Berkovice','Dolni Berkovice',''),('CZ','BBY','Brumov-Bylnice','Brumov-Bylnice',''),('CZ','BCV','Bucovice','Bucovice',''),('CZ','BDA','Bozi Dar','Bozi Dar',''),('CZ','BDI','Bridlicna','Bridlicna',''),('CZ','BEN','Benesov','Benesov',''),('CZ','BER','Beroun','Beroun',''),('CZ','BHD','Bohdanec','Bohdanec',''),('CZ','BIL','Bila','Bila',''),('CZ','BIP','Bily Potok','Bily Potok',''),('CZ','BLA','Blansko','Blansko',''),('CZ','BLC','Bilcice','Bilcice',''),('CZ','BLN','Bilina','Bilina',''),('CZ','BNJ','Benatky nad Jizerou','Benatky nad Jizerou',''),('CZ','BNL','Brandys nad Labem','Brandys nad Labem',''),('CZ','BNT','Bruntal','Bruntal',''),('CZ','BOH','Bohumin','Bohumin',''),('CZ','BOL','Bolatice','Bolatice',''),('CZ','BOR','Bor u Tachova','Bor u Tachova',''),('CZ','BOV','Borovany','Borovany',''),('CZ','BPB','Bela pod Bezdezem','Bela pod Bezdezem',''),('CZ','BPH','Bystrice','Bystrice',''),('CZ','BRE','Brezova','Brezova',''),('CZ','BRM','Broumov','Broumov',''),('CZ','BRQ','Brno','Brno',''),('CZ','BTC','Boretice','Boretice',''),('CZ','BUD','Budinek','Budinek',''),('CZ','BUO','Branka','Branka',''),('CZ','BVA','Breclav','Breclav',''),('CZ','BVE','Bohunovice','Bohunovice',''),('CZ','BYP','Bystrice pod Hostynem','Bystrice pod Hostynem',''),('CZ','BZC','Bzenec','Bzenec',''),('CZ','BZI','Brezi','Brezi',''),('CZ','BZN','Bezno','Bezno',''),('CZ','CAS','Castolovice','Castolovice',''),('CZ','CCA','Cinovec','Cinovec',''),('CZ','CCE','Cestlice','Cestlice',''),('CZ','CCN','Chocen','Chocen',''),('CZ','CEK','Ceska Kubice','Ceska Kubice',''),('CZ','CHB','Cheb','Cheb',''),('CZ','CHM','Chomutov','Chomutov',''),('CZ','CHO','Chodov','Chodov',''),('CZ','CHR','Chrudim','Chrudim',''),('CZ','CHT','Chotebuz','Chotebuz',''),('CZ','CHU','Chudobin','Chudobin',''),('CZ','CHV','Chvaletice','Chvaletice',''),('CZ','CKB','Ceske Budejovice','Ceske Budejovice',''),('CZ','CKP','Ceske Kopisty','Ceske Kopisty',''),('CZ','CKR','Cesky Krumlov','Cesky Krumlov',''),('CZ','CLI','Ceska Lipa','Ceska Lipa',''),('CZ','CLK','Celakovice','Celakovice',''),('CZ','CNC','Cernuc','Cernuc',''),('CZ','CNZ','Cernozice','Cernozice',''),('CZ','CPL','Chodova Plana','Chodova Plana',''),('CZ','CSB','Cesky Brod','Cesky Brod',''),('CZ','CSK','Ceska Skalice','Ceska Skalice',''),('CZ','CTR','Ceska Trebova','Ceska Trebova',''),('CZ','CUL','Chrastava','Chrastava',''),('CZ','CVJ','Cervene Janovice','Cervene Janovice',''),('CZ','CVY','Cerveny Kostelec','Cerveny Kostelec',''),('CZ','DBI','Dubi','Dubi',''),('CZ','DBV','Dolni Becva','Dolni Becva',''),('CZ','DBY','Dobrany','Dobrany',''),('CZ','DBZ','Breznik','Breznik',''),('CZ','DCB','Decin','Decin',''),('CZ','DCE','Dolni Cetno','Dolni Cetno',''),('CZ','DCI','Dacice','Dacice',''),('CZ','DDA','Dolni Dvoriste','Dolni Dvoriste',''),('CZ','DIV','Divisov','Divisov',''),('CZ','DJE','Dobrejovice','Dobrejovice',''),('CZ','DKE','Dobkovice','Dobkovice',''),('CZ','DKN','Dolni Kalna','Dolni Kalna',''),('CZ','DKV','Drzkov','Drzkov',''),('CZ','DLC','Dalecin','Dalecin',''),('CZ','DLI','Dolni Lipka','Dolni Lipka',''),('CZ','DLN','Dolany','Dolany',''),('CZ','DOB','Dolni Benesov','Dolni Benesov',''),('CZ','DOL','Dolni Lhota','Dolni Lhota',''),('CZ','DOM','Domazlice','Domazlice',''),('CZ','DRS','Dobris','Dobris',''),('CZ','DSY','Drisy','Drisy',''),('CZ','DUC','Duchcov','Duchcov',''),('CZ','DVI','Dalovice','Dalovice',''),('CZ','DVK','Dvur Kralove nad Labem','Dvur Kralove nad Labem',''),('CZ','DYM','Dymokury','Dymokury',''),('CZ','DYY','Dysina','Dysina',''),('CZ','EJP','Ejpovice','Ejpovice',''),('CZ','FOL','Folmava','Folmava',''),('CZ','FRM','Frydek-Mistek','Frydek-Mistek',''),('CZ','FRT','Frenstat pod Radhostem','Frenstat pod Radhostem',''),('CZ','FRY','Frydlant','Frydlant',''),('CZ','GOL','Golcuv Jenikov','Golcuv Jenikov',''),('CZ','HAH','Horni Adrspach','Horni Adrspach',''),('CZ','HAT','Hate','Hate',''),('CZ','HAV','Havirov','Havirov',''),('CZ','HBC','Horni Becva','Horni Becva',''),('CZ','HCE','Holice','Holice',''),('CZ','HCV','Horni Cerekev','Horni Cerekev',''),('CZ','HDA','Horni Dvoriste','Horni Dvoriste',''),('CZ','HEA','Hevlin','Hevlin',''),('CZ','HER','Hermanova Hut','Hermanova Hut',''),('CZ','HJI','Horni Jiretin','Horni Jiretin',''),('CZ','HKR','Hradec Kralove','Hradec Kralove',''),('CZ','HLB','Hlubocky','Hlubocky',''),('CZ','HLD','Horni Lidec','Horni Lidec',''),('CZ','HLK','Hluk','Hluk',''),('CZ','HLM','Halamky','Halamky',''),('CZ','HLN','Hlinsko','Hlinsko',''),('CZ','HLT','Hradistko','Hradistko',''),('CZ','HMM','Hermanuv Mestec','Hermanuv Mestec',''),('CZ','HNE','Hnevotin','Hnevotin',''),('CZ','HOD','Hodonin','Hodonin',''),('CZ','HOL','Holesov','Holesov',''),('CZ','HOM','Hodkovice nad Mohelkou','Hodkovice nad Mohelkou',''),('CZ','HOS','Hora Svateho Sebestiana','Hora Svateho Sebestiana',''),('CZ','HPC','Humpolec','Humpolec',''),('CZ','HPE','Hustopece','Hustopece',''),('CZ','HRM','Hradec-nad-Moravici','Hradec-nad-Moravici',''),('CZ','HRP','Horice','Horice',''),('CZ','HRV','Horovice','Horovice',''),('CZ','HSA','Hrensko','Hrensko',''),('CZ','HSO','Horni Slavkov','Horni Slavkov',''),('CZ','HSU','Horni Sucha','Horni Sucha',''),('CZ','HTA','Habartice','Habartice',''),('CZ','HTE','Horni Tasovice','Horni Tasovice',''),('CZ','HUA','Hradek nad Nisou','Hradek nad Nisou',''),('CZ','HUD','Hudlice','Hudlice',''),('CZ','HUL','Hulin','Hulin',''),('CZ','HUS','Husinec','Husinec',''),('CZ','HVA','Harrachov','Harrachov',''),('CZ','HVB','Havlickuv Brod','Havlickuv Brod',''),('CZ','HVE','Hostivice','Hostivice',''),('CZ','HVI','Hnevice','Hnevice',''),('CZ','HZV','Horazd\' ovice','Horazd\' ovice',''),('CZ','ICE','Ivancice','Ivancice',''),('CZ','JAB','Jablonne nad Orlici','Jablonne nad Orlici',''),('CZ','JAR','Jaromer','Jaromer',''),('CZ','JBC','Jablonec nad Nisou','Jablonec nad Nisou',''),('CZ','JBV','Jablunkov','Jablunkov',''),('CZ','JEV','Jevicko','Jevicko',''),('CZ','JHV','Jihlava','Jihlava',''),('CZ','JIC','Jicin','Jicin',''),('CZ','JIL','Jilemnice','Jilemnice',''),('CZ','JNC','Jenec','Jenec',''),('CZ','JNH','Jindrichuv Hradec','Jindrichuv Hradec',''),('CZ','JNJ','Jablonec nad Jizerou','Jablonec nad Jizerou',''),('CZ','JPR','Jilove u Prahy','Jilove u Prahy',''),('CZ','JPY','Jablonecke Paseky','Jablonecke Paseky',''),('CZ','JRA','Jirikov','Jirikov',''),('CZ','JRN','Jirny','Jirny',''),('CZ','JSN','Jesenik','Jesenik',''),('CZ','JTV','JetYichov','JetYichov',''),('CZ','KAD','Kada?','Kada?',''),('CZ','KAP','Kaplice','Kaplice',''),('CZ','KAR','Karlin','Karlin',''),('CZ','KCC','Klasterec nad Orlici','Klasterec nad Orlici',''),('CZ','KCL','Kostelec nad Cernymi Lesy','Kostelec nad Cernymi Lesy',''),('CZ','KJV','Kaznejov','Kaznejov',''),('CZ','KLC','Klicany','Klicany',''),('CZ','KLD','Kladno','Kladno',''),('CZ','KLK','Kraliky','Kraliky',''),('CZ','KLN','Kolin','Kolin',''),('CZ','KLV','Karlovy Vary','Karlovy Vary',''),('CZ','KLY','Klatovy','Klatovy',''),('CZ','KMN','Kamenna','Kamenna',''),('CZ','KMR','Kromeriz','Kromeriz',''),('CZ','KNO','Klasterec nad Ohri','Klasterec nad Ohri',''),('CZ','KNV','Kralupy nad Vltavou','Kralupy nad Vltavou',''),('CZ','KOJ','Kojetice','Kojetice',''),('CZ','KOO','Kostelec nad Orlici','Kostelec nad Orlici',''),('CZ','KOP','Koprivnice','Koprivnice',''),('CZ','KOS','Kostany','Kostany',''),('CZ','KOZ','Kozlany','Kozlany',''),('CZ','KRL','Kralovec','Kralovec',''),('CZ','KRM','Kourim','Kourim',''),('CZ','KRN','Krnov','Krnov',''),('CZ','KRV','Karvina','Karvina',''),('CZ','KRY','Kryry','Kryry',''),('CZ','KSA','Krasna','Krasna',''),('CZ','KSL','Kostelec nad Labem','Kostelec nad Labem',''),('CZ','KST','Kostomlatky','Kostomlatky',''),('CZ','KSV','Kamenicky Senov','Kamenicky Senov',''),('CZ','KTA','Kos?alov','Kos?alov',''),('CZ','KTV','Klatovy','Klatovy',''),('CZ','KUH','Kutna Hora','Kutna Hora',''),('CZ','KUN','Kunovice','Kunovice',''),('CZ','KUR','Kurim','Kurim',''),('CZ','KUV','Karolinka','Karolinka',''),('CZ','KVC','Kunovice','Kunovice',''),('CZ','KVO','Kamyk nad Vltavou','Kamyk nad Vltavou',''),('CZ','KYJ','Kyjov','Kyjov',''),('CZ','KZE','Knezeves','Knezeves',''),('CZ','LBC','Lubenec','Lubenec',''),('CZ','LBR','Liberec','Liberec',''),('CZ','LCE','Litice','Litice',''),('CZ','LCH','Lichkov','Lichkov',''),('CZ','LDV','Ladvi','Ladvi',''),('CZ','LEC','Lechovice','Lechovice',''),('CZ','LIB','Libosovice','Libosovice',''),('CZ','LIC','Libochovany','Libochovany',''),('CZ','LIS','Liskova u Nemanic','Liskova u Nemanic',''),('CZ','LMS','Litomysl','Litomysl',''),('CZ','LNN','Lucany nad Nisou','Lucany nad Nisou',''),('CZ','LOD','Lodenice','Lodenice',''),('CZ','LOE','Letovice','Letovice',''),('CZ','LOM','Lomnice nad Popelkou','Lomnice nad Popelkou',''),('CZ','LOU','Louny','Louny',''),('CZ','LTC','Litomerice','Litomerice',''),('CZ','LTV','Litovel','Litovel',''),('CZ','LUK','Lochovice','Lochovice',''),('CZ','LUL','Luhacovice','Luhacovice',''),('CZ','LUS','Lustenice','Lustenice',''),('CZ','LVC','Lovosice','Lovosice',''),('CZ','LVV','Litvinov','Litvinov',''),('CZ','LYL','Lysa nad Labem','Lysa nad Labem',''),('CZ','LZH','Lanzhot','Lanzhot',''),('CZ','MBV','Mlada Boleslav','Mlada Boleslav',''),('CZ','MCA','Mikulovice','Mikulovice',''),('CZ','MCH','Mchnov','Mchnov',''),('CZ','MDR','Modrice','Modrice',''),('CZ','MEE','Mutenice','Mutenice',''),('CZ','MEL','Melnik','Melnik',''),('CZ','MHC','Mnichovice','Mnichovice',''),('CZ','MHL','Mohelnice','Mohelnice',''),('CZ','MHT','Mnichovo Hradiste','Mnichovo Hradiste',''),('CZ','MIL','Milevsko','Milevsko',''),('CZ','MJB','Mosty u Jablunkova','Mosty u Jablunkova',''),('CZ','MKA','Marianske Lazne','Marianske Lazne',''),('CZ','MKL','Mikulov','Mikulov',''),('CZ','MKV','Moravsky Krumlov','Moravsky Krumlov',''),('CZ','MLN','Milin','Milin',''),('CZ','MMN','Mimon','Mimon',''),('CZ','MNV','Michnov','Michnov',''),('CZ','MOD','Modletice','Modletice',''),('CZ','MOK','Mokra','Mokra',''),('CZ','MOS','Mosnov','Mosnov',''),('CZ','MST','Most','Most',''),('CZ','MSV','Male Svatonovice','Male Svatonovice',''),('CZ','MTK','Mostek','Mostek',''),('CZ','MVB','Moravska Trebova','Moravska Trebova',''),('CZ','MYB','Moravsky Beroun','Moravsky Beroun',''),('CZ','MZA','Mezimesti','Mezimesti',''),('CZ','NAA','Nachod','Nachod',''),('CZ','NBR','Nizbor','Nizbor',''),('CZ','NCA','Nova Bystrice','Nova Bystrice',''),('CZ','NED','Nedasova Lhota','Nedasova Lhota',''),('CZ','NEJ','Nejdek','Nejdek',''),('CZ','NHK','Novy Hradek','Novy Hradek',''),('CZ','NHV','Novy Hrozenkov','Novy Hrozenkov',''),('CZ','NIC','Nestemice','Nestemice',''),('CZ','NJC','Novy Jicin','Novy Jicin',''),('CZ','NLH','Nelahozeves','Nelahozeves',''),('CZ','NMB','Nymburk','Nymburk',''),('CZ','NMN','Nove Mesto nad Metuji','Nove Mesto nad Metuji',''),('CZ','NMO','Nove Mesto na Morave','Nove Mesto na Morave',''),('CZ','NOB','Novy Bor','Novy Bor',''),('CZ','NPJ','Napajedla','Napajedla',''),('CZ','NRL','Nova Role','Nova Role',''),('CZ','NRT','Neratovice','Neratovice',''),('CZ','NRY','Nyrany','Nyrany',''),('CZ','NST','Nove Straseci','Nove Straseci',''),('CZ','NUP','Nupaky','Nupaky',''),('CZ','NVC','Nivnice','Nivnice',''),('CZ','NVI','Netovice','Netovice',''),('CZ','NVS','Nosovice','Nosovice',''),('CZ','NVV','Novy Vestec','Novy Vestec',''),('CZ','NVY','Nove Dvory','Nove Dvory',''),('CZ','OBT','Obristvi','Obristvi',''),('CZ','ODO','Odolena Voda','Odolena Voda',''),('CZ','ODV','Odolena Voda','Odolena Voda',''),('CZ','ODY','Odry','Odry',''),('CZ','OHA','Pomezi nad Ohri','Pomezi nad Ohri',''),('CZ','OKY','Okrisky','Okrisky',''),('CZ','OLO','Olomouc','Olomouc',''),('CZ','OMO','Omoljica','Omoljica',''),('CZ','OND','Ondrejov','Ondrejov',''),('CZ','ONO','Ostrov','Ostrov',''),('CZ','ONV','Ostrozska Nova Ves','Ostrozska Nova Ves',''),('CZ','OPA','Opava','Opava',''),('CZ','OPY','Oparany','Oparany',''),('CZ','OSR','Ostrava','Ostrava',''),('CZ','OSY','Oslavany','Oslavany',''),('CZ','OTC','Otrokovice','Otrokovice',''),('CZ','OTV','Otovice','Otovice',''),('CZ','OVC','Otvovice','Otvovice',''),('CZ','OVK','Smrzovka','Smrzovka',''),('CZ','OVO','Ostrov nad Ohri','Ostrov nad Ohri',''),('CZ','PBY','Podborany','Podborany',''),('CZ','PEL','Pelhrimov','Pelhrimov',''),('CZ','PHE','Pruhonice','Pruhonice',''),('CZ','PKA','Petrovice u Karvine','Petrovice u Karvine',''),('CZ','PKY','Pecky','Pecky',''),('CZ','PLC','Prelouc','Prelouc',''),('CZ','PLK','Policka','Policka',''),('CZ','PLO','Polevsko','Polevsko',''),('CZ','PLZ','Plzen','Plzen',''),('CZ','PNB','Panenske Brezany','Panenske Brezany',''),('CZ','PNJ','Police nad Metuji','Police nad Metuji',''),('CZ','PNL','Predmerice nad Labem','Predmerice nad Labem',''),('CZ','POC','Pocatky','Pocatky',''),('CZ','POD','Podebrady','Podebrady',''),('CZ','POL','Polerady','Polerady',''),('CZ','POT','Potucky-silnice','Potucky-silnice',''),('CZ','PPO','Pavlovice u Prerova','Pavlovice u Prerova',''),('CZ','PRB','Pardubice','Pardubice',''),('CZ','PRE','Pohorelice','Pohorelice',''),('CZ','PRG','Praha','Praha',''),('CZ','PRI','Pribram','Pribram',''),('CZ','PRO','Prostejov','Prostejov',''),('CZ','PRS','Porici nad Sazavou','Porici nad Sazavou',''),('CZ','PRT','Prachatice','Prachatice',''),('CZ','PRV','Prerov','Prerov',''),('CZ','PSK','Pisek','Pisek',''),('CZ','PSN','Pisnice','Pisnice',''),('CZ','PSV','Paskov','Paskov',''),('CZ','PTI','Pteni','Pteni',''),('CZ','PTV','Petrov','Petrov',''),('CZ','PVN','Provodin','Provodin',''),('CZ','PVY','Plavy','Plavy',''),('CZ','PZO','Pobezovice','Pobezovice',''),('CZ','PZY','Pouzdrany','Pouzdrany',''),('CZ','RAK','Rakovnik','Rakovnik',''),('CZ','RAT','Rapotin','Rapotin',''),('CZ','RCY','Ricany','Ricany',''),('CZ','RDA','Zelezna Ruda','Zelezna Ruda',''),('CZ','RKC','Rokycany','Rokycany',''),('CZ','RNH','Kralice na Hane','Kralice na Hane',''),('CZ','RNK','Rychnov nad Kneznou','Rychnov nad Kneznou',''),('CZ','RNL','Roudnice nad Labem','Roudnice nad Labem',''),('CZ','RPO','Rapotice','Rapotice',''),('CZ','RPR','Roznov pod Radhosthem','Roznov pod Radhosthem',''),('CZ','RSV','Rousinov','Rousinov',''),('CZ','RUA','Rumburk','Rumburk',''),('CZ','RUD','Rudna','Rudna',''),('CZ','RUR','Rosice u Brna','Rosice u Brna',''),('CZ','RVC','Racovice','Racovice',''),('CZ','RVN','Radovesnice','Radovesnice',''),('CZ','RZA','Rozvadov','Rozvadov',''),('CZ','RZT','Roztoky','Roztoky',''),('CZ','SAA','Satov','Satov',''),('CZ','SAZ','Sazava','Sazava',''),('CZ','SBE','Sobeslav','Sobeslav',''),('CZ','SBO','Stara Boleslav','Stara Boleslav',''),('CZ','SDC','Sudice','Sudice',''),('CZ','SDI','Sardice','Sardice',''),('CZ','SDO','Sviadnov','Sviadnov',''),('CZ','SED','Sedlcany','Sedlcany',''),('CZ','SEZ','Sezimovo Usti','Sezimovo Usti',''),('CZ','SHD','Stare Hradiste','Stare Hradiste',''),('CZ','SHZ','Stary Hrozenkov','Stary Hrozenkov',''),('CZ','SKL','Valtinov','Valtinov',''),('CZ','SKN','Strakonice','Strakonice',''),('CZ','SKT','Skutec','Skutec',''),('CZ','SKV','Skvorec','Skvorec',''),('CZ','SLN','Slany','Slany',''),('CZ','SLY','Slany','Slany',''),('CZ','SLZ','Sucha Loz','Sucha Loz',''),('CZ','SML','Semily','Semily',''),('CZ','SMO','Smichov','Smichov',''),('CZ','SMR','Smirice','Smirice',''),('CZ','SNB','Skuhrov nad Belou','Skuhrov nad Belou',''),('CZ','SNH','Senice na Hane','Senice na Hane',''),('CZ','SNN','Straz nad Nisou','Straz nad Nisou',''),('CZ','SNS','Svetla nad Sazavou','Svetla nad Sazavou',''),('CZ','SNV','Stitna nad Vlari','Stitna nad Vlari',''),('CZ','SNY','Slatinany','Slatinany',''),('CZ','SOB','Sobotin','Sobotin',''),('CZ','SOK','Sokolov','Sokolov',''),('CZ','SPC','Stary Plzenec','Stary Plzenec',''),('CZ','SRL','Strelna','Strelna',''),('CZ','SRO','Stara Role','Stara Role',''),('CZ','STA','Slatina','Slatina',''),('CZ','STB','Sternberk','Sternberk',''),('CZ','STC','Strancice','Strancice',''),('CZ','STD','Stadlec','Stadlec',''),('CZ','STE','Stechovice','Stechovice',''),('CZ','STN','Strani','Strani',''),('CZ','STR','Straznice','Straznice',''),('CZ','STT','Steti','Steti',''),('CZ','STU','Studena','Studena',''),('CZ','STV','Svitavy','Svitavy',''),('CZ','STY','Studanky','Studanky',''),('CZ','SUD','Sudomerice','Sudomerice',''),('CZ','SUM','Sumperk','Sumperk',''),('CZ','SUS','Susice','Susice',''),('CZ','SVK','Svaty Kriz','Svaty Kriz',''),('CZ','SVO','Straskov','Straskov',''),('CZ','SVR','Svrkyn?','Svrkyn?',''),('CZ','SZA','Strazny','Strazny',''),('CZ','TAC','Tachov','Tachov',''),('CZ','TAS','Tynec nad Sazavou','Tynec nad Sazavou',''),('CZ','TBD','Treboradice','Treboradice',''),('CZ','TBR','Tabor','Tabor',''),('CZ','TDI','Tvrdonice','Tvrdonice',''),('CZ','TEA','Cesky Tesin','Cesky Tesin',''),('CZ','TEP','Teplice','Teplice',''),('CZ','TIS','Tisnov','Tisnov',''),('CZ','TMO','Tremosnice','Tremosnice',''),('CZ','TNC','Trinec','Trinec',''),('CZ','TOM','Touzim','Touzim',''),('CZ','TOV','Tovacov','Tovacov',''),('CZ','TPO','Trebechovice pod Orebem','Trebechovice pod Orebem',''),('CZ','TRB','Trebic','Trebic',''),('CZ','TRM','Trmice','Trmice',''),('CZ','TRU','Trutnov','Trutnov',''),('CZ','TSO','Trebestovice','Trebestovice',''),('CZ','TUR','Turnov','Turnov',''),('CZ','TVA','Tanvald','Tanvald',''),('CZ','TYL','Tynec nad Labem','Tynec nad Labem',''),('CZ','UBR','Uhersky Brod','Uhersky Brod',''),('CZ','UCV','Unicov','Unicov',''),('CZ','UHE','Uherske Hradiste','Uherske Hradiste',''),('CZ','ULN','Usti nad Labem','Usti nad Labem',''),('CZ','UOI','Usti nad Orlici','Usti nad Orlici',''),('CZ','UPI','Upice','Upice',''),('CZ','USV','Usov','Usov',''),('CZ','VAA','Veverska Bityska','Veverska Bityska',''),('CZ','VBY','Vseruby','Vseruby',''),('CZ','VCE','Velke Opatovice','Velke Opatovice',''),('CZ','VCH','Vysoky Chlumec','Vysoky Chlumec',''),('CZ','VCR','Volduchy','Volduchy',''),('CZ','VEA','Ceske Velenice','Ceske Velenice',''),('CZ','VEB','Velka Biteš','Velka Biteš',''),('CZ','VEL','Veletov','Veletov',''),('CZ','VFA','Varnsdorf','Varnsdorf',''),('CZ','VIM','Vimperk','Vimperk',''),('CZ','VJA','Vojtanov','Vojtanov',''),('CZ','VJO','Vojkovice','Vojkovice',''),('CZ','VKC','Velke Karlovice','Velke Karlovice',''),('CZ','VKS','Velky Cenov','Velky Cenov',''),('CZ','VKV','Vyskov','Vyskov',''),('CZ','VLM','Vlasim','Vlasim',''),('CZ','VLN','Velen','Velen',''),('CZ','VLT','Veltruby','Veltruby',''),('CZ','VMB','Vamberk','Vamberk',''),('CZ','VMI','Velke Mezirici','Velke Mezirici',''),('CZ','VMO','Vysoke Myto','Vysoke Myto',''),('CZ','VMZ','Valasske Mezirici','Valasske Mezirici',''),('CZ','VNR','Vinor','Vinor',''),('CZ','VNV','Velka nad Velickou','Velka nad Velickou',''),('CZ','VNY','Vranany','Vranany',''),('CZ','VOS','Velky Osek','Velky Osek',''),('CZ','VPO','Velke Popovice','Velke Popovice',''),('CZ','VRC','Vrchlabi','Vrchlabi',''),('CZ','VRN','Vrane nad Vltavou','Vrane nad Vltavou',''),('CZ','VRY','Volary','Volary',''),('CZ','VSE','Vsetaty','Vsetaty',''),('CZ','VST','Vsetin','Vsetin',''),('CZ','VTC','Valtice','Valtice',''),('CZ','YHO','Holubice','Holubice',''),('CZ','ZAM','Zamberk','Zamberk',''),('CZ','ZAT','Zatec','Zatec',''),('CZ','ZBU','Zbuzany','Zbuzany',''),('CZ','ZBY','Zdiby','Zdiby',''),('CZ','ZCR','Zacler','Zacler',''),('CZ','ZDA','Zdanice','Zdanice',''),('CZ','ZEB','Zebrak','Zebrak',''),('CZ','ZHR','Zlate Hory','Zlate Hory',''),('CZ','ZIV','Zirovnice','Zirovnice',''),('CZ','ZKQ','Rohatec','Rohatec',''),('CZ','ZLK','Zelenky','Zelenky',''),('CZ','ZLN','Zlin','Zlin',''),('CZ','ZMO','Znojmo','Znojmo',''),('CZ','ZND','Zdirec Nad Doubravkou','Zdirec Nad Doubravkou',''),('CZ','ZNM','Zabreh na Morave','Zabreh na Morave',''),('CZ','ZNS','Zdar nad Sazavou','Zdar nad Sazavou',''),('CZ','ZRS','Zruc nad Sazavou','Zruc nad Sazavou',''),('CZ','ZVE','Zverinek','Zverinek',''),('DE','','','',''),('DE','AAC','Aach','Aach','BW'),('DE','AAH','Aachen','Aachen','NW'),('DE','AAL','Aalen','Aalen','BW'),('DE','AAR','Aarbergen','Aarbergen','HE'),('DE','AAS','Arolsen','Arolsen','HE'),('DE','ABC','Altbach','Altbach','BW'),('DE','ABE','Abensberg','Abensberg','BY'),('DE','ABF','Abbenfleth','Abbenfleth','NI'),('DE','ABH','Abbehausen','Abbehausen','NI'),('DE','ABK','Albbruck','Albbruck','BW'),('DE','ABL','Abbesbuttel','Abbesbuttel','NI'),('DE','ABM','Asbach-Baumenheim','Asbach-Baumenheim','BY'),('DE','ABO','Alt Bork','Alt Bork','BR'),('DE','ABS','Asbach','Asbach','RP'),('DE','ABT','Abtswind','Abtswind','BY'),('DE','ACB','Achenbach','Achenbach','NW'),('DE','ACH','Achern','Achern','BW'),('DE','ACM','Achim','Achim','NI'),('DE','ACT','Achstetten','Achstetten','BW'),('DE','ADF','Altdorf','Altdorf','BY'),('DE','ADN','Adelsdorf','Adelsdorf','BY'),('DE','ADO','Allendorf','Allendorf','HE'),('DE','ADS','Andechs','Andechs','BY'),('DE','ADT','Weinstadt','Weinstadt','BW'),('DE','AEG','Ascheberg','Ascheberg','NW'),('DE','AER','Aerzen','Aerzen','NI'),('DE','AFE','Ahrensfelde','Ahrensfelde','BR'),('DE','AFF','Affalterbach','Affalterbach','BY'),('DE','AFT','Alfter','Alfter','NW'),('DE','AGB','Augsburg','Augsburg','BY'),('DE','AGE','Wangerooge','Wangerooge','NI'),('DE','AGT','Augustdorf','Augustdorf','NW'),('DE','AHA','Ahaus','Ahaus','NW'),('DE','AHB','Althegnenberg','Althegnenberg','BY'),('DE','AHD','Aichhalden','Aichhalden','BW'),('DE','AHE','Altheim','Altheim','BY'),('DE','AHF','Adelheidsdorf','Adelheidsdorf','NI'),('DE','AHL','Ahlen','Ahlen','NW'),('DE','AHM','Aschheim','Aschheim','BY'),('DE','AHN','Ahorn','Ahorn','BY'),('DE','AHR','Ahrensburg','Ahrensburg','SH'),('DE','AIC','Aichach','Aichach','BY'),('DE','AIH','Aich','Aich','BW'),('DE','AIL','Aichtal','Aichtal','BW'),('DE','AIN','Unter Abtsteinach','Unter Abtsteinach','HE'),('DE','AIS','Bodenmais','Bodenmais','BY'),('DE','AIT','Aitrach','Aitrach','BW'),('DE','AKT','Altenkunstadt','Altenkunstadt','BY'),('DE','ALB','Albstadt','Albstadt','BW'),('DE','ALC','Altenburg','Altenburg','TH'),('DE','ALD','Alsfeld','Alsfeld','HE'),('DE','ALE','Albershausen','Albershausen','BW'),('DE','ALF','Alfeld/Leine','Alfeld/Leine','NI'),('DE','ALG','Altotting','Altotting','BY'),('DE','ALH','Alsbach','Alsbach','RP'),('DE','ALI','Aislingen','Aislingen','BY'),('DE','ALK','Altenkirchen/Westerwald','Altenkirchen/Westerwald','RP'),('DE','ALL','Allershausen','Allershausen','BY'),('DE','ALM','Altlussheim','Altlussheim','BW'),('DE','ALN','Aldingen','Aldingen','BW'),('DE','ALO','Alsdorf, Altenkirchen','Alsdorf, Altenkirchen','RP'),('DE','ALP','Alpen','Alpen','NW'),('DE','ALR','Altusried','Altusried','BY'),('DE','ALS','Alsdorf','Alsdorf','NW'),('DE','ALT','Altena','Altena','NW'),('DE','ALZ','Alzenau','Alzenau','BY'),('DE','AMB','Amberg','Amberg','BY'),('DE','AME','Ameln','Ameln','NW'),('DE','AMK','Altenmarkt an der Alz','Altenmarkt an der Alz','BY'),('DE','AML','Amelsburen','Amelsburen','NW'),('DE','AMM','Ammerbuch','Ammerbuch','BW'),('DE','AMN','Altomunster','Altomunster','BY'),('DE','AMO','Amorbach','Amorbach','BY'),('DE','AMR','Achmer','Achmer','NI'),('DE','AMS','Ammersbek','Ammersbek','SH'),('DE','AMU','Angermunde','Angermunde','BR'),('DE','ANB','Annaberg-Buchholz','Annaberg-Buchholz','SN'),('DE','ANC','Angersbach','Angersbach','HE'),('DE','AND','Andernach','Andernach','RP'),('DE','ANG','Anger','Anger','BY'),('DE','ANH','Altenhain','Altenhain','HE'),('DE','ANK','Anklam','Anklam','MV'),('DE','ANN','Annweiler','Annweiler','RP'),('DE','ANS','Ansbach','Ansbach','BY'),('DE','ANU','Ankum','Ankum','NI'),('DE','ANZ','Anzing','Anzing','BY'),('DE','AOR','Arnstorf','Arnstorf','BY'),('DE','APE','Apen','Apen','NI'),('DE','APO','Apolda','Apolda','TH'),('DE','APP','Amperpettenbach','Amperpettenbach','BY'),('DE','APW','Appenweier','Appenweier','BW'),('DE','AQF','Alf','Alf','RP'),('DE','ARB','Allersberg','Allersberg','BY'),('DE','ARF','Alfdorf','Alfdorf','BW'),('DE','ARG','Ainring','Ainring','BY'),('DE','ARH','Anrochte','Anrochte','NW'),('DE','ARL','Ammerland','Ammerland','BY'),('DE','ARN','Arnsberg','Arnsberg','NW'),('DE','ARR','Scharenstetten','Scharenstetten','BW'),('DE','ARS','Arnstadt','Arnstadt','TH'),('DE','ARU','Arnbruck','Arnbruck','BY'),('DE','ASA','Assamstadt','Assamstadt','BW'),('DE','ASB','Alpirsbach','Alpirsbach','BW'),('DE','ASC','Aschaffenburg','Aschaffenburg','BY'),('DE','ASD','Albersdorf','Albersdorf','SH'),('DE','ASE','Arendsee','Arendsee','ST'),('DE','ASF','Asch','Asch','BY'),('DE','ASG','Altensteig','Altensteig','BW'),('DE','ASH','Ahrenshoft','Ahrenshoft','SH'),('DE','ASI','Alsheim','Alsheim','RP'),('DE','ASL','Asslar','Asslar','HE'),('DE','ASN','Aschersleben','Aschersleben','ST'),('DE','ASO','Alsdorf, Bitburg','Alsdorf, Bitburg','RP'),('DE','ASS','Assel','Assel','NI'),('DE','AST','Kastl','Kastl','BY'),('DE','ASU','Aschau','Aschau','TH'),('DE','ATB','Altenberge','Altenberge','NW'),('DE','ATF','Altdorf','Altdorf','BY'),('DE','ATG','Altleiningen','Altleiningen','RP'),('DE','ATH','Altenhain','Altenhain','SN'),('DE','ATL','Altenlingen','Altenlingen','NI'),('DE','ATN','Attendorn','Attendorn','NW'),('DE','ATZ','Amtzell','Amtzell','BW'),('DE','AUE','Auerbach/Vogtland','Auerbach/Vogtland','SN'),('DE','AUG','Augustfehn','Augustfehn','NI'),('DE','AUL','Aulendorf','Aulendorf','BW'),('DE','AUM','Aumuhle','Aumuhle','SH'),('DE','AUR','Aurich','Aurich','NI'),('DE','AUS','Aussernzell','Aussernzell','BY'),('DE','AUZ','Aue/Sachsen','Aue/Sachsen','SN'),('DE','AVL','Alveslohe','Alveslohe','SH'),('DE','AVW','Aicha vorm Wald','Aicha vorm Wald','BY'),('DE','AWD','Aichwald','Aichwald','BW'),('DE','AWR','Achterwehr','Achterwehr','SH'),('DE','AXS','Aschau am Inn','Aschau am Inn','BY'),('DE','AYH','Altenoythe','Altenoythe','NI'),('DE','AYI','Aying','Aying','BY'),('DE','AYL','Ayl','Ayl','RP'),('DE','AZY','Alzey','Alzey','RP'),('DE','BAA','Baalsdorf','Baalsdorf','SN'),('DE','BAB','Baden Baden','Baden Baden','BW'),('DE','BAC','Backnang','Backnang','BW'),('DE','BAD','Baddeckenstedt','Baddeckenstedt','NI'),('DE','BAE','Barleben','Barleben','ST'),('DE','BAF','Barnstorf','Barnstorf','NI'),('DE','BAG','Bachhagel','Bachhagel','BY'),('DE','BAH','Bahratal','Bahratal','SN'),('DE','BAI','Bad Aibling','Bad Aibling','BY'),('DE','BAL','Balingen','Balingen','BW'),('DE','BAM','Bamberg','Bamberg','BY'),('DE','BAN','Bad Zwischenahn','Bad Zwischenahn','NI'),('DE','BAP','Barntrup','Barntrup','NW'),('DE','BAQ','Barenstein','Barenstein','NW'),('DE','BAR','Bargteheide','Bargteheide','SH'),('DE','BAS','Basbeck','Basbeck','NI'),('DE','BAT','Ballenstedt','Ballenstedt','ST'),('DE','BAU','Bautzen','Bautzen','SN'),('DE','BAW','Bad Worishofen','Bad Worishofen','BY'),('DE','BAX','Bad Alexandersbad','Bad Alexandersbad','BY'),('DE','BAY','Bayerbach','Bayerbach','BY'),('DE','BBA','Bad Blankenburg','Bad Blankenburg','TH'),('DE','BBB','Bad Bellingen','Bad Bellingen','BW'),('DE','BBC','Breidenbach','Breidenbach','HE'),('DE','BBE','Bad Berleburg','Bad Berleburg','NW'),('DE','BBG','Brandenburg','Brandenburg','BR'),('DE','BBH','Barth','Barth','MV'),('DE','BBI','Bietigheim-Bissingen','Bietigheim-Bissingen','BW'),('DE','BBK','Bersenbruck','Bersenbruck','NI'),('DE','BBL','Biblis','Biblis','HE'),('DE','BBN','Babenhausen','Babenhausen','HE'),('DE','BBO','Bad Boll','Bad Boll','BW'),('DE','BBR','Bad Brambach','Bad Brambach','SN'),('DE','BBU','Bad Bruckenau','Bad Bruckenau','BY'),('DE','BBV','Bad Bevensen','Bad Bevensen','NI'),('DE','BBW','Burbach','Burbach','RP'),('DE','BBX','Bad Berka','Bad Berka','TH'),('DE','BBY','Barby','Barby','ST'),('DE','BBZ','Bebitz','Bebitz','ST'),('DE','BCA','Brockhagen','Brockhagen','NW'),('DE','BCB','Buckeburg','Buckeburg','NI'),('DE','BCC','Bickenbach','Bickenbach','HE'),('DE','BCD','Burscheid','Burscheid','NW'),('DE','BCF','Barchfeld','Barchfeld','TH'),('DE','BCG','Berching','Berching','BY'),('DE','BCH','Buckenhof','Buckenhof','BY'),('DE','BCK','Bickendorf','Bickendorf','RP'),('DE','BCL','Bruchsal','Bruchsal','BW'),('DE','BCM','Brackenheim','Brackenheim','BW'),('DE','BCN','Burgkirchen','Burgkirchen','BY'),('DE','BCO','Bockholdt','Bockholdt','NI'),('DE','BCR','Bockhorn','Bockhorn','NI'),('DE','BCS','Buschhausen','Buschhausen','NW'),('DE','BCT','Borschutz','Borschutz','BR'),('DE','BCW','Brachwitz','Brachwitz','ST'),('DE','BCZ','Bucknitz','Bucknitz','BR'),('DE','BDA','Brodenbach','Brodenbach','RP'),('DE','BDB','Bad Bentheim','Bad Bentheim','NI'),('DE','BDC','Bad Camberg','Bad Camberg','HE'),('DE','BDD','Neu Buddenstedt','Neu Buddenstedt','NI'),('DE','BDE','Bad Elster','Bad Elster','SN'),('DE','BDF','Bendorf/Rhein','Bendorf/Rhein','RP'),('DE','BDG','Bedburg-Hau','Bedburg-Hau','NW'),('DE','BDH','Bad Harzburg','Bad Harzburg','NI'),('DE','BDI','Brandis','Brandis','SN'),('DE','BDK','Bad Krozingen','Bad Krozingen','BW'),('DE','BDM','Beindersheim','Beindersheim','RP'),('DE','BDN','Bodnegg','Bodnegg','BW'),('DE','BDO','Beckedorf','Beckedorf','NI'),('DE','BDR','Bad Driburg','Bad Driburg','NW'),('DE','BDS','Bad Schandau','Bad Schandau','SN'),('DE','BDT','Burstadt','Burstadt','HE'),('DE','BDU','Bad Durkheim','Bad Durkheim','RP'),('DE','BDW','Bad Windsheim','Bad Windsheim','BY'),('DE','BEA','Berne','Berne','NI'),('DE','BEB','Bebra','Bebra','HE'),('DE','BEC','Beckum','Beckum','NW'),('DE','BED','Bendorf','Bendorf','SH'),('DE','BEE','Bietigheim','Bietigheim','BW'),('DE','BEF','Brand-Erbisdorf','Brand-Erbisdorf','SN'),('DE','BEG','Berchtesgaden','Berchtesgaden','BY'),('DE','BEH','Bensheim','Bensheim','HE'),('DE','BEI','Beidenfleth','Beidenfleth','SH'),('DE','BEJ','Berghulen','Berghulen','BW'),('DE','BEK','Bernkastel-Kues','Bernkastel-Kues','RP'),('DE','BEL','Bellheim','Bellheim','RP'),('DE','BEM','Besigheim','Besigheim','BW'),('DE','BEN','Bensersiel','Bensersiel','NI'),('DE','BEO','Bornersdorf','Bornersdorf','SN'),('DE','BEQ','Bernburg','Bernburg','ST'),('DE','BER','Berlin','Berlin','BE'),('DE','BES','Bad Essen','Bad Essen','NI'),('DE','BET','Betzdorf','Betzdorf','RP'),('DE','BEU','Bullenhausen','Bullenhausen','NI'),('DE','BEV','Beverungen','Beverungen','NW'),('DE','BEW','Berka/Werra','Berka/Werra','TH'),('DE','BEX','Bexbach','Bexbach','SL'),('DE','BEZ','Bahlingen','Bahlingen','BW'),('DE','BFD','Buschfeld','Buschfeld','SL'),('DE','BFE','Bielefeld','Bielefeld','NW'),('DE','BFF','Boffzen','Boffzen','NI'),('DE','BFH','Bad Friedrichshall','Bad Friedrichshall','BW'),('DE','BFL','Borsfleth','Borsfleth','SH'),('DE','BFN','Bad Salzuflen','Bad Salzuflen','NW'),('DE','BFS','Bischofsheim','Bischofsheim','BY'),('DE','BFT','Baienfurt','Baienfurt','BW'),('DE','BFX','Breitenfelde','Breitenfelde','SH'),('DE','BGA','Berga','Berga','BR'),('DE','BGB','Gronenbach','Gronenbach','BY'),('DE','BGD','Bergedorf','Bergedorf','NI'),('DE','BGE','Bergen','Bergen','MV'),('DE','BGH','Bergheim-Westfalen','Bergheim-Westfalen','NW'),('DE','BGL','Bergisch Gladbach','Bergisch Gladbach','NW'),('DE','BGM','Bad Gandersheim','Bad Gandersheim','NI'),('DE','BGN','Barsinghausen','Barsinghausen','NI'),('DE','BGO','Bad Godesberg','Bad Godesberg','NW'),('DE','BGQ','Bruggen','Bruggen','NW'),('DE','BGR','Beilngries','Beilngries','BY'),('DE','BGT','Burgthann','Burgthann','BY'),('DE','BGU','Burgau','Burgau','BY'),('DE','BGV','Berlingerode','Berlingerode','TH'),('DE','BGX','Burg','Burg','ST'),('DE','BGZ','Berge','Berge','BR'),('DE','BHA','Borgholzhausen','Borgholzhausen','NW'),('DE','BHB','Buchbach','Buchbach','BY'),('DE','BHD','Baumholder','Baumholder','RP'),('DE','BHE','Bad Hersfeld','Bad Hersfeld','HE'),('DE','BHF','Bad Honnef','Bad Honnef','NW'),('DE','BHG','Birken-Honigsessen','Birken-Honigsessen','RP'),('DE','BHH','Bruchhausen','Bruchhausen','BW'),('DE','BHI','Bad Honningen','Bad Honningen','RP'),('DE','BHK','Bruchkobel','Bruchkobel','HE'),('DE','BHL','Buchlberg','Buchlberg','BY'),('DE','BHM','Bergheim','Bergheim','NW'),('DE','BHN','Burghausen','Burghausen','BY'),('DE','BHO','Bad Homburg','Bad Homburg','HE'),('DE','BHP','Berghaupten','Berghaupten','BW'),('DE','BHQ','Bahrenfeld','Bahrenfeld','HH'),('DE','BHR','Bobenheim-Roxheim','Bobenheim-Roxheim','RP'),('DE','BHS','Bodelshausen','Bodelshausen','BW'),('DE','BHT','Bocholt','Bocholt','NW'),('DE','BHU','Buchholz in der Nordheide','Buchholz in der Nordheide','NI'),('DE','BHV','Bruchhausen-Vilsen','Bruchhausen-Vilsen','NI'),('DE','BHW','Bruchweiler','Bruchweiler','RP'),('DE','BHX','Breitenheerda','Breitenheerda','TH'),('DE','BIA','Birkenau','Birkenau','HE'),('DE','BIB','Biberach','Biberach','BW'),('DE','BIC','Bildstock','Bildstock','SL'),('DE','BID','Bitterfeld','Bitterfeld','ST'),('DE','BIE','Biebesheim','Biebesheim','HE'),('DE','BIG','Biebergemund','Biebergemund','HE'),('DE','BIH','Biessenhofen','Biessenhofen','BY'),('DE','BII','Breitenstein','Breitenstein','BW'),('DE','BIK','Bismark','Bismark','MV'),('DE','BIL','Billerbeck','Billerbeck','NW'),('DE','BIM','Bischofsheim','Bischofsheim','HE'),('DE','BIN','Bingen','Bingen','RP'),('DE','BIR','Birkenfeld','Birkenfeld','RP'),('DE','BIS','Bischweier','Bischweier','BW'),('DE','BIT','Bitburg','Bitburg','RP'),('DE','BIU','Rechenberg-Bienenmuhle','Rechenberg-Bienenmuhle','SN'),('DE','BIW','Bindow','Bindow','BR'),('DE','BIZ','Binzen','Binzen','BW'),('DE','BKA','Bad Karlshafen','Bad Karlshafen','HE'),('DE','BKB','Bruckberg','Bruckberg','BY'),('DE','BKC','Bromskirchen','Bromskirchen','HE'),('DE','BKE','Brake','Brake','NI'),('DE','BKF','Biedenkopf','Biedenkopf','HE'),('DE','BKG','Blankenburg','Blankenburg','ST'),('DE','BKH','Bockhorst','Bockhorst','NI'),('DE','BKI','Bad Kissingen','Bad Kissingen','BY'),('DE','BKK','Brakel','Brakel','NW'),('DE','BKL','Berkatal','Berkatal','HE'),('DE','BKM','Bruckmuhl','Bruckmuhl','BY'),('DE','BKN','Bergkamen','Bergkamen','NW'),('DE','BKO','Bad Konigshofen','Bad Konigshofen','BY'),('DE','BKR','Bad Kreuznach','Bad Kreuznach','RP'),('DE','BKT','Burgkunstadt','Burgkunstadt','BY'),('DE','BKU','Bucha','Bucha','TH'),('DE','BKW','Beeskow','Beeskow','BR'),('DE','BLA','Bad Laer','Bad Laer','NI'),('DE','BLB','Bad Lauterberg','Bad Lauterberg','NI'),('DE','BLD','Burglengenfeld','Burglengenfeld','BY'),('DE','BLE','Blaubeuren','Blaubeuren','BW'),('DE','BLF','Blaufelden','Blaufelden','BW'),('DE','BLG','Brieselang','Brieselang','BR'),('DE','BLH','Bindlach','Bindlach','BY'),('DE','BLK','Blankenhain','Blankenhain','TH'),('DE','BLM','Blumenthal','Blumenthal','HB'),('DE','BLN','Buttelborn','Buttelborn','HE'),('DE','BLO','Buchloe','Buchloe','BY'),('DE','BLS','Blaustein','Blaustein','BW'),('DE','BLT','Buhlertal','Buhlertal','BW'),('DE','BLU','Blumberg','Blumberg','BW'),('DE','BLW','Bodman','Bodman','BW'),('DE','BMA','Bad Marienberg','Bad Marienberg','RP'),('DE','BMB','Baumbach','Baumbach','RP'),('DE','BME','Bad Mergentheim','Bad Mergentheim','BW'),('DE','BMG','Blomberg','Blomberg','NW'),('DE','BMH','Bruchmuhlbach-Miesau','Bruchmuhlbach-Miesau','RP'),('DE','BMK','Borkum','Borkum','NI'),('DE','BML','Bad Munstereifel','Bad Munstereifel','NW'),('DE','BMN','Bermatingen','Bermatingen','BW'),('DE','BMO','Borgemoor','Borgemoor','NI'),('DE','BMP','Bempflingen','Bempflingen','BW'),('DE','BMR','Baltrum','Baltrum','NI'),('DE','BMT','Barmstedt','Barmstedt','SH'),('DE','BMU','Bad Munder','Bad Munder','NI'),('DE','BMV','Bremervorde','Bremervorde','NI'),('DE','BNA','Bad Nauheim','Bad Nauheim','HE'),('DE','BNB','Berneburg','Berneburg','HE'),('DE','BND','Brand','Brand','BY'),('DE','BNE','Bad Neustadt','Bad Neustadt','BY'),('DE','BNG','Bretnig','Bretnig','SN'),('DE','BNH','Badenhausen','Badenhausen','NI'),('DE','BNK','Brink','Brink','NI'),('DE','BNL','Bad Soden-Salmunster','Bad Soden-Salmunster','HE'),('DE','BNM','Bubenheim','Bubenheim','BY'),('DE','BNN','Bonen','Bonen','NW'),('DE','BNO','Berg bei Neumarkt in der Oberpfalz','Berg bei Neumarkt in der Oberpfalz','RP'),('DE','BNR','Bad Neuenahr-Ahrweiler','Bad Neuenahr-Ahrweiler','RP'),('DE','BNS','Bernsdorf','Bernsdorf','BR'),('DE','BNT','Bergneustadt','Bergneustadt','NW'),('DE','BNU','Breitenau','Breitenau','RP'),('DE','BNV','Bornhoved','Bornhoved','SH'),('DE','BNW','Buttenwiesen','Buttenwiesen','BY'),('DE','BNZ','Banteln','Banteln','NI'),('DE','BOA','Bogen','Bogen','BY'),('DE','BOB','Bobingen','Bobingen','BY'),('DE','BOC','Bockhorst','Bockhorst','NW'),('DE','BOD','Boppard','Boppard','RP'),('DE','BOE','Boblingen','Boblingen','BW'),('DE','BOF','Berndshof','Berndshof','MV'),('DE','BOG','Bochingen','Bochingen','RP'),('DE','BOH','Bohmte','Bohmte','NI'),('DE','BOK','Bokel','Bokel','NI'),('DE','BOL','Bad Oldesloe','Bad Oldesloe','SH'),('DE','BOM','Bochum','Bochum','NW'),('DE','BON','Bonn','Bonn','NW'),('DE','BOO','Bondorf','Bondorf','BW'),('DE','BOP','Bopfingen','Bopfingen','BW'),('DE','BOQ','Boden','Boden','RP'),('DE','BOR','Borken','Borken','NW'),('DE','BOT','Bottrop','Bottrop','NW'),('DE','BOV','Bovenden','Bovenden','NI'),('DE','BOX','Borna','Borna','SN'),('DE','BOY','Bad Oeynhausen','Bad Oeynhausen','NW'),('DE','BOZ','Bobzin','Bobzin','MV'),('DE','BPA','Ubach-Palenberg','Ubach-Palenberg','NW'),('DE','BPF','Burrweiler','Burrweiler','RP'),('DE','BPP','Bad Rappenau','Bad Rappenau','BW'),('DE','BPT','Bad Peterstal-Griesbach','Bad Peterstal-Griesbach','BW'),('DE','BPY','Bad Pyrmont','Bad Pyrmont','NI'),('DE','BPZ','Biebelnheim','Biebelnheim','RP'),('DE','BRA','Bramel','Bramel','NI'),('DE','BRB','Brunsbuttel','Brunsbuttel','SH'),('DE','BRC','Brachttal','Brachttal','HE'),('DE','BRD','Briedern','Briedern','RP'),('DE','BRE','Bremen','Bremen','HB'),('DE','BRF','Brebach-Fechingen','Brebach-Fechingen','SL'),('DE','BRG','Burg/Dithmarschen','Burg/Dithmarschen','SH'),('DE','BRH','Bad Reichenhall','Bad Reichenhall','BY'),('DE','BRI','Brilon','Brilon','NW'),('DE','BRK','Barnkrug','Barnkrug','NI'),('DE','BRL','Borstel, Diepholz','Borstel, Diepholz','NI'),('DE','BRM','Bramsche','Bramsche','NI'),('DE','BRN','Bornsen','Bornsen','SH'),('DE','BRO','Brohl-Lutzing','Brohl-Lutzing','RP'),('DE','BRP','Bad Rippoldsau-Schapbach','Bad Rippoldsau-Schapbach','BW'),('DE','BRR','Baiersbronn','Baiersbronn','BW'),('DE','BRS','Birstein','Birstein','HE'),('DE','BRT','Breitenberg','Breitenberg','BY'),('DE','BRU','Bruhl','Bruhl','NW'),('DE','BRV','Bremerhaven','Bremerhaven','HB'),('DE','BRW','Bracht','Bracht','NW'),('DE','BRX','Breitungen','Breitungen','TH'),('DE','BRY','Braunlingen','Braunlingen','BW'),('DE','BRZ','Bretzenheim','Bretzenheim','RP'),('DE','BSA','Bad Sackingen','Bad Sackingen','BW'),('DE','BSB','Barsbuttel','Barsbuttel','SH'),('DE','BSC','Bad Sachsa','Bad Sachsa','NI'),('DE','BSD','Burscheid','Burscheid','RP'),('DE','BSE','Bad Segeberg','Bad Segeberg','SH'),('DE','BSF','Bad Salzdetfurth','Bad Salzdetfurth','NI'),('DE','BSH','Breisach','Breisach','BW'),('DE','BSI','Bubsheim','Bubsheim','BW'),('DE','BSK','Burgstaaken/Fehmarn','Burgstaaken/Fehmarn','SH'),('DE','BSM','Bassum','Bassum','NI'),('DE','BSN','Bad Schonborn','Bad Schonborn','BW'),('DE','BSO','Bad Soden am Taunus','Bad Soden am Taunus','HE'),('DE','BSQ','Buseck','Buseck','HE'),('DE','BSR','Bad Schussenried','Bad Schussenried','BW'),('DE','BSS','Bessenbach','Bessenbach','BY'),('DE','BSU','Bad Schwartau','Bad Schwartau','SH'),('DE','BSW','Baesweiler','Baesweiler','NW'),('DE','BSZ','Bad Salzungen','Bad Salzungen','TH'),('DE','BTA','Bortfeld','Bortfeld','NI'),('DE','BTB','Burtenbach','Burtenbach','BY'),('DE','BTC','Bodenteich','Bodenteich','NI'),('DE','BTD','Burgstadt','Burgstadt','BY'),('DE','BTE','Breitscheid','Breitscheid','HE'),('DE','BTF','Brahlstorf','Brahlstorf','MV'),('DE','BTG','Breitenburg','Breitenburg','SH'),('DE','BTH','Bammental','Bammental','BW'),('DE','BTI','Bertingen','Bertingen','ST'),('DE','BTL','Baunatal','Baunatal','HE'),('DE','BTM','Bechtheim','Bechtheim','RP'),('DE','BTN','Bretten','Bretten','BW'),('DE','BTO','Bad Tolz','Bad Tolz','BY'),('DE','BTR','Brotterode','Brotterode','TH'),('DE','BTS','Beltershausen','Beltershausen','HE'),('DE','BTT','Barnstadt','Barnstadt','ST'),('DE','BTU','Breitenbrunn','Breitenbrunn','BY'),('DE','BTW','Bentwisch','Bentwisch','MV'),('DE','BTZ','Botzingen','Botzingen','BW'),('DE','BUA','Baunach','Baunach','BY'),('DE','BUB','Bubingen','Bubingen','SL'),('DE','BUC','Buchen','Buchen','BW'),('DE','BUD','Budenheim','Budenheim','RP'),('DE','BUE','Bunde','Bunde','NW'),('DE','BUF','Burkhardtsdorf','Burkhardtsdorf','SN'),('DE','BUG','Breuberg','Breuberg','HE'),('DE','BUH','Burbach/Siegen','Burbach/Siegen','NW'),('DE','BUI','Burgbrohl','Burgbrohl','RP'),('DE','BUK','Bad Uberkingen','Bad Uberkingen','BW'),('DE','BUL','Buhl','Buhl','BW'),('DE','BUM','Busum','Busum','SH'),('DE','BUN','Budingen','Budingen','HE'),('DE','BUO','Braunsdorf','Braunsdorf','SN'),('DE','BUQ','Buren','Buren','NW'),('DE','BUR','Burg bei Magdeburg','Burg bei Magdeburg','ST'),('DE','BUS','Burgstetten','Burgstetten','BW'),('DE','BUT','Butjadingen','Butjadingen','NI'),('DE','BUU','Braunau','Braunau','HE'),('DE','BUX','Buxtehude','Buxtehude','NI'),('DE','BUZ','Butzfleth','Butzfleth','NI'),('DE','BVG','Bodenkirchen','Bodenkirchen','BY'),('DE','BVI','Bad Vilbel','Bad Vilbel','HE'),('DE','BVN','Bevern','Bevern','SH'),('DE','BWB','Bad Wildbad','Bad Wildbad','BW'),('DE','BWD','Bischofswerda','Bischofswerda','SN'),('DE','BWE','Braunschweig','Braunschweig','NI'),('DE','BWF','Bad Wimpfen','Bad Wimpfen','BW'),('DE','BWG','Bestwig','Bestwig','NW'),('DE','BWH','Burgwindheim','Burgwindheim','BY'),('DE','BWI','Bad Wildungen','Bad Wildungen','HE'),('DE','BWK','Bisingen','Bisingen','BW'),('DE','BWL','Burgwedel','Burgwedel','NI'),('DE','BWN','Bockwen','Bockwen','SN'),('DE','BWR','Bodenwerder','Bodenwerder','NI'),('DE','BWS','Bad Waldsee','Bad Waldsee','BW'),('DE','BXB','Boxberg','Boxberg','BW'),('DE','BXE','Buxheim, Unterallgau','Buxheim, Unterallgau','BY'),('DE','BXH','Bornheim','Bornheim','NW'),('DE','BXN','Blexen','Blexen','NI'),('DE','BXR','Baruth','Baruth','BR'),('DE','BXX','Bernried','Bernried','BW'),('DE','BYR','Bergen','Bergen','NI'),('DE','BYS','Schwebheim','Schwebheim','BY'),('DE','BYU','Bayreuth','Bayreuth','BY'),('DE','BZF','Bretzfeld','Bretzfeld','BW'),('DE','BZG','Belzig','Belzig','BR'),('DE','BZH','Butzbach','Butzbach','HE'),('DE','BZN','Bad Bergzabern','Bad Bergzabern','RP'),('DE','BZS','Beddingen','Beddingen','NI'),('DE','CAL','Calw','Calw','BW'),('DE','CAN','Calden','Calden','HE'),('DE','CAO','Cadolzburg','Cadolzburg','BY'),('DE','CAP','Cappeln','Cappeln','NI'),('DE','CAR','Carolinensiel','Carolinensiel','NI'),('DE','CBE','Colbe','Colbe','HE'),('DE','CDE','Palzem','Palzem','RP'),('DE','CEL','Celle','Celle','NI'),('DE','CGL','Creglingen','Creglingen','BW'),('DE','CGN','Koln','Koln','NW'),('DE','CGS','Camburg','Camburg','TH'),('DE','CHA','Cham','Cham','BY'),('DE','CHE','Chemnitz','Chemnitz','SN'),('DE','CHI','Chiemsee','Chiemsee','BY'),('DE','CHO','Schondra','Schondra','BY'),('DE','CHZ','Clarholz','Clarholz','NW'),('DE','CKH','Blankenheim','Blankenheim','NW'),('DE','CLK','Glienicke','Glienicke','BR'),('DE','CLO','Cloppenburg','Cloppenburg','NI'),('DE','CMU','Crimmitschau','Crimmitschau','SN'),('DE','CNZ','Claussnitz','Claussnitz','SN'),('DE','COB','Coburg','Coburg','BY'),('DE','COC','Cochem','Cochem','RP'),('DE','COF','Coesfeld','Coesfeld','NW'),('DE','CON','Conow','Conow','MV'),('DE','COT','Cottbus','Cottbus','BR'),('DE','CPZ','Copitz','Copitz','SN'),('DE','CRH','Crailsheim','Crailsheim','BW'),('DE','CRK','Crock','Crock','TH'),('DE','CRL','Castrop-Rauxel','Castrop-Rauxel','NW'),('DE','CUL','Clausthal','Clausthal','NI'),('DE','CUX','Cuxhaven','Cuxhaven','NI'),('DE','CUZ','Buchholz','Buchholz','NI'),('DE','CWE','Cunewalde','Cunewalde','SN'),('DE','CWG','Coswig','Coswig','SN'),('DE','DAC','Dachau','Dachau','BY'),('DE','DAF','Dampfach','Dampfach','BY'),('DE','DAG','Dagebull','Dagebull','SH'),('DE','DAH','Dahlen','Dahlen','SN'),('DE','DAM','Damme','Damme','NI'),('DE','DAN','Dangast','Dangast','NI'),('DE','DAP','Damp','Damp','SH'),('DE','DAR','Darmstadt','Darmstadt','HE'),('DE','DAT','Datteln','Datteln','NW'),('DE','DAU','Daun','Daun','RP'),('DE','DBA','Diebach','Diebach','BY'),('DE','DBG','Dornburg','Dornburg','ST'),('DE','DBL','Dinkelsbuhl','Dinkelsbuhl','BY'),('DE','DBR','Dobern','Dobern','BR'),('DE','DBU','Dolbau','Dolbau','ST'),('DE','DCG','Dischingen','Dischingen','BW'),('DE','DCH','Bacharach','Bacharach','RP'),('DE','DDD','Letmathe','Letmathe','NW'),('DE','DDM','Deidesheim','Deidesheim','RP'),('DE','DDT','Dingelstadt','Dingelstadt','TH'),('DE','DEF','Dabendorf','Dabendorf','BE'),('DE','DEG','Deggendorf','Deggendorf','BY'),('DE','DEH','Dexheim','Dexheim','RP'),('DE','DEI','Deisenhofen','Deisenhofen','BY'),('DE','DEK','Delbruck','Delbruck','NW'),('DE','DEL','Delmenhorst','Delmenhorst','NI'),('DE','DEN','Donaueschingen','Donaueschingen','BW'),('DE','DEP','Prisdorf','Prisdorf','SH'),('DE','DER','Dernbach bei Montabaur','Dernbach bei Montabaur','RP'),('DE','DES','Dessau/Anhalt','Dessau/Anhalt','ST'),('DE','DET','Detmold','Detmold','NW'),('DE','DEU','Dernau','Dernau','RP'),('DE','DEZ','Diez','Diez','RP'),('DE','DFG','Dingolfing','Dingolfing','BY'),('DE','DFS','Dorfles','Dorfles','BY'),('DE','DFX','Niederdollendorf','Niederdollendorf','NW'),('DE','DGA','Deggenau','Deggenau','BY'),('DE','DGN','Dingen','Dingen','SH'),('DE','DHG','Derching','Derching','BY'),('DE','DHL','Dietzholztal','Dietzholztal','HE'),('DE','DHN','Dahn','Dahn','RP'),('DE','DHU','Huckingen','Huckingen','NW'),('DE','DIB','Dillenburg','Dillenburg','HE'),('DE','DIE','Dietzenbach','Dietzenbach','HE'),('DE','DIG','Dieburg','Dieburg','HE'),('DE','DIH','Diefenbach','Diefenbach','RP'),('DE','DIL','Dillingen','Dillingen','SL'),('DE','DIN','Dinslaken','Dinslaken','NW'),('DE','DIR','Dierdorf','Dierdorf','RP'),('DE','DIS','Dissen','Dissen','NI'),('DE','DIT','Ditzum','Ditzum','NI'),('DE','DIZ','Diepholz','Diepholz','NI'),('DE','DKE','Denklingen','Denklingen','BY'),('DE','DKF','Denkendorf','Denkendorf','BW'),('DE','DKG','Dinklage','Dinklage','NI'),('DE','DKN','Dulken','Dulken','NW'),('DE','DLA','Durrlauingen','Durrlauingen','BY'),('DE','DLB','Dahlenburg','Dahlenburg','NI'),('DE','DLF','Altendorf','Altendorf','BY'),('DE','DLG','Dillingen','Dillingen','HE'),('DE','DLH','Delitzsch','Delitzsch','SN'),('DE','DLI','Deisslingen','Deisslingen','BW'),('DE','DLN','Delligsen','Delligsen','NI'),('DE','DLW','Dallgow','Dallgow','BE'),('DE','DMG','Dormagen','Dormagen','NW'),('DE','DMH','Dommershausen','Dommershausen','RP'),('DE','DMN','Demmin','Demmin','MV'),('DE','DMT','Durmentingen','Durmentingen','BW'),('DE','DNG','Dannenberg','Dannenberg','NI'),('DE','DNH','Dettenheim','Dettenheim','BW'),('DE','DNM','Dietenheim','Dietenheim','BW'),('DE','DNN','Densborn','Densborn','RP'),('DE','DNR','Derenburg','Derenburg','ST'),('DE','DNS','Dannstadt-Schauernheim','Dannstadt-Schauernheim','RP'),('DE','DNT','Dorenthe','Dorenthe','NW'),('DE','DNU','Donautal','Donautal','BW'),('DE','DOB','Dornbusch','Dornbusch','NI'),('DE','DOE','Dobeln','Dobeln','SN'),('DE','DOF','Dorfen','Dorfen','BY'),('DE','DOG','Dogern','Dogern','BW'),('DE','DOH','Dorgenhausen','Dorgenhausen','SN'),('DE','DOK','Doberlug-Kirchhain','Doberlug-Kirchhain','BR'),('DE','DON','Dorsten','Dorsten','NW'),('DE','DOR','Dornburg','Dornburg','HE'),('DE','DOW','Donauworth','Donauworth','BY'),('DE','DOZ','Doberitz','Doberitz','BR'),('DE','DPL','Dautphetal','Dautphetal','HE'),('DE','DPN','Dorfprozelten','Dorfprozelten','BY'),('DE','DPW','Dippoldiswalde','Dippoldiswalde','SN'),('DE','DRA','Dranske','Dranske','MV'),('DE','DRB','Drubber','Drubber','NI'),('DE','DRC','Durach','Durach','BY'),('DE','DRE','Dreieich','Dreieich','HE'),('DE','DRF','Driedorf','Driedorf','HE'),('DE','DRH','Dorth','Dorth','RP'),('DE','DRL','Drolshagen','Drolshagen','NW'),('DE','DRO','Drochtersen','Drochtersen','NI'),('DE','DRP','Dorpen','Dorpen','NI'),('DE','DRS','Dresden','Dresden','SN'),('DE','DRZ','Dietramszell','Dietramszell','BY'),('DE','DSC','Dinkelscherben','Dinkelscherben','BY'),('DE','DSG','Dasing','Dasing','BY'),('DE','DSL','Dassel','Dassel','NI'),('DE','DSM','Dossenheim','Dossenheim','BW'),('DE','DSN','Dornstetten','Dornstetten','BW'),('DE','DST','Dornstadt','Dornstadt','BW'),('DE','DTB','Dettelbach','Dettelbach','BY'),('DE','DTG','Dettingen','Dettingen','BW'),('DE','DTH','Dietenhofen','Dietenhofen','BY'),('DE','DTM','Dortmund','Dortmund','NW'),('DE','DTN','Ditzingen','Ditzingen','BW'),('DE','DTP','Dorentrup','Dorentrup','NW'),('DE','DUD','Duderstadt','Duderstadt','NI'),('DE','DUE','Duren','Duren','NW'),('DE','DUG','Dauchingen','Dauchingen','BW'),('DE','DUI','Duisburg','Duisburg','NW'),('DE','DUL','Dusslingen','Dusslingen','BW'),('DE','DUN','Dulmen','Dulmen','NW'),('DE','DUR','Durbach','Durbach','BW'),('DE','DUS','Dusseldorf','Dusseldorf','NW'),('DE','DVE','Dorverden','Dorverden','NI'),('DE','DWB','Dahlenwarsleben','Dahlenwarsleben','ST'),('DE','DWE','Dockweiler','Dockweiler','RP'),('DE','DWH','Dahlwitz-Hoppegarten','Dahlwitz-Hoppegarten','BR'),('DE','DWO','Walddorfhaslach','Walddorfhaslach','BW'),('DE','DWR','Dudweiler','Dudweiler','SL'),('DE','DYK','Dyckhausen','Dyckhausen','NI'),('DE','DYN','Dunsen','Dunsen','NI'),('DE','DZD','Donzdorf','Donzdorf','BW'),('DE','DZN','Denzlingen','Denzlingen','BW'),('DE','DZR','Salzbergen','Salzbergen','NI'),('DE','DZU','Deizisau','Deizisau','BW'),('DE','EAH','Ebernhahn','Ebernhahn','RP'),('DE','EAM','Erlenbach am Main','Erlenbach am Main','BY'),('DE','EAN','Eslarn','Eslarn','BY'),('DE','EAS','Eging am See','Eging am See','BY'),('DE','EBA','Eschbach','Eschbach','BW'),('DE','EBB','Eberbach','Eberbach','BW'),('DE','EBD','Engelsbrand','Engelsbrand','BW'),('DE','EBE','Ebersbach an der Fils','Ebersbach an der Fils','BW'),('DE','EBG','Eisenberg','Eisenberg','RP'),('DE','EBH','Erlenbach','Erlenbach','BW'),('DE','EBM','Ebermannstadt','Ebermannstadt','BY'),('DE','EBO','Ebersdorf','Ebersdorf','BY'),('DE','EBR','Ebrach','Ebrach','BY'),('DE','EBS','Erbach','Erbach','BW'),('DE','EBT','Eibelstadt','Eibelstadt','BY'),('DE','EBU','Ettenbeuren','Ettenbeuren','BY'),('DE','EBW','Eberswalde','Eberswalde','BR'),('DE','EBX','Essenbach','Essenbach','BY'),('DE','EBY','Ebern','Ebern','BY'),('DE','EBZ','Eberdingen','Eberdingen','BW'),('DE','ECH','Eching/Freising','Eching/Freising','BY'),('DE','ECI','Eich','Eich','RP'),('DE','ECK','Eckernforde','Eckernforde','SH'),('DE','EDB','Edersberg','Edersberg','BY'),('DE','EDD','Eiderdeich','Eiderdeich','SH'),('DE','EDE','Edesheim','Edesheim','RP'),('DE','EDF','Erbendorf','Erbendorf','BY'),('DE','EDG','Eimeldingen','Eimeldingen','BW'),('DE','EDH','Ederheim','Ederheim','BY'),('DE','EDI','Edingen','Edingen','BW'),('DE','EDL','Edling','Edling','BY'),('DE','EDM','Edemissen','Edemissen','NI'),('DE','EDN','Emsdetten','Emsdetten','NW'),('DE','EDO','Ensdorf','Ensdorf','SL'),('DE','EDT','Edewecht','Edewecht','NI'),('DE','EEG','Ebersberg','Ebersberg','BY'),('DE','EEN','Essen','Essen','NI'),('DE','EFD','Ebensfeld','Ebensfeld','BY'),('DE','EFG','Empfingen','Empfingen','BW'),('DE','EFK','Efringen-Kirchen','Efringen-Kirchen','BW'),('DE','EFL','Effelder','Effelder','TH'),('DE','EGB','Egelsbach','Egelsbach','HE'),('DE','EGC','Eching/Landshut','Eching/Landshut','BY'),('DE','EGD','Ergolding','Ergolding','BY'),('DE','EGE','Eggingen','Eggingen','BW'),('DE','EGG','Eggenfelden','Eggenfelden','BY'),('DE','EGH','Eggenthal','Eggenthal','BY'),('DE','EGI','Sankt Egidien','Sankt Egidien','SN'),('DE','EGL','Eggenstein-Leopoldshafen','Eggenstein-Leopoldshafen','BW'),('DE','EGN','Essingen','Essingen','BW'),('DE','EGS','Eggstatt','Eggstatt','BY'),('DE','EGT','Engstingen','Engstingen','BW'),('DE','EHA','Einhausen','Einhausen','HE'),('DE','EHC','Eschach','Eschach','BW'),('DE','EHE','Eslohe','Eslohe','NW'),('DE','EHF','Einsiedlerhof','Einsiedlerhof','RP'),('DE','EHG','Ehningen','Ehningen','BW'),('DE','EHH','Emlichheim','Emlichheim','NI'),('DE','EHI','Ehingen','Ehingen','BW'),('DE','EHM','Senheim','Senheim','RP'),('DE','EHN','Ebenhofen','Ebenhofen','BY'),('DE','EHR','Ehringshausen/Lahn-Dill','Ehringshausen/Lahn-Dill','HE'),('DE','EHS','Eisenhuttenstadt','Eisenhuttenstadt','BR'),('DE','EHZ','Eichenzell','Eichenzell','HE'),('DE','EIB','Einbeck','Einbeck','NI'),('DE','EIC','Eichstatt','Eichstatt','BY'),('DE','EID','Eisfeld','Eisfeld','TH'),('DE','EIE','Elgersweier','Elgersweier','BW'),('DE','EIF','Eitorf','Eitorf','NW'),('DE','EIH','Eimbeckhausen','Eimbeckhausen','NI'),('DE','EIM','Eimke','Eimke','NI'),('DE','EIN','Eisleben','Eisleben','ST'),('DE','EIS','Eisenach','Eisenach','TH'),('DE','EKI','Engelskirchen','Engelskirchen','NW'),('DE','EKN','Edenkoben','Edenkoben','RP'),('DE','EKR','Emskirchen','Emskirchen','BY'),('DE','ELA','Ellenberg','Ellenberg','RP'),('DE','ELB','Ellerbek','Ellerbek','SH'),('DE','ELC','Elchingen','Elchingen','BY'),('DE','ELD','Nohfelden','Nohfelden','SL'),('DE','ELE','Selters, Taunus','Selters, Taunus','HE'),('DE','ELF','Elsenfeld','Elsenfeld','BY'),('DE','ELG','Belgern','Belgern','SN'),('DE','ELI','Emmingen-Liptingen','Emmingen-Liptingen','BW'),('DE','ELK','Ecklak','Ecklak','SH'),('DE','ELL','Elztal','Elztal','BW'),('DE','ELM','Elmshorn','Elmshorn','SH'),('DE','ELN','Eislingen','Eislingen','BW'),('DE','ELS','Elsfleth','Elsfleth','NI'),('DE','ELT','Elterlein','Elterlein','SN'),('DE','ELU','Ellerau','Ellerau','SH'),('DE','ELW','Ellwangen','Ellwangen','BW'),('DE','ELX','Elxleben','Elxleben','TH'),('DE','ELZ','Elze','Elze','NI'),('DE','EMB','Embsen','Embsen','NI'),('DE','EME','Emden','Emden','NI'),('DE','EMG','Emmering','Emmering','BY'),('DE','EML','Emlichheim','Emlichheim','NI'),('DE','EMM','Emmerich','Emmerich','NW'),('DE','EMN','Emmendingen','Emmendingen','BW'),('DE','EMS','Emsburen','Emsburen','NI'),('DE','ENA','Brehna','Brehna','ST'),('DE','ENB','Eilenburg','Eilenburg','SN'),('DE','END','Endingen','Endingen','BW'),('DE','ENE','Engen','Engen','BW'),('DE','ENG','Engter','Engter','NI'),('DE','ENH','Ennigerloh','Ennigerloh','NW'),('DE','ENM','Ensheim','Ensheim','RP'),('DE','ENN','Ennepetal','Ennepetal','NW'),('DE','ENP','Parsit','Parsit','NW'),('DE','ENR','Enger','Enger','NW'),('DE','ENS','Ense','Ense','NW'),('DE','ENT','Ernstthal','Ernstthal','TH'),('DE','ENX','Elben','Elben','ST'),('DE','ENZ','Benz','Benz','MV'),('DE','EPA','Eppertshausen','Eppertshausen','HE'),('DE','EPB','Eppelborn','Eppelborn','SL'),('DE','EPI','Eppingen','Eppingen','BW'),('DE','EPP','Eppelheim','Eppelheim','BW'),('DE','EPS','Eppstein','Eppstein','HE'),('DE','ERB','Erbach/Odenwald','Erbach/Odenwald','HE'),('DE','ERD','Erdweg','Erdweg','BY'),('DE','ERE','Erlensee','Erlensee','HE'),('DE','ERF','Erfurt','Erfurt','TH'),('DE','ERG','Erding','Erding','BY'),('DE','ERH','Erkrath','Erkrath','NW'),('DE','ERK','Erkelenz','Erkelenz','NW'),('DE','ERL','Erlangen','Erlangen','BY'),('DE','ERM','Erdmannhausen','Erdmannhausen','BW'),('DE','ERN','Erndtebruck','Erndtebruck','NW'),('DE','ERR','Durrholz','Durrholz','RP'),('DE','ERS','Ellerstadt','Ellerstadt','RP'),('DE','ERT','Erftstadt','Erftstadt','NW'),('DE','ERW','Erwitte','Erwitte','NW'),('DE','ERZ','Erzhausen','Erzhausen','HE'),('DE','ESB','Eilsbrunn','Eilsbrunn','BY'),('DE','ESC','Eschborn','Eschborn','HE'),('DE','ESD','Elsdorf','Elsdorf','NW'),('DE','ESE','Eschenlohe','Eschenlohe','BY'),('DE','ESF','Estorf/Weser','Estorf/Weser','NI'),('DE','ESG','Eschenburg','Eschenburg','HE'),('DE','ESH','Eschenbach','Eschenbach','BY'),('DE','ESI','Eresing','Eresing','BY'),('DE','ESL','Esslingen','Esslingen','BW'),('DE','ESN','Eschershausen','Eschershausen','NI'),('DE','ESP','Espelkamp','Espelkamp','NW'),('DE','ESR','Eschweiler','Eschweiler','NW'),('DE','ESS','Essen','Essen','NW'),('DE','EST','Eichstetten','Eichstetten','BW'),('DE','ESU','Emmelsum','Emmelsum','NW'),('DE','ESW','Eschwege','Eschwege','HE'),('DE','ETB','Elsterberg','Elsterberg','SN'),('DE','ETG','Eutingen','Eutingen','BW'),('DE','ETI','Ettenheim','Ettenheim','BW'),('DE','ETM','Eltmann','Eltmann','BY'),('DE','ETN','Elten','Elten','NW'),('DE','ETO','Ebstorf','Ebstorf','NI'),('DE','ETR','Ettringen','Ettringen','BY'),('DE','ETT','Ettlingen','Ettlingen','BW'),('DE','ETZ','Etzbach','Etzbach','RP'),('DE','EUS','Euskirchen','Euskirchen','NW'),('DE','EUT','Eutin','Eutin','SH'),('DE','EVI','Eltville','Eltville','HE'),('DE','EWA','Elsterwerda','Elsterwerda','BR'),('DE','EWH','Eckwarderhorne','Eckwarderhorne','NI'),('DE','EWL','Esseratsweiler','Esseratsweiler','BW'),('DE','EYP','Eystrup','Eystrup','NI'),('DE','EZH','Elzach','Elzach','BW'),('DE','EZL','Elz','Elz','HE'),('DE','FAC','Farchant','Farchant','BY'),('DE','FAL','Fallingbostel','Fallingbostel','NI'),('DE','FAR','Falkenrehde','Falkenrehde','BR'),('DE','FBE','Friedberg','Friedberg','BY'),('DE','FBG','Freiburg im Breisgau','Freiburg im Breisgau','BW'),('DE','FBH','Fellbach','Fellbach','BW'),('DE','FBK','Fuldabruck','Fuldabruck','HE'),('DE','FCI','Fachingen','Fachingen','RP'),('DE','FDB','Frondenberg','Frondenberg','NW'),('DE','FDG','Fridingen','Fridingen','BW'),('DE','FDH','Friedrichshafen','Friedrichshafen','BW'),('DE','FDM','Friedelsheim','Friedelsheim','RP'),('DE','FDN','Freden','Freden','NI'),('DE','FDS','Friedrichsschleuse','Friedrichsschleuse','NI'),('DE','FEG','Freiberg am Neckar','Freiberg am Neckar','BW'),('DE','FEI','Freilingen','Freilingen','RP'),('DE','FEL','Furstenfeldbruck','Furstenfeldbruck','BY'),('DE','FEN','Greifenberg','Greifenberg','BY'),('DE','FEU','Feucht','Feucht','BY'),('DE','FEW','Feuchtwangen','Feuchtwangen','BY'),('DE','FFD','Furfeld','Furfeld','RP'),('DE','FFI','Feldafing','Feldafing','BY'),('DE','FFO','Frankfurt/Oder','Frankfurt/Oder','BR'),('DE','FGB','Freudenberg','Freudenberg','NW'),('DE','FGD','Feldgeding','Feldgeding','BY'),('DE','FHB','Fischbach','Fischbach','BW'),('DE','FHI','Flonheim','Flonheim','RP'),('DE','FHM','Fellheim','Fellheim','BY'),('DE','FHN','Fohren','Fohren','RP'),('DE','FHU','Fischerhutte','Fischerhutte','SH'),('DE','FIB','Friedeburg','Friedeburg','NI'),('DE','FIC','Fichtelberg','Fichtelberg','BY'),('DE','FIG','Freiberg','Freiberg','SN'),('DE','FIH','Fichtenau','Fichtenau','BW'),('DE','FIL','Filderstadt','Filderstadt','BW'),('DE','FIN','Gundelfingen','Gundelfingen','BY'),('DE','FIO','Friolzheim','Friolzheim','BW'),('DE','FIS','Fischach','Fischach','BY'),('DE','FIT','Finnentrop','Finnentrop','NW'),('DE','FIW','Finsterwalde/Niederlausitz','Finsterwalde/Niederlausitz','BR'),('DE','FIZ','Foeritz','Foeritz','TH'),('DE','FKG','Frankenberg','Frankenberg','HE'),('DE','FKH','Frickenhausen','Frickenhausen','BW'),('DE','FKM','Feldkirchen','Feldkirchen','BY'),('DE','FKR','Feldkirchen','Feldkirchen','BY'),('DE','FKS','Falkenstein','Falkenstein','SN'),('DE','FLF','Flensburg','Flensburg','SH'),('DE','FLO','Florsheim am Main','Florsheim am Main','HE'),('DE','FLS','Florstadt','Florstadt','HE'),('DE','FNB','Fichtenberg','Fichtenberg','BW'),('DE','FNL','Fernthal','Fernthal','RP'),('DE','FOH','Forchheim','Forchheim','BY'),('DE','FOR','Forst','Forst','BY'),('DE','FOS','Floss','Floss','BY'),('DE','FRA','Frankfurt am Main','Frankfurt am Main','HE'),('DE','FRB','Friedberg','Friedberg','HE'),('DE','FRC','Frankenbach','Frankenbach','BW'),('DE','FRD','Fredersdorf','Fredersdorf','BR'),('DE','FRE','Fresenburg','Fresenburg','NI'),('DE','FRF','Friedrichsdorf','Friedrichsdorf','HE'),('DE','FRG','Freising','Freising','BY'),('DE','FRH','Freudenberg','Freudenberg','BW'),('DE','FRI','Friedrichstadt','Friedrichstadt','SH'),('DE','FRK','Frankeneck','Frankeneck','RP'),('DE','FRL','Freilassing','Freilassing','BY'),('DE','FRN','Frechen','Frechen','NW'),('DE','FRR','Frauenau','Frauenau','BY'),('DE','FRS','Friedrichsthal','Friedrichsthal','SL'),('DE','FRT','Freigericht','Freigericht','HE'),('DE','FRU','Friesau','Friesau','TH'),('DE','FRX','Fronhausen','Fronhausen','HE'),('DE','FRY','Freyung','Freyung','BY'),('DE','FRZ','Fritzlar','Fritzlar','HE'),('DE','FSB','Felsberg','Felsberg','HE'),('DE','FSG','Fussgonheim','Fussgonheim','RP'),('DE','FSN','Furstenstein','Furstenstein','BY'),('DE','FSS','Fussen','Fussen','BY'),('DE','FST','Freudenstadt','Freudenstadt','BW'),('DE','FTA','Freital','Freital','SN'),('DE','FTB','Forchtenberg','Forchtenberg','BW'),('DE','FTE','Furstenwalde','Furstenwalde','BR'),('DE','FTG','Forsting','Forsting','BY'),('DE','FTI','Forstinning','Forstinning','BY'),('DE','FTL','Frankenthal/Pfalz','Frankenthal/Pfalz','RP'),('DE','FUE','Furth','Furth','BY'),('DE','FUL','Fulda','Fulda','HE'),('DE','FUR','Furth','Furth','HE'),('DE','FUT','Fuldatal','Fuldatal','HE'),('DE','FUU','Bad Fussing','Bad Fussing','BY'),('DE','FUW','Furth im Wald','Furth im Wald','BY'),('DE','FWD','Forstwald','Forstwald','BY'),('DE','FWM','Feldkirchen-Westerham','Feldkirchen-Westerham','BY'),('DE','FWN','Furtwangen','Furtwangen','BW'),('DE','FWR','Friedenweiler','Friedenweiler','BW'),('DE','FYE','Friesoythe','Friesoythe','NI'),('DE','FZC','Feilitzsch','Feilitzsch','BY'),('DE','GAA','Garching an der Alz','Garching an der Alz','BY'),('DE','GAB','Gablingen','Gablingen','BY'),('DE','GAE','Gailingen','Gailingen','BW'),('DE','GAF','Grub am Forst','Grub am Forst','BY'),('DE','GAG','Gaggenau','Gaggenau','BW'),('DE','GAI','Gaildorf','Gaildorf','BW'),('DE','GAL','Garrel','Garrel','NI'),('DE','GAM','Gaimersheim','Gaimersheim','BY'),('DE','GAN','Ganderkesee','Ganderkesee','NI'),('DE','GAO','Gau Odernheim','Gau Odernheim','RP'),('DE','GAP','Garmisch-Partenkirchen','Garmisch-Partenkirchen','BY'),('DE','GAR','Gardelegen','Gardelegen','ST'),('DE','GAT','Garlstedt','Garlstedt','NI'),('DE','GAU','Gauensiek','Gauensiek','NI'),('DE','GBB','Gebersbach','Gebersbach','SN'),('DE','GBG','Grasberg','Grasberg','NI'),('DE','GBH','Gernsbach','Gernsbach','BW'),('DE','GBM','Garching bei Munchen','Garching bei Munchen','BY'),('DE','GBN','Gerabronn','Gerabronn','BW'),('DE','GBR','Gross-Rohrheim','Gross-Rohrheim','HE'),('DE','GBS','Garbsen','Garbsen','NI'),('DE','GBT','Giebelstadt','Giebelstadt','BY'),('DE','GBU','Grasbrunn','Grasbrunn','BY'),('DE','GBZ','Glaubitz','Glaubitz','SN'),('DE','GCA','Grossschirma','Grossschirma','SN'),('DE','GCG','Gilching','Gilching','BY'),('DE','GCH','Gelchsheim','Gelchsheim','BY'),('DE','GDA','Gnadau','Gnadau','ST'),('DE','GDE','Glinde','Glinde','SH'),('DE','GDG','Gudingen','Gudingen','SL'),('DE','GDI','Greding','Greding','BY'),('DE','GDN','Geldern','Geldern','NW'),('DE','GDO','Godorf','Godorf','NW'),('DE','GDU','Grundau','Grundau','HE'),('DE','GEA','Gera','Gera','TH'),('DE','GEB','Gevelsberg','Gevelsberg','NW'),('DE','GED','Geretsried','Geretsried','BY'),('DE','GEE','Geseke','Geseke','NW'),('DE','GEF','Gettorf','Gettorf','SH'),('DE','GEH','Gelnhausen','Gelnhausen','HE'),('DE','GEI','Geisenheim','Geisenheim','HE'),('DE','GEK','Gelsenkirchen','Gelsenkirchen','NW'),('DE','GEL','Gelting','Gelting','SH'),('DE','GEM','Gemunden','Gemunden','BY'),('DE','GEN','Gensingen','Gensingen','RP'),('DE','GEO','Georgsdorf','Georgsdorf','NI'),('DE','GER','Germersheim','Germersheim','RP'),('DE','GES','Gerolstein','Gerolstein','RP'),('DE','GET','Geesthacht','Geesthacht','SH'),('DE','GEU','Greussen','Greussen','TH'),('DE','GEV','Geversdorf','Geversdorf','NI'),('DE','GEZ','Gerden','Gerden','NI'),('DE','GFD','Gersfeld','Gersfeld','HE'),('DE','GFE','Grosskitzighofen','Grosskitzighofen','BY'),('DE','GFF','Grafschaft','Grafschaft','RP'),('DE','GFG','Grafing','Grafing','BY'),('DE','GFH','Grafenhausen','Grafenhausen','BW'),('DE','GFI','Gundelfingen','Gundelfingen','BW'),('DE','GFN','Grafenau','Grafenau','BY'),('DE','GFS','Greifenstein','Greifenstein','HE'),('DE','GFT','Grafschaft','Grafschaft','NW'),('DE','GGD','Georgensgmund','Georgensgmund','BY'),('DE','GGE','Gross Glienicke','Gross Glienicke','BE'),('DE','GGF','Gingen an der Fils','Gingen an der Fils','BW'),('DE','GGG','Gungolding','Gungolding','BY'),('DE','GGH','Gengenbach','Gengenbach','BW'),('DE','GGI','Guglingen','Guglingen','BW'),('DE','GGL','Georgsheil','Georgsheil','NI'),('DE','GGN','Giengen','Giengen','BW'),('DE','GGO','Langgons','Langgons','HE'),('DE','GGS','Guldengossa','Guldengossa','SN'),('DE','GGT','Gangelt','Gangelt','NW'),('DE','GHA','Gerichshain','Gerichshain','SN'),('DE','GHD','Gehrden','Gehrden','NI'),('DE','GHE','Grafenrheinfeld','Grafenrheinfeld','BY'),('DE','GHH','Grossharthau','Grossharthau','SN'),('DE','GHI','Grossostheim','Grossostheim','BY'),('DE','GHM','Gernsheim','Gernsheim','HE'),('DE','GHN','Gersthofen','Gersthofen','BY'),('DE','GHO','Grosshelfendorf','Grosshelfendorf','BY'),('DE','GHT','Glashutten','Glashutten','HE'),('DE','GHU','Glauchau','Glauchau','SN'),('DE','GHX','Grebenhain','Grebenhain','HE'),('DE','GHZ','Gersheim','Gersheim','SL'),('DE','GIA','Geisa','Geisa','TH'),('DE','GIE','Giessen','Giessen','HE'),('DE','GIF','Gifhorn','Gifhorn','NI'),('DE','GIG','Ginsheim-Gustavsburg','Ginsheim-Gustavsburg','HE'),('DE','GIH','Geinsheim','Geinsheim','RP'),('DE','GIM','Gimbsheim','Gimbsheim','RP'),('DE','GIN','Gallin','Gallin','MV'),('DE','GIT','Gittelde','Gittelde','NI'),('DE','GIU','Grinau','Grinau','SH'),('DE','GKB','Grosskarlbach','Grosskarlbach','RP'),('DE','GKG','Gross Krotzenburg','Gross Krotzenburg','HE'),('DE','GKH','Gaukonigshofen','Gaukonigshofen','BY'),('DE','GKI','Geilenkirchen','Geilenkirchen','NW'),('DE','GKT','Grunkraut','Grunkraut','BW'),('DE','GLA','Gladbeck','Gladbeck','NW'),('DE','GLD','Goeland','Goeland','NW'),('DE','GLF','Geltendorf','Geltendorf','BY'),('DE','GLG','Gerlingen','Gerlingen','BW'),('DE','GLH','Gladenbach','Gladenbach','HE'),('DE','GLI','Geislingen an der Steige','Geislingen an der Steige','BW'),('DE','GLN','Glatten','Glatten','BW'),('DE','GLO','Glothe','Glothe','ST'),('DE','GLU','Gluckstadt','Gluckstadt','SH'),('DE','GLX','Gleina','Gleina','ST'),('DE','GMA','Grimma','Grimma','SN'),('DE','GMB','Grumbach','Grumbach','RP'),('DE','GMD','Grossmaischeid','Grossmaischeid','RP'),('DE','GME','Grossmehring','Grossmehring','BY'),('DE','GMG','Gemmingen','Gemmingen','BW'),('DE','GMH','Georgsmarienhutte','Georgsmarienhutte','NI'),('DE','GMN','Grimmen','Grimmen','MV'),('DE','GMR','Grimberg','Grimberg','NW'),('DE','GMU','Gmund','Gmund','BY'),('DE','GNA','Gnarrenburg','Gnarrenburg','NI'),('DE','GND','Grundau','Grundau','SN'),('DE','GNE','Gernrode/Harz','Gernrode/Harz','ST'),('DE','GNG','Gauting','Gauting','BY'),('DE','GNH','Gedern','Gedern','HE'),('DE','GNN','Gonnersdorf','Gonnersdorf','RP'),('DE','GNS','Gingst','Gingst','MV'),('DE','GNT','Genthin','Genthin','ST'),('DE','GNU','Gronau','Gronau','NW'),('DE','GOA','Gotha','Gotha','TH'),('DE','GOB','Grossbettlingen','Grossbettlingen','BW'),('DE','GOC','Goch','Goch','NW'),('DE','GOE','Gottingen','Gottingen','NI'),('DE','GOF','Grossefehn','Grossefehn','NI'),('DE','GOH','Gochsheim','Gochsheim','BY'),('DE','GOI','Gosheim','Gosheim','BW'),('DE','GOK','Grosskoschen','Grosskoschen','BR'),('DE','GOL','Golssen','Golssen','BR'),('DE','GOM','Gomaringen','Gomaringen','BW'),('DE','GON','Goppingen','Goppingen','BW'),('DE','GOO','Grossorner','Grossorner','ST'),('DE','GOR','Gorlitz','Gorlitz','SN'),('DE','GOS','Goslar','Goslar','NI'),('DE','GOT','Gottmadingen','Gottmadingen','BW'),('DE','GOZ','Gotz','Gotz','BR'),('DE','GPN','Greppin','Greppin','ST'),('DE','GPR','Groppenbruch','Groppenbruch','NW'),('DE','GRA','Grambow','Grambow','MV'),('DE','GRB','Grossbeeren','Grossbeeren','BR'),('DE','GRC','Grossraschen','Grossraschen','BR'),('DE','GRD','Greifswald','Greifswald','MV'),('DE','GRE','Greetsiel','Greetsiel','NI'),('DE','GRF','Grafelfing','Grafelfing','BY'),('DE','GRG','Gross-Gerau','Gross-Gerau','HE'),('DE','GRH','Grefrath','Grefrath','NW'),('DE','GRI','Greiz','Greiz','TH'),('DE','GRK','Gross Kienitz','Gross Kienitz','BR'),('DE','GRL','Grimmenthal','Grimmenthal','TH'),('DE','GRM','Griesheim','Griesheim','HE'),('DE','GRN','Graben-Neudorf','Graben-Neudorf','BW'),('DE','GRO','Grossenbrode','Grossenbrode','SH'),('DE','GRP','Grunenplan','Grunenplan','NI'),('DE','GRR','Grafenwohr','Grafenwohr','BY'),('DE','GRS','Gorisried','Gorisried','BY'),('DE','GRT','Grunstadt','Grunstadt','RP'),('DE','GRU','Grunberg','Grunberg','HE'),('DE','GRV','Grevenbroich','Grevenbroich','NW'),('DE','GRW','Gronwohld','Gronwohld','SH'),('DE','GRX','Gross Rheide','Gross Rheide','SH'),('DE','GRZ','Gartz','Gartz','BR'),('DE','GSA','Grosslehna','Grosslehna','ST'),('DE','GSB','Gross Steinberg','Gross Steinberg','SN'),('DE','GSC','Gorschen','Gorschen','ST'),('DE','GSE','Gras-Ellenbach','Gras-Ellenbach','HE'),('DE','GSH','Grossenhain','Grossenhain','SN'),('DE','GSI','Grossensiel','Grossensiel','NI'),('DE','GSL','Grabsleben','Grabsleben','TH'),('DE','GSM','Grossalmerode','Grossalmerode','HE'),('DE','GSR','Gescher','Gescher','NW'),('DE','GSS','Grossauheim','Grossauheim','HE'),('DE','GST','Geeste','Geeste','NI'),('DE','GSU','Grassau','Grassau','BY'),('DE','GSW','Grossruckerswalde','Grossruckerswalde','SN'),('DE','GTD','Gunthersdorf','Gunthersdorf','ST'),('DE','GTE','Gerstungen','Gerstungen','TH'),('DE','GTG','Gammertingen','Gammertingen','BW'),('DE','GTH','Geithain','Geithain','SN'),('DE','GTN','Gartringen','Gartringen','BW'),('DE','GTU','Guttau','Guttau','SN'),('DE','GTZ','Groditz','Groditz','BR'),('DE','GUB','Guben','Guben','BR'),('DE','GUC','Gutach im Breisgau','Gutach im Breisgau','BW'),('DE','GUG','Gunzburg','Gunzburg','BY'),('DE','GUH','Gunzenhausen','Gunzenhausen','BY'),('DE','GUL','Guldental','Guldental','RP'),('DE','GUM','Gummersbach','Gummersbach','NW'),('DE','GUN','Gundelsheim','Gundelsheim','BW'),('DE','GUS','Gussenstadt','Gussenstadt','BW'),('DE','GUT','Gutersloh','Gutersloh','NW'),('DE','GUW','Gustrow','Gustrow','MV'),('DE','GUX','Guxhagen','Guxhagen','HE'),('DE','GUZ','Urmitz','Urmitz','RP'),('DE','GVN','Greven','Greven','NW'),('DE','GWA','Geringswalde','Geringswalde','SN'),('DE','GWH','Gravenwiesbach','Gravenwiesbach','HE'),('DE','GWL','Gorwihl','Gorwihl','BW'),('DE','GWN','Gossweinstein','Gossweinstein','BY'),('DE','GWP','Grosspostwitz','Grosspostwitz','SN'),('DE','GWS','Grosswallstadt','Grosswallstadt','BY'),('DE','GWT','Westerland','Westerland','SH'),('DE','GWY','Grenzach-Wyhlen','Grenzach-Wyhlen','BW'),('DE','GXD','Gross-Umstadt','Gross-Umstadt','HE'),('DE','GYR','Geyer','Geyer','SN'),('DE','GZF','Gerolzhofen','Gerolzhofen','BY'),('DE','GZI','Gross-Zimmern','Gross-Zimmern','HE'),('DE','GZN','Gross Ziethen','Gross Ziethen','BR'),('DE','HAA','Haan','Haan','NW'),('DE','HAB','Hambergen','Hambergen','NI'),('DE','HAC','Hachenburg','Hachenburg','RP'),('DE','HAE','Halle','Halle','NW'),('DE','HAF','Hafenlohr','Hafenlohr','BY'),('DE','HAG','Hagen','Hagen','NW'),('DE','HAH','Haiterbach','Haiterbach','BW'),('DE','HAI','Haibach/Aschaffenburg','Haibach/Aschaffenburg','BY'),('DE','HAJ','Hannover','Hannover','NI'),('DE','HAK','Halstenbek','Halstenbek','SH'),('DE','HAL','Halle','Halle','ST'),('DE','HAM','Hamburg','Hamburg','HH'),('DE','HAN','Hameln','Hameln','NI'),('DE','HAO','Hasloch','Hasloch','BY'),('DE','HAQ','Haar','Haar','BY'),('DE','HAR','Haiger','Haiger','HE'),('DE','HAS','Hassfurt','Hassfurt','BY'),('DE','HAT','Hattingen','Hattingen','NW'),('DE','HAU','Hanau','Hanau','HE'),('DE','HAW','Hagenow','Hagenow','MV'),('DE','HAX','Hausen','Hausen','BY'),('DE','HAZ','Au in der Hallertau','Au in der Hallertau','BY'),('DE','HBC','Hornbach','Hornbach','HE'),('DE','HBE','Homberg','Homberg','HE'),('DE','HBG','Herzberg','Herzberg','NI'),('DE','HBH','Hosbach','Hosbach','BY'),('DE','HBL','Hankensbuttel','Hankensbuttel','NI'),('DE','HBM','Herbolzheim','Herbolzheim','BW'),('DE','HBN','Herborn','Herborn','HE'),('DE','HBO','Homberg','Homberg','NW'),('DE','HBR','Herbrum','Herbrum','NI'),('DE','HBU','Harburg','Harburg','HH'),('DE','HCA','Harschbach','Harschbach','RP'),('DE','HCB','Hochbruck','Hochbruck','BY'),('DE','HCH','Heuchelheim','Heuchelheim','RP'),('DE','HCK','Herdecke','Herdecke','NW'),('DE','HCS','Hochst','Hochst','HE'),('DE','HCT','Hochstetten','Hochstetten','RP'),('DE','HDD','Heinsdorfergrund','Heinsdorfergrund','SN'),('DE','HDE','Heide','Heide','SH'),('DE','HDF','Heringsdorf','Heringsdorf','MV'),('DE','HDG','Haldenwang','Haldenwang','BY'),('DE','HDH','Hardheim','Hardheim','BW'),('DE','HDI','Hiddingsel','Hiddingsel','NW'),('DE','HDK','Heidkaten','Heidkaten','SH'),('DE','HDL','Hindelang','Hindelang','BY'),('DE','HDM','Heddesheim','Heddesheim','BW'),('DE','HDN','Heiden/Borken','Heiden/Borken','NW'),('DE','HDO','Hilmersdorf','Hilmersdorf','SN'),('DE','HDR','Hessdorf','Hessdorf','BY'),('DE','HDS','Heldenstein','Heldenstein','BY'),('DE','HEA','Hodenhagen','Hodenhagen','NI'),('DE','HEC','Hechingen','Hechingen','BW'),('DE','HED','Heikendorf','Heikendorf','SH'),('DE','HEE','Herne','Herne','NW'),('DE','HEF','Hennef','Hennef','NW'),('DE','HEG','Heinsberg','Heinsberg','NW'),('DE','HEH','Heimenkirch','Heimenkirch','BY'),('DE','HEI','Heidelberg','Heidelberg','BW'),('DE','HEK','Hersbruck','Hersbruck','BY'),('DE','HEL','Helmstedt','Helmstedt','NI'),('DE','HEM','Heidenheim','Heidenheim','BW'),('DE','HEN','Heilbronn','Heilbronn','BW'),('DE','HEO','Herdorf','Herdorf','RP'),('DE','HEP','Heppenheim','Heppenheim','HE'),('DE','HEQ','Hedemunden','Hedemunden','NI'),('DE','HER','Herbrechtingen','Herbrechtingen','BW'),('DE','HES','Heiligenhaus/Mettmann','Heiligenhaus/Mettmann','NW'),('DE','HET','Heroldstatt','Heroldstatt','BW'),('DE','HEU','Heubach','Heubach','BW'),('DE','HEX','Heising','Heising','BY'),('DE','HFD','Harsefeld','Harsefeld','NI'),('DE','HFE','Hofen an der Enz','Hofen an der Enz','BW'),('DE','HFG','Halfing','Halfing','BY'),('DE','HFH','Hofheim/Taunus','Hofheim/Taunus','HE'),('DE','HFN','Hunfelden','Hunfelden','HE'),('DE','HFS','Hohenfels','Hohenfels','BY'),('DE','HFU','Hofheim in Unterfranken','Hofheim in Unterfranken','BY'),('DE','HGA','Hohenbrunn','Hohenbrunn','BY'),('DE','HGB','Hengersberg','Hengersberg','BY'),('DE','HGD','Hirschberg','Hirschberg','BW'),('DE','HGE','Hooge','Hooge','SH'),('DE','HGI','Herrngiersdorf','Herrngiersdorf','BY'),('DE','HGL','Helgoland','Helgoland','SH'),('DE','HGM','Hofgeismar','Hofgeismar','HE'),('DE','HGN','Hohr-Grenzhausen','Hohr-Grenzhausen','RP'),('DE','HGO','Harzgerode','Harzgerode','ST'),('DE','HGR','Harlingerode','Harlingerode','NI'),('DE','HGS','Heiligenstadt','Heiligenstadt','TH'),('DE','HGW','Hurtgenwald','Hurtgenwald','NW'),('DE','HGZ','Hergatz','Hergatz','BY'),('DE','HHA','Herleshausen','Herleshausen','HE'),('DE','HHB','Hallenberg','Hallenberg','NW'),('DE','HHD','Hochscheid','Hochscheid','RP'),('DE','HHE','Hohentengen','Hohentengen','BW'),('DE','HHF','Heiligenhafen','Heiligenhafen','SH'),('DE','HHH','Hochheim','Hochheim','RP'),('DE','HHK','Hardthausen am Kocher','Hardthausen am Kocher','BW'),('DE','HHL','Hehlen','Hehlen','NI'),('DE','HHM','Hattersheim','Hattersheim','HE'),('DE','HHN','Hirschhorn','Hirschhorn','HE'),('DE','HHS','Hohenhorn','Hohenhorn','SH'),('DE','HHT','Hullhorst','Hullhorst','NW'),('DE','HHU','Haimhausen','Haimhausen','BY'),('DE','HHW','Hohenwestedt','Hohenwestedt','SH'),('DE','HHZ','Harbergen','Harbergen','NI'),('DE','HID','Hilden','Hilden','NW'),('DE','HIE','Hille','Hille','NW'),('DE','HIF','Hirschfelde','Hirschfelde','SN'),('DE','HIG','Hirrlingen','Hirrlingen','BW'),('DE','HIH','Hilchenbach','Hilchenbach','NW'),('DE','HII','Heiligenroth','Heiligenroth','RP'),('DE','HIK','Himmelkron','Himmelkron','BY'),('DE','HIL','Hildesheim','Hildesheim','NI'),('DE','HIN','Hiddenhausen','Hiddenhausen','NW'),('DE','HIR','Hilter','Hilter','NI'),('DE','HIU','Hirschau','Hirschau','BY'),('DE','HKH','Hohenkirchen','Hohenkirchen','BY'),('DE','HKK','Halsbrucke','Halsbrucke','SN'),('DE','HKL','Hamminkeln','Hamminkeln','NW'),('DE','HKN','Holzkirchen','Holzkirchen','BY'),('DE','HLA','Helsa','Helsa','HE'),('DE','HLC','Haslach im Kinzigtal','Haslach im Kinzigtal','BW'),('DE','HLD','Hillscheid','Hillscheid','RP'),('DE','HLE','Harrislee','Harrislee','SH'),('DE','HLG','Hohenlimburg','Hohenlimburg','NW'),('DE','HLH','Haldensleben','Haldensleben','ST'),('DE','HLI','Hessisch Lichtenau','Hessisch Lichtenau','HE'),('DE','HLL','Hollern','Hollern','BY'),('DE','HLM','Haselmuhl','Haselmuhl','BY'),('DE','HLN','Hollenstedt','Hollenstedt','NI'),('DE','HLO','Haseldorf','Haseldorf','SH'),('DE','HLP','Hiltrup','Hiltrup','NW'),('DE','HLR','Hollriegelskreuth','Hollriegelskreuth','BY'),('DE','HLS','Holtsee','Holtsee','SH'),('DE','HLT','Hallstadt','Hallstadt','BY'),('DE','HLU','Hainburg','Hainburg','HE'),('DE','HLX','Holm','Holm','NI'),('DE','HLZ','Hilzingen','Hilzingen','BW'),('DE','HMA','Hemau','Hemau','BY'),('DE','HMB','Hammelburg','Hammelburg','BY'),('DE','HMD','Hemmingstedt','Hemmingstedt','SH'),('DE','HME','Hattenheim','Hattenheim','HE'),('DE','HMF','Hartmannsdorf','Hartmannsdorf','SN'),('DE','HMG','Hermaringen','Hermaringen','BW'),('DE','HMH','Hemhofen','Hemhofen','BY'),('DE','HMI','Hemmingen','Hemmingen','NI'),('DE','HMK','Hermeskeil','Hermeskeil','RP'),('DE','HMM','Hamm','Hamm','NW'),('DE','HMN','Heimerdingen','Heimerdingen','BW'),('DE','HMO','Hemmoor','Hemmoor','NI'),('DE','HMR','Hemer','Hemer','NW'),('DE','HMS','Hallbergmoos','Hallbergmoos','BY'),('DE','HMU','Hannoversch Munden','Hannoversch Munden','NI'),('DE','HNA','Honau','Honau','BW'),('DE','HND','Hohenlinden','Hohenlinden','BY'),('DE','HNG','Herrenberg','Herrenberg','BW'),('DE','HNH','Hahn Apt','Hahn Apt','HE'),('DE','HNN','Haselunne','Haselunne','NI'),('DE','HNT','Hardt bei Nurtingen','Hardt bei Nurtingen','BW'),('DE','HOB','Horb','Horb','BW'),('DE','HOC','Hockenheim','Hockenheim','BW'),('DE','HOD','Hochdonn','Hochdonn','SH'),('DE','HOE','Hochst im Odenwald','Hochst im Odenwald','HE'),('DE','HOF','Hessisch Oldendorf','Hessisch Oldendorf','NI'),('DE','HOG','Hohenburg','Hohenburg','BY'),('DE','HOH','Hohenlockstedt','Hohenlockstedt','SH'),('DE','HOI','Hohenstein-Ernstthal','Hohenstein-Ernstthal','SN'),('DE','HOL','Hollage','Hollage','NI'),('DE','HOM','Homburg','Homburg','SL'),('DE','HON','Hollern','Hollern','NI'),('DE','HOO','Hooksiel','Hooksiel','NI'),('DE','HOP','Hopsten','Hopsten','NW'),('DE','HOQ','Hof','Hof','BY'),('DE','HOR','Horka/Oberlausitz','Horka/Oberlausitz','SN'),('DE','HOS','Horumersiel','Horumersiel','NI'),('DE','HOT','Hochstadt an der Aisch','Hochstadt an der Aisch','BY'),('DE','HOW','Hoppstadten-Weiersbach','Hoppstadten-Weiersbach','RP'),('DE','HOX','Hoxter','Hoxter','NW'),('DE','HOY','Hoya','Hoya','NI'),('DE','HPE','Hoopte','Hoopte','NI'),('DE','HPF','Hedelfingen','Hedelfingen','BW'),('DE','HRA','Horstmar','Horstmar','NW'),('DE','HRB','Horneburg','Horneburg','NI'),('DE','HRD','Herford','Herford','NW'),('DE','HRE','Hirzenhein','Hirzenhein','HE'),('DE','HRG','Heringen','Heringen','HE'),('DE','HRH','Herringhausen','Herringhausen','NW'),('DE','HRI','Heringen','Heringen','TH'),('DE','HRL','Horstel','Horstel','NW'),('DE','HRM','Hornum/Sylt','Hornum/Sylt','SH'),('DE','HRN','Haren/Ems','Haren/Ems','NI'),('DE','HRR','Herrenhausen','Herrenhausen','NI'),('DE','HRS','Harsum','Harsum','NI'),('DE','HRT','Herten','Herten','NW'),('DE','HRZ','Hattorf am Harz','Hattorf am Harz','NI'),('DE','HSA','Hohensaaten','Hohensaaten','BR'),('DE','HSB','Horselberg','Horselberg','TH'),('DE','HSC','Hassloch','Hassloch','RP'),('DE','HSD','Herscheid','Herscheid','NW'),('DE','HSE','Harsleben','Harsleben','ST'),('DE','HSF','Harsdorf','Harsdorf','BY'),('DE','HSG','Heroldsberg','Heroldsberg','BY'),('DE','HSH','Hausach','Hausach','BW'),('DE','HSI','Heidesheim','Heidesheim','RP'),('DE','HSK','Kaisersesch','Kaisersesch','RP'),('DE','HSL','Hauptstuhl','Hauptstuhl','RP'),('DE','HSM','Heusenstamm','Heusenstamm','HE'),('DE','HSN','Hauslingen','Hauslingen','NI'),('DE','HSO','Hemsloh','Hemsloh','NI'),('DE','HSP','Hochspeyer','Hochspeyer','RP'),('DE','HSS','Heimboldshausen','Heimboldshausen','HE'),('DE','HST','Halberstadt','Halberstadt','ST'),('DE','HSU','Hundsmuhlen','Hundsmuhlen','NI'),('DE','HSW','Heusweiler','Heusweiler','SL'),('DE','HSX','Harlesiel','Harlesiel','NI'),('DE','HTA','Holthausen','Holthausen','NW'),('DE','HTE','Heltersberg','Heltersberg','RP'),('DE','HTF','Hattenhofen','Hattenhofen','BY'),('DE','HTH','Heitersheim','Heitersheim','BW'),('DE','HTI','Heimertingen','Heimertingen','BY'),('DE','HTL','Hellenthal','Hellenthal','NW'),('DE','HTM','Huttisheim','Huttisheim','BW'),('DE','HTN','Haltern','Haltern','NW'),('DE','HTQ','Hettingen','Hettingen','BW'),('DE','HTS','Hartenstein','Hartenstein','SN'),('DE','HTT','Heimstetten','Heimstetten','BY'),('DE','HTU','Holtenau','Holtenau','SH'),('DE','HTZ','Hetzerath','Hetzerath','RP'),('DE','HUB','Berggiesshubel','Berggiesshubel','SN'),('DE','HUD','Hunfeld','Hunfeld','HE'),('DE','HUE','Hurth','Hurth','NW'),('DE','HUF','Hunderdorf','Hunderdorf','BY'),('DE','HUG','Hungen','Hungen','HE'),('DE','HUH','Hausham','Hausham','BY'),('DE','HUI','Huisheim','Huisheim','BY'),('DE','HUL','Huls','Huls','NW'),('DE','HUN','Huntebruck','Huntebruck','NI'),('DE','HUR','Heldburg','Heldburg','TH'),('DE','HUS','Husum','Husum','SH'),('DE','HUT','Hauenstein','Hauenstein','BW'),('DE','HUZ','Henstedt-Ulzburg','Henstedt-Ulzburg','SH'),('DE','HVF','Hovelhof','Hovelhof','NW'),('DE','HVN','Huckelhoven','Huckelhoven','NW'),('DE','HVR','Halver','Halver','NW'),('DE','HWA','Hawangen','Hawangen','BY'),('DE','HWD','Hohwald','Hohwald','SN'),('DE','HWE','Hoyerswerda','Hoyerswerda','SN'),('DE','HWG','Huckeswagen','Huckeswagen','NW'),('DE','HWL','Harsewinkel','Harsewinkel','NW'),('DE','HWR','Hagenwerder','Hagenwerder','SN'),('DE','HWT','Hinterweidenthal','Hinterweidenthal','RP'),('DE','HXE','Hunxe','Hunxe','NW'),('DE','HXL','Herxheim bei Landau/Pfalz','Herxheim bei Landau/Pfalz','RP'),('DE','HXM','Hamm (Sieg)','Hamm (Sieg)','RP'),('DE','HXX','Hassmersheim','Hassmersheim','BW'),('DE','HYZ','Heynitz','Heynitz','SN'),('DE','HZB','Hauzenberg','Hauzenberg','BY'),('DE','HZC','Herzebrock','Herzebrock','NW'),('DE','HZE','Holzwickede','Holzwickede','NW'),('DE','HZF','Hatzfeld','Hatzfeld','HE'),('DE','HZH','Herzogenaurach','Herzogenaurach','BY'),('DE','HZL','Herzlake','Herzlake','NI'),('DE','HZM','Holzheim','Holzheim','BY'),('DE','HZN','Holzminden','Holzminden','NI'),('DE','HZR','Herzogenrath','Herzogenrath','NW'),('DE','HZZ','Huttingen','Huttingen','BW'),('DE','IBB','Ibbenburen','Ibbenburen','NW'),('DE','IBL','Isenbuttel','Isenbuttel','NI'),('DE','IBU','Ilsenburg','Ilsenburg','ST'),('DE','ICH','Ichtershausen','Ichtershausen','TH'),('DE','IDE','Inden','Inden','NW'),('DE','IDN','Illerrieden','Illerrieden','BW'),('DE','IDS','Idstein','Idstein','HE'),('DE','IED','Morschied','Morschied','RP'),('DE','IEE','Ilsede','Ilsede','NI'),('DE','IEN','Biene','Biene','NI'),('DE','IGE','Igenhausen','Igenhausen','BY'),('DE','IGF','Ingelfingen','Ingelfingen','BW'),('DE','IGG','Iggingen','Iggingen','BW'),('DE','IGH','Igersheim','Igersheim','BW'),('DE','IGN','Beihingen','Beihingen','BW'),('DE','IGU','Issigau','Issigau','BY'),('DE','IHN','Immenhausen','Immenhausen','HE'),('DE','IHW','Ihlienworth','Ihlienworth','NI'),('DE','ILB','Ilbesheim','Ilbesheim','RP'),('DE','ILH','Lich','Lich','HE'),('DE','ILL','Illingen','Illingen','SL'),('DE','ILM','Illesheim','Illesheim','BY'),('DE','ILN','Illertissen','Illertissen','BY'),('DE','ILU','Gehren','Gehren','TH'),('DE','IMG','Ismaning','Ismaning','BY'),('DE','IMM','Immenstadt im Allgau','Immenstadt im Allgau','BY'),('DE','ING','Ingolstadt','Ingolstadt','BY'),('DE','INM','Ingelheim','Ingelheim','RP'),('DE','INU','Ilmenau','Ilmenau','TH'),('DE','INZ','Inzlingen','Inzlingen','BW'),('DE','ION','Idar-Oberstein','Idar-Oberstein','RP'),('DE','IPH','Iphofen','Iphofen','BY'),('DE','ISE','Iserlohn','Iserlohn','NW'),('DE','ISN','Isernhagen','Isernhagen','NI'),('DE','ISU','Issum','Issum','NW'),('DE','ISY','Isny im Allgau','Isny im Allgau','BW'),('DE','ITG','Ittlingen','Ittlingen','BW'),('DE','ITZ','Itzehoe','Itzehoe','SH'),('DE','JAG','Jagstzell','Jagstzell','BW'),('DE','JAW','Wallerstein','Wallerstein','BY'),('DE','JBG','Juterbog','Juterbog','BR'),('DE','JBK','Jubek','Jubek','SH'),('DE','JBO','Jacobsdorf','Jacobsdorf','BR'),('DE','JDF','Jahnsdorf','Jahnsdorf','SN'),('DE','JEG','Jesteburg','Jesteburg','NI'),('DE','JEM','Jemgum','Jemgum','NI'),('DE','JEN','Jena','Jena','TH'),('DE','JES','Jestetten','Jestetten','BW'),('DE','JET','Jettenbach','Jettenbach','RP'),('DE','JEV','Jever','Jever','NI'),('DE','JFD','Johnsdorf','Johnsdorf','SN'),('DE','JHN','Juchen','Juchen','NW'),('DE','JNB','Jandelsbrunn','Jandelsbrunn','BY'),('DE','JOH','Johannisberg','Johannisberg','BE'),('DE','JOR','Jork','Jork','NI'),('DE','JSN','Jossen','Jossen','NW'),('DE','JTN','Jettingen','Jettingen','BY'),('DE','JUB','Judenbach','Judenbach','TH'),('DE','JUE','Julich','Julich','NW'),('DE','JUH','Junkerath','Junkerath','RP'),('DE','JUI','Juist','Juist','NI'),('DE','JWE','Janschwalde','Janschwalde','BR'),('DE','KAA','Kaarst','Kaarst','NW'),('DE','KAD','Karlsfeld','Karlsfeld','BY'),('DE','KAE','Karlsruhe','Karlsruhe','BW'),('DE','KAG','Kaufering','Kaufering','BY'),('DE','KAK','Karlskron','Karlskron','BY'),('DE','KAL','Kall','Kall','NW'),('DE','KAM','Kahl am Main','Kahl am Main','BY'),('DE','KAN','Kalenborn/Ahrweiler','Kalenborn/Ahrweiler','RP'),('DE','KAP','Kappeln','Kappeln','SH'),('DE','KAR','Karnin','Karnin','MV'),('DE','KAS','Kassel','Kassel','HE'),('DE','KAT','Kastl','Kastl','BY'),('DE','KAU','Kaufbeuren','Kaufbeuren','BY'),('DE','KAZ','Kamenz','Kamenz','SN'),('DE','KBB','Konigsberg','Konigsberg','BY'),('DE','KBF','Kleinblittersdorf','Kleinblittersdorf','SL'),('DE','KBH','Korschenbroich','Korschenbroich','NW'),('DE','KBN','Karben','Karben','HE'),('DE','KBR','Kinderbeuern','Kinderbeuern','RP'),('DE','KBU','Korbussen','Korbussen','TH'),('DE','KCH','Kirchzarten','Kirchzarten','BW'),('DE','KCI','Kirchheim','Kirchheim','BW'),('DE','KCN','Kirchen an der Sieg','Kirchen an der Sieg','RP'),('DE','KCO','Kirchmoser','Kirchmoser','BR'),('DE','KDB','Kindsbach','Kindsbach','RP'),('DE','KDF','Kirchdorf (Iller)','Kirchdorf (Iller)','BW'),('DE','KDG','Kummersdorf-Gut','Kummersdorf-Gut','BR'),('DE','KDI','Kinding','Kinding','BY'),('DE','KDN','Kloden','Kloden','ST'),('DE','KDZ','Koditz','Koditz','BY'),('DE','KEB','Kelsterbach','Kelsterbach','HE'),('DE','KEH','Kehl','Kehl','BW'),('DE','KEI','Keitum','Keitum','SH'),('DE','KEL','Kiel','Kiel','SH'),('DE','KEM','Kelheim','Kelheim','BY'),('DE','KEN','Kempten','Kempten','BY'),('DE','KER','Kerpen','Kerpen','RP'),('DE','KES','Kesselsdorf','Kesselsdorf','SN'),('DE','KEV','Kevelaer','Kevelaer','NW'),('DE','KEZ','Kellmunz','Kellmunz','BY'),('DE','KFN','Kiefersfelden','Kiefersfelden','BY'),('DE','KGD','Kirchgandern','Kirchgandern','TH'),('DE','KGE','Kirchgellersen','Kirchgellersen','NI'),('DE','KGF','Kobern-Gondorf','Kobern-Gondorf','RP'),('DE','KGM','Konigsmoor','Konigsmoor','NI'),('DE','KGN','Konigsbrunn','Konigsbrunn','BY'),('DE','KGO','Konigsmoos','Konigsmoos','BY'),('DE','KGT','Klingenthal','Klingenthal','SN'),('DE','KGU','Kriegenbrunn','Kriegenbrunn','BY'),('DE','KGW','Klein Gaglow','Klein Gaglow','BR'),('DE','KHA','Klipphausen','Klipphausen','SN'),('DE','KHB','Kirchberg','Kirchberg','RP'),('DE','KHE','Konigsheim','Konigsheim','BW'),('DE','KHG','Kosching','Kosching','BY'),('DE','KHH','Kirchhain','Kirchhain','HE'),('DE','KHM','Kelkheim','Kelkheim','HE'),('DE','KHN','Kellinghusen','Kellinghusen','SH'),('DE','KHU','Karthaus','Karthaus','NW'),('DE','KID','Kisdorf','Kisdorf','SH'),('DE','KIE','Kietz','Kietz','BR'),('DE','KIG','Krailling','Krailling','BY'),('DE','KIH','Kirschau','Kirschau','SN'),('DE','KIJ','Kirkel','Kirkel','SL'),('DE','KIL','Kraichtal','Kraichtal','BW'),('DE','KIM','Kulsheim','Kulsheim','BW'),('DE','KIN','Kirn/Nahe','Kirn/Nahe','RP'),('DE','KIP','Kippenheim','Kippenheim','BW'),('DE','KIR','Kirchheim/Teck','Kirchheim/Teck','BW'),('DE','KIS','Kisslegg','Kisslegg','BW'),('DE','KIT','Kitzingen','Kitzingen','BY'),('DE','KKB','Kleinkarlbach','Kleinkarlbach','RP'),('DE','KKH','Kirchhofen','Kirchhofen','BW'),('DE','KKN','Kaltenkirchen','Kaltenkirchen','SH'),('DE','KKR','Kalkar','Kalkar','NW'),('DE','KKU','Kunkemuhle','Kunkemuhle','NI'),('DE','KLB','Kalbe (Milde)','Kalbe (Milde)','ST'),('DE','KLE','Kleve','Kleve','NW'),('DE','KLF','Kamp-Lintfort','Kamp-Lintfort','NW'),('DE','KLG','Kirchlengern','Kirchlengern','NW'),('DE','KLH','Kleinheubach','Kleinheubach','BY'),('DE','KLI','Klingenberg','Klingenberg','BY'),('DE','KLL','Kell','Kell','RP'),('DE','KLN','Kirchlinteln','Kirchlinteln','NI'),('DE','KLS','Kesselstadt','Kesselstadt','HE'),('DE','KLT','Kaiserslautern','Kaiserslautern','RP'),('DE','KLU','Klettgau','Klettgau','BW'),('DE','KLW','Kleinmachnow','Kleinmachnow','BR'),('DE','KMG','Korntal-Munchingen','Korntal-Munchingen','BW'),('DE','KMH','Kemnath','Kemnath','BY'),('DE','KMN','Kamen','Kamen','NW'),('DE','KMP','Kempen','Kempen','NW'),('DE','KMT','Kaimt','Kaimt','RP'),('DE','KND','Kaltennordheim','Kaltennordheim','TH'),('DE','KNE','Kernen','Kernen','BW'),('DE','KNF','Knautnaundorf','Knautnaundorf','SN'),('DE','KNG','Kranenburg','Kranenburg','NW'),('DE','KNH','Karlsdorf-Neuthard','Karlsdorf-Neuthard','BW'),('DE','KNL','Kandel','Kandel','RP'),('DE','KNN','Kongen','Kongen','BW'),('DE','KNW','Konigswald','Konigswald','SN'),('DE','KNY','Konnern','Konnern','ST'),('DE','KNZ','Konitz','Konitz','TH'),('DE','KOB','Koblenz am Rhein','Koblenz am Rhein','RP'),('DE','KOE','Kotz','Kotz','BY'),('DE','KOF','Kolenfeld','Kolenfeld','NI'),('DE','KOG','Kollig','Kollig','RP'),('DE','KOH','Korbach','Korbach','HE'),('DE','KOL','Kollmar','Kollmar','SH'),('DE','KOM','Kolbermoor','Kolbermoor','BY'),('DE','KON','Konstanz','Konstanz','BW'),('DE','KOR','Kornwestheim','Kornwestheim','BW'),('DE','KOS','Konigstein','Konigstein','HE'),('DE','KOW','Konigswinter','Konigswinter','NW'),('DE','KOX','Korb','Korb','BW'),('DE','KOZ','Konz','Konz','RP'),('DE','KPE','Kampe','Kampe','NI'),('DE','KPS','Kups','Kups','BY'),('DE','KPT','Kroppenstedt','Kroppenstedt','ST'),('DE','KRA','Krautsand','Krautsand','NI'),('DE','KRB','Krummennaab','Krummennaab','BY'),('DE','KRC','Kirchheimbolanden','Kirchheimbolanden','RP'),('DE','KRD','Kirchardt','Kirchardt','BW'),('DE','KRE','Krefeld','Krefeld','NW'),('DE','KRF','Karpfham','Karpfham','BY'),('DE','KRG','Kronberg','Kronberg','HE'),('DE','KRH','Krauchenwies','Krauchenwies','BW'),('DE','KRI','Kriftel','Kriftel','HE'),('DE','KRL','Kreuztal','Kreuztal','NW'),('DE','KRM','Krautheim','Krautheim','BW'),('DE','KRN','Kreiensen','Kreiensen','NI'),('DE','KRO','Kronach','Kronach','BY'),('DE','KRP','Kerpen','Kerpen','NW'),('DE','KRR','Kraiburg am Inn','Kraiburg am Inn','BY'),('DE','KRS','Kriebstein','Kriebstein','SN'),('DE','KRT','Kruft','Kruft','RP'),('DE','KRU','Krumbach','Krumbach','BY'),('DE','KRV','Krov','Krov','RP'),('DE','KRW','Kritzow','Kritzow','MV'),('DE','KRY','Kirrweiler','Kirrweiler','RP'),('DE','KSA','Kastellaun','Kastellaun','RP'),('DE','KSB','Konigsbronn','Konigsbronn','BW'),('DE','KSD','Karlstadt','Karlstadt','BY'),('DE','KSE','Kierspe','Kierspe','NW'),('DE','KSG','Kissing','Kissing','BY'),('DE','KSH','Klein-Winternheim','Klein-Winternheim','RP'),('DE','KSL','Kroslin','Kroslin','MV'),('DE','KSN','Karlstein am Main','Karlstein am Main','BY'),('DE','KSR','Kastorf','Kastorf','NI'),('DE','KST','Konstein','Konstein','BY'),('DE','KSU','Konradsreuth','Konradsreuth',''),('DE','KTA','Korbetha','Korbetha','ST'),('DE','KTD','Kusterdingen','Kusterdingen','BW'),('DE','KTG','Kleinaitingen','Kleinaitingen','BY'),('DE','KTH','Ketsch','Ketsch','BW'),('DE','KTL','Kalletal','Kalletal','NW'),('DE','KTM','Kleinostheim','Kleinostheim',''),('DE','KTN','Kosten','Kosten','BY'),('DE','KTS','Kesten','Kesten','RP'),('DE','KTT','Katterbach','Katterbach','BY'),('DE','KTU','Kleintettau','Kleintettau','BY'),('DE','KTZ','Kiebitzreihe','Kiebitzreihe','SH'),('DE','KUA','Kussaberg','Kussaberg','BW'),('DE','KUC','Kuchenheim','Kuchenheim','NW'),('DE','KUE','Kunzelsau','Kunzelsau','BW'),('DE','KUK','Kummersbruck','Kummersbruck','BY'),('DE','KUL','Kulmbach','Kulmbach','BY'),('DE','KUN','Konigsee','Konigsee','TH'),('DE','KUR','Kirchheim in Unterfranken','Kirchheim in Unterfranken','BY'),('DE','KUS','Kusel','Kusel','RP'),('DE','KUZ','Kupferzell','Kupferzell','BW'),('DE','KWA','Konigswartha','Konigswartha','SN'),('DE','KWD','Knull','Knull','NI'),('DE','KWH','Konigs Wusterhausen','Konigs Wusterhausen','BR'),('DE','KWL','Streckewalde','Streckewalde','SN'),('DE','KWM','Kreuzwertheim','Kreuzwertheim','BY'),('DE','KWP','Kappelwindeck','Kappelwindeck','BW'),('DE','KWZ','Krauschwitz','Krauschwitz','SN'),('DE','KXF','Kirschhofen','Kirschhofen','HE'),('DE','KYR','Kyritz','Kyritz','BR'),('DE','KZB','Kranzberg','Kranzberg','BY'),('DE','KZF','Kreuzfeld','Kreuzfeld','SH'),('DE','KZL','Kunzell','Kunzell','HE'),('DE','KZU','Kreuzau','Kreuzau','NW'),('DE','LAA','Bad Laasphe (Laasphe)','Bad Laasphe (Laasphe)','NW'),('DE','LAB','Laboe','Laboe','SH'),('DE','LAC','Lachen','Lachen','BY'),('DE','LAD','Landau in der Pfalz','Landau in der Pfalz','RP'),('DE','LAE','Lagerdorf','Lagerdorf','SH'),('DE','LAF','Lauf an der Pegnitz','Lauf an der Pegnitz','BY'),('DE','LAG','Landsberg','Landsberg','BY'),('DE','LAH','Lahnstein','Lahnstein','RP'),('DE','LAI','Lauchheim','Lauchheim','BW'),('DE','LAM','Lampertheim','Lampertheim','HE'),('DE','LAN','Landwurden','Landwurden','NI'),('DE','LAR','Lahr','Lahr','BW'),('DE','LAT','Lathen','Lathen','NI'),('DE','LAU','Lauterbach','Lauterbach','HE'),('DE','LAW','Langewiesen','Langewiesen','TH'),('DE','LAY','Laer','Laer','NW'),('DE','LAZ','Laatzen','Laatzen','NI'),('DE','LBA','Lobau','Lobau','SN'),('DE','LBB','Langenberg','Langenberg','NW'),('DE','LBC','Lubeck','Lubeck','SH'),('DE','LBE','Lubbecke','Lubbecke','NW'),('DE','LBG','Luneburg','Luneburg','NI'),('DE','LBH','Laubach','Laubach','HE'),('DE','LBK','Lauenbruck','Lauenbruck','NI'),('DE','LBN','Lauben im Oberallgau','Lauben im Oberallgau','BY'),('DE','LBR','Liebertwolkwitz','Liebertwolkwitz','SN'),('DE','LBS','Lebus','Lebus','BR'),('DE','LBT','Lambrecht','Lambrecht','RP'),('DE','LBU','Langenburg','Langenburg','BW'),('DE','LBX','Lubtheen','Lubtheen','MV'),('DE','LCG','Laichingen','Laichingen','BW'),('DE','LCH','Lengerich','Lengerich','NI'),('DE','LCU','Laucha an der Unstrut','Laucha an der Unstrut','ST'),('DE','LDB','Ladbergen','Ladbergen','NW'),('DE','LDE','Lugde','Lugde','NW'),('DE','LDG','Ladeburg','Ladeburg','ST'),('DE','LDH','Landshut','Landshut','BY'),('DE','LDN','Linden','Linden','HE'),('DE','LDR','Lindlar','Lindlar','NW'),('DE','LDU','Landau an der Isar','Landau an der Isar','BY'),('DE','LEA','Leuna','Leuna','ST'),('DE','LEB','Lebach','Lebach','SL'),('DE','LEC','Leinfelden-Echterdingen','Leinfelden-Echterdingen','BW'),('DE','LEE','Leer','Leer','NI'),('DE','LEF','Lengfeld','Lengfeld','HE'),('DE','LEG','Legden','Legden','NW'),('DE','LEH','Lehrte','Lehrte','NI'),('DE','LEI','Leinburg','Leinburg','BY'),('DE','LEJ','Leipzig','Leipzig','SN'),('DE','LEM','Lemgo','Lemgo','NW'),('DE','LEN','Lenningen','Lenningen','BW'),('DE','LEO','Leonberg','Leonberg','BW'),('DE','LEU','Leutkirch im Allgau','Leutkirch im Allgau','BW'),('DE','LEV','Leverkusen','Leverkusen','NW'),('DE','LEW','Lemwerder','Lemwerder','NI'),('DE','LEZ','Lenzen (Elbe)','Lenzen (Elbe)','BR'),('DE','LFE','Lindenfels','Lindenfels','HE'),('DE','LFF','Loffingen','Loffingen','BW'),('DE','LFG','Laufenburg','Laufenburg','BW'),('DE','LFL','Lohfelden','Lohfelden','HE'),('DE','LFN','Lauffen am Neckar','Lauffen am Neckar','BW'),('DE','LGA','Liegau-Augustusbad','Liegau-Augustusbad','SN'),('DE','LGB','Langenbach','Langenbach','BW'),('DE','LGD','Langenselbold','Langenselbold','HE'),('DE','LGE','Lage','Lage','NW'),('DE','LGF','Langenfeld','Langenfeld','NW'),('DE','LGG','Langhagen','Langhagen','MV'),('DE','LGH','Langerwehe','Langerwehe','NW'),('DE','LGM','Langelsheim','Langelsheim','NI'),('DE','LGN','Lauingen','Lauingen','BY'),('DE','LGO','Langeoog','Langeoog','NI'),('DE','LGR','Leupoldsgrun','Leupoldsgrun','BY'),('DE','LGS','Lenggries','Lenggries','BY'),('DE','LGT','Leingarten','Leingarten','BW'),('DE','LGU','Langenau','Langenau','BW'),('DE','LGW','Lengenwang','Lengenwang','BY'),('DE','LGX','Ludwigshohe','Ludwigshohe','RP'),('DE','LHA','Lahnau','Lahnau','HE'),('DE','LHD','Lahde','Lahde','NW'),('DE','LHE','Lohne','Lohne','NW'),('DE','LHG','Lauchringen','Lauchringen','BW'),('DE','LHH','Langenhahn','Langenhahn','RP'),('DE','LHJ','Leiblfing','Leiblfing','BY'),('DE','LHN','Langenhagen','Langenhagen','NI'),('DE','LHO','Lauterhofen','Lauterhofen','BY'),('DE','LHS','Lehesten','Lehesten','TH'),('DE','LIA','Leina','Leina','TH'),('DE','LIB','Liebenau','Liebenau','NI'),('DE','LIC','Lichtenfels','Lichtenfels','BY'),('DE','LID','Lippendorf','Lippendorf','SN'),('DE','LIE','Lienen','Lienen','NW'),('DE','LIG','Lingen','Lingen','NI'),('DE','LIH','Linnich','Linnich','NW'),('DE','LIM','Limburg','Limburg','BY'),('DE','LIN','Lintelermarsch','Lintelermarsch','NI'),('DE','LIP','Lippstadt','Lippstadt','NW'),('DE','LIS','List/Sylt','List/Sylt','SH'),('DE','LIT','Lichtenau','Lichtenau','NW'),('DE','LIU','Lindau','Lindau','BY'),('DE','LIV','Langenargen','Langenargen','BW'),('DE','LJA','Lanzenhain','Lanzenhain','HE'),('DE','LJE','Lutjensee','Lutjensee','SH'),('DE','LJH','Leienkaul','Leienkaul','RP'),('DE','LKE','Linken','Linken','MV'),('DE','LKH','Linkenheim','Linkenheim','BW'),('DE','LKI','Lankwitz','Lankwitz','BE'),('DE','LKN','Lauda-Konigshofen','Lauda-Konigshofen','BW'),('DE','LLA','Langula','Langula','TH'),('DE','LLD','Leinefelde','Leinefelde','TH'),('DE','LLM','Langenlonsheim','Langenlonsheim','RP'),('DE','LLN','Leichlingen','Leichlingen','NW'),('DE','LLS','Lulsdorf','Lulsdorf','NW'),('DE','LMB','Limbach','Limbach','BW'),('DE','LME','Lemforde','Lemforde','NI'),('DE','LML','Limburg an der Lahn','Limburg an der Lahn','HE'),('DE','LMN','Leimen','Leimen','BW'),('DE','LNA','Lauenau','Lauenau','NI'),('DE','LNB','Lindenberg im Allgau','Lindenberg im Allgau','BY'),('DE','LNC','Langenneufnach','Langenneufnach','BY'),('DE','LND','Lindweiler','Lindweiler','NW'),('DE','LNE','Lohne bei Vechta','Lohne bei Vechta','NI'),('DE','LNG','Langen bei Bremerhaven','Langen bei Bremerhaven','NI'),('DE','LNH','Lohnerheide','Lohnerheide','NW'),('DE','LNI','Loningen','Loningen','NI'),('DE','LNN','Langen','Langen','HE'),('DE','LNR','Lindern','Lindern','NI'),('DE','LNT','Langenaltheim','Langenaltheim','BY'),('DE','LNU','Lauenburg/Elbe','Lauenburg/Elbe','SH'),('DE','LNZ','Lanz','Lanz','BR'),('DE','LOB','Lobichau','Lobichau','TH'),('DE','LOC','Lorch','Lorch','BW'),('DE','LOE','Lorrach','Lorrach','BW'),('DE','LOF','Limbach-Oberfrohna','Limbach-Oberfrohna','SN'),('DE','LOG','Lossburg','Lossburg','BW'),('DE','LOH','Lohmar','Lohmar','NW'),('DE','LOL','Lollar','Lollar','HE'),('DE','LON','Longuich','Longuich','RP'),('DE','LOR','Lohr','Lohr','BY'),('DE','LOS','Lobenstein','Lobenstein','TH'),('DE','LOT','Lotte','Lotte','NW'),('DE','LOX','Loxstedt','Loxstedt','NI'),('DE','LPE','Lippetal','Lippetal','NW'),('DE','LPH','Leipheim','Leipheim','BY'),('DE','LPM','Laupheim','Laupheim','BW'),('DE','LPW','Lampertswalde','Lampertswalde','SN'),('DE','LRG','Ladenburg','Ladenburg','BW'),('DE','LRH','Lorch','Lorch','BW'),('DE','LRN','Linz am Rhein','Linz am Rhein','RP'),('DE','LRS','Lampertswalde','Lampertswalde','SN'),('DE','LRW','Lorsch','Lorsch','HE'),('DE','LRZ','Luderitz','Luderitz','ST'),('DE','LSB','Landsberg','Landsberg','ST'),('DE','LSC','Lauscha','Lauscha','TH'),('DE','LSD','Landscheid','Landscheid','RP'),('DE','LSG','Linsengericht','Linsengericht','HE'),('DE','LSL','Landstuhl','Landstuhl','RP'),('DE','LSM','Losheim','Losheim','SL'),('DE','LST','Lennestadt','Lennestadt','NW'),('DE','LSU','Ludwigsau','Ludwigsau','HE'),('DE','LSW','Lensahn','Lensahn','SH'),('DE','LSY','Lachen bei Speyerdorf','Lachen bei Speyerdorf','RP'),('DE','LTA','Liederbach am Taunus','Liederbach am Taunus','HE'),('DE','LTE','Leeste','Leeste','NI'),('DE','LTG','Lenting','Lenting','BY'),('DE','LTH','Linthe','Linthe','BR'),('DE','LTN','Lauterecken','Lauterecken','RP'),('DE','LTP','Lastrup','Lastrup','NI'),('DE','LTS','Lottstetten','Lottstetten','BW'),('DE','LTT','Lette','Lette','NW'),('DE','LTW','Luttow','Luttow','MV'),('DE','LTZ','Lautzenhausen','Lautzenhausen','RP'),('DE','LUB','Lubben','Lubben','BR'),('DE','LUC','Luckenbach','Luckenbach','RP'),('DE','LUD','Ludenscheid','Ludenscheid','NW'),('DE','LUE','Lunen','Lunen','NW'),('DE','LUF','Lauenforde','Lauenforde','NI'),('DE','LUG','Ludwigsburg','Ludwigsburg','SH'),('DE','LUH','Ludwigshafen','Ludwigshafen','RP'),('DE','LUK','Lechbruck','Lechbruck','BY'),('DE','LUL','Ludwigslust','Ludwigslust','MV'),('DE','LUN','Ludinghausen','Ludinghausen','NW'),('DE','LUQ','Luckenwalde','Luckenwalde','BR'),('DE','LUS','Lubars','Lubars','ST'),('DE','LUT','Ludwigsstadt','Ludwigsstadt','BY'),('DE','LUW','Luchow','Luchow','NI'),('DE','LWB','Lowenberg','Lowenberg','BR'),('DE','LWD','Langweid','Langweid','BY'),('DE','LWE','Ludwigsfelde','Ludwigsfelde','BR'),('DE','LWF','Langenwetzendorf','Langenwetzendorf','TH'),('DE','LWG','Ludwigsburg','Ludwigsburg','BW'),('DE','LWI','Luhe-Wildenau','Luhe-Wildenau','BY'),('DE','LWN','Leiwen','Leiwen','RP'),('DE','LXG','Lengede','Lengede','NI'),('DE','LXI','Lichtenstein','Lichtenstein','SN'),('DE','LYC','Lychen','Lychen','BR'),('DE','LZE','Leezen','Leezen','MV'),('DE','LZI','Leizen','Leizen','MV'),('DE','LZN','Langenzenn','Langenzenn','BY'),('DE','MAC','Maisach','Maisach','BY'),('DE','MAD','Marktheidenfeld','Marktheidenfeld','BY'),('DE','MAE','Marne','Marne','SH'),('DE','MAF','Markdorf','Markdorf','BW'),('DE','MAG','Magdeburg','Magdeburg','ST'),('DE','MAH','Mahlberg','Mahlberg','NW'),('DE','MAI','Mainz','Mainz','RP'),('DE','MAL','Marl','Marl','NW'),('DE','MAM','Malente','Malente','SH'),('DE','MAN','Marnheim','Marnheim','RP'),('DE','MAR','Marburg','Marburg','HE'),('DE','MAS','Magstadt','Magstadt','BW'),('DE','MAT','Marktschorgast','Marktschorgast','BY'),('DE','MAU','Mylau','Mylau','SN'),('DE','MAW','Malbergweich','Malbergweich','RP'),('DE','MAX','Maxdorf/Pfalz','Maxdorf/Pfalz','RP'),('DE','MAY','Mayen','Mayen','RP'),('DE','MAZ','Marktredwitz','Marktredwitz','BY'),('DE','MBA','Murlenbach','Murlenbach','RP'),('DE','MBB','Merenberg','Merenberg','HE'),('DE','MBG','Meersburg','Meersburg','BW'),('DE','MBH','Morsbach','Morsbach','NW'),('DE','MBI','Markt Bibart','Markt Bibart','BY'),('DE','MBN','Maulbronn','Maulbronn','BW'),('DE','MBR','Meckenbeuren','Meckenbeuren','BW'),('DE','MBW','Markt Erlbach','Markt Erlbach','BY'),('DE','MBY','Mering','Mering','BY'),('DE','MCB','Mackenbach','Mackenbach','RP'),('DE','MCH','Much','Much','NW'),('DE','MCI','Mechernich','Mechernich','NW'),('DE','MCK','Mucke','Mucke','HE'),('DE','MCN','Malchin','Malchin','MV'),('DE','MDB','Medebach','Medebach','NW'),('DE','MDC','Rodach','Rodach','BY'),('DE','MDF','Mariendorf','Mariendorf','BE'),('DE','MDI','Meiderich','Meiderich','NW'),('DE','MDN','Malterdingen','Malterdingen','BW'),('DE','MDO','Markersdorf','Markersdorf','SN'),('DE','MDT','Mutterstadt','Mutterstadt','RP'),('DE','MDU','Modautal','Modautal','HE'),('DE','MDW','Dodow','Dodow','MV'),('DE','MEB','Morlenbach','Morlenbach','HE'),('DE','MEC','Meckenheim','Meckenheim','NW'),('DE','MED','Meddersheim','Meddersheim','RP'),('DE','MEE','Melle','Melle','NI'),('DE','MEG','Merseburg','Merseburg','ST'),('DE','MEH','Mettlach','Mettlach','SL'),('DE','MEI','Meissen','Meissen','SN'),('DE','MEK','Merkers','Merkers','TH'),('DE','MEL','Meldorf','Meldorf','SH'),('DE','MEM','Memmert','Memmert','NI'),('DE','MEN','Menden/Sauerland','Menden/Sauerland','NW'),('DE','MEP','Meppen','Meppen','NI'),('DE','MER','Merzig','Merzig','SL'),('DE','MES','Messkirch','Messkirch','BW'),('DE','MET','Mettmann','Mettmann','NW'),('DE','MEX','Mieste','Mieste','ST'),('DE','MEY','Meyenburg/Prignitz','Meyenburg/Prignitz','BR'),('DE','MEZ','Meilschnitz','Meilschnitz','BY'),('DE','MFA','Frieda','Frieda','HE'),('DE','MFD','Marienfeld','Marienfeld','NW'),('DE','MFI','Mulfingen','Mulfingen','BW'),('DE','MFL','Malsfeld','Malsfeld','HE'),('DE','MGE','Mengen','Mengen','BW'),('DE','MGI','Mietingen','Mietingen','BW'),('DE','MGL','Monchengladbach','Monchengladbach','NW'),('DE','MGN','Munsingen','Munsingen','BW'),('DE','MGS','Muggensturm','Muggensturm','BW'),('DE','MGU','Gunne/Mohnesee','Gunne/Mohnesee','NW'),('DE','MGX','Mugeln','Mugeln','SN'),('DE','MHD','Marienheide','Marienheide','NW'),('DE','MHE','Moschheim','Moschheim','RP'),('DE','MHF','Mohrendorf','Mohrendorf','BY'),('DE','MHG','Mannheim','Mannheim','BW'),('DE','MHH','Munchhausen','Munchhausen','HE'),('DE','MHI','Meinheim','Meinheim','BY'),('DE','MHL','Muhlhausen','Muhlhausen','TH'),('DE','MHM','Monheim','Monheim','NW'),('DE','MHR','Mehring','Mehring','RP'),('DE','MHT','Murrhardt','Murrhardt','BW'),('DE','MIB','Misburg','Misburg','NI'),('DE','MIC','Michelau in Oberfranken','Michelau in Oberfranken','BY'),('DE','MID','Minden','Minden','NW'),('DE','MIE','Miesbach','Miesbach','BY'),('DE','MIF','Markt Indersdorf','Markt Indersdorf','BY'),('DE','MIH','Mindelheim','Mindelheim','BY'),('DE','MII','Meitingen','Meitingen','BY'),('DE','MIL','Miltenberg','Miltenberg','BY'),('DE','MIN','Minsen','Minsen','NI'),('DE','MIS','Michelstadt','Michelstadt','HE'),('DE','MIT','Mittenwald','Mittenwald','BY'),('DE','MKA','Mulheim-Karlich','Mulheim-Karlich','RP'),('DE','MKD','Merkendorf','Merkendorf','BY'),('DE','MKE','Einersheim','Einersheim','BY'),('DE','MKG','Markgroningen','Markgroningen','BW'),('DE','MKH','Markneukirchen','Markneukirchen','SN'),('DE','MKI','Mengerskirchen','Mengerskirchen','HE'),('DE','MKN','Mariakirchen','Mariakirchen','BY'),('DE','MKS','Markranstadt','Markranstadt','SN'),('DE','MLB','Maulburg','Maulburg','BW'),('DE','MLD','Muhldorf','Muhldorf','HE'),('DE','MLG','Muhlenberg','Muhlenberg','BW'),('DE','MLH','Malsch','Malsch','BW'),('DE','MLM','Muhlheim am Main','Muhlheim am Main','HE'),('DE','MLN','Moglingen','Moglingen','BW'),('DE','MLS','Melsungen','Melsungen','HE'),('DE','MMB','Mombris','Mombris','BY'),('DE','MME','Sommershausen','Sommershausen','BY'),('DE','MMG','Momlingen','Momlingen','BY'),('DE','MML','Mockmuhl','Mockmuhl','BW'),('DE','MMM','Mommenheim','Mommenheim','RP'),('DE','MMN','Memmingen','Memmingen','BY'),('DE','MMO','Mulheim','Mulheim','RP'),('DE','MNB','Mainburg','Mainburg','BY'),('DE','MND','Mending','Mending','RP'),('DE','MNG','Mellingen','Mellingen','TH'),('DE','MNH','Mainhausen','Mainhausen','HE'),('DE','MNI','Meiningen','Meiningen','TH'),('DE','MNN','Mohnsen','Mohnsen','SH'),('DE','MNQ','Munster-Sarmsheim','Munster-Sarmsheim','RP'),('DE','MNR','Munnerstadt','Munnerstadt','BY'),('DE','MNS','Mohnesee','Mohnesee','NW'),('DE','MNT','Mainhardt','Mainhardt','BW'),('DE','MNU','Mildenau','Mildenau','SN'),('DE','MNZ','Monzingen','Monzingen','RP'),('DE','MOB','Mosbach','Mosbach','BW'),('DE','MOD','Moorenweis','Moorenweis','BY'),('DE','MOE','Molln','Molln','SH'),('DE','MOF','Marktoberdorf','Marktoberdorf','BY'),('DE','MOG','Mogendorf','Mogendorf','RP'),('DE','MOH','Moosach','Moosach','BY'),('DE','MOI','Mossingen','Mossingen','BW'),('DE','MOM','Monsheim','Monsheim','BW'),('DE','MON','Montabaur','Montabaur','RP'),('DE','MOO','Moosburg','Moosburg','BY'),('DE','MOR','Morsum','Morsum','SH'),('DE','MOS','Moers','Moers','NW'),('DE','MOT','Motten','Motten','BY'),('DE','MOU','Monschau','Monschau','NW'),('DE','MOW','Manschnow','Manschnow','BR'),('DE','MPF','Mallersdorf-Pfaffenberg','Mallersdorf-Pfaffenberg','BY'),('DE','MPH','Meuspath','Meuspath','RP'),('DE','MQT','Marquardt','Marquardt','BR'),('DE','MRB','Morbach','Morbach','RP'),('DE','MRD','Merbelsrod','Merbelsrod','TH'),('DE','MRE','Meerane','Meerane','SN'),('DE','MRG','Murg','Murg','BW'),('DE','MRH','Meerbusch','Meerbusch','NW'),('DE','MRI','Marienberg','Marienberg','SN'),('DE','MRK','Marklkofen','Marklkofen','BY'),('DE','MRM','Marcardsmoor','Marcardsmoor','NI'),('DE','MRN','Mandern','Mandern','HE'),('DE','MRO','Mullrose','Mullrose','BR'),('DE','MRR','Martinsried','Martinsried','BY'),('DE','MRS','Mariensiel','Mariensiel','NI'),('DE','MRU','Mehrum','Mehrum','NI'),('DE','MRW','Murr','Murr','BW'),('DE','MRZ','Marzling','Marzling','BY'),('DE','MSB','Mittelsburen','Mittelsburen','HB'),('DE','MSC','Maschen','Maschen','NI'),('DE','MSD','Mudersbach','Mudersbach','RP'),('DE','MSE','Meschede','Meschede','NW'),('DE','MSF','Mainaschaff','Mainaschaff','BY'),('DE','MSG','Marsberg','Marsberg','NW'),('DE','MSH','Mescherin','Mescherin','BR'),('DE','MSJ','Mulsen Sankt Jacob','Mulsen Sankt Jacob','SN'),('DE','MSL','Marksuhl','Marksuhl','TH'),('DE','MSN','Markt Schwaben','Markt Schwaben','BY'),('DE','MSO','Moos','Moos','BY'),('DE','MSR','Munster','Munster','NW'),('DE','MSS','Messel','Messel','HE'),('DE','MST','Mellrichstadt','Mellrichstadt','BY'),('DE','MSU','Mossautal','Mossautal','HE'),('DE','MSZ','Mannschatz','Mannschatz','SN'),('DE','MTA','Menteroda','Menteroda','TH'),('DE','MTE','Merdingen','Merdingen','BW'),('DE','MTG','Mertingen','Mertingen','BY'),('DE','MTH','Mitterteich','Mitterteich','BY'),('DE','MTI','Mottingen','Mottingen','BY'),('DE','MTL','Maintal','Maintal','HE'),('DE','MTM','Mettenheim','Mettenheim','RP'),('DE','MTN','Metzingen','Metzingen','BW'),('DE','MTR','Mintraching','Mintraching','BY'),('DE','MTS','Meiste','Meiste','NW'),('DE','MTT','Mettingen','Mettingen','NW'),('DE','MTW','Mittweida','Mittweida','SN'),('DE','MTZ','Mitwitz','Mitwitz','BY'),('DE','MUC','Munchen','Munchen','BY'),('DE','MUD','Munden','Munden','HE'),('DE','MUE','Mullheim','Mullheim','BW'),('DE','MUF','Muhldorf am Inn','Muhldorf am Inn','BY'),('DE','MUG','Munchberg','Munchberg','BY'),('DE','MUH','Mulheim an der Ruhr','Mulheim an der Ruhr','NW'),('DE','MUK','Mukran','Mukran','MV'),('DE','MUL','Muhlacker','Muhlacker','BW'),('DE','MUM','Munchsmunster','Munchsmunster','BY'),('DE','MUN','Munster','Munster','NI'),('DE','MUR','Murnau','Murnau','BY'),('DE','MUS','Munster','Munster','HE'),('DE','MUT','Muhltal','Muhltal','HE'),('DE','MUU','Mudau','Mudau','BW'),('DE','MUW','Munchweiler an der Rodalbe','Munchweiler an der Rodalbe','RP'),('DE','MUX','Mauer','Mauer','BW'),('DE','MUZ','Mutzschen','Mutzschen','SN'),('DE','MWA','Morfelden-Walldorf','Morfelden-Walldorf','HE'),('DE','MWF','Mittelherwigsdorf','Mittelherwigsdorf','SN'),('DE','MWH','Maroldsweisach','Maroldsweisach','BY'),('DE','MWN','Mochenwangen','Mochenwangen','BW'),('DE','MWZ','Meuselwitz','Meuselwitz','TH'),('DE','MXA','Maxau','Maxau','BW'),('DE','MXM','Maximiliansau','Maximiliansau','RP'),('DE','MZH','Merzenich','Merzenich','NW'),('DE','MZN','Meinerzhagen','Meinerzhagen','NW'),('DE','MZW','Miltzow','Miltzow','MV'),('DE','NAB','Nabburg','Nabburg','BY'),('DE','NAC','Nackenheim','Nackenheim','RP'),('DE','NAG','Nagold','Nagold','BW'),('DE','NAI','Neuburg Am Inn','Neuburg Am Inn','BY'),('DE','NAN','Nastatten','Nastatten','RP'),('DE','NAR','Neuhaus am Rennweg','Neuhaus am Rennweg','TH'),('DE','NAS','Neuenhaus','Neuenhaus','NI'),('DE','NAT','Nattheim','Nattheim','BW'),('DE','NBA','Neu Bartelshagen','Neu Bartelshagen','MV'),('DE','NBE','Niederbergkirchen','Niederbergkirchen','BY'),('DE','NBG','Neuburg an der Donau','Neuburg an der Donau','BY'),('DE','NBH','Niederaichbach','Niederaichbach','BY'),('DE','NBN','Nordhalben','Nordhalben','BY'),('DE','NBR','Neuenburg am Rhein','Neuenburg am Rhein','BW'),('DE','NBU','Naumburg','Naumburg','ST'),('DE','NBW','Neunburg vorm Wald','Neunburg vorm Wald','BY'),('DE','NCA','Neuscharrel','Neuscharrel','NI'),('DE','NCH','Nachrodt','Nachrodt','NW'),('DE','NCN','Neunkirchen/Siegen','Neunkirchen/Siegen','NW'),('DE','NCZ','Nieschutz','Nieschutz','SN'),('DE','NDB','Niedernberg','Niedernberg','BY'),('DE','NDD','Norddeich/Dithmarschen','Norddeich/Dithmarschen','SH'),('DE','NDF','Neuendorf','Neuendorf','TH'),('DE','NDH','Nordhausen','Nordhausen','TH'),('DE','NDL','Niederlehme','Niederlehme','BR'),('DE','NDM','Nordheim','Nordheim','BY'),('DE','NDN','Neidenstein','Neidenstein','BW'),('DE','NDO','Niederdorla','Niederdorla','TH'),('DE','NDR','Niederirsen','Niederirsen','RP'),('DE','NDT','Neustadt','Neustadt','HE'),('DE','NDW','Nieder-Werbe','Nieder-Werbe','HE'),('DE','NEA','Neureichenau','Neureichenau','BY'),('DE','NEB','Neubrandenburg','Neubrandenburg','MV'),('DE','NEC','Neustadt/Coburg','Neustadt/Coburg','BY'),('DE','NED','Neuwied','Neuwied','RP'),('DE','NEE','Neubrucke','Neubrucke','RP'),('DE','NEF','Neufeld','Neufeld','SH'),('DE','NEG','Neuenburg','Neuenburg','BW'),('DE','NEH','Neuhaus an der Oste','Neuhaus an der Oste','NI'),('DE','NEI','Neidenfels/Pfalz','Neidenfels/Pfalz','RP'),('DE','NEK','Neuenkirchen','Neuenkirchen','NW'),('DE','NEL','Neuland/Elbe','Neuland/Elbe','NI'),('DE','NEM','Neckarsulm','Neckarsulm','BW'),('DE','NEN','Neunkirchen-Seelscheid','Neunkirchen-Seelscheid','NW'),('DE','NER','Neustrelitz','Neustrelitz','MV'),('DE','NES','Nessmersiel','Nessmersiel','NI'),('DE','NET','Neumarkt in der Oberpfalz','Neumarkt in der Oberpfalz','BY'),('DE','NEU','Neumunster','Neumunster','SH'),('DE','NEV','Neuenrade','Neuenrade','NW'),('DE','NEW','Neustadt (Wied)','Neustadt (Wied)','RP'),('DE','NEX','Neustadt','Neustadt','SN'),('DE','NEZ','Neckarelz','Neckarelz','BW'),('DE','NFB','Niederfischbach','Niederfischbach','RP'),('DE','NFF','Neufahrn bei Freising','Neufahrn bei Freising','BY'),('DE','NFN','Niefern','Niefern','BW'),('DE','NGD','Neugersdorf','Neugersdorf','SN'),('DE','NGH','Niederneuching','Niederneuching','BY'),('DE','NGK','Neuburg an der Kammel','Neuburg an der Kammel','BY'),('DE','NGL','Neustadt-Glewe','Neustadt-Glewe','MV'),('DE','NGN','Nellingen','Nellingen','BW'),('DE','NGO','Nemsdorf Gohrendorf','Nemsdorf Gohrendorf','ST'),('DE','NHA','Nordenham','Nordenham','NI'),('DE','NHE','Nordheim','Nordheim','BW'),('DE','NHF','Neuhausen auf den Fildern','Neuhausen auf den Fildern','BW'),('DE','NHL','Niehl/Koln','Niehl/Koln','NW'),('DE','NHN','Nordhorn','Nordhorn','NI'),('DE','NHO','Neustadt in Holstein','Neustadt in Holstein','SH'),('DE','NHS','Neuharlingersiel','Neuharlingersiel','NI'),('DE','NHT','Niederhochstadt','Niederhochstadt','RP'),('DE','NHU','Nentershausen','Nentershausen','HE'),('DE','NIA','Niederaula','Niederaula','HE'),('DE','NIB','Neubiberg','Neubiberg','BY'),('DE','NID','Nidda','Nidda','HE'),('DE','NIE','Nienburg','Nienburg','NI'),('DE','NIG','Neulingen','Neulingen','ST'),('DE','NIK','Neukirch','Neukirch','SN'),('DE','NIL','Niebull','Niebull','SH'),('DE','NIN','Nierstein','Nierstein','RP'),('DE','NIR','Niederzier','Niederzier','NW'),('DE','NIS','Neu Isenburg','Neu Isenburg','HE'),('DE','NIT','Nittenau','Nittenau','BY'),('DE','NIX','Niersbach','Niersbach','RP'),('DE','NKC','Neukirchen/Pleisse','Neukirchen/Pleisse','SN'),('DE','NKI','Neukirchen im Erzgebirge','Neukirchen im Erzgebirge','SN'),('DE','NKL','Niederkassel','Niederkassel','NW'),('DE','NKN','Neunkirchen','Neunkirchen','SL'),('DE','NKS','Neunkirchen am Sand','Neunkirchen am Sand','BY'),('DE','NKT','Neuenkirchen/Steinfurt','Neuenkirchen/Steinfurt','NW'),('DE','NKV','Neukirchen','Neukirchen','NW'),('DE','NKZ','Neckartenzlingen','Neckartenzlingen','BW'),('DE','NLA','Naila','Naila','BY'),('DE','NLM','Neulussheim','Neulussheim','BW'),('DE','NLN','Nottuln','Nottuln','NW'),('DE','NMD','Neckargemund','Neckargemund','BW'),('DE','NMF','Nentmannsdorf','Nentmannsdorf','SN'),('DE','NMG','Niemegk','Niemegk','BR'),('DE','NMN','Neumagen','Neumagen','RP'),('DE','NMT','Nempitz','Nempitz','ST'),('DE','NND','Sonnefeld','Sonnefeld','BY'),('DE','NNN','Nienhagen (bei Celle)','Nienhagen (bei Celle)','NI'),('DE','NNP','Kenn','Kenn','RP'),('DE','NNS','Niederneisen','Niederneisen','RP'),('DE','NNT','Neuenstadt am Kocher','Neuenstadt am Kocher','BW'),('DE','NNW','Nonnweiler','Nonnweiler','SL'),('DE','NOC','Nochten','Nochten','SN'),('DE','NOD','Norden','Norden','NI'),('DE','NOE','Norddeich','Norddeich','NI'),('DE','NOH','Norten-Hardenberg','Norten-Hardenberg','NI'),('DE','NOL','Nieder-Olm','Nieder-Olm','RP'),('DE','NOM','Northeim','Northeim','NI'),('DE','NON','Nordlingen','Nordlingen','BY'),('DE','NOP','Nortrup','Nortrup','NI'),('DE','NOR','Nordstrand','Nordstrand','SH'),('DE','NOT','Norderstedt','Norderstedt','SH'),('DE','NPN','Netphen','Netphen','NW'),('DE','NPO','Neuengonna-Porstendorf','Neuengonna-Porstendorf','TH'),('DE','NPP','Neuruppin','Neuruppin','BR'),('DE','NRA','Nohra','Nohra','TH'),('DE','NRB','Neustadt am Rubenberge','Neustadt am Rubenberge','NI'),('DE','NRC','Nordrach','Nordrach','BW'),('DE','NRD','Norderney','Norderney','NI'),('DE','NRH','Niedernhausen','Niedernhausen','HE'),('DE','NRN','Niederkruchten','Niederkruchten','NW'),('DE','NRS','Niederorschel','Niederorschel','TH'),('DE','NRW','Neuweier','Neuweier','BW'),('DE','NSA','Neustadt/Aisch','Neustadt/Aisch','BY'),('DE','NSB','Neustadt an der Waldnaab','Neustadt an der Waldnaab','BY'),('DE','NSC','Neuenschleuse','Neuenschleuse','NI'),('DE','NSD','Neustadt','Neustadt','BR'),('DE','NSE','Neuessen','Neuessen','NW'),('DE','NSH','Neresheim','Neresheim','BW'),('DE','NSL','Niestetal','Niestetal','HE'),('DE','NSN','Nossen','Nossen','SN'),('DE','NSS','Neuss','Neuss','NW'),('DE','NST','Neckarsteinach','Neckarsteinach','HE'),('DE','NSU','Nassau/Lahn','Nassau/Lahn','RP'),('DE','NSV','Neumarkt-Sankt Veit','Neumarkt-Sankt Veit','BY'),('DE','NSW','Neustadt/Weinstrasse','Neustadt/Weinstrasse','RP'),('DE','NSZ','Neusitz','Neusitz','BY'),('DE','NTA','Neckartailfingen','Neckartailfingen','BW'),('DE','NTD','Neustadt an der Donau','Neustadt an der Donau','BY'),('DE','NTE','Neuenstein','Neuenstein','BW'),('DE','NTF','Nortorf','Nortorf','SH'),('DE','NTG','Neutraubling','Neutraubling','BY'),('DE','NTH','Nathern','Nathern','ST'),('DE','NTL','Nettetal','Nettetal','NW'),('DE','NTN','Neitersen','Neitersen','RP'),('DE','NTR','Nister','Nister','RP'),('DE','NTZ','Nunchritz','Nunchritz','SN'),('DE','NUA','Neu-Anspach','Neu-Anspach','HE'),('DE','NUE','Nurnberg','Nurnberg','BY'),('DE','NUF','Nufringen','Nufringen','BW'),('DE','NUG','Neuerburg','Neuerburg','RP'),('DE','NUH','Nussloch','Nussloch','BW'),('DE','NUI','Neuotting','Neuotting','BY'),('DE','NUL','Neu Ulm','Neu Ulm','BY'),('DE','NUM','Nauheim','Nauheim','HE'),('DE','NUN','Nurtingen','Nurtingen','BW'),('DE','NUQ','Nauen','Nauen','BR'),('DE','NUS','Neusass','Neusass','BY'),('DE','NUT','Numbrecht','Numbrecht','NW'),('DE','NUX','Neuhausen','Neuhausen','BW'),('DE','NVL','Neukirchen-Vluyn','Neukirchen-Vluyn','NW'),('DE','NWE','Nordwalde','Nordwalde','NW'),('DE','NWF','Niederwalluf','Niederwalluf','HE'),('DE','NWK','Niederwinkling','Niederwinkling','BY'),('DE','NWM','Niederwerrn','Niederwerrn','BY'),('DE','NWR','Neuweiler','Neuweiler','BW'),('DE','NWU','Neu Wulmstorf','Neu Wulmstorf','NI'),('DE','NXF','Neuffen','Neuffen','BW'),('DE','NZK','Netzschkau','Netzschkau','SN'),('DE','OAN','Oberhausen an der Nahe','Oberhausen an der Nahe','RP'),('DE','OAU','Ostrau','Ostrau','SN'),('DE','OBA','Oberammergau','Oberammergau','BY'),('DE','OBC','Oberasbach','Oberasbach','BY'),('DE','OBD','Oberdachstetten','Oberdachstetten','BY'),('DE','OBE','Oberhausen','Oberhausen','NW'),('DE','OBF','Oberstdorf','Oberstdorf','BY'),('DE','OBG','Obernburg am Main','Obernburg am Main','BY'),('DE','OBH','Oberwolfach','Oberwolfach','BW'),('DE','OBK','Obernkirchen','Obernkirchen','NI'),('DE','OBL','Oberursel','Oberursel','HE'),('DE','OBN','Obertshausen','Obertshausen','HE'),('DE','OBR','Ober Ramstadt','Ober Ramstadt','HE'),('DE','OBS','Oberschleissheim','Oberschleissheim','BY'),('DE','OBT','Obertraubling','Obertraubling','BY'),('DE','OBU','Olbernhau','Olbernhau','SN'),('DE','OBV','Oberviechtach','Oberviechtach','BY'),('DE','OBW','Oberweser','Oberweser','HE'),('DE','OCE','Ortenburg','Ortenburg','BY'),('DE','OCF','Ochsenfurt','Ochsenfurt','BY'),('DE','OCH','Ochsenhausen','Ochsenhausen','BW'),('DE','OCP','Ostercappeln','Ostercappeln','NI'),('DE','OCT','Ochtrup','Ochtrup','NW'),('DE','ODE','Odenthal','Odenthal','NW'),('DE','ODF','Oberndorf am Neckar','Oberndorf am Neckar','BW'),('DE','ODM','Bodenheim','Bodenheim','RP'),('DE','ODN','Oberderdingen','Oberderdingen','BW'),('DE','ODQ','Offenbach an der Queich','Offenbach an der Queich','RP'),('DE','ODR','Ohrdruf','Ohrdruf','TH'),('DE','OEA','Oelsa/Freital','Oelsa/Freital','SN'),('DE','OED','Oederan','Oederan','SN'),('DE','OEH','Ohringen','Ohringen','BW'),('DE','OEL','Oelde','Oelde','NW'),('DE','OEN','Oerlinghausen','Oerlinghausen','NW'),('DE','OER','Oer-Erkenschwick','Oer-Erkenschwick','NW'),('DE','OES','Ostringen','Ostringen','BW'),('DE','OEV','Oversee','Oversee','SH'),('DE','OFD','Oberstenfeld','Oberstenfeld','BW'),('DE','OFF','Offenbach','Offenbach','HE'),('DE','OFG','Offenburg','Offenburg','BW'),('DE','OFH','Offenhausen','Offenhausen','BY'),('DE','OFN','Offingen','Offingen','BY'),('DE','OFT','Ofterschwang','Ofterschwang','BY'),('DE','OGH','Obrigheim','Obrigheim','BW'),('DE','OGL','Obermassfeld-Grimmenthal','Obermassfeld-Grimmenthal','TH'),('DE','OHA','Oberhaching','Oberhaching','BY'),('DE','OHF','Ostrhauderfehn','Ostrhauderfehn','NI'),('DE','OHG','Ohningen','Ohningen','BW'),('DE','OHI','Ottenheim','Ottenheim','BW'),('DE','OHN','Osterhofen','Osterhofen','BY'),('DE','OHO','Oberhochstadt','Oberhochstadt','RP'),('DE','OHR','Oberahr','Oberahr','RP'),('DE','OKH','Oberkirch','Oberkirch','BW'),('DE','OKL','Oberkleen','Oberkleen','HE'),('DE','OKO','Oberkochen','Oberkochen','BW'),('DE','OKY','Oberkotzau','Oberkotzau','BY'),('DE','OLB','Oldenbuttel','Oldenbuttel','SH'),('DE','OLC','Olching','Olching','BY'),('DE','OLD','Oldendorf','Oldendorf','NI'),('DE','OLE','Olpe','Olpe','NW'),('DE','OLF','Olbersdorf','Olbersdorf','SN'),('DE','OLH','Oldenburg in Holstein','Oldenburg in Holstein','SH'),('DE','OLK','Wolkenstein','Wolkenstein','SN'),('DE','OLN','Oschersleben','Oschersleben','ST'),('DE','OLO','Oldenburg','Oldenburg','NI'),('DE','OLP','Olpenitz','Olpenitz','SH'),('DE','OLS','Olsberg','Olsberg','NW'),('DE','OMH','Obermarschacht','Obermarschacht','NI'),('DE','ONM','Osann-Monzel','Osann-Monzel','RP'),('DE','OOA','Oberdorla','Oberdorla','TH'),('DE','OOO','Ottensoos','Ottensoos','BY'),('DE','OOT','Oberrot','Oberrot','BW'),('DE','OPB','Opfenbach','Opfenbach','BY'),('DE','OPG','Oppurg','Oppurg','TH'),('DE','OPP','Oppenheim','Oppenheim','RP'),('DE','OPU','Oppenau','Oppenau','BW'),('DE','ORA','Oranienburg','Oranienburg','BR'),('DE','ORB','Ortenberg','Ortenberg','HE'),('DE','ORC','Orbis','Orbis','RP'),('DE','ORF','Michendorf','Michendorf','BR'),('DE','ORM','Obermorlen','Obermorlen','HE'),('DE','ORS','Orsoy','Orsoy','NW'),('DE','ORT','Orth/Fehmarn','Orth/Fehmarn','SH'),('DE','OSB','Ossenberg','Ossenberg','NW'),('DE','OSD','Rosendahl','Rosendahl','NW'),('DE','OSE','Osterode am Harz','Osterode am Harz','NI'),('DE','OSF','Ostfildern','Ostfildern','BW'),('DE','OSH','Osterhausen','Osterhausen','ST'),('DE','OSK','Oststeinbek','Oststeinbek','SH'),('DE','OSL','Osloss','Osloss','NI'),('DE','OSM','Obersulm','Obersulm','BW'),('DE','OSN','Osnabruck','Osnabruck','NI'),('DE','OSR','Ostermoor','Ostermoor','SH'),('DE','OSS','Osterholz-Scharmbeck','Osterholz-Scharmbeck','NI'),('DE','OST','Osterburken','Osterburken','BW'),('DE','OSW','Oestrich-Winkel','Oestrich-Winkel','HE'),('DE','OSZ','Oelsnitz','Oelsnitz','SN'),('DE','OTB','Ottobeuren','Ottobeuren','BY'),('DE','OTD','Ortrand','Ortrand','BR'),('DE','OTG','Otigheim','Otigheim','BW'),('DE','OTK','Oortkaten','Oortkaten','HH'),('DE','OTL','Otzberg Lengfeld','Otzberg Lengfeld','RP'),('DE','OTN','Ottobrunn','Ottobrunn','BY'),('DE','OTR','Ottersheim','Ottersheim','RP'),('DE','OTT','Otterndorf','Otterndorf','NI'),('DE','OTV','Ostbevern','Ostbevern','NW'),('DE','OTZ','Oschatz','Oschatz','SN'),('DE','OUH','Oberaurach','Oberaurach','BY'),('DE','OVE','Ovelgonne','Ovelgonne','NI'),('DE','OWD','Osterweddingen','Osterweddingen','ST'),('DE','OWE','Ottweiler','Ottweiler','SL'),('DE','OWL','Ohlweiler','Ohlweiler','RP'),('DE','OWN','Owen','Owen','BW'),('DE','OWT','Oberwinter','Oberwinter','RP'),('DE','OYT','Oyten','Oyten','NI'),('DE','OZG','Otzberg','Otzberg','HE'),('DE','OZH','Obersontheim','Obersontheim','BW'),('DE','PAD','Paderborn','Paderborn','NW'),('DE','PAH','Pahlhude','Pahlhude','SH'),('DE','PAP','Papenburg','Papenburg','NI'),('DE','PAR','Parsberg','Parsberg','BY'),('DE','PAS','Passau','Passau','BY'),('DE','PBG','Peissenberg','Peissenberg','BY'),('DE','PBN','Putzbrunn','Putzbrunn','BY'),('DE','PCH','Parchim','Parchim','MV'),('DE','PDF','Puschendorf','Puschendorf','BY'),('DE','PDO','Parsdorf','Parsdorf','BY'),('DE','PEB','Perleberg','Perleberg','BR'),('DE','PEF','Peenemunde','Peenemunde','MV'),('DE','PEG','Pegnitz','Pegnitz','BY'),('DE','PEI','Peine','Peine','NI'),('DE','PEL','Pellworm','Pellworm','SH'),('DE','PEN','Pente','Pente','NI'),('DE','PER','Perlesreut','Perlesreut','BY'),('DE','PET','Petersberg','Petersberg','HE'),('DE','PEZ','Penzberg','Penzberg','BY'),('DE','PFA','Pfaffenhofen an der Ilm','Pfaffenhofen an der Ilm','BY'),('DE','PFD','Pleinfeld','Pleinfeld','BY'),('DE','PFE','Pfatter','Pfatter','BY'),('DE','PFF','Pfaffenhausen ','Pfaffenhausen ','BY'),('DE','PFJ','Pfaffenhofen an der Glonn','Pfaffenhofen an der Glonn','BY'),('DE','PFK','Pfarrkirchen','Pfarrkirchen','BY'),('DE','PFN','Pfullingen','Pfullingen','BW'),('DE','PFO','Pforzheim','Pforzheim','BW'),('DE','PFR','Pfronten','Pfronten','BY'),('DE','PFS','Pfaffen-Schwabenheim','Pfaffen-Schwabenheim','RP'),('DE','PFT','Pfungstadt','Pfungstadt','HE'),('DE','PFU','Pfullendorf','Pfullendorf','BW'),('DE','PGR','Pfalzgrafenweiler','Pfalzgrafenweiler','BW'),('DE','PHG','Philippsburg','Philippsburg','BW'),('DE','PHI','Philippsthal','Philippsthal','HE'),('DE','PHL','Puhlheim','Puhlheim','BY'),('DE','PHN','Pluderhausen','Pluderhausen','BW'),('DE','PHS','Pfeffenhausen','Pfeffenhausen','BY'),('DE','PHT','Philippsthal','Philippsthal','BR'),('DE','PIG','Penig','Penig','SN'),('DE','PIN','Pinneberg','Pinneberg','SH'),('DE','PIR','Pirmasens','Pirmasens','RP'),('DE','PIZ','Prittitz','Prittitz','ST'),('DE','PJI','Petersaurach','Petersaurach','BY'),('DE','PKS','Plankstadt','Plankstadt','BW'),('DE','PKU','Putzkau','Putzkau','SN'),('DE','PLA','Plattling','Plattling','BY'),('DE','PLE','Plettenberg','Plettenberg','NW'),('DE','PLG','Planegg','Planegg','BY'),('DE','PLH','Pleidelsheim','Pleidelsheim','BW'),('DE','PLL','Pollhagen','Pollhagen','NI'),('DE','PLN','Plon','Plon','SH'),('DE','PLO','Plochingen','Plochingen','BW'),('DE','PLS','Pliezhausen','Pliezhausen','BW'),('DE','PLT','Plaidt','Plaidt','RP'),('DE','PLU','Plauen','Plauen','SN'),('DE','PLZ','Plotzin','Plotzin','BR'),('DE','PMD','Pfreimd','Pfreimd','BY'),('DE','PNN','Pattensen','Pattensen','NI'),('DE','POC','Pocking','Pocking','BY'),('DE','POE','Pollenfeld Wieger','Pollenfeld Wieger','BY'),('DE','POG','Poing','Poing','BY'),('DE','POH','Pohlheim','Pohlheim','HE'),('DE','POK','Pokrent','Pokrent','MV'),('DE','POL','Preussisch-Oldendorf','Preussisch-Oldendorf','NW'),('DE','POM','Pomellen','Pomellen','MV'),('DE','POR','Porz','Porz','NW'),('DE','POS','Postbauer-Heng','Postbauer-Heng','BY'),('DE','POT','Potsdam','Potsdam','BR'),('DE','POW','Porta Westfalica','Porta Westfalica','NW'),('DE','PPE','Poppenroth','Poppenroth','BY'),('DE','PPP','Pappenheim','Pappenheim','BY'),('DE','PPT','Piesport','Piesport','RP'),('DE','PQL','Polch','Polch','RP'),('DE','PRA','Pirna','Pirna','SN'),('DE','PRE','Preetz','Preetz','SH'),('DE','PRI','Prien/Chiemsee','Prien/Chiemsee','BY'),('DE','PRK','Pritzwalk','Pritzwalk','BR'),('DE','PRS','Prisdorf','Prisdorf','BE'),('DE','PRT','Prichsenstadt','Prichsenstadt','BY'),('DE','PRU','Prum','Prum','RP'),('DE','PRW','Prerow','Prerow','MV'),('DE','PRY','Parey','Parey','BR'),('DE','PSA','Plessa','Plessa','BR'),('DE','PSB','Piesberger','Piesberger','NI'),('DE','PSD','Porschendorf','Porschendorf','SN'),('DE','PSH','St Peter-Ording','St Peter-Ording','SH'),('DE','PSM','Postmunster','Postmunster','BY'),('DE','PSN','Pottenstein','Pottenstein','BY'),('DE','PSR','Piesteritz','Piesteritz','ST'),('DE','PSU','Piesau','Piesau','TH'),('DE','PSW','Petershagen/Weser','Petershagen/Weser','NW'),('DE','PSZ','Priessnitz','Priessnitz','SN'),('DE','PTD','Petersdorf','Petersdorf','BY'),('DE','PTG','Peiting','Peiting','BY'),('DE','PTH','Petershausen','Petershausen','BY'),('DE','PTN','Parkentin','Parkentin','MV'),('DE','PTS','Partenstein','Partenstein','BY'),('DE','PTU','Pratau','Pratau','ST'),('DE','PTV','Possneck','Possneck','TH'),('DE','PTZ','Premnitz','Premnitz','BR'),('DE','PUC','Puchheim','Puchheim','BY'),('DE','PUH','Pullach','Pullach','BY'),('DE','PUI','Pullach im Isartal','Pullach im Isartal','BY'),('DE','PUL','Pulheim','Pulheim','NW'),('DE','PUM','Pullenreuth','Pullenreuth','BY'),('DE','PUT','Puttgarden','Puttgarden','SH'),('DE','PUZ','Putzborn','Putzborn','RP'),('DE','PWK','Pasewalk','Pasewalk','MV'),('DE','PWZ','Priestewitz','Priestewitz','SN'),('DE','PZB','Patz','Patz','BR'),('DE','PZD','Pretzfeld','Pretzfeld','BY'),('DE','PZI','Pautzfeld','Pautzfeld','BY'),('DE','QHA','Aspisheim','Aspisheim','RP'),('DE','QKB','Quickborn','Quickborn','SH'),('DE','QUA','Quakenbruck','Quakenbruck','NI'),('DE','QUE','Quedlinburg','Quedlinburg','ST'),('DE','QUS','Queis','Queis','ST'),('DE','RAB','Rabenau','Rabenau','SN'),('DE','RAD','Radolfzell','Radolfzell','BW'),('DE','RAE','Rastede','Rastede','NI'),('DE','RAF','Raisdorf','Raisdorf','SH'),('DE','RAG','Radeberg','Radeberg','SN'),('DE','RAH','Rahden','Rahden','NW'),('DE','RAI','Rott am Inn','Rott am Inn','BY'),('DE','RAK','Ratekau','Ratekau','SH'),('DE','RAL','Rain am Lech','Rain am Lech','BY'),('DE','RAM','Ramstein-Miesenbach','Ramstein-Miesenbach','RP'),('DE','RAN','Rantum','Rantum','SH'),('DE','RAR','Ruhstorf an der Rott','Ruhstorf an der Rott','BY'),('DE','RAS','Rastatt','Rastatt','BW'),('DE','RAT','Ratingen','Ratingen','NW'),('DE','RAU','Raunheim','Raunheim','HE'),('DE','RAV','Ravensburg','Ravensburg','BW'),('DE','RAX','Ranstadt','Ranstadt','HE'),('DE','RBA','Ransbach-Baumbach','Ransbach-Baumbach','RP'),('DE','RBB','Rheinbreitbach','Rheinbreitbach','RP'),('DE','RBC','Raubach','Raubach','HE'),('DE','RBE','Ronsberg','Ronsberg','BY'),('DE','RBF','Rotenburg an der Fulda','Rotenburg an der Fulda','HE'),('DE','RBG','Rauschenberg','Rauschenberg','HE'),('DE','RBH','Rottenbach','Rottenbach','BY'),('DE','RBK','Riesenbeck','Riesenbeck','NW'),('DE','RBL','Radebeul','Radebeul','SN'),('DE','RBN','Rheinbollen','Rheinbollen','RP'),('DE','RBS','Baar-Ebenhausen','Baar-Ebenhausen','BY'),('DE','RCH','Rohrnbach','Rohrnbach','BY'),('DE','RCK','Recke','Recke','NW'),('DE','RCN','Renchen','Renchen','BW'),('DE','RDB','Rieden (Amberg-Sulzbach)','Rieden (Amberg-Sulzbach)','BY'),('DE','RDE','Riede','Riede','NI'),('DE','RDF','Rossdorf','Rossdorf','HE'),('DE','RDG','Roding','Roding','BY'),('DE','RDH','Rodach','Rodach','BY'),('DE','RDL','Riedlhutte','Riedlhutte','BY'),('DE','RDN','Rehden','Rehden','NI'),('DE','RDO','Rudersdorf','Rudersdorf','BR'),('DE','RDR','Rohrsdorf','Rohrsdorf','SN'),('DE','RDT','Rot an der Rot','Rot an der Rot','BW'),('DE','RDU','Radeburg','Radeburg','SN'),('DE','RDV','Radevormwald','Radevormwald','NW'),('DE','RDW','Rudow','Rudow','BE'),('DE','RDZ','Riederich','Riederich','BW'),('DE','REC','Recklinghausen','Recklinghausen','NW'),('DE','RED','Remscheid','Remscheid','NW'),('DE','REE','Reepsholt','Reepsholt','NI'),('DE','REF','Rengsdorf','Rengsdorf','RP'),('DE','REG','Regensburg','Regensburg','BY'),('DE','REH','Rednitzhembach','Rednitzhembach','BY'),('DE','REI','Reinbek','Reinbek','SH'),('DE','REK','Reken','Reken','NW'),('DE','REL','Rellingen','Rellingen','SH'),('DE','REM','Remagen','Remagen','RP'),('DE','REN','Rendsburg','Rendsburg','SH'),('DE','RER','Rehe','Rehe','RP'),('DE','RES','Rees','Rees','NW'),('DE','RET','Rethem','Rethem','NI'),('DE','REU','Reutlingen','Reutlingen','BW'),('DE','RFA','Reinsdorf','Reinsdorf','NI'),('DE','RFD','Reinfeld','Reinfeld','SH'),('DE','RFE','Radefeld','Radefeld','SN'),('DE','RFI','Reichenbach an der Fils','Reichenbach an der Fils','BW'),('DE','RFN','Rheinfelden','Rheinfelden','BW'),('DE','RGB','Riegelsberg','Riegelsberg','SL'),('DE','RGD','Roggendorf','Roggendorf','MV'),('DE','RGH','Roigheim','Roigheim','BW'),('DE','RGI','Ringsheim','Ringsheim','BW'),('DE','RGL','Riegel','Riegel','BW'),('DE','RGN','Regen','Regen','BY'),('DE','RGU','Rodinghausen','Rodinghausen','NW'),('DE','RGZ','Rogatz','Rogatz','ST'),('DE','RHA','Reckertshausen','Reckertshausen','BY'),('DE','RHB','Rheinberg','Rheinberg','NW'),('DE','RHD','Rheindahlen','Rheindahlen','NW'),('DE','RHE','Rheine','Rheine','NW'),('DE','RHF','Rohrdorf','Rohrdorf','BY'),('DE','RHH','Rheinbach','Rheinbach','NW'),('DE','RHI','Rheinau, Ortenaukreis','Rheinau, Ortenaukreis','BW'),('DE','RHL','Rheinbrohl','Rheinbrohl','RP'),('DE','RHM','Reinheim','Reinheim','HE'),('DE','RHN','Remshalden','Remshalden','BW'),('DE','RHQ','Rotthalmunster','Rotthalmunster','BY'),('DE','RHR','Rheinmunster','Rheinmunster','BW'),('DE','RHS','Reinhardtsdorf-Schona','Reinhardtsdorf-Schona','SN'),('DE','RHT','Rhodt','Rhodt','RP'),('DE','RHU','Rehau','Rehau','BY'),('DE','RHW','Rheda-Wiedenbruck','Rheda-Wiedenbruck','NW'),('DE','RHZ','Rochlitz','Rochlitz','SN'),('DE','RIA','Rielasingen-Worblingen','Rielasingen-Worblingen','BW'),('DE','RIB','Reisenbach','Reisenbach','BW'),('DE','RID','Ried','Ried','HE'),('DE','RIE','Riedlingen','Riedlingen','BW'),('DE','RIG','Rietberg','Rietberg','NW'),('DE','RII','Reilingen','Reilingen','BW'),('DE','RIK','Rieneck','Rieneck','BY'),('DE','RIL','Rinnthal','Rinnthal','RP'),('DE','RIM','Rimbach','Rimbach','HE'),('DE','RIN','Rinteln','Rinteln','NI'),('DE','RIP','Rippershausen','Rippershausen','TH'),('DE','RIT','Ritsch','Ritsch','NI'),('DE','RIZ','Britz','Britz','BE'),('DE','RKH','Ruckholz','Ruckholz','BY'),('DE','RKN','Reiskirchen','Reiskirchen','HE'),('DE','RKW','Rackwitz','Rackwitz','SN'),('DE','RLA','Rottenburg an der Laaber','Rottenburg an der Laaber','BY'),('DE','RLG','Raubling','Raubling','BY'),('DE','RLH','Riemsloh','Riemsloh','NI'),('DE','RLI','Remlingen','Remlingen','BY'),('DE','RLM','Reichelsheim','Reichelsheim','HE'),('DE','RLN','Rossleben','Rossleben','TH'),('DE','RLO','Rehburg-Loccum','Rehburg-Loccum','NI'),('DE','RLU','Rosslau','Rosslau','ST'),('DE','RMD','Rathmannsdorf','Rathmannsdorf','SN'),('DE','RMM','Rammingen','Rammingen','BW'),('DE','RMO','Ramelsloh','Ramelsloh','NI'),('DE','RNA','Bernau','Bernau','BW'),('DE','RNB','Rothenbach','Rothenbach','BY'),('DE','RND','Rennerod','Rennerod','RP'),('DE','RNG','Rottenegg (Geisenfeld)','Rottenegg (Geisenfeld)','BY'),('DE','RNH','Rheinhausen','Rheinhausen','BW'),('DE','RNI','Rammelsbach','Rammelsbach','RP'),('DE','RNN','Renningen','Renningen','BW'),('DE','RNT','Runthe','Runthe','NW'),('DE','RNU','Reichenau','Reichenau','BW'),('DE','RNW','Rathenow','Rathenow','BR'),('DE','ROB','Rodenbach','Rodenbach','HE'),('DE','ROC','Rockenberg','Rockenberg','HE'),('DE','ROD','Rodenkirchen','Rodenkirchen','NI'),('DE','ROE','Roblingen am See','Roblingen am See','ST'),('DE','ROF','Reichshof','Reichshof','NW'),('DE','ROG','Romerberg','Romerberg','RP'),('DE','ROH','Rockenhausen','Rockenhausen','RP'),('DE','ROK','Rodermark','Rodermark','HE'),('DE','ROL','Rottweil','Rottweil','BW'),('DE','RON','Ronneburg','Ronneburg','TH'),('DE','ROO','Rottleberode','Rottleberode','ST'),('DE','ROP','Rothenbach an der Pegnitz','Rothenbach an der Pegnitz','BY'),('DE','ROR','Ruhrort','Ruhrort','NW'),('DE','ROS','Rosenheim','Rosenheim','BY'),('DE','ROT','Rothenburg ob der Tauber','Rothenburg ob der Tauber','BY'),('DE','ROU','Rodgau','Rodgau','HE'),('DE','ROW','Rotenburg/Wumme','Rotenburg/Wumme','NI'),('DE','RPE','Rampe','Rampe','MV'),('DE','RPN','Riepen','Riepen','NI'),('DE','RRH','Rosrath','Rosrath','NW'),('DE','RRO','Runderoth','Runderoth','NW'),('DE','RRZ','Redwitz an der Rodach','Redwitz an der Rodach','BY'),('DE','RSA','Riesa','Riesa','SN'),('DE','RSB','Rosbach','Rosbach','NW'),('DE','RSD','Rosenfeld','Rosenfeld','BW'),('DE','RSE','Rieste','Rieste','NI'),('DE','RSF','Reinersdorf','Reinersdorf','BY'),('DE','RSG','Rosenberg/Ostalb','Rosenberg/Ostalb','BW'),('DE','RSH','Ritschenhausen','Ritschenhausen','TH'),('DE','RSI','Herrstein','Herrstein','RP'),('DE','RSK','Rostock','Rostock','MV'),('DE','RSL','Rossla','Rossla','ST'),('DE','RSN','Rudisleben','Rudisleben','TH'),('DE','RST','Regenstauf','Regenstauf','BY'),('DE','RSU','Risum-Lindholm','Risum-Lindholm','SH'),('DE','RSW','Reichenschwand','Reichenschwand','BY'),('DE','RTA','Rottenacker','Rottenacker','BW'),('DE','RTB','Rottenbach','Rottenbach','TH'),('DE','RTC','Rottach-Egern','Rottach-Egern','BY'),('DE','RTE','Ritterhude','Ritterhude','NI'),('DE','RTG','Rothenburg','Rothenburg','BY'),('DE','RTH','Roth','Roth','BY'),('DE','RTI','Rothlein','Rothlein','BY'),('DE','RTL','Rodental','Rodental','BY'),('DE','RTM','Rutesheim','Rutesheim','BW'),('DE','RTN','Rottenbuch','Rottenbuch','BY'),('DE','RTO','Rottenburg','Rottenburg','BW'),('DE','RTR','Rittershausen','Rittershausen','HE'),('DE','RTT','Rottingen','Rottingen','BY'),('DE','RTZ','Rothkreuz','Rothkreuz','BY'),('DE','RUA','Ruhla','Ruhla','TH'),('DE','RUB','Rusbend','Rusbend','NI'),('DE','RUD','Rudersberg','Rudersberg','BW'),('DE','RUE','Rudesheim','Rudesheim','HE'),('DE','RUG','Ruhpolding','Ruhpolding','BY'),('DE','RUH','Rummelsheim','Rummelsheim','RP'),('DE','RUL','Rudolstadt','Rudolstadt','TH'),('DE','RUM','Russelsheim','Russelsheim','HE'),('DE','RUN','Runkel','Runkel','HE'),('DE','RUP','Ruppichteroth','Ruppichteroth','NW'),('DE','RUS','Rothausen','Rothausen','BY'),('DE','RUT','Ruthen','Ruthen','NW'),('DE','RWA','Rowa','Rowa','MV'),('DE','RWN','Rendswuhren','Rendswuhren','SH'),('DE','RZF','Rosdorf','Rosdorf','NI'),('DE','RZG','Ratzeburg','Ratzeburg','SH'),('DE','RZS','Roitzsch','Roitzsch','ST'),('DE','RZZ','Rotz','Rotz','BY'),('DE','SAA','Saarlouis','Saarlouis','SL'),('DE','SAB','Sasbach','Sasbach','BW'),('DE','SAC','Sachsen bei Ansbach','Sachsen bei Ansbach','BY'),('DE','SAD','Saalfeld','Saalfeld','TH'),('DE','SAE','St Aldegund','St Aldegund','RP'),('DE','SAF','Saffig','Saffig','RP'),('DE','SAG','Saarburg','Saarburg','RP'),('DE','SAH','Saulheim','Saulheim','RP'),('DE','SAI','Stadtilm','Stadtilm','TH'),('DE','SAJ','Schontal','Schontal','BW'),('DE','SAK','Sassenbach','Sassenbach','RP'),('DE','SAL','Stadtallendorf','Stadtallendorf','HE'),('DE','SAM','Sahms','Sahms','SH'),('DE','SAN','Sandhausen','Sandhausen','BW'),('DE','SAO','Stadelhofen','Stadelhofen','BY'),('DE','SAP','Satrup','Satrup','SH'),('DE','SAR','Salzgitter','Salzgitter','NI'),('DE','SAS','Sassnitz','Sassnitz','MV'),('DE','SAT','Sarstedt','Sarstedt','NI'),('DE','SAU','Schacht-Audorf','Schacht-Audorf','SH'),('DE','SAW','Steinbach am Wald','Steinbach am Wald','BY'),('DE','SBC','Stammbach','Stammbach','BY'),('DE','SBF','Saalburg-Ebersdorf','Saalburg-Ebersdorf','TH'),('DE','SBG','Sedelsberg','Sedelsberg','NI'),('DE','SBH','Schrobenhausen','Schrobenhausen','BY'),('DE','SBL','St Blasien','St Blasien','BW'),('DE','SBM','Sobernheim','Sobernheim','RP'),('DE','SBN','Schwabhausen','Schwabhausen','BY'),('DE','SBO','Steinenbronn','Steinenbronn','BW'),('DE','SBR','Staufen im Breisgau','Staufen im Breisgau','BW'),('DE','SBS','Schwalbach','Schwalbach','SL'),('DE','SCA','Schladern','Schladern','NW'),('DE','SCB','Schonberg','Schonberg','SN'),('DE','SCC','Schonach','Schonach','BW'),('DE','SCD','Scheinfeld','Scheinfeld','BY'),('DE','SCE','Schwerte','Schwerte','NW'),('DE','SCF','Schwandorf','Schwandorf','BY'),('DE','SCG','Schramberg','Schramberg','BW'),('DE','SCH','Schwetzingen','Schwetzingen','BW'),('DE','SCI','Schelklingen','Schelklingen','BW'),('DE','SCK','Schermbeck','Schermbeck','NW'),('DE','SCL','Scheessel','Scheessel','NI'),('DE','SCM','Schriesheim','Schriesheim','BW'),('DE','SCN','Saarbrucken','Saarbrucken','SL'),('DE','SCO','Schonlind','Schonlind','BY'),('DE','SCQ','Schomberg','Schomberg','BW'),('DE','SCR','Schierling','Schierling','BY'),('DE','SCS','Schortens','Schortens','NI'),('DE','SCT','Schwalmstadt','Schwalmstadt','HE'),('DE','SCU','Schlauroth','Schlauroth','SN'),('DE','SCV','Schleiden','Schleiden','NW'),('DE','SCW','Schweinfurt','Schweinfurt','BY'),('DE','SCZ','Schleiz','Schleiz','TH'),('DE','SDA','Schwanewede','Schwanewede','NI'),('DE','SDB','Sandbach','Sandbach','HE'),('DE','SDD','Steenodde, Amrum','Steenodde, Amrum','SH'),('DE','SDE','Sande, Friesland','Sande, Friesland','NI'),('DE','SDF','Schorndorf','Schorndorf','BW'),('DE','SDG','Stadtbergen','Stadtbergen','BY'),('DE','SDH','Sondershausen','Sondershausen','TH'),('DE','SDI','Schalding','Schalding','BY'),('DE','SDK','Soltendieck','Soltendieck','NI'),('DE','SDL','Sudlohn','Sudlohn','NW'),('DE','SDN','Sindelfingen','Sindelfingen','BW'),('DE','SDO','Saal an der Donau','Saal an der Donau','BY'),('DE','SDR','Schnelldorf','Schnelldorf','BY'),('DE','SDS','Seddiner See','Seddiner See','BR'),('DE','SDT','Schwedt','Schwedt','BR'),('DE','SDX','Steindorf','Steindorf','BY'),('DE','SEA','Schlema','Schlema','SN'),('DE','SEB','Selb','Selb','BY'),('DE','SEC','Seck','Seck','RP'),('DE','SEE','Seesen','Seesen','NI'),('DE','SEF','Schelldorf','Schelldorf','ST'),('DE','SEG','Seeg','Seeg','BY'),('DE','SEH','Sehestedt/Eider','Sehestedt/Eider','SH'),('DE','SEI','Steinen','Steinen','BW'),('DE','SEK','Saerbeck','Saerbeck','NW'),('DE','SEL','Selters/Westerwald','Selters/Westerwald','RP'),('DE','SEM','Selm','Selm','NW'),('DE','SEN','Sendenhorst','Sendenhorst','NW'),('DE','SEQ','Scheer','Scheer','BW'),('DE','SER','Sundern','Sundern','NW'),('DE','SES','Schierstein','Schierstein','HE'),('DE','SET','Scheidt','Scheidt','SL'),('DE','SEW','Schonewerda','Schonewerda','TH'),('DE','SEX','Sembach','Sembach','RP'),('DE','SEZ','Schmelz','Schmelz','SL'),('DE','SFB','Staufenberg','Staufenberg','HE'),('DE','SFD','Schlusselfeld','Schlusselfeld','BY'),('DE','SFE','Scheuerfeld','Scheuerfeld','RP'),('DE','SFF','Staffelstein','Staffelstein','BY'),('DE','SFG','Steffenberg','Steffenberg','HE'),('DE','SFL','Schonfeld','Schonfeld','SN'),('DE','SFM','Schaafheim','Schaafheim','HE'),('DE','SFN','Sonthofen','Sonthofen','BY'),('DE','SFS','Schifferstadt','Schifferstadt','RP'),('DE','SFZ','Steinefrenz','Steinefrenz','RP'),('DE','SGA','Steigra','Steigra','ST'),('DE','SGD','Schwabisch Gmund','Schwabisch Gmund','BW'),('DE','SGE','Siegen','Siegen','NW'),('DE','SGF','Sottrum','Sottrum','NI'),('DE','SGG','Scheidegg','Scheidegg','BY'),('DE','SGH','Singhofen','Singhofen','RP'),('DE','SGL','Siegelsbach','Siegelsbach','BW'),('DE','SGN','Steinhagen','Steinhagen','NW'),('DE','SGO','Sankt Goarshausen','Sankt Goarshausen','RP'),('DE','SGR','Strassgrabchen','Strassgrabchen','SN'),('DE','SGS','Sankt Georgen im Schwarzwald','Sankt Georgen im Schwarzwald','BW'),('DE','SGT','Seelingstadt','Seelingstadt','TH'),('DE','SGU','Schongau','Schongau','BY'),('DE','SGZ','Steglitz','Steglitz','BE'),('DE','SHA','Sangerhausen','Sangerhausen','ST'),('DE','SHB','Sessenbach','Sessenbach','RP'),('DE','SHD','Steinheid','Steinheid','TH'),('DE','SHE','Seeheim-Jugenheim','Seeheim-Jugenheim','HE'),('DE','SHF','Solnhofen','Solnhofen','BY'),('DE','SHG','Stuhlingen','Stuhlingen','BW'),('DE','SHH','Stahlhofen','Stahlhofen','RP'),('DE','SHI','Schmilka','Schmilka','SN'),('DE','SHK','Schonkirchen','Schonkirchen','SH'),('DE','SHL','Schwabisch Hall','Schwabisch Hall','BW'),('DE','SHM','Schopfheim','Schopfheim','BW'),('DE','SHN','Siershahn','Siershahn','RP'),('DE','SHO','Schonungen','Schonungen','BY'),('DE','SHR','Straubenhardt','Straubenhardt','BW'),('DE','SHS','Schloss Holte-Stukenbrock','Schloss Holte-Stukenbrock','NW'),('DE','SHT','Rheinstetten','Rheinstetten','BW'),('DE','SHU','Schwarzenhasel','Schwarzenhasel','HE'),('DE','SHW','Bad Schwalbach','Bad Schwalbach','HE'),('DE','SHZ','Schwarzenberg','Schwarzenberg','SN'),('DE','SIB','Simbach am Inn','Simbach am Inn','BY'),('DE','SIC','Schiltach','Schiltach','BW'),('DE','SIE','Siegertsbrunn','Siegertsbrunn','BY'),('DE','SIG','Siegburg','Siegburg','NW'),('DE','SIH','Sinsheim','Sinsheim','BW'),('DE','SIL','Simmertal','Simmertal','RP'),('DE','SIM','Simmern/Hunsruck','Simmern/Hunsruck','RP'),('DE','SIN','Singen','Singen','BW'),('DE','SIO','Selbitz','Selbitz','BY'),('DE','SIR','Rohrbach','Rohrbach','SL'),('DE','SIS','Seligenstadt','Seligenstadt','BY'),('DE','SIT','Sittensen','Sittensen','NI'),('DE','SIZ','Schlitz','Schlitz','HE'),('DE','SJO','St Johann','St Johann','BW'),('DE','SKA','Sankt Augustin','Sankt Augustin','NW'),('DE','SKB','Schonenberg','Schonenberg','RP'),('DE','SKF','Stockelsdorf','Stockelsdorf','SH'),('DE','SKG','Starkenberg','Starkenberg','TH'),('DE','SKH','Stockach','Stockach','BW'),('DE','SKI','Strasskirchen','Strasskirchen','BY'),('DE','SKK','Seckenhausen','Seckenhausen','NI'),('DE','SKM','Stockheim','Stockheim','NW'),('DE','SKN','Stephanskirchen','Stephanskirchen','BY'),('DE','SKO','Schkopau','Schkopau','ST'),('DE','SKT','Selfkant','Selfkant','NW'),('DE','SKV','Schwalbach','Schwalbach','HE'),('DE','SKZ','Schkeuditz','Schkeuditz','SN'),('DE','SLA','Sailach','Sailach','BW'),('DE','SLB','Siegelbach','Siegelbach','TH'),('DE','SLC','Schalkam','Schalkam','BY'),('DE','SLD','Saterland','Saterland','NI'),('DE','SLE','Spelle','Spelle','NI'),('DE','SLF','Strullendorf','Strullendorf','BY'),('DE','SLG','Schmallenberg','Schmallenberg','NW'),('DE','SLH','Schopfloch/Freudenstadt','Schopfloch/Freudenstadt','BW'),('DE','SLI','Schliengen','Schliengen','BW'),('DE','SLJ','Stolzenau','Stolzenau','NI'),('DE','SLK','Schollkrippen','Schollkrippen','BY'),('DE','SLL','Stelle','Stelle','NI'),('DE','SLM','Schwelm','Schwelm','NW'),('DE','SLN','Schluchtern','Schluchtern','HE'),('DE','SLO','Stadtlohn','Stadtlohn','NW'),('DE','SLR','Schlierbach','Schlierbach','BW'),('DE','SLS','Schleswig','Schleswig','SH'),('DE','SLT','Seligenstadt','Seligenstadt','HE'),('DE','SLU','Saulgau','Saulgau','BW'),('DE','SLX','Salach','Salach','BW'),('DE','SLZ','Sulzbach-Laufen','Sulzbach-Laufen','BW'),('DE','SMA','St Margarethen','St Margarethen','SH'),('DE','SMB','Spremberg','Spremberg','BR'),('DE','SMD','Schmolde','Schmolde','BR'),('DE','SME','Schalksmuhle','Schalksmuhle','NW'),('DE','SMF','Schmiedefeld','Schmiedefeld','TH'),('DE','SMG','Sigmaringen','Sigmaringen','BW'),('DE','SMH','Schemmerhofen','Schemmerhofen','BW'),('DE','SMI','St Michaelisdonn','St Michaelisdonn','SH'),('DE','SMM','Schemmerberg','Schemmerberg','BW'),('DE','SMN','Schwabmunchen','Schwabmunchen','BY'),('DE','SMP','Stimpfach','Stimpfach','BW'),('DE','SMR','Sommerach','Sommerach','BY'),('DE','SMT','Samtens','Samtens','MV'),('DE','SMW','Stemwede','Stemwede','NW'),('DE','SNA','Schnaittenbach','Schnaittenbach','BY'),('DE','SNB','Steinberg','Steinberg','ST'),('DE','SNC','Sunching','Sunching','BY'),('DE','SND','Senden','Senden','BY'),('DE','SNE','Sehnde','Sehnde','NI'),('DE','SNF','Steinfeld','Steinfeld','NI'),('DE','SNG','Sennelager','Sennelager','NW'),('DE','SNH','Singen','Singen','TH'),('DE','SNI','Schoneiche','Schoneiche','BR'),('DE','SNK','Schoneck','Schoneck','HE'),('DE','SNL','Sankt Leon','Sankt Leon','BW'),('DE','SNM','Sontheim an der Brenz','Sontheim an der Brenz','BW'),('DE','SNN','Sundern/Hochsauerlandkreis','Sundern/Hochsauerlandkreis','NW'),('DE','SNR','Schnackenburg','Schnackenburg','NI'),('DE','SNU','Steinau','Steinau','HE'),('DE','SNW','Steinwenden','Steinwenden','RP'),('DE','SNZ','Sornzig','Sornzig','SN'),('DE','SOA','Sontra','Sontra','HE'),('DE','SOB','Stollberg','Stollberg','SN'),('DE','SOC','Stollhofen','Stollhofen','BW'),('DE','SOD','Sonnenfeld','Sonnenfeld','BY'),('DE','SOE','Soest','Soest','NW'),('DE','SOF','Siegsdorf','Siegsdorf','BY'),('DE','SOG','Sogel','Sogel','NI'),('DE','SOH','Sohren','Sohren','RP'),('DE','SOK','Sonsbeck','Sonsbeck','NW'),('DE','SOL','Solingen','Solingen','NW'),('DE','SOM','Sommerda','Sommerda','TH'),('DE','SON','Sonneberg','Sonneberg','TH'),('DE','SOO','Stadtoldendorf','Stadtoldendorf','NI'),('DE','SOR','Sorup','Sorup','SH'),('DE','SOS','Solms','Solms','HE'),('DE','SOT','Schotten','Schotten','HE'),('DE','SOU','Soltau','Soltau','NI'),('DE','SOY','Soyen','Soyen','BY'),('DE','SPA','Spaichingen','Spaichingen','BW'),('DE','SPC','Spechtsbrunn','Spechtsbrunn','TH'),('DE','SPD','Schopsdorf','Schopsdorf','ST'),('DE','SPE','Speyer','Speyer','RP'),('DE','SPF','Speichersdorf','Speichersdorf','BY'),('DE','SPG','Spenge','Spenge','NW'),('DE','SPH','Spreenhagen','Spreenhagen','BR'),('DE','SPI','Spiekeroog','Spiekeroog','NI'),('DE','SPL','Spalt','Spalt','BY'),('DE','SPM','Spangdahlem','Spangdahlem','RP'),('DE','SPN','Spaden','Spaden','NI'),('DE','SPO','Sprockhovel','Sprockhovel','NW'),('DE','SPR','Sprendlingen/Rheinhessen','Sprendlingen/Rheinhessen','RP'),('DE','SPS','Schulper Neuensiel','Schulper Neuensiel','SH'),('DE','SPT','Sinspelt','Sinspelt','RP'),('DE','SPU','Spiegelau','Spiegelau','BY'),('DE','SPW','Spreewitz','Spreewitz','SN'),('DE','SPY','Spay','Spay','RP'),('DE','SPZ','Schwepnitz','Schwepnitz','SN'),('DE','SRB','Schrecksbach','Schrecksbach','HE'),('DE','SRD','Stralendorf','Stralendorf','MV'),('DE','SRE','Springe','Springe','NI'),('DE','SRF','Schuttorf','Schuttorf','NI'),('DE','SRG','Schonberg','Schonberg','SH'),('DE','SRH','Simmerath','Simmerath','NW'),('DE','SRI','Schweringen','Schweringen','NI'),('DE','SRK','Strackholt','Strackholt','NI'),('DE','SRL','Sauerlach','Sauerlach','BY'),('DE','SRM','Surheim','Surheim','BY'),('DE','SRN','Straelen','Straelen','NW'),('DE','SRO','Sulzbach-Rosenberg','Sulzbach-Rosenberg','BY'),('DE','SRR','Saarwellingen','Saarwellingen','SL'),('DE','SRT','Streithausen','Streithausen','RP'),('DE','SRU','Sarlhusen','Sarlhusen','SH'),('DE','SRZ','Sirzenich','Sirzenich','RP'),('DE','SSC','Schieder-Schwalenberg','Schieder-Schwalenberg','NW'),('DE','SSD','Starsiedel','Starsiedel','ST'),('DE','SSE','Stutensee','Stutensee','BW'),('DE','SSF','Steinsfeld','Steinsfeld','BY'),('DE','SSL','Hesselte','Hesselte','NI'),('DE','SSM','Florsheim-Dalsheim','Florsheim-Dalsheim','RP'),('DE','SSN','Sachsenheim','Sachsenheim','BW'),('DE','SSP','Stephansposching','Stephansposching','BY'),('DE','SSR','Sandersdorf','Sandersdorf','ST'),('DE','SSS','Hessen','Hessen','ST'),('DE','SSX','Schallstadt','Schallstadt','BW'),('DE','STA','Stade','Stade','NI'),('DE','STB','Straubing','Straubing','BY'),('DE','STC','Stockstadt','Stockstadt','HE'),('DE','STD','Strande','Strande','SH'),('DE','STE','Steinbach am Taunus','Steinbach am Taunus','HE'),('DE','STF','Stassfurt','Stassfurt','ST'),('DE','STG','Stolberg','Stolberg','NW'),('DE','STH','Stadthagen','Stadthagen','NI'),('DE','STI','St Ingbert','St Ingbert','SL'),('DE','STK','St Katharinen','St Katharinen','RP'),('DE','STL','Stralsund','Stralsund','MV'),('DE','STM','Steinheim','Steinheim','NW'),('DE','STN','Starnberg','Starnberg','BY'),('DE','STO','Stolberg/Harz','Stolberg/Harz','ST'),('DE','STP','Stolpen','Stolpen','SN'),('DE','STQ','Stendal','Stendal','ST'),('DE','STR','Stuttgart','Stuttgart','BW'),('DE','STS','Stader Sand','Stader Sand','NI'),('DE','STT','Steinfurt','Steinfurt','BW'),('DE','STU','Stuhr','Stuhr','NI'),('DE','STW','Steinweiler','Steinweiler','BW'),('DE','STX','Strehla','Strehla','SN'),('DE','STY','Steyerberg','Steyerberg','NI'),('DE','STZ','Stein','Stein','BW'),('DE','SUC','Schluchsee','Schluchsee','BW'),('DE','SUD','Suderstapel','Suderstapel','SH'),('DE','SUE','Sturzelberg','Sturzelberg','NW'),('DE','SUF','Staufen','Staufen','BY'),('DE','SUG','Sassenburg','Sassenburg','NI'),('DE','SUH','Sulzach','Sulzach','BY'),('DE','SUL','Suhl','Suhl','TH'),('DE','SUN','Sulingen','Sulingen','NI'),('DE','SUR','Surwold','Surwold','NI'),('DE','SUS','Sussen','Sussen','BW'),('DE','SUT','Struth','Struth','TH'),('DE','SUZ','Sulzbach','Sulzbach','HE'),('DE','SVJ','Saal an der Saale','Saal an der Saale','BY'),('DE','SVL','Seevetal','Seevetal','NI'),('DE','SVN','Schneverdingen','Schneverdingen','NI'),('DE','SWA','Swisttal','Swisttal','NW'),('DE','SWB','Schwabach','Schwabach','BY'),('DE','SWD','Schwarzenfeld','Schwarzenfeld','BY'),('DE','SWE','St Wendel','St Wendel','SL'),('DE','SWG','Schwaig','Schwaig','BY'),('DE','SWH','Schweich','Schweich','RP'),('DE','SWI','Schwieberdingen','Schwieberdingen','BW'),('DE','SWK','Schwaikheim','Schwaikheim','BW'),('DE','SWL','Schwalmtal','Schwalmtal','NW'),('DE','SWN','Schweigen','Schweigen','RP'),('DE','SWR','Schwerin','Schwerin','MV'),('DE','SWU','Schwallungen','Schwallungen','TH'),('DE','SXF','Berlin-Schonefeld Apt','Berlin-Schonefeld Apt','BR'),('DE','SYK','Syke','Syke','NI'),('DE','SZA','Schwarzadler','Schwarzadler','SN'),('DE','SZB','Schwarzenbach an der Saale','Schwarzenbach an der Saale','BY'),('DE','SZD','Schwarzenbach am Wald','Schwarzenbach am Wald','BY'),('DE','SZE','Seelze','Seelze','NI'),('DE','SZG','Sinzig','Sinzig','RP'),('DE','SZH','Schwarzach','Schwarzach','BW'),('DE','SZI','Schwarzheide','Schwarzheide','BR'),('DE','SZL','Schenkenzell','Schenkenzell','BW'),('DE','SZN','Salzkotten','Salzkotten','NW'),('DE','SZT','Sereetz','Sereetz','SH'),('DE','SZW','Salzwedel','Salzwedel','ST'),('DE','TAB','Tannenbergsthal','Tannenbergsthal','SN'),('DE','TAD','Grettstadt','Grettstadt','BY'),('DE','TAE','Tangermunde','Tangermunde','ST'),('DE','TAM','Tamm','Tamm','BW'),('DE','TAN','Tantow','Tantow','BR'),('DE','TAP','Stapelfeld','Stapelfeld','SH'),('DE','TAR','Taben','Taben','RP'),('DE','TAU','Tauberbischofsheim','Tauberbischofsheim','BW'),('DE','TAW','Tawern','Tawern','RP'),('DE','TBG','Trostberg','Trostberg','BY'),('DE','TBI','Teublitz','Teublitz','BY'),('DE','TBK','Tarbek','Tarbek','SH'),('DE','TBN','Trebbin','Trebbin','BR'),('DE','TBR','Trebur','Trebur','HE'),('DE','TCV','Tiefenbach','Tiefenbach','BY'),('DE','TDF','Todendorf','Todendorf','SH'),('DE','TDM','Trebendorf','Trebendorf','SN'),('DE','TDN','Toddin','Toddin','MV'),('DE','TEB','Teugn','Teugn','BY'),('DE','TEE','Treuen','Treuen','SN'),('DE','TEG','Tegernsee','Tegernsee','BY'),('DE','TEI','Westheim','Westheim','BY'),('DE','TEL','Teutschenthal','Teutschenthal','ST'),('DE','TEN','Messstetten','Messstetten','BW'),('DE','TET','Tettnang','Tettnang','BW'),('DE','TEU','Tettau','Tettau','BY'),('DE','TFR','Thaleischweiler-Froschen','Thaleischweiler-Froschen','RP'),('DE','TFS','Triefenstein','Triefenstein','BY'),('DE','TGM','Thungersheim','Thungersheim','BY'),('DE','TGN','Teningen','Teningen','BW'),('DE','TGW','Torgelow','Torgelow','MV'),('DE','THA','Thale','Thale','ST'),('DE','THD','Thedinghausen','Thedinghausen','NI'),('DE','THE','Trittenheim','Trittenheim','RP'),('DE','THF','Berlin-Tempelhof Apt','Berlin-Tempelhof Apt','BE'),('DE','THG','Thalfang','Thalfang','RP'),('DE','THI','Thiendorf','Thiendorf','SN'),('DE','THL','Thal','Thal','TH'),('DE','THM','Thalheim/Erzgebirge','Thalheim/Erzgebirge','SN'),('DE','THN','Thungen','Thungen','BY'),('DE','THS','Thansau','Thansau','BY'),('DE','THU','Thune','Thune','NI'),('DE','TIE','Tiefensee','Tiefensee','BR'),('DE','TIG','Tittling','Tittling','BY'),('DE','TIN','Tinnum','Tinnum','SH'),('DE','TIR','Tirschenreuth','Tirschenreuth','BY'),('DE','TIT','Tittmoning','Tittmoning','BY'),('DE','TKH','Taufkirchen','Taufkirchen','BY'),('DE','TKN','Taufkirchen','Taufkirchen','BY'),('DE','TLH','Talheim','Talheim','BW'),('DE','TLY','Theley','Theley','SL'),('DE','TMG','Thalmassing','Thalmassing','BY'),('DE','TMH','Torfmoorholle','Torfmoorholle','BY'),('DE','TMM','Temmels','Temmels','RP'),('DE','TNE','Titisee-Neustadt','Titisee-Neustadt','BW'),('DE','TNG','Toging am Inn','Toging am Inn','BY'),('DE','TNH','Tornesch','Tornesch','SH'),('DE','TNN','Tengen','Tengen','BW'),('DE','TOD','Todtnau','Todtnau','BW'),('DE','TOE','Tonning','Tonning','SH'),('DE','TOS','Tossens','Tossens','NI'),('DE','TOU','Torgau','Torgau','SN'),('DE','TPT','Triptis','Triptis','TH'),('DE','TRA','Traunstein','Traunstein','BY'),('DE','TRB','Trabitz','Trabitz','BY'),('DE','TRE','Treuchtlingen','Treuchtlingen','BY'),('DE','TRG','Triberg','Triberg','BW'),('DE','TRH','Trechtingshausen','Trechtingshausen','RP'),('DE','TRI','Trier','Trier','RP'),('DE','TRL','Trippstadt','Trippstadt','RP'),('DE','TRN','Trossingen','Trossingen','BW'),('DE','TRO','Troisdorf','Troisdorf','NW'),('DE','TRR','Traunreut','Traunreut','BY'),('DE','TRT','Traben-Trarbach','Traben-Trarbach','RP'),('DE','TRU','Trittau','Trittau','SH'),('DE','TRV','Travemunde','Travemunde','SH'),('DE','TRX','Traisen','Traisen','RP'),('DE','TSC','Tschirn','Tschirn','BY'),('DE','TSN','Taunusstein','Taunusstein','HE'),('DE','TST','Tostedt','Tostedt','NI'),('DE','TSU','Tiessau','Tiessau','NI'),('DE','TTE','Hatten','Hatten','NI'),('DE','TTG','Tacherting','Tacherting','BY'),('DE','TTH','Tuntenhausen','Tuntenhausen','BY'),('DE','TTL','Trusetal','Trusetal','TH'),('DE','TTN','Train','Train','BY'),('DE','TTT','Titting','Titting','BY'),('DE','TTW','Teterow','Teterow','MV'),('DE','TUE','Tubingen','Tubingen','BW'),('DE','TUM','Turkheim','Turkheim','BY'),('DE','TUN','Tuningen','Tuningen','BW'),('DE','TUS','Tussenhausen','Tussenhausen','BY'),('DE','TUT','Tuttlingen','Tuttlingen','BW'),('DE','TVT','Tonisvorst','Tonisvorst','NW'),('DE','TWD','Teichwolframsdorf','Teichwolframsdorf','TH'),('DE','TWI','Twist','Twist','NI'),('DE','TWR','Trierweiler','Trierweiler','RP'),('DE','TWT','Twistetal','Twistetal','HE'),('DE','TWX','Twistringen','Twistringen','NI'),('DE','TWZ','Thallwitz','Thallwitz','SN'),('DE','TXL','Berlin-Tegel Apt','Berlin-Tegel Apt','BE'),('DE','TYM','Thyrnau','Thyrnau','BY'),('DE','UAA','Unterfohring','Unterfohring','BY'),('DE','UAN','Unterahrain','Unterahrain','BY'),('DE','UAS','Uffing','Uffing','BY'),('DE','UBE','Unterwellenborn','Unterwellenborn','TH'),('DE','UBG','Bad Durrenberg','Bad Durrenberg','ST'),('DE','UBN','Brauneberg','Brauneberg','RP'),('DE','UBR','Ubersee','Ubersee','BY'),('DE','UBW','Ubstadt-Weiher','Ubstadt-Weiher','BW'),('DE','UCH','Buch','Buch','BY'),('DE','UCK','Ueckermunde','Ueckermunde','MV'),('DE','UDE','Hude','Hude','SH'),('DE','UDG','Runding','Runding','BY'),('DE','UEB','Uberlingen','Uberlingen','BW'),('DE','UED','Uedem','Uedem','NW'),('DE','UEL','Uelzen','Uelzen','NI'),('DE','UEN','Uberherrn','Uberherrn','SL'),('DE','UER','Urzig','Urzig','RP'),('DE','UES','Uesen','Uesen','NI'),('DE','UET','Uetersen','Uetersen','SH'),('DE','UFF','Uffenheim','Uffenheim','BY'),('DE','UFT','Umpferstedt','Umpferstedt','TH'),('DE','UGE','Burgbernheim','Burgbernheim','BY'),('DE','UGO','Untergroningen','Untergroningen','BW'),('DE','UHA','Unterhaching','Unterhaching','BY'),('DE','UHI','Uhingen','Uhingen','BW'),('DE','UHL','Buhl','Buhl','BW'),('DE','UHM','Uxheim','Uxheim','RP'),('DE','UKH','Umkirch','Umkirch','BW'),('DE','ULM','Ulm','Ulm','BW'),('DE','UMH','Untermunkheim','Untermunkheim','BW'),('DE','UMM','Ummendorf','Ummendorf','BW'),('DE','UMN','Ulmen','Ulmen','RP'),('DE','UNA','Unnau','Unnau','RP'),('DE','UNE','Unterkirnach','Unterkirnach','BW'),('DE','UNK','Unterkochen','Unterkochen','BW'),('DE','UNN','Unna','Unna','NW'),('DE','UNR','Untermeitingen','Untermeitingen','BY'),('DE','UNT','Unterelchingen','Unterelchingen','BY'),('DE','UPS','Upschort','Upschort','NI'),('DE','URB','Urbach','Urbach','BW'),('DE','URG','Unterensingen','Unterensingen','BW'),('DE','URH','Bad Urach','Bad Urach','BW'),('DE','USA','Uslar','Uslar','NI'),('DE','USE','Bassenheim','Bassenheim','RP'),('DE','USG','Usingen','Usingen','HE'),('DE','USH','Unterschneidheim','Unterschneidheim','BW'),('DE','USL','Unterschleissheim','Unterschleissheim','BY'),('DE','USM','Untersiemau','Untersiemau','BY'),('DE','USN','Ursensollen','Ursensollen','BY'),('DE','UST','Ummerstadt','Ummerstadt','TH'),('DE','UTG','Utting','Utting','BY'),('DE','UTM','Buttenheim','Buttenheim','BY'),('DE','UTZ','Schutzbach','Schutzbach','RP'),('DE','UUN','Unterneukirchen','Unterneukirchen','BY'),('DE','UWB','Unterwattenbach','Unterwattenbach','BY'),('DE','UZF','Utzenfeld','Utzenfeld','BW'),('DE','VAC','Vacha','Vacha','TH'),('DE','VAI','Vaihingen an der Enz','Vaihingen an der Enz','BW'),('DE','VAL','Valwig','Valwig','RP'),('DE','VAR','Varel','Varel','NI'),('DE','VBH','Vorbach','Vorbach','BY'),('DE','VBL','Volkenroth','Volkenroth','RP'),('DE','VBM','Vielbrunn','Vielbrunn','HE'),('DE','VBS','Vilsbiburg','Vilsbiburg','BY'),('DE','VDR','Vadenrod','Vadenrod','HE'),('DE','VEC','Vechta','Vechta','NI'),('DE','VED','Versmold','Versmold','NW'),('DE','VEJ','Vetschau','Vetschau','BR'),('DE','VEL','Velbert','Velbert','NW'),('DE','VEN','Venne','Venne','NI'),('DE','VER','Verden','Verden','NI'),('DE','VES','Vestenbergsgreuth','Vestenbergsgreuth','BY'),('DE','VIB','Visbek','Visbek','NI'),('DE','VIE','Viersen','Viersen','NW'),('DE','VIH','Vilshofen','Vilshofen','BY'),('DE','VIL','Vilseck','Vilseck','BY'),('DE','VIM','Viernheim','Viernheim','HE'),('DE','VIR','Vierraden','Vierraden','BR'),('DE','VIS','Villingen-Schwenningen','Villingen-Schwenningen','BW'),('DE','VIT','Viechtach','Viechtach','BY'),('DE','VKH','Volkertshausen','Volkertshausen','BW'),('DE','VKN','Volkmarsen','Volkmarsen','BE'),('DE','VLB','Vellberg','Vellberg','BW'),('DE','VLE','Velden','Velden','BY'),('DE','VLG','Villingendorf','Villingendorf','BW'),('DE','VLL','Valluhn','Valluhn','MV'),('DE','VLM','Vellmar','Vellmar','HE'),('DE','VLN','Velen','Velen','NW'),('DE','VLO','Vlotho','Vlotho','NW'),('DE','VLT','Velten','Velten','BR'),('DE','VMR','Villmar','Villmar','HE'),('DE','VNA','Venhaus','Venhaus','NI'),('DE','VNG','Venningen','Venningen','RP'),('DE','VOC','Vockfey','Vockfey','NI'),('DE','VOE','Volklingen','Volklingen','SL'),('DE','VOG','Vogtsburg im Kaiserstuhl','Vogtsburg im Kaiserstuhl','BW'),('DE','VOL','Volkach','Volkach','BY'),('DE','VON','Vohringen','Vohringen','BY'),('DE','VPK','Volpke','Volpke','ST'),('DE','VRB','Vohrenbach','Vohrenbach','BW'),('DE','VRD','Voerde','Voerde','NW'),('DE','VRE','Vreden','Vreden','NW'),('DE','VRL','Verl','Verl','NW'),('DE','VRS','Vrees','Vrees','NI'),('DE','VSK','Visbeck','Visbeck','NW'),('DE','VSS','Vohenstrauss','Vohenstrauss','BY'),('DE','VSW','Volkenschwand','Volkenschwand','BY'),('DE','VTA','Voltlage','Voltlage','NI'),('DE','VTF','Volkstorf','Volkstorf','NI'),('DE','VTL','Vettelschoss','Vettelschoss','RP'),('DE','VTR','Vaterstetten','Vaterstetten','BY'),('DE','VVD','Visselhovede','Visselhovede','NI'),('DE','WAA','Wanna','Wanna','NI'),('DE','WAB','Waldbrol','Waldbrol','NW'),('DE','WAC','Westeraccumersiel','Westeraccumersiel','NI'),('DE','WAD','Warendorf','Warendorf','NW'),('DE','WAE','Wachtersbach','Wachtersbach','HE'),('DE','WAF','Waldershof','Waldershof','BY'),('DE','WAG','Warburg','Warburg','NW'),('DE','WAH','Wahlstedt','Wahlstedt','SH'),('DE','WAI','Waiblingen','Waiblingen','BW'),('DE','WAJ','Wachau','Wachau','SN'),('DE','WAK','Waakirchen','Waakirchen','BY'),('DE','WAL','Walsrode','Walsrode','NI'),('DE','WAM','Waldheim','Waldheim','SN'),('DE','WAN','Warstein','Warstein','NW'),('DE','WAO','Waldmohr','Waldmohr','RP'),('DE','WAR','Warnemunde','Warnemunde','MV'),('DE','WAS','Wasserburg am Inn','Wasserburg am Inn','BY'),('DE','WAT','Waldshut-Tiengen','Waldshut-Tiengen','BW'),('DE','WAU','Wallau','Wallau','HE'),('DE','WAW','Wahlwinkel','Wahlwinkel','TH'),('DE','WAX','Wangen','Wangen',''),('DE','WAZ','Wabern','Wabern','HE'),('DE','WBA','Wachtberg','Wachtberg','NW'),('DE','WBC','Wembach','Wembach','BW'),('DE','WBD','Waibstadt','Waibstadt','BW'),('DE','WBE','Wassenberg','Wassenberg','NW'),('DE','WBG','Westerburg/Westerwaldkreis','Westerburg/Westerwaldkreis','RP'),('DE','WBH','Waldenbuch','Waldenbuch','BW'),('DE','WBK','Wasbek','Wasbek','SH'),('DE','WBL','Wolfenbuttel','Wolfenbuttel','NI'),('DE','WBN','Weissenborn','Weissenborn','ST'),('DE','WBO','Waldbronn','Waldbronn','BW'),('DE','WBQ','Wettenberg','Wettenberg','HE'),('DE','WBR','Wustenbrand','Wustenbrand','SN'),('DE','WBU','Weissenburg','Weissenburg','BR'),('DE','WBW','Waldenburg','Waldenburg','BW'),('DE','WBX','Wardenburg','Wardenburg','NI'),('DE','WCH','Wachenheim','Wachenheim','RP'),('DE','WCK','Wickede','Wickede','NW'),('DE','WCU','Wachau','Wachau','SN'),('DE','WDA','Werdau','Werdau','SN'),('DE','WDB','Wildberg','Wildberg','BW'),('DE','WDD','Wittstock an der Dosse','Wittstock an der Dosse','BR'),('DE','WDE','Wedemark','Wedemark','NI'),('DE','WDF','Walldorf','Walldorf','BW'),('DE','WDG','Weiding','Weiding','BY'),('DE','WDH','Windischeschenbach','Windischeschenbach','BY'),('DE','WDI','Wellendingen','Wellendingen','BW'),('DE','WDK','Waldeck','Waldeck','HE'),('DE','WDL','Wolfach','Wolfach','BW'),('DE','WDN','Wendelstein','Wendelstein','BY'),('DE','WDO','Waltersdorf','Waltersdorf','BR'),('DE','WDR','Wiedemar','Wiedemar','SN'),('DE','WDS','Weil der Stadt','Weil der Stadt','BW'),('DE','WDT','Weiterstadt','Weiterstadt','HE'),('DE','WDU','Waldenburg','Waldenburg','SN'),('DE','WEA','Wiesau','Wiesau','BY'),('DE','WEB','Werder','Werder','BR'),('DE','WEC','Wegscheid','Wegscheid','BY'),('DE','WED','Wedel','Wedel','SH'),('DE','WEE','Weener','Weener','NI'),('DE','WEF','Weissenfels','Weissenfels','ST'),('DE','WEG','Weilburg','Weilburg','HE'),('DE','WEH','Weisenbach','Weisenbach','BW'),('DE','WEI','Weiden in der Oberpfalz','Weiden in der Oberpfalz','BY'),('DE','WEK','Wermelskirchen','Wermelskirchen','NW'),('DE','WEL','Werl','Werl','NW'),('DE','WEM','Weilheim in Oberbayern','Weilheim in Oberbayern','BY'),('DE','WEN','Wenningstedt','Wenningstedt','SH'),('DE','WEO','Wallersdorf','Wallersdorf','BY'),('DE','WER','Werdohl','Werdohl','NW'),('DE','WES','Wesel','Wesel','NW'),('DE','WET','Wetzlar','Wetzlar','HE'),('DE','WEU','Werneuchen','Werneuchen','BR'),('DE','WEW','Wewelsfleth','Wewelsfleth','SH'),('DE','WEY','Weyhe','Weyhe','NI'),('DE','WEZ','Weiden','Weiden','BY'),('DE','WFB','Waldfischbach-Burgalben','Waldfischbach-Burgalben','RP'),('DE','WFE','Wolfegg','Wolfegg','BW'),('DE','WFH','Wolfhagen','Wolfhagen','HE'),('DE','WFK','Wildflecken','Wildflecken','BY'),('DE','WFL','Weferlingen','Weferlingen','NI'),('DE','WFM','Wolfersheim','Wolfersheim','HE'),('DE','WFS','Wallenfels','Wallenfels','BY'),('DE','WFT','Wolfertschwenden','Wolfertschwenden','BY'),('DE','WFX','Weitefeld','Weitefeld','RP'),('DE','WGA','Weingarten','Weingarten','BW'),('DE','WGB','Wiggensbach','Wiggensbach','BY'),('DE','WGE','Wernigerode','Wernigerode','ST'),('DE','WGF','Wagenfeld','Wagenfeld','NI'),('DE','WGG','Wegberg','Wegberg','NW'),('DE','WGL','Waghausel','Waghausel','BW'),('DE','WGN','Wangen im Allgau','Wangen im Allgau','BW'),('DE','WGS','Waging am See','Waging am See','BY'),('DE','WGU','Weissandt-Golzau','Weissandt-Golzau','ST'),('DE','WGZ','Weselberg','Weselberg','RP'),('DE','WHA','Witzenhausen','Witzenhausen','HE'),('DE','WHD','Wiesentheid','Wiesentheid','BY'),('DE','WHE','Wattenheim','Wattenheim','HE'),('DE','WHF','Wilhermsdorf','Wilhermsdorf','BY'),('DE','WHG','Windhagen','Windhagen','NW'),('DE','WHH','Weiherhammer','Weiherhammer','BY'),('DE','WHI','Wietmarschen','Wietmarschen','NI'),('DE','WHL','Wiehl','Wiehl','NW'),('DE','WHM','Weinheim','Weinheim','BW'),('DE','WHN','Westhofen/Rheinhessen','Westhofen/Rheinhessen','RP'),('DE','WHO','Wallenhorst','Wallenhorst','NI'),('DE','WHR','Wahrstedt','Wahrstedt','NI'),('DE','WHS','Wettenhausen','Wettenhausen','BY'),('DE','WHU','Wildeshausen','Wildeshausen','NI'),('DE','WHX','Warthausen','Warthausen','BE'),('DE','WIB','Wiesbaden','Wiesbaden','HE'),('DE','WID','Wildenrath','Wildenrath','NW'),('DE','WIE','Wiesens','Wiesens','NI'),('DE','WIF','Wischhafen','Wischhafen','NI'),('DE','WIG','Winterberg','Winterberg','NW'),('DE','WIH','Wisch','Wisch','SH'),('DE','WIK','Wiek','Wiek','MV'),('DE','WIL','Wilster','Wilster','SH'),('DE','WIM','Wimmer','Wimmer','NI'),('DE','WIN','Winsen/Luhe','Winsen/Luhe','NI'),('DE','WIR','Wirges','Wirges','RP'),('DE','WIS','Wismar','Wismar','MV'),('DE','WIT','Wittlage','Wittlage','NI'),('DE','WIW','Weidenberg','Weidenberg','BY'),('DE','WIX','Winnenden','Winnenden','BW'),('DE','WIZ','Wieren','Wieren','NI'),('DE','WKC','Schweitenkirchen','Schweitenkirchen','BY'),('DE','WKD','Wackersdorf','Wackersdorf','BY'),('DE','WKG','Waldkraiburg','Waldkraiburg','BY'),('DE','WKN','Weiskirchen','Weiskirchen','SL'),('DE','WKP','Westerkappeln','Westerkappeln','NW'),('DE','WKR','Waldkirch','Waldkirch','BW'),('DE','WKX','Waldkirchen','Waldkirchen','BY'),('DE','WLA','Wittlaer','Wittlaer','NW'),('DE','WLB','Wechselburg','Wechselburg','SN'),('DE','WLC','Willich','Willich','NW'),('DE','WLD','Walkenried','Walkenried','NI'),('DE','WLE','Walheim','Walheim','BW'),('DE','WLF','Wulfrath','Wulfrath','NW'),('DE','WLG','Wesseling','Wesseling','NW'),('DE','WLH','Weilheim an der Teck','Weilheim an der Teck','BW'),('DE','WLL','Willingen','Willingen','RP'),('DE','WLM','Walsum','Walsum','NW'),('DE','WLN','Wielen','Wielen','NI'),('DE','WLO','Wadersloh','Wadersloh','NW'),('DE','WLR','Weil am Rhein','Weil am Rhein','BW'),('DE','WLS','Wollstadt','Wollstadt','HE'),('DE','WLT','Werlte','Werlte','NI'),('DE','WLU','Waldlaubersheim','Waldlaubersheim','RP'),('DE','WLX','Wellen','Wellen','RP'),('DE','WLZ','Wolnzach','Wolnzach','BY'),('DE','WMA','Weimar/Giessen','Weimar/Giessen','HE'),('DE','WMC','Warmensteinach','Warmensteinach','BY'),('DE','WMD','Wittmund','Wittmund','NI'),('DE','WMF','Wassmannsdorf','Wassmannsdorf','BR'),('DE','WMG','Wurmberg','Wurmberg','BW'),('DE','WMH','Wallmenroth','Wallmenroth','RP'),('DE','WMI','Wald-Michelbach','Wald-Michelbach','HE'),('DE','WMM','Wemmetsweiler','Wemmetsweiler','SL'),('DE','WMO','Wiesmoor','Wiesmoor','NI'),('DE','WMR','Weimar','Weimar','TH'),('DE','WMS','Walsheim','Walsheim','RP'),('DE','WMU','Weilmunster','Weilmunster','HE'),('DE','WNB','Weissensee/Berlin','Weissensee/Berlin','BE'),('DE','WND','Wadern','Wadern','SL'),('DE','WNE','Wenden','Wenden','NW'),('DE','WNF','Wernfeld','Wernfeld','BY'),('DE','WNG','Weissenburg in Bayern','Weissenburg in Bayern','BY'),('DE','WNH','Windheim','Windheim','NW'),('DE','WNI','Winnweiler','Winnweiler','RP'),('DE','WNK','Windeck','Windeck','NW'),('DE','WNL','Wandersleben','Wandersleben','TH'),('DE','WNM','Wackernheim','Wackernheim','RP'),('DE','WNN','Wendlingen am Neckar','Wendlingen am Neckar','BW'),('DE','WNR','Wilnsdorf','Wilnsdorf','NW'),('DE','WNS','Windesheim','Windesheim','RP'),('DE','WNU','Weissenthurm','Weissenthurm','RP'),('DE','WOB','Wolfsburg','Wolfsburg','NI'),('DE','WOD','Westoverledingen, Gemeinde','Westoverledingen, Gemeinde','NI'),('DE','WOE','Worth am Rhein','Worth am Rhein','RP'),('DE','WOF','Wolfgang','Wolfgang','HE'),('DE','WOG','Worringen','Worringen','NW'),('DE','WOH','Wolfratshausen','Wolfratshausen','BY'),('DE','WOL','Wolgast','Wolgast','MV'),('DE','WON','Wolfstein/Pfalz','Wolfstein/Pfalz','RP'),('DE','WOR','Worms','Worms','RP'),('DE','WOS','Wollstein','Wollstein','RP'),('DE','WOT','Wort','Wort','BW'),('DE','WOZ','Wornitz','Wornitz','BY'),('DE','WPH','Wipperfurth','Wipperfurth','NW'),('DE','WQR','Wehr','Wehr','BW'),('DE','WRB','Weilerbach','Weilerbach','RP'),('DE','WRD','Weilrod','Weilrod','HE'),('DE','WRE','Werne','Werne','NW'),('DE','WRG','Wernesgrun','Wernesgrun','SN'),('DE','WRH','Wehrheim','Wehrheim','HE'),('DE','WRI','Wrist','Wrist','SH'),('DE','WRM','Wiernsheim','Wiernsheim','BW'),('DE','WRN','Walldurn','Walldurn','BW'),('DE','WRP','Worpswede','Worpswede','NI'),('DE','WRR','Worrstadt','Worrstadt','RP'),('DE','WRS','Wurselen','Wurselen','NW'),('DE','WRT','Wartenberg','Wartenberg','BY'),('DE','WRU','Wernau','Wernau','BW'),('DE','WRZ','Waren','Waren','MV'),('DE','WSA','Weissbach','Weissbach','BY'),('DE','WSB','Weinsberg','Weinsberg','BW'),('DE','WSC','Weissach','Weissach','BW'),('DE','WSD','Wallscheid','Wallscheid','RP'),('DE','WSE','Westerstede','Westerstede','NI'),('DE','WSF','Waldaschaff','Waldaschaff','BY'),('DE','WSG','Wirsberg','Wirsberg','BY'),('DE','WSH','Weil im Schonbuch','Weil im Schonbuch','BW'),('DE','WSI','Weissensee','Weissensee','TH'),('DE','WSK','Wittstock','Wittstock','BR'),('DE','WSL','Wessling','Wessling','BY'),('DE','WSM','Westerheim','Westerheim','BW'),('DE','WSN','Wissen','Wissen','RP'),('DE','WSP','Wiershop','Wiershop','SH'),('DE','WSS','Waldsassen','Waldsassen','BY'),('DE','WST','Willstatt','Willstatt','BW'),('DE','WSU','Wittschau','Wittschau','BY'),('DE','WSX','Wistedt','Wistedt','NI'),('DE','WSY','Wiesloch','Wiesloch','BW'),('DE','WTA','Worth an der Donau','Worth an der Donau','BY'),('DE','WTB','Wartenberg','Wartenberg','RP'),('DE','WTC','Winterbach','Winterbach','BW'),('DE','WTD','Wassertrudingen','Wassertrudingen','BY'),('DE','WTE','Wertingen','Wertingen','BY'),('DE','WTF','Woltersdorf','Woltersdorf','BR'),('DE','WTG','Wittenberg','Wittenberg','ST'),('DE','WTH','Wittlich','Wittlich','RP'),('DE','WTI','Wettingen','Wettingen','BW'),('DE','WTL','Waldachtal','Waldachtal','BW'),('DE','WTM','Wertheim','Wertheim','BW'),('DE','WTN','Wittingen','Wittingen','NI'),('DE','WTO','Wentorf','Wentorf','SH'),('DE','WTP','Waltrop','Waltrop','NW'),('DE','WTR','Wetter','Wetter','NW'),('DE','WTS','Waltershausen','Waltershausen','TH'),('DE','WTT','Witten','Witten','NW'),('DE','WTU','Wittichenau','Wittichenau','SN'),('DE','WTX','Wilthen','Wilthen','SN'),('DE','WUA','Wutha','Wutha','TH'),('DE','WUD','Wulsdorf','Wulsdorf','HB'),('DE','WUE','Wurzburg','Wurzburg','BY'),('DE','WUG','Wunnenberg','Wunnenberg','NW'),('DE','WUL','Wunsiedel','Wunsiedel','BY'),('DE','WUM','Wurmsham','Wurmsham','BY'),('DE','WUN','Wunstorf','Wunstorf','NI'),('DE','WUP','Wuppertal','Wuppertal','NW'),('DE','WUR','Worth am Main','Worth am Main','BY'),('DE','WUT','Wustenrot','Wustenrot','BW'),('DE','WUW','Waldburg','Waldburg','BW'),('DE','WVN','Wilhelmshaven','Wilhelmshaven','NI'),('DE','WWE','Westhausen','Westhausen','BW'),('DE','WWF','Waidhofen','Waidhofen','BY'),('DE','WWI','Weilerswist','Weilerswist','NW'),('DE','WWL','Weisweil','Weisweil','BW'),('DE','WWS','Weisswasser','Weisswasser','SN'),('DE','WWW','Weissenhorn','Weissenhorn','BY'),('DE','WWZ','Wallwitz','Wallwitz','ST'),('DE','WXS','Sonnern','Sonnern','NW'),('DE','WXT','Waldstetten','Waldstetten','BW'),('DE','WYD','Weil im Dorf','Weil im Dorf','BW'),('DE','WYK','Wyk auf Fohr','Wyk auf Fohr','SH'),('DE','WZA','Wiedenzhausen','Wiedenzhausen','BY'),('DE','WZB','Wurzbach','Wurzbach','TH'),('DE','WZE','Weeze','Weeze','NW'),('DE','WZM','Welzheim','Welzheim','BW'),('DE','WZN','Wurzen','Wurzen','SN'),('DE','WZU','Wietzendorf','Wietzendorf','NI'),('DE','XFW','Finkenwerder','Finkenwerder','HH'),('DE','XHR','Horhausen','Horhausen','RP'),('DE','XMN','Schmiechen','Schmiechen','BW'),('DE','XTE','Xanten','Xanten','NW'),('DE','XUE','Unterbernbach','Unterbernbach','BY'),('DE','YDX','Beverstedt','Beverstedt','NI'),('DE','YRD','Rhede','Rhede','NI'),('DE','YRW','Kalefeld','Kalefeld','NI'),('DE','YSF','Seifhennersdorf','Seifhennersdorf','SN'),('DE','YWX','Waxweiler','Waxweiler','RP'),('DE','ZAG','Zell unter Aichelberg','Zell unter Aichelberg','BW'),('DE','ZAR','Zarrentin','Zarrentin','MV'),('DE','ZAS','Arenshausen','Arenshausen','TH'),('DE','ZBI','Zorbig','Zorbig','ST'),('DE','ZBT','Zerbst','Zerbst','ST'),('DE','ZBU','Zorbau','Zorbau','ST'),('DE','ZEH','Zell am Harmersbach','Zell am Harmersbach','BW'),('DE','ZEI','Zeil am Main','Zeil am Main','BY'),('DE','ZEL','Zell/Mosel','Zell/Mosel','RP'),('DE','ZEN','Zellingen','Zellingen','BY'),('DE','ZER','Zernsdorf','Zernsdorf','BR'),('DE','ZET','Zetel','Zetel','NI'),('DE','ZEU','Zeulenroda','Zeulenroda','TH'),('DE','ZEV','Zeven','Zeven','NI'),('DE','ZEW','Zell im Wiesental','Zell im Wiesental','BW'),('DE','ZEZ','Zeitz','Zeitz','ST'),('DE','ZHA','Zahna','Zahna','ST'),('DE','ZIN','Zinnowitz','Zinnowitz','MV'),('DE','ZIR','Zirndorf','Zirndorf','BY'),('DE','ZIS','Zingst','Zingst','MV'),('DE','ZIT','Zittau','Zittau','SN'),('DE','ZLE','Zehlendorf','Zehlendorf','BE'),('DE','ZLG','Holzgerlingen','Holzgerlingen','BW'),('DE','ZLT','Zeltingen-Rachtig','Zeltingen-Rachtig','RP'),('DE','ZNW','Zinnwald-Georgenfeld','Zinnwald-Georgenfeld','SN'),('DE','ZNZ','Zollnitz','Zollnitz','TH'),('DE','ZOG','Zolling','Zolling','BY'),('DE','ZRD','Zorneding','Zorneding','BY'),('DE','ZSA','Zachow','Zachow','BR'),('DE','ZSC','Zschornewitz','Zschornewitz','ST'),('DE','ZSE','Zeesen','Zeesen','BR'),('DE','ZSR','Ziesar','Ziesar','BR'),('DE','ZTN','Zeithain','Zeithain','SN'),('DE','ZUE','Zulpich','Zulpich','NW'),('DE','ZUS','Zusmarshausen','Zusmarshausen','BY'),('DE','ZWE','Zweibrucken','Zweibrucken','RP'),('DE','ZWI','Zwickau','Zwickau','SN'),('DE','ZWK','Zwenkau','Zwenkau','SN'),('DE','ZWL','Zwiesel','Zwiesel','BY'),('DE','ZWO','Zwochau','Zwochau','SN'),('DE','ZWZ','Zwonitz','Zwonitz','SN'),('DE','ZZH','Zuzenhausen','Zuzenhausen','BW'),('DJ','','','',''),('DJ','JIB','Djibouti','Djibouti',''),('DK','','','',''),('DK','AAB','Aabenraa','Aabenraa',''),('DK','AAL','Aalborg','Aalborg',''),('DK','AAP','Aarup','Aarup',''),('DK','AAR','Arhus','Arhus',''),('DK','ABK','Alebak','Alebak',''),('DK','ABT','Albertslund','Albertslund',''),('DK','ADN','Arden','Arden',''),('DK','AEY','Aalestrup','Aalestrup',''),('DK','AGD','Agerbak','Agerbak',''),('DK','AGE','Allinge','Allinge',''),('DK','AGH','Agger Havn','Agger Havn',''),('DK','AGO','Agerso','Agerso',''),('DK','AHJ','Abyhoj/Arhus','Abyhoj/Arhus',''),('DK','ALL','Allerod','Allerod',''),('DK','ALN','Allingabro','Allingabro',''),('DK','ANB','Ans by','Ans by',''),('DK','ANH','Anholt','Anholt',''),('DK','ANS','Ansager','Ansager',''),('DK','ARD','Arosund','Arosund',''),('DK','ARK','Aroskobing','Aroskobing',''),('DK','ARO','Aro','Aro',''),('DK','ASA','Asaa','Asaa',''),('DK','ASH','Aggersund','Aggersund',''),('DK','ASK','Asko','Asko',''),('DK','ASN','Assens','Assens',''),('DK','ASP','Allestrup','Allestrup',''),('DK','ASS','Asnas','Asnas',''),('DK','ASV','Asnasvarkets Havn','Asnasvarkets Havn',''),('DK','AUB','Augustenborg','Augustenborg',''),('DK','AUU','Aulum','Aulum',''),('DK','AVE','Avedorevarkets Havn','Avedorevarkets Havn',''),('DK','AVK','Avernak By','Avernak By',''),('DK','AVL','Avlum','Avlum',''),('DK','AYB','Abybro','Abybro',''),('DK','AZS','Aars','Aars',''),('DK','BAG','Bagenkop','Bagenkop',''),('DK','BBG','Bovlingbjerg','Bovlingbjerg',''),('DK','BDE','Branderup','Branderup',''),('DK','BDG','Bording','Bording',''),('DK','BDV','Bronderslev','Bronderslev',''),('DK','BDX','Bandholm','Bandholm',''),('DK','BDY','Brody','Brody',''),('DK','BEL','Bellinge','Bellinge',''),('DK','BGO','Baago','Baago',''),('DK','BGS','Bagsvard','Bagsvard',''),('DK','BGZ','Bogense','Bogense',''),('DK','BID','Bindslev','Bindslev',''),('DK','BIR','Birkerod','Birkerod',''),('DK','BJB','Bjerringbro','Bjerringbro',''),('DK','BJE','Bjert Strand','Bjert Strand',''),('DK','BKH','Blokhus','Blokhus',''),('DK','BKP','Borkop','Borkop',''),('DK','BLB','Ballebro','Ballebro',''),('DK','BLG','Balling','Balling',''),('DK','BLL','Billund','Billund',''),('DK','BLN','Blans','Blans',''),('DK','BLP','Ballerup','Ballerup',''),('DK','BLU','Baelum','Baelum',''),('DK','BMG','Bramming','Bramming',''),('DK','BOG','Bogo By','Bogo By',''),('DK','BOR','Borup','Borup',''),('DK','BOS','Bojden','Bojden',''),('DK','BOY','Broby','Broby',''),('DK','BRA','Brande','Brande',''),('DK','BRB','Brabrand','Brabrand',''),('DK','BRD','Bredsten','Bredsten',''),('DK','BRE','Bredebro','Bredebro',''),('DK','BRH','Branden Havn','Branden Havn',''),('DK','BRO','Bronderslev','Bronderslev',''),('DK','BRP','Brorup','Brorup',''),('DK','BRT','Brovst','Brovst',''),('DK','BRU','Brenderup, Ejby','Brenderup, Ejby',''),('DK','BRY','Brondby','Brondby',''),('DK','BSU','Braedstrup','Braedstrup',''),('DK','BTP','Bostrup','Bostrup',''),('DK','BUP','Broderup','Broderup',''),('DK','BYL','Bylderup','Bylderup',''),('DK','CNL','Sindal','Sindal',''),('DK','CPH','Kobenhavn','Kobenhavn',''),('DK','CSF','Christiansfeld','Christiansfeld',''),('DK','DAL','Dalmose','Dalmose',''),('DK','DAN','Cementfabriken Dania','Cementfabriken Dania',''),('DK','DAS','Dansk Salts Havn','Dansk Salts Havn',''),('DK','DIA','Dianalund','Dianalund',''),('DK','DKD','Dokkedal','Dokkedal',''),('DK','DLB','Dalby','Dalby',''),('DK','DLD','Dronninglund','Dronninglund',''),('DK','DRA','Dragor','Dragor',''),('DK','DRP','Durup','Durup',''),('DK','DRS','Drosby','Drosby',''),('DK','EBJ','Esbjerg','Esbjerg',''),('DK','EBT','Ebeltoft','Ebeltoft',''),('DK','EDL','Endelave','Endelave',''),('DK','EGA','Ega','Ega',''),('DK','EGN','Egense','Egense',''),('DK','EGV','Egtved','Egtved',''),('DK','EJS','Ejstrup','Ejstrup',''),('DK','EJY','Ejby','Ejby',''),('DK','END','Egernsund','Egernsund',''),('DK','ENS','Enstedvarket Havn','Enstedvarket Havn',''),('DK','ENV','Engesvang','Engesvang',''),('DK','ESP','Espergarde','Espergarde',''),('DK','FAA','Faaborg','Faaborg',''),('DK','FAK','Fakse Ladeplads Havn','Fakse Ladeplads Havn',''),('DK','FBG','Frederiksberg','Frederiksberg',''),('DK','FDH','Frederikshavn','Frederikshavn',''),('DK','FDS','Frederikssund','Frederikssund',''),('DK','FDV','Frederiksvark','Frederiksvark',''),('DK','FEJ','Fejo','Fejo',''),('DK','FER','Ferritslev','Ferritslev',''),('DK','FGS','Feggesund','Feggesund',''),('DK','FJV','Fjerritslev','Fjerritslev',''),('DK','FMO','Femo','Femo',''),('DK','FNS','Fornas','Fornas',''),('DK','FRA','Fraugde','Fraugde',''),('DK','FRC','Fredericia','Fredericia',''),('DK','FRE','Fredensborg','Fredensborg',''),('DK','FRM','Farum','Farum',''),('DK','FSO','Farso','Farso',''),('DK','FTL','Ferritslev','Ferritslev',''),('DK','FUG','Fuglebjerg','Fuglebjerg',''),('DK','FUH','Fur','Fur',''),('DK','FUP','Faarup','Faarup',''),('DK','FVG','Faarvang','Faarvang',''),('DK','FVJ','Faarevejle','Faarevejle',''),('DK','FYH','Fynshav','Fynshav',''),('DK','GBJ','Gadbjerg','Gadbjerg',''),('DK','GBY','Gamby','Gamby',''),('DK','GDM','Gudhjem','Gudhjem',''),('DK','GDS','Gedsted','Gedsted',''),('DK','GED','Gedser','Gedser',''),('DK','GFH','Gulfhavn','Gulfhavn',''),('DK','GIS','Gislinge','Gislinge',''),('DK','GIV','Give','Give',''),('DK','GJN','Gjern','Gjern',''),('DK','GJR','Gjerlev','Gjerlev',''),('DK','GJS','Gjessing','Gjessing',''),('DK','GLB','Gleibjerg','Gleibjerg',''),('DK','GLD','Gelsted','Gelsted',''),('DK','GLE','Gilleleje','Gilleleje',''),('DK','GLM','Glamsbjerg','Glamsbjerg',''),('DK','GLS','Glostrup','Glostrup',''),('DK','GLT','Galten','Galten',''),('DK','GLV','Gorlev','Gorlev',''),('DK','GLY','Glyngore','Glyngore',''),('DK','GRA','Grasten','Grasten',''),('DK','GRD','Gredstedbro','Gredstedbro',''),('DK','GRE','Grenaa','Grenaa',''),('DK','GRG','Gording','Gording',''),('DK','GRI','Grimstrup','Grimstrup',''),('DK','GRN','Grindsted','Grindsted',''),('DK','GRS','Grasted','Grasted',''),('DK','GRV','Greve','Greve',''),('DK','GSP','Gistrup','Gistrup',''),('DK','GTR','Gistrup','Gistrup',''),('DK','GUD','Gudbjerg','Gudbjerg',''),('DK','HAA','Harlev','Harlev',''),('DK','HAD','Haderslev','Haderslev',''),('DK','HAN','Hanstholm','Hanstholm',''),('DK','HAP','Havdrup','Havdrup',''),('DK','HAS','Hals','Hals',''),('DK','HBA','Humlebak','Humlebak',''),('DK','HBG','Houborg','Houborg',''),('DK','HBK','Holbak','Holbak',''),('DK','HBO','Hobro','Hobro',''),('DK','HBR','Harboor','Harboor',''),('DK','HBY','Haarby','Haarby',''),('DK','HDH','Hardeshoj','Hardeshoj',''),('DK','HDS','Hadsten','Hadsten',''),('DK','HED','Hedensted','Hedensted',''),('DK','HEL','Helsinge','Helsinge',''),('DK','HER','Herning','Herning',''),('DK','HFE','Herfolge','Herfolge',''),('DK','HGL','Hogelund','Hogelund',''),('DK','HHM','Horsholm','Horsholm',''),('DK','HHS','Hedehusene','Hedehusene',''),('DK','HIL','Hillerod','Hillerod',''),('DK','HIR','Hirtshals','Hirtshals',''),('DK','HJB','Hojbjerg','Hojbjerg',''),('DK','HJE','Hojer','Hojer',''),('DK','HJG','Hjorring','Hjorring',''),('DK','HJM','Hjerm','Hjerm',''),('DK','HJT','Hjerting','Hjerting',''),('DK','HKV','Halsskov','Halsskov',''),('DK','HLE','Hellested','Hellested',''),('DK','HLS','Helsingor','Helsingor',''),('DK','HME','Hammel','Hammel',''),('DK','HNB','Havneby','Havneby',''),('DK','HNG','Hong','Hong',''),('DK','HNN','Hinnerup','Hinnerup',''),('DK','HOE','Holte','Holte',''),('DK','HOH','Hou Havn','Hou Havn',''),('DK','HOL','Holeby','Holeby',''),('DK','HOO','Holme-Olstrup','Holme-Olstrup',''),('DK','HOR','Horsens','Horsens',''),('DK','HPN','Hampen','Hampen',''),('DK','HRN','Horning','Horning',''),('DK','HRP','Hellerup','Hellerup',''),('DK','HRU','Horup','Horup',''),('DK','HRV','Herlev','Herlev',''),('DK','HSB','Holstebro','Holstebro',''),('DK','HSL','Hasle','Hasle',''),('DK','HSS','Hasselager','Hasselager',''),('DK','HST','Holsted','Holsted',''),('DK','HSU','Hadsund','Hadsund',''),('DK','HSV','Haslev','Haslev',''),('DK','HSY','Hornsyld','Hornsyld',''),('DK','HTT','Hatting','Hatting',''),('DK','HUN','Hundested','Hundested',''),('DK','HUR','Hurup','Hurup',''),('DK','HVA','Hvalpsund','Hvalpsund',''),('DK','HVG','Havnegade','Havnegade',''),('DK','HVN','Havnso','Havnso',''),('DK','HVS','Hvide Sande','Hvide Sande',''),('DK','HVV','Hvidovre','Hvidovre',''),('DK','IKA','Ikast','Ikast',''),('DK','ISJ','Ishoj','Ishoj',''),('DK','JRD','Jordlose','Jordlose',''),('DK','JRP','Jyderup','Jyderup',''),('DK','JSD','Jersie Strand','Jersie Strand',''),('DK','JUE','Juelsminde','Juelsminde',''),('DK','JYL','Jyllinge','Jyllinge',''),('DK','KAL','Kalundborg','Kalundborg',''),('DK','KAR','Karlslunde','Karlslunde',''),('DK','KBY','Kyndbyvaerkets Havn','Kyndbyvaerkets Havn',''),('DK','KDM','Kollund Mole','Kollund Mole',''),('DK','KEP','Kirke-Eskilstrup','Kirke-Eskilstrup',''),('DK','KHV','Knudshoved','Knudshoved',''),('DK','KIB','Kibak','Kibak',''),('DK','KJE','Kjellerup','Kjellerup',''),('DK','KLD','Kolind','Kolind',''),('DK','KNB','Knebel','Knebel',''),('DK','KOG','Koge','Koge',''),('DK','KOK','Kolby Kas','Kolby Kas',''),('DK','KOL','Kolding','Kolding',''),('DK','KON','Cementfabrikken Kongsdal Havn','Cementfabrikken Kongsdal Havn',''),('DK','KPV','Kliplev','Kliplev',''),('DK','KRA','Kragenas','Kragenas',''),('DK','KRB','Kirkeby','Kirkeby',''),('DK','KRP','Karup','Karup',''),('DK','KRR','Korsor','Korsor',''),('DK','KRS','Krusa','Krusa',''),('DK','KTD','Kerteminde','Kerteminde',''),('DK','KTP','Kastrup','Kastrup',''),('DK','KVB','Klovborg','Klovborg',''),('DK','KVG','Kvistgaard','Kvistgaard',''),('DK','KVR','Kvarndrup','Kvarndrup',''),('DK','LAA','Lasby','Lasby',''),('DK','LAN','Langa','Langa',''),('DK','LEJ','Lejre','Lejre',''),('DK','LEM','Lem','Lem',''),('DK','LGR','Logstor','Logstor',''),('DK','LGS','Langeskov','Langeskov',''),('DK','LIG','Losning','Losning',''),('DK','LIN','Lindo Havn','Lindo Havn',''),('DK','LKO','Logumkloster','Logumkloster',''),('DK','LLS','Lille Skensved','Lille Skensved',''),('DK','LND','Lunderskov','Lunderskov',''),('DK','LNE','Lynge','Lynge',''),('DK','LOG','Logstrup','Logstrup',''),('DK','LOH','Lohals','Lohals',''),('DK','LVG','Lemvig','Lemvig',''),('DK','LYN','Lyngby','Lyngby',''),('DK','LYO','Lyngs Odde Havn','Lyngs Odde Havn',''),('DK','MAR','Marslev','Marslev',''),('DK','MAS','Masnedo','Masnedo',''),('DK','MID','Middelfart','Middelfart',''),('DK','MKE','Morke','Morke',''),('DK','MKH','Masnedovaerkets Havn/Vordingborg','Masnedovaerkets Havn/Vordingborg',''),('DK','MLV','Malov','Malov',''),('DK','MNK','Munkebo','Munkebo',''),('DK','MNS','Masnedsund','Masnedsund',''),('DK','MOM','Mommark','Mommark',''),('DK','MRB','Marbak Havn','Marbak Havn',''),('DK','MRR','Mariager','Mariager',''),('DK','MRS','Marstal','Marstal',''),('DK','MRU','Mundelstrup','Mundelstrup',''),('DK','MRV','Maribo','Maribo',''),('DK','MUP','Moldrup','Moldrup',''),('DK','NAG','Norager','Norager',''),('DK','NAK','Nakskov','Nakskov',''),('DK','NAV','Norre Alslev','Norre Alslev',''),('DK','NBE','Norreballe','Norreballe',''),('DK','NBG','Nyborg','Nyborg',''),('DK','NBR','Nordborg','Nordborg',''),('DK','NDB','Nordby Havn, Fano','Nordby Havn, Fano',''),('DK','NEX','Nekso','Nekso',''),('DK','NGB','Nagbol','Nagbol',''),('DK','NIB','Nibe','Nibe',''),('DK','NKV','Nordenskov','Nordenskov',''),('DK','NRE','Norre Aaby','Norre Aaby',''),('DK','NRM','Narum','Narum',''),('DK','NRS','Norresundby','Norresundby',''),('DK','NRV','Norre Vium','Norre Vium',''),('DK','NSD','Norre Snede','Norre Snede',''),('DK','NTD','Nysted','Nysted',''),('DK','NUD','Nassund','Nassund',''),('DK','NVD','Nastved','Nastved',''),('DK','NVM','Vium','Vium',''),('DK','NYF','Nykobing Falster','Nykobing Falster',''),('DK','NYM','Nykobing Mors','Nykobing Mors',''),('DK','OAS','Oster Assels','Oster Assels',''),('DK','ODD','Oster Doense','Oster Doense',''),('DK','ODE','Odense','Odense',''),('DK','ODX','Odder','Odder',''),('DK','OEL','Olstykke Stationsby','Olstykke Stationsby',''),('DK','OFQ','Orbak','Orbak',''),('DK','OHJ','Ornhoj','Ornhoj',''),('DK','OKB','Ostbirk','Ostbirk',''),('DK','OLG','Olgod','Olgod',''),('DK','OMO','Omo','Omo',''),('DK','ORE','Orehoved, Falster','Orehoved, Falster',''),('DK','ORO','Oro','Oro',''),('DK','OSD','Oster Snede','Oster Snede',''),('DK','OSX','Osby','Osby',''),('DK','OTK','Olstykke','Olstykke',''),('DK','OTR','Ovtrup','Ovtrup',''),('DK','OTT','Otterup','Otterup',''),('DK','OTV','Oster Torslev','Oster Torslev',''),('DK','OYK','Olstykke','Olstykke',''),('DK','PAN','Pandrup','Pandrup',''),('DK','PAO','Padborg','Padborg',''),('DK','RAN','Randers','Randers',''),('DK','RDG','Rodding','Rodding',''),('DK','RDK','Rodekro','Rodekro',''),('DK','REY','Ry','Ry',''),('DK','RIB','Ribe','Ribe',''),('DK','RIN','Ringe','Ringe',''),('DK','RKB','Rudkobing','Rudkobing',''),('DK','RKE','Roskilde','Roskilde',''),('DK','RKG','Ringkobing','Ringkobing',''),('DK','RNG','Ringsted','Ringsted',''),('DK','RNM','Ranum','Ranum',''),('DK','RNN','Ronne','Ronne',''),('DK','ROD','Rodbyhavn','Rodbyhavn',''),('DK','ROF','Rodby (Fagehavn)','Rodby (Fagehavn)',''),('DK','ROR','Aalborg Portland Cementfabrikk','Aalborg Portland Cementfabrikk',''),('DK','RRV','Rorvig','Rorvig',''),('DK','RSL','Roslev','Roslev',''),('DK','RSS','Risskov','Risskov',''),('DK','RUG','Rungsted','Rungsted',''),('DK','RVY','Ruds-Vedby','Ruds-Vedby',''),('DK','RYM','Ryomgard','Ryomgard',''),('DK','RYN','Rynkeby','Rynkeby',''),('DK','SAE','Saby','Saby',''),('DK','SAG','Sandager','Sandager',''),('DK','SAX','Sakskobing','Sakskobing',''),('DK','SBG','Soborg','Soborg',''),('DK','SBK','Stubbekobing','Stubbekobing',''),('DK','SBY','Sundby','Sundby',''),('DK','SDA','Sydals','Sydals',''),('DK','SDO','Skaro/Drejo','Skaro/Drejo',''),('DK','SDR','Sonderso','Sonderso',''),('DK','SDS','Sonderso','Sonderso',''),('DK','SEJ','Sejerslev','Sejerslev',''),('DK','SEO','Sejero','Sejero',''),('DK','SGD','Sonderborg','Sonderborg',''),('DK','SJB','Skejby','Skejby',''),('DK','SJO','Sjallands Odde','Sjallands Odde',''),('DK','SKA','Skagen','Skagen',''),('DK','SKB','Skarbak','Skarbak',''),('DK','SKD','Skovlund','Skovlund',''),('DK','SKE','Skavinge','Skavinge',''),('DK','SKG','Skanderborg','Skanderborg',''),('DK','SKI','Stenkilde','Stenkilde',''),('DK','SKJ','Skjern','Skjern',''),('DK','SKL','Skals','Skals',''),('DK','SKM','Skamby','Skamby',''),('DK','SKO','Skodborg','Skodborg',''),('DK','SKP','Skorping','Skorping',''),('DK','SKR','Skrydstrup','Skrydstrup',''),('DK','SKS','Vojens','Vojens',''),('DK','SKT','Skodstrup','Skodstrup',''),('DK','SKV','Skive','Skive',''),('DK','SKY','Skibby','Skibby',''),('DK','SLA','Slangerup','Slangerup',''),('DK','SLB','Silkeborg','Silkeborg',''),('DK','SLE','Stenlose','Stenlose',''),('DK','SLG','Slagelse','Slagelse',''),('DK','SLV','Salvig Havn','Salvig Havn',''),('DK','SMA','Stokkemarke','Stokkemarke',''),('DK','SMO','Smorum','Smorum',''),('DK','SND','Sonder','Sonder',''),('DK','SNE','Snekkersten','Snekkersten',''),('DK','SNN','Svinninge','Svinninge',''),('DK','SNO','Stryno','Stryno',''),('DK','SNS','Stenstrup','Stenstrup',''),('DK','SNY','Sundby, Mors','Sundby, Mors',''),('DK','SOB','Soby Havn','Soby Havn',''),('DK','SOK','Kongerslev','Kongerslev',''),('DK','SOM','Sonder Omme','Sonder Omme',''),('DK','SOV','Sorvad','Sorvad',''),('DK','SPB','Spodsbjerg Havn','Spodsbjerg Havn',''),('DK','SPO','Spottrup','Spottrup',''),('DK','SPP','Sporup','Sporup',''),('DK','SRO','Soro','Soro',''),('DK','SRP','Stenderup','Stenderup',''),('DK','SSK','Skalskor','Skalskor',''),('DK','SSV','Studstrupvarkets Havn','Studstrupvarkets Havn',''),('DK','STA','Stavning','Stavning',''),('DK','STB','Strib Havn','Strib Havn',''),('DK','STE','Stege','Stege',''),('DK','STG','Stignasvarkets Havn','Stignasvarkets Havn',''),('DK','STL','Stenlille','Stenlille',''),('DK','STN','Stigsnas','Stigsnas',''),('DK','STO','Stovring','Stovring',''),('DK','STR','Struer','Struer',''),('DK','STT','Statoil-Havnen','Statoil-Havnen',''),('DK','SUE','Sundsore','Sundsore',''),('DK','SUS','Sunds','Sunds',''),('DK','SVA','Svaneke','Svaneke',''),('DK','SVE','Svendborg','Svendborg',''),('DK','SVG','Sandvig','Sandvig',''),('DK','SVN','Svenstrup','Svenstrup',''),('DK','SVV','Stalvalsevarket','Stalvalsevarket',''),('DK','SYD','Sydborg','Sydborg',''),('DK','TBA','Taarbak','Taarbak',''),('DK','TED','Thisted','Thisted',''),('DK','TFT','Toftlund','Toftlund',''),('DK','TGV','Tinglev','Tinglev',''),('DK','THM','Them','Them',''),('DK','THO','Thuro','Thuro',''),('DK','THY','Thyholm','Thyholm',''),('DK','TIL','Tilst','Tilst',''),('DK','TIS','Tistrup','Tistrup',''),('DK','TKA','Tranekaer','Tranekaer',''),('DK','TLV','Taulov','Taulov',''),('DK','TMD','Thorsminde','Thorsminde',''),('DK','TNO','Tuno','Tuno',''),('DK','TOE','Torring','Torring',''),('DK','TOM','Tommerup','Tommerup',''),('DK','TON','Tonder','Tonder',''),('DK','TRI','Trige','Trige',''),('DK','TRM','Tarm','Tarm',''),('DK','TRN','Tranebjerg','Tranebjerg',''),('DK','TRS','Tars','Tars',''),('DK','TTR','Tastrup','Tastrup',''),('DK','TUB','Tuborg','Tuborg',''),('DK','TUR','Tureby','Tureby',''),('DK','TYB','Tyboron','Tyboron',''),('DK','ULB','Ulfborg','Ulfborg',''),('DK','ULD','Uldum','Uldum',''),('DK','ULL','Ullerslev','Ullerslev',''),('DK','UNX','Masnedsund Godningshamn','Masnedsund Godningshamn',''),('DK','VAD','Vadum','Vadum',''),('DK','VAE','Vallensbaek','Vallensbaek',''),('DK','VAL','Valby','Valby',''),('DK','VAS','Vigsnas','Vigsnas',''),('DK','VBG','Vissenbjerg','Vissenbjerg',''),('DK','VBI','Viby/Sjalland','Viby/Sjalland',''),('DK','VBJ','Vestbjerg','Vestbjerg',''),('DK','VBK','Vedbak','Vedbak',''),('DK','VDE','Varde','Varde',''),('DK','VDP','Vamdrup','Vamdrup',''),('DK','VEJ','Vejle','Vejle',''),('DK','VEN','Veno Havn','Veno Havn',''),('DK','VES','Vestero Havn, Laso','Vestero Havn, Laso',''),('DK','VIB','Viborg','Viborg',''),('DK','VID','Videbaek','Videbaek',''),('DK','VIG','Vig','Vig',''),('DK','VIR','Virum','Virum',''),('DK','VIY','Viby J','Viby J',''),('DK','VJN','Vejen','Vejen',''),('DK','VLE','Varlose','Varlose',''),('DK','VMB','Vemb','Vemb',''),('DK','VNG','Vang Havn','Vang Havn',''),('DK','VNR','Vinderup','Vinderup',''),('DK','VOK','Vodskov','Vodskov',''),('DK','VOR','Vordingborg','Vordingborg',''),('DK','VPP','Vipperod','Vipperod',''),('DK','VRA','Vra','Vra',''),('DK','VSV','Norjyllandsvarkets havn','Norjyllandsvarkets havn',''),('DM','','','',''),('DM','ADM','Anse du Mai','Anse du Mai',''),('DM','BEL','Belfast','Belfast',''),('DM','DOM','Dominica','Dominica',''),('DM','POR','Portsmouth','Portsmouth',''),('DM','RSU','Roseau','Roseau',''),('DO','','','',''),('DO','AZU','Azua','Azua',''),('DO','BAN','Bani','Bani',''),('DO','BCC','Boca Chica','Boca Chica',''),('DO','BRX','Barahona','Barahona',''),('DO','CAU','Caucedo','Caucedo',''),('DO','CBJ','Cabo Rojo','Cabo Rojo',''),('DO','DAJ','Dajabon','Dajabon',''),('DO','HAI','Rio Haina','Rio Haina',''),('DO','JIM','Jimani','Jimani',''),('DO','LRM','La Romana','La Romana',''),('DO','MAN','Manzanillo','Manzanillo',''),('DO','MCR','San Fernando de Monte Cristi','San Fernando de Monte Cristi',''),('DO','PAL','Palenque','Palenque',''),('DO','PDR','Pedernales','Pedernales',''),('DO','PIM','Pimentel','Pimentel',''),('DO','POP','Puerto Plata','Puerto Plata',''),('DO','PUD','Puerto Duarte','Puerto Duarte',''),('DO','PUJ','Punta Cana Apt','Punta Cana Apt',''),('DO','PUO','Puerto Libertador','Puerto Libertador',''),('DO','PVA','Puerto Viejo de Azua','Puerto Viejo de Azua',''),('DO','SAL','Salcedo','Salcedo',''),('DO','SAM','Santa Barbara de Samana','Santa Barbara de Samana',''),('DO','SCR','San Cristobal','San Cristobal',''),('DO','SDQ','Santo Domingo','Santo Domingo',''),('DO','SFN','San Francisco de Macoris','San Francisco de Macoris',''),('DO','SIS','San Ignacio Sabaneta','San Ignacio Sabaneta',''),('DO','SJM','San Juan de la Maguana','San Juan de la Maguana',''),('DO','SNX','Sabana de la Mar','Sabana de la Mar',''),('DO','SNZ','Sanchez','Sanchez',''),('DO','SPM','San Pedro de Macoris','San Pedro de Macoris',''),('DO','STI','Santiago de los Caballeros','Santiago de los Caballeros',''),('DO','VAL','Villa Altagracia','Villa Altagracia',''),('DZ','','','',''),('DZ','AAE','Annaba (ex Bone)','Annaba (ex Bone)',''),('DZ','ALG','Alger (Algiers)','Alger (Algiers)',''),('DZ','ANI','L\'Arbaa Nait Irathen','L\'Arbaa Nait Irathen',''),('DZ','AZW','Arzew','Arzew',''),('DZ','BJA','Bejaia (ex Bougie)','Bejaia (ex Bougie)',''),('DZ','BOM','Bordj Menaiel','Bordj Menaiel',''),('DZ','BOR','Bordj Bou Arreridj','Bordj Bou Arreridj',''),('DZ','BOU','Boumerdas','Boumerdas',''),('DZ','BSF','Benisaf','Benisaf',''),('DZ','BTA','Bethoula','Bethoula',''),('DZ','CHE','Cherchell','Cherchell',''),('DZ','CLE','La Calle','La Calle',''),('DZ','COL','Collo','Collo',''),('DZ','CZL','Constantine','Constantine',''),('DZ','DEL','Dellys','Dellys',''),('DZ','DEM','Draa el Mizan','Draa el Mizan',''),('DZ','DJE','Djen-Djen','Djen-Djen',''),('DZ','DJI','Djidjelli','Djidjelli',''),('DZ','GHA','Ghardaia','Ghardaia',''),('DZ','GHZ','Ghazaouet','Ghazaouet',''),('DZ','HME','Hassi Messaoud','Hassi Messaoud',''),('DZ','KHE','Kherrata','Kherrata',''),('DZ','KHM','Khemis Miliana','Khemis Miliana',''),('DZ','MOS','Mostaganem','Mostaganem',''),('DZ','ORN','Oran','Oran',''),('DZ','SET','Setif','Setif',''),('DZ','SKI','Skikda (ex Philippeville)','Skikda (ex Philippeville)',''),('DZ','TAH','Taher','Taher',''),('DZ','TEN','Tenes','Tenes',''),('DZ','TLM','Tlemcen','Tlemcen',''),('EC','','','',''),('EC','ATF','Ambato','Ambato',''),('EC','AYO','Puerto Ayora, Isla Santa Cruz','Puerto Ayora, Isla Santa Cruz',''),('EC','BAQ','Puerto Baquerizo Moreno','Puerto Baquerizo Moreno',''),('EC','BHA','Bahia de Caraquez','Bahia de Caraquez',''),('EC','CAR','Pedro Carbo','Pedro Carbo',''),('EC','CAT','Caleta Tagus','Caleta Tagus',''),('EC','CHA','Chanduy','Chanduy',''),('EC','CHG','Chongon','Chongon',''),('EC','CUE','Cuenca','Cuenca',''),('EC','DUN','Duran','Duran',''),('EC','EBL','Balao','Balao',''),('EC','ELC','El Carmen','El Carmen',''),('EC','ESM','Esmeraldas','Esmeraldas',''),('EC','GPS','Galapagos Islands','Galapagos Islands',''),('EC','GYE','Guayaquil','Guayaquil',''),('EC','JIP','Jipijapa','Jipijapa',''),('EC','LAS','Lasso','Lasso',''),('EC','LAT','Latacunga','Latacunga',''),('EC','LLD','La Libertad','La Libertad',''),('EC','LOH','Loja','Loja',''),('EC','LPT','La Puntilla','La Puntilla',''),('EC','MAC','Machachi','Machachi',''),('EC','MCH','Machala','Machala',''),('EC','MEC','Manta','Manta',''),('EC','MRR','Macara','Macara',''),('EC','MTV','Monteverde','Monteverde',''),('EC','PBO','Puerto Bolivar','Puerto Bolivar',''),('EC','PSJ','Posorja','Posorja',''),('EC','PUN','Puna','Puna',''),('EC','PVO','Portoviejo','Portoviejo',''),('EC','QUI','Quinche','Quinche',''),('EC','QVD','Quevedo','Quevedo',''),('EC','RBA','Riobamba','Riobamba',''),('EC','SBO','Simon Bolivar','Simon Bolivar',''),('EC','SDO','Santo Domingo de los Colorados','Santo Domingo de los Colorados',''),('EC','SLR','San Lorenzo','San Lorenzo',''),('EC','SNC','Salinas','Salinas',''),('EC','SYM','Seymour','Seymour',''),('EC','TEP','Tepre','Tepre',''),('EC','UIO','Quito','Quito',''),('EC','VEI','Velasco Ibarra','Velasco Ibarra',''),('EC','VIL','Puerto Villamil, Isla Isabela','Puerto Villamil, Isla Isabela',''),('EC','ZPT','Zapotal de Colonche','Zapotal de Colonche',''),('EE','','','',''),('EE','AHJ','Ahja','Ahja','65'),('EE','APL','Abja-Paluoja','Abja-Paluoja','84'),('EE','ARD','Ardu','Ardu','37'),('EE','ASE','Aseri','Aseri','44'),('EE','AUD','Audru','Audru','67'),('EE','BEK','Bekkeri','Bekkeri','37'),('EE','DIR','Dirhami','Dirhami','57'),('EE','ELV','Elva','Elva','78'),('EE','HAA','Haapsalu','Haapsalu','57'),('EE','HJA','Haljala','Haljala','59'),('EE','HLA','Halinga','Halinga','67'),('EE','HLT','Heltermaa','Heltermaa','39'),('EE','HNE','Haabneeme','Haabneeme','37'),('EE','IMA','Imavere','Imavere','51'),('EE','JGA','Jogeva','Jogeva','49'),('EE','JUR','Juri','Juri','37'),('EE','JVI','Johvi','Johvi','44'),('EE','KAD','Kadrina','Kadrina','49'),('EE','KDL','Kardla','Kardla','39'),('EE','KEI','Keila','Keila','37'),('EE','KHA','Kohila','Kohila','70'),('EE','KIA','Kaina','Kaina','39'),('EE','KJE','Kohtla-Jarve','Kohtla-Jarve','44'),('EE','KJI','Kolga-Jaani','Kolga-Jaani','84'),('EE','KLL','Kallaste','Kallaste','78'),('EE','KND','Kunda','Kunda','59'),('EE','KUI','Kuivastu','Kuivastu','74'),('EE','KUR','Kuressaare sadam','Kuressaare sadam','74'),('EE','LAA','Laagri','Laagri','37'),('EE','LHT','Lehtma','Lehtma','39'),('EE','LHU','Lohusuu','Lohusuu','44'),('EE','LIH','Lihula','Lihula','57'),('EE','LIN','Lindi','Lindi','67'),('EE','LSA','Loksa','Loksa','37'),('EE','LSL','Lohusalu','Lohusalu','37'),('EE','MDR','Miiduranna','Miiduranna','37'),('EE','MNT','Montu','Montu','74'),('EE','MRD','Maardu','Maardu','37'),('EE','MRS','Meeruse','Meeruse','37'),('EE','MUG','Muuga','Muuga','37'),('EE','NAI','Naissaare','Naissaare','37'),('EE','NAR','Narva','Narva','44'),('EE','NAS','Nasva','Nasva','74'),('EE','OTP','Otepaa','Otepaa','82'),('EE','PAI','Paide','Paide','51'),('EE','PAS','Paljassaare','Paljassaare','37'),('EE','PIR','Pirita','Pirita','37'),('EE','PLA','Paldiski','Paldiski','37'),('EE','PLN','Paldiski Pohjasadam','Paldiski Pohjasadam','37'),('EE','PLS','Paldiski Lounasadam','Paldiski Lounasadam','37'),('EE','POV','Polva','Polva','65'),('EE','PRN','Parnu','Parnu','67'),('EE','PVE','Palivere','Palivere','57'),('EE','RAA','Raasiku','Raasiku','37'),('EE','RAK','Rakvere','Rakvere','59'),('EE','RGU','Rongu','Rongu','78'),('EE','RHK','Rohukula','Rohukula','57'),('EE','RID','Ridala','Ridala','57'),('EE','RMS','Roomassaare','Roomassaare','74'),('EE','RON','Rohuneeme','Rohuneeme','37'),('EE','RPA','Rapina','Rapina','65'),('EE','SAL','Salme','Salme','74'),('EE','SAU','Saue','Saue','37'),('EE','SIN','Sindi','Sindi','67'),('EE','SKU','Saku','Saku','37'),('EE','SLM','Sillamae','Sillamae','44'),('EE','SRU','Soru','Soru','39'),('EE','SVI','Sviby','Sviby','57'),('EE','TAP','Tapa','Tapa','59'),('EE','TAY','Tartu','Tartu','78'),('EE','TDV','Todva','Todva','37'),('EE','TGI','Triigi','Triigi','74'),('EE','TLL','Tallinn','Tallinn','37'),('EE','TUR','Turi','Turi','51'),('EE','URE','Kuressaare','Kuressaare','74'),('EE','VAI','Vaida','Vaida','37'),('EE','VAN','Vanasadam','Vanasadam','37'),('EE','VBA','Varbola','Varbola','70'),('EE','VDA','Vandra','Vandra','67'),('EE','VEB','Vene-Balti','Vene-Balti','37'),('EE','VEE','Veere','Veere','74'),('EE','VII','Viimsi','Viimsi','37'),('EE','VIL','Viljandi','Viljandi','84'),('EE','VIR','Virtsu','Virtsu','57'),('EE','VLG','Valga','Valga','82'),('EE','VOU','Vooru','Vooru','84'),('EE','VRU','Voru','Voru','86'),('EE','VVS','Virtsu Vanasadam','Virtsu Vanasadam','57'),('EG','','','',''),('EG','AAC','El\'Arish','El\'Arish',''),('EG','ABS','Abu Simbel','Abu Simbel',''),('EG','ADA','Adabiya','Adabiya',''),('EG','AGN','Abu Ghosoun','Abu Ghosoun',''),('EG','AIS','Ain Sukhna','Ain Sukhna',''),('EG','AKI','Abu Kir','Abu Kir',''),('EG','ALM','Al Mansurah','Al Mansurah',''),('EG','ALY','El Iskandariya (= Alexandria)','El Iskandariya (= Alexandria)',''),('EG','AQU','Al Qusayr','Al Qusayr',''),('EG','ASW','Aswan','Aswan',''),('EG','AUE','Abu Rudeis','Abu Rudeis',''),('EG','AZA','Abu Zenimah','Abu Zenimah',''),('EG','CAI','El Qahira (= Cairo)','El Qahira (= Cairo)',''),('EG','DAM','Damietta','Damietta',''),('EG','DMN','Damanhour','Damanhour',''),('EG','EDK','El Dekheila','El Dekheila',''),('EG','FAD','Fa\'id','Fa\'id',''),('EG','FAN','Fanara','Fanara',''),('EG','GEI','Geisum Terminal','Geisum Terminal',''),('EG','HAL','Halaib','Halaib',''),('EG','HAM','Hamrawein','Hamrawein',''),('EG','HBE','Burj al Arab','Burj al Arab',''),('EG','HRG','Hurghada','Hurghada',''),('EG','IKU','Idku','Idku',''),('EG','ISM','Ismailia','Ismailia',''),('EG','LXR','Luxor','Luxor',''),('EG','MAH','Mersa El Hamra','Mersa El Hamra',''),('EG','NUW','Nuwaiba','Nuwaiba',''),('EG','PIB','Port Ibrahim','Port Ibrahim',''),('EG','PRA','Port Rashid','Port Rashid',''),('EG','PSD','Port Said','Port Said',''),('EG','PTK','Port Tewfik','Port Tewfik',''),('EG','RAG','Ras Gharib','Ras Gharib',''),('EG','RSH','Ras Shukheir','Ras Shukheir',''),('EG','SAD','Sadat City','Sadat City',''),('EG','SAL','Sallum','Sallum',''),('EG','SBA','Sidi Barrani','Sidi Barrani',''),('EG','SGA','Safaga','Safaga',''),('EG','SKT','Sidi Kerir Terminal','Sidi Kerir Terminal',''),('EG','SOC','6th October','6th October',''),('EG','SOK','Sokhna Port','Sokhna Port',''),('EG','SOS','Sosdi/6th October','Sosdi/6th October',''),('EG','SSH','Sharm ash Shaykh','Sharm ash Shaykh',''),('EG','SUZ','El Suweis (= Suez)','El Suweis (= Suez)',''),('EG','TAN','Tanta','Tanta',''),('EG','TRC','10th of Ramadan City','10th of Ramadan City',''),('EG','UVL','New Valley','New Valley',''),('EG','WAF','Wadi Feiran','Wadi Feiran',''),('EH','','','',''),('EH','EAI','Ejbei Uad el Aabd','Ejbei Uad el Aabd',''),('EH','VIC','Ad Dakhla','Ad Dakhla',''),('ER','','','',''),('ER','ASA','Assab','Assab',''),('ER','ASM','Asmara','Asmara',''),('ER','MSW','Massawa (Mitsiwa)','Massawa (Mitsiwa)',''),('ES','','','',''),('ES','AAA','Albiztur','Albiztur',''),('ES','AAF','Atarfe','Atarfe',''),('ES','AAG','Agua Amarga','Agua Amarga',''),('ES','AAH','Alhama de Granada','Alhama de Granada',''),('ES','AAJ','Aranjuez','Aranjuez',''),('ES','AAN','Alagon','Alagon',''),('ES','AAO','Arona','Arona',''),('ES','AAR','Aiguafreda','Aiguafreda',''),('ES','ABA','Abadiano-Zelaieta','Abadiano-Zelaieta',''),('ES','ABE','Abrera','Abrera',''),('ES','ABL','Abalos','Abalos',''),('ES','ABO','Arrabaldo','Arrabaldo',''),('ES','ABR','Abronigal','Abronigal',''),('ES','ABZ','Alcobendas','Alcobendas',''),('ES','ACA','Alcanar','Alcanar',''),('ES','ACB','Albolote','Albolote',''),('ES','ACC','Alcorcon','Alcorcon',''),('ES','ACE','Arrecife de Lanzarote','Arrecife de Lanzarote',''),('ES','ACL','Alcala de Henares','Alcala de Henares',''),('ES','ACM','Aguilar de Campoo','Aguilar de Campoo',''),('ES','ACN','Aracena','Aracena',''),('ES','ACO','Agoncillo','Agoncillo',''),('ES','ACP','Aldeanueva Del Campo','Aldeanueva Del Campo',''),('ES','ACR','Alcora','Alcora',''),('ES','ACS','Arbucias','Arbucias',''),('ES','ACU','L\' Alcudia de Crespins','L\' Alcudia de Crespins',''),('ES','ACW','Alcudia de Carlet','Alcudia de Carlet',''),('ES','ACY','Albarracin','Albarracin',''),('ES','ACZ','Alcaniz','Alcaniz',''),('ES','ADA','Aldea','Aldea',''),('ES','ADC','L\'Alcudia de Crespins','L\'Alcudia de Crespins',''),('ES','ADD','Aranda de Duero','Aranda de Duero',''),('ES','ADE','Alhama de Aragon','Alhama de Aragon',''),('ES','ADF','Aguilar de la Frontera','Aguilar de la Frontera',''),('ES','ADJ','Arrabal de Jesus','Arrabal de Jesus',''),('ES','ADL','Aldea de los rios','Aldea de los rios',''),('ES','ADM','Alcocer de Mola (Dupl.ADP)','Alcocer de Mola (Dupl.ADP)',''),('ES','ADP','Alcocer de Planes','Alcocer de Planes',''),('ES','ADR','Adra','Adra',''),('ES','ADU','Aduna','Aduna',''),('ES','ADY','Aldaya','Aldaya',''),('ES','ADZ','Almaden','Almaden',''),('ES','AEB','Abaran','Abaran',''),('ES','AEF','Aldea del Fresno','Aldea del Fresno',''),('ES','AEI','Albalat de la Ribera','Albalat de la Ribera',''),('ES','AEJ','Adeje','Adeje',''),('ES','AEO','Almonte','Almonte',''),('ES','AEQ','Almunecar','Almunecar',''),('ES','AEV','Almodovar del Rio','Almodovar del Rio',''),('ES','AFA','Alfara','Alfara',''),('ES','AFE','Almusafes','Almusafes',''),('ES','AFF','Alfacar','Alfacar',''),('ES','AFJ','Alfarras','Alfarras',''),('ES','AFN','Alarcon','Alarcon',''),('ES','AFO','Alfaro','Alfaro',''),('ES','AFP','Alfara del Patriarca','Alfara del Patriarca',''),('ES','AFR','Arcos de la Frontera','Arcos de la Frontera',''),('ES','AFU','Alfahuir','Alfahuir',''),('ES','AGA','Agaete','Agaete',''),('ES','AGC','Argoncillo','Argoncillo',''),('ES','AGD','La Guardia','La Guardia',''),('ES','AGF','Algimia de Alfara','Algimia de Alfara',''),('ES','AGH','Alginet','Alginet',''),('ES','AGI','Aguinaga','Aguinaga',''),('ES','AGN','Alguena','Alguena',''),('ES','AGO','Agost','Agost',''),('ES','AGP','Malaga','Malaga',''),('ES','AGQ','Algimia de Almonacid','Algimia de Almonacid',''),('ES','AGR','Agramunt','Agramunt',''),('ES','AGS','Aguimes','Aguimes',''),('ES','AGT','Agullent','Agullent',''),('ES','AGU','Aguilas','Aguilas',''),('ES','AGY','Alfondeguilla','Alfondeguilla',''),('ES','AGZ','Alguazas','Alguazas',''),('ES','AHA','Alhama de Almeria','Alhama de Almeria',''),('ES','AHF','Albaida','Albaida',''),('ES','AHH','Alcira','Alcira',''),('ES','AHI','Alhaurin de la Torre','Alhaurin de la Torre',''),('ES','AHJ','Ahin','Ahin',''),('ES','AHP','Alhama','Alhama',''),('ES','AHZ','Archidona','Archidona',''),('ES','AIJ','Algemesi','Algemesi',''),('ES','AIP','Alacuas','Alacuas',''),('ES','AIU','Albudeite','Albudeite',''),('ES','AJA','Abanilla','Abanilla',''),('ES','AJB','Albal','Albal',''),('ES','AJD','Aldeatejada','Aldeatejada',''),('ES','AJE','Albatera','Albatera',''),('ES','AJG','Alhaurin el Grande','Alhaurin el Grande',''),('ES','AJH','Almendralejo','Almendralejo',''),('ES','AJL','Albalat dels Sorells','Albalat dels Sorells',''),('ES','AJN','Alfajarin','Alfajarin',''),('ES','AJQ','Alberique','Alberique',''),('ES','AJR','Andujar','Andujar',''),('ES','AJS','Azuqueca de Henares','Azuqueca de Henares',''),('ES','AJT','Albalat de Segart','Albalat de Segart',''),('ES','AKA','Alcala la Real','Alcala la Real',''),('ES','AKC','Alcaudete','Alcaudete',''),('ES','AKE','Alcolea del Rio','Alcolea del Rio',''),('ES','AKF','Alcoy','Alcoy',''),('ES','AKG','Alcala de Guadaira','Alcala de Guadaira',''),('ES','AKJ','Alcantarilla','Alcantarilla',''),('ES','AKM','Almachar','Almachar',''),('ES','AKQ','Alcolea','Alcolea',''),('ES','AKZ','Alcazar de San Juan','Alcazar de San Juan',''),('ES','ALA','Villarreal de Alava','Villarreal de Alava',''),('ES','ALB','Albacete','Albacete',''),('ES','ALC','Alicante','Alicante',''),('ES','ALD','Alcudia','Alcudia',''),('ES','ALF','Alfafar','Alfafar',''),('ES','ALG','Algeciras','Algeciras',''),('ES','ALJ','Aljucen','Aljucen',''),('ES','ALL','Alcoletge','Alcoletge',''),('ES','ALM','Almagro','Almagro',''),('ES','ALN','Alcanices','Alcanices',''),('ES','ALO','Alora','Alora',''),('ES','ALP','Algar de Palancia','Algar de Palancia',''),('ES','ALQ','Alquerias','Alquerias',''),('ES','ALR','Alboraya','Alboraya',''),('ES','ALS','Aldeaseca','Aldeaseca',''),('ES','ALU','Alguaire','Alguaire',''),('ES','ALV','Alovera','Alovera',''),('ES','ALZ','Almanzora','Almanzora',''),('ES','AMA','Santa Amalia','Santa Amalia',''),('ES','AMD','Arrasate-Mondragon','Arrasate-Mondragon',''),('ES','AMI','Arroyo de la Miel','Arroyo de la Miel',''),('ES','AMN','Almansa','Almansa',''),('ES','AMO','Amorebieta','Amorebieta',''),('ES','AMP','Ampuero','Ampuero',''),('ES','AMR','Alhama de Murcia','Alhama de Murcia',''),('ES','AMU','Amurrio','Amurrio',''),('ES','AMZ','Almazora','Almazora',''),('ES','ANA','Anoeta','Anoeta',''),('ES','ANL','Anleo','Anleo',''),('ES','ANO','Arano','Arano',''),('ES','ANP','Alquerias del nino perdido','Alquerias del nino perdido',''),('ES','ANT','Argentona','Argentona',''),('ES','ANX','Acerinox','Acerinox',''),('ES','ANZ','Antzuola','Antzuola',''),('ES','AOI','Andoain','Andoain',''),('ES','AOL','Autol','Autol',''),('ES','AOQ','Almacera','Almacera',''),('ES','AOT','Alpuente','Alpuente',''),('ES','AOZ','Almaraz','Almaraz',''),('ES','APE','Aspe','Aspe',''),('ES','APM','Almoines','Almoines',''),('ES','APR','A Pobra de Trives','A Pobra de Trives',''),('ES','APT','Azpeitia','Azpeitia',''),('ES','AQA','Altea','Altea',''),('ES','AQC','Albocacer','Albocacer',''),('ES','AQE','Alcacer','Alcacer',''),('ES','AQG','Algete, Spain','Algete, Spain',''),('ES','AQH','Alborache','Alborache',''),('ES','AQI','Alcala de Chivert','Alcala de Chivert',''),('ES','AQR','Antequera','Antequera',''),('ES','AQS','Alacuas','Alacuas',''),('ES','AQU','Alcala del Jucar','Alcala del Jucar',''),('ES','AQZ','Alcaraz','Alcaraz',''),('ES','ARA','Arrigorriaga','Arrigorriaga',''),('ES','ARB','Arbas','Arbas',''),('ES','ARC','Archena','Archena',''),('ES','ARD','Aguarda','Aguarda',''),('ES','ARE','Arre','Arre',''),('ES','ARF','Arafo','Arafo',''),('ES','ARG','Arganda del Rey','Arganda del Rey',''),('ES','ARI','Arguineguin','Arguineguin',''),('ES','ARJ','Arteijo','Arteijo',''),('ES','ARL','Arrubal (La Rioja)','Arrubal (La Rioja)',''),('ES','ARM','Armuna','Armuna',''),('ES','ARN','Arenys de Mar','Arenys de Mar',''),('ES','ARO','Arnedo','Arnedo',''),('ES','ARR','Arrancudiaga','Arrancudiaga',''),('ES','ART','Areta','Areta',''),('ES','ARV','Arevalo','Arevalo',''),('ES','ARY','Araya','Araya',''),('ES','ARZ','Allariz','Allariz',''),('ES','ASL','Andosilla','Andosilla',''),('ES','ASN','Asturianos','Asturianos',''),('ES','AST','Asturias','Asturias',''),('ES','ASU','Alsasua','Alsasua',''),('ES','ATA','Artica','Artica',''),('ES','ATO','El Astillero','El Astillero',''),('ES','ATS','Artes','Artes',''),('ES','AVA','Aiguaviva','Aiguaviva',''),('ES','AVI','Avila','Avila',''),('ES','AVS','Aviles','Aviles',''),('ES','AWI','Asua','Asua',''),('ES','AWN','Almenara','Almenara',''),('ES','AWR','Alcover','Alcover',''),('ES','AWV','Almodovar del Pinar','Almodovar del Pinar',''),('ES','AXC','Albuixech','Albuixech',''),('ES','AXO','A Baiuca','A Baiuca',''),('ES','AXZ','Armuna de Almanzora','Armuna de Almanzora',''),('ES','AYA','Ayamonte','Ayamonte',''),('ES','AYI','Aya','Aya',''),('ES','AYL','Ayelo de Malferit','Ayelo de Malferit',''),('ES','AZA','Azcoitia','Azcoitia',''),('ES','AZB','Aizarnazabal','Aizarnazabal',''),('ES','AZC','Aznalcazar','Aznalcazar',''),('ES','AZG','Azagra','Azagra',''),('ES','AZJ','Alzira','Alzira',''),('ES','AZP','Amposta','Amposta',''),('ES','BAA','Baza','Baza',''),('ES','BAD','Badalona','Badalona',''),('ES','BAI','Bailen','Bailen',''),('ES','BAL','Balaguer','Balaguer',''),('ES','BAN','Baneres','Baneres',''),('ES','BAO','Baracaldo','Baracaldo',''),('ES','BAS','Basauri','Basauri',''),('ES','BAT','La Batlloria','La Batlloria',''),('ES','BAV','Barco De Valdeorras','Barco De Valdeorras',''),('ES','BAZ','Bazalote','Bazalote',''),('ES','BBA','Balboa','Balboa',''),('ES','BCM','Benicasim','Benicasim',''),('ES','BCN','Barcelona','Barcelona',''),('ES','BCO','Barcena de Cicero','Barcena de Cicero',''),('ES','BDC','Bollullos par del Condado','Bollullos par del Condado',''),('ES','BDF','Barbate de Franco','Barbate de Franco',''),('ES','BDG','Benalua de Guadix','Benalua de Guadix',''),('ES','BDI','Bedia','Bedia',''),('ES','BDM','Bollullos de la Mitacion','Bollullos de la Mitacion',''),('ES','BDV','Barbera del Valles','Barbera del Valles',''),('ES','BEA','Berriatua','Berriatua',''),('ES','BEC','Bechi','Bechi',''),('ES','BEI','Beriain','Beriain',''),('ES','BEJ','Beniajan','Beniajan',''),('ES','BEL','Bellvei','Bellvei',''),('ES','BEM','Benidorm','Benidorm',''),('ES','BEN','Beniel','Beniel',''),('ES','BEO','Benisano','Benisano',''),('ES','BER','Berriz','Berriz',''),('ES','BES','Beasain','Beasain',''),('ES','BET','Betera','Betera',''),('ES','BEV','Benavente','Benavente',''),('ES','BFA','Benifayo','Benifayo',''),('ES','BFL','Benifla','Benifla',''),('ES','BGA','Berga','Berga',''),('ES','BGL','Benaguacil','Benaguacil',''),('ES','BGO','Bergondo','Bergondo',''),('ES','BGR','Bergara','Bergara',''),('ES','BGU','Bigues','Bigues',''),('ES','BIG','Bigastro','Bigastro',''),('ES','BIN','Binefar','Binefar',''),('ES','BIO','Bilbao','Bilbao',''),('ES','BIR','Biar','Biar',''),('ES','BJA','Berja','Berja',''),('ES','BJN','Benejama','Benejama',''),('ES','BJS','Barajas','Barajas',''),('ES','BJZ','Badajoz','Badajoz',''),('ES','BLA','Blanes','Blanes',''),('ES','BLB','Blanca Abaran','Blanca Abaran',''),('ES','BLG','Bellreguart','Bellreguart',''),('ES','BLL','Ballobar','Ballobar',''),('ES','BLM','Balmaseda','Balmaseda',''),('ES','BLN','Blanca','Blanca',''),('ES','BLO','Benlloch','Benlloch',''),('ES','BLS','Bellus','Bellus',''),('ES','BLZ','Balazote','Balazote',''),('ES','BMD','Benalmadena','Benalmadena',''),('ES','BMJ','Bormujos','Bormujos',''),('ES','BNA','Benisa','Benisa',''),('ES','BNC','Benacazon','Benacazon',''),('ES','BND','Binaced','Binaced',''),('ES','BNF','Benifairo de la Valldigna','Benifairo de la Valldigna',''),('ES','BNG','Beniganim','Beniganim',''),('ES','BNH','Benahadux','Benahadux',''),('ES','BNI','Benicarlo','Benicarlo',''),('ES','BNJ','Beniarjo','Beniarjo',''),('ES','BNL','Baonoles','Baonoles',''),('ES','BNM','Benimamet','Benimamet',''),('ES','BNP','Beniparrell','Beniparrell',''),('ES','BNS','Bonares','Bonares',''),('ES','BNT','Benetuser','Benetuser',''),('ES','BOI','Bocairente','Bocairente',''),('ES','BOJ','Borja','Borja',''),('ES','BOL','Borriol','Borriol',''),('ES','BOR','Bordon','Bordon',''),('ES','BPU','Bellpuig','Bellpuig',''),('ES','BRA','Barreda','Barreda',''),('ES','BRB','Barbastro','Barbastro',''),('ES','BRE','Brenes','Brenes',''),('ES','BRJ','Burjasot','Burjasot',''),('ES','BRL','Burela','Burela',''),('ES','BRM','Bermeo','Bermeo',''),('ES','BRN','Bornos','Bornos',''),('ES','BRO','Borox','Borox',''),('ES','BRR','Berrioplano','Berrioplano',''),('ES','BRX','Burriana','Burriana',''),('ES','BRY','Balsareny','Balsareny',''),('ES','BSA','Barasoain','Barasoain',''),('ES','BSU','Besalu','Besalu',''),('ES','BTS','Betanzos','Betanzos',''),('ES','BUA','Burlada','Burlada',''),('ES','BUC','Burcena','Burcena',''),('ES','BUE','Bueu','Bueu',''),('ES','BUG','Bugarra','Bugarra',''),('ES','BUL','Bullas','Bullas',''),('ES','BUN','Bunol','Bunol',''),('ES','BUR','Burgos','Burgos',''),('ES','BVA','Becilla de Valderaduey','Becilla de Valderaduey',''),('ES','BYM','Bonrepos I Mirambell','Bonrepos I Mirambell',''),('ES','BZA','Baeza','Baeza',''),('ES','BZB','Pazos de Borben','Pazos de Borben',''),('ES','CAA','Castalla','Castalla',''),('ES','CAB','Cabra','Cabra',''),('ES','CAC','Cabezo Cortado','Cabezo Cortado',''),('ES','CAD','Cadiz','Cadiz',''),('ES','CAE','Camarma de Esteruelas','Camarma de Esteruelas',''),('ES','CAF','Calaf','Calaf',''),('ES','CAG','Cangas','Cangas',''),('ES','CAH','Calamocha','Calamocha',''),('ES','CAI','Castellvi de Rosanes','Castellvi de Rosanes',''),('ES','CAJ','Carballino','Carballino',''),('ES','CAL','Calera de Leon','Calera de Leon',''),('ES','CAM','Camas','Camas',''),('ES','CAN','Canfranc','Canfranc',''),('ES','CAO','Carreno','Carreno',''),('ES','CAP','Calasparra','Calasparra',''),('ES','CAR','Cartagena','Cartagena',''),('ES','CAS','Castellon de la Plana','Castellon de la Plana',''),('ES','CAT','Catadau','Catadau',''),('ES','CAU','Caudete','Caudete',''),('ES','CAV','Castellar del Valles','Castellar del Valles',''),('ES','CAZ','Cazalegas','Cazalegas',''),('ES','CBA','Carballo','Carballo',''),('ES','CBB','Castilbisbal','Castilbisbal',''),('ES','CBD','Cambados','Cambados',''),('ES','CBL','Cambrils','Cambrils',''),('ES','CBM','Cabrera de Mar','Cabrera de Mar',''),('ES','CBO','Carballo','Carballo',''),('ES','CBS','Cala Sabina','Cala Sabina',''),('ES','CBT','Cabezo de Torres','Cabezo de Torres',''),('ES','CBZ','Cabezuela','Cabezuela',''),('ES','CCA','Carrascosa del Campo','Carrascosa del Campo',''),('ES','CCC','Casaseca de Las Chanas','Casaseca de Las Chanas',''),('ES','CCH','Casariche','Casariche',''),('ES','CCN','Corcubion','Corcubion',''),('ES','CCO','Carcastillo','Carcastillo',''),('ES','CCS','Caceres','Caceres',''),('ES','CCT','Cascante','Cascante',''),('ES','CCU','Castilleja de la Cuesta','Castilleja de la Cuesta',''),('ES','CDC','Caravaca De La Cruz','Caravaca De La Cruz',''),('ES','CDD','Cardedeu','Cardedeu',''),('ES','CDE','Callosa de Ensarria','Callosa de Ensarria',''),('ES','CDF','Castelldefels','Castelldefels',''),('ES','CDI','Carrizal','Carrizal',''),('ES','CDL','Caudiel','Caudiel',''),('ES','CDM','Caldes de Malavella','Caldes de Malavella',''),('ES','CDN','Cangas de Narcea','Cangas de Narcea',''),('ES','CDO','Cabanillas del Campo','Cabanillas del Campo',''),('ES','CDR','Castellon de Rugat','Castellon de Rugat',''),('ES','CDS','Callosa de Segura','Callosa de Segura',''),('ES','CDV','Casayo de Valdeorras','Casayo de Valdeorras',''),('ES','CEC','Cedillo del Condado','Cedillo del Condado',''),('ES','CEE','Cee','Cee',''),('ES','CEG','Cisterniga','Cisterniga',''),('ES','CEH','Cehegin','Cehegin',''),('ES','CEL','Celeiro','Celeiro',''),('ES','CER','La Calera','La Calera',''),('ES','CET','Ceuti','Ceuti',''),('ES','CEU','Ceuta','Ceuta',''),('ES','CEZ','Cabezon de la Sal','Cabezon de la Sal',''),('ES','CFR','Cofrentes','Cofrentes',''),('ES','CGL','Cantagallo','Cantagallo',''),('ES','CHA','Chapela','Chapela',''),('ES','CHC','Chiprana','Chiprana',''),('ES','CHF','Chiclana de la Frontera','Chiclana de la Frontera',''),('ES','CHI','Chilches','Chilches',''),('ES','CHL','Chulilla','Chulilla',''),('ES','CHN','Chinchon','Chinchon',''),('ES','CHP','Chipiona','Chipiona',''),('ES','CHS','Cheste','Cheste',''),('ES','CHT','Chantada','Chantada',''),('ES','CHU','Chauchina','Chauchina',''),('ES','CHV','Chirivel','Chirivel',''),('ES','CIC','Cinco Casas','Cinco Casas',''),('ES','CIL','Carril','Carril',''),('ES','CIR','Ciudad Real','Ciudad Real',''),('ES','CJQ','Corcoya','Corcoya',''),('ES','CJS','Crevillente','Crevillente',''),('ES','CLC','Carrion de los Cespedes','Carrion de los Cespedes',''),('ES','CLF','Caudete de las Fuentes','Caudete de las Fuentes',''),('ES','CLG','Caleruega','Caleruega',''),('ES','CLH','Calahorra','Calahorra',''),('ES','CLL','Castellbisbal','Castellbisbal',''),('ES','CLM','Casas del Monte','Casas del Monte',''),('ES','CLO','Cudillero','Cudillero',''),('ES','CLP','Calpe','Calpe',''),('ES','CLR','Celra','Celra',''),('ES','CLS','Camarles','Camarles',''),('ES','CLT','Canete de las Torres','Canete de las Torres',''),('ES','CLV','Churriana de la Vega','Churriana de la Vega',''),('ES','CLZ','Cornella','Cornella',''),('ES','CMA','Castellv De La Marca (Dupl.)','Castellv De La Marca (Dupl.)',''),('ES','CMB','Caldas de Montbuy','Caldas de Montbuy',''),('ES','CMN','Camarenilla','Camarenilla',''),('ES','CMO','Canamero','Canamero',''),('ES','CMP','Campdevanol','Campdevanol',''),('ES','CMR','Campos del Rio','Campos del Rio',''),('ES','CMS','Campillos','Campillos',''),('ES','CMV','Camprovin','Camprovin',''),('ES','CNA','Candeleda','Candeleda',''),('ES','CND','Canada','Canada',''),('ES','CNI','Cenicero','Cenicero',''),('ES','CNJ','Canjayar','Canjayar',''),('ES','CNL','Caniles','Caniles',''),('ES','CNN','Carinena','Carinena',''),('ES','CNO','Carino','Carino',''),('ES','CNR','Cintruenigo','Cintruenigo',''),('ES','CNS','Canals','Canals',''),('ES','CNT','Canete','Canete',''),('ES','CNU','Casa Nueva','Casa Nueva',''),('ES','CNV','Canovellas','Canovellas',''),('ES','COA','Cocentaina','Cocentaina',''),('ES','COB','Cobena','Cobena',''),('ES','COD','Colindres','Colindres',''),('ES','COL','Colmenar','Colmenar',''),('ES','COM','Comunion','Comunion',''),('ES','CON','Cangas de Onis','Cangas de Onis',''),('ES','COO','Coruno','Coruno',''),('ES','COR','Corella','Corella',''),('ES','COT','Cornella de Llobregat','Cornella de Llobregat',''),('ES','COZ','Cortes','Cortes',''),('ES','CPC','Capcanes','Capcanes',''),('ES','CPL','Campanillas','Campanillas',''),('ES','CPN','Campanas','Campanas',''),('ES','CPO','Caparroso','Caparroso',''),('ES','CRA','Cabanas Raras','Cabanas Raras',''),('ES','CRB','Corbera','Corbera',''),('ES','CRC','Carcagente','Carcagente',''),('ES','CRD','Cerdanyola del Valles','Cerdanyola del Valles',''),('ES','CRL','Carcelen','Carcelen',''),('ES','CRM','Cartama','Cartama',''),('ES','CRN','Carnota','Carnota',''),('ES','CRO','Culleredo','Culleredo',''),('ES','CRR','Carcer','Carcer',''),('ES','CRS','Carboneras','Carboneras',''),('ES','CRT','Carlet','Carlet',''),('ES','CRU','Curillas','Curillas',''),('ES','CRV','Cervera','Cervera',''),('ES','CSA','Casablanca','Casablanca',''),('ES','CSC','Cascante','Cascante',''),('ES','CSD','Caseda','Caseda',''),('ES','CSE','Coreses','Coreses',''),('ES','CSL','Consell','Consell',''),('ES','CSM','Caldes de Montbui','Caldes de Montbui',''),('ES','CSO','Castropol','Castropol',''),('ES','CSP','Caspe','Caspe',''),('ES','CSR','Casares','Casares',''),('ES','CSS','Coeses','Coeses',''),('ES','CST','Casatejada','Casatejada',''),('ES','CSV','Cassa de la Selva','Cassa de la Selva',''),('ES','CSY','Caldas de Reyes','Caldas de Reyes',''),('ES','CTA','Cantoria','Cantoria',''),('ES','CTE','Cartes','Cartes',''),('ES','CTI','Cobatillas','Cobatillas',''),('ES','CTJ','Catarroja','Catarroja',''),('ES','CTN','Constanti','Constanti',''),('ES','CTO','Cestona','Cestona',''),('ES','CTR','Catral','Catral',''),('ES','CTS','Casetas','Casetas',''),('ES','CUA','Churra','Churra',''),('ES','CUD','Cuarte de Huerva','Cuarte de Huerva',''),('ES','CUE','Cuenca','Cuenca',''),('ES','CUL','Cuellar','Cuellar',''),('ES','CUO','Couso','Couso',''),('ES','CUR','Castro-Urdiales','Castro-Urdiales',''),('ES','CVA','Chiva','Chiva',''),('ES','CVE','La Chirivella','La Chirivella',''),('ES','CVL','Canaveral','Canaveral',''),('ES','CXQ','Coslada','Coslada',''),('ES','CYC','Calera y Chozas','Calera y Chozas',''),('ES','CYG','Castellet y Gornal','Castellet y Gornal',''),('ES','CYQ','Coin','Coin',''),('ES','CZA','Cieza','Cieza',''),('ES','CZE','Competa','Competa',''),('ES','CZL','Cazorla','Cazorla',''),('ES','CZQ','Coria','Coria',''),('ES','CZR','Coria del Rio','Coria del Rio',''),('ES','CZS','Constantina','Constantina',''),('ES','DDP','Dolores','Dolores',''),('ES','DEA','Daganzo de Arriba','Daganzo de Arriba',''),('ES','DHM','Dos Hermanas','Dos Hermanas',''),('ES','DIS','Dalias','Dalias',''),('ES','DMA','Daimiel','Daimiel',''),('ES','DMC','Dona Mencia','Dona Mencia',''),('ES','DNA','Denia','Denia',''),('ES','DNB','Don Benito','Don Benito',''),('ES','DOL','Dolar','Dolar',''),('ES','DOY','Domayo','Domayo',''),('ES','DRG','Durango','Durango',''),('ES','DRI','Derio','Derio',''),('ES','DSO','Dicastillo','Dicastillo',''),('ES','DUC','Durcal','Durcal',''),('ES','DUN','Duenas','Duenas',''),('ES','EAF','Elavega','Elavega',''),('ES','EAH','Arahal','Arahal',''),('ES','EAO','El Bonillo','El Bonillo',''),('ES','EAS','San Sebastian','San Sebastian',''),('ES','EBA','El Barco de Avila','El Barco de Avila',''),('ES','EBG','Santa Eugenia de Berga','Santa Eugenia de Berga',''),('ES','EBR','Eibar','Eibar',''),('ES','ECA','El Carpio','El Carpio',''),('ES','ECE','Elche','Elche',''),('ES','ECJ','Ecija','Ecija',''),('ES','ECV','El Cuervo','El Cuervo',''),('ES','ECZ','Escoriaza','Escoriaza',''),('ES','EDE','El Burgo de Ebro','El Burgo de Ebro',''),('ES','EDG','San Esteban de Gormaz','San Esteban de Gormaz',''),('ES','EEJ','El Ejido','El Ejido',''),('ES','EES','El Escorial','El Escorial',''),('ES','EEV','Echevarria','Echevarria',''),('ES','EFQ','El Farque','El Farque',''),('ES','EGD','El Gador','El Gador',''),('ES','EGI','El Gordo','El Gordo',''),('ES','EGL','Garidells','Garidells',''),('ES','EGR','Grove','Grove',''),('ES','EJC','Ejea de los Caballeros','Ejea de los Caballeros',''),('ES','ELB','El Bruc','El Bruc',''),('ES','ELD','Elda','Elda',''),('ES','ELG','Elciego','Elciego',''),('ES','ELI','Elizondo','Elizondo',''),('ES','ELM','Espinosa de Los Monteros','Espinosa de Los Monteros',''),('ES','ELR','El Raal','El Raal',''),('ES','EMJ','El Mojon','El Mojon',''),('ES','EOI','Elgoibar','Elgoibar',''),('ES','EPA','Estepa','Estepa',''),('ES','EPB','El Prat','El Prat',''),('ES','EPC','El Perello','El Perello',''),('ES','EPG','El Puig','El Puig',''),('ES','EPI','Epila','Epila',''),('ES','EPL','El Palo','El Palo',''),('ES','EPM','El Palmar','El Palmar',''),('ES','EPN','Estepona','Estepona',''),('ES','EPV','El Provencio','El Provencio',''),('ES','EQQ','Esquiroz','Esquiroz',''),('ES','ERO','Elorrio','Elorrio',''),('ES','ERS','Ermua','Ermua',''),('ES','ERT','Era-Alta','Era-Alta',''),('ES','ERU','El Goro','El Goro',''),('ES','ESC','Escombreras','Escombreras',''),('ES','ESI','Espartinas','Espartinas',''),('ES','ESL','Estella/Lizarra','Estella/Lizarra',''),('ES','ESN','Escalonilla','Escalonilla',''),('ES','ESO','El Rosario','El Rosario',''),('ES','ESP','Espinardo','Espinardo',''),('ES','ESQ','Esquivias','Esquivias',''),('ES','ESR','El Esparragal','El Esparragal',''),('ES','ESS','Casinos','Casinos',''),('ES','ESU','Espeluy','Espeluy',''),('ES','ESZ','Esplugas de Llobregat','Esplugas de Llobregat',''),('ES','ETR','La Estrada','La Estrada',''),('ES','ETX','San Andres de Echevarria','San Andres de Echevarria',''),('ES','EUG','Santa Eugenia','Santa Eugenia',''),('ES','EUX','Esparraguera','Esparraguera',''),('ES','EVI','El Viso del Alcor','El Viso del Alcor',''),('ES','EZC','Ezcaray','Ezcaray',''),('ES','EZI','Ezkio-Itsaso','Ezkio-Itsaso',''),('ES','FAA','Flassa','Flassa',''),('ES','FAO','Fuente-Alamo de Murcia','Fuente-Alamo de Murcia',''),('ES','FAP','Fraga','Fraga',''),('ES','FAV','Favara','Favara',''),('ES','FBD','Fuenlabrada','Fuenlabrada',''),('ES','FCL','Fuentes Claras','Fuentes Claras',''),('ES','FDJ','Fuente el Saz de Jarama','Fuente el Saz de Jarama',''),('ES','FDM','Fogars De Montclus','Fogars De Montclus',''),('ES','FDR','Fuente de Piedra','Fuente de Piedra',''),('ES','FDT','Faramontanos de Tabara','Faramontanos de Tabara',''),('ES','FGL','Fuengirola','Fuengirola',''),('ES','FGN','Fregenal de la Sierra','Fregenal de la Sierra',''),('ES','FGS','Fogas de Tordera','Fogas de Tordera',''),('ES','FGU','Figueras','Figueras',''),('ES','FIN','Fines','Fines',''),('ES','FJU','Funes','Funes',''),('ES','FLH','Fuente la Higuera','Fuente la Higuera',''),('ES','FNT','Fontanar','Fontanar',''),('ES','FON','Fuentes de Onoro','Fuentes de Onoro',''),('ES','FQV','Les Franqueses del Valles','Les Franqueses del Valles',''),('ES','FRD','Foronda','Foronda',''),('ES','FRI','Font Rubi','Font Rubi',''),('ES','FRO','Ferrol','Ferrol',''),('ES','FRS','Figueruelas','Figueruelas',''),('ES','FUA','Faura','Faura',''),('ES','FUE','Puerto del Rosario-Fuerteventura','Puerto del Rosario-Fuerteventura',''),('ES','FUJ','Fuentiduena de Tajo','Fuentiduena de Tajo',''),('ES','FUM','Fuenmayor','Fuenmayor',''),('ES','FUP','Fuentepelayo','Fuentepelayo',''),('ES','FUS','Fustinana','Fustinana',''),('ES','FYO','Foyos','Foyos',''),('ES','GAJ','Gajano','Gajano',''),('ES','GAN','Gandia','Gandia',''),('ES','GAO','Gador','Gador',''),('ES','GAR','Garrucha','Garrucha',''),('ES','GCJ','Guadiana del Caudillo','Guadiana del Caudillo',''),('ES','GCL','Guadalcanal','Guadalcanal',''),('ES','GCN','Grao de Castellon','Grao de Castellon',''),('ES','GCO','Gordoncillo','Gordoncillo',''),('ES','GDA','Gelida','Gelida',''),('ES','GDO','Guardo','Guardo',''),('ES','GDU','Godelleta','Godelleta',''),('ES','GDX','Guadasuar','Guadasuar',''),('ES','GET','Getaria','Getaria',''),('ES','GEZ','Granollers','Granollers',''),('ES','GGG','Gata de Gorgos','Gata de Gorgos',''),('ES','GIA','Gilena','Gilena',''),('ES','GIJ','Gijon','Gijon',''),('ES','GIN','Gines','Gines',''),('ES','GIR','Gironella','Gironella',''),('ES','GJI','Granja de San Idelfonso','Granja de San Idelfonso',''),('ES','GJV','Gava','Gava',''),('ES','GLD','Galdacano','Galdacano',''),('ES','GLP','Galapagar','Galapagar',''),('ES','GLT','Gallarta','Gallarta',''),('ES','GMN','Mogente','Mogente',''),('ES','GNL','Gornal','Gornal',''),('ES','GRA','Granen','Granen',''),('ES','GRB','Gurb','Gurb',''),('ES','GRI','Grinon','Grinon',''),('ES','GRL','Sant Salvador de Guardiola','Sant Salvador de Guardiola',''),('ES','GRN','Guarroman','Guarroman',''),('ES','GRO','Gerona (Girona)','Gerona (Girona)',''),('ES','GRX','Granada','Granada',''),('ES','GRY','Grao','Grao',''),('ES','GSA','Guissona','Guissona',''),('ES','GSY','Gustey','Gustey',''),('ES','GTA','Guantarajal','Guantarajal',''),('ES','GTF','Getafe','Getafe',''),('ES','GTI','Getaria','Getaria',''),('ES','GTP','Gratallops','Gratallops',''),('ES','GTS','Getares','Getares',''),('ES','GUA','Guadalajara','Guadalajara',''),('ES','GUE','Guernica y Luno','Guernica y Luno',''),('ES','GUI','Guipuzcoa','Guipuzcoa',''),('ES','GUN','Guarnizo','Guarnizo',''),('ES','GUR','Guadarrama','Guadarrama',''),('ES','GUX','Guadix','Guadix',''),('ES','GUZ','Guillena','Guillena',''),('ES','HAD','Huercal de Almeria','Huercal de Almeria',''),('ES','HAR','Haro','Haro',''),('ES','HCU','Hospitalet de Llobregat','Hospitalet de Llobregat',''),('ES','HDO','Hospital De Orbigo','Hospital De Orbigo',''),('ES','HDU','La Herradura','La Herradura',''),('ES','HEL','Hellin','Hellin',''),('ES','HER','Herencia','Herencia',''),('ES','HEV','Hueva','Hueva',''),('ES','HHR','Herrera','Herrera',''),('ES','HIE','Hierro','Hierro',''),('ES','HJO','Hinojos','Hinojos',''),('ES','HJS','Horcajo de Santiago','Horcajo de Santiago',''),('ES','HKX','Hernani','Hernani',''),('ES','HMS','Humanes de Madrid','Humanes de Madrid',''),('ES','HNR','Honrubia','Honrubia',''),('ES','HON','Hontoria','Hontoria',''),('ES','HQT','Herrera de Alcantara','Herrera de Alcantara',''),('ES','HRT','Huarte','Huarte',''),('ES','HTT','Huetor-Tajar','Huetor-Tajar',''),('ES','HUC','Huesca','Huesca',''),('ES','HUT','Huarte (Pamplona)','Huarte (Pamplona)',''),('ES','HUV','Huelva','Huelva',''),('ES','HVR','Huevar','Huevar',''),('ES','HWC','Huecija','Huecija',''),('ES','HWG','Huerto','Huerto',''),('ES','HWV','Huerto-Vega','Huerto-Vega',''),('ES','HZS','Hoyos','Hoyos',''),('ES','IBI','Ibi','Ibi',''),('ES','IBR','Ibros','Ibros',''),('ES','IBU','Ibiricu','Ibiricu',''),('ES','IBZ','Ibiza','Ibiza',''),('ES','IEG','Ibiricu-de-Egues','Ibiricu-de-Egues',''),('ES','IGE','Igea','Igea',''),('ES','IGL','Igualada','Igualada',''),('ES','IGO','Igorre','Igorre',''),('ES','ILL','La Penilla','La Penilla',''),('ES','ILS','Illescas','Illescas',''),('ES','IOA','Igollo de Carmago','Igollo de Carmago',''),('ES','IOO','Llodio','Llodio',''),('ES','IRA','Izurza','Izurza',''),('ES','IRU','Irun','Irun',''),('ES','IRZ','Irurtzun','Irurtzun',''),('ES','IST','Iniesta','Iniesta',''),('ES','IUA','Iurreta','Iurreta',''),('ES','IVU','Ivars d\'Urgell','Ivars d\'Urgell',''),('ES','IZA','Izarra','Izarra',''),('ES','IZL','Idiazabal','Idiazabal',''),('ES','JAC','Jaca','Jaca',''),('ES','JAE','Jaen','Jaen',''),('ES','JAP','Jable, Las Palmas (Dupl. JAE)','Jable, Las Palmas (Dupl. JAE)',''),('ES','JAV','Javea','Javea',''),('ES','JCO','Jaraco','Jaraco',''),('ES','JDC','Jerez de los Caballeros','Jerez de los Caballeros',''),('ES','JDR','Jodar','Jodar',''),('ES','JJO','Jijona','Jijona',''),('ES','JLF','Jimena de la Frontera','Jimena de la Frontera',''),('ES','JLN','Jabali Viejo','Jabali Viejo',''),('ES','JNV','Jabali Nuevo','Jabali Nuevo',''),('ES','JRB','Jorba','Jorba',''),('ES','JRE','Jeresa','Jeresa',''),('ES','JRN','Jarandilla de la Vera','Jarandilla de la Vera',''),('ES','JRZ','Jerez de la Frontera','Jerez de la Frontera',''),('ES','JTV','Jativa','Jativa',''),('ES','JUA','Jedula','Jedula',''),('ES','JUM','Jumilla','Jumilla',''),('ES','JUN','Juneda','Juneda',''),('ES','JZB','Juzbado','Juzbado',''),('ES','JZD','Jaraiz de la Vera','Jaraiz de la Vera',''),('ES','LAC','La Alberca','La Alberca',''),('ES','LAG','Langreo','Langreo',''),('ES','LAL','La Aljorra','La Aljorra',''),('ES','LAM','La Muela','La Muela',''),('ES','LAP','Lapuebla de Labarca','Lapuebla de Labarca',''),('ES','LAQ','La Bisbal','La Bisbal',''),('ES','LAR','Larrondo','Larrondo',''),('ES','LAS','Lasarte','Lasarte',''),('ES','LAV','Lavern','Lavern',''),('ES','LBS','Lobres','Lobres',''),('ES','LBT','La Albatalia','La Albatalia',''),('ES','LCA','La Campana','La Campana',''),('ES','LCD','La Copa','La Copa',''),('ES','LCG','La Coruna','La Coruna',''),('ES','LCH','Lominchar','Lominchar',''),('ES','LCN','La Canada','La Canada',''),('ES','LCR','Los Cristianos','Los Cristianos',''),('ES','LCS','Loeches','Loeches',''),('ES','LDA','Labastida','Labastida',''),('ES','LDO','Laredo','Laredo',''),('ES','LDR','Llosa de Ranes','Llosa de Ranes',''),('ES','LDS','Lodosa','Lodosa',''),('ES','LDT','Llic d\'Amunt (Llica d\'Amunt)','Llic d\'Amunt (Llica d\'Amunt)',''),('ES','LDV','Llinars del Valles','Llinars del Valles',''),('ES','LDY','San Leonardo de Yague','San Leonardo de Yague',''),('ES','LEC','Lecumberri','Lecumberri',''),('ES','LEG','Leganes','Leganes',''),('ES','LEI','Almeria','Almeria',''),('ES','LEJ','Lebrija','Lebrija',''),('ES','LEK','Lekeitio','Lekeitio',''),('ES','LEN','Leon','Leon',''),('ES','LEP','Lepe','Lepe',''),('ES','LER','Lerez','Lerez',''),('ES','LES','La Estaca','La Estaca',''),('ES','LEU','Seo de Urgel','Seo de Urgel',''),('ES','LEX','Les','Les',''),('ES','LEZ','Leioa','Leioa',''),('ES','LGA','Laguardia','Laguardia',''),('ES','LGD','Laguna de Duero','Laguna de Duero',''),('ES','LGO','Lugo','Lugo',''),('ES','LGR','Logrono','Logrono',''),('ES','LGS','Legazpia','Legazpia',''),('ES','LGT','Legorreta','Legorreta',''),('ES','LGU','Legutiano','Legutiano',''),('ES','LHP','Llombay','Llombay',''),('ES','LIJ','Librilla','Librilla',''),('ES','LIZ','Linares','Linares',''),('ES','LJA','Loja','Loja',''),('ES','LJC','La Canya','La Canya',''),('ES','LJD','Lerida','Lerida',''),('ES','LJJ','La Garriga','La Garriga',''),('ES','LJM','La Ametlla del Vall','La Ametlla del Vall',''),('ES','LJN','La Eliana','La Eliana',''),('ES','LJO','La Llagosta','La Llagosta',''),('ES','LJQ','Les Presses','Les Presses',''),('ES','LJR','Lanjaron','Lanjaron',''),('ES','LJU','La Junquera','La Junquera',''),('ES','LKB','Lekunberri','Lekunberri',''),('ES','LLA','Lloreda','Lloreda',''),('ES','LLE','Lleida','Lleida',''),('ES','LLG','Llagostera','Llagostera',''),('ES','LLI','La Linea de la Concepcion','La Linea de la Concepcion',''),('ES','LLL','Lugo de Llanera','Lugo de Llanera',''),('ES','LLM','Las Lomas','Las Lomas',''),('ES','LLN','Lalin','Lalin',''),('ES','LLO','Lloret de Mar','Lloret de Mar',''),('ES','LLR','Lliria','Lliria',''),('ES','LLS','Las Labores','Las Labores',''),('ES','LLU','La Luisiana','La Luisiana',''),('ES','LLV','Llica de Vall','Llica de Vall',''),('ES','LMA','Lemona','Lemona',''),('ES','LMC','La Maruca','La Maruca',''),('ES','LNC','La Nucia','La Nucia',''),('ES','LOB','Los Barrios','Los Barrios',''),('ES','LOC','Los Corrales de Buelna','Los Corrales de Buelna',''),('ES','LOI','Loiu','Loiu',''),('ES','LOJ','La Nora','La Nora',''),('ES','LON','Longares','Longares',''),('ES','LOR','L\'Olleria','L\'Olleria',''),('ES','LOY','Los Yebenes','Los Yebenes',''),('ES','LPA','Las Palmas','Las Palmas',''),('ES','LPC','Puebla del Caraminal','Puebla del Caraminal',''),('ES','LPD','Las Pedroneras','Las Pedroneras',''),('ES','LPL','La Palma','La Palma',''),('ES','LPM','La Pobla de Mafumet','La Pobla de Mafumet',''),('ES','LPR','La Pobla de Claramunt','La Pobla de Claramunt',''),('ES','LPV','Los Palacios y Villafranca','Los Palacios y Villafranca',''),('ES','LPZ','La Puebla de Cazalla','La Puebla de Cazalla',''),('ES','LQA','Lorca','Lorca',''),('ES','LQB','Las Cabezas','Las Cabezas',''),('ES','LQL','La Carlota','La Carlota',''),('ES','LQR','La Carolina','La Carolina',''),('ES','LQZ','Los Alcazares','Los Alcazares',''),('ES','LRA','La Rambla','La Rambla',''),('ES','LRB','L\'Arbocet','L\'Arbocet',''),('ES','LRD','La Roda','La Roda',''),('ES','LRJ','La Arboleja','La Arboleja',''),('ES','LRL','Los Rodeos la Laguna','Los Rodeos la Laguna',''),('ES','LRM','La Romana','La Romana',''),('ES','LRO','Las Rozas de Madrid','Las Rozas de Madrid',''),('ES','LRQ','Lorqui','Lorqui',''),('ES','LRR','Lardero','Lardero',''),('ES','LRS','Las Arenas','Las Arenas',''),('ES','LRZ','La Roda De Albacete','La Roda De Albacete',''),('ES','LSF','Les Franquesese','Les Franquesese',''),('ES','LSH','La Roda de Andalucia','La Roda de Andalucia',''),('ES','LSL','La Seu d\'Urgell','La Seu d\'Urgell',''),('ES','LSR','Las Rozas','Las Rozas',''),('ES','LTA','La Tallada','La Tallada',''),('ES','LTD','Las Torres de Cotillas','Las Torres de Cotillas',''),('ES','LUA','Luarca','Luarca',''),('ES','LUG','Lugones','Lugones',''),('ES','LXC','La Palma del Condado','La Palma del Condado',''),('ES','LXE','Lora de Estepa','Lora de Estepa',''),('ES','LXF','La Foya','La Foya',''),('ES','LXO','La Llosa','La Llosa',''),('ES','LXR','La Rinconada','La Rinconada',''),('ES','LXU','Lucena','Lucena',''),('ES','LXZ','La Alberca de Zancara','La Alberca de Zancara',''),('ES','LYJ','Liria','Liria',''),('ES','LYR','Lora del Rio','Lora del Rio',''),('ES','LZA','Lezama','Lezama',''),('ES','LZJ','La Zaida','La Zaida',''),('ES','LZK','Jalon','Jalon',''),('ES','MAD','Madrid','Madrid',''),('ES','MAE','Maestu','Maestu',''),('ES','MAG','Masamagrell','Masamagrell',''),('ES','MAH','Mahon, Menorca','Mahon, Menorca',''),('ES','MAM','Malgrat','Malgrat',''),('ES','MAN','Manacor','Manacor',''),('ES','MAO','Meano','Meano',''),('ES','MAR','Marin','Marin',''),('ES','MAS','Massanassa','Massanassa',''),('ES','MAV','Mallabia','Mallabia',''),('ES','MAY','Moreda','Moreda',''),('ES','MBC','Mollerusa','Mollerusa',''),('ES','MBM','Molla Del Penedes','Molla Del Penedes',''),('ES','MBO','Mondariz-Balneario','Mondariz-Balneario',''),('ES','MCF','Moncofar','Moncofar',''),('ES','MCL','Marcilla','Marcilla',''),('ES','MCM','Muchamiel','Muchamiel',''),('ES','MCP','Mejorada del Campo','Mejorada del Campo',''),('ES','MDA','Moron de Almazan','Moron de Almazan',''),('ES','MDB','Massies de Voltrega','Massies de Voltrega',''),('ES','MDC','Mota del Cuervo','Mota del Cuervo',''),('ES','MDJ','Mondejar','Mondejar',''),('ES','MDP','Motilla del Palancar','Motilla del Palancar',''),('ES','MDR','Medina de Rioseco','Medina de Rioseco',''),('ES','MDX','Molins de Rey','Molins de Rey',''),('ES','MDY','Muro de Alcoy','Muro de Alcoy',''),('ES','MEA','Merida','Merida',''),('ES','MEJ','Mejorada','Mejorada',''),('ES','MEN','Mendavia','Mendavia',''),('ES','MER','Meres','Meres',''),('ES','MES','Montesa','Montesa',''),('ES','MFH','Menjibar','Menjibar',''),('ES','MFK','Macael','Macael',''),('ES','MFQ','Monturque','Monturque',''),('ES','MFS','Martos','Martos',''),('ES','MFT','Monforte del Cid','Monforte del Cid',''),('ES','MGO','Milagro','Milagro',''),('ES','MGT','Montagut','Montagut',''),('ES','MIL','Meliana','Meliana',''),('ES','MIN','Minglanilla','Minglanilla',''),('ES','MIS','Mislata','Mislata',''),('ES','MIX','Miranda de Ebro','Miranda de Ebro',''),('ES','MJC','Mijas','Mijas',''),('ES','MJD','Mojados','Mojados',''),('ES','MJJ','Miajadas','Miajadas',''),('ES','MJP','Malpica','Malpica',''),('ES','MJU','Muelva','Muelva',''),('ES','MJV','Murcia','Murcia',''),('ES','MKZ','Muskiz','Muskiz',''),('ES','MLA','Moratalla','Moratalla',''),('ES','MLC','Medina del Campo','Medina del Campo',''),('ES','MLG','Malagon','Malagon',''),('ES','MLI','Melide','Melide',''),('ES','MLL','Mallorca','Mallorca',''),('ES','MLN','Melilla','Melilla',''),('ES','MLO','Maliano','Maliano',''),('ES','MLP','Malpartida Plasencia','Malpartida Plasencia',''),('ES','MLR','Milagro','Milagro',''),('ES','MLS','Molins','Molins',''),('ES','MLV','Mollet del Valles','Mollet del Valles',''),('ES','MMA','Malgrat de Mar','Malgrat de Mar',''),('ES','MML','Montmell','Montmell',''),('ES','MMS','Mansilla de las Mulas','Mansilla de las Mulas',''),('ES','MNC','Moncada','Moncada',''),('ES','MNJ','Montijo','Montijo',''),('ES','MNL','Manlleu','Manlleu',''),('ES','MNN','Manan','Manan',''),('ES','MNR','Manresa','Manresa',''),('ES','MNU','Monteagudo','Monteagudo',''),('ES','MNY','Monistrol','Monistrol',''),('ES','MNZ','Monzon','Monzon',''),('ES','MOA','Moana','Moana',''),('ES','MOH','Montehermoso','Montehermoso',''),('ES','MOJ','Mojacar','Mojacar',''),('ES','MOL','Molina de Segura','Molina de Segura',''),('ES','MON','Mondragon','Mondragon',''),('ES','MOS','Mos','Mos',''),('ES','MOT','Motril','Motril',''),('ES','MOX','Mos','Mos',''),('ES','MPA','Maspalomas','Maspalomas',''),('ES','MPG','Marin, Pontevedra','Marin, Pontevedra',''),('ES','MQC','Marchena','Marchena',''),('ES','MQE','Marbella','Marbella',''),('ES','MQF','Manilva','Manilva',''),('ES','MQJ','Mairena del Aljarafe','Mairena del Aljarafe',''),('ES','MQN','Mequinenza','Mequinenza',''),('ES','MQP','Montoro','Montoro',''),('ES','MQR','Mairena del Alcor','Mairena del Alcor',''),('ES','MRA','Morayra','Morayra',''),('ES','MRD','Monreal del Campo','Monreal del Campo',''),('ES','MRG','Santa Margarida de Montbui','Santa Margarida de Montbui',''),('ES','MRK','Markina','Markina',''),('ES','MRL','Moraleja','Moraleja',''),('ES','MRM','Montcada I Reixac','Montcada I Reixac',''),('ES','MRR','Marratxi','Marratxi',''),('ES','MRS','Muros','Muros',''),('ES','MRT','Lazkao','Lazkao',''),('ES','MSM','Mostoles-Madrid','Mostoles-Madrid',''),('ES','MSN','Masnou','Masnou',''),('ES','MSS','Massalfassar','Massalfassar',''),('ES','MST','Mostoles','Mostoles',''),('ES','MSY','Manises','Manises',''),('ES','MTB','Mutilva Baja','Mutilva Baja',''),('ES','MTC','Montblanc','Montblanc',''),('ES','MTG','Montgat','Montgat',''),('ES','MTM','Montmelo','Montmelo',''),('ES','MTO','Mataro','Mataro',''),('ES','MTQ','Montesquiu','Montesquiu',''),('ES','MTS','Martorell','Martorell',''),('ES','MTV','Montaverner','Montaverner',''),('ES','MUA','Mutilva Alta','Mutilva Alta',''),('ES','MUL','Mula','Mula',''),('ES','MUN','Munguia','Munguia',''),('ES','MUO','Museros','Museros',''),('ES','MUS','Musel-Arnao','Musel-Arnao',''),('ES','MVA','Monovar','Monovar',''),('ES','MVS','Miravalles','Miravalles',''),('ES','MVT','Montilla','Montilla',''),('ES','MWR','Mancha Real','Mancha Real',''),('ES','MWU','Mora la Nueva','Mora la Nueva',''),('ES','MXA','Minaya','Minaya',''),('ES','MXH','Maraleja','Maraleja',''),('ES','MXJ','Mollina','Mollina',''),('ES','MXX','Maraleda','Maraleda',''),('ES','MYC','Massanet de la Selva','Massanet de la Selva',''),('ES','MZF','Moron de la Frontera','Moron de la Frontera',''),('ES','MZG','Moguer','Moguer',''),('ES','MZJ','Manzanilla','Manzanilla',''),('ES','MZO','Mazarron','Mazarron',''),('ES','MZR','Manzanares el Real','Manzanares el Real',''),('ES','MZX','Manzanares','Manzanares',''),('ES','NAJ','Navarrete','Navarrete',''),('ES','NAN','Nanclares de la Oca','Nanclares de la Oca',''),('ES','NAR','Naron','Naron',''),('ES','NAV','Navia','Navia',''),('ES','NDP','Navalvillar de Pela','Navalvillar de Pela',''),('ES','NDS','Numancia de la Sagra','Numancia de la Sagra',''),('ES','NFO','Navalmoral de la Mata','Navalmoral de la Mata',''),('ES','NIE','Niebla','Niebla',''),('ES','NIJ','Nijar','Nijar',''),('ES','NIN','Noain','Noain',''),('ES','NJA','Nerja','Nerja',''),('ES','NMZ','Navalmanzano','Navalmanzano',''),('ES','NON','Nonduermas','Nonduermas',''),('ES','NUL','Nules','Nules',''),('ES','NVA','Novelda','Novelda',''),('ES','NVC','Navalcarnero','Navalcarnero',''),('ES','NVR','Navarres','Navarres',''),('ES','NVT','Navarrete','Navarrete',''),('ES','NVV','Navarra','Navarra',''),('ES','OAR','Murieta','Murieta',''),('ES','OAZ','Orena','Orena',''),('ES','OCA','Ocana','Ocana',''),('ES','ODA','St Miguel de Olerdola','St Miguel de Olerdola',''),('ES','ODB','Cordoba','Cordoba',''),('ES','ODE','Odena','Odena',''),('ES','ODR','Otero de Rey','Otero de Rey',''),('ES','OEJ','Ordenes','Ordenes',''),('ES','OGA','Ontigola','Ontigola',''),('ES','OGY','Ondara','Ondara',''),('ES','OHL','Orihuela','Orihuela',''),('ES','OIT','Olite','Olite',''),('ES','OLA','Olaberria','Olaberria',''),('ES','OLC','Olmedilla del Campo','Olmedilla del Campo',''),('ES','OLE','Olerdola','Olerdola',''),('ES','OLM','Olmedo','Olmedo',''),('ES','OLR','Olleria','Olleria',''),('ES','OLS','Olesa de Bonesvalls','Olesa de Bonesvalls',''),('ES','OLV','Oliva','Oliva',''),('ES','OLX','Olesa de Montserrat','Olesa de Montserrat',''),('ES','OLZ','Olazagutia','Olazagutia',''),('ES','ONA','Onda','Onda',''),('ES','OND','Ondarroa','Ondarroa',''),('ES','ONI','Onate','Onate',''),('ES','ONL','Onil','Onil',''),('ES','ONS','Obanos','Obanos',''),('ES','ONT','Onteniente (Ontinyent)','Onteniente (Ontinyent)',''),('ES','ONZ','Onzonilla','Onzonilla',''),('ES','OOE','Olot','Olot',''),('ES','ORE','Orense','Orense',''),('ES','ORG','Orgaz','Orgaz',''),('ES','ORI','Orio','Orio',''),('ES','ORM','Ormaiztegui','Ormaiztegui',''),('ES','ORO','Ororbia','Ororbia',''),('ES','ORS','Oleiros','Oleiros',''),('ES','ORT','Ortuella','Ortuella',''),('ES','ORY','Orcoyen','Orcoyen',''),('ES','ORZ','Oronoz','Oronoz',''),('ES','OSU','Osuna','Osuna',''),('ES','OTU','Otura','Otura',''),('ES','OVA','Olvega','Olvega',''),('ES','OVF','Oliva de la Frontera','Oliva de la Frontera',''),('ES','OVO','Oviedo','Oviedo',''),('ES','OVS','Olivares','Olivares',''),('ES','OVZ','Olivenza','Olivenza',''),('ES','OXD','Otxandio','Otxandio',''),('ES','OYN','Oyon','Oyon',''),('ES','OZN','Oiartzun (Elizalde)','Oiartzun (Elizalde)',''),('ES','PAA','Peralta','Peralta',''),('ES','PAC','Palencia','Palencia',''),('ES','PAD','Padron','Padron',''),('ES','PAG','Pereiro de Aguiar','Pereiro de Aguiar',''),('ES','PAI','Patino','Patino',''),('ES','PAL','Palamos','Palamos',''),('ES','PAR','Palol de Rebardit','Palol de Rebardit',''),('ES','PAS','Pasajes','Pasajes',''),('ES','PAU','Paracuellos de Jarama','Paracuellos de Jarama',''),('ES','PBB','Pasito Blanco, Canary Is','Pasito Blanco, Canary Is',''),('ES','PBC','Puebla de la Calzada','Puebla de la Calzada',''),('ES','PBM','Penaranda de Bracamonte','Penaranda de Bracamonte',''),('ES','PBN','Pueblo Nuevo Del Guadian','Pueblo Nuevo Del Guadian',''),('ES','PBO','Port-Bou','Port-Bou',''),('ES','PCO','Puerto Colom','Puerto Colom',''),('ES','PCS','Puentecesures','Puentecesures',''),('ES','PDA','Puebla de Alfinden','Puebla de Alfinden',''),('ES','PDD','Premia de Dalt','Premia de Dalt',''),('ES','PDF','Puebla de Farnals','Puebla de Farnals',''),('ES','PDL','Prat de Llobregat','Prat de Llobregat',''),('ES','PDP','Pedrosa de Duero','Pedrosa de Duero',''),('ES','PDQ','Palma Del Condado','Palma Del Condado',''),('ES','PDR','Pradena del Rincon','Pradena del Rincon',''),('ES','PDS','Puerto de Sagunto','Puerto de Sagunto',''),('ES','PDT','Portillo de Toledo','Portillo de Toledo',''),('ES','PDU','Paradas','Paradas',''),('ES','PDV','Parets Del Valles','Parets Del Valles',''),('ES','PDZ','Pedraneras','Pedraneras',''),('ES','PEF','Pedrera','Pedrera',''),('ES','PEM','Pedro Munoz','Pedro Munoz',''),('ES','PEV','Pontevedra','Pontevedra',''),('ES','PFA','Perafita','Perafita',''),('ES','PFL','Palafrugell','Palafrugell',''),('ES','PFO','Palma Del Rio','Palma Del Rio',''),('ES','PFS','Palomares Del Rio','Palomares Del Rio',''),('ES','PFT','Palos de la Frontera','Palos de la Frontera',''),('ES','PGG','Puga','Puga',''),('ES','PGJ','Pego','Pego',''),('ES','PGN','Puente-Genil','Puente-Genil',''),('ES','PGQ','Palau De Plegamans','Palau De Plegamans',''),('ES','PGR','Organya','Organya',''),('ES','PGZ','Peligros','Peligros',''),('ES','PIA','Pinoso','Pinoso',''),('ES','PIN','Pinarejos','Pinarejos',''),('ES','PIQ','Pilas','Pilas',''),('ES','PJO','Pinto','Pinto',''),('ES','PLH','Pedreguer','Pedreguer',''),('ES','PLL','Portilla','Portilla',''),('ES','PLM','Palomar','Palomar',''),('ES','PLU','Palau de Anglesola','Palau de Anglesola',''),('ES','PLY','Polinya','Polinya',''),('ES','PLZ','Palleja','Palleja',''),('ES','PMI','Palma de Mallorca','Palma de Mallorca',''),('ES','PMN','Palmones','Palmones',''),('ES','PNA','Pamplona','Pamplona',''),('ES','PNR','Penarrolla','Penarrolla',''),('ES','PNT','Playa Honda','Playa Honda',''),('ES','PNX','Portals Nous','Portals Nous',''),('ES','POA','Porullena','Porullena',''),('ES','POL','Puerto Lumbreras','Puerto Lumbreras',''),('ES','PON','Ponferrada','Ponferrada',''),('ES','POR','Portugalete','Portugalete',''),('ES','POS','Ponts','Ponts',''),('ES','POV','Potries','Potries',''),('ES','PPQ','Pacs Del Penedes','Pacs Del Penedes',''),('ES','PQI','Picana','Picana',''),('ES','PQZ','Picasent','Picasent',''),('ES','PRA','Praves','Praves',''),('ES','PRC','Porcuna','Porcuna',''),('ES','PRG','Puig-reig','Puig-reig',''),('ES','PRL','Parla','Parla',''),('ES','PRR','Porrino','Porrino',''),('ES','PSC','Plasencia','Plasencia',''),('ES','PSM','Puerto de Santa Maria','Puerto de Santa Maria',''),('ES','PSO','Pola de Siero','Pola de Siero',''),('ES','PSQ','Pesquera','Pesquera',''),('ES','PSR','Pola de Siero','Pola de Siero',''),('ES','PTO','Puente Tocinos','Puente Tocinos',''),('ES','PTR','Ponteareas','Ponteareas',''),('ES','PTS','Pontejos','Pontejos',''),('ES','PUD','Puebla De Tornesa','Puebla De Tornesa',''),('ES','PUI','Puigcerda','Puigcerda',''),('ES','PUL','Pulianas','Pulianas',''),('ES','PUO','Puertollano','Puertollano',''),('ES','PUS','Puerto Real','Puerto Real',''),('ES','PUW','Paracuellos','Paracuellos',''),('ES','PUZ','Puerto De Mazarron','Puerto De Mazarron',''),('ES','PVB','Puebla de Vallbona','Puebla de Vallbona',''),('ES','PWE','Puebla de Mula','Puebla de Mula',''),('ES','PXA','Paterna','Paterna',''),('ES','PXP','Paiporta','Paiporta',''),('ES','PXR','Petrel','Petrel',''),('ES','PYO','Porceyo','Porceyo',''),('ES','PZA','Pozuelo de Alarcon','Pozuelo de Alarcon',''),('ES','PZB','Pozoblanco','Pozoblanco',''),('ES','PZU','Puzol','Puzol',''),('ES','PZX','Palafolls','Palafolls',''),('ES','QDR','Quintanar del Rey','Quintanar del Rey',''),('ES','QDS','Quintana de la Serena','Quintana de la Serena',''),('ES','QFU','Corralejo','Corralejo',''),('ES','QIU','Ciudadela','Ciudadela',''),('ES','QLY','Playa Blanca','Playa Blanca',''),('ES','QTN','Quintanar de la Orden','Quintanar de la Orden',''),('ES','QUO','Quero','Quero',''),('ES','QUR','Quart De Poblet','Quart De Poblet',''),('ES','RAB','Rafelbunol','Rafelbunol',''),('ES','RAL','Sarral','Sarral',''),('ES','RAN','Cangas','Cangas',''),('ES','RAO','Ribarroja','Ribarroja',''),('ES','RAS','Rascafria','Rascafria',''),('ES','RBA','Rabade','Rabade',''),('ES','RBI','Ribeira (Santa Uxia)','Ribeira (Santa Uxia)',''),('ES','RBS','Ribadesella','Ribadesella',''),('ES','RCV','Rincon De La Victoria','Rincon De La Victoria',''),('ES','RDG','Real de Gandia','Real de Gandia',''),('ES','RDO','Rodeiro','Rodeiro',''),('ES','RDS','Riudarenas','Riudarenas',''),('ES','RDU','Ribadumia','Ribadumia',''),('ES','RED','Redondela','Redondela',''),('ES','REF','Redovan','Redovan',''),('ES','REN','Renedo','Renedo',''),('ES','RFA','Ribaforada','Ribaforada',''),('ES','RFL','Rafal','Rafal',''),('ES','RFT','Rosal de la Frontera','Rosal de la Frontera',''),('ES','RGU','Ragol','Ragol',''),('ES','RIA','Rianjo','Rianjo',''),('ES','RIB','Ribadeo','Ribadeo',''),('ES','RIU','Rubi','Rubi',''),('ES','RJA','Ribas de Jarama','Ribas de Jarama',''),('ES','RLS','Riudellots de la Selva','Riudellots de la Selva',''),('ES','RMN','Ramoneda','Ramoneda',''),('ES','RNA','Ronda','Ronda',''),('ES','RNS','Reinosa','Reinosa',''),('ES','ROA','Roales','Roales',''),('ES','ROB','La Robla','La Robla',''),('ES','ROL','Rosal','Rosal',''),('ES','ROS','Rosas','Rosas',''),('ES','ROT','Rota','Rota',''),('ES','RPL','Ripoll','Ripoll',''),('ES','RPP','Ripollet','Ripollet',''),('ES','RQA','Requena','Requena',''),('ES','RQD','Requijada','Requijada',''),('ES','RQM','Roquetas de Mar','Roquetas de Mar',''),('ES','RSB','Ribesalbes','Ribesalbes',''),('ES','RSO','Rosello','Rosello',''),('ES','RTA','Renteria','Renteria',''),('ES','RUE','Rueda','Rueda',''),('ES','RUS','Reus','Reus',''),('ES','RVM','Rivas-Vaciamadrid','Rivas-Vaciamadrid',''),('ES','RXI','Riudoms','Riudoms',''),('ES','SAA','San Antonio','San Antonio',''),('ES','SAB','San Adrian de Besos','San Adrian de Besos',''),('ES','SAD','Sada','Sada',''),('ES','SAG','Sagunto','Sagunto',''),('ES','SAL','Salteras','Salteras',''),('ES','SAM','Santa Marta','Santa Marta',''),('ES','SAN','San Adrian','San Adrian',''),('ES','SAP','San Pedro Pescador','San Pedro Pescador',''),('ES','SAR','San Roman','San Roman',''),('ES','SAS','San Asensio','San Asensio',''),('ES','SAT','Salinetas','Salinetas',''),('ES','SAX','Sax','Sax',''),('ES','SBA','Sanlucar De Barrameda','Sanlucar De Barrameda',''),('ES','SBG','San Bartolome D/Grau','San Bartolome D/Grau',''),('ES','SBL','Sant Boi de Ilobregat','Sant Boi de Ilobregat',''),('ES','SBP','Sabadell','Sabadell',''),('ES','SBS','Sorbas','Sorbas',''),('ES','SBU','Saldana de Burgos','Saldana de Burgos',''),('ES','SCB','Santa Cruz de Bezana','Santa Cruz de Bezana',''),('ES','SCF','Santa Coloma de Farners','Santa Coloma de Farners',''),('ES','SCI','San Ciprian','San Ciprian',''),('ES','SCL','San Clemente','San Clemente',''),('ES','SCM','Santa Cruz de Mudela','Santa Cruz de Mudela',''),('ES','SCQ','Santiago de Compostela','Santiago de Compostela',''),('ES','SCR','San Carlos de la Rapita','San Carlos de la Rapita',''),('ES','SCT','Santa Cruz de Tenerife','Santa Cruz de Tenerife',''),('ES','SCU','San Cugat De Valles','San Cugat De Valles',''),('ES','SCV','San Ciprian de Vinas','San Ciprian de Vinas',''),('ES','SDA','Saldana','Saldana',''),('ES','SDB','San Andreas De La Barca','San Andreas De La Barca',''),('ES','SDC','Sondika','Sondika',''),('ES','SDE','Sodupe','Sodupe',''),('ES','SDM','San Juan de Mozarrifar','San Juan de Mozarrifar',''),('ES','SDR','Santander','Santander',''),('ES','SDV','Sedavi','Sedavi',''),('ES','SDX','San Agustin del Pozo','San Agustin del Pozo',''),('ES','SEA','Serina','Serina',''),('ES','SEB','Sant Esteve de la Sarga','Sant Esteve de la Sarga',''),('ES','SEE','Sesena Nuevo','Sesena Nuevo',''),('ES','SEG','Segovia','Segovia',''),('ES','SEO','San Esteban de Pravia','San Esteban de Pravia',''),('ES','SES','San Esteve De Sesrovires','San Esteve De Sesrovires',''),('ES','SFA','Fogars de la Selva','Fogars de la Selva',''),('ES','SFB','San Felices de Buelna','San Felices de Buelna',''),('ES','SFC','San Feliu De Codinas','San Feliu De Codinas',''),('ES','SFG','San Fulgencio','San Fulgencio',''),('ES','SFH','San Fernando (de Henares)','San Fernando (de Henares)',''),('ES','SFL','Sant Feliu de Llobregat','Sant Feliu de Llobregat',''),('ES','SFO','San Fernando','San Fernando',''),('ES','SFR','Sant Fruitos de Bages','Sant Fruitos de Bages',''),('ES','SFU','San Feliu De Guixols','San Feliu De Guixols',''),('ES','SGF','Sant Guim de Freixenet','Sant Guim de Freixenet',''),('ES','SGG','Sant Gregori','Sant Gregori',''),('ES','SGJ','Santa Margarita Monjos','Santa Margarita Monjos',''),('ES','SGP','Sant Guim de la Plana','Sant Guim de la Plana',''),('ES','SGR','Segorbe','Segorbe',''),('ES','SGS','San Gines de la Jara','San Gines de la Jara',''),('ES','SIG','Siguenza','Siguenza',''),('ES','SIL','Silla','Silla',''),('ES','SJA','San Juan de Aznalfarache','San Juan de Aznalfarache',''),('ES','SJB','San Juan de las Abadesas','San Juan de las Abadesas',''),('ES','SJD','San Juan Despi (Dupl. SJN)','San Juan Despi (Dupl. SJN)',''),('ES','SJF','San Juan Le Fonts','San Juan Le Fonts',''),('ES','SJJ','Sabinanigo','Sabinanigo',''),('ES','SJM','San Juan D Moro','San Juan D Moro',''),('ES','SJN','San Juan De Nivea','San Juan De Nivea',''),('ES','SJO','Sant Joan Despi','Sant Joan Despi',''),('ES','SJP','San Juan del Puerto','San Juan del Puerto',''),('ES','SJQ','San Justo Desvern','San Justo Desvern',''),('ES','SJR','San Javier','San Javier',''),('ES','SJT','Sant Josep de sa Talaia','Sant Josep de sa Talaia',''),('ES','SLA','Salobrena','Salobrena',''),('ES','SLM','Salamanca','Salamanca',''),('ES','SLO','Salou','Salou',''),('ES','SLT','Salt','Salt',''),('ES','SMA','Soto de la Marina','Soto de la Marina',''),('ES','SMB','San Miguel de Abona','San Miguel de Abona',''),('ES','SMM','Santa Maria de Martorelles','Santa Maria de Martorelles',''),('ES','SMS','San Martin Sarroca','San Martin Sarroca',''),('ES','SMT','San Martin Del Teso','San Martin Del Teso',''),('ES','SMV','San Martin de Valdeiglesias','San Martin de Valdeiglesias',''),('ES','SMZ','Somozas','Somozas',''),('ES','SNA','La Salineta','La Salineta',''),('ES','SNB','San Esteban De Bas','San Esteban De Bas',''),('ES','SND','Santa Andreu de la b','Santa Andreu de la b',''),('ES','SNE','San Esteban','San Esteban',''),('ES','SNL','San Lorenzo de El Escoria','San Lorenzo de El Escoria',''),('ES','SNO','Sanchonuno','Sanchonuno',''),('ES','SNR','Santurce','Santurce',''),('ES','SOA','Santa Oliva','Santa Oliva',''),('ES','SOC','Socuellamos','Socuellamos',''),('ES','SOD','Sobradiel','Sobradiel',''),('ES','SON','Soneja','Soneja',''),('ES','SOR','Soria','Soria',''),('ES','SPA','San Pedro De Alcantara','San Pedro De Alcantara',''),('ES','SPB','Santa Perpetua de Bogota','Santa Perpetua de Bogota',''),('ES','SPC','Santa Cruz de La Palma','Santa Cruz de La Palma',''),('ES','SPD','San Pedro De Premia','San Pedro De Premia',''),('ES','SPL','Espina','Espina',''),('ES','SPM','Santa Perpetua de Moguda','Santa Perpetua de Moguda',''),('ES','SPN','Santiponce','Santiponce',''),('ES','SPO','Santa Pola','Santa Pola',''),('ES','SPP','San Pedro del Pinatar','San Pedro del Pinatar',''),('ES','SPR','San Pedro Riudevitlles','San Pedro Riudevitlles',''),('ES','SQA','Sueca','Sueca',''),('ES','SQU','San Quirico Del Vall','San Quirico Del Vall',''),('ES','SRA','Serrada','Serrada',''),('ES','SRE','Soto del Real','Soto del Real',''),('ES','SRO','Siero','Siero',''),('ES','SRQ','San Roque','San Roque',''),('ES','SRS','Solares','Solares',''),('ES','SRZ','Sarria De Ter','Sarria De Ter',''),('ES','SSA','Sant Sadurni d\'Anoia','Sant Sadurni d\'Anoia',''),('ES','SSC','Sonseca','Sonseca',''),('ES','SSG','San Sebastian de la Gomera','San Sebastian de la Gomera',''),('ES','SSN','Solsona','Solsona',''),('ES','SSR','San Sebastian D/L Reyes','San Sebastian D/L Reyes',''),('ES','SST','Sestao/Bilbao','Sestao/Bilbao',''),('ES','SSV','San Salvador','San Salvador',''),('ES','SSY','San Sadurni D Noya','San Sadurni D Noya',''),('ES','STA','Sant Andreu','Sant Andreu',''),('ES','STE','Santa Eulalia del Rio','Santa Eulalia del Rio',''),('ES','STF','Sant Feliu','Sant Feliu',''),('ES','STG','Sotogrande','Sotogrande',''),('ES','STM','Santa Margarita','Santa Margarita',''),('ES','STP','Santomera','Santomera',''),('ES','STV','San Salvador de Cantamuda','San Salvador de Cantamuda',''),('ES','STX','Santiuste de San Juan Bautista','Santiuste de San Juan Bautista',''),('ES','STY','San Cipriano de Vallalta','San Cipriano de Vallalta',''),('ES','SUD','Sudanell','Sudanell',''),('ES','SUS','Sanguesa','Sanguesa',''),('ES','SVA','San Vicente De Alcantara','San Vicente De Alcantara',''),('ES','SVB','San Vicente de la Barquera','San Vicente de la Barquera',''),('ES','SVH','San Vicente dels Horts','San Vicente dels Horts',''),('ES','SVQ','Sevilla','Sevilla',''),('ES','SVR','San Vicente del Raspeig','San Vicente del Raspeig',''),('ES','SVS','San Vicente de la Sonsierra','San Vicente de la Sonsierra',''),('ES','SVT','Sant Vicenc de Torello','Sant Vicenc de Torello',''),('ES','SXH','San Hilario Sacalm','San Hilario Sacalm',''),('ES','SXS','San Esteban Sasroviras','San Esteban Sasroviras',''),('ES','SXV','San Vicente de Castellet','San Vicente de Castellet',''),('ES','SYG','Sierra de Yeguas','Sierra de Yeguas',''),('ES','SZO','Soses','Soses',''),('ES','TAB','Tabernes de Valldigna','Tabernes de Valldigna',''),('ES','TAF','Tafalla','Tafalla',''),('ES','TAQ','Tarancon','Tarancon',''),('ES','TAR','Tarragona','Tarragona',''),('ES','TAS','Tabernas','Tabernas',''),('ES','TAY','Calatayud','Calatayud',''),('ES','TAZ','Tazacorte','Tazacorte',''),('ES','TBC','Torreblanca','Torreblanca',''),('ES','TCI','Tenerife','Tenerife',''),('ES','TCS','Torrecaballeros','Torrecaballeros',''),('ES','TDD','Tudela de Duero','Tudela de Duero',''),('ES','TDF','Torrellas de Foix','Torrellas de Foix',''),('ES','TDK','Torre del Campo','Torre del Campo',''),('ES','TDM','Torre del Mar','Torre del Mar',''),('ES','TEJ','Taradell','Taradell',''),('ES','TEL','Telde','Telde',''),('ES','TER','Teruel','Teruel',''),('ES','TFA','Torrefarrera','Torrefarrera',''),('ES','TGW','Torreaguera','Torreaguera',''),('ES','TGY','Tarrega','Tarrega',''),('ES','TIE','Tierga','Tierga',''),('ES','TIO','Torello','Torello',''),('ES','TJI','La Tejita','La Tejita',''),('ES','TJM','Torredonjimeno','Torredonjimeno',''),('ES','TJR','Torrejon El Rubio','Torrejon El Rubio',''),('ES','TJS','Tejares','Tejares',''),('ES','TLA','Torres de la Alameda','Torres de la Alameda',''),('ES','TLI','Talavera de la Reina','Talavera de la Reina',''),('ES','TLS','Torremolinos','Torremolinos',''),('ES','TLV','Talavera la Real','Talavera la Real',''),('ES','TMA','Tomares','Tomares',''),('ES','TMD','Tamarite de Litera','Tamarite de Litera',''),('ES','TME','Tomelloso','Tomelloso',''),('ES','TOA','Tolosa','Tolosa',''),('ES','TOF','Torrente de Cinca','Torrente de Cinca',''),('ES','TOG','Tora de Riubregos','Tora de Riubregos',''),('ES','TOL','Toledo','Toledo',''),('ES','TON','Tona','Tona',''),('ES','TOO','Torroella de Montgri','Torroella de Montgri',''),('ES','TOR','Torrevieja','Torrevieja',''),('ES','TOT','Tortosa','Tortosa',''),('ES','TOV','Torrelavid','Torrelavid',''),('ES','TPQ','Torrepacheco','Torrepacheco',''),('ES','TQB','Tabernes Blanques','Tabernes Blanques',''),('ES','TQE','Terrassa','Terrassa',''),('ES','TRA','Trapaga','Trapaga',''),('ES','TRE','Trebujena','Trebujena',''),('ES','TRF','Tarifa','Tarifa',''),('ES','TRJ','Torrejon De Ardoz','Torrejon De Ardoz',''),('ES','TRL','Torrellano','Torrellano',''),('ES','TRR','Torredembarra','Torredembarra',''),('ES','TRU','Trubia','Trubia',''),('ES','TSS','Turis','Turis',''),('ES','TSX','Tarrasa','Tarrasa',''),('ES','TTA','Totana','Totana',''),('ES','TTO','Treto','Treto',''),('ES','TUD','Tudela','Tudela',''),('ES','TUY','Tuy','Tuy',''),('ES','TVG','Torrelavega','Torrelavega',''),('ES','TXQ','Tuitar D/Caudillo','Tuitar D/Caudillo',''),('ES','TYZ','Talayuela','Talayuela',''),('ES','TZA','Tarazona de la Mancha','Tarazona de la Mancha',''),('ES','UBD','Ubeda','Ubeda',''),('ES','UBQ','Ubrique','Ubrique',''),('ES','ULL','Ullastrell','Ullastrell',''),('ES','UMB','Umbrete','Umbrete',''),('ES','URZ','Urroz','Urroz',''),('ES','USU','Usurbil','Usurbil',''),('ES','UTA','Utrera','Utrera',''),('ES','UTE','Utebo','Utebo',''),('ES','UTO','Montornes Del Valles','Montornes Del Valles',''),('ES','UTS','Utrillas','Utrillas',''),('ES','VAA','Viana','Viana',''),('ES','VAB','Vall d\'Alba','Vall d\'Alba',''),('ES','VAD','La Vall d\'Uxo','La Vall d\'Uxo',''),('ES','VAH','Valdehornillos','Valdehornillos',''),('ES','VAK','Visos Del Alcor','Visos Del Alcor',''),('ES','VAL','Valga','Valga',''),('ES','VAO','Valdemoro','Valdemoro',''),('ES','VAP','Valdepenas','Valdepenas',''),('ES','VAR','Valderubio','Valderubio',''),('ES','VAS','Valles','Valles',''),('ES','VAV','Villava','Villava',''),('ES','VBA','Venta de Banos','Venta de Banos',''),('ES','VBG','Vallfogona de Balaguer','Vallfogona de Balaguer',''),('ES','VBN','Villabona','Villabona',''),('ES','VBX','Vilablareix','Vilablareix',''),('ES','VCA','Vallclara','Vallclara',''),('ES','VCC','Vallcarca','Vallcarca',''),('ES','VCD','Viladecavalls','Viladecavalls',''),('ES','VCH','Vilches','Vilches',''),('ES','VCL','Valcarlos','Valcarlos',''),('ES','VCM','Villalon de Campos','Villalon de Campos',''),('ES','VCN','Viladecans','Viladecans',''),('ES','VCO','Villacarrillo','Villacarrillo',''),('ES','VCP','Valencia de la Concepcion','Valencia de la Concepcion',''),('ES','VCR','Villaricos','Villaricos',''),('ES','VCS','Vila de Cruces','Vila de Cruces',''),('ES','VDA','Valencia de Alcantara','Valencia de Alcantara',''),('ES','VDB','Bera/Vera de Bidasoa','Bera/Vera de Bidasoa',''),('ES','VDC','Vilar del Caudillo','Vilar del Caudillo',''),('ES','VDD','Valbuena de Duero','Valbuena de Duero',''),('ES','VDE','Vilovi','Vilovi',''),('ES','VDF','Valverde del Fresno','Valverde del Fresno',''),('ES','VDG','Villanueva de Gallego','Villanueva de Gallego',''),('ES','VDH','Valverde (Isla del Hierro)','Valverde (Isla del Hierro)',''),('ES','VDL','Villares de la Reina','Villares de la Reina',''),('ES','VDM','Valverde del Majano','Valverde del Majano',''),('ES','VDO','Villamuriel de Cerrato','Villamuriel de Cerrato',''),('ES','VDQ','Vara De Quart','Vara De Quart',''),('ES','VDR','Villanueva Del Rio','Villanueva Del Rio',''),('ES','VDS','Villarejo de Salva','Villarejo de Salva',''),('ES','VDT','Valle de Trapaga','Valle de Trapaga',''),('ES','VDU','Vall De Uxo','Vall De Uxo',''),('ES','VDY','Villar del Rey','Villar del Rey',''),('ES','VEB','Velez de Benaudalla','Velez de Benaudalla',''),('ES','VEC','Valverde del Camino','Valverde del Camino',''),('ES','VEP','Valls','Valls',''),('ES','VER','Verin','Verin',''),('ES','VFA','Villafranca','Villafranca',''),('ES','VFB','Villafranca de los Barros','Villafranca de los Barros',''),('ES','VFD','Vilafranca del Panades','Vilafranca del Panades',''),('ES','VFI','Villafames','Villafames',''),('ES','VFR','Vilafranca del Penedes','Vilafranca del Penedes',''),('ES','VFU','Valdelafuente','Valdelafuente',''),('ES','VGC','Vega De Celin','Vega De Celin',''),('ES','VGL','Vergel','Vergel',''),('ES','VGO','Vigo','Vigo',''),('ES','VGQ','Villafranco Del Guadalqu','Villafranco Del Guadalqu',''),('ES','VGR','Valle Gran Rey','Valle Gran Rey',''),('ES','VGS','Vargas','Vargas',''),('ES','VGU','Villafranco Del Guadiana','Villafranco Del Guadiana',''),('ES','VGZ','Villagonzalo','Villagonzalo',''),('ES','VIA','Viator','Viator',''),('ES','VIB','Villalbilla de Burgos','Villalbilla de Burgos',''),('ES','VIC','Vic','Vic',''),('ES','VIL','Villagarcia (de Arousa)','Villagarcia (de Arousa)',''),('ES','VIM','Villamalea','Villamalea',''),('ES','VIO','Villa del Rio','Villa del Rio',''),('ES','VIQ','Vicar','Vicar',''),('ES','VIT','Vitoria','Vitoria',''),('ES','VIV','Viveiro','Viveiro',''),('ES','VIW','Velilla de San Antonio','Velilla de San Antonio',''),('ES','VJF','Vejer de la Frontera','Vejer de la Frontera',''),('ES','VJY','Villajoyosa','Villajoyosa',''),('ES','VLA','Vallada','Vallada',''),('ES','VLB','Villaralbo','Villaralbo',''),('ES','VLC','Valencia','Valencia',''),('ES','VLD','Vilada','Vilada',''),('ES','VLG','Vilanova i la Geltru','Vilanova i la Geltru',''),('ES','VLI','Villanueva de los Infantes','Villanueva de los Infantes',''),('ES','VLL','Valladolid','Valladolid',''),('ES','VLN','Villalonga','Villalonga',''),('ES','VLO','Villafranca de los Caballeros','Villafranca de los Caballeros',''),('ES','VLQ','Villanueva de la Jara','Villanueva de la Jara',''),('ES','VLS','Vierlas','Vierlas',''),('ES','VMA','Vilamalla','Vilamalla',''),('ES','VMG','Velez-Malaga','Velez-Malaga',''),('ES','VMO','Villar de Moros','Villar de Moros',''),('ES','VNA','Villena','Villena',''),('ES','VNC','Villanueva de Cordoba','Villanueva de Cordoba',''),('ES','VOI','Valdemorillo de la Sierra','Valdemorillo de la Sierra',''),('ES','VOJ','Valmojado','Valmojado',''),('ES','VPS','Villa Presente','Villa Presente',''),('ES','VRF','Villarrobledo','Villarrobledo',''),('ES','VRG','Verges','Verges',''),('ES','VRL','Villareal','Villareal',''),('ES','VRS','Villarrasa','Villarrasa',''),('ES','VRX','Valldoreix','Valldoreix',''),('ES','VSE','Vilaseca','Vilaseca',''),('ES','VSV','Villarejo de Salvanes','Villarejo de Salvanes',''),('ES','VTC','Villanueva del Trabuco','Villanueva del Trabuco',''),('ES','VTN','Valentin','Valentin',''),('ES','VVA','Villanueva del Aceral','Villanueva del Aceral',''),('ES','VVC','Villanueva de Castellon','Villanueva de Castellon',''),('ES','VVE','Villaverde','Villaverde',''),('ES','VVL','Valverde de Leganes','Valverde de Leganes',''),('ES','VVP','Vilviestre del Pinar','Vilviestre del Pinar',''),('ES','VVS','Villanueva de la Serena','Villanueva de la Serena',''),('ES','VVT','Villanueva de Tapia','Villanueva de Tapia',''),('ES','VVX','Villaviciosa','Villaviciosa',''),('ES','VYR','Villamayor','Villamayor',''),('ES','VZR','Vinaroz','Vinaroz',''),('ES','XAT','Xativa (Xativa)','Xativa (Xativa)',''),('ES','XDL','Xinzo de Limia Santa Marian','Xinzo de Limia Santa Marian',''),('ES','XIR','Xirivella','Xirivella',''),('ES','YEC','Yecla','Yecla',''),('ES','YUN','Yuncos','Yuncos',''),('ES','YUR','Yurre','Yurre',''),('ES','ZAF','Zafra','Zafra',''),('ES','ZAH','Zahinos','Zahinos',''),('ES','ZAM','Zamudio','Zamudio',''),('ES','ZAR','Zaratamo','Zaratamo',''),('ES','ZAU','Zarautz','Zarautz',''),('ES','ZAZ','Zaragoza','Zaragoza',''),('ES','ZBA','Zierbena','Zierbena',''),('ES','ZDA','Zaldibar','Zaldibar',''),('ES','ZDG','Zarza de Granadilla','Zarza de Granadilla',''),('ES','ZFR','Zona Franca de Cadiz','Zona Franca de Cadiz',''),('ES','ZIZ','Zizurquil','Zizurquil',''),('ES','ZLG','Zubillaga','Zubillaga',''),('ES','ZLM','San Lucar La Mayor','San Lucar La Mayor',''),('ES','ZMR','Zamora','Zamora',''),('ES','ZMY','Zumaya','Zumaya',''),('ES','ZOI','Torrijos','Torrijos',''),('ES','ZRR','Zumarraga','Zumarraga',''),('ES','ZRT','Zaratan','Zaratan',''),('ES','ZUB','Zubiri','Zubiri',''),('ES','ZUE','Zuera','Zuera',''),('ES','ZYY','Zafarraya','Zafarraya',''),('ET','','','',''),('ET','ADD','Addis Ababa','Addis Ababa',''),('ET','AMH','Arba Mintch','Arba Mintch',''),('ET','ASO','Asosa','Asosa',''),('ET','AWA','Awassa','Awassa',''),('ET','AXU','Axum','Axum',''),('ET','BCY','Bulchi','Bulchi',''),('ET','BJR','Bahar Dar','Bahar Dar',''),('ET','DBM','Debra Marcos','Debra Marcos',''),('ET','DEM','Dembidollo','Dembidollo',''),('ET','DIR','Dire Dawa','Dire Dawa',''),('ET','DSE','Dessie','Dessie',''),('ET','GDQ','Gondar','Gondar',''),('ET','GMB','Gambela','Gambela',''),('ET','GOB','Goba','Goba',''),('ET','GOR','Gore','Gore',''),('ET','HUE','Humera','Humera',''),('ET','JIM','Jimma','Jimma',''),('ET','LFO','K\'elafo','K\'elafo',''),('ET','MKS','Mekane Selam','Mekane Selam',''),('ET','MQX','Makale','Makale',''),('ET','MTF','Mizan Teferi','Mizan Teferi',''),('ET','MUJ','Mui','Mui',''),('ET','MZX','Mena','Mena',''),('ET','NZR','Nazret','Nazret',''),('ET','OTA','Mot\'a','Mot\'a',''),('ET','SOD','Sodo','Sodo',''),('ET','SXU','Soddu','Soddu',''),('ET','TIE','Tippi','Tippi',''),('ET','WAC','Waca','Waca',''),('FI','','','',''),('FI','AAN','Aanekoski','Aanekoski','LS'),('FI','AJI','Alajarvi','Alajarvi','LS'),('FI','ALV','Alavus','Alavus','LS'),('FI','ANJ','Anjalankoski','Anjalankoski','ES'),('FI','ANT','Antskog','Antskog','ES'),('FI','ATI','Ahtari','Ahtari',''),('FI','AUR','Aura','Aura','LS'),('FI','AVS','Aavasaksa','Aavasaksa','LL'),('FI','BAS','Backsbacka','Backsbacka','LS'),('FI','BJO','Bjorkholmsund','Bjorkholmsund','LS'),('FI','BRA','Brando','Brando','AL'),('FI','BRO','Bromarv','Bromarv','ES'),('FI','DEG','Degerby','Degerby','ES'),('FI','DLS','Dalsbruk (Taalintehdas)','Dalsbruk (Taalintehdas)','LS'),('FI','DRA','Dragsfjard','Dragsfjard','LS'),('FI','ECK','Eckero','Eckero','AL'),('FI','EJO','Euraaminne (Eurajoki)','Euraaminne (Eurajoki)','LS'),('FI','ENF','Enontekio (Enontekis)','Enontekio (Enontekis)','LL'),('FI','ENK','Enonkoski','Enonkoski','IS'),('FI','ENO','Eno','Eno','IS'),('FI','ERV','Ervasto','Ervasto','ES'),('FI','ESP','Esbo (Espoo)','Esbo (Espoo)','ES'),('FI','EUA','Eura','Eura','LS'),('FI','FAR','Farjsund','Farjsund','AL'),('FI','FOG','Foglo','Foglo','AL'),('FI','FOR','Forby','Forby','LS'),('FI','FSF','Forssa','Forssa','ES'),('FI','FSO','Finstrom','Finstrom','AL'),('FI','GAM','Gammelby','Gammelby','ES'),('FI','GDB','Godby','Godby','AL'),('FI','GUL','Gullo/Tammisaari (Ekenas)','Gullo/Tammisaari (Ekenas)','ES'),('FI','HAA','Haapajarvi','Haapajarvi','OL'),('FI','HAK','Hakkola','Hakkola','LS'),('FI','HAL','Halosenniemi (Halonen)','Halosenniemi (Halonen)','LL'),('FI','HAO','Hailuoto','Hailuoto','OL'),('FI','HAU','Haukipudas','Haukipudas','OL'),('FI','HEA','Heinola','Heinola','ES'),('FI','HEL','Helsingfors (Helsinki)','Helsingfors (Helsinki)','ES'),('FI','HHO','Hauho','Hauho','LS'),('FI','HIJ','Hinnerjoki','Hinnerjoki','LS'),('FI','HJI','Hausjarvi','Hausjarvi','ES'),('FI','HKO','Hango (Hanko)','Hango (Hanko)','ES'),('FI','HKY','Hameenkyro','Hameenkyro','LS'),('FI','HLK','Halikko','Halikko','LS'),('FI','HLL','Hallnas','Hallnas','LS'),('FI','HMA','Himankakyla','Himankakyla','LS'),('FI','HMN','Fredrikshamn (Hamina)','Fredrikshamn (Hamina)','ES'),('FI','HMY','Hameenlinna (Tavastehus)','Hameenlinna (Tavastehus)','ES'),('FI','HOL','Hollola','Hollola','ES'),('FI','HOU','Houtskar (Houtskari)','Houtskar (Houtskari)','LS'),('FI','HRJ','Harjavalta','Harjavalta','LS'),('FI','HUM','Humppila','Humppila','ES'),('FI','HUN','Huittinen','Huittinen','LS'),('FI','HVA','Hervanta','Hervanta','LS'),('FI','HYR','Hyryla','Hyryla','ES'),('FI','HYV','Hyvinge (Hyvinkaa)','Hyvinge (Hyvinkaa)','ES'),('FI','IIS','Idensalmi (Iisalmi)','Idensalmi (Iisalmi)','IS'),('FI','IJK','Ilmajoki','Ilmajoki','LS'),('FI','IKA','Ikaalinen','Ikaalinen','LS'),('FI','IKK','Ikkala, Uusimaa','Ikkala, Uusimaa','ES'),('FI','ILO','Ilomantsi','Ilomantsi','LS'),('FI','IMA','Imatra','Imatra','ES'),('FI','INI','Inio','Inio','LS'),('FI','INK','Inga (Inkoo)','Inga (Inkoo)','ES'),('FI','ISN','Isnas','Isnas','ES'),('FI','IVL','Ivalo','Ivalo','LL'),('FI','JMS','Jamsa','Jamsa','LS'),('FI','JOE','Joensuu','Joensuu','IS'),('FI','JOK','Jokioinen','Jokioinen','ES'),('FI','JOU','Joutseno','Joutseno','ES'),('FI','JPA','Jeppo (Jepua)','Jeppo (Jepua)','LS'),('FI','JRV','Jurva','Jurva','LS'),('FI','JSA','Joutsa','Joutsa','LS'),('FI','JSK','Jamsankoski','Jamsankoski','LS'),('FI','JVA','Juva','Juva','IS'),('FI','JVP','Jarvenpaa (Traskanda)','Jarvenpaa (Traskanda)','ES'),('FI','JYV','Jyvaskyla','Jyvaskyla','LS'),('FI','KAA','Kaarina (St Karins)','Kaarina (St Karins)','LS'),('FI','KAI','Karigasniemi','Karigasniemi','LL'),('FI','KAJ','Kajaani (Kajana)','Kajaani (Kajana)','OL'),('FI','KAL','Kalkkiranta (Kalkstrand)','Kalkkiranta (Kalkstrand)','ES'),('FI','KAN','Kantlax (Kaitalahti)','Kantlax (Kaitalahti)','LS'),('FI','KAO','Kuusamo','Kuusamo','OL'),('FI','KAR','Karstula','Karstula','LS'),('FI','KAS','Kaskinen (Kasko)','Kaskinen (Kasko)','LS'),('FI','KAU','Kauhava','Kauhava','LS'),('FI','KBY','Kallby (Kolppi)','Kallby (Kolppi)','LS'),('FI','KEI','Keikya','Keikya','LS'),('FI','KEM','Kemi/Tornea (Kemi/Tornio)','Kemi/Tornea (Kemi/Tornio)','LL'),('FI','KER','Kerava (Kervo)','Kerava (Kervo)','ES'),('FI','KES','Kesalahti','Kesalahti','IS'),('FI','KEU','Keuruu','Keuruu','LS'),('FI','KEV','Kuorevesi','Kuorevesi','LS'),('FI','KHJ','Kauhajoki','Kauhajoki','LS'),('FI','KIH','Kihnio','Kihnio','LS'),('FI','KIL','Kilpisjarvi','Kilpisjarvi','LL'),('FI','KIM','Kemio (Kimito)','Kemio (Kimito)','LS'),('FI','KIN','Grankulla (Kauniainen)','Grankulla (Kauniainen)','ES'),('FI','KIV','Kivilompolo','Kivilompolo','LL'),('FI','KJA','Karis (Karjaa)','Karis (Karjaa)','ES'),('FI','KJI','Kemijarvi','Kemijarvi','LL'),('FI','KJO','Kalajoki','Kalajoki','OL'),('FI','KKI','Kirkkonummi','Kirkkonummi','ES'),('FI','KKO','Kyroskoski','Kyroskoski','LS'),('FI','KKP','Koskenpaa','Koskenpaa','LS'),('FI','KKR','Kokar','Kokar','AL'),('FI','KLA','Klamila','Klamila','ES'),('FI','KLE','Kempele','Kempele','OL'),('FI','KLI','Kolari','Kolari','LL'),('FI','KLO','Kulloo (Kullo)','Kulloo (Kullo)','ES'),('FI','KLT','Kalanti','Kalanti','LS'),('FI','KMI','Kokemaki','Kokemaki','LS'),('FI','KMM','Keminmaa','Keminmaa','LL'),('FI','KNP','Kankaanpaa','Kankaanpaa','LS'),('FI','KNS','Kannus','Kannus','LS'),('FI','KNT','Kantvik','Kantvik','ES'),('FI','KOK','Karleby (Kokkola)','Karleby (Kokkola)','LS'),('FI','KOR','Korpo (Korppoo)','Korpo (Korppoo)','LS'),('FI','KPN','Kaipiainen','Kaipiainen',''),('FI','KRK','Hogfors (Karkkila)','Hogfors (Karkkila)','ES'),('FI','KRO','Kronvik','Kronvik','LS'),('FI','KRS','Kristiinankaupunki (Kristinestad)','Kristiinankaupunki (Kristinestad)','LS'),('FI','KRT','Kuortane','Kuortane','LS'),('FI','KRV','Kaaresuvanto','Kaaresuvanto','LL'),('FI','KSA','Kangasala','Kangasala','LS'),('FI','KSI','Kuusankoski','Kuusankoski','ES'),('FI','KSK','Karsamaki','Karsamaki','OL'),('FI','KSL','Kausala','Kausala','ES'),('FI','KTK','Kotka','Kotka','ES'),('FI','KTQ','Kitee','Kitee','IS'),('FI','KTT','Kittila','Kittila','LL'),('FI','KUH','Kuhmo','Kuhmo','OL'),('FI','KUL','Karhula','Karhula','ES'),('FI','KUM','Kumlinge','Kumlinge','AL'),('FI','KUO','Kuopio','Kuopio','IS'),('FI','KUR','Kuru','Kuru','LS'),('FI','KUS','Gustavs (Kustavi)','Gustavs (Kustavi)','LS'),('FI','KUV','Kauvatsa','Kauvatsa','LS'),('FI','KVH','Koverhaara (Koverhar)','Koverhaara (Koverhar)','ES'),('FI','KVI','Kiuruvesi','Kiuruvesi','IS'),('FI','KVO','Kouvola','Kouvola','ES'),('FI','KYP','Kylanpaa','Kylanpaa','LS'),('FI','LAI','Laitila','Laitila','LS'),('FI','LAM','Lammi','Lammi','ES'),('FI','LAN','Langnas','Langnas','AL'),('FI','LAP','Lappohja (Lappvik)','Lappohja (Lappvik)','ES'),('FI','LAU','Lauhala','Lauhala','LS'),('FI','LEO','Lieto','Lieto','LS'),('FI','LHI','Lahti (Lahtis)','Lahti (Lahtis)','ES'),('FI','LHJ','Lohja (Lojo)','Lohja (Lojo)','ES'),('FI','LHK','Luhtajoki','Luhtajoki','ES'),('FI','LHT','Lehtimaki','Lehtimaki','LS'),('FI','LIK','Lieksa','Lieksa','IS'),('FI','LLJ','Liljendal','Liljendal','ES'),('FI','LLX','Lielax','Lielax','LS'),('FI','LMA','Loimaa','Loimaa','LS'),('FI','LMI','Langelmaki','Langelmaki','LS'),('FI','LON','Littoinen','Littoinen','LS'),('FI','LOV','Loviisa (Lovisa)','Loviisa (Lovisa)','ES'),('FI','LPA','Lapua','Lapua','LS'),('FI','LPI','Lappi','Lappi','LS'),('FI','LPL','Lempaala','Lempaala','LS'),('FI','LPP','Lappeenranta (Villmanstrand)','Lappeenranta (Villmanstrand)','ES'),('FI','LUK','Laukaa','Laukaa','LS'),('FI','LUV','Luvia','Luvia','LS'),('FI','MAA','Maaninka','Maaninka','IS'),('FI','MAN','Mantta','Mantta','LS'),('FI','MAS','Masku','Masku','LS'),('FI','MAX','Maksamaa (Maxmo)','Maksamaa (Maxmo)','LS'),('FI','MBY','Masaby','Masaby','ES'),('FI','MER','Merikarvia (Sastmola)','Merikarvia (Sastmola)','LS'),('FI','MHQ','Maarianhamina (Mariehamn)','Maarianhamina (Mariehamn)','AL'),('FI','MHU','Mantyharju','Mantyharju','IS'),('FI','MIK','Mikkeli (St Michel)','Mikkeli (St Michel)','IS'),('FI','MJL','Muijala','Muijala','ES'),('FI','MJO','Mjosund','Mjosund','LS'),('FI','MKA','Miehikkala','Miehikkala','ES'),('FI','MKI','Marinkainen','Marinkainen','LS'),('FI','MKY','Metsakyla/ Hamina','Metsakyla/ Hamina','ES'),('FI','MLX','Maalahti (Malax)','Maalahti (Malax)','LS'),('FI','MMI','Malmi','Malmi','ES'),('FI','MRE','Muurame','Muurame','LS'),('FI','MRL','Muurla','Muurla','LS'),('FI','MRS','Marsund','Marsund','LS'),('FI','MTL','Mantyluoto','Mantyluoto','LS'),('FI','MUO','Muonio','Muonio','LL'),('FI','MUS','Mustola','Mustola','ES'),('FI','MYL','Myllykoski','Myllykoski','ES'),('FI','NAJ','Naarajarvi (Pieksamaen Maalaiskunta)','Naarajarvi (Pieksamaen Maalaiskunta)','IS'),('FI','NAU','Nagu (Nauvo)','Nagu (Nauvo)','LS'),('FI','NII','Niirala','Niirala','IS'),('FI','NJI','Nurmijarvi','Nurmijarvi','ES'),('FI','NKK','Nakkila','Nakkila','LS'),('FI','NLI','Naantali (Nadendal)','Naantali (Nadendal)','LS'),('FI','NML','Nummela','Nummela','ES'),('FI','NOK','Nokia','Nokia','LS'),('FI','NOU','Nousiainen','Nousiainen','LS'),('FI','NRP','Narpes (Narpio)','Narpes (Narpio)','LS'),('FI','NST','Nastola','Nastola','ES'),('FI','NUI','Nuijamaa','Nuijamaa','ES'),('FI','NUR','Nurmes','Nurmes','IS'),('FI','NUU','Nuutajarvi','Nuutajarvi','LS'),('FI','NVA','Nivala','Nivala','OL'),('FI','NYH','Nyhem','Nyhem','ES'),('FI','ODE','Odenso','Odenso','ES'),('FI','OIP','Oripaa','Oripaa','LS'),('FI','OLA','Oulainen','Oulainen','OL'),('FI','OLU','Oulu','Oulu','OL'),('FI','OMA','Orimattila','Orimattila','ES'),('FI','ORV','Orivesi','Orivesi','LS'),('FI','OTA','Otanmaki','Otanmaki','OL'),('FI','OTI','Oitti','Oitti','ES'),('FI','OUK','Outokumpu','Outokumpu','IS'),('FI','OUL','Uleaborg (Oulu)','Uleaborg (Oulu)','OL'),('FI','PAI','Paimio','Paimio','LS'),('FI','PAO','Parkano','Parkano','LS'),('FI','PAR','Parainen (Pargas)','Parainen (Pargas)','LS'),('FI','PEL','Peltosalmi','Peltosalmi','IS'),('FI','PER','Perna (Pernaja)','Perna (Pernaja)','ES'),('FI','PET','Petolahti','Petolahti','LS'),('FI','PII','Piispanristi','Piispanristi','LS'),('FI','PIK','Pikkala','Pikkala','ES'),('FI','PIR','Birkala (Pirkkala)','Birkala (Pirkkala)','LS'),('FI','PLA','Palokka','Palokka','LS'),('FI','PLL','Pello','Pello','LL'),('FI','PNI','Pateniemi','Pateniemi','LL'),('FI','PNO','Pernio','Pernio','LS'),('FI','POA','Porkkala','Porkkala','ES'),('FI','POH','Pohjankuru (Skuru)','Pohjankuru (Skuru)','ES'),('FI','POR','Bjorneborg (Pori)','Bjorneborg (Pori)','LS'),('FI','PRS','Jacobstad (Pietarsaari)','Jacobstad (Pietarsaari)','LS'),('FI','PRV','Borga (Porvoo)','Borga (Porvoo)','ES'),('FI','PSM','Pieksamaki','Pieksamaki','IS'),('FI','PSP','Piispanristi','Piispanristi','OL'),('FI','PUD','Pudasjarvi','Pudasjarvi','OL'),('FI','PUU','Puumala','Puumala','IS'),('FI','PYH','Pyharanta','Pyharanta','LS'),('FI','PYI','Pyhasalmi','Pyhasalmi','OL'),('FI','RAA','Brahestad (Raahe)','Brahestad (Raahe)','OL'),('FI','RAH','Rahja','Rahja','LS'),('FI','RAJ','Rajajooseppi','Rajajooseppi','LL'),('FI','RAO','Raisio','Raisio','LS'),('FI','RAU','Rauma (Raumo)','Rauma (Raumo)','LS'),('FI','RIA','Riihimaki','Riihimaki','ES'),('FI','RIS','Ristiina','Ristiina','IS'),('FI','RJM','Rajamaki','Rajamaki','ES'),('FI','RLI','Rautalampi','Rautalampi','IS'),('FI','ROO','Ruotila','Ruotila','ES'),('FI','ROU','Rauha','Rauha','IS'),('FI','RTR','Rautaruukki/Raahe','Rautaruukki/Raahe','OL'),('FI','RUI','Ruovesi','Ruovesi','LS'),('FI','RUO','Ruotsinpyhtaa (Stromfors)','Ruotsinpyhtaa (Stromfors)','ES'),('FI','RUU','Ruukki','Ruukki','OL'),('FI','RVN','Rovaniemi','Rovaniemi','LL'),('FI','RYM','Rimito (Rymattyla)','Rimito (Rymattyla)','LS'),('FI','SAI','Saarijarvi','Saarijarvi','LS'),('FI','SAK','Sakyla','Sakyla','LS'),('FI','SAL','Salo','Salo','LS'),('FI','SAN','Sando','Sando','LS'),('FI','SAR','Finby (Sarkisalo)','Finby (Sarkisalo)','LS'),('FI','SBG','Suomenlinna (Sveaborg)','Suomenlinna (Sveaborg)','ES'),('FI','SII','Siilinjarvi','Siilinjarvi','IS'),('FI','SIO','Siuro','Siuro','LS'),('FI','SIP','Sibbo (Sipoo)','Sibbo (Sipoo)','ES'),('FI','SJI','Sammaljoki','Sammaljoki','LS'),('FI','SJY','Seinajoki','Seinajoki','LS'),('FI','SKA','Soderkulla','Soderkulla','ES'),('FI','SKB','Skogby','Skogby','ES'),('FI','SKI','Skinnarvik','Skinnarvik','LS'),('FI','SKV','Kilpilahti (Skoldvik)','Kilpilahti (Skoldvik)','ES'),('FI','SLI','Suolahti','Suolahti','LS'),('FI','SLL','Salla','Salla','LL'),('FI','SMO','Sotkamo','Sotkamo','IS'),('FI','SNA','Snappertuna','Snappertuna','ES'),('FI','SNI','Siuntio','Siuntio','ES'),('FI','SOI','Soini','Soini','LS'),('FI','SOT','Sodankyla','Sodankyla','LL'),('FI','SPE','Savitaipale','Savitaipale','ES'),('FI','SPJ','Kuivasalmi','Kuivasalmi','IS'),('FI','SPK','Salpakangas','Salpakangas','ES'),('FI','SRO','Somero','Somero','ES'),('FI','STA','Seutula','Seutula','ES'),('FI','STR','Stromma','Stromma','LS'),('FI','SUJ','Suonenjoki','Suonenjoki','IS'),('FI','SVL','Nyslott (Savonlinna)','Nyslott (Savonlinna)','IS'),('FI','TAI','Ekenas (Tammisaari)','Ekenas (Tammisaari)','ES'),('FI','TAK','Taivalkoski','Taivalkoski','OL'),('FI','TEI','Teijo','Teijo','LS'),('FI','TER','Teerijarvi (Terjarv)','Teerijarvi (Terjarv)','LS'),('FI','TES','Tessvarr','Tessvarr','ES'),('FI','TIL','Poppola','Poppola','LL'),('FI','TJA','Toijala','Toijala','LS'),('FI','TKR','Tikkurila','Tikkurila','ES'),('FI','TKU','Abo (Turku)','Abo (Turku)','LS'),('FI','TMP','Tammerfors (Tampere)','Tammerfors (Tampere)','LS'),('FI','TOJ','Tojby','Tojby','LS'),('FI','TOK','Tolkis (Tolkkinen)','Tolkis (Tolkkinen)','ES'),('FI','TOR','Tornea (Tornio)','Tornea (Tornio)','LL'),('FI','TRA','Trask','Trask','AL'),('FI','TRI','Turenki','Turenki','ES'),('FI','TRK','Tervakoski','Tervakoski','ES'),('FI','TUP','Tupavuori','Tupavuori','LS'),('FI','TUU','Tuusula','Tuusula','ES'),('FI','TVA','Tvarminne','Tvarminne','ES'),('FI','TVS','Taivassalo (Tovsala)','Taivassalo (Tovsala)','LS'),('FI','UIM','Uimaharju','Uimaharju','IS'),('FI','UKI','Nystad (Uusikaupunki)','Nystad (Uusikaupunki)','LS'),('FI','UKP','Nykarleby (Uusikaarlepyy)','Nykarleby (Uusikaarlepyy)','LS'),('FI','ULV','Ulvila','Ulvila','LS'),('FI','URA','Urjala','Urjala','LS'),('FI','USK','Uskela','Uskela','LS'),('FI','UTS','Utsjoki','Utsjoki','LL'),('FI','UTT','Kauttua','Kauttua','LS'),('FI','UUK','Uukuniemi','Uukuniemi','IS'),('FI','VAA','Vaasa (Vasa)','Vaasa (Vasa)','LS'),('FI','VAI','Vainikkala','Vainikkala','ES'),('FI','VAJ','Vaajakoski','Vaajakoski','LS'),('FI','VAM','Vammala','Vammala','LS'),('FI','VAR','Vartsala','Vartsala','LS'),('FI','VAS','Vastlax','Vastlax','LS'),('FI','VAT','Vanda (Vantaa)','Vanda (Vantaa)','ES'),('FI','VEL','Velkua','Velkua','LS'),('FI','VES','Vesso','Vesso','LL'),('FI','VET','Veteli','Veteli','LS'),('FI','VIR','Varpuniemi (Kello)','Varpuniemi (Kello)','LL'),('FI','VJI','Vuolijoki','Vuolijoki','OL'),('FI','VKK','Valkeakoski','Valkeakoski','LS'),('FI','VKO','Valko (Valkom)','Valko (Valkom)','ES'),('FI','VKT','Vuoksen Terminal','Vuoksen Terminal','ES'),('FI','VKY','Vaaksy','Vaaksy','ES'),('FI','VLA','Vaalimaa','Vaalimaa','ES'),('FI','VLI','Virolahti','Virolahti','ES'),('FI','VNA','Vanhalinna','Vanhalinna','LS'),('FI','VRK','Varkaus','Varkaus','IS'),('FI','VRT','Vartius','Vartius','OL'),('FI','VSI','Viitasaari','Viitasaari','LS'),('FI','VTF','Vastanfjard','Vastanfjard','LS'),('FI','VTO','Vahto','Vahto','LS'),('FI','VTV','Vihtavuori','Vihtavuori','LS'),('FI','VUO','Vuokatti','Vuokatti','OL'),('FI','YJA','Ylojarvi','Ylojarvi','LS'),('FI','YLI','Ylivieska','Ylivieska','OL'),('FI','YMU','Ylimarkku (Overmark)','Ylimarkku (Overmark)','LS'),('FI','YMY','Ylamylly','Ylamylly','IS'),('FJ','','','',''),('FJ','AQS','Saqani','Saqani',''),('FJ','BFJ','Ba','Ba',''),('FJ','BVF','Bua','Bua',''),('FJ','BXL','Blue Lagoon','Blue Lagoon',''),('FJ','CST','Castaway','Castaway',''),('FJ','ELL','Ellington','Ellington',''),('FJ','ICI','Cicia','Cicia',''),('FJ','KAY','Wakaya Island','Wakaya Island',''),('FJ','KDV','Kandavu','Kandavu',''),('FJ','KVU','Korolevu','Korolevu',''),('FJ','KXF','Koro Island','Koro Island',''),('FJ','LBS','Labasa','Labasa',''),('FJ','LEV','Bureta','Bureta',''),('FJ','LKB','Lakeba','Lakeba',''),('FJ','LTK','Lautoka','Lautoka',''),('FJ','LUC','Laucala Is','Laucala Is',''),('FJ','MAL','Malau (Labasa)','Malau (Labasa)',''),('FJ','MFJ','Moala','Moala',''),('FJ','MNF','Mana Island','Mana Island',''),('FJ','MOM','Momi','Momi',''),('FJ','NAM','Nambouwalu','Nambouwalu',''),('FJ','NAN','Nadi','Nadi',''),('FJ','NGI','Ngau Island','Ngau Island',''),('FJ','NTA','Natadola','Natadola',''),('FJ','ONU','Ono-i-Lau','Ono-i-Lau',''),('FJ','PHR','Pacific Harbor','Pacific Harbor',''),('FJ','PTF','Malolo Lailai Island','Malolo Lailai Island',''),('FJ','RBI','Rabi','Rabi',''),('FJ','RTA','Rotuma','Rotuma',''),('FJ','SIN','Singatoka','Singatoka',''),('FJ','SUV','Suva','Suva',''),('FJ','SVU','Savusavu','Savusavu',''),('FJ','TTL','Turtle Island','Turtle Island',''),('FJ','TVU','Taveuni','Taveuni',''),('FJ','VAT','Vatia','Vatia',''),('FJ','VAU','Vatukoula','Vatukoula',''),('FJ','VBV','Vanua Mbalavu','Vanua Mbalavu',''),('FJ','VTF','Vatulele','Vatulele',''),('FJ','VUD','Vuda','Vuda',''),('FJ','YAS','Yasawa Island','Yasawa Island',''),('FK','','','',''),('FK','FBE','Fox Bay','Fox Bay',''),('FK','MPN','Mount Pleasant','Mount Pleasant',''),('FK','PSY','Port Stanley','Port Stanley',''),('FM','','','',''),('FM','FSI','Faisi','Faisi',''),('FM','KSA','Kosrae (ex Kusaie)','Kosrae (ex Kusaie)',''),('FM','PNI','Pohnpei (ex Ponape)','Pohnpei (ex Ponape)',''),('FM','TKK','Chuuk (ex Truk)','Chuuk (ex Truk)',''),('FM','ULI','Ulithi','Ulithi',''),('FM','YAP','Yap','Yap',''),('FO','','','',''),('FO','FAE','Faroo Islands-Vagar Apt','Faroo Islands-Vagar Apt',''),('FO','FUG','Fuglafirdi (Fuglefjord)','Fuglafirdi (Fuglefjord)',''),('FO','HUS','Husevig','Husevig',''),('FO','KOL','Kollafjordur','Kollafjordur',''),('FO','KVI','Klaksvik','Klaksvik',''),('FO','LOP','Lopra','Lopra',''),('FO','NSK','Noryskali','Noryskali',''),('FO','SMJ','Solmundefjord','Solmundefjord',''),('FO','SRV','Sorvagur','Sorvagur',''),('FO','THO','Thorshavn','Thorshavn',''),('FO','TVO','Tvoroyri','Tvoroyri',''),('FO','VAG','Vagur','Vagur',''),('FO','VAZ','Vagur','Vagur',''),('FO','VES','Vestmanhavn','Vestmanhavn',''),('FO','VID','Vadair','Vadair',''),('FR','','','',''),('FR','AAA','Aillant-sur-Tholon','Aillant-sur-Tholon','89'),('FR','AAD','Baladou','Baladou','46'),('FR','AAE','Arques','Arques','11'),('FR','AAG','Amagne','Amagne','08'),('FR','AAL','Avail','Avail','36'),('FR','AAM','Aramits','Aramits','64'),('FR','AAN','Arques','Arques','12'),('FR','AAO','Aramon','Aramon','30'),('FR','AAR','Arrens-Marsous','Arrens-Marsous','65'),('FR','AAS','Allassac','Allassac','19'),('FR','AAT','Attichy','Attichy','60'),('FR','AAU','Anzin-Saint-Aubin','Anzin-Saint-Aubin','62'),('FR','AAV','Amblainville','Amblainville','60'),('FR','AAY','Alizay','Alizay','27'),('FR','AAZ','St-Brisson-sur-Loire','St-Brisson-sur-Loire','45'),('FR','ABB','Abbeville','Abbeville','80'),('FR','ABC','Armbouts-Cappel','Armbouts-Cappel','59'),('FR','ABD','Abidos','Abidos','64'),('FR','ABE','La Beaume','La Beaume','05'),('FR','ABF','Albefeuille-Lagarde','Albefeuille-Lagarde','82'),('FR','ABG','Aubagne','Aubagne','13'),('FR','ABI','Aubiet','Aubiet','32'),('FR','ABL','Ablis','Ablis','78'),('FR','ABM','Alba-la-Romaine','Alba-la-Romaine','07'),('FR','ABN','Alban','Alban','81'),('FR','ABO','Amboise','Amboise','37'),('FR','ABP','Amelie-les-Bains-Palalda','Amelie-les-Bains-Palalda','66'),('FR','ABQ','Albon','Albon','26'),('FR','ABR','Aubigne-Racan','Aubigne-Racan','72'),('FR','ABS','Aubusson','Aubusson','23'),('FR','ABV','Aubreville','Aubreville','55'),('FR','ABY','Amberieu-en-Bugey','Amberieu-en-Bugey','01'),('FR','ABZ','Aubazines','Aubazines','19'),('FR','ACA','Arcay','Arcay','86'),('FR','ACB','Salles-Courbaties','Salles-Courbaties','12'),('FR','ACE','Avesnes-le-Comte','Avesnes-le-Comte','62'),('FR','ACG','Arcangues','Arcangues','64'),('FR','ACH','Acheres','Acheres','78'),('FR','ACI','Achicourt','Achicourt','62'),('FR','ACL','Auchel','Auchel','62'),('FR','ACN','Lacanau','Lacanau','33'),('FR','ACO','Abancourt','Abancourt','60'),('FR','ACP','St-Charles-de-Percy','St-Charles-de-Percy',''),('FR','ACQ','Acquigny','Acquigny','27'),('FR','ACR','Argenton-sur-Creuse','Argenton-sur-Creuse','36'),('FR','ACS','Archamps','Archamps','74'),('FR','ACT','Audincourt','Audincourt','25'),('FR','ACU','Auxi-le-Chateau','Auxi-le-Chateau','62'),('FR','ACV','Ancerville','Ancerville','55'),('FR','ACX','Arches','Arches','15'),('FR','ACZ','Beaucouze','Beaucouze','49'),('FR','ADB','Andernos-les-Bains','Andernos-les-Bains','33'),('FR','ADC','Andance','Andance','07'),('FR','ADD','Ardentes','Ardentes','36'),('FR','ADE','Ande','Ande','27'),('FR','ADF','Alteckendorf','Alteckendorf','67'),('FR','ADI','Landrais','Landrais','17'),('FR','ADL','Agos-Vidalos','Agos-Vidalos','65'),('FR','ADM','Andelot-en-Montagne','Andelot-en-Montagne','39'),('FR','ADN','Arradon','Arradon','56'),('FR','ADO','Audun-le-Roman','Audun-le-Roman','54'),('FR','ADP','Argentre du Plessis','Argentre du Plessis','35'),('FR','ADR','Aire-sur-l\'Adour','Aire-sur-l\'Adour','40'),('FR','ADS','Aubigne','Aubigne','79'),('FR','ADT','Andrest','Andrest','65'),('FR','ADU','Anduze','Anduze','30'),('FR','ADV','Agnieres-en-Devoluy','Agnieres-en-Devoluy','05'),('FR','ADX','Ardoix','Ardoix','07'),('FR','ADY','Cande','Cande','49'),('FR','AEB','St Laurent-des-Bois','St Laurent-des-Bois','41'),('FR','AEC','Amecourt','Amecourt','27'),('FR','AED','Allevard','Allevard','38'),('FR','AEE','Avesnes','Avesnes','62'),('FR','AEG','Aregno','Aregno','2B'),('FR','AEI','Aleria','Aleria','2B'),('FR','AEL','Martel','Martel','46'),('FR','AEM','Allennes-les-Marais','Allennes-les-Marais','59'),('FR','AEN','Avesnelles','Avesnelles','59'),('FR','AEO','Auvers-sur-Oise','Auvers-sur-Oise','95'),('FR','AER','Ars-en-Re','Ars-en-Re','17'),('FR','AES','Lambersart','Lambersart','59'),('FR','AET','Anet','Anet','28'),('FR','AEU','Amaye-sur-Orne','Amaye-sur-Orne','14'),('FR','AEV','Ailleville','Ailleville','10'),('FR','AFA','Auffay','Auffay','76'),('FR','AFM','Aigrefeuille-sur-Maine','Aigrefeuille-sur-Maine','44'),('FR','AFO','Amphion les Bains','Amphion les Bains','74'),('FR','AFS','Laferte-sur-Amance','Laferte-sur-Amance','52'),('FR','AFU','Laifour','Laifour','08'),('FR','AFV','Amfreville-la-Mi-Voie','Amfreville-la-Mi-Voie','76'),('FR','AGA','Aubigny','Aubigny','62'),('FR','AGB','Aignan','Aignan',''),('FR','AGC','Agonac','Agonac','24'),('FR','AGE','Bauge','Bauge','49'),('FR','AGF','Agen','Agen','47'),('FR','AGG','Saugues','Saugues','43'),('FR','AGH','Algolsheim','Algolsheim','68'),('FR','AGI','Sanguinet','Sanguinet','40'),('FR','AGJ','Algajola','Algajola','2B'),('FR','AGL','Aiguillon','Aiguillon','47'),('FR','AGM','Labergement-Sante-Marie','Labergement-Sante-Marie','25'),('FR','AGN','Ayguetinte','Ayguetinte','32'),('FR','AGO','Arengosse','Arengosse','40'),('FR','AGP','Aigueperse','Aigueperse','69'),('FR','AGQ','Sagy','Sagy','71'),('FR','AGR','Aguilcourt','Aguilcourt','02'),('FR','AGT','Anglefort','Anglefort','01'),('FR','AGU','Aguessac','Aguessac','12'),('FR','AGV','Aigues vives','Aigues vives',''),('FR','AGX','Argentan','Argentan','61'),('FR','AGY','Angy','Angy','60'),('FR','AGZ','Argeles-Gazost','Argeles-Gazost','65'),('FR','AHA','Basse-Ham','Basse-Ham','57'),('FR','AHC','La Roche-Chalais','La Roche-Chalais','24'),('FR','AHI','Aubry-du-Hainaut','Aubry-du-Hainaut','59'),('FR','AHL','Athies-sous-Laon','Athies-sous-Laon','02'),('FR','AHM','Saint-Abraham','Saint-Abraham','56'),('FR','AHN','Ahun','Ahun','23'),('FR','AHO','Lahontan','Lahontan','64'),('FR','AHR','La Chatre','La Chatre','36'),('FR','AHS','Araches','Araches','74'),('FR','AHT','Angeac-Charente','Angeac-Charente','16'),('FR','AHU','Auberchicourt','Auberchicourt','59'),('FR','AHY','Machy','Machy','80'),('FR','AHZ','L\'Alpe d\'Huez','L\'Alpe d\'Huez','38'),('FR','AIA','Airan','Airan','14'),('FR','AIB','Aigueblanche','Aigueblanche','73'),('FR','AIC','Aisy-sur-Armancon','Aisy-sur-Armancon','89'),('FR','AIE','Assevillers','Assevillers','80'),('FR','AIG','Aigre','Aigre','16'),('FR','AII','Abitain','Abitain','64'),('FR','AIL','Ailly-sur-Noye','Ailly-sur-Noye','80'),('FR','AIM','Aime','Aime','73'),('FR','AIN','Carvin','Carvin','62'),('FR','AIO','Les Assions','Les Assions','07'),('FR','AIR','Airaines','Airaines','80'),('FR','AIS','Cassis','Cassis','13'),('FR','AIT','Airvault','Airvault','79'),('FR','AIU','Aiglun','Aiglun','06'),('FR','AIV','Aubigne','Aubigne','35'),('FR','AIX','Alixan','Alixan','26'),('FR','AIY','Amilly','Amilly','45'),('FR','AJA','Ajaccio','Ajaccio','2A'),('FR','AJN','Ajain','Ajain','23'),('FR','AKH','Altkirch','Altkirch','68'),('FR','ALA','Altillac','Altillac','19'),('FR','ALB','Albias','Albias','82'),('FR','ALC','Aloxe-Corton','Aloxe-Corton','21'),('FR','ALD','Aignay-le-Duc','Aignay-le-Duc','21'),('FR','ALE','Alencon','Alencon','61'),('FR','ALF','Alfortville','Alfortville','94'),('FR','ALG','Ambares-et-Lagrave','Ambares-et-Lagrave','33'),('FR','ALI','Salies-de-Bearn','Salies-de-Bearn','64'),('FR','ALJ','Almont-les-Junies','Almont-les-Junies','12'),('FR','ALL','Allaines Mervilliers','Allaines Mervilliers','28'),('FR','ALN','Maligny','Maligny','89'),('FR','ALO','Allonnes','Allonnes','72'),('FR','ALP','Althen-des-Paluds','Althen-des-Paluds','84'),('FR','ALQ','Allain','Allain','54'),('FR','ALR','Albert','Albert','80'),('FR','ALS','Ales','Ales','30'),('FR','ALT','Anglet','Anglet','64'),('FR','ALV','St Andre-les-Vergers','St Andre-les-Vergers','10'),('FR','ALX','Allex','Allex','26'),('FR','ALY','Avilly-Saint-Leonard','Avilly-Saint-Leonard','60'),('FR','ALZ','Arc-les-Gray','Arc-les-Gray','70'),('FR','AMA','Saint-Chamas','Saint-Chamas','13'),('FR','AMB','Amberieux','Amberieux','01'),('FR','AMC','Amenoncourt','Amenoncourt','54'),('FR','AMD','Autevielle-Saint-Martin-Bideren','Autevielle-Saint-Martin-Bideren','64'),('FR','AME','Ames','Ames','62'),('FR','AMG','Aimargues','Aimargues','30'),('FR','AMI','Amiens','Amiens','80'),('FR','AML','Aubigne','Aubigne','49'),('FR','AMM','Sammarcolles','Sammarcolles','86'),('FR','AMN','Amneville','Amneville','57'),('FR','AMO','Ambillou','Ambillou','37'),('FR','AMP','Amplepuis','Amplepuis','69'),('FR','AMR','Ambert','Ambert','63'),('FR','AMS','Ambes','Ambes','33'),('FR','AMU','Aumale','Aumale','76'),('FR','AMV','Aucamville','Aucamville','82'),('FR','AMY','Ambilly','Ambilly','74'),('FR','ANA','Anthy-sur-Leman','Anthy-sur-Leman','74'),('FR','ANB','Bain-de-Bretagne','Bain-de-Bretagne','35'),('FR','ANC','Ancenis','Ancenis','44'),('FR','AND','Andelot-Blancheville','Andelot-Blancheville','52'),('FR','ANE','Angers','Angers','49'),('FR','ANG','Angouleme','Angouleme','16'),('FR','ANH','Anche','Anche','86'),('FR','ANI','Aniche','Aniche','59'),('FR','ANL','Anould','Anould','88'),('FR','ANM','Annemasse','Annemasse','74'),('FR','ANN','Aniane','Aniane','34'),('FR','ANO','Langon','Langon','33'),('FR','ANQ','Arbonne','Arbonne','64'),('FR','ANR','Ancerville','Ancerville','57'),('FR','ANS','Albens','Albens','73'),('FR','ANT','Antibes','Antibes','06'),('FR','ANU','La Noue','La Noue','51'),('FR','ANV','Angerville','Angerville','91'),('FR','ANX','Antrain','Antrain','35'),('FR','ANY','Anneyron','Anneyron','26'),('FR','ANZ','Anzin','Anzin','59'),('FR','AOA','Ambronay','Ambronay','01'),('FR','AOC','Amoncourt','Amoncourt','70'),('FR','AOE','Avignonet-de-Lauragais','Avignonet-de-Lauragais','31'),('FR','AOG','St-Martin-Longueau','St-Martin-Longueau','60'),('FR','AOI','Avoise','Avoise','72'),('FR','AOP','Ablaincourt-Pressoir','Ablaincourt-Pressoir','80'),('FR','AOR','Avord','Avord','18'),('FR','AOS','Aoste','Aoste','38'),('FR','AOU','Allouagne','Allouagne','62'),('FR','AOV','Agon-Coutainville','Agon-Coutainville','50'),('FR','AOY','Annonay','Annonay','07'),('FR','APA','Capian','Capian','33'),('FR','APC','Authon-du-Perche','Authon-du-Perche','28'),('FR','APE','Capens','Capens','31'),('FR','APH','Avezac-Prat-Lahitte','Avezac-Prat-Lahitte','65'),('FR','API','Achiet-le-Petit','Achiet-le-Petit','62'),('FR','APL','Champlitte','Champlitte','70'),('FR','APN','Arpajon','Arpajon','91'),('FR','APO','Asasp-Arros','Asasp-Arros','64'),('FR','APP','Appoigny','Appoigny','89'),('FR','APR','Apprieu','Apprieu','38'),('FR','APT','Apt','Apt','84'),('FR','APU','Arnac-Pompadour','Arnac-Pompadour','19'),('FR','APW','Appenwihr','Appenwihr','68'),('FR','AQB','Arques-la-Bataille','Arques-la-Bataille','76'),('FR','AQC','Allenc','Allenc','48'),('FR','AQG','Angres','Angres','62'),('FR','AQS','Asnieres-sur-Seine','Asnieres-sur-Seine','92'),('FR','AQU','Asques','Asques','82'),('FR','ARA','Arnage','Arnage','72'),('FR','ARB','Arbent','Arbent','01'),('FR','ARC','Arcachon','Arcachon','33'),('FR','ARD','Ardres','Ardres','62'),('FR','ARE','Ste Alvere','Ste Alvere','24'),('FR','ARG','Argis','Argis','01'),('FR','ARI','Avrille','Avrille','49'),('FR','ARK','Arlanc','Arlanc','63'),('FR','ARL','Arles','Arles','13'),('FR','ARM','Saint-Armel','Saint-Armel','35'),('FR','ARN','Arnas','Arnas','69'),('FR','ARO','Carbonne','Carbonne','31'),('FR','ARP','Arpajon-sur-Cere','Arpajon-sur-Cere','15'),('FR','ARQ','Arques','Arques','62'),('FR','ARR','Arras','Arras','62'),('FR','ARS','Arbois','Arbois','39'),('FR','ART','Artix','Artix','64'),('FR','ARV','Arches','Arches','88'),('FR','ARY','Argonay','Argonay','74'),('FR','ARZ','Arzens','Arzens','11'),('FR','ASA','Arcis-sur-Aube','Arcis-sur-Aube','10'),('FR','ASB','Aulnay-sous-Bois','Aulnay-sous-Bois','93'),('FR','ASC','Alby-sur-Cheran','Alby-sur-Cheran','74'),('FR','ASE','Ancy-sur-Moselle','Ancy-sur-Moselle','57'),('FR','ASG','Bassing','Bassing','57'),('FR','ASI','Massiac','Massiac','15'),('FR','ASL','Aurec-sur-Loire','Aurec-sur-Loire','43'),('FR','ASN','Aussillon','Aussillon','81'),('FR','ASO','Aunay-sur-Odon','Aunay-sur-Odon','14'),('FR','ASP','Aspiran','Aspiran','34'),('FR','ASR','Asnieres-la-Giraud','Asnieres-la-Giraud','17'),('FR','ASS','Sassierges-Saint-Germain','Sassierges-Saint-Germain','36'),('FR','AST','Astaffort','Astaffort','47'),('FR','ASU','Arc-sur-Tille','Arc-sur-Tille','21'),('FR','ASV','Ansac-sur-Vienne','Ansac-sur-Vienne','16'),('FR','ASY','Bessay-sur-Allier','Bessay-sur-Allier','03'),('FR','ATA','Antignac','Antignac','31'),('FR','ATB','Alet-les-Bains','Alet-les-Bains','11'),('FR','ATC','Antignac','Antignac','15'),('FR','ATD','Argent-sur-Sauldre','Argent-sur-Sauldre','18'),('FR','ATE','Castets','Castets','40'),('FR','ATF','Albestroff','Albestroff','57'),('FR','ATG','Cartigny','Cartigny','80'),('FR','ATI','Anteuil','Anteuil','25'),('FR','ATL','Argenteuil','Argenteuil','95'),('FR','ATM','Athis-Mons','Athis-Mons','91'),('FR','ATN','Atton','Atton','54'),('FR','ATO','Avanton','Avanton','86'),('FR','ATQ','Artres','Artres','59'),('FR','ATS','Artigues-pres-Bourdeaux','Artigues-pres-Bourdeaux','33'),('FR','ATT','Attignat','Attignat','01'),('FR','ATU','Aillevillers-et-Lyaumont','Aillevillers-et-Lyaumont','70'),('FR','ATV','Albertville','Albertville','73'),('FR','ATY','Antony/Paris','Antony/Paris','92'),('FR','ATZ','Maatz','Maatz','52'),('FR','AUA','Aulus-les-Bains','Aulus-les-Bains','09'),('FR','AUB','Aube','Aube',''),('FR','AUC','Auch','Auch','32'),('FR','AUD','Audierne','Audierne','29'),('FR','AUE','Autet','Autet','70'),('FR','AUF','Auxerre','Auxerre','89'),('FR','AUG','Aubergenville','Aubergenville','78'),('FR','AUI','Aubiere','Aubiere','63'),('FR','AUL','Aulnoye','Aulnoye','59'),('FR','AUN','Auneau','Auneau','28'),('FR','AUO','Auron','Auron','06'),('FR','AUP','Aubie-et-Espessas','Aubie-et-Espessas','33'),('FR','AUR','Aurillac','Aurillac','15'),('FR','AUS','Auby','Auby','59'),('FR','AUT','Autun','Autun','71'),('FR','AUU','Auneuil','Auneuil','60'),('FR','AUV','Autreville','Autreville','02'),('FR','AUX','Auxon','Auxon','10'),('FR','AUY','Arudy','Arudy','64'),('FR','AUZ','Auzecourt','Auzecourt','55'),('FR','AVA','Ambrieres-les-Vallees','Ambrieres-les-Vallees','53'),('FR','AVC','Amfreville','Amfreville','14'),('FR','AVD','Avoudrey','Avoudrey','25'),('FR','AVE','Auterive','Auterive',''),('FR','AVF','Avoriaz','Avoriaz','74'),('FR','AVG','Alvignac','Alvignac','46'),('FR','AVI','Avelin','Avelin','59'),('FR','AVL','Avallon','Avallon','89'),('FR','AVM','Amfreville','Amfreville','50'),('FR','AVN','Avignon','Avignon','84'),('FR','AVO','Avion','Avion','62'),('FR','AVR','Avranches','Avranches','50'),('FR','AVS','Aubervilliers','Aubervilliers','93'),('FR','AVT','Aubin-Saint-Vaast','Aubin-Saint-Vaast','62'),('FR','AVX','St-Avit','St-Avit','63'),('FR','AVY','Aubevoye','Aubevoye','27'),('FR','AVZ','Aveze','Aveze','30'),('FR','AXB','Aix-les-Bains','Aix-les-Bains','73'),('FR','AXD','Aix','Aix','59'),('FR','AXN','Avon','Avon','77'),('FR','AXV','Acheux-en-Vimeu','Acheux-en-Vimeu','80'),('FR','AYC','Anizy-le-Chateau','Anizy-le-Chateau','02'),('FR','AYE','Saint-Amand-en-Puisaye','Saint-Amand-en-Puisaye','58'),('FR','AYG','Autrey-les-Gray','Autrey-les-Gray','70'),('FR','AYH','Charnay-les-Chalon','Charnay-les-Chalon','71'),('FR','AYJ','Autruy-sur-Juine','Autruy-sur-Juine','45'),('FR','AYL','Arnay-le-Duc','Arnay-le-Duc','21'),('FR','AYM','Ay-sur-Moselle','Ay-sur-Moselle','57'),('FR','AYN','Aynac','Aynac','46'),('FR','AYT','Aytre','Aytre','17'),('FR','AYU','Aubigny-sur-Nere','Aubigny-sur-Nere','18'),('FR','AYW','Ay','Ay','51'),('FR','AYX','Aulnoye-Aymeries','Aulnoye-Aymeries','59'),('FR','AYY','Andilly-en-Bassigny','Andilly-en-Bassigny','52'),('FR','AYZ','Ayze','Ayze','69'),('FR','AZE','Azerailles','Azerailles','54'),('FR','AZG','Alzing','Alzing','57'),('FR','AZN','Annezin','Annezin','62'),('FR','AZO','Ayzac-Ost','Ayzac-Ost','65'),('FR','AZS','Auzits','Auzits','12'),('FR','AZU','Allaire','Allaire','56'),('FR','AZX','Andrezieux-Boutheon','Andrezieux-Boutheon','42'),('FR','BAA','Bransat','Bransat','03'),('FR','BAB','Bagneres-de-Bigorre','Bagneres-de-Bigorre','65'),('FR','BAC','Baccarat','Baccarat','54'),('FR','BAD','Badinieres','Badinieres','38'),('FR','BAE','Barcelonnette','Barcelonnette','04'),('FR','BAF','Baillet-en-France','Baillet-en-France','95'),('FR','BAG','Bagnolet','Bagnolet','93'),('FR','BAH','Barbezieux-Saint-Hilaire','Barbezieux-Saint-Hilaire','16'),('FR','BAI','Basse-Indre','Basse-Indre','44'),('FR','BAL','Ballancourt-sur-Essonne','Ballancourt-sur-Essonne','91'),('FR','BAM','Bassemberg','Bassemberg','67'),('FR','BAN','Bantzenheim','Bantzenheim','68'),('FR','BAO','Bailleul','Bailleul','61'),('FR','BAP','Bapaume','Bapaume','62'),('FR','BAR','Barr','Barr','67'),('FR','BAS','Bassens','Bassens','33'),('FR','BAT','Batilly','Batilly','54'),('FR','BAU','Boucau','Boucau','64'),('FR','BAV','Bavilliers','Bavilliers','90'),('FR','BAX','Bax','Bax','31'),('FR','BAY','Bayonne','Bayonne','64'),('FR','BAZ','Bazancourt','Bazancourt','60'),('FR','BBA','Bas-en-Basset','Bas-en-Basset','43'),('FR','BBB','Le Roc-St-Andre','Le Roc-St-Andre','56'),('FR','BBC','Bolbec','Bolbec','76'),('FR','BBE','Barbentane','Barbentane','13'),('FR','BBG','Barenton-Bugny','Barenton-Bugny','02'),('FR','BBL','La Bourboule','La Bourboule','63'),('FR','BBM','Beblenheim','Beblenheim','68'),('FR','BBN','Bettborn','Bettborn','57'),('FR','BBR','Besse-sur-Braye','Besse-sur-Braye','72'),('FR','BBT','Beausemblant','Beausemblant','26'),('FR','BBU','Boisbreteau','Boisbreteau','16'),('FR','BBX','Barby','Barby','73'),('FR','BBY','Balbigny','Balbigny','42'),('FR','BBZ','Beton-Bazoches','Beton-Bazoches','77'),('FR','BCA','Beaucaire','Beaucaire','30'),('FR','BCC','Baccon','Baccon','45'),('FR','BCD','Bernac-Dessus','Bernac-Dessus','65'),('FR','BCE','Bagnols-sur-Ceze','Bagnols-sur-Ceze','30'),('FR','BCF','Bussac-Foret','Bussac-Foret','17'),('FR','BCG','Brancourt-le-Grand','Brancourt-le-Grand','02'),('FR','BCH','Bischwiller','Bischwiller','67'),('FR','BCI','Berric','Berric','56'),('FR','BCL','Bois-Colombes','Bois-Colombes','92'),('FR','BCN','Briancon','Briancon','05'),('FR','BCP','Beauchamp','Beauchamp','95'),('FR','BCQ','Boissettes','Boissettes','77'),('FR','BCR','Beaucaire','Beaucaire','32'),('FR','BCS','Beauchamps','Beauchamps','80'),('FR','BCT','Beaucourt','Beaucourt','90'),('FR','BCV','Bersac-sur-Rivalier','Bersac-sur-Rivalier','87'),('FR','BCX','Beire-le-Chatel','Beire-le-Chatel','21'),('FR','BCY','Bouillancourt-en-Sery','Bouillancourt-en-Sery','80'),('FR','BCZ','Boucoiran-et-Nozieres','Boucoiran-et-Nozieres','30'),('FR','BDA','Baume-les-Dames','Baume-les-Dames','25'),('FR','BDB','Bernac-Debat','Bernac-Debat','65'),('FR','BDC','Bagneres-de-Luchon','Bagneres-de-Luchon','31'),('FR','BDD','Bidart','Bidart','64'),('FR','BDE','Budeliere','Budeliere','23'),('FR','BDF','Bondoufle','Bondoufle','91'),('FR','BDG','Baignes-Sainte-Radegonde','Baignes-Sainte-Radegonde','16'),('FR','BDH','La Baume-d\'Hostun','La Baume-d\'Hostun','26'),('FR','BDI','Le Bois-d\'Oingt','Le Bois-d\'Oingt','69'),('FR','BDL','Blenod-les-Toul','Blenod-les-Toul','54'),('FR','BDM','Bayard-sur-Marne','Bayard-sur-Marne','52'),('FR','BDN','Bagnoles-de-l\'Orne','Bagnoles-de-l\'Orne','61'),('FR','BDO','Bedous','Bedous','64'),('FR','BDP','Bourg-de-Peage','Bourg-de-Peage','26'),('FR','BDQ','Blendecques','Blendecques','62'),('FR','BDR','Baudricourt','Baudricourt','88'),('FR','BDS','Berteaucourt-les-Dames','Berteaucourt-les-Dames','80'),('FR','BDT','Bourg-de-Thizy','Bourg-de-Thizy','69'),('FR','BDU','Bedarieux','Bedarieux','34'),('FR','BDV','Beaumes-de-Venise','Beaumes-de-Venise','84'),('FR','BDX','Bourdic','Bourdic','30'),('FR','BDY','Bondy/Paris','Bondy/Paris','93'),('FR','BEA','Beaune','Beaune','21'),('FR','BEB','Bourg-en-Bresse','Bourg-en-Bresse','01'),('FR','BEC','Bec d\'Ambes','Bec d\'Ambes','33'),('FR','BED','Bedee','Bedee','35'),('FR','BEE','Berre','Berre','13'),('FR','BEF','Bree','Bree','53'),('FR','BEG','Bening-les-Saint-Avold','Bening-les-Saint-Avold','57'),('FR','BEH','Beinheim','Beinheim','67'),('FR','BEI','Berguette','Berguette','62'),('FR','BEJ','Beaujeu','Beaujeu','04'),('FR','BEL','Bellegarde-sur-Valserine','Bellegarde-sur-Valserine','01'),('FR','BEM','Belleme','Belleme','61'),('FR','BEN','Benfeld','Benfeld','67'),('FR','BEO','Bessancourt','Bessancourt','95'),('FR','BEP','Brazey-en-Plaine','Brazey-en-Plaine','21'),('FR','BEQ','Belval','Belval','50'),('FR','BER','Bernay','Bernay','72'),('FR','BES','Brest','Brest','29'),('FR','BET','Bethune','Bethune','62'),('FR','BEU','Beaupreau','Beaupreau','49'),('FR','BEV','Berville-sur-Mer','Berville-sur-Mer','27'),('FR','BEX','Bezouotte','Bezouotte','21'),('FR','BEY','Beynost','Beynost','01'),('FR','BEZ','Bernin','Bernin','38'),('FR','BFA','Bellefontaine','Bellefontaine','39'),('FR','BFB','Bar-sur-Aube','Bar-sur-Aube','10'),('FR','BFF','Benestroff','Benestroff','57'),('FR','BFH','Behren-les-Forbach','Behren-les-Forbach','57'),('FR','BFN','Bouffemont','Bouffemont','95'),('FR','BFR','Beaufort','Beaufort','39'),('FR','BFT','Botans','Botans','90'),('FR','BGA','Bagas','Bagas','33'),('FR','BGB','Bouge-Chambalud','Bouge-Chambalud','38'),('FR','BGC','Bagnac-sur-Cele','Bagnac-sur-Cele','46'),('FR','BGD','Bourg-Madame','Bourg-Madame','66'),('FR','BGE','Boulogne-sur-Gesse','Boulogne-sur-Gesse','31'),('FR','BGF','Bourganeuf','Bourganeuf','23'),('FR','BGG','Brignogan-Plage','Brignogan-Plage','29'),('FR','BGI','Bois Guillaume','Bois Guillaume','76'),('FR','BGJ','Bourgoin-Jallieu','Bourgoin-Jallieu','38'),('FR','BGL','Begles','Begles','33'),('FR','BGM','Blaringhem','Blaringhem','59'),('FR','BGN','Bagneaux','Bagneaux','89'),('FR','BGO','Bagnols-les-Bains','Bagnols-les-Bains','48'),('FR','BGQ','Branges','Branges','71'),('FR','BGR','Bruguieres','Bruguieres','31'),('FR','BGS','Bages','Bages','11'),('FR','BGT','Bugeat','Bugeat','19'),('FR','BGU','Biguglia','Biguglia','2B'),('FR','BGV','Bourg-les-Valence','Bourg-les-Valence','26'),('FR','BGY','Beaugency','Beaugency','45'),('FR','BGZ','Bucey-les-Gy','Bucey-les-Gy','70'),('FR','BHE','Braches','Braches','80'),('FR','BHG','Bercheres-St-Germain','Bercheres-St-Germain','28'),('FR','BHL','Berthelming','Berthelming','57'),('FR','BHM','Baldenheim','Baldenheim','67'),('FR','BHN','Bertholene','Bertholene','12'),('FR','BHS','Bischtroff-sur-Sarre','Bischtroff-sur-Sarre','67'),('FR','BHT','Bruyeres-le-Chatel','Bruyeres-le-Chatel','91'),('FR','BHZ','Bergholtz','Bergholtz','68'),('FR','BIA','Bastia','Bastia','2B'),('FR','BIB','Blaisy-Bas','Blaisy-Bas','21'),('FR','BIC','Biars-sur-Cere','Biars-sur-Cere','46'),('FR','BID','Bidos','Bidos','64'),('FR','BIE','Balsieges','Balsieges','48'),('FR','BIG','Brigueuil','Brigueuil','16'),('FR','BIH','Bischoffsheim','Bischoffsheim','67'),('FR','BII','Bieville-Beuville','Bieville-Beuville','14'),('FR','BIL','Bailleul','Bailleul','80'),('FR','BIM','Bischheim','Bischheim','67'),('FR','BIN','Bourgtheroulde-Infreville','Bourgtheroulde-Infreville','27'),('FR','BIO','Brioude','Brioude','43'),('FR','BIQ','Biarritz','Biarritz','64'),('FR','BIR','Barbieres','Barbieres','26'),('FR','BIS','Brissac','Brissac','34'),('FR','BIT','Biot','Biot','06'),('FR','BIU','Bailleul','Bailleul','59'),('FR','BIX','Baisieux','Baisieux','59'),('FR','BIY','Bacilly','Bacilly','50'),('FR','BIZ','Briouze','Briouze','61'),('FR','BJC','Barjac','Barjac',''),('FR','BJG','Blancafort','Blancafort','18'),('FR','BJN','Bouray-sur-Juine','Bouray-sur-Juine','91'),('FR','BJU','Beaujeu','Beaujeu','69'),('FR','BKG','Begadan','Begadan','33'),('FR','BLA','Blainville-sur-l\'Eau','Blainville-sur-l\'Eau','54'),('FR','BLB','Bouze-les-Beaune','Bouze-les-Beaune','21'),('FR','BLC','Bage-le-Chatel','Bage-le-Chatel','01'),('FR','BLD','Bar-le-Duc','Bar-le-Duc','55'),('FR','BLE','Brenouille','Brenouille','60'),('FR','BLF','Balaruc-les-Bains','Balaruc-les-Bains','34'),('FR','BLG','Blagnac','Blagnac','31'),('FR','BLH','Beaulieu-les-Loches','Beaulieu-les-Loches','37'),('FR','BLI','Barlin','Barlin','62'),('FR','BLL','Bosville','Bosville','76'),('FR','BLM','Ballan-Mire','Ballan-Mire','37'),('FR','BLN','Bagneaux-sur-Loing','Bagneaux-sur-Loing','77'),('FR','BLO','Blois','Blois','41'),('FR','BLQ','Blanquefort','Blanquefort','32'),('FR','BLR','Belabre','Belabre','36'),('FR','BLS','Baillargues','Baillargues','34'),('FR','BLU','Bouillargues','Bouillargues','30'),('FR','BLV','Belleville/Paris','Belleville/Paris','75'),('FR','BLX','Belley','Belley','01'),('FR','BLY','Balleroy','Balleroy','14'),('FR','BLZ','Blotzheim','Blotzheim','68'),('FR','BMA','Benesse-Maremne','Benesse-Maremne','40'),('FR','BMG','Bermering','Bermering','57'),('FR','BMH','Beaumont-Hague','Beaumont-Hague','50'),('FR','BMI','Bainville-aux-Miroirs','Bainville-aux-Miroirs','54'),('FR','BMJ','Beaucamp-le-Jeune','Beaucamp-le-Jeune','80'),('FR','BMM','Belleville','Belleville','54'),('FR','BMN','Bully-les-Mines','Bully-les-Mines','62'),('FR','BMO','Beaumont-le-Roger','Beaumont-le-Roger','27'),('FR','BMP','Balma','Balma','31'),('FR','BMR','Batz-sur-Mer','Batz-sur-Mer','44'),('FR','BMS','Bommiers','Bommiers','36'),('FR','BMT','Beaumont-sur-Oise','Beaumont-sur-Oise','95'),('FR','BMU','Bourg-Saint-Maurice','Bourg-Saint-Maurice','73'),('FR','BMV','Beaucamp-le-Vieux','Beaucamp-le-Vieux','80'),('FR','BNA','Beine-Nauroy','Beine-Nauroy','51'),('FR','BNB','Blangy-sur-Bresle','Blangy-sur-Bresle','76'),('FR','BNC','Bouttencourt','Bouttencourt','80'),('FR','BND','Balanod','Balanod','39'),('FR','BNE','Branne','Branne','33'),('FR','BNG','Becon-les-Granits','Becon-les-Granits','49'),('FR','BNH','Brettnach','Brettnach','57'),('FR','BNI','Bonnieres-sur-Seine','Bonnieres-sur-Seine','78'),('FR','BNL','Bonneuil-les-Eaux','Bonneuil-les-Eaux','60'),('FR','BNN','Brionne','Brionne','27'),('FR','BNO','Boen','Boen','42'),('FR','BNR','Bar-sur-Seine','Bar-sur-Seine','10'),('FR','BNS','Boussens','Boussens','31'),('FR','BNT','Bonnetable','Bonnetable','72'),('FR','BNV','Barneville-Carteret','Barneville-Carteret','50'),('FR','BNX','Balnot-sur-Laignes','Balnot-sur-Laignes','10'),('FR','BNY','Bernay','Bernay','27'),('FR','BOA','Bouc-Bel-Air','Bouc-Bel-Air','13'),('FR','BOB','Bobigny','Bobigny','93'),('FR','BOC','Boissy-le-Chatel','Boissy-le-Chatel','77'),('FR','BOD','Bordeaux','Bordeaux','33'),('FR','BOE','Bon-Encontre','Bon-Encontre','47'),('FR','BOF','Bruyere-sur-Oise','Bruyere-sur-Oise','95'),('FR','BOG','Bologne','Bologne','52'),('FR','BOH','Bouhey','Bouhey','21'),('FR','BOI','Bouguenais','Bouguenais','44'),('FR','BOJ','Bousies','Bousies','59'),('FR','BOK','Bourbon-Lancy','Bourbon-Lancy','71'),('FR','BOL','Boulogne-sur-Mer','Boulogne-sur-Mer','62'),('FR','BOM','Billom','Billom','63'),('FR','BON','Bonifacio','Bonifacio','2A'),('FR','BOO','Boos','Boos','76'),('FR','BOP','Boue','Boue','02'),('FR','BOQ','Bonson','Bonson','42'),('FR','BOR','Belfort','Belfort','90'),('FR','BOS','Bousbecque','Bousbecque','59'),('FR','BOT','Bourgtheroulde','Bourgtheroulde','27'),('FR','BOU','Bourges','Bourges','18'),('FR','BOV','Bonneville','Bonneville','74'),('FR','BOX','Boisseaux','Boisseaux','45'),('FR','BOY','Boissy-Saint-Leger','Boissy-Saint-Leger','94'),('FR','BOZ','Boulazac','Boulazac','24'),('FR','BPA','Bompas','Bompas','66'),('FR','BPE','Baupte','Baupte','50'),('FR','BPI','Bournoncle-St-Pierre','Bournoncle-St-Pierre','43'),('FR','BPL','Bonchamp-les-Laval','Bonchamp-les-Laval','53'),('FR','BPN','Bucy-les-Pierrepont','Bucy-les-Pierrepont','02'),('FR','BPO','Blanzac-Porcheresse','Blanzac-Porcheresse','16'),('FR','BPR','Labastide-St-Pierre','Labastide-St-Pierre','82'),('FR','BPS','Blenod-les-Pont-a-Mousson','Blenod-les-Pont-a-Mousson','54'),('FR','BPT','Brion-pres-Thouet','Brion-pres-Thouet','79'),('FR','BPY','Bellenot-sous-Pouilly','Bellenot-sous-Pouilly','21'),('FR','BQA','Bauvin','Bauvin','59'),('FR','BQC','Bricquebec','Bricquebec','50'),('FR','BQE','Boe','Boe','47'),('FR','BQG','Bocquegney','Bocquegney','88'),('FR','BQH','La Bussiere-sur-Ouche','La Bussiere-sur-Ouche','21'),('FR','BQL','Bosquel','Bosquel','80'),('FR','BQQ','Bron','Bron','69'),('FR','BQT','Brebotte','Brebotte','90'),('FR','BQU','Bolquere','Bolquere','66'),('FR','BQV','Baraqueville','Baraqueville','12'),('FR','BQZ','Besne','Besne','44'),('FR','BRA','Bercy Rapee/Paris','Bercy Rapee/Paris','75'),('FR','BRB','Brou','Brou','28'),('FR','BRC','Brives-Charensac','Brives-Charensac','43'),('FR','BRD','Bordes','Bordes',''),('FR','BRE','Bretigny-sur-Orge','Bretigny-sur-Orge','91'),('FR','BRF','Breuil-le-Sec','Breuil-le-Sec','60'),('FR','BRG','Brignoud','Brignoud','38'),('FR','BRH','Brehand','Brehand','22'),('FR','BRI','Brignais','Brignais','69'),('FR','BRJ','Bressols','Bressols','82'),('FR','BRK','Barret','Barret','16'),('FR','BRL','Brens','Brens','81'),('FR','BRM','Brumath','Brumath','67'),('FR','BRN','Brignoles','Brignoles','83'),('FR','BRO','Bourogne','Bourogne','90'),('FR','BRP','Breuilpont','Breuilpont','27'),('FR','BRQ','Brebieres','Brebieres','62'),('FR','BRR','Briare','Briare','45'),('FR','BRS','Bergues','Bergues','59'),('FR','BRT','Brie-Comte-Robert','Brie-Comte-Robert','77'),('FR','BRU','Bruges/Bordeaux','Bruges/Bordeaux','33'),('FR','BRV','Brives','Brives','36'),('FR','BRW','Brassac','Brassac','82'),('FR','BRX','Briatexte','Briatexte','81'),('FR','BRY','Bruyeres','Bruyeres','88'),('FR','BRZ','Brezins','Brezins','38'),('FR','BSA','Bourg-Saint-Andeol','Bourg-Saint-Andeol','07'),('FR','BSB','Boigny-sur-Bionne','Boigny-sur-Bionne','45'),('FR','BSC','Bonsecours','Bonsecours','76'),('FR','BSD','Brive','Brive','44'),('FR','BSE','Bassens','Bassens','73'),('FR','BSF','Bagnols-en-Foret','Bagnols-en-Foret','83'),('FR','BSG','Bourg-sur-Gironde','Bourg-sur-Gironde','33'),('FR','BSH','Biesheim','Biesheim','68'),('FR','BSI','Breal-sous-Vitre','Breal-sous-Vitre','35'),('FR','BSJ','Bessines-sur-Gartempe','Bessines-sur-Gartempe','87'),('FR','BSK','Barsac','Barsac','33'),('FR','BSL','Le Bar-sur-Loup','Le Bar-sur-Loup','06'),('FR','BSM','Bonneuil-sur-Marne','Bonneuil-sur-Marne','94'),('FR','BSN','Besancon','Besancon','25'),('FR','BSO','Blainville-sur-Orne','Blainville-sur-Orne','14'),('FR','BSP','Boisset-Saint-Priest','Boisset-Saint-Priest','42'),('FR','BSQ','Bresles','Bresles','60'),('FR','BSR','Bois-le-Roi','Bois-le-Roi','77'),('FR','BSS','Belleville-sur-Saone','Belleville-sur-Saone','69'),('FR','BST','Bailleul-sur-Therain','Bailleul-sur-Therain','60'),('FR','BSU','Bressey-sur-Tille','Bressey-sur-Tille','21'),('FR','BSV','Biache-Saint-Vaast','Biache-Saint-Vaast','62'),('FR','BSX','Bussy-Albieux','Bussy-Albieux','42'),('FR','BSY','Breteuil','Breteuil','60'),('FR','BSZ','Brie-sous-Archiac','Brie-sous-Archiac','17'),('FR','BTA','Baerenthal','Baerenthal','57'),('FR','BTB','Breitenbach','Breitenbach',''),('FR','BTC','Bitche','Bitche','57'),('FR','BTD','Bastide/Bordeaux','Bastide/Bordeaux','33'),('FR','BTE','Boutenac','Boutenac','11'),('FR','BTF','Betschdorf','Betschdorf','67'),('FR','BTG','Boisset-et-Gaujac','Boisset-et-Gaujac','30'),('FR','BTH','Bethoncourt','Bethoncourt','25'),('FR','BTL','Bitschwiller-les-Thann','Bitschwiller-les-Thann','68'),('FR','BTM','Bartenheim','Bartenheim','68'),('FR','BTN','Barentin','Barentin','76'),('FR','BTO','Bort-les-Orgues','Bort-les-Orgues','19'),('FR','BTQ','Belmont-de-la-Loire','Belmont-de-la-Loire','42'),('FR','BTR','Breteniere','Breteniere','21'),('FR','BTS','Bertrichamps','Bertrichamps','54'),('FR','BTT','Bourdettes','Bourdettes','64'),('FR','BTU','Betton','Betton','35'),('FR','BTV','Beaufort-en-Vallee','Beaufort-en-Vallee','49'),('FR','BTX','Bretenoux','Bretenoux','46'),('FR','BTY','Bethisy-St-Pierre','Bethisy-St-Pierre','60'),('FR','BTZ','Betz','Betz','60'),('FR','BUA','Beaurieux','Beaurieux','02'),('FR','BUB','Buis-les-Baronnies','Buis-les-Baronnies','26'),('FR','BUC','Buc','Buc','90'),('FR','BUD','Baudrieres','Baudrieres','71'),('FR','BUE','Bouee','Bouee','44'),('FR','BUG','Bugnicourt','Bugnicourt','59'),('FR','BUH','Buchelay','Buchelay','78'),('FR','BUI','Buire-le-Sec','Buire-le-Sec','62'),('FR','BUL','Beaulieu','Beaulieu',''),('FR','BUM','Boulay-Moselle','Boulay-Moselle','57'),('FR','BUN','Beaurainville','Beaurainville','62'),('FR','BUO','Beausoleil','Beausoleil','06'),('FR','BUQ','Bussy','Bussy','18'),('FR','BUR','Bures-en-Bray','Bures-en-Bray','76'),('FR','BUS','Beaurains','Beaurains','62'),('FR','BUT','Bourth','Bourth','27'),('FR','BUU','Bouy','Bouy','51'),('FR','BUV','Bouville','Bouville',''),('FR','BUX','Buxy','Buxy','71'),('FR','BUY','Bruay-la-Buissiere','Bruay-la-Buissiere','62'),('FR','BUZ','Bruz','Bruz','35'),('FR','BVA','Beauvais','Beauvais','60'),('FR','BVC','Beville-le-Comte','Beville-le-Comte','28'),('FR','BVE','Brive-la-Gaillarde','Brive-la-Gaillarde','19'),('FR','BVG','Beuvrages','Beuvrages','59'),('FR','BVI','Belleville-sur-Vie','Belleville-sur-Vie','85'),('FR','BVL','Bailleval','Bailleval','60'),('FR','BVM','Blainville-sur-Mer','Blainville-sur-Mer','50'),('FR','BVN','Bouvines','Bouvines','59'),('FR','BVO','Beauvoisin','Beauvoisin','39'),('FR','BVQ','Boulleville','Boulleville','27'),('FR','BVS','Belleville','Belleville','79'),('FR','BVU','Bretteville-l\'Orgueilleuse','Bretteville-l\'Orgueilleuse','14'),('FR','BVX','St-Bris-le-Vineux','St-Bris-le-Vineux','89'),('FR','BVY','Blavozy','Blavozy','43'),('FR','BVZ','Belvezet','Belvezet','30'),('FR','BWG','Bennwihr','Bennwihr','68'),('FR','BXA','Bias','Bias','47'),('FR','BXH','Brax','Brax','31'),('FR','BXJ','Baigneux-les-Juifs','Baigneux-les-Juifs','21'),('FR','BXN','Balan','Balan','01'),('FR','BXS','Baixas','Baixas','66'),('FR','BXY','Brecey','Brecey','50'),('FR','BYC','Baleycourt','Baleycourt','55'),('FR','BYE','Blaye','Blaye','33'),('FR','BYH','Balagny-sur-Therain','Balagny-sur-Therain','60'),('FR','BYJ','Broye','Broye','71'),('FR','BYL','Bayel','Bayel','10'),('FR','BYM','Bry-sur-Marne/Paris','Bry-sur-Marne/Paris','94'),('FR','BYQ','Bray-en-Val','Bray-en-Val','45'),('FR','BYR','Beyrede-Jumet','Beyrede-Jumet','65'),('FR','BYS','Boynes','Boynes','45'),('FR','BYU','Bray-et-Lu','Bray-et-Lu','95'),('FR','BYV','Buc','Buc','78'),('FR','BYX','Bayeux','Bayeux','14'),('FR','BYY','Boissy-sous-St-Yon','Boissy-sous-St-Yon','91'),('FR','BZA','Blanzac-les-Matha','Blanzac-les-Matha','17'),('FR','BZC','Buzancais','Buzancais','36'),('FR','BZE','Bazainville','Bazainville','78'),('FR','BZH','Bazoches','Bazoches','58'),('FR','BZI','Belz','Belz','56'),('FR','BZL','Bozouls','Bozouls','12'),('FR','BZN','Cebazan','Cebazan','34'),('FR','BZO','Bezons','Bezons','95'),('FR','BZQ','Brezolles','Brezolles','28'),('FR','BZR','Beziers','Beziers','34'),('FR','BZS','Bazas','Bazas','33'),('FR','BZT','Bizanet','Bizanet','11'),('FR','BZU','Bezu-St-Eloi','Bezu-St-Eloi','27'),('FR','BZV','Bouzonville','Bouzonville','57'),('FR','BZY','Blanzy','Blanzy','71'),('FR','CAA','Challans','Challans','85'),('FR','CAB','Cabannes','Cabannes','13'),('FR','CAC','Carsac-Aillac','Carsac-Aillac','24'),('FR','CAD','Caudies-de-Fenouilledes','Caudies-de-Fenouilledes','66'),('FR','CAE','Caestre','Caestre','59'),('FR','CAF','Caffiers','Caffiers','62'),('FR','CAG','Chavagnes','Chavagnes','49'),('FR','CAH','Charny','Charny','21'),('FR','CAI','Chabanais','Chabanais','16'),('FR','CAJ','La Calmette','La Calmette','30'),('FR','CAK','Florensac','Florensac','34'),('FR','CAL','Caluire-et-Cuire','Caluire-et-Cuire','69'),('FR','CAM','Camaret-sur-Mer','Camaret-sur-Mer','29'),('FR','CAN','Chanes','Chanes','71'),('FR','CAO','Chalonnes-sur-Loire','Chalonnes-sur-Loire','49'),('FR','CAP','Capdenac-Gare','Capdenac-Gare','12'),('FR','CAQ','Camon','Camon','80'),('FR','CAR','Chateau-Arnoux','Chateau-Arnoux','04'),('FR','CAS','Castres','Castres','81'),('FR','CAT','Castres','Castres','44'),('FR','CAU','Cauderan','Cauderan','33'),('FR','CAV','Cavaillon','Cavaillon','84'),('FR','CAW','Cabourg','Cabourg','14'),('FR','CAX','Cannet','Cannet','13'),('FR','CAY','Cayeux-sur-Mer','Cayeux-sur-Mer','80'),('FR','CAZ','Chariez','Chariez','70'),('FR','CBA','Corbas','Corbas','69'),('FR','CBB','Charbonnieres-les-Bains','Charbonnieres-les-Bains','69'),('FR','CBC','Carbon-Blanc','Carbon-Blanc','33'),('FR','CBD','Chateaubriant','Chateaubriant','44'),('FR','CBE','Chasseneuil-sur-Bonnieure','Chasseneuil-sur-Bonnieure','16'),('FR','CBF','Cheval-Blanc','Cheval-Blanc','84'),('FR','CBG','Croissy-Beaubourg','Croissy-Beaubourg','77'),('FR','CBH','Chambeon','Chambeon','42'),('FR','CBI','Corbie','Corbie','80'),('FR','CBL','Corbeil','Corbeil','51'),('FR','CBM','La Chapelle-Basse Mer','La Chapelle-Basse Mer','44'),('FR','CBN','Corbigny','Corbigny','58'),('FR','CBO','Colombelles','Colombelles','14'),('FR','CBQ','Chateaubernard','Chateaubernard','16'),('FR','CBR','Coulombiers','Coulombiers','86'),('FR','CBS','Cambo-les-Bains','Cambo-les-Bains','64'),('FR','CBT','Capbreton','Capbreton','40'),('FR','CBU','Combourg','Combourg','35'),('FR','CBV','Cany-Barville','Cany-Barville','76'),('FR','CBW','Chambon','Chambon','37'),('FR','CBX','Cabries','Cabries','13'),('FR','CBY','Chambly','Chambly','60'),('FR','CBZ','Chamboret','Chamboret','87'),('FR','CCB','Le Cateau-Cambresis','Le Cateau-Cambresis','59'),('FR','CCC','Crecy-la-Chapelle','Crecy-la-Chapelle','77'),('FR','CCE','Chace','Chace','49'),('FR','CCF','Carcassonne','Carcassonne','11'),('FR','CCG','Charchigne','Charchigne','53'),('FR','CCH','Clichy','Clichy','92'),('FR','CCI','Castelculier','Castelculier','47'),('FR','CCL','Cosne-Cours-sur-Loire','Cosne-Cours-sur-Loire','58'),('FR','CCN','Cerons','Cerons','33'),('FR','CCO','Chevry-Cossigny','Chevry-Cossigny','77'),('FR','CCP','Cubzac-les-Ponts','Cubzac-les-Ponts','33'),('FR','CCR','Clermont-Creans','Clermont-Creans','72'),('FR','CCS','Clairvaux-les-Lacs','Clairvaux-les-Lacs','39'),('FR','CCT','Cercy-la-Tour','Cercy-la-Tour','58'),('FR','CCU','Cenac','Cenac','33'),('FR','CCX','Corcieux','Corcieux','88'),('FR','CCY','Clamecy','Clamecy',''),('FR','CDA','Cire d\'Aunis','Cire d\'Aunis','17'),('FR','CDB','Chartres-de-Bretagne','Chartres-de-Bretagne','35'),('FR','CDC','Charenton-du-Cher','Charenton-du-Cher','18'),('FR','CDD','Champdeniers-Saint-Denis','Champdeniers-Saint-Denis','79'),('FR','CDE','Chedde','Chedde','74'),('FR','CDF','Chateauneuf-du-Faou','Chateauneuf-du-Faou','29'),('FR','CDG','Charles de Gaulle Apt/Paris','Charles de Gaulle Apt/Paris','95'),('FR','CDH','Castets-en-Dorthe','Castets-en-Dorthe','33'),('FR','CDI','Cons-la-Grandville','Cons-la-Grandville','54'),('FR','CDL','Chateau-du-Loir','Chateau-du-Loir','72'),('FR','CDM','Champs de Mars/Lille','Champs de Mars/Lille','59'),('FR','CDN','Cadenet','Cadenet','84'),('FR','CDO','Codognan','Codognan','30'),('FR','CDP','Chateauneuf-du-Pape','Chateauneuf-du-Pape','84'),('FR','CDR','Chalindrey','Chalindrey','52'),('FR','CDS','Castelnau-d\'Estretefonds','Castelnau-d\'Estretefonds','31'),('FR','CDT','Champdieu','Champdieu','42'),('FR','CDU','Castillon-du-Gard','Castillon-du-Gard','30'),('FR','CDV','Condat-sur-Vienne','Condat-sur-Vienne','87'),('FR','CDW','Champ-sur-Drac','Champ-sur-Drac','38'),('FR','CDX','Capendu','Capendu','11'),('FR','CDY','Caudry','Caudry','59'),('FR','CDZ','Cerdon','Cerdon','45'),('FR','CEA','Cestas','Cestas','33'),('FR','CEB','Cerbere','Cerbere','66'),('FR','CEC','Caudebec-en-Caux','Caudebec-en-Caux','76'),('FR','CED','Castelnau-de-Montratier','Castelnau-de-Montratier','46'),('FR','CEE','Cesson-Sevigne','Cesson-Sevigne','35'),('FR','CEF','Caudebec-les-Elbeuf','Caudebec-les-Elbeuf','76'),('FR','CEG','Collegien','Collegien','77'),('FR','CEH','La Caillere-Sainte-Hilaire','La Caillere-Sainte-Hilaire','85'),('FR','CEI','Chatenois','Chatenois','67'),('FR','CEJ','Conflans-en-Jarnisy','Conflans-en-Jarnisy','54'),('FR','CEL','Chantelle','Chantelle','03'),('FR','CEM','Chire-en-Montreuil','Chire-en-Montreuil','86'),('FR','CEN','Cheminot','Cheminot','57'),('FR','CEO','Cenon','Cenon','33'),('FR','CEP','Cergy','Cergy','95'),('FR','CEQ','Cannes','Cannes','06'),('FR','CER','Cherbourg','Cherbourg','50'),('FR','CES','Cognieres','Cognieres','70'),('FR','CET','Cholet','Cholet','49'),('FR','CEU','Chateauneuf-les-Martigues','Chateauneuf-les-Martigues','13'),('FR','CEV','Crepy-en-Valois','Crepy-en-Valois','60'),('FR','CEX','Cesson','Cesson','77'),('FR','CEY','Catenoy','Catenoy','60'),('FR','CEZ','Chelles','Chelles','77'),('FR','CFC','Chateauneuf-sur-Charente','Chateauneuf-sur-Charente','16'),('FR','CFE','Clermont-Ferrand','Clermont-Ferrand','63'),('FR','CFF','Chauffry','Chauffry','77'),('FR','CFH','Chateauneuf-sur-Cher','Chateauneuf-sur-Cher','18'),('FR','CFI','Chateauneuf-sur-Isere','Chateauneuf-sur-Isere','26'),('FR','CFK','Coufouleux','Coufouleux','81'),('FR','CFL','Confolens','Confolens','16'),('FR','CFM','Clermont-les-Fermes','Clermont-les-Fermes','02'),('FR','CFR','Caen','Caen','14'),('FR','CFS','Chateauneuf-sur-Sarthe','Chateauneuf-sur-Sarthe','49'),('FR','CFT','Chateauneuf-en-Thymerais','Chateauneuf-en-Thymerais','28'),('FR','CFU','Chef-du-Pont','Chef-du-Pont','50'),('FR','CFX','Chateauneuf-du-Rhone','Chateauneuf-du-Rhone','26'),('FR','CFY','Cauffry','Cauffry','60'),('FR','CGC','Corgoloin','Corgoloin','21'),('FR','CGD','Chavagnes-les-Redoux','Chavagnes-les-Redoux','85'),('FR','CGE','Chavagne','Chavagne','35'),('FR','CGG','Cavignac','Cavignac','33'),('FR','CGI','Clermont','Clermont','60'),('FR','CGL','Carling','Carling','57'),('FR','CGM','Castelnaud-de-Gratecambe','Castelnaud-de-Gratecambe','47'),('FR','CGN','Carignan','Carignan','08'),('FR','CGO','Chateau-Gontier','Chateau-Gontier','53'),('FR','CGQ','Change','Change','72'),('FR','CGR','Cappelle-la-Grande','Cappelle-la-Grande','59'),('FR','CGS','Coignieres','Coignieres','78'),('FR','CGT','Chatuzange-le-Goubet','Chatuzange-le-Goubet','26'),('FR','CGU','Courgis','Courgis','89'),('FR','CGV','Cran-Gevrier','Cran-Gevrier','74'),('FR','CGX','Cagny','Cagny','14'),('FR','CGY','Chagny','Chagny','71'),('FR','CHA','Chartres','Chartres','28'),('FR','CHB','Chabris','Chabris','36'),('FR','CHC','Charvieu-Chavagneux','Charvieu-Chavagneux','38'),('FR','CHD','Chambord','Chambord','41'),('FR','CHE','Checy','Checy','45'),('FR','CHF','Change','Change','71'),('FR','CHG','Changy','Changy',''),('FR','CHH','Chateauroux','Chateauroux','05'),('FR','CHI','Chassieu','Chassieu','69'),('FR','CHJ','Champsac','Champsac','87'),('FR','CHK','Chatenay-Malabry','Chatenay-Malabry','92'),('FR','CHL','Chatellerault','Chatellerault','86'),('FR','CHM','Charleville-Mezieres','Charleville-Mezieres','08'),('FR','CHN','Chaulnes','Chaulnes','80'),('FR','CHO','Choisy-le-Roi','Choisy-le-Roi','94'),('FR','CHP','Champagne-sur-Seine','Champagne-sur-Seine','77'),('FR','CHQ','Chocques','Chocques','62'),('FR','CHR','Chateauroux','Chateauroux','36'),('FR','CHS','Champigneulles','Champigneulles','54'),('FR','CHT','Chatenay','Chatenay','28'),('FR','CHU','Chateau','Chateau','71'),('FR','CHV','Charleval','Charleval','13'),('FR','CHW','Chalus','Chalus','87'),('FR','CHX','Chateaucreux/Saint-Etienne','Chateaucreux/Saint-Etienne','42'),('FR','CHY','Chauny','Chauny','02'),('FR','CHZ','Charnoz','Charnoz','01'),('FR','CIA','Choisy-au-Bac','Choisy-au-Bac','60'),('FR','CIB','Chantenay-St-Imbert','Chantenay-St-Imbert','58'),('FR','CIC','Civray','Civray','18'),('FR','CID','Chailland','Chailland','53'),('FR','CIE','Chemille','Chemille','49'),('FR','CIG','Chaveignes','Chaveignes','37'),('FR','CII','Chissay-en-Touraine','Chissay-en-Touraine','41'),('FR','CIL','Chatillon','Chatillon','92'),('FR','CIM','Chimilin','Chimilin','38'),('FR','CIN','Chatillon','Chatillon','03'),('FR','CIO','Cires-les-Mello','Cires-les-Mello','60'),('FR','CIP','Chiry-Ourscamps','Chiry-Ourscamps','60'),('FR','CIQ','Cherisy','Cherisy','28'),('FR','CIR','Chatillon','Chatillon','69'),('FR','CIS','Chauffailles','Chauffailles','71'),('FR','CIT','Cornimont','Cornimont','88'),('FR','CIU','Chailloue','Chailloue','61'),('FR','CIV','Civray','Civray','86'),('FR','CIX','La Croix','La Croix','35'),('FR','CIY','Choisy','Choisy','74'),('FR','CIZ','Couiza','Couiza','11'),('FR','CJC','Cadaujac','Cadaujac','33'),('FR','CJR','Cajarc','Cajarc','46'),('FR','CJX','Casteljaloux','Casteljaloux','47'),('FR','CKQ','Coudekerque','Coudekerque','59'),('FR','CLA','Clamart','Clamart','92'),('FR','CLB','Colombes','Colombes','92'),('FR','CLC','Clerac','Clerac','17'),('FR','CLD','St Cloud','St Cloud','92'),('FR','CLE','Cleon','Cleon','76'),('FR','CLF','Chateauneuf-la-Foret','Chateauneuf-la-Foret','87'),('FR','CLG','Crevecoeur-le-Grand','Crevecoeur-le-Grand','60'),('FR','CLH','Clermont-l\'Herault','Clermont-l\'Herault','34'),('FR','CLI','Coulommiers','Coulommiers','77'),('FR','CLJ','Corcelles-les-Citeaux','Corcelles-les-Citeaux','21'),('FR','CLL','Chantilly','Chantilly','60'),('FR','CLM','Collonges-au-Mont-d\'Or','Collonges-au-Mont-d\'Or','69'),('FR','CLN','Cleon-d\'Andran','Cleon-d\'Andran','26'),('FR','CLO','Clisson','Clisson','44'),('FR','CLP','Chalampe','Chalampe','68'),('FR','CLQ','Chaleins','Chaleins','01'),('FR','CLR','Chatenoy-le-Royal','Chatenoy-le-Royal','71'),('FR','CLS','Chelles','Chelles','60'),('FR','CLT','Chamelet','Chamelet','69'),('FR','CLU','Cluses','Cluses','74'),('FR','CLV','Combs-la-Ville','Combs-la-Ville','77'),('FR','CLW','Colombe','Colombe','38'),('FR','CLX','Clairoix','Clairoix','60'),('FR','CLY','Calvi','Calvi','2B'),('FR','CLZ','Clonas-sur-Vareze','Clonas-sur-Vareze','38'),('FR','CMA','Camares','Camares','12'),('FR','CMB','Cambrai','Cambrai','59'),('FR','CMC','Chamblanc','Chamblanc','21'),('FR','CMD','Castelnau-de-Medoc','Castelnau-de-Medoc','33'),('FR','CME','Cagnes-sur-Mer','Cagnes-sur-Mer','06'),('FR','CMF','Chambery','Chambery','73'),('FR','CMG','Chambolle-Musigny','Chambolle-Musigny','21'),('FR','CMH','Charmes-sur-Rhone','Charmes-sur-Rhone','07'),('FR','CMI','Charmeil','Charmeil','03'),('FR','CMJ','Champcueil','Champcueil','91'),('FR','CMK','Chamesson','Chamesson','21'),('FR','CML','Champforgeuil','Champforgeuil','71'),('FR','CMM','Commentry','Commentry','03'),('FR','CMN','Comines','Comines','59'),('FR','CMO','La Chapelle-Montreuil','La Chapelle-Montreuil','86'),('FR','CMP','Compiegne','Compiegne','60'),('FR','CMQ','Champlan','Champlan','91'),('FR','CMR','Colmar','Colmar','68'),('FR','CMS','Cambes','Cambes',''),('FR','CMT','Chaumont','Chaumont','52'),('FR','CMU','Coetmieux','Coetmieux','22'),('FR','CMV','Caunes-Minervois','Caunes-Minervois','11'),('FR','CMW','Chemaudin','Chemaudin','25'),('FR','CMX','Carmaux','Carmaux','81'),('FR','CMY','Commercy','Commercy','55'),('FR','CMZ','La Chaussee-sur-Marne','La Chaussee-sur-Marne','51'),('FR','CNA','Chenas','Chenas','69'),('FR','CNB','St-Colomban','St-Colomban','44'),('FR','CNC','Cantenac','Cantenac','33'),('FR','CND','Corps-Nuds','Corps-Nuds','35'),('FR','CNE','Crosne/Paris','Crosne/Paris','91'),('FR','CNG','Cognac','Cognac','16'),('FR','CNH','Chatillon-sur-Indre','Chatillon-sur-Indre','36'),('FR','CNI','Champniers','Champniers','16'),('FR','CNJ','Change','Change','53'),('FR','CNL','Canly','Canly','60'),('FR','CNM','Chenimenil','Chenimenil','88'),('FR','CNN','Chaneins','Chaneins','01'),('FR','CNO','Chantonnay','Chantonnay','85'),('FR','CNP','Charenton-le-Pont','Charenton-le-Pont','94'),('FR','CNQ','Canals','Canals','82'),('FR','CNR','Connerre','Connerre','72'),('FR','CNS','Chatillon-sur-Seine','Chatillon-sur-Seine','21'),('FR','CNT','Certines','Certines','01'),('FR','CNU','Condrieu','Condrieu','69'),('FR','CNV','Chenove','Chenove','21'),('FR','CNW','Le Cergne','Le Cergne',''),('FR','CNX','Cormenon','Cormenon','41'),('FR','CNY','Chantenay','Chantenay',''),('FR','CNZ','Chanaz','Chanaz','73'),('FR','COA','Cournon-d\'Auvergne','Cournon-d\'Auvergne','63'),('FR','COB','Cour-et-Buis','Cour-et-Buis','38'),('FR','COC','Concarneau','Concarneau','29'),('FR','COD','Condom','Condom','32'),('FR','COE','Corbeil-Essonnes','Corbeil-Essonnes','91'),('FR','COF','Corcelles-Ferrieres','Corcelles-Ferrieres','25'),('FR','COG','Cognin','Cognin','73'),('FR','COH','Conde-sur-Sarthe','Conde-sur-Sarthe','61'),('FR','COI','Coudeville','Coudeville','50'),('FR','COJ','Champagne-au-Mont-d\'Or','Champagne-au-Mont-d\'Or','69'),('FR','COK','Coudekerque-Branche','Coudekerque-Branche','59'),('FR','COL','Corcoue-sur-Logne','Corcoue-sur-Logne','44'),('FR','COM','Comblanchien','Comblanchien','21'),('FR','CON','Conflandey','Conflandey','70'),('FR','COO','Colomiers','Colomiers','31'),('FR','COQ','Condal','Condal','71'),('FR','COR','Corbehem','Corbehem','62'),('FR','COS','Carros','Carros','06'),('FR','COT','Coutances','Coutances','50'),('FR','COU','Coussol/Fos sur Mer','Coussol/Fos sur Mer','13'),('FR','COV','Conde-sur-Vire','Conde-sur-Vire','50'),('FR','COW','Couesmes','Couesmes','37'),('FR','COX','Croix','Croix','90'),('FR','COY','Chouilly','Chouilly','51'),('FR','COZ','Caronte','Caronte','13'),('FR','CPA','Cap-d\'Ail','Cap-d\'Ail','06'),('FR','CPB','La Chapelle Biche','La Chapelle Biche',''),('FR','CPC','Chaspuzac','Chaspuzac','43'),('FR','CPD','Campagne-d\'Armagnac','Campagne-d\'Armagnac','32'),('FR','CPE','Courpiere','Courpiere','63'),('FR','CPF','Champfromier','Champfromier','01'),('FR','CPG','Champagnole','Champagnole','39'),('FR','CPI','Champier','Champier','38'),('FR','CPL','Champillet','Champillet','36'),('FR','CPM','Champagne-Mouton','Champagne-Mouton','16'),('FR','CPN','Cases-de-Pene','Cases-de-Pene','66'),('FR','CPO','Cormeilles-en-Parisis','Cormeilles-en-Parisis','95'),('FR','CPQ','Chaponnay','Chaponnay','69'),('FR','CPR','Le Clapier','Le Clapier','12'),('FR','CPS','Campsas','Campsas','82'),('FR','CPU','Corpeau','Corpeau','21'),('FR','CPX','Champeaux','Champeaux','50'),('FR','CPY','Champigny-sur-Marne/Paris','Champigny-sur-Marne/Paris','94'),('FR','CQA','Craon','Craon','53'),('FR','CQD','Cendrecourt','Cendrecourt','70'),('FR','CQF','Calais','Calais','62'),('FR','CQG','Caumont-sur-Garonne','Caumont-sur-Garonne','47'),('FR','CQK','Cogolin','Cogolin','83'),('FR','CQN','Chateau-Landon','Chateau-Landon','77'),('FR','CQO','Coquainvilliers','Coquainvilliers','14'),('FR','CQP','Cinq-Mars-la-Pile','Cinq-Mars-la-Pile','37'),('FR','CQS','Coquelles','Coquelles','62'),('FR','CQT','Carpiquet','Carpiquet','14'),('FR','CQU','Carquefou','Carquefou','44'),('FR','CRA','Crancot','Crancot','39'),('FR','CRB','Courbevoie','Courbevoie','92'),('FR','CRC','Cerences','Cerences','50'),('FR','CRD','Creutzwald','Creutzwald','57'),('FR','CRE','Charolles','Charolles','71'),('FR','CRF','Cramant','Cramant','51'),('FR','CRG','Carrouges','Carrouges','61'),('FR','CRH','Chasse-sur-Rhone','Chasse-sur-Rhone','38'),('FR','CRI','Corbelin','Corbelin','38'),('FR','CRJ','Chateaurenard','Chateaurenard','13'),('FR','CRL','Creil','Creil','60'),('FR','CRM','Charmoille','Charmoille','70'),('FR','CRN','Carantec','Carantec','29'),('FR','CRO','Cronenbourg/Strasbourg','Cronenbourg/Strasbourg','67'),('FR','CRP','Carpentras','Carpentras','84'),('FR','CRQ','Craponne','Craponne','69'),('FR','CRR','Cherre','Cherre','72'),('FR','CRS','Chars','Chars','95'),('FR','CRT','Carteret','Carteret','50'),('FR','CRU','Cremieu','Cremieu','38'),('FR','CRV','Crevin','Crevin','35'),('FR','CRW','Chamberet','Chamberet','19'),('FR','CRX','Contrexeville','Contrexeville','88'),('FR','CRY','Cernay','Cernay','68'),('FR','CRZ','Courthezon','Courthezon','84'),('FR','CSA','Camaret-sur-Aigues','Camaret-sur-Aigues','84'),('FR','CSB','Celles-sur-Belle','Celles-sur-Belle','79'),('FR','CSC','Cousance','Cousance','39'),('FR','CSD','Creches-sur-Saone','Creches-sur-Saone','71'),('FR','CSE','Chatillon-sur-Chalaronne','Chatillon-sur-Chalaronne','01'),('FR','CSF','Les Clayes-sous-Bois','Les Clayes-sous-Bois','78'),('FR','CSG','Ciry-Salsogne','Ciry-Salsogne','02'),('FR','CSH','Conflans-Sainte-Honorine','Conflans-Sainte-Honorine','78'),('FR','CSI','Cosse-le-Vivien','Cosse-le-Vivien','53'),('FR','CSJ','Castries','Castries','34'),('FR','CSL','Chalette-sur-Loing','Chalette-sur-Loing','45'),('FR','CSM','Chalons-en-Champagne','Chalons-en-Champagne','51'),('FR','CSN','Carrieres-sur-Seine','Carrieres-sur-Seine','78'),('FR','CSO','Conques-sur-Orbiel','Conques-sur-Orbiel','11'),('FR','CSP','Carrieres-sous-Poissy','Carrieres-sous-Poissy','78'),('FR','CSQ','Cranves-Sales','Cranves-Sales','74'),('FR','CSR','Cousolre','Cousolre','59'),('FR','CSS','Chalon-sur-Saone','Chalon-sur-Saone','71'),('FR','CST','Custines','Custines','54'),('FR','CSU','La Chapelle-Saint-Aubin','La Chapelle-Saint-Aubin','72'),('FR','CSV','Cahuzac-sur-Vere','Cahuzac-sur-Vere','81'),('FR','CSX','Cuiseaux','Cuiseaux','71'),('FR','CSY','Croissy-sur-Seine','Croissy-sur-Seine','78'),('FR','CSZ','Craponne-sur-Arzon','Craponne-sur-Arzon','43'),('FR','CTA','Carentan','Carentan','50'),('FR','CTB','Cabestany','Cabestany','66'),('FR','CTC','Castelnaud-la-Chapelle','Castelnaud-la-Chapelle','24'),('FR','CTD','Chateaudun','Chateaudun','28'),('FR','CTE','Creteil','Creteil','94'),('FR','CTF','Confort','Confort','01'),('FR','CTG','Chateaubourg','Chateaubourg',''),('FR','CTH','Chateau-Thierry','Chateau-Thierry','02'),('FR','CTI','Catillon-Fumechon','Catillon-Fumechon','60'),('FR','CTJ','Chatillon','Chatillon','39'),('FR','CTK','Castellane','Castellane','04'),('FR','CTL','Chateaulin','Chateaulin','29'),('FR','CTM','La Chapelle-Saint-Martin','La Chapelle-Saint-Martin','73'),('FR','CTN','Castelsarrasin','Castelsarrasin','82'),('FR','CTO','Ceton','Ceton','61'),('FR','CTQ','Canteleu','Canteleu','76'),('FR','CTR','Chantereine','Chantereine','55'),('FR','CTS','Castillonnes','Castillonnes','47'),('FR','CTT','Le Castellet','Le Castellet','83'),('FR','CTU','Chatou','Chatou','78'),('FR','CTV','Chatillon','Chatillon','86'),('FR','CTW','Carnoet','Carnoet','22'),('FR','CTY','Castelnaudary','Castelnaudary','11'),('FR','CTZ','La Cote','La Cote','73'),('FR','CUA','Contamine-sur-Arve','Contamine-sur-Arve','74'),('FR','CUB','Cublize','Cublize','69'),('FR','CUC','Cuincy','Cuincy','59'),('FR','CUD','Caudan','Caudan','56'),('FR','CUE','Cuers','Cuers','83'),('FR','CUG','Cugnaux','Cugnaux','31'),('FR','CUH','Chatillon-sur-Thouet','Chatillon-sur-Thouet','79'),('FR','CUI','Cuisery','Cuisery','71'),('FR','CUJ','Chabeuil','Chabeuil','26'),('FR','CUL','Coulogne','Coulogne','62'),('FR','CUM','Cour-Cheverny','Cour-Cheverny','41'),('FR','CUN','Coueron','Coueron','44'),('FR','CUO','Coudes','Coudes','63'),('FR','CUP','Chateauponsac','Chateauponsac','87'),('FR','CUQ','Cuiry-les-Chaudardes','Cuiry-les-Chaudardes','02'),('FR','CUR','Couterne','Couterne','61'),('FR','CUS','Caussade','Caussade','82'),('FR','CUT','Courchelettes','Courchelettes','59'),('FR','CUU','Corvol-l\'Orgueilleux','Corvol-l\'Orgueilleux','58'),('FR','CUV','Coulanges-les-Nevers','Coulanges-les-Nevers','58'),('FR','CUX','Cobrieux','Cobrieux','59'),('FR','CUY','Cluny','Cluny','71'),('FR','CUZ','Culoz','Culoz','01'),('FR','CVA','Charleval','Charleval','27'),('FR','CVB','Charavines','Charavines','38'),('FR','CVC','Chevanceaux','Chevanceaux','17'),('FR','CVD','Chavanod','Chavanod','74'),('FR','CVE','Chaville','Chaville','92'),('FR','CVF','Courchevel','Courchevel','73'),('FR','CVG','Chauvigny','Chauvigny','86'),('FR','CVH','Cherves-Richemont','Cherves-Richemont','16'),('FR','CVI','Chanteloup-les-Vignes','Chanteloup-les-Vignes','78'),('FR','CVL','Champagne-en-Valromey','Champagne-en-Valromey','01'),('FR','CVM','Charleville','Charleville','51'),('FR','CVN','Chevagnes','Chevagnes','03'),('FR','CVO','Chambon-sur-Voueize','Chambon-sur-Voueize','23'),('FR','CVP','La Cavalerie','La Cavalerie','12'),('FR','CVQ','Cavan','Cavan','22'),('FR','CVR','Chevreuse','Chevreuse','78'),('FR','CVS','Celle-Levescault','Celle-Levescault','86'),('FR','CVT','Chavelot','Chavelot','88'),('FR','CVU','Courville-sur-Eure','Courville-sur-Eure','28'),('FR','CVV','St Clement-de-Riviere','St Clement-de-Riviere','34'),('FR','CVX','Chaumont-en-Vexin','Chaumont-en-Vexin','60'),('FR','CVY','Chevilly-Larue/Paris','Chevilly-Larue/Paris','94'),('FR','CVZ','Chavenay','Chavenay','78'),('FR','CWA','Cambrin','Cambrin','62'),('FR','CWO','Calvisson','Calvisson','30'),('FR','CXC','Caillac','Caillac','46'),('FR','CXD','Champenard','Champenard','27'),('FR','CXG','Ceaux-d\'Allegre','Ceaux-d\'Allegre','43'),('FR','CXL','Crolles','Crolles','38'),('FR','CXM','Chamonix-Mont-Blanc','Chamonix-Mont-Blanc','74'),('FR','CXN','Croix','Croix','59'),('FR','CXP','Carhaix-Plouguer','Carhaix-Plouguer','29'),('FR','CXR','Chavannes-sur-Reyssouze','Chavannes-sur-Reyssouze','01'),('FR','CXS','Chatillon-sur-Loire','Chatillon-sur-Loire','45'),('FR','CXT','Ceret','Ceret','66'),('FR','CXU','Charlieu','Charlieu','42'),('FR','CXV','Chatillon-le-Roi','Chatillon-le-Roi','45'),('FR','CXX','Colognac','Colognac','30'),('FR','CXZ','Corseul','Corseul','22'),('FR','CYA','Cheilly-les-Maranges','Cheilly-les-Maranges','71'),('FR','CYB','Colombey-les-Belles','Colombey-les-Belles','54'),('FR','CYC','Chevagny-les-Chevrieres','Chevagny-les-Chevrieres','71'),('FR','CYE','Crecy-sur-Serre','Crecy-sur-Serre','02'),('FR','CYF','Cuy-St-Fiacre','Cuy-St-Fiacre','76'),('FR','CYL','Chassey-les-Scey','Chassey-les-Scey','70'),('FR','CYM','Chilly-Mazarin','Chilly-Mazarin','91'),('FR','CYO','Champs-sur-Yonne','Champs-sur-Yonne','89'),('FR','CYP','Couilly-Pont-aux-Dames','Couilly-Pont-aux-Dames','77'),('FR','CYQ','Chauray','Chauray','79'),('FR','CYS','Chevigny-Saint-Sauveur','Chevigny-Saint-Sauveur','21'),('FR','CYT','Chambray-les-Tours','Chambray-les-Tours','37'),('FR','CYU','Creys-Mepieu','Creys-Mepieu','38'),('FR','CYX','Crissey','Crissey','71'),('FR','CYY','Champigny','Champigny','89'),('FR','CYZ','Ceyzeriat','Ceyzeriat','01'),('FR','CZA','Crezancy','Crezancy','02'),('FR','CZB','Chazey-Bons','Chazey-Bons','01'),('FR','CZE','Coarraze','Coarraze','64'),('FR','CZG','Civrieux-d\'Azergues','Civrieux-d\'Azergues','69'),('FR','CZI','Courzieu','Courzieu','69'),('FR','CZL','Chazelles-sur-Lyon','Chazelles-sur-Lyon','42'),('FR','CZM','Couzon-au-Mont-d\'Or','Couzon-au-Mont-d\'Or','69'),('FR','CZN','Crozon','Crozon','29'),('FR','CZO','Cuzorn','Cuzorn','47'),('FR','CZR','Creuzier-le-Neuf','Creuzier-le-Neuf','03'),('FR','CZS','Cazals','Cazals','46'),('FR','CZT','Cebazat','Cebazat','63'),('FR','CZU','Chalezeule','Chalezeule','25'),('FR','CZY','Cerizay','Cerizay','79'),('FR','DAE','Domagne','Domagne','35'),('FR','DAG','Daignac','Daignac','33'),('FR','DAM','Dammartin-sur-Meuse','Dammartin-sur-Meuse','52'),('FR','DAO','Daours','Daours','80'),('FR','DAR','Darney','Darney','88'),('FR','DAT','Damiatte','Damiatte','81'),('FR','DAX','Dax','Dax','40'),('FR','DAY','Dardilly','Dardilly','69'),('FR','DAZ','Chazay-d\'Azergues','Chazay-d\'Azergues','69'),('FR','DBA','Deuil-la-Barre','Deuil-la-Barre','95'),('FR','DBG','Dol-de-Bretagne','Dol-de-Bretagne','35'),('FR','DBL','Louvigne-de-Bais','Louvigne-de-Bais','35'),('FR','DBS','Doubs','Doubs','25'),('FR','DBV','Dambach-la-Ville','Dambach-la-Ville','67'),('FR','DCA','St-Denis-de-Cabanne','St-Denis-de-Cabanne','42'),('FR','DCL','Cordes-sur-Ciel','Cordes-sur-Ciel','81'),('FR','DCN','Dorceau','Dorceau','61'),('FR','DCO','St-Andre-de-Corcy','St-Andre-de-Corcy','01'),('FR','DCR','Dannemarie-sur-Crete','Dannemarie-sur-Crete','25'),('FR','DCT','Descartes','Descartes','37'),('FR','DCY','Drancy','Drancy','93'),('FR','DCZ','Decize','Decize','58'),('FR','DDF','Pont-de-Roide','Pont-de-Roide','25'),('FR','DDV','Dordives','Dordives','45'),('FR','DEA','Bedenac','Bedenac','17'),('FR','DEB','Doucy-en-Bauges','Doucy-en-Bauges','73'),('FR','DEC','Decines-Charpieu','Decines-Charpieu','69'),('FR','DEL','Delle','Delle','90'),('FR','DEM','Demouville','Demouville','14'),('FR','DEN','Denain','Denain','59'),('FR','DEP','Dammarie-en-Puisaye','Dammarie-en-Puisaye','45'),('FR','DER','Derval','Derval','44'),('FR','DES','Deols','Deols','36'),('FR','DGE','Dinge','Dinge','35'),('FR','DGL','Daglan','Daglan','24'),('FR','DGN','Digne','Digne','04'),('FR','DGO','Digoin','Digoin','71'),('FR','DGS','Dourges','Dourges','62'),('FR','DGT','Doingt','Doingt','80'),('FR','DGX','Dagneux','Dagneux','01'),('FR','DHL','D\'Huison-Longueville','D\'Huison-Longueville','91'),('FR','DHM','Duppigheim','Duppigheim','67'),('FR','DHU','Dhuisy','Dhuisy','77'),('FR','DID','Saint-Didier-sur-Chalaronne','Saint-Didier-sur-Chalaronne','01'),('FR','DIE','Die','Die','26'),('FR','DII','Dirinon','Dirinon','29'),('FR','DIJ','Dijon','Dijon','21'),('FR','DIL','Dielette','Dielette','50'),('FR','DIM','Dinsheim','Dinsheim','67'),('FR','DIN','Divonne-les-Bains','Divonne-les-Bains','01'),('FR','DIU','Villedieu-les-Poeles','Villedieu-les-Poeles','50'),('FR','DJU','Danjoutin','Danjoutin','90'),('FR','DJX','Donjeux','Donjeux','57'),('FR','DKK','Dunkerque','Dunkerque','59'),('FR','DLD','Douvres-la-Delivrande','Douvres-la-Delivrande','14'),('FR','DLE','Dole','Dole','39'),('FR','DLF','Doue-la-Fontaine','Doue-la-Fontaine','49'),('FR','DLL','Dammarie-les-Lys','Dammarie-les-Lys','77'),('FR','DLO','Dompierre-les-Ormes','Dompierre-les-Ormes','71'),('FR','DLR','Deville-les-Rouen','Deville-les-Rouen','76'),('FR','DLS','St-Sauveur-des-Landes','St-Sauveur-des-Landes','35'),('FR','DLT','Dieulefit','Dieulefit','26'),('FR','DLV','Delivrance/Lille','Delivrance/Lille','59'),('FR','DMA','Dommartin','Dommartin','80'),('FR','DMB','Dommary-Baroncourt','Dommary-Baroncourt','55'),('FR','DME','Dammarie','Dammarie','28'),('FR','DMI','Damblain','Damblain','88'),('FR','DML','Dom-le-Mesnil','Dom-le-Mesnil','08'),('FR','DMN','Domont','Domont','95'),('FR','DMO','Deulemont','Deulemont','59'),('FR','DMP','Dompierre-sur-Mont','Dompierre-sur-Mont','39'),('FR','DMR','St-Didier-au-Mont-d\'Or','St-Didier-au-Mont-d\'Or','69'),('FR','DMS','Dormans','Dormans','51'),('FR','DMU','St Denis-des-Murs','St Denis-des-Murs','87'),('FR','DMY','Daumeray','Daumeray','49'),('FR','DNA','Merdrignac','Merdrignac','22'),('FR','DNE','Lardenne','Lardenne','31'),('FR','DNG','Diebling','Diebling','57'),('FR','DNM','Dannemarie','Dannemarie',''),('FR','DNN','Dinan','Dinan','22'),('FR','DNR','Dinard','Dinard','35'),('FR','DNS','Dannes','Dannes','62'),('FR','DNY','Dugny-sur-Meuse','Dugny-sur-Meuse','55'),('FR','DOA','Dourdan','Dourdan','91'),('FR','DOC','Docelles','Docelles','88'),('FR','DOF','Domfront','Domfront','61'),('FR','DOI','Douai','Douai','59'),('FR','DOJ','Domjean','Domjean','50'),('FR','DOL','Deauville','Deauville','14'),('FR','DOM','Domene','Domene','38'),('FR','DON','Donges','Donges','44'),('FR','DOR','Dornecy','Dornecy','58'),('FR','DOS','Diors','Diors','36'),('FR','DOT','Dorat','Dorat','63'),('FR','DOU','Douvaine','Douvaine','74'),('FR','DOY','Donchery','Donchery','08'),('FR','DPE','Dieppe','Dieppe','76'),('FR','DPH','Dompierre-sur-Helpe','Dompierre-sur-Helpe','59'),('FR','DPS','Damparis','Damparis','39'),('FR','DRA','Draguignan','Draguignan','83'),('FR','DRC','Drocourt','Drocourt','62'),('FR','DRE','Dreux','Dreux','28'),('FR','DRN','Drulingen','Drulingen','67'),('FR','DRS','Les Adrets','Les Adrets','38'),('FR','DRU','Drusenheim','Drusenheim','67'),('FR','DRV','Duravel','Duravel','46'),('FR','DRZ','Douarnenez','Douarnenez','29'),('FR','DSA','Simandre-sur-Suran','Simandre-sur-Suran','01'),('FR','DSB','Dompierre-sur-Besbre','Dompierre-sur-Besbre','49'),('FR','DSC','Dissay-sous-Courcillon','Dissay-sous-Courcillon','72'),('FR','DSD','Domnon-les-Dieuze','Domnon-les-Dieuze','57'),('FR','DSI','Dreuil-les-Amiens','Dreuil-les-Amiens','80'),('FR','DSL','Dasle','Dasle','25'),('FR','DSM','Dives-sur-Mer','Dives-sur-Mer','14'),('FR','DSO','Doulaincourt-Saucourt','Doulaincourt-Saucourt','52'),('FR','DSS','Dampierre','Dampierre',''),('FR','DSV','Domevre-sur-Vezouze','Domevre-sur-Vezouze','54'),('FR','DSX','St-Didier-sur-Beaujeu','St-Didier-sur-Beaujeu','69'),('FR','DTE','Distre','Distre','49'),('FR','DTH','St-Donat-sur-l\'Herbasse','St-Donat-sur-l\'Herbasse','26'),('FR','DTL','Durtol','Durtol','63'),('FR','DTM','Duttlenheim','Duttlenheim','67'),('FR','DTO','Distroff','Distroff','57'),('FR','DUB','St-Andre-du-Bois','St-Andre-du-Bois','33'),('FR','DUC','Ducey','Ducey','50'),('FR','DUG','Dugny','Dugny','93'),('FR','DUL','Doullens','Doullens','80'),('FR','DUR','Durtal','Durtal','49'),('FR','DUV','Duvy','Duvy','60'),('FR','DVE','Dienville','Dienville','10'),('FR','DVI','Damville','Damville','27'),('FR','DVL','Deville','Deville','08'),('FR','DVN','Dolving','Dolving','57'),('FR','DVR','Douvrin','Douvrin','62'),('FR','DVY','Dissay','Dissay','86'),('FR','DWV','Cairanne','Cairanne','84'),('FR','DXA','Les Deux Alpes','Les Deux Alpes','38'),('FR','DXO','St Laurent-Medoc','St Laurent-Medoc','33'),('FR','DYA','Serdinya','Serdinya','66'),('FR','DYL','Dracy-Saint-Loup','Dracy-Saint-Loup','71'),('FR','DYR','St Medard-d\'Eyrans','St Medard-d\'Eyrans','33'),('FR','DYY','Dizy','Dizy','51'),('FR','DZA','Damazan','Damazan','47'),('FR','DZC','Douzillac','Douzillac','24'),('FR','DZD','Deneze-sous-Doue','Deneze-sous-Doue','49'),('FR','DZE','Dieuze','Dieuze','57'),('FR','DZS','Dossenheim-sur-Zinsel','Dossenheim-sur-Zinsel','67'),('FR','DZV','Decazeville','Decazeville','12'),('FR','DZX','Davezieux','Davezieux','07'),('FR','DZY','Donzy','Donzy','58'),('FR','EAI','Benais','Benais','37'),('FR','EAL','Leval','Leval','90'),('FR','EAN','Etain','Etain','55'),('FR','EAR','Etang-sur-Arroux','Etang-sur-Arroux','71'),('FR','EAT','Ecole-Valentin','Ecole-Valentin','25'),('FR','EAU','Chevreaux','Chevreaux','39'),('FR','EAX','Chenonceaux','Chenonceaux','37'),('FR','EAY','Bretteville-sur-Ay','Bretteville-sur-Ay','50'),('FR','EAZ','Eauze','Eauze','32'),('FR','EBA','Bellebat','Bellebat','33'),('FR','EBF','Elbeuf','Elbeuf','76'),('FR','EBG','Bebing','Bebing','57'),('FR','EBH','Eckbolsheim','Eckbolsheim','67'),('FR','EBL','Le Breuil','Le Breuil','51'),('FR','EBM','Ebblinghem','Ebblinghem','59'),('FR','EBO','Salleboeuf','Salleboeuf','33'),('FR','EBS','Etrembieres','Etrembieres','74'),('FR','EBU','Saint-Etienne','Saint-Etienne','42'),('FR','EBY','Erbray','Erbray','44'),('FR','ECA','L\'Escarene','L\'Escarene','06'),('FR','ECB','Crevecoeur-en-Brie','Crevecoeur-en-Brie','77'),('FR','ECE','Eecke','Eecke','59'),('FR','ECF','Echauffour','Echauffour','61'),('FR','ECH','Echirolles','Echirolles','38'),('FR','ECI','Ecuelles','Ecuelles','77'),('FR','ECL','Les Echelles','Les Echelles','73'),('FR','ECN','Echenon','Echenon','21'),('FR','ECO','Ecommoy','Ecommoy','72'),('FR','ECR','St-Seurin-de-Cadourne','St-Seurin-de-Cadourne','33'),('FR','ECS','Escalquens','Escalquens','31'),('FR','ECT','Exincourt','Exincourt','25'),('FR','ECU','Ecouen','Ecouen','95'),('FR','ECX','Echenevex','Echenevex','01'),('FR','ECY','Ecully','Ecully','69'),('FR','EDC','Ludon-Medoc','Ludon-Medoc','33'),('FR','EDM','La Roche-sur-Yon','La Roche-sur-Yon','85'),('FR','EDN','Edern','Edern','29'),('FR','EDO','St-Etienne-d\'Orthe','St-Etienne-d\'Orthe','40'),('FR','EDU','Dieulouard','Dieulouard','54'),('FR','EDY','Brelidy','Brelidy','22'),('FR','EEC','St Etienne-en-Cogles','St Etienne-en-Cogles','35'),('FR','EEE','Ernee','Ernee','53'),('FR','EES','Sees','Sees','61'),('FR','EET','Benet','Benet','85'),('FR','EEW','Ennetieres-en-Weppes','Ennetieres-en-Weppes','59'),('FR','EEY','Esternay','Esternay','51'),('FR','EGC','Bergerac','Bergerac','24'),('FR','EGE','Labege','Labege','31'),('FR','EGI','Ergue-Gaberic','Ergue-Gaberic','29'),('FR','EGM','Eguzon-Chantome','Eguzon-Chantome','36'),('FR','EGN','Veigne','Veigne','37'),('FR','EGO','Egletons','Egletons','19'),('FR','EGS','Eguilles','Eguilles','13'),('FR','EGU','Eguisheim','Eguisheim','68'),('FR','EGY','Eguilly','Eguilly','21'),('FR','EHE','La Lechere','La Lechere','73'),('FR','EHI','Einsisheim','Einsisheim','68'),('FR','EHN','Le Chesne','Le Chesne','08'),('FR','EHS','Esches','Esches','60'),('FR','EHU','Ercheu','Ercheu','80'),('FR','EIC','Vern-sur-Seiche','Vern-sur-Seiche','35'),('FR','EIE','Retiers','Retiers','35'),('FR','EIL','Mareuil','Mareuil','46'),('FR','EIM','Herrlisheim-pres-Colmar','Herrlisheim-pres-Colmar','68'),('FR','EIV','St Etienne-la-Varenne','St Etienne-la-Varenne','69'),('FR','ELA','Elancourt','Elancourt','78'),('FR','ELB','Enghien-les-Bains','Enghien-les-Bains','95'),('FR','ELD','Mesland','Mesland','41'),('FR','ELG','Essigny-le-Grand','Essigny-le-Grand','02'),('FR','ELI','Sellieres','Sellieres','39'),('FR','ELL','Epiais-les-Louvres','Epiais-les-Louvres','95'),('FR','ELN','Elne','Elne','66'),('FR','ELO','St Etienne-les-Orgues','St Etienne-les-Orgues','04'),('FR','ELR','Les Essarts-le-Roi','Les Essarts-le-Roi','78'),('FR','ELS','Etaples','Etaples','62'),('FR','ELT','Meaulte','Meaulte','80'),('FR','ELU','Pelussin','Pelussin','43'),('FR','ELV','Belves','Belves','24'),('FR','ELY','Eloyes','Eloyes','88'),('FR','EME','Blesme','Blesme','51'),('FR','EML','Embermenil','Embermenil','54'),('FR','EMO','Le Montet','Le Montet','03'),('FR','EMS','Les Mesnuls','Les Mesnuls','78'),('FR','EMT','Eulmont','Eulmont','54'),('FR','EMV','Emerainville','Emerainville','77'),('FR','ENA','Genay','Genay','70'),('FR','ENC','Nancy','Nancy','54'),('FR','ENG','Les Angles','Les Angles','66'),('FR','ENI','Ensisheim','Ensisheim','68'),('FR','ENL','Vernassal','Vernassal','43'),('FR','ENN','Ennery','Ennery','57'),('FR','ENR','Laboissiere-en-Santerre','Laboissiere-en-Santerre','80'),('FR','ENT','Entrammes','Entrammes','53'),('FR','ENV','Envermeu','Envermeu','76'),('FR','ENX','Entraigues-sur-la-Sorgue','Entraigues-sur-la-Sorgue','84'),('FR','ENY','Senailly','Senailly','21'),('FR','EOC','Belleroche','Belleroche','42'),('FR','EOL','Verniolle','Verniolle','09'),('FR','EON','Saint-Pol-de-Leon','Saint-Pol-de-Leon','29'),('FR','EOR','Les Orres','Les Orres','05'),('FR','EOS','Epoisses','Epoisses','21'),('FR','EOV','Le Rove','Le Rove','13'),('FR','EOY','Belloy','Belloy','60'),('FR','EPA','Espalion','Espalion','12'),('FR','EPE','Epehy','Epehy','80'),('FR','EPG','Eterpigny','Eterpigny','80'),('FR','EPH','Saint-Estephe','Saint-Estephe','24'),('FR','EPI','Epierre','Epierre','73'),('FR','EPL','Epinal','Epinal','88'),('FR','EPN','Epernon','Epernon','28'),('FR','EPO','Epone','Epone','78'),('FR','EPR','Saint-Martin-sur-le-Pre','Saint-Martin-sur-le-Pre','51'),('FR','EPS','Epinay-sous-Senart','Epinay-sous-Senart','91'),('FR','EPT','Sept-Sorts','Sept-Sorts','77'),('FR','EPY','Epernay','Epernay','51'),('FR','EPZ','Epinouze','Epinouze','26'),('FR','EQL','Equilly','Equilly','50'),('FR','EQQ','Esquelbecq','Esquelbecq','59'),('FR','EQS','Estrees','Estrees','59'),('FR','EQV','Ecquevilly','Ecquevilly','78'),('FR','ERC','Ercuis','Ercuis','60'),('FR','ERD','Senard','Senard','55'),('FR','ERE','Mere','Mere','78'),('FR','ERG','Le Rouget','Le Rouget','15'),('FR','ERI','Meriel','Meriel','95'),('FR','ERL','Erquinghem-Lys','Erquinghem-Lys','59'),('FR','ERM','Ermont','Ermont','95'),('FR','ERN','Erstein','Erstein','67'),('FR','ERO','Berson','Berson','33'),('FR','ERS','Erquinghem-le-Sec','Erquinghem-le-Sec','59'),('FR','ERT','Saint-Just-Saint-Rambert','Saint-Just-Saint-Rambert','42'),('FR','ERU','Meru','Meru','60'),('FR','ERV','Eurville','Eurville','52'),('FR','ERX','Erce','Erce','09'),('FR','ERZ','Chery-les-Rozoy','Chery-les-Rozoy','02'),('FR','ESA','Les Abrets','Les Abrets','38'),('FR','ESB','Esbly','Esbly','77'),('FR','ESC','Eschau','Eschau','67'),('FR','ESD','Estrees-Saint-Denis','Estrees-Saint-Denis','60'),('FR','ESE','Messein','Messein','54'),('FR','ESF','Escrennes','Escrennes','45'),('FR','ESG','Les Gets','Les Gets','74'),('FR','ESI','Pressins','Pressins','38'),('FR','ESN','Conde-sur-Noireau','Conde-sur-Noireau','14'),('FR','ESO','Eragny','Eragny','95'),('FR','ESQ','Esquieze-Sere','Esquieze-Sere','65'),('FR','ESR','Etoile-sur-Rhone','Etoile-sur-Rhone','26'),('FR','ESS','Epinay-sur-Seine','Epinay-sur-Seine','93'),('FR','EST','Estissac','Estissac','10'),('FR','ESU','Lescun','Lescun','64'),('FR','ESV','Esvres','Esvres','37'),('FR','ESY','Esquennoy','Esquennoy','60'),('FR','ETB','Berre-l\'Etang','Berre-l\'Etang','13'),('FR','ETF','Petit-Fayt','Petit-Fayt','39'),('FR','ETG','Estagel','Estagel','66'),('FR','ETI','Etival-Clairefontaine','Etival-Clairefontaine','88'),('FR','ETL','Estillac','Estillac','47'),('FR','ETM','Etampes','Etampes','91'),('FR','ETO','Etrochey','Etrochey','21'),('FR','ETP','Etupes','Etupes','25'),('FR','ETR','Etrechy','Etrechy','91'),('FR','ETS','L\'Etoile','L\'Etoile','80'),('FR','ETV','Estivareilles','Estivareilles',''),('FR','ETX','Etigny','Etigny','89'),('FR','ETY','Etrepagny','Etrepagny','27'),('FR','EUE','Beguey','Beguey','33'),('FR','EUG','St-Eugene','St-Eugene','17'),('FR','EUH','Eu','Eu','76'),('FR','EUS','Saint-Eusebe','Saint-Eusebe','71'),('FR','EUX','Lesseux','Lesseux','88'),('FR','EVA','Evisa','Evisa','2A'),('FR','EVE','Sevenans','Sevenans','90'),('FR','EVG','Le Vigan','Le Vigan','46'),('FR','EVI','Evian-les-Bains','Evian-les-Bains','74'),('FR','EVL','Ennevelin','Ennevelin','59'),('FR','EVN','Elven','Elven','56'),('FR','EVO','Evron','Evron','53'),('FR','EVR','Evry','Evry','91'),('FR','EVS','Evette-Salbert','Evette-Salbert','90'),('FR','EVU','Einvaux','Einvaux','54'),('FR','EVX','Evreux','Evreux','27'),('FR','EVZ','St Evarzec','St Evarzec','29'),('FR','EXD','Excideuil','Excideuil','24'),('FR','EYA','Alenya','Alenya','66'),('FR','EYC','Bengy-sur-Craon','Bengy-sur-Craon','18'),('FR','EYG','Eygalieres','Eygalieres','13'),('FR','EYI','Eymoutiers','Eymoutiers','87'),('FR','EYL','Eycheil','Eycheil','09'),('FR','EYN','Eybens','Eybens','38'),('FR','EYO','Epinay-sur-Orge','Epinay-sur-Orge','91'),('FR','EYR','Eygurande','Eygurande','19'),('FR','EYS','Eysines','Eysines','33'),('FR','EYU','Eyragues','Eyragues','13'),('FR','EZE','Meze','Meze','34'),('FR','EZG','Metzing','Metzing','57'),('FR','EZI','Entzheim','Entzheim','67'),('FR','EZT','Ennezat','Ennezat','63'),('FR','EZY','Cezy','Cezy','89'),('FR','FAC','Facture','Facture','33'),('FR','FAG','Fagnieres','Fagnieres','51'),('FR','FAN','Frasne','Frasne','25'),('FR','FAR','Faremoutiers','Faremoutiers','77'),('FR','FAS','Falaise','Falaise','14'),('FR','FAV','Faverges','Faverges','74'),('FR','FBU','Fontainebleau','Fontainebleau','77'),('FR','FBY','Folembray','Folembray','02'),('FR','FCA','Lafrancaise','Lafrancaise','82'),('FR','FCE','Flacheres','Flacheres','38'),('FR','FCH','Fechain','Fechain','59'),('FR','FCI','Francin','Francin','73'),('FR','FCJ','La Fleche','La Fleche','72'),('FR','FCN','Fontanil-Cornillon','Fontanil-Cornillon','38'),('FR','FCS','Froncles','Froncles','52'),('FR','FCT','Fremecourt','Fremecourt','95'),('FR','FCX','Flers-en-Escrebieux','Flers-en-Escrebieux','59'),('FR','FDC','Froideconche','Froideconche','70'),('FR','FDN','Fleville-devant-Nancy','Fleville-devant-Nancy','54'),('FR','FDO','Fours','Fours','33'),('FR','FDS','Fondettes','Fondettes','37'),('FR','FDU','Ferdrupt','Ferdrupt','88'),('FR','FEA','Ferrieres-en-Gatinais ','Ferrieres-en-Gatinais ','45'),('FR','FEC','Fecamp','Fecamp','76'),('FR','FEE','Fresse','Fresse','70'),('FR','FEG','Fegersheim','Fegersheim','67'),('FR','FEI','Feillens','Feillens','01'),('FR','FEN','Fenouillet','Fenouillet','31'),('FR','FER','Fervaques','Fervaques','14'),('FR','FES','Fresnes/Paris','Fresnes/Paris','94'),('FR','FET','Fere-en-Tardenois','Fere-en-Tardenois','02'),('FR','FEU','Feurs','Feurs','42'),('FR','FEV','Ferney-Voltaire','Ferney-Voltaire','01'),('FR','FEY','Feyzin','Feyzin','69'),('FR','FFD','Forstfeld','Forstfeld','67'),('FR','FFI','Froidefontaine','Froidefontaine','90'),('FR','FFO','Fayl-la-Foret','Fayl-la-Foret','52'),('FR','FFU','Pfaffenheim','Pfaffenheim','68'),('FR','FGA','Figeac','Figeac','46'),('FR','FGE','Froges','Froges','38'),('FR','FGH','Fargues-Saint-Hilaire','Fargues-Saint-Hilaire','33'),('FR','FGM','Freyming-Merlebach','Freyming-Merlebach','57'),('FR','FGN','Feignies','Feignies','59'),('FR','FHB','Fourchambault','Fourchambault','58'),('FR','FIL','Fillinges','Fillinges','74'),('FR','FIM','St-Firmin','St-Firmin','71'),('FR','FIV','Flere-la-Riviere','Flere-la-Riviere','36'),('FR','FIY','Firminy','Firminy','42'),('FR','FLA','Fleury-les-Aubrais','Fleury-les-Aubrais','45'),('FR','FLB','Fouquieres-les-Bethune','Fouquieres-les-Bethune','62'),('FR','FLC','Fesches-le-Chatel','Fesches-le-Chatel','25'),('FR','FLD','Fontaine-les-Dijon','Fontaine-les-Dijon','21'),('FR','FLE','Flers','Flers','61'),('FR','FLG','Florange','Florange','57'),('FR','FLI','La Faloise','La Faloise','80'),('FR','FLK','Floirac','Floirac','33'),('FR','FLL','Fouquieres-les-Lens','Fouquieres-les-Lens','62'),('FR','FLM','Faumont','Faumont','59'),('FR','FLO','Floirac','Floirac','46'),('FR','FLP','Fresney-le-Puceux','Fresney-le-Puceux','14'),('FR','FLR','Fleurie','Fleurie','69'),('FR','FLS','Fislis','Fislis','68'),('FR','FLU','Fleurance','Fleurance','32'),('FR','FLV','Fontenay-le-Vicomte','Fontenay-le-Vicomte','91'),('FR','FLX','Forges-les-Eaux','Forges-les-Eaux','76'),('FR','FLY','Fleury-sur-Andelle','Fleury-sur-Andelle','27'),('FR','FME','Formerie','Formerie','60'),('FR','FMI','Faches-Thumesnil','Faches-Thumesnil','59'),('FR','FMK','Fameck','Fameck','57'),('FR','FMO','Fresse-sur-Moselle','Fresse-sur-Moselle','88'),('FR','FNA','Fondamente','Fondamente','12'),('FR','FNF','Fontenay-le-Fleury','Fontenay-le-Fleury','78'),('FR','FNI','Nimes','Nimes','30'),('FR','FNN','Fronton','Fronton','31'),('FR','FNO','Franois','Franois','25'),('FR','FNS','Flins','Flins','78'),('FR','FNT','Fontaine','Fontaine','90'),('FR','FNV','Fontvieille','Fontvieille','13'),('FR','FOC','Fontenay-le-Comte','Fontenay-le-Comte','85'),('FR','FOE','Fosse','Fosse','41'),('FR','FOG','Foug','Foug','54'),('FR','FOH','Fougueyrolles','Fougueyrolles','24'),('FR','FOI','Foix','Foix','09'),('FR','FOL','Folschviller','Folschviller','57'),('FR','FON','Fontaine-les-Luxeuil','Fontaine-les-Luxeuil','70'),('FR','FOP','Fontaine-le-Port','Fontaine-le-Port','77'),('FR','FOR','Forbach','Forbach','57'),('FR','FOS','Fos-sur-Mer','Fos-sur-Mer','13'),('FR','FOT','Fontenay-Tresigny','Fontenay-Tresigny','77'),('FR','FOU','Fougeres','Fougeres','35'),('FR','FOV','Fontevraud-l\'Abbaye','Fontevraud-l\'Abbaye','49'),('FR','FOW','Fournes-en-Weppes','Fournes-en-Weppes','59'),('FR','FOY','Sainte-Foy-l\'Argentiere','Sainte-Foy-l\'Argentiere','69'),('FR','FPB','Pont-de-Buis-les-Quimerch','Pont-de-Buis-les-Quimerch','29'),('FR','FPO','Frepillon','Frepillon','95'),('FR','FQM','Faulquemont','Faulquemont','57'),('FR','FQR','Feuquieres','Feuquieres','60'),('FR','FQS','Ferques','Ferques','62'),('FR','FQU','Flocques','Flocques','76'),('FR','FRA','Franqueville','Franqueville',''),('FR','FRC','Fere-Champenoise','Fere-Champenoise','51'),('FR','FRE','Fressenneville','Fressenneville','80'),('FR','FRI','Frais','Frais','90'),('FR','FRJ','Frejus','Frejus','83'),('FR','FRM','Fourmies','Fourmies','59'),('FR','FRN','Frontenaud','Frontenaud','71'),('FR','FRO','Frontignan','Frontignan','34'),('FR','FRS','Foreste','Foreste','02'),('FR','FRV','Fronville','Fronville','52'),('FR','FRX','La Fere','La Fere','02'),('FR','FRY','Fresnoy-le-Grand','Fresnoy-le-Grand','02'),('FR','FRZ','Fraize','Fraize','88'),('FR','FSC','Figari','Figari','2A'),('FR','FSE','Fontenay-sur-Eure','Fontenay-sur-Eure','28'),('FR','FSI','Flassans-sur-Issole','Flassans-sur-Issole','83'),('FR','FSM','Fismes','Fismes','51'),('FR','FSN','Friesen','Friesen','68'),('FR','FSR','Freistroff','Freistroff','57'),('FR','FSS','Fontaines-sur-Saone','Fontaines-sur-Saone','69'),('FR','FTG','Fenetrange','Fenetrange','57'),('FR','FTI','Felletin','Felletin','23'),('FR','FTN','Fontenay','Fontenay','76'),('FR','FTO','Fontaine-sur-Somme','Fontaine-sur-Somme','80'),('FR','FTP','Fontpedrouse','Fontpedrouse','66'),('FR','FTS','Les Fontinettes','Les Fontinettes','62'),('FR','FTT','Feytiat','Feytiat','87'),('FR','FTX','Frontenex','Frontenex','73'),('FR','FTY','Fontoy','Fontoy','57'),('FR','FUA','Fouras','Fouras','17'),('FR','FUI','Fuisse','Fuisse','72'),('FR','FUM','Fumel','Fumel','47'),('FR','FUO','Fouilloy','Fouilloy','80'),('FR','FUR','Furiani','Furiani','2A'),('FR','FUS','Fouesnant','Fouesnant','29'),('FR','FVA','Freteval','Freteval','41'),('FR','FVC','Frevin-Capelle','Frevin-Capelle','62'),('FR','FVI','Feuquieres-en-Vimeu','Feuquieres-en-Vimeu','80'),('FR','FVL','Faverolles','Faverolles','80'),('FR','FVN','Fontaine-les-Vervins','Fontaine-les-Vervins','02'),('FR','FVO','Faverolles','Faverolles','28'),('FR','FVR','Farschviller','Farschviller','57'),('FR','FVY','Flevy','Flevy','57'),('FR','FXN','Fixin','Fixin','22'),('FR','FXS','Fleurieux-sur-L\'Arbresle','Fleurieux-sur-L\'Arbresle','69'),('FR','FXU','Flixecourt','Flixecourt','80'),('FR','FXV','Francheville','Francheville','27'),('FR','FYB','Fontenay-sous-Bois','Fontenay-sous-Bois','94'),('FR','FYO','Fontenoy-sur-Moselle','Fontenoy-sur-Moselle','54'),('FR','FYR','Foulayronnes','Foulayronnes','47'),('FR','FYS','Fontenay-aux-Roses','Fontenay-aux-Roses','92'),('FR','GAA','Gaillac-d\'Aveyron','Gaillac-d\'Aveyron','12'),('FR','GAC','Gace','Gace','61'),('FR','GAD','Gaillard','Gaillard','74'),('FR','GAE','Gaye','Gaye','51'),('FR','GAI','Gaillon','Gaillon','27'),('FR','GAL','Galgon','Galgon','33'),('FR','GAM','Gambais','Gambais','78'),('FR','GAN','Gannat','Gannat','03'),('FR','GAR','Gargenville','Gargenville','78'),('FR','GAS','Gassin','Gassin','83'),('FR','GAT','Gap','Gap','05'),('FR','GAU','Gauchy','Gauchy','02'),('FR','GAY','Gasny','Gasny','27'),('FR','GAZ','Saint-Andre-le-Gaz','Saint-Andre-le-Gaz','38'),('FR','GBC','Grandpuits Bailly Carrois','Grandpuits Bailly Carrois','77'),('FR','GBF','Grosbliederstroff','Grosbliederstroff','57'),('FR','GBM','Granges-les-Beaumont','Granges-les-Beaumont','26'),('FR','GCD','Guiscard','Guiscard','60'),('FR','GCE','Garches','Garches','92'),('FR','GCF','Gagnac-sur-Cere','Gagnac-sur-Cere','46'),('FR','GCH','Guichen','Guichen','35'),('FR','GCI','Goncelin','Goncelin','38'),('FR','GCL','Le Grand Celland','Le Grand Celland','50'),('FR','GCM','Grand Champ','Grand Champ','56'),('FR','GCO','Genicourt','Genicourt','95'),('FR','GCR','La Grand Croix','La Grand Croix','42'),('FR','GCS','Gamaches','Gamaches','80'),('FR','GCT','Gondecourt','Gondecourt','59'),('FR','GCV','Guichainville','Guichainville','27'),('FR','GCY','Gercy','Gercy','02'),('FR','GDA','Le Grau-d\'Agde','Le Grau-d\'Agde','34'),('FR','GDB','St Gildas des Bois','St Gildas des Bois',''),('FR','GDE','Gardanne','Gardanne','13'),('FR','GDM','La Grande-Motte','La Grande-Motte','34'),('FR','GDO','Gourdon','Gourdon','46'),('FR','GDR','Grand-Rozoy','Grand-Rozoy','02'),('FR','GDS','Grande-Synthe','Grande-Synthe','59'),('FR','GDV','Grandvillars','Grandvillars','90'),('FR','GDY','Lugon-et-l\'Ile-du-Carnay','Lugon-et-l\'Ile-du-Carnay','33'),('FR','GEA','Grenay','Grenay','62'),('FR','GEC','Gevrey-Chambertin','Gevrey-Chambertin','21'),('FR','GEE','Gieres','Gieres','38'),('FR','GEI','St-Genies','St-Genies','24'),('FR','GEL','Genlis','Genlis','21'),('FR','GEM','Gemenos','Gemenos','13'),('FR','GEN','Genas','Genas','69'),('FR','GEO','Genouillac','Genouillac','23'),('FR','GER','Gerardmer','Gerardmer','88'),('FR','GES','Geispolsheim','Geispolsheim','67'),('FR','GET','Geneston','Geneston','44'),('FR','GEU','Saint-Forgeux','Saint-Forgeux','69'),('FR','GEV','Ste-Genevieve','Ste-Genevieve','60'),('FR','GEX','Gex','Gex','01'),('FR','GEZ','Gemozac','Gemozac','17'),('FR','GFC','Graffigny-Chemin','Graffigny-Chemin','52'),('FR','GFR','Granville','Granville','50'),('FR','GFY','Gif-sur-Yvette','Gif-sur-Yvette','91'),('FR','GGC','St Georges-d\'Aurac','St Georges-d\'Aurac','43'),('FR','GGG','St-Georges-d\'Orques','St-Georges-d\'Orques',''),('FR','GGN','Gignac','Gignac',''),('FR','GGS','Guilherand-Granges','Guilherand-Granges','07'),('FR','GGV','Gigondas','Gigondas','84'),('FR','GGY','Gagny','Gagny','93'),('FR','GHM','Gambsheim','Gambsheim','67'),('FR','GIC','Gilocourt','Gilocourt','60'),('FR','GIE','Gien','Gien','45'),('FR','GIG','Gigean','Gigean','34'),('FR','GIL','Guillac','Guillac','33'),('FR','GIN','Giens','Giens','83'),('FR','GIR','Gironde-sur-Dropt','Gironde-sur-Dropt','33'),('FR','GIS','Givors','Givors','69'),('FR','GIT','Giat','Giat','63'),('FR','GIV','Givet','Givet','08'),('FR','GIY','Grigny','Grigny','69'),('FR','GIZ','Giez','Giez','74'),('FR','GJX','Saint-Germain-les-Arpajon','Saint-Germain-les-Arpajon','91'),('FR','GLA','Les Angles','Les Angles','30'),('FR','GLB','La Guerche sur l\'Aubois','La Guerche sur l\'Aubois','18'),('FR','GLC','Gondrecourt-le-Chateau','Gondrecourt-le-Chateau','55'),('FR','GLD','Gallardon','Gallardon','28'),('FR','GLE','Gilles','Gilles','28'),('FR','GLG','Garges-les-Gonesse','Garges-les-Gonesse','95'),('FR','GLH','Graulhet','Graulhet','81'),('FR','GLI','Glisy','Glisy','80'),('FR','GLJ','Glere','Glere','25'),('FR','GLL','Grandvilliers','Grandvilliers','60'),('FR','GLN','Grez-sur-Loing','Grez-sur-Loing','77'),('FR','GLO','Gonfreville-l\'Orcher','Gonfreville-l\'Orcher','76'),('FR','GLR','Bourg-la-Reine','Bourg-la-Reine','92'),('FR','GLS','Glos','Glos','14'),('FR','GLU','Gonfreville-Caillot','Gonfreville-Caillot','76'),('FR','GLV','Gruchet-le-Valasse','Gruchet-le-Valasse','76'),('FR','GLY','Egly','Egly','91'),('FR','GLZ','Gigors-et-Lozeron','Gigors-et-Lozeron','26'),('FR','GMA','Gramat','Gramat','46'),('FR','GMI','Germaine','Germaine','51'),('FR','GMP','Guemene-Penfao','Guemene-Penfao','44'),('FR','GMS','Gujan-Mestras','Gujan-Mestras','33'),('FR','GMT','Guillemont','Guillemont','80'),('FR','GMU','Bogny-sur-Meuse','Bogny-sur-Meuse','08'),('FR','GMX','Gemeaux','Gemeaux','21'),('FR','GNA','Generac','Generac','33'),('FR','GNB','Grenoble','Grenoble','38'),('FR','GNC','Gensac-la-Pallue','Gensac-la-Pallue','16'),('FR','GNE','Solgne','Solgne','57'),('FR','GNI','Sainte-Genevieve','Sainte-Genevieve','02'),('FR','GNN','Garennes-sur-Eure','Garennes-sur-Eure','27'),('FR','GNO','Genolhac','Genolhac','30'),('FR','GNQ','Soulignac','Soulignac','33'),('FR','GNS','St Gratien','St Gratien','80'),('FR','GNT','Magnet','Magnet','03'),('FR','GNU','Guignicourt','Guignicourt','02'),('FR','GNV','Gainneville','Gainneville','76'),('FR','GNY','Grigny','Grigny','91'),('FR','GNZ','Genay','Genay','21'),('FR','GOA','Guerande','Guerande','44'),('FR','GOC','Lagorce','Lagorce','07'),('FR','GOD','Les Gonds','Les Gonds','17'),('FR','GOG','Gorges','Gorges','44'),('FR','GOH','Gonnehem','Gonnehem','62'),('FR','GOL','Golbey','Golbey','88'),('FR','GON','St Gereon','St Gereon','44'),('FR','GOP','Gond-Pontouvre','Gond-Pontouvre','16'),('FR','GOR','Gorcy','Gorcy','54'),('FR','GOS','Groisy','Groisy','74'),('FR','GOT','Gareoult','Gareoult','83'),('FR','GOU','Gourin','Gourin','56'),('FR','GOV','Gondreville','Gondreville',''),('FR','GOX','Gouvieux','Gouvieux','60'),('FR','GOY','Gournay-en-Bray','Gournay-en-Bray','76'),('FR','GPI','St-Leger-le-Petit','St-Leger-le-Petit','18'),('FR','GPS','Gespunsart','Gespunsart','08'),('FR','GPY','Guipry','Guipry','35'),('FR','GQN','Grostenquin','Grostenquin','57'),('FR','GRA','Gretz-Armainvilliers','Gretz-Armainvilliers','77'),('FR','GRC','Grand-Couronne','Grand-Couronne','76'),('FR','GRD','Gardonne','Gardonne','24'),('FR','GRE','Guillotiere/Lyon','Guillotiere/Lyon','69'),('FR','GRG','Gradignan','Gradignan','33'),('FR','GRL','Grivy-Loisy','Grivy-Loisy','08'),('FR','GRM','St-Geours-de-Maremne','St-Geours-de-Maremne','40'),('FR','GRO','Gron','Gron','89'),('FR','GRP','Le Grand-Pressigny','Le Grand-Pressigny','37'),('FR','GRR','Lagrauliere','Lagrauliere','19'),('FR','GRS','Grasse','Grasse','06'),('FR','GRT','Groissiat','Groissiat','01'),('FR','GRU','Grisy-Suisnes','Grisy-Suisnes','77'),('FR','GRV','Gravelines','Gravelines','59'),('FR','GRX','Greux','Greux','88'),('FR','GRY','Gray','Gray','70'),('FR','GRZ','Gerzat','Gerzat','63'),('FR','GSA','Gresy-sur-Aix','Gresy-sur-Aix','73'),('FR','GSB','St-Georges-les-Bains','St-Georges-les-Bains','07'),('FR','GSC','Genissac','Genissac','33'),('FR','GSI','Gosselming','Gosselming','57'),('FR','GSL','Grisolles','Grisolles','82'),('FR','GSN','St-Gervais-les-Bains','St-Gervais-les-Bains','74'),('FR','GSO','Bligny-sur-Ouche','Bligny-sur-Ouche','21'),('FR','GSR','Gisors','Gisors','27'),('FR','GST','Gastins','Gastins','77'),('FR','GSU','Morsang-sur-Seine','Morsang-sur-Seine','91'),('FR','GSV','Goussainville','Goussainville','95'),('FR','GTE','Gattieres','Gattieres','06'),('FR','GTI','Getigne','Getigne','44'),('FR','GTL','Gestel','Gestel','56'),('FR','GTR','Argentre','Argentre','53'),('FR','GTS','Le Gault-Soigny','Le Gault-Soigny','51'),('FR','GTT','Argentat','Argentat','19'),('FR','GTV','Gudmont-Villiers','Gudmont-Villiers','52'),('FR','GTY','Gentilly','Gentilly','94'),('FR','GUA','Guenange','Guenange','57'),('FR','GUC','Guyancourt','Guyancourt','78'),('FR','GUD','Guidel','Guidel','56'),('FR','GUE','Gueret','Gueret','23'),('FR','GUG','Gueugnon','Gueugnon','71'),('FR','GUI','Guingamp','Guingamp','22'),('FR','GUL','Guillaucourt','Guillaucourt','80'),('FR','GUM','Guimerville','Guimerville','76'),('FR','GUN','Guesnain','Guesnain','59'),('FR','GUQ','Guerlesquin','Guerlesquin','29'),('FR','GUR','Gauriac','Gauriac','33'),('FR','GUS','Guise','Guise','02'),('FR','GUY','Guerigny','Guerigny','58'),('FR','GVE','Grivillers','Grivillers','80'),('FR','GVI','Grentheville','Grentheville','14'),('FR','GVL','Gennevilliers','Gennevilliers','92'),('FR','GVO','Gasville-Oiseme','Gasville-Oiseme','28'),('FR','GVS','Gievres','Gievres','41'),('FR','GVT','Gavet','Gavet','38'),('FR','GVY','Gravigny','Gravigny','27'),('FR','GVZ','Geveze','Geveze','35'),('FR','GWB','Guebwiller','Guebwiller','68'),('FR','GXA','Gondrexange','Gondrexange','57'),('FR','GXE','Guenrouet','Guenrouet','44'),('FR','GXZ','St Maurice-en-Gourgois','St Maurice-en-Gourgois','42'),('FR','GYA','Magny','Magny','28'),('FR','GYC','St Geyrac','St Geyrac','24'),('FR','GYE','Germigny-l\'Eveque','Germigny-l\'Eveque',''),('FR','GYG','Savigny-sur-Orge','Savigny-sur-Orge','91'),('FR','GYM','Gevigney-et-Mercey','Gevigney-et-Mercey','70'),('FR','GYR','Montigny-le-Roi','Montigny-le-Roi','52'),('FR','GYU','Augy','Augy','89'),('FR','GZA','Baons-le-Comte','Baons-le-Comte','76'),('FR','GZC','Gouzeaucourt','Gouzeaucourt','59'),('FR','GZE','Gazeran','Gazeran','78'),('FR','GZL','Grezillac','Grezillac','33'),('FR','GZN','Gouzon','Gouzon','23'),('FR','GZS','Grezes','Grezes','24'),('FR','GZY','Gizy','Gizy','02'),('FR','HAA','Chalamont','Chalamont','01'),('FR','HAB','Chablis','Chablis','89'),('FR','HAE','Hagondange','Hagondange','57'),('FR','HAG','Haguenau','Haguenau','67'),('FR','HAH','Habsheim','Habsheim','68'),('FR','HAI','Haironville','Haironville','55'),('FR','HAL','Halluin','Halluin','59'),('FR','HAM','Ham','Ham','80'),('FR','HAN','Cachan','Cachan','94'),('FR','HAS','Hasnon','Hasnon','59'),('FR','HAU','Haubourdin','Haubourdin','59'),('FR','HAX','Haux','Haux','33'),('FR','HBC','Herbignac','Herbignac','44'),('FR','HBD','Hombourg-Budange','Hombourg-Budange','57'),('FR','HBH','Hambach','Hambach','57'),('FR','HBI','Chambourg-sur-Indre','Chambourg-sur-Indre','37'),('FR','HBV','Heudebouville','Heudebouville','27'),('FR','HCC','Hauconcourt','Hauconcourt','57'),('FR','HCI','Chatillon-en-Michaille','Chatillon-en-Michaille','01'),('FR','HCO','Herimoncourt','Herimoncourt','25'),('FR','HCT','Hericourt','Hericourt','70'),('FR','HCU','Hennecourt','Hennecourt','88'),('FR','HDI','Chamandrin','Chamandrin','05'),('FR','HDN','Chadenet','Chadenet','48'),('FR','HDP','Hardelot-Plage','Hardelot-Plage','62'),('FR','HEA','Cherac','Cherac','17'),('FR','HEB','Henin-Beaumont','Henin-Beaumont','62'),('FR','HEC','Hecmanville','Hecmanville','27'),('FR','HEI','Heimsbrunn','Heimsbrunn','68'),('FR','HEL','Hellemmes-Lille','Hellemmes-Lille','59'),('FR','HEN','Hendaye','Hendaye','64'),('FR','HER','Herouville','Herouville','95'),('FR','HES','Hesdin','Hesdin','62'),('FR','HET','Hennebont','Hennebont','56'),('FR','HEU','Theuley','Theuley','70'),('FR','HEY','Chessy','Chessy','77'),('FR','HEZ','Chezy-sur-Marne','Chezy-sur-Marne','02'),('FR','HFN','Hochfelden','Hochfelden','67'),('FR','HGA','Le Houga','Le Houga','32'),('FR','HGB','Hangenbieten','Hangenbieten','67'),('FR','HGG','Heiligenberg','Heiligenberg','67'),('FR','HGM','Hargarten-aux-Mines','Hargarten-aux-Mines','57'),('FR','HGO','Hargicourt','Hargicourt','80'),('FR','HGU','Hodeng-au-Bosc','Hodeng-au-Bosc','76'),('FR','HHB','Hallennes-lez-Haubourdin','Hallennes-lez-Haubourdin','59'),('FR','HHG','Herserange','Herserange','54'),('FR','HHM','Hegenheim','Hegenheim','68'),('FR','HIN','Chinon','Chinon','37'),('FR','HIR','Hirson','Hirson','02'),('FR','HIS','Chapareillan','Chapareillan','38'),('FR','HIX','Hinx','Hinx','40'),('FR','HIY','Chierry','Chierry','02'),('FR','HJQ','Humes-Jorquenay','Humes-Jorquenay','52'),('FR','HLA','Chalais','Chalais','16'),('FR','HLC','Husseren-les-Chateaux','Husseren-les-Chateaux','68'),('FR','HLE','Houilles','Houilles','78'),('FR','HLI','Hundling','Hundling','57'),('FR','HLL','La Haillan','La Haillan','33'),('FR','HLM','Le Houlme','Le Houlme','76'),('FR','HLN','Hillion','Hillion','22'),('FR','HLO','Chatillon-sur-Saone','Chatillon-sur-Saone','88'),('FR','HLR','Holacourt','Holacourt','57'),('FR','HLS','Houplines','Houplines','59'),('FR','HLT','Houlgate','Houlgate','14'),('FR','HLV','Chateau-la-Valliere','Chateau-la-Valliere','37'),('FR','HLY','Chevilly','Chevilly','45'),('FR','HLZ','St-Hilaire-de-Riez','St-Hilaire-de-Riez','85'),('FR','HMA','Hattmatt','Hattmatt','67'),('FR','HMO','Chevremont','Chevremont','90'),('FR','HMS','Hermies','Hermies','62'),('FR','HMT','Hautmont','Hautmont','59'),('FR','HMU','Homecourt','Homecourt','54'),('FR','HNI','Cheniers','Cheniers','23'),('FR','HNM','Chantemerle','Chantemerle','51'),('FR','HNO','Chaumont-sur-Tharonne','Chaumont-sur-Tharonne','41'),('FR','HNS','Henansal','Henansal','22'),('FR','HOA','Houplin-Ancoisne','Houplin-Ancoisne','59'),('FR','HOC','Chomerac','Chomerac','07'),('FR','HOE','Hoerdt','Hoerdt','67'),('FR','HON','Honfleur','Honfleur','14'),('FR','HOS','Hondschoote','Hondschoote','59'),('FR','HOU','Hourcade/Bordeaux','Hourcade/Bordeaux','33'),('FR','HOW','Horbourg-Wihr','Horbourg-Wihr','68'),('FR','HOY','Charmoy','Charmoy','52'),('FR','HPL','St-Hippolyte','St-Hippolyte','68'),('FR','HPO','St Hippolyte','St Hippolyte','33'),('FR','HPT','Chaponost','Chaponost','69'),('FR','HPY','Chipilly','Chipilly','80'),('FR','HRB','Herblay','Herblay','95'),('FR','HRC','Heric','Heric','44'),('FR','HRD','Le Chatelard','Le Chatelard','73'),('FR','HRF','Harfleur','Harfleur','76'),('FR','HRI','St-Hilaire-du-Rosier','St-Hilaire-du-Rosier','38'),('FR','HRN','Harnes','Harnes','62'),('FR','HRO','Hautecourt-Romaneche','Hautecourt-Romaneche','01'),('FR','HRR','Haute-Rivoire','Haute-Rivoire','69'),('FR','HRS','Hortes','Hortes','52'),('FR','HRT','Montpeyroux','Montpeyroux','34'),('FR','HRV','Herouville-Saint-Clair','Herouville-Saint-Clair','14'),('FR','HRX','Heyrieux','Heyrieux','38'),('FR','HSB','Hieres-sur-Amby','Hieres-sur-Amby','38'),('FR','HSG','Hossegor','Hossegor','40'),('FR','HSM','Chennevieres-sur-Marne','Chennevieres-sur-Marne','94'),('FR','HSN','Le Theil-sur-Huisne','Le Theil-sur-Huisne','61'),('FR','HSO','Chatonrupt-Sommermont','Chatonrupt-Sommermont','52'),('FR','HSP','Chasseneuil-du-Poitou','Chasseneuil-du-Poitou','86'),('FR','HSS','Haussimont','Haussimont','51'),('FR','HST','Charost','Charost','18'),('FR','HSU','Hery-sur-Ugines','Hery-sur-Ugines','73'),('FR','HTA','Hettange-Grande','Hettange-Grande','57'),('FR','HTE','Hitte','Hitte','65'),('FR','HTH','Holtzheim','Holtzheim','67'),('FR','HTM','Chateaumeillant','Chateaumeillant','18'),('FR','HTN','Huttenheim','Huttenheim','67'),('FR','HTO','Hattencourt','Hattencourt','80'),('FR','HTP','Chatelaillon-Plage','Chatelaillon-Plage','17'),('FR','HTR','Le Chateau-d\'Oleron','Le Chateau-d\'Oleron','17'),('FR','HTS','Chatres','Chatres','77'),('FR','HTY','Chatelguyon','Chatelguyon','63'),('FR','HTZ','Hatrize','Hatrize','54'),('FR','HUI','Huisseau-sur-Cosson','Huisseau-sur-Cosson','41'),('FR','HUM','Humieres','Humieres','62'),('FR','HUN','Huningue','Huningue','68'),('FR','HUS','Chaourse','Chaourse','02'),('FR','HVE','Chevannes','Chevannes','21'),('FR','HVO','Chevillon','Chevillon','89'),('FR','HVR','Chevrieres','Chevrieres','60'),('FR','HVS','Chavannes-sur-Suran','Chavannes-sur-Suran','01'),('FR','HYA','Hayange','Hayange','57'),('FR','HYB','Haybes','Haybes','08'),('FR','HYO','Chemilly-sur-Yonne','Chemilly-sur-Yonne','89'),('FR','HYR','Hyeres','Hyeres','83'),('FR','HYT','Hymont','Hymont','88'),('FR','HYX','Achy','Achy','60'),('FR','HZB','Hazebrouck','Hazebrouck','59'),('FR','IAC','Archiac','Archiac','17'),('FR','IAN','St-Martial-sur-Ne','St-Martial-sur-Ne','17'),('FR','IAS','Millas','Millas','66'),('FR','IAT','Polliat','Polliat','01'),('FR','IAU','Aigues-Mortes','Aigues-Mortes','30'),('FR','IAV','St-Savinien','St-Savinien','17'),('FR','IAY','Mionnay','Mionnay','01'),('FR','IBL','Miribel','Miribel','01'),('FR','IBS','Ibos','Ibos','65'),('FR','IBT','St Imbert','St Imbert','58'),('FR','IBU','Isigny-le-Buat','Isigny-le-Buat','50'),('FR','ICA','St-Ciers-Champagne','St-Ciers-Champagne','17'),('FR','ICB','St Vincent-en-Bresse','St Vincent-en-Bresse','71'),('FR','ICH','Chiche','Chiche','79'),('FR','ICO','Bricon','Bricon','52'),('FR','ICP','Siorac-en-Perigord','Siorac-en-Perigord','24'),('FR','ICT','Avricourt','Avricourt','57'),('FR','ICV','Incarville','Incarville','27'),('FR','ICY','Le Raincy','Le Raincy','93'),('FR','IDE','L\'Isle-d\'Espagnac','L\'Isle-d\'Espagnac','16'),('FR','IDR','Idron-Ousse-Sendets','Idron-Ousse-Sendets','64'),('FR','IEA','Inchy-en-Artois','Inchy-en-Artois','62'),('FR','IEN','Saint-Vivien','Saint-Vivien','17'),('FR','IER','Villers','Villers','88'),('FR','IES','Biesles','Biesles','52'),('FR','IEU','Saulieu','Saulieu','21'),('FR','IEY','Lirey','Lirey','10'),('FR','IFF','Iffendic','Iffendic','35'),('FR','IGA','Sigean','Sigean','11'),('FR','IGD','Ingrandes','Ingrandes','36'),('FR','IGE','Ige','Ige','71'),('FR','IGL','L\'Aigle','L\'Aigle','61'),('FR','IGN','Blaignan','Blaignan','33'),('FR','IGO','Avignonet','Avignonet','38'),('FR','IGR','La Batie-Montsaleon','La Batie-Montsaleon','05'),('FR','IGS','Ingrandes-sur-Loire','Ingrandes-sur-Loire','49'),('FR','IGU','La Brigue','La Brigue','06'),('FR','IGX','Ligueux','Ligueux','33'),('FR','IHM','Ingolsheim','Ingolsheim','67'),('FR','IKG','Illkirch-Graffenstaden','Illkirch-Graffenstaden','67'),('FR','ILA','Servon-sur-Vilaine','Servon-sur-Vilaine','35'),('FR','ILB','Ivry-la-Bataille','Ivry-la-Bataille','27'),('FR','ILC','Illiers-Combray','Illiers-Combray','28'),('FR','ILE','Lillers','Lillers','62'),('FR','ILL','Maillat','Maillat','01'),('FR','ILM','Issy-les-Moulineaux','Issy-les-Moulineaux','92'),('FR','ILN','Maillane','Maillane','13'),('FR','ILR','L\'Ile-Rousse','L\'Ile-Rousse','2B'),('FR','ILT','Villette','Villette','78'),('FR','ILZ','Illzach','Illzach','68'),('FR','IMH','Limersheim','Limersheim','67'),('FR','IMN','St Michel-de-Maurienne','St Michel-de-Maurienne','73'),('FR','IMO','Limours','Limours','91'),('FR','IMR','Simandre','Simandre','71'),('FR','IMS','Isles-les-Meldeuses','Isles-les-Meldeuses','77'),('FR','IMT','Limonest','Limonest','69'),('FR','INA','St-Aignan','St-Aignan','82'),('FR','INE','Saint-Martin-la-Plaine','Saint-Martin-la-Plaine','42'),('FR','ING','Ingre','Ingre','45'),('FR','INH','Ste Sigolene','Ste Sigolene','43'),('FR','INL','Inzinzac-Lochrist','Inzinzac-Lochrist','56'),('FR','INS','Salins-les-Bains','Salins-les-Bains','39'),('FR','INW','Ingwiller','Ingwiller','67'),('FR','INY','Linay','Linay','08'),('FR','ION','Brion','Brion','71'),('FR','IOS','St-Ours','St-Ours','63'),('FR','IOY','Igornay','Igornay','71'),('FR','IPC','Ispagnac','Ispagnac','48'),('FR','IPG','Ippling','Ippling','57'),('FR','IPH','Imphy','Imphy','58'),('FR','IPY','Liposthey','Liposthey','40'),('FR','IRE','Sainte-Luce-sur-Loire','Sainte-Luce-sur-Loire','44'),('FR','IRG','Irouleguy','Irouleguy','64'),('FR','IRI','Irigny','Irigny','69'),('FR','IRN','Beautiran','Beautiran','33'),('FR','IRT','Bissert','Bissert','67'),('FR','IRY','St Martin-des-Noyers','St Martin-des-Noyers','85'),('FR','ISA','Isola','Isola','06'),('FR','ISC','Ire-le-Sec','Ire-le-Sec','55'),('FR','ISD','Issoudun','Issoudun','36'),('FR','ISE','Isbergues','Isbergues','62'),('FR','ISL','Belle-Isle-en-Terre','Belle-Isle-en-Terre','22'),('FR','ISM','Isigny-sur-Mer','Isigny-sur-Mer','14'),('FR','ISS','Issoire','Issoire','63'),('FR','IST','Istres','Istres','13'),('FR','ITC','Itancourt','Itancourt','02'),('FR','ITO','Aiton','Aiton','73'),('FR','ITR','Ceintrey','Ceintrey','54'),('FR','ITT','Villette','Villette','73'),('FR','IUH','Illfurth','Illfurth','68'),('FR','IUT','St Mathieu','St Mathieu','87'),('FR','IVR','Bievres','Bievres','91'),('FR','IVS','Ivry-sur-Seine','Ivry-sur-Seine','94'),('FR','IVX','St Privat-des-Vieux','St Privat-des-Vieux','30'),('FR','IYA','Boissy-l\'Aillerie','Boissy-l\'Aillerie','95'),('FR','IYB','St Mars-la-Briere','St Mars-la-Briere','72'),('FR','IYR','Singleyrac','Singleyrac','24'),('FR','IYV','Montigny-les-Vesoul','Montigny-les-Vesoul','70'),('FR','IZA','Bize','Bize','65'),('FR','IZO','Izon','Izon','33'),('FR','IZR','Izernore','Izernore','01'),('FR','IZS','Izeste','Izeste','64'),('FR','IZY','Crisse','Crisse','72'),('FR','JAA','Jouy-aux-Arches','Jouy-aux-Arches','57'),('FR','JAG','St Jean-d\'Angely','St Jean-d\'Angely','17'),('FR','JAN','Janze','Janze','35'),('FR','JAR','Jarnac','Jarnac','16'),('FR','JAY','Jarny','Jarny','54'),('FR','JBF','St-Jean-de-Boeuf','St-Jean-de-Boeuf','21'),('FR','JBS','Jublains','Jublains','53'),('FR','JCE','Saint Just en Chaussee','Saint Just en Chaussee','60'),('FR','JCM','Jouy-sur-Morin','Jouy-sur-Morin','77'),('FR','JDM','Juigne-des-Moutiers','Juigne-des-Moutiers','44'),('FR','JDR','Jardres','Jardres','86'),('FR','JEB','Jebsheim','Jebsheim','68'),('FR','JEC','St-Just-en-Chaussee','St-Just-en-Chaussee','60'),('FR','JEU','Jeumont','Jeumont','59'),('FR','JGU','Jargeau','Jargeau','45'),('FR','JGY','Jeugny','Jeugny','10'),('FR','JIE','Juvigny-sous-Andaine','Juvigny-sous-Andaine','61'),('FR','JLI','St Julien','St Julien','88'),('FR','JLN','Julienas','Julienas','69'),('FR','JLP','Juan-les-Pins','Juan-les-Pins','06'),('FR','JLS','St Jean-Lasseille','St Jean-Lasseille','66'),('FR','JLV','St-Julien-la-Vetre','St-Julien-la-Vetre','42'),('FR','JLY','Juilly','Juilly','77'),('FR','JME','Jeanmenil','Jeanmenil','88'),('FR','JMO','St-Jean-de-Monts','St-Jean-de-Monts','85'),('FR','JMV','St-Jean-des-Mauvrets','St-Jean-des-Mauvrets','49'),('FR','JNE','Julienne','Julienne','16'),('FR','JNS','Jarnages','Jarnages','23'),('FR','JNV','Janville','Janville','28'),('FR','JNZ','Jonzac','Jonzac','17'),('FR','JOI','Joinville','Joinville','52'),('FR','JOS','Jons','Jons','01'),('FR','JQR','Jonquieres','Jonquieres','60'),('FR','JRN','Jarnac-Champagne','Jarnac-Champagne','17'),('FR','JRR','Jarrie','Jarrie','38'),('FR','JSN','Josselin','Josselin','56'),('FR','JSR','Jassans-Riottier','Jassans-Riottier','01'),('FR','JTS','Joue-les-Tours','Joue-les-Tours','37'),('FR','JUF','Joeuf','Joeuf','54'),('FR','JUL','Saint-Julien-du-Sault','Saint-Julien-du-Sault','89'),('FR','JUN','St Julien','St Julien','21'),('FR','JUS','Jussey','Jussey','70'),('FR','JUU','Jouarre','Jouarre','77'),('FR','JUV','Juvisy-sur-Orge','Juvisy-sur-Orge','91'),('FR','JUX','Jaux','Jaux','60'),('FR','JVR','Javron-les-Chapelles','Javron-les-Chapelles','53'),('FR','JYJ','Jouy-en-Josas','Jouy-en-Josas','78'),('FR','JYT','Juvigny-le-Tertre','Juvigny-le-Tertre','50'),('FR','JYV','Jonchery-sur-Vesle','Jonchery-sur-Vesle','51'),('FR','JZR','Juziers','Juziers','78'),('FR','KBG','Kaysersberg','Kaysersberg','68'),('FR','KCR','Kedange-sur-Canner','Kedange-sur-Canner','57'),('FR','KHM','Kingersheim','Kingersheim','68'),('FR','KKS','Keskastel','Keskastel','67'),('FR','KLS','Kilstett','Kilstett','67'),('FR','KNT','Knutange','Knutange','57'),('FR','KRA','Krafft','Krafft','67'),('FR','KUN','Kunheim','Kunheim','68'),('FR','KZG','Kuntzig','Kuntzig','57'),('FR','LAA','Lacalm','Lacalm','12'),('FR','LAB','La Bathie','La Bathie','73'),('FR','LAC','Lacq','Lacq','64'),('FR','LAD','L\'Ardoise','L\'Ardoise','30'),('FR','LAE','Lamastre','Lamastre','07'),('FR','LAF','La Farlede','La Farlede','83'),('FR','LAG','Lagnieu','Lagnieu','01'),('FR','LAH','La Creche','La Creche','79'),('FR','LAI','Lannion','Lannion','22'),('FR','LAL','Lalinde','Lalinde','24'),('FR','LAM','Lamanon','Lamanon','13'),('FR','LAN','Langres','Langres','52'),('FR','LAO','Laon','Laon','02'),('FR','LAP','La Chapelle-Saint-Ursin','La Chapelle-Saint-Ursin','18'),('FR','LAQ','Lambesc','Lambesc','13'),('FR','LAR','Les Arcs','Les Arcs','83'),('FR','LAS','Landas','Landas','59'),('FR','LAT','Lavelanet','Lavelanet','09'),('FR','LAU','Lauterbourg','Lauterbourg','67'),('FR','LAV','Lavera','Lavera','13'),('FR','LAX','L\'Arbresle','L\'Arbresle','69'),('FR','LAY','Les Andelys','Les Andelys','27'),('FR','LAZ','La Canourgue','La Canourgue','48'),('FR','LBA','La Balme-de-Sillingy','La Balme-de-Sillingy','74'),('FR','LBB','Le Bocasse','Le Bocasse','76'),('FR','LBC','Le Bouscat','Le Bouscat','33'),('FR','LBD','La Bassee','La Bassee','59'),('FR','LBE','La Brede','La Brede','33'),('FR','LBF','La Bruffiere','La Bruffiere','85'),('FR','LBG','Le Bourget Apt/Paris','Le Bourget Apt/Paris','93'),('FR','LBH','La Bohalle','La Bohalle','49'),('FR','LBI','Albi','Albi','81'),('FR','LBK','Le Blanc','Le Blanc','36'),('FR','LBL','Laborel','Laborel','26'),('FR','LBM','Le Blanc-Mesnil','Le Blanc-Mesnil','93'),('FR','LBN','Labenne','Labenne','40'),('FR','LBO','La Bocca','La Bocca','06'),('FR','LBP','Le Barp','Le Barp','33'),('FR','LBQ','Le Boucau','Le Boucau','64'),('FR','LBR','Labruguiere','Labruguiere','81'),('FR','LBS','La Bastide','La Bastide',''),('FR','LBT','Labatut-Riviere','Labatut-Riviere','65'),('FR','LBU','La Bruguiere','La Bruguiere','30'),('FR','LBV','Lamotte-Beuvron','Lamotte-Beuvron','41'),('FR','LBX','La Buisse','La Buisse','38'),('FR','LBY','La Baule','La Baule','44'),('FR','LBZ','La Brillanne','La Brillanne','04'),('FR','LCA','La Clayette','La Clayette','71'),('FR','LCB','La Chambre','La Chambre','73'),('FR','LCC','Listrac-Medoc','Listrac-Medoc','33'),('FR','LCD','La Chapelle d\'Armentieres','La Chapelle d\'Armentieres','59'),('FR','LCE','La Chataigneraie','La Chataigneraie','85'),('FR','LCF','Le Chambon-Feugerolles','Le Chambon-Feugerolles','42'),('FR','LCG','Lichtenberg','Lichtenberg','67'),('FR','LCH','La Chapelle/Paris','La Chapelle/Paris','75'),('FR','LCI','Lencloitre','Lencloitre','86'),('FR','LCJ','La Lechere','La Lechere','01'),('FR','LCK','La Chapelle-sur-Erdre','La Chapelle-sur-Erdre','44'),('FR','LCL','La Colle-sur-Loup','La Colle-sur-Loup','06'),('FR','LCM','La Chapelle-Saint-Mesmin','La Chapelle-Saint-Mesmin','45'),('FR','LCN','Le Chesnay/Paris','Le Chesnay/Paris','78'),('FR','LCO','La Courtine','La Courtine','23'),('FR','LCP','La Chapelle-sur-Loire','La Chapelle-sur-Loire','37'),('FR','LCQ','La Coquille','La Coquille','24'),('FR','LCR','Le Creusot','Le Creusot','71'),('FR','LCS','La Chapelle-en-Serval','La Chapelle-en-Serval','60'),('FR','LCT','La Ciotat','La Ciotat','13'),('FR','LCU','Lacaune','Lacaune','81'),('FR','LCV','La Courneuve','La Courneuve','93'),('FR','LCW','Lachapelle','Lachapelle','54'),('FR','LCX','Les Clavaux','Les Clavaux','38'),('FR','LCY','La Chapelle-de-Guinchay','La Chapelle-de-Guinchay','71'),('FR','LCZ','La Crau','La Crau','83'),('FR','LDA','Landaul','Landaul','56'),('FR','LDB','Laveline-devant-Bruyeres','Laveline-devant-Bruyeres','88'),('FR','LDC','Latour-de-Carol','Latour-de-Carol','66'),('FR','LDE','Lourdes','Lourdes','65'),('FR','LDG','St Laurent-des-Vignes','St Laurent-des-Vignes','24'),('FR','LDH','Landersheim','Landersheim','67'),('FR','LDL','Le Bourget-du-Lac','Le Bourget-du-Lac','73'),('FR','LDM','La Barre-de-Monts','La Barre-de-Monts','85'),('FR','LDN','Landerneau','Landerneau','29'),('FR','LDO','Ladon','Ladon','45'),('FR','LDP','La Grande-Paroisse','La Grande-Paroisse','77'),('FR','LDR','La Roche-de-Rame','La Roche-de-Rame','05'),('FR','LDS','Ludres','Ludres','54'),('FR','LDT','Ledat','Ledat','47'),('FR','LDU','Landerrouat','Landerrouat','33'),('FR','LDV','Landivisiau','Landivisiau','29'),('FR','LDX','Lavardac','Lavardac','47'),('FR','LDY','La Bastide-Puylaurent','La Bastide-Puylaurent','48'),('FR','LDZ','La Douze','La Douze','24'),('FR','LEA','Langeais','Langeais','37'),('FR','LEB','Le Boulou','Le Boulou','66'),('FR','LEC','Le Cannet','Le Cannet','06'),('FR','LED','Labastide-Murat','Labastide-Murat','46'),('FR','LEE','Leers','Leers','59'),('FR','LEF','Le Fayet','Le Fayet','74'),('FR','LEG','Loos-en-Gohelle','Loos-en-Gohelle','62'),('FR','LEH','Le Havre','Le Havre','76'),('FR','LEI','Le Chatelet-en-Brie','Le Chatelet-en-Brie','77'),('FR','LEJ','Le Genest-Saint-Isle','Le Genest-Saint-Isle','53'),('FR','LEK','Le Nouvion-en-Thierache','Le Nouvion-en-Thierache','02'),('FR','LEL','Le Luc','Le Luc','83'),('FR','LEM','Lembeye','Lembeye','64'),('FR','LEN','Lens','Lens','62'),('FR','LEO','Leognan','Leognan','33'),('FR','LEP','Le Passage','Le Passage','47'),('FR','LEQ','Lescar','Lescar','64'),('FR','LER','L\'Etrat','L\'Etrat','42'),('FR','LES','Lieusaint','Lieusaint','77'),('FR','LET','Levet','Levet','18'),('FR','LEU','Le Meux','Le Meux','60'),('FR','LEV','Les Pavillons-sous-Bois','Les Pavillons-sous-Bois','93'),('FR','LEW','Les Essarts-Varimpre','Les Essarts-Varimpre','76'),('FR','LEX','Lexy','Lexy','54'),('FR','LEY','Le Muy','Le Muy','83'),('FR','LEZ','Lezardrieux','Lezardrieux','22'),('FR','LFA','La Ferte-Saint-Aubin','La Ferte-Saint-Aubin','45'),('FR','LFB','La Ferte-Bernard','La Ferte-Bernard','72'),('FR','LFC','La Ferte-Mace','La Ferte-Mace','61'),('FR','LFE','Loge-Fougereuse','Loge-Fougereuse','85'),('FR','LFF','Liffre','Liffre','35'),('FR','LFG','La Ferte-Gaucher','La Ferte-Gaucher','77'),('FR','LFH','Lavaufranche','Lavaufranche','23'),('FR','LFI','Le Fuilet','Le Fuilet','49'),('FR','LFL','La Fleche','La Fleche','72'),('FR','LFN','La Ferte-Milon','La Ferte-Milon','02'),('FR','LFO','Le Fousseret','Le Fousseret','31'),('FR','LFR','Le Fret','Le Fret','29'),('FR','LFS','La Fossette','La Fossette','83'),('FR','LFT','Lafitte','Lafitte',''),('FR','LFU','La Fouillouse','La Fouillouse','42'),('FR','LFY','La Fresnaye-au-Sauvage','La Fresnaye-au-Sauvage','61'),('FR','LGA','La Gacilly','La Gacilly','56'),('FR','LGB','Savigny-les-Beaune','Savigny-les-Beaune','21'),('FR','LGC','La Gorce','La Gorce','23'),('FR','LGE','Lege','Lege',''),('FR','LGF','La Garde-Freinet','La Garde-Freinet','83'),('FR','LGG','La Gorgue','La Gorgue','59'),('FR','LGH','Lingolsheim','Lingolsheim','67'),('FR','LGI','Lorgies','Lorgies','62'),('FR','LGJ','Liergues','Liergues','69'),('FR','LGL','Longueil-Sainte-Marie','Longueil-Sainte-Marie','60'),('FR','LGM','Lagny-sur-Marne','Lagny-sur-Marne','77'),('FR','LGN','Livry-Gargan','Livry-Gargan','93'),('FR','LGO','Langogne','Langogne','48'),('FR','LGP','Le Grand-Lemps','Le Grand-Lemps','38'),('FR','LGQ','Le Grand-Quevilly','Le Grand-Quevilly','76'),('FR','LGR','Le Grau-du-Roi','Le Grau-du-Roi','30'),('FR','LGS','Longuenesse','Longuenesse','62'),('FR','LGT','La Genete','La Genete','71'),('FR','LGU','Le Guildo/Crehen','Le Guildo/Crehen','22'),('FR','LGV','Laigneville','Laigneville','60'),('FR','LGX','Langeac','Langeac','43'),('FR','LGY','Lagny','Lagny','60'),('FR','LGZ','Labergement-les-Seurre','Labergement-les-Seurre','21'),('FR','LHA','La Roche-Maurice','La Roche-Maurice','29'),('FR','LHB','Les Herbiers','Les Herbiers','85'),('FR','LHD','La Chaise Dieu','La Chaise Dieu',''),('FR','LHE','La Chapelle-Heulin','La Chapelle-Heulin','44'),('FR','LHF','La Haie-Fouassiere','La Haie-Fouassiere','42'),('FR','LHG','L\'Herbergement','L\'Herbergement','85'),('FR','LHM','L\'Hermitage','L\'Hermitage','35'),('FR','LHN','Lagarde-Hachan','Lagarde-Hachan','32'),('FR','LHO','L\'Horme','L\'Horme','42'),('FR','LHP','L\'Hospitalet-Pas-de-la-Case','L\'Hospitalet-Pas-de-la-Case','09'),('FR','LHR','Les Hautes-Rivieres','Les Hautes-Rivieres','08'),('FR','LHS','Louhans','Louhans','71'),('FR','LHU','La Roche-Clermault','La Roche-Clermault','37'),('FR','LHY','Labouheyre','Labouheyre','40'),('FR','LIA','L\'Isle-d\'Abeau','L\'Isle-d\'Abeau','38'),('FR','LIB','Libourne','Libourne','33'),('FR','LIC','Labastide D\'Armagnac','Labastide D\'Armagnac','40'),('FR','LID','La Bridoire','La Bridoire','73'),('FR','LIE','Lievin','Lievin','62'),('FR','LIF','Liffol-le-Grand','Liffol-le-Grand','88'),('FR','LIG','Limoges','Limoges','87'),('FR','LIH','Le Mont-Saint-Michel','Le Mont-Saint-Michel','50'),('FR','LII','Larouillies','Larouillies','59'),('FR','LIM','Limoux','Limoux','11'),('FR','LIN','Linselles','Linselles','59'),('FR','LIO','Lyon','Lyon','69'),('FR','LIP','Lipsheim','Lipsheim','67'),('FR','LIQ','Ligne','Ligne','44'),('FR','LIR','La Menitre','La Menitre','49'),('FR','LIS','L\'Isle-sur-la-Sorgue','L\'Isle-sur-la-Sorgue','84'),('FR','LIT','Lisle-sur-Tarn','Lisle-sur-Tarn','81'),('FR','LIU','Ligueux','Ligueux','24'),('FR','LIV','Lingreville','Lingreville','50'),('FR','LIX','Lisieux','Lisieux','14'),('FR','LIY','Laissey','Laissey','25'),('FR','LIZ','Linas','Linas','91'),('FR','LJD','La Jaudonniere','La Jaudonniere',''),('FR','LJH','Le Juch','Le Juch','29'),('FR','LJM','La Jumelliere','La Jumelliere','49'),('FR','LJN','L\'Isle-Jourdain','L\'Isle-Jourdain','32'),('FR','LJO','Lanuejouls','Lanuejouls','12'),('FR','LJR','La Jarne','La Jarne','17'),('FR','LJZ','Laujuzan','Laujuzan','32'),('FR','LKB','Le Kremlin-Bicetre','Le Kremlin-Bicetre','94'),('FR','LLA','Les Laumes','Les Laumes','21'),('FR','LLB','Les Lucs-sur-Boulogne','Les Lucs-sur-Boulogne','85'),('FR','LLC','Lassay-les-Chateaux','Lassay-les-Chateaux','53'),('FR','LLD','La Lande-sur-Drome','La Lande-sur-Drome','14'),('FR','LLE','Lille','Lille','59'),('FR','LLG','Le Legue','Le Legue','22'),('FR','LLI','Les Lilas','Les Lilas','93'),('FR','LLL','Lanhelin','Lanhelin','35'),('FR','LLM','Les Loges-Marchis','Les Loges-Marchis','50'),('FR','LLN','Le Landreau','Le Landreau','44'),('FR','LLO','La Longine','La Longine','70'),('FR','LLP','La Loupe','La Loupe','28'),('FR','LLQ','Lalbenque','Lalbenque','46'),('FR','LLS','Lons-le-Saunier','Lons-le-Saunier','39'),('FR','LLT','Le Val-Saint-Pere','Le Val-Saint-Pere','50'),('FR','LLU','Le Lude','Le Lude','72'),('FR','LLV','La Liviniere','La Liviniere','34'),('FR','LLX','Lussac-les-Chateaux','Lussac-les-Chateaux','86'),('FR','LLY','Le Tholy','Le Tholy','88'),('FR','LMA','La Madeleine','La Madeleine','59'),('FR','LMB','Lamballe','Lamballe','22'),('FR','LMC','Lesparre-Medoc','Lesparre-Medoc','33'),('FR','LMD','La Mede','La Mede','13'),('FR','LME','Le Mans','Le Mans','72'),('FR','LMF','Limeil-Brevannes','Limeil-Brevannes','94'),('FR','LMG','La Meilleraie-Tillay','La Meilleraie-Tillay','85'),('FR','LMH','Le Mele-sur-Sarthe','Le Mele-sur-Sarthe','61'),('FR','LMI','La Machine','La Machine','58'),('FR','LMJ','Le May-sur-Evre','Le May-sur-Evre','49'),('FR','LML','Les Milles','Les Milles','13'),('FR','LMM','La Monnerie-le Montel','La Monnerie-le Montel','63'),('FR','LMN','Laragne-Monteglin','Laragne-Monteglin','05'),('FR','LMO','Lormont','Lormont','33'),('FR','LMP','Lempdes','Lempdes','63'),('FR','LMQ','La Milesse','La Milesse','72'),('FR','LMR','Lumbres','Lumbres','62'),('FR','LMS','Le Mesnil','Le Mesnil','50'),('FR','LMT','La Motte','La Motte',''),('FR','LMU','Lamure-sur-Azergues','Lamure-sur-Azergues','69'),('FR','LMV','Lacapelle-Marival','Lacapelle-Marival','46'),('FR','LMW','La Maxe','La Maxe','57'),('FR','LMX','Les Mureaux','Les Mureaux','78'),('FR','LMY','Limay','Limay','78'),('FR','LMZ','Limetz-Villez','Limetz-Villez','78'),('FR','LNA','Lieu-Saint-Amand','Lieu-Saint-Amand','59'),('FR','LNC','Lancey','Lancey','38'),('FR','LND','Landiras','Landiras','33'),('FR','LNE','Lillebonne','Lillebonne','76'),('FR','LNG','Longueville-sur-Scie','Longueville-sur-Scie','76'),('FR','LNH','Lacanche','Lacanche','21'),('FR','LNI','Lonrai','Lonrai','61'),('FR','LNJ','Longjumeau','Longjumeau','91'),('FR','LNL','Langlade','Langlade','30'),('FR','LNN','Languenan','Languenan','22'),('FR','LNO','La Norville','La Norville','91'),('FR','LNP','Longpont','Longpont','02'),('FR','LNQ','Latronquiere','Latronquiere','46'),('FR','LNR','Liancourt','Liancourt','60'),('FR','LNS','Lanester','Lanester','56'),('FR','LNT','Lenoncourt','Lenoncourt','54'),('FR','LNU','Longuyon','Longuyon','54'),('FR','LNV','Longeville','Longeville','25'),('FR','LNX','Lancieux','Lancieux','22'),('FR','LNY','Lanvallay','Lanvallay','22'),('FR','LOA','Longueau','Longueau','80'),('FR','LOB','Lombers','Lombers','81'),('FR','LOC','Loctudy','Loctudy','29'),('FR','LOD','Loudun','Loudun','86'),('FR','LOE','Loivre','Loivre','51'),('FR','LOF','Lamothe-Fenelon','Lamothe-Fenelon','46'),('FR','LOG','Lognes','Lognes','77'),('FR','LOH','La Mothe-Saint-Heray','La Mothe-Saint-Heray','79'),('FR','LOI','L\'Oie','L\'Oie','85'),('FR','LOJ','Louan','Louan','77'),('FR','LOK','Locmine','Locmine','56'),('FR','LOL','Loison-sous-Lens','Loison-sous-Lens','62'),('FR','LOM','Lomme','Lomme','59'),('FR','LON','Longueville','Longueville','77'),('FR','LOO','Loon-Plage','Loon-Plage','59'),('FR','LOP','Lompret','Lompret','59'),('FR','LOQ','Lons','Lons','64'),('FR','LOR','Loriol-sur-Drome','Loriol-sur-Drome','26'),('FR','LOS','Loos','Loos','59'),('FR','LOT','Lorette','Lorette','42'),('FR','LOU','St Louis-de-Montferrand','St Louis-de-Montferrand','33'),('FR','LOV','Longvic','Longvic','21'),('FR','LOW','Loisy','Loisy','71'),('FR','LOX','Lonnes','Lonnes','16'),('FR','LOY','Longwy','Longwy','54'),('FR','LOZ','Lozanne','Lozanne','69'),('FR','LPA','La Poterie-Cap-d\'Antifer','La Poterie-Cap-d\'Antifer','76'),('FR','LPB','Le Plessis-Belleville','Le Plessis-Belleville','60'),('FR','LPC','La Planche','La Planche','44'),('FR','LPD','La Plaine-Saint-Denis','La Plaine-Saint-Denis','93'),('FR','LPE','La Pallice','La Pallice','17'),('FR','LPG','Le Puy','Le Puy','33'),('FR','LPH','La Penne-sur-Huveaune','La Penne-sur-Huveaune','13'),('FR','LPI','Lespinasse','Lespinasse','31'),('FR','LPL','Lapalisse','Lapalisse','03'),('FR','LPM','Le Pin-en-Mauges','Le Pin-en-Mauges','49'),('FR','LPN','Les-Pennes-Mirabeau','Les-Pennes-Mirabeau','13'),('FR','LPO','Le Pontet','Le Pontet','73'),('FR','LPP','L\'Hospitalet-pres-l\'Andorre','L\'Hospitalet-pres-l\'Andorre','09'),('FR','LPQ','Le Pecq/Paris','Le Pecq/Paris','78'),('FR','LPR','Le Puy-Sainte-Reparade','Le Puy-Sainte-Reparade','13'),('FR','LPS','Le Plessis-Robinson','Le Plessis-Robinson','92'),('FR','LPT','Levallois-Perret','Levallois-Perret','92'),('FR','LPU','Lapugnoy','Lapugnoy','62'),('FR','LPV','Liepvre','Liepvre','68'),('FR','LPW','Le Poet','Le Poet','05'),('FR','LPX','La Pernelle','La Pernelle','50'),('FR','LPY','Le Puy-en-Velay','Le Puy-en-Velay','43'),('FR','LPZ','Le Pouzin','Le Pouzin','07'),('FR','LQA','Le Mas-d\'Agenais','Le Mas-d\'Agenais','47'),('FR','LQL','Laqueuille','Laqueuille','63'),('FR','LQM','Laroque-d\'Olmes','Laroque-d\'Olmes','09'),('FR','LQO','Laroquebrou','Laroquebrou','15'),('FR','LQR','Les Quatre-Routes-du-Lot','Les Quatre-Routes-du-Lot','46'),('FR','LQS','Laval-sur-Vologne','Laval-sur-Vologne','88'),('FR','LQU','Les Attaques','Les Attaques','62'),('FR','LQV','Leuvrigny','Leuvrigny','51'),('FR','LQY','Limogne-en-Quercy','Limogne-en-Quercy','46'),('FR','LRA','Les Granges','Les Granges','10'),('FR','LRB','La Reole','La Reole','33'),('FR','LRC','Libercourt','Libercourt','62'),('FR','LRE','Lure','Lure','70'),('FR','LRF','La Roche-sur-Foron','La Roche-sur-Foron','74'),('FR','LRG','La Roche-de-Glun','La Roche-de-Glun','26'),('FR','LRH','La Rochelle','La Rochelle','17'),('FR','LRI','La Riche','La Riche','37'),('FR','LRJ','Solre-le-Chateau','Solre-le-Chateau','59'),('FR','LRL','Laboissiere-en-Thelle','Laboissiere-en-Thelle','60'),('FR','LRM','La Romieu','La Romieu','32'),('FR','LRN','Laure-Minervois','Laure-Minervois','11'),('FR','LRO','La Roche-Vineuse','La Roche-Vineuse','71'),('FR','LRP','La Rochepot','La Rochepot','21'),('FR','LRR','Le Garric','Le Garric','81'),('FR','LRS','Lorgues','Lorgues','83'),('FR','LRT','Lorient','Lorient','56'),('FR','LRU','La Rochefoucauld','La Rochefoucauld','16'),('FR','LRV','La Ravoire','La Ravoire','73'),('FR','LRX','Langeron','Langeron','58'),('FR','LRY','Lery','Lery',''),('FR','LRZ','Lor','Lor',''),('FR','LSA','Les Avenieres','Les Avenieres','38'),('FR','LSB','Les Billaux','Les Billaux','33'),('FR','LSC','Lansac','Lansac','46'),('FR','LSD','Livron-sur-Drome','Livron-sur-Drome','26'),('FR','LSE','Largeasse','Largeasse','79'),('FR','LSF','Ligny-Saint-Flochel','Ligny-Saint-Flochel','62'),('FR','LSG','Lusignan','Lusignan','86'),('FR','LSH','Les Cheres','Les Cheres','69'),('FR','LSI','La Charite-sur-Loire','La Charite-sur-Loire','58'),('FR','LSJ','La Sauve','La Sauve','33'),('FR','LSK','Lansargues','Lansargues','34'),('FR','LSL','La Chapelle-Saint-Luc','La Chapelle-Saint-Luc','10'),('FR','LSM','Les Mees','Les Mees','04'),('FR','LSN','Lacroix-Saint-Ouen','Lacroix-Saint-Ouen','60'),('FR','LSO','Les Sables-d\'Olonne','Les Sables-d\'Olonne','85'),('FR','LSP','Longpre-les-Corps-Saints','Longpre-les-Corps-Saints','80'),('FR','LSQ','Lesquin','Lesquin','59'),('FR','LSR','Lestrem','Lestrem','62'),('FR','LSS','Les Artigues-de-Lussac','Les Artigues-de-Lussac','33'),('FR','LST','Lastours','Lastours','11'),('FR','LSU','La Selle-en-Luitre','La Selle-en-Luitre','35'),('FR','LSV','La Chaussee-Saint-Victor','La Chaussee-Saint-Victor','41'),('FR','LSX','Laissac','Laissac','12'),('FR','LSY','Lassigny','Lassigny','60'),('FR','LSZ','La Roche-Bernard','La Roche-Bernard','56'),('FR','LTA','La Tour-d\'Aigues','La Tour-d\'Aigues','84'),('FR','LTB','Le Temple-de-Bretagne','Le Temple-de-Bretagne','44'),('FR','LTC','La Mothe-Achard','La Mothe-Achard','85'),('FR','LTD','La Talaudiere','La Talaudiere','42'),('FR','LTE','Le Pontet','Le Pontet','84'),('FR','LTF','Les Trois Fontaines','Les Trois Fontaines','08'),('FR','LTG','Le Tranger','Le Tranger','36'),('FR','LTH','Le Thillot','Le Thillot','88'),('FR','LTI','La Trinite','La Trinite','06'),('FR','LTJ','Le Teil','Le Teil','07'),('FR','LTL','Luce/Eure-et-Loir','Luce/Eure-et-Loir','28'),('FR','LTN','La Tronche','La Tronche','38'),('FR','LTO','Le Thor','Le Thor','84'),('FR','LTP','La Tour-du-Pin','La Tour-du-Pin','38'),('FR','LTQ','Le Touquet-Paris-Plage','Le Touquet-Paris-Plage','62'),('FR','LTR','Le Treport','Le Treport','76'),('FR','LTU','Le Coteau','Le Coteau','42'),('FR','LTV','La Batie-Neuve','La Batie-Neuve','05'),('FR','LTX','Labastide-Rouairoux','Labastide-Rouairoux','81'),('FR','LTY','Le Thillay','Le Thillay','95'),('FR','LTZ','Labrit','Labrit','40'),('FR','LUA','Le Mont-Dore','Le Mont-Dore','63'),('FR','LUB','Lubersac','Lubersac','19'),('FR','LUC','Lucon','Lucon','85'),('FR','LUD','Loudeac','Loudeac','22'),('FR','LUE','Luce','Luce','61'),('FR','LUF','Lussat','Lussat','63'),('FR','LUG','Lugny','Lugny','71'),('FR','LUH','La Guierche','La Guierche','72'),('FR','LUI','Lanouaille','Lanouaille','24'),('FR','LUK','Luceau','Luceau','72'),('FR','LUL','Les Ulis','Les Ulis','91'),('FR','LUM','Lumes','Lumes','08'),('FR','LUN','Lunel-Viel','Lunel-Viel','34'),('FR','LUO','La Couronne','La Couronne','16'),('FR','LUQ','Lugrin','Lugrin','74'),('FR','LUR','Luray','Luray','28'),('FR','LUS','Lusigny','Lusigny','03'),('FR','LUT','Luisant','Luisant','28'),('FR','LUU','Laudun','Laudun','30'),('FR','LUV','La Longueville','La Longueville','59'),('FR','LUX','Langueux','Langueux','22'),('FR','LUY','Lunay','Lunay','41'),('FR','LUZ','Luzenac','Luzenac','09'),('FR','LVA','Laval','Laval','53'),('FR','LVC','Louveciennes','Louveciennes','78'),('FR','LVD','Liverdun','Liverdun','54'),('FR','LVE','Le Verdon-sur-Mer','Le Verdon-sur-Mer','33'),('FR','LVF','Laverune','Laverune','34'),('FR','LVG','Les Vigneres','Les Vigneres','84'),('FR','LVH','Le Vaudreuil','Le Vaudreuil','27'),('FR','LVI','Laval (Isere)','Laval (Isere)','38'),('FR','LVL','Luneville','Luneville','54'),('FR','LVN','Le Vesinet','Le Vesinet','78'),('FR','LVO','La Voulte-sur-Rhone','La Voulte-sur-Rhone','07'),('FR','LVP','La Verpilliere','La Verpilliere','38'),('FR','LVQ','Le Vigan','Le Vigan','30'),('FR','LVR','Lavaur','Lavaur','81'),('FR','LVS','Louviers','Louviers','27'),('FR','LVT','Lavercantiere','Lavercantiere','46'),('FR','LVU','Laveur','Laveur',''),('FR','LVV','La Veuve','La Veuve','51'),('FR','LVX','Les Leves-et-Thoumeyragues','Les Leves-et-Thoumeyragues','33'),('FR','LVY','Laveyrune','Laveyrune','48'),('FR','LVZ','Le Vigen','Le Vigen','87'),('FR','LWA','Lavaur','Lavaur','24'),('FR','LWZ','La Wantzenau','La Wantzenau','67'),('FR','LXA','Le Perreux-sur-Marne','Le Perreux-sur-Marne','94'),('FR','LXB','Luxeuil-les-Bains','Luxeuil-les-Bains','70'),('FR','LXC','Le Cheylas','Le Cheylas','38'),('FR','LXD','Les Aix-d\'Angillon','Les Aix-d\'Angillon','18'),('FR','LXE','Lisses','Lisses','91'),('FR','LXI','Lavit','Lavit','82'),('FR','LXM','Liomer','Liomer','80'),('FR','LXP','Lachapelle-aux-Pots','Lachapelle-aux-Pots','60'),('FR','LXS','Ladoix Serrigny','Ladoix Serrigny','21'),('FR','LXV','La Croix-Valmer','La Croix-Valmer','83'),('FR','LXX','Liesse Notre Dame','Liesse Notre Dame','02'),('FR','LXY','Luynes','Luynes','37'),('FR','LYA','Lury-sur-Arnon','Lury-sur-Arnon','18'),('FR','LYB','L\'Ile Bouchard','L\'Ile Bouchard','37'),('FR','LYC','Lagny-le-Sec','Lagny-le-Sec','60'),('FR','LYD','Le Puy','Le Puy','25'),('FR','LYE','Lamorlaye','Lamorlaye','60'),('FR','LYG','Lignieres','Lignieres',''),('FR','LYI','Billy','Billy','03'),('FR','LYL','Lucenay-l\'Eveque','Lucenay-l\'Eveque','71'),('FR','LYM','Leyment','Leyment',''),('FR','LYN','Bron Apt/Lyon','Bron Apt/Lyon','69'),('FR','LYO','Lyons-la-Foret','Lyons-la-Foret','27'),('FR','LYP','La Haye-Pesnel','La Haye-Pesnel','50'),('FR','LYR','La Loyere','La Loyere','71'),('FR','LYS','Satolas Apt/Lyon','Satolas Apt/Lyon','69'),('FR','LYU','Lapeyrouse','Lapeyrouse','01'),('FR','LYV','Mailly-la-Ville','Mailly-la-Ville','89'),('FR','LYX','Lalley','Lalley','38'),('FR','LYY','Le Molay-Littry','Le Molay-Littry','14'),('FR','LYZ','Lisse','Lisse','47'),('FR','LZA','Labourse','Labourse','62'),('FR','LZC','Lezignan-Corbieres','Lezignan-Corbieres','11'),('FR','LZD','Loue','Loue','72'),('FR','LZE','Lezigne','Lezigne','49'),('FR','LZG','La Bazoche-Gouet','La Bazoche-Gouet','28'),('FR','LZH','Lutzelhouse','Lutzelhouse','67'),('FR','LZI','Lezinnes','Lezinnes','89'),('FR','LZM','Luzy-sur-Marne','Luzy-sur-Marne','52'),('FR','LZN','Lannemezan','Lannemezan','65'),('FR','LZO','Lizy-sur-Ourcq','Lizy-sur-Ourcq','77'),('FR','LZP','Les Ancizes-Comps','Les Ancizes-Comps','63'),('FR','LZS','Luzarches','Luzarches','95'),('FR','LZV','Luz-Saint-Sauveur','Luz-Saint-Sauveur','65'),('FR','LZX','Lezoux','Lezoux','63'),('FR','LZY','Lezay','Lezay','79'),('FR','LZZ','Lezat-sur-Leze','Lezat-sur-Leze','09'),('FR','MAA','Mariac','Mariac','07'),('FR','MAB','Maubourguet','Maubourguet','65'),('FR','MAC','Macon','Macon','71'),('FR','MAD','Manduel','Manduel','30'),('FR','MAE','Malloue','Malloue','14'),('FR','MAG','Magny-en-Vexin','Magny-en-Vexin','95'),('FR','MAH','Machecoul','Machecoul','44'),('FR','MAI','Maignelay Montigny','Maignelay Montigny','60'),('FR','MAJ','Le Mesnil-Amelot','Le Mesnil-Amelot','77'),('FR','MAK','Marck','Marck','62'),('FR','MAL','Malesherbes','Malesherbes','45'),('FR','MAM','Marles-les-Mines','Marles-les-Mines','62'),('FR','MAN','Mantes-la-Jolie','Mantes-la-Jolie','78'),('FR','MAO','Matour','Matour','71'),('FR','MAQ','Manosque','Manosque','04'),('FR','MAR','Marmande','Marmande','47'),('FR','MAS','Maisdon-sur-Sevre','Maisdon-sur-Sevre','44'),('FR','MAT','Matha','Matha','17'),('FR','MAU','Maubeuge','Maubeuge','59'),('FR','MAV','Malataverne','Malataverne','26'),('FR','MAX','Maxeville','Maxeville','54'),('FR','MAY','Mayenne','Mayenne','53'),('FR','MAZ','Mazamet','Mazamet','81'),('FR','MBA','Montbazens','Montbazens','12'),('FR','MBB','Lamotte-Brebiere','Lamotte-Brebiere','80'),('FR','MBC','Mirabel-et-Blacons','Mirabel-et-Blacons','26'),('FR','MBD','Martigne-Briand','Martigne-Briand','49'),('FR','MBE','Montreuil-Bellay','Montreuil-Bellay','49'),('FR','MBG','Montauban-de-Bretagne','Montauban-de-Bretagne','35'),('FR','MBH','Marbache','Marbache','54'),('FR','MBI','Morbier','Morbier','39'),('FR','MBL','Mably','Mably','42'),('FR','MBM','Muhlbach-sur-Munster','Muhlbach-sur-Munster','68'),('FR','MBN','Monbalen','Monbalen','47'),('FR','MBO','Montbron','Montbron','16'),('FR','MBR','Montbrun-les-Bains','Montbrun-les-Bains','26'),('FR','MBS','Montbrison','Montbrison','26'),('FR','MBT','Montbartier','Montbartier','82'),('FR','MBU','Malbuisson','Malbuisson','25'),('FR','MBV','Marseille-en-Beauvaisis','Marseille-en-Beauvaisis','60'),('FR','MBX','Montagny-les-Beaune','Montagny-les-Beaune','21'),('FR','MBZ','Mur-de-Barrez','Mur-de-Barrez','12'),('FR','MCA','Montignac-Charente','Montignac-Charente','16'),('FR','MCB','Montredon-des-Corbieres','Montredon-des-Corbieres','11'),('FR','MCD','St Mesmin','St Mesmin','21'),('FR','MCE','Maiche','Maiche','25'),('FR','MCF','Morteaux-Couliboeuf','Morteaux-Couliboeuf','14'),('FR','MCH','Montchevrel','Montchevrel','61'),('FR','MCL','Marcillac-la-Croze','Marcillac-la-Croze','19'),('FR','MCM','Mesnil-Clinchamps','Mesnil-Clinchamps','14'),('FR','MCN','Montcornet','Montcornet','02'),('FR','MCO','Marconne','Marconne','62'),('FR','MCQ','Macau','Macau','33'),('FR','MCR','Moissy-Cramayel','Moissy-Cramayel','77'),('FR','MCS','Mecleuves','Mecleuves','57'),('FR','MCT','Manchecourt','Manchecourt','45'),('FR','MCU','Montlucon','Montlucon','03'),('FR','MCV','Magnac-Laval','Magnac-Laval','87'),('FR','MCX','Morcenx','Morcenx','40'),('FR','MCY','Marcigny','Marcigny','71'),('FR','MCZ','Marcellaz','Marcellaz','74'),('FR','MDA','Mudaison','Mudaison','34'),('FR','MDB','Maine-de-Boixe','Maine-de-Boixe','16'),('FR','MDC','St-Meard-de-Gurcon','St-Meard-de-Gurcon','24'),('FR','MDD','Montdidier','Montdidier','80'),('FR','MDE','Modene','Modene','84'),('FR','MDG','Mondelange','Mondelange','57'),('FR','MDH','Mundolsheim','Mundolsheim','67'),('FR','MDL','Mordelles','Mordelles','35'),('FR','MDM','Mont-de-Marsan','Mont-de-Marsan','40'),('FR','MDN','Modane','Modane','73'),('FR','MDQ','Mareuil-sur-Lay-Dissais','Mareuil-sur-Lay-Dissais','85'),('FR','MDR','Mondragon','Mondragon','84'),('FR','MDU','Mondoubleau','Mondoubleau','41'),('FR','MDX','St-Medard-d\'Excideuil','St-Medard-d\'Excideuil','24'),('FR','MEA','Meaux','Meaux','77'),('FR','MEB','Marolles-en-Brie','Marolles-en-Brie','94'),('FR','MEC','Mennecy','Mennecy','91'),('FR','MED','Montendre','Montendre',''),('FR','MEE','Le Mee-sur-Seine','Le Mee-sur-Seine','77'),('FR','MEG','Meung-sur-Loire','Meung-sur-Loire','45'),('FR','MEH','Mehun-sur-Yevre','Mehun-sur-Yevre','18'),('FR','MEI','Merignac','Merignac','33'),('FR','MEL','Melun','Melun','77'),('FR','MEM','Meymac','Meymac','19'),('FR','MEN','Mende','Mende','48'),('FR','MEO','Marquette-en-Ostrevant','Marquette-en-Ostrevant','59'),('FR','MEP','Merpins','Merpins','16'),('FR','MEQ','Melesse','Melesse','35'),('FR','MER','Mercurey','Mercurey','71'),('FR','MES','Messia-sur-Sorne','Messia-sur-Sorne','39'),('FR','MET','Marseillette','Marseillette','11'),('FR','MEU','Meursault','Meursault','21'),('FR','MEV','Merville','Merville',''),('FR','MEX','Mer','Mer','41'),('FR','MEY','Meyzieu','Meyzieu','69'),('FR','MEZ','Mezidon-Canon','Mezidon-Canon','14'),('FR','MFC','Martigne-Ferchaud','Martigne-Ferchaud','35'),('FR','MFE','Montfermeil','Montfermeil','93'),('FR','MFF','La Meauffe','La Meauffe','50'),('FR','MFG','Montfort-le-Gesnois','Montfort-le-Gesnois','72'),('FR','MFO','Mortefontaine','Mortefontaine','60'),('FR','MFQ','Monflanquin','Monflanquin','47'),('FR','MFR','Montfranc','Montfranc','12'),('FR','MFX','Meribel','Meribel','73'),('FR','MFY','Montfort-l\'Amaury','Montfort-l\'Amaury','78'),('FR','MFZ','Montferrier','Montferrier','09'),('FR','MGA','Magenta','Magenta','51'),('FR','MGB','Magnac-Bourg','Magnac-Bourg','87'),('FR','MGC','Montigny-sur-Chiers','Montigny-sur-Chiers','54'),('FR','MGD','Mouguerre','Mouguerre','64'),('FR','MGE','Montigny-en-Gohelle','Montigny-en-Gohelle','62'),('FR','MGG','Mesgrigny','Mesgrigny','10'),('FR','MGH','Mansgne','Mansgne','72'),('FR','MGI','Mougins','Mougins','06'),('FR','MGL','Maneglise','Maneglise','76'),('FR','MGM','Montigny Les Monts','Montigny Les Monts',''),('FR','MGN','Marignane','Marignane','13'),('FR','MGP','Maizieres-la-Grande-Paroisse','Maizieres-la-Grande-Paroisse','10'),('FR','MGQ','Montguyon','Montguyon','17'),('FR','MGR','Magnieres','Magnieres','54'),('FR','MGS','Morangis','Morangis','91'),('FR','MGT','Martignat','Martignat','01'),('FR','MGU','Mauguio','Mauguio','34'),('FR','MGV','Margival','Margival','02'),('FR','MGX','Margaux','Margaux','33'),('FR','MGY','Marigny','Marigny','50'),('FR','MGZ','Mesanger','Mesanger','44'),('FR','MHA','Mauleon-Licharre','Mauleon-Licharre','64'),('FR','MHD','Ste Menehould','Ste Menehould','51'),('FR','MHE','Morhange','Morhange','57'),('FR','MHG','St-Michel-de-Montaigne','St-Michel-de-Montaigne','24'),('FR','MHL','Merinchal','Merinchal','23'),('FR','MHM','Marlenheim','Marlenheim','67'),('FR','MHP','Marolles-en-Hurepoix','Marolles-en-Hurepoix','91'),('FR','MHS','Mittelhausen','Mittelhausen','67'),('FR','MHU','Munchhausen','Munchhausen','67'),('FR','MHX','Magny-les-Hameaux','Magny-les-Hameaux','78'),('FR','MHY','Montlhery','Montlhery','91'),('FR','MIA','Migne-Auxances','Migne-Auxances','86'),('FR','MIC','St Michel-sur-Orge','St Michel-sur-Orge','91'),('FR','MID','Malissard','Malissard','26'),('FR','MIE','Martin-Eglise','Martin-Eglise','76'),('FR','MIF','Milly-la-Foret','Milly-la-Foret','91'),('FR','MIG','Migennes','Migennes','89'),('FR','MIH','Mietesheim','Mietesheim','67'),('FR','MII','Montlouis-sur-Loire','Montlouis-sur-Loire','37'),('FR','MIJ','Ste Hermine','Ste Hermine','85'),('FR','MIL','Millau','Millau','12'),('FR','MIM','Mitry-Mory','Mitry-Mory','77'),('FR','MIN','Miniac-Morvan','Miniac-Morvan','35'),('FR','MIO','Mions','Mions','69'),('FR','MIQ','Maisse','Maisse','91'),('FR','MIR','Miramas','Miramas','13'),('FR','MIS','Menilles','Menilles','27'),('FR','MIT','Maillet','Maillet',''),('FR','MIV','Melle','Melle','35'),('FR','MIX','Mios','Mios','33'),('FR','MIY','Melisey','Melisey','70'),('FR','MIZ','Marines','Marines','95'),('FR','MJE','Meulan','Meulan','78'),('FR','MJK','Mirande','Mirande','32'),('FR','MJL','Montjean-sur-Loire','Montjean-sur-Loire','49'),('FR','MKH','Mollkirch','Mollkirch','67'),('FR','MKM','Marckolsheim','Marckolsheim','67'),('FR','MKO','Malakoff','Malakoff','92'),('FR','MLA','Mareuil-sur-Ay','Mareuil-sur-Ay','51'),('FR','MLB','Mers-les-Bains','Mers-les-Bains','80'),('FR','MLC','Le Cheylard','Le Cheylard','07'),('FR','MLD','Monistrol-d\'Allier','Monistrol-d\'Allier','43'),('FR','MLE','Melle','Melle','79'),('FR','MLF','Mouilleron-le-Captif','Mouilleron-le-Captif','85'),('FR','MLG','Mourmelon-le-Grand','Mourmelon-le-Grand','51'),('FR','MLH','Mulhouse','Mulhouse','68'),('FR','MLI','Moulines','Moulines','50'),('FR','MLJ','Mane','Mane','04'),('FR','MLK','Malicorne','Malicorne','03'),('FR','MLL','Montluel','Montluel','01'),('FR','MLM','Montceau-les-Mines','Montceau-les-Mines','71'),('FR','MLN','Moulins','Moulins','02'),('FR','MLO','Mauleon','Mauleon','79'),('FR','MLP','Montreal-la-Cluse','Montreal-la-Cluse','01'),('FR','MLQ','Meaulne','Meaulne','03'),('FR','MLR','Melrand','Melrand','56'),('FR','MLS','Melisey','Melisey','89'),('FR','MLT','Malemort-sur-Correze','Malemort-sur-Correze','19'),('FR','MLV','Marne-la-Vallee','Marne-la-Vallee','77'),('FR','MLX','Moulineaux','Moulineaux','76'),('FR','MLY','Meuilley','Meuilley','21'),('FR','MLZ','Moulins-les-Metz','Moulins-les-Metz','57'),('FR','MMA','St Mesmin/Aube','St Mesmin/Aube','10'),('FR','MMB','Montmoreau-Saint-Cybard','Montmoreau-Saint-Cybard','16'),('FR','MMC','Montreuil-sur-Mer','Montreuil-sur-Mer','62'),('FR','MMD','St Mesmin/Dordogne','St Mesmin/Dordogne','24'),('FR','MME','Meslay-du-Maine','Meslay-du-Maine','53'),('FR','MMF','Marimont-les-Benestroff','Marimont-les-Benestroff','57'),('FR','MMG','Montmagny','Montmagny','95'),('FR','MMH','Mont-sur-Meurthe','Mont-sur-Meurthe','54'),('FR','MMI','Montmirail','Montmirail','51'),('FR','MML','Montmelian','Montmelian','73'),('FR','MMN','St Mesmin','St Mesmin','85'),('FR','MMO','Mallemort','Mallemort','13'),('FR','MMP','Mourmelon-le-Petit','Mourmelon-le-Petit','51'),('FR','MMQ','Commequiers','Commequiers','85'),('FR','MMR','Marmoutier','Marmoutier','67'),('FR','MMS','Maumusson-Laguian','Maumusson-Laguian',''),('FR','MMT','Mormant','Mormant','77'),('FR','MMX','Mormoiron','Mormoiron','84'),('FR','MMZ','Mimizan','Mimizan','40'),('FR','MNA','Marennes','Marennes','69'),('FR','MNB','Montblanc','Montblanc','34'),('FR','MNC','Monchy','Monchy',''),('FR','MND','Mandelieu-la-Napoule','Mandelieu-la-Napoule','06'),('FR','MNE','Mansle','Mansle','16'),('FR','MNF','Montemboeuf','Montemboeuf','16'),('FR','MNG','Montgiscard','Montgiscard',''),('FR','MNH','Mommenheim','Mommenheim','67'),('FR','MNI','Margny-les-Compiegne','Margny-les-Compiegne','60'),('FR','MNK','Montagne','Montagne','33'),('FR','MNL','Les Montils','Les Montils','41'),('FR','MNM','Montmorillon','Montmorillon','86'),('FR','MNN','Morannes','Morannes','49'),('FR','MNO','Montrottier','Montrottier','69'),('FR','MNQ','Montcuq','Montcuq','46'),('FR','MNR','Menerbes','Menerbes','84'),('FR','MNS','Masnieres','Masnieres','59'),('FR','MNT','Montaigu','Montaigu','02'),('FR','MNU','Montaigu','Montaigu','85'),('FR','MNX','Monteaux','Monteaux','41'),('FR','MNY','Marigny','Marigny',''),('FR','MNZ','Montbazon','Montbazon','37'),('FR','MOA','Montegut-Arros','Montegut-Arros','32'),('FR','MOB','Monbazillac','Monbazillac','24'),('FR','MOC','Montchanin','Montchanin','71'),('FR','MOD','Montbard','Montbard','21'),('FR','MOE','Montataire','Montataire','60'),('FR','MOF','Mornas','Mornas','84'),('FR','MOG','Mortagne-sur-Sevre','Mortagne-sur-Sevre','85'),('FR','MOH','Mouthiers-sur-Boheme','Mouthiers-sur-Boheme','16'),('FR','MOI','Moirans','Moirans','38'),('FR','MOJ','Montreuil-Juigne','Montreuil-Juigne','49'),('FR','MOK','Moreac','Moreac','56'),('FR','MOL','Molsheim','Molsheim','67'),('FR','MOM','Manom','Manom','57'),('FR','MON','Montreux','Montreux','54'),('FR','MOO','Montesson','Montesson','78'),('FR','MOP','Monchy-le-Preux','Monchy-le-Preux','62'),('FR','MOQ','Morestel','Morestel','38'),('FR','MOR','Morteau','Morteau','25'),('FR','MOS','Montargis','Montargis','45'),('FR','MOT','Montauban','Montauban','82'),('FR','MOU','Moulins','Moulins','03'),('FR','MOV','Montalieu-Vercieu','Montalieu-Vercieu','38'),('FR','MOX','Monteux','Monteux','84'),('FR','MOY','Moyon','Moyon','50'),('FR','MOZ','Marboz','Marboz','01'),('FR','MPA','Mont','Mont','64'),('FR','MPB','Montpont-en-Bresse','Montpont-en-Bresse','71'),('FR','MPD','Lampourdier','Lampourdier','84'),('FR','MPE','Merkwiller-Pechelbronn','Merkwiller-Pechelbronn','67'),('FR','MPH','Malmerspach','Malmerspach','68'),('FR','MPI','Monsempron-Libos','Monsempron-Libos','47'),('FR','MPL','Montpellier','Montpellier','34'),('FR','MPM','Montpon-Menesterol','Montpon-Menesterol','24'),('FR','MPO','Marchelepot','Marchelepot','80'),('FR','MPS','Maurepas','Maurepas','80'),('FR','MPV','Monferran-Plaves','Monferran-Plaves','32'),('FR','MPY','Montaignac-Saint-Hippolyte','Montaignac-Saint-Hippolyte','19'),('FR','MQB','Marcq-en-Baroeul','Marcq-en-Baroeul','59'),('FR','MQE','Marcoule','Marcoule','30'),('FR','MQL','Marquette-lez-Lille','Marquette-lez-Lille','59'),('FR','MQU','La Mure','La Mure','38'),('FR','MRA','Mereau','Mereau','18'),('FR','MRB','Miribel','Miribel','26'),('FR','MRC','Montierchaume','Montierchaume','36'),('FR','MRD','Mardeuil','Mardeuil','51'),('FR','MRE','Marle','Marle','02'),('FR','MRF','Motreff','Motreff','29'),('FR','MRG','Marguerittes','Marguerittes','30'),('FR','MRH','Merrey','Merrey','52'),('FR','MRI','Maringues','Maringues','63'),('FR','MRL','Marly','Marly',''),('FR','MRM','Mairy-sur-Marne','Mairy-sur-Marne','51'),('FR','MRN','Marans','Marans','17'),('FR','MRO','Maromme','Maromme','76'),('FR','MRP','Maurepas','Maurepas','78'),('FR','MRQ','Marquise','Marquise','62'),('FR','MRR','Mortree','Mortree','61'),('FR','MRS','Marseille','Marseille','13'),('FR','MRT','Margut','Margut','08'),('FR','MRU','Maroeuil','Maroeuil','62'),('FR','MRV','Marville','Marville','55'),('FR','MRX','Mourenx','Mourenx','64'),('FR','MRY','Morey','Morey','71'),('FR','MRZ','Marnaz','Marnaz','74'),('FR','MSA','Maisons-Alfort','Maisons-Alfort','94'),('FR','MSB','Montrond-les-Bains','Montrond-les-Bains','42'),('FR','MSC','Moissac','Moissac','82'),('FR','MSD','Mussidan','Mussidan','24'),('FR','MSE','Mours-Saint-Eusebe','Mours-Saint-Eusebe','26'),('FR','MSF','Moussy-le-Neuf','Moussy-le-Neuf','77'),('FR','MSG','Mortagne-sur-Gironde','Mortagne-sur-Gironde','17'),('FR','MSI','Mery-sur-Oise','Mery-sur-Oise','95'),('FR','MSL','Marsillargues','Marsillargues','34'),('FR','MSM','Mont-Saint-Martin','Mont-Saint-Martin','54'),('FR','MSN','Mesnil-Saint-Nicaise','Mesnil-Saint-Nicaise','80'),('FR','MSO','Morsang-sur-Orge','Morsang-sur-Orge','91'),('FR','MSQ','Mont-Saint-Eloi','Mont-Saint-Eloi','62'),('FR','MSR','Montfort-sur-Risle','Montfort-sur-Risle','27'),('FR','MSS','Messac','Messac',''),('FR','MST','Magnac-sur-Touvre','Magnac-sur-Touvre','16'),('FR','MSU','Mauves-sur-Loire','Mauves-sur-Loire','44'),('FR','MSV','Marange-Silvange','Marange-Silvange','57'),('FR','MSX','Mouans-Sartoux','Mouans-Sartoux','06'),('FR','MSY','Massy','Massy','91'),('FR','MSZ','Momeres','Momeres','65'),('FR','MTA','Montrabe','Montrabe','31'),('FR','MTB','Montbrison','Montbrison','42'),('FR','MTC','Montcaret','Montcaret','24'),('FR','MTD','Montbeliard','Montbeliard','25'),('FR','MTE','Montereau','Montereau','45'),('FR','MTF','Montmorot','Montmorot','39'),('FR','MTG','Montrouge','Montrouge','92'),('FR','MTH','Montherme','Montherme','08'),('FR','MTI','Montain','Montain','82'),('FR','MTJ','Montaigu','Montaigu','39'),('FR','MTK','Montans','Montans',''),('FR','MTL','Montreuil','Montreuil','93'),('FR','MTM','Montelimar','Montelimar','26'),('FR','MTN','Maintenon','Maintenon','28'),('FR','MTO','Montieramey','Montieramey','10'),('FR','MTP','Martillac','Martillac','33'),('FR','MTQ','Martres-Tolosane','Martres-Tolosane','31'),('FR','MTR','Montereau-faut-Yonne','Montereau-faut-Yonne','77'),('FR','MTS','Montigny-les-Cormeilles','Montigny-les-Cormeilles','95'),('FR','MTT','Montreuil','Montreuil','28'),('FR','MTU','Martigues','Martigues','13'),('FR','MTV','Montevrain','Montevrain','77'),('FR','MTW','Montagnac','Montagnac','34'),('FR','MTX','Montoir-de-Bretagne','Montoir-de-Bretagne','44'),('FR','MTY','Montelier','Montelier','26'),('FR','MTZ','Muntzenheim','Muntzenheim','68'),('FR','MUA','Malaunay','Malaunay','76'),('FR','MUB','Mirebeau-sur-Beze','Mirebeau-sur-Beze','21'),('FR','MUC','Malaucene','Malaucene','84'),('FR','MUD','Mouchard','Mouchard','39'),('FR','MUE','Maule','Maule','78'),('FR','MUF','Margueron','Margueron','33'),('FR','MUG','Marcilly','Marcilly','89'),('FR','MUH','Mery-sur-Cher','Mery-sur-Cher','18'),('FR','MUI','Montreuil','Montreuil','85'),('FR','MUL','Moreuil','Moreuil','80'),('FR','MUM','Munster','Munster','57'),('FR','MUN','Mulhouse Nord','Mulhouse Nord','68'),('FR','MUO','Mouroux','Mouroux','77'),('FR','MUR','Muret','Muret','31'),('FR','MUS','Mussy-sur-Seine','Mussy-sur-Seine','10'),('FR','MUU','Montestruc-sur-Gers','Montestruc-sur-Gers','32'),('FR','MUX','Mandeure','Mandeure','25'),('FR','MUY','Mouy','Mouy','60'),('FR','MUZ','Mussey-sur-Marne','Mussey-sur-Marne','52'),('FR','MVA','Malville','Malville','44'),('FR','MVB','Mont-le-Vignoble','Mont-le-Vignoble','54'),('FR','MVD','Moers-Verdey','Moers-Verdey','51'),('FR','MVE','Mondeville','Mondeville','91'),('FR','MVI','Moulins','Moulins','35'),('FR','MVJ','Marvejols','Marvejols','48'),('FR','MVL','Monnet-la-Ville','Monnet-la-Ville','39'),('FR','MVN','Marcillac-Vallon','Marcillac-Vallon','12'),('FR','MVO','Mirecourt','Mirecourt','88'),('FR','MVR','Marainviller','Marainviller','54'),('FR','MVS','Mervans','Mervans','71'),('FR','MVT','Mervent','Mervent','85'),('FR','MVU','Masevaux','Masevaux','67'),('FR','MVV','Megeve','Megeve','74'),('FR','MVW','Mollans-sur-Ouveze','Mollans-sur-Ouveze','26'),('FR','MVX','Mouvaux','Mouvaux','59'),('FR','MVY','Montfaucon-en-Velay','Montfaucon-en-Velay','43'),('FR','MVZ','Magny-les-Villers','Magny-les-Villers','21'),('FR','MWI','Mertzwiller','Mertzwiller','67'),('FR','MWY','Milly','Milly','50'),('FR','MXB','Mignaloux-Beauvoir','Mignaloux-Beauvoir','86'),('FR','MXG','St-Magne-de-Castillon','St-Magne-de-Castillon','33'),('FR','MXH','Merxheim','Merxheim','68'),('FR','MXI','Saint-Maximin','Saint-Maximin','60'),('FR','MXL','Mesnil sur l\'Estree','Mesnil sur l\'Estree','27'),('FR','MXM','Meximieux','Meximieux','01'),('FR','MXN','Morlaix','Morlaix','29'),('FR','MXO','St-Morillon','St-Morillon','33'),('FR','MXQ','Male','Male','61'),('FR','MXR','Mesnil-Raoul','Mesnil-Raoul','76'),('FR','MXS','Monthureux-sur-Saone','Monthureux-sur-Saone','88'),('FR','MXT','Saint-Maixent-l\'Ecole','Saint-Maixent-l\'Ecole','79'),('FR','MXX','Mornant','Mornant','69'),('FR','MYB','Martigny-les-Bains','Martigny-les-Bains','88'),('FR','MYC','Magny-Cours','Magny-Cours','58'),('FR','MYD','Dissais','Dissais','85'),('FR','MYE','Monchy-Saint-Eloi','Monchy-Saint-Eloi','60'),('FR','MYG','Moyeuvre-Grande','Moyeuvre-Grande','57'),('FR','MYH','Milly-sur-Therain','Milly-sur-Therain','60'),('FR','MYI','Morigny-Champigny','Morigny-Champigny',''),('FR','MYL','Meylan','Meylan','38'),('FR','MYM','Mery','Mery','73'),('FR','MYN','Monthyon','Monthyon','77'),('FR','MYO','Marly-le-Roi','Marly-le-Roi','78'),('FR','MYP','Moulis-en-Medoc','Moulis-en-Medoc','33'),('FR','MYR','Meyreuil','Meyreuil','13'),('FR','MYT','Meythet','Meythet','74'),('FR','MYU','Marigny-le-Chatel','Marigny-le-Chatel','10'),('FR','MYV','Marly-la-Ville','Marly-la-Ville','95'),('FR','MYY','Milly','Milly','89'),('FR','MZA','Mezzavia','Mezzavia','2A'),('FR','MZC','Montmort-Lucy','Montmort-Lucy','51'),('FR','MZE','Maizieres','Maizieres','52'),('FR','MZG','Mutzig','Mutzig','67'),('FR','MZH','Metzeresche','Metzeresche','57'),('FR','MZI','Mouzillon','Mouzillon','44'),('FR','MZL','Moutier-Rozeille','Moutier-Rozeille','23'),('FR','MZM','Metz','Metz','57'),('FR','MZN','Mouzon','Mouzon','08'),('FR','MZO','Mazion','Mazion','33'),('FR','MZQ','Montpezat-de-Quercy','Montpezat-de-Quercy','82'),('FR','MZR','Mazeres ','Mazeres ','33'),('FR','MZS','Mezieres-sur-Seine','Mezieres-sur-Seine','78'),('FR','MZT','Metz-Tessy','Metz-Tessy','74'),('FR','MZV','Mazet-St-Voy','Mazet-St-Voy','43'),('FR','MZZ','Maizieres-les-Metz','Maizieres-les-Metz','57'),('FR','NAB','Neuville-aux-Bois','Neuville-aux-Bois','45'),('FR','NAC','Carnac','Carnac','56'),('FR','NAE','Nantes Armees','Nantes Armees','44'),('FR','NAG','Nangis','Nangis','77'),('FR','NAI','Naveil','Naveil','41'),('FR','NAL','Novalaise','Novalaise','73'),('FR','NAN','Nanterre','Nanterre','92'),('FR','NAR','Narbonne','Narbonne','11'),('FR','NAS','Banassac','Banassac','48'),('FR','NAU','Naucelle','Naucelle','12'),('FR','NAV','Naves','Naves','19'),('FR','NAY','Marsannay-la-Cote','Marsannay-la-Cote','21'),('FR','NBG','Le Neubourg','Le Neubourg','27'),('FR','NBS','Norrey-en-Bessin','Norrey-en-Bessin','14'),('FR','NBY','Nogent-en-Bassigny','Nogent-en-Bassigny','52'),('FR','NCE','Nice','Nice','06'),('FR','NCI','Montastruc-la-Conseillere','Montastruc-la-Conseillere','31'),('FR','NCL','La Vancelle','La Vancelle','67'),('FR','NCN','Neac','Neac','33'),('FR','NCO','Lancon-Provence','Lancon-Provence','13'),('FR','NCR','Montcornet','Montcornet','08'),('FR','NCT','Neuilly-sous-Clermont','Neuilly-sous-Clermont','60'),('FR','NCX','Nogent-sur-Oise','Nogent-sur-Oise','60'),('FR','NCY','Annecy','Annecy','74'),('FR','NDA','Mont-de-Lans','Mont-de-Lans','38'),('FR','NDB','Notre-Dame-de-Briancon','Notre-Dame-de-Briancon','73'),('FR','NDE','Landres','Landres','54'),('FR','NDG','Notre-Dame-de-Gravenchon','Notre-Dame-de-Gravenchon','76'),('FR','NDH','Le Mesnil-St-Denis','Le Mesnil-St-Denis','78'),('FR','NDM','Mont-Notre-Dame','Mont-Notre-Dame','02'),('FR','NDN','St-Sernin-du-Plain','St-Sernin-du-Plain','71'),('FR','NDO','Niedermodern','Niedermodern','67'),('FR','NDP','Neuville-de-Poitou','Neuville-de-Poitou','86'),('FR','NDR','Landry','Landry','73'),('FR','NDS','Septfonds','Septfonds','82'),('FR','NEA','Nebias','Nebias','11'),('FR','NEB','Neufchatel-en-Bray','Neufchatel-en-Bray','76'),('FR','NEC','Sennece-les-Macon','Sennece-les-Macon','71'),('FR','NEF','Neuf-Brisach','Neuf-Brisach','68'),('FR','NEI','Neuville-les-Dieppe','Neuville-les-Dieppe','76'),('FR','NEL','Nesle','Nesle','80'),('FR','NEO','Nevoy','Nevoy','45'),('FR','NEP','Neuvy-Pailloux','Neuvy-Pailloux','36'),('FR','NEQ','Neuilly-l\'Eveque','Neuilly-l\'Eveque','52'),('FR','NER','Nersac','Nersac','16'),('FR','NES','Neussargues-Moissac','Neussargues-Moissac','15'),('FR','NET','Neuilly-en-Thelle','Neuilly-en-Thelle','60'),('FR','NEU','Neufchateau','Neufchateau','88'),('FR','NEV','Neuilly-Plaisance','Neuilly-Plaisance','93'),('FR','NEX','Neaux','Neaux','42'),('FR','NEY','Neyron','Neyron','01'),('FR','NFN','Neufmaison','Neufmaison','08'),('FR','NFS','Neufmaisons','Neufmaisons','54'),('FR','NGA','Longueil-Annel','Longueil-Annel','60'),('FR','NGE','Molinges','Molinges','39'),('FR','NGI','St-Gilles','St-Gilles','71'),('FR','NGL','Larnagol','Larnagol','46'),('FR','NGO','Noyelles-Godault','Noyelles-Godault','62'),('FR','NGR','Le Longeron','Le Longeron','49'),('FR','NGS','Nogent-sur-Seine','Nogent-sur-Seine','10'),('FR','NGT','Montaigut','Montaigut','63'),('FR','NGU','Launaguet','Launaguet','31'),('FR','NGV','Nogent-sur-Vernisson','Nogent-sur-Vernisson','45'),('FR','NHA','Noalhac','Noalhac','48'),('FR','NHD','Nanteuil-le-Haudouin','Nanteuil-le-Haudouin','60'),('FR','NHM','Niederhergheim','Niederhergheim','68'),('FR','NHO','Le Ponthou','Le Ponthou','29'),('FR','NHR','Niherne','Niherne','36'),('FR','NHU','Canihuel','Canihuel','22'),('FR','NIC','Saint-Nicolas-de-Port','Saint-Nicolas-de-Port','54'),('FR','NIE','Niederbruck','Niederbruck','68'),('FR','NIH','Niederhaslach','Niederhaslach','67'),('FR','NIL','Neville','Neville','76'),('FR','NIO','Nancois-sur-Ornain','Nancois-sur-Ornain','55'),('FR','NIR','Nitry','Nitry','89'),('FR','NIS','Noisiel','Noisiel','77'),('FR','NIT','Niort','Niort','79'),('FR','NJC','Najac','Najac','12'),('FR','NLA','Sainte-Anne-sur-Vilaine','Sainte-Anne-sur-Vilaine','35'),('FR','NLB','Niederbronn-les-Bains','Niederbronn-les-Bains','67'),('FR','NLC','St-Martin-Lacaussade','St-Martin-Lacaussade','33'),('FR','NLF','Nouan-le-Fuzelier','Nouan-le-Fuzelier','41'),('FR','NLI','Montilliers','Montilliers','37'),('FR','NLN','Montaulin','Montaulin','10'),('FR','NLO','Niolon','Niolon','13'),('FR','NLP','Nans-les-Pins','Nans-les-Pins','83'),('FR','NLR','Nogent-le-Rotrou','Nogent-le-Rotrou','28'),('FR','NLS','Noisy-le-Sec','Noisy-le-Sec','93'),('FR','NLV','Noidans-les-Vesoul','Noidans-les-Vesoul','70'),('FR','NLX','Noidant-le-Rocheux','Noidant-le-Rocheux','52'),('FR','NLY','Neuvilly','Neuvilly','60'),('FR','NME','Nogent-sur-Marne','Nogent-sur-Marne','94'),('FR','NML','Nivolas Vermelle','Nivolas Vermelle','39'),('FR','NMO','St-Maurice-Colombier','St-Maurice-Colombier','25'),('FR','NMS','Nemours','Nemours','77'),('FR','NMU','Montmaur','Montmaur','11'),('FR','NMY','St-Martin-d\'Oney','St-Martin-d\'Oney','40'),('FR','NNA','Bannay','Bannay','18'),('FR','NNE','Larchamp','Larchamp','53'),('FR','NNO','Lannoy','Lannoy','59'),('FR','NNT','Nantille','Nantille','17'),('FR','NNU','Nantua','Nantua','01'),('FR','NOB','Monterolier','Monterolier','76'),('FR','NOC','Noce','Noce','61'),('FR','NOD','Iwuy','Iwuy','59'),('FR','NOE','Valensole','Valensole','04'),('FR','NOG','Nogent-le-Roi','Nogent-le-Roi','28'),('FR','NOI','Noirmoutier-en-l\'Ile','Noirmoutier-en-l\'Ile','85'),('FR','NON','Thenon','Thenon','24'),('FR','NOS','Noisy-le-Grand','Noisy-le-Grand','93'),('FR','NOU','Port-la-Nouvelle','Port-la-Nouvelle','11'),('FR','NOV','Noves','Noves','13'),('FR','NOX','Nolay','Nolay','21'),('FR','NOY','Noyon','Noyon','60'),('FR','NPI','St-Piat','St-Piat','28'),('FR','NPO','Noyal-Pontivy','Noyal-Pontivy','56'),('FR','NPP','Nieppe','Nieppe','59'),('FR','NPS','St-Prest','St-Prest','28'),('FR','NQE','Nortkerque','Nortkerque','62'),('FR','NRA','Anor','Anor','59'),('FR','NRC','Nerac','Nerac','47'),('FR','NRD','Bonnard','Bonnard','89'),('FR','NRI','Noisy-le-Roi','Noisy-le-Roi','78'),('FR','NRO','Nogaro','Nogaro','32'),('FR','NRS','Narrosse','Narrosse','40'),('FR','NRT','Noiretable','Noiretable','42'),('FR','NRU','Montmarault','Montmarault','03'),('FR','NRV','Norges-la-Ville','Norges-la-Ville','21'),('FR','NRY','Noyarey','Noyarey','38'),('FR','NRZ','La Bernerie-en-Retz','La Bernerie-en-Retz','44'),('FR','NSA','Notre-Dame-de-Sanilhac','Notre-Dame-de-Sanilhac','24'),('FR','NSC','Cransac','Cransac','12'),('FR','NSE','Nort-sur-Erdre','Nort-sur-Erdre','44'),('FR','NSG','Nuits-Saint-Georges','Nuits-Saint-Georges','21'),('FR','NSL','Nieul-sur-l\'Autise','Nieul-sur-l\'Autise','85'),('FR','NSM','Blonville-sur-Mer','Blonville-sur-Mer','14'),('FR','NSN','Sains-du-Nord','Sains-du-Nord','59'),('FR','NSO','Montsoult','Montsoult','95'),('FR','NSR','Neuville-Saint-Remy','Neuville-Saint-Remy','59'),('FR','NSS','Neuilly-sur-Seine','Neuilly-sur-Seine','92'),('FR','NST','Monestrol','Monestrol','31'),('FR','NSU','Montsurs','Montsurs','53'),('FR','NSV','Noyal-sur-Vilaine','Noyal-sur-Vilaine','35'),('FR','NSX','Nod-sur-Seine','Nod-sur-Seine','21'),('FR','NSY','Mainbressy','Mainbressy','08'),('FR','NSZ','Niederstinzel','Niederstinzel','57'),('FR','NTA','Montaut','Montaut','64'),('FR','NTE','Nantes','Nantes','44'),('FR','NTL','Nointel','Nointel','95'),('FR','NTR','Nontron','Nontron','24'),('FR','NTS','Monts','Monts','37'),('FR','NTT','Nantiat','Nantiat','87'),('FR','NTV','Montville','Montville','76'),('FR','NTY','Montry','Montry','77'),('FR','NTZ','Bantouzelle','Bantouzelle','59'),('FR','NUA','Nouatre','Nouatre','37'),('FR','NUC','Nuces','Nuces','12'),('FR','NUE','Nogueres','Nogueres',''),('FR','NUQ','Nordausques','Nordausques','62'),('FR','NUR','Nurieux-Volognat','Nurieux-Volognat','01'),('FR','NUS','Nanteuil-sur-Aisne','Nanteuil-sur-Aisne','08'),('FR','NUX','Nanteuil-les-Meaux','Nanteuil-les-Meaux','77'),('FR','NVA','Nilvange','Nilvange','57'),('FR','NVE','Villeneuve-la-Guyard','Villeneuve-la-Guyard','89'),('FR','NVF','Neuville-en-Ferrain','Neuville-en-Ferrain','59'),('FR','NVL','Neuville-sur-Saone','Neuville-sur-Saone','69'),('FR','NVR','Nievroz','Nievroz','01'),('FR','NVS','Nevers','Nevers','58'),('FR','NVU','Neuvy-Sautour','Neuvy-Sautour','89'),('FR','NVV','Neuville-les-Vaucouleurs','Neuville-les-Vaucouleurs','55'),('FR','NWS','Neuwiller-les-Saverne','Neuwiller-les-Saverne','67'),('FR','NXC','St Nic','St Nic','29'),('FR','NXI','Noeux-les-Mines','Noeux-les-Mines','62'),('FR','NXO','Nexon','Nexon','87'),('FR','NYA','Marnay-sur-Marne','Marnay-sur-Marne','52'),('FR','NYC','Noyelles-les-Seclin','Noyelles-les-Seclin','59'),('FR','NYE','Noisy-sur-Ecole','Noisy-sur-Ecole','77'),('FR','NYF','Neuilly-Saint-Front','Neuilly-Saint-Front','02'),('FR','NYL','Noyelles','Noyelles',''),('FR','NYN','Noyen-sur-Sarthe','Noyen-sur-Sarthe','72'),('FR','NYR','Noyers','Noyers',''),('FR','NZE','Nezel','Nezel','78'),('FR','NZV','Nouzonville','Nouzonville','08'),('FR','OAG','Bourg-Argental','Bourg-Argental','42'),('FR','OAL','St-Christol-les-Ales','St-Christol-les-Ales','30'),('FR','OAY','Le Coudray','Le Coudray','28'),('FR','OBA','Colombier-Saugnieu','Colombier-Saugnieu','69'),('FR','OBC','La Baule-Escoublac','La Baule-Escoublac','44'),('FR','OBE','Obernai','Obernai','67'),('FR','OBJ','Objat','Objat','19'),('FR','OBL','Combourtille','Combourtille','35'),('FR','OBN','Corberon','Corberon','21'),('FR','OBS','Aubenas','Aubenas','07'),('FR','OBU','Bourguebus','Bourguebus','14'),('FR','OBY','Orbey','Orbey','68'),('FR','OBZ','Oberstinzel','Oberstinzel','57'),('FR','OCA','Villers-Bocage','Villers-Bocage','14'),('FR','OCI','Orcieres','Orcieres','05'),('FR','OCM','Ourches-sur-Meuse','Ourches-sur-Meuse','55'),('FR','OCN','Montcenis','Montcenis','71'),('FR','OCO','Locronan','Locronan','29'),('FR','OCR','Calonne-Ricouart','Calonne-Ricouart','62'),('FR','OCS','Loches','Loches','37'),('FR','OCT','Octeville-sur-Mer','Octeville-sur-Mer','76'),('FR','OCU','Soncourt','Soncourt','88'),('FR','OCY','Corcy','Corcy','02'),('FR','ODE','Odenas','Odenas','69'),('FR','ODS','Odos','Odos','65'),('FR','ODV','Lodeve','Lodeve','34'),('FR','OEA','Romenay','Romenay','71'),('FR','OEB','Ons-en-Bray','Ons-en-Bray','60'),('FR','OES','Osses','Osses',''),('FR','OET','Portets','Portets','33'),('FR','OEU','Quittebeuf','Quittebeuf','27'),('FR','OEY','Colmey','Colmey','54'),('FR','OEZ','St Martin-Belle-Roche','St Martin-Belle-Roche','71'),('FR','OFF','Plogoff','Plogoff','29'),('FR','OFV','Offranville','Offranville','76'),('FR','OGA','Longages','Longages','31'),('FR','OGE','Oradour-sur-Glane','Oradour-sur-Glane','87'),('FR','OGL','Orgelet','Orgelet','39'),('FR','OGN','Orgon','Orgon','13'),('FR','OGO','Borgo','Borgo','2B'),('FR','OGR','Longuerue','Longuerue','76'),('FR','OGS','Orignolles','Orignolles','17'),('FR','OGT','Bourg-Lastic','Bourg-Lastic','63'),('FR','OGU','Olliergues','Olliergues','63'),('FR','OGV','Longuevoisin','Longuevoisin','80'),('FR','OGX','Long','Long','80'),('FR','OGY','Longroy','Longroy','76'),('FR','OHD','Cohade','Cohade','43'),('FR','OHP','Orchamps','Orchamps','39'),('FR','OHS','Lourches','Lourches','59'),('FR','OIA','Corscia','Corscia','2B'),('FR','OIL','Oissel','Oissel','76'),('FR','OIN','Avoine','Avoine','37'),('FR','OIO','Crimolois','Crimolois','21'),('FR','OIR','Oiry','Oiry','51'),('FR','OIS','Boisset','Boisset','15'),('FR','OIY','Cramoisy','Cramoisy','60'),('FR','OLB','Ogeu-les-Bains','Ogeu-les-Bains','64'),('FR','OLC','Onet-le-Chateau','Onet-le-Chateau','12'),('FR','OLE','Collinee','Collinee','22'),('FR','OLF','Ozoir-la-Ferriere','Ozoir-la-Ferriere','77'),('FR','OLG','Bouligny','Bouligny','55'),('FR','OLI','Conlie','Conlie','72'),('FR','OLL','La Bouille','La Bouille','76'),('FR','OLN','Moliens','Moliens','60'),('FR','OLO','Oloron-Sainte-Marie','Oloron-Sainte-Marie','64'),('FR','OLR','Bois-le-Roi','Bois-le-Roi','27'),('FR','OLT','Moult','Moult','14'),('FR','OLY','Olby','Olby','63'),('FR','OMA','Ormes','Ormes','10'),('FR','OMB','Combes','Combes','34'),('FR','OME','Ormes','Ormes','27'),('FR','OMG','Oermingen','Oermingen','67'),('FR','OML','Ormes','Ormes','45'),('FR','OMR','Cormery','Cormery','37'),('FR','OMS','Ormes','Ormes','71'),('FR','OMT','Cormatin','Cormatin','71'),('FR','ONA','Peronnas','Peronnas','01'),('FR','ONE','Gonesse','Gonesse','95'),('FR','ONG','Onnaing','Onnaing','59'),('FR','ONI','Baronville','Baronville','57'),('FR','ONL','Onville','Onville','54'),('FR','ONN','La Bonneville','La Bonneville','50'),('FR','ONR','Savonnieres','Savonnieres','37'),('FR','ONS','Ornans','Ornans','25'),('FR','ONT','Contres','Contres','41'),('FR','ONV','Bonneville','Bonneville','80'),('FR','OON','Broons','Broons','22'),('FR','OOS','Boos','Boos','40'),('FR','OOZ','Chooz','Chooz','08'),('FR','OPH','Loupershouse','Loupershouse','57'),('FR','OPI','Opio','Opio','06'),('FR','OPP','Oppede','Oppede','84'),('FR','OPS','Compans','Compans','77'),('FR','OQV','Ocqueville','Ocqueville','76'),('FR','ORA','Orange','Orange','84'),('FR','ORB','Sorbets','Sorbets','32'),('FR','ORC','Orchies','Orchies','59'),('FR','ORG','Orgeval','Orgeval','02'),('FR','ORH','Morsbach','Morsbach','57'),('FR','ORI','Orville','Orville','62'),('FR','ORL','Bornel','Bornel','60'),('FR','ORM','Ormes','Ormes','51'),('FR','ORN','Ornon','Ornon','38'),('FR','ORO','Ormoy','Ormoy','91'),('FR','ORR','Orleans','Orleans','45'),('FR','ORS','Orsay','Orsay','91'),('FR','ORT','Orthez','Orthez','64'),('FR','ORU','Orvault','Orvault','44'),('FR','ORV','Orval','Orval','18'),('FR','ORY','Orly','Orly','94'),('FR','OSA','Roussas','Roussas','26'),('FR','OSC','Bossancourt','Bossancourt','10'),('FR','OSE','Fosses','Fosses','95'),('FR','OSI','Morsains','Morsains','51'),('FR','OSJ','Osseja','Osseja','66'),('FR','OSL','Monistrol-sur-Loire','Monistrol-sur-Loire','43'),('FR','OSM','Olonne-sur-Mer','Olonne-sur-Mer','85'),('FR','OSN','Osny','Osny','95'),('FR','OSO','Oraison','Oraison','04'),('FR','OSS','Sigolsheim','Sigolsheim','68'),('FR','OST','Ouzouer-sur-Trezee','Ouzouer-sur-Trezee','45'),('FR','OSU','Mousteru','Mousteru','22'),('FR','OSV','Oradour-sur-Vayres','Oradour-sur-Vayres','87'),('FR','OSY','Oisly','Oisly','41'),('FR','OTA','Coutras','Coutras','33'),('FR','OTE','Otterswiller','Otterswiller','67'),('FR','OTG','Ottange','Ottange','57'),('FR','OTI','Mortain','Mortain','51'),('FR','OTL','Lavoute-sur-Loire','Lavoute-sur-Loire','43'),('FR','OTM','Ottmarsheim','Ottmarsheim','68'),('FR','OTN','Montanay','Montanay','69'),('FR','OTR','Les Portes-en-Re','Les Portes-en-Re','17'),('FR','OTS','Cercottes','Cercottes','45'),('FR','OTT','La Motte-Servolex','La Motte-Servolex','73'),('FR','OTV','Motteville','Motteville','76'),('FR','OTW','Ostwald','Ostwald','67'),('FR','OTY','Le Crotoy','Le Crotoy','80'),('FR','OUA','Bouaye','Bouaye','01'),('FR','OUB','Soubise','Soubise','17'),('FR','OUC','Oucques','Oucques','41'),('FR','OUD','Oudalle','Oudalle','76'),('FR','OUE','Courteron','Courteron','10'),('FR','OUG','Ouge','Ouge','70'),('FR','OUI','Ouistreham','Ouistreham','14'),('FR','OUJ','Soual','Soual',''),('FR','OUL','Oullins','Oullins','69'),('FR','OUR','Bourgogne','Bourgogne','51'),('FR','OUS','Saint-Ouen','Saint-Ouen','93'),('FR','OUT','Lapoutroie','Lapoutroie','68'),('FR','OUV','Souvigny','Souvigny','03'),('FR','OUY','Coussey','Coussey','88'),('FR','OUZ','Ouzouer-le-Marche','Ouzouer-le-Marche','41'),('FR','OVA','Orval','Orval','50'),('FR','OVL','Ouveillan','Ouveillan','11'),('FR','OVN','Mont-le-Vernois','Mont-le-Vernois','70'),('FR','OVO','La Bonneville-sur-Iton','La Bonneville-sur-Iton','27'),('FR','OVR','Louvroil','Louvroil','59'),('FR','OVS','Boves','Boves','80'),('FR','OVT','Olivet','Olivet','45'),('FR','OVY','Orgeval','Orgeval','78'),('FR','OYA','Pomas','Pomas','11'),('FR','OYE','Voyenne','Voyenne','02'),('FR','OYN','Moyen','Moyen','54'),('FR','OYO','Oyonnax','Oyonnax','01'),('FR','OYS','Coucy-les-Eppes','Coucy-les-Eppes','02'),('FR','OYT','Origny-en-Thierache','Origny-en-Thierache','02'),('FR','OYV','Ormoy-Villers','Ormoy-Villers','60'),('FR','OZE','Soreze','Soreze','81'),('FR','OZN','Onzain','Onzain','41'),('FR','OZT','Montbizot','Montbizot','72'),('FR','OZV','Ozouer-le-Voulgis','Ozouer-le-Voulgis','77'),('FR','PAA','Parsac','Parsac','23'),('FR','PAB','Pont l\'Abbe','Pont l\'Abbe','29'),('FR','PAC','Pacy-sur-Eure','Pacy-sur-Eure','27'),('FR','PAE','Pace','Pace','35'),('FR','PAG','Pagny-sur-Meuse','Pagny-sur-Meuse','55'),('FR','PAI','Paimpol','Paimpol','22'),('FR','PAL','Palaiseau','Palaiseau','91'),('FR','PAM','Pont-a-Mousson','Pont-a-Mousson','54'),('FR','PAN','Pouance','Pouance','49'),('FR','PAO','Porcieu-Amblagnieu','Porcieu-Amblagnieu','38'),('FR','PAP','Pauillac','Pauillac','33'),('FR','PAR','Paris','Paris','75'),('FR','PAS','Pannes','Pannes','45'),('FR','PAT','Port d\'Atelier','Port d\'Atelier','70'),('FR','PAU','Paladru','Paladru','38'),('FR','PAV','Parcay-sur-Vienne','Parcay-sur-Vienne','37'),('FR','PAX','Pougues-les-Eaux','Pougues-les-Eaux','58'),('FR','PAY','Priay','Priay','01'),('FR','PAZ','Sainte-Pazanne','Sainte-Pazanne','44'),('FR','PBA','Portbail','Portbail','50'),('FR','PBF','Paimboeuf','Paimboeuf','44'),('FR','PBG','Puberg','Puberg','67'),('FR','PBL','St Pierre de Bailleul','St Pierre de Bailleul',''),('FR','PBT','Port-Brillet','Port-Brillet','53'),('FR','PBV','Le Pont-de-Beauvoisin','Le Pont-de-Beauvoisin','38'),('FR','PCA','Pont-du-Casse','Pont-du-Casse','47'),('FR','PCB','Portel-des-Corbieres','Portel-des-Corbieres','11'),('FR','PCE','Precigne','Precigne','72'),('FR','PCH','Puicheric','Puicheric','11'),('FR','PCI','Poix-de-Picardie','Poix-de-Picardie','80'),('FR','PCN','Pontcharra-sur-Turdine','Pontcharra-sur-Turdine','69'),('FR','PCO','Ponchon','Ponchon','60'),('FR','PCQ','Pontacq','Pontacq','64'),('FR','PCR','Pierrecourt','Pierrecourt','76'),('FR','PCS','Perenchies','Perenchies','59'),('FR','PCT','Pleucadeuc','Pleucadeuc','56'),('FR','PCU','Pont-du-Chateau','Pont-du-Chateau','63'),('FR','PCX','Le Pont-de-Claix','Le Pont-de-Claix','38'),('FR','PCY','Poincy','Poincy','77'),('FR','PDA','Pont-d\'Ain','Pont-d\'Ain','01'),('FR','PDB','Port-de-Bouc','Port-de-Bouc','13'),('FR','PDC','Plan de Campagne','Plan de Campagne','13'),('FR','PDE','Prades','Prades','66'),('FR','PDG','Le Plan-de-Grasse','Le Plan-de-Grasse',''),('FR','PDI','Pradines','Pradines','46'),('FR','PDN','Le Pas des Lanciers','Le Pas des Lanciers','13'),('FR','PDO','Plan-d\'Orgon','Plan-d\'Orgon','13'),('FR','PDP','Port-de-Piles','Port-de-Piles','86'),('FR','PDR','Pont du Rhin/Strasbourg','Pont du Rhin/Strasbourg','67'),('FR','PDS','Plougastel-Daoulas','Plougastel-Daoulas','29'),('FR','PDV','Pont-de-Veyle','Pont-de-Veyle','01'),('FR','PDX','St-Pierre-de-Varengeville','St-Pierre-de-Varengeville','76'),('FR','PDY','St Pierre-du-Vauvray','St Pierre-du-Vauvray','27'),('FR','PEA','Pouilly-en-Auxois','Pouilly-en-Auxois','21'),('FR','PEB','Parentis-en-Born','Parentis-en-Born','40'),('FR','PEC','Pessac','Pessac','33'),('FR','PEE','Peltre','Peltre','57'),('FR','PEG','Pegomas','Pegomas','06'),('FR','PEI','Periers','Periers','50'),('FR','PEL','Pellegrue','Pellegrue','33'),('FR','PEM','Pouilly-le-Monial','Pouilly-le-Monial','69'),('FR','PEN','Penne-d\'Agenais','Penne-d\'Agenais','47'),('FR','PEO','Peronne','Peronne','80'),('FR','PER','Le Peage-de-Roussillon','Le Peage-de-Roussillon','38'),('FR','PES','Peschadoires','Peschadoires','63'),('FR','PET','Petit Couronne','Petit Couronne','76'),('FR','PEU','Pieusse','Pieusse','11'),('FR','PEV','Pont-Eveque','Pont-Eveque','38'),('FR','PEX','Perreux','Perreux','42'),('FR','PEY','Peyrehorade','Peyrehorade','40'),('FR','PEZ','Pezenas','Pezenas','34'),('FR','PFA','Pfaffenhoffen','Pfaffenhoffen','67'),('FR','PFQ','Saint-Pierre-de-Franqueville','Saint-Pierre-de-Franqueville','76'),('FR','PFR','Ploufragan','Ploufragan','22'),('FR','PFV','Provencheres-sur-Fave','Provencheres-sur-Fave','88'),('FR','PGA','Port-le-Grand','Port-le-Grand','80'),('FR','PGF','Perpignan','Perpignan','66'),('FR','PGN','Pusignan','Pusignan','69'),('FR','PGO','Plougonvelin','Plougonvelin','29'),('FR','PGR','Perros-Guirec','Perros-Guirec','22'),('FR','PGS','Palinges','Palinges','71'),('FR','PGU','Pompignac','Pompignac','33'),('FR','PGV','Plougonver','Plougonver','22'),('FR','PGX','Perigueux','Perigueux','24'),('FR','PGY','Perigny','Perigny','17'),('FR','PHI','Saint-Philibert','Saint-Philibert','56'),('FR','PHL','Phalsbourg','Phalsbourg','57'),('FR','PHO','Saint-Symphorien-de-Lay','Saint-Symphorien-de-Lay','42'),('FR','PHP','Phalempin','Phalempin','59'),('FR','PHR','La Porcherie','La Porcherie','87'),('FR','PIA','Pia','Pia','66'),('FR','PIB','Pierre-Benite','Pierre-Benite','69'),('FR','PIC','Pierreclos','Pierreclos','71'),('FR','PIE','Pierrefitte','Pierrefitte',''),('FR','PIG','Pulligny','Pulligny','54'),('FR','PIH','Pineuilh','Pineuilh','33'),('FR','PIL','Pierrelaye','Pierrelaye','95'),('FR','PIM','St-Palais-sur-Mer','St-Palais-sur-Mer','17'),('FR','PIN','Piennes','Piennes','54'),('FR','PIO','Piolenc','Piolenc','84'),('FR','PIP','Pierrepont','Pierrepont',''),('FR','PIR','Piriac-sur-Mer','Piriac-sur-Mer','44'),('FR','PIS','Poitiers','Poitiers','86'),('FR','PIT','St Pierre-Toirac','St Pierre-Toirac','46'),('FR','PIU','Pierrefeu-du-Var','Pierrefeu-du-Var','83'),('FR','PIV','Pithiviers','Pithiviers','45'),('FR','PIY','Pirey','Pirey','25'),('FR','PJB','St Pierre-les-Elbeuf','St Pierre-les-Elbeuf','76'),('FR','PJE','Port-Jerome','Port-Jerome','76'),('FR','PJG','Prechacq-Josbaig','Prechacq-Josbaig','64'),('FR','PKS','Pouilly-sur-Loire','Pouilly-sur-Loire','58'),('FR','PLA','Plailly','Plailly','60'),('FR','PLB','Plumelin','Plumelin','56'),('FR','PLC','Pontault-Combault','Pontault-Combault','77'),('FR','PLD','Paris-La Defense','Paris-La Defense','92'),('FR','PLE','Puy-l\'Eveque','Puy-l\'Eveque','46'),('FR','PLF','Pouilly-les-Feurs','Pouilly-les-Feurs','42'),('FR','PLG','La Plagne','La Plagne','73'),('FR','PLH','Paulhaguet','Paulhaguet','43'),('FR','PLI','Plaisir','Plaisir','78'),('FR','PLL','Ploneour-Lanvern','Ploneour-Lanvern','29'),('FR','PLM','Paray-le-Monial','Paray-le-Monial','71'),('FR','PLN','Paulhan','Paulhan','34'),('FR','PLO','Plougasnou','Plougasnou','29'),('FR','PLP','Port-Launay','Port-Launay','29'),('FR','PLQ','Plelo','Plelo','22'),('FR','PLR','Plerin','Plerin','22'),('FR','PLS','Palis','Palis','10'),('FR','PLT','Le Plessis-Trevise','Le Plessis-Trevise','94'),('FR','PLU','Plouigneau','Plouigneau','29'),('FR','PLV','Pierrefontaine-les-Varans','Pierrefontaine-les-Varans','25'),('FR','PLY','Pleyber-Christ','Pleyber-Christ','29'),('FR','PLZ','Plouzane','Plouzane','29'),('FR','PMA','Pont-a-Marcq','Pont-a-Marcq','59'),('FR','PMB','Pont-Trambouze','Pont-Trambouze','69'),('FR','PMC','Plounevez-Moedec','Plounevez-Moedec','22'),('FR','PMD','Pommard','Pommard','21'),('FR','PME','Parcay-Meslay','Parcay-Meslay','37'),('FR','PMG','Ploumoguer','Ploumoguer','29'),('FR','PMH','Ploumanac\'h','Ploumanac\'h','22'),('FR','PMM','La Pommeraye','La Pommeraye','49'),('FR','PMP','Parempuyre','Parempuyre','33'),('FR','PMR','Ploumagoar','Ploumagoar','22'),('FR','PMS','Pamiers','Pamiers','09'),('FR','PMT','Plemet','Plemet','22'),('FR','PMY','Premery','Premery','58'),('FR','PNA','Pontcharra','Pontcharra','38'),('FR','PNB','Poncin','Poncin','01'),('FR','PNC','Pontchateau','Pontchateau','44'),('FR','PND','Pont-de-Dore','Pont-de-Dore','63'),('FR','PNE','La Possonniere','La Possonniere','49'),('FR','PNH','Pont-d\'Ouche','Pont-d\'Ouche','21'),('FR','PNI','Panissieres','Panissieres','42'),('FR','PNN','Pontarion','Pontarion','23'),('FR','PNO','Plancoet','Plancoet','22'),('FR','PNQ','Pontonx-sur-l\'Adour','Pontonx-sur-l\'Adour','40'),('FR','PNR','Pont-Remy','Pont-Remy','80'),('FR','PNS','Pons','Pons','17'),('FR','PNT','Pinet','Pinet','34'),('FR','PNU','Paillencourt','Paillencourt','59'),('FR','PNX','Prigonrieux','Prigonrieux','24'),('FR','POA','Pont-Audemer','Pont-Audemer','27'),('FR','POB','Pontaubault','Pontaubault','50'),('FR','POC','Pont-de-Cheruy','Pont-de-Cheruy','38'),('FR','POD','Podensac','Podensac','33'),('FR','POE','Pont-l\'Eveque','Pont-l\'Eveque','14'),('FR','POF','Port','Port','01'),('FR','POH','Poule-les-Echarmeaux','Poule-les-Echarmeaux','69'),('FR','POI','Poissy','Poissy','78'),('FR','POL','Poligny','Poligny',''),('FR','POM','Pomacle','Pomacle','51'),('FR','PON','Pontarlier','Pontarlier','25'),('FR','POO','Pomerols','Pomerols','34'),('FR','POP','Plescop','Plescop','56'),('FR','POR','Portes-les-Valence','Portes-les-Valence','26'),('FR','POS','Perols','Perols','34'),('FR','POT','La Poterie','La Poterie','22'),('FR','POU','Poullaouen','Poullaouen','29'),('FR','POV','Port-Vendres','Port-Vendres','66'),('FR','POX','Pontrieux','Pontrieux','22'),('FR','POY','Prouvy','Prouvy','59'),('FR','POZ','Pouzauges','Pouzauges','85'),('FR','PPR','Pipriac','Pipriac','35'),('FR','PPX','Pamproux','Pamproux','79'),('FR','PPY','Pont-de-Pany','Pont-de-Pany','21'),('FR','PQC','Pont-Rean','Pont-Rean','35'),('FR','PQE','Poses','Poses','27'),('FR','PQS','Pernes','Pernes','62'),('FR','PRA','Prauthoy','Prauthoy','52'),('FR','PRC','Pornic','Pornic','44'),('FR','PRE','Preignac','Preignac','33'),('FR','PRG','Perrignier','Perrignier','74'),('FR','PRH','Prahecq','Prahecq','79'),('FR','PRI','Pringy','Pringy',''),('FR','PRJ','Port-Joinville','Port-Joinville','85'),('FR','PRL','Ploermel','Ploermel','56'),('FR','PRM','Prevessin-Moens','Prevessin-Moens','01'),('FR','PRN','Parnac','Parnac',''),('FR','PRP','Propriano','Propriano','2A'),('FR','PRR','Pierrelatte','Pierrelatte','26'),('FR','PRS','Persan','Persan','95'),('FR','PRT','Portet-sur-Garonne','Portet-sur-Garonne','31'),('FR','PRU','Prunay','Prunay','51'),('FR','PRV','Privas','Privas','07'),('FR','PRW','Proville','Proville','59'),('FR','PRX','Parcieux','Parcieux','01'),('FR','PRY','Perrigny','Perrigny','21'),('FR','PSA','Port-sur-Saone','Port-sur-Saone','70'),('FR','PSC','Prayssac','Prayssac','46'),('FR','PSE','Pont-Saint-Esprit','Pont-Saint-Esprit','30'),('FR','PSG','Puget-sur-Argens','Puget-sur-Argens','83'),('FR','PSJ','Pins-Justaret','Pins-Justaret','31'),('FR','PSL','Port-Saint-Louis-du-Rhone','Port-Saint-Louis-du-Rhone','13'),('FR','PSM','Pont-Saint-Martin','Pont-Saint-Martin','44'),('FR','PSN','Palluau-sur-Indre','Palluau-sur-Indre','36'),('FR','PSO','Precy-sur-Oise','Precy-sur-Oise','60'),('FR','PSP','Pont-Saint-Pierre','Pont-Saint-Pierre','27'),('FR','PSQ','Pusey','Pusey','70'),('FR','PSR','Pouilly-sur-Serre','Pouilly-sur-Serre','02'),('FR','PSS','Portet St Simon','Portet St Simon','31'),('FR','PST','Pont-Saint-Vincent','Pont-Saint-Vincent','54'),('FR','PSU','Passy','Passy','74'),('FR','PSV','Le Poire-sur-Vie','Le Poire-sur-Vie','85'),('FR','PSX','Pont-Sainte-Maxence','Pont-Sainte-Maxence','60'),('FR','PSY','Pont-sur-Yonne','Pont-sur-Yonne','89'),('FR','PTA','Pontanevaux','Pontanevaux','71'),('FR','PTB','Petersbach','Petersbach','67'),('FR','PTE','Pontoise','Pontoise','95'),('FR','PTF','Petite Foret','Petite Foret','59'),('FR','PTL','Plaintel','Plaintel','22'),('FR','PTM','Pont-Sainte-Marie','Pont-Sainte-Marie','10'),('FR','PTN','Porte Neuve/Dijon','Porte Neuve/Dijon','21'),('FR','PTQ','Le Petit-Quevilly','Le Petit-Quevilly','76'),('FR','PTR','Petit-Rederching','Petit-Rederching','57'),('FR','PTU','Pertuis','Pertuis','84'),('FR','PTV','Pontavert','Pontavert','02'),('FR','PTY','Parthenay','Parthenay','79'),('FR','PTZ','Pratz','Pratz','39'),('FR','PUA','Pluguffan','Pluguffan','29'),('FR','PUC','Pugnac','Pugnac','33'),('FR','PUE','Pruniers','Pruniers','36'),('FR','PUF','Pau','Pau','64'),('FR','PUG','Puy-Guillaume','Puy-Guillaume','63'),('FR','PUI','La Puye','La Puye','86'),('FR','PUJ','Pujo','Pujo','65'),('FR','PUL','Pulversheim','Pulversheim','68'),('FR','PUM','Precy-sur-Marne','Precy-sur-Marne','77'),('FR','PUN','Pulnoy','Pulnoy','54'),('FR','PUO','Puiseaux','Puiseaux','45'),('FR','PUQ','Pure','Pure','08'),('FR','PUR','Ploemeur','Ploemeur','56'),('FR','PUT','Puteaux','Puteaux','92'),('FR','PUU','Puisseguin','Puisseguin','33'),('FR','PUX','Pouxeux','Pouxeux','88'),('FR','PUY','Puyoo','Puyoo','64'),('FR','PVA','Plainval','Plainval','60'),('FR','PVE','Porcheville','Porcheville','78'),('FR','PVG','Pluvigner','Pluvigner','56'),('FR','PVI','Pierreville','Pierreville','54'),('FR','PVL','Picauville','Picauville','50'),('FR','PVO','Porto Vecchio','Porto Vecchio','2A'),('FR','PVP','Provins','Provins','77'),('FR','PVQ','Pont l\'Eveque','Pont l\'Eveque','60'),('FR','PVR','Capvern','Capvern','65'),('FR','PVT','Passavant-la-Rochere','Passavant-la-Rochere','70'),('FR','PVV','Pernand-Vergelesses','Pernand-Vergelesses','21'),('FR','PVX','Pont-de-Vaux','Pont-de-Vaux','01'),('FR','PVY','Pontivy','Pontivy','56'),('FR','PXL','Presles','Presles','95'),('FR','PXT','Poix-Terron','Poix-Terron','08'),('FR','PXU','Pennautier','Pennautier','11'),('FR','PYB','Puybrun','Puybrun','46'),('FR','PYC','Pagny-le-Chateau','Pagny-le-Chateau','21'),('FR','PYG','Prunay-le-Gillon','Prunay-le-Gillon','28'),('FR','PYI','Peyrilhac','Peyrilhac','87'),('FR','PYL','Pouilly-sous-Charlieu','Pouilly-sous-Charlieu','42'),('FR','PYM','Puligny-Montrachet','Puligny-Montrachet','21'),('FR','PYN','Peynier','Peynier','13'),('FR','PYP','Peypin ','Peypin ','13'),('FR','PYR','Peyrins','Peyrins','26'),('FR','PYS','Peyruis','Peyruis','04'),('FR','PYV','Le Perray-en-Yvelines','Le Perray-en-Yvelines','78'),('FR','PYY','Percy','Percy','50'),('FR','PZA','Pranzac','Pranzac','16'),('FR','PZE','Prisse','Prisse','71'),('FR','PZO','Panzoult','Panzoult','37'),('FR','PZP','St Pierre-de-Plesguen','St Pierre-de-Plesguen','35'),('FR','QAY','Saclay','Saclay','91'),('FR','QBO','Bou','Bou','45'),('FR','QCE','Crest','Crest','26'),('FR','QCO','Creon','Creon','33'),('FR','QCR','Corte','Corte','2B'),('FR','QCS','Cleres','Cleres','76'),('FR','QDO','Mont-Dore','Mont-Dore','63'),('FR','QEB','Quincie-en-Beaujolais','Quincie-en-Beaujolais','69'),('FR','QFI','Baille','Baille','35'),('FR','QGO','Lesgor','Lesgor','40'),('FR','QGS','Soulanges','Soulanges','51'),('FR','QKK','Breal-sous-Montfort','Breal-sous-Montfort','35'),('FR','QLE','Le Mee','Le Mee','28'),('FR','QLN','Quillan','Quillan','11'),('FR','QLO','Ablon','Ablon','14'),('FR','QLY','Pavilly','Pavilly','76'),('FR','QMO','Camors','Camors','56'),('FR','QMP','Quimperle','Quimperle','29'),('FR','QMU','Moutiers','Moutiers','73'),('FR','QMY','Machy','Machy','10'),('FR','QMZ','St Macaire','St Macaire','33'),('FR','QNA','Annay','Annay','58'),('FR','QNX','Quincieux','Quincieux','69'),('FR','QNY','Quesnoy','Quesnoy',''),('FR','QOL','Dol','Dol','23'),('FR','QPI','Provin','Provin','59'),('FR','QPY','Quaedypre','Quaedypre','59'),('FR','QRO','Ors','Ors','59'),('FR','QSE','Lesse','Lesse','57'),('FR','QSG','Quelaines-Saint-Gault','Quelaines-Saint-Gault','53'),('FR','QSN','Le Quesne','Le Quesne','80'),('FR','QSR','St Romain-en-Gal','St Romain-en-Gal','69'),('FR','QST','Oust','Oust','09'),('FR','QTC','Quintenic','Quintenic','22'),('FR','QUB','Quebriac','Quebriac','35'),('FR','QUE','Queven','Queven','56'),('FR','QUI','Quiberon','Quiberon','56'),('FR','QUS','Quessoy','Quessoy','22'),('FR','QUT','Quetigny','Quetigny','21'),('FR','QUV','Quevert','Quevert','22'),('FR','QVA','Lavau','Lavau','10'),('FR','QVI','Quevauvillers','Quevauvillers','80'),('FR','QXB','Aix-en-Provence','Aix-en-Provence','13'),('FR','QYR','Troyes','Troyes','10'),('FR','RAB','Rambervillers','Rambervillers','88'),('FR','RAC','Brossac','Brossac','16'),('FR','RAD','Radicatel','Radicatel','55'),('FR','RAE','Braine','Braine','02'),('FR','RAG','Marsangy','Marsangy','89'),('FR','RAI','Raival','Raival','55'),('FR','RAL','Breval','Breval','78'),('FR','RAM','Raismes','Raismes','59'),('FR','RAN','Rantigny','Rantigny','60'),('FR','RAR','La Roche-des-Arnauds','La Roche-des-Arnauds','05'),('FR','RAS','Rasteau','Rasteau','84'),('FR','RAT','Garat','Garat','16'),('FR','RAV','Cravant','Cravant','89'),('FR','RAX','Rai','Rai','61'),('FR','RBA','Rebais','Rebais','77'),('FR','RBC','Briec','Briec','29'),('FR','RBE','Ribiers','Ribiers','05'),('FR','RBM','Ribemont','Ribemont','02'),('FR','RBN','Brochon','Brochon','21'),('FR','RBO','Harbonnieres','Harbonnieres','80'),('FR','RBS','Rombas','Rombas','57'),('FR','RBT','Rambouillet','Rambouillet','78'),('FR','RBY','Barberey-Saint-Sulpice','Barberey-Saint-Sulpice','10'),('FR','RCA','Racrange','Racrange','57'),('FR','RCB','Rochecorbon','Rochecorbon','37'),('FR','RCC','Rochefort','Rochefort','21'),('FR','RCD','Rocamadour','Rocamadour','46'),('FR','RCE','Brece','Brece','35'),('FR','RCI','Arcueil','Arcueil','94'),('FR','RCN','Arc-et-Senans','Arc-et-Senans','25'),('FR','RCO','Rochefort','Rochefort','17'),('FR','RCP','Ronchamp','Ronchamp','70'),('FR','RCS','Rochefort','Rochefort','73'),('FR','RCT','Raucourt-et-Flaba','Raucourt-et-Flaba','08'),('FR','RCU','Racecourt','Racecourt','88'),('FR','RCY','Courcay','Courcay','37'),('FR','RDA','Riviers-d\'Allemond','Riviers-d\'Allemond','38'),('FR','RDC','Radenac','Radenac',''),('FR','RDE','Ardes','Ardes','63'),('FR','RDI','St Medard-sur-Ille','St Medard-sur-Ille','35'),('FR','RDL','Rion-des-Landes','Rion-des-Landes','40'),('FR','RDM','La Couarde-sur-Mer','La Couarde-sur-Mer','17'),('FR','RDN','Redon','Redon','35'),('FR','RDO','St-Romain-au-Mont-d\'Or','St-Romain-au-Mont-d\'Or','69'),('FR','RDR','St Pierre-du-Regard','St Pierre-du-Regard','61'),('FR','RDU','Regnie-Durette','Regnie-Durette','69'),('FR','RDY','Lardy','Lardy','91'),('FR','RDZ','Rodez','Rodez','12'),('FR','REA','Reau','Reau','77'),('FR','REB','Roissy-en-Brie','Roissy-en-Brie','77'),('FR','REC','Recquignies','Recquignies','59'),('FR','REE','La Feree','La Feree','08'),('FR','REG','Remigny','Remigny','71'),('FR','REH','Rethel','Rethel','08'),('FR','REI','Reichstett','Reichstett','67'),('FR','REL','Remalard','Remalard','61'),('FR','REM','Remoulins','Remoulins','30'),('FR','REN','Renaze','Renaze','53'),('FR','REP','Crepy-en-Laonnois','Crepy-en-Laonnois','02'),('FR','REQ','Requista','Requista','12'),('FR','RER','La Verriere','La Verriere','78'),('FR','RES','Rosieres-en-Santerre','Rosieres-en-Santerre','80'),('FR','RET','Realmont','Realmont','81'),('FR','REV','Revigny-sur-Ornain','Revigny-sur-Ornain','55'),('FR','REY','Remy','Remy','60'),('FR','REZ','Reze','Reze','44'),('FR','RFF','Ruffec','Ruffec','16'),('FR','RFI','Rang-du-Fliers','Rang-du-Fliers','62'),('FR','RFM','Rochefort-Montagne','Rochefort-Montagne','63'),('FR','RFN','Romelfing','Romelfing','57'),('FR','RFO','St Roch','St Roch','37'),('FR','RGA','Reignac','Reignac','33'),('FR','RGC','Rougnac','Rougnac','16'),('FR','RGD','Caissargues','Caissargues','30'),('FR','RGE','Renage','Renage','38'),('FR','RGL','Rugles','Rugles','27'),('FR','RGN','Rognes','Rognes','13'),('FR','RGQ','Reignac','Reignac','16'),('FR','RGR','Reignac-sur-Indre','Reignac-sur-Indre','37'),('FR','RGS','Riom-es-Montagne','Riom-es-Montagne','15'),('FR','RGT','Rougemont','Rougemont','25'),('FR','RHE','Reims','Reims','51'),('FR','RHN','Rehon','Rehon','54'),('FR','RHV','Rehainviller','Rehainviller','54'),('FR','RHY','Curchy','Curchy','80'),('FR','RIA','Rians','Rians','18'),('FR','RIB','Ribecourt-Dreslincourt','Ribecourt-Dreslincourt','60'),('FR','RIC','Richwiller','Richwiller','68'),('FR','RID','Riedisheim','Riedisheim','68'),('FR','RIE','Rieux','Rieux',''),('FR','RIG','Riorges','Riorges','42'),('FR','RIH','Ria-Sirach','Ria-Sirach','66'),('FR','RIL','Rillieux-la-Pape','Rillieux-la-Pape','69'),('FR','RIM','Rimaucourt','Rimaucourt','52'),('FR','RIN','Rinxent','Rinxent','62'),('FR','RIO','Riom','Riom','63'),('FR','RIQ','Riquewihr','Riquewihr','68'),('FR','RIR','Riberac','Riberac','24'),('FR','RIS','Riscle','Riscle','32'),('FR','RIU','Richelieu','Richelieu','37'),('FR','RIV','Rivesaltes','Rivesaltes','66'),('FR','RIY','Briey','Briey','54'),('FR','RIZ','Rioz','Rioz','70'),('FR','RLA','Villers le Lac','Villers le Lac','25'),('FR','RLC','St Romain-Lachalm','St Romain-Lachalm','43'),('FR','RLE','Ruffey-les-Echirey','Ruffey-les-Echirey','21'),('FR','RLG','Brulange','Brulange','57'),('FR','RLH','Rumersheim-le-Haut','Rumersheim-le-Haut','68'),('FR','RLI','Ramillies','Ramillies','59'),('FR','RLL','Reuilly','Reuilly','36'),('FR','RLM','Raissac-sur-Lampy','Raissac-sur-Lampy','11'),('FR','RLO','Varennes-sur-Loire','Varennes-sur-Loire','49'),('FR','RLP','Raon-l\'Etape','Raon-l\'Etape','88'),('FR','RLR','Mars-la-Tour','Mars-la-Tour','54'),('FR','RLS','Brouvelieures','Brouvelieures','88'),('FR','RLT','Roullet-Saint-Estephe','Roullet-Saint-Estephe','16'),('FR','RLU','Ruelle-sur-Touvre','Ruelle-sur-Touvre','16'),('FR','RLV','Realville','Realville','82'),('FR','RLY','Breil-sur-Roya','Breil-sur-Roya','06'),('FR','RMB','Raimbeaucourt','Raimbeaucourt','59'),('FR','RMC','Rombach-le-Franc','Rombach-le-Franc','68'),('FR','RME','Armentieres','Armentieres','59'),('FR','RMF','Remelfang','Remelfang','57'),('FR','RMG','Romagne','Romagne','35'),('FR','RMI','Saint-Remy','Saint-Remy','14'),('FR','RML','Richardmenil','Richardmenil','54'),('FR','RMM','Remiremont','Remiremont','88'),('FR','RMN','Romainville','Romainville','93'),('FR','RMP','Ramonchamp','Ramonchamp','88'),('FR','RMS','Rieux-Minervois','Rieux-Minervois','11'),('FR','RMW','St-Remy','St-Remy','12'),('FR','RMY','Remy','Remy','62'),('FR','RMZ','Roumazieres-Loubert','Roumazieres-Loubert','16'),('FR','RNA','Barnay','Barnay','71'),('FR','RNC','Gornac','Gornac','33'),('FR','RND','Randan','Randan',''),('FR','RNE','Roanne','Roanne','42'),('FR','RNG','Ris-Orangis','Ris-Orangis','91'),('FR','RNI','Sarre-Union','Sarre-Union','67'),('FR','RNL','St Martin-Labouval','St Martin-Labouval','46'),('FR','RNO','Bernouville','Bernouville','27'),('FR','RNS','Rennes','Rennes','35'),('FR','RNT','Barenton','Barenton','50'),('FR','RNU','St-Laurent-en-Grandvaux','St-Laurent-en-Grandvaux','39'),('FR','RNV','Reventin-Vaugris','Reventin-Vaugris','38'),('FR','ROA','Roman','Roman','27'),('FR','ROB','St-Romain-de-Benet','St-Romain-de-Benet','17'),('FR','ROC','Roche-la-Moliere','Roche-la-Moliere','42'),('FR','ROD','Rosendael','Rosendael','59'),('FR','ROE','Roannes-Saint-Mary','Roannes-Saint-Mary','15'),('FR','ROG','Rognac','Rognac','13'),('FR','ROH','Rohan','Rohan','56'),('FR','ROI','Roissy-en-France','Roissy-en-France','95'),('FR','ROL','Rouillac','Rouillac','22'),('FR','ROM','Rochemaure','Rochemaure','07'),('FR','RON','Roncq','Roncq','59'),('FR','ROO','Orleans Sta/Rouen','Orleans Sta/Rouen','76'),('FR','ROP','Roppentzwiller','Roppentzwiller','68'),('FR','ROQ','Rixheim','Rixheim','68'),('FR','ROR','Rorthais','Rorthais','79'),('FR','ROS','Roscoff','Roscoff','29'),('FR','ROT','Romaneche-Thorins','Romaneche-Thorins','71'),('FR','ROU','Roubaix','Roubaix','59'),('FR','ROV','Rogerville','Rogerville','76'),('FR','ROX','Royeres','Royeres','87'),('FR','ROY','Rouy','Rouy','58'),('FR','RPD','Rosporden','Rosporden','29'),('FR','RPE','Latrape','Latrape','31'),('FR','RPL','Replonges','Replonges','01'),('FR','RPP','Roppe','Roppe','90'),('FR','RPR','Rosieres-pres-Troyes','Rosieres-pres-Troyes','10'),('FR','RPS','Recoules-Previnquieres','Recoules-Previnquieres','12'),('FR','RPT','Saint-Genest-Lerpt','Saint-Genest-Lerpt','42'),('FR','RPY','Rieupeyroux','Rieupeyroux',''),('FR','RQB','Roquefort-la-Bedoule','Roquefort-la-Bedoule','13'),('FR','RQE','Rech','Rech','57'),('FR','RQF','Roquefort','Roquefort',''),('FR','RQN','Roquebrun','Roquebrun','34'),('FR','RQS','Roqueseriere','Roqueseriere','31'),('FR','RQT','Roquettes','Roquettes','31'),('FR','RQU','Roquebrune-Cap-Martin','Roquebrune-Cap-Martin','06'),('FR','RQV','Roques','Roques','32'),('FR','RRE','Serres-Castet','Serres-Castet','64'),('FR','RRG','Larringes','Larringes','74'),('FR','RRI','Le Perrier','Le Perrier','85'),('FR','RRL','Romorantin-Lanthenay','Romorantin-Lanthenay','41'),('FR','RRN','Laperriere-sur-Saone','Laperriere-sur-Saone','21'),('FR','RRO','Ciron','Ciron','36'),('FR','RRT','Marssac-sur-Tarn','Marssac-sur-Tarn','81'),('FR','RRY','Rivery','Rivery','80'),('FR','RSA','Roquebrune-sur-Argens','Roquebrune-sur-Argens','83'),('FR','RSB','Brides-les-Bains','Brides-les-Bains','73'),('FR','RSC','Renescure','Renescure','59'),('FR','RSE','Bressuire','Bressuire','79'),('FR','RSG','Razac-de-Saussignac','Razac-de-Saussignac','24'),('FR','RSH','Raedersheim','Raedersheim','68'),('FR','RSI','Rousies','Rousies','59'),('FR','RSL','St Lary-Soulan','St Lary-Soulan','65'),('FR','RSM','Ressons-sur-Matz','Ressons-sur-Matz','60'),('FR','RSN','Roussillon','Roussillon','38'),('FR','RSO','Crouy-sur-Ourcq','Crouy-sur-Ourcq','77'),('FR','RSP','La Rue-Saint-Pierre','La Rue-Saint-Pierre','76'),('FR','RSR','Roches-sur-Marne','Roches-sur-Marne','52'),('FR','RSS','Romilly-sur-Seine','Romilly-sur-Seine','10'),('FR','RST','Rousset','Rousset','13'),('FR','RSU','Romans-sur-Isere','Romans-sur-Isere','26'),('FR','RSV','Rouesse-Vasse','Rouesse-Vasse','72'),('FR','RTA','Ribaute-les-Tavernes','Ribaute-les-Tavernes','30'),('FR','RTC','Roocourt-la-Cote','Roocourt-la-Cote','52'),('FR','RTE','Bourg-Charente','Bourg-Charente','16'),('FR','RTH','Arinthod','Arinthod','39'),('FR','RTJ','Retjons','Retjons',''),('FR','RTM','Rupt-sur-Moselle','Rupt-sur-Moselle','88'),('FR','RTN','Merten','Merten','57'),('FR','RTR','Reterre','Reterre','23'),('FR','RTS','Rots','Rots','14'),('FR','RTU','Courteuil','Courteuil','60'),('FR','RTY','Bertry','Bertry','59'),('FR','RUA','Ruaudin','Ruaudin','72'),('FR','RUC','Ruch','Ruch','33'),('FR','RUE','Rueil-Malmaison','Rueil-Malmaison','92'),('FR','RUF','Rouffach','Rouffach','68'),('FR','RUI','Rouillac','Rouillac','16'),('FR','RUL','Rully','Rully',''),('FR','RUM','Rumilly','Rumilly',''),('FR','RUN','Rungis','Rungis','94'),('FR','RUO','Ruoms','Ruoms','07'),('FR','RUP','Ruppes','Ruppes','88'),('FR','RUQ','Ruan','Ruan','45'),('FR','RUR','Plouer-sur-Rance','Plouer-sur-Rance','22'),('FR','RUT','Reaumont','Reaumont','38'),('FR','RUX','Courlaoux','Courlaoux','39'),('FR','RUY','Rouvray','Rouvray','59'),('FR','RUZ','Ruitz','Ruitz','62'),('FR','RVA','Rouvroy-sur-Audry','Rouvroy-sur-Audry','08'),('FR','RVB','Ribeauville','Ribeauville','68'),('FR','RVC','Rivecourt','Rivecourt','60'),('FR','RVE','Revel','Revel','38'),('FR','RVF','Revin','Revin','08'),('FR','RVG','Rive-de-Gier','Rive-de-Gier','42'),('FR','RVL','Revel','Revel','31'),('FR','RVN','St Reverend','St Reverend','85'),('FR','RVO','Rouvignies','Rouvignies','59'),('FR','RVR','Ravieres','Ravieres','89'),('FR','RVS','Rives','Rives','38'),('FR','RWI','Reville','Reville','50'),('FR','RWR','Romanswiller','Romanswiller','67'),('FR','RXB','Rouxmesnil-Bouteilles','Rouxmesnil-Bouteilles','76'),('FR','RXL','Rosieres-aux-Salines','Rosieres-aux-Salines','54'),('FR','RXZ','St Medard-de-Guizieres','St Medard-de-Guizieres','33'),('FR','RYB','Rosny-sous-Bois','Rosny-sous-Bois','93'),('FR','RYC','Remilly-Aillicourt','Remilly-Aillicourt','08'),('FR','RYD','Rochy-Conde','Rochy-Conde','60'),('FR','RYE','Roye','Roye','80'),('FR','RYL','Rouilly-Saint-Loup','Rouilly-Saint-Loup','10'),('FR','RYM','Charnay-les-Macon','Charnay-les-Macon','71'),('FR','RYN','Royan','Royan','17'),('FR','RYR','Carry-le-Rouet','Carry-le-Rouet','13'),('FR','RYS','Creysse','Creysse','24'),('FR','RYU','Reyrieux','Reyrieux','01'),('FR','RYV','St-Remy-sur-Avre','St-Remy-sur-Avre','28'),('FR','RZE','Toulouzette','Toulouzette','40'),('FR','RZH','Rountzenheim','Rountzenheim','67'),('FR','RZN','Arzon','Arzon','56'),('FR','RZS','Rozoy-sur-Serre','Rozoy-sur-Serre','02'),('FR','RZY','Vierzy','Vierzy','02'),('FR','SAA','Saint-Ave','Saint-Ave','56'),('FR','SAB','Sablon/Metz','Sablon/Metz','57'),('FR','SAC','Salses-le-Chateau','Salses-le-Chateau','66'),('FR','SAD','St Andre-de-Boege','St Andre-de-Boege','74'),('FR','SAE','St Andre-de-l\'Eure','St Andre-de-l\'Eure','27'),('FR','SAF','St Antoine-de-Ficalba','St Antoine-de-Ficalba','47'),('FR','SAG','St Aignan','St Aignan',''),('FR','SAH','St Andre-d\'Hebertot','St Andre-d\'Hebertot','14'),('FR','SAI','Salindres','Salindres','30'),('FR','SAL','Salaise-sur-Sanne','Salaise-sur-Sanne','38'),('FR','SAM','St Ame','St Ame','88'),('FR','SAN','St Alban-de-Roche','St Alban-de-Roche','38'),('FR','SAO','St Amand-Longpre','St Amand-Longpre','41'),('FR','SAP','St Apollinare','St Apollinare',''),('FR','SAQ','St Affrique','St Affrique','12'),('FR','SAR','Sarreguemines','Sarreguemines','57'),('FR','SAS','Salernes','Salernes','83'),('FR','SAT','Sautron','Sautron','44'),('FR','SAU','Saumur','Saumur','49'),('FR','SAV','Saverne','Saverne','67'),('FR','SAW','St Witz','St Witz','95'),('FR','SAX','Saint-Maixant','Saint-Maixant','33'),('FR','SAY','Saint-Martin-d\'Aubigny','Saint-Martin-d\'Aubigny','50'),('FR','SAZ','Saint-Avit-Saint-Nazaire','Saint-Avit-Saint-Nazaire','33'),('FR','SBA','Sainte-Bazeille','Sainte-Bazeille','47'),('FR','SBB','Sain-Bel','Sain-Bel','69'),('FR','SBC','St Bonnet-le-Chateau','St Bonnet-le-Chateau','42'),('FR','SBD','St Cibard','St Cibard','33'),('FR','SBE','Steenbecque','Steenbecque','59'),('FR','SBF','St Brice-sous-Foret','St Brice-sous-Foret','95'),('FR','SBG','Sarrebourg','Sarrebourg','57'),('FR','SBH','St Blaise-la-Roche','St Blaise-la-Roche','67'),('FR','SBI','Saint-Aubin-sur-Mer','Saint-Aubin-sur-Mer','14'),('FR','SBJ','St-Simon-de-Bordes','St-Simon-de-Bordes','17'),('FR','SBK','St Brieuc','St Brieuc','22'),('FR','SBL','Savy-Berlette','Savy-Berlette','62'),('FR','SBM','St Samson-de-Bonfosse','St Samson-de-Bonfosse','50'),('FR','SBN','Saint-Bonnet','Saint-Bonnet','16'),('FR','SBO','Saint-Auban-sur-L\'Ouveze','Saint-Auban-sur-L\'Ouveze','26'),('FR','SBP','St-Benoit-du-Sault','St-Benoit-du-Sault','36'),('FR','SBQ','Satolas-et-Bonce','Satolas-et-Bonce','38'),('FR','SBR','Sault-Brenaz','Sault-Brenaz','01'),('FR','SBS','St Clement-des-Baleines','St Clement-des-Baleines','17'),('FR','SBT','St Benoit-la-Foret','St Benoit-la-Foret','37'),('FR','SBU','St Martin-le-Beau','St Martin-le-Beau','37'),('FR','SBV','Steinbourg','Steinbourg','67'),('FR','SBY','St Barthelemy-d\'Anjou','St Barthelemy-d\'Anjou','49'),('FR','SBZ','Saint-Bauzille-de-Putois','Saint-Bauzille-de-Putois','34'),('FR','SCA','Scaer','Scaer','29'),('FR','SCB','St Caprais-de-Bordeaux','St Caprais-de-Bordeaux','33'),('FR','SCC','St Cyr-sur-Loire','St Cyr-sur-Loire','37'),('FR','SCD','St Chamond','St Chamond','42'),('FR','SCE','St-Cyr-en-Bourg','St-Cyr-en-Bourg','49'),('FR','SCF','St Chef','St Chef','38'),('FR','SCG','St Ciers-sur-Gironde','St Ciers-sur-Gironde','33'),('FR','SCH','Schiltigheim','Schiltigheim','67'),('FR','SCI','St Calais','St Calais','72'),('FR','SCJ','St-Cricq-Chalosse','St-Cricq-Chalosse','40'),('FR','SCK','St-Cybranet','St-Cybranet','24'),('FR','SCL','St Claud','St Claud','16'),('FR','SCM','Saint-Cyr-sur-Menthon','Saint-Cyr-sur-Menthon','01'),('FR','SCN','Seclin','Seclin','59'),('FR','SCO','St Come','St Come','33'),('FR','SCP','St Crepin','St Crepin','05'),('FR','SCQ','Semecourt','Semecourt','57'),('FR','SCR','St Clair-du-Rhone','St Clair-du-Rhone','38'),('FR','SCS','Sallanches','Sallanches','74'),('FR','SCT','St Clair-de-la-Tour','St Clair-de-la-Tour','38'),('FR','SCU','St Antoine-Cumond','St Antoine-Cumond','24'),('FR','SCV','St-Cosme-en-Vairais','St-Cosme-en-Vairais','72'),('FR','SCW','Schweighausen-sur-Moder','Schweighausen-sur-Moder','67'),('FR','SCX','St Cheron','St Cheron','91'),('FR','SCY','Saint-Cyprien/Toulouse','Saint-Cyprien/Toulouse','31'),('FR','SCZ','Scionzier','Scionzier','74'),('FR','SDA','St Laurent-d\'Agny','St Laurent-d\'Agny','69'),('FR','SDB','St Germain-du-Bel-Air','St Germain-du-Bel-Air','46'),('FR','SDC','Saint Aubin du Cormier','Saint Aubin du Cormier','35'),('FR','SDD','St Doulchard','St Doulchard','18'),('FR','SDE','St Jean-d\'Ardieres','St Jean-d\'Ardieres','69'),('FR','SDF','St-Bonnet-de-Rochefort','St-Bonnet-de-Rochefort','03'),('FR','SDG','Salin-de-Giraud','Salin-de-Giraud','13'),('FR','SDH','St-Sulpice-de-Faleyrens','St-Sulpice-de-Faleyrens','33'),('FR','SDI','St Die','St Die','88'),('FR','SDL','St Aubin-des-Landes','St Aubin-des-Landes','35'),('FR','SDM','Saint-Amand-Montrond','Saint-Amand-Montrond','18'),('FR','SDN','St Leonard-de-Noblat','St Leonard-de-Noblat','87'),('FR','SDO','St Symphorien-d\'Ozon','St Symphorien-d\'Ozon','69'),('FR','SDP','Salon-de-Provence','Salon-de-Provence','13'),('FR','SDR','Serezin-du-Rhone','Serezin-du-Rhone','69'),('FR','SDS','Saint-Gaudens','Saint-Gaudens','31'),('FR','SDT','St Sebastien-de-Morsent','St Sebastien-de-Morsent','27'),('FR','SDV','St-Didier-sous-Riverie','St-Didier-sous-Riverie','69'),('FR','SDX','St Didier-sur-Arroux','St Didier-sur-Arroux','71'),('FR','SDY','St Didier-en-Velay','St Didier-en-Velay','43'),('FR','SDZ','Saint-Dizant-du-Gua','Saint-Dizant-du-Gua','17'),('FR','SEA','Senas','Senas','13'),('FR','SEB','St Gervais-en-Belin','St Gervais-en-Belin','72'),('FR','SEC','Serre-Chevalier','Serre-Chevalier','05'),('FR','SED','Sedan','Sedan','08'),('FR','SEE','St Menet','St Menet','13'),('FR','SEF','Strueth','Strueth','68'),('FR','SEG','Segoufielle','Segoufielle','32'),('FR','SEH','Seichamps','Seichamps','54'),('FR','SEI','Senlis','Senlis','62'),('FR','SEJ','Sevran','Sevran','93'),('FR','SEL','Selestat','Selestat','67'),('FR','SEM','St Eloy-les-Mines','St Eloy-les-Mines','63'),('FR','SEN','Sens','Sens','89'),('FR','SEO','Senonches','Senonches','28'),('FR','SEP','Septemes-les-Vallons','Septemes-les-Vallons','13'),('FR','SEQ','Semeac','Semeac','65'),('FR','SER','Serifontaine','Serifontaine','60'),('FR','SES','St Etienne-de-Saint-Geoirs','St Etienne-de-Saint-Geoirs','38'),('FR','SET','Sete','Sete','34'),('FR','SEU','St-Etienne-des-Oullieres','St-Etienne-des-Oullieres','69'),('FR','SEV','Sevres','Sevres','92'),('FR','SEW','Saighin-en-Weppes','Saighin-en-Weppes','59'),('FR','SEX','Semur-en-Auxois','Semur-en-Auxois','21'),('FR','SEY','Selongey','Selongey','21'),('FR','SEZ','Sezanne','Sezanne','51'),('FR','SFC','St Florent-sur-Cher','St Florent-sur-Cher','18'),('FR','SFF','Souffelweyersheim','Souffelweyersheim','67'),('FR','SFG','St Felix-Lauragais','St Felix-Lauragais','31'),('FR','SFL','St Floret','St Floret','63'),('FR','SFN','Ste Florine','Ste Florine','43'),('FR','SFP','Six-Fours-Les-Plages','Six-Fours-Les-Plages','83'),('FR','SFR','Saint-Fargeau-Ponthierry','Saint-Fargeau-Ponthierry','77'),('FR','SFT','St Florentin','St Florentin',''),('FR','SFU','St-Fulgent','St-Fulgent','85'),('FR','SFY','St Pierre-en-Faucigny','St Pierre-en-Faucigny','74'),('FR','SGA','Saint Genest D\'Ambiere','Saint Genest D\'Ambiere','86'),('FR','SGB','St Gobain','St Gobain','02'),('FR','SGC','Sainte-Gauburge-Sainte-Colombe','Sainte-Gauburge-Sainte-Colombe','61'),('FR','SGD','St Germain-au-Mont-d\'Or','St Germain-au-Mont-d\'Or','69'),('FR','SGE','St Georges-des-Groseillers','St Georges-des-Groseillers','61'),('FR','SGF','Saint-Gervais-la-Foret','Saint-Gervais-la-Foret','41'),('FR','SGG','St Germain-de-Lusignan','St Germain-de-Lusignan','17'),('FR','SGH','St Genouph','St Genouph','37'),('FR','SGI','Saint-Geoirs','Saint-Geoirs','38'),('FR','SGJ','St-Genes-de-Lombaud','St-Genes-de-Lombaud','33'),('FR','SGK','St-Germain-Laprade','St-Germain-Laprade','43'),('FR','SGL','St Germain-en-Laye','St Germain-en-Laye','78'),('FR','SGM','Sogny-aux-Moulins','Sogny-aux-Moulins','51'),('FR','SGN','Salsigne','Salsigne','11'),('FR','SGO','St Gratien','St Gratien','95'),('FR','SGP','Saint-Germain-de-Princay','Saint-Germain-de-Princay','85'),('FR','SGQ','St Agathon','St Agathon','22'),('FR','SGR','Saint-Egreve','Saint-Egreve','38'),('FR','SGS','St-Georges-du-Bois','St-Georges-du-Bois','17'),('FR','SGT','Sainte-Gemmes-sur-Loire','Sainte-Gemmes-sur-Loire','49'),('FR','SGU','Sille-le-Guillaume','Sille-le-Guillaume','72'),('FR','SGV','St Jean-de-Gonville','St Jean-de-Gonville','01'),('FR','SGW','Stiring-Wendel','Stiring-Wendel','57'),('FR','SGX','Saint-Georges-des-Gardes','Saint-Georges-des-Gardes','49'),('FR','SGY','Savigny','Savigny','69'),('FR','SGZ','St Goazec','St Goazec','29'),('FR','SHA','Seilhac','Seilhac','19'),('FR','SHB','St Herblain','St Herblain','44'),('FR','SHC','St-Hilaire-les-Places','St-Hilaire-les-Places','87'),('FR','SHE','Saint-Estephe','Saint-Estephe','16'),('FR','SHF','St Hilaire-Saint-Florent','St Hilaire-Saint-Florent','49'),('FR','SHG','Serrieres-en-Chautagne','Serrieres-en-Chautagne','73'),('FR','SHH','Saint-Hilaire-du-Harcouet','Saint-Hilaire-du-Harcouet','50'),('FR','SHI','St Mathurin','St Mathurin','85'),('FR','SHL','St-Hilaire-de-Loulay','St-Hilaire-de-Loulay','85'),('FR','SHM','Sausheim','Sausheim','68'),('FR','SHN','Seilhan','Seilhan','31'),('FR','SHO','Soorts-Hossegor','Soorts-Hossegor','40'),('FR','SHP','Schopperten','Schopperten','67'),('FR','SHR','St Antoine-du-Rocher','St Antoine-du-Rocher','37'),('FR','SHS','St Hilaire-sous-Romilly','St Hilaire-sous-Romilly','10'),('FR','SHT','St Michel-sur-Meurthe','St Michel-sur-Meurthe','88'),('FR','SHX','Sochaux','Sochaux','25'),('FR','SHY','Sachy','Sachy','08'),('FR','SIA','Salviac','Salviac','46'),('FR','SIB','Sibelin','Sibelin','69'),('FR','SIC','St Etienne-de-Chigny','St Etienne-de-Chigny','37'),('FR','SID','St Nicolas-d\'Aliermont','St Nicolas-d\'Aliermont','76'),('FR','SIE','Assier','Assier','46'),('FR','SIF','Saint-Vallier','Saint-Vallier','26'),('FR','SIG','Signes','Signes','83'),('FR','SII','St Pierre-le-Moutier','St Pierre-le-Moutier','58'),('FR','SIJ','St-Just-d\'Avray','St-Just-d\'Avray','69'),('FR','SIL','Savines-le-Lac','Savines-le-Lac','05'),('FR','SIM','Saint-Martin-des-Entrees','Saint-Martin-des-Entrees','14'),('FR','SIN','Saintes','Saintes','17'),('FR','SIO','Saint-Bonnet-de-Mure','Saint-Bonnet-de-Mure','69'),('FR','SIP','Saint-Palais','Saint-Palais','64'),('FR','SIQ','Sillans','Sillans','38'),('FR','SIR','St Remy','St Remy','21'),('FR','SIS','Sapois','Sapois','88'),('FR','SIT','Saint-Vit','Saint-Vit','25'),('FR','SIV','St Pierre-sur-Dives','St Pierre-sur-Dives','14'),('FR','SIX','Seix','Seix','09'),('FR','SJA','St Yorre','St Yorre','03'),('FR','SJC','Saint-Jean-Cap-Ferrat/Nice','Saint-Jean-Cap-Ferrat/Nice','06'),('FR','SJD','St Jean-de-Maurienne','St Jean-de-Maurienne','73'),('FR','SJE','Sainte-Julie','Sainte-Julie','01'),('FR','SJF','St-Jean-du-Falga','St-Jean-du-Falga','09'),('FR','SJG','St Julien-en-Genevois','St Julien-en-Genevois','74'),('FR','SJI','St Jean-d\'Illac','St Jean-d\'Illac','33'),('FR','SJL','St Jacques-de-la-Lande','St Jacques-de-la-Lande','35'),('FR','SJN','Saujon','Saujon','17'),('FR','SJO','Saint-Jeoire-Prieure','Saint-Jeoire-Prieure','73'),('FR','SJP','Saint-Jean-Poutge','Saint-Jean-Poutge','32'),('FR','SJR','St Juery','St Juery',''),('FR','SJT','St Jean-de-la-Porte','St Jean-de-la-Porte','73'),('FR','SJU','St Jean-de-la-Ruelle','St Jean-de-la-Ruelle','45'),('FR','SJV','St Jean-de-Vedas','St Jean-de-Vedas','34'),('FR','SJX','St-Jean-le-Vieux','St-Jean-le-Vieux','01'),('FR','SJY','Saint-Jean-d\'Angely','Saint-Jean-d\'Angely','17'),('FR','SKS','St-Amans-Soult','St-Amans-Soult','81'),('FR','SLA','St Laud/Angers','St Laud/Angers','49'),('FR','SLB','Sierck-les-Bains','Sierck-les-Bains','57'),('FR','SLC','Sarlat-la-Caneda','Sarlat-la-Caneda','24'),('FR','SLD','St Leonard','St Leonard','62'),('FR','SLE','St Aubin-les-Elbeuf','St Aubin-les-Elbeuf','76'),('FR','SLF','St Leu-la-Foret','St Leu-la-Foret','95'),('FR','SLG','Souge-le-Ganelon','Souge-le-Ganelon','72'),('FR','SLH','Soufflenheim','Soufflenheim','67'),('FR','SLI','St Maurice-de-Lignon','St Maurice-de-Lignon','43'),('FR','SLJ','Sauvigny-les-Bois','Sauvigny-les-Bois','58'),('FR','SLL','Salles','Salles','33'),('FR','SLM','St Laurent-de-Mure','St Laurent-de-Mure','69'),('FR','SLN','Sin-le-Noble','Sin-le-Noble','59'),('FR','SLO','St Lo','St Lo','50'),('FR','SLP','St Brevin-les-Pins','St Brevin-les-Pins','44'),('FR','SLQ','Saint-Lin','Saint-Lin','79'),('FR','SLR','St Laurent-sur-Saone','St Laurent-sur-Saone','01'),('FR','SLS','Solesmes','Solesmes','59'),('FR','SLT','Saultain','Saultain','59'),('FR','SLU','St Lupicin','St Lupicin','39'),('FR','SLV','Solesmes','Solesmes','72'),('FR','SLX','Saulxures-sur-Moselotte','Saulxures-sur-Moselotte','88'),('FR','SLY','Saulxures-les-Nancy','Saulxures-les-Nancy','54'),('FR','SLZ','Saulon-la-Chapelle','Saulon-la-Chapelle','21'),('FR','SMA','St Maur','St Maur',''),('FR','SMB','St-Martin-d\'Abbat','St-Martin-d\'Abbat','45'),('FR','SMC','St Martin-de-Crau','St Martin-de-Crau','13'),('FR','SMD','St Meloir-des-Ondes','St Meloir-des-Ondes','35'),('FR','SME','St Menoux','St Menoux','03'),('FR','SMF','Sorel-Moussel','Sorel-Moussel','28'),('FR','SMH','St Michel','St Michel','02'),('FR','SMI','St Emilion','St Emilion','33'),('FR','SMJ','St Mars-la-Jaille','St Mars-la-Jaille','44'),('FR','SMK','Schirmeck','Schirmeck','67'),('FR','SML','St Malo','St Malo','35'),('FR','SMM','St Memmie','St Memmie','51'),('FR','SMN','St Martin-de-Londres','St Martin-de-Londres','34'),('FR','SMO','St Martin-du-Mont','St Martin-du-Mont','01'),('FR','SMP','St Hilaire-au-Temple','St Hilaire-au-Temple','51'),('FR','SMQ','Samer','Samer','62'),('FR','SMR','Ste Marguerite','Ste Marguerite','88'),('FR','SMS','St Lon-les-Mines','St Lon-les-Mines','40'),('FR','SMT','St Mathieu-de-Treviers','St Mathieu-de-Treviers','34'),('FR','SMU','St Marceau','St Marceau','08'),('FR','SMV','St Amans-Valtoret','St Amans-Valtoret','81'),('FR','SMX','St Maxent','St Maxent','80'),('FR','SMY','St Martory','St Martory','31'),('FR','SMZ','Sainte-Marie-aux-Chenes','Sainte-Marie-aux-Chenes','57'),('FR','SNA','Savenay','Savenay','44'),('FR','SNB','Saint-Nabord-sur-Aube','Saint-Nabord-sur-Aube','88'),('FR','SNC','St Cere','St Cere','46'),('FR','SND','St Amand','St Amand','62'),('FR','SNE','Salles-d\'Angles','Salles-d\'Angles','16'),('FR','SNG','St Nazaire','St Nazaire','30'),('FR','SNH','St-Thibault','St-Thibault','10'),('FR','SNI','Sancoins','Sancoins',''),('FR','SNJ','St Severin','St Severin',''),('FR','SNL','St Nicolas-de-la-Taille','St Nicolas-de-la-Taille','76'),('FR','SNM','Flammerans','Flammerans','21'),('FR','SNN','Senones','Senones','88'),('FR','SNO','Senlis','Senlis','60'),('FR','SNP','St Nazaire','St Nazaire','66'),('FR','SNQ','Sance','Sance','71'),('FR','SNR','St Nazaire','St Nazaire','44'),('FR','SNS','Cessenon','Cessenon','34'),('FR','SNT','St Cannat','St Cannat','13'),('FR','SNV','Sandouville','Sandouville','76'),('FR','SNX','St Amant-de-Boixe','St Amant-de-Boixe','16'),('FR','SOA','Soulac-sur-Mer','Soulac-sur-Mer','33'),('FR','SOB','Vinsobres','Vinsobres','26'),('FR','SOD','Soudan','Soudan','44'),('FR','SOE','St Loup-sur-Semouse','St Loup-sur-Semouse','70'),('FR','SOF','Soultz-sous-Forets','Soultz-sous-Forets','67'),('FR','SOG','St-Georges-d\'Esperanche','St-Georges-d\'Esperanche','38'),('FR','SOH','St Omer-en-Chaussee','St Omer-en-Chaussee','60'),('FR','SOI','Soissons','Soissons','02'),('FR','SOL','St Ouen-l\'Aumone','St Ouen-l\'Aumone','95'),('FR','SOM','Somain','Somain','59'),('FR','SON','Sons-et-Roncheres','Sons-et-Roncheres','02'),('FR','SOP','St Loup-Lamaire','St Loup-Lamaire','79'),('FR','SOQ','Souesmes','Souesmes','41'),('FR','SOR','Sorgues','Sorgues','84'),('FR','SOS','St Ouen','St Ouen','80'),('FR','SOT','Sotteville-les-Rouen','Sotteville-les-Rouen','76'),('FR','SOU','Soultz-Haut-Rhin','Soultz-Haut-Rhin','68'),('FR','SOV','Sotteville','Sotteville','50'),('FR','SOX','Soyaux','Soyaux','16'),('FR','SOY','Semoy','Semoy','45'),('FR','SOZ','Solenzara','Solenzara','2A'),('FR','SPA','St Priest','St Priest','07'),('FR','SPB','St-Pal-de-Chalencon','St-Pal-de-Chalencon','43'),('FR','SPC','St Priest','St Priest','23'),('FR','SPD','St Pierre-des-Corps','St Pierre-des-Corps','37'),('FR','SPE','St Pierre-Eglise','St Pierre-Eglise','50'),('FR','SPG','Saint-Pargoire','Saint-Pargoire','34'),('FR','SPH','St Estephe','St Estephe','33'),('FR','SPI','Spincourt','Spincourt','55'),('FR','SPJ','St-Paul-de-Jarrat','St-Paul-de-Jarrat','09'),('FR','SPK','Spycker','Spycker','59'),('FR','SPL','St Parres-les-Vaudes','St Parres-les-Vaudes','10'),('FR','SPM','Saint-Pierre-du-Mont','Saint-Pierre-du-Mont','40'),('FR','SPN','St Pierre-les-Nemours','St Pierre-les-Nemours','77'),('FR','SPO','Saint-Pol-sur-Ternoise','Saint-Pol-sur-Ternoise','62'),('FR','SPP','St-Pierre-Montlimart','St-Pierre-Montlimart','49'),('FR','SPQ','Saint-Pol-sur-Mer','Saint-Pol-sur-Mer','59'),('FR','SPR','St Pierre-d\'Entremont','St Pierre-d\'Entremont',''),('FR','SPS','Seyssinet-Pariset','Seyssinet-Pariset','38'),('FR','SPT','St Prouant','St Prouant','85'),('FR','SPU','St-Sulpice-de-Mareuil','St-Sulpice-de-Mareuil','24'),('FR','SPV','St Paul','St Paul','87'),('FR','SPW','St-Pere-en-Retz','St-Pere-en-Retz','44'),('FR','SPX','Saint-Paul-les-Dax','Saint-Paul-les-Dax','40'),('FR','SPY','Saint-Pierre-de-Chandieu','Saint-Pierre-de-Chandieu','69'),('FR','SPZ','St Paulien','St Paulien','43'),('FR','SQB','St-Quentin-de-Baron','St-Quentin-de-Baron','33'),('FR','SQC','St-Quentin-au-Bosc','St-Quentin-au-Bosc','76'),('FR','SQF','St Quentin-Fallavier','St Quentin-Fallavier','38'),('FR','SQH','St-Quentin-sur-le-Homme','St-Quentin-sur-le-Homme','50'),('FR','SQM','St Ouen-Marchefroy','St Ouen-Marchefroy','28'),('FR','SQN','Sequedin','Sequedin','59'),('FR','SQO','St Cirq-Lapopie','St Cirq-Lapopie','46'),('FR','SQR','St-Pierre-Quiberon','St-Pierre-Quiberon','56'),('FR','SQS','St-Christ-Briost','St-Christ-Briost','80'),('FR','SQT','St-Astier','St-Astier','24'),('FR','SQU','St Andre-de-Cubzac','St Andre-de-Cubzac','33'),('FR','SQV','Sandrancourt','Sandrancourt','78'),('FR','SQX','Serqueux','Serqueux','76'),('FR','SQY','Saint-Quentin-en-Yvelines','Saint-Quentin-en-Yvelines','78'),('FR','SRA','St Rambert-d\'Albon','St Rambert-d\'Albon','26'),('FR','SRB','Sorbiers','Sorbiers','42'),('FR','SRC','Sarcelles','Sarcelles','95'),('FR','SRE','Saint-Renan','Saint-Renan','29'),('FR','SRF','Sarraltroff','Sarraltroff','57'),('FR','SRG','Soings-en-Sologne','Soings-en-Sologne','41'),('FR','SRH','Sainte-Marie-sur-Ouche','Sainte-Marie-sur-Ouche','21'),('FR','SRI','Serain','Serain','02'),('FR','SRJ','St-Andre','St-Andre','73'),('FR','SRL','Saint-Raphael','Saint-Raphael','13'),('FR','SRM','St Romain','St Romain','21'),('FR','SRN','Saran','Saran','45'),('FR','SRO','Sarrola-Carcopino','Sarrola-Carcopino','2A'),('FR','SRP','Senarpont','Senarpont','80'),('FR','SRQ','Serquigny','Serquigny','27'),('FR','SRR','Sancerre','Sancerre','18'),('FR','SRS','Sarrians','Sarrians','84'),('FR','SRT','St-Christoly-de-Blaye','St-Christoly-de-Blaye','33'),('FR','SRU','Sours','Sours','28'),('FR','SRV','Servon','Servon','77'),('FR','SRW','St-Romain-du-Puy','St-Romain-du-Puy','42'),('FR','SRX','Saint-Maurice-l\'Exil','Saint-Maurice-l\'Exil','38'),('FR','SRY','St-Remy-les-Chevreuse','St-Remy-les-Chevreuse','78'),('FR','SRZ','Saint-Remy-en-Bouzemont-Saint-Genest-et-Isson','Saint-Remy-en-Bouzemont-Saint-Genest-et-Isson','51'),('FR','SSA','Scey-sur-Saone-et-Saint-Albin','Scey-sur-Saone-et-Saint-Albin','70'),('FR','SSB','St Simeon-de-Bressieux','St Simeon-de-Bressieux','38'),('FR','SSC','St Saturnin-de-Lucian','St Saturnin-de-Lucian','34'),('FR','SSD','Serrieres-de-Briord','Serrieres-de-Briord','01'),('FR','SSE','St Berthevin','St Berthevin','53'),('FR','SSF','St Fons','St Fons','69'),('FR','SSG','Sarreinsming','Sarreinsming','57'),('FR','SSH','Selles-sur-Cher','Selles-sur-Cher','41'),('FR','SSI','Serrieres','Serrieres','07'),('FR','SSJ','St-Sauvant','St-Sauvant','17'),('FR','SSL','St Seurin-sur-l\'Isle','St Seurin-sur-l\'Isle','33'),('FR','SSM','Serrieres','Serrieres','54'),('FR','SSN','Saintry-sur-Seine','Saintry-sur-Seine','91'),('FR','SSO','Serrieres/Saone-et-Loire','Serrieres/Saone-et-Loire','71'),('FR','SSP','St Christophe-Vallon','St Christophe-Vallon','12'),('FR','SSQ','Sainte-Savine','Sainte-Savine','10'),('FR','SSR','Sable-sur-Sarthe','Sable-sur-Sarthe','72'),('FR','SSS','Sassenage','Sassenage','38'),('FR','SST','St Saturnin-les-Avignon','St Saturnin-les-Avignon','84'),('FR','SSU','St Symphorien-sur-Coise','St Symphorien-sur-Coise','69'),('FR','SSV','St-Sauveur','St-Sauveur','31'),('FR','SSW','Sauviat-sur-Vige','Sauviat-sur-Vige','87'),('FR','SSX','St Savin-de-Blay','St Savin-de-Blay','33'),('FR','SSY','Cessy','Cessy','01'),('FR','SSZ','Sainte-Suzanne','Sainte-Suzanne','25'),('FR','STA','St Avold','St Avold','57'),('FR','STB','St Bartelemy','St Bartelemy',''),('FR','STC','St Claude','St Claude','39'),('FR','STD','St Denis/Paris','St Denis/Paris','93'),('FR','STE','St Andre','St Andre','59'),('FR','STF','St-Leonard','St-Leonard','51'),('FR','STG','St Gervais','St Gervais','33'),('FR','STH','Saint Thonan','Saint Thonan','29'),('FR','STI','Saint-Longis','Saint-Longis','72'),('FR','STJ','St Jory','St Jory','31'),('FR','STK','St-Jean-du-Cardonnay','St-Jean-du-Cardonnay','76'),('FR','STL','St Louis','St Louis','68'),('FR','STM','St-Marcel','St-Marcel','71'),('FR','STN','St Amarin','St Amarin','68'),('FR','STO','St Omer','St Omer','62'),('FR','STP','St Tropez','St Tropez','83'),('FR','STQ','St Quentin','St Quentin','02'),('FR','STR','St Amour','St Amour','39'),('FR','STS','St-Ferme','St-Ferme','33'),('FR','STT','St Laurent-sur-Sevre','St Laurent-sur-Sevre','85'),('FR','STU','Saint-Auban','Saint-Auban','06'),('FR','STV','Steenvoorde','Steenvoorde','59'),('FR','STX','St Amand-les-Eaux','St Amand-les-Eaux','59'),('FR','STY','St Yan','St Yan','71'),('FR','STZ','Stenay','Stenay','55'),('FR','SUA','Souillac','Souillac','46'),('FR','SUB','Saint-Aubin','Saint-Aubin','39'),('FR','SUC','Sucy-en-Brie','Sucy-en-Brie','94'),('FR','SUD','Salleles-d\'Aude','Salleles-d\'Aude','11'),('FR','SUE','Sainte-Tulle','Sainte-Tulle','04'),('FR','SUF','Sundhoffen','Sundhoffen','68'),('FR','SUG','Surgeres','Surgeres','17'),('FR','SUH','Struth','Struth','67'),('FR','SUI','Suippes','Suippes','51'),('FR','SUL','Sully-sur-Loire','Sully-sur-Loire','45'),('FR','SUM','Sallaumines','Sallaumines','62'),('FR','SUN','Suresnes','Suresnes','92'),('FR','SUO','Semoutiers-Monsaon','Semoutiers-Monsaon','52'),('FR','SUP','Seurre','Seurre','71'),('FR','SUQ','Soumont-St-Quentin','Soumont-St-Quentin','14'),('FR','SUR','Survilliers','Survilliers','95'),('FR','SUS','St Laurent-de-Ceris','St Laurent-de-Ceris','16'),('FR','SUT','St Laurent','St Laurent','31'),('FR','SUU','St Sulpice-Lauriere','St Sulpice-Lauriere','87'),('FR','SUV','Suevres','Suevres','41'),('FR','SUX','Saleux','Saleux','80'),('FR','SUY','Sury-le-Comtal','Sury-le-Comtal','42'),('FR','SUZ','Suze','Suze','26'),('FR','SVA','Servas','Servas','01'),('FR','SVB','Saint-Vulbas','Saint-Vulbas','01'),('FR','SVC','St Victoret','St Victoret','13'),('FR','SVD','St Vigor-d\'Ymonville','St Vigor-d\'Ymonville','76'),('FR','SVE','Sancheville','Sancheville','28'),('FR','SVG','Savigny-le-Temple','Savigny-le-Temple','77'),('FR','SVI','Saillat-sur-Vienne','Saillat-sur-Vienne','87'),('FR','SVL','Sartrouville','Sartrouville','78'),('FR','SVN','Servian','Servian','34'),('FR','SVO','Savigny-en-veron','Savigny-en-veron','37'),('FR','SVP','St Vincent-de-Paul','St Vincent-de-Paul','40'),('FR','SVR','Saint-Victor','Saint-Victor','07'),('FR','SVS','St Valery-sur-Somme','St Valery-sur-Somme','80'),('FR','SVT','Sauveterre','Sauveterre',''),('FR','SVU','Savigny-sur-Seille','Savigny-sur-Seille','71'),('FR','SVV','St Gervais-d\'Auvergne','St Gervais-d\'Auvergne','63'),('FR','SVX','St Martin-Valmeroux','St Martin-Valmeroux','15'),('FR','SVY','Sevrey','Sevrey','71'),('FR','SVZ','Savasse','Savasse','26'),('FR','SWD','St Wandrille-Rancon','St Wandrille-Rancon','76'),('FR','SWE','Sarrewerden','Sarrewerden','67'),('FR','SWK','Steenwerck','Steenwerck','59'),('FR','SWM','Schwindratzheim','Schwindratzheim','67'),('FR','SWY','Sonnay','Sonnay','38'),('FR','SXB','Strasbourg','Strasbourg','67'),('FR','SXC','St Yrieix-sur-Charente','St Yrieix-sur-Charente','16'),('FR','SXD','Sophia Antipolis','Sophia Antipolis','06'),('FR','SXE','Severac-le-Chateau','Severac-le-Chateau','12'),('FR','SXH','Saulx','Saulx','70'),('FR','SXM','Ste Marie-aux-Mines','Ste Marie-aux-Mines','68'),('FR','SXN','St-Meme-les-Carrieres','St-Meme-les-Carrieres','16'),('FR','SXO','St Maixent-l\'Ecole','St Maixent-l\'Ecole','79'),('FR','SXS','Salbris','Salbris','41'),('FR','SXT','St Clet','St Clet','22'),('FR','SXX','St-Bonnet-les-Oules','St-Bonnet-les-Oules','42'),('FR','SXZ','St-Jean-de-Muzols','St-Jean-de-Muzols','07'),('FR','SYA','Sousceyrac','Sousceyrac','46'),('FR','SYB','Savigny-sur-Braye','Savigny-sur-Braye','41'),('FR','SYC','Saint-Cyr-l\'Ecole','Saint-Cyr-l\'Ecole','78'),('FR','SYD','Seynod','Seynod','74'),('FR','SYE','St Hippolyte','St Hippolyte','37'),('FR','SYG','St-Gaudens','St-Gaudens','31'),('FR','SYH','Seychalles','Seychalles','63'),('FR','SYJ','St Sylvain-d\'Anjou','St Sylvain-d\'Anjou','49'),('FR','SYL','Savigny-Levescault','Savigny-Levescault','86'),('FR','SYM','Soisy-sous-Montmorency','Soisy-sous-Montmorency','95'),('FR','SYN','Seyne','Seyne',''),('FR','SYO','Sennecey-les-Dijon','Sennecey-les-Dijon','21'),('FR','SYP','St-Yrieix-la-Perche','St-Yrieix-la-Perche','87'),('FR','SYQ','Sauvoy','Sauvoy','55'),('FR','SYR','Savigny-en-Revermont','Savigny-en-Revermont','71'),('FR','SYS','Seyssins','Seyssins','38'),('FR','SYT','St-Chely-d\'Apcher','St-Chely-d\'Apcher','48'),('FR','SYV','Santeny','Santeny','94'),('FR','SZA','Segonzac','Segonzac','16'),('FR','SZL','Sailly-lez-Lannoy','Sailly-lez-Lannoy','59'),('FR','SZM','Soultzmatt','Soultzmatt','68'),('FR','SZN','Sail-sous-Couzan','Sail-sous-Couzan','42'),('FR','SZR','St Dizier','St Dizier','52'),('FR','SZS','La Suze-sur-Sarthe','La Suze-sur-Sarthe','72'),('FR','SZT','Sauzet','Sauzet','26'),('FR','SZU','Saincaize-Meauce','Saincaize-Meauce','58'),('FR','SZV','Sauze-Vaussais','Sauze-Vaussais','79'),('FR','SZY','Souzy','Souzy','69'),('FR','TAA','Tavera','Tavera','2A'),('FR','TAB','Tarbes','Tarbes','65'),('FR','TAC','Teuillac','Teuillac','33'),('FR','TAE','Betaille','Betaille','46'),('FR','TAG','St Agne','St Agne','24'),('FR','TAH','Tour d\'Aigues','Tour d\'Aigues','68'),('FR','TAK','Thenac','Thenac','17'),('FR','TAL','Talloires','Talloires','74'),('FR','TAM','Montamise','Montamise','86'),('FR','TAP','Staple','Staple','59'),('FR','TAR','Tarnos','Tarnos','40'),('FR','TAS','Trannes','Trannes','10'),('FR','TAU','Taule','Taule','29'),('FR','TAV','Tavel','Tavel','30'),('FR','TAY','Santenay','Santenay','21'),('FR','TBA','Lutterbach','Lutterbach','68'),('FR','TBL','Trambly','Trambly','71'),('FR','TBO','St Boil','St Boil','71'),('FR','TBR','Trets','Trets','14'),('FR','TBY','Tincourt-Boucly','Tincourt-Boucly','80'),('FR','TCA','St Cesaire','St Cesaire','30'),('FR','TCH','Thore-la-Rochette','Thore-la-Rochette','41'),('FR','TCI','St Cernin','St Cernin','46'),('FR','TCL','St Clair','St Clair','07'),('FR','TCN','Tuchan','Tuchan','11'),('FR','TCO','St-Trivier-de-Courtes','St-Trivier-de-Courtes','01'),('FR','TCS','Bretoncelles','Bretoncelles','61'),('FR','TCT','Tricot','Tricot','60'),('FR','TCU','Trie-Chateau','Trie-Chateau','60'),('FR','TCY','Saint-Cyr-de-Favieres','Saint-Cyr-de-Favieres','42'),('FR','TDA','St-Tugdual','St-Tugdual','56'),('FR','TDB','La Teste-de-Buch','La Teste-de-Buch','33'),('FR','TDC','Thedirac','Thedirac','46'),('FR','TDD','St Didier ','St Didier ','84'),('FR','TDE','Tallende','Tallende','63'),('FR','TDI','Theding','Theding','57'),('FR','TDS','Taillades','Taillades','84'),('FR','TDU','Tassin-la-Demi-Lune','Tassin-la-Demi-Lune','69'),('FR','TEA','Castella','Castella','47'),('FR','TEB','Tournan-en-Brie','Tournan-en-Brie','77'),('FR','TEE','Treves','Treves','30'),('FR','TEF','Tremblay-les-Gonesse','Tremblay-les-Gonesse','93'),('FR','TEG','Donzac','Donzac','82'),('FR','TEM','St-Erme-Outre-et-Ramecourt','St-Erme-Outre-et-Ramecourt','02'),('FR','TEP','Chantepie','Chantepie','35'),('FR','TER','Tergnier','Tergnier','02'),('FR','TES','Tresse','Tresse','35'),('FR','TET','Saint-Etienne-les-Remiremont','Saint-Etienne-les-Remiremont','88'),('FR','TEU','Sainte-Eulalie','Sainte-Eulalie','33'),('FR','TEV','Treves','Treves','69'),('FR','TFA','Ternay','Ternay','41'),('FR','TFD','Fontguenand','Fontguenand','36'),('FR','TFG','Tiffauges','Tiffauges','85'),('FR','TFL','Tournefeuille','Tournefeuille','31'),('FR','TFO','Saint-Flour','Saint-Flour','15'),('FR','TFR','Tournefort','Tournefort','06'),('FR','TFS','Troisfontaines','Troisfontaines','57'),('FR','TFT','Treffort-Cuisiat','Treffort-Cuisiat','01'),('FR','TFU','Tour-de-Faure','Tour-de-Faure','46'),('FR','TGA','St Agnan','St Agnan','89'),('FR','TGB','Gaillac','Gaillac','81'),('FR','TGC','Telgruc-sur-Mer','Telgruc-sur-Mer','29'),('FR','TGE','St Germe','St Germe','32'),('FR','TGF','Tignes','Tignes','73'),('FR','TGJ','Tignieu-Jameyzieu','Tignieu-Jameyzieu','38'),('FR','TGL','Bertangles','Bertangles','80'),('FR','TGM','Ste Gemme','Ste Gemme','81'),('FR','TGN','St Agnant','St Agnant','17'),('FR','TGO','Tagolsheim','Tagolsheim','68'),('FR','TGQ','Targon','Targon','33'),('FR','TGR','St Leger','St Leger','77'),('FR','TGS','Trigueres','Trigueres','45'),('FR','TGT','Tregastel','Tregastel','22'),('FR','TGU','St Genou','St Genou','36'),('FR','THA','Thann','Thann','68'),('FR','THB','Chateau-Thebaud','Chateau-Thebaud','44'),('FR','THC','Thou','Thou','45'),('FR','THD','Therdonne','Therdonne','60'),('FR','THE','Thourotte','Thourotte','60'),('FR','THG','Thiron Gardais','Thiron Gardais','28'),('FR','THJ','Thiais','Thiais','94'),('FR','THL','Theillay','Theillay','41'),('FR','THN','Thaon','Thaon','14'),('FR','THO','Thonon-les-Bains','Thonon-les-Bains','74'),('FR','THP','Trept','Trept','38'),('FR','THR','Thuir','Thuir','66'),('FR','THS','Thouars','Thouars','79'),('FR','THT','Thiat','Thiat','87'),('FR','THU','Thouarce','Thouarce','49'),('FR','THX','Theix','Theix','56'),('FR','THY','St-Thibery','St-Thibery','34'),('FR','THZ','Thezan-les-Beziers','Thezan-les-Beziers','34'),('FR','TIC','Tierce','Tierce','49'),('FR','TIE','Laventie','Laventie','62'),('FR','TIG','Tigery','Tigery','91'),('FR','TIL','Totes','Totes','76'),('FR','TIN','Pantin','Pantin','93'),('FR','TIO','Troncais','Troncais','03'),('FR','TIY','Tigy','Tigy','45'),('FR','TJA','St Jal','St Jal','19'),('FR','TJE','Trouville-sur-Mer','Trouville-sur-Mer','14'),('FR','TJR','St Julien-l\'Ars','St Julien-l\'Ars','86'),('FR','TJU','St Julien','St Julien','88'),('FR','TKM','Turckheim','Turckheim','68'),('FR','TLA','Tillieres-sur-Avre','Tillieres-sur-Avre','27'),('FR','TLB','Thoisy la Berchere','Thoisy la Berchere',''),('FR','TLE','Tulle','Tulle','19'),('FR','TLG','Toulouges','Toulouges','66'),('FR','TLI','Tourville-les-Ifs','Tourville-les-Ifs','76'),('FR','TLL','Tille','Tille','60'),('FR','TLM','Tilloy-les-Mofflaines','Tilloy-les-Mofflaines','62'),('FR','TLN','Toulon','Toulon','83'),('FR','TLO','Castanet-Tolosan','Castanet-Tolosan','31'),('FR','TLR','Tillieres','Tillieres','49'),('FR','TLS','Toulouse','Toulouse','31'),('FR','TLT','Tulette','Tulette','26'),('FR','TLU','Le Tallud','Le Tallud','79'),('FR','TLV','Thonon-les-Vosges','Thonon-les-Vosges',''),('FR','TLY','Thilay','Thilay','08'),('FR','TLZ','Trelaze','Trelaze','49'),('FR','TMA','St Mariens','St Mariens','33'),('FR','TMB','St Martin-Boulogne','St Martin-Boulogne','62'),('FR','TMI','Treminis','Treminis','38'),('FR','TML','St Mihiel','St Mihiel','55'),('FR','TMN','Thun-St-Martin','Thun-St-Martin','59'),('FR','TMO','St Mont','St Mont','32'),('FR','TMQ','Sainte-Maure-de-Touraine','Sainte-Maure-de-Touraine','37'),('FR','TMR','Tremeur','Tremeur','22'),('FR','TMS','Tremons','Tremons','47'),('FR','TMT','Trementines','Trementines','49'),('FR','TMX','Terminiers','Terminiers','28'),('FR','TNC','Talence','Talence','33'),('FR','TND','Ternand','Ternand','69'),('FR','TNE','Tonneins','Tonneins','47'),('FR','TNF','Toussus-le-Noble','Toussus-le-Noble','78'),('FR','TNH','Tain-l\'Hermitage','Tain-l\'Hermitage','26'),('FR','TNL','Chantenay-Villedieu','Chantenay-Villedieu','72'),('FR','TNR','Tonnerre','Tonnerre','89'),('FR','TNS','Tessonniere','Tessonniere','79'),('FR','TNV','Lantenne-Vertiere','Lantenne-Vertiere','25'),('FR','TNX','St Martin-D\'Auxy','St Martin-D\'Auxy','71'),('FR','TNY','Tenay','Tenay','01'),('FR','TOA','Toulon-sur-Allier','Toulon-sur-Allier','03'),('FR','TOC','Torcieu','Torcieu','01'),('FR','TOE','Toeufles','Toeufles','80'),('FR','TOF','Toufflers','Toufflers','59'),('FR','TOG','Tourcoing','Tourcoing','59'),('FR','TOM','Tournemire','Tournemire','12'),('FR','TON','Tonnay-Charente','Tonnay-Charente','17'),('FR','TOR','Torcy','Torcy','77'),('FR','TOS','Thoraise','Thoraise','25'),('FR','TOT','St-Nicolas-de-Bourgueil','St-Nicolas-de-Bourgueil','37'),('FR','TOU','Toul','Toul','54'),('FR','TOV','Tourlaville','Tourlaville','50'),('FR','TOY','Tournay','Tournay','65'),('FR','TPA','St Sulpice','St Sulpice','81'),('FR','TPC','Torcy','Torcy','62'),('FR','TPE','Torpes','Torpes','25'),('FR','TPI','St Patrice','St Patrice','37'),('FR','TPL','Le Temple-sur-Lot','Le Temple-sur-Lot','47'),('FR','TPM','Templemars','Templemars','59'),('FR','TPN','St Pons-de-Thomieres','St Pons-de-Thomieres','34'),('FR','TPO','Trilport','Trilport','77'),('FR','TPT','Trepot','Trepot','25'),('FR','TPV','St-Prive','St-Prive','71'),('FR','TQS','Tresques','Tresques','30'),('FR','TQX','Tinqueux','Tinqueux','51'),('FR','TRA','Trappes','Trappes','78'),('FR','TRB','La Tremblade','La Tremblade',''),('FR','TRC','Torce','Torce','35'),('FR','TRE','Treguier','Treguier','22'),('FR','TRG','Tregueux','Tregueux','22'),('FR','TRI','Trignac','Trignac','44'),('FR','TRL','Trelissac','Trelissac','24'),('FR','TRM','Tremblay','Tremblay','35'),('FR','TRN','Tournus','Tournus','71'),('FR','TRO','Tournon-sur-Rhone','Tournon-sur-Rhone','07'),('FR','TRR','Tarare','Tarare','69'),('FR','TRS','Thiers','Thiers','63'),('FR','TRT','Tremolat','Tremolat','24'),('FR','TRU','Thouare-sur-Loire','Thouare-sur-Loire','44'),('FR','TRV','Tourves','Tourves','83'),('FR','TRW','Torvilliers','Torvilliers','10'),('FR','TRX','Trevoux','Trevoux','01'),('FR','TRY','Thoiry','Thoiry','74'),('FR','TSA','Tarascon-sur-Ariege','Tarascon-sur-Ariege','09'),('FR','TSB','Trie sur Baise','Trie sur Baise',''),('FR','TSC','Tarascon','Tarascon','13'),('FR','TSE','Thesee','Thesee','41'),('FR','TSG','Ste Segree','Ste Segree','80'),('FR','TSI','Troisvilles','Troisvilles','59'),('FR','TSL','Tourette-sur-Loup','Tourette-sur-Loup',''),('FR','TSM','Tours-sur-Marne','Tours-sur-Marne','51'),('FR','TSN','St Savin','St Savin','86'),('FR','TSS','Tressin','Tressin','59'),('FR','TSU','St Usuge','St Usuge','71'),('FR','TSV','Torigni-sur-Vire','Torigni-sur-Vire','50'),('FR','TTC','Tinteniac','Tinteniac','35'),('FR','TTG','Teteghem','Teteghem','59'),('FR','TTH','Teterchen','Teterchen','57'),('FR','TTN','Torteron','Torteron','18'),('FR','TTS','Tartas','Tartas','40'),('FR','TTV','Thiers-sur-Theve','Thiers-sur-Theve','60'),('FR','TTY','Toutry','Toutry','21'),('FR','TUA','St Usage','St Usage','21'),('FR','TUC','Touffreville','Touffreville','14'),('FR','TUF','Tours','Tours','37'),('FR','TUI','Les Thuiles','Les Thuiles','04'),('FR','TUL','Tullins','Tullins','38'),('FR','TUM','Trelou-sur-Marne','Trelou-sur-Marne','02'),('FR','TUN','Saint-Fortunat-sur-Eyrieux','Saint-Fortunat-sur-Eyrieux','07'),('FR','TUO','La Tour-sur-Orb','La Tour-sur-Orb','34'),('FR','TUR','Turenne','Turenne','19'),('FR','TUS','La Toussuire','La Toussuire','73'),('FR','TUX','Thieux','Thieux','77'),('FR','TUY','Sauveterre-de-Guyenne','Sauveterre-de-Guyenne','33'),('FR','TVB','Tronville-en-Barrois','Tronville-en-Barrois','55'),('FR','TVD','Terrasson-la-Villedieu','Terrasson-la-Villedieu','24'),('FR','TVE','Auterrive','Auterrive','64'),('FR','TVI','Tantonville','Tantonville','54'),('FR','TVL','Thionville','Thionville','57'),('FR','TVM','Thiaville-sur-Meurthe','Thiaville-sur-Meurthe','54'),('FR','TVO','Thaon-les-Vosges','Thaon-les-Vosges','88'),('FR','TVR','Tourouvre','Tourouvre','61'),('FR','TVS','Thiviers','Thiviers','24'),('FR','TVX','Tavaux','Tavaux','39'),('FR','TVY','Taverny','Taverny','95'),('FR','TYA','St-Thomas-en-Royans','St-Thomas-en-Royans','26'),('FR','TYG','Thezy-Glimont','Thezy-Glimont','80'),('FR','TYM','Le Tremblay-sur-Mauldre','Le Tremblay-sur-Mauldre','78'),('FR','TYO','Tracy-le-Mont','Tracy-le-Mont','61'),('FR','TYR','Saint-Cyr-en-Val','Saint-Cyr-en-Val','45'),('FR','TYS','Torcy','Torcy','71'),('FR','TZY','Thizy','Thizy','69'),('FR','UAC','Maussac','Maussac','19'),('FR','UAG','Bussang','Bussang','88'),('FR','UAL','Beauval','Beauval','80'),('FR','UAN','Lourmarin','Lourmarin','84'),('FR','UAY','Pussay','Pussay','91'),('FR','UBA','St-Auban','St-Auban','04'),('FR','UBE','Auboue','Auboue','54'),('FR','UBG','Aubigny','Aubigny','80'),('FR','UBH','Uberach','Uberach','67'),('FR','UBI','Aubin','Aubin','12'),('FR','UBL','Luble','Luble','37'),('FR','UBN','St-Aubin','St-Aubin','21'),('FR','UBS','Saubusse','Saubusse','40'),('FR','UCG','Lucinges','Lucinges','74'),('FR','UCH','Uchaud','Uchaud','30'),('FR','UCK','Uckange','Uckange','57'),('FR','UCT','Laucourt','Laucourt','80'),('FR','UCU','St-Laurent-de-Chamousset','St-Laurent-de-Chamousset','69'),('FR','UCX','Uchaux','Uchaux','84'),('FR','UCY','Courcy','Courcy','51'),('FR','UCZ','Busseau-sur-Creuse','Busseau-sur-Creuse','23'),('FR','UDE','St Caradec','St Caradec','22'),('FR','UEC','Burey-la-Cote','Burey-la-Cote','55'),('FR','UEL','Bueil','Bueil','27'),('FR','UEN','St-Leu-d\'Esserent','St-Leu-d\'Esserent','60'),('FR','UER','St-Ouen-la-Rouerie','St-Ouen-la-Rouerie','37'),('FR','UES','Soues','Soues','80'),('FR','UEY','Uxegney','Uxegney','88'),('FR','UGA','Le Fauga','Le Fauga','31'),('FR','UGI','Ugine','Ugine','73'),('FR','UGL','Bourgueil','Bourgueil','37'),('FR','UGN','La Meaugon','La Meaugon','22'),('FR','UGO','Bussy-Saint-Georges','Bussy-Saint-Georges','77'),('FR','UGR','Fougerolles','Fougerolles','70'),('FR','UGS','Ungersheim','Ungersheim','68'),('FR','UGU','Le Bugue','Le Bugue','24'),('FR','UGY','Busigny','Busigny','59'),('FR','UIL','Vouille','Vouille','86'),('FR','UIP','Quimper','Quimper','29'),('FR','UIS','Puiseux-le-Hauberger','Puiseux-le-Hauberger','60'),('FR','ULA','Saint-Martin-au-Laert','Saint-Martin-au-Laert','62'),('FR','ULC','Luc','Luc','12'),('FR','ULL','Lully','Lully','74'),('FR','ULN','Mons-en-Barouel','Mons-en-Barouel','59'),('FR','ULO','Coullons','Coullons','45'),('FR','ULS','Vourles','Vourles','70'),('FR','ULT','Sault-les-Rethel','Sault-les-Rethel','08'),('FR','ULX','Baule','Baule','45'),('FR','UMA','Urmatt','Urmatt','67'),('FR','UMS','Coulombs','Coulombs','28'),('FR','UNE','Champagney','Champagney','25'),('FR','UNL','Cauneille','Cauneille','40'),('FR','UNO','L\'Union','L\'Union','31'),('FR','UNR','St Lunaire','St Lunaire','35'),('FR','UNS','Guines','Guines','62'),('FR','UNY','Brunoy','Brunoy','91'),('FR','UON','Cuon','Cuon','49'),('FR','UOR','Le Mesnil-sur-Oger','Le Mesnil-sur-Oger','51'),('FR','UOS','Maurois','Maurois','59'),('FR','UPA','Ampuis','Ampuis','69'),('FR','UPI','St Sulpice','St Sulpice','60'),('FR','UPO','Souprosse','Souprosse','40'),('FR','UPP','Saint-Soupplets','Saint-Soupplets','77'),('FR','UPS','Loupes','Loupes','33'),('FR','URA','Mauriac','Mauriac','15'),('FR','URB','Courbillac','Courbillac','16'),('FR','URC','St Pourcain-sur-Sioule','St Pourcain-sur-Sioule','03'),('FR','URG','Courgains','Courgains','72'),('FR','URH','Saulce-sur-Rhone','Saulce-sur-Rhone','26'),('FR','URI','Urimenil','Urimenil','88'),('FR','URL','Chateau-Renault','Chateau-Renault','37'),('FR','URN','Mauron','Mauron','56'),('FR','URO','Rouen','Rouen','76'),('FR','URR','Bourre','Bourre','41'),('FR','URS','Lurcy-Levis','Lurcy-Levis','03'),('FR','URV','Urville','Urville','10'),('FR','URX','Rue','Rue','80'),('FR','URY','Ury','Ury','77'),('FR','URZ','Ur','Ur','66'),('FR','USC','Ussac','Ussac','19'),('FR','USG','Ully-Saint-Georges','Ully-Saint-Georges','60'),('FR','USI','La Bussiere','La Bussiere','45'),('FR','USN','Ruesnes','Ruesnes','59'),('FR','USR','Buire-sur-l\'Ancre','Buire-sur-l\'Ancre','80'),('FR','USS','Ussel','Ussel',''),('FR','UST','Saint-Augustin-des-Bois','Saint-Augustin-des-Bois','49'),('FR','USZ','Ustaritz','Ustaritz','64'),('FR','UTE','Leucate','Leucate','11'),('FR','UTR','Chaintre','Chaintre','71'),('FR','UVA','Auvillar','Auvillar','82'),('FR','UVG','Beuvraignes','Beuvraignes','80'),('FR','UVO','Beauvoir-de-Marc','Beauvoir-de-Marc','38'),('FR','UVR','Louvres','Louvres','95'),('FR','UVS','Beauvoisin','Beauvoisin','30'),('FR','UXB','St-Herblon','St-Herblon','44'),('FR','UYM','Ugny-sur-Meuse','Ugny-sur-Meuse','55'),('FR','UYR','Banyuls-sur-Mer','Banyuls-sur-Mer','66'),('FR','UZA','Muzillac','Muzillac','56'),('FR','UZC','Uzerche','Uzerche','19'),('FR','UZE','Uzes','Uzes','30'),('FR','UZL','Uzel','Uzel','22'),('FR','UZN','Muizon','Muizon','51'),('FR','UZY','Luzy','Luzy','58'),('FR','VAA','Valence','Valence','82'),('FR','VAB','Vrigne-aux-Bois','Vrigne-aux-Bois','08'),('FR','VAC','Valence','Valence','16'),('FR','VAD','La Ville-aux-Dames','La Ville-aux-Dames','37'),('FR','VAE','Valliquerville','Valliquerville','76'),('FR','VAF','Valence','Valence','26'),('FR','VAG','Varennes-le-Grand','Varennes-le-Grand','71'),('FR','VAH','Valdahon','Valdahon','25'),('FR','VAI','Villers-le-Sec','Villers-le-Sec','02'),('FR','VAL','Valenciennes','Valenciennes','59'),('FR','VAN','Vandoeuvre-les-Nancy','Vandoeuvre-les-Nancy','54'),('FR','VAR','Varangeville','Varangeville','54'),('FR','VAS','Vaas','Vaas','72'),('FR','VAT','Vatimont','Vatimont','57'),('FR','VAU','Vallauris','Vallauris','06'),('FR','VAV','Vaivre','Vaivre','25'),('FR','VAX','Le Val','Le Val','83'),('FR','VAY','Vagney','Vagney','88'),('FR','VAZ','Val-d\'Isere','Val-d\'Isere','73'),('FR','VBA','Vals-les-Bains','Vals-les-Bains','07'),('FR','VBE','Valbonne','Valbonne','06'),('FR','VBG','Villeneuve-de-Berg','Villeneuve-de-Berg','07'),('FR','VBI','Verberie','Verberie','60'),('FR','VBL','Villedieu-la-Blouere','Villedieu-la-Blouere','49'),('FR','VBN','Villeurbanne','Villeurbanne','69'),('FR','VBR','Voisins-le-Bretonneux','Voisins-le-Bretonneux','78'),('FR','VBU','Villebarou','Villebarou','41'),('FR','VBX','Villers-Bretonneux','Villers-Bretonneux','80'),('FR','VCA','Velle-le-Chatel','Velle-le-Chatel','70'),('FR','VCB','Vic-en-Bigorre','Vic-en-Bigorre','65'),('FR','VCC','Vic-le-Comte','Vic-le-Comte','63'),('FR','VCG','St Magne-de-Castillon','St Magne-de-Castillon','89'),('FR','VCH','Villiers-Charlemagne','Villiers-Charlemagne',''),('FR','VCL','Villers-Ecalles','Villers-Ecalles','76'),('FR','VCM','St Sauveur-le-Vicomte','St Sauveur-le-Vicomte','50'),('FR','VCN','Vincennes','Vincennes','94'),('FR','VCO','Vieux-Conde','Vieux-Conde','59'),('FR','VCR','Villecresnes','Villecresnes','94'),('FR','VCT','Villers-Cotterets','Villers-Cotterets','02'),('FR','VCU','Vaucouleurs','Vaucouleurs','55'),('FR','VDA','Vendargues','Vendargues','34'),('FR','VDB','Villars-les-Dombes','Villars-les-Dombes','01'),('FR','VDC','Vendenesse-les-Charolles','Vendenesse-les-Charolles','71'),('FR','VDG','Vaudreching','Vaudreching','57'),('FR','VDI','Valdoie','Valdoie','90'),('FR','VDL','Vaudreuille','Vaudreuille','31'),('FR','VDM','Villeneuve-de-Marsan','Villeneuve-de-Marsan','40'),('FR','VDO','Villenave-d\'Ornon','Villenave-d\'Ornon','33'),('FR','VDP','St Vincent-de-Pertignas','St Vincent-de-Pertignas','33'),('FR','VDS','Val de Saane','Val de Saane','76'),('FR','VDT','St Vallier-de-Thiey','St Vallier-de-Thiey','06'),('FR','VDV','Vendeville','Vendeville','59'),('FR','VDZ','Vieu-d\'Izenave','Vieu-d\'Izenave','01'),('FR','VEA','Veauche','Veauche','42'),('FR','VEC','Vecquemont','Vecquemont','80'),('FR','VED','Vedene','Vedene','84'),('FR','VEE','Vezelise','Vezelise','54'),('FR','VEG','Vilde-Guingalan','Vilde-Guingalan','22'),('FR','VEI','Velines','Velines','24'),('FR','VEL','Vesoul','Vesoul','70'),('FR','VEM','Vermelles','Vermelles','62'),('FR','VEN','Venelles','Venelles','13'),('FR','VEO','Vernaison','Vernaison','69'),('FR','VEP','Lavancia-Epercy','Lavancia-Epercy','39'),('FR','VER','Versailles','Versailles','78'),('FR','VES','Venissieux','Venissieux','69'),('FR','VET','Vernouillet','Vernouillet','78'),('FR','VEU','Velaux','Velaux','13'),('FR','VEV','Vaulx-en-Velin','Vaulx-en-Velin','69'),('FR','VEZ','Vergeze','Vergeze','30'),('FR','VFB','Valframbert','Valframbert','61'),('FR','VFE','Villefranche-de-Lauragais','Villefranche-de-Lauragais','31'),('FR','VFI','Vineuil-Saint-Firmin','Vineuil-Saint-Firmin','60'),('FR','VFL','Verfeuil','Verfeuil','30'),('FR','VFM','Villefranche-sur-Mer','Villefranche-sur-Mer','06'),('FR','VFT','Viols-le-Fort','Viols-le-Fort','34'),('FR','VFY','Viroflay','Viroflay','78'),('FR','VGA','Villefagnan','Villefagnan','16'),('FR','VGC','Salvagnac','Salvagnac','81'),('FR','VGD','Ville-la-Grand','Ville-la-Grand','74'),('FR','VGE','Villegusien-le-Lac','Villegusien-le-Lac','52'),('FR','VGG','Voeuil-et-Giget','Voeuil-et-Giget','16'),('FR','VGL','Volgelsheim','Volgelsheim','68'),('FR','VGM','Sanvignes-les-Mines','Sanvignes-les-Mines','71'),('FR','VGN','Villeneuve-Saint-Germain','Villeneuve-Saint-Germain','02'),('FR','VGO','Velotte-et-Tatignecourt','Velotte-et-Tatignecourt','88'),('FR','VGR','Vallant-Saint-Georges','Vallant-Saint-Georges','10'),('FR','VGS','Varages','Varages','83'),('FR','VGU','Valergues','Valergues','34'),('FR','VGX','Vigneux','Vigneux',''),('FR','VGY','Vigy','Vigy','57'),('FR','VHA','Vitrolles','Vitrolles','05'),('FR','VHC','Villefranche-sur-Cher ','Villefranche-sur-Cher ','41'),('FR','VHI','Vauchretien','Vauchretien','49'),('FR','VHN','Le Valdahon','Le Valdahon','25'),('FR','VHO','Venthon','Venthon','73'),('FR','VHP','Villefranche-de-Panat','Villefranche-de-Panat','12'),('FR','VHR','Vilhonneur','Vilhonneur','16'),('FR','VHS','Villers-le-Sec','Villers-le-Sec','70'),('FR','VHV','Villecheneve','Villecheneve','69'),('FR','VHY','Vichy','Vichy','03'),('FR','VIA','Ville-d\'Avray','Ville-d\'Avray','92'),('FR','VIB','Villard-Bonnot','Villard-Bonnot','38'),('FR','VIC','Vivier-au-Court','Vivier-au-Court','08'),('FR','VID','Les Villedieu','Les Villedieu','25'),('FR','VIE','Vienne','Vienne','38'),('FR','VIF','Vif','Vif','38'),('FR','VIG','Saint-Thibault-des-Vignes','Saint-Thibault-des-Vignes','77'),('FR','VIH','Vigneulles-les-Hattonchatel','Vigneulles-les-Hattonchatel','55'),('FR','VII','Villiers-le-Sec','Villiers-le-Sec','52'),('FR','VIL','Villepinte','Villepinte','93'),('FR','VIM','Villeneuve-la-Garenne','Villeneuve-la-Garenne','92'),('FR','VIN','Viane','Viane','81'),('FR','VIO','Viotte/Besancon','Viotte/Besancon','25'),('FR','VIQ','Ville','Ville','67'),('FR','VIR','Vitre','Vitre','35'),('FR','VIS','Villers-Saint-Sepulcre','Villers-Saint-Sepulcre','60'),('FR','VIT','Vitrolles','Vitrolles','13'),('FR','VIU','Virieu','Virieu','38'),('FR','VIV','Viviers','Viviers',''),('FR','VIY','Vincey','Vincey','88'),('FR','VIZ','Vizille','Vizille','38'),('FR','VJO','Valanjou','Valanjou','49'),('FR','VJR','Vaujours','Vaujours','93'),('FR','VJT','Villejust','Villejust','91'),('FR','VLA','Voulangis','Voulangis','77'),('FR','VLB','La Valbonne','La Valbonne','01'),('FR','VLC','Vannes-le-Chatel','Vannes-le-Chatel','54'),('FR','VLD','Villaz','Villaz','74'),('FR','VLE','Villemade','Villemade','82'),('FR','VLF','Valflaunes','Valflaunes','34'),('FR','VLG','Saint-Martin-de-Valgalgues','Saint-Martin-de-Valgalgues','30'),('FR','VLH','Velaine-en-Haye','Velaine-en-Haye','54'),('FR','VLI','Villevieille','Villevieille','30'),('FR','VLL','Villefranche-de-Rouergue','Villefranche-de-Rouergue','12'),('FR','VLM','Venarey-les-Laumes','Venarey-les-Laumes','21'),('FR','VLN','Villeneuve','Villeneuve',''),('FR','VLO','Villeron','Villeron','95'),('FR','VLP','Villerupt','Villerupt','54'),('FR','VLR','Vaison-la-Romaine','Vaison-la-Romaine','84'),('FR','VLS','Villiers','Villiers',''),('FR','VLT','Vallet','Vallet','44'),('FR','VLU','Val-de-Reuil','Val-de-Reuil','27'),('FR','VLV','Vendin-le-Vieil','Vendin-le-Vieil','62'),('FR','VLW','Villabe','Villabe','91'),('FR','VLX','Villeneuve-sur-Lot','Villeneuve-sur-Lot','47'),('FR','VLY','Valentigney','Valentigney','25'),('FR','VLZ','St Valery-sur-Bresle','St Valery-sur-Bresle','60'),('FR','VMA','Villers-le-Sec','Villers-le-Sec','51'),('FR','VMC','Vernois-sur-Mance','Vernois-sur-Mance','70'),('FR','VMD','Vermondans','Vermondans','25'),('FR','VME','Villers-le-Sec','Villers-le-Sec','55'),('FR','VMI','Vaumoise','Vaumoise','60'),('FR','VMO','Villers-la-Montagne','Villers-la-Montagne','54'),('FR','VMR','Villers-sur-Mer','Villers-sur-Mer','14'),('FR','VMS','Vimoutiers','Vimoutiers','61'),('FR','VMT','Valmont','Valmont','57'),('FR','VMY','Vimy','Vimy','62'),('FR','VNB','Villaines-sous-Bois','Villaines-sous-Bois','95'),('FR','VNC','Vincelles','Vincelles','89'),('FR','VND','Vendome','Vendome','41'),('FR','VNE','Vannes','Vannes','56'),('FR','VNG','Voellerdingen','Voellerdingen','67'),('FR','VNI','Vineuil','Vineuil','41'),('FR','VNL','Ventillon','Ventillon',''),('FR','VNS','Valognes','Valognes','50'),('FR','VNV','Vanves','Vanves','92'),('FR','VNX','Varen','Varen','82'),('FR','VNY','Vinay','Vinay','38'),('FR','VOA','Violaines','Violaines','62'),('FR','VOC','Vouciennes','Vouciennes','51'),('FR','VOG','Vogue','Vogue','07'),('FR','VOI','Voiron','Voiron','38'),('FR','VOL','Villebois-Lavalette','Villebois-Lavalette','16'),('FR','VOM','Voivres-les-le-Mans','Voivres-les-le-Mans','72'),('FR','VON','Vonnas','Vonnas','01'),('FR','VOR','Voreppe','Voreppe','38'),('FR','VOS','Violes','Violes','84'),('FR','VOU','Vouecourt','Vouecourt','52'),('FR','VOV','Volvic','Volvic','63'),('FR','VOX','Vecoux','Vecoux','88'),('FR','VOY','Vougy','Vougy','74'),('FR','VPA','St Vaast-Dieppedalle','St Vaast-Dieppedalle','76'),('FR','VPC','Vallon-Pont-d\'Arc','Vallon-Pont-d\'Arc','07'),('FR','VPO','Villers-les-Pots','Villers-les-Pots','21'),('FR','VPZ','Villeparisis','Villeparisis','77'),('FR','VQI','La Verrie','La Verrie','85'),('FR','VQL','Verquigneul','Verquigneul','62'),('FR','VQR','Veron','Veron','89'),('FR','VQU','Vacqueyras','Vacqueyras','84'),('FR','VRA','Valreas','Valreas','84'),('FR','VRC','Varces-Allieres-et-Risset','Varces-Allieres-et-Risset','38'),('FR','VRD','Verdun','Verdun','55'),('FR','VRE','Vire','Vire','71'),('FR','VRG','Verdigny','Verdigny','18'),('FR','VRH','Varilhes','Varilhes','09'),('FR','VRI','Vervins','Vervins','02'),('FR','VRL','Vaureal','Vaureal','95'),('FR','VRM','Vosne-Romanee','Vosne-Romanee','21'),('FR','VRN','Vernon','Vernon',''),('FR','VRO','Valleroy','Valleroy','54'),('FR','VRR','Verneuil-sur-Serre','Verneuil-sur-Serre','02'),('FR','VRS','Vire','Vire','14'),('FR','VRT','Viriat','Viriat','01'),('FR','VRV','Varennes-St-Sauveur','Varennes-St-Sauveur','71'),('FR','VRX','Vallabrix','Vallabrix','30'),('FR','VRY','Vatry','Vatry','51'),('FR','VSA','Varennes-sur-Allier','Varennes-sur-Allier','03'),('FR','VSB','Vouneuil-sous-Biard','Vouneuil-sous-Biard','87'),('FR','VSC','Vic-sur-Cere','Vic-sur-Cere','15'),('FR','VSD','Varennes-sous-Dun','Varennes-sous-Dun','71'),('FR','VSE','Vitre','Vitre','79'),('FR','VSF','Villiers-Saint-Frederic','Villiers-Saint-Frederic','78'),('FR','VSG','Villeneuve-Saint-Georges','Villeneuve-Saint-Georges','94'),('FR','VSL','Vire-sur-Lot','Vire-sur-Lot','46'),('FR','VSM','Vaires-sur-Marne','Vaires-sur-Marne','77'),('FR','VSN','Visan','Visan','84'),('FR','VSP','Villers-Saint-Paul','Villers-Saint-Paul','60'),('FR','VSQ','Varesnes','Varesnes','60'),('FR','VSR','Vis-en-Artois','Vis-en-Artois','62'),('FR','VSS','Villefranche-sur-Saone','Villefranche-sur-Saone','69'),('FR','VST','Venansault','Venansault','85'),('FR','VSU','Vic-sur-Aisne','Vic-sur-Aisne','02'),('FR','VSV','Verneuil-sur-Avre','Verneuil-sur-Avre','27'),('FR','VSW','Villeneuve-sur-Verberie','Villeneuve-sur-Verberie','60'),('FR','VSX','Vesseaux','Vesseaux','07'),('FR','VSY','Villebon-sur-Yvette','Villebon-sur-Yvette','91'),('FR','VTA','Vertolaye','Vertolaye','63'),('FR','VTB','Vernet-les-Bains','Vernet-les-Bains','66'),('FR','VTC','Verteillac','Verteillac','24'),('FR','VTE','Villetaneuse','Villetaneuse','93'),('FR','VTL','Vittel','Vittel','88'),('FR','VTN','Valenton','Valenton','94'),('FR','VTR','Lavilletertre','Lavilletertre','60'),('FR','VTS','Vitry-le-Francois','Vitry-le-Francois','51'),('FR','VTT','La Valette-du-Var','La Valette-du-Var','83'),('FR','VTU','Vertou','Vertou','44'),('FR','VTV','Vitrolles','Vitrolles','84'),('FR','VTX','Les Villettes','Les Villettes','43'),('FR','VTY','Vitry-sur-Seine','Vitry-sur-Seine','94'),('FR','VUC','Vaucluse','Vaucluse','84'),('FR','VUD','Vaudes','Vaudes','10'),('FR','VUE','Velluire','Velluire','85'),('FR','VUG','St-Vougay','St-Vougay','29'),('FR','VUI','Villeneuve-le-Roi','Villeneuve-le-Roi','94'),('FR','VUL','Veuil','Veuil','36'),('FR','VUM','Villemandeur','Villemandeur','45'),('FR','VUN','Villedieu-sur-Indre','Villedieu-sur-Indre','36'),('FR','VUO','Villaines-en-Duesmois','Villaines-en-Duesmois','21'),('FR','VUR','Vaucresson','Vaucresson','92'),('FR','VUT','Voujeaucourt','Voujeaucourt','25'),('FR','VUV','Vertus','Vertus','51'),('FR','VUY','Vouvray','Vouvray','37'),('FR','VUZ','Viuz-en-Sallaz','Viuz-en-Sallaz',''),('FR','VVA','Villeneuve-sur-Allier','Villeneuve-sur-Allier','03'),('FR','VVB','Villiers-le-Bel','Villiers-le-Bel','95'),('FR','VVC','Villeveyrac','Villeveyrac','34'),('FR','VVE','Voves','Voves','28'),('FR','VVF','Vivonne','Vivonne','86'),('FR','VVG','Vieillevigne','Vieillevigne','44'),('FR','VVI','Vieville','Vieville','52'),('FR','VVL','Villeneuve-les-Avignon','Villeneuve-les-Avignon','30'),('FR','VVN','Ventavon','Ventavon','05'),('FR','VVO','Vievola','Vievola','06'),('FR','VVQ','Villeneuve-d\'Ascq','Villeneuve-d\'Ascq','59'),('FR','VVR','Vendeuvre-sur-Barse','Vendeuvre-sur-Barse','10'),('FR','VVT','Vauvert','Vauvert','30'),('FR','VVU','Villeneuve-les-Maguelonne','Villeneuve-les-Maguelonne','34'),('FR','VVV','Villeneuve-Loubet','Villeneuve-Loubet','06'),('FR','VVY','Vivy','Vivy','49'),('FR','VVZ','Viviez','Viviez','12'),('FR','VXC','Vieux-Charmont','Vieux-Charmont','25'),('FR','VXE','St Sever','St Sever','40'),('FR','VXL','Villersexel','Villersexel','70'),('FR','VXP','Vaux-le-Penil','Vaux-le-Penil','77'),('FR','VXQ','Vieux-Berquin','Vieux-Berquin','59'),('FR','VXT','Vieux-Thann','Vieux-Thann','68'),('FR','VXV','Vernoux-en-Vivarais','Vernoux-en-Vivarais','07'),('FR','VYC','Viry-Chatillon','Viry-Chatillon','91'),('FR','VYE','Vayres','Vayres','33'),('FR','VYG','Vigny','Vigny',''),('FR','VYI','Viry-Noureuil','Viry-Noureuil','02'),('FR','VYM','Vitrey-sur-Mance','Vitrey-sur-Mance','70'),('FR','VYR','Veyrines','Veyrines',''),('FR','VYU','Verrey-sous-Dree','Verrey-sous-Dree','21'),('FR','VYX','Vabres-l\'Abbaye','Vabres-l\'Abbaye',''),('FR','VYZ','Veyrignac','Veyrignac','24'),('FR','VZA','Vezac','Vezac','24'),('FR','VZE','Vezelay','Vezelay','89'),('FR','VZI','Vezins','Vezins','49'),('FR','VZL','Venizel','Venizel','02'),('FR','VZN','Vierzon','Vierzon','18'),('FR','VZO','Vezenobres','Vezenobres','30'),('FR','VZS','Vouziers','Vouziers','08'),('FR','VZU','Velizy-Villacoublay','Velizy-Villacoublay','78'),('FR','VZX','Vias','Vias','34'),('FR','VZY','Velizy','Velizy','78'),('FR','WAL','Wallers','Wallers','59'),('FR','WAR','Warhem','Warhem','59'),('FR','WAS','Wasselonne','Wasselonne','67'),('FR','WAT','Wattrelos','Wattrelos','59'),('FR','WBO','Waltembourg','Waltembourg','57'),('FR','WBS','Wambrechies','Wambrechies','59'),('FR','WET','Wettolsheim','Wettolsheim','68'),('FR','WGA','Wolfgantzen','Wolfgantzen','68'),('FR','WGM','Wingen-sur-Moder','Wingen-sur-Moder','67'),('FR','WHE','Wingersheim','Wingersheim','67'),('FR','WHM','Wintzenheim','Wintzenheim','68'),('FR','WHT','Wormhout','Wormhout','59'),('FR','WIM','Wimille','Wimille','62'),('FR','WIS','Wisches','Wisches','67'),('FR','WLG','Wargnies-le-Grand','Wargnies-le-Grand','59'),('FR','WLH','Walheim','Walheim','68'),('FR','WLR','Witry-les-Reims','Witry-les-Reims','51'),('FR','WLU','Warluis','Warluis','60'),('FR','WMB','Wissembourg','Wissembourg','67'),('FR','WNT','Warneton','Warneton','59'),('FR','WOI','Woippy','Woippy','57'),('FR','WQM','Wacquemoulin','Wacquemoulin','60'),('FR','WRV','Wihr-au-Val','Wihr-au-Val','68'),('FR','WSE','Wegscheid','Wegscheid','68'),('FR','WSQ','Wasquehal','Wasquehal','59'),('FR','WSS','Wissous','Wissous','91'),('FR','WTG','Wattignies','Wattignies','59'),('FR','WTM','Wittelsheim','Wittelsheim','68'),('FR','WVQ','Wervicq-Sud','Wervicq-Sud','59'),('FR','WWE','Waldwisse','Waldwisse','57'),('FR','WWM','Wilwisheim','Wilwisheim','67'),('FR','WZN','Wizernes','Wizernes','62'),('FR','WZR','Waziers','Waziers','59'),('FR','XAN','Anse','Anse','69'),('FR','XAQ','Aix','Aix','19'),('FR','XCA','Cassen','Cassen','40'),('FR','XDV','St Laurent-du-Var','St Laurent-du-Var','06'),('FR','XEM','St Etienne-le-Molard','St Etienne-le-Molard','42'),('FR','XFY','Ste Foy-la-Grande','Ste Foy-la-Grande','33'),('FR','XGL','St-Gilles','St-Gilles','30'),('FR','XGV','St Gilles-Croix-de-Vie','St Gilles-Croix-de-Vie','85'),('FR','XHM','St Martin-d\'Heres','St Martin-d\'Heres','38'),('FR','XLB','St Laurent-Blangy','St Laurent-Blangy','62'),('FR','XLI','Isle','Isle','87'),('FR','XLT','Ax-les-Thermes','Ax-les-Thermes','09'),('FR','XOU','St Loubes','St Loubes','33'),('FR','XPG','St Pierre-la-Garenne','St Pierre-la-Garenne','27'),('FR','XPY','Pugey','Pugey','25'),('FR','XRL','Xermamenil','Xermamenil','54'),('FR','XRO','St Romain-sur-Cher','St Romain-sur-Cher','41'),('FR','XRT','Artenay','Artenay','45'),('FR','XSA','Marsac','Marsac','23'),('FR','XSC','St-Sylvestre-Cappel','St-Sylvestre-Cappel','59'),('FR','XSM','St Medar de Mussidan','St Medar de Mussidan',''),('FR','XSN','Sarrancolin','Sarrancolin','65'),('FR','XTG','Xertigny','Xertigny','88'),('FR','XUA','St Maur-des-Fosses','St Maur-des-Fosses','94'),('FR','XUL','Luc','Luc','48'),('FR','XUZ','St Uze','St Uze','26'),('FR','XZC','St Sylvestre-sur-Lot','St Sylvestre-sur-Lot','47'),('FR','XZF','St Marcellin-en-Forez','St Marcellin-en-Forez','42'),('FR','YAC','Vayrac','Vayrac','46'),('FR','YAI','Boussy-St-Antoine','Boussy-St-Antoine','91'),('FR','YAM','Amendeuix-Oneix','Amendeuix-Oneix','64'),('FR','YAR','Crancey','Crancey','10'),('FR','YAS','Asnois','Asnois','86'),('FR','YBE','Yebles','Yebles','77'),('FR','YBG','Blagny','Blagny','08'),('FR','YBM','Belmont-Tramonet','Belmont-Tramonet','73'),('FR','YCU','Beychac-et-Caillau','Beychac-et-Caillau','33'),('FR','YDE','Ydes','Ydes','15'),('FR','YDS','St-Pey-d\'Armens','St-Pey-d\'Armens','33'),('FR','YEZ','St Remy-de-Provence','St Remy-de-Provence','13'),('FR','YFF','Yffiniac','Yffiniac','22'),('FR','YGA','Sancey-le-Grand','Sancey-le-Grand','25'),('FR','YGS','St Genis-Laval','St Genis-Laval','69'),('FR','YGU','Meyrargues','Meyrargues','13'),('FR','YHC','Couchey','Couchey','21'),('FR','YIO','Clion','Clion','36'),('FR','YJQ','Saint-Jacques','Saint-Jacques','04'),('FR','YLA','Ally','Ally','43'),('FR','YLC','Barisey-la-Cote','Barisey-la-Cote','54'),('FR','YLE','Blere','Blere','37'),('FR','YLG','Sancey-le-Long','Sancey-le-Long','25'),('FR','YLM','St Barthelemy-le-Meil','St Barthelemy-le-Meil','07'),('FR','YLO','Cloyes-sur-le-Loir','Cloyes-sur-le-Loir','28'),('FR','YLZ','Yutz','Yutz','57'),('FR','YMC','Amancy','Amancy','74'),('FR','YMD','Merey-sous-Montrond','Merey-sous-Montrond','25'),('FR','YMI','Maille','Maille','86'),('FR','YMU','Moneteau','Moneteau','89'),('FR','YNE','La Seyne-sur-Mer','La Seyne-sur-Mer','83'),('FR','YNG','Sologny','Sologny','71'),('FR','YNN','Yenne','Yenne','73'),('FR','YOI','Brion','Brion','01'),('FR','YON','Bayon','Bayon','54'),('FR','YPZ','St Puy','St Puy','32'),('FR','YQU','Tincques','Tincques','62'),('FR','YRE','La-Vielle-Lyre','La-Vielle-Lyre','27'),('FR','YRI','Brie','Brie','80'),('FR','YRO','St-Cyr-sur-le-Rhone','St-Cyr-sur-le-Rhone','69'),('FR','YRR','Yerres','Yerres','91'),('FR','YRU','Veyrins-Thuellin','Veyrins-Thuellin','38'),('FR','YSC','Prayssac','Prayssac','12'),('FR','YSL','Seyssel','Seyssel','74'),('FR','YSO','Fleurey-sur-Ouche','Fleurey-sur-Ouche','21'),('FR','YSS','Saint-Alban-Leysse','Saint-Alban-Leysse','73'),('FR','YST','Cessey-sur-Tille','Cessey-sur-Tille','21'),('FR','YSX','Yssingeaux','Yssingeaux','43'),('FR','YSY','St Hippolyte-du-Fort','St Hippolyte-du-Fort','30'),('FR','YSZ','Sarzeau','Sarzeau','56'),('FR','YTA','Ytrac','Ytrac','15'),('FR','YVG','Blagny-sur-Vingeanne','Blagny-sur-Vingeanne','21'),('FR','YVR','Yvrac','Yvrac','33'),('FR','YVT','Yvetot','Yvetot','76'),('FR','YVV','St Vigor','St Vigor','27'),('FR','YXF','Saint-Martin-du-Frene','Saint-Martin-du-Frene','01'),('FR','YXU','St Laurent-les-Tours','St Laurent-les-Tours','46'),('FR','YZF','Santes','Santes','59'),('FR','YZR','Yzeure','Yzeure','03'),('FR','ZAO','Cahors','Cahors','46'),('FR','ZAY','Rozay-en-Brie','Rozay-en-Brie','77'),('FR','ZBI','Bias','Bias','40'),('FR','ZDP','St Laurent-du-Pont','St Laurent-du-Pont','38'),('FR','ZEF','St Etienne-du-Rouvray','St Etienne-du-Rouvray','76'),('FR','ZEL','Varennes-Vauzelles','Varennes-Vauzelles','58'),('FR','ZET','Bazet','Bazet','65'),('FR','ZFB','St Florent','St Florent',''),('FR','ZFM','St Marcellin','St Marcellin','38'),('FR','ZFO','Ste Foy-les-Lyon','Ste Foy-les-Lyon','69'),('FR','ZFZ','St Felix-de-Lodez','St Felix-de-Lodez','34'),('FR','ZGF','St Georges-sur-Loire','St Georges-sur-Loire','49'),('FR','ZGJ','St Germain-de-Joux','St Germain-de-Joux','01'),('FR','ZGM','St Galmier','St Galmier','42'),('FR','ZGP','St Germain-du-Plain','St Germain-du-Plain','71'),('FR','ZGW','St Genis-Pouilly','St Genis-Pouilly','01'),('FR','ZIJ','St Georges-de-Reneins','St Georges-de-Reneins','69'),('FR','ZIQ','St Leger','St Leger','49'),('FR','ZJF','St Jean-de-Braye','St Jean-de-Braye','45'),('FR','ZJI','St Julien-Mont-Denis','St Julien-Mont-Denis','73'),('FR','ZJU','St Julien-les-Villas','St Julien-les-Villas','10'),('FR','ZJZ','St Jean-de-Luz','St Jean-de-Luz','64'),('FR','ZLA','St Leger-sous-la-Bussiere','St Leger-sous-la-Bussiere','71'),('FR','ZLX','Ste Livrade','Ste Livrade','31'),('FR','ZMT','St Martin-le-Vinoux','St Martin-le-Vinoux','38'),('FR','ZMX','Ste Maxime','Ste Maxime','83'),('FR','ZNS','Vezinnes','Vezinnes','89'),('FR','ZOU','Saint-Ouen','Saint-Ouen','41'),('FR','ZPU','Saint-Paul-Trois-Chateaux','Saint-Paul-Trois-Chateaux','26'),('FR','ZPX','St Paul-de-Varax','St Paul-de-Varax','01'),('FR','ZQS','St Romain-de-Colbosc','St Romain-de-Colbosc','76'),('FR','ZRL','Mauze-sur-le-Mignon','Mauze-sur-le-Mignon',''),('FR','ZRP','St Priest','St Priest','69'),('FR','ZSB','Mezieres-en-Brenne','Mezieres-en-Brenne','36'),('FR','ZTG','Zetting','Zetting','57'),('FR','ZTZ','Stains','Stains','93'),('FR','ZUE','St Saulve','St Saulve','59'),('FR','ZUI','Buzet-sur-Baise','Buzet-sur-Baise','47'),('FR','ZWL','Zinswiller','Zinswiller','67'),('FR','ZXG','St Girons','St Girons','09'),('FR','ZXM','St Max','St Max','54'),('GA','','','',''),('GA','AKE','Akieni','Akieni',''),('GA','BEL','Belleville','Belleville',''),('GA','BGB','Booue','Booue',''),('GA','BMM','Bitam','Bitam',''),('GA','CCB','Cocobeach','Cocobeach',''),('GA','CLZ','Cap Lopez','Cap Lopez',''),('GA','EKU','Equata','Equata',''),('GA','FOU','Fougamou','Fougamou',''),('GA','GAX','Gamba','Gamba',''),('GA','KDJ','Ndjole','Ndjole',''),('GA','KDN','Ndende','Ndende',''),('GA','KOU','Koulamoutou','Koulamoutou',''),('GA','LBQ','Lambarene','Lambarene',''),('GA','LBV','Libreville','Libreville',''),('GA','LTL','Lastoursville','Lastoursville',''),('GA','LUC','Lucina','Lucina',''),('GA','MBC','Mbigou','Mbigou',''),('GA','MBY','M\'bya Terminal','M\'bya Terminal',''),('GA','MDV','Medouneu','Medouneu',''),('GA','MFF','Moanda','Moanda',''),('GA','MGO','Manega','Manega',''),('GA','MJL','Mouila','Mouila',''),('GA','MKB','Mekambo','Mekambo',''),('GA','MKU','Makokou','Makokou',''),('GA','MVB','Franceville','Franceville',''),('GA','MVE','Mvengue','Mvengue',''),('GA','MYB','Mayoumba','Mayoumba',''),('GA','MZC','Mitzic','Mitzic',''),('GA','NYA','Nyanga','Nyanga',''),('GA','OKN','Okondja','Okondja',''),('GA','OMB','Omboue','Omboue',''),('GA','OWE','Owendo','Owendo',''),('GA','OYE','Oyem','Oyem',''),('GA','POG','Port Gentil','Port Gentil',''),('GA','TCH','Tchibanga','Tchibanga',''),('GB','','','',''),('GB','ABA','Aberaeron','Aberaeron','DFD'),('GB','ABB','Abbots Langley','Abbots Langley','HRT'),('GB','ABD','Aberdeen','Aberdeen','GMP'),('GB','ABE','Aberdare','Aberdare','POW'),('GB','ABG','Abridge','Abridge','ESS'),('GB','ABL','Aberlour','Aberlour','GMP'),('GB','ABM','Abermule','Abermule','POW'),('GB','ABN','Abington','Abington','NTH'),('GB','ABO','Albourne','Albourne','WSX'),('GB','ABR','Appley Bridge','Appley Bridge','LAN'),('GB','ABT','Abertillery','Abertillery','GNT'),('GB','ABU','Ashburton','Ashburton','DEV'),('GB','ABX','Alford','Alford','LIN'),('GB','ABY','Aboyne','Aboyne','GMP'),('GB','ACF','Abercraf','Abercraf','POW'),('GB','ACG','Acocks Green/Birmingham','Acocks Green/Birmingham','WMD'),('GB','ACH','Auchterarder','Auchterarder','TAY'),('GB','ACI','Alderney','Alderney','CHA'),('GB','ACK','Ackworth','Ackworth','WYK'),('GB','ACL','Acle','Acle','NFK'),('GB','ACM','Altrincham','Altrincham','GTM'),('GB','ACN','Acton','Acton','GTL'),('GB','ACR','Accrington','Accrington','LAN'),('GB','ACS','Alcester','Alcester','WAR'),('GB','ACT','Acton Grange','Acton Grange','CHS'),('GB','ACY','Abercynon','Abercynon','MGM'),('GB','ADA','Adbaston','Adbaston','STS'),('GB','ADB','Aldbourne','Aldbourne','WIL'),('GB','ADD','Addingham','Addingham','WYK'),('GB','ADE','Ardsley East = Ardsley','Ardsley East = Ardsley','WYK'),('GB','ADG','Aldridge','Aldridge','WMD'),('GB','ADI','Addington','Addington','KEN'),('GB','ADL','Adlington','Adlington','LAN'),('GB','ADN','Addlestone','Addlestone','SRY'),('GB','ADT','Aldington','Aldington','KEN'),('GB','ADW','Addiewell','Addiewell','LTN'),('GB','ADY','Adderbury','Adderbury','OXF'),('GB','ADZ','Ashby de la Zouch','Ashby de la Zouch','LEC'),('GB','AEG','Aberbeeg','Aberbeeg',''),('GB','AEY','Arley','Arley','WAR'),('GB','AFO','Alford','Alford','ABD'),('GB','AFT','Afriston','Afriston','ESX'),('GB','AGE','Bagstone','Bagstone','SGC'),('GB','AGH','Aghadowey','Aghadowey','CLR'),('GB','AGN','Abingdon','Abingdon','OXF'),('GB','AGO','Arinagour','Arinagour','AGB'),('GB','AGR','Ashley','Ashley','CAM'),('GB','AGY','Abergavenny','Abergavenny','GNT'),('GB','AHE','Ashtead/London','Ashtead/London','SRY'),('GB','AHM','Altham','Altham','LAN'),('GB','AHO','Arkholme','Arkholme','LAN'),('GB','AHP','Ashampstead','Ashampstead','WBK'),('GB','AHV','Ash Vale','Ash Vale','SRY'),('GB','AII','Airlie','Airlie','TAY'),('GB','AIN','Aintree','Aintree','MSY'),('GB','AIR','Airdrie','Airdrie','STD'),('GB','AKS','Adwick le Street','Adwick le Street','DNC'),('GB','AKV','Aughnacloy','Aughnacloy','DGN'),('GB','AKY','Ashton Keynes','Ashton Keynes','WIL'),('GB','ALA','Alva','Alva','CLK'),('GB','ALB','Aldeburgh','Aldeburgh','SFK'),('GB','ALD','Aldershot','Aldershot','HAM'),('GB','ALE','Alderley Edge','Alderley Edge','CHS'),('GB','ALF','Alfreton','Alfreton','DBY'),('GB','ALG','Alsager','Alsager','CHS'),('GB','ALH','Aldenham','Aldenham','HRT'),('GB','ALL','Alloa','Alloa','CLK'),('GB','ALM','Alnmouth','Alnmouth','NBL'),('GB','ALN','Alton','Alton','HAM'),('GB','ALR','Aldermaston','Aldermaston','WBK'),('GB','ALS','Alston','Alston','CMA'),('GB','ALU','Aldbury','Aldbury','HRT'),('GB','ALV','Alveston','Alveston','SGC'),('GB','ALW','Alnwick','Alnwick','NBL'),('GB','ALX','Alexandria','Alexandria',''),('GB','ALY','Alconbury','Alconbury','CAM'),('GB','AMB','Amble','Amble','NBL'),('GB','AME','Amersham','Amersham','BKM'),('GB','AMG','Ambergate','Ambergate','DBY'),('GB','AML','Ambleside','Ambleside','CMA'),('GB','AMM','Ammanford','Ammanford','DFD'),('GB','AMP','Ampthill','Ampthill','BDF'),('GB','AMS','Amesbury','Amesbury','WIL'),('GB','AMW','Amlwch','Amlwch',''),('GB','ANA','Anasuria','Anasuria','SCT'),('GB','ANB','Anlaby','Anlaby',''),('GB','ANC','Barnacle','Barnacle','WAR'),('GB','ANG','Annalong','Annalong','NYM'),('GB','ANN','Annan','Annan','DGY'),('GB','ANT','Antrim','Antrim','ANT'),('GB','ANW','Annesley Woodhouse','Annesley Woodhouse','NTT'),('GB','AOM','Abbots Morton','Abbots Morton','WOR'),('GB','AON','Aston','Aston','SYK'),('GB','APH','Alphington','Alphington','DVV'),('GB','APL','Appleton','Appleton','OXF'),('GB','APN','Alperton','Alperton','BEN'),('GB','APP','Appledore','Appledore',''),('GB','APT','Appleton Thorn','Appleton Thorn','CHS'),('GB','AQO','Ash','Ash','KEN'),('GB','ARB','Arbroath','Arbroath','TAY'),('GB','ARD','Ardrossan','Ardrossan','STD'),('GB','ARE','Armadale','Armadale','LTN'),('GB','ARI','Armitage','Armitage','STS'),('GB','ARK','Askern','Askern','SYK'),('GB','ARL','New Alresford','New Alresford','HAM'),('GB','ARM','Armagh','Armagh','ARM'),('GB','ARN','Arnesby','Arnesby','LEC'),('GB','ARO','Arnold','Arnold','NTT'),('GB','ARR','Arrington','Arrington','CAM'),('GB','ARS','Ardersier','Ardersier','HLD'),('GB','ART','Artigarvan','Artigarvan','STB'),('GB','ARU','Arundel','Arundel','WSX'),('GB','ARY','Bardney','Bardney','LIN'),('GB','ASB','Abbots Bromley','Abbots Bromley','STS'),('GB','ASC','Ascot','Ascot','WNM'),('GB','ASD','Ashford','Ashford','KEN'),('GB','ASE','Allestree','Allestree','DBY'),('GB','ASF','Ashford','Ashford','SRY'),('GB','ASG','Ardrishaig','Ardrishaig','STD'),('GB','ASH','Ashbourne','Ashbourne','DBY'),('GB','ASL','Ashton under Lyne','Ashton under Lyne','GTM'),('GB','ASM','Ashton in Makerfield','Ashton in Makerfield','GTM'),('GB','ASN','Aston','Aston','WOK'),('GB','ASO','Aston','Aston','HRT'),('GB','ASQ','Askham','Askham','CMA'),('GB','AST','Ashington','Ashington','NBL'),('GB','ASV','Aston Somerville','Aston Somerville','HWR'),('GB','ASW','Ashwell','Ashwell','LEC'),('GB','ASY','Arlesey','Arlesey','BDF'),('GB','ATE','Abernyte','Abernyte','TAY'),('GB','ATH','Atherstone','Atherstone','LEC'),('GB','ATL','Acton Turville','Acton Turville','GLS'),('GB','ATN','Aston Clinton','Aston Clinton','BKM'),('GB','ATO','Acton, Sudbury','Acton, Sudbury','SFK'),('GB','ATR','Atherton','Atherton','GTM'),('GB','ATT','Attenborough','Attenborough','NTT'),('GB','ATY','Ansty','Ansty','WSX'),('GB','AUD','Audenshaw','Audenshaw','GTM'),('GB','AVE','Aveley','Aveley','ESS'),('GB','AVL','Alveley','Alveley','SHR'),('GB','AVO','Avonmouth','Avonmouth','BST'),('GB','AVR','Andover','Andover','HAM'),('GB','AWA','Ashwater','Ashwater','DVV'),('GB','AWL','Attleborough','Attleborough','NFK'),('GB','AWR','Ailsworth','Ailsworth','CAM'),('GB','AXB','Axbridge','Axbridge','SOM'),('GB','AXM','Axminster','Axminster',''),('GB','AXP','Aspatria','Aspatria','CMA'),('GB','AYA','Aylesbeare','Aylesbeare','DEV'),('GB','AYD','Aberdour','Aberdour','FIF'),('GB','AYE','Aylesham','Aylesham','KEN'),('GB','AYF','Aycliffe','Aycliffe','DUR'),('GB','AYL','Aylesbury','Aylesbury','BKM'),('GB','AYR','Ayr','Ayr','STD'),('GB','AYS','Aylesford','Aylesford','KEN'),('GB','AYW','Aberystwyth','Aberystwyth','DFD'),('GB','AZV','Appleby','Appleby','CMA'),('GB','BAA','Bala','Bala','GWN'),('GB','BAB','Banbury','Banbury','OXF'),('GB','BAC','Balsall Common','Balsall Common','WMD'),('GB','BAD','Barry Dock','Barry Dock','SGM'),('GB','BAE','Ballyclare','Ballyclare','ANT'),('GB','BAF','Barrowford','Barrowford','LAN'),('GB','BAG','Baginton','Baginton','WAR'),('GB','BAH','Barrhead','Barrhead','STD'),('GB','BAI','Baildon','Baildon','WYK'),('GB','BAK','Barnoldswick','Barnoldswick','LAN'),('GB','BAL','Baldock','Baldock','HRT'),('GB','BAM','Bingham','Bingham','NTT'),('GB','BAN','Bangor','Bangor','DOW'),('GB','BAO','Bascote','Bascote','WAR'),('GB','BAP','Bacup','Bacup','LAN'),('GB','BAR','Barnes','Barnes','GTL'),('GB','BAS','Basildon','Basildon','ESS'),('GB','BAT','Battlesbridge','Battlesbridge','ESS'),('GB','BAU','Baulking','Baulking','OXF'),('GB','BAV','Bidford','Bidford','WAR'),('GB','BAW','Baltic Wharf','Baltic Wharf','GTL'),('GB','BAY','Batley','Batley','WYK'),('GB','BBA','Burbage','Burbage','WIL'),('GB','BBC','Benbecula','Benbecula',''),('GB','BBD','Barton Bendish','Barton Bendish','NFK'),('GB','BBG','Banbridge','Banbridge','BNB'),('GB','BBH','Bilborough','Bilborough','NTT'),('GB','BBP','Bembridge','Bembridge','IOW'),('GB','BBR','Boroughbridge','Boroughbridge','NYK'),('GB','BBS','Blackbush','Blackbush',''),('GB','BBU','Bredbury','Bredbury','SKP'),('GB','BBW','Buckland Brewer','Buckland Brewer','DEV'),('GB','BCA','Barnard Castle','Barnard Castle','DUR'),('GB','BCB','Blackboys','Blackboys','ESX'),('GB','BCC','Beccles','Beccles','SFK'),('GB','BCF','Blackfordby','Blackfordby','LEC'),('GB','BCK','Brackley','Brackley','NTH'),('GB','BCL','Buckley','Buckley','CWD'),('GB','BCN','Brecon','Brecon','POW'),('GB','BCT','Beckton','Beckton','GTL'),('GB','BCV','Birch Vale','Birch Vale','DBY'),('GB','BCW','Blackwood Hill','Blackwood Hill','GNT'),('GB','BCY','Barton in the Clay','Barton in the Clay','BDF'),('GB','BDA','Birkdale','Birkdale','SFT'),('GB','BDC','Bordon Camp','Bordon Camp','CAM'),('GB','BDD','Beddington','Beddington','GTL'),('GB','BDE','Biddenden','Biddenden','KEN'),('GB','BDI','Brodick','Brodick','STD'),('GB','BDK','Banchory - Devenick','Banchory - Devenick','GMP'),('GB','BDL','Bedale','Bedale','NYK'),('GB','BDM','Bodmin','Bodmin','CON'),('GB','BDN','Boldon','Boldon','TWR'),('GB','BDS','Bieldside','Bieldside','GMP'),('GB','BDT','Broadstairs','Broadstairs','KEN'),('GB','BDU','Biddulph','Biddulph','STS'),('GB','BDW','Bedwas','Bedwas','MGM'),('GB','BDY','Brawdy','Brawdy','DFD'),('GB','BEA','Beaconsfield','Beaconsfield','BKM'),('GB','BEB','Bebington','Bebington','MSY'),('GB','BEC','Beckingham','Beckingham','LIN'),('GB','BED','Bedfont','Bedfont','GTL'),('GB','BEE','Beeston','Beeston','NTT'),('GB','BEF','Bedford','Bedford','BDF'),('GB','BEH','Berry Head','Berry Head',''),('GB','BEI','Beith','Beith','STD'),('GB','BEL','Belfast','Belfast','BFS'),('GB','BEM','Burslem','Burslem','STS'),('GB','BEN','Belton','Belton','NLN'),('GB','BEO','Burrelton','Burrelton','TAY'),('GB','BER','Bearsted','Bearsted','KEN'),('GB','BES','Benson','Benson','OXF'),('GB','BET','Bethesda','Bethesda','DFD'),('GB','BEU','Bures','Bures','SFK'),('GB','BEV','Beverley','Beverley','HUM'),('GB','BEW','Beaworthy','Beaworthy','DEV'),('GB','BEX','Bexley','Bexley','GTL'),('GB','BEY','Bromley','Bromley','KEN'),('GB','BEZ','Bearley','Bearley','WAR'),('GB','BFB','Braefoot Bay','Braefoot Bay','FIF'),('GB','BFD','Brentford','Brentford','GTL'),('GB','BFE','Brierfield','Brierfield','LAN'),('GB','BFF','Banff','Banff','GMP'),('GB','BFH','Bramfield','Bramfield','HRT'),('GB','BFI','Binfield','Binfield','BRC'),('GB','BFO','Bodffordd','Bodffordd','AGY'),('GB','BFY','Briton Ferry','Briton Ferry','WGM'),('GB','BGA','Bridge of Allan','Bridge of Allan','STG'),('GB','BGD','Bridgend','Bridgend','TAY'),('GB','BGE','Barns Green','Barns Green','WSX'),('GB','BGG','Brigg','Brigg','HUM'),('GB','BGH','Burscough','Burscough','LAN'),('GB','BGK','Basingstoke','Basingstoke','HAM'),('GB','BGL','Bagillt','Bagillt','CWD'),('GB','BGN','Borough Green','Borough Green','KEN'),('GB','BGO','Bargoed','Bargoed','WGM'),('GB','BGR','Burnham Green','Burnham Green','HRT'),('GB','BGS','Bagshot','Bagshot','SRY'),('GB','BGT','Billingshurst','Billingshurst','WSX'),('GB','BGV','Bromsgrove','Bromsgrove','HWR'),('GB','BGW','Ballygowan','Ballygowan','DOW'),('GB','BGX','Biggar','Biggar','SLK'),('GB','BGY','Bingley','Bingley','WYK'),('GB','BHA','Beetham','Beetham','CMA'),('GB','BHE','Balsall Heath','Balsall Heath','BIR'),('GB','BHG','Bellaghy','Bellaghy','MFT'),('GB','BHH','Buckhurst Hill','Buckhurst Hill','ESS'),('GB','BHI','Bardon Hill','Bardon Hill','LEC'),('GB','BHK','Bromborough','Bromborough','MSY'),('GB','BHL','Bramhall','Bramhall','GTM'),('GB','BHM','Birmingham','Birmingham','WMD'),('GB','BHO','Boughton','Boughton','NFK'),('GB','BHP','Beckhampton','Beckhampton','WIL'),('GB','BHR','Barrow-upon-Humber','Barrow-upon-Humber','HUM'),('GB','BHS','Barnet','Barnet','GTL'),('GB','BHT','Blackheath/London','Blackheath/London',''),('GB','BHV','Buckhaven','Buckhaven','FIF'),('GB','BHW','Billingham','Billingham','CLV'),('GB','BHY','Billinghay','Billinghay','LIN'),('GB','BIC','Bicester','Bicester','OXF'),('GB','BID','Bideford','Bideford',''),('GB','BIE','Birtley','Birtley','HWR'),('GB','BIF','Barrow in Furness','Barrow in Furness','CMA'),('GB','BIG','Bridgtown','Bridgtown','STS'),('GB','BIH','Bickenhill','Bickenhill','SOL'),('GB','BII','Brill','Brill','BKM'),('GB','BIL','Billericay','Billericay','ESS'),('GB','BIN','Ballingry','Ballingry','FIF'),('GB','BIO','Bitton','Bitton','SGC'),('GB','BIP','Bishop Auckland','Bishop Auckland','DUR'),('GB','BIR','Birtley','Birtley','TWR'),('GB','BIS','Bilston','Bilston','WMD'),('GB','BIT','Birstall','Birstall','LEC'),('GB','BIW','Biggleswade','Biggleswade','BDF'),('GB','BIX','Brixworth','Brixworth','NTH'),('GB','BIY','Bisley','Bisley','GLS'),('GB','BJT','Bartestree','Bartestree','HWR'),('GB','BKA','Buckfast','Buckfast','DEV'),('GB','BKB','Bannockburn','Bannockburn','STG'),('GB','BKD','Buckden','Buckden','CAM'),('GB','BKF','Belleek','Belleek','FER'),('GB','BKG','Barking/London','Barking/London','ESS'),('GB','BKH','Berkhamsted','Berkhamsted','HRT'),('GB','BKL','Bickley','Bickley','GTL'),('GB','BKM','Beckenham','Beckenham','GTL'),('GB','BKN','Bracknell','Bracknell','BRC'),('GB','BKO','Bally Kelly','Bally Kelly',''),('GB','BKP','Brookmans Park','Brookmans Park','HRT'),('GB','BKR','Brockworth','Brockworth','GLS'),('GB','BKS','Blackness','Blackness','FAL'),('GB','BKT','Brockenhurst','Brockenhurst','HAM'),('GB','BKW','Bakewell','Bakewell','DBY'),('GB','BKY','Blockley','Blockley','GLS'),('GB','BLA','Blackford','Blackford','SOM'),('GB','BLB','Blackburn','Blackburn','LAN'),('GB','BLD','Blaydon','Blaydon','TWR'),('GB','BLE','Bletchley','Bletchley','BKM'),('GB','BLF','Blandford Forum','Blandford Forum','DOR'),('GB','BLG','Ballygown','Ballygown','STD'),('GB','BLH','Ballynahinch','Ballynahinch','DOW'),('GB','BLK','Blackpool','Blackpool','LAN'),('GB','BLL','Bellshill','Bellshill','STD'),('GB','BLM','Ballymoney','Ballymoney','BLY'),('GB','BLN','Bletchingley','Bletchingley','SRY'),('GB','BLO','Balerno','Balerno','LTN'),('GB','BLP','Belper','Belper','DBY'),('GB','BLR','Ballylumford','Ballylumford','LRN'),('GB','BLS','Brightlingsea','Brightlingsea','ESS'),('GB','BLT','Bolton','Bolton','GTM'),('GB','BLU','Beaulieu','Beaulieu','HAM'),('GB','BLV','Belvedere','Belvedere','GTL'),('GB','BLW','Blackwood','Blackwood','GNT'),('GB','BLX','Bloxwich','Bloxwich','WMD'),('GB','BLY','Blyth','Blyth','NBL'),('GB','BMA','Burnham-on-Sea','Burnham-on-Sea','SOM'),('GB','BMB','Bamberbridge','Bamberbridge','LAN'),('GB','BMD','Borehamwood','Borehamwood','HRT'),('GB','BME','Bermondsey/London','Bermondsey/London','SWK'),('GB','BMH','Bramhope','Bramhope','WYK'),('GB','BMI','Brackmills','Brackmills','NTH'),('GB','BML','Bramley','Bramley','ROT'),('GB','BMM','Bromham','Bromham','WIL'),('GB','BMN','Beaminster','Beaminster','DOR'),('GB','BMP','Brompton','Brompton','KEN'),('GB','BMR','Beaumaris','Beaumaris','GWN'),('GB','BMS','Bushmills','Bushmills','MYL'),('GB','BMW','Brynmawr','Brynmawr','GNT'),('GB','BMY','Bramley','Bramley','SYK'),('GB','BNA','Brynna','Brynna','MGM'),('GB','BNC','Banchory','Banchory','GMP'),('GB','BND','Barnstaple','Barnstaple',''),('GB','BNE','Bran End','Bran End','ESS'),('GB','BNF','Benfield','Benfield','DGY'),('GB','BNG','Bangor','Bangor','GWN'),('GB','BNH','Barton upon Humber','Barton upon Humber','HUM'),('GB','BNI','Bethania','Bethania','CGN'),('GB','BNL','Binley','Binley','HAM'),('GB','BNM','Barton','Barton','MSY'),('GB','BNN','Braunton','Braunton',''),('GB','BNO','Barton-under-Needwood','Barton-under-Needwood','STS'),('GB','BNS','Bolton le Sands','Bolton le Sands','LAN'),('GB','BNT','Bridgnorth','Bridgnorth','SHR'),('GB','BNW','Burtonwood','Burtonwood','CHS'),('GB','BNY','Bonnybridge','Bonnybridge','FAL'),('GB','BOA','Bradford on Avon','Bradford on Avon','WIL'),('GB','BOC','Burnham on Crouch','Burnham on Crouch','ESS'),('GB','BOD','Boscombe','Boscombe','DOR'),('GB','BOE','Bootle','Bootle','MSY'),('GB','BOG','Bonnyrigg','Bonnyrigg','LTN'),('GB','BOH','Bournemouth','Bournemouth','DOR'),('GB','BOI','Bollington','Bollington','CHS'),('GB','BOL','Botley','Botley','BKM'),('GB','BON','Bo\'ness','Bo\'ness','FAL'),('GB','BOO','Bootle','Bootle','CMA'),('GB','BOR','Borden','Borden','KEN'),('GB','BOS','Boston','Boston','LIN'),('GB','BOU','Bourton-on-the-Water','Bourton-on-the-Water','GLS'),('GB','BOW','Bowling','Bowling','STD'),('GB','BOY','Botley','Botley','HAM'),('GB','BPL','Black Pill','Black Pill','WGM'),('GB','BPM','Burpham','Burpham','SRY'),('GB','BPO','Brampton','Brampton','CAM'),('GB','BPW','Bishop\'s Waltham','Bishop\'s Waltham','HAM'),('GB','BQH','Biggin Hill','Biggin Hill','GTL'),('GB','BQL','Belleek','Belleek','ARM'),('GB','BQN','Burnaston','Burnaston','DBY'),('GB','BQY','Broseley','Broseley','SHR'),('GB','BRA','Brandon','Brandon','SFK'),('GB','BRC','Brechin','Brechin','TAY'),('GB','BRD','Bridgend','Bridgend','STD'),('GB','BRE','Braehead','Braehead','TAY'),('GB','BRF','Bradford','Bradford','WYK'),('GB','BRG','Bridgend','Bridgend','MGM'),('GB','BRH','Brighouse','Brighouse','WYK'),('GB','BRI','Braintree','Braintree','ESS'),('GB','BRK','Birkenhead','Birkenhead','MSY'),('GB','BRL','Barwell','Barwell','LEC'),('GB','BRM','Brantham','Brantham','SFK'),('GB','BRN','Burnley','Burnley','LAN'),('GB','BRO','Broadheath','Broadheath','GTM'),('GB','BRP','Bridport','Bridport','DOR'),('GB','BRQ','Bradley','Bradley','STS'),('GB','BRR','Barra','Barra',''),('GB','BRS','Bristol','Bristol','BST'),('GB','BRT','Bridlington','Bridlington','HUM'),('GB','BRW','Bridgwater','Bridgwater','SOM'),('GB','BRX','Brixham','Brixham',''),('GB','BRY','Bryn','Bryn','WGM'),('GB','BRZ','Brenchley','Brenchley','KEN'),('GB','BSA','Banstead','Banstead','SRY'),('GB','BSD','Bearsden','Bearsden',''),('GB','BSE','Bury St Edmunds','Bury St Edmunds','SFK'),('GB','BSF','Bassingfield','Bassingfield','NTT'),('GB','BSG','Brislington','Brislington','BST'),('GB','BSH','Brighton','Brighton','ESX'),('GB','BSI','Bognor Regis','Bognor Regis','WSX'),('GB','BSK','Bradley Stoke','Bradley Stoke','SGC'),('GB','BSL','Bosley','Bosley','CHS'),('GB','BSN','Baltasound','Baltasound','ZET'),('GB','BSO','Bolsover','Bolsover','DBY'),('GB','BSP','Bishopbriggs','Bishopbriggs','STD'),('GB','BSR','Bransgore','Bransgore','HAM'),('GB','BST','Bishop\'s Stortford','Bishop\'s Stortford','HRT'),('GB','BSW','Bishopsworth','Bishopsworth','BST'),('GB','BSY','Barnsley','Barnsley','SYK'),('GB','BTA','Broughton Astley','Broughton Astley','LEC'),('GB','BTB','Barnetby-le-Wold','Barnetby-le-Wold','NLN'),('GB','BTC','Barton Stacey','Barton Stacey','HAM'),('GB','BTD','Burton','Burton','DFD'),('GB','BTE','Battle','Battle','ESX'),('GB','BTF','Bathford','Bathford','BAS'),('GB','BTG','Bethnal Green/London','Bethnal Green/London','GTL'),('GB','BTH','Bathgate','Bathgate','LTN'),('GB','BTL','Burntisland','Burntisland','FIF'),('GB','BTM','Bath','Bath','BAS'),('GB','BTN','Bedlington','Bedlington','TWR'),('GB','BTO','Buntingford','Buntingford','HRT'),('GB','BTR','Burton upon Trent','Burton upon Trent','STS'),('GB','BTS','Bircotes','Bircotes','NTT'),('GB','BTT','Battersea','Battersea','GTL'),('GB','BTW','Betchworth','Betchworth','SRY'),('GB','BTY','Botley','Botley','OXF'),('GB','BUA','Budleigh Salterton','Budleigh Salterton',''),('GB','BUB','Bugbrooke','Bugbrooke','NTH'),('GB','BUC','Buckie','Buckie','GMP'),('GB','BUD','Bude','Bude','CON'),('GB','BUE','Bursledon','Bursledon','HAM'),('GB','BUG','Bungay','Bungay','SFK'),('GB','BUH','Burghead','Burghead','GMP'),('GB','BUI','Builth Wells','Builth Wells','POW'),('GB','BUJ','Burton Joyce','Burton Joyce','NTT'),('GB','BUK','Buckingham','Buckingham','BKM'),('GB','BUL','Burgess Hill','Burgess Hill','WSX'),('GB','BUM','Burnham','Burnham','BKM'),('GB','BUN','Burton','Burton','LIN'),('GB','BUO','Barrow On Soar','Barrow On Soar','LEC'),('GB','BUP','Bulpham','Bulpham','THR'),('GB','BUR','Bourne','Bourne','LIN'),('GB','BUS','Burton upon Stather','Burton upon Stather','HUM'),('GB','BUW','Burntwood','Burntwood','STS'),('GB','BUX','Buxton','Buxton','DBY'),('GB','BUY','Bury','Bury','GTM'),('GB','BUZ','Burley','Burley','HAM'),('GB','BVD','Bovingdon','Bovingdon','DOR'),('GB','BVE','Bournville/Birmingham','Bournville/Birmingham','WMD'),('GB','BVN','Blaenavon','Blaenavon','LTN'),('GB','BVT','Bovey Tracey','Bovey Tracey',''),('GB','BWA','Broadway','Broadway','WOR'),('GB','BWD','Brentwood','Brentwood','ESS'),('GB','BWE','Bowden','Bowden','BOR'),('GB','BWH','Birstwith','Birstwith','NYK'),('GB','BWI','Bridge of Weir','Bridge of Weir',''),('GB','BWK','Berwick-upon-Tweed','Berwick-upon-Tweed','NBL'),('GB','BWL','Bothwell','Bothwell','STD'),('GB','BWN','Bowburn','Bowburn','DUR'),('GB','BWO','Bedworth','Bedworth','WAR'),('GB','BWQ','Bow','Bow','DEV'),('GB','BWR','Burrow','Burrow','SOM'),('GB','BWS','Brownhills','Brownhills','WMD'),('GB','BWT','Bawtry','Bawtry','DNC'),('GB','BWW','Brinkworth','Brinkworth','WIL'),('GB','BWY','Bodelwyddan','Bodelwyddan','CWD'),('GB','BXB','Bexhill','Bexhill','ESX'),('GB','BXD','Boxted','Boxted','ESS'),('GB','BXG','Brassington','Brassington','DBY'),('GB','BXM','Ballinamallard','Ballinamallard','FER'),('GB','BXN','Broxbourne','Broxbourne','HRT'),('GB','BXR','Burwell','Burwell','CAM'),('GB','BXU','Broxburn','Broxburn','LTN'),('GB','BYB','Blythe Bridge','Blythe Bridge','BOR'),('GB','BYC','Ballycastle','Ballycastle','ANT'),('GB','BYD','Bromyard','Bromyard','HWR'),('GB','BYE','Bushey Heath','Bushey Heath','HRT'),('GB','BYF','Byfleet','Byfleet','SRY'),('GB','BYG','Barry','Barry','SGM'),('GB','BYL','Bulwell/Nottingham','Bulwell/Nottingham','NTT'),('GB','BYM','Ballymena','Ballymena','BLA'),('GB','BYQ','Bushey','Bushey','HRT'),('GB','BYR','Blantyre','Blantyre','STD'),('GB','BYU','Little Chalfont','Little Chalfont','BKM'),('GB','BYW','Ballygawley','Ballygawley','DGN'),('GB','BYY','Broughty Ferry','Broughty Ferry','TAY'),('GB','BZE','Belford','Belford','NBL'),('GB','BZL','Birstall','Birstall','WYK'),('GB','BZT','Broughton','Broughton','CWD'),('GB','BZZ','Brize Norton','Brize Norton','OXF'),('GB','CAC','Castle Cary','Castle Cary','SOM'),('GB','CAD','Castle Donington','Castle Donington','LEC'),('GB','CAE','Caerphilly','Caerphilly','MGM'),('GB','CAI','Caistor','Caistor','LIN'),('GB','CAK','Carluke','Carluke','STD'),('GB','CAM','Cambus','Cambus','CLK'),('GB','CAN','Canvey Island','Canvey Island','ESS'),('GB','CAO','Carlton','Carlton','NYK'),('GB','CAP','Capel','Capel','SRY'),('GB','CAR','Cardigan','Cardigan','DFD'),('GB','CAS','Castleton','Castleton','DBY'),('GB','CAT','Catrine','Catrine','STD'),('GB','CAX','Carlisle','Carlisle','CMA'),('GB','CAY','Camberley','Camberley','SRY'),('GB','CBA','Castlebay','Castlebay','WIS'),('GB','CBB','Coombe Bissett','Coombe Bissett','WIL'),('GB','CBG','Corbridge','Corbridge','NBL'),('GB','CBH','Cobham','Cobham','KEN'),('GB','CBI','Canonbie','Canonbie','DGY'),('GB','CBK','Cranbrook','Cranbrook','KEN'),('GB','CBO','Cranborne','Cranborne','DOR'),('GB','CBR','Colnbrook','Colnbrook','GTL'),('GB','CBS','Cambois','Cambois','NBL'),('GB','CBT','Campbeltown','Campbeltown','STD'),('GB','CBU','Cambuslang','Cambuslang','STD'),('GB','CBW','Camberwell','Camberwell','GTL'),('GB','CBY','Corby','Corby','NTH'),('GB','CCF','Cockfosters','Cockfosters','GTL'),('GB','CCG','Church Gresley','Church Gresley','DBY'),('GB','CCH','Christchurch','Christchurch','DOR'),('GB','CCK','Cleckheaton','Cleckheaton','WYK'),('GB','CCN','Chipping Campden','Chipping Campden','GLS'),('GB','CCO','Colden Common','Colden Common','HAM'),('GB','CCR','Catterick','Catterick','NYK'),('GB','CCT','Calcot','Calcot','WBK'),('GB','CCW','Churchstow','Churchstow','DEV'),('GB','CCY','Castlecary','Castlecary','STD'),('GB','CDA','Cheddar','Cheddar','SOM'),('GB','CDB','Cadeby','Cadeby','LEC'),('GB','CDD','Chadderton','Chadderton','GTM'),('GB','CDE','Chadwell St Mary','Chadwell St Mary','ESS'),('GB','CDF','Cardiff','Cardiff','SGM'),('GB','CDG','Cowbridge','Cowbridge','SGM'),('GB','CDH','Cheadle Hulme','Cheadle Hulme','GTM'),('GB','CDI','Crediton','Crediton','DVV'),('GB','CDL','Cheadle','Cheadle','STS'),('GB','CDR','Curdridge','Curdridge','HAM'),('GB','CDT','Caldicot','Caldicot','GNT'),('GB','CDW','Chadwell Heath','Chadwell Heath','GTL'),('GB','CDY','Cradley','Cradley','HWR'),('GB','CEA','Cleland','Cleland','STD'),('GB','CED','Coleford','Coleford','GLS'),('GB','CEE','Cheetham Hill','Cheetham Hill','GTM'),('GB','CEG','Chester','Chester','CHS'),('GB','CEM','Clayton-le-Moors','Clayton-le-Moors','LAN'),('GB','CEN','Colerne','Colerne','WIL'),('GB','CEO','Charlecote','Charlecote','WAR'),('GB','CER','Chesterton','Chesterton','STS'),('GB','CES','Chesterfield','Chesterfield','DBY'),('GB','CEY','Cowley','Cowley','OXF'),('GB','CFD','Chelmsford','Chelmsford','ESS'),('GB','CFE','Crieff','Crieff','PKN'),('GB','CFF','Carryduff','Carryduff','ARD'),('GB','CFG','Carrickfergus','Carrickfergus','CKF'),('GB','CFL','Cuckfield','Cuckfield','WSX'),('GB','CFO','Chandlers Ford','Chandlers Ford','HAM'),('GB','CGD','Claygate','Claygate','SRY'),('GB','CGF','Chingford','Chingford',''),('GB','CGH','Cranleigh','Cranleigh','SRY'),('GB','CGI','Crudgington','Crudgington','SHR'),('GB','CGN','Cogenhoe','Cogenhoe','NTH'),('GB','CGO','Cassington','Cassington','OXF'),('GB','CGR','Cononbridge','Cononbridge','HLD'),('GB','CGS','Chessington','Chessington','SRY'),('GB','CGV','Chalgrove','Chalgrove','OXF'),('GB','CGW','Cullingworth','Cullingworth','WYK'),('GB','CGY','Congresbury','Congresbury','NSM'),('GB','CHA','Cheadle','Cheadle','GTM'),('GB','CHB','Chobham','Chobham','SRY'),('GB','CHC','Checkendon','Checkendon','OXF'),('GB','CHD','Charleston','Charleston','TAY'),('GB','CHE','Mostyn','Mostyn','CWD'),('GB','CHF','Charlestown','Charlestown','CON'),('GB','CHG','Charing','Charing','KEN'),('GB','CHH','Cheshunt','Cheshunt','HRT'),('GB','CHI','Chigwell','Chigwell','ESS'),('GB','CHK','Chiswick','Chiswick','GTL'),('GB','CHL','Cholsey','Cholsey','OXF'),('GB','CHM','Chartham','Chartham','KEN'),('GB','CHN','Charlton','Charlton','GTL'),('GB','CHO','Chilton','Chilton','DUR'),('GB','CHP','Chipping Norton','Chipping Norton','OXF'),('GB','CHQ','Chale','Chale','IOW'),('GB','CHR','Chorley','Chorley','LAN'),('GB','CHS','Chasetown','Chasetown','STS'),('GB','CHT','Chepstow','Chepstow','GNT'),('GB','CHU','Chudleigh','Chudleigh',''),('GB','CHV','Chelveston','Chelveston','NTH'),('GB','CHW','Chorleywood','Chorleywood','HRT'),('GB','CHX','Chellaston/Derby','Chellaston/Derby','DBY'),('GB','CHZ','Chelford','Chelford','CHS'),('GB','CIK','Chirk','Chirk','CWD'),('GB','CIL','Chilmark','Chilmark','WIL'),('GB','CIN','Cinderford','Cinderford','GLS'),('GB','CIO','Conisbrough','Conisbrough','SYK'),('GB','CIR','Cirencester','Cirencester','GLS'),('GB','CIS','Coniston','Coniston','CMA'),('GB','CIW','Chiseldon','Chiseldon','WIL'),('GB','CJY','Chailey','Chailey','ESX'),('GB','CKE','Cricklade','Cricklade','WIL'),('GB','CKH','Cookham','Cookham','WNM'),('GB','CKL','Cookley','Cookley','HWR'),('GB','CKM','Cockermouth','Cockermouth','CMA'),('GB','CKP','Cockburnspath','Cockburnspath','SCB'),('GB','CLA','Clackmannan','Clackmannan','CLK'),('GB','CLC','Clay Cross','Clay Cross','DBY'),('GB','CLD','Cumbernauld','Cumbernauld','STD'),('GB','CLE','Cleator','Cleator','CMA'),('GB','CLF','Cliffe','Cliffe','KEN'),('GB','CLG','Cricklewood/London','Cricklewood/London','BEN'),('GB','CLH','Clydach','Clydach','WGM'),('GB','CLI','Clitheroe','Clitheroe','LAN'),('GB','CLK','Colwick','Colwick','NTT'),('GB','CLL','Coleshill','Coleshill','WAR'),('GB','CLN','Colne','Colne','LAN'),('GB','CLO','Colyton','Colyton','DEV'),('GB','CLP','Clapham','Clapham','GTL'),('GB','CLR','Coleraine','Coleraine','CLR'),('GB','CLS','Clacton-on-Sea','Clacton-on-Sea','ESS'),('GB','CLT','Cheltenham','Cheltenham','GLS'),('GB','CLW','Colwich','Colwich','STS'),('GB','CLY','Clydebank','Clydebank','STD'),('GB','CMA','Cefn-Mawr','Cefn-Mawr','WRX'),('GB','CMB','Camborne','Camborne','CON'),('GB','CME','Cheam','Cheam','SRY'),('GB','CMG','Cambridge','Cambridge','CAM'),('GB','CMH','Chulmleigh','Chulmleigh','DEV'),('GB','CML','Crumlin','Crumlin','GNT'),('GB','CMM','Cleobury Mortimer','Cleobury Mortimer','SHR'),('GB','CMO','St Columb Major','St Columb Major','CON'),('GB','CMR','Carmarthen','Carmarthen',''),('GB','CMT','Cramlington','Cramlington','NBL'),('GB','CMY','Cumnock','Cumnock','STD'),('GB','CNB','Canterbury','Canterbury','KEN'),('GB','CND','Chirnside','Chirnside','BOR'),('GB','CNE','Calne','Calne','WIL'),('GB','CNF','Carnforth','Carnforth','LAN'),('GB','CNG','Coningsby','Coningsby','LIN'),('GB','CNK','Cannock','Cannock','STS'),('GB','CNL','Cantley','Cantley','SYK'),('GB','CNN','Callington','Callington','CON'),('GB','CNR','Charnock Richard','Charnock Richard','LAN'),('GB','CNS','Carnoustie','Carnoustie','TAY'),('GB','CNT','Consett','Consett','DUR'),('GB','CNU','Craignure','Craignure','STD'),('GB','CNV','Caernarfon','Caernarfon','GWN'),('GB','CNW','Cornwell','Cornwell','OXF'),('GB','CNY','Chinley','Chinley','DBY'),('GB','CNZ','Cockenzie','Cockenzie','LTN'),('GB','COA','Coalville','Coalville','LEC'),('GB','COB','Cobham','Cobham','SRY'),('GB','COD','Coalisland','Coalisland','DGN'),('GB','COF','Coleford','Coleford','SOM'),('GB','COG','Coggeshall','Coggeshall','ESS'),('GB','COH','Cowdenbeath','Cowdenbeath','FIF'),('GB','COK','Crook','Crook','CMA'),('GB','COL','Colchester','Colchester','ESS'),('GB','CON','Congleton','Congleton','CHS'),('GB','COO','Cookstown','Cookstown','CKT'),('GB','COQ','Connah\'s Quay','Connah\'s Quay','CWD'),('GB','COR','Corpach','Corpach','HLD'),('GB','COS','Cosham','Cosham','HAM'),('GB','COT','Coatbridge','Coatbridge','STD'),('GB','COU','Coulport','Coulport','STD'),('GB','COV','Coverack','Coverack','CON'),('GB','COW','Cowes','Cowes','IOW'),('GB','COY','Coryton','Coryton','ESS'),('GB','CPH','Copthorne','Copthorne','SRY'),('GB','CPL','Chapel en le Frith','Chapel en le Frith','DBY'),('GB','CPN','Chippenham','Chippenham','WIL'),('GB','CPO','Compton','Compton','WBK'),('GB','CPS','Clipstone','Clipstone','NTT'),('GB','CPT','Clipstone','Clipstone','BDF'),('GB','CRB','Crosby','Crosby','MSY'),('GB','CRC','Church','Church','LAN'),('GB','CRD','Cornhill-on-Tweed','Cornhill-on-Tweed','NBL'),('GB','CRE','Crewe','Crewe','CHS'),('GB','CRF','Cranfield','Cranfield','BDF'),('GB','CRG','Craigavon','Craigavon','CGV'),('GB','CRH','Cradley Heath','Cradley Heath',''),('GB','CRI','Crick','Crick','NTH'),('GB','CRK','Crewkerne','Crewkerne','SOM'),('GB','CRL','Croft','Croft','LEC'),('GB','CRM','Croughton','Croughton','NTH'),('GB','CRN','Cromarty','Cromarty','HLD'),('GB','CRO','Croydon','Croydon','GTL'),('GB','CRP','Cropthorne','Cropthorne','HWR'),('GB','CRR','Cromer','Cromer','NFK'),('GB','CRS','Corsham','Corsham','WIL'),('GB','CRT','Carrington','Carrington','GTM'),('GB','CRU','Cranbourne','Cranbourne','BRC'),('GB','CRW','Caerwent','Caerwent','GNT'),('GB','CRY','Crayford','Crayford','GTL'),('GB','CSA','Colonsay','Colonsay',''),('GB','CSB','Castle Bromwich','Castle Bromwich','WMD'),('GB','CSD','Coulsdon','Coulsdon','GTL'),('GB','CSE','Chelsea/London','Chelsea/London','GTL'),('GB','CSG','Chalfont St Giles','Chalfont St Giles','BKM'),('GB','CSH','Chesham','Chesham','BKM'),('GB','CSK','Cross Keys','Cross Keys','GNT'),('GB','CSL','Chislehurst','Chislehurst','GTL'),('GB','CSM','Codford St Mary','Codford St Mary','WIL'),('GB','CSN','Garston','Garston',''),('GB','CSO','Chipping Sodbury','Chipping Sodbury','SGC'),('GB','CSP','Chalfont Saint Peter','Chalfont Saint Peter','BKM'),('GB','CSS','Cressing','Cressing','ESS'),('GB','CST','Chichester','Chichester','WSX'),('GB','CTA','Coltishall','Coltishall','NFK'),('GB','CTD','Castle Douglas','Castle Douglas','DGY'),('GB','CTE','Chester-le-Street','Chester-le-Street','DUR'),('GB','CTF','Castleford','Castleford','WYK'),('GB','CTH','Cleethorpes','Cleethorpes','HUM'),('GB','CTL','Catfield','Catfield','NFK'),('GB','CTM','Chatham','Chatham','KEN'),('GB','CTN','Castletown','Castletown','HLD'),('GB','CTO','Carshalton','Carshalton','GTL'),('GB','CTR','Caterham','Caterham','SRY'),('GB','CTT','Cotterstock','Cotterstock','NTH'),('GB','CTW','Cheddleton','Cheddleton','STS'),('GB','CUD','Cuddington','Cuddington','BKM'),('GB','CUL','Cullompton','Cullompton',''),('GB','CUP','Cupar','Cupar','FIF'),('GB','CUR','Curlew','Curlew',''),('GB','CUT','Cutnall Green','Cutnall Green','HWR'),('GB','CVF','Caversfield','Caversfield','OXF'),('GB','CVG','Chevington','Chevington','SFK'),('GB','CVT','Coventry','Coventry','WMD'),('GB','CVY','Cheveley','Cheveley','CAM'),('GB','CWA','Conwy (Conway)','Conwy (Conway)','GWN'),('GB','CWB','Crowborough','Crowborough','ESX'),('GB','CWD','Cowden','Cowden','KEN'),('GB','CWE','Chilwell','Chilwell','NTT'),('GB','CWM','Cwmbran','Cwmbran','GNT'),('GB','CWO','Cousley Wood','Cousley Wood','ESX'),('GB','CWR','Chelworth','Chelworth','WIL'),('GB','CWS','Cawston','Cawston','NFK'),('GB','CWT','Crowthorne','Crowthorne','BRC'),('GB','CWX','Castlewellan','Castlewellan','DOW'),('GB','CWY','Crawley','Crawley','WSX'),('GB','CXB','Coxbench','Coxbench','DBY'),('GB','CXM','Cromford','Cromford','DBY'),('GB','CXT','Cottingham','Cottingham',''),('GB','CXY','Cosby','Cosby','LEC'),('GB','CYB','Cullybackey','Cullybackey','ANT'),('GB','CYH','Cherry Hinton','Cherry Hinton','CAM'),('GB','CYK','Corley','Corley',''),('GB','CYL','Crays Hill','Crays Hill','ESS'),('GB','CYM','Clyst St Mary','Clyst St Mary','DVV'),('GB','CYN','Cairnryan','Cairnryan','DGY'),('GB','CYO','Clayton','Clayton','LAN'),('GB','CYP','Clydeport','Clydeport','STD'),('GB','CYS','Caerwys','Caerwys','CWD'),('GB','CYW','Cynwyd','Cynwyd','DEN'),('GB','CYY','Colwyn Bay','Colwyn Bay','CWD'),('GB','CZT','Chard','Chard','SOM'),('GB','DAG','Dagenham','Dagenham','GTL'),('GB','DAL','Dalton in Furness','Dalton in Furness','CMA'),('GB','DAT','Datchet','Datchet','WNM'),('GB','DBD','Debden','Debden','ESS'),('GB','DBI','Denbigh','Denbigh','CWD'),('GB','DBN','Debenham','Debenham','SFK'),('GB','DBP','Dibden Purlieu','Dibden Purlieu','HAM'),('GB','DBR','Dunbar','Dunbar','ELN'),('GB','DBT','Dumbarton','Dumbarton','STD'),('GB','DCP','Drumchapel','Drumchapel','STD'),('GB','DDD','Dundonald','Dundonald','STD'),('GB','DDG','Doveridge','Doveridge','DBY'),('GB','DDH','Danderhall','Danderhall','MLN'),('GB','DDL','Dudley','Dudley','WMD'),('GB','DDM','Dundrum','Dundrum','DOW'),('GB','DDN','Dundrennan','Dundrennan','DGY'),('GB','DDT','Durward Dauntless','Durward Dauntless',''),('GB','DEL','Delph','Delph','GTM'),('GB','DEN','Denton','Denton','TAM'),('GB','DEP','Deptford','Deptford','GTL'),('GB','DER','Dereham','Dereham','NFK'),('GB','DES','Desford','Desford','LEC'),('GB','DET','Denton','Denton','ESX'),('GB','DEX','Deal','Deal','KEN'),('GB','DFD','Dartford','Dartford','KEN'),('GB','DFR','Dunfermline','Dunfermline','FIF'),('GB','DGL','Douglas','Douglas','STD'),('GB','DGN','Dungannon','Dungannon','DGN'),('GB','DGO','Donaghmore','Donaghmore',''),('GB','DGS','Douglas','Douglas','IOM'),('GB','DGT','Dunnington','Dunnington','NYK'),('GB','DGU','Dunning','Dunning','SCT'),('GB','DHD','Donaghadee','Donaghadee','DOW'),('GB','DHG','Deanshanger','Deanshanger','NTH'),('GB','DHM','Denham','Denham','BKM'),('GB','DHR','Dorchester','Dorchester','DOR'),('GB','DHT','Dunston Heath','Dunston Heath','STS'),('GB','DID','Didcot','Didcot','OXF'),('GB','DIN','Dingle','Dingle','MSY'),('GB','DIO','Dinton','Dinton','WIL'),('GB','DIS','Diss','Diss','NFK'),('GB','DIT','Ditchingham','Ditchingham','NFK'),('GB','DKG','Dorking','Dorking','SRY'),('GB','DKW','Dunkeswell','Dunkeswell','DEV'),('GB','DLG','Dolgellau','Dolgellau','GWN'),('GB','DLK','Dalkeith','Dalkeith','LTN'),('GB','DLL','Dullingham','Dullingham','CAM'),('GB','DLS','Dalston','Dalston','GTL'),('GB','DLX','Dalry','Dalry','STD'),('GB','DMC','Dymock','Dymock','GLS'),('GB','DMO','Dromore','Dromore','BNB'),('GB','DMR','Dalmuir','Dalmuir','STD'),('GB','DMT','Dechmont','Dechmont','WLN'),('GB','DNB','Danbury','Danbury','ESS'),('GB','DND','Riverside Park Apt/Dundee','Riverside Park Apt/Dundee','TAY'),('GB','DNG','Donnington','Donnington','SHR'),('GB','DNH','Denholme','Denholme','WYK'),('GB','DNQ','Dean Quarry','Dean Quarry','CON'),('GB','DNR','Dunsford','Dunsford',''),('GB','DNS','Durness','Durness','HLD'),('GB','DNT','Doonfoot','Doonfoot','STD'),('GB','DNU','Dunoon','Dunoon','STD'),('GB','DNV','Denver','Denver','NFK'),('GB','DNY','Denny','Denny','FAL'),('GB','DOC','Dornoch','Dornoch','HLD'),('GB','DOL','Dolgarrog','Dolgarrog','CWY'),('GB','DON','Doncaster','Doncaster','SYK'),('GB','DOT','Dorrington','Dorrington','SHR'),('GB','DOU','Doune','Doune',''),('GB','DOW','Downham Market','Downham Market','NFK'),('GB','DPC','Deepcut','Deepcut','SRY'),('GB','DQF','Dukinfield','Dukinfield','GTM'),('GB','DRF','Driffield','Driffield','HUM'),('GB','DRG','Drighlington','Drighlington','WYK'),('GB','DRH','Durham','Durham','DUR'),('GB','DRL','Darlington','Darlington','DUR'),('GB','DRM','Drummore','Drummore','DGY'),('GB','DRN','Dronfield','Dronfield','DBY'),('GB','DRO','Droitwich','Droitwich','HWR'),('GB','DRR','Durrington','Durrington','WSX'),('GB','DRS','Darlaston','Darlaston','WLL'),('GB','DRY','Droylsden','Droylsden','GTM'),('GB','DSA','Dersingham','Dersingham','NFK'),('GB','DSB','Desborough','Desborough','NTH'),('GB','DSE','Deeside','Deeside','CWD'),('GB','DSL','Disley','Disley','CHS'),('GB','DST','Duston','Duston','NTH'),('GB','DSX','Hibaldstow','Hibaldstow','HUM'),('GB','DTE','Dunstable','Dunstable','BDF'),('GB','DTG','Dartington','Dartington',''),('GB','DTH','Ditchling','Ditchling','ESX'),('GB','DTM','Dartmouth','Dartmouth',''),('GB','DTN','Dunston','Dunston','TWR'),('GB','DTO','Darton','Darton','SYK'),('GB','DTT','Ditton','Ditton','KEN'),('GB','DUB','Dunblane','Dunblane','STG'),('GB','DUD','Dundonald','Dundonald','BFS'),('GB','DUF','Duffield','Duffield','DBY'),('GB','DUL','Dundonald','Dundonald','CSR'),('GB','DUM','Dumfries','Dumfries','DGY'),('GB','DUN','Dundee','Dundee','TAY'),('GB','DUR','Dursley','Dursley','GLS'),('GB','DUS','Duns','Duns','SCB'),('GB','DUY','Dunmurry','Dunmurry','LSB'),('GB','DVP','Devonport','Devonport',''),('GB','DVR','Dover','Dover','KEN'),('GB','DVY','Daventry','Daventry','NTH'),('GB','DVZ','Devizes','Devizes','WIL'),('GB','DWD','Downend','Downend','IOW'),('GB','DWK','Downpatrick','Downpatrick','DOW'),('GB','DWL','Bradwell Waterside','Bradwell Waterside','ESS'),('GB','DWN','Darwen','Darwen','LAN'),('GB','DWY','Dewsbury','Dewsbury','WYK'),('GB','DXF','Duxford','Duxford','CAM'),('GB','DXO','Droxford','Droxford','HAM'),('GB','DXY','Derby','Derby','DBY'),('GB','DYB','Dalgety Bay','Dalgety Bay','FIF'),('GB','DYC','Dyce','Dyce','GMP'),('GB','DYL','Derrylin','Derrylin','FER'),('GB','EAD','East Dereham','East Dereham','NFK'),('GB','EAL','Eastleigh','Eastleigh','DVV'),('GB','EAM','Eastham','Eastham','MSY'),('GB','EAN','Easton','Easton','CAM'),('GB','EAO','Easton','Easton','LIN'),('GB','EAR','Earls Barton','Earls Barton','NTH'),('GB','EAS','East Malling','East Malling','SRY'),('GB','EAT','Eastleigh','Eastleigh','HAM'),('GB','EAW','Eastburn','Eastburn','WYK'),('GB','EAY','Eastry','Eastry','KEN'),('GB','EBB','Ebbw Vale','Ebbw Vale','GNT'),('GB','EBF','East Bedfont/London','East Bedfont/London','GTL'),('GB','EBO','Eastbourne','Eastbourne','ESX'),('GB','ECC','Ecclesfield','Ecclesfield','SYK'),('GB','ECO','Earls Colne','Earls Colne','ESS'),('GB','ECS','Eccles','Eccles','GTM'),('GB','EDB','Enderby','Enderby','LEC'),('GB','EDE','Edenbridge','Edenbridge','KEN'),('GB','EDG','Edgware','Edgware','GTL'),('GB','EDI','Edinburgh','Edinburgh','LTN'),('GB','EDM','Edmonton','Edmonton','GTL'),('GB','EDW','Edwinstowe','Edwinstowe','NTT'),('GB','EDY','Eardisley','Eardisley','HEF'),('GB','EDZ','Edzell','Edzell','TAY'),('GB','EFD','Eastfield','Eastfield','NYK'),('GB','EFO','Sefton','Sefton','MSY'),('GB','EGA','Effingham','Effingham','SRY'),('GB','EGD','East Grinstead','East Grinstead','WSX'),('GB','EGG','Egglescliffe','Egglescliffe','CLV'),('GB','EGH','Egham','Egham','SRY'),('GB','EGL','Eaglescliffe','Eaglescliffe','CLV'),('GB','EGY','Easton Grey','Easton Grey','WIL'),('GB','EHA','East Harling','East Harling','NFK'),('GB','EIG','Easton-in-Gordano','Easton-in-Gordano','NSM'),('GB','EKB','East Kilbride','East Kilbride','STD'),('GB','EKI','Erskine','Erskine','STD'),('GB','ELE','Elsenham','Elsenham','ESS'),('GB','ELG','Elgin','Elgin','GMP'),('GB','ELH','Elmesthorpe','Elmesthorpe','LEC'),('GB','ELI','Elie','Elie','FIF'),('GB','ELK','Elkesley','Elkesley','NTT'),('GB','ELL','Ellesmere Port','Ellesmere Port','CHS'),('GB','ELM','Ellesmere','Ellesmere','SHR'),('GB','ELN','Ealing','Ealing','GTL'),('GB','ELO','Ellistown','Ellistown','LEC'),('GB','ELT','Ellington','Ellington','CAM'),('GB','ELV','Elvington','Elvington','NYK'),('GB','ELY','Ely','Ely','CAM'),('GB','EMA','East Midlands Apt','East Midlands Apt','LEC'),('GB','EMB','Emberton','Emberton','BKM'),('GB','EMO','East Molesey','East Molesey','SRY'),('GB','EMP','Elm Park','Elm Park','GTL'),('GB','EMS','Emsworth','Emsworth','HAM'),('GB','END','Elland','Elland','WYK'),('GB','ENF','Enfield','Enfield','GTL'),('GB','ENG','Englefield Green','Englefield Green','SRY'),('GB','ENK','Enniskillen','Enniskillen','FER'),('GB','ENS','Eynsford','Eynsford','KEN'),('GB','ENW','Easingwold','Easingwold','NYK'),('GB','EOI','Eday','Eday','ORK'),('GB','EOL','Ellon','Ellon','ABD'),('GB','EON','Seaton','Seaton','DEV'),('GB','EPN','East Pennard','East Pennard','SOM'),('GB','EPP','Epping','Epping','ESS'),('GB','EPS','Epsom','Epsom','SRY'),('GB','ERB','Earby','Earby','LAN'),('GB','ERD','Erdington','Erdington','WMD'),('GB','ERF','East Retford','East Retford','NTT'),('GB','ERH','Earith','Earith','CAM'),('GB','ERI','Erith','Erith','GTL'),('GB','ERR','Berriedale','Berriedale','HLD'),('GB','ESA','Eastergate','Eastergate','WSX'),('GB','ESB','East Bridgford','East Bridgford','NTT'),('GB','ESC','Eaton Socon','Eaton Socon','BDF'),('GB','ESH','Shoreham-by-Sea','Shoreham-by-Sea','WSX'),('GB','ESL','Eastcote','Eastcote','GTL'),('GB','ESO','Enstone','Enstone','OXF'),('GB','ESR','Esher','Esher','SRY'),('GB','ESW','East Wellow','East Wellow','HAM'),('GB','ESY','East Horsley','East Horsley','SRY'),('GB','ETA','Etchingham','Etchingham','ESX'),('GB','ETB','Eaton Bishop','Eaton Bishop','HWR'),('GB','ETN','Eton','Eton','WNM'),('GB','ETO','Eaton','Eaton','CHS'),('GB','ETP','East Peckham','East Peckham','KEN'),('GB','ETR','Elstree','Elstree','HRT'),('GB','ETY','Betley','Betley','STS'),('GB','EVE','Evesham','Evesham','HWR'),('GB','EVY','Eversley','Eversley','BKM'),('GB','EWE','Ewell','Ewell','SRY'),('GB','EWH','Elworth','Elworth','CHS'),('GB','EWM','Ewelme','Ewelme','OXF'),('GB','EWO','Eastwood','Eastwood','ESS'),('GB','EXE','Exeter','Exeter',''),('GB','EXM','Exmouth','Exmouth',''),('GB','EXN','Exning','Exning','CAM'),('GB','EYA','Eyam','Eyam','DBY'),('GB','EYE','Eye','Eye','SFK'),('GB','EYH','Eynsham','Eynsham','OXF'),('GB','EYM','Eyemouth','Eyemouth','BOR'),('GB','FAL','Falmouth','Falmouth','CON'),('GB','FAN','Faringdon','Faringdon','OXF'),('GB','FAR','Farnham','Farnham','SRY'),('GB','FAS','Faslane','Faslane','STD'),('GB','FAV','Faversham','Faversham','KEN'),('GB','FAW','Fawley','Fawley','HAM'),('GB','FBG','Felbridge','Felbridge','SRY'),('GB','FBN','Fulbourn','Fulbourn','CAM'),('GB','FBO','Farnborough','Farnborough','HAM'),('GB','FBU','Fishbourne','Fishbourne','IOW'),('GB','FBY','Flimby','Flimby','CMA'),('GB','FCB','Fochabers','Fochabers','GMP'),('GB','FCT','Frampton Cotterell','Frampton Cotterell','SGC'),('GB','FDH','Fordhouses','Fordhouses','WMD'),('GB','FDK','Fosdyke','Fosdyke','LIN'),('GB','FDM','Fordham','Fordham','CAM'),('GB','FDN','Ferndown','Ferndown','DOR'),('GB','FDR','Farnham','Farnham','DOR'),('GB','FDS','Frodsham','Frodsham','CHS'),('GB','FDU','Fordoun','Fordoun','GMP'),('GB','FEA','Fetlar','Fetlar',''),('GB','FEB','Ferrybridge','Ferrybridge','WKF'),('GB','FEE','Fairlie','Fairlie','STD'),('GB','FEL','Feltwell','Feltwell','NFK'),('GB','FEM','Feltham','Feltham','GTL'),('GB','FEN','Fenton','Fenton','STS'),('GB','FER','Fersfield','Fersfield','NFK'),('GB','FET','Fleet','Fleet','HAM'),('GB','FFD','Falfield','Falfield','SGC'),('GB','FFO','Fairford','Fairford','GLS'),('GB','FGB','Fordingbridge','Fordingbridge','HAM'),('GB','FGH','Froghall','Froghall','STS'),('GB','FHA','Fernham','Fernham','OXF'),('GB','FHM','Fareham','Fareham','HAM'),('GB','FIE','Fair Isle','Fair Isle','ZET'),('GB','FIN','Findhorn','Findhorn','GMP'),('GB','FIS','Fishguard','Fishguard','DFD'),('GB','FKK','Falkirk','Falkirk','FAL'),('GB','FKM','Fakenham','Fakenham','NFK'),('GB','FKY','Fleckney','Fleckney','SYK'),('GB','FLA','Flackwell Heath','Flackwell Heath','BKM'),('GB','FLB','Filby','Filby','NFK'),('GB','FLC','Flitwick','Flitwick','BDF'),('GB','FLE','Fleetwood','Fleetwood','LAN'),('GB','FLF','Fulford','Fulford','NYK'),('GB','FLH','Flotta','Flotta','ORK'),('GB','FLI','Flint','Flint','CWD'),('GB','FLL','Felling','Felling','TWR'),('GB','FLM','Fulham','Fulham','GTL'),('GB','FLR','Flore','Flore','NTH'),('GB','FLS','Failsworth','Failsworth','GTM'),('GB','FLW','Flixborough','Flixborough','HUM'),('GB','FLX','Flixton','Flixton','GTM'),('GB','FLY','Filey','Filey','NYK'),('GB','FME','Frome','Frome','SOM'),('GB','FNC','Finchampstead','Finchampstead','WOK'),('GB','FND','Finedon','Finedon','NTH'),('GB','FNT','Finnart','Finnart','TAY'),('GB','FNU','Fernhurst','Fernhurst','WSX'),('GB','FNV','Foinaven','Foinaven',''),('GB','FNW','Farnworth','Farnworth','GTM'),('GB','FOA','Foula','Foula',''),('GB','FOD','Ford','Ford','WSX'),('GB','FOF','Forfar','Forfar','TAY'),('GB','FOH','Ford','Ford','STS'),('GB','FOK','Four Oaks','Four Oaks','ESX'),('GB','FOL','Folkestone','Folkestone','KEN'),('GB','FOR','Forth','Forth','LTN'),('GB','FOW','Frisby on the Wreake','Frisby on the Wreake','LEC'),('GB','FOY','Fowey','Fowey','CON'),('GB','FRA','Framlingham','Framlingham','SFK'),('GB','FRB','Fraserburgh','Fraserburgh','GMP'),('GB','FRC','Farnham Common','Farnham Common','BKM'),('GB','FRD','Ferndale','Ferndale','MGM'),('GB','FRG','Forest Gate','Forest Gate','GTL'),('GB','FRH','Fingringhoe','Fingringhoe','ESS'),('GB','FRL','Fritchley','Fritchley','DBY'),('GB','FRM','Formby','Formby','MSY'),('GB','FRN','Frenchay','Frenchay','SGC'),('GB','FRR','Farringdon','Farringdon',''),('GB','FRS','Forres','Forres','GMP'),('GB','FRT','Frant','Frant','ESX'),('GB','FRY','Ferryhill','Ferryhill','DUR'),('GB','FSH','Felmersham','Felmersham','BDF'),('GB','FST','Full Sutton','Full Sutton','ERY'),('GB','FTC','Fetcham','Fetcham','SRY'),('GB','FTF','Fforest-Fach','Fforest-Fach','WGM'),('GB','FTH','Featherstone','Featherstone','WYK'),('GB','FTI','The Forties','The Forties','DBY'),('GB','FTN','Farington','Farington','LAN'),('GB','FTO','Fourstones','Fourstones','NBL'),('GB','FTU','Fetterangus','Fetterangus','ABD'),('GB','FUL','Fulmer','Fulmer','BKM'),('GB','FWK','Fawham Green','Fawham Green','KEN'),('GB','FWL','Fontwell','Fontwell','WSX'),('GB','FWM','Fort William','Fort William','HLD'),('GB','FXF','Foxton','Foxton','LEC'),('GB','FXT','Felixstowe','Felixstowe','SFK'),('GB','FXY','Flaxby','Flaxby','NYK'),('GB','FZO','Filton','Filton',''),('GB','GAE','Graemsay','Graemsay','ORK'),('GB','GAG','Gamlingay','Gamlingay','CAM'),('GB','GAH','Galashiels','Galashiels','BOR'),('GB','GAI','Gainsborough','Gainsborough','LIN'),('GB','GAL','Great Alne','Great Alne','WAR'),('GB','GAM','Great Amwell','Great Amwell','HRT'),('GB','GAT','Gateshead','Gateshead','TWR'),('GB','GAW','Gaerwen','Gaerwen','GWN'),('GB','GAY','Gaydon','Gaydon','WAR'),('GB','GBD','Gilberdyke','Gilberdyke','ERY'),('GB','GBG','Great Broughton','Great Broughton','NYK'),('GB','GBH','Grandborough','Grandborough','WAR'),('GB','GBK','Great Bookham','Great Bookham','SRY'),('GB','GBN','Gisburn','Gisburn','LAN'),('GB','GBO','Boughton','Boughton','NTT'),('GB','GBT','Great Barton','Great Barton','SFK'),('GB','GBU','Great Budworth','Great Budworth','CHS'),('GB','GBV','Glenbervie','Glenbervie','ABD'),('GB','GBY','Great Bentley','Great Bentley','ESS'),('GB','GCH','Great Chishill','Great Chishill','CAM'),('GB','GCI','Guernsey','Guernsey','GSY'),('GB','GDB','Guardbridge','Guardbridge','FIF'),('GB','GDD','Guildford','Guildford','SRY'),('GB','GDG','Golders Green','Golders Green','GTL'),('GB','GDM','Godmanchester','Godmanchester','CAM'),('GB','GDN','Gardenstown','Gardenstown','GMP'),('GB','GDP','Gidea Park','Gidea Park','GTL'),('GB','GDR','Gildersome','Gildersome','WYK'),('GB','GDS','Godstone','Godstone','SRY'),('GB','GET','Great Easton','Great Easton','ESS'),('GB','GFD','Greenfield','Greenfield','BDF'),('GB','GFI','Greenfield','Greenfield','FLN'),('GB','GFO','Goff\'s Oak','Goff\'s Oak','HRT'),('GB','GFR','Greenford','Greenford','GTL'),('GB','GFT','Gosforth','Gosforth','CMA'),('GB','GGI','Garrigill','Garrigill','CMA'),('GB','GGV','Gargrave','Gargrave','NYK'),('GB','GHI','Greenhithe','Greenhithe','KEN'),('GB','GHN','Guyhirn','Guyhirn','CAM'),('GB','GHW','Great Haywood','Great Haywood','STS'),('GB','GHY','Great Haseley','Great Haseley','OXF'),('GB','GIL','Gillingham','Gillingham','KEN'),('GB','GIR','Girvan','Girvan','STD'),('GB','GIS','Garlieston','Garlieston','DGY'),('GB','GLD','Glasson Dock','Glasson Dock','LAN'),('GB','GLE','Glemsford','Glemsford','SFK'),('GB','GLF','Glenfield','Glenfield','LEC'),('GB','GLL','Gillingham','Gillingham','DOR'),('GB','GLN','Glanton','Glanton','NBL'),('GB','GLO','Gloucester','Gloucester','GLS'),('GB','GLS','Glenrothes','Glenrothes','FIF'),('GB','GLW','Glasgow','Glasgow','STD'),('GB','GML','Great Malvern','Great Malvern','HWR'),('GB','GMS','Gomersal','Gomersal','WYK'),('GB','GMT','Gamston','Gamston','NTT'),('GB','GNG','Goring','Goring','OXF'),('GB','GNW','Greenwich','Greenwich','GTL'),('GB','GOD','Godalming','Godalming','SRY'),('GB','GOL','Golborne','Golborne','GTM'),('GB','GOO','Goole','Goole','HUM'),('GB','GOQ','Gorseinon','Gorseinon','WGM'),('GB','GOS','Gosport','Gosport','HAM'),('GB','GOU','Goudhurst','Goudhurst','KEN'),('GB','GOW','Gowerton','Gowerton','SWA'),('GB','GRA','Gransden','Gransden','CAM'),('GB','GRB','Great Blakenham','Great Blakenham','SFK'),('GB','GRC','Gerrards Cross','Gerrards Cross','BKM'),('GB','GRD','Great Dunmow','Great Dunmow','ESS'),('GB','GRG','Grangemouth','Grangemouth','FAL'),('GB','GRH','Great Harwood','Great Harwood','LAN'),('GB','GRK','Greenock','Greenock','STD'),('GB','GRL','Gorleston-on-Sea','Gorleston-on-Sea','NFK'),('GB','GRM','Great Missenden','Great Missenden','BKM'),('GB','GRN','Granton','Granton','LTN'),('GB','GRP','Gristhorpe','Gristhorpe','NYK'),('GB','GRR','Great Ryburgh','Great Ryburgh','NFK'),('GB','GRS','Great Sankey','Great Sankey','CHS'),('GB','GRT','Gretna','Gretna','DGY'),('GB','GRV','Garvald','Garvald','LTN'),('GB','GRW','Grove Wharves','Grove Wharves','HUM'),('GB','GRX','Great Gransden','Great Gransden','CAM'),('GB','GRY','Glastonbury','Glastonbury','SOM'),('GB','GRZ','Great Shelford','Great Shelford','CAM'),('GB','GSA','Glensanda','Glensanda','HLD'),('GB','GSB','Guisborough','Guisborough','CLV'),('GB','GSF','Gosfield','Gosfield','ESS'),('GB','GSN','Galston','Galston','STD'),('GB','GSP','Glossop','Glossop','DBY'),('GB','GST','Gastard','Gastard','WIL'),('GB','GSU','Great Sutton','Great Sutton','CHS'),('GB','GSY','Grimsby','Grimsby','HUM'),('GB','GTA','Garstang','Garstang','LAN'),('GB','GTC','Gartcosh','Gartcosh','STD'),('GB','GTF','Whitefield','Whitefield','GTM'),('GB','GTH','Greatham','Greatham','HAM'),('GB','GTL','Greetland','Greetland','WYK'),('GB','GTM','Grantham','Grantham','LIN'),('GB','GTN','Garston','Garston','MSY'),('GB','GTO','Great Torrington','Great Torrington',''),('GB','GTR','Great Brickhill','Great Brickhill','BKM'),('GB','GTS','Great Snoring','Great Snoring','NFK'),('GB','GTT','Great Tey','Great Tey','ESS'),('GB','GTY','Great Yarmouth','Great Yarmouth','NFK'),('GB','GUI','Guiseley','Guiseley','WYK'),('GB','GUM','Gunnislake','Gunnislake','CON'),('GB','GUN','Gunn','Gunn','DVV'),('GB','GUR','Gourock','Gourock','STD'),('GB','GUW','Gunness Wharf','Gunness Wharf','HUM'),('GB','GVO','Goveton','Goveton','DEV'),('GB','GVS','Gravesend','Gravesend','KEN'),('GB','GWN','Grangetown','Grangetown','CLV'),('GB','GWY','Great Wyrley','Great Wyrley','STS'),('GB','GYS','Grays','Grays','ESS'),('GB','GZT','Grassington','Grassington','NYK'),('GB','GZY','Grazeley','Grazeley','WOK'),('GB','HAB','Halbeath','Halbeath','FIF'),('GB','HAD','Haddington','Haddington','LTN'),('GB','HAE','Hale','Hale','CHS'),('GB','HAF','Hereford','Hereford','HWR'),('GB','HAG','Halton Gill','Halton Gill','NYK'),('GB','HAH','Haywards Heath','Haywards Heath','WSX'),('GB','HAI','Hailsham','Hailsham','ESX'),('GB','HAK','Harle Syke','Harle Syke','LAN'),('GB','HAL','Haverhill','Haverhill','SFK'),('GB','HAM','Hamble','Hamble','HAM'),('GB','HAN','Hatton','Hatton','DBY'),('GB','HAO','Hanworth','Hanworth','HNS'),('GB','HAP','Hapton','Hapton','LAN'),('GB','HAR','Hardley','Hardley','HAM'),('GB','HAS','Harleston','Harleston','NFK'),('GB','HAT','Hatfield','Hatfield','HRT'),('GB','HAV','Havant','Havant','HAM'),('GB','HAY','Hayle','Hayle','CON'),('GB','HAZ','Hartford','Hartford','CHS'),('GB','HBC','Husborne Crawley','Husborne Crawley','BDF'); +INSERT INTO `ISO_LOCATION` VALUES ('GB','HBE','High Bentham','High Bentham','NYK'),('GB','HBG','Hebden Bridge','Hebden Bridge','WYK'),('GB','HBH','Hillsborough','Hillsborough','LSB'),('GB','HBN','Hurstburne Tarrant','Hurstburne Tarrant','HAM'),('GB','HBO','Honeybourne','Honeybourne','WOR'),('GB','HBP','Hampton Bishop','Hampton Bishop','HRT'),('GB','HBR','Hambridge','Hambridge','SOM'),('GB','HBT','Hambleton','Hambleton','LAN'),('GB','HBX','Holbury','Holbury','HAM'),('GB','HBY','Hellaby','Hellaby','SYK'),('GB','HCE','Hucclecote','Hucclecote','GLS'),('GB','HCH','Holme Chapel','Holme Chapel','LAN'),('GB','HCK','Hackney','Hackney','GTL'),('GB','HCN','Hitchin','Hitchin','HRT'),('GB','HCY','Hockley','Hockley','ESS'),('GB','HDC','Hardwick','Hardwick','CAM'),('GB','HDD','Howdendyke','Howdendyke','HUM'),('GB','HDF','Huddersfield','Huddersfield','WYK'),('GB','HDG','Headington','Headington','OXF'),('GB','HDH','Haddenham','Haddenham','CAM'),('GB','HDK','Haydock','Haydock','MSY'),('GB','HDL','Hadleigh','Hadleigh','SFK'),('GB','HDN','Haslingden','Haslingden','LAN'),('GB','HDO','Hendon','Hendon','GTL'),('GB','HDT','Horndon on the Hill','Horndon on the Hill','ESS'),('GB','HDW','Halton West','Halton West','NYK'),('GB','HDY','Hadley','Hadley','HWR'),('GB','HEA','Heacham','Heacham','NFK'),('GB','HEB','Hebburn','Hebburn','TWR'),('GB','HED','Headcorn','Headcorn','KEN'),('GB','HEF','Hertford','Hertford','HRT'),('GB','HEG','Hindley Green','Hindley Green','GTM'),('GB','HEH','Hemsworth','Hemsworth','WYK'),('GB','HEI','Heighington','Heighington','DUR'),('GB','HEK','Heckmondwike','Heckmondwike','WYK'),('GB','HEL','Halwell','Halwell','DEV'),('GB','HEM','Hempstead','Hempstead','NFK'),('GB','HEN','Henley-on-Thames','Henley-on-Thames','OXF'),('GB','HEO','Headley Down','Headley Down','HAM'),('GB','HER','Hurstpierpoint','Hurstpierpoint','WSX'),('GB','HES','Heston','Heston','GTL'),('GB','HEV','Hove','Hove','ESX'),('GB','HEW','Henlow','Henlow','BDF'),('GB','HEY','Chertsey','Chertsey','SRY'),('GB','HFD','Haslingfield','Haslingfield','CAM'),('GB','HFO','Handforth','Handforth','CHS'),('GB','HFR','Halliford','Halliford','SRY'),('GB','HFX','Halifax','Halifax','WYK'),('GB','HGA','High Ackworth','High Ackworth','WYK'),('GB','HGD','Hastingwood','Hastingwood','ESS'),('GB','HGE','Hedge End','Hedge End','HAM'),('GB','HGF','Higham Ferrers','Higham Ferrers','NTH'),('GB','HGG','Highgate/London','Highgate/London','GTL'),('GB','HGH','Higham','Higham','KEN'),('GB','HGN','Hurst Green','Hurst Green','ESX'),('GB','HGO','Highworth','Highworth','SWD'),('GB','HGP','Hogsthorpe','Hogsthorpe','LIN'),('GB','HGR','Houghton Regis','Houghton Regis','BDF'),('GB','HGS','Horningsea','Horningsea','CAM'),('GB','HGT','Harlington','Harlington','GTL'),('GB','HGW','Hightown','Hightown','MSY'),('GB','HGX','Hougham','Hougham','LIN'),('GB','HHA','Waltham Abbey','Waltham Abbey','ESS'),('GB','HHE','Hemel Hempstead','Hemel Hempstead','HRT'),('GB','HHF','Heathfield','Heathfield','SOM'),('GB','HHH','Heathhall','Heathhall','DGY'),('GB','HHI','Harold Hill','Harold Hill','GTL'),('GB','HHL','Harrow on the Hill','Harrow on the Hill','GTL'),('GB','HHN','Holehaven','Holehaven',''),('GB','HHO','Hawthorn','Hawthorn','WIL'),('GB','HID','Hillend','Hillend','FIF'),('GB','HIG','Highbridge','Highbridge','SOM'),('GB','HIH','Horwich','Horwich','GTM'),('GB','HIL','Hinckley','Hinckley','LEC'),('GB','HIN','Honiton','Honiton',''),('GB','HIS','Histon','Histon','CAM'),('GB','HIY','Hindley','Hindley','GTM'),('GB','HKB','Hackbridge','Hackbridge','STN'),('GB','HKI','Halkirk','Halkirk','HLD'),('GB','HKL','Hucknall','Hucknall','NTT'),('GB','HKO','Hackforth','Hackforth','NYK'),('GB','HKY','Hockley','Hockley','BIR'),('GB','HLB','Hillsborough','Hillsborough','SYK'),('GB','HLC','Holmes Chapel','Holmes Chapel','CHS'),('GB','HLD','Harold Wood','Harold Wood','GTL'),('GB','HLE','Hale Bank','Hale Bank','CHS'),('GB','HLF','Hurlford','Hurlford','STD'),('GB','HLG','Halling','Halling','KEN'),('GB','HLI','Hollingworth','Hollingworth','GTM'),('GB','HLL','Hillingdon','Hillingdon','GTL'),('GB','HLM','Helmdon','Helmdon','NTH'),('GB','HLN','Helensburgh','Helensburgh','STD'),('GB','HLO','Holy Loch','Holy Loch','STD'),('GB','HLR','Holmfirth','Holmfirth','WYK'),('GB','HLS','Houghton le Spring','Houghton le Spring','TWR'),('GB','HLT','Holt','Holt','NFK'),('GB','HLU','Hunslet/Leeds','Hunslet/Leeds','LDS'),('GB','HLV','Hallen','Hallen','SGC'),('GB','HLW','Halewood','Halewood','MSY'),('GB','HLY','Holyhead','Holyhead','GWN'),('GB','HMB','Hambleden','Hambleden','BKM'),('GB','HMD','Holmewood','Holmewood','DBY'),('GB','HMI','Hayes','Hayes','GTL'),('GB','HMM','Hammersmith','Hammersmith','GTL'),('GB','HMO','Hamworthy','Hamworthy','DOR'),('GB','HMP','Hampton','Hampton','GTL'),('GB','HMR','Humber','Humber',''),('GB','HMS','Hampstead','Hampstead','GTL'),('GB','HMT','Hamilton','Hamilton','STD'),('GB','HMW','Harmondsworth','Harmondsworth','GTL'),('GB','HND','Handsworth','Handsworth','SYK'),('GB','HNF','Henfield','Henfield','WSX'),('GB','HNG','Hengoed','Hengoed','MGM'),('GB','HNL','Hanley','Hanley','STS'),('GB','HNO','Henton','Henton','OXF'),('GB','HNR','Heanor','Heanor','DBY'),('GB','HNT','Hunstanton','Hunstanton','NFK'),('GB','HNU','Hainault','Hainault','GTL'),('GB','HOB','Horrabridge','Horrabridge','DVV'),('GB','HOD','Holmeswood','Holmeswood','LAN'),('GB','HOE','Hooe','Hooe',''),('GB','HOF','Holford','Holford','SOM'),('GB','HOG','Houghton','Houghton','CAM'),('GB','HOH','Horsham','Horsham','WSX'),('GB','HOK','Hook','Hook','LIN'),('GB','HOL','Holbeach','Holbeach','LIN'),('GB','HON','Hoddesdon','Hoddesdon','HRT'),('GB','HOO','Hoo','Hoo','KEN'),('GB','HOR','Horndean','Horndean','HAM'),('GB','HOT','Horton','Horton','WNM'),('GB','HOU','Hounslow','Hounslow','GTL'),('GB','HOW','Holt','Holt','WIL'),('GB','HOX','Hooton','Hooton','CAM'),('GB','HOY','Hornsey','Hornsey','GTL'),('GB','HOZ','Hoole','Hoole','CHS'),('GB','HPD','Harpenden','Harpenden','HRT'),('GB','HPE','Hope','Hope','FLN'),('GB','HPJ','Highpeak Junction','Highpeak Junction','DBY'),('GB','HPO','Hampole','Hampole','SYK'),('GB','HPT','Hound Point','Hound Point','LTN'),('GB','HRA','Horam','Horam','ESX'),('GB','HRB','Horbury','Horbury','WYK'),('GB','HRC','Hornchurch','Hornchurch','GTL'),('GB','HRD','Harlesden','Harlesden','GTL'),('GB','HRE','Humbie','Humbie','LTN'),('GB','HRF','Harefield','Harefield','GTL'),('GB','HRL','Harlow','Harlow','ESS'),('GB','HRN','Herne Bay','Herne Bay','KEN'),('GB','HRO','Harrow','Harrow','GTL'),('GB','HRR','Harrington','Harrington','CMA'),('GB','HRS','Horsmonden','Horsmonden','KEN'),('GB','HRT','Harrogate','Harrogate','NYK'),('GB','HRW','Harwich','Harwich','ESS'),('GB','HRY','Horley','Horley','SRY'),('GB','HSB','Helsby','Helsby','CHS'),('GB','HSE','Hessle','Hessle','HUM'),('GB','HSF','Horsforth','Horsforth','WYK'),('GB','HSG','Haslington','Haslington','CHS'),('GB','HSH','Hersham','Hersham','SRY'),('GB','HSK','Hassocks','Hassocks','WSX'),('GB','HSL','Haslemere','Haslemere','SRY'),('GB','HSN','Halesowen','Halesowen','WMD'),('GB','HSO','Helmshore','Helmshore','LAN'),('GB','HSP','Hassop','Hassop','DBY'),('GB','HST','Hunterston','Hunterston','CHS'),('GB','HSW','Halesworth','Halesworth','SFK'),('GB','HSY','Haseley','Haseley','WAR'),('GB','HTB','Hartlebury','Hartlebury','HWR'),('GB','HTD','Halstead','Halstead','ESS'),('GB','HTE','Hatch End','Hatch End','GTL'),('GB','HTF','Hartfield','Hartfield','GTL'),('GB','HTG','Hastings','Hastings','ESX'),('GB','HTH','Hythe','Hythe','KEN'),('GB','HTL','Huntly','Huntly','GMP'),('GB','HTN','Hillington','Hillington','STD'),('GB','HTO','Hatton','Hatton','GTL'),('GB','HTP','Hartlepool','Hartlepool','HPL'),('GB','HTR','Hatherton','Hatherton','CHS'),('GB','HTT','Hetton','Hetton','NYK'),('GB','HTW','Hartwell','Hartwell','NTH'),('GB','HTX','Holton','Holton','SFK'),('GB','HTY','Heytesbury','Heytesbury','WIL'),('GB','HUD','Huntingdon','Huntingdon','CAM'),('GB','HUE','Hurley','Hurley','WNM'),('GB','HUF','Hungerford','Hungerford','WBK'),('GB','HUL','Hull','Hull','HUM'),('GB','HUN','Hunwick','Hunwick','DUR'),('GB','HUO','Hunton','Hunton','NYK'),('GB','HUR','Hurst','Hurst','WOK'),('GB','HUS','Hursley','Hursley','HAM'),('GB','HUU','Staplehurst','Staplehurst','KEN'),('GB','HUY','Humberside Apt','Humberside Apt','HUM'),('GB','HVG','Hevingham','Hevingham','NFK'),('GB','HVM','Hoveringham','Hoveringham','NTT'),('GB','HVN','Hullavington','Hullavington','WIL'),('GB','HVR','Haverfordwest','Haverfordwest','DFD'),('GB','HWC','Hawick','Hawick','BOR'),('GB','HWD','How','How','HUM'),('GB','HWE','Hawes','Hawes','NYK'),('GB','HWH','Hawthorn Hill','Hawthorn Hill','LIN'),('GB','HWI','Hartley Wintney','Hartley Wintney','HAM'),('GB','HWK','Hawkhurst','Hawkhurst','KEN'),('GB','HWL','Holywell','Holywell','CWD'),('GB','HWN','Hawarden','Hawarden','CWD'),('GB','HWO','Holsworthy','Holsworthy',''),('GB','HWR','Harworth','Harworth','NTT'),('GB','HWS','Haltwhistle','Haltwhistle','NBL'),('GB','HWT','Haworth','Haworth','WYK'),('GB','HWW','Hawkwell','Hawkwell','ESS'),('GB','HWY','High Wycombe','High Wycombe','BKM'),('GB','HXH','Hexham','Hexham','NBL'),('GB','HXN','Hixon','Hixon','STS'),('GB','HXO','Hoton','Hoton','LEC'),('GB','HXT','Hexton','Hexton','HRT'),('GB','HXY','Harby','Harby','NTT'),('GB','HYB','Heswall','Heswall','MSY'),('GB','HYD','Hyde','Hyde','GTM'),('GB','HYJ','Helston','Helston','CON'),('GB','HYK','Hemyock','Hemyock','DEV'),('GB','HYL','Hoylake','Hoylake','MSY'),('GB','HYM','Heysham','Heysham','LAN'),('GB','HYN','Huyton','Huyton','MSY'),('GB','HYO','Hoy','Hoy','ORK'),('GB','HYP','Holyport','Holyport','WNM'),('GB','HYS','Haynes','Haynes','BDF'),('GB','HYW','Heywood','Heywood','GTM'),('GB','HYY','Henllys','Henllys','GNT'),('GB','HZG','Hazel Grove','Hazel Grove','GTM'),('GB','HZL','Hazlemere','Hazlemere','BKM'),('GB','HZO','Hazelwood','Hazelwood','DBY'),('GB','IAB','Isle Abbotts','Isle Abbotts','SOM'),('GB','IAO','Iron Acton','Iron Acton','SGC'),('GB','ICD','Inkberrow','Inkberrow','HWR'),('GB','IFD','Ilford','Ilford','GTL'),('GB','IGM','Ingoldmells','Ingoldmells','LIN'),('GB','IHM','Ingham','Ingham','SFK'),('GB','IIB','Irthlingborough','Irthlingborough','NTH'),('GB','IKS','Ilkeston','Ilkeston','DBY'),('GB','ILF','Ilfracombe','Ilfracombe',''),('GB','ILH','Illston on the Hill','Illston on the Hill','LEC'),('GB','ILK','Ilkley','Ilkley','WYK'),('GB','ILL','Gills','Gills','HLD'),('GB','ILP','Islip','Islip','OXF'),('GB','ILY','Islay Apt','Islay Apt','STD'),('GB','IMM','Immingham','Immingham','HUM'),('GB','IMP','Impington','Impington','CAM'),('GB','IMR','Ilminster','Ilminster','SOM'),('GB','INC','Ince','Ince','CHS'),('GB','ING','Ingham','Ingham','LIN'),('GB','INH','Inchinnan','Inchinnan','STD'),('GB','INK','Inverkeithing','Inverkeithing','FIF'),('GB','INL','Ingleton','Ingleton','NYK'),('GB','INV','Inverness','Inverness','HLD'),('GB','IOG','Isle of Grain','Isle of Grain','KEN'),('GB','IOM','Isle of Man','Isle of Man','IOM'),('GB','IOP','Isle of Portland','Isle of Portland','DOR'),('GB','IPS','Ipswich','Ipswich','SFK'),('GB','IRL','Irlam','Irlam','GTM'),('GB','IRV','Irvine','Irvine','STD'),('GB','ISC','Isles of Scilly','Isles of Scilly','IOS'),('GB','ISS','Liss','Liss','HAM'),('GB','IST','Islington','Islington','GTL'),('GB','ISW','Isleworth','Isleworth','GTL'),('GB','ITC','Itchenor','Itchenor','WSX'),('GB','IVB','Inverbervie','Inverbervie','GMP'),('GB','IVE','Iver','Iver','BKM'),('GB','IVG','Invergordon','Invergordon','HLD'),('GB','IVH','Iver Heath','Iver Heath','BKM'),('GB','IVI','Inverurie','Inverurie','GMP'),('GB','IVK','Inverkip','Inverkip','SCT'),('GB','IVT','Irvinestown','Irvinestown','FER'),('GB','IVY','Ivybridge','Ivybridge',''),('GB','IXW','Ixworth','Ixworth','SFK'),('GB','JAR','Jarrow','Jarrow','TWR'),('GB','JBG','Jedburgh','Jedburgh','BOR'),('GB','JER','Jersey','Jersey','JSY'),('GB','JHT','Johnstone','Johnstone','STD'),('GB','JOT','Jarrow','Jarrow','TWR'),('GB','JTB','Johnstonebridge','Johnstonebridge','DGY'),('GB','KBA','Kirkby in Ashfield','Kirkby in Ashfield','NTT'),('GB','KBE','Kinlochbervie','Kinlochbervie','HLD'),('GB','KBK','Burstwick','Burstwick','ERY'),('GB','KBN','Kilburn','Kilburn','GTL'),('GB','KBP','Kingston Bagpuize','Kingston Bagpuize','OXF'),('GB','KBT','Kirkcudbright','Kirkcudbright','DGY'),('GB','KBW','Knebworth','Knebworth','HRT'),('GB','KCG','Kennacraig','Kennacraig','STD'),('GB','KDM','Kidderminster','Kidderminster','HWR'),('GB','KDN','Kingsdown','Kingsdown','KEN'),('GB','KDY','Keady','Keady','ARM'),('GB','KEA','Keadby','Keadby','HUM'),('GB','KEG','Kegworth','Kegworth','DBY'),('GB','KEH','Kempston Hardwick','Kempston Hardwick','BDF'),('GB','KEI','Keighley','Keighley','WYK'),('GB','KEL','Kells','Kells','ANT'),('GB','KEM','Kemble','Kemble','WIL'),('GB','KEN','Kensington/London','Kensington/London','GTL'),('GB','KEW','Kew','Kew','GTL'),('GB','KEY','Keymer','Keymer','WSX'),('GB','KGA','Kesgrave','Kesgrave','SFK'),('GB','KGC','King\'s Cliffe','King\'s Cliffe','NTH'),('GB','KGH','Killingholme','Killingholme','HUM'),('GB','KGL','Kings Langley','Kings Langley','HRT'),('GB','KGN','Kings Norton','Kings Norton','BIR'),('GB','KGO','Kilmington','Kilmington','WIL'),('GB','KGS','Kingsley','Kingsley','HAM'),('GB','KGW','Kingswinford','Kingswinford','WMD'),('GB','KHM','Kirk Hammerton','Kirk Hammerton','NYK'),('GB','KIH','Kirkham','Kirkham','NYK'),('GB','KIL','Kilbride','Kilbride','STD'),('GB','KIN','Kingswood','Kingswood','SRY'),('GB','KIR','Kirknewton','Kirknewton','NBL'),('GB','KKB','Kirkby','Kirkby','MSY'),('GB','KKD','Kirkcaldy','Kirkcaldy','FIF'),('GB','KKI','Kirkliston','Kirkliston','LTN'),('GB','KKL','Kirkby Lonsdale','Kirkby Lonsdale','CMA'),('GB','KKS','Kirk Sandall','Kirk Sandall','SYK'),('GB','KKT','Kirkintilloch','Kirkintilloch','STD'),('GB','KLB','Kilbarchan','Kilbarchan',''),('GB','KLK','Kilkeel','Kilkeel','DOW'),('GB','KLL','Killinghall','Killinghall','NYK'),('GB','KLN','King\'s Lynn','King\'s Lynn','NFK'),('GB','KLO','Kelso','Kelso','SCB'),('GB','KLR','Kilroot','Kilroot','ANT'),('GB','KLT','Kilsyth','Kilsyth','STD'),('GB','KLW','Kenilworth','Kenilworth','WAR'),('GB','KMB','Kemberton','Kemberton','SHR'),('GB','KMI','Kemsing','Kemsing','KEN'),('GB','KMK','Kilmarnock','Kilmarnock','STD'),('GB','KML','Kirkmichael','Kirkmichael','SAY'),('GB','KMN','Kilmacolm','Kilmacolm','STD'),('GB','KMP','Kempsford','Kempsford','GLS'),('GB','KNA','Knaresborough','Knaresborough','NYK'),('GB','KND','Kendal','Kendal','CMA'),('GB','KNE','Kineton','Kineton','WAR'),('GB','KNF','King\'s Lynn','King\'s Lynn','NFK'),('GB','KNG','Kingsteignton','Kingsteignton',''),('GB','KNH','Kings Heath','Kings Heath','WMD'),('GB','KNK','Kingsnorth','Kingsnorth','KEN'),('GB','KNL','Kinloss','Kinloss','GMP'),('GB','KNN','Kenninghall','Kenninghall','NFK'),('GB','KNO','Knottingley','Knottingley','WYK'),('GB','KNR','Kinross','Kinross','TAY'),('GB','KNS','Kingston','Kingston','HWR'),('GB','KNT','Kenton','Kenton','SFK'),('GB','KNW','Knowsley','Knowsley','MSY'),('GB','KNY','Kinnerley','Kinnerley','SHR'),('GB','KOA','Kilchoan','Kilchoan','HLD'),('GB','KOH','Kinloch','Kinloch','HLD'),('GB','KOT','Cottenham','Cottenham','CAM'),('GB','KOW','Knowle','Knowle','WMD'),('GB','KPT','Knapton','Knapton','NYK'),('GB','KRE','Kentmere','Kentmere','CMA'),('GB','KRK','Kirkby Stephen','Kirkby Stephen','CMA'),('GB','KRR','Kirriemuir','Kirriemuir','TAY'),('GB','KSB','Kentisbeare','Kentisbeare','DEV'),('GB','KSF','Knutsford','Knutsford','CHS'),('GB','KSW','Kingswood','Kingswood','GLS'),('GB','KSY','Kearsley','Kearsley','BOL'),('GB','KTE','Kettlethorpe','Kettlethorpe','LIN'),('GB','KTG','Kitt Green','Kitt Green','GTM'),('GB','KTH','Keith','Keith','GMP'),('GB','KTN','Kington','Kington','HWR'),('GB','KTR','Kettering','Kettering','NTH'),('GB','KUH','Kingston upon Hull','Kingston upon Hull','HUM'),('GB','KUT','Kingston upon Thames','Kingston upon Thames','GTL'),('GB','KVD','Kelvedon','Kelvedon','ESS'),('GB','KWC','Keswick','Keswick','CMA'),('GB','KWG','Kilwinning','Kilwinning','STD'),('GB','KWL','Kirkwall','Kirkwall','ORK'),('GB','KWO','Kegworth','Kegworth','LEC'),('GB','KWS','Kingswells','Kingswells','GMP'),('GB','KWT','Kensworth','Kensworth','BDF'),('GB','KXG','Knotty Green','Knotty Green','BKM'),('GB','KYL','Kyle of Lochalsh','Kyle of Lochalsh','HLD'),('GB','KYS','Keynsham','Keynsham','BAS'),('GB','LAD','Little Addington','Little Addington','NTH'),('GB','LAG','Lancing','Lancing','WSX'),('GB','LAH','Lamlash','Lamlash','STD'),('GB','LAI','Laindon','Laindon','ESS'),('GB','LAK','Lakenheath','Lakenheath','SFK'),('GB','LAL','Langley','Langley','SLG'),('GB','LAM','Llanarmon','Llanarmon','CWD'),('GB','LAN','Lancaster','Lancaster','LAN'),('GB','LAR','Larne','Larne','LRN'),('GB','LAT','Langport','Langport','SOM'),('GB','LAU','Launceston','Launceston','CON'),('GB','LAV','Lavenham','Lavenham','SFK'),('GB','LAW','Law','Law','SLK'),('GB','LAX','Laxo','Laxo','ZET'),('GB','LBA','Leeds','Leeds','WYK'),('GB','LBI','Llanberis','Llanberis','GWN'),('GB','LBK','Barking','Barking','SFK'),('GB','LBN','Longbenton','Longbenton','TWR'),('GB','LBO','Little Brampton','Little Brampton','SHR'),('GB','LBR','Lambourn','Lambourn','WBK'),('GB','LBU','Long Buckby','Long Buckby','NTH'),('GB','LBZ','Leighton Buzzard','Leighton Buzzard','BDF'),('GB','LCH','Lochwinnoch','Lochwinnoch','STD'),('GB','LCK','Leckhampstead','Leckhampstead','WBK'),('GB','LCL','London Colney','London Colney','HRT'),('GB','LCN','Lincoln','Lincoln','LIN'),('GB','LCS','Leicester','Leicester','LEC'),('GB','LCW','Leckwith','Leckwith','SGM'),('GB','LDD','Liddington','Liddington','WIL'),('GB','LDE','Luddenden','Luddenden','WYK'),('GB','LDG','Longbridge','Longbridge','WMD'),('GB','LDH','Langdon Hills','Langdon Hills','ESS'),('GB','LDI','Lindfield','Lindfield','WSX'),('GB','LDL','Ludlow','Ludlow','SHR'),('GB','LDO','Llandudno','Llandudno','GWN'),('GB','LDQ','Loddon','Loddon','NFK'),('GB','LDT','Lydiate','Lydiate','MSY'),('GB','LDW','Llandrindod Wells','Llandrindod Wells','POW'),('GB','LDX','Long Ditton','Long Ditton','SRY'),('GB','LDY','Londonderry','Londonderry','DRY'),('GB','LEA','Long Eaton','Long Eaton','DBY'),('GB','LEB','Lane End','Lane End','BKM'),('GB','LEC','Lechlade','Lechlade','WIL'),('GB','LED','Ledbury','Ledbury','HWR'),('GB','LEE','Leeds ICD','Leeds ICD','WYK'),('GB','LEG','Leigh','Leigh','KEN'),('GB','LEH','Leatherhead','Leatherhead','SRY'),('GB','LEI','Leith','Leith','LTN'),('GB','LEK','Leek','Leek','STS'),('GB','LEM','Lenham','Lenham','KEN'),('GB','LEN','Leiston','Leiston','SFK'),('GB','LEO','Leominster','Leominster','HWR'),('GB','LEQ','Land\'s End','Land\'s End','CON'),('GB','LER','Lerwick','Lerwick','ZET'),('GB','LES','Lee-on-the-Solent','Lee-on-the-Solent','HAM'),('GB','LET','Letterston','Letterston','DFD'),('GB','LEV','Leven','Leven','FIF'),('GB','LEY','Leyburn','Leyburn','NYK'),('GB','LFD','Limpsfield','Limpsfield','SRY'),('GB','LFH','Llanfyrnach','Llanfyrnach','PEM'),('GB','LFP','Llanfairpwllgwyngyll','Llanfairpwllgwyngyll','GWN'),('GB','LFY','Llanfyllin','Llanfyllin','POW'),('GB','LGA','Llangarron','Llangarron','HEF'),('GB','LGB','Long Hanborough','Long Hanborough','OXF'),('GB','LGD','Little Gransden','Little Gransden','CAM'),('GB','LGE','Lightwater','Lightwater','SRY'),('GB','LGF','Longfield','Longfield','KEN'),('GB','LGG','Langton Green','Langton Green','KEN'),('GB','LGH','Leigh','Leigh','GTM'),('GB','LGI','Llangefni','Llangefni','AGY'),('GB','LGL','Langley Mill','Langley Mill','DBY'),('GB','LGN','Loughton','Loughton','BKM'),('GB','LGR','Langar','Langar','NTT'),('GB','LGS','Largs','Largs','STD'),('GB','LGT','Longton','Longton','STS'),('GB','LGU','Letham','Letham','TAY'),('GB','LGW','Gatwick Apt/London','Gatwick Apt/London','WSX'),('GB','LGY','Loch Gelly','Loch Gelly','FIF'),('GB','LHF','Lichfield','Lichfield','STS'),('GB','LHG','Little Houghton','Little Houghton','SYK'),('GB','LHH','Little Heath','Little Heath','WMD'),('GB','LHM','Laleham','Laleham','SRY'),('GB','LHN','Loughton','Loughton','ESS'),('GB','LHO','Longhope','Longhope','ORK'),('GB','LHP','Longhope','Longhope','GLS'),('GB','LHR','Heathrow Apt/London','Heathrow Apt/London','GTL'),('GB','LHS','Loch Striven','Loch Striven','STD'),('GB','LIE','Lye','Lye','WMD'),('GB','LIG','Lighthorne','Lighthorne','WAR'),('GB','LIM','Limavady','Limavady','LMV'),('GB','LIN','Lisnaskea','Lisnaskea','FER'),('GB','LIR','Little Rissington','Little Rissington','GLS'),('GB','LIS','Lisburn','Lisburn','LSB'),('GB','LIT','Littlehampton','Littlehampton','WSX'),('GB','LIV','Liverpool','Liverpool','MSY'),('GB','LJN','Littleton','Littleton',''),('GB','LKB','Lockerbie','Lockerbie','DGY'),('GB','LKD','Liskeard','Liskeard','CON'),('GB','LKH','Locks Heath','Locks Heath','HAM'),('GB','LKK','Laurencekirk','Laurencekirk','ABD'),('GB','LKT','Lower Kinnerton','Lower Kinnerton','CHS'),('GB','LLA','Llandeilo','Llandeilo','DFD'),('GB','LLB','Littleborough','Littleborough','GTM'),('GB','LLC','Little Carlton','Little Carlton','LIN'),('GB','LLD','Llanddulas','Llanddulas','CWD'),('GB','LLE','Llangoed','Llangoed','GWN'),('GB','LLF','Llanfrynach','Llanfrynach','POW'),('GB','LLG','Llangennech','Llangennech','DFD'),('GB','LLH','Little Hadham','Little Hadham','HRT'),('GB','LLI','Llangeinor','Llangeinor','BGE'),('GB','LLM','Little Milton','Little Milton','OXF'),('GB','LLN','Llanelli','Llanelli','DFD'),('GB','LLR','Little Horsted','Little Horsted','ESX'),('GB','LLT','Llantrisant','Llantrisant','MGM'),('GB','LLV','Little Lever','Little Lever','GTM'),('GB','LLW','Linlithgow','Linlithgow','LTN'),('GB','LLY','Llay','Llay','CWD'),('GB','LMA','Lochmaddy','Lochmaddy','WIS'),('GB','LMB','Lamberhurst','Lamberhurst','KEN'),('GB','LMD','Long Melford','Long Melford','SFK'),('GB','LMM','Lymm','Lymm','CHS'),('GB','LMO','Lynemouth','Lynemouth','NBL'),('GB','LMP','Lampeter','Lampeter','DFD'),('GB','LMR','Lyminster','Lyminster','WSX'),('GB','LMY','Llanarmon yn Lal','Llanarmon yn Lal','CWD'),('GB','LNE','Lyne','Lyne','SRY'),('GB','LNF','Lingfield','Lingfield','SRY'),('GB','LNH','Loanhead','Loanhead','LTN'),('GB','LNK','Lanark','Lanark','STD'),('GB','LNM','Lynmouth','Lynmouth',''),('GB','LNW','Linwood','Linwood','STD'),('GB','LNY','Langley','Langley','CHS'),('GB','LNZ','Lenzie','Lenzie','STD'),('GB','LOC','Long Crendon','Long Crendon','BKM'),('GB','LOG','Lostock Gralam','Lostock Gralam','CHS'),('GB','LOH','Lochgilphead','Lochgilphead',''),('GB','LOI','Long Itchington','Long Itchington','WAR'),('GB','LOL','Lochaline','Lochaline','HLD'),('GB','LON','London','London','GTL'),('GB','LOR','Langworth','Langworth','LIN'),('GB','LOS','Leigh-on-Sea','Leigh-on-Sea','ESS'),('GB','LOT','Louth','Louth','LIN'),('GB','LOU','Loughborough','Loughborough','LEC'),('GB','LOV','Lochinver','Lochinver','HLD'),('GB','LOW','Lowestoft','Lowestoft','SFK'),('GB','LPF','Lapford','Lapford',''),('GB','LPH','Liphook','Liphook','HAM'),('GB','LPW','Lapworth','Lapworth','WAR'),('GB','LRB','Larbert','Larbert','FAL'),('GB','LRE','Longridge','Longridge','LAN'),('GB','LRH','Lark Hill','Lark Hill','WIL'),('GB','LRK','Larkfield','Larkfield','STD'),('GB','LSA','Ludgershall','Ludgershall','WIL'),('GB','LSI','Sumburgh','Sumburgh','ZET'),('GB','LSK','Linstock','Linstock','CMA'),('GB','LSL','Leslie','Leslie','GMP'),('GB','LSN','Long Sutton','Long Sutton','LIN'),('GB','LSP','Leamington Spa','Leamington Spa','WAR'),('GB','LSR','Little Somborne','Little Somborne','HAM'),('GB','LSS','Lossiemouth','Lossiemouth','GMP'),('GB','LSY','Laisterdyke','Laisterdyke','BRD'),('GB','LTC','Litchfield','Litchfield','HAM'),('GB','LTE','Little Eaton','Little Eaton','DBY'),('GB','LTF','Langtoft','Langtoft','LIN'),('GB','LTH','Letchworth','Letchworth','HRT'),('GB','LTL','Littlebrook','Littlebrook','KEN'),('GB','LTM','Llantwit Major','Llantwit Major','SGM'),('GB','LTN','Linton','Linton','KEN'),('GB','LTO','Litton','Litton','DBY'),('GB','LTT','Lutterworth','Lutterworth','LEC'),('GB','LUG','Lugton','Lugton','EAY'),('GB','LUT','Luton','Luton','BDF'),('GB','LUX','Luxulyan','Luxulyan','CON'),('GB','LVN','Levenshulme','Levenshulme','GTM'),('GB','LVS','Liversedge','Liversedge','WYK'),('GB','LVY','Leven','Leven','ERY'),('GB','LWA','Loudwater','Loudwater','BKM'),('GB','LWE','Lewes','Lewes','ESX'),('GB','LWM','Low Moor','Low Moor','BKM'),('GB','LWN','Lowton','Lowton','GTM'),('GB','LWR','Lower Weare','Lower Weare','SOM'),('GB','LWS','Lewisham','Lewisham','GTL'),('GB','LWT','West Thurrock','West Thurrock','ESS'),('GB','LXW','Lower Stondon','Lower Stondon','BDF'),('GB','LYA','Lytham St Annes','Lytham St Annes','LAN'),('GB','LYD','Lydney','Lydney','GLS'),('GB','LYE','Lyneham','Lyneham','WIL'),('GB','LYH','Lyndhurst','Lyndhurst','HAM'),('GB','LYK','Ladybank','Ladybank','FIF'),('GB','LYL','Leyland','Leyland','LAN'),('GB','LYM','Lymington','Lymington','HAM'),('GB','LYN','Lympne','Lympne','KEN'),('GB','LYO','Leyton','Leyton','GTL'),('GB','LYS','Lyness','Lyness','ORK'),('GB','LYX','Lydd','Lydd','KEN'),('GB','LZD','Lizard','Lizard','CON'),('GB','MAC','Machrihanish','Machrihanish','STD'),('GB','MAD','Maddiston','Maddiston','SCT'),('GB','MAG','Magor','Magor','GNT'),('GB','MAH','Maidenhead','Maidenhead','WNM'),('GB','MAK','Marrick','Marrick','NYK'),('GB','MAL','Maldon','Maldon','ESS'),('GB','MAR','March','March','CAM'),('GB','MAS','Masham','Masham','NYK'),('GB','MAT','Market Lavington','Market Lavington','WIL'),('GB','MAW','Marchwood','Marchwood','HAM'),('GB','MAY','Mayfield','Mayfield','LTN'),('GB','MBE','Melbourne','Melbourne','DBY'),('GB','MBH','Malborough','Malborough','DVV'),('GB','MBO','Marylebone','Marylebone','GTL'),('GB','MBU','Membury','Membury','DEV'),('GB','MBY','Melton Mowbray','Melton Mowbray','LEC'),('GB','MCA','Much Hadham','Much Hadham','HRT'),('GB','MCD','Macduff','Macduff','GMP'),('GB','MCL','Macclesfield','Macclesfield','CHS'),('GB','MCM','Macmerry','Macmerry','ELN'),('GB','MCN','Machen','Machen','MGM'),('GB','MDD','Middlefield Law','Middlefield Law','CLV'),('GB','MDH','Midhurst','Midhurst','WSX'),('GB','MDL','Middleham','Middleham','NYK'),('GB','MDN','Middleton','Middleton','GTM'),('GB','MDO','Milden','Milden','SFK'),('GB','MDP','Market Deeping','Market Deeping','CAM'),('GB','MDS','Micheldever Station','Micheldever Station','HAM'),('GB','MDT','Maidstone','Maidstone','KEN'),('GB','MDV','Maida Vale/London','Maida Vale/London','GTL'),('GB','MDW','Middlewich','Middlewich','CHS'),('GB','MDY','Madeley','Madeley','STS'),('GB','MEA','Manea','Manea','CAM'),('GB','MEB','Menai Bridge','Menai Bridge','GWN'),('GB','MEE','Maesteg','Maesteg','MGM'),('GB','MEL','Melbourn','Melbourn','CAM'),('GB','MEN','Mendlesham','Mendlesham','SFK'),('GB','MEO','Merton','Merton','GTL'),('GB','MET','Merthyr Tydfil','Merthyr Tydfil','MGM'),('GB','MFD','Mansfield','Mansfield','NTT'),('GB','MFT','Magherafelt','Magherafelt','NIR'),('GB','MGH','Maghera','Maghera','NBL'),('GB','MGL','Maghull','Maghull','MSY'),('GB','MGM','Margam','Margam','WGM'),('GB','MGO','Magheramorne','Magheramorne',''),('GB','MGT','Margate','Margate','KEN'),('GB','MHA','Maghera','Maghera','MFT'),('GB','MHD','Minehead','Minehead','SOM'),('GB','MHE','Mochdre','Mochdre',''),('GB','MHI','Mamhilad','Mamhilad','MON'),('GB','MHL','Mill Hill','Mill Hill','GTL'),('GB','MHM','Martlesham','Martlesham','SFK'),('GB','MHO','Much Hoole','Much Hoole','LAN'),('GB','MHY','Munlochy','Munlochy','HLD'),('GB','MID','Middlesbrough','Middlesbrough','CLV'),('GB','MIK','Milton Keynes','Milton Keynes','BKM'),('GB','MIL','Milton','Milton','KEN'),('GB','MIM','Moreton-in-Marsh','Moreton-in-Marsh','GLS'),('GB','MIN','Minworth','Minworth','WMD'),('GB','MIO','Milton, Abingdon','Milton, Abingdon','OXF'),('GB','MIR','Mirfield','Mirfield','WYK'),('GB','MIS','Mistley','Mistley','ESS'),('GB','MIT','Mitcheldean','Mitcheldean','GLS'),('GB','MKB','Matlock Bath','Matlock Bath','DBY'),('GB','MKD','Market Drayton','Market Drayton','SHR'),('GB','MKH','Market Harborough','Market Harborough','LEC'),('GB','MKI','Muirkirk','Muirkirk','EAY'),('GB','MKL','Market Hill','Market Hill','ARM'),('GB','MKO','Monkton','Monkton','STY'),('GB','MKR','Market Rasen','Market Rasen','LIN'),('GB','MKT','Mickle Trafford','Mickle Trafford','CHS'),('GB','MLA','Meltham','Meltham','WYK'),('GB','MLB','Millbrook','Millbrook','CON'),('GB','MLD','Meldreth','Meldreth','CAM'),('GB','MLF','Milford Haven','Milford Haven','DFD'),('GB','MLG','Mallaig','Mallaig','HLD'),('GB','MLH','Melksham','Melksham','WIL'),('GB','MLJ','Mellor','Mellor','GTM'),('GB','MLK','Mallusk','Mallusk',''),('GB','MLL','Mildenhall','Mildenhall','SFK'),('GB','MLM','Millom','Millom','CMA'),('GB','MLN','Malton','Malton','NYK'),('GB','MLO','Milnrow','Milnrow','GTM'),('GB','MLR','Melrose','Melrose','BOR'),('GB','MLS','Molesworth','Molesworth','CAM'),('GB','MLT','Milnathort','Milnathort','TAY'),('GB','MLU','Melbourne','Melbourne','ERY'),('GB','MLV','Milngavie','Milngavie','STD'),('GB','MLW','Marlow','Marlow','BKM'),('GB','MLY','Maltby','Maltby','SYK'),('GB','MMB','Malmesbury','Malmesbury','WIL'),('GB','MME','Teesside','Teesside','CLV'),('GB','MMH','Medmenham','Medmenham','BKM'),('GB','MMI','Balmedie','Balmedie','ABD'),('GB','MMO','Monmouth','Monmouth','GNT'),('GB','MMR','Mossmoran','Mossmoran',''),('GB','MMY','Montgomery Trefaldwyn','Montgomery Trefaldwyn',''),('GB','MNC','Manchester','Manchester','GTM'),('GB','MNL','Machynlleth','Machynlleth','POW'),('GB','MNN','Manningtree','Manningtree','ESS'),('GB','MNO','Monkton','Monkton','SAY'),('GB','MNP','Milnthorpe','Milnthorpe','CMA'),('GB','MNU','Moreton on Lugg','Moreton on Lugg','HWR'),('GB','MNW','Mintlaw','Mintlaw','GMP'),('GB','MNY','Manby','Manby','LIN'),('GB','MOA','Moira','Moira','LSB'),('GB','MOB','Mobberley','Mobberley','CHS'),('GB','MOC','Morecambe','Morecambe','LAN'),('GB','MOD','Morden','Morden','GTL'),('GB','MOE','Moulsoe','Moulsoe','BKM'),('GB','MOL','Mold','Mold','CWD'),('GB','MON','Montrose','Montrose','TAY'),('GB','MOO','Muir of Ord','Muir of Ord','HLD'),('GB','MOR','Morpeth','Morpeth','NBL'),('GB','MOS','Moston','Moston','GTM'),('GB','MOT','Moreton','Moreton','MSY'),('GB','MOU','Moulton','Moulton','NTH'),('GB','MOW','Motherwell','Motherwell','STD'),('GB','MOY','Moresby','Moresby','CMA'),('GB','MQR','Moira','Moira','LEC'),('GB','MRC','Marchington','Marchington','STS'),('GB','MRD','Marden','Marden','KEN'),('GB','MRE','Mere','Mere','WIL'),('GB','MRF','Marfleet','Marfleet','HUM'),('GB','MRK','Markinch','Markinch','FIF'),('GB','MRL','Marlborough','Marlborough','WIL'),('GB','MRM','Martham','Martham','NFK'),('GB','MRN','Marston','Marston','OXF'),('GB','MRO','Morton','Morton','LIN'),('GB','MRT','Moreton','Moreton','DOR'),('GB','MRY','Maryport','Maryport','CMA'),('GB','MSE','Manston','Manston',''),('GB','MSJ','Marshland Saint James','Marshland Saint James','NFK'),('GB','MSM','Midsomer Norton','Midsomer Norton','SOM'),('GB','MSO','Marlesford','Marlesford','SFK'),('GB','MSR','Menstrie','Menstrie','CLK'),('GB','MSS','Mossley Hill','Mossley Hill','GTM'),('GB','MTC','Mitcham','Mitcham','GTL'),('GB','MTG','Matching Green','Matching Green','ESS'),('GB','MTH','Methil','Methil','FIF'),('GB','MTK','Methlick','Methlick','GMP'),('GB','MTL','Matlock','Matlock','DBY'),('GB','MTN','Maryton','Maryton','TAY'),('GB','MTO','Melton','Melton','SFK'),('GB','MTT','Marston Trussell','Marston Trussell','NTH'),('GB','MTZ','Mortlake','Mortlake','GTL'),('GB','MUD','Maulden','Maulden','BDF'),('GB','MUK','Muckamore','Muckamore','ANT'),('GB','MUL','Mull Apt','Mull Apt',''),('GB','MUS','Musselburgh','Musselburgh','LTN'),('GB','MVW','Malvern Wells','Malvern Wells','HWR'),('GB','MWD','Methwold','Methwold','NFK'),('GB','MWE','Market Weighton','Market Weighton','ERY'),('GB','MWG','Mawgan','Mawgan','CON'),('GB','MWI','Marchwiel','Marchwiel','CWD'),('GB','MXB','Mexborough','Mexborough','SYK'),('GB','MXK','Morley','Morley','WYK'),('GB','MXO','Moore','Moore',''),('GB','MYB','Maybole','Maybole','STD'),('GB','MYT','Mytholmroyd','Mytholmroyd','WYK'),('GB','MYW','Maesycwmmer','Maesycwmmer','CAY'),('GB','MZL','Marple','Marple','GTM'),('GB','NAI','Nairn','Nairn','HLD'),('GB','NAL','Northallerton','Northallerton','NYK'),('GB','NAY','Newton Aycliffe','Newton Aycliffe','DUR'),('GB','NBA','Newton Abbot','Newton Abbot',''),('GB','NBG','Narborough','Narborough','LEC'),('GB','NBH','Narberth','Narberth','PEM'),('GB','NBI','Nethy Bridge','Nethy Bridge','HLD'),('GB','NBU','Newburgh','Newburgh','FIF'),('GB','NBW','North Berwick','North Berwick','LTN'),('GB','NBY','Newbury','Newbury','WBK'),('GB','NCE','Newcastle-under-Lyme','Newcastle-under-Lyme','STS'),('GB','NCL','Newcastle upon Tyne','Newcastle upon Tyne','TWR'),('GB','NCN','Norton Canes','Norton Canes','STS'),('GB','NCP','New Chapel','New Chapel','SRY'),('GB','NCV','North Cave','North Cave','HUM'),('GB','NDE','Neasden','Neasden','GTL'),('GB','NDS','New Duston','New Duston','NTH'),('GB','NDY','Sanday','Sanday','ORK'),('GB','NEA','Neath Abbey','Neath Abbey','WGM'),('GB','NEC','Nesscliffe','Nesscliffe','SHR'),('GB','NEH','Neap House','Neap House','HUM'),('GB','NES','Neston','Neston','CHS'),('GB','NET','Neath','Neath','WGM'),('GB','NFF','Nafferton','Nafferton','HUM'),('GB','NFI','Ninfield','Ninfield','ESX'),('GB','NFT','Northfleet','Northfleet','KEN'),('GB','NGG','Nigg','Nigg','HLD'),('GB','NGO','Newington','Newington','KEN'),('GB','NGR','Nantgarw','Nantgarw','RCT'),('GB','NHA','North Hayling','North Hayling','HAM'),('GB','NHE','Newhouse','Newhouse','STD'),('GB','NHF','Nether Heyford','Nether Heyford','NTH'),('GB','NHI','Northiam','Northiam','ESX'),('GB','NHM','Needham Market','Needham Market','SFK'),('GB','NHO','New Holland','New Holland','HUM'),('GB','NHP','Northampton','Northampton','NTH'),('GB','NHT','Northolt','Northolt','GTL'),('GB','NHV','Newhaven','Newhaven','ESX'),('GB','NHY','North Hykeham','North Hykeham','LIN'),('GB','NKH','North Killingholme','North Killingholme','NLN'),('GB','NKT','Newmarket','Newmarket','SFK'),('GB','NLF','North Luffenham','North Luffenham','LEC'),('GB','NLN','Nelson','Nelson','LAN'),('GB','NLV','Newton Longville','Newton Longville','BKM'),('GB','NLW','Newton-le-Willows','Newton-le-Willows','MSY'),('GB','NLY','Netherley','Netherley','ABD'),('GB','NMA','New Malden','New Malden','GTL'),('GB','NMD','Normandy','Normandy','SRY'),('GB','NML','Newmilns','Newmilns','STD'),('GB','NMN','New Milton','New Milton','HAM'),('GB','NMS','Nomansland','Nomansland','WIL'),('GB','NNH','Napton on the Hill','Napton on the Hill','WAR'),('GB','NNT','Newton Heath','Newton Heath','GTM'),('GB','NOM','Northam','Northam',''),('GB','NOR','Normanton','Normanton','WYK'),('GB','NPO','Newport','Newport','IOW'),('GB','NPR','Newport','Newport','SHR'),('GB','NPT','Newport','Newport','GNT'),('GB','NQY','Newquay','Newquay','CON'),('GB','NRC','North Cheam','North Cheam','GTL'),('GB','NRF','North Ferriby','North Ferriby','HUM'),('GB','NRH','Northchapel','Northchapel','WSX'),('GB','NRL','North Lancing','North Lancing','WSX'),('GB','NRM','North Walsham','North Walsham','NFK'),('GB','NRO','North Ronaldsay','North Ronaldsay','ORK'),('GB','NRS','North Ronaldsay Apt','North Ronaldsay Apt','ORK'),('GB','NRW','Norwich','Norwich','NFK'),('GB','NRY','Newry','Newry','DOW'),('GB','NSE','Nailsea','Nailsea','NSM'),('GB','NSH','North Shields','North Shields','TWR'),('GB','NSW','Newton Stewart','Newton Stewart','DGY'),('GB','NTA','Newtownabbey','Newtownabbey','NTA'),('GB','NTE','Netherton','Netherton','WMD'),('GB','NTG','Nottingham','Nottingham','NTT'),('GB','NTH','Northwich','Northwich','CHS'),('GB','NTN','Nuneaton','Nuneaton','WAR'),('GB','NTP','Nether Poppleton','Nether Poppleton','NYK'),('GB','NTS','Newtownards','Newtownards','DOW'),('GB','NTW','Nantwich','Nantwich','CHS'),('GB','NTY','Bentley','Bentley',''),('GB','NUR','Nursling','Nursling','HAM'),('GB','NUT','Newark upon Trent','Newark upon Trent','NTT'),('GB','NWB','Newbridge','Newbridge','LTN'),('GB','NWC','Newick','Newick','ESX'),('GB','NWD','Northwood','Northwood','GTL'),('GB','NWE','Newent','Newent','GLS'),('GB','NWK','Newark','Newark','DGY'),('GB','NWL','North Weald Bassett/London','North Weald Bassett/London','ESS'),('GB','NWO','Newton','Newton','CHS'),('GB','NWP','Newport Pagnell','Newport Pagnell','BKM'),('GB','NWR','Newbridge','Newbridge','GNT'),('GB','NWT','Newtown','Newtown','POW'),('GB','NWY','New York','New York','LIN'),('GB','NYL','Newlyn','Newlyn','CON'),('GB','OAK','Oakhamness','Oakhamness',''),('GB','OAR','Oare','Oare','WIL'),('GB','OBA','Oban','Oban','STD'),('GB','OBM','Ogbourne Maizey','Ogbourne Maizey','WIL'),('GB','OBY','Oldbury','Oldbury','WMD'),('GB','OCY','Offord Cluny','Offord Cluny','CAM'),('GB','ODH','Oldham','Oldham','GTM'),('GB','ODM','Odiham','Odiham','HAM'),('GB','OET','Coleorton','Coleorton','LEC'),('GB','OGP','Osgathorpe','Osgathorpe','LEC'),('GB','OGR','Ongar','Ongar','ESS'),('GB','OHA','Ockham','Ockham','SRY'),('GB','OHI','Cross Hills','Cross Hills','NYK'),('GB','OKE','Stokeham','Stokeham','NTT'),('GB','OKH','Okehampton','Okehampton',''),('GB','OKK','Old Kilpatrick','Old Kilpatrick','STD'),('GB','OKM','Oakham','Oakham','LEC'),('GB','OKW','Oakworth','Oakworth','WYK'),('GB','OLD','Old','Old','NTH'),('GB','OLN','Olney','Olney','BKM'),('GB','OLP','Osterley Park','Osterley Park','HNS'),('GB','OLW','Old Woking','Old Woking','SRY'),('GB','OLY','Holywood','Holywood','DGY'),('GB','OMA','Omagh','Omagh','OMH'),('GB','OMK','Ormskirk','Ormskirk','LAN'),('GB','OMU','Oldmeldrum','Oldmeldrum','ABD'),('GB','ONH','Ongar Hill','Ongar Hill','ESS'),('GB','OPG','Orpington','Orpington','GTL'),('GB','ORO','Orton','Orton','CMA'),('GB','ORP','Orchard Portman','Orchard Portman','SOM'),('GB','ORT','Orsett','Orsett','ESS'),('GB','OSM','Ottery St. Mary','Ottery St. Mary',''),('GB','OSN','Ossington','Ossington','NTT'),('GB','OSO','Woolaston','Woolaston','GLS'),('GB','OSS','Ossett','Ossett','WYK'),('GB','OSY','Mossley','Mossley','GTM'),('GB','OTH','Otham','Otham','KEN'),('GB','OTL','Otley','Otley','WYK'),('GB','OTN','Offerton','Offerton','TWR'),('GB','OTO','Wollaston','Wollaston','WMD'),('GB','OTT','Ottershaw','Ottershaw','SRY'),('GB','OUK','Outer Skerries','Outer Skerries','ZET'),('GB','OUT','Tomintoul','Tomintoul','GMP'),('GB','OVE','Overton','Overton','HAM'),('GB','OVR','Over','Over','CAM'),('GB','OWR','Oswestry','Oswestry','SHR'),('GB','OXD','Oxted','Oxted','SRY'),('GB','OXF','Oxford','Oxford','OXF'),('GB','OXI','Oxhill','Oxhill','WAR'),('GB','OXT','Oxshott','Oxshott','SRY'),('GB','PAB','Pangbourne','Pangbourne','OXF'),('GB','PAD','Padstow','Padstow','CON'),('GB','PAK','Port Askaig','Port Askaig','STD'),('GB','PAL','Palnackie','Palnackie','DGY'),('GB','PAR','Par','Par','CON'),('GB','PAS','Paisley','Paisley','STD'),('GB','PBI','Pirbright','Pirbright','SRY'),('GB','PBK','Pinchbeck','Pinchbeck','LIN'),('GB','PBL','Parbold','Parbold','LAN'),('GB','PBR','Perry Barr','Perry Barr','WMD'),('GB','PCD','Pencader','Pencader','DFD'),('GB','PCI','Pencaitland','Pencaitland','LTN'),('GB','PCK','Peckham','Peckham','GTL'),('GB','PCL','Pickhill','Pickhill','NYK'),('GB','PCR','Puckeridge','Puckeridge','HRT'),('GB','PCT','Prescot','Prescot','MSY'),('GB','PCU','Penicuik','Penicuik','LTN'),('GB','PCW','Porthcawl','Porthcawl','MGM'),('GB','PDG','Podington','Podington','BDF'),('GB','PDH','Padiham','Padiham','LAN'),('GB','PDI','Port Dinorwic','Port Dinorwic','GWN'),('GB','PDW','Paddock Wood','Paddock Wood','KEN'),('GB','PDY','Pudsey','Pudsey','WYK'),('GB','PED','Pembroke Dock','Pembroke Dock','DFD'),('GB','PEE','Peebles','Peebles','BOR'),('GB','PEL','Peel','Peel','IOM'),('GB','PEM','Pembroke','Pembroke','DFD'),('GB','PEN','Penzance','Penzance','CON'),('GB','PER','Perth','Perth','TAY'),('GB','PET','Peterborough','Peterborough','CAM'),('GB','PEV','Papworth Everard','Papworth Everard','CAM'),('GB','PEX','Pettistree','Pettistree','SFK'),('GB','PEY','Penderyn','Penderyn','RCT'),('GB','PFF','Ponders End','Ponders End','GTL'),('GB','PFT','Purfleet','Purfleet','ESS'),('GB','PGN','Paignton','Paignton',''),('GB','PGR','Pamber Green','Pamber Green','HAM'),('GB','PGT','Polegate','Polegate','ESX'),('GB','PGW','Pentre-bach','Pentre-bach','GNT'),('GB','PHD','Peterhead','Peterhead','GMP'),('GB','PHG','Potter Heigham','Potter Heigham','NFK'),('GB','PHO','Pinhoe','Pinhoe','DEV'),('GB','PIK','Prestwick','Prestwick','SAY'),('GB','PIN','Pinner','Pinner','GTL'),('GB','PIT','Prittlewell','Prittlewell','ESS'),('GB','PKL','Pocklington','Pocklington','HUM'),('GB','PKR','Pickering','Pickering','NYK'),('GB','PLD','Polstead','Polstead','SFK'),('GB','PLE','Poyle','Poyle','WNM'),('GB','PLG','Palmers Green','Palmers Green','GTL'),('GB','PLL','Pollokshields','Pollokshields','STD'),('GB','PLN','Port Ellen','Port Ellen','STD'),('GB','PLT','Peckleton','Peckleton',''),('GB','PLX','Pulloxhill','Pulloxhill','BDF'),('GB','PLY','Plymouth','Plymouth',''),('GB','PMB','Pembury','Pembury','KEN'),('GB','PMD','Portmadoc','Portmadoc','GWN'),('GB','PME','Portsmouth','Portsmouth','HAM'),('GB','PMG','Plumpton Green','Plumpton Green','ESX'),('GB','PMH','Peasmarsh','Peasmarsh','ESX'),('GB','PMM','Penmaenmawr','Penmaenmawr','GWN'),('GB','PMT','Plympton','Plympton',''),('GB','PNA','Patna','Patna','EAY'),('GB','PNC','Pontyclun','Pontyclun','MGM'),('GB','PND','Pencoed','Pencoed','MGM'),('GB','PNH','Penarth','Penarth','SGM'),('GB','PNL','Ponteland','Ponteland','NBL'),('GB','PNN','Penn','Penn','BKM'),('GB','PNR','Penrith','Penrith','CMA'),('GB','PNS','Penistone','Penistone','SYK'),('GB','PNT','Pontllanfraith','Pontllanfraith','WLS'),('GB','PNY','Pontypridd','Pontypridd','MGM'),('GB','POB','Potters Bar','Potters Bar','HRT'),('GB','POC','Port Clarence','Port Clarence','STT'),('GB','POF','Pontefract','Pontefract','WYK'),('GB','POH','Porthoustock','Porthoustock','CON'),('GB','POL','Polebrook','Polebrook','NTH'),('GB','PON','Potterne','Potterne','WIL'),('GB','POO','Poole','Poole','DOR'),('GB','POR','Porth','Porth','RCT'),('GB','POT','Portlethen','Portlethen','ABD'),('GB','POY','Poynton','Poynton','CHS'),('GB','PPE','Port Penrhyn','Port Penrhyn','GWN'),('GB','PPL','Poplar','Poplar','GTL'),('GB','PPW','Papa Westray','Papa Westray',''),('GB','PRC','Portchester','Portchester','HAM'),('GB','PRD','Prudhoe','Prudhoe','NBL'),('GB','PRE','Preston','Preston','LAN'),('GB','PRG','Partridge Green','Partridge Green','WSX'),('GB','PRH','Portland Harbour','Portland Harbour','DOR'),('GB','PRK','Portskewett','Portskewett','GNT'),('GB','PRO','Purton','Purton','WIL'),('GB','PRR','Princes Risborough','Princes Risborough','BKM'),('GB','PRS','Prestatyn','Prestatyn','CWD'),('GB','PRT','Portree','Portree','HLD'),('GB','PRU','Portbury','Portbury','NSM'),('GB','PRV','Perivale','Perivale','GTL'),('GB','PRW','Prestwich','Prestwich','GTM'),('GB','PRY','Penryn','Penryn','CON'),('GB','PSA','Preesall','Preesall','LAN'),('GB','PSB','Sutton Bridge','Sutton Bridge','LIN'),('GB','PSH','Pershore','Pershore','HWR'),('GB','PSI','Pott Shrigley','Pott Shrigley','CHS'),('GB','PSO','Preston','Preston','KEN'),('GB','PST','Parkeston Quay','Parkeston Quay','ESS'),('GB','PSU','Port Sunlight','Port Sunlight','MSY'),('GB','PSV','Papa Stour','Papa Stour',''),('GB','PTA','Point of Ayre','Point of Ayre','IOM'),('GB','PTB','Port Talbot','Port Talbot','WGM'),('GB','PTE','Peterlee','Peterlee','DUR'),('GB','PTF','Petersfield','Petersfield','HAM'),('GB','PTH','Portishead','Portishead','NSM'),('GB','PTL','Portland','Portland','DOR'),('GB','PTN','Puttenham','Puttenham','SRY'),('GB','PTP','Pontypool','Pontypool','GNT'),('GB','PTR','Portrush','Portrush','ANT'),('GB','PTS','Portslade','Portslade','ESX'),('GB','PTT','Partington','Partington','GTM'),('GB','PTW','Portadown','Portadown','ARM'),('GB','PTY','Putney','Putney','GTL'),('GB','PUL','Pulborough','Pulborough','WSX'),('GB','PUR','Purley','Purley','GTL'),('GB','PWD','Prestwood','Prestwood','BKM'),('GB','PWL','Pwllheli','Pwllheli','GWN'),('GB','PWS','Pewsey','Pewsey','WIL'),('GB','PWY','Patchway','Patchway','SGC'),('GB','PXT','Plaxtol','Plaxtol','KEN'),('GB','PYE','Poyle','Poyle','BKM'),('GB','PYL','Pyle','Pyle','MGM'),('GB','PYR','Pyrford','Pyrford','SRY'),('GB','QFR','Queensferry','Queensferry','CWD'),('GB','QLT','Elton','Elton','CHS'),('GB','QMV','Bruton','Bruton','SOM'),('GB','QRA','Bartley','Bartley','HAM'),('GB','QTN','Quainton','Quainton','BKM'),('GB','QUB','Queenborough','Queenborough','KEN'),('GB','QVG','Sandgate','Sandgate','KEN'),('GB','QVY','South Lancing','South Lancing','WSX'),('GB','QWH','Swadlincote','Swadlincote','DBY'),('GB','QWY','Wyboston','Wyboston','BDF'),('GB','QZL','Clevedon','Clevedon','NSM'),('GB','RAA','Arnish','Arnish','HLD'),('GB','RAD','Radley','Radley','OXF'),('GB','RAH','Rainham','Rainham','GTL'),('GB','RAL','Rednal','Rednal','SHR'),('GB','RAM','Ramsey','Ramsey','IOM'),('GB','RAT','Rathfriland','Rathfriland','NYM'),('GB','RAW','Rawtenstall','Rawtenstall','LAN'),('GB','RAY','Rothesay','Rothesay','STD'),('GB','RBG','Redbridge/London','Redbridge/London','GTL'),('GB','RBR','Robertsbridge','Robertsbridge','ESX'),('GB','RBT','Ribbleton','Ribbleton','LAN'),('GB','RBY','Rubery','Rubery','WMD'),('GB','RCH','Richmond','Richmond','NYK'),('GB','RCK','Bricket Wood','Bricket Wood','HRT'),('GB','RCS','Rochester','Rochester','KEN'),('GB','RCU','Richmond upon Thames','Richmond upon Thames','GTL'),('GB','RDB','Redbourn','Redbourn','LIN'),('GB','RDC','Radcliffe','Radcliffe','GTM'),('GB','RDD','Redditch','Redditch','HWR'),('GB','RDF','Redford','Redford','TAY'),('GB','RDG','Riddings','Riddings','DBY'),('GB','RDI','Redding','Redding','SCT'),('GB','RDL','Radlett','Radlett','HRT'),('GB','RDM','Ridgmont','Ridgmont','BDF'),('GB','RDN','Reading','Reading','RDG'),('GB','RDO','Ruddington','Ruddington','NTT'),('GB','RDQ','Ramsden Heath','Ramsden Heath','ESS'),('GB','RDT','Randalstown','Randalstown','ANT'),('GB','REB','Redcliff Bay','Redcliff Bay','NSM'),('GB','REH','Redhill','Redhill','SRY'),('GB','REL','Rednal','Rednal','WMD'),('GB','REN','Renfrew','Renfrew','STD'),('GB','RER','Redcar','Redcar','CLV'),('GB','REY','Rugeley','Rugeley','STS'),('GB','RFD','Rochford','Rochford','ESS'),('GB','RFF','Roecliffe','Roecliffe','NYK'),('GB','RFO','Retford','Retford','NTT'),('GB','RGP','Regent\'s Park','Regent\'s Park','GTL'),('GB','RGR','Ringmer','Ringmer','ESX'),('GB','RGT','Reigate','Reigate','SRY'),('GB','RGV','Redgrave','Redgrave','SFK'),('GB','RHG','Rhigos','Rhigos','MGM'),('GB','RHM','Rendlesham','Rendlesham','SFK'),('GB','RHN','Ruthin','Ruthin','CWD'),('GB','RHO','Rhondda','Rhondda','MGM'),('GB','RHT','Rishton','Rishton','LAN'),('GB','RHY','Rhyl','Rhyl','CWD'),('GB','RID','Ridham Dock','Ridham Dock','KEN'),('GB','RIH','Brierley Hill','Brierley Hill','WMD'),('GB','RIN','Ringstead','Ringstead','NFK'),('GB','RIP','Ripon','Ripon','NYK'),('GB','RIW','Ringwood','Ringwood','HAM'),('GB','RKW','Rickmansworth','Rickmansworth','HRT'),('GB','RLA','Rosslea','Rosslea','FER'),('GB','RLH','Rayleigh','Rayleigh','ESS'),('GB','RLY','Ropley','Ropley','HAM'),('GB','RMB','Ramsbottom','Ramsbottom','GTM'),('GB','RMF','Romford','Romford','GTL'),('GB','RMG','Ramsgate','Ramsgate','KEN'),('GB','RML','Ramsdell','Ramsdell','HAM'),('GB','RMS','Romsey','Romsey','HAM'),('GB','RMY','Redmarley D\'Abitot','Redmarley D\'Abitot','GLS'),('GB','RNA','Rainham','Rainham','KEN'),('GB','RNG','Rustington','Rustington','WSX'),('GB','RNS','Ranskill','Ranskill','NTT'),('GB','RNT','Radcliffe on Trent','Radcliffe on Trent','NTT'),('GB','RNW','Ross-on-wye','Ross-on-wye','HWR'),('GB','ROA','Roade','Roade','NTH'),('GB','ROG','Rogerstone','Rogerstone','NWP'),('GB','ROH','Roche','Roche','CON'),('GB','ROL','Rochdale','Rochdale','GTM'),('GB','ROM','Romney Marsh','Romney Marsh','KEN'),('GB','ROS','Royston','Royston','HRT'),('GB','ROT','Rothes','Rothes','GMP'),('GB','ROW','Rowhedge','Rowhedge','ESS'),('GB','ROY','Rosyth','Rosyth','LTN'),('GB','RPP','Ripponden','Ripponden','WYK'),('GB','RPY','Ripley','Ripley','DBY'),('GB','RRS','Henstridge','Henstridge','SOM'),('GB','RRU','Redruth','Redruth','CON'),('GB','RSC','Risca','Risca','GNT'),('GB','RSG','Rushlake Green','Rushlake Green','ESX'),('GB','RSH','Rosneath','Rosneath','AGB'),('GB','RSK','Radstock','Radstock','BAS'),('GB','RSN','Rushton','Rushton','CHS'),('GB','RSS','Ross','Ross','DGY'),('GB','RSY','Ramsey','Ramsey','CAM'),('GB','RTH','Rotherham','Rotherham','SYK'),('GB','RTN','Royton','Royton','GTM'),('GB','RTO','Rettendon','Rettendon','ESS'),('GB','RTR','Rotherfield','Rotherfield','ESX'),('GB','RUD','Raunds','Raunds','NTH'),('GB','RUG','Rugby','Rugby','WAR'),('GB','RUH','Rushock','Rushock','HEF'),('GB','RUI','Ruislip','Ruislip','GTL'),('GB','RUK','Rushock','Rushock','WOR'),('GB','RUN','Runcorn','Runcorn','CHS'),('GB','RUS','Rushden','Rushden','NTH'),('GB','RUT','Rutherglen','Rutherglen','STD'),('GB','RUW','Ruabon','Ruabon','CWD'),('GB','RWE','Rowledge','Rowledge','SRY'),('GB','RWL','Rosewell','Rosewell','MLN'),('GB','RYD','Ryde','Ryde','IOW'),('GB','RYE','Rye','Rye','ESX'),('GB','RYN','Ryton','Ryton','GAT'),('GB','RYR','Rowley Regis','Rowley Regis','WMD'),('GB','RYY','Rhymney','Rhymney','MGM'),('GB','SAB','Sabden','Sabden','LAN'),('GB','SAE','Sale','Sale','GTM'),('GB','SAF','Stanford le Hope','Stanford le Hope','THR'),('GB','SAH','Standish','Standish','GTM'),('GB','SAJ','Sanquhar','Sanquhar','DGY'),('GB','SAK','Stocklake','Stocklake','BKM'),('GB','SAL','Saltby','Saltby','LEC'),('GB','SAM','Samlesbury','Samlesbury','LAN'),('GB','SAN','Sandbach','Sandbach','CHS'),('GB','SAO','Stratton','Stratton',''),('GB','SAS','Sawston','Sawston','CAM'),('GB','SAT','Saltash','Saltash','CON'),('GB','SAV','Stratford-upon-Avon','Stratford-upon-Avon','WAR'),('GB','SAW','Saffron Walden','Saffron Walden','ESS'),('GB','SAX','Saxham','Saxham','SFK'),('GB','SAY','Swanley','Swanley','KEN'),('GB','SBC','Severn Beach','Severn Beach','SGC'),('GB','SBD','Stockbridge','Stockbridge','HAM'),('GB','SBF','South Benfleet','South Benfleet','ESS'),('GB','SBG','Stocksbridge','Stocksbridge','SYK'),('GB','SBH','Sible Hedingham','Sible Hedingham','BDF'),('GB','SBK','Scarisbrick','Scarisbrick','LAN'),('GB','SBO','Sutton Bonnington','Sutton Bonnington','NTT'),('GB','SBR','Shrewsbury','Shrewsbury','SHR'),('GB','SBT','Stubbington','Stubbington','HAM'),('GB','SBW','Newtown St Boswells','Newtown St Boswells','SCB'),('GB','SBY','Sunbury','Sunbury','SRY'),('GB','SCA','Scarborough','Scarborough','NYK'),('GB','SCB','Salcombe','Salcombe','DVV'),('GB','SCE','Shenley Church End','Shenley Church End',''),('GB','SCK','Stockton','Stockton','SHR'),('GB','SCL','St Clears','St Clears','DFD'),('GB','SCP','Scunthorpe','Scunthorpe','HUM'),('GB','SCR','Scrabster','Scrabster','HLD'),('GB','SCS','Scatsta','Scatsta',''),('GB','SCT','Stockton','Stockton','HWR'),('GB','SCY','Stirchley','Stirchley','SHR'),('GB','SDA','Studham','Studham','BDF'),('GB','SDC','Sidcup','Sidcup','GTL'),('GB','SDG','Stourbridge','Stourbridge','WMD'),('GB','SDI','Sandiacre','Sandiacre','DBY'),('GB','SDK','Stradbroke','Stradbroke','SFK'),('GB','SDL','Snodland','Snodland','KEN'),('GB','SDM','Sidmouth','Sidmouth',''),('GB','SDN','Shildon','Shildon','DUR'),('GB','SDR','Sanderstead','Sanderstead','GTL'),('GB','SDV','Seaton Delaval','Seaton Delaval','NBL'),('GB','SDW','Sandwich','Sandwich','KEN'),('GB','SDX','Stroud','Stroud','GLS'),('GB','SDY','Sandy','Sandy','BDF'),('GB','SEA','Seaham','Seaham','DUR'),('GB','SED','Salt End','Salt End','HUM'),('GB','SEE','Seamer','Seamer','NYK'),('GB','SEF','Seaforth','Seaforth','MSY'),('GB','SEH','Sedbergh','Sedbergh','CMA'),('GB','SEN','Southend Municipal Apt','Southend Municipal Apt','ESS'),('GB','SEO','Selsdon','Selsdon','GTL'),('GB','SET','Settle','Settle','NYK'),('GB','SEV','Sevenoaks','Sevenoaks','KEN'),('GB','SEY','Semley','Semley','WIL'),('GB','SFD','Stretford','Stretford','GTM'),('GB','SFE','Stoke Ferry','Stoke Ferry','NFK'),('GB','SFL','Stotfold','Stotfold','HRT'),('GB','SFO','Stapleford','Stapleford','NTT'),('GB','SFR','Seaford','Seaford','ESX'),('GB','SFT','Sandford On Thames','Sandford On Thames','OXF'),('GB','SFV','Stanford in the Vale','Stanford in the Vale','OXF'),('GB','SFW','Scapa Flow','Scapa Flow','ORK'),('GB','SFY','Salford','Salford','GTM'),('GB','SGD','Sunningdale','Sunningdale','WNM'),('GB','SGE','Sedgefield','Sedgefield','DUR'),('GB','SGF','Shillingford','Shillingford','OXF'),('GB','SGH','Seighford','Seighford','STS'),('GB','SGL','Sunninghill','Sunninghill','SRY'),('GB','SGY','South Gyle','South Gyle','EDH'),('GB','SHA','Shrivenham','Shrivenham','OXF'),('GB','SHB','Shaftesbury','Shaftesbury','DOR'),('GB','SHC','Stinchcombe','Stinchcombe','GLS'),('GB','SHD','South Darenth','South Darenth','KEN'),('GB','SHE','Sheffield','Sheffield','SYK'),('GB','SHF','Shefford','Shefford','BDF'),('GB','SHG','South Hayling','South Hayling','HAM'),('GB','SHH','Shipdham','Shipdham','NFK'),('GB','SHI','Shipley','Shipley','WYK'),('GB','SHK','Southwick','Southwick','WSX'),('GB','SHL','Shenfield','Shenfield','ESS'),('GB','SHM','Shepton Mallet','Shepton Mallet','SOM'),('GB','SHO','Shoreham','Shoreham','KEN'),('GB','SHP','Shepherds Bush','Shepherds Bush','GTL'),('GB','SHQ','South Heighton','South Heighton','ESX'),('GB','SHR','Sherborne','Sherborne','DOR'),('GB','SHS','Sheerness','Sheerness','KEN'),('GB','SHT','Shotton','Shotton','CWD'),('GB','SHV','Shell Haven','Shell Haven','ESS'),('GB','SHW','Shaw','Shaw','GTM'),('GB','SHY','St Helens','St Helens','MSY'),('GB','SIG','Stirling','Stirling','STG'),('GB','SIK','Southwick','Southwick','WIL'),('GB','SIL','Silloth','Silloth','CMA'),('GB','SIN','Singleton','Singleton','LAN'),('GB','SIT','Sittingbourne','Sittingbourne','KEN'),('GB','SIY','Shirley','Shirley','GTM'),('GB','SKD','Skelmersdale','Skelmersdale','LAN'),('GB','SKE','Skegness','Skegness','LIN'),('GB','SKG','Stoke Gifford','Stoke Gifford','SGC'),('GB','SKH','Stokenchurch','Stokenchurch','BKM'),('GB','SKI','Skipton','Skipton','NYK'),('GB','SKL','Skelton','Skelton','HUM'),('GB','SKY','Isle of Skye Apt','Isle of Skye Apt',''),('GB','SLA','St Leonards','St Leonards','ESX'),('GB','SLB','Selby','Selby','NYK'),('GB','SLC','Saltcoats','Saltcoats','STD'),('GB','SLD','Stockland','Stockland',''),('GB','SLE','Sleaford','Sleaford','LIN'),('GB','SLF','Shelf','Shelf','WYK'),('GB','SLG','Stallingborough','Stallingborough','HUM'),('GB','SLH','Stanford-le-Hope','Stanford-le-Hope','THR'),('GB','SLI','Slinfold','Slinfold','WSX'),('GB','SLK','Shiplake','Shiplake','OXF'),('GB','SLL','Southall','Southall','GTL'),('GB','SLN','Saltburn-by-the-Sea','Saltburn-by-the-Sea','CLV'),('GB','SLO','Slough','Slough','SLG'),('GB','SLR','Silchester','Silchester','HAM'),('GB','SLS','Salisbury','Salisbury','WIL'),('GB','SLT','Saltney','Saltney','CHS'),('GB','SLW','Slawston','Slawston','LEC'),('GB','SLY','Sileby','Sileby','LEC'),('GB','SMB','Somersby','Somersby','LIN'),('GB','SMD','Small Dole','Small Dole','WSX'),('GB','SME','Smethwick','Smethwick','WMD'),('GB','SMI','South Mimms','South Mimms','HRT'),('GB','SML','Stramshall','Stramshall','STS'),('GB','SMN','St Martin','St Martin','CON'),('GB','SMO','Simonstone','Simonstone','LAN'),('GB','SMR','Somerton','Somerton','SOM'),('GB','SMS','South Marston','South Marston','WIL'),('GB','SMW','Simonswood','Simonswood','MSY'),('GB','SNB','Sutton Benger','Sutton Benger','WIL'),('GB','SND','Southend','Southend','ESS'),('GB','SNE','Stoke Newington','Stoke Newington','GTL'),('GB','SNF','Sandycroft','Sandycroft','CWD'),('GB','SNG','Singleton','Singleton','WSX'),('GB','SNH','Stanton Harcourt','Stanton Harcourt','OXF'),('GB','SNL','Stanley','Stanley','DUR'),('GB','SNM','Stanmore','Stanmore','WBK'),('GB','SNN','Swindon','Swindon','WIL'),('GB','SNO','South Normanton','South Normanton','DBY'),('GB','SNR','South Norwood','South Norwood','GTL'),('GB','SNS','Stromness','Stromness','ORK'),('GB','SNT','St Neots','St Neots','CAM'),('GB','SNW','St Andrews','St Andrews','FIF'),('GB','SNY','Stoke by Nayland','Stoke by Nayland','SFK'),('GB','SOB','Southborough','Southborough','KEN'),('GB','SOD','Stapleford','Stapleford','CAM'),('GB','SOE','Stoke','Stoke','WMD'),('GB','SOF','Southfleet','Southfleet','KEN'),('GB','SOH','Southam','Southam','WAR'),('GB','SOK','South Kirkby','South Kirkby','WYK'),('GB','SOL','Solihull','Solihull','WMD'),('GB','SOM','Somercotes','Somercotes','DBY'),('GB','SON','Standon','Standon','STS'),('GB','SOO','South Ockendon','South Ockendon','ESS'),('GB','SOP','Stanhope','Stanhope','BOR'),('GB','SOQ','South Queensferry','South Queensferry','LTN'),('GB','SOR','Stourton','Stourton','WIL'),('GB','SOS','St Osyth','St Osyth','ESS'),('GB','SOT','Stoke on Trent','Stoke on Trent','STS'),('GB','SOU','Southampton','Southampton','HAM'),('GB','SOW','Stanlow','Stanlow','CHS'),('GB','SOX','Stanton','Stanton','SFK'),('GB','SOY','Stronsay','Stronsay',''),('GB','SPA','Spalding','Spalding','LIN'),('GB','SPB','Steeple Bumpstead','Steeple Bumpstead','ESS'),('GB','SPD','Shepshed','Shepshed','LEC'),('GB','SPE','Spellbrook','Spellbrook','HRT'),('GB','SPF','Stapleford','Stapleford','WIL'),('GB','SPG','Stoke Poges','Stoke Poges','BKM'),('GB','SPH','St Asaph','St Asaph','CWD'),('GB','SPK','Speke','Speke','MSY'),('GB','SPL','Stapleton','Stapleton','LEC'),('GB','SPM','Shipham','Shipham','SOM'),('GB','SPN','Spennymoor','Spennymoor','DUR'),('GB','SPO','Spondon','Spondon','DBY'),('GB','SPP','Shepperton','Shepperton','SRY'),('GB','SPR','Sparkford','Sparkford','SOM'),('GB','SPS','Stourport on Severn','Stourport on Severn','HWR'),('GB','SPT','St Peter Port','St Peter Port','GSY'),('GB','SPU','Sherbourne','Sherbourne','WAR'),('GB','SPW','Spencers Wood','Spencers Wood','WOK'),('GB','SPY','Shapinsay','Shapinsay','ORK'),('GB','SQN','Sonning','Sonning','WOK'),('GB','SQZ','Scampton','Scampton','LIN'),('GB','SRD','Stafford','Stafford','STS'),('GB','SRF','Seacroft','Seacroft','NYK'),('GB','SRN','Storrington','Storrington','WSX'),('GB','SRS','Sherston','Sherston','WIL'),('GB','SRT','Southport','Southport','MSY'),('GB','SSA','Stanstead Abbots','Stanstead Abbots','HRT'),('GB','SSC','Seascale','Seascale','CMA'),('GB','SSD','Silsden','Silsden','WYK'),('GB','SSG','Sissinghurst','Sissinghurst','KEN'),('GB','SSH','South Shields','South Shields','TWR'),('GB','SSJ','Sutton St James','Sutton St James','LIN'),('GB','SSN','Stevenston','Stevenston','STD'),('GB','SSS','Sharpness','Sharpness','GLS'),('GB','SST','Shenstone','Shenstone','STS'),('GB','SSY','Selsey','Selsey','WSX'),('GB','STA','Southwater','Southwater','WSX'),('GB','STB','Strabane','Strabane','STB'),('GB','STC','South Cave','South Cave','HUM'),('GB','STD','Strood','Strood','KEN'),('GB','STE','Street','Street','SOM'),('GB','STF','Stratford','Stratford','GTL'),('GB','STG','Seething','Seething','NFK'),('GB','STH','St Helier','St Helier','JSY'),('GB','STI','St Ives','St Ives','CAM'),('GB','STJ','Stoneleigh','Stoneleigh','WAR'),('GB','STK','Stockport','Stockport','GTM'),('GB','STL','St Austell','St Austell','CON'),('GB','STM','Stanmore','Stanmore','GTL'),('GB','STN','Stansted Apt/London','Stansted Apt/London','ESS'),('GB','STO','Stornoway','Stornoway','WIS'),('GB','STP','Staple Hill','Staple Hill','SGC'),('GB','STQ','St Quivox','St Quivox','SAY'),('GB','STR','Stranraer','Stranraer','DGY'),('GB','STS','Staines','Staines','SRY'),('GB','STT','Stockton-on-Tees','Stockton-on-Tees','CLV'),('GB','STU','Studley','Studley','WAR'),('GB','STV','Stevenage','Stevenage','HRT'),('GB','STW','Stowmarket','Stowmarket','SFK'),('GB','STX','Stone','Stone','STS'),('GB','STY','Stalybridge','Stalybridge','GTM'),('GB','SUA','Sutton in Ashfield','Sutton in Ashfield','NTT'),('GB','SUB','Sandhurst','Sandhurst','BRC'),('GB','SUC','Sutton Coldfield','Sutton Coldfield','WMD'),('GB','SUD','Sudbury','Sudbury','SFK'),('GB','SUH','Spurn Head','Spurn Head',''),('GB','SUL','Sullom Voe','Sullom Voe','ZET'),('GB','SUN','Sunderland','Sunderland','TWR'),('GB','SUR','Surbiton','Surbiton','GTL'),('GB','SUS','Sutton','Sutton','GTL'),('GB','SUT','South Arne','South Arne',''),('GB','SUU','Soulbury','Soulbury','BKM'),('GB','SUW','Southowram','Southowram','CLD'),('GB','SUY','Sully','Sully','SGM'),('GB','SVE','Silverton','Silverton',''),('GB','SVK','Seven Kings','Seven Kings','GTL'),('GB','SVN','Stonehaven','Stonehaven','GMP'),('GB','SVR','Staverton','Staverton','WIL'),('GB','SVT','Silvertown','Silvertown',''),('GB','SWA','Swansea','Swansea','WGM'),('GB','SWB','Swanscombe','Swanscombe','KEN'),('GB','SWD','Southwold','Southwold','SFK'),('GB','SWF','South Woodham Ferrers','South Woodham Ferrers','ESS'),('GB','SWH','Swaffham','Swaffham',''),('GB','SWK','Swanwick','Swanwick','HAM'),('GB','SWL','Stanwell','Stanwell','SRY'),('GB','SWM','Swanmore','Swanmore','HAM'),('GB','SWN','Swinton','Swinton','GTM'),('GB','SWO','South Weston','South Weston','OXF'),('GB','SWR','Southwark','Southwark','GTL'),('GB','SWW','Sawbridgeworth','Sawbridgeworth','HRT'),('GB','SWY','Scalloway','Scalloway','ZET'),('GB','SXM','Saxmundham','Saxmundham','SFK'),('GB','SXN','Steventon','Steventon','HAM'),('GB','SXX','Seal','Seal','KEN'),('GB','SXY','Shipley','Shipley','WSX'),('GB','SYB','Sowerby Bridge','Sowerby Bridge','YOR'),('GB','SYC','Sayers Common','Sayers Common','WSX'),('GB','SYD','Stoneywood','Stoneywood','ABE'),('GB','SYG','Steyning','Steyning','WSX'),('GB','SYM','Symbister','Symbister','ZET'),('GB','SYN','Shoeburyness','Shoeburyness','ESS'),('GB','SYO','Stony Middleton','Stony Middleton','DBY'),('GB','SYS','Syston','Syston','LEC'),('GB','SYW','Sywell','Sywell','NTH'),('GB','SZM','Soham','Soham','CAM'),('GB','TAB','Tarbert','Tarbert','WIS'),('GB','TAF','Stamford','Stamford','LIN'),('GB','TAL','Theale','Theale','WBK'),('GB','TAS','Tavistock','Tavistock',''),('GB','TAU','Taunton','Taunton','SOM'),('GB','TAV','Taverham','Taverham','NFK'),('GB','TAW','Tamworth','Tamworth','STS'),('GB','TAY','Tayport','Tayport','FIF'),('GB','TBA','Tebay','Tebay','CMA'),('GB','TBB','Thornbury','Thornbury','SGC'),('GB','TBG','Trowbridge','Trowbridge','WIL'),('GB','TBL','St Albans','St Albans','HRT'),('GB','TBS','Tibshelf','Tibshelf','DBY'),('GB','TCH','Ticehurst','Ticehurst','ESX'),('GB','TDD','Teddington','Teddington','GTL'),('GB','TDG','Tandragee','Tandragee','ARM'),('GB','TDM','Todmorden','Todmorden','WYK'),('GB','TDN','Toddington','Toddington','BDF'),('GB','TDR','Tredegar','Tredegar','GNT'),('GB','TDS','Tadcaster','Tadcaster','NYK'),('GB','TDT','Thames Ditton','Thames Ditton','SRY'),('GB','TDW','Tadworth','Tadworth','SRY'),('GB','TDY','Tadley','Tadley','HAM'),('GB','TEB','Tewkesbury','Tewkesbury','GLS'),('GB','TEE','Teesport','Teesport','CLV'),('GB','TEF','Telford','Telford','SHR'),('GB','TET','Tetbury','Tetbury','GLS'),('GB','TFD','Thetford','Thetford','NFK'),('GB','TFF','Trottiscliffe','Trottiscliffe','KEN'),('GB','TFK','Trafford Park','Trafford Park','MAN'),('GB','TFO','Tilford','Tilford','SRY'),('GB','TFR','Trefforest','Trefforest','MGM'),('GB','TFW','Taff\'s Well','Taff\'s Well','MGM'),('GB','THA','Thatcham','Thatcham','WBK'),('GB','THB','Thornbridge','Thornbridge','DBY'),('GB','THC','Three Legged Cross','Three Legged Cross','DOR'),('GB','THE','Thame','Thame','OXF'),('GB','THH','Thornton Heath','Thornton Heath','GTL'),('GB','THL','Tilton on the Hill','Tilton on the Hill','LEC'),('GB','THM','Topsham','Topsham',''),('GB','THN','Thornton','Thornton','LAN'),('GB','THO','Thormanby','Thormanby','NYK'),('GB','THP','Thamesport','Thamesport','KEN'),('GB','THR','Thurso','Thurso','HLD'),('GB','THS','Thames Haven','Thames Haven','ESS'),('GB','THY','Thorney','Thorney','PTE'),('GB','TIC','Tickhill','Tickhill','SYK'),('GB','TID','Titchfield','Titchfield','HAM'),('GB','TIL','Tilbury','Tilbury','ESS'),('GB','TIM','Timsbury','Timsbury','BAS'),('GB','TIP','Tiptree','Tiptree','ESS'),('GB','TKG','Throcking','Throcking','HRT'),('GB','TKL','Tankersley','Tankersley','BNS'),('GB','TKM','Tickenham','Tickenham','NSM'),('GB','TKW','Tockwith','Tockwith','NYK'),('GB','TKY','Takeley','Takeley','ESS'),('GB','TLB','Tullibody','Tullibody','CLK'),('GB','TLG','Tylers Green','Tylers Green','BKM'),('GB','TLH','Thurleigh','Thurleigh','BDF'),('GB','TLQ','Totton','Totton','HAM'),('GB','TLW','Taplow','Taplow','BKM'),('GB','TLY','Trimley Heath','Trimley Heath','SFK'),('GB','TMS','Thurmaston','Thurmaston','LEC'),('GB','TNB','Tonbridge','Tonbridge','KEN'),('GB','TNL','Tunstall','Tunstall','STS'),('GB','TNM','Teignmouth','Teignmouth',''),('GB','TNT','Tranent','Tranent','LTN'),('GB','TOA','Tomatin','Tomatin','HLD'),('GB','TOB','Tobermory','Tobermory','STD'),('GB','TOE','Thorne','Thorne','SYK'),('GB','TOF','Toft','Toft','LIN'),('GB','TOL','Tollesbury','Tollesbury','ESS'),('GB','TOM','Tolleshunt D\'Arcy','Tolleshunt D\'Arcy','ESS'),('GB','TON','Livingston','Livingston','LTN'),('GB','TOO','Toomebridge','Toomebridge','ANT'),('GB','TOR','Torquay','Torquay',''),('GB','TOT','Thornaby on Tees','Thornaby on Tees','CLV'),('GB','TOW','Towcester','Towcester','NTH'),('GB','TPC','Templecombe','Templecombe','SOM'),('GB','TPH','Torphichen','Torphichen','LTN'),('GB','TPI','Torphins','Torphins','GMP'),('GB','TPL','Tarporley','Tarporley','CHS'),('GB','TPN','Tipton','Tipton','WMD'),('GB','TPO','Torpoint','Torpoint','CON'),('GB','TPP','Thrupp','Thrupp','GLS'),('GB','TPS','Thrapston','Thrapston','NTH'),('GB','TPT','Tupton','Tupton','DBY'),('GB','TRA','Tranmere','Tranmere','MSY'),('GB','TRE','Tiree','Tiree',''),('GB','TRF','Turriff','Turriff','ABD'),('GB','TRG','Tregaron','Tregaron','CGN'),('GB','TRH','Treherbert','Treherbert','MGM'),('GB','TRI','Tring','Tring','HRT'),('GB','TRK','Thurrock','Thurrock','ESS'),('GB','TRL','Thornhill','Thornhill','DBY'),('GB','TRM','Thornham','Thornham','NFK'),('GB','TRN','Troon','Troon','STD'),('GB','TRU','Truro','Truro','CON'),('GB','TRW','Trelawnyd','Trelawnyd','CWD'),('GB','TRY','Treorchy','Treorchy','MGM'),('GB','TSE','Tunstead','Tunstead','NFK'),('GB','TSK','Thirsk','Thirsk','NYK'),('GB','TSM','Tivertshall St Margaret','Tivertshall St Margaret','NFK'),('GB','TSO','Tresco','Tresco','IOS'),('GB','TSW','Tilsworth','Tilsworth','BDF'),('GB','TSY','Tisbury','Tisbury','WIL'),('GB','TTD','Tenterden','Tenterden','KEN'),('GB','TTF','Tatsfield','Tatsfield','SRY'),('GB','TTH','Tattenhall','Tattenhall','CHS'),('GB','TTL','Tetney Terminal','Tetney Terminal','HUM'),('GB','TTO','Tillington','Tillington','HEF'),('GB','TTR','Totteridge','Totteridge','GTL'),('GB','TTS','Totnes','Totnes',''),('GB','TTT','Tottenham','Tottenham','GTL'),('GB','TTY','Trinity','Trinity','JSY'),('GB','TUF','Cuffley','Cuffley','HRT'),('GB','TUT','Tutbury','Tutbury','STS'),('GB','TUW','Tunbridge Wells','Tunbridge Wells','KEN'),('GB','TUX','Tuxford','Tuxford','NTT'),('GB','TVD','Tividale','Tividale','DUD'),('GB','TVH','Teversham','Teversham','CAM'),('GB','TVL','Tovil','Tovil','KEN'),('GB','TVN','Tiverton','Tiverton',''),('GB','TWC','Twickenham','Twickenham','GTL'),('GB','TWD','Trawden','Trawden','LAN'),('GB','TWF','Twyford','Twyford','WOK'),('GB','TWL','Tingwall','Tingwall','ZET'),('GB','TWM','Thornwood Common','Thornwood Common','HRT'),('GB','TWO','Tawstock','Tawstock','DVV'),('GB','TWT','Tolworth','Tolworth','GTL'),('GB','TWW','Tow Law','Tow Law','DUR'),('GB','TWY','Twyford','Twyford','BKM'),('GB','TXD','Thaxted','Thaxted','ESS'),('GB','TYH','Teynham','Teynham','KEN'),('GB','TYL','Tyldesley','Tyldesley','GTM'),('GB','TYM','Tynemouth','Tynemouth','TWR'),('GB','TYW','Tenbury Wells','Tenbury Wells','HWR'),('GB','TYY','Tyseley','Tyseley','BIR'),('GB','UCK','Uckfield','Uckfield','ESX'),('GB','UDD','Uddingston','Uddingston','STD'),('GB','UFC','Uffculme','Uffculme','DEV'),('GB','UFG','Uffington','Uffington','OXF'),('GB','UFY','Upper Froyle','Upper Froyle','HAM'),('GB','UHD','Upper Hartfield','Upper Hartfield','ESX'),('GB','UHF','Upper Heyford','Upper Heyford','OXF'),('GB','UIG','Uig','Uig','HLD'),('GB','ULL','Ullapool','Ullapool','HLD'),('GB','ULN','Urlay Nook','Urlay Nook','CLV'),('GB','ULV','Ulverston','Ulverston','CMA'),('GB','UNT','Unst','Unst','ZET'),('GB','UPD','Upper Dicker','Upper Dicker','ESX'),('GB','UPL','Upper Poppleton','Upper Poppleton','YOR'),('GB','UPM','Upminster','Upminster','GTL'),('GB','UPO','Upton','Upton','WKF'),('GB','UPP','Upper Dean','Upper Dean','BDF'),('GB','UPS','Upshire','Upshire','ESS'),('GB','UPT','Upton','Upton','SLG'),('GB','UPV','Upavon','Upavon','WIL'),('GB','UPW','Upwood','Upwood','CAM'),('GB','URL','Lurgan','Lurgan','ARM'),('GB','URS','Urmston','Urmston','GTM'),('GB','URY','Hurley','Hurley','WAR'),('GB','USK','Usk','Usk','MON'),('GB','UTN','Upton','Upton','CHS'),('GB','UTX','Uttoxeter','Uttoxeter','STS'),('GB','UUR','Hurn','Hurn','DOR'),('GB','UXB','Uxbridge','Uxbridge','GTL'),('GB','VAL','Vale of Leven','Vale of Leven','WDU'),('GB','VEM','Fivemiletown','Fivemiletown','DGN'),('GB','VER','Verwood','Verwood','DOR'),('GB','VGI','Varg field','Varg field',''),('GB','VGN','Virginia Water','Virginia Water','SRY'),('GB','VOB','Vobster','Vobster','SOM'),('GB','WAA','Watlington','Watlington','NFK'),('GB','WAB','Wadebridge','Wadebridge','CON'),('GB','WAC','Waltham Cross','Waltham Cross','HRT'),('GB','WAF','Watford','Watford','HRT'),('GB','WAK','Wakes Colne','Wakes Colne','ESS'),('GB','WAL','Walsall','Walsall','WMD'),('GB','WAM','Warminster','Warminster','WIL'),('GB','WAN','Wandsworth','Wandsworth','GTL'),('GB','WAO','Wallington','Wallington','STN'),('GB','WAR','Ware','Ware','HRT'),('GB','WAT','Watchet','Watchet','SOM'),('GB','WAU','Walkerburn','Walkerburn','BOR'),('GB','WAV','Watford Village','Watford Village',''),('GB','WAW','Warwick','Warwick','CMA'),('GB','WAY','Wallasey','Wallasey','MSY'),('GB','WBC','Wombourne','Wombourne','STS'),('GB','WBD','Wimbledon','Wimbledon','GTL'),('GB','WBE','Waterbeach','Waterbeach','CAM'),('GB','WBG','Woodbridge','Woodbridge','SFK'),('GB','WBH','Wimbish','Wimbish','ESS'),('GB','WBL','Wimblington','Wimblington','CAM'),('GB','WBN','Woburn','Woburn','BDF'),('GB','WBO','Walberton','Walberton','WSX'),('GB','WBR','Weybridge','Weybridge','SRY'),('GB','WBT','West Byfleet','West Byfleet','SRY'),('GB','WBU','Whitburn','Whitburn','LTN'),('GB','WBW','Wombwell','Wombwell','SYK'),('GB','WBY','Wembley','Wembley','GTL'),('GB','WCF','Witchford','Witchford','CAM'),('GB','WCH','Wincham','Wincham','CHS'),('GB','WCK','Wick','Wick','SGC'),('GB','WCO','Westcott','Westcott','SRY'),('GB','WCT','Wincanton','Wincanton','SOM'),('GB','WCU','Whitchurch','Whitchurch','SOM'),('GB','WCW','West Challow','West Challow','OXF'),('GB','WDA','Woodhall','Woodhall','NYK'),('GB','WDD','Waddington','Waddington','LAN'),('GB','WDE','Woodley','Woodley','WBK'),('GB','WDH','Woodhall Spa','Woodhall Spa','LIN'),('GB','WDL','Windlesham','Windlesham','SRY'),('GB','WDM','Windermere','Windermere','CMA'),('GB','WDN','Widnes','Widnes','CHS'),('GB','WDO','Wendover','Wendover','BKM'),('GB','WDR','West Drayton','West Drayton','GTL'),('GB','WDS','Woodstock','Woodstock','OXF'),('GB','WDW','Woodnewton','Woodnewton','NTH'),('GB','WEA','Wealdstone','Wealdstone','GTL'),('GB','WEB','West Bromwich','West Bromwich','WMD'),('GB','WED','Wednesbury','Wednesbury','WMD'),('GB','WEE','Weedon','Weedon','BKM'),('GB','WEF','Wednesfield','Wednesfield','WMD'),('GB','WEG','Welling','Welling','BEX'),('GB','WEH','Winchmore Hill','Winchmore Hill','BKM'),('GB','WEL','Wellingborough','Wellingborough','NTH'),('GB','WEM','Welham Green','Welham Green','HRT'),('GB','WEN','West End','West End','HAM'),('GB','WEQ','Westcott','Westcott',''),('GB','WER','Westerham','Westerham','KEN'),('GB','WES','Weston','Weston','HRT'),('GB','WET','Wetherby','Wetherby','WYK'),('GB','WEW','Wentworth','Wentworth','SRY'),('GB','WEY','Weymouth','Weymouth','DOR'),('GB','WFD','Wakefield','Wakefield','WYK'),('GB','WFE','Whitfield','Whitfield','KEN'),('GB','WFI','Westfield','Westfield',''),('GB','WFL','Warfield','Warfield','BRC'),('GB','WFO','Westcliffe on Sea','Westcliffe on Sea','ESS'),('GB','WFV','Weston Favell','Weston Favell','NTH'),('GB','WGC','Welwyn Garden City','Welwyn Garden City','HRT'),('GB','WGE','Wantage','Wantage','OXF'),('GB','WGF','West Bridgford','West Bridgford','NTT'),('GB','WGH','Wingham','Wingham','KEN'),('GB','WGN','Wigan','Wigan','GTM'),('GB','WGO','Little Weighton','Little Weighton','HUM'),('GB','WGS','Wigston','Wigston','LEC'),('GB','WGT','Wigton','Wigton','CMA'),('GB','WGV','Wargrave','Wargrave','WOK'),('GB','WHA','Whatton','Whatton','NTT'),('GB','WHB','Whitebooth Roads','Whitebooth Roads',''),('GB','WHC','Whitchurch','Whitchurch','SHR'),('GB','WHE','Whitehead','Whitehead','CKF'),('GB','WHF','Wethersfield','Wethersfield','ESS'),('GB','WHG','Washington','Washington','WSX'),('GB','WHI','Whitland','Whitland','DFD'),('GB','WHM','Wetherden','Wetherden','SFK'),('GB','WHN','West Hanney','West Hanney','OXF'),('GB','WHO','West Horndon','West Horndon','ESS'),('GB','WHP','Wheathampstead','Wheathampstead','HRT'),('GB','WHS','Walthamstow','Walthamstow','GTL'),('GB','WHT','Whitton','Whitton','NBL'),('GB','WHU','Woodhurst','Woodhurst','CAM'),('GB','WHV','Whitehaven','Whitehaven','CMA'),('GB','WHW','Wishaw','Wishaw','STD'),('GB','WHY','Whalsay','Whalsay',''),('GB','WIB','Winchcombe','Winchcombe','GLS'),('GB','WIC','Wick','Wick','HLD'),('GB','WID','Wickford','Wickford','ESS'),('GB','WIE','Wiltshire','Wiltshire','WIL'),('GB','WIF','Winsford','Winsford','CHS'),('GB','WIG','Wigtown','Wigtown','DGY'),('GB','WIH','Witham','Witham','ESS'),('GB','WII','Willen','Willen','BKM'),('GB','WIL','Willand','Willand',''),('GB','WIM','Wimborne Minster','Wimborne Minster','DOR'),('GB','WIN','Witney','Witney','OXF'),('GB','WIR','Wirksworth','Wirksworth','DBY'),('GB','WIS','Wisbech','Wisbech','CAM'),('GB','WIV','Wivenhoe','Wivenhoe','ESS'),('GB','WIX','Wix','Wix','ESS'),('GB','WIZ','Wilton','Wilton','CLV'),('GB','WJV','Walgrave','Walgrave','NTH'),('GB','WKB','West Kilbride','West Kilbride','STD'),('GB','WKD','Walkden','Walkden','GTM'),('GB','WKE','Wyke','Wyke','WYK'),('GB','WKF','Winkfield','Winkfield','BRC'),('GB','WKG','Woking','Woking','SRY'),('GB','WKI','West Kirby','West Kirby','MSY'),('GB','WKL','Winkleigh','Winkleigh',''),('GB','WKM','Wickham','Wickham','HAM'),('GB','WKN','Walkern','Walkern','HRT'),('GB','WKO','Warkworth','Warkworth','NBL'),('GB','WKS','West Kingsdown','West Kingsdown','KEN'),('GB','WLA','Wallasea','Wallasea','ESS'),('GB','WLB','Welbury','Welbury','NYK'),('GB','WLC','Waltham Chase','Waltham Chase','HAM'),('GB','WLD','Welford','Welford','NTH'),('GB','WLE','Walton-on-Thames','Walton-on-Thames','SRY'),('GB','WLF','Wallingford','Wallingford','OXF'),('GB','WLL','Willenhall','Willenhall','WMD'),('GB','WLN','Welwyn','Welwyn','HRT'),('GB','WLO','Walton','Walton','DBY'),('GB','WLR','Wooler','Wooler','NBL'),('GB','WLS','Wells','Wells','SOM'),('GB','WLT','Wilton','Wilton','WIL'),('GB','WLV','Waterlooville','Waterlooville','HAM'),('GB','WLW','Woolwich','Woolwich','GTL'),('GB','WLY','Warley','Warley',''),('GB','WMB','Wemyss Bay','Wemyss Bay','STD'),('GB','WMF','Walmer','Walmer','KEN'),('GB','WMG','Woolmer Green','Woolmer Green','HRT'),('GB','WMH','Worminghall','Worminghall','BKM'),('GB','WMK','Wickham Market','Wickham Market','SFK'),('GB','WML','West Malling','West Malling','KEN'),('GB','WMN','West Meon','West Meon','HAM'),('GB','WMS','West Mersea','West Mersea','ESS'),('GB','WMT','Wilmington','Wilmington','ESX'),('GB','WMV','Worth Matravers','Worth Matravers','DOR'),('GB','WMY','Warmley','Warmley','SGC'),('GB','WNB','Wootton Bassett','Wootton Bassett','WIL'),('GB','WNC','Wilnecote','Wilnecote','STS'),('GB','WNE','Winchester','Winchester','HAM'),('GB','WNF','Winchfield','Winchfield','HAM'),('GB','WNH','Warlingham','Warlingham','SRY'),('GB','WNN','Washington','Washington','TWR'),('GB','WNO','Winscombe','Winscombe','NSM'),('GB','WNR','Wem','Wem','SHR'),('GB','WNS','Wells-next-the-Sea','Wells-next-the-Sea','NFK'),('GB','WNT','Wellington','Wellington','SOM'),('GB','WNW','Winfrith Newburgh','Winfrith Newburgh','DOR'),('GB','WNY','Woodmansey','Woodmansey','HUM'),('GB','WNZ','Walton-on-the-Naze','Walton-on-the-Naze','ESS'),('GB','WOA','Welford on Avon','Welford on Avon','WAR'),('GB','WOB','Suttonheath','Suttonheath',''),('GB','WOC','Woodchester','Woodchester','GLS'),('GB','WOD','Woldingham','Woldingham','SRY'),('GB','WOE','Worle','Worle','NSM'),('GB','WOF','Woodford','Woodford','NTH'),('GB','WOG','Wood Green','Wood Green','GTL'),('GB','WOH','Woodford Halse','Woodford Halse','NTH'),('GB','WOI','Worthing','Worthing','NFK'),('GB','WOK','Wokingham','Wokingham','WOK'),('GB','WOL','North Woolwich','North Woolwich','GTL'),('GB','WON','Witton','Witton','NFK'),('GB','WOO','Worlington','Worlington','SFK'),('GB','WOR','Workington','Workington','CMA'),('GB','WOS','Woburn Sands','Woburn Sands','BKM'),('GB','WOT','Worthing','Worthing','WSX'),('GB','WOV','Wolverhampton','Wolverhampton','WMD'),('GB','WOX','Wardington','Wardington','OXF'),('GB','WOY','Woodbury','Woodbury',''),('GB','WOZ','Wollaston','Wollaston','NTH'),('GB','WPL','Whimple','Whimple',''),('GB','WPS','Welshpool','Welshpool','POW'),('GB','WPT','Warrenpoint','Warrenpoint','DOW'),('GB','WQL','Wellington','Wellington','HWR'),('GB','WQT','Welton','Welton','CMA'),('GB','WRA','Warnham','Warnham','WSX'),('GB','WRD','Woodford Green','Woodford Green','GTL'),('GB','WRE','Wardle','Wardle','CHS'),('GB','WRF','Waterford','Waterford','HEF'),('GB','WRG','Werrington','Werrington','CAM'),('GB','WRH','Wareham','Wareham','DOR'),('GB','WRK','Worksop','Worksop','NTT'),('GB','WRL','Warton','Warton','WAR'),('GB','WRN','Warrington','Warrington','CHS'),('GB','WRO','Wrotham','Wrotham','KEN'),('GB','WRS','Worsley','Worsley','GTM'),('GB','WRT','Warton','Warton','LAN'),('GB','WRY','Westray','Westray','ORK'),('GB','WSB','Wraysbury','Wraysbury','WNM'),('GB','WSD','Walsden','Walsden','WYK'),('GB','WSF','West Stafford','West Stafford','DOR'),('GB','WSL','Winslow','Winslow','BKM'),('GB','WSM','Weston-Super-Mare','Weston-Super-Mare','NSM'),('GB','WSN','Weston','Weston','STS'),('GB','WSO','Whetstone','Whetstone','LEC'),('GB','WSP','Weston Point','Weston Point','CHS'),('GB','WSR','Windsor','Windsor','WNM'),('GB','WSS','Warsash','Warsash','HAM'),('GB','WST','Woolston','Woolston','CHS'),('GB','WSW','Wilmslow','Wilmslow','CHS'),('GB','WSY','Westbury','Westbury','WIL'),('GB','WTB','Whitby','Whitby','NYK'),('GB','WTC','Whitchurch','Whitchurch',''),('GB','WTD','Wanstead','Wanstead','GTL'),('GB','WTF','Whittlesford','Whittlesford','CAM'),('GB','WTG','Westhoughton','Westhoughton','GTM'),('GB','WTH','Withnell','Withnell','LAN'),('GB','WTI','Westfield','Westfield','ESX'),('GB','WTL','Whitley Bay','Whitley Bay','TWR'),('GB','WTM','West Hallam','West Hallam','DBY'),('GB','WTN','Waddington','Waddington','LIN'),('GB','WTO','Water Orton','Water Orton','WAR'),('GB','WTR','Worcester','Worcester','HWR'),('GB','WTS','Whitstable','Whitstable','KEN'),('GB','WTT','Watton','Watton','NFK'),('GB','WTU','Winterbourne','Winterbourne','SGC'),('GB','WTW','Wallsend','Wallsend','TWR'),('GB','WTY','Witley','Witley','SRY'),('GB','WUD','Wath upon Dearne','Wath upon Dearne','SYK'),('GB','WUE','Wotton-under-Edge','Wotton-under-Edge','GLS'),('GB','WUG','Wooburn Green','Wooburn Green','BKM'),('GB','WUT','Weston upon Trent','Weston upon Trent','STS'),('GB','WVC','Wolvercote','Wolvercote','OXF'),('GB','WVF','Wivelsfield Green','Wivelsfield Green','ESX'),('GB','WVT','Wolverton','Wolverton','BKM'),('GB','WWC','West Wickham','West Wickham','GTL'),('GB','WWH','Walworth/London','Walworth/London','GTL'),('GB','WWI','Whitwick','Whitwick','LEC'),('GB','WWK','Warwick','Warwick','WAR'),('GB','WWM','White Waltham','White Waltham','WNM'),('GB','WWO','Wormington','Wormington','GLS'),('GB','WWR','Wickwar','Wickwar','SGC'),('GB','WWS','Westwoodside','Westwoodside','HUM'),('GB','WWY','Wembworthy','Wembworthy','DVV'),('GB','WXH','Wrexham','Wrexham','CWD'),('GB','WXN','Willaston','Willaston','CHS'),('GB','WXR','Worth','Worth','WSX'),('GB','WYA','Wykeham','Wykeham','NYK'),('GB','WYB','Whaley Bridge','Whaley Bridge','DBY'),('GB','WYD','Wymondham','Wymondham','NFK'),('GB','WYH','Wythenshawe','Wythenshawe','GTM'),('GB','WYL','Whyteleafe','Whyteleafe','SRY'),('GB','WYM','Wylam','Wylam','NBL'),('GB','WYS','Westbury on Severn','Westbury on Severn','GLS'),('GB','WYY','Wybunbury','Wybunbury','CHS'),('GB','XCY','Caldy','Caldy','MSY'),('GB','XDB','Chedburgh','Chedburgh','SFK'),('GB','XST','Steeton','Steeton','WYK'),('GB','YAL','Yalding','Yalding','KEN'),('GB','YAT','Yate','Yate','GLS'),('GB','YDN','Yeadon','Yeadon','WYK'),('GB','YEB','Bourne End','Bourne End','BKM'),('GB','YEL','Hailey','Hailey','OXF'),('GB','YEO','Yeovil','Yeovil','SOM'),('GB','YET','Chipping Ongar','Chipping Ongar','ESS'),('GB','YKH','Southwick','Southwick','TWR'),('GB','YKJ','Blaina','Blaina','GNT'),('GB','YLL','Yelland','Yelland',''),('GB','YMO','Yarmouth','Yarmouth','IOW'),('GB','YRD','Yardley','Yardley','WMD'),('GB','YRK','York','York','NYK'),('GB','YSD','Ystradowen','Ystradowen','MGM'),('GB','YST','Ystradgynlais','Ystradgynlais','POW'),('GB','YTE','Yateley','Yateley','HAM'),('GB','YTN','Yatton','Yatton','NSM'),('GB','YUR','Church Stretton','Church Stretton','SHR'),('GB','YVT','Yelvertoft','Yelvertoft','NTH'),('GB','YVZ','Stonehouse','Stonehouse','GLS'),('GB','YXL','Coseley','Coseley','WMD'),('GB','ZDD','Chiddingfold','Chiddingfold','SRY'),('GB','ZLD','Blairgowrie','Blairgowrie','TAY'),('GB','ZLS','Zeals','Zeals','WIL'),('GB','ZOR','Martock','Martock','SOM'),('GD','','','',''),('GD','GND','Grenada','Grenada',''),('GD','GRE','Grenville','Grenville',''),('GD','HIL','Hillsborough, Carriacou Is','Hillsborough, Carriacou Is',''),('GD','STG','Saint George\'s','Saint George\'s',''),('GE','','','',''),('GE','BUS','Batumi','Batumi',''),('GE','GUR','Gurjaani','Gurjaani',''),('GE','KUT','Kutaisi','Kutaisi',''),('GE','PTI','Poti','Poti',''),('GE','SUI','Sukhumi','Sukhumi',''),('GE','TBS','Tbilisi','Tbilisi',''),('GE','TEL','T\'elavi','T\'elavi',''),('GF','','','',''),('GF','CAY','Cayenne','Cayenne',''),('GF','DDC','Degrad des Cannes','Degrad des Cannes',''),('GF','LVT','Le Larivot','Le Larivot',''),('GF','MPY','Maripasoula','Maripasoula',''),('GF','OYP','Saint Georges de l\'Oyapock','Saint Georges de l\'Oyapock',''),('GF','QKR','Kourou','Kourou',''),('GF','REI','Regina','Regina',''),('GF','SLM','St Laurent du Maroni','St Laurent du Maroni',''),('GF','SMY','Sinnamary','Sinnamary',''),('GF','XAU','Saul','Saul',''),('GG','','','',''),('GG','ACI','Alderney','Alderney',''),('GG','GCI','Guernsey','Guernsey',''),('GG','SPT','St Peter Port','St Peter Port',''),('GH','','','',''),('GH','ACC','Accra','Accra',''),('GH','ADA','Ada','Ada',''),('GH','ASA','Asamankese','Asamankese',''),('GH','AUR','Aura','Aura',''),('GH','AXI','Axim','Axim',''),('GH','BKM','Berekum','Berekum',''),('GH','CCT','Cape Coast','Cape Coast',''),('GH','EJU','Ejura','Ejura',''),('GH','KGO','Konongo','Konongo',''),('GH','KIT','Keta','Keta',''),('GH','KMS','Kumasi','Kumasi',''),('GH','KMU','Kumawu','Kumawu',''),('GH','KOF','Koforidua','Koforidua',''),('GH','KPA','Kpandu','Kpandu',''),('GH','KPE','Kpetoe','Kpetoe',''),('GH','KTP','Kotoka','Kotoka',''),('GH','LEG','Legon','Legon',''),('GH','NSA','Nsawam','Nsawam',''),('GH','NYI','Sunyani','Sunyani',''),('GH','OBU','Obuasi','Obuasi',''),('GH','ODA','Oda','Oda',''),('GH','SEK','Sekondi','Sekondi',''),('GH','SHA','Shama','Shama',''),('GH','SPD','Saltpond','Saltpond',''),('GH','TEM','Tema','Tema',''),('GH','TKD','Takoradi','Takoradi',''),('GH','TML','Tamale','Tamale',''),('GH','TWA','Tarkwa','Tarkwa',''),('GH','WEA','Winneba','Winneba',''),('GI','','','',''),('GI','GIB','Gibraltar','Gibraltar',''),('GL','','','',''),('GL','AGM','Angmagssalik','Angmagssalik',''),('GL','CNP','Neerlerit Inaat','Neerlerit Inaat',''),('GL','DAN','Daneborg','Daneborg',''),('GL','DUN','Dundas','Dundas',''),('GL','FHN','Kangerdluarssoruseg (Faringehavn','Kangerdluarssoruseg (Faringehavn',''),('GL','GOH','Nuuk (Godthaab)','Nuuk (Godthaab)',''),('GL','IUT','Ivigtut','Ivigtut',''),('GL','JAV','Ilulissat (Jakobshavn)','Ilulissat (Jakobshavn)',''),('GL','JCH','Qasigiannguit (Christianshaab)','Qasigiannguit (Christianshaab)',''),('GL','JEG','Aasiaat (Egedesminde)','Aasiaat (Egedesminde)',''),('GL','JFR','Paamiut (Fredrikshaab)','Paamiut (Fredrikshaab)',''),('GL','JGO','Qeqertarsuaq (Godhavn)','Qeqertarsuaq (Godhavn)',''),('GL','JGR','Kangilinguit (Gronnedal)','Kangilinguit (Gronnedal)',''),('GL','JHS','Sisimiut (Holsteinsborg)','Sisimiut (Holsteinsborg)',''),('GL','JJU','Qaqortoq (Julianehaab)','Qaqortoq (Julianehaab)',''),('GL','JNN','Nanortalik','Nanortalik',''),('GL','JNS','Narsaq','Narsaq',''),('GL','JRK','Arsuk','Arsuk',''),('GL','JSU','Maniitsoq (Sukkertoppen)','Maniitsoq (Sukkertoppen)',''),('GL','JUV','Upernavik','Upernavik',''),('GL','KUN','Kuummiut','Kuummiut',''),('GL','KUS','Kulusuk','Kulusuk',''),('GL','MRG','Mesters Vig','Mesters Vig',''),('GL','NAL','Nalunaq Gold Mine','Nalunaq Gold Mine',''),('GL','NAQ','Qaanaaq','Qaanaaq',''),('GL','OBY','Illorqortoormiut (Scoresbysund)','Illorqortoormiut (Scoresbysund)',''),('GL','SEQ','Seqi Olivine Mine','Seqi Olivine Mine',''),('GL','SFJ','Kangerlussuaq (Sondre Stromfjord','Kangerlussuaq (Sondre Stromfjord',''),('GL','THU','Pituffik','Pituffik',''),('GL','TNT','Tiniteqilaaq','Tiniteqilaaq',''),('GL','TOV','Toqqusaq','Toqqusaq',''),('GL','UAK','Narsarsuaq','Narsarsuaq',''),('GL','UMD','Uummannaq','Uummannaq',''),('GM','','','',''),('GM','BAK','Bakau','Bakau',''),('GM','BAN','Bansang','Bansang',''),('GM','BJL','Banjul','Banjul',''),('GM','BRB','Brikama Ba','Brikama Ba',''),('GM','BSS','Basse Santa Su','Basse Santa Su',''),('GM','BWI','Bwiam','Bwiam',''),('GM','FAR','Farafenni','Farafenni',''),('GM','JTB','MacCarthy Island (Jangjangbureh)','MacCarthy Island (Jangjangbureh)','M'),('GM','KAU','Kau-ur','Kau-ur',''),('GM','KUN','Kuntair','Kuntair',''),('GM','MAK','Mansa Konko','Mansa Konko',''),('GM','SKE','Serekunda','Serekunda',''),('GN','','','',''),('GN','BKJ','Boke','Boke',''),('GN','BTY','Benty','Benty',''),('GN','CKY','Conakry','Conakry',''),('GN','FAA','Faranah','Faranah',''),('GN','FIG','Fria','Fria',''),('GN','GII','Siguiri','Siguiri',''),('GN','KMR','Port-Kamsar','Port-Kamsar',''),('GN','KNN','Kankan','Kankan',''),('GN','KSI','Kissidougou','Kissidougou',''),('GN','LEK','Labe','Labe',''),('GN','MCA','Macenta','Macenta',''),('GN','NZE','Nzerekore','Nzerekore',''),('GN','SBI','Koundara','Koundara',''),('GP','','','',''),('GP','BBR','Basse-Terre','Basse-Terre',''),('GP','CCE','Grand Case','Grand Case',''),('GP','DSD','La Desirade','La Desirade',''),('GP','GBJ','Marie-Galante','Marie-Galante',''),('GP','GRB','Grand-Bourg','Grand-Bourg',''),('GP','GUS','Gustavia','Gustavia',''),('GP','HTB','Terre-de-Bas','Terre-de-Bas',''),('GP','JAR','Jarry','Jarry',''),('GP','LSS','Terre-de-Haut','Terre-de-Haut',''),('GP','MSB','Marigot','Marigot',''),('GP','PTL','Port-Louis','Port-Louis',''),('GP','PTP','Pointe-a-Pitre','Pointe-a-Pitre',''),('GP','SBH','St Barthelemy','St Barthelemy',''),('GP','SFG','Saint Martin Apt','Saint Martin Apt',''),('GQ','','','',''),('GQ','ABU','San Antonio de Pale','San Antonio de Pale',''),('GQ','BSG','Bata','Bata',''),('GQ','BUL','Butuku-Luba','Butuku-Luba',''),('GQ','COG','Cogo','Cogo',''),('GQ','LUB','Luba','Luba',''),('GQ','MON','Mongomo','Mongomo',''),('GQ','RMN','Rio Muni','Rio Muni',''),('GQ','SIS','Santa Isabel','Santa Isabel',''),('GQ','SSG','Malabo','Malabo',''),('GR','','','',''),('GR','ABO','Ambelokipoi','Ambelokipoi',''),('GR','ACH','Akharnai','Akharnai',''),('GR','ACL','Achladi','Achladi',''),('GR','ADO','Ahdendron','Ahdendron',''),('GR','AEF','Agia Efimia','Agia Efimia',''),('GR','AEG','Aegina','Aegina',''),('GR','AGA','Agria','Agria',''),('GR','AGG','Agistri Aiginas','Agistri Aiginas',''),('GR','AGI','Agia Trias','Agia Trias',''),('GR','AGK','Agiokampos Larissas','Agiokampos Larissas',''),('GR','AGM','Agia Marina','Agia Marina',''),('GR','AGN','Agathonisi','Agathonisi',''),('GR','AGO','Agios Efstratios','Agios Efstratios',''),('GR','AGP','Agios Pavlos','Agios Pavlos',''),('GR','AGQ','Agrinion','Agrinion',''),('GR','AGR','Agrinion','Agrinion',''),('GR','AGS','Agios Stefanos','Agios Stefanos',''),('GR','AGT','Agio Theodoroi','Agio Theodoroi',''),('GR','AHS','Ankhialos','Ankhialos',''),('GR','AIO','Alimos','Alimos',''),('GR','AIY','Aiyion','Aiyion',''),('GR','AKI','Agios Kirykos','Agios Kirykos',''),('GR','AKO','Agios Konstantinos','Agios Konstantinos',''),('GR','ALI','Aliartos','Aliartos',''),('GR','ALM','Almiros','Almiros',''),('GR','ALO','Alonnisos','Alonnisos',''),('GR','ALV','Aliverion','Aliverion',''),('GR','ALX','Alexandria','Alexandria',''),('GR','AMA','Amalias','Amalias',''),('GR','AMF','Amfilochia','Amfilochia',''),('GR','AMI','Amoliani','Amoliani',''),('GR','AMO','Amorgos','Amorgos',''),('GR','AMP','Amfissa','Amfissa',''),('GR','AMS','Adhamas','Adhamas',''),('GR','AMY','Amindaion','Amindaion',''),('GR','ANA','Anafi','Anafi',''),('GR','AND','Andros','Andros',''),('GR','ANI','Agios Nikolaos, Kriti','Agios Nikolaos, Kriti',''),('GR','ANP','Antiparos','Antiparos',''),('GR','ANT','Andirrion','Andirrion',''),('GR','AOK','Karpathos','Karpathos',''),('GR','AOS','Agios Athanasios','Agios Athanasios',''),('GR','APE','Agia Pelagia','Agia Pelagia',''),('GR','APL','Amaliapolis','Amaliapolis',''),('GR','APS','Apsalos','Apsalos',''),('GR','APV','Asprovalta','Asprovalta',''),('GR','ARE','Areopolis','Areopolis',''),('GR','ARG','Argos (Argolis)','Argos (Argolis)',''),('GR','ARI','Aridaia','Aridaia',''),('GR','ARK','Arkitsa','Arkitsa',''),('GR','ARM','Argostolion','Argostolion',''),('GR','ARN','Arnaia','Arnaia',''),('GR','ARS','Astros','Astros',''),('GR','ART','Arta','Arta',''),('GR','ASO','Asopos','Asopos',''),('GR','ASP','Aspra Spitia','Aspra Spitia',''),('GR','ASS','Aspropirgos','Aspropirgos',''),('GR','AST','Astakos','Astakos',''),('GR','ASV','Asvestochorion','Asvestochorion',''),('GR','ATA','Atalandi','Atalandi',''),('GR','ATH','Athinai','Athinai',''),('GR','ATK','Antikyra','Antikyra',''),('GR','ATR','Ayia Trias','Ayia Trias',''),('GR','ATS','Altsi','Altsi',''),('GR','ATT','Attiki','Attiki',''),('GR','AVA','Avlida','Avlida',''),('GR','AVL','Avlon','Avlon',''),('GR','AXD','Alexandroupolis','Alexandroupolis',''),('GR','CFU','Kerkira (Corfu)','Kerkira (Corfu)',''),('GR','CHI','Chaidari, Athens','Chaidari, Athens',''),('GR','CHQ','Canea','Canea',''),('GR','CLK','Chalkis','Chalkis',''),('GR','CRG','Corinth','Corinth',''),('GR','CSF','Khora Sfakion','Khora Sfakion',''),('GR','DAF','Dafni','Dafni',''),('GR','DAG','Dagla','Dagla',''),('GR','DHI','Dhidhimotikhon','Dhidhimotikhon',''),('GR','DHS','Dhrimos','Dhrimos',''),('GR','DIA','Diafanion','Diafanion',''),('GR','DKI','Dheskati','Dheskati',''),('GR','DOM','Domokos','Domokos',''),('GR','DOS','Delos','Delos',''),('GR','DOX','Dhoxaton','Dhoxaton',''),('GR','DPA','Drapetzona','Drapetzona',''),('GR','DRM','Drama','Drama',''),('GR','DRS','Dhroseron','Dhroseron',''),('GR','EDE','Edessa','Edessa',''),('GR','EDI','Edipsos','Edipsos',''),('GR','EGA','Aiyaleo','Aiyaleo',''),('GR','ELA','Elatia','Elatia',''),('GR','ELE','Elefsis (Elevsis)','Elefsis (Elevsis)',''),('GR','ELL','Ellasona','Ellasona',''),('GR','ELT','Eleftheres','Eleftheres',''),('GR','EPI','Epidavros','Epidavros',''),('GR','ERE','Eretria','Eretria',''),('GR','ERM','Ermioni','Ermioni',''),('GR','ETL','Etolikon','Etolikon',''),('GR','EVM','Evosmon','Evosmon',''),('GR','EVZ','Evzonoi','Evzonoi',''),('GR','EYD','Eydilos','Eydilos',''),('GR','FAR','Farsala','Farsala',''),('GR','FER','Ferai','Ferai',''),('GR','FIA','Florina','Florina',''),('GR','FIL','Filiatra','Filiatra',''),('GR','FIS','Fiskardo','Fiskardo',''),('GR','FOL','Folegandros','Folegandros',''),('GR','FOU','Fournoi','Fournoi',''),('GR','GAS','Gastouni','Gastouni',''),('GR','GAV','Gavrion','Gavrion',''),('GR','GAZ','Gazoros','Gazoros',''),('GR','GEF','Gefyra','Gefyra',''),('GR','GER','Gerakas','Gerakas',''),('GR','GKU','Gerakarou','Gerakarou',''),('GR','GLO','Glossa','Glossa',''),('GR','GLY','Glyfa Fthiotidas','Glyfa Fthiotidas',''),('GR','GPA','Patras','Patras',''),('GR','GRA','Agios Ioannis Rentis','Agios Ioannis Rentis',''),('GR','GSI','Galatsion','Galatsion',''),('GR','GVA','Grevena','Grevena',''),('GR','GYT','Gythion','Gythion',''),('GR','HAL','Halki Dodekanison','Halki Dodekanison',''),('GR','HER','Heraklion (Iraklion)','Heraklion (Iraklion)',''),('GR','HLS','Chalastra','Chalastra',''),('GR','HYD','Hydra (Idhra)','Hydra (Idhra)',''),('GR','IER','Ierapetra','Ierapetra',''),('GR','IGO','Igoumenitsa','Igoumenitsa',''),('GR','IKN','Ikonian','Ikonian',''),('GR','ILI','Ilion','Ilion',''),('GR','ILO','Ilioupolis','Ilioupolis',''),('GR','INF','Inofyta','Inofyta',''),('GR','INO','Inousses','Inousses',''),('GR','IOA','Ioannina','Ioannina',''),('GR','IOS','Ios','Ios',''),('GR','IRA','Iraklia','Iraklia',''),('GR','ITA','Itea','Itea',''),('GR','ITH','Ithaki (Ithaca)','Ithaki (Ithaca)',''),('GR','ITM','Isthmia','Isthmia',''),('GR','JIK','Ikaria','Ikaria',''),('GR','JKH','Chios','Chios',''),('GR','JMK','Mykonos','Mykonos',''),('GR','JNX','Naxos','Naxos',''),('GR','JSH','Siteia','Siteia',''),('GR','JSI','Skiathos','Skiathos',''),('GR','JSY','Syra (Syros)','Syra (Syros)',''),('GR','JTR','Thira','Thira',''),('GR','JTY','Astypalaia','Astypalaia',''),('GR','KAC','Kato Akhaia','Kato Akhaia',''),('GR','KAK','Katakolon','Katakolon',''),('GR','KAN','Leondarion','Leondarion',''),('GR','KAP','Kapsalion','Kapsalion',''),('GR','KAR','Neon Karlovasion','Neon Karlovasion',''),('GR','KAS','Kastellorizou (ex Megisti)','Kastellorizou (ex Megisti)',''),('GR','KAT','Katokhi','Katokhi',''),('GR','KCH','Kalives Valtsaiikes','Kalives Valtsaiikes',''),('GR','KDM','Kardamyla','Kardamyla',''),('GR','KDO','Kolindros','Kolindros',''),('GR','KEA','Kea','Kea',''),('GR','KEI','Katerini','Katerini',''),('GR','KER','Keramoti','Keramoti',''),('GR','KFL','Kefallinia','Kefallinia',''),('GR','KFO','Kefalovrison','Kefalovrison',''),('GR','KFS','Kifisia','Kifisia',''),('GR','KGS','Kos','Kos',''),('GR','KHR','Khrisoupolis','Khrisoupolis',''),('GR','KIA','Afidhnai','Afidhnai',''),('GR','KIL','Killini','Killini',''),('GR','KIM','Kimi','Kimi',''),('GR','KIO','Kiato','Kiato',''),('GR','KIS','Kastelli Kissamou','Kastelli Kissamou',''),('GR','KIT','Kythira','Kythira',''),('GR','KKZ','Kilkis','Kilkis',''),('GR','KLH','Kalohori','Kalohori',''),('GR','KLL','Kalilimenes','Kalilimenes',''),('GR','KLM','Kalamaki','Kalamaki',''),('GR','KLX','Kalamata','Kalamata',''),('GR','KLY','Kalyvia','Kalyvia',''),('GR','KMI','Kalymnos','Kalymnos',''),('GR','KMS','Kimolos','Kimolos',''),('GR','KOA','Konitsa','Konitsa',''),('GR','KOL','Kolokinthou','Kolokinthou',''),('GR','KOM','Komotini','Komotini',''),('GR','KOR','Koropion','Koropion',''),('GR','KPO','Koropi','Koropi',''),('GR','KRA','Keratea','Keratea',''),('GR','KRD','Karditsa','Karditsa',''),('GR','KRI','Krioneri','Krioneri',''),('GR','KRT','Korinthos','Korinthos',''),('GR','KSJ','Kassos','Kassos',''),('GR','KSO','Kastoria','Kastoria',''),('GR','KSS','Karpenisi','Karpenisi',''),('GR','KST','Karystos','Karystos',''),('GR','KTP','Katapola','Katapola',''),('GR','KTS','Keratsinion','Keratsinion',''),('GR','KVA','Kavala','Kavala',''),('GR','KYL','Kyllini','Kyllini',''),('GR','KYM','Kimasi','Kimasi',''),('GR','KYP','Kyparissia','Kyparissia',''),('GR','KYT','Kythnos','Kythnos',''),('GR','KZI','Kozani','Kozani',''),('GR','KZS','Kastelorizo','Kastelorizo',''),('GR','LAK','Lakkia','Lakkia',''),('GR','LAM','Lamia','Lamia',''),('GR','LAN','Langadhas','Langadhas',''),('GR','LAV','Laurium (Lavrion)','Laurium (Lavrion)',''),('GR','LEA','Levadeia','Levadeia',''),('GR','LEF','Lefkandi','Lefkandi',''),('GR','LEV','Lefkada','Lefkada',''),('GR','LFK','Lefkimmi','Lefkimmi',''),('GR','LII','Limni','Limni',''),('GR','LIP','Lipsoi','Lipsoi',''),('GR','LIT','Litokhoron','Litokhoron',''),('GR','LIV','Livanatai','Livanatai',''),('GR','LIX','Lixuri','Lixuri',''),('GR','LKV','Likovrisi','Likovrisi',''),('GR','LND','Leonidion','Leonidion',''),('GR','LOU','Loutraki','Loutraki',''),('GR','LRA','Larisa','Larisa',''),('GR','LRM','Larmes','Larmes',''),('GR','LRS','Leros','Leros',''),('GR','LRY','Larymna','Larymna',''),('GR','LSA','Nea Liosia','Nea Liosia',''),('GR','LVR','Aliverio','Aliverio',''),('GR','LXS','Lemnos','Lemnos',''),('GR','MAD','Mandra','Mandra',''),('GR','MAL','Malaoi','Malaoi',''),('GR','MAN','Manolas','Manolas',''),('GR','MAR','Markopoulon','Markopoulon',''),('GR','MAV','Mavrothalassa','Mavrothalassa',''),('GR','MAZ','Marina Zeas','Marina Zeas',''),('GR','MDR','Moudhros','Moudhros',''),('GR','MEG','Megalon Livadion','Megalon Livadion',''),('GR','MEL','Mesolongion','Mesolongion',''),('GR','MEN','Menidi','Menidi',''),('GR','MES','Messogia','Messogia',''),('GR','MET','Methoni','Methoni',''),('GR','MGN','Meganisi','Meganisi',''),('GR','MGO','Magiko','Magiko',''),('GR','MGR','Megara','Megara',''),('GR','MHI','Mesta Hiou','Mesta Hiou',''),('GR','MIS','Missimi','Missimi',''),('GR','MJT','Mytilene','Mytilene',''),('GR','MLA','Melia','Melia',''),('GR','MLK','Malakasa','Malakasa',''),('GR','MLO','Milos','Milos',''),('GR','MMS','Metamorfosis','Metamorfosis',''),('GR','MNI','Messini','Messini',''),('GR','MOL','Molyvos','Molyvos',''),('GR','MON','Monemvasia','Monemvasia',''),('GR','MOS','Moschaton','Moschaton',''),('GR','MOU','Moutsouna','Moutsouna',''),('GR','MRA','Mouriai','Mouriai',''),('GR','MRM','Marmari','Marmari',''),('GR','MRN','Marmarion','Marmarion',''),('GR','MSV','Metsovon','Metsovon',''),('GR','MTI','Mantoudion','Mantoudion',''),('GR','MYL','Mylaki','Mylaki',''),('GR','MYR','Mirina','Mirina',''),('GR','NAF','Nafplion','Nafplion',''),('GR','NAI','Iraklion','Iraklion',''),('GR','NAL','Nea Alikarnassos','Nea Alikarnassos',''),('GR','NAR','Nea Artaki','Nea Artaki',''),('GR','NAV','Navarino','Navarino',''),('GR','NCO','Neokhoroudha','Neokhoroudha',''),('GR','NEA','Neapolis','Neapolis',''),('GR','NER','Nea Erythrea','Nea Erythrea',''),('GR','NEY','Kato Nevrokopion','Kato Nevrokopion',''),('GR','NGA','Nigrita','Nigrita',''),('GR','NID','Nidhrion','Nidhrion',''),('GR','NIK','Nikaia','Nikaia',''),('GR','NIS','Nisiros','Nisiros',''),('GR','NKA','Nea Kallikratia','Nea Kallikratia',''),('GR','NKK','Nea Khalkidhon','Nea Khalkidhon',''),('GR','NKL','Neohorion Kyllinis','Neohorion Kyllinis',''),('GR','NKS','Nea Kios','Nea Kios',''),('GR','NKV','Nea Karvali','Nea Karvali',''),('GR','NMA','Nea Moudhania','Nea Moudhania',''),('GR','NME','Nemea','Nemea',''),('GR','NPA','Nea Pella','Nea Pella',''),('GR','NPK','Navpaktos','Navpaktos',''),('GR','NPY','Nea Playia','Nea Playia',''),('GR','NSA','Naousa','Naousa',''),('GR','NSN','Nea Santa','Nea Santa',''),('GR','NST','Nea Stira','Nea Stira',''),('GR','ORA','Oraiokastron','Oraiokastron',''),('GR','ORC','Orchomenos','Orchomenos',''),('GR','ORE','Orei','Orei',''),('GR','ORM','Ormilia','Ormilia',''),('GR','ORO','Oropos','Oropos',''),('GR','ORS','Orestias','Orestias',''),('GR','OUR','Ouranopolis','Ouranopolis',''),('GR','PAA','Palaia Psara','Palaia Psara',''),('GR','PAI','Paiania','Paiania',''),('GR','PAL','Palaion Faliron','Palaion Faliron',''),('GR','PAN','Panoi','Panoi',''),('GR','PAO','Paloukia','Paloukia',''),('GR','PAR','Parga','Parga',''),('GR','PAS','Paros','Paros',''),('GR','PAT','Panetolion','Panetolion',''),('GR','PAX','Paxi','Paxi',''),('GR','PEP','Palaia Epidavros','Palaia Epidavros',''),('GR','PER','Perama','Perama',''),('GR','PET','Petra','Petra',''),('GR','PFA','Palaia Fokaia','Palaia Fokaia',''),('GR','PHE','Porto Heli','Porto Heli',''),('GR','PIK','Pikermion','Pikermion',''),('GR','PIR','Piraeus','Piraeus',''),('GR','PKE','Poros Kefallinias','Poros Kefallinias',''),('GR','PKH','Portochelion','Portochelion',''),('GR','PLA','Pilea (Pylaia)','Pilea (Pylaia)',''),('GR','PLI','Pyli','Pyli',''),('GR','PLT','Plati','Plati',''),('GR','PMS','Patmos','Patmos',''),('GR','PNA','Panorama','Panorama',''),('GR','POL','Polygyros','Polygyros',''),('GR','PPG','Pallini','Pallini',''),('GR','PRA','Porto Rafti (Limin Mesoyaias)','Porto Rafti (Limin Mesoyaias)',''),('GR','PRI','Peristeri','Peristeri',''),('GR','PRT','Protoria','Protoria',''),('GR','PSA','Psakhna','Psakhna',''),('GR','PSF','Paleohora Sfakion','Paleohora Sfakion',''),('GR','PST','Peristera','Peristera',''),('GR','PTF','Pendalofos','Pendalofos',''),('GR','PTK','Politika','Politika',''),('GR','PTL','Porto Lagos','Porto Lagos',''),('GR','PTN','Platanos','Platanos',''),('GR','PTR','Poros Trizinias','Poros Trizinias',''),('GR','PVK','Preveza/Lefkas','Preveza/Lefkas',''),('GR','PYL','Pylos','Pylos',''),('GR','PYR','Pyrgos','Pyrgos',''),('GR','PYT','Pythagoreion','Pythagoreion',''),('GR','QKG','Chalkis','Chalkis',''),('GR','RAF','Rafina','Rafina',''),('GR','REN','Rentis','Rentis',''),('GR','RET','Rethymnon','Rethymnon',''),('GR','REV','Revithoussa','Revithoussa',''),('GR','RHO','Rhodes','Rhodes',''),('GR','RIO','Rio','Rio',''),('GR','RTS','Ritsona','Ritsona',''),('GR','SAI','Sami','Sami',''),('GR','SAL','Salamis','Salamis',''),('GR','SAM','Samothraki','Samothraki',''),('GR','SAP','Stavros Agias Paraskevis','Stavros Agias Paraskevis',''),('GR','SDH','Souda','Souda',''),('GR','SDS','Sindhos','Sindhos',''),('GR','SER','Seriphos','Seriphos',''),('GR','SFN','Souflion','Souflion',''),('GR','SGB','St George','St George',''),('GR','SHA','Stavros Halkidikis','Stavros Halkidikis',''),('GR','SID','Sidirokastro','Sidirokastro',''),('GR','SIF','Apollonia','Apollonia',''),('GR','SII','Sikinos','Sikinos',''),('GR','SIK','Sikionia','Sikionia',''),('GR','SIS','Sindos','Sindos',''),('GR','SKA','Skaramangas','Skaramangas',''),('GR','SKG','Thessaloniki','Thessaloniki',''),('GR','SKH','Skhimatarion','Skhimatarion',''),('GR','SKL','Skala Lakonias','Skala Lakonias',''),('GR','SKO','Skopelos','Skopelos',''),('GR','SKU','Skiros','Skiros',''),('GR','SKY','Skydra','Skydra',''),('GR','SMI','Samos','Samos',''),('GR','SMT','Schimatarion','Schimatarion',''),('GR','SOU','Soussaki','Soussaki',''),('GR','SPA','Sparti','Sparti',''),('GR','SPE','Spetsai','Spetsai',''),('GR','SPT','Spata','Spata',''),('GR','SRI','Serrai','Serrai',''),('GR','SRS','Serres','Serres',''),('GR','STA','Stavroupolis','Stavroupolis',''),('GR','STE','Steni Evvias','Steni Evvias',''),('GR','STI','Stratoni','Stratoni',''),('GR','STY','Stylinda','Stylinda',''),('GR','SUD','Suda Bay','Suda Bay',''),('GR','SVL','Savalia','Savalia',''),('GR','SYM','Symi','Symi',''),('GR','SYO','Syra Island','Syra Island',''),('GR','SYS','Stylida','Stylida',''),('GR','TAL','Trachia Argolidas','Trachia Argolidas',''),('GR','TFP','Trachia Fafplio','Trachia Fafplio',''),('GR','TGN','Traganon','Traganon',''),('GR','THI','Thisvi','Thisvi',''),('GR','THR','Thermi','Thermi',''),('GR','TIL','Tilos','Tilos',''),('GR','TIN','Tinos','Tinos',''),('GR','TRA','Tranovalton','Tranovalton',''),('GR','TRI','Trikala','Trikala',''),('GR','TRP','Tripolis','Tripolis',''),('GR','TRS','Thirasia','Thirasia',''),('GR','TSI','Tsingeli','Tsingeli',''),('GR','TSO','Thasos','Thasos',''),('GR','TVA','Thivai','Thivai',''),('GR','TYR','Tyrnavos','Tyrnavos',''),('GR','VAO','Vasilikon','Vasilikon',''),('GR','VAR','Varibobi','Varibobi',''),('GR','VAS','Vasilika','Vasilika',''),('GR','VAT','Vathi','Vathi',''),('GR','VEL','Velo','Velo',''),('GR','VEO','Kato Vermion','Kato Vermion',''),('GR','VER','Veria','Veria',''),('GR','VLX','Volax','Volax',''),('GR','VOA','Vonitsa','Vonitsa',''),('GR','VOL','Volos','Volos',''),('GR','VOR','Kapparia','Kapparia',''),('GR','VOT','Votanikos','Votanikos',''),('GR','VRI','Vrisakia','Vrisakia',''),('GR','VRN','Voreinon','Voreinon',''),('GR','VTH','Port Vathy','Port Vathy',''),('GR','XAN','Xanthi','Xanthi',''),('GR','YER','Yerakini','Yerakini',''),('GR','YLI','Yali Island','Yali Island',''),('GR','YNN','Yiannitsa','Yiannitsa',''),('GR','ZEA','Zea Island','Zea Island',''),('GR','ZEY','Zevgolation','Zevgolation',''),('GR','ZPI','Akra Zefiros','Akra Zefiros',''),('GR','ZTH','Zakynthos','Zakynthos',''),('GS','','','',''),('GS','GRV','Grytviken','Grytviken',''),('GS','LEH','Leith Harbour','Leith Harbour',''),('GT','','','',''),('GT','AAZ','Quetzaltenango','Quetzaltenango',''),('GT','ADU','Aduana','Aduana',''),('GT','AMA','Amatitlan','Amatitlan',''),('GT','AMI','Asuncion Mita','Asuncion Mita',''),('GT','ANT','Antigua','Antigua',''),('GT','BAB','Barberena','Barberena',''),('GT','BAR','Barcenas','Barcenas',''),('GT','BOC','Boca del Monte','Boca del Monte',''),('GT','CBV','Coban','Coban',''),('GT','CDV','Ciudad Vieja','Ciudad Vieja',''),('GT','CHC','Chicacao','Chicacao',''),('GT','CHI','Chimaltenango','Chimaltenango',''),('GT','CHQ','Chiquimulilla','Chiquimulilla',''),('GT','CHR','Champerico','Champerico',''),('GT','CIQ','Chiquimula','Chiquimula',''),('GT','CMM','Carmelita','Carmelita',''),('GT','COY','Cuyotenango','Cuyotenango',''),('GT','CTF','Coatepeque','Coatepeque',''),('GT','CTU','Ciudad Tecun Uman','Ciudad Tecun Uman',''),('GT','CUI','Cuilapa','Cuilapa',''),('GT','DON','Dos Lagunas','Dos Lagunas',''),('GT','ELP','El Pino','El Pino',''),('GT','ELR','El Rancho','El Rancho',''),('GT','ELT','El Tejar','El Tejar',''),('GT','ENJ','El Naranjo','El Naranjo',''),('GT','ERH','El Rancho','El Rancho',''),('GT','ERI','Entre Rios','Entre Rios',''),('GT','ESC','Escuintla','Escuintla',''),('GT','ESQ','Esquipulas','Esquipulas',''),('GT','EST','Estanzuela','Estanzuela',''),('GT','FRA','Fraijanes','Fraijanes',''),('GT','FRS','Flores','Flores',''),('GT','GUA','Guatemala City','Guatemala City',''),('GT','HUG','Huehuetenango','Huehuetenango',''),('GT','IXT','San Ixtan','San Ixtan',''),('GT','JAL','Jalapa','Jalapa',''),('GT','JUT','Jutiapa','Jutiapa',''),('GT','LAA','La Aurora','La Aurora',''),('GT','LAF','La Fragua','La Fragua',''),('GT','LIV','Livingston','Livingston',''),('GT','MAS','Masagua','Masagua',''),('GT','MAZ','Mazatenango','Mazatenango',''),('GT','MCR','Melchor de Mencos','Melchor de Mencos',''),('GT','MIX','Mixco','Mixco',''),('GT','NAH','Nahualate','Nahualate',''),('GT','OBE','Obero','Obero',''),('GT','PAL','Palin','Palin',''),('GT','PAR','Parramos','Parramos',''),('GT','PAT','Patulul','Patulul',''),('GT','PBR','Puerto Barrios','Puerto Barrios',''),('GT','PCG','Paso Caballos','Paso Caballos',''),('GT','PLA','Palencia','Palencia',''),('GT','PNV','Pueblo Nuevo Vinas','Pueblo Nuevo Vinas',''),('GT','PON','Poptun','Poptun',''),('GT','PRO','El Progreso','El Progreso',''),('GT','PRQ','Puerto Quetzal','Puerto Quetzal',''),('GT','PTZ','Patzicia','Patzicia',''),('GT','PUR','Purulha','Purulha',''),('GT','QUI','Quirigua','Quirigua',''),('GT','RDC','Rio Dulce','Rio Dulce',''),('GT','RIH','Rio Hondo','Rio Hondo',''),('GT','RTE','Retalhuleu','Retalhuleu',''),('GT','RUV','Rubelsanto','Rubelsanto',''),('GT','SAA','San Antonio Suchitepequez','San Antonio Suchitepequez',''),('GT','SAB','San Bartolome Milpas Altas','San Bartolome Milpas Altas',''),('GT','SAI','San Andres Itzapa','San Andres Itzapa',''),('GT','SAL','San Lucas Sacatepequez','San Lucas Sacatepequez',''),('GT','SAM','San Marcos','San Marcos',''),('GT','SAR','Sanarate','Sanarate',''),('GT','SAS','Santiago Sacatepequez','Santiago Sacatepequez',''),('GT','SCA','San Cristobal Acasaguastlan','San Cristobal Acasaguastlan',''),('GT','SCP','Santa Catarina Pinula','Santa Catarina Pinula',''),('GT','SDS','Santo Domingo Suchitepequez','Santo Domingo Suchitepequez',''),('GT','SEB','San Sebastian','San Sebastian',''),('GT','SIQ','Siquinala','Siquinala',''),('GT','SJC','San Juan Chamelco','San Juan Chamelco',''),('GT','SJE','San Jeronimo','San Jeronimo',''),('GT','SJP','San Jose Pinula','San Jose Pinula',''),('GT','SJS','San Juan Sacatepequez','San Juan Sacatepequez',''),('GT','SLC','Santa Lucia Cotzumalguapa','Santa Lucia Cotzumalguapa',''),('GT','SLM','Salama','Salama',''),('GT','SLU','Santa Lucia Milpas Altas','Santa Lucia Milpas Altas',''),('GT','SMC','Santa Maria Cauque','Santa Maria Cauque',''),('GT','SMI','San Miguel Petapa','San Miguel Petapa',''),('GT','SNJ','San Jose','San Jose',''),('GT','SNT','Santiago Atitlan','Santiago Atitlan',''),('GT','SPS','San Pedro Sacatepequez','San Pedro Sacatepequez',''),('GT','STC','Puerto Santo Tomas de Castilla','Puerto Santo Tomas de Castilla',''),('GT','STM','Santo Tomas Milpas Altas','Santo Tomas Milpas Altas',''),('GT','STU','Santo Tomas La Union','Santo Tomas La Union',''),('GT','SUM','Sumpango','Sumpango',''),('GT','TCP','Tecpan Guatemala','Tecpan Guatemala',''),('GT','TEC','Teculutan','Teculutan',''),('GT','TIG','Tiquisate','Tiquisate',''),('GT','TKM','Tikal','Tikal',''),('GT','TOT','Totonicapan','Totonicapan',''),('GT','UAX','Uaxactun','Uaxactun',''),('GT','USU','Usumatlan','Usumatlan',''),('GT','VIN','Villa Nueva','Villa Nueva',''),('GT','VLL','Villa Canales','Villa Canales',''),('GT','VLO','Villalobos','Villalobos',''),('GT','ZAC','Zacapa','Zacapa',''),('GU','','','',''),('GU','AGA','Agana','Agana',''),('GU','APR','Apra (Agana)','Apra (Agana)',''),('GU','DED','Dededo','Dededo',''),('GU','GUM','Guam','Guam',''),('GW','','','',''),('GW','BOL','Bolama','Bolama',''),('GW','BQE','Bubaque','Bubaque',''),('GW','CAC','Cacheu','Cacheu','CA'),('GW','OXB','Bissau','Bissau','BS'),('GY','','','',''),('GY','AHL','Aishalton','Aishalton',''),('GY','BCG','Bemichi','Bemichi',''),('GY','BMJ','Baramita','Baramita',''),('GY','EKE','Ekereku','Ekereku',''),('GY','GEO','Georgetown','Georgetown',''),('GY','GFO','Bartica','Bartica',''),('GY','IMB','Imbaimadai','Imbaimadai',''),('GY','KAI','Kaieteur','Kaieteur',''),('GY','KAR','Kamarang','Kamarang',''),('GY','KKG','Konawaruk','Konawaruk',''),('GY','KPG','Kurupung','Kurupung',''),('GY','KRG','Karasabai','Karasabai',''),('GY','KRM','Karanambo','Karanambo',''),('GY','KTO','Kato','Kato',''),('GY','LDN','Linden','Linden',''),('GY','LTM','Lethem','Lethem',''),('GY','LUB','Lumid Pau','Lumid Pau',''),('GY','MHA','Mahdia','Mahdia',''),('GY','MKZ','Mackenzie','Mackenzie',''),('GY','MWJ','Matthews Ridge','Matthews Ridge',''),('GY','MYM','Monkey Mountain','Monkey Mountain',''),('GY','NAI','Annai','Annai',''),('GY','NAM','New Amsterdam','New Amsterdam',''),('GY','OGL','Ogle','Ogle',''),('GY','ORJ','Orinduik','Orinduik',''),('GY','PIQ','Pipillipai','Pipillipai',''),('GY','PKM','Port Kaituma','Port Kaituma',''),('GY','PMT','Paramakotoi','Paramakotoi',''),('GY','PRR','Paruima','Paruima',''),('GY','SDC','Sandcreek','Sandcreek',''),('GY','SKM','Skeldon','Skeldon',''),('GY','THI','Thimery','Thimery',''),('GY','USI','Mabaruma','Mabaruma',''),('GY','VEG','Maikwak','Maikwak',''),('HK','','','',''),('HK','CHW','Chai Wan','Chai Wan',''),('HK','CWB','Causeway Bay','Causeway Bay',''),('HK','HKC','Ha Kwai Chung','Ha Kwai Chung',''),('HK','HKG','Hong Kong','Hong Kong',''),('HK','KWN','Kowloon','Kowloon',''),('HK','MUN','Tuen Mun','Tuen Mun',''),('HK','QBY','Quarry Bay','Quarry Bay',''),('HK','TKT','Tai Kok Tsui','Tai Kok Tsui',''),('HK','TLS','Tai Lang Shui','Tai Lang Shui',''),('HK','TNO','Tai No','Tai No',''),('HK','TOL','Tolo Harbour','Tolo Harbour',''),('HK','VIC','Victoria','Victoria',''),('HK','ZTW','Tsuen Wan','Tsuen Wan',''),('HM','','','',''),('HM','HEA','Heard Island','Heard Island',''),('HM','MCD','McDonald Island','McDonald Island',''),('HN','','','',''),('HN','AHS','Auas','Auas',''),('HN','AMP','Amapala','Amapala',''),('HN','ART','Amarateca','Amarateca',''),('HN','BHG','Brus Laguna','Brus Laguna',''),('HN','BUF','Bufalo','Bufalo',''),('HN','CAA','Catacamas','Catacamas',''),('HN','CDD','Cauquira','Cauquira',''),('HN','CHO','Choloma','Choloma',''),('HN','CHT','Choluteca','Choluteca',''),('HN','CHU','Chumbagua','Chumbagua',''),('HN','CMY','Comayagua','Comayagua',''),('HN','COF','Cofradia','Cofradia',''),('HN','COM','Comayaguela','Comayaguela',''),('HN','CUY','Cuyamapa','Cuyamapa',''),('HN','CYL','Coyoles','Coyoles',''),('HN','DNL','Danli','Danli',''),('HN','EDQ','Erandique','Erandique',''),('HN','ELC','El Calan','El Calan',''),('HN','ENQ','Coronel E Soto Cano Ab','Coronel E Soto Cano Ab',''),('HN','GAC','Gracias','Gracias',''),('HN','GJA','Guanaja','Guanaja',''),('HN','GUO','Gualaco','Gualaco',''),('HN','HNN','Henecan','Henecan',''),('HN','IRN','Iriona','Iriona',''),('HN','JUT','Juticalpa','Juticalpa',''),('HN','LCE','La Ceiba','La Ceiba',''),('HN','LEZ','La Esperanza','La Esperanza',''),('HN','LLH','Las Limas','Las Limas',''),('HN','LLM','La Lima','La Lima',''),('HN','LMH','Limon','Limon',''),('HN','LUI','La Union','La Union',''),('HN','MRJ','Marcala','Marcala',''),('HN','MZN','Morazan','Morazan',''),('HN','NAC','Naco','Naco',''),('HN','OAN','Olanchito','Olanchito',''),('HN','PCA','Puerto Castilla','Puerto Castilla',''),('HN','PCH','Palacios','Palacios',''),('HN','PCR','Puerto Cortes','Puerto Cortes',''),('HN','PEU','Puerto Lempira','Puerto Lempira',''),('HN','PRO','El Progreso','El Progreso',''),('HN','PTL','Potrerillos','Potrerillos',''),('HN','RIO','Rio Nance','Rio Nance',''),('HN','RTB','Roatan','Roatan',''),('HN','RUY','Copan','Copan',''),('HN','SAN','Santa Rita','Santa Rita',''),('HN','SAP','San Pedro Sula','San Pedro Sula',''),('HN','SBA','Santa Barbara','Santa Barbara',''),('HN','SCD','Sulaco','Sulaco',''),('HN','SDH','Santa Rosa de Copan','Santa Rosa de Copan',''),('HN','SET','San Esteban','San Esteban',''),('HN','SIN','Sinuapa','Sinuapa',''),('HN','SLM','Salamar','Salamar',''),('HN','SLO','San Lorenzo','San Lorenzo',''),('HN','SRI','Santa Rita','Santa Rita',''),('HN','STP','Siguatepeque','Siguatepeque',''),('HN','TCF','Tocoa','Tocoa',''),('HN','TEA','Tela','Tela',''),('HN','TGA','Talanga','Talanga',''),('HN','TGU','Tegucigalpa','Tegucigalpa',''),('HN','TJI','Trujillo','Trujillo',''),('HN','UII','Utila','Utila',''),('HN','VDA','Valle de Angeles','Valle de Angeles',''),('HN','VLN','Villa Nueva','Villa Nueva',''),('HN','VNA','Villanueva','Villanueva',''),('HN','VTA','Victoria','Victoria',''),('HN','YOR','Yoro','Yoro',''),('HR','','','',''),('HR','ALJ','Aljmas','Aljmas',''),('HR','ATL','Antenal','Antenal',''),('HR','BAK','Bakar','Bakar',''),('HR','BAS','Baska','Baska',''),('HR','BAT','Batina','Batina',''),('HR','BJE','Bjelovar','Bjelovar',''),('HR','BJN','Boljun','Boljun',''),('HR','BKC','Bedekovcina','Bedekovcina',''),('HR','BLC','Belisce','Belisce',''),('HR','BLE','Blace','Blace',''),('HR','BNM','Biograd na Moru','Biograd na Moru',''),('HR','BOL','Bol','Bol',''),('HR','BOR','Borovo','Borovo',''),('HR','BOT','Botovo','Botovo',''),('HR','BRB','Brbinj/Lucina','Brbinj/Lucina',''),('HR','BRE','Brinje','Brinje',''),('HR','BRI','Brioni','Brioni',''),('HR','BRV','Borovo Selo','Borovo Selo',''),('HR','BUZ','Buzet','Buzet',''),('HR','BVA','Brezovica','Brezovica',''),('HR','BVO','Baska Voda','Baska Voda',''),('HR','BZA','Bozava','Bozava',''),('HR','CAK','?akovec','?akovec',''),('HR','CRA','Crikvenica','Crikvenica',''),('HR','CRS','Cres','Cres',''),('HR','CVT','Cavtat','Cavtat',''),('HR','DAR','Daruvar','Daruvar',''),('HR','DBV','Dubrovnik','Dubrovnik',''),('HR','DDA','Darda','Darda',''),('HR','DEL','Delnice','Delnice',''),('HR','DGS','Dugo Sela','Dugo Sela',''),('HR','DKC','Donji Kraljevec','Donji Kraljevec',''),('HR','DLJ','Dalj','Dalj',''),('HR','DMC','Durmanec','Durmanec',''),('HR','DMH','Donji Miholjac','Donji Miholjac',''),('HR','DNC','Donje Celo','Donje Celo',''),('HR','DRK','Drvenik','Drvenik',''),('HR','DUR','Dugi Rat','Dugi Rat',''),('HR','DVA','Dubravica','Dubravica',''),('HR','ERD','Erdut','Erdut',''),('HR','FNA','Fazana','Fazana',''),('HR','GCN','Gorican','Gorican',''),('HR','GNA','Gazenica','Gazenica',''),('HR','GOM','Gomirje','Gomirje',''),('HR','GRA','Gra?ac','Gra?ac',''),('HR','GSP','Gospi?','Gospi?',''),('HR','HLE','Hrvatski Leskovac','Hrvatski Leskovac',''),('HR','HVA','Hvar','Hvar',''),('HR','ILO','Ilok','Ilok',''),('HR','IST','Ist','Ist',''),('HR','JAB','Jablanac','Jablanac',''),('HR','JBO','Jastrebarsko','Jastrebarsko',''),('HR','JDR','Jadrija','Jadrija',''),('HR','JNC','Jablanovec','Jablanovec',''),('HR','JSA','Jelsa','Jelsa',''),('HR','KAB','Karlobag','Karlobag',''),('HR','KAR','Karlovac','Karlovac',''),('HR','KLK','Klek','Klek',''),('HR','KMN','Klimno','Klimno',''),('HR','KMZ','Komiza','Komiza',''),('HR','KNA','Klana','Klana',''),('HR','KNI','Knin','Knin',''),('HR','KOP','Koprno','Koprno',''),('HR','KOR','Korcula','Korcula',''),('HR','KOV','Koprivnica','Koprivnica',''),('HR','KPA','Krapina','Krapina',''),('HR','KPR','Kaprije','Kaprije',''),('HR','KRA','Kraljevica','Kraljevica',''),('HR','KRI','Krizevci','Krizevci',''),('HR','KRK','Krk','Krk',''),('HR','KRM','Koromacno','Koromacno',''),('HR','KRZ','Kriz','Kriz',''),('HR','KUT','Kutina','Kutina',''),('HR','LAM','Lamjane','Lamjane',''),('HR','LKE','Lokve','Lokve',''),('HR','LKR','Lokrum','Lokrum',''),('HR','LPD','Lopud','Lopud',''),('HR','LPR','Lopar','Lopar',''),('HR','LST','Lastovo','Lastovo',''),('HR','LSZ','Mali Losinj','Mali Losinj',''),('HR','MAK','Makarska','Makarska',''),('HR','MAL','Malinska','Malinska',''),('HR','MAS','Maslenica','Maslenica',''),('HR','MAV','Martinska Ves Desna','Martinska Ves Desna',''),('HR','MCC','Macinec','Macinec',''),('HR','MET','Metkovi?','Metkovi?',''),('HR','MHV','Mohovo','Mohovo',''),('HR','MIL','Milna','Milna',''),('HR','MNK','Misnjak','Misnjak',''),('HR','MOD','Moscenicka Draga','Moscenicka Draga',''),('HR','MPD','Moslavina Podravska','Moslavina Podravska',''),('HR','MRG','Merag','Merag',''),('HR','MRJ','Muna na Zirju','Muna na Zirju',''),('HR','MSC','Marusevec','Marusevec',''),('HR','MTA','Martinscica','Martinscica',''),('HR','MUR','Murter','Murter',''),('HR','MVN','Motovun','Motovun',''),('HR','NDN','Nadin','Nadin',''),('HR','NEM','Nemetin','Nemetin',''),('HR','NGR','Nova Gradiska','Nova Gradiska',''),('HR','NLE','Nedelise','Nedelise',''),('HR','NRZ','Nerezine','Nerezine',''),('HR','NVD','Novi Vinodolski','Novi Vinodolski',''),('HR','NVG','Novigrad','Novigrad',''),('HR','NVL','Novalja','Novalja',''),('HR','NVM','Novi Marof','Novi Marof',''),('HR','OGU','Ogulin','Ogulin',''),('HR','OMI','Omisalj','Omisalj',''),('HR','OMS','Omis','Omis',''),('HR','ONJ','Obonjan','Obonjan',''),('HR','OPA','Opatija','Opatija',''),('HR','OPT','Opatovac','Opatovac',''),('HR','ORB','Orebic','Orebic',''),('HR','OSI','Osijek','Osijek',''),('HR','OTO','Oto?ac','Oto?ac',''),('HR','OVA','Orahovica','Orahovica',''),('HR','OVC','Oriovac','Oriovac',''),('HR','PAG','Pag','Pag',''),('HR','PAZ','Pazin','Pazin',''),('HR','PCA','Pucisca','Pucisca',''),('HR','PGA','Pregrada','Pregrada',''),('HR','PIJ','Petrinja','Petrinja',''),('HR','PLA','Polace','Polace',''),('HR','PLE','Ploce','Ploce',''),('HR','PLM','Plomin','Plomin',''),('HR','PMN','Pomena','Pomena',''),('HR','PNT','Punat','Punat',''),('HR','POR','Porec','Porec',''),('HR','POS','Postire','Postire',''),('HR','PRE','Preko','Preko',''),('HR','PRI','Primosten','Primosten',''),('HR','PRN','Prizna','Prizna',''),('HR','PRP','Prapratno','Prapratno',''),('HR','PRS','Prvic Sepurine','Prvic Sepurine',''),('HR','PRV','Prvic','Prvic',''),('HR','PRZ','Porozina','Porozina',''),('HR','PUY','Pula','Pula',''),('HR','PZG','Pozega','Pozega',''),('HR','RAB','Rab','Rab',''),('HR','RAS','Rasa','Rasa',''),('HR','RBC','Rabac','Rabac',''),('HR','RGC','Rogac','Rogac',''),('HR','RGN','Rogoznica','Rogoznica',''),('HR','RGO','Ravna Gora','Ravna Gora',''),('HR','RJK','Rijeka','Rijeka',''),('HR','ROG','Rogotin','Rogotin',''),('HR','ROV','Rovinj','Rovinj',''),('HR','RSA','Rasinja','Rasinja',''),('HR','SAL','Sali','Sali',''),('HR','SBC','Stobrec','Stobrec',''),('HR','SBD','Slavonski Brod','Slavonski Brod',''),('HR','SBR','Sobra','Sobra',''),('HR','SDA','Satnica Dakovac?ka','Satnica Dakovac?ka',''),('HR','SDR','Sudurad','Sudurad',''),('HR','SEN','Senj','Senj',''),('HR','SGA','Strigova','Strigova',''),('HR','SGD','Stari Grad','Stari Grad',''),('HR','SGR','Starigrad','Starigrad',''),('HR','SIB','Sibenik','Sibenik',''),('HR','SIL','Silba','Silba',''),('HR','SIN','Sinj','Sinj',''),('HR','SIS','Sisak','Sisak',''),('HR','SIZ','Sveti Ivan Zelina','Sveti Ivan Zelina',''),('HR','SJO','Skrljevo','Skrljevo',''),('HR','SLA','Slano','Slano',''),('HR','SLC','Selce','Selce',''),('HR','SLM','Slum','Slum',''),('HR','SLN','Solin','Solin',''),('HR','SLO','Silo','Silo',''),('HR','SLT','Slatine','Slatine',''),('HR','SLU','Slunj','Slunj',''),('HR','SMN','Sumartin','Sumartin',''),('HR','SOT','Sotin','Sotin',''),('HR','SPU','Split','Split',''),('HR','SRD','Skradin','Skradin',''),('HR','SRG','Sarengrad','Sarengrad',''),('HR','SSK','Susak','Susak',''),('HR','STM','Stomorska','Stomorska',''),('HR','STO','Ston','Ston',''),('HR','STP','Sustjepan','Sustjepan',''),('HR','SUC','Sucuraj','Sucuraj',''),('HR','SUP','Supetar','Supetar',''),('HR','SUR','Sucurac','Sucurac',''),('HR','SUS','Rijeka Susak','Rijeka Susak',''),('HR','SVJ','Sveti Juraj','Sveti Juraj',''),('HR','SVK','Sveti Kajo','Sveti Kajo',''),('HR','SVN','Sveta Nedjelja','Sveta Nedjelja',''),('HR','TJI','Trnjani','Trnjani',''),('HR','TJN','Tinjan','Tinjan',''),('HR','TKN','Tkon','Tkon',''),('HR','TNO','Tisno','Tisno',''),('HR','TNR','Tunarica','Tunarica',''),('HR','TPO','Terezino Polje','Terezino Polje',''),('HR','TRB','Trnovec Bartolovecki','Trnovec Bartolovecki',''),('HR','TRJ','Trpanj','Trpanj',''),('HR','TRK','Trstenik','Trstenik',''),('HR','TRO','Trogir','Trogir',''),('HR','UBL','Ubli','Ubli',''),('HR','UMG','Umag','Umag',''),('HR','UNJ','Unije','Unije',''),('HR','VDC','Vodice','Vodice',''),('HR','VGN','Viganj','Viganj',''),('HR','VGO','Velika Gorica','Velika Gorica',''),('HR','VIN','Vinkovci','Vinkovci',''),('HR','VIR','Vir','Vir',''),('HR','VIS','Vis','Vis',''),('HR','VKO','Velika Kopanica','Velika Kopanica',''),('HR','VKV','Viskovo','Viskovo',''),('HR','VLB','Valbiska','Valbiska',''),('HR','VLK','Vela Luka','Vela Luka',''),('HR','VLN','Veli Losinj','Veli Losinj',''),('HR','VRA','Vranjic','Vranjic',''),('HR','VRB','Vrbovec','Vrbovec',''),('HR','VRC','Virovitica','Virovitica',''),('HR','VRG','Vrgada','Vrgada',''),('HR','VRK','Vrbnik','Vrbnik',''),('HR','VRN','Vranjic','Vranjic',''),('HR','VRR','Vrsar','Vrsar',''),('HR','VRS','Vrboska','Vrboska',''),('HR','VUK','Vukovar','Vukovar',''),('HR','VZN','Varazdin','Varazdin',''),('HR','ZAD','Zadar','Zadar',''),('HR','ZAG','Zagreb','Zagreb',''),('HR','ZBK','Zabok','Zabok',''),('HR','ZGL','Zigljen','Zigljen',''),('HR','ZLA','Zlatar','Zlatar',''),('HR','ZLR','Zlarin','Zlarin',''),('HR','ZMJ','Zminj','Zminj',''),('HR','ZUP','Zupanja','Zupanja',''),('HT','','','',''),('HT','ACA','Les Cayes','Les Cayes',''),('HT','CAP','Cap-Haitien','Cap-Haitien',''),('HT','CRC','Caracol','Caracol',''),('HT','FLI','Fort Liberte','Fort Liberte',''),('HT','FOM','Fond Mombin','Fond Mombin',''),('HT','GVS','Gonaives','Gonaives',''),('HT','JAK','Jacmel','Jacmel',''),('HT','JEE','Jeremie','Jeremie',''),('HT','LFF','Laffiteau','Laffiteau',''),('HT','MIR','Miragoane','Miragoane',''),('HT','PAP','Port-au-Prince','Port-au-Prince',''),('HT','PDP','Port de Paix','Port de Paix',''),('HT','PEG','Petit Goave','Petit Goave',''),('HT','PTY','Poty','Poty',''),('HT','SMC','St Marc','St Marc',''),('HU','','','',''),('HU','ABO','Abony','Abony',''),('HU','ADY','Adony','Adony',''),('HU','AFU','Almasfuzito','Almasfuzito',''),('HU','AGE','Agerdomajor','Agerdomajor',''),('HU','AGF','Agfalva','Agfalva',''),('HU','AGG','Aggtelek','Aggtelek',''),('HU','AJK','Ajka','Ajka',''),('HU','AKT','Andornaktalya','Andornaktalya',''),('HU','ALA','Alattyan','Alattyan',''),('HU','ALB','Albertirsa','Albertirsa',''),('HU','ALS','Alsoors','Alsoors',''),('HU','APG','Apostag','Apostag',''),('HU','ART','Artand','Artand',''),('HU','BAA','Baja','Baja',''),('HU','BAB','Babolna','Babolna',''),('HU','BAJ','Bajansenye','Bajansenye',''),('HU','BAL','Balassagyarmat','Balassagyarmat',''),('HU','BAN','Banreve','Banreve',''),('HU','BEK','Bekescsaba','Bekescsaba',''),('HU','BES','Bekes','Bekes',''),('HU','BGO','Bagod','Bagod',''),('HU','BIC','Bicske','Bicske',''),('HU','BIH','Biharkeresztes','Biharkeresztes',''),('HU','BLT','Balatonboglar','Balatonboglar',''),('HU','BOL','Boly','Boly',''),('HU','BON','Bonyhad','Bonyhad',''),('HU','BTB','Biatorbagy','Biatorbagy',''),('HU','BTF','Berettyoufalu','Berettyoufalu',''),('HU','BUA','Budaors','Budaors',''),('HU','BUC','Bucsu','Bucsu',''),('HU','BUD','Budapest','Budapest',''),('HU','BUK','Buk','Buk',''),('HU','BZE','Berzence','Berzence',''),('HU','CEG','Cegled','Cegled',''),('HU','CGD','Csongrad','Csongrad',''),('HU','CGE','Csenger','Csenger',''),('HU','CMR','Csomor','Csomor',''),('HU','CPE','Csepel','Csepel',''),('HU','CSD','Cserszegtomaj','Cserszegtomaj',''),('HU','CSE','Csengersima','Csengersima',''),('HU','CSO','Csorna','Csorna',''),('HU','CSU','Csurgo','Csurgo',''),('HU','CSV','Csorvas','Csorvas',''),('HU','DDA','Dudar','Dudar',''),('HU','DEB','Debrecen','Debrecen',''),('HU','DKI','Dunakiliti','Dunakiliti',''),('HU','DKZ','Dunakeszi','Dunakeszi',''),('HU','DOB','Dombovar','Dombovar',''),('HU','DPA','Dunapataj','Dunapataj',''),('HU','DRA','Dravaszabolcs','Dravaszabolcs',''),('HU','DRE','Dunaremete','Dunaremete',''),('HU','DSZ','Dunaharaszti','Dunaharaszti',''),('HU','DUK','Dunavarsany','Dunavarsany',''),('HU','DUU','Dunaujvaros','Dunaujvaros',''),('HU','DUZ','Dunaszentmiklos','Dunaszentmiklos',''),('HU','DVE','Dunavecse','Dunavecse',''),('HU','EDF','Endrefalva','Endrefalva',''),('HU','EGR','Eger','Eger',''),('HU','ELK','Elek','Elek',''),('HU','ENC','Encs','Encs',''),('HU','EPE','Eperjeske','Eperjeske',''),('HU','EST','Esztergom','Esztergom',''),('HU','FAC','Facankert','Facankert',''),('HU','FEO','Fertod','Fertod',''),('HU','FER','Fertoujlak','Fertoujlak',''),('HU','FEZ','Fertrszentmiklos','Fertrszentmiklos',''),('HU','FNY','Felsonyek','Felsonyek',''),('HU','FOT','Fot','Fot',''),('HU','FUO','Fugod','Fugod',''),('HU','GDL','Godollo','Godollo',''),('HU','GGY','Gyongyos','Gyongyos',''),('HU','GNY','Gonyu','Gonyu',''),('HU','GOA','Goganfa','Goganfa',''),('HU','GRL','Gerla','Gerla',''),('HU','GYE','Gyekenyes','Gyekenyes',''),('HU','GYG','Gyongyos','Gyongyos',''),('HU','GYH','Gyomaendrod','Gyomaendrod',''),('HU','GYJ','Gyongyostarjan','Gyongyostarjan',''),('HU','GYL','Gyal','Gyal',''),('HU','GYO','Gyor','Gyor',''),('HU','GYR','Gyomro','Gyomro',''),('HU','GYU','Gyula','Gyula',''),('HU','HAB','Halasztelek','Halasztelek',''),('HU','HAJ','Hajduboszormeny','Hajduboszormeny',''),('HU','HAL','Halasztelek','Halasztelek',''),('HU','HAT','Hatvan','Hatvan',''),('HU','HDM','Hodmezovasarhely','Hodmezovasarhely',''),('HU','HEG','Hegyeshalom','Hegyeshalom',''),('HU','HER','Hercegszanto','Hercegszanto',''),('HU','HEV','Heves','Heves',''),('HU','HIS','Hidasnemeti','Hidasnemeti',''),('HU','HMV','Hodmez?vasarhely','Hodmez?vasarhely',''),('HU','HRY','Hater','Hater',''),('HU','IPO','Ipolytarnoc','Ipolytarnoc',''),('HU','IPS','Ipolytolgyes','Ipolytolgyes',''),('HU','JAF','Jaszfenyszaru','Jaszfenyszaru',''),('HU','JAN','Janossomorja','Janossomorja',''),('HU','JAO','Janoshalma','Janoshalma',''),('HU','JAS','Jaszbereny','Jaszbereny',''),('HU','JHA','Janoshaza','Janoshaza',''),('HU','JKZ','Jaszarokszallas','Jaszarokszallas',''),('HU','JSZ','Jaszapati','Jaszapati',''),('HU','KAB','Kaba','Kaba',''),('HU','KAR','Karcag','Karcag',''),('HU','KAZ','Kazincbarcika','Kazincbarcika',''),('HU','KCO','Kalocsa','Kalocsa',''),('HU','KCS','Kecskemet','Kecskemet',''),('HU','KEL','Kelebia','Kelebia',''),('HU','KER','Kernye','Kernye',''),('HU','KEZ','Keszthely','Keszthely',''),('HU','KGY','Kerekegyhaza','Kerekegyhaza',''),('HU','KIA','Kisvarda','Kisvarda',''),('HU','KIS','Kiskunfelegyhaza','Kiskunfelegyhaza',''),('HU','KIT','Kistarcsa','Kistarcsa',''),('HU','KKS','Kisk?ros','Kisk?ros',''),('HU','KLK','Kistelek','Kistelek',''),('HU','KMD','Kunmadaras','Kunmadaras',''),('HU','KMJ','Kiskunmajsa','Kiskunmajsa',''),('HU','KOM','Komarom','Komarom',''),('HU','KOR','Kormend','Kormend',''),('HU','KOS','Koszeg','Koszeg',''),('HU','KOT','Kotegyan','Kotegyan',''),('HU','KPS','Kaposvar','Kaposvar',''),('HU','KRK','Kereki','Kereki',''),('HU','KSD','Korosladany','Korosladany',''),('HU','KSK','Kiskunhalas','Kiskunhalas',''),('HU','KVE','Kevermes','Kevermes',''),('HU','KVP','Kapuvar','Kapuvar',''),('HU','LAB','Labatlan','Labatlan',''),('HU','LAJ','Lajosmizse','Lajosmizse',''),('HU','LET','Letenye','Letenye',''),('HU','LMY','Lagymanyos','Lagymanyos',''),('HU','LOK','Lokoshaza','Lokoshaza',''),('HU','MAD','Madocsa','Madocsa',''),('HU','MAR','Marcali','Marcali',''),('HU','MAT','Mateszalka','Mateszalka',''),('HU','MCQ','Miskolc','Miskolc',''),('HU','MEZ','Mezokovesd','Mezokovesd',''),('HU','MFE','Martfu','Martfu',''),('HU','MGB','Magyarboly','Magyarboly',''),('HU','MGF','Magyarfalva','Magyarfalva',''),('HU','MIR','Mirelite','Mirelite',''),('HU','MKN','Mecseknadasd','Mecseknadasd',''),('HU','MKS','Mezokovacshaza','Mezokovacshaza',''),('HU','MNM','Mosonmagyarovar','Mosonmagyarovar',''),('HU','MOH','Mohacs','Mohacs',''),('HU','MOR','Mor','Mor',''),('HU','MOZ','Mosonszolnok','Mosonszolnok',''),('HU','MUR','Murakeresztur','Murakeresztur',''),('HU','MYH','Magyarbanhegyes','Magyarbanhegyes',''),('HU','MYZ','Mihalyhaza','Mihalyhaza',''),('HU','MZY','Mezobereny','Mezobereny',''),('HU','NAD','Nadudvar','Nadudvar',''),('HU','NAG','Nagylak','Nagylak',''),('HU','NAY','Nagyigmand','Nagyigmand',''),('HU','NBR','Nyirbator','Nyirbator',''),('HU','NEM','Nemesvamos','Nemesvamos',''),('HU','NGD','Nagyrede','Nagyrede',''),('HU','NGH','Nyiregyhaza','Nyiregyhaza',''),('HU','NGT','Nagyatad','Nagyatad',''),('HU','NGY','Nagykanizsa','Nagykanizsa',''),('HU','NKS','Nagykoros','Nagykoros',''),('HU','NSZ','Neszmely','Neszmely',''),('HU','NYI','Nyirabrany','Nyirabrany',''),('HU','NYR','Nyirgelse','Nyirgelse',''),('HU','OCS','Ocsa','Ocsa',''),('HU','ORO','Oroszlany','Oroszlany',''),('HU','ORS','Oroshaza','Oroshaza',''),('HU','PAK','Paks','Paks',''),('HU','PAP','Papa','Papa',''),('HU','PAR','Parassapuszta','Parassapuszta',''),('HU','PEC','Pecs','Pecs',''),('HU','PER','Perkupa','Perkupa',''),('HU','PLL','Pilisvorosvar','Pilisvorosvar',''),('HU','PSU','Pusztaszabolcs','Pusztaszabolcs',''),('HU','PTY','Paty','Paty',''),('HU','RAA','Rackeve','Rackeve',''),('HU','RAB','Rabafuzes','Rabafuzes',''),('HU','RDE','Erdokertes','Erdokertes',''),('HU','RED','Redics','Redics',''),('HU','RJB','Rajkabrany','Rajkabrany',''),('HU','RJK','Rajka','Rajka',''),('HU','ROS','Roszke','Roszke',''),('HU','RPK','Repcelak','Repcelak',''),('HU','RSP','Sarospatak','Sarospatak',''),('HU','RTG','Retsag','Retsag',''),('HU','SAG','Sagvar','Sagvar',''),('HU','SAJ','Sajoszentpeter','Sajoszentpeter',''),('HU','SAL','Salgotarjan','Salgotarjan',''),('HU','SAT','Satoraljaujhely','Satoraljaujhely',''),('HU','SBG','Sarbogard','Sarbogard',''),('HU','SCY','Szecseny','Szecseny',''),('HU','SGY','Szabadegyhaza','Szabadegyhaza',''),('HU','SHA','Szeghalom','Szeghalom',''),('HU','SHO','Szazhalombatta','Szazhalombatta',''),('HU','SIK','Siklos','Siklos',''),('HU','SIO','Siofok','Siofok',''),('HU','SMI','Sarszentmihaly','Sarszentmihaly',''),('HU','SMS','Szorgalmatos','Szorgalmatos',''),('HU','SNA','Szentlorinckata','Szentlorinckata',''),('HU','SNM','Alsonemedi','Alsonemedi',''),('HU','SOB','Sarmellek','Sarmellek',''),('HU','SOM','Somoskoujfalu','Somoskoujfalu',''),('HU','SOP','Sopron','Sopron',''),('HU','SPG','Sopron Gysev','Sopron Gysev',''),('HU','SRY','Simontornya','Simontornya',''),('HU','SVR','Sarvar','Sarvar',''),('HU','SVS','Szarvas','Szarvas',''),('HU','SVY','Savoly','Savoly',''),('HU','SYG','Szugy','Szugy',''),('HU','SZA','Szalanta','Szalanta',''),('HU','SZB','Szazhalombatta','Szazhalombatta',''),('HU','SZC','Szerencs','Szerencs',''),('HU','SZD','Szentendre','Szentendre',''),('HU','SZE','Szeged','Szeged',''),('HU','SZG','Szentgotthard','Szentgotthard',''),('HU','SZI','Szigetvar','Szigetvar',''),('HU','SZJ','Szajol','Szajol',''),('HU','SZK','Szekszard','Szekszard',''),('HU','SZL','Szolnok','Szolnok',''),('HU','SZM','Szigetszentmiklos','Szigetszentmiklos',''),('HU','SZO','Szob','Szob',''),('HU','SZR','Szekesfehervar','Szekesfehervar',''),('HU','SZV','Szarcsas','Szarcsas',''),('HU','SZY','Szombathely','Szombathely',''),('HU','TAA','Tatabanya','Tatabanya',''),('HU','TAP','Tapolca','Tapolca',''),('HU','TAT','Tata','Tata',''),('HU','TEL','Telekgerendas','Telekgerendas',''),('HU','TKB','Torokbalint','Torokbalint',''),('HU','TOD','Tornanadaska','Tornanadaska',''),('HU','TOK','Torokszentmiklos','Torokszentmiklos',''),('HU','TOM','Tompa','Tompa',''),('HU','TON','Tornyosnemeti','Tornyosnemeti',''),('HU','TOS','Tolcsva','Tolcsva',''),('HU','TRC','Tarcal','Tarcal',''),('HU','TZK','Tiszalok','Tiszalok',''),('HU','TZS','Tiszaujvaros','Tiszaujvaros',''),('HU','TZV','Tiszavasvari','Tiszavasvari',''),('HU','UDV','Udvar','Udvar',''),('HU','UJH','Ujhartyan','Ujhartyan',''),('HU','ULL','Ullo','Ullo',''),('HU','UPS','Ujpest','Ujpest',''),('HU','VAC','Vac','Vac',''),('HU','VAM','Vamosszabadi','Vamosszabadi',''),('HU','VAR','Varpalota','Varpalota',''),('HU','VEC','Vecses','Vecses',''),('HU','VEL','Velence','Velence',''),('HU','VER','Verocemaros','Verocemaros',''),('HU','VGY','Veresegyhaz','Veresegyhaz',''),('HU','VIG','Visegrad','Visegrad',''),('HU','VIL','Villany','Villany',''),('HU','VRP','Verpelet','Verpelet',''),('HU','VSZ','Vasszecseny','Vasszecseny',''),('HU','VVR','Vasvar','Vasvar',''),('HU','VZP','Veszprem','Veszprem',''),('HU','ZAH','Zahony','Zahony',''),('HU','ZAK','Zalakomar','Zalakomar',''),('HU','ZAL','Zala','Zala',''),('HU','ZER','Zalaegerszeg','Zalaegerszeg',''),('HU','ZRC','Zirc','Zirc',''),('ID','','','',''),('ID','ABU','Atambua','Atambua',''),('ID','ADB','Adang Bay','Adang Bay',''),('ID','AHI','Amahai','Amahai',''),('ID','AJN','Arjuna, Java','Arjuna, Java',''),('ID','AMA','Amamapare, Ij','Amamapare, Ij',''),('ID','AMI','Mataram','Mataram',''),('ID','AMP','Ampenan, Bali','Ampenan, Bali',''),('ID','AMQ','Ambon, Molucas','Ambon, Molucas',''),('ID','ANR','Anyer Kidul','Anyer Kidul',''),('ID','API','Api Api','Api Api',''),('ID','ARB','Aroe Bay','Aroe Bay',''),('ID','ARD','Alor Island','Alor Island',''),('ID','AUN','Arun','Arun',''),('ID','BAK','Batu Kilat','Batu Kilat',''),('ID','BAL','Balongan Terminal','Balongan Terminal',''),('ID','BCH','Baucau','Baucau',''),('ID','BDJ','Banjarmasin','Banjarmasin',''),('ID','BDO','Bandung, Java','Bandung, Java',''),('ID','BEJ','Berau','Berau',''),('ID','BEK','Bekapai Terminal','Bekapai Terminal',''),('ID','BEN','Benete','Benete',''),('ID','BGG','Banggai','Banggai',''),('ID','BIK','Biak, Irian Jaya','Biak, Irian Jaya',''),('ID','BIR','Biringkassi','Biringkassi',''),('ID','BIT','Bitung, Sulawesi','Bitung, Sulawesi',''),('ID','BJG','Bolaang','Bolaang',''),('ID','BJU','Banjuwangi, Java','Banjuwangi, Java',''),('ID','BJW','Bajawa','Bajawa',''),('ID','BKA','Bekasi','Bekasi',''),('ID','BKI','Bengkalis, St','Bengkalis, St',''),('ID','BKS','Bengkulu, Sumatra','Bengkulu, Sumatra',''),('ID','BLI','Blinju, Banka','Blinju, Banka',''),('ID','BLL','Blang Lancang, St','Blang Lancang, St',''),('ID','BLT','Belitung','Belitung',''),('ID','BLV','Beliling','Beliling',''),('ID','BLW','Belawan, Sumatra','Belawan, Sumatra',''),('ID','BMT','Bima Terminal, Jv','Bima Terminal, Jv',''),('ID','BMU','Bima, Sb','Bima, Sb',''),('ID','BNG','Bonggala','Bonggala',''),('ID','BOA','Benoa, Bali','Benoa, Bali',''),('ID','BOG','Bogor','Bogor',''),('ID','BPN','Balikpapan, Kalimantan','Balikpapan, Kalimantan',''),('ID','BTH','Batam (ex Batu Besar)','Batam (ex Batu Besar)',''),('ID','BTJ','Banda Aceh','Banda Aceh',''),('ID','BTM','Batam Island','Batam Island',''),('ID','BTN','Banten','Banten',''),('ID','BTW','Batulicin','Batulicin',''),('ID','BUA','Bula','Bula',''),('ID','BUG','Buleleng, Bali','Buleleng, Bali',''),('ID','BUI','Bokondini','Bokondini',''),('ID','BUN','Buatan','Buatan',''),('ID','BUR','Batu Ampal','Batu Ampal',''),('ID','BUW','Baubau, Butung','Baubau, Butung',''),('ID','BXD','Bade','Bade',''),('ID','BXT','Bontang, Kl','Bontang, Kl',''),('ID','CBN','Cirebon (Tjeribon)','Cirebon (Tjeribon)',''),('ID','CEB','Celukan Bawang, Bl','Celukan Bawang, Bl',''),('ID','CEN','Cengkareng','Cengkareng',''),('ID','CGK','Soekarno-Hatta Apt/Jakarta','Soekarno-Hatta Apt/Jakarta',''),('ID','CIG','Cigading','Cigading',''),('ID','CIK','Cikampek','Cikampek',''),('ID','CIN','Cinta, Java','Cinta, Java',''),('ID','CIW','Ciwandan','Ciwandan',''),('ID','CSA','Cape Sago','Cape Sago',''),('ID','CTT','Ciputat','Ciputat',''),('ID','CXP','Cilacap (Tjilatjap)','Cilacap (Tjilatjap)',''),('ID','DAS','Dabo, Singkep Isl','Dabo, Singkep Isl',''),('ID','DIV','Diviematra','Diviematra',''),('ID','DJA','Djankar','Djankar',''),('ID','DJB','Jambi, Sumatra','Jambi, Sumatra',''),('ID','DJJ','Jayapura, Irian Jaya','Jayapura, Irian Jaya',''),('ID','DMA','Demta','Demta',''),('ID','DOB','Dobo','Dobo',''),('ID','DOG','Donggi','Donggi',''),('ID','DPS','Denpasar, Bali','Denpasar, Bali',''),('ID','DUM','Dumai, Sumatra','Dumai, Sumatra',''),('ID','ENE','Ende, Flores','Ende, Flores',''),('ID','ENO','Kuala Enok','Kuala Enok',''),('ID','EWE','Ewer','Ewer',''),('ID','EWI','Enarotali','Enarotali',''),('ID','FKQ','Fak Fak, Irian Jaya','Fak Fak, Irian Jaya',''),('ID','FOO','Numfoor','Numfoor',''),('ID','GAG','Gag Island','Gag Island',''),('ID','GEB','Gebe','Gebe',''),('ID','GIL','Gilimanuk, Bali','Gilimanuk, Bali',''),('ID','GLX','Galela, Halmahera','Galela, Halmahera',''),('ID','GNS','Gunung Sitoli, St','Gunung Sitoli, St',''),('ID','GRE','Gresik, Java','Gresik, Java',''),('ID','GTO','Gorontalo, Sulawesi','Gorontalo, Sulawesi',''),('ID','ILA','Illaga','Illaga',''),('ID','JBG','Jatibarang','Jatibarang',''),('ID','JEM','Jember','Jember',''),('ID','JKT','Jakarta, Java','Jakarta, Java',''),('ID','JOG','Yogyakarta','Yogyakarta',''),('ID','JTH','Jatitujuh','Jatitujuh',''),('ID','KAB','Kabil','Kabil',''),('ID','KAH','Kahayan Bay','Kahayan Bay',''),('ID','KAM','Kambunong, Celebes','Kambunong, Celebes',''),('ID','KAR','Karosa, Sulawesi','Karosa, Sulawesi',''),('ID','KAS','Kasim, Ij','Kasim, Ij',''),('ID','KAT','Kalianget','Kalianget',''),('ID','KBF','Karubaga','Karubaga',''),('ID','KBH','Kalabahi','Kalabahi',''),('ID','KBU','Kotabaru','Kotabaru',''),('ID','KCI','Kon','Kon',''),('ID','KDI','Kendari, Sulawesi','Kendari, Sulawesi',''),('ID','KEA','Keisah','Keisah',''),('ID','KEI','Kepi','Kepi',''),('ID','KEM','Kempo, Sb','Kempo, Sb',''),('ID','KEQ','Kebar','Kebar',''),('ID','KID','Kidjang, Bintan','Kidjang, Bintan',''),('ID','KJN','Kajang','Kajang',''),('ID','KKA','Kuala Kapuas, Kl','Kuala Kapuas, Kl',''),('ID','KKB','Kunak, Borneo','Kunak, Borneo',''),('ID','KLQ','Keluang','Keluang',''),('ID','KLT','Kaltim','Kaltim',''),('ID','KMA','Kuala Mandah, Sumatra','Kuala Mandah, Sumatra',''),('ID','KMM','Kimam','Kimam',''),('ID','KNG','Kaimana, Irian Jaya','Kaimana, Irian Jaya',''),('ID','KNL','Kolonodale','Kolonodale',''),('ID','KOD','Kotabangun','Kotabangun',''),('ID','KOE','Kupang, Timor','Kupang, Timor',''),('ID','KOJ','Koja','Koja',''),('ID','KOX','Kokonao','Kokonao',''),('ID','KPN','Kotapinang, Baru','Kotapinang, Baru',''),('ID','KRC','Kerinci','Kerinci',''),('ID','KRG','Kariangau','Kariangau',''),('ID','KSE','Kassue','Kassue',''),('ID','KSO','Kalbut Situbondo','Kalbut Situbondo',''),('ID','KTG','Ketapang, Kl','Ketapang, Kl',''),('ID','KTJ','Kualatanjung','Kualatanjung',''),('ID','KTK','Kualatungkal','Kualatungkal',''),('ID','KUA','Kualalangsa','Kualalangsa',''),('ID','KUM','Kumai','Kumai',''),('ID','LAH','Labuha, Molucas','Labuha, Molucas',''),('ID','LAJ','Labuhan','Labuhan',''),('ID','LAS','Langsa, Sumatra','Langsa, Sumatra',''),('ID','LAT','Lalang Terminal, St','Lalang Terminal, St',''),('ID','LBJ','Labuanbajo','Labuanbajo',''),('ID','LBM','Lobam','Lobam',''),('ID','LBW','Long Bawan','Long Bawan',''),('ID','LHI','Lereh','Lereh',''),('ID','LHK','Lhoknga','Lhoknga',''),('ID','LIF','Lifamatola','Lifamatola',''),('ID','LII','Mulia','Mulia',''),('ID','LKA','Larantuka','Larantuka',''),('ID','LLA','Lawe-Lawe, Kl','Lawe-Lawe, Kl',''),('ID','LLN','Kelila','Kelila',''),('ID','LMB','Lombok Strait','Lombok Strait',''),('ID','LPU','Long Apung','Long Apung',''),('ID','LRT','Larat','Larat',''),('ID','LSW','Lhokseumawe','Lhokseumawe',''),('ID','LSX','Lhok Sukon','Lhok Sukon',''),('ID','LUV','Langgur','Langgur',''),('ID','LUW','Luwuk','Luwuk',''),('ID','LWE','Lewoleba','Lewoleba',''),('ID','LYK','Lunyuk','Lunyuk',''),('ID','MAJ','Majene, Sv','Majene, Sv',''),('ID','MAK','Makassar','Makassar',''),('ID','MAL','Mangole','Mangole',''),('ID','MAN','Manggar','Manggar',''),('ID','MDC','Manado','Manado',''),('ID','MDP','Mindiptana','Mindiptana',''),('ID','MDR','Madura Terminal','Madura Terminal',''),('ID','MEQ','Meulaboh, Sumatra','Meulaboh, Sumatra',''),('ID','MES','Medan, Sumatra','Medan, Sumatra',''),('ID','MGB','Manggis','Manggis',''),('ID','MJU','Mamuju','Mamuju',''),('ID','MJY','Mangunjaya','Mangunjaya',''),('ID','MKJ','Mangkajang','Mangkajang',''),('ID','MKQ','Merauke, Irian Jaya','Merauke, Irian Jaya',''),('ID','MKW','Manokwari, Irian Jaya','Manokwari, Irian Jaya',''),('ID','MLG','Malang','Malang',''),('ID','MLI','Malili, Sulawesi','Malili, Sulawesi',''),('ID','MNA','Melonguanne','Melonguanne',''),('ID','MNT','Mantang, Riau','Mantang, Riau',''),('ID','MOF','Maumere, Flores','Maumere, Flores',''),('ID','MPC','Muko-Muko','Muko-Muko',''),('ID','MPT','Maliana','Maliana',''),('ID','MRB','Merantibunting, Sumatra','Merantibunting, Sumatra',''),('ID','MRI','Musi River, Sumatra','Musi River, Sumatra',''),('ID','MRK','Merak, Java','Merak, Java',''),('ID','MSI','Masalembo','Masalembo',''),('ID','MTU','Muturi','Muturi',''),('ID','MUB','Muara Berau','Muara Berau',''),('ID','MUD','Muara Djawa','Muara Djawa',''),('ID','MUF','Muting','Muting',''),('ID','MUO','Muntok, Banka','Muntok, Banka',''),('ID','MUP','Muara Pegah','Muara Pegah',''),('ID','MWK','Matak','Matak',''),('ID','MXB','Masamba','Masamba',''),('ID','NAF','Banaina','Banaina',''),('ID','NAH','Naha','Naha',''),('ID','NAM','Namlea','Namlea',''),('ID','NBX','Nabire','Nabire',''),('ID','NDA','Bandanaira','Bandanaira',''),('ID','NKD','Sinak','Sinak',''),('ID','NNX','Nunukan','Nunukan',''),('ID','NPL','North Pulau Laut','North Pulau Laut',''),('ID','NPO','Nangapinoh','Nangapinoh',''),('ID','NRE','Namrole','Namrole',''),('ID','NTI','Bintuni','Bintuni',''),('ID','NTX','Natuna Ranai','Natuna Ranai',''),('ID','OBD','Obano','Obano',''),('ID','OBI','Obi Island','Obi Island',''),('ID','OEC','Ocussi','Ocussi',''),('ID','OJA','Olah Jasa Andal/Jakarta','Olah Jasa Andal/Jakarta',''),('ID','OKL','Oksibil','Oksibil',''),('ID','OKQ','Okaba, Irian Jaya','Okaba, Irian Jaya',''),('ID','OLO','Olee Lheue','Olee Lheue',''),('ID','ONI','Moanamani','Moanamani',''),('ID','ORA','Oransbari','Oransbari',''),('ID','OZI','Morotai I','Morotai I',''),('ID','PAG','Pagatan, Kalimantan','Pagatan, Kalimantan',''),('ID','PAI','Paiton','Paiton',''),('ID','PAL','Palu','Palu',''),('ID','PAP','Pare Pare','Pare Pare',''),('ID','PAS','Pasir Panjang','Pasir Panjang',''),('ID','PAZ','Pasuruan, Java','Pasuruan, Java',''),('ID','PBJ','Pulau Bunyu','Pulau Bunyu',''),('ID','PBW','Palibelo','Palibelo',''),('ID','PCB','Pondok Cabe','Pondok Cabe',''),('ID','PDG','Padang','Padang',''),('ID','PDJ','Tandjang','Tandjang',''),('ID','PDO','Pendopo','Pendopo',''),('ID','PEM','Pemangkat, Kl','Pemangkat, Kl',''),('ID','PER','Perawang','Perawang',''),('ID','PEX','Pekalongan, Java','Pekalongan, Java',''),('ID','PGA','Pagerungan','Pagerungan',''),('ID','PGK','Pangkalpinang, Banka','Pangkalpinang, Banka',''),('ID','PGX','Pangkal Balam, Banka','Pangkal Balam, Banka',''),('ID','PJG','Panjang (Lampung, Sumatra)','Panjang (Lampung, Sumatra)',''),('ID','PJM','Pandjung Mani','Pandjung Mani',''),('ID','PKN','Pangkalanbuun','Pangkalanbuun',''),('ID','PKR','Pangkalan Brandan, Sumatra','Pangkalan Brandan, Sumatra',''),('ID','PKS','Pangkalan Susu, Sumatra','Pangkalan Susu, Sumatra',''),('ID','PKU','Pekanbaru, Sumatra','Pekanbaru, Sumatra',''),('ID','PKY','Palangkaraya','Palangkaraya',''),('ID','PLA','Plaju, Sumatra','Plaju, Sumatra',''),('ID','PLM','Palembang, Sumatra','Palembang, Sumatra',''),('ID','PMG','Port Meneng','Port Meneng',''),('ID','PNG','Penuba','Penuba',''),('ID','PNJ','Panjang','Panjang',''),('ID','PNK','Pontianak, Kalimantan','Pontianak, Kalimantan',''),('ID','PNN','Pamanukan, Java','Pamanukan, Java',''),('ID','PNT','Prointal, Jv','Prointal, Jv',''),('ID','PPJ','Pulau Panjang','Pulau Panjang',''),('ID','PPO','Palapo, Sulawesi','Palapo, Sulawesi',''),('ID','PPS','Pulangpisau','Pulangpisau',''),('ID','PRN','Panarukan, Java','Panarukan, Java',''),('ID','PRO','Probolinggo, Java','Probolinggo, Java',''),('ID','PSJ','Poso, Sulawesi','Poso, Sulawesi',''),('ID','PSS','Pulau Sambu, Riau','Pulau Sambu, Riau',''),('ID','PSU','Putussibau','Putussibau',''),('ID','PTL','Pantoloan, Sv','Pantoloan, Sv',''),('ID','PTO','Port Okha','Port Okha',''),('ID','PUM','Pomalaa, Sulawesi','Pomalaa, Sulawesi',''),('ID','PUR','Purwakarta','Purwakarta',''),('ID','PUT','Pulau Laut','Pulau Laut',''),('ID','PWG','Perawang, Sumatra','Perawang, Sumatra',''),('ID','PWL','Purwokerto','Purwokerto',''),('ID','RAQ','Raha','Raha',''),('ID','RDE','Merdey','Merdey',''),('ID','REM','Rembang','Rembang',''),('ID','RGT','Rengat, Sumatra','Rengat, Sumatra',''),('ID','RKI','Rokot','Rokot',''),('ID','RKO','Sipora','Sipora',''),('ID','RNI','Ranai','Ranai',''),('ID','RSK','Ransiki','Ransiki',''),('ID','RTG','Ruteng, Flores','Ruteng, Flores',''),('ID','RTI','Roti','Roti',''),('ID','RUF','Yuruf','Yuruf',''),('ID','SAD','Sadau, Borneo','Sadau, Borneo',''),('ID','SAE','Sangir','Sangir',''),('ID','SAN','Sanang, Celebes','Sanang, Celebes',''),('ID','SAS','Sasayap','Sasayap',''),('ID','SAT','Santan Terminal, Kl','Santan Terminal, Kl',''),('ID','SAU','Sawu','Sawu',''),('ID','SBG','Sabang, Sumatra','Sabang, Sumatra',''),('ID','SBS','Sambas, Kalimantan','Sambas, Kalimantan',''),('ID','SEB','Sebangan Bay, Kalimantan','Sebangan Bay, Kalimantan',''),('ID','SEG','Segama, Borneo','Segama, Borneo',''),('ID','SEH','Senggeh','Senggeh',''),('ID','SEQ','Sungai Pakning, Sumatra','Sungai Pakning, Sumatra',''),('ID','SER','Serang','Serang',''),('ID','SGO','Port Segoro Fajar Satryo/Jakarta','Port Segoro Fajar Satryo/Jakarta',''),('ID','SGQ','Sanggata','Sanggata',''),('ID','SIA','Siak Yechil, Riau','Siak Yechil, Riau',''),('ID','SID','Sidangoli','Sidangoli',''),('ID','SIQ','Singkep Isl Apt','Singkep Isl Apt',''),('ID','SIW','Sibisa','Sibisa',''),('ID','SKI','Sangkulirang, Kalimantan','Sangkulirang, Kalimantan',''),('ID','SKK','Soengei Kolak','Soengei Kolak',''),('ID','SKP','Sekupang','Sekupang',''),('ID','SKT','Surakarta','Surakarta',''),('ID','SKW','Singkawang, Kalimantan','Singkawang, Kalimantan',''),('ID','SLG','Sibolga, Sumatra','Sibolga, Sumatra',''),('ID','SMB','Semangka Bay, St','Semangka Bay, St',''),('ID','SMQ','Sampit, Kalimantan','Sampit, Kalimantan',''),('ID','SNG','Sinabang','Sinabang',''),('ID','SOC','Solo City','Solo City',''),('ID','SOQ','Sorong','Sorong',''),('ID','SPA','Selat Pandjang, Sumatra','Selat Pandjang, Sumatra',''),('ID','SPH','Senipah Terminal','Senipah Terminal',''),('ID','SQG','Sintang','Sintang',''),('ID','SQN','Sanana','Sanana',''),('ID','SQR','Soroako','Soroako',''),('ID','SRG','Semarang, Java','Semarang, Java',''),('ID','SRI','Samarinda, Kalimantan','Samarinda, Kalimantan',''),('ID','SSI','Siak Sri Indrapura','Siak Sri Indrapura',''),('ID','SSO','Susu','Susu',''),('ID','STU','Satui','Satui',''),('ID','SUB','Surabaya','Surabaya',''),('ID','SUG','Sungai Gerong, Sumatra','Sungai Gerong, Sumatra',''),('ID','SUP','Sumenep, Madura','Sumenep, Madura',''),('ID','SUQ','Sungai Guntung, Sumatra','Sungai Guntung, Sumatra',''),('ID','SUS','Susoh, Sumatra','Susoh, Sumatra',''),('ID','SVP','Sevivara Point','Sevivara Point',''),('ID','SWQ','Sumbawa','Sumbawa',''),('ID','SXK','Saumlaki','Saumlaki',''),('ID','SZH','Senipah','Senipah',''),('ID','TAB','Taboneo','Taboneo',''),('ID','TAN','Tanjunguban','Tanjunguban',''),('ID','TAR','Tarjun','Tarjun',''),('ID','TAX','Taliabu Island Apt, Moluccas','Taliabu Island Apt, Moluccas',''),('ID','TBA','Tanjung Bara, Kl','Tanjung Bara, Kl',''),('ID','TBG','Teluk Betung, Sumatra','Teluk Betung, Sumatra',''),('ID','TBM','Tumbang Samba','Tumbang Samba',''),('ID','TBN','Tuban, Jv','Tuban, Jv',''),('ID','TBO','Tobelo','Tobelo',''),('ID','TBR','Telukbayur','Telukbayur',''),('ID','TBT','Tandjung Batu, Riau','Tandjung Batu, Riau',''),('ID','TEG','Tegal, Java','Tegal, Java',''),('ID','TIM','Tembagapura','Tembagapura',''),('ID','TJB','Tanjung Balai','Tanjung Balai',''),('ID','TJG','Tanjung Warukin','Tanjung Warukin',''),('ID','TJP','Tanjungperak','Tanjungperak',''),('ID','TJQ','Tanjung Pandan','Tanjung Pandan',''),('ID','TJS','Tanjung Selor','Tanjung Selor',''),('ID','TKA','Telok Ayer, Kalimantan','Telok Ayer, Kalimantan',''),('ID','TKG','Bandar Lampung','Bandar Lampung',''),('ID','TLI','Tolitoli','Tolitoli',''),('ID','TMC','Tambolaka','Tambolaka',''),('ID','TMH','Tanahmerah, Kalimantan','Tanahmerah, Kalimantan',''),('ID','TMO','Telok Melano','Telok Melano',''),('ID','TMY','Tiom','Tiom',''),('ID','TNB','Tanah Grogot','Tanah Grogot',''),('ID','TNJ','Tanjung Pinang, Riau','Tanjung Pinang, Riau',''),('ID','TPK','Tapaktuan, Sumatra','Tapaktuan, Sumatra',''),('ID','TPN','Tanjung Pemancingan','Tanjung Pemancingan',''),('ID','TPP','Tanjung Priok','Tanjung Priok',''),('ID','TRG','Tangerang','Tangerang',''),('ID','TRH','Tarahan','Tarahan',''),('ID','TRK','Tarakan, Kalimantan','Tarakan, Kalimantan',''),('ID','TSE','Tanjung Sekong, Jv','Tanjung Sekong, Jv',''),('ID','TSX','Tanjung Santan','Tanjung Santan',''),('ID','TSY','Tasikmalaya','Tasikmalaya',''),('ID','TTE','Ternate, Halmahera','Ternate, Halmahera',''),('ID','TTI','Tebingtinggi','Tebingtinggi',''),('ID','TTR','Tana Toraja','Tana Toraja',''),('ID','TXM','Teminabuan','Teminabuan',''),('ID','UAI','Suai','Suai',''),('ID','UBR','Ubrub','Ubrub',''),('ID','UGU','Zugapa','Zugapa',''),('ID','UOL','Buol','Buol',''),('ID','UPG','Ujung Pandang, Sulawesi','Ujung Pandang, Sulawesi',''),('ID','VIQ','Viqueque','Viqueque',''),('ID','WAR','Waris','Waris',''),('ID','WBA','Wahai','Wahai',''),('ID','WET','Wagethe','Wagethe',''),('ID','WGP','Waingapu, Sumba','Waingapu, Sumba',''),('ID','WMX','Wamena','Wamena',''),('ID','WON','Wonosari','Wonosari',''),('ID','WSR','Wasior','Wasior',''),('ID','ZEG','Senggo','Senggo',''),('ID','ZKL','Steenkool','Steenkool',''),('ID','ZRI','Serui, Irian Jaya','Serui, Irian Jaya',''),('IE','','','',''),('IE','ABB','Abbeyleix','Abbeyleix',''),('IE','ABY','Athboy','Athboy',''),('IE','ACH','Ardcath','Ardcath',''),('IE','ADA','Adare','Adare',''),('IE','ALQ','Alexandra Quay','Alexandra Quay',''),('IE','ANN','Annagassan','Annagassan',''),('IE','ARA','Ardara','Ardara',''),('IE','ARD','Ardmore','Ardmore',''),('IE','ARE','Ardee','Ardee',''),('IE','ARK','Arklow','Arklow',''),('IE','ARN','Ardfinnan','Ardfinnan',''),('IE','ARO','Alexandra Road Oil','Alexandra Road Oil',''),('IE','ART','Ardfert','Ardfert',''),('IE','ARY','Athenry','Athenry',''),('IE','ASD','Ashford','Ashford',''),('IE','ASH','Ashbourne','Ashbourne',''),('IE','ASK','Askeaton','Askeaton',''),('IE','ATE','Athleague','Athleague',''),('IE','ATH','Athlone','Athlone',''),('IE','ATY','Athy','Athy',''),('IE','AUG','Aughinish Island','Aughinish Island',''),('IE','AUM','Aughrim','Aughrim',''),('IE','AUU','An Uaimh','An Uaimh',''),('IE','AVO','Avoca','Avoca',''),('IE','AYF','Abbeyfeale','Abbeyfeale',''),('IE','BAD','Ballindine','Ballindine',''),('IE','BAE','Ballinasloe','Ballinasloe',''),('IE','BAG','Bagenalstown','Bagenalstown',''),('IE','BAI','Bailieborough','Bailieborough',''),('IE','BAL','Baldonnel','Baldonnel',''),('IE','BAM','Ballinamore','Ballinamore',''),('IE','BAN','Ballineen','Ballineen',''),('IE','BAO','Ballyboro','Ballyboro',''),('IE','BAV','Ballivor','Ballivor',''),('IE','BAY','Baldoyle','Baldoyle',''),('IE','BBG','Balbriggan','Balbriggan',''),('IE','BBY','Ballybofey','Ballybofey',''),('IE','BDO','Bandon','Bandon',''),('IE','BFO','Burnfoot','Burnfoot',''),('IE','BGD','Ballaghaderreen','Ballaghaderreen',''),('IE','BGR','Banagher','Banagher',''),('IE','BHS','Ballyhaunis','Ballyhaunis',''),('IE','BHT','Blanchardstown','Blanchardstown',''),('IE','BIF','B & I Ferryport','B & I Ferryport',''),('IE','BIR','Birr','Birr',''),('IE','BIT','B & I Terminal','B & I Terminal',''),('IE','BLA','Blackrock','Blackrock',''),('IE','BLE','Blessington','Blessington',''),('IE','BLF','Ballyjamesduff','Ballyjamesduff',''),('IE','BLG','Ballygar','Ballygar',''),('IE','BLL','Ballina','Ballina',''),('IE','BLM','Ballymahon','Ballymahon',''),('IE','BLN','Ballycotton','Ballycotton',''),('IE','BMT','Ballymount','Ballymount',''),('IE','BNG','Bangor','Bangor',''),('IE','BOY','Boyle','Boyle',''),('IE','BRA','Bray','Bray',''),('IE','BSN','Ballyshannon','Ballyshannon',''),('IE','BTM','Baltimore','Baltimore',''),('IE','BUC','Buncrana','Buncrana',''),('IE','BUN','Bunbeg','Bunbeg',''),('IE','BUR','Burtonport','Burtonport',''),('IE','BUT','Butlerstown','Butlerstown',''),('IE','BUY','Bunclody','Bunclody',''),('IE','BYT','Bantry','Bantry',''),('IE','CAA','Castlerea','Castlerea',''),('IE','CAD','Castleisland','Castleisland',''),('IE','CAE','Carrigaline','Carrigaline',''),('IE','CAI','Cahir (An Chathair)','Cahir (An Chathair)',''),('IE','CAL','Castleconnell','Castleconnell',''),('IE','CAM','Castlebellingham','Castlebellingham',''),('IE','CAN','Carrickcarnan','Carrickcarnan',''),('IE','CAR','Carlingford','Carlingford',''),('IE','CAS','Carrickmacross','Carrickmacross',''),('IE','CAT','Castlecomer','Castlecomer',''),('IE','CAU','Causeway','Causeway',''),('IE','CAV','Cavan','Cavan',''),('IE','CAW','Carlow','Carlow',''),('IE','CBY','Castleblayney','Castleblayney',''),('IE','CCT','Coastal Control Terminal','Coastal Control Terminal',''),('IE','CEL','Celbridge','Celbridge',''),('IE','CFI','Castlefinn','Castlefinn',''),('IE','CFN','Donegal','Donegal',''),('IE','CGO','Carrigtohill','Carrigtohill',''),('IE','CHA','Charleville','Charleville',''),('IE','CHE','Cahirciveen','Cahirciveen',''),('IE','CHR','Caher','Caher',''),('IE','CKS','Crookstown','Crookstown',''),('IE','CKY','Clonakilty','Clonakilty',''),('IE','CLA','Clara','Clara',''),('IE','CLB','Castlebar','Castlebar',''),('IE','CLC','Clarecastle','Clarecastle',''),('IE','CLE','Clonee','Clonee',''),('IE','CLI','Clifden','Clifden',''),('IE','CLK','Clondalkin','Clondalkin',''),('IE','CLL','Clonmel','Clonmel',''),('IE','CLN','Cloonlara','Cloonlara',''),('IE','CLO','Cloghore','Cloghore',''),('IE','CLR','Cloghran','Cloghran',''),('IE','CLS','Clones','Clones',''),('IE','CLY','Collooney','Collooney',''),('IE','COB','Cobh','Cobh',''),('IE','COL','Collinstown','Collinstown',''),('IE','COO','Cootehill','Cootehill',''),('IE','COS','Carrick-on-Shannon','Carrick-on-Shannon',''),('IE','CPD','Castlepollard','Castlepollard',''),('IE','CRN','Corrin','Corrin',''),('IE','CRO','Crookhaven','Crookhaven',''),('IE','CTB','Castletown Bearhaven','Castletown Bearhaven',''),('IE','CTN','Castletown','Castletown',''),('IE','CTT','Clontibret','Clontibret',''),('IE','CUR','Curracloe','Curracloe',''),('IE','DAL','Dalkey','Dalkey',''),('IE','DBG','Doonbeg','Doonbeg',''),('IE','DCN','Duncannon','Duncannon',''),('IE','DDK','Dundalk','Dundalk',''),('IE','DEA','Deans Grange','Deans Grange',''),('IE','DER','Derryveagh','Derryveagh',''),('IE','DGV','Dungarvan','Dungarvan',''),('IE','DIN','Dingle','Dingle',''),('IE','DLG','Dun Laoghaire','Dun Laoghaire',''),('IE','DMN','Drumone','Drumone',''),('IE','DNB','Dunboyne','Dunboyne',''),('IE','DNL','Dunleer','Dunleer',''),('IE','DNM','Dunmore East','Dunmore East',''),('IE','DNW','Dunmanway','Dunmanway',''),('IE','DOW','Durrow','Durrow',''),('IE','DRO','Drogheda','Drogheda',''),('IE','DRU','Drumshanbo','Drumshanbo',''),('IE','DUB','Dublin','Dublin',''),('IE','DUK','Duleek','Duleek',''),('IE','DUW','Dunglow','Dunglow',''),('IE','EDE','Edenderry','Edenderry',''),('IE','ENI','Ennis','Ennis',''),('IE','ENN','Enniscorthy','Enniscorthy',''),('IE','FCW','Frank Cassin Wharf','Frank Cassin Wharf',''),('IE','FEN','Fenit','Fenit',''),('IE','FER','Fermoy','Fermoy',''),('IE','FFO','Farranfore','Farranfore',''),('IE','FID','Fiddown','Fiddown',''),('IE','FOV','Foynes','Foynes',''),('IE','GGA','Glengariff','Glengariff',''),('IE','GNV','Glasnevin','Glasnevin',''),('IE','GON','Gormanston','Gormanston',''),('IE','GOR','Gorey','Gorey',''),('IE','GOT','Gort','Gort',''),('IE','GRN','Greenore','Greenore',''),('IE','GRY','Greystones','Greystones',''),('IE','GWY','Galway','Galway',''),('IE','HAU','Haulbowline','Haulbowline',''),('IE','HOW','Howth','Howth',''),('IE','IIA','Inishmaan','Inishmaan',''),('IE','INQ','Inisheer','Inisheer',''),('IE','INV','Inveran','Inveran',''),('IE','IOR','Inishmore','Inishmore',''),('IE','IRD','Irish Rail Freight Depot','Irish Rail Freight Depot',''),('IE','KBS','Killybegs','Killybegs',''),('IE','KCK','Kilcock','Kilcock',''),('IE','KCL','Kilclare','Kilclare',''),('IE','KCT','Kingscourt','Kingscourt',''),('IE','KEN','Kenmare','Kenmare',''),('IE','KIA','Kinvarra','Kinvarra',''),('IE','KIK','Kill, Kildare','Kill, Kildare',''),('IE','KIL','Kildare','Kildare',''),('IE','KIN','Kilronan','Kilronan',''),('IE','KIR','Kerry County','Kerry County',''),('IE','KIY','Killiney','Killiney',''),('IE','KKA','Kilmokea','Kilmokea',''),('IE','KLA','Killala','Killala',''),('IE','KLK','Kilkenny','Kilkenny',''),('IE','KLL','Kells','Kells',''),('IE','KLN','Kinsale','Kinsale',''),('IE','KLR','Kilrush','Kilrush',''),('IE','KLY','Killarney','Killarney',''),('IE','KNT','Kanturk','Kanturk',''),('IE','KRN','Kilronan','Kilronan',''),('IE','LEI','Leitrim','Leitrim',''),('IE','LEX','Leixlip','Leixlip',''),('IE','LIC','Little Island/Cork','Little Island/Cork',''),('IE','LIF','Lifford','Lifford',''),('IE','LKY','Lucan','Lucan',''),('IE','LMK','Limerick','Limerick',''),('IE','LON','Longford','Longford',''),('IE','LOU','Loughrea','Loughrea',''),('IE','LST','Listowel','Listowel',''),('IE','LTH','Louth','Louth',''),('IE','LTR','Letterkenny','Letterkenny',''),('IE','MAG','Maghera','Maghera',''),('IE','MAH','Malahide','Malahide',''),('IE','MAL','Mallow','Mallow',''),('IE','MAP','Marino Point','Marino Point',''),('IE','MAY','Maynooth','Maynooth',''),('IE','MCR','Macroom','Macroom',''),('IE','MID','Midleton','Midleton',''),('IE','MIL','Millstreet','Millstreet',''),('IE','MIT','Mitchelstown','Mitchelstown',''),('IE','MLL','Mulligan','Mulligan',''),('IE','MLT','Mulhurddart','Mulhurddart',''),('IE','MOB','Moy Bridge','Moy Bridge',''),('IE','MON','Monaghan','Monaghan',''),('IE','MOT','Moneypoint','Moneypoint',''),('IE','MOU','Mountmellick','Mountmellick',''),('IE','MOV','Moville','Moville',''),('IE','MUL','Mullingar','Mullingar',''),('IE','NAA','Naas','Naas',''),('IE','NAY','Newtonabbey','Newtonabbey',''),('IE','NBR','Droichead Nua','Droichead Nua',''),('IE','NEN','Nenagh','Nenagh',''),('IE','NET','Newport','Newport',''),('IE','NEW','Newcastle West','Newcastle West',''),('IE','NMK','Newtown Mount Kennedy','Newtown Mount Kennedy',''),('IE','NNR','Spiddal','Spiddal',''),('IE','NOC','Knock','Knock',''),('IE','NOV','Oldcastle','Oldcastle',''),('IE','NRS','New Ross','New Ross',''),('IE','NVN','Navan','Navan',''),('IE','OCA','Ocallaghansmills','Ocallaghansmills',''),('IE','ORK','Cork','Cork',''),('IE','PAP','Parnell Place','Parnell Place',''),('IE','PAT','Pandoro Terminal','Pandoro Terminal',''),('IE','PGN','Portglenone','Portglenone',''),('IE','POK','Portmarnock','Portmarnock',''),('IE','POR','Portarlington','Portarlington',''),('IE','PTL','Portlaoise','Portlaoise',''),('IE','QSH','Cashel','Cashel',''),('IE','RAE','Rathkeale','Rathkeale',''),('IE','RAM','Rathmore','Rathmore',''),('IE','RAT','Rathmullan','Rathmullan',''),('IE','RAV','Rossaveel','Rossaveel',''),('IE','RCC','Rathcormack','Rathcormack',''),('IE','RCO','Rathcoole','Rathcoole',''),('IE','RIN','Ringaskiddy','Ringaskiddy',''),('IE','RNG','Rathangan','Rathangan',''),('IE','RNS','Rosenallis','Rosenallis',''),('IE','ROE','Rosslare','Rosslare',''),('IE','RON','Roscommon','Roscommon',''),('IE','ROO','Roosky','Roosky',''),('IE','ROS','Rosslare Harbour','Rosslare Harbour',''),('IE','RSC','Roscrea','Roscrea',''),('IE','RSS','Rosses Point','Rosses Point',''),('IE','RTN','Ramelton','Ramelton',''),('IE','RUS','Rushbrooke','Rushbrooke',''),('IE','RVM','River Moy','River Moy',''),('IE','SAG','Saggart','Saggart',''),('IE','SAL','Salt Hill','Salt Hill',''),('IE','SAN','Santry/Dublin','Santry/Dublin',''),('IE','SCF','Scariff','Scariff',''),('IE','SCH','Schull','Schull',''),('IE','SKE','Skerries','Skerries',''),('IE','SKL','Skull','Skull',''),('IE','SLI','Sligo','Sligo',''),('IE','SLN','Slane','Slane',''),('IE','SNN','Shannon','Shannon',''),('IE','STF','Straffan','Straffan',''),('IE','SUU','Carrick on Suir','Carrick on Suir',''),('IE','SWO','Swords','Swords',''),('IE','SXL','Sligo Apt','Sligo Apt',''),('IE','TAL','Tallaght','Tallaght',''),('IE','TAR','Tarbert','Tarbert',''),('IE','TEM','Templemore','Templemore',''),('IE','THO','Thomastown','Thomastown',''),('IE','THR','Thurles','Thurles',''),('IE','TIV','Tivoli','Tivoli',''),('IE','TME','Tramore','Tramore',''),('IE','TPY','Tipperary','Tipperary',''),('IE','TRA','Tralee','Tralee',''),('IE','TRI','Trim','Trim',''),('IE','TUB','Tubbercurry','Tubbercurry',''),('IE','TUL','Tullamore','Tullamore',''),('IE','TUW','Tullow','Tullow',''),('IE','TYA','Tynagh','Tynagh',''),('IE','UTN','Urlingford','Urlingford',''),('IE','VIR','Virginia','Virginia',''),('IE','WAL','Walkinstown','Walkinstown',''),('IE','WAT','Waterford','Waterford',''),('IE','WES','Westport','Westport',''),('IE','WEX','Wexford','Wexford',''),('IE','WGH','Watergrasshill','Watergrasshill',''),('IE','WHI','Whitegate','Whitegate',''),('IE','WIC','Wicklow','Wicklow',''),('IE','YOU','Youghal','Youghal',''),('IE','ZMY','Borris','Borris',''),('IL','','','',''),('IL','ACR','Acre','Acre',''),('IL','ADM','Adam','Adam',''),('IL','AFU','Afula','Afula',''),('IL','AKL','Ashkelon','Ashkelon',''),('IL','ALN','Alenbi','Alenbi',''),('IL','ARV','Arava','Arava',''),('IL','ASH','Ashdod','Ashdod',''),('IL','BAT','Bat Yam','Bat Yam',''),('IL','BBK','Bene Beraq','Bene Beraq',''),('IL','BET','Bet Shean','Bet Shean',''),('IL','BEV','Beer Sheba','Beer Sheba',''),('IL','BRN','Bitanit','Bitanit',''),('IL','BSE','Bet Shemesh','Bet Shemesh',''),('IL','BTZ','Beit Zera','Beit Zera',''),('IL','CAE','Caesarea','Caesarea',''),('IL','CML','Carmiel','Carmiel',''),('IL','DIM','Dimona','Dimona',''),('IL','EIY','Ein Yahav','Ein Yahav',''),('IL','ETH','Elat (Eilath)','Elat (Eilath)',''),('IL','GDA','Gedera','Gedera',''),('IL','GHK','Gush Katif','Gush Katif',''),('IL','GYV','Gan Yavne','Gan Yavne',''),('IL','HAD','Hadera','Hadera',''),('IL','HDR','Hadar \'Am','Hadar \'Am',''),('IL','HFA','Haifa','Haifa',''),('IL','HHS','Hod Ha\'Sharon','Hod Ha\'Sharon',''),('IL','HOL','Holon/Tel Aviv','Holon/Tel Aviv',''),('IL','JOR','Jordan','Jordan',''),('IL','KAN','Kannot','Kannot',''),('IL','KFS','Kafr Saba','Kafr Saba',''),('IL','KNT','Konetra','Konetra',''),('IL','KSV','Kefar Sava','Kefar Sava',''),('IL','KSW','Kiryat Shmona','Kiryat Shmona',''),('IL','LOD','Lod','Lod',''),('IL','MHK','Mishmar Ha\'emek','Mishmar Ha\'emek',''),('IL','MIP','Mitspeh Ramon','Mitspeh Ramon',''),('IL','MTL','Matula','Matula',''),('IL','MTZ','Masada','Masada',''),('IL','NAT','Netanya','Netanya',''),('IL','NWY','Newe Yamin','Newe Yamin',''),('IL','NZN','Nizana','Nizana',''),('IL','NZY','Nes Ziyyona','Nes Ziyyona',''),('IL','OYH','Or Yehuda','Or Yehuda',''),('IL','PHH','Pardes Hanna','Pardes Hanna',''),('IL','PTQ','Petah Tiqwa','Petah Tiqwa',''),('IL','QIS','Qiryat Shemona','Qiryat Shemona',''),('IL','QYB','Qiryat Bialik','Qiryat Bialik',''),('IL','QYM','Qiryat Mal\'akhi','Qiryat Mal\'akhi',''),('IL','QYT','Qiryat Gat','Qiryat Gat',''),('IL','RAA','Ra\'ananna','Ra\'ananna',''),('IL','RAH','Rafah','Rafah',''),('IL','REH','Rehovot','Rehovot',''),('IL','RFH','Rafiach','Rafiach',''),('IL','RHA','Rosh Ha\'ayin','Rosh Ha\'ayin',''),('IL','RHN','Rosh Hanikra','Rosh Hanikra',''),('IL','RHV','Ramat HaKovesh','Ramat HaKovesh',''),('IL','RLZ','Rishon Letsiyon','Rishon Letsiyon',''),('IL','RMG','Ramat Gan','Ramat Gan',''),('IL','RML','Ramla','Ramla',''),('IL','RPN','Rosh Pina','Rosh Pina',''),('IL','SDT','Sederot','Sederot',''),('IL','SED','Sedom','Sedom',''),('IL','SUK','Sukrier','Sukrier',''),('IL','TAB','Taba','Taba',''),('IL','TCL','Tirat Carmel','Tirat Carmel',''),('IL','TIB','Tiberias','Tiberias',''),('IL','TLV','Tel Aviv-Yafo','Tel Aviv-Yafo',''),('IL','VDA','Ovda','Ovda',''),('IL','YKN','Yokneam','Yokneam',''),('IL','YOT','Yotvata','Yotvata',''),('IL','YVL','Yavne\'el','Yavne\'el',''),('IM','','','',''),('IM','CTN','Castletown','Castletown',''),('IM','DGS','Douglas','Douglas',''),('IM','IOM','Ronaldsway Apt','Ronaldsway Apt',''),('IM','PEL','Peel','Peel',''),('IM','RAM','Ramsey','Ramsey',''),('IN','','','',''),('IN','ABG','Alibag','Alibag','MH'),('IN','ACH','Achra','Achra','MH'),('IN','ADI','Androth Is','Androth Is','LD'),('IN','AGR','Agra','Agra','UP'),('IN','AGX','Agatti Island','Agatti Island',''),('IN','AJL','Aizawl','Aizawl',''),('IN','AKD','Akola','Akola',''),('IN','AKV','Ankleshwar','Ankleshwar','GJ'),('IN','ALA','Alang SBY','Alang SBY',''),('IN','ALF','Alleppey','Alleppey','KL'),('IN','AMD','Ahmedabad','Ahmedabad','GJ'),('IN','AMG','Amingaon (Gauhati)','Amingaon (Gauhati)','AS'),('IN','AMI','Andorth Is','Andorth Is','LD'),('IN','ANG','Anijengo','Anijengo','KL'),('IN','ANL','Arnala','Arnala','MH'),('IN','APT','Anaparti','Anaparti','AP'),('IN','ARK','Arakkonam','Arakkonam','TN'),('IN','ARR','Aroor','Aroor','KL'),('IN','ATQ','Amritsar','Amritsar','PB'),('IN','ATR','Attari Road','Attari Road','PB'),('IN','ATT','Attari Rail Station','Attari Rail Station','PB'),('IN','AUR','Auraiya','Auraiya','UP'),('IN','AZK','Azhikkal','Azhikkal','KL'),('IN','BAD','Bhaddi','Bhaddi','PB'),('IN','BAN','Banswara','Banswara','RJ'),('IN','BBI','Bhubaneswar','Bhubaneswar','OR'),('IN','BBP','Bahabal Pur','Bahabal Pur','OR'),('IN','BDA','Bandra','Bandra','MH'),('IN','BDG','Badagara','Badagara','KL'),('IN','BDQ','Vadodara','Vadodara','GJ'),('IN','BDR','Baindur','Baindur','KA'),('IN','BED','Bedi','Bedi','GJ'),('IN','BEK','Bareilly','Bareilly','UP'),('IN','BEL','Betul','Betul','MP'),('IN','BEP','Bellary','Bellary',''),('IN','BET','Betul','Betul','GA'),('IN','BEY','Beypore','Beypore','KL'),('IN','BGH','Ballabgarh','Ballabgarh','HR'),('IN','BGK','Jodhpur-Bhagat Ki Kothi','Jodhpur-Bhagat Ki Kothi',''),('IN','BGM','Baghamara','Baghamara','ML'),('IN','BGU','Bairgania','Bairgania','BR'),('IN','BGW','Bhagwa','Bhagwa','GJ'),('IN','BHI','Bhilai','Bhilai','CT'),('IN','BHJ','Bhuj','Bhuj',''),('IN','BHL','Bhilwara','Bhilwara','RJ'),('IN','BHM','Bheemunipatnam','Bheemunipatnam','AP'),('IN','BHO','Bhopal','Bhopal',''),('IN','BHU','Bhavnagar','Bhavnagar','GJ'),('IN','BKB','Bikaner','Bikaner',''),('IN','BKT','Bankot','Bankot','MH'),('IN','BLK','Belekeri','Belekeri','KA'),('IN','BLM','Bilimora','Bilimora','GJ'),('IN','BLP','Belapur','Belapur','MH'),('IN','BLR','Bangalore','Bangalore','KA'),('IN','BLT','Balet','Balet','ML'),('IN','BMR','Barmer Rail Station','Barmer Rail Station','RJ'),('IN','BND','Banddar','Banddar','AP'),('IN','BNR','Bhimnagar','Bhimnagar','BR'),('IN','BNY','Berhni','Berhni','UP'),('IN','BOL','Bolanganj','Bolanganj','ML'),('IN','BOM','Mumbai (ex Bombay)','Mumbai (ex Bombay)','MH'),('IN','BPT','Bang?rapet','Bang?rapet','KA'),('IN','BRA','Barsora','Barsora','ML'),('IN','BRC','Baroda','Baroda','GJ'),('IN','BRH','Broach','Broach','GJ'),('IN','BRM','Borliai-Mandla','Borliai-Mandla','MH'),('IN','BRN','Boranada, Jodhpur','Boranada, Jodhpur','RJ'),('IN','BRU','Bharoch','Bharoch','GJ'),('IN','BRY','Borya','Borya','MH'),('IN','BSA','Banbasa','Banbasa','UP'),('IN','BSL','Bhusaval','Bhusaval','MH'),('IN','BSN','Bassain','Bassain','MH'),('IN','BSR','Bulsar','Bulsar','GJ'),('IN','BTK','Bhatkal','Bhatkal','KA'),('IN','BTM','Bhithamore (Sursnad)','Bhithamore (Sursnad)','BR'),('IN','BTR','Bitra Is','Bitra Is','LD'),('IN','BUD','Budge-Budge','Budge-Budge','WB'),('IN','BUN','Bund?la','Bund?la','PB'),('IN','BUP','Bhatinda','Bhatinda','PB'),('IN','BWD','Bhiwadi','Bhiwadi','RJ'),('IN','BWN','Bhiwandi','Bhiwandi','MH'),('IN','BYT','Beyt','Beyt','GJ'),('IN','CAM','Cambay','Cambay','GJ'),('IN','CAP','Calingapatam','Calingapatam','AP'),('IN','CAR','Carijam','Carijam',''),('IN','CBD','Car Nicobar','Car Nicobar',''),('IN','CBL','Chandbali','Chandbali','OR'),('IN','CCJ','Kozhikode (ex Calicut)','Kozhikode (ex Calicut)','KL'),('IN','CCU','Kolkata (ex Calcutta)','Kolkata (ex Calcutta)','WB'),('IN','CDL','Cuddalore','Cuddalore','TN'),('IN','CDP','Cuddapah','Cuddapah',''),('IN','CHM','Chamurci','Chamurci','SK'),('IN','CHN','Chhani/Vadodora','Chhani/Vadodora','GJ'),('IN','CHP','Champai','Champai','MZ'),('IN','CHR','Chapora','Chapora','GA'),('IN','CJB','Coimbatore','Coimbatore','TN'),('IN','CLX','Chirala','Chirala','AP'),('IN','CNN','Cannanore','Cannanore','KL'),('IN','COH','Cooch Behar','Cooch Behar',''),('IN','COK','Cochin','Cochin','KL'),('IN','COL','Colochel','Colochel',''),('IN','COO','Coondapur (Ganguly)','Coondapur (Ganguly)','KA'),('IN','COS','Cossipore','Cossipore','WB'),('IN','CPU','Chengalpattu','Chengalpattu','TN'),('IN','CRB','Changrabandha','Changrabandha','WB'),('IN','CRN','Cornwallis','Cornwallis','AN'),('IN','CTI','Chetlat Is','Chetlat Is','LD'),('IN','DAE','Daparizo','Daparizo',''),('IN','DAH','Dahej','Dahej','GJ'),('IN','DAI','Darjeeling','Darjeeling',''),('IN','DAM','Daman','Daman','DD'),('IN','DBD','Dhanbad','Dhanbad',''),('IN','DED','Dehra Dun','Dehra Dun',''),('IN','DEG','Deogad','Deogad','MH'),('IN','DEL','Delhi','Delhi','DL'),('IN','DEP','Deparizo','Deparizo',''),('IN','DHB','Dhubri Steamerghat','Dhubri Steamerghat','AS'),('IN','DHL','Dhalaighat','Dhalaighat','TR'),('IN','DHM','Dharamsala','Dharamsala',''),('IN','DHP','Dabhol Port','Dabhol Port','MH'),('IN','DHR','Dholera','Dholera','GJ'),('IN','DHU','Dahanu','Dahanu','MH'),('IN','DIB','Dibrugarh','Dibrugarh',''),('IN','DIG','Dighi (Pune)','Dighi (Pune)','MH'),('IN','DIU','Diu','Diu','DD'),('IN','DIV','Div','Div','GJ'),('IN','DLA','Dharchula','Dharchula','UP'),('IN','DLB','Daulatabad','Daulatabad','MH'),('IN','DLU','Dalu','Dalu','ML'),('IN','DMR','Demagir','Demagir','NL'),('IN','DMT','Dharamtar','Dharamtar','MH'),('IN','DMU','Dimapur','Dimapur',''),('IN','DPR','Dapper','Dapper','PB'),('IN','DRG','Darranga','Darranga','AS'),('IN','DRI','Dadri','Dadri','UP'),('IN','DRK','Dwarka (Rupen)','Dwarka (Rupen)','GJ'),('IN','DRL','Dabolim','Dabolim','GA'),('IN','DSK','Dhanu-shkodi','Dhanu-shkodi','TN'),('IN','DTW','Dantiwara','Dantiwara','MH'),('IN','DUR','Durgapur','Durgapur','WB'),('IN','DWA','Dwarka','Dwarka','GJ'),('IN','DWK','Dawki','Dawki','ML'),('IN','ENR','Ennore','Ennore','TN'),('IN','ESH','Elphinstone Harbour','Elphinstone Harbour','AN'),('IN','FAR','Farakka','Farakka',''),('IN','FBD','Faridabad','Faridabad','HR'),('IN','FLT','Falta','Falta','WB'),('IN','GAI','Gauriphanta','Gauriphanta','UP'),('IN','GAL','Galgalia','Galgalia','BR'),('IN','GAN','Gandhar','Gandhar',''),('IN','GAU','Gauhati (Panidi)','Gauhati (Panidi)','AS'),('IN','GAW','Guwahati','Guwahati','AS'),('IN','GAY','Gaya','Gaya',''),('IN','GED','Gede Rail Station','Gede Rail Station','WB'),('IN','GGA','Gogha','Gogha','GJ'),('IN','GGN','Gurgaon','Gurgaon',''),('IN','GHA','Ghogha','Ghogha','GJ'),('IN','GHP','Ghasuapara','Ghasuapara','ML'),('IN','GHR','Garhi Harsaru','Garhi Harsaru','HR'),('IN','GIN','Gandhidham','Gandhidham','GJ'),('IN','GJI','Gunji','Gunji','UP'),('IN','GJX','Ghojadanga','Ghojadanga','WB'),('IN','GKJ','Golakganj Rail Station','Golakganj Rail Station','AS'),('IN','GOI','Goa','Goa',''),('IN','GOP','Gorakhpur','Gorakhpur','UP'),('IN','GPR','Gopalpur','Gopalpur','OR'),('IN','GTG','Gitaldah Road','Gitaldah Road','AS'),('IN','GTR','Guntur','Guntur','AP'),('IN','GTZ','Getandah','Getandah','WB'),('IN','GUD','Gudur','Gudur',''),('IN','GUX','Guna','Guna',''),('IN','GWL','Gwalior','Gwalior','MP'),('IN','GZD','Gh?zi?b?d','Gh?zi?b?d','UP'),('IN','HAL','Haldia','Haldia','WB'),('IN','HAS','Hassan','Hassan','KA'),('IN','HBX','Hubli','Hubli',''),('IN','HGL','Hingalganj','Hingalganj','WB'),('IN','HGT','Hangarkatta','Hangarkatta','KA'),('IN','HJR','Khajuraho','Khajuraho',''),('IN','HLD','Haldibari Rail Stat ion','Haldibari Rail Stat ion','AS'),('IN','HLI','Hilli','Hilli','WB'),('IN','HLO','Halol','Halol','GJ'),('IN','HON','Honavar','Honavar','KA'),('IN','HRN','Harnai','Harnai','MH'),('IN','HSS','Hissar','Hissar',''),('IN','HTS','Hatisar','Hatisar','AS'),('IN','HWR','Honawar','Honawar','KA'),('IN','HYD','Hyderabad','Hyderabad','AP'),('IN','ICD','New Delhi','New Delhi','DL'),('IN','IDR','Indore','Indore','MP'),('IN','IMF','Imphal','Imphal','MN'),('IN','ISK','Nasik','Nasik','MH'),('IN','IXA','Agartala','Agartala',''),('IN','IXB','Bagdogra','Bagdogra','WB'),('IN','IXC','Chandigarh','Chandigarh',''),('IN','IXD','Allahabad','Allahabad',''),('IN','IXE','Mangalore','Mangalore','KA'),('IN','IXG','Belgaum','Belgaum',''),('IN','IXH','Kailashahar','Kailashahar',''),('IN','IXI','Lilabari','Lilabari',''),('IN','IXJ','Jammu','Jammu',''),('IN','IXK','Keshod','Keshod',''),('IN','IXL','Leh','Leh',''),('IN','IXM','Madurai','Madurai','TN'),('IN','IXN','Khowai','Khowai',''),('IN','IXP','Pathankot','Pathankot',''),('IN','IXQ','Kamalpur','Kamalpur',''),('IN','IXR','Ranchi','Ranchi','BR'),('IN','IXS','Silchar','Silchar',''),('IN','IXT','Pasighat','Pasighat',''),('IN','IXU','Aurangabad','Aurangabad',''),('IN','IXW','Jamshedpur','Jamshedpur',''),('IN','IXY','Kandla','Kandla','GJ'),('IN','IXZ','Port Blair','Port Blair','AN'),('IN','JAI','Jaipur','Jaipur','RJ'),('IN','JAK','Jakhau','Jakhau','GJ'),('IN','JAL','Jalgaon','Jalgaon','MH'),('IN','JAY','Jayanagar','Jayanagar','BR'),('IN','JBD','Jafarabad','Jafarabad','GJ'),('IN','JBN','Jogbani','Jogbani','BR'),('IN','JDA','Jodia','Jodia','GJ'),('IN','JDH','Jodhpur','Jodhpur','RJ'),('IN','JGA','Jamnagar','Jamnagar',''),('IN','JGB','Jagdalpur','Jagdalpur',''),('IN','JGD','Jaigad','Jaigad','MH'),('IN','JHO','Jhulaghat (Pithoragarh)','Jhulaghat (Pithoragarh)','UP'),('IN','JIG','Jaigaon','Jaigaon','WB'),('IN','JLR','Jabalpur','Jabalpur',''),('IN','JNP','Port Jawaharlal Nehru','Port Jawaharlal Nehru',''),('IN','JPG','Jalpaiguri','Jalpaiguri','WB'),('IN','JRH','Jorhat','Jorhat',''),('IN','JSA','Jaisalmer','Jaisalmer',''),('IN','JSZ','Jaipur-Sitapura','Jaipur-Sitapura','RJ'),('IN','JTP','Jaitapur','Jaitapur','MH'),('IN','JUC','Jalandhar','Jalandhar','PB'),('IN','JUX','Basni','Basni','RJ'),('IN','JWA','Jarwa','Jarwa','UP'),('IN','KAK','Kakinada','Kakinada','AP'),('IN','KAL','Kallai','Kallai','KL'),('IN','KAP','Kapadra (Surat)','Kapadra (Surat)','GJ'),('IN','KAR','Karur','Karur','TN'),('IN','KBT','Khambhat','Khambhat','GJ'),('IN','KDD','Karedu','Karedu','AP'),('IN','KDI','Kadmat Is','Kadmat Is','LD'),('IN','KDP','Kondiapetnam','Kondiapetnam','KL'),('IN','KEL','Kel Sahar Subdivision','Kel Sahar Subdivision','TR'),('IN','KHP','Khopta','Khopta',''),('IN','KIW','Kelwa','Kelwa','MH'),('IN','KKR','Kilakari','Kilakari','TN'),('IN','KKU','Jaipur-Kanakpura','Jaipur-Kanakpura',''),('IN','KLH','Kolhapur','Kolhapur','MH'),('IN','KLY','Kalyan','Kalyan','MH'),('IN','KMB','Kumbharu','Kumbharu','MH'),('IN','KND','Kankudy','Kankudy','KL'),('IN','KNL','Kunauli','Kunauli','BR'),('IN','KNU','Kanpur','Kanpur','UP'),('IN','KOC','Kochi','Kochi',''),('IN','KOD','Kodinar','Kodinar','GJ'),('IN','KOI','Koilthottum','Koilthottum','KL'),('IN','KOK','Koka','Koka','GJ'),('IN','KON','Konarak','Konarak','KA'),('IN','KRI','Krishnapatnam','Krishnapatnam','AP'),('IN','KRK','Karaikal','Karaikal','PY'),('IN','KRN','Karanja','Karanja','MH'),('IN','KRP','Kiranpani','Kiranpani','MH'),('IN','KRW','Karwar','Karwar','KA'),('IN','KSG','Kasargod','Kasargod','KL'),('IN','KSH','Kelshi','Kelshi','MH'),('IN','KSP','Kulasekarapanam','Kulasekarapanam','TN'),('IN','KTD','Kotda','Kotda','GJ'),('IN','KTG','Katarniyaghat','Katarniyaghat','UP'),('IN','KTI','Kiltan Is','Kiltan Is','LD'),('IN','KTR','Kathinhar','Kathinhar','BR'),('IN','KTU','Kota','Kota','RJ'),('IN','KTW','Koheshwar','Koheshwar','GJ'),('IN','KUN','Kundla','Kundla','GJ'),('IN','KUU','Kulu','Kulu',''),('IN','KVI','Kavi','Kavi','GJ'),('IN','KVL','Kovalam','Kovalam','KL'),('IN','KVT','Kavaram Is','Kavaram Is','LD'),('IN','KWA','Khunwa','Khunwa','UP'),('IN','KWG','Khowaighat','Khowaighat','TR'),('IN','LAL','Lalru','Lalru','PB'),('IN','LDA','Malda','Malda',''),('IN','LGL','Lalgola Town','Lalgola Town','WB'),('IN','LKO','Lucknow','Lucknow','UP'),('IN','LPR','Leapuram','Leapuram','KL'),('IN','LTB','Latu Bazar','Latu Bazar','AS'),('IN','LUH','Ludhiana','Ludhiana','PB'),('IN','MAA','Chennai (ex Madras)','Chennai (ex Madras)','TN'),('IN','MAH','Mahe','Mahe','PY'),('IN','MAL','Malpe','Malpe','KA'),('IN','MAP','Masulipatnam','Masulipatnam','AP'),('IN','MBD','Pakwara (Moradabad)','Pakwara (Moradabad)','UP'),('IN','MCI','Minicoi I','Minicoi I','KL'),('IN','MDA','Magdalla','Magdalla','GJ'),('IN','MDK','Mul Dwarka','Mul Dwarka','GJ'),('IN','MDP','Mandapam','Mandapam','TN'),('IN','MDV','Mandvi','Mandvi','GJ'),('IN','MDW','Meadows','Meadows','AN'),('IN','MER','Meerut','Meerut','UP'),('IN','MGH','Mahendraganj','Mahendraganj','ML'),('IN','MGR','Mangrol','Mangrol','GJ'),('IN','MHA','Mahuva','Mahuva','GJ'),('IN','MHD','Kotawalighat (Mohedipur)','Kotawalighat (Mohedipur)','WB'),('IN','MHG','Mahurighat','Mahurighat','TR'),('IN','MHI','Mohali','Mohali','MH'),('IN','MHN','Mahisashan Rail Station','Mahisashan Rail Station','AS'),('IN','MKC','Manikarchar','Manikarchar','AS'),('IN','MLI','Maroli','Maroli','GJ'),('IN','MLP','Mallipuram','Mallipuram','KL'),('IN','MLW','Malwan','Malwan','MH'),('IN','MNB','Munabao Rail Station','Munabao Rail Station','RJ'),('IN','MNR','Manori','Manori','MH'),('IN','MNU','Manu','Manu','AS'),('IN','MNW','Mandwa','Mandwa','MH'),('IN','MOH','Mohanbari','Mohanbari',''),('IN','MOR','Moradabad','Moradabad','UP'),('IN','MPR','Malanpur','Malanpur','MP'),('IN','MRA','Mora','Mora','MH'),('IN','MRE','Moreh','Moreh','ML'),('IN','MRG','Madgaon','Madgaon','GA'),('IN','MRI','Mithivirdi','Mithivirdi','GJ'),('IN','MRJ','Miraj','Miraj','MH'),('IN','MRM','Marmagao (Marmugao)','Marmagao (Marmugao)','GA'),('IN','MTW','Metwad','Metwad','GJ'),('IN','MUG','Munger','Munger','BR'),('IN','MUL','Mulgund','Mulgund','KA'),('IN','MUN','Mundra','Mundra','GJ'),('IN','MUR','Murad','Murad','MH'),('IN','MYB','Mayabandar','Mayabandar','AN'),('IN','MYQ','Mysore','Mysore',''),('IN','MZA','Muzaffarnagar','Muzaffarnagar',''),('IN','MZU','Muzaffarpur','Muzaffarpur',''),('IN','NAG','Nagpur','Nagpur','MH'),('IN','NAN','Nancowrie','Nancowrie','AN'),('IN','NAV','Navlakhi','Navlakhi','GJ'),('IN','NDA','Noida','Noida',''),('IN','NDC','Nanded','Nanded',''),('IN','NDG','Nandgaon','Nandgaon','MH'),('IN','NEE','Nindakara','Nindakara','KL'),('IN','NEL','Nellore','Nellore','AP'),('IN','NGR','Nepalgunj Road','Nepalgunj Road','UP'),('IN','NGS','Village Namaya Shipkila','Village Namaya Shipkila','MN'),('IN','NHV','Nhave','Nhave','MH'),('IN','NKN','Namkhana','Namkhana','WB'),('IN','NMB','Navi Mumbai','Navi Mumbai','MH'),('IN','NML','New Mangalore','New Mangalore','KA'),('IN','NMT','Neamari Stemerghat','Neamari Stemerghat','AS'),('IN','NPG','Nampong','Nampong','AP'),('IN','NPR','Nagapur','Nagapur','MH'),('IN','NPT','Nagappattinam','Nagappattinam','TN'),('IN','NSA','Jawaharlal Nehru (Nhava Sheva)','Jawaharlal Nehru (Nhava Sheva)','MH'),('IN','NTU','New Tuticorin','New Tuticorin','TN'),('IN','NVB','Navabunder','Navabunder','GJ'),('IN','NVP','Navaspur','Navaspur','AP'),('IN','NVT','Nivti','Nivti','MH'),('IN','NVY','Neyveli','Neyveli',''),('IN','NWP','Newapur','Newapur','MH'),('IN','OKH','Okha','Okha','GJ'),('IN','OMN','Osmanabad','Osmanabad',''),('IN','ONJ','Onjal','Onjal','GJ'),('IN','PAB','Bilaspur','Bilaspur',''),('IN','PAN','Panaji Port','Panaji Port','GA'),('IN','PAP','Panipat','Panipat','HR'),('IN','PAT','Patna','Patna','BR'),('IN','PAV','Pipavav (Victor) Port','Pipavav (Victor) Port','GJ'),('IN','PBD','Porbandar','Porbandar','GJ'),('IN','PDD','Padubidri','Padubidri','KA'),('IN','PDI','Padi','Padi',''),('IN','PGH','Pantnagar','Pantnagar',''),('IN','PHB','Phulbari','Phulbari','AS'),('IN','PID','Port Indai','Port Indai',''),('IN','PIN','Pindhara','Pindhara','GJ'),('IN','PIR','Pithampur','Pithampur','MP'),('IN','PMB','Pamban','Pamban','TN'),('IN','PMP','Pimpri','Pimpri','MH'),('IN','PNJ','Panjim','Panjim','GA'),('IN','PNM','Panambur, Va Mangalore','Panambur, Va Mangalore',''),('IN','PNN','Ponnani','Ponnani','KL'),('IN','PNP','Babarpur','Babarpur','HR'),('IN','PNQ','Pune','Pune','MH'),('IN','PNT','Panitankit (Nazalbari)','Panitankit (Nazalbari)','WB'),('IN','PNY','Pondicherry','Pondicherry','PY'),('IN','PPG','Patparganj','Patparganj','DL'),('IN','PPJ','Pellet Plant Jetty/Shiroda','Pellet Plant Jetty/Shiroda','GA'),('IN','PRG','Purangad','Purangad','MH'),('IN','PRN','Portonovo','Portonovo','TN'),('IN','PRT','Paradip Garh','Paradip Garh','OR'),('IN','PSH','Palshet','Palshet','MH'),('IN','PST','Positra','Positra','GJ'),('IN','PTP','Petrapole Road','Petrapole Road','WB'),('IN','PUL','Pulicat','Pulicat','TN'),('IN','PUR','Puri','Puri','OR'),('IN','PUT','Puttaparthi','Puttaparthi',''),('IN','PVL','Panvel','Panvel','MH'),('IN','PYB','Jeypore','Jeypore',''),('IN','QUI','Quilon','Quilon','KL'),('IN','RAJ','Rajkot','Rajkot','GJ'),('IN','RAM','Rameshwaram','Rameshwaram','TN'),('IN','RDP','Radhikapur Rail Station','Radhikapur Rail Station','WB'),('IN','REA','Rewari','Rewari','HR'),('IN','RED','Redi','Redi','MH'),('IN','REW','Rewa','Rewa',''),('IN','RGB','Old Raghna Bazar','Old Raghna Bazar','TR'),('IN','RGH','Balurghat','Balurghat',''),('IN','RGT','Ranghat Bay','Ranghat Bay','AN'),('IN','RGU','Ryngku','Ryngku','ML'),('IN','RJA','Rajahmundry','Rajahmundry',''),('IN','RJI','Rajouri','Rajouri',''),('IN','RJP','Rajpara/Navabunder','Rajpara/Navabunder','GJ'),('IN','RJR','Rajpuri','Rajpuri','MH'),('IN','RJU','Rajula','Rajula','GJ'),('IN','RKG','Rajakkamangalam','Rajakkamangalam','KL'),('IN','RMD','Ramagundam','Ramagundam',''),('IN','RNG','Ranaghat Rail Station','Ranaghat Rail Station','WB'),('IN','RNR','Ranpar','Ranpar','MH'),('IN','ROH','Rohtak','Rohtak','HR'),('IN','RPL','Raddipalam','Raddipalam','AP'),('IN','RPR','Raipur','Raipur','MP'),('IN','RRI','Raili','Raili','BR'),('IN','RRK','Rourkela','Rourkela',''),('IN','RTC','Ratnagiri','Ratnagiri','MH'),('IN','RUP','Rupsi','Rupsi',''),('IN','RVD','Revdanda','Revdanda','MH'),('IN','RXL','Raxaul','Raxaul','BR'),('IN','SAB','Sabroom','Sabroom','TR'),('IN','SAC','Sachin (Surat)','Sachin (Surat)','GJ'),('IN','SAD','Sanathnagar','Sanathnagar','HR'),('IN','SAL','Salaya','Salaya','GJ'),('IN','SBH','Sinbhour','Sinbhour','GJ'),('IN','SBZ','Shella Bazar','Shella Bazar','ML'),('IN','SHI','Shirola','Shirola','KA'),('IN','SHL','Shillong','Shillong',''),('IN','SHP','Simbhour Port','Simbhour Port',''),('IN','SHR','Sholinghur','Sholinghur','TN'),('IN','SIK','Sika','Sika','GJ'),('IN','SIM','Sima/Navabunder','Sima/Navabunder','GJ'),('IN','SIR','Singanallur','Singanallur','TN'),('IN','SJP','Surajpur','Surajpur','UP'),('IN','SKK','Sikkim','Sikkim','AN'),('IN','SKP','Sukhia Pokhari','Sukhia Pokhari','WB'),('IN','SLT','Salt Lake','Salt Lake','WB'),('IN','SLV','Simla','Simla',''),('IN','SMP','Srimantapur','Srimantapur','TR'),('IN','SMR','Simor','Simor','GJ'),('IN','SNB','Sonabarsa','Sonabarsa','DL'),('IN','SNG','Singabad Rail Station','Singabad Rail Station','WB'),('IN','SNL','Sonauli','Sonauli','UP'),('IN','SON','Sonepat','Sonepat','HR'),('IN','SRE','Saharanpur','Saharanpur','UP'),('IN','SRV','Surasani-Yanam','Surasani-Yanam','AP'),('IN','SSE','Sholapur','Sholapur',''),('IN','STI','Sitai','Sitai','WB'),('IN','STP','Satpati','Satpati','MH'),('IN','STR','Sutarkandi','Sutarkandi','AS'),('IN','STV','Surat','Surat','GJ'),('IN','SWD','Shriwardhan','Shriwardhan','MH'),('IN','SXR','Srinagar','Srinagar','JK'),('IN','SXV','Salem','Salem','TN'),('IN','TAD','Tadri','Tadri','KA'),('IN','TDE','Tudiyalur','Tudiyalur','TN'),('IN','TEI','Tezu','Tezu',''),('IN','TEL','Tellicherry','Tellicherry','KL'),('IN','TEZ','Tezpur','Tezpur',''),('IN','THA','Jodhpur-Thar','Jodhpur-Thar',''),('IN','THL','Thal','Thal','MH'),('IN','TIR','Tirupati','Tirupati',''),('IN','TIV','Tiviri','Tiviri',''),('IN','TJA','Talaja','Talaja','GJ'),('IN','TJV','Thanjavur','Thanjavur',''),('IN','TKD','Tughlakabad','Tughlakabad','DL'),('IN','TKN','Tikonia','Tikonia','UP'),('IN','TMP','Trombay','Trombay','MH'),('IN','TNA','Thana','Thana','MH'),('IN','TND','Tondi','Tondi','TN'),('IN','TNG','Tungi','Tungi','WB'),('IN','TNK','Tankari','Tankari','GJ'),('IN','TPH','Thopputhurai','Thopputhurai','TN'),('IN','TPN','Talpona','Talpona','GA'),('IN','TRA','Tranquebar','Tranquebar','TN'),('IN','TRP','Tarapur','Tarapur','MH'),('IN','TRV','Thiruvananthapuram (ex Trivandrum','Thiruvananthapuram (ex Trivandrum','KL'),('IN','TRZ','Tiruchirapalli','Tiruchirapalli','TN'),('IN','TTS','T.T.Shed','T.T.Shed','WB'),('IN','TUN','Tuna','Tuna','GJ'),('IN','TUP','Tiruppur','Tiruppur','TN'),('IN','TUT','Tuticorin','Tuticorin','TN'),('IN','TYR','Tirukkadayyur','Tirukkadayyur','TN'),('IN','UDR','Udaipur','Udaipur','RJ'),('IN','ULP','Ultapani','Ultapani','AS'),('IN','ULW','Ulwa','Ulwa','MH'),('IN','UMB','Umbergoan','Umbergoan','GJ'),('IN','UMG','Umbergaon','Umbergaon','MH'),('IN','UMR','Umarsadi','Umarsadi','GJ'),('IN','UND','Secunderabad','Secunderabad','AP'),('IN','UTN','Uttan','Uttan','MH'),('IN','VAD','Vadinar','Vadinar','GJ'),('IN','VEN','Vengurla','Vengurla','MH'),('IN','VEP','Veppalodai','Veppalodai','TN'),('IN','VGA','Vijayawada','Vijayawada',''),('IN','VKM','Valinokkam','Valinokkam','TN'),('IN','VNG','Vemgira','Vemgira','MH'),('IN','VNS','Varanasi','Varanasi','UP'),('IN','VPI','Vapi','Vapi','GJ'),('IN','VRD','Varavda','Varavda','MH'),('IN','VRU','Vadarevu','Vadarevu','AP'),('IN','VSI','Vansi-Borsi','Vansi-Borsi','GJ'),('IN','VSV','Varsova','Varsova','MH'),('IN','VTZ','Visakhapatnam','Visakhapatnam','AP'),('IN','VVA','Veraval','Veraval','GJ'),('IN','VYD','Vijaydurg','Vijaydurg','MH'),('IN','VZJ','Vazhinjam','Vazhinjam','KL'),('IN','WAL','Waluj (Aurangabad)','Waluj (Aurangabad)','MH'),('IN','WGC','Warrangal','Warrangal',''),('IN','ZUM','Tumkur','Tumkur','KA'),('IO','','','',''),('IO','DGA','Diego Garcia','Diego Garcia',''),('IQ','','','',''),('IQ','ABL','Arbil','Arbil',''),('IQ','ALF','Abu Al Fulus','Abu Al Fulus',''),('IQ','ALK','Abu Al Khasib','Abu Al Khasib',''),('IQ','AMA','Amara (Al-Amarah)','Amara (Al-Amarah)',''),('IQ','ANJ','An Najaf','An Najaf',''),('IQ','ARK','Arak','Arak',''),('IQ','ASD','Al Asad','Al Asad',''),('IQ','BAI','Baigi','Baigi',''),('IQ','BAL','Balad','Balad',''),('IQ','BAQ','Ba\'qubah','Ba\'qubah',''),('IQ','BGW','Baghdad','Baghdad',''),('IQ','BSR','Basra','Basra',''),('IQ','DIW','Diwaniyah','Diwaniyah',''),('IQ','DOK','Dohuk','Dohuk',''),('IQ','FAL','Falluja','Falluja',''),('IQ','FAO','Fao','Fao',''),('IQ','HIL','Al Hillah','Al Hillah',''),('IQ','HIT','Hit','Hit',''),('IQ','HND','Hindiya','Hindiya',''),('IQ','IKD','Iskandariyha','Iskandariyha',''),('IQ','IRB','Irbil','Irbil',''),('IQ','KAB','Khan al Baghdadi','Khan al Baghdadi',''),('IQ','KAR','Karbala','Karbala',''),('IQ','KAZ','Khor al Zubair','Khor al Zubair',''),('IQ','KFA','Kufa','Kufa',''),('IQ','KHA','Khor Al Amaya','Khor Al Amaya',''),('IQ','KIK','Kirkuk','Kirkuk',''),('IQ','KUT','Al Kut','Al Kut',''),('IQ','MAB','Mina\' al Bakr','Mina\' al Bakr',''),('IQ','MAN','Mandali','Mandali',''),('IQ','NAS','Najat','Najat',''),('IQ','NJF','Najaf','Najaf',''),('IQ','NMA','Nahr an Nu\'maniyah','Nahr an Nu\'maniyah',''),('IQ','NRH','An Nasiriyah','An Nasiriyah',''),('IQ','NSR','Nasiriyah','Nasiriyah',''),('IQ','OSM','Mosul (Ak Mawsil)','Mosul (Ak Mawsil)',''),('IQ','RMD','Ramadi','Ramadi',''),('IQ','RTM','Ratawi','Ratawi',''),('IQ','SAM','Samarra\'','Samarra\'',''),('IQ','SBA','Ash Shu\'aybah','Ash Shu\'aybah',''),('IQ','SMW','Samawa (As-Samawah)','Samawa (As-Samawah)',''),('IQ','SYH','Sulaymaniyah','Sulaymaniyah',''),('IQ','TJI','Taji','Taji',''),('IQ','TKT','Tikrit','Tikrit',''),('IQ','TQD','Al Taqaddum','Al Taqaddum',''),('IQ','UQR','Umm Qasr','Umm Qasr',''),('IQ','UZA','Al \'Uzayr','Al \'Uzayr',''),('IQ','ZAO','Zakho','Zakho',''),('IQ','ZUB','Al Zuwayr','Al Zuwayr',''),('IR','','','',''),('IR','ABD','Abadan','Abadan',''),('IR','ACZ','Zabol','Zabol',''),('IR','ADU','Ardabil','Ardabil',''),('IR','AMR','Amara','Amara',''),('IR','ARA','Arak','Arak',''),('IR','ASA','Asaluyeh','Asaluyeh',''),('IR','ASR','Astara','Astara',''),('IR','AWZ','Ahwaz','Ahwaz',''),('IR','AZD','Yazd','Yazd',''),('IR','BAH','Bandar Assaluyeh','Bandar Assaluyeh',''),('IR','BAJ','Bajgiran','Bajgiran',''),('IR','BAZ','Bandar-e Anzali','Bandar-e Anzali',''),('IR','BBL','Babolsar','Babolsar',''),('IR','BDH','Bandar-e Lengeh','Bandar-e Lengeh',''),('IR','BJB','Bojnurd','Bojnurd',''),('IR','BKM','Bandar Khomeini','Bandar Khomeini',''),('IR','BMR','Bandar Mashur','Bandar Mashur',''),('IR','BND','Bandar Abbas','Bandar Abbas',''),('IR','BRG','Bandar-e Gaz','Bandar-e Gaz',''),('IR','BSR','Bandar Shahid Rajaee','Bandar Shahid Rajaee',''),('IR','BUZ','Bushehr','Bushehr',''),('IR','BXR','Bam','Bam',''),('IR','CKT','Sarakhs','Sarakhs',''),('IR','DAM','Damavand','Damavand',''),('IR','DGN','Basargan','Basargan',''),('IR','DJU','Jolfa','Jolfa',''),('IR','DOG','Do Gharun','Do Gharun',''),('IR','ESF','Esfahan','Esfahan',''),('IR','GHA','Ghazvin (Qazwin)','Ghazvin (Qazwin)',''),('IR','GSM','Gheshm','Gheshm',''),('IR','HDM','Hamadan','Hamadan',''),('IR','HEJ','Henjam','Henjam',''),('IR','HOR','Hormuz','Hormuz',''),('IR','IAQ','Bahregan','Bahregan',''),('IR','IFN','Isfahan','Isfahan',''),('IR','IMH','Imam Hasan','Imam Hasan',''),('IR','IQH','Islam Qal\'eh','Islam Qal\'eh',''),('IR','JAK','Jask','Jask',''),('IR','KAS','Kashan','Kashan',''),('IR','KER','Kerman','Kerman',''),('IR','KHA','Khaneh','Khaneh',''),('IR','KHD','Khorramabad','Khorramabad',''),('IR','KHK','Khark Island','Khark Island',''),('IR','KHO','Khorramshahr','Khorramshahr',''),('IR','KHS','Khosravi','Khosravi',''),('IR','KHY','Khvoy','Khvoy',''),('IR','KIH','Kish Island','Kish Island',''),('IR','KMS','Kermanshah','Kermanshah',''),('IR','KNR','Kangan','Kangan',''),('IR','KSH','Kermanshah (Bakhtaran)','Kermanshah (Bakhtaran)',''),('IR','LIN','Lingah','Lingah',''),('IR','LRR','Lar','Lar',''),('IR','LVP','Lavan','Lavan',''),('IR','MHD','Mashad','Mashad',''),('IR','MRX','Bandar-e Mah Shahr','Bandar-e Mah Shahr',''),('IR','NKW','Nakhjavan Tappeh','Nakhjavan Tappeh',''),('IR','NSH','Now Shahr','Now Shahr',''),('IR','OMH','Urmieh','Urmieh',''),('IR','ORU','Orumiyeh','Orumiyeh',''),('IR','OSM','Mosul','Mosul',''),('IR','PYK','Payam Apt','Payam Apt',''),('IR','QAZ','Qazvin','Qazvin',''),('IR','QKC','Karaj','Karaj',''),('IR','QSH','Qeshm island','Qeshm island',''),('IR','QSM','Qeshm','Qeshm',''),('IR','QUM','Qum','Qum',''),('IR','RAS','Rasht','Rasht',''),('IR','RBA','Ras Bahrgan','Ras Bahrgan',''),('IR','RJN','Rafsanjan','Rafsanjan',''),('IR','RTM','Ratawi','Ratawi',''),('IR','RZR','Ramsar','Ramsar',''),('IR','SAN','Sahlan','Sahlan',''),('IR','SDG','Sanandaj','Sanandaj',''),('IR','SEK','Shahr-e Kord','Shahr-e Kord',''),('IR','SEM','Semnan','Semnan',''),('IR','SIX','Sari','Sari',''),('IR','SMW','Samawa','Samawa',''),('IR','SRA','Sarooj Anchorage','Sarooj Anchorage',''),('IR','SRJ','Sirjan','Sirjan',''),('IR','SRY','Sary','Sary',''),('IR','SVH','Saveh','Saveh',''),('IR','SXI','Sirri Island','Sirri Island',''),('IR','SYZ','Shiraz','Shiraz',''),('IR','TAJ','Tajabad','Tajabad',''),('IR','TBZ','Tabriz','Tabriz',''),('IR','TCX','Tabas','Tabas',''),('IR','THR','Tehran','Tehran',''),('IR','TMB','Tombak','Tombak',''),('IR','UZA','Al Uzsayr','Al Uzsayr',''),('IR','WPS','Persepolis','Persepolis',''),('IR','XBJ','Birjand','Birjand',''),('IR','YAS','Yasuj','Yasuj',''),('IR','ZAH','Zahedan','Zahedan',''),('IR','ZAN','Zanjan','Zanjan',''),('IR','ZBR','Chah Bahar','Chah Bahar',''),('IS','','','',''),('IS','AEY','Akureyri Apt','Akureyri Apt',''),('IS','AKR','Akranes','Akranes',''),('IS','AKU','Akureyri','Akureyri',''),('IS','ASS','Arskogssandur','Arskogssandur',''),('IS','BAK','Bakkafjordur','Bakkafjordur',''),('IS','BGJ','Borgarfjordur eystri','Borgarfjordur eystri',''),('IS','BIL','Bildudalur - hofn','Bildudalur - hofn',''),('IS','BIU','Bildudalur Apt','Bildudalur Apt',''),('IS','BLO','Blonduos','Blonduos',''),('IS','BOI','Bordeyri','Bordeyri',''),('IS','BOL','Bolungarvik','Bolungarvik',''),('IS','BOR','Borgarnes','Borgarnes',''),('IS','BOV','Bolungarvirk','Bolungarvirk',''),('IS','BRE','Breiddalsvik','Breiddalsvik',''),('IS','BUD','Budardalur','Budardalur',''),('IS','DAL','Dalvik','Dalvik',''),('IS','DJU','Djupivogur','Djupivogur',''),('IS','DPV','Djupavik','Djupavik',''),('IS','DRA','Drangsnes','Drangsnes',''),('IS','EFJ','Eskifjordur Apt','Eskifjordur Apt',''),('IS','EGS','Egilsstadir','Egilsstadir',''),('IS','ESK','Eskifjordur - hofn','Eskifjordur - hofn',''),('IS','FAG','Fagurholsmyri','Fagurholsmyri',''),('IS','FAS','Faskrudsfjordur','Faskrudsfjordur',''),('IS','FLA','Flateyri','Flateyri',''),('IS','FLI','Flateyri Apt','Flateyri Apt',''),('IS','GJR','Gjogur','Gjogur',''),('IS','GRB','Gardabaer','Gardabaer',''),('IS','GRD','Gardur','Gardur',''),('IS','GRE','Grenivik','Grenivik',''),('IS','GRF','Grundarfjordur','Grundarfjordur',''),('IS','GRI','Grindavik','Grindavik',''),('IS','GRT','Grundartangi','Grundartangi',''),('IS','GRY','Grimsey','Grimsey',''),('IS','GUF','Gufunes/Reykjavik','Gufunes/Reykjavik',''),('IS','HAF','Hafnarfjordur','Hafnarfjordur',''),('IS','HFN','Hofn, Hornafjordur','Hofn, Hornafjordur',''),('IS','HJA','Hjalteyri','Hjalteyri',''),('IS','HNR','Hafnir','Hafnir',''),('IS','HOF','Hofsos','Hofsos',''),('IS','HRI','Hrisey','Hrisey',''),('IS','HUS','Husavik - hofn','Husavik - hofn',''),('IS','HVK','Holmavik','Holmavik',''),('IS','HVM','Hvammstangi','Hvammstangi',''),('IS','HVO','Hvolsvollur','Hvolsvollur',''),('IS','HVR','Hvalfjordur','Hvalfjordur',''),('IS','ISA','Isafjordur - hofn','Isafjordur - hofn',''),('IS','KEF','Keflavik','Keflavik',''),('IS','KEV','Keflavikurkaupstadur','Keflavikurkaupstadur',''),('IS','KJF','Skerjafjordur','Skerjafjordur',''),('IS','KOP','Kopasker - hofn','Kopasker - hofn',''),('IS','KOV','Kopavogur','Kopavogur',''),('IS','KRO','Krokfjardarnes','Krokfjardarnes',''),('IS','MJO','Mjofjordur','Mjofjordur',''),('IS','MOS','Mosfellsbaer','Mosfellsbaer',''),('IS','MVA','Myvatn','Myvatn',''),('IS','NES','Neskaupstadur','Neskaupstadur',''),('IS','NJA','Njardvik','Njardvik',''),('IS','NOU','Nordurfjordur','Nordurfjordur',''),('IS','OLF','Olafsfjordur','Olafsfjordur',''),('IS','OLV','Olafsvik','Olafsvik',''),('IS','OSP','Ospakseyri','Ospakseyri',''),('IS','PAT','Patreksfjordur - hofn','Patreksfjordur - hofn',''),('IS','RAU','Raufarhofn','Raufarhofn',''),('IS','REY','Reykjavik','Reykjavik',''),('IS','RFJ','Reydarfjordur','Reydarfjordur',''),('IS','RHA','Reykholar','Reykholar',''),('IS','RIF','Rif-Hellisandur','Rif-Hellisandur',''),('IS','SAN','Sandgerdi','Sandgerdi',''),('IS','SAU','Saudarkrokur - hofn','Saudarkrokur - hofn',''),('IS','SEL','Selfoss','Selfoss',''),('IS','SEY','Seydisfjordur','Seydisfjordur',''),('IS','SFS','Selfoss - Apt','Selfoss - Apt',''),('IS','SIG','Siglufjordur - hofn','Siglufjordur - hofn',''),('IS','SKA','Skagastrond','Skagastrond',''),('IS','STD','Stodhvarfjordur','Stodhvarfjordur',''),('IS','STR','Straumsvik','Straumsvik',''),('IS','STY','Stykkisholmur - hofn','Stykkisholmur - hofn',''),('IS','SUD','Sudureyri/Sugandafjord','Sudureyri/Sugandafjord',''),('IS','SUV','Sudavik','Sudavik',''),('IS','SVA','Svalbardseyri','Svalbardseyri',''),('IS','TAL','Talknafjordur/Sveinseyri','Talknafjordur/Sveinseyri',''),('IS','TEY','Thingeyri','Thingeyri',''),('IS','THH','Thorlakshofn','Thorlakshofn',''),('IS','THN','Tjorneshofn','Tjorneshofn',''),('IS','THO','Thorshofn','Thorshofn',''),('IS','VES','Vestmannaeyjar - hofn','Vestmannaeyjar - hofn',''),('IS','VOG','Vogar','Vogar',''),('IS','VPN','Vopnafjordur','Vopnafjordur',''),('IT','','','',''),('IT','ABD','Alzano Lombardo','Alzano Lombardo',''),('IT','ABE','Albairate','Albairate',''),('IT','ABG','Albignasego','Albignasego',''),('IT','ABI','Albiolo','Albiolo',''),('IT','ABL','Albano Laziale','Albano Laziale',''),('IT','ABN','Albino','Albino',''),('IT','ABO','Albareto','Albareto',''),('IT','ABR','Alzate Brianza','Alzate Brianza',''),('IT','ABT','Albettone','Albettone',''),('IT','ACA','Acate','Acate',''),('IT','ACC','Ariccia','Ariccia',''),('IT','ACD','Arcidosso','Arcidosso',''),('IT','ACE','Arcole','Arcole',''),('IT','ACI','Acqui Terme','Acqui Terme',''),('IT','ACL','Aci Castello','Aci Castello',''),('IT','ACO','Arco','Arco',''),('IT','ACQ','Acquaviva Picena','Acquaviva Picena',''),('IT','ACR','Acireale','Acireale',''),('IT','ACS','Acquasparta','Acquasparta',''),('IT','ACT','Acitrezza','Acitrezza',''),('IT','ACU','Acquanegra Cremonese','Acquanegra Cremonese',''),('IT','ACZ','Aicurzio','Aicurzio',''),('IT','ADA','Andora','Andora',''),('IT','ADD','Cornate d\'Adda','Cornate d\'Adda',''),('IT','ADE','Anzola dell\'Emilia','Anzola dell\'Emilia',''),('IT','ADN','Aldino','Aldino',''),('IT','ADO','Madone','Madone',''),('IT','ADP','Sant Antonio di Pontecagnano','Sant Antonio di Pontecagnano',''),('IT','ADR','Andria','Andria',''),('IT','ADS','Ardesio','Ardesio',''),('IT','ADT','Albiano','Albiano',''),('IT','AEA','Aversa','Aversa',''),('IT','AEL','Castel Volturno','Castel Volturno',''),('IT','AFE','Ferrere','Ferrere',''),('IT','AFF','Affi','Affi',''),('IT','AFR','Afragola','Afragola',''),('IT','AGA','Agira','Agira',''),('IT','AGB','Agrate Brianza','Agrate Brianza',''),('IT','AGE','Angera','Angera',''),('IT','AGI','Aglie','Aglie',''),('IT','AGL','Agliana','Agliana',''),('IT','AGN','Cassano Magnago','Cassano Magnago',''),('IT','AGO','Agnadello','Agnadello',''),('IT','AGP','Agropoli','Agropoli',''),('IT','AGR','Agrigento','Agrigento',''),('IT','AGS','Arsago Seprio','Arsago Seprio',''),('IT','AGT','Argenta','Argenta',''),('IT','AGU','Agugliaro','Agugliaro',''),('IT','AHO','Alghero','Alghero',''),('IT','AIA','Airasca','Airasca',''),('IT','AIL','Acilia','Acilia',''),('IT','AIO','Aci Sant Antonia','Aci Sant Antonia',''),('IT','AJA','Albinea','Albinea',''),('IT','AKA','Arluno','Arluno',''),('IT','AKD','Arzergrande','Arzergrande',''),('IT','ALA','Ala','Ala',''),('IT','ALB','Albizzate','Albizzate',''),('IT','ALC','Alcamo','Alcamo',''),('IT','ALD','Calderino','Calderino',''),('IT','ALE','Alessandria','Alessandria',''),('IT','ALF','Alife','Alife',''),('IT','ALI','Alicudi','Alicudi',''),('IT','ALL','Albenga','Albenga',''),('IT','ALM','Alme','Alme',''),('IT','ALO','Alonte','Alonte',''),('IT','ALR','Airuno','Airuno',''),('IT','ALS','Alassio','Alassio',''),('IT','ALT','Altare','Altare',''),('IT','ALV','Altavilla Vicentina','Altavilla Vicentina',''),('IT','AMA','Amalfi','Amalfi',''),('IT','AMN','Santa Maria Navarrese','Santa Maria Navarrese',''),('IT','AMS','Albisano','Albisano',''),('IT','AMT','Amantea','Amantea',''),('IT','ANA','Anagni','Anagni',''),('IT','AND','Ardenno','Ardenno',''),('IT','ANE','Marone','Marone',''),('IT','ANG','Angiari','Angiari',''),('IT','ANJ','Sant\'Angelo di Piove di Sacco','Sant\'Angelo di Piove di Sacco',''),('IT','ANN','Annicco','Annicco',''),('IT','ANO','Aliano','Aliano',''),('IT','ANZ','Anzio','Anzio',''),('IT','AOA','Paola','Paola',''),('IT','AOI','Ancona','Ancona',''),('IT','AOL','Acciaroli','Acciaroli',''),('IT','AON','Saonara','Saonara',''),('IT','AOO','Arosio','Arosio',''),('IT','AOR','Caorle','Caorle',''),('IT','AOT','Aosta','Aosta',''),('IT','AOV','Casatenovo','Casatenovo',''),('IT','APA','Aprilia','Aprilia',''),('IT','APC','Anzano del Parco','Anzano del Parco',''),('IT','APG','Caponago','Caponago',''),('IT','APO','Altopascio','Altopascio',''),('IT','APV','Alano Di Piave','Alano Di Piave',''),('IT','APZ','Ampezzo','Ampezzo',''),('IT','ARA','Adria','Adria',''),('IT','ARC','Arcore','Arcore',''),('IT','ARD','Ardea','Ardea',''),('IT','ARE','Arezzo','Arezzo',''),('IT','ARG','Maruggio','Maruggio',''),('IT','ARI','Arzignano','Arzignano',''),('IT','ARJ','Arsie','Arsie',''),('IT','ARL','Argelato','Argelato',''),('IT','ARN','Arconate','Arconate',''),('IT','ARO','Adro','Adro',''),('IT','ARP','Arena Po','Arena Po',''),('IT','ARQ','Arquata Scrivia','Arquata Scrivia',''),('IT','ARS','Arsiero','Arsiero',''),('IT','ART','Artegna','Artegna',''),('IT','ARV','Carvico','Carvico',''),('IT','ARZ','Arzano','Arzano',''),('IT','ASA','Albano Sant Alessandro','Albano Sant Alessandro',''),('IT','ASC','Cascina della Costa','Cascina della Costa',''),('IT','ASG','Albosaggia','Albosaggia',''),('IT','ASI','Assisi','Assisi',''),('IT','ASL','Asola','Asola',''),('IT','ASM','Albisola Marina','Albisola Marina',''),('IT','ASN','Sustinenza','Sustinenza',''),('IT','ASO','Asolo','Asolo',''),('IT','ASP','Ascoli Piceno','Ascoli Piceno',''),('IT','ASS','Assago','Assago',''),('IT','AST','Asti','Asti',''),('IT','ASU','Albisola Superiore','Albisola Superiore',''),('IT','ATA','Arma di Taggia','Arma di Taggia',''),('IT','ATE','Atessa','Atessa',''),('IT','ATG','Castegnero','Castegnero',''),('IT','ATI','Castiglioncello','Castiglioncello',''),('IT','ATL','Atena Lucana','Atena Lucana',''),('IT','ATM','Altamura','Altamura',''),('IT','ATO','Altedo','Altedo',''),('IT','ATR','Abbiategrasso','Abbiategrasso',''),('IT','ATT','Attigliano','Attigliano',''),('IT','ATV','Cerano d\'Intelvi','Cerano d\'Intelvi',''),('IT','ATX','Arbatax','Arbatax',''),('IT','AUA','Aulla','Aulla',''),('IT','AUG','Augusta','Augusta',''),('IT','AUS','Aurisina','Aurisina',''),('IT','AUV','Arcugnano','Arcugnano',''),('IT','AVA','Albavilla','Albavilla',''),('IT','AVE','Avellino','Avellino',''),('IT','AVI','Aviano','Aviano',''),('IT','AVL','Altavilla','Altavilla',''),('IT','AVM','Altavilla Monferrato','Altavilla Monferrato',''),('IT','AVN','Avenza','Avenza',''),('IT','AVO','Avola','Avola',''),('IT','AVT','Avetrana','Avetrana',''),('IT','AVZ','Avezzano','Avezzano',''),('IT','AZA','Arenzano','Arenzano',''),('IT','AZD','Azzano Decimo','Azzano Decimo',''),('IT','AZO','Andezeno','Andezeno',''),('IT','AZT','Azzate','Azzate',''),('IT','AZZ','Castel D\'Azzano','Castel D\'Azzano',''),('IT','BAA','Bagnaria Arsa','Bagnaria Arsa',''),('IT','BAB','Bressana Bottarone','Bressana Bottarone',''),('IT','BAC','Baraccola','Baraccola',''),('IT','BAD','Basaldella','Basaldella',''),('IT','BAG','Bagno-Rubiera','Bagno-Rubiera',''),('IT','BAI','Baia','Baia',''),('IT','BAL','Bagnolo','Bagnolo',''),('IT','BAM','Bagnolo Mella','Bagnolo Mella',''),('IT','BAN','Bagno','Bagno',''),('IT','BAO','Basiano','Basiano',''),('IT','BAR','Barcellona','Barcellona',''),('IT','BAS','Bastia Umbra','Bastia Umbra',''),('IT','BAT','Battipaglia','Battipaglia',''),('IT','BAV','Bagni di Tivoli','Bagni di Tivoli',''),('IT','BBA','Brenna','Brenna',''),('IT','BBB','Bibbiena','Bibbiena',''),('IT','BBG','Barbariga','Barbariga',''),('IT','BBN','Bribano','Bribano',''),('IT','BBO','Bubano di Mordano','Bubano di Mordano',''),('IT','BBR','Barbara','Barbara',''),('IT','BBU','Borgo a Buggiano','Borgo a Buggiano',''),('IT','BCB','Bagnara Calabra','Bagnara Calabra',''),('IT','BCE','Bisceglie','Bisceglie',''),('IT','BCG','Badia Cantignano','Badia Cantignano',''),('IT','BCI','Bacoli','Bacoli',''),('IT','BCL','San Biagio di Callalta','San Biagio di Callalta',''),('IT','BCO','Buccino','Buccino',''),('IT','BCR','Bagnolo Cremasco','Bagnolo Cremasco',''),('IT','BCV','Baldissero Canavese','Baldissero Canavese',''),('IT','BDA','Buttigliera d\'Asti','Buttigliera d\'Asti',''),('IT','BDF','Bianconese di Fontevivo','Bianconese di Fontevivo',''),('IT','BDG','Bassano del Grappa','Bassano del Grappa',''),('IT','BDI','Bardi','Bardi',''),('IT','BDO','Borgo San Donato','Borgo San Donato',''),('IT','BDR','Brugnetto di Ripe','Brugnetto di Ripe',''),('IT','BDS','Brindisi','Brindisi',''),('IT','BDT','Belvedere di Tezze','Belvedere di Tezze',''),('IT','BEA','Benna','Benna',''),('IT','BED','Bedizzole(Brescia)','Bedizzole(Brescia)',''),('IT','BEK','Bruneck','Bruneck',''),('IT','BEL','Bellano','Bellano',''),('IT','BEN','Benevento','Benevento',''),('IT','BEV','Bene Vagienna','Bene Vagienna',''),('IT','BFE','Belfiore','Belfiore',''),('IT','BFI','Belforte all\'Isauro','Belforte all\'Isauro',''),('IT','BFO','Bonefro','Bonefro',''),('IT','BFR','Bonferraro','Bonferraro',''),('IT','BGA','Brignano Gera d \'Adda','Brignano Gera d \'Adda',''),('IT','BGE','Barge','Barge',''),('IT','BGG','Baggiovara','Baggiovara',''),('IT','BGH','Bordighera','Bordighera',''),('IT','BGI','Borgoricco','Borgoricco',''),('IT','BGJ','Busnago','Busnago',''),('IT','BGL','Belgioioso','Belgioioso',''),('IT','BGM','Borgosesia','Borgosesia',''),('IT','BGN','Brugnera','Brugnera',''),('IT','BGO','Bergamo','Bergamo',''),('IT','BGP','Bagnolo in Piano','Bagnolo in Piano',''),('IT','BGR','Bolgare','Bolgare',''),('IT','BGS','Bagnoli di Sopra','Bagnoli di Sopra',''),('IT','BGT','Borgo Ticino','Borgo Ticino',''),('IT','BGU','Buguggiate','Buguggiate',''),('IT','BGV','Bagnacavallo','Bagnacavallo',''),('IT','BGZ','Breganze','Breganze',''),('IT','BHA','Bagheria','Bagheria',''),('IT','BHI','Bolgheri','Bolgheri',''),('IT','BHR','Brugherio','Brugherio',''),('IT','BIA','Biassono','Biassono',''),('IT','BIE','Biella','Biella',''),('IT','BIG','Bigolino','Bigolino',''),('IT','BIN','Bertinoro','Bertinoro',''),('IT','BIO','Binasco','Binasco',''),('IT','BIR','Bairo','Bairo',''),('IT','BIS','Badia a Settimo','Badia a Settimo',''),('IT','BIT','Bitritto','Bitritto',''),('IT','BLA','Bellaria','Bellaria',''),('IT','BLB','Bellagio','Bellagio',''),('IT','BLG','Bollengo','Bollengo',''),('IT','BLI','Bardolino','Bardolino',''),('IT','BLL','Bellusco','Bellusco',''),('IT','BLM','Bodio Lomnago','Bodio Lomnago',''),('IT','BLN','Bagnoli','Bagnoli',''),('IT','BLO','Borghetto Lodigiano','Borghetto Lodigiano',''),('IT','BLP','Belpasso','Belpasso',''),('IT','BLQ','Bologna','Bologna',''),('IT','BLS','Vigliano Biellese','Vigliano Biellese',''),('IT','BLT','Barletta','Barletta',''),('IT','BLX','Belluno','Belluno',''),('IT','BLZ','Bolzaneto','Bolzaneto',''),('IT','BME','Bosco Mesola','Bosco Mesola',''),('IT','BMF','Belforte Monferrato','Belforte Monferrato',''),('IT','BMG','Burago Di Molgora','Burago Di Molgora',''),('IT','BMO','Bovisio Masciago','Bovisio Masciago',''),('IT','BMR','Borgomanero','Borgomanero',''),('IT','BMT','Belvedere Marittimo','Belvedere Marittimo',''),('IT','BMZ','Borgo a Mozzano','Borgo a Mozzano',''),('IT','BNA','Bagnatica','Bagnatica',''),('IT','BNB','Besana in Brianza','Besana in Brianza',''),('IT','BNC','Bianco','Bianco',''),('IT','BND','Bando','Bando',''),('IT','BNE','Beinette','Beinette',''),('IT','BNG','Binago','Binago',''),('IT','BNM','Bonemerse','Bonemerse',''),('IT','BNN','Brusnengo','Brusnengo',''),('IT','BNO','Bregnano','Bregnano',''),('IT','BNR','Biandronno','Biandronno',''),('IT','BNS','Bagnasco','Bagnasco',''),('IT','BNZ','Baranzate','Baranzate',''),('IT','BOA','Bosa','Bosa',''),('IT','BOC','Bornasco','Bornasco',''),('IT','BOE','Bollate','Bollate',''),('IT','BOF','Bussi Officine','Bussi Officine',''),('IT','BOG','Borgofranco d\'Ivrea','Borgofranco d\'Ivrea',''),('IT','BOL','Bolognetta','Bolognetta',''),('IT','BOM','Bomporto','Bomporto',''),('IT','BON','Bondeno','Bondeno',''),('IT','BOO','Borgolavezzaro','Borgolavezzaro',''),('IT','BOR','Borgo Di Trevi','Borgo Di Trevi',''),('IT','BOS','Bossolasco','Bossolasco',''),('IT','BOV','Bovolenta','Bovolenta',''),('IT','BOZ','Bozzolo','Bozzolo',''),('IT','BPA','Buttapietra','Buttapietra',''),('IT','BPG','Borgo Panigale','Borgo Panigale',''),('IT','BPI','Capalbio','Capalbio',''),('IT','BPO','Barcellona-Pozzo di Gotto','Barcellona-Pozzo di Gotto',''),('IT','BPS','Badia Polesine','Badia Polesine',''),('IT','BRA','Bra','Bra',''),('IT','BRB','Barbarasco','Barbarasco',''),('IT','BRC','Brescia','Brescia',''),('IT','BRE','Brescello','Brescello',''),('IT','BRF','Barrafranca','Barrafranca',''),('IT','BRG','Briga Novarese','Briga Novarese',''),('IT','BRI','Bari','Bari',''),('IT','BRL','Bagno a Ripoli','Bagno a Ripoli',''),('IT','BRN','Brendola (Vicenza)','Brendola (Vicenza)',''),('IT','BRO','Burolo','Burolo',''),('IT','BRR','Bareggio','Bareggio',''),('IT','BRS','Brembate','Brembate',''),('IT','BRT','Boretto','Boretto',''),('IT','BRV','Borgo San Giovanni','Borgo San Giovanni',''),('IT','BRZ','Borzago','Borzago',''),('IT','BSA','Borgo Sabotino','Borgo Sabotino',''),('IT','BSC','Bosconero','Bosconero',''),('IT','BSD','Borgo San Dalmazzo','Borgo San Dalmazzo',''),('IT','BSE','Borsea','Borsea',''),('IT','BSG','Brisighella','Brisighella',''),('IT','BSI','Basiglio','Basiglio',''),('IT','BSL','Borgo San Lorenzo','Borgo San Lorenzo',''),('IT','BSM','Bosco Marengo','Bosco Marengo',''),('IT','BSN','Busana','Busana',''),('IT','BSO','Bresso','Bresso',''),('IT','BSP','Bosisio Parini','Bosisio Parini',''),('IT','BSQ','Bersano','Bersano',''),('IT','BSR','Borgo San Michele','Borgo San Michele',''),('IT','BSS','Bosnasco','Bosnasco',''),('IT','BST','Busseto','Busseto',''),('IT','BSU','Busalla','Busalla',''),('IT','BSV','Bressanvido','Bressanvido',''),('IT','BSZ','Besozzo','Besozzo',''),('IT','BTC','Botticino Sera','Botticino Sera',''),('IT','BTG','Bastiglia','Bastiglia',''),('IT','BTI','Boffalora sopra Ticino','Boffalora sopra Ticino',''),('IT','BTO','Bitonto','Bitonto',''),('IT','BTP','Bonate di Sopra','Bonate di Sopra',''),('IT','BTR','Borgaro Torinese','Borgaro Torinese',''),('IT','BTS','Isorella, Brescia','Isorella, Brescia',''),('IT','BTT','Buttrio','Buttrio',''),('IT','BTV','Bosentino','Bosentino',''),('IT','BUA','Busto Arsizio','Busto Arsizio',''),('IT','BUB','Bubbio','Bubbio',''),('IT','BUC','Buccinasco','Buccinasco',''),('IT','BUD','Budrio','Budrio',''),('IT','BUG','Busto Garolfo','Busto Garolfo',''),('IT','BUI','Buriasco','Buriasco',''),('IT','BUL','Bussolengo','Bussolengo',''),('IT','BUN','Bruino','Bruino',''),('IT','BUO','Busano','Busano',''),('IT','BUS','Bussero','Bussero',''),('IT','BUT','Buscate','Buscate',''),('IT','BUV','Buonvicino','Buonvicino',''),('IT','BVA','Badia Calavena','Badia Calavena',''),('IT','BVD','Barberino Val D\'Elsa','Barberino Val D\'Elsa',''),('IT','BVE','Borgo Vercelli','Borgo Vercelli',''),('IT','BVG','Bentivoglio','Bentivoglio',''),('IT','BVI','Brivio','Brivio',''),('IT','BVL','Bovolone','Bovolone',''),('IT','BVM','Bova Marina','Bova Marina',''),('IT','BVN','Baveno','Baveno',''),('IT','BVR','Bevera','Bevera',''),('IT','BVS','Boves','Boves',''),('IT','BVT','Borgonovo Val Tidone','Borgonovo Val Tidone',''),('IT','BVV','Brissago Valtravaglia','Brissago Valtravaglia',''),('IT','BWA','Busca','Busca',''),('IT','BYS','Banyoles','Banyoles',''),('IT','BZA','Barzana','Barzana',''),('IT','BZD','Bruzolo di Susa','Bruzolo di Susa',''),('IT','BZG','Barzago','Barzago',''),('IT','BZL','Bagnarola','Bagnarola',''),('IT','BZO','Bolzano','Bolzano',''),('IT','BZZ','Basaluzzo','Basaluzzo',''),('IT','CAA','Capolona','Capolona',''),('IT','CAB','Cabiate','Cabiate',''),('IT','CAC','Carcare','Carcare',''),('IT','CAD','Cadelbosco di Sopra','Cadelbosco di Sopra',''),('IT','CAE','Canegrate','Canegrate',''),('IT','CAF','Casalfiumanese','Casalfiumanese',''),('IT','CAG','Cagliari','Cagliari',''),('IT','CAI','Caivano','Caivano',''),('IT','CAJ','Caianello','Caianello',''),('IT','CAL','Calenzano','Calenzano',''),('IT','CAM','Cambiago','Cambiago',''),('IT','CAN','Canelli','Canelli',''),('IT','CAO','Camerano','Camerano',''),('IT','CAP','Campodarsego','Campodarsego',''),('IT','CAQ','Caselette','Caselette',''),('IT','CAR','Casalmoro','Casalmoro',''),('IT','CAS','Castellammare di Stabia','Castellammare di Stabia',''),('IT','CAT','Cartignano','Cartignano',''),('IT','CAU','Cantu','Cantu',''),('IT','CAV','Cavallirio','Cavallirio',''),('IT','CAX','Casella/Genova','Casella/Genova',''),('IT','CAZ','Calzolaro','Calzolaro',''),('IT','CBB','Carobbio','Carobbio',''),('IT','CBC','Castelnuovo Bocca d\'Adda','Castelnuovo Bocca d\'Adda',''),('IT','CBD','Casalbordino','Casalbordino',''),('IT','CBE','Corbetta','Corbetta',''),('IT','CBF','Castelbelforte','Castelbelforte',''),('IT','CBG','Cisano Bergamasco','Cisano Bergamasco',''),('IT','CBI','Cassinetta Rizzone','Cassinetta Rizzone',''),('IT','CBL','Castel Bolognese','Castel Bolognese',''),('IT','CBN','Corbanese','Corbanese',''),('IT','CBO','Castel Boglione','Castel Boglione',''),('IT','CBR','Cassago Brianza','Cassago Brianza',''),('IT','CBS','Costabissara','Costabissara',''),('IT','CBT','Caresanablot','Caresanablot',''),('IT','CBU','Casalbuttano','Casalbuttano',''),('IT','CBX','Carobbio degli Angeli','Carobbio degli Angeli',''),('IT','CBZ','Campi Bisenzio','Campi Bisenzio',''),('IT','CCA','Civita Castellana','Civita Castellana',''),('IT','CCC','Cecchina','Cecchina',''),('IT','CCE','Capocolle','Capocolle',''),('IT','CCG','Cuceglio','Cuceglio',''),('IT','CCH','Collecchio','Collecchio',''),('IT','CCI','Castelcovati','Castelcovati',''),('IT','CCL','Cattolica','Cattolica',''),('IT','CCN','Cascina','Cascina',''),('IT','CCO','Cividate Camuno','Cividate Camuno',''),('IT','CCP','Campomorone','Campomorone',''),('IT','CCQ','Cetraro','Cetraro',''),('IT','CCR','Concamarise','Concamarise',''),('IT','CCS','Castel di Casio','Castel di Casio',''),('IT','CCT','Calcinate','Calcinate',''),('IT','CCU','Cassano Valcuvia','Cassano Valcuvia',''),('IT','CCV','Collecorvino','Collecorvino',''),('IT','CCZ','Concorezzo','Concorezzo',''),('IT','CDA','Casella d\'Asolo','Casella d\'Asolo',''),('IT','CDB','Canale D\'alba','Canale D\'alba',''),('IT','CDC','Citta di Castello','Citta di Castello',''),('IT','CDD','Cassano d\'Adda','Cassano d\'Adda',''),('IT','CDE','Castione Andevenno','Castione Andevenno',''),('IT','CDF','Cortina d\'Ampezzo','Cortina d\'Ampezzo',''),('IT','CDG','Chiusa D Ginestreto','Chiusa D Ginestreto',''),('IT','CDH','Castiglione d\'Adda','Castiglione d\'Adda',''),('IT','CDI','Calderari','Calderari',''),('IT','CDL','Colle di Val d\'Elsa','Colle di Val d\'Elsa',''),('IT','CDM','Crocetta del Montello','Crocetta del Montello',''),('IT','CDN','Cordenons','Cordenons',''),('IT','CDO','Ca\' Degli Oppi','Ca\' Degli Oppi',''),('IT','CDP','Cecchini di Pasiano','Cecchini di Pasiano',''),('IT','CDQ','Castions di Strada','Castions di Strada',''),('IT','CDR','Cadorago','Cadorago',''),('IT','CDS','Calendasco','Calendasco',''),('IT','CDT','Castiglione delle Stiviere','Castiglione delle Stiviere',''),('IT','CDU','Candelu','Candelu',''),('IT','CDV','Castrette di Villorba','Castrette di Villorba',''),('IT','CDX','Castelnovo di Sotto','Castelnovo di Sotto',''),('IT','CDZ','Cadola','Cadola',''),('IT','CEA','Cerignola','Cerignola',''),('IT','CEB','Cesana Brianza','Cesana Brianza',''),('IT','CEC','Cecina','Cecina',''),('IT','CED','Castelnuovo del Garda','Castelnuovo del Garda',''),('IT','CEE','Cermenate','Cermenate',''),('IT','CEF','Campiglione-Fenile','Campiglione-Fenile',''),('IT','CEG','Castegnato','Castegnato',''),('IT','CEH','Campagnola Emilia','Campagnola Emilia',''),('IT','CEI','Cesiomaggiore','Cesiomaggiore',''),('IT','CEL','Cella','Cella',''),('IT','CEM','Cesano Maderno','Cesano Maderno',''),('IT','CEN','Cesara Novara','Cesara Novara',''),('IT','CEO','Castello','Castello',''),('IT','CEP','Crespina','Crespina',''),('IT','CEQ','Castiglione della Pescaia','Castiglione della Pescaia',''),('IT','CER','Ceranesi','Ceranesi',''),('IT','CES','Cessalto','Cessalto',''),('IT','CET','Certaldo','Certaldo',''),('IT','CEU','Cairate','Cairate',''),('IT','CEV','Cervia','Cervia',''),('IT','CEX','Cerano','Cerano',''),('IT','CEZ','Cesena','Cesena',''),('IT','CFA','Castelfranco di Sopra','Castelfranco di Sopra',''),('IT','CFD','Castelfidardo','Castelfidardo',''),('IT','CFE','Castelfranco Emilia','Castelfranco Emilia',''),('IT','CFI','Corte de Frati','Corte de Frati',''),('IT','CFM','Ca de Fabbri','Ca de Fabbri',''),('IT','CFO','Colleferro','Colleferro',''),('IT','CFS','Cafasse','Cafasse',''),('IT','CFT','Casale Monferrato','Casale Monferrato',''),('IT','CFU','Cefalu','Cefalu',''),('IT','CFV','Castelfranco Veneto','Castelfranco Veneto',''),('IT','CGA','Campo Galliano','Campo Galliano',''),('IT','CGB','Cavenago di Brianza','Cavenago di Brianza',''),('IT','CGC','Corigliano Calabro','Corigliano Calabro',''),('IT','CGD','Castelgrande','Castelgrande',''),('IT','CGE','Cologne','Cologne',''),('IT','CGF','Castel Goffredo','Castel Goffredo',''),('IT','CGG','Correggio','Correggio',''),('IT','CGH','Ciliverghe','Ciliverghe',''),('IT','CGI','Casnigo','Casnigo',''),('IT','CGL','Castiglione','Castiglione',''),('IT','CGM','Crugola di Mornago','Crugola di Mornago',''),('IT','CGN','Codogno','Codogno',''),('IT','CGO','Cogollo del Cengio','Cogollo del Cengio',''),('IT','CGR','Casalgrasso','Casalgrasso',''),('IT','CGS','Cologno al Serio','Cologno al Serio',''),('IT','CGT','Cogliate','Cogliate',''),('IT','CGV','Cologna Veneta','Cologna Veneta',''),('IT','CHA','Chiavazza','Chiavazza',''),('IT','CHD','Chiuduno','Chiuduno',''),('IT','CHE','Cherasco','Cherasco',''),('IT','CHG','Chignolo D\'Isola','Chignolo D\'Isola',''),('IT','CHI','Chioggia','Chioggia',''),('IT','CHN','Chatillon','Chatillon',''),('IT','CHO','Chiampo','Chiampo',''),('IT','CHP','Chiuppano','Chiuppano',''),('IT','CHR','Chiara','Chiara',''),('IT','CHU','Chiuro','Chiuro',''),('IT','CHV','Chiavenna','Chiavenna',''),('IT','CHX','Chiavari','Chiavari',''),('IT','CIA','Ciampino Apt/Roma','Ciampino Apt/Roma',''),('IT','CIB','Cinisello Balsamo','Cinisello Balsamo',''),('IT','CIC','Cilavegna','Cilavegna',''),('IT','CID','Ca\' di David','Ca\' di David',''),('IT','CIE','Chieri','Chieri',''),('IT','CIF','Cividale del Friuli','Cividale del Friuli',''),('IT','CIG','Cislago','Cislago',''),('IT','CIH','Chiari','Chiari',''),('IT','CII','Chieti','Chieti',''),('IT','CIL','Conialo','Conialo',''),('IT','CIM','Cimadolmo','Cimadolmo',''),('IT','CIN','Cambiano','Cambiano',''),('IT','CIO','Corio','Corio',''),('IT','CIR','Cirie','Cirie',''),('IT','CIS','Cisterna di Latina','Cisterna di Latina',''),('IT','CIT','Cittadella','Cittadella',''),('IT','CIU','Cassinetta di Lugagnano','Cassinetta di Lugagnano',''),('IT','CIV','Chivasso','Chivasso',''),('IT','CIY','Comiso','Comiso',''),('IT','CIZ','Cizzolo','Cizzolo',''),('IT','CJZ','Castel San Giorgio','Castel San Giorgio',''),('IT','CLA','Calamandrana','Calamandrana',''),('IT','CLB','Colle Umberto','Colle Umberto',''),('IT','CLC','Calcio','Calcio',''),('IT','CLD','Calusco d\'Adda','Calusco d\'Adda',''),('IT','CLE','Castelleone','Castelleone',''),('IT','CLF','Carloforte','Carloforte',''),('IT','CLG','Casalgrande','Casalgrande',''),('IT','CLI','Cavallina','Cavallina',''),('IT','CLK','Cellatica','Cellatica',''),('IT','CLL','Collebeato','Collebeato',''),('IT','CLN','Colonnella','Colonnella',''),('IT','CLO','Ceriano Laghetto','Ceriano Laghetto',''),('IT','CLP','Corteolona','Corteolona',''),('IT','CLR','Calcara','Calcara',''),('IT','CLS','Calasetta','Calasetta',''),('IT','CLT','Collalto','Collalto',''),('IT','CLU','Castellucchio','Castellucchio',''),('IT','CLV','Conselve','Conselve',''),('IT','CLZ','Cologno Monzese','Cologno Monzese',''),('IT','CMA','Castel Madama','Castel Madama',''),('IT','CMB','Cerro al Lambro','Cerro al Lambro',''),('IT','CME','Castel Mella','Castel Mella',''),('IT','CMG','Castel Maggiore','Castel Maggiore',''),('IT','CMI','Carmignano di Brenta','Carmignano di Brenta',''),('IT','CML','Casamicciola Terme','Casamicciola Terme',''),('IT','CMM','Camignone','Camignone',''),('IT','CMN','Cormano','Cormano',''),('IT','CMO','Cairo Montenotte','Cairo Montenotte',''),('IT','CMP','Campello sul Clitunno','Campello sul Clitunno',''),('IT','CMR','Crema','Crema',''),('IT','CMS','Cormons','Cormons',''),('IT','CMT','Castelmarte','Castelmarte',''),('IT','CMU','Comun Nuovo','Comun Nuovo',''),('IT','CMV','Camisano Vicentino','Camisano Vicentino',''),('IT','CMX','Campochiaro','Campochiaro',''),('IT','CMZ','Costa di Mezzate','Costa di Mezzate',''),('IT','CNA','Corana','Corana',''),('IT','CNB','Cossano Belbo','Cossano Belbo',''),('IT','CNC','Castelnuovo Calcea','Castelnuovo Calcea',''),('IT','CND','Candiana','Candiana',''),('IT','CNE','Casnate','Casnate',''),('IT','CNF','Cavaria con Premezzo','Cavaria con Premezzo',''),('IT','CNG','Castel San Giovanni','Castel San Giovanni',''),('IT','CNH','Cadoneghe','Cadoneghe',''),('IT','CNI','Cenia','Cenia',''),('IT','CNL','Colognola ai Colli','Colognola ai Colli',''),('IT','CNM','Caerano di San Marco','Caerano di San Marco',''),('IT','CNN','Castronno','Castronno',''),('IT','CNO','Cernusco','Cernusco',''),('IT','CNP','Castiglione Cosentino','Castiglione Cosentino',''),('IT','CNQ','Castelnovo ne\' Monti','Castelnovo ne\' Monti',''),('IT','CNR','Contrada','Contrada',''),('IT','CNS','Castelnuovo Scrivia','Castelnuovo Scrivia',''),('IT','CNT','Cesenatico','Cesenatico',''),('IT','CNU','Cassina Nuova','Cassina Nuova',''),('IT','CNV','Cassolnovo','Cassolnovo',''),('IT','CNW','Cusano Milanino','Cusano Milanino',''),('IT','CNY','Cisano sul Neva','Cisano sul Neva',''),('IT','CNZ','Cento','Cento',''),('IT','COA','Cortenova','Cortenova',''),('IT','COB','Campobasso','Campobasso',''),('IT','COD','Caldarola','Caldarola',''),('IT','COE','Conetta','Conetta',''),('IT','COG','Conegliano','Conegliano',''),('IT','COI','Collesalvetti','Collesalvetti',''),('IT','COL','Colico','Colico',''),('IT','COM','Castelvetro di Modena','Castelvetro di Modena',''),('IT','CON','Condove','Condove',''),('IT','COO','Coriano','Coriano',''),('IT','COP','Caronno Pertusella','Caronno Pertusella',''),('IT','COQ','Capo d\'Orlando','Capo d\'Orlando',''),('IT','COR','Corcagnano','Corcagnano',''),('IT','COS','Cossato','Cossato',''),('IT','COT','Castrocaro Terme','Castrocaro Terme',''),('IT','COV','Cornedo Vicentino','Cornedo Vicentino',''),('IT','COY','Calolziocorte','Calolziocorte',''),('IT','COZ','Ciano d\'Enza','Ciano d\'Enza',''),('IT','CPA','Capraia','Capraia',''),('IT','CPB','Campo Calabro','Campo Calabro',''),('IT','CPC','Cassina de\'Pecchi','Cassina de\'Pecchi',''),('IT','CPD','Campodoro','Campodoro',''),('IT','CPE','Cappelle sul Tavo','Cappelle sul Tavo',''),('IT','CPF','Capodarco di Fermo','Capodarco di Fermo',''),('IT','CPG','Campegine','Campegine',''),('IT','CPI','Capriate San Gervasio','Capriate San Gervasio',''),('IT','CPL','Casalpusterlengo','Casalpusterlengo',''),('IT','CPM','Cupra Marittima','Cupra Marittima',''),('IT','CPO','Crespellano','Crespellano',''),('IT','CPP','Copparo','Copparo',''),('IT','CPR','Castano Primo','Castano Primo',''),('IT','CPS','Camposampiero','Camposampiero',''),('IT','CPT','Castel San Pietro Terme','Castel San Pietro Terme',''),('IT','CPU','Capua','Capua',''),('IT','CPV','Campoverde','Campoverde',''),('IT','CPX','Carpiano','Carpiano',''),('IT','CPZ','Capezzano Pianore','Capezzano Pianore',''),('IT','CQQ','Ciserano','Ciserano',''),('IT','CRA','Carrara','Carrara',''),('IT','CRB','Carbonera','Carbonera',''),('IT','CRC','Carasco','Carasco',''),('IT','CRD','Camin - Rione di Padova','Camin - Rione di Padova',''),('IT','CRE','Cremona','Cremona',''),('IT','CRF','Casarsa della Delizia','Casarsa della Delizia',''),('IT','CRG','Castello Roganzuolo','Castello Roganzuolo',''),('IT','CRI','Cosseria','Cosseria',''),('IT','CRL','Capriano del Colle','Capriano del Colle',''),('IT','CRM','Carmagnola','Carmagnola',''),('IT','CRN','Corniglio','Corniglio',''),('IT','CRO','Caraglio','Caraglio',''),('IT','CRP','Carpenedolo','Carpenedolo',''),('IT','CRQ','Castro Marina','Castro Marina',''),('IT','CRR','Carru','Carru',''),('IT','CRS','Corsico','Corsico',''),('IT','CRT','Cariati','Cariati',''),('IT','CRU','Carugate','Carugate',''),('IT','CRV','Crotone','Crotone',''),('IT','CRX','Cerea','Cerea',''),('IT','CRY','Carisio','Carisio',''),('IT','CRZ','Casorezzo','Casorezzo',''),('IT','CSA','Casirate d\'Adda','Casirate d\'Adda',''),('IT','CSB','Campolongo sul Brenta','Campolongo sul Brenta',''),('IT','CSC','Castellina in Chianti','Castellina in Chianti',''),('IT','CSD','Casale di Scodosia','Casale di Scodosia',''),('IT','CSE','Casarile','Casarile',''),('IT','CSG','Castelgomberto','Castelgomberto',''),('IT','CSH','Cassola','Cassola',''),('IT','CSI','Casinalbo','Casinalbo',''),('IT','CSL','Caselle di Altivole','Caselle di Altivole',''),('IT','CSM','Casalmaggiore','Casalmaggiore',''),('IT','CSN','Casandrino','Casandrino',''),('IT','CSO','Cassino','Cassino',''),('IT','CSP','Cassano Spinola','Cassano Spinola',''),('IT','CSQ','Casamassima','Casamassima',''),('IT','CSR','Casalecchio di Reno','Casalecchio di Reno',''),('IT','CSS','Casale sul Sile','Casale sul Sile',''),('IT','CST','Caserta','Caserta',''),('IT','CSU','Santa Croce sull\'Arno','Santa Croce sull\'Arno',''),('IT','CSV','Castelnuovo Valsugana','Castelnuovo Valsugana',''),('IT','CSY','Castello di Godego','Castello di Godego',''),('IT','CSZ','Castellanza','Castellanza',''),('IT','CTA','Catania','Catania',''),('IT','CTB','Carate Brianza','Carate Brianza',''),('IT','CTD','Castenedolo','Castenedolo',''),('IT','CTE','Caravate','Caravate',''),('IT','CTF','Castell\'Alfredo','Castell\'Alfredo',''),('IT','CTG','Casteggio','Casteggio',''),('IT','CTI','Caselle Torinese','Caselle Torinese',''),('IT','CTK','Castelsardo','Castelsardo',''),('IT','CTL','Castelguelfo','Castelguelfo',''),('IT','CTM','Castelminio','Castelminio',''),('IT','CTN','Castagnaro','Castagnaro',''),('IT','CTO','Castellarano','Castellarano',''),('IT','CTP','Castelplanio','Castelplanio',''),('IT','CTQ','Cantello','Cantello',''),('IT','CTR','Castellammare del Golfo','Castellammare del Golfo',''),('IT','CTS','Caltanissetta','Caltanissetta',''),('IT','CTT','Crocetta','Crocetta',''),('IT','CTU','Castelnuovo di Magra','Castelnuovo di Magra',''),('IT','CTV','Civitella in Val di Chiana','Civitella in Val di Chiana',''),('IT','CTX','Colli del Tronto','Colli del Tronto',''),('IT','CUA','Casapulla','Casapulla',''),('IT','CUD','Cornuda','Cornuda',''),('IT','CUE','Clusone','Clusone',''),('IT','CUG','Cureggio','Cureggio',''),('IT','CUI','Cuvio','Cuvio',''),('IT','CUN','Cuneo','Cuneo',''),('IT','CUO','Cusago','Cusago',''),('IT','CUR','Curno','Curno',''),('IT','CUS','Cusinati Di Rosa','Cusinati Di Rosa',''),('IT','CUU','Cutro','Cutro',''),('IT','CUV','Cuveglio','Cuveglio',''),('IT','CVA','Castellana','Castellana',''),('IT','CVB','Crevalcore','Crevalcore',''),('IT','CVC','Castro dei Volsci','Castro dei Volsci',''),('IT','CVE','Cervarese Santa Croce','Cervarese Santa Croce',''),('IT','CVG','Caravaggio','Caravaggio',''),('IT','CVH','Chiusavecchia','Chiusavecchia',''),('IT','CVI','Cavriago','Cavriago',''),('IT','CVL','Cravagliana','Cravagliana',''),('IT','CVM','Chiesa in Valmalenco','Chiesa in Valmalenco',''),('IT','CVN','Cavaion Veronese','Cavaion Veronese',''),('IT','CVO','Calvenzano','Calvenzano',''),('IT','CVP','Castelvetro Piacentino','Castelvetro Piacentino',''),('IT','CVQ','Castrovillari','Castrovillari',''),('IT','CVR','Cervere','Cervere',''),('IT','CVS','Chiopris-Viscone','Chiopris-Viscone',''),('IT','CVT','Castelovati','Castelovati',''),('IT','CVU','Civate','Civate',''),('IT','CVV','Civitavecchia','Civitavecchia',''),('IT','CVX','Cavo','Cavo',''),('IT','CVZ','Cavarzere','Cavarzere',''),('IT','CXA','Carugo','Carugo',''),('IT','CXB','Calmasino','Calmasino',''),('IT','CXE','Carpenedo','Carpenedo',''),('IT','CXI','Cameri','Cameri',''),('IT','CXL','Castelseprio','Castelseprio',''),('IT','CXM','Carmignano','Carmignano',''),('IT','CXN','Cotignola','Cotignola',''),('IT','CXO','Crescentino','Crescentino',''),('IT','CXR','Casoria','Casoria',''),('IT','CXV','Casale','Casale',''),('IT','CZA','Casazza','Casazza',''),('IT','CZL','Casaza Ligure','Casaza Ligure',''),('IT','CZM','Cazzago San Martino','Cazzago San Martino',''),('IT','CZN','Costanzana','Costanzana',''),('IT','CZO','Civezzano','Civezzano',''),('IT','CZP','Cazzago di Pianiga','Cazzago di Pianiga',''),('IT','CZS','Cazzano Sant\'Andrea','Cazzano Sant\'Andrea',''),('IT','CZT','Colzate','Colzate',''),('IT','CZU','Casarza Ligure','Casarza Ligure',''),('IT','CZZ','Creazzo','Creazzo',''),('IT','DAR','Castello D\'Argile','Castello D\'Argile',''),('IT','DCI','Decimomannu','Decimomannu',''),('IT','DDC','Diegaro','Diegaro',''),('IT','DDG','Desenzano del Garda','Desenzano del Garda',''),('IT','DDO','Dogana do Ortonovo','Dogana do Ortonovo',''),('IT','DEG','Dego','Dego',''),('IT','DEI','Castiglione dei Pepoli','Castiglione dei Pepoli',''),('IT','DEL','Dello','Dello',''),('IT','DER','Dermulo','Dermulo',''),('IT','DES','Desio','Desio',''),('IT','DEV','Dervio','Dervio',''),('IT','DGL','Domegliara','Domegliara',''),('IT','DGO','Dongo','Dongo',''),('IT','DIA','Diamante','Diamante',''),('IT','DIC','Ceretta','Ceretta',''),('IT','DIM','San Croce di Magliano','San Croce di Magliano',''),('IT','DIO','Maclodio','Maclodio',''),('IT','DIP','Masera di Padova','Masera di Padova',''),('IT','DLA','Dogliola','Dogliola',''),('IT','DLL','Medolla','Medolla',''),('IT','DME','Dalmine','Dalmine',''),('IT','DNO','Duino','Duino',''),('IT','DOG','Dogana','Dogana',''),('IT','DOL','Dolo','Dolo',''),('IT','DOM','Domodossola','Domodossola',''),('IT','DOO','Dosso','Dosso',''),('IT','DOS','Dosimo','Dosimo',''),('IT','DRG','Granaloro dell\'Emilia','Granaloro dell\'Emilia',''),('IT','DRI','Calderara di Reno','Calderara di Reno',''),('IT','DRO','Dorno','Dorno',''),('IT','DRS','Dresano','Dresano',''),('IT','DRZ','Drizzona','Drizzona',''),('IT','DSO','Dossobuono','Dossobuono',''),('IT','DSS','Dosson','Dosson',''),('IT','DUV','Dueville','Dueville',''),('IT','DVO','Daverio','Daverio',''),('IT','EAN','Masserano','Masserano',''),('IT','EBA','Elba','Elba',''),('IT','EBB','Eboli','Eboli',''),('IT','ECA','Alte Ceccato','Alte Ceccato',''),('IT','ECO','Ellera di Corciano','Ellera di Corciano',''),('IT','EDL','Edolo','Edolo',''),('IT','EDO','Corneliano D\'Alba','Corneliano D\'Alba',''),('IT','EGO','Martinengo','Martinengo',''),('IT','ELE','Felegara','Felegara',''),('IT','ELV','Salvaterra','Salvaterra',''),('IT','ENE','Cene','Cene',''),('IT','ENL','Leno','Leno',''),('IT','ENO','Enna','Enna',''),('IT','ENT','Lentini','Lentini',''),('IT','EPI','Empoli','Empoli',''),('IT','ERA','Merate','Merate',''),('IT','ERB','Erba','Erba',''),('IT','ERC','Ercolano','Ercolano',''),('IT','ERO','Pero','Pero',''),('IT','ERR','Ferrandina','Ferrandina',''),('IT','ESA','Ceresara','Ceresara',''),('IT','ESN','Esine','Esine',''),('IT','ESO','Erbusco','Erbusco',''),('IT','ESS','Cressa','Cressa',''),('IT','EST','Este','Este',''),('IT','ETA','Sermoneta','Sermoneta',''),('IT','ETT','Spinetta Marengo','Spinetta Marengo',''),('IT','EVA','Ceva','Ceva',''),('IT','FAA','Fagagna','Fagagna',''),('IT','FAE','Faenza','Faenza',''),('IT','FAG','Fagnano Olona','Fagnano Olona',''),('IT','FAI','Forino','Forino',''),('IT','FAL','Falconara','Falconara',''),('IT','FAO','Fano','Fano',''),('IT','FAR','Farra D\'Alpago','Farra D\'Alpago',''),('IT','FAV','Favignana','Favignana',''),('IT','FBI','Fombio','Fombio',''),('IT','FBO','Firenzuola','Firenzuola',''),('IT','FBR','Fabriano','Fabriano',''),('IT','FCE','Forno Canavese','Forno Canavese',''),('IT','FCO','Fiumicino','Fiumicino',''),('IT','FCV','Foce Varano','Foce Varano',''),('IT','FDB','Fornaci di Barga','Fornaci di Barga',''),('IT','FDM','Forte dei Marmi','Forte dei Marmi',''),('IT','FDR','Fabrica di Roma','Fabrica di Roma',''),('IT','FDV','Fossalta di Piave','Fossalta di Piave',''),('IT','FDZ','Fidenza','Fidenza',''),('IT','FEG','Fegino','Fegino',''),('IT','FEL','Fellette Di Romano','Fellette Di Romano',''),('IT','FEN','Ferno','Ferno',''),('IT','FEO','Flero','Flero',''),('IT','FER','Fermo','Fermo',''),('IT','FGA','Formigosa','Formigosa',''),('IT','FGD','Fara Gera d\'Adda','Fara Gera d\'Adda',''),('IT','FGE','Fregene','Fregene',''),('IT','FGN','Figino','Figino',''),('IT','FGO','Francenigo','Francenigo',''),('IT','FIA','Fiano Romano','Fiano Romano',''),('IT','FIC','Fisciano','Fisciano',''),('IT','FIE','Finale Emilia','Finale Emilia',''),('IT','FIL','Filago','Filago',''),('IT','FIN','Fino Mornasco','Fino Mornasco',''),('IT','FIR','Fiorano Modenese','Fiorano Modenese',''),('IT','FIS','Fara in Sabina','Fara in Sabina',''),('IT','FIU','Fiume Veneto','Fiume Veneto',''),('IT','FIZ','Fizzonasco di Pieve Emanuele','Fizzonasco di Pieve Emanuele',''),('IT','FLM','Flumeri','Flumeri',''),('IT','FLO','Folignano','Folignano',''),('IT','FLR','Firenze','Firenze',''),('IT','FMD','Fiorano Modenese','Fiorano Modenese',''),('IT','FME','Francavilla al Mare','Francavilla al Mare',''),('IT','FMG','Formigine','Formigine',''),('IT','FMN','Fermignano','Fermignano',''),('IT','FNI','Ferentino','Ferentino',''),('IT','FNL','Finale Ligure','Finale Ligure',''),('IT','FNO','Fanano','Fanano',''),('IT','FNT','Fontaneto d\'Agogna','Fontaneto d\'Agogna',''),('IT','FNZ','Fiorenzuola d\'Arda','Fiorenzuola d\'Arda',''),('IT','FOD','Fossalta di Portogruaro','Fossalta di Portogruaro',''),('IT','FOG','Foggia','Foggia',''),('IT','FOL','Follonica','Follonica',''),('IT','FOM','Formia','Formia',''),('IT','FON','Fornacette','Fornacette',''),('IT','FOO','Fognano','Fognano',''),('IT','FOT','Front','Front',''),('IT','FPO','Filicudi Porto','Filicudi Porto',''),('IT','FPP','Forlimpopoli','Forlimpopoli',''),('IT','FRA','Frascati','Frascati',''),('IT','FRD','Forio','Forio',''),('IT','FRG','Fatagliano','Fatagliano',''),('IT','FRI','Fornaci','Fornaci',''),('IT','FRL','Forli','Forli',''),('IT','FRN','Fiorano Modenese','Fiorano Modenese',''),('IT','FRO','Frosinone','Frosinone',''),('IT','FRR','Ferrara','Ferrara',''),('IT','FRT','Fratta Todina','Fratta Todina',''),('IT','FRZ','Ferrazza','Ferrazza',''),('IT','FSA','Fusina','Fusina',''),('IT','FSD','Fossadello','Fossadello',''),('IT','FSE','Fiesse','Fiesse',''),('IT','FSI','Fossoli','Fossoli',''),('IT','FSO','Fusine','Fusine',''),('IT','FSS','Fossano','Fossano',''),('IT','FSZ','Figino Serenza','Figino Serenza',''),('IT','FTE','Feltre','Feltre',''),('IT','FTF','Fontanafredda','Fontanafredda',''),('IT','FTL','Ferentillo','Ferentillo',''),('IT','FTM','Frattamaggiore','Frattamaggiore',''),('IT','FTO','Felitto','Felitto',''),('IT','FTV','Fontaniva','Fontaniva',''),('IT','FUC','Fucecchio','Fucecchio',''),('IT','FUM','Fumane','Fumane',''),('IT','FUN','Funo D\'argelato','Funo D\'argelato',''),('IT','FUO','Fuorni','Fuorni',''),('IT','FUS','Fusignano','Fusignano',''),('IT','FUT','Fiesso Umbertiano','Fiesso Umbertiano',''),('IT','FVD','Figline Valdarno','Figline Valdarno',''),('IT','FVF','Foiano di Val Fortore','Foiano di Val Fortore',''),('IT','FVO','Fontevivo','Fontevivo',''),('IT','FVR','Favara','Favara',''),('IT','FZI','Fornace Zarattini','Fornace Zarattini',''),('IT','FZO','Fonzaso','Fonzaso',''),('IT','GAE','Gaeta','Gaeta',''),('IT','GAG','Gaglianico','Gaglianico',''),('IT','GAI','Golfo Aranci','Golfo Aranci',''),('IT','GAL','Gallipoli','Gallipoli',''),('IT','GAM','Gambolo','Gambolo',''),('IT','GAN','Gaglianico','Gaglianico',''),('IT','GAO','Gallico','Gallico',''),('IT','GAR','Gardone Val Trompia','Gardone Val Trompia',''),('IT','GAS','Garessio','Garessio',''),('IT','GAT','Gatteo','Gatteo',''),('IT','GAV','Gavi','Gavi',''),('IT','GAZ','Gazzada','Gazzada',''),('IT','GBA','Galbiate','Galbiate',''),('IT','GBI','Gambassi Terme','Gambassi Terme',''),('IT','GBL','Gambellara','Gambellara',''),('IT','GBR','Gambarare','Gambarare',''),('IT','GBT','Gambettola','Gambettola',''),('IT','GCN','Cona','Cona',''),('IT','GCO','Gattico','Gattico',''),('IT','GCS','Gratacasolo','Gratacasolo',''),('IT','GCV','San Giorgio Canavese','San Giorgio Canavese',''),('IT','GDA','Gricignano d\'Aversa','Gricignano d\'Aversa',''),('IT','GDC','Gioia del Colle','Gioia del Colle',''),('IT','GDF','Gemona del Friuli','Gemona del Friuli',''),('IT','GDO','Gardolo','Gardolo',''),('IT','GDR','Genzano di Roma','Genzano di Roma',''),('IT','GDS','Gandosso','Gandosso',''),('IT','GDX','Gagliano del Capo','Gagliano del Capo',''),('IT','GEA','Gela','Gela',''),('IT','GED','Gazzola','Gazzola',''),('IT','GER','Gerbido di Mortizza','Gerbido di Mortizza',''),('IT','GFT','Ginestra','Ginestra',''),('IT','GGE','Gorgoglione','Gorgoglione',''),('IT','GGI','Gaggiano','Gaggiano',''),('IT','GGL','Graglia','Graglia',''),('IT','GGM','Gaggio Montano','Gaggio Montano',''),('IT','GGN','Grigno','Grigno',''),('IT','GGO','Gargnano','Gargnano',''),('IT','GGS','Villaggio Sereno','Villaggio Sereno',''),('IT','GGZ','Gorgonzola','Gorgonzola',''),('IT','GHI','Ghedi','Ghedi',''),('IT','GHM','Ghemme','Ghemme',''),('IT','GHO','Langhirano','Langhirano',''),('IT','GIA','Giardini','Giardini',''),('IT','GIC','Greve in Chianti','Greve in Chianti',''),('IT','GII','Giannutri','Giannutri',''),('IT','GIL','Santa Giuletta','Santa Giuletta',''),('IT','GIN','Ginosa','Ginosa',''),('IT','GIO','Cortemaggiore','Cortemaggiore',''),('IT','GIP','San Giovanni in Persiceto','San Giovanni in Persiceto',''),('IT','GIT','Gioia Tauro','Gioia Tauro',''),('IT','GLA','Gallo','Gallo',''),('IT','GLI','Galtelli','Galtelli',''),('IT','GLJ','Camogli','Camogli',''),('IT','GLL','Galliera','Galliera',''),('IT','GLM','Gorla Maggiore','Gorla Maggiore',''),('IT','GLO','Gera Lario','Gera Lario',''),('IT','GLT','Gualtieri','Gualtieri',''),('IT','GMA','Gabicce Mare','Gabicce Mare',''),('IT','GMB','Gambara','Gambara',''),('IT','GMD','Grumello del Monte','Grumello del Monte',''),('IT','GME','Gorla Minore','Gorla Minore',''),('IT','GMO','Grumolo delle Abbadesse','Grumolo delle Abbadesse',''),('IT','GMR','San Giorgio Monferrato','San Giorgio Monferrato',''),('IT','GNA','Germignaga','Germignaga',''),('IT','GND','Gandino','Gandino',''),('IT','GNL','Genola','Genola',''),('IT','GNN','Gerenzano','Gerenzano',''),('IT','GNO','Gragnano','Gragnano',''),('IT','GNS','Grignano','Grignano',''),('IT','GOA','Genoa','Genoa',''),('IT','GOE','Gorle','Gorle',''),('IT','GOG','Castello D\'Agogna','Castello D\'Agogna',''),('IT','GOI','Goito','Goito',''),('IT','GOM','Gorgo al Monticano','Gorgo al Monticano',''),('IT','GON','Gonnosfanadiga','Gonnosfanadiga',''),('IT','GOO','Goro','Goro',''),('IT','GOR','Gorgona','Gorgona',''),('IT','GOS','Ginostra','Ginostra',''),('IT','GOV','San Gennaro Vesuviano','San Gennaro Vesuviano',''),('IT','GPR','Giglio Porto','Giglio Porto',''),('IT','GRA','Grassobbio','Grassobbio',''),('IT','GRB','Garbagnate Milanese','Garbagnate Milanese',''),('IT','GRC','Gropello Cairoli','Gropello Cairoli',''),('IT','GRD','Grado','Grado',''),('IT','GRE','Gavirate','Gavirate',''),('IT','GRG','Grugliasco','Grugliasco',''),('IT','GRI','Gaiarine','Gaiarine',''),('IT','GRM','Giavera del Montello','Giavera del Montello',''),('IT','GRN','Grandate','Grandate',''),('IT','GRO','Grone','Grone',''),('IT','GRS','Grosseto','Grosseto',''),('IT','GRT','Grottaglie','Grottaglie',''),('IT','GRU','Grumo Appula','Grumo Appula',''),('IT','GRZ','Grezzana','Grezzana',''),('IT','GSA','Giussano','Giussano',''),('IT','GSB','Ghisalba','Ghisalba',''),('IT','GSL','Gossolengo','Gossolengo',''),('IT','GSO','Gassino Torinese','Gassino Torinese',''),('IT','GSS','Gussago','Gussago',''),('IT','GSU','Godega di Sant\'Urbano','Godega di Sant\'Urbano',''),('IT','GTA','Gattinara','Gattinara',''),('IT','GTC','Gattatico','Gattatico',''),('IT','GTD','Gualdo Tadino','Gualdo Tadino',''),('IT','GTE','Gallarate','Gallarate',''),('IT','GTN','Galatina','Galatina',''),('IT','GTT','Grantorto','Grantorto',''),('IT','GUA','Guardamiglio','Guardamiglio',''),('IT','GUE','Guarene','Guarene',''),('IT','GUI','Giulianova Lido','Giulianova Lido',''),('IT','GUS','Guastalla','Guastalla',''),('IT','GUT','Guasticce','Guasticce',''),('IT','GUZ','Guidizzolo','Guidizzolo',''),('IT','GVA','Giaveno','Giaveno',''),('IT','GVC','San Giovanni in Croce','San Giovanni in Croce',''),('IT','GVE','Galliera Veneta','Galliera Veneta',''),('IT','GVO','Gavardo','Gavardo',''),('IT','GVR','Gaverina Terme','Gaverina Terme',''),('IT','GVT','Gravellona Toce','Gravellona Toce',''),('IT','GVZ','Giovinazzo','Giovinazzo',''),('IT','GZA','Gorizia','Gorizia',''),('IT','GZG','Gonzaga','Gonzaga',''),('IT','GZI','Gazzaniga','Gazzaniga',''),('IT','GZO','Gozzano','Gozzano',''),('IT','HIA','Anghiari','Anghiari',''),('IT','HJT','Andalo Valtellino','Andalo Valtellino',''),('IT','ICA','Tor Vajanica','Tor Vajanica',''),('IT','ICE','Conselice','Conselice',''),('IT','IDF','Isola delle Femmine','Isola delle Femmine',''),('IT','IDG','Isola del Giglio','Isola del Giglio',''),('IT','IDS','Isola della Scala','Isola della Scala',''),('IT','IEO','Iseo','Iseo',''),('IT','IEV','Pieve','Pieve',''),('IT','IGL','Savigliano','Savigliano',''),('IT','IGO','Cartigliano','Cartigliano',''),('IT','IIO','San Gillio','San Gillio',''),('IT','IML','Imola','Imola',''),('IT','IMP','Imperia','Imperia',''),('IT','INO','Induno Olona','Induno Olona',''),('IT','INV','Invorio','Invorio',''),('IT','IOA','Civitanova Marche','Civitanova Marche',''),('IT','IOB','Baiso','Baiso',''),('IT','IOE','Issogne','Issogne',''),('IT','IOI','Maiori','Maiori',''),('IT','IRO','Sirone','Sirone',''),('IT','IRZ','Isola Rizza','Isola Rizza',''),('IT','ISE','Isernia','Isernia',''),('IT','ISH','Ischia','Ischia',''),('IT','ISI','Cinisi','Cinisi',''),('IT','ISO','Ortonova, Isola','Ortonova, Isola',''),('IT','ISP','Ispica','Ispica',''),('IT','ISS','Isola Santo Stefano','Isola Santo Stefano',''),('IT','IST','Istrana','Istrana',''),('IT','ISV','Isola Vicentina','Isola Vicentina',''),('IT','IVA','Incisa In Val d\'Arno','Incisa In Val d\'Arno',''),('IT','IVG','Inverigo','Inverigo',''),('IT','IVO','Inveruno','Inveruno',''),('IT','IVR','Ivrea','Ivrea',''),('IT','IZA','Inzago','Inzago',''),('IT','JCO','Jerago con Orago','Jerago con Orago',''),('IT','JES','Jesi','Jesi',''),('IT','JLO','Jesolo','Jesolo',''),('IT','JZU','Jerzu','Jerzu',''),('IT','KAT','Catona','Catona',''),('IT','LAA','Laterina','Laterina',''),('IT','LAC','Lacedonia','Lacedonia',''),('IT','LAD','Ladispoli','Ladispoli',''),('IT','LAE','Lacco Ameno','Lacco Ameno',''),('IT','LAG','Lagonegro','Lagonegro',''),('IT','LAM','La Morra','La Morra',''),('IT','LAN','Lanciole di Piteglio','Lanciole di Piteglio',''),('IT','LAO','Legnago','Legnago',''),('IT','LAQ','L\'Aquila','L\'Aquila',''),('IT','LAR','Larderello','Larderello',''),('IT','LAV','Lavis','Lavis',''),('IT','LAW','Lavagna','Lavagna',''),('IT','LBA','Alba','Alba',''),('IT','LBD','Lombardore','Lombardore',''),('IT','LBG','Lambrugo','Lambrugo',''),('IT','LCC','Lecce','Lecce',''),('IT','LCG','Lucignano','Lucignano',''),('IT','LCI','Lanciano','Lanciano',''),('IT','LCM','Limido Comasco','Limido Comasco',''),('IT','LCO','Lecco','Lecco',''),('IT','LCR','Lacchiarella','Lacchiarella',''),('IT','LCV','Lucca','Lucca',''),('IT','LDA','Meldola','Meldola',''),('IT','LDC','Solignano Nuovo-Castelvetro di Modena','Solignano Nuovo-Castelvetro di Modena',''),('IT','LDG','Caldogno','Caldogno',''),('IT','LDI','Lodi','Lodi',''),('IT','LDO','Landriano','Landriano',''),('IT','LDS','Limidi Di Soliera','Limidi Di Soliera',''),('IT','LDV','Lugo di Vicenza','Lugo di Vicenza',''),('IT','LEA','Scalea','Scalea',''),('IT','LEC','Leuca','Leuca',''),('IT','LEE','Levate','Levate',''),('IT','LEI','Leini','Leini',''),('IT','LEN','Levanto','Levanto',''),('IT','LEO','Lessona','Lessona',''),('IT','LER','Lerici','Lerici',''),('IT','LES','Lesina','Lesina',''),('IT','LET','Casaletto Lodigiano','Casaletto Lodigiano',''),('IT','LEU','Leumann','Leumann',''),('IT','LEV','Levanzo','Levanzo',''),('IT','LFF','Leffe','Leffe',''),('IT','LGE','Longarone','Longarone',''),('IT','LGG','Celle Ligure','Celle Ligure',''),('IT','LGN','Legnano','Legnano',''),('IT','LGO','Lancenigo','Lancenigo',''),('IT','LGR','Legnaro','Legnaro',''),('IT','LGV','Luserna San Giovanni','Luserna San Giovanni',''),('IT','LIA','Loiano','Loiano',''),('IT','LIB','Lizzano in Belvedere','Lizzano in Belvedere',''),('IT','LIC','Licata','Licata',''),('IT','LIM','Limito','Limito',''),('IT','LIN','Linate Apt/Milano','Linate Apt/Milano',''),('IT','LIP','Lipari','Lipari',''),('IT','LIS','Liscate','Liscate',''),('IT','LIU','Linosa','Linosa',''),('IT','LIV','Livorno','Livorno',''),('IT','LJB','Lastra a Signa','Lastra a Signa',''),('IT','LKT','Lunata','Lunata',''),('IT','LLE','Collevecchio','Collevecchio',''),('IT','LLI','Legoli','Legoli',''),('IT','LLO','Lallio','Lallio',''),('IT','LLT','Savelletri','Savelletri',''),('IT','LMA','Limena','Limena',''),('IT','LMB','Limbiate','Limbiate',''),('IT','LMD','Limiti','Limiti',''),('IT','LMG','Lomagna','Lomagna',''),('IT','LMM','Lammari','Lammari',''),('IT','LMO','Lamporecchio','Lamporecchio',''),('IT','LMP','Lampedusa','Lampedusa',''),('IT','LMR','Lurago Marinone','Lurago Marinone',''),('IT','LMS','San Marco in Lamis','San Marco in Lamis',''),('IT','LMZ','Lomazzo','Lomazzo',''),('IT','LNA','Lucernate','Lucernate',''),('IT','LNG','Longiano','Longiano',''),('IT','LNI','Lonigo','Lonigo',''),('IT','LNO','Lariano','Lariano',''),('IT','LOA','Loano','Loano',''),('IT','LOL','Castiglione Olona','Castiglione Olona',''),('IT','LOP','Lonate Pozzolo','Lonate Pozzolo',''),('IT','LOZ','Lozza','Lozza',''),('IT','LPP','Lonate Ceppino','Lonate Ceppino',''),('IT','LRC','Larciano, Firenze','Larciano, Firenze',''),('IT','LRG','Loreggia','Loreggia',''),('IT','LRT','Loreto','Loreto',''),('IT','LRV','Lovara','Lovara',''),('IT','LSA','Limite sull\'Arno','Limite sull\'Arno',''),('IT','LSD','Lignano Sabbiadoro','Lignano Sabbiadoro',''),('IT','LSK','Lisiko','Lisiko',''),('IT','LSN','Latisana','Latisana',''),('IT','LSO','Lissone','Lissone',''),('IT','LSS','Lentate sul Seveso','Lentate sul Seveso',''),('IT','LTA','Lastra','Lastra',''),('IT','LTE','Lainate','Lainate',''),('IT','LTH','Luttach','Luttach',''),('IT','LTN','Latina','Latina',''),('IT','LTZ','Locate di Triulzi','Locate di Triulzi',''),('IT','LUG','Lugo','Lugo',''),('IT','LUI','Luino','Luino',''),('IT','LUR','Ca\' di Lugo','Ca\' di Lugo',''),('IT','LUZ','Lauzacco','Lauzacco',''),('IT','LVE','Laives','Laives',''),('IT','LVO','Locate Varesino','Locate Varesino',''),('IT','LVR','Lovere','Lovere',''),('IT','LZA','Luzzara','Luzzara',''),('IT','LZE','Lazise','Lazise',''),('IT','LZI','Lanzo d\'Intelvi','Lanzo d\'Intelvi',''),('IT','LZN','Lumezzane','Lumezzane',''),('IT','LZO','Lavezzola','Lavezzola',''),('IT','LZT','Lanzo Torinese','Lanzo Torinese',''),('IT','MAA','Melara','Melara',''),('IT','MAB','Monticello d\'Alba','Monticello d\'Alba',''),('IT','MAC','Macherio','Macherio',''),('IT','MAD','Madignano','Madignano',''),('IT','MAE','Maerne','Maerne',''),('IT','MAF','Massa Fiscaglia','Massa Fiscaglia',''),('IT','MAG','Masnago','Masnago',''),('IT','MAH','Marina di Ginosa','Marina di Ginosa',''),('IT','MAI','Mairano','Mairano',''),('IT','MAJ','Marano Lagunare','Marano Lagunare',''),('IT','MAL','Malgesso','Malgesso',''),('IT','MAM','Marciana Marina','Marciana Marina',''),('IT','MAN','Mantova','Mantova',''),('IT','MAO','Maclodio','Maclodio',''),('IT','MAP','Manoppello','Manoppello',''),('IT','MAR','Maranello','Maranello',''),('IT','MAS','Motta sant Anastasia','Motta sant Anastasia',''),('IT','MAT','Malnate','Malnate',''),('IT','MAY','Capannori','Capannori',''),('IT','MAZ','Mazara del Vallo','Mazara del Vallo',''),('IT','MBA','San Martino Buon Albergo','San Martino Buon Albergo',''),('IT','MBC','Misterbianco, Catania','Misterbianco, Catania',''),('IT','MBI','Mezzana Bigli','Mezzana Bigli',''),('IT','MBO','Sant\'Ambrogio di Torino','Sant\'Ambrogio di Torino',''),('IT','MCA','Macerata','Macerata',''),('IT','MCC','Montecchio Emilia','Montecchio Emilia',''),('IT','MCE','Mariano Comense','Mariano Comense',''),('IT','MCH','Montichiari','Montichiari',''),('IT','MCI','Monleone di Cicagna','Monleone di Cicagna',''),('IT','MCL','Macellai','Macellai',''),('IT','MCM','Macomer','Macomer',''),('IT','MCN','Marcon','Marcon',''),('IT','MCO','Monchiero','Monchiero',''),('IT','MCP','Montecchia di Crosara','Montecchia di Crosara',''),('IT','MCR','Mezzocorona','Mezzocorona',''),('IT','MCS','Mercato San Severino','Mercato San Severino',''),('IT','MCT','Mottalciata','Mottalciata',''),('IT','MCU','Mirabello','Mirabello',''),('IT','MCV','Molinetto-Ciliverghe','Molinetto-Ciliverghe',''),('IT','MCZ','Massa e Cozzile','Massa e Cozzile',''),('IT','MDA','La Maddalena','La Maddalena',''),('IT','MDB','Mandolossa','Mandolossa',''),('IT','MDC','Marina di Carrara','Marina di Carrara',''),('IT','MDD','Madonna dell\'Olmo','Madonna dell\'Olmo',''),('IT','MDE','Madonna','Madonna',''),('IT','MDG','Modigliana','Modigliana',''),('IT','MDI','Medicina','Medicina',''),('IT','MDL','Maddalene','Maddalene',''),('IT','MDM','Marina di Montemarciano','Marina di Montemarciano',''),('IT','MDO','Meduno','Meduno',''),('IT','MDP','Musile di Piave','Musile di Piave',''),('IT','MDR','Morciano di Romagna','Morciano di Romagna',''),('IT','MDS','Meledo','Meledo',''),('IT','MDT','Marino del Tronto','Marino del Tronto',''),('IT','MDU','Monteroduni','Monteroduni',''),('IT','MDV','Mazzo di Valtellina','Mazzo di Valtellina',''),('IT','MDW','Margherita di Savoia','Margherita di Savoia',''),('IT','MEA','Montecarotto','Montecarotto',''),('IT','MEC','Monte Cremasco','Monte Cremasco',''),('IT','MED','Meda','Meda',''),('IT','MEE','Mesero','Mesero',''),('IT','MEG','Mediglia','Mediglia',''),('IT','MEI','Melfi','Melfi',''),('IT','MEL','Melilli','Melilli',''),('IT','MEN','Merano','Merano',''),('IT','MEO','Meolo','Meolo',''),('IT','MER','Merone','Merone',''),('IT','MES','Mesagne','Mesagne',''),('IT','MET','Mestre','Mestre',''),('IT','MEZ','Mezzolombardo','Mezzolombardo',''),('IT','MFD','Montefiore dell\'Aso','Montefiore dell\'Aso',''),('IT','MFI','Menfi','Menfi',''),('IT','MFR','Manfredonia','Manfredonia',''),('IT','MFS','Massafra','Massafra',''),('IT','MGA','Magenta','Magenta',''),('IT','MGD','Mongrando','Mongrando',''),('IT','MGE','Marina Grande','Marina Grande',''),('IT','MGG','Maggiore','Maggiore',''),('IT','MGI','Campolongo Maggiore','Campolongo Maggiore',''),('IT','MGL','Montegaldella','Montegaldella',''),('IT','MGN','Magnago','Magnago',''),('IT','MGO','Mercogliano','Mercogliano',''),('IT','MGR','Magreta','Magreta',''),('IT','MGT','Montegiordano','Montegiordano',''),('IT','MHE','Macereto','Macereto',''),('IT','MHI','Mathi','Mathi',''),('IT','MIA','Mira','Mira',''),('IT','MID','Mirandola','Mirandola',''),('IT','MIE','Moie','Moie',''),('IT','MIG','Monteriggioni','Monteriggioni',''),('IT','MII','Misinto','Misinto',''),('IT','MIL','Milano','Milano',''),('IT','MIM','Mili Marina','Mili Marina',''),('IT','MIN','Merlino','Merlino',''),('IT','MIO','Maniago','Maniago',''),('IT','MIR','Mirano','Mirano',''),('IT','MIS','Misano Adriatico','Misano Adriatico',''),('IT','MIT','Marina di Camerota','Marina di Camerota',''),('IT','MJC','Mollicciara','Mollicciara',''),('IT','MLA','Molinella','Molinella',''),('IT','MLB','Marina della Lobra','Marina della Lobra',''),('IT','MLC','Montalcino','Montalcino',''),('IT','MLD','Molino del Piano','Molino del Piano',''),('IT','MLE','Massalengo','Massalengo',''),('IT','MLG','Melegnano','Melegnano',''),('IT','MLI','Maddaloni','Maddaloni',''),('IT','MLL','Mandello del Lario','Mandello del Lario',''),('IT','MLN','Maslianico','Maslianico',''),('IT','MLO','Malo','Malo',''),('IT','MLS','Montalto di Castro','Montalto di Castro',''),('IT','MLT','Malcantone','Malcantone',''),('IT','MLU','Massa Lubrense','Massa Lubrense',''),('IT','MLV','Marcallo con Casone','Marcallo con Casone',''),('IT','MLZ','Milazzo','Milazzo',''),('IT','MMA','Montemarciano','Montemarciano',''),('IT','MMG','Montecchio Maggiore','Montecchio Maggiore',''),('IT','MMI','Marmentino','Marmentino',''),('IT','MMN','Marina di Monasterace','Marina di Monasterace',''),('IT','MMO','Marettimo','Marettimo',''),('IT','MMR','Montemerano','Montemerano',''),('IT','MNA','Manta','Manta',''),('IT','MNB','Montelabbate','Montelabbate',''),('IT','MNC','Mandrio di Correggio','Mandrio di Correggio',''),('IT','MND','Mondello, Palermo','Mondello, Palermo',''),('IT','MNE','Marnate','Marnate',''),('IT','MNF','Monfalcone','Monfalcone',''),('IT','MNG','Mignagola di Carbonera','Mignagola di Carbonera',''),('IT','MNN','Manesseno','Manesseno',''),('IT','MNO','Monsano','Monsano',''),('IT','MNP','Monopoli','Monopoli',''),('IT','MNR','Minerbio','Minerbio',''),('IT','MNS','Monastier di Treviso','Monastier di Treviso',''),('IT','MNT','Montale','Montale',''),('IT','MNU','Marinella di Selinunte','Marinella di Selinunte',''),('IT','MNZ','Manzano','Manzano',''),('IT','MOA','Montebelluna','Montebelluna',''),('IT','MOC','Morano Calabro','Morano Calabro',''),('IT','MOD','Modena','Modena',''),('IT','MOE','Monselice','Monselice',''),('IT','MOF','Monteforte d\'Alpone','Monteforte d\'Alpone',''),('IT','MOG','Mogliano Veneto','Mogliano Veneto',''),('IT','MOI','Moimacco','Moimacco',''),('IT','MOK','Montelupo Albese','Montelupo Albese',''),('IT','MOL','Molfetta','Molfetta',''),('IT','MOM','Montemarano','Montemarano',''),('IT','MON','Moncalieri','Moncalieri',''),('IT','MOO','Montemurlo','Montemurlo',''),('IT','MOP','Monte Porzio','Monte Porzio',''),('IT','MOQ','Nizza Monferrato','Nizza Monferrato',''),('IT','MOR','Mordano','Mordano',''),('IT','MOS','Morolo','Morolo',''),('IT','MOT','Monsummano Terme','Monsummano Terme',''),('IT','MOU','Monte Urano','Monte Urano',''),('IT','MOV','San Marzano Oliveto','San Marzano Oliveto',''),('IT','MOY','Mosciano Sant\'Angelo','Mosciano Sant\'Angelo',''),('IT','MOZ','Mozzanica','Mozzanica',''),('IT','MPA','Marina di Pisa','Marina di Pisa',''),('IT','MPC','Montepulciano','Montepulciano',''),('IT','MPE','Monteprandone','Monteprandone',''),('IT','MPI','Montecchio Precalcino','Montecchio Precalcino',''),('IT','MPL','Mapello','Mapello',''),('IT','MPO','Montelupo Fiorentino','Montelupo Fiorentino',''),('IT','MPP','Mappano','Mappano',''),('IT','MPR','Campomarino','Campomarino',''),('IT','MPT','Monteveglio','Monteveglio',''),('IT','MQL','Mel','Mel',''),('IT','MRA','Marsala','Marsala',''),('IT','MRB','Manerbio','Manerbio',''),('IT','MRC','Marcianise','Marcianise',''),('IT','MRE','Montale Rangone','Montale Rangone',''),('IT','MRG','Mornago','Mornago',''),('IT','MRL','Marliano','Marliano',''),('IT','MRM','Ciro Marina','Ciro Marina',''),('IT','MRN','Marnello','Marnello',''),('IT','MRO','Montirone','Montirone',''),('IT','MRP','Marina di Campo','Marina di Campo',''),('IT','MRQ','Martorano','Martorano',''),('IT','MRR','Marzabotto','Marzabotto',''),('IT','MRS','Marsciano','Marsciano',''),('IT','MRT','Marostica','Marostica',''),('IT','MRV','Marano Vicentino','Marano Vicentino',''),('IT','MRZ','Marzano','Marzano',''),('IT','MSA','Massa','Massa',''),('IT','MSB','Marina di Pisciotta','Marina di Pisciotta',''),('IT','MSC','Carbonate','Carbonate',''),('IT','MSD','Marina di Grosseto','Marina di Grosseto',''),('IT','MSE','Masate','Masate',''),('IT','MSF','Montespertoli','Montespertoli',''),('IT','MSG','Missaglia','Missaglia',''),('IT','MSI','Montorso Vicentino','Montorso Vicentino',''),('IT','MSL','Massa Lombarda','Massa Lombarda',''),('IT','MSN','Messina','Messina',''),('IT','MSO','Millesimo','Millesimo',''),('IT','MSP','Monte San Pietro','Monte San Pietro',''),('IT','MSR','Mornico al Serio','Mornico al Serio',''),('IT','MSS','Massarosa','Massarosa',''),('IT','MST','Monsagrati','Monsagrati',''),('IT','MSU','Moscufo','Moscufo',''),('IT','MTA','Mortara','Mortara',''),('IT','MTC','Marano Ticino','Marano Ticino',''),('IT','MTD','Monterotondo','Monterotondo',''),('IT','MTE','Monte San Savino','Monte San Savino',''),('IT','MTF','Martina Franca','Martina Franca',''),('IT','MTG','Montegiorgio','Montegiorgio',''),('IT','MTH','Meta','Meta',''),('IT','MTI','Montesilvano','Montesilvano',''),('IT','MTL','Motta di Livenza','Motta di Livenza',''),('IT','MTN','Montignoso','Montignoso',''),('IT','MTO','Molteno','Molteno',''),('IT','MTR','Matera','Matera',''),('IT','MTS','Martinsicuro','Martinsicuro',''),('IT','MTT','Motteggiana','Motteggiana',''),('IT','MTU','Minturno','Minturno',''),('IT','MUF','Montalto Uffugo','Montalto Uffugo',''),('IT','MUG','Mugnano di Napoli','Mugnano di Napoli',''),('IT','MUO','Modugno','Modugno',''),('IT','MUS','Mussolente','Mussolente',''),('IT','MUZ','Mulazzano','Mulazzano',''),('IT','MVA','Molvena','Molvena',''),('IT','MVC','Mason Vicentino','Mason Vicentino',''),('IT','MVE','Monteviale','Monteviale',''),('IT','MVI','Mondovi','Mondovi',''),('IT','MVL','Monvalle','Monvalle',''),('IT','MVO','Montebello Vicentino','Montebello Vicentino',''),('IT','MVT','Megliadino San Vitale','Megliadino San Vitale',''),('IT','MXG','Muggio','Muggio',''),('IT','MXP','Malpensa Apt/Milano','Malpensa Apt/Milano',''),('IT','MZA','Monza','Monza',''),('IT','MZB','Monzambano','Monzambano',''),('IT','MZE','Morazzone','Morazzone',''),('IT','MZM','Mazzo','Mazzo',''),('IT','MZN','Manziana','Manziana',''),('IT','MZO','Melzo','Melzo',''),('IT','MZP','Mozzo','Mozzo',''),('IT','MZR','Mezzolara','Mezzolara',''),('IT','MZT','Mozzate','Mozzate',''),('IT','MZZ','Mozzecane','Mozzecane',''),('IT','NAN','Alpignano','Alpignano',''),('IT','NAP','Napoli','Napoli',''),('IT','NAR','Narni','Narni',''),('IT','NAV','Nave','Nave',''),('IT','NBA','Nocera Umbra','Nocera Umbra',''),('IT','NBO','Nibionno','Nibionno',''),('IT','NCI','Noci','Noci',''),('IT','NCO','Noceto','Noceto',''),('IT','NCT','San Cataldo','San Cataldo',''),('IT','NDB','Nervesa della Battaglia','Nervesa della Battaglia',''),('IT','NDL','Nigoline Bonomelli','Nigoline Bonomelli',''),('IT','NEM','Nembro','Nembro',''),('IT','NER','Nerviano','Nerviano',''),('IT','NFA','Novafeltria','Novafeltria',''),('IT','NGA','Sperlonga','Sperlonga',''),('IT','NGN','Nigoline','Nigoline',''),('IT','NGO','Canneto sull\'Oglio','Canneto sull\'Oglio',''),('IT','NGR','Negrar','Negrar',''),('IT','NIC','Pian di Macina','Pian di Macina',''),('IT','NIE','Neive','Neive',''),('IT','NLG','Novi Ligure','Novi Ligure',''),('IT','NLI','Noli','Noli',''),('IT','NLO','Nichelino','Nichelino',''),('IT','NML','Novate Milanese','Novate Milanese',''),('IT','NNA','Partanna','Partanna',''),('IT','NNE','Cala Gonone','Cala Gonone',''),('IT','NNT','Nanto','Nanto',''),('IT','NOA','Noale','Noale',''),('IT','NOC','Nocera Inferiore','Nocera Inferiore',''),('IT','NOE','Nove','Nove',''),('IT','NOL','Nola','Nola',''),('IT','NOM','Nova Milanese','Nova Milanese',''),('IT','NON','Nonantola','Nonantola',''),('IT','NOR','Nogara','Nogara',''),('IT','NOV','Novellara','Novellara',''),('IT','NRC','Nogarole Rocca','Nogarole Rocca',''),('IT','NRD','Nardo','Nardo',''),('IT','NSC','Niscemi','Niscemi',''),('IT','NSY','Sigonella','Sigonella',''),('IT','NTA','Sant\'Antioco','Sant\'Antioco',''),('IT','NTE','Sestri Levante','Sestri Levante',''),('IT','NTO','Noto','Noto',''),('IT','NTT','Nettuno','Nettuno',''),('IT','NUM','Numana','Numana',''),('IT','NVE','Nuvolento','Nuvolento',''),('IT','NVG','Noviglio','Noviglio',''),('IT','NVL','Nuvolera','Nuvolera',''),('IT','NVM','Novate Mezzola','Novate Mezzola',''),('IT','NVO','Nuova Olonio','Nuova Olonio',''),('IT','NVP','Noventa di Piave','Noventa di Piave',''),('IT','NVR','Novara','Novara',''),('IT','NVT','Novedrate','Novedrate',''),('IT','OAA','Bonagia','Bonagia',''),('IT','OAD','Pozzo d\'Adda','Pozzo d\'Adda',''),('IT','OAS','Orio Al Serio','Orio Al Serio',''),('IT','OBS','Orbassano','Orbassano',''),('IT','OBT','Orbetello','Orbetello',''),('IT','OCI','Occhieppo Inferiore','Occhieppo Inferiore',''),('IT','OCO','Occimiano','Occimiano',''),('IT','OCS','Oggiona con Santo Stefano','Oggiona con Santo Stefano',''),('IT','ODB','Mola di Bari','Mola di Bari',''),('IT','ODG','Mondragone','Mondragone',''),('IT','ODL','Odolo','Odolo',''),('IT','ODZ','Oderzo','Oderzo',''),('IT','OEN','None','None',''),('IT','OEO','Offanengo','Offanengo',''),('IT','OGA','Ostiglia','Ostiglia',''),('IT','OGG','Oggiono','Oggiono',''),('IT','OGI','Oleggio Castello','Oleggio Castello',''),('IT','OGL','Ogliastro Cilento','Ogliastro Cilento',''),('IT','OGN','Ognina','Ognina',''),('IT','OGO','Ornago','Ornago',''),('IT','OHB','Occhiobello','Occhiobello',''),('IT','OLA','Parola','Parola',''),('IT','OLB','Olbia','Olbia',''),('IT','OLC','Olgiate Comasco','Olgiate Comasco',''),('IT','OLE','Oleggio','Oleggio',''),('IT','OLG','Olginate','Olginate',''),('IT','OLM','Olmo al Brembo','Olmo al Brembo',''),('IT','OLN','Olgiate Olona','Olgiate Olona',''),('IT','OLO','Olona','Olona',''),('IT','OLS','Oleis','Oleis',''),('IT','OMG','Omegna','Omegna',''),('IT','OMM','Oste-Montemurlo','Oste-Montemurlo',''),('IT','OMO','Como','Como',''),('IT','ONA','Orani','Orani',''),('IT','ONE','Oneglia','Oneglia',''),('IT','ONG','Montagnana','Montagnana',''),('IT','ONI','Osini','Osini',''),('IT','ONN','Osmannoro','Osmannoro',''),('IT','ONO','Ottana','Ottana',''),('IT','ONR','Onara','Onara',''),('IT','ONT','Monta D\'Alba','Monta D\'Alba',''),('IT','ONV','Conversano','Conversano',''),('IT','OON','Ossona','Ossona',''),('IT','OPD','Ospedaletti','Ospedaletti',''),('IT','OPL','Ospedaletto Lodigiano','Ospedaletto Lodigiano',''),('IT','OPP','Oppeano','Oppeano',''),('IT','OPR','Opera','Opera',''),('IT','ORA','Ora','Ora',''),('IT','ORE','Orte','Orte',''),('IT','ORG','Origgio','Origgio',''),('IT','ORI','Orio Litta (Milano)','Orio Litta (Milano)',''),('IT','ORL','Porticello','Porticello',''),('IT','ORM','Ormelle','Ormelle',''),('IT','ORN','Ortonovo','Ortonovo',''),('IT','ORO','Orero','Orero',''),('IT','ORR','Cornaredo','Cornaredo',''),('IT','ORT','Orta Nova','Orta Nova',''),('IT','ORV','Orvieto','Orvieto',''),('IT','ORZ','Orzinuovi','Orzinuovi',''),('IT','OSE','Coseano','Coseano',''),('IT','OSG','Orsago','Orsago',''),('IT','OSI','Osio Di Sopra','Osio Di Sopra',''),('IT','OSM','Osimo','Osimo',''),('IT','OSN','Osnago','Osnago',''),('IT','OSO','Ospedaletto','Ospedaletto',''),('IT','OSP','Ospitaletto','Ospitaletto',''),('IT','OSR','Occhieppo Superiore','Occhieppo Superiore',''),('IT','OSS','Osio Sotto','Osio Sotto',''),('IT','OST','Osteria Grande','Osteria Grande',''),('IT','OSU','Ostuni','Ostuni',''),('IT','OTA','Prato','Prato',''),('IT','OTE','Montone, Teramo','Montone, Teramo',''),('IT','OTG','Pontoglio','Pontoglio',''),('IT','OTN','Ortona','Ortona',''),('IT','OTO','Otranto','Otranto',''),('IT','OTT','Castellana Grotte','Castellana Grotte',''),('IT','OTV','Ottaviano','Ottaviano',''),('IT','OVD','Ovada','Ovada',''),('IT','OVO','Casalnuovo di Napoli','Casalnuovo di Napoli',''),('IT','OVS','Casola Valsenio','Casola Valsenio',''),('IT','OZA','Correzzana','Correzzana',''),('IT','OZE','Ozzano dell\'Emilia','Ozzano dell\'Emilia',''),('IT','OZI','Pozzillo, Catania','Pozzillo, Catania',''),('IT','PAA','Paruzzaro','Paruzzaro',''),('IT','PAC','Pachino','Pachino',''),('IT','PAD','Paladina','Paladina',''),('IT','PAE','Ponte a Evola','Ponte a Evola',''),('IT','PAG','Campagna','Campagna',''),('IT','PAI','Pagani','Pagani',''),('IT','PAL','Palazzolo dello Stella','Palazzolo dello Stella',''),('IT','PAM','Ponte a Moriano','Ponte a Moriano',''),('IT','PAN','Panarea','Panarea',''),('IT','PAO','Passirano','Passirano',''),('IT','PAP','Paderno Ponchielli','Paderno Ponchielli',''),('IT','PAR','Paratico','Paratico',''),('IT','PAS','Paolisi','Paolisi',''),('IT','PAU','Palau','Palau',''),('IT','PAV','Pavia','Pavia',''),('IT','PAZ','Porto Azzurro','Porto Azzurro',''),('IT','PBA','Santa Palomba','Santa Palomba',''),('IT','PCA','Pescia','Pescia',''),('IT','PCB','Pessano con Bornago','Pessano con Bornago',''),('IT','PCC','Peccioli','Peccioli',''),('IT','PCD','Pieve di Cadore','Pieve di Cadore',''),('IT','PCE','Porto Cervo','Porto Cervo',''),('IT','PCG','Piano di Coreglia','Piano di Coreglia',''),('IT','PCH','Peschici','Peschici',''),('IT','PCI','Pisticci','Pisticci',''),('IT','PCM','Portacomaro','Portacomaro',''),('IT','PCN','Porto Conte','Porto Conte',''),('IT','PCO','Percoto','Percoto',''),('IT','PCR','Policoro','Policoro',''),('IT','PCS','Porto Corsini','Porto Corsini',''),('IT','PCZ','Piacenza','Piacenza',''),('IT','PDA','Padova','Padova',''),('IT','PDC','Pieve di Cento','Pieve di Cento',''),('IT','PDD','Paderno Dugnano','Paderno Dugnano',''),('IT','PDG','Pove del Grappa','Pove del Grappa',''),('IT','PDI','Porto d\'Ischia','Porto d\'Ischia',''),('IT','PDL','Ponte dell\'Olio','Ponte dell\'Olio',''),('IT','PDM','Pradamano','Pradamano',''),('IT','PDN','Paradigna','Paradigna',''),('IT','PDO','Pandino','Pandino',''),('IT','PDP','Prata di Pordenone','Prata di Pordenone',''),('IT','PDS','Porto d\'Ascoli','Porto d\'Ascoli',''),('IT','PDU','Pavia di Udine','Pavia di Udine',''),('IT','PEA','Pavone del Mella','Pavone del Mella',''),('IT','PEC','Paceco','Paceco',''),('IT','PED','Pedaso','Pedaso',''),('IT','PEE','Paese','Paese',''),('IT','PEG','Perugia','Perugia',''),('IT','PEL','Pellaro','Pellaro',''),('IT','PEM','Porto Empedocle','Porto Empedocle',''),('IT','PEN','Pegognaga','Pegognaga',''),('IT','PEO','Pontevico','Pontevico',''),('IT','PER','Perosa Argentina','Perosa Argentina',''),('IT','PES','Pesaro','Pesaro',''),('IT','PET','Pettinengo','Pettinengo',''),('IT','PEV','Peveragno','Peveragno',''),('IT','PFE','Portoferraio','Portoferraio',''),('IT','PFO','Ponte Fornaci','Ponte Fornaci',''),('IT','PFR','Poggiofiorito','Poggiofiorito',''),('IT','PFX','Porto Foxi (Sarroch)','Porto Foxi (Sarroch)',''),('IT','PGA','Porto Garibaldi','Porto Garibaldi',''),('IT','PGD','Poggiridenti','Poggiridenti',''),('IT','PGG','Poggibonsi','Poggibonsi',''),('IT','PGI','Pergine Valdarno','Pergine Valdarno',''),('IT','PGL','Portigliola','Portigliola',''),('IT','PGN','Pagnacco','Pagnacco',''),('IT','PGO','Peregallo','Peregallo',''),('IT','PGQ','Ponte Buggianese','Ponte Buggianese',''),('IT','PGR','Portogruaro','Portogruaro',''),('IT','PGT','Pantigliate','Pantigliate',''),('IT','PGZ','Preganziol','Preganziol',''),('IT','PHS','Ponte Chiasso','Ponte Chiasso',''),('IT','PIA','Pianosa','Pianosa',''),('IT','PIB','Piobesi D\'Alba','Piobesi D\'Alba',''),('IT','PIC','Patrica','Patrica',''),('IT','PID','Piateda','Piateda',''),('IT','PIE','Pietrasanta','Pietrasanta',''),('IT','PIF','Pianezze','Pianezze',''),('IT','PIG','Pianiga','Pianiga',''),('IT','PII','Pignataro Interamna','Pignataro Interamna',''),('IT','PIL','Pinerolo','Pinerolo',''),('IT','PIM','Praia a Mare','Praia a Mare',''),('IT','PIN','Pianella','Pianella',''),('IT','PIO','Piombino','Piombino',''),('IT','PIR','Poirino','Poirino',''),('IT','PIS','Pistoia','Pistoia',''),('IT','PIT','Piantedo','Piantedo',''),('IT','PIV','Piove di Sacco','Piove di Sacco',''),('IT','PIX','San Pietro all\'Olmo','San Pietro all\'Olmo',''),('IT','PIZ','Pizzo','Pizzo',''),('IT','PKF','Prati','Prati',''),('IT','PLA','Pradalunga','Pradalunga',''),('IT','PLB','Policastro Bussentino','Policastro Bussentino',''),('IT','PLC','Palosco','Palosco',''),('IT','PLG','Pontelongo','Pontelongo',''),('IT','PLI','Porto Lignano','Porto Lignano',''),('IT','PLL','Polla','Polla',''),('IT','PLM','Palazzolo Milanese','Palazzolo Milanese',''),('IT','PLN','Palinuro','Palinuro',''),('IT','PLO','Pioltello','Pioltello',''),('IT','PLR','San Paolo d\'Argon','San Paolo d\'Argon',''),('IT','PLS','Polesine','Polesine',''),('IT','PLT','Palestro','Palestro',''),('IT','PLU','Peschiera del Garda','Peschiera del Garda',''),('IT','PLV','Pievebelvicino','Pievebelvicino',''),('IT','PMA','Marghera','Marghera',''),('IT','PMC','Premariacco','Premariacco',''),('IT','PME','Pogliano Milanese','Pogliano Milanese',''),('IT','PMF','Parma','Parma',''),('IT','PMG','Portomaggiore','Portomaggiore',''),('IT','PMI','Pombia','Pombia',''),('IT','PML','Pontremoli','Pontremoli',''),('IT','PMM','Palmi','Palmi',''),('IT','PMN','Primaluna, Lecco','Primaluna, Lecco',''),('IT','PMO','Palermo','Palermo',''),('IT','PMP','Pompei','Pompei',''),('IT','PMS','Pozzuolo Martesana','Pozzuolo Martesana',''),('IT','PMU','Piedimulera','Piedimulera',''),('IT','PMV','Porto Mantovano','Porto Mantovano',''),('IT','PMZ','Porto Maurizio','Porto Maurizio',''),('IT','PNA','Parona','Parona',''),('IT','PNC','Pescantina','Pescantina',''),('IT','PND','Pontedera','Pontedera',''),('IT','PNE','Ponte, Benevento','Ponte, Benevento',''),('IT','PNG','Porto Nogaro','Porto Nogaro',''),('IT','PNI','Pocenia','Pocenia',''),('IT','PNL','Pantelleria','Pantelleria',''),('IT','PNM','Pian Camuno','Pian Camuno',''),('IT','PNN','Perignano','Perignano',''),('IT','PNO','Ponte Nova','Ponte Nova',''),('IT','PNR','Pianoro','Pianoro',''),('IT','PNT','Pontecchio','Pontecchio',''),('IT','PNV','Palmanova','Palmanova',''),('IT','PNZ','Ponza','Ponza',''),('IT','POA','Parona di Valpolicella','Parona di Valpolicella',''),('IT','POC','Porcari','Porcari',''),('IT','POD','Podenzano','Podenzano',''),('IT','POG','Poggio Renatico','Poggio Renatico',''),('IT','POI','Poiano','Poiano',''),('IT','POL','Pollein','Pollein',''),('IT','POM','Pomezia','Pomezia',''),('IT','PON','Pontassieve','Pontassieve',''),('IT','POO','Pontedassio','Pontedassio',''),('IT','POP','Ponte della Priula','Ponte della Priula',''),('IT','POR','Pomigliano D\'Arco','Pomigliano D\'Arco',''),('IT','POS','Positano','Positano',''),('IT','POT','Ponte Taro','Ponte Taro',''),('IT','POV','Povolaro','Povolaro',''),('IT','POZ','Pozzuoli','Pozzuoli',''),('IT','PPA','Piediripa','Piediripa',''),('IT','PPF','Porto Palo','Porto Palo',''),('IT','PPG','Polpenazze del Garda','Polpenazze del Garda',''),('IT','PPL','Portopalo','Portopalo',''),('IT','PPM','San Prospero Parmense','San Prospero Parmense',''),('IT','PPT','Porto Tolle','Porto Tolle',''),('IT','PRA','Pratrivero','Pratrivero',''),('IT','PRB','Pray Biellese','Pray Biellese',''),('IT','PRC','Porcia','Porcia',''),('IT','PRD','Pordenone','Pordenone',''),('IT','PRE','Pressana','Pressana',''),('IT','PRF','Porto Recanati','Porto Recanati',''),('IT','PRG','Parabiago','Parabiago',''),('IT','PRH','Sapri','Sapri',''),('IT','PRI','Petritoli','Petritoli',''),('IT','PRJ','Capri','Capri',''),('IT','PRL','Priolo Gargallo','Priolo Gargallo',''),('IT','PRM','Pregnana Milanese','Pregnana Milanese',''),('IT','PRN','Porrena','Porrena',''),('IT','PRO','Procida','Procida',''),('IT','PRR','Piano di Sorrento','Piano di Sorrento',''),('IT','PRS','Persico','Persico',''),('IT','PRT','Porretta Terme','Porretta Terme',''),('IT','PRV','Priverno','Priverno',''),('IT','PRW','Portovenere','Portovenere',''),('IT','PRZ','Predazzo','Predazzo',''),('IT','PSA','Pisa','Pisa',''),('IT','PSB','Peschiera Borromeo','Peschiera Borromeo',''),('IT','PSC','Pieve Sestina Cesena','Pieve Sestina Cesena',''),('IT','PSE','Pescate','Pescate',''),('IT','PSG','Ponte San Giovanni','Ponte San Giovanni',''),('IT','PSI','Plesio','Plesio',''),('IT','PSM','Ponte San Marco','Ponte San Marco',''),('IT','PSN','Pessione','Pessione',''),('IT','PSO','Palazzolo sull\'Oglio','Palazzolo sull\'Oglio',''),('IT','PSP','Ponte San Pietro','Ponte San Pietro',''),('IT','PSQ','Pessinetto','Pessinetto',''),('IT','PSR','Pescara','Pescara',''),('IT','PSS','Porto Santo Stefano','Porto Santo Stefano',''),('IT','PST','Pastrengo','Pastrengo',''),('IT','PSZ','Portacomaro Stazione','Portacomaro Stazione',''),('IT','PTA','Pontinia','Pontinia',''),('IT','PTB','Pontebba','Pontebba',''),('IT','PTC','Portici','Portici',''),('IT','PTD','Pontedecimo','Pontedecimo',''),('IT','PTE','Paitone','Paitone',''),('IT','PTF','Portofino','Portofino',''),('IT','PTG','Pitigliano','Pitigliano',''),('IT','PTH','Porto Ercole','Porto Ercole',''),('IT','PTI','Patti','Patti',''),('IT','PTL','Capistrello','Capistrello',''),('IT','PTM','Pietramurata','Pietramurata',''),('IT','PTN','Pontenure','Pontenure',''),('IT','PTO','Porto Torres','Porto Torres',''),('IT','PTP','Potenza Picena','Potenza Picena',''),('IT','PTQ','Petriolo','Petriolo',''),('IT','PTR','Paterno','Paterno',''),('IT','PTT','Ponte Tresa','Ponte Tresa',''),('IT','PTV','Piano Tavola','Piano Tavola',''),('IT','PUG','Montecorvino Pugliano','Montecorvino Pugliano',''),('IT','PUI','Pernumia','Pernumia',''),('IT','PUL','Paullo','Paullo',''),('IT','PUO','Pontirolo Nuovo','Pontirolo Nuovo',''),('IT','PUT','Putignano','Putignano',''),('IT','PUZ','Trepuzzi','Trepuzzi',''),('IT','PVA','Prevalle','Prevalle',''),('IT','PVC','Pratovecchio','Pratovecchio',''),('IT','PVD','Pieve di Soligo','Pieve di Soligo',''),('IT','PVE','Portoscuso (Porto Vesme)','Portoscuso (Porto Vesme)',''),('IT','PVG','Povegliano Veronese','Povegliano Veronese',''),('IT','PVI','Poviglio','Poviglio',''),('IT','PVL','Pergine Valsugana','Pergine Valsugana',''),('IT','PVM','Pieve Emanuele','Pieve Emanuele',''),('IT','PVN','Piovene Rocchette','Piovene Rocchette',''),('IT','PVO','Pavullo nel Frignano','Pavullo nel Frignano',''),('IT','PVS','Provaglio d\'Iseo','Provaglio d\'Iseo',''),('IT','PVT','Porto Levante','Porto Levante',''),('IT','PXT','Prato Sesia','Prato Sesia',''),('IT','PXZ','Panzano','Panzano',''),('IT','PZA','Pallanza','Pallanza',''),('IT','PZB','Piazza Brembana','Piazza Brembana',''),('IT','PZD','Paderno d\'Adda','Paderno d\'Adda',''),('IT','PZE','Ponzone','Ponzone',''),('IT','PZF','Pozzolo Formigaro','Pozzolo Formigaro',''),('IT','PZG','Palazzo San Gervasio','Palazzo San Gervasio',''),('IT','PZI','Pozzaglio ed Uniti','Pozzaglio ed Uniti',''),('IT','PZL','Pozzallo','Pozzallo',''),('IT','PZO','Ponzano Magra','Ponzano Magra',''),('IT','PZZ','Pozzolengo','Pozzolengo',''),('IT','QCS','Cosenza','Cosenza',''),('IT','QCZ','Catanzaro','Catanzaro',''),('IT','QGO','Santo Stefano di Magra','Santo Stefano di Magra',''),('IT','QLO','Qualiano','Qualiano',''),('IT','QMM','Marina di Massa','Marina di Massa',''),('IT','QNU','Nuoro','Nuoro',''),('IT','QNZ','Quinzano d\'Oglio','Quinzano d\'Oglio',''),('IT','QOS','Oristano','Oristano',''),('IT','QOY','Quero','Quero',''),('IT','QPO','Potenza','Potenza',''),('IT','QRC','Querceta','Querceta',''),('IT','QSA','Castello d\'Annone','Castello d\'Annone',''),('IT','QSS','Sassari','Sassari',''),('IT','QTD','Quinto di Treviso','Quinto di Treviso',''),('IT','QTO','Quarto','Quarto',''),('IT','QTT','Quattordio','Quattordio',''),('IT','QUA','Quarrata','Quarrata',''),('IT','QUO','Quistello','Quistello',''),('IT','RAC','Racconigi','Racconigi',''),('IT','RAN','Ravenna','Ravenna',''),('IT','RAO','Sora','Sora',''),('IT','RAV','Ravarino','Ravarino',''),('IT','RBA','Rubano','Rubano',''),('IT','RBC','Robecco','Robecco',''),('IT','RBD','Robecchetto con Induno','Robecchetto con Induno',''),('IT','RBO','Retorbido','Retorbido',''),('IT','RBS','Robassomero','Robassomero',''),('IT','RCA','Rende Cosenza','Rende Cosenza',''),('IT','RCB','Ronco Briantino','Ronco Briantino',''),('IT','RCC','Roccasecca','Roccasecca',''),('IT','RCE','Riccione','Riccione',''),('IT','RCL','Roncello','Roncello',''),('IT','RCO','Riccio','Riccio',''),('IT','RDA','Roseto degli Abruzzi','Roseto degli Abruzzi',''),('IT','RDC','Redecesio','Redecesio',''),('IT','RDE','Roncadelle','Roncadelle',''),('IT','RDG','Riva del Garda','Riva del Garda',''),('IT','RDM','Ruvo del Monte','Ruvo del Monte',''),('IT','RDN','Rodano','Rodano',''),('IT','RDO','Rodengo','Rodengo',''),('IT','RDR','Rivarolo del Re','Rivarolo del Re',''),('IT','RDT','Rivalta di Torino','Rivalta di Torino',''),('IT','REC','Recco','Recco',''),('IT','REG','Reggio Calabria','Reggio Calabria',''),('IT','REN','Rogeno','Rogeno',''),('IT','REV','Trevi','Trevi',''),('IT','REZ','Remanzacco','Remanzacco',''),('IT','RFC','Refrontolo','Refrontolo',''),('IT','RFN','Rufina','Rufina',''),('IT','RFO','Rottofreno','Rottofreno',''),('IT','RGA','Ragusa','Ragusa',''),('IT','RGB','Ragogna','Ragogna',''),('IT','RGG','Rodi Garganico','Rodi Garganico',''),('IT','RGL','Revigliasco','Revigliasco',''),('IT','RGN','Rogno','Rogno',''),('IT','RGO','Reggiolo','Reggiolo',''),('IT','RGS','Ricco del Golfo di Spezia','Ricco del Golfo di Spezia',''),('IT','RHO','Rho','Rho',''),('IT','RIA','Riano','Riano',''),('IT','RIB','Rivalta Bormida','Rivalta Bormida',''),('IT','RIC','Radda in Chianti','Radda in Chianti',''),('IT','RIL','Riola','Riola',''),('IT','RIO','Rivoli Veronese','Rivoli Veronese',''),('IT','RIV','Rivalta Scrivia','Rivalta Scrivia',''),('IT','RLL','Rutigliano','Rutigliano',''),('IT','RLS','Rovellasca','Rovellasca',''),('IT','RLT','Rapolano Terme','Rapolano Terme',''),('IT','RMA','Rio Marina','Rio Marina',''),('IT','RMC','Romano Canavese','Romano Canavese',''),('IT','RMG','Riomaggiore','Riomaggiore',''),('IT','RMI','Rimini','Rimini',''),('IT','RMO','Rosignano Marittimo','Rosignano Marittimo',''),('IT','RMS','Romagnano Sesia','Romagnano Sesia',''),('IT','RMT','Romentino','Romentino',''),('IT','RMV','Rivarolo Mantovano','Rivarolo Mantovano',''),('IT','RNA','Strona','Strona',''),('IT','RNE','Reggio nell\'Emilia','Reggio nell\'Emilia',''),('IT','RNI','Carini','Carini',''),('IT','RNO','Ronago','Ronago',''),('IT','RNS','Spotorno','Spotorno',''),('IT','RNT','Recanati','Recanati',''),('IT','ROA','Rodengo Saiano','Rodengo Saiano',''),('IT','ROB','Robecco sul Naviglio','Robecco sul Naviglio',''),('IT','ROC','Roccella Ionica','Roccella Ionica',''),('IT','ROE','Rocca Canavese','Rocca Canavese',''),('IT','ROF','Roncoferraro','Roncoferraro',''),('IT','ROG','Rogoredo, Milan','Rogoredo, Milan',''),('IT','ROL','Romano di Lombardia','Romano di Lombardia',''),('IT','ROM','Roma','Roma',''),('IT','RON','Rondissone','Rondissone',''),('IT','ROO','Robbio','Robbio',''),('IT','ROQ','Rovato','Rovato',''),('IT','ROR','Roreto','Roreto',''),('IT','ROS','Rosa','Rosa',''),('IT','ROT','Roteglia','Roteglia',''),('IT','ROV','Roveleto','Roveleto',''),('IT','ROZ','Romano D\'Ezzelino','Romano D\'Ezzelino',''),('IT','RPB','Ripaberarda','Ripaberarda',''),('IT','RPD','Riese Pio Decimo','Riese Pio Decimo',''),('IT','RPI','Carpi','Carpi',''),('IT','RPL','Ripalta Cremasca','Ripalta Cremasca',''),('IT','RPO','Rapallo','Rapallo',''),('IT','RPT','Riposto','Riposto',''),('IT','RQI','Rocca Pietore','Rocca Pietore',''),('IT','RQS','Rocca San Casciano','Rocca San Casciano',''),('IT','RRA','Roccarainola','Roccarainola',''),('IT','RRC','Serra Ricco','Serra Ricco',''),('IT','RRE','Roreto Chisone','Roreto Chisone',''),('IT','RRO','Sorrento','Sorrento',''),('IT','RRT','Recoaro Terme','Recoaro Terme',''),('IT','RRV','Sferracavallo','Sferracavallo',''),('IT','RSA','Resana','Resana',''),('IT','RSB','Rignano sull\'Arno','Rignano sull\'Arno',''),('IT','RSC','Rescaldina','Rescaldina',''),('IT','RSE','Bagno Roselle','Bagno Roselle',''),('IT','RSG','Rocca San Giovanni','Rocca San Giovanni',''),('IT','RSI','Rastignano','Rastignano',''),('IT','RSL','Rio Saliceto','Rio Saliceto',''),('IT','RSM','Monterosso al Mare','Monterosso al Mare',''),('IT','RSN','Rossano','Rossano',''),('IT','RSO','Borso del Grappa','Borso del Grappa',''),('IT','RSS','Russi','Russi',''),('IT','RST','Rosate','Rosate',''),('IT','RTA','Marta','Marta',''),('IT','RTI','Rieti','Rieti',''),('IT','RTO','Rovereto','Rovereto',''),('IT','RTS','Riva Trigoso','Riva Trigoso',''),('IT','RTT','Marotta','Marotta',''),('IT','RUB','Rubiera','Rubiera',''),('IT','RUD','Rudiano','Rudiano',''),('IT','RVB','Codogne','Codogne',''),('IT','RVC','Roe Volcanico','Roe Volcanico',''),('IT','RVG','Rovagnate','Rovagnate',''),('IT','RVI','Ravina','Ravina',''),('IT','RVL','Rivoli','Rivoli',''),('IT','RVO','Rovigo','Rovigo',''),('IT','RVR','Revere','Revere',''),('IT','RVV','Rivarolo Canavese','Rivarolo Canavese',''),('IT','RZA','Rivanazzano','Rivanazzano',''),('IT','RZO','Rozzano','Rozzano',''),('IT','SAA','San Giorgio di Mantova','San Giorgio di Mantova',''),('IT','SAB','Sabbioneta','Sabbioneta',''),('IT','SAD','San Secondo di Pinerolo','San Secondo di Pinerolo',''),('IT','SAE','Sant\'Antonio Abate','Sant\'Antonio Abate',''),('IT','SAF','Sant\'Angelo le Fratte','Sant\'Angelo le Fratte',''),('IT','SAG','Sant\'Agata di Militello','Sant\'Agata di Militello',''),('IT','SAI','Sant\'Agata Irpina','Sant\'Agata Irpina',''),('IT','SAL','Salerno','Salerno',''),('IT','SAM','Santa Margherita d\'Adige','Santa Margherita d\'Adige',''),('IT','SAN','Sandigliano','Sandigliano',''),('IT','SAO','Sant\'Agostino','Sant\'Agostino',''),('IT','SAP','San Pietro di Legnago','San Pietro di Legnago',''),('IT','SAR','San Rocco','San Rocco',''),('IT','SAS','Sant\'Albano Stura','Sant\'Albano Stura',''),('IT','SAT','Sant\' Antioco','Sant\' Antioco',''),('IT','SAU','Sessa Aurunca','Sessa Aurunca',''),('IT','SAV','Savignone','Savignone',''),('IT','SAZ','Sarzana','Sarzana',''),('IT','SBA','Solbiate Arno','Solbiate Arno',''),('IT','SBC','Sambuca di Pesa','Sambuca di Pesa',''),('IT','SBE','Sala Bolognese','Sala Bolognese',''),('IT','SBF','San Bonifacio','San Bonifacio',''),('IT','SBG','Spilimbergo','Spilimbergo',''),('IT','SBH','Sabbio Chiese','Sabbio Chiese',''),('IT','SBI','Stabbia','Stabbia',''),('IT','SBM','Solara di Bomporto','Solara di Bomporto',''),('IT','SBO','Solbiate Olona','Solbiate Olona',''),('IT','SBR','Sala Baganza','Sala Baganza',''),('IT','SBS','San Benedetto Val di Sambro','San Benedetto Val di Sambro',''),('IT','SBT','Solbiate','Solbiate',''),('IT','SBU','Santa Giustina Bellunese','Santa Giustina Bellunese',''),('IT','SBV','San Bernardino Verbano','San Bernardino Verbano',''),('IT','SCA','Scandiano','Scandiano',''),('IT','SCC','Scandicci','Scandicci',''),('IT','SCD','San Candido','San Candido',''),('IT','SCE','San Flice','San Flice',''),('IT','SCF','Scafati','Scafati',''),('IT','SCG','Sommacampagna','Sommacampagna',''),('IT','SCH','Schio','Schio',''),('IT','SCI','Scicli','Scicli',''),('IT','SCK','Sciacca','Sciacca',''),('IT','SCL','Sacile','Sacile',''),('IT','SCM','San Clemente','San Clemente',''),('IT','SCN','San Cipriano Po','San Cipriano Po',''),('IT','SCO','Scoglitti','Scoglitti',''),('IT','SCP','San Casciano in Val di Pesa','San Casciano in Val di Pesa',''),('IT','SCQ','Saccolongo','Saccolongo',''),('IT','SCR','Santa Croce','Santa Croce',''),('IT','SCS','San Cesario sul Panaro','San Cesario sul Panaro',''),('IT','SCT','Saint Christophe','Saint Christophe',''),('IT','SCU','Scarzara','Scarzara',''),('IT','SCZ','Scorze','Scorze',''),('IT','SDA','Spino d\'Adda','Spino d\'Adda',''),('IT','SDB','San Benedetto del Tronto','San Benedetto del Tronto',''),('IT','SDC','Sega di Cavaion','Sega di Cavaion',''),('IT','SDE','San Donato Milanese','San Donato Milanese',''),('IT','SDF','San Daniele del Friuli','San Daniele del Friuli',''),('IT','SDG','Sandrigo','Sandrigo',''),('IT','SDI','Saline di Volterra','Saline di Volterra',''),('IT','SDL','Soiano Del Lago','Soiano Del Lago',''),('IT','SDM','San Damiano d\'Asti','San Damiano d\'Asti',''),('IT','SDN','San Defendente','San Defendente',''),('IT','SDO','Sedico','Sedico',''),('IT','SDP','San Dona di Piave','San Dona di Piave',''),('IT','SDR','Sarmeola di Rubano','Sarmeola di Rubano',''),('IT','SDT','San Donato','San Donato',''),('IT','SDV','Seghe di Velo','Seghe di Velo',''),('IT','SEA','Silea','Silea',''),('IT','SEC','Settimello-Calenzano','Settimello-Calenzano',''),('IT','SED','Sedriano','Sedriano',''),('IT','SEE','Sesto Calende','Sesto Calende',''),('IT','SEF','Sant\'Agata Feltria','Sant\'Agata Feltria',''),('IT','SEG','Senigallia','Senigallia',''),('IT','SEI','Serravalle Pistoiese','Serravalle Pistoiese',''),('IT','SEN','Senago','Senago',''),('IT','SEO','Sepino','Sepino',''),('IT','SEP','Settimo di Pescantina','Settimo di Pescantina',''),('IT','SER','Seriate','Seriate',''),('IT','SET','Settecamini','Settecamini',''),('IT','SEV','Seveso','Seveso',''),('IT','SEZ','Sezze','Sezze',''),('IT','SFC','Santo Stefano Ticino','Santo Stefano Ticino',''),('IT','SFE','San Felice Circeo','San Felice Circeo',''),('IT','SFL','Santa Flavia','Santa Flavia',''),('IT','SFM','Santa Foca di Melendugno','Santa Foca di Melendugno',''),('IT','SFO','Sassoferrato','Sassoferrato',''),('IT','SFP','San Felice sul Panaro','San Felice sul Panaro',''),('IT','SFR','San Fior','San Fior',''),('IT','SGA','San Giovanni Reatino','San Giovanni Reatino',''),('IT','SGB','San Giovanni Bianco','San Giovanni Bianco',''),('IT','SGD','San Giustino Valdarno','San Giustino Valdarno',''),('IT','SGE','Segrate','Segrate',''),('IT','SGF','Monferrato','Monferrato',''),('IT','SGG','San Giorgio di Nogaro','San Giorgio di Nogaro',''),('IT','SGI','San Giuliano Milanese','San Giuliano Milanese',''),('IT','SGL','San Giovanni Lupatoto','San Giovanni Lupatoto',''),('IT','SGM','San Giovanni in Marignano','San Giovanni in Marignano',''),('IT','SGN','San Giovanni al Natisone','San Giovanni al Natisone',''),('IT','SGO','Seregno','Seregno',''),('IT','SGP','San Giorgio di Piano','San Giorgio di Piano',''),('IT','SGR','Salgareda','Salgareda',''),('IT','SGS','San Genesio','San Genesio',''),('IT','SGT','San Giuliano Terme','San Giuliano Terme',''),('IT','SGU','San Guiseppe','San Guiseppe',''),('IT','SGV','San Giovanni Valdarno','San Giovanni Valdarno',''),('IT','SHA','Santhia','Santhia',''),('IT','SHI','Schieti','Schieti',''),('IT','SIA','Siniscola','Siniscola',''),('IT','SIB','San Giorgio in Bosco','San Giorgio in Bosco',''),('IT','SID','Siderno Marina','Siderno Marina',''),('IT','SIE','Sesto Imolese','Sesto Imolese',''),('IT','SIG','Porto San Giorgio','Porto San Giorgio',''),('IT','SII','Sieci','Sieci',''),('IT','SIL','San Giorgio a Liri','San Giorgio a Liri',''),('IT','SIN','Casina','Casina',''),('IT','SIO','Siano','Siano',''),('IT','SIR','Siracusa','Siracusa',''),('IT','SIS','Sissa','Sissa',''),('IT','SIT','Ostia','Ostia',''),('IT','SIV','Sommariva del Bosco','Sommariva del Bosco',''),('IT','SLA','Santa Marina Salina','Santa Marina Salina',''),('IT','SLC','Saline, Reggio Calabria','Saline, Reggio Calabria',''),('IT','SLE','Sellero','Sellero',''),('IT','SLG','Solignano','Solignano',''),('IT','SLH','Scalenghe','Scalenghe',''),('IT','SLI','Sulbiate','Sulbiate',''),('IT','SLL','Scilla','Scilla',''),('IT','SLM','Salerano sul Lambro','Salerano sul Lambro',''),('IT','SLN','Salorno','Salorno',''),('IT','SLO','Salo','Salo',''),('IT','SLP','Sulmona','Sulmona',''),('IT','SLR','Solero','Solero',''),('IT','SLS','San Lazzaro di Savena','San Lazzaro di Savena',''),('IT','SLT','Spoleto','Spoleto',''),('IT','SLU','Salussola','Salussola',''),('IT','SLV','Silvi Marina','Silvi Marina',''),('IT','SLZ','Salizzole','Salizzole',''),('IT','SMA','Santa Marinella','Santa Marinella',''),('IT','SMB','Somma Lombardo','Somma Lombardo',''),('IT','SMC','Santa Maria Capua Vetere','Santa Maria Capua Vetere',''),('IT','SMD','San Martino dall\'Argine','San Martino dall\'Argine',''),('IT','SME','Santa Maria degli Angeli','Santa Maria degli Angeli',''),('IT','SMF','San Martino Alfieri','San Martino Alfieri',''),('IT','SMG','San Michele di Ganzaria','San Michele di Ganzaria',''),('IT','SMH','San Marco dei Cavoti','San Marco dei Cavoti',''),('IT','SMI','San Miniato','San Miniato',''),('IT','SMK','Santa Maria di Castellabate','Santa Maria di Castellabate',''),('IT','SML','Santa Margherita Ligure','Santa Margherita Ligure',''),('IT','SMM','San Michele Mondovi','San Michele Mondovi',''),('IT','SMN','Santa Maria Nuova','Santa Maria Nuova',''),('IT','SMO','San Mauro Torinese','San Mauro Torinese',''),('IT','SMP','San Michele Prazzo','San Michele Prazzo',''),('IT','SMR','San Marco Argentano','San Marco Argentano',''),('IT','SMS','Santa Maria di Sala','Santa Maria di Sala',''),('IT','SMT','Spigno Monferrato','Spigno Monferrato',''),('IT','SMU','San Martino di Lupari','San Martino di Lupari',''),('IT','SMV','San Maurizio Canavese','San Maurizio Canavese',''),('IT','SMX','San Michele Extra','San Michele Extra',''),('IT','SMZ','Santa Maria Codifiume','Santa Maria Codifiume',''),('IT','SNA','Siena','Siena',''),('IT','SNC','San Cesario di Lecce','San Cesario di Lecce',''),('IT','SND','Sondrio','Sondrio',''),('IT','SNE','Santena','Santena',''),('IT','SNF','San Nicolo Ferrarese','San Nicolo Ferrarese',''),('IT','SNG','San Giorgio del Sannio','San Giorgio del Sannio',''),('IT','SNH','Sant\'Antonino','Sant\'Antonino',''),('IT','SNI','San Nicola Manfredi','San Nicola Manfredi',''),('IT','SNL','Sinalunga','Sinalunga',''),('IT','SNM','San Michele, Alessandria','San Michele, Alessandria',''),('IT','SNO','Seano','Seano',''),('IT','SNP','San Pietro','San Pietro',''),('IT','SNR','Terrasini','Terrasini',''),('IT','SNS','San Nicola la Strada','San Nicola la Strada',''),('IT','SNT','San Nicolo a Trebbia','San Nicolo a Trebbia',''),('IT','SNU','Sanguinetto','Sanguinetto',''),('IT','SNV','San Vendemiano','San Vendemiano',''),('IT','SNW','Songavazzo','Songavazzo',''),('IT','SNY','Sona','Sona',''),('IT','SNZ','Spinazzola','Spinazzola',''),('IT','SOA','Sorga','Sorga',''),('IT','SOB','Sant\'Omobono Imagna','Sant\'Omobono Imagna',''),('IT','SOC','Soriano nel Cimino','Soriano nel Cimino',''),('IT','SOD','San Martino della Battaglia','San Martino della Battaglia',''),('IT','SOE','Soleto','Soleto',''),('IT','SOG','Somaglia','Somaglia',''),('IT','SOH','Sant\'Angelo Lodigiano','Sant\'Angelo Lodigiano',''),('IT','SOI','Solesino','Solesino',''),('IT','SOL','Solofra','Solofra',''),('IT','SOM','San Pietro Mosezzo','San Pietro Mosezzo',''),('IT','SON','Soncino','Soncino',''),('IT','SOO','Soverato','Soverato',''),('IT','SOP','Osoppo','Osoppo',''),('IT','SOR','Sorbolo','Sorbolo',''),('IT','SOS','Sossano','Sossano',''),('IT','SOT','Cenate Sotto','Cenate Sotto',''),('IT','SOV','Soave','Soave',''),('IT','SOX','Soragna','Soragna',''),('IT','SOZ','Solza','Solza',''),('IT','SPA','Santa Panagia','Santa Panagia',''),('IT','SPB','San Piero in Bagno','San Piero in Bagno',''),('IT','SPC','San Pancrazio','San Pancrazio',''),('IT','SPD','San Polo di Torrile','San Polo di Torrile',''),('IT','SPE','La Spezia','La Spezia',''),('IT','SPF','San Polo d\'Enza in Caviano','San Polo d\'Enza in Caviano',''),('IT','SPI','Spilamberto','Spilamberto',''),('IT','SPL','Spello','Spello',''),('IT','SPM','San Pietro Mussolini','San Pietro Mussolini',''),('IT','SPN','Spinetta','Spinetta',''),('IT','SPO','Sospiro','Sospiro',''),('IT','SPP','San Polo Di Podenzano','San Polo Di Podenzano',''),('IT','SPQ','San Prospero','San Prospero',''),('IT','SPR','Spoltore','Spoltore',''),('IT','SPS','San Pietro in Casale','San Pietro in Casale',''),('IT','SPT','San Pellegrino Terme','San Pellegrino Terme',''),('IT','SPU','San Paolo Solbrito','San Paolo Solbrito',''),('IT','SPV','San Pietro Viminario','San Pietro Viminario',''),('IT','SPX','San Paolo','San Paolo',''),('IT','SPZ','Spezzano Albanese','Spezzano Albanese',''),('IT','SQI','Soci','Soci',''),('IT','SQN','San Quirino','San Quirino',''),('IT','SQO','Santorso','Santorso',''),('IT','SQR','Sant\'Arcangelo','Sant\'Arcangelo',''),('IT','SQZ','Squinzano','Squinzano',''),('IT','SRA','San Rocco Castagnaretta','San Rocco Castagnaretta',''),('IT','SRC','Santeramo in Colle','Santeramo in Colle',''),('IT','SRD','Sordevolo','Sordevolo',''),('IT','SRE','San Remo','San Remo',''),('IT','SRG','Sarego','Sarego',''),('IT','SRH','Scario','Scario',''),('IT','SRI','Sarnico','Sarnico',''),('IT','SRL','Scarlino','Scarlino',''),('IT','SRM','San Martino in Rio','San Martino in Rio',''),('IT','SRN','Saronno','Saronno',''),('IT','SRO','Sarno','Sarno',''),('IT','SRP','San Rocco di Piegara','San Rocco di Piegara',''),('IT','SRR','Serralunga D\'alba','Serralunga D\'alba',''),('IT','SRV','Serravalle Scrivia','Serravalle Scrivia',''),('IT','SRZ','Strozza','Strozza',''),('IT','SSA','San Salvo','San Salvo',''),('IT','SSB','Santo Stefano Belbo','Santo Stefano Belbo',''),('IT','SSC','Sansepolcro','Sansepolcro',''),('IT','SSD','San Martino in Strada','San Martino in Strada',''),('IT','SSE','San Giorgio su Legnano','San Giorgio su Legnano',''),('IT','SSF','Santo Stefano al Mare','Santo Stefano al Mare',''),('IT','SSG','Sesto San Giovanni','Sesto San Giovanni',''),('IT','SSI','Sisini','Sisini',''),('IT','SSL','Sassello','Sassello',''),('IT','SSM','Sasso Marconi','Sasso Marconi',''),('IT','SSO','San Sisto','San Sisto',''),('IT','SSP','Savignano sul Panaro','Savignano sul Panaro',''),('IT','SSR','Savignano sul Rubicone','Savignano sul Rubicone',''),('IT','SSS','Sesso','Sesso',''),('IT','SSU','Sassuolo','Sassuolo',''),('IT','SSZ','Massanzago','Massanzago',''),('IT','STA','Sant\'Angelo a Scala','Sant\'Angelo a Scala',''),('IT','STB','Maso Stabbio','Maso Stabbio',''),('IT','STC','Sant\'Eraclio','Sant\'Eraclio',''),('IT','STE','Santa Teresa di Gallura','Santa Teresa di Gallura',''),('IT','STF','Sesto Fiorentino','Sesto Fiorentino',''),('IT','STG','Stagno','Stagno',''),('IT','STI','Settimo Milanese','Settimo Milanese',''),('IT','STL','Saletto, Bologna','Saletto, Bologna',''),('IT','STM','Settimo','Settimo',''),('IT','STN','Sant\'Arcangelo di Romagna','Sant\'Arcangelo di Romagna',''),('IT','STO','Solto Collina','Solto Collina',''),('IT','STP','Stenico','Stenico',''),('IT','STR','Stromboli','Stromboli',''),('IT','STS','Stresa','Stresa',''),('IT','STT','Settimo Torinese','Settimo Torinese',''),('IT','STZ','Stezzano','Stezzano',''),('IT','SUF','Lamezia-Terme','Lamezia-Terme',''),('IT','SUI','Suisio','Suisio',''),('IT','SUL','Sesto Ulteriano','Sesto Ulteriano',''),('IT','SUP','Maserada sul Piave','Maserada sul Piave',''),('IT','SUR','Sumirago','Sumirago',''),('IT','SUS','Susegana','Susegana',''),('IT','SVA','Serravalle','Serravalle',''),('IT','SVB','Sovico','Sovico',''),('IT','SVC','San Vito lo Capo','San Vito lo Capo',''),('IT','SVD','Santa Vittoria d\'Alba','Santa Vittoria d\'Alba',''),('IT','SVE','Stallavena','Stallavena',''),('IT','SVI','Strevi','Strevi',''),('IT','SVL','San Vito di Leguzzano','San Vito di Leguzzano',''),('IT','SVN','Savona','Savona',''),('IT','SVO','San Severo','San Severo',''),('IT','SVR','San Valentino Torio','San Valentino Torio',''),('IT','SVS','Santa Maria della Versa','Santa Maria della Versa',''),('IT','SVT','San Vito al Tagliamento','San Vito al Tagliamento',''),('IT','SVV','Somma Vesuviana','Somma Vesuviana',''),('IT','SVX','San Vito','San Vito',''),('IT','SVZ','Seravezza','Seravezza',''),('IT','SXG','San Giorgio','San Giorgio',''),('IT','SXM','San Martino sulla Marruccina','San Martino sulla Marruccina',''),('IT','SZA','Suzzara','Suzzara',''),('IT','SZJ','Scanzano Jonico','Scanzano Jonico',''),('IT','SZN','San Zeno naviglio','San Zeno naviglio',''),('IT','SZO','Salzano','Salzano',''),('IT','SZP','San Maurizio d\'Opaglio','San Maurizio d\'Opaglio',''),('IT','SZT','Scanzorosciate','Scanzorosciate',''),('IT','SZZ','Selvazzano Dentro','Selvazzano Dentro',''),('IT','TAA','Cetara','Cetara',''),('IT','TAL','Talamone','Talamone',''),('IT','TAN','Trana','Trana',''),('IT','TAO','Taormina','Taormina',''),('IT','TAR','Taranto','Taranto',''),('IT','TAT','Torrevecchia Teatina','Torrevecchia Teatina',''),('IT','TBA','Tribiano','Tribiano',''),('IT','TBE','Trebaseleghe','Trebaseleghe',''),('IT','TBO','Torbiato','Torbiato',''),('IT','TCC','Trebisacce','Trebisacce',''),('IT','TCM','Tricesimo','Tricesimo',''),('IT','TCO','Corciano','Corciano',''),('IT','TCS','Torre Cesarea','Torre Cesarea',''),('IT','TCT','Tarcento','Tarcento',''),('IT','TCU','Torrecuso','Torrecuso',''),('IT','TCZ','Truccazzano','Truccazzano',''),('IT','TDG','Torre del Greco','Torre del Greco',''),('IT','TDI','Todi','Todi',''),('IT','TDO','Terno d\'Isola','Terno d\'Isola',''),('IT','TDQ','Torri di Quartesolo','Torri di Quartesolo',''),('IT','TDS','Torino di Sangro','Torino di Sangro',''),('IT','TDV','Tombelle','Tombelle',''),('IT','TDZ','Toscanella Di Dozza','Toscanella Di Dozza',''),('IT','TEA','Maratea','Maratea',''),('IT','TEB','Terranuova Bracciolini','Terranuova Bracciolini',''),('IT','TEF','Santo Stefano di Camastra','Santo Stefano di Camastra',''),('IT','TEG','Tregnago','Tregnago',''),('IT','TEL','Telgate','Telgate',''),('IT','TEO','Teramo','Teramo',''),('IT','TER','Terni','Terni',''),('IT','TES','Tessera','Tessera',''),('IT','TEV','Tavernelle Vicentina-Altavilla Vicentina','Tavernelle Vicentina-Altavilla Vicentina',''),('IT','TFR','Trofarello','Trofarello',''),('IT','TGA','Taggia','Taggia',''),('IT','TGC','Tavagnacco','Tavagnacco',''),('IT','TGI','Trigolo','Trigolo',''),('IT','TGL','Travagliato','Travagliato',''),('IT','TGN','Trevignano','Trevignano',''),('IT','TGO','Turbigo','Turbigo',''),('IT','TGR','Torregrande','Torregrande',''),('IT','TGV','Torre Gaveta','Torre Gaveta',''),('IT','THA','Trichiana','Trichiana',''),('IT','THE','Thiene','Thiene',''),('IT','TIA','Treia','Treia',''),('IT','TIN','Castiglion Fiorentino','Castiglion Fiorentino',''),('IT','TIO','Postioma di Paese','Postioma di Paese',''),('IT','TIT','Tito','Tito',''),('IT','TIV','Tivoli','Tivoli',''),('IT','TLA','Settala','Settala',''),('IT','TMA','Talamona','Talamona',''),('IT','TMG','Costa Masnaga','Costa Masnaga',''),('IT','TMI','Termoli','Termoli',''),('IT','TMT','Tremiti','Tremiti',''),('IT','TNA','Terontola','Terontola',''),('IT','TNI','Trani','Trani',''),('IT','TNO','Tirano','Tirano',''),('IT','TNT','Ternate','Ternate',''),('IT','TOA','Torre Annunziata','Torre Annunziata',''),('IT','TOI','Frossasco','Frossasco',''),('IT','TOM','Tombolo','Tombolo',''),('IT','TON','Torriana','Torriana',''),('IT','TOR','Tornaco','Tornaco',''),('IT','TOS','Toscolano','Toscolano',''),('IT','TPS','Trapani','Trapani',''),('IT','TRA','Turate','Turate',''),('IT','TRB','Torbole','Torbole',''),('IT','TRC','Terracina','Terracina',''),('IT','TRD','Tradate','Tradate',''),('IT','TRE','Trecate','Trecate',''),('IT','TRF','Treiso','Treiso',''),('IT','TRG','Treglio','Treglio',''),('IT','TRH','Torre Faro','Torre Faro',''),('IT','TRI','Termini Imerese','Termini Imerese',''),('IT','TRL','Trambileno','Trambileno',''),('IT','TRN','Torino','Torino',''),('IT','TRO','Trissino','Trissino',''),('IT','TRP','Tropea','Tropea',''),('IT','TRQ','Tarquinia','Tarquinia',''),('IT','TRR','Terruggia','Terruggia',''),('IT','TRS','Trieste','Trieste',''),('IT','TRT','Trento','Trento',''),('IT','TRU','Torre San Giovanni','Torre San Giovanni',''),('IT','TRV','Treviso','Treviso',''),('IT','TRZ','Trezzo sull\'Adda','Trezzo sull\'Adda',''),('IT','TSB','Tezze sul Brenta','Tezze sul Brenta',''),('IT','TSE','Tricase','Tricase',''),('IT','TSG','Torre San Giorgio','Torre San Giorgio',''),('IT','TSO','Tesero','Tesero',''),('IT','TST','Trestina','Trestina',''),('IT','TTA','Tortona','Tortona',''),('IT','TTB','Tortoli','Tortoli',''),('IT','TTF','Tirrenia','Tirrenia',''),('IT','TTL','Tortoreto','Tortoreto',''),('IT','TTN','Stintino','Stintino',''),('IT','TTP','Tor Tre Ponti','Tor Tre Ponti',''),('IT','TUR','Campo Tures (Sand in Taufers)','Campo Tures (Sand in Taufers)',''),('IT','TVA','Tovo di Sant\'Agata','Tovo di Sant\'Agata',''),('IT','TVC','Torviscosa','Torviscosa',''),('IT','TVG','Treviglio','Treviglio',''),('IT','TVI','Torrebelvicino','Torrebelvicino',''),('IT','TVL','Treviolo','Treviolo',''),('IT','TVN','Tavernelle','Tavernelle',''),('IT','TVO','Travesio','Travesio',''),('IT','TVR','Tavernerio','Tavernerio',''),('IT','TXN','Taino','Taino',''),('IT','TXO','Torgiano','Torgiano',''),('IT','TZO','Tarzo','Tarzo',''),('IT','TZR','Trezzano Rosa','Trezzano Rosa',''),('IT','TZV','Trezzano sul Naviglio','Trezzano sul Naviglio',''),('IT','UBD','Uboldo','Uboldo',''),('IT','UBE','Ubersetto','Ubersetto',''),('IT','UCG','Castel Guelfo di Bologna','Castel Guelfo di Bologna',''),('IT','UDN','Udine','Udine',''),('IT','UGG','Muggia','Muggia',''),('IT','UID','Guidonia','Guidonia',''),('IT','UIS','Visano','Visano',''),('IT','URB','Urbino','Urbino',''),('IT','URC','Scauri Alto','Scauri Alto',''),('IT','URG','Urgnano','Urgnano',''),('IT','URI','Scauri','Scauri',''),('IT','URT','Curtatone','Curtatone',''),('IT','USI','Chiusi','Chiusi',''),('IT','UST','Ustica','Ustica',''),('IT','VAA','Valfenera','Valfenera',''),('IT','VAC','Castenaso','Castenaso',''),('IT','VAD','Vado/Bologna','Vado/Bologna',''),('IT','VAE','Vallese','Vallese',''),('IT','VAI','Vaiano Cremasco','Vaiano Cremasco',''),('IT','VAN','Vigano','Vigano',''),('IT','VAO','Varedo','Varedo',''),('IT','VAP','Vaprio D\'Agogna','Vaprio D\'Agogna',''),('IT','VAR','Varese','Varese',''),('IT','VBA','Vignole Borbera','Vignole Borbera',''),('IT','VBH','Varano Borghi','Varano Borghi',''),('IT','VBM','Valbrembo','Valbrembo',''),('IT','VBR','Villa Bartolomea','Villa Bartolomea',''),('IT','VBS','Villarbasse','Villarbasse',''),('IT','VCA','Villanova Camposanpiero','Villanova Camposanpiero',''),('IT','VCD','Villacidro','Villacidro',''),('IT','VCE','Venezia','Venezia',''),('IT','VCI','Vinci','Vinci',''),('IT','VCO','Vico','Vico',''),('IT','VCR','Vercurago','Vercurago',''),('IT','VCS','Villanova','Villanova',''),('IT','VDA','Vada','Vada',''),('IT','VDB','Vedano Olona','Vedano Olona',''),('IT','VDC','Vighizzolo Di Cantu','Vighizzolo Di Cantu',''),('IT','VDD','Villa d\'Adda','Villa d\'Adda',''),('IT','VDE','Valli del Pasubio','Valli del Pasubio',''),('IT','VDI','Villanova D\'Asti','Villanova D\'Asti',''),('IT','VDL','Vado Ligure','Vado Ligure',''),('IT','VDN','Viadana','Viadana',''),('IT','VDO','Vado/Lucca','Vado/Lucca',''),('IT','VDP','Vidor','Vidor',''),('IT','VDR','Verderio','Verderio',''),('IT','VDS','Vandoies','Vandoies',''),('IT','VDT','Valdottavo','Valdottavo',''),('IT','VDU','Vallo della Lucania','Vallo della Lucania',''),('IT','VDV','Villafranca di Verona','Villafranca di Verona',''),('IT','VDZ','Vigodarzere','Vigodarzere',''),('IT','VEA','Verbania','Verbania',''),('IT','VED','Velo D\'astico','Velo D\'astico',''),('IT','VEG','Venegono','Venegono',''),('IT','VEI','Vaie','Vaie',''),('IT','VEL','Vedelago','Vedelago',''),('IT','VEM','Velturno/Feldthurns','Velturno/Feldthurns',''),('IT','VEN','Ventimiglia','Ventimiglia',''),('IT','VEO','Verrone','Verrone',''),('IT','VEP','Vitorchiano','Vitorchiano',''),('IT','VER','Verolanuova','Verolanuova',''),('IT','VEV','Vittuone','Vittuone',''),('IT','VEZ','Vezza D\'Alba','Vezza D\'Alba',''),('IT','VFA','Villafalletto','Villafalletto',''),('IT','VFO','Villafontana','Villafontana',''),('IT','VGA','Valduggia','Valduggia',''),('IT','VGE','Viagrande','Viagrande',''),('IT','VGH','Voghera','Voghera',''),('IT','VGI','Veggiano','Veggiano',''),('IT','VGL','Vagliagli','Vagliagli',''),('IT','VGM','Vigarano Mainarda','Vigarano Mainarda',''),('IT','VGN','Vignale Monferrato','Vignale Monferrato',''),('IT','VGO','Valdagno','Valdagno',''),('IT','VGR','Villa Ganzerla','Villa Ganzerla',''),('IT','VGS','Venegono Superiore','Venegono Superiore',''),('IT','VGU','Vidigulfo','Vidigulfo',''),('IT','VGV','Vigevano','Vigevano',''),('IT','VGZ','Vigolzone','Vigolzone',''),('IT','VIA','Viareggio','Viareggio',''),('IT','VIC','Vicenza','Vicenza',''),('IT','VID','Villanova D\'Albenga','Villanova D\'Albenga',''),('IT','VIE','Vieste','Vieste',''),('IT','VIG','Vigliano','Vigliano',''),('IT','VIL','Villa d\'Ogna','Villa d\'Ogna',''),('IT','VIM','Vimercate','Vimercate',''),('IT','VIN','Vignola','Vignola',''),('IT','VIO','Veduggio con Colzano','Veduggio con Colzano',''),('IT','VIP','Virle Piemonte','Virle Piemonte',''),('IT','VIR','Villa Raspa','Villa Raspa',''),('IT','VIS','Vigasio','Vigasio',''),('IT','VIT','Viterbo','Viterbo',''),('IT','VIZ','Vigonza','Vigonza',''),('IT','VLA','Volla','Volla',''),('IT','VLB','Villalba','Villalba',''),('IT','VLC','Villa Cortese','Villa Cortese',''),('IT','VLD','Villa di Serio','Villa di Serio',''),('IT','VLE','Valdengo','Valdengo',''),('IT','VLG','Volargne','Volargne',''),('IT','VLI','Verdellino','Verdellino',''),('IT','VLL','Villesse','Villesse',''),('IT','VLM','Valmadrera','Valmadrera',''),('IT','VLN','Volano','Volano',''),('IT','VLO','Vitulazio','Vitulazio',''),('IT','VLP','Villastanza di Parabiago','Villastanza di Parabiago',''),('IT','VLR','Villaricca','Villaricca',''),('IT','VLS','Villadossola','Villadossola',''),('IT','VLT','Voltana','Voltana',''),('IT','VLU','Vicolungo','Vicolungo',''),('IT','VMA','Volta Mantovana','Volta Mantovana',''),('IT','VMD','Vimodrone','Vimodrone',''),('IT','VMF','Villanova Monferrato','Villanova Monferrato',''),('IT','VMO','Villanova Mondovi','Villanova Mondovi',''),('IT','VNA','Villanova d\'Ardenghi','Villanova d\'Ardenghi',''),('IT','VNE','Vallone','Vallone',''),('IT','VNF','Venafro','Venafro',''),('IT','VNL','Veronella','Veronella',''),('IT','VNO','Veniano','Veniano',''),('IT','VNS','Venasca','Venasca',''),('IT','VNT','Vignate','Vignate',''),('IT','VOE','Laveno','Laveno',''),('IT','VOL','Volvera','Volvera',''),('IT','VOR','Villorba','Villorba',''),('IT','VOS','Valle Mosso','Valle Mosso',''),('IT','VPA','Valperga','Valperga',''),('IT','VPD','Vaprio d\'Adda','Vaprio d\'Adda',''),('IT','VPI','Volpiano','Volpiano',''),('IT','VPM','Varallo Pombia','Varallo Pombia',''),('IT','VPS','Villar Perosa','Villar Perosa',''),('IT','VRA','Verolavecchia','Verolavecchia',''),('IT','VRC','Verucchio','Verucchio',''),('IT','VRD','Verdello','Verdello',''),('IT','VRE','Venaria Reale','Venaria Reale',''),('IT','VRG','Vergnasco','Vergnasco',''),('IT','VRI','Veroli','Veroli',''),('IT','VRL','Vercelli','Vercelli',''),('IT','VRN','Verona','Verona',''),('IT','VRO','San Vittore Olona','San Vittore Olona',''),('IT','VRR','Verres','Verres',''),('IT','VRU','Verduno','Verduno',''),('IT','VRV','Vittorio Veneto','Vittorio Veneto',''),('IT','VRZ','Varazze','Varazze',''),('IT','VSA','Villanova sull\'Arda','Villanova sull\'Arda',''),('IT','VSE','Visone','Visone',''),('IT','VSG','Villa San Giovanni, Calabria','Villa San Giovanni, Calabria',''),('IT','VSI','Villastellone','Villastellone',''),('IT','VSL','Villa Santa Lucia','Villa Santa Lucia',''),('IT','VSM','Valeggio sul Mincio','Valeggio sul Mincio',''),('IT','VSN','Villasanta','Villasanta',''),('IT','VSO','Vasto','Vasto',''),('IT','VSR','Verderio Superiore','Verderio Superiore',''),('IT','VSS','Villa Sesso','Villa Sesso',''),('IT','VSU','Villasimius','Villasimius',''),('IT','VTA','Villotta di Chions','Villotta di Chions',''),('IT','VTE','Vernate','Vernate',''),('IT','VTI','Voltri','Voltri',''),('IT','VTM','Vertemate','Vertemate',''),('IT','VTN','Vestone','Vestone',''),('IT','VTO','Vittoria','Vittoria',''),('IT','VTT','Ventotene','Ventotene',''),('IT','VUL','Vulcano porto','Vulcano porto',''),('IT','VVA','Vibo Valentia','Vibo Valentia',''),('IT','VVE','Valvasone','Valvasone',''),('IT','VVL','Villaverla','Villaverla',''),('IT','VVN','Viano','Viano',''),('IT','VVO','Vinovo','Vinovo',''),('IT','VZA','Valenza','Valenza',''),('IT','VZL','Vezzano Ligure','Vezzano Ligure',''),('IT','VZN','Vernazza','Vernazza',''),('IT','VZO','Viguzzolo','Viguzzolo',''),('IT','VZZ','Vezzano','Vezzano',''),('IT','XAV','Sant\'Ambrogio di Valpolicella','Sant\'Ambrogio di Valpolicella',''),('IT','XMA','Malcontenta','Malcontenta',''),('IT','YBB','Barbiano','Barbiano',''),('IT','YZL','Lucrezia','Lucrezia',''),('IT','ZAF','Zaffaria','Zaffaria',''),('IT','ZAM','Mazzantica','Mazzantica',''),('IT','ZAN','Zandobbio','Zandobbio',''),('IT','ZBO','Zero Branco','Zero Branco',''),('IT','ZCA','Zocca, Modena','Zocca, Modena',''),('IT','ZCC','Zeccone','Zeccone',''),('IT','ZCO','Zocco','Zocco',''),('IT','ZGO','Zogno','Zogno',''),('IT','ZIN','Zingonia','Zingonia',''),('IT','ZMD','Novello','Novello',''),('IT','ZML','Zimella','Zimella',''),('IT','ZNC','Zanica','Zanica',''),('IT','ZNE','Zane','Zane',''),('IT','ZOL','Zola Predosa','Zola Predosa',''),('IT','ZOP','Zoppola','Zoppola',''),('IT','ZPZ','Spezzano','Spezzano',''),('IT','ZRM','Zermeghedo','Zermeghedo',''),('IT','ZSG','Zibido San Giacomo','Zibido San Giacomo',''),('IT','ZUG','Zugliano','Zugliano',''),('IT','ZVO','Zevio','Zevio',''),('JE','','','',''),('JE','JER','States Apt, Jersey','States Apt, Jersey',''),('JE','STH','St Helier','St Helier',''),('JE','TTY','Trinity','Trinity',''),('JM','','','',''),('JM','ALP','Alligator Pond','Alligator Pond',''),('JM','BLR','Black River','Black River',''),('JM','BWN','Bowden','Bowden',''),('JM','CLA','Clarendon','Clarendon',''),('JM','FMH','Falmouth','Falmouth',''),('JM','KIN','Kingston','Kingston',''),('JM','LUC','Lucea','Lucea',''),('JM','MBJ','Montego Bay','Montego Bay',''),('JM','MVJ','Mandeville','Mandeville',''),('JM','NAI','Nain','Nain',''),('JM','NEG','Negril','Negril',''),('JM','OCJ','Ocho Rios','Ocho Rios',''),('JM','ORC','Oracabessa','Oracabessa',''),('JM','PEV','Port Esquivel','Port Esquivel',''),('JM','PKS','Port Kaiser','Port Kaiser',''),('JM','PMO','Port Morant','Port Morant',''),('JM','POT','Port Antonio','Port Antonio',''),('JM','PRH','Port Rhoades','Port Rhoades',''),('JM','PRO','Port Royal','Port Royal',''),('JM','RIB','Rio Bueno','Rio Bueno',''),('JM','ROP','Rocky Point','Rocky Point',''),('JM','SAW','St Anns Bay','St Anns Bay',''),('JM','SLM','Savanna-la-Mar','Savanna-la-Mar',''),('JM','SPT','Spanish Town','Spanish Town',''),('JM','SRI','Salt River','Salt River',''),('JM','STH','Saint Thomas','Saint Thomas',''),('JO','','','',''),('JO','AMM','Amman','Amman',''),('JO','AQB','Aqaba Free Zone','Aqaba Free Zone',''),('JO','AQJ','Al \'Aqabah','Al \'Aqabah',''),('JO','ASA','As Samr?\'','As Samr?\'',''),('JO','FUH','Al Fuhays','Al Fuhays',''),('JO','MPQ','Ma\'an','Ma\'an',''),('JO','QIR','Irbid','Irbid',''),('JO','ZAR','Az Zarqa\'','Az Zarqa\'',''),('JP','','','',''),('JP','AAM','Ama, Shimane','Ama, Shimane','32'),('JP','ABA','Abashiri','Abashiri','01'),('JP','ABO','Aboshi/Himeji','Aboshi/Himeji','28'),('JP','ABS','Abohshita','Abohshita','42'),('JP','ABT','Abuto','Abuto','34'),('JP','ABU','Aburatsu','Aburatsu','45'),('JP','ACH','Ajisu','Ajisu','35'),('JP','ADE','Ade','Ade','28'),('JP','ADO','Ado','Ado','37'),('JP','AGJ','Aguni','Aguni','47'),('JP','AGN','Agenosho','Agenosho','35'),('JP','AGR','Agonoura','Agonoura','47'),('JP','AGS','Ageshima','Ageshima','37'),('JP','AIA','Ainouraaoki/Naru','Ainouraaoki/Naru','42'),('JP','AII','Aio','Aio','35'),('JP','AIK','Aikawa, Niigata','Aikawa, Niigata','15'),('JP','AIM','Aishima','Aishima','35'),('JP','AIN','Ainoura/Sasebo','Ainoura/Sasebo','42'),('JP','AIO','Aioi','Aioi','28'),('JP','AIW','Aikawa, Nagasaki','Aikawa, Nagasaki','42'),('JP','AIZ','Aizu, Kumamoto','Aizu, Kumamoto','43'),('JP','AJI','Aji','Aji','37'),('JP','AJK','Ajigasawa','Ajigasawa','02'),('JP','AJN','Ajino','Ajino','33'),('JP','AJO','Anjo','Anjo','23'),('JP','AJR','Ajiro, Shizuoka','Ajiro, Shizuoka','22'),('JP','AJX','Aja','Aja','47'),('JP','AKA','Akashi','Akashi','28'),('JP','AKB','Akohbaru','Akohbaru','46'),('JP','AKD','Akadomari','Akadomari','15'),('JP','AKE','Akkeshi','Akkeshi','01'),('JP','AKG','Akakina','Akakina','46'),('JP','AKH','Akehama','Akehama','38'),('JP','AKI','Aikakita','Aikakita','32'),('JP','AKJ','Asahikawa','Asahikawa','01'),('JP','AKK','Akasaki, Kumamoto','Akasaki, Kumamoto','43'),('JP','AKM','Akamizu','Akamizu','46'),('JP','AKN','Akune','Akune','46'),('JP','AKO','Akoh','Akoh','28'),('JP','AKT','Akitsu','Akitsu','34'),('JP','AKW','Azako','Azako','46'),('JP','AKZ','Aika','Aika','32'),('JP','AMA','Amagasaki','Amagasaki','28'),('JP','AMG','Asamogawa','Asamogawa','26'),('JP','AMI','Atami','Atami','22'),('JP','AMJ','Amaji','Amaji','39'),('JP','AMM','Ama, Hyogo','Ama, Hyogo','28'),('JP','AMR','Arimura','Arimura','46'),('JP','AMS','Amasaki','Amasaki','38'),('JP','AMT','Amatsuke','Amatsuke','43'),('JP','AMU','Amura','Amura','43'),('JP','AMX','AmagasakiNishinomiyaAshiya','AmagasakiNishinomiyaAshiya','28'),('JP','AMY','Amiya','Amiya','32'),('JP','ANA','Anan','Anan','36'),('JP','ANB','Anbo','Anbo','46'),('JP','ANE','Anegasaki','Anegasaki','12'),('JP','ANM','Anamizu','Anamizu','17'),('JP','AOE','Aoe','Aoe','35'),('JP','AOG','Aogashima','Aogashima','13'),('JP','AOI','Aoki','Aoki','37'),('JP','AOJ','Aomori','Aomori','02'),('JP','AOK','Aokata','Aokata','42'),('JP','AOM','Omi','Omi','15'),('JP','AON','Aonae','Aonae','01'),('JP','AOS','Aoshima','Aoshima','42'),('JP','ARA','Arari','Arari','22'),('JP','ARG','Amurogama','Amurogama','46'),('JP','ARK','Arikawa','Arikawa','42'),('JP','ARO','Arao','Arao','43'),('JP','ARZ','Arouzu','Arouzu','38'),('JP','ASA','Asa','Asa','35'),('JP','ASB','Ashibe','Ashibe','42'),('JP','ASH','Ashinoura','Ashinoura','42'),('JP','ASI','Asahimachi','Asahimachi','14'),('JP','ASJ','Amamioshima','Amamioshima','46'),('JP','ASK','Akasaki, Tottori','Akasaki, Tottori','31'),('JP','ASM','Asami','Asami','43'),('JP','ASR','Ashizuri','Ashizuri','39'),('JP','AST','Ashitoku','Ashitoku','46'),('JP','ASW','Asakawa','Asakawa','36'),('JP','ASZ','Ashiya, Fukuoka','Ashiya, Fukuoka','40'),('JP','ATA','Ataka','Ataka','17'),('JP','ATK','Atsuki','Atsuki','35'),('JP','ATM','Atsumi','Atsumi','23'),('JP','ATT','Atatajima','Atatajima','34'),('JP','AWA','Awa','Awa','47'),('JP','AWM','Awashimanishi','Awashimanishi','37'),('JP','AWS','Awashima','Awashima','37'),('JP','AWZ','Awazu','Awazu','36'),('JP','AXT','Akita','Akita','05'),('JP','AYS','Ayase-Shi','Ayase-Shi','14'),('JP','AYU','Ayukawa','Ayukawa','04'),('JP','AZJ','Ajiro, Tottori','Ajiro, Tottori','31'),('JP','AZR','Ajiro, Okayama','Ajiro, Okayama','33'),('JP','AZU','Azu','Azu','42'),('JP','BDM','Bohdomari','Bohdomari','46'),('JP','BEP','Beppu, Shimane','Beppu, Shimane','32'),('JP','BFS','Beppushinko','Beppushinko','44'),('JP','BOM','Boma','Boma','46'),('JP','BPU','Beppu, Oita','Beppu, Oita','44'),('JP','BYO','Byobu','Byobu','37'),('JP','CAU','Chiyoda-ku','Chiyoda-ku','13'),('JP','CHB','Chiba','Chiba','12'),('JP','CHF','Chofu','Chofu','35'),('JP','CHG','Chigasaki','Chigasaki','14'),('JP','CHH','Chichii','Chichii','32'),('JP','CHI','China','China','46'),('JP','CHK','Chikubushima','Chikubushima','25'),('JP','CHO','Choshi','Choshi','12'),('JP','CHT','Chitose, Hiroshima','Chitose, Hiroshima','34'),('JP','CHU','Churui','Churui','01'),('JP','CHY','Chiyoda','Chiyoda','08'),('JP','CIO','Chio','Chio','33'),('JP','CJU','Chiju','Chiju','43'),('JP','CKM','Chikumi','Chikumi','32'),('JP','CNS','Chinase','Chinase','46'),('JP','CTA','Chita','Chita','23'),('JP','CTS','Chitose Apt/Sapporo','Chitose Apt/Sapporo','01'),('JP','CYZ','Chiyozaki','Chiyozaki','24'),('JP','DAT','Date','Date','01'),('JP','DKI','Daikoku Island','Daikoku Island','14'),('JP','DNA','Kadena','Kadena','47'),('JP','DSR','Dohshiro','Dohshiro','42'),('JP','DTU','Daito','Daito','42'),('JP','DZK','Dohzaki','Dohzaki','42'),('JP','EBI','Ebito','Ebito','43'),('JP','EGO','Ego','Ego','43'),('JP','EGS','Eigashima','Eigashima','28'),('JP','EII','Ei','Ei','28'),('JP','EIS','Eishi','Eishi','46'),('JP','EJM','Ejima','Ejima','37'),('JP','EKZ','Enokizu','Enokizu','42'),('JP','EMM','Erimo','Erimo','01'),('JP','EMU','Emukae','Emukae','42'),('JP','ENA','Ena','Ena','07'),('JP','ENH','Enohama','Enohama','33'),('JP','ENN','En','En','46'),('JP','ENO','Enoura, Shizuoka','Enoura, Shizuoka','22'),('JP','ENR','Enoura, Kagawa','Enoura, Kagawa','37'),('JP','ESI','Esashi/Hiyama','Esashi/Hiyama','01'),('JP','ESK','Esaki','Esaki','35'),('JP','ESM','Eshima','Eshima','32'),('JP','ESS','Esashi/Soya','Esashi/Soya','01'),('JP','ETA','Etajima','Etajima','34'),('JP','ETM','Etomo','Etomo','32'),('JP','EZA','Ezaki','Ezaki','47'),('JP','FAE','Fukae, Nagasaki','Fukae, Nagasaki','42'),('JP','FCH','Fuchu-shi','Fuchu-shi','13'),('JP','FCM','Fuchinomoto','Fuchinomoto','42'),('JP','FGS','Fugusaki','Fugusaki','23'),('JP','FGW','Futagawa','Futagawa','46'),('JP','FHR','Furubira','Furubira','01'),('JP','FJK','Fujioka','Fujioka','23'),('JP','FJN','Fujino','Fujino','46'),('JP','FKA','Fukaya','Fukaya','11'),('JP','FKD','Fukuda','Fukuda','34'),('JP','FKE','Fukue, Aichi','Fukue, Aichi','23'),('JP','FKF','Fukushima','Fukushima','07'),('JP','FKH','Fukae, Hiroshima','Fukae, Hiroshima','34'),('JP','FKI','Fukai','Fukai','33'),('JP','FKJ','Fukui','Fukui','18'),('JP','FKK','Fukaura, Aomori','Fukaura, Aomori','02'),('JP','FKM','Fukushima, Nagasaki','Fukushima, Nagasaki','42'),('JP','FKR','Fukaura, Ehime','Fukaura, Ehime','38'),('JP','FKS','Fukushima Apt','Fukushima Apt','07'),('JP','FKU','Fukushima, Hokkaido','Fukushima, Hokkaido','01'),('JP','FKW','Furukawa','Furukawa','04'),('JP','FKY','Fukuyama, Hiroshima','Fukuyama, Hiroshima','34'),('JP','FMD','Futamado','Futamado','43'),('JP','FMS','Fukushima, Miyazaki','Fukushima, Miyazaki','45'),('JP','FMT','Futamata, Kagoshima','Futamata, Kagoshima','46'),('JP','FNA','Funaya','Funaya','38'),('JP','FNB','Funabashi','Funabashi','12'),('JP','FND','Funadomari','Funadomari','01'),('JP','FNK','Funagawa','Funagawa','05'),('JP','FNR','Funaura','Funaura','47'),('JP','FNS','Funakoshi','Funakoshi','38'),('JP','FNU','Funauki','Funauki','47'),('JP','FNZ','Funazu','Funazu','32'),('JP','FRA','Fukura, Hyogo','Fukura, Hyogo','28'),('JP','FRE','Furue, Nagasaki','Furue, Nagasaki','42'),('JP','FRI','Fukari','Fukari','42'),('JP','FRJ','Fukuura, Ishikawa','Fukuura, Ishikawa','17'),('JP','FRK','Furuike','Furuike','28'),('JP','FRM','Furue, Miyazaki','Furue, Miyazaki','45'),('JP','FRS','Furusato, Nagasaki','Furusato, Nagasaki','42'),('JP','FRU','Furue, Kagoshima','Furue, Kagoshima','46'),('JP','FRX','Furue, Ehime','Furue, Ehime','38'),('JP','FSH','Funakakushi','Funakakushi','37'),('JP','FSK','Fushiki','Fushiki','16'),('JP','FST','Furusato, Kagoshima','Furusato, Kagoshima','46'),('JP','FTE','Futae','Futae','43'),('JP','FTG','Futago','Futago','32'),('JP','FTM','Futenma','Futenma','47'),('JP','FTT','Futamata, Shimane','Futamata, Shimane','32'),('JP','FUA','Fukuura, Kumamoto','Fukuura, Kumamoto','43'),('JP','FUE','Fuke','Fuke','27'),('JP','FUI','Fuji','Fuji','22'),('JP','FUJ','Fukue, Nagasaki','Fukue, Nagasaki','42'),('JP','FUK','Fukuoka','Fukuoka','40'),('JP','FUM','Fukami','Fukami','43'),('JP','FUO','Fukuro','Fukuro','30'),('JP','FUR','Fukuura, Ehime','Fukuura, Ehime','38'),('JP','FUT','Futajima','Futajima','40'),('JP','FUU','Fukura, Kagoshima','Fukura, Kagoshima','46'),('JP','FUW','Fukawa','Fukawa','35'),('JP','FYM','Fukuyama, Kagoshima','Fukuyama, Kagoshima','46'),('JP','GAJ','Yamagata','Yamagata','06'),('JP','GAM','Gamagori','Gamagori','23'),('JP','GIF','Gifu','Gifu','21'),('JP','GKA','Gushikawa','Gushikawa','47'),('JP','GKB','Gohnokubi','Gohnokubi','42'),('JP','GKN','Gokan','Gokan','33'),('JP','GKS','Gokasho','Gokasho','24'),('JP','GNG','Gunge','Gunge','28'),('JP','GNW','Ginowan','Ginowan','47'),('JP','GOI','Goi/Ichihara','Goi/Ichihara','12'),('JP','GON','Gonoura','Gonoura','42'),('JP','GOT','Gohtsu','Gohtsu','32'),('JP','GPT','Gendentokai','Gendentokai','08'),('JP','GYA','Gyohda','Gyohda','11'),('JP','HAA','Hami','Hami','46'),('JP','HAB','Habu, Hiroshima','Habu, Hiroshima','34'),('JP','HAC','Hachijojima','Hachijojima','13'),('JP','HAD','Heda','Heda','22'),('JP','HAE','Haenohama','Haenohama','46'),('JP','HAG','Hagi','Hagi','35'),('JP','HAH','Hashima','Hashima','35'),('JP','HAI','Haiki','Haiki','42'),('JP','HAM','Hamasarufutsu','Hamasarufutsu','01'),('JP','HAN','Hannan','Hannan','27'),('JP','HAO','Hachioji','Hachioji','13'),('JP','HAR','Hara','Hara','42'),('JP','HAS','Hashihama','Hashihama','38'),('JP','HAU','Habu, Tokyo','Habu, Tokyo','13'),('JP','HBA','Haibara','Haibara','22'),('JP','HBB','Habu, Yamaguchi','Habu, Yamaguchi','35'),('JP','HBO','Haboro','Haboro','01'),('JP','HBR','Hiburi','Hiburi','38'),('JP','HDA','Handa','Handa','23'),('JP','HDK','Hidaka','Hidaka','30'),('JP','HDO','Himedo','Himedo','43'),('JP','HEA','Hiketa','Hiketa','37'),('JP','HED','Hetono','Hetono','46'),('JP','HEI','Henza','Henza','47'),('JP','HES','Hesaki','Hesaki','40'),('JP','HET','Heta','Heta','46'),('JP','HGH','Higashihazu','Higashihazu','23'),('JP','HGO','Hachigo','Hachigo','46'),('JP','HGS','Ohshima/Hagi','Ohshima/Hagi','35'),('JP','HGU','Hirugaura','Hirugaura','42'),('JP','HHE','Hachinohe','Hachinohe','02'),('JP','HHH','Higashinohama','Higashinohama','46'),('JP','HHM','Hohomi','Hohomi','32'),('JP','HHR','Higashiharima','Higashiharima','28'),('JP','HIA','Hiagari/Kitakiushu','Hiagari/Kitakiushu','40'),('JP','HIB','Hibi','Hibi','33'),('JP','HIC','Hitachinaka','Hitachinaka','08'),('JP','HIE','Hikone','Hikone','25'),('JP','HIG','Higashishioya','Higashishioya','46'),('JP','HII','Hirasaki','Hirasaki','46'),('JP','HIJ','Hiroshima','Hiroshima','34'),('JP','HIK','Hiki','Hiki','30'),('JP','HIM','Himeji','Himeji','28'),('JP','HIN','Hinase','Hinase','33'),('JP','HIO','Higashi-Ogishima','Higashi-Ogishima','14'),('JP','HIR','Hiroo','Hiroo','01'),('JP','HIS','Hikoshima','Hikoshima','35'),('JP','HIU','Hiratsuka','Hiratsuka','14'),('JP','HIZ','Hizenohshima','Hizenohshima','42'),('JP','HJA','Honjima','Honjima','37'),('JP','HJI','Hiji','Hiji','44'),('JP','HJM','Hamajima','Hamajima','24'),('JP','HJO','Hojo','Hojo','38'),('JP','HJR','Hamajiri','Hamajiri','46'),('JP','HJT','Hirota, Kagoshima','Hirota, Kagoshima','46'),('JP','HKA','Hirakata','Hirakata','27'),('JP','HKD','Hakodate','Hakodate','01'),('JP','HKI','Hikami','Hikami','28'),('JP','HKJ','Hamasaka','Hamasaka','28'),('JP','HKK','Hyakkan','Hyakkan','43'),('JP','HKM','Honkushima','Honkushima','38'),('JP','HKN','Hekinan','Hekinan','23'),('JP','HKR','Hikari','Hikari','35'),('JP','HKS','Hakatashima','Hakatashima','38'),('JP','HKT','Hakata/Fukuoka','Hakata/Fukuoka','40'),('JP','HKU','Hakoura','Hakoura','37'),('JP','HKW','Hamakanaya','Hamakanaya','12'),('JP','HKZ','Hikozaki','Hikozaki','33'),('JP','HMA','Hishima','Hishima','35'),('JP','HMC','Hamochi','Hamochi','15'),('JP','HMD','Hamada','Hamada','32'),('JP','HMG','Hamaguri','Hamaguri','38'),('JP','HMH','Himeshima','Himeshima','44'),('JP','HMI','Hatami','Hatami','34'),('JP','HMJ','Himi','Himi','16'),('JP','HMK','Himekawa','Himekawa','15'),('JP','HMM','Hamamatsu','Hamamatsu','22'),('JP','HMN','Hamana','Hamana','22'),('JP','HMS','Himosashi','Himosashi','42'),('JP','HMT','Hikimoto','Hikimoto','24'),('JP','HMW','Hamawaki','Hamawaki','42'),('JP','HMX','Hamasaki','Hamasaki','47'),('JP','HNA','Hanamaki','Hanamaki','03'),('JP','HND','Haneda Apt/Tokyo','Haneda Apt/Tokyo','13'),('JP','HNE','Hane','Hane','44'),('JP','HNG','Hinagu','Hinagu','43'),('JP','HNJ','Honjo, Kyoto','Honjo, Kyoto','26'),('JP','HNK','Hanasaki','Hanasaki','01'),('JP','HNN','Honmoku','Honmoku','14'),('JP','HNO','Hadano','Hadano','14'),('JP','HNR','Himenoura','Himenoura','32'),('JP','HNS','Hinoshima','Hinoshima','43'),('JP','HNY','Hanyu','Hanyu','32'),('JP','HNZ','Hinozu','Hinozu','32'),('JP','HOD','Hondo','Hondo','43'),('JP','HON','Honjo, Akita','Honjo, Akita','05'),('JP','HOS','Hoshika, Saga','Hoshika, Saga','41'),('JP','HOT','Hotokegaura','Hotokegaura','02'),('JP','HPP','Hoppozaki','Hoppozaki','46'),('JP','HRA','Hirao','Hirao','35'),('JP','HRD','Hirado','Hirado','42'),('JP','HRE','Horie','Horie','38'),('JP','HRH','Hirohata','Hirohata','28'),('JP','HRI','Horikappu','Horikappu','01'),('JP','HRJ','Hirai','Hirai','35'),('JP','HRK','Hirakata','Hirakata','08'),('JP','HRM','Haramachi','Haramachi','07'),('JP','HRO','Hiro','Hiro','34'),('JP','HRR','Hirara','Hirara','47'),('JP','HRS','Hirase','Hirase','43'),('JP','HRU','Hiroura','Hiroura','42'),('JP','HRW','Hiraiwa','Hiraiwa','45'),('JP','HSH','Hashi','Hashi','32'),('JP','HSI','Hoshika, Nagasaki','Hoshika, Nagasaki','42'),('JP','HSK','Hamasako','Hamasako','42'),('JP','HSM','Hososhima','Hososhima','45'),('JP','HSN','Hisanohama','Hisanohama','07'),('JP','HSR','Hashirajima','Hashirajima','35'),('JP','HSS','Hase','Hase','46'),('JP','HSU','Hamasuki','Hamasuki','46'),('JP','HSW','Hirasawa','Hirasawa','05'),('JP','HTA','Hirota, Iwate','Hirota, Iwate','03'),('JP','HTC','Hitachi','Hitachi','08'),('JP','HTD','Hakata','Hakata','38'),('JP','HTK','Hitakatsu','Hitakatsu','42'),('JP','HTM','Futami, Tokyo','Futami, Tokyo','13'),('JP','HTO','Hatoma','Hatoma','47'),('JP','HTR','Hateruma','Hateruma','47'),('JP','HTS','Hitsushima','Hitsushima','35'),('JP','HTT','Hata','Hata','33'),('JP','HUD','Hoda','Hoda','32'),('JP','HUR','Hannoura','Hannoura','17'),('JP','HUT','Futami, Niigata','Futami, Niigata','15'),('JP','HWA','Hamatsuwaki','Hamatsuwaki','46'),('JP','HWS','Hiwasa','Hiwasa','36'),('JP','HYG','Hyugadomari','Hyugadomari','44'),('JP','HYK','Hayakawa','Hayakawa','38'),('JP','HYM','Hayama','Hayama','14'),('JP','HYR','Hyakunoura','Hyakunoura','38'),('JP','HYS','Hisayoshi','Hisayoshi','38'),('JP','HYT','Hayato','Hayato','46'),('JP','HYU','Hyuga','Hyuga','45'),('JP','IBI','Ibiwaga','Ibiwaga','21'),('JP','IBR','Iburi','Iburi','39'),('JP','IBS','Ibusuki','Ibusuki','46'),('JP','ICD','Icchoda','Icchoda','43'),('JP','ICH','Ichihara','Ichihara','12'),('JP','ICK','Ichikawa','Ichikawa','12'),('JP','IDA','Iida','Iida','17'),('JP','IDJ','Indohji','Indohji','42'),('JP','IDM','Iwayadomari','Iwayadomari','46'),('JP','IEJ','Iejima/Okinawa','Iejima/Okinawa','47'),('JP','IER','Ieura','Ieura','37'),('JP','IES','Ieshima, Hyogo','Ieshima, Hyogo','28'),('JP','IGO','Igo','Igo','32'),('JP','IGR','Imagire','Imagire','36'),('JP','IHA','Niihama','Niihama','38'),('JP','IHN','Ichinomiya','Ichinomiya','23'),('JP','IHO','Ihota','Ihota','35'),('JP','IIB','Iibi','Iibi','32'),('JP','III','Ii','Ii','35'),('JP','IIN','Nishinoomote','Nishinoomote','46'),('JP','IKA','Ikeda, Kagawa','Ikeda, Kagawa','37'),('JP','IKC','Ikuchi','Ikuchi','34'),('JP','IKD','Ikeda, Wakayama','Ikeda, Wakayama','30'),('JP','IKE','Ikeshima','Ikeshima','42'),('JP','IKI','Iki','Iki','42'),('JP','IKJ','Isshiki','Isshiki','23'),('JP','IKK','Ikitsuki','Ikitsuki','42'),('JP','IKN','Ikina','Ikina','38'),('JP','IKR','Ikara','Ikara','46'),('JP','IKT','Ikata','Ikata','38'),('JP','IKU','Ikunohama','Ikunohama','37'),('JP','IKW','Ishikawa','Ishikawa','47'),('JP','IMA','Imafuku','Imafuku','42'),('JP','IMB','Imabari','Imabari','38'),('JP','IMI','Imari','Imari','41'),('JP','IMM','Imi','Imi','44'),('JP','IMT','Imazato','Imazato','42'),('JP','IMZ','Imazu','Imazu','38'),('JP','INA','Ina','Ina','42'),('JP','IND','Inonada','Inonada','32'),('JP','INE','Ine','Ine','26'),('JP','ING','Inugaura','Inugaura','42'),('JP','INK','Inokushi, Oita','Inokushi, Oita','44'),('JP','INO','Inobe','Inobe','46'),('JP','INR','Inatori','Inatori','22'),('JP','INS','Innoshima','Innoshima','34'),('JP','INT','Iinoseto','Iinoseto','42'),('JP','INY','Inuyama','Inuyama','23'),('JP','INZ','Inujima','Inujima','33'),('JP','IOU','Iwojima, Kagoshima','Iwojima, Kagoshima','46'),('JP','IRK','Irago','Irago','23'),('JP','ISA','Issai','Issai','39'),('JP','ISB','Ishiba','Ishiba','37'),('JP','ISC','Ishiwaki','Ishiwaki','31'),('JP','ISD','Ishida','Ishida','42'),('JP','ISE','Ise','Ise','24'),('JP','ISG','Ishigaki','Ishigaki','47'),('JP','ISH','Ishima','Ishima','33'),('JP','ISI','Ishikari','Ishikari','01'),('JP','ISK','Iseki','Iseki','46'),('JP','ISM','Ishinomaki','Ishinomaki','04'),('JP','ISS','Ishikariwanshinko','Ishikariwanshinko','01'),('JP','ISU','Isuwan','Isuwan','46'),('JP','ISW','Ishikariwan','Ishikariwan','01'),('JP','ISX','Isozaki','Isozaki','08'),('JP','ISY','Isahaya','Isahaya','42'),('JP','ISZ','Isezaki','Isezaki','10'),('JP','ITA','Itami/Hyogo','Itami/Hyogo','28'),('JP','ITJ','Itoh, Shizuoka','Itoh, Shizuoka','22'),('JP','ITK','Itako','Itako','08'),('JP','ITO','Itozaki','Itozaki','34'),('JP','ITS','Itsukushima','Itsukushima','34'),('JP','ITU','Itoh, Shimane','Itoh, Shimane','32'),('JP','IUH','Inokuchi, Ehime','Inokuchi, Ehime','38'),('JP','IWA','Iwamatsu','Iwamatsu','38'),('JP','IWG','Iwagi,Ehime','Iwagi,Ehime','38'),('JP','IWH','Iwafune','Iwafune','15'),('JP','IWI','Iwaki','Iwaki','07'),('JP','IWK','Iwakuni','Iwakuni','35'),('JP','IWN','Iwanai','Iwanai','01'),('JP','IWO','Iwojima, Tokyo','Iwojima, Tokyo','13'),('JP','IWT','Iwojima, Nagasaki','Iwojima, Nagasaki','42'),('JP','IWY','Iwaya','Iwaya','28'),('JP','IYA','Iya','Iya','32'),('JP','IYM','Iyomishima','Iyomishima','38'),('JP','IYO','Iyo','Iyo','38'),('JP','IZH','Izuhara','Izuhara','42'),('JP','IZI','Izumi, Nagasaki','Izumi, Nagasaki','42'),('JP','IZM','Izumi, Aichi','Izumi, Aichi','23'),('JP','IZO','Izumo','Izumo','32'),('JP','IZS','Izumisano','Izumisano','27'),('JP','IZU','Izuka','Izuka','37'),('JP','IZW','Inazawa','Inazawa','23'),('JP','JKT','Kotoura','Kotoura','33'),('JP','JKW','Jokawauchi','Jokawauchi','46'),('JP','JON','Jonoshita','Jonoshita','42'),('JP','JTS','Joetsu','Joetsu','15'),('JP','KAA','Kada','Kada','30'),('JP','KAB','Kabanoki','Kabanoki','43'),('JP','KAC','Kasaura','Kasaura','32'),('JP','KAD','Kaita','Kaita','34'),('JP','KAE','Kashimae','Kashimae','42'),('JP','KAF','Kafuri','Kafuri','40'),('JP','KAG','Kawarago','Kawarago','08'),('JP','KAH','Kamihira','Kamihira','43'),('JP','KAI','Kainan','Kainan','30'),('JP','KAJ','Kama, Shimane','Kama, Shimane','32'),('JP','KAK','Kasukabe','Kasukabe','11'),('JP','KAM','Kametoku','Kametoku','46'),('JP','KAN','Karuno','Karuno','08'),('JP','KAO','Kashino','Kashino','33'),('JP','KAR','Karatsu','Karatsu','41'),('JP','KAT','Katsuura, Wakayama','Katsuura, Wakayama','30'),('JP','KAU','Kasumigaura','Kasumigaura','08'),('JP','KAW','Kawauchi','Kawauchi','02'),('JP','KAX','Komoe','Komoe','28'),('JP','KAZ','Kaizaki','Kaizaki','32'),('JP','KBA','Katasoba','Katasoba','46'),('JP','KBI','Kobui','Kobui','01'),('JP','KBK','Kafuka','Kafuka','01'),('JP','KBM','Kabashima','Kabashima','42'),('JP','KBR','Kubura','Kubura','47'),('JP','KBS','Kobishima','Kobishima','33'),('JP','KBT','Kobato','Kobato','42'),('JP','KBU','Kubuki','Kubuki','42'),('JP','KCF','Kuchinofukuura','Kuchinofukuura','46'),('JP','KCH','Kawachi, Kumamoto','Kawachi, Kumamoto','43'),('JP','KCZ','Kochi','Kochi','39'),('JP','KDA','Kishiwada','Kishiwada','27'),('JP','KDI','Kodai','Kodai','42'),('JP','KDJ','Kasedo','Kasedo','46'),('JP','KDK','Kodakashima','Kodakashima','44'),('JP','KDM','Kodomari, Kumamoto','Kodomari, Kumamoto','43'),('JP','KDO','Kadokura','Kadokura','46'),('JP','KDR','Katadomari','Katadomari','46'),('JP','KDW','Kadokawa','Kadokawa','45'),('JP','KDX','Kita/Minamidaito','Kita/Minamidaito','47'),('JP','KEB','Kebuki','Kebuki','42'),('JP','KEC','Kechi','Kechi','42'),('JP','KEE','Kameike','Kameike','47'),('JP','KEG','Kegoya','Kegoya','34'),('JP','KEJ','Keraji','Keraji','46'),('JP','KEM','Keruma','Keruma','47'),('JP','KER','Kakeroma','Kakeroma','46'),('JP','KFU','Kohtsufukae','Kohtsufukae','43'),('JP','KGA','Kakogawa','Kakogawa','28'),('JP','KGB','Kuka','Kuka','35'),('JP','KGC','Koguchi','Koguchi','42'),('JP','KGE','Kumage','Kumage','44'),('JP','KGI','Kasugai','Kasugai','23'),('JP','KGJ','Kigasajima','Kigasajima','37'),('JP','KGM','Kagami','Kagami','43'),('JP','KGO','Kumago','Kumago','38'),('JP','KGR','Kamagari','Kamagari','34'),('JP','KGS','Kogushi, Yamaguchi','Kogushi, Yamaguchi','35'),('JP','KGT','Kaigata','Kaigata','46'),('JP','KGU','Kanegusuku','Kanegusuku','47'),('JP','KGW','Kakegawa','Kakegawa','22'),('JP','KHJ','Kurimamaehama','Kurimamaehama','47'),('JP','KHM','Ohama, Kagoshima','Ohama, Kagoshima','46'),('JP','KHR','Kihara','Kihara','34'),('JP','KHS','Kurahashi','Kurahashi','34'),('JP','KIA','Kiami','Kiami','32'),('JP','KIB','Kibe','Kibe','44'),('JP','KII','Kiire','Kiire','46'),('JP','KIJ','Niigata','Niigata','15'),('JP','KIK','Kikuma','Kikuma','38'),('JP','KIM','Kineshima','Kineshima','37'),('JP','KIN','Kinwan','Kinwan','47'),('JP','KIR','Kitaura, Ehime','Kitaura, Ehime','38'),('JP','KIS','Kamaishi','Kamaishi','03'),('JP','KIT','Kitaura, Miyazaki','Kitaura, Miyazaki','45'),('JP','KIW','Kisawa','Kisawa','37'),('JP','KIX','Kansai Int Apt','Kansai Int Apt','27'),('JP','KIY','Koriyama','Koriyama','07'),('JP','KJA','Kohjima','Kohjima','33'),('JP','KJD','Kudadon','Kudadon','46'),('JP','KJG','Kaga, Shimane','Kaga, Shimane','32'),('JP','KJI','Kuji, Iwate','Kuji, Iwate','03'),('JP','KJJ','Koshima','Koshima','46'),('JP','KJK','Kajiki','Kajiki','46'),('JP','KJM','Kameura, Kumamoto','Kameura, Kumamoto','43'),('JP','KJN','Kannonji','Kannonji','37'),('JP','KJO','Kinjo','Kinjo','23'),('JP','KJP','Kerama','Kerama','47'),('JP','KJR','Kiriishi','Kiriishi','46'),('JP','KJT','Kitaura, Akita','Kitaura, Akita','05'),('JP','KJU','Koura, Kagoshima','Koura, Kagoshima','46'),('JP','KKA','Karakuma','Karakuma','46'),('JP','KKB','Kokubo','Kokubo','38'),('JP','KKE','Komukae','Komukae','42'),('JP','KKI','Komaki','Komaki','23'),('JP','KKJ','Kitakyushu','Kitakyushu','40'),('JP','KKK','Kushiku','Kushiku','44'),('JP','KKL','Kohzaki','Kohzaki','42'),('JP','KKM','Katakami','Katakami','33'),('JP','KKO','Komenotsu','Komenotsu','46'),('JP','KKR','Kouri','Kouri','47'),('JP','KKT','Kamikatetsu','Kamikatetsu','46'),('JP','KKU','Kuji, Kagoshima','Kuji, Kagoshima','46'),('JP','KKW','Kanokawa','Kanokawa','34'),('JP','KKX','Kikaishima','Kikaishima','46'),('JP','KKZ','Kashikojima','Kashikojima','24'),('JP','KMA','Kama','Kama','35'),('JP','KMD','Komoda','Komoda','42'),('JP','KME','Kamae','Kamae','44'),('JP','KMF','Kaminofuruta','Kaminofuruta','46'),('JP','KMG','Kumagaya','Kumagaya','11'),('JP','KMH','Kumihama','Kumihama','26'),('JP','KMI','Miyazaki, Miyazaki','Miyazaki, Miyazaki','45'),('JP','KMJ','Kumamoto','Kumamoto','43'),('JP','KMK','Kaminokae','Kaminokae','39'),('JP','KMM','Kaminato','Kaminato','13'),('JP','KMN','Kominato','Kominato','02'),('JP','KMO','Kamo','Kamo','06'),('JP','KMQ','Komatsu, Ishikawa','Komatsu, Ishikawa','17'),('JP','KMR','Kameura, Tokushima','Kameura, Tokushima','36'),('JP','KMS','Kumeshima','Kumeshima','47'),('JP','KMT','Kimitsu','Kimitsu','12'),('JP','KMU','Kamiura','Kamiura','38'),('JP','KMW','Kamikawaguchi','Kamikawaguchi','39'),('JP','KMX','Komatsu, Yamaguchi','Komatsu, Yamaguchi','35'),('JP','KMY','Kamiyakunagata','Kamiyakunagata','46'),('JP','KNA','Kuwana','Kuwana','24'),('JP','KNB','Konbukariishi','Konbukariishi','01'),('JP','KND','Kanda, Fukuoka','Kanda, Fukuoka','40'),('JP','KNE','Kinoe','Kinoe','34'),('JP','KNG','Kuniga','Kuniga','32'),('JP','KNH','Kunehama','Kunehama','42'),('JP','KNI','Konagai','Konagai','42'),('JP','KNJ','Kisane','Kisane','32'),('JP','KNK','Kinkasan','Kinkasan','04'),('JP','KNN','Kin','Kin','42'),('JP','KNO','Konoura','Konoura','05'),('JP','KNR','Kohnoura','Kohnoura','42'),('JP','KNS','Kunisaki','Kunisaki','44'),('JP','KNT','Kinomoto','Kinomoto','24'),('JP','KNU','Kinuura','Kinuura','23'),('JP','KNX','KinNakagusuku','KinNakagusuku','47'),('JP','KNY','Koniya','Koniya','46'),('JP','KNZ','Kanazawa','Kanazawa','17'),('JP','KOA','Koshigaya','Koshigaya','11'),('JP','KOB','Koza','Koza','30'),('JP','KOD','Kodomari, Aomori','Kodomari, Aomori','02'),('JP','KOF','Konan','Konan','07'),('JP','KOG','Kogushi, Okayama','Kogushi, Okayama','33'),('JP','KOH','Kohama','Kohama','47'),('JP','KOI','Koike/Uwajima','Koike/Uwajima','38'),('JP','KOJ','Kagoshima','Kagoshima','46'),('JP','KOK','Kokura','Kokura','40'),('JP','KOM','Komatsushima','Komatsushima','36'),('JP','KON','Konoshima','Konoshima','33'),('JP','KOO','Kohmen','Kohmen','46'),('JP','KOR','Koura, Kagawa','Koura, Kagawa','37'),('JP','KOS','Kose','Kose','37'),('JP','KOU','Kohzujima','Kohzujima','13'),('JP','KOX','Kaminoseki','Kaminoseki','35'),('JP','KOY','Koyoh/Etajima','Koyoh/Etajima','34'),('JP','KOZ','Kozuna','Kozuna','42'),('JP','KRA','Kannoura','Kannoura','39'),('JP','KRB','Karubi','Karubi','32'),('JP','KRC','Kuramai','Kuramai','23'),('JP','KRD','Kuroda','Kuroda','32'),('JP','KRE','Kure, Hiroshima','Kure, Hiroshima','34'),('JP','KRH','Kurihama','Kurihama','14'),('JP','KRI','Kurio','Kurio','46'),('JP','KRJ','Kuroshima, Okinawa','Kuroshima, Okinawa','47'),('JP','KRK','Karakizaki','Karakizaki','43'),('JP','KRM','Kurokami','Kurokami','46'),('JP','KRN','Kuranotani','Kuranotani','32'),('JP','KRR','Kujiragaura','Kujiragaura','42'),('JP','KRS','Kurushima','Kurushima','38'),('JP','KRT','Kiritappu','Kiritappu','01'),('JP','KRU','Kurii','Kurii','32'),('JP','KRX','Kuroi','Kuroi','45'),('JP','KRY','Kariya, Saga','Kariya, Saga','41'),('JP','KSA','Kasaoka','Kasaoka','33'),('JP','KSB','Kusubo','Kusubo','42'),('JP','KSC','Kashima, Saga','Kashima, Saga','41'),('JP','KSD','Kasado','Kasado','35'),('JP','KSE','Kamoise','Kamoise','42'),('JP','KSH','Kishiku','Kishiku','42'),('JP','KSI','Katsuta','Katsuta','08'),('JP','KSK','Kurosaki','Kurosaki','40'),('JP','KSM','Kashima, Ibaraki','Kashima, Ibaraki','08'),('JP','KSN','Kesennuma','Kesennuma','04'),('JP','KSO','Kushikino','Kushikino','46'),('JP','KSR','Kishira','Kishira','46'),('JP','KSS','Kasasa, Kagoshima','Kasasa, Kagoshima','46'),('JP','KST','Kisakata','Kisakata','05'),('JP','KSU','Katsumoto','Katsumoto','42'),('JP','KSW','Kashiwa, Ehime','Kashiwa, Ehime','38'),('JP','KSX','Kosuki','Kosuki','46'),('JP','KSY','Kasasa, Yamaguchi','Kasasa, Yamaguchi','35'),('JP','KTA','Kitanada','Kitanada','38'),('JP','KTD','Kitadaito Apt','Kitadaito Apt','47'),('JP','KTG','Kutsugata','Kutsugata','01'),('JP','KTI','Kataichi','Kataichi','34'),('JP','KTJ','Kotakarajima','Kotakarajima','46'),('JP','KTK','Kataku','Kataku','44'),('JP','KTL','Kitakijima','Kitakijima','33'),('JP','KTM','Karatomari','Karatomari','40'),('JP','KTN','Kitakami','Kitakami','03'),('JP','KTO','Kottoi','Kottoi','35'),('JP','KTR','Kitaura, Kagawa','Kitaura, Kagawa','37'),('JP','KTS','Katashima','Katashima','39'),('JP','KTU','Kohtsuura','Kohtsuura','43'),('JP','KTX','Kita/Kitadaito','Kita/Kitadaito','47'),('JP','KTZ','Kata','Kata','24'),('JP','KUA','Kurashiki','Kurashiki','33'),('JP','KUC','Kuchinotsu','Kuchinotsu','42'),('JP','KUD','Kudamatsu','Kudamatsu','35'),('JP','KUE','Kure, Kochi','Kure, Kochi','39'),('JP','KUF','Kofu','Kofu','19'),('JP','KUG','Kugui','Kugui','33'),('JP','KUH','Kushiro','Kushiro','01'),('JP','KUJ','Kushimoto','Kushimoto','30'),('JP','KUK','Suzuka','Suzuka','24'),('JP','KUM','Yakushima','Yakushima','46'),('JP','KUR','Katsuura, Chiba','Katsuura, Chiba','12'),('JP','KUT','Kute','Kute','32'),('JP','KUU','Kumanoe','Kumanoe','45'),('JP','KUW','Kuwanoura','Kuwanoura','46'),('JP','KUX','Kuronohama','Kuronohama','46'),('JP','KUZ','Kuzu','Kuzu','37'),('JP','KWA','Kawanazu','Kawanazu','38'),('JP','KWC','Kawachi, Nagasaki','Kawachi, Nagasaki','42'),('JP','KWE','Kawagoe','Kawagoe','11'),('JP','KWI','Kawanoishi','Kawanoishi','38'),('JP','KWJ','Kawajiri, Hiroshima','Kawajiri, Hiroshima','34'),('JP','KWM','Kawashimo','Kawashimo','32'),('JP','KWN','Kawanoe','Kawanoe','38'),('JP','KWR','Kawajiri, Ibaraki','Kawajiri, Ibaraki','08'),('JP','KWS','Kawasaki','Kawasaki','14'),('JP','KWT','Kawatana','Kawatana','42'),('JP','KWX','Kowa','Kowa','23'),('JP','KWZ','Kashiwazaki','Kashiwazaki','15'),('JP','KXK','Kusukawa','Kusukawa','46'),('JP','KXS','Kasumi','Kasumi','28'),('JP','KYA','Kanoya','Kanoya','46'),('JP','KYK','Kanayaki','Kanayaki','43'),('JP','KYM','Kuyama','Kuyama','42'),('JP','KYO','Koyoh/Kawajiri','Koyoh/Kawajiri','34'),('JP','KYR','Isso','Isso','46'),('JP','KZA','Kaizuka','Kaizuka','27'),('JP','KZE','Kozera','Kozera','42'),('JP','KZH','Kazuhara','Kazuhara','37'),('JP','KZI','Kijima','Kijima','33'),('JP','KZJ','Kozai','Kozai','37'),('JP','KZK','Kozukushi','Kozukushi','39'),('JP','KZM','Kazume','Kazume','42'),('JP','KZR','Kohjiro','Kohjiro','42'),('JP','KZS','Kazusaminato','Kazusaminato','12'),('JP','KZU','Kisarazu','Kisarazu','12'),('JP','MAB','Maruichibi','Maruichibi','44'),('JP','MAD','Maedomari/Iheya','Maedomari/Iheya','47'),('JP','MAE','Maebashi','Maebashi','10'),('JP','MAG','Mategata','Mategata','38'),('JP','MAI','Maizuru','Maizuru','26'),('JP','MAK','Makiyama','Makiyama','40'),('JP','MAM','Matama','Matama','44'),('JP','MAO','Matsuo','Matsuo','33'),('JP','MAR','Marugame','Marugame','37'),('JP','MAS','Masaki','Masaki','38'),('JP','MAT','Matsushima, Nagasaki','Matsushima, Nagasaki','42'),('JP','MAU','Matsuura, Kagoshima','Matsuura, Kagoshima','46'),('JP','MAW','Nishimaizuru','Nishimaizuru','26'),('JP','MBE','Monbetsu/Abashiri','Monbetsu/Abashiri','01'),('JP','MBR','Mebaruzaki','Mebaruzaki','34'),('JP','MBT','Motobu','Motobu','47'),('JP','MCD','Mochidoi','Mochidoi','42'),('JP','MCH','Mochiishi','Mochiishi','32'),('JP','MDJ','Masuda, Kagoshima','Masuda, Kagoshima','46'),('JP','MDR','Maedomari/Tarama','Maedomari/Tarama','47'),('JP','MEG','Megi','Megi','37'),('JP','MEI','Meihama','Meihama','40'),('JP','MEN','Mei','Mei','42'),('JP','MER','Maeura','Maeura','33'),('JP','MET','Meitsu','Meitsu','45'),('JP','MGA','Matsugaura','Matsugaura','46'),('JP','MGC','Maguchi','Maguchi','33'),('JP','MGM','Magome','Magome','42'),('JP','MGN','Mogine','Mogine','43'),('JP','MGS','Megoshima','Megoshima','42'),('JP','MGU','Magusa','Magusa','23'),('JP','MGY','Nagayama','Nagayama','47'),('JP','MHI','Minachi','Minachi','30'),('JP','MHM','Maehama','Maehama','38'),('JP','MHN','Mihowan','Mihowan','31'),('JP','MHR','Mihara','Mihara','34'),('JP','MIH','Mihonoseki','Mihonoseki','32'),('JP','MII','Miike, Fukuoka','Miike, Fukuoka','40'),('JP','MIJ','Miike, Tokyo','Miike, Tokyo','13'),('JP','MIK','Misaki, Kanagawa','Misaki, Kanagawa','14'),('JP','MIN','Minamata','Minamata','43'),('JP','MIR','Miura/Mitsushima','Miura/Mitsushima','42'),('JP','MIS','Misumi, Kumamoto','Misumi, Kumamoto','43'),('JP','MIT','Mitaka, Hiroshima','Mitaka, Hiroshima','34'),('JP','MIY','Miyazu','Miyazu','26'),('JP','MIZ','Mizushima','Mizushima','33'),('JP','MKA','Mukata','Mukata','44'),('JP','MKG','Makigawa','Makigawa','46'),('JP','MKI','Misaki, Kochi','Misaki, Kochi','39'),('JP','MKJ','Mikisato','Mikisato','24'),('JP','MKK','Makurazaki','Makurazaki','46'),('JP','MKM','Mikame','Mikame','38'),('JP','MKR','Mikurajima','Mikurajima','13'),('JP','MKS','Mitsukoshima','Mitsukoshima','34'),('JP','MKU','Mukunoura','Mukunoura','34'),('JP','MKW','Mikawa','Mikawa','23'),('JP','MKX','Mishima, Kawanoe','Mishima, Kawanoe','38'),('JP','MMA','Maenohama','Maenohama','46'),('JP','MMB','Memanbetsu','Memanbetsu','01'),('JP','MMD','Minamidaito','Minamidaito','47'),('JP','MMI','Misumi, Shimane','Misumi, Shimane','32'),('JP','MMJ','Matsumoto','Matsumoto','20'),('JP','MMM','Mageshimamisaki','Mageshimamisaki','46'),('JP','MMT','Mimitsu','Mimitsu','45'),('JP','MMY','Miyakojima','Miyakojima','47'),('JP','MNA','Manazuru','Manazuru','14'),('JP','MNE','Mine','Mine','42'),('JP','MNG','Matsunaga','Matsunaga','34'),('JP','MNJ','Minna/Motobu','Minna/Motobu','47'),('JP','MNM','Minami','Minami','32'),('JP','MNN','Minna/Tarama','Minna/Tarama','47'),('JP','MNO','Miyanoura/Kamiyaku','Miyanoura/Kamiyaku','46'),('JP','MNR','Miyanoura, Nagasaki','Miyanoura, Nagasaki','42'),('JP','MNT','Minato, Hyogo','Minato, Hyogo','28'),('JP','MNY','Minmaya','Minmaya','02'),('JP','MOG','Mogi','Mogi','42'),('JP','MOJ','Moji/Kitakyushu','Moji/Kitakyushu','40'),('JP','MOM','Morodomi','Morodomi','41'),('JP','MOO','Morie','Morie','44'),('JP','MOR','Mori','Mori','01'),('JP','MOT','Motomachi','Motomachi','13'),('JP','MOU','Motoura/Toshima','Motoura/Toshima','46'),('JP','MOX','Monoi','Monoi','32'),('JP','MQT','Mito, Kagawa','Mito, Kagawa','37'),('JP','MRA','Matsushima, Miyagi','Matsushima, Miyagi','04'),('JP','MRE','Mure','Mure','37'),('JP','MRG','Moriage','Moriage','38'),('JP','MRH','Morinohama','Morinohama','42'),('JP','MRJ','Murotomisaki','Murotomisaki','39'),('JP','MRK','Morakui','Morakui','32'),('JP','MRM','Muromoto','Muromoto','37'),('JP','MRO','Murokita','Murokita','37'),('JP','MRS','Murotsu, Hyogo','Murotsu, Hyogo','28'),('JP','MRT','Murotsu, Yamaguchi','Murotsu, Yamaguchi','35'),('JP','MRU','Maruo','Maruo','35'),('JP','MRW','Morioka','Morioka','03'),('JP','MRZ','Morozaki','Morozaki','23'),('JP','MSA','Matsusaka','Matsusaka','24'),('JP','MSD','Masuda, Shimane','Masuda, Shimane','32'),('JP','MSH','Musashi','Musashi','44'),('JP','MSI','MieShikimi','MieShikimi','42'),('JP','MSJ','Misawa','Misawa','02'),('JP','MSK','Mashike','Mashike','01'),('JP','MSM','Mishima, Shizuoka','Mishima, Shizuoka','22'),('JP','MSO','Misho','Misho','38'),('JP','MSR','Mishiro','Mishiro','42'),('JP','MSS','Matsushima, Okayama','Matsushima, Okayama','33'),('JP','MST','Misato','Misato','42'),('JP','MSX','Misaki, Ehime','Misaki, Ehime','38'),('JP','MTA','Mitaka, Tokyo','Mitaka, Tokyo','13'),('JP','MTC','Mitachi','Mitachi','37'),('JP','MTD','Matsudo','Matsudo','12'),('JP','MTE','Matsue','Matsue','32'),('JP','MTH','Mitsuhama','Mitsuhama','38'),('JP','MTI','Mitarai','Mitarai','34'),('JP','MTK','Mitsukue','Mitsukue','38'),('JP','MTM','Matsumae','Matsumae','01'),('JP','MTO','Motoura/Azuma','Motoura/Azuma','46'),('JP','MTR','Mutsure','Mutsure','35'),('JP','MTS','Matsuura, Nagasaki','Matsuura, Nagasaki','42'),('JP','MTU','Matsuura, Oita','Matsuura, Oita','44'),('JP','MTY','Matoya','Matoya','24'),('JP','MTZ','Matsuzaki','Matsuzaki','22'),('JP','MUG','Mugi','Mugi','36'),('JP','MUK','Mukaishima','Mukaishima','34'),('JP','MUR','Muroran','Muroran','01'),('JP','MUT','Mutsuogawara','Mutsuogawara','02'),('JP','MUX','Murotsu, Kochi','Murotsu, Kochi','39'),('JP','MUY','Miyanoura, Kagawa','Miyanoura, Kagawa','37'),('JP','MWA','Maruiwa','Maruiwa','33'),('JP','MWR','Mawari','Mawari','42'),('JP','MXT','Mita','Mita','32'),('JP','MYA','Muya','Muya','36'),('JP','MYE','Miyakejima Apt/Tokyo','Miyakejima Apt/Tokyo','13'),('JP','MYG','Miyagahama','Miyagahama','46'),('JP','MYI','Miyagi','Miyagi','10'),('JP','MYJ','Matsuyama','Matsuyama','38'),('JP','MYK','Miyako, Iwate','Miyako, Iwate','03'),('JP','MYN','Miyanoura/Azuma','Miyanoura/Azuma','46'),('JP','MYU','Miyaura','Miyaura','38'),('JP','MZK','Miyazaki, Ehime','Miyazaki, Ehime','38'),('JP','MZM','Murozumi','Murozumi','35'),('JP','MZR','Motozaru','Motozaru','44'),('JP','MZS','Mizusaki','Mizusaki','42'),('JP','NAA','Nagaura, Nagasaki','Nagaura, Nagasaki','42'),('JP','NAB','Nagara','Nagara','46'),('JP','NAD','Nadahama','Nadahama','28'),('JP','NAG','Nagahama, Shimane','Nagahama, Shimane','32'),('JP','NAH','Naha, Okinawa','Naha, Okinawa','47'),('JP','NAI','Narashino','Narashino','12'),('JP','NAK','Nakagusuku','Nakagusuku','47'),('JP','NAM','Nama','Nama','42'),('JP','NAN','Nakanoseki','Nakanoseki','35'),('JP','NAO','Naoetsu','Naoetsu','15'),('JP','NAR','Naarai','Naarai','12'),('JP','NAS','Naoshima','Naoshima','37'),('JP','NAT','Nakatsu','Nakatsu','44'),('JP','NAY','Nagayo','Nagayo','42'),('JP','NAZ','Naze','Naze','46'),('JP','NBS','Nobeokashinko','Nobeokashinko','45'),('JP','NBU','Nobu/Mitsushima','Nobu/Mitsushima','42'),('JP','NCO','Nonoichi, Ishikawa','Nonoichi, Ishikawa','17'),('JP','NDI','Nishi/Minamidaito','Nishi/Minamidaito','47'),('JP','NDY','Nadayama','Nadayama','32'),('JP','NEJ','Nejime','Nejime','46'),('JP','NEM','Nemuro','Nemuro','01'),('JP','NEO','Neo','Neo','42'),('JP','NEX','Nagae, Ehime','Nagae, Ehime','38'),('JP','NEZ','Nezugaseki','Nezugaseki','06'),('JP','NGD','Nagouda','Nagouda','32'),('JP','NGE','Nagae, Shimane','Nagae, Shimane','32'),('JP','NGG','Nagame','Nagame','43'),('JP','NGH','Nagahama, Ehime','Nagahama, Ehime','38'),('JP','NGI','Neghishi/Yokohama','Neghishi/Yokohama','14'),('JP','NGK','Nakakoshi','Nakakoshi','01'),('JP','NGM','Nagimi','Nagimi','38'),('JP','NGN','Naigainoura','Naigainoura','39'),('JP','NGO','Nagoya, Aichi','Nagoya, Aichi','23'),('JP','NGR','Nagaura/Yokosuka','Nagaura/Yokosuka','14'),('JP','NGS','Nagasaki','Nagasaki','42'),('JP','NGU','Nagasu, Kumamoto','Nagasu, Kumamoto','43'),('JP','NGY','Nagoya, Oita','Nagoya, Oita','44'),('JP','NHA','Nakahama, Hiroshima','Nakahama, Hiroshima','34'),('JP','NHI','Nahari','Nahari','39'),('JP','NHJ','Noheji','Noheji','02'),('JP','NHM','Nagahama, Shiga','Nagahama, Shiga','25'),('JP','NHN','Nagasakinohana','Nagasakinohana','37'),('JP','NHO','Nishio','Nishio','23'),('JP','NHR','Nishihara','Nishihara','47'),('JP','NIA','Nita','Nita','42'),('JP','NIC','Nichinan','Nichinan','45'),('JP','NID','Nishi/Kitadaito','Nishi/Kitadaito','47'),('JP','NIH','Niigatahigashi','Niigatahigashi','15'),('JP','NIJ','Niijima','Niijima','13'),('JP','NIM','Nima','Nima','32'),('JP','NIN','Niigatanishi','Niigatanishi','15'),('JP','NIO','Nio','Nio','37'),('JP','NIS','Nishinaka','Nishinaka','38'),('JP','NIT','Namikata','Namikata','38'),('JP','NIX','Nii','Nii','42'),('JP','NJA','Atsugi','Atsugi','14'),('JP','NJM','Nakajima','Nakajima','38'),('JP','NJR','Nojiri','Nojiri','46'),('JP','NKD','Nakada','Nakada','47'),('JP','NKH','Nakahama, Tottori','Nakahama, Tottori','31'),('JP','NKJ','Nakahama, Kyoto','Nakahama, Kyoto','26'),('JP','NKK','Nakakoshiki','Nakakoshiki','46'),('JP','NKL','Nakama, Kagoshima','Nakama, Kagoshima','46'),('JP','NKM','Nakama, Okinawa','Nakama, Okinawa','47'),('JP','NKN','Nakanoura','Nakanoura','42'),('JP','NKO','Nanko','Nanko','27'),('JP','NKR','Nakiri','Nakiri','24'),('JP','NKS','Nakanoshima','Nakanoshima','46'),('JP','NKT','Nakata, Hiroshima','Nakata, Hiroshima','34'),('JP','NKX','Nakanosaku','Nakanosaku','07'),('JP','NKY','Nakayama','Nakayama','32'),('JP','NKZ','Nakashima','Nakashima','36'),('JP','NMA','Nagahama, Kagoshima','Nagahama, Kagoshima','46'),('JP','NMC','Nakamichi','Nakamichi','19'),('JP','NMI','Nomi','Nomi','45'),('JP','NMK','Nomaike','Nomaike','46'),('JP','NMT','Nakaminato','Nakaminato','08'),('JP','NNG','Nagano','Nagano','20'),('JP','NNH','Nunohama','Nunohama','33'),('JP','NNK','Nenokuchi','Nenokuchi','02'),('JP','NNO','Nanao','Nanao','17'),('JP','NNT','Nanatsugama','Nanatsugama','42'),('JP','NOB','Nobeoka','Nobeoka','45'),('JP','NOD','Noda','Noda','12'),('JP','NOH','Nohara','Nohara','26'),('JP','NOM','Nomizaki','Nomizaki','43'),('JP','NON','Nonohama','Nonohama','33'),('JP','NOU','Noh','Noh','15'),('JP','NQH','Noho','Noho','47'),('JP','NRI','Narita, Chiba','Narita, Chiba','12'),('JP','NRO','Narao','Narao','42'),('JP','NRS','Narushima','Narushima','42'),('JP','NRT','Narita Apt/Tokyo','Narita Apt/Tokyo','12'),('JP','NRU','Naruto','Naruto','36'),('JP','NSA','Nagashima','Nagashima','24'),('JP','NSB','Nishibe','Nishibe','38'),('JP','NSH','Nishishioya','Nishishioya','46'),('JP','NSI','Nishiesan','Nishiesan','01'),('JP','NSK','Nishiki','Nishiki','27'),('JP','NSM','Nishimura','Nishimura','32'),('JP','NSR','Noshiro','Noshiro','05'),('JP','NST','Nishikata','Nishikata','46'),('JP','NSU','Nagasu, Oita','Nagasu, Oita','44'),('JP','NSX','Nasa','Nasa','36'),('JP','NTX','Nakata, Kumamoto','Nakata, Kumamoto','43'),('JP','NTY','Nanatsuyama','Nanatsuyama','46'),('JP','NUM','Numazu','Numazu','22'),('JP','NUR','Nishiura','Nishiura','22'),('JP','NWA','Nyugawa','Nyugawa','38'),('JP','NXG','Nigishima','Nigishima','24'),('JP','NYA','Nishinomiya','Nishinomiya','28'),('JP','NYK','Nyukou','Nyukou','32'),('JP','NYO','Nanyo','Nanyo','06'),('JP','NYW','Neyagawa','Neyagawa','27'),('JP','NYZ','Nyuzu','Nyuzu','44'),('JP','OAA','Okada','Okada','13'),('JP','OAD','Onoaida','Onoaida','46'),('JP','OAM','Oyama','Oyama','09'),('JP','OAR','Oarai','Oarai','08'),('JP','OAT','Ogatsu','Ogatsu','04'),('JP','OAX','Oma','Oma','02'),('JP','OBA','Obama, Mie','Obama, Mie','24'),('JP','OBB','Obama, Nagasaki','Obama, Nagasaki','42'),('JP','OBE','Obe, Ehime','Obe, Ehime','38'),('JP','OBM','Obama, Fukui','Obama, Fukui','18'),('JP','OBO','Obihiro','Obihiro','01'),('JP','OBS','Ohbishima','Ohbishima','33'),('JP','OBX','Ohbe, Kagawa','Ohbe, Kagawa','37'),('JP','OCH','Okunouchi','Okunouchi','34'),('JP','ODA','Odahigashi','Odahigashi','32'),('JP','ODM','Odomari','Odomari','46'),('JP','ODN','Ohdana','Ohdana','46'),('JP','ODO','Odoh','Odoh','43'),('JP','ODS','Odeshima','Odeshima','37'),('JP','OFK','Ohfunakoshi','Ohfunakoshi','42'),('JP','OFR','Ohfukaura','Ohfukaura','39'),('JP','OFT','Ohfunato','Ohfunato','03'),('JP','OGA','Ogasawara','Ogasawara','13'),('JP','OGC','Ongachi','Ongachi','46'),('JP','OGE','Ohge','Ohge','38'),('JP','OGF','Ogifushi','Ogifushi','01'),('JP','OGG','Ogaki','Ogaki','21'),('JP','OGH','Oginohama','Oginohama','04'),('JP','OGI','Ogi, Niigata','Ogi, Niigata','15'),('JP','OGK','Ogi, Kagawa','Ogi, Kagawa','37'),('JP','OGM','Ogomori','Ogomori','46'),('JP','OGN','Yonagunijima','Yonagunijima','47'),('JP','OGS','Ohgishima','Ohgishima','14'),('JP','OGU','Ohgushi','Ohgushi','42'),('JP','OHA','Ohama, Kagawa','Ohama, Kagawa','37'),('JP','OHM','Ohama, Ehime','Ohama, Ehime','38'),('JP','OHO','Ohi','Ohi','13'),('JP','OHT','Ohata','Ohata','02'),('JP','OIG','Ohigawa','Ohigawa','22'),('JP','OII','Ogi, Ishikawa','Ogi, Ishikawa','17'),('JP','OIM','Ohshima, Tokyo','Ohshima, Tokyo','13'),('JP','OIR','Okushiri','Okushiri','01'),('JP','OIS','Oiso','Oiso','14'),('JP','OIT','Oita','Oita','44'),('JP','OIU','Okiura, Hiroshima','Okiura, Hiroshima','34'),('JP','OJI','Ojika','Ojika','42'),('JP','OJM','Omosu','Omosu','32'),('JP','OJO','Osako','Osako','34'),('JP','OKA','Okinawa','Okinawa','47'),('JP','OKB','Okubo, Tokyo','Okubo, Tokyo','13'),('JP','OKC','Okitsu, Chiba','Okitsu, Chiba','12'),('JP','OKD','Okadama Apt/Sapporo','Okadama Apt/Sapporo','01'),('JP','OKE','Okinoerabu','Okinoerabu','46'),('JP','OKG','Okogi','Okogi','38'),('JP','OKH','Ohkawara','Ohkawara','42'),('JP','OKI','Oki','Oki','32'),('JP','OKJ','Okayama','Okayama','33'),('JP','OKK','Okinokojima','Okinokojima','46'),('JP','OKM','Okamoto','Okamoto','32'),('JP','OKN','Okinajima','Okinajima','07'),('JP','OKO','Yokota Apt/Tokyo','Yokota Apt/Tokyo','13'),('JP','OKR','Ohbukura/Uwajima','Ohbukura/Uwajima','38'),('JP','OKS','Okiuranishi','Okiuranishi','35'),('JP','OKT','Okitsu, Shizuoka','Okitsu, Shizuoka','22'),('JP','OKU','Oku','Oku','47'),('JP','OKW','Okawa, Wakayama','Okawa, Wakayama','30'),('JP','OKX','Okiura, Yamaguchi','Okiura, Yamaguchi','35'),('JP','OKY','Okaya','Okaya','20'),('JP','OKZ','Okazaki','Okazaki','23'),('JP','OMD','Omodaka','Omodaka','42'),('JP','OMH','Omotehama','Omotehama','04'),('JP','OMI','Omi','Omi','38'),('JP','OMJ','Omura','Omura','42'),('JP','OMN','Omon','Omon','43'),('JP','OMO','Omoto','Omoto','03'),('JP','OMR','Okamura','Okamura','38'),('JP','OMS','Omishima','Omishima','38'),('JP','OMT','Ominato','Ominato','02'),('JP','OMU','Omuta','Omuta','40'),('JP','OMW','Omonawa','Omonawa','46'),('JP','OMX','Ohama, Tottori','Ohama, Tottori','31'),('JP','OMY','Omiyaji','Omiyaji','43'),('JP','OMZ','Omaezaki','Omaezaki','22'),('JP','ONA','Onahama','Onahama','07'),('JP','ONB','Onnebetsu','Onnebetsu','01'),('JP','OND','Onoda','Onoda','35'),('JP','ONE','Ohnejime','Ohnejime','46'),('JP','ONG','Onagawa','Onagawa','04'),('JP','ONI','Onishi','Onishi','38'),('JP','ONJ','Oniike','Oniike','43'),('JP','ONK','Oniki','Oniki','43'),('JP','ONO','Onomichi','Onomichi','34'),('JP','ONS','Ohnishi/Ohsaki','Ohnishi/Ohsaki','34'),('JP','ONU','Onuki','Onuki','04'),('JP','ONW','Oniwaki','Oniwaki','01'),('JP','ONX','OnomichiItozaki','OnomichiItozaki','34'),('JP','OOA','Oura, Saga','Oura, Saga','41'),('JP','OOB','Obatake','Obatake','35'),('JP','OOC','Ochiyo','Ochiyo','13'),('JP','OOG','Ohgaki','Ohgaki','34'),('JP','OOH','Ohama, Okayama','Ohama, Okayama','33'),('JP','OOJ','Okubo, Kagoshima','Okubo, Kagoshima','46'),('JP','OOM','Ohshima, Kagawa','Ohshima, Kagawa','37'),('JP','OON','Ohnoh','Ohnoh','45'),('JP','OOO','Ozu','Ozu','34'),('JP','OOR','Oura/Kasaoka','Oura/Kasaoka','33'),('JP','OOW','Okawa, Nagasaki','Okawa, Nagasaki','42'),('JP','OPA','Oppama','Oppama','14'),('JP','ORA','Ohra','Ohra','38'),('JP','ORG','Origami','Origami','42'),('JP','ORN','Orino','Orino','36'),('JP','ORR','Oura/Uchinoura','Oura/Uchinoura','46'),('JP','ORX','Oura/Marugame','Oura/Marugame','37'),('JP','OSA','Osaka','Osaka','27'),('JP','OSD','Oshidomari','Oshidomari','01'),('JP','OSE','Osoe','Osoe','32'),('JP','OSH','Ohshima, Wakayama','Ohshima, Wakayama','30'),('JP','OSI','Ohshima, Ehime','Ohshima, Ehime','38'),('JP','OSJ','Otsu, Ibaraki','Otsu, Ibaraki','08'),('JP','OSK','Osaki, Miyagi','Osaki, Miyagi','04'),('JP','OSL','Oshima, Yamaguchi','Oshima, Yamaguchi','35'),('JP','OSM','Oshima, Nagasaki','Oshima, Nagasaki','42'),('JP','OSN','Osaki/Mitsushima','Osaki/Mitsushima','42'),('JP','OSO','Ohshima, Miyazaki','Ohshima, Miyazaki','45'),('JP','OSR','Ohgasari','Ohgasari','46'),('JP','OSS','Ohshima, Fukuoka','Ohshima, Fukuoka','40'),('JP','OST','Osetoyanagi','Osetoyanagi','42'),('JP','OSU','Osuki','Osuki','46'),('JP','OSX','Osaki, Kagoshima','Osaki, Kagoshima','46'),('JP','OTA','Otao','Otao','42'),('JP','OTG','Ota, Gunma','Ota, Gunma','10'),('JP','OTJ','Otsuchi','Otsuchi','03'),('JP','OTK','Otake','Otake','34'),('JP','OTM','Otomi','Otomi','18'),('JP','OTO','Osato','Osato','46'),('JP','OTR','Otaru','Otaru','01'),('JP','OTU','Otsu, Shiga','Otsu, Shiga','25'),('JP','OTW','Otawa','Otawa','42'),('JP','OUA','Oura/Ariake','Oura/Ariake','43'),('JP','OUK','Osaka, Tottori','Osaka, Tottori','31'),('JP','OUM','Omu','Omu','01'),('JP','OUR','Oura/Kamitsushima','Oura/Kamitsushima','42'),('JP','OUS','Ohse','Ohse','08'),('JP','OWA','Owase','Owase','24'),('JP','OYA','Ojoya','Ojoya','46'),('JP','OYB','Oyabu','Oyabu','33'),('JP','OYM','Ohyama/Mitsushima','Ohyama/Mitsushima','42'),('JP','OZJ','Ohzuku','Ohzuku','32'),('JP','OZU','Ozuku','Ozuku','32'),('JP','OZX','Ozaki','Ozaki','27'),('JP','QSG','Saga, Saga','Saga, Saga','41'),('JP','RAU','Rausu','Rausu','01'),('JP','RBJ','Rebun','Rebun','01'),('JP','RHK','Reihoku','Reihoku','43'),('JP','RIS','Rishiri','Rishiri','01'),('JP','RKO','Rokko Island','Rokko Island','28'),('JP','RMI','Rumoi','Rumoi','01'),('JP','RND','Ronden','Ronden','32'),('JP','RNJ','Yoronjima','Yoronjima','46'),('JP','RYG','Ryugamizu','Ryugamizu','46'),('JP','RYO','Ryotsu','Ryotsu','15'),('JP','RYS','Ryohshida','Ryohshida','34'),('JP','SAA','Sayama','Sayama','11'),('JP','SAB','Saba','Saba','38'),('JP','SAC','Sai, Shimane','Sai, Shimane','32'),('JP','SAD','Saidoh','Saidoh','46'),('JP','SAE','Saiki','Saiki','44'),('JP','SAG','Saganoseki','Saganoseki','44'),('JP','SAI','Saigo, Shimane','Saigo, Shimane','32'),('JP','SAJ','Saijo','Saijo','38'),('JP','SAK','Sakai','Sakai','27'),('JP','SAM','Samani','Samani','01'),('JP','SAN','Sanbonmatsu','Sanbonmatsu','37'),('JP','SAO','Sato','Sato','46'),('JP','SAR','Shikaura','Shikaura','46'),('JP','SAS','Sasago','Sasago','32'),('JP','SAT','Sakate','Sakate','37'),('JP','SAU','Sakitsu','Sakitsu','43'),('JP','SAW','Sagawa','Sagawa','38'),('JP','SAZ','Saza','Saza','42'),('JP','SBK','Sakaisenboku','Sakaisenboku','27'),('JP','SBS','Shibushi','Shibushi','46'),('JP','SBU','Shibaura','Shibaura','13'),('JP','SBY','Shibayama','Shibayama','28'),('JP','SCH','Shichirinagahama','Shichirinagahama','02'),('JP','SCR','Shichirui','Shichirui','32'),('JP','SDA','Shimoda, Nagasaki','Shimoda, Nagasaki','42'),('JP','SDJ','Sendai, Miyagi','Sendai, Miyagi','04'),('JP','SDK','Shitooke','Shitooke','46'),('JP','SDO','Sado','Sado','15'),('JP','SDS','Sendaishinko','Sendaishinko','04'),('JP','SDU','Sodegaura','Sodegaura','12'),('JP','SDZ','Saidaiji','Saidaiji','33'),('JP','SEA','Setagaya-ku/Tokyo','Setagaya-ku/Tokyo','13'),('JP','SEB','Seibu','Seibu','13'),('JP','SEG','Seigaura','Seigaura','46'),('JP','SEK','Sekinehama','Sekinehama','02'),('JP','SEN','Sendai, Kagoshima','Sendai, Kagoshima','46'),('JP','SEQ','Se/Izuhara','Se/Izuhara','42'),('JP','SES','Sesoko','Sesoko','47'),('JP','SEZ','Sezaki','Sezaki','46'),('JP','SGA','Saga, Kochi','Saga, Kochi','39'),('JP','SGE','Suge','Suge','38'),('JP','SGH','Sagamihara','Sagamihara','14'),('JP','SGI','Shigetomi','Shigetomi','46'),('JP','SGJ','Sagi','Sagi','34'),('JP','SGM','Sendaishiogama','Sendaishiogama','04'),('JP','SGR','Sagara','Sagara','22'),('JP','SGT','Shiogatani','Shiogatani','44'),('JP','SGU','Saigo, Nagasaki','Saigo, Nagasaki','42'),('JP','SGW','Segawa','Segawa','42'),('JP','SGX','Sonogi','Sonogi','42'),('JP','SHB','Nakashibetsu','Nakashibetsu','01'),('JP','SHG','Shinagawa-ku/Tokyo','Shinagawa-ku/Tokyo','13'),('JP','SHH','Shirahama, Kagoshima','Shirahama, Kagoshima','46'),('JP','SHI','Shimojishima','Shimojishima','47'),('JP','SHJ','Shinko','Shinko','20'),('JP','SHK','Shinkiba','Shinkiba','13'),('JP','SHM','Shirahama, Wakayama','Shirahama, Wakayama','30'),('JP','SHN','Shingu','Shingu','30'),('JP','SHO','Shizuoka','Shizuoka','22'),('JP','SHR','Shari','Shari','01'),('JP','SHS','Shimonoseki','Shimonoseki','35'),('JP','SHU','Shushi','Shushi','42'),('JP','SHZ','Shimazuya','Shimazuya','32'),('JP','SIA','Shimoda, Kumamoto','Shimoda, Kumamoto','43'),('JP','SID','Shido','Shido','37'),('JP','SIG','Shigei','Shigei','34'),('JP','SIH','Shirahama, Okinawa','Shirahama, Okinawa','47'),('JP','SIK','Shikamachi','Shikamachi','42'),('JP','SIM','Shimama','Shimama','46'),('JP','SIN','Shiinoki','Shiinoki','46'),('JP','SIO','Shioya, Ishikawa','Shioya, Ishikawa','17'),('JP','SIR','Shirahama, Nagasaki','Shirahama, Nagasaki','42'),('JP','SIS','Shishikui','Shishikui','36'),('JP','SIT','Shitanoura','Shitanoura','42'),('JP','SJA','Sai, Aomori','Sai, Aomori','02'),('JP','SJI','Shishijima, Kagawa','Shishijima, Kagawa','37'),('JP','SJM','Shishijima, Kagoshima','Shishijima, Kagoshima','46'),('JP','SJR','Shiroko','Shiroko','24'),('JP','SKB','Shibukawa','Shibukawa','33'),('JP','SKD','Sakaide','Sakaide','37'),('JP','SKH','Sakihama','Sakihama','39'),('JP','SKK','Sakaki','Sakaki','39'),('JP','SKM','Shikama','Shikama','28'),('JP','SKN','Shikinejima','Shikinejima','13'),('JP','SKO','Sakoshi','Sakoshi','28'),('JP','SKR','Sakuraikako','Sakuraikako','38'),('JP','SKT','Sakata','Sakata','06'),('JP','SKU','Shiraku','Shiraku','33'),('JP','SKW','Shinkawa, Aichi','Shinkawa, Aichi','23'),('JP','SKY','Sekiya','Sekiya','37'),('JP','SMA','Souma','Souma','07'),('JP','SMB','Shimabara','Shimabara','42'),('JP','SMD','Shimoda, Shizuoka','Shimoda, Shizuoka','22'),('JP','SME','Same','Same','02'),('JP','SMH','Shimohisage','Shimohisage','38'),('JP','SMI','Sumie','Sumie','45'),('JP','SMK','Samukawa','Samukawa','14'),('JP','SMM','Shimamaki','Shimamaki','01'),('JP','SMN','Sakaiminato','Sakaiminato','31'),('JP','SMO','Shimoda, Kochi','Shimoda, Kochi','39'),('JP','SMR','Shimodomari/Mikame','Shimodomari/Mikame','38'),('JP','SMT','Shimotsu','Shimotsu','30'),('JP','SMU','Sakimui','Sakimui','01'),('JP','SMY','Sumiyoshi','Sumiyoshi','46'),('JP','SMZ','Shimizu','Shimizu','22'),('JP','SNA','Sonai/Yonaguni','Sonai/Yonaguni','47'),('JP','SNE','Sone','Sone','42'),('JP','SNI','Sonai/Taketomi','Sonai/Taketomi','47'),('JP','SNJ','Shinojima','Shinojima','23'),('JP','SNK','Shinkawa, Kagoshima','Shinkawa, Kagoshima','46'),('JP','SNM','Sanami','Sanami','32'),('JP','SNN','Shonan','Shonan','14'),('JP','SNO','Shitanoe','Shitanoe','44'),('JP','SNR','Shukunoura','Shukunoura','42'),('JP','SNU','Shimanoura','Shimanoura','45'),('JP','SNW','Shinokawa','Shinokawa','46'),('JP','SNX','Sanagi','Sanagi','37'),('JP','SNZ','Shinzaike','Shinzaike','37'),('JP','SOG','Sogo','Sogo','33'),('JP','SOH','Shiohama','Shiohama','32'),('JP','SOO','Shimonokae','Shimonokae','39'),('JP','SOR','Sonoura','Sonoura','42'),('JP','SOT','Sotodomari/Nishiumi','Sotodomari/Nishiumi','38'),('JP','SOY','Soya','Soya','01'),('JP','SOZ','Sozu','Sozu','32'),('JP','SPK','Sapporo','Sapporo','01'),('JP','SRA','Shiraki','Shiraki','35'),('JP','SRH','Shirahama, Kagawa','Shirahama, Kagawa','37'),('JP','SRJ','Shiro','Shiro','32'),('JP','SRK','Shirosaki','Shirosaki','03'),('JP','SRO','Shiraoi','Shiraoi','01'),('JP','SRS','Shirose','Shirose','46'),('JP','SRT','Shirakata','Shirakata','38'),('JP','SRX','Shirahama, Chiba','Shirahama, Chiba','12'),('JP','SRZ','Sakurajima','Sakurajima','46'),('JP','SSA','Shimotsuura','Shimotsuura','43'),('JP','SSB','Sasebo','Sasebo','42'),('JP','SSE','Sasue','Sasue','46'),('JP','SSH','Shishiboe','Shishiboe','42'),('JP','SSI','Sashiki','Sashiki','43'),('JP','SSJ','Shisakajima','Shisakajima','38'),('JP','SSK','Saizaki','Saizaki','34'),('JP','SSM','Shishimi','Shishimi','42'),('JP','SSN','Sasuna','Sasuna','42'),('JP','STA','Sata','Sata','46'),('JP','STB','Shitaba','Shitaba','38'),('JP','STD','Setoda','Setoda','34'),('JP','STE','Satoura','Satoura','37'),('JP','STI','Shimotsui','Shimotsui','33'),('JP','STJ','Shikata','Shikata','34'),('JP','STN','Setana','Setana','01'),('JP','STO','Sakito','Sakito','42'),('JP','STR','Shirotori','Shirotori','37'),('JP','STT','Seto, Kagoshima','Seto, Kagoshima','46'),('JP','STU','Suttsu','Suttsu','01'),('JP','STW','Satsukawawan','Satsukawawan','46'),('JP','STZ','Saitozaki','Saitozaki','40'),('JP','SUE','Sunoe','Sunoe','34'),('JP','SUG','Suga','Suga','32'),('JP','SUH','Sumoto, Hyogo','Sumoto, Hyogo','28'),('JP','SUK','Sukumowan','Sukumowan','39'),('JP','SUM','Suminoe','Suminoe','41'),('JP','SUR','Sugeura','Sugeura','32'),('JP','SUS','Susa','Susa','35'),('JP','SUT','Sumoto, Kumamoto','Sumoto, Kumamoto','43'),('JP','SUU','Sugawa','Sugawa','42'),('JP','SUW','Suwa','Suwa','32'),('JP','SUZ','Susaki','Susaki','39'),('JP','SWA','Shimokawaguchi','Shimokawaguchi','39'),('JP','SWR','Sawara','Sawara','12'),('JP','SXM','Sunami','Sunami','34'),('JP','SXO','Shinjuku-ku','Shinjuku-ku','13'),('JP','SXT','Seto, Kagawa','Seto, Kagawa','37'),('JP','SYA','Shioya, Okinawa','Shioya, Okinawa','47'),('JP','SYG','Shioyagamoto','Shioyagamoto','46'),('JP','SYM','Sonoyama','Sonoyama','46'),('JP','SYO','Shoura','Shoura','46'),('JP','SYZ','Shiriyazaki','Shiriyazaki','02'),('JP','SZG','Shizugawa','Shizugawa','04'),('JP','SZI','Shinjima','Shinjima','46'),('JP','SZK','Senzaki','Senzaki','35'),('JP','SZU','Shizuura','Shizuura','22'),('JP','TAA','Takamijima','Takamijima','37'),('JP','TAB','Tabugawa','Tabugawa','46'),('JP','TAC','Tachiyama','Tachiyama','46'),('JP','TAD','Tadotsu','Tadotsu','37'),('JP','TAE','Tanabe','Tanabe','30'),('JP','TAG','Tagi','Tagi','32'),('JP','TAH','Takahama, Ehime','Takahama, Ehime','38'),('JP','TAI','Tamatsukuri','Tamatsukuri','08'),('JP','TAJ','Tajiri','Tajiri','46'),('JP','TAK','Takamatsu','Takamatsu','37'),('JP','TAL','Tainouchi','Tainouchi','34'),('JP','TAM','Tamano','Tamano','33'),('JP','TAN','Tanagawa','Tanagawa','27'),('JP','TAO','Tago','Tago','22'),('JP','TAQ','Taira','Taira','42'),('JP','TAR','Tahara','Tahara','34'),('JP','TAS','Takeshiki','Takeshiki','42'),('JP','TAT','Tatsugo','Tatsugo','46'),('JP','TAU','Taura','Taura','35'),('JP','TAW','Tannowa','Tannowa','27'),('JP','TAZ','Tai','Tai','26'),('JP','TBN','Tachibana','Tachibana','36'),('JP','TBO','Tobo','Tobo','41'),('JP','TBR','Tabira','Tabira','42'),('JP','TBS','Awajikoryunotsubasa','Awajikoryunotsubasa','28'),('JP','TBT','Tobata/Kitakyushu','Tobata/Kitakyushu','40'),('JP','TBU','Tabu','Tabu','35'),('JP','TCC','Tokuchi','Tokuchi','47'),('JP','TCH','Tsuchiura','Tsuchiura','08'),('JP','TDA','Tohda','Tohda','32'),('JP','TDJ','Takedatsu','Takedatsu','44'),('JP','TDN','Tadanoumi','Tadanoumi','34'),('JP','TDT','Tairadate','Tairadate','02'),('JP','TEA','Takena','Takena','32'),('JP','TEE','Take','Take','46'),('JP','TEI','Tei','Tei','39'),('JP','TEK','Tekutsuku','Tekutsuku','46'),('JP','TEN','Tendo','Tendo','06'),('JP','TER','Teuri','Teuri','01'),('JP','TET','Tateishi, Ehime','Tateishi, Ehime','38'),('JP','TEU','Teuchi','Teuchi','46'),('JP','TGC','Toguchi','Toguchi','46'),('JP','TGM','Taguma','Taguma','40'),('JP','TGO','Tagonoura','Tagonoura','22'),('JP','THA','Toyohira-ku','Toyohira-ku','01'),('JP','THM','Tanohama','Tanohama','03'),('JP','THR','Takehara','Takehara','34'),('JP','THS','Toyohashi','Toyohashi','23'),('JP','TIA','Taisha','Taisha','32'),('JP','TIN','Tainoura','Tainoura','42'),('JP','TIS','Teishi','Teishi','22'),('JP','TJI','Takarajima','Takarajima','46'),('JP','TJJ','Tomamae','Tomamae','01'),('JP','TJK','Takashima/Masuda','Takashima/Masuda','32'),('JP','TJM','Tojima','Tojima','38'),('JP','TJO','Toshima, Hyogo','Toshima, Hyogo','28'),('JP','TJR','Tajiri, Tottori','Tajiri, Tottori','31'),('JP','TJS','Tokashiki','Tokashiki','47'),('JP','TKA','Tokai','Tokai','23'),('JP','TKC','Takanokuchi','Takanokuchi','46'),('JP','TKD','Takada','Takada','44'),('JP','TKE','Takeno','Takeno','28'),('JP','TKG','Takasu, Kagoshima','Takasu, Kagoshima','46'),('JP','TKH','Takahama/Amakusa','Takahama/Amakusa','43'),('JP','TKI','Taki','Taki','17'),('JP','TKJ','Tokujin','Tokujin','47'),('JP','TKK','Takaoka','Takaoka','16'),('JP','TKM','Takuma','Takuma','37'),('JP','TKN','Tokunoshima','Tokunoshima','46'),('JP','TKO','Tokonami','Tokonami','42'),('JP','TKR','Tokoro','Tokoro','01'),('JP','TKS','Tokushima','Tokushima','36'),('JP','TKT','Taketoyo','Taketoyo','23'),('JP','TKU','Takuno','Takuno','32'),('JP','TKW','Tainokawa','Tainokawa','46'),('JP','TKY','Tokuyama','Tokuyama','35'),('JP','TKZ','Takezaki','Takezaki','42'),('JP','TMA','Tomari/Shiribeshi','Tomari/Shiribeshi','01'),('JP','TME','Tomie','Tomie','42'),('JP','TMI','Tsukumi','Tsukumi','44'),('JP','TMJ','Takami','Takami','37'),('JP','TMK','Tomakomai','Tomakomai','01'),('JP','TMM','Tomiku','Tomiku','44'),('JP','TMN','Tamanoura','Tamanoura','42'),('JP','TMO','Tomioka, Kumamoto','Tomioka, Kumamoto','43'),('JP','TMR','Tomari, Okinawa','Tomari, Okinawa','47'),('JP','TMS','Tamatsu, Ehime','Tamatsu, Ehime','38'),('JP','TMT','Tamatsu, Okayama','Tamatsu, Okayama','33'),('JP','TMU','Tomitsu','Tomitsu','43'),('JP','TMZ','Tarumizu','Tarumizu','46'),('JP','TNA','Tsuna','Tsuna','28'),('JP','TNB','Takanabe','Takanabe','45'),('JP','TND','Tonda','Tonda','35'),('JP','TNE','Tanegashima','Tanegashima','46'),('JP','TNH','Tonoshohigash','Tonoshohigash','37'),('JP','TNI','Tsuneishi','Tsuneishi','34'),('JP','TNK','Tanasoko','Tanasoko','43'),('JP','TNO','Tonosho','Tonosho','37'),('JP','TNR','Tanoura, Kumamoto','Tanoura, Kumamoto','43'),('JP','TNS','Tsunoshima','Tsunoshima','35'),('JP','TNU','Tanoura/Kitakyushu','Tanoura/Kitakyushu','40'),('JP','TNW','Tanowaki','Tanowaki','46'),('JP','TOB','Toba','Toba','24'),('JP','TOD','Todohokke','Todohokke','01'),('JP','TOG','Togi','Togi','17'),('JP','TOI','Toi','Toi','22'),('JP','TOJ','Toga','Toga','05'),('JP','TOK','Tokachi','Tokachi','01'),('JP','TOM','Tomioka, Tokushima','Tomioka, Tokushima','36'),('JP','TON','Tonoura','Tonoura','45'),('JP','TOR','Toride','Toride','08'),('JP','TOS','Toyamashinko','Toyamashinko','16'),('JP','TOT','Totoro','Totoro','45'),('JP','TOU','Touyo','Touyo','38'),('JP','TOX','Toshima/Tokyo','Toshima/Tokyo','13'),('JP','TOY','Toyama','Toyama','16'),('JP','TRA','Taramajima','Taramajima','47'),('JP','TRC','Tsuruuchi','Tsuruuchi','37'),('JP','TRD','Teradomari','Teradomari','15'),('JP','TRG','Tsuruga','Tsuruga','18'),('JP','TRH','Tarugahama','Tarugahama','42'),('JP','TRO','Tororo','Tororo','43'),('JP','TRR','Tomariura','Tomariura','39'),('JP','TRU','Tsurumi, Okayama','Tsurumi, Okayama','33'),('JP','TRZ','Terazu/Yatsuka','Terazu/Yatsuka','32'),('JP','TSA','Takasaki','Takasaki','10'),('JP','TSB','Tsukuba','Tsukuba','08'),('JP','TSG','Takasago','Takasago','28'),('JP','TSH','Tsushi','Tsushi','28'),('JP','TSI','Teshima','Teshima','37'),('JP','TSJ','Tsushima','Tsushima','42'),('JP','TSK','Tsurusaki','Tsurusaki','44'),('JP','TSM','Takashima/Nishisonogi','Takashima/Nishisonogi','42'),('JP','TSO','Teshio','Teshio','01'),('JP','TSS','Tasumi','Tasumi','32'),('JP','TST','Tsutsu','Tsutsu','42'),('JP','TSU','Tsu','Tsu','24'),('JP','TSX','Takeshima','Takeshima','46'),('JP','TSZ','Tosashimizu','Tosashimizu','39'),('JP','TTH','Taketomihigashi','Taketomihigashi','47'),('JP','TTJ','Tottori','Tottori','31'),('JP','TTM','Tsutsumi','Tsutsumi','32'),('JP','TTS','Tateishi, Kagawa','Tateishi, Kagawa','37'),('JP','TTU','Tokitsu','Tokitsu','42'),('JP','TTY','Tateyama','Tateyama','12'),('JP','TUD','Tsuda','Tsuda','37'),('JP','TUI','Tsui','Tsui','28'),('JP','TUR','Tanoura, Ehime','Tanoura, Ehime','38'),('JP','TUS','Toyoshige','Toyoshige','31'),('JP','TUU','Tsukumo','Tsukumo','34'),('JP','TWA','Tsukinokawa','Tsukinokawa','42'),('JP','TXK','Takasu, Fukui','Takasu, Fukui','18'),('JP','TXN','Tokoname','Tokoname','23'),('JP','TYA','Toyota','Toyota','23'),('JP','TYH','Toyohama, Kagawa','Toyohama, Kagawa','37'),('JP','TYJ','Toyohama, Aichi','Toyohama, Aichi','23'),('JP','TYN','Tsuiyama','Tsuiyama','28'),('JP','TYO','Tokyo','Tokyo','13'),('JP','TYP','Tsuyoshi','Tsuyoshi','42'),('JP','TYR','Toyoura','Toyoura','33'),('JP','TYU','Tayui','Tayui','42'),('JP','TZA','Taiza','Taiza','26'),('JP','TZU','Terazu/Matsue','Terazu/Matsue','32'),('JP','UAO','Urago','Urago','32'),('JP','UBJ','Ube','Ube','35'),('JP','UBK','Ushibuka','Ushibuka','43'),('JP','UBY','Ubuyu','Ubuyu','32'),('JP','UCH','Uchiumi','Uchiumi','45'),('JP','UCN','Uchinomi','Uchinomi','37'),('JP','UCR','Uchiura, Ishikawa','Uchiura, Ishikawa','17'),('JP','UCU','Uchiura, Fukui','Uchiura, Fukui','18'),('JP','UDD','Udo','Udo','46'),('JP','UDO','Udono','Udono','24'),('JP','UEC','Uechi','Uechi','47'),('JP','UGA','Uga','Uga','32'),('JP','UGU','Ugusu','Ugusu','22'),('JP','UHH','Uchihana','Uchihana','47'),('JP','UIA','Hakui','Hakui','17'),('JP','UJI','Ujina','Ujina','34'),('JP','UJY','Ujiyamada','Ujiyamada','24'),('JP','UKA','Usuka','Usuka','42'),('JP','UKB','Kobe','Kobe','28'),('JP','UKI','Ukui','Ukui','30'),('JP','UKJ','Ukejima','Ukejima','46'),('JP','UKN','Uken','Uken','46'),('JP','UKT','Ukitsu','Ukitsu','46'),('JP','UKY','Kyoto','Kyoto','26'),('JP','UMG','Umagoe','Umagoe','37'),('JP','UNM','Uranomae','Uranomae','46'),('JP','UNO','Uno','Uno','33'),('JP','UNS','Unoshima','Unoshima','40'),('JP','UNT','Unten','Unten','47'),('JP','UNU','Uchinourahetsuka','Uchinourahetsuka','46'),('JP','UOM','Uomi','Uomi','46'),('JP','UOU','Uozu, Shimane','Uozu, Shimane','32'),('JP','UOZ','Uozu, Toyama','Uozu, Toyama','16'),('JP','URA','Ura','Ura','28'),('JP','URG','Uraga','Uraga','14'),('JP','URH','Urahara','Urahara','46'),('JP','URK','Urakawa','Urakawa','01'),('JP','URM','Uragami','Uragami','30'),('JP','URR','Urashiro','Urashiro','44'),('JP','URS','Urasoko','Urasoko','46'),('JP','URU','Furumi','Furumi','32'),('JP','USA','Usa/Tosa','Usa/Tosa','39'),('JP','USG','Ushigakubijima','Ushigakubijima','37'),('JP','USH','Ushimado','Ushimado','33'),('JP','USI','Ushine','Ushine','46'),('JP','USJ','Usujiri','Usujiri','01'),('JP','USK','Usuki','Usuki','44'),('JP','USN','Usuno','Usuno','44'),('JP','UST','Ushitsu','Ushitsu','17'),('JP','USU','Usunoura','Usunoura','42'),('JP','UTM','Utsumi, Aichi','Utsumi, Aichi','23'),('JP','UTO','Utsunomiya','Utsunomiya','09'),('JP','UTS','Utsumi, Hiroshima','Utsumi, Hiroshima','34'),('JP','UTZ','Utazu','Utazu','37'),('JP','UUR','Uchinoura','Uchinoura','46'),('JP','UWA','Uwajima','Uwajima','38'),('JP','UYA','Urayasu','Urayasu','12'),('JP','UZK','Uzuki','Uzuki','32'),('JP','WAD','Wadomari','Wadomari','46'),('JP','WAI','Waita','Waita','35'),('JP','WAK','Wakayama','Wakayama','30'),('JP','WAM','Wakamatsu/Kitakyushu','Wakamatsu/Kitakyushu','40'),('JP','WAN','Wan','Wan','46'),('JP','WAT','Watanoha','Watanoha','04'),('JP','WDA','Wada','Wada','18'),('JP','WJM','Wajima','Wajima','17'),('JP','WKI','Wakimisaki','Wakimisaki','42'),('JP','WKJ','Wakkanai','Wakkanai','01'),('JP','WKR','Wakura','Wakura','17'),('JP','WKT','Wakatsu','Wakatsu','40'),('JP','WKW','Wakinosawa','Wakinosawa','02'),('JP','WKZ','Wakizaki','Wakizaki','46'),('JP','WMT','Wakimoto','Wakimoto','38'),('JP','WNA','Wano','Wano','46'),('JP','WNI','Waniura','Waniura','42'),('JP','WSB','Washibeyanoura','Washibeyanoura','34'),('JP','WTU','Wakamatsu, Nagasaki','Wakamatsu, Nagasaki','42'),('JP','YAA','Yanagi','Yanagi','43'),('JP','YAD','Yamada, Iwate','Yamada, Iwate','03'),('JP','YAE','Yaeyama Island','Yaeyama Island','47'),('JP','YAG','Yagi, Hyogo','Yagi, Hyogo','28'),('JP','YAM','Yamagawa','Yamagawa','46'),('JP','YAN','Yanai','Yanai','35'),('JP','YAS','Yasumiya','Yasumiya','02'),('JP','YAT','Yatsushiro','Yatsushiro','43'),('JP','YBK','Yobuko','Yobuko','41'),('JP','YBT','Yubetsu','Yubetsu','01'),('JP','YCH','Yachiyo','Yachiyo','12'),('JP','YDA','Yoshida, Aichi','Yoshida, Aichi','23'),('JP','YDM','Yudomari','Yudomari','46'),('JP','YGE','Yuge','Yuge','38'),('JP','YGH','Yamaguchihigashi','Yamaguchihigashi','35'),('JP','YGI','Yagi, Iwate','Yagi, Iwate','03'),('JP','YGJ','Yonago','Yonago','31'),('JP','YGR','Yagishiri','Yagishiri','01'),('JP','YHA','Yoshiura/Yunotsu','Yoshiura/Yunotsu','32'),('JP','YHI','Yoshiumi','Yoshiumi','38'),('JP','YIC','Yoichi','Yoichi','01'),('JP','YKI','Yuki','Yuki','08'),('JP','YKK','Yokkaichi','Yokkaichi','24'),('JP','YKS','Yokoshima/Kurahashi','Yokoshima/Kurahashi','34'),('JP','YKT','Yokota, Hiroshima','Yokota, Hiroshima','34'),('JP','YKU','Yakuzu','Yakuzu','46'),('JP','YMA','Yasurahama','Yasurahama','46'),('JP','YMC','Yumachi','Yumachi','32'),('JP','YMD','Yamada, Okayama','Yamada, Okayama','33'),('JP','YMG','Yamaguchi','Yamaguchi','35'),('JP','YMN','Yamanoura','Yamanoura','43'),('JP','YMT','Yamatani','Yamatani','32'),('JP','YMU','Yumugi','Yumugi','46'),('JP','YNE','Yaene','Yaene','13'),('JP','YNI','Yani','Yani','46'),('JP','YNM','Yunomochiki','Yunomochiki','46'),('JP','YNN','Yanma','Yanma','46'),('JP','YNS','Yamanashi','Yamanashi','19'),('JP','YNT','Yunotsu','Yunotsu','32'),('JP','YNZ','Yonouzu','Yonouzu','44'),('JP','YOC','Yoichigaura','Yoichigaura','43'),('JP','YOG','Yonegura','Yonegura','33'),('JP','YOK','Yokohama','Yokohama','14'),('JP','YOR','Yoro','Yoro','46'),('JP','YOS','Yokosuka','Yokosuka','14'),('JP','YOT','Yotsukura','Yotsukura','07'),('JP','YOU','Youra','Youra','44'),('JP','YQD','Yamada','Yamada','28'),('JP','YRA','Yura, Hyogo','Yura, Hyogo','28'),('JP','YRG','Yurigahama','Yurigahama','46'),('JP','YSD','Yoshida, Ehime','Yoshida, Ehime','38'),('JP','YSG','Yasugi','Yasugi','32'),('JP','YSH','Yuasahiro','Yuasahiro','30'),('JP','YSM','Yoshima','Yoshima','37'),('JP','YSN','Yoshinozaki','Yoshinozaki','37'),('JP','YSR','Yoshiura/Misumi','Yoshiura/Misumi','32'),('JP','YSS','Yoshiase','Yoshiase','34'),('JP','YSU','Yoshiura','Yoshiura','34'),('JP','YSZ','Yoshizu','Yoshizu','24'),('JP','YTI','Yutai','Yutai','38'),('JP','YUA','Yura, Yamaguchi','Yura, Yamaguchi','35'),('JP','YUJ','Yura, Yamagata','Yura, Yamagata','06'),('JP','YUK','Yuki','Yuki','36'),('JP','YUR','Yura, Wakayama','Yura, Wakayama','30'),('JP','YUS','Yusu','Yusu','38'),('JP','YUU','Yuu','Yuu','35'),('JP','YUZ','Yuza','Yuza','06'),('JP','YWH','Yawatahama','Yawatahama','38'),('JP','YWN','Yuwan','Yuwan','46'),('JP','YWT','Yawata/Kitakyushu','Yawata/Kitakyushu','40'),('JP','YYA','Awano','Awano','35'),('JP','YZU','Yaizu','Yaizu','22'),('JP','ZAM','Zama','Zama','14'),('JP','ZMM','Zamami','Zamami','47'),('KE','','','',''),('KE','ASV','Amboseli','Amboseli',''),('KE','BMQ','Bamburi','Bamburi',''),('KE','EDL','Eldoret','Eldoret',''),('KE','EMB','Embakasi','Embakasi',''),('KE','EYS','Eliye Springs','Eliye Springs',''),('KE','FER','Fergusons Gulf','Fergusons Gulf',''),('KE','GAS','Garissa','Garissa',''),('KE','HOA','Hola','Hola',''),('KE','ILU','Kilaguni','Kilaguni',''),('KE','KAJ','Kajiado','Kajiado',''),('KE','KAK','Kakamega','Kakamega',''),('KE','KEY','Kericho','Kericho',''),('KE','KIL','Kilindini','Kilindini',''),('KE','KIS','Kisumu','Kisumu',''),('KE','KIU','Kiunga','Kiunga',''),('KE','KLK','Kalokol','Kalokol',''),('KE','KRV','Kerio Valley','Kerio Valley',''),('KE','KTL','Kitale','Kitale',''),('KE','KWY','Kiwayu','Kiwayu',''),('KE','LAU','Lamu','Lamu',''),('KE','LBK','Liboi','Liboi',''),('KE','LBN','Lake Baringo','Lake Baringo',''),('KE','LKG','Lokichoggio','Lokichoggio',''),('KE','LKU','Lake Rudolf','Lake Rudolf',''),('KE','LOK','Lodwar','Lodwar',''),('KE','LOY','Loyangalani','Loyangalani',''),('KE','MAL','Malaba','Malaba',''),('KE','MBA','Mombasa','Mombasa',''),('KE','MRE','Mara Lodges','Mara Lodges',''),('KE','MUM','Mumias','Mumias',''),('KE','MYD','Malindi','Malindi',''),('KE','NAR','Narok','Narok',''),('KE','NBO','Nairobi','Nairobi',''),('KE','NDE','Mandera','Mandera',''),('KE','NUU','Nakuru','Nakuru',''),('KE','NYE','Nyeri','Nyeri',''),('KE','NYK','Nanyuki','Nanyuki',''),('KE','NZO','Nzoia','Nzoia',''),('KE','OYL','Moyale','Moyale',''),('KE','RBT','Marsabit','Marsabit',''),('KE','SOT','Sotik','Sotik',''),('KE','THK','Thika','Thika',''),('KE','UAS','Samburu','Samburu',''),('KE','UKA','Ukunda','Ukunda',''),('KE','WIL','Wilson Apt/Nairobi','Wilson Apt/Nairobi',''),('KE','WJR','Wajir','Wajir',''),('KG','','','',''),('KG','ALA','Alamedin','Alamedin',''),('KG','BYK','Balykchy','Balykchy',''),('KG','FRU','Bishkek (ex Frunze)','Bishkek (ex Frunze)',''),('KG','JLD','Jalal-Abad','Jalal-Abad',''),('KG','OSS','Osh','Osh',''),('KH','','','',''),('KH','BBM','Battambang','Battambang',''),('KH','CHE','Cheko','Cheko',''),('KH','KKO','Kas Kong','Kas Kong',''),('KH','KKZ','Koh Kong','Koh Kong',''),('KH','KMT','Kampot','Kampot',''),('KH','KOS','Kampong Saom','Kampong Saom',''),('KH','KTI','Kratie','Kratie',''),('KH','KZC','Kampong Chhnang','Kampong Chhnang',''),('KH','KZD','Krakor','Krakor',''),('KH','KZK','Kompong Thom','Kompong Thom',''),('KH','MWV','Mundulkiri','Mundulkiri',''),('KH','OMY','Oddor Meanche','Oddor Meanche',''),('KH','PAI','Pailin','Pailin',''),('KH','PNH','Phnom Penh','Phnom Penh',''),('KH','PPT','Paoy Pet (Poipet)','Paoy Pet (Poipet)',''),('KH','RBE','Ratanakiri','Ratanakiri',''),('KH','REP','Siem Reap','Siem Reap',''),('KH','SVR','Svay Rieng','Svay Rieng',''),('KH','TNX','Stung Treng','Stung Treng',''),('KI','','','',''),('KI','AAK','Aranuka','Aranuka',''),('KI','ABF','Abaiang','Abaiang',''),('KI','AEA','Abemama','Abemama',''),('KI','AIS','Arorae Island','Arorae Island',''),('KI','BBG','Butaritari','Butaritari',''),('KI','BEZ','Beru','Beru',''),('KI','CIS','Canton Island','Canton Island',''),('KI','CXI','Christmas Island','Christmas Island',''),('KI','FIS','Fanning Islands','Fanning Islands',''),('KI','KUC','Kuria','Kuria',''),('KI','MNK','Maiana','Maiana',''),('KI','MTK','Makin Island','Makin Island',''),('KI','MZK','Marakei','Marakei',''),('KI','NIG','Nikunau','Nikunau',''),('KI','NON','Nonouti','Nonouti',''),('KI','OOT','Onotoa','Onotoa',''),('KI','PHO','Phoenix Islands','Phoenix Islands',''),('KI','TBF','Tabiteuea North','Tabiteuea North',''),('KI','TMN','Tamana Island','Tamana Island',''),('KI','TNQ','Teraina','Teraina',''),('KI','TNV','Tabuaeran','Tabuaeran',''),('KI','TRW','Tarawa','Tarawa',''),('KI','TSU','Tabiteuea South','Tabiteuea South',''),('KI','WNI','Washington Islands','Washington Islands',''),('KM','','','',''),('KM','AJN','Anjouan Apt','Anjouan Apt','A'),('KM','FOU','Foumboni, Moheli','Foumboni, Moheli',''),('KM','HAH','Hahaya Apt/Moroni','Hahaya Apt/Moroni',''),('KM','MUT','Mutsamudu, Anjouan','Mutsamudu, Anjouan','A'),('KM','NWA','Moheli Apt','Moheli Apt','M'),('KM','YVA','Moroni','Moroni',''),('KN','','','',''),('KN','BAS','Basseterre, St Kitts','Basseterre, St Kitts',''),('KN','NEV','Charlestown, Nevis','Charlestown, Nevis',''),('KN','SKB','St Kitts','St Kitts',''),('KP','','','',''),('KP','CHO','Chongjin','Chongjin',''),('KP','FNJ','Pyongyang','Pyongyang',''),('KP','GEN','Gensan','Gensan',''),('KP','HAE','Haeju','Haeju',''),('KP','HGM','Hungnam','Hungnam',''),('KP','KSN','Kaesong','Kaesong',''),('KP','NAM','Nampo','Nampo',''),('KP','NJN','Najin','Najin',''),('KP','ODA','Odaejin','Odaejin',''),('KP','PNG','Panjang','Panjang',''),('KP','REM','Bumpyo (Rempo)','Bumpyo (Rempo)',''),('KP','RIW','Riwon','Riwon',''),('KP','SAM','Samcha do','Samcha do',''),('KP','SII','Sinuiju','Sinuiju',''),('KP','SIN','Sinpo','Sinpo',''),('KP','SON','Songjin','Songjin',''),('KP','WON','Wonsan','Wonsan',''),('KR','','','',''),('KR','ADG','Andong','Andong','47'),('KR','ANS','Ansung','Ansung','41'),('KR','ANY','Anyang','Anyang','41'),('KR','ASA','Asan','Asan','44'),('KR','ASG','Anseong','Anseong','41'),('KR','ASN','Ansan','Ansan','41'),('KR','BAA','BALAN/Hwaseoung','BALAN/Hwaseoung','41'),('KR','BAN','Buan-gun','Buan-gun','45'),('KR','BCN','Bucheon','Bucheon','41'),('KR','BDE','Bongdong-eup/Wanju-gun','Bongdong-eup/Wanju-gun','45'),('KR','BEN','Boeun-gun','Boeun-gun','43'),('KR','BHA','Bonghwa-gun','Bonghwa-gun','47'),('KR','BJJ','Bukjeju-gun','Bukjeju-gun','49'),('KR','BOR','Boryeong','Boryeong','44'),('KR','BSG','Boseong-gun','Boseong-gun','46'),('KR','BUK','Bupyong/Incheon','Bupyong/Incheon','28'),('KR','BYO','Buyeo-gun','Buyeo-gun','44'),('KR','CDO','Cheongdo-gun','Cheongdo-gun','47'),('KR','CGK','Chilgok-gun','Chilgok-gun','47'),('KR','CHA','Jeju','Jeju','49'),('KR','CHC','Chuncheon','Chuncheon','42'),('KR','CHF','Jinhae','Jinhae','48'),('KR','CHG','Janghang/Seocheon-gun','Janghang/Seocheon-gun','44'),('KR','CHI','Chonui/Yeongi-gun','Chonui/Yeongi-gun','44'),('KR','CHN','Chonju','Chonju','45'),('KR','CHO','Cheonan','Cheonan','44'),('KR','CHU','Chungju','Chungju','43'),('KR','CHW','Changwon','Changwon','48'),('KR','CJJ','Cheongju Apt','Cheongju Apt','43'),('KR','CNG','Changnyeong-gun','Changnyeong-gun','48'),('KR','COJ','Chongju','Chongju','43'),('KR','CSG','Cheongsong-gun','Cheongsong-gun','47'),('KR','CWN','Cheorwon-gun','Cheorwon-gun','42'),('KR','CWO','Cheongwon-gun','Cheongwon-gun','43'),('KR','CYG','Cheongyang-gun','Cheongyang-gun','44'),('KR','DBL','Daebul/Yeongam-gun','Daebul/Yeongam-gun','46'),('KR','DDC','Dongducheon','Dongducheon','41'),('KR','DDO','Dokdo','Dokdo','47'),('KR','DRS','Dorasan/Paju','Dorasan/Paju','41'),('KR','DSG','Dalseong-gun/Daegu','Dalseong-gun/Daegu','27'),('KR','DYA','Damyang-gun','Damyang-gun','46'),('KR','DYG','Danyang-gun','Danyang-gun','43'),('KR','ESG','Eumseong-gun','Eumseong-gun','43'),('KR','GCG','Gochang-gun','Gochang-gun','45'),('KR','GCH','Geochang-gun','Geochang-gun','48'),('KR','GCN','Gwacheon','Gwacheon','41'),('KR','GHA','Ganghwa-gun/Incheon','Ganghwa-gun/Incheon','28'),('KR','GHG','Goheung-gun','Goheung-gun','46'),('KR','GJE','Gimje','Gimje','45'),('KR','GJG','Gijang-gun/Busan','Gijang-gun/Busan','26'),('KR','GJN','Gangjin-gun','Gangjin-gun','46'),('KR','GJU','Gyeongju','Gyeongju','47'),('KR','GMG','Gwangmyeong','Gwangmyeong','41'),('KR','GMP','Gimpo','Gimpo','41'),('KR','GOJ','Gongju','Gongju','44'),('KR','GPG','Gapyeong-gun','Gapyeong-gun','41'),('KR','GRE','Gurye-gun','Gurye-gun','46'),('KR','GRG','Goryeong-gun','Goryeong-gun','47'),('KR','GRI','Guri','Guri','41'),('KR','GSA','Geumsan-gun','Geumsan-gun','44'),('KR','GSE','Gokseong-gun','Gokseong-gun','46'),('KR','GSG','Goseong-gun','Goseong-gun','42'),('KR','GSN','Goesan-gun','Goesan-gun','43'),('KR','GSO','Goseong-gun','Goseong-gun','47'),('KR','GUN','Gunpo','Gunpo','41'),('KR','GWI','Gunwi-gun','Gunwi-gun','47'),('KR','GYG','Goyang','Goyang','41'),('KR','GYS','Gyeongsan','Gyeongsan','47'),('KR','HAN','Haman-gun','Haman-gun','48'),('KR','HCE','Hapcheon-gun','Hapcheon-gun','48'),('KR','HCH','Hwacheon-gun','Hwacheon-gun','42'),('KR','HCN','Hongcheon-gun','Hongcheon-gun','42'),('KR','HDG','Hadong-gun','Hadong-gun','48'),('KR','HDM','Hyeondo-myeon/Cheongwon-gun','Hyeondo-myeon/Cheongwon-gun','43'),('KR','HIN','Jinju','Jinju','48'),('KR','HNM','Hanam','Hanam','41'),('KR','HPG','Hampyeong-gun','Hampyeong-gun','46'),('KR','HSE','Hongseong-gun','Hongseong-gun','44'),('KR','HSG','Hoengseong-gun','Hoengseong-gun','42'),('KR','HSN','Hwasun-gun','Hwasun-gun','49'),('KR','HYG','Hamyang-gun','Hamyang-gun','48'),('KR','HYP','Hyeonpoong/Daegu','Hyeonpoong/Daegu','27'),('KR','ICE','Icheon','Icheon','41'),('KR','ICH','Incheon','Incheon','28'),('KR','ICN','Incheon Intl Apt/Seoul','Incheon Intl Apt/Seoul','28'),('KR','IJE','Inje-gun','Inje-gun','42'),('KR','IKS','Iksan','Iksan','45'),('KR','ISL','Imsil-gun','Imsil-gun','45'),('KR','JAN','Jinan-gun','Jinan-gun','45'),('KR','JCH','Jecheon','Jecheon','43'),('KR','JCN','Jincheon-gun','Jincheon-gun','43'),('KR','JCW','Jochiwon-eup/Yeongi-gun','Jochiwon-eup/Yeongi-gun','44'),('KR','JDO','Jindo-gun','Jindo-gun','46'),('KR','JEO','Jeongeup','Jeongeup','45'),('KR','JGE','Geoje','Geoje','48'),('KR','JHG','Jangheung-gun','Jangheung-gun','46'),('KR','JNJ','Jeonju','Jeonju','45'),('KR','JSE','Jeongseon-gun','Jeongseon-gun','42'),('KR','JSN','Jangseong/Jangseong-gun','Jangseong/Jangseong-gun','46'),('KR','JSU','Jangsu-gun','Jangsu-gun','45'),('KR','JYG','Jeungpyeung','Jeungpyeung','43'),('KR','KAG','Gangneung','Gangneung','42'),('KR','KAN','Gwangyang','Gwangyang','46'),('KR','KCN','Gamcheon/Busan','Gamcheon/Busan','26'),('KR','KHN','Gohyeon/Geoje','Gohyeon/Geoje','48'),('KR','KJE','Geoje','Geoje','48'),('KR','KMC','Gimcheon','Gimcheon','47'),('KR','KMH','Gimhae','Gimhae','48'),('KR','KMP','Kimpo','Kimpo','41'),('KR','KPO','Pohang','Pohang','47'),('KR','KUM','Gumi','Gumi','47'),('KR','KUV','Gunsan','Gunsan','45'),('KR','KWJ','Gwangju','Gwangju','29'),('KR','KWU','Gwangju','Gwangju','41'),('KR','MAN','Muan-gun','Muan-gun','46'),('KR','MAS','Masan','Masan','48'),('KR','MGG','Mungyeong','Mungyeong','47'),('KR','MIP','Mipo/Ulsan','Mipo/Ulsan','31'),('KR','MJU','Muju-gun','Muju-gun','45'),('KR','MOK','Mokpo','Mokpo','46'),('KR','MPK','Mokpo Apt','Mokpo Apt','46'),('KR','MSN','Munsan/Paju','Munsan/Paju','41'),('KR','MUK','Mukho/Donghae','Mukho/Donghae','42'),('KR','NHE','Namhae-gun','Namhae-gun','48'),('KR','NJU','Naju','Naju','46'),('KR','NSN','Nonsan','Nonsan','44'),('KR','NWN','Namwon','Namwon','45'),('KR','NYJ','Namyang/Goheung-gun','Namyang/Goheung-gun','46'),('KR','NYU','Namyangju','Namyangju','41'),('KR','OCH','Ochang','Ochang','43'),('KR','OCN','Okcheon-gun','Okcheon-gun','43'),('KR','OKK','Okgye/Gangneung','Okgye/Gangneung','42'),('KR','OKP','Okpo/Geoje','Okpo/Geoje','48'),('KR','ONS','Onsan/Ulsan','Onsan/Ulsan','31'),('KR','OSN','Osan','Osan','41'),('KR','PCG','Pyeongchang-gun','Pyeongchang-gun','42'),('KR','PJU','Paju','Paju','41'),('KR','PMJ','Panmoonjeom','Panmoonjeom','41'),('KR','POC','Pocheon','Pocheon','41'),('KR','PTK','Pyeongtaek','Pyeongtaek','41'),('KR','PUS','Busan','Busan','26'),('KR','QET','Daedeok/Dawjeon','Daedeok/Dawjeon','30'),('KR','RSU','Yeosu Apt','Yeosu Apt','46'),('KR','SAH','Sacheon','Sacheon','48'),('KR','SAN','Sinan-gun','Sinan-gun','46'),('KR','SCE','Seocheon-gun','Seocheon-gun','44'),('KR','SCG','Sunchang-gun','Sunchang-gun','45'),('KR','SCH','Sancheong-gun','Sancheong-gun','48'),('KR','SCN','Seocheon-gun','Seocheon-gun','44'),('KR','SCP','Samcheonpo/Sacheon','Samcheonpo/Sacheon','48'),('KR','SEJ','Seongju-gun','Seongju-gun','47'),('KR','SEL','Seoul','Seoul','11'),('KR','SHE','Siheung','Siheung','41'),('KR','SHG','Sinhang/Pohang','Sinhang/Pohang','48'),('KR','SHO','Sokcho','Sokcho','42'),('KR','SIG','Siheung-dong/Seoul','Siheung-dong/Seoul','11'),('KR','SJU','Sangju','Sangju','47'),('KR','SPO','Seogwipo','Seogwipo','49'),('KR','SSA','Seosan','Seosan','44'),('KR','SSN','Sungnam (Seoul Ab)','Sungnam (Seoul Ab)','41'),('KR','SSP','Seongsan-po/Namjeju-gun','Seongsan-po/Namjeju-gun','49'),('KR','SUK','Samcheok','Samcheok','42'),('KR','SUO','Suwon','Suwon','41'),('KR','SWU','Suwon Apt','Suwon Apt','41'),('KR','SYS','Suncheon','Suncheon','46'),('KR','TAE','Daegu','Daegu','27'),('KR','TAN','Taean-gun','Taean-gun','44'),('KR','TBK','Taebaek','Taebaek','42'),('KR','TGH','Donghae','Donghae','42'),('KR','TJI','Dangjin-gun','Dangjin-gun','44'),('KR','TJN','Daejeon','Daejeon','30'),('KR','TSN','Daesan/Seosan','Daesan/Seosan','44'),('KR','TYG','Tongyeong','Tongyeong','48'),('KR','UIJ','Uijeongbu','Uijeongbu','41'),('KR','UJN','Uljin-gun','Uljin-gun','47'),('KR','UJU','Ulju-gun/Ulsan','Ulju-gun/Ulsan','31'),('KR','ULG','Ulleung-gun','Ulleung-gun','47'),('KR','URG','Uiryeong-gun','Uiryeong-gun','48'),('KR','USG','Uiseong-gun','Uiseong-gun','47'),('KR','USN','Ulsan','Ulsan','31'),('KR','UWN','Uiwang','Uiwang','41'),('KR','WAJ','Wanju-gun','Wanju-gun','45'),('KR','WJU','Wonju','Wonju','42'),('KR','WND','Wando-gun','Wando-gun','46'),('KR','YAM','Yeongam-gun','Yeongam-gun','46'),('KR','YCH','Yeongcheon','Yeongcheon','47'),('KR','YCN','Yeoncheon-gun','Yeoncheon-gun','41'),('KR','YDG','Yeongdong-gun','Yeongdong-gun','43'),('KR','YDK','Yeongdeok-gun','Yeongdeok-gun','47'),('KR','YEC','Yecheon-gun','Yecheon-gun','47'),('KR','YEJ','Yeongju','Yeongju','47'),('KR','YGG','Yeonggwang-gun','Yeonggwang-gun','46'),('KR','YGI','Yeongi-gun','Yeongi-gun','44'),('KR','YGU','Yanggu-gun','Yanggu-gun','42'),('KR','YJU','Yeoju-gun','Yeoju-gun','41'),('KR','YNG','Yongin','Yongin','41'),('KR','YNY','Yangyang-gun','Yangyang-gun','42'),('KR','YOC','Yochon','Yochon','47'),('KR','YON','Yongi','Yongi','45'),('KR','YOS','Yeosu','Yeosu','46'),('KR','YPG','Yangpyeong-gun','Yangpyeong-gun','41'),('KR','YSN','Yangsan','Yangsan','48'),('KR','YWL','Yeongwol-gun','Yeongwol-gun','42'),('KR','YYG','Yeongyang-gun','Yeongyang-gun','47'),('KR','YYU','Yangju-gun','Yangju-gun','41'),('KW','','','',''),('KW','ABD','Al \'Abdaliyah','Al \'Abdaliyah',''),('KW','AHJ','Ahmed Al Jaber','Ahmed Al Jaber',''),('KW','AIS','Ali al Salem AB','Ali al Salem AB',''),('KW','CAJ','Camp Arifjan','Camp Arifjan',''),('KW','CDH','Camp Doha','Camp Doha',''),('KW','JAH','Jahran','Jahran',''),('KW','JBD','Jebel Dhana','Jebel Dhana',''),('KW','KWI','Kuwait','Kuwait',''),('KW','KWM','Khor al Mufatta','Khor al Mufatta',''),('KW','MAM','Mina Alo Manti','Mina Alo Manti',''),('KW','MEA','Mina\' al Ahmadi','Mina\' al Ahmadi',''),('KW','MIB','Mina\' \'Abd Allah','Mina\' \'Abd Allah',''),('KW','MIS','Mina Saud','Mina Saud',''),('KW','SAA','Shuaiba','Shuaiba',''),('KW','SAF','Safat','Safat',''),('KW','SAL','As Salimiyah','As Salimiyah',''),('KW','SWK','Shuwaikh','Shuwaikh',''),('KW','SYA','As Saba?iyah','As Saba?iyah',''),('KW','WAF','Al Wafrah','Al Wafrah',''),('KY','','','',''),('KY','CYB','Cayman Brac','Cayman Brac',''),('KY','GCM','Grand Cayman','Grand Cayman',''),('KY','GEC','Georgetown, Grand Cayman','Georgetown, Grand Cayman',''),('KY','LYB','Little Cayman','Little Cayman',''),('KZ','','','',''),('KZ','AAU','Aktau','Aktau',''),('KZ','ABE','Aktobe','Aktobe',''),('KZ','AKS','Aksay','Aksay',''),('KZ','AKX','Aqtobe (Aktyubinsk)','Aqtobe (Aktyubinsk)',''),('KZ','ALA','Almaty','Almaty',''),('KZ','ALS','Alashankou','Alashankou',''),('KZ','AST','Astana (ex Tselinograd)','Astana (ex Tselinograd)',''),('KZ','ATX','Atbasar','Atbasar',''),('KZ','AYK','Arkalyk','Arkalyk',''),('KZ','BXH','Balhash','Balhash',''),('KZ','BXJ','Burundai','Burundai',''),('KZ','CIT','Shimkent','Shimkent',''),('KZ','DMB','Zhambyl','Zhambyl',''),('KZ','DZH','Dzhambul','Dzhambul',''),('KZ','DZN','Zhezkazgan','Zhezkazgan',''),('KZ','EKB','Ekibastuz','Ekibastuz',''),('KZ','GUW','Atyrau (ex Guryev)','Atyrau (ex Guryev)',''),('KZ','HOR','Horgos','Horgos',''),('KZ','HRC','Zhairem','Zhairem',''),('KZ','KGF','Karaganda','Karaganda',''),('KZ','KOR','Kordai','Kordai',''),('KZ','KOV','Kokshetau','Kokshetau',''),('KZ','KSN','Kostanay','Kostanay',''),('KZ','KUL','Kul\'sary','Kul\'sary',''),('KZ','KYH','Kandyagash','Kandyagash',''),('KZ','KZO','Kzyl-Orda','Kzyl-Orda',''),('KZ','LKK','Lisakovsk','Lisakovsk',''),('KZ','PLX','Semey (Semipalatinsk)','Semey (Semipalatinsk)',''),('KZ','PPK','Petropavlovsk','Petropavlovsk',''),('KZ','PWQ','Pavlodar','Pavlodar',''),('KZ','SCK','Shchuchinsk','Shchuchinsk',''),('KZ','SHU','Shubarkuduk','Shubarkuduk',''),('KZ','SRY','Saryagach','Saryagach',''),('KZ','SZI','Zaisan','Zaisan',''),('KZ','TDK','Taldy-Kurgan','Taldy-Kurgan',''),('KZ','UKK','Ust-Kamenogorsk','Ust-Kamenogorsk',''),('KZ','URA','Uralsk','Uralsk',''),('KZ','UZE','Uzen','Uzen',''),('KZ','ZYR','Zyryanovsk','Zyryanovsk',''),('LA','','','',''),('LA','AOU','Attopeu','Attopeu',''),('LA','HOE','Houeisay','Houeisay',''),('LA','KOG','Khong','Khong',''),('LA','LPQ','Luang Prabang','Luang Prabang',''),('LA','LXG','Luang Namtha','Luang Namtha',''),('LA','NEU','Sam Neua','Sam Neua',''),('LA','ODY','Oudomxay','Oudomxay',''),('LA','OUI','Ban Houei','Ban Houei',''),('LA','PKS','Paksane','Paksane',''),('LA','PKZ','Pakxe','Pakxe',''),('LA','SAV','Savannakhet','Savannakhet',''),('LA','SND','Seno','Seno',''),('LA','THG','Thanaleng','Thanaleng',''),('LA','THK','Thakhek','Thakhek',''),('LA','TLE','Thanalouang','Thanalouang',''),('LA','UDO','Udomxay','Udomxay',''),('LA','UON','Muong Sai','Muong Sai',''),('LA','VAN','Vangtoud','Vangtoud',''),('LA','VGG','Vangrieng','Vangrieng',''),('LA','VNA','Saravane','Saravane',''),('LA','VNG','Viengxay','Viengxay',''),('LA','VTE','Vientiane','Vientiane',''),('LA','XAY','Xayabury','Xayabury',''),('LA','XIE','Xienglom','Xienglom',''),('LA','XKH','Xieng Khouang','Xieng Khouang',''),('LA','ZBY','Sayaboury','Sayaboury',''),('LB','','','',''),('LB','BEY','Beirut','Beirut',''),('LB','BFZ','Beirut Free Zone','Beirut Free Zone',''),('LB','CHK','Chekka','Chekka',''),('LB','JIE','Jieh','Jieh',''),('LB','KHA','Khalde','Khalde',''),('LB','KYE','Tripoli','Tripoli',''),('LB','NAQ','En Naqoura','En Naqoura',''),('LB','OUZ','Ouzai','Ouzai',''),('LB','QJN','Jounieh','Jounieh',''),('LB','RST','Ras Selata','Ras Selata',''),('LB','SAY','Sayda','Sayda',''),('LB','SEL','Selaata','Selaata',''),('LB','SUR','Sur (Tyre)','Sur (Tyre)',''),('LB','ZHR','Zahrani Terminal','Zahrani Terminal',''),('LC','','','',''),('LC','CAS','Castries','Castries',''),('LC','CDS','Cul de Sac','Cul de Sac',''),('LC','SLU','St Lucia Apt','St Lucia Apt',''),('LC','VIF','Vieux Fort','Vieux Fort',''),('LI','','','',''),('LI','BAZ','Balzers','Balzers',''),('LI','RGL','Ruggell','Ruggell',''),('LI','SCH','Schaanwald','Schaanwald',''),('LI','SCN','Schaan','Schaan',''),('LI','TES','Triesen','Triesen',''),('LI','VDZ','Vaduz','Vaduz',''),('LK','','','',''),('LK','ADP','Anuradhapura','Anuradhapura',''),('LK','BRW','Beruwala','Beruwala',''),('LK','BTC','Batticoloa','Batticoloa',''),('LK','CMB','Colombo','Colombo',''),('LK','GAL','Galle','Galle',''),('LK','GOY','Gal Oya','Gal Oya',''),('LK','HAT','Hatton','Hatton',''),('LK','HBA','Hambantota','Hambantota',''),('LK','JAF','Jaffna','Jaffna',''),('LK','JCT','Jaya Container Terminal','Jaya Container Terminal',''),('LK','KAL','Kalpitiya','Kalpitiya',''),('LK','KAN','Kandy','Kandy',''),('LK','KAT','Katunayake','Katunayake',''),('LK','KAY','Kayts','Kayts',''),('LK','KIL','Kilinochchi','Kilinochchi',''),('LK','KLT','Kalutara','Kalutara',''),('LK','KNK','Kankesanturai','Kankesanturai',''),('LK','KNW','Konwelana','Konwelana',''),('LK','KON','Kondavattavan','Kondavattavan',''),('LK','KTK','Katukurunda','Katukurunda',''),('LK','MAN','Mannar','Mannar',''),('LK','MAW','Mawella','Mawella',''),('LK','MNH','Minneriya','Minneriya',''),('LK','MUL','Mulativu','Mulativu',''),('LK','PPE','Point Pedro','Point Pedro',''),('LK','PUL','Pulmoddai','Pulmoddai',''),('LK','RML','Colombo/Ratmalana Apt','Colombo/Ratmalana Apt',''),('LK','SGT','South Asia Gateway Terminal','South Asia Gateway Terminal',''),('LK','SIG','Sigiriya','Sigiriya',''),('LK','TAL','Talaimannar','Talaimannar',''),('LK','TRR','Trincomalee','Trincomalee',''),('LK','UCT','Unity Container Terminal','Unity Container Terminal',''),('LK','UHA','Uhana','Uhana',''),('LR','','','',''),('LR','BYL','Bella Yella','Bella Yella',''),('LR','CMT','Cape Mount','Cape Mount',''),('LR','CPA','Cape Palmas','Cape Palmas',''),('LR','FIM','Fimibo','Fimibo',''),('LR','FOY','Foya','Foya',''),('LR','GBS','Grand Bassa','Grand Bassa',''),('LR','GRC','Grand Cess','Grand Cess',''),('LR','GRE','Greenville','Greenville',''),('LR','HAR','Harper','Harper',''),('LR','HBL','Harbel','Harbel',''),('LR','LOB','Lower Buchanan','Lower Buchanan',''),('LR','MAR','Marshall','Marshall',''),('LR','MLW','Monrovia','Monrovia',''),('LR','NIA','Nimba','Nimba',''),('LR','ROX','Robertsport','Robertsport',''),('LR','RVC','River Cess','River Cess',''),('LR','SAB','Sarioe Bay','Sarioe Bay',''),('LR','SAZ','Sasstown','Sasstown',''),('LR','SNI','Sinoe','Sinoe',''),('LR','THC','Tchien','Tchien',''),('LR','TPT','Tapeta','Tapeta',''),('LR','TRT','Trade Town','Trade Town',''),('LR','UCN','Buchanan','Buchanan',''),('LR','VOI','Voinjama','Voinjama',''),('LR','WES','Weasua','Weasua',''),('LR','WOI','Wologissi','Wologissi',''),('LS','','','',''),('LS','LEF','Lebakeng','Lebakeng',''),('LS','LES','Lesobeng','Lesobeng',''),('LS','LRB','Leribe','Leribe',''),('LS','MFC','Mafeteng','Mafeteng',''),('LS','MKH','Mokhotlong','Mokhotlong',''),('LS','MPS','Maputsoe','Maputsoe',''),('LS','MSG','Matsaile','Matsaile',''),('LS','MSU','Maseru','Maseru',''),('LS','NKU','Nkaus','Nkaus',''),('LS','PEL','Pelaneng','Pelaneng',''),('LS','SHK','Sehonghong','Sehonghong',''),('LS','SHZ','Seshutes','Seshutes',''),('LS','SKQ','Sekakes','Sekakes',''),('LS','SOK','Semongkong','Semongkong',''),('LS','THB','Thaba-Tseka','Thaba-Tseka',''),('LS','TKO','Tlokoeng','Tlokoeng',''),('LS','UNE','Qacha\'s Nek','Qacha\'s Nek',''),('LS','UTG','Quthing','Quthing',''),('LT','','','',''),('LT','AYS','Alytus','Alytus',''),('LT','AZI','Avizieniai','Avizieniai',''),('LT','BOT','Botinge','Botinge',''),('LT','BRZ','Birzai','Birzai',''),('LT','DKI','Druskininkai','Druskininkai',''),('LT','ETI','Elektrenai','Elektrenai',''),('LT','GKS','Grinkiskis','Grinkiskis',''),('LT','JNA','Jonava','Jonava',''),('LT','JON','Joniskis','Joniskis',''),('LT','JUR','Jurbarkas','Jurbarkas',''),('LT','KDN','Kedainiai','Kedainiai',''),('LT','KDO','Kaisiadorio','Kaisiadorio',''),('LT','KLJ','Klaipeda','Klaipeda',''),('LT','KLO','Klovainiai','Klovainiai',''),('LT','KLT','Kaltene','Kaltene',''),('LT','KRA','Kazlu Ruda','Kazlu Ruda',''),('LT','KRE','Kretinga','Kretinga',''),('LT','KUN','Kaunas','Kaunas',''),('LT','KUP','Kupiskis','Kupiskis',''),('LT','KUR','Kursenai','Kursenai',''),('LT','LAZ','Lazdijai','Lazdijai',''),('LT','MJP','Marijampole','Marijampole',''),('LT','MLI','Moletai','Moletai',''),('LT','MNK','Musninkai','Musninkai',''),('LT','MOC','Mockava','Mockava',''),('LT','MZK','Mazeikiai','Mazeikiai',''),('LT','NAK','Naujoji Akmene','Naujoji Akmene',''),('LT','NJM','Naujamiestis','Naujamiestis',''),('LT','NMS','Nemaksciai','Nemaksciai',''),('LT','PAB','Pabrade','Pabrade',''),('LT','PLG','Plunges','Plunges',''),('LT','PLQ','Palanga','Palanga',''),('LT','PLS','Pusalotas','Pusalotas',''),('LT','PNA','Pelednagiai','Pelednagiai',''),('LT','PNV','Panevezys','Panevezys',''),('LT','PRI','Prienai','Prienai',''),('LT','PVS','Pasvalys','Pasvalys',''),('LT','RAS','Raseiniai','Raseiniai',''),('LT','RKS','Rokiskis','Rokiskis',''),('LT','RTS','Rietavas','Rietavas',''),('LT','RUM','Rumiskies','Rumiskies',''),('LT','SIL','Silute','Silute',''),('LT','SKU','Skuodas','Skuodas',''),('LT','SLE','Silale','Silale',''),('LT','SNI','Salcininkai','Salcininkai',''),('LT','SQQ','Siauliai','Siauliai',''),('LT','STR','Senieji Trakai','Senieji Trakai',''),('LT','TAU','Taurage','Taurage',''),('LT','TEL','Telsiai','Telsiai',''),('LT','TKS','Traksedis','Traksedis',''),('LT','TVI','Tytuvenai','Tytuvenai',''),('LT','UKE','Ukmerge','Ukmerge',''),('LT','UTA','Utena','Utena',''),('LT','VKV','Vilkaviskis','Vilkaviskis',''),('LT','VNO','Vilnius','Vilnius',''),('LT','ZAR','Zarasai','Zarasai',''),('LT','ZZM','Ziezmariai','Ziezmariai',''),('LU','','','',''),('LU','AZN','Alzingen','Alzingen',''),('LU','BDB','Boudler','Boudler',''),('LU','BDL','Bridel','Bridel',''),('LU','BET','Bettembourg','Bettembourg',''),('LU','BKE','Beckerich','Beckerich',''),('LU','BKM','Bech-Kleinmacher','Bech-Kleinmacher',''),('LU','BRE','Bertrange','Bertrange',''),('LU','BRG','Berg-sur-Syre','Berg-sur-Syre',''),('LU','BSC','Bascharage','Bascharage',''),('LU','BSN','Bissen','Bissen',''),('LU','CEL','Clervaux','Clervaux',''),('LU','COL','Colmarberg','Colmarberg',''),('LU','CPL','Capellen','Capellen',''),('LU','CTN','Contern','Contern',''),('LU','DDE','Differdange','Differdange',''),('LU','DIE','Diekirch','Diekirch',''),('LU','DUD','Dudelange','Dudelange',''),('LU','EBN','Eselborn','Eselborn',''),('LU','ECH','Echternach','Echternach',''),('LU','EDE','Erpeldange','Erpeldange',''),('LU','EHL','Ehlerange','Ehlerange',''),('LU','ETT','Ettelbruck','Ettelbruck',''),('LU','EZT','Esch-sur-Alzette','Esch-sur-Alzette',''),('LU','FDL','Findel','Findel',''),('LU','FEN','Fentange','Fentange',''),('LU','GVC','Grevenmacher','Grevenmacher',''),('LU','HDF','Hunsdorf','Hunsdorf',''),('LU','HES','Hesperange','Hesperange',''),('LU','HOS','Hosingen','Hosingen',''),('LU','HSG','Helmsange','Helmsange',''),('LU','KHL','Kehlen','Kehlen',''),('LU','KOE','Koetschette','Koetschette',''),('LU','LDL','Leudelange','Leudelange',''),('LU','LUX','Luxembourg','Luxembourg',''),('LU','LWR','Lorentzweiler','Lorentzweiler',''),('LU','MFT','Moutfort','Moutfort',''),('LU','MME','Mamer','Mamer',''),('LU','MOS','Mosingen','Mosingen',''),('LU','NAN','Niederanven','Niederanven',''),('LU','NDC','Niederkorn','Niederkorn',''),('LU','OBR','Oberanven','Oberanven',''),('LU','PPR','Pontpierre','Pontpierre',''),('LU','PTN','Petange','Petange',''),('LU','PTZ','Pratz','Pratz',''),('LU','RDN','Redange','Redange',''),('LU','ROD','Rodange','Rodange',''),('LU','RST','Rost','Rost',''),('LU','SAN','Sanem','Sanem',''),('LU','SKK','Steinfort','Steinfort',''),('LU','STE','Steinsel','Steinsel',''),('LU','STN','Strassen','Strassen',''),('LU','TRO','Troisvierges','Troisvierges',''),('LU','VIA','Vianden','Vianden',''),('LU','WIL','Wiltz','Wiltz',''),('LV','','','',''),('LV','AIN','Ainazi','Ainazi','LM'),('LV','AIZ','Aizkraukle','Aizkraukle','AI'),('LV','AKI','Akniste','Akniste','JK'),('LV','APE','Aizpute','Aizpute','LE'),('LV','ASE','Aluksne','Aluksne','AL'),('LV','AUC','Auce','Auce','DO'),('LV','BAU','Bauska','Bauska','BU'),('LV','BRC','Broc?ni','Broc?ni','SA'),('LV','BZC','Briezuciems','Briezuciems','BL'),('LV','CES','Cesis','Cesis','CE'),('LV','DGP','Daugavpils','Daugavpils','DW'),('LV','DOB','Dobele','Dobele','DO'),('LV','GBA','Grobina','Grobina','LPX'),('LV','GKE','Garkalne','Garkalne','RI'),('LV','GUL','Gulbene','Gulbene','GU'),('LV','ICK','Incukalns','Incukalns','RI'),('LV','JGA','Jelgava','Jelgava','JL'),('LV','JPS','Jekabpils','Jekabpils','JK'),('LV','KDA','Kuldiga','Kuldiga','KU'),('LV','LMS','Lapmezciems','Lapmezciems','TU'),('LV','LPX','Liepaja','Liepaja','LPX'),('LV','LVI','Livani','Livani','PR'),('LV','LZS','Lizums','Lizums','GU'),('LV','MAD','Madona','Madona','MA'),('LV','MAL','Malta','Malta','RE'),('LV','MGI','Mangali','Mangali','LE'),('LV','MRX','Mersrags','Mersrags','TA'),('LV','OLA','Olaine','Olaine','RI'),('LV','ORE','Ogre','Ogre','OG'),('LV','PAC','Pace','Pace','BU'),('LV','PBZ','Pabazi','Pabazi','RI'),('LV','PRE','Preli (Preili)','Preli (Preili)','PR'),('LV','REZ','Rezekne','Rezekne','RE'),('LV','RIX','Riga','Riga','RIX'),('LV','RNA','Rauna','Rauna','CE'),('LV','SAL','Salacgriva','Salacgriva','LM'),('LV','SAR','Sarkani','Sarkani','MA'),('LV','SDS','Saldus','Saldus','SA'),('LV','SKU','Skulte','Skulte','LM'),('LV','SPS','Salaspils','Salaspils','RI'),('LV','TKM','Tukums','Tukums','TU'),('LV','TSI','Talsi','Talsi','TA'),('LV','VAL','Valka','Valka','VK'),('LV','VGE','Valdgale','Valdgale','TA'),('LV','VGI','Vangazi','Vangazi','RI'),('LV','VIA','Valmiera','Valmiera','VM'),('LV','VNT','Ventspils','Ventspils','VEN'),('LY','','','',''),('LY','ABA','Al Bayda','Al Bayda',''),('LY','ABK','Abu Kammash','Abu Kammash',''),('LY','AKF','Al Khofra (Kufra)','Al Khofra (Kufra)',''),('LY','APO','Apollonia','Apollonia',''),('LY','BAR','Bardiyah','Bardiyah',''),('LY','BCQ','Birak','Birak',''),('LY','BEN','Bingazi (Benghazi)','Bingazi (Benghazi)',''),('LY','BOU','El Bouri','El Bouri',''),('LY','BUA','Bu\'ayrat al Hasun','Bu\'ayrat al Hasun',''),('LY','DNF','Darnah','Darnah',''),('LY','DRX','Darnah','Darnah',''),('LY','ESI','As Sidr','As Sidr',''),('LY','GHT','Ghat','Ghat',''),('LY','KHO','Al Khums','Al Khums',''),('LY','LAQ','Beida','Beida',''),('LY','LMQ','Marsa Brega','Marsa Brega',''),('LY','LTD','Ghadames','Ghadames',''),('LY','MBR','Marsa Al Burayqah','Marsa Al Burayqah',''),('LY','MEH','Marsa El Hania','Marsa El Hania',''),('LY','MHR','Marsa el Hariga','Marsa el Hariga',''),('LY','MJI','Mitiga','Mitiga',''),('LY','MRA','Misurata','Misurata',''),('LY','NFR','Nafoora','Nafoora',''),('LY','REH','Ras el Hilal','Ras el Hilal',''),('LY','RLA','Ras Lanuf','Ras Lanuf',''),('LY','SEB','Sebha','Sebha',''),('LY','SOU','Soussah','Soussah',''),('LY','SRT','Sirte (Surt)','Sirte (Surt)',''),('LY','SRX','Sert','Sert',''),('LY','TAG','Tagiura','Tagiura',''),('LY','TIP','Tripoli','Tripoli',''),('LY','TOA','Toulmeitha','Toulmeitha',''),('LY','TOB','Tobruk','Tobruk',''),('LY','TUK','Tukrah','Tukrah',''),('LY','WAX','Zwara','Zwara',''),('LY','ZAW','Az Zawiyah','Az Zawiyah',''),('LY','ZLI','Zliten','Zliten',''),('LY','ZUA','Zuara','Zuara',''),('LY','ZUE','Zueitina','Zueitina',''),('MA','','','',''),('MA','AGA','Agadir','Agadir',''),('MA','AHU','Al Hoceima','Al Hoceima',''),('MA','ASE','Ain Sebaa','Ain Sebaa',''),('MA','ASI','Asilah','Asilah',''),('MA','AZE','Azemmour','Azemmour',''),('MA','AZR','Azrou','Azrou',''),('MA','BED','Berrechid','Berrechid',''),('MA','BEM','Beni Mellal','Beni Mellal',''),('MA','BEN','Benguerir','Benguerir',''),('MA','BER','Berkane','Berkane',''),('MA','BOU','Bouznika','Bouznika',''),('MA','BRE','Breich','Breich',''),('MA','CAS','Casablanca','Casablanca',''),('MA','ELJ','El Jadida','El Jadida',''),('MA','ERH','Errachidia','Errachidia',''),('MA','ESS','Essaouira','Essaouira',''),('MA','EUN','Laayoune (El Aaiun)','Laayoune (El Aaiun)',''),('MA','FEZ','Fez','Fez',''),('MA','GLN','Goulimime','Goulimime',''),('MA','JFL','Jorf Lasfar','Jorf Lasfar',''),('MA','KAT','Kasba Tadla','Kasba Tadla',''),('MA','KHA','Khouribga','Khouribga',''),('MA','KHE','Khemisset','Khemisset',''),('MA','LAR','Larache','Larache',''),('MA','MEK','Meknes','Meknes',''),('MA','MOH','Mohammedia','Mohammedia',''),('MA','NDR','Nador','Nador',''),('MA','NNA','Kenitra (ex Port Lyautey)','Kenitra (ex Port Lyautey)',''),('MA','NOU','Nouasseur','Nouasseur',''),('MA','OUD','Oujda','Oujda',''),('MA','OZZ','Ouarzazate','Ouarzazate',''),('MA','RAK','Marrakech','Marrakech',''),('MA','RBA','Rabat','Rabat',''),('MA','SAL','Sale','Sale',''),('MA','SEK','Ksar Es Souk','Ksar Es Souk',''),('MA','SET','Settat','Settat',''),('MA','SFI','Safi','Safi',''),('MA','SII','Sidi Ifni','Sidi Ifni',''),('MA','SIK','Sidi Kacem','Sidi Kacem',''),('MA','SMW','Smara','Smara',''),('MA','TAR','Taroudannt','Taroudannt',''),('MA','TAZ','Taza','Taza',''),('MA','TFY','Tarfaya','Tarfaya',''),('MA','THI','Tinerhir','Tinerhir',''),('MA','TNG','Tangier','Tangier',''),('MA','TTA','Tan Tan','Tan Tan',''),('MA','TTU','Tetouan','Tetouan',''),('MA','TZI','Tiznit','Tiznit',''),('MA','VIL','Dakhla','Dakhla',''),('MC','','','',''),('MC','MCM','Monte-Carlo','Monte-Carlo',''),('MC','MON','Monaco','Monaco',''),('MD','','','',''),('MD','BEL','Balti (Bel\'cy)','Balti (Bel\'cy)',''),('MD','BRS','Berestovitsa','Berestovitsa',''),('MD','KIV','Chisinau (ex Kishinev)','Chisinau (ex Kishinev)',''),('MD','LEU','Leusheny','Leusheny',''),('MD','RIB','Ribnita','Ribnita',''),('MD','TIR','Tiraspol','Tiraspol',''),('MD','UNG','Ungeny','Ungeny',''),('MD','VUL','Vulc?nesti','Vulc?nesti',''),('ME','','','',''),('ME','BAR','Bar','Bar',''),('ME','BIJ','Bijela','Bijela',''),('ME','BUD','Budva','Budva',''),('ME','HNO','Hercegnovi','Hercegnovi',''),('ME','IGL','Igalo','Igalo',''),('ME','IVG','Berane (Yvangrad)','Berane (Yvangrad)',''),('ME','KOT','Kotor','Kotor',''),('ME','NIK','Niksic','Niksic',''),('ME','PVC','Petrovac','Petrovac',''),('ME','RSN','Risan (Risano)','Risan (Risano)',''),('ME','TGD','Podgorica','Podgorica',''),('ME','TIV','Tivat','Tivat',''),('ME','ULC','Ulcinj','Ulcinj',''),('ME','ZBK','Zabljak','Zabljak',''),('ME','ZEL','Zelenika','Zelenika',''),('MG','','','',''),('MG','ADK','Androka','Androka',''),('MG','AHY','Ambatolahy','Ambatolahy',''),('MG','AMB','Ambilobe','Ambilobe',''),('MG','AMP','Ampanihy','Ampanihy',''),('MG','AMY','Ambatomainty','Ambatomainty',''),('MG','ANM','Antalaha','Antalaha',''),('MG','ATJ','Antsirabe','Antsirabe',''),('MG','BIK','Brickaville','Brickaville',''),('MG','BKU','Betioky','Betioky',''),('MG','BMD','Belo','Belo',''),('MG','BPY','Besalampy','Besalampy',''),('MG','BRR','Barren Islands','Barren Islands',''),('MG','BSV','Besakoa','Besakoa',''),('MG','DIE','Antsiranana','Antsiranana',''),('MG','DOA','Doany','Doany',''),('MG','DWB','Soalala','Soalala',''),('MG','FTU','Fort Dauphin (Toalagnaro)','Fort Dauphin (Toalagnaro)',''),('MG','HLV','Hell-Ville','Hell-Ville',''),('MG','HVA','Analalava','Analalava',''),('MG','IHO','Ihosy','Ihosy',''),('MG','ILK','Ilaka','Ilaka',''),('MG','IVA','Ambanja','Ambanja',''),('MG','JVA','Ankavandra','Ankavandra',''),('MG','MJA','Manja','Manja',''),('MG','MJN','Majunga (Mahajanga)','Majunga (Mahajanga)',''),('MG','MNJ','Mananjary','Mananjary',''),('MG','MOB','Manombo','Manombo',''),('MG','MOQ','Morondava','Morondava',''),('MG','MXM','Morombe','Morombe',''),('MG','MXT','Maintirano','Maintirano',''),('MG','NOS','Nosy-Be','Nosy-Be',''),('MG','NOV','Nosy-Varika','Nosy-Varika',''),('MG','OVA','Bekily','Bekily',''),('MG','PSL','Port Saint Louis','Port Saint Louis',''),('MG','RVA','Farafangana','Farafangana',''),('MG','SMS','Ste Marie','Ste Marie',''),('MG','SVB','Sambava','Sambava',''),('MG','TDV','Tanandava','Tanandava',''),('MG','TLE','Tulear (Toliara)','Tulear (Toliara)',''),('MG','TLN','Taolagnaro','Taolagnaro',''),('MG','TMM','Tamatave (Toamasina)','Tamatave (Toamasina)',''),('MG','TNR','Antananarivo','Antananarivo',''),('MG','TOA','Toamasina','Toamasina',''),('MG','TTS','Tsaratanana','Tsaratanana',''),('MG','TVA','Morafenobe','Morafenobe',''),('MG','VAT','Vatomandry','Vatomandry',''),('MG','VEH','Vehiperro','Vehiperro',''),('MG','VND','Vangaindrano','Vangaindrano',''),('MG','VOH','Vohemar','Vohemar',''),('MG','VVB','Mahanoro','Mahanoro',''),('MG','WAD','Andriamena','Andriamena',''),('MG','WAI','Antsohihy','Antsohihy',''),('MG','WAK','Ankazoabo','Ankazoabo',''),('MG','WAM','Ambatondrazaka','Ambatondrazaka',''),('MG','WAQ','Antsalova','Antsalova',''),('MG','WBD','Befandriana','Befandriana',''),('MG','WBE','Bealanana','Bealanana',''),('MG','WBO','Beroroha','Beroroha',''),('MG','WFI','Fianarantsoa','Fianarantsoa',''),('MG','WMA','Mandritsara','Mandritsara',''),('MG','WMD','Mandabe','Mandabe',''),('MG','WML','Malaimbandy','Malaimbandy',''),('MG','WMN','Maroantsetra','Maroantsetra',''),('MG','WMP','Mampikony','Mampikony',''),('MG','WMR','Mananara','Mananara',''),('MG','WMV','Madirovalo','Madirovalo',''),('MG','WOR','Ankorefo','Ankorefo',''),('MG','WPB','Port Berge Vaovao','Port Berge Vaovao',''),('MG','WTA','Tambohorano','Tambohorano',''),('MG','WTS','Tsiroanomandidy','Tsiroanomandidy',''),('MG','WVK','Manakara','Manakara',''),('MG','ZVA','Miandrivazo','Miandrivazo',''),('MG','ZWA','Andapa','Andapa',''),('MH','','','',''),('MH','KWA','Kwajalein','Kwajalein',''),('MH','LIK','Likiep Island','Likiep Island',''),('MH','LML','Lae Island','Lae Island',''),('MH','LOF','Loen','Loen',''),('MH','MAJ','Majuro','Majuro',''),('MH','MAV','Maloelap Island','Maloelap Island',''),('MH','MIJ','Mili Island','Mili Island',''),('MH','MJB','Mejit Island','Mejit Island',''),('MH','MJE','Majkin','Majkin',''),('MH','NDK','Namdrik Island','Namdrik Island',''),('MH','NMU','Namu','Namu',''),('MH','RNP','Rongelap Island','Rongelap Island',''),('MH','TAR','Taroa','Taroa',''),('MH','TBV','Tabal','Tabal',''),('MH','TIC','Tinak Island','Tinak Island',''),('MH','UJE','Ujae Island','Ujae Island',''),('MH','UTK','Utirik Island','Utirik Island',''),('MH','WJA','Woja','Woja',''),('MH','WTE','Wotje Island','Wotje Island',''),('MH','WTO','Wotho Island','Wotho Island',''),('MK','','','',''),('MK','BDA','Bogdanci','Bogdanci',''),('MK','BLC','Blace','Blace',''),('MK','BLT','Blato','Blato',''),('MK','BRD','Bogorodica','Bogorodica',''),('MK','BRV','Berovo','Berovo',''),('MK','BTL','Bitola','Bitola',''),('MK','DEB','Debar','Debar',''),('MK','DLV','Delcevo','Delcevo',''),('MK','DVB','Deve Bair','Deve Bair',''),('MK','GST','Gostivar','Gostivar',''),('MK','GVL','Gevgelija','Gevgelija',''),('MK','JNC','Jacince','Jacince',''),('MK','KBI','Karbinci','Karbinci',''),('MK','KCI','Kocani','Kocani',''),('MK','KCV','Kicevo','Kicevo',''),('MK','KFN','Kafasan','Kafasan',''),('MK','KOS','Kosovo','Kosovo',''),('MK','KUM','Kumanovo','Kumanovo',''),('MK','KVD','Kavadarci','Kavadarci',''),('MK','MTL','Medzitlija','Medzitlija',''),('MK','NGT','Negotino','Negotino',''),('MK','NSL','Novo Selo','Novo Selo',''),('MK','OHD','Ohrid','Ohrid',''),('MK','PLN','Pelince','Pelince',''),('MK','PLP','Prilep','Prilep',''),('MK','PRO','Probistip','Probistip',''),('MK','PTR','Petrovec','Petrovec',''),('MK','RSN','Resen','Resen',''),('MK','SDR','Star Dojran','Star Dojran',''),('MK','SKP','Skopje','Skopje',''),('MK','SPT','Sopot','Sopot',''),('MK','STE','Stenje','Stenje',''),('MK','STG','Struga','Struga',''),('MK','STM','Strumica','Strumica',''),('MK','STN','Sveti Naum','Sveti Naum',''),('MK','STP','Stip','Stip',''),('MK','TBN','Tabanovce','Tabanovce',''),('MK','TBR','Trubarevo','Trubarevo',''),('MK','TEV','Tetovo','Tetovo',''),('MK','TTV','Veles','Veles',''),('MK','VAL','Valandovo','Valandovo',''),('MK','VIN','Vinica','Vinica',''),('MK','VLK','Volkovo','Volkovo',''),('ML','','','',''),('ML','AMB','Ambidedi','Ambidedi',''),('ML','BGI','Bougouni','Bougouni',''),('ML','BKO','Bamako','Bamako',''),('ML','BLA','Bla','Bla',''),('ML','FAN','Fana','Fana',''),('ML','GAQ','Gao','Gao',''),('ML','IKO','Koulikoro','Koulikoro',''),('ML','KIT','Kita','Kita',''),('ML','KOR','Korouma','Korouma',''),('ML','KPR','Kemparana','Kemparana',''),('ML','KTX','Koutiala','Koutiala',''),('ML','KYS','Kayes','Kayes',''),('ML','MAH','Mahana','Mahana',''),('ML','MAI','Mahina','Mahina',''),('ML','MOR','Morila','Morila',''),('ML','MZI','Mopti','Mopti',''),('ML','NDE','Ndebougou','Ndebougou',''),('ML','NEG','Negala','Negala',''),('ML','NIO','Niono','Niono',''),('ML','NIX','Nioro','Nioro',''),('ML','NRM','Nara','Nara',''),('ML','OLB','Ouolossebougou','Ouolossebougou',''),('ML','SAN','San','San',''),('ML','SEV','Sevare','Sevare',''),('ML','SIK','Sikasso','Sikasso',''),('ML','SLA','Sadiola','Sadiola',''),('ML','SZU','Segou','Segou',''),('ML','TOU','Touana','Touana',''),('ML','YAT','Yatela','Yatela',''),('MM','','','',''),('MM','AKY','Akyab (Sittwe)','Akyab (Sittwe)',''),('MM','BIL','Bilin','Bilin',''),('MM','BMO','Bhamo','Bhamo',''),('MM','BOG','Bogale','Bogale',''),('MM','BPE','Bagan','Bagan',''),('MM','BSX','Bassein','Bassein',''),('MM','GAW','Gangaw','Gangaw',''),('MM','GWA','Gwa','Gwa',''),('MM','HEB','Henzada','Henzada',''),('MM','HEN','Heho','Heho',''),('MM','HOX','Homalin','Homalin',''),('MM','INS','Insein','Insein',''),('MM','KAW','Kawthaung','Kawthaung',''),('MM','KET','Keng Tung','Keng Tung',''),('MM','KHM','Khamti','Khamti',''),('MM','KMV','Kalemyo','Kalemyo',''),('MM','KYA','Kyaiklat','Kyaiklat',''),('MM','KYP','Kyaukpyu','Kyaukpyu',''),('MM','KYT','Kyauktaw','Kyauktaw',''),('MM','LIW','Loikaw','Loikaw',''),('MM','LSH','Lashio','Lashio',''),('MM','MAR','Martaban','Martaban',''),('MM','MDL','Mandalay','Mandalay',''),('MM','MER','Mergui','Mergui',''),('MM','MGK','Mong Ton','Mong Ton',''),('MM','MGU','Manaung','Manaung',''),('MM','MGZ','Myeik','Myeik',''),('MM','MNU','Mawlamyine (Moulmein)','Mawlamyine (Moulmein)',''),('MM','MOE','Momeik','Momeik',''),('MM','MOG','Mong Hsat','Mong Hsat',''),('MM','MUR','Murdon','Murdon',''),('MM','MWQ','Magwe','Magwe',''),('MM','MXE','Male','Male',''),('MM','MYT','Myitkyina','Myitkyina',''),('MM','NMS','Namsang','Namsang',''),('MM','NMT','Namtu','Namtu',''),('MM','NYU','Nyaung-U','Nyaung-U',''),('MM','PAA','Pa-An','Pa-An',''),('MM','PAU','Pauk','Pauk',''),('MM','PBU','Putao','Putao',''),('MM','PEG','Pegu','Pegu',''),('MM','PKK','Pakokku','Pakokku',''),('MM','PPU','Papun','Papun',''),('MM','RGN','Yangon','Yangon',''),('MM','SNW','Thandwe (ex Sandoway)','Thandwe (ex Sandoway)',''),('MM','TAS','Tah Sala','Tah Sala',''),('MM','TAV','Tavoy','Tavoy',''),('MM','TEN','Tanintharyi','Tanintharyi',''),('MM','TER','Terutao Island','Terutao Island',''),('MM','THA','Thaton','Thaton',''),('MM','THL','Tachilek','Tachilek',''),('MM','TIO','Tilin','Tilin',''),('MM','TVY','Dawe','Dawe',''),('MM','VIC','Victoria Point','Victoria Point',''),('MM','XYE','Ye','Ye',''),('MN','','','',''),('MN','AVK','Arvaikheer','Arvaikheer',''),('MN','BYN','Bayankhongor','Bayankhongor',''),('MN','COQ','Choibalsan','Choibalsan',''),('MN','DLZ','Dalandzadgad','Dalandzadgad',''),('MN','DZU','Dzamin Uud','Dzamin Uud',''),('MN','ERT','Erdenet','Erdenet',''),('MN','HAT','Hatgal','Hatgal',''),('MN','HJT','Khujirt','Khujirt',''),('MN','HVD','Khovd','Khovd',''),('MN','KHR','Kharkhorin','Kharkhorin',''),('MN','LTI','Altai','Altai',''),('MN','MXV','Moron','Moron',''),('MN','MXW','Mandalgobi','Mandalgobi',''),('MN','TOS','Tosontsengel','Tosontsengel',''),('MN','TSZ','Tsetserleg','Tsetserleg',''),('MN','UGA','Bulgan','Bulgan',''),('MN','ULG','Ulgit','Ulgit',''),('MN','ULN','Ulaanbaatar','Ulaanbaatar',''),('MN','ULO','Ulaangom','Ulaangom',''),('MN','ULZ','Uliastay','Uliastay',''),('MN','UNR','Underkhaan','Underkhaan',''),('MN','UUN','Baruun-Urt','Baruun-Urt',''),('MO','','','',''),('MO','MFM','Macau','Macau',''),('MP','','','',''),('MP','ROP','Rota','Rota',''),('MP','SPN','Saipan','Saipan',''),('MP','TIQ','Tinian','Tinian',''),('MQ','','','',''),('MQ','DUC','Ducos','Ducos',''),('MQ','FDF','Fort-de-France','Fort-de-France',''),('MQ','LFR','Le Francois','Le Francois',''),('MQ','LMT','Le Lamentin','Le Lamentin',''),('MQ','SHL','Scholcher','Scholcher',''),('MQ','SPI','St Pierre','St Pierre',''),('MR','','','',''),('MR','AEO','Aioun el Atrouss','Aioun el Atrouss',''),('MR','AJJ','Akjoujt','Akjoujt',''),('MR','ATR','Atar','Atar',''),('MR','BGH','Boghe','Boghe',''),('MR','CGT','Chinguitti','Chinguitti',''),('MR','EMN','Nema','Nema',''),('MR','FGD','Fderik','Fderik',''),('MR','KED','Kaedi','Kaedi',''),('MR','KFA','Kiffa','Kiffa',''),('MR','LEG','Aleg','Aleg',''),('MR','MBR','Mbout','Mbout',''),('MR','MOM','Moudjeria','Moudjeria',''),('MR','NDB','Nouadhibou','Nouadhibou',''),('MR','NKC','Nouakchott','Nouakchott',''),('MR','OTL','Boutilimit','Boutilimit',''),('MR','OUZ','Zouerat','Zouerat',''),('MR','PCE','Point Central','Point Central',''),('MR','SEY','Selibaby','Selibaby',''),('MR','THI','Tichitt','Tichitt',''),('MR','THT','Tamchakett','Tamchakett',''),('MR','TIY','Tidjikja','Tidjikja',''),('MR','TMD','Timbedra','Timbedra',''),('MR','ZLG','El Gouera','El Gouera',''),('MS','','','',''),('MS','LTB','Little Bay','Little Bay',''),('MS','MNI','Montserrat','Montserrat',''),('MS','PLY','Plymouth','Plymouth',''),('MT','','','',''),('MT','DIS','Malta Freeport Distripark','Malta Freeport Distripark',''),('MT','FLO','Floriana','Floriana',''),('MT','GZM','Gozo','Gozo',''),('MT','JCO','Comino','Comino',''),('MT','LUQ','Luqa','Luqa',''),('MT','MAR','Marsaxlokk','Marsaxlokk',''),('MT','MLA','Malta (Valetta)','Malta (Valetta)',''),('MT','MOA','Mosta','Mosta',''),('MT','MSX','Marsamxett','Marsamxett',''),('MT','PAO','Paola','Paola',''),('MT','RMI','Qormi','Qormi',''),('MT','SGW','San ?wann, Valletta','San ?wann, Valletta',''),('MT','SJN','San ?iljan (St Julian)','San ?iljan (St Julian)',''),('MT','SPB','St Paul\'s Bay (San Paul il-Bahir)','St Paul\'s Bay (San Paul il-Bahir)',''),('MU','','','',''),('MU','CDE','Cloverdale','Cloverdale',''),('MU','CUR','Curepipe','Curepipe',''),('MU','MAH','Mahebourg','Mahebourg',''),('MU','MRU','Sir Seewoosagur Ramgoolam Int Apt','Sir Seewoosagur Ramgoolam Int Apt',''),('MU','PLU','Port Louis','Port Louis',''),('MU','PMA','Port Mathurin','Port Mathurin',''),('MU','PMG','Plaine Magnien','Plaine Magnien',''),('MU','RRG','Rodrigues','Rodrigues',''),('MV','','','',''),('MV','GAN','Gan','Gan',''),('MV','HAQ','Hanimaadhoo','Hanimaadhoo',''),('MV','KDM','Kaadedhdhoo','Kaadedhdhoo',''),('MV','KDO','Kadhdhoo','Kadhdhoo',''),('MV','KEL','Kelai','Kelai',''),('MV','MLE','Male','Male',''),('MW','','','',''),('MW','BLZ','Blantyre','Blantyre',''),('MW','KGJ','Karonga','Karonga',''),('MW','LBE','Limbe','Limbe',''),('MW','LLW','Lilongwe','Lilongwe',''),('MW','ZZU','Mzuzu','Mzuzu',''),('MX','','','',''),('MX','ACA','Acapulco','Acapulco','GRO'),('MX','ACB','Acambaro','Acambaro','GUA'),('MX','ACC','Ascencion','Ascencion','CHH'),('MX','ACN','Ciudad Acuna','Ciudad Acuna',''),('MX','ACP','Acaponeta','Acaponeta','NAY'),('MX','ACU','Acuna','Acuna',''),('MX','ACX','Acaxochitlan','Acaxochitlan','HID'),('MX','AGD','Agua Dulce','Agua Dulce','BCN'),('MX','AGU','Aguascalientes','Aguascalientes','AGU'),('MX','AJS','Abreojos','Abreojos',''),('MX','AKI','Akil','Akil','YUC'),('MX','ALC','Atlacomulco','Atlacomulco','MOR'),('MX','ALO','Alamo','Alamo','VER'),('MX','AOB','Alvaro Obregon','Alvaro Obregon',''),('MX','APA','Apaseo el Grande','Apaseo el Grande','GUA'),('MX','APD','Apodaca','Apodaca',''),('MX','API','Apizaco','Apizaco','TLA'),('MX','APR','Agua Prieta','Agua Prieta','SON'),('MX','APX','Apaxco de Ocampo','Apaxco de Ocampo','MEX'),('MX','APZ','Azcapotzalco','Azcapotzalco','MEX'),('MX','AQL','Atotonilquillo','Atotonilquillo','JAL'),('MX','ARA','Arandas','Arandas','JAL'),('MX','ARC','Arcelia','Arcelia','GRO'),('MX','ARZ','Arizpe','Arizpe','SON'),('MX','ATE','Atequiza','Atequiza','JAL'),('MX','ATI','Atitalaquia','Atitalaquia','HID'),('MX','ATL','Atlixco','Atlixco','PUE'),('MX','ATM','Altamira','Altamira',''),('MX','ATO','Atotonilco el Alto','Atotonilco el Alto','JAL'),('MX','ATT','Atotonilco','Atotonilco','DUR'),('MX','AUT','Autlan','Autlan','JAL'),('MX','AVD','Alvarado','Alvarado','VER'),('MX','AYA','Ayala','Ayala','MOR'),('MX','AYO','Ayotlan','Ayotlan','JAL'),('MX','AYU','Ayutla','Ayutla','JAL'),('MX','AZG','Apatzingan','Apatzingan',''),('MX','BAA','Bahia de los Angeles','Bahia de los Angeles','BCN'),('MX','BAL','Balancan','Balancan','TAB'),('MX','BDN','Barra de Navidad','Barra de Navidad','JAL'),('MX','BDR','Boca del Rio','Boca del Rio','VER'),('MX','BHL','Bahia Angeles','Bahia Angeles',''),('MX','CAL','Calpulalpan','Calpulalpan','MEX'),('MX','CAN','Canatlan','Canatlan','DUR'),('MX','CAR','Tequixquitla','Tequixquitla','TLA'),('MX','CAS','Casimiro Castillo','Casimiro Castillo','JAL'),('MX','CAT','Cayo Arcas Terminal','Cayo Arcas Terminal',''),('MX','CAU','Cuautlancingo','Cuautlancingo','PUE'),('MX','CBV','Caborca Viejo','Caborca Viejo','SON'),('MX','CCN','Coalcoman','Coalcoman','MIC'),('MX','CCU','Ciudad Cuauthemoc','Ciudad Cuauthemoc','CHP'),('MX','CDD','Ciudad Madero','Ciudad Madero','TAM'),('MX','CDF','Cienega de Flores','Cienega de Flores','NLE'),('MX','CDN','Cardenas','Cardenas',''),('MX','CDO','Concepcion del Oro','Concepcion del Oro','ZAC'),('MX','CDU','Cordoba','Cordoba','VER'),('MX','CDV','Ciudad Valles','Ciudad Valles','SLP'),('MX','CED','Cedros','Cedros','BCN'),('MX','CEN','Ciudad Obregon','Ciudad Obregon','SON'),('MX','CFJ','Chipilio de Francisco Javier Mina','Chipilio de Francisco Javier Mina','PUE'),('MX','CHH','Chahuites','Chahuites','OAX'),('MX','CHI','Chilpancingo','Chilpancingo','GRO'),('MX','CHL','Coahuila','Coahuila','SON'),('MX','CHM','Chamela','Chamela','JAL'),('MX','CHN','China','China','CAM'),('MX','CHO','Choix','Choix','SIN'),('MX','CHT','Cuauhtemoc','Cuauhtemoc',''),('MX','CIA','Ciudad Altamirano','Ciudad Altamirano','GRO'),('MX','CIO','Cutzio','Cutzio','MIC'),('MX','CJI','Cuajinicuilapa','Cuajinicuilapa','GRO'),('MX','CJS','Ciudad Juarez','Ciudad Juarez','CHH'),('MX','CJT','Comitan','Comitan',''),('MX','CLY','Celaya','Celaya','GUA'),('MX','CME','Ciudad del Carmen','Ciudad del Carmen','CAM'),('MX','CML','Chimalapa','Chimalapa','CHP'),('MX','CMP','Cumpas','Cumpas','SON'),('MX','CNA','Cananea','Cananea','SON'),('MX','COA','Coatzacoalcos','Coatzacoalcos','VER'),('MX','COL','Colima','Colima','COL'),('MX','COS','Cosoleacaque','Cosoleacaque','VER'),('MX','COT','Cotija','Cotija','MIC'),('MX','CPE','Campeche','Campeche','CAM'),('MX','CPT','Col Portales','Col Portales',''),('MX','CSG','Ciudad Sahagun','Ciudad Sahagun','HID'),('MX','CSL','Cabo San Lucas','Cabo San Lucas','BCS'),('MX','CTL','Cuautla','Cuautla','JAL'),('MX','CTM','Chetumal','Chetumal','ROO'),('MX','CTP','Coatepac','Coatepac','VER'),('MX','CTX','Cotaxtla','Cotaxtla','VER'),('MX','CTZ','Cartazar','Cartazar','GUA'),('MX','CUA','Ciudad Constitucion','Ciudad Constitucion','BCS'),('MX','CUE','Cuencame','Cuencame','DUR'),('MX','CUJ','Cuajimalpa','Cuajimalpa','MEX'),('MX','CUL','Culiacan','Culiacan','SIN'),('MX','CUM','Cuautla Morelos','Cuautla Morelos','MOR'),('MX','CUN','Cancun','Cancun','ROO'),('MX','CUT','Cuautitlan Izcalli','Cuautitlan Izcalli','MEX'),('MX','CUU','Chihuahua','Chihuahua','CHH'),('MX','CVC','Cuernavaca','Cuernavaca','MOR'),('MX','CVM','Ciudad Victoria','Ciudad Victoria','TAM'),('MX','CZA','Chichen-Itza','Chichen-Itza',''),('MX','CZM','Cozumel','Cozumel','ROO'),('MX','CZR','Cortazar','Cortazar','GUA'),('MX','DBT','Dos Bocas Terminal','Dos Bocas Terminal',''),('MX','DGO','Durango','Durango','DUR'),('MX','DHD','Dolores Hidalgo','Dolores Hidalgo','GUA'),('MX','ELD','Eldorado','Eldorado',''),('MX','ELN','El Naranjillo','El Naranjillo','GRO'),('MX','ELP','El Paso','El Paso','COA'),('MX','ELR','El Ranchito','El Ranchito','MIC'),('MX','ELS','El Salto','El Salto',''),('MX','EMQ','El Marques','El Marques','QUE'),('MX','EPC','Ecatepec','Ecatepec','MEX'),('MX','EPM','Empalme','Empalme','SON'),('MX','ESC','Escobedo','Escobedo','NLE'),('MX','ESE','Ensenada','Ensenada','BCN'),('MX','ESO','El Salto','El Salto','JAL'),('MX','ETP','Ecatepec','Ecatepec','OAX'),('MX','EVI','El Vizcaino','El Vizcaino','BCS'),('MX','FCP','Felipe Carrillo Puerto','Felipe Carrillo Puerto','ROO'),('MX','FGE','Fresnillo de Gonzalez Echeverria','Fresnillo de Gonzalez Echeverria','ZAC'),('MX','FRC','Frontera Comalapa','Frontera Comalapa','CHP'),('MX','FRN','Frontera','Frontera','TAB'),('MX','FTZ','Fronteras','Fronteras','SON'),('MX','GDL','Guadalajara','Guadalajara','JAL'),('MX','GET','General Teran','General Teran','NLE'),('MX','GGA','Garza Garcia','Garza Garcia','NLE'),('MX','GLP','Guadalupe','Guadalupe','NLE'),('MX','GMP','Gomez Palacio','Gomez Palacio','DUR'),('MX','GSV','Guasave','Guasave','SIN'),('MX','GUA','Guanajuato','Guanajuato','GUA'),('MX','GUB','Guerrero Negro','Guerrero Negro',''),('MX','GUV','Guanacevi','Guanacevi','DUR'),('MX','GUZ','Ciudad Guzman','Ciudad Guzman','JAL'),('MX','GYM','Guaymas','Guaymas','SON'),('MX','HAU','Huamantla','Huamantla','TLA'),('MX','HDG','Hidalgo','Hidalgo','CAM'),('MX','HJP','Huajuapan','Huajuapan','OAX'),('MX','HJZ','Huejotzingo','Huejotzingo','PUE'),('MX','HMO','Hermosillo','Hermosillo','SON'),('MX','HTO','Huatulco (Santa Maria Huatulco)','Huatulco (Santa Maria Huatulco)','OAX'),('MX','HUA','Huatabampo','Huatabampo','SON'),('MX','HUE','Huehuetoca','Huehuetoca','ZAC'),('MX','HUI','Huimanguillo','Huimanguillo','TAB'),('MX','HUJ','Huejutla de Reyes','Huejutla de Reyes','HID'),('MX','HUT','Huetamo','Huetamo','MIC'),('MX','HXD','Huixquilucan de Degollado','Huixquilucan de Degollado','MEX'),('MX','HYC','Huayacocotla','Huayacocotla','VER'),('MX','IMU','Imuris','Imuris','SON'),('MX','IRP','Irapuato','Irapuato','GUA'),('MX','ISD','Isla Cedros','Isla Cedros','BCN'),('MX','ISJ','Isla Mujeres','Isla Mujeres','ROO'),('MX','ISL','Isla','Isla','VER'),('MX','IXM','Ixmiquilpan','Ixmiquilpan','HID'),('MX','IXP','Ixtapalapa','Ixtapalapa','MEX'),('MX','IZT','Ixtepec','Ixtepec',''),('MX','JAA','Jalacingo','Jalacingo','VER'),('MX','JAL','Jalapa','Jalapa',''),('MX','JAO','Jalostotitlan','Jalostotitlan','JAL'),('MX','JDP','Jaral del Progreso','Jaral del Progreso','GUA'),('MX','JIU','Jiutepec (Temixco)','Jiutepec (Temixco)','MOR'),('MX','JLC','Jalisco','Jalisco','DUR'),('MX','JPC','Jilotepec','Jilotepec','PUE'),('MX','JPR','Jacona de Plancarte','Jacona de Plancarte','MIC'),('MX','JRZ','Juarez','Juarez',''),('MX','JTP','Jilotepec','Jilotepec','OAX'),('MX','JUP','Juchipila','Juchipila','ZAC'),('MX','JUZ','Juarez','Juarez','CHH'),('MX','LAP','La Paz','La Paz','BCS'),('MX','LDC','Llera de Canales','Llera de Canales','TAM'),('MX','LEN','Leon','Leon','GUA'),('MX','LER','Lerma','Lerma',''),('MX','LIN','Linares','Linares','NLE'),('MX','LMM','Los Mochis','Los Mochis',''),('MX','LOB','Loma Bonita','Loma Bonita','OAX'),('MX','LOM','Lagos de Moreno','Lagos de Moreno',''),('MX','LOP','Lopez Mateos','Lopez Mateos','JAL'),('MX','LOV','Monclova','Monclova','COA'),('MX','LPC','La Piedad de Cabadas','La Piedad de Cabadas','MIC'),('MX','LRE','Los Reyes','Los Reyes','VER'),('MX','LTO','Loreto','Loreto',''),('MX','LUM','Luis Moya','Luis Moya','ZAC'),('MX','LZC','Lazaro Cardenas','Lazaro Cardenas','MIC'),('MX','MAM','Matamoros','Matamoros','TAM'),('MX','MCN','Michacan','Michacan','MIC'),('MX','MDA','Magdalena','Magdalena','JAL'),('MX','MDF','Motul de Felipe Carrillo Puerto','Motul de Felipe Carrillo Puerto','YUC'),('MX','MDK','Magdalena de Kino','Magdalena de Kino','SON'),('MX','MEM','Melchor Muzquiz','Melchor Muzquiz','COA'),('MX','MEX','Mexico City','Mexico City',''),('MX','MEZ','Mezquital','Mezquital','NLE'),('MX','MIC','Michoacan','Michoacan','TAB'),('MX','MID','Merida','Merida','YUC'),('MX','MIR','Miramar','Miramar','TAM'),('MX','MLM','Morelia','Morelia','MIC'),('MX','MLT','Martinez de La Torre','Martinez de La Torre','VER'),('MX','MMC','Ciudad Mante','Ciudad Mante','TAM'),('MX','MOL','Molango','Molango','HID'),('MX','MOR','Moroleon','Moroleon','GUA'),('MX','MPC','Metepec','Metepec','MEX'),('MX','MRE','Morro Redondo','Morro Redondo',''),('MX','MSC','Mariscala','Mariscala','OAX'),('MX','MTE','Matehuala','Matehuala','SLP'),('MX','MTM','Montemorelos','Montemorelos','NLE'),('MX','MTR','Matias Romero','Matias Romero','OAX'),('MX','MTT','Minatitlan','Minatitlan','VER'),('MX','MTY','Monterrey','Monterrey','NLE'),('MX','MUG','Mulege','Mulege',''),('MX','MXL','Mexicali','Mexicali','BCN'),('MX','MZT','Mazatlan','Mazatlan','SIN'),('MX','NAN','Nanchital','Nanchital',''),('MX','NAU','Nautla','Nautla','VER'),('MX','NCG','Nueva Casas Grandes','Nueva Casas Grandes',''),('MX','NDG','Nacozari de Garcia','Nacozari de Garcia',''),('MX','NDJ','Naucalpan de Juarez','Naucalpan de Juarez','MEX'),('MX','NHY','Nezahualcoyotl','Nezahualcoyotl','MEX'),('MX','NLD','Nuevo Laredo','Nuevo Laredo','TAM'),('MX','NOG','Nogales','Nogales','SON'),('MX','NOP','Nopala','Nopala','HID'),('MX','NUO','Nuevo Urecho','Nuevo Urecho','MIC'),('MX','NUR','Nueva Rosita','Nueva Rosita','COA'),('MX','NVS','Navojoa','Navojoa','SON'),('MX','OAX','Oaxaca','Oaxaca','OAX'),('MX','OBR','Obregon','Obregon','SLP'),('MX','OCO','Ocotlan','Ocotlan','JAL'),('MX','OJI','Ojinaga','Ojinaga','CHH'),('MX','OJU','Ojuelos','Ojuelos','JAL'),('MX','OME','Ometepec','Ometepec','GRO'),('MX','ORI','Orizaba','Orizaba','VER'),('MX','OXK','Oxkutzcab','Oxkutzcab','YUC'),('MX','OYO','Ocoyoacac','Ocoyoacac','MEX'),('MX','PAC','Pachuca','Pachuca',''),('MX','PAJ','Pajaritos','Pajaritos','VER'),('MX','PAN','Pantaco','Pantaco',''),('MX','PAZ','Poza Rica','Poza Rica',''),('MX','PBC','Puebla','Puebla','PUE'),('MX','PBJ','Punta Baja','Punta Baja','BCN'),('MX','PCM','Playa del Carmen','Playa del Carmen',''),('MX','PCO','Punta Colorada','Punta Colorada',''),('MX','PCV','Punta Chivato','Punta Chivato',''),('MX','PDB','Purisima de Bustos','Purisima de Bustos','GUA'),('MX','PER','Perula','Perula','JAL'),('MX','PGO','Progreso','Progreso','YUC'),('MX','PIB','Port Isabel','Port Isabel',''),('MX','PIC','Pichilingue','Pichilingue','BCS'),('MX','PIE','Piedras Negras','Piedras Negras','COA'),('MX','PIJ','Pijijiapan','Pijijiapan','CHP'),('MX','PJZ','Puerto Juarez','Puerto Juarez',''),('MX','PLO','Plomosas','Plomosas','CHH'),('MX','PLS','Platon Sanchez','Platon Sanchez','VER'),('MX','PMD','Puerto Madero','Puerto Madero','CHP'),('MX','PMS','Puerto Morelos','Puerto Morelos','ROO'),('MX','PMX','Puerto Mexico','Puerto Mexico','VER'),('MX','PNG','Puerto Angel','Puerto Angel','OAX'),('MX','PNO','Pinotepa Nacional','Pinotepa Nacional',''),('MX','POO','Polanco','Polanco','DF'),('MX','PPE','Puerto Penasco','Puerto Penasco','SON'),('MX','PQA','Pesqueria','Pesqueria',''),('MX','PQM','Palenque','Palenque',''),('MX','PRS','Parras de la Fuente','Parras de la Fuente','COA'),('MX','PTA','Puerta','Puerta','SIN'),('MX','PUH','Pochutla','Pochutla',''),('MX','PVN','Punta Venado','Punta Venado','ROO'),('MX','PVR','Puerto Vallarta','Puerto Vallarta','JAL'),('MX','PXM','Puerto Escondido','Puerto Escondido',''),('MX','PZO','Patzcuaro','Patzcuaro','MIC'),('MX','QRO','Queretaro','Queretaro','QUE'),('MX','QUP','Quecholac','Quecholac','PUE'),('MX','RBG','Rabon Grande','Rabon Grande','VER'),('MX','RBV','Rio Bravo','Rio Bravo','TAM'),('MX','RDO','Rio de Ocampo','Rio de Ocampo','CHH'),('MX','REX','Reynosa','Reynosa','TAM'),('MX','RMA','Ramos Arizpe','Ramos Arizpe','COA'),('MX','RSR','Rosario','Rosario','SIN'),('MX','RST','Rosarito Terminal','Rosarito Terminal',''),('MX','SAA','San Angel','San Angel','DF'),('MX','SAF','Santa Fe','Santa Fe','DF'),('MX','SAH','San Andres Huaxpaltepec','San Andres Huaxpaltepec','OAX'),('MX','SAN','Nextlalpan','Nextlalpan','MEX'),('MX','SAP','Santiago Papasquiaro','Santiago Papasquiaro','DUR'),('MX','SAX','San Andres Tuxtla','San Andres Tuxtla','VER'),('MX','SBN','Sabinas','Sabinas','COA'),('MX','SBS','San Blas','San Blas','NAY'),('MX','SCA','Santa Clara','Santa Clara','MIC'),('MX','SCB','San Cristobal de la Barranca','San Cristobal de la Barranca','JAL'),('MX','SCC','Santa Clara del Cobre','Santa Clara del Cobre','MIC'),('MX','SCL','Santa Clara','Santa Clara','YUC'),('MX','SCM','San Cosme','San Cosme','BCS'),('MX','SCR','San Carlos','San Carlos','BCS'),('MX','SCT','Santa Cruz Tecamac','Santa Cruz Tecamac','MEX'),('MX','SCX','Salina Cruz','Salina Cruz','OAX'),('MX','SFH','San Felipe','San Felipe','BCS'),('MX','SFO','San Felipe Orizatlan','San Felipe Orizatlan','HID'),('MX','SFR','San Francisco del Rincon','San Francisco del Rincon','GUA'),('MX','SFS','San Francisco de los Romos','San Francisco de los Romos','AGU'),('MX','SGM','San Ignacio','San Ignacio',''),('MX','SHO','Sabinas Hidalgo','Sabinas Hidalgo','NLE'),('MX','SIL','Silao','Silao','GUA'),('MX','SJC','San Juan de la Costa','San Juan de la Costa',''),('MX','SJD','San Jose Cabo','San Jose Cabo',''),('MX','SJI','San Jose Iturbide','San Jose Iturbide','GUA'),('MX','SJR','San Juan del Rio','San Juan del Rio',''),('MX','SJT','San Juan Bautista Tuxtepec','San Juan Bautista Tuxtepec','OAX'),('MX','SLO','San Lorenzo','San Lorenzo',''),('MX','SLP','San Luis Potosi','San Luis Potosi','SLP'),('MX','SLT','Teolocholco','Teolocholco','TLA'),('MX','SLU','San Luis de la Paz','San Luis de la Paz','GUA'),('MX','SLW','Saltillo','Saltillo','COA'),('MX','SMC','Salamanca','Salamanca','GUA'),('MX','SMG','San Miguel de Allende','San Miguel de Allende','GUA'),('MX','SMI','Isla San Marcos','Isla San Marcos','BCS'),('MX','SMT','San Martin Texmelucan','San Martin Texmelucan','PUE'),('MX','SND','San Nicolas de los Garza','San Nicolas de los Garza','NLE'),('MX','SNQ','San Quintin','San Quintin',''),('MX','SON','Sonoyta','Sonoyta','SON'),('MX','SRL','Santa Rosalia','Santa Rosalia','BCS'),('MX','STC','Santa Catarina','Santa Catarina','NLE'),('MX','STP','San Pedro Tapanatepec','San Pedro Tapanatepec','OAX'),('MX','STT','Santa Teresa','Santa Teresa','NAY'),('MX','STX','Santiago Tuxtla','Santiago Tuxtla','VER'),('MX','SUN','San Tiburcio','San Tiburcio','ZAC'),('MX','SZT','S.Cristobal deL Casas','S.Cristobal deL Casas',''),('MX','TAC','Tacambaro','Tacambaro','MIC'),('MX','TAM','Tampico','Tampico','TAM'),('MX','TAP','Tapachula','Tapachula','CHP'),('MX','TAX','Tlaxiaco','Tlaxiaco','OAX'),('MX','TCA','Tecamac','Tecamac','MEX'),('MX','TCM','Tecoman','Tecoman','COL'),('MX','TCN','Tehuacan','Tehuacan',''),('MX','TCT','Tecate','Tecate','BCN'),('MX','TCU','Tecuala','Tecuala',''),('MX','TDL','Tepanco de Lopez','Tepanco de Lopez','PUE'),('MX','TEC','Tecolotlan','Tecolotlan','JAL'),('MX','TEL','Teloloapan','Teloloapan','GRO'),('MX','TEN','Tenabo','Tenabo','CAM'),('MX','TEP','Tepatitlan de Morelos','Tepatitlan de Morelos','JAL'),('MX','TEQ','Tequila','Tequila','JAL'),('MX','TGO','Teul de Gonzalez Ortega','Teul de Gonzalez Ortega','ZAC'),('MX','TGZ','Tuxtla Gutierrez','Tuxtla Gutierrez','CHP'),('MX','TIJ','Tijuana','Tijuana','BCN'),('MX','TIN','Tinguindin','Tinguindin','MIC'),('MX','TIX','Tixtla','Tixtla','GRO'),('MX','TIZ','Tizayuca','Tizayuca','HID'),('MX','TLA','Tlalnepantla','Tlalnepantla',''),('MX','TLC','Toluca','Toluca','MEX'),('MX','TLI','Tulancingo','Tulancingo','HID'),('MX','TLP','Tlalneplantla de Baz','Tlalneplantla de Baz','MEX'),('MX','TLQ','Tlaquepaque','Tlaquepaque',''),('MX','TLX','Tlaxmalac','Tlaxmalac','GRO'),('MX','TLY','Tolcayuca','Tolcayuca','HID'),('MX','TLZ','Tilzapotla','Tilzapotla','GRO'),('MX','TMO','Tlajomulco de Zuniga','Tlajomulco de Zuniga','JAL'),('MX','TMP','Tamaulipas','Tamaulipas','SIN'),('MX','TMZ','Tamazula','Tamazula','JAL'),('MX','TNL','Tonala','Tonala','CHP'),('MX','TON','Tonala','Tonala','JAL'),('MX','TPB','Topolobampo','Topolobampo','SIN'),('MX','TPH','Temapache','Temapache','VER'),('MX','TPQ','Tepic','Tepic','NAY'),('MX','TPR','Tepeji de Ocampo','Tepeji de Ocampo','HID'),('MX','TPT','Tepetlalco','Tepetlalco','PUE'),('MX','TPX','Tepexpan','Tepexpan','MEX'),('MX','TPZ','Tepotzotlan','Tepotzotlan','MEX'),('MX','TQQ','Tequisquiapan','Tequisquiapan','QUE'),('MX','TRC','Torreon','Torreon','COA'),('MX','TSL','Tamuin','Tamuin',''),('MX','TTL','Tetla','Tetla','TLA'),('MX','TTN','Tultilan','Tultilan',''),('MX','TUA','Tula','Tula','TAM'),('MX','TUL','Tula de Allende','Tula de Allende','HID'),('MX','TUX','Tuxpan','Tuxpan','VER'),('MX','TUY','Tulum','Tulum',''),('MX','TXH','Telixtlahuaca','Telixtlahuaca','OAX'),('MX','TXL','Tlaxcala','Tlaxcala',''),('MX','TXO','Texcoco','Texcoco','MEX'),('MX','TXP','San Juan Tuxtepec','San Juan Tuxtepec','MEX'),('MX','TZM','Tizimin','Tizimin',''),('MX','UAC','San Luis Rio Colorado','San Luis Rio Colorado',''),('MX','UPN','Uruapan del Progreso','Uruapan del Progreso','MIC'),('MX','URI','Uriangato','Uriangato','GUA'),('MX','VDG','Villa de Garcia','Villa de Garcia','NLE'),('MX','VER','Veracruz','Veracruz','VER'),('MX','VGN','Villagran','Villagran','GUA'),('MX','VGO','Villa Guerrero','Villa Guerrero','MEX'),('MX','VGR','Villa Guerrero','Villa Guerrero','JAL'),('MX','VHM','Valle Hermoso','Valle Hermoso','DUR'),('MX','VIB','Villa Constitucion','Villa Constitucion',''),('MX','VNR','Villa Nicolas Romero','Villa Nicolas Romero','MEX'),('MX','VOC','Venustiano Carranza','Venustiano Carranza','MIC'),('MX','VSA','Villahermosa','Villahermosa','TAB'),('MX','XAL','Xalostoc','Xalostoc','MEX'),('MX','XIH','Zihuatanejo','Zihuatanejo','GRO'),('MX','XMO','Xochimilco','Xochimilco','MEX'),('MX','XPI','Xpichil','Xpichil','ROO'),('MX','YUK','Yukalpeten','Yukalpeten',''),('MX','YZX','Yecapixtla','Yecapixtla','MOR'),('MX','ZAC','Zacatlan','Zacatlan','PUE'),('MX','ZAP','Zapopan','Zapopan','JAL'),('MX','ZCA','Cadereyta Jimenez','Cadereyta Jimenez','NLE'),('MX','ZCL','Zacatecas','Zacatecas','ZAC'),('MX','ZDR','Zumpango del Rio','Zumpango del Rio','GRO'),('MX','ZDT','Zacoalco de Torres','Zacoalco de Torres','JAL'),('MX','ZIH','Ixtapa/Zihuatanejo','Ixtapa/Zihuatanejo',''),('MX','ZIP','Ixtapaluca','Ixtapaluca','MEX'),('MX','ZKP','Zakapu','Zakapu','MIC'),('MX','ZLO','Manzanillo','Manzanillo','COL'),('MX','ZMM','Zamora','Zamora','MIC'),('MX','ZPU','Zumpahuacan','Zumpahuacan','MEX'),('MX','ZRZ','Zaragoza','Zaragoza','PUE'),('MX','ZUM','Zumpango de Ocampo','Zumpango de Ocampo','MEX'),('MY','','','',''),('MY','AOG','Alor Gajah','Alor Gajah',''),('MY','AOR','Alor Setar','Alor Setar',''),('MY','BAG','Bagan Datok','Bagan Datok',''),('MY','BAI','Bangi','Bangi',''),('MY','BAL','Balakong','Balakong',''),('MY','BAN','Banting','Banting',''),('MY','BAT','Batu Pahat','Batu Pahat',''),('MY','BAU','Bau, Sarawak','Bau, Sarawak',''),('MY','BBA','Batu Batu, Sabah','Batu Batu, Sabah',''),('MY','BBN','Bario','Bario',''),('MY','BDV','Bandau, Sabah','Bandau, Sabah',''),('MY','BEL','Beluran, Sabah','Beluran, Sabah',''),('MY','BEN','Bentong','Bentong',''),('MY','BGG','Bunan Gega, Sarawak','Bunan Gega, Sarawak',''),('MY','BGU','Bangau','Bangau',''),('MY','BIA','Biawak, Sarawak','Biawak, Sarawak',''),('MY','BKI','Kota Kinabalu, Sabah','Kota Kinabalu, Sabah',''),('MY','BKM','Ba Kelalan','Ba Kelalan',''),('MY','BKP','Bakapit','Bakapit',''),('MY','BKR','Bukit Keteri','Bukit Keteri',''),('MY','BLE','Bayan Lepas','Bayan Lepas',''),('MY','BLG','Belaga, Sarawak','Belaga, Sarawak',''),('MY','BLI','Batu Lintang, Sarawak','Batu Lintang, Sarawak',''),('MY','BMA','Bandar Maharani','Bandar Maharani',''),('MY','BNG','Binatang, Sarawak','Binatang, Sarawak',''),('MY','BNT','Benut, Johor','Benut, Johor',''),('MY','BRJ','Bukit Raja','Bukit Raja',''),('MY','BRN','Beranang','Beranang',''),('MY','BSE','Sematan, Sarawak','Sematan, Sarawak',''),('MY','BST','Kuala Besut','Kuala Besut',''),('MY','BTG','Betong, Sarawak','Betong, Sarawak',''),('MY','BTN','Bintangor','Bintangor',''),('MY','BTU','Bintulu, Sarawak','Bintulu, Sarawak',''),('MY','BWH','Bagan Luar (Butterworth)','Bagan Luar (Butterworth)',''),('MY','DDW','Danjindawai','Danjindawai',''),('MY','DGN','Dungun (Kuala Dungun)','Dungun (Kuala Dungun)',''),('MY','DRO','Daro, Sarawak','Daro, Sarawak',''),('MY','END','Endau','Endau',''),('MY','GEB','Gebeng','Gebeng',''),('MY','GTK','Sungei Tekai','Sungei Tekai',''),('MY','HUM','Hutan Melintang','Hutan Melintang',''),('MY','IPH','Ipoh','Ipoh',''),('MY','JAM','Jambongan, Sabah','Jambongan, Sabah',''),('MY','JEP','Jelapang','Jelapang',''),('MY','JHB','Johor Bahru','Johor Bahru',''),('MY','JTA','Jitra, Kedah','Jitra, Kedah',''),('MY','KAB','Kabong, Sarawak','Kabong, Sarawak',''),('MY','KAP','Kapar','Kapar',''),('MY','KAR','Kuala Kangsar','Kuala Kangsar',''),('MY','KBA','Kuala Baram','Kuala Baram',''),('MY','KBD','Kota Belud, Sabah','Kota Belud, Sabah',''),('MY','KBE','Kuala Belud, Sabah','Kuala Belud, Sabah',''),('MY','KBR','Kota Bharu','Kota Bharu',''),('MY','KBS','Kuala Besar','Kuala Besar',''),('MY','KCH','Kuching, Sarawak','Kuching, Sarawak',''),('MY','KEL','Kelang','Kelang',''),('MY','KEM','Kemaman','Kemaman',''),('MY','KEP','Kepong Cubitt Forest Village','Kepong Cubitt Forest Village',''),('MY','KES','Kejit','Kejit',''),('MY','KET','Kertih','Kertih',''),('MY','KGR','Kangar','Kangar',''),('MY','KIJ','Kijal','Kijal',''),('MY','KIM','Kimanis, Sabah','Kimanis, Sabah',''),('MY','KKH','Kuala Kedah','Kuala Kedah',''),('MY','KKP','Kukup','Kukup',''),('MY','KLA','Klang','Klang',''),('MY','KLG','Kuala Langat','Kuala Langat',''),('MY','KLM','Kulim','Kulim',''),('MY','KLU','Keluang','Keluang',''),('MY','KPI','Kapit, Sarawak','Kapit, Sarawak',''),('MY','KPS','Kuala Perlis','Kuala Perlis',''),('MY','KPU','Kuala Penyu, Sabah','Kuala Penyu, Sabah',''),('MY','KRE','Krety','Krety',''),('MY','KSD','Kuala Sedili','Kuala Sedili',''),('MY','KSG','Kuala Segama, Sabah','Kuala Segama, Sabah',''),('MY','KSL','Kuala Selangor','Kuala Selangor',''),('MY','KTE','Kerteh','Kerteh',''),('MY','KTI','Kota Tinggi','Kota Tinggi',''),('MY','KUA','Kuantan (Tanjong Gelang)','Kuantan (Tanjong Gelang)',''),('MY','KUD','Kudat, Sabah','Kudat, Sabah',''),('MY','KUG','Kuala Gula','Kuala Gula',''),('MY','KUL','Kuala Lumpur','Kuala Lumpur',''),('MY','KUN','Kunak, Sabah','Kunak, Sabah',''),('MY','KUR','Kampong Ulu Redang','Kampong Ulu Redang',''),('MY','LAH','Lahat','Lahat',''),('MY','LAP','Langkap','Langkap',''),('MY','LBH','Labuan Haji','Labuan Haji',''),('MY','LBU','Labuan, Sabah','Labuan, Sabah',''),('MY','LDU','Lahad Datu, Sabah','Lahad Datu, Sabah',''),('MY','LGG','Lingga, Sarawak','Lingga, Sarawak',''),('MY','LGK','Langkawi','Langkawi',''),('MY','LMN','Limbang, Sarawak','Limbang, Sarawak',''),('MY','LSM','Long Semado','Long Semado',''),('MY','LSU','Long Sukang','Long Sukang',''),('MY','LUM','Lumut','Lumut',''),('MY','LUN','Lundu, Sarawak','Lundu, Sarawak',''),('MY','LUT','Lutong, Sarawak','Lutong, Sarawak',''),('MY','LWY','Lawas, Sarawak','Lawas, Sarawak',''),('MY','MAM','Mak Mandin','Mak Mandin',''),('MY','MAN','Manjung','Manjung',''),('MY','MEL','Menglembu','Menglembu',''),('MY','MEM','Mempakul, Sabah','Mempakul, Sabah',''),('MY','MEN','Nenasi','Nenasi',''),('MY','MEP','Mersing','Mersing',''),('MY','MEU','Meru','Meru',''),('MY','MKM','Mukah, Sarawak','Mukah, Sarawak',''),('MY','MKZ','Malacca','Malacca',''),('MY','MUA','Muar','Muar',''),('MY','MUR','Marudi, Sarawak','Marudi, Sarawak',''),('MY','MYY','Miri, Sarawak','Miri, Sarawak',''),('MY','ODN','Long Seridan','Long Seridan',''),('MY','PAL','Paloh, Sarawak','Paloh, Sarawak',''),('MY','PAN','Panchang','Panchang',''),('MY','PAS','Pasir Gogok','Pasir Gogok',''),('MY','PAY','Pamol','Pamol',''),('MY','PBA','Pulau Batik, Sabah','Pulau Batik, Sabah',''),('MY','PBK','Pelabuhan Kelang','Pelabuhan Kelang',''),('MY','PDI','Port Dickson','Port Dickson',''),('MY','PED','Pedena','Pedena',''),('MY','PEN','Penang (Georgetown)','Penang (Georgetown)',''),('MY','PET','Sungai Petani','Sungai Petani',''),('MY','PGB','Padang Besar','Padang Besar',''),('MY','PGG','Pengerang','Pengerang',''),('MY','PGK','Pangkur','Pangkur',''),('MY','PGU','Pasir Gudang, Johor','Pasir Gudang, Johor',''),('MY','PHI','Pasir Hitam','Pasir Hitam',''),('MY','PJA','Petaling Jaya','Petaling Jaya',''),('MY','PKG','Port Kelang','Port Kelang',''),('MY','PKK','Pengkalan Kubor','Pengkalan Kubor',''),('MY','PMT','Penara Marine Terminal','Penara Marine Terminal',''),('MY','POW','Pontian','Pontian',''),('MY','PPI','Pulau Pisang','Pulau Pisang',''),('MY','PRA','Prai','Prai',''),('MY','PRN','Kuala Rompin','Kuala Rompin',''),('MY','PTB','Pulau Tambisan, Sabah','Pulau Tambisan, Sabah',''),('MY','PUC','Puchong','Puchong',''),('MY','PUN','Punang, Sarawak','Punang, Sarawak',''),('MY','REJ','Rejang, Sarawak','Rejang, Sarawak',''),('MY','RNU','Ranau','Ranau',''),('MY','SAB','Sobak Bernam','Sobak Bernam',''),('MY','SAM','Samu','Samu',''),('MY','SAR','Sarikei','Sarikei',''),('MY','SBL','Sungai Buluh','Sungai Buluh',''),('MY','SBT','Sabahat','Sabahat',''),('MY','SBW','Sibu, Sarawak','Sibu, Sarawak',''),('MY','SDK','Sandakan, Sabah','Sandakan, Sabah',''),('MY','SDM','Sindumin','Sindumin',''),('MY','SDR','Sundar, Sarawak','Sundar, Sarawak',''),('MY','SEI','Senai','Senai',''),('MY','SEJ','Sejingkat, Sarawak','Sejingkat, Sarawak',''),('MY','SEL','Selalang, Sarawak','Selalang, Sarawak',''),('MY','SEP','Sepang, Selangor','Sepang, Selangor',''),('MY','SEW','Senawang','Senawang',''),('MY','SGM','Segamat','Segamat',''),('MY','SHA','Shah Alam','Shah Alam',''),('MY','SIJ','Sijingkat','Sijingkat',''),('MY','SIL','Silay','Silay',''),('MY','SIR','Siran','Siran',''),('MY','SKB','Seri Kembangan','Seri Kembangan',''),('MY','SME','Sri Medan','Sri Medan',''),('MY','SMG','Simanggang, Sarawak','Simanggang, Sarawak',''),('MY','SMJ','Simunjan, Sarawak','Simunjan, Sarawak',''),('MY','SMM','Semporna, Sabah','Semporna, Sabah',''),('MY','SPE','Sepulot','Sepulot',''),('MY','SPG','Simpangan, Sabah','Simpangan, Sabah',''),('MY','SPT','Sipitang, Sabah','Sipitang, Sabah',''),('MY','SRB','Seremban','Seremban',''),('MY','SRE','Sungai Rengit','Sungai Rengit',''),('MY','SRK','Sirikin, Sarawak','Sirikin, Sarawak',''),('MY','SUB','Subang Jaya','Subang Jaya',''),('MY','SUW','Sungai Way','Sungai Way',''),('MY','SWY','Sitiawan','Sitiawan',''),('MY','SXT','Taman Negara','Taman Negara',''),('MY','TAE','Kampong Tasek','Kampong Tasek',''),('MY','TAI','Tampoi','Tampoi',''),('MY','TAM','Tanjung Malim','Tanjung Malim',''),('MY','TAN','Telok Anson','Telok Anson',''),('MY','TAS','Telok Intan','Telok Intan',''),('MY','TAT','Tapis Terminal','Tapis Terminal',''),('MY','TBA','Tanjong Baran','Tanjong Baran',''),('MY','TBE','Tanjong Berhala','Tanjong Berhala',''),('MY','TBI','Tanjong Bin','Tanjong Bin',''),('MY','TDA','Tanjong Dawai','Tanjong Dawai',''),('MY','TEM','Temerloh','Temerloh',''),('MY','TEN','Tengku, Sabah','Tengku, Sabah',''),('MY','TGE','Tanjung Gelang','Tanjung Gelang',''),('MY','TGG','Kuala Terengganu','Kuala Terengganu',''),('MY','TIB','Kampung Tikam Batu','Kampung Tikam Batu',''),('MY','TKI','Tanjong Kidurong','Tanjong Kidurong',''),('MY','TKK','Tangkak','Tangkak',''),('MY','TKL','Tanjong Kling','Tanjong Kling',''),('MY','TKP','Kampong Tanjong Kupang','Kampong Tanjong Kupang',''),('MY','TMB','Tumbum','Tumbum',''),('MY','TMG','Tomanggong','Tomanggong',''),('MY','TMI','Tanjong Mani, Sarawak','Tanjong Mani, Sarawak',''),('MY','TMR','Tanah Merah','Tanah Merah',''),('MY','TOD','Tioman','Tioman',''),('MY','TPG','Taiping','Taiping',''),('MY','TPP','Tanjung Pelepas','Tanjung Pelepas',''),('MY','TRM','Telok Ramunia','Telok Ramunia',''),('MY','TSR','Tanjong Surat','Tanjong Surat',''),('MY','TTE','Tandjung Tengelili','Tandjung Tengelili',''),('MY','TUM','Tumpat','Tumpat',''),('MY','TUN','Tungku','Tungku',''),('MY','TWU','Tawau, Sabah','Tawau, Sabah',''),('MY','UTI','Ulu Tiram','Ulu Tiram',''),('MY','WAL','Wallace Bay, Sabah','Wallace Bay, Sabah',''),('MY','WES','Weston, Sabah','Weston, Sabah',''),('MY','WSP','Westport/Port Klang','Westport/Port Klang',''),('MZ','','','',''),('MZ','AME','Alto Molocue','Alto Molocue',''),('MZ','ANO','Angoche','Angoche',''),('MZ','APL','Nampula','Nampula',''),('MZ','BCW','Benguera Island','Benguera Island',''),('MZ','BEL','Bela Vista','Bela Vista',''),('MZ','BEW','Beira','Beira',''),('MZ','BJN','Bajone','Bajone',''),('MZ','BZB','Bazaruto Island','Bazaruto Island',''),('MZ','CHO','Chokwe','Chokwe',''),('MZ','CMZ','Caia','Caia',''),('MZ','IBO','Ibo','Ibo',''),('MZ','IMG','Inhaminga','Inhaminga',''),('MZ','INE','Chinde','Chinde',''),('MZ','INH','Inhambane','Inhambane',''),('MZ','LBM','Luabo','Luabo',''),('MZ','LMO','Lumbo','Lumbo',''),('MZ','LMZ','Palma','Palma',''),('MZ','MAT','Matola','Matola',''),('MZ','MAX','Maxixe','Maxixe',''),('MZ','MCU','Macuse','Macuse',''),('MZ','MEM','Memba','Memba',''),('MZ','MFW','Magaruque','Magaruque',''),('MZ','MJS','Maganja Da Costa','Maganja Da Costa',''),('MZ','MMW','Moma','Moma',''),('MZ','MNC','Nacala','Nacala',''),('MZ','MOR','Morrumbene','Morrumbene',''),('MZ','MPM','Maputo','Maputo',''),('MZ','MSG','Massinga','Massinga',''),('MZ','MTU','Montepuez','Montepuez',''),('MZ','MUD','Mueda','Mueda',''),('MZ','MZB','Mocimboa da Praia','Mocimboa da Praia',''),('MZ','MZQ','Mocambique','Mocambique',''),('MZ','NND','Nangade','Nangade',''),('MZ','NSO','Nova Sofala','Nova Sofala',''),('MZ','NTC','Santa Carolina','Santa Carolina',''),('MZ','PBE','Porto Belo','Porto Belo',''),('MZ','PEB','Pebane','Pebane',''),('MZ','POL','Pemba','Pemba',''),('MZ','RRM','Marromeu','Marromeu',''),('MZ','TET','Tete','Tete',''),('MZ','UEL','Quelimane','Quelimane',''),('MZ','VJB','Xai-Xai','Xai-Xai',''),('MZ','VJQ','Gurue','Gurue',''),('MZ','VPY','Chimoio','Chimoio',''),('MZ','VXC','Lichinga','Lichinga',''),('NA','','','',''),('NA','ADI','Arandis','Arandis',''),('NA','AIW','Ai-Ais','Ai-Ais',''),('NA','BQI','Bagani','Bagani',''),('NA','GFY','Grootfontein','Grootfontein',''),('NA','GOG','Gobabis','Gobabis',''),('NA','HAL','Halali','Halali',''),('NA','KAS','Karasburg','Karasburg',''),('NA','KMP','Keetmanshoop','Keetmanshoop',''),('NA','KRB','Karibib','Karibib',''),('NA','LUD','Luderitz','Luderitz',''),('NA','MAR','Mariental','Mariental',''),('NA','MJO','Mount Etjo Lodge','Mount Etjo Lodge',''),('NA','MPA','Mpacha','Mpacha',''),('NA','MQG','Midgard','Midgard',''),('NA','NDU','Rundu','Rundu',''),('NA','NNI','Namutoni','Namutoni',''),('NA','OGV','Ongava Game Reserve','Ongava Game Reserve',''),('NA','OHI','Oshakati','Oshakati',''),('NA','OKF','Okaukuejo','Okaukuejo',''),('NA','OKU','Mokuti Lodge','Mokuti Lodge',''),('NA','OMD','Oranjemund','Oranjemund',''),('NA','OMG','Omega','Omega',''),('NA','OND','Ondangwa','Ondangwa',''),('NA','OPW','Opuwa','Opuwa',''),('NA','OTJ','Otjiwarongo','Otjiwarongo',''),('NA','SWP','Swakopmund','Swakopmund',''),('NA','SZM','Sesriem','Sesriem',''),('NA','TCY','Terrace Bay','Terrace Bay',''),('NA','TSB','Tsumeb','Tsumeb',''),('NA','WDH','Windhoek','Windhoek',''),('NA','WOR','Noordoewer','Noordoewer',''),('NA','WVB','Walvis Bay','Walvis Bay',''),('NC','','','',''),('NC','BDB','Baie de Prony','Baie de Prony',''),('NC','BMY','Belep Island','Belep Island',''),('NC','BUG','Baie Ugue','Baie Ugue',''),('NC','DNB','Doniambo/Noumea','Doniambo/Noumea',''),('NC','DUS','Ducos','Ducos',''),('NC','HLU','Houailou','Houailou',''),('NC','ILP','Ile des Pins','Ile des Pins',''),('NC','KNQ','Kone','Kone',''),('NC','KOC','Koumac','Koumac',''),('NC','KOU','Kouaoua','Kouaoua',''),('NC','MEE','Mare','Mare',''),('NC','NAK','Nakety','Nakety',''),('NC','NEP','Nepoui','Nepoui',''),('NC','NOU','Noumea','Noumea',''),('NC','PDC','Station de Mueo','Station de Mueo',''),('NC','PNY','Prony','Prony',''),('NC','POR','Poro','Poro',''),('NC','THI','Thio','Thio',''),('NC','TON','Tontouta','Tontouta',''),('NC','TOU','Touho','Touho',''),('NC','TUD','Teoudie','Teoudie',''),('NC','UVE','Ouvea','Ouvea',''),('NE','','','',''),('NE','AJY','Agades','Agades',''),('NE','BKN','Birni Nkoni','Birni Nkoni',''),('NE','DOG','Dogodountchi','Dogodountchi',''),('NE','DSS','Dosso','Dosso',''),('NE','MAL','Malbaza','Malbaza',''),('NE','MFQ','Maradi','Maradi',''),('NE','NIM','Niamey','Niamey',''),('NE','RLT','Arlit','Arlit',''),('NE','THZ','Tahoua','Tahoua',''),('NE','ZND','Zinder','Zinder',''),('NF','','','',''),('NF','NLK','Norfolk Island','Norfolk Island',''),('NG','','','',''),('NG','ABO','Abonnema','Abonnema',''),('NG','ABV','Abuja','Abuja',''),('NG','ADO','Ado','Ado',''),('NG','AKA','Abeokuta','Abeokuta',''),('NG','AKR','Akure','Akure',''),('NG','AMI','Amaruru Ikeduru','Amaruru Ikeduru',''),('NG','ANT','Anta','Anta',''),('NG','APP','Apapa','Apapa',''),('NG','BAD','Badagri','Badagri',''),('NG','BKA','Bakana','Bakana',''),('NG','BNI','Benin City','Benin City',''),('NG','BON','Bonny','Bonny',''),('NG','BRA','Brass','Brass',''),('NG','BUR','Burutu','Burutu',''),('NG','CBQ','Calabar','Calabar',''),('NG','DEN','Denema','Denema',''),('NG','EKE','Eket','Eket',''),('NG','ENU','Enugu','Enugu',''),('NG','ESC','Escravos','Escravos',''),('NG','FOR','Forcados','Forcados',''),('NG','GRP','Greek Port','Greek Port',''),('NG','IBA','Ibadan','Ibadan',''),('NG','IKE','Ikeja','Ikeja',''),('NG','IKO','Ikorodu','Ikorodu',''),('NG','ILA','Ilesha','Ilesha',''),('NG','ILR','Ilorin','Ilorin',''),('NG','JOS','Jos','Jos',''),('NG','KAD','Kaduna','Kaduna',''),('NG','KAL','Kaltungo','Kaltungo',''),('NG','KAN','Kano','Kano',''),('NG','KIR','Kirikakiri','Kirikakiri',''),('NG','KOK','Koko','Koko',''),('NG','KUL','Kula','Kula',''),('NG','LOS','Lagos','Lagos',''),('NG','MDI','Makurdi','Makurdi',''),('NG','MIU','Maiduguri','Maiduguri',''),('NG','MXJ','Minna','Minna',''),('NG','NSU','Nsukka','Nsukka',''),('NG','OBO','Que Oboe Terminal/Eket','Que Oboe Terminal/Eket',''),('NG','OGB','Ogbomosho','Ogbomosho',''),('NG','OKR','Okrika','Okrika',''),('NG','ONI','Onitsha','Onitsha',''),('NG','ONN','Onne','Onne',''),('NG','ORO','Oron','Oron',''),('NG','OWE','Owerri','Owerri',''),('NG','PEN','Pennington','Pennington',''),('NG','PHC','Port Harcourt','Port Harcourt',''),('NG','QIB','Qua Iboe','Qua Iboe',''),('NG','RDR','Rio Del Rey','Rio Del Rey',''),('NG','SKO','Sokoto','Sokoto',''),('NG','SPL','Sapele','Sapele',''),('NG','TIK','Tiko','Tiko',''),('NG','TIN','Tincan/Lagos','Tincan/Lagos',''),('NG','WAR','Warri','Warri',''),('NG','YOL','Yola','Yola',''),('NG','ZAR','Zaria','Zaria',''),('NI','','','',''),('NI','BEF','Bluefields','Bluefields',''),('NI','BOA','Boaco','Boaco',''),('NI','BZA','Bonanza','Bonanza',''),('NI','CCG','Chichigalpa','Chichigalpa',''),('NI','CHI','Chinandega','Chinandega',''),('NI','CIO','Corinto','Corinto',''),('NI','DIR','Diriamba','Diriamba',''),('NI','ELB','El Bluff','El Bluff',''),('NI','GRA','Granada','Granada',''),('NI','JGP','Juigalpa','Juigalpa',''),('NI','JIN','Jinotepe','Jinotepe',''),('NI','JPA','Jalapa','Jalapa',''),('NI','LEO','Leon','Leon',''),('NI','LPC','La Paz Centro','La Paz Centro',''),('NI','MAL','Malacatoya','Malacatoya',''),('NI','MAS','Masaya','Masaya',''),('NI','MGA','Managua','Managua',''),('NI','MTG','Matagalpa','Matagalpa',''),('NI','NAN','Nandaime','Nandaime',''),('NI','NCR','San Carlos','San Carlos',''),('NI','NUG','Nueva Guinea','Nueva Guinea',''),('NI','OCO','Ocotal','Ocotal',''),('NI','PIB','Puerto Isabel','Puerto Isabel',''),('NI','PRI','Prinzapolca','Prinzapolca',''),('NI','PSN','Puerto Sandino','Puerto Sandino',''),('NI','PSZ','Puerto Somoza','Puerto Somoza',''),('NI','PUZ','Puerto Cabezas','Puerto Cabezas',''),('NI','RAM','Rama','Rama',''),('NI','RFS','Rosita','Rosita',''),('NI','RIB','Rio Blanco','Rio Blanco',''),('NI','RNI','Corn Island','Corn Island',''),('NI','RVV','Rivas','Rivas',''),('NI','SEB','Sebaco','Sebaco',''),('NI','SFL','San Francisco Libre','San Francisco Libre',''),('NI','SIU','Siuna','Siuna',''),('NI','SJS','San Juan del Sur','San Juan del Sur',''),('NI','TEU','Teustepe','Teustepe',''),('NI','WSP','Waspam','Waspam',''),('NL','','','',''),('NL','AAL','Aalst','Aalst',''),('NL','AAM','Aalsmeer','Aalsmeer',''),('NL','AAN','Gaanderen','Gaanderen',''),('NL','AAR','Aardenburg','Aardenburg',''),('NL','ABB','Abbekerk','Abbekerk',''),('NL','ABC','Abcoude','Abcoude',''),('NL','ABE','Abbenes','Abbenes',''),('NL','ABK','Abbenbroek','Abbenbroek',''),('NL','ABL','Alblasserdam','Alblasserdam',''),('NL','ABN','Albergen','Albergen',''),('NL','ADV','Aarlanderveen','Aarlanderveen',''),('NL','AEH','Aerdenhout','Aerdenhout',''),('NL','AER','Almere','Almere',''),('NL','AGT','Abbegaasterketting','Abbegaasterketting',''),('NL','AHO','Achthoven','Achthoven',''),('NL','AIJ','Andijk','Andijk',''),('NL','AJM','Anjum','Anjum',''),('NL','AKK','Almkerk','Almkerk',''),('NL','AKL','Akersloot','Akersloot',''),('NL','AKR','Akkrum','Akkrum',''),('NL','ALB','Aalburg','Aalburg',''),('NL','ALH','Amstelhoek','Amstelhoek',''),('NL','ALK','Alkmaar','Alkmaar',''),('NL','ALM','Almelo','Almelo',''),('NL','ALW','Allingawier','Allingawier',''),('NL','AMB','Aalsmeerderbrug','Aalsmeerderbrug',''),('NL','AME','Amersfoort','Amersfoort',''),('NL','AML','Ameland','Ameland',''),('NL','AMR','Amerongen','Amerongen',''),('NL','AMS','Amsterdam','Amsterdam',''),('NL','AMV','Amstelveen','Amstelveen',''),('NL','AMZ','Ammerzoden','Ammerzoden',''),('NL','ANL','Andel','Andel',''),('NL','ANP','Anna Paulowna','Anna Paulowna',''),('NL','ANT','Andelst','Andelst',''),('NL','APE','Apeldoorn','Apeldoorn',''),('NL','APN','Alphen aan den Rijn','Alphen aan den Rijn',''),('NL','APP','Appingedam','Appingedam',''),('NL','ARC','Arcen','Arcen',''),('NL','ARD','Baard','Baard',''),('NL','ARI','Aarle Rixtel','Aarle Rixtel',''),('NL','ARK','Arkel','Arkel',''),('NL','ARM','Arnemuiden','Arnemuiden',''),('NL','ARN','Arnhem','Arnhem',''),('NL','ASD','Assendelft','Assendelft',''),('NL','ASP','Asperen','Asperen',''),('NL','ASS','Assen','Assen',''),('NL','AST','Asten','Asten',''),('NL','AVE','Avenhorn','Avenhorn',''),('NL','AWD','Albrandswaard','Albrandswaard',''),('NL','AXL','Axel','Axel',''),('NL','AZU','Aan de Zuwe','Aan de Zuwe',''),('NL','BAA','Baarn','Baarn',''),('NL','BAD','Badhoevedorp','Badhoevedorp',''),('NL','BAF','Baflo','Baflo',''),('NL','BAK','Bakel','Bakel',''),('NL','BAL','Balk','Balk',''),('NL','BAN','Bant','Bant',''),('NL','BAR','Barneveld','Barneveld',''),('NL','BAV','Bavel','Bavel',''),('NL','BDA','Birdaard','Birdaard',''),('NL','BDD','Budel-Dorplain','Budel-Dorplain',''),('NL','BDR','Bilderdam','Bilderdam',''),('NL','BEB','Bennebroek','Bennebroek',''),('NL','BEC','Beusichem','Beusichem',''),('NL','BED','Bedum','Bedum',''),('NL','BEE','Beek en Donk','Beek en Donk',''),('NL','BEG','Bergen','Bergen',''),('NL','BEH','Bergh-Autoweg','Bergh-Autoweg',''),('NL','BEI','Beilen','Beilen',''),('NL','BEK','Bergschenhoek','Bergschenhoek',''),('NL','BEM','Bemmel','Bemmel',''),('NL','BEN','Bentveld','Bentveld',''),('NL','BEQ','Beek','Beek',''),('NL','BER','Berkel en Rodenrijs','Berkel en Rodenrijs',''),('NL','BES','Berkel-Enschot','Berkel-Enschot',''),('NL','BEU','Beugen','Beugen',''),('NL','BEV','Beverwijk','Beverwijk',''),('NL','BEW','Beiswijk','Beiswijk',''),('NL','BEY','Bergeijk','Bergeijk',''),('NL','BFD','Belfeld','Belfeld',''),('NL','BGB','Bergambacht','Bergambacht',''),('NL','BGE','Baambrugge','Baambrugge',''),('NL','BGI','Bergerheide','Bergerheide',''),('NL','BGM','Beetgum','Beetgum',''),('NL','BGO','Barsingerhorn','Barsingerhorn',''),('NL','BGR','Borger','Borger',''),('NL','BGU','Bergum','Bergum',''),('NL','BGW','Borgsweer','Borgsweer',''),('NL','BHM','Bartlehiem','Bartlehiem',''),('NL','BHV','Bilthoven','Bilthoven',''),('NL','BHZ','Benthuizen','Benthuizen',''),('NL','BIT','Biest','Biest',''),('NL','BIW','Broek in Waterland','Broek in Waterland',''),('NL','BKB','Balkbrug','Balkbrug',''),('NL','BKE','Berkel','Berkel',''),('NL','BKL','Boekelo','Boekelo',''),('NL','BKM','Bennekom','Bennekom',''),('NL','BLA','Blaricum','Blaricum',''),('NL','BLD','Blaaksedijk','Blaaksedijk',''),('NL','BLE','Blerick','Blerick',''),('NL','BLG','Bleskensgraaf','Bleskensgraaf',''),('NL','BLK','Blokker','Blokker',''),('NL','BLL','Bladel','Bladel',''),('NL','BLO','Baarlo','Baarlo',''),('NL','BLU','Berlicum','Berlicum',''),('NL','BLW','Bleiswijk','Bleiswijk',''),('NL','BMD','Bloemendaal','Bloemendaal',''),('NL','BMK','Boortmeerkerk','Boortmeerkerk',''),('NL','BNB','Bornerbroek','Bornerbroek',''),('NL','BNE','Bunde','Bunde',''),('NL','BNH','Boarnsterhim','Boarnsterhim',''),('NL','BNK','Bunnink','Bunnink',''),('NL','BNM','Binnenmaas','Binnenmaas',''),('NL','BNN','Beuningen','Beuningen',''),('NL','BNS','Baarle-Nassau','Baarle-Nassau',''),('NL','BNU','Buggenum','Buggenum',''),('NL','BNZ','Biddinghuizen','Biddinghuizen',''),('NL','BOE','Boekel','Boekel',''),('NL','BOG','Bodegraven','Bodegraven',''),('NL','BOK','Bontebok','Bontebok',''),('NL','BOL','Bolsward','Bolsward',''),('NL','BON','Born','Born',''),('NL','BOR','Borssele','Borssele',''),('NL','BOT','Botlek','Botlek',''),('NL','BOV','Bovenkarspel','Bovenkarspel',''),('NL','BOX','Boxmeer','Boxmeer',''),('NL','BRA','Baarland','Baarland',''),('NL','BRC','Borculo','Borculo',''),('NL','BRD','Breda','Breda',''),('NL','BRG','Berg','Berg',''),('NL','BRI','Brielle','Brielle',''),('NL','BRK','Brakel','Brakel',''),('NL','BRL','Broek op Langedijk','Broek op Langedijk',''),('NL','BRM','Brummen','Brummen',''),('NL','BRN','Brunssum','Brunssum',''),('NL','BRO','Brouwershaven','Brouwershaven',''),('NL','BRR','Barendrecht','Barendrecht',''),('NL','BRS','Breskens','Breskens',''),('NL','BRU','Bruchem','Bruchem',''),('NL','BRV','Biervliet','Biervliet',''),('NL','BRZ','Breezand','Breezand',''),('NL','BSD','Beesd','Beesd',''),('NL','BSE','Bruinisse','Bruinisse',''),('NL','BSH','Bosscherheide','Bosscherheide',''),('NL','BSK','Boskoop','Boskoop',''),('NL','BSS','Bussum','Bussum',''),('NL','BST','Best','Best',''),('NL','BTA','Bourtange','Bourtange',''),('NL','BTH','Bathmen','Bathmen',''),('NL','BTS','Beets','Beets',''),('NL','BTT','Berg en Terblijt','Berg en Terblijt',''),('NL','BUD','Budel','Budel',''),('NL','BUE','Boesingheliede','Boesingheliede',''),('NL','BUK','Bunnik','Bunnik',''),('NL','BUN','Bunschoten','Bunschoten',''),('NL','BUW','Beneden-Leeuwen','Beneden-Leeuwen',''),('NL','BVG','Burgervlotbrug','Burgervlotbrug',''),('NL','BVI','Bovensmilde','Bovensmilde',''),('NL','BWE','Burgwerd','Burgwerd',''),('NL','BWW','Boornzwaag over de Wielen','Boornzwaag over de Wielen',''),('NL','BXC','Bosch','Bosch',''),('NL','BXE','Baexem','Baexem',''),('NL','BXT','Boxtel','Boxtel',''),('NL','BZL','Blokzijl','Blokzijl',''),('NL','BZM','Bergen op Zoom','Bergen op Zoom',''),('NL','BZO','Biezenmortel','Biezenmortel',''),('NL','BZW','Boornzwaag','Boornzwaag',''),('NL','CAP','Capelle','Capelle',''),('NL','CAS','Castricum','Castricum',''),('NL','COE','Coevorden','Coevorden',''),('NL','COL','Colijnsplaat','Colijnsplaat',''),('NL','COT','Cothen','Cothen',''),('NL','CPI','Capelle aan den IJssel','Capelle aan den IJssel',''),('NL','CRI','Creil','Creil',''),('NL','CRU','Cruquius','Cruquius',''),('NL','CUB','Culemborg','Culemborg',''),('NL','CUY','Cuijk','Cuijk',''),('NL','CZD','Cadzand','Cadzand',''),('NL','DAL','Dalfsen','Dalfsen',''),('NL','DBG','Den Burg','Den Burg',''),('NL','DBI','De Bilt','De Bilt',''),('NL','DBM','Den Bommel','Den Bommel',''),('NL','DBU','Driebruggen','Driebruggen',''),('NL','DDM','Didam','Didam',''),('NL','DDO','Den Dolder','Den Dolder',''),('NL','DED','Dedemsvaart','Dedemsvaart',''),('NL','DEL','Delden','Delden',''),('NL','DEM','De Meern','De Meern',''),('NL','DEN','Denekamp','Denekamp',''),('NL','DEU','Deurne','Deurne',''),('NL','DEV','Deventer','Deventer',''),('NL','DEW','De Wilp','De Wilp',''),('NL','DFT','Delft','Delft',''),('NL','DGW','Delfgauw','Delfgauw',''),('NL','DHA','De Hare','De Hare',''),('NL','DHE','De Heen','De Heen',''),('NL','DHK','De Haukes','De Haukes',''),('NL','DHN','Den Hoorn','Den Hoorn',''),('NL','DHO','Den Hool','Den Hool',''),('NL','DHR','Den Helder','Den Helder',''),('NL','DIE','Diever','Diever',''),('NL','DIK','Dirkshorn','Dirkshorn',''),('NL','DIM','Diemen','Diemen',''),('NL','DIN','Dinteloord','Dinteloord',''),('NL','DIR','Dieren','Dieren',''),('NL','DKO','De Kooy','De Kooy',''),('NL','DKP','De Kempen','De Kempen',''),('NL','DKR','De Krim','De Krim',''),('NL','DKS','Dijkshorne','Dijkshorne',''),('NL','DKW','De Kwakel','De Kwakel',''),('NL','DLR','De Lier','De Lier',''),('NL','DLU','De Lutte','De Lutte',''),('NL','DMK','Demmerik','Demmerik',''),('NL','DNO','Donkerbroek','Donkerbroek',''),('NL','DNR','Dronrijp','Dronrijp',''),('NL','DNU','Dongjum','Dongjum',''),('NL','DOE','Doesburg','Doesburg',''),('NL','DOI','Doetinchem','Doetinchem',''),('NL','DOK','Dokkum','Dokkum',''),('NL','DON','Dongen','Dongen',''),('NL','DOO','Doorn','Doorn',''),('NL','DOR','Dordrecht','Dordrecht',''),('NL','DPH','Diepenheim','Diepenheim',''),('NL','DPO','De Pol','De Pol',''),('NL','DPS','De Poppe','De Poppe',''),('NL','DRA','Drachten','Drachten',''),('NL','DRE','Doenrade','Doenrade',''),('NL','DRI','Driebergen','Driebergen',''),('NL','DRK','Dirksland','Dirksland',''),('NL','DRL','Driel','Driel',''),('NL','DRM','Drimmelen','Drimmelen',''),('NL','DRN','Drunen','Drunen',''),('NL','DRO','Dronten','Dronten',''),('NL','DRP','De Rijp','De Rijp',''),('NL','DRS','Dorst','Dorst',''),('NL','DRU','Druten','Druten',''),('NL','DSE','Diessen','Diessen',''),('NL','DSG','De Steeg','De Steeg',''),('NL','DSI','Doodstil','Doodstil',''),('NL','DSM','Driesum','Driesum',''),('NL','DSO','De Strook','De Strook',''),('NL','DST','Deest','Deest',''),('NL','DTK','Den Hoorn, Texel','Den Hoorn, Texel',''),('NL','DUG','Dukenburg','Dukenburg',''),('NL','DUI','Duiven','Duiven',''),('NL','DUM','Dreumel','Dreumel',''),('NL','DUS','Dussen','Dussen',''),('NL','DUZ','Duizel','Duizel',''),('NL','DVB','Dieverbrug','Dieverbrug',''),('NL','DVT','Duivendrecht','Duivendrecht',''),('NL','DWA','Dodewaard','Dodewaard',''),('NL','DWK','De Wijk','De Wijk',''),('NL','DXP','Dinxperlo','Dinxperlo',''),('NL','DZK','De Zilk','De Zilk',''),('NL','DZL','Delfzijl','Delfzijl',''),('NL','EAZ','Egmond aan Zee','Egmond aan Zee',''),('NL','ECD','Echteld','Echteld',''),('NL','ECH','Echt','Echt',''),('NL','EDE','Ede','Ede',''),('NL','EDM','Edam','Edam',''),('NL','EED','Eede','Eede',''),('NL','EEE','Eerbeek','Eerbeek',''),('NL','EEL','Eelde-Paterswolde','Eelde-Paterswolde',''),('NL','EEM','Eemshaven','Eemshaven',''),('NL','EEN','Eenrum','Eenrum',''),('NL','EES','Eemnes','Eemnes',''),('NL','EFE','Eefde','Eefde',''),('NL','EGL','Egchel','Egchel',''),('NL','EHU','Echtenerbrug','Echtenerbrug',''),('NL','EIB','Eibergen','Eibergen',''),('NL','EIN','Eindhoven','Eindhoven',''),('NL','ELB','Elburg','Elburg',''),('NL','ELL','Ellecom','Ellecom',''),('NL','ELO','Elsloo','Elsloo',''),('NL','ELS','Elsendorp','Elsendorp',''),('NL','ELX','Ell','Ell',''),('NL','ELZ','Ellerhuizen','Ellerhuizen',''),('NL','EMC','Emmer-Compascuum','Emmer-Compascuum',''),('NL','EME','Emmer-Erfscheidenveen','Emmer-Erfscheidenveen',''),('NL','EML','Emmeloord','Emmeloord',''),('NL','EMM','Emmen','Emmen',''),('NL','ENG','Engwierum','Engwierum',''),('NL','ENK','Enkhuizen','Enkhuizen',''),('NL','ENP','Enspijk','Enspijk',''),('NL','ENS','Enschede','Enschede',''),('NL','ENX','Ens','Ens',''),('NL','EPE','Epe','Epe',''),('NL','EPL','Empel','Empel',''),('NL','EPN','Epen','Epen',''),('NL','ERA','Erica','Erica',''),('NL','ERI','Eric','Eric',''),('NL','ERM','Ermelo','Ermelo',''),('NL','ERP','Erp','Erp',''),('NL','ESP','Espel','Espel',''),('NL','ETN','Echten','Echten',''),('NL','ETT','Etten Leur','Etten Leur',''),('NL','EUR','Europoort','Europoort',''),('NL','EVG','Everingen','Everingen',''),('NL','EVN','Ederveen','Ederveen',''),('NL','EWK','Ewijk','Ewijk',''),('NL','EWO','Eernewoude','Eernewoude',''),('NL','EXZ','Exmorrazijl','Exmorrazijl',''),('NL','EYS','Eijsden','Eijsden',''),('NL','FAR','Farmsum','Farmsum',''),('NL','FEE','Feerwerd','Feerwerd',''),('NL','FFJ','Fijnaart','Fijnaart',''),('NL','FJA','Fonejacht','Fonejacht',''),('NL','FKP','Fraamklap','Fraamklap',''),('NL','FOX','Foxhol','Foxhol',''),('NL','FRK','Franeker','Franeker',''),('NL','GAM','Gameren','Gameren',''),('NL','GAR','Garderen','Garderen',''),('NL','GAS','Gassel','Gassel',''),('NL','GBC','Grevenbicht','Grevenbicht',''),('NL','GBG','Gramsbergen','Gramsbergen',''),('NL','GBV','Grubbenvorst','Grubbenvorst',''),('NL','GDK','Gouderak','Gouderak',''),('NL','GDM','Geldermalsen','Geldermalsen',''),('NL','GDO','Groot Dochteren','Groot Dochteren',''),('NL','GDR','Goedereede','Goedereede',''),('NL','GEC','Gellicum','Gellicum',''),('NL','GEE','Geleen','Geleen',''),('NL','GEM','Gemert','Gemert',''),('NL','GEN','Gennep','Gennep',''),('NL','GET','Gendt','Gendt',''),('NL','GFN','Geffen','Geffen',''),('NL','GGN','Gendringen','Gendringen',''),('NL','GHO','Giethoorn','Giethoorn',''),('NL','GIB','Giesbeek','Giesbeek',''),('NL','GIS','Giessen','Giessen',''),('NL','GKN','Gaarkeuken','Gaarkeuken',''),('NL','GLA','Glanerbrug','Glanerbrug',''),('NL','GLD','Geldrop','Geldrop',''),('NL','GLL','Geulle','Geulle',''),('NL','GME','Gaastmeer','Gaastmeer',''),('NL','GND','Genderen','Genderen',''),('NL','GNK','Groenekan','Groenekan',''),('NL','GNM','Genemuiden','Genemuiden',''),('NL','GOE','Goes','Goes',''),('NL','GOI','Goirle','Goirle',''),('NL','GOJ','Goingarijp','Goingarijp',''),('NL','GOK','Grootebroek','Grootebroek',''),('NL','GOO','Goor','Goor',''),('NL','GOR','Gorinchem','Gorinchem',''),('NL','GOU','Gouda','Gouda',''),('NL','GOW','Goudswaard','Goudswaard',''),('NL','GOY','\'t Goy','\'t Goy',''),('NL','GRA','\'s-Gravendeel','\'s-Gravendeel',''),('NL','GRK','Groenendijk','Groenendijk',''),('NL','GRN','Groenlo','Groenlo',''),('NL','GRO','Groot-Ammers','Groot-Ammers',''),('NL','GRQ','Groningen','Groningen',''),('NL','GRS','Groessen','Groessen',''),('NL','GRV','Geervliet','Geervliet',''),('NL','GRW','Groeneweg','Groeneweg',''),('NL','GRZ','\'s-Gravenzande','\'s-Gravenzande',''),('NL','GSB','Geesbrug','Geesbrug',''),('NL','GSM','Giessendam','Giessendam',''),('NL','GST','Gasteren','Gasteren',''),('NL','GTB','Geertruidenberg','Geertruidenberg',''),('NL','GWD','Groenewoud','Groenewoud',''),('NL','GWO','Garmerwolde','Garmerwolde',''),('NL','GWU','Geeuwenbrug','Geeuwenbrug',''),('NL','GZE','Gilze','Gilze',''),('NL','GZR','Gilzerijen','Gilzerijen',''),('NL','HAA','Haarlem','Haarlem',''),('NL','HAE','Haelen','Haelen',''),('NL','HAG','\'s-Gravenhage (Den Haag)','\'s-Gravenhage (Den Haag)',''),('NL','HAL','Halsteren','Halsteren',''),('NL','HAM','Harmelen','Harmelen',''),('NL','HAN','Hansweert','Hansweert',''),('NL','HAP','Hapert','Hapert',''),('NL','HAR','Harlingen','Harlingen',''),('NL','HAS','Hasselt','Hasselt',''),('NL','HAU','Haulerwijk','Haulerwijk',''),('NL','HAZ','Hazerswoude','Hazerswoude',''),('NL','HBG','Hardenberg','Hardenberg',''),('NL','HBK','Haaldersbroek','Haaldersbroek',''),('NL','HBR','Hoensbroek','Hoensbroek',''),('NL','HBU','Hogebrug','Hogebrug',''),('NL','HCH','Haastrecht','Haastrecht',''),('NL','HDL','Hedel','Hedel',''),('NL','HE','Hengevelde','Hengevelde',''),('NL','HEC','Heesch','Heesch',''),('NL','HEE','Heel','Heel',''),('NL','HEG','Heeg','Heeg',''),('NL','HEJ','Heijen','Heijen',''),('NL','HEL','Helden','Helden',''),('NL','HEN','Heerlen','Heerlen',''),('NL','HES','Heusden','Heusden',''),('NL','HEU','Heurne','Heurne',''),('NL','HFD','Hoofddorp','Hoofddorp',''),('NL','HFN','Haaften','Haaften',''),('NL','HFW','Halfweg','Halfweg',''),('NL','HGL','Hengelo','Hengelo',''),('NL','HGM','Hoogmade','Hoogmade',''),('NL','HGV','Hoogvliet','Hoogvliet',''),('NL','HGX','Hooge-Hexel','Hooge-Hexel',''),('NL','HGZ','Hoogezand','Hoogezand',''),('NL','HHW','Heerhugowaard','Heerhugowaard',''),('NL','HIA','Hendrik-Ido-Ambacht','Hendrik-Ido-Ambacht',''),('NL','HIL','Hillegom','Hillegom',''),('NL','HJY','Heijningen','Heijningen',''),('NL','HKD','Haskerdijken','Haskerdijken',''),('NL','HKE','Heemskerk','Heemskerk',''),('NL','HKF','Heerjansdam','Heerjansdam',''),('NL','HKG','Hakkelaarsbrug','Hakkelaarsbrug',''),('NL','HKH','Haaksbergen','Haaksbergen',''),('NL','HKI','Herkingen','Herkingen',''),('NL','HKM','Hijkersmilde','Hijkersmilde',''),('NL','HKO','Hekendorp','Hekendorp',''),('NL','HKP','Hoogkarspel','Hoogkarspel',''),('NL','HKT','Heikant','Heikant',''),('NL','HLL','Hallum','Hallum',''),('NL','HLM','Helmond','Helmond',''),('NL','HLO','Heiloo','Heiloo',''),('NL','HLP','Hindeloopen','Hindeloopen',''),('NL','HLR','Haarlemmerliede','Haarlemmerliede',''),('NL','HLT','Holten','Holten',''),('NL','HMD','Hooge Mierde','Hooge Mierde',''),('NL','HME','Holtheme','Holtheme',''),('NL','HMI','Hoogersmilde','Hoogersmilde',''),('NL','HMS','Heemstede','Heemstede',''),('NL','HNA','Hoornaar','Hoornaar',''),('NL','HNK','Hank','Hank',''),('NL','HNN','Heinen','Heinen',''),('NL','HNO','Heino','Heino',''),('NL','HNS','Honselersdijk','Honselersdijk',''),('NL','HOD','Heinenoord','Heinenoord',''),('NL','HOE','Hoevelaken','Hoevelaken',''),('NL','HOG','Hooglanderveen','Hooglanderveen',''),('NL','HOH','Hoogerheide','Hoogerheide',''),('NL','HOL','Hoogland','Hoogland',''),('NL','HON','Hoeven','Hoeven',''),('NL','HOO','Hoogwoud','Hoogwoud',''),('NL','HOR','Hordijkerveld','Hordijkerveld',''),('NL','HOT','Holt','Holt',''),('NL','HOU','Houten','Houten',''),('NL','HOV','Hoogeveen','Hoogeveen',''),('NL','HOX','Horn','Horn',''),('NL','HOZ','Hooge Zwaluwe','Hooge Zwaluwe',''),('NL','HPE','Hempens','Hempens',''),('NL','HPL','Hoofdplaat','Hoofdplaat',''),('NL','HPN','Herpen','Herpen',''),('NL','HPS','Haps','Haps',''),('NL','HPT','Hoptille','Hoptille',''),('NL','HRA','Haaren','Haaren',''),('NL','HRB','s-Heerenberg','s-Heerenberg',''),('NL','HRD','Harderwijk','Harderwijk',''),('NL','HRE','Haren','Haren',''),('NL','HRK','Herkenbosch','Herkenbosch',''),('NL','HRL','Heerlen-Autoweg','Heerlen-Autoweg',''),('NL','HRN','Hoorn','Hoorn',''),('NL','HRS','Horst','Horst',''),('NL','HRV','Heerenveen','Heerenveen',''),('NL','HRW','Heerewaarden','Heerewaarden',''),('NL','HRX','Boven-Hardinxveld','Boven-Hardinxveld',''),('NL','HSL','Hellevoetsluis','Hellevoetsluis',''),('NL','HSN','Hagestein','Hagestein',''),('NL','HSO','Holsloot','Holsloot',''),('NL','HST','Haghorst','Haghorst',''),('NL','HSW','Heeswijk','Heeswijk',''),('NL','HTB','\'s-Hertogenbosch','\'s-Hertogenbosch',''),('NL','HTH','Huis ter Heide','Huis ter Heide',''),('NL','HTK','Hattemerbroek','Hattemerbroek',''),('NL','HTM','Hattem','Hattem',''),('NL','HTN','Hontenisse','Hontenisse',''),('NL','HTR','Heteren','Heteren',''),('NL','HUI','Huizen','Huizen',''),('NL','HUL','Hulst','Hulst',''),('NL','HUM','Heumen','Heumen',''),('NL','HUN','Hunsel','Hunsel',''),('NL','HVD','Herveld','Herveld',''),('NL','HVE','Havelte','Havelte',''),('NL','HVH','Hoek van Holland','Hoek van Holland',''),('NL','HVK','Hilvarenbeek','Hilvarenbeek',''),('NL','HVO','Helvoirt','Helvoirt',''),('NL','HVS','Hilversum','Hilversum',''),('NL','HYY','Heythuysen','Heythuysen',''),('NL','HZA','Heinkensand','Heinkensand',''),('NL','HZD','Hoogezand','Hoogezand',''),('NL','HZE','Heeze','Heeze',''),('NL','HZK','Hazeldonck','Hazeldonck',''),('NL','IJI','IJsselstein','IJsselstein',''),('NL','IJM','IJmuiden','IJmuiden',''),('NL','ILO','Illikhoven','Illikhoven',''),('NL','ILP','Ilpendam','Ilpendam',''),('NL','ITR','Itteren','Itteren',''),('NL','ITT','Ittervoort','Ittervoort',''),('NL','IZD','IJzendijke','IJzendijke',''),('NL','JLD','Julianadorp','Julianadorp',''),('NL','JNE','Junne','Junne',''),('NL','JOU','Joure','Joure',''),('NL','KAD','Kamperland','Kamperland',''),('NL','KAG','Kaag','Kaag',''),('NL','KAI','Krimpen aan den IJssel','Krimpen aan den IJssel',''),('NL','KAM','Kampen','Kampen',''),('NL','KAP','Kapellebrug','Kapellebrug',''),('NL','KAT','Kats','Kats',''),('NL','KAZ','Katwijk aan Zee','Katwijk aan Zee',''),('NL','KDM','Koudum','Koudum',''),('NL','KEB','Keijenborg','Keijenborg',''),('NL','KEK','Kekerdom','Kekerdom',''),('NL','KER','Kerkrade','Kerkrade',''),('NL','KGH','Konigsbosch','Konigsbosch',''),('NL','KGZ','Koog aan de Zaan','Koog aan de Zaan',''),('NL','KHO','Kuikhorne','Kuikhorne',''),('NL','KHR','Kolhorn','Kolhorn',''),('NL','KHV','Ketelhaven','Ketelhaven',''),('NL','KIJ','Kinderdijk','Kinderdijk',''),('NL','KKO','Kakeshoek','Kakeshoek',''),('NL','KLM','Kollum','Kollum',''),('NL','KLT','Kloosterzande','Kloosterzande',''),('NL','KLU','Klundert','Klundert',''),('NL','KLV','Kloosterveen','Kloosterveen',''),('NL','KLW','Klaaswaal','Klaaswaal',''),('NL','KLZ','Klazienaveen','Klazienaveen',''),('NL','KML','Kommerzijl','Kommerzijl',''),('NL','KMR','Kamerik','Kamerik',''),('NL','KMS','Krammersluizen','Krammersluizen',''),('NL','KOG','Kortgene','Kortgene',''),('NL','KOK','Koudekerke','Koudekerke',''),('NL','KOR','Koudekerk aan den Rijn','Koudekerk aan den Rijn',''),('NL','KPE','Kelpen','Kelpen',''),('NL','KPL','Kapelle','Kapelle',''),('NL','KRD','Kerkdriel','Kerkdriel',''),('NL','KRE','Kreil','Kreil',''),('NL','KRI','\'t Kruis','\'t Kruis',''),('NL','KRM','Krommenie','Krommenie',''),('NL','KRP','Krimpen aan de Lek','Krimpen aan de Lek',''),('NL','KRU','Kruiningen','Kruiningen',''),('NL','KSL','Kessel','Kessel',''),('NL','KST','Kesteren','Kesteren',''),('NL','KTH','Kortenhoef','Kortenhoef',''),('NL','KTN','Kantens','Kantens',''),('NL','KTS','Kaatsheuvel','Kaatsheuvel',''),('NL','KTV','Katerveer','Katerveer',''),('NL','KWA','Kwadendamme','Kwadendamme',''),('NL','KWK','Katwijk','Katwijk',''),('NL','KWR','Katwijk aan den Rijn','Katwijk aan den Rijn',''),('NL','KWS','Kwintsheul','Kwintsheul',''),('NL','KWT','Koewacht','Koewacht',''),('NL','KWZ','Kornwerderzand','Kornwerderzand',''),('NL','KZV','Keizersveer','Keizersveer',''),('NL','LAF','Landgraaf','Landgraaf',''),('NL','LAG','Langerak','Langerak',''),('NL','LAK','Langbroek','Langbroek',''),('NL','LAM','Landsmeer','Landsmeer',''),('NL','LAN','Lauwersoog','Lauwersoog',''),('NL','LAR','Laren','Laren',''),('NL','LAV','Loenen aan de Vecht','Loenen aan de Vecht',''),('NL','LAW','Lage Weide','Lage Weide',''),('NL','LBK','Lisserbroek','Lisserbroek',''),('NL','LCH','Lochem','Lochem',''),('NL','LCV','Lichtenvoorde','Lichtenvoorde',''),('NL','LDD','Leiderdorp','Leiderdorp',''),('NL','LDS','Leidschendam','Leidschendam',''),('NL','LEE','Leek','Leek',''),('NL','LEK','Lekkerkerk','Lekkerkerk',''),('NL','LEM','Lemsterland','Lemsterland',''),('NL','LEO','Leons','Leons',''),('NL','LES','Leens','Leens',''),('NL','LEU','Leusden','Leusden',''),('NL','LEY','Lelystad','Lelystad',''),('NL','LGB','Landgoed Baest','Landgoed Baest',''),('NL','LGD','Lageland','Lageland',''),('NL','LGI','Langelille','Langelille',''),('NL','LGW','Langweer','Langweer',''),('NL','LID','Leiden','Leiden',''),('NL','LIE','Lienden','Lienden',''),('NL','LIN','Linne','Linne',''),('NL','LIT','Lith','Lith',''),('NL','LKL','Lopikerkapel','Lopikerkapel',''),('NL','LKN','\'t Leuken','\'t Leuken',''),('NL','LME','Limmel','Limmel',''),('NL','LMM','Limmen','Limmen',''),('NL','LMR','Lemmer','Lemmer',''),('NL','LMU','Leimuiden','Leimuiden',''),('NL','LNO','Loenersloot','Loenersloot',''),('NL','LNT','Lent','Lent',''),('NL','LOB','Lobith','Lobith',''),('NL','LOM','Lomm','Lomm',''),('NL','LON','Loenen','Loenen',''),('NL','LOS','Losser','Losser',''),('NL','LPK','Lopik','Lopik',''),('NL','LRD','Leerdam','Leerdam',''),('NL','LRU','Leimuiderbrug','Leimuiderbrug',''),('NL','LSC','Linschoten','Linschoten',''),('NL','LSH','Lieshout','Lieshout',''),('NL','LSR','Nieuw-Loosdrecht','Nieuw-Loosdrecht',''),('NL','LTE','Aalten','Aalten',''),('NL','LTH','Leuth','Leuth',''),('NL','LTS','Laatste Stuiver','Laatste Stuiver',''),('NL','LWE','Lalleweer','Lalleweer',''),('NL','LWG','Langeweg','Langeweg',''),('NL','LWI','Lauwerzijl','Lauwerzijl',''),('NL','LWO','Lippenwoude','Lippenwoude',''),('NL','LWR','Leeuwarden','Leeuwarden',''),('NL','LXM','Lexmond','Lexmond',''),('NL','LZA','Lage Zwaluwe','Lage Zwaluwe',''),('NL','LZG','Langezwaag','Langezwaag',''),('NL','MAB','Maarsbergen','Maarsbergen',''),('NL','MAD','Malden','Malden',''),('NL','MAL','Maasland','Maasland',''),('NL','MAN','Marknesse','Marknesse',''),('NL','MAR','Markelo','Markelo',''),('NL','MAU','Maurik','Maurik',''),('NL','MAV','Maarn','Maarn',''),('NL','MBK','Milsbeek','Milsbeek',''),('NL','MCK','Melick','Melick',''),('NL','MDB','Middelbeers','Middelbeers',''),('NL','MDG','Muiderberg','Muiderberg',''),('NL','MDK','Maasdijk','Maasdijk',''),('NL','MDL','Middelburg','Middelburg',''),('NL','MDM','Medemblik','Medemblik',''),('NL','MDO','Melderslo','Melderslo',''),('NL','MDT','Mildert','Mildert',''),('NL','MDU','Middelstum','Middelstum',''),('NL','MEB','Merkelbeek','Merkelbeek',''),('NL','MEE','Meer','Meer',''),('NL','MEP','Meppel','Meppel',''),('NL','MES','Meers','Meers',''),('NL','MEW','Meerlo-Wansum','Meerlo-Wansum',''),('NL','MGT','Molengat','Molengat',''),('NL','MHU','Maarhuizen','Maarhuizen',''),('NL','MHZ','Maarheeze','Maarheeze',''),('NL','MID','Middelburg','Middelburg',''),('NL','MIE','Mierlo','Mierlo',''),('NL','MIH','Middelharnis','Middelharnis',''),('NL','MIJ','Mijdrecht','Mijdrecht',''),('NL','MJA','Mandjeswaard','Mandjeswaard',''),('NL','MKE','Munnekeburen','Munnekeburen',''),('NL','MKK','Meerkerk','Meerkerk',''),('NL','MKN','Marken','Marken',''),('NL','MKP','Moerkapelle','Moerkapelle',''),('NL','MKZ','Munnekezijl','Munnekezijl',''),('NL','MLA','Middelaar','Middelaar',''),('NL','MLL','Mill','Mill',''),('NL','MLR','Millingen aan de Rijn','Millingen aan de Rijn',''),('NL','MNN','Monnickendam','Monnickendam',''),('NL','MNT','Montfoort','Montfoort',''),('NL','MNU','Menaldum','Menaldum',''),('NL','MOE','Moerdijk','Moerdijk',''),('NL','MOG','Molenaarsgraaf','Molenaarsgraaf',''),('NL','MOK','Mook','Mook',''),('NL','MOL','Molenhoek','Molenhoek',''),('NL','MON','Monster','Monster',''),('NL','MOO','Moordrecht','Moordrecht',''),('NL','MOT','Molenschot','Molenschot',''),('NL','MRM','Marum','Marum',''),('NL','MRS','Maarssenbroek','Maarssenbroek',''),('NL','MRT','Maartensdijk','Maartensdijk',''),('NL','MRU','Marssum','Marssum',''),('NL','MSB','Maasbracht','Maasbracht',''),('NL','MSD','Maasdam','Maasdam',''),('NL','MSL','Maassluis','Maassluis',''),('NL','MSS','Maarssen','Maarssen',''),('NL','MST','Maastricht','Maastricht',''),('NL','MSV','Maasvlakte','Maasvlakte',''),('NL','MSW','Mensingeweer','Mensingeweer',''),('NL','MUD','Muiden','Muiden',''),('NL','MVE','Middelie','Middelie',''),('NL','NAA','Naarden','Naarden',''),('NL','NAM','Nieuw-Amsterdam','Nieuw-Amsterdam',''),('NL','NAW','Naaldwijk','Naaldwijk',''),('NL','NBG','Nieuwerbrug','Nieuwerbrug',''),('NL','NBU','Nieuwe Brug','Nieuwe Brug',''),('NL','NBW','Neder-Betuwe','Neder-Betuwe',''),('NL','NDB','Nederhorst den Berg','Nederhorst den Berg',''),('NL','NDI','Nieuwediep','Nieuwediep',''),('NL','NDL','Noordwijk aan Zee','Noordwijk aan Zee',''),('NL','NDP','Nootdorp','Nootdorp',''),('NL','NEC','Neck','Neck',''),('NL','NEE','Neede','Neede',''),('NL','NER','Neer','Neer',''),('NL','NES','Nes','Nes',''),('NL','NGA','Nijega','Nijega',''),('NL','NGV','Nigtevecht','Nigtevecht',''),('NL','NHE','Nijehaske','Nijehaske',''),('NL','NHM','Nieuwehorne','Nieuwehorne',''),('NL','NIE','Nieuwerkerk aan den IJssel','Nieuwerkerk aan den IJssel',''),('NL','NIH','Nieuwenhagen','Nieuwenhagen',''),('NL','NIJ','Nijmegen','Nijmegen',''),('NL','NIS','Nispen','Nispen',''),('NL','NIU','Nieuwdorp','Nieuwdorp',''),('NL','NKK','Nijkerk','Nijkerk',''),('NL','NKV','Nijkerkerveen','Nijkerkerveen',''),('NL','NLG','Nagele','Nagele',''),('NL','NLK','Nieuw-Lekkerland','Nieuw-Lekkerland',''),('NL','NMD','Nijemirdum','Nijemirdum',''),('NL','NNE','Annen','Annen',''),('NL','NNN','Nuenen','Nuenen',''),('NL','NOJ','Noordwijkerhout','Noordwijkerhout',''),('NL','NPK','Nieuwe Pekela','Nieuwe Pekela',''),('NL','NRW','Nederweert','Nederweert',''),('NL','NSA','Nes aan de Amstel','Nes aan de Amstel',''),('NL','NSB','Nieuwe Schans','Nieuwe Schans',''),('NL','NSC','Nieuweschans','Nieuweschans',''),('NL','NSD','Nieuw-Scheemda','Nieuw-Scheemda',''),('NL','NSS','Nisse','Nisse',''),('NL','NST','Nederasselt','Nederasselt',''),('NL','NSU','Nessersluis','Nessersluis',''),('NL','NSW','Noord-Scharwoude','Noord-Scharwoude',''),('NL','NSZ','Nieuwe Statenzijl','Nieuwe Statenzijl',''),('NL','NTH','Nuth','Nuth',''),('NL','NTO','Ten Boer','Ten Boer',''),('NL','NUD','Numansdorp','Numansdorp',''),('NL','NUI','Nuis','Nuis',''),('NL','NUN','Nunspeet','Nunspeet',''),('NL','NVD','Nijverdal','Nijverdal',''),('NL','NVE','Nieuw-Vennep','Nieuw-Vennep',''),('NL','NVO','Nieuw-Vossemeer','Nieuw-Vossemeer',''),('NL','NVP','Nieuw-Vennep','Nieuw-Vennep',''),('NL','NWD','Noordwolde','Noordwolde',''),('NL','NWG','Nieuwegein','Nieuwegein',''),('NL','NWK','Nieuwkoop','Nieuwkoop',''),('NL','NWL','Nieuwleusen','Nieuwleusen',''),('NL','NWO','Nieuwolda','Nieuwolda',''),('NL','NWP','Nieuwpoort','Nieuwpoort',''),('NL','NWS','Nieuwstadt','Nieuwstadt',''),('NL','NWT','Nieuwe-Tonge','Nieuwe-Tonge',''),('NL','NWV','Nieuwveen','Nieuwveen',''),('NL','NZI','Niezijl','Niezijl',''),('NL','NZJ','Nijezijl','Nijezijl',''),('NL','OAI','Ouderkerk aan den IJssel','Ouderkerk aan den IJssel',''),('NL','OBD','Obdam','Obdam',''),('NL','OBG','Oostburg','Oostburg',''),('NL','OBL','Oud-Beijerland','Oud-Beijerland',''),('NL','OBO','Oudenbosch','Oudenbosch',''),('NL','OCC','Ochten','Ochten',''),('NL','ODH','Oudenhoorn','Oudenhoorn',''),('NL','ODK','Odijk','Odijk',''),('NL','ODN','Odoorn','Odoorn',''),('NL','ODP','Oude Pekela','Oude Pekela',''),('NL','ODR','Ouderkerk aan de Amstel','Ouderkerk aan de Amstel',''),('NL','ODT','Oude-Tonge','Oude-Tonge',''),('NL','ODW','Oudewater','Oudewater',''),('NL','OED','St Oedenrode','St Oedenrode',''),('NL','OGA','Oudega','Oudega',''),('NL','OGE','Oegstgeest','Oegstgeest',''),('NL','OGN','Oud Gein','Oud Gein',''),('NL','OGP','Ooltgensplaat','Ooltgensplaat',''),('NL','OHE','Oudehaske','Oudehaske',''),('NL','OHI','Oudeschild','Oudeschild',''),('NL','OHM','Oosthem','Oosthem',''),('NL','OHN','Oosterhesselen','Oosterhesselen',''),('NL','OHW','Oude Schouw','Oude Schouw',''),('NL','OHZ','Oosthuizen','Oosthuizen',''),('NL','OIH','Oirschot','Oirschot',''),('NL','OIW','Oisterwijk','Oisterwijk',''),('NL','OLD','Oldeberkoop','Oldeberkoop',''),('NL','OLK','Oldemarkt','Oldemarkt',''),('NL','OLO','Oud-Loosdrecht','Oud-Loosdrecht',''),('NL','OLS','Oosterlittens','Oosterlittens',''),('NL','OLZ','Oldenzaal','Oldenzaal',''),('NL','OMD','Roermond','Roermond',''),('NL','OME','Oostermeer','Oostermeer',''),('NL','OMM','Ommen','Ommen',''),('NL','OMR','Oudemirdum','Oudemirdum',''),('NL','OOS','Oosterhout','Oosterhout',''),('NL','OOT','Ootmarsum','Ootmarsum',''),('NL','OOY','Ooij','Ooij',''),('NL','OPE','Opeinde','Opeinde',''),('NL','ORJ','Oudenrijn','Oudenrijn',''),('NL','ORL','Oterleek','Oterleek',''),('NL','OSB','Oosterbeek','Oosterbeek',''),('NL','OSD','Oostdijk','Oostdijk',''),('NL','OSG','Oud-Sabbinge','Oud-Sabbinge',''),('NL','OSH','Ossendrecht','Ossendrecht',''),('NL','OSK','Overschild','Overschild',''),('NL','OSL','Oudesluis','Oudesluis',''),('NL','OSP','Ospel','Ospel',''),('NL','OSS','Oss','Oss',''),('NL','OST','Oostrum','Oostrum',''),('NL','OSW','Oosterwolde','Oosterwolde',''),('NL','OSZ','Oostzaan','Oostzaan',''),('NL','OTL','Oosterland','Oosterland',''),('NL','OUG','Oud-Gastel','Oud-Gastel',''),('NL','OUM','Oude Meer','Oude Meer',''),('NL','OVL','Overloon','Overloon',''),('NL','OVM','Oud-Vossemeer','Oud-Vossemeer',''),('NL','OVN','Oostvoorne','Oostvoorne',''),('NL','OVR','Oud-Vroenhoven','Oud-Vroenhoven',''),('NL','OVZ','Ovezande','Ovezande',''),('NL','OZL','Ossenzijl','Ossenzijl',''),('NL','OZU','Oud-Zuilen','Oud-Zuilen',''),('NL','PAN','Panningen','Panningen',''),('NL','PAP','Papendrecht','Papendrecht',''),('NL','PDJ','Poederoijen','Poederoijen',''),('NL','PDK','Poeldijk','Poeldijk',''),('NL','PER','Pernis','Pernis',''),('NL','PHL','Panheel','Panheel',''),('NL','PIJ','Pijnacker','Pijnacker',''),('NL','PLP','Sint Philipsland','Sint Philipsland',''),('NL','PNN','Pannerden','Pannerden',''),('NL','PRB','Prinsenbeek','Prinsenbeek',''),('NL','PTN','Putten','Putten',''),('NL','PTT','Petten','Petten',''),('NL','PUM','Purmerend','Purmerend',''),('NL','PUT','Putte','Putte',''),('NL','PVT','Poortvliet','Poortvliet',''),('NL','PZI','Pieterzijl','Pieterzijl',''),('NL','QCJ','Acht','Acht',''),('NL','QCT','Eersel','Eersel',''),('NL','QCU','Elst','Elst',''),('NL','QDG','Lisse','Lisse',''),('NL','QDJ','Made','Made',''),('NL','QDS','Raalte','Raalte',''),('NL','RAA','Raamsdonksveer','Raamsdonksveer',''),('NL','RAS','Ravenstein','Ravenstein',''),('NL','RAV','Roelofarendsveen','Roelofarendsveen',''),('NL','RBG','Rijnsburg','Rijnsburg',''),('NL','RBO','Robbenoord','Robbenoord',''),('NL','RCP','Rucphen','Rucphen',''),('NL','RED','Ried','Ried',''),('NL','REU','Reuver','Reuver',''),('NL','REW','Reimerswaal','Reimerswaal',''),('NL','RGT','Rinsumageest','Rinsumageest',''),('NL','RHD','Rheden','Rheden',''),('NL','RHE','Rhenen','Rhenen',''),('NL','RHO','Rhoon','Rhoon',''),('NL','RID','Ridderkerk','Ridderkerk',''),('NL','RIE','Riel','Riel',''),('NL','RIJ','Rijs','Rijs',''),('NL','RJE','Rijen','Rijen',''),('NL','RJS','Rijssen','Rijssen',''),('NL','RJV','Rijkevoort','Rijkevoort',''),('NL','RLA','Rilland','Rilland',''),('NL','RMA','Rosmalen','Rosmalen',''),('NL','RNK','Renkum','Renkum',''),('NL','ROD','Roden','Roden',''),('NL','ROG','Roggel','Roggel',''),('NL','ROO','Roosendaal','Roosendaal',''),('NL','ROR','Rodenrijs','Rodenrijs',''),('NL','ROZ','Rozenburg','Rozenburg',''),('NL','RPL','Ramspol','Ramspol',''),('NL','RRO','Ruurlo','Ruurlo',''),('NL','RSH','Rijsenhout','Rijsenhout',''),('NL','RSL','Reusel','Reusel',''),('NL','RST','Roosteren','Roosteren',''),('NL','RTG','Rustenburg','Rustenburg',''),('NL','RTH','Riethoven','Riethoven',''),('NL','RTM','Rotterdam','Rotterdam',''),('NL','RUK','Breukelen','Breukelen',''),('NL','RUM','Rumpt','Rumpt',''),('NL','RUT','Rutten','Rutten',''),('NL','RUW','Reeuwijk','Reeuwijk',''),('NL','RWD','Renswoude','Renswoude',''),('NL','RWI','Rijpwetering','Rijpwetering',''),('NL','RYB','Rijsbergen','Rijsbergen',''),('NL','RYS','Rijswijk','Rijswijk',''),('NL','RZD','Rozendaal','Rozendaal',''),('NL','SAN','Sint Annaparochie','Sint Annaparochie',''),('NL','SAP','Sappemeer','Sappemeer',''),('NL','SAR','St Andries','St Andries',''),('NL','SAS','Sassenheim','Sassenheim',''),('NL','SBG','Scharsterbrug','Scharsterbrug',''),('NL','SBS','Sijbrandahuis','Sijbrandahuis',''),('NL','SBU','Schagerbrug','Schagerbrug',''),('NL','SCA','Sprang','Sprang',''),('NL','SCB','Schoonebeek','Schoonebeek',''),('NL','SCE','Scheveningen','Scheveningen',''),('NL','SCH','Schagen','Schagen',''),('NL','SCI','Schiedam','Schiedam',''),('NL','SCN','Schinnen','Schinnen',''),('NL','SCP','Schipluiden','Schipluiden',''),('NL','SDB','Standdaarbuiten','Standdaarbuiten',''),('NL','SDM','Stadsdam','Stadsdam',''),('NL','SDN','Steenderen','Steenderen',''),('NL','SDW','Schildwolde','Schildwolde',''),('NL','SGL','\'s-Graveland','\'s-Graveland',''),('NL','SGM','\'s-Gravenmoer','\'s-Gravenmoer',''),('NL','SGP','\'s-Gravenpolder','\'s-Gravenpolder',''),('NL','SHB','\'s-Heerenbroek','\'s-Heerenbroek',''),('NL','SHE','\'s-Heerenhoek','\'s-Heerenhoek',''),('NL','SHH','Schoonhoven','Schoonhoven',''),('NL','SHO','Schermerhorn','Schermerhorn',''),('NL','SIM','Simpelveld','Simpelveld',''),('NL','SIT','Sittard','Sittard',''),('NL','SIV','Silvolde','Silvolde',''),('NL','SJB','Strijbeek','Strijbeek',''),('NL','SJK','Spijk','Spijk',''),('NL','SJO','Sintjohannesga','Sintjohannesga',''),('NL','SKG','Slijkenburg','Slijkenburg',''),('NL','SKL','Stieltjeskanaal','Stieltjeskanaal',''),('NL','SKM','Slikkendam','Slikkendam',''),('NL','SKW','Schalkwijk','Schalkwijk',''),('NL','SLD','Sliedrecht','Sliedrecht',''),('NL','SLG','Stokkelaarsbrug','Stokkelaarsbrug',''),('NL','SLI','Slikkerveer','Slikkerveer',''),('NL','SLO','Slochteren','Slochteren',''),('NL','SLS','Sluis','Sluis',''),('NL','SLT','Sloten','Sloten',''),('NL','SLU','Sluiskil','Sluiskil',''),('NL','SMB','Sambeek','Sambeek',''),('NL','SMD','Scheemda','Scheemda',''),('NL','SMI','Smilde','Smilde',''),('NL','SMK','Sint Maartensdijk','Sint Maartensdijk',''),('NL','SML','Smallingerland','Smallingerland',''),('NL','SMN','Sint Maarten','Sint Maarten',''),('NL','SMV','Sint Maartensvlotbrug','Sint Maartensvlotbrug',''),('NL','SMZ','Scheemderzwaag','Scheemderzwaag',''),('NL','SND','Schijndel','Schijndel',''),('NL','SNK','Sneek','Sneek',''),('NL','SNW','Snelrewaard','Snelrewaard',''),('NL','SOD','Sondel','Sondel',''),('NL','SOE','Soest','Soest',''),('NL','SOG','Schin op Geul','Schin op Geul',''),('NL','SOM','Someren','Someren',''),('NL','SON','Son','Son',''),('NL','SOP','Stolpen','Stolpen',''),('NL','SOR','Schoor','Schoor',''),('NL','SOS','Soesterberg','Soesterberg',''),('NL','SPA','Spaubeek','Spaubeek',''),('NL','SPB','Spanbroek','Spanbroek',''),('NL','SPD','Spaarndam','Spaarndam',''),('NL','SPG','Stampersgat','Stampersgat',''),('NL','SPI','Spijkenisse','Spijkenisse',''),('NL','SPK','Spakenburg','Spakenburg',''),('NL','SPL','Schiphol','Schiphol',''),('NL','SPR','Sprundel','Sprundel',''),('NL','SPV','Stolpervlotbrug','Stolpervlotbrug',''),('NL','SRK','Schiphol-Rijk','Schiphol-Rijk',''),('NL','SRP','Scherpenzeel','Scherpenzeel',''),('NL','STA','Stavoren','Stavoren',''),('NL','STD','Stellendam','Stellendam',''),('NL','STE','Steenbergen','Steenbergen',''),('NL','STH','Staphorst','Staphorst',''),('NL','STI','Stein','Stein',''),('NL','STK','Stadskanaal','Stadskanaal',''),('NL','STN','Stiens','Stiens',''),('NL','STO','\'t Stort','\'t Stort',''),('NL','STW','Steenwijk','Steenwijk',''),('NL','SUD','St Cloud','St Cloud',''),('NL','SUR','Surhuisterveen','Surhuisterveen',''),('NL','SVG','Sas van Gent','Sas van Gent',''),('NL','SVW','Stevensweert','Stevensweert',''),('NL','SWB','Sint Willebrord','Sint Willebrord',''),('NL','SWI','Swifterbant','Swifterbant',''),('NL','SWJ','Stolwijk','Stolwijk',''),('NL','SWK','Sleeuwijk','Sleeuwijk',''),('NL','SWL','Schouwerzijl','Schouwerzijl',''),('NL','SWM','Swalmen','Swalmen',''),('NL','SZL','Schoterzijl','Schoterzijl',''),('NL','TAK','Ter Apelkanaal','Ter Apelkanaal',''),('NL','TBB','Tubbergen','Tubbergen',''),('NL','TBO','Terborg','Terborg',''),('NL','TEA','Ter Aar','Ter Aar',''),('NL','TEG','Tegelen','Tegelen',''),('NL','TEX','Texel','Texel',''),('NL','THO','Tholen','Tholen',''),('NL','TIE','Tiel','Tiel',''),('NL','TKM','Tolkamer','Tolkamer',''),('NL','TKW','Tjerkwerd','Tjerkwerd',''),('NL','TLB','Tilburg','Tilburg',''),('NL','TLD','Toldijk','Toldijk',''),('NL','TNO','Tynaarlo','Tynaarlo',''),('NL','TNZ','Terneuzen','Terneuzen',''),('NL','TOK','Tollebeek','Tollebeek',''),('NL','TOR','Torontostraat','Torontostraat',''),('NL','TPH','Ter Apel','Ter Apel',''),('NL','TRJ','Strijen','Strijen',''),('NL','TRO','Terhorne','Terhorne',''),('NL','TUH','Tuitjenhorn','Tuitjenhorn',''),('NL','TUL','Tuil','Tuil',''),('NL','TWA','\'t Waar','\'t Waar',''),('NL','TWE','Twello','Twello',''),('NL','TZA','\'t Zand','\'t Zand',''),('NL','UDE','Uden','Uden',''),('NL','UDH','Udenhout','Udenhout',''),('NL','UFE','Uffelte','Uffelte',''),('NL','UIT','Uithoorn','Uithoorn',''),('NL','ULF','Ulft','Ulft',''),('NL','ULR','Ulrum','Ulrum',''),('NL','ULS','Ulestraten','Ulestraten',''),('NL','UMO','Urmond','Urmond',''),('NL','URK','Urk','Urk',''),('NL','URS','Ursem','Ursem',''),('NL','UTC','Utrecht','Utrecht',''),('NL','UTG','Uitgeest','Uitgeest',''),('NL','UTR','Uitermeer','Uitermeer',''),('NL','UTZ','Uithuizen','Uithuizen',''),('NL','VAA','Vaassen','Vaassen',''),('NL','VAL','Valkenswaard','Valkenswaard',''),('NL','VAN','Vianen','Vianen',''),('NL','VAR','Varsen','Varsen',''),('NL','VBK','Velserbroek','Velserbroek',''),('NL','VDH','Veldhoven','Veldhoven',''),('NL','VDM','Veendam','Veendam',''),('NL','VDN','Vredenduin','Vredenduin',''),('NL','VED','Velden','Velden',''),('NL','VEE','Veenendaal','Veenendaal',''),('NL','VEG','Veghel','Veghel',''),('NL','VEL','Velsen','Velsen',''),('NL','VEN','Venlo','Venlo',''),('NL','VEP','Velp','Velp',''),('NL','VFR','Vorden','Vorden',''),('NL','VGB','Voetangelbrug','Voetangelbrug',''),('NL','VGT','Vught','Vught',''),('NL','VHA','Veldriel','Veldriel',''),('NL','VHZ','Voorthuizen','Voorthuizen',''),('NL','VIE','Vierlingsbeek','Vierlingsbeek',''),('NL','VIJ','Vijfhuizen','Vijfhuizen',''),('NL','VIV','Vinkeveen','Vinkeveen',''),('NL','VKK','Vierakker','Vierakker',''),('NL','VKS','Valkenisse','Valkenisse',''),('NL','VLA','Vlaardingen','Vlaardingen',''),('NL','VLD','Vlodrop','Vlodrop',''),('NL','VLE','Volkel','Volkel',''),('NL','VLI','Vlissingen','Vlissingen',''),('NL','VLK','Valkenburg','Valkenburg',''),('NL','VLL','Vlieland','Vlieland',''),('NL','VLM','Vlijmen','Vlijmen',''),('NL','VLO','Venlo-Autoweg','Venlo-Autoweg',''),('NL','VLS','Vaals','Vaals',''),('NL','VLT','Vleuten','Vleuten',''),('NL','VLW','Vogelwaarde','Vogelwaarde',''),('NL','VNE','Van Essen','Van Essen',''),('NL','VNH','Venhuizen','Venhuizen',''),('NL','VNK','Veendijk','Veendijk',''),('NL','VNO','Veenoord','Veenoord',''),('NL','VNR','Venray','Venray',''),('NL','VOB','Voorburg','Voorburg',''),('NL','VOD','Volendam','Volendam',''),('NL','VOH','Voorhout','Voorhout',''),('NL','VOS','Voorschoten','Voorschoten',''),('NL','VRA','Vrouwenakker','Vrouwenakker',''),('NL','VRD','Vreeland','Vreeland',''),('NL','VRH','Vroomshoop','Vroomshoop',''),('NL','VRN','Vuren','Vuren',''),('NL','VRS','Voorst','Voorst',''),('NL','VRZ','Vriezenveen','Vriezenveen',''),('NL','VSI','Visvliet','Visvliet',''),('NL','VSM','Vessem','Vessem',''),('NL','VSN','Velsen-Noord','Velsen-Noord',''),('NL','VSR','Varsseveld','Varsseveld',''),('NL','WAA','Waalre','Waalre',''),('NL','WAB','Waardenburg','Waardenburg',''),('NL','WAD','Waddinxveen','Waddinxveen',''),('NL','WAJ','Wanroij','Wanroij',''),('NL','WAL','Waalhaven','Waalhaven',''),('NL','WAM','West-Knollendam','West-Knollendam',''),('NL','WAP','Wapenveld','Wapenveld',''),('NL','WAR','Warnsveld','Warnsveld',''),('NL','WAT','Wateringen','Wateringen',''),('NL','WBD','Wijk bij Duurstede','Wijk bij Duurstede',''),('NL','WBK','Westerbork','Westerbork',''),('NL','WBS','Westbeemster','Westbeemster',''),('NL','WCH','Wijchen','Wijchen',''),('NL','WCM','Woudrichem','Woudrichem',''),('NL','WDB','Woudenberg','Woudenberg',''),('NL','WDE','Waarde','Waarde',''),('NL','WDM','Weidum','Weidum',''),('NL','WDN','Waardenburg','Waardenburg',''),('NL','WDP','Westdorpe','Westdorpe',''),('NL','WDR','Waarder','Waarder',''),('NL','WDS','Wijdenes','Wijdenes',''),('NL','WEA','Wijk en Aalburg','Wijk en Aalburg',''),('NL','WED','Wemeldinge','Wemeldinge',''),('NL','WEH','Wervershoof','Wervershoof',''),('NL','WEL','Well','Well',''),('NL','WEM','Westmaas','Westmaas',''),('NL','WES','Westerhaar-Vriezenveensewijk','Westerhaar-Vriezenveensewijk',''),('NL','WEU','Weurt','Weurt',''),('NL','WEV','Westervoort','Westervoort',''),('NL','WFM','Warffum','Warffum',''),('NL','WGD','West-Graftdijk','West-Graftdijk',''),('NL','WGE','Westergeest','Westergeest',''),('NL','WGN','Wognum','Wognum',''),('NL','WGR','Wieringermeer','Wieringermeer',''),('NL','WGT','Wijgeest','Wijgeest',''),('NL','WGW','Wageningen','Wageningen',''),('NL','WHD','Wilhelminadorp','Wilhelminadorp',''),('NL','WHL','Wehl','Wehl',''),('NL','WHN','Westerhoven','Westerhoven',''),('NL','WHO','Wehe-den Hoorn','Wehe-den Hoorn',''),('NL','WHT','Wernhout','Wernhout',''),('NL','WHU','Warfhuizen','Warfhuizen',''),('NL','WID','Wierden','Wierden',''),('NL','WIE','Wier','Wier',''),('NL','WIJ','Wijhe','Wijhe',''),('NL','WIK','Wijk','Wijk',''),('NL','WIS','Willemstad','Willemstad',''),('NL','WIT','Wittelte','Wittelte',''),('NL','WIW','Wieringerwerf','Wieringerwerf',''),('NL','WJW','Wijnjewoude','Wijnjewoude',''),('NL','WKD','Werkendam','Werkendam',''),('NL','WKG','Wolsumerketting','Wolsumerketting',''),('NL','WKP','Westkapelle','Westkapelle',''),('NL','WKS','Weakens','Weakens',''),('NL','WKU','Workum','Workum',''),('NL','WLD','Wildervank','Wildervank',''),('NL','WLK','Waalwijk','Waalwijk',''),('NL','WLL','Wellerlooi','Wellerlooi',''),('NL','WLN','Wilnis','Wilnis',''),('NL','WMH','Warmenhuizen','Warmenhuizen',''),('NL','WMO','Wormer','Wormer',''),('NL','WMS','Wommels','Wommels',''),('NL','WNK','Winkel','Winkel',''),('NL','WNS','Winsum','Winsum',''),('NL','WOR','Woerden','Woerden',''),('NL','WOU','Wouw','Wouw',''),('NL','WPI','Waspik','Waspik',''),('NL','WRA','Warga','Warga',''),('NL','WRD','Warder','Warder',''),('NL','WRG','Wieringen','Wieringen',''),('NL','WRL','Waarland','Waarland',''),('NL','WRM','Warmond','Warmond',''),('NL','WRP','Welsrijp','Welsrijp',''),('NL','WRT','Weert','Weert',''),('NL','WRV','Wormerveer','Wormerveer',''),('NL','WSC','Winschoten','Winschoten',''),('NL','WSD','Woudsend','Woudsend',''),('NL','WSM','Wessem','Wessem',''),('NL','WSO','Walsoorden','Walsoorden',''),('NL','WSP','Weesp','Weesp',''),('NL','WSR','Waspik','Waspik',''),('NL','WSS','Wassenaar','Wassenaar',''),('NL','WTE','West-Terschelling','West-Terschelling',''),('NL','WTN','Warten','Warten',''),('NL','WTU','Westwoud','Westwoud',''),('NL','WTW','Winterswijk','Winterswijk',''),('NL','WTZ','Westzaan','Westzaan',''),('NL','WVG','Wolvega','Wolvega',''),('NL','WWO','Wijdewormer','Wijdewormer',''),('NL','WWR','Wijde Wormer','Wijde Wormer',''),('NL','WXM','Wamel','Wamel',''),('NL','YPG','Ypenburg','Ypenburg',''),('NL','YSK','Yerseke','Yerseke',''),('NL','ZAA','Zaandam','Zaandam',''),('NL','ZAD','Zaandijk','Zaandijk',''),('NL','ZAG','Zwaag','Zwaag',''),('NL','ZBJ','Zuid-Beijerland','Zuid-Beijerland',''),('NL','ZBK','Zevenbergschen Hoek','Zevenbergschen Hoek',''),('NL','ZBO','Zuidbroek','Zuidbroek',''),('NL','ZDL','Zuidlaren','Zuidlaren',''),('NL','ZDM','Zeddam','Zeddam',''),('NL','ZDV','Zandvoort','Zandvoort',''),('NL','ZEI','Zuideinde','Zuideinde',''),('NL','ZEM','Zelhem','Zelhem',''),('NL','ZET','Zetten','Zetten',''),('NL','ZEV','Zevenaar','Zevenaar',''),('NL','ZEW','Zeewolde','Zeewolde',''),('NL','ZGD','Zwaagdijk','Zwaagdijk',''),('NL','ZGE','Zwiggelte','Zwiggelte',''),('NL','ZHN','Zevenhuizen (Utrecht)','Zevenhuizen (Utrecht)',''),('NL','ZHO','Zwaanshoek','Zwaanshoek',''),('NL','ZHU','Zevenhuizen (Friesland)','Zevenhuizen (Friesland)',''),('NL','ZIE','Zierikzee','Zierikzee',''),('NL','ZIT','Zeist','Zeist',''),('NL','ZLB','Zaltbommel','Zaltbommel',''),('NL','ZLD','Zoutelande','Zoutelande',''),('NL','ZLK','Zalk','Zalk',''),('NL','ZMM','Zwammerdam','Zwammerdam',''),('NL','ZND','Zenderen','Zenderen',''),('NL','ZOE','Zoelen','Zoelen',''),('NL','ZOT','Zoutkamp','Zoutkamp',''),('NL','ZPO','Zandpol','Zandpol',''),('NL','ZPS','Zijpersluis','Zijpersluis',''),('NL','ZTM','Zoetermeer','Zoetermeer',''),('NL','ZUD','Zundert','Zundert',''),('NL','ZUL','Zuidland','Zuidland',''),('NL','ZUT','Zutphen','Zutphen',''),('NL','ZVB','Zevenbergen','Zevenbergen',''),('NL','ZWA','Zwanenburg','Zwanenburg',''),('NL','ZWB','Zwartenberg','Zwartenberg',''),('NL','ZWD','Zoeterwoude-Rijndijk','Zoeterwoude-Rijndijk',''),('NL','ZWE','Zwaagwesteinde','Zwaagwesteinde',''),('NL','ZWI','Zwijndrecht','Zwijndrecht',''),('NL','ZWL','Zuidwolde','Zuidwolde',''),('NL','ZWN','Zwinderen','Zwinderen',''),('NL','ZWO','Zwolle','Zwolle',''),('NL','ZWS','Zwartsluis','Zwartsluis',''),('NO','','','',''),('NO','AAF','Afjord','Afjord','16'),('NO','AAN','Ardal','Ardal','14'),('NO','AAS','As','As','02'),('NO','AAV','Alvik','Alvik','12'),('NO','ABN','Aarebakken','Aarebakken','08'),('NO','ADL','Alvdal','Alvdal','04'),('NO','ADN','Andenes','Andenes','18'),('NO','ADY','Andoy','Andoy','18'),('NO','AES','Alesund','Alesund','15'),('NO','AFT','Agnefest','Agnefest','10'),('NO','AGD','Agdenes','Agdenes','16'),('NO','AGO','Agotnes','Agotnes','12'),('NO','AHM','Aaheim','Aaheim','15'),('NO','AHS','Arhus','Arhus','12'),('NO','AKM','Aakrehamn','Aakrehamn','11'),('NO','ALF','Alta','Alta','20'),('NO','ALG','Algard','Algard','11'),('NO','ALN','Alnabru','Alnabru','03'),('NO','ALS','Alstahaug','Alstahaug','18'),('NO','AND','Andalsnes','Andalsnes','15'),('NO','ANN','Sannidal','Sannidal','08'),('NO','ANU','Andebu','Andebu','07'),('NO','ARD','Ardalstangen','Ardalstangen','14'),('NO','ARE','Arendal','Arendal','09'),('NO','ARN','Arnes','Arnes','02'),('NO','ASH','Austrheim','Austrheim','12'),('NO','ASK','Asker','Asker','02'),('NO','ASL','Askvoll','Askvoll','14'),('NO','ASM','Askim','Askim','01'),('NO','ASR','Ana-Sira','Ana-Sira','11'),('NO','ASV','Austevoll','Austevoll','12'),('NO','ASY','Askoy','Askoy','12'),('NO','AUE','Aure','Aure','15'),('NO','AUK','Aukra','Aukra','15'),('NO','AUL','Aurland','Aurland','14'),('NO','AUR','Aurskog','Aurskog','01'),('NO','AVA','Avaldsnes','Avaldsnes','11'),('NO','AVE','Averoy','Averoy','15'),('NO','BAF','Balsfjord','Balsfjord','19'),('NO','BAK','Barkaker','Barkaker','07'),('NO','BAM','Bamble','Bamble','08'),('NO','BAR','Barum','Barum','02'),('NO','BBG','Bosberg','Bosberg','16'),('NO','BDN','Blomsterdalen','Blomsterdalen','12'),('NO','BDU','Bardufoss','Bardufoss','19'),('NO','BEJ','Beiarn','Beiarn','18'),('NO','BER','Berg','Berg','19'),('NO','BGO','Bergen','Bergen','12'),('NO','BGS','Borgestad','Borgestad','08'),('NO','BHL','Balholm','Balholm',''),('NO','BIN','Bindal','Bindal','18'),('NO','BIS','Bismo','Bismo','05'),('NO','BJF','Batsfjord','Batsfjord','20'),('NO','BJK','Bjerke','Bjerke','03'),('NO','BJU','Bjugn','Bjugn','16'),('NO','BJX','Bjorkas','Bjorkas','02'),('NO','BJY','Bjarkoy','Bjarkoy','19'),('NO','BKD','Brakstad','Brakstad','12'),('NO','BKS','Brekstad','Brekstad','16'),('NO','BKV','Bjerkvik','Bjerkvik','18'),('NO','BLD','Birkeland','Birkeland','09'),('NO','BLL','Ballangen','Ballangen','18'),('NO','BLS','Balestrand','Balestrand','14'),('NO','BNN','Bronnoysund','Bronnoysund','18'),('NO','BOG','Bogen','Bogen','18'),('NO','BOK','Bokn','Bokn','11'),('NO','BOM','Bomlo','Bomlo','12'),('NO','BOO','Bodo','Bodo','18'),('NO','BOR','Borgenhaugen','Borgenhaugen','01'),('NO','BOS','Borkenes','Borkenes','19'),('NO','BOX','Bo','Bo',''),('NO','BRA','Bryggja','Bryggja','14'),('NO','BRE','Bremanger','Bremanger','14'),('NO','BRG','Borg','Borg',''),('NO','BRK','Berkak','Berkak','12'),('NO','BRO','Bronnoy','Bronnoy','18'),('NO','BRR','Borre','Borre','07'),('NO','BRU','Brumunddal','Brumunddal','04'),('NO','BRV','Brattvag','Brattvag','15'),('NO','BRY','Bryne','Bryne','11'),('NO','BSD','Ballstad','Ballstad','18'),('NO','BSU','Bangsund','Bangsund','17'),('NO','BUV','Buvika','Buvika','04'),('NO','BVG','Berlevag','Berlevag','20'),('NO','BVK','Brevik','Brevik','08'),('NO','BVL','Brandval','Brandval','04'),('NO','BYG','Bygland','Bygland','09'),('NO','DAL','Dal','Dal','02'),('NO','DGR','Digernes','Digernes','04'),('NO','DIM','Dimmelsvik','Dimmelsvik','12'),('NO','DIR','Dirdal','Dirdal',''),('NO','DIS','Disena','Disena','04'),('NO','DOK','Dokka','Dokka','05'),('NO','DOM','Dombas','Dombas','05'),('NO','DON','Donna','Donna','18'),('NO','DRE','Drevsjo','Drevsjo','04'),('NO','DRG','Drag','Drag','18'),('NO','DRK','Drobak','Drobak','02'),('NO','DRM','Drammen','Drammen','06'),('NO','DUS','Dusavik','Dusavik','11'),('NO','DYR','Dyrvik','Dyrvik','16'),('NO','DYY','Dyroy','Dyroy','19'),('NO','EBN','Elvebakken','Elvebakken','20'),('NO','EDE','Eide','Eide','15'),('NO','EDF','Eidfjord','Eidfjord','12'),('NO','EGD','Eigersund','Eigersund','11'),('NO','EGE','Egersund','Egersund','11'),('NO','EGG','Eggesbones','Eggesbones','15'),('NO','EGV','Engelsviken','Engelsviken','01'),('NO','EID','Eid','Eid','14'),('NO','EIL','Eidslandet','Eidslandet','12'),('NO','EIV','Eidsvag','Eidsvag','12'),('NO','EKF','Eikefet','Eikefet','12'),('NO','ELL','Ellingsoy','Ellingsoy','15'),('NO','ELN','Elnesvagen','Elnesvagen','15'),('NO','ELV','Elverum','Elverum','04'),('NO','ENA','Eina','Eina','05'),('NO','EPA','Espa','Espa','12'),('NO','ESP','Espevik','Espevik','11'),('NO','ETN','Etne','Etne','12'),('NO','EVE','Evenes','Evenes','18'),('NO','EVJ','Evje','Evje','09'),('NO','EYD','Eydehavn','Eydehavn','09'),('NO','FAN','Farsund','Farsund','10'),('NO','FAU','Fauske','Fauske','18'),('NO','FAX','Fagerstrand','Fagerstrand','08'),('NO','FDE','Forde','Forde','14'),('NO','FED','Fedje','Fedje','12'),('NO','FFD','Flekkefjord','Flekkefjord','10'),('NO','FGN','Fagernes','Fagernes','05'),('NO','FIS','Fiska','Fiska',''),('NO','FIT','Fitjar','Fitjar','12'),('NO','FJA','Fjaler','Fjaler','14'),('NO','FJE','Fjell','Fjell','12'),('NO','FJL','Fjelldal','Fjelldal','18'),('NO','FKS','Flakstad','Flakstad','18'),('NO','FLA','Flam','Flam','14'),('NO','FLS','Flisa','Flisa','04'),('NO','FLT','Flatanger','Flatanger','17'),('NO','FND','Finneid','Finneid','18'),('NO','FNE','Finnsnes','Finnsnes','19'),('NO','FNT','Fiskeneset','Fiskeneset',''),('NO','FNY','Finnoy','Finnoy','11'),('NO','FOL','Foldafoss','Foldafoss','17'),('NO','FOR','Forsand','Forsand','11'),('NO','FOS','Fosnavag','Fosnavag','15'),('NO','FRA','Froya','Froya','16'),('NO','FRE','Fraena','Fraena','15'),('NO','FRJ','Frei','Frei','15'),('NO','FRK','Fredrikstad','Fredrikstad','01'),('NO','FRN','Frogn','Frogn','02'),('NO','FRO','Floro','Floro','14'),('NO','FRS','Forus','Forus','11'),('NO','FRT','Frosta','Frosta','17'),('NO','FSD','Fjellstrand','Fjellstrand',''),('NO','FSN','Fosnes','Fosnes','17'),('NO','FSR','Fosser','Fosser','02'),('NO','FSU','Fetsund','Fetsund','19'),('NO','FTL','Fortun-Luster','Fortun-Luster','14'),('NO','FTU','Fetsund','Fetsund','02'),('NO','FUS','Fusa','Fusa','12'),('NO','GAM','Gamvik','Gamvik','20'),('NO','GAU','Gaular','Gaular','14'),('NO','GBD','Gibostad','Gibostad','19'),('NO','GDM','Gjerdrum','Gjerdrum','02'),('NO','GEI','Geilo','Geilo','06'),('NO','GEN','Gardermoen','Gardermoen','02'),('NO','GFR','Gamle Fredrikstad','Gamle Fredrikstad',''),('NO','GIL','Gildeskal','Gildeskal','18'),('NO','GIS','Giske','Giske','15'),('NO','GJM','Gjemnes','Gjemnes','15'),('NO','GJS','Gjesdal','Gjesdal','11'),('NO','GLL','Gol','Gol','06'),('NO','GLO','Glomfjord','Glomfjord','18'),('NO','GLP','Gloppen','Gloppen','14'),('NO','GNE','Garnes','Garnes','12'),('NO','GNR','Geiranger','Geiranger','15'),('NO','GPE','Gaupen','Gaupen','04'),('NO','GPN','Gaupne','Gaupne','14'),('NO','GRD','Gravdal','Gravdal',''),('NO','GRE','Greaker','Greaker','01'),('NO','GRO','Grong','Grong','17'),('NO','GRT','Gratangen','Gratangen','19'),('NO','GRV','Granvin','Granvin','12'),('NO','GRY','Gryllefjord','Gryllefjord',''),('NO','GSD','Gjerstad','Gjerstad','09'),('NO','GTD','Grimstad','Grimstad','09'),('NO','GTH','Geithus','Geithus','06'),('NO','GUD','Gudvangen','Gudvangen','14'),('NO','GUL','Gulen','Gulen','14'),('NO','GUS','Gullsmedvika/Mo i Rana','Gullsmedvika/Mo i Rana','18'),('NO','GVK','Gjovik','Gjovik','05'),('NO','HAA','Ha','Ha','11'),('NO','HAD','Hadsel','Hadsel','18'),('NO','HAG','Hagan','Hagan','16'),('NO','HAL','Halden','Halden','01'),('NO','HAN','Halvorshavn','Halvorshavn','06'),('NO','HAR','Haram','Haram','15'),('NO','HAS','Haslum','Haslum','02'),('NO','HAU','Haugesund','Haugesund','11'),('NO','HAV','Havoysund','Havoysund','20'),('NO','HDL','Heimdal','Heimdal','08'),('NO','HDV','Ervik','Ervik','12'),('NO','HEL','Hellvik','Hellvik','11'),('NO','HEN','Henningsvar','Henningsvar','18'),('NO','HER','Hermansverk','Hermansverk','14'),('NO','HES','Hestvika','Hestvika','16'),('NO','HFL','Hammerfall','Hammerfall',''),('NO','HFS','Honefoss','Honefoss','06'),('NO','HFT','Hammerfest','Hammerfest','20'),('NO','HGL','Heggedal','Heggedal','02'),('NO','HGN','Hagan','Hagan','14'),('NO','HGV','Haugsvik','Haugsvik','12'),('NO','HHF','Hafrsfjord','Hafrsfjord','11'),('NO','HIL','Hillevag/Stavanger','Hillevag/Stavanger','11'),('NO','HIT','Hitra','Hitra','16'),('NO','HJE','Hjerkinn','Hjerkinn','05'),('NO','HJL','Hjelmland','Hjelmland','11'),('NO','HJO','Hjorungavag','Hjorungavag','15'),('NO','HLA','Holla','Holla','08'),('NO','HLL','Hollen','Hollen','10'),('NO','HLM','Holmedal','Holmedal','14'),('NO','HLN','Holen','Holen','02'),('NO','HLS','Halsa','Halsa','15'),('NO','HLT','Hoylandet','Hoylandet','17'),('NO','HLV','Halsvik','Halsvik','14'),('NO','HLY','Hafslundsoy','Hafslundsoy','01'),('NO','HME','Hemne','Hemne','16'),('NO','HMN','Haslemoen','Haslemoen','04'),('NO','HMR','Hamar','Hamar','04'),('NO','HMS','Hemnes','Hemnes','18'),('NO','HMY','Hamaroy','Hamaroy','18'),('NO','HND','Hornindal','Hornindal','14'),('NO','HNE','Hemnesberget','Hemnesberget','18'),('NO','HNN','Hovdenakken','Hovdenakken',''),('NO','HNS','Hanestad','Hanestad','04'),('NO','HOD','Hokksund','Hokksund',''),('NO','HOK','Hommelvik','Hommelvik','16'),('NO','HOL','Holmestrand','Holmestrand','07'),('NO','HOR','Horten','Horten','07'),('NO','HOS','Hov','Hov','05'),('NO','HOV','Orsta-Volda','Orsta-Volda','15'),('NO','HOY','Husoy','Husoy','07'),('NO','HRD','Harstad','Harstad','19'),('NO','HRE','Herre-Bamble','Herre-Bamble','08'),('NO','HRI','Hareid','Hareid','15'),('NO','HRY','Heroya','Heroya','08'),('NO','HSD','Hemsedal','Hemsedal','06'),('NO','HSY','Hellesylt','Hellesylt','15'),('NO','HUN','Hunndalen','Hunndalen','05'),('NO','HUR','Hurum','Hurum','06'),('NO','HUS','Husnes','Husnes','12'),('NO','HVA','Hvaler','Hvaler','01'),('NO','HVG','Honningsvag','Honningsvag','20'),('NO','HVI','Havik','Havik',''),('NO','HVK','Hasvik','Hasvik','20'),('NO','HVL','Hvalstad','Hvalstad','02'),('NO','HVN','Haakonsvern','Haakonsvern',''),('NO','HYL','Hyllestado','Hyllestado','14'),('NO','HYN','Hyne','Hyne','07'),('NO','HYR','Hoyanger','Hoyanger','14'),('NO','IBE','Ibestad','Ibestad','19'),('NO','IFN','Isfjorden','Isfjorden',''),('NO','IKR','Ikornnes','Ikornnes','15'),('NO','IND','Inderoy','Inderoy','17'),('NO','INV','Innvik','Innvik','14'),('NO','ISD','Isdalsto','Isdalsto','12'),('NO','JAR','Jarlsberg Apt/Tonsberg','Jarlsberg Apt/Tonsberg','07'),('NO','JEL','Jelsa','Jelsa','11'),('NO','JLD','Jorpeland','Jorpeland','12'),('NO','JON','Jondal','Jondal','12'),('NO','JSH','Jessheim','Jessheim','02'),('NO','JSS','Jossinghamn','Jossinghamn','11'),('NO','JVK','Jevnaker','Jevnaker','05'),('NO','KAF','Kafjord','Kafjord','20'),('NO','KAL','Kvalneset','Kvalneset','14'),('NO','KAR','Karsto','Karsto','11'),('NO','KAS','Karmsund','Karmsund','11'),('NO','KAY','Karlsoy','Karlsoy','19'),('NO','KBT','Kolbotn','Kolbotn','02'),('NO','KDT','Kalandseidet','Kalandseidet','12'),('NO','KGM','Kongsmoen','Kongsmoen','17'),('NO','KIN','Kinn','Kinn','18'),('NO','KIV','Kinsarvik','Kinsarvik','12'),('NO','KJF','Kjollefjord','Kjollefjord','20'),('NO','KJK','Kjopsvik','Kjopsvik','18'),('NO','KKN','Kirkenes','Kirkenes','20'),('NO','KKR','Kirkenar','Kirkenar',''),('NO','KLE','Kleppesto','Kleppesto','12'),('NO','KLO','Klofta','Klofta','02'),('NO','KLP','Klepp','Klepp','11'),('NO','KLR','Kjeller','Kjeller','20'),('NO','KMO','Kambo','Kambo','01'),('NO','KMS','Kjopmannskjar','Kjopmannskjar','07'),('NO','KMY','Karmoy','Karmoy','11'),('NO','KON','Kollsnes','Kollsnes','12'),('NO','KOP','Kopervik','Kopervik','11'),('NO','KPG','Kaupanger','Kaupanger','14'),('NO','KPP','Koppang','Koppang','04'),('NO','KRA','Kragero','Kragero','08'),('NO','KRS','Kristiansand','Kristiansand','10'),('NO','KRV','Knarrevik','Knarrevik','12'),('NO','KRY','Kraakeroy','Kraakeroy','01'),('NO','KSA','Krokstadelva','Krokstadelva','06'),('NO','KSB','Kongsberg','Kongsberg','06'),('NO','KSD','Kilsund','Kilsund','09'),('NO','KSJ','Karasjok','Karasjok','20'),('NO','KSU','Kristiansund','Kristiansund','15'),('NO','KSV','Kongsvinger','Kongsvinger','04'),('NO','KSY','Kvitsoy','Kvitsoy','11'),('NO','KTK','Kautokeino','Kautokeino','20'),('NO','KVA','Kalvaag','Kalvaag','14'),('NO','KVB','Kvaleberg','Kvaleberg','11'),('NO','KVD','Kvinesdal','Kvinesdal','10'),('NO','KVF','Kvafjord','Kvafjord','19'),('NO','KVH','Kvinnherad','Kvinnherad','12'),('NO','KVM','Kvam','Kvam','12'),('NO','KVN','Kvanangen','Kvanangen','19'),('NO','KVS','Kvalsund','Kvalsund','20'),('NO','KYR','Kyrksaterora','Kyrksaterora','16'),('NO','LAD','Langesund','Langesund','08'),('NO','LAN','Langevag','Langevag','15'),('NO','LAR','Larvik','Larvik','07'),('NO','LAV','Lavangen','Lavangen','19'),('NO','LDS','Lindesnes','Lindesnes','10'),('NO','LEB','Lebesby','Lebesby','20'),('NO','LEF','Leirfjord','Leirfjord','18'),('NO','LEI','Leira','Leira','05'),('NO','LEK','Leikanger','Leikanger','14'),('NO','LEN','Lensvik','Lensvik','16'),('NO','LEP','Leirpollen','Leirpollen','20'),('NO','LER','Lervik','Lervik','01'),('NO','LEV','Levanger','Levanger','17'),('NO','LHS','Langhus','Langhus','02'),('NO','LIE','Lier','Lier','06'),('NO','LIL','Lillesand','Lillesand','09'),('NO','LIN','Lindas','Lindas','12'),('NO','LIS','Lierstranda','Lierstranda','06'),('NO','LKA','Leka','Leka','17'),('NO','LKE','Loken','Loken','19'),('NO','LKL','Lakselv','Lakselv','20'),('NO','LKN','Leknes','Leknes',''),('NO','LKV','Leksvik','Leksvik','17'),('NO','LLH','Lillehammer','Lillehammer','05'),('NO','LND','Lyngdal','Lyngdal','10'),('NO','LNG','Lyngor','Lyngor','09'),('NO','LNS','Lyngstad','Lyngstad','15'),('NO','LOD','Lodingen','Lodingen','18'),('NO','LOE','Loen','Loen','14'),('NO','LOM','Lom','Lom','05'),('NO','LOP','Loppa','Loppa','20'),('NO','LRD','Lardal','Lardal','14'),('NO','LRI','Leirvik','Leirvik','12'),('NO','LRK','Larkollen','Larkollen','01'),('NO','LSG','Lorenskog','Lorenskog','02'),('NO','LST','Lillestrom','Lillestrom','02'),('NO','LUR','Luroy','Luroy','18'),('NO','LUS','Luster','Luster','14'),('NO','LUT','Lutnes','Lutnes','04'),('NO','LVG','Laksevag','Laksevag','12'),('NO','LYN','Lyngen','Lyngen','19'),('NO','LYR','Longyearbyen','Longyearbyen',''),('NO','LYS','Lysaker','Lysaker','02'),('NO','MAG','Magnor','Magnor','04'),('NO','MAK','Malvik','Malvik','16'),('NO','MAN','Mandal','Mandal','10'),('NO','MAR','Marikoven','Marikoven','12'),('NO','MAV','Malselv','Malselv','19'),('NO','MAY','Maloy','Maloy','14'),('NO','MEH','Mehamn','Mehamn','20'),('NO','MEL','Melbu','Melbu','18'),('NO','MEN','Menstad','Menstad','08'),('NO','MEV','Melsomvik','Melsomvik','07'),('NO','MEY','Meloy','Meloy','18'),('NO','MID','Midsund','Midsund','15'),('NO','MIN','Minde','Minde',''),('NO','MJF','Mosjoen','Mosjoen','18'),('NO','MJO','Mjondalen','Mjondalen','06'),('NO','MLD','Meland','Meland','12'),('NO','MLH','Mindleheim','Mindleheim',''),('NO','MLK','Melkoya','Melkoya','20'),('NO','MLM','Malm','Malm','17'),('NO','MLS','Melhus','Melhus','16'),('NO','MLT','Moldtustranda','Moldtustranda','15'),('NO','MOD','Modalen','Modalen','12'),('NO','MOI','Moi','Moi','10'),('NO','MOL','Molde','Molde','15'),('NO','MON','Mongstad','Mongstad','12'),('NO','MQN','Mo i Rana','Mo i Rana','18'),('NO','MRV','Muruvik','Muruvik','16'),('NO','MSF','Masfjorden','Masfjorden','12'),('NO','MSK','Moskenes','Moskenes','18'),('NO','MSS','Moss','Moss','01'),('NO','MSV','Mosvik','Mosvik','17'),('NO','MSY','Masoy','Masoy','20'),('NO','MYO','Myre-Oksnes','Myre-Oksnes','18'),('NO','MYS','Mysen','Mysen','01'),('NO','NAE','Narbo','Narbo','11'),('NO','NAN','Nanset','Nanset','07'),('NO','NAU','Naustdal','Naustdal','14'),('NO','NDE','Namdalseid','Namdalseid','17'),('NO','NEO','Nesodden','Nesodden','02'),('NO','NES','Nesflaten-Suldal','Nesflaten-Suldal','11'),('NO','NFD','Nordfjordeid','Nordfjordeid','14'),('NO','NHS','Norheimsund','Norheimsund','12'),('NO','NIT','Nittedal','Nittedal','02'),('NO','NKB','Nordkjosbotn','Nordkjosbotn','19'),('NO','NLD','Nodeland','Nodeland',''),('NO','NOD','Norddal','Norddal','15'),('NO','NOK','Nordkapp','Nordkapp','20'),('NO','NOR','Nordreisa','Nordreisa','19'),('NO','NRS','Noresund','Noresund','06'),('NO','NRY','Naroy','Naroy','17'),('NO','NSB','Nesseby','Nesseby','20'),('NO','NSD','Nybergsund','Nybergsund','04'),('NO','NSN','Nesna','Nesna',''),('NO','NSS','Narsnes','Narsnes','06'),('NO','NST','Nesset','Nesset','15'),('NO','NTB','Notodden','Notodden','08'),('NO','NTN','Nesttun','Nesttun',''),('NO','NTY','Notteroy','Notteroy','07'),('NO','NVK','Narvik','Narvik','18'),('NO','NYG','Nygard','Nygard','05'),('NO','OAS','Osteras','Osteras','02'),('NO','OBG','Oseberg','Oseberg','07'),('NO','ODD','Odda','Odda','12'),('NO','OEY','Oye','Oye','05'),('NO','OKF','Oksfjord','Oksfjord','20'),('NO','OKS','Oksnes','Oksnes','18'),('NO','OLA','Orland','Orland','16'),('NO','OLD','Olden','Olden','14'),('NO','OLN','Olen','Olen','12'),('NO','OOS','Os','Os','04'),('NO','OPA','Opakermoen','Opakermoen','02'),('NO','OPG','Oppegard','Oppegard','02'),('NO','OPP','Oppdal','Oppdal','16'),('NO','ORD','Orkdal','Orkdal','16'),('NO','ORJ','Orje','Orje','01'),('NO','ORK','Orkanger','Orkanger','16'),('NO','ORS','Orsta','Orsta','15'),('NO','ORV','Ortnevik','Ortnevik','14'),('NO','OSA','Osa','Osa','12'),('NO','OSG','Orskog','Orskog','15'),('NO','OSL','Oslo','Oslo','03'),('NO','OSN','Osen','Osen','16'),('NO','OST','Osteroy','Osteroy','12'),('NO','OSY','Namsos','Namsos','17'),('NO','OSZ','Os','Os','12'),('NO','OTT','Otta','Otta','05'),('NO','OYE','Oye','Oye','10'),('NO','OYG','Oygarden','Oygarden','12'),('NO','PAR','Porsanger','Porsanger','20'),('NO','PFS','Prestfoss','Prestfoss','06'),('NO','POR','Porsgrunn','Porsgrunn','08'),('NO','RAA','Rakkestad','Rakkestad','01'),('NO','RAD','Rade','Rade','01'),('NO','RAF','Rafnes','Rafnes','08'),('NO','RAM','Ramsund','Ramsund','18'),('NO','RAO','Roa','Roa','05'),('NO','RAU','Rauma','Rauma','15'),('NO','RAY','Radoy','Radoy','12'),('NO','RBG','Rodberg','Rodberg','06'),('NO','RBV','Raubergvika','Raubergvika','15'),('NO','RDB','Randaberg','Randaberg','11'),('NO','RDY','Rodoy','Rodoy','18'),('NO','REK','Rekefjord','Rekefjord','11'),('NO','REN','Rennesoy','Rennesoy','11'),('NO','RET','Rost','Rost','18'),('NO','RFS','Raufoss','Raufoss','05'),('NO','RHT','Raholt','Raholt','02'),('NO','RIA','Rislokka','Rislokka','03'),('NO','RIN','Ringebu','Ringebu','05'),('NO','RIS','Risor','Risor','09'),('NO','RKN','Rjukan','Rjukan','08'),('NO','RLL','Rollag','Rollag','06'),('NO','RLN','Raelingen','Raelingen','14'),('NO','RMJ','Ramfjordnes','Ramfjordnes','19'),('NO','RNA','Rana','Rana','18'),('NO','RNS','Risnes','Risnes','12'),('NO','ROA','Roan','Roan','16'),('NO','ROE','Royken','Royken','06'),('NO','ROG','Rognan','Rognan','18'),('NO','RON','Ronningen','Ronningen','08'),('NO','RRS','Roros','Roros','16'),('NO','RSD','Rausand','Rausand','15'),('NO','RSG','Romskog','Romskog','01'),('NO','RSN','Raudsandnes','Raudsandnes',''),('NO','RSS','Rissa','Rissa','16'),('NO','RVK','Rorvik','Rorvik','17'),('NO','RVY','Rolvsoy','Rolvsoy','01'),('NO','RYG','Rygge','Rygge','01'),('NO','SAA','Skaland','Skaland','19'),('NO','SAB','Staubo','Staubo','09'),('NO','SAD','Sandefjord','Sandefjord','07'),('NO','SAL','Salangen','Salangen','19'),('NO','SAM','Samnanger','Samnanger','12'),('NO','SAN','Skaun','Skaun','16'),('NO','SAS','Sandnes','Sandnes','11'),('NO','SAT','Salten','Salten','18'),('NO','SAU','Sauda','Sauda','11'),('NO','SAY','Sandsoy','Sandsoy','15'),('NO','SBE','Solbergelva','Solbergelva','06'),('NO','SBK','Stabekk','Stabekk','02'),('NO','SBU','Salsbruket','Salsbruket','17'),('NO','SDI','Sandvika','Sandvika','02'),('NO','SDL','Saltdal','Saltdal','18'),('NO','SDN','Sandane','Sandane','14'),('NO','SDX','Sande','Sande','07'),('NO','SDZ','Stordal','Stordal','15'),('NO','SEI','Skanevik','Skanevik','12'),('NO','SEK','Sellebakk','Sellebakk','01'),('NO','SEL','Seljord','Seljord','08'),('NO','SEM','Sem','Sem','08'),('NO','SET','Sem-Tonsberg','Sem-Tonsberg','07'),('NO','SGE','Slagen','Slagen','07'),('NO','SGJ','Straumsgjerde','Straumsgjerde','15'),('NO','SGN','Sagene','Sagene','03'),('NO','SGU','Sagstua','Sagstua','04'),('NO','SIG','Siggerud','Siggerud','04'),('NO','SIK','Ski','Ski','02'),('NO','SIR','Siri','Siri',''),('NO','SJA','Senja','Senja','19'),('NO','SJE','Selje','Selje','14'),('NO','SJH','Senjehopen','Senjehopen','19'),('NO','SJO','Sjoholt','Sjoholt','15'),('NO','SJT','Skjetten','Skjetten','02'),('NO','SJU','Sjursoja/Oslo','Sjursoja/Oslo','03'),('NO','SKA','Skarer','Skarer','02'),('NO','SKB','Skibotn','Skibotn','19'),('NO','SKD','Skedsmokorset','Skedsmokorset','03'),('NO','SKE','Skien','Skien','08'),('NO','SKJ','Skjetten','Skjetten','03'),('NO','SKL','Skanland','Skanland','19'),('NO','SKM','Skalle','Skalle','15'),('NO','SKN','Stokmarknes','Stokmarknes','18'),('NO','SKO','Skodje','Skodje','15'),('NO','SKR','Skarnes','Skarnes','04'),('NO','SKS','Skatval-Stjordal','Skatval-Stjordal','17'),('NO','SKU','Skudeneshavn','Skudeneshavn','11'),('NO','SKV','Skalevik','Skalevik','12'),('NO','SKX','Skogn','Skogn','17'),('NO','SKY','Skjervoy','Skjervoy','19'),('NO','SLA','Sola','Sola','11'),('NO','SLD','Solund','Solund','14'),('NO','SLE','Slependen','Slependen','02'),('NO','SLG','Slagentangen','Slagentangen','07'),('NO','SLM','Slemmestad','Slemmestad','06'),('NO','SLN','Skjolden','Skjolden','14'),('NO','SLX','Sortland','Sortland','18'),('NO','SMM','Strommen','Strommen','02'),('NO','SMN','Somna','Somna','18'),('NO','SMO','Smola','Smola','15'),('NO','SMR','Sofiemyr','Sofiemyr','02'),('NO','SNA','Sokna','Sokna','06'),('NO','SND','Sund','Sund','12'),('NO','SNE','Sogne','Sogne','10'),('NO','SNI','Snillfjord','Snillfjord','16'),('NO','SOA','Soroya','Soroya','20'),('NO','SOE','Sorumsand','Sorumsand','01'),('NO','SOF','Sorfold','Sorfold','18'),('NO','SOG','Sogndal','Sogndal','14'),('NO','SOK','Sokndal','Sokndal','11'),('NO','SOM','Sommaroy','Sommaroy','19'),('NO','SON','Son','Son',''),('NO','SOV','Sovik','Sovik','15'),('NO','SPD','Spongdal','Spongdal','16'),('NO','SPG','Sarpsborg','Sarpsborg','01'),('NO','SPM','Spillam','Spillam','17'),('NO','SPV','Spjelkavik','Spjelkavik','15'),('NO','SPY','Spydeberg','Spydeberg','01'),('NO','SRA','Sorreisa','Sorreisa','19'),('NO','SRM','Straumsnes','Straumsnes','18'),('NO','SRN','Stranda','Stranda','15'),('NO','SRP','Stord','Stord','12'),('NO','SRV','Sirevaag','Sirevaag','11'),('NO','SRX','Sotra','Sotra','12'),('NO','SSD','Steinsund','Steinsund','14'),('NO','SSJ','Sandnessjoen','Sandnessjoen','18'),('NO','SSN','Storsteinnes','Storsteinnes','19'),('NO','SST','Skjerstad','Skjerstad','18'),('NO','STA','Stathelle','Stathelle','08'),('NO','STB','Storabo','Storabo','12'),('NO','STD','Strand','Strand','11'),('NO','STE','Steinkjar','Steinkjar','17'),('NO','STF','Storfjord','Storfjord','19'),('NO','STG','Steigen','Steigen','18'),('NO','STH','Steinshamn','Steinshamn','15'),('NO','STJ','Stjordal','Stjordal','17'),('NO','STK','Stokke','Stokke','07'),('NO','STL','Steilene','Steilene','02'),('NO','STM','Straumen','Straumen',''),('NO','STN','Stange','Stange','04'),('NO','STO','Stokkvaagan','Stokkvaagan','18'),('NO','STR','Stryn','Stryn','14'),('NO','STS','Storskog','Storskog','20'),('NO','STT','Statfjord Terminal','Statfjord Terminal',''),('NO','STU','Stura','Stura','12'),('NO','STV','Stavern','Stavern','07'),('NO','STY','Stjernoya','Stjernoya','20'),('NO','SUA','Sula','Sula','15'),('NO','SUL','Suldal','Suldal','11'),('NO','SUN','Sunndalsora','Sunndalsora','15'),('NO','SUR','Surnadal','Surnadal','15'),('NO','SUZ','Stamsund','Stamsund','18'),('NO','SVA','Sor-Varanger','Sor-Varanger','20'),('NO','SVD','Svinesund','Svinesund','01'),('NO','SVE','Svelgen','Svelgen','14'),('NO','SVF','Sande i Vestfold','Sande i Vestfold',''),('NO','SVG','Stavanger','Stavanger','11'),('NO','SVJ','Svolvar','Svolvar','18'),('NO','SVO','Sveio','Sveio','12'),('NO','SVV','Svelvik','Svelvik','07'),('NO','SYA','Skytta','Skytta','03'),('NO','SYK','Sykkylven','Sykkylven','15'),('NO','TAA','Tana','Tana','20'),('NO','TAE','Tananger','Tananger','11'),('NO','TAF','Tafjord','Tafjord','15'),('NO','TAU','Tau','Tau','11'),('NO','TBL','Tobol','Tobol',''),('NO','TBO','Tjeldbergodden','Tjeldbergodden','16'),('NO','TGA','Tolga','Tolga','04'),('NO','THA','Thamshamn','Thamshamn','16'),('NO','TIL','Tiller','Tiller','16'),('NO','TIN','Tingvoll','Tingvoll','15'),('NO','TJO','Tjome','Tjome','07'),('NO','TJR','Tjorvag','Tjorvag','15'),('NO','TJS','Tjeldsund','Tjeldsund','18'),('NO','TLG','Tjodalyng','Tjodalyng','07'),('NO','TNB','Tranby','Tranby','06'),('NO','TNS','Trones','Trones',''),('NO','TOF','Tofte i Hurum','Tofte i Hurum','06'),('NO','TOM','Tomrefjord','Tomrefjord',''),('NO','TON','Tonsberg','Tonsberg','07'),('NO','TOR','Torsken','Torsken','19'),('NO','TOS','Tromso','Tromso','19'),('NO','TOV','Tovik','Tovik','19'),('NO','TRA','Trana','Trana','18'),('NO','TRD','Trondheim','Trondheim','16'),('NO','TRE','Tretten','Tretten','05'),('NO','TRL','Trysil','Trysil','04'),('NO','TRP','Torp','Torp','01'),('NO','TRY','Tranoy','Tranoy','19'),('NO','TSD','Torvastad','Torvastad','11'),('NO','TSX','Tyssedal','Tyssedal','12'),('NO','TUN','Tunborg','Tunborg',''),('NO','TUS','Tustna','Tustna','15'),('NO','TVE','Tvedestrand','Tvedestrand','09'),('NO','TVT','Tveit','Tveit','10'),('NO','TYF','Tysfjord','Tysfjord','18'),('NO','TYN','Tysnes','Tysnes','12'),('NO','TYV','Tysvar','Tysvar','11'),('NO','UGD','Uggdal','Uggdal','12'),('NO','ULL','Ullensvang','Ullensvang','12'),('NO','ULS','Ulsteinvik','Ulsteinvik','15'),('NO','ULT','Ulset','Ulset','12'),('NO','ULV','Ulven','Ulven','02'),('NO','USD','Uskedal','Uskedal','12'),('NO','UTS','Utsira','Utsira','11'),('NO','UVG','Ulsvag','Ulsvag','18'),('NO','UVK','Ulvik','Ulvik','12'),('NO','UVR','Utvar','Utvar','14'),('NO','VAA','Vale','Vale','07'),('NO','VAB','Varangerbotn','Varangerbotn','20'),('NO','VAG','Valevag','Valevag','12'),('NO','VAK','Vaksdal','Vaksdal','12'),('NO','VAL','Valloy','Valloy','07'),('NO','VAN','Vanvikan-Leksvik','Vanvikan-Leksvik','17'),('NO','VAO','Vardo','Vardo','20'),('NO','VAY','Vanylven','Vanylven','15'),('NO','VDA','Volda','Volda','15'),('NO','VDS','Vadso','Vadso','20'),('NO','VEF','Vefsn','Vefsn','18'),('NO','VEG','Vega','Vega','18'),('NO','VER','Verdal','Verdal','17'),('NO','VEV','Vevelstad','Vevelstad','18'),('NO','VEY','Varoy','Varoy','18'),('NO','VGG','Veggli','Veggli','06'),('NO','VGN','Vagan','Vagan','18'),('NO','VGR','Vestre Gran','Vestre Gran','05'),('NO','VGY','Vagsoy','Vagsoy','14'),('NO','VHM','Vadheim','Vadheim','14'),('NO','VHN','Vikholmen','Vikholmen',''),('NO','VIF','Vindafjord','Vindafjord','11'),('NO','VIN','Vinstra','Vinstra','05'),('NO','VIS','Vik i Sogn','Vik i Sogn','14'),('NO','VKN','Vikna','Vikna','17'),('NO','VLL','Voll','Voll','11'),('NO','VLR','Valer','Valer','01'),('NO','VNA','Vennesla','Vennesla','10'),('NO','VOL','Voldafjorden','Voldafjorden','15'),('NO','VOS','Voss','Voss','12'),('NO','VRE','Vrengen','Vrengen','07'),('NO','VRR','Verran','Verran','17'),('NO','VSD','Vormsund','Vormsund','02'),('NO','VSE','Vanse','Vanse','10'),('NO','VST','Vestnes','Vestnes','15'),('NO','VSY','Vestby','Vestby','02'),('NO','VTR','Vettre','Vettre','02'),('NO','VVY','Vestvagoy','Vestvagoy','18'),('NP','','','',''),('NP','ANP','Annapurna','Annapurna',''),('NP','BDP','Bhadrapur','Bhadrapur',''),('NP','BGL','Baglung','Baglung',''),('NP','BHP','Bhojpur','Bhojpur',''),('NP','BHR','Bharatpur','Bharatpur',''),('NP','BIR','Biratnagar','Biratnagar',''),('NP','BIT','Baitadi','Baitadi',''),('NP','BJH','Bajhang','Bajhang',''),('NP','BJU','Bajura','Bajura',''),('NP','BRG','Birgunj','Birgunj',''),('NP','BWA','Bhairawa','Bhairawa',''),('NP','DAP','Darchula','Darchula',''),('NP','DHG','Dhaulagiri','Dhaulagiri',''),('NP','DHI','Dhangarhi','Dhangarhi',''),('NP','DNP','Dang','Dang',''),('NP','DOP','Dolpa','Dolpa',''),('NP','FEB','Sanfebagar','Sanfebagar',''),('NP','GKH','Gorkha','Gorkha',''),('NP','HRJ','Chaurjhari','Chaurjhari',''),('NP','IMK','Simikot','Simikot',''),('NP','JIR','Jiri','Jiri',''),('NP','JKR','Janakpur','Janakpur',''),('NP','JMO','Jomsom','Jomsom',''),('NP','JUM','Jumla','Jumla',''),('NP','KAI','Kailali','Kailali',''),('NP','KAK','Kakarbitta','Kakarbitta',''),('NP','KEP','Nepalganj','Nepalganj',''),('NP','KGJ','Kanchenjunga','Kanchenjunga',''),('NP','KTM','Kathmandu','Kathmandu',''),('NP','LDN','Lamidanda','Lamidanda',''),('NP','LTG','Langtang','Langtang',''),('NP','LUA','Lukla','Lukla',''),('NP','MEY','Meghauli','Meghauli',''),('NP','MWP','Mountain','Mountain',''),('NP','NGX','Manang','Manang',''),('NP','PKR','Pokhara','Pokhara',''),('NP','PPL','Phaplu','Phaplu',''),('NP','RHP','Ramechhap','Ramechhap',''),('NP','RJB','Rajbiraj','Rajbiraj',''),('NP','RPA','Rolpa','Rolpa',''),('NP','RUK','Rukumkot','Rukumkot',''),('NP','RUM','Rumjatar','Rumjatar',''),('NP','SIF','Simara','Simara',''),('NP','SIH','Silgarhi-Doti','Silgarhi-Doti',''),('NP','SKH','Surkhet','Surkhet',''),('NP','SUN','Sunauli','Sunauli',''),('NP','SYH','Syangboche','Syangboche',''),('NP','TMI','Tumlingtar','Tumlingtar',''),('NP','TPJ','Taplejung','Taplejung',''),('NP','TPU','Tikapur','Tikapur',''),('NR','','','',''),('NR','INU','Nauru Island','Nauru Island',''),('NU','','','',''),('NU','ALO','Alofi','Alofi',''),('NU','IUE','Niue Island','Niue Island',''),('NZ','','','',''),('NZ','ABY','Albany','Albany','AUK'),('NZ','AKA','Akaroa','Akaroa','CAN'),('NZ','AKL','Auckland','Auckland','AUK'),('NZ','ALR','Alexandra','Alexandra','OTA'),('NZ','AMZ','Ardmore','Ardmore','AUK'),('NZ','ASG','Ashburton','Ashburton','CAN'),('NZ','BAL','Balclutha','Balclutha','OTA'),('NZ','BEL','Belfast','Belfast','CAN'),('NZ','BHE','Blenheim','Blenheim','MBH'),('NZ','BLU','Bluff','Bluff','STL'),('NZ','BUL','Bulls','Bulls','MWT'),('NZ','CGE','Cambridge','Cambridge','WKO'),('NZ','CHC','Christchurch','Christchurch','CAN'),('NZ','CHE','Cheviot','Cheviot','CAN'),('NZ','CHT','Chatham Island','Chatham Island','CAN'),('NZ','CLY','Clyde','Clyde','OTA'),('NZ','CMV','Coromandel','Coromandel','WKO'),('NZ','CRO','Cromwell','Cromwell','OTA'),('NZ','CTN','Carterton','Carterton','WGN'),('NZ','DAN','Dannevirke','Dannevirke','NTL'),('NZ','DEV','Devonport','Devonport','AUK'),('NZ','DGO','Doubtful Sound','Doubtful Sound','STL'),('NZ','DGR','Dargaville','Dargaville','NTL'),('NZ','DPC','Deep Cove','Deep Cove','STL'),('NZ','DUD','Dunedin','Dunedin','OTA'),('NZ','DUS','Dusky Sound','Dusky Sound',''),('NZ','EDC','Edgecumbe','Edgecumbe','BOP'),('NZ','ELM','Eltham','Eltham','TKI'),('NZ','ERH','Edendale','Edendale','STL'),('NZ','FGL','Fox Glacier','Fox Glacier','WTC'),('NZ','FKT','Frankton','Frankton','OTA'),('NZ','FLD','Feilding','Feilding','MWT'),('NZ','FOR','Fortrose','Fortrose','STL'),('NZ','FOX','Foxton','Foxton','MWT'),('NZ','GBS','Port Fitzroy','Port Fitzroy','AUK'),('NZ','GBZ','Great Barrier Is','Great Barrier Is','AUK'),('NZ','GIS','Gisborne','Gisborne','GIS'),('NZ','GMN','Greymouth','Greymouth','WTC'),('NZ','GOB','Golden Bay','Golden Bay','TAS'),('NZ','GOR','Gore','Gore','STL'),('NZ','GTO','Greerton','Greerton','BOP'),('NZ','HAS','Hastings','Hastings','HKB'),('NZ','HAW','Hawera','Hawera','MWT'),('NZ','HKK','Hokitika','Hokitika','WTC'),('NZ','HLY','Huntly','Huntly','WKO'),('NZ','HLZ','Hamilton','Hamilton','WKO'),('NZ','HOU','Horotiu','Horotiu','WKO'),('NZ','IVC','Invercargill','Invercargill','STL'),('NZ','KAK','Kakariki','Kakariki','MWT'),('NZ','KAP','Kaiapoi','Kaiapoi','CAN'),('NZ','KAT','Kaitaia','Kaitaia','NTL'),('NZ','KAW','Kawerau','Kawerau','BOP'),('NZ','KBZ','Kaikoura','Kaikoura','CAN'),('NZ','KKE','Kerikeri','Kerikeri','AUK'),('NZ','KKO','Kaikohe','Kaikohe','NTL'),('NZ','KOK','Kokiri','Kokiri','WTC'),('NZ','KTF','Takaka','Takaka','TAS'),('NZ','KTG','Kaitangata','Kaitangata','OTA'),('NZ','KTK','Katikati','Katikati','BOP'),('NZ','KUI','Kawau Island','Kawau Island','AUK'),('NZ','KWU','Mansion House','Mansion House',''),('NZ','LEV','Levin','Levin','MWT'),('NZ','LRV','Lorneville','Lorneville','STL'),('NZ','LYJ','Lower Hutt','Lower Hutt','WGN'),('NZ','LYT','Lyttelton','Lyttelton','CAN'),('NZ','MAP','Marsden Point','Marsden Point','NTL'),('NZ','MFN','Milford Sound','Milford Sound',''),('NZ','MKW','Makarewa','Makarewa','STL'),('NZ','MMU','Mount Maunganui','Mount Maunganui','BOP'),('NZ','MNK','Manakau','Manakau','TAS'),('NZ','MNR','Middleton/Christchurch','Middleton/Christchurch','CAN'),('NZ','MOE','Moerewa','Moerewa','AUK'),('NZ','MON','Mount Cook','Mount Cook','CAN'),('NZ','MOR','Morrinsville','Morrinsville','WKO'),('NZ','MRB','Martinborough','Martinborough','WGN'),('NZ','MRO','Masterton','Masterton',''),('NZ','MRT','Marton','Marton','MWT'),('NZ','MTA','Matamata','Matamata','WKO'),('NZ','MTG','Matangi','Matangi','WKO'),('NZ','MTR','Mataura','Mataura','STL'),('NZ','MWL','Mount Wellington','Mount Wellington','AUK'),('NZ','MZP','Motueka','Motueka','TAS'),('NZ','NPE','Napier','Napier','HKB'),('NZ','NPL','New Plymouth','New Plymouth','TKI'),('NZ','NSN','Nelson','Nelson','NSN'),('NZ','OAM','Oamaru','Oamaru','OTA'),('NZ','OHA','Ohakea','Ohakea','MWT'),('NZ','OHK','Ohakune','Ohakune','MWT'),('NZ','OKA','Okarito','Okarito',''),('NZ','ONE','Onehunga (Manukau Harbour)','Onehunga (Manukau Harbour)','AUK'),('NZ','OPX','Opua','Opua','NTL'),('NZ','ORH','Otorohanga','Otorohanga','WKO'),('NZ','ORI','Orini','Orini','WKO'),('NZ','ORR','Otago Harbour','Otago Harbour','OTA'),('NZ','OTA','Otaki','Otaki','MWT'),('NZ','PAE','Paeroa','Paeroa','WKO'),('NZ','PAI','Paihia','Paihia','NTL'),('NZ','PAR','Pareora','Pareora','CAN'),('NZ','PCN','Picton','Picton','MBH'),('NZ','PEO','Penrose','Penrose','AUK'),('NZ','PKK','Pukekohe','Pukekohe','AUK'),('NZ','PKL','Pakatoa Island','Pakatoa Island','AUK'),('NZ','PKR','Pukeuri Junction','Pukeuri Junction','STL'),('NZ','PMR','Palmerston North','Palmerston North','MWT'),('NZ','PMS','Palmerston','Palmerston','OTA'),('NZ','POE','Port Chalmers','Port Chalmers','OTA'),('NZ','POK','Pokeno','Pokeno','AUK'),('NZ','PPQ','Paraparaumu','Paraparaumu','WGN'),('NZ','PRR','Porirua','Porirua','TAS'),('NZ','PTR','Putaruru','Putaruru','WKO'),('NZ','RAG','Raglan','Raglan','WKO'),('NZ','RAU','Rangiuru','Rangiuru','BOP'),('NZ','RAV','Ravensbourne','Ravensbourne','OTA'),('NZ','RGO','Rangiora','Rangiora','CAN'),('NZ','RMD','Richmond','Richmond','NSN'),('NZ','RNW','Renwick','Renwick','MBH'),('NZ','ROT','Rotorua','Rotorua','BOP'),('NZ','RUS','Russel','Russel',''),('NZ','RXB','Roxburgh','Roxburgh','OTA'),('NZ','SBN','Sockburn','Sockburn',''),('NZ','SMF','Smithfield','Smithfield',''),('NZ','STR','Stratford','Stratford',''),('NZ','SZS','Stewart Island','Stewart Island','STL'),('NZ','TAR','Te Aroha','Te Aroha','BOP'),('NZ','TAU','Taumarunui','Taumarunui','TKI'),('NZ','TAW','Te Awamutu','Te Awamutu','WKO'),('NZ','TEK','Te Kauwhata','Te Kauwhata','WKO'),('NZ','TEU','Te Anau','Te Anau','STL'),('NZ','THH','Taharoa','Taharoa','WKO'),('NZ','THP','Taihape','Taihape','MWT'),('NZ','TIU','Timaru','Timaru','CAN'),('NZ','TKA','Temuka','Temuka','CAN'),('NZ','TKH','Tarakohe','Tarakohe','TAS'),('NZ','TKI','Te Kuiti','Te Kuiti','WKO'),('NZ','TKU','Takapau','Takapau','HKB'),('NZ','TKZ','Tokoroa','Tokoroa','WKO'),('NZ','TMZ','Thames','Thames','WKO'),('NZ','TOA','Tomoana','Tomoana','HKB'),('NZ','TPK','Te Puke','Te Puke','BOP'),('NZ','TPN','Te Puna','Te Puna','BOP'),('NZ','TRG','Tauranga','Tauranga','BOP'),('NZ','TUO','Taupo','Taupo','WKO'),('NZ','TWI','Tiwai Point/Bluff Port','Tiwai Point/Bluff Port',''),('NZ','UBA','Upper Hutt','Upper Hutt','WGN'),('NZ','WAA','Waitoa','Waitoa','WKO'),('NZ','WAG','Wanganui','Wanganui','MWT'),('NZ','WAI','Waitotara','Waitotara','MWT'),('NZ','WAO','Waiouru','Waiouru','MWT'),('NZ','WAR','Wairau Valley','Wairau Valley','MBH'),('NZ','WAT','Waharoa','Waharoa','WKO'),('NZ','WAV','Waverley Harbour','Waverley Harbour','TKI'),('NZ','WDY','Washdyke','Washdyke','CAN'),('NZ','WHA','Whakatu','Whakatu','HKB'),('NZ','WHE','Whekenui','Whekenui','MBH'),('NZ','WHI','Waihi','Waihi','BOP'),('NZ','WHK','Whakatane','Whakatane','BOP'),('NZ','WHN','Whangaparapara','Whangaparapara','AUK'),('NZ','WHO','Franz Josef','Franz Josef','WTC'),('NZ','WII','Wiri','Wiri','AUK'),('NZ','WIK','Surfdale','Surfdale','AUK'),('NZ','WIR','Wairoa','Wairoa','HKB'),('NZ','WJL','Waipukurau','Waipukurau','HKB'),('NZ','WKA','Wanaka','Wanaka','OTA'),('NZ','WKI','Waikari','Waikari','CAN'),('NZ','WKW','Waikawa','Waikawa','STL'),('NZ','WLF','Wellsford','Wellsford','NTL'),('NZ','WLG','Wellington','Wellington','WGN'),('NZ','WNP','Whenuapai','Whenuapai','AUK'),('NZ','WNT','Winton','Winton','STL'),('NZ','WRE','Whangarei','Whangarei','NTL'),('NZ','WSZ','Westport','Westport','WTC'),('NZ','WTA','Waitara','Waitara','TKI'),('NZ','WTG','Waitangi','Waitangi','NTL'),('NZ','WTI','Waitaki','Waitaki','CAN'),('NZ','WTZ','Whitianga','Whitianga','WKO'),('NZ','WUK','Waiuku','Waiuku','AUK'),('NZ','WWA','Warkworth','Warkworth','AUK'),('NZ','WYH','Wyndham','Wyndham','STL'),('NZ','YGC','Spring Creek','Spring Creek','MBH'),('NZ','ZQN','Queenstown','Queenstown','OTA'),('OM','','','',''),('OM','BYB','Dibaa','Dibaa',''),('OM','FAH','Fahal','Fahal',''),('OM','KHS','Khasab','Khasab',''),('OM','MCT','Muscat','Muscat',''),('OM','MFH','Mina\' al Fahl','Mina\' al Fahl',''),('OM','MNQ','Mina\' Qabus','Mina\' Qabus',''),('OM','MSH','Masirah','Masirah',''),('OM','MUT','Muthra','Muthra',''),('OM','OMM','Marmul','Marmul',''),('OM','OPQ','Port Qaboos','Port Qaboos',''),('OM','QAL','Qalhat','Qalhat',''),('OM','RAY','Raysut','Raysut',''),('OM','RMB','Buraimi','Buraimi',''),('OM','RWI','Ruwi','Ruwi',''),('OM','SEE','Seeb','Seeb',''),('OM','SLL','Salalah','Salalah',''),('OM','SOH','Sohar','Sohar',''),('OM','STQ','Mina Sultan Qaboos, Muscat','Mina Sultan Qaboos, Muscat',''),('OM','SUH','Sur','Sur',''),('OM','SUL','Port Sultan','Port Sultan',''),('OM','TTH','Thumrait','Thumrait',''),('PA','','','',''),('PA','ABA','Agua Buena','Agua Buena',''),('PA','ACO','Ancon','Ancon',''),('PA','ACU','Achutupo','Achutupo',''),('PA','AGD','Aguadulce','Aguadulce',''),('PA','AIL','Ailigandi','Ailigandi',''),('PA','ALA','Alanje','Alanje',''),('PA','AML','Puerto Armuelles','Puerto Armuelles',''),('PA','ATA','Atalaya','Atalaya',''),('PA','BAG','Bagala','Bagala',''),('PA','BAY','Bayano','Bayano',''),('PA','BEL','Bella Vista','Bella Vista',''),('PA','BFQ','Bahia Pina','Bahia Pina',''),('PA','BLB','Balboa','Balboa',''),('PA','BOC','Bocas del Toro','Bocas del Toro',''),('PA','BOQ','Boqueron','Boqueron',''),('PA','BQT','Boquete','Boquete',''),('PA','CAM','Caimito','Caimito',''),('PA','CAP','Capira','Capira',''),('PA','CAR','La Carrasquilla','La Carrasquilla',''),('PA','CDE','Caledonia','Caledonia',''),('PA','CFZ','Colon Free Zone','Colon Free Zone',''),('PA','CHA','Charco Azul','Charco Azul',''),('PA','CHB','Chilibre','Chilibre',''),('PA','CHE','Chepo','Chepo',''),('PA','CHG','Chiriqui Grande','Chiriqui Grande',''),('PA','CHQ','Chiriqui','Chiriqui',''),('PA','CHX','Changuinola','Changuinola',''),('PA','CLB','Calobre','Calobre',''),('PA','CRR','La Chorrera','La Chorrera',''),('PA','CRT','Ciruelito','Ciruelito',''),('PA','CSO','Coco Solo','Coco Solo',''),('PA','CTB','Cristobal','Cristobal',''),('PA','CTD','Chitre','Chitre',''),('PA','CTE','Carti Tupile','Carti Tupile',''),('PA','CZJ','Corazon de Jesus','Corazon de Jesus',''),('PA','CZO','Corozal','Corozal',''),('PA','CZZ','Canazas','Canazas',''),('PA','DAV','David','David',''),('PA','DIV','Divala','Divala',''),('PA','DOR','El Dorado','El Dorado',''),('PA','EGL','El Guayabal','El Guayabal',''),('PA','EJO','El Ejido','El Ejido',''),('PA','ELE','El Real','El Real',''),('PA','ELH','El Higo','El Higo',''),('PA','FLZ','Flores','Flores',''),('PA','FSM','Finca Santa Monica','Finca Santa Monica',''),('PA','GBA','Gamboa','Gamboa',''),('PA','GDE','Rio Grande','Rio Grande',''),('PA','GHE','Garachine','Garachine',''),('PA','GTN','Gatun','Gatun',''),('PA','HOW','Fort Kobbe','Fort Kobbe',''),('PA','JQE','Jaque','Jaque',''),('PA','LAS','Las Lomas','Las Lomas',''),('PA','LIO','Puerto Limon','Puerto Limon',''),('PA','LRN','La Arena','La Arena',''),('PA','LTB','Las Tablas','Las Tablas',''),('PA','MAZ','Puerto Mariato','Puerto Mariato',''),('PA','MFS','Miraflores','Miraflores',''),('PA','MIT','Manzanillo','Manzanillo',''),('PA','MNP','Las Minas','Las Minas',''),('PA','MPI','Mamitupo','Mamitupo',''),('PA','MPP','Mulatupo','Mulatupo',''),('PA','NGN','Nargana','Nargana',''),('PA','NMG','San Miguel','San Miguel',''),('PA','NZO','San Lorenzo','San Lorenzo',''),('PA','OCU','Ocu','Ocu',''),('PA','ONX','Colon','Colon',''),('PA','OTD','Contadora','Contadora',''),('PA','PAI','Paraiso','Paraiso',''),('PA','PAM','Almirante','Almirante',''),('PA','PAY','Payardi','Payardi',''),('PA','PBE','Portobelo','Portobelo',''),('PA','PBM','Bahia Las Minas','Bahia Las Minas',''),('PA','PCA','Puerto Caimito','Puerto Caimito',''),('PA','PCO','Pacora','Pacora',''),('PA','PDS','Pedasi','Pedasi',''),('PA','PED','Pedregal','Pedregal',''),('PA','PGR','Rio Grande','Rio Grande',''),('PA','PLP','La Palma','La Palma',''),('PA','POE','Pedro Miguel','Pedro Miguel',''),('PA','PRS','Potrerillos','Potrerillos',''),('PA','PTY','Panama, Ciudad de','Panama, Ciudad de',''),('PA','PUE','Puerto Obaldia','Puerto Obaldia',''),('PA','PVE','El Porvenir','El Porvenir',''),('PA','PYC','Playon Chico','Playon Chico',''),('PA','PYV','Yavisa','Yavisa',''),('PA','RHA','Rio Hato','Rio Hato',''),('PA','RIO','Rio Viejo de los Valdes','Rio Viejo de los Valdes',''),('PA','RIT','Rio Tigre','Rio Tigre',''),('PA','RIZ','Rio Azucar','Rio Azucar',''),('PA','RSI','Rio Sidra','Rio Sidra',''),('PA','SAX','Sambu','Sambu',''),('PA','SCL','Santa Clara','Santa Clara',''),('PA','SFW','Santa Fe','Santa Fe',''),('PA','SYP','Santiago','Santiago',''),('PA','TBG','Taboguilla','Taboguilla',''),('PA','TJC','Ticantiqui','Ticantiqui',''),('PA','TNS','Tonosi','Tonosi',''),('PA','TON','Tonosi','Tonosi',''),('PA','TOR','Torti','Torti',''),('PA','TUE','Tupile','Tupile',''),('PA','TUW','Tubuala','Tubuala',''),('PA','UTU','Ustupo','Ustupo',''),('PA','VAC','Vacamonte','Vacamonte',''),('PA','VCZ','Veracruz','Veracruz',''),('PA','ZAN','Zanguenga','Zanguenga',''),('PE','','','',''),('PE','ALD','Alerta','Alerta',''),('PE','ANC','Ancon','Ancon',''),('PE','ANS','Andahuaylas','Andahuaylas',''),('PE','APE','San Juan Aposento','San Juan Aposento',''),('PE','AQP','Arequipa','Arequipa',''),('PE','ARI','Arica','Arica',''),('PE','ATA','Anta','Anta',''),('PE','ATI','Atico','Atico',''),('PE','AYP','Ayacucho','Ayacucho',''),('PE','BLP','Bellavista','Bellavista',''),('PE','CAB','Cabo Blanco','Cabo Blanco',''),('PE','CAS','Casma','Casma',''),('PE','CHH','Chachapoyas','Chachapoyas',''),('PE','CHI','Chincha','Chincha',''),('PE','CHM','Chimbote','Chimbote',''),('PE','CHN','Chancan','Chancan',''),('PE','CHY','Chancay','Chancay',''),('PE','CIX','Chiclayo','Chiclayo',''),('PE','CJA','Cajamarca','Cajamarca',''),('PE','CLL','Callao','Callao',''),('PE','CON','Conchan','Conchan',''),('PE','CRZ','Cerro Azul','Cerro Azul',''),('PE','CUZ','Cuzco','Cuzco',''),('PE','EEN','Eten','Eten',''),('PE','GSM','General San Martin','General San Martin',''),('PE','HCO','Huacho','Huacho',''),('PE','HUA','Huaral','Huaral',''),('PE','HUU','Huanuco','Huanuco',''),('PE','HUY','Huarmey','Huarmey',''),('PE','HUZ','Huaraz','Huaraz',''),('PE','IBP','Iberia','Iberia',''),('PE','ICA','Ica','Ica',''),('PE','ILQ','Ilo','Ilo',''),('PE','IQT','Iquitos','Iquitos',''),('PE','JAE','Jaen','Jaen',''),('PE','JAU','Jauja','Jauja',''),('PE','JJI','Juanjui','Juanjui',''),('PE','JUL','Juliaca','Juliaca',''),('PE','LIM','Lima','Lima',''),('PE','LOA','La Oroya','La Oroya',''),('PE','LOB','Lobitos','Lobitos',''),('PE','LOO','Los Organos','Los Organos',''),('PE','LPN','La Planchada','La Planchada',''),('PE','LPP','La Pampilla','La Pampilla',''),('PE','MAL','Mala','Mala',''),('PE','MBP','Moyobamba','Moyobamba',''),('PE','MCA','Mancora','Mancora',''),('PE','MFT','Machu Picchu','Machu Picchu',''),('PE','MLQ','Mollendo','Mollendo',''),('PE','MRI','Matarani','Matarani',''),('PE','NGS','Negritos','Negritos',''),('PE','OQU','Oquendo','Oquendo',''),('PE','PAC','Pacasmayo','Pacasmayo',''),('PE','PAI','Paita','Paita',''),('PE','PAM','Paramonga','Paramonga',''),('PE','PCH','Puerto Chicama','Puerto Chicama',''),('PE','PCL','Pucallpa','Pucallpa',''),('PE','PEM','Puerto Maldonado','Puerto Maldonado',''),('PE','PIO','Pisco','Pisco',''),('PE','PIU','Piura','Piura',''),('PE','PLO','Punta Lobitos','Punta Lobitos',''),('PE','PMT','Pimentel','Pimentel',''),('PE','PUB','Bayovar','Bayovar',''),('PE','PUN','Puno','Puno',''),('PE','QUI','Quinches','Quinches',''),('PE','RIJ','Rioja','Rioja',''),('PE','RIM','Rodriguez de Mendoza','Rodriguez de Mendoza',''),('PE','SAM','Samanco','Samanco',''),('PE','SJA','San Juan','San Juan',''),('PE','SMG','Santa Maria','Santa Maria',''),('PE','SNX','San Nicolas','San Nicolas',''),('PE','SQU','Saposoa','Saposoa',''),('PE','SUL','Sullana','Sullana',''),('PE','SUP','Supe','Supe',''),('PE','SVY','Salaverry','Salaverry',''),('PE','SYC','Shiringayoc','Shiringayoc',''),('PE','TAG','Tambo Grande','Tambo Grande',''),('PE','TBP','Tumbes','Tumbes',''),('PE','TCQ','Tacna','Tacna',''),('PE','TDM','Tambo de Mora','Tambo de Mora',''),('PE','TGI','Tingo Maria','Tingo Maria',''),('PE','TPP','Tarapoto','Tarapoto',''),('PE','TRU','Trujillo','Trujillo',''),('PE','TYL','Talara','Talara',''),('PE','UMI','Quince Mil','Quince Mil',''),('PE','YMS','Yurimaguas','Yurimaguas',''),('PE','ZOR','Zorritos','Zorritos',''),('PF','','','',''),('PF','AAA','Anaa','Anaa',''),('PF','AHE','Ahe','Ahe',''),('PF','AHU','Ahurei','Ahurei',''),('PF','APK','Apataki','Apataki',''),('PF','AUQ','Atuona','Atuona',''),('PF','AXR','Arutua','Arutua',''),('PF','BOB','Bora-Bora','Bora-Bora',''),('PF','FAA','Faaa, Tahiti','Faaa, Tahiti',''),('PF','FAC','Faaite','Faaite',''),('PF','FAV','Fakarava','Fakarava',''),('PF','FGU','Fangatau','Fangatau',''),('PF','FHZ','Fakahina','Fakahina',''),('PF','GMR','Iles Gambier','Iles Gambier',''),('PF','HHZ','Hikueru','Hikueru',''),('PF','HIX','Hiva Oa','Hiva Oa',''),('PF','HOI','Hao Is','Hao Is',''),('PF','HUH','Huahine','Huahine',''),('PF','KKR','Kaukura','Kaukura',''),('PF','MAU','Maupiti','Maupiti',''),('PF','MEE','Maroe','Maroe',''),('PF','MKP','Makemo','Makemo',''),('PF','MOZ','Moorea','Moorea',''),('PF','MVT','Mataiva','Mataiva',''),('PF','NAU','Napuka Island','Napuka Island',''),('PF','NHV','Nuku Hiva','Nuku Hiva',''),('PF','NUK','Nukutavake','Nukutavake',''),('PF','PKP','Atoll Pukapuka','Atoll Pukapuka',''),('PF','PPT','Papeete','Papeete',''),('PF','PUK','Pukarua','Pukarua',''),('PF','REA','Reao','Reao',''),('PF','RFP','Raiatea','Raiatea',''),('PF','RGI','Rangiroa','Rangiroa',''),('PF','RUR','Rurutu','Rurutu',''),('PF','TAI','Taiohae','Taiohae',''),('PF','TIH','Tikehau','Tikehau',''),('PF','TJN','Takume','Takume',''),('PF','TKP','Takapoto','Takapoto',''),('PF','TKV','Tatakoto','Tatakoto',''),('PF','TKX','Takaroa','Takaroa',''),('PF','TTI','Tetiaroa Is','Tetiaroa Is',''),('PF','TUB','Tubuai','Tubuai',''),('PF','UAH','Ua Huka','Ua Huka',''),('PF','UAP','Ua Pou','Ua Pou',''),('PF','UTU','Uturoa','Uturoa',''),('PF','VAI','Vaitape','Vaitape',''),('PF','VHZ','Vahitahi','Vahitahi',''),('PF','XMH','Manihi','Manihi',''),('PF','ZTA','Tureia','Tureia',''),('PG','','','',''),('PG','ABP','Atkamba','Atkamba',''),('PG','ABW','Abau','Abau',''),('PG','AEK','Aseki','Aseki',''),('PG','AFR','Afore','Afore',''),('PG','AGG','Angoram','Angoram',''),('PG','AGK','Kagua','Kagua',''),('PG','AGL','Wanigela','Wanigela',''),('PG','AHO','Ahioma','Ahioma',''),('PG','AIE','Aiome','Aiome',''),('PG','AKG','Anguganak','Anguganak',''),('PG','AKI','Akinum','Akinum',''),('PG','AMF','Ama','Ama',''),('PG','AMG','Amboin','Amboin',''),('PG','AMU','Amanab','Amanab',''),('PG','ANB','Anewa Bay','Anewa Bay',''),('PG','AOA','Aroa','Aroa',''),('PG','AOB','Annanberg','Annanberg',''),('PG','AON','Arona','Arona',''),('PG','APP','Asapa','Asapa',''),('PG','APR','April River','April River',''),('PG','ARP','Aragip','Aragip',''),('PG','ASZ','Asirim','Asirim',''),('PG','ATN','Namatanai','Namatanai',''),('PG','ATP','Aitape','Aitape',''),('PG','AUI','Aua Island','Aua Island',''),('PG','AUJ','Ambunti','Ambunti',''),('PG','AUP','Agaun','Agaun',''),('PG','AUV','Aumo','Aumo',''),('PG','AWB','Awaba','Awaba',''),('PG','AWR','Awar','Awar',''),('PG','AYU','Aiyura','Aiyura',''),('PG','AZB','Amazon Bay','Amazon Bay',''),('PG','BAA','Bialla','Bialla',''),('PG','BAJ','Bali','Bali',''),('PG','BAP','Baibara','Baibara',''),('PG','BCP','Bambu','Bambu',''),('PG','BDZ','Baindoung','Baindoung',''),('PG','BEA','Bereina','Bereina',''),('PG','BIJ','Biliau','Biliau',''),('PG','BIZ','Bimin','Bimin',''),('PG','BMH','Bomai','Bomai',''),('PG','BMZ','Bamu','Bamu',''),('PG','BNA','Buna','Buna',''),('PG','BNM','Bodinumu','Bodinumu',''),('PG','BNT','Bundi','Bundi',''),('PG','BNV','Boana','Boana',''),('PG','BNZ','Banz','Banz',''),('PG','BOQ','Boku','Boku',''),('PG','BOR','Boroko','Boroko',''),('PG','BOT','Boset','Boset',''),('PG','BOV','Boang','Boang',''),('PG','BPB','Boridi','Boridi',''),('PG','BPD','Bapi','Bapi',''),('PG','BRH','Brahman','Brahman',''),('PG','BRP','Biaru','Biaru',''),('PG','BSP','Bensbach','Bensbach',''),('PG','BUA','Buka','Buka',''),('PG','BUL','Bulolo','Bulolo',''),('PG','BVP','Bolovip','Bolovip',''),('PG','BWJ','Bawan','Bawan',''),('PG','BWP','Bewani','Bewani',''),('PG','BXZ','Bunsil','Bunsil',''),('PG','CGC','Cape Gloucester','Cape Gloucester',''),('PG','CMU','Kundiawa','Kundiawa',''),('PG','CPI','Cape Orford','Cape Orford',''),('PG','CPN','Cape Rodney','Cape Rodney',''),('PG','CVB','Chungribu','Chungribu',''),('PG','CVL','Cape Vogel','Cape Vogel',''),('PG','DAF','Daup','Daup',''),('PG','DAU','Daru','Daru',''),('PG','DBP','Debepare','Debepare',''),('PG','DDM','Dodoima','Dodoima',''),('PG','DER','Derim','Derim',''),('PG','DGG','Daugo','Daugo',''),('PG','DLB','Dalbertis','Dalbertis',''),('PG','DNU','Dinangat','Dinangat',''),('PG','DOI','Doini','Doini',''),('PG','DOO','Dorobisoro','Dorobisoro',''),('PG','DOS','Dios','Dios',''),('PG','DPU','Dumpu','Dumpu',''),('PG','EFG','Efogi','Efogi',''),('PG','EGA','Engati','Engati',''),('PG','EIA','Eia','Eia',''),('PG','EMI','Emirau','Emirau',''),('PG','EMO','Emo','Emo',''),('PG','EMS','Embessa','Embessa',''),('PG','EPT','Eliptamin','Eliptamin',''),('PG','ERE','Erave','Erave',''),('PG','ERU','Erume','Erume',''),('PG','ESA','Esa\'ala','Esa\'ala',''),('PG','FAQ','Freida River','Freida River',''),('PG','FIN','Finschhafen','Finschhafen',''),('PG','FNE','Fane','Fane',''),('PG','FRQ','Feramin','Feramin',''),('PG','FUB','Fulleborn','Fulleborn',''),('PG','FUM','Fuma','Fuma',''),('PG','GAP','Gusap','Gusap',''),('PG','GAR','Garaina','Garaina',''),('PG','GAZ','Guasopa','Guasopa',''),('PG','GBC','Gasuke','Gasuke',''),('PG','GBF','Negarbo','Negarbo',''),('PG','GEI','Green Islands','Green Islands',''),('PG','GEW','Gewoia','Gewoia',''),('PG','GIL','Gilau','Gilau',''),('PG','GKA','Goroka','Goroka',''),('PG','GLP','Gulgubip','Gulgubip',''),('PG','GMI','Gasmata Island','Gasmata Island',''),('PG','GOC','Gora','Gora',''),('PG','GOE','Gonalia','Gonalia',''),('PG','GRH','Garuahi','Garuahi',''),('PG','GRL','Garasa','Garasa',''),('PG','GUE','Guriaso','Guriaso',''),('PG','GUG','Guari','Guari',''),('PG','GUR','Alotau','Alotau',''),('PG','GUV','Mougulu','Mougulu',''),('PG','GVI','Green River','Green River',''),('PG','GWN','Gnarowein','Gnarowein',''),('PG','HAZ','Hatzfeldthaven','Hatzfeldthaven',''),('PG','HEO','Haelogo','Haelogo',''),('PG','HGU','Mount Hagen','Mount Hagen',''),('PG','HIT','Hivaro','Hivaro',''),('PG','HKN','Hoskins','Hoskins',''),('PG','HNI','Heiweni','Heiweni',''),('PG','HNN','Honinabi','Honinabi',''),('PG','HOC','Komako','Komako',''),('PG','HWA','Hawabango','Hawabango',''),('PG','HYF','Hayfields','Hayfields',''),('PG','IAU','Iaura','Iaura',''),('PG','IBI','Iboki','Iboki',''),('PG','IDN','Indagen','Indagen',''),('PG','IHU','Ihu','Ihu',''),('PG','IIS','Nissan Island','Nissan Island',''),('PG','ILX','Ileg','Ileg',''),('PG','IMA','Iamalele','Iamalele',''),('PG','IMD','Imonda','Imonda',''),('PG','IMN','Imane','Imane',''),('PG','IOK','Iokea','Iokea',''),('PG','IOP','Ioma','Ioma',''),('PG','ITK','Itogama','Itogama',''),('PG','IUS','Inus','Inus',''),('PG','JAC','Jacksons','Jacksons',''),('PG','JAQ','Jacquinot Bay','Jacquinot Bay',''),('PG','JOP','Josephstaal','Josephstaal',''),('PG','KAF','Karato','Karato',''),('PG','KAK','Kar','Kar',''),('PG','KAQ','Kamulai','Kamulai',''),('PG','KBM','Kabwum','Kabwum',''),('PG','KCJ','Komaio','Komaio',''),('PG','KDE','Koroba','Koroba',''),('PG','KDP','Kandep','Kandep',''),('PG','KDQ','Kamberatoro','Kamberatoro',''),('PG','KDR','Kandrian','Kandrian',''),('PG','KEG','Keglsugl','Keglsugl',''),('PG','KEX','Kanabea','Kanabea',''),('PG','KGB','Konge','Konge',''),('PG','KGH','Yongai','Yongai',''),('PG','KGM','Kungum','Kungum',''),('PG','KGW','Kagi','Kagi',''),('PG','KIA','Kaiapit','Kaiapit',''),('PG','KIE','Kieta','Kieta',''),('PG','KIM','Kimbe','Kimbe',''),('PG','KIQ','Kira','Kira',''),('PG','KIZ','Kikinonda','Kikinonda',''),('PG','KJU','Kamiraba','Kamiraba',''),('PG','KKD','Kokoda','Kokoda',''),('PG','KLO','Kalo','Kalo',''),('PG','KMA','Kerema','Kerema',''),('PG','KMB','Koinambe','Koinambe',''),('PG','KMF','Kamina','Kamina',''),('PG','KMR','Karimui','Karimui',''),('PG','KNE','Kanainj','Kanainj',''),('PG','KNL','Kelanoa','Kelanoa',''),('PG','KOM','Komo-Manda','Komo-Manda',''),('PG','KOR','Kokoro','Kokoro',''),('PG','KPA','Kopiago','Kopiago',''),('PG','KPE','Yapsiei','Yapsiei',''),('PG','KPM','Kompiam','Kompiam',''),('PG','KPP','Kakapo','Kakapo',''),('PG','KQL','Kol','Kol',''),('PG','KRI','Kikori','Kikori',''),('PG','KRJ','Karawari','Karawari',''),('PG','KRK','Kairuku','Kairuku',''),('PG','KRU','Kerau','Kerau',''),('PG','KRX','Karkar Is','Karkar Is',''),('PG','KSB','Kasanombe','Kasanombe',''),('PG','KSG','Kisengan','Kisengan',''),('PG','KSP','Kosipe','Kosipe',''),('PG','KSX','Yasuru','Yasuru',''),('PG','KTK','Kanua','Kanua',''),('PG','KUL','Kumul','Kumul',''),('PG','KUP','Kupiano','Kupiano',''),('PG','KUQ','Kuri','Kuri',''),('PG','KUY','Kamusi','Kamusi',''),('PG','KVE','Kitava','Kitava',''),('PG','KVG','Kavieng','Kavieng',''),('PG','KWO','Kawito','Kawito',''),('PG','KWV','Kurwina','Kurwina',''),('PG','KWX','Kiwai Island','Kiwai Island',''),('PG','KXR','Karoola','Karoola',''),('PG','KYX','Yalumet','Yalumet',''),('PG','KZF','Kaintiba','Kaintiba',''),('PG','LAB','Lablab','Lablab',''),('PG','LAE','Lae','Lae',''),('PG','LDT','Londolovit','Londolovit',''),('PG','LGM','Laiagam','Laiagam',''),('PG','LGN','Linga Linga','Linga Linga',''),('PG','LHP','Lehu','Lehu',''),('PG','LMG','Lamassa','Lamassa',''),('PG','LMI','Lumi','Lumi',''),('PG','LMY','Lake Murray','Lake Murray',''),('PG','LNC','Lengbati','Lengbati',''),('PG','LNF','Munbil','Munbil',''),('PG','LNG','Lese','Lese',''),('PG','LNM','Langimar','Langimar',''),('PG','LNQ','Loani','Loani',''),('PG','LNV','Lihir Island','Lihir Island',''),('PG','LOL','Loloho','Loloho',''),('PG','LOR','Lorengau, Manus Island','Lorengau, Manus Island',''),('PG','LPN','Leron Plains','Leron Plains',''),('PG','LSA','Losuia','Losuia',''),('PG','LSJ','Long Island','Long Island',''),('PG','LTF','Leitre','Leitre',''),('PG','LWI','Lowai','Lowai',''),('PG','MAG','Madang','Madang',''),('PG','MAM','Manam Island','Manam Island',''),('PG','MAN','Manda','Manda',''),('PG','MAP','Mamai','Mamai',''),('PG','MAS','Manus Island','Manus Island',''),('PG','MBV','Masa','Masa',''),('PG','MDM','Munduku','Munduku',''),('PG','MDU','Mendi','Mendi',''),('PG','MFO','Manguna','Manguna',''),('PG','MFZ','Mesalia','Mesalia',''),('PG','MGG','Margarima','Margarima',''),('PG','MGP','Manga','Manga',''),('PG','MHY','Morehead','Morehead',''),('PG','MIE','Mielelek','Mielelek',''),('PG','MIS','Misima Island','Misima Island',''),('PG','MJJ','Moki','Moki',''),('PG','MKN','Malekolon','Malekolon',''),('PG','MLQ','Malalaua','Malalaua',''),('PG','MMV','Mal','Mal',''),('PG','MNP','Maron','Maron',''),('PG','MPF','Mapoda','Mapoda',''),('PG','MPG','Makini','Makini',''),('PG','MPU','Mapua','Mapua',''),('PG','MPX','Miyanmin','Miyanmin',''),('PG','MRH','May River','May River',''),('PG','MRM','Manare','Manare',''),('PG','MVI','Manetai','Manetai',''),('PG','MWG','Marawaka','Marawaka',''),('PG','MWI','Maramuni','Maramuni',''),('PG','MWU','Mussau','Mussau',''),('PG','MXH','Moro','Moro',''),('PG','MXK','Mindik','Mindik',''),('PG','MYX','Menyamya','Menyamya',''),('PG','MZN','Minj','Minj',''),('PG','NBA','Nambaiyufa','Nambaiyufa',''),('PG','NDI','Namudi','Namudi',''),('PG','NDN','Nadunumu','Nadunumu',''),('PG','NGR','Ningerum','Ningerum',''),('PG','NIS','Simberi Island','Simberi Island',''),('PG','NKN','Nankina','Nankina',''),('PG','NMN','Nomane','Nomane',''),('PG','NOM','Nomad River','Nomad River',''),('PG','NOO','Naoro','Naoro',''),('PG','NPG','Nipa','Nipa',''),('PG','NUG','Nuguria','Nuguria',''),('PG','NUT','Nutuve','Nutuve',''),('PG','NWT','Nowata','Nowata',''),('PG','OBM','Morobe','Morobe',''),('PG','OBX','Obo','Obo',''),('PG','OGE','Ogeranang','Ogeranang',''),('PG','OKP','Oksapmin','Oksapmin',''),('PG','OLQ','Olsobip','Olsobip',''),('PG','OML','Omkalai','Omkalai',''),('PG','ONB','Ononge','Ononge',''),('PG','OPB','Open Bay','Open Bay',''),('PG','OPU','Balimo','Balimo',''),('PG','OSE','Omora','Omora',''),('PG','OSG','Ossima','Ossima',''),('PG','OTY','Oria','Oria',''),('PG','PAW','Pambwa','Pambwa',''),('PG','PDI','Pindiu','Pindiu',''),('PG','PDO','Pondo Harbour','Pondo Harbour',''),('PG','PGB','Pangoa','Pangoa',''),('PG','PGE','Yegepa','Yegepa',''),('PG','PGN','Pangia','Pangia',''),('PG','PLE','Paiela','Paiela',''),('PG','PMN','Pumani','Pumani',''),('PG','PMP','Pimaga','Pimaga',''),('PG','PNP','Popondetta','Popondetta',''),('PG','POM','Port Moresby','Port Moresby',''),('PG','PPX','Param','Param',''),('PG','PUA','Puas','Puas',''),('PG','PUI','Pureni','Pureni',''),('PG','RAA','Rakanda','Rakanda',''),('PG','RAB','Rabaul','Rabaul',''),('PG','RAM','Rambutyo Island','Rambutyo Island',''),('PG','RAW','Arawa','Arawa',''),('PG','RAX','Oram','Oram',''),('PG','RBP','Rabaraba','Rabaraba',''),('PG','RGE','Porgera','Porgera',''),('PG','RKU','Yule Island','Yule Island',''),('PG','RMN','Rumginae','Rumginae',''),('PG','RNR','Robinson River','Robinson River',''),('PG','ROR','Orobay','Orobay',''),('PG','RUU','Ruti','Ruti',''),('PG','RVI','Russel Island','Russel Island',''),('PG','SAM','Salamo','Salamo',''),('PG','SBC','Selbang','Selbang',''),('PG','SBE','Suabi','Suabi',''),('PG','SBV','Sabah','Sabah',''),('PG','SCH','Schauten','Schauten',''),('PG','SDI','Saidor','Saidor',''),('PG','SFU','Safia','Safia',''),('PG','SGB','Singaua','Singaua',''),('PG','SGJ','Sagarai','Sagarai',''),('PG','SGK','Sangapi','Sangapi',''),('PG','SIL','Sila','Sila',''),('PG','SIM','Simbai','Simbai',''),('PG','SIZ','Sissano','Sissano',''),('PG','SKC','Suki','Suki',''),('PG','SMH','Sapmanga','Sapmanga',''),('PG','SMJ','Sim','Sim',''),('PG','SMP','Stockholm','Stockholm',''),('PG','SMU','Salamaua','Salamaua',''),('PG','SOI','Sokar Island','Sokar Island',''),('PG','SPH','Sopu','Sopu',''),('PG','SPL','Sipul','Sipul',''),('PG','SPV','Sepik Plains','Sepik Plains',''),('PG','SQT','Samarai','Samarai',''),('PG','SSS','Siassi','Siassi',''),('PG','SUZ','Suria','Suria',''),('PG','SWE','Siwea','Siwea',''),('PG','SWG','Satwag','Satwag',''),('PG','SWR','Silur','Silur',''),('PG','SXA','Sialum','Sialum',''),('PG','SXH','Sehulea','Sehulea',''),('PG','SXW','Sauren','Sauren',''),('PG','TAI','Tambutyo Island','Tambutyo Island',''),('PG','TAU','Taugu Island','Taugu Island',''),('PG','TBA','Tabibuga','Tabibuga',''),('PG','TBE','Timbunke','Timbunke',''),('PG','TBG','Tabubil','Tabubil',''),('PG','TBQ','Tarabo','Tarabo',''),('PG','TCJ','Torembi','Torembi',''),('PG','TCK','Tinboli','Tinboli',''),('PG','TDB','Tetebedi','Tetebedi',''),('PG','TEO','Terapo','Terapo',''),('PG','TEP','Teptep','Teptep',''),('PG','TFA','Tilfalmin','Tilfalmin',''),('PG','TFI','Tufi','Tufi',''),('PG','TFM','Telefomin','Telefomin',''),('PG','TGL','Tagula','Tagula',''),('PG','TIG','Tingwon','Tingwon',''),('PG','TIZ','Tari','Tari',''),('PG','TKB','Tekadu','Tekadu',''),('PG','TKW','Tekin','Tekin',''),('PG','TLO','Tol','Tol',''),('PG','TLP','Tumolbil','Tumolbil',''),('PG','TLW','Talasea','Talasea',''),('PG','TOI','Tolokiwa Island','Tolokiwa Island',''),('PG','TOK','Torokina','Torokina',''),('PG','TON','Tonu','Tonu',''),('PG','TPI','Tapini','Tapini',''),('PG','TRJ','Tarakbits','Tarakbits',''),('PG','TSI','Tsili Tsili','Tsili Tsili',''),('PG','TSK','Taskul','Taskul',''),('PG','TSW','Tsewi','Tsewi',''),('PG','TUT','Tauta','Tauta',''),('PG','TWY','Tawa','Tawa',''),('PG','UAE','Mount Aue','Mount Aue',''),('PG','UBI','Buin','Buin',''),('PG','UKU','Nuku','Nuku',''),('PG','ULE','Sule','Sule',''),('PG','UMC','Umba','Umba',''),('PG','UNG','Kiunga','Kiunga',''),('PG','UPR','Upiara','Upiara',''),('PG','URU','Uroubi','Uroubi',''),('PG','USO','Usino','Usino',''),('PG','UUU','Manumu','Manumu',''),('PG','UVO','Uvol','Uvol',''),('PG','VAI','Vanimo','Vanimo',''),('PG','VIV','Vivigani','Vivigani',''),('PG','VLA','Vailala','Vailala',''),('PG','VMU','Baimuru','Baimuru',''),('PG','WAB','Wabag','Wabag',''),('PG','WAJ','Wawoi Falls','Wawoi Falls',''),('PG','WAO','Wabo','Wabo',''),('PG','WBC','Wapolu','Wapolu',''),('PG','WBM','Wapenamanda','Wapenamanda',''),('PG','WED','Wedau','Wedau',''),('PG','WEP','Weam','Weam',''),('PG','WGU','Wagau','Wagau',''),('PG','WIU','Witu','Witu',''),('PG','WKN','Wakunai','Wakunai',''),('PG','WNU','Wanuma','Wanuma',''),('PG','WOA','Wonenara','Wonenara',''),('PG','WOK','Woodlark','Woodlark',''),('PG','WPM','Wipim','Wipim',''),('PG','WSA','Wasua','Wasua',''),('PG','WSU','Wasu','Wasu',''),('PG','WTP','Woitape','Woitape',''),('PG','WTT','Wantoat','Wantoat',''),('PG','WUG','Wau','Wau',''),('PG','WUM','Wasum','Wasum',''),('PG','WUV','Wuvulu Is','Wuvulu Is',''),('PG','WWK','Wewak','Wewak',''),('PG','XBN','Biniguni','Biniguni',''),('PG','XYR','Yellow River','Yellow River',''),('PG','YEQ','Yenkis','Yenkis',''),('PG','YVD','Yeva','Yeva',''),('PG','ZEN','Zenag','Zenag',''),('PH','','','',''),('PH','AAV','Alah','Alah',''),('PH','ABU','Abulog/Aparri','Abulog/Aparri',''),('PH','ADL','Adlay/Bislig','Adlay/Bislig',''),('PH','AGL','Angeles','Angeles',''),('PH','AHE','Aheron/Ozamis','Aheron/Ozamis',''),('PH','ALA','Alasang/Siain','Alasang/Siain',''),('PH','ALE','Aleran/Ozamis','Aleran/Ozamis',''),('PH','AMU','Amunitan/Aparri','Amunitan/Aparri',''),('PH','ANA','Anakan/Masao','Anakan/Masao',''),('PH','APR','Aparri, Luzon','Aparri, Luzon',''),('PH','AQE','Hamtic','Hamtic',''),('PH','ARA','Aras Asan/Bislig','Aras Asan/Bislig',''),('PH','ATI','Atimonan/Siain','Atimonan/Siain',''),('PH','BAB','Babato/Dadiangas','Babato/Dadiangas',''),('PH','BAG','Baguio','Baguio',''),('PH','BAI','Bais/Dumaguete','Bais/Dumaguete',''),('PH','BAL','Balaboe','Balaboe',''),('PH','BAS','Basiauang/Dadiangas','Basiauang/Dadiangas',''),('PH','BAU','Bauan/Batangas','Bauan/Batangas',''),('PH','BCD','Bacolod, Negros','Bacolod, Negros',''),('PH','BCO','Bacon/Legaspi','Bacon/Legaspi',''),('PH','BCT','Isabela, Basilan','Isabela, Basilan',''),('PH','BCU','Baculin/Mati','Baculin/Mati',''),('PH','BGC','Bagac','Bagac',''),('PH','BGI','Bagui Bay/San Fernando','Bagui Bay/San Fernando',''),('PH','BGR','Bucar Grande/Suriagao','Bucar Grande/Suriagao',''),('PH','BGS','Balingasag','Balingasag',''),('PH','BGV','Borongan','Borongan',''),('PH','BIY','Biyawa/Davao','Biyawa/Davao',''),('PH','BLA','Balanga/Batan','Balanga/Batan',''),('PH','BLC','Balabac, Palawan','Balabac, Palawan',''),('PH','BLG','Balogo/Batangas','Balogo/Batangas',''),('PH','BLN','Balengan/Siain','Balengan/Siain',''),('PH','BLP','Bolos Point/Aparri','Bolos Point/Aparri',''),('PH','BLT','Balintang/Puerto Princesa','Balintang/Puerto Princesa',''),('PH','BLU','Balumo/Zamboanga','Balumo/Zamboanga',''),('PH','BNG','Bauang','Bauang',''),('PH','BNQ','Baganga/Mati','Baganga/Mati',''),('PH','BNW','Banawan/Dadiangas','Banawan/Dadiangas',''),('PH','BOA','Boac, Marinduque','Boac, Marinduque',''),('PH','BOG','Bogo','Bogo',''),('PH','BOS','Boston/Davao','Boston/Davao',''),('PH','BPH','Bislig, Mindanao','Bislig, Mindanao',''),('PH','BQA','Baler/Siain','Baler/Siain',''),('PH','BRB','Barobo/Bislig','Barobo/Bislig',''),('PH','BRP','Brookes Point, Palawan','Brookes Point, Palawan',''),('PH','BRT','Barton/Puerto Princesa','Barton/Puerto Princesa',''),('PH','BSO','Basco','Basco',''),('PH','BSY','Basey/Catbalogan','Basey/Catbalogan',''),('PH','BTG','Batangas, Luzon','Batangas, Luzon',''),('PH','BTN','Bataan, Mariveles','Bataan, Mariveles',''),('PH','BTS','Batarasa/Puerto Princesa','Batarasa/Puerto Princesa',''),('PH','BTY','Bantayon/San Jose','Bantayon/San Jose',''),('PH','BUD','Budbud/Davao','Budbud/Davao',''),('PH','BUG','Bugo','Bugo',''),('PH','BUL','Bulan, Luzon','Bulan, Luzon',''),('PH','BUR','Burdeos, Polillo Isl','Burdeos, Polillo Isl',''),('PH','BXU','Butuan Bay/Masao','Butuan Bay/Masao',''),('PH','BYB','Baybay/Tacloban','Baybay/Tacloban',''),('PH','BYP','Bayang Point','Bayang Point',''),('PH','BYS','Bayabas/Bislig','Bayabas/Bislig',''),('PH','BYW','Bayawan/Dumaguete','Bayawan/Dumaguete',''),('PH','CAA','Calaca','Calaca',''),('PH','CAB','Cabugao Bay/Legaspi','Cabugao Bay/Legaspi',''),('PH','CAJ','Cajidiocan, Visayan Isl','Cajidiocan, Visayan Isl',''),('PH','CAL','Calamba','Calamba',''),('PH','CAM','Camarines Norte/Jose Panganiban','Camarines Norte/Jose Panganiban',''),('PH','CAZ','Cadiz','Cadiz',''),('PH','CBO','Cotabato, Mindanao','Cotabato, Mindanao',''),('PH','CBY','Calbayog, Samar','Calbayog, Samar',''),('PH','CCG','Calag-Calag/Dumaguete','Calag-Calag/Dumaguete',''),('PH','CDB','Caldera Bay/Zamboanga','Caldera Bay/Zamboanga',''),('PH','CDY','Cagayan De Sulu','Cagayan De Sulu',''),('PH','CEB','Cebu','Cebu',''),('PH','CGG','Casiguran/Siain','Casiguran/Siain',''),('PH','CGM','Camiguin Island/Aparri','Camiguin Island/Aparri',''),('PH','CGP','Calug Point/Zamboanga','Calug Point/Zamboanga',''),('PH','CGT','Calaguitan/Tacloban','Calaguitan/Tacloban',''),('PH','CGY','Cagayan de Oro, Mindanao','Cagayan de Oro, Mindanao',''),('PH','CLB','Canlubang','Canlubang',''),('PH','CLP','Calapan/Batangas','Calapan/Batangas',''),('PH','CLV','Claveria/Aparri','Claveria/Aparri',''),('PH','CML','Camalagawan/Aparri','Camalagawan/Aparri',''),('PH','CMO','Currimao','Currimao',''),('PH','CNT','Cantilan/Surigao','Cantilan/Surigao',''),('PH','CNY','Canaybon/Catbalogan','Canaybon/Catbalogan',''),('PH','CPL','Capalonga/Siain','Capalonga/Siain',''),('PH','CRG','Caraga/Mati','Caraga/Mati',''),('PH','CRM','Catarman','Catarman',''),('PH','CSB','Casul Bay/Ozamis','Casul Bay/Ozamis',''),('PH','CSI','Culasi','Culasi',''),('PH','CST','Castanas','Castanas',''),('PH','CTB','Catamon Bay/Iloilo','Catamon Bay/Iloilo',''),('PH','CTS','Catbalogan, Samar','Catbalogan, Samar',''),('PH','CUG','Calubian, Leyte','Calubian, Leyte',''),('PH','CUJ','Culion','Culion',''),('PH','CUN','Catanauan','Catanauan',''),('PH','CUR','Curuan/Zamboanga','Curuan/Zamboanga',''),('PH','CVE','Cavite, Luzon','Cavite, Luzon',''),('PH','CWY','Calowayan/Catabalogan','Calowayan/Catabalogan',''),('PH','CYP','Calbayog Apt, Samar','Calbayog Apt, Samar',''),('PH','CYU','Cuyo','Cuyo',''),('PH','CYZ','Cauayan','Cauayan',''),('PH','DCB','Dahikan Bay','Dahikan Bay',''),('PH','DDW','Dinadiawan/Aparri','Dinadiawan/Aparri',''),('PH','DGL','Dingalan/Siain','Dingalan/Siain',''),('PH','DGT','Dumaguete','Dumaguete',''),('PH','DIC','Diculum/Zamboanga','Diculum/Zamboanga',''),('PH','DID','Didadongan/Aparri','Didadongan/Aparri',''),('PH','DIO','Diotorin/Siain','Diotorin/Siain',''),('PH','DIR','Dirgalan','Dirgalan',''),('PH','DIV','Divilacan/Aparri','Divilacan/Aparri',''),('PH','DNG','Dinagat Island/Surigao','Dinagat Island/Surigao',''),('PH','DNL','Dinalongan/Siain','Dinalongan/Siain',''),('PH','DNO','Danao','Danao',''),('PH','DPL','Dipolog/Ozamis','Dipolog/Ozamis',''),('PH','DPT','Diapitan/Siain','Diapitan/Siain',''),('PH','DRB','Diaraboan/Siain','Diaraboan/Siain',''),('PH','DSG','Dilasag','Dilasag',''),('PH','DTE','Daet','Daet',''),('PH','DUL','Dulag','Dulag',''),('PH','DVO','Davao, Mindanao','Davao, Mindanao',''),('PH','ENI','El Nido/Puerto Princesa','El Nido/Puerto Princesa',''),('PH','GAC','Gachitorena/Jose Panganiban','Gachitorena/Jose Panganiban',''),('PH','GAS','Gasan','Gasan',''),('PH','GES','General Santos','General Santos',''),('PH','GGG','Gigaquit, Mindanao','Gigaquit, Mindanao',''),('PH','GGM','Gigmoto, Catanduanes','Gigmoto, Catanduanes',''),('PH','GIN','Gingoog/Masao','Gingoog/Masao',''),('PH','GMS','Guimaras/Iloilo','Guimaras/Iloilo',''),('PH','GNI','General Island/Bislig','General Island/Bislig',''),('PH','GUI','Guinabasan','Guinabasan',''),('PH','HIJ','Hijo Wharf/Davao','Hijo Wharf/Davao',''),('PH','HIM','Himamaylan, Negros','Himamaylan, Negros',''),('PH','HNB','Hinobaan/Iloilo','Hinobaan/Iloilo',''),('PH','HNG','Hinigaran/Iloilo','Hinigaran/Iloilo',''),('PH','HNT','Hinatuan/Bislig','Hinatuan/Bislig',''),('PH','HON','Hondagua/Siain','Hondagua/Siain',''),('PH','HOO','Hook Bay/Siain','Hook Bay/Siain',''),('PH','HYB','Hagnava Bay','Hagnava Bay',''),('PH','ICO','Sicogon Island','Sicogon Island',''),('PH','IGN','Iligan, Mindanao','Iligan, Mindanao',''),('PH','ILO','Iloilo, Panay','Iloilo, Panay',''),('PH','INP','Inampulugan Island','Inampulugan Island',''),('PH','IPE','Ipil/Zamboanga','Ipil/Zamboanga',''),('PH','ISL','Isabel','Isabel',''),('PH','JAG','Jagna','Jagna',''),('PH','JAS','Jasaan','Jasaan',''),('PH','JNZ','Jimenez/Ozamis','Jimenez/Ozamis',''),('PH','JOL','Jolo','Jolo',''),('PH','JPM','Jose Panganiban, Luzon','Jose Panganiban, Luzon',''),('PH','KAR','Karomatan/Iligan','Karomatan/Iligan',''),('PH','KAS','Kabasalan/Zamboanga','Kabasalan/Zamboanga',''),('PH','KAT','Katipunan/Ozamis','Katipunan/Ozamis',''),('PH','KIA','Kiamba/Dadiangas','Kiamba/Dadiangas',''),('PH','KIL','Kilbay Point/Jose Panganiban','Kilbay Point/Jose Panganiban',''),('PH','KIN','Kinogitan/Iligan','Kinogitan/Iligan',''),('PH','KIP','Kipit/Ozamis','Kipit/Ozamis',''),('PH','KIW','Kiwalan/Iligan','Kiwalan/Iligan',''),('PH','KLM','Kalamansig','Kalamansig',''),('PH','KLO','Kalibo','Kalibo',''),('PH','KOL','Kolambugan/Iligan','Kolambugan/Iligan',''),('PH','KUM','Kumalarang/Zamboanga','Kumalarang/Zamboanga',''),('PH','LAB','Labason/Zamboanga','Labason/Zamboanga',''),('PH','LAG','Lagonoy/Jose Panganiban','Lagonoy/Jose Panganiban',''),('PH','LAM','Lamit Bay/Jose Panganiban','Lamit Bay/Jose Panganiban',''),('PH','LAN','Lanuza/Bislig','Lanuza/Bislig',''),('PH','LAO','Laoag, Luzon','Laoag, Luzon',''),('PH','LAY','Lagondy River','Lagondy River',''),('PH','LBK','Lebak/Parang','Lebak/Parang',''),('PH','LBX','Lubang','Lubang',''),('PH','LEY','Leyte','Leyte',''),('PH','LGG','Lingig/Bislig','Lingig/Bislig',''),('PH','LGP','Legaspi Apt, Luzon','Legaspi Apt, Luzon',''),('PH','LIA','Lianga/Bislig','Lianga/Bislig',''),('PH','LIB','Libjo/Surigao','Libjo/Surigao',''),('PH','LIM','Limay/Bataan','Limay/Bataan',''),('PH','LIN','Lingayen, Luzon','Lingayen, Luzon',''),('PH','LNK','Linik/Dadiangas','Linik/Dadiangas',''),('PH','LNO','Lunao','Lunao',''),('PH','LOM','Lomuyon/Dadiangas','Lomuyon/Dadiangas',''),('PH','LOO','Looc Bay/San Jose','Looc Bay/San Jose',''),('PH','LOP','Long Point/Puerto Princesa','Long Point/Puerto Princesa',''),('PH','LPA','Lipa','Lipa',''),('PH','LPU','Lapu-Lapu, Cebu','Lapu-Lapu, Cebu',''),('PH','LPZ','La Paz/Iloilo','La Paz/Iloilo',''),('PH','LRP','La Rap/Jose Panganiban','La Rap/Jose Panganiban',''),('PH','LUG','Lugait','Lugait',''),('PH','LUM','Lumasal/Dadiangas','Lumasal/Dadiangas',''),('PH','LWA','Lwbak','Lwbak',''),('PH','LZB','Lazi','Lazi',''),('PH','MAA','Maasin','Maasin',''),('PH','MAB','Mabini, Mindanao','Mabini, Mindanao',''),('PH','MAC','Matho Cortez/Bislig','Matho Cortez/Bislig',''),('PH','MAD','Madaum/Davao','Madaum/Davao',''),('PH','MAI','Maitum/Dadiangas','Maitum/Dadiangas',''),('PH','MAK','Makar/Dadiangas','Makar/Dadiangas',''),('PH','MAN','Mandaue, Cebu','Mandaue, Cebu',''),('PH','MAS','Masao','Masao',''),('PH','MBO','Mamburao','Mamburao',''),('PH','MBT','Masbate','Masbate',''),('PH','MCD','Mercedes/Jose Panganiban','Mercedes/Jose Panganiban',''),('PH','MCJ','Macojalan/Ozamis','Macojalan/Ozamis',''),('PH','MCO','Maco/Davao','Maco/Davao',''),('PH','MDL','Mandaluyong','Mandaluyong',''),('PH','MDN','Medina','Medina',''),('PH','MGA','Magalona/Iloilo','Magalona/Iloilo',''),('PH','MGB','Magueda Bay/Catbalogan','Magueda Bay/Catbalogan',''),('PH','MGD','Mabaguid','Mabaguid',''),('PH','MGG','Mangogoy/Bislig','Mangogoy/Bislig',''),('PH','MGI','Mambagid','Mambagid',''),('PH','MHT','Marihatag, Mindanao','Marihatag, Mindanao',''),('PH','MIC','Misamis Or./Cagayan De Oro','Misamis Or./Cagayan De Oro',''),('PH','MIL','Milbuk/Dadiangas','Milbuk/Dadiangas',''),('PH','MIO','Misamis Occ./Ozamis','Misamis Occ./Ozamis',''),('PH','MLB','Maluso, Basilan','Maluso, Basilan',''),('PH','MLL','Malalag/Davao','Malalag/Davao',''),('PH','MLP','Malabang','Malabang',''),('PH','MLS','Magellanes/Masao','Magellanes/Masao',''),('PH','MNL','Manila','Manila',''),('PH','MNN','Manila North Harbour','Manila North Harbour',''),('PH','MNS','Manila South Harbour','Manila South Harbour',''),('PH','MNY','Manay/Mati','Manay/Mati',''),('PH','MON','Monserrat/Mati','Monserrat/Mati',''),('PH','MOR','Morong/Mariveles','Morong/Mariveles',''),('PH','MPH','Caticlan','Caticlan',''),('PH','MRQ','Marinduque','Marinduque',''),('PH','MSB','Malasugat Bay/Zamboanga','Malasugat Bay/Zamboanga',''),('PH','MSC','Masinloc/Sual','Masinloc/Sual',''),('PH','MSS','Mission/Aparri','Mission/Aparri',''),('PH','MSY','Manansalay/Batangas','Manansalay/Batangas',''),('PH','MTA','Matina Aplaya/Davao','Matina Aplaya/Davao',''),('PH','MUL','Mulanay/Siain','Mulanay/Siain',''),('PH','MVS','Mariveles, Luzon','Mariveles, Luzon',''),('PH','MXI','Mati, Mindanao','Mati, Mindanao',''),('PH','NAB','Nabulao Bay/Iloilo','Nabulao Bay/Iloilo',''),('PH','NAG','Naga, Luzon','Naga, Luzon',''),('PH','NAL','Nalungga/Iloilo','Nalungga/Iloilo',''),('PH','NAP','Napsan/Puerto Princesa','Napsan/Puerto Princesa',''),('PH','NAR','Naris Point/Puerto Princesa','Naris Point/Puerto Princesa',''),('PH','NAS','Nasipit/Masao','Nasipit/Masao',''),('PH','NGH','Nagh','Nagh',''),('PH','NID','Nido Terminal','Nido Terminal',''),('PH','NON','Nonoc/Surigao Del Norte','Nonoc/Surigao Del Norte',''),('PH','NOP','Mactan Island Apt','Mactan Island Apt',''),('PH','NPT','Napot Point','Napot Point',''),('PH','NSP','Sangley Point','Sangley Point',''),('PH','NTO','Nato','Nato',''),('PH','NUG','Nasugbu, Luzon','Nasugbu, Luzon',''),('PH','OLO','Olongapo','Olongapo',''),('PH','OPO','Opol','Opol',''),('PH','ORA','Orayuita','Orayuita',''),('PH','ORC','Ormoc/Tacloban','Ormoc/Tacloban',''),('PH','ORS','Oras/Catbalogan','Oras/Catbalogan',''),('PH','OTE','Oteiza/Bislig','Oteiza/Bislig',''),('PH','OZC','Ozamis, Mindanao','Ozamis, Mindanao',''),('PH','PAG','Pagadian/Zamboanga','Pagadian/Zamboanga',''),('PH','PAM','Pampanga','Pampanga',''),('PH','PAS','Pasay, Luzon','Pasay, Luzon',''),('PH','PBA','Port Barton/Palawan','Port Barton/Palawan',''),('PH','PCA','Panacosa/Puerto Princesa','Panacosa/Puerto Princesa',''),('PH','PCN','Panacan/Davao','Panacan/Davao',''),('PH','PDC','Polanco, Mindanao','Polanco, Mindanao',''),('PH','PDR','Pacio de Rozas/Batangas','Pacio de Rozas/Batangas',''),('PH','PGT','Pangutaran/Jolo','Pangutaran/Jolo',''),('PH','PHD','Port Holland','Port Holland',''),('PH','PIN','Pinamalayan/Batangas','Pinamalayan/Batangas',''),('PH','PLA','Plaridel/Ozamis','Plaridel/Ozamis',''),('PH','PLB','Palamit Bay/San Jose','Palamit Bay/San Jose',''),('PH','PLC','Polloc','Polloc',''),('PH','PLL','Polillo, Polillo Isl','Polillo, Polillo Isl',''),('PH','PLP','Palapag/San Jose','Palapag/San Jose',''),('PH','PLW','Palawan/Ozamis','Palawan/Ozamis',''),('PH','PMT','Pamintayan/Zamboanga','Pamintayan/Zamboanga',''),('PH','PNB','Panabutan/Zamboanga','Panabutan/Zamboanga',''),('PH','PNN','Paninirongan/Sanjose','Paninirongan/Sanjose',''),('PH','PNT','Punti/Aparri','Punti/Aparri',''),('PH','PPL','Pamplona/Aparri','Pamplona/Aparri',''),('PH','PPN','Palompon','Palompon',''),('PH','PPP','Pagudpud, Luzon','Pagudpud, Luzon',''),('PH','PPS','Puerto Princesa, Palawan','Puerto Princesa, Palawan',''),('PH','PRA','Parang','Parang',''),('PH','PRO','Poro/San Fernando','Poro/San Fernando',''),('PH','PSG','Pasig/Manila','Pasig/Manila',''),('PH','PSL','Pasaleng, Luzon','Pasaleng, Luzon',''),('PH','PSM','Puerto Santa Maria','Puerto Santa Maria',''),('PH','PTL','Puntalinao/Mati','Puntalinao/Mati',''),('PH','PUG','Pugad/Bislig','Pugad/Bislig',''),('PH','PUL','Pulupandan','Pulupandan',''),('PH','QBI','Quinabigan','Quinabigan',''),('PH','QBL','Quinablagan/Mati','Quinablagan/Mati',''),('PH','QPT','Quipit Bay/Ozamis','Quipit Bay/Ozamis',''),('PH','QUE','Queson/Siain','Queson/Siain',''),('PH','QUI','Quiddiao/Aparri','Quiddiao/Aparri',''),('PH','REA','Real/Siain','Real/Siain',''),('PH','RIZ','Rizal, Luzon','Rizal, Luzon',''),('PH','RLN','Romblon','Romblon',''),('PH','RSO','Rosario','Rosario',''),('PH','RTB','Rio Tuba','Rio Tuba',''),('PH','RXS','Roxas/Puerto Princesa','Roxas/Puerto Princesa',''),('PH','SAG','Sagay/Iloilo','Sagay/Iloilo',''),('PH','SAN','Santa Ana/Aparri','Santa Ana/Aparri',''),('PH','SAS','Sasa/Davao','Sasa/Davao',''),('PH','SAY','Sayao/Batangas','Sayao/Batangas',''),('PH','SBB','Sabbot/Siain','Sabbot/Siain',''),('PH','SBG','Sabang','Sabang',''),('PH','SBY','Sablayan/Batangas','Sablayan/Batangas',''),('PH','SCA','San Carlos/Dumaguete','San Carlos/Dumaguete',''),('PH','SCR','Santa Cruz/Sual','Santa Cruz/Sual',''),('PH','SCT','Santa Catalina/Dumaguete','Santa Catalina/Dumaguete',''),('PH','SDG','Sindangan/Ozamis','Sindangan/Ozamis',''),('PH','SFE','San Fernando, Luzon','San Fernando, Luzon',''),('PH','SFS','Subic Bay','Subic Bay',''),('PH','SGD','Sogod/Tacloban','Sogod/Tacloban',''),('PH','SGS','Sanga Sanga','Sanga Sanga',''),('PH','SIG','Sigayan/Parang','Sigayan/Parang',''),('PH','SIN','Siain, Luzon','Siain, Luzon',''),('PH','SIO','San Ignacio/Mati','San Ignacio/Mati',''),('PH','SIR','Siari/Ozamis','Siari/Ozamis',''),('PH','SIS','San Isidro/Sanjose','San Isidro/Sanjose',''),('PH','SIY','Siay/Zamboanga','Siay/Zamboanga',''),('PH','SJI','San Jose Apt, Mindoro','San Jose Apt, Mindoro',''),('PH','SKU','Sultan Kudarat/Dadiangas','Sultan Kudarat/Dadiangas',''),('PH','SLU','Santa Lucia/Puerto Princesa','Santa Lucia/Puerto Princesa',''),('PH','SMA','Santa Maria/Zamboanga','Santa Maria/Zamboanga',''),('PH','SMR','Semirara','Semirara',''),('PH','SNG','Sangi/Cebu','Sangi/Cebu',''),('PH','SNI','Santa Nino','Santa Nino',''),('PH','SOR','Sorsogon/Legaspi','Sorsogon/Legaspi',''),('PH','SPQ','San Pio Quinto/Aparri','San Pio Quinto/Aparri',''),('PH','SSV','Siasi','Siasi',''),('PH','STE','San Teodoro/Batangas','San Teodoro/Batangas',''),('PH','STS','Santo Tomas','Santo Tomas',''),('PH','SUA','Sual','Sual',''),('PH','SUG','Surigao, Mindanao','Surigao, Mindanao',''),('PH','TAB','Tabango, Leyte','Tabango, Leyte',''),('PH','TAC','Tacloban, Leyte','Tacloban, Leyte',''),('PH','TAG','Tagbilaran, Bohol','Tagbilaran, Bohol',''),('PH','TAL','Talibon','Talibon',''),('PH','TAN','Tandayag','Tandayag',''),('PH','TAR','Tarlac, Luzon','Tarlac, Luzon',''),('PH','TAY','Taytay/Puerto Princesa','Taytay/Puerto Princesa',''),('PH','TBC','Tabaco/Legaspi','Tabaco/Legaspi',''),('PH','TBG','Tabangoa','Tabangoa',''),('PH','TBH','Tablas','Tablas',''),('PH','TBU','Tagabuli/Davao','Tagabuli/Davao',''),('PH','TDC','Tandoc','Tandoc',''),('PH','TDG','Tandag/Bislig','Tandag/Bislig',''),('PH','TGB','Tagbita','Tagbita',''),('PH','TGD','Tagudin/San Fernando','Tagudin/San Fernando',''),('PH','TGI','Tuguis/Dadiangas','Tuguis/Dadiangas',''),('PH','TGL','Taguilon/Ozamis','Taguilon/Ozamis',''),('PH','TGN','Tambungon/Davao','Tambungon/Davao',''),('PH','TGO','Tagoloan','Tagoloan',''),('PH','TGT','Taguite Bay/Zamboanga','Taguite Bay/Zamboanga',''),('PH','TGW','Tungawan Bay/Zamboanga','Tungawan Bay/Zamboanga',''),('PH','TIB','Tibungco/Davao','Tibungco/Davao',''),('PH','TKW','Tagkawayan/Siain','Tagkawayan/Siain',''),('PH','TLD','Toledo/Cebu','Toledo/Cebu',''),('PH','TLG','Tolong/Dumaguete','Tolong/Dumaguete',''),('PH','TLM','Talomo/Davao','Talomo/Davao',''),('PH','TLP','Tolopo','Tolopo',''),('PH','TLS','Tolosa/Tacloban','Tolosa/Tacloban',''),('PH','TMA','Trece Martires','Trece Martires',''),('PH','TNU','Tanauan/Tacloban','Tanauan/Tacloban',''),('PH','TOB','Toboso/Dumaguete','Toboso/Dumaguete',''),('PH','TRO','Troloban','Troloban',''),('PH','TUG','Tuguegarao','Tuguegarao',''),('PH','TWT','Tawitawi','Tawitawi',''),('PH','ULY','Ulugan Bay','Ulugan Bay',''),('PH','URR','Umrur','Umrur',''),('PH','USU','Busuanga','Busuanga',''),('PH','VCS','Victorias, Negros','Victorias, Negros',''),('PH','VNV','Villanueva','Villanueva',''),('PH','VRC','Virac','Virac',''),('PH','VTL','Vitali/Zamboanga','Vitali/Zamboanga',''),('PH','VTO','Vito/Iloilo','Vito/Iloilo',''),('PH','WAS','Wasag/Dadiangas','Wasag/Dadiangas',''),('PH','WAW','Wawa/Batangas','Wawa/Batangas',''),('PH','WNP','Naga/Zamboanga','Naga/Zamboanga',''),('PH','XCN','Coron','Coron',''),('PH','XMA','Maramag','Maramag',''),('PH','XSO','Siocon/Zamboanga','Siocon/Zamboanga',''),('PH','ZAM','Zamboanga','Zamboanga',''),('PK','','','',''),('PK','AAW','Abbottabad','Abbottabad',''),('PK','ATG','Attock','Attock',''),('PK','BDN','Badin','Badin',''),('PK','BHC','Bhurban','Bhurban',''),('PK','BHV','Bahawalpur','Bahawalpur',''),('PK','BNP','Bannu','Bannu',''),('PK','BQM','Karachi-Muhammad Bin Qasim','Karachi-Muhammad Bin Qasim',''),('PK','CHB','Chilas','Chilas',''),('PK','CJL','Chitral','Chitral',''),('PK','CMN','Chaman','Chaman',''),('PK','CWP','Campbellpore','Campbellpore',''),('PK','DBA','Dalbandin','Dalbandin',''),('PK','DDU','Dadu','Dadu',''),('PK','DEA','Dera Ghazi Khan','Dera Ghazi Khan',''),('PK','DSK','Dera Ismail Khan','Dera Ismail Khan',''),('PK','GIL','Gilgit','Gilgit',''),('PK','GRT','Gujrat','Gujrat',''),('PK','GWD','Gwadar','Gwadar',''),('PK','HDD','Hyderabad','Hyderabad',''),('PK','HRA','Mansehra','Mansehra',''),('PK','ISB','Islamabad','Islamabad',''),('PK','JAG','Jacobabad','Jacobabad',''),('PK','JIW','Jiwani','Jiwani',''),('PK','KBH','Kalat','Kalat',''),('PK','KBU','Keti Bunder','Keti Bunder',''),('PK','KCF','Kadanwari','Kadanwari',''),('PK','KCT','Karachi Container Terminal','Karachi Container Terminal',''),('PK','KDD','Khuzdar','Khuzdar',''),('PK','KDU','Skardu','Skardu',''),('PK','KHI','Karachi','Karachi',''),('PK','KRB','Khokhropar','Khokhropar',''),('PK','LHE','Lahore','Lahore',''),('PK','LRG','Lora Lai','Lora Lai',''),('PK','LYP','Faisalabad','Faisalabad',''),('PK','MAN','Mangla','Mangla',''),('PK','MFG','Muzaffarabad','Muzaffarabad',''),('PK','MGP','Mogulpura/Lahore','Mogulpura/Lahore',''),('PK','MJD','Mohenjodaro','Mohenjodaro',''),('PK','MPD','Mirpur Khas (= Sindhri)','Mirpur Khas (= Sindhri)',''),('PK','MUX','Multan','Multan',''),('PK','MWD','Mianwali','Mianwali',''),('PK','MZJ','Muzaffargarh','Muzaffargarh',''),('PK','NDD','Nok Kundi','Nok Kundi',''),('PK','NHS','Nushki','Nushki',''),('PK','OHT','Kohat','Kohat',''),('PK','ORW','Ormara','Ormara',''),('PK','PAJ','Para Chinar','Para Chinar',''),('PK','PEW','Peshawar','Peshawar',''),('PK','PJG','Panjgur','Panjgur',''),('PK','PSI','Pasni','Pasni',''),('PK','PZH','Zhob','Zhob',''),('PK','QKH','Kharian','Kharian',''),('PK','RAZ','Rawala Kot','Rawala Kot',''),('PK','RWP','Rawalpindi','Rawalpindi',''),('PK','RYK','Rahim Yar Khan','Rahim Yar Khan',''),('PK','SBQ','Sibi','Sibi',''),('PK','SDT','Saidu Sharif','Saidu Sharif',''),('PK','SGI','Sargodha','Sargodha',''),('PK','SKT','Sialkot','Sialkot',''),('PK','SKZ','Sukkur','Sukkur',''),('PK','SUL','Sui','Sui',''),('PK','SWN','Sahiwal','Sahiwal',''),('PK','SWV','Shikarpur','Shikarpur',''),('PK','SYW','Sehwen Sharif','Sehwen Sharif',''),('PK','TFT','Koh-I-Taftan','Koh-I-Taftan',''),('PK','TLB','Tarbela','Tarbela',''),('PK','TOR','Torkham','Torkham',''),('PK','TUK','Turbat','Turbat',''),('PK','UET','Quetta','Quetta',''),('PK','WAF','Wana','Wana',''),('PK','WAG','Wagha','Wagha',''),('PK','WGB','Bahawalnagar','Bahawalnagar',''),('PK','WGH','Wagah','Wagah',''),('PK','WNS','Nawabshah','Nawabshah',''),('PK','ZEO','Savi Ragha','Savi Ragha',''),('PL','','','',''),('PL','ADC','Andrychow','Andrychow',''),('PL','ADJ','Adamow','Adamow',''),('PL','ALK','Aleksandrow Kujawski','Aleksandrow Kujawski',''),('PL','AUG','Augustow','Augustow',''),('PL','AWL','Aleksandrow Lodzki','Aleksandrow Lodzki',''),('PL','BAP','Biala Podlaska','Biala Podlaska',''),('PL','BAR','Bartoszyce','Bartoszyce',''),('PL','BCA','Bochnia','Bochnia',''),('PL','BED','B?dzino','B?dzino',''),('PL','BEL','Be??yce','Be??yce',''),('PL','BGA','Boguchwala','Boguchwala',''),('PL','BGW','BoguchwaBa','BoguchwaBa',''),('PL','BGY','Bogatynia','Bogatynia',''),('PL','BIA','Bialystok','Bialystok',''),('PL','BIB','Bielsko-Biala','Bielsko-Biala',''),('PL','BID','Biadoliny','Biadoliny',''),('PL','BKI','Brzesc Kujawski','Brzesc Kujawski',''),('PL','BLE','Bledow','Bledow',''),('PL','BLK','Barlinek','Barlinek',''),('PL','BLO','Blonie','Blonie',''),('PL','BLS','Bielsk Podlaski','Bielsk Podlaski',''),('PL','BLW','Bielawa','Bielawa',''),('PL','BNA','Brodnica','Brodnica',''),('PL','BNH','Baniocha','Baniocha',''),('PL','BNO','Banino','Banino',''),('PL','BOL','Boleslawiec','Boleslawiec',''),('PL','BOW','Bolimow','Bolimow',''),('PL','BRG','Brzeg','Brzeg',''),('PL','BRI','Brwinow','Brwinow',''),('PL','BRO','Brzeznio','Brzeznio',''),('PL','BRT','Bierutow','Bierutow',''),('PL','BRZ','Brzesko','Brzesko',''),('PL','BST','Bierun Stary','Bierun Stary',''),('PL','BSU','Borne','Borne',''),('PL','BTW','Belchatow','Belchatow',''),('PL','BUK','Buk','Buk',''),('PL','BUS','Busko-Zdroj','Busko-Zdroj',''),('PL','BWG','Boguszow-Gorce','Boguszow-Gorce',''),('PL','BYT','Bytom','Bytom',''),('PL','BYW','Bielany Wroclawskie','Bielany Wroclawskie',''),('PL','BZD','Brzeg Dolny','Brzeg Dolny',''),('PL','BZG','Bydgoszcz','Bydgoszcz',''),('PL','BZI','Burzenin','Burzenin',''),('PL','BZO','Bialaczow','Bialaczow',''),('PL','CHD','Chodziez','Chodziez',''),('PL','CHE','Chojnice','Chojnice',''),('PL','CHO','Chelmno','Chelmno',''),('PL','CHZ','Chocianow','Chocianow',''),('PL','CIE','Ciechanow','Ciechanow',''),('PL','CIK','Ciechocinek','Ciechocinek',''),('PL','CJO','Chojnow','Chojnow',''),('PL','CKL','Czerwionka','Czerwionka',''),('PL','CLK','Chelm Lubelska','Chelm Lubelska',''),('PL','CLZ','Czeladz','Czeladz',''),('PL','CNW','Chrzanow','Chrzanow',''),('PL','CRW','Chorzow','Chorzow',''),('PL','CWL','Chociwel','Chociwel',''),('PL','CWY','Cieplowody','Cieplowody',''),('PL','CZA','Czarnkow','Czarnkow',''),('PL','CZD','Czechowice-Dziedzice','Czechowice-Dziedzice',''),('PL','CZK','Czaplinek','Czaplinek',''),('PL','CZW','Czestochowa','Czestochowa',''),('PL','CZY','Cieszyn','Cieszyn',''),('PL','DAB','Dabrowa Gornicza','Dabrowa Gornicza',''),('PL','DAR','Darlowo','Darlowo',''),('PL','DBE','Dabie','Dabie',''),('PL','DBL','Deblin','Deblin',''),('PL','DBN','Dabrowno','Dabrowno',''),('PL','DBZ','Dobrodzien','Dobrodzien',''),('PL','DCE','Dobczyce','Dobczyce',''),('PL','DEB','Debica','Debica',''),('PL','DKA','Debnica Kaszubska','Debnica Kaszubska',''),('PL','DNW','Dobrzyn nad Wisla','Dobrzyn nad Wisla',''),('PL','DOK','Dobrzyniewo Koscielne','Dobrzyniewo Koscielne',''),('PL','DOL','Do?uje Mierzyn','Do?uje Mierzyn',''),('PL','DUS','Duszniki Zdroj','Duszniki Zdroj',''),('PL','DZE','Dobrzykowice Wroclawskie','Dobrzykowice Wroclawskie',''),('PL','DZI','Dzialdowo','Dzialdowo',''),('PL','DZO','Dzierzoniow','Dzierzoniow',''),('PL','DZW','Smardzew','Smardzew',''),('PL','ELB','Elblag','Elblag',''),('PL','FBI','Fabianki','Fabianki',''),('PL','GBN','Grebocin','Grebocin',''),('PL','GCW','Goclaw','Goclaw',''),('PL','GDK','Gadki','Gadki',''),('PL','GDN','Gdansk','Gdansk',''),('PL','GDY','Gdynia','Gdynia',''),('PL','GIZ','Gizycko','Gizycko',''),('PL','GJW','Grajewo','Grajewo',''),('PL','GKI','Glinki','Glinki',''),('PL','GKW','Godzikowice','Godzikowice',''),('PL','GLE','Garbatka-Letnisko','Garbatka-Letnisko',''),('PL','GLO','Gluchowo','Gluchowo',''),('PL','GLW','Glogow','Glogow',''),('PL','GNI','Gniewino','Gniewino',''),('PL','GNW','Gniewkowo','Gniewkowo',''),('PL','GNZ','Gniezno','Gniezno',''),('PL','GOC','Goczalkow','Goczalkow',''),('PL','GOD','Golub-Dobrzyn','Golub-Dobrzyn',''),('PL','GOE','Goleszow','Goleszow',''),('PL','GOK','Gora Kalwaria','Gora Kalwaria',''),('PL','GOL','Goleniow','Goleniow',''),('PL','GOW','Gorzow Wielkopolski','Gorzow Wielkopolski',''),('PL','GRA','Gora','Gora',''),('PL','GRC','Gieralcice','Gieralcice',''),('PL','GRN','Gryfino','Gryfino',''),('PL','GRO','Grojec','Grojec',''),('PL','GRU','Grudziadz','Grudziadz',''),('PL','GRY','Gryfice','Gryfice',''),('PL','GSL','Gora Slaska','Gora Slaska',''),('PL','GTW','Gieraltowiec','Gieraltowiec',''),('PL','GTY','Gostyn','Gostyn',''),('PL','GUZ','Guzow','Guzow',''),('PL','GWC','Gliwice','Gliwice',''),('PL','GWI','Garwolin','Garwolin',''),('PL','GWO','Glowno','Glowno',''),('PL','GZA','Gluszyca','Gluszyca',''),('PL','GZE','Gorzyce (Tarnobrzeg)','Gorzyce (Tarnobrzeg)',''),('PL','GZK','Grodzisk Wielkopolski','Grodzisk Wielkopolski',''),('PL','GZW','Gorzow','Gorzow',''),('PL','HBZ','Hrubieszow','Hrubieszow',''),('PL','HEL','Hel','Hel',''),('PL','HJK','Hajnowka','Hajnowka',''),('PL','IBN','Izabelin','Izabelin',''),('PL','IEG','Zielona Gora','Zielona Gora',''),('PL','ILA','Ilawa','Ilawa',''),('PL','ILW','Ilowa','Ilowa',''),('PL','INO','Inowroclaw','Inowroclaw',''),('PL','IWA','Iwaniska','Iwaniska',''),('PL','IYC','Iwierzyce','Iwierzyce',''),('PL','JAA','Jasienica','Jasienica',''),('PL','JAO','Janikowo','Janikowo',''),('PL','JAR','Jaroslaw','Jaroslaw',''),('PL','JAS','Jaslo','Jaslo',''),('PL','JAT','Jastarnia','Jastarnia',''),('PL','JAW','Jaworzno','Jaworzno',''),('PL','JEG','Jelenia Gora','Jelenia Gora',''),('PL','JKI','Janki','Janki',''),('PL','JKO','Jastkowice','Jastkowice',''),('PL','JKR','Jaktorow','Jaktorow',''),('PL','JLE','Jelcz-Laskowice','Jelcz-Laskowice',''),('PL','JNK','Jelonek','Jelonek',''),('PL','JON','Jarocin','Jarocin',''),('PL','JRT','Jurata','Jurata',''),('PL','JWE','Jaworze','Jaworze',''),('PL','JWL','Janow Lubelski','Janow Lubelski',''),('PL','JWO','Jaworzno','Jaworzno',''),('PL','JWP','Janow Podlaski','Janow Podlaski',''),('PL','JWR','Jawor','Jawor',''),('PL','JZB','Jastrzebie Zdroj','Jastrzebie Zdroj',''),('PL','JZW','Jedrzejow','Jedrzejow',''),('PL','KAA','Kowala St?pocina','Kowala St?pocina',''),('PL','KAJ','Karlikowo','Karlikowo',''),('PL','KAL','Kalisz','Kalisz',''),('PL','KAM','Kamienna Gora','Kamienna Gora',''),('PL','KAZ','Kazimierz','Kazimierz',''),('PL','KCL','Kucelinska','Kucelinska',''),('PL','KCN','Krasocin','Krasocin',''),('PL','KEK','K?dzierzyn-Ko?le','K?dzierzyn-Ko?le',''),('PL','KEP','Kepno','Kepno',''),('PL','KIJ','Kijow','Kijow',''),('PL','KKE','Krapkowice','Krapkowice',''),('PL','KLA','Kobylanka','Kobylanka',''),('PL','KLC','Kielce','Kielce',''),('PL','KLE','Kleszczow','Kleszczow',''),('PL','KLI','Klikawa','Klikawa',''),('PL','KLN','Kolno','Kolno',''),('PL','KLO','Klodzko','Klodzko',''),('PL','KLQ','Kolo','Kolo',''),('PL','KLS','Koluszki','Koluszki',''),('PL','KLU','Kluczbork','Kluczbork',''),('PL','KLW','Klimontow','Klimontow',''),('PL','KMC','Kamieniec','Kamieniec',''),('PL','KNK','Koneck','Koneck',''),('PL','KNO','Kolno','Kolno',''),('PL','KNQ','Karlino','Karlino',''),('PL','KNS','Konstantcin','Konstantcin',''),('PL','KOA','Kobylka','Kobylka',''),('PL','KOD','Krosno Odrzanskie','Krosno Odrzanskie',''),('PL','KOL','Kolobrzeg','Kolobrzeg',''),('PL','KOM','Komorowice','Komorowice',''),('PL','KON','Konin','Konin',''),('PL','KOP','Kopytow','Kopytow',''),('PL','KOR','Koroszczyn','Koroszczyn',''),('PL','KOZ','Kozy','Kozy',''),('PL','KPI','Kamien Pomorski','Kamien Pomorski',''),('PL','KRA','Krasnystaw','Krasnystaw',''),('PL','KRC','Kroscienko','Kroscienko',''),('PL','KRK','Krakow','Krakow',''),('PL','KRN','Krotoszyn','Krotoszyn',''),('PL','KRO','Krosno','Krosno',''),('PL','KRS','Krasnik','Krasnik',''),('PL','KRW','Krerowo','Krerowo',''),('PL','KRY','Krynica','Krynica',''),('PL','KRZ','Krzyz','Krzyz',''),('PL','KSC','Koscian','Koscian',''),('PL','KSE','Konskie','Konskie',''),('PL','KSW','Kielcze Stare','Kielcze Stare',''),('PL','KTW','Katowice','Katowice',''),('PL','KTY','Kety','Kety',''),('PL','KTZ','Kartuzy','Kartuzy',''),('PL','KUE','Kurznie','Kurznie',''),('PL','KUT','Kutno','Kutno',''),('PL','KWD','Kwidzyn','Kwidzyn',''),('PL','KWE','Karlowice','Karlowice',''),('PL','KWL','Konstantynow Lodzki','Konstantynow Lodzki',''),('PL','KWO','Ksawerow','Ksawerow',''),('PL','KYC','Korycin','Korycin',''),('PL','KYE','Kobierzyce','Kobierzyce',''),('PL','KYW','Katy Wroclawskie','Katy Wroclawskie',''),('PL','KYZ','Krzy|','Krzy|',''),('PL','KZA','Kolbuszowa','Kolbuszowa',''),('PL','KZC','Krzeszowice','Krzeszowice',''),('PL','KZE','Kozienice','Kozienice',''),('PL','KZK','Krzyszkowice','Krzyszkowice',''),('PL','KZO','Kleszczewo','Kleszczewo',''),('PL','KZW','Krzeszow','Krzeszow',''),('PL','KZY','Kostrzyn','Kostrzyn',''),('PL','LAZ','Laziska','Laziska',''),('PL','LBC','Lubicz','Lubicz',''),('PL','LBN','Luban','Luban',''),('PL','LBO','Lubon','Lubon',''),('PL','LBR','Lubartow','Lubartow',''),('PL','LBS','Lubiszewo','Lubiszewo',''),('PL','LBZ','Lubiszewo','Lubiszewo',''),('PL','LDN','Ladna','Ladna',''),('PL','LEA','Leba','Leba',''),('PL','LEB','Lebork','Lebork',''),('PL','LEG','Legnica','Legnica',''),('PL','LEJ','Lekawica','Lekawica',''),('PL','LEK','Lezajsk','Lezajsk',''),('PL','LEZ','Leszno','Leszno',''),('PL','LGO','Legionowo','Legionowo',''),('PL','LIP','Lipno','Lipno',''),('PL','LIW','Lidzbark Warminski','Lidzbark Warminski',''),('PL','LKO','Lyszkowice','Lyszkowice',''),('PL','LKW','Lukow','Lukow',''),('PL','LMA','Limanowa','Limanowa',''),('PL','LOD','Lodz','Lodz',''),('PL','LOK','Lomianki','Lomianki',''),('PL','LOW','Lowicz','Lowicz',''),('PL','LSK','Lask','Lask',''),('PL','LTK','Lutomiersk','Lutomiersk',''),('PL','LTY','Lutynia','Lutynia',''),('PL','LUB','Lubawa','Lubawa',''),('PL','LUC','Lubliniec','Lubliniec',''),('PL','LUL','Lublin','Lublin',''),('PL','LUN','Lubin','Lubin',''),('PL','LWK','Lubawka','Lubawka',''),('PL','LZN','Leszno','Leszno',''),('PL','LZO','Luzino','Luzino',''),('PL','LZW','Laskarzew','Laskarzew',''),('PL','LZY','Leczyca','Leczyca',''),('PL','MAA','Malaszewicze','Malaszewicze',''),('PL','MAG','Malkinia Gorna','Malkinia Gorna',''),('PL','MAK','Makow','Makow',''),('PL','MAL','Malechowo','Malechowo',''),('PL','MAW','Malanow','Malanow',''),('PL','MBZ','Milobadz','Milobadz',''),('PL','MCA','Mosciska','Mosciska',''),('PL','MIA','Modlinica','Modlinica',''),('PL','MIC','Miechow','Miechow',''),('PL','MID','Miedzyzdroje','Miedzyzdroje',''),('PL','MIE','Michalowice','Michalowice',''),('PL','MIK','Miko?ow','Miko?ow',''),('PL','MIN','Minsk Mazowiecki','Minsk Mazowiecki',''),('PL','MIR','Mirkow','Mirkow',''),('PL','MKI','Marki','Marki',''),('PL','MKW','Mietkow','Mietkow',''),('PL','MLA','Mlawa','Mlawa',''),('PL','MLB','Malbork','Malbork',''),('PL','MLC','Mielec','Mielec',''),('PL','MLW','Milanowek','Milanowek',''),('PL','MLZ','Milicz','Milicz',''),('PL','MMZ','Makow Mazowiecki','Makow Mazowiecki',''),('PL','MNI','Monki','Monki',''),('PL','MNZ','Mniszek','Mniszek',''),('PL','MRO','Mrokow','Mrokow',''),('PL','MRY','Marynki','Marynki',''),('PL','MSD','Mszana Dolna','Mszana Dolna',''),('PL','MSW','Mszczonow','Mszczonow',''),('PL','MSZ','Moszczenica','Moszczenica',''),('PL','MTZ','Motycz','Motycz',''),('PL','MUR','Murowana Goslina','Murowana Goslina',''),('PL','MWA','Mrowla','Mrowla',''),('PL','MWI','Morawica','Morawica',''),('PL','MYC','Myslenice','Myslenice',''),('PL','MYL','Myslowice','Myslowice',''),('PL','MYS','Myslakowice','Myslakowice',''),('PL','MYZ','Mysliborz','Mysliborz',''),('PL','MZE','Miloszyce','Miloszyce',''),('PL','MZN','Morzeszczyn','Morzeszczyn',''),('PL','MZW','Myszkow','Myszkow',''),('PL','NEK','Nekla','Nekla',''),('PL','NFW','Neufahrwasser','Neufahrwasser',''),('PL','NID','Nidzica','Nidzica',''),('PL','NIS','Nisko','Nisko',''),('PL','NLD','Nieledew','Nieledew',''),('PL','NLL','Nasielsk','Nasielsk',''),('PL','NMA','Nowe Marzy','Nowe Marzy',''),('PL','NOB','Nowogrod Bobrzanski','Nowogrod Bobrzanski',''),('PL','NOE','Nowe','Nowe',''),('PL','NOS','Nowa Sol','Nowa Sol',''),('PL','NOW','Nowy Port','Nowy Port',''),('PL','NPL','Niepolomice','Niepolomice',''),('PL','NSY','Nowe Skalmierzyce','Nowe Skalmierzyce',''),('PL','NSZ','Nowa Sarzyna','Nowa Sarzyna',''),('PL','NWA','Nowe Warpno','Nowe Warpno',''),('PL','NWS','Nowy Sacz','Nowy Sacz',''),('PL','NWY','Nowy Dwor Mazowiecki','Nowy Dwor Mazowiecki',''),('PL','NWZ','Nowogrodziec','Nowogrodziec',''),('PL','NYS','Nysa','Nysa',''),('PL','NYT','Nowy Tomysl','Nowy Tomysl',''),('PL','NZW','Naleczow','Naleczow',''),('PL','OAI','Omianki','Omianki',''),('PL','OBN','Oborniki','Oborniki',''),('PL','ODO','Odolanow','Odolanow',''),('PL','OIE','Ostrowiec','Ostrowiec',''),('PL','OKO','Okocim','Okocim',''),('PL','OKW','Ozorkow','Ozorkow',''),('PL','OLA','Olawa','Olawa',''),('PL','OLB','Osno Lubuskie','Osno Lubuskie',''),('PL','OLC','Olecko','Olecko',''),('PL','OLE','Olesnica','Olesnica',''),('PL','OLS','Olsztyn','Olsztyn',''),('PL','OMW','Otmuchow','Otmuchow',''),('PL','OPA','Opatow','Opatow',''),('PL','OPO','Opole','Opole',''),('PL','OPZ','Opoczno','Opoczno',''),('PL','ORL','Orle','Orle',''),('PL','ORN','Orneta','Orneta',''),('PL','OSJ','Ostrow Mazowiecka','Ostrow Mazowiecka',''),('PL','OSR','Ostrowiec Swietokrzyski','Ostrowiec Swietokrzyski',''),('PL','OSS','Ostroleka','Ostroleka',''),('PL','OST','Ostroda','Ostroda',''),('PL','OSW','Oswiecim','Oswiecim',''),('PL','OSZ','Koszalin','Koszalin',''),('PL','OTW','Otwock','Otwock',''),('PL','OWA','Owinska','Owinska',''),('PL','OWK','Ostrow Wielkopolski','Ostrow Wielkopolski',''),('PL','OZM','Ozarow Mazowiecki','Ozarow Mazowiecki',''),('PL','OZR','Ozarowice','Ozarowice',''),('PL','PAB','Pabjanice','Pabjanice',''),('PL','PAI','Pabianice','Pabianice',''),('PL','PAL','Pawlow','Pawlow',''),('PL','PAW','Parszow','Parszow',''),('PL','PBD','Bedzin','Bedzin',''),('PL','PBI','Poddebice','Poddebice',''),('PL','PCI','Pszczolki','Pszczolki',''),('PL','PCZ','Pelczyce','Pelczyce',''),('PL','PIA','Piaseczno','Piaseczno',''),('PL','PIK','Piotrkow Kujawski','Piotrkow Kujawski',''),('PL','PIL','Pila','Pila',''),('PL','PIM','Piatek Maly','Piatek Maly',''),('PL','PIN','Piwniczna','Piwniczna',''),('PL','PIO','Piotrkow','Piotrkow',''),('PL','PIS','Piekary Slaskie','Piekary Slaskie',''),('PL','PIT','Piotrkow Trybunalski','Piotrkow Trybunalski',''),('PL','PIW','Pisarzowice','Pisarzowice',''),('PL','PIZ','Pisz','Pisz',''),('PL','PKI','Pionki','Pionki',''),('PL','PKJ','Pokoj','Pokoj',''),('PL','PKW','Proszkow','Proszkow',''),('PL','PLC','Police','Police',''),('PL','PLI','Pilica','Pilica',''),('PL','PLK','Plonsk','Plonsk',''),('PL','PLO','Plock','Plock',''),('PL','PNY','Pniewy','Pniewy',''),('PL','POC','PoBaniec','PoBaniec',''),('PL','POR','Poraj','Poraj',''),('PL','POZ','Poznan','Poznan',''),('PL','PRA','Prabuty','Prabuty',''),('PL','PRC','Parczew','Parczew',''),('PL','PRU','Prudnik','Prudnik',''),('PL','PRZ','Przemysl','Przemysl',''),('PL','PSO','Pustkow','Pustkow',''),('PL','PSS','Piastow','Piastow',''),('PL','PSY','Przasnysz','Przasnysz',''),('PL','PSZ','Pszczyna','Pszczyna',''),('PL','PUC','Puck','Puck',''),('PL','PWI','Pawlowice','Pawlowice',''),('PL','PWK','Przeworsk','Przeworsk',''),('PL','PWO','Przechlewo','Przechlewo',''),('PL','PYS','Pyskowice','Pyskowice',''),('PL','PZA','Praszka','Praszka',''),('PL','PZG','Pruszcz Gdanski','Pruszcz Gdanski',''),('PL','PZI','Plizin','Plizin',''),('PL','PZJ','Polczyn-Zdroj','Polczyn-Zdroj',''),('PL','PZK','Pruszkow','Pruszkow',''),('PL','PZO','Pilzno','Pilzno',''),('PL','PZW','Pleszew','Pleszew',''),('PL','PZY','Przysucha','Przysucha',''),('PL','QAZ','Zakopane','Zakopane',''),('PL','QEP','Tarnobrzeg','Tarnobrzeg',''),('PL','QKD','Elk','Elk',''),('PL','QLC','Gliwice','Gliwice',''),('PL','QOY','Lomza','Lomza',''),('PL','QXQ','Stalowa Wola','Stalowa Wola',''),('PL','RAD','Radomsko','Radomsko',''),('PL','RAP','Radzyn Podlaski','Radzyn Podlaski',''),('PL','RAW','Rawicz','Rawicz',''),('PL','RCZ','Raciborz','Raciborz',''),('PL','RDM','Radom','Radom',''),('PL','RDN','Rudniki','Rudniki',''),('PL','RDS','Ruda Slaska','Ruda Slaska',''),('PL','RDZ','Radzionkow','Radzionkow',''),('PL','RES','Resko','Resko',''),('PL','RGZ','Rudna gwizdanow','Rudna gwizdanow',''),('PL','RMA','Rawa Mazowiecka','Rawa Mazowiecka',''),('PL','RNW','Rakoniewice','Rakoniewice',''),('PL','ROG','Rogozno','Rogozno',''),('PL','ROP','Ropczyce','Ropczyce',''),('PL','RUI','Rumia','Rumia',''),('PL','RUS','Rusiec','Rusiec',''),('PL','RYB','Rybnik','Rybnik',''),('PL','RYD','Rydzyna','Rydzyna',''),('PL','RYK','Ryki','Ryki',''),('PL','RYZ','Raszyn/Warszawa','Raszyn/Warszawa',''),('PL','RZE','Rzeszow','Rzeszow',''),('PL','RZP','Rzepin','Rzepin',''),('PL','RZW','Rzgow','Rzgow',''),('PL','RZY','Pyrzyce','Pyrzyce',''),('PL','SCE','Swiecie','Swiecie',''),('PL','SCN','Sulecin, Gorzow','Sulecin, Gorzow',''),('PL','SCW','Sycow','Sycow',''),('PL','SDC','Siedlce','Siedlce',''),('PL','SDK','Swidnik','Swidnik',''),('PL','SED','Sedziszow Malopolski','Sedziszow Malopolski',''),('PL','SEK','Sepolno Krajenskie','Sepolno Krajenskie',''),('PL','SEO','Sekocin Nowy','Sekocin Nowy',''),('PL','SGM','Strzegom','Strzegom',''),('PL','SIC','Siechnice','Siechnice',''),('PL','SIR','Sieradz','Sieradz',''),('PL','SIW','Sianow','Sianow',''),('PL','SIZ','Siewierz','Siewierz',''),('PL','SKA','Skawina','Skawina',''),('PL','SKE','Skepe','Skepe',''),('PL','SKI','Skierniewice','Skierniewice',''),('PL','SKK','Skarzysko-Kamienna','Skarzysko-Kamienna',''),('PL','SKL','Szklarska Poreba','Szklarska Poreba',''),('PL','SKP','Skopanie','Skopanie',''),('PL','SKW','Skwierzyna','Skwierzyna',''),('PL','SKZ','Skalmierzyce','Skalmierzyce',''),('PL','SLA','S?awno','S?awno',''),('PL','SLC','Slupca','Slupca',''),('PL','SLE','Slubice, Mazowieckie','Slubice, Mazowieckie',''),('PL','SLP','Slupsk','Slupsk',''),('PL','SLU','Slubice, Lubuskie','Slubice, Lubuskie',''),('PL','SLW','Stanislawice','Stanislawice',''),('PL','SMA','Sandomierz','Sandomierz',''),('PL','SMN','Strumien','Strumien',''),('PL','SNK','Sanok','Sanok',''),('PL','SOC','Sochaczew','Sochaczew',''),('PL','SOI','Solec Kujawski','Solec Kujawski',''),('PL','SOK','Sokolka','Sokolka',''),('PL','SON','Sonsk','Sonsk',''),('PL','SOP','Sopot','Sopot',''),('PL','SOW','Siemianowice','Siemianowice',''),('PL','SPA','Stepnica','Stepnica',''),('PL','SPC','Sierpc','Sierpc',''),('PL','SPO','Sokolow Podlaski','Sokolow Podlaski',''),('PL','SPW','Staporkow','Staporkow',''),('PL','SPY','Spiczyn','Spiczyn',''),('PL','SRA','Szprotawa','Szprotawa',''),('PL','SRE','Srem','Srem',''),('PL','SRW','Sroda','Sroda',''),('PL','SSK','Stronie Zlskie','Stronie Zlskie',''),('PL','SSZ','Staszow','Staszow',''),('PL','STB','Stare Babice','Stare Babice',''),('PL','STC','Stupiec','Stupiec',''),('PL','STD','Starogard','Starogard',''),('PL','STE','Starachowice','Starachowice',''),('PL','STG','Starogard Gdanski','Starogard Gdanski',''),('PL','STJ','Stare Je?ewo','Stare Je?ewo',''),('PL','STM','Stare Miasto','Stare Miasto',''),('PL','STN','Straszyn','Straszyn',''),('PL','STP','Stare Pole','Stare Pole',''),('PL','STR','Strykow','Strykow',''),('PL','STS','Stargard Szczecinski','Stargard Szczecinski',''),('PL','STU','Stroze','Stroze',''),('PL','STW','Steszew','Steszew',''),('PL','STZ','Strzelin','Strzelin',''),('PL','SUC','Suchy Las','Suchy Las',''),('PL','SUP','Slupy','Slupy',''),('PL','SWA','Swadzim','Swadzim',''),('PL','SWB','Swiebodzin','Swiebodzin',''),('PL','SWC','Sosnowiec','Sosnowiec',''),('PL','SWD','Swidwin','Swidwin',''),('PL','SWE','Swiebodzice','Swiebodzice',''),('PL','SWI','Swinoujscie','Swinoujscie',''),('PL','SWL','Suwalki','Suwalki',''),('PL','SWN','Swidnica','Swidnica',''),('PL','SWO','Sulaszewo','Sulaszewo',''),('PL','SWT','Swietochlowice','Swietochlowice',''),('PL','SWZ','Stawiszyn','Stawiszyn',''),('PL','SYZ','Stryszawa','Stryszawa',''),('PL','SZA','Szczytna','Szczytna',''),('PL','SZB','Strzebielino','Strzebielino',''),('PL','SZC','Szczecinek','Szczecinek',''),('PL','SZE','Siemiatycze','Siemiatycze',''),('PL','SZN','Swarozyn','Swarozyn',''),('PL','SZO','Solec-Zdroj','Solec-Zdroj',''),('PL','SZU','Szubin','Szubin',''),('PL','SZW','Skrzyszow','Skrzyszow',''),('PL','SZY','Szymany','Szymany',''),('PL','SZZ','Szczecin','Szczecin',''),('PL','TAN','Tarnowiec','Tarnowiec',''),('PL','TAR','Tarnow','Tarnow',''),('PL','TBZ','Trzebiez','Trzebiez',''),('PL','TDZ','Tubadzin','Tubadzin',''),('PL','TEN','Tenczynek','Tenczynek',''),('PL','TER','Terespol','Terespol',''),('PL','TES','Teresin ','Teresin ',''),('PL','TGO','Tarnowskie Gory','Tarnowskie Gory',''),('PL','TMO','Tolkmicko','Tolkmicko',''),('PL','TMW','Tomaszow Mazowiecki','Tomaszow Mazowiecki',''),('PL','TOL','Tomaszow Lubelski','Tomaszow Lubelski',''),('PL','TOM','Torzym','Torzym',''),('PL','TOR','Torun','Torun',''),('PL','TPO','Tarnowo Podgorne','Tarnowo Podgorne',''),('PL','TRA','Trawniki','Trawniki',''),('PL','TRK','Turek','Turek',''),('PL','TRW','Tarnowa','Tarnowa',''),('PL','TRZ','Trzebownisko','Trzebownisko',''),('PL','TUC','Tuchola','Tuchola',''),('PL','TWA','Twardogora','Twardogora',''),('PL','TWN','Tuszow Narodowy','Tuszow Narodowy',''),('PL','TYK','Tykocin','Tykocin',''),('PL','TYY','Tychy','Tychy',''),('PL','TZA','Trzcianka','Trzcianka',''),('PL','TZN','Tyczyn','Tyczyn',''),('PL','TZW','Tczew','Tczew',''),('PL','TZY','Tuszyn','Tuszyn',''),('PL','UJA','Ujazd','Ujazd',''),('PL','ULK','Ulkowy','Ulkowy',''),('PL','UMS','Ustronie Morskie','Ustronie Morskie',''),('PL','UNS','Unislaw Slaski','Unislaw Slaski',''),('PL','URD','Urad','Urad',''),('PL','URZ','Urzedow','Urzedow',''),('PL','USD','Ustrzyki Dolne','Ustrzyki Dolne',''),('PL','USR','Ustron','Ustron',''),('PL','UST','Ustka','Ustka',''),('PL','WAD','Wadowice','Wadowice',''),('PL','WAW','Warszawa','Warszawa',''),('PL','WAZ','Walcz','Walcz',''),('PL','WBM','Wolbrom','Wolbrom',''),('PL','WBW','Wroblew','Wroblew',''),('PL','WBZ','Wabrzezno','Wabrzezno',''),('PL','WCW','Wielichowo','Wielichowo',''),('PL','WDW','Wadowice','Wadowice',''),('PL','WEJ','Wejherowo','Wejherowo',''),('PL','WIA','Wisznia Mala','Wisznia Mala',''),('PL','WIE','Wierzchoslawice','Wierzchoslawice',''),('PL','WIS','Wisla','Wisla',''),('PL','WKA','Warka','Warka',''),('PL','WLA','Wladyslawowo','Wladyslawowo',''),('PL','WLB','Warlubie','Warlubie',''),('PL','WLI','Wolin','Wolin',''),('PL','WLM','Wolomin','Wolomin',''),('PL','WLN','Wielun','Wielun',''),('PL','WLO','Wloclawek','Wloclawek',''),('PL','WLS','Wloszczowa','Wloszczowa',''),('PL','WMA','Wysokie Mazowieckie','Wysokie Mazowieckie',''),('PL','WOI','Wolow','Wolow',''),('PL','WOL','Wolborz','Wolborz',''),('PL','WPZ','Wielopole Skrzynskie','Wielopole Skrzynskie',''),('PL','WRN','Wronki','Wronki',''),('PL','WRO','Wroclaw','Wroclaw',''),('PL','WSC','Wschowa','Wschowa',''),('PL','WWE','Wilkowice','Wilkowice',''),('PL','WYG','Wygledi','Wygledi',''),('PL','WYM','Wysokie Mazowieckie','Wysokie Mazowieckie',''),('PL','WYZ','Wyszkow','Wyszkow',''),('PL','WZA','Wrzesnia','Wrzesnia',''),('PL','WZH','Walbrzych','Walbrzych',''),('PL','WZN','Wiazowna','Wiazowna',''),('PL','WZO','Wegorzyno','Wegorzyno',''),('PL','WZT','Wolsztyn','Wolsztyn',''),('PL','ZAB','Zabrze','Zabrze',''),('PL','ZAG','Zagan','Zagan',''),('PL','ZAK','Zagnansk','Zagnansk',''),('PL','ZAM','Zamosc','Zamosc',''),('PL','ZAN','Zabno','Zabno',''),('PL','ZAS','Zabkowice Slaskie','Zabkowice Slaskie',''),('PL','ZBK','Zbaszynek','Zbaszynek',''),('PL','ZBN','Zbaszyn','Zbaszyn',''),('PL','ZDU','Zdunska Wola','Zdunska Wola',''),('PL','ZDY','Zduny','Zduny',''),('PL','ZEB','Zebrzydowice','Zebrzydowice',''),('PL','ZGI','Zgierz','Zgierz',''),('PL','ZGZ','Zagorz','Zagorz',''),('PL','ZIE','Ziebice','Ziebice',''),('PL','ZIL','Zielonka','Zielonka',''),('PL','ZKW','?yrakow','?yrakow',''),('PL','ZLA','Zolynia','Zolynia',''),('PL','ZLO','Zlotow','Zlotow',''),('PL','ZNI','Znin','Znin',''),('PL','ZOY','Zory','Zory',''),('PL','ZPO','Zpowtuchola','Zpowtuchola',''),('PL','ZRY','Zary','Zary',''),('PL','ZTO','Zlotoryja','Zlotoryja',''),('PL','ZTY','Olsztynek','Olsztynek',''),('PL','ZUK','Zukowo','Zukowo',''),('PL','ZWR','Zawiercie','Zawiercie',''),('PL','ZWZ','Zawadzkie','Zawadzkie',''),('PL','ZYN','Zychlin','Zychlin',''),('PL','ZYR','Zyrardow','Zyrardow',''),('PL','ZYW','Zywiec','Zywiec',''),('PL','ZZI','Zaczernie','Zaczernie',''),('PL','ZZY','Zdzary','Zdzary',''),('PM','','','',''),('PM','FSP','St Pierre','St Pierre',''),('PM','MQC','Miquelon','Miquelon',''),('PN','','','',''),('PN','PCN','Pitcairn Is','Pitcairn Is',''),('PR','','','',''),('PR','ADJ','Adjuntas','Adjuntas',''),('PR','AGU','Aguada','Aguada',''),('PR','AIB','Aibonito','Aibonito',''),('PR','ANA','Anasco','Anasco',''),('PR','ARE','Arecibo','Arecibo',''),('PR','ARR','Arroyo/Guayama','Arroyo/Guayama',''),('PR','BAR','Barceloneta','Barceloneta',''),('PR','BAS','Barranquitas','Barranquitas',''),('PR','BAY','Bayamon','Bayamon',''),('PR','BQN','Aguadilla','Aguadilla',''),('PR','CAG','Caguas','Caguas',''),('PR','CAH','Caparra Hills','Caparra Hills',''),('PR','CAM','Camuy','Camuy',''),('PR','CAN','Canovanas','Canovanas',''),('PR','CAR','Carolina','Carolina',''),('PR','CAT','Catano','Catano',''),('PR','CAY','Cayey','Cayey',''),('PR','CBJ','Cabo Rojo','Cabo Rojo',''),('PR','CIA','Cidra','Cidra',''),('PR','CID','Cidra','Cidra',''),('PR','CLE','Ciales','Ciales',''),('PR','COA','Coamo','Coamo',''),('PR','COE','Comerio','Comerio',''),('PR','COM','Comerio','Comerio',''),('PR','CPX','Culebra','Culebra',''),('PR','CUP','Cupey, San Juan','Cupey, San Juan',''),('PR','DDP','Dorado','Dorado',''),('PR','FAJ','Fajardo','Fajardo',''),('PR','GMA','Guayama','Guayama',''),('PR','GUA','Guabano','Guabano',''),('PR','GUO','Guaynabo','Guaynabo',''),('PR','GUR','Gurabo','Gurabo',''),('PR','GUX','Guanica','Guanica',''),('PR','GUY','Guayanilla','Guayanilla',''),('PR','HDE','Hato Tejas','Hato Tejas',''),('PR','HRE','Hato Rey','Hato Rey',''),('PR','HTL','Hatillo','Hatillo',''),('PR','HUC','Humacao','Humacao',''),('PR','ISB','Isabela','Isabela',''),('PR','JAY','Jayuya','Jayuya',''),('PR','JDI','Juana Diaz','Juana Diaz',''),('PR','JIC','Jicome','Jicome',''),('PR','JUN','Juncos','Juncos',''),('PR','LAM','Las Mareas (Guayama)','Las Mareas (Guayama)',''),('PR','LJS','Lajas','Lajas',''),('PR','LPS','Las Piedras','Las Piedras',''),('PR','LUQ','Luquillo','Luquillo',''),('PR','MAN','Manati','Manati',''),('PR','MAR','Maricao','Maricao',''),('PR','MAZ','Mayaguez','Mayaguez',''),('PR','MIR','Miramar','Miramar',''),('PR','MOC','Moca','Moca',''),('PR','NAG','Naguabo','Naguabo',''),('PR','NRR','Roosevelt Roads','Roosevelt Roads',''),('PR','NXL','Noxell','Noxell',''),('PR','PEN','Penuelas','Penuelas',''),('PR','PJO','Puerto de Jobos','Puerto de Jobos',''),('PR','PNU','Puerto Nuevo','Puerto Nuevo',''),('PR','PSE','Ponce','Ponce',''),('PR','PTL','Patillas','Patillas',''),('PR','PYA','Puerto Yabucoa','Puerto Yabucoa',''),('PR','RGD','Rio Grande','Rio Grande',''),('PR','RIN','Rincon','Rincon',''),('PR','RPS','Rio Piedras','Rio Piedras',''),('PR','SGM','San German','San German',''),('PR','SGR','Sabana Grande','Sabana Grande',''),('PR','SIS','Santa Isabel','Santa Isabel',''),('PR','SJU','San Juan','San Juan',''),('PR','TBJ','Toa Baja','Toa Baja',''),('PR','TOT','Tottillas','Tottillas',''),('PR','TRU','Trujillo Bajo, Carolina','Trujillo Bajo, Carolina',''),('PR','UTU','Utuado','Utuado',''),('PR','VAL','Vega Alta','Vega Alta',''),('PR','VBA','Vega Baja','Vega Baja',''),('PR','VQS','Vieques','Vieques',''),('PR','YAB','Yabucoa','Yabucoa',''),('PR','YAU','Yauco','Yauco',''),('PT','','','',''),('PT','ABA','Azambujeira','Azambujeira','14'),('PT','ABF','Albufeira','Albufeira','08'),('PT','ABO','Aboboda','Aboboda','11'),('PT','ABR','Abrunheira','Abrunheira','06'),('PT','ABT','Abrantes','Abrantes','14'),('PT','ABV','Albergaria-a-Velha','Albergaria-a-Velha','01'),('PT','ACB','Alcabideche','Alcabideche','11'),('PT','ACD','Alcanede','Alcanede','14'),('PT','ACR','Alcoentre','Alcoentre','11'),('PT','ACT','Alcoutim','Alcoutim','08'),('PT','ACZ','Arcozelo','Arcozelo','18'),('PT','ADC','Aveiras de Cima','Aveiras de Cima','11'),('PT','ADH','Angra do Heroismo','Angra do Heroismo','20'),('PT','ADS','Alcacer do Sal','Alcacer do Sal','15'),('PT','ADV','Almodovar','Almodovar','02'),('PT','AER','Alem da Ribeira','Alem da Ribeira','16'),('PT','AES','Aves','Aves','13'),('PT','AFA','Alfena','Alfena','13'),('PT','AFE','Alfandega da Fe','Alfandega da Fe','04'),('PT','AGB','Aguiar da Beira','Aguiar da Beira','09'),('PT','AGE','Agrela','Agrela','03'),('PT','AGL','Argoncilhe','Argoncilhe','01'),('PT','AGM','Aguas de Moura','Aguas de Moura','15'),('PT','AGN','Arganil','Arganil','06'),('PT','AGS','Alges','Alges','11'),('PT','AGU','Agueda','Agueda','01'),('PT','AGZ','Argozelo','Argozelo','04'),('PT','AIO','Aiao','Aiao','13'),('PT','AJT','Aljustrel','Aljustrel','02'),('PT','AJZ','Aljezur','Aljezur','08'),('PT','ALB','Albergaria','Albergaria','10'),('PT','ALC','Alcanena','Alcanena','14'),('PT','ALD','Almeida','Almeida','09'),('PT','ALE','Alcochete','Alcochete','15'),('PT','ALJ','Alijo','Alijo','17'),('PT','ALM','Almada','Almada','15'),('PT','ALN','Alenquer','Alenquer','11'),('PT','ALO','Alcobaca','Alcobaca','10'),('PT','ALR','Almeirim','Almeirim','14'),('PT','ALS','Alcains','Alcains','05'),('PT','ALT','Alter do Chao','Alter do Chao','12'),('PT','ALV','Alverca','Alverca','11'),('PT','AMA','Amadora','Amadora','11'),('PT','AMC','Amiaes de Cima','Amiaes de Cima','14'),('PT','AMG','Almagreira','Almagreira','10'),('PT','AMI','Amorim','Amorim','13'),('PT','AMJ','Amareleja','Amareleja','02'),('PT','AML','Almancil','Almancil','08'),('PT','AMO','Amora','Amora','15'),('PT','AMP','Almargem','Almargem','11'),('PT','AMR','Amares','Amares','03'),('PT','AMT','Amarante','Amarante','13'),('PT','ANA','Anadia','Anadia','01'),('PT','ANS','Ansiao','Ansiao','10'),('PT','AOD','Alandroal','Alandroal','07'),('PT','APC','Alpiarca','Alpiarca','14'),('PT','ARA','Areosa','Areosa','16'),('PT','ARC','Arouca','Arouca','01'),('PT','ARD','Ardido','Ardido','10'),('PT','ARE','Alferrarede','Alferrarede','14'),('PT','ARF','Arrifana','Arrifana','06'),('PT','ARG','Arreigada','Arreigada','13'),('PT','ARL','Arraiolos','Arraiolos','07'),('PT','ARM','Armamar','Armamar','18'),('PT','ARP','Armacao de Pera','Armacao de Pera','08'),('PT','ARR','Arronches','Arronches','12'),('PT','ARV','Arruda dos Vinhos','Arruda dos Vinhos','11'),('PT','ARZ','Ariz','Ariz','13'),('PT','ASD','Adaes','Adaes','03'),('PT','ATB','Atouguia da Baleia','Atouguia da Baleia','10'),('PT','AVC','Avanca','Avanca','01'),('PT','AVD','Aveleda','Aveleda','13'),('PT','AVE','Aveiro','Aveiro','01'),('PT','AVI','Avintes','Avintes','13'),('PT','AVL','Alvarelhos','Alvarelhos','13'),('PT','AVM','Abade de Vermoim','Abade de Vermoim','03'),('PT','AVS','Avis','Avis','12'),('PT','AVT','Alvito','Alvito','02'),('PT','AVV','Arcos de Valdevez','Arcos de Valdevez','16'),('PT','AVZ','Alvaiazere','Alvaiazere','10'),('PT','AZA','Azambuja','Azambuja','11'),('PT','AZJ','Azaruja','Azaruja','07'),('PT','AZT','Azeitao','Azeitao','15'),('PT','BAA','Baiao','Baiao','13'),('PT','BAN','Banatica','Banatica','15'),('PT','BAR','Barcelos','Barcelos','03'),('PT','BAT','Batalha','Batalha','10'),('PT','BBA','Borba','Borba','07'),('PT','BBL','Bobadela','Bobadela','11'),('PT','BBN','Baixa da Banheira','Baixa da Banheira','15'),('PT','BCA','Branca','Branca','01'),('PT','BEA','Barcarena','Barcarena','11'),('PT','BEJ','Beja','Beja','02'),('PT','BGC','Braganca','Braganca','04'),('PT','BGZ','Braga','Braga','03'),('PT','BHC','Banho e Carvalhosa','Banho e Carvalhosa','13'),('PT','BLS','Belas','Belas','11'),('PT','BLZ','Balazar','Balazar','13'),('PT','BML','Belem','Belem','08'),('PT','BMT','Belmonte','Belmonte','05'),('PT','BNT','Benedita','Benedita','10'),('PT','BNV','Benavente','Benavente','14'),('PT','BOM','Bombarral','Bombarral','10'),('PT','BRO','Barreiro','Barreiro','15'),('PT','BRR','Barrancos','Barrancos','02'),('PT','BRS','Barroselas','Barroselas','16'),('PT','BTS','Boticas','Boticas','17'),('PT','CAA','Cacia','Cacia','01'),('PT','CAB','Cabeco de Vide','Cabeco de Vide','12'),('PT','CAC','Cacem','Cacem','11'),('PT','CAL','Calheta, I. Sao Jorge','Calheta, I. Sao Jorge','20'),('PT','CAM','Caminha','Caminha','16'),('PT','CAN','Condeixa a Nova','Condeixa a Nova','06'),('PT','CAR','Carvalhos','Carvalhos','03'),('PT','CAS','Cascais','Cascais','11'),('PT','CAX','Caxias','Caxias','11'),('PT','CBL','Cabrela','Cabrela','07'),('PT','CBN','Casal dos Bernardos','Casal dos Bernardos','14'),('PT','CBP','Coimbra','Coimbra','06'),('PT','CBR','Castelo Branco','Castelo Branco','05'),('PT','CBS','Cabeceiras de Basto','Cabeceiras de Basto','03'),('PT','CBT','Celorico de Basto','Celorico de Basto','03'),('PT','CDC','Coimbra CDP','Coimbra CDP','06'),('PT','CDL','Lisboa CDP','Lisboa CDP','11'),('PT','CDM','Cedovim','Cedovim','09'),('PT','CDO','Porto CDP','Porto CDP','13'),('PT','CDP','Cais do Pico','Cais do Pico','20'),('PT','CDR','Caldas da Rainha','Caldas da Rainha','10'),('PT','CDV','Cadaval','Cadaval','11'),('PT','CEO','Canedo','Canedo','01'),('PT','CHM','Chamusca','Chamusca','14'),('PT','CHV','Chaves','Chaves','17'),('PT','CLB','Celorico da Beira','Celorico da Beira','09'),('PT','CLH','Calheta, I. Madeira','Calheta, I. Madeira','30'),('PT','CLJ','Cercal do Alentejo','Cercal do Alentejo','15'),('PT','CLR','Colares','Colares','11'),('PT','CMH','Camacha','Camacha','30'),('PT','CML','Camara de Lobos','Camara de Lobos','30'),('PT','CMM','Castro Marim','Castro Marim','08'),('PT','CMO','Campelos','Campelos','11'),('PT','CMR','Campo Maior','Campo Maior','12'),('PT','CMT','Camarate','Camarate','11'),('PT','CNA','Coina','Coina','15'),('PT','CNC','Canecas','Canecas','11'),('PT','CNF','Cinfaes','Cinfaes','18'),('PT','CNI','Canas de Senhorim','Canas de Senhorim','18'),('PT','CNL','Canical','Canical','30'),('PT','CNO','Canico','Canico','30'),('PT','CNS','Canelas','Canelas','13'),('PT','CNX','Carnaxide','Carnaxide','11'),('PT','COI','Coimbrao','Coimbrao','10'),('PT','COJ','Coja','Coja','06'),('PT','CON','Constancia','Constancia','14'),('PT','COV','Covilha','Covilha','05'),('PT','CPB','Campo de Besteiros','Campo de Besteiros','18'),('PT','CPC','Caparica','Caparica','15'),('PT','CPL','Capelo','Capelo','20'),('PT','CPR','Castanheira de Pera','Castanheira de Pera','10'),('PT','CPV','Castelo de Paiva','Castelo de Paiva','01'),('PT','CRA','Carregal do Sal','Carregal do Sal','18'),('PT','CRE','Coruche','Coruche','14'),('PT','CRG','Carrazedo de Montenegro','Carrazedo de Montenegro','17'),('PT','CRI','Castanheira do Ribatejo','Castanheira do Ribatejo','11'),('PT','CRO','Caramulo','Caramulo','18'),('PT','CRR','Carregado','Carregado','11'),('PT','CRS','Corroios','Corroios','15'),('PT','CRT','Crato','Crato','12'),('PT','CSR','Cesar','Cesar','01'),('PT','CST','Crestuma','Crestuma','13'),('PT','CTD','Castro Daire','Castro Daire','18'),('PT','CTH','Cantanhede','Cantanhede','06'),('PT','CUB','Cuba','Cuba','02'),('PT','CUC','Cucujaes','Cucujaes','01'),('PT','CVD','Castelo de Vide','Castelo de Vide','12'),('PT','CVL','Unhais da Serra','Unhais da Serra','05'),('PT','CVO','Covelo','Covelo','06'),('PT','CVP','Cova da Piedade','Cova da Piedade','15'),('PT','CVR','Castro Verde','Castro Verde','02'),('PT','CVU','Corvo Island Apt','Corvo Island Apt','20'),('PT','CVZ','Caldas de Vizela','Caldas de Vizela','03'),('PT','CXO','Cartaxo','Cartaxo','14'),('PT','CXP','Charneca da Caparica','Charneca da Caparica','15'),('PT','CZZ','Carrazeda de Anciaes','Carrazeda de Anciaes','04'),('PT','DTO','Santo Antao do Tojal','Santo Antao do Tojal','11'),('PT','ECL','Estreito de Camara de Lobos','Estreito de Camara de Lobos','30'),('PT','ELV','Elvas','Elvas','12'),('PT','EMZ','Esmoriz','Esmoriz','01'),('PT','ENT','Entroncamento','Entroncamento','14'),('PT','EOR','Entre-os-Rios','Entre-os-Rios','13'),('PT','EPS','Esposende','Esposende','03'),('PT','ERC','Ericeira','Ericeira','11'),('PT','ERM','Ermezinde','Ermezinde','13'),('PT','ERS','Ermidas','Ermidas','15'),('PT','ESC','Escandarao','Escandarao','14'),('PT','ESP','Espinho','Espinho','18'),('PT','EST','Estoril','Estoril','11'),('PT','ESZ','Estremoz','Estremoz','07'),('PT','ETR','Estarreja','Estarreja','01'),('PT','EVR','Evora','Evora','07'),('PT','EXP','Lisboa-EXPO','Lisboa-EXPO','11'),('PT','FAG','Fornos de Algodres','Fornos de Algodres','09'),('PT','FAJ','Fajozes','Fajozes','13'),('PT','FAL','Ferreira do Alentejo','Ferreira do Alentejo','02'),('PT','FAM','Famalicao','Famalicao','09'),('PT','FAO','Faro','Faro','08'),('PT','FCR','Figueira de Castelo Rodrigo','Figueira de Castelo Rodrigo','09'),('PT','FDF','Figueira da Foz','Figueira da Foz','06'),('PT','FEC','Freixo de Espada a Cinta','Freixo de Espada a Cinta','04'),('PT','FEL','Felgueiras','Felgueiras','13'),('PT','FFE','Fafe','Fafe','03'),('PT','FGV','Figueiro dos Vinhos','Figueiro dos Vinhos','10'),('PT','FIA','Fiaes','Fiaes','01'),('PT','FIL','Faial','Faial','30'),('PT','FLW','Flores Island Apt','Flores Island Apt','20'),('PT','FNC','Funchal, Madeira','Funchal, Madeira','30'),('PT','FNF','Fernao Ferro','Fernao Ferro','15'),('PT','FNZ','Fanzeres','Fanzeres','13'),('PT','FRL','Frielas','Frielas','11'),('PT','FRS','Furnas','Furnas','20'),('PT','FTM','Fatima','Fatima','14'),('PT','FTR','Fronteira','Fronteira','12'),('PT','FUA','Fundao','Fundao','05'),('PT','FXO','Freixieiro','Freixieiro','13'),('PT','FZZ','Ferreira do Zezere','Ferreira do Zezere','14'),('PT','GAV','Gaviao','Gaviao','12'),('PT','GCS','Graciosa','Graciosa','01'),('PT','GDA','Guarda','Guarda','09'),('PT','GDL','Grandola','Grandola','15'),('PT','GDN','Gafanha da Nazare','Gafanha da Nazare','01'),('PT','GIA','Guia','Guia','08'),('PT','GIF','Guifoes','Guifoes','13'),('PT','GIN','Ginetes','Ginetes','20'),('PT','GLG','Golega','Golega','14'),('PT','GOI','Gois','Gois','06'),('PT','GON','Gondomar','Gondomar','03'),('PT','GRI','Grijo','Grijo','13'),('PT','GRS','Geres','Geres','03'),('PT','GRW','Graciosa Island Apt','Graciosa Island Apt','20'),('PT','GUI','Guimaraes','Guimaraes','03'),('PT','GVI','Gouveia','Gouveia','09'),('PT','HOR','Horta','Horta','20'),('PT','IDN','Idanha-a-Nova','Idanha-a-Nova','05'),('PT','ILH','Ilhavo','Ilhavo','01'),('PT','LAJ','Lajes das Flores','Lajes das Flores','20'),('PT','LAV','Linda-a-Velha','Linda-a-Velha','11'),('PT','LDB','Leca do Bailio','Leca do Bailio','13'),('PT','LDP','Lajes','Lajes','20'),('PT','LDR','Lordelo','Lordelo','03'),('PT','LEA','Leiria','Leiria','10'),('PT','LEI','Leixoes','Leixoes','13'),('PT','LEP','Leca da Palmeira','Leca da Palmeira','13'),('PT','LER','Leiros','Leiros','17'),('PT','LGA','Lagoa, Algarve','Lagoa, Algarve','08'),('PT','LGP','Lagoa, I. Sao Miguel','Lagoa, I. Sao Miguel','20'),('PT','LIS','Lisboa','Lisboa','11'),('PT','LMG','Lamego','Lamego','18'),('PT','LNH','Lourinha','Lourinha','11'),('PT','LOA','Lousada','Lousada','13'),('PT','LOS','Lagos','Lagos','08'),('PT','LOU','Lourosa','Lourosa','01'),('PT','LRC','Lourical','Lourical','10'),('PT','LRS','Loures','Loures','11'),('PT','LSA','Lousa','Lousa','06'),('PT','LSI','Linho','Linho','11'),('PT','LSO','Luso','Luso','01'),('PT','LUL','Loule','Loule','08'),('PT','LVR','Lavra','Lavra','13'),('PT','LXA','Lixa','Lixa','13'),('PT','MAD','Madalena','Madalena','20'),('PT','MAI','Maia','Maia','13'),('PT','MAL','Maceira Lis','Maceira Lis','10'),('PT','MAS','Maia, I. Sao Miguel','Maia, I. Sao Miguel','20'),('PT','MAT','Matosinhos','Matosinhos','13'),('PT','MBR','Moimenta da Beira','Moimenta da Beira','18'),('PT','MCD','Macedo de Cavaleiros','Macedo de Cavaleiros','04'),('PT','MCH','Machico','Machico','30'),('PT','MCQ','Monchique','Monchique','08'),('PT','MCV','Miranda do Corvo','Miranda do Corvo','06'),('PT','MDA','Meda','Meda','09'),('PT','MDB','Mondim de Basto','Mondim de Basto','17'),('PT','MDL','Mirandela','Mirandela','04'),('PT','MDR','Miranda do Douro','Miranda do Douro','04'),('PT','MEM','Memoria','Memoria','11'),('PT','MFR','Mafra','Mafra','11'),('PT','MFT','Monforte','Monforte','12'),('PT','MGD','Mogadouro','Mogadouro','04'),('PT','MGL','Mangualde','Mangualde','18'),('PT','MGR','Marinha Grande','Marinha Grande','10'),('PT','MHU','Malhou','Malhou','14'),('PT','MIE','Mira d\'Aire','Mira d\'Aire','10'),('PT','MIN','Minde','Minde','14'),('PT','MIR','Mira','Mira','06'),('PT','MLD','Mealhada','Mealhada','01'),('PT','MLG','Melgaco','Melgaco','16'),('PT','MLV','Malveira','Malveira','11'),('PT','MMA','Mem Martins','Mem Martins','11'),('PT','MMN','Montemor-o-Novo','Montemor-o-Novo','07'),('PT','MMV','Montemor-o-Velho','Montemor-o-Velho','06'),('PT','MNG','Manteigas','Manteigas','09'),('PT','MNO','Moncao','Moncao','16'),('PT','MOA','Mora','Mora','07'),('PT','MOC','Moura','Moura','06'),('PT','MON','Montijo','Montijo','15'),('PT','MOR','Mortena','Mortena','11'),('PT','MOU','Mourao','Mourao','07'),('PT','MPQ','Panasqueira','Panasqueira','05'),('PT','MRA','Moura','Moura','02'),('PT','MRC','Marco de Canavezes','Marco de Canavezes','13'),('PT','MRE','Monte Real','Monte Real','10'),('PT','MRL','Loures-MARL','Loures-MARL','11'),('PT','MRN','Marinhais','Marinhais','14'),('PT','MRT','Mortagua','Mortagua','18'),('PT','MRV','Marvao','Marvao','12'),('PT','MSA','Murtosa','Murtosa','01'),('PT','MSF','Mesao Frio','Mesao Frio','17'),('PT','MSV','Moscavide','Moscavide','11'),('PT','MTA','Moita','Moita','15'),('PT','MTC','Monte da Caparica','Monte da Caparica','15'),('PT','MTE','Murtede','Murtede','06'),('PT','MTG','Montargil','Montargil','12'),('PT','MTL','Mertola','Mertola','02'),('PT','MTR','Montalegre','Montalegre','17'),('PT','MTV','Montalvao','Montalvao','12'),('PT','MUR','Murca','Murca','17'),('PT','MZL','Mozelos','Mozelos','16'),('PT','NDC','Nogueira do Cravo','Nogueira do Cravo','06'),('PT','NEL','Nelas','Nelas','18'),('PT','NIS','Nisa','Nisa','12'),('PT','NNE','Nine','Nine','03'),('PT','NRD','Nordeste','Nordeste','20'),('PT','NZR','Nazare','Nazare','10'),('PT','OBD','Obidos','Obidos','10'),('PT','ODA','Oliveira de Azemeis','Oliveira de Azemeis','01'),('PT','ODE','Odemira','Odemira','02'),('PT','ODI','Odivelas','Odivelas','11'),('PT','OEI','Oeiras','Oeiras','11'),('PT','OFR','Oliveira de Frades','Oliveira de Frades','18'),('PT','OHP','Oliveira do Hospital','Oliveira do Hospital','06'),('PT','OLB','Olival do Basto','Olival do Basto','11'),('PT','OLH','Olhao','Olhao','08'),('PT','OLI','Oliveira do Bairro','Oliveira do Bairro','01'),('PT','OLR','Oleiros','Oleiros','05'),('PT','OPO','Porto','Porto','13'),('PT','ORQ','Ourique','Ourique','02'),('PT','ORV','Orvalho','Orvalho','05'),('PT','OUR','Ourem','Ourem','14'),('PT','OUT','Outeiro','Outeiro','03'),('PT','OVA','Ovar','Ovar','01'),('PT','PAL','Palmela','Palmela','15'),('PT','PCS','Paco de Arcos','Paco de Arcos','11'),('PT','PCT','Penalva do Castelo','Penalva do Castelo','18'),('PT','PCV','Penacova','Penacova','06'),('PT','PCZ','Porto da Cruz','Porto da Cruz','30'),('PT','PDL','Ponta Delgada','Ponta Delgada','20'),('PT','PDM','Porto de Mos','Porto de Mos','10'),('PT','PDR','Ponte do Rol','Ponte do Rol','11'),('PT','PDS','Ponte de Sor','Ponte de Sor','12'),('PT','PDV','Povoa de Varzim','Povoa de Varzim','13'),('PT','PEG','Pegoes','Pegoes','15'),('PT','PEN','Peniche','Peniche','10'),('PT','PER','Paredes de Coura','Paredes de Coura','16'),('PT','PFL','Penafiel','Penafiel','13'),('PT','PFR','Pacos de Ferreira','Pacos de Ferreira','13'),('PT','PFT','Perafita','Perafita','13'),('PT','PGA','Peso da Regua','Peso da Regua','17'),('PT','PGR','Pedrogao Grande','Pedrogao Grande','10'),('PT','PIC','Pico','Pico','03'),('PT','PID','Piedade','Piedade',''),('PT','PIN','Pinhel','Pinhel','09'),('PT','PLM','Ponte do Lima','Ponte do Lima','16'),('PT','PLO','Pombal','Pombal','10'),('PT','PMZ','Porto Moniz','Porto Moniz','30'),('PT','PNC','Penamacor','Penamacor','05'),('PT','PND','Penedono','Penedono','18'),('PT','PNL','Penela','Penela','06'),('PT','PNO','Pinhao','Pinhao','17'),('PT','PNT','Pontinha','Pontinha','11'),('PT','PNV','Pinhal Novo','Pinhal Novo','15'),('PT','POA','Porto Alto','Porto Alto','14'),('PT','POB','Pombal','Pombal',''),('PT','POM','Pomarao','Pomarao','02'),('PT','POR','Portalegre','Portalegre','12'),('PT','PPH','Pero Pinheiro','Pero Pinheiro','11'),('PT','PPS','Pampilhosa da Serra','Pampilhosa da Serra','06'),('PT','PRA','Proenca-a-Nova','Proenca-a-Nova','05'),('PT','PRE','Parede','Parede','11'),('PT','PRG','Praia da Graciosa','Praia da Graciosa','20'),('PT','PRL','Portel','Portel','07'),('PT','PRM','Portimao','Portimao','08'),('PT','PRO','Pedroso','Pedroso','13'),('PT','PRS','Paredes','Paredes','13'),('PT','PRV','Praia da Vitoria','Praia da Vitoria','20'),('PT','PSI','Povoa de Santa Iria','Povoa de Santa Iria','11'),('PT','PSL','Ponta do Sol','Ponta do Sol','30'),('PT','PSV','Porto Salvo','Porto Salvo','11'),('PT','PTB','Ponte da Barca','Ponte da Barca','16'),('PT','PTG','Ponta do Pargo','Ponta do Pargo','30'),('PT','PTS','Pataias','Pataias','10'),('PT','PVC','Povoacao','Povoacao','20'),('PT','PVL','Povoa de Lanhoso','Povoa de Lanhoso','03'),('PT','PXO','Porto Santo Island','Porto Santo Island','30'),('PT','QCD','Quinta do Conde','Quinta do Conde','15'),('PT','QDB','Queluz','Queluz','11'),('PT','QEG','Ribeira Grande','Ribeira Grande','20'),('PT','QRT','Quarteira','Quarteira','08'),('PT','RBD','Rebordelo','Rebordelo','04'),('PT','RBR','Ribeira Brava','Ribeira Brava','30'),('PT','RDD','Redondo','Redondo','07'),('PT','RDM','Rio de Mouro','Rio de Mouro','11'),('PT','RDV','Riba de Ave','Riba de Ave','03'),('PT','REB','Rebordosa','Rebordosa','06'),('PT','REV','Pevidem','Pevidem','03'),('PT','RFB','Rio Frio','Rio Frio','04'),('PT','RIA','Riachos','Riachos','14'),('PT','RIO','Rio Meao','Rio Meao','01'),('PT','RMA','Rio Maior','Rio Maior','14'),('PT','RMZ','Reguengos de Monsaraz','Reguengos de Monsaraz','07'),('PT','RPN','Ribeira de Pena','Ribeira de Pena','17'),('PT','RSD','Resende','Resende','18'),('PT','RTI','Rio Tinto','Rio Tinto','13'),('PT','SAC','Sacavem','Sacavem','11'),('PT','SAN','Sangalhos','Sangalhos','01'),('PT','SAT','Satao','Satao','18'),('PT','SBA','Sao Bras de Alportel','Sao Bras de Alportel','08'),('PT','SBG','Sobral de Monte Agraco','Sobral de Monte Agraco','11'),('PT','SBL','Sabugal','Sabugal','09'),('PT','SBM','Sao Bartolomeu de Messines','Sao Bartolomeu de Messines','08'),('PT','SBR','Sabrosa','Sabrosa','17'),('PT','SCD','Santa Comba Dao','Santa Comba Dao','18'),('PT','SCF','Santa Cruz das Flores','Santa Cruz das Flores','20'),('PT','SCG','Santa Cruz da Graciosa','Santa Cruz da Graciosa','20'),('PT','SCV','Vale','Vale','03'),('PT','SCZ','Santa Cruz','Santa Cruz','30'),('PT','SDM','Salir de Matos','Salir de Matos','10'),('PT','SDR','Sao Domingos de Rana','Sao Domingos de Rana','11'),('PT','SEE','Seia','Seia','09'),('PT','SEI','Seixal','Seixal','15'),('PT','SER','Serzedo','Serzedo','13'),('PT','SET','Setubal','Setubal','15'),('PT','SFR','Safara','Safara','02'),('PT','SGU','Salgueiro','Salgueiro','05'),('PT','SHA','Senhora da Hora','Senhora da Hora','13'),('PT','SIA','Santa Iria de Azoia','Santa Iria de Azoia','11'),('PT','SIE','Sines','Sines','15'),('PT','SJM','Sao Joao da Madeira','Sao Joao da Madeira','01'),('PT','SJP','Sao Joao da Pesqueira','Sao Joao da Pesqueira','18'),('PT','SJT','Sao Joao da Talha','Sao Joao da Talha','11'),('PT','SJZ','Sao Jorge Island Apt','Sao Jorge Island Apt','20'),('PT','SLH','Soalheira','Soalheira','05'),('PT','SLV','Silves','Silves','08'),('PT','SMA','Santa Maria Island Apt','Santa Maria Island Apt','20'),('PT','SMD','Sao Mamede de Infesta','Sao Mamede de Infesta','13'),('PT','SMF','Santa Maria da Feira','Santa Maria da Feira','01'),('PT','SMG','Salvaterra de Magos','Salvaterra de Magos','14'),('PT','SMI','Sao Miguel','Sao Miguel',''),('PT','SMP','Santa Marta de Penaguiao','Santa Marta de Penaguiao','17'),('PT','SMR','Samora Correia','Samora Correia','14'),('PT','SMT','Sao Mateus','Sao Mateus',''),('PT','SND','Sendim','Sendim','13'),('PT','SNT','Santarem','Santarem','14'),('PT','SOU','Soure','Soure','06'),('PT','SPA','Serpa','Serpa','02'),('PT','SPS','Sao Pedro do Sul','Sao Pedro do Sul','18'),('PT','SRD','Sardoal','Sardoal','14'),('PT','SRL','Sernancelhe','Sernancelhe','18'),('PT','SRP','Sao Roque do Pico','Sao Roque do Pico','20'),('PT','SRT','Serta','Serta','05'),('PT','SRV','Santa Clara-a-Velha','Santa Clara-a-Velha','02'),('PT','SSB','Sesimbra','Sesimbra','15'),('PT','SSL','Souzel','Souzel','12'),('PT','STA','Sintra','Sintra','11'),('PT','STC','Santiago do Cacem','Santiago do Cacem','15'),('PT','STI','Santo Tirso','Santo Tirso','13'),('PT','STN','Santana','Santana','30'),('PT','SVB','Sao Vicente da Beira','Sao Vicente da Beira','05'),('PT','SVC','Sao Vicente','Sao Vicente','30'),('PT','SVV','Sever do Vouga','Sever do Vouga','01'),('PT','SZL','Souzelas','Souzelas','06'),('PT','TAB','Tabua','Tabua','06'),('PT','TBC','Tabuaco','Tabuaco','18'),('PT','TBR','Terras de Bouro','Terras de Bouro','03'),('PT','TCS','Trancoso','Trancoso','09'),('PT','TDH','Torre de Dona Chama','Torre de Dona Chama','04'),('PT','TER','Terceira Island Apt','Terceira Island Apt','20'),('PT','TGL','Tramagal','Tramagal','14'),('PT','TMC','Torre de Moncorvo','Torre de Moncorvo','04'),('PT','TMR','Tomar','Tomar','14'),('PT','TNV','Torres Novas','Torres Novas','14'),('PT','TON','Tondela','Tondela','18'),('PT','TOR','Torrao','Torrao','15'),('PT','TPO','Topo','Topo','20'),('PT','TRC','Tarouca','Tarouca','18'),('PT','TRO','Trofa','Trofa','01'),('PT','TVE','Torres Vedras','Torres Vedras','11'),('PT','TVR','Tavira','Tavira','08'),('PT','UGV','Agualva','Agualva','11'),('PT','VAL','Valongo','Valongo','12'),('PT','VBP','Vila do Bispo','Vila do Bispo','08'),('PT','VCA','Vale de Cambra','Vale de Cambra','01'),('PT','VDC','Viana do Castelo','Viana do Castelo','16'),('PT','VDE','Vide','Vide','09'),('PT','VDG','Vidago','Vidago','17'),('PT','VDN','Vendas Novas','Vendas Novas','07'),('PT','VDP','Vila do Porto','Vila do Porto','20'),('PT','VDR','Valadares','Valadares','16'),('PT','VEL','Velas','Velas','20'),('PT','VFC','Vila Franca do Campo','Vila Franca do Campo','20'),('PT','VFL','Vila Flor','Vila Flor','04'),('PT','VFX','Vila Franca de Xira','Vila Franca de Xira','11'),('PT','VGA','Vidigueira','Vidigueira','02'),('PT','VGS','Vagos','Vagos','01'),('PT','VIA','Vialonga','Vialonga','11'),('PT','VIC','Vila do Conde','Vila do Conde','13'),('PT','VIV','Vila Vicosa','Vila Vicosa','07'),('PT','VLD','Vila da Ponte','Vila da Ponte','18'),('PT','VLF','Vilar Formoso','Vilar Formoso','09'),('PT','VLN','Valenca','Valenca','16'),('PT','VLP','Valpacos','Valpacos','17'),('PT','VLR','Vila de Rei','Vila de Rei','05'),('PT','VMA','Vila Mea','Vila Mea','13'),('PT','VMS','Vimioso','Vimioso','04'),('PT','VNA','Vila Nova da Cerveira','Vila Nova da Cerveira','16'),('PT','VNB','Vila Nova da Barquinha','Vila Nova da Barquinha','14'),('PT','VNC','Vila Nova do Corvo','Vila Nova do Corvo',''),('PT','VNF','Vila Nova de Famalicao','Vila Nova de Famalicao','03'),('PT','VNG','Vila Nova de Gaia','Vila Nova de Gaia','13'),('PT','VNH','Vinhais','Vinhais','04'),('PT','VNM','Vila Nova de Milfontes','Vila Nova de Milfontes','02'),('PT','VNO','Vila Nova de Ourem','Vila Nova de Ourem','14'),('PT','VNP','Vila Nova de Poiares','Vila Nova de Poiares','06'),('PT','VNT','Viana do Alentejo','Viana do Alentejo','07'),('PT','VNZ','Vila Nova de Fozcoa','Vila Nova de Fozcoa','09'),('PT','VOP','Vila Nova de Paiva','Vila Nova de Paiva','18'),('PT','VPA','Vila Pouca de Aguiar','Vila Pouca de Aguiar','17'),('PT','VPO','Vilar do Pinheiro','Vilar do Pinheiro','13'),('PT','VRE','Vila Real de Santo Antonio','Vila Real de Santo Antonio','08'),('PT','VRL','Vila Real','Vila Real','17'),('PT','VRM','Vieira do Minho','Vieira do Minho','03'),('PT','VSA','Vila Nova de Santo Andre','Vila Nova de Santo Andre','15'),('PT','VSE','Viseu','Viseu','18'),('PT','VVD','Vila Verde','Vila Verde','03'),('PT','VVR','Vila Velha de Rodao','Vila Velha de Rodao','05'),('PT','VZL','Vouzela','Vouzela','18'),('PT','ZFM','Zona Franca da Madeira','Zona Franca da Madeira','30'),('PT','ZIB','Zibreira','Zibreira','05'),('PT','ZVI','Vizela','Vizela','03'),('PW','','','',''),('PW','ANG','Angaur','Angaur',''),('PW','ROR','Koror','Koror',''),('PY','','','',''),('PY','AGT','Ciudad del Este','Ciudad del Este',''),('PY','ASU','Asuncion','Asuncion',''),('PY','AYO','Ayolas','Ayolas',''),('PY','BCM','Barrio Caacupe Mi','Barrio Caacupe Mi',''),('PY','CAA','Caacupe','Caacupe',''),('PY','CNP','Concepcion','Concepcion',''),('PY','ENO','Encarnacion','Encarnacion',''),('PY','ESG','Mariscal Estigarribia','Mariscal Estigarribia',''),('PY','FLM','Filadelfia','Filadelfia',''),('PY','FUO','Fuerte Olimpo','Fuerte Olimpo',''),('PY','ITE','Ita Enramada','Ita Enramada',''),('PY','MRA','Colonia Mariano Roque Alonso','Colonia Mariano Roque Alonso',''),('PY','PCJ','Puerto la Victoria','Puerto la Victoria',''),('PY','PIL','Pilar','Pilar',''),('PY','PJC','Pedro Juan Caballero','Pedro Juan Caballero',''),('PY','SAN','San Antonio','San Antonio',''),('PY','SLO','San Lorenzo','San Lorenzo',''),('PY','TER','Terport (San Antonio)','Terport (San Antonio)',''),('PY','VEL','Villa Elisa','Villa Elisa',''),('PY','VLL','Villeta','Villeta',''),('PY','VMI','Vallemi','Vallemi',''),('QA','','','',''),('QA','ALU','Al Udeid','Al Udeid',''),('QA','ASN','Al Shaheen','Al Shaheen',''),('QA','DOH','Doha','Doha',''),('QA','HAL','Halul','Halul',''),('QA','HNA','Hanna','Hanna',''),('QA','RLF','Ras Laffan','Ras Laffan',''),('QA','UMS','Umm Sa\'id (Mesaieed)','Umm Sa\'id (Mesaieed)',''),('RE','','','',''),('RE','LPT','Le Port','Le Port',''),('RE','PDG','Port de Pointe des Galets','Port de Pointe des Galets',''),('RE','REU','Reunion','Reunion',''),('RE','RUN','Saint-Denis de la Reunion Apt','Saint-Denis de la Reunion Apt',''),('RE','SDR','Saint-Andre','Saint-Andre',''),('RE','SGL','Saint-Gilles-les Bains','Saint-Gilles-les Bains',''),('RE','SJH','Saint-Joseph','Saint-Joseph',''),('RE','SMA','Ste Marie','Ste Marie',''),('RE','SPH','Saint-Philippe','Saint-Philippe',''),('RE','SPL','Saint-Paul','Saint-Paul',''),('RE','ZSE','St Pierre de la Reunion','St Pierre de la Reunion',''),('RO','','','',''),('RO','ABM','Abram','Abram',''),('RO','ACB','Alexandru cel Bun','Alexandru cel Bun',''),('RO','AGI','Agigea','Agigea',''),('RO','ALB','Albesti','Albesti',''),('RO','ALD','Alesd','Alesd',''),('RO','ALI','Alba Iulia','Alba Iulia',''),('RO','ALX','Alexandria','Alexandria',''),('RO','AMI','Afumati','Afumati',''),('RO','ARW','Arad','Arad',''),('RO','ATI','Acatari','Acatari',''),('RO','AVG','Avrig','Avrig',''),('RO','AVR','Avrig','Avrig',''),('RO','BAB','Basarabi','Basarabi',''),('RO','BAI','Balesti','Balesti',''),('RO','BAL','Bals','Bals',''),('RO','BAR','Barticesti','Barticesti',''),('RO','BAY','Baia Mare','Baia Mare',''),('RO','BBU','Bucuresti-Baneasa Apt','Bucuresti-Baneasa Apt',''),('RO','BCA','Borca','Borca',''),('RO','BCM','Bacau','Bacau',''),('RO','BCN','Beclean','Beclean',''),('RO','BCO','Bacova','Bacova',''),('RO','BCT','Bechet ','Bechet ',''),('RO','BCU','Baciu, Cluj','Baciu, Cluj',''),('RO','BDI','Bodesti','Bodesti',''),('RO','BDU','Bragadiru, Ilfov','Bragadiru, Ilfov',''),('RO','BIT','Bistrita','Bistrita',''),('RO','BLA','Blaj','Blaj',''),('RO','BLJ','Blejoi','Blejoi',''),('RO','BOA','Borsa','Borsa',''),('RO','BOB','Bobota','Bobota',''),('RO','BOC','Bocsa','Bocsa',''),('RO','BOR','Bors','Bors',''),('RO','BOS','Botosani','Botosani',''),('RO','BOV','Bolintin Vale','Bolintin Vale',''),('RO','BOZ','Bozovici','Bozovici',''),('RO','BPU','Baneasa Apt/Bucuresti','Baneasa Apt/Bucuresti',''),('RO','BRA','Braila','Braila',''),('RO','BRC','Berca','Berca',''),('RO','BRD','Brad, Hunedoara','Brad, Hunedoara',''),('RO','BRE','Brebu','Brebu',''),('RO','BRL','Barlad','Barlad',''),('RO','BRT','Bratca','Bratca',''),('RO','BRV','Brasov','Brasov',''),('RO','BSC','Borsec','Borsec',''),('RO','BTD','Baile Tusnad','Baile Tusnad',''),('RO','BUB','Bucuresti Basarab','Bucuresti Basarab',''),('RO','BUC','Buce?','Buce?',''),('RO','BUD','Budesti, Calarasi','Budesti, Calarasi',''),('RO','BUF','Buftea','Buftea',''),('RO','BUH','Bucuresti','Bucuresti',''),('RO','BUI','Bucuresti Intrepozite','Bucuresti Intrepozite',''),('RO','BUM','Becicherecu Mic','Becicherecu Mic',''),('RO','BUN','Bucuresti Nord','Bucuresti Nord',''),('RO','BUV','Bucuresti 50 Vama','Bucuresti 50 Vama',''),('RO','BUZ','Buzau','Buzau',''),('RO','BZA','Breaza, Prahova','Breaza, Prahova',''),('RO','BZI','Bazias','Bazias',''),('RO','BZS','Buzias','Buzias',''),('RO','CAF','Calafat','Calafat',''),('RO','CAM','Campina','Campina',''),('RO','CAR','Carei','Carei',''),('RO','CAS','Calarasi','Calarasi',''),('RO','CBI','Colibasi','Colibasi',''),('RO','CCA','Carcea','Carcea',''),('RO','CCI','Clinceni','Clinceni',''),('RO','CCL','Caracal','Caracal',''),('RO','CDA','Curtea de Arge?','Curtea de Arge?',''),('RO','CEV','Cernavoda','Cernavoda',''),('RO','CJA','Chiajna','Chiajna',''),('RO','CLA','Codlea','Codlea',''),('RO','CLG','Cimpulung','Cimpulung',''),('RO','CLJ','Cluj-Napoca','Cluj-Napoca',''),('RO','CNC','Cilnic, Gorj','Cilnic, Gorj',''),('RO','CND','Constanta','Constanta',''),('RO','CNO','Chirnogi','Chirnogi',''),('RO','CNU','Cornetu, Ilfov','Cornetu, Ilfov',''),('RO','COB','Corabia','Corabia',''),('RO','COM','Comanesti','Comanesti',''),('RO','COV','Covasna','Covasna',''),('RO','CPG','Cimpulung la Tisa','Cimpulung la Tisa',''),('RO','CPI','Campeni','Campeni',''),('RO','CRA','Craiova','Craiova',''),('RO','CRB','Corbeanca','Corbeanca',''),('RO','CRI','Criseni','Criseni',''),('RO','CRU','Cerasu','Cerasu',''),('RO','CSB','Caransebes','Caransebes',''),('RO','CTA','Chitila','Chitila',''),('RO','CTI','Campia Turzii','Campia Turzii',''),('RO','CUT','Curtici','Curtici',''),('RO','DBA','Dobrana','Dobrana',''),('RO','DBR','Dumbraveni, Sibiu','Dumbraveni, Sibiu',''),('RO','DCD','Dorna Candrenilor','Dorna Candrenilor',''),('RO','DCI','Dulcesti, Neamt','Dulcesti, Neamt',''),('RO','DCU','Dascalu','Dascalu',''),('RO','DEJ','Dej','Dej',''),('RO','DHO','Dorohoi','Dorohoi',''),('RO','DIM','Dimbovi?a','Dimbovi?a',''),('RO','DOR','Dornesti','Dornesti',''),('RO','DSI','Dragasani','Dragasani',''),('RO','DTS','Drobeta Turnu Severin','Drobeta Turnu Severin',''),('RO','DVA','Deva','Deva',''),('RO','DVI','Dumbravita, Timis','Dumbravita, Timis',''),('RO','EPB','Episcopia Bihorului','Episcopia Bihorului',''),('RO','FAC','Falciu','Falciu',''),('RO','FAL','Falticeni','Falticeni',''),('RO','FDP','Filipestii de Padure','Filipestii de Padure',''),('RO','FEI','Fieni','Fieni',''),('RO','FGA','Fagaras','Fagaras',''),('RO','FLO','Dealu Floreni','Dealu Floreni',''),('RO','FMU','Frumusani','Frumusani',''),('RO','FOS','Focsani','Focsani',''),('RO','FRT','Floresti','Floresti',''),('RO','GAE','Gaesti','Gaesti',''),('RO','GAL','Galati','Galati',''),('RO','GAT','Galati Transbordare','Galati Transbordare',''),('RO','GDS','Geoagiu','Geoagiu',''),('RO','GEI','Gheraesti','Gheraesti',''),('RO','GGH','Gheorgheni','Gheorgheni',''),('RO','GHL','Gherla','Gherla',''),('RO','GHM','Gherta Mare','Gherta Mare',''),('RO','GIL','Gilau','Gilau',''),('RO','GIU','Giubega','Giubega',''),('RO','GMA','Garla-Mare','Garla-Mare',''),('RO','GMZ','Grumazesti','Grumazesti',''),('RO','GNI','Ganesti','Ganesti',''),('RO','GRA','Gruia','Gruia',''),('RO','GRG','Giurgiu','Giurgiu',''),('RO','GRN','Giurgiu Nord','Giurgiu Nord',''),('RO','HAL','Halmeu','Halmeu',''),('RO','HGU','Hangu','Hangu',''),('RO','HID','Hida','Hida',''),('RO','HTG','Hateg, Hunedoara','Hateg, Hunedoara',''),('RO','HTI','Hintesti','Hintesti',''),('RO','HUN','Hunedoara','Hunedoara',''),('RO','IAS','Iasi','Iasi',''),('RO','IMA','Ialomica, Judecul','Ialomica, Judecul',''),('RO','IVE','Ivesti, Galati','Ivesti, Galati',''),('RO','IZB','Izbiceni','Izbiceni',''),('RO','JIL','Jimbolia','Jimbolia',''),('RO','JUD','Jud. Maramures','Jud. Maramures',''),('RO','JVA','Jilava','Jilava',''),('RO','LGU','Lunguletu','Lunguletu',''),('RO','LMA','Lumina','Lumina',''),('RO','LMN','Lemnia','Lemnia',''),('RO','LMU','Lunca Muresului, Alba','Lunca Muresului, Alba',''),('RO','LRM','Lancram','Lancram',''),('RO','LUG','Lugoj','Lugoj',''),('RO','MAG','Mangalia','Mangalia',''),('RO','MAU','Mediesu Aurit','Mediesu Aurit',''),('RO','MCA','Miercurea-Ciuc','Miercurea-Ciuc',''),('RO','MDA','Mehadia','Mehadia',''),('RO','MED','Medgidia','Medgidia',''),('RO','MES','Medias','Medias',''),('RO','MID','Midia','Midia',''),('RO','MKO','Mihail Kogalniceanu','Mihail Kogalniceanu',''),('RO','MNI','Moinesti','Moinesti',''),('RO','MON','Mosnita Noua','Mosnita Noua',''),('RO','MOV','Moldova Veche','Moldova Veche',''),('RO','MRI','Moreni, Dimbovita','Moreni, Dimbovita',''),('RO','MSA','Mogosoaia','Mogosoaia',''),('RO','MSI','Moisei','Moisei',''),('RO','MTI','Mateesti','Mateesti',''),('RO','MUR','Murfatlar','Murfatlar',''),('RO','MVU','Mihai Viteazu','Mihai Viteazu',''),('RO','NAD','Naidas','Naidas',''),('RO','NAZ','Nazna','Nazna',''),('RO','NDI','Navodari','Navodari',''),('RO','NEV','Negru Voda','Negru Voda',''),('RO','NIB','Nicolae Balcescu','Nicolae Balcescu',''),('RO','NIN','Nicolina','Nicolina',''),('RO','NVA','Novacu','Novacu',''),('RO','OCM','Ocna Mures','Ocna Mures',''),('RO','ODL','Orodelu','Orodelu',''),('RO','OLT','Oltenita','Oltenita',''),('RO','OMR','Oradea','Oradea',''),('RO','OPR','Oprisor','Oprisor',''),('RO','ORV','Orsova','Orsova',''),('RO','OSE','Odorheiu Secuiesc','Odorheiu Secuiesc',''),('RO','OSI','Onesti, Bacau','Onesti, Bacau',''),('RO','OTP','Otopeni Apt/Bucuresti','Otopeni Apt/Bucuresti',''),('RO','OTZ','Oituz, Bacau','Oituz, Bacau',''),('RO','OVA','Oravita','Oravita',''),('RO','PAN','Panic','Panic',''),('RO','PAS','Pascani','Pascani',''),('RO','PCA','Pecica','Pecica',''),('RO','PCI','Pascani','Pascani',''),('RO','PDM','Poienarii de Muscel','Poienarii de Muscel',''),('RO','PEI','Petrosani','Petrosani',''),('RO','PET','Petre?ti','Petre?ti',''),('RO','PFD','Portile de Fier Doi','Portile de Fier Doi',''),('RO','PFU','Portile de Fier Unu','Portile de Fier Unu',''),('RO','PIA','Piatra Olt','Piatra Olt',''),('RO','PIN','Piatra Neamt','Piatra Neamt',''),('RO','PIT','Pitesti','Pitesti',''),('RO','PLE','Popesti-Leordeni','Popesti-Leordeni',''),('RO','PLT','Ploiesti','Ploiesti',''),('RO','PNC','Panciu','Panciu',''),('RO','PNG','Poiana Negrii','Poiana Negrii',''),('RO','PNT','Pantelimon','Pantelimon',''),('RO','POA','Pietroasa','Pietroasa',''),('RO','PRA','Petrila, Hunedoara','Petrila, Hunedoara',''),('RO','PRI','Polovragi','Polovragi',''),('RO','PRS','Peris, Ilfov','Peris, Ilfov',''),('RO','PSI','Poiana Sibiului','Poiana Sibiului',''),('RO','PTI','Pietrari, Valcea','Pietrari, Valcea',''),('RO','RAU','Radauti','Radauti',''),('RO','RBI','Razboieni','Razboieni',''),('RO','RCR','Rucar','Rucar',''),('RO','RDS','Rona de Sus','Rona de Sus',''),('RO','REA','Resita','Resita',''),('RO','REC','Recas','Recas',''),('RO','REN','Resita Nord','Resita Nord',''),('RO','RES','Resita Sud','Resita Sud',''),('RO','RHN','Reghin','Reghin',''),('RO','RIV','Ramnicu Valcea','Ramnicu Valcea',''),('RO','RMA','Remetea, Harghita','Remetea, Harghita',''),('RO','RMN','Roman','Roman',''),('RO','RNV','Rasnov','Rasnov',''),('RO','ROV','Rovinari','Rovinari',''),('RO','RRM','Balotesti','Balotesti',''),('RO','RUP','Rupea','Rupea',''),('RO','RVA','Harsova','Harsova',''),('RO','RZV','Roznov','Roznov',''),('RO','SAT','Salonta','Salonta',''),('RO','SAU','Saulia','Saulia',''),('RO','SBA','Slobozia','Slobozia',''),('RO','SBS','Sebes, Alba','Sebes, Alba',''),('RO','SBZ','Sibiu','Sibiu',''),('RO','SCI','Sincraieni','Sincraieni',''),('RO','SCS','Suncuius','Suncuius',''),('RO','SCV','Suceava','Suceava',''),('RO','SDJ','Salciua de Jos','Salciua de Jos',''),('RO','SDM','Sincraiu de Mures','Sincraiu de Mures',''),('RO','SDN','Smardan','Smardan',''),('RO','SEC','Secueni','Secueni',''),('RO','SEI','Seitin','Seitin',''),('RO','SFG','Sfantul-Gheorghe','Sfantul-Gheorghe',''),('RO','SGV','Snagov','Snagov',''),('RO','SIM','Sighetu Marmatiei','Sighetu Marmatiei',''),('RO','SIT','Simeria','Simeria',''),('RO','SLA','Slatina','Slatina',''),('RO','SLE','Saliste','Saliste',''),('RO','SLO','Slobozia, Arges','Slobozia, Arges',''),('RO','SMU','Sintana de Mures','Sintana de Mures',''),('RO','SOC','Socetu','Socetu',''),('RO','SOI','Sabaoani','Sabaoani',''),('RO','SOL','Socola','Socola',''),('RO','SOM','Someseni','Someseni',''),('RO','SSA','Sighisoara','Sighisoara',''),('RO','STG','Sintereag','Sintereag',''),('RO','STI','Stefanesti, Arges','Stefanesti, Arges',''),('RO','STM','Stamora Germana','Stamora Germana',''),('RO','SUJ','Satu Mare','Satu Mare',''),('RO','SUL','Sulina (Port et Zone Franche)','Sulina (Port et Zone Franche)',''),('RO','SUN','Suceava Nord','Suceava Nord',''),('RO','TAD','Tileagd','Tileagd',''),('RO','TAR','Targoviste','Targoviste',''),('RO','TCE','Tulcea','Tulcea',''),('RO','TDA','Turda','Turda',''),('RO','TET','Tetchea','Tetchea',''),('RO','TGA','Teregova','Teregova',''),('RO','TGM','Targu-Mures','Targu-Mures',''),('RO','TIC','Ticleni','Ticleni',''),('RO','TIG','Tiganesti','Tiganesti',''),('RO','TJI','Tarju Jiu','Tarju Jiu',''),('RO','TJU','Tirgu Jiu','Tirgu Jiu',''),('RO','TNI','Tonesti, Olt','Tonesti, Olt',''),('RO','TOH','Tohani','Tohani',''),('RO','TON','Teleorman','Teleorman',''),('RO','TSC','Targu Secuiesc','Targu Secuiesc',''),('RO','TSN','Timisoara Nord','Timisoara Nord',''),('RO','TSR','Timisoara','Timisoara',''),('RO','TUM','Turnu Magurele','Turnu Magurele',''),('RO','TVI','Tarnaveni','Tarnaveni',''),('RO','URA','Unirea','Unirea',''),('RO','URZ','Urziceni','Urziceni',''),('RO','VAM','Valea Luimihai','Valea Luimihai',''),('RO','VAS','Varsand','Varsand',''),('RO','VAV','Vama Veche','Vama Veche',''),('RO','VDE','Videle','Videle',''),('RO','VDI','Vladesti','Vladesti',''),('RO','VDM','Valenii de Munte','Valenii de Munte',''),('RO','VDO','Vatra Dornei','Vatra Dornei',''),('RO','VDR','Vidra, Vrancea','Vidra, Vrancea',''),('RO','VDS','Viseu de Sus','Viseu de Sus',''),('RO','VER','Vernesti','Vernesti',''),('RO','VEU','Vladimirescu','Vladimirescu',''),('RO','VIS','Vicsani','Vicsani',''),('RO','VIZ','Vadu Izei','Vadu Izei',''),('RO','VLI','Vaslui','Vaslui',''),('RO','VMA','Vanatorii-Mari','Vanatorii-Mari',''),('RO','VNI','Voine_ti','Voine_ti',''),('RO','VRI','Vacaresti, Dimbovita','Vacaresti, Dimbovita',''),('RO','VTG','Voiteg','Voiteg',''),('RO','ZAR','Zarnesti','Zarnesti',''),('RO','ZAU','Zalau','Zalau',''),('RO','ZIC','Zimnicea','Zimnicea',''),('RO','ZTA','Zlatna','Zlatna',''),('RS','','','',''),('RS','ADA','Ada','Ada',''),('RS','ALC','Arandjelovac','Arandjelovac',''),('RS','APT','Apatin','Apatin',''),('RS','ARJ','Arilje','Arilje',''),('RS','BCN','Beocin','Beocin',''),('RS','BEC','Becej','Becej',''),('RS','BEG','Belgrade (Beograd)','Belgrade (Beograd)',''),('RS','BOR','Bor','Bor',''),('RS','BPA','Backa Palanka','Backa Palanka',''),('RS','BRC','Baric','Baric',''),('RS','BSA','Baracka','Baracka',''),('RS','BTO','Backa Topola','Backa Topola',''),('RS','BUJ','Bujanovac','Bujanovac',''),('RS','BVO','Bogojevo','Bogojevo',''),('RS','BZD','Bezdam','Bezdam',''),('RS','CAC','Cacak','Cacak',''),('RS','CBO','Camp Bondsteel','Camp Bondsteel',''),('RS','CMI','Camp Montieth','Camp Montieth',''),('RS','CRG','Curug','Curug',''),('RS','CUP','Cuprija','Cuprija',''),('RS','CVC','Cerevic','Cerevic',''),('RS','DIM','Dimitrovgrad','Dimitrovgrad',''),('RS','DZC','Drazevac','Drazevac',''),('RS','GMI','Gornji Milanovac','Gornji Milanovac',''),('RS','GRU','Gruza','Gruza',''),('RS','INI','Nis','Nis',''),('RS','IVA','Ivanjica','Ivanjica',''),('RS','JAG','Jagodina','Jagodina',''),('RS','KAY','Kikinda','Kikinda',''),('RS','KDV','Kladovo','Kladovo',''),('RS','KGV','Kragujevac','Kragujevac',''),('RS','KJA','Kanjiza','Kanjiza',''),('RS','KMA','Kursumlija','Kursumlija',''),('RS','KNC','Knic','Knic',''),('RS','KPJ','Kosovo Polje (Fushe Kosove)','Kosovo Polje (Fushe Kosove)',''),('RS','KRA','Kraljevo','Kraljevo',''),('RS','KRU','Krusevac','Krusevac',''),('RS','KTC','Kostolac','Kostolac',''),('RS','KVC','Knjazevac','Knjazevac',''),('RS','LBE','Lebane','Lebane',''),('RS','LJG','Ljig','Ljig',''),('RS','LOZ','Loznica','Loznica',''),('RS','LPO','Lapovo','Lapovo',''),('RS','LTE','Lestane','Lestane',''),('RS','LVC','Leskovac','Leskovac',''),('RS','MJI','Mrcajevci','Mrcajevci',''),('RS','MLI','Melenci','Melenci',''),('RS','MNC','Mladenovac','Mladenovac',''),('RS','MSA','Merosina','Merosina',''),('RS','NEG','Negotin','Negotin',''),('RS','NOS','Novo Selo','Novo Selo',''),('RS','NSL','Novi Slankamen','Novi Slankamen',''),('RS','NVP','Novi Pazar','Novi Pazar',''),('RS','NVS','Novi Sad','Novi Sad',''),('RS','ONC','Obrenovac','Obrenovac',''),('RS','PCN','Parain','Parain',''),('RS','PHO','Prahovo','Prahovo',''),('RS','PIR','Pirot','Pirot',''),('RS','PLC','Palic','Palic',''),('RS','POZ','Pozega','Pozega',''),('RS','PRI','Prijepolje','Prijepolje',''),('RS','PRN','Pristina','Pristina',''),('RS','PRO','Prokuplje','Prokuplje',''),('RS','PRZ','Prizren','Prizren',''),('RS','PYJ','Pancevo','Pancevo',''),('RS','RPJ','Ripanj','Ripanj',''),('RS','RUM','Ruma','Ruma',''),('RS','SAB','Sabac','Sabac',''),('RS','SCA','Sremcica','Sremcica',''),('RS','SEV','Sevojno','Sevojno',''),('RS','SID','Sid','Sid',''),('RS','SKA','Sremski Karlovci','Sremski Karlovci',''),('RS','SMO','Smederevo','Smederevo',''),('RS','SNC','Svilajnac','Svilajnac',''),('RS','SOM','Sombor','Sombor',''),('RS','SPA','Stara Pazova','Stara Pazova',''),('RS','SRG','Sirig','Sirig',''),('RS','SRM','Sremska Mitrovica','Sremska Mitrovica',''),('RS','STZ','Strezimirovci','Strezimirovci',''),('RS','SUB','Subotica','Subotica',''),('RS','TJV','Tresnjevac','Tresnjevac',''),('RS','UZC','Uzice','Uzice',''),('RS','VGS','Veliko Gradiste','Veliko Gradiste',''),('RS','VLA','Vlasotince','Vlasotince',''),('RS','VLJ','Valjevo','Valjevo',''),('RS','VRA','Vranje','Vranje',''),('RS','VRB','Vrbas','Vrbas',''),('RS','VRS','Vrsac','Vrsac',''),('RS','ZAJ','Zajecar','Zajecar',''),('RS','ZEM','Zemun','Zemun',''),('RS','ZRN','Zrenjanin','Zrenjanin',''),('RS','ZZP','Pozarevac','Pozarevac',''),('RU','','','',''),('RU','AAD','Aleksandrov (Alexandrov)','Aleksandrov (Alexandrov)',''),('RU','AAQ','Anapa','Anapa',''),('RU','ABA','Abakan','Abakan',''),('RU','ABS','Akhtubinsk','Akhtubinsk',''),('RU','ACS','Achinsk','Achinsk',''),('RU','ADH','Aldan','Aldan',''),('RU','AER','Adler/Sochi','Adler/Sochi',''),('RU','AGI','Aginskoye','Aginskoye',''),('RU','AHR','Akhtari','Akhtari',''),('RU','ALV','Aleksandrov','Aleksandrov',''),('RU','AMB','Ambetsu','Ambetsu',''),('RU','AMV','Amderma','Amderma',''),('RU','ARH','Arkhangelsk','Arkhangelsk',''),('RU','ARM','Arman (Magadan)','Arman (Magadan)',''),('RU','ASB','Asbest','Asbest',''),('RU','ASF','Astrakhan','Astrakhan',''),('RU','ATK','Almetyevsk','Almetyevsk',''),('RU','AZO','Azov','Azov',''),('RU','BAK','Baksan','Baksan',''),('RU','BAL','Balobanovo','Balobanovo',''),('RU','BAX','Barnaul','Barnaul',''),('RU','BCX','Beloreck','Beloreck',''),('RU','BEK','Belorechensk','Belorechensk',''),('RU','BEL','Belushye','Belushye',''),('RU','BEM','Belomorsk','Belomorsk',''),('RU','BER','Beringovskiy, Port','Beringovskiy, Port',''),('RU','BGK','Boksitogorsk','Boksitogorsk',''),('RU','BGR','Bagrationovsk','Bagrationovsk',''),('RU','BIY','Biysk','Biysk',''),('RU','BKH','Bektyashka','Bektyashka',''),('RU','BKV','Balakirevo','Balakirevo',''),('RU','BLA','Balashikha','Balashikha',''),('RU','BLT','Baltiysk','Baltiysk',''),('RU','BOS','Boshnyakovo','Boshnyakovo',''),('RU','BOV','Bolshaya Vishera','Bolshaya Vishera',''),('RU','BQS','Blagoveschensk','Blagoveschensk',''),('RU','BRO','Bronnitsy','Bronnitsy',''),('RU','BRY','Bryansk','Bryansk',''),('RU','BRZ','Berezniki','Berezniki',''),('RU','BTK','Bratsk','Bratsk',''),('RU','BUZ','Buzuluk','Buzuluk',''),('RU','BWO','Balakovo','Balakovo',''),('RU','CAI','Chaykovskiy','Chaykovskiy',''),('RU','CEE','Cherepovets','Cherepovets',''),('RU','CEK','Chelyabinsk','Chelyabinsk',''),('RU','CHA','Chamgu','Chamgu',''),('RU','CHB','Chebarkul\'','Chebarkul\'',''),('RU','CHD','Chudovo','Chudovo',''),('RU','CHK','Chernyakhovsk','Chernyakhovsk',''),('RU','CIH','Chikacheva','Chikacheva',''),('RU','CKH','Chokurdah','Chokurdah',''),('RU','CKL','Chkalovsky','Chkalovsky',''),('RU','CNN','Chulman','Chulman',''),('RU','CSY','Cheboksary','Cheboksary',''),('RU','CYO','Chernyy Otrog','Chernyy Otrog',''),('RU','CYX','Cherskiy','Cherskiy',''),('RU','DBO','Dubrovo','Dubrovo',''),('RU','DHA','Derbeshkinskiy','Derbeshkinskiy',''),('RU','DKA','De-Kastri','De-Kastri',''),('RU','DKS','Dikson','Dikson',''),('RU','DME','Domodedovo Apt/Moscow','Domodedovo Apt/Moscow',''),('RU','DMT','Dimitrovgrad','Dimitrovgrad',''),('RU','DTV','Dmitrov','Dmitrov',''),('RU','DUD','Dudinka','Dudinka',''),('RU','DVO','Davidovo','Davidovo',''),('RU','DYA','Dyad\'kovo','Dyad\'kovo',''),('RU','DYR','Anadyr','Anadyr',''),('RU','EGO','Belgorod','Belgorod',''),('RU','EGV','Egvekinot','Egvekinot',''),('RU','EIE','Eniseysk','Eniseysk',''),('RU','EKO','Ekonomiya','Ekonomiya',''),('RU','ELG','Elektrogorsk','Elektrogorsk',''),('RU','ESL','Elista','Elista',''),('RU','ESS','Yessentuki (Essentuki)','Yessentuki (Essentuki)',''),('RU','EVK','Yegor\'yevsk','Yegor\'yevsk',''),('RU','FUR','Furmanov','Furmanov',''),('RU','GAT','Gatchina','Gatchina',''),('RU','GDG','Magdagachi','Magdagachi',''),('RU','GDX','Magadan','Magadan',''),('RU','GDZ','Gelendzik','Gelendzik',''),('RU','GKA','Golchikka','Golchikka',''),('RU','GKY','Gus Khrustalny','Gus Khrustalny',''),('RU','GOA','Gorno Altaisk','Gorno Altaisk',''),('RU','GOJ','Nizhniy Novgorod (ex Gorkiy)','Nizhniy Novgorod (ex Gorkiy)',''),('RU','GOR','Gorkino','Gorkino',''),('RU','GRH','Gremikha','Gremikha',''),('RU','GRK','Grodekovo','Grodekovo',''),('RU','GRV','Groznyj','Groznyj',''),('RU','GSA','Gorskaya','Gorskaya',''),('RU','GUB','Gubkin','Gubkin',''),('RU','GUO','Znamenskoye Gubailovo','Znamenskoye Gubailovo',''),('RU','GVS','Gusevskiy','Gusevskiy',''),('RU','GVY','Gavrilov-Yam','Gavrilov-Yam',''),('RU','GZV','Glazov','Glazov',''),('RU','HOR','Horlovo','Horlovo',''),('RU','HRA','Khropunovo','Khropunovo',''),('RU','HTA','Chita','Chita',''),('RU','HTG','Hatanga','Hatanga',''),('RU','HYR','Khyrov','Khyrov',''),('RU','IAA','Igarka','Igarka',''),('RU','IAR','Yaroslavl','Yaroslavl',''),('RU','IJK','Izhevsk','Izhevsk',''),('RU','IKJ','Isayevskoje','Isayevskoje',''),('RU','IKS','Tiksi','Tiksi',''),('RU','IKT','Irkutsk','Irkutsk',''),('RU','INA','Inta','Inta',''),('RU','IOK','Iokanka','Iokanka',''),('RU','IOY','Ikryanoye','Ikryanoye',''),('RU','IRB','Irbit','Irbit',''),('RU','ISM','Ishim','Ishim',''),('RU','IVA','Ivangorod','Ivangorod',''),('RU','IVO','Ivanovo','Ivanovo',''),('RU','IWA','Ivanova','Ivanova',''),('RU','JOK','Joshkar-Ola','Joshkar-Ola',''),('RU','KAD','Korolev (ex Kaliningrad), Moskovskaya','Korolev (ex Kaliningrad), Moskovskaya',''),('RU','KAM','Kamyshin','Kamyshin',''),('RU','KAN','Kandalaksha','Kandalaksha',''),('RU','KAR','Karpinsk','Karpinsk',''),('RU','KAS','Kashira','Kashira',''),('RU','KAV','Kavalerovo','Kavalerovo',''),('RU','KCG','Kol\'chugino','Kol\'chugino',''),('RU','KCP','Kirovo-Chepetsk','Kirovo-Chepetsk',''),('RU','KDK','Kodinsk','Kodinsk',''),('RU','KDN','Kildin','Kildin',''),('RU','KDT','Kronshtadt','Kronshtadt',''),('RU','KEJ','Kemerovo','Kemerovo',''),('RU','KEM','Kem','Kem',''),('RU','KER','Keret','Keret',''),('RU','KGD','Kaliningrad','Kaliningrad',''),('RU','KGP','Kogalym','Kogalym',''),('RU','KGS','Kingisepp','Kingisepp',''),('RU','KHM','Khanty-Mansiysk','Khanty-Mansiysk',''),('RU','KHO','Kholmsk','Kholmsk',''),('RU','KHS','Khasan','Khasan',''),('RU','KHV','Khabarovsk','Khabarovsk',''),('RU','KIN','Kineshma','Kineshma',''),('RU','KIR','Kirishi','Kirishi',''),('RU','KIY','Kirovskiy','Kirovskiy',''),('RU','KJA','Krasnojarsk','Krasnojarsk',''),('RU','KLF','Kaluga','Kaluga',''),('RU','KLI','Klin','Klin',''),('RU','KLM','Kolomna','Kolomna',''),('RU','KMA','Kostomuksha','Kostomuksha',''),('RU','KMK','Krasnoarmeysk','Krasnoarmeysk',''),('RU','KMM','Malaya Kheta','Malaya Kheta',''),('RU','KMU','Kamskoye Ustye','Kamskoye Ustye',''),('RU','KMV','Velikaya Kema','Velikaya Kema',''),('RU','KMW','Kostroma','Kostroma',''),('RU','KNK','Krasnokamsk','Krasnokamsk',''),('RU','KNV','Krasnovodsk','Krasnovodsk',''),('RU','KNY','Khvalynsk','Khvalynsk',''),('RU','KOH','Kokhma','Kokhma',''),('RU','KOK','Konakovo','Konakovo',''),('RU','KOR','Korsakov','Korsakov',''),('RU','KOV','Kovrov','Kovrov',''),('RU','KPA','Kondopoga','Kondopoga',''),('RU','KRA','Krasnoyarsk','Krasnoyarsk',''),('RU','KRF','Korf','Korf',''),('RU','KRO','Kurgan','Kurgan',''),('RU','KRR','Krasnodar','Krasnodar',''),('RU','KRU','Krugloye Pole','Krugloye Pole',''),('RU','KSI','Kasimov','Kasimov',''),('RU','KSL','Kislaya Guba','Kislaya Guba',''),('RU','KST','Kostarikha','Kostarikha',''),('RU','KSZ','Kotlas','Kotlas',''),('RU','KUF','Samara','Samara',''),('RU','KUL','Kultuk','Kultuk',''),('RU','KUY','Kamensk-Ural\'skiy','Kamensk-Ural\'skiy',''),('RU','KUZ','Kuznetsk','Kuznetsk',''),('RU','KVK','Kirovsk','Kirovsk',''),('RU','KVX','Kirov','Kirov',''),('RU','KXK','Komsomolsk Na Amure','Komsomolsk Na Amure',''),('RU','KYB','Krasnyye Barrikady','Krasnyye Barrikady',''),('RU','KYZ','Kyzyl','Kyzyl',''),('RU','KZN','Kazan','Kazan',''),('RU','LAZ','Lazarev','Lazarev',''),('RU','LBA','Lobnya','Lobnya',''),('RU','LDY','Lebedyan\'','Lebedyan\'',''),('RU','LED','Saint Petersburg (ex Leningrad)','Saint Petersburg (ex Leningrad)',''),('RU','LEK','Leningradskaya','Leningradskaya',''),('RU','LES','Lesogorsk','Lesogorsk',''),('RU','LKA','Luzhaika','Luzhaika',''),('RU','LNR','Linakhamari','Linakhamari',''),('RU','LNX','Smolensk','Smolensk',''),('RU','LOM','Lomonosov','Lomonosov',''),('RU','LPK','Lipetsk (Lipeck)','Lipetsk (Lipeck)',''),('RU','LVR','Lavrentiya','Lavrentiya',''),('RU','LYU','Lyubuchany','Lyubuchany',''),('RU','MAG','Magadansky, Port','Magadansky, Port',''),('RU','MAS','Miass','Miass',''),('RU','MCX','Makhachkala','Makhachkala',''),('RU','MEG','Medvezhyegorsk','Medvezhyegorsk',''),('RU','MEZ','Mezen','Mezen',''),('RU','MGO','Mago','Mago',''),('RU','MIK','Mikhnevo','Mikhnevo',''),('RU','MJZ','Mirnyj','Mirnyj',''),('RU','MMK','Murmansk','Murmansk',''),('RU','MMO','Mamonova','Mamonova',''),('RU','MND','Mondy','Mondy',''),('RU','MOL','Molot','Molot',''),('RU','MOW','Moskva','Moskva',''),('RU','MQF','Magnitogorsk','Magnitogorsk',''),('RU','MRV','Mineralnye Vody','Mineralnye Vody',''),('RU','MSH','Mys Shmidta','Mys Shmidta',''),('RU','MSK','Mishkino','Mishkino',''),('RU','MVO','Moskalvo','Moskalvo',''),('RU','MYB','Malyye Bazy','Malyye Bazy',''),('RU','MZV','Mezhevoy','Mezhevoy',''),('RU','NAC','Naberezhnyye Chelny','Naberezhnyye Chelny',''),('RU','NAL','Nalchik','Nalchik',''),('RU','NDK','Novodvinsk','Novodvinsk',''),('RU','NEF','Neftekamsk','Neftekamsk',''),('RU','NEK','Nevinnomyssk','Nevinnomyssk',''),('RU','NER','Neryungri','Neryungri',''),('RU','NEV','Nevelsk','Nevelsk',''),('RU','NFG','Nefteyugansk','Nefteyugansk',''),('RU','NGI','Noginsk','Noginsk',''),('RU','NIA','Nikolayevsk-na-Amure','Nikolayevsk-na-Amure',''),('RU','NIT','Nizhniy Tagil','Nizhniy Tagil',''),('RU','NJC','Nizhnevartovsk','Nizhnevartovsk',''),('RU','NJK','Nakhodka','Nakhodka',''),('RU','NKI','Naushki','Naushki',''),('RU','NMK','Novomoskovsk','Novomoskovsk',''),('RU','NNM','Naryan Mar','Naryan Mar',''),('RU','NOG','Nogliki','Nogliki',''),('RU','NOJ','Nojabrxsk','Nojabrxsk',''),('RU','NOZ','Novokuznetsk','Novokuznetsk',''),('RU','NSK','Noril\'sk','Noril\'sk',''),('RU','NUX','Novy Urengoy','Novy Urengoy',''),('RU','NVK','Novocherkassk','Novocherkassk',''),('RU','NVR','Novgorod','Novgorod',''),('RU','NVS','Novorossiysk','Novorossiysk',''),('RU','NVY','Novyy','Novyy',''),('RU','NYM','Nadym','Nadym',''),('RU','NZK','Nizhnekamsk','Nizhnekamsk',''),('RU','NZL','Nizhniy Lomov','Nizhniy Lomov',''),('RU','NZV','Novozybkov','Novozybkov',''),('RU','OBK','Obninsk','Obninsk',''),('RU','OHO','Okhotsk','Okhotsk',''),('RU','OKA','Okha, Sakhalin','Okha, Sakhalin',''),('RU','OKT','Oktyabr\'skiy','Oktyabr\'skiy',''),('RU','OLB','Bukhta Olga','Bukhta Olga',''),('RU','OLG','Olenya, Guba','Olenya, Guba',''),('RU','OLO','Oleniy Ostrov','Oleniy Ostrov',''),('RU','OMS','Omsk','Omsk',''),('RU','ONE','Otradnoye','Otradnoye',''),('RU','ONG','Onega','Onega',''),('RU','ONK','Obninsk','Obninsk',''),('RU','ORE','Orel','Orel',''),('RU','ORL','Or\'ol','Or\'ol',''),('RU','OSO','Odintsovo','Odintsovo',''),('RU','OSW','Orsk','Orsk',''),('RU','OTR','Otradnyy','Otradnyy',''),('RU','OVB','Novosibirsk','Novosibirsk',''),('RU','OYA','Olya','Olya',''),('RU','OZE','Oranzherei','Oranzherei',''),('RU','OZK','Ozerko','Ozerko',''),('RU','OZY','Ozery','Ozery',''),('RU','PCE','Pechenga','Pechenga',''),('RU','PDK','Podolsk','Podolsk',''),('RU','PDY','Pravdinskiy','Pravdinskiy',''),('RU','PEE','Perm','Perm',''),('RU','PEK','Petrokrepost','Petrokrepost',''),('RU','PER','Pereslavl\'-Zalesskiy','Pereslavl\'-Zalesskiy',''),('RU','PES','Petrozavodsk','Petrozavodsk',''),('RU','PEX','Pechora','Pechora',''),('RU','PEZ','Penza','Penza',''),('RU','PGN','Prigorodnoye','Prigorodnoye',''),('RU','PGO','Pargolovo','Pargolovo',''),('RU','PHK','Petushki','Petushki',''),('RU','PKC','Petropavlovsk-Kamchatskiy','Petropavlovsk-Kamchatskiy',''),('RU','PKI','Pochinki','Pochinki',''),('RU','PKO','Pokrov','Pokrov',''),('RU','PKR','Pitkyaranta','Pitkyaranta',''),('RU','PKV','Pskov','Pskov',''),('RU','PLO','Pavlovo','Pavlovo',''),('RU','PNY','Pionerskiy','Pionerskiy',''),('RU','POS','Posin\'ye','Posin\'ye',''),('RU','PPZ','Podporozh\'ye','Podporozh\'ye',''),('RU','PRI','Primorsk (Koivisto)','Primorsk (Koivisto)',''),('RU','PRN','Poronaisk','Poronaisk',''),('RU','PRY','Preobrazheniye','Preobrazheniye',''),('RU','PSE','Posyet','Posyet',''),('RU','PSH','Pushkino','Pushkino',''),('RU','PSK','Privolzhsk','Privolzhsk',''),('RU','PTN','Plastun','Plastun',''),('RU','PUD','Pudozh','Pudozh',''),('RU','PUK','Pushkin','Pushkin',''),('RU','PVK','Pervoural\'sk','Pervoural\'sk',''),('RU','PVS','Provideniya, Bukhta','Provideniya, Bukhta',''),('RU','PVX','Provedenia','Provedenia',''),('RU','PWE','Pevek','Pevek',''),('RU','PYA','Pyatigorsk','Pyatigorsk',''),('RU','PYJ','Polyarnyj','Polyarnyj',''),('RU','PYO','Poyarkovo','Poyarkovo',''),('RU','PZK','Priozersk','Priozersk',''),('RU','RAM','Ramenskoye','Ramenskoye',''),('RU','RAT','Raduzhnyi','Raduzhnyi',''),('RU','RDP','Rudnaya Pristan','Rudnaya Pristan',''),('RU','REN','Orenburg','Orenburg',''),('RU','RNA','Rudnya','Rudnya',''),('RU','RND','Rostov-na-Donu','Rostov-na-Donu',''),('RU','ROV','Rostov','Rostov',''),('RU','RTV','Reutov','Reutov',''),('RU','RTW','Saratov','Saratov',''),('RU','RYB','Rybinsk','Rybinsk',''),('RU','RYS','Ryshkovo','Ryshkovo',''),('RU','RZN','Ryazan','Ryazan',''),('RU','RZV','Rzhev','Rzhev',''),('RU','SAK','Aleksandrovsk-Sakhalinskiy','Aleksandrovsk-Sakhalinskiy',''),('RU','SAL','Salavat','Salavat',''),('RU','SAR','Sarova','Sarova',''),('RU','SCW','Syktyvkar','Syktyvkar',''),('RU','SEG','Segezha','Segezha',''),('RU','SEW','Severodvinsk','Severodvinsk',''),('RU','SGC','Surgut','Surgut',''),('RU','SGV','Sergiyev Posad','Sergiyev Posad',''),('RU','SHA','Shakhtersk','Shakhtersk',''),('RU','SHU','Shushenskoye','Shushenskoye',''),('RU','SHV','Serpukhov','Serpukhov',''),('RU','SIZ','Siziman','Siziman',''),('RU','SKA','Slavyanka','Slavyanka',''),('RU','SKH','Shumikha','Shumikha',''),('RU','SKO','Skopin','Skopin',''),('RU','SKX','Saransk','Saransk',''),('RU','SLA','Shala','Shala',''),('RU','SLO','Sertolovo','Sertolovo',''),('RU','SLV','Solovyevsk','Solovyevsk',''),('RU','SLY','Salehard','Salehard',''),('RU','SNG','Solnechnogorsk','Solnechnogorsk',''),('RU','SOB','Sosnovyy Bor','Sosnovyy Bor',''),('RU','SOC','Sochi','Sochi',''),('RU','SOG','Sovetskaya Gavan','Sovetskaya Gavan',''),('RU','SOK','Solikamsk','Solikamsk',''),('RU','SPA','Spafaryeva, O','Spafaryeva, O',''),('RU','SPO','Stupino','Stupino',''),('RU','SRM','Severomorsk','Severomorsk',''),('RU','SRP','Sarapul','Sarapul',''),('RU','SRV','Serov','Serov',''),('RU','SSK','Sovetsk','Sovetsk',''),('RU','SSY','Sosenskiy','Sosenskiy',''),('RU','STA','Shatura','Shatura',''),('RU','STO','Staryy Oskol','Staryy Oskol',''),('RU','STW','Stavropol','Stavropol',''),('RU','SUP','Suponevo','Suponevo',''),('RU','SVB','Severobaykal\'sk','Severobaykal\'sk',''),('RU','SVE','Svetlaya','Svetlaya',''),('RU','SVG','Svetogorsk','Svetogorsk',''),('RU','SVK','Severo-Kurilsk','Severo-Kurilsk',''),('RU','SVO','Sheremetyevo Apt/Moscow','Sheremetyevo Apt/Moscow',''),('RU','SWT','Strzhewoi','Strzhewoi',''),('RU','SYR','Staraya Russa','Staraya Russa',''),('RU','SYZ','Syzran','Syzran',''),('RU','TAG','Taganrog','Taganrog',''),('RU','TAT','Tatishchevo','Tatishchevo',''),('RU','TAU','Tauisk','Tauisk',''),('RU','TBW','Tambov','Tambov',''),('RU','TDO','Trudfront','Trudfront',''),('RU','THK','Torzhok','Torzhok',''),('RU','TIK','Tikhvin','Tikhvin',''),('RU','TJM','Tyumen','Tyumen',''),('RU','TMR','Temryuk','Temryuk',''),('RU','TOF','Tomsk','Tomsk',''),('RU','TOX','Tobolsk','Tobolsk',''),('RU','TRK','Troitsk','Troitsk',''),('RU','TRO','Troitsk, Mordovia','Troitsk, Mordovia',''),('RU','TRR','Trifonov Ruchey','Trifonov Ruchey',''),('RU','TSO','Tosno','Tosno',''),('RU','TTI','Tolyatti','Tolyatti',''),('RU','TUA','Tuapse','Tuapse',''),('RU','TVE','Tverskoye','Tverskoye',''),('RU','TVK','Timashevsk','Timashevsk',''),('RU','TVR','Tver\'','Tver\'',''),('RU','TYA','Tula','Tula',''),('RU','TYD','Tynda','Tynda',''),('RU','TYL','Tyulkino','Tyulkino',''),('RU','UCT','Ukhta','Ukhta',''),('RU','UFA','Ufa','Ufa',''),('RU','UGC','Uglich','Uglich',''),('RU','UGL','Uglegorsk','Uglegorsk',''),('RU','UIK','Ust-Ilimsk','Ust-Ilimsk',''),('RU','UKK','Ust-Kamchatsk','Ust-Kamchatsk',''),('RU','UKX','Ust-Kut','Ust-Kut',''),('RU','ULY','Ulyanovsk (Simbirsk)','Ulyanovsk (Simbirsk)',''),('RU','UMB','Umba','Umba',''),('RU','URA','Ura-Guba','Ura-Guba',''),('RU','URJ','Uraj','Uraj',''),('RU','URS','Kursk','Kursk',''),('RU','USA','Usad','Usad',''),('RU','USK','Usinsk','Usinsk',''),('RU','USS','Ussuriysk','Ussuriysk',''),('RU','UUA','Bugulma','Bugulma',''),('RU','UUD','Ulan-Ude','Ulan-Ude',''),('RU','UUS','Yuzhno-Sakhalinsk','Yuzhno-Sakhalinsk',''),('RU','VAO','Vassilevsky Ostrov/St Petersburg','Vassilevsky Ostrov/St Petersburg',''),('RU','VAR','Varandey','Varandey',''),('RU','VCG','Vichuga','Vichuga',''),('RU','VGD','Vologda','Vologda',''),('RU','VIC','Vyshniy Volocheck','Vyshniy Volocheck',''),('RU','VIT','Vitino','Vitino',''),('RU','VKO','Vnukovo Apt/Moscow','Vnukovo Apt/Moscow',''),('RU','VKS','Voskresensk','Voskresensk',''),('RU','VKT','Vorkuta','Vorkuta',''),('RU','VLA','Vladikavkaz','Vladikavkaz',''),('RU','VLK','Volgodonsk','Volgodonsk',''),('RU','VLU','Velikiye Luki','Velikiye Luki',''),('RU','VLZ','Vetluzhskiy','Vetluzhskiy',''),('RU','VMR','Vladimir, Vladimirskaya','Vladimir, Vladimirskaya',''),('RU','VNN','Vanino','Vanino',''),('RU','VNP','Verkhnedneprovskiy','Verkhnedneprovskiy',''),('RU','VOG','Volgograd','Volgograd',''),('RU','VOS','Voskresensk','Voskresensk',''),('RU','VOZ','Voronezh','Voronezh',''),('RU','VPO','Vyatskiye Polyany','Vyatskiye Polyany',''),('RU','VRH','Verkhove','Verkhove',''),('RU','VSE','Vsevolozhsk','Vsevolozhsk',''),('RU','VTZ','Vityaz','Vityaz',''),('RU','VUS','Velikij Ustyug','Velikij Ustyug',''),('RU','VVO','Vladivostok','Vladivostok',''),('RU','VYA','Vyartsilya','Vyartsilya',''),('RU','VYG','Vyborg','Vyborg',''),('RU','VYK','Vyksa','Vyksa',''),('RU','VYP','Vostochniy, Port','Vostochniy, Port',''),('RU','VZA','Vyaz\'ma','Vyaz\'ma',''),('RU','VZB','Vozrozhdeniya, Bukhta','Vozrozhdeniya, Bukhta',''),('RU','VZH','Volzhsk','Volzhsk',''),('RU','YAB','Yagelnaya Bukhta','Yagelnaya Bukhta',''),('RU','YAG','Yagodnyy','Yagodnyy',''),('RU','YBE','Yelabuga','Yelabuga',''),('RU','YEF','Yefremov (Efremov)','Yefremov (Efremov)',''),('RU','YEK','Yekaterinburg (Ekaterinburg)','Yekaterinburg (Ekaterinburg)',''),('RU','YEY','Yeysk','Yeysk',''),('RU','YKS','Yakutsk','Yakutsk',''),('RU','YLT','Yelets','Yelets',''),('RU','ZAO','Zavyalova, O','Zavyalova, O',''),('RU','ZAR','Zarubino','Zarubino',''),('RU','ZAV','Zav\'yalovo','Zav\'yalovo',''),('RU','ZBK','Zabaikalsk','Zabaikalsk',''),('RU','ZDK','Zelenodol\'sk','Zelenodol\'sk',''),('RU','ZEM','Zeleniy Mys','Zeleniy Mys',''),('RU','ZHI','Zhirnovsk','Zhirnovsk',''),('RU','ZHL','Zheleznodorozhniy','Zheleznodorozhniy',''),('RU','ZKA','Zhukovka, Bryansk','Zhukovka, Bryansk',''),('RU','ZLY','Zlynka','Zlynka',''),('RU','ZPY','Zapolyarnyy','Zapolyarnyy',''),('RU','ZSY','Zhukovskiy','Zhukovskiy',''),('RU','ZTT','Zlatoust','Zlatoust',''),('RU','ZVK','Zmiyevka','Zmiyevka',''),('RU','ZYK','Zaraysk','Zaraysk',''),('RU','ZZO','Zheleznogorsk','Zheleznogorsk',''),('RW','','','',''),('RW','BTQ','Butare','Butare',''),('RW','GYI','Gisenyi','Gisenyi',''),('RW','KGL','Kigali','Kigali',''),('RW','KME','Kamembe','Kamembe',''),('RW','RHG','Ruhengeri','Ruhengeri',''),('SA','','','',''),('SA','ABT','Al-Baha','Al-Baha',''),('SA','AHA','Al Hada','Al Hada',''),('SA','AHB','Abha','Abha',''),('SA','AJF','Jouf','Jouf',''),('SA','AKH','Al Kharj','Al Kharj',''),('SA','ALK','Al Khobar','Al Khobar',''),('SA','AQI','Qaisumah','Qaisumah',''),('SA','ARR','Ar Rass','Ar Rass',''),('SA','AWI','Waisumah','Waisumah',''),('SA','BAH','Al Bahah','Al Bahah',''),('SA','BDN','Badanah','Badanah',''),('SA','BHH','Bisha','Bisha',''),('SA','DHA','Dhahran','Dhahran',''),('SA','DHU','Dhuba','Dhuba',''),('SA','DMM','Ad Dammam','Ad Dammam',''),('SA','EAM','Nejran','Nejran',''),('SA','EJH','Wedjh','Wedjh',''),('SA','ELQ','Gassim','Gassim',''),('SA','GIZ','Jizan','Jizan',''),('SA','HAS','Hail','Hail',''),('SA','HBT','Hafar al Batin','Hafar al Batin',''),('SA','HOF','Hofuf','Hofuf',''),('SA','JBI','Al Jubayl Industrial City','Al Jubayl Industrial City',''),('SA','JED','Jeddah','Jeddah',''),('SA','JIZ','Jizan','Jizan',''),('SA','JUB','Jubail','Jubail',''),('SA','JUT','Juaymah Terminal','Juaymah Terminal',''),('SA','KFH','King Fhad','King Fhad',''),('SA','KKH','King Khalid','King Khalid',''),('SA','KMX','Khamis Mushayt','Khamis Mushayt',''),('SA','LIT','Lith','Lith',''),('SA','MAK','Makkah','Makkah',''),('SA','MAN','Manailih','Manailih',''),('SA','MED','Madinah','Madinah',''),('SA','MJH','Majma','Majma',''),('SA','MUF','Manfouha','Manfouha',''),('SA','QAL','Qalsn','Qalsn',''),('SA','QTF','Qatif','Qatif',''),('SA','QUR','Qurayyah','Qurayyah',''),('SA','RAB','Rabigh','Rabigh',''),('SA','RAE','Arar','Arar',''),('SA','RAH','Rafha','Rafha',''),('SA','RAM','Ras al Mishab','Ras al Mishab',''),('SA','RAR','Ras al Khafji','Ras al Khafji',''),('SA','RTA','Ras Tanura','Ras Tanura',''),('SA','RUH','Riyadh','Riyadh',''),('SA','RYP','Riyadh Dry Port','Riyadh Dry Port',''),('SA','SAY','Sayhat','Sayhat',''),('SA','SHW','Sharurah','Sharurah',''),('SA','SUH','Salboukh','Salboukh',''),('SA','TIF','Taif','Taif',''),('SA','TUI','Turaif','Turaif',''),('SA','TUU','Tabuk','Tabuk',''),('SA','URY','Gurayat','Gurayat',''),('SA','UZH','Unayzah','Unayzah',''),('SA','VLA','Umm Lajj','Umm Lajj',''),('SA','WAE','Wadi ad Dawasir','Wadi ad Dawasir',''),('SA','YBI','Yanbu Industrial City','Yanbu Industrial City',''),('SA','YNB','Yanbu al-Bahr','Yanbu al-Bahr',''),('SA','ZUL','Zilfi','Zilfi',''),('SA','ZUY','Zulayfayn','Zulayfayn',''),('SB','','','',''),('SB','AFT','Afutara','Afutara',''),('SB','AKS','Auki, Malaita Is','Auki, Malaita Is',''),('SB','ALB','Allardyce Harbour, Sta Isabel Is','Allardyce Harbour, Sta Isabel Is',''),('SB','ANH','Anuha Island','Anuha Island',''),('SB','AOB','Aola Bay','Aola Bay',''),('SB','ATD','Ato\'ifi','Ato\'ifi',''),('SB','AVU','Avu Avu, Guadalcanal Is','Avu Avu, Guadalcanal Is',''),('SB','BAS','Balalai Island','Balalai Island',''),('SB','BNY','Bellona','Bellona',''),('SB','BPF','Batuna','Batuna',''),('SB','CHY','Choiseul Bay','Choiseul Bay',''),('SB','EGM','Seghe','Seghe',''),('SB','FRE','Fera Island','Fera Island',''),('SB','GEF','Geva','Geva',''),('SB','GTA','Nggatokae Island','Nggatokae Island',''),('SB','GZO','Gizo','Gizo',''),('SB','HIR','Honiara, Guadalcanal Is','Honiara, Guadalcanal Is',''),('SB','IRA','Kirakira, San Cristobal Is','Kirakira, San Cristobal Is',''),('SB','KGE','Kaghau Island','Kaghau Island',''),('SB','KUE','Kukundu','Kukundu',''),('SB','KWR','Kwai Harbour','Kwai Harbour',''),('SB','KWS','Kwailabesi','Kwailabesi',''),('SB','LEV','Lever Harbour','Lever Harbour',''),('SB','LOF','Lofung','Lofung',''),('SB','MBU','Mbambanakira, Guadalcanal Is','Mbambanakira, Guadalcanal Is',''),('SB','MNY','Mono','Mono',''),('SB','MUA','Munda, New Georgia','Munda, New Georgia',''),('SB','NEM','Nemba','Nemba',''),('SB','NNB','Santa Ana','Santa Ana',''),('SB','NOR','Noro, New Georgia','Noro, New Georgia',''),('SB','ONE','Onepusu, Malaita Island','Onepusu, Malaita Island',''),('SB','OTV','Ontong Java','Ontong Java',''),('SB','PRS','Parasi, Malaita Island','Parasi, Malaita Island',''),('SB','PSG','Pulisingau','Pulisingau',''),('SB','RBV','Ramata','Ramata',''),('SB','RIN','Ringgi Cove, Kolombangara','Ringgi Cove, Kolombangara',''),('SB','RNL','Rennell Island','Rennell Island',''),('SB','RRI','Barora Ite Island','Barora Ite Island',''),('SB','RUS','Marau Sound, Guadalcanal Is','Marau Sound, Guadalcanal Is',''),('SB','SCZ','Santa Cruz Is','Santa Cruz Is',''),('SB','SHH','Shortland Harbour','Shortland Harbour',''),('SB','SSG','Filuo','Filuo',''),('SB','SVY','Savo','Savo',''),('SB','TAA','Tarapaina','Tarapaina',''),('SB','TLG','Tulagi, Ngella','Tulagi, Ngella',''),('SB','VAO','Suavanao','Suavanao',''),('SB','VEV','Barakoma','Barakoma',''),('SB','VIU','Viru Harbour','Viru Harbour',''),('SB','XYA','Yandina, Russell Island','Yandina, Russell Island',''),('SC','','','',''),('SC','BDI','Bird Island','Bird Island',''),('SC','DEI','Denis Island','Denis Island',''),('SC','DES','Ile Desroches','Ile Desroches',''),('SC','FRK','Fregate','Fregate',''),('SC','MAW','Mahe','Mahe',''),('SC','POV','Port Victoria','Port Victoria',''),('SC','PRI','Praslin Island','Praslin Island',''),('SC','SEZ','Mahe Island Apt','Mahe Island Apt',''),('SD','','','',''),('SD','AAD','Ad Dabbah','Ad Dabbah',''),('SD','ATB','Atbara','Atbara',''),('SD','DNI','Wad Medani','Wad Medani',''),('SD','DNX','Dinder','Dinder',''),('SD','DOG','Dongola','Dongola',''),('SD','EBD','El Obeid','El Obeid',''),('SD','EDB','Eldebba','Eldebba',''),('SD','EGN','Geneina','Geneina',''),('SD','ELF','El Fasher','El Fasher',''),('SD','GBU','Khashm El Girba','Khashm El Girba',''),('SD','GSU','Gedaref','Gedaref',''),('SD','JUM','Juba','Juba',''),('SD','KRT','Khartoum','Khartoum',''),('SD','KSL','Kassala','Kassala',''),('SD','KST','Kosti','Kosti',''),('SD','MAK','Malakal','Malakal',''),('SD','MBH','Marsa Bashayer','Marsa Bashayer',''),('SD','MWE','Merowe','Merowe',''),('SD','NHF','New Halfa','New Halfa',''),('SD','NUD','En Nahud','En Nahud',''),('SD','PZU','Port Sudan','Port Sudan',''),('SD','RBK','Rumbek','Rumbek',''),('SD','RSS','Roseires','Roseires',''),('SD','SWA','Swakin','Swakin',''),('SD','UYL','Nyala','Nyala',''),('SD','WHF','Wadi Halfa','Wadi Halfa',''),('SD','WUU','Wau','Wau',''),('SE','','','',''),('SE','AAK','Akers Styckebruk','Akers Styckebruk','D'),('SE','AAR','Ar','Ar','I'),('SE','AAS','Aseda','Aseda','F'),('SE','ABI','Aby','Aby',''),('SE','ABS','Abisko','Abisko','BD'),('SE','ABY','Aneby','Aneby','F'),('SE','ADG','Arildslage','Arildslage','M'),('SE','AEN','Alvdalen','Alvdalen','W'),('SE','AGB','Agnesberg','Agnesberg','O'),('SE','AGE','Ange','Ange','Y'),('SE','AGH','Helsingborg-Angelholm Apt','Helsingborg-Angelholm Apt','M'),('SE','AGN','Alvangen','Alvangen','O'),('SE','AGO','Ago','Ago',''),('SE','AHR','Aha','Aha','AC'),('SE','AHT','Alghult','Alghult','G'),('SE','AHU','Ahus','Ahus','M'),('SE','AJG','Emmaljunga','Emmaljunga',''),('SE','AJR','Arvidsjaur','Arvidsjaur','BD'),('SE','AKA','Akersberga','Akersberga','AB'),('SE','AKP','Akarp','Akarp','M'),('SE','AKR','Ankarsrum','Ankarsrum','H'),('SE','ALA','Ala','Ala','X'),('SE','ALB','Alby','Alby','Y'),('SE','ALF','Alfredshem','Alfredshem','Y'),('SE','ALI','Alingsas','Alingsas','O'),('SE','ALM','Almhult','Almhult','G'),('SE','ALN','Alvenas','Alvenas','S'),('SE','ALS','Alvsjo/Stockholm','Alvsjo/Stockholm','AB'),('SE','ALV','Alvesta','Alvesta','G'),('SE','AMA','Amal','Amal','O'),('SE','ANG','Angelholm','Angelholm','M'),('SE','ANK','Ankarsvik','Ankarsvik','C'),('SE','ANN','Ann','Ann','Z'),('SE','ANP','Anderstorp','Anderstorp','F'),('SE','ARA','Arboga','Arboga','U'),('SE','ARB','Arbra','Arbra','X'),('SE','ARD','Arstadal','Arstadal','AB'),('SE','ARE','Are','Are','Z'),('SE','ARG','Arjeplog','Arjeplog','BD'),('SE','ARI','Arninge','Arninge','AB'),('SE','ARJ','Arjang','Arjang','O'),('SE','ARK','Arnoviken','Arnoviken','C'),('SE','ARL','Arlov','Arlov','M'),('SE','ARN','Arlanda Apt/Stockholm','Arlanda Apt/Stockholm','C'),('SE','ARS','Arsta/Stockholm','Arsta/Stockholm','AB'),('SE','ART','Arlandastad','Arlandastad','AB'),('SE','ARV','Arvika','Arvika','S'),('SE','ASA','Asarum','Asarum','K'),('SE','ASD','Askersund','Askersund','T'),('SE','ASE','Asensbruk','Asensbruk','O'),('SE','ASH','Ashammar','Ashammar','X'),('SE','ASK','Askloster','Askloster','N'),('SE','ASL','Andersloev','Andersloev','M'),('SE','AST','Astorp','Astorp','M'),('SE','ASU','Arkosund','Arkosund','E'),('SE','ATV','Atvidaberg','Atvidaberg','E'),('SE','AVE','Avesta','Avesta','W'),('SE','AVK','Almvik','Almvik',''),('SE','BAA','Balsta','Balsta','C'),('SE','BAC','Backviken','Backviken','M'),('SE','BAL','Ballingslov','Ballingslov','M'),('SE','BAR','Backhammar','Backhammar','S'),('SE','BAS','Bastad','Bastad','M'),('SE','BAT','Batskarsnas','Batskarsnas','BD'),('SE','BBE','Baberg','Baberg','O'),('SE','BBG','Blidsberg','Blidsberg','O'),('SE','BBH','Barsebackshamn','Barsebackshamn','M'),('SE','BCK','Bracke','Bracke','Z'),('SE','BDQ','Boda','Boda','H'),('SE','BDS','Bodafors','Bodafors','F'),('SE','BEA','Bergkvara','Bergkvara','H'),('SE','BER','Bergs oljehamn','Bergs oljehamn','AB'),('SE','BFS','Backfors','Backfors','AC'),('SE','BGA','Berga Orlogsskolor','Berga Orlogsskolor',''),('SE','BGO','Bagarmossen/Stockholm','Bagarmossen/Stockholm','AB'),('SE','BGS','Borgstena','Borgstena','O'),('SE','BHM','Bergshamra','Bergshamra','AB'),('SE','BIL','Billingsfors','Billingsfors','O'),('SE','BIM','Billesholm','Billesholm','M'),('SE','BJA','Bjarnum','Bjarnum','M'),('SE','BJK','Bjorklinge','Bjorklinge','C'),('SE','BJN','Bjorneborg','Bjorneborg','S'),('SE','BJR','Bjarred','Bjarred','M'),('SE','BJU','Bjuv','Bjuv','M'),('SE','BLA','Blankaholm','Blankaholm','H'),('SE','BLD','Bovallstrand','Bovallstrand','O'),('SE','BLE','Borlange','Borlange','W'),('SE','BLL','Bollebygd','Bollebygd','O'),('SE','BLO','Blomstermala','Blomstermala','H'),('SE','BLS','Bollnas','Bollnas','X'),('SE','BLV','Ballstaviken','Ballstaviken','AB'),('SE','BMA','Bromma Apt/Stockholm','Bromma Apt/Stockholm','AB'),('SE','BMH','Bramhult','Bramhult','O'),('SE','BND','Bankeryd','Bankeryd','F'),('SE','BNF','Brannfors','Brannfors','AC'),('SE','BNG','Bandhagen/Stockholm','Bandhagen/Stockholm','AB'),('SE','BOD','Boden','Boden','BD'),('SE','BOG','Borensberg','Borensberg','E'),('SE','BOH','Bohus','Bohus','O'),('SE','BOI','Boliden','Boliden','AC'),('SE','BOL','Bollstabruk','Bollstabruk','Y'),('SE','BOM','Borgholm','Borgholm','H'),('SE','BON','Borghamn','Borghamn','E'),('SE','BOS','Boras','Boras','O'),('SE','BOT','Bottnaryd','Bottnaryd','F'),('SE','BOX','Boxholm','Boxholm','E'),('SE','BPG','Bispgarden','Bispgarden','Z'),('SE','BRA','Bralanda','Bralanda','O'),('SE','BRD','Bredaryd','Bredaryd','F'),('SE','BRE','Bredviken','Bredviken',''),('SE','BRH','Brakne-Hoby','Brakne-Hoby','K'),('SE','BRM','Bromolla','Bromolla','M'),('SE','BRO','Brofjorden','Brofjorden','O'),('SE','BRT','Brottby','Brottby','AB'),('SE','BRX','Bro','Bro','AB'),('SE','BTA','Brastad','Brastad','O'),('SE','BTF','Bengtsfors','Bengtsfors','O'),('SE','BUK','Burtrask','Burtrask','AC'),('SE','BUR','Burea','Burea','AC'),('SE','BUV','Burgsvik','Burgsvik','I'),('SE','BVK','Braviken','Braviken','E'),('SE','BYS','Byske (Brannfors)','Byske (Brannfors)','AC'),('SE','BYU','Bygdsiljum','Bygdsiljum','AC'),('SE','BYX','Byxelkrok','Byxelkrok','H'),('SE','CHA','Charlottenberg','Charlottenberg','S'),('SE','DAL','Dals-Langed','Dals-Langed','O'),('SE','DAN','Dannemora','Dannemora','C'),('SE','DEG','Degerhamn','Degerhamn','H'),('SE','DEJ','Deje','Deje','S'),('SE','DEL','Delsbo','Delsbo','X'),('SE','DFO','Dalsjofors','Dalsjofors','O'),('SE','DFS','Degerfors','Degerfors','T'),('SE','DHN','Djurhamn','Djurhamn','AB'),('SE','DJN','Djuron','Djuron','E'),('SE','DJP','Djupvik','Djupvik','O'),('SE','DJU','Djurmo','Djurmo','W'),('SE','DLA','Dalaro','Dalaro','D'),('SE','DLB','Dalby','Dalby','M'),('SE','DLP','Dalstorp','Dalstorp','O'),('SE','DND','Danderyd','Danderyd','AB'),('SE','DNG','Dingle','Dingle','O'),('SE','DOM','Domsjo','Domsjo','Y'),('SE','DON','Donso','Donso','O'),('SE','DRT','Drottningholm','Drottningholm','AB'),('SE','DSE','Dvaersaett','Dvaersaett','Z'),('SE','DSM','Djursholm','Djursholm','AB'),('SE','DYN','Dynas','Dynas','Y'),('SE','ECK','Lackeby','Lackeby','H'),('SE','EDS','Edsbyn','Edsbyn','X'),('SE','EDZ','Ed','Ed','O'),('SE','EEN','Ekenassjon','Ekenassjon','F'),('SE','EKE','Ekero','Ekero','AB'),('SE','EKS','Eksjo','Eksjo','F'),('SE','EKT','Eskilstuna','Eskilstuna','D'),('SE','EMM','Emmaboda','Emmaboda','H'),('SE','ENA','Eneryda','Eneryda','G'),('SE','ENE','Enebyberg','Enebyberg','AB'),('SE','ENK','Enkoping','Enkoping','C'),('SE','ERI','Erikslund','Erikslund','Y'),('SE','ERS','Ersmark','Ersmark','AC'),('SE','ESL','Eslov','Eslov','M'),('SE','ESS','Essvik','Essvik','Y'),('SE','EVG','Sveg','Sveg','Z'),('SE','FAA','Fagersta','Fagersta','U'),('SE','FAE','Fargelanda','Fargelanda','O'),('SE','FAG','Falkenberg','Falkenberg','N'),('SE','FAK','Fagervik','Fagervik','X'),('SE','FAN','Falun','Falun','W'),('SE','FAR','Farjestaden','Farjestaden','H'),('SE','FBK','Fiskebackskil','Fiskebackskil','O'),('SE','FBO','Farbo','Farbo','H'),('SE','FBY','Floby','Floby','O'),('SE','FEL','Fellingsbro','Fellingsbro','T'),('SE','FEN','Fegen','Fegen','N'),('SE','FHD','Forsheda','Forsheda','F'),('SE','FIG','Figeholm','Figeholm','H'),('SE','FIL','Filipstad','Filipstad','S'),('SE','FIN','Finspang','Finspang','E'),('SE','FIS','Fiskeback','Fiskeback','O'),('SE','FJA','Fjallbacka','Fjallbacka','O'),('SE','FJC','Fjaras','Fjaras','N'),('SE','FKG','Falkoping','Falkoping','O'),('SE','FLE','Flen','Flen','D'),('SE','FLM','Flemingsberg/Stockholm','Flemingsberg/Stockholm','AB'),('SE','FLX','Flaxenvik','Flaxenvik',''),('SE','FOA','Forsbacka','Forsbacka','X'),('SE','FOM','Forserum','Forserum','F'),('SE','FOR','Forsmark','Forsmark','C'),('SE','FOS','Forshaga','Forshaga','S'),('SE','FRA','Frano','Frano','Y'),('SE','FRI','Fristad','Fristad','O'),('SE','FRO','Frovi','Frovi','T'),('SE','FRS','Fors','Fors','W'),('SE','FSA','Frillesaas','Frillesaas','N'),('SE','FSB','Falsterbo','Falsterbo','M'),('SE','FSD','Farosund','Farosund','I'),('SE','FTY','Fritsla','Fritsla','O'),('SE','FVK','Forsvik','Forsvik','O'),('SE','GAA','Granna','Granna','F'),('SE','GAD','Gaddviken','Gaddviken',''),('SE','GAM','Gamleby','Gamleby','H'),('SE','GAR','Garphyttan','Garphyttan','T'),('SE','GET','Getinge','Getinge','N'),('SE','GEV','Gallivare','Gallivare','BD'),('SE','GGE','Grangarde','Grangarde','W'),('SE','GGF','Gagnef','Gagnef','W'),('SE','GHR','Ganghester','Ganghester','O'),('SE','GIS','Gislaved','Gislaved','F'),('SE','GKS','Gustavsvik/Stockholm','Gustavsvik/Stockholm','AB'),('SE','GKV','Grankullaviken','Grankullaviken','H'),('SE','GLA','Glanshammar','Glanshammar','T'),('SE','GLI','Glimakra','Glimakra','M'),('SE','GML','Gemla','Gemla','G'),('SE','GMS','Grums','Grums','S'),('SE','GNA','Gnarp','Gnarp','X'),('SE','GNE','Gnesta','Gnesta','D'),('SE','GNO','Gnosjo','Gnosjo','F'),('SE','GOA','Gota','Gota','O'),('SE','GOE','Gotene','Gotene','O'),('SE','GOR','Gorsingeholm','Gorsingeholm','D'),('SE','GOT','Goteborg','Goteborg','O'),('SE','GRA','Grabo','Grabo','O'),('SE','GRD','Grundsund','Grundsund','O'),('SE','GRE','Grebbestad','Grebbestad','O'),('SE','GRH','Grisslehamn','Grisslehamn','AB'),('SE','GRI','Grimsas','Grimsas','O'),('SE','GRK','Grundvik','Grundvik',''),('SE','GRN','Grangesberg','Grangesberg','W'),('SE','GRP','Grastorp','Grastorp','O'),('SE','GRT','Grytgol','Grytgol','S'),('SE','GRU','Gruvon','Gruvon','S'),('SE','GRV','Grevie','Grevie','M'),('SE','GRY','Grycksbo','Grycksbo','W'),('SE','GUB','Gustavsberg','Gustavsberg','AB'),('SE','GUM','Gusum','Gusum','E'),('SE','GUN','Gunnebo','Gunnebo','E'),('SE','GUS','Gustavsvik','Gustavsvik','Y'),('SE','GVN','Gravarne','Gravarne','O'),('SE','GVX','Gavle','Gavle','X'),('SE','HAA','Haparanda','Haparanda','BD'),('SE','HAB','Habo','Habo','O'),('SE','HAD','Halmstad','Halmstad','N'),('SE','HAG','Hagen','Hagen','W'),('SE','HAH','Haraholmen','Haraholmen','BD'),('SE','HAK','Hallstavik','Hallstavik','AB'),('SE','HAL','Hallstahammar','Hallstahammar','U'),('SE','HAN','Hargshamn','Hargshamn','C'),('SE','HAR','Harspranget','Harspranget','BD'),('SE','HAS','Hallstanas','Hallstanas','Y'),('SE','HBA','Hisings Backa','Hisings Backa','O'),('SE','HBB','Holsbybrunn','Holsbybrunn','F'),('SE','HBG','Hamburgsund','Hamburgsund','O'),('SE','HBV','Hasselbyverket/Stockholm','Hasselbyverket/Stockholm','AB'),('SE','HED','Hedemora','Hedemora','W'),('SE','HEE','Hede','Hede','Z'),('SE','HEG','Heberg','Heberg','N'),('SE','HEJ','Herrljunga','Herrljunga','O'),('SE','HEL','Helsingborg','Helsingborg','M'),('SE','HER','Herrang','Herrang','AB'),('SE','HES','Hestra','Hestra','F'),('SE','HFS','Hagfors','Hagfors','S'),('SE','HGR','Hagersten/Stockholm','Hagersten/Stockholm','AB'),('SE','HGS','Hogsjo','Hogsjo','Y'),('SE','HIL','Hillerstorp','Hillerstorp','F'),('SE','HIT','Hittarp','Hittarp','M'),('SE','HJA','Hjarnarp','Hjarnarp','M'),('SE','HJD','Hjorted','Hjorted','H'),('SE','HJO','Hjo','Hjo','O'),('SE','HLD','Holmsund','Holmsund','AC'),('SE','HLF','Hultsfred','Hultsfred','H'),('SE','HLL','Hallefors','Hallefors','T'),('SE','HLN','Helgenas','Helgenas',''),('SE','HLO','Holo','Holo','AB'),('SE','HLS','Hallekis','Hallekis','O'),('SE','HMD','Hammerdal','Hammerdal','Z'),('SE','HMV','Hemavan','Hemavan','AC'),('SE','HNB','Horneborg','Horneborg',''),('SE','HND','Harnosand','Harnosand','Y'),('SE','HNE','Haninge','Haninge','D'),('SE','HNF','Hornefors','Hornefors','AC'),('SE','HNI','Haninge','Haninge','AB'),('SE','HNK','Hanaskog','Hanaskog','M'),('SE','HNO','Hono','Hono','O'),('SE','HOD','Horred','Horred','O'),('SE','HOE','Horby','Horby','M'),('SE','HOF','Hofors','Hofors','X'),('SE','HOG','Hoganas','Hoganas','M'),('SE','HOL','Holmsjo','Holmsjo','K'),('SE','HON','Honsater','Honsater','O'),('SE','HOO','Hoor','Hoor','M'),('SE','HOR','Hogsater','Hogsater','O'),('SE','HOV','Hovmantorp','Hovmantorp','G'),('SE','HRD','Harestad','Harestad','O'),('SE','HRN','Horndal','Horndal','W'),('SE','HRR','Hisings Karra/Goteborg','Hisings Karra/Goteborg','O'),('SE','HRS','Halleforsnas','Halleforsnas','D'),('SE','HSG','Hallsberg','Hallsberg','T'),('SE','HSM','Hassleholm','Hassleholm','M'),('SE','HSP','Hasslarp','Hasslarp','M'),('SE','HSQ','Huskvarna','Huskvarna','F'),('SE','HTM','Hjartum','Hjartum','O'),('SE','HUE','Huddinge','Huddinge','AB'),('SE','HUN','Hunnebostrand','Hunnebostrand','O'),('SE','HUS','Husum','Husum','Y'),('SE','HUV','Hudiksvall','Hudiksvall','X'),('SE','HVA','Hova','Hova','O'),('SE','HVD','Hastveda','Hastveda','M'),('SE','HYD','Hallaryd','Hallaryd','G'),('SE','HYL','Hyltebruk','Hyltebruk','F'),('SE','HYP','Hyppeln','Hyppeln','O'),('SE','HZS','Hovslatt','Hovslatt','F'),('SE','IDB','Idre','Idre','W'),('SE','IGG','Iggesund','Iggesund','X'),('SE','INS','Insjon','Insjon','W'),('SE','JAO','Jarbo','Jarbo','X'),('SE','JAR','Jarfalla','Jarfalla','AB'),('SE','JAT','Jatterson','Jatterson','H'),('SE','JHV','Johanneshov','Johanneshov','AB'),('SE','JKG','Jonkoping','Jonkoping','F'),('SE','JMJ','Jamjo','Jamjo','K'),('SE','JNA','Jorlanda','Jorlanda','O'),('SE','JOH','Johannedal','Johannedal',''),('SE','JON','Jonsered','Jonsered','O'),('SE','JOR','Jordbro','Jordbro','AB'),('SE','JUK','Jukkasjarvi','Jukkasjarvi','BD'),('SE','JUN','Junsele','Junsele','Y'),('SE','KAA','Karlskrona','Karlskrona','K'),('SE','KAD','Kallered','Kallered','O'),('SE','KAE','Kattilstorp','Kattilstorp','O'),('SE','KAG','Kage','Kage','AC'),('SE','KAK','Karlsvik','Karlsvik','X'),('SE','KAL','Kalmarsand','Kalmarsand','C'),('SE','KAM','Katrineholm','Katrineholm','D'),('SE','KAN','Karlshamn','Karlshamn','K'),('SE','KAO','Karo','Karo','C'),('SE','KAS','Karskar','Karskar','X'),('SE','KAT','Katthammarsvik','Katthammarsvik','I'),('SE','KAX','Kalix','Kalix','BD'),('SE','KBG','Karlsborg','Karlsborg','O'),('SE','KBK','Karlholmsbruk','Karlholmsbruk','C'),('SE','KBY','Kallby','Kallby','O'),('SE','KGG','Kagghamra','Kagghamra',''),('SE','KGR','Kungsor','Kungsor','U'),('SE','KHN','Kristinehamn','Kristinehamn','S'),('SE','KIA','Kinna','Kinna','O'),('SE','KID','Kristianstad','Kristianstad','M'),('SE','KIL','Kil','Kil','S'),('SE','KIN','Kinnarp','Kinnarp','O'),('SE','KIS','Kista','Kista','AB'),('SE','KKO','Krokom','Krokom','Z'),('SE','KKS','Kyrkesund','Kyrkesund','O'),('SE','KLA','Klavrestrom','Klavrestrom','G'),('SE','KLI','Klintehamn','Klintehamn','I'),('SE','KLP','Klippan','Klippan','M'),('SE','KLR','Kalmar','Kalmar','H'),('SE','KLV','Kullavik','Kullavik','N'),('SE','KMH','Kopmanholmen','Kopmanholmen','Y'),('SE','KNA','Knivsta','Knivsta','C'),('SE','KNN','Kungsangen','Kungsangen','AB'),('SE','KOA','Kolsva','Kolsva','U'),('SE','KOG','Koping','Koping','U'),('SE','KOL','Kolback','Kolback','U'),('SE','KOR','Korsberga','Korsberga','F'),('SE','KOS','Korsnas','Korsnas','W'),('SE','KPA','Karpalund','Karpalund','M'),('SE','KPH','Kappelshamn','Kappelshamn','I'),('SE','KPO','Kopparberg','Kopparberg','T'),('SE','KPS','Kapellskar','Kapellskar','AB'),('SE','KRD','Kagerod','Kagerod','M'),('SE','KRF','Kramfors','Kramfors','Y'),('SE','KRH','Karehamn','Karehamn','H'),('SE','KRN','Kiruna','Kiruna','BD'),('SE','KRY','Krylbo','Krylbo','W'),('SE','KSA','Kisa','Kisa','E'),('SE','KSD','Karlstad','Karlstad','S'),('SE','KSK','Karlskoga','Karlskoga','T'),('SE','KSL','Koskullskulle','Koskullskulle','BD'),('SE','KSP','Klagstorp','Klagstorp','M'),('SE','KST','Kosta','Kosta','G'),('SE','KUA','Kungsbacka','Kungsbacka','N'),('SE','KUB','Kubikenborg','Kubikenborg','X'),('SE','KUM','Kumla','Kumla','T'),('SE','KUN','Kungshamn','Kungshamn','O'),('SE','KUV','Kungalv','Kungalv','O'),('SE','KVA','Kvarnholmen','Kvarnholmen','AB'),('SE','KVH','Kopparverkshamnen','Kopparverkshamnen','M'),('SE','KVL','Kavlinge','Kavlinge','M'),('SE','KVM','Kvanum','Kvanum','O'),('SE','KVN','Kvarnsveden','Kvarnsveden','W'),('SE','KXH','Kaxholmen','Kaxholmen','F'),('SE','KXV','Karlsborg Axelvik','Karlsborg Axelvik','AC'),('SE','KYR','Kyrkebyn','Kyrkebyn','S'),('SE','LAA','Landskrona','Landskrona','M'),('SE','LAH','Laholm','Laholm','N'),('SE','LAM','Lammhult','Lammhult','F'),('SE','LAN','Langasjo','Langasjo','F'),('SE','LAO','Landsbro','Landsbro','F'),('SE','LAX','Laxa','Laxa','T'),('SE','LBY','Lyckeby','Lyckeby','K'),('SE','LDG','Lindesberg','Lindesberg','T'),('SE','LDK','Lidkoping','Lidkoping','O'),('SE','LDN','Lofsdalen','Lofsdalen','Z'),('SE','LDO','Lodose','Lodose','O'),('SE','LDV','Lenhovda','Lenhovda','G'),('SE','LED','Lilla Edet','Lilla Edet','O'),('SE','LEK','Leksand','Leksand','W'),('SE','LEO','Lessebo','Lessebo','G'),('SE','LER','Lerum','Lerum','O'),('SE','LES','Lesjofors','Lesjofors','S'),('SE','LGN','Lagan','Lagan','G'),('SE','LHM','Ljusfallshammar','Ljusfallshammar','E'),('SE','LIL','Liljendal','Liljendal','S'),('SE','LIM','Limhamn','Limhamn','M'),('SE','LIO','Lidingo','Lidingo','AB'),('SE','LIS','Linanas','Linanas','AB'),('SE','LIT','Lidhult','Lidhult','G'),('SE','LJB','Ljungsbro','Ljungsbro','E'),('SE','LJL','Ljusdal','Ljusdal','X'),('SE','LJO','Ljustero','Ljustero','AB'),('SE','LJU','Ljusne','Ljusne','X'),('SE','LJY','Ljungby','Ljungby','G'),('SE','LLA','Lulea','Lulea','BD'),('SE','LMD','Limmared','Limmared','O'),('SE','LNG','Langshyttan','Langshyttan','W'),('SE','LOF','Loftahammar','Loftahammar','H'),('SE','LOM','Lomma','Lomma','M'),('SE','LOT','Loten','Loten',''),('SE','LOU','Loudden/Stockholm','Loudden/Stockholm','AB'),('SE','LPI','Linkoping','Linkoping','E'),('SE','LUD','Lund','Lund','M'),('SE','LUG','Lugnvik','Lugnvik','Y'),('SE','LUN','Lovholmen','Lovholmen','BD'),('SE','LUV','Ludvika','Ludvika','W'),('SE','LVR','Lovanger','Lovanger','AC'),('SE','LYC','Lycksele','Lycksele','AC'),('SE','LYS','Lysekil','Lysekil','O'),('SE','MAD','Mariestad','Mariestad','O'),('SE','MAN','Marsviken','Marsviken','D'),('SE','MAP','Mantorp','Mantorp','E'),('SE','MAR','Marieberg','Marieberg',''),('SE','MAT','Matfors','Matfors','Y'),('SE','MBT','Malmberget','Malmberget','BD'),('SE','MDM','Munkedalshamn','Munkedalshamn','O'),('SE','MEL','Mellerud','Mellerud','O'),('SE','MEM','Mem','Mem','E'),('SE','MHA','Moheda','Moheda','G'),('SE','MHM','Moholm','Moholm','O'),('SE','MJB','Mjolby','Mjolby','E'),('SE','MLJ','Munka-Ljungby','Munka-Ljungby','M'),('SE','MLO','Mollosund','Mollosund','O'),('SE','MLS','Mellansel','Mellansel','Y'),('SE','MLU','Malung','Malung','W'),('SE','MLY','Moelnlycke','Moelnlycke','O'),('SE','MMA','Malmo','Malmo','M'),('SE','MND','Molndal','Molndal','O'),('SE','MNF','Munkfors','Munkfors','S'),('SE','MOC','Mockfjard','Mockfjard','W'),('SE','MOE','Molnlycke','Molnlycke','O'),('SE','MOF','Mortfors','Mortfors','H'),('SE','MOL','Molkom','Molkom','S'),('SE','MOM','Morrum','Morrum','K'),('SE','MON','Monsteras','Monsteras','H'),('SE','MOO','Mo','Mo','Y'),('SE','MOP','Morarp','Morarp','M'),('SE','MOR','Morbylanga','Morbylanga','H'),('SE','MOT','Motala','Motala','E'),('SE','MRA','Mora','Mora','W'),('SE','MRF','Mariefred','Mariefred','D'),('SE','MRH','Marieholm','Marieholm','M'),('SE','MRK','Markaryd','Markaryd','G'),('SE','MSD','Marstrand','Marstrand','O'),('SE','MSK','Musko','Musko','AB'),('SE','MST','Marsta','Marsta','AB'),('SE','MTM','Mattmar','Mattmar','Z'),('SE','MUK','Munkedal','Munkedal','O'),('SE','MUL','Mullsjo','Mullsjo','O'),('SE','MUN','Munksund','Munksund','BD'),('SE','MVK','Maryvik','Maryvik',''),('SE','NAC','Nacka','Nacka','AB'),('SE','NAS','Nas','Nas','W'),('SE','NAV','Navekvarn','Navekvarn','D'),('SE','NBG','Norberg','Norberg','W'),('SE','NCS','Nacka Strand','Nacka Strand','AB'),('SE','NDE','Nodinge','Nodinge','O'),('SE','NGV','Nykvarn','Nykvarn','AB'),('SE','NHN','Nyhamn','Nyhamn','X'),('SE','NHR','Norrahammar','Norrahammar','F'),('SE','NJA','Norrbottens Jarnverk-SSAB','Norrbottens Jarnverk-SSAB','BD'),('SE','NML','Nymala','Nymala','H'),('SE','NOA','Nora','Nora','T'),('SE','NOE','Norrtalje','Norrtalje','AB'),('SE','NOG','Nordmaling','Nordmaling','AC'),('SE','NOJ','Norsjo','Norsjo','AC'),('SE','NOL','Nol (ports)','Nol (ports)','O'),('SE','NOR','Norrbyskar','Norrbyskar','Y'),('SE','NOT','Norrsundet','Norrsundet','X'),('SE','NRH','Norrhult','Norrhult','H'),('SE','NRK','Norrkoping','Norrkoping','E'),('SE','NRS','Norsborg','Norsborg','D'),('SE','NSG','Norsborg','Norsborg','AB'),('SE','NSJ','Nassjo','Nassjo','F'),('SE','NSO','Nossebro','Nossebro','O'),('SE','NTY','Naettraby','Naettraby','K'),('SE','NVK','Nasviken','Nasviken','Y'),('SE','NYB','Nybro','Nybro','H'),('SE','NYM','Nymolla','Nymolla','M'),('SE','NYN','Nynashamn','Nynashamn','AB'),('SE','NYO','Nykoping','Nykoping','D'),('SE','NYP','Nyvarp','Nyvarp',''),('SE','OAX','Oaxen','Oaxen','D'),('SE','OBB','Obbola','Obbola','AC'),('SE','OCK','Ockelbo','Ockelbo','X'),('SE','OCO','Ockero','Ockero','O'),('SE','ODE','Odeshog','Odeshog','E'),('SE','OEM','Overum','Overum','H'),('SE','OEN','On','On','C'),('SE','OER','Ornskoldsvik','Ornskoldsvik','Y'),('SE','OEV','Overkalix','Overkalix','BD'),('SE','OFS','Orrefors','Orrefors','H'),('SE','OGR','Oregrund','Oregrund','C'),('SE','OLO','Olofstrom','Olofstrom','K'),('SE','ORB','Orebro','Orebro','T'),('SE','ORK','Orkelljunga','Orkelljunga','M'),('SE','ORS','Orsa','Orsa','W'),('SE','ORT','Ortviken','Ortviken','Y'),('SE','ORV','Orviken','Orviken','AC'),('SE','OSB','Osby','Osby','M'),('SE','OSD','Ostersund','Ostersund','Z'),('SE','OSH','Osthammar','Osthammar','C'),('SE','OSK','Oskarshamn','Oskarshamn','H'),('SE','OSO','Osmo','Osmo','AB'),('SE','OST','Ostrand','Ostrand','X'),('SE','OSV','Ostra Sonnarslov','Ostra Sonnarslov','M'),('SE','OTT','Otterbacken','Otterbacken','O'),('SE','OVL','Overlida','Overlida','O'),('SE','OVN','Oviken','Oviken','Z'),('SE','OXE','Oxelosund','Oxelosund','D'),('SE','PAR','Partille','Partille','O'),('SE','PAS','Paskallavik','Paskallavik','H'),('SE','PIT','Pitea','Pitea','BD'),('SE','PJA','Pajala','Pajala','AC'),('SE','PPK','Perstorp','Perstorp','M'),('SE','PSO','Palsboda','Palsboda','T'),('SE','RAA','Raa','Raa','M'),('SE','RAM','Ramvik','Ramvik','Y'),('SE','RAN','Ramnas','Ramnas','U'),('SE','RBY','Ronnebyhamn','Ronnebyhamn','K'),('SE','REP','Reftele','Reftele','F'),('SE','RIM','Rimbo','Rimbo','AB'),('SE','RNB','Ronneby','Ronneby','K'),('SE','RNG','Ronnang','Ronnang','O'),('SE','RNH','Ronehamn','Ronehamn','I'),('SE','RNS','Rottneros','Rottneros','S'),('SE','ROE','Rone','Rone','I'),('SE','ROR','Ronnskar','Ronnskar','X'),('SE','ROS','Rosersberg','Rosersberg','AB'),('SE','ROT','Rotebro','Rotebro','AB'),('SE','ROV','Ronnskarsverken','Ronnskarsverken','X'),('SE','RST','Ransta','Ransta','U'),('SE','RUN','Runsten','Runsten','H'),('SE','RUR','Runmaro','Runmaro','AB'),('SE','RUV','Rundvik','Rundvik','AC'),('SE','RVK','Rattvik','Rattvik','W'),('SE','RYD','Rydsgard','Rydsgard','M'),('SE','RYM','Rydaholm','Rydaholm','F'),('SE','RYZ','Ryd','Ryd','G'),('SE','SAE','Sandarne','Sandarne','X'),('SE','SAF','Saffle','Saffle','S'),('SE','SAK','Sandvik','Sandvik',''),('SE','SAL','Sala','Sala','U'),('SE','SAN','Sandviken','Sandviken','X'),('SE','SAR','Sater','Sater','W'),('SE','SBB','Saltsjo-Boo','Saltsjo-Boo','AB'),('SE','SBN','Saltsjobaden','Saltsjobaden','D'),('SE','SBO','Sjobo','Sjobo','M'),('SE','SBV','Satra Brunn','Satra Brunn','U'),('SE','SDL','Sundsvall','Sundsvall','Y'),('SE','SDR','Soderfors','Soderfors','X'),('SE','SEA','Svedala','Svedala','M'),('SE','SES','Seskaro','Seskaro','BD'),('SE','SFS','Storfors','Storfors','S'),('SE','SFT','Skelleftea','Skelleftea','AC'),('SE','SGM','Skagshamn','Skagshamn','Y'),('SE','SGT','Sigtuna','Sigtuna','AB'),('SE','SGZ','Skogas','Skogas','AB'),('SE','SIK','Sikea','Sikea','AC'),('SE','SIM','Simrishamn','Simrishamn','M'),('SE','SJA','Svenljunga','Svenljunga','O'),('SE','SJQ','Savsjo','Savsjo','F'),('SE','SKA','Skapafors','Skapafors','O'),('SE','SKB','Skarblacka','Skarblacka','E'),('SE','SKE','Skelleftehamn','Skelleftehamn','AC'),('SE','SKG','Skanninge','Skanninge','E'),('SE','SKH','Skarholmen/Stockholm','Skarholmen/Stockholm','AB'),('SE','SKI','Skillingaryd','Skillingaryd','F'),('SE','SKK','Skonvik','Skonvik','Z'),('SE','SKL','Skalhamn','Skalhamn','O'),('SE','SKM','Skarhamn','Skarhamn','O'),('SE','SKN','Skuthamn','Skuthamn','BD'),('SE','SKO','Skoghall','Skoghall','S'),('SE','SKR','Skredsvik','Skredsvik','O'),('SE','SKT','Skattkarr','Skattkarr','S'),('SE','SKU','Skurup','Skurup','M'),('SE','SKV','Skovde','Skovde','O'),('SE','SKZ','Skene','Skene','O'),('SE','SLF','Solleftea','Solleftea','Y'),('SE','SLG','Sloinge','Sloinge','N'),('SE','SLI','Slite','Slite','I'),('SE','SLN','Solna','Solna','AB'),('SE','SMA','Smalandsstenar','Smalandsstenar','F'),('SE','SMD','Stromstad','Stromstad','O'),('SE','SME','Smedjebacken','Smedjebacken','W'),('SE','SMO','Smogen','Smogen','O'),('SE','SMS','Salmis','Salmis','BD'),('SE','SNA','Svangsta','Svangsta','K'),('SE','SNN','Sennan','Sennan','N'),('SE','SNY','Sundby','Sundby','D'),('SE','SOA','Sollentuna','Sollentuna','AB'),('SE','SOE','Sodertalje','Sodertalje','AB'),('SE','SOG','Soderkoping','Soderkoping','E'),('SE','SOK','Storvik','Storvik','X'),('SE','SOL','Solvesborg','Solvesborg','K'),('SE','SOO','Soderhamn','Soderhamn','X'),('SE','SOR','Soraker','Soraker','Y'),('SE','SPA','Spanga','Spanga','AB'),('SE','SPG','Skarplinge','Skarplinge','C'),('SE','SPL','Skepplanda','Skepplanda','O'),('SE','SPR','Sprangsviken','Sprangsviken','Y'),('SE','SRA','Skara','Skara','O'),('SE','SRU','Sorunda','Sorunda','AB'),('SE','SSD','Stromsund','Stromsund','Z'),('SE','SSG','Skinnskatteberg','Skinnskatteberg','U'),('SE','SSL','Sosdala','Sosdala','M'),('SE','SSO','Stensjo','Stensjo','AC'),('SE','SSR','Skutskar','Skutskar','C'),('SE','STA','Stocka','Stocka','Y'),('SE','STD','Stalldalen','Stalldalen','T'),('SE','STE','Stenungsund','Stenungsund','O'),('SE','STG','Stigtomta','Stigtomta','D'),('SE','STK','Stockvik','Stockvik','Y'),('SE','STL','Saltkallan','Saltkallan','O'),('SE','STN','Storlien','Storlien','Z'),('SE','STO','Stockholm','Stockholm','AB'),('SE','STP','Staffanstorp','Staffanstorp','M'),('SE','STQ','Strangnas','Strangnas','D'),('SE','STS','Stromsnasbruk','Stromsnasbruk','G'),('SE','STU','Stugsund','Stugsund','X'),('SE','STV','Stora Vika','Stora Vika','AB'),('SE','STZ','Skultuna','Skultuna','U'),('SE','SUD','Stocksund','Stocksund','AB'),('SE','SUE','Sunne','Sunne','S'),('SE','SUG','Sundbyberg','Sundbyberg','AB'),('SE','SUH','Surahammar','Surahammar','U'),('SE','SUN','Sund','Sund',''),('SE','SUR','Surte','Surte','O'),('SE','SUS','Storugns','Storugns','I'),('SE','SVD','Silverdalen','Silverdalen','H'),('SE','SVI','Svinesund','Svinesund','O'),('SE','SVK','Svartvik','Svartvik','X'),('SE','SVO','Svardsjo','Svardsjo','W'),('SE','SVR','Savar','Savar','AC'),('SE','SVX','Svano','Svano','Y'),('SE','SYS','Syssleback','Syssleback','S'),('SE','TAE','Tarnaby','Tarnaby','AC'),('SE','TAG','Tangaberg','Tangaberg','N'),('SE','TAN','Tanumshede','Tanumshede','O'),('SE','TAO','Tranemo','Tranemo','O'),('SE','TBO','Tobo','Tobo','C'),('SE','TBY','Taby','Taby','AB'),('SE','TEG','Taberg','Taberg','F'),('SE','THN','Trollhattan','Trollhattan','O'),('SE','THR','Torpshammar','Torpshammar','Y'),('SE','TIB','Tibro','Tibro','O'),('SE','TID','Tidaholm','Tidaholm','O'),('SE','TIE','Tierp','Tierp','C'),('SE','TIM','Timra','Timra','Y'),('SE','TIN','Tingsryd','Tingsryd','G'),('SE','TJP','Tjornarp','Tjornarp','M'),('SE','TKF','Tocksfors','Tocksfors','S'),('SE','TLL','Tollarp','Tollarp','M'),('SE','TNH','Tenhult','Tenhult','F'),('SE','TNS','Tranas','Tranas','F'),('SE','TOA','Torshalla','Torshalla','D'),('SE','TOB','Toreboda','Toreboda','O'),('SE','TOE','Tore','Tore','BD'),('SE','TOM','Tomelilla','Tomelilla','M'),('SE','TOP','Torup','Torup','N'),('SE','TOR','Torsas','Torsas','H'),('SE','TOV','Torekov','Torekov','M'),('SE','TRA','Trangsviken','Trangsviken','Z'),('SE','TRD','Traryd','Traryd','G'),('SE','TRG','Trelleborg','Trelleborg','M'),('SE','TRL','Torslanda','Torslanda','O'),('SE','TRR','Travad','Travad','O'),('SE','TRS','Trosa','Trosa','D'),('SE','TSB','Tagsjoberg','Tagsjoberg','Y'),('SE','TSO','Torso','Torso','K'),('SE','TTD','Tomtbod','Tomtbod','I'),('SE','TUL','Tungelsta','Tungelsta','AB'),('SE','TUM','Tumba','Tumba','AB'),('SE','TUN','Tunadal','Tunadal','Y'),('SE','TVA','Tvaaker','Tvaaker',''),('SE','TVK','Torsvik','Torsvik','F'),('SE','TYF','Torsby','Torsby','S'),('SE','TYG','Tygelsjo','Tygelsjo','M'),('SE','TYN','Tyngsjo','Tyngsjo','W'),('SE','TYR','Tyringe','Tyringe','M'),('SE','TYS','Tyreso','Tyreso','AB'),('SE','UDD','Uddevalla','Uddevalla','O'),('SE','UGG','Ugglarp','Ugglarp','N'),('SE','UGN','Ulebergshamn','Ulebergshamn','O'),('SE','ULD','Ullared','Ullared','N'),('SE','ULF','Ulfvik','Ulfvik',''),('SE','ULR','Ulricehamn','Ulricehamn','O'),('SE','UME','Umea','Umea','AC'),('SE','UND','Underas','Underas',''),('SE','UPL','Upplands-Vasby','Upplands-Vasby','AB'),('SE','UPP','Uppsala','Uppsala','C'),('SE','URD','Unnaryd','Unnaryd','N'),('SE','URS','Ursviken','Ursviken','AC'),('SE','UTA','Utansjo','Utansjo','Y'),('SE','VAA','Valberg','Valberg','S'),('SE','VAD','Vadstena','Vadstena','E'),('SE','VAG','Varberg','Varberg','N'),('SE','VAJ','Vaja','Vaja','Y'),('SE','VAK','Valdemarsvik','Valdemarsvik','E'),('SE','VAL','Vallvik','Vallvik','X'),('SE','VAN','Vanersborg','Vanersborg','O'),('SE','VAO','Vansbro','Vansbro','W'),('SE','VAR','Varnamo','Varnamo','F'),('SE','VAX','Vara','Vara','O'),('SE','VAY','Vallingby','Vallingby','AB'),('SE','VBC','Varobacka','Varobacka','N'),('SE','VBY','Visby','Visby','I'),('SE','VDS','Vaderstad','Vaderstad','E'),('SE','VEL','Vellinge','Vellinge','M'),('SE','VER','Verkeback','Verkeback','H'),('SE','VFA','Vastra Frolunda','Vastra Frolunda','O'),('SE','VGD','Vaggeryd','Vaggeryd','F'),('SE','VGN','Vargon','Vargon','O'),('SE','VGO','Vrango','Vrango','O'),('SE','VHD','Vagnharad','Vagnharad','D'),('SE','VHE','Vasterhaninge','Vasterhaninge','AB'),('SE','VHM','Vilhelmina','Vilhelmina','AC'),('SE','VIA','Vingaker','Vingaker','D'),('SE','VIK','Vikmanshyttan','Vikmanshyttan','W'),('SE','VIM','Vimmerby','Vimmerby','H'),('SE','VIN','Vindeln','Vindeln','BD'),('SE','VIO','Virsbo Bruk','Virsbo Bruk','U'),('SE','VIR','Virserum','Virserum','H'),('SE','VIS','Vinslov','Vinslov','M'),('SE','VIT','Vittaryd','Vittaryd','G'),('SE','VIV','Vivstavarv','Vivstavarv','X'),('SE','VKF','Viskafors','Viskafors','O'),('SE','VLA','Vasterlanda','Vasterlanda','O'),('SE','VLB','Valbo','Valbo','X'),('SE','VLN','Vislanda','Vislanda','G'),('SE','VRB','Varby','Varby','AB'),('SE','VRG','Vargarda','Vargarda','O'),('SE','VRM','Varmdo','Varmdo','AB'),('SE','VSJ','Vittsjo','Vittsjo','M'),('SE','VST','Vasteras','Vasteras','U'),('SE','VTA','Vallentuna','Vallentuna','AB'),('SE','VTL','Vetlanda','Vetlanda','F'),('SE','VVK','Vastervik','Vastervik','H'),('SE','VXH','Vaxholm','Vaxholm','AB'),('SE','VXO','Vaxjo','Vaxjo','G'),('SE','VXT','Vaxtorp','Vaxtorp','N'),('SE','WAL','Wallhamn','Wallhamn','O'),('SE','YST','Ystad','Ystad','M'),('SG','','','',''),('SG','AYC','Pulan Ayer Chawan','Pulan Ayer Chawan',''),('SG','JUR','Jurong/Singapore','Jurong/Singapore',''),('SG','KEP','Keppel Wharves','Keppel Wharves',''),('SG','PAP','Pasir Panjang Wharves','Pasir Panjang Wharves',''),('SG','PUB','Pulau Bukom','Pulau Bukom',''),('SG','SCT','Singapore Container Terminal','Singapore Container Terminal',''),('SG','SEB','Pulau Sebarok','Pulau Sebarok',''),('SG','SEM','Sembawang Port','Sembawang Port',''),('SG','SIN','Singapore','Singapore',''),('SG','SLT','Seletar','Seletar',''),('SG','TAY','Telok Ayer Basin','Telok Ayer Basin',''),('SG','TGA','Tengah','Tengah',''),('SG','TPG','Tanjong Pagar','Tanjong Pagar',''),('SG','TPN','Tanjong Penjuru','Tanjong Penjuru',''),('SG','WDL','Woodlands','Woodlands',''),('SH','','','',''),('SH','ASC','Ascension','Ascension',''),('SH','ASI','Georgetown','Georgetown',''),('SH','SHN','Jamestown','Jamestown',''),('SH','TDC','Tristan da Cunha','Tristan da Cunha',''),('SI','','','',''),('SI','AJD','Ajdovscina','Ajdovscina',''),('SI','ANH','Anhovo','Anhovo',''),('SI','BLE','Bled','Bled',''),('SI','BNG','Begunje na Gorenjskem','Begunje na Gorenjskem',''),('SI','BVC','Bovec','Bovec',''),('SI','CJE','Celje','Celje',''),('SI','CKC','Cerknica','Cerknica',''),('SI','CRE','Crnice','Crnice',''),('SI','DZE','Domzale','Domzale',''),('SI','FRA','Fram','Fram',''),('SI','GSZ','Gorenja Straza','Gorenja Straza',''),('SI','IZO','Izola','Izola',''),('SI','JCE','Jesenice','Jesenice',''),('SI','KCV','Kocevje','Kocevje',''),('SI','KNK','Kamnik','Kamnik',''),('SI','KOP','Koper','Koper',''),('SI','KRJ','Kranj','Kranj',''),('SI','KST','Kostanjevica na Krki','Kostanjevica na Krki',''),('SI','LJR','Ljutomer','Ljutomer',''),('SI','LJU','Ljubljana','Ljubljana',''),('SI','LOG','Logatec','Logatec',''),('SI','LVS','Lenart v Slovenskih Goricah','Lenart v Slovenskih Goricah',''),('SI','MBX','Maribor','Maribor',''),('SI','MDE','Medvode','Medvode',''),('SI','MUS','Murska Sobota','Murska Sobota',''),('SI','MZA','Mezica','Mezica',''),('SI','NKO','Naklo','Naklo',''),('SI','NMO','Novo Mesto','Novo Mesto',''),('SI','NOG','Nova Gorica','Nova Gorica',''),('SI','ORZ','Ormoz','Ormoz',''),('SI','PIR','Piran','Piran',''),('SI','POS','Postojna','Postojna',''),('SI','POW','Portoroz','Portoroz',''),('SI','PTV','Petrovce','Petrovce',''),('SI','RNA','Ribnica','Ribnica',''),('SI','RNK','Ravne na Koroskem','Ravne na Koroskem',''),('SI','RSA','Rogaska Slatina','Rogaska Slatina',''),('SI','SBA','Slovenska Bistrica','Slovenska Bistrica',''),('SI','SLG','Slovenj Gradec','Slovenj Gradec',''),('SI','SLK','Slovenske Konjice','Slovenske Konjice',''),('SI','SZA','Sezana','Sezana',''),('SI','TRZ','Trzin','Trzin',''),('SI','TZI','Trzic','Trzic',''),('SI','VEL','Velenje','Velenje',''),('SI','VRH','Vrhnika','Vrhnika',''),('SI','ZAL','Zalec','Zalec',''),('SI','ZRE','Zrece','Zrece',''),('SJ','','','',''),('SJ','BAR','Barentsburg','Barentsburg',''),('SJ','LYR','Longyearbyen','Longyearbyen',''),('SJ','NYA','Ny-Alesund','Ny-Alesund',''),('SJ','SVE','Sveagruva','Sveagruva',''),('SK','','','',''),('SK','BAA','Devinska Nova Ves/Bratislava','Devinska Nova Ves/Bratislava',''),('SK','BAB','Bratislava Port','Bratislava Port',''),('SK','BBY','Banska Bystrica','Banska Bystrica',''),('SK','BCA','Bytca','Bytca',''),('SK','BDM','Budmerice','Budmerice',''),('SK','BDV','Bardejov','Bardejov',''),('SK','BEC','Becherov','Becherov',''),('SK','BEL','Belusa','Belusa',''),('SK','BNB','Banovce nad Bebravou','Banovce nad Bebravou',''),('SK','BOJ','Bojnice','Bojnice',''),('SK','BOS','Bosany','Bosany',''),('SK','BRO','Brodske','Brodske',''),('SK','BRP','Petrzalka/Bratislava','Petrzalka/Bratislava',''),('SK','BTS','Bratislava','Bratislava',''),('SK','CAD','Cadca','Cadca',''),('SK','CAN','Cana','Cana',''),('SK','CEK','Cerveny Kamen','Cerveny Kamen',''),('SK','CNT','Cierna nad Tisou','Cierna nad Tisou',''),('SK','DBR','Dobra','Dobra',''),('SK','DJA','Dunajska Streda','Dunajska Streda',''),('SK','DNV','Dubnica nad Vahom','Dubnica nad Vahom',''),('SK','DOK','Dolny Kubin','Dolny Kubin',''),('SK','DOM','Domica','Domica',''),('SK','DOV','Dolne Vestenice','Dolne Vestenice',''),('SK','DRI','Drietoma','Drietoma',''),('SK','DTA','Detva','Detva',''),('SK','DZI','Dvory nad Zitavou','Dvory nad Zitavou',''),('SK','FIA','Filakovo','Filakovo',''),('SK','GEM','Gemerska Horka','Gemerska Horka',''),('SK','GLA','Gelnica','Gelnica',''),('SK','GLT','Galanta','Galanta',''),('SK','HAR','Harichovce','Harichovce',''),('SK','HBO','Hurbanovo','Hurbanovo',''),('SK','HBV','Hurbanova Ves','Hurbanova Ves',''),('SK','HDL','Handlova','Handlova',''),('SK','HHA','Hranicne','Hranicne',''),('SK','HKS','Haniska pri Kosiciach','Haniska pri Kosiciach',''),('SK','HLA','Handlova','Handlova',''),('SK','HLO','Hlohovec','Hlohovec',''),('SK','HNA','Hrinova','Hrinova',''),('SK','HNE','Humenne','Humenne',''),('SK','HOL','Holic','Holic',''),('SK','HOS','Hostovce','Hostovce',''),('SK','HRI','Hricov','Hricov',''),('SK','HSM','Horne Srnie','Horne Srnie',''),('SK','HUM','Humenne','Humenne',''),('SK','ILV','Ilava','Ilava',''),('SK','ILZ','Zilina','Zilina',''),('SK','JAR','Jarovce','Jarovce',''),('SK','JAS','Jasenica','Jasenica',''),('SK','JAV','Javorina','Javorina',''),('SK','JNT','Jablonov nad Turnou','Jablonov nad Turnou',''),('SK','JSK','Jesenske','Jesenske',''),('SK','KAL','Kalonda','Kalonda',''),('SK','KDV','Krizovany nad Dudvahom','Krizovany nad Dudvahom',''),('SK','KHU','Katarinska Huta','Katarinska Huta',''),('SK','KLO','Klokocov','Klokocov',''),('SK','KNA','Komarno','Komarno',''),('SK','KNM','Kysucke Nove Mesto','Kysucke Nove Mesto',''),('SK','KNP','Komarno Port','Komarno Port',''),('SK','KOC','Kocovce','Kocovce',''),('SK','KPY','Krompachy','Krompachy',''),('SK','KRA','Kral','Kral',''),('SK','KRM','Koromla','Koromla',''),('SK','KRU','Krupina','Krupina',''),('SK','KRV','Krivan','Krivan',''),('SK','KRY','Krizovany','Krizovany',''),('SK','KSC','Kosice','Kosice',''),('SK','KUT','Kuty','Kuty',''),('SK','KZK','Kezmarok','Kezmarok',''),('SK','LEN','Lenartovce','Lenartovce',''),('SK','LIM','Liptovsky Mikulas','Liptovsky Mikulas',''),('SK','LMH','Luky p Makytou-Horni Lidec','Luky p Makytou-Horni Lidec',''),('SK','LMS','Lysa pod Makytou-Strelna','Lysa pod Makytou-Strelna',''),('SK','LNR','Lednicke Rovne','Lednicke Rovne',''),('SK','LUE','Lucenec','Lucenec',''),('SK','LVE','Levice','Levice',''),('SK','LYD','Lysa nad Dunajcom','Lysa nad Dunajcom',''),('SK','LZO','Lozorno','Lozorno',''),('SK','MAC','Malacky','Malacky',''),('SK','MAT','Martovce','Martovce',''),('SK','MED','Medvedov','Medvedov',''),('SK','MHB','Makov-Horni Becva','Makov-Horni Becva',''),('SK','MHC','Michalovce','Michalovce',''),('SK','MIL','Milhost','Milhost',''),('SK','MLY','Sarisske Michal\'any','Sarisske Michal\'any',''),('SK','MOL','Moravske Lieskove','Moravske Lieskove',''),('SK','MPA','Mnisek nad Popradom','Mnisek nad Popradom',''),('SK','MRT','Martin','Martin',''),('SK','MSJ','Moravsky Svaty Jan','Moravsky Svaty Jan',''),('SK','MVA','Matovske Vojkovske','Matovske Vojkovske',''),('SK','MYJ','Myjava','Myjava',''),('SK','MYV','Myjava-Vrbovce','Myjava-Vrbovce',''),('SK','NKY','Novaky','Novaky',''),('SK','NMV','Nove Mesto nad Vahom','Nove Mesto nad Vahom',''),('SK','NOB','Nova Bosaca','Nova Bosaca',''),('SK','NOL','Boleraz','Boleraz',''),('SK','NOV','Nove Zamky','Nove Zamky',''),('SK','NRA','Nitra','Nitra',''),('SK','NSA','Nove Sady','Nove Sady',''),('SK','NSO','Namestovo','Namestovo',''),('SK','OLV','Orlov','Orlov',''),('SK','ORP','Oravska Polhora','Oravska Polhora',''),('SK','PAL','Palota','Palota',''),('SK','PBY','Povazska Bystrica','Povazska Bystrica',''),('SK','PCV','Puchov','Puchov',''),('SK','PLA','Plavec','Plavec',''),('SK','PLT','Poltar','Poltar',''),('SK','POD','Podspady','Podspady',''),('SK','POM','Podzavoz (Milosova)','Podzavoz (Milosova)',''),('SK','POV','Presov','Presov',''),('SK','PRS','Pruske','Pruske',''),('SK','PVZ','Povazany','Povazany',''),('SK','PZA','Prievidza','Prievidza',''),('SK','PZK','Pezinok','Pezinok',''),('SK','PZY','Piestany','Piestany',''),('SK','RAD','Radzovce','Radzovce',''),('SK','RDN','Rudna','Rudna',''),('SK','REV','Revuca','Revuca',''),('SK','RKA','Rakova','Rakova',''),('SK','ROZ','Roznava','Roznava',''),('SK','RSV','Rusovce/Bratislava','Rusovce/Bratislava',''),('SK','RVK','Rovinka','Rovinka',''),('SK','RVN','Rovne','Rovne',''),('SK','RZK','Ruzomberok','Ruzomberok',''),('SK','SAA','Sala','Sala',''),('SK','SAB','Sabinov','Sabinov',''),('SK','SAL','Salka','Salka',''),('SK','SCY','Sucany','Sucany',''),('SK','SDA','Slovenske Darmoty','Slovenske Darmoty',''),('SK','SEN','Sankovce','Sankovce',''),('SK','SER','Sered','Sered',''),('SK','SHA','Sahy','Sahy',''),('SK','SIB','Siatorska Bukovinka','Siatorska Bukovinka',''),('SK','SKA','Skalica','Skalica',''),('SK','SKE','Skalite','Skalite',''),('SK','SKV','Senkvice','Senkvice',''),('SK','SKZ','Skalite-Zwardon','Skalite-Zwardon',''),('SK','SLA','Sala','Sala',''),('SK','SLB','Stara Lubovna','Stara Lubovna',''),('SK','SLD','Sliac','Sliac',''),('SK','SLO','Slovenska Lupca','Slovenska Lupca',''),('SK','SLP','Selpice','Selpice',''),('SK','SLV','Sladkovicovo','Sladkovicovo',''),('SK','SMO','Smolenice','Smolenice',''),('SK','SNA','Snina','Snina',''),('SK','SNC','Senica, Okres','Senica, Okres',''),('SK','SNE','Senec','Senec',''),('SK','SNV','Spisska Nova Ves','Spisska Nova Ves',''),('SK','SOB','Sobrance','Sobrance',''),('SK','SOP','Soporna','Soporna',''),('SK','SPA','Stupava','Stupava',''),('SK','SPV','Stropkov','Stropkov',''),('SK','SRA','Sturovo','Sturovo',''),('SK','SSA','Slovenske Nove Mesto','Slovenske Nove Mesto',''),('SK','STR','Strba','Strba',''),('SK','SUH','Sucha Hora','Sucha Hora',''),('SK','SVC','Secovce','Secovce',''),('SK','SVK','Svidnik','Svidnik',''),('SK','SVR','Srvcinovec','Srvcinovec',''),('SK','SVT','Svit','Svit',''),('SK','SZY','Smizany','Smizany',''),('SK','TAT','Poprad/Tatry','Poprad/Tatry',''),('SK','TCY','Topol\'cany','Topol\'cany',''),('SK','TLM','Tlmace','Tlmace',''),('SK','TNA','Trnava','Trnava',''),('SK','TNY','Turany','Turany',''),('SK','TRB','Trebiaov','Trebiaov',''),('SK','TRE','Trencin','Trencin',''),('SK','TRH','Trhoviste','Trhoviste',''),('SK','TRT','Trancianska Tapla','Trancianska Tapla',''),('SK','TSA','Trstena','Trstena',''),('SK','UBL','Ubla','Ubla',''),('SK','VBE','Vrable','Vrable',''),('SK','VEK','Vefky Kamenec, Pacin','Vefky Kamenec, Pacin',''),('SK','VJB','Vysna Jablonka','Vysna Jablonka',''),('SK','VKL','Velke Levare','Velke Levare',''),('SK','VKO','Vel\'ke Kostol\'any','Vel\'ke Kostol\'any',''),('SK','VKP','Velke Kapusany','Velke Kapusany',''),('SK','VKS','Velky Krtis','Velky Krtis',''),('SK','VLA','Velicna','Velicna',''),('SK','VMD','Velky Meder','Velky Meder',''),('SK','VNA','Vlkanova','Vlkanova',''),('SK','VRN','Varin','Varin',''),('SK','VSC','Velke Slemence','Velke Slemence',''),('SK','VSK','Vysny Komarnik','Vysny Komarnik',''),('SK','VVC','Vlckovce','Vlckovce',''),('SK','VYN','Vysne Nemecke','Vysne Nemecke',''),('SK','ZEL','Zeliezovce','Zeliezovce',''),('SK','ZHR','Zohor','Zohor',''),('SK','ZIA','Ziar nad Hronom','Ziar nad Hronom',''),('SK','ZLM','Zlate Moravce','Zlate Moravce',''),('SK','ZRC','Zuberec','Zuberec',''),('SK','ZSK','Strazske','Strazske',''),('SK','ZSL','Zvolenska Slatina','Zvolenska Slatina',''),('SK','ZVN','Zvolen','Zvolen',''),('SL','','','',''),('SL','BTE','Bonthe','Bonthe',''),('SL','DSL','Daru','Daru',''),('SL','FNA','Freetown','Freetown',''),('SL','GBK','Gbangbatok','Gbangbatok',''),('SL','HGS','Hastings Apt/Freetown','Hastings Apt/Freetown',''),('SL','KBA','Kabala','Kabala',''),('SL','KBS','Bo','Bo',''),('SL','KEN','Kenema','Kenema',''),('SL','MUT','Muta','Muta',''),('SL','NIT','Nitti','Nitti',''),('SL','PEP','Pepel','Pepel',''),('SL','SBO','Sherbro','Sherbro',''),('SM','','','',''),('SM','SAI','San Marino','San Marino',''),('SN','','','',''),('SN','BXE','Bakel','Bakel',''),('SN','CSK','Cap Skiring','Cap Skiring',''),('SN','DAG','Dagana','Dagana',''),('SN','DKR','Dakar','Dakar',''),('SN','FOU','Foundiougne','Foundiougne',''),('SN','KAH','Kahone','Kahone',''),('SN','KDA','Kolda','Kolda',''),('SN','KGG','Kedougou','Kedougou',''),('SN','KLC','Kaolack','Kaolack',''),('SN','LOU','Louga','Louga',''),('SN','LYN','Lyndiane','Lyndiane',''),('SN','MAX','Matam','Matam',''),('SN','MBA','M\'bao Terminal','M\'bao Terminal',''),('SN','MBO','Mbour','Mbour',''),('SN','NIK','Niokolo Koba','Niokolo Koba',''),('SN','POD','Podor','Podor',''),('SN','RDT','Richard Toll','Richard Toll',''),('SN','SMY','Simenti','Simenti',''),('SN','THI','Thies','Thies',''),('SN','TOU','Touba','Touba',''),('SN','TUD','Tambacounda','Tambacounda',''),('SN','XLS','St Louis','St Louis',''),('SN','ZIG','Ziguinchor','Ziguinchor',''),('SO','','','',''),('SO','ALU','Alula','Alula',''),('SO','BBO','Berbera','Berbera',''),('SO','BIB','Baidoa','Baidoa',''),('SO','BSA','Bossaso','Bossaso',''),('SO','BSY','Bardera','Bardera',''),('SO','BUO','Burao','Burao',''),('SO','BXX','Borama','Borama',''),('SO','CMO','Obbia','Obbia',''),('SO','CMS','Scusciuban','Scusciuban',''),('SO','CXN','Candala','Candala',''),('SO','DAN','Dante (Ras Hafun)','Dante (Ras Hafun)',''),('SO','ELM','El Maan','El Maan',''),('SO','ERA','Erigavo','Erigavo',''),('SO','GBM','Garbaharey','Garbaharey',''),('SO','GGR','Garoe','Garoe',''),('SO','GHR','Giohar','Giohar',''),('SO','GLK','Galcaio','Galcaio',''),('SO','GSR','Gardo','Gardo',''),('SO','HCM','Eil','Eil',''),('SO','HGA','Hargeisa','Hargeisa',''),('SO','KMU','Kismayu','Kismayu',''),('SO','LGX','Lugh Ganane','Lugh Ganane',''),('SO','LKR','Las Khoreh','Las Khoreh',''),('SO','MER','Merca','Merca',''),('SO','MGQ','Mogadishu','Mogadishu',''),('SR','','','',''),('SR','AAJ','Awaradam','Awaradam',''),('SR','ABN','Albina','Albina',''),('SR','AGI','Wageningen','Wageningen',''),('SR','BTO','Botopasie','Botopasie',''),('SR','DOE','Djoemoe','Djoemoe',''),('SR','DRJ','Drietabbetje','Drietabbetje',''),('SR','ICK','Nieuw Nickerie','Nieuw Nickerie',''),('SR','KCB','Kasikasima','Kasikasima',''),('SR','LDO','Ladouanie','Ladouanie',''),('SR','MOJ','Moengo','Moengo',''),('SR','OEM','Paloemeu','Paloemeu',''),('SR','PBM','Paramaribo','Paramaribo',''),('SR','PRM','Paranam','Paranam',''),('SR','SMA','Smalkalden','Smalkalden',''),('SR','SMZ','Stoelmans Eiland','Stoelmans Eiland',''),('SR','TOT','Totness','Totness',''),('SR','WSO','Washabo','Washabo',''),('SR','ZDJ','Zanderij','Zanderij',''),('ST','','','',''),('ST','ANG','Angolares','Angolares',''),('ST','GUA','Guadalupe','Guadalupe',''),('ST','MAD','Madalena','Madalena',''),('ST','NEV','Neves','Neves',''),('ST','PCP','Principe','Principe',''),('ST','PGP','Porto Alegre','Porto Alegre',''),('ST','RIA','Ribeira Afonso','Ribeira Afonso',''),('ST','SAA','Santo Antonio','Santo Antonio',''),('ST','SAM','Santo Amaro','Santo Amaro',''),('ST','SOK','Stormskaer','Stormskaer',''),('ST','STA','Santana','Santana',''),('ST','TMS','Sao Tome Island','Sao Tome Island',''),('ST','TRI','Trindade','Trindade',''),('SV','','','',''),('SV','ACN','Ahuachapan','Ahuachapan',''),('SV','AQJ','Acajutla','Acajutla',''),('SV','BER','Berlin','Berlin',''),('SV','CHA','Chalchuapa','Chalchuapa',''),('SV','CNG','Chalatenango','Chalatenango',''),('SV','CPL','Comalapa','Comalapa',''),('SV','CSC','Cara Sucia','Cara Sucia',''),('SV','EPL','El Pedregal','El Pedregal',''),('SV','LLD','La Libertad','La Libertad',''),('SV','LUN','La Union','La Union',''),('SV','MET','Metapan','Metapan',''),('SV','OLO','Olocuilta','Olocuilta',''),('SV','ROS','El Rosario','El Rosario',''),('SV','SAL','San Salvador','San Salvador',''),('SV','SBT','San Bartolo','San Bartolo',''),('SV','SDM','Santiago de Maria','Santiago de Maria',''),('SV','SFG','San Francisco Gotera','San Francisco Gotera',''),('SV','SMG','San Miguel','San Miguel',''),('SV','SOY','Soyapango','Soyapango',''),('SV','SPT','San Pablo Tacachico','San Pablo Tacachico',''),('SV','SST','Sonsonate','Sonsonate',''),('SV','STA','Santa Ana','Santa Ana',''),('SV','STO','Santo Tomas','Santo Tomas',''),('SV','SVE','San Vicente','San Vicente',''),('SV','USU','Usulutan','Usulutan',''),('SY','','','',''),('SY','ALD','Al Ladhiqiyah','Al Ladhiqiyah',''),('SY','ALP','Aleppo (Alep)','Aleppo (Alep)',''),('SY','ARW','Arwad','Arwad',''),('SY','BAN','Baniyas','Baniyas',''),('SY','BEN','Banghazi','Banghazi',''),('SY','DAM','Damascus (Damas)','Damascus (Damas)',''),('SY','DEZ','Deirezzor','Deirezzor',''),('SY','HMS','Homs','Homs',''),('SY','KAC','Kameshli','Kameshli',''),('SY','LTK','Latakia','Latakia',''),('SY','PMS','Palmyra','Palmyra',''),('SY','QDR','Dera\'a','Dera\'a',''),('SY','QHM','Hama','Hama',''),('SY','QSW','Sweida','Sweida',''),('SY','RAD','Rouad','Rouad',''),('SY','RUI','Ruad Island','Ruad Island',''),('SY','SOR','Al Thaurah','Al Thaurah',''),('SY','TTS','Tartus','Tartus',''),('SY','WST','Wasit','Wasit',''),('SZ','','','',''),('SZ','MAL','Malkerns','Malkerns',''),('SZ','MAT','Matsapha','Matsapha',''),('SZ','MTS','Manzini','Manzini',''),('SZ','NHL','Nhlangano','Nhlangano',''),('SZ','QMN','Mbabane','Mbabane',''),('TC','','','',''),('TC','GDT','Grand Turk Island','Grand Turk Island',''),('TC','MDS','Middle Caicos','Middle Caicos',''),('TC','NCA','North Caicos','North Caicos',''),('TC','PIC','Pine Cay','Pine Cay',''),('TC','PLS','Providenciales','Providenciales',''),('TC','SLX','Salt Cay','Salt Cay',''),('TC','XSC','South Caicos','South Caicos',''),('TD','','','',''),('TD','AEH','Abeche','Abeche',''),('TD','AKM','Zakouma','Zakouma',''),('TD','AMC','Am Timan','Am Timan',''),('TD','AMO','Mao','Mao',''),('TD','AOD','Abou-Deia','Abou-Deia',''),('TD','ATV','Ati','Ati',''),('TD','BKR','Bokoro','Bokoro',''),('TD','BND','Banda','Banda',''),('TD','DOB','Doba','Doba',''),('TD','FYT','Faya','Faya',''),('TD','GAY','Gaya','Gaya',''),('TD','GHD','Gadang-Haddad-Dandi','Gadang-Haddad-Dandi',''),('TD','KEL','Kelo','Kelo',''),('TD','KME','Kome','Kome',''),('TD','KMR','Koumra','Koumra',''),('TD','KOU','Koumara','Koumara',''),('TD','LER','Lere','Lere',''),('TD','LTC','Lai','Lai',''),('TD','MEF','Melfi','Melfi',''),('TD','MQQ','Moundou','Moundou',''),('TD','MVO','Mongo','Mongo',''),('TD','NDJ','N\'Djamena','N\'Djamena',''),('TD','OGR','Bongor','Bongor',''),('TD','OTC','Bol','Bol',''),('TD','OUM','Oum Hadjer','Oum Hadjer',''),('TD','OUT','Bousso','Bousso',''),('TD','PLF','Pala','Pala',''),('TD','SRH','Sarh','Sarh',''),('TF','','','',''),('TG','','','',''),('TG','ANE','Aneho','Aneho',''),('TG','DPG','Dapaong','Dapaong',''),('TG','KAN','Kante','Kante',''),('TG','KON','Konpiena','Konpiena',''),('TG','KPE','Kpeme','Kpeme',''),('TG','LFW','Lome','Lome',''),('TG','LRL','Niamtougou - Lama-Kara','Niamtougou - Lama-Kara',''),('TH','','','',''),('TH','ARA','Aranyaprathet','Aranyaprathet',''),('TH','ATH','Ang Thong','Ang Thong',''),('TH','BAI','Bangpoomai','Bangpoomai',''),('TH','BAO','Ban Mak Khaen','Ban Mak Khaen',''),('TH','BFV','Buri Ram','Buri Ram',''),('TH','BGP','Bangpakong','Bangpakong',''),('TH','BKK','Bangkok','Bangkok',''),('TH','BMT','Bangkok Modern Terminals/Bangkok','Bangkok Modern Terminals/Bangkok',''),('TH','BND','Bandon','Bandon',''),('TH','BNG','Bangnara','Bangnara',''),('TH','BNK','Ban Kantang','Ban Kantang',''),('TH','BNL','Banlaem','Banlaem',''),('TH','BPG','Ban Pong','Ban Pong',''),('TH','BRK','Bang Rak','Bang Rak',''),('TH','BSE','Bangsu','Bangsu',''),('TH','BSP','Bang Saphan','Bang Saphan',''),('TH','BTP','Ban Talat Takua Pa','Ban Talat Takua Pa',''),('TH','CAN','Amnat Charoen','Amnat Charoen',''),('TH','CEI','Chiang Rai','Chiang Rai',''),('TH','CHA','Chanthaburi','Chanthaburi',''),('TH','CHB','Chon Buri','Chon Buri',''),('TH','CHU','Chumporn','Chumporn',''),('TH','CNX','Chiang Mai','Chiang Mai',''),('TH','CSD','Chachoengsao','Chachoengsao',''),('TH','HDY','Hat Yai','Hat Yai',''),('TH','HGN','Mae Hong Son','Mae Hong Son',''),('TH','HHQ','Hua Hin','Hua Hin',''),('TH','HKT','Phuket','Phuket',''),('TH','HOP','Hoping','Hoping',''),('TH','KAN','Kantang','Kantang',''),('TH','KBV','Krabi','Krabi',''),('TH','KCB','Kanchanaburi','Kanchanaburi',''),('TH','KHA','Khanom','Khanom',''),('TH','KKC','Khon Kaen','Khon Kaen',''),('TH','KKM','Lop Buri','Lop Buri',''),('TH','KLA','Koh Lanta','Koh Lanta',''),('TH','KLY','Khlong Yai','Khlong Yai',''),('TH','KNO','Koh Nok','Koh Nok',''),('TH','KOP','Nakhom Phanom','Nakhom Phanom',''),('TH','KPT','Kamphaeng Phet','Kamphaeng Phet',''),('TH','KRN','Krathum Baen','Krathum Baen',''),('TH','KSI','Koh Sichang','Koh Sichang',''),('TH','KTY','Khlong Toei','Khlong Toei',''),('TH','KYO','Koh Yao','Koh Yao',''),('TH','LAS','Lang Suan','Lang Suan',''),('TH','LCH','Laem Chabang','Laem Chabang',''),('TH','LKR','Lat Krabang','Lat Krabang',''),('TH','LOE','Loei','Loei',''),('TH','LPT','Lampang','Lampang',''),('TH','MAQ','Mae Sot','Mae Sot',''),('TH','MAT','Mab Tapud','Mab Tapud',''),('TH','MEK','Meklong','Meklong',''),('TH','MTP','Ban Map Ta Phut','Ban Map Ta Phut',''),('TH','NAK','Nakhon Ratchasima','Nakhon Ratchasima',''),('TH','NAW','Narathiwat','Narathiwat',''),('TH','NBO','Nong Bua Lamphu','Nong Bua Lamphu',''),('TH','NIM','Nim Port','Nim Port',''),('TH','NNT','Nan','Nan',''),('TH','NON','Nong Khaem','Nong Khaem',''),('TH','NPM','Nakhon Pathom','Nakhon Pathom',''),('TH','NSA','Nakhon Sawan','Nakhon Sawan',''),('TH','NST','Nakhon Si Thammarat','Nakhon Si Thammarat',''),('TH','NTB','Nonthaburi','Nonthaburi',''),('TH','PAN','Pattani','Pattani',''),('TH','PAT','Pat Bangkok','Pat Bangkok',''),('TH','PBM','Phibun Mangsahan','Phibun Mangsahan',''),('TH','PBS','Patong Beach','Patong Beach',''),('TH','PCH','Pak Chong','Pak Chong',''),('TH','PHA','Phangnga','Phangnga',''),('TH','PHE','Phet Buri','Phet Buri',''),('TH','PHS','Phitsanulok','Phitsanulok',''),('TH','PHT','Phan Thong','Phan Thong',''),('TH','PHZ','Phi Phi Island','Phi Phi Island',''),('TH','PKB','Pakbara','Pakbara',''),('TH','PKK','Prachuap Khiri Khan','Prachuap Khiri Khan',''),('TH','PKN','Paknam','Paknam',''),('TH','PKP','Pakpanang','Pakpanang',''),('TH','PKR','Pak Kret','Pak Kret',''),('TH','PMM','Phanom Sarakham','Phanom Sarakham',''),('TH','PNA','Phra Nakhon si Ayutthaya','Phra Nakhon si Ayutthaya',''),('TH','PPA','Phra Pradeng','Phra Pradeng',''),('TH','PRG','Phra Pradaeng','Phra Pradaeng',''),('TH','PRH','Phrae','Phrae',''),('TH','PTH','Pathum Thani','Pathum Thani',''),('TH','PTR','Photharam','Photharam',''),('TH','QJX','Nong Khai','Nong Khai',''),('TH','RAT','Ratchaburi','Ratchaburi',''),('TH','ROI','Roi Et','Roi Et',''),('TH','RYG','Rayong','Rayong',''),('TH','SAM','Samphanthawong','Samphanthawong',''),('TH','SAN','Sam Phran','Sam Phran',''),('TH','SAT','Sattahip','Sattahip',''),('TH','SAU','Samut Sakhon, Changwat','Samut Sakhon, Changwat',''),('TH','SBI','Sara Buri','Sara Buri',''),('TH','SBP','Siam Bangkok Port','Siam Bangkok Port',''),('TH','SGZ','Songkhla','Songkhla',''),('TH','SIC','Sichol','Sichol',''),('TH','SIR','Si Racha','Si Racha',''),('TH','SKW','Sre Kaew','Sre Kaew',''),('TH','SNO','Sakon Nakhon','Sakon Nakhon',''),('TH','SNR','Surin','Surin',''),('TH','SNT','Satun','Satun',''),('TH','SPR','Samut Prakarn','Samut Prakarn',''),('TH','SRI','Sriracha','Sriracha',''),('TH','STH','Sathun','Sathun',''),('TH','TAC','Ta-Chalaeb','Ta-Chalaeb',''),('TH','THA','Tha Sala','Tha Sala',''),('TH','THS','Sukhothai','Sukhothai',''),('TH','TKH','Takhli','Takhli',''),('TH','TKT','Tak','Tak',''),('TH','TPT','Thai prosperity terminal','Thai prosperity terminal',''),('TH','TST','Trang','Trang',''),('TH','UBP','Ubon Ratchathani','Ubon Ratchathani',''),('TH','UCT','Unithai Container Terminal','Unithai Container Terminal',''),('TH','UNN','Ranong','Ranong',''),('TH','URT','Surat Thani','Surat Thani',''),('TH','USM','Koh Samui','Koh Samui',''),('TH','UTH','Udon Thani','Udon Thani',''),('TH','UTP','Utapao','Utapao',''),('TH','UTR','Uttaradit','Uttaradit',''),('TH','YAL','Yala','Yala',''),('TH','YNT','Yasothon','Yasothon',''),('TJ','','','',''),('TJ','DYU','Dushanbe','Dushanbe',''),('TJ','KLB','Kulob','Kulob',''),('TJ','KUR','Qurghonteppa','Qurghonteppa',''),('TJ','LBD','Khudzhand','Khudzhand',''),('TJ','PJK','Penjikent','Penjikent',''),('TJ','STZ','Shaartuz','Shaartuz',''),('TK','','','',''),('TK','AFU','Atafu','Atafu',''),('TK','FKO','Fakaofo','Fakaofo',''),('TK','NKU','Nukunonu','Nukunonu',''),('TL','','','',''),('TL','DIL','Dili','Dili',''),('TL','SUA','Suai','Suai',''),('TM','','','',''),('TM','AKD','Akdepe','Akdepe',''),('TM','ASB','Ashkhabad','Ashkhabad',''),('TM','BAB','Babadayhan','Babadayhan',''),('TM','BAH','Baherden','Baherden',''),('TM','BAL','Balkanabat','Balkanabat',''),('TM','BAY','Bayramaly','Bayramaly',''),('TM','BKH','Bekdash','Bekdash',''),('TM','BOL','Boldumsaz','Boldumsaz',''),('TM','BZY','Buzmeyin','Buzmeyin',''),('TM','CJV','Charjew','Charjew',''),('TM','CRZ','Tchardjou','Tchardjou',''),('TM','DHZ','Dashhowuz','Dashhowuz',''),('TM','FAR','Farap','Farap',''),('TM','GAL','Galkynys','Galkynys',''),('TM','GUB','Gubadag','Gubadag',''),('TM','HAL','Halach','Halach',''),('TM','KAK','Kaka','Kaka',''),('TM','KER','Kerkichi','Kerkichi',''),('TM','KHS','Khodzhambas','Khodzhambas',''),('TM','KON','Koneurgench','Koneurgench',''),('TM','KRA','Krasnovodsk','Krasnovodsk',''),('TM','KRW','Turkmenbashi','Turkmenbashi',''),('TM','KUK','Kushka','Kushka',''),('TM','LEB','Lebap','Lebap',''),('TM','MUR','Murgap','Murgap',''),('TM','MYP','Mary','Mary',''),('TM','SAK','Sakar','Sakar',''),('TM','SAY','Sayat','Sayat',''),('TM','SHI','Shirvan-Kala','Shirvan-Kala',''),('TM','SRK','Sarakhs','Sarakhs',''),('TM','TAG','Tagta','Tagta',''),('TM','TAZ','Tashauz','Tashauz',''),('TM','TEJ','Tejen','Tejen',''),('TM','TMZ','Termez','Termez',''),('TM','TUR','Turkmen-Kala','Turkmen-Kala',''),('TM','YLA','Yylanly','Yylanly',''),('TM','YOL','Yoloten','Yoloten',''),('TN','','','',''),('TN','AQR','Al Qayrawan','Al Qayrawan',''),('TN','AQY','Al Qasrayn','Al Qasrayn',''),('TN','ASH','Ashtart Terminal','Ashtart Terminal',''),('TN','BEB','Borj el Bey','Borj el Bey',''),('TN','BEJ','Beja','Beja',''),('TN','BGA','Ben Gardane','Ben Gardane',''),('TN','BIZ','Bizerte','Bizerte',''),('TN','BNA','Bin Arous','Bin Arous',''),('TN','CHB','Chebba','Chebba',''),('TN','DJE','Djerba','Djerba',''),('TN','EBM','El Borma','El Borma',''),('TN','EFA','Enfida','Enfida',''),('TN','EZA','Ez Zahra','Ez Zahra',''),('TN','GAE','Gabes','Gabes',''),('TN','GAF','Gafsa','Gafsa',''),('TN','HMM','Al Hammamat','Al Hammamat',''),('TN','JAR','Jarjis','Jarjis',''),('TN','JEM','Jammal','Jammal',''),('TN','JUL','Jundubah','Jundubah',''),('TN','KEL','Qulaybiyah','Qulaybiyah',''),('TN','KER','Kerkena','Kerkena',''),('TN','KKE','Kalaa Kebira','Kalaa Kebira',''),('TN','KOR','Korba','Korba',''),('TN','LGN','La Goulette Nord (Halqueloued)','La Goulette Nord (Halqueloued)',''),('TN','LSK','La Skhirra','La Skhirra',''),('TN','MAD','Mahdia','Mahdia',''),('TN','MAH','Mahires','Mahires',''),('TN','MAT','Mateur','Mateur',''),('TN','MBA','Menzel Bourguiba','Menzel Bourguiba',''),('TN','MDN','Madanin','Madanin',''),('TN','MEG','Megrine-Lescure','Megrine-Lescure',''),('TN','MIR','Monastir','Monastir',''),('TN','MOK','Moknine','Moknine',''),('TN','MTE','Menzel Temime','Menzel Temime',''),('TN','NAB','Nabeul','Nabeul',''),('TN','QKN','Kairouan','Kairouan',''),('TN','RDS','Rades/Tunis','Rades/Tunis',''),('TN','SBZ','Sidi Bu Zayd','Sidi Bu Zayd',''),('TN','SFA','Sfax','Sfax',''),('TN','SUS','Sousse','Sousse',''),('TN','TAT','Tazerka Terminal','Tazerka Terminal',''),('TN','TBJ','Tabarka','Tabarka',''),('TN','TOE','Tozeur','Tozeur',''),('TN','TUN','Tunis','Tunis',''),('TO','','','',''),('TO','EUA','\'Eua Island','\'Eua Island',''),('TO','HPA','Ha\'apai','Ha\'apai',''),('TO','NEI','Neiafu','Neiafu',''),('TO','NFO','Niuafo\'ou','Niuafo\'ou',''),('TO','NTT','Niuatoputapu','Niuatoputapu',''),('TO','PAN','Pangai','Pangai',''),('TO','TBU','Nuku\'alofa','Nuku\'alofa',''),('TO','VAV','Vava\'u','Vava\'u',''),('TR','','','',''),('TR','ABK','Alibeykoy','Alibeykoy','34'),('TR','ACI','Acibadem','Acibadem','34'),('TR','ADA','Adana','Adana','01'),('TR','ADI','Adiyaman','Adiyaman','02'),('TR','ADK','Anadolukavagi','Anadolukavagi','34'),('TR','ADN','Aydin','Aydin','09'),('TR','ADZ','Adapazari','Adapazari','54'),('TR','AFY','Afyonkarahisar','Afyonkarahisar','03'),('TR','AHM','Ahmetli','Ahmetli','45'),('TR','AHR','Aksehir','Aksehir','42'),('TR','AHS','Akhisar','Akhisar','45'),('TR','AIZ','Altinusagi','Altinusagi','23'),('TR','AJI','Agri','Agri','04'),('TR','AKA','Antakya','Antakya','31'),('TR','AKB','Akcaabat','Akcaabat','61'),('TR','AKI','Akseki','Akseki','07'),('TR','AKS','Aksaray','Aksaray','34'),('TR','AKY','Akcay','Akcay','10'),('TR','AKZ','Akyazi','Akyazi','54'),('TR','ALA','Alanya','Alanya','07'),('TR','ALE','Alemdag','Alemdag','34'),('TR','ALI','Aliaga','Aliaga','35'),('TR','ALT','Altintepe','Altintepe','34'),('TR','AMA','Amasra','Amasra','67'),('TR','AMB','Ambarli','Ambarli','08'),('TR','AMY','Amasya','Amasya','05'),('TR','ANA','Anamur','Anamur','33'),('TR','ANC','Alsancak','Alsancak','35'),('TR','ANK','Ankara','Ankara','06'),('TR','API','Alapli','Alapli','67'),('TR','APY','Acipayam','Acipayam','20'),('TR','ARI','Ayranci','Ayranci','70'),('TR','ARN','Arnavutkoy/Istambul','Arnavutkoy/Istambul','34'),('TR','ARY','Aksaray','Aksaray','68'),('TR','ASH','Alasehir','Alasehir','45'),('TR','ASR','Kayseri','Kayseri','38'),('TR','ATS','Altinsehir','Altinsehir','34'),('TR','AVC','Avcilar','Avcilar','34'),('TR','AVN','Artvin','Artvin','08'),('TR','AYA','Ayancik','Ayancik','57'),('TR','AYD','Altinkum','Altinkum','09'),('TR','AYK','Aydinlikoy','Aydinlikoy','34'),('TR','AYS','Ayas','Ayas','06'),('TR','AYT','Antalya','Antalya','07'),('TR','AYV','Ayvalik','Ayvalik','10'),('TR','AYZ','Ayazaga','Ayazaga','34'),('TR','BAB','Babaeski','Babaeski','39'),('TR','BAC','Bahcesaray','Bahcesaray','65'),('TR','BAF','Bafra','Bafra','55'),('TR','BAG','Bagcilar','Bagcilar','34'),('TR','BAH','Bahcelievler','Bahcelievler','34'),('TR','BAK','Bakirkoy','Bakirkoy','34'),('TR','BAL','Batman','Batman','72'),('TR','BAN','Banaz','Banaz','64'),('TR','BAS','Basmahane','Basmahane','35'),('TR','BAY','Bayrampasa','Bayrampasa','34'),('TR','BBD','Babadag','Babadag','20'),('TR','BBI','Beylerbeyi','Beylerbeyi','34'),('TR','BCE','Buyukcekmece','Buyukcekmece','34'),('TR','BCK','Bucak','Bucak','15'),('TR','BDG','Bozdogan','Bozdogan','09'),('TR','BDM','Bandirma','Bandirma','10'),('TR','BDN','Buldan','Buldan','20'),('TR','BDR','Burdur','Burdur','15'),('TR','BER','Bergama','Bergama','35'),('TR','BEY','Beykoz','Beykoz','34'),('TR','BGD','Bigadic','Bigadic','10'),('TR','BHN','Burhaniye','Burhaniye','10'),('TR','BIG','Biga','Biga','17'),('TR','BIL','Bilecik','Bilecik','11'),('TR','BIN','Bingol','Bingol','12'),('TR','BKC','Basmakci','Basmakci','03'),('TR','BKY','Baskoy','Baskoy','16'),('TR','BLA','Bala','Bala','06'),('TR','BLY','Balya','Balya','10'),('TR','BOG','Bogazagzi','Bogazagzi','67'),('TR','BOL','Bolu','Bolu','14'),('TR','BOR','Bornova','Bornova','35'),('TR','BOS','Bostanci','Bostanci','34'),('TR','BOT','Botas','Botas',''),('TR','BPZ','Beypazari','Beypazari','06'),('TR','BTN','Bartin','Bartin','74'),('TR','BTS','Besiktas','Besiktas','34'),('TR','BTZ','Bursa','Bursa','16'),('TR','BUC','Buca','Buca','35'),('TR','BUH','Buharkent','Buharkent','09'),('TR','BUY','Buyukcukur','Buyukcukur','16'),('TR','BVN','Bolvadin','Bolvadin','03'),('TR','BXN','Bodrum','Bodrum','48'),('TR','BYD','Beydag','Beydag','35'),('TR','BYL','Beylikduzu','Beylikduzu','34'),('TR','BYM','Bayramic','Bayramic','17'),('TR','BYN','Bayindir','Bayindir','35'),('TR','BYR','Bayramoglu','Bayramoglu','41'),('TR','BYS','Beysehir','Beysehir','42'),('TR','BYT','Bayburt','Bayburt','69'),('TR','BZB','Bozburun','Bozburun','48'),('TR','BZC','Bozcaada','Bozcaada','17'),('TR','BZI','Balikesir','Balikesir','10'),('TR','BZY','Bozuyuk','Bozuyuk','11'),('TR','CAB','Caybasi','Caybasi','16'),('TR','CAL','Cal','Cal','20'),('TR','CAM','Camalti','Camalti','35'),('TR','CAN','Can','Can','17'),('TR','CAR','Cardak','Cardak','20'),('TR','CAT','Catalca','Catalca','34'),('TR','CAY','Cayirova','Cayirova','41'),('TR','CCY','Cay','Cay','03'),('TR','CDR','Camlidere','Camlidere','06'),('TR','CES','Cesme','Cesme','35'),('TR','CEV','Cevizli','Cevizli','34'),('TR','CEY','Ceyhan','Ceyhan','01'),('TR','CHB','Cihanbeyli','Cihanbeyli','42'),('TR','CID','Cide','Cide','37'),('TR','CIF','Ciftehavuzlar','Ciftehavuzlar','34'),('TR','CIG','Cigli','Cigli','35'),('TR','CIN','Cine','Cine','09'),('TR','CIV','Civril','Civril',''),('TR','CKR','Cankiri','Cankiri','18'),('TR','CKY','Cerkezkoy','Cerkezkoy','59'),('TR','CKZ','Canakkale','Canakkale','17'),('TR','CMB','Camdibi','Camdibi','16'),('TR','CML','Camlica','Camlica','34'),('TR','CMR','Cumra','Cumra','42'),('TR','CNE','Cigne','Cigne','09'),('TR','CNR','Cobanlar','Cobanlar','03'),('TR','COM','Corum','Corum','19'),('TR','COR','Corlu','Corlu','59'),('TR','CTK','Celtik','Celtik','42'),('TR','CUB','Cubuklu','Cubuklu','34'),('TR','CUM','Caycuma','Caycuma','67'),('TR','CVD','Cavdir','Cavdir','15'),('TR','CZE','Cizre','Cizre','73'),('TR','DAR','Darica','Darica','41'),('TR','DAT','Datca','Datca','48'),('TR','DAZ','Dazkiri','Dazkiri','03'),('TR','DCI','Demirci','Demirci','45'),('TR','DDM','Didim','Didim','09'),('TR','DEK','Derekoy','Derekoy','39'),('TR','DEM','Demirkoy','Demirkoy','39'),('TR','DHN','Doganhisar','Doganhisar','42'),('TR','DIK','Dikili','Dikili','35'),('TR','DIL','Diliskelesi','Diliskelesi','41'),('TR','DIY','Diyarbakir','Diyarbakir','21'),('TR','DLM','Dalaman','Dalaman','48'),('TR','DLV','Dilovasi','Dilovasi','41'),('TR','DMC','Domanic Kozluca','Domanic Kozluca','43'),('TR','DNR','Dinar','Dinar','03'),('TR','DNZ','Denizli','Denizli','20'),('TR','DOL','Dolayoba','Dolayoba','34'),('TR','DPR','Dumlupinar','Dumlupinar','43'),('TR','DRC','Derince','Derince','41'),('TR','DRK','Devrek','Devrek','67'),('TR','DRY','Dursunbey','Dursunbey','10'),('TR','DUD','Dudullu','Dudullu','34'),('TR','DUZ','Duzce','Duzce','14'),('TR','DYL','Dortyol','Dortyol','31'),('TR','ECE','Eceabat','Eceabat','17'),('TR','EDI','Edirne','Edirne','22'),('TR','EDK','Edincik','Edincik','10'),('TR','EDO','Edremit','Edremit','10'),('TR','EGI','Egirdir','Egirdir','32'),('TR','EGZ','Emirgazi','Emirgazi','42'),('TR','ELI','Eregli','Eregli','42'),('TR','ELM','Elmali','Elmali','07'),('TR','EME','Emet','Emet','43'),('TR','EMG','Emirdag','Emirdag','03'),('TR','EMI','Eminonu','Eminonu','34'),('TR','EMK','Ermenek','Ermenek','70'),('TR','ENE','Enez','Enez','22'),('TR','ERC','Erzincan','Erzincan','24'),('TR','ERE','Eregli','Eregli','67'),('TR','ERG','Konya Ereglisi','Konya Ereglisi','42'),('TR','ERK','Erdek','Erdek','10'),('TR','ERN','Erenkoy','Erenkoy','34'),('TR','ERZ','Erzurum','Erzurum','25'),('TR','ESB','Esenboga Apt/Ankara','Esenboga Apt/Ankara','06'),('TR','ESE','Esenler','Esenler','34'),('TR','ESK','Eskisehir','Eskisehir','26'),('TR','ESM','Esme','Esme','64'),('TR','ESY','Esenyurt','Esenyurt','34'),('TR','ETI','Etiler','Etiler','34'),('TR','EVY','Evyapan','Evyapan','36'),('TR','EYU','Eyup','Eyup','34'),('TR','EZI','Ezine','Ezine','17'),('TR','EZS','Elazig','Elazig','23'),('TR','FAS','Fatsa','Fatsa','52'),('TR','FAT','Fatih','Fatih','34'),('TR','FET','Fethiye','Fethiye','48'),('TR','FIK','Fikirtepe','Fikirtepe','34'),('TR','FIN','Finike','Finike','07'),('TR','FLO','Florya','Florya','34'),('TR','FOC','Foca','Foca','35'),('TR','GAY','Gayrettepe','Gayrettepe','34'),('TR','GAZ','Gaziosmanpasa','Gaziosmanpasa','34'),('TR','GBS','Golbasi','Golbasi','06'),('TR','GCA','Imroz','Imroz','17'),('TR','GCK','Gocek','Gocek','48'),('TR','GDS','Gordes','Gordes','45'),('TR','GDZ','Gediz','Gediz','43'),('TR','GEB','Gebze','Gebze','41'),('TR','GEL','Gelibolu','Gelibolu','17'),('TR','GEM','Gemlik','Gemlik','16'),('TR','GER','Gerede','Gerede','14'),('TR','GEY','Geyve','Geyve','54'),('TR','GHN','Gumushane','Gumushane','29'),('TR','GIR','Giresun','Giresun','28'),('TR','GKV','Akcapinar','Akcapinar','48'),('TR','GLP','Golpazari','Golpazari','11'),('TR','GMA','Golmarmara','Golmarmara','45'),('TR','GOK','Golcuk','Golcuk','41'),('TR','GON','Gonen','Gonen','10'),('TR','GOR','Gorele','Gorele','28'),('TR','GOZ','Goztepe','Goztepe','34'),('TR','GRK','Germencik','Germencik','09'),('TR','GRS','Gursu','Gursu','16'),('TR','GTA','Galata','Galata','34'),('TR','GUG','Gungoren','Gungoren','34'),('TR','GUL','Gulluk','Gulluk','48'),('TR','GUN','Gunesli','Gunesli','34'),('TR','GYN','Goynuk','Goynuk','14'),('TR','GZE','Gerze','Gerze',''),('TR','GZM','Gaziemir','Gaziemir','35'),('TR','GZT','Gaziantep','Gaziantep','27'),('TR','HAB','Habibler','Habibler','34'),('TR','HAD','Boyalik','Boyalik','34'),('TR','HAK','Hakkari','Hakkari','30'),('TR','HAL','Halkali','Halkali','34'),('TR','HAP','Hasanpasa','Hasanpasa','34'),('TR','HAR','Haramidere','Haramidere','34'),('TR','HAS','Haskoy','Haskoy','34'),('TR','HAT','Hatay','Hatay','31'),('TR','HAV','Havsa','Havsa','22'),('TR','HAY','Haydarpasa','Haydarpasa','34'),('TR','HEN','Hendek','Hendek','54'),('TR','HER','Hereke','Hereke','41'),('TR','HIS','Hisaronu','Hisaronu','48'),('TR','HMA','Haymana','Haymana','06'),('TR','HOP','Hopa','Hopa','08'),('TR','HVR','Havran','Havran','10'),('TR','HYR','Hayrabolu','Hayrabolu','59'),('TR','ICE','Icerenkoy','Icerenkoy','34'),('TR','ICO','Incirliova','Incirliova','09'),('TR','IGD','Igdir','Igdir','76'),('TR','IGN','Igneada','Igneada','39'),('TR','IKI','Ikitelli','Ikitelli','34'),('TR','ILG','Ilgin','Ilgin','42'),('TR','INC','Incirlik','Incirlik','01'),('TR','INE','Inebolu','Inebolu','37'),('TR','INH','Inhisar','Inhisar','11'),('TR','INL','Inegol','Inegol','16'),('TR','INO','Inonu','Inonu','26'),('TR','IPS','Ipsala','Ipsala','22'),('TR','ISE','Isparta','Isparta','32'),('TR','ISK','Iskenderun','Iskenderun','31'),('TR','IST','Istanbul','Istanbul','34'),('TR','ITY','Istinye/Istambul','Istinye/Istambul','34'),('TR','IZK','Iznik','Iznik','16'),('TR','IZM','?zmir','?zmir','35'),('TR','IZT','Izmit','Izmit','41'),('TR','KAD','Kadikoy','Kadikoy','34'),('TR','KAG','Kagithane','Kagithane','34'),('TR','KAL','Kalekoy','Kalekoy',''),('TR','KAN','Kandira','Kandira','41'),('TR','KAR','Kartal','Kartal','34'),('TR','KAS','Kas','Kas','07'),('TR','KAV','Kavacik','Kavacik','34'),('TR','KAY','Kaynarca','Kaynarca','34'),('TR','KAZ','Kazlicesme','Kazlicesme','34'),('TR','KBG','Kumburgaz','Kumburgaz',''),('TR','KBK','Karabuk','Karabuk','78'),('TR','KBN','Karaburun','Karaburun','35'),('TR','KBY','Karacabey','Karacabey','16'),('TR','KCA','Kaynarca','Kaynarca','54'),('TR','KCB','Keciborlu','Keciborlu','32'),('TR','KCE','Kucukcekmece','Kucukcekmece','34'),('TR','KCK','Kuyucak','Kuyucak','09'),('TR','KCL','Kocarli','Kocarli','09'),('TR','KCM','Kahramanmaras','Kahramanmaras','46'),('TR','KCO','Kocaeli','Kocaeli','41'),('TR','KCU','Karacasu','Karacasu','09'),('TR','KCZ','Koycegiz','Koycegiz','48'),('TR','KEB','Keban','Keban','23'),('TR','KEM','Kemerburgaz','Kemerburgaz','34'),('TR','KES','Kesan','Kesan','22'),('TR','KFK','Kefken','Kefken',''),('TR','KHN','Kadinhani','Kadinhani','42'),('TR','KIC','Kirkagac','Kirkagac','45'),('TR','KIL','Kilis','Kilis',''),('TR','KIR','Kirklareli','Kirklareli','39'),('TR','KIS','Kayisdagi','Kayisdagi',''),('TR','KKB','Kazimkarabekir','Kazimkarabekir','70'),('TR','KKY','Karakoy/Istambul','Karakoy/Istambul','34'),('TR','KLA','Kula','Kula','45'),('TR','KLS','Keles','Keles','16'),('TR','KLU','Karpuzlu','Karpuzlu','09'),('TR','KMN','Karaman','Karaman','70'),('TR','KMR','Kemer','Kemer','07'),('TR','KMX','Kumport','Kumport','34'),('TR','KNK','Kinik','Kinik','35'),('TR','KOC','Kusukkuyu','Kusukkuyu','10'),('TR','KOR','Korkuteli','Korkuteli','07'),('TR','KOZ','Kozyatagi','Kozyatagi','34'),('TR','KPN','Karapinar','Karapinar','42'),('TR','KPS','Kemalpasa','Kemalpasa','35'),('TR','KPU','Kapikule','Kapikule','22'),('TR','KPY','Kapikoy','Kapikoy','65'),('TR','KRB','Karabiga','Karabiga','17'),('TR','KRC','Kirac','Kirac',''),('TR','KRH','Karahanli','Karahanli','64'),('TR','KRK','Kirikkale','Kirikkale','71'),('TR','KRM','Karamursel','Karamursel','41'),('TR','KRS','Karasu','Karasu','54'),('TR','KRZ','Kiraz','Kiraz','35'),('TR','KSH','Kirsehir','Kirsehir','40'),('TR','KSK','Kosk','Kosk','09'),('TR','KSL','Kestel','Kestel','16'),('TR','KST','Kepsut','Kepsut','10'),('TR','KSY','Kars','Kars','36'),('TR','KTM','Kastamonu','Kastamonu','37'),('TR','KTY','Kutahya','Kutahya','43'),('TR','KUC','Kucukbakkal','Kucukbakkal','34'),('TR','KUK','Kucukkoy','Kucukkoy','34'),('TR','KUL','Kulu','Kulu','42'),('TR','KUM','Kumluca','Kumluca','07'),('TR','KUR','Kurtkoy','Kurtkoy','34'),('TR','KUS','Kusadasi','Kusadasi','09'),('TR','KUY','Kucukyali','Kucukyali','34'),('TR','KYA','Konya','Konya','42'),('TR','KZE','Kiziltepe','Kiziltepe','47'),('TR','KZI','Kazanli','Kazanli','33'),('TR','KZM','Kizilcahamam','Kizilcahamam','06'),('TR','KZN','Kozan','Kozan','01'),('TR','KZZ','Kazan','Kazan','06'),('TR','LAL','Lalapasa','Lalapasa','22'),('TR','LAP','Lapseki','Lapseki','17'),('TR','LEV','Levent','Levent','34'),('TR','LMA','Limas','Limas','35'),('TR','LUL','Luleburgaz','Luleburgaz','39'),('TR','MAD','Mardas','Mardas','34'),('TR','MAH','Mahmutbey','Mahmutbey','34'),('TR','MAL','Maltepe','Maltepe','34'),('TR','MAM','Manisa','Manisa','45'),('TR','MAR','Marmara Ereglisi','Marmara Ereglisi','59'),('TR','MAS','Maslak','Maslak','34'),('TR','MDN','Mardin','Mardin','47'),('TR','MDR','Mudurnu','Mudurnu','14'),('TR','MEK','Mevlanakapi','Mevlanakapi','34'),('TR','MEN','Menderes','Menderes','35'),('TR','MER','Mersin','Mersin','33'),('TR','MFZ','Mersin-Free Zone','Mersin-Free Zone','33'),('TR','MHM','Mahmudiye','Mahmudiye','26'),('TR','MIL','Milas','Milas','48'),('TR','MKP','Mustafa Kemalpa?a','Mustafa Kemalpa?a','16'),('TR','MLK','Malkara','Malkara','59'),('TR','MLX','Malatya','Malatya','44'),('TR','MNM','Menemen','Menemen','35'),('TR','MPT','Marport','Marport','34'),('TR','MQJ','Merkez Apt/Balikesir','Merkez Apt/Balikesir','10'),('TR','MRA','Marmara','Marmara','10'),('TR','MRC','Meric','Meric','22'),('TR','MRM','Marmaris','Marmaris','48'),('TR','MRT','Merter','Merter','34'),('TR','MSR','Mus','Mus','49'),('TR','MUD','Mudanya','Mudanya','16'),('TR','MUG','Mugla','Mugla','48'),('TR','MUR','Muratli','Muratli','59'),('TR','MUT','Mut','Mut','70'),('TR','MVG','Manavgat','Manavgat','07'),('TR','MYS','Manyas','Manyas','10'),('TR','MZH','Merzifon','Merzifon','05'),('TR','NAL','Nallihan','Nallihan','06'),('TR','NEM','Nemrut Bay','Nemrut Bay','35'),('TR','NEV','Nevsehir','Nevsehir','50'),('TR','NIG','Nigde','Nigde','51'),('TR','NZL','Nazilli','Nazilli','09'),('TR','ODE','Odemis','Odemis','35'),('TR','ODU','Odunluk','Odunluk','17'),('TR','OGZ','Orhangazi','Orhangazi','16'),('TR','OHL','Orhaneli','Orhaneli','16'),('TR','OKM','Okmeydani','Okmeydani','34'),('TR','OLI','Osmaneli','Osmaneli','11'),('TR','OME','Omerli','Omerli','34'),('TR','ORD','Ordu','Ordu','52'),('TR','ORH','Orhanli','Orhanli','34'),('TR','ORN','Ornektepe','Ornektepe','34'),('TR','ORT','Ortaca','Ortaca','48'),('TR','OSE','Osmaniye','Osmaniye','80'),('TR','OSZ','Osmangazi','Osmangazi','16'),('TR','PAM','Ambarli','Ambarli','66'),('TR','PAS','Pasabahce','Pasabahce','34'),('TR','PAY','Payas','Payas','31'),('TR','PAZ','Pazarkule,','Pazarkule,','22'),('TR','PEH','Pehlivankoy','Pehlivankoy','39'),('TR','PEN','Pendik','Pendik','34'),('TR','PIN','Pinarhisar','Pinarhisar','39'),('TR','POV','Pamukova','Pamukova','54'),('TR','PTL','Polatli','Polatli','06'),('TR','PYI','Pazaryeri','Pazaryeri','11'),('TR','PZR','Pazar','Pazar',''),('TR','RAH','Rahmanlar','Rahmanlar','34'),('TR','RAI','Rami','Rami','34'),('TR','RAM','Raman','Raman','21'),('TR','RES','Resadiye','Resadiye','60'),('TR','RIZ','Rize','Rize','53'),('TR','SAF','Safranbolu','Safranbolu',''),('TR','SAL','Salihli','Salihli','45'),('TR','SAM','Samandira','Samandira','34'),('TR','SAR','Saray','Saray','59'),('TR','SCA','Sapanca','Sapanca','54'),('TR','SCK','Selcuk','Selcuk','35'),('TR','SCN','Sincan','Sincan','06'),('TR','SDG','Sindirgi','Sindirgi','10'),('TR','SDI','Sultandagi','Sultandagi','03'),('TR','SEF','Sefakoy','Sefakoy','34'),('TR','SEI','Serik','Serik','07'),('TR','SEL','Selimiye','Selimiye','34'),('TR','SEN','Senirkent','Senirkent','32'),('TR','SER','Serviburun','Serviburun','34'),('TR','SEY','Seydisehir','Seydisehir','42'),('TR','SFH','Seferihisar','Seferihisar','35'),('TR','SFQ','Sanliurfa','Sanliurfa','63'),('TR','SGL','Sarigol','Sarigol','45'),('TR','SGT','Sogut','Sogut','11'),('TR','SHL','Saruhanli','Saruhanli','45'),('TR','SHN','Saphane','Saphane','43'),('TR','SHR','Sultanhisar','Sultanhisar','09'),('TR','SIC','Sinop','Sinop','57'),('TR','SIL','Silivri','Silivri','34'),('TR','SIR','Sirkeci','Sirkeci','34'),('TR','SIS','Sisli','Sisli','34'),('TR','SKE','Soke','Soke','09'),('TR','SKH','Sereflikochisar','Sereflikochisar','06'),('TR','SKR','Sarkikaraagac','Sarkikaraagac','32'),('TR','SKY','Saraykoy','Saraykoy','20'),('TR','SLE','Sile','Sile',''),('TR','SMA','Soma','Soma','45'),('TR','SMV','Simav','Simav','43'),('TR','SNK','Sirnak','Sirnak',''),('TR','SNU','Sarayonu','Sarayonu','42'),('TR','SRG','Sarigazi','Sarigazi','34'),('TR','SRK','Sarkoy','Sarkoy','59'),('TR','SRN','Sirinevler','Sirinevler','34'),('TR','SRS','Sar?seki','Sar?seki','31'),('TR','SRY','Sariyer','Sariyer','34'),('TR','SSL','Susurluk','Susurluk','10'),('TR','SSX','Samsun','Samsun','55'),('TR','SUA','Suadiye','Suadiye','34'),('TR','SUR','Surmene','Surmene','61'),('TR','SUT','Sutluce','Sutluce','34'),('TR','SVR','Sivrihisar','Sivrihisar','26'),('TR','SVS','Sivasli','Sivasli','64'),('TR','SXZ','Siirt','Siirt','56'),('TR','SYR','Seyrantepe','Seyrantepe','34'),('TR','SYT','Seyitgazi','Seyitgazi','26'),('TR','SZF','Carsamba Apt/Samsun','Carsamba Apt/Samsun','55'),('TR','TAK','Taksim/Istambul','Taksim/Istambul','34'),('TR','TAR','Tarsus','Tarsus','33'),('TR','TAS','Tasucu','Tasucu','33'),('TR','TAV','Tavas','Tavas','20'),('TR','TBY','Tarabya','Tarabya','34'),('TR','TEK','Tekirdag','Tekirdag','59'),('TR','TFN','Tefenni','Tefenni','15'),('TR','TGL','Turgutlu','Turgutlu','45'),('TR','TGT','Toros Gubre Terminal, Gubre','Toros Gubre Terminal, Gubre','31'),('TR','TIR','Tirebolu','Tirebolu','28'),('TR','TJK','Tokat','Tokat','60'),('TR','TOC','Topcular','Topcular','34'),('TR','TOP','Topkapi','Topkapi','34'),('TR','TOR','Torbali','Torbali','35'),('TR','TRE','Tire','Tire','35'),('TR','TSD','Tasdelen','Tasdelen','34'),('TR','TUN','Tunceli','Tunceli','62'),('TR','TUR','Turan','Turan','35'),('TR','TUT','Tutunciftlik','Tutunciftlik','41'),('TR','TUZ','Tuzla','Tuzla','34'),('TR','TVS','Tavsanli','Tavsanli','43'),('TR','TZX','Trabzon','Trabzon','61'),('TR','ULA','Ula','Ula','48'),('TR','ULU','Ulubey','Ulubey','64'),('TR','UMR','Umraniye','Umraniye','34'),('TR','UNY','Unye','Unye','52'),('TR','URL','Urla','Urla','35'),('TR','USA','Usak','Usak','64'),('TR','USK','Uskudar','Uskudar','34'),('TR','UZU','Uzunkopru','Uzunkopru','22'),('TR','VAK','Vakfikebir','Vakfikebir',''),('TR','VAN','Van','Van','65'),('TR','VAS','Sivas','Sivas','58'),('TR','VIZ','Vize','Vize','39'),('TR','YAK','Yakacik','Yakacik','34'),('TR','YAL','Yalova','Yalova','77'),('TR','YAR','Yarimca','Yarimca','41'),('TR','YBS','Yenibosna','Yenibosna','34'),('TR','YCA','Yenicaga','Yenicaga','14'),('TR','YEN','Yenice','Yenice','17'),('TR','YES','Yesilkoy','Yesilkoy','34'),('TR','YEZ','Yenipazar','Yenipazar','11'),('TR','YKP','Yakuplu','Yakuplu','34'),('TR','YLV','Yalvac','Yalvac','32'),('TR','YOZ','Yozgat','Yozgat','66'),('TR','YPZ','Yenipazar','Yenipazar','09'),('TR','YSR','Yenisehir','Yenisehir','16'),('TR','YTG','Yatagan','Yatagan','48'),('TR','YUM','Yumurtalik Bay','Yumurtalik Bay','01'),('TR','ZEY','Zeytinburnu','Zeytinburnu','34'),('TR','ZON','Zonguldak','Zonguldak','67'),('TT','','','',''),('TT','CHA','Chaguaramas','Chaguaramas',''),('TT','CRN','Carenage','Carenage',''),('TT','LAB','La Brea (Brighton)','La Brea (Brighton)',''),('TT','MAR','Marabella','Marabella',''),('TT','PIA','Piarco','Piarco',''),('TT','PLY','Plymouth','Plymouth',''),('TT','POS','Port-of-Spain','Port-of-Spain',''),('TT','PPL','Point Lizza','Point Lizza',''),('TT','PTF','Point Fortin','Point Fortin',''),('TT','PTG','Point Galeota','Point Galeota',''),('TT','PTP','Pointe a Pierre','Pointe a Pierre',''),('TT','PTS','Point Lisas','Point Lisas',''),('TT','SCA','Scarborough/Tobago','Scarborough/Tobago',''),('TT','SCR','Scarborough','Scarborough',''),('TT','SFE','San Fernando','San Fernando',''),('TT','TAB','Tobago','Tobago',''),('TT','TEM','Tembladora','Tembladora',''),('TT','TUN','Tunapuna','Tunapuna',''),('TT','VBL','Vista Bella','Vista Bella',''),('TV','','','',''),('TV','FUN','Funafuti','Funafuti',''),('TW','','','',''),('TW','APG','An Ping','An Ping',''),('TW','CHW','Chang-Hua','Chang-Hua',''),('TW','CLI','Chung-Li','Chung-Li',''),('TW','CMJ','Chi Mei','Chi Mei',''),('TW','CYI','Chiayi','Chiayi',''),('TW','FEY','Yuang-wang','Yuang-wang',''),('TW','GNI','Green Island','Green Island',''),('TW','HCN','Hengchun','Hengchun',''),('TW','HSZ','Hsin-chu','Hsin-chu',''),('TW','HUN','Hualien','Hualien',''),('TW','ILA','I-lan','I-lan',''),('TW','KEL','Keelung (Chilung)','Keelung (Chilung)',''),('TW','KEZ','Kepz','Kepz',''),('TW','KHH','Kaohsiung','Kaohsiung',''),('TW','KNH','Kinmen','Kinmen',''),('TW','KYD','Orchid Island','Orchid Island',''),('TW','LHN','Lishan','Lishan',''),('TW','MAL','Mai-Liai','Mai-Liai',''),('TW','MFK','Matsu','Matsu',''),('TW','MLI','Mai-liao','Mai-liao',''),('TW','MZG','Makung','Makung',''),('TW','NEZ','Nepz, Nantze','Nepz, Nantze',''),('TW','PIF','Pingtung','Pingtung',''),('TW','SHL','Sha-lun','Sha-lun',''),('TW','SMT','Sun Moon Lake','Sun Moon Lake',''),('TW','SUO','Suao','Suao',''),('TW','TAI','T\'ai-nan-hsien','T\'ai-nan-hsien',''),('TW','TGH','Tung Hai','Tung Hai',''),('TW','TNN','Tainan','Tainan',''),('TW','TOF','Toufen','Toufen',''),('TW','TPE','Taipei','Taipei',''),('TW','TTT','Taitung','Taitung',''),('TW','TUZ','Tou-liu','Tou-liu',''),('TW','TXG','Taichung','Taichung',''),('TW','TYN','Taoyuan','Taoyuan',''),('TW','WOT','Wonan','Wonan',''),('TW','WTU','Wu-tu','Wu-tu',''),('TW','WUJ','Wu-jih','Wu-jih',''),('TW','YAN','Yung-an','Yung-an',''),('TW','ZMI','Miao-li','Miao-li',''),('TZ','','','',''),('TZ','ARK','Arusha','Arusha',''),('TZ','BKZ','Bukoba','Bukoba',''),('TZ','DAR','Dar es Salaam','Dar es Salaam',''),('TZ','DOD','Dodoma','Dodoma',''),('TZ','GIT','Geita','Geita',''),('TZ','IKW','Ikwiriri','Ikwiriri',''),('TZ','IRI','Iringa','Iringa',''),('TZ','ISK','Isaka','Isaka',''),('TZ','JOM','Njombe','Njombe',''),('TZ','JRO','Kilimanjaro','Kilimanjaro',''),('TZ','KHM','Kahama','Kahama',''),('TZ','KIK','Kilwa Kivinje','Kilwa Kivinje',''),('TZ','KIM','Kilwa Masoko','Kilwa Masoko',''),('TZ','KIY','Kilwa','Kilwa',''),('TZ','KRG','Korogwe','Korogwe',''),('TZ','LDI','Lindi','Lindi',''),('TZ','LKY','Lake Manyara','Lake Manyara',''),('TZ','LUY','Lushoto','Lushoto',''),('TZ','MBI','Mbeya','Mbeya',''),('TZ','MFA','Mafia','Mafia',''),('TZ','MIC','Michiuja','Michiuja',''),('TZ','MIK','Mikindani','Mikindani',''),('TZ','MKO','Mkokotoni, Zanzibar','Mkokotoni, Zanzibar',''),('TZ','MOH','Mohoro','Mohoro',''),('TZ','MRG','Morogoro','Morogoro',''),('TZ','MTS','Mtsora','Mtsora',''),('TZ','MUZ','Musoma','Musoma',''),('TZ','MWN','Mwadui','Mwadui',''),('TZ','MWZ','Mwanza','Mwanza',''),('TZ','MYW','Mtwara','Mtwara',''),('TZ','NCH','Nachingwea','Nachingwea',''),('TZ','NZG','Nzega','Nzega',''),('TZ','PAN','Pangani','Pangani',''),('TZ','PMA','Pemba','Pemba',''),('TZ','RIJ','Rijiju','Rijiju',''),('TZ','SAM','Samanga','Samanga',''),('TZ','SEU','Seronera','Seronera',''),('TZ','SGX','Songea','Songea',''),('TZ','SHY','Shinyanga','Shinyanga',''),('TZ','SUT','Sumbawanga','Sumbawanga',''),('TZ','TBO','Tabora','Tabora',''),('TZ','TGT','Tanga','Tanga',''),('TZ','TKQ','Kigoma','Kigoma',''),('TZ','TUN','Tunduna','Tunduna',''),('TZ','WHA','Wesha','Wesha',''),('TZ','XMI','Masasi','Masasi',''),('TZ','ZNZ','Zanzibar','Zanzibar',''),('UA','','','',''),('UA','BGD','Belgorod-Dnestrovskiy','Belgorod-Dnestrovskiy',''),('UA','BRO','Brovary','Brovary',''),('UA','BUC','Bucha','Bucha',''),('UA','CBA','Chernobayevka','Chernobayevka',''),('UA','CCI','Chop-Chierna','Chop-Chierna',''),('UA','CEJ','Chernigov','Chernigov',''),('UA','CHD','Chinadiyevo','Chinadiyevo',''),('UA','CHE','Chornobyl\'','Chornobyl\'',''),('UA','CKC','Cherkassy','Cherkassy',''),('UA','CKK','Cherkasskaya','Cherkasskaya',''),('UA','COP','Chop','Chop',''),('UA','CWC','Chernivtsi (Chernovtsy)','Chernivtsi (Chernovtsy)',''),('UA','CZA','Chop-Zakhon','Chop-Zakhon',''),('UA','DNE','Dorozhnoye','Dorozhnoye',''),('UA','DNK','Dnepropetrovsk','Dnepropetrovsk',''),('UA','DOK','Donetsk','Donetsk',''),('UA','DZK','Dneprodzerzhinsk','Dneprodzerzhinsk',''),('UA','ERD','Berdyansk','Berdyansk',''),('UA','FEO','Feodosiya','Feodosiya',''),('UA','HMJ','Khmelnitskiy','Khmelnitskiy',''),('UA','HRK','Kharkov','Kharkov',''),('UA','IEV','Kiev','Kiev',''),('UA','IFO','Ivano-Frankovsk','Ivano-Frankovsk',''),('UA','ILK','Illichivs\'k','Illichivs\'k',''),('UA','IZM','Izmail','Izmail',''),('UA','KAL','Kalush','Kalush',''),('UA','KBP','Borispol Apt/Kiev','Borispol Apt/Kiev',''),('UA','KCP','Kamenets-Podolskiy','Kamenets-Podolskiy',''),('UA','KEH','Kerch','Kerch',''),('UA','KGD','Krasnograd','Krasnograd',''),('UA','KGO','Kirovograd','Kirovograd',''),('UA','KHE','Kherson','Kherson',''),('UA','KHU','Kremenchug','Kremenchug',''),('UA','KIA','Kiliya','Kiliya',''),('UA','KRQ','Kramatorsk','Kramatorsk',''),('UA','KSK','Komsomol\'sk','Komsomol\'sk',''),('UA','KTP','Konotop','Konotop',''),('UA','KUL','Kulinichi','Kulinichi',''),('UA','KVL','Kovel\'','Kovel\'',''),('UA','KWG','Krivoy Rog','Krivoy Rog',''),('UA','LVI','L\'viv','L\'viv',''),('UA','LWO','Lwow','Lwow',''),('UA','MDK','Mandrykino','Mandrykino',''),('UA','MKA','Mostiska','Mostiska',''),('UA','MPW','Mariupol (ex Zhdanov)','Mariupol (ex Zhdanov)',''),('UA','MUK','Mukachevo','Mukachevo',''),('UA','MXR','Mirgorod','Mirgorod',''),('UA','NIK','Nikolayev','Nikolayev',''),('UA','NLV','Nikolaev','Nikolaev',''),('UA','NNP','Nizhnedneprovsk','Nizhnedneprovsk',''),('UA','NOV','Novovolyns\'k','Novovolyns\'k',''),('UA','NVO','Novohrad-Volyns\'kyy','Novohrad-Volyns\'kyy',''),('UA','OCT','Oktyabrsk','Oktyabrsk',''),('UA','ODS','Odessa','Odessa',''),('UA','OLK','Olevsk','Olevsk',''),('UA','OZH','Zaporozhye','Zaporozhye',''),('UA','PAH','Pavlohrad','Pavlohrad',''),('UA','PLK','Pryluky','Pryluky',''),('UA','PLV','Poltava','Poltava',''),('UA','PMY','Pustomyty','Pustomyty',''),('UA','PRN','Plodorodnoye','Plodorodnoye',''),('UA','PRU','Prut','Prut',''),('UA','RAR','Rava Ruskaya','Rava Ruskaya',''),('UA','RNI','Reni','Reni',''),('UA','RWN','Rovno','Rovno',''),('UA','SDR','Soledar','Soledar',''),('UA','SEV','Severodoneck','Severodoneck',''),('UA','SIP','Simferopol','Simferopol',''),('UA','SKD','Skadovsk','Skadovsk',''),('UA','SLY','Susly','Susly',''),('UA','STA','Starokonstantinov','Starokonstantinov',''),('UA','SVP','Sevastopol','Sevastopol',''),('UA','SYA','Slov\'yans\'k','Slov\'yans\'k',''),('UA','TCV','Tyachiv','Tyachiv',''),('UA','TNL','Ternopol','Ternopol',''),('UA','TSY','Trostyanets','Trostyanets',''),('UA','UCK','Lutsk','Lutsk',''),('UA','UDY','Ust Dunaysk','Ust Dunaysk',''),('UA','UGL','Uglegorsk','Uglegorsk',''),('UA','UMY','Sumy','Sumy',''),('UA','USD','Ust Donetskiy','Ust Donetskiy',''),('UA','UZH','Uzhgorod','Uzhgorod',''),('UA','VAD','Vadul','Vadul',''),('UA','VBO','Velyikyy Bychkiv','Velyikyy Bychkiv',''),('UA','VEY','Velikiy','Velikiy',''),('UA','VIN','Vinnica','Vinnica',''),('UA','VLV','Vladimir-Volynskiy','Vladimir-Volynskiy',''),('UA','VSG','Lugansk','Lugansk',''),('UA','YAL','Yalta','Yalta',''),('UA','YEO','Yemil\'chino','Yemil\'chino',''),('UA','YUZ','Yuzhnyy','Yuzhnyy',''),('UA','YVV','Yavorov','Yavorov',''),('UA','ZDO','Zavydovo','Zavydovo',''),('UA','ZOL','Zolotaya Balka','Zolotaya Balka',''),('UA','ZTR','Zhitomir','Zhitomir',''),('UG','','','',''),('UG','BUG','Bugembe','Bugembe',''),('UG','BUS','Busia','Busia',''),('UG','EBB','Entebbe','Entebbe',''),('UG','FPO','Fort Portal','Fort Portal',''),('UG','GAB','Gaba','Gaba',''),('UG','JIN','Jinja','Jinja',''),('UG','KAB','Kabale','Kabale',''),('UG','KBG','Kabalega Falls','Kabalega Falls',''),('UG','KCU','Masindi','Masindi',''),('UG','KGM','Kitgum','Kitgum',''),('UG','KLA','Kampala','Kampala',''),('UG','KOB','Koboko','Koboko',''),('UG','KSE','Kasese','Kasese',''),('UG','LIR','Lira','Lira',''),('UG','LUG','Lugazi','Lugazi',''),('UG','MAL','Malaba','Malaba',''),('UG','MBA','Mbale','Mbale',''),('UG','MBQ','Mbarara','Mbarara',''),('UG','MSK','Masaka','Masaka',''),('UG','MUB','Mubende','Mubende',''),('UG','OYG','Moyo','Moyo',''),('UG','PAF','Pakuba','Pakuba',''),('UG','PKE','Pakelle','Pakelle',''),('UG','RUA','Arua','Arua',''),('UG','SRT','Soroti','Soroti',''),('UG','TRY','Tororo','Tororo',''),('UG','ULU','Gulu','Gulu',''),('UM','','','',''),('UM','AWK','Wake Island','Wake Island','79'),('UM','BAK','Baker Island','Baker Island','81'),('UM','HOW','Howland Island','Howland Island','84'),('UM','JAR','Jarvis Island','Jarvis Island','86'),('UM','JON','Johnston Atoll','Johnston Atoll','67'),('UM','KIN','Kingman Reef','Kingman Reef','89'),('UM','MDY','Midway Islands','Midway Islands','71'),('UM','NAV','Navassa Island','Navassa Island','76'),('UM','PAL','Palmyra Atoll','Palmyra Atoll','95'),('US','','','',''),('US','AA4','Acampo','Acampo','CA'),('US','AA5','Sparta','Sparta','GA'),('US','AA6','Amador','Amador','IA'),('US','AAA','Attalla','Attalla','AL'),('US','AAB','Anamosa','Anamosa','IA'),('US','AAC','Bloomfield','Bloomfield','CT'),('US','AAD','Bessemer City','Bessemer City','NC'),('US','AAE','Arapahoe','Arapahoe','CO'),('US','AAF','Apalachicola','Apalachicola','FL'),('US','AAG','Cohutta','Cohutta','GA'),('US','AAH','Covington','Covington','TN'),('US','AAI','Alpharetta','Alpharetta','GA'),('US','AAJ','Sweetwater','Sweetwater','FL'),('US','AAK','Armada','Armada','MI'),('US','AAL','Madison','Madison','OH'),('US','AAM','Salem','Salem','AL'),('US','AAN','Aurora','Aurora','NC'),('US','AAO','Summit','Summit','SC'),('US','AAP','Arlington/Baltimore','Arlington/Baltimore','MD'),('US','AAQ','Audubon','Audubon','PA'),('US','AAR','Culpeper','Culpeper','VA'),('US','AAS','Saint Charles','Saint Charles','MN'),('US','AAT','Danville','Danville','WA'),('US','AAU','Dresden','Dresden','NY'),('US','AAV','East Berlin','East Berlin','CT'),('US','AAW','Manahawkin','Manahawkin','NJ'),('US','AAX','Eatonton','Eatonton','GA'),('US','AAY','Saint Anthony','Saint Anthony','IN'),('US','AAZ','Parker','Parker','AZ'),('US','AB2','Albany','Albany','WY'),('US','AB3','Aberdeen','Aberdeen','NJ'),('US','ABA','Oldsmar','Oldsmar','FL'),('US','ABB','Abbeville','Abbeville','AL'),('US','ABC','Pt Hadlock','Pt Hadlock','WA'),('US','ABD','Abbotsford','Abbotsford','WI'),('US','ABE','Easton','Easton','PA'),('US','ABF','Abbeville','Abbeville','SC'),('US','ABG','Abingdon','Abingdon','IL'),('US','ABH','Auburn Hills','Auburn Hills','MI'),('US','ABI','Abilene','Abilene','TX'),('US','ABJ','Abbott Park','Abbott Park','IL'),('US','ABK','Aberdeen','Aberdeen','KY'),('US','ABL','Ambler','Ambler','AK'),('US','ABM','Auburn','Auburn','MI'),('US','ABN','Ashburn','Ashburn','GA'),('US','ABO','Bartow','Bartow','GA'),('US','ABP','St Charles','St Charles','MO'),('US','ABQ','Albuquerque','Albuquerque','NM'),('US','ABR','Aberdeen','Aberdeen','SD'),('US','ABS','Spring','Spring','TX'),('US','ABT','Sabattus','Sabattus','ME'),('US','ABU','Auburn','Auburn','MA'),('US','ABV','Albertville','Albertville','AL'),('US','ABX','Du Pont','Du Pont','WA'),('US','ABY','Albany','Albany','GA'),('US','ABZ','Abilene','Abilene','KS'),('US','AC2','Arcade','Arcade','NY'),('US','AC3','Pacific','Pacific','MO'),('US','AC4','Lavaca','Lavaca','AR'),('US','AC5','Alcade','Alcade','NM'),('US','ACA','Alicia','Alicia','MI'),('US','ACB','Bellaire','Bellaire','MI'),('US','ACC','Raymond','Raymond','WA'),('US','ACD','Capitol Heights','Capitol Heights','MD'),('US','ACE','Carol Stream','Carol Stream','IL'),('US','ACF','Sumas','Sumas','WA'),('US','ACG','Catskill','Catskill','NY'),('US','ACH','Central Falls','Central Falls','RI'),('US','ACI','Machias','Machias','ME'),('US','ACJ','South Bend','South Bend','WA'),('US','ACK','Nantucket','Nantucket','MA'),('US','ACL','Chester','Chester','VT'),('US','ACM','Chaska','Chaska','MN'),('US','ACN','Cliffside','Cliffside','NC'),('US','ACO','Alcoa','Alcoa','TN'),('US','ACP','Anchor Point','Anchor Point','AK'),('US','ACQ','Ancram','Ancram','NY'),('US','ACR','Ackerman','Ackerman','GA'),('US','ACS','Cementon','Cementon','NY'),('US','ACT','Waco','Waco','TX'),('US','ACU','Canton','Canton','MA'),('US','ACV','Arcata','Arcata','CA'),('US','ACW','Columbia','Columbia','MD'),('US','ACX','Absecon','Absecon','NJ'),('US','ACY','American Canyon','American Canyon','CA'),('US','ACZ','Conway','Conway','SC'),('US','AD2','Shadeland, Tippecanoe','Shadeland, Tippecanoe','IN'),('US','ADA','Arkadelphia','Arkadelphia','AR'),('US','ADB','Corning','Corning','IA'),('US','ADC','Camphill','Camphill','PA'),('US','ADD','Addis','Addis','LA'),('US','ADE','Adel','Adel','GA'),('US','ADF','Cordele','Cordele','GA'),('US','ADG','Adrian','Adrian','MI'),('US','ADH','Adams','Adams','NY'),('US','ADI','Arcadia','Arcadia','WI'),('US','ADJ','Chester','Chester','CT'),('US','ADK','Adak Island/Adak Apt','Adak Island/Adak Apt','AK'),('US','ADL','Andalusia','Andalusia','AL'),('US','ADM','Ardmore','Ardmore','OK'),('US','ADN','Ashdown','Ashdown','AR'),('US','ADO','Coventry','Coventry','RI'),('US','ADP','Conway','Conway','AR'),('US','ADQ','Kodiak','Kodiak','AK'),('US','ADR','Andrews','Andrews','SC'),('US','ADS','Addison','Addison','AL'),('US','ADT','Ada','Ada','OK'),('US','ADU','Adelanto','Adelanto','CA'),('US','ADV','Adairsville','Adairsville','GA'),('US','ADW','Camp Springs','Camp Springs','MD'),('US','ADX','Addison','Addison','OH'),('US','ADY','Ardsley','Ardsley','NY'),('US','ADZ','Ada','Ada','MI'),('US','AE2','Evadale','Evadale','AR'),('US','AE3','Whaleysville','Whaleysville','MD'),('US','AE4','Mena','Mena','AR'),('US','AE5','Swansea','Swansea','MA'),('US','AE6','Haven','Haven','KS'),('US','AEA','Flora','Flora','IL'),('US','AEB','Fords','Fords','NJ'),('US','AEC','Clarence','Clarence','NY'),('US','AED','Aleneva','Aleneva','AK'),('US','AEE','Gaffney','Gaffney','SC'),('US','AEF','Gibsonton','Gibsonton','FL'),('US','AEG','Marengo','Marengo','IN'),('US','AEH','Greensburg','Greensburg','KY'),('US','AEI','Amelia','Amelia','LA'),('US','AEJ','Adamstown','Adamstown','PA'),('US','AEK','Aberdeen','Aberdeen','MS'),('US','AEL','Albert Lea','Albert Lea','MN'),('US','AEM','Water Mill','Water Mill','NY'),('US','AEN','Alsen','Alsen','NY'),('US','AEO','Calverton','Calverton','VA'),('US','AEP','Sarepta','Sarepta','LA'),('US','AEQ','Anderson City','Anderson City','GA'),('US','AER','Ayer','Ayer','MA'),('US','AES','Matteson','Matteson','IL'),('US','AET','Allakaket','Allakaket','AK'),('US','AEU','Hamden','Hamden','CT'),('US','AEV','Asheville','Asheville','NC'),('US','AEW','Allentown','Allentown','NJ'),('US','AEX','Alexander','Alexander','IA'),('US','AEY','Carneys Point','Carneys Point','NJ'),('US','AEZ','Armstrong','Armstrong','IA'),('US','AF2','Ashford','Ashford','AL'),('US','AFA','Alstead','Alstead','NH'),('US','AFB','Avondale','Avondale','PA'),('US','AFC','Atascadero','Atascadero','CA'),('US','AFD','Mansfield','Mansfield','LA'),('US','AFE','Alfred','Alfred','ME'),('US','AFF','Affton','Affton','MO'),('US','AFG','Blackduck','Blackduck','MN'),('US','AFH','Bath','Bath','NC'),('US','AFI','Brandon','Brandon','SD'),('US','AFJ','Beloit','Beloit','OH'),('US','AFK','Afognak','Afognak','AK'),('US','AFL','Bluefield','Bluefield','WV'),('US','AFM','Bingham','Bingham','ME'),('US','AFN','Jaffrey','Jaffrey','NH'),('US','AFO','Afton','Afton','WY'),('US','AFP','Big Flats','Big Flats','NY'),('US','AFQ','Afton','Afton','VA'),('US','AFR','Brooks','Brooks','KY'),('US','AFS','Alfred Station','Alfred Station','NY'),('US','AFT','Afton','Afton','TN'),('US','AFU','Butler','Butler','GA'),('US','AFV','Battenville','Battenville','NY'),('US','AFW','Webster, Harris','Webster, Harris','TX'),('US','AFX','Bethayres','Bethayres','PA'),('US','AFY','Ballard/Seattle','Ballard/Seattle','WA'),('US','AFZ','Brooklyn','Brooklyn','WI'),('US','AGA','Saginaw','Saginaw','OR'),('US','AGB','Byant','Byant','SD'),('US','AGC','Bear','Bear','DE'),('US','AGD','Brundidge','Brundidge','AL'),('US','AGE','Adger','Adger','AL'),('US','AGF','Bowie','Bowie','AZ'),('US','AGG','Cottage Grove','Cottage Grove','MN'),('US','AGH','Agoura Hills','Agoura Hills','CA'),('US','AGI','Magnolia','Magnolia','TX'),('US','AGK','Danville','Danville','OH'),('US','AGL','Atglen','Atglen','PA'),('US','AGM','Andrews','Andrews','NC'),('US','AGN','Angoon','Angoon','AK'),('US','AGO','Magnolia','Magnolia','AR'),('US','AGP','Gap','Gap','PA'),('US','AGQ','Algonquin','Algonquin','IL'),('US','AGR','Granger','Granger','WA'),('US','AGS','Augusta','Augusta','GA'),('US','AGT','Arlington','Arlington','SD'),('US','AGU','Augusta','Augusta','KY'),('US','AGV','Autaugaville','Autaugaville','AL'),('US','AGW','Arlington, Houston','Arlington, Houston','TN'),('US','AGX','Angleton','Angleton','TX'),('US','AGY','Amargosa Valley','Amargosa Valley','NV'),('US','AGZ','Arlington','Arlington','AZ'),('US','AHA','Aloha','Aloha','OR'),('US','AHB','Archbald','Archbald','PA'),('US','AHC','Herlong','Herlong','CA'),('US','AHD','Aberdeen','Aberdeen','OH'),('US','AHE','Ahoskie','Ahoskie','NC'),('US','AHG','Stratford','Stratford','NY'),('US','AHH','Amery','Amery','WI'),('US','AHI','Branchville','Branchville','NJ'),('US','AHL','Ashland','Ashland','NH'),('US','AHM','Hampton','Hampton','AL'),('US','AHN','Athens','Athens','GA'),('US','AHO','Athol','Athol','MA'),('US','AHR','Amherst','Amherst','VA'),('US','AHS','Calhoun Falls','Calhoun Falls','SC'),('US','AHT','Amchitka','Amchitka','AK'),('US','AHU','Alachua','Alachua','FL'),('US','AHV','Caruthersville','Caruthersville','MO'),('US','AHW','Ashaway','Ashaway','RI'),('US','AHY','Ashley','Ashley','PA'),('US','AIA','Alliance','Alliance','NE'),('US','AIB','Anita Bay','Anita Bay','AK'),('US','AIC','Maricopa','Maricopa','CA'),('US','AID','Anderson','Anderson','IN'),('US','AIE','Aiea (Oahu)','Aiea (Oahu)','HI'),('US','AIF','Fairfax','Fairfax','CA'),('US','AIG','Lansing','Lansing','OH'),('US','AIH','Alliance','Alliance','OH'),('US','AII','Sardinia','Sardinia','NY'),('US','AIJ','Saint James','Saint James','MO'),('US','AIK','Aiken','Aiken','SC'),('US','AIL','Annville','Annville','PA'),('US','AIM','Mannington Mills','Mannington Mills','NJ'),('US','AIN','Wainwright','Wainwright','AK'),('US','AIO','Atlantic','Atlantic','IA'),('US','AIP','Saint Rose Plantation','Saint Rose Plantation','LA'),('US','AIR','Martinsburg','Martinsburg','PA'),('US','AIS','Atkins','Atkins','VA'),('US','AIT','Saint Marks','Saint Marks','FL'),('US','AIU','Manlius','Manlius','NY'),('US','AIV','Aliceville','Aliceville','AL'),('US','AIW','Fair View','Fair View','NJ'),('US','AIX','Fairfax','Fairfax','VT'),('US','AIY','Atlantic City','Atlantic City','NJ'),('US','AIZ','Kaiser/Lake Ozark','Kaiser/Lake Ozark','MO'),('US','AJC','Angelica','Angelica','NY'),('US','AJD','Adell','Adell','WI'),('US','AJH','Anthem','Anthem','AZ'),('US','AJR','Andover','Andover','SD'),('US','AJW','Avondale','Avondale','CO'),('US','AJY','Casey','Casey','IL'),('US','AKA','Akron','Akron','MI'),('US','AKB','Atka','Atka','AK'),('US','AKC','Akron','Akron','IN'),('US','AKD','Lake Dallas','Lake Dallas','TX'),('US','AKE','Ankeny','Ankeny','IA'),('US','AKH','Akron','Akron','OH'),('US','AKI','Akiak','Akiak','AK'),('US','AKK','Akhiok','Akhiok','AK'),('US','AKL','Pataskala','Pataskala','OH'),('US','AKM','Adams','Adams','TN'),('US','AKN','King Salmon','King Salmon','AK'),('US','AKO','Akron','Akron','CO'),('US','AKP','Anaktuvuk','Anaktuvuk','AK'),('US','AKR','Akron','Akron','NY'),('US','AKS','Parkston','Parkston','SD'),('US','AKT','Marked Tree','Marked Tree','AR'),('US','AKU','Akutan','Akutan','AK'),('US','AKV','Arcola','Arcola','IL'),('US','AKW','Walkertown','Walkertown','NC'),('US','AKY','Ackley','Ackley','IA'),('US','AL2','Albany','Albany','MN'),('US','ALA','Albany','Albany','CA'),('US','ALB','Albany','Albany','NY'),('US','ALD','Ashland','Ashland','VA'),('US','ALE','Alpine','Alpine','TX'),('US','ALF','Alva','Alva','FL'),('US','ALG','Algonac','Algonac','MI'),('US','ALH','Alhambra','Alhambra','CA'),('US','ALI','Alice','Alice','TX'),('US','ALJ','Alcester','Alcester','SD'),('US','ALK','Allison Park','Allison Park','PA'),('US','ALL','Allegan','Allegan','MI'),('US','ALM','Alamogordo','Alamogordo','NM'),('US','ALN','Alton','Alton','IL'),('US','ALO','Waterloo','Waterloo','IA'),('US','ALP','Alpha','Alpha','OH'),('US','ALQ','Avilla','Avilla','IN'),('US','ALR','Alburg','Alburg','VT'),('US','ALS','Alamosa','Alamosa','CO'),('US','ALT','Allerton','Allerton','IA'),('US','ALU','Alburtis','Alburtis','PA'),('US','ALV','Albertville','Albertville','MN'),('US','ALW','Walla Walla','Walla Walla','WA'),('US','ALX','Alexander City','Alexander City','AL'),('US','ALY','Ashland','Ashland','AL'),('US','ALZ','Alitak','Alitak','AK'),('US','AMA','Amarillo','Amarillo','TX'),('US','AMB','Ambrose','Ambrose','ND'),('US','AMC','Alamance','Alamance','NC'),('US','AMD','Ama','Ama','LA'),('US','AME','Ardmore','Ardmore','TN'),('US','AMF','Amagansett','Amagansett','NY'),('US','AMG','Cambridge','Cambridge','WI'),('US','AMH','Amherst','Amherst','NY'),('US','AMI','Carmi','Carmi','IL'),('US','AMJ','Amity','Amity','OR'),('US','AMK','Atmore','Atmore','AL'),('US','AML','Amelia','Amelia','VA'),('US','AMM','Amasa','Amasa','MI'),('US','AMN','Alma','Alma','MI'),('US','AMO','Alamo','Alamo','TX'),('US','AMP','Assumption','Assumption','IL'),('US','AMQ','Alma','Alma','GA'),('US','AMR','Ambler','Ambler','PA'),('US','AMS','Amsterdam','Amsterdam','NY'),('US','AMT','Alamo','Alamo','TN'),('US','AMU','Americus','Americus','GA'),('US','AMV','Marvell','Marvell','AR'),('US','AMW','Ames','Ames','IA'),('US','AMX','Amesbury','Amesbury','MA'),('US','AMY','Amboy','Amboy','IL'),('US','AMZ','Algoma','Algoma','MS'),('US','ANA','Anaheim','Anaheim','CA'),('US','ANB','Anniston','Anniston','AL'),('US','ANC','Anchorage','Anchorage','AK'),('US','AND','Anderson','Anderson','SC'),('US','ANE','Anderson','Anderson','AL'),('US','ANF','Andrews','Andrews','IN'),('US','ANG','Angier','Angier','NC'),('US','ANH','Angola','Angola','NY'),('US','ANI','Aniak','Aniak','AK'),('US','ANJ','San Joaquin River','San Joaquin River','CA'),('US','ANK','Anoka','Anoka','MN'),('US','ANL','Ashland','Ashland','KY'),('US','ANM','Anmoore','Anmoore','WV'),('US','ANN','Annette Island','Annette Island','AK'),('US','ANO','Anderson','Anderson','MO'),('US','ANP','Annapolis','Annapolis','MD'),('US','ANQ','Angola','Angola','IN'),('US','ANR','Andover','Andover','MA'),('US','ANS','Ansonia','Ansonia','OH'),('US','ANT','Antler','Antler','ND'),('US','ANU','Andrade','Andrade','CA'),('US','ANV','Anvik','Anvik','AK'),('US','ANW','Avon','Avon','CO'),('US','ANX','Antonia','Antonia','MO'),('US','ANY','Anthony','Anthony','KS'),('US','ANZ','Antioch','Antioch','CA'),('US','AOA','Santa Rosa','Santa Rosa','NM'),('US','AOB','Albion','Albion','IL'),('US','AOC','Avoca','Avoca','PA'),('US','AOD','Atoka','Atoka','OK'),('US','AOE','Malone','Malone','TX'),('US','AOF','Homer Glen','Homer Glen','IL'),('US','AOI','Lavonia','Lavonia','GA'),('US','AOK','Catatonk','Catatonk','NY'),('US','AOL','Paoli','Paoli','PA'),('US','AOM','Attleboro','Attleboro','MA'),('US','AON','Albion','Albion','NY'),('US','AOO','Altoona','Altoona','PA'),('US','AOP','Apopka','Apopka','FL'),('US','AOQ','Alto','Alto','GA'),('US','AOR','Falconer','Falconer','NY'),('US','AOS','Amook','Amook','AK'),('US','AOT','Mascot','Mascot','TN'),('US','AOV','Dover','Dover','MA'),('US','AOW','Marlow','Marlow','OK'),('US','AOX','Albion','Albion','MI'),('US','AOY','Alloy','Alloy','WV'),('US','AOZ','Andersonville','Andersonville','TN'),('US','APA','Alpha','Alpha','NJ'),('US','APB','Campbell','Campbell','TX'),('US','APC','Napa','Napa','CA'),('US','APD','Aberdeen','Aberdeen','ID'),('US','APE','Lapeer','Lapeer','MI'),('US','APF','Naples','Naples','FL'),('US','APG','Aberdeen','Aberdeen','MD'),('US','APH','Bowling Green','Bowling Green','VA'),('US','API','Apalachin','Apalachin','NY'),('US','APJ','Apache Junction','Apache Junction','AZ'),('US','APK','Allen Park','Allen Park','MI'),('US','APL','Alpine','Alpine','AL'),('US','APM','Pelham','Pelham','AL'),('US','APN','Alpena','Alpena','MI'),('US','APO','Aptos','Aptos','CA'),('US','APP','Appleton','Appleton','MN'),('US','APS','Attapulgus','Attapulgus','GA'),('US','APT','Jasper','Jasper','TN'),('US','APU','Sapulpa','Sapulpa','OK'),('US','APV','Apple Valley','Apple Valley','CA'),('US','APW','Wickenburg','Wickenburg','AZ'),('US','APX','Apex','Apex','NC'),('US','AQB','Ava','Ava','MO'),('US','AQD','Aledo','Aledo','TX'),('US','AQE','Seale','Seale','AL'),('US','AQF','Anamoose','Anamoose','ND'),('US','AQI','Albin','Albin','WY'),('US','AQL','Arnold','Arnold','PA'),('US','AQN','Cameron','Cameron','OK'),('US','AQO','Aquebogue','Aquebogue','NY'),('US','AQP','Aliquippa','Aliquippa','PA'),('US','AQS','Manchester','Manchester','TN'),('US','AQT','Barton','Barton','AL'),('US','AQX','Arabi','Arabi','LA'),('US','AQY','Alyeska','Alyeska','AK'),('US','AQZ','Ansonia','Ansonia','CT'),('US','ARA','New Iberia','New Iberia','LA'),('US','ARB','Ann Arbor','Ann Arbor','MI'),('US','ARC','Arctic Village','Arctic Village','AK'),('US','ARD','Arlington','Arlington','GA'),('US','ARE','Arlington','Arlington','MN'),('US','ARF','Arlington','Arlington','OR'),('US','ARG','Walnut Ridge','Walnut Ridge','AR'),('US','ARH','Arden Hills','Arden Hills','MN'),('US','ARI','Arcadia','Arcadia','FL'),('US','ARJ','Arlington','Arlington','TX'),('US','ARK','Arkansas City','Arkansas City','KS'),('US','ARL','Arley','Arley','AL'),('US','ARM','Armuchee','Armuchee','GA'),('US','ARN','Akron','Akron','PA'),('US','ARO','Archbold','Archbold','OH'),('US','ARP','Arlington','Arlington','VA'),('US','ARQ','Marble','Marble','NC'),('US','ARR','Arleta','Arleta','CA'),('US','ARS','Arenzville','Arenzville','IL'),('US','ART','Watertown','Watertown','NY'),('US','ARU','Arbuckle','Arbuckle','CA'),('US','ARV','Minocqua','Minocqua','WI'),('US','ARW','Warsaw','Warsaw','NY'),('US','ARX','Asbury Park','Asbury Park','NJ'),('US','ARY','Amory','Amory','MS'),('US','ARZ','Arcadia','Arcadia','SC'),('US','ASA','Astoria/Queens/New York','Astoria/Queens/New York','NY'),('US','ASB','Asbury, Gloucester','Asbury, Gloucester','NJ'),('US','ASC','Arkansas City','Arkansas City','AR'),('US','ASD','Ashland','Ashland','MA'),('US','ASE','Aspen','Aspen','CO'),('US','ASF','Ashtabula','Ashtabula','OH'),('US','ASG','Austinburg','Austinburg','OH'),('US','ASH','Nashua','Nashua','NH'),('US','ASI','Ashland','Ashland','OR'),('US','ASJ','Assonet','Assonet','MA'),('US','ASK','Ashland','Ashland','OH'),('US','ASL','Marshall','Marshall','TX'),('US','ASM','Ashkum','Ashkum','IL'),('US','ASN','Talladega','Talladega','AL'),('US','ASO','Ashville','Ashville','OH'),('US','ASP','Altamonte Springs','Altamonte Springs','FL'),('US','ASQ','Austin','Austin','NV'),('US','ASR','Asheboro','Asheboro','NC'),('US','ASS','Ware Shoals','Ware Shoals','SC'),('US','AST','Astoria','Astoria','OR'),('US','ASU','Asbury, Warren','Asbury, Warren','NJ'),('US','ASV','Ashton','Ashton','ID'),('US','ASW','Watsontown','Watsontown','PA'),('US','ASX','Ashland','Ashland','WI'),('US','ASY','Ashley','Ashley','ND'),('US','ASZ','Sumiton','Sumiton','AL'),('US','AT2','Allentown, Allegany','Allentown, Allegany','NY'),('US','AT3','Arlington, Knox','Arlington, Knox','TN'),('US','AT4','Astoria','Astoria','IL'),('US','ATA','Athens','Athens','AL'),('US','ATB','Athens','Athens','NY'),('US','ATC','Atherton','Atherton','CA'),('US','ATD','Athol','Athol','ID'),('US','ATE','Antlers','Antlers','OK'),('US','ATF','Atkins','Atkins','AR'),('US','ATG','Atwood','Atwood','CA'),('US','ATH','Bath','Bath','NY'),('US','ATI','Mantachie','Mantachie','MS'),('US','ATJ','Almont','Almont','MI'),('US','ATK','Atqasuk','Atqasuk','AK'),('US','ATL','Atlanta','Atlanta','GA'),('US','ATM','Artesia','Artesia','CA'),('US','ATN','Athens','Athens','PA'),('US','ATO','Athens','Athens','OH'),('US','ATP','Atlas Point','Atlas Point','DE'),('US','ATQ','Atchison','Atchison','KS'),('US','ATR','Atreco','Atreco','TX'),('US','ATS','Artesia','Artesia','NM'),('US','ATT','Atmautluak','Atmautluak','AK'),('US','ATU','Attu Island','Attu Island','AK'),('US','ATV','Altavista','Altavista','VA'),('US','ATW','Appleton','Appleton','WI'),('US','ATX','Allenstown','Allenstown','NH'),('US','ATY','Watertown','Watertown','SD'),('US','ATZ','Atwater','Atwater','CA'),('US','AUA','Astatula','Astatula','FL'),('US','AUB','Auburn','Auburn','NY'),('US','AUC','Aurora','Aurora','CO'),('US','AUD','Auburndale','Auburndale','FL'),('US','AUE','Auburn','Auburn','ME'),('US','AUF','Aurora','Aurora','OH'),('US','AUG','Augusta','Augusta','ME'),('US','AUH','Auburn Heights','Auburn Heights','MI'),('US','AUI','Auburn','Auburn','IN'),('US','AUJ','Auburn','Auburn','WA'),('US','AUK','Alakanuk','Alakanuk','AK'),('US','AUL','Austell','Austell','GA'),('US','AUM','Austin','Austin','MN'),('US','AUN','Auburn','Auburn','CA'),('US','AUO','Auburn','Auburn','AL'),('US','AUQ','Aurora','Aurora','NE'),('US','AUR','Aurora','Aurora','NY'),('US','AUS','Austin','Austin','TX'),('US','AUT','Augusta','Augusta','AR'),('US','AUU','Aurora','Aurora','MO'),('US','AUV','Austintown','Austintown','OH'),('US','AUW','Wausau','Wausau','WI'),('US','AUX','Aurora','Aurora','OR'),('US','AUY','Aulander','Aulander','NC'),('US','AUZ','Aurora','Aurora','IL'),('US','AVA','Arvada','Arvada','CO'),('US','AVB','Avalon','Avalon','TX'),('US','AVC','Avon Lake','Avon Lake','ME'),('US','AVD','Avondale','Avondale','LA'),('US','AVE','Avenel','Avenel','NJ'),('US','AVF','Avon','Avon','MN'),('US','AVG','Avondale','Avondale','AZ'),('US','AVH','Avon-by-the-Sea','Avon-by-the-Sea','NJ'),('US','AVI','Avery Island','Avery Island','LA'),('US','AVJ','Aliso Viejo','Aliso Viejo','CA'),('US','AVK','Avon Lake','Avon Lake','OH'),('US','AVL','Arundel Village','Arundel Village','MD'),('US','AVM','Avonmore','Avonmore','PA'),('US','AVN','Avon','Avon','MA'),('US','AVO','Avon Park','Avon Park','FL'),('US','AVP','Wilkes-Barre/Scranton Apt','Wilkes-Barre/Scranton Apt','PA'),('US','AVQ','Avon','Avon','OH'),('US','AVR','Manville','Manville','RI'),('US','AVS','Avalon','Avalon','GA'),('US','AVT','Avery','Avery','TX'),('US','AVU','Aventura','Aventura','FL'),('US','AVV','Avon','Avon','NY'),('US','AVW','Avenel/Washington, D.C.','Avenel/Washington, D.C.','MD'),('US','AVX','Advance','Advance','MO'),('US','AVY','Avon','Avon','KY'),('US','AVZ','Avon','Avon','CT'),('US','AWA','Lawndale','Lawndale','NC'),('US','AWB','Ashwaubenon','Ashwaubenon','WI'),('US','AWD','Atwood','Atwood','KS'),('US','AWE','Caldwell','Caldwell','TX'),('US','AWI','Baldwin','Baldwin','MI'),('US','AWL','Hawley','Hawley','PA'),('US','AWM','West Memphis','West Memphis','AR'),('US','AWN','Allentown','Allentown','PA'),('US','AWO','Allenwood','Allenwood','NJ'),('US','AWP','Wall','Wall','PA'),('US','AWQ','Harwood','Harwood','MO'),('US','AWR','Acworth','Acworth','GA'),('US','AWS','Newcastle','Newcastle','ME'),('US','AWW','Awendaw','Awendaw','SC'),('US','AWX','Athens','Athens','TX'),('US','AWY','Gallaway','Gallaway','TN'),('US','AX2','Saxton','Saxton','PA'),('US','AXA','Alexandria','Alexandria','PA'),('US','AXB','Alexandria Bay','Alexandria Bay','NY'),('US','AXC','Armonk','Armonk','NY'),('US','AXD','Alexandria','Alexandria','IN'),('US','AXE','Armorel','Armorel','AR'),('US','AXF','Arnold','Arnold','MO'),('US','AXG','Algona','Algona','IA'),('US','AXH','Arthur','Arthur','IL'),('US','AXI','Arvin','Arvin','CA'),('US','AXM','Ashland','Ashland','MS'),('US','AXN','Alexandria','Alexandria','MN'),('US','AXO','Axton','Axton','VA'),('US','AXR','Alexandria','Alexandria','VA'),('US','AXS','Axis','Axis','AL'),('US','AXT','Baxter','Baxter','MN'),('US','AXV','Wapakoneta','Wapakoneta','OH'),('US','AXW','Maxwell','Maxwell','CA'),('US','AXX','Angel Fire','Angel Fire','NM'),('US','AXY','Alexandria','Alexandria','MO'),('US','AYA','Ashton','Ashton','IL'),('US','AYC','Canyon Country','Canyon Country','CA'),('US','AYD','Arbyrd','Arbyrd','MO'),('US','AYE','Fort Devens','Fort Devens','MA'),('US','AYF','Mayfield, Cuyahoga','Mayfield, Cuyahoga','OH'),('US','AYG','Cayuga','Cayuga','NY'),('US','AYH','Airway Heights','Airway Heights','WA'),('US','AYI','Cary','Cary','IL'),('US','AYL','Sandy Lake','Sandy Lake','PA'),('US','AYN','Wayland','Wayland','MI'),('US','AYO','Canyon','Canyon','TX'),('US','AYP','Sandy Springs','Sandy Springs','SC'),('US','AYQ','Ashland','Ashland','TN'),('US','AYR','Ayersville','Ayersville','GA'),('US','AYS','Waycross','Waycross','GA'),('US','AYT','Aylett','Aylett','VA'),('US','AYV','Saylesville','Saylesville','RI'),('US','AYY','Arden','Arden','NC'),('US','AYZ','Amityville','Amityville','NY'),('US','AZA','Altadena','Altadena','CA'),('US','AZB','Alvarado','Alvarado','CA'),('US','AZC','Alvin','Alvin','TX'),('US','AZD','Alviso','Alviso','CA'),('US','AZL','Azle','Azle','TX'),('US','AZM','Adams','Adams','WI'),('US','AZN','Altamont','Altamont','IL'),('US','AZO','Kalamazoo','Kalamazoo','MI'),('US','AZP','Altoona','Altoona','WI'),('US','AZQ','Altoona','Altoona','FL'),('US','AZS','Sierra Vista','Sierra Vista','AZ'),('US','AZT','Alum Rock','Alum Rock','CA'),('US','AZU','Azusa','Azusa','CA'),('US','AZX','Altus','Altus','AR'),('US','AZZ','Arlington','Arlington','WA'),('US','BAA','Bad Axe','Bad Axe','MI'),('US','BAB','Barboursville','Barboursville','WV'),('US','BAC','Bassett','Bassett','CA'),('US','BAD','Baldwin','Baldwin','NY'),('US','BAE','Baden','Baden','PA'),('US','BAF','Westfield','Westfield','MA'),('US','BAG','Bagdad','Bagdad','PA'),('US','BAH','Beacon Hills','Beacon Hills','NY'),('US','BAI','Bailey','Bailey','MI'),('US','BAJ','Blair','Blair','NE'),('US','BAK','Babcock','Babcock','WI'),('US','BAL','Baltimore','Baltimore','MD'),('US','BAM','Battle Mountain','Battle Mountain','NV'),('US','BAN','Badin','Badin','NC'),('US','BAO','Barlow','Barlow','OH'),('US','BAP','Bean City','Bean City','FL'),('US','BAQ','Baldwin','Baldwin','SC'),('US','BAR','Baker Island','Baker Island','AK'),('US','BAS','Bastrop','Bastrop','LA'),('US','BAT','Barberton','Barberton','OH'),('US','BAU','Burgaw','Burgaw','NC'),('US','BAV','Barnesville','Barnesville','GA'),('US','BAW','Balfour','Balfour','NC'),('US','BAX','Baldwin','Baldwin','FL'),('US','BAY','Bayonne','Bayonne','NJ'),('US','BAZ','Balboa','Balboa','CA'),('US','BB2','Burbank','Burbank','WA'),('US','BBA','Bethany Beach','Bethany Beach','DE'),('US','BBB','Benson','Benson','MN'),('US','BBC','Bay City','Bay City','TX'),('US','BBD','Brady','Brady','TX'),('US','BBE','Boscobel','Boscobel','WI'),('US','BBF','Burlington','Burlington','MA'),('US','BBG','Batesburg','Batesburg','SC'),('US','BBH','Blacksburg','Blacksburg','SC'),('US','BBI','Bradenton','Bradenton','FL'),('US','BBJ','Baldwin','Baldwin','GA'),('US','BBK','Bound Brook','Bound Brook','NJ'),('US','BBL','Big Bear Lake','Big Bear Lake','CA'),('US','BBM','Bamberg','Bamberg','SC'),('US','BBN','Ball Ground','Ball Ground','GA'),('US','BBO','Battleboro','Battleboro','NC'),('US','BBP','Bartlett','Bartlett','TN'),('US','BBQ','Bloomsbury','Bloomsbury','NJ'),('US','BBR','Brattleboro','Brattleboro','VT'),('US','BBS','Basin City','Basin City','WA'),('US','BBT','Barbours Cut','Barbours Cut','TX'),('US','BBU','Bloomingburg','Bloomingburg','OH'),('US','BBV','Beech Bottom','Beech Bottom','WV'),('US','BBW','Broken Bow','Broken Bow','NE'),('US','BBX','Blue Bell','Blue Bell','PA'),('US','BBY','Babylon','Babylon','NY'),('US','BBZ','Barbourville','Barbourville','KY'),('US','BC2','Bluffcreek','Bluffcreek','LA'),('US','BC3','Bow Center','Bow Center','NH'),('US','BCA','Bainbridge','Bainbridge','NY'),('US','BCB','Blacksburg','Blacksburg','VA'),('US','BCC','Bear Creek','Bear Creek','AK'),('US','BCD','Bedminster','Bedminster','NJ'),('US','BCE','Bryce','Bryce','UT'),('US','BCF','Belle Glade','Belle Glade','FL'),('US','BCG','Boca Grande','Boca Grande','FL'),('US','BCH','Brushvale','Brushvale','MN'),('US','BCI','Berlin','Berlin','MD'),('US','BCJ','Bartonville','Bartonville','IL'),('US','BCK','Brunswick','Brunswick','OH'),('US','BCL','Beulaville','Beulaville','NC'),('US','BCM','Bruceton Mills','Bruceton Mills','WV'),('US','BCN','Beacon','Beacon','NY'),('US','BCO','Bristol','Bristol','CT'),('US','BCP','Bastian','Bastian','VA'),('US','BCQ','Beattystown','Beattystown','NJ'),('US','BCR','Bear Creek','Bear Creek','AL'),('US','BCS','Belle Chasse','Belle Chasse','LA'),('US','BCT','Boca Raton','Boca Raton','FL'),('US','BCU','Blue Island','Blue Island','IL'),('US','BCV','Brevard','Brevard','NC'),('US','BCW','Brewster','Brewster','MA'),('US','BCX','Blanchester','Blanchester','OH'),('US','BCY','Bay City','Bay City','MI'),('US','BCZ','Bruce','Bruce','MS'),('US','BDA','Boardman','Boardman','OR'),('US','BDB','Bridgeport','Bridgeport','NY'),('US','BDC','Bland','Bland','VA'),('US','BDD','Braddock','Braddock','PA'),('US','BDE','Baudette','Baudette','MN'),('US','BDF','Bradford','Bradford','IL'),('US','BDG','Blanding','Blanding','UT'),('US','BDH','Bedford Heights','Bedford Heights','OH'),('US','BDI','Borden','Borden','IN'),('US','BDJ','Biddeford','Biddeford','ME'),('US','BDK','Budd Lake','Budd Lake','NJ'),('US','BDL','Windsor Locks-Hartford Apt','Windsor Locks-Hartford Apt','CT'),('US','BDM','Boardman','Boardman','OH'),('US','BDN','Blandon','Blandon','PA'),('US','BDO','Bradford','Bradford','AR'),('US','BDP','Bedford Park','Bedford Park','IL'),('US','BDQ','Bland','Bland','MO'),('US','BDR','Bridgeport','Bridgeport','CT'),('US','BDS','Biscoe','Biscoe','NC'),('US','BDT','Bridgewater','Bridgewater','ME'),('US','BDU','Buda','Buda','TX'),('US','BDV','Baldwinsville','Baldwinsville','NY'),('US','BDW','Broadway','Broadway','VA'),('US','BDX','Broadus','Broadus','MT'),('US','BDY','Bandon','Bandon','OR'),('US','BDZ','Bladensburg','Bladensburg','MD'),('US','BEA','Beardstown','Beardstown','IL'),('US','BEB','Beaver','Beaver','PA'),('US','BEC','Beckemeyer','Beckemeyer','IL'),('US','BED','Bedford','Bedford','MA'),('US','BEE','Beech Island','Beech Island','SC'),('US','BEF','Beecher Falls','Beecher Falls','VT'),('US','BEG','Bellevue','Bellevue','NE'),('US','BEH','Benton Harbor','Benton Harbor','MI'),('US','BEI','Berkeley Springs','Berkeley Springs','WV'),('US','BEJ','Belcamp','Belcamp','MD'),('US','BEK','Beacon Falls','Beacon Falls','CT'),('US','BEL','Belfast','Belfast','ME'),('US','BEM','Bremen','Bremen','OH'),('US','BEN','Bena','Bena','VA'),('US','BEO','Bernalillo','Bernalillo','NM'),('US','BEP','Belpre','Belpre','OH'),('US','BEQ','Beachwood','Beachwood','OH'),('US','BER','Berwick','Berwick','ME'),('US','BES','Beltsville','Beltsville','MD'),('US','BET','Bethel','Bethel','AK'),('US','BEU','Berea','Berea','KY'),('US','BEV','Beaver Dam','Beaver Dam','OH'),('US','BEW','Berwyn','Berwyn','PA'),('US','BEX','Bethlehem','Bethlehem','PA'),('US','BEY','Berryton','Berryton','KS'),('US','BEZ','Belzoni','Belzoni','MS'),('US','BF2','Brookfield','Brookfield','NY'),('US','BF3','Boeing Field Apt','Boeing Field Apt','WA'),('US','BF4','Bigfork','Bigfork','MT'),('US','BF5','Brimfield','Brimfield','MA'),('US','BFA','Buford','Buford','GA'),('US','BFB','Blue Fox Bay','Blue Fox Bay','AK'),('US','BFC','Branford','Branford','CT'),('US','BFD','Bradford','Bradford','PA'),('US','BFE','Bluffton','Bluffton','IN'),('US','BFF','Scottsbluff','Scottsbluff','NE'),('US','BFG','Bullfrog Basin','Bullfrog Basin','UT'),('US','BFH','Brandy Station','Brandy Station','VA'),('US','BFI','Bayfield','Bayfield','WI'),('US','BFJ','Briarcliff Manor','Briarcliff Manor','NY'),('US','BFK','Barclay','Barclay','MD'),('US','BFL','Bakersfield','Bakersfield','CA'),('US','BFN','Bellefontaine','Bellefontaine','OH'),('US','BFO','Beaufort','Beaufort','NC'),('US','BFP','Beaver Falls','Beaver Falls','PA'),('US','BFQ','Bluffton','Bluffton','SC'),('US','BFR','Bedford','Bedford','IN'),('US','BFS','Bristol','Bristol','VA'),('US','BFT','Beaufort','Beaufort','SC'),('US','BFU','Buffalo','Buffalo','MO'),('US','BFV','Bellville','Bellville','OH'),('US','BFX','Bellflower','Bellflower','CA'),('US','BFY','Buckeye Lake','Buckeye Lake','OH'),('US','BFZ','Brookfield','Brookfield','OH'),('US','BG2','Bangor','Bangor','WI'),('US','BG3','Bulls Gap','Bulls Gap','TN'),('US','BG4','Boling','Boling','TX'),('US','BGA','Burlington','Burlington','WA'),('US','BGB','Burr Ridge','Burr Ridge','IL'),('US','BGC','Bushnell','Bushnell','IL'),('US','BGD','Bowdon','Bowdon','GA'),('US','BGE','Bainbridge','Bainbridge','GA'),('US','BGF','Butler','Butler','AL'),('US','BGG','Butler','Butler','NJ'),('US','BGH','Butternut','Butternut','WI'),('US','BGI','Burlingame','Burlingame','CA'),('US','BGJ','Bellefontaine','Bellefontaine','MS'),('US','BGK','Brighton','Brighton','CO'),('US','BGL','Bloomingdale','Bloomingdale','NJ'),('US','BGM','Binghamton-Endicott-Johnson City Apt','Binghamton-Endicott-Johnson City Apt','NY'),('US','BGN','Bennington','Bennington','VT'),('US','BGO','Buffalo Grove','Buffalo Grove','IL'),('US','BGP','Bridgeport','Bridgeport','NE'),('US','BGQ','Big Lake','Big Lake','AK'),('US','BGR','Bangor','Bangor','ME'),('US','BGS','Billings','Billings','MO'),('US','BGT','Bagdad','Bagdad','AZ'),('US','BGU','Belgium','Belgium','WI'),('US','BGV','Burlington','Burlington','OR'),('US','BGW','Bridgewater','Bridgewater','NY'),('US','BGX','Belgrade','Belgrade','MT'),('US','BGY','Bridgeton','Bridgeton','NJ'),('US','BGZ','Burlington','Burlington','IN'),('US','BH2','Binghampton','Binghampton','IL'),('US','BH3','Beverly Hills','Beverly Hills','MI'),('US','BH4','Brodhead','Brodhead','WI'),('US','BHA','Byhalia','Byhalia','MS'),('US','BHB','Bar Harbor','Bar Harbor','ME'),('US','BHC','Bridgehampton','Bridgehampton','NY'),('US','BHD','Bradner','Bradner','OH'),('US','BHE','Berkeley Heights','Berkeley Heights','NJ'),('US','BHF','Brandon','Brandon','MS'),('US','BHG','Boring','Boring','OR'),('US','BHH','Bethany','Bethany','OR'),('US','BHI','Bruce','Bruce','WI'),('US','BHJ','Burlington','Burlington','KY'),('US','BHK','Bluffton','Bluffton','OH'),('US','BHL','Buhl','Buhl','ID'),('US','BHM','Birmingham','Birmingham','AL'),('US','BHN','Buckhannon','Buckhannon','WV'),('US','BHO','Brighton','Brighton','MI'),('US','BHP','Burnham','Burnham','PA'),('US','BHQ','Brush','Brush','CO'),('US','BHR','Bridgewater','Bridgewater','VA'),('US','BHS','Brooklyn Heights','Brooklyn Heights','OH'),('US','BHT','Barnhart','Barnhart','MO'),('US','BHU','Bethel, Clermont','Bethel, Clermont','OH'),('US','BHV','Branchville','Branchville','SC'),('US','BHW','Brightwood','Brightwood','OR'),('US','BHX','Bishop','Bishop','TX'),('US','BHY','Bethany','Bethany','MO'),('US','BHZ','Bergholz','Bergholz','OH'),('US','BIA','Batavia','Batavia','NY'),('US','BIB','Birdsboro','Birdsboro','PA'),('US','BIC','Big Creek','Big Creek','AK'),('US','BID','Block Island','Block Island','RI'),('US','BIE','Beatrice','Beatrice','NE'),('US','BIF','Bluff City','Bluff City','TN'),('US','BIG','Big Delta','Big Delta','AK'),('US','BIH','Bishop','Bishop','CA'),('US','BII','Bainbridge Island','Bainbridge Island','WA'),('US','BIJ','Bartlett','Bartlett','IL'),('US','BIK','Berlin','Berlin','CT'),('US','BIL','Billings','Billings','MT'),('US','BIM','Buttonwillow','Buttonwillow','CA'),('US','BIN','Birmingham','Birmingham','NJ'),('US','BIO','Binghamton','Binghamton','NY'),('US','BIP','Biglerville','Biglerville','PA'),('US','BIQ','Bridger','Bridger','MT'),('US','BIR','Birchwood','Birchwood','AK'),('US','BIS','Bismarck','Bismarck','ND'),('US','BIT','Bricktown','Bricktown','NJ'),('US','BIU','Boyne Falls','Boyne Falls','MI'),('US','BIV','Bishopville','Bishopville','SC'),('US','BIW','Blair','Blair','SC'),('US','BIX','Biloxi','Biloxi','MS'),('US','BIY','Big Sandy','Big Sandy','TN'),('US','BIZ','Birmingham','Birmingham','MI'),('US','BJA','Barree','Barree','PA'),('US','BJB','Bridgeburg','Bridgeburg','PA'),('US','BJC','Broomfield','Broomfield','CO'),('US','BJD','Bearden','Bearden','AR'),('US','BJE','Barre','Barre','MA'),('US','BJI','Bemidji','Bemidji','MN'),('US','BJJ','Wooster','Wooster','OH'),('US','BJK','Brookline','Brookline','MO'),('US','BJL','Bushnell','Bushnell','FL'),('US','BJN','Brent','Brent','AL'),('US','BJO','Boron','Boron','CA'),('US','BJP','Blue Ridge Summit','Blue Ridge Summit','PA'),('US','BJQ','Brooklyn Park','Brooklyn Park','MD'),('US','BJR','Barnet','Barnet','VT'),('US','BJT','Bridgetown','Bridgetown','MD'),('US','BJW','Bridgewater','Bridgewater','MA'),('US','BJX','Bellingham','Bellingham','MA'),('US','BJY','Buena','Buena','NJ'),('US','BKA','Bucks','Bucks','AL'),('US','BKB','Bunker','Bunker','MO'),('US','BKC','Buckland','Buckland','AK'),('US','BKD','Breckenridge','Breckenridge','TX'),('US','BKE','Baker','Baker','OR'),('US','BKF','Brooks Lake','Brooks Lake','AK'),('US','BKG','Baker','Baker','FL'),('US','BKH','Kekaha','Kekaha','HI'),('US','BKI','Buckeye','Buckeye','AR'),('US','BKJ','Brooksville','Brooksville','FL'),('US','BKK','Berkeley','Berkeley','IL'),('US','BKL','Berkley','Berkley','MI'),('US','BKM','Baker','Baker','LA'),('US','BKN','Brookhaven','Brookhaven','MS'),('US','BKO','Becker','Becker','MN'),('US','BKP','Bakerstown','Bakerstown','PA'),('US','BKQ','Brooksville','Brooksville','IN'),('US','BKR','Brookley','Brookley','AL'),('US','BKS','Brockton','Brockton','MA'),('US','BKT','Blackstone','Blackstone','VA'),('US','BKU','Brooklyn','Brooklyn','OH'),('US','BKV','Brecksville','Brecksville','OH'),('US','BKW','Beckley','Beckley','WV'),('US','BKX','Brookings','Brookings','SD'),('US','BKY','Brockway','Brockway','PA'),('US','BKZ','Brookfield','Brookfield','MA'),('US','BL2','Blackland, Rockwell','Blackland, Rockwell','TX'),('US','BL3','Brooklin, Hancock','Brooklin, Hancock','ME'),('US','BLA','Blaine','Blaine','WI'),('US','BLB','Belair','Belair','CA'),('US','BLC','Black Creek','Black Creek','WI'),('US','BLD','Boulder City','Boulder City','NV'),('US','BLE','Belle','Belle','WV'),('US','BLF','Princeton','Princeton','WV'),('US','BLG','Bell Gardens','Bell Gardens','CA'),('US','BLH','Blythe','Blythe','CA'),('US','BLI','Bellingham','Bellingham','WA'),('US','BLJ','Belle Mead','Belle Mead','NJ'),('US','BLK','Blackfoot','Blackfoot','ID'),('US','BLL','Ballwin','Ballwin','MO'),('US','BLM','Belmar','Belmar','NJ'),('US','BLN','Belen','Belen','NM'),('US','BLO','Bloomington','Bloomington','TX'),('US','BLP','Belle Plaine','Belle Plaine','IA'),('US','BLQ','Belleville','Belleville','PA'),('US','BLR','Ballinger','Ballinger','TX'),('US','BLS','Blissfield','Blissfield','MI'),('US','BLT','Buellton','Buellton','CA'),('US','BLU','Blue Canyon','Blue Canyon','CA'),('US','BLV','Belleville','Belleville','IL'),('US','BLW','Waimanalo','Waimanalo','HI'),('US','BLX','Bel Air','Bel Air','MD'),('US','BLY','Bally','Bally','PA'),('US','BLZ','Belleville','Belleville','MI'),('US','BMA','Brookline','Brookline','MA'),('US','BMB','Bloomingburg','Bloomingburg','NY'),('US','BMC','Brigham City','Brigham City','UT'),('US','BMD','Bloomingdale','Bloomingdale','GA'),('US','BME','Bay Minette','Bay Minette','AL'),('US','BMF','Bloomfield','Bloomfield','IN'),('US','BMG','Bloomington','Bloomington','IN'),('US','BMH','Sandoval','Sandoval','IL'),('US','BMI','Bloomington-Normal Apt','Bloomington-Normal Apt','IL'),('US','BMJ','Belmont','Belmont','MI'),('US','BMK','Belmond','Belmond','IA'),('US','BML','Berlin','Berlin','NH'),('US','BMM','Belmont','Belmont','MS'),('US','BMN','Bloomfield','Bloomfield','NJ'),('US','BMO','Big Mountain','Big Mountain','MN'),('US','BMP','Brampton','Brampton','MI'),('US','BMQ','Belmont','Belmont','NC'),('US','BMR','Bloomington','Bloomington','NY'),('US','BMS','Billerica','Billerica','MA'),('US','BMT','Belmont','Belmont','OH'),('US','BMU','Blakely','Blakely','GA'),('US','BMV','Bessemer','Bessemer','AL'),('US','BMW','Bowmanstown','Bowmanstown','PA'),('US','BMX','Big Mountain','Big Mountain','AK'),('US','BMY','Brimfield','Brimfield','IN'),('US','BMZ','Bridgeton','Bridgeton','MO'),('US','BN2','Brighton','Brighton','MN'),('US','BN3','Benton','Benton','LA'),('US','BN5','Brooklyn','Brooklyn','MD'),('US','BNA','Nashville','Nashville','TN'),('US','BNB','Burns Harbor','Burns Harbor','IN'),('US','BNC','Benicia','Benicia','CA'),('US','BND','Burleson','Burleson','TX'),('US','BNE','Blaine','Blaine','MN'),('US','BNF','Baranof','Baranof','AK'),('US','BNG','Banning','Banning','CA'),('US','BNH','Burnham','Burnham','ME'),('US','BNI','Burnsville','Burnsville','NC'),('US','BNJ','Bengies','Bengies','MD'),('US','BNK','Bolingbrook','Bolingbrook','IL'),('US','BNL','Barnwell','Barnwell','SC'),('US','BNM','Bensalem','Bensalem','PA'),('US','BNN','Bannockburn','Bannockburn','IL'),('US','BNO','Burns','Burns','OR'),('US','BNP','Brayton Point','Brayton Point','MA'),('US','BNQ','Bangor','Bangor','MI'),('US','BNR','Brandenburg','Brandenburg','KY'),('US','BNS','Bether Springs','Bether Springs','TN'),('US','BNT','Bentonville','Bentonville','AR'),('US','BNU','Branchburg Park','Branchburg Park','NJ'),('US','BNV','Bensenville','Bensenville','IL'),('US','BNW','Boone','Boone','IA'),('US','BNX','Bronxville','Bronxville','NY'),('US','BNY','Bunn','Bunn','NC'),('US','BNZ','Benson','Benson','NC'),('US','BOA','Bon Air','Bon Air','AL'),('US','BOB','Bowler','Bowler','WI'),('US','BOC','Brooklyn','Brooklyn','CT'),('US','BOD','Bedford','Bedford','TX'),('US','BOE','Boyertown','Boyertown','PA'),('US','BOF','Botsford','Botsford','CT'),('US','BOG','Bogota','Bogota','NJ'),('US','BOH','Bohemia','Bohemia','NY'),('US','BOI','Boise','Boise','ID'),('US','BOJ','Bordentown','Bordentown','NJ'),('US','BOK','Brookings','Brookings','OR'),('US','BOL','Bolton','Bolton','MA'),('US','BOM','Bonham','Bonham','TX'),('US','BON','Bonanza','Bonanza','UT'),('US','BOO','Booneville','Booneville','MS'),('US','BOP','Bonita Springs','Bonita Springs','FL'),('US','BOQ','Booneville','Booneville','AR'),('US','BOR','Bourg','Bourg','LA'),('US','BOS','Boston','Boston','MA'),('US','BOT','Beloit','Beloit','WI'),('US','BOU','Bonduel','Bonduel','WI'),('US','BOV','Bolivar','Bolivar','MO'),('US','BOW','Bartow','Bartow','FL'),('US','BOX','Bow','Bow','NH'),('US','BOY','Brooklyn/New York','Brooklyn/New York','NY'),('US','BOZ','Bonger','Bonger','TX'),('US','BP3','Bridgeport','Bridgeport','CO'),('US','BPA','Bethpage','Bethpage','NY'),('US','BPB','Bayport','Bayport','MN'),('US','BPC','Brook Park','Brook Park','MN'),('US','BPD','Blue Rapids','Blue Rapids','KS'),('US','BPE','Bonsall','Bonsall','CA'),('US','BPF','Boundary','Boundary','WA'),('US','BPG','Bridgeport','Bridgeport','NJ'),('US','BPH','Boiling Springs, Barnwell','Boiling Springs, Barnwell','SC'),('US','BPI','Big Piney','Big Piney','WY'),('US','BPJ','Buchanan','Buchanan','TN'),('US','BPK','Brockport','Brockport','NY'),('US','BPM','Bridgeport','Bridgeport','MI'),('US','BPN','Balch Springs','Balch Springs','TX'),('US','BPO','Brook Park','Brook Park','OH'),('US','BPP','Bellport','Bellport','NY'),('US','BPQ','Broadway','Broadway','NJ'),('US','BPR','Blue Springs','Blue Springs','MS'),('US','BPT','Beaumont','Beaumont','TX'),('US','BPV','Belhaven','Belhaven','NC'),('US','BPX','Bayport','Bayport','TX'),('US','BPY','Big Pine Key','Big Pine Key','FL'),('US','BPZ','Bayport','Bayport','NY'),('US','BQA','Bowie','Bowie','MD'),('US','BQB','Brentwood','Brentwood','NY'),('US','BQC','Bell','Bell','CA'),('US','BQD','Bradford','Bradford','RI'),('US','BQE','Brea','Brea','CA'),('US','BQF','Bridgewater','Bridgewater','NJ'),('US','BQG','Brier','Brier','WA'),('US','BQH','Bath','Bath','PA'),('US','BQI','Bloomington','Bloomington','MN'),('US','BQL','Burkville','Burkville','AL'),('US','BQM','Black Mountain','Black Mountain','NC'),('US','BQN','Brownstown','Brownstown','MI'),('US','BQO','Benton','Benton','TN'),('US','BQP','Brooklyn Park','Brooklyn Park','MN'),('US','BQQ','Bedford Hills','Bedford Hills','NY'),('US','BQR','Bosque Farms','Bosque Farms','NM'),('US','BQS','Brainards','Brainards','NJ'),('US','BQT','Bloomington','Bloomington','CA'),('US','BQU','Berkeley','Berkeley','RI'),('US','BQW','Blackwood','Blackwood','NJ'),('US','BQX','Bayville','Bayville','NJ'),('US','BQY','Ballston Spa','Ballston Spa','NY'),('US','BR2','Burritts Rapids','Burritts Rapids',''),('US','BR3','Beirne','Beirne','AR'),('US','BRA','Bradwood','Bradwood','OR'),('US','BRB','Berlin','Berlin','WI'),('US','BRC','Bern','Bern','KS'),('US','BRD','Brainerd','Brainerd','MN'),('US','BRE','Bellaire','Bellaire','TX'),('US','BRF','Bergenfield','Bergenfield','NJ'),('US','BRG','Whitesburg','Whitesburg','KY'),('US','BRH','Bergholtz','Bergholtz','NY'),('US','BRI','Berlin','Berlin','NY'),('US','BRJ','Broadview','Broadview','IL'),('US','BRK','Brookfield','Brookfield','CT'),('US','BRL','Burlington','Burlington','IA'),('US','BRM','Brimfield','Brimfield','IL'),('US','BRN','Barrington','Barrington','NJ'),('US','BRO','Brownsville','Brownsville','TX'),('US','BRP','Brandon','Brandon','MN'),('US','BRQ','Barrington','Barrington','IL'),('US','BRR','Brewster','Brewster','OH'),('US','BRS','Brooks','Brooks','OR'),('US','BRT','Bristol','Bristol','CO'),('US','BRU','Battle Ground','Battle Ground','WA'),('US','BRV','Bernardsville','Bernardsville','NJ'),('US','BRW','Barrow','Barrow','AK'),('US','BRX','Bronx/New York','Bronx/New York','NY'),('US','BRY','Bryan','Bryan','OH'),('US','BRZ','Barrington','Barrington','RI'),('US','BS2','Blackshear, Pierce','Blackshear, Pierce','GA'),('US','BS3','Burns','Burns','TN'),('US','BSA','Brisbane','Brisbane','CA'),('US','BSB','Bloomsburg','Bloomsburg','PA'),('US','BSC','Bascom','Bascom','OH'),('US','BSD','Brownsville','Brownsville','TN'),('US','BSE','Bristol','Bristol','RI'),('US','BSF','Pohakuloa','Pohakuloa','HI'),('US','BSG','Baxter Springs','Baxter Springs','KS'),('US','BSH','Bay Shore','Bay Shore','NY'),('US','BSI','Blairsville','Blairsville','PA'),('US','BSJ','Bristol','Bristol','WI'),('US','BSK','Basking Ridge','Basking Ridge','NJ'),('US','BSL','Bay Saint Louis','Bay Saint Louis','MS'),('US','BSM','Big Sandy','Big Sandy','MT'),('US','BSN','Boston','Boston','VA'),('US','BSO','Bristol Apt','Bristol Apt','TN'),('US','BSP','Bartlett Springs','Bartlett Springs','CA'),('US','BSQ','Bisbee','Bisbee','AZ'),('US','BSR','Bossier City','Bossier City','LA'),('US','BSS','Bassett','Bassett','VA'),('US','BST','Bean Station','Bean Station','TN'),('US','BSU','Bonner Springs','Bonner Springs','KS'),('US','BSV','Blairs','Blairs','VA'),('US','BSW','Boswell Bay','Boswell Bay','AK'),('US','BSX','Bristol','Bristol','IN'),('US','BSY','Broussard, Lafayette','Broussard, Lafayette','LA'),('US','BSZ','Bartletts','Bartletts','AK'),('US','BT2','Bryant, Hamlin','Bryant, Hamlin','SD'),('US','BTA','Batavia','Batavia','IL'),('US','BTB','Boonton','Boonton','NJ'),('US','BTC','Braintree','Braintree','MA'),('US','BTD','Bettendorf','Bettendorf','IA'),('US','BTE','Bethune','Bethune','SC'),('US','BTF','Bountiful','Bountiful','UT'),('US','BTG','Bethel','Bethel','PA'),('US','BTH','Bath','Bath','ME'),('US','BTI','Barter Island','Barter Island','AK'),('US','BTJ','Bethel','Bethel','CT'),('US','BTK','Botkins','Botkins','OH'),('US','BTL','Battle Creek','Battle Creek','MI'),('US','BTM','Butte','Butte','MT'),('US','BTN','Bennettsville','Bennettsville','SC'),('US','BTO','Brighton Heights','Brighton Heights','PA'),('US','BTP','Butler','Butler','PA'),('US','BTQ','Benton','Benton','IL'),('US','BTR','Baton Rouge','Baton Rouge','LA'),('US','BTS','Batesville','Batesville','AR'),('US','BTT','Bettles','Bettles','AK'),('US','BTU','Burt','Burt','NY'),('US','BTV','Burlington','Burlington','VT'),('US','BTW','Bethany','Bethany','CT'),('US','BTX','Bethany','Bethany','IL'),('US','BTY','Beatty','Beatty','NV'),('US','BTZ','Benton','Benton','ME'),('US','BUA','Bradbury','Bradbury','CA'),('US','BUB','Bruceton','Bruceton','TN'),('US','BUC','Buchanan','Buchanan','MI'),('US','BUD','Bude','Bude','MS'),('US','BUE','Buena','Buena','WA'),('US','BUF','Buffalo','Buffalo','NY'),('US','BUG','Buffalo Lake','Buffalo Lake','MN'),('US','BUH','Burlington','Burlington','NJ'),('US','BUI','Butler','Butler','IN'),('US','BUJ','Butler','Butler','KY'),('US','BUK','Burbank','Burbank','IL'),('US','BUL','Blue Lake','Blue Lake','CA'),('US','BUM','Butler','Butler','MO'),('US','BUN','Buena Park','Buena Park','CA'),('US','BUO','Beaumont','Beaumont','CA'),('US','BUP','Bucksport','Bucksport','ME'),('US','BUQ','Burr Oak','Burr Oak','MI'),('US','BUR','Burbank','Burbank','CA'),('US','BUS','Buras','Buras','LA'),('US','BUT','Burton','Burton','OH'),('US','BUU','Burlington','Burlington','CT'),('US','BUV','Burtonsville','Burtonsville','MD'),('US','BUW','Burlington','Burlington','WI'),('US','BUX','Batavia','Batavia','OH'),('US','BUY','Blauvelt','Blauvelt','NY'),('US','BUZ','Buckley','Buckley','WA'),('US','BV2','Broadview, Summit','Broadview, Summit','OH'),('US','BV3','Barnesville','Barnesville','PA'),('US','BV4','Brookville','Brookville','IN'),('US','BVA','Beaver Dam','Beaver Dam','WI'),('US','BVB','Bellville','Bellville','TX'),('US','BVC','Berthoud','Berthoud','CO'),('US','BVD','Beaver Inlet','Beaver Inlet','AK'),('US','BVE','Bellevue','Bellevue','WA'),('US','BVF','Beaver Falls','Beaver Falls','NY'),('US','BVG','Bevington','Bevington','IA'),('US','BVH','Beverly Hills','Beverly Hills','CA'),('US','BVI','Breinigsville','Breinigsville','PA'),('US','BVJ','Belvidere','Belvidere','IL'),('US','BVK','Belleville','Belleville','WI'),('US','BVL','Boonville','Boonville','NC'),('US','BVM','Boonville','Boonville','MO'),('US','BVN','Belle Vernon','Belle Vernon','PA'),('US','BVO','Bartlesville','Bartlesville','OK'),('US','BVP','Brookville','Brookville','PA'),('US','BVQ','Boonville','Boonville','IN'),('US','BVR','Beverly','Beverly','OH'),('US','BVS','Buena Vista','Buena Vista','VA'),('US','BVT','Belmont','Belmont','CA'),('US','BVU','Beluga','Beluga','AK'),('US','BVV','Berryville','Berryville','AR'),('US','BVW','Beaverton','Beaverton','OR'),('US','BVX','Batesville','Batesville','AR'),('US','BVY','Beverly','Beverly','MA'),('US','BVZ','Batesville','Batesville','MS'),('US','BWA','Brookwood','Brookwood','AL'),('US','BWB','Brownsburg','Brownsburg','IN'),('US','BWC','Brawley','Brawley','CA'),('US','BWD','Brownwood','Brownwood','TX'),('US','BWE','Brentwood','Brentwood','TN'),('US','BWF','Bellows Falls','Bellows Falls','VT'),('US','BWG','Bowling Green','Bowling Green','KY'),('US','BWH','Bigelow','Bigelow','AR'),('US','BWI','Baltimore-Washington Int Apt','Baltimore-Washington Int Apt','MD'),('US','BWJ','Brockwell','Brockwell','AR'),('US','BWK','Blowing Rock','Blowing Rock','NC'),('US','BWL','Blackwell','Blackwell','OK'),('US','BWM','Bowman','Bowman','ND'),('US','BWN','Bowerston','Bowerston','OH'),('US','BWO','Bowling Green','Bowling Green','OH'),('US','BWP','Baldwin Park','Baldwin Park','CA'),('US','BWQ','Broken Arrow','Broken Arrow','OK'),('US','BWR','Bellmawr','Bellmawr','NJ'),('US','BWS','Blaine','Blaine','WA'),('US','BWT','Braithwaite','Braithwaite','LA'),('US','BWU','Baldwyn','Baldwyn','MS'),('US','BWV','Bowmansville','Bowmansville','PA'),('US','BWW','Brownton','Brownton','MN'),('US','BWX','Bon Wier','Bon Wier','TX'),('US','BWY','Berwyn','Berwyn','IL'),('US','BWZ','Brewster','Brewster','NY'),('US','BXA','Bogalusa','Bogalusa','LA'),('US','BXB','Breaux Bridge','Breaux Bridge','LA'),('US','BXC','Boxborough','Boxborough','MA'),('US','BXD','Breese','Breese','IL'),('US','BXE','Bremen','Bremen','IN'),('US','BXF','Brentwood','Brentwood','CA'),('US','BXG','Brentwood','Brentwood','MD'),('US','BXH','Brewer','Brewer','ME'),('US','BXI','Brewster','Brewster','WA'),('US','BXJ','Brewton','Brewton','AL'),('US','BXK','Buckeye','Buckeye','AZ'),('US','BXL','Brian','Brian','LA'),('US','BXM','Bridgeport','Bridgeport','AL'),('US','BXN','Benton','Benton','AR'),('US','BXO','Bladenboro','Bladenboro','NC'),('US','BXP','Box Springs','Box Springs','CA'),('US','BXQ','Brodnax','Brodnax','VA'),('US','BXR','Baxter','Baxter','TN'),('US','BXS','Borrego Springs','Borrego Springs','CA'),('US','BXT','Bauxite','Bauxite','AR'),('US','BXU','Brownfield','Brownfield','TX'),('US','BXV','Brownstown','Brownstown','IN'),('US','BXW','Bucyrus','Bucyrus','OH'),('US','BXX','Brandon','Brandon','FL'),('US','BXY','Bixby','Bixby','OK'),('US','BXZ','Blairs','Blairs','VA'),('US','BYA','Boundary','Boundary','AK'),('US','BYB','Boynton Beach','Boynton Beach','FL'),('US','BYC','Boyceville','Boyceville','WI'),('US','BYD','Bayard','Bayard','NE'),('US','BYE','Bryn Mawr','Bryn Mawr','PA'),('US','BYF','Bryson City','Bryson City','NC'),('US','BYG','Buffalo','Buffalo','WY'),('US','BYH','Blytheville','Blytheville','AR'),('US','BYI','Burley-Rupert Apt','Burley-Rupert Apt','ID'),('US','BYJ','Broadway','Broadway','NJ'),('US','BYK','Byron Center','Byron Center','MI'),('US','BYL','Bradley','Bradley','IL'),('US','BYM','Byram','Byram','CT'),('US','BYN','Burney','Burney','CA'),('US','BYO','Burnsville','Burnsville','MN'),('US','BYP','Burley','Burley','PA'),('US','BYQ','Byberry','Byberry','PA'),('US','BYR','Byron','Byron','CA'),('US','BYS','Fort Irwin','Fort Irwin','CA'),('US','BYT','Bay Meadows','Bay Meadows','GA'),('US','BYU','Bayou la Batre','Bayou la Batre','AL'),('US','BYV','Berryville','Berryville','VA'),('US','BYW','Blakely Island','Blakely Island','WA'),('US','BYX','Baxley','Baxley','GA'),('US','BYY','Breckenridge','Breckenridge','MN'),('US','BYZ','Boyne City','Boyne City','MI'),('US','BZA','Brazil','Brazil','IN'),('US','BZB','Baltimore','Baltimore','OH'),('US','BZC','Barnesville','Barnesville','OH'),('US','BZD','Boston','Boston','GA'),('US','BZE','Belton','Belton','MO'),('US','BZH','Bethesda','Bethesda','MD'),('US','BZI','Baldwin City','Baldwin City','KS'),('US','BZL','Bristol','Bristol','VT'),('US','BZM','Bozeman','Bozeman','MT'),('US','BZN','Bozeman','Bozeman','MT'),('US','BZO','Bend','Bend','OR'),('US','BZR','Big Prairie','Big Prairie','OH'),('US','BZS','Boswell','Boswell','IN'),('US','BZT','Brazoria','Brazoria','TX'),('US','BZU','Bruce','Bruce','SD'),('US','BZV','Branson West','Branson West','MO'),('US','BZW','Barstow','Barstow','CA'),('US','BZX','Brimfield','Brimfield','OH'),('US','BZY','Blue Springs','Blue Springs','MO'),('US','BZZ','Blacklick','Blacklick','OH'),('US','CAA','Calimesa','Calimesa','CA'),('US','CAB','Canby','Canby','OR'),('US','CAC','Cactus','Cactus','TX'),('US','CAD','Cadillac','Cadillac','MI'),('US','CAE','Columbia','Columbia','SC'),('US','CAF','Columbia Station','Columbia Station','OH'),('US','CAG','Calistoga','Calistoga','CA'),('US','CAH','Calhoun','Calhoun','GA'),('US','CAI','Chapin','Chapin','SC'),('US','CAJ','Columbia City','Columbia City','IN'),('US','CAK','Clark Fork','Clark Fork','ID'),('US','CAL','Calais','Calais','ME'),('US','CAM','Cambridge City','Cambridge City','IN'),('US','CAN','Camanche','Camanche','IA'),('US','CAO','Clayton','Clayton','NM'),('US','CAP','Capitan','Capitan','CA'),('US','CAQ','Caldwell','Caldwell','OH'),('US','CAR','Caribou','Caribou','ME'),('US','CAS','Castine','Castine','ME'),('US','CAT','Camden','Camden','TN'),('US','CAU','Calcasieu','Calcasieu','LA'),('US','CAV','Cleveland','Cleveland','TX'),('US','CAW','Carthage','Carthage','IN'),('US','CAX','Carrollton','Carrollton','TX'),('US','CAY','Calumet City','Calumet City','IL'),('US','CAZ','Cynthiana','Cynthiana','KY'),('US','CB2','Clear Brook','Clear Brook','VA'),('US','CB3','Cosby','Cosby','TN'),('US','CB8','Columbus','Columbus','MT'),('US','CBA','Corner Bay','Corner Bay','AK'),('US','CBB','Chambersburg','Chambersburg','PA'),('US','CBC','Centerbrook','Centerbrook','CT'),('US','CBD','Cambridge','Cambridge','MN'),('US','CBE','Cumberland','Cumberland','MD'),('US','CBF','Council Bluffs','Council Bluffs','IA'),('US','CBG','Christiansburg','Christiansburg','VA'),('US','CBH','Cambridge','Cambridge','OH'),('US','CBI','Corbin','Corbin','KY'),('US','CBJ','Country Side','Country Side','IL'),('US','CBK','Colby','Colby','KS'),('US','CBL','Coupeville','Coupeville','WA'),('US','CBM','Cabool','Cabool','MO'),('US','CBN','Cleburne','Cleburne','TX'),('US','CBO','Campobello','Campobello','SC'),('US','CBP','Courtland','Courtland','AL'),('US','CBQ','Courtland','Courtland','KS'),('US','CBR','Courtland','Courtland','MN'),('US','CBS','Centerburg','Centerburg','OH'),('US','CBT','Clinton','Clinton','MO'),('US','CBU','Campbellsburg','Campbellsburg','KY'),('US','CBV','Cedar Bayou','Cedar Bayou','TX'),('US','CBW','Columbus','Columbus','WI'),('US','CBX','Cannon Beach','Cannon Beach','OR'),('US','CBY','Carbury','Carbury','ND'),('US','CBZ','Cabin Creek','Cabin Creek','AK'),('US','CC2','Cape Coral','Cape Coral','FL'),('US','CC3','Cass City','Cass City','MI'),('US','CC4','Casco','Casco','MI'),('US','CC5','City of Commerce','City of Commerce','CA'),('US','CC6','Claycomo','Claycomo','MO'),('US','CCA','Fort Chaffee','Fort Chaffee','AR'),('US','CCB','Upland','Upland','CA'),('US','CCC','Cicero','Cicero','NY'),('US','CCD','Caledonia','Caledonia','OH'),('US','CCE','Chicopee','Chicopee','MO'),('US','CCF','Concord','Concord','MA'),('US','CCG','Crane','Crane','TX'),('US','CCH','Churchville','Churchville','VA'),('US','CCI','Calhoun City','Calhoun City','MS'),('US','CCJ','Cape Charles','Cape Charles','VA'),('US','CCK','Chuckatuck','Chuckatuck','VA'),('US','CCL','Chocolate Bayou','Chocolate Bayou','TX'),('US','CCM','Crystal City','Crystal City','MO'),('US','CCN','Clinton','Clinton','MA'),('US','CCO','Canton','Canton','OH'),('US','CCP','Caspian','Caspian','MI'),('US','CCQ','Cockeysville','Cockeysville','MD'),('US','CCR','Concord','Concord','CA'),('US','CCS','Cave City','Cave City','KY'),('US','CCT','Calvert City','Calvert City','KY'),('US','CCU','Coconut Creek','Coconut Creek','FL'),('US','CCV','Colchester','Colchester','VT'),('US','CCW','Centereach','Centereach','NY'),('US','CCX','Chepachet','Chepachet','RI'),('US','CCY','Charles City','Charles City','IA'),('US','CCZ','Cooleemee','Cooleemee','NC'),('US','CD2','Corydon, Wayne','Corydon, Wayne','IA'),('US','CD3','Cottondale','Cottondale','AL'),('US','CD4','Coronado','Coronado','CA'),('US','CDA','Carlsbad','Carlsbad','CA'),('US','CDB','Cold Bay','Cold Bay','AK'),('US','CDC','Cedar City','Cedar City','UT'),('US','CDD','Camden','Camden','AL'),('US','CDE','Camden','Camden','NJ'),('US','CDF','Candler','Candler','NC'),('US','CDG','Chestnut Ridge','Chestnut Ridge','NY'),('US','CDH','Camden','Camden','AR'),('US','CDI','Cedartown','Cedartown','GA'),('US','CDJ','Cedar Hills','Cedar Hills','OR'),('US','CDK','Cedar Key','Cedar Key','FL'),('US','CDL','Candle','Candle','AK'),('US','CDM','Cold Spring','Cold Spring','MN'),('US','CDN','Camden','Camden','SC'),('US','CDO','Chardon','Chardon','OH'),('US','CDP','Childs','Childs','PA'),('US','CDQ','Colden','Colden','NY'),('US','CDR','Chadron','Chadron','NE'),('US','CDS','Childress','Childress','TX'),('US','CDT','Camdenton','Camdenton','MO'),('US','CDU','Cedar Lake','Cedar Lake','MI'),('US','CDV','Cordova','Cordova','AK'),('US','CDW','Caldwell','Caldwell','NJ'),('US','CDX','Caldwell','Caldwell','ID'),('US','CDY','Conneaut','Conneaut','OH'),('US','CDZ','Caledonia','Caledonia','MI'),('US','CE2','Colonie','Colonie','NY'),('US','CE3','Corrales','Corrales','NM'),('US','CE4','Centreville','Centreville','MS'),('US','CEA','Celina','Celina','OH'),('US','CEB','Calera','Calera','AL'),('US','CEC','Crescent City','Crescent City','CA'),('US','CED','Cedar Grove','Cedar Grove','NJ'),('US','CEE','Centerville','Centerville','CA'),('US','CEF','Chicopee','Chicopee','MA'),('US','CEG','Cedarburg','Cedarburg','WI'),('US','CEH','Campbell Hall','Campbell Hall','NY'),('US','CEI','Cooper Landing','Cooper Landing','AK'),('US','CEJ','Coppell','Coppell','TX'),('US','CEK','Cerritos','Cerritos','CA'),('US','CEL','Cape Elizabeth','Cape Elizabeth','ME'),('US','CEM','Central','Central','AK'),('US','CEN','Convent','Convent','LA'),('US','CEO','Claremont','Claremont','NC'),('US','CEP','Chapman','Chapman','AL'),('US','CEQ','College','College','AK'),('US','CER','Centre','Centre','AL'),('US','CES','Cedar Springs','Cedar Springs','GA'),('US','CET','Copiague','Copiague','NY'),('US','CEU','Clemson','Clemson','SC'),('US','CEV','Connersville','Connersville','IN'),('US','CEW','Crestview','Crestview','FL'),('US','CEX','Chena Hot Springs','Chena Hot Springs','AK'),('US','CEY','Murray','Murray','KY'),('US','CEZ','Cortez','Cortez','CO'),('US','CF2','Claflin','Claflin','KS'),('US','CF3','Clifton, Mesa','Clifton, Mesa','CO'),('US','CF4','Clifton','Clifton','VA'),('US','CFA','Coffee Point','Coffee Point','AK'),('US','CFB','Crawfordsville','Crawfordsville','IN'),('US','CFC','Cary','Cary','NC'),('US','CFD','Bryan','Bryan','TX'),('US','CFE','Chesterfield','Chesterfield','MO'),('US','CFF','Cherryfield','Cherryfield','ME'),('US','CFG','Chesterfield','Chesterfield','NH'),('US','CFH','Clifton Heights','Clifton Heights','PA'),('US','CFI','Canal Fulton','Canal Fulton','OH'),('US','CFJ','California','California','MO'),('US','CFK','Cresco','Cresco','IA'),('US','CFL','Chesterfield','Chesterfield','MI'),('US','CFM','Columbia','Columbia','MS'),('US','CFN','Cape Fear','Cape Fear','NC'),('US','CFO','Chagrin Falls','Chagrin Falls','OH'),('US','CFP','Clifton Park','Clifton Park','NY'),('US','CFQ','Crafton','Crafton','PA'),('US','CFR','Chadds Ford','Chadds Ford','PA'),('US','CFS','Cannon Falls','Cannon Falls','MN'),('US','CFT','Clifton','Clifton','AZ'),('US','CFU','Clifton','Clifton','NJ'),('US','CFV','Coffeyville','Coffeyville','KS'),('US','CFW','Clermont','Clermont','FL'),('US','CFX','Clifton','Clifton','TX'),('US','CFY','Cheverly','Cheverly','MD'),('US','CFZ','Fort Carson','Fort Carson','CO'),('US','CG2','Coalgate','Coalgate','OK'),('US','CGA','Craig','Craig','AK'),('US','CGB','Coral Gables','Coral Gables','FL'),('US','CGC','Corning','Corning','AR'),('US','CGD','Collegedale','Collegedale','TN'),('US','CGE','Cambridge','Cambridge','MD'),('US','CGF','Cape May','Cape May','NJ'),('US','CGG','College Grove','College Grove','TN'),('US','CGH','Chicago Heights','Chicago Heights','IL'),('US','CGI','Cape Girardeau','Cape Girardeau','MO'),('US','CGJ','Cerro Gordo','Cerro Gordo','IL'),('US','CGK','Catlettsburg','Catlettsburg','KY'),('US','CGL','Collingdale','Collingdale','PA'),('US','CGM','Crosby','Crosby','MN'),('US','CGN','Clairton','Clairton','PA'),('US','CGO','Chittenango','Chittenango','NY'),('US','CGQ','Columbus Grove','Columbus Grove','OH'),('US','CGR','Cedar Grove','Cedar Grove','WI'),('US','CGS','College Park','College Park','MD'),('US','CGT','Carthage','Carthage','MS'),('US','CGU','Clam Gulch','Clam Gulch','AK'),('US','CGV','Collegeville','Collegeville','PA'),('US','CGW','Chickasaw','Chickasaw','AL'),('US','CGY','Colony','Colony','WY'),('US','CGZ','Casa Grande','Casa Grande','AZ'),('US','CH2','Chillicothe','Chillicothe','IL'),('US','CH3','Chino Hills','Chino Hills','CA'),('US','CH4','Clarendon Hill','Clarendon Hill','IL'),('US','CH5','Crest Hill','Crest Hill','IL'),('US','CHA','Chattanooga','Chattanooga','TN'),('US','CHB','Chadbourn','Chadbourn','NC'),('US','CHC','Cheshire','Cheshire','CT'),('US','CHD','Chandler','Chandler','AZ'),('US','CHE','Chapel Hill','Chapel Hill','NC'),('US','CHF','Chalfont','Chalfont','PA'),('US','CHG','Cheboygan','Cheboygan','MI'),('US','CHH','Channahon','Channahon','IL'),('US','CHI','Chicago','Chicago','IL'),('US','CHJ','Cherryville','Cherryville','NC'),('US','CHK','Chickasha','Chickasha','OK'),('US','CHL','Challis','Challis','ID'),('US','CHM','Champlain','Champlain','NY'),('US','CHN','Charlestown','Charlestown','MA'),('US','CHO','Charlottesville','Charlottesville','VA'),('US','CHP','Circle Hot Springs','Circle Hot Springs','AK'),('US','CHQ','Chanhassen','Chanhassen','MN'),('US','CHR','Chugiak','Chugiak','AK'),('US','CHS','Charleston','Charleston','SC'),('US','CHT','Chester','Chester','PA'),('US','CHU','Chuathbaluk','Chuathbaluk','AK'),('US','CHV','Cherry Valley','Cherry Valley','CA'),('US','CHW','Cheswold','Cheswold','DE'),('US','CHX','Cherry Hill','Cherry Hill','NJ'),('US','CHY','Castle Hayne','Castle Hayne','NC'),('US','CHZ','Chiloquin','Chiloquin','OR'),('US','CI2','Cincinnati','Cincinnati','KY'),('US','CIA','Centerville','Centerville','IA'),('US','CIB','Casselberry','Casselberry','FL'),('US','CIC','Chico','Chico','CA'),('US','CID','Cedar Rapids','Cedar Rapids','IA'),('US','CIE','Circleville','Circleville','OH'),('US','CIF','Chatham','Chatham','NY'),('US','CIG','Craig','Craig','CO'),('US','CIH','Chapel Hill','Chapel Hill','TN'),('US','CII','Chili','Chili','NY'),('US','CIJ','Chesaning','Chesaning','MI'),('US','CIK','Chalkyitsik','Chalkyitsik','AK'),('US','CIL','Council','Council','AK'),('US','CIM','Campti','Campti','LA'),('US','CIN','Carroll','Carroll','IA'),('US','CIO','Chino Valley','Chino Valley','AZ'),('US','CIP','Central Islip','Central Islip','NY'),('US','CIQ','Chariton','Chariton','IA'),('US','CIR','Cairo','Cairo','IL'),('US','CIS','Cisco','Cisco','TX'),('US','CIT','Citronelle','Citronelle','AL'),('US','CIU','Centreville','Centreville','IL'),('US','CIV','Chomley','Chomley','AK'),('US','CIW','Collinwood','Collinwood','TN'),('US','CIX','Clinton','Clinton','IN'),('US','CIY','Chillicothe','Chillicothe','OH'),('US','CIZ','Clearing','Clearing','IL'),('US','CJA','Cressona','Cressona','PA'),('US','CJD','Clayton','Clayton','MO'),('US','CJE','Collierville','Collierville','TN'),('US','CJG','Corning','Corning','CA'),('US','CJH','Canajoharie','Canajoharie','NY'),('US','CJI','Centreville','Centreville','AL'),('US','CJJ','Cedar Knolls','Cedar Knolls','NJ'),('US','CJK','Clarkton','Clarkton','NC'),('US','CJL','Chandler','Chandler','IN'),('US','CJM','Champion','Champion','PA'),('US','CJN','El Cajon','El Cajon','CA'),('US','CJO','Caro','Caro','MI'),('US','CJP','Carthage','Carthage','TX'),('US','CJQ','Carthage','Carthage','MO'),('US','CJR','Cairo','Cairo','GA'),('US','CJS','Cashiers','Cashiers','NC'),('US','CJT','Charleston','Charleston','OR'),('US','CJU','Canyon','Canyon','CA'),('US','CJV','Covesville','Covesville','VA'),('US','CJX','Clayton','Clayton','CA'),('US','CJY','Crosby','Crosby','TX'),('US','CKA','Cherokee','Cherokee','OK'),('US','CKB','Clarksburg','Clarksburg','WV'),('US','CKC','Clinton','Clinton','MS'),('US','CKD','Crooked Creek','Crooked Creek','AK'),('US','CKE','Cherokee','Cherokee','IA'),('US','CKF','Cherokee Falls','Cherokee Falls','SC'),('US','CKG','Cherokee','Cherokee','AL'),('US','CKH','Cheriton','Cheriton','VA'),('US','CKI','Catalina Is','Catalina Is','CA'),('US','CKJ','Clarksboro','Clarksboro','NJ'),('US','CKK','Cherokee','Cherokee','AR'),('US','CKL','Clarkston','Clarkston','WA'),('US','CKM','Clarksdale','Clarksdale','MS'),('US','CKN','Crookston','Crookston','MN'),('US','CKO','Colebrook','Colebrook','NH'),('US','CKP','Columbia','Columbia','PA'),('US','CKQ','Clarksville','Clarksville','IN'),('US','CKR','Crane Island','Crane Island','WA'),('US','CKS','Clarkston','Clarkston','GA'),('US','CKT','Cheektowaga','Cheektowaga','NY'),('US','CKU','Clarks Summit','Clarks Summit','PA'),('US','CKV','Clarksville','Clarksville','TN'),('US','CKW','Choctaw','Choctaw','MS'),('US','CKX','Chicken','Chicken','AK'),('US','CKY','Clayton','Clayton','IL'),('US','CKZ','Clayton','Clayton','IN'),('US','CL2','Castorland','Castorland','NY'),('US','CL3','Chualar','Chualar','CA'),('US','CL4','Clark','Clark','MO'),('US','CL5','Cleveland','Cleveland','IL'),('US','CL6','Columbia','Columbia','IL'),('US','CL7','Carlisle, Spartanburg','Carlisle, Spartanburg','SC'),('US','CL8','Celina','Celina','TN'),('US','CLA','Claymont','Claymont','DE'),('US','CLB','Clinton','Clinton','CT'),('US','CLC','Clearlake','Clearlake','TX'),('US','CLD','Carlsbad','Carlsbad','CA'),('US','CLE','Cleveland','Cleveland','OH'),('US','CLF','Cliffwood','Cliffwood','NJ'),('US','CLG','Coalinga','Coalinga','CA'),('US','CLH','Calhan','Calhan','CO'),('US','CLI','Clintonville','Clintonville','WI'),('US','CLJ','Camp Lejeune','Camp Lejeune','NC'),('US','CLK','Claverack','Claverack','NY'),('US','CLL','College Station','College Station','TX'),('US','CLM','Pt Angeles','Pt Angeles','WA'),('US','CLN','Clinton','Clinton','SC'),('US','CLO','Clermont','Clermont','KY'),('US','CLP','Clarks Point','Clarks Point','AK'),('US','CLQ','Chalmette','Chalmette','LA'),('US','CLR','Calipatria','Calipatria','CA'),('US','CLS','Chehalis','Chehalis','WA'),('US','CLT','Charlotte','Charlotte','NC'),('US','CLU','Columbus','Columbus','IN'),('US','CLV','Clarksville','Clarksville','AR'),('US','CLW','Clearwater','Clearwater','FL'),('US','CLX','Clarksburg','Clarksburg','TN'),('US','CLY','Clayton','Clayton','NY'),('US','CLZ','Clements','Clements','CA'),('US','CM2','Corona del Mar','Corona del Mar','CA'),('US','CM3','Carmichael','Carmichael','CA'),('US','CMA','Coleman','Coleman','MI'),('US','CMB','Cambridge','Cambridge','MS'),('US','CMC','Comanche','Comanche','TX'),('US','CMD','Chelmsford','Chelmsford','MA'),('US','CME','Clayton','Clayton','NC'),('US','CMF','Commack','Commack','NY'),('US','CMG','Cumming','Cumming','GA'),('US','CMH','Columbus','Columbus','OH'),('US','CMI','Champaign','Champaign','IL'),('US','CMJ','Comanche','Comanche','OK'),('US','CMK','Coloma','Coloma','MI'),('US','CML','Camilla','Camilla','GA'),('US','CMM','Chamblee','Chamblee','GA'),('US','CMN','Camino','Camino','CA'),('US','CMO','Clemmons','Clemmons','NC'),('US','CMP','Campbellsville','Campbellsville','KY'),('US','CMQ','Claremont','Claremont','CA'),('US','CMR','Camarillo','Camarillo','CA'),('US','CMS','Camas','Camas','WA'),('US','CMT','Commerce City','Commerce City','CO'),('US','CMU','Cameron','Cameron','NC'),('US','CMV','Carmel Valley','Carmel Valley','CA'),('US','CMW','Camano Is.','Camano Is.','WA'),('US','CMX','Hancock','Hancock','MI'),('US','CMY','Sparta','Sparta','WI'),('US','CMZ','Carmel','Carmel','NY'),('US','CN2','Cheney','Cheney','KS'),('US','CN6','New Connecticut','New Connecticut','NY'),('US','CNA','Collins','Collins','MS'),('US','CNB','Clinton','Clinton','MD'),('US','CNC','Clinton','Clinton','MI'),('US','CND','Canandaigua','Canandaigua','NY'),('US','CNE','Canon City','Canon City','CO'),('US','CNF','Canfield','Canfield','OH'),('US','CNG','Clinton','Clinton','NJ'),('US','CNH','Claremont','Claremont','NH'),('US','CNI','Chilton','Chilton','WI'),('US','CNJ','Colonial Heights','Colonial Heights','VA'),('US','CNK','Concordia','Concordia','KS'),('US','CNL','Carleton','Carleton','MI'),('US','CNM','Carlsbad','Carlsbad','NM'),('US','CNN','Canonsburg','Canonsburg','PA'),('US','CNO','Chino','Chino','CA'),('US','CNP','Canton','Canton','MS'),('US','CNQ','Canton','Canton','NC'),('US','CNR','Candor','Candor','NC'),('US','CNS','Canastota','Canastota','NY'),('US','CNT','Canton','Canton','MI'),('US','CNU','Chanute','Chanute','KS'),('US','CNV','Carlin','Carlin','NV'),('US','CNW','Buckner','Buckner','KY'),('US','CNX','Canton','Canton','GA'),('US','CNY','Moab','Moab','UT'),('US','CNZ','Canton','Canton','MO'),('US','CO2','Crab Orchard','Crab Orchard','TN'),('US','COA','Columbia','Columbia','CA'),('US','COB','Coos Bay','Coos Bay','OR'),('US','COC','Coachella','Coachella','CA'),('US','COD','Cody','Cody','WY'),('US','COE','Coeur d\'Alene','Coeur d\'Alene','ID'),('US','COF','Colfax','Colfax','LA'),('US','COG','Columbiana','Columbiana','OH'),('US','COH','Castleton On Hudson','Castleton On Hudson','NY'),('US','COI','Cocoa','Cocoa','FL'),('US','COJ','Cochranton','Cochranton','PA'),('US','COK','Cokato','Cokato','MN'),('US','COL','Colbert','Colbert','WA'),('US','COM','Coleman','Coleman','TX'),('US','CON','Concord','Concord','NH'),('US','COO','Cohoes','Cohoes','NY'),('US','COP','Cooperstown','Cooperstown','NY'),('US','COQ','Colquitt','Colquitt','GA'),('US','COR','Colora','Colora','MD'),('US','COS','Colorado Springs','Colorado Springs','CO'),('US','COT','Cotulla','Cotulla','TX'),('US','COU','Columbia','Columbia','MO'),('US','COV','Columbia','Columbia','WI'),('US','COW','Coldwater','Coldwater','OH'),('US','COX','Colmar','Colmar','PA'),('US','COY','Coal City','Coal City','IL'),('US','COZ','Columbia','Columbia','AL'),('US','CP2','Claypool','Claypool','AZ'),('US','CP3','Centerport, Gayuga','Centerport, Gayuga','NY'),('US','CP4','Cherry Point','Cherry Point','WA'),('US','CPA','Canoga Park','Canoga Park','CA'),('US','CPB','Campbell','Campbell','CA'),('US','CPC','Carle Place','Carle Place','NY'),('US','CPD','Cranberry Lake','Cranberry Lake','NY'),('US','CPE','Campbell','Campbell','NY'),('US','CPF','Chippewa Falls','Chippewa Falls','WI'),('US','CPG','College Park','College Park','GA'),('US','CPH','Cape Hatteras','Cape Hatteras','NC'),('US','CPI','Copperhill','Copperhill','TN'),('US','CPJ','Coral Springs','Coral Springs','FL'),('US','CPK','Cedar Park','Cedar Park','TX'),('US','CPL','Campbell','Campbell','MO'),('US','CPM','Compton','Compton','CA'),('US','CPN','College Point','College Point','NY'),('US','CPO','Cherry Point','Cherry Point','NC'),('US','CPP','Coraopolis','Coraopolis','PA'),('US','CPQ','Cowpens','Cowpens','SC'),('US','CPR','Casper','Casper','WY'),('US','CPS','Cosmopolis','Cosmopolis','WA'),('US','CPT','Carpinteria','Carpinteria','CA'),('US','CPU','Coopersburg','Coopersburg','PA'),('US','CPV','Cape Canaveral','Cape Canaveral','FL'),('US','CPW','Cooper City','Cooper City','FL'),('US','CPX','Chester Springs','Chester Springs','PA'),('US','CPY','Copley','Copley','OH'),('US','CPZ','Capistrano Beach','Capistrano Beach','CA'),('US','CQA','Colma','Colma','CA'),('US','CQB','Columbus Junction','Columbus Junction','IA'),('US','CQC','Colusa','Colusa','CA'),('US','CQD','Carbondale','Carbondale','PA'),('US','CQE','Cranbury','Cranbury','NJ'),('US','CQF','Cantonment','Cantonment','FL'),('US','CQG','Cranford','Cranford','NJ'),('US','CQH','Cranston','Cranston','RI'),('US','CQI','Carlisle','Carlisle','IN'),('US','CQJ','Clinton Township','Clinton Township','NJ'),('US','CQK','Creighton','Creighton','PA'),('US','CQL','Colo','Colo','IA'),('US','CQM','Cloquet','Cloquet','MN'),('US','CQN','Crescent','Crescent','IA'),('US','CQO','Charter Oak','Charter Oak','CA'),('US','CQP','Connellsville','Connellsville','PA'),('US','CQQ','Crete','Crete','IL'),('US','CQR','Carrollton','Carrollton','OH'),('US','CQS','Chesnee','Chesnee','SC'),('US','CQT','Clinton','Clinton','TN'),('US','CQU','Clearfield','Clearfield','UT'),('US','CQV','Cleveland','Cleveland','GA'),('US','CQW','Chocowinity','Chocowinity','NC'),('US','CQX','Clackamas','Clackamas','OR'),('US','CQY','Clayton','Clayton','DE'),('US','CQZ','Chester','Chester','SC'),('US','CR2','Carrollton','Carrollton','MO'),('US','CR3','Cream Ridge','Cream Ridge','NJ'),('US','CR4','Cuero','Cuero','TX'),('US','CR5','Chester','Chester','WV'),('US','CRA','Centralia','Centralia','WA'),('US','CRB','Carrabelle','Carrabelle','FL'),('US','CRC','Commerce/Los Angeles','Commerce/Los Angeles','CA'),('US','CRD','Cedar Falls','Cedar Falls','IA'),('US','CRE','Carnegie','Carnegie','PA'),('US','CRF','Croydon','Croydon','PA'),('US','CRG','Chicago Ridge','Chicago Ridge','IL'),('US','CRH','Church Hill','Church Hill','TN'),('US','CRI','Crisfield','Crisfield','MD'),('US','CRJ','Carman','Carman','NY'),('US','CRK','Carrollton','Carrollton','KY'),('US','CRL','Carlisle','Carlisle','OH'),('US','CRM','Crockett','Crockett','CA'),('US','CRN','Coon Rapids','Coon Rapids','IA'),('US','CRO','Corcoran','Corcoran','CA'),('US','CRP','Corpus Christi','Corpus Christi','TX'),('US','CRQ','Charlotte','Charlotte','MI'),('US','CRR','Carrollton','Carrollton','GA'),('US','CRS','Corsicana','Corsicana','TX'),('US','CRT','Crossett','Crossett','AR'),('US','CRU','Carson','Carson','CA'),('US','CRV','Carpentersville','Carpentersville','IL'),('US','CRW','Charleston','Charleston','WV'),('US','CRX','Corinth','Corinth','MS'),('US','CRY','Careywood','Careywood','ID'),('US','CRZ','Ceres','Ceres','CA'),('US','CS2','Cash','Cash','AR'),('US','CS4','St Clair Shores','St Clair Shores','MI'),('US','CS5','Chelsea','Chelsea','OK'),('US','CS6','Coxsackie, Greene','Coxsackie, Greene','NY'),('US','CSA','Cape Sabine','Cape Sabine','AK'),('US','CSB','Chebanse','Chebanse','IL'),('US','CSC','Coshocton','Coshocton','OH'),('US','CSD','Cliffside Park','Cliffside Park','NJ'),('US','CSE','Crested Butte','Crested Butte','CO'),('US','CSF','Carteret','Carteret','NJ'),('US','CSG','Columbus','Columbus','GA'),('US','CSH','Conshohocken','Conshohocken','PA'),('US','CSI','Chester','Chester','IL'),('US','CSJ','Carlisle','Carlisle','MA'),('US','CSK','Castle Rock','Castle Rock','CO'),('US','CSL','San Luis Obispo','San Luis Obispo','CA'),('US','CSM','Clinton','Clinton','OK'),('US','CSN','Carson City','Carson City','NV'),('US','CSO','Casnovia','Casnovia','MI'),('US','CSP','Cape Spencer','Cape Spencer','AK'),('US','CSQ','Creston','Creston','IA'),('US','CSR','Chester','Chester','NY'),('US','CSS','Clifton Springs','Clifton Springs','NY'),('US','CST','Charleston','Charleston','TX'),('US','CSU','Carsonville','Carsonville','MI'),('US','CSV','Crossville','Crossville','TN'),('US','CSW','Chickamauga','Chickamauga','GA'),('US','CSX','Charlevoix','Charlevoix','MI'),('US','CSY','Crosby','Crosby','ND'),('US','CSZ','Chester','Chester','VA'),('US','CT3','Clinton','Clinton','MN'),('US','CT4','Cottontown','Cottontown','TN'),('US','CT5','Castleton','Castleton','VT'),('US','CT6','Centerville','Centerville','MA'),('US','CTA','Catawba','Catawba','SC'),('US','CTB','Cut Bank','Cut Bank','MT'),('US','CTC','Charleston','Charleston','TN'),('US','CTD','Crystal Lake','Crystal Lake','IL'),('US','CTE','Chattahoochee','Chattahoochee','FL'),('US','CTF','Crete','Crete','NE'),('US','CTG','Cresco','Cresco','PA'),('US','CTH','Coatesville','Coatesville','PA'),('US','CTI','Contoocook','Contoocook','NH'),('US','CTJ','Canton','Canton','IL'),('US','CTK','Canton','Canton','SD'),('US','CTL','Central','Central','SC'),('US','CTM','Cottondale','Cottondale','FL'),('US','CTN','Colts Neck','Colts Neck','NJ'),('US','CTO','Calverton','Calverton','NY'),('US','CTP','Campton','Campton','KY'),('US','CTQ','Catawba','Catawba','NC'),('US','CTR','Carter Lake','Carter Lake','IA'),('US','CTS','Charles Town','Charles Town','WV'),('US','CTT','Centerport','Centerport','NY'),('US','CTU','Citrus Heights','Citrus Heights','CA'),('US','CTV','Castroville','Castroville','CA'),('US','CTW','Cottonwood','Cottonwood','AZ'),('US','CTX','Cortland','Cortland','NY'),('US','CTY','Cross City','Cross City','FL'),('US','CTZ','Clinton','Clinton','NC'),('US','CU2','Clute','Clute','TX'),('US','CUA','Cuba','Cuba','NM'),('US','CUB','Columbia','Columbia','NC'),('US','CUC','Counce','Counce','TN'),('US','CUD','Cudahy','Cudahy','WI'),('US','CUE','Cumberland','Cumberland','RI'),('US','CUF','Cut and Shoot','Cut and Shoot','TX'),('US','CUG','Cutler','Cutler','CA'),('US','CUH','Cushing','Cushing','OK'),('US','CUI','Curwensville','Curwensville','PA'),('US','CUJ','Cuyahoga Falls','Cuyahoga Falls','OH'),('US','CUK','Central City','Central City','KY'),('US','CUL','Cullman','Cullman','AL'),('US','CUM','Canaan','Canaan','CT'),('US','CUN','Conover','Conover','NC'),('US','CUO','Cupertino','Cupertino','CA'),('US','CUP','Calumet Park','Calumet Park','IL'),('US','CUQ','Caney','Caney','KS'),('US','CUR','Coburg','Coburg','OR'),('US','CUS','Columbus','Columbus','NM'),('US','CUT','Chestnut','Chestnut','CA'),('US','CUU','Cannelton','Cannelton','IN'),('US','CUV','Chula Vista','Chula Vista','CA'),('US','CUW','Cube Cove','Cube Cove','AK'),('US','CUX','Chateaugay','Chateaugay','NY'),('US','CUY','Cudahy','Cudahy','CA'),('US','CUZ','Carlisle','Carlisle','AR'),('US','CV2','Centreville','Centreville','GA'),('US','CV3','Conneautville','Conneautville','PA'),('US','CV4','Correctionville','Correctionville','IA'),('US','CV5','Camas Valley','Camas Valley','OR'),('US','CV6','Coulterville','Coulterville','IL'),('US','CV7','Cove','Cove','AR'),('US','CV8','Culver','Culver','OR'),('US','CV9','Caseyville','Caseyville','IL'),('US','CVA','Castro Valley','Castro Valley','CA'),('US','CVB','Coralville','Coralville','IA'),('US','CVC','Comstock','Comstock','MI'),('US','CVD','Cleveland','Cleveland','MS'),('US','CVE','Centerville','Centerville','GA'),('US','CVF','Covington','Covington','GA'),('US','CVG','Cincinnati','Cincinnati','OH'),('US','CVH','Crothersville','Crothersville','IN'),('US','CVI','Cape Vincent','Cape Vincent','NY'),('US','CVJ','Covington','Covington','VA'),('US','CVK','Covington','Covington','KY'),('US','CVL','Corvallis','Corvallis','OR'),('US','CVM','Catonsville','Catonsville','MD'),('US','CVN','Clovis','Clovis','NM'),('US','CVO','Albany-Corvallis Apt','Albany-Corvallis Apt','OR'),('US','CVP','Cloverport','Cloverport','KY'),('US','CVQ','Covina','Covina','CA'),('US','CVR','Culver City','Culver City','CA'),('US','CVS','Clovis','Clovis','CA'),('US','CVT','Cleveland','Cleveland','NC'),('US','CVU','Channelview','Channelview','TX'),('US','CVV','Cloverdale','Cloverdale','VA'),('US','CVW','Cleveland','Cleveland','WI'),('US','CVX','Cavendish','Cavendish','VT'),('US','CVY','Clarksville','Clarksville','VA'),('US','CVZ','Centerville','Centerville','LA'),('US','CW2','Cowen, Webster','Cowen, Webster','WV'),('US','CW3','Cropwell','Cropwell','AL'),('US','CWA','Coldwater','Coldwater','MI'),('US','CWB','Crestwood','Crestwood','IL'),('US','CWC','Chowchilla','Chowchilla','CA'),('US','CWD','Collingswood','Collingswood','NJ'),('US','CWE','Chilhowie','Chilhowie','VA'),('US','CWF','Centerville','Centerville','MN'),('US','CWG','Callaway Gardens','Callaway Gardens','GA'),('US','CWH','Chatsworth','Chatsworth','CA'),('US','CWI','Clinton','Clinton','IA'),('US','CWJ','Cave Junction','Cave Junction','OR'),('US','CWK','Cheswick','Cheswick','PA'),('US','CWL','Crowley','Crowley','LA'),('US','CWM','Chatham','Chatham','VA'),('US','CWN','Chestertown','Chestertown','MD'),('US','CWO','Colwich','Colwich','KS'),('US','CWP','Coldwater','Coldwater','MS'),('US','CWQ','Center Valley','Center Valley','PA'),('US','CWR','Clearwater','Clearwater','NE'),('US','CWS','Center Island','Center Island','WA'),('US','CWT','Covington','Covington','LA'),('US','CWU','Carroll','Carroll','OH'),('US','CWV','Coral Way Village/Miami','Coral Way Village/Miami','FL'),('US','CWW','Clarkesville','Clarkesville','GA'),('US','CWX','Cleveland','Cleveland','MO'),('US','CWY','Conway','Conway','NH'),('US','CWZ','Clinton','Clinton','WI'),('US','CXA','Croswell','Croswell','MI'),('US','CXB','Carver','Carver','OR'),('US','CXC','Chitina','Chitina','AK'),('US','CXD','Creve Coeur','Creve Coeur','IL'),('US','CXE','Clarita','Clarita','OK'),('US','CXF','Coldfoot','Coldfoot','AK'),('US','CXG','Cross Junction','Cross Junction','VA'),('US','CXH','Cross Plains','Cross Plains','WI'),('US','CXI','Clear','Clear','AK'),('US','CXJ','Carey','Carey','OH'),('US','CXK','Carmichaels','Carmichaels','PA'),('US','CXL','Calexico','Calexico','CA'),('US','CXM','Cameron','Cameron','TX'),('US','CXN','Clermont','Clermont','NY'),('US','CXO','Conroe','Conroe','TX'),('US','CXP','Colorado City','Colorado City','TX'),('US','CXQ','Clayton','Clayton','AL'),('US','CXR','Closter/New Jersey','Closter/New Jersey','NJ'),('US','CXS','Charleston','Charleston','MO'),('US','CXT','Claxton','Claxton','GA'),('US','CXU','Connellys Springs','Connellys Springs','NC'),('US','CXV','Clover','Clover','SC'),('US','CXW','Centerville','Centerville','OH'),('US','CXX','Caledonia','Caledonia','WI'),('US','CXY','Crosbyton','Crosbyton','TX'),('US','CXZ','Sharon Center','Sharon Center','OH'),('US','CY2','The Colony','The Colony','TX'),('US','CY5','Conyngham','Conyngham','PA'),('US','CY6','Clay','Clay','NY'),('US','CYA','Clyde','Clyde','NY'),('US','CYB','Clyde','Clyde','OH'),('US','CYC','Cayce','Cayce','SC'),('US','CYD','Cecilton','Cecilton','MD'),('US','CYE','Crystal Lake','Crystal Lake','PA'),('US','CYF','Chefornak','Chefornak','AK'),('US','CYG','Cayuga','Cayuga','IN'),('US','CYH','Crystal Springs','Crystal Springs','MS'),('US','CYI','Cloverdale','Cloverdale','CA'),('US','CYJ','Cresskill','Cresskill','NJ'),('US','CYK','Clay Center','Clay Center','KS'),('US','CYL','Chantilly','Chantilly','VA'),('US','CYM','Chatham','Chatham','AK'),('US','CYN','Clayton','Clayton','NJ'),('US','CYO','Croton','Croton','OH'),('US','CYP','Corry','Corry','PA'),('US','CYQ','Cypress','Cypress','CA'),('US','CYR','Conyers','Conyers','GA'),('US','CYS','Cheyenne','Cheyenne','WY'),('US','CYT','Clayton','Clayton','OH'),('US','CYU','Cayuta','Cayuta','NY'),('US','CYV','Cordova','Cordova','WV'),('US','CYW','Clyattville','Clyattville','GA'),('US','CYX','Cypress','Cypress','TX'),('US','CYY','Crystal City','Crystal City','TX'),('US','CYZ','Chester','Chester','NJ'),('US','CZA','Cornelia','Cornelia','GA'),('US','CZB','Corydon','Corydon','IN'),('US','CZC','Copper Centre','Copper Centre','AK'),('US','CZD','Cornwells Heights','Cornwells Heights','PA'),('US','CZE','Corona','Corona','CA'),('US','CZF','Cape Romanzof','Cape Romanzof','AK'),('US','CZG','Cornelius','Cornelius','OR'),('US','CZH','Cornelius Pass','Cornelius Pass','OR'),('US','CZI','Cassopolis','Cassopolis','MI'),('US','CZK','Cascade Locks','Cascade Locks','OR'),('US','CZL','Corte Madera','Corte Madera','CA'),('US','CZM','Costa Mesa','Costa Mesa','CA'),('US','CZN','Chisana','Chisana','AK'),('US','CZO','Chistochina','Chistochina','AK'),('US','CZP','Cape Pole','Cape Pole','AK'),('US','CZQ','Coudersport','Coudersport','PA'),('US','CZR','Crozet','Crozet','VA'),('US','CZS','Chelsea','Chelsea','MA'),('US','CZT','Carrizo Springs','Carrizo Springs','TX'),('US','CZU','Conley','Conley','GA'),('US','CZV','Cottonwood','Cottonwood','CA'),('US','CZW','Cottonwood','Cottonwood','MN'),('US','CZX','Columbus','Columbus','NC'),('US','CZY','Comyn','Comyn','TX'),('US','CZZ','Campo','Campo','CA'),('US','DA2','Delta','Delta','OH'),('US','DAA','Fort Belvoir','Fort Belvoir','VA'),('US','DAB','Daytona Beach','Daytona Beach','FL'),('US','DAC','Dallas','Dallas','NC'),('US','DAD','Dania','Dania','FL'),('US','DAE','Dallas','Dallas','OR'),('US','DAG','Daggett','Daggett','CA'),('US','DAH','Danboro','Danboro','PA'),('US','DAI','Dailey','Dailey','WV'),('US','DAK','Dakota City','Dakota City','IA'),('US','DAL','Dallas','Dallas','TX'),('US','DAM','Damascus','Damascus','GA'),('US','DAN','Danville','Danville','VA'),('US','DAO','Davidson','Davidson','NC'),('US','DAP','Danville','Danville','PA'),('US','DAQ','Darien','Darien','CT'),('US','DAR','Dardanelle','Dardanelle','AR'),('US','DAS','Davis','Davis','CA'),('US','DAT','Dayton','Dayton','TN'),('US','DAU','Danbury','Danbury','NH'),('US','DAV','Davenport','Davenport','CA'),('US','DAW','Dawson','Dawson','GA'),('US','DAX','Dandridge','Dandridge','TN'),('US','DAY','Dayton','Dayton','OH'),('US','DAZ','Dallastown','Dallastown','PA'),('US','DB2','DeBary','DeBary','FL'),('US','DBA','Del Bonita','Del Bonita','MT'),('US','DBB','Darby','Darby','PA'),('US','DBF','Dobbs Ferry','Dobbs Ferry','NY'),('US','DBI','Dubois','Dubois','IN'),('US','DBL','Dublin','Dublin','TX'),('US','DBN','Dublin','Dublin','GA'),('US','DBO','Dalbo','Dalbo','MN'),('US','DBQ','Dubuque','Dubuque','IA'),('US','DBR','Diamond Bar','Diamond Bar','CA'),('US','DBS','Dubois','Dubois','ID'),('US','DBU','Middleburg, Logan','Middleburg, Logan','OH'),('US','DBY','Derby Line','Derby Line','VT'),('US','DC2','Dale City','Dale City','VA'),('US','DC3','Ducktown','Ducktown','TN'),('US','DCA','National Apt/Washington','National Apt/Washington','DC'),('US','DCB','DeKalb','DeKalb','IL'),('US','DCG','Decatur','Decatur','GA'),('US','DCH','Decherd','Decherd','TN'),('US','DCI','Delaware City','Delaware City','DE'),('US','DCK','Dahl Creek','Dahl Creek','AK'),('US','DCL','Declo','Declo','ID'),('US','DCO','Ducor','Ducor','CA'),('US','DCQ','Dacono','Dacono','CO'),('US','DCR','Decatur','Decatur','IN'),('US','DCS','Dorchester','Dorchester','WI'),('US','DCT','Derby','Derby','CT'),('US','DCU','Decatur','Decatur','AL'),('US','DD2','Ada','Ada','MN'),('US','DD3','Middletown, Shelby','Middletown, Shelby','IN'),('US','DDA','Tuckerman','Tuckerman','AR'),('US','DDB','Dade City','Dade City','FL'),('US','DDC','Dodge City','Dodge City','KS'),('US','DDD','Dorr','Dorr','MI'),('US','DDE','Deerfield','Deerfield','MA'),('US','DDF','South Deerfield','South Deerfield','MA'),('US','DDG','Dodge','Dodge','NE'),('US','DDI','Durand','Durand','IL'),('US','DDJ','Dry Ridge','Dry Ridge','KY'),('US','DDO','Eldorado','Eldorado','TX'),('US','DDQ','Dundalk','Dundalk','MD'),('US','DDR','Darien','Darien','WI'),('US','DDV','Dodgeville','Dodgeville','WI'),('US','DDW','Deadwood','Deadwood','SD'),('US','DDX','Addison','Addison','TX'),('US','DDY','Middleway','Middleway','WV'),('US','DEA','Delavan','Delavan','WI'),('US','DEB','Wadesboro','Wadesboro','NC'),('US','DEC','Decatur','Decatur','IL'),('US','DED','Dedham','Dedham','MA'),('US','DEE','Deerfield Beach','Deerfield Beach','FL'),('US','DEF','Deferiet','Deferiet','NY'),('US','DEH','Decorah','Decorah','IA'),('US','DEI','Delphi','Delphi','IN'),('US','DEK','De Kalb','De Kalb','IL'),('US','DEL','Delaware','Delaware','OH'),('US','DEM','Dermott','Dermott','AR'),('US','DEN','Denver','Denver','CO'),('US','DEO','Dearborn','Dearborn','MI'),('US','DEP','Delphos','Delphos','OH'),('US','DEQ','Deep River','Deep River','CT'),('US','DER','Dover','Dover','IL'),('US','DES','Des Plaines','Des Plaines','IL'),('US','DET','Detroit','Detroit','MI'),('US','DEU','Decatur','Decatur','TX'),('US','DEV','Devon','Devon','PA'),('US','DEW','Dewitt','Dewitt','NY'),('US','DEX','Deer Park','Deer Park','TX'),('US','DEY','Delray Beach','Delray Beach','FL'),('US','DEZ','Dewitt','Dewitt','IL'),('US','DFC','Defiance','Defiance','MO'),('US','DFD','Deerfield','Deerfield','WI'),('US','DFE','Deerfield','Deerfield','NH'),('US','DFF','Cedar Bluff','Cedar Bluff','VA'),('US','DFG','Daingerfield','Daingerfield','TX'),('US','DFI','Defiance','Defiance','OH'),('US','DFK','Dry Fork, Pittsylvania','Dry Fork, Pittsylvania','VA'),('US','DFL','Deerfield','Deerfield','OH'),('US','DFM','Deerfield','Deerfield','MO'),('US','DFN','De Funiak Springs','De Funiak Springs','FL'),('US','DFO','De Forest','De Forest','WI'),('US','DFR','Bedford','Bedford','NH'),('US','DFS','Dumfries','Dumfries','VA'),('US','DFU','Dunnellon','Dunnellon','FL'),('US','DFW','Dallas-Fort Worth Int Apt','Dallas-Fort Worth Int Apt','TX'),('US','DFX','Defense','Defense','TX'),('US','DGA','Duluth','Duluth','GA'),('US','DGB','Danger Bay','Danger Bay','AK'),('US','DGE','Chenango Bridge','Chenango Bridge','NY'),('US','DGL','Douglassville','Douglassville','PA'),('US','DGN','Dahlgren','Dahlgren','VA'),('US','DGO','Edgewood','Edgewood','NM'),('US','DGP','Shade Gap','Shade Gap','PA'),('US','DGR','Deer Grove','Deer Grove','IL'),('US','DGS','Douglaston/Queens/New York','Douglaston/Queens/New York','NY'),('US','DGT','Dighton','Dighton','MA'),('US','DGV','Douglasville','Douglasville','GA'),('US','DGW','Douglas','Douglas','WY'),('US','DGZ','Douglas','Douglas','AR'),('US','DHG','Dearborn Heights','Dearborn Heights','MI'),('US','DHH','Durham','Durham','OR'),('US','DHI','Delhi','Delhi','IA'),('US','DHL','Dahlonega','Dahlonega','GA'),('US','DHN','Dothan','Dothan','AL'),('US','DHQ','Durham','Durham','CT'),('US','DHS','Desert Hot Springs','Desert Hot Springs','CA'),('US','DHT','Dalhart','Dalhart','TX'),('US','DHX','Delhi','Delhi','LA'),('US','DIA','Adrian','Adrian','WI'),('US','DIB','Diboll','Diboll','TX'),('US','DIC','Madison','Madison','FL'),('US','DID','Denver','Denver','NC'),('US','DIG','Dunnigan','Dunnigan','CA'),('US','DIK','Dickinson','Dickinson','ND'),('US','DIL','Danville','Danville','NY'),('US','DIM','Derma','Derma','MS'),('US','DIN','Medina','Medina','TX'),('US','DIO','Diomede Island','Diomede Island','AK'),('US','DIS','Daniels','Daniels','WV'),('US','DIU','Dinuba','Dinuba','CA'),('US','DIV','Cedar River','Cedar River','MI'),('US','DIZ','Dominguez Hills','Dominguez Hills','CA'),('US','DJN','Delta Junction','Delta Junction','AK'),('US','DJR','Dunlap','Dunlap','IL'),('US','DKC','Dakota City','Dakota City','NE'),('US','DKD','Dunkirk','Dunkirk','IN'),('US','DKK','Dunkirk','Dunkirk','NY'),('US','DKS','Dierks','Dierks','AR'),('US','DL2','Donnelly','Donnelly','ID'),('US','DLA','Delair','Delair','NJ'),('US','DLD','De Land','De Land','FL'),('US','DLE','Delisle','Delisle','MS'),('US','DLF','De Leon Springs','De Leon Springs','FL'),('US','DLG','Dillingham','Dillingham','AK'),('US','DLH','Duluth','Duluth','MN'),('US','DLI','Danville','Danville','IN'),('US','DLJ','Delanco','Delanco','NJ'),('US','DLK','Dayville','Dayville','CT'),('US','DLL','Dillon','Dillon','SC'),('US','DLN','Dillon','Dillon','MT'),('US','DLO','Dolomi','Dolomi','AK'),('US','DLP','Darlington','Darlington','PA'),('US','DLQ','Deer Lake, Schuylkill','Deer Lake, Schuylkill','PA'),('US','DLR','Dal-nor','Dal-nor','TX'),('US','DLS','The Dalles','The Dalles','OR'),('US','DLT','Deltona','Deltona','FL'),('US','DLU','Delano','Delano','PA'),('US','DLV','Danville','Danville','IA'),('US','DLX','Dallas','Dallas','GA'),('US','DLY','Del Rey','Del Rey','CA'),('US','DLZ','Deerfield','Deerfield','MI'),('US','DM2','Del Mar, San Diego','Del Mar, San Diego','CA'),('US','DM3','Delmar','Delmar','DE'),('US','DMB','Double Springs','Double Springs','AL'),('US','DMD','Diamond','Diamond','MO'),('US','DMG','Dillsburg','Dillsburg','PA'),('US','DMI','Drayton Plains','Drayton Plains','MI'),('US','DMK','Denmark','Denmark','SC'),('US','DML','Dimondale','Dimondale','MI'),('US','DMN','Deming','Deming','NM'),('US','DMO','Sedalia','Sedalia','MO'),('US','DMP','Demopolis','Demopolis','AL'),('US','DMR','Dixmoor','Dixmoor','IL'),('US','DMS','Dumas','Dumas','AR'),('US','DMT','Deer River','Deer River','MN'),('US','DMU','Damascus','Damascus','VA'),('US','DMZ','Dominguez','Dominguez','CA'),('US','DN2','Del Norte','Del Norte','CO'),('US','DN3','Darrington','Darrington','WA'),('US','DNA','Donaldsonville','Donaldsonville','LA'),('US','DNB','Dunedin','Dunedin','FL'),('US','DNC','Dorrance','Dorrance','KS'),('US','DND','Dundee','Dundee','MI'),('US','DNE','Dane','Dane','WI'),('US','DNG','Dongola','Dongola','IL'),('US','DNI','Denali','Denali','AK'),('US','DNK','Duncan','Duncan','SC'),('US','DNL','Denville','Denville','NJ'),('US','DNM','Denham Springs','Denham Springs','LA'),('US','DNN','Dalton','Dalton','GA'),('US','DNO','Delano','Delano','CA'),('US','DNP','Derry','Derry','NH'),('US','DNQ','Denver','Denver','PA'),('US','DNR','Drain','Drain','OR'),('US','DNS','Denison','Denison','IA'),('US','DNT','Downingtown','Downingtown','PA'),('US','DNV','Dunnville','Dunnville','KY'),('US','DNY','Danby','Danby','VT'),('US','DNZ','Dunmore','Dunmore','PA'),('US','DO6','Dora','Dora','AL'),('US','DOA','Cordova','Cordova','TN'),('US','DOB','Dobson','Dobson','NC'),('US','DOD','McDonald, Muskingum','McDonald, Muskingum','OH'),('US','DOE','Doe Run','Doe Run','KY'),('US','DOF','Dora Bay','Dora Bay','AK'),('US','DOG','Douglas, Allegan','Douglas, Allegan','MI'),('US','DOL','Dolomite','Dolomite','AL'),('US','DON','DeLeon','DeLeon','TX'),('US','DOO','Dover','Dover','OH'),('US','DOR','Dover','Dover','FL'),('US','DOS','Doswell','Doswell','VA'),('US','DOT','DeSoto','DeSoto','TX'),('US','DOU','Douglas','Douglas','GA'),('US','DOV','Dover-Cheswold','Dover-Cheswold','DE'),('US','DOW','Dowagiac','Dowagiac','MI'),('US','DOX','Delano','Delano','MN'),('US','DOY','Doyle','Doyle','CA'),('US','DP2','Deer Park, Camden','Deer Park, Camden','NJ'),('US','DPA','Deerpark','Deerpark','FL'),('US','DPC','Deer Park','Deer Park','PA'),('US','DPE','Depew','Depew','NY'),('US','DPF','Deptford','Deptford','NJ'),('US','DPG','Dugway','Dugway','UT'),('US','DPH','Doniphan','Doniphan','MO'),('US','DPI','Deposit','Deposit','NY'),('US','DPK','Deer Park','Deer Park','NY'),('US','DPO','Deport','Deport','TX'),('US','DPQ','Dalton','Dalton','PA'),('US','DPT','Dana Point','Dana Point','CA'),('US','DPV','Disputanta','Disputanta','VA'),('US','DPW','Deepwater','Deepwater','NJ'),('US','DQB','Dublin','Dublin','CA'),('US','DQL','Dacula','Dacula','GA'),('US','DQN','Dolton','Dolton','IL'),('US','DR2','Dover','Dover','PA'),('US','DRA','Mercury','Mercury','NV'),('US','DRB','Bridgeport','Bridgeport','TX'),('US','DRD','Deerfield','Deerfield','IL'),('US','DRE','Drummond Island','Drummond Island','MI'),('US','DRF','Drift River','Drift River','AK'),('US','DRG','Deering','Deering','AK'),('US','DRH','Doraville','Doraville','GA'),('US','DRI','De Ridder','De Ridder','LA'),('US','DRJ','Delran','Delran','NJ'),('US','DRK','Draper','Draper','AR'),('US','DRL','Drexel','Drexel','MO'),('US','DRM','Drew','Drew','MS'),('US','DRN','Darlington','Darlington','SC'),('US','DRO','Durango','Durango','CO'),('US','DRP','Donora','Donora','PA'),('US','DRQ','Draper','Draper','UT'),('US','DRR','Darrow','Darrow','LA'),('US','DRS','Dorsey','Dorsey','MD'),('US','DRT','Del Rio','Del Rio','TX'),('US','DRU','Drummond','Drummond','MT'),('US','DRV','Dover','Dover','NH'),('US','DRW','De Pere','De Pere','WI'),('US','DRX','Drexel','Drexel','NC'),('US','DRY','Dry Branch','Dry Branch','GA'),('US','DRZ','Del Rio','Del Rio','TN'),('US','DSC','Damascus','Damascus','OR'),('US','DSD','Dresden','Dresden','TN'),('US','DSE','Dunstable','Dunstable','MA'),('US','DSG','Dawson Springs','Dawson Springs','KY'),('US','DSH','Deshler','Deshler','OH'),('US','DSI','Destin','Destin','FL'),('US','DSK','Swords Creek','Swords Creek','VA'),('US','DSL','Donalsonville','Donalsonville','GA'),('US','DSM','Des Moines','Des Moines','IA'),('US','DSN','Des Moines','Des Moines','WA'),('US','DSO','Danielson','Danielson','CT'),('US','DSP','Dallas','Dallas','PA'),('US','DSQ','De Soto','De Soto','MO'),('US','DSR','Deshler','Deshler','NE'),('US','DST','Adamston','Adamston','WV'),('US','DSU','Decatur','Decatur','NE'),('US','DSV','Dansville','Dansville','NY'),('US','DSW','Dresser','Dresser','WI'),('US','DSX','Dickinson','Dickinson','TX'),('US','DSZ','Denison','Denison','TX'),('US','DT2','Decatur','Decatur','IA'),('US','DT3','Dorset','Dorset','VT'),('US','DT4','De Tour Village','De Tour Village','MI'),('US','DTA','Delta','Delta','UT'),('US','DTH','Death Valley','Death Valley','CA'),('US','DTL','Detroit Lakes','Detroit Lakes','MN'),('US','DTN','Denton','Denton','TX'),('US','DTO','Denton','Denton','GA'),('US','DTP','Portland','Portland','TX'),('US','DTR','Decatur Island','Decatur Island','WA'),('US','DTT','Detroit','Detroit','IL'),('US','DTU','Decatur','Decatur','AR'),('US','DTV','Decatur','Decatur','TN'),('US','DTW','Wayne County Apt/Detroit','Wayne County Apt/Detroit','MI'),('US','DTX','Dayton','Dayton','TX'),('US','DU8','Dutton','Dutton','MI'),('US','DUA','Durant','Durant','OK'),('US','DUB','Duarte','Duarte','CA'),('US','DUC','Duncan','Duncan','OK'),('US','DUD','Duffield','Duffield','VA'),('US','DUE','Dunbridge','Dunbridge','OH'),('US','DUF','Duck','Duck','NC'),('US','DUG','Douglas','Douglas','AZ'),('US','DUI','Dublin','Dublin','PA'),('US','DUJ','Dubois','Dubois','PA'),('US','DUK','Duke','Duke','OK'),('US','DUL','Dunellen','Dunellen','NJ'),('US','DUM','Dunn','Dunn','SC'),('US','DUN','Dunseith','Dunseith','ND'),('US','DUO','Dublin','Dublin','OH'),('US','DUP','Dupo','Dupo','IL'),('US','DUQ','Duquoin','Duquoin','IL'),('US','DUR','Durham','Durham','NC'),('US','DUS','Dushore','Dushore','PA'),('US','DUT','Dutch Harbor','Dutch Harbor','AK'),('US','DUU','Du Quoin','Du Quoin','IL'),('US','DUV','Duncansville','Duncansville','PA'),('US','DUW','Durbin','Durbin','WV'),('US','DUX','Dumas','Dumas','TX'),('US','DUZ','Dunn','Dunn','NC'),('US','DV2','Davidsonville','Davidsonville','MD'),('US','DV3','Duncanville','Duncanville','TX'),('US','DV4','Daleville','Daleville','VA'),('US','DVA','Delevan','Delevan','NY'),('US','DVB','Dravosburg','Dravosburg','PA'),('US','DVC','Denver City','Denver City','TX'),('US','DVD','Devine','Devine','TX'),('US','DVE','Davie','Davie','NC'),('US','DVF','Davie','Davie','FL'),('US','DVI','Danville','Danville','IL'),('US','DVJ','Dover','Dover','NJ'),('US','DVK','Danville','Danville','KY'),('US','DVL','Devils Lake','Devils Lake','ND'),('US','DVN','Davenport','Davenport','IA'),('US','DVO','Davison','Davison','MI'),('US','DVP','Davenport','Davenport','FL'),('US','DVQ','Delmont','Delmont','PA'),('US','DVR','Danvers','Danvers','MA'),('US','DVS','Davis','Davis','OK'),('US','DVT','Davant','Davant','LA'),('US','DVV','Davisville','Davisville','RI'),('US','DVW','Grandview','Grandview','IN'),('US','DVX','Dawsonville','Dawsonville','GA'),('US','DVY','Daleville','Daleville','AL'),('US','DW2','Derwood','Derwood','MD'),('US','DWA','De Witt','De Witt','AR'),('US','DWD','Deerwood','Deerwood','MN'),('US','DWG','Delaware Water Gap','Delaware Water Gap','PA'),('US','DWH','Dilworth','Dilworth','MN'),('US','DWI','Dwight','Dwight','IL'),('US','DWL','Caldwell','Caldwell','KS'),('US','DWO','Dewey','Dewey','OK'),('US','DWR','Redwood','Redwood','MS'),('US','DWT','De Witt','De Witt','MI'),('US','DWV','Dunbar','Dunbar','WV'),('US','DWW','Dewitt','Dewitt','IA'),('US','DWX','De Witt','De Witt','NE'),('US','DWZ','Downey','Downey','PA'),('US','DX2','Dexter City','Dexter City','OH'),('US','DXC','Dixon','Dixon','CA'),('US','DXD','Durand','Durand','WI'),('US','DXE','Dexter','Dexter','MO'),('US','DXG','Diamond Springs','Diamond Springs','CA'),('US','DXI','Dexter','Dexter','NM'),('US','DXL','Daly City','Daly City','CA'),('US','DXN','Dixon','Dixon','IL'),('US','DXR','Danbury','Danbury','CT'),('US','DXT','Dexter','Dexter','NY'),('US','DXY','Dollar Bay','Dollar Bay','MI'),('US','DY2','Dayton','Dayton','KY'),('US','DY3','Dilley','Dilley','TX'),('US','DYA','Duryea','Duryea','PA'),('US','DYC','Days Creek','Days Creek','OR'),('US','DYD','Dayton','Dayton','NY'),('US','DYE','Dyersville','Dyersville','IA'),('US','DYG','Shady Grove','Shady Grove','PA'),('US','DYI','Dundee','Dundee','IL'),('US','DYJ','Dayton','Dayton','NV'),('US','DYK','Dundee','Dundee','NY'),('US','DYL','Doylestown','Doylestown','PA'),('US','DYQ','Dyer','Dyer','IN'),('US','DYR','Dyersburg','Dyersburg','TN'),('US','DYS','Dyer','Dyer','TN'),('US','DYT','Dayton','Dayton','NJ'),('US','DYU','Dundee','Dundee','FL'),('US','DYV','Dayton','Dayton','VA'),('US','DYW','Dayton','Dayton','WA'),('US','DYX','Donnelly','Donnelly','AK'),('US','DZL','Dalzell','Dalzell','SC'),('US','DZM','Dorchester','Dorchester','MA'),('US','DZN','Vinton','Vinton','LA'),('US','DZQ','Scott Depot','Scott Depot','WV'),('US','DZU','Dulzura','Dulzura','CA'),('US','EAA','Eagle','Eagle','AK'),('US','EAB','East Bridgewater','East Bridgewater','MA'),('US','EAC','Beach','Beach','ND'),('US','EAD','England','England','AR'),('US','EAE','Earle','Earle','NJ'),('US','EAF','Clear Lake','Clear Lake','IA'),('US','EAG','Eagle Point','Eagle Point','NJ'),('US','EAH','East Hampton','East Hampton','CT'),('US','EAI','East Irvine','East Irvine','CA'),('US','EAJ','Eatontown','Eatontown','NJ'),('US','EAK','Clearlake','Clearlake','CA'),('US','EAL','Easley','Easley','SC'),('US','EAM','Earle','Earle','AR'),('US','EAN','Wheatland','Wheatland','WY'),('US','EAO','East Aurora','East Aurora','NY'),('US','EAP','East Northport','East Northport','NY'),('US','EAQ','Eaton','Eaton','OH'),('US','EAR','Kearney','Kearney','NE'),('US','EAS','Eastover','Eastover','SC'),('US','EAT','Wenatchee','Wenatchee','WA'),('US','EAU','Eau Claire','Eau Claire','WI'),('US','EAV','Eagleville','Eagleville','PA'),('US','EAW','Elma','Elma','WA'),('US','EAY','East Lyme','East Lyme','CT'),('US','EB2','Elburn','Elburn','IL'),('US','EBA','Elba','Elba','AL'),('US','EBB','West Babylon','West Babylon','NY'),('US','EBC','East Bridgeport','East Bridgeport','CT'),('US','EBD','East Bend','East Bend','NC'),('US','EBE','Ebensburg','Ebensburg','PA'),('US','EBG','Eastaboga','Eastaboga','AL'),('US','EBL','East Berlin','East Berlin','PA'),('US','EBN','East Boston','East Boston','MA'),('US','EBQ','East Brookfield','East Brookfield','MA'),('US','EBR','East Brunswick','East Brunswick','NJ'),('US','EBS','Webster City','Webster City','IA'),('US','EBT','East Butler','East Butler','PA'),('US','EBY','East Granby','East Granby','CT'),('US','EC2','Eclectic','Eclectic','AL'),('US','ECA','East Tawas','East Tawas','MI'),('US','ECB','Edgecomb','Edgecomb','ME'),('US','ECC','Ellicott City','Ellicott City','MD'),('US','ECD','Escondido','Escondido','CA'),('US','ECE','Spencerville','Spencerville','OH'),('US','ECG','Elizabeth City','Elizabeth City','NC'),('US','ECH','East Chicago','East Chicago','IN'),('US','ECI','Mechanicsburg, Beaver','Mechanicsburg, Beaver','PA'),('US','ECL','East Clinton','East Clinton','IL'),('US','ECM','East Cambridge','East Cambridge','MA'),('US','ECN','East Camden','East Camden','AR'),('US','ECO','El Centro','El Centro','CA'),('US','ECP','El Campo','El Campo','TX'),('US','ECQ','El Cerrito','El Cerrito','CA'),('US','ECR','Spencer','Spencer','NC'),('US','ECS','Newcastle','Newcastle','WY'),('US','ECT','Pecatonica','Pecatonica','IL'),('US','ECU','White Cloud','White Cloud','KS'),('US','ECV','Ellicottville','Ellicottville','NY'),('US','ECW','Enumclaw','Enumclaw','WA'),('US','ECX','East Concord','East Concord','NY'),('US','ECZ','East Canton','East Canton','OH'),('US','ED2','Eldorado','Eldorado','IL'),('US','EDA','Edna Bay','Edna Bay','AK'),('US','EDB','Eden','Eden','NC'),('US','EDC','Edmonton','Edmonton','KY'),('US','EDD','Edgewood','Edgewood','NJ'),('US','EDE','Edenton','Edenton','NC'),('US','EDF','Edgefield','Edgefield','SC'),('US','EDG','Edgewood','Edgewood','MD'),('US','EDH','Alden','Alden','IA'),('US','EDI','Eden','Eden','ID'),('US','EDJ','El Dorado','El Dorado','CA'),('US','EDK','El Dorado','El Dorado','KS'),('US','EDL','Allendale','Allendale','SC'),('US','EDM','Edina/Minneapolis','Edina/Minneapolis','MN'),('US','EDN','Edison','Edison','NJ'),('US','EDO','East Douglas','East Douglas','MA'),('US','EDP','Eden Prairie','Eden Prairie','MN'),('US','EDQ','Edinburg','Edinburg','TX'),('US','EDR','Eldridge','Eldridge','IA'),('US','EDS','Edison','Edison','CA'),('US','EDT','Eldon','Eldon','TX'),('US','EDU','East Dublin','East Dublin','GA'),('US','EDV','Eddyville','Eddyville','KY'),('US','EDW','Edwardsville','Edwardsville','KS'),('US','EDX','Edcouch','Edcouch','TX'),('US','EDY','Eden','Eden','NY'),('US','EDZ','Edwards','Edwards','CO'),('US','EE2','Erie','Erie','MI'),('US','EE3','East Earl','East Earl','PA'),('US','EE4','Eastanolle','Eastanolle','GA'),('US','EEA','Berea','Berea','OH'),('US','EEB','Bethel, Pitt','Bethel, Pitt','NC'),('US','EEC','Seneca','Seneca','KS'),('US','EED','Needles','Needles','CA'),('US','EEE','Wheeler','Wheeler','MI'),('US','EEF','Greenfield','Greenfield','MN'),('US','EEH','Beech Creek','Beech Creek','PA'),('US','EEI','Emmett','Emmett','ID'),('US','EEK','Eek','Eek','AK'),('US','EEL','Bremen','Bremen','GA'),('US','EEM','Belle Mina','Belle Mina','AL'),('US','EEN','Keene','Keene','NH'),('US','EEO','Greenwood','Greenwood','MO'),('US','EEP','Enterprise, Washington','Enterprise, Washington','UT'),('US','EER','Beaver','Beaver','OR'),('US','EES','Weedsport','Weedsport','NY'),('US','EET','Leetonia','Leetonia','OH'),('US','EEV','Reeseville','Reeseville','WI'),('US','EEW','Englewood','Englewood','TN'),('US','EEX','Essex','Essex','CT'),('US','EEY','Elsberry','Elsberry','MO'),('US','EF2','Eglin Air Force Base','Eglin Air Force Base','FL'),('US','EFB','Eight Fathom Bight','Eight Fathom Bight','AK'),('US','EFD','Eastford','Eastford','CT'),('US','EFF','Seffner','Seffner','FL'),('US','EFG','Everglades City','Everglades City','FL'),('US','EFI','Effingham','Effingham','IL'),('US','EFK','Newport','Newport','VT'),('US','EFL','Enfield','Enfield','NC'),('US','EFN','East Freetown','East Freetown','MA'),('US','EFO','East Fork','East Fork','AK'),('US','EFR','East Farmingdale','East Farmingdale','NY'),('US','EFT','Effort','Effort','PA'),('US','EFW','Jefferson','Jefferson','IA'),('US','EG2','Ewing','Ewing','NE'),('US','EGA','Edgar','Edgar','WI'),('US','EGC','Granby','Granby','CT'),('US','EGD','Edwards','Edwards','MS'),('US','EGE','Elgin','Elgin','SC'),('US','EGF','Eagle Grove','Eagle Grove','IA'),('US','EGG','Egg Harbor City','Egg Harbor City','NJ'),('US','EGH','Effingham','Effingham','SC'),('US','EGK','Elk Grove','Elk Grove','CA'),('US','EGL','Eagle','Eagle','PA'),('US','EGM','Edgemont','Edgemont','PA'),('US','EGN','Elgin','Elgin','IL'),('US','EGO','East Goshen','East Goshen','PA'),('US','EGP','Eagle Pass','Eagle Pass','TX'),('US','EGQ','East Grand Forks','East Grand Forks','MN'),('US','EGR','Eagle Rock','Eagle Rock','CA'),('US','EGS','Emigsville','Emigsville','PA'),('US','EGT','Edgerton','Edgerton','WI'),('US','EGU','Edgemoor','Edgemoor','DE'),('US','EGV','Eagle River','Eagle River','WI'),('US','EGW','Edgewater','Edgewater','NJ'),('US','EGX','Egegik','Egegik','AK'),('US','EGY','East Greenbush','East Greenbush','NY'),('US','EGZ','East Glenville','East Glenville','NY'),('US','EH2','Elmhurst','Elmhurst','NY'),('US','EHA','East Hanover','East Hanover','NJ'),('US','EHE','Bethlehem','Bethlehem','NH'),('US','EHG','Ethridge','Ethridge','TN'),('US','EHI','El Dorado Hills','El Dorado Hills','CA'),('US','EHL','Bethlehem','Bethlehem','GA'),('US','EHM','Cape Newenham','Cape Newenham','AK'),('US','EHN','Easthampton','Easthampton','MA'),('US','EHO','West Harrison','West Harrison','NY'),('US','EHP','Ephrata','Ephrata','PA'),('US','EHS','Cedar Hills','Cedar Hills','UT'),('US','EHT','East Hartford','East Hartford','CT'),('US','EHV','East Haven','East Haven','CT'),('US','EHW','Selah','Selah','WA'),('US','EI3','Elida','Elida','NM'),('US','EIA','Elyria','Elyria','OH'),('US','EID','Eldridge','Eldridge','ND'),('US','EIE','Bernie','Bernie','MO'),('US','EIG','Eight Mile','Eight Mile','AL'),('US','EIH','Eighty Four','Eighty Four','PA'),('US','EIK','Elkins Park','Elkins Park','PA'),('US','EIL','Elsie','Elsie','MI'),('US','EIM','Enigma','Enigma','GA'),('US','EIN','Elkin','Elkin','NC'),('US','EIO','East Norriton','East Norriton','PA'),('US','EIS','Bella Vista','Bella Vista','AR'),('US','EIT','Elliston','Elliston','VA'),('US','EIV','Reedsville','Reedsville','WV'),('US','EIW','Belleview','Belleview','FL'),('US','EIY','Seminary','Seminary','MS'),('US','EIZ','Elizabethville','Elizabethville','PA'),('US','EJA','Egan','Egan','SD'),('US','EJD','East Jordan','East Jordan','MI'),('US','EJW','Edgewater','Edgewater','FL'),('US','EKA','Eureka','Eureka','CA'),('US','EKD','Elkridge','Elkridge','MD'),('US','EKE','Elkview','Elkview','WV'),('US','EKH','Elkhart','Elkhart','IA'),('US','EKI','Elkhart','Elkhart','IN'),('US','EKK','Elkhart Lake','Elkhart Lake','WI'),('US','EKL','Eskdale','Eskdale','WV'),('US','EKM','Elkton','Elkton','MI'),('US','EKN','Elkins','Elkins','WV'),('US','EKO','Elko','Elko','NV'),('US','EKP','Ecorse','Ecorse','MI'),('US','EKR','Elkhorn','Elkhorn','NE'),('US','EKT','Elkton','Elkton','KY'),('US','EKV','Elkton','Elkton','VA'),('US','EKW','Elkwood','Elkwood','VA'),('US','EKX','Elizabethtown','Elizabethtown','KY'),('US','EKZ','Elkton','Elkton','SD'),('US','EL2','Elma, Erie','Elma, Erie','NY'),('US','ELA','Eagle Lake','Eagle Lake','TX'),('US','ELB','Elberton','Elberton','GA'),('US','ELC','Euless','Euless','TX'),('US','ELD','El Dorado','El Dorado','AR'),('US','ELE','Tennille','Tennille','GA'),('US','ELG','Elbridge','Elbridge','NY'),('US','ELH','Elkhorn','Elkhorn','WI'),('US','ELI','Elim','Elim','AK'),('US','ELJ','Ellijay','Ellijay','GA'),('US','ELK','Elk City','Elk City','OK'),('US','ELL','Elwood','Elwood','IN'),('US','ELM','Elmira','Elmira','NY'),('US','ELN','Ellensburg','Ellensburg','WA'),('US','ELO','East Liverpool','East Liverpool','OH'),('US','ELP','El Paso','El Paso','TX'),('US','ELQ','Elkland','Elkland','PA'),('US','ELR','Elmhurst','Elmhurst','IL'),('US','ELS','El Segundo','El Segundo','CA'),('US','ELT','Elkton','Elkton','MD'),('US','ELU','Ellisville','Ellisville','MO'),('US','ELV','Elfin Cove','Elfin Cove','AK'),('US','ELW','Ellamar','Ellamar','AK'),('US','ELY','Ely','Ely','NV'),('US','ELZ','Wellsville','Wellsville','NY'),('US','EM2','Elsmere','Elsmere','DE'),('US','EM3','Edmore','Edmore','MI'),('US','EM6','Elm','Elm','PA'),('US','EM7','East Machias','East Machias','ME'),('US','EMA','Emelle','Emelle','AL'),('US','EMB','Embarcadero/San Francisco','Embarcadero/San Francisco','CA'),('US','EMC','Eldersburg','Eldersburg','MD'),('US','EMD','El Modena/Orange','El Modena/Orange','CA'),('US','EME','Semmes','Semmes','AL'),('US','EMG','Emmetsburg','Emmetsburg','IA'),('US','EMH','Emsworth','Emsworth','PA'),('US','EMI','East Millinocket','East Millinocket','ME'),('US','EMK','Emmonak','Emmonak','AK'),('US','EMM','Kemmerer','Kemmerer','WY'),('US','EMN','East Moline','East Moline','IL'),('US','EMO','Elmore','Elmore','WV'),('US','EMP','Emporia','Emporia','KS'),('US','EMQ','Fremont','Fremont','IA'),('US','EMR','Elmira Heights','Elmira Heights','NY'),('US','EMS','Le Mars','Le Mars','IA'),('US','EMT','El Monte','El Monte','CA'),('US','EMU','Emmaus','Emmaus','PA'),('US','EMW','Elmwood Park','Elmwood Park','IL'),('US','EMX','Emlenton','Emlenton','PA'),('US','EMY','Emery','Emery','SD'),('US','EMZ','El Mirage','El Mirage','AZ'),('US','EN2','Eminence','Eminence','KY'),('US','EN3','English','English','IN'),('US','EN4','Edgerton','Edgerton','MN'),('US','ENA','Kenai','Kenai','AK'),('US','ENB','Edinburgh','Edinburgh','IN'),('US','ENC','Endicott','Endicott','NY'),('US','END','Endeavor','Endeavor','PA'),('US','ENE','Ennis','Ennis','TX'),('US','ENF','Enfield','Enfield','CT'),('US','ENG','Englewood Cliffs','Englewood Cliffs','NJ'),('US','ENH','Chestnut Hill','Chestnut Hill','MA'),('US','ENI','Lenni','Lenni','PA'),('US','ENJ','Ellenton','Ellenton','FL'),('US','ENK','Enka','Enka','NC'),('US','ENL','Centralia','Centralia','IL'),('US','ENM','Enon','Enon','OH'),('US','ENN','Nenana','Nenana','AK'),('US','ENO','Encino','Encino','CA'),('US','ENP','Enterprise','Enterprise','OR'),('US','ENQ','East Norwalk','East Norwalk','CT'),('US','ENR','Glen Arm','Glen Arm','MD'),('US','ENS','Ensley','Ensley','AL'),('US','ENT','Denton','Denton','NC'),('US','ENU','Mendon','Mendon','MO'),('US','ENV','Wendover','Wendover','UT'),('US','ENW','Kenosha','Kenosha','WI'),('US','ENY','Cheney','Cheney','WA'),('US','EOA','Metamora','Metamora','IL'),('US','EOD','Edmond','Edmond','OK'),('US','EOE','Glencoe','Glencoe','IL'),('US','EOG','East Orange','East Orange','NJ'),('US','EOH','Shorter','Shorter','AL'),('US','EOI','Caledonia','Caledonia','MN'),('US','EOK','Keokuk','Keokuk','IA'),('US','EOL','East Alton','East Alton','IL'),('US','EOM','Welcome','Welcome','LA'),('US','EON','Enoree','Enoree','SC'),('US','EOO','El Dorado Springs','El Dorado Springs','MO'),('US','EOR','Elloree','Elloree','SC'),('US','EOS','Neosho','Neosho','MO'),('US','EOT','Edmonston','Edmonston','MD'),('US','EOW','Edmonds','Edmonds','WA'),('US','EOY','Eloy','Eloy','AZ'),('US','EP2','Elka Park','Elka Park','NY'),('US','EP3','Evergreen Park','Evergreen Park','IL'),('US','EP5','East Penn','East Penn','PA'),('US','EP6','Eastpointe','Eastpointe','MI'),('US','EPA','Earl Park','Earl Park','IN'),('US','EPD','East Palo Alto','East Palo Alto','CA'),('US','EPE','Empire','Empire','LA'),('US','EPG','Weeping Water','Weeping Water','NE'),('US','EPH','Ephrata','Ephrata','WA'),('US','EPI','Eastport','Eastport','ID'),('US','EPJ','East Providence','East Providence','RI'),('US','EPK','Eaton Park','Eaton Park','FL'),('US','EPM','Eastport','Eastport','ME'),('US','EPN','East Point','East Point','GA'),('US','EPO','East Peoria','East Peoria','IL'),('US','EPR','East Providence','East Providence','RI'),('US','EPS','Stephenson','Stephenson','MI'),('US','EPT','Export','Export','PA'),('US','EPY','East Point','East Point','KY'),('US','EQA','Cabot','Cabot','AR'),('US','EQE','East Dubuque','East Dubuque','IL'),('US','EQG','East Quogue','East Quogue','NY'),('US','EQO','Elco','Elco','IL'),('US','EQU','Ecru','Ecru','MS'),('US','EQX','Edinburg','Edinburg','VA'),('US','EQZ','Ellport','Ellport','PA'),('US','ER2','Elk River','Elk River','MN'),('US','ER3','Eagle Rock, Botetourt','Eagle Rock, Botetourt','VA'),('US','ERA','Emporia','Emporia','VA'),('US','ERC','East Rochester','East Rochester','NY'),('US','ERD','Elfrida','Elfrida','AZ'),('US','ERE','Earl','Earl','NC'),('US','ERG','Energy','Energy','IL'),('US','ERI','Erie','Erie','PA'),('US','ERK','East Flat Rock','East Flat Rock','NC'),('US','ERL','Erlanger','Erlanger','KY'),('US','ERN','Clermont','Clermont','IA'),('US','ERO','Eldred Rock','Eldred Rock','AK'),('US','ERP','Deer Park','Deer Park','MD'),('US','ERQ','Eagle River','Eagle River','AK'),('US','ERR','Errol','Errol','NH'),('US','ERS','Bernardston','Bernardston','MA'),('US','ERT','Mertzon','Mertzon','TX'),('US','ERU','East Rutherford','East Rutherford','NJ'),('US','ERV','Kerrville','Kerrville','TX'),('US','ERW','Erwin','Erwin','TN'),('US','ERY','Elroy','Elroy','WI'),('US','ERZ','Erie','Erie','IL'),('US','ES2','East Swanzey','East Swanzey','NH'),('US','ES3','Westchester','Westchester','IL'),('US','ESA','East Sparta','East Sparta','OH'),('US','ESB','Estero Bay','Estero Bay','CA'),('US','ESC','Escanaba','Escanaba','MI'),('US','ESD','Eastsound','Eastsound','WA'),('US','ESE','Essex','Essex','MD'),('US','ESF','Alexandria','Alexandria','LA'),('US','ESG','Estero','Estero','FL'),('US','ESH','Ashley','Ashley','IN'),('US','ESI','West Windsor','West Windsor','VT'),('US','ESK','Belews Creek','Belews Creek','NC'),('US','ESL','East Saint Louis','East Saint Louis','IL'),('US','ESM','Esmond','Esmond','RI'),('US','ESN','Easton','Easton','MD'),('US','ESO','Espanola','Espanola','NM'),('US','ESP','East Stroudsburg','East Stroudsburg','PA'),('US','ESR','Ellsworth','Ellsworth','ME'),('US','ESS','Essex Junction','Essex Junction','VT'),('US','EST','Estherville','Estherville','IA'),('US','ESV','Evansville','Evansville','WI'),('US','ESW','Easton','Easton','WA'),('US','ESX','Eddystone','Eddystone','PA'),('US','ESY','East Syracuse','East Syracuse','NY'),('US','ET2','Etna','Etna','WY'),('US','ET3','Etna','Etna','PA'),('US','ETA','East Los Angeles','East Los Angeles','CA'),('US','ETB','West Bend','West Bend','WI'),('US','ETC','Earth City','Earth City','MO'),('US','ETD','East Bernstadt','East Bernstadt','KY'),('US','ETE','West Bend','West Bend','IA'),('US','ETG','Eton','Eton','GA'),('US','ETH','Ether','Ether','NC'),('US','ETI','Centerville','Centerville','UT'),('US','ETJ','Eastchester','Eastchester','NY'),('US','ETK','East Newark','East Newark','NJ'),('US','ETL','East Longmeadow','East Longmeadow','MA'),('US','ETM','Easton','Easton','MA'),('US','ETN','Eastland','Eastland','TX'),('US','ETO','Etowah','Etowah','TN'),('US','ETP','Eaton Rapids','Eaton Rapids','MI'),('US','ETQ','Eaton','Eaton','CO'),('US','ETR','El Toro','El Toro','CA'),('US','ETS','Enterprise','Enterprise','AL'),('US','ETT','Etter','Etter','TX'),('US','ETU','East Taunton','East Taunton','MA'),('US','ETV','Eatonville','Eatonville','WA'),('US','ETW','Edgartown','Edgartown','MA'),('US','ETX','Essington','Essington','PA'),('US','ETY','East Liberty','East Liberty','OH'),('US','EUC','Euclid','Euclid','OH'),('US','EUD','Eudora','Eudora','AR'),('US','EUE','Eureka','Eureka','NV'),('US','EUF','Eufaula','Eufaula','AL'),('US','EUG','Eugene','Eugene','OR'),('US','EUI','Emporium','Emporium','PA'),('US','EUK','Eureka, Perry','Eureka, Perry','MO'),('US','EUL','Eklutna','Eklutna','AK'),('US','EUN','Eugene','Eugene','MO'),('US','EUO','West Union','West Union','OH'),('US','EUP','Eupora','Eupora','MS'),('US','EUR','Eureka, St Louis','Eureka, St Louis','MO'),('US','EUS','Eustis','Eustis','FL'),('US','EV2','Evart','Evart','MI'),('US','EV3','Ellenville','Ellenville','NY'),('US','EVA','Evadale','Evadale','TX'),('US','EVC','Evans City','Evans City','PA'),('US','EVD','Evanston','Evanston','IL'),('US','EVE','Ellisville','Ellisville','MS'),('US','EVF','Edneyville','Edneyville','NC'),('US','EVG','Evans','Evans','GA'),('US','EVI','Elk Grove Village','Elk Grove Village','IL'),('US','EVK','Evansville','Evansville','WV'),('US','EVL','Evendale','Evendale','OH'),('US','EVM','Eveleth','Eveleth','MN'),('US','EVN','Evansville','Evansville','IL'),('US','EVO','Elverson','Elverson','PA'),('US','EVP','Seven Points','Seven Points','TX'),('US','EVR','Evergreen','Evergreen','AL'),('US','EVT','Everett','Everett','MA'),('US','EVV','Evansville','Evansville','IN'),('US','EVW','Evanston','Evanston','WY'),('US','EVY','Beverly','Beverly','WV'),('US','EVZ','Everett','Everett','PA'),('US','EW2','East Woodstock','East Woodstock','CT'),('US','EW3','Elmwood, Pierce','Elmwood, Pierce','WI'),('US','EW4','Englewood','Englewood','NY'),('US','EW5','Edgewood, Suffolk','Edgewood, Suffolk','NY'),('US','EW6','Edgewood','Edgewood','IA'),('US','EWA','Edwards','Edwards','CA'),('US','EWB','Fall River-New Bedford Apt','Fall River-New Bedford Apt','MA'),('US','EWC','Sewickley','Sewickley','PA'),('US','EWD','Englewood','Englewood','NJ'),('US','EWE','Elwell','Elwell','MI'),('US','EWF','Eden','Eden','WI'),('US','EWG','Clearwater','Clearwater','MN'),('US','EWH','Ewa Beach (Oahu)','Ewa Beach (Oahu)','HI'),('US','EWI','Elwood','Elwood','IL'),('US','EWJ','Erwin','Erwin','NC'),('US','EWK','Newton','Newton','KS'),('US','EWN','New Bern','New Bern','NC'),('US','EWO','Bellwood','Bellwood','PA'),('US','EWP','Elmwood Park','Elmwood Park','NJ'),('US','EWQ','Elwood','Elwood','NJ'),('US','EWR','Newark Apt/New York','Newark Apt/New York','NJ'),('US','EWS','East Windsor','East Windsor','NJ'),('US','EWT','Ellsworth','Ellsworth','WA'),('US','EWV','Edwardsville','Edwardsville','IL'),('US','EWW','Elwood','Elwood','KS'),('US','EWY','East Weymouth','East Weymouth','MA'),('US','EXA','Exmore','Exmore','VA'),('US','EXB','Berne','Berne','IN'),('US','EXD','Exeland','Exeland','WI'),('US','EXE','Exeter','Exeter','NH'),('US','EXG','Evergreen','Evergreen','WA'),('US','EXI','Excursion Inlet','Excursion Inlet','AK'),('US','EXN','Exton','Exton','PA'),('US','EXP','Exeter','Exeter','PA'),('US','EXQ','Estacada','Estacada','OR'),('US','EXR','Exeter','Exeter','RI'),('US','EXT','Exeter','Exeter','CA'),('US','EXW','Elmwood','Elmwood','IL'),('US','EYB','Early Branch','Early Branch','SC'),('US','EYF','Piney Flats','Piney Flats','TN'),('US','EYO','Kenyon','Kenyon','MN'),('US','EYP','Eynon','Eynon','PA'),('US','EYR','Yerington','Yerington','NV'),('US','EYV','Eddyville','Eddyville','IA'),('US','EYW','Key West','Key West','FL'),('US','EZA','Elizabeth','Elizabeth','NJ'),('US','EZB','Elizabethton','Elizabethton','TN'),('US','EZG','Eastman','Eastman','GA'),('US','EZH','Elizabeth','Elizabeth','IN'),('US','EZI','Ellsinore','Ellsinore','MO'),('US','EZO','Esparto','Esparto','CA'),('US','EZR','El Sereno','El Sereno','CA'),('US','EZT','Elizabethtown','Elizabethtown','PA'),('US','EZV','East Danville','East Danville','VA'),('US','EZW','Elizabethtown','Elizabethtown','NC'),('US','FA2','Felda','Felda','FL'),('US','FAA','Fair Haven','Fair Haven','VT'),('US','FAB','Fabens','Fabens','TX'),('US','FAC','Falls Church','Falls Church','VA'),('US','FAD','Fairfield','Fairfield','IL'),('US','FAE','Fairfield','Fairfield','TN'),('US','FAF','Fort Eustis','Fort Eustis','VA'),('US','FAG','Fairgrove','Fairgrove','MI'),('US','FAH','Fairless Hills','Fairless Hills','PA'),('US','FAI','Fairbanks','Fairbanks','AK'),('US','FAJ','Fairland','Fairland','OK'),('US','FAK','False Island','False Island','AK'),('US','FAL','Roma','Roma','TX'),('US','FAM','Farmington','Farmington','MO'),('US','FAN','Fairmont','Fairmont','NC'),('US','FAO','Fairfield','Fairfield','OH'),('US','FAP','Farrell','Farrell','PA'),('US','FAQ','Faulkner','Faulkner','MD'),('US','FAR','Fargo','Fargo','ND'),('US','FAS','Fallsington','Fallsington','PA'),('US','FAT','Fresno','Fresno','CA'),('US','FAU','Franklin Furnace','Franklin Furnace','OH'),('US','FAV','Fall River','Fall River','MA'),('US','FAW','Farwell','Farwell','TX'),('US','FAX','Fairfield','Fairfield','TX'),('US','FAY','Fayetteville','Fayetteville','NC'),('US','FAZ','Fall River','Fall River','WI'),('US','FBA','Fairborn','Fairborn','OH'),('US','FBG','Fort Bragg','Fort Bragg','NC'),('US','FBL','Faribault','Faribault','MN'),('US','FBM','Fraziers Bottom','Fraziers Bottom','WV'),('US','FBN','Fairburn','Fairburn','GA'),('US','FBR','Fort Bridger','Fort Bridger','WY'),('US','FBS','Fairchild Air Force Base','Fairchild Air Force Base','WA'),('US','FBX','Farmers Branch','Farmers Branch','TX'),('US','FBY','Fairbury','Fairbury','NE'),('US','FCA','Kalispell','Kalispell','MT'),('US','FCB','Frisco City','Frisco City','AL'),('US','FCC','Forest City','Forest City','IL'),('US','FCD','Candler','Candler','FL'),('US','FCE','Florence','Florence','WI'),('US','FCH','Fitchville','Fitchville','CT'),('US','FCI','Foster City','Foster City','CA'),('US','FCK','Frisco','Frisco','PA'),('US','FCL','Florence','Florence','CA'),('US','FCM','Fort Campbell','Fort Campbell','KY'),('US','FCN','Forest City','Forest City','NC'),('US','FCO','Fort Covington','Fort Covington','NY'),('US','FCP','French Camp','French Camp','CA'),('US','FCR','Fancher','Fancher','NY'),('US','FCT','Ford City','Ford City','PA'),('US','FCV','Francesville','Francesville','IN'),('US','FCW','Fredericktown','Fredericktown','OH'),('US','FCY','Forrest City','Forrest City','AR'),('US','FDA','Ferdinand','Ferdinand','IN'),('US','FDB','Fredericksburg','Fredericksburg','VA'),('US','FDC','Fordyce','Fordyce','AR'),('US','FDD','Floydada','Floydada','TX'),('US','FDH','Friendship','Friendship','WI'),('US','FDI','Crawfordville','Crawfordville','GA'),('US','FDJ','Fieldsboro','Fieldsboro','NJ'),('US','FDK','Frederick','Frederick','MD'),('US','FDL','Federalsburg','Federalsburg','MD'),('US','FDN','Fairland','Fairland','IN'),('US','FDO','Fredonia','Fredonia','AR'),('US','FDR','Frederick','Frederick','OK'),('US','FDT','Ferndale','Ferndale','WA'),('US','FDU','Fridley','Fridley','MN'),('US','FDW','Federal Way','Federal Way','WA'),('US','FDY','Findlay','Findlay','OH'),('US','FDZ','Flanders','Flanders','NJ'),('US','FEA','Feasterville','Feasterville','PA'),('US','FEB','Fernandina Beach','Fernandina Beach','FL'),('US','FEC','Frontenac','Frontenac','MO'),('US','FED','Fredericktown','Fredericktown','MO'),('US','FEE','Ferndale','Ferndale','MI'),('US','FEH','Freehold','Freehold','NJ'),('US','FEI','Ferris','Ferris','TX'),('US','FEK','Felt','Felt','OK'),('US','FEL','Fellsmere','Fellsmere','FL'),('US','FEM','Fremont','Fremont','MI'),('US','FEN','Freeland','Freeland','MI'),('US','FEO','Fredonia','Fredonia','NY'),('US','FEP','Freeport','Freeport','IL'),('US','FER','Ferrysburg','Ferrysburg','MI'),('US','FES','Forest Hill','Forest Hill','MD'),('US','FET','Fremont','Fremont','NE'),('US','FEV','Friendsville','Friendsville','MD'),('US','FEW','Fairview','Fairview','TN'),('US','FF2','Fairfax','Fairfax','MN'),('US','FFA','Kill Devil Hills','Kill Devil Hills','NC'),('US','FFB','Fairfield','Fairfield','AL'),('US','FFD','Frankford','Frankford','PA'),('US','FFE','Fairfield','Fairfield','WA'),('US','FFF','Fort Fairfield','Fort Fairfield','ME'),('US','FFI','Fairfield','Fairfield','CT'),('US','FFL','Fairfield','Fairfield','IA'),('US','FFM','Fergus Falls','Fergus Falls','MN'),('US','FFO','Buffalo','Buffalo','WV'),('US','FFR','Fairforest','Fairforest','SC'),('US','FFS','Fife','Fife','WA'),('US','FFT','Frankfort','Frankfort','KY'),('US','FFX','Fairfax','Fairfax','AL'),('US','FFY','Fairfield','Fairfield','NY'),('US','FGA','Fort George G Meade','Fort George G Meade','MD'),('US','FGD','Fredonia','Fredonia','KY'),('US','FGH','Feeding Hills','Feeding Hills','MA'),('US','FGM','Frogmore','Frogmore','SC'),('US','FGV','Forest Grove','Forest Grove','OR'),('US','FH2','Fair Haven','Fair Haven','NJ'),('US','FHA','Fulshear','Fulshear','TX'),('US','FHE','Fletcher','Fletcher','NC'),('US','FHH','Foothill Farms','Foothill Farms','CA'),('US','FHI','Farmington Hills','Farmington Hills','MI'),('US','FHL','Forest Hills/Queens/New York','Forest Hills/Queens/New York','NY'),('US','FHM','Framingham','Framingham','MA'),('US','FHN','Frohna','Frohna','MO'),('US','FHO','Fort Hood','Fort Hood','TX'),('US','FHP','Fair Hill','Fair Hill','PA'),('US','FHQ','Firth','Firth','ID'),('US','FHS','Far Hills','Far Hills','NJ'),('US','FHU','Fort Huachuca-Sierra Vista Apt','Fort Huachuca-Sierra Vista Apt','AZ'),('US','FHV','Fishersville','Fishersville','VA'),('US','FIA','Fairdale','Fairdale','KY'),('US','FIC','Fire Cove','Fire Cove','AK'),('US','FID','Fishers Island','Fishers Island','NY'),('US','FIE','Fieldale','Fieldale','VA'),('US','FIF','Fyffe','Fyffe','AL'),('US','FIG','Farmington','Farmington','MN'),('US','FIH','Fairview Heights','Fairview Heights','IL'),('US','FII','Filer','Filer','ID'),('US','FIK','Fishkill','Fishkill','NY'),('US','FIL','Fillmore','Fillmore','UT'),('US','FIM','Fillmore','Fillmore','CA'),('US','FIN','Franklin','Franklin','WV'),('US','FIP','Five Points','Five Points','CA'),('US','FIQ','Fernwood','Fernwood','MS'),('US','FIR','Firebaugh','Firebaugh','CA'),('US','FIS','Fountain Inn','Fountain Inn','SC'),('US','FIT','Fitchburg','Fitchburg','MA'),('US','FIV','Five Finger','Five Finger','AK'),('US','FIW','Friendswood','Friendswood','TX'),('US','FIX','Frisco','Frisco','TX'),('US','FJ2','Fort Jones, Siskiyou','Fort Jones, Siskiyou','CA'),('US','FJF','Highland','Highland','KS'),('US','FJK','Frankfort','Frankfort','IL'),('US','FK2','Frederick','Frederick','CO'),('US','FKA','Franklin','Franklin','IN'),('US','FKI','Franklin','Franklin','NH'),('US','FKL','Franklin','Franklin','PA'),('US','FKM','Frankenmuth','Frankenmuth','MI'),('US','FKN','Franklin','Franklin','VA'),('US','FKO','Faulkton','Faulkton','SD'),('US','FKR','Frankfort','Frankfort','NY'),('US','FKT','Fort Kent','Fort Kent','ME'),('US','FKU','Fork Union','Fork Union','VA'),('US','FKV','Falkville','Falkville','AL'),('US','FKW','Fredericktown','Fredericktown','PA'),('US','FKX','Fredericksburg','Fredericksburg','IA'),('US','FKY','Florence','Florence','KY'),('US','FL2','Fallston','Fallston','MD'),('US','FL3','Fairlawn','Fairlawn','OH'),('US','FLA','Fairfield','Fairfield','NJ'),('US','FLB','Flowery Branch','Flowery Branch','GA'),('US','FLD','Fond du Lac','Fond du Lac','WI'),('US','FLE','Flemington','Flemington','NJ'),('US','FLF','Flatrock','Flatrock','MI'),('US','FLG','Flagstaff','Flagstaff','AZ'),('US','FLH','Franklin','Franklin','OH'),('US','FLI','Franklin Park','Franklin Park','IL'),('US','FLJ','Falls Bay','Falls Bay','AK'),('US','FLK','Franklin','Franklin','KY'),('US','FLL','Fort Lauderdale','Fort Lauderdale','FL'),('US','FLM','Florence','Florence','MA'),('US','FLN','Franklin','Franklin','MA'),('US','FLO','Florence','Florence','SC'),('US','FLP','Floral Park','Floral Park','NY'),('US','FLQ','Sledge','Sledge','MS'),('US','FLR','Florence','Florence','NJ'),('US','FLS','Foley','Foley','FL'),('US','FLT','Flat','Flat','AK'),('US','FLU','Flushing Apt/New York','Flushing Apt/New York','NY'),('US','FLV','Fort Leavenworth','Fort Leavenworth','KS'),('US','FLW','Franklin','Franklin','WI'),('US','FLX','Florence','Florence','TX'),('US','FLY','Fair Lawn','Fair Lawn','NJ'),('US','FLZ','Florence','Florence','CO'),('US','FM3','Folsom','Folsom','NJ'),('US','FMA','Fort McCoy','Fort McCoy','FL'),('US','FMB','Flemingsburg','Flemingsburg','KY'),('US','FMC','Five Mile','Five Mile','AK'),('US','FME','Fort Meade','Fort Meade','MD'),('US','FMF','Farmington','Farmington','CT'),('US','FMG','Fort Morgan','Fort Morgan','CO'),('US','FMH','Falmouth','Falmouth','MA'),('US','FMI','Farmington','Farmington','MI'),('US','FMJ','Farmingdale','Farmingdale','NJ'),('US','FMK','Fairmount','Fairmount','ND'),('US','FML','Fort Mill','Fort Mill','SC'),('US','FMN','Farmington','Farmington','NM'),('US','FMO','Fillmore','Fillmore','NY'),('US','FMQ','Farmington','Farmington','ME'),('US','FMS','Fort Madison','Fort Madison','IA'),('US','FMT','Fremont','Fremont','IN'),('US','FMU','Fairmount','Fairmount','GA'),('US','FMV','Farmville','Farmville','VA'),('US','FMW','Fairmont, Will','Fairmont, Will','IL'),('US','FMY','Fort Myers','Fort Myers','FL'),('US','FNA','Farnam','Farnam','NE'),('US','FNC','Fremont','Fremont','CA'),('US','FND','Friendly','Friendly','WV'),('US','FNE','Florence','Florence','AL'),('US','FNI','Floyds Knobs','Floyds Knobs','IN'),('US','FNK','Fink Creek','Fink Creek','AK'),('US','FNL','Fort Collins','Fort Collins','CO'),('US','FNM','Fenton','Fenton','MO'),('US','FNN','Franklin','Franklin','NJ'),('US','FNO','Fenton','Fenton','MI'),('US','FNR','Funter Bay','Funter Bay','AK'),('US','FNT','Flint','Flint','MI'),('US','FNV','Friendsville','Friendsville','TN'),('US','FNW','Falling Waters','Falling Waters','WV'),('US','FNX','Forney','Forney','TX'),('US','FNY','Fountain City','Fountain City','IN'),('US','FOA','Florida','Florida','NY'),('US','FOB','Fort Bragg','Fort Bragg','CA'),('US','FOC','Port Fourchon','Port Fourchon','LA'),('US','FOD','Fort Dodge','Fort Dodge','IA'),('US','FOE','Forestville','Forestville','CT'),('US','FOG','Fogelsville','Fogelsville','PA'),('US','FOH','Foothill Ranch','Foothill Ranch','CA'),('US','FOI','Flora','Flora','IN'),('US','FOJ','Folsom','Folsom','LA'),('US','FOK','Westhampton','Westhampton','NY'),('US','FOL','Fort Lee','Fort Lee','NJ'),('US','FOM','Flora','Flora','MS'),('US','FON','Folkston','Folkston','GA'),('US','FOO','Follansbee','Follansbee','WV'),('US','FOP','Forest Park','Forest Park','GA'),('US','FOR','Fallbrook','Fallbrook','CA'),('US','FOS','Fair Oaks','Fair Oaks','CA'),('US','FOT','Florissant','Florissant','MO'),('US','FOU','Folsom','Folsom','CA'),('US','FOV','Forty Fort','Forty Fort','PA'),('US','FOW','Fowler','Fowler','CA'),('US','FOX','Fox','Fox','AK'),('US','FOY','Fonda','Fonda','NY'),('US','FOZ','Fox River Grove','Fox River Grove','IL'),('US','FP2','Florham Park','Florham Park','NJ'),('US','FPA','Forest Park','Forest Park','IL'),('US','FPI','Fort Pierre','Fort Pierre','SD'),('US','FPJ','Fremont Junction','Fremont Junction','UT'),('US','FPN','Fort Payne','Fort Payne','AL'),('US','FPO','Freeport','Freeport','TX'),('US','FPP','Flippin','Flippin','AR'),('US','FPR','Fort Pierce','Fort Pierce','FL'),('US','FPT','Fairport Harbor Village','Fairport Harbor Village','OH'),('US','FPY','Perry','Perry','FL'),('US','FQA','Bloomfield','Bloomfield','MI'),('US','FQD','Freeland','Freeland','PA'),('US','FQE','Florence','Florence','OR'),('US','FQL','Franklin','Franklin','NC'),('US','FQN','Fresno','Fresno','OH'),('US','FQP','Frank','Frank','PA'),('US','FQR','Frank','Frank','WV'),('US','FQS','Fresno','Fresno','TX'),('US','FQT','Fayette','Fayette','IA'),('US','FQV','Franklinville','Franklinville','NJ'),('US','FQZ','Falmouth','Falmouth','KY'),('US','FR2','Far Rockaway, Queens','Far Rockaway, Queens','NY'),('US','FR3','Fort Rucker','Fort Rucker','AL'),('US','FRA','Franklinville','Franklinville','NC'),('US','FRB','Forreston','Forreston','IL'),('US','FRD','Friday Harbor','Friday Harbor','WA'),('US','FRE','Fairview','Fairview','NJ'),('US','FRF','Friendship','Friendship','NC'),('US','FRG','Farmingdale','Farmingdale','NY'),('US','FRH','French Lick','French Lick','IN'),('US','FRI','Fort Riley','Fort Riley','KS'),('US','FRJ','Friant','Friant','CA'),('US','FRK','Frankfort Springs','Frankfort Springs','PA'),('US','FRL','Franklin Lakes','Franklin Lakes','NJ'),('US','FRM','Fairmont','Fairmont','MN'),('US','FRN','Fort Richardson','Fort Richardson','AK'),('US','FRO','Frontier','Frontier','WA'),('US','FRP','Fresh Water Bay','Fresh Water Bay','AK'),('US','FRQ','Frankfort','Frankfort','IN'),('US','FRR','Front Royal','Front Royal','VA'),('US','FRS','Forrest City','Forrest City','AR'),('US','FRT','Fortuna','Fortuna','ND'),('US','FRU','Frostproof','Frostproof','FL'),('US','FRV','Farmville','Farmville','NC'),('US','FRW','Fredericksburg','Fredericksburg','PA'),('US','FRX','Freeport','Freeport','NY'),('US','FRY','Fryeburg','Fryeburg','ME'),('US','FRZ','Frazer','Frazer','PA'),('US','FS2','Fallston','Fallston','NC'),('US','FS3','Freestone, Sonoma','Freestone, Sonoma',''),('US','FSA','Franconia','Franconia','PA'),('US','FSC','Frisco','Frisco','CO'),('US','FSD','Sioux Falls','Sioux Falls','SD'),('US','FSF','Summerfield','Summerfield','FL'),('US','FSG','Flushing/Queens/New York','Flushing/Queens/New York','NY'),('US','FSH','Fishers','Fishers','IN'),('US','FSI','Fort Sill','Fort Sill','OK'),('US','FSK','Fort Scott','Fort Scott','KS'),('US','FSL','Forest Lake','Forest Lake','MN'),('US','FSM','Fort Smith','Fort Smith','AR'),('US','FSN','Fort Sheridan','Fort Sheridan','IL'),('US','FSO','Fostoria','Fostoria','OH'),('US','FSQ','Forest Dale','Forest Dale','VT'),('US','FSR','Franklin Square','Franklin Square','NY'),('US','FSS','Fosston','Fosston','MN'),('US','FST','Fort Stockton','Fort Stockton','TX'),('US','FSU','Fort Sumner','Fort Sumner','NM'),('US','FSV','Fordsville','Fordsville','KY'),('US','FSY','Falls City','Falls City','NE'),('US','FSZ','Frost','Frost','TX'),('US','FTB','Fulton','Fulton','KY'),('US','FTC','Fort Calhoun','Fort Calhoun','NE'),('US','FTD','Fultondale','Fultondale','AL'),('US','FTE','Fort Edward','Fort Edward','NY'),('US','FTG','Fort Gaines','Fort Gaines','GA'),('US','FTH','Fort Branch','Fort Branch','IN'),('US','FTI','Forest','Forest','MS'),('US','FTJ','Frackville','Frackville','PA'),('US','FTK','Fort Knox','Fort Knox','KY'),('US','FTL','Fortuna Ledge','Fortuna Ledge','AK'),('US','FTM','Fort Monmouth','Fort Monmouth','NJ'),('US','FTN','Franklinton','Franklinton','NC'),('US','FTO','Flagtown','Flagtown','NJ'),('US','FTP','Flatonia','Flatonia','TX'),('US','FTQ','Fortuna','Fortuna','CA'),('US','FTR','Fentress','Fentress','VA'),('US','FTS','Fort Gibson','Fort Gibson','OK'),('US','FTT','Fort Oglethorpe','Fort Oglethorpe','GA'),('US','FTV','Fort Valley','Fort Valley','GA'),('US','FTW','Forest View','Forest View','IL'),('US','FTX','Friona','Friona','TX'),('US','FTY','Filer City','Filer City','MI'),('US','FTZ','Fulton','Fulton','MS'),('US','FUA','Falmouth','Falmouth','ME'),('US','FUD','Fulda','Fulda','IN'),('US','FUH','Flushing','Flushing','MI'),('US','FUI','Fruithurst','Fruithurst','AL'),('US','FUL','Fullerton','Fullerton','CA'),('US','FUN','Fulton','Fulton','NY'),('US','FUO','Belle Fourche','Belle Fourche','SD'),('US','FUS','Festus','Festus','MO'),('US','FUT','Fulton','Fulton','MO'),('US','FUV','Fuquay-Varina','Fuquay-Varina','NC'),('US','FVC','Fountain Valley','Fountain Valley','CA'),('US','FVE','Fairview','Fairview','PA'),('US','FVF','Farmerville','Farmerville','LA'),('US','FVH','Fairhaven','Fairhaven','MA'),('US','FVI','Fairview','Fairview','OR'),('US','FVL','Forestville','Forestville','MD'),('US','FVR','Fort Recovery','Fort Recovery','OH'),('US','FVW','Franksville','Franksville','WI'),('US','FW2','Floodwood','Floodwood','MN'),('US','FW3','Fairwater','Fairwater','WI'),('US','FWA','Fort Wayne','Fort Wayne','IN'),('US','FWB','Fort Walton Beach','Fort Walton Beach','FL'),('US','FWD','Flowood','Flowood','MS'),('US','FWE','Fernwood','Fernwood','ID'),('US','FWG','Fort Wingate','Fort Wingate','NM'),('US','FWH','Wheatfield','Wheatfield','IN'),('US','FWI','Fowler','Fowler','IN'),('US','FWJ','Fanwood','Fanwood','NJ'),('US','FWL','Farewell','Farewell','AK'),('US','FWN','Fort Lawn','Fort Lawn','SC'),('US','FWP','Fleetwood','Fleetwood','PA'),('US','FWR','Fort Wright','Fort Wright','KY'),('US','FWS','Webster','Webster','FL'),('US','FWT','Fort Worth','Fort Worth','TX'),('US','FWY','Fort Washington','Fort Washington','MD'),('US','FXB','Foxboro','Foxboro','MA'),('US','FXC','Foxcroft','Foxcroft','PA'),('US','FXG','Fredericksburg','Fredericksburg','TX'),('US','FXM','Flaxman Island','Flaxman Island','AK'),('US','FXN','Fallon','Fallon','CA'),('US','FXO','Fairfax, Hamilton','Fairfax, Hamilton','OH'),('US','FXP','Fox Point','Fox Point','WI'),('US','FXX','Fairfax','Fairfax','VA'),('US','FXY','Forest City','Forest City','IA'),('US','FY4','Farley','Farley','IA'),('US','FYA','Fairfax','Fairfax','SC'),('US','FYB','Folly Beach','Folly Beach','SC'),('US','FYC','Five Corners','Five Corners','WA'),('US','FYD','Felida','Felida','WA'),('US','FYE','Fayetteville','Fayetteville','GA'),('US','FYH','Forsyth','Forsyth','IL'),('US','FYM','Fayetteville','Fayetteville','TN'),('US','FYN','Fountain','Fountain','CO'),('US','FYR','Fernley','Fernley','NV'),('US','FYT','Fayette','Fayette','AL'),('US','FYU','Fort Yukon','Fort Yukon','AK'),('US','FYV','Fayetteville','Fayetteville','AR'),('US','FZC','Forest City','Forest City','PA'),('US','FZG','Fitzgerald','Fitzgerald','GA'),('US','FZH','Frostburg','Frostburg','MD'),('US','FZO','Faison','Faison','NC'),('US','FZR','Fisher','Fisher','WA'),('US','FZW','Fitzwilliam','Fitzwilliam','NH'),('US','FZY','Fraser','Fraser','NY'),('US','FZZ','Freedom','Freedom','PA'),('US','GA2','Galena','Galena','KS'),('US','GAA','Graham','Graham','GA'),('US','GAB','Gabbs','Gabbs','NV'),('US','GAC','Gardena','Gardena','CA'),('US','GAD','Gadsden','Gadsden','AL'),('US','GAE','Garrattsville','Garrattsville','NY'),('US','GAF','Garfield','Garfield','NJ'),('US','GAG','Gage','Gage','OK'),('US','GAH','Gahanna','Gahanna','OH'),('US','GAI','Gaithersburg','Gaithersburg','MD'),('US','GAJ','Bagley','Bagley','MN'),('US','GAK','Gakona','Gakona','AK'),('US','GAL','Galena','Galena','AK'),('US','GAM','Gambell','Gambell','AK'),('US','GAN','Gallatin','Gallatin','TN'),('US','GAO','Grafton','Grafton','WV'),('US','GAP','Gallipolis','Gallipolis','OH'),('US','GAQ','Galt','Galt','CA'),('US','GAR','Garden City','Garden City','NJ'),('US','GAS','Granite Shoals','Granite Shoals','TX'),('US','GAT','Gaston','Gaston','SC'),('US','GAV','Gassville','Gassville','AR'),('US','GAW','Glendale','Glendale','MD'),('US','GAX','Garrison','Garrison','MD'),('US','GAY','Gaylord','Gaylord','MN'),('US','GAZ','Gratz','Gratz','PA'),('US','GB2','Greensburg','Greensburg','KS'),('US','GB3','Groesbeck','Groesbeck','TX'),('US','GBA','Globe','Globe','AZ'),('US','GBB','Gibbsboro','Gibbsboro','NJ'),('US','GBC','Gibson City','Gibson City','IL'),('US','GBD','Great Bend','Great Bend','KS'),('US','GBE','Gilbert','Gilbert','AZ'),('US','GBG','Galesburg','Galesburg','IL'),('US','GBH','Galbraith Lake','Galbraith Lake','AK'),('US','GBI','Greenbrier, Robertson','Greenbrier, Robertson','TN'),('US','GBK','Green Brook','Green Brook','NJ'),('US','GBL','Braselton','Braselton','GA'),('US','GBM','Glen Burnie','Glen Burnie','MD'),('US','GBN','Gila Bend','Gila Bend','AZ'),('US','GBO','Greensboro','Greensboro','NC'),('US','GBR','Great Barrington','Great Barrington','MA'),('US','GBS','Greensboro','Greensboro','AL'),('US','GBT','Gainesboro','Gainesboro','TN'),('US','GBU','Grantsburg','Grantsburg','WI'),('US','GBV','Garberville','Garberville','CA'),('US','GBY','Granbury','Granbury','TX'),('US','GBZ','Gulf Breeze','Gulf Breeze','FL'),('US','GC2','Glencoe','Glencoe','AL'),('US','GCA','Golconda','Golconda','NV'),('US','GCC','Gillette','Gillette','WY'),('US','GCD','Glen Allen','Glen Allen','MD'),('US','GCE','Grace','Grace','SC'),('US','GCG','Garden City','Garden City','GA'),('US','GCH','Gerlach','Gerlach','NV'),('US','GCI','Gas City','Gas City','IN'),('US','GCK','Garden City','Garden City','KS'),('US','GCL','Coolidge','Coolidge','GA'),('US','GCM','Garden City','Garden City','MO'),('US','GCN','Grand Canyon','Grand Canyon','AZ'),('US','GCO','Grand Coulee','Grand Coulee','WA'),('US','GCP','Green Springs','Green Springs','OH'),('US','GCQ','Garden City','Garden City','MI'),('US','GCR','Greenacres','Greenacres','FL'),('US','GCS','Green Cove Springs','Green Cove Springs','FL'),('US','GCT','Gilcrest','Gilcrest','CO'),('US','GCU','Grand Chute','Grand Chute','WI'),('US','GCV','Graceville','Graceville','FL'),('US','GCY','Greenville','Greenville','TN'),('US','GCZ','Glencoe','Glencoe','MN'),('US','GD2','Ganado','Ganado','AZ'),('US','GD3','Glendale','Glendale','UT'),('US','GD4','Girard','Girard','KS'),('US','GDA','Glendale','Glendale','AZ'),('US','GDB','Grand Bay','Grand Bay','AL'),('US','GDC','Garden City','Garden City','MN'),('US','GDD','Giddings','Giddings','TX'),('US','GDE','Gladstone','Gladstone','MI'),('US','GDF','Godfrey','Godfrey','IL'),('US','GDG','Grand Ledge','Grand Ledge','MI'),('US','GDH','Golden Horn','Golden Horn','AK'),('US','GDI','Grandville','Grandville','MI'),('US','GDJ','Guildhall','Guildhall','VT'),('US','GDL','Glendale','Glendale','NY'),('US','GDM','Gardner','Gardner','MA'),('US','GDN','Gardiner','Gardiner','ME'),('US','GDO','Golden','Golden','MS'),('US','GDP','Grand Prairie','Grand Prairie','TX'),('US','GDQ','Glendora','Glendora','CA'),('US','GDR','Gardiner','Gardiner','OR'),('US','GDS','Gladstone','Gladstone','MO'),('US','GDT','Goodlettsville','Goodlettsville','TN'),('US','GDV','Glendive','Glendive','MT'),('US','GDW','Gladwin','Gladwin','MI'),('US','GDY','Gardner','Gardner','PA'),('US','GDZ','Gardner','Gardner','KS'),('US','GEA','Germantown','Germantown','IL'),('US','GEB','Greenboro','Greenboro','NY'),('US','GEC','Garden City','Garden City','TX'),('US','GED','Georgetown','Georgetown','DE'),('US','GEE','Glendale','Glendale','WI'),('US','GEF','Glenford','Glenford','OH'),('US','GEG','Spokane','Spokane','WA'),('US','GEH','McGehee','McGehee','AR'),('US','GEI','Greenfield','Greenfield','TN'),('US','GEK','Ganes Creek','Ganes Creek','AK'),('US','GEL','Glen Ellyn','Glen Ellyn','IL'),('US','GEM','Glenmoore','Glenmoore','PA'),('US','GEN','Geneva','Geneva','NY'),('US','GEO','Georgetown','Georgetown','KY'),('US','GEQ','Georgetown','Georgetown','FL'),('US','GER','Georgetown','Georgetown','GA'),('US','GES','Geneseo','Geneseo','NY'),('US','GET','Gravette','Gravette','AR'),('US','GEU','Glen Allen','Glen Allen','VA'),('US','GEV','Geneva','Geneva','NE'),('US','GEW','Georgetown','Georgetown','WA'),('US','GEY','Greybull','Greybull','WY'),('US','GEZ','Gilbertville','Gilbertville','MA'),('US','GF2','Gilford','Gilford','ME'),('US','GF3','Guilford','Guilford','CT'),('US','GF4','Goodfield','Goodfield','IL'),('US','GFA','Granite Falls','Granite Falls','NC'),('US','GFB','Togiak Fish','Togiak Fish','AK'),('US','GFC','Greenfield','Greenfield','CA'),('US','GFD','Greenfield','Greenfield','IN'),('US','GFE','Gallipolis Ferry','Gallipolis Ferry','WV'),('US','GFH','Greenfield','Greenfield','MO'),('US','GFI','Griffin','Griffin','TX'),('US','GFK','Grand Forks','Grand Forks','ND'),('US','GFL','Glens Falls','Glens Falls','NY'),('US','GFN','Grafton','Grafton','WI'),('US','GFO','Grafton','Grafton','OH'),('US','GFP','Gulfport','Gulfport','FL'),('US','GFQ','Grove','Grove','OK'),('US','GFR','Garfield','Garfield','NY'),('US','GFS','Granite Falls','Granite Falls','WA'),('US','GFT','Grafton','Grafton','ND'),('US','GFV','Grandview','Grandview','WA'),('US','GFW','Goffstown','Goffstown','NH'),('US','GFY','Glenns Ferry','Glenns Ferry','ID'),('US','GG2','Gallatin Gateway','Gallatin Gateway','MT'),('US','GG3','Georgia','Georgia','AL'),('US','GG4','Georgiana','Georgiana','AL'),('US','GGA','Georgia','Georgia','VT'),('US','GGE','Georgetown','Georgetown','SC'),('US','GGG','Gladewater-Longview-Kilgore Apt','Gladewater-Longview-Kilgore Apt','TX'),('US','GGH','Greenville','Greenville','OH'),('US','GGI','Wiggins','Wiggins','MS'),('US','GGL','La Grange','La Grange','NC'),('US','GGM','Morgan','Morgan','UT'),('US','GGN','Georgetown, Fairfield','Georgetown, Fairfield','CT'),('US','GGO','Gouldsboro','Gouldsboro','PA'),('US','GGP','Goodman','Goodman','WI'),('US','GGR','Garden Grove','Garden Grove','CA'),('US','GGS','Glasgow','Glasgow','MO'),('US','GGV','Greenville','Greenville','NH'),('US','GGW','Glasgow','Glasgow','DE'),('US','GGZ','Gig Harbor','Gig Harbor','WA'),('US','GHA','Gorham','Gorham','NH'),('US','GHC','Grays Harbor City','Grays Harbor City','WA'),('US','GHE','Ghent','Ghent','KY'),('US','GHH','Gorham','Gorham','ME'),('US','GHI','Glendale Hghts','Glendale Hghts','IL'),('US','GHJ','Overton, Clark','Overton, Clark','NV'),('US','GHK','Schaghticoke','Schaghticoke','NY'),('US','GHL','Granada Hills','Granada Hills','CA'),('US','GHM','Centerville','Centerville','TN'),('US','GHN','Grand Haven','Grand Haven','MI'),('US','GHO','Gresham','Gresham','OR'),('US','GHP','Glen Hope','Glen Hope','PA'),('US','GHQ','Graehl','Graehl','AK'),('US','GHR','Aberdeen','Aberdeen','WA'),('US','GHS','Goshen','Goshen','CA'),('US','GHT','Graham','Graham','TX'),('US','GHZ','Garfield Heights','Garfield Heights','OH'),('US','GIA','Greenfield','Greenfield','IA'),('US','GIB','Gibbstown','Gibbstown','NJ'),('US','GIC','Gilbert','Gilbert','SC'),('US','GID','Gideon','Gideon','MO'),('US','GIE','Greenville','Greenville','WI'),('US','GIF','Winter Haven','Winter Haven','FL'),('US','GIG','Guild','Guild','TN'),('US','GIH','Goodrich','Goodrich','MI'),('US','GII','Gainesville','Gainesville','VA'),('US','GIJ','Grand Isle','Grand Isle','LA'),('US','GIL','Gillette','Gillette','NJ'),('US','GIM','Green Isle','Green Isle','MN'),('US','GIN','Gilman','Gilman','CT'),('US','GIO','Gilmore City','Gilmore City','IA'),('US','GIR','Gilroy','Gilroy','CA'),('US','GIS','Gibsonburg','Gibsonburg','OH'),('US','GIT','Gibraltar','Gibraltar','MI'),('US','GIV','Grain Valley','Grain Valley','MO'),('US','GIW','Grinnell','Grinnell','IA'),('US','GIX','Gilmer','Gilmer','TX'),('US','GIY','Gainesville','Gainesville','MO'),('US','GIZ','Gibson','Gibson','PA'),('US','GJC','Genesee','Genesee','WI'),('US','GJD','Gardner','Gardner','IL'),('US','GJF','Germansville','Germansville','PA'),('US','GJJ','Gibsonia','Gibsonia','PA'),('US','GJM','Grimes','Grimes','IA'),('US','GJN','Grand Junction','Grand Junction','TN'),('US','GJT','Grand Junction','Grand Junction','CO'),('US','GKE','Allendale','Allendale','MI'),('US','GKH','Goshen','Goshen','OH'),('US','GKN','Gulkana','Gulkana','AK'),('US','GKO','Greenwood','Greenwood','DE'),('US','GKT','Gatlinburg','Gatlinburg','TN'),('US','GL2','Grenloch','Grenloch','NJ'),('US','GL3','Guilderland','Guilderland','NY'),('US','GLA','Goldendale','Goldendale','WA'),('US','GLB','Glenola','Glenola','NC'),('US','GLC','Gloucester City','Gloucester City','NJ'),('US','GLD','Goodland','Goodland','KS'),('US','GLE','Gainesville','Gainesville','TX'),('US','GLH','Greenville','Greenville','MS'),('US','GLI','Glenside','Glenside','PA'),('US','GLJ','Goldston','Goldston','NC'),('US','GLK','Glen Rock','Glen Rock','NJ'),('US','GLL','Glastonbury','Glastonbury','CT'),('US','GLM','Glenbrook','Glenbrook','CT'),('US','GLN','Glen Cove','Glen Cove','NY'),('US','GLO','Gloucester','Gloucester','MA'),('US','GLP','Green Lane','Green Lane','PA'),('US','GLQ','Glennallen','Glennallen','AK'),('US','GLR','Glassboro','Glassboro','NJ'),('US','GLS','Galveston','Galveston','TX'),('US','GLT','Greenbelt','Greenbelt','MD'),('US','GLU','Gloster','Gloster','MS'),('US','GLV','Golovin','Golovin','AK'),('US','GLW','Glasgow','Glasgow','KY'),('US','GLX','Galax','Galax','VA'),('US','GLY','Glen Rose','Glen Rose','TX'),('US','GLZ','Gleason','Gleason','TN'),('US','GM2','Gypsum','Gypsum','CO'),('US','GMA','Gilman','Gilman','IL'),('US','GML','Georges Mills','Georges Mills','NH'),('US','GMN','Germantown','Germantown','WI'),('US','GMO','Germantown','Germantown','OH'),('US','GMR','Graham','Graham','NC'),('US','GMT','Granite Mountain','Granite Mountain','AK'),('US','GMV','Monument Valley Gldngs','Monument Valley Gldngs','UT'),('US','GMW','Greenwood, El Dorado','Greenwood, El Dorado','CA'),('US','GMX','Gallman','Gallman','MS'),('US','GN2','Genoa, Ottawa','Genoa, Ottawa','OH'),('US','GNA','Greenwich','Greenwich','VA'),('US','GNB','Grant','Grant','NE'),('US','GNC','Garner','Garner','NC'),('US','GND','Gnadenhutten','Gnadenhutten','OH'),('US','GNE','Glenolden','Glenolden','PA'),('US','GNF','Greenfield','Greenfield','OH'),('US','GNG','Gooding','Gooding','ID'),('US','GNH','Greenfield','Greenfield','MA'),('US','GNI','Geneva','Geneva','IL'),('US','GNJ','Georgetown, Vermilion','Georgetown, Vermilion','OH'),('US','GNK','Great Neck','Great Neck','NY'),('US','GNL','Greenland','Greenland','NH'),('US','GNM','Greenville','Greenville','MI'),('US','GNN','Greenland','Greenland','TN'),('US','GNO','Greensboro','Greensboro','GA'),('US','GNP','Greenville','Greenville','PA'),('US','GNQ','Greenwood','Greenwood','AR'),('US','GNR','Garner','Garner','IA'),('US','GNS','Greenwood, Guernsey','Greenwood, Guernsey','OH'),('US','GNT','Grants','Grants','NM'),('US','GNU','Goodnews Bay','Goodnews Bay','AK'),('US','GNV','Gainesville','Gainesville','FL'),('US','GNW','Greenwood','Greenwood','IN'),('US','GNY','Greenville','Greenville','NY'),('US','GNZ','Gonzales','Gonzales','LA'),('US','GO2','Goleta','Goleta','CA'),('US','GOA','Goddard','Goddard','KS'),('US','GOB','Gibson','Gibson','GA'),('US','GOC','Glen Rock','Glen Rock','PA'),('US','GOD','Godwin','Godwin','NC'),('US','GOE','Golden','Golden','CO'),('US','GOG','Goshen','Goshen','VA'),('US','GOH','Gorham','Gorham','NM'),('US','GOI','Genoa','Genoa','IL'),('US','GOK','Guthrie','Guthrie','OK'),('US','GOL','Gold Beach','Gold Beach','OR'),('US','GOM','Gorman','Gorman','TX'),('US','GON','Groton-New London Apt','Groton-New London Apt','CT'),('US','GOO','Groton','Groton','SD'),('US','GOP','Good Hope','Good Hope','LA'),('US','GOR','Gordon','Gordon','GA'),('US','GOS','Goshen','Goshen','AL'),('US','GOT','Groton','Groton','MA'),('US','GOU','Goulds','Goulds','FL'),('US','GOV','Gordonsville','Gordonsville','TN'),('US','GOY','Gregory','Gregory','TX'),('US','GOZ','Gonzales','Gonzales','TX'),('US','GP2','Gosport','Gosport','IN'),('US','GP4','Greenport','Greenport','NY'),('US','GPB','Garfield','Garfield','AR'),('US','GPE','Gardners','Gardners','PA'),('US','GPK','Galena Park','Galena Park','TX'),('US','GPL','Grapeland','Grapeland','TX'),('US','GPS','Greenwell Springs','Greenwell Springs','LA'),('US','GPT','Gulfport','Gulfport','MS'),('US','GPU','Gypsum','Gypsum','OH'),('US','GPV','Grapevine','Grapevine','TX'),('US','GPX','Glassport','Glassport','PA'),('US','GPZ','Grand Rapids','Grand Rapids','MN'),('US','GQQ','Galion','Galion','OH'),('US','GQS','Grant City','Grant City','MO'),('US','GQW','Greenwood','Greenwood','ME'),('US','GR2','Graton','Graton','CA'),('US','GR3','Green Ridge','Green Ridge','MO'),('US','GRA','Grand Portage','Grand Portage','MN'),('US','GRB','Green Bay','Green Bay','WI'),('US','GRC','Graceville','Graceville','FL'),('US','GRD','Greenwood','Greenwood','SC'),('US','GRE','Greenville','Greenville','IL'),('US','GRF','Grasonville','Grasonville','MD'),('US','GRG','Gray','Gray','ME'),('US','GRH','Greenwich','Greenwich','CT'),('US','GRI','Grand Island','Grand Island','NE'),('US','GRJ','Girard','Girard','PA'),('US','GRK','Grant Park','Grant Park','IL'),('US','GRL','Great Lakes','Great Lakes','IL'),('US','GRM','Grand Marais','Grand Marais','MN'),('US','GRN','Greenville','Greenville','AL'),('US','GRO','Grove City','Grove City','PA'),('US','GRP','Greencastle','Greencastle','PA'),('US','GRQ','Graham','Graham','WA'),('US','GRR','Grand Rapids','Grand Rapids','MI'),('US','GRS','Greensburg','Greensburg','IN'),('US','GRT','Groveton','Groveton','NH'),('US','GRU','Grundy Center','Grundy Center','IA'),('US','GRV','Grays River','Grays River','WA'),('US','GRW','Greenwich','Greenwich','NY'),('US','GRX','Garland','Garland','TX'),('US','GRY','Gramercy','Gramercy','LA'),('US','GRZ','Griffin','Griffin','GA'),('US','GSB','Goldsboro','Goldsboro','NC'),('US','GSC','Goose Creek','Goose Creek','SC'),('US','GSE','Glouster','Glouster','OH'),('US','GSF','Gales Ferry','Gales Ferry','CT'),('US','GSG','Glasgow','Glasgow','MT'),('US','GSH','Goshen','Goshen','IN'),('US','GSL','Geyserville','Geyserville','CA'),('US','GSM','Geismar','Geismar','LA'),('US','GSN','Gaston','Gaston','NC'),('US','GSO','Greensboro-High Point Apt','Greensboro-High Point Apt','NC'),('US','GSP','Greenville-Greer Apt','Greenville-Greer Apt','SC'),('US','GSR','Glade Spring','Glade Spring','VA'),('US','GSS','Grosse Pointe','Grosse Pointe','MI'),('US','GST','Gustavus','Gustavus','AK'),('US','GSU','Galesburg','Galesburg','MI'),('US','GSV','Griswoldville','Griswoldville','MA'),('US','GSW','Big Sur','Big Sur','CA'),('US','GSY','Gassaway','Gassaway','WV'),('US','GSZ','Garrison','Garrison','MO'),('US','GT2','Gates','Gates','TN'),('US','GTA','Grant','Grant','AL'),('US','GTB','Granite Bay','Granite Bay','CA'),('US','GTE','Grantsville','Grantsville','UT'),('US','GTF','Great Falls','Great Falls','MT'),('US','GTG','Grovetown','Grovetown','GA'),('US','GTJ','Grant','Grant','MI'),('US','GTL','Gretna','Gretna','LA'),('US','GTM','Mount Sterling','Mount Sterling','IL'),('US','GTN','Germantown','Germantown','MD'),('US','GTO','Guntown','Guntown','MS'),('US','GTP','Green Tree','Green Tree','PA'),('US','GTR','Gentry','Gentry','AR'),('US','GTS','Greeneville','Greeneville','TN'),('US','GTT','Gillett','Gillett','WI'),('US','GTU','Gladstone','Gladstone','OR'),('US','GTV','Graniteville','Graniteville','SC'),('US','GTW','Georgetown','Georgetown','TX'),('US','GTY','Gettysburg','Gettysburg','PA'),('US','GTZ','Glenmont','Glenmont','NY'),('US','GU2','Greenup','Greenup','IL'),('US','GUA','Altenburg','Altenburg','MO'),('US','GUC','Gunnison','Gunnison','CO'),('US','GUD','Guild','Guild','NH'),('US','GUE','Guntersville','Guntersville','AL'),('US','GUF','Gulf Shores','Gulf Shores','AL'),('US','GUL','Guilford','Guilford','ME'),('US','GUN','Guernsey','Guernsey','WY'),('US','GUO','Gurdon','Gurdon','AR'),('US','GUP','Gallup','Gallup','NM'),('US','GUR','Gurnee','Gurnee','IL'),('US','GUS','Peru','Peru','IN'),('US','GUT','Gustine','Gustine','CA'),('US','GUV','Gulliver','Gulliver','MI'),('US','GUW','Guilderland Center','Guilderland Center','NY'),('US','GUY','Guymon','Guymon','OK'),('US','GV2','Garnerville','Garnerville','NY'),('US','GV3','Gillsville','Gillsville','GA'),('US','GV4','Greenwood Village','Greenwood Village','CO'),('US','GV5','Glenville','Glenville','NY'),('US','GV6','Green Valley','Green Valley','AZ'),('US','GVA','Gore','Gore','VA'),('US','GVB','Grover Beach','Grover Beach','CA'),('US','GVC','Granville','Granville','OH'),('US','GVD','Groveland','Groveland','FL'),('US','GVE','Gordonsville','Gordonsville','VA'),('US','GVH','Grove Hill','Grove Hill','AL'),('US','GVI','Granville','Granville','NY'),('US','GVJ','Greenvale','Greenvale','NY'),('US','GVK','Gloversville','Gloversville','NY'),('US','GVL','Gainesville','Gainesville','GA'),('US','GVO','Groveland','Groveland','MA'),('US','GVP','Groveport','Groveport','OH'),('US','GVQ','Greenville','Greenville','MA'),('US','GVR','Gansevoort','Gansevoort','NY'),('US','GVT','Greenville','Greenville','TX'),('US','GVV','Green River','Green River','WY'),('US','GVW','Grandview','Grandview','MO'),('US','GVX','Glen View','Glen View','IL'),('US','GVY','Golden Valley','Golden Valley','MN'),('US','GVZ','Gordonville','Gordonville','PA'),('US','GW2','Gwinnett','Gwinnett','ID'),('US','GW3','Greenwood','Greenwood','NE'),('US','GW4','Greenwood, Henry','Greenwood, Henry','GA'),('US','GWA','George','George','WA'),('US','GWC','Greenwood','Greenwood','WI'),('US','GWD','Greenwood','Greenwood','FL'),('US','GWE','Greenville','Greenville','MO'),('US','GWF','Greenleaf','Greenleaf','ID'),('US','GWG','Grawn','Grawn','MI'),('US','GWH','Greenview Hills','Greenview Hills','TX'),('US','GWI','Gwinner','Gwinner','ND'),('US','GWK','Girdwood','Girdwood','AK'),('US','GWL','Glenshaw','Glenshaw','PA'),('US','GWN','Georgetown, Fayette','Georgetown, Fayette','IL'),('US','GWO','Greenwood','Greenwood','MS'),('US','GWR','Bridgewater','Bridgewater','CT'),('US','GWS','Glenwood Springs','Glenwood Springs','CO'),('US','GWT','Goodwater','Goodwater','AL'),('US','GWU','Guin','Guin','AL'),('US','GWV','Glendale','Glendale','WV'),('US','GWW','Glenwillow','Glenwillow','OH'),('US','GWX','Glenwood','Glenwood','IA'),('US','GWY','Gwynedd','Gwynedd','PA'),('US','GXA','Geneva','Geneva','FL'),('US','GXF','Grafton','Grafton','VA'),('US','GXN','Geneva','Geneva','AL'),('US','GXQ','Greencastle','Greencastle','IN'),('US','GXT','Georgetown','Georgetown','MA'),('US','GXV','Gilbertsville','Gilbertsville','PA'),('US','GXX','Greer','Greer','SC'),('US','GXY','Greeley','Greeley','CO'),('US','GY2','Gascoyne','Gascoyne','ND'),('US','GY3','Gridley ','Gridley ','CA'),('US','GY4','Gurley','Gurley','AL'),('US','GY5','Gray','Gray','TN'),('US','GYA','Gray','Gray','LA'),('US','GYC','Grass Valley','Grass Valley','CA'),('US','GYD','Gaylord','Gaylord','MI'),('US','GYE','Greenville','Greenville','RI'),('US','GYF','Griffith','Griffith','IN'),('US','GYH','Gayville, Yankton','Gayville, Yankton','SD'),('US','GYJ','Grand Ridge','Grand Ridge','IL'),('US','GYK','Gray','Gray','KY'),('US','GYL','Grayslake','Grayslake','IL'),('US','GYN','Glyndon','Glyndon','MD'),('US','GYO','Grayson','Grayson','KY'),('US','GYP','Greeley','Greeley','PA'),('US','GYR','Goodyear','Goodyear','AZ'),('US','GYS','Garysburg','Garysburg','NC'),('US','GYT','Griffith','Griffith','AZ'),('US','GYV','Garyville','Garyville','LA'),('US','GYY','Gary','Gary','IN'),('US','GZB','Grabill','Grabill','IN'),('US','GZC','Garden City','Garden City','AL'),('US','GZE','Getzville','Getzville','NY'),('US','GZI','Granite City','Granite City','IL'),('US','GZL','Gonzalez','Gonzalez','FL'),('US','GZS','Gonzales','Gonzales','CA'),('US','GZV','Garrettsville','Garrettsville','OH'),('US','GZY','Montgomery Center','Montgomery Center','VT'),('US','HAA','Havertown','Havertown','PA'),('US','HAB','Hamilton','Hamilton','AL'),('US','HAC','Hamilton City','Hamilton City','CA'),('US','HAD','Healdton','Healdton','OK'),('US','HAE','Havasupai','Havasupai','AZ'),('US','HAF','Half Moon Bay','Half Moon Bay','CA'),('US','HAG','Haskell','Haskell','OK'),('US','HAH','Hahnville','Hahnville','LA'),('US','HAI','Three Rivers','Three Rivers','MI'),('US','HAL','Hallandale','Hallandale','FL'),('US','HAM','Hamburg','Hamburg','NJ'),('US','HAN','Hanover','Hanover','NJ'),('US','HAO','Hamilton','Hamilton','OH'),('US','HAP','Hauppauge','Hauppauge','NY'),('US','HAQ','Hartland','Hartland','ME'),('US','HAR','Harrisburg','Harrisburg','PA'),('US','HAS','Hartsdale','Hartsdale','NY'),('US','HAT','Hatfield','Hatfield','PA'),('US','HAU','Harrisburg','Harrisburg','SD'),('US','HAV','Haverhill','Haverhill','MA'),('US','HAW','Hawthorne','Hawthorne','NY'),('US','HAX','Hampton','Hampton','NH'),('US','HAY','Haycock','Haycock','AK'),('US','HAZ','Hawkinsville','Hawkinsville','GA'),('US','HB2','Hackleburg','Hackleburg','AL'),('US','HB3','Harrisburg','Harrisburg','OR'),('US','HB4','Harbor Beach','Harbor Beach','MI'),('US','HB5','Hillsboro','Hillsboro','TN'),('US','HBA','Hobart','Hobart','IN'),('US','HBB','Hilbert','Hilbert','WI'),('US','HBC','Hanus Bay','Hanus Bay','AK'),('US','HBD','Harbeson','Harbeson','DE'),('US','HBE','Hobe Sound','Hobe Sound','FL'),('US','HBF','Harrodsburg','Harrodsburg','KY'),('US','HBG','Hattiesburg','Hattiesburg','MS'),('US','HBH','Hobart Bay','Hobart Bay','AK'),('US','HBI','Hubbard','Hubbard','OR'),('US','HBK','Hoboken','Hoboken','NJ'),('US','HBL','Hannibal','Hannibal','MO'),('US','HBM','Hillburn','Hillburn','NY'),('US','HBN','Hebron','Hebron','KY'),('US','HBO','Hansboro','Hansboro','ND'),('US','HBQ','Hamburg','Hamburg','IA'),('US','HBR','Hobart','Hobart','OK'),('US','HBS','Heber Springs','Heber Springs','AR'),('US','HBT','Hulbert','Hulbert','OK'),('US','HBU','Washburn','Washburn','IL'),('US','HBV','Harrisonburg','Harrisonburg','VA'),('US','HBX','Hubbell','Hubbell','MI'),('US','HBZ','Heidlersburg','Heidlersburg','PA'),('US','HC2','Heber City','Heber City','UT'),('US','HCA','Big Spring','Big Spring','TX'),('US','HCB','Shoal Cove','Shoal Cove','AK'),('US','HCC','Hudson','Hudson','NY'),('US','HCD','Camp Hill','Camp Hill','AL'),('US','HCE','Honey Creek','Honey Creek','WI'),('US','HCF','Haines City','Haines City','FL'),('US','HCG','Mechanicsburg','Mechanicsburg','IL'),('US','HCH','Hutchinson','Hutchinson','MN'),('US','HCI','Hill City','Hill City','SD'),('US','HCK','Hackensack','Hackensack','NJ'),('US','HCM','Holcomb','Holcomb','IL'),('US','HCN','Holt','Holt','MI'),('US','HCP','Church Point','Church Point','LA'),('US','HCR','Holy Cross','Holy Cross','AK'),('US','HCS','Hockessin','Hockessin','DE'),('US','HCT','Hackettstown','Hackettstown','NJ'),('US','HCV','Hanceville','Hanceville','AL'),('US','HCW','Cheraw','Cheraw','SC'),('US','HCY','Haltom City','Haltom City','TX'),('US','HCZ','Harford','Harford','NY'),('US','HD2','Holladay','Holladay','UT'),('US','HD3','Hemstead','Hemstead','TX'),('US','HDA','Hidden Falls','Hidden Falls','AK'),('US','HDB','Hollidaysburg','Hollidaysburg','PA'),('US','HDC','Havre de Grace','Havre de Grace','MD'),('US','HDD','Hiddenite','Hiddenite','NC'),('US','HDE','Holdrege','Holdrege','NE'),('US','HDF','Hilliard','Hilliard','FL'),('US','HDG','Hodges','Hodges','SC'),('US','HDI','Holiday City','Holiday City','OH'),('US','HDK','Haddock','Haddock','GA'),('US','HDL','Hinsdale','Hinsdale','NH'),('US','HDM','Hudson','Hudson','MA'),('US','HDN','Hayden','Hayden','CO'),('US','HDO','Henderson','Henderson','CO'),('US','HDP','Harding','Harding','PA'),('US','HDQ','Heidelberg','Heidelberg','PA'),('US','HDR','Hildebran','Hildebran','NC'),('US','HDS','Hudson','Hudson','CO'),('US','HDT','Henderson','Henderson','TN'),('US','HDU','Hudson','Hudson','NH'),('US','HDV','Hendersonville','Hendersonville','TN'),('US','HDW','Hudson','Hudson','WI'),('US','HDX','Hood River','Hood River','OR'),('US','HDY','Hadley','Hadley','PA'),('US','HDZ','Holmdel','Holmdel','NJ'),('US','HEA','Hearne','Hearne','TX'),('US','HEB','Hebron','Hebron','OH'),('US','HEC','Hermosa Beach','Hermosa Beach','CA'),('US','HED','Herendeen','Herendeen','AK'),('US','HEE','Helena','Helena','AR'),('US','HEF','Heflin','Heflin','AL'),('US','HEH','Hershey','Hershey','PA'),('US','HEI','Sheffield','Sheffield','OH'),('US','HEK','Hyde Park','Hyde Park','NY'),('US','HEL','Hellertown','Hellertown','PA'),('US','HEM','Hemlock','Hemlock','MI'),('US','HEN','Henderson','Henderson','NC'),('US','HEO','Hebron','Hebron','IL'),('US','HEP','Hempstead','Hempstead','NY'),('US','HER','Herrin','Herrin','IL'),('US','HES','Hermiston','Hermiston','OR'),('US','HET','Hesston','Hesston','KS'),('US','HEU','Helm','Helm','CA'),('US','HEV','Hendersonville','Hendersonville','NC'),('US','HEW','Hopewell','Hopewell','NJ'),('US','HEY','Henry','Henry','TN'),('US','HEZ','Natchez','Natchez','MS'),('US','HF2','Highland Falls','Highland Falls','NY'),('US','HFA','Honeoye Falls','Honeoye Falls','NY'),('US','HFC','Hartford City','Hartford City','IN'),('US','HFD','Hartford','Hartford','CT'),('US','HFE','Hatfield','Hatfield','AR'),('US','HFF','Hoffman','Hoffman','NC'),('US','HFI','Hartford','Hartford','IL'),('US','HFL','Haddonfield','Haddonfield','NJ'),('US','HFN','Hamilton','Hamilton','IN'),('US','HFO','Hartford','Hartford','WI'),('US','HFR','Hereford','Hereford','TX'),('US','HFY','Hudson Falls','Hudson Falls','NY'),('US','HG2','Hastings','Hastings','MI'),('US','HG3','Hegins','Hegins','PA'),('US','HG4','Hughes','Hughes','AR'),('US','HGA','Hogansville','Hogansville','GA'),('US','HGE','Higley','Higley','AZ'),('US','HGH','Highland Park','Highland Park','CA'),('US','HGI','Highspire','Highspire','PA'),('US','HGL','Highland','Highland','IL'),('US','HGM','Hingham','Hingham','MA'),('US','HGN','Hawaiian Gardens','Hawaiian Gardens','CA'),('US','HGO','Haughton','Haughton','LA'),('US','HGR','Hagerstown','Hagerstown','MD'),('US','HGS','Highlands','Highlands','NJ'),('US','HGT','Jolon','Jolon','CA'),('US','HGU','Huguenot','Huguenot','NY'),('US','HGW','Huntington Woods','Huntington Woods','MI'),('US','HGX','Hermitage','Hermitage','PA'),('US','HGZ','Hogatza','Hogatza','AK'),('US','HHA','Ashburnham','Ashburnham','MA'),('US','HHB','Humboldt','Humboldt','TN'),('US','HHE','Hacienda Heights','Hacienda Heights','CA'),('US','HHG','Harker Heights','Harker Heights','TX'),('US','HHH','Hilton Head Island','Hilton Head Island','SC'),('US','HHI','Wahiawa','Wahiawa','HI'),('US','HHK','Ho-Ho-Kus','Ho-Ho-Kus','NJ'),('US','HHL','Holly Hill','Holly Hill','FL'),('US','HHM','Hamilton','Hamilton','TX'),('US','HHO','Haverhill','Haverhill','OH'),('US','HHQ','Holly Hill','Holly Hill','SC'),('US','HHR','Hawthorne','Hawthorne','CA'),('US','HHS','South Hutchinson','South Hutchinson','KS'),('US','HHT','Harwood Heights','Harwood Heights','IL'),('US','HHU','Hope Hull','Hope Hull','AL'),('US','HHV','Heathsville','Heathsville','VA'),('US','HHY','Herkimer','Herkimer','NY'),('US','HIA','Highland Park','Highland Park','IL'),('US','HIB','Chisholm-Hibbing Apt','Chisholm-Hibbing Apt','MN'),('US','HIC','Highland City','Highland City','FL'),('US','HID','Hidalgo','Hidalgo','TX'),('US','HIE','Whitefield','Whitefield','NH'),('US','HIF','Hill Air Force Base','Hill Air Force Base','UT'),('US','HIG','Higganum','Higganum','CT'),('US','HIH','Highland','Highland','NY'),('US','HII','Lake Havasu City','Lake Havasu City','AZ'),('US','HIJ','Highland','Highland','IN'),('US','HIK','Highland Heights','Highland Heights','OH'),('US','HIL','Hills','Hills','IA'),('US','HIM','White Marsh','White Marsh','MD'),('US','HIN','Highlands','Highlands','TX'),('US','HIO','Hillsboro','Hillsboro','OR'),('US','HIP','Highland Park','Highland Park','MI'),('US','HIQ','Highland','Highland','CA'),('US','HIR','Harrison','Harrison','MI'),('US','HIS','Highgate Springs','Highgate Springs','VT'),('US','HIT','Highpoint','Highpoint','OH'),('US','HIU','Hinesburg','Hinesburg','VT'),('US','HIV','Hillsville','Hillsville','VA'),('US','HIW','High View','High View','WV'),('US','HIY','Hickory','Hickory','KY'),('US','HIZ','Hinckley','Hinckley','OH'),('US','HJF','Hudson','Hudson','IA'),('US','HJK','Hamilton','Hamilton','NY'),('US','HJL','Hilliard','Hilliard','OH'),('US','HJO','Hamilton, Ocean','Hamilton, Ocean','NJ'),('US','HJQ','Hood','Hood','CA'),('US','HJW','Hillsboro','Hillsboro','IN'),('US','HKB','Healy Lake','Healy Lake','AK'),('US','HKI','Haskins','Haskins','OH'),('US','HKK','Hickok','Hickok','KS'),('US','HKL','Hinckley','Hinckley','ME'),('US','HKM','Herkimer','Herkimer','KS'),('US','HKN','Hopkinton','Hopkinton','MA'),('US','HKQ','Houlka','Houlka','MS'),('US','HKR','Henniker','Henniker','NH'),('US','HKS','South Hackensack/New Jersey','South Hackensack/New Jersey','NJ'),('US','HKY','Hickory','Hickory','NC'),('US','HL2','Hartland','Hartland','MN'),('US','HL3','Highland','Highland','MI'),('US','HL4','Hoagland','Hoagland','IN'),('US','HL5','Havelock','Havelock','NC'),('US','HL6','Holland, Effingham','Holland, Effingham','IL'),('US','HL7','Highland, Dallas','Highland, Dallas','TX'),('US','HLA','Healdsburg','Healdsburg','CA'),('US','HLB','Batesville','Batesville','IN'),('US','HLC','Hill City','Hill City','KS'),('US','HLD','Haledon','Haledon','NJ'),('US','HLE','Headland','Headland','AL'),('US','HLF','Hialeah','Hialeah','FL'),('US','HLG','Wheeling','Wheeling','WV'),('US','HLH','Hinkley','Hinkley','CA'),('US','HLI','Hollister','Hollister','CA'),('US','HLJ','Halls','Halls','TN'),('US','HLK','Houghton Lake','Houghton Lake','MI'),('US','HLL','Hillsboro','Hillsboro','TX'),('US','HLM','Holland','Holland','MI'),('US','HLN','Helena','Helena','MT'),('US','HLO','Hammond','Hammond','LA'),('US','HLP','Holly Pond','Holly Pond','AL'),('US','HLQ','Holcomb','Holcomb','KS'),('US','HLS','Hillside','Hillside','NJ'),('US','HLT','Hamilton','Hamilton','MT'),('US','HLU','Hollis','Hollis','NY'),('US','HLV','Haileyville','Haileyville','OK'),('US','HLW','Hollywood','Hollywood','CA'),('US','HLX','Holland','Holland','PA'),('US','HLY','Haleyville','Haleyville','AL'),('US','HLZ','Healy','Healy','AK'),('US','HM2','Hamilton','Hamilton','MI'),('US','HM3','Hickman','Hickman','KY'),('US','HM4','Herculaneum','Herculaneum','MO'),('US','HMA','Harmans','Harmans','MD'),('US','HMB','Hamilton Square','Hamilton Square','PA'),('US','HMC','Richmond','Richmond','MO'),('US','HMD','Hammondsville','Hammondsville','OH'),('US','HME','Hoffman Estates','Hoffman Estates','IL'),('US','HMG','Hamilton, Monmouth','Hamilton, Monmouth','NJ'),('US','HMH','Homer','Homer','LA'),('US','HMI','Homedale','Homedale','ID'),('US','HMJ','Harvey','Harvey','LA'),('US','HML','Hamlet','Hamlet','NC'),('US','HMM','Hammond','Hammond','WI'),('US','HMN','Hammond','Hammond','IN'),('US','HMO','Harrisonville','Harrisonville','MO'),('US','HMP','Hammondsport','Hammondsport','NY'),('US','HMQ','Hamburg','Hamburg','PA'),('US','HMR','Hamer','Hamer','ID'),('US','HMS','Homeshore','Homeshore','AK'),('US','HMT','Hemet','Hemet','CA'),('US','HMV','Homerville','Homerville','GA'),('US','HMW','Homewood','Homewood','IL'),('US','HMX','Humble','Humble','TX'),('US','HMY','Harmony','Harmony','PA'),('US','HMZ','Hamilton','Hamilton','MS'),('US','HN2','Haney','Haney','TX'),('US','HN3','Hebron','Hebron','ND'),('US','HN4','Halltown','Halltown','WV'),('US','HNA','Hannah','Hannah','ND'),('US','HNB','Huntingburg','Huntingburg','IN'),('US','HNC','Hatteras','Hatteras','NC'),('US','HND','Hernando','Hernando','MS'),('US','HNE','Tahneta Pass Lodge','Tahneta Pass Lodge','AK'),('US','HNF','Hanford','Hanford','CA'),('US','HNG','Huntington Park','Huntington Park','CA'),('US','HNH','Hoonah','Hoonah','AK'),('US','HNI','Hansen','Hansen','ID'),('US','HNJ','Henning','Henning','TN'),('US','HNK','Hancock','Hancock','ME'),('US','HNL','Honolulu','Honolulu','HI'),('US','HNM','Hana','Hana','HI'),('US','HNN','Hanoverton','Hanoverton','OH'),('US','HNO','China Grove','China Grove','NC'),('US','HNP','Hanover','Hanover','PA'),('US','HNQ','Henagar','Henagar','AL'),('US','HNR','Hainesport','Hainesport','NJ'),('US','HNS','Haines','Haines','AK'),('US','HNT','Huntsville','Huntsville','TN'),('US','HNU','Huntington','Huntington','WV'),('US','HNV','Hampton','Hampton','VA'),('US','HNW','Hornell','Hornell','NY'),('US','HNX','Hanna','Hanna','WY'),('US','HNY','Honey Brook','Honey Brook','PA'),('US','HNZ','Henderson','Henderson','NV'),('US','HOA','Horsham','Horsham','PA'),('US','HOB','Hobbs','Hobbs','NM'),('US','HOC','Holly','Holly','MI'),('US','HOD','Honesdale','Honesdale','PA'),('US','HOE','Sweet Home','Sweet Home','OR'),('US','HOF','Hoosierlift','Hoosierlift','IN'),('US','HOH','Hohenwald','Hohenwald','TN'),('US','HOJ','Howell','Howell','NJ'),('US','HOK','Hodgkins','Hodgkins','IL'),('US','HOL','Holikachuk','Holikachuk','AK'),('US','HOM','Homer','Homer','AK'),('US','HON','Huron','Huron','SD'),('US','HOO','Holland','Holland','OH'),('US','HOP','Hopkinsville','Hopkinsville','KY'),('US','HOQ','Helotes','Helotes','TX'),('US','HOR','Homer','Homer','NY'),('US','HOS','Horseshoe','Horseshoe','NC'),('US','HOT','Hot Springs','Hot Springs','AR'),('US','HOU','Houston','Houston','TX'),('US','HOV','Holtsville','Holtsville','NY'),('US','HOW','Hueytown','Hueytown','AL'),('US','HOX','Hastings-on-Hudson','Hastings-on-Hudson','NY'),('US','HOY','Howe','Howe','IN'),('US','HPA','Hyde Park','Hyde Park','CA'),('US','HPB','Hooper Bay','Hooper Bay','AK'),('US','HPD','Hampstead','Hampstead','MD'),('US','HPE','Shepherd','Shepherd','TX'),('US','HPF','Hampton','Hampton','FL'),('US','HPG','Hughes Springs','Hughes Springs','TX'),('US','HPH','Halethorpe','Halethorpe','MD'),('US','HPI','Hope','Hope','IN'),('US','HPK','Hanover Park','Hanover Park','IL'),('US','HPL','Hapeville','Hapeville','GA'),('US','HPN','Westchester County Apt','Westchester County Apt','NY'),('US','HPO','Hopkins','Hopkins','MN'),('US','HPP','Hot Springs National Park','Hot Springs National Park','AR'),('US','HPR','Hope','Hope','AR'),('US','HPS','Hampshire','Hampshire','IL'),('US','HPT','Hampton','Hampton','IA'),('US','HPW','Hopewell','Hopewell','VA'),('US','HPX','Hopedale','Hopedale','MA'),('US','HPY','Baytown','Baytown','TX'),('US','HPZ','High Point','High Point','NC'),('US','HQA','Horn Lake','Horn Lake','MS'),('US','HQB','Hillsborough','Hillsborough','CA'),('US','HQF','Highgrove','Highgrove','CA'),('US','HQG','Hagaman','Hagaman','NY'),('US','HQH','Highway Highlands','Highway Highlands','CA'),('US','HQL','Haskell','Haskell','TX'),('US','HQM','Hoquiam','Hoquiam','WA'),('US','HQN','Houston','Houston','MO'),('US','HQO','Holden','Holden','WV'),('US','HQP','Hesperia','Hesperia','CA'),('US','HQQ','Houghton','Houghton','IA'),('US','HQT','Holton','Holton','KS'),('US','HQU','South Houston','South Houston','TX'),('US','HQV','Happy Valley','Happy Valley','OR'),('US','HQW','Highlands','Highlands','WA'),('US','HQZ','Hazel Dell','Hazel Dell','WA'),('US','HR2','Hiram','Hiram','OH'),('US','HRB','Harbor City','Harbor City','CA'),('US','HRC','Hurricane','Hurricane','UT'),('US','HRE','Harlem','Harlem','GA'),('US','HRF','Harford','Harford','PA'),('US','HRG','Harrington','Harrington','ME'),('US','HRH','Horseheads','Horseheads','NY'),('US','HRI','Harriman','Harriman','NY'),('US','HRJ','Harahan','Harahan','LA'),('US','HRK','Holbrook','Holbrook','MA'),('US','HRL','Harlingen','Harlingen','TX'),('US','HRM','Hollister','Hollister','MO'),('US','HRN','Harrison','Harrison','NJ'),('US','HRO','Harrison','Harrison','AR'),('US','HRP','Harpersfield','Harpersfield','OH'),('US','HRQ','High Ridge','High Ridge','MO'),('US','HRR','Harrington','Harrington','DE'),('US','HRS','Charleston','Charleston','MS'),('US','HRT','Hart','Hart','MI'),('US','HRU','Harvard','Harvard','IL'),('US','HRV','Herndon','Herndon','VA'),('US','HRW','Horicon','Horicon','WI'),('US','HRX','Haw River','Haw River','NC'),('US','HRY','Harvey','Harvey','IL'),('US','HS2','Hackensack','Hackensack','MN'),('US','HS3','Harbor Springs','Harbor Springs','MI'),('US','HS4','Heaters','Heaters','WV'),('US','HS5','Holly Springs, Carteret','Holly Springs, Carteret','NC'),('US','HS6','Hallstead','Hallstead','PA'),('US','HS7','Holly Springs, Marshall','Holly Springs, Marshall','MS'),('US','HSA','Hinsdale','Hinsdale','IL'),('US','HSB','Harrisburg','Harrisburg','IL'),('US','HSC','Harmony','Harmony','SC'),('US','HSD','Hillside','Hillside','CO'),('US','HSE','Hillsdale','Hillsdale','MI'),('US','HSF','Hudson','Hudson','FL'),('US','HSG','Hillsborough','Hillsborough','NC'),('US','HSH','Hollis','Hollis','NH'),('US','HSI','Hastings','Hastings','NE'),('US','HSJ','Hospers','Hospers','IA'),('US','HSK','Hanson','Hanson','KY'),('US','HSL','Huslia','Huslia','AK'),('US','HSM','Houston','Houston','MS'),('US','HSN','Holstein','Holstein','IA'),('US','HSO','Houston','Houston','PA'),('US','HSP','Hot Springs','Hot Springs','VA'),('US','HSQ','Hamilton Square','Hamilton Square','NJ'),('US','HSR','Harrisburg','Harrisburg','NC'),('US','HSS','High Springs','High Springs','FL'),('US','HST','Homestead','Homestead','FL'),('US','HSU','Hillsborough','Hillsborough','NJ'),('US','HSV','Huntsville','Huntsville','AL'),('US','HSW','Schleswig','Schleswig','IA'),('US','HSY','Chase City','Chase City','VA'),('US','HT2','Hamilton','Hamilton','VA'),('US','HT3','Hampton','Hampton','GA'),('US','HT4','Hermantown','Hermantown','MN'),('US','HT5','Hutto','Hutto','TX'),('US','HT6','Hometown','Hometown','PA'),('US','HT7','Holt','Holt','FL'),('US','HT8','Henrietta','Henrietta','NY'),('US','HTC','Hutchins','Hutchins','TX'),('US','HTD','Huntington Beach','Huntington Beach','CA'),('US','HTE','Hartselle','Hartselle','AL'),('US','HTF','Hartford','Hartford','KY'),('US','HTG','Huntingdon','Huntingdon','PA'),('US','HTH','Hawthorne','Hawthorne','NV'),('US','HTI','Hawthorne','Hawthorne','NJ'),('US','HTK','Hutchinson','Hutchinson','KS'),('US','HTL','Houghton','Houghton','MI'),('US','HTM','Hartwell','Hartwell','GA'),('US','HTN','Hinton','Hinton','VA'),('US','HTO','East Hampton','East Hampton','NY'),('US','HTP','Hatboro','Hatboro','PA'),('US','HTQ','Huntley','Huntley','IL'),('US','HTR','Whistler','Whistler','AL'),('US','HTS','Ashland-Huntington Apt','Ashland-Huntington Apt','WV'),('US','HTT','Hartford','Hartford','MI'),('US','HTV','Huntsville','Huntsville','TX'),('US','HTW','Chesapeake','Chesapeake','OH'),('US','HTX','Henrietta','Henrietta','TX'),('US','HTY','Hartley','Hartley','IA'),('US','HTZ','Huntington','Huntington','VA'),('US','HU2','Hurley','Hurley','NM'),('US','HUA','Huber','Huber','GA'),('US','HUB','Huron','Huron','OH'),('US','HUC','Hurlock','Hurlock','MD'),('US','HUD','Humboldt','Humboldt','IA'),('US','HUE','Humboldt','Humboldt','KS'),('US','HUF','Terre Haute','Terre Haute','IN'),('US','HUG','Hugo','Hugo','OK'),('US','HUH','Huntington','Huntington','NY'),('US','HUI','Hunts Point/Bronx/New York','Hunts Point/Bronx/New York','NY'),('US','HUJ','Hurt','Hurt','VA'),('US','HUK','Hustonville','Hustonville','KY'),('US','HUL','Houlton','Houlton','ME'),('US','HUM','Houma','Houma','LA'),('US','HUN','Huntington','Huntington','IN'),('US','HUO','Hudson','Hudson','OH'),('US','HUP','Hoopeston','Hoopeston','IL'),('US','HUQ','Housatonic','Housatonic','MA'),('US','HUR','Hurst','Hurst','TX'),('US','HUS','Hughes','Hughes','AK'),('US','HUT','Hutchinson','Hutchinson','AR'),('US','HUV','Hudsonville','Hudsonville','MI'),('US','HUY','Hurley','Hurley','WI'),('US','HV2','Hughesville','Hughesville','PA'),('US','HV3','Havana','Havana','FL'),('US','HV4','Harvey','Harvey','IA'),('US','HVA','Hoover','Hoover','AL'),('US','HVD','Hunt Valley','Hunt Valley','MD'),('US','HVE','Hanksville','Hanksville','UT'),('US','HVI','Hartville','Hartville','OH'),('US','HVL','Harrisville','Harrisville','RI'),('US','HVM','Hanover','Hanover','MD'),('US','HVN','New Haven','New Haven','CT'),('US','HVP','Harleysville','Harleysville','PA'),('US','HVQ','Hanover','Hanover','MA'),('US','HVR','Havre','Havre','MT'),('US','HVS','Hartsville','Hartsville','SC'),('US','HVT','Haverstraw','Haverstraw','NY'),('US','HVV','Havana','Havana','IL'),('US','HVW','Harrisville','Harrisville','WV'),('US','HVY','Huntingdon Valley','Huntingdon Valley','PA'),('US','HW2','Chewelah','Chewelah','WA'),('US','HW3','Harwich','Harwich','MA'),('US','HW4','Hiawatha','Hiawatha','KS'),('US','HW5','Hiawatha','Hiawatha','IA'),('US','HWA','Homewood','Homewood','AL'),('US','HWB','Howe','Howe','OK'),('US','HWD','Hayward','Hayward','CA'),('US','HWE','Howey In The Hills','Howey In The Hills','FL'),('US','HWI','Hawk Inlet','Hawk Inlet','AK'),('US','HWK','Hardwick','Hardwick','MA'),('US','HWL','Howell','Howell','MI'),('US','HWM','Hayward','Hayward','MO'),('US','HWN','Hagerstown','Hagerstown','IN'),('US','HWO','Hollywood','Hollywood','FL'),('US','HWP','Hummelstown','Hummelstown','PA'),('US','HWR','Howard','Howard','SD'),('US','HWS','Hiwassee','Hiwassee','VA'),('US','HWT','Hawkins','Hawkins','TX'),('US','HWW','Hollywood','Hollywood','AL'),('US','HWY','Hemingway','Hemingway','SC'),('US','HWZ','Hawkins','Hawkins','WI'),('US','HX2','Hoxie','Hoxie','AR'),('US','HXB','Hammond','Hammond','OR'),('US','HXC','Haslett','Haslett','TX'),('US','HXF','Hungerford','Hungerford','TX'),('US','HXM','Hope Mills','Hope Mills','NC'),('US','HXN','Henderson','Henderson','TX'),('US','HXO','Huxford','Huxford','AL'),('US','HXP','Hampton Falls','Hampton Falls','NH'),('US','HXR','Henderson','Henderson','NE'),('US','HXS','Hixson','Hixson','TN'),('US','HXV','Hamburg','Hamburg','MI'),('US','HXX','Hollister','Hollister','FL'),('US','HXZ','Horizon City','Horizon City','TX'),('US','HYA','Hyannis','Hyannis','MA'),('US','HYB','Hayden Lake','Hayden Lake','ID'),('US','HYC','Holston','Holston','TN'),('US','HYD','Hyde','Hyde','PA'),('US','HYE','Hyde Park','Hyde Park','MA'),('US','HYF','Hickory Flat, Chicasaw','Hickory Flat, Chicasaw','MS'),('US','HYG','Hydaburg','Hydaburg','AK'),('US','HYH','Holcomb','Holcomb','NY'),('US','HYI','Harlan','Harlan','IA'),('US','HYK','Holyoke','Holyoke','CO'),('US','HYL','Hollis','Hollis','AK'),('US','HYM','Chrome','Chrome','NJ'),('US','HYN','Haynesville','Haynesville','OH'),('US','HYO','Henryetta','Henryetta','OK'),('US','HYP','Hypoluxo','Hypoluxo','FL'),('US','HYQ','Harmon','Harmon','ND'),('US','HYR','Hayward','Hayward','WI'),('US','HYS','Hays','Hays','KS'),('US','HYT','McSherrystown','McSherrystown','PA'),('US','HYU','Hyrum','Hyrum','UT'),('US','HYV','Hayesville','Hayesville','NC'),('US','HYW','Heyworth','Heyworth','IL'),('US','HYY','Henry','Henry','IL'),('US','HYZ','Harriman','Harriman','TN'),('US','HZ2','Hazel','Hazel','KY'),('US','HZA','Saint Henry','Saint Henry','OH'),('US','HZB','Hepzibah','Hepzibah','WV'),('US','HZH','Hazelhurst','Hazelhurst','GA'),('US','HZI','Hephzibah','Hephzibah','GA'),('US','HZJ','Hopelawn','Hopelawn','NJ'),('US','HZL','Hazleton','Hazleton','PA'),('US','HZO','Halsey','Halsey','OR'),('US','HZQ','Hebron','Hebron','NY'),('US','HZR','Hales Corners','Hales Corners','WI'),('US','HZT','Hazelton','Hazelton','ID'),('US','HZU','Hazlehurst','Hazlehurst','MS'),('US','HZV','Helena','Helena','AL'),('US','HZW','Hazelwood','Hazelwood','MO'),('US','HZY','Haysville','Haysville','KS'),('US','HZZ','Hawesville','Hawesville','KY'),('US','IAA','Indianola','Indianola','IA'),('US','IAB','Addison','Addison','ME'),('US','IAC','Reliance','Reliance','WY'),('US','IAD','Dulles Int Apt/Washington','Dulles Int Apt/Washington','VA'),('US','IAG','Niagara Falls','Niagara Falls','NY'),('US','IAL','Midland','Midland','NC'),('US','IAM','Miamisburg','Miamisburg','OH'),('US','IAN','Kiana','Kiana','AK'),('US','IAO','Cotati','Cotati','CA'),('US','IAR','Girard','Girard','IL'),('US','IBA','Itta Bena','Itta Bena','MS'),('US','IBB','Hibbing','Hibbing','MN'),('US','IBC','Miramar Beach','Miramar Beach','FL'),('US','IBE','Iberia','Iberia','OH'),('US','IBF','Brookfield','Brookfield','IL'),('US','IBG','Waitsburg','Waitsburg','WA'),('US','ICC','Clinton','Clinton','IL'),('US','ICD','Columbia Cross Roads','Columbia Cross Roads','PA'),('US','ICE','Spiceland','Spiceland','IN'),('US','ICH','Nicholls','Nicholls','GA'),('US','ICI','Mill City','Mill City','NV'),('US','ICL','Clarinda','Clarinda','IA'),('US','ICM','Mica','Mica','WA'),('US','ICS','Chelsea','Chelsea','MI'),('US','ICT','Wichita','Wichita','KS'),('US','ICV','Riceville','Riceville','TN'),('US','ICY','Icy Bay','Icy Bay','AK'),('US','IDA','Idaho Falls','Idaho Falls','ID'),('US','IDC','Independence','Independence','VA'),('US','IDD','Middlesex','Middlesex','NC'),('US','IDE','Independence','Independence','OR'),('US','IDG','Ida Grove','Ida Grove','IA'),('US','IDH','Idaho Springs','Idaho Springs','CO'),('US','IDI','Indiana','Indiana','PA'),('US','IDL','Indianola','Indianola','WA'),('US','IDN','Indianola','Indianola','MS'),('US','IDO','Imperial','Imperial','CA'),('US','IDP','Independence','Independence','KS'),('US','IDR','Widener','Widener','AR'),('US','IDS','Lindsay','Lindsay','OK'),('US','IDT','Indiantown','Indiantown','FL'),('US','IDV','Midvale','Midvale','OH'),('US','IDW','Midwest City','Midwest City','OK'),('US','IDY','Midland City','Midland City','AL'),('US','IEA','Mineral','Mineral','VA'),('US','IEL','Litchfield Park','Litchfield Park','AZ'),('US','IER','Silverton','Silverton','CO'),('US','IES','Winters','Winters','CA'),('US','IET','Marietta','Marietta','FL'),('US','IEV','Circleville','Circleville','UT'),('US','IEY','Riley','Riley','KS'),('US','IFA','Iowa Falls','Iowa Falls','IA'),('US','IFD','Whiteford','Whiteford','MD'),('US','IFI','Plainfield','Plainfield','OH'),('US','IFL','Island Falls','Island Falls','ME'),('US','IFN','Fenton','Fenton','IA'),('US','IFP','Bullhead City','Bullhead City','AZ'),('US','IFR','Ranier','Ranier','MN'),('US','IFT','Clifton','Clifton','TN'),('US','IGC','Spring Creek','Spring Creek','NV'),('US','IGE','Slinger','Slinger','WI'),('US','IGG','Igiugig','Igiugig','AK'),('US','IGH','Binghamton','Binghamton','WI'),('US','IGM','Kingman','Kingman','AZ'),('US','IGN','Arlington','Arlington','IA'),('US','IGO','Carrington','Carrington','ND'),('US','IGR','Singer','Singer','LA'),('US','IGS','Big Stone','Big Stone','DE'),('US','IGT','Arlington, Shelby','Arlington, Shelby','TN'),('US','IGW','Bridgewater','Bridgewater','VT'),('US','IHH','High Hill','High Hill','MO'),('US','IHL','Richland','Richland','OR'),('US','IHR','Winchester','Winchester','CA'),('US','IHT','Winchester','Winchester','MA'),('US','IHV','Smithville, Wayne','Smithville, Wayne','OH'),('US','IHW','Hollywood','Hollywood','MD'),('US','IIA','Williamsville','Williamsville','NY'),('US','III','Davisville, Wood','Davisville, Wood','WV'),('US','IIL','Littletown','Littletown','PA'),('US','IIM','Williamston','Williamston','MI'),('US','IIN','Inwood','Inwood','IA'),('US','IIS','Willis','Willis','MI'),('US','IIT','Hillister','Hillister','TX'),('US','IIV','Iron River','Iron River','WI'),('US','IIW','Williams','Williams','CA'),('US','IJA','Ijamsville','Ijamsville','MD'),('US','IJX','Jacksonville','Jacksonville','IL'),('US','IK2','Inkster','Inkster','MI'),('US','IKA','Minooka','Minooka','IL'),('US','IKB','Wilkesboro','Wilkesboro','NC'),('US','IKK','Kankakee','Kankakee','IL'),('US','IKO','Nikolski','Nikolski','AK'),('US','ILA','Imlay City','Imlay City','MI'),('US','ILB','Millersburg','Millersburg','KY'),('US','ILC','Charleston','Charleston','IL'),('US','ILD','Midland','Midland','MI'),('US','ILE','Killeen','Killeen','TX'),('US','ILG','Wilmington','Wilmington','DE'),('US','ILI','Iliamna','Iliamna','AK'),('US','ILK','Silver Lake','Silver Lake','IN'),('US','ILL','Willmar','Willmar','MN'),('US','ILM','Wilmington','Wilmington','NC'),('US','ILN','Wilmington','Wilmington','OH'),('US','ILO','Lodi','Lodi','WI'),('US','ILP','Illiopolis','Illiopolis','IL'),('US','ILR','Millersport','Millersport','OH'),('US','ILS','Wills Point','Wills Point','TX'),('US','ILT','Manito','Manito','IL'),('US','ILU','Buda','Buda','IL'),('US','ILV','Silvis','Silvis','IL'),('US','ILY','Baileyville','Baileyville','ME'),('US','IMA','Marion','Marion','WI'),('US','IME','Wilmerding','Wilmerding','PA'),('US','IMG','Wilmington','Wilmington','VA'),('US','IMK','Mokena','Mokena','IL'),('US','IML','Imperial','Imperial','NE'),('US','IMM','Immokalee','Immokalee','FL'),('US','IMO','Monona','Monona','WI'),('US','IMP','Imperial','Imperial','PA'),('US','IMR','Imperial','Imperial','MO'),('US','IMS','Williams','Williams','MN'),('US','IMT','Iron Mountain','Iron Mountain','MI'),('US','IMW','Miamitown','Miamitown','OH'),('US','IMX','Climax','Climax','GA'),('US','INA','Institute','Institute','WV'),('US','INB','Windsor, Bertie','Windsor, Bertie','NC'),('US','INC','Lincoln','Lincoln','AR'),('US','IND','Indianapolis','Indianapolis','IN'),('US','INE','Independence','Independence','IA'),('US','INF','Winfield','Winfield','TX'),('US','ING','Inglewood','Inglewood','CA'),('US','INH','Shelby','Shelby','IN'),('US','INI','Indianola','Indianola','FL'),('US','INJ','Iselin','Iselin','NJ'),('US','INK','Wink','Wink','TX'),('US','INL','International Falls','International Falls','MN'),('US','INM','Inman','Inman','SC'),('US','INN','Lincoln','Lincoln','AL'),('US','INO','Inwood','Inwood','NY'),('US','INP','Independence','Independence','KY'),('US','INQ','Monroe','Monroe','IN'),('US','INR','Shiner','Shiner','TX'),('US','INS','Indian Springs','Indian Springs','NV'),('US','INT','Winston Salem','Winston Salem','NC'),('US','INU','Industry','Industry','PA'),('US','INV','Madisonville','Madisonville','LA'),('US','INW','Winslow','Winslow','AZ'),('US','INX','Mosinee','Mosinee','WI'),('US','INY','Saint Marys','Saint Marys','IN'),('US','IO2','Indian Orchard','Indian Orchard','MA'),('US','IOA','Arion','Arion','IA'),('US','IOC','Indio','Indio','CA'),('US','IOD','Wildwood','Wildwood','PA'),('US','IOL','Iola','Iola','KS'),('US','ION','Ione','Ione','CA'),('US','IOO','Millwood','Millwood','KY'),('US','IOP','Isle of Palms','Isle of Palms','SC'),('US','IOR','Samoa','Samoa','CA'),('US','IOW','Iowa City','Iowa City','IA'),('US','IPA','Irwin','Irwin','PA'),('US','IPC','Independence','Independence','LA'),('US','IPD','Independence','Independence','OH'),('US','IPE','Perry','Perry','MI'),('US','IPK','Iowa Park','Iowa Park','TX'),('US','IPM','Independence','Independence','MO'),('US','IPO','Paoli','Paoli','IN'),('US','IPR','Millport','Millport','AL'),('US','IPS','Minneapolis','Minneapolis','KS'),('US','IPT','Williamsport','Williamsport','PA'),('US','IPW','Ipswich','Ipswich','MA'),('US','IQH','Issaquah','Issaquah','WA'),('US','IR2','Indian River City','Indian River City','FL'),('US','IRA','Citra','Citra','FL'),('US','IRB','Iraan','Iraan','TX'),('US','IRC','Circle','Circle','AK'),('US','IRD','Irwindale','Irwindale','CA'),('US','IRE','Siren','Siren','WI'),('US','IRF','Irvona','Irvona','PA'),('US','IRG','Irvington','Irvington','CA'),('US','IRH','Firth','Firth','NE'),('US','IRI','White River','White River','SD'),('US','IRJ','Irvington','Irvington','NJ'),('US','IRK','Kirksville','Kirksville','MO'),('US','IRL','Mirror Lake','Mirror Lake','NH'),('US','IRM','Irmo','Irmo','SC'),('US','IRN','Ironton','Ironton','OH'),('US','IRO','Irondale','Irondale','CO'),('US','IRR','Irrigon','Irrigon','OR'),('US','IRS','Sturgis','Sturgis','MI'),('US','IRT','Irving','Irving','TX'),('US','IRV','Irving','Irving','PA'),('US','IRW','Iron River','Iron River','MI'),('US','IRY','Iron City','Iron City','TN'),('US','IRZ','Irvington','Irvington','AL'),('US','IS2','Iron Station','Iron Station','NC'),('US','ISA','Isola','Isola','MS'),('US','ISB','Ishpeming','Ishpeming','MI'),('US','ISE','Millersville','Millersville','PA'),('US','ISF','Blissfield','Blissfield','OH'),('US','ISH','Sharon','Sharon','WI'),('US','ISI','Isanti','Isanti','MN'),('US','ISL','Isabel Pass','Isabel Pass','AK'),('US','ISM','Kissimmee','Kissimmee','FL'),('US','ISN','Williston','Williston','ND'),('US','ISO','Kinston','Kinston','NC'),('US','ISP','Islip','Islip','NY'),('US','ISQ','Manistique','Manistique','MI'),('US','ISR','Islamorada','Islamorada','FL'),('US','ISS','Wiscasset','Wiscasset','ME'),('US','IST','Sistersville','Sistersville','WV'),('US','ISU','Salisbury','Salisbury','MO'),('US','ISV','Sissonville','Sissonville','WV'),('US','ISW','Wisconsin Rapids','Wisconsin Rapids','WI'),('US','ITA','Ithaca','Ithaca','MI'),('US','ITD','Crittenden','Crittenden','KY'),('US','ITE','Whitsett','Whitsett','NC'),('US','ITH','Ithaca','Ithaca','NY'),('US','ITL','Whiteland','Whiteland','IN'),('US','ITN','Smithton','Smithton','PA'),('US','ITO','Hilo','Hilo','HI'),('US','ITP','Waite Park','Waite Park','MN'),('US','ITR','Indian Trail','Indian Trail','NC'),('US','ITS','Itasca','Itasca','IL'),('US','ITT','Pittsfield','Pittsfield','NH'),('US','ITV','Pittsville','Pittsville','WI'),('US','ITW','Morristown','Morristown','OH'),('US','ITY','Story City','Story City','IA'),('US','IUA','Urbana','Urbana','IN'),('US','IUK','Iuka','Iuka','MS'),('US','IV2','Iva','Iva','SC'),('US','IVA','Isle','Isle','MN'),('US','IVE','Shively','Shively','KY'),('US','IVF','Ivorydale','Ivorydale','OH'),('US','IVG','Incline Village','Incline Village','NV'),('US','IVH','Ivishak','Ivishak','AK'),('US','IVK','Irvine','Irvine','KY'),('US','IVL','Blairsville','Blairsville','GA'),('US','IVN','Irvine','Irvine','CA'),('US','IVO','Ivanhoe','Ivanhoe','CA'),('US','IVP','Silver Peak','Silver Peak','NV'),('US','IVR','Inverness','Inverness','MS'),('US','IVT','Irvington','Irvington','NY'),('US','IVV','Inver Grove Heights','Inver Grove Heights','MN'),('US','IVY','Ivyland','Ivyland','PA'),('US','IWD','Ironwood','Ironwood','MI'),('US','IWE','Weston','Weston','MI'),('US','IWO','Birchwood','Birchwood','WI'),('US','IWV','Inwood','Inwood','WV'),('US','IWY','Midway','Midway','AR'),('US','IYK','Inyokern','Inyokern','CA'),('US','IYN','Ivoryton','Ivoryton','CT'),('US','JAA','Jackson','Jackson','MO'),('US','JAC','Jackson','Jackson','WY'),('US','JAE','Jane Lew','Jane Lew','WV'),('US','JAK','Jackson','Jackson','OH'),('US','JAM','Jackman','Jackman','ME'),('US','JAN','Jackson','Jackson','MS'),('US','JAO','Jacksonville','Jacksonville','AL'),('US','JAP','Jasper','Jasper','IN'),('US','JAR','Arcadia','Arcadia','CA'),('US','JAS','Jasper','Jasper','TX'),('US','JAT','Jamestown','Jamestown','NC'),('US','JAV','Janesville','Janesville','IA'),('US','JAW','Jackson','Jackson','WI'),('US','JAX','Jacksonville','Jacksonville','FL'),('US','JAY','Jay','Jay','ME'),('US','JB2','Juno Beach','Juno Beach','FL'),('US','JBC','Jensen Beach','Jensen Beach','FL'),('US','JBE','Belle','Belle','MO'),('US','JBK','Berkeley','Berkeley','CA'),('US','JBN','Blanca','Blanca','CO'),('US','JBO','Jonesboro','Jonesboro','GA'),('US','JBR','Jonesboro','Jonesboro','AR'),('US','JBS','Pleasanton','Pleasanton','CA'),('US','JBY','St Johnsbury','St Johnsbury','VT'),('US','JCC','Junction City','Junction City','KS'),('US','JCE','Corinne','Corinne','UT'),('US','JCI','Johnson City','Johnson City','TN'),('US','JCK','Jack','Jack','AL'),('US','JCL','Clinton','Clinton','UT'),('US','JCN','Jefferson City','Jefferson City','TN'),('US','JCR','Jackson Center','Jackson Center','OH'),('US','JCS','Jackson','Jackson','PA'),('US','JCT','Junction','Junction','TX'),('US','JCX','Jacinto City','Jacinto City','TX'),('US','JCY','Johnson City','Johnson City','TX'),('US','JDA','John Day','John Day','OR'),('US','JDN','Jordan','Jordan','MT'),('US','JDY','Downey','Downey','CA'),('US','JEA','Jeannette','Jeannette','PA'),('US','JEC','Jersey City','Jersey City','NJ'),('US','JED','Jefferson Island','Jefferson Island','LA'),('US','JEE','Jeffersonville','Jeffersonville','PA'),('US','JEF','Jefferson City','Jefferson City','MO'),('US','JEI','Jeffersonville','Jeffersonville','NY'),('US','JEM','Emeryville','Emeryville','CA'),('US','JEN','Jennings','Jennings','LA'),('US','JEO','Jefferson','Jefferson','TX'),('US','JEP','Jessup','Jessup','PA'),('US','JER','Jerome','Jerome','ID'),('US','JES','Jesup','Jesup','GA'),('US','JET','Jeffersontown','Jeffersontown','KY'),('US','JEV','Jeffersonville','Jeffersonville','GA'),('US','JEW','Jewell','Jewell','IA'),('US','JF2','Jefferson, Jackson','Jefferson, Jackson','GA'),('US','JFE','Jefferson','Jefferson','IN'),('US','JFF','Jefferson','Jefferson','LA'),('US','JFG','Jefferson','Jefferson','GA'),('US','JFJ','Jefferson Junction','Jefferson Junction','WI'),('US','JFK','John F. Kennedy Apt/New York','John F. Kennedy Apt/New York','NY'),('US','JFL','Jefferson','Jefferson','MS'),('US','JFN','Jefferson','Jefferson','OH'),('US','JFO','Jeffersonville','Jeffersonville','OH'),('US','JFS','Jefferson','Jefferson','WI'),('US','JFV','Jeffersonville','Jeffersonville','IN'),('US','JGC','Grove City','Grove City','OH'),('US','JGE','Jean','Jean','NV'),('US','JGX','Glendale','Glendale','CA'),('US','JHB','Johnsonburg','Johnsonburg','PA'),('US','JHC','Garden City','Garden City','NY'),('US','JHE','Johnston','Johnston','SC'),('US','JHM','Kapalua','Kapalua','HI'),('US','JHN','Johnston','Johnston','OH'),('US','JHS','Johnston','Johnston','IA'),('US','JHV','Johnsonville','Johnsonville','SC'),('US','JHW','Jamestown','Jamestown','NY'),('US','JHY','Cambridge','Cambridge','MA'),('US','JID','City of Industry','City of Industry','CA'),('US','JIS','Johns Island','Johns Island','SC'),('US','JKB','Jacksonboro','Jacksonboro','SC'),('US','JKG','Jackson','Jackson','GA'),('US','JKH','Jackson Heights','Jackson Heights','NY'),('US','JKS','Jackson','Jackson','AL'),('US','JKT','Jenkintown','Jenkintown','PA'),('US','JKV','Jacksonville','Jacksonville','TX'),('US','JL2','Juliette','Juliette','GA'),('US','JLA','Cooper Lodge','Cooper Lodge','AK'),('US','JLC','Jellico','Jellico','TN'),('US','JLH','Arlington Heights','Arlington Heights','IL'),('US','JLM','Arcadia','Arcadia','IN'),('US','JLN','Joplin','Joplin','MO'),('US','JLX','Jonesville','Jonesville','LA'),('US','JLY','Lake City','Lake City','GA'),('US','JMB','Jamesburg','Jamesburg','NJ'),('US','JMC','Sausalito','Sausalito','CA'),('US','JMH','Schaumburg','Schaumburg','IL'),('US','JMI','Medicine Lodge','Medicine Lodge','KS'),('US','JMP','Jamesport','Jamesport','MO'),('US','JMS','Jamestown','Jamestown','ND'),('US','JMT','Jamestown','Jamestown','KY'),('US','JMV','Jamesville','Jamesville','VA'),('US','JMW','Jamestown','Jamestown','CA'),('US','JN2','Jourdanton','Jourdanton','TX'),('US','JN3','Jordan, Scott','Jordan, Scott','MN'),('US','JNA','Jena','Jena','LA'),('US','JNC','Junction City','Junction City','GA'),('US','JNJ','Orange','Orange','NJ'),('US','JNP','Newport Beach','Newport Beach','CA'),('US','JNS','Jenison','Jenison','MI'),('US','JNT','Jonestown','Jonestown','PA'),('US','JNU','Juneau','Juneau','AK'),('US','JNY','Johnson','Johnson','NY'),('US','JOA','Johnson','Johnson','AR'),('US','JOC','Johnson City','Johnson City','OR'),('US','JOE','Jonesville','Jonesville','MI'),('US','JOI','Jonesville','Jonesville','NC'),('US','JOL','Jonesville','Jonesville','SC'),('US','JON','Jonesport','Jonesport','ME'),('US','JOO','Jonesboro','Jonesboro','TN'),('US','JOP','Joppa','Joppa','MD'),('US','JOQ','San Joaquin','San Joaquin','CA'),('US','JOR','Orange','Orange','CA'),('US','JOS','Johnston','Johnston','RI'),('US','JOT','Joliet','Joliet','IL'),('US','JOW','Johnstown','Johnstown','OH'),('US','JOY','Johnson City','Johnson City','NY'),('US','JPA','Joppa','Joppa','IL'),('US','JPB','San Juan Pueblo','San Juan Pueblo','NM'),('US','JPE','Jasper','Jasper','MO'),('US','JPG','Prince George','Prince George','VA'),('US','JPR','Jasper','Jasper','AR'),('US','JPT','Jupiter','Jupiter','FL'),('US','JQK','Jacksboro','Jacksboro','TN'),('US','JQS','Jacksonville','Jacksonville','NJ'),('US','JRB','North Arab','North Arab','AL'),('US','JRI','Jericho','Jericho','NY'),('US','JRM','Jerome','Jerome','IN'),('US','JRO','Jacksboro','Jacksboro','TX'),('US','JS2','Jackson','Jackson','CA'),('US','JS3','Jackson','Jackson','KY'),('US','JS4','Johnston','Johnston','PA'),('US','JSA','Judsonia','Judsonia','AR'),('US','JSD','Stratford','Stratford','CT'),('US','JSG','Jarvisburg','Jarvisburg','NC'),('US','JSI','Justin','Justin','TX'),('US','JSL','Joslin','Joslin','IL'),('US','JSP','Jasper','Jasper','AL'),('US','JST','Johnstown','Johnstown','PA'),('US','JSV','Janesville','Janesville','MN'),('US','JSY','St James City','St James City','FL'),('US','JTA','Montana City','Montana City','MT'),('US','JTE','Jeanerette','Jeanerette','LA'),('US','JTN','Josephtown','Josephtown','PA'),('US','JTO','Thousand Oaks','Thousand Oaks','CA'),('US','JTT','Jewett','Jewett','TX'),('US','JTW','Johnstown','Johnstown','NY'),('US','JTX','Joshua','Joshua','TX'),('US','JUC','Junction City, Perry','Junction City, Perry','OH'),('US','JUD','Juda','Juda','WI'),('US','JUK','Jenks','Jenks','OK'),('US','JUN','Junction City','Junction City','OR'),('US','JV2','Jacksonville','Jacksonville','TN'),('US','JV3','Jollyville','Jollyville','TX'),('US','JVA','North Java','North Java','WY'),('US','JVI','Manville','Manville','NJ'),('US','JVL','Janesville','Janesville','WI'),('US','JWL','Jewell','Jewell','KS'),('US','JWT','Jewett City','Jewett City','CT'),('US','JXI','James Island','James Island','SC'),('US','JXN','Jackson','Jackson','MI'),('US','JY2','Jolly','Jolly','TX'),('US','KAD','Oakland, Fayette','Oakland, Fayette','TN'),('US','KAE','Kake','Kake','AK'),('US','KAG','Kaguyak','Kaguyak','AK'),('US','KAH','Kenmore/Seattle','Kenmore/Seattle','WA'),('US','KAI','Kaiser','Kaiser','CA'),('US','KAL','Kaltag','Kaltag','AK'),('US','KAM','Kalama','Kalama','WA'),('US','KAN','Kane','Kane','PA'),('US','KAO','Kanosh','Kanosh','UT'),('US','KAP','Knapp','Knapp','WI'),('US','KAT','Katonah','Katonah','NY'),('US','KAU','Kaukauna','Kaukauna','WI'),('US','KAV','Kaneville','Kaneville','IL'),('US','KAY','Kaysville','Kaysville','UT'),('US','KB2','Kingsbury','Kingsbury','IN'),('US','KBA','Kings Bay','Kings Bay','FL'),('US','KBC','Birch Creek','Birch Creek','AK'),('US','KBE','Bell Island','Bell Island','AK'),('US','KBG','Kingsburg','Kingsburg','CA'),('US','KBJ','Kings Beach','Kings Beach','CA'),('US','KBK','Klag Bay','Klag Bay','AK'),('US','KBL','Kimberly','Kimberly','WI'),('US','KBN','Kennebunk','Kennebunk','ME'),('US','KBS','Key Biscayne','Key Biscayne','FL'),('US','KBU','Keithsburg','Keithsburg','IL'),('US','KBY','Boykin','Boykin','GA'),('US','KCC','Coffman Cove','Coffman Cove','AK'),('US','KCK','Kansas City','Kansas City','KS'),('US','KCL','Chignik','Chignik','AK'),('US','KCM','Chatom','Chatom','AL'),('US','KCN','Chernofski','Chernofski','AK'),('US','KCO','East Stockton','East Stockton','CA'),('US','KCQ','Kirtland','Kirtland','OH'),('US','KCR','Colorado Creek','Colorado Creek','AK'),('US','KCS','Kings Creek','Kings Creek','SC'),('US','KCT','Kent City','Kent City','MI'),('US','KCY','King City','King City','OR'),('US','KCZ','Karns City','Karns City','PA'),('US','KDA','Kodak','Kodak','TN'),('US','KDE','Cade','Cade','LA'),('US','KDL','Kendall','Kendall','LA'),('US','KDR','Kendrick','Kendrick','ID'),('US','KDV','Kendallville','Kendallville','IN'),('US','KDY','Kenedy','Kenedy','TX'),('US','KEA','Keasbey','Keasbey','NJ'),('US','KEB','English Bay','English Bay','AK'),('US','KEC','Kellogg','Kellogg','IA'),('US','KED','Kennedale','Kennedale','TX'),('US','KEE','Keyesport','Keyesport','IL'),('US','KEG','Kenbridge','Kenbridge','VA'),('US','KEH','Kenmore Air Harbor','Kenmore Air Harbor','WA'),('US','KEI','Kiel','Kiel','WI'),('US','KEK','Ekwok','Ekwok','AK'),('US','KEL','Kendall','Kendall','FL'),('US','KEM','Kemah','Kemah','TX'),('US','KEN','Kensington','Kensington','GA'),('US','KEO','Kenton','Kenton','MI'),('US','KER','Hunker','Hunker','PA'),('US','KES','Kenner','Kenner','LA'),('US','KET','Kent','Kent','WA'),('US','KEU','Kelly Bar','Kelly Bar','AK'),('US','KEV','Keysville','Keysville','VA'),('US','KEW','Kewanee','Kewanee','IL'),('US','KEX','Keller','Keller','TX'),('US','KEY','Keyport','Keyport','NJ'),('US','KFA','Kaufman','Kaufman','TX'),('US','KFD','Kingsford','Kingsford','MI'),('US','KFE','Kiefer','Kiefer','OK'),('US','KFI','Fiskeville','Fiskeville','RI'),('US','KFO','Kasilof','Kasilof','AK'),('US','KFP','False Pass','False Pass','AK'),('US','KG2','Kew Gardens, Queens','Kew Gardens, Queens','NY'),('US','KG3','King','King','WI'),('US','KGB','Stockbridge','Stockbridge','VT'),('US','KGD','Kingwood','Kingwood','WV'),('US','KGE','Kingdom City','Kingdom City','MO'),('US','KGI','Kellogg','Kellogg','ID'),('US','KGK','New Koliganek','New Koliganek','AK'),('US','KGM','Kings Mills','Kings Mills','OH'),('US','KGN','Kingston','Kingston','MA'),('US','KGR','Kilgore','Kilgore','TX'),('US','KGS','Kingstree','Kingstree','SC'),('US','KGT','Kingston','Kingston','NY'),('US','KGX','Grayling','Grayling','AK'),('US','KGZ','Glacier Creek','Glacier Creek','AK'),('US','KH2','Kahoka','Kahoka','MO'),('US','KHA','Brookhaven','Brookhaven','PA'),('US','KHE','Kaneohe','Kaneohe','HI'),('US','KHH','Kailua Kona','Kailua Kona','HI'),('US','KHX','Karthaus','Karthaus','PA'),('US','KIA','Kiawah Island','Kiawah Island','SC'),('US','KIB','Ivanof Bay','Ivanof Bay','AK'),('US','KIC','King City','King City','CA'),('US','KID','Kidron','Kidron','OH'),('US','KIE','Lakeville','Lakeville','NY'),('US','KIF','Kingfisher','Kingfisher','OK'),('US','KIG','King','King','NC'),('US','KIH','Kihei','Kihei','HI'),('US','KIK','Killbuck','Killbuck','OH'),('US','KIL','Killingly','Killingly','CT'),('US','KIM','Kimberton','Kimberton','PA'),('US','KIN','Kings Mountain','Kings Mountain','NC'),('US','KIO','Kinwood','Kinwood','TX'),('US','KIR','Kirkwood','Kirkwood','NY'),('US','KIS','Kiska Island','Kiska Island','AK'),('US','KIU','Kiln','Kiln','MS'),('US','KIW','Kingwood','Kingwood','TX'),('US','KIY','Kimberly','Kimberly','ID'),('US','KK2','Kealakekua','Kealakekua','HI'),('US','KK3','Krakow','Krakow','WI'),('US','KKA','Koyuk','Koyuk','AK'),('US','KKB','Kitoi Bay','Kitoi Bay','AK'),('US','KKF','Kagvik Creek','Kagvik Creek','AK'),('US','KKH','Kongiganak','Kongiganak','AK'),('US','KKI','Akiachak','Akiachak','AK'),('US','KKK','Kalakaket','Kalakaket','AK'),('US','KKL','Karluk Lake','Karluk Lake','AK'),('US','KKT','Kentland','Kentland','IN'),('US','KKU','Ekuk','Ekuk','AK'),('US','KL2','Knobel','Knobel','AR'),('US','KLA','Rockland','Rockland','NY'),('US','KLC','Lake City','Lake City','KS'),('US','KLD','Kalida','Kalida','OH'),('US','KLE','Parkville','Parkville','MO'),('US','KLG','Kalskag','Kalskag','AK'),('US','KLI','Killen','Killen','AL'),('US','KLK','Kalkaska','Kalkaska','MI'),('US','KLL','Levelock','Levelock','AK'),('US','KLN','Larsen Bay','Larsen Bay','AK'),('US','KLO','Kellogg','Kellogg','OR'),('US','KLP','Kelp Bay','Kelp Bay','AK'),('US','KLS','Kelso','Kelso','WA'),('US','KLV','Kettlersville','Kettlersville','OH'),('US','KLW','Klawock','Klawock','AK'),('US','KM2','Kamiah','Kamiah','ID'),('US','KM3','Kremmling','Kremmling','CO'),('US','KM4','Kimball','Kimball','MN'),('US','KMI','Lake Mills','Lake Mills','IA'),('US','KML','Kremlin','Kremlin','MT'),('US','KMN','Kinsman, Belmont','Kinsman, Belmont','OH'),('US','KMO','Manokotak','Manokotak','AK'),('US','KMQ','Kerman','Kerman','CA'),('US','KMR','Kenmore','Kenmore','NY'),('US','KMT','Kingsmountain','Kingsmountain','NC'),('US','KMY','Moser Bay','Moser Bay','AK'),('US','KN2','Keene','Keene','TX'),('US','KN3','Kenly','Kenly','NC'),('US','KNA','Keenan','Keenan','TX'),('US','KNB','Kanab','Kanab','UT'),('US','KNC','Hopkins','Hopkins','SC'),('US','KND','Oakland','Oakland','OR'),('US','KNE','Skaneateles','Skaneateles','NY'),('US','KNG','Kingman','Kingman','IN'),('US','KNI','Knightdale','Knightdale','NC'),('US','KNJ','Kingston','Kingston','NJ'),('US','KNK','Kakhonak','Kakhonak','AK'),('US','KNL','Kingsland','Kingsland','GA'),('US','KNM','Kingman','Kingman','KS'),('US','KNN','Kennett Square','Kennett Square','PA'),('US','KNO','Kenton','Kenton','OH'),('US','KNP','Kannapolis','Kannapolis','NC'),('US','KNQ','Kenton','Kenton','TN'),('US','KNS','Kingston','Kingston','PA'),('US','KNT','Kennett','Kennett','MO'),('US','KNU','Kentwood','Kentwood','LA'),('US','KNV','Kenansville','Kenansville','NC'),('US','KNW','New Stuyahok','New Stuyahok','AK'),('US','KNX','Knox','Knox','IN'),('US','KNY','McKinleyville','McKinleyville','CA'),('US','KO2','Kootenai','Kootenai','ID'),('US','KOD','Rockford','Rockford','MN'),('US','KON','Killona','Killona','LA'),('US','KOO','Rockwood','Rockwood','IL'),('US','KOR','Kohler','Kohler','WI'),('US','KOT','Kotlik','Kotlik','AK'),('US','KOY','Olga Bay','Olga Bay','AK'),('US','KOZ','Ouzinkie','Ouzinkie','AK'),('US','KP2','Knippa','Knippa','TX'),('US','KPA','Lake Park','Lake Park','GA'),('US','KPB','Point Baker','Point Baker','AK'),('US','KPC','Pt Clarence','Pt Clarence','AK'),('US','KPD','King of Prussia','King of Prussia','PA'),('US','KPH','Pauloff Harbor','Pauloff Harbor','AK'),('US','KPK','Parks','Parks','AK'),('US','KPL','Kaplan','Kaplan','LA'),('US','KPN','Kipnuk','Kipnuk','AK'),('US','KPP','Koppel','Koppel','PA'),('US','KPT','Jackpot','Jackpot','NV'),('US','KPV','Perryville','Perryville','AK'),('US','KPY','Pt Bailey','Pt Bailey','AK'),('US','KQA','Akutan','Akutan','AK'),('US','KQO','Kailua (Oahu)','Kailua (Oahu)','HI'),('US','KR2','Kilmanrock','Kilmanrock','VA'),('US','KRN','Kernersville','Kernersville','NC'),('US','KRP','Kreamer','Kreamer','PA'),('US','KRT','Stryker','Stryker','OH'),('US','KRW','Kershaw','Kershaw','SC'),('US','KRZ','Kirkwood','Kirkwood','PA'),('US','KS2','Kasota','Kasota','MN'),('US','KS3','Kingston Springs','Kingston Springs','TN'),('US','KS4','Keystone','Keystone','WV'),('US','KSA','Kinsman, Trumbull','Kinsman, Trumbull','OH'),('US','KSH','Hooksett','Hooksett','NH'),('US','KSI','Lakeside','Lakeside','CA'),('US','KSL','Brooksville','Brooksville','MS'),('US','KSM','St Marys','St Marys','AK'),('US','KSN','Kingston','Kingston','NY'),('US','KSO','Kingston','Kingston','RI'),('US','KSP','Kings Park','Kings Park','NY'),('US','KSR','Sandy River','Sandy River','AK'),('US','KST','Kosse','Kosse','TX'),('US','KSV','Kansasville','Kansasville','WI'),('US','KSW','Kennesaw','Kennesaw','GA'),('US','KT5','Kingston','Kingston','NH'),('US','KTB','Thorne Bay','Thorne Bay','AK'),('US','KTG','Kittanning','Kittanning','PA'),('US','KTH','Tikchik','Tikchik','AK'),('US','KTN','Ketchikan','Ketchikan','AK'),('US','KTO','Kent','Kent','OH'),('US','KTP','Kensington','Kensington','PA'),('US','KTQ','Kingston','Kingston','TN'),('US','KTR','Kettering','Kettering','OH'),('US','KTS','Teller Mission','Teller Mission','AK'),('US','KTT','Kitty Hawk','Kitty Hawk','NC'),('US','KTW','Smoketown','Smoketown','PA'),('US','KTX','Katy','Katy','TX'),('US','KUA','Kaunakakai (Molokai)','Kaunakakai (Molokai)','HI'),('US','KUI','Kailua (Maui)','Kailua (Maui)','HI'),('US','KUK','Kasigluk','Kasigluk','AK'),('US','KUL','Kulpmont','Kulpmont','PA'),('US','KUP','Kulpsville','Kulpsville','PA'),('US','KUR','Currie','Currie','NC'),('US','KUT','Kutztown','Kutztown','PA'),('US','KUW','Kugururok River','Kugururok River','AK'),('US','KUY','Uyak','Uyak','AK'),('US','KV2','Keithville','Keithville','LA'),('US','KV3','Kelseyville','Kelseyville','CA'),('US','KV4','Kennedyville','Kennedyville','MD'),('US','KV5','Kenvil','Kenvil','NJ'),('US','KVA','Kenova','Kenova','WV'),('US','KVC','King Cove','King Cove','AK'),('US','KVE','Stokesdale','Stokesdale','NC'),('US','KVI','Clarksville','Clarksville','MD'),('US','KVL','Kivalina','Kivalina','AK'),('US','KVN','La Vale','La Vale','MD'),('US','KW2','Konawa','Konawa','OK'),('US','KWA','Kiowa','Kiowa','OK'),('US','KWC','Kennewick','Kennewick','WA'),('US','KWD','Kentwood','Kentwood','MI'),('US','KWE','Rockwell','Rockwell','NC'),('US','KWF','Waterfall','Waterfall','AK'),('US','KWH','Kawaihae','Kawaihae','HI'),('US','KWI','Kewaskum','Kewaskum','WI'),('US','KWK','Kwigillingok','Kwigillingok','AK'),('US','KWM','King William','King William','VA'),('US','KWN','Quinhagak','Quinhagak','AK'),('US','KWO','Kenilworth','Kenilworth','NJ'),('US','KWP','West Point','West Point','AK'),('US','KWT','Kwethluk','Kwethluk','AK'),('US','KXA','Kasaan','Kasaan','AK'),('US','KXC','Kincaid','Kincaid','KS'),('US','KXE','Knoxville','Knoxville','IA'),('US','KXT','West Kingston','West Kingston','RI'),('US','KXV','Knoxville','Knoxville','AR'),('US','KY2','Keymar','Keymar','MD'),('US','KY3','Keyser','Keyser','WV'),('US','KYE','Kearney','Kearney','MO'),('US','KYK','Karluk','Karluk','AK'),('US','KYL','Key Largo','Key Largo','FL'),('US','KYN','Kenyon','Kenyon','RI'),('US','KYO','Kenton','Kenton','OR'),('US','KYS','Keystone','Keystone','CO'),('US','KYU','Koyukuk','Koyukuk','AK'),('US','KYV','Kearneysville','Kearneysville','WV'),('US','KYX','Auxier','Auxier','KY'),('US','KZB','Zachar Bay','Zachar Bay','AK'),('US','KZH','Kizhuyak','Kizhuyak','AK'),('US','KZS','Krotz Springs','Krotz Springs','LA'),('US','KZY','Louisa','Louisa','KY'),('US','LA2','Lake Arrowhead','Lake Arrowhead','CA'),('US','LAA','Lamar','Lamar','CO'),('US','LAB','Laguna Beach','Laguna Beach','CA'),('US','LAC','Lancaster','Lancaster','NY'),('US','LAD','Lauderhill','Lauderhill','FL'),('US','LAE','La Mesa','La Mesa','CA'),('US','LAF','Lafayette','Lafayette','IN'),('US','LAG','Lansing','Lansing','NC'),('US','LAH','Los Altos Hills','Los Altos Hills','CA'),('US','LAI','La Grange','La Grange','IL'),('US','LAJ','L\'Anse','L\'Anse','MI'),('US','LAK','Lady Lake','Lady Lake','FL'),('US','LAL','Lakeland','Lakeland','FL'),('US','LAM','Los Alamos','Los Alamos','NM'),('US','LAN','Lansing','Lansing','MI'),('US','LAO','La Porte','La Porte','IN'),('US','LAP','La Plata','La Plata','MD'),('US','LAQ','Lawrenceburg','Lawrenceburg','KY'),('US','LAR','Laramie','Laramie','WY'),('US','LAS','Las Vegas','Las Vegas','NV'),('US','LAT','Los Alamitos','Los Alamitos','CA'),('US','LAU','Laurier','Laurier','WA'),('US','LAV','Lawrenceville','Lawrenceville','KY'),('US','LAW','Lawton','Lawton','OK'),('US','LAX','Los Angeles','Los Angeles','CA'),('US','LAY','Lacey','Lacey','WA'),('US','LB2','Lubec','Lubec','ME'),('US','LBA','Alabaster','Alabaster','AL'),('US','LBB','Lubbock','Lubbock','TX'),('US','LBC','Lake Bluff','Lake Bluff','IL'),('US','LBD','Lebanon','Lebanon','IN'),('US','LBE','Latrobe','Latrobe','PA'),('US','LBF','North Platte','North Platte','NE'),('US','LBG','Lewisburg','Lewisburg','TN'),('US','LBH','Long Beach','Long Beach','MS'),('US','LBI','Liberty','Liberty','NC'),('US','LBJ','Calabasas','Calabasas','CA'),('US','LBK','Liberty','Liberty','IN'),('US','LBL','Liberal','Liberal','KS'),('US','LBM','Lebanon','Lebanon','MO'),('US','LBN','Lebanon','Lebanon','TN'),('US','LBO','Lebanon','Lebanon','CT'),('US','LBP','Lebanon','Lebanon','PA'),('US','LBQ','Calabash','Calabash','NC'),('US','LBR','Lewisberry','Lewisberry','PA'),('US','LBS','Lumberton','Lumberton','MS'),('US','LBT','Lumberton','Lumberton','NC'),('US','LBU','Lewisburg','Lewisburg','OH'),('US','LBV','Libertyville','Libertyville','IL'),('US','LBW','Lake Buena Vista','Lake Buena Vista','FL'),('US','LBX','Liberty','Liberty','TX'),('US','LBY','Liberty','Liberty','SC'),('US','LBZ','Libby','Libby','MT'),('US','LC2','Loup City','Loup City','NE'),('US','LCA','La Canada-Flintridge','La Canada-Flintridge','CA'),('US','LCB','Lucerne Valley','Lucerne Valley','CA'),('US','LCC','Lucas','Lucas','KS'),('US','LCD','Little Canada','Little Canada','MN'),('US','LCE','Lincoln Center','Lincoln Center','ME'),('US','LCF','Leitchfield','Leitchfield','KY'),('US','LCG','Le Compte','Le Compte','LA'),('US','LCH','Lake Charles','Lake Charles','LA'),('US','LCI','Laconia','Laconia','NH'),('US','LCK','Lockbourne','Lockbourne','OH'),('US','LCL','Lincoln','Lincoln','IL'),('US','LCM','Leicester','Leicester','MA'),('US','LCN','Lincoln','Lincoln','RI'),('US','LCO','Lincolnshire','Lincolnshire','IL'),('US','LCP','Lecompte','Lecompte','LA'),('US','LCQ','Lincoln','Lincoln','MA'),('US','LCR','La Crescenta','La Crescenta','CA'),('US','LCS','Lancaster','Lancaster','MA'),('US','LCT','Lincolnton','Lincolnton','NC'),('US','LCU','Lucedale','Lucedale','MS'),('US','LCV','Black River Falls','Black River Falls','WI'),('US','LCW','Lincolnwood','Lincolnwood','IL'),('US','LCY','Lake City','Lake City','TN'),('US','LCZ','Locust Grove','Locust Grove','GA'),('US','LDA','Lansdale','Lansdale','PA'),('US','LDB','Lindsborg','Lindsborg','KS'),('US','LDC','Old Ocean','Old Ocean','TX'),('US','LDD','Ladd','Ladd','IL'),('US','LDE','Linden','Linden','TN'),('US','LDF','Lamar','Lamar','MO'),('US','LDG','Landenberg','Landenberg','PA'),('US','LDH','Lindenhurst','Lindenhurst','NY'),('US','LDI','Lodi','Lodi','CA'),('US','LDJ','Linden','Linden','NJ'),('US','LDK','Baldwin','Baldwin','LA'),('US','LDL','Lindale','Lindale','GA'),('US','LDM','Ludington','Ludington','MI'),('US','LDN','London','London','OH'),('US','LDO','Langdon','Langdon','ND'),('US','LDP','Portland','Portland','AR'),('US','LDQ','Lead','Lead','SD'),('US','LDR','Landover','Landover','MD'),('US','LDS','Leeds','Leeds','AL'),('US','LDT','Lyndhurst','Lyndhurst','NJ'),('US','LDU','Landrum','Landrum','SC'),('US','LDV','Landisville','Landisville','NJ'),('US','LDW','Lansdowne','Lansdowne','MD'),('US','LDX','Ladonia','Ladonia','TX'),('US','LDY','Ledyard Center','Ledyard Center','CT'),('US','LDZ','Ladson','Ladson','SC'),('US','LE2','Lake Elmo','Lake Elmo','MN'),('US','LE3','Lake Elsinore','Lake Elsinore','CA'),('US','LEA','Leander','Leander','TX'),('US','LEB','Hanover-Lebanon-White River Apt','Hanover-Lebanon-White River Apt','NH'),('US','LEC','Leechburg','Leechburg','PA'),('US','LED','Leeds','Leeds','SC'),('US','LEE','Leesburg','Leesburg','FL'),('US','LEF','Lehigh Acres','Lehigh Acres','FL'),('US','LEG','Lehigh','Lehigh','PA'),('US','LEH','Lee','Lee','MA'),('US','LEI','Lehi','Lehi','UT'),('US','LEJ','Leland','Leland','IA'),('US','LEK','Lake Park','Lake Park','MN'),('US','LEL','Lexington','Lexington','TN'),('US','LEM','Lemmon','Lemmon','SD'),('US','LEN','Lena','Lena','IL'),('US','LEO','Levittown','Levittown','NY'),('US','LEP','Leesport','Leesport','PA'),('US','LEQ','Lewis Center','Lewis Center','OH'),('US','LER','Lenoir','Lenoir','NC'),('US','LES','Leesburg','Leesburg','GA'),('US','LET','Lexington','Lexington','SC'),('US','LEU','Cle Elum','Cle Elum','WA'),('US','LEW','Auburn-Lewiston Apt','Auburn-Lewiston Apt','ME'),('US','LEX','Lexington','Lexington','KY'),('US','LEY','Locust Valley','Locust Valley','NY'),('US','LEZ','Lester','Lester','PA'),('US','LF2','Lafayette','Lafayette','OH'),('US','LF3','Lisbon Falls','Lisbon Falls','ME'),('US','LFA','Lebanon','Lebanon','KY'),('US','LFB','Laughlin Air Force Base','Laughlin Air Force Base','TX'),('US','LFC','Lake Forest','Lake Forest','CA'),('US','LFD','Landis','Landis','NC'),('US','LFE','La Fayette','La Fayette','KY'),('US','LFF','Bluffdale','Bluffdale','UT'),('US','LFG','Lafayette','Lafayette','GA'),('US','LFJ','Little Falls','Little Falls','NJ'),('US','LFK','Lufkin','Lufkin','TX'),('US','LFL','La Belle','La Belle','FL'),('US','LFM','Mansfield','Mansfield','MO'),('US','LFN','Louisburg','Louisburg','NC'),('US','LFO','La Follette','La Follette','TN'),('US','LFP','Laflin','Laflin','PA'),('US','LFQ','Lewisburg','Lewisburg','PA'),('US','LFR','Lake Forest','Lake Forest','IL'),('US','LFS','Little Falls','Little Falls','MN'),('US','LFT','Lafayette','Lafayette','LA'),('US','LFW','Lafayette','Lafayette','NJ'),('US','LFX','La Feria','La Feria','TX'),('US','LFY','Lafayette','Lafayette','CO'),('US','LG2','Lake George','Lake George','NY'),('US','LG3','Lemon Grove','Lemon Grove','CA'),('US','LGA','La Guardia Apt/New York','La Guardia Apt/New York','NY'),('US','LGB','Long Beach','Long Beach','CA'),('US','LGC','La Grange','La Grange','GA'),('US','LGD','La Grande','La Grande','OR'),('US','LGE','Loganville','Loganville','GA'),('US','LGG','Long Grove','Long Grove','IL'),('US','LGH','Laughlin','Laughlin','NV'),('US','LGI','Ligonier','Ligonier','IN'),('US','LGJ','Long Valley','Long Valley','NJ'),('US','LGK','La Grange','La Grange','MO'),('US','LGL','Langley','Langley','WA'),('US','LGN','Lagrange','Lagrange','IN'),('US','LGO','Burlington','Burlington','CO'),('US','LGP','Logansport','Logansport','IN'),('US','LGQ','Largo','Largo','MD'),('US','LGR','La Grange','La Grange','KY'),('US','LGS','Livingston','Livingston','CA'),('US','LGT','Leighton','Leighton','AL'),('US','LGU','Logan','Logan','UT'),('US','LGV','Collegeville','Collegeville','MN'),('US','LGW','Longwood','Longwood','FL'),('US','LGX','La Grange','La Grange','TX'),('US','LGY','Langley','Langley','SC'),('US','LH2','Lafayette Hill','Lafayette Hill','PA'),('US','LH3','Liberty Hill, Milam','Liberty Hill, Milam','TX'),('US','LH4','Lindenhurst','Lindenhurst','IL'),('US','LHA','La Habra, Orange','La Habra, Orange','CA'),('US','LHB','Lost Harbor','Lost Harbor','AK'),('US','LHC','McElhattan','McElhattan','PA'),('US','LHE','Lutherville','Lutherville','MD'),('US','LHF','Litchfield','Litchfield','MN'),('US','LHG','Lehighton','Lehighton','PA'),('US','LHH','Langeloth','Langeloth','PA'),('US','LHI','Laguna Hills','Laguna Hills','CA'),('US','LHJ','Laurel Hill, Lincoln','Laurel Hill, Lincoln','NC'),('US','LHK','Little Hocking','Little Hocking','OH'),('US','LHL','Leachville','Leachville','AR'),('US','LHM','Lake Hamilton','Lake Hamilton','FL'),('US','LHN','Lahaina','Lahaina','HI'),('US','LHO','Lehigh Valley','Lehigh Valley','PA'),('US','LHS','Lithia Springs','Lithia Springs','GA'),('US','LHT','Letohatchee','Letohatchee','LA'),('US','LHV','Lock Haven','Lock Haven','PA'),('US','LHW','Lake Hiawatha','Lake Hiawatha','NJ'),('US','LHY','Locust Hill, Middlesex','Locust Hill, Middlesex','VA'),('US','LIA','Lima','Lima','OH'),('US','LIB','Liberty','Liberty','MO'),('US','LIC','Limon','Limon','CO'),('US','LID','Lindale','Lindale','TX'),('US','LIE','Lindside','Lindside','WV'),('US','LIF','Littlefield','Littlefield','TX'),('US','LIG','Ligonier','Ligonier','PA'),('US','LIH','Kauai Island Apt','Kauai Island Apt','HI'),('US','LII','Los Indios','Los Indios','TX'),('US','LIJ','Long Island','Long Island','AK'),('US','LIK','St Clair, Franklin','St Clair, Franklin','MO'),('US','LIL','Lakeville','Lakeville','MA'),('US','LIM','Milan','Milan','OH'),('US','LIN','Lionville','Lionville','PA'),('US','LIO','Lithonia','Lithonia','GA'),('US','LIP','Lincoln Park','Lincoln Park','MI'),('US','LIQ','Linesville','Linesville','PA'),('US','LIR','Lanier','Lanier','GA'),('US','LIS','Listerhill','Listerhill','AL'),('US','LIT','Little Rock','Little Rock','AR'),('US','LIU','Lihue (Kauai)','Lihue (Kauai)','HI'),('US','LIV','Livengood','Livengood','AK'),('US','LIW','Linwood','Linwood','PA'),('US','LIX','Livingston','Livingston','TX'),('US','LIY','Hinesville','Hinesville','GA'),('US','LIZ','Limestone','Limestone','ME'),('US','LJA','Cordelia','Cordelia','CA'),('US','LJB','Lisbon','Lisbon','NH'),('US','LJH','La Junta','La Junta','CO'),('US','LJK','Lakewood','Lakewood','CO'),('US','LJL','La Jolla','La Jolla','CA'),('US','LJN','Lake Jackson','Lake Jackson','TX'),('US','LJV','Lewisville','Lewisville','TX'),('US','LJW','Lowell','Lowell','WI'),('US','LK2','Lake Katerine','Lake Katerine','NY'),('US','LKA','Lake Alfred','Lake Alfred','FL'),('US','LKB','Lake City','Lake City','FL'),('US','LKC','Lake City','Lake City','SC'),('US','LKD','Lakewood','Lakewood','OH'),('US','LKE','Lake City','Lake City','MN'),('US','LKF','Little Lake','Little Lake','CA'),('US','LKG','Lakeland','Lakeland','GA'),('US','LKH','Lake Harbor','Lake Harbor','FL'),('US','LKI','Lake In The Hills','Lake In The Hills','IL'),('US','LKK','Kulik Lake','Kulik Lake','AK'),('US','LKL','Lockland','Lockland','OH'),('US','LKM','Lake Mary','Lake Mary','FL'),('US','LKN','Lumpkin','Lumpkin','GA'),('US','LKO','Lake Norden','Lake Norden','SD'),('US','LKP','Lake Placid','Lake Placid','NY'),('US','LKQ','Lexington','Lexington','OH'),('US','LKR','Walker','Walker','MI'),('US','LKS','Lakeside','Lakeside','TX'),('US','LKT','Lake Station','Lake Station','IN'),('US','LKU','Lake Almanor','Lake Almanor','CA'),('US','LKV','Lakeview','Lakeview','OR'),('US','LKW','Lakewood','Lakewood','NJ'),('US','LKX','Lakeview','Lakeview','GA'),('US','LKY','Lakewood','Lakewood','NY'),('US','LKZ','Lake Zurich','Lake Zurich','IL'),('US','LL2','Llano','Llano','TX'),('US','LL3','Loma Linda','Loma Linda','CA'),('US','LL4','Luttrell, Union','Luttrell, Union','TN'),('US','LLA','Leola','Leola','PA'),('US','LLB','Lino Lakes','Lino Lakes','MN'),('US','LLC','Leland','Leland','NC'),('US','LLD','Leland','Leland','MS'),('US','LLE','Long Lake','Long Lake','MN'),('US','LLF','Little Falls','Little Falls','NY'),('US','LLG','Lilburn','Lilburn','GA'),('US','LLH','Dulles','Dulles','VA'),('US','LLI','Lovelady','Lovelady','TX'),('US','LLJ','Gordonville','Gordonville','KY'),('US','LLK','Liberty Lake','Liberty Lake','WA'),('US','LLL','Lillington','Lillington','NC'),('US','LLM','Stillmore','Stillmore','GA'),('US','LLN','Lincoln','Lincoln','CA'),('US','LLO','Lordstown','Lordstown','OH'),('US','LLP','Long Prairie','Long Prairie','MN'),('US','LLQ','Lowland','Lowland','TN'),('US','LLR','Dell','Dell','AR'),('US','LLS','Land O\' Lakes','Land O\' Lakes','WI'),('US','LLT','Los Altos','Los Altos','CA'),('US','LLU','Los Lunas','Los Lunas','NM'),('US','LLV','Lovell','Lovell','WY'),('US','LLW','Ludlow','Ludlow','KY'),('US','LLX','Lyndonville','Lyndonville','VT'),('US','LLY','Mt Holly','Mt Holly','NJ'),('US','LLZ','Levelland','Levelland','TX'),('US','LM2','Lamont','Lamont','MS'),('US','LM3','Leoma','Leoma','TN'),('US','LM4','Livingston Manor','Livingston Manor','NY'),('US','LMA','Lake Minchumina','Lake Minchumina','AK'),('US','LMB','Lumberton','Lumberton','TX'),('US','LMC','Lemmon','Lemmon','IL'),('US','LMD','Lamont','Lamont','NY'),('US','LME','Lanham','Lanham','MD'),('US','LMF','Lamar','Lamar','SC'),('US','LMG','Laguna Niguel','Laguna Niguel','CA'),('US','LMI','La Mirada','La Mirada','CA'),('US','LMJ','Lemont','Lemont','IL'),('US','LMK','Limerick','Limerick','PA'),('US','LML','Lambertville','Lambertville','MI'),('US','LMM','Calumet','Calumet','MI'),('US','LMN','Clermont','Clermont','GA'),('US','LMO','Morgan City','Morgan City','LA'),('US','LMP','Lampeter','Lampeter','PA'),('US','LMQ','Lyme','Lyme','NH'),('US','LMR','Leominster','Leominster','MA'),('US','LMS','Louisville','Louisville','MS'),('US','LMT','Klamath Falls','Klamath Falls','OR'),('US','LMV','Lambertville','Lambertville','NJ'),('US','LMW','Lakemills','Lakemills','WI'),('US','LMX','Little Mountain','Little Mountain','SC'),('US','LMY','Lemay','Lemay','MO'),('US','LMZ','Lemeta','Lemeta','AK'),('US','LNA','Linden','Linden','AL'),('US','LNB','Lebanon','Lebanon','OH'),('US','LNC','Lancaster','Lancaster','OH'),('US','LND','Lander','Lander','WY'),('US','LNE','Los Nietos','Los Nietos','CA'),('US','LNF','Plainfield','Plainfield','WI'),('US','LNG','Longmont','Longmont','CO'),('US','LNH','Clinton, Township of','Clinton, Township of','MI'),('US','LNI','Lonely','Lonely','AK'),('US','LNJ','Linn','Linn','MO'),('US','LNK','Lincoln','Lincoln','NE'),('US','LNL','Landisville','Landisville','PA'),('US','LNM','Linthicum','Linthicum','MD'),('US','LNN','Willoughby','Willoughby','OH'),('US','LNO','Lando','Lando','SC'),('US','LNP','Wise','Wise','VA'),('US','LNQ','Lena','Lena','LA'),('US','LNR','Lone Rock','Lone Rock','WI'),('US','LNS','Lancaster','Lancaster','PA'),('US','LNT','Lantana','Lantana','FL'),('US','LNU','Laona','Laona','WI'),('US','LNV','Lineville','Lineville','AL'),('US','LNW','Lancaster','Lancaster','SC'),('US','LNX','Lenox','Lenox','MA'),('US','LNY','Lanai City','Lanai City','HI'),('US','LNZ','Linwood','Linwood','NC'),('US','LO2','Live Oak','Live Oak','CA'),('US','LOA','Lomita','Lomita','CA'),('US','LOB','Lido Beach','Lido Beach','NY'),('US','LOC','Lodi','Lodi','OH'),('US','LOD','Londonderry','Londonderry','NH'),('US','LOE','Lowell','Lowell','MA'),('US','LOF','Lugoff','Lugoff','SC'),('US','LOG','Longview','Longview','WA'),('US','LOH','Lyoth','Lyoth','CA'),('US','LOI','Lodi','Lodi','NJ'),('US','LOJ','Lovington','Lovington','NM'),('US','LOK','Lonoke','Lonoke','AR'),('US','LOL','Lovelock','Lovelock','NV'),('US','LOM','Lombard','Lombard','IL'),('US','LON','Lebanon','Lebanon','OR'),('US','LOO','Lake Oswego','Lake Oswego','OR'),('US','LOP','Lockport','Lockport','NY'),('US','LOQ','Live Oak','Live Oak','FL'),('US','LOR','Lorain','Lorain','OH'),('US','LOS','Louisville','Louisville','TN'),('US','LOT','Lockport','Lockport','IL'),('US','LOU','Louise','Louise','TX'),('US','LOV','Loveland','Loveland','CO'),('US','LOW','Louisa','Louisa','VA'),('US','LOX','Lennox','Lennox','CA'),('US','LOY','Lyons','Lyons','OH'),('US','LOZ','London','London','KY'),('US','LPA','La Palma','La Palma','CA'),('US','LPB','Lowell','Lowell','MI'),('US','LPC','Lompoc','Lompoc','CA'),('US','LPD','Lincoln Park, Chicago','Lincoln Park, Chicago','IL'),('US','LPE','La Porte','La Porte','CA'),('US','LPF','Lake Placid','Lake Placid','FL'),('US','LPI','Lapoint','Lapoint','UT'),('US','LPJ','Lincoln Park','Lincoln Park','NJ'),('US','LPK','Lake Forest Park','Lake Forest Park','WA'),('US','LPL','La Place','La Place','LA'),('US','LPN','McAlpin','McAlpin','FL'),('US','LPO','Laporte','Laporte','IN'),('US','LPQ','Lake Park','Lake Park','FL'),('US','LPR','Lakeport','Lakeport','CA'),('US','LPS','Lopez Island','Lopez Island','WA'),('US','LPT','Lockport','Lockport','LA'),('US','LPV','Lorton','Lorton','VA'),('US','LPW','Little Port Walter','Little Port Walter','AK'),('US','LPX','Liverpool','Liverpool','NY'),('US','LPY','Plains','Plains','PA'),('US','LQB','Lacombe','Lacombe','LA'),('US','LQD','Holland','Holland','MO'),('US','LQI','Lakeville','Lakeville','MI'),('US','LQJ','Lafayette','Lafayette','TN'),('US','LQK','Pickens','Pickens','SC'),('US','LQN','Linn','Linn','TX'),('US','LQO','Lake Odessa','Lake Odessa','MI'),('US','LQQ','Lakewood','Lakewood','CA'),('US','LQR','Le Roy','Le Roy','KS'),('US','LQS','Lyons','Lyons','NE'),('US','LQV','Lakeville','Lakeville','CT'),('US','LQW','Lakeview','Lakeview','CA'),('US','LQY','Lockney','Lockney','TX'),('US','LR2','Leroy','Leroy','AL'),('US','LR3','Little River','Little River','SC'),('US','LRA','Luray','Luray','VA'),('US','LRB','Laurinburg','Laurinburg','NC'),('US','LRC','Long Reach','Long Reach','WV'),('US','LRD','Laredo','Laredo','TX'),('US','LRE','Claremore','Claremore','OK'),('US','LRF','Jacksonville','Jacksonville','AR'),('US','LRG','Middleburg','Middleburg','PA'),('US','LRH','Carlton','Carlton','MN'),('US','LRI','Clarion','Clarion','IA'),('US','LRJ','Lemars','Lemars','IA'),('US','LRK','Lincoln Rock','Lincoln Rock','AK'),('US','LRL','Plantersville','Plantersville','MS'),('US','LRM','Laurel','Laurel','MD'),('US','LRO','Lathrop','Lathrop','CA'),('US','LRP','Lake Orion','Lake Orion','MI'),('US','LRQ','Le Roy','Le Roy','IL'),('US','LRR','Larimore','Larimore','ND'),('US','LRS','Larose','Larose','LA'),('US','LRT','Clarkston','Clarkston','MI'),('US','LRU','Las Cruces','Las Cruces','NM'),('US','LRV','Lawrenceville','Lawrenceville','NJ'),('US','LRW','Lawrenceville','Lawrenceville','GA'),('US','LRX','Laurens','Laurens','IA'),('US','LRY','Luray','Luray','TN'),('US','LRZ','Loris','Loris','SC'),('US','LS2','Lake Stevens','Lake Stevens','WA'),('US','LSA','Lisle','Lisle','IL'),('US','LSB','Lordsburg','Lordsburg','NM'),('US','LSC','Laurens','Laurens','SC'),('US','LSD','Lansdale','Lansdale','PA'),('US','LSE','La Crosse','La Crosse','WI'),('US','LSF','Fort Benning','Fort Benning','GA'),('US','LSG','Lansing','Lansing','KS'),('US','LSH','Pleasant Hill','Pleasant Hill','IA'),('US','LSI','Lansing','Lansing','IL'),('US','LSJ','Leipsic','Leipsic','OH'),('US','LSK','Lusk','Lusk','WY'),('US','LSL','Leetsdale','Leetsdale','PA'),('US','LSM','Lee\'s Summit','Lee\'s Summit','MO'),('US','LSN','Los Banos','Los Banos','CA'),('US','LSO','Leesburg','Leesburg','OH'),('US','LSR','Lost River','Lost River','AK'),('US','LSS','Lake Success','Lake Success','NY'),('US','LST','Logansport','Logansport','LA'),('US','LSU','Lees Summit','Lees Summit','MO'),('US','LSV','Leesville','Leesville','LA'),('US','LSW','Laguna Woods','Laguna Woods','CA'),('US','LSX','Lone Star','Lone Star','TX'),('US','LSY','Lindsay','Lindsay','CA'),('US','LT2','Latonia','Latonia','KY'),('US','LT3','Loogootee','Loogootee','IN'),('US','LTA','Lometa','Lometa','TX'),('US','LTB','Satellite Beach','Satellite Beach','FL'),('US','LTC','Little Chute','Little Chute','WI'),('US','LTD','Litchfield','Litchfield','MI'),('US','LTE','Lanett','Lanett','GA'),('US','LTF','Little Ferry','Little Ferry','NJ'),('US','LTH','Lathrop Wells','Lathrop Wells','NV'),('US','LTI','Lititz','Lititz','PA'),('US','LTJ','Layton','Layton','UT'),('US','LTK','Flat Rock','Flat Rock','IL'),('US','LTL','Littleton','Littleton','NH'),('US','LTM','Latham','Latham','NY'),('US','LTN','Littleton','Littleton','MA'),('US','LTO','Littleton','Littleton','CO'),('US','LTQ','Lecanto','Lecanto','FL'),('US','LTR','Flat Rock','Flat Rock','NC'),('US','LTS','Altus','Altus','OK'),('US','LTT','Levittown','Levittown','PA'),('US','LTU','Linthicum Heights','Linthicum Heights','MD'),('US','LTV','Locustville','Locustville','VA'),('US','LTW','Leonardtown','Leonardtown','MD'),('US','LTX','Lancaster','Lancaster','TX'),('US','LTY','Liberty Hill, Williamson','Liberty Hill, Williamson','TN'),('US','LTZ','Lutz','Lutz','FL'),('US','LUA','Louisiana','Louisiana','MO'),('US','LUB','Lumber Bridge','Lumber Bridge','NC'),('US','LUC','Luck','Luck','WI'),('US','LUD','Lukeville','Lukeville','AZ'),('US','LUE','Louisville','Louisville','CO'),('US','LUF','Blue Earth','Blue Earth','MN'),('US','LUG','Lunenburg','Lunenburg','MA'),('US','LUI','Louisville','Louisville','KY'),('US','LUJ','Mt Laurel','Mt Laurel','NJ'),('US','LUK','Luke','Luke','MD'),('US','LUL','Laurel','Laurel','MS'),('US','LUM','Lumberton','Lumberton','NJ'),('US','LUN','Luana','Luana','IA'),('US','LUO','Loudonville','Loudonville','OH'),('US','LUP','Kalaupapa','Kalaupapa','HI'),('US','LUR','Cape Lisburne','Cape Lisburne','AK'),('US','LUS','Laurens','Laurens','NY'),('US','LUT','Lewiston','Lewiston','NY'),('US','LUU','Le Sueur','Le Sueur','MN'),('US','LUV','Louisville','Louisville','OH'),('US','LUW','Ludlow','Ludlow','MA'),('US','LUY','Louisville','Louisville','GA'),('US','LV2','Lago Vista','Lago Vista','TX'),('US','LV3','Lavinia','Lavinia','TN'),('US','LV4','Lilesville','Lilesville','NC'),('US','LVA','Lakeville','Lakeville','MN'),('US','LVD','Lime Village','Lime Village','AK'),('US','LVE','Lakeview','Lakeview','IA'),('US','LVF','Livermore Falls','Livermore Falls','ME'),('US','LVG','Livingston','Livingston','NJ'),('US','LVH','Laveen','Laveen','AZ'),('US','LVI','Livonia','Livonia','MI'),('US','LVJ','Lovejoy','Lovejoy','GA'),('US','LVK','Livermore','Livermore','CA'),('US','LVL','Lawrenceville','Lawrenceville','VA'),('US','LVM','Livingston','Livingston','MT'),('US','LVN','Leavenworth','Leavenworth','WA'),('US','LVO','Livingston','Livingston','LA'),('US','LVP','Liverpool','Liverpool','PA'),('US','LVR','La Puente','La Puente','CA'),('US','LVS','Las Vegas','Las Vegas','NM'),('US','LVT','Livingston','Livingston','AL'),('US','LVU','Lawrenceburg','Lawrenceburg','IN'),('US','LVV','La Vergne','La Vergne','TN'),('US','LVW','Lakeview','Lakeview','MI'),('US','LVX','Leavittsburg','Leavittsburg','OH'),('US','LVY','Livingston','Livingston','NY'),('US','LW2','Lawyers','Lawyers','VA'),('US','LWA','Lake Wales','Lake Wales','FL'),('US','LWB','Lewisburg','Lewisburg','WV'),('US','LWC','Lawrence','Lawrence','KS'),('US','LWD','Lewisport','Lewisport','KY'),('US','LWE','Lawrence','Lawrence','NY'),('US','LWF','Lowville','Lowville','NY'),('US','LWG','Lakewood','Lakewood','GA'),('US','LWH','Lake Worth','Lake Worth','FL'),('US','LWI','Lewisville','Lewisville','AR'),('US','LWJ','Lawndale','Lawndale','CA'),('US','LWK','Leawood','Leawood','KS'),('US','LWL','Wells','Wells','NV'),('US','LWM','Lawrence','Lawrence','MA'),('US','LWN','Lawrence','Lawrence','PA'),('US','LWO','Ledgewood','Ledgewood','NJ'),('US','LWP','Lewes','Lewes','DE'),('US','LWQ','Lowell, Lake','Lowell, Lake','IN'),('US','LWR','Lawrence','Lawrence','MI'),('US','LWS','Lewiston','Lewiston','ID'),('US','LWT','Lewistown','Lewistown','MT'),('US','LWU','Lakeview','Lakeview','FL'),('US','LWV','Lawrenceville','Lawrenceville','IL'),('US','LWW','Lewistown, Mifflin','Lewistown, Mifflin','PA'),('US','LWX','Lena','Lena','WI'),('US','LWY','Lowell','Lowell','AR'),('US','LWZ','Lewisville','Lewisville','NC'),('US','LXA','Lenexa','Lenexa','KS'),('US','LXD','Lenox Dale','Lenox Dale','MA'),('US','LXE','Lakeville','Lakeville','IN'),('US','LXG','Lexington','Lexington','NC'),('US','LXH','Lexington','Lexington','VA'),('US','LXI','Lexington','Lexington','MA'),('US','LXJ','Lake Winola','Lake Winola','PA'),('US','LXK','Lenox','Lenox','IL'),('US','LXM','Lexington','Lexington','MI'),('US','LXN','Lexington','Lexington','NE'),('US','LXO','Lexington','Lexington','MS'),('US','LXS','Lyons','Lyons','SD'),('US','LXT','Lexington','Lexington','IL'),('US','LXV','Leadville','Leadville','CO'),('US','LXX','Los Gatos','Los Gatos','CA'),('US','LXY','Loxley','Loxley','AL'),('US','LYA','Lynn','Lynn','AL'),('US','LYB','Lynbrook','Lynbrook','NY'),('US','LYC','Lynchburg','Lynchburg','SC'),('US','LYD','Linden','Linden','CA'),('US','LYE','Lyme','Lyme','CT'),('US','LYF','Lynnwood','Lynnwood','WA'),('US','LYG','Luling','Luling','LA'),('US','LYH','Lynchburg','Lynchburg','VA'),('US','LYI','Lynn','Lynn','IN'),('US','LYJ','Lynwood','Lynwood','CA'),('US','LYK','Little Neck/Queens/New York','Little Neck/Queens/New York','NY'),('US','LYL','Lynnville','Lynnville','IA'),('US','LYM','Lynn Haven','Lynn Haven','FL'),('US','LYN','Lynden','Lynden','WA'),('US','LYO','Lyons','Lyons','KS'),('US','LYP','Lemoyne','Lemoyne','PA'),('US','LYQ','Lyon Station','Lyon Station','PA'),('US','LYR','Lyerly','Lyerly','GA'),('US','LYS','Lyons','Lyons','IL'),('US','LYT','Lytton','Lytton','IA'),('US','LYU','Ely','Ely','MN'),('US','LYV','Livingston','Livingston','TN'),('US','LYW','Lynwood','Lynwood','IL'),('US','LYX','Lynchburg','Lynchburg','TN'),('US','LYY','Lyons','Lyons','NY'),('US','LYZ','Lutts','Lutts','TN'),('US','LZA','Clyman','Clyman','WI'),('US','LZB','Lisbon','Lisbon','IA'),('US','LZC','Lancaster','Lancaster','MN'),('US','LZG','Leesburg','Leesburg','AL'),('US','LZI','Lisbon','Lisbon','OH'),('US','LZK','Lindsay','Lindsay','NE'),('US','LZN','Lynn','Lynn','MA'),('US','LZO','Lewiston','Lewiston','UT'),('US','LZP','Lansford','Lansford','PA'),('US','LZV','Landing','Landing','NJ'),('US','LZW','Luverne','Luverne','AL'),('US','LZX','Lafayette','Lafayette','CA'),('US','LZZ','Lenoir City','Lenoir City','TN'),('US','MA2','McAlisterville','McAlisterville','PA'),('US','MAA','Mayo','Mayo','FL'),('US','MAB','Mandeville','Mandeville','LA'),('US','MAC','Macon','Macon','MO'),('US','MAD','Madawaska','Madawaska','ME'),('US','MAE','Madera','Madera','CA'),('US','MAF','Midland','Midland','TX'),('US','MAG','Magnolia','Magnolia','MA'),('US','MAH','Marcus Hook','Marcus Hook','PA'),('US','MAI','Maida','Maida','ND'),('US','MAJ','Mahopac','Mahopac','NY'),('US','MAK','Marina','Marina','CA'),('US','MAL','Malibu','Malibu','CA'),('US','MAM','Miamiville','Miamiville','OH'),('US','MAN','Martin','Martin','MI'),('US','MAO','Madison','Madison','TN'),('US','MAP','Maple Heights','Maple Heights','OH'),('US','MAQ','Manor','Manor','TX'),('US','MAR','Marrero','Marrero','LA'),('US','MAS','Mansfield','Mansfield','PA'),('US','MAT','Mahrt','Mahrt','AL'),('US','MAU','Mauldin','Mauldin','SC'),('US','MAV','Manvel','Manvel','TX'),('US','MAW','Malden','Malden','MO'),('US','MAX','Mexia','Mexia','TX'),('US','MAY','Mayfield','Mayfield','KY'),('US','MAZ','Madison','Madison','AL'),('US','MB2','Marlborough, Middlesex','Marlborough, Middlesex','MA'),('US','MBA','Millbrae','Millbrae','CA'),('US','MBB','Marlboro','Marlboro','NJ'),('US','MBC','Montoursville','Montoursville','PA'),('US','MBD','Millsboro','Millsboro','DE'),('US','MBE','Melbourne Beach','Melbourne Beach','FL'),('US','MBF','Merritt Island','Merritt Island','FL'),('US','MBG','Mobridge','Mobridge','SD'),('US','MBH','Montrose','Montrose','CA'),('US','MBI','McBride','McBride','MO'),('US','MBJ','Millbrook','Millbrook','AL'),('US','MBK','Milbank','Milbank','SD'),('US','MBL','Manistee','Manistee','MI'),('US','MBM','Montville','Montville','CT'),('US','MBN','Mebane','Mebane','NC'),('US','MBO','Salem','Salem','WV'),('US','MBP','Mercersburg','Mercersburg','PA'),('US','MBQ','Manhattan Beach','Manhattan Beach','CA'),('US','MBR','Middlesboro','Middlesboro','KY'),('US','MBS','Bay City-Saginaw-Midland Apt','Bay City-Saginaw-Midland Apt','MI'),('US','MBT','Millbury','Millbury','MA'),('US','MBU','Middlebury','Middlebury','VT'),('US','MBV','Middleburgh Heights','Middleburgh Heights','OH'),('US','MBW','Moore','Moore','SC'),('US','MBX','Maben','Maben','MS'),('US','MBY','Moberly','Moberly','MO'),('US','MBZ','Marlboro','Marlboro','NY'),('US','MC2','McClellan Air Force Base','McClellan Air Force Base','CA'),('US','MC3','Mill Creek','Mill Creek','PA'),('US','MC4','Mineral City','Mineral City','OH'),('US','MC5','Missouri City','Missouri City','TX'),('US','MC6','Mount Carmel','Mount Carmel','IL'),('US','MC7','Mouthcard','Mouthcard','KY'),('US','MC8','Mansfield Center','Mansfield Center','CT'),('US','MCA','McAdoo','McAdoo','PA'),('US','MCB','McComb','McComb','MS'),('US','MCC','McCrory','McCrory','AR'),('US','MCD','Mackinac Island','Mackinac Island','MI'),('US','MCE','Merced','Merced','CA'),('US','MCF','McFarland','McFarland','CA'),('US','MCG','McGrath','McGrath','AK'),('US','MCH','McDonough','McDonough','GA'),('US','MCI','Monticello','Monticello','IN'),('US','MCJ','Mishawaka','Mishawaka','IN'),('US','MCK','McCook','McCook','NE'),('US','MCL','Mt McKinley','Mt McKinley','AK'),('US','MCM','McMurray','McMurray','PA'),('US','MCN','Macon','Macon','GA'),('US','MCO','McCook','McCook','IL'),('US','MCP','Moncure','Moncure','NC'),('US','MCQ','McIntyre','McIntyre','GA'),('US','MCR','Manchester','Manchester','WA'),('US','MCS','Mancos','Mancos','CO'),('US','MCT','McKinney','McKinney','TX'),('US','MCU','McArthur','McArthur','OH'),('US','MCV','McAdenville','McAdenville','NC'),('US','MCW','Mason City','Mason City','IA'),('US','MCX','Manchester','Manchester','KY'),('US','MCY','Minden City','Minden City','MI'),('US','MCZ','Monticello','Monticello','MS'),('US','MD2','Matador','Matador','TX'),('US','MD3','McDade','McDade','TX'),('US','MD4','Mead','Mead','NE'),('US','MD5','Meredith','Meredith','NH'),('US','MD6','Medora','Medora','KS'),('US','MD7','Moody','Moody','AL'),('US','MD8','McDonald, Trumbull','McDonald, Trumbull','OH'),('US','MDA','Madelia','Madelia','MN'),('US','MDB','Montville','Montville','NJ'),('US','MDC','Medfield','Medfield','MA'),('US','MDD','Midland','Midland','TX'),('US','MDE','Medford','Medford','NY'),('US','MDF','Medford','Medford','WI'),('US','MDG','Mendota Heights','Mendota Heights','MN'),('US','MDH','Carbondale','Carbondale','IL'),('US','MDI','Madison','Madison','NC'),('US','MDJ','Madison-Madras Apt','Madison-Madras Apt','OR'),('US','MDK','Medina','Medina','NY'),('US','MDL','Midland Park','Midland Park','NJ'),('US','MDM','Madras','Madras','OR'),('US','MDN','Madison','Madison','IN'),('US','MDO','Middleton Island','Middleton Island','AK'),('US','MDP','McDonald','McDonald','PA'),('US','MDQ','Medina','Medina','OH'),('US','MDR','Medfra','Medfra','AK'),('US','MDS','Madison','Madison','GA'),('US','MDT','McDermott','McDermott','OH'),('US','MDU','Middlebury','Middlebury','IN'),('US','MDV','Middle River','Middle River','MD'),('US','MDW','Middleton','Middleton','WI'),('US','MDX','Marina del Rey','Marina del Rey','CA'),('US','MDY','Medley','Medley','FL'),('US','MDZ','Moundridge','Moundridge','KS'),('US','ME2','Mount Eaton','Mount Eaton','OH'),('US','MEA','Mentor','Mentor','OH'),('US','MEB','Monument','Monument','CO'),('US','MEC','Mechanicsville','Mechanicsville','VA'),('US','MED','Midlothian','Midlothian','VA'),('US','MEE','Manatee','Manatee','FL'),('US','MEF','Moffett Field','Moffett Field','CA'),('US','MEG','Mechanicsburg','Mechanicsburg','PA'),('US','MEH','Mehoopany','Mehoopany','PA'),('US','MEI','Meridian','Meridian','MS'),('US','MEJ','Meadville','Meadville','PA'),('US','MEK','Mappsville','Mappsville','VA'),('US','MEL','Merrillville','Merrillville','IN'),('US','MEM','Memphis','Memphis','TN'),('US','MEN','Mendota','Mendota','IL'),('US','MEO','Manteo','Manteo','NC'),('US','MEP','Maple Park','Maple Park','IL'),('US','MEQ','Milford','Milford','DE'),('US','MER','Merrick','Merrick','NY'),('US','MES','Minneapolis','Minneapolis','MN'),('US','MET','Metropolis','Metropolis','IL'),('US','MEU','Metuchen','Metuchen','NJ'),('US','MEV','Minden','Minden','NV'),('US','MEW','Merriam','Merriam','KS'),('US','MEX','Mecca','Mecca','CA'),('US','MEY','Modena','Modena','PA'),('US','MEZ','Menasha','Menasha','WI'),('US','MF2','Moorefield','Moorefield','KY'),('US','MF3','Moorefield','Moorefield','WV'),('US','MF4','Moravian Falls','Moravian Falls','NC'),('US','MF5','Milford','Milford','MI'),('US','MF6','McFarland','McFarland','WI'),('US','MF7','Mayfield, Butler','Mayfield, Butler','OH'),('US','MF8','Marshfield','Marshfield','MO'),('US','MFA','Marble Falls','Marble Falls','TX'),('US','MFB','Marshfield','Marshfield','MA'),('US','MFC','Medford','Medford','MA'),('US','MFD','Mansfield','Mansfield','OH'),('US','MFE','McAllen-Mission Apt','McAllen-Mission Apt','TX'),('US','MFF','Milford','Milford','IL'),('US','MFG','Myrtle Point','Myrtle Point','OR'),('US','MFH','Mesquite','Mesquite','NV'),('US','MFI','Marshfield','Marshfield','WI'),('US','MFJ','Milford','Milford','IA'),('US','MFK','Milford','Milford','MA'),('US','MFL','Mansfield','Mansfield','TX'),('US','MFM','Mountain City','Mountain City','TN'),('US','MFN','Mifflinville','Mifflinville','PA'),('US','MFO','Milford','Milford','ME'),('US','MFP','Mayfield','Mayfield','PA'),('US','MFQ','Milford','Milford','PA'),('US','MFR','Medford','Medford','OR'),('US','MFS','McChord Air Force Base','McChord Air Force Base','WA'),('US','MFT','Milford','Milford','NJ'),('US','MFU','Murfreesboro','Murfreesboro','TN'),('US','MFV','Melfa','Melfa','VA'),('US','MFW','Milford','Milford','NH'),('US','MFX','Milford','Milford','CT'),('US','MFY','Martins Ferry','Martins Ferry','OH'),('US','MFZ','Moundsville','Moundsville','WV'),('US','MG2','McGregor','McGregor','IA'),('US','MG3','McGregor','McGregor','MN'),('US','MG4','McGregor','McGregor','TX'),('US','MG5','Malaga','Malaga','WA'),('US','MG6','Montgomery','Montgomery','TX'),('US','MGA','Malaga','Malaga','NJ'),('US','MGB','Macungie','Macungie','PA'),('US','MGC','Michigan City','Michigan City','IN'),('US','MGD','Mogadore','Mogadore','OH'),('US','MGE','Marietta','Marietta','GA'),('US','MGF','Melvindale','Melvindale','MI'),('US','MGG','Morgantown','Morgantown','KY'),('US','MGH','Montgomery','Montgomery','MN'),('US','MGI','Matagorda Island','Matagorda Island','TX'),('US','MGJ','Montgomery','Montgomery','NY'),('US','MGK','Mt Sterling','Mt Sterling','KY'),('US','MGL','Middle Granville','Middle Granville','NY'),('US','MGM','Montgomery','Montgomery','AL'),('US','MGN','Morgan City','Morgan City','AL'),('US','MGO','Marengo','Marengo','IA'),('US','MGP','Morgantown','Morgantown','PA'),('US','MGQ','Mount Gilead','Mount Gilead','NC'),('US','MGR','Moultrie','Moultrie','GA'),('US','MGS','Munising','Munising','MI'),('US','MGT','Margate','Margate','FL'),('US','MGU','Maringouin','Maringouin','LA'),('US','MGV','Morton Grove','Morton Grove','IL'),('US','MGW','Morgantown','Morgantown','WV'),('US','MGX','Marlborough','Marlborough','NH'),('US','MGY','Millington','Millington','NJ'),('US','MGZ','Maple Grove','Maple Grove','OH'),('US','MH2','Marblehead','Marblehead','MA'),('US','MH3','Mayhew','Mayhew','MS'),('US','MH4','Mount Horeb','Mount Horeb','WI'),('US','MH5','Madison Heights','Madison Heights','VA'),('US','MH6','Mount Holly','Mount Holly','AR'),('US','MH7','Merry Hill','Merry Hill','NC'),('US','MH8','Manhasset','Manhasset','NY'),('US','MHA','Minnehaha','Minnehaha','WA'),('US','MHB','McHenry','McHenry','IL'),('US','MHC','Mitchell','Mitchell','IN'),('US','MHD','Marshville','Marshville','NC'),('US','MHE','Mitchell','Mitchell','SD'),('US','MHF','Manheim','Manheim','PA'),('US','MHG','Marshall','Marshall','MI'),('US','MHH','Marathon','Marathon','WI'),('US','MHI','Manchester','Manchester','GA'),('US','MHJ','Mullica Hill','Mullica Hill','NJ'),('US','MHK','Manhattan','Manhattan','KS'),('US','MHL','Marshall','Marshall','MO'),('US','MHM','Minchumina','Minchumina','AK'),('US','MHN','Mullen','Mullen','NE'),('US','MHO','Cameron Park','Cameron Park','CA'),('US','MHP','Mill Hall','Mill Hall','PA'),('US','MHQ','Murrieta','Murrieta','CA'),('US','MHR','Morehead','Morehead','KY'),('US','MHS','Mt Shasta','Mt Shasta','CA'),('US','MHT','Manchester','Manchester','NH'),('US','MHU','Mountain Home','Mountain Home','NC'),('US','MHV','Mechanicville','Mechanicville','NY'),('US','MHW','Mahwah','Mahwah','NJ'),('US','MHX','Mt Holly','Mt Holly','NC'),('US','MHY','Maryland Heights','Maryland Heights','MO'),('US','MHZ','Mine Hill','Mine Hill','NJ'),('US','MI2','Mio','Mio','MI'),('US','MIA','Miami','Miami','FL'),('US','MIB','Midlothian','Midlothian','TX'),('US','MIC','Milton','Milton','PA'),('US','MID','Middleboro','Middleboro','MA'),('US','MIE','Muncie','Muncie','IN'),('US','MIF','Monahans','Monahans','TX'),('US','MIG','Mingo','Mingo','KS'),('US','MIH','Mitchell','Mitchell','NE'),('US','MII','Milford','Milford','IN'),('US','MIJ','Middletown','Middletown','NJ'),('US','MIK','Mira Loma','Mira Loma','CA'),('US','MIL','Madill','Madill','OK'),('US','MIM','Maple Island','Maple Island','MN'),('US','MIN','Marion','Marion','NC'),('US','MIO','Miami','Miami','OK'),('US','MIP','Middleport','Middleport','OH'),('US','MIQ','Milan','Milan','IL'),('US','MIR','Marietta','Marietta','OK'),('US','MIS','Middlesex','Middlesex','NJ'),('US','MIT','Shafter','Shafter','CA'),('US','MIU','Middletown','Middletown','DE'),('US','MIV','Millville','Millville','NJ'),('US','MIW','Marshalltown','Marshalltown','IA'),('US','MIX','Mineola','Mineola','TX'),('US','MIY','Middletown','Middletown','NY'),('US','MIZ','Miami Springs','Miami Springs','FL'),('US','MJA','Meridian','Meridian','ID'),('US','MJB','Mount Juliet','Mount Juliet','TN'),('US','MJC','Morral','Morral','OH'),('US','MJD','Midland','Midland','GA'),('US','MJE','Morrison','Morrison','CO'),('US','MJF','Morrison','Morrison','TN'),('US','MJG','Morristown','Morristown','IN'),('US','MJH','Mission Hills','Mission Hills','CA'),('US','MJI','Mission Viejo','Mission Viejo','CA'),('US','MJJ','Mortons Gap','Mortons Gap','KY'),('US','MJK','Morro Bay','Morro Bay','CA'),('US','MJL','Moscow','Moscow','ID'),('US','MJM','Mora','Mora','MN'),('US','MJN','Moss','Moss','TN'),('US','MJO','Mounds View','Mounds View','MN'),('US','MJP','Middleton','Middleton','TN'),('US','MJQ','Jackson','Jackson','MN'),('US','MJR','Mt Berry','Mt Berry','GA'),('US','MJS','Morattico','Morattico','VA'),('US','MJT','Marlton','Marlton','NJ'),('US','MJU','Monmouth Junction','Monmouth Junction','NJ'),('US','MJV','Morgan Hill','Morgan Hill','CA'),('US','MJW','Mathews','Mathews','LA'),('US','MJX','Toms River','Toms River','NJ'),('US','MJY','Mt Joy','Mt Joy','PA'),('US','MJZ','Morgantown','Morgantown','NC'),('US','MK2','McKenzie','McKenzie','AL'),('US','MK3','Meeker','Meeker','OK'),('US','MKA','Minnetonka','Minnetonka','MN'),('US','MKB','Melba','Melba','ID'),('US','MKC','Kansas City','Kansas City','MO'),('US','MKD','Macdoel','Macdoel','CA'),('US','MKE','Milwaukee','Milwaukee','WI'),('US','MKF','Malakoff','Malakoff','TX'),('US','MKG','Muskegon','Muskegon','MI'),('US','MKH','Markham','Markham','TX'),('US','MKI','Mukilteo','Mukilteo','WA'),('US','MKJ','McKees Rocks','McKees Rocks','PA'),('US','MKK','Hoolehua','Hoolehua','HI'),('US','MKL','Jackson','Jackson','TN'),('US','MKM','Markham','Markham','IL'),('US','MKN','McKenney','McKenney','VA'),('US','MKO','Muskogee','Muskogee','OK'),('US','MKP','Maceo','Maceo','KY'),('US','MKQ','Markesan','Markesan','WI'),('US','MKR','McKeesport','McKeesport','PA'),('US','MKS','Mt Kisco','Mt Kisco','NY'),('US','MKT','Mankato','Mankato','MN'),('US','MKU','Menlo Park','Menlo Park','CA'),('US','MKV','Mocksville','Mocksville','NC'),('US','MKW','Mill Creek','Mill Creek','WA'),('US','MKX','McCalla','McCalla','AL'),('US','MKY','Mt Airy','Mt Airy','NC'),('US','MKZ','Mukwonago','Mukwonago','WI'),('US','ML2','Marlin','Marlin','PA'),('US','ML3','Maitland','Maitland','FL'),('US','ML4','Milaca','Milaca','MN'),('US','ML5','Mountain Lake','Mountain Lake','MN'),('US','ML6','Mainland','Mainland','PA'),('US','ML7','Milan','Milan','GA'),('US','ML8','Marshall','Marshall','IL'),('US','MLA','McKinley Park','McKinley Park','AK'),('US','MLB','Melbourne','Melbourne','FL'),('US','MLC','McAlester','McAlester','OK'),('US','MLD','Malad City','Malad City','ID'),('US','MLE','Maumelle','Maumelle','AR'),('US','MLF','Milford','Milford','UT'),('US','MLG','Moss Landing','Moss Landing','CA'),('US','MLH','Midlothian','Midlothian','IL'),('US','MLI','Moline','Moline','IL'),('US','MLJ','Milledgeville','Milledgeville','GA'),('US','MLK','Malta','Malta','MT'),('US','MLL','Mottville','Mottville','MI'),('US','MLM','Mira Mesa','Mira Mesa','CA'),('US','MLN','Malin','Malin','OR'),('US','MLO','Melrose','Melrose','MA'),('US','MLP','Magnolia Park','Magnolia Park','CA'),('US','MLQ','Milbridge','Milbridge','ME'),('US','MLR','Montclair','Montclair','NJ'),('US','MLS','Miles City','Miles City','MT'),('US','MLT','Millinocket','Millinocket','ME'),('US','MLU','Monroe','Monroe','LA'),('US','MLV','Millersburg','Millersburg','OH'),('US','MLW','Milton','Milton','DE'),('US','MLX','Malta','Malta','NY'),('US','MLY','Manley Hot Springs','Manley Hot Springs','AK'),('US','MLZ','Meridianville','Meridianville','AL'),('US','MM2','Merrimac','Merrimac','MA'),('US','MM3','Metamora','Metamora','MI'),('US','MM4','Moscow Mills','Moscow Mills','MO'),('US','MMA','Mora','Mora','NM'),('US','MMB','Mount Morris','Mount Morris','MI'),('US','MMC','McMinnville','McMinnville','OR'),('US','MMD','Merrill','Merrill','MI'),('US','MME','Momence','Momence','IL'),('US','MMF','Menomonee Falls','Menomonee Falls','WI'),('US','MMG','Murtaugh','Murtaugh','ID'),('US','MMH','Mammoth Lakes','Mammoth Lakes','CA'),('US','MMI','Athens','Athens','TN'),('US','MMJ','Milltown','Milltown','NJ'),('US','MMK','Miami Lakes','Miami Lakes','FL'),('US','MML','Marshall','Marshall','MN'),('US','MMM','Menomonie','Menomonie','WI'),('US','MMN','Stow','Stow','MA'),('US','MMO','Monett','Monett','MO'),('US','MMP','Montpelier','Montpelier','OH'),('US','MMQ','Morrison','Morrison','IL'),('US','MMR','Miramar','Miramar','FL'),('US','MMS','Marks','Marks','MS'),('US','MMT','Martin','Martin','TN'),('US','MMU','Morristown','Morristown','NJ'),('US','MMV','Mountainville','Mountainville','NJ'),('US','MMW','McMillin','McMillin','WA'),('US','MMX','Marion','Marion','IA'),('US','MMY','Maumee','Maumee','OH'),('US','MMZ','Melrose','Melrose','MN'),('US','MN2','Marion','Marion','LA'),('US','MN3','Medon','Medon','TN'),('US','MN4','Milner','Milner','GA'),('US','MN5','Menemsha','Menemsha','MA'),('US','MN6','Minden','Minden','NE'),('US','MN7','Meriden','Meriden','KS'),('US','MN8','Magnolia','Magnolia','MS'),('US','MNA','Mineola','Mineola','NY'),('US','MNB','McConnellsburg','McConnellsburg','PA'),('US','MNC','Michigan Center','Michigan Center','MI'),('US','MND','Mendocino','Mendocino','CA'),('US','MNE','Manchester','Manchester','CT'),('US','MNF','Marianna','Marianna','FL'),('US','MNG','Manning','Manning','SC'),('US','MNH','Manhattan/New York','Manhattan/New York','NY'),('US','MNI','Monmouth','Monmouth','IL'),('US','MNJ','Manchester Center','Manchester Center','VT'),('US','MNK','Moncks Corner','Moncks Corner','SC'),('US','MNL','Menlo','Menlo','GA'),('US','MNM','Menominee','Menominee','MI'),('US','MNN','Marion','Marion','OH'),('US','MNO','Mt Olive','Mt Olive','NC'),('US','MNP','Monaca','Monaca','PA'),('US','MNQ','Morton','Morton','MS'),('US','MNR','Monroe','Monroe','NC'),('US','MNS','Mansfield','Mansfield','MA'),('US','MNT','Minto','Minto','AK'),('US','MNU','Mermentau','Mermentau','LA'),('US','MNV','Minerva','Minerva','OH'),('US','MNW','Mattawan','Mattawan','MI'),('US','MNX','Manchester','Manchester','IA'),('US','MNY','Manchester','Manchester','MO'),('US','MNZ','Manassas','Manassas','VA'),('US','MOA','Moundville','Moundville','AL'),('US','MOB','Mobile','Mobile','AL'); +INSERT INTO `ISO_LOCATION` VALUES ('US','MOC','Monticello','Monticello','KY'),('US','MOD','Modesto','Modesto','CA'),('US','MOE','Monroe','Monroe','GA'),('US','MOF','Motley','Motley','MN'),('US','MOG','Moss Point','Moss Point','MS'),('US','MOH','Monmouth','Monmouth','ME'),('US','MOI','Monroe','Monroe','MI'),('US','MOJ','Mojave','Mojave','CA'),('US','MOK','Morrill','Morrill','NE'),('US','MOL','Molalla','Molalla','OR'),('US','MOM','Monroe','Monroe','CT'),('US','MON','Manson','Manson','IA'),('US','MOO','Moonachie/New Jersey','Moonachie/New Jersey','NJ'),('US','MOP','Mt Pleasant','Mt Pleasant','MI'),('US','MOQ','Monticello','Monticello','AR'),('US','MOR','Morristown','Morristown','TN'),('US','MOS','Moses Point','Moses Point','AK'),('US','MOT','Minot','Minot','ND'),('US','MOU','Mountain Village','Mountain Village','AK'),('US','MOV','Marceline','Marceline','MO'),('US','MOW','Monroe','Monroe','WA'),('US','MOX','Morris','Morris','MN'),('US','MOY','Marinette','Marinette','WI'),('US','MOZ','Montezuma','Montezuma','GA'),('US','MP2','Mauckport','Mauckport','IN'),('US','MP3','Mineral Point, Iowa','Mineral Point, Iowa','WI'),('US','MP4','Maple Plain','Maple Plain','MN'),('US','MP5','Machesney Park','Machesney Park','IL'),('US','MPA','Morris Plains','Morris Plains','NJ'),('US','MPB','Maspeth','Maspeth','NY'),('US','MPC','Manchester','Manchester','MI'),('US','MPD','Marietta','Marietta','PA'),('US','MPE','Madison','Madison','CT'),('US','MPF','Moorlands','Moorlands','WA'),('US','MPG','Moonachie','Moonachie','NJ'),('US','MPH','Mt Pleasant','Mt Pleasant','SC'),('US','MPI','Montpelier','Montpelier','VT'),('US','MPJ','Morrilton','Morrilton','AR'),('US','MPK','Mt Pulaski','Mt Pulaski','IL'),('US','MPL','Mt Pleasant','Mt Pleasant','TN'),('US','MPM','Mapleton','Mapleton','ME'),('US','MPN','McCamey','McCamey','TX'),('US','MPO','Mt Pocono','Mt Pocono','PA'),('US','MPP','Morgans Point','Morgans Point','TX'),('US','MPQ','Monroe Park','Monroe Park','NC'),('US','MPR','McPherson','McPherson','KS'),('US','MPS','Mt Pleasant','Mt Pleasant','TX'),('US','MPT','Milpitas','Milpitas','CA'),('US','MPU','Maple Hill','Maple Hill','KS'),('US','MPV','Barre-Montpelier Apt','Barre-Montpelier Apt','VT'),('US','MPW','Maplewood','Maplewood','NJ'),('US','MPX','Mapleville','Mapleville','RI'),('US','MPY','Mt Pleasant','Mt Pleasant','FL'),('US','MPZ','Mt Pleasant','Mt Pleasant','IA'),('US','MQA','Mesa','Mesa','AR'),('US','MQB','Macomb','Macomb','IL'),('US','MQC','Monticello','Monticello','GA'),('US','MQD','Monticello','Monticello','IL'),('US','MQE','Moores Mill','Moores Mill','NY'),('US','MQF','Maywood, Albany','Maywood, Albany','NY'),('US','MQG','Moneta','Moneta','VA'),('US','MQH','Marlette','Marlette','MI'),('US','MQI','Quincy','Quincy','MA'),('US','MQJ','Melbourne','Melbourne','AR'),('US','MQK','Moorpark','Moorpark','CA'),('US','MQL','Markle','Markle','IN'),('US','MQM','Marion','Marion','AR'),('US','MQN','Manalapan','Manalapan','FL'),('US','MQO','Maquoketa','Maquoketa','IA'),('US','MQP','Martins Creek','Martins Creek','PA'),('US','MQQ','Maple City','Maple City','MI'),('US','MQR','Morenci','Morenci','MI'),('US','MQS','Mesquite','Mesquite','NM'),('US','MQT','Marquette','Marquette','MI'),('US','MQU','Mequon','Mequon','WI'),('US','MQV','Mt Olive','Mt Olive','NJ'),('US','MQW','McRae','McRae','GA'),('US','MQX','Mercer','Mercer','PA'),('US','MQY','Smyrna','Smyrna','TN'),('US','MQZ','Mercer Island','Mercer Island','WA'),('US','MR2','Marseilles','Marseilles','IL'),('US','MR3','Morris','Morris','LA'),('US','MR4','Morris','Morris','CT'),('US','MR5','Murdock','Murdock','IL'),('US','MR6','Moroni','Moroni','UT'),('US','MR7','Manchester','Manchester','ME'),('US','MRA','Manorville','Manorville','NY'),('US','MRB','Martinsburg','Martinsburg','WV'),('US','MRC','Columbia','Columbia','TN'),('US','MRD','Meriden','Meriden','CT'),('US','MRE','Moraine','Moraine','OH'),('US','MRF','Marfa','Marfa','TX'),('US','MRG','Morgan','Morgan','MT'),('US','MRH','Morehead City','Morehead City','NC'),('US','MRI','Mariemont','Mariemont','OH'),('US','MRJ','Moorestown','Moorestown','NJ'),('US','MRK','Marco Island','Marco Island','FL'),('US','MRL','Maryville','Maryville','TN'),('US','MRM','Merrimack','Merrimack','NH'),('US','MRN','Morganton','Morganton','NC'),('US','MRO','Hermon','Hermon','ME'),('US','MRP','Melrose Park','Melrose Park','IL'),('US','MRQ','Milford','Milford','OH'),('US','MRR','Murray Hill','Murray Hill','NJ'),('US','MRS','Mercedes','Mercedes','TX'),('US','MRT','Morristown','Morristown','NY'),('US','MRU','Meeker','Meeker','CO'),('US','MRV','Marysville','Marysville','OH'),('US','MRW','Morrow','Morrow','GA'),('US','MRX','McNary','McNary','OR'),('US','MRY','Carmel-Monterey Apt','Carmel-Monterey Apt','CA'),('US','MRZ','Martinez','Martinez','CA'),('US','MS2','Millis','Millis','MA'),('US','MS3','Maidens','Maidens','VA'),('US','MS4','Madison','Madison','VA'),('US','MS5','Murphys','Murphys','CA'),('US','MS6','Mims','Mims','FL'),('US','MS7','Millstadt','Millstadt','IL'),('US','MS8','Manitou Springs','Manitou Springs','CO'),('US','MSA','Masaryktown','Masaryktown','FL'),('US','MSB','Madison','Madison','NE'),('US','MSC','Mesa','Mesa','AZ'),('US','MSD','Mt Pleasant','Mt Pleasant','UT'),('US','MSE','Monsey','Monsey','NY'),('US','MSF','Mansfield','Mansfield','GA'),('US','MSG','Marsing','Marsing','ID'),('US','MSH','Madison Heights','Madison Heights','MI'),('US','MSJ','Mountainside','Mountainside','NJ'),('US','MSK','Mascoutah','Mascoutah','IL'),('US','MSL','Florence-Muscle Shoals Apt','Florence-Muscle Shoals Apt','AL'),('US','MSM','Madison','Madison','MS'),('US','MSN','Madison','Madison','WI'),('US','MSO','Missoula','Missoula','MT'),('US','MSP','Minneapolis/St Paul Apt','Minneapolis/St Paul Apt','MN'),('US','MSQ','Mesquite','Mesquite','TX'),('US','MSR','Marion','Marion','SC'),('US','MSS','Massena','Massena','NY'),('US','MST','Muenster','Muenster','TX'),('US','MSU','Masury','Masury','OH'),('US','MSV','Monticello','Monticello','NY'),('US','MSW','Morris','Morris','IL'),('US','MSX','Mesilla Park','Mesilla Park','NM'),('US','MSY','New Orleans','New Orleans','LA'),('US','MSZ','Moose Pass','Moose Pass','AK'),('US','MT2','Mettawa','Mettawa','IL'),('US','MT3','Middleton','Middleton','IL'),('US','MT4','Millerton','Millerton','NY'),('US','MT5','Milton','Milton','VT'),('US','MT7','Mannington','Mannington','NJ'),('US','MTA','Manteca','Manteca','CA'),('US','MTB','Montebello','Montebello','CA'),('US','MTC','Mt Clemens','Mt Clemens','MI'),('US','MTD','Mattydale','Mattydale','NY'),('US','MTE','Metairie','Metairie','LA'),('US','MTF','Metaline Falls','Metaline Falls','WA'),('US','MTG','Mont Belvieu','Mont Belvieu','TX'),('US','MTH','Marathon','Marathon','FL'),('US','MTI','Morton','Morton','IL'),('US','MTJ','Montrose','Montrose','CO'),('US','MTK','Mount Carmel','Mount Carmel','PA'),('US','MTL','Millington','Millington','MD'),('US','MTM','Metlakatla','Metlakatla','AK'),('US','MTN','Martin Mariet/Baltimore','Martin Mariet/Baltimore','MD'),('US','MTO','Mattoon','Mattoon','IL'),('US','MTP','Montauk','Montauk','NY'),('US','MTQ','Mattapoisett','Mattapoisett','MA'),('US','MTR','Manteno','Manteno','IL'),('US','MTS','Mountain Pass','Mountain Pass','CA'),('US','MTT','Mt Pleasant','Mt Pleasant','PA'),('US','MTU','Matanuska','Matanuska','AK'),('US','MTV','Martinsville','Martinsville','VA'),('US','MTW','Manitowoc','Manitowoc','WI'),('US','MTX','Memphis','Memphis','TX'),('US','MTY','Metzger','Metzger','OR'),('US','MTZ','Mantee','Mantee','MS'),('US','MUA','Matthews','Matthews','NC'),('US','MUB','Muncie','Muncie','IL'),('US','MUC','Murfreesboro','Murfreesboro','NC'),('US','MUD','Mt Dora','Mt Dora','FL'),('US','MUE','Kamuela','Kamuela','HI'),('US','MUF','Mulberry','Mulberry','FL'),('US','MUG','Millersburg','Millersburg','PA'),('US','MUH','Muleshoe','Muleshoe','TX'),('US','MUI','Fort Indiantown','Fort Indiantown','PA'),('US','MUJ','Mundelein','Mundelein','IL'),('US','MUK','Mountain View','Mountain View','GA'),('US','MUL','Mountain View','Mountain View','AL'),('US','MUM','Mountain Home','Mountain Home','TN'),('US','MUN','Muncy','Muncy','PA'),('US','MUO','Mountain Home','Mountain Home','ID'),('US','MUP','Mt Prospect','Mt Prospect','IL'),('US','MUQ','Munster','Munster','IN'),('US','MUS','Murchison','Murchison','TX'),('US','MUT','Muscatine','Muscatine','IA'),('US','MUU','Mt Union','Mt Union','PA'),('US','MUV','Mountain Top','Mountain Top','PA'),('US','MUW','Moulton','Moulton','AL'),('US','MUX','Mamou','Mamou','LA'),('US','MUY','Murray','Murray','UT'),('US','MUZ','Muscoda','Muscoda','WI'),('US','MV2','Millville','Millville','PA'),('US','MV3','Mount Vernon','Mount Vernon','TX'),('US','MV4','Moreno Valley','Moreno Valley','CA'),('US','MV5','Myersville','Myersville','MD'),('US','MVA','Mar Vista','Mar Vista','CA'),('US','MVB','Millersville','Millersville','MD'),('US','MVC','Monroeville','Monroeville','AL'),('US','MVD','Maryville','Maryville','MO'),('US','MVE','Montevideo','Montevideo','MN'),('US','MVF','Marionville','Marionville','MO'),('US','MVG','Middle Village','Middle Village','NY'),('US','MVH','Mt Vernon','Mt Vernon','NY'),('US','MVI','Millville','Millville','RI'),('US','MVJ','Mossville','Mossville','IL'),('US','MVK','Middleville','Middleville','MI'),('US','MVL','Stowe','Stowe','VT'),('US','MVM','Kayenta','Kayenta','AZ'),('US','MVN','Mount Vernon','Mount Vernon','IL'),('US','MVO','Montevallo','Montevallo','AL'),('US','MVP','Minersville','Minersville','PA'),('US','MVQ','Madisonville','Madisonville','KY'),('US','MVR','Malvern','Malvern','OH'),('US','MVS','Mercerville','Mercerville','NJ'),('US','MVT','McVeytown','McVeytown','PA'),('US','MVU','Maysville','Maysville','KY'),('US','MVV','Marysville','Marysville','MI'),('US','MVW','Mt Vernon','Mt Vernon','WA'),('US','MVX','Mt Vernon','Mt Vernon','TX'),('US','MVY','Martha\'s Vineyard','Martha\'s Vineyard','MA'),('US','MVZ','McConnelsville','McConnelsville','OH'),('US','MW2','Maplewood','Maplewood','MO'),('US','MW3','Moscow','Moscow','IA'),('US','MW4','Millwood','Millwood','WV'),('US','MW5','Mineralwells','Mineralwells','WV'),('US','MWA','Marion','Marion','IL'),('US','MWB','Mabank','Mabank','TX'),('US','MWC','Midway City','Midway City','CA'),('US','MWD','Meadow Lands','Meadow Lands','PA'),('US','MWE','Marlow Heights','Marlow Heights','MD'),('US','MWF','Mt Wolf','Mt Wolf','PA'),('US','MWG','Morgantown','Morgantown','TN'),('US','MWH','Moses Lake','Moses Lake','WA'),('US','MWI','Monroe','Monroe','WI'),('US','MWJ','Mason','Mason','MI'),('US','MWK','McGraw Park','McGraw Park','IL'),('US','MWL','Mineral Wells','Mineral Wells','TX'),('US','MWM','Windom','Windom','MN'),('US','MWN','Malvern','Malvern','PA'),('US','MWO','Middletown','Middletown','OH'),('US','MWP','Manver','Manver','PA'),('US','MWQ','Maywood/Chicago','Maywood/Chicago','IL'),('US','MWR','Mount Crawford','Mount Crawford','VA'),('US','MWS','Mt Wilson','Mt Wilson','CA'),('US','MWT','Mt Vernon','Mt Vernon','OH'),('US','MWU','Maxwell','Maxwell','OK'),('US','MWV','Middletown','Middletown','VA'),('US','MWW','Manawa','Manawa','WI'),('US','MWX','Milwaukie','Milwaukie','OR'),('US','MWY','Midway','Midway','TN'),('US','MWZ','Marrowbone','Marrowbone','KY'),('US','MXA','Manila','Manila','AR'),('US','MXB','Marion','Marion','NY'),('US','MXC','Monticello','Monticello','UT'),('US','MXD','Milner','Milner','ID'),('US','MXE','Maxton','Maxton','NC'),('US','MXF','Mt Vernon','Mt Vernon','IA'),('US','MXG','Marlboro (Marlborough)','Marlboro (Marlborough)','MA'),('US','MXH','Mt Vernon','Mt Vernon','IN'),('US','MXI','Mexico','Mexico','MO'),('US','MXJ','Monona','Monona','IA'),('US','MXK','Minatare','Minatare','NE'),('US','MXL','Milton','Milton','MA'),('US','MXM','Max Meadows','Max Meadows','VA'),('US','MXN','Milan','Milan','TN'),('US','MXO','Monticello','Monticello','IA'),('US','MXP','Meraux','Meraux','LA'),('US','MXQ','Mt Orab','Mt Orab','OH'),('US','MXR','Mt Morris','Mt Morris','IL'),('US','MXS','Martinsville','Martinsville','IN'),('US','MXT','Mt Bethel','Mt Bethel','PA'),('US','MXU','Mullins','Mullins','SC'),('US','MXV','Mt Vernon','Mt Vernon','KY'),('US','MXW','Milton','Milton','IA'),('US','MXX','Monongahela','Monongahela','PA'),('US','MXY','McCarthy','McCarthy','AK'),('US','MXZ','Monte Alto','Monte Alto','TX'),('US','MY2','Manayunk','Manayunk','PA'),('US','MY3','Monterey','Monterey','CA'),('US','MYA','Maywood','Maywood','CA'),('US','MYB','Maynard','Maynard','MN'),('US','MYC','Mystic','Mystic','CT'),('US','MYD','Meyersdale','Meyersdale','PA'),('US','MYE','Marysville','Marysville','KS'),('US','MYF','Midway','Midway','FL'),('US','MYG','Myrtle Grove','Myrtle Grove','LA'),('US','MYH','Marble Canyon','Marble Canyon','AZ'),('US','MYI','Mayville','Mayville','WI'),('US','MYJ','Mays Landing','Mays Landing','NJ'),('US','MYK','May Creek','May Creek','AK'),('US','MYL','McCall','McCall','ID'),('US','MYM','Mt Airy','Mt Airy','MD'),('US','MYN','Middleton','Middleton','MA'),('US','MYO','Mayodan','Mayodan','NC'),('US','MYP','Marysville','Marysville','PA'),('US','MYQ','Maybrook','Maybrook','NY'),('US','MYR','Myrtle Beach','Myrtle Beach','SC'),('US','MYS','Marysville','Marysville','WA'),('US','MYT','Mary Esther','Mary Esther','FL'),('US','MYU','Mekoryuk','Mekoryuk','AK'),('US','MYV','Marysville','Marysville','CA'),('US','MYW','Maywood','Maywood','NJ'),('US','MYX','Minden','Minden','LA'),('US','MYY','Madison','Madison','ME'),('US','MYZ','Mooresville','Mooresville','IN'),('US','MZA','Meridian','Meridian','CA'),('US','MZB','Meta','Meta','MO'),('US','MZC','Midvale','Midvale','UT'),('US','MZD','Millington','Millington','TN'),('US','MZE','Milroy','Milroy','PA'),('US','MZF','Mazon','Mazon','IL'),('US','MZG','Milton','Milton','NY'),('US','MZH','Milton-Freewater','Milton-Freewater','OR'),('US','MZI','McIntosh','McIntosh','AL'),('US','MZJ','Marana','Marana','AZ'),('US','MZK','Maywood Park','Maywood Park','OR'),('US','MZL','Morrisville','Morrisville','NY'),('US','MZM','Montezuma','Montezuma','IN'),('US','MZN','Methuen','Methuen','MA'),('US','MZO','Minster','Minster','OH'),('US','MZP','Mertztown','Mertztown','PA'),('US','MZQ','Mentone','Mentone','CA'),('US','MZR','Merrifield','Merrifield','MN'),('US','MZS','Monson','Monson','MA'),('US','MZT','Montclair','Montclair','CA'),('US','MZU','Monterey Park','Monterey Park','CA'),('US','MZV','Mazomanie','Mazomanie','WI'),('US','MZW','Montesano','Montesano','WA'),('US','MZX','Madison','Madison','IL'),('US','MZY','Monterey','Monterey','TN'),('US','MZZ','Marion','Marion','IN'),('US','NA2','New Augusta','New Augusta','MS'),('US','NAA','North Abington','North Abington','MA'),('US','NAB','Narrows','Narrows','VA'),('US','NAC','Naco','Naco','AZ'),('US','NAD','Menands','Menands','NY'),('US','NAE','Nanuet','Nanuet','NY'),('US','NAH','Natrona Heights','Natrona Heights','PA'),('US','NAI','Nappanee','Nappanee','IN'),('US','NAK','Natick','Natick','MA'),('US','NAL','Napoleon','Napoleon','OH'),('US','NAM','New Albany','New Albany','MS'),('US','NAN','Newnan','Newnan','GA'),('US','NAO','Wahoo','Wahoo','NE'),('US','NAP','North East','North East','MD'),('US','NAQ','Norwalk','Norwalk','CA'),('US','NAR','Lanark','Lanark','IL'),('US','NAS','Nashville','Nashville','NC'),('US','NAT','Natural Bridge','Natural Bridge','NY'),('US','NAU','North Augusta','North Augusta','SC'),('US','NAV','Nauvoo','Nauvoo','AL'),('US','NAX','Barbers Point (Oahu)','Barbers Point (Oahu)','HI'),('US','NAY','Pine Valley','Pine Valley','NY'),('US','NAZ','Nazareth','Nazareth','PA'),('US','NBA','North Billerica','North Billerica','MA'),('US','NBB','New Berlin','New Berlin','WI'),('US','NBC','North Branford','North Branford','CT'),('US','NBD','New Bedford','New Bedford','MA'),('US','NBE','Newbern','Newbern','TN'),('US','NBF','Newberry','Newberry','FL'),('US','NBH','North Baltimore','North Baltimore','OH'),('US','NBI','New Brighton','New Brighton','MN'),('US','NBJ','New Brunswick','New Brunswick','NJ'),('US','NBK','Nebraska City','Nebraska City','NE'),('US','NBL','New Bloomfield','New Bloomfield','MO'),('US','NBM','North Berwick','North Berwick','ME'),('US','NBN','North Bergen','North Bergen','NJ'),('US','NBO','Northborough','Northborough','MA'),('US','NBP','North Brookfield','North Brookfield','MA'),('US','NBQ','Sanborn','Sanborn','NY'),('US','NBR','New Berlin','New Berlin','NY'),('US','NBS','North Brunswick','North Brunswick','NJ'),('US','NBT','New Baltimore','New Baltimore','MI'),('US','NBU','Glenview','Glenview','IL'),('US','NBV','North Bay Shore','North Bay Shore','NY'),('US','NBX','New Boston','New Boston','TX'),('US','NBY','North Babylon','North Babylon','NY'),('US','NBZ','Newberry','Newberry','SC'),('US','NC3','New Carlisle','New Carlisle','IN'),('US','NCA','New Carrollton','New Carrollton','MD'),('US','NCB','Newcomb','Newcomb','TN'),('US','NCD','New Castle','New Castle','DE'),('US','NCE','Misenheimer','Misenheimer','NC'),('US','NCF','North Chelmsford','North Chelmsford','MA'),('US','NCH','North Charlotte','North Charlotte','NC'),('US','NCI','National City','National City','IL'),('US','NCK','Nicholasville','Nicholasville','KY'),('US','NCL','Nichols','Nichols','SC'),('US','NCM','Norco','Norco','LA'),('US','NCN','New Chenega','New Chenega','AK'),('US','NCO','Quonset Point','Quonset Point','RI'),('US','NCP','New Castle','New Castle','PA'),('US','NCQ','Nice','Nice','CA'),('US','NCR','North Clarendon','North Clarendon','VT'),('US','NCS','Charleston','Charleston','NC'),('US','NCT','North Scituate','North Scituate','MA'),('US','NCU','New Cumberland','New Cumberland','WV'),('US','NCV','North Cove','North Cove','NC'),('US','NCX','Norcross','Norcross','VA'),('US','NCY','New Caney','New Caney','TX'),('US','NDA','Neodesha','Neodesha','KS'),('US','NDC','North Highlands','North Highlands','CA'),('US','NDD','Nederland','Nederland','CO'),('US','NDG','North Dighton','North Dighton','MA'),('US','NDI','New Baden','New Baden','IL'),('US','NDL','Glen Dale','Glen Dale','WV'),('US','NDN','Mandan','Mandan','ND'),('US','NDO','Mendon','Mendon','MA'),('US','NDQ','Norden','Norden','CA'),('US','NDR','Mandarin','Mandarin','FL'),('US','NDU','Bondurant','Bondurant','IA'),('US','NDV','Anacostia','Anacostia','DC'),('US','NDW','Newald','Newald','WI'),('US','NDX','Nederland','Nederland','TX'),('US','NDY','Norwood','Norwood','OH'),('US','NEA','Glynco','Glynco','GA'),('US','NEB','Neah Bay','Neah Bay','WA'),('US','NEC','Neche','Neche','ND'),('US','NED','New London','New London','OH'),('US','NEE','Needham','Needham','MA'),('US','NEF','New Kingstown','New Kingstown','PA'),('US','NEG','Negley','Negley','OH'),('US','NEH','New Bethlehem','New Bethlehem','PA'),('US','NEI','Newfields','Newfields','NH'),('US','NEJ','Necedah','Necedah','WI'),('US','NEK','Newark','Newark','OH'),('US','NEL','Lakehurst','Lakehurst','NJ'),('US','NEM','New Milford','New Milford','CT'),('US','NEN','Whitehouse','Whitehouse','FL'),('US','NEO','Newton','Newton','GA'),('US','NEP','Newport','Newport','MI'),('US','NEQ','Netcong','Netcong','NJ'),('US','NER','New Carlisle','New Carlisle','OH'),('US','NES','Nesconset','Nesconset','NY'),('US','NET','New Brighton','New Brighton','PA'),('US','NEU','New Wilmington','New Wilmington','PA'),('US','NEV','New Haven','New Haven','IN'),('US','NEW','Destrehan','Destrehan','LA'),('US','NEY','Newbury','Newbury','OH'),('US','NEZ','New Paltz','New Paltz','NY'),('US','NFA','Norphlet','Norphlet','AR'),('US','NFC','Nevada City','Nevada City','CA'),('US','NFD','Newfield','Newfield','NY'),('US','NFE','Newfane','Newfane','NY'),('US','NFF','Norfolk','Norfolk','CT'),('US','NFG','New Franklin','New Franklin','MO'),('US','NFH','North Falmouth','North Falmouth','MA'),('US','NFI','Penfield','Penfield','NY'),('US','NFJ','Norfolk','Norfolk','MA'),('US','NFK','Norfolk','Norfolk','NY'),('US','NFL','Fallon','Fallon','NV'),('US','NFM','Newton Upper Falls','Newton Upper Falls','MA'),('US','NFN','New Franken','New Franken','WI'),('US','NFO','New Florence','New Florence','MO'),('US','NFQ','New Florence','New Florence','PA'),('US','NFR','New Freedom','New Freedom','PA'),('US','NFS','Newton Falls','Newton Falls','NY'),('US','NFT','North Wales','North Wales','PA'),('US','NFY','Newfoundland','Newfoundland','NJ'),('US','NGG','Kettering','Kettering','MD'),('US','NGI','Carnegie','Carnegie','OK'),('US','NGK','Naugatuck','Naugatuck','CT'),('US','NGL','Northglenn','Northglenn','CO'),('US','NGP','New Egypt','New Egypt','NJ'),('US','NGR','North Grafton','North Grafton','MA'),('US','NGT','Northgate','Northgate','ND'),('US','NGU','Narragansett','Narragansett','RI'),('US','NGV','Newton Grove','Newton Grove','NC'),('US','NGW','Niagara','Niagara','WI'),('US','NGY','Montgomery','Montgomery','OH'),('US','NGZ','Alameda','Alameda','CA'),('US','NH2','New Haven','New Haven','MO'),('US','NH3','New Haven','New Haven','NC'),('US','NHA','Naheola','Naheola','AL'),('US','NHB','New Braunfels','New Braunfels','TX'),('US','NHC','Nash, Ellis','Nash, Ellis','TX'),('US','NHD','North Hollywood','North Hollywood','CA'),('US','NHE','Hamel','Hamel','MN'),('US','NHF','North Port','North Port','FL'),('US','NHG','Nottingham','Nottingham','PA'),('US','NHH','North Hills','North Hills','CA'),('US','NHI','New Hope','New Hope','PA'),('US','NHK','Patuxent River','Patuxent River','MD'),('US','NHL','Northfield','Northfield','NJ'),('US','NHM','Northampton','Northampton','MA'),('US','NHN','New Hudson','New Hudson','MI'),('US','NHO','New Hope','New Hope','MN'),('US','NHP','Northport','Northport','AL'),('US','NHQ','North Hartland','North Hartland','VT'),('US','NHR','Mount Hermon','Mount Hermon','CA'),('US','NHS','North Anson','North Anson','ME'),('US','NHT','New Hartford','New Hartford','CT'),('US','NHU','North Huntingdon','North Huntingdon','PA'),('US','NHV','North Vassalboro','North Vassalboro','ME'),('US','NHW','Northwood, Wood','Northwood, Wood','OH'),('US','NHX','Foley','Foley','AL'),('US','NHY','New Hyde Park','New Hyde Park','NY'),('US','NHZ','Brunswick','Brunswick','ME'),('US','NIA','Niota','Niota','TN'),('US','NIB','Nikolai','Nikolai','AK'),('US','NIE','Niblack','Niblack','AK'),('US','NIH','Nighthawk','Nighthawk','WA'),('US','NII','Niantic','Niantic','CT'),('US','NIJ','Nawiliwili','Nawiliwili','HI'),('US','NIK','Nikiski','Nikiski','AK'),('US','NIL','Niles','Niles','IL'),('US','NIM','New Hampton','New Hampton','IA'),('US','NIN','Ninilchik','Ninilchik','AK'),('US','NIO','Nipomo','Nipomo','CA'),('US','NIR','Beeville','Beeville','TX'),('US','NIT','Nitro','Nitro','WV'),('US','NIV','Niceville','Niceville','FL'),('US','NIX','Nixon','Nixon','PA'),('US','NIZ','Niles','Niles','CA'),('US','NJ2','North Jackson','North Jackson','OH'),('US','NJB','Nabb','Nabb','IN'),('US','NJC','Clark','Clark','NJ'),('US','NJH','Nashville','Nashville','IN'),('US','NJJ','Jackson','Jackson','NJ'),('US','NJO','Norway','Norway','IA'),('US','NJR','North Ridgeville','North Ridgeville','OH'),('US','NJT','North Arlington','North Arlington','NJ'),('US','NKE','North Kingsville','North Kingsville','OH'),('US','NKI','Naukiti','Naukiti','AK'),('US','NKL','Conklin','Conklin','NY'),('US','NKN','Franklin','Franklin','TX'),('US','NKO','Anadarko','Anadarko','OK'),('US','NKP','New Kensington','New Kensington','PA'),('US','NKQ','Newark','Newark','CA'),('US','NKT','North Kingstown','North Kingstown','RI'),('US','NKV','Nichen Cove','Nichen Cove','AK'),('US','NKX','New Knoxville','New Knoxville','OH'),('US','NKY','North Kansas City','North Kansas City','MO'),('US','NL2','New Londonderry','New Londonderry','NH'),('US','NL3','North Long Beach','North Long Beach','CA'),('US','NLA','North Lima','North Lima','OH'),('US','NLB','North Lawrence','North Lawrence','OH'),('US','NLC','Lemoore','Lemoore','CA'),('US','NLD','New London','New London','WI'),('US','NLE','Niles','Niles','MI'),('US','NLF','Plainfield','Plainfield','IA'),('US','NLG','Nelson Lagoon','Nelson Lagoon','AK'),('US','NLI','New Lisbon','New Lisbon','WI'),('US','NLK','Central Lake','Central Lake','MI'),('US','NLL','Nunnelly','Nunnelly','TN'),('US','NLN','National City','National City','CA'),('US','NLO','New London','New London','CT'),('US','NLQ','North Loup','North Loup','NE'),('US','NLR','New Liberty','New Liberty','IA'),('US','NLS','Niles','Niles','OH'),('US','NLV','Pine Level, Johnston','Pine Level, Johnston','NC'),('US','NLW','North Little Rock','North Little Rock','AR'),('US','NLX','New Lexington','New Lexington','OH'),('US','NLY','North Lawrence','North Lawrence','NY'),('US','NM2','New Martinsville','New Martinsville','WV'),('US','NM3','New Middletown','New Middletown','IN'),('US','NMA','Marshall','Marshall','NC'),('US','NMB','North Myrtle Beach','North Myrtle Beach','SC'),('US','NMD','New Milford','New Milford','PA'),('US','NME','Nightmute','Nightmute','AK'),('US','NMF','New Milford','New Milford','NJ'),('US','NMG','Normangee','Normangee','TX'),('US','NMH','Champlin','Champlin','MN'),('US','NMI','New Miami','New Miami','OH'),('US','NMJ','Manchester','Manchester','NJ'),('US','NMK','Newmarket','Newmarket','NH'),('US','NMO','Neelys','Neelys','MO'),('US','NMQ','Newton','Newton','IL'),('US','NMS','Center Moriches','Center Moriches','NY'),('US','NMT','New Market','New Market','AL'),('US','NMV','Montgomery Village','Montgomery Village','MD'),('US','NMW','Newman','Newman','CA'),('US','NNA','Anna','Anna','OH'),('US','NNB','Nash','Nash','TX'),('US','NNC','Nanticoke','Nanticoke','PA'),('US','NND','North Bend','North Bend','OH'),('US','NNE','Mentone','Mentone','IN'),('US','NNG','Pennington','Pennington','NJ'),('US','NNI','Camp Dennison','Camp Dennison','OH'),('US','NNK','Naknek','Naknek','AK'),('US','NNL','Nondalton','Nondalton','AK'),('US','NNM','Norton','Norton','MA'),('US','NNN','Centennial','Centennial','CO'),('US','NNO','Nanticoke','Nanticoke','MD'),('US','NNR','Tanner','Tanner','AL'),('US','NNS','Newport News','Newport News','VA'),('US','NNT','Anniston','Anniston','MO'),('US','NNV','Nelsonville','Nelsonville','OH'),('US','NNW','North Newton','North Newton','KS'),('US','NNY','Newark','Newark','NY'),('US','NO2','North Oxford','North Oxford','MA'),('US','NOA','North Aurora','North Aurora','IL'),('US','NOB','North Bend','North Bend','WA'),('US','NOC','Norwich','Norwich','CT'),('US','NOD','North Olmsted','North Olmsted','OH'),('US','NOE','Noel','Noel','MO'),('US','NOF','Altoona','Altoona','IA'),('US','NOG','Norton','Norton','VA'),('US','NOH','North Haven','North Haven','CT'),('US','NOI','North Richland Hills','North Richland Hills','TX'),('US','NOK','Hancock','Hancock','MN'),('US','NOL','Nakolik River','Nakolik River','AK'),('US','NOM','Normal','Normal','IL'),('US','NON','Nelson','Nelson','GA'),('US','NOO','Noonan','Noonan','ND'),('US','NOP','Newport','Newport','RI'),('US','NOR','North','North','SC'),('US','NOS','North Manchester','North Manchester','IN'),('US','NOT','Novato','Novato','CA'),('US','NOV','Novi','Novi','MI'),('US','NOW','Norwell','Norwell','MA'),('US','NOX','New Lenox','New Lenox','IL'),('US','NOY','Noyes','Noyes','MN'),('US','NOZ','Newport','Newport','ME'),('US','NP2','New Preston','New Preston','CT'),('US','NP3','North Providence','North Providence','RI'),('US','NP4','Newport','Newport','NC'),('US','NPA','Nampa','Nampa','ID'),('US','NPB','Neptune Beach','Neptune Beach','FL'),('US','NPC','Neptune City','Neptune City','NJ'),('US','NPD','Newport','Newport','DE'),('US','NPE','North Prairie','North Prairie','WI'),('US','NPF','Newport','Newport','IN'),('US','NPG','New Providence','New Providence','IA'),('US','NPH','Nephi','Nephi','UT'),('US','NPI','New Paris','New Paris','IN'),('US','NPK','Naples','Naples','NY'),('US','NPL','Naples','Naples','NC'),('US','NPM','Newport','Newport','MN'),('US','NPN','Newport','Newport','AR'),('US','NPO','Newport','Newport','OR'),('US','NPP','New Philadelphia','New Philadelphia','PA'),('US','NPQ','Maplewood','Maplewood','MN'),('US','NPR','Newport','Newport','TN'),('US','NPS','New Prospect','New Prospect','SC'),('US','NPT','Newport','Newport','RI'),('US','NPV','Naperville','Naperville','IL'),('US','NPX','New Providence','New Providence','NJ'),('US','NPY','North Plains','North Plains','OR'),('US','NPZ','North Potomac','North Potomac','MD'),('US','NQA','Snoqualmie','Snoqualmie','WA'),('US','NQG','Newington','Newington','VA'),('US','NQI','Kingsville','Kingsville','TX'),('US','NQK','Nikishka','Nikishka','AK'),('US','NQL','Nicollet','Nicollet','MN'),('US','NQM','Nokomis','Nokomis','FL'),('US','NQO','Norco','Norco','CA'),('US','NQR','Newry','Newry','PA'),('US','NQS','New Castle','New Castle','IN'),('US','NQZ','North Rose','North Rose','NY'),('US','NRA','Glen Raven','Glen Raven','NC'),('US','NRB','Mayport','Mayport','FL'),('US','NRC','Crows Landing','Crows Landing','CA'),('US','NRD','Norwood','Norwood','NJ'),('US','NRE','Northfield','Northfield','MN'),('US','NRF','Norridge','Norridge','IL'),('US','NRG','North Reading','North Reading','MA'),('US','NRH','New Port Richey','New Port Richey','FL'),('US','NRI','Shangri-la','Shangri-la','OK'),('US','NRJ','Northridge','Northridge','CA'),('US','NRK','Newark','Newark','TX'),('US','NRL','Norlina','Norlina','NC'),('US','NRM','Natrium','Natrium','WV'),('US','NRN','North Collins','North Collins','NY'),('US','NRO','Monroe','Monroe','OH'),('US','NRP','Newport, Perry','Newport, Perry','PA'),('US','NRQ','Monroe','Monroe','IA'),('US','NRR','North','North','NY'),('US','NRS','Imperial Beach','Imperial Beach','CA'),('US','NRT','Norton','Norton','VT'),('US','NRU','North Riverside','North Riverside','IL'),('US','NRV','Centreville','Centreville','MI'),('US','NRW','New Strawn','New Strawn','KS'),('US','NRX','Monroe','Monroe','VA'),('US','NRY','North Liberty','North Liberty','IA'),('US','NS2','New Salisbury','New Salisbury','IN'),('US','NS3','Nichols, Tioga','Nichols, Tioga','NY'),('US','NSA','North Santee','North Santee','SC'),('US','NSB','New Smyrna Beach','New Smyrna Beach','FL'),('US','NSC','North Sioux City','North Sioux City','SD'),('US','NSE','Milton','Milton','FL'),('US','NSH','Nashville','Nashville','GA'),('US','NSI','North Syracuse','North Syracuse','NY'),('US','NSL','North Salt Lake','North Salt Lake','UT'),('US','NSM','North Smithfield','North Smithfield','RI'),('US','NSN','Neshanic Station','Neshanic Station','NJ'),('US','NSQ','Nesquehoning','Nesquehoning','PA'),('US','NSR','Seward','Seward','NE'),('US','NSS','Sabine Pass','Sabine Pass','TX'),('US','NST','New Stanton','New Stanton','PA'),('US','NSU','Mansura','Mansura','LA'),('US','NSV','Mannsville','Mannsville','NY'),('US','NT2','Northford','Northford','CT'),('US','NTA','North Chicago','North Chicago','IL'),('US','NTB','North Bennington','North Bennington','VT'),('US','NTC','Newtown','Newtown','CT'),('US','NTD','Port Hueneme','Port Hueneme','CA'),('US','NTE','North East','North East','PA'),('US','NTF','Northfield','Northfield','VT'),('US','NTG','Northbridge','Northbridge','MA'),('US','NTH','Natchitoches','Natchitoches','LA'),('US','NTI','Northlake','Northlake','IL'),('US','NTJ','Manti','Manti','UT'),('US','NTK','Nowata','Nowata','OK'),('US','NTL','National Gardens','National Gardens','FL'),('US','NTM','Newton','Newton','MS'),('US','NTN','Newton','Newton','MA'),('US','NTO','Nettleton','Nettleton','MS'),('US','NTP','North Pole','North Pole','AK'),('US','NTQ','Newtown Square','Newtown Square','PA'),('US','NTR','Norton Shores','Norton Shores','MI'),('US','NTS','North Charleston','North Charleston','SC'),('US','NTT','North Attleboro','North Attleboro','MA'),('US','NTU','Oceana','Oceana','VA'),('US','NTV','Northville','Northville','MI'),('US','NTW','Newtown','Newtown','PA'),('US','NTX','Nocona','Nocona','TX'),('US','NTY','North Troy','North Troy','VT'),('US','NUC','Newcastle','Newcastle','CA'),('US','NUG','Newberg','Newberg','OR'),('US','NUI','Nuiqsut','Nuiqsut','AK'),('US','NUL','Nulato','Nulato','AK'),('US','NUM','Northumberland','Northumberland','PA'),('US','NUP','Nunapitchuk','Nunapitchuk','AK'),('US','NUQ','Mountain View','Mountain View','CA'),('US','NUT','Nutley','Nutley','NJ'),('US','NUU','Blue Diamond','Blue Diamond','NV'),('US','NUV','Newark Valley','Newark Valley','NY'),('US','NUW','Whidbey Island','Whidbey Island','WA'),('US','NUY','New Berlin','New Berlin','PA'),('US','NV2','Nortonville','Nortonville','KS'),('US','NVA','Navarre','Navarre','FL'),('US','NVB','Noblesville','Noblesville','IN'),('US','NVC','New Providence','New Providence','PA'),('US','NVD','Nevada','Nevada','MO'),('US','NVE','Needville','Needville','TX'),('US','NVF','Navarre','Navarre','OH'),('US','NVG','Newell','Newell','WV'),('US','NVH','New Vienna','New Vienna','OH'),('US','NVI','Neville Island','Neville Island','PA'),('US','NVJ','North Windham','North Windham','ME'),('US','NVK','Newbury Park','Newbury Park','CA'),('US','NVL','Northvale','Northvale','NJ'),('US','NVM','McCarran','McCarran','NV'),('US','NVO','Narvon','Narvon','PA'),('US','NVP','New Centerville','New Centerville','PA'),('US','NVR','Northville (Riverhead)','Northville (Riverhead)','NY'),('US','NVS','North Las Vegas','North Las Vegas','NV'),('US','NVU','Schenevus','Schenevus','NY'),('US','NVW','Napoleonville','Napoleonville','LA'),('US','NVY','North Vernon','North Vernon','IN'),('US','NW2','North Wildwood','North Wildwood','NJ'),('US','NW3','North Windham','North Windham','CT'),('US','NW4','Northwood, Logan','Northwood, Logan','OH'),('US','NWA','New Albany','New Albany','IN'),('US','NWB','North Wilkesboro','North Wilkesboro','NC'),('US','NWC','New Canaan','New Canaan','CT'),('US','NWD','New Cumberland','New Cumberland','PA'),('US','NWE','New Holstein','New Holstein','WI'),('US','NWF','Newfield','Newfield','NJ'),('US','NWG','Newington','Newington','CT'),('US','NWH','Newport','Newport','NH'),('US','NWI','New Windsor','New Windsor','NY'),('US','NWJ','New Johnsonville','New Johnsonville','TN'),('US','NWK','Newark','Newark','DE'),('US','NWL','Cornwall','Cornwall','NY'),('US','NWM','New Windsor','New Windsor','MD'),('US','NWN','Newton','Newton','NJ'),('US','NWO','Newaygo','Newaygo','MI'),('US','NWP','New Prague','New Prague','MN'),('US','NWQ','New Weston','New Weston','OH'),('US','NWR','Newburg','Newburg','OH'),('US','NWS','New Salem','New Salem','PA'),('US','NWT','New Britain','New Britain','CT'),('US','NWU','Newton','Newton','NH'),('US','NWV','New Waverly','New Waverly','TX'),('US','NWW','New Tazewell','New Tazewell','TN'),('US','NWX','Newtown','Newtown','OH'),('US','NWY','North Weymouth','North Weymouth','MA'),('US','NWZ','Newington','Newington','NH'),('US','NXB','New Britain','New Britain','PA'),('US','NXC','New Century','New Century','KS'),('US','NXD','New Deal','New Deal','TX'),('US','NXF','New Oxford','New Oxford','PA'),('US','NXG','New Eagle','New Eagle','PA'),('US','NXI','Nixa','Nixa','MO'),('US','NXO','Norwood','Norwood','NC'),('US','NXP','Noxapater','Noxapater','MS'),('US','NXQ','Newcomerstown','Newcomerstown','OH'),('US','NXV','Nashville','Nashville','IL'),('US','NXX','Willow Grove','Willow Grove','PA'),('US','NXY','North City','North City','WA'),('US','NXZ','Nesbit','Nesbit','MS'),('US','NYA','Marathon','Marathon','NY'),('US','NYB','Cuba','Cuba','NY'),('US','NYC','New York','New York','NY'),('US','NYD','Snyder','Snyder','OK'),('US','NYE','Elba','Elba','NY'),('US','NYG','Quantico','Quantico','VA'),('US','NYH','Holley','Holley','NY'),('US','NYI','Stony Point, Rockland','Stony Point, Rockland','NY'),('US','NYL','Stanley','Stanley','WI'),('US','NYM','Malone','Malone','NY'),('US','NYP','Perry','Perry','NY'),('US','NYQ','New York Mills','New York Mills','MN'),('US','NYR','Snyder','Snyder','NY'),('US','NYS','Newberry Springs','Newberry Springs','CA'),('US','NYT','Thornwood','Thornwood','NY'),('US','NYU','Nassau','Nassau','NY'),('US','NYX','Nyack','Nyack','NY'),('US','NYY','Smyrna','Smyrna','NY'),('US','NZP','Nezperce','Nezperce','ID'),('US','NZQ','Needmore','Needmore','PA'),('US','NZW','South Weymouth','South Weymouth','MA'),('US','NZY','West Swanzey','West Swanzey','NH'),('US','OAA','Onalaska','Onalaska','WA'),('US','OAB','Oak Brook','Oak Brook','IL'),('US','OAC','Oak Creek','Oak Creek','WI'),('US','OAD','Hollandale','Hollandale','MS'),('US','OAE','Osage','Osage','IA'),('US','OAF','Orange','Orange','MA'),('US','OAG','Orangeville','Orangeville','IL'),('US','OAH','Oak Hill','Oak Hill','OH'),('US','OAI','Oak Island','Oak Island','NC'),('US','OAJ','Jacksonville','Jacksonville','NC'),('US','OAK','Oakland','Oakland','CA'),('US','OAL','Rockvale','Rockvale','TN'),('US','OAN','Olympia Fields','Olympia Fields','IL'),('US','OAQ','Bon Aqua','Bon Aqua','TN'),('US','OAR','Arnett','Arnett','OK'),('US','OAS','Oaks','Oaks','PA'),('US','OAT','Pocatalico','Pocatalico','WV'),('US','OAV','Oak Hill, Fairfax','Oak Hill, Fairfax','VA'),('US','OAW','Oakwood, Buchanan','Oakwood, Buchanan','VA'),('US','OAZ','Boaz','Boaz','AL'),('US','OB2','Oak Bluffs','Oak Bluffs','MA'),('US','OB3','Ocean Beach','Ocean Beach','CA'),('US','OB4','Osborne','Osborne','KS'),('US','OBA','Roberta','Roberta','GA'),('US','OBC','Orange Beach','Orange Beach','AL'),('US','OBE','Obetz','Obetz','OH'),('US','OBG','Orangeburg','Orangeburg','NY'),('US','OBH','Ocean Isle Beach','Ocean Isle Beach','NC'),('US','OBI','Obion','Obion','TN'),('US','OBK','Northbrook','Northbrook','IL'),('US','OBL','Noble','Noble','OK'),('US','OBR','Colbert','Colbert','GA'),('US','OBS','Robertsdale','Robertsdale','AL'),('US','OBT','Oakland','Oakland','MD'),('US','OBU','Kobuk','Kobuk','AK'),('US','OBV','Bernville','Bernville','PA'),('US','OC2','Orange City','Orange City','IA'),('US','OC3','Osco','Osco','IL'),('US','OCA','Ocean Reef','Ocean Reef','FL'),('US','OCC','Orange Cove','Orange Cove','CA'),('US','OCD','Orchard','Orchard','NE'),('US','OCE','Ocean City','Ocean City','MD'),('US','OCF','Ocala','Ocala','FL'),('US','OCG','Ochlocknee','Ochlocknee','GA'),('US','OCH','Nacogdoches','Nacogdoches','TX'),('US','OCI','Oceanic','Oceanic','AK'),('US','OCJ','Orchards','Orchards','WA'),('US','OCK','Oak Creek','Oak Creek','CO'),('US','OCL','Osceola','Osceola','IA'),('US','OCM','Ocoee','Ocoee','FL'),('US','OCN','Oceanside','Oceanside','CA'),('US','OCO','Oconomowoc','Oconomowoc','WI'),('US','OCQ','Oconto','Oconto','WI'),('US','OCR','Social Circle','Social Circle','GA'),('US','OCU','Cuba','Cuba','MO'),('US','OCV','Rockville','Rockville','CT'),('US','OCW','Washington','Washington','NC'),('US','OCY','Ocean','Ocean','NJ'),('US','ODA','Oakdale','Oakdale','LA'),('US','ODB','Ormond Beach','Ormond Beach','FL'),('US','ODC','Oildale','Oildale','CA'),('US','ODE','Odell','Odell','OR'),('US','ODF','Odessa','Odessa','FL'),('US','ODI','Mondovi','Mondovi','WI'),('US','ODL','Owendale','Owendale','MI'),('US','ODM','Odem','Odem','TX'),('US','ODN','Odenton','Odenton','MD'),('US','ODO','O\'donnell','O\'donnell','TX'),('US','ODR','Old Bridge','Old Bridge','NJ'),('US','ODS','Odessa','Odessa','NY'),('US','ODT','South Dartmouth','South Dartmouth','MA'),('US','ODV','Cordova','Cordova','IL'),('US','ODW','Oak Harbor','Oak Harbor','WA'),('US','ODY','Ordinary','Ordinary','VA'),('US','OEA','Vincennes','Vincennes','IN'),('US','OEB','Boerne','Boerne','TX'),('US','OEC','Ocean City','Ocean City','NJ'),('US','OED','Mooreland','Mooreland','OK'),('US','OEE','Florence','Florence','VT'),('US','OEF','Woorburn','Woorburn','KY'),('US','OEG','Oregon','Oregon','OH'),('US','OEL','Moselle','Moselle','MS'),('US','OEM','Coleman','Coleman','WI'),('US','OEN','Goshen','Goshen','NY'),('US','OEO','Osceola','Osceola','WI'),('US','OEP','Honea Path','Honea Path','SC'),('US','OEQ','Orwell','Orwell','OH'),('US','OER','Dover','Dover','OK'),('US','OES','Money','Money','MS'),('US','OET','Sorrento','Sorrento','CA'),('US','OEU','Orem','Orem','UT'),('US','OEV','Orangevale','Orangevale','CA'),('US','OEY','Olney','Olney','MD'),('US','OEZ','Florence','Florence','MO'),('US','OFA','O\'Fallon','O\'Fallon','IL'),('US','OFB','Bloomfield','Bloomfield','MO'),('US','OFC','Oxford','Oxford','IN'),('US','OFD','Oxford','Oxford','FL'),('US','OFI','Brookfield','Brookfield','MO'),('US','OFK','Norfolk','Norfolk','NE'),('US','OFL','O\'fallon','O\'fallon','MO'),('US','OFM','Oxford','Oxford','MI'),('US','OFN','Crofton','Crofton','KY'),('US','OFO','Old Fort','Old Fort','OH'),('US','OFR','Oak Forest','Oak Forest','IL'),('US','OFS','Los Fresno','Los Fresno','TX'),('US','OFT','Old Fort','Old Fort','NC'),('US','OFX','Colfax','Colfax','NC'),('US','OFY','Oriskany Falls','Oriskany Falls','NY'),('US','OGA','Ogallala','Ogallala','NE'),('US','OGB','Orangeburg','Orangeburg','SC'),('US','OGD','Ogden','Ogden','UT'),('US','OGE','Orange','Orange','VA'),('US','OGG','Kahului','Kahului','HI'),('US','OGI','Oregon','Oregon','IL'),('US','OGK','Oak Grove','Oak Grove','LA'),('US','OGN','Logan','Logan','OH'),('US','OGO','Ogden','Ogden','IA'),('US','OGP','Logansport','Logansport','KY'),('US','OGQ','Onondaga','Onondaga','NY'),('US','OGR','Oak Grove','Oak Grove','OR'),('US','OGS','Ogdensburg','Ogdensburg','NY'),('US','OGU','Ogdensburg','Ogdensburg','NJ'),('US','OGV','Orangeville','Orangeville','UT'),('US','OGY','Oglesby','Oglesby','IL'),('US','OH2','Oldham','Oldham','SD'),('US','OHA','Olathia','Olathia','MO'),('US','OHB','Ohio','Ohio','PA'),('US','OHC','Northeast Cape','Northeast Cape','AK'),('US','OHD','Himrod','Himrod','NY'),('US','OHE','Weston','Weston','OH'),('US','OHH','Ohatchee','Ohatchee','AL'),('US','OHI','Old Hickory','Old Hickory','AR'),('US','OHL','Oak Hill, Pittsylvania','Oak Hill, Pittsylvania','VA'),('US','OHM','Amelia','Amelia','OH'),('US','OHN','Cochran','Cochran','GA'),('US','OHO','Oak Harbor','Oak Harbor','OH'),('US','OHP','Okahumpka','Okahumpka','FL'),('US','OHQ','Oglethorpe','Oglethorpe','GA'),('US','OHR','Creston','Creston','OH'),('US','OHS','Shreve','Shreve','OH'),('US','OHV','Ohioview','Ohioview','PA'),('US','OHW','Wellston','Wellston','OH'),('US','OHY','Ohiopyle','Ohiopyle','PA'),('US','OIA','Magnolia','Magnolia','OH'),('US','OIC','Norwich','Norwich','NY'),('US','OID','Onida','Onida','SD'),('US','OIE','Olive','Olive','CA'),('US','OIG','Corning','Corning','NY'),('US','OIH','Corinth','Corinth','NY'),('US','OII','Collinsville','Collinsville','AL'),('US','OIK','McCormick','McCormick','SC'),('US','OIL','Oil City','Oil City','PA'),('US','OIN','O\'brien','O\'brien','FL'),('US','OIO','Monticello','Monticello','IN'),('US','OIS','Meredoisa','Meredoisa','IL'),('US','OIT','Lolita','Lolita','TX'),('US','OIV','Olivia','Olivia','MN'),('US','OJA','Ojai','Ojai','CA'),('US','OKA','Okolona','Okolona','MS'),('US','OKB','Okeechobee','Okeechobee','FL'),('US','OKC','Oklahoma City','Oklahoma City','OK'),('US','OKD','Oakland','Oakland','ME'),('US','OKE','Oakdale','Oakdale','MN'),('US','OKF','Oakfield','Oakfield','WI'),('US','OKG','Oakwood, Paulding','Oakwood, Paulding','OH'),('US','OKH','Oakhurst','Oakhurst','NJ'),('US','OKI','Oak Island','Oak Island','NJ'),('US','OKJ','Oklawaha','Oklawaha','FL'),('US','OKK','Kokomo','Kokomo','IN'),('US','OKL','Oak Lawn','Oak Lawn','IL'),('US','OKM','Okmulgee','Okmulgee','OK'),('US','OKN','Okeene','Okeene','OK'),('US','OKO','Oklahoma','Oklahoma','TX'),('US','OKP','Oak','Oak','PA'),('US','OKQ','Oakdale','Oakdale','CA'),('US','OKR','Oak Ridge','Oak Ridge','TN'),('US','OKS','Oshkosh','Oshkosh','NE'),('US','OKT','Brooklet','Brooklet','GA'),('US','OKU','Oakton','Oakton','VA'),('US','OKV','Oakville','Oakville','CT'),('US','OKW','Oakwood','Oakwood','GA'),('US','OKX','Okemos','Okemos','MI'),('US','OKY','Oriskany','Oriskany','NY'),('US','OKZ','Okolona','Okolona','OH'),('US','OLA','Ocilla','Ocilla','GA'),('US','OLB','Olathe','Olathe','KS'),('US','OLC','Schoolcraft','Schoolcraft','MI'),('US','OLD','Old Town','Old Town','ME'),('US','OLE','Olean','Olean','NY'),('US','OLF','Wolf Point','Wolf Point','MT'),('US','OLG','Solvang','Solvang','CA'),('US','OLH','Old Harbor','Old Harbor','AK'),('US','OLI','Oakland','Oakland','IA'),('US','OLJ','Orland','Orland','IN'),('US','OLK','Roland','Roland','OK'),('US','OLL','Old Lyme','Old Lyme','CT'),('US','OLM','Olympia','Olympia','WA'),('US','OLN','Orleans','Orleans','MA'),('US','OLO','Montello','Montello','WI'),('US','OLP','Columbus','Columbus','MO'),('US','OLQ','Tolleson','Tolleson','AZ'),('US','OLR','Coleraine','Coleraine','MN'),('US','OLS','Nogales','Nogales','AZ'),('US','OLT','Okeelanta','Okeelanta','FL'),('US','OLU','Columbus','Columbus','NE'),('US','OLV','Olive Branch','Olive Branch','MS'),('US','OLW','Oelwein','Oelwein','IA'),('US','OLY','Olney','Olney','IL'),('US','OLZ','Coleman','Coleman','OK'),('US','OM2','Omro','Omro','WI'),('US','OMA','Omaha','Omaha','NE'),('US','OMB','Macomb','Macomb','MI'),('US','OMC','Commerce','Commerce','TX'),('US','OMD','Romoland','Romoland','CA'),('US','OME','Nome','Nome','AK'),('US','OMF','Comfort','Comfort','TX'),('US','OMG','Olmito','Olmito','TX'),('US','OMH','Monmouth','Monmouth','IA'),('US','OMI','Bloomingdale','Bloomingdale','IL'),('US','OMJ','Okemah','Okemah','OK'),('US','OMK','Omak','Omak','WA'),('US','OML','Milan','Milan','MO'),('US','OMM','Commerce Township','Commerce Township','MI'),('US','OMN','Holloman Air Force Base','Holloman Air Force Base','NM'),('US','OMO','Mount Angel','Mount Angel','OR'),('US','OMP','Somerset','Somerset','WI'),('US','OMR','Commerce','Commerce','OK'),('US','OMS','Combes','Combes','TX'),('US','OMT','Somerset','Somerset','CO'),('US','OMV','Somerville','Somerville','OH'),('US','OMY','Fombell','Fombell','PA'),('US','ONA','Winona','Winona','MN'),('US','ONB','Alton','Alton','VA'),('US','ONC','Concordville','Concordville','PA'),('US','OND','Oneida','Oneida','NY'),('US','ONE','Oneco','Oneco','FL'),('US','ONF','Oneonta','Oneonta','AL'),('US','ONG','Ontonagon','Ontonagon','MI'),('US','ONH','Oneonta','Oneonta','NY'),('US','ONI','Oneida','Oneida','WI'),('US','ONJ','Morenci','Morenci','AZ'),('US','ONK','Onekama','Onekama','MI'),('US','ONL','O\'Neill','O\'Neill','NE'),('US','ONM','Socorro','Socorro','NM'),('US','ONN','Onion Bay','Onion Bay','AK'),('US','ONO','Ontario','Ontario','OR'),('US','ONP','Ono','Ono','PA'),('US','ONQ','Mason, Bayfield','Mason, Bayfield','WI'),('US','ONR','Monroe Township','Monroe Township','NJ'),('US','ONS','Onset','Onset','MA'),('US','ONT','Ontario','Ontario','CA'),('US','ONU','Mount Union','Mount Union','PA'),('US','ONV','Converse','Converse','LA'),('US','ONW','Oceanway','Oceanway','FL'),('US','ONY','Olney','Olney','TX'),('US','ONZ','New Concord','New Concord','OH'),('US','OO2','Old Orchard Beach','Old Orchard Beach','ME'),('US','OO3','Oologah','Oologah','OK'),('US','OOA','Oskaloosa','Oskaloosa','IA'),('US','OOB','Hillsboro, Madison','Hillsboro, Madison','AL'),('US','OOC','Morocco','Morocco','ID'),('US','OOD','Woodbine','Woodbine','MD'),('US','OOE','Monroe, Tippecanoe','Monroe, Tippecanoe','IN'),('US','OOF','Moore','Moore','OK'),('US','OOG','Glenwood','Glenwood','IL'),('US','OOH','Hillsboro, Lawrence','Hillsboro, Lawrence','AL'),('US','OOI','Ortonville','Ortonville','MI'),('US','OOJ','Norfork','Norfork','AR'),('US','OOK','Toksook Bay','Toksook Bay','AK'),('US','OOL','Golden','Golden','MO'),('US','OOM','Bloomer','Bloomer','WI'),('US','OON','Monon','Monon','IN'),('US','OOO','Bronwood','Bronwood','GA'),('US','OOR','Moorestown','Moorestown','PA'),('US','OOS','Crooksville','Crooksville','OH'),('US','OOT','Wolcott','Wolcott','NY'),('US','OOU','Moosup','Moosup','CT'),('US','OOV','Brookville','Brookville','OH'),('US','OOW','Otis Orchards','Otis Orchards','WA'),('US','OOX','Chesterton','Chesterton','IN'),('US','OOY','Moody','Moody','TX'),('US','OP2','Oakland Park, Broward','Oakland Park, Broward','FL'),('US','OPA','Opp','Opp','AL'),('US','OPC','Oak Park, Oakland','Oak Park, Oakland','MI'),('US','OPE','Copake Falls','Copake Falls','NY'),('US','OPH','Opheim','Opheim','MT'),('US','OPI','Opelika','Opelika','AL'),('US','OPK','Opa Locka','Opa Locka','FL'),('US','OPL','Opelousas','Opelousas','LA'),('US','OPR','Woodland Park','Woodland Park','CO'),('US','OPY','Orchard Park','Orchard Park','NY'),('US','OQH','Oak Hill','Oak Hill','FL'),('US','OQL','Coquille','Coquille','OR'),('US','OQO','Conroy','Conroy','IA'),('US','OQR','Oakridge','Oakridge','OR'),('US','OQY','Oakley','Oakley','CA'),('US','ORA','Oradell','Oradell','NJ'),('US','ORB','Orange','Orange','CT'),('US','ORC','Oregon City','Oregon City','OR'),('US','ORD','O\'Hare Apt/Chicago','O\'Hare Apt/Chicago','IL'),('US','ORE','Oak Ridge','Oak Ridge','NJ'),('US','ORF','Norfolk','Norfolk','VA'),('US','ORG','Orange','Orange','TX'),('US','ORH','Worcester','Worcester','MA'),('US','ORI','Pt Lions','Pt Lions','AK'),('US','ORJ','Orleans','Orleans','VT'),('US','ORK','Ozark','Ozark','MO'),('US','ORL','Orlando','Orlando','FL'),('US','ORM','Gorham','Gorham','NY'),('US','ORN','Orland','Orland','CA'),('US','ORO','Orosi','Orosi','CA'),('US','ORP','Orange Park','Orange Park','FL'),('US','ORQ','Norwalk','Norwalk','CT'),('US','ORR','Orrville','Orrville','OH'),('US','ORS','Morrisville','Morrisville','VT'),('US','ORT','Northway','Northway','AK'),('US','ORU','Orestes','Orestes','IN'),('US','ORV','Noorvik','Noorvik','AK'),('US','ORW','Orwell','Orwell','VT'),('US','ORY','Ordbend','Ordbend','CA'),('US','ORZ','Orleans','Orleans','IN'),('US','OS2','Osseo','Osseo','MI'),('US','OSA','Osceola','Osceola','AR'),('US','OSB','Osage Beach','Osage Beach','MO'),('US','OSC','Oscoda','Oscoda','MI'),('US','OSD','Odessa','Odessa','TX'),('US','OSE','Boscawen','Boscawen','NH'),('US','OSG','Oswego','Oswego','IL'),('US','OSH','Oshkosh','Oshkosh','WI'),('US','OSI','Collinsville','Collinsville','VA'),('US','OSK','Woonsocket','Woonsocket','SD'),('US','OSL','Oslo','Oslo','MN'),('US','OSM','Selma','Selma','OR'),('US','OSN','Collinston','Collinston','UT'),('US','OSO','Rosholt','Rosholt','SD'),('US','OSR','Foster','Foster','RI'),('US','OSS','Ossining','Ossining','NY'),('US','OST','Ostrica','Ostrica','LA'),('US','OSU','Oostburg','Oostburg','WI'),('US','OSV','Ottsville','Ottsville','PA'),('US','OSW','Oswego','Oswego','NY'),('US','OSX','Kosciusko','Kosciusko','MS'),('US','OSY','Old Saybrook','Old Saybrook','CT'),('US','OTA','Cotton Plant','Cotton Plant','AR'),('US','OTC','Monticello','Monticello','MN'),('US','OTD','Onsted','Onsted','MI'),('US','OTE','Montgomery','Montgomery','WV'),('US','OTF','Ontario','Ontario','NY'),('US','OTG','Worthington','Worthington','MN'),('US','OTH','North Bend','North Bend','OR'),('US','OTI','Port Norris','Port Norris','NJ'),('US','OTK','Poestenkill','Poestenkill','NY'),('US','OTL','Ottawa Lake','Ottawa Lake','MI'),('US','OTM','Ottumwa','Ottumwa','IA'),('US','OTN','Oaktown','Oaktown','IN'),('US','OTO','Otto','Otto','NM'),('US','OTP','Orrtanna','Orrtanna','PA'),('US','OTQ','Ottawa','Ottawa','OH'),('US','OTR','Ottawa','Ottawa','KS'),('US','OTS','Anacortes','Anacortes','WA'),('US','OTT','Cottonton','Cottonton','AL'),('US','OTU','Botetourt','Botetourt','VA'),('US','OTV','Scottsville','Scottsville','NY'),('US','OTW','Ottawa','Ottawa','IL'),('US','OTZ','Kotzebue','Kotzebue','AK'),('US','OUA','Mount Ayr','Mount Ayr','IA'),('US','OUC','Council','Council','ID'),('US','OUD','Mound','Mound','MN'),('US','OUF','Oakland','Oakland','IL'),('US','OUG','South Gate','South Gate','FL'),('US','OUH','Southgate','Southgate','KY'),('US','OUI','Blountville','Blountville','TN'),('US','OUK','Mounds','Mounds','OK'),('US','OUL','South Charleston','South Charleston','OH'),('US','OUM','Mount Meigs','Mount Meigs','AL'),('US','OUN','Norman','Norman','OK'),('US','OUO','Mount Morris','Mount Morris','NY'),('US','OUR','Ouray','Ouray','CO'),('US','OUT','Courtdale','Courtdale','PA'),('US','OUV','Mount Vernon','Mount Vernon','MO'),('US','OUY','South Yarmouth','South Yarmouth','MA'),('US','OV2','Orangeville','Orangeville','PA'),('US','OVA','Solvay','Solvay','NY'),('US','OVD','Overland','Overland','MO'),('US','OVE','Oroville','Oroville','CA'),('US','OVH','Olivehurst','Olivehurst','CA'),('US','OVI','Covington','Covington','OH'),('US','OVL','Overland Park','Overland Park','KS'),('US','OVN','Monroe','Monroe','OR'),('US','OVR','Overpeck','Overpeck','OH'),('US','OVW','Oroville','Oroville','WA'),('US','OVX','Clover, Halifax','Clover, Halifax','VA'),('US','OVZ','Otwell','Otwell','AR'),('US','OW2','Onaway','Onaway','MI'),('US','OW3','Owasso','Owasso','OK'),('US','OWA','Owatonna','Owatonna','MN'),('US','OWB','Owensboro','Owensboro','KY'),('US','OWC','Welch','Welch','OK'),('US','OWD','Norwood','Norwood','MA'),('US','OWE','Lowell','Lowell','NC'),('US','OWG','Owego','Owego','NY'),('US','OWI','Owings Mills','Owings Mills','MD'),('US','OWK','Norridgewock','Norridgewock','ME'),('US','OWL','Bowling Green','Bowling Green','MO'),('US','OWN','Orrstown','Orrstown','PA'),('US','OWO','Owosso','Owosso','MI'),('US','OWP','Orwigsburg','Orwigsburg','PA'),('US','OWT','Brownstown Township','Brownstown Township','MI'),('US','OWU','Oakwood, Oakland','Oakwood, Oakland','MI'),('US','OWV','Owensville','Owensville','MO'),('US','OX2','Oxford','Oxford','ME'),('US','OXA','Oxford','Oxford','IA'),('US','OXB','Oxford','Oxford','MA'),('US','OXC','Oxford','Oxford','CT'),('US','OXD','Oxford','Oxford','OH'),('US','OXF','Oxford','Oxford','NC'),('US','OXG','Oxford','Oxford','GA'),('US','OXH','Oxon Hill','Oxon Hill','MD'),('US','OXK','Oakland Mills','Oakland Mills','MD'),('US','OXL','Olin','Olin','NC'),('US','OXN','Oxnard','Oxnard','CA'),('US','OXO','Oxford','Oxford','AL'),('US','OXP','Newton','Newton','NC'),('US','OXQ','Corunna','Corunna','IN'),('US','OXR','Oxnard-Ventura Apt','Oxnard-Ventura Apt','CA'),('US','OXT','Olanta','Olanta','PA'),('US','OXX','Oasis','Oasis','CA'),('US','OYB','Oyster Bay','Oyster Bay','NY'),('US','OYC','Boyce','Boyce','LA'),('US','OYD','Boyden','Boyden','IA'),('US','OYI','Oneida','Oneida','TN'),('US','OYM','Otay Mesa','Otay Mesa','CA'),('US','OYN','Brooklyn','Brooklyn','IA'),('US','OYS','Yosemite Ntl Park','Yosemite Ntl Park','CA'),('US','OYT','Savoy','Savoy','TX'),('US','OYY','Troy','Troy','IN'),('US','OZA','Ozona','Ozona','TX'),('US','OZB','Millheim','Millheim','PA'),('US','OZE','Ocoee, Polk','Ocoee, Polk','TN'),('US','OZI','Old Monroe','Old Monroe','MO'),('US','OZK','Ozark','Ozark','AR'),('US','OZO','Ozone Park/Queens/New York','Ozone Park/Queens/New York','NY'),('US','OZR','Ozark','Ozark','AL'),('US','OZX','Nerstrand','Nerstrand','MN'),('US','OZZ','Osseo','Osseo','WI'),('US','PAA','Pine Apple','Pine Apple','AL'),('US','PAB','Palm Beach','Palm Beach','FL'),('US','PAC','Park City','Park City','UT'),('US','PAD','Paulding','Paulding','OH'),('US','PAE','Everett','Everett','WA'),('US','PAF','Plainfield','Plainfield','IN'),('US','PAG','Pisgah','Pisgah','AL'),('US','PAH','Paducah','Paducah','KY'),('US','PAI','Paintsville','Paintsville','KY'),('US','PAK','Hanapepe','Hanapepe','HI'),('US','PAL','Pt Allen','Pt Allen','HI'),('US','PAM','Parma','Parma','MI'),('US','PAN','Patterson','Patterson','NY'),('US','PAO','Palo Alto','Palo Alto','CA'),('US','PAP','Pleasant Plain','Pleasant Plain','OH'),('US','PAQ','Palmer','Palmer','AK'),('US','PAR','Parlier','Parlier','CA'),('US','PAS','Pasadena','Pasadena','TX'),('US','PAT','Paterson','Paterson','NJ'),('US','PAU','Paulsboro','Paulsboro','NJ'),('US','PAV','Pearl River','Pearl River','NY'),('US','PAW','Pawtucket','Pawtucket','RI'),('US','PAX','Paxson','Paxson','AK'),('US','PAY','Perth Amboy','Perth Amboy','NJ'),('US','PAZ','Paul','Paul','ID'),('US','PB2','Petersburg, Menard','Petersburg, Menard','IL'),('US','PB3','Prestonsburg','Prestonsburg','KY'),('US','PB4','Pensacola Beach','Pensacola Beach','FL'),('US','PBA','Pebble Beach','Pebble Beach','CA'),('US','PBB','Petersburg','Petersburg','TX'),('US','PBC','Pt of Palm Beach','Pt of Palm Beach','FL'),('US','PBD','Pembroke','Pembroke','FL'),('US','PBE','Palatine Bridge','Palatine Bridge','NY'),('US','PBF','Pine Bluff','Pine Bluff','AR'),('US','PBG','Pittsburg','Pittsburg','CA'),('US','PBH','Parma','Parma','OH'),('US','PBI','West Palm Beach','West Palm Beach','FL'),('US','PBJ','Palmyra','Palmyra','NJ'),('US','PBK','Pack Creek','Pack Creek','AK'),('US','PBL','Pinebluff','Pinebluff','NC'),('US','PBN','North Palm Beach','North Palm Beach','FL'),('US','PBO','Pine Brook','Pine Brook','NJ'),('US','PBQ','Pittsboro','Pittsboro','IN'),('US','PBR','Pitsburg','Pitsburg','OH'),('US','PBS','Boswell','Boswell','PA'),('US','PBT','Pabst','Pabst','GA'),('US','PBU','Petersburg','Petersburg','PA'),('US','PBV','Preston','Preston','MD'),('US','PBW','Pt Bienville','Pt Bienville','MS'),('US','PBY','Palm Bay','Palm Bay','FL'),('US','PC2','Pinecrest','Pinecrest','CA'),('US','PC3','Princeton','Princeton','IA'),('US','PC4','Piper City','Piper City','IL'),('US','PCA','Portage Creek','Portage Creek','AK'),('US','PCB','Phil Campbell','Phil Campbell','AL'),('US','PCC','Placentia','Placentia','CA'),('US','PCD','Prairie du Chien','Prairie du Chien','WI'),('US','PCE','Painter Creek','Painter Creek','AK'),('US','PCF','Pitcairn','Pitcairn','PA'),('US','PCG','Peach Glen','Peach Glen','PA'),('US','PCH','Pt Charlotte','Pt Charlotte','FL'),('US','PCI','Plant City','Plant City','FL'),('US','PCJ','Princeton','Princeton','IN'),('US','PCK','Porcupine Creek','Porcupine Creek','AK'),('US','PCL','Pocola','Pocola','OK'),('US','PCM','Pass Christian','Pass Christian','MS'),('US','PCN','Pt Clinton','Pt Clinton','OH'),('US','PCO','Princeton','Princeton','IL'),('US','PCP','Patchogue','Patchogue','NY'),('US','PCQ','Patterson','Patterson','CA'),('US','PCR','Point Comfort','Point Comfort','TX'),('US','PCS','Ponchatoula','Ponchatoula','LA'),('US','PCT','Princeton','Princeton','NJ'),('US','PCU','Picayune','Picayune','MS'),('US','PCV','Port Canaveral','Port Canaveral','FL'),('US','PCW','Pachuta','Pachuta','MS'),('US','PCX','Pt Costa','Pt Costa','CA'),('US','PCY','Paden City','Paden City','WV'),('US','PCZ','Pace','Pace','FL'),('US','PDA','Peace Dale','Peace Dale','RI'),('US','PDB','Pedro Bay','Pedro Bay','AK'),('US','PDE','Palisade','Palisade','NJ'),('US','PDI','Port Madison','Port Madison','WA'),('US','PDL','Pt Lions','Pt Lions','AL'),('US','PDM','Pounding Mill','Pounding Mill','VA'),('US','PDN','Pendleton','Pendleton','IN'),('US','PDO','Pendleton','Pendleton','SC'),('US','PDP','Philadelphia','Philadelphia','NY'),('US','PDQ','Doral','Doral','FL'),('US','PDS','Powder Springs','Powder Springs','GA'),('US','PDT','Pendleton','Pendleton','OR'),('US','PDW','Pt Edwards','Pt Edwards','WI'),('US','PDX','Portland','Portland','OR'),('US','PDY','Pittsford','Pittsford','NY'),('US','PE2','Port Ewen','Port Ewen','NY'),('US','PEA','Pearl Harbor','Pearl Harbor','HI'),('US','PEB','Pt Elizabeth','Pt Elizabeth','NJ'),('US','PEC','Pelican','Pelican','AK'),('US','PED','Peabody','Peabody','MA'),('US','PEE','Peterman','Peterman','AL'),('US','PEF','Pt Everglades','Pt Everglades','FL'),('US','PEG','Prairie Grove','Prairie Grove','AR'),('US','PEH','Pelham','Pelham','GA'),('US','PEI','Peoria','Peoria','AZ'),('US','PEJ','Pearson','Pearson','GA'),('US','PEK','Pecksville','Pecksville','NY'),('US','PEL','Pella','Pella','IA'),('US','PEM','Pemberville','Pemberville','OH'),('US','PEN','Penndel','Penndel','PA'),('US','PEO','Petrolia','Petrolia','PA'),('US','PEP','Pepperell','Pepperell','MA'),('US','PEQ','Pecos City','Pecos City','TX'),('US','PER','Perris','Perris','CA'),('US','PES','Pearl','Pearl','MS'),('US','PET','Petoskey','Petoskey','MI'),('US','PEU','Pearsall','Pearsall','TX'),('US','PEV','Pipersville','Pipersville','PA'),('US','PEW','Pewaukee','Pewaukee','WI'),('US','PEX','Pelham Manor','Pelham Manor','NY'),('US','PEY','Pleasant Valley','Pleasant Valley','MO'),('US','PEZ','Pearl City','Pearl City','IL'),('US','PFA','Paf Warren','Paf Warren','AK'),('US','PFB','Paxton','Paxton','IL'),('US','PFC','Pacific City','Pacific City','OR'),('US','PFD','Pt Frederick','Pt Frederick','AK'),('US','PFE','Plainfield','Plainfield','CT'),('US','PFF','Pomfret Center','Pomfret Center','CT'),('US','PFG','Providence Forge','Providence Forge','VA'),('US','PFH','Pleasant Hill','Pleasant Hill','CA'),('US','PFI','Post Falls','Post Falls','ID'),('US','PFJ','Pennsville','Pennsville','NJ'),('US','PFK','Prince Frederick','Prince Frederick','MD'),('US','PFL','Poinciana','Poinciana','FL'),('US','PFN','Panama City','Panama City','FL'),('US','PFO','Park Forest','Park Forest','IL'),('US','PFP','Palmetto','Palmetto','GA'),('US','PFQ','Pacifica','Pacifica','CA'),('US','PFR','Pomfret','Pomfret','CT'),('US','PFS','Point of Rocks','Point of Rocks','WY'),('US','PFT','Pfaftown','Pfaftown','NC'),('US','PFV','Pflugerville','Pflugerville','TX'),('US','PFX','Pharr','Pharr','TX'),('US','PGA','Page','Page','AZ'),('US','PGB','Pt Gibson','Pt Gibson','MS'),('US','PGC','Petersburg','Petersburg','WV'),('US','PGD','Punta Gorda','Punta Gorda','FL'),('US','PGE','Pagedale','Pagedale','MO'),('US','PGF','Pisgah Forest','Pisgah Forest','NC'),('US','PGG','Pendergrass','Pendergrass','GA'),('US','PGH','Pt Gamble','Pt Gamble','WA'),('US','PGI','Portageville','Portageville','MO'),('US','PGJ','Pine Grove, Clearfield','Pine Grove, Clearfield','PA'),('US','PGL','Pascagoula','Pascagoula','MS'),('US','PGM','Pt Graham','Pt Graham','AK'),('US','PGN','Piegan','Piegan','MT'),('US','PGO','Pagosa Springs','Pagosa Springs','CO'),('US','PGP','Penns Grove','Penns Grove','NJ'),('US','PGR','Paragould','Paragould','AR'),('US','PGS','Peach Springs','Peach Springs','AZ'),('US','PGT','Pennington','Pennington','AR'),('US','PGV','Greenville','Greenville','NC'),('US','PGW','Parkwood','Parkwood','PA'),('US','PGY','Spring Valley, San Diego','Spring Valley, San Diego','CA'),('US','PH2','Pocahontas ','Pocahontas ','MS'),('US','PH3','Philmont','Philmont','NY'),('US','PH4','Panhandle, Cass','Panhandle, Cass','TX'),('US','PHA','Phenix City','Phenix City','AL'),('US','PHB','Peoria Heights','Peoria Heights','IL'),('US','PHC','Pointe a la Hache','Pointe a la Hache','LA'),('US','PHD','New Philadelphia','New Philadelphia','OH'),('US','PHE','Pelahatchie','Pelahatchie','MS'),('US','PHF','Hampton-Williamsburg-Newport News Apt','Hampton-Williamsburg-Newport News Apt','VA'),('US','PHG','Pittsburg','Pittsburg','TX'),('US','PHH','Pocahontas','Pocahontas','TN'),('US','PHI','Phillipsburg','Phillipsburg','NJ'),('US','PHJ','Phillipsburg','Phillipsburg','KS'),('US','PHK','Pahokee','Pahokee','FL'),('US','PHL','Philadelphia','Philadelphia','PA'),('US','PHM','Prospect Harbor','Prospect Harbor','ME'),('US','PHN','Pt Huron','Pt Huron','MI'),('US','PHO','Point Hope','Point Hope','AK'),('US','PHP','Philip','Philip','SD'),('US','PHQ','Panorama City','Panorama City','CA'),('US','PHR','Hampshire','Hampshire','TN'),('US','PHS','Pinehurst','Pinehurst','MA'),('US','PHT','Paris','Paris','TN'),('US','PHU','Parachute','Parachute','CO'),('US','PHV','Pt Hudson','Pt Hudson','LA'),('US','PHW','Pelham','Pelham','NY'),('US','PHX','Phoenix','Phoenix','AZ'),('US','PHY','Panhandle, Carson','Panhandle, Carson','TX'),('US','PHZ','Pinehurst','Pinehurst','NC'),('US','PIA','Peoria','Peoria','IL'),('US','PIB','Pontiac','Pontiac','SC'),('US','PIC','Picacho','Picacho','AZ'),('US','PID','Pine Hill','Pine Hill','AL'),('US','PIE','St Petersburg','St Petersburg','FL'),('US','PIF','Pierson','Pierson','FL'),('US','PIG','Pigeon','Pigeon','MI'),('US','PIH','Pocatello','Pocatello','ID'),('US','PIJ','Piedmont','Piedmont','SC'),('US','PIK','Pikeville','Pikeville','TN'),('US','PIL','Piscataway','Piscataway','NJ'),('US','PIM','Pine Mountain','Pine Mountain','GA'),('US','PIN','Pinecreek','Pinecreek','MN'),('US','PIP','Pilot Point','Pilot Point','AK'),('US','PIQ','Piedmont','Piedmont','MO'),('US','PIR','Pierre','Pierre','SD'),('US','PIS','Port Isabel','Port Isabel','TX'),('US','PIT','Pittsburgh','Pittsburgh','PA'),('US','PIU','Piru','Piru','CA'),('US','PIV','Pineville','Pineville','AL'),('US','PIW','Pilottown','Pilottown','LA'),('US','PIX','Piedmont','Piedmont','KS'),('US','PIY','Port Ivory/Staten Isl/New York','Port Ivory/Staten Isl/New York','NY'),('US','PIZ','Point Lay','Point Lay','AK'),('US','PJB','Payson','Payson','AZ'),('US','PJD','Portland','Portland','IN'),('US','PJH','Point Judith','Point Judith','RI'),('US','PJK','Pierce','Pierce','ID'),('US','PJL','Porthill','Porthill','ID'),('US','PJO','Princeton Junction','Princeton Junction','NJ'),('US','PJP','Phillips','Phillips','WI'),('US','PJR','Pine River','Pine River','MN'),('US','PJS','Pt San Juan','Pt San Juan','AK'),('US','PJV','Port Jervis','Port Jervis','NY'),('US','PKA','Napaskiak','Napaskiak','AK'),('US','PKB','Parkersburg','Parkersburg','WV'),('US','PKC','Park City','Park City','IL'),('US','PKD','Park Rapids','Park Rapids','MN'),('US','PKE','Prior Lake','Prior Lake','MN'),('US','PKF','Park Falls','Park Falls','WI'),('US','PKH','Park Hills','Park Hills','MO'),('US','PKI','Pekin','Pekin','IL'),('US','PKJ','Park Junction','Park Junction','PA'),('US','PKK','Pikeville','Pikeville','KY'),('US','PKL','Pulaski','Pulaski','TN'),('US','PKM','Pocomoke City','Pocomoke City','MD'),('US','PKN','Pedricktown','Pedricktown','NJ'),('US','PKO','Pandora','Pandora','OH'),('US','PKP','Parkesburg','Parkesburg','PA'),('US','PKR','Parker Ford','Parker Ford','PA'),('US','PKS','Perkasie','Perkasie','PA'),('US','PKT','Parkton','Parkton','NC'),('US','PKU','Piketon','Piketon','OH'),('US','PKV','Spokane Valley','Spokane Valley','WA'),('US','PKW','Parker','Parker','WA'),('US','PKX','Pekin','Pekin','IN'),('US','PKY','Parksley','Parksley','VA'),('US','PKZ','Parkrose','Parkrose','OR'),('US','PL2','Palmer','Palmer','PA'),('US','PL3','Plato','Plato','MO'),('US','PL4','Plympton','Plympton','MA'),('US','PLA','Palmerton','Palmerton','PA'),('US','PLB','Plattsburgh','Plattsburgh','NY'),('US','PLC','Pearl City (Oahu)','Pearl City (Oahu)','HI'),('US','PLD','Poland Spring','Poland Spring','ME'),('US','PLE','Palatine','Palatine','IL'),('US','PLF','Plainfield','Plainfield','NJ'),('US','PLG','Plaines','Plaines','IL'),('US','PLH','Plymouth','Plymouth','OH'),('US','PLI','Plainfield','Plainfield','IL'),('US','PLK','Branson','Branson','MO'),('US','PLL','Pt Allen','Pt Allen','LA'),('US','PLM','Palm Coast','Palm Coast','FL'),('US','PLN','Pineland','Pineland','FL'),('US','PLO','Platteville','Platteville','CO'),('US','PLP','Pleasant Prairie','Pleasant Prairie','WI'),('US','PLQ','Plaquemine','Plaquemine','LA'),('US','PLR','Pell City','Pell City','AL'),('US','PLS','Plains','Plains','GA'),('US','PLT','Palatka','Palatka','FL'),('US','PLU','Pt Ludlow','Pt Ludlow','WA'),('US','PLV','Port Lavaca','Port Lavaca','TX'),('US','PLW','Plover','Plover','WI'),('US','PLX','Plain City','Plain City','OH'),('US','PLY','Plymouth','Plymouth','IN'),('US','PLZ','Plano','Plano','TX'),('US','PM2','Pine Mountain Valley','Pine Mountain Valley','GA'),('US','PM3','Port Monmouth','Port Monmouth','NJ'),('US','PM4','Port Morris, Bronx','Port Morris, Bronx','NY'),('US','PMA','Pomona','Pomona','NY'),('US','PMB','Pembina','Pembina','ND'),('US','PMC','Pineville','Pineville','WV'),('US','PMD','Palm Desert','Palm Desert','CA'),('US','PME','Port Manatee','Port Manatee','FL'),('US','PMF','Plymouth','Plymouth','FL'),('US','PMG','Palm Beach Gardens','Palm Beach Gardens','FL'),('US','PMH','Portsmouth','Portsmouth','OH'),('US','PMI','Palm City','Palm City','FL'),('US','PMJ','Pompton Plains','Pompton Plains','NJ'),('US','PMK','Potomac','Potomac','MD'),('US','PML','Pt Moller','Pt Moller','AK'),('US','PMM','Plymouth Meeting','Plymouth Meeting','PA'),('US','PMN','Pitman','Pitman','NJ'),('US','PMO','Pomona','Pomona','MO'),('US','PMQ','Paramount','Paramount','CA'),('US','PMR','Palmyra','Palmyra','MO'),('US','PMS','Lemasters','Lemasters','PA'),('US','PMT','Palmetto','Palmetto','FL'),('US','PMU','Paimiut','Paimiut','AK'),('US','PMV','Port MacKenzie','Port MacKenzie','AK'),('US','PMW','Plymouth','Plymouth','WI'),('US','PMX','Palmer','Palmer','MA'),('US','PMY','Plymouth','Plymouth','PA'),('US','PMZ','Palmertown','Palmertown','PA'),('US','PN2','Pana','Pana','IL'),('US','PN3','Pioneer, Amador','Pioneer, Amador','CA'),('US','PN4','Pound','Pound','VA'),('US','PNA','Pinedale','Pinedale','AZ'),('US','PNB','Pontoon Beach','Pontoon Beach','IL'),('US','PNC','Ponca City','Ponca City','OK'),('US','PND','Pearland','Pearland','TX'),('US','PNE','Philadelphia North East Apt','Philadelphia North East Apt','PA'),('US','PNF','Peterson\'s Point','Peterson\'s Point','AK'),('US','PNG','Pleasant Gap','Pleasant Gap','PA'),('US','PNH','Pine Hall','Pine Hall','NC'),('US','PNI','Pine Island','Pine Island','NY'),('US','PNJ','Pt Newark','Pt Newark','NJ'),('US','PNK','Princeton','Princeton','KY'),('US','PNL','Pinedale','Pinedale','CA'),('US','PNM','Fennimore','Fennimore','WI'),('US','PNN','Princeton','Princeton','ME'),('US','PNO','Plano','Plano','IL'),('US','PNP','Pentwater','Pentwater','MI'),('US','PNQ','Patterson','Patterson','NC'),('US','PNR','Penn Run','Penn Run','PA'),('US','PNS','Pensacola','Pensacola','FL'),('US','PNT','Piedmont','Piedmont','WV'),('US','PNU','Panguitch','Panguitch','UT'),('US','PNV','Pineville','Pineville','NC'),('US','PNW','Plainwell','Plainwell','MI'),('US','PNX','Sherman-Denison','Sherman-Denison','TX'),('US','PNY','Pine City','Pine City','MN'),('US','PNZ','Princeville','Princeville','IL'),('US','PO2','Port Orford','Port Orford','OR'),('US','POA','Pt Arthur','Pt Arthur','TX'),('US','POB','Pt Bolivar','Pt Bolivar','TX'),('US','POC','La Verne','La Verne','CA'),('US','POD','Porterdale','Porterdale','GA'),('US','POE','Fort Polk','Fort Polk','LA'),('US','POF','Poplar Bluff','Poplar Bluff','MO'),('US','POG','Pottersburg','Pottersburg','OH'),('US','POH','Pocahontas','Pocahontas','IA'),('US','POI','Pontiac','Pontiac','IL'),('US','POJ','Portage','Portage','IN'),('US','POK','Pontotoc','Pontotoc','MS'),('US','POL','Portland','Portland','MD'),('US','POM','Portsmouth','Portsmouth','RI'),('US','PON','Pt Neches','Pt Neches','TX'),('US','POO','Polo','Polo','IL'),('US','POP','Prospect','Prospect','KY'),('US','POQ','Polk Inlet','Polk Inlet','AK'),('US','POR','Pocono Manor','Pocono Manor','PA'),('US','POS','Polson','Polson','MT'),('US','POT','Pt Tampa','Pt Tampa','FL'),('US','POU','Poughkeepsie','Poughkeepsie','NY'),('US','POV','Poynette','Poynette','WI'),('US','POW','Pt Washington','Pt Washington','NY'),('US','POX','Poca','Poca','WV'),('US','POY','Lovell-Powell Apt','Lovell-Powell Apt','WY'),('US','POZ','Pooler','Pooler','GA'),('US','PP2','Palos Park','Palos Park','IL'),('US','PP3','Point Pleasant Beach','Point Pleasant Beach','NJ'),('US','PPA','Pampa','Pampa','TX'),('US','PPB','Pinellas Park','Pinellas Park','FL'),('US','PPC','Prospect Creek','Prospect Creek','AK'),('US','PPD','Camp Pendleton','Camp Pendleton','CA'),('US','PPE','Pipestone','Pipestone','MN'),('US','PPF','Parsons','Parsons','KS'),('US','PPH','Pacific Palisades','Pacific Palisades','CA'),('US','PPI','Philippi','Philippi','WV'),('US','PPJ','Pamplico','Pamplico','SC'),('US','PPK','Prospect Park','Prospect Park','PA'),('US','PPL','Pleasant Plains','Pleasant Plains','IL'),('US','PPM','Pompano Beach','Pompano Beach','FL'),('US','PPN','Prophetstown','Prophetstown','IL'),('US','PPO','Sparrows Point','Sparrows Point','MD'),('US','PPP','Philpot','Philpot','KY'),('US','PPR','Pt Providence','Pt Providence','PA'),('US','PPS','Pennsauken','Pennsauken','NJ'),('US','PPT','Potsdam','Potsdam','NY'),('US','PPV','Pt Protection','Pt Protection','AK'),('US','PPW','Paw Paw','Paw Paw','MI'),('US','PPY','Parsippany','Parsippany','NJ'),('US','PPZ','Point Pleasant','Point Pleasant','WV'),('US','PQA','Piqua','Piqua','OH'),('US','PQB','Paton','Paton','IA'),('US','PQC','Pomona','Pomona','CA'),('US','PQD','Portland','Portland','TN'),('US','PQH','Peachtree City','Peachtree City','GA'),('US','PQI','Presque Isle','Presque Isle','ME'),('US','PQL','Pelican','Pelican','LA'),('US','PQM','Palm','Palm','PA'),('US','PQN','Pequannock','Pequannock','NJ'),('US','PQO','Pomona','Pomona','IL'),('US','PQQ','Penn Yan','Penn Yan','NY'),('US','PQR','Pageland','Pageland','SC'),('US','PQS','Pilot Station','Pilot Station','AK'),('US','PQT','Portal','Portal','ND'),('US','PQU','Pico Rivera','Pico Rivera','CA'),('US','PQV','Pahrump','Pahrump','NV'),('US','PQW','Prescott','Prescott','WA'),('US','PQY','Perry','Perry','OH'),('US','PQZ','Patten','Patten','ME'),('US','PR2','Penrose','Penrose','CO'),('US','PR3','Perkins','Perkins','OK'),('US','PR4','Piercy','Piercy','CA'),('US','PR5','Proctor','Proctor','WV'),('US','PR6','Prairie','Prairie','MS'),('US','PR7','Puerto Rico','Puerto Rico','TX'),('US','PRA','Prairieville','Prairieville','LA'),('US','PRB','Paso Robles','Paso Robles','CA'),('US','PRC','Prescott','Prescott','AZ'),('US','PRD','Pt Reading','Pt Reading','NJ'),('US','PRE','Presidio','Presidio','TX'),('US','PRF','Pt Johnson','Pt Johnson','AK'),('US','PRG','Progreso','Progreso','TX'),('US','PRH','Preston','Preston','WA'),('US','PRI','Perrine','Perrine','FL'),('US','PRJ','Pt Royal','Pt Royal','SC'),('US','PRK','Parkridge','Parkridge','NJ'),('US','PRL','Pt Oceanic','Pt Oceanic','AK'),('US','PRM','Paramus','Paramus','NJ'),('US','PRN','Preston','Preston','IA'),('US','PRO','Perry','Perry','IA'),('US','PRP','Paris','Paris','IL'),('US','PRQ','Powell','Powell','WY'),('US','PRR','Perry','Perry','OK'),('US','PRS','Point Roberts','Point Roberts','WA'),('US','PRT','Point Retreat','Point Retreat','AK'),('US','PRU','Prinsburg','Prinsburg','MN'),('US','PRV','Prattville','Prattville','AL'),('US','PRW','Prentice','Prentice','WI'),('US','PRX','Paris','Paris','TX'),('US','PRY','Pt Blakely','Pt Blakely','WA'),('US','PRZ','Prineville','Prineville','OR'),('US','PS2','Posen','Posen','MI'),('US','PS3','Prairie du Sac','Prairie du Sac','WI'),('US','PSA','Palisades Park','Palisades Park','NJ'),('US','PSB','Bellefonte-Clearfield Apt','Bellefonte-Clearfield Apt','PA'),('US','PSC','Pasco','Pasco','WA'),('US','PSD','Pasadena','Pasadena','CA'),('US','PSE','Passaic','Passaic','NJ'),('US','PSF','Pittsfield','Pittsfield','MA'),('US','PSG','Petersburg','Petersburg','AK'),('US','PSH','Peshtigo','Peshtigo','WI'),('US','PSI','Potosi','Potosi','MO'),('US','PSJ','Port Saint Joe','Port Saint Joe','FL'),('US','PSK','Dublin','Dublin','VA'),('US','PSL','Pt San Luis','Pt San Luis','CA'),('US','PSM','Portsmouth','Portsmouth','NH'),('US','PSN','Palestine','Palestine','TX'),('US','PSO','Preston','Preston','GA'),('US','PSP','Palm Springs','Palm Springs','CA'),('US','PSR','Pottsboro','Pottsboro','TX'),('US','PSS','Presque Isle','Presque Isle','MI'),('US','PST','Peosta','Peosta','IA'),('US','PSU','Parish','Parish','NY'),('US','PSV','Pottsville','Pottsville','PA'),('US','PSW','Plainview','Plainview','OH'),('US','PSX','Palacios','Palacios','TX'),('US','PSY','Port Sulphur','Port Sulphur','LA'),('US','PSZ','Parsons','Parsons','TN'),('US','PT2','Patterson','Patterson','WA'),('US','PT4','Petal','Petal','MS'),('US','PT5','Pleasanton','Pleasanton','TX'),('US','PTA','Pt Alsworth','Pt Alsworth','AK'),('US','PTB','Petersburg','Petersburg','VA'),('US','PTC','Pt Alice','Pt Alice','AK'),('US','PTD','Pt Alexander','Pt Alexander','AK'),('US','PTE','Portage','Portage','MI'),('US','PTF','Pittsfield','Pittsfield','ME'),('US','PTG','Pt Allegany','Pt Allegany','PA'),('US','PTH','Pt Heiden','Pt Heiden','AK'),('US','PTI','Pleasant Hill','Pleasant Hill','MO'),('US','PTJ','Pt Jefferson','Pt Jefferson','NY'),('US','PTK','Pontiac','Pontiac','MI'),('US','PTL','Pt Armstrong','Pt Armstrong','AK'),('US','PTM','Portsmouth','Portsmouth','VA'),('US','PTN','Morgan City-Patterson Apt','Morgan City-Patterson Apt','LA'),('US','PTO','Pittston','Pittston','PA'),('US','PTP','Pinetops','Pinetops','NC'),('US','PTQ','Portland','Portland','CT'),('US','PTR','Pleasant Harbour','Pleasant Harbour','AK'),('US','PTS','Pittsburg','Pittsburg','KS'),('US','PTT','Pratt','Pratt','KS'),('US','PTU','Platinum','Platinum','AK'),('US','PTV','Porterville','Porterville','CA'),('US','PTW','Pottstown','Pottstown','PA'),('US','PTX','Pearlington','Pearlington','MS'),('US','PTY','Pt Washington','Pt Washington','NJ'),('US','PTZ','Pittsfield','Pittsfield','PA'),('US','PUA','Pulaski','Pulaski','NY'),('US','PUB','Pueblo','Pueblo','CO'),('US','PUC','Price','Price','UT'),('US','PUD','Dupont','Dupont','PA'),('US','PUE','Pauline','Pauline','KS'),('US','PUI','Purcellville','Purcellville','VA'),('US','PUJ','Parlin','Parlin','NJ'),('US','PUL','Poulsbo','Poulsbo','WA'),('US','PUM','Petaluma','Petaluma','CA'),('US','PUN','Putnam','Putnam','CT'),('US','PUP','Dupont','Dupont','WA'),('US','PUQ','Pacoima','Pacoima','CA'),('US','PUR','Plumerville','Plumerville','AR'),('US','PUT','Putney','Putney','VT'),('US','PUV','Plumsteadville','Plumsteadville','PA'),('US','PUW','Pullman','Pullman','WA'),('US','PUY','Puyallup','Puyallup','WA'),('US','PUZ','Purcell','Purcell','OK'),('US','PV2','Potter Valley','Potter Valley','CA'),('US','PV3','Prattsville','Prattsville','AR'),('US','PV4','Prescott Valley','Prescott Valley','AZ'),('US','PV5','Providence','Providence','NC'),('US','PVA','Pine Valley','Pine Valley','CA'),('US','PVB','Pevely','Pevely','MO'),('US','PVC','Provincetown','Provincetown','MA'),('US','PVD','Providence','Providence','RI'),('US','PVE','Pineville','Pineville','LA'),('US','PVF','Placerville','Placerville','CA'),('US','PVG','Plainville','Plainville','GA'),('US','PVH','Plymouth','Plymouth','NH'),('US','PVI','Plainville','Plainville','CT'),('US','PVJ','Pauls Valley','Pauls Valley','OK'),('US','PVK','Piedmont','Piedmont','CA'),('US','PVL','Pineville','Pineville','AR'),('US','PVM','Spring Grove','Spring Grove','MN'),('US','PVN','Plainview','Plainview','MN'),('US','PVO','Pittsville','Pittsville','MO'),('US','PVP','Palos Verdes Estates','Palos Verdes Estates','CA'),('US','PVR','Purvis','Purvis','MS'),('US','PVS','Port Everglades','Port Everglades','FL'),('US','PVT','Pt Trevorton','Pt Trevorton','PA'),('US','PVU','Provo','Provo','UT'),('US','PVV','Proctorville','Proctorville','OH'),('US','PVW','Plainview','Plainview','TX'),('US','PVX','Plainview','Plainview','NY'),('US','PVY','Pope Vanoy','Pope Vanoy','AK'),('US','PVZ','Painesville','Painesville','OH'),('US','PWA','Pt Washington','Pt Washington','WI'),('US','PWB','Poplar Bluff','Poplar Bluff','MO'),('US','PWC','Point Mugu Nawc','Point Mugu Nawc','CA'),('US','PWD','Plentywood','Plentywood','MT'),('US','PWE','Pawnee','Pawnee','IL'),('US','PWF','Pt Wakefield','Pt Wakefield','AK'),('US','PWI','Pt Williams','Pt Williams','AK'),('US','PWL','Pawling','Pawling','NY'),('US','PWM','Portland','Portland','ME'),('US','PWN','Pt Wentworth','Pt Wentworth','GA'),('US','PWO','Porter','Porter','IN'),('US','PWP','Pawcatuck','Pawcatuck','CT'),('US','PWR','Pt Walter','Pt Walter','AK'),('US','PWS','Prosser','Prosser','WA'),('US','PWT','Bremerton','Bremerton','WA'),('US','PWU','Sparrow Bush','Sparrow Bush','NY'),('US','PWV','Parsons','Parsons','WV'),('US','PWY','Painted Post','Painted Post','NY'),('US','PWZ','Pleasant View, Cheatham','Pleasant View, Cheatham','TN'),('US','PX2','Pax','Pax','WV'),('US','PXG','Pleasant Grove','Pleasant Grove','UT'),('US','PXH','Pocahontas','Pocahontas','AR'),('US','PXL','Polacca','Polacca','AZ'),('US','PXM','Portales','Portales','NM'),('US','PXO','Pt Orchard','Pt Orchard','WA'),('US','PXR','Promontory','Promontory','UT'),('US','PXS','Paxinos','Paxinos','PA'),('US','PXT','Phoenix Township','Phoenix Township','AR'),('US','PXV','Phoenixville','Phoenixville','PA'),('US','PXW','Punxsutawney','Punxsutawney','PA'),('US','PXX','Philadelphia','Philadelphia','MS'),('US','PXY','Pixley','Pixley','CA'),('US','PXZ','Pikesville','Pikesville','MD'),('US','PY2','Payne','Payne','OH'),('US','PYA','Palmyra','Palmyra','IN'),('US','PYB','Perryman','Perryman','MD'),('US','PYC','Prichard','Prichard','AL'),('US','PYE','Payette','Payette','ID'),('US','PYG','Perry','Perry','GA'),('US','PYH','Pioneer','Pioneer','OH'),('US','PYI','Perryville','Perryville','MD'),('US','PYK','Pulaski','Pulaski','WI'),('US','PYL','Perry Island','Perry Island','AK'),('US','PYM','Plymouth','Plymouth','MA'),('US','PYN','Pinson','Pinson','AL'),('US','PYO','Plymouth','Plymouth','MN'),('US','PYP','Piney Point','Piney Point','MD'),('US','PYQ','Playa del Rey','Playa del Rey','CA'),('US','PYR','Pryor','Pryor','OK'),('US','PYS','Perryopolis','Perryopolis','PA'),('US','PYT','Plymouth','Plymouth','CA'),('US','PYU','Payson','Payson','UT'),('US','PYV','Perrysville','Perrysville','OH'),('US','PYW','Paynesville','Paynesville','MN'),('US','PYX','Perryville','Perryville','MO'),('US','PYY','Palmyra','Palmyra','PA'),('US','PYZ','Poseyville','Poseyville','IN'),('US','PZE','Pewamo','Pewamo','MI'),('US','PZJ','Pejepscot','Pejepscot','ME'),('US','PZK','Patrick','Patrick','NV'),('US','PZL','Pt Saint Lucie','Pt Saint Lucie','FL'),('US','PZM','Parchment','Parchment','MI'),('US','PZQ','Palmyra','Palmyra','NY'),('US','PZS','Post','Post','TX'),('US','PZT','Paris','Paris','KY'),('US','PZX','Plaistow','Plaistow','NH'),('US','PZY','Piggott','Piggott','AR'),('US','QAB','Alum Bank','Alum Bank','PA'),('US','QAC','Cato','Cato','NY'),('US','QAD','Redan','Redan','GA'),('US','QAE','Auburn','Auburn','NE'),('US','QAF','Alfred','Alfred','NY'),('US','QAG','Algoma','Algoma','WI'),('US','QAI','Clare','Clare','IL'),('US','QAM','Marion','Marion','MA'),('US','QAO','Milford','Milford','VA'),('US','QAP','Creekside','Creekside','PA'),('US','QAR','Arlington','Arlington','NJ'),('US','QAS','Ashburn','Ashburn','VA'),('US','QAT','Atlantic Beach','Atlantic Beach','FL'),('US','QAY','Quaker City','Quaker City','OH'),('US','QAZ','Cadiz','Cadiz','OH'),('US','QBA','Baskin','Baskin','LA'),('US','QBB','Bell Buckle','Bell Buckle','TN'),('US','QBC','Baltic','Baltic','OH'),('US','QBH','Bath','Bath','NH'),('US','QBL','Belfast','Belfast','TN'),('US','QBM','Baltic','Baltic','CT'),('US','QBO','Bondsville','Bondsville','MA'),('US','QBR','Brownsville','Brownsville','FL'),('US','QBS','Bessemer','Bessemer','PA'),('US','QBT','Bettsville','Bettsville','OH'),('US','QBU','Burton','Burton','MI'),('US','QBV','Brownville','Brownville','NY'),('US','QBX','Bristol','Bristol','IL'),('US','QBY','Queensbury','Queensbury','NY'),('US','QCA','Acra','Acra','NY'),('US','QCB','Claysburg','Claysburg','PA'),('US','QCC','Chevy Chase','Chevy Chase','MD'),('US','QCE','Copper Mountain','Copper Mountain','CO'),('US','QCH','Carthage','Carthage','NY'),('US','QCI','Chisholm','Chisholm','MN'),('US','QCJ','Califon','Califon','NJ'),('US','QCK','Queen Creek','Queen Creek','AZ'),('US','QCL','Richland','Richland','NY'),('US','QCN','Coal Center','Coal Center','PA'),('US','QCO','Clarion','Clarion','PA'),('US','QCP','Campbellsport','Campbellsport','WI'),('US','QCQ','Chautauqua','Chautauqua','NY'),('US','QCS','Chelsea','Chelsea','NY'),('US','QCT','Clanton','Clanton','AL'),('US','QCW','Wilton','Wilton','CT'),('US','QCY','Quincy','Quincy','FL'),('US','QCZ','Cozad','Cozad','NE'),('US','QDA','Ronda','Ronda','NC'),('US','QDB','Woodbury','Woodbury','TN'),('US','QDL','Dalton','Dalton','OH'),('US','QDM','Elmont','Elmont','NY'),('US','QDQ','DeQuincy','DeQuincy','LA'),('US','QDR','Derry','Derry','PA'),('US','QDT','Dalton','Dalton','MA'),('US','QDV','Devenscrest','Devenscrest','MA'),('US','QDY','Dolgeville','Dolgeville','NY'),('US','QEB','Edinboro','Edinboro','PA'),('US','QED','Eden','Eden','GA'),('US','QEE','Queens/New York','Queens/New York','NY'),('US','QEI','Ewing','Ewing','NJ'),('US','QEN','Elon','Elon','NC'),('US','QEO','Earlington','Earlington','KY'),('US','QET','East Setauket','East Setauket','NY'),('US','QEV','Earlville','Earlville','IA'),('US','QEW','Erwins','Erwins','NY'),('US','QEY','Eakly','Eakly','OK'),('US','QFA','Fort Davis','Fort Davis','TX'),('US','QFC','Fairmont City','Fairmont City','PA'),('US','QFI','Ferriday','Ferriday','LA'),('US','QFM','Farmington Hill','Farmington Hill','PA'),('US','QFN','Ferndale','Ferndale','NY'),('US','QFU','Fort Lupton','Fort Lupton','CO'),('US','QFW','Fort Washington','Fort Washington','PA'),('US','QFY','Fairmont City','Fairmont City','IL'),('US','QGA','Gem','Gem','KS'),('US','QGB','Grand Blanc','Grand Blanc','MI'),('US','QGE','Glen','Glen','MT'),('US','QGH','Grayling','Grayling','MI'),('US','QGR','Bangor','Bangor','PA'),('US','QGT','Garrett','Garrett','IN'),('US','QGX','Goldthwaite','Goldthwaite','TX'),('US','QHA','Hatton','Hatton','ND'),('US','QHC','Hancock','Hancock','VT'),('US','QHD','Hartford','Hartford','NY'),('US','QHE','Hooker','Hooker','OK'),('US','QHG','Huger','Huger','SC'),('US','QHI','Hillsboro','Hillsboro','NH'),('US','QHJ','Haskell','Haskell','NJ'),('US','QHK','Hopkinton','Hopkinton','IA'),('US','QHL','Hamel','Hamel','IL'),('US','QHM','Chama','Chama','NM'),('US','QHO','Oak Brook','Oak Brook','IL'),('US','QHR','Homer City','Homer City','PA'),('US','QHS','Mount Holly Springs','Mount Holly Springs','PA'),('US','QHT','Huber Heights','Huber Heights','OH'),('US','QHV','Hanover','Hanover','IL'),('US','QIA','New Vienna','New Vienna','IA'),('US','QIC','Castaic','Castaic','CA'),('US','QIG','Meigs','Meigs','GA'),('US','QIL','Idabel','Idabel','OK'),('US','QIM','Coldwater','Coldwater','MS'),('US','QIS','Inverness','Inverness','CA'),('US','QJB','Jobstown','Jobstown','NJ'),('US','QJE','Jefferson','Jefferson','PA'),('US','QJM','Jamestown','Jamestown','SC'),('US','QKC','Kimberling City','Kimberling City','MO'),('US','QKF','Beresford','Beresford','SD'),('US','QKK','Keswick','Keswick','IA'),('US','QKL','Kinston','Kinston','AL'),('US','QKM','Ketchum','Ketchum','ID'),('US','QKO','Elkton','Elkton','OH'),('US','QKS','Quicksburg','Quicksburg','VA'),('US','QKT','Quakertown','Quakertown','NJ'),('US','QL2','Clio','Clio','MI'),('US','QLC','Carlisle','Carlisle','SC'),('US','QLD','Lansdowne','Lansdowne','PA'),('US','QLE','Lee','Lee','FL'),('US','QLF','Linn Creek','Linn Creek','MO'),('US','QLH','Laurelville','Laurelville','OH'),('US','QLI','Loves Park','Loves Park','IL'),('US','QLM','Salem','Salem','SD'),('US','QLN','Carrollton','Carrollton','VA'),('US','QLO','Leonia','Leonia','NJ'),('US','QLR','Laureldale','Laureldale','PA'),('US','QLT','Loretto','Loretto','PA'),('US','QLW','Lewiston','Lewiston','ME'),('US','QLY','Lyles','Lyles','TN'),('US','QMA','Moscow','Moscow','PA'),('US','QMB','Mabel','Mabel','PA'),('US','QMC','McLeansville','McLeansville','NC'),('US','QMD','Madison','Madison','WV'),('US','QME','Magee','Magee','MS'),('US','QMG','Montgomery','Montgomery','PA'),('US','QMH','Marshall','Marshall','CA'),('US','QMI','Middlefield','Middlefield','OH'),('US','QMJ','Madison','Madison','NJ'),('US','QMK','Markleville','Markleville','IN'),('US','QML','Marshall','Marshall','WI'),('US','QMM','Marne','Marne','MI'),('US','QMN','Quitman','Quitman','MS'),('US','QMO','Moraga','Moraga','CA'),('US','QMR','Montrose','Montrose','PA'),('US','QMS','Means','Means','KY'),('US','QMT','Minto','Minto','ND'),('US','QMU','Mantua','Mantua','NJ'),('US','QMV','Montvale','Montvale','NJ'),('US','QMW','McCleary','McCleary','WA'),('US','QMX','Monroe','Monroe','NJ'),('US','QMY','Midway, Liberty','Midway, Liberty','GA'),('US','QN2','Quinnesec','Quinnesec','MI'),('US','QNC','Quincy','Quincy','WA'),('US','QND','New Hartford','New Hartford','NY'),('US','QNE','Newportville','Newportville','PA'),('US','QNH','Northampton','Northampton','PA'),('US','QNL','Nelson','Nelson','WI'),('US','QNM','North Miami','North Miami','FL'),('US','QNN','New Ipswich','New Ipswich','NH'),('US','QNR','Quinter','Quinter','KS'),('US','QNS','Ramsey','Ramsey','MN'),('US','QNT','Quanah','Quanah','TX'),('US','QNV','Nokesville','Nokesville','VA'),('US','QOA','Olyphant','Olyphant','PA'),('US','QOG','Oak Grove','Oak Grove','IL'),('US','QON','Mason','Mason','TN'),('US','QOO','Bono','Bono','AR'),('US','QOP','Oak Park','Oak Park','IL'),('US','QOR','Moravia','Moravia','IA'),('US','QOT','Olton','Olton','TX'),('US','QP2','Quapaw','Quapaw','OK'),('US','QPA','Parma','Parma','ID'),('US','QPB','Pembroke','Pembroke','GA'),('US','QPD','Poland','Poland','OH'),('US','QPE','Pelham','Pelham','NH'),('US','QPH','Pocahontas','Pocahontas','TN'),('US','QPL','Palmdale','Palmdale','CA'),('US','QPM','Pamplin','Pamplin','VA'),('US','QPN','Peconic','Peconic','NY'),('US','QPO','Pittsboro','Pittsboro','NC'),('US','QPS','Pine Bluffs','Pine Bluffs','WY'),('US','QPT','Port Alto','Port Alto','TX'),('US','QPV','Ponte Vedra','Ponte Vedra','FL'),('US','QPW','Poway','Poway','CA'),('US','QPX','Prosper','Prosper','TX'),('US','QPY','Pine Plains','Pine Plains','NY'),('US','QQZ','Strasburg','Strasburg','PA'),('US','QRA','Parma','Parma','MO'),('US','QRC','Rockville Centre','Rockville Centre','NY'),('US','QRD','Radcliff','Radcliff','KY'),('US','QRE','Regal','Regal','NC'),('US','QRI','Burlison','Burlison','TN'),('US','QRL','Erial','Erial','NJ'),('US','QRN','Heron','Heron','MT'),('US','QRU','Murray','Murray','IA'),('US','QRY','Surry','Surry','VA'),('US','QSE','Conestee','Conestee','SC'),('US','QSG','Spring Green','Spring Green','WI'),('US','QSI','Sea Island','Sea Island','GA'),('US','QSK','Saco','Saco','ME'),('US','QSN','South Easton','South Easton','MA'),('US','QSO','Nelson','Nelson','CA'),('US','QSQ','Smock','Smock','PA'),('US','QSR','Seward','Seward','IL'),('US','QST','Stoystown','Stoystown','PA'),('US','QSV','Somerville','Somerville','TN'),('US','QSW','South Walpole','South Walpole','MA'),('US','QSY','Shrewsbury','Shrewsbury','PA'),('US','QTA','Catalina','Catalina','AZ'),('US','QTB','Tabor City','Tabor City','NC'),('US','QTE','Monette','Monette','AR'),('US','QTF','Three Forks Junction','Three Forks Junction','MT'),('US','QTG','Quitaque','Quitaque','TX'),('US','QTH','Tomah','Tomah','WI'),('US','QTI','Trinity','Trinity','AL'),('US','QTM','Quitman','Quitman','GA'),('US','QTN','Tornillo','Tornillo','TX'),('US','QTO','Tonica','Tonica','IL'),('US','QTR','Telluride','Telluride','CO'),('US','QTS','Englewood','Englewood','CO'),('US','QTY','Terry','Terry','MS'),('US','QTZ','Quartzsite','Quartzsite','AZ'),('US','QUE','Queenstown','Queenstown','MD'),('US','QUI','Quincy','Quincy','CA'),('US','QUO','Quogue','Quogue','NY'),('US','QUP','Union Point','Union Point','GA'),('US','QUS','Upper Saint Regis','Upper Saint Regis','NY'),('US','QUY','Quincy','Quincy','MI'),('US','QVA','Vale','Vale','SD'),('US','QVW','Bridgeview','Bridgeview','IL'),('US','QWB','New Albany','New Albany','OH'),('US','QWD','Waelder','Waelder','TX'),('US','QWL','Willimantic','Willimantic','CT'),('US','QWR','Wauregan','Wauregan','CT'),('US','QWT','Walton','Walton','KY'),('US','QWW','Wynnewood','Wynnewood','PA'),('US','QWY','Westley','Westley','CA'),('US','QYC','Corona','Corona','NY'),('US','QYL','Loudonville','Loudonville','NY'),('US','QZE','Monee','Monee','IL'),('US','QZG','Glasgow','Glasgow','VA'),('US','QZN','New Point','New Point','VA'),('US','RAA','Alma','Alma','AR'),('US','RAB','Arab','Arab','AL'),('US','RAC','Racine','Racine','WI'),('US','RAD','St Meinrad','St Meinrad','IN'),('US','RAE','Rosedale','Rosedale','MS'),('US','RAF','Ringle','Ringle','WI'),('US','RAG','Raleigh','Raleigh','NC'),('US','RAH','Rahway','Rahway','NJ'),('US','RAI','Rainier','Rainier','OR'),('US','RAJ','Rotterdam','Rotterdam','NY'),('US','RAK','Franklin','Franklin','GA'),('US','RAL','Riverside','Riverside','CA'),('US','RAM','Raymore','Raymore','MO'),('US','RAN','Raton','Raton','NM'),('US','RAO','Granton','Granton','WI'),('US','RAP','Rapid City','Rapid City','SD'),('US','RAR','Radnor','Radnor','PA'),('US','RAS','Ranson','Ranson','WV'),('US','RAT','Raritan','Raritan','NJ'),('US','RAU','Raiford','Raiford','FL'),('US','RAV','Ransomville','Ransomville','NY'),('US','RAY','Rahway','Rahway','OH'),('US','RAZ','Rancho Palos Verdes','Rancho Palos Verdes','CA'),('US','RB2','Reinbeck','Reinbeck','IA'),('US','RB3','Rimersburg','Rimersburg','PA'),('US','RBA','Robards','Robards','KY'),('US','RBB','Robbinsville','Robbinsville','NC'),('US','RBC','Riviera Beach','Riviera Beach','FL'),('US','RBD','Redondo Beach','Redondo Beach','CA'),('US','RBE','Robesonia','Robesonia','PA'),('US','RBF','Big Bear','Big Bear','CA'),('US','RBG','Roseburg','Roseburg','OR'),('US','RBH','Brooks Lodge','Brooks Lodge','AK'),('US','RBI','Rexburg','Rexburg','ID'),('US','RBK','Rancho','Rancho','CA'),('US','RBL','Red Bluff','Red Bluff','CA'),('US','RBN','Fort Jefferson','Fort Jefferson','FL'),('US','RBO','Rancho Bernardo','Rancho Bernardo','CA'),('US','RBP','Red Boiling Springs','Red Boiling Springs','TN'),('US','RBR','Ranburne','Ranburne','AL'),('US','RBS','Robbins','Robbins','NC'),('US','RBT','Roberts','Roberts','WI'),('US','RBU','Cedar Bluff','Cedar Bluff','AL'),('US','RBV','Robbinsville','Robbinsville','NJ'),('US','RBW','Walterboro','Walterboro','SC'),('US','RBY','Ruby','Ruby','AK'),('US','RC2','Rutherford College','Rutherford College','NC'),('US','RC3','Rice','Rice','MN'),('US','RCA','Rockland','Rockland','MA'),('US','RCB','Raceland','Raceland','LA'),('US','RCC','Rebecca','Rebecca','GA'),('US','RCD','Richmond','Richmond','OH'),('US','RCE','Roche Harbor','Roche Harbor','WA'),('US','RCF','Rockford','Rockford','MI'),('US','RCG','Riceboro','Riceboro','GA'),('US','RCH','Richmond','Richmond','CA'),('US','RCI','Richlands','Richlands','NC'),('US','RCK','Rockdale','Rockdale','TX'),('US','RCL','Rochelle','Rochelle','GA'),('US','RCM','Richfield','Richfield','MN'),('US','RCN','Richmond','Richmond','MI'),('US','RCO','Carencro','Carencro','LA'),('US','RCP','Rocky Point','Rocky Point','NC'),('US','RCR','Rochester','Rochester','IN'),('US','RCS','Rochester','Rochester','MA'),('US','RCT','Reed City','Reed City','MI'),('US','RCU','Rancho Cucamonga','Rancho Cucamonga','CA'),('US','RCV','Rock Valley','Rock Valley','IA'),('US','RCW','Rochester','Rochester','WA'),('US','RCX','Rochelle','Rochelle','IL'),('US','RCY','Rogers City','Rogers City','MI'),('US','RCZ','Rochester','Rochester','MI'),('US','RD2','Reeder','Reeder','ND'),('US','RDA','Rosedale','Rosedale','AR'),('US','RDB','Red Dog','Red Dog','AK'),('US','RDC','Reedley','Reedley','CA'),('US','RDD','Redding','Redding','CA'),('US','RDE','Ridgeland','Ridgeland','MS'),('US','RDF','Redford','Redford','MI'),('US','RDG','Reading','Reading','PA'),('US','RDH','Randolph','Randolph','MA'),('US','RDI','Reading','Reading','MA'),('US','RDJ','Reading','Reading','OH'),('US','RDK','Red Oak','Red Oak','IA'),('US','RDL','Riverdale','Riverdale','NJ'),('US','RDM','Bend-Redmond Apt','Bend-Redmond Apt','OR'),('US','RDN','Bridgman','Bridgman','MI'),('US','RDO','Rancho Dominguez','Rancho Dominguez','CA'),('US','RDP','Randolph','Randolph','NJ'),('US','RDR','Red River','Red River','ND'),('US','RDS','Reedsburg','Reedsburg','WI'),('US','RDT','Bradenton Beach','Bradenton Beach','FL'),('US','RDU','Durham-Raleigh Apt','Durham-Raleigh Apt','NC'),('US','RDV','Red Devil','Red Devil','AK'),('US','RDW','Red Wing','Red Wing','MN'),('US','RDY','Red Bay','Red Bay','AL'),('US','REA','Readville','Readville','MA'),('US','REB','Reddick','Reddick','FL'),('US','REC','Rose City','Rose City','MI'),('US','RED','Lewistown-Reedsville Apt','Lewistown-Reedsville Apt','PA'),('US','REE','Reidsville','Reidsville','GA'),('US','REF','Roderfield','Roderfield','WV'),('US','REG','Marengo','Marengo','IL'),('US','REH','Rehoboth Beach','Rehoboth Beach','DE'),('US','REI','Reedsville','Reedsville','WI'),('US','REK','Reamstown','Reamstown','PA'),('US','REL','Reedsville','Reedsville','PA'),('US','REM','Bremen','Bremen','AL'),('US','REN','Red Bank','Red Bank','NJ'),('US','REO','Rome','Rome','OR'),('US','REP','Freeport','Freeport','ME'),('US','REQ','Richfield','Richfield','OH'),('US','RER','Rensselaer','Rensselaer','NY'),('US','RES','Rescue','Rescue','VA'),('US','RET','Preston','Preston','MN'),('US','REU','Elora','Elora','TN'),('US','REV','Reedville','Reedville','VA'),('US','REW','Red Hook','Red Hook','NY'),('US','REX','Rex','Rex','GA'),('US','REY','Reynolds','Reynolds','GA'),('US','REZ','Revere','Revere','MA'),('US','RF2','Reform','Reform','AL'),('US','RF3','Ridgefield','Ridgefield','CT'),('US','RF4','Rockfall','Rockfall','CT'),('US','RFA','Rattan','Rattan','OK'),('US','RFB','Rumford','Rumford','RI'),('US','RFD','Rockford','Rockford','IL'),('US','RFE','Ruffs Dale','Ruffs Dale','PA'),('US','RFF','Roff','Roff','OK'),('US','RFG','Refugio','Refugio','TX'),('US','RFH','Rohnert Park','Rohnert Park','CA'),('US','RFI','Rock Falls','Rock Falls','IL'),('US','RFK','Anguilla','Anguilla','MS'),('US','RFL','River Falls','River Falls','AL'),('US','RFM','Rumford','Rumford','ME'),('US','RFN','Raeford','Raeford','NC'),('US','RFO','Rockford','Rockford','OH'),('US','RFP','Ridgefield Park','Ridgefield Park','NJ'),('US','RFQ','Redfield','Redfield','IA'),('US','RFR','Richford','Richford','VT'),('US','RFS','Rosemead','Rosemead','CA'),('US','RFW','River Falls','River Falls','WI'),('US','RFX','Fairfax','Fairfax','MO'),('US','RFY','Rolling Fork','Rolling Fork','MS'),('US','RG2','Richgrove','Richgrove','CA'),('US','RG3','Rigby','Rigby','ID'),('US','RGA','Baraga','Baraga','MI'),('US','RGB','Bergen','Bergen','NY'),('US','RGC','Rio Grande City','Rio Grande City','TX'),('US','RGD','Ringgold','Ringgold','GA'),('US','RGE','Ridgeland','Ridgeland','SC'),('US','RGF','Rio Grande','Rio Grande','NJ'),('US','RGG','Rabun Gap','Rabun Gap','GA'),('US','RGH','Brighton','Brighton','MA'),('US','RGI','Spring Hill','Spring Hill','KS'),('US','RGJ','Rivergate','Rivergate','OR'),('US','RGK','Springhills','Springhills','OH'),('US','RGL','Riegelwood','Riegelwood','NC'),('US','RGM','Rockingham','Rockingham','NC'),('US','RGN','Ringtown','Ringtown','PA'),('US','RGO','Ridgewood','Ridgewood','NY'),('US','RGP','Borger','Borger','TX'),('US','RGQ','Rogers','Rogers','TX'),('US','RGR','Ranger','Ranger','TX'),('US','RGS','Rogers','Rogers','CT'),('US','RGT','Register','Register','GA'),('US','RGU','Rogue River','Rogue River','OR'),('US','RGV','Rogersville','Rogersville','TN'),('US','RH2','Rogers Haven','Rogers Haven','DE'),('US','RHA','Crenshaw','Crenshaw','MS'),('US','RHC','Rock Hill','Rock Hill','NC'),('US','RHD','Riverhead','Riverhead','NY'),('US','RHE','Rhine','Rhine','GA'),('US','RHH','Rochester Hills/Detroit','Rochester Hills/Detroit','MI'),('US','RHI','Rhinelander','Rhinelander','WI'),('US','RHJ','Rolling Hills','Rolling Hills','CA'),('US','RHK','Rich Creek','Rich Creek','VA'),('US','RHL','Richmondville','Richmondville','NY'),('US','RHM','Richmond','Richmond','KY'),('US','RHN','Rahns','Rahns','PA'),('US','RHO','Rhode Island','Rhode Island','NY'),('US','RHR','Rochester','Rochester','PA'),('US','RHS','Crestview Hills','Crestview Hills','KY'),('US','RHT','Brighton','Brighton','TN'),('US','RHU','Rathdrum','Rathdrum','ID'),('US','RHV','Fair Haven','Fair Haven','MI'),('US','RHW','Rowland Heights','Rowland Heights','CA'),('US','RHX','Red Hill','Red Hill','AR'),('US','RHY','Red Hill','Red Hill','PA'),('US','RIA','Marianna','Marianna','AR'),('US','RIB','Rickenbacker International Apt','Rickenbacker International Apt','OH'),('US','RIC','Richmond','Richmond','VA'),('US','RID','Richmond','Richmond','IN'),('US','RIE','Rice Lake','Rice Lake','WI'),('US','RIF','Richfield','Richfield','UT'),('US','RIG','River Grove/Chicago','River Grove/Chicago','IL'),('US','RIH','Ririe','Ririe','ID'),('US','RII','Richfield','Richfield','ID'),('US','RIK','Rincon','Rincon','GA'),('US','RIL','Rifle','Rifle','CO'),('US','RIM','Rimer','Rimer','OH'),('US','RIN','Richardson','Richardson','TX'),('US','RIO','Ringwood','Ringwood','IL'),('US','RIP','Ripon','Ripon','CA'),('US','RIQ','Richland','Richland','MI'),('US','RIR','Riddle','Riddle','OR'),('US','RIS','Ridgeville','Ridgeville','SC'),('US','RIT','Ridgeway','Ridgeway','WI'),('US','RIU','Ariton','Ariton','AL'),('US','RIV','Reidsville','Reidsville','NC'),('US','RIW','Riverton','Riverton','WY'),('US','RIX','Richmond Hill/Queens/New York','Richmond Hill/Queens/New York','NY'),('US','RIY','Brinkley','Brinkley','AR'),('US','RJE','Riverton','Riverton','KS'),('US','RJG','Redgranite','Redgranite','WI'),('US','RJH','Richmond Highlands','Richmond Highlands','WA'),('US','RJJ','Richmond Beach','Richmond Beach','WA'),('US','RJK','Richmond Hill','Richmond Hill','GA'),('US','RJL','Richland','Richland','MS'),('US','RJM','Rogers','Rogers','MN'),('US','RJN','Rotterdam Junction','Rotterdam Junction','NY'),('US','RJO','Ringgold','Ringgold','PA'),('US','RJV','Ridgeway','Ridgeway','VA'),('US','RJW','Ridgway','Ridgway','IL'),('US','RKA','Rockmart','Rockmart','GA'),('US','RKC','Yreka','Yreka','CA'),('US','RKD','Rockland','Rockland','ME'),('US','RKE','Rockledge','Rockledge','FL'),('US','RKF','Rocky Ford','Rocky Ford','CO'),('US','RKH','Rock Hill','Rock Hill','SC'),('US','RKI','Rock Island','Rock Island','IL'),('US','RKJ','Rockaway','Rockaway','NJ'),('US','RKK','Ronkonkoma','Ronkonkoma','NY'),('US','RKL','Rocklin','Rocklin','CA'),('US','RKN','Ruskin','Ruskin','FL'),('US','RKO','Rockport','Rockport','NJ'),('US','RKP','Rockport','Rockport','TX'),('US','RKR','Poteau','Poteau','OK'),('US','RKS','Rock Springs','Rock Springs','WY'),('US','RKT','Rockton','Rockton','IL'),('US','RKV','Rockville','Rockville','MD'),('US','RKW','Rockwood','Rockwood','TN'),('US','RKY','Rocky River','Rocky River','OH'),('US','RL2','Round Lake','Round Lake','MN'),('US','RLA','Rolla','Rolla','MO'),('US','RLB','Roseland','Roseland','NJ'),('US','RLC','Richland Center','Richland Center','WI'),('US','RLD','Richland','Richland','WA'),('US','RLE','Roselle','Roselle','NJ'),('US','RLF','Ridgefield','Ridgefield','WA'),('US','RLG','Arlington','Arlington','IL'),('US','RLH','Spring Lake Park','Spring Lake Park','MN'),('US','RLI','Rio Linda','Rio Linda','CA'),('US','RLK','Random Lake','Random Lake','WI'),('US','RLL','Roselle','Roselle','IL'),('US','RLM','Rolling Meadows','Rolling Meadows','IL'),('US','RLN','Red Lion','Red Lion','PA'),('US','RLO','Rialto','Rialto','CA'),('US','RLP','Randolph','Randolph','MS'),('US','RLR','Colt','Colt','AR'),('US','RLS','Redlands','Redlands','CA'),('US','RLT','Roosevelt','Roosevelt','WA'),('US','RLU','Bornite','Bornite','AK'),('US','RLV','Richlands','Richlands','VA'),('US','RLW','Relay','Relay','MD'),('US','RLZ','Reelsville','Reelsville','IN'),('US','RM2','Raymond','Raymond','WI'),('US','RM3','Raymond','Raymond','OH'),('US','RM4','Richmond','Richmond','UT'),('US','RMA','Hermann','Hermann','MO'),('US','RMB','Raymond','Raymond','MN'),('US','RMD','Redmond','Redmond','OR'),('US','RME','Rome','Rome','NY'),('US','RMG','Rome','Rome','GA'),('US','RMI','Reese','Reese','MI'),('US','RMJ','Ramsey','Ramsey','NJ'),('US','RML','Carmel','Carmel','IN'),('US','RMM','Rosemount','Rosemount','MN'),('US','RMN','Richmond','Richmond','IL'),('US','RMO','Romeo','Romeo','MI'),('US','RMP','Rampart','Rampart','AK'),('US','RMQ','Redmond','Redmond','UT'),('US','RMT','Birmingport','Birmingport','AL'),('US','RMV','Raymondville','Raymondville','TX'),('US','RMY','Ramsey','Ramsey','IN'),('US','RN2','Roanoke','Roanoke','AL'),('US','RNA','Reno','Reno','PA'),('US','RNB','Granby','Granby','CO'),('US','RNC','McMinnville','McMinnville','TN'),('US','RND','Raymond','Raymond','MT'),('US','RNE','Roanoke','Roanoke','TX'),('US','RNF','Springfield','Springfield','KY'),('US','RNG','Rangely','Rangely','CO'),('US','RNH','New Richmond','New Richmond','WI'),('US','RNJ','Randleman','Randleman','NC'),('US','RNK','Franklin','Franklin','LA'),('US','RNL','Rantoul','Rantoul','IL'),('US','RNM','Carson','Carson','MS'),('US','RNN','Clarendon','Clarendon','AR'),('US','RNO','Reno','Reno','NV'),('US','RNP','Randolph','Randolph','WI'),('US','RNQ','Reno','Reno','TX'),('US','RNR','Arnolds Park','Arnolds Park','IA'),('US','RNS','Ransom','Ransom','PA'),('US','RNT','Renton','Renton','WA'),('US','RNU','Rainelle','Rainelle','WV'),('US','RNV','Rainsville','Rainsville','AL'),('US','RNW','Ronan','Ronan','MT'),('US','RNX','Ramona','Ramona','CA'),('US','RNY','Brantley','Brantley','AL'),('US','RNZ','Rensselaer','Rensselaer','IN'),('US','ROA','Roanoke','Roanoke','VA'),('US','ROB','Robinson','Robinson','IL'),('US','ROC','Rochester','Rochester','NY'),('US','ROD','Rosendale','Rosendale','WI'),('US','ROE','Rockdale','Rockdale','IL'),('US','ROF','Rockford','Rockford','TN'),('US','ROG','Rogers','Rogers','AR'),('US','ROH','Rochester','Rochester','IL'),('US','ROI','Romeoville','Romeoville','IL'),('US','ROK','Rocky Hill','Rocky Hill','CT'),('US','ROL','Roosevelt','Roosevelt','UT'),('US','ROM','Round Mountain','Round Mountain','NV'),('US','RON','Rosenhayn','Rosenhayn','NJ'),('US','ROO','Roosville','Roosville','MT'),('US','ROP','Rosemont','Rosemont','PA'),('US','ROR','Rochester','Rochester','NH'),('US','ROS','Roseville','Roseville','OH'),('US','ROT','Ronceverte','Ronceverte','WV'),('US','ROU','Romulus','Romulus','MI'),('US','ROV','Rocky Mount','Rocky Mount','VA'),('US','ROW','Roswell','Roswell','NM'),('US','ROX','Roseau','Roseau','MN'),('US','ROY','Royston','Royston','GA'),('US','ROZ','Rosedale','Rosedale','NJ'),('US','RP2','Rego Park, Queens','Rego Park, Queens','NY'),('US','RP3','Rockport','Rockport','ME'),('US','RPA','Rolling Prairie','Rolling Prairie','IN'),('US','RPE','Ripley','Ripley','WV'),('US','RPG','Red Springs','Red Springs','NC'),('US','RPI','Arpin','Arpin','WI'),('US','RPK','Ridley Park','Ridley Park','PA'),('US','RPL','Ripley','Ripley','TN'),('US','RPM','Ripley','Ripley','MS'),('US','RPN','Ripon','Ripon','WI'),('US','RPO','Freeport','Freeport','MN'),('US','RPQ','Rancho Park','Rancho Park','CA'),('US','RPR','Rockport','Rockport','WA'),('US','RPS','Radium Springs','Radium Springs','NM'),('US','RPT','Rupert','Rupert','ID'),('US','RPV','Roopville','Roopville','GA'),('US','RPX','Roundup','Roundup','MT'),('US','RQA','Smarr','Smarr','GA'),('US','RQB','Roebuck','Roebuck','SC'),('US','RQG','Resaca','Resaca','GA'),('US','RQH','Rural Hall','Rural Hall','NC'),('US','RQJ','Roebling','Roebling','NJ'),('US','RQL','Rolla','Rolla','ND'),('US','RQO','Rockwood','Rockwood','OR'),('US','RQP','Rockport','Rockport','IN'),('US','RQQ','River Edge','River Edge','NJ'),('US','RQS','La Crosse','La Crosse','KS'),('US','RQV','Riverdale','Riverdale','GA'),('US','RQX','Roanoke','Roanoke','IL'),('US','RQY','Rush','Rush','KY'),('US','RRA','Scranton','Scranton','AR'),('US','RRC','Rio Rancho','Rio Rancho','NM'),('US','RRD','Riverdale','Riverdale','IL'),('US','RRE','Rural Retreat','Rural Retreat','VA'),('US','RRF','Furrs','Furrs','MS'),('US','RRH','Parrish','Parrish','AL'),('US','RRI','Sherrill','Sherrill','NY'),('US','RRJ','River Rouge','River Rouge','MI'),('US','RRL','Merrill','Merrill','WI'),('US','RRM','Richland','Richland','MO'),('US','RRN','Sorrento','Sorrento','FL'),('US','RRO','Robersonville','Robersonville','NC'),('US','RRP','Warrior','Warrior','AL'),('US','RRQ','Rio Rico','Rio Rico','AZ'),('US','RRS','Roaring Spring','Roaring Spring','PA'),('US','RRT','Warroad','Warroad','MN'),('US','RRV','Red River Ad','Red River Ad','TX'),('US','RRW','Riverview','Riverview','FL'),('US','RRX','Round Rock','Round Rock','TX'),('US','RRY','Rossmoor','Rossmoor','CA'),('US','RS2','Reeds Spring','Reeds Spring','MO'),('US','RS3','Reno-Stead','Reno-Stead','NV'),('US','RS4','Ross','Ross','OH'),('US','RS5','Russell Springs','Russell Springs','KY'),('US','RSA','Rosedale','Rosedale','MD'),('US','RSB','Roseboro','Roseboro','NC'),('US','RSC','Prescott','Prescott','OR'),('US','RSD','Riverside','Riverside','NJ'),('US','RSE','Reseda','Reseda','CA'),('US','RSF','Reserve','Reserve','LA'),('US','RSG','Rosenberg','Rosenberg','TX'),('US','RSH','Russian Mission','Russian Mission','AK'),('US','RSI','Rosemont','Rosemont','IL'),('US','RSJ','Rosario','Rosario','WA'),('US','RSK','Rosiclare','Rosiclare','IL'),('US','RSL','Russell','Russell','KS'),('US','RSM','Rancho Santa Margarita','Rancho Santa Margarita','CA'),('US','RSN','Ruston','Ruston','LA'),('US','RSO','Rossford','Rossford','OH'),('US','RSP','Raspberry Strait','Raspberry Strait','AK'),('US','RSQ','Roscoe','Roscoe','IL'),('US','RSR','Ramseur','Ramseur','NC'),('US','RSS','Rossville','Rossville','GA'),('US','RST','Rochester','Rochester','MN'),('US','RSU','Rancho Santa Fe','Rancho Santa Fe','CA'),('US','RSV','Roseville','Roseville','MI'),('US','RSW','Reisterstown','Reisterstown','MD'),('US','RSX','Rouses Point','Rouses Point','NY'),('US','RTA','Marietta','Marietta','SC'),('US','RTC','Firestone','Firestone','CO'),('US','RTD','Rotunda','Rotunda','FL'),('US','RTE','Marguerite Bay','Marguerite Bay','AK'),('US','RTH','Rutherford','Rutherford','CA'),('US','RTI','Martinez','Martinez','GA'),('US','RTL','Spirit Lake','Spirit Lake','IA'),('US','RTM','North Bloomfield','North Bloomfield','OH'),('US','RTN','Rittman','Rittman','OH'),('US','RTO','Colton','Colton','CA'),('US','RTP','North Palm Springs','North Palm Springs','CA'),('US','RTS','Rothschild','Rothschild','WI'),('US','RTT','Marietta','Marietta','OH'),('US','RTU','Rantoul','Rantoul','KS'),('US','RTV','Reston','Reston','VA'),('US','RTW','Brentwood','Brentwood','NH'),('US','RTX','Rotan','Rotan','TX'),('US','RTY','Ratliff City','Ratliff City','OK'),('US','RUA','Rutledge','Rutledge','GA'),('US','RUB','Rubonia','Rubonia','FL'),('US','RUC','Round Lake','Round Lake','IL'),('US','RUD','Durand','Durand','MI'),('US','RUE','Russellville','Russellville','TN'),('US','RUF','Rushford','Rushford','MN'),('US','RUH','Rushville','Rushville','IN'),('US','RUI','Ruidoso','Ruidoso','NM'),('US','RUK','Ruckersville','Ruckersville','VA'),('US','RUL','Rule','Rule','TX'),('US','RUN','Rising Sun','Rising Sun','MD'),('US','RUO','Russells Point','Russells Point','OH'),('US','RUP','Russell Springs','Russell Springs','KS'),('US','RUQ','Remus','Remus','MI'),('US','RUR','Rutherfordton','Rutherfordton','NC'),('US','RUS','Russellville','Russellville','AR'),('US','RUT','Rutland','Rutland','VT'),('US','RUV','Russellville','Russellville','AL'),('US','RUY','Ruby','Ruby','SC'),('US','RUZ','Romulus','Romulus','NY'),('US','RV2','Reidville','Reidville','SC'),('US','RV3','Russiaville','Russiaville','IN'),('US','RVA','Rio Vista','Rio Vista','CA'),('US','RVB','Robertsville','Robertsville','NJ'),('US','RVC','Roseville','Roseville','CA'),('US','RVD','Ravenna','Ravenna','NE'),('US','RVE','Roseville','Roseville','MN'),('US','RVF','Rolesville','Rolesville','NC'),('US','RVG','Ruther Glen','Ruther Glen','VA'),('US','RVH','Rockhill','Rockhill','SC'),('US','RVI','Ruleville','Ruleville','MS'),('US','RVJ','Riverton','Riverton','NJ'),('US','RVK','Russellville','Russellville','KY'),('US','RVL','Riverdale','Riverdale','MD'),('US','RVM','Riverside','Riverside','MI'),('US','RVN','Ravenna','Ravenna','OH'),('US','RVP','Ropesville','Ropesville','TX'),('US','RVR','Green River','Green River','UT'),('US','RVS','Tulsa','Tulsa','OR'),('US','RVT','Rooseveltown','Rooseveltown','NY'),('US','RVV','Riverview','Riverview','FL'),('US','RVW','Riverview','Riverview','MI'),('US','RVY','Rayville','Rayville','LA'),('US','RW2','Rockwood','Rockwood','MI'),('US','RWA','Bridgewater','Bridgewater','MI'),('US','RWB','Rowan Bay','Rowan Bay','AK'),('US','RWC','Redwood City','Redwood City','CA'),('US','RWD','Ridgewood','Ridgewood','NJ'),('US','RWE','Roswell','Roswell','GA'),('US','RWF','Redwood Falls','Redwood Falls','MN'),('US','RWI','Rocky Mount','Rocky Mount','NC'),('US','RWL','Rawlins','Rawlins','WY'),('US','RWO','Richwood','Richwood','KY'),('US','RWT','Fort Stewart','Fort Stewart','GA'),('US','RWV','Rowe','Rowe','VA'),('US','RWW','Ravenswood','Ravenswood','WV'),('US','RWY','Rowley','Rowley','UT'),('US','RXB','Roxboro','Roxboro','NC'),('US','RXG','Remington','Remington','IN'),('US','RXH','Rockleigh','Rockleigh','NJ'),('US','RXJ','Richburg','Richburg','SC'),('US','RXQ','Roxbury','Roxbury','CT'),('US','RXT','Rochester','Rochester','TX'),('US','RXV','Ringgold','Ringgold','VA'),('US','RXY','Roxbury','Roxbury','MA'),('US','RYA','Royal','Royal','AR'),('US','RYC','Royal Center','Royal Center','IN'),('US','RYD','Raymondville','Raymondville','MO'),('US','RYE','Cherryvale','Cherryvale','KS'),('US','RYG','Reynoldsburg','Reynoldsburg','OH'),('US','RYL','Rayne','Rayne','LA'),('US','RYM','Royal Oak','Royal Oak','MI'),('US','RYO','Raymond','Raymond','NH'),('US','RYP','Ramapo','Ramapo','NY'),('US','RYR','Rothbury','Rothbury','MI'),('US','RYT','Cranberry Township','Cranberry Township','PA'),('US','RYV','Rouseville','Rouseville','PA'),('US','RYW','Roy','Roy','WA'),('US','RYX','Royse City','Royse City','TX'),('US','RZC','Rancho Cordova','Rancho Cordova','CA'),('US','RZH','Rose Hill','Rose Hill','NC'),('US','RZI','Rienzi','Rienzi','MS'),('US','RZL','Russell','Russell','WA'),('US','RZZ','Roanoke Rapids','Roanoke Rapids','NC'),('US','SA2','San Augustine','San Augustine','TX'),('US','SA3','St Albans','St Albans','WV'),('US','SAA','Saratoga','Saratoga','WY'),('US','SAB','Sabine','Sabine','TX'),('US','SAC','Sacramento','Sacramento','CA'),('US','SAD','Safford','Safford','AZ'),('US','SAE','Salem','Salem','OH'),('US','SAF','Santa Fe','Santa Fe','NM'),('US','SAG','Sagwon','Sagwon','AK'),('US','SAH','Sasser','Sasser','GA'),('US','SAI','Saginaw','Saginaw','AL'),('US','SAJ','San Juan Capistrano','San Juan Capistrano','CA'),('US','SAK','San Pablo','San Pablo','CA'),('US','SAL','St Paul','St Paul','VA'),('US','SAM','Santa Clarita','Santa Clarita','CA'),('US','SAN','San Diego','San Diego','CA'),('US','SAO','Sarles','Sarles','ND'),('US','SAP','Saltville','Saltville','VA'),('US','SAQ','Sasabe','Sasabe','AZ'),('US','SAR','Sparta','Sparta','IL'),('US','SAS','Salton City','Salton City','CA'),('US','SAT','San Antonio','San Antonio','TX'),('US','SAU','Sauget','Sauget','IL'),('US','SAV','Savannah','Savannah','GA'),('US','SAW','Spotswood','Spotswood','NJ'),('US','SAX','Sandston','Sandston','VA'),('US','SAY','Stayton','Stayton','OR'),('US','SAZ','Sophia','Sophia','NC'),('US','SB2','Saxonburg','Saxonburg','PA'),('US','SB3','Scott Air Force Base','Scott Air Force Base','IL'),('US','SB4','Saybrook','Saybrook','OH'),('US','SB5','South Barre','South Barre','MA'),('US','SB6','Shirleysburg','Shirleysburg','PA'),('US','SBA','Santa Barbara','Santa Barbara','CA'),('US','SBB','Sabina','Sabina','OH'),('US','SBC','South Boston','South Boston','MA'),('US','SBD','St Bernard Parish','St Bernard Parish','LA'),('US','SBE','Sunset Beach','Sunset Beach','CA'),('US','SBF','Sheboygan Falls','Sheboygan Falls','WI'),('US','SBG','Strasburg','Strasburg','OH'),('US','SBH','Streetsboro','Streetsboro','OH'),('US','SBI','Shelby','Shelby','OH'),('US','SBJ','Seabrook','Seabrook','NJ'),('US','SBK','Saddle Brook','Saddle Brook','NJ'),('US','SBL','South Beloit','South Beloit','IL'),('US','SBM','Sheboygan','Sheboygan','WI'),('US','SBN','South Bend','South Bend','IN'),('US','SBO','Salina','Salina','UT'),('US','SBP','Sanibel','Sanibel','FL'),('US','SBR','Ambrose','Ambrose','GA'),('US','SBS','Steamboat Springs','Steamboat Springs','CO'),('US','SBT','San Bernardino','San Bernardino','CA'),('US','SBU','Southbury','Southbury','CT'),('US','SBV','Shelbyville','Shelbyville','IL'),('US','SBW','Schulenburg','Schulenburg','TX'),('US','SBX','Shelby','Shelby','MT'),('US','SBY','Salisbury','Salisbury','MD'),('US','SBZ','San Benito','San Benito','TX'),('US','SC2','Sauk Centre','Sauk Centre','MN'),('US','SC3','Sauk City','Sauk City','WI'),('US','SC4','Secane','Secane','PA'),('US','SC5','Surf City','Surf City','NJ'),('US','SC6','Santa Claus','Santa Claus','IN'),('US','SCA','Scappoose','Scappoose','OR'),('US','SCB','Scribner','Scribner','NE'),('US','SCC','Prudhoe Bay','Prudhoe Bay','AK'),('US','SCD','Scotland Neck','Scotland Neck','NC'),('US','SCE','State College','State College','PA'),('US','SCF','Sanford','Sanford','NC'),('US','SCG','Scarsdale','Scarsdale','NY'),('US','SCH','Schenectady','Schenectady','NY'),('US','SCI','Sun City','Sun City','AZ'),('US','SCJ','Smith Cove','Smith Cove','AK'),('US','SCK','Stockton','Stockton','CA'),('US','SCL','St Clair','St Clair','MI'),('US','SCM','Scammon Bay','Scammon Bay','AK'),('US','SCN','Scottville','Scottville','MI'),('US','SCO','Scobey','Scobey','MT'),('US','SCP','Schenley','Schenley','PA'),('US','SCQ','Scott City','Scott City','MO'),('US','SCR','Scranton','Scranton','PA'),('US','SCS','St Clairsville','St Clairsville','OH'),('US','SCT','South Charleston','South Charleston','WV'),('US','SCU','Scituate','Scituate','MA'),('US','SCV','Scottsville','Scottsville','KY'),('US','SCW','Scobeyville','Scobeyville','NJ'),('US','SCX','Schaller','Schaller','IA'),('US','SCY','Studio City','Studio City','CA'),('US','SCZ','Santa Clara','Santa Clara','CA'),('US','SD2','San Diego','San Diego','TX'),('US','SD3','Sidell','Sidell','IL'),('US','SD4','Stockdale','Stockdale','TX'),('US','SDA','San Dimas','San Dimas','CA'),('US','SDB','Smartt','Smartt','TN'),('US','SDC','Sand City','Sand City','CA'),('US','SDD','Snead','Snead','AL'),('US','SDE','Smithfield','Smithfield','KY'),('US','SDF','Smiths Creek','Smiths Creek','MI'),('US','SDG','Stroudsburg','Stroudsburg','PA'),('US','SDH','Shenandoah','Shenandoah','IA'),('US','SDI','Sanderson','Sanderson','FL'),('US','SDJ','Stamford','Stamford','NY'),('US','SDK','Smyrna','Smyrna','DE'),('US','SDL','Shelby','Shelby','MI'),('US','SDM','South El Monte','South El Monte','CA'),('US','SDN','Sidney','Sidney','OH'),('US','SDO','South Hill','South Hill','VA'),('US','SDP','Sand Point','Sand Point','AK'),('US','SDQ','Sand Springs','Sand Springs','OK'),('US','SDR','South Johnson City','South Johnson City','TN'),('US','SDS','Swedesboro','Swedesboro','NJ'),('US','SDT','South Lee','South Lee','MA'),('US','SDU','Sudan','Sudan','TX'),('US','SDV','Sheridan','Sheridan','CO'),('US','SDW','Sandusky','Sandusky','MI'),('US','SDX','Sedona','Sedona','AZ'),('US','SDY','Sidney','Sidney','MT'),('US','SDZ','Stratford','Stratford','NJ'),('US','SE2','South Elgin','South Elgin','IL'),('US','SEA','Seattle','Seattle','WA'),('US','SEB','Sebring','Sebring','OH'),('US','SEC','Seiple','Seiple','PA'),('US','SED','Sheffield','Sheffield','IA'),('US','SEE','Snellville','Snellville','GA'),('US','SEF','Sebring','Sebring','FL'),('US','SEG','Selinsgrove','Selinsgrove','PA'),('US','SEH','Sterling Heights','Sterling Heights','MI'),('US','SEI','Sheldon','Sheldon','IA'),('US','SEJ','Seymour','Seymour','MO'),('US','SEK','Sterling','Sterling','PA'),('US','SEL','Selby','Selby','CA'),('US','SEM','Salem','Salem','NJ'),('US','SEN','Senatobia','Senatobia','MS'),('US','SEO','Seabrook','Seabrook','TX'),('US','SEP','Stephenville','Stephenville','TX'),('US','SEQ','Spindale','Spindale','NC'),('US','SER','Seymour','Seymour','IN'),('US','SES','Selma','Selma','AL'),('US','SET','Seymour','Seymour','TX'),('US','SEU','Sellersburg','Sellersburg','IN'),('US','SEV','Severn','Severn','MD'),('US','SEW','Seward','Seward','AK'),('US','SEX','Sterlington','Sterlington','LA'),('US','SEY','Shelby','Shelby','NC'),('US','SEZ','Seatac','Seatac','WA'),('US','SF2','St Francis','St Francis','KS'),('US','SF3','Smithfield','Smithfield','PA'),('US','SFA','Southgate','Southgate','MI'),('US','SFB','Sanford','Sanford','FL'),('US','SFC','Stafford Springs','Stafford Springs','CT'),('US','SFD','South Plainfield','South Plainfield','NJ'),('US','SFE','Seaford','Seaford','DE'),('US','SFF','Strafford','Strafford','MO'),('US','SFG','Springfield Gardens','Springfield Gardens','NY'),('US','SFH','Spring House','Spring House','PA'),('US','SFI','Springfield','Springfield','NJ'),('US','SFJ','Southfield','Southfield','MI'),('US','SFK','Springfield','Springfield','MD'),('US','SFL','Snowflake','Snowflake','AZ'),('US','SFM','Sanford','Sanford','ME'),('US','SFN','Woonsocket','Woonsocket','RI'),('US','SFO','San Francisco','San Francisco','CA'),('US','SFP','Safety Harbor','Safety Harbor','FL'),('US','SFQ','Saraland','Saraland','AL'),('US','SFR','San Fernando','San Fernando','CA'),('US','SFS','Seneca Falls','Seneca Falls','NY'),('US','SFT','Schaefferstown','Schaefferstown','PA'),('US','SFU','Spanish Fork','Spanish Fork','UT'),('US','SFV','St Francisville','St Francisville','LA'),('US','SFW','Schofield','Schofield','WI'),('US','SFX','Southfield','Southfield','MA'),('US','SFY','Springfield','Springfield','MA'),('US','SFZ','Smithfield','Smithfield','RI'),('US','SG2','Ste Genevieve','Ste Genevieve','MO'),('US','SG3','Spring Grove','Spring Grove','IL'),('US','SGA','Saratoga Springs','Saratoga Springs','NY'),('US','SGB','Sergeant Bluff','Sergeant Bluff','IA'),('US','SGC','South Gate','South Gate','CA'),('US','SGD','Spring City','Spring City','TN'),('US','SGE','Savage','Savage','MD'),('US','SGF','Springfield','Springfield','MO'),('US','SGG','San Gabriel','San Gabriel','CA'),('US','SGH','Springfield','Springfield','OH'),('US','SGI','Sterling','Sterling','IL'),('US','SGJ','Sanger','Sanger','TX'),('US','SGK','Seagraves','Seagraves','TX'),('US','SGL','St Gabriel','St Gabriel','LA'),('US','SGM','Saginaw','Saginaw','MI'),('US','SGN','Stonington','Stonington','CT'),('US','SGO','Surgoinsville','Surgoinsville','TN'),('US','SGP','Springlake','Springlake','TX'),('US','SGR','Sugar Land','Sugar Land','TX'),('US','SGS','St George','St George','SC'),('US','SGT','Stuttgart','Stuttgart','AR'),('US','SGU','St George','St George','UT'),('US','SGV','Sterling','Sterling','VA'),('US','SGW','Saginaw Bay','Saginaw Bay','AK'),('US','SGX','Sugar Grove','Sugar Grove','PA'),('US','SGY','Skagway','Skagway','AK'),('US','SGZ','Suring','Suring','WI'),('US','SH2','Seaside Heights','Seaside Heights','NJ'),('US','SH3','Shafter, Kern','Shafter, Kern','CA'),('US','SH4','Shamong','Shamong','NJ'),('US','SH5','Skowhegan','Skowhegan','ME'),('US','SH6','Standish','Standish','MI'),('US','SH7','Susquehanna','Susquehanna','PA'),('US','SH8','Savannah','Savannah','OH'),('US','SHA','Sunshine','Sunshine','AL'),('US','SHB','Shoreview','Shoreview','MN'),('US','SHC','Shawnee','Shawnee','KS'),('US','SHD','Staunton','Staunton','VA'),('US','SHE','St Helena','St Helena','CA'),('US','SHF','Sheffield','Sheffield','AL'),('US','SHG','Shungnak','Shungnak','AK'),('US','SHH','Shishmaref','Shishmaref','AK'),('US','SHI','Spring Hill','Spring Hill','FL'),('US','SHJ','Schuyler','Schuyler','NE'),('US','SHK','Shrub Oak','Shrub Oak','NY'),('US','SHL','Sharon Hill','Sharon Hill','PA'),('US','SHM','Sharon','Sharon','MA'),('US','SHN','Shelton','Shelton','WA'),('US','SHO','Shannon','Shannon','GA'),('US','SHP','Sherman','Sherman','TX'),('US','SHQ','Sharon','Sharon','PA'),('US','SHR','Sheridan','Sheridan','WY'),('US','SHS','Sharon Springs','Sharon Springs','NY'),('US','SHT','Stonehurst','Stonehurst','CA'),('US','SHU','Shrewsbury','Shrewsbury','MA'),('US','SHV','Shreveport','Shreveport','LA'),('US','SHW','Sherwood','Sherwood','ND'),('US','SHX','Shageluk','Shageluk','AK'),('US','SHY','Shadyside','Shadyside','OH'),('US','SHZ','Shelley','Shelley','ID'),('US','SI2','Sledge Island','Sledge Island','AK'),('US','SIA','Scotia','Scotia','CA'),('US','SIB','Silver Bay','Silver Bay','MN'),('US','SIC','Steilacoom','Steilacoom','WA'),('US','SID','Schiller Park','Schiller Park','IL'),('US','SIE','Silver Springs','Silver Springs','FL'),('US','SIF','Silverdale','Silverdale','WA'),('US','SIG','Sterling','Sterling','AK'),('US','SIH','Showell','Showell','MD'),('US','SII','Signal Hill','Signal Hill','CA'),('US','SIJ','Simpsonville','Simpsonville','KY'),('US','SIK','Sikeston','Sikeston','MO'),('US','SIL','Suitland','Suitland','MD'),('US','SIM','Sierra Madre','Sierra Madre','CA'),('US','SIN','Singer Island','Singer Island','FL'),('US','SIO','Simsboro','Simsboro','LA'),('US','SIP','Saint Peter','Saint Peter','MN'),('US','SIQ','Springhill','Springhill','LA'),('US','SIR','Siler City','Siler City','NC'),('US','SIS','Silver Spring','Silver Spring','MD'),('US','SIT','Sitka','Sitka','AK'),('US','SIU','Simi Valley','Simi Valley','CA'),('US','SIV','Sullivan','Sullivan','IN'),('US','SIW','Sheridan','Sheridan','AR'),('US','SIX','Suisun City','Suisun City','CA'),('US','SIY','Montague','Montague','CA'),('US','SIZ','Sallis','Sallis','MS'),('US','SJ2','St James','St James','MI'),('US','SJ3','St Jo','St Jo','TX'),('US','SJ4','St Johns','St Johns','MI'),('US','SJ5','St Martin','St Martin','MN'),('US','SJA','St James','St James','MN'),('US','SJB','San Ramon','San Ramon','CA'),('US','SJC','San Jose','San Jose','CA'),('US','SJD','Sandy','Sandy','OR'),('US','SJE','Sandy','Sandy','UT'),('US','SJF','Saint Joseph','Saint Joseph','FL'),('US','SJG','Sheridan','Sheridan','OR'),('US','SJH','Sagamore Hills','Sagamore Hills','OH'),('US','SJI','Saline','Saline','MI'),('US','SJJ','Sherman Oaks','Sherman Oaks','CA'),('US','SJK','Sherrard','Sherrard','IL'),('US','SJL','Southampton','Southampton','PA'),('US','SJM','St James','St James','OH'),('US','SJN','St Johns','St Johns','AZ'),('US','SJO','St John','St John','ND'),('US','SJP','Saint Joseph','Saint Joseph','MN'),('US','SJQ','Saginaw','Saginaw','TX'),('US','SJR','Shirley','Shirley','MA'),('US','SJT','San Angelo','San Angelo','TX'),('US','SJU','Sherwood','Sherwood','OR'),('US','SJV','Shorewood','Shorewood','OR'),('US','SJW','St Marys','St Marys','GA'),('US','SJY','Sun City','Sun City','FL'),('US','SJZ','Stevenson','Stevenson','AL'),('US','SK2','South Kearny','South Kearny','NJ'),('US','SK3','Summerland Key','Summerland Key','FL'),('US','SKB','Stockbridge','Stockbridge','GA'),('US','SKC','Saint Charles','Saint Charles','MD'),('US','SKD','Sneads Ferry','Sneads Ferry','NC'),('US','SKE','Shakopee','Shakopee','MN'),('US','SKG','Stockbridge','Stockbridge','MI'),('US','SKI','Selkirk','Selkirk','NY'),('US','SKJ','Sitkinak Island','Sitkinak Island','AK'),('US','SKK','Shaktoolik','Shaktoolik','AK'),('US','SKL','Schuylkill','Schuylkill','PA'),('US','SKM','St Martinville','St Martinville','LA'),('US','SKN','Schodack Landing','Schodack Landing','NY'),('US','SKO','Showhegan','Showhegan','ME'),('US','SKP','Skippers','Skippers','VA'),('US','SKQ','Suncook','Suncook','NH'),('US','SKR','Santa Clara','Santa Clara','UT'),('US','SKS','Sinking Spring','Sinking Spring','PA'),('US','SKT','Stickney','Stickney','IL'),('US','SKU','Schuylkill Haven','Schuylkill Haven','PA'),('US','SKV','Spicewood','Spicewood','TX'),('US','SKW','Skwentna','Skwentna','AK'),('US','SKX','Sugar Creek','Sugar Creek','MO'),('US','SKY','Sandusky, Erie','Sandusky, Erie','OH'),('US','SKZ','Saint Clair','Saint Clair','PA'),('US','SL2','St Lucie','St Lucie','FL'),('US','SL3','Spring Lake','Spring Lake','NC'),('US','SL4','Sartell','Sartell','MN'),('US','SLA','Sallisaw','Sallisaw','OK'),('US','SLB','Storm Lake','Storm Lake','IA'),('US','SLC','Salt Lake City','Salt Lake City','UT'),('US','SLD','Sutherlin','Sutherlin','OR'),('US','SLE','Salem','Salem','OR'),('US','SLF','Salem','Salem','IN'),('US','SLG','Siloam Springs','Siloam Springs','AR'),('US','SLH','Seal Beach','Seal Beach','CA'),('US','SLI','San Luis','San Luis','AZ'),('US','SLJ','Sledge','Sledge','MS'),('US','SLK','Saranac Lake','Saranac Lake','NY'),('US','SLL','Saltillo','Saltillo','MS'),('US','SLM','Salem','Salem','MA'),('US','SLN','Salina','Salina','KS'),('US','SLO','Salem','Salem','IL'),('US','SLP','Sulphur','Sulphur','LA'),('US','SLQ','Sleetmute','Sleetmute','AK'),('US','SLR','Sulphur Springs','Sulphur Springs','TX'),('US','SLS','Salisbury','Salisbury','MA'),('US','SLT','Salida','Salida','CO'),('US','SLU','San Luis','San Luis','CO'),('US','SLV','Slatersville','Slatersville','RI'),('US','SLW','Stevensville','Stevensville','MI'),('US','SLX','Shallotte','Shallotte','NC'),('US','SLY','Sealy','Sealy','TX'),('US','SLZ','St Louis Park','St Louis Park','MN'),('US','SM2','Shawnee Mission','Shawnee Mission','KS'),('US','SM3','Sunman','Sunman','IN'),('US','SMA','St Marys','St Marys','WV'),('US','SMB','St Matthews','St Matthews','SC'),('US','SMC','San Marcos','San Marcos','TX'),('US','SMD','San Marino','San Marino','CA'),('US','SME','Somerset','Somerset','KY'),('US','SMF','Smithfield','Smithfield','NC'),('US','SMG','Santa Margarita','Santa Margarita','CA'),('US','SMH','Stratham','Stratham','NH'),('US','SMI','Smithville','Smithville','GA'),('US','SMJ','Strathmore','Strathmore','CA'),('US','SMK','St Michael','St Michael','AK'),('US','SML','Shermans Dale','Shermans Dale','PA'),('US','SMM','Strathmere','Strathmere','NJ'),('US','SMN','Salmon','Salmon','ID'),('US','SMO','Santa Monica','Santa Monica','CA'),('US','SMP','Sampit','Sampit','SC'),('US','SMQ','Salem','Salem','MO'),('US','SMR','St Marys','St Marys','OH'),('US','SMS','Sutter','Sutter','CA'),('US','SMT','Smithfield','Smithfield','VA'),('US','SMU','Sheep Mountain','Sheep Mountain','AK'),('US','SMV','Somerdale','Somerdale','NJ'),('US','SMW','Streamwood','Streamwood','IL'),('US','SMX','Santa Maria','Santa Maria','CA'),('US','SMY','Smyrna','Smyrna','GA'),('US','SMZ','Summit','Summit','AL'),('US','SN2','Senoia','Senoia','GA'),('US','SN3','Sharon','Sharon','VT'),('US','SNA','Santa Ana','Santa Ana','CA'),('US','SNB','Strang','Strang','TX'),('US','SNC','Sunset','Sunset','CA'),('US','SND','Sunland','Sunland','CA'),('US','SNE','Seneca','Seneca','MO'),('US','SNF','Springfield','Springfield','MN'),('US','SNG','Southington','Southington','CT'),('US','SNH','San Leandro','San Leandro','CA'),('US','SNI','Snohomish','Snohomish','WA'),('US','SNJ','Saint James','Saint James','LA'),('US','SNK','Snyder','Snyder','TX'),('US','SNL','Shawnee','Shawnee','OK'),('US','SNM','San Marcos','San Marcos','CA'),('US','SNN','Sunnyvale','Sunnyvale','CA'),('US','SNO','Swannanoa','Swannanoa','NC'),('US','SNP','St Paul Island','St Paul Island','AK'),('US','SNQ','Savanna','Savanna','IL'),('US','SNR','Severna Park','Severna Park','MD'),('US','SNS','Salinas','Salinas','CA'),('US','SNT','Sioux Center','Sioux Center','IA'),('US','SNU','Springville','Springville','UT'),('US','SNV','Sandersville','Sandersville','GA'),('US','SNW','Stanwood','Stanwood','WA'),('US','SNX','Spenard','Spenard','AK'),('US','SNY','Sidney','Sidney','NE'),('US','SNZ','Spencer','Spencer','WI'),('US','SOA','Scotia','Scotia','NY'),('US','SOB','Sodus','Sodus','MI'),('US','SOC','St Cloud','St Cloud','FL'),('US','SOD','Sodus Point','Sodus Point','NY'),('US','SOE','Seminole','Seminole','TX'),('US','SOF','South Bay','South Bay','FL'),('US','SOG','South Boston','South Boston','VA'),('US','SOH','South Haven','South Haven','MI'),('US','SOI','South Dayton','South Dayton','NY'),('US','SOJ','Somerset','Somerset','NJ'),('US','SOK','Skokie','Skokie','IL'),('US','SOL','Solomon','Solomon','AK'),('US','SOM','Somerville','Somerville','NJ'),('US','SON','South Norwalk','South Norwalk','CT'),('US','SOO','Solon','Solon','OH'),('US','SOP','Southern Pines','Southern Pines','NC'),('US','SOQ','South Grafton','South Grafton','MA'),('US','SOR','Sonora','Sonora','CA'),('US','SOS','Spring Park','Spring Park','MN'),('US','SOT','Souderton','Souderton','PA'),('US','SOU','Stoughton','Stoughton','MA'),('US','SOV','Seldovia','Seldovia','AK'),('US','SOW','Show Low','Show Low','AZ'),('US','SOX','South Portland','South Portland','ME'),('US','SOY','Sonoma','Sonoma','CA'),('US','SOZ','Somerset','Somerset','TX'),('US','SP2','Sagaponack','Sagaponack','NY'),('US','SP3','Skippack','Skippack','PA'),('US','SP4','Southport','Southport','IN'),('US','SP5','Strawberry Point','Strawberry Point','IA'),('US','SP6','Spencerport','Spencerport','NY'),('US','SPA','Spartanburg','Spartanburg','SC'),('US','SPB','Spartansburg','Spartansburg','PA'),('US','SPC','Spencer','Spencer','NY'),('US','SPD','Springdale','Springdale','PA'),('US','SPE','Sun Prairie','Sun Prairie','WI'),('US','SPF','Spearfish','Spearfish','SD'),('US','SPG','Springfield','Springfield','VA'),('US','SPH','South Point','South Point','OH'),('US','SPI','Springfield','Springfield','IL'),('US','SPJ','Scotch Plains','Scotch Plains','NJ'),('US','SPK','Sparks','Sparks','NV'),('US','SPL','Springville','Springville','AL'),('US','SPM','Sparks','Sparks','GA'),('US','SPN','Spring Valley','Spring Valley','IL'),('US','SPO','Spooner','Spooner','WI'),('US','SPP','Spencer','Spencer','OH'),('US','SPQ','San Pedro','San Pedro','CA'),('US','SPR','Spencer','Spencer','MA'),('US','SPS','Wichita Falls','Wichita Falls','TX'),('US','SPT','South St Paul','South St Paul','MN'),('US','SPU','Spruce Pine','Spruce Pine','NC'),('US','SPV','Spring Valley','Spring Valley','NY'),('US','SPW','Spencer','Spencer','IA'),('US','SPX','Sparta','Sparta','TN'),('US','SPY','Springfield','Springfield','OR'),('US','SPZ','Springdale','Springdale','AR'),('US','SQA','Santa Ynez','Santa Ynez','CA'),('US','SQB','Scottsboro','Scottsboro','AL'),('US','SQC','Selma','Selma','NC'),('US','SQD','Selma','Selma','TX'),('US','SQE','Selmer','Selmer','TN'),('US','SQF','Sepulveda','Sepulveda','CA'),('US','SQH','Sparta','Sparta','MI'),('US','SQI','Sterling-Rockfalls Apt','Sterling-Rockfalls Apt','IL'),('US','SQJ','Succasunna','Succasunna','NJ'),('US','SQK','Sheldon Springs','Sheldon Springs','VT'),('US','SQL','San Carlos','San Carlos','CA'),('US','SQM','Skillman','Skillman','NJ'),('US','SQN','Shepherdsville','Shepherdsville','KY'),('US','SQO','Springboro','Springboro','OH'),('US','SQP','Sheldon','Sheldon','MO'),('US','SQQ','Soquel','Soquel','CA'),('US','SQR','Shelton','Shelton','CT'),('US','SQS','St Peters','St Peters','MO'),('US','SQT','Squaw Valley','Squaw Valley','CA'),('US','SQU','Seguin','Seguin','TX'),('US','SQV','Sequim','Sequim','WA'),('US','SQW','Seneca','Seneca','SC'),('US','SQX','Slater','Slater','SC'),('US','SQY','Sneedville','Sneedville','TN'),('US','SQZ','Selma','Selma','CA'),('US','SR2','Shell Rock','Shell Rock','IA'),('US','SR3','South Rockwood','South Rockwood','MI'),('US','SR4','Shalimar','Shalimar','FL'),('US','SR5','Shamrock, Wheeler','Shamrock, Wheeler','TX'),('US','SR6','Sahuarita','Sahuarita','AZ'),('US','SRA','Sauk Rapids','Sauk Rapids','MN'),('US','SRB','Saratoga','Saratoga','MN'),('US','SRC','Searcy','Searcy','AR'),('US','SRD','Sheridan','Sheridan','NY'),('US','SRE','St Rose','St Rose','LA'),('US','SRF','San Rafael','San Rafael','CA'),('US','SRG','Springfield','Springfield','TN'),('US','SRH','Shoreham','Shoreham','VT'),('US','SRI','Shoreline','Shoreline','WA'),('US','SRJ','Sunbury','Sunbury','PA'),('US','SRK','Sanger','Sanger','CA'),('US','SRL','Springdale','Springdale','OH'),('US','SRM','Sparks','Sparks','MD'),('US','SRN','Saranac','Saranac','MI'),('US','SRO','Spring Hope','Spring Hope','NC'),('US','SRP','Searsport','Searsport','ME'),('US','SRQ','Bradenton-Sarasota Apt','Bradenton-Sarasota Apt','FL'),('US','SRR','Sherburne','Sherburne','NY'),('US','SRS','Strasburg','Strasburg','VA'),('US','SRT','Schertz','Schertz','TX'),('US','SRU','Santa Cruz','Santa Cruz','CA'),('US','SRV','Stony River','Stony River','AK'),('US','SRW','Salisbury','Salisbury','NC'),('US','SRX','Sturtevant','Sturtevant','WI'),('US','SRY','Simpsonville','Simpsonville','SC'),('US','SRZ','Sunbury','Sunbury','OH'),('US','SS2','Sisseton','Sisseton','SD'),('US','SS3','Somerset','Somerset','MA'),('US','SS4','Sunset','Sunset','UT'),('US','SS5','Swansea','Swansea','SC'),('US','SS6','Sunnyside, Queens','Sunnyside, Queens','NY'),('US','SS7','Stevens','Stevens','PA'),('US','SSA','South Paris','South Paris','ME'),('US','SSB','St Bernard','St Bernard','OH'),('US','SSC','Sumter','Sumter','SC'),('US','SSD','South Pasadena','South Pasadena','CA'),('US','SSE','South River','South River','NJ'),('US','SSF','Southard','Southard','OK'),('US','SSG','Shippensburg','Shippensburg','PA'),('US','SSH','South Shore','South Shore','KY'),('US','SSI','Brunswick','Brunswick','GA'),('US','SSJ','Somis','Somis','CA'),('US','SSK','Southampton','Southampton','NY'),('US','SSL','St Charles','St Charles','IL'),('US','SSM','Sault Ste Marie','Sault Ste Marie','MI'),('US','SSN','Snyder','Snyder','NE'),('US','SSO','South Sioux City','South Sioux City','NE'),('US','SSP','South Range','South Range','MI'),('US','SSQ','South Pierce','South Pierce','FL'),('US','SSR','Sardis','Sardis','MS'),('US','SSS','St Simons Island','St Simons Island','GA'),('US','SST','South River','South River','MO'),('US','SSU','White Sulphur Springs','White Sulphur Springs','WV'),('US','SSV','Strongsville','Strongsville','OH'),('US','SSW','Stuart Island','Stuart Island','WA'),('US','SSX','Somersworth','Somersworth','NH'),('US','SSY','Sussex','Sussex','WI'),('US','SSZ','Scottsburg','Scottsburg','IN'),('US','ST2','Stuart','Stuart','VA'),('US','STA','St Albans','St Albans','VT'),('US','STB','Stafford','Stafford','VA'),('US','STC','St Cloud','St Cloud','MN'),('US','STD','Stafford','Stafford','TX'),('US','STE','Stevens Point','Stevens Point','WI'),('US','STF','Stamford','Stamford','TX'),('US','STG','St George Island','St George Island','AK'),('US','STH','St Helens','St Helens','OR'),('US','STI','Stanton','Stanton','CA'),('US','STJ','Saint Joseph','Saint Joseph','MO'),('US','STK','Sterling','Sterling','CO'),('US','STL','St Louis','St Louis','MO'),('US','STM','Stamps','Stamps','AR'),('US','STN','Stanhope','Stanhope','NJ'),('US','STO','Stone','Stone','SC'),('US','STP','St Paul','St Paul','MN'),('US','STQ','St Marys','St Marys','PA'),('US','STR','Streator','Streator','IL'),('US','STS','Santa Rosa','Santa Rosa','CA'),('US','STT','Stockertown','Stockertown','PA'),('US','STU','Stoneham','Stoneham','MA'),('US','STV','Stoneville','Stoneville','MS'),('US','STW','Strausstown','Strausstown','PA'),('US','STX','Stanton','Stanton','TX'),('US','STY','Smithtown','Smithtown','NY'),('US','STZ','Scottsdale','Scottsdale','AZ'),('US','SUA','Stuart','Stuart','FL'),('US','SUB','Shubuta','Shubuta','MS'),('US','SUC','Sundance','Sundance','WY'),('US','SUD','Stroud','Stroud','OK'),('US','SUE','Sturgeon Bay','Sturgeon Bay','WI'),('US','SUF','Suffolk','Suffolk','VA'),('US','SUG','Sulligent','Sulligent','AL'),('US','SUH','Summerhill','Summerhill','PA'),('US','SUI','South Holland','South Holland','IL'),('US','SUJ','Suffern','Suffern','NY'),('US','SUK','Shattuck','Shattuck','OK'),('US','SUL','Pt Sulphur','Pt Sulphur','LA'),('US','SUM','Stone Mountain','Stone Mountain','GA'),('US','SUN','Hailey-Sun Valley Apt','Hailey-Sun Valley Apt','ID'),('US','SUO','Sun River','Sun River','OR'),('US','SUP','Sutton','Sutton','WV'),('US','SUQ','Success','Success','MO'),('US','SUR','Sudbury','Sudbury','MA'),('US','SUS','Spirit of St Louis Apt/St Louis','Spirit of St Louis Apt/St Louis','MO'),('US','SUT','Sunny Point','Sunny Point','NC'),('US','SUU','Fairfield','Fairfield','CA'),('US','SUV','Saugerties','Saugerties','NY'),('US','SUW','Superior','Superior','WI'),('US','SUX','Sioux City','Sioux City','IA'),('US','SUY','Sunnyside','Sunnyside','WA'),('US','SUZ','Sublimity','Sublimity','OR'),('US','SV2','Sanbornville','Sanbornville','NH'),('US','SV3','Schuylerville','Schuylerville','NY'),('US','SV4','Scotts Valley','Scotts Valley','CA'),('US','SV5','Sicklerville','Sicklerville','NJ'),('US','SV6','Sutersville','Sutersville','PA'),('US','SV7','Stewartville','Stewartville','MN'),('US','SVA','Savoonga','Savoonga','AK'),('US','SVB','Shickshinny','Shickshinny','PA'),('US','SVC','Silver City','Silver City','NM'),('US','SVD','Sunnyvale','Sunnyvale','TX'),('US','SVE','Susanville','Susanville','CA'),('US','SVF','Shiremanstown','Shiremanstown','PA'),('US','SVG','Suwanee','Suwanee','GA'),('US','SVH','Statesville','Statesville','NC'),('US','SVI','Seagoville','Seagoville','TX'),('US','SVJ','Severn','Severn','VA'),('US','SVK','Slate Hill','Slate Hill','NY'),('US','SVL','Schererville','Schererville','IN'),('US','SVM','Slater','Slater','MO'),('US','SVN','Severn','Severn','NC'),('US','SVO','Summitville','Summitville','OH'),('US','SVP','Slatington','Slatington','PA'),('US','SVQ','Southaven','Southaven','MS'),('US','SVR','Silver Springs','Silver Springs','NY'),('US','SVS','Stevens Village','Stevens Village','AK'),('US','SVT','Slippery Rock','Slippery Rock','PA'),('US','SVU','Sevierville','Sevierville','TN'),('US','SVV','Stevensville','Stevensville','MD'),('US','SVW','Sparrevohn','Sparrevohn','AK'),('US','SVX','Stoneville','Stoneville','NC'),('US','SVY','Sun Valley','Sun Valley','CA'),('US','SVZ','Shelbyville','Shelbyville','KY'),('US','SW2','Sedro Woolley','Sedro Woolley','WA'),('US','SW3','Shorewood','Shorewood','IL'),('US','SW4','South West City','South West City','MO'),('US','SW5','Swanzey','Swanzey','NH'),('US','SW6','Swansea','Swansea','IL'),('US','SWA','Swanton','Swanton','VT'),('US','SWB','Sebewaing','Sebewaing','MI'),('US','SWC','Sandwich','Sandwich','MA'),('US','SWD','Seward','Seward','AK'),('US','SWE','Sunset Whitney Ranch','Sunset Whitney Ranch','CA'),('US','SWF','Newburgh','Newburgh','NY'),('US','SWG','Sweet Grass','Sweet Grass','MT'),('US','SWH','Sandwich','Sandwich','IL'),('US','SWI','Swissvale','Swissvale','PA'),('US','SWJ','Swainsboro','Swainsboro','GA'),('US','SWK','Seekonk','Seekonk','MA'),('US','SWL','Stonewall','Stonewall','MS'),('US','SWM','Snowmass Village','Snowmass Village','CO'),('US','SWN','Sewaren','Sewaren','NJ'),('US','SWO','Stillwater','Stillwater','OK'),('US','SWP','Summit Point','Summit Point','WV'),('US','SWQ','Swanton','Swanton','OH'),('US','SWR','Sawyer','Sawyer','MI'),('US','SWS','Shawano','Shawano','WI'),('US','SWT','Stow','Stow','OH'),('US','SWU','South Pittsburg','South Pittsburg','TN'),('US','SWV','Summersville','Summersville','WV'),('US','SWW','Sweetwater','Sweetwater','TX'),('US','SWX','South Windham','South Windham','ME'),('US','SWY','Spanaway','Spanaway','WA'),('US','SWZ','Swepsonville','Swepsonville','NC'),('US','SXA','Salem','Salem','NH'),('US','SXB','San Bruno','San Bruno','CA'),('US','SXC','Danville','Danville','CA'),('US','SXD','Santee','Santee','CA'),('US','SXE','Strong','Strong','ME'),('US','SXF','San Mateo','San Mateo','CA'),('US','SXG','Sumner','Sumner','GA'),('US','SXH','St Pauls','St Pauls','NC'),('US','SXI','Steele','Steele','AL'),('US','SXJ','San Martin','San Martin','CA'),('US','SXK','Starkville','Starkville','MS'),('US','SXL','Sauk Village','Sauk Village','IL'),('US','SXM','Sixela','Sixela','NM'),('US','SXN','Samson','Samson','AL'),('US','SXP','Sheldon Point','Sheldon Point','AK'),('US','SXQ','Soldotna','Soldotna','AK'),('US','SXR','Sevier','Sevier','NC'),('US','SXS','Society Hill','Society Hill','SC'),('US','SXT','Santa Teresa','Santa Teresa','NM'),('US','SXU','Sutton','Sutton','AK'),('US','SXV','Silver Creek','Silver Creek','GA'),('US','SXW','St Paul','St Paul','AL'),('US','SXX','Saint Joseph','Saint Joseph','MI'),('US','SXY','Sidney','Sidney','NY'),('US','SXZ','Swartz Creek','Swartz Creek','MI'),('US','SYA','Shemya','Shemya','AK'),('US','SYB','Seal Bay','Seal Bay','AK'),('US','SYC','Sycamore','Sycamore','IL'),('US','SYD','Sebastopol','Sebastopol','CA'),('US','SYE','Sleepy Eye','Sleepy Eye','MN'),('US','SYF','South San Francisco','South San Francisco','CA'),('US','SYG','Savoy','Savoy','IL'),('US','SYH','Shelbyville','Shelbyville','IN'),('US','SYI','Shelbyville','Shelbyville','TN'),('US','SYJ','Stanley','Stanley','VA'),('US','SYK','Saybrook','Saybrook','CT'),('US','SYL','San Miguel','San Miguel','CA'),('US','SYM','South Hadley','South Hadley','MA'),('US','SYN','Stanton','Stanton','MN'),('US','SYO','San Ysidro','San Ysidro','CA'),('US','SYP','Sandy Point','Sandy Point','ME'),('US','SYQ','Syosset','Syosset','NY'),('US','SYR','Syracuse','Syracuse','NY'),('US','SYS','Sayville','Sayville','NY'),('US','SYT','St Louis','St Louis','MI'),('US','SYU','Sylacauga','Sylacauga','AL'),('US','SYV','Sylvester','Sylvester','GA'),('US','SYW','Seymour','Seymour','WI'),('US','SYX','Supreme','Supreme','LA'),('US','SYY','Sylmar','Sylmar','CA'),('US','SYZ','Syracuse','Syracuse','IN'),('US','SZA','Sparta','Sparta','NJ'),('US','SZB','Solana Beach','Solana Beach','CA'),('US','SZC','Scholls','Scholls','OR'),('US','SZD','Scottdale','Scottdale','GA'),('US','SZE','Scottdale','Scottdale','PA'),('US','SZF','Scottsville','Scottsville','TX'),('US','SZG','Sebastian','Sebastian','FL'),('US','SZH','Shenandoah','Shenandoah','VA'),('US','SZI','Silver City','Silver City','NC'),('US','SZJ','Shady Dale','Shady Dale','GA'),('US','SZK','Seymour','Seymour','CT'),('US','SZL','Warrensburg','Warrensburg','MO'),('US','SZM','Sherman','Sherman','MS'),('US','SZN','Shannon','Shannon','MS'),('US','SZO','Solomon','Solomon','KS'),('US','SZP','Santa Paula','Santa Paula','CA'),('US','SZR','Somerset','Somerset','PA'),('US','SZS','Summit','Summit','PA'),('US','SZT','Stanleytown','Stanleytown','VA'),('US','SZU','Simsbury','Simsbury','CT'),('US','SZV','Southborough','Southborough','MA'),('US','SZW','Southwick','Southwick','MA'),('US','SZX','Scarborough','Scarborough','ME'),('US','SZY','Staley','Staley','NC'),('US','SZZ','St Nazianz','St Nazianz','WI'),('US','TAA','Tallapoosa','Tallapoosa','GA'),('US','TAB','Tabb','Tabb','VA'),('US','TAC','Tahoe City','Tahoe City','CA'),('US','TAD','Trinidad','Trinidad','CO'),('US','TAE','Stapleton','Stapleton','GA'),('US','TAF','Taftville','Taftville','CT'),('US','TAH','Tahoka','Tahoka','TX'),('US','TAI','Stallings','Stallings','NC'),('US','TAK','Tallman','Tallman','NY'),('US','TAL','Tanana','Tanana','AK'),('US','TAM','Tama','Tama','IA'),('US','TAN','Stanford','Stanford','KY'),('US','TAO','Taylor','Taylor','WI'),('US','TAP','Tappan','Tappan','NY'),('US','TAR','Hart','Hart','TX'),('US','TAS','Stearns','Stearns','KY'),('US','TAT','Atlanta','Atlanta','TX'),('US','TAU','Tallulah','Tallulah','LA'),('US','TAV','Tavares','Tavares','FL'),('US','TAW','Matawan','Matawan','NJ'),('US','TAY','Thayer','Thayer','KS'),('US','TB2','Thorsby','Thorsby','AL'),('US','TBA','St Albans','St Albans','MO'),('US','TBB','Talla Bena','Talla Bena','LA'),('US','TBC','Tuba City','Tuba City','AZ'),('US','TBD','Taylorville','Taylorville','IL'),('US','TBE','East Bernard','East Bernard','TX'),('US','TBG','Twinsburg','Twinsburg','OH'),('US','TBL','Trumbull','Trumbull','CT'),('US','TBN','Fort Leonard Wood','Fort Leonard Wood','MO'),('US','TBO','Mount Hebron','Mount Hebron','MD'),('US','TBP','Tobyhanna','Tobyhanna','PA'),('US','TBR','Statesboro','Statesboro','GA'),('US','TBV','Trumbauersville','Trumbauersville','PA'),('US','TBY','Boyd','Boyd','MT'),('US','TC2','Town Creek','Town Creek','AL'),('US','TCA','St Charles','St Charles','IL'),('US','TCC','Tucumcari','Tucumcari','NM'),('US','TCE','Tecumseh','Tecumseh','OK'),('US','TCH','Taconite Harbor','Taconite Harbor','MN'),('US','TCI','Temple City','Temple City','CA'),('US','TCL','Tuscaloosa','Tuscaloosa','AL'),('US','TCN','Canton','Canton','TX'),('US','TCR','Trout Creek','Trout Creek','NY'),('US','TCS','Truth Or Consequences','Truth Or Consequences','NM'),('US','TCT','Takotna','Takotna','AK'),('US','TCU','Tecumseh','Tecumseh','KS'),('US','TDE','Tierra Verde','Tierra Verde','FL'),('US','TDO','Toledo','Toledo','WA'),('US','TDV','Toddville','Toddville','NC'),('US','TEA','Teaneck','Teaneck','NJ'),('US','TEB','Teterboro','Teterboro','NJ'),('US','TEC','Tecate','Tecate','CA'),('US','TED','Toleda','Toleda','IA'),('US','TEE','Terrell','Terrell','TN'),('US','TEF','Telford','Telford','PA'),('US','TEG','Pantego','Pantego','NC'),('US','TEH','Tetlin','Tetlin','AK'),('US','TEI','Waterville','Waterville','OH'),('US','TEJ','Chester Heights','Chester Heights','PA'),('US','TEK','Tatitlek','Tatitlek','AK'),('US','TEL','Tell City','Tell City','IN'),('US','TEM','Temperanceville','Temperanceville','VA'),('US','TEN','Tennent','Tennent','NJ'),('US','TEO','Theodore','Theodore','AL'),('US','TEP','Stephentown','Stephentown','NY'),('US','TEQ','Trenton','Trenton','IL'),('US','TER','Stewart','Stewart','AL'),('US','TES','Stevensville','Stevensville','MT'),('US','TET','Teton Village','Teton Village','WY'),('US','TEU','Tequesta','Tequesta','FL'),('US','TEV','Temperance','Temperance','MI'),('US','TEW','Tewksbury','Tewksbury','MA'),('US','TEX','Texarkana','Texarkana','TX'),('US','TF2','Taft','Taft','CA'),('US','TF3','Topsfield','Topsfield','MA'),('US','TFD','Stanfield','Stanfield','AZ'),('US','TFE','Pittsfield','Pittsfield','IL'),('US','TFF','Trafford','Trafford','PA'),('US','TFG','Trafalgar','Trafalgar','IN'),('US','TFN','Tiffin','Tiffin','OH'),('US','TFO','Stratford','Stratford','WI'),('US','TFR','Transfer','Transfer','PA'),('US','TFT','Taft','Taft','LA'),('US','TFY','Taneytown','Taneytown','MD'),('US','TG2','Tyngsboro','Tyngsboro','MA'),('US','TGE','Tuskegee','Tuskegee','AL'),('US','TGG','Cottage Grove','Cottage Grove','OR'),('US','TGM','Mountain Green','Mountain Green','UT'),('US','TGN','St Genevieve','St Genevieve','MO'),('US','TGO','Pleasant Grove','Pleasant Grove','AL'),('US','TGR','Tigerton','Tigerton','WI'),('US','TGT','Torrington','Torrington','CT'),('US','TGU','Tahlequah','Tahlequah','OK'),('US','TGV','Pittsgrove','Pittsgrove','NJ'),('US','THA','Tullahoma','Tullahoma','TN'),('US','THB','Two Harbors','Two Harbors','MN'),('US','THC','Mather','Mather','CA'),('US','THD','Southbridge','Southbridge','MA'),('US','THE','Three Bridges','Three Bridges','NJ'),('US','THF','Thompson Falls','Thompson Falls','MT'),('US','THG','Heath Springs','Heath Springs','SC'),('US','THH','Temple Hills','Temple Hills','MD'),('US','THI','Thibodaux','Thibodaux','LA'),('US','THK','Thacker','Thacker','WV'),('US','THL','Thompsonville','Thompsonville','MI'),('US','THM','Thompsonfield','Thompsonfield','MO'),('US','THN','Athena','Athena','OR'),('US','THO','Thomaston','Thomaston','CT'),('US','THP','Thermopolis','Thermopolis','WY'),('US','THR','Thorndale','Thorndale','PA'),('US','THS','Thomaston','Thomaston','GA'),('US','THT','Thornton','Thornton','CO'),('US','THU','Croton-on-Hudson','Croton-on-Hudson','NY'),('US','THV','York','York','PA'),('US','THW','The Woodlands','The Woodlands','TX'),('US','TIA','Tulia','Tulia','TX'),('US','TIC','Ticonderoga','Ticonderoga','NY'),('US','TID','Tigard','Tigard','OR'),('US','TIE','Wolcottville','Wolcottville','IN'),('US','TIH','Antioch','Antioch','IL'),('US','TII','Tipton','Tipton','IN'),('US','TIJ','Tijeras','Tijeras','NM'),('US','TIL','Waterville','Waterville','WA'),('US','TIN','Tinton Falls','Tinton Falls','NJ'),('US','TIO','Antioch','Antioch','TN'),('US','TIR','Trinity','Trinity','NC'),('US','TIS','Stillwater','Stillwater','MN'),('US','TIT','Titusville','Titusville','PA'),('US','TIV','Tiverton','Tiverton','RI'),('US','TIW','Tacoma','Tacoma','WA'),('US','TIX','Titusville','Titusville','FL'),('US','TIY','Terminal Island','Terminal Island','CA'),('US','TJN','Tujunga','Tujunga','CA'),('US','TJS','St James','St James','NY'),('US','TKA','Talkeetna','Talkeetna','AK'),('US','TKE','Tenakee Springs','Tenakee Springs','AK'),('US','TKF','Truckee','Truckee','CA'),('US','TKI','Tokeen','Tokeen','AK'),('US','TKJ','Tok','Tok','AK'),('US','TKK','Tunkhannock','Tunkhannock','PA'),('US','TKL','Taku Lodge','Taku Lodge','AK'),('US','TKP','Bethel Park','Bethel Park','PA'),('US','TKV','Tappahannock','Tappahannock','VA'),('US','TKY','Loretto','Loretto','KY'),('US','TL2','Tilton','Tilton','NH'),('US','TL3','Timber Lake','Timber Lake','SD'),('US','TL4','Tuolumne','Tuolumne','CA'),('US','TLA','Teller','Teller','AK'),('US','TLC','Turtle Creek','Turtle Creek','PA'),('US','TLD','Tolland','Tolland','CT'),('US','TLE','Timberlake','Timberlake','NC'),('US','TLF','Telida','Telida','AK'),('US','TLG','Telogia','Telogia','FL'),('US','TLH','Tallahassee','Tallahassee','FL'),('US','TLI','Mint Hill','Mint Hill','NC'),('US','TLJ','Tatalina','Tatalina','AK'),('US','TLK','Turlock','Turlock','CA'),('US','TLL','Tulelake','Tulelake','CA'),('US','TLM','Tillamook','Tillamook','OR'),('US','TLN','Atlanta','Atlanta','IN'),('US','TLO','Talmo','Talmo','GA'),('US','TLR','Tulare','Tulare','CA'),('US','TLS','West Hills','West Hills','CA'),('US','TLT','Tuluksak','Tuluksak','AK'),('US','TLU','Toluca','Toluca','IL'),('US','TLV','Central Valley','Central Valley','NY'),('US','TLW','Littlestown','Littlestown','PA'),('US','TLY','Tully','Tully','NY'),('US','TM2','Thomas','Thomas','WV'),('US','TMA','Tifton','Tifton','GA'),('US','TMB','Timberville','Timberville','VA'),('US','TMC','Temecula','Temecula','CA'),('US','TMG','Tallmadge','Tallmadge','OH'),('US','TMH','Tekamah','Tekamah','NE'),('US','TMI','St Michael','St Michael','MN'),('US','TMJ','Mill Spring','Mill Spring','NC'),('US','TML','Temple','Temple','GA'),('US','TMM','Tamms','Tamms','IL'),('US','TMN','Trumann','Trumann','AR'),('US','TMO','Altamont','Altamont','UT'),('US','TMP','Temple','Temple','PA'),('US','TMQ','Tamaqua','Tamaqua','PA'),('US','TMR','Altheimer','Altheimer','AR'),('US','TMV','Thomasville','Thomasville','PA'),('US','TMX','Tremont','Tremont','MS'),('US','TMZ','Tecumseh','Tecumseh','MO'),('US','TN2','Toney','Toney','AL'),('US','TN3','Tonganoxie','Tonganoxie','KS'),('US','TNA','Byant','Byant','AR'),('US','TNB','Stanberry','Stanberry','MO'),('US','TNC','Tin City','Tin City','AK'),('US','TND','Cortland','Cortland','IL'),('US','TNE','Tavernier','Tavernier','FL'),('US','TNF','Tenafly','Tenafly','NJ'),('US','TNG','Trion','Trion','GA'),('US','TNH','Huron','Huron','TN'),('US','TNI','Tunica','Tunica','MS'),('US','TNJ','Constantine','Constantine','MI'),('US','TNK','Tununak','Tununak','AK'),('US','TNL','Tinley Park','Tinley Park','IL'),('US','TNM','Turner','Turner','ME'),('US','TNN','Thornton','Thornton','CA'),('US','TNO','Powell','Powell','TN'),('US','TNP','Twentynine Palms','Twentynine Palms','CA'),('US','TNR','Trenton','Trenton','CA'),('US','TNS','Taunton','Taunton','MA'),('US','TNU','Newton','Newton','IA'),('US','TNV','Triangle','Triangle','VA'),('US','TNW','Tarrant','Tarrant','AL'),('US','TNX','Trenton','Trenton','OH'),('US','TNY','Anthony','Anthony','NM'),('US','TOA','Torrance','Torrance','CA'),('US','TOB','Tomball','Tomball','TX'),('US','TOC','Toccoa','Toccoa','GA'),('US','TOD','Toronto','Toronto','OH'),('US','TOG','Togiak Village','Togiak Village','AK'),('US','TOH','Tonopah','Tonopah','AZ'),('US','TOI','Troy','Troy','AL'),('US','TOK','Tonkawa','Tonkawa','OK'),('US','TOL','Toledo','Toledo','OH'),('US','TON','Sutton','Sutton','MA'),('US','TOO','Tooele','Tooele','UT'),('US','TOP','Topeka','Topeka','KS'),('US','TOR','Torrington','Torrington','WY'),('US','TOS','Thonotosassa','Thonotosassa','FL'),('US','TOT','Totowa','Totowa','NJ'),('US','TOV','Ottoville','Ottoville','OH'),('US','TOW','Towanda','Towanda','PA'),('US','TOX','Tremont','Tremont','PA'),('US','TOY','Troy','Troy','ME'),('US','TPA','Tampa','Tampa','FL'),('US','TPE','Tempe','Tempe','AZ'),('US','TPH','Tonopah','Tonopah','NV'),('US','TPI','Tellico Plains','Tellico Plains','TN'),('US','TPK','Topeka','Topeka','IN'),('US','TPL','Temple','Temple','TX'),('US','TPM','Tompkinsville','Tompkinsville','KY'),('US','TPN','Stapleton','Stapleton','NE'),('US','TPO','Tanalian Point','Tanalian Point','AK'),('US','TPP','Toppenish','Toppenish','WA'),('US','TPR','West Peoria','West Peoria','IL'),('US','TPS','Thompson','Thompson','OH'),('US','TPT','Tipton','Tipton','CA'),('US','TPV','Tiptonville','Tiptonville','TN'),('US','TPW','Thompsontown','Thompsontown','PA'),('US','TQD','Toledo','Toledo','IL'),('US','TQE','Theresa','Theresa','NY'),('US','TQH','Tar Heel','Tar Heel','NC'),('US','TQK','Topeka','Topeka','IL'),('US','TQL','Toluca Lake','Toluca Lake','CA'),('US','TQO','Tobaccoville','Tobaccoville','NC'),('US','TQY','Tye','Tye','TX'),('US','TRA','Trainer','Trainer','PA'),('US','TRB','Latrobe','Latrobe','CA'),('US','TRC','Tracy','Tracy','CA'),('US','TRD','Terre Hill','Terre Hill','PA'),('US','TRE','Theresa','Theresa','WI'),('US','TRF','Thorofare','Thorofare','NJ'),('US','TRG','Stirling','Stirling','NJ'),('US','TRH','Trona','Trona','CA'),('US','TRI','Bristol-Johnson City-Kingsport Apt','Bristol-Johnson City-Kingsport Apt','TN'),('US','TRJ','Three Rivers','Three Rivers','MA'),('US','TRK','Tamarac','Tamarac','FL'),('US','TRL','Terrell','Terrell','TX'),('US','TRM','Thermal','Thermal','CA'),('US','TRN','Trenton','Trenton','TN'),('US','TRO','Trotwood','Trotwood','OH'),('US','TRP','Tree Point','Tree Point','AK'),('US','TRR','Trout River','Trout River','NY'),('US','TRS','Struthers','Struthers','OH'),('US','TRT','Tremonton','Tremonton','UT'),('US','TRU','Trussville','Trussville','AL'),('US','TRV','Shorterville','Shorterville','AL'),('US','TRW','Winterville','Winterville','NC'),('US','TRX','Trenton','Trenton','MO'),('US','TRY','Troy','Troy','NY'),('US','TRZ','Troutman','Troutman','NC'),('US','TS2','Tekonsha','Tekonsha','MI'),('US','TS3','Teays','Teays','WV'),('US','TSA','Savannah','Savannah','TN'),('US','TSC','Tuscumbia','Tuscumbia','AL'),('US','TSD','Townshend','Townshend','VT'),('US','TSE','Otisville','Otisville','NY'),('US','TSG','Tanacross','Tanacross','AK'),('US','TSH','Topsham','Topsham','ME'),('US','TSI','Tishomingo','Tishomingo','OK'),('US','TSJ','Thomson','Thomson','GA'),('US','TSK','Thomaston','Thomaston','ME'),('US','TSL','Ten Sleep','Ten Sleep','WY'),('US','TSM','Taos','Taos','NM'),('US','TSO','Lost Hills','Lost Hills','CA'),('US','TSP','Tehachapi','Tehachapi','CA'),('US','TSS','Curtiss','Curtiss','WI'),('US','TST','Stennis Space Center','Stennis Space Center','MS'),('US','TSU','Treasure Island/Los Angeles','Treasure Island/Los Angeles','CA'),('US','TSV','Thiensville','Thiensville','WI'),('US','TSW','Pittstown','Pittstown','NY'),('US','TSZ','Bronston','Bronston','KY'),('US','TT2','Tipton','Tipton','IA'),('US','TT3','Tilton','Tilton','IL'),('US','TT4','Templeton','Templeton','IA'),('US','TTA','Latta','Latta','SC'),('US','TTB','Burnett','Burnett','TX'),('US','TTC','Coaltown','Coaltown','PA'),('US','TTD','Troutdale','Troutdale','OR'),('US','TTE','Tate','Tate','GA'),('US','TTF','Monett','Monett','KS'),('US','TTH','Smethport','Smethport','PA'),('US','TTI','Stateline','Stateline','NV'),('US','TTJ','Potterstown','Potterstown','NJ'),('US','TTK','Turtle Lake','Turtle Lake','WI'),('US','TTL','Whitehall','Whitehall','OH'),('US','TTM','Tarentum','Tarentum','PA'),('US','TTN','Trenton','Trenton','NJ'),('US','TTO','Britton','Britton','SD'),('US','TTP','Tipton','Tipton','PA'),('US','TTQ','Tylertown','Tylertown','MS'),('US','TTR','Metter','Metter','GA'),('US','TTU','Tatum','Tatum','SC'),('US','TTV','Tottenville, Staten Island','Tottenville, Staten Island','NY'),('US','TTW','Tullytown','Tullytown','PA'),('US','TTX','Teutopolis','Teutopolis','IL'),('US','TTY','Troy','Troy','TN'),('US','TTZ','Platteville','Platteville','WI'),('US','TUA','Truman','Truman','MN'),('US','TUC','Tucker','Tucker','GA'),('US','TUD','Stuarts Draft','Stuarts Draft','VA'),('US','TUE','Turnersville','Turnersville','NJ'),('US','TUG','Sturgis','Sturgis','KY'),('US','TUK','Tukwila','Tukwila','WA'),('US','TUL','Tulsa','Tulsa','OK'),('US','TUM','Timonium','Timonium','MD'),('US','TUN','Tustin','Tustin','CA'),('US','TUO','Turners Station','Turners Station','KY'),('US','TUP','Tupelo','Tupelo','MS'),('US','TUQ','Turkey','Turkey','NC'),('US','TUR','Turner','Turner','MT'),('US','TUS','Tuscon International Apt','Tuscon International Apt','AZ'),('US','TUT','Tutwiler','Tutwiler','MS'),('US','TUW','Tumwater','Tumwater','WA'),('US','TVC','Traverse City','Traverse City','MI'),('US','TVE','Thomasville','Thomasville','NC'),('US','TVF','Thief River Falls','Thief River Falls','MN'),('US','TVI','Thomasville','Thomasville','GA'),('US','TVL','South Lake Tahoe','South Lake Tahoe','CA'),('US','TVN','Woodburn','Woodburn','KY'),('US','TVO','Trevor','Trevor','WI'),('US','TVR','Trevorton','Trevorton','PA'),('US','TVS','Trevose','Trevose','PA'),('US','TVY','Traver','Traver','CA'),('US','TWA','Twin Hills','Twin Hills','AK'),('US','TWB','Townsend','Townsend','MA'),('US','TWC','Tower City','Tower City','PA'),('US','TWD','Pt Townsend','Pt Townsend','WA'),('US','TWE','Taylor','Taylor','AK'),('US','TWF','Twin Falls','Twin Falls','ID'),('US','TWG','Warrenton','Warrenton','TX'),('US','TWH','Wantagh','Wantagh','NY'),('US','TWI','Twisp','Twisp','WA'),('US','TWJ','Towaco','Towaco','NJ'),('US','TWL','Tualatin','Tualatin','OR'),('US','TWM','Stewart, McLeod','Stewart, McLeod','MN'),('US','TWN','Twin City','Twin City','GA'),('US','TWO','Wurtsboro','Wurtsboro','NY'),('US','TWQ','Winton','Winton','NC'),('US','TWR','Two Rivers','Two Rivers','WI'),('US','TWS','Towson','Towson','MD'),('US','TWT','Stewart','Stewart','AL'),('US','TWY','Tawas City','Tawas City','MI'),('US','TWZ','Tarrytown','Tarrytown','NY'),('US','TXA','Texas','Texas','MD'),('US','TXC','McAllen','McAllen','TX'),('US','TXD','Tuxedo','Tuxedo','MD'),('US','TXG','Gladewater','Gladewater','TX'),('US','TXH','Haslet','Haslet','TX'),('US','TXK','Texarkana','Texarkana','AR'),('US','TXN','Thomson','Thomson','IL'),('US','TXP','Troup','Troup','TX'),('US','TXR','Berkeley','Berkeley','MO'),('US','TXS','Tolar','Tolar','TX'),('US','TXT','Texas City','Texas City','TX'),('US','TXV','Toano','Toano','VA'),('US','TY2','Tracy','Tracy','MN'),('US','TYA','Ty Ty','Ty Ty','GA'),('US','TYB','Tyrone','Tyrone','NM'),('US','TYC','Taylorsville','Taylorsville','UT'),('US','TYE','Tyonek','Tyonek','AK'),('US','TYG','Troy Grove','Troy Grove','IL'),('US','TYH','Troy','Troy','OH'),('US','TYI','Troy','Troy','MS'),('US','TYJ','Tyro','Tyro','VA'),('US','TYK','Trinity Park','Trinity Park','NC'),('US','TYL','Tyler','Tyler','AL'),('US','TYM','Troy','Troy','MI'),('US','TYN','Taylorsville','Taylorsville','NC'),('US','TYO','Troy','Troy','VA'),('US','TYP','Taylor','Taylor','PA'),('US','TYQ','Taylors','Taylors','SC'),('US','TYR','Tyler','Tyler','TX'),('US','TYS','Knoxville','Knoxville','TN'),('US','TYT','Taylor','Taylor','TX'),('US','TYU','Troy','Troy','MO'),('US','TYV','Taylorsville','Taylorsville','MS'),('US','TYW','Terrytown','Terrytown','LA'),('US','TYX','Troy','Troy','NC'),('US','TYY','East Troy','East Troy','WI'),('US','TYZ','Taylor','Taylor','AZ'),('US','TZE','Trent','Trent','SD'),('US','TZR','Tarzana','Tarzana','CA'),('US','TZW','Tazewell','Tazewell','TN'),('US','TZZ','Tecumseh','Tecumseh','MI'),('US','UAA','Unalaska','Unalaska','AK'),('US','UAB','Abbeville','Abbeville','LA'),('US','UAC','Bristol','Bristol','PA'),('US','UAD','Albemarle','Albemarle','NC'),('US','UAE','Aberdeen','Aberdeen','NC'),('US','UAF','Abernathy','Abernathy','TX'),('US','UAG','Ackerman','Ackerman','MS'),('US','UAH','Acton','Acton','MA'),('US','UAI','Cleveland','Cleveland','TN'),('US','UAJ','Adams Run','Adams Run','SC'),('US','UAK','Carlstadt','Carlstadt','NJ'),('US','UAL','Sumrall, Lamar','Sumrall, Lamar','MS'),('US','UAM','Adamsville','Adamsville','TN'),('US','UAN','Adams','Adams','MA'),('US','UAO','Adrian','Adrian','OR'),('US','UAP','Addison','Addison','IL'),('US','UAR','Advance','Advance','NC'),('US','UAS','Addyston','Addyston','OH'),('US','UAT','Adams','Adams','OR'),('US','UAU','Cookeville','Cookeville','TN'),('US','UAX','Agoura','Agoura','CA'),('US','UAY','Algiers','Algiers','LA'),('US','UAZ','Allendale','Allendale','NJ'),('US','UBA','Albany','Albany','OH'),('US','UBB','Alamo','Alamo','CA'),('US','UBC','Alsip','Alsip','IL'),('US','UBD','Altamahaw','Altamahaw','NC'),('US','UBE','Albany','Albany','TX'),('US','UBF','Ambridge','Ambridge','PA'),('US','UBG','Amana','Amana','IA'),('US','UBH','Amite','Amite','LA'),('US','UBI','Amherst','Amherst','NH'),('US','UBJ','Algona','Algona','WA'),('US','UBK','Andersonville','Andersonville','GA'),('US','UBL','Urbandale','Urbandale','IA'),('US','UBM','Anthony','Anthony','TX'),('US','UBN','Antigo','Antigo','WI'),('US','UBO','Andrews','Andrews','TX'),('US','UBP','Allegheny','Allegheny','PA'),('US','UBQ','Columbia Heights','Columbia Heights','MN'),('US','UBR','Aspers','Aspers','PA'),('US','UBS','Columbus','Columbus','MS'),('US','UBT','Brookline','Brookline','NH'),('US','UBU','Belleville','Belleville','NJ'),('US','UBV','Blythewood','Blythewood','SC'),('US','UBZ','Bulville','Bulville','NY'),('US','UCA','Utica','Utica','NY'),('US','UCC','Yucca Flat','Yucca Flat','NV'),('US','UCE','Eunice','Eunice','LA'),('US','UCG','Union City','Union City','GA'),('US','UCJ','Union City','Union City','NJ'),('US','UCK','Chubbuck','Chubbuck','ID'),('US','UCO','Unicoi','Unicoi','TN'),('US','UCR','Urbancrest','Urbancrest','OH'),('US','UCS','Union','Union','SC'),('US','UCT','Strum','Strum','WI'),('US','UCU','Columbus','Columbus','KS'),('US','UCY','Union City','Union City','TN'),('US','UDA','Saluda','Saluda','SC'),('US','UDC','Cumberland City','Cumberland City','TN'),('US','UDE','Burnside','Burnside','LA'),('US','UDL','Unadilla','Unadilla','GA'),('US','UDS','Dundas','Dundas','MN'),('US','UDY','Upper Darby','Upper Darby','PA'),('US','UEI','Usibelli','Usibelli','AK'),('US','UEL','Bunnell','Bunnell','FL'),('US','UES','Waukesha','Waukesha','WI'),('US','UET','Calumet','Calumet','OK'),('US','UFA','Bellwood','Bellwood','IL'),('US','UFB','Church Hill','Church Hill','MO'),('US','UFC','Chillicothe','Chillicothe','MO'),('US','UFD','Crandon Lakes','Crandon Lakes','NJ'),('US','UFF','Coram','Coram','NY'),('US','UFG','Chesapeake','Chesapeake','VA'),('US','UFH','Carrizozo','Carrizozo','NM'),('US','UFI','Carlisle','Carlisle','PA'),('US','UFJ','Cambridge Springs','Cambridge Springs','PA'),('US','UFK','Cartersville','Cartersville','GA'),('US','UFL','Buffalo','Buffalo','MN'),('US','UFO','Downers Grove','Downers Grove','IL'),('US','UFP','Dillwyn','Dillwyn','VA'),('US','UFR','Elmsford','Elmsford','NY'),('US','UFS','Eagan','Eagan','MN'),('US','UFT','East Greenville','East Greenville','PA'),('US','UFU','East Greenwich','East Greenwich','RI'),('US','UFX','Englishtown','Englishtown','NJ'),('US','UGA','Sugar Valley','Sugar Valley','GA'),('US','UGC','Sugar Creek','Sugar Creek','OH'),('US','UGI','Uganik','Uganik','AK'),('US','UGL','Sugar Loaf','Sugar Loaf','NY'),('US','UGN','Waukegan','Waukegan','IL'),('US','UGO','Mount Gilead','Mount Gilead','OH'),('US','UGR','Union Grove','Union Grove','WI'),('US','UGS','Ugashik','Ugashik','AK'),('US','UGT','Hugoton','Hugoton','KS'),('US','UGU','Saugus','Saugus','CA'),('US','UHD','Spruce Head','Spruce Head','ME'),('US','UHI','Unity','Unity','ME'),('US','UHL','Buhler','Buhler','KS'),('US','UHV','Uhrichsville','Uhrichsville','OH'),('US','UIE','Burien','Burien','WA'),('US','UIL','Quillayute','Quillayute','WA'),('US','UIN','Quincy','Quincy','IL'),('US','UIO','Union, Monroe','Union, Monroe','WV'),('US','UIS','St Louis','St Louis','CA'),('US','UIZ','Utica','Utica','MI'),('US','UJA','Franklin','Franklin','TN'),('US','UJB','Flat River','Flat River','MO'),('US','UJD','Folcroft','Folcroft','PA'),('US','UJF','Fort Gillem','Fort Gillem','GA'),('US','UJG','Gibraltar','Gibraltar','PA'),('US','UJH','Grenada','Grenada','MS'),('US','UJI','Geneva','Geneva','OH'),('US','UJK','Greensburg','Greensburg','PA'),('US','UJL','Hazard','Hazard','KY'),('US','UJM','Hicksville','Hicksville','NY'),('US','UJN','Hanahan','Hanahan','SC'),('US','UJO','Hillside','Hillside','IL'),('US','UJP','Hanson','Hanson','MA'),('US','UJQ','Holyoke','Holyoke','MA'),('US','UJS','Hampton','Hampton','SC'),('US','UJT','Hightstown','Hightstown','NJ'),('US','UJV','Jamaica/Queens/New York','Jamaica/Queens/New York','NY'),('US','UJX','Kinnelon','Kinnelon','NJ'),('US','UJY','La Salle','La Salle','IL'),('US','UJZ','Leesville','Leesville','SC'),('US','UKI','Ukiah','Ukiah','CA'),('US','UKJ','Simpson','Simpson','PA'),('US','UKN','Waukon','Waukon','IA'),('US','UKT','Quakertown','Quakertown','PA'),('US','ULA','Peninsula','Peninsula','OH'),('US','ULG','Luling','Luling','TX'),('US','ULH','Ladysmith','Ladysmith','VA'),('US','ULI','Sullivan','Sullivan','IL'),('US','ULL','Hull','Hull','IA'),('US','ULM','New Ulm','New Ulm','MN'),('US','ULO','Bunola','Bunola','PA'),('US','ULT','Sultana','Sultana','CA'),('US','ULU','Lindsay','Lindsay','TX'),('US','ULV','Sullivan','Sullivan','NH'),('US','ULW','Lake Worth','Lake Worth','TX'),('US','UMA','Umatilla','Umatilla','OR'),('US','UMB','Umnak Island','Umnak Island','AK'),('US','UMC','Cumberland','Cumberland','IN'),('US','UMD','Summerland','Summerland','CA'),('US','UME','Summerfield','Summerfield','NC'),('US','UMI','Columbiana','Columbiana','AL'),('US','UML','Umatilla','Umatilla','FL'),('US','UMM','Summit','Summit','AK'),('US','UMN','Sumner','Sumner','TX'),('US','UMR','Summerton','Summerton','SC'),('US','UMS','Drums','Drums','PA'),('US','UMT','Umiat','Umiat','AK'),('US','UMU','Mustang','Mustang','OK'),('US','UMY','Maynard','Maynard','MA'),('US','UNA','Union Beach','Union Beach','NJ'),('US','UNB','Union Bridge','Union Bridge','MD'),('US','UNC','Union City','Union City','CA'),('US','UND','Underwood','Underwood','ND'),('US','UNE','Muncie','Muncie','KS'),('US','UNF','Munfordville','Munfordville','KY'),('US','UNG','Thousand Palms','Thousand Palms','CA'),('US','UNI','Union','Union','PA'),('US','UNK','Unalakleet','Unalakleet','AK'),('US','UNL','Dunlap','Dunlap','TN'),('US','UNN','Union City','Union City','PA'),('US','UNO','Union City','Union City','IN'),('US','UNP','Sunnyslope','Sunnyslope','ID'),('US','UNR','Sunray','Sunray','TX'),('US','UNT','Staunton','Staunton','IL'),('US','UNU','Juneau','Juneau','WI'),('US','UNV','Munnsville','Munnsville','NY'),('US','UNY','Sun City','Sun City','KS'),('US','UNZ','Union','Union','IL'),('US','UOA','Aurora','Aurora','UT'),('US','UOD','Uniondale','Uniondale','NY'),('US','UOF','Cut Off','Cut Off','LA'),('US','UOI','Union, Franklin','Union, Franklin','MO'),('US','UOL','Sunol','Sunol','CA'),('US','UON','Union','Union','NJ'),('US','UOR','Aurora','Aurora','SD'),('US','UOS','Sewanee','Sewanee','TN'),('US','UOX','Oxford','Oxford','MS'),('US','UPA','Mount Pleasant, Cabarrus','Mount Pleasant, Cabarrus','NC'),('US','UPE','Upper Sandusky','Upper Sandusky','OH'),('US','UPK','University Park','University Park','IL'),('US','UPL','Upland','Upland','IN'),('US','UPM','Upper Marlboro','Upper Marlboro','MD'),('US','UPP','Upolu Point','Upolu Point','HI'),('US','UPR','Superior','Superior','NE'),('US','UPT','Upton','Upton','MA'),('US','UQA','Le Suer','Le Suer','MN'),('US','UQE','Queen','Queen','AK'),('US','UQF','La Porte','La Porte','TX'),('US','UQG','Le Roy','Le Roy','NY'),('US','UQH','Lyman','Lyman','SC'),('US','UQJ','Mamaroneck','Mamaroneck','NY'),('US','UQL','Mableton','Mableton','GA'),('US','UQN','Medford','Medford','NJ'),('US','UQO','Maiden','Maiden','NC'),('US','UQS','Mt Holly','Mt Holly','SC'),('US','UQT','Middletown','Middletown','PA'),('US','UQV','Mt Jackson','Mt Jackson','VA'),('US','UQX','McKenzie','McKenzie','TN'),('US','UQY','Milesburg','Milesburg','PA'),('US','UQZ','Milan','Milan','MI'),('US','URA','Durant','Durant','MS'),('US','URB','Urbana','Urbana','IL'),('US','URC','Urbana','Urbana','IA'),('US','URE','Laurel','Laurel','DE'),('US','URH','Uriah','Uriah','AL'),('US','URI','Missouri City','Missouri City','MO'),('US','URL','Summerdale','Summerdale','AL'),('US','URN','Urania','Urania','LA'),('US','URO','Urbana','Urbana','OH'),('US','URR','Port Murray','Port Murray','NJ'),('US','URT','Duart','Duart','NC'),('US','URW','Washburn','Washburn','TN'),('US','URY','Middlebury Center','Middlebury Center','PA'),('US','USA','Bourbonnais','Bourbonnais','IL'),('US','USB','Curtis Bay, Baltimore','Curtis Bay, Baltimore','MD'),('US','USC','Union South Carolina','Union South Carolina','SC'),('US','USE','Custer','Custer','SD'),('US','USG','Muskego','Muskego','WI'),('US','USH','Muscle Shoals','Muscle Shoals','AL'),('US','USI','Greenview','Greenview','IL'),('US','USJ','Sabinal','Sabinal','TX'),('US','USK','Usk','Usk','WA'),('US','USL','Russell','Russell','MA'),('US','USO','Hurtsboro','Hurtsboro','AL'),('US','USP','Union Springs','Union Springs','AL'),('US','USR','Custar','Custar','OH'),('US','USS','Russia','Russia','OH'),('US','UST','St Augustine','St Augustine','FL'),('US','USY','Ulysses','Ulysses','KS'),('US','UT2','Uniontown','Uniontown','KY'),('US','UTA','Tchula','Tchula','MS'),('US','UTC','Cutchogue','Cutchogue','NY'),('US','UTE','Custer','Custer','WI'),('US','UTG','Huntington','Huntington','TN'),('US','UTL','Canutillo','Canutillo','TX'),('US','UTN','Uniontown','Uniontown','PA'),('US','UTO','Utopia Creek','Utopia Creek','AK'),('US','UTQ','Utica','Utica','IL'),('US','UTR','Custer','Custer','WA'),('US','UTT','Huntington','Huntington','UT'),('US','UTV','Mountville','Mountville','SC'),('US','UUK','Kuparuk','Kuparuk','AK'),('US','UUM','Abington','Abington','MA'),('US','UUN','Auburn','Auburn','IL'),('US','UVA','Uvalde','Uvalde','TX'),('US','UVB','Barnsdall','Barnsdall','OK'),('US','UVC','Universal City','Universal City','CA'),('US','UVE','Bullville','Bullville','NY'),('US','UVI','Russellville','Russellville','IN'),('US','UVL','Uncasville','Uncasville','CT'),('US','UVN','Luverne','Luverne','MN'),('US','UWA','Ware','Ware','MA'),('US','UWC','Uwchland','Uwchland','PA'),('US','UWH','South Windham','South Windham','CT'),('US','UXB','Moosic','Moosic','PA'),('US','UXE','Mason','Mason','OH'),('US','UXG','Montgomeryville','Montgomeryville','PA'),('US','UXI','New Bremen','New Bremen','OH'),('US','UXJ','North Canton','North Canton','OH'),('US','UXK','Neenah','Neenah','WI'),('US','UXL','New Holland','New Holland','PA'),('US','UXN','Norcross','Norcross','GA'),('US','UXO','New Rochelle','New Rochelle','NY'),('US','UXQ','Norristown','Norristown','PA'),('US','UXR','Oakdale','Oakdale','PA'),('US','UXS','Oakmont','Oakmont','PA'),('US','UXT','Paw Paw','Paw Paw','WV'),('US','UXV','Pleasantville','Pleasantville','NJ'),('US','UXX','Uxbridge','Uxbridge','MA'),('US','UXY','Plymouth','Plymouth','MI'),('US','UXZ','Pt Chester','Pt Chester','NY'),('US','UYB','Pulaski','Pulaski','VA'),('US','UYD','Bayside','Bayside','WI'),('US','UYE','Ridgefield','Ridgefield','NJ'),('US','UYG','Raymond','Raymond','MS'),('US','UYH','Royersford','Royersford','PA'),('US','UYI','Rutherford','Rutherford','NJ'),('US','UYJ','Steubenville','Steubenville','OH'),('US','UYK','Secaucus','Secaucus','NJ'),('US','UYL','Spring City','Spring City','PA'),('US','UYN','Slidell','Slidell','LA'),('US','UYO','Sodus','Sodus','NY'),('US','UYP','Seneca','Seneca','NY'),('US','UYQ','Salem','Salem','VA'),('US','UYR','Santa Fe Springs','Santa Fe Springs','CA'),('US','UYS','Shenandoah','Shenandoah','GA'),('US','UYU','Staten Island/New York','Staten Island/New York','NY'),('US','UYV','Smithfield','Smithfield','OH'),('US','UYX','Summit','Summit','NJ'),('US','UYY','Straughn','Straughn','IN'),('US','UYZ','Skyland','Skyland','NC'),('US','UZA','Stanley','Stanley','NC'),('US','UZB','Somerville','Somerville','MA'),('US','UZC','Summerville','Summerville','SC'),('US','UZD','Tarboro','Tarboro','NC'),('US','UZE','Tipp City','Tipp City','OH'),('US','UZF','Tonawanda','Tonawanda','NY'),('US','UZG','Troutville','Troutville','VA'),('US','UZI','Wood-Ridge','Wood-Ridge','NJ'),('US','UZJ','Webster','Webster','NY'),('US','UZK','Waterford','Waterford','NY'),('US','UZL','West Nyack','West Nyack','NY'),('US','UZM','Wrens','Wrens','GA'),('US','UZN','Williston','Williston','SC'),('US','UZO','Warwick','Warwick','RI'),('US','VAA','Bealeton','Bealeton','VA'),('US','VAB','Virginia Beach','Virginia Beach','VA'),('US','VAC','Vail','Vail','CO'),('US','VAD','Valders','Valders','WI'),('US','VAE','Valley','Valley','GA'),('US','VAF','Floyd','Floyd','VA'),('US','VAI','Vailsgate','Vailsgate','NY'),('US','VAK','Chevak','Chevak','AK'),('US','VAL','Valdese','Valdese','NC'),('US','VAM','Van Buren','Van Buren','IN'),('US','VAN','Vancouver','Vancouver','WA'),('US','VAO','Avon','Avon','IN'),('US','VAR','Vanar','Vanar','AZ'),('US','VAS','Vassar','Vassar','MI'),('US','VAT','Valatie','Valatie','NY'),('US','VAW','Willston','Willston','VA'),('US','VAY','Valley','Valley','AL'),('US','VBL','Byesville','Byesville','OH'),('US','VBM','Van Buren Township','Van Buren Township','MI'),('US','VBN','Van Buren','Van Buren','ME'),('US','VBO','Vanceboro','Vanceboro','ME'),('US','VBR','Barre','Barre','VT'),('US','VBS','Bluefield','Bluefield','VA'),('US','VBU','Van Buren','Van Buren','AR'),('US','VBY','Beverly','Beverly','WA'),('US','VCA','Vernon','Vernon','CA'),('US','VCB','Columbus','Columbus','TX'),('US','VCC','Cave Creek','Cave Creek','AZ'),('US','VCE','Vance','Vance','AL'),('US','VCI','Venice','Venice','CA'),('US','VCJ','Valley Cottage','Valley Cottage','NY'),('US','VCK','Vickery','Vickery','TX'),('US','VCN','Carlinville','Carlinville','IL'),('US','VCO','Valley City','Valley City','OH'),('US','VCR','Beavercreek','Beavercreek','OH'),('US','VCT','Victoria','Victoria','TX'),('US','VCU','Verdugo City','Verdugo City','CA'),('US','VCV','Victorville','Victorville','CA'),('US','VCW','Victor','Victor','MT'),('US','VCX','Vacaville','Vacaville','CA'),('US','VDA','Columbus','Columbus','MI'),('US','VDC','Providence, Webster','Providence, Webster','KY'),('US','VDD','Vandalia','Vandalia','NY'),('US','VDH','Vandalia','Vandalia','OH'),('US','VDI','Vidalia','Vidalia','GA'),('US','VDL','Vidalia','Vidalia','LA'),('US','VDO','Vidor','Vidor','TX'),('US','VDW','Vardaman','Vardaman','MS'),('US','VDZ','Valdez','Valdez','AK'),('US','VE8','Colville','Colville','WA'),('US','VEA','Verona','Verona','MO'),('US','VED','Vineyard','Vineyard','UT'),('US','VEE','Venetie','Venetie','AK'),('US','VEG','Vega','Vega','TX'),('US','VEH','Vestavia Hills','Vestavia Hills','AL'),('US','VEI','Verdi','Verdi','NV'),('US','VEL','Vernal','Vernal','UT'),('US','VEM','Vermillion','Vermillion','SD'),('US','VEN','Vernon','Vernon','AL'),('US','VEO','Verona','Verona','PA'),('US','VER','Verona','Verona','NJ'),('US','VES','Vesper','Vesper','WI'),('US','VET','Silverton','Silverton','OH'),('US','VEW','Westwood','Westwood','MA'),('US','VEX','Tioga','Tioga','ND'),('US','VEY','Harvey','Harvey','ND'),('US','VFG','Valley Forge','Valley Forge','PA'),('US','VGE','Savage','Savage','MT'),('US','VGF','Vandergrift','Vandergrift','PA'),('US','VGI','Virginia','Virginia','MN'),('US','VGN','Western Grove','Western Grove','AR'),('US','VGS','Vanceburg','Vanceburg','KY'),('US','VHF','Vint Hill Farms','Vint Hill Farms','VA'),('US','VHI','Vernon Hills','Vernon Hills','IL'),('US','VHJ','Voorhees','Voorhees','NJ'),('US','VHL','Hartsville','Hartsville','TN'),('US','VHN','Van Horn','Van Horn','TX'),('US','VHO','Vienna','Vienna','OH'),('US','VHW','Woodhaven','Woodhaven','NY'),('US','VHX','Vauxhall','Vauxhall','NJ'),('US','VIA','Vinita','Vinita','OK'),('US','VIC','Victor','Victor','NY'),('US','VIE','Vienna','Vienna','IL'),('US','VIG','Vienna','Vienna','GA'),('US','VIH','Vichy','Vichy','MO'),('US','VII','La Vista','La Vista','NE'),('US','VIJ','Moravia','Moravia','NY'),('US','VIK','Kavik','Kavik','AK'),('US','VIL','Lake Villa','Lake Villa','IL'),('US','VIN','Vineland','Vineland','NJ'),('US','VIO','Viola','Viola','TX'),('US','VIR','Viroqua','Viroqua','WI'),('US','VIS','Visalia','Visalia','CA'),('US','VIT','Victor','Victor','CO'),('US','VIV','Vienna','Vienna','VA'),('US','VJI','Abingdon','Abingdon','VA'),('US','VJY','Jay','Jay','VT'),('US','VKS','Vicksburg','Vicksburg','MS'),('US','VKV','Watkinsville','Watkinsville','GA'),('US','VKW','West Kavik','West Kavik','AK'),('US','VLA','Vandalia','Vandalia','IL'),('US','VLB','Centerville','Centerville','MS'),('US','VLC','Valencia','Valencia','CA'),('US','VLD','Valdosta','Valdosta','GA'),('US','VLE','Valle','Valle','AZ'),('US','VLG','Volga','Volga','SD'),('US','VLH','Walhalla','Walhalla','ND'),('US','VLL','Waller','Waller','TX'),('US','VLO','Vallejo','Vallejo','CA'),('US','VLQ','Valrico','Valrico','FL'),('US','VLR','Villa Rica','Villa Rica','GA'),('US','VLS','Van Alstyne','Van Alstyne','TX'),('US','VLY','Valley','Valley','NE'),('US','VMB','Medicine Bow','Medicine Bow','WY'),('US','VML','Monroeville','Monroeville','PA'),('US','VMT','Vinemont','Vinemont','AL'),('US','VMV','Mountain Grove','Mountain Grove','MO'),('US','VMZ','Monte Vista','Monte Vista','CO'),('US','VN2','Vaughn','Vaughn','NM'),('US','VNA','Verona','Verona','MS'),('US','VNC','Venice','Venice','FL'),('US','VND','Cleveland','Cleveland','OK'),('US','VNE','Mulvane','Mulvane','KS'),('US','VNL','Vandalia','Vandalia','MO'),('US','VNN','Vernon','Vernon','NY'),('US','VNO','Vernon, Camden','Vernon, Camden','NJ'),('US','VNQ','Vale','Vale','NC'),('US','VNS','Devens','Devens','MA'),('US','VNT','Ventura','Ventura','CA'),('US','VNW','Van Wert','Van Wert','OH'),('US','VNY','Van Nuys','Van Nuys','CA'),('US','VOA','Viola','Viola','ID'),('US','VOK','Camp Douglas','Camp Douglas','WI'),('US','VOL','Viola','Viola','VA'),('US','VON','Avon','Avon','IL'),('US','VOO','Voorheesville','Voorheesville','NY'),('US','VOR','Victor','Victor','ID'),('US','VOY','Vogleyville','Vogleyville','PA'),('US','VPA','Valley Park','Valley Park','MO'),('US','VPD','Paradise','Paradise','TX'),('US','VPH','Phelan','Phelan','CA'),('US','VPK','Villa Park','Villa Park','CA'),('US','VPO','Valparaiso','Valparaiso','NE'),('US','VPR','Villa Park','Villa Park','IL'),('US','VPS','Valparaiso','Valparaiso','FL'),('US','VPT','Ville Platte','Ville Platte','LA'),('US','VPZ','Valparaiso','Valparaiso','IN'),('US','VQN','Vonore','Vonore','TN'),('US','VRA','Verona','Verona','WI'),('US','VRB','Vero Beach','Vero Beach','FL'),('US','VRI','Vernalis','Vernalis','CA'),('US','VRN','Vernon','Vernon','CT'),('US','VRO','Verona','Verona','KY'),('US','VRS','Versailles','Versailles','MO'),('US','VRT','Vernon','Vernon','TX'),('US','VRU','Viburnum','Viburnum','MO'),('US','VRV','Verona','Verona','VA'),('US','VSA','Navasota','Navasota','TX'),('US','VSB','Vassalboro','Vassalboro','ME'),('US','VSD','Riverside','Riverside','IA'),('US','VSF','Springfield','Springfield','VT'),('US','VSH','Vadnais Heights','Vadnais Heights','MN'),('US','VSI','Versailles','Versailles','CT'),('US','VSJ','Springfield, Calhoun','Springfield, Calhoun','MI'),('US','VSN','Winston','Winston','GA'),('US','VSQ','Stapleton','Stapleton','AL'),('US','VSR','Valley Stream','Valley Stream','NY'),('US','VSS','Versailles','Versailles','KY'),('US','VST','Vansant','Vansant','VA'),('US','VSW','Stillwater','Stillwater','NJ'),('US','VSZ','Stafford','Stafford','KS'),('US','VTA','Volta','Volta','CA'),('US','VTB','Vestaburg','Vestaburg','MI'),('US','VTD','Wilder','Wilder','VT'),('US','VTI','Vista','Vista','CA'),('US','VTL','Waterloo','Waterloo','AL'),('US','VTN','Valentine','Valentine','NE'),('US','VTO','Washington','Washington','IA'),('US','VTR','Woodson Terrace/St Louis','Woodson Terrace/St Louis','MO'),('US','VTW','Vinton','Vinton','IA'),('US','VTY','Victory City','Victory City','TX'),('US','VVK','Staples','Staples','MN'),('US','VVL','Summitville','Summitville','IN'),('US','VVN','Vivian','Vivian','LA'),('US','VVT','Eastpoint','Eastpoint','FL'),('US','VVV','Saukville','Saukville','WI'),('US','VVW','Valley View','Valley View','PA'),('US','VWB','West Kennebunk','West Kennebunk','ME'),('US','VWC','Van Wyck','Van Wyck','SC'),('US','VWD','Riverwoods','Riverwoods','IL'),('US','VWH','Worthington','Worthington','PA'),('US','VWL','Waterville','Waterville','KS'),('US','VWR','Warren','Warren','OR'),('US','VWT','Van Wert','Van Wert','IA'),('US','VWV','Vienna','Vienna','WV'),('US','VXS','Walburg','Walburg','TX'),('US','VYH','Vineyard Haven','Vineyard Haven','MA'),('US','VYL','Bentleyville','Bentleyville','PA'),('US','VYM','Valmy','Valmy','NV'),('US','VYS','Peru','Peru','IL'),('US','VYV','Mill Valley','Mill Valley','CA'),('US','VYW','Spring Valley','Spring Valley','WI'),('US','VYX','Rixeyville','Rixeyville','VA'),('US','VYY','Valley City','Valley City','ND'),('US','WAA','Wales','Wales','AK'),('US','WAB','Washington','Washington','GA'),('US','WAC','Walnut Creek','Walnut Creek','CA'),('US','WAD','Waddington','Waddington','NY'),('US','WAE','Wardensville','Wardensville','WV'),('US','WAF','Watertown','Watertown','WI'),('US','WAG','Walnut Grove','Walnut Grove','MS'),('US','WAH','Wahpeton','Wahpeton','ND'),('US','WAI','Waitsfield','Waitsfield','VT'),('US','WAJ','Warren','Warren','RI'),('US','WAK','Wallkill','Wallkill','NY'),('US','WAL','Chincoteague','Chincoteague','VA'),('US','WAM','Warren','Warren','MI'),('US','WAN','Wanamingo','Wanamingo','MN'),('US','WAO','Wamego','Wamego','KS'),('US','WAP','Warsaw','Warsaw','IN'),('US','WAQ','Wagram','Wagram','NC'),('US','WAR','Warne','Warne','NC'),('US','WAS','Washington','Washington','DC'),('US','WAT','Waterbury','Waterbury','CT'),('US','WAU','Wauna','Wauna','OR'),('US','WAV','Waverly','Waverly','OH'),('US','WAW','Walworth','Walworth','WI'),('US','WAX','Waxahachie','Waxahachie','TX'),('US','WAY','Waynesburg','Waynesburg','PA'),('US','WAZ','Waynesville','Waynesville','MO'),('US','WB2','Wittenberg','Wittenberg','WI'),('US','WBA','Wabasso','Wabasso','MN'),('US','WBB','Stebbins','Stebbins','AK'),('US','WBC','West Branch','West Branch','MI'),('US','WBD','West Brookfield','West Brookfield','MA'),('US','WBE','Wilkes-Barre','Wilkes-Barre','PA'),('US','WBF','West Bloomfield','West Bloomfield','MI'),('US','WBG','Walbridge','Walbridge','OH'),('US','WBH','Wabash','Wabash','IN'),('US','WBJ','Woodburn','Woodburn','OR'),('US','WBK','Williamsburg','Williamsburg','KY'),('US','WBL','Walled Lake','Walled Lake','MI'),('US','WBM','West Boylston','West Boylston','MA'),('US','WBN','Woburn','Woburn','MA'),('US','WBO','West Burlington','West Burlington','IA'),('US','WBP','Wellsboro','Wellsboro','PA'),('US','WBQ','Beaver','Beaver','AK'),('US','WBR','Big Rapids','Big Rapids','MI'),('US','WBS','West Berlin','West Berlin','NJ'),('US','WBT','Wallace','Wallace','SC'),('US','WBU','Boulder','Boulder','CO'),('US','WBV','Waterbury','Waterbury','VT'),('US','WBW','West Bridgewater','West Bridgewater','MA'),('US','WBX','Woodbridge','Woodbridge','VA'),('US','WBY','Westbury','Westbury','NY'),('US','WC2','West Chop','West Chop','MA'),('US','WC3','Wesley Chapel','Wesley Chapel','FL'),('US','WC4','Wicomico Church','Wicomico Church','VA'),('US','WCA','West Carrollton','West Carrollton','OH'),('US','WCB','West Columbia','West Columbia','SC'),('US','WCC','Winchester Center','Winchester Center','CT'),('US','WCD','Winchendon','Winchendon','MA'),('US','WCE','West Creek','West Creek','NJ'),('US','WCF','West Chesterfield','West Chesterfield','MA'),('US','WCG','Washington Crossing','Washington Crossing','PA'),('US','WCH','Winchester','Winchester','NH'),('US','WCI','West Chicago','West Chicago','IL'),('US','WCJ','Weare','Weare','NH'),('US','WCK','West Conshohocken','West Conshohocken','PA'),('US','WCL','West Caldwell','West Caldwell','NJ'),('US','WCN','West Blocton','West Blocton','AL'),('US','WCO','Welcome','Welcome','NC'),('US','WCP','Wicker Park','Wicker Park','IL'),('US','WCQ','Washington Court House','Washington Court House','OH'),('US','WCR','Chandalar','Chandalar','AK'),('US','WCS','Winchester','Winchester','IN'),('US','WCT','West Chester','West Chester','PA'),('US','WCU','Wright City','Wright City','MO'),('US','WCV','Winchester','Winchester','TN'),('US','WCW','Lake Waccamaw','Lake Waccamaw','NC'),('US','WCX','West Coxsackie','West Coxsackie','NY'),('US','WCY','White City','White City','OR'),('US','WCZ','Wellington','Wellington','IL'),('US','WD2','West Dover','West Dover','VT'),('US','WD3','Weed','Weed','CA'),('US','WDA','Walden','Walden','NY'),('US','WDB','Deep Bay','Deep Bay','AK'),('US','WDC','Ward Cove','Ward Cove','AK'),('US','WDD','Wood Dale','Wood Dale','IL'),('US','WDE','Wendell','Wendell','ID'),('US','WDF','Womelsdorf','Womelsdorf','PA'),('US','WDG','Enid','Enid','OK'),('US','WDH','Wadsworth','Wadsworth','OH'),('US','WDI','Woodlawn','Woodlawn','IL'),('US','WDJ','Waldoboro','Waldoboro','ME'),('US','WDK','Woodstock','Woodstock','MD'),('US','WDM','Waldron','Waldron','MI'),('US','WDN','Waldron Island','Waldron Island','WA'),('US','WDO','Woodstown','Woodstown','NJ'),('US','WDP','West Deptford','West Deptford','NJ'),('US','WDQ','Woodland','Woodland','CA'),('US','WDR','Winder','Winder','GA'),('US','WDS','Woodstock','Woodstock','CT'),('US','WDT','Wadsworth','Wadsworth','TX'),('US','WDU','Woodbury, Nassau','Woodbury, Nassau','NY'),('US','WDV','Woodinville','Woodinville','WA'),('US','WDW','Wendover','Wendover','WY'),('US','WDX','Wendell','Wendell','NC'),('US','WDY','Woodbury','Woodbury','MN'),('US','WDZ','Woodside','Woodside','CA'),('US','WEA','Weatherford','Weatherford','TX'),('US','WEB','Webster','Webster','MA'),('US','WEC','Weber City','Weber City','VA'),('US','WED','West Hatfield','West Hatfield','MA'),('US','WEE','West Henrietta','West Henrietta','NY'),('US','WEF','Wellford','Wellford','SC'),('US','WEG','West Greenwich','West Greenwich','RI'),('US','WEH','Weatherly','Weatherly','PA'),('US','WEI','White Salmon','White Salmon','WA'),('US','WEJ','West Jordan','West Jordan','UT'),('US','WEK','White Lake','White Lake','MI'),('US','WEL','Wellesley','Wellesley','MA'),('US','WEM','West Des Moines','West Des Moines','IA'),('US','WEN','Warren','Warren','IL'),('US','WEO','Weldon','Weldon','NC'),('US','WEP','Westampton','Westampton','NJ'),('US','WEQ','West Allis','West Allis','WI'),('US','WER','Webberville','Webberville','MI'),('US','WES','Wellsburg','Wellsburg','WV'),('US','WET','Weirton','Weirton','WV'),('US','WEU','West Union','West Union','SC'),('US','WEV','Wytheville','Wytheville','VA'),('US','WEW','Warden','Warden','WA'),('US','WEX','Wellington','Wellington','KS'),('US','WEY','Weymouth','Weymouth','MA'),('US','WEZ','West Elizabeth','West Elizabeth','PA'),('US','WF2','Westfield','Westfield','WI'),('US','WFA','Wheaton','Wheaton','MD'),('US','WFD','Wallingford','Wallingford','CT'),('US','WFE','Wakefield','Wakefield','MI'),('US','WFF','Westcliffe','Westcliffe','CO'),('US','WFG','West Fargo','West Fargo','ND'),('US','WFH','Wando','Wando','SC'),('US','WFI','Westfield','Westfield','IN'),('US','WFJ','Waterford Works','Waterford Works','NJ'),('US','WFK','Frenchville','Frenchville','ME'),('US','WFL','Westfield','Westfield','NC'),('US','WFM','Waldorf','Waldorf','MD'),('US','WFN','Winnfield','Winnfield','LA'),('US','WFO','West Foreland','West Foreland',''),('US','WFP','Williamsport','Williamsport','MD'),('US','WFQ','Walford','Walford','IA'),('US','WFR','Westford','Westford','MA'),('US','WFS','Wappingers Falls','Wappingers Falls','NY'),('US','WFT','Warrenton','Warrenton','NC'),('US','WFW','Wheatland','Wheatland','WI'),('US','WFX','Waverly','Waverly','MD'),('US','WFY','Waverly','Waverly','NY'),('US','WFZ','Winchester','Winchester','OH'),('US','WGA','Waldo','Waldo','WI'),('US','WGB','Winnebago, Faribault','Winnebago, Faribault','MN'),('US','WGE','Wagoner','Wagoner','OK'),('US','WGG','Wiggins','Wiggins','CO'),('US','WGH','Worthington','Worthington','OH'),('US','WGI','Washington','Washington','IL'),('US','WGL','Wheatland','Wheatland','PA'),('US','WGM','West Groton','West Groton','MA'),('US','WGN','Wellington','Wellington','OH'),('US','WGO','Winchester','Winchester','VA'),('US','WGP','Wyomissing','Wyomissing','PA'),('US','WGQ','Weyers Cave','Weyers Cave','VA'),('US','WGR','Walnut Grove','Walnut Grove','MO'),('US','WGS','Waynesboro','Waynesboro','MS'),('US','WGT','Washington','Washington','UT'),('US','WGW','Wagontown','Wagontown','PA'),('US','WGX','Wingate','Wingate','TX'),('US','WGY','Williamsburg/Brooklyn/New York','Williamsburg/Brooklyn/New York','NY'),('US','WGZ','Wrightstown','Wrightstown','NJ'),('US','WHA','West Hazleton','West Hazleton','PA'),('US','WHB','White Bluff','White Bluff','TN'),('US','WHC','West Haven','West Haven','CT'),('US','WHD','Hyder','Hyder','AK'),('US','WHE','Wheeling','Wheeling','IL'),('US','WHF','West Hartford','West Hartford','CT'),('US','WHG','Whiting','Whiting','IN'),('US','WHH','Warrensville Heights','Warrensville Heights','OH'),('US','WHI','Whippany','Whippany','NJ'),('US','WHJ','Walhalla','Walhalla','SC'),('US','WHK','Whitner','Whitner','KY'),('US','WHL','Whitlash','Whitlash','MT'),('US','WHM','Windham','Windham','OH'),('US','WHN','Whitehall','Whitehall','NY'),('US','WHO','Whitestone/Queens/New York','Whitestone/Queens/New York','NY'),('US','WHP','Westhope','Westhope','ND'),('US','WHQ','West Helena','West Helena','AR'),('US','WHR','Whittier','Whittier','CA'),('US','WHS','Whitetail','Whitetail','MT'),('US','WHT','Wharton','Wharton','TX'),('US','WHU','White House','White House','TN'),('US','WHV','Whitesville','Whitesville','WV'),('US','WHW','Whitehall','Whitehall','WI'),('US','WHX','Wheaton','Wheaton','IL'),('US','WHY','Whitehall','Whitehall','PA'),('US','WHZ','Ward Hill','Ward Hill','MA'),('US','WIA','Williams','Williams','TX'),('US','WIB','Willow Brook','Willow Brook','IL'),('US','WIC','Wickliffe','Wickliffe','OH'),('US','WID','Windber','Windber','PA'),('US','WIE','Winterport','Winterport','ME'),('US','WIF','Winfield','Winfield','AL'),('US','WIG','Winthrop','Winthrop','MN'),('US','WIH','Willapa','Willapa','WA'),('US','WII','Wilder','Wilder','KY'),('US','WIJ','Wilder','Wilder','ID'),('US','WIK','Wilkins','Wilkins','SC'),('US','WIL','Williston','Williston','VT'),('US','WIM','Wilton','Wilton','NY'),('US','WIN','Winchester','Winchester','KY'),('US','WIO','Wilton','Wilton','NH'),('US','WIP','Winter Park','Winter Park','CO'),('US','WIQ','Wilson','Wilson','AR'),('US','WIR','Willamette City','Willamette City','OR'),('US','WIS','Williamson','Williamson','NY'),('US','WIT','Williston','Williston','FL'),('US','WIU','Wimauma','Wimauma','FL'),('US','WIV','Windsor','Windsor','VT'),('US','WIW','Willow Wood','Willow Wood','OH'),('US','WIX','Wixom','Wixom','MI'),('US','WIY','Wainscott','Wainscott','NY'),('US','WIZ','Wissahickon','Wissahickon','PA'),('US','WJA','Wathena','Wathena','KS'),('US','WJF','Lancaster','Lancaster','CA'),('US','WJI','Whitlock','Whitlock','TN'),('US','WJJ','Winnsboro','Winnsboro','TX'),('US','WJK','Wakefield','Wakefield','NE'),('US','WJL','West Linn','West Linn','OR'),('US','WJM','West Jefferson, Madison','West Jefferson, Madison','OH'),('US','WJN','Winsted','Winsted','MN'),('US','WJO','Westmont','Westmont','IL'),('US','WJP','Walton Hills','Walton Hills','OH'),('US','WJQ','Weehawken','Weehawken','NJ'),('US','WJR','Weimar','Weimar','TX'),('US','WJS','Westside','Westside','IA'),('US','WJW','West Jefferson, Williams','West Jefferson, Williams','OH'),('US','WJX','Wilsonville','Wilsonville','OR'),('US','WJY','Warm Springs','Warm Springs','CA'),('US','WJZ','Watts','Watts','CA'),('US','WKA','Waseca','Waseca','MN'),('US','WKB','Wilkes Barre','Wilkes Barre','PA'),('US','WKC','Walkerton','Walkerton','IN'),('US','WKD','Wakefield','Wakefield','VA'),('US','WKE','Waukee','Waukee','IA'),('US','WKF','Wakefield','Wakefield','MA'),('US','WKG','Watkins Glen','Watkins Glen','NY'),('US','WKH','Windham','Windham','NH'),('US','WKI','Watkins','Watkins','MN'),('US','WKK','Aleknagik','Aleknagik','AK'),('US','WKL','Waikoloa','Waikoloa','HI'),('US','WKM','Wilkinsonville','Wilkinsonville','MA'),('US','WKN','Walkerton','Walkerton','VA'),('US','WKO','Weslaco','Weslaco','TX'),('US','WKR','Wake Forest','Wake Forest','NC'),('US','WKS','Weeks','Weeks','LA'),('US','WKT','Whitakers','Whitakers','NC'),('US','WKV','Wilkesville','Wilkesville','OH'),('US','WKW','Waunakee','Waunakee','WI'),('US','WKX','Weskan','Weskan','KS'),('US','WKY','Wickliffe','Wickliffe','KY'),('US','WKZ','West Covina','West Covina','CA'),('US','WL2','Wayland','Wayland','MA'),('US','WL3','West Liberty','West Liberty','IA'),('US','WLA','Willard','Willard','OH'),('US','WLB','Labouchere Bay','Labouchere Bay','AK'),('US','WLC','Windsor Locks','Windsor Locks','CT'),('US','WLD','Winfield','Winfield','KS'),('US','WLE','Wallace','Wallace','NC'),('US','WLF','Waldo','Waldo','FL'),('US','WLG','Williamsburg','Williamsburg','VA'),('US','WLH','West Liberty','West Liberty','KY'),('US','WLI','West Lebanon','West Lebanon','IN'),('US','WLJ','Wall','Wall','NJ'),('US','WLK','Selawik','Selawik','AK'),('US','WLL','Wrenshall','Wrenshall','MN'),('US','WLM','Waltham','Waltham','MA'),('US','WLN','Little Naukati','Little Naukati','AK'),('US','WLO','Willingboro','Willingboro','NJ'),('US','WLP','Walpole','Walpole','NH'),('US','WLQ','West Long Branch','West Long Branch','NJ'),('US','WLR','Loring','Loring','AK'),('US','WLS','Walls','Walls','MS'),('US','WLT','Wallington','Wallington','NJ'),('US','WLU','Walnut','Walnut','CA'),('US','WLV','Wallisville','Wallisville','TX'),('US','WLW','Willows','Willows','CA'),('US','WLX','Westlake','Westlake','OH'),('US','WLY','West Lafayette','West Lafayette','IN'),('US','WLZ','Winamac','Winamac','IN'),('US','WM2','Wagon Mound','Wagon Mound','NM'),('US','WMA','Wilma','Wilma','WA'),('US','WMB','Cambria','Cambria','WI'),('US','WMC','Winnemucca','Winnemucca','NV'),('US','WMD','Westminster','Westminster','MD'),('US','WME','Westminster','Westminster','CO'),('US','WMF','West Mifflin','West Mifflin','PA'),('US','WMG','Minong','Minong','WI'),('US','WMH','Mountain Home','Mountain Home','AR'),('US','WMI','Westminster','Westminster','MA'),('US','WMJ','Windham','Windham','CT'),('US','WMK','Meyers Chuck','Meyers Chuck','AK'),('US','WML','Westmoreland','Westmoreland','PA'),('US','WMM','Wampum','Wampum','PA'),('US','WMN','West Middlesex','West Middlesex','PA'),('US','WMO','White Mountain','White Mountain','AK'),('US','WMP','Whitmore Lake','Whitmore Lake','MI'),('US','WMQ','Whitehall','Whitehall','MI'),('US','WMR','Westminster','Westminster','SC'),('US','WMS','Williamstown','Williamstown','MA'),('US','WMT','Wilmington','Wilmington','VT'),('US','WMU','West Yarmouth','West Yarmouth','MA'),('US','WMV','Wareham','Wareham','MA'),('US','WMW','West Milwaukee','West Milwaukee','WI'),('US','WMX','West Monroe','West Monroe','LA'),('US','WMY','Windermere','Windermere','FL'),('US','WMZ','Westminster','Westminster','CA'),('US','WNA','Napakiak','Napakiak','AK'),('US','WNB','Winnsboro','Winnsboro','SC'),('US','WNC','Tuxekan Island','Tuxekan Island','AK'),('US','WND','Windsor','Windsor','CT'),('US','WNE','Wayne','Wayne','MI'),('US','WNF','Wisconsin Dells','Wisconsin Dells','WI'),('US','WNG','Wind Gap','Wind Gap','PA'),('US','WNH','Wentworth','Wentworth','NH'),('US','WNI','Warrenville','Warrenville','NJ'),('US','WNJ','Windsor','Windsor','NJ'),('US','WNK','Winooski','Winooski','VT'),('US','WNL','Winterville','Winterville','GA'),('US','WNM','Weston Mills','Weston Mills','NY'),('US','WNN','Winnebago','Winnebago','IL'),('US','WNO','Weston','Weston','FL'),('US','WNP','Wayne','Wayne','PA'),('US','WNQ','Wadena','Wadena','MN'),('US','WNR','Weiner','Weiner','AR'),('US','WNS','Winsted','Winsted','CT'),('US','WNT','Winterset','Winterset','IA'),('US','WNU','Walnutport','Walnutport','PA'),('US','WNV','Waynesville','Waynesville','PA'),('US','WNW','Wrightwood','Wrightwood','CA'),('US','WNX','Wellman','Wellman','TX'),('US','WNY','West New York','West New York','NJ'),('US','WNZ','West End','West End','NC'),('US','WOA','Woodland','Woodland','TX'),('US','WOB','Woodbridge','Woodbridge','CT'),('US','WOC','Worcester','Worcester','NY'),('US','WOD','Lockwood','Lockwood','MO'),('US','WOE','Woodville','Woodville','MS'),('US','WOF','Wolfforth','Wolfforth','TX'),('US','WOG','Wonewoc','Wonewoc','WI'),('US','WOH','Woods Hole','Woods Hole','MA'),('US','WOI','West Point','West Point','GA'),('US','WOJ','Woodbury','Woodbury','NJ'),('US','WOK','Woodstock','Woodstock','AL'),('US','WOL','Holland','Holland','WI'),('US','WOM','Wilmington','Wilmington','MA'),('US','WON','Woodlawn','Woodlawn','OH'),('US','WOO','Waterloo','Waterloo','NY'),('US','WOP','Willowbrook, DuPage','Willowbrook, DuPage','IL'),('US','WOQ','Woodridge','Woodridge','IL'),('US','WOR','West Orange/New Jersey','West Orange/New Jersey','NJ'),('US','WOS','Woodside/Queens/New York','Woodside/Queens/New York','NY'),('US','WOT','West Point','West Point','NY'),('US','WOU','Woodruff','Woodruff','SC'),('US','WOV','Woodsville','Woodsville','NH'),('US','WOW','Willow','Willow','AK'),('US','WOX','Windsor','Windsor','CA'),('US','WOY','Woodstock','Woodstock','GA'),('US','WOZ','Woodstock','Woodstock','IL'),('US','WPA','Warren','Warren','PA'),('US','WPB','Wills Point','Wills Point','NJ'),('US','WPC','Warehouse Point','Warehouse Point','CT'),('US','WPD','Woodland Hills','Woodland Hills','CA'),('US','WPE','Westport','Westport','MA'),('US','WPF','Waterproof','Waterproof','LA'),('US','WPG','West Springfield','West Springfield','NH'),('US','WPH','Waipahu (Oahu)','Waipahu (Oahu)','HI'),('US','WPI','White Pigeon','White Pigeon','MI'),('US','WPJ','Westwood Village','Westwood Village','CA'),('US','WPK','Winter Park','Winter Park','FL'),('US','WPL','Walpole','Walpole','MA'),('US','WPM','West Point','West Point','MS'),('US','WPN','West Plains','West Plains','MO'),('US','WPO','Paonia','Paonia','CO'),('US','WPP','Westport','Westport','PA'),('US','WPQ','West Lebanon','West Lebanon','NH'),('US','WPR','Westport','Westport','CT'),('US','WPS','Wabasso','Wabasso','FL'),('US','WPT','Westport','Westport','CA'),('US','WPU','West St Paul','West St Paul','MN'),('US','WPV','Waterloo, Johnson','Waterloo, Johnson','IN'),('US','WPW','Wapato','Wapato','WA'),('US','WPX','Winthrop Harbor','Winthrop Harbor','IL'),('US','WPZ','Westernport','Westernport','MD'),('US','WQA','Whitman','Whitman','MA'),('US','WQE','Wheatridge','Wheatridge','CO'),('US','WQF','Whittier','Whittier','AK'),('US','WQG','Wilmington','Wilmington','IL'),('US','WQH','Westchester','Westchester','CA'),('US','WQJ','West Los Angeles','West Los Angeles','CA'),('US','WQL','Westlake','Westlake','LA'),('US','WQN','Wauconda','Wauconda','IL'),('US','WQO','Waconia','Waconia','MN'),('US','WQR','Warren','Warren','AR'),('US','WQS','Wasco','Wasco','CA'),('US','WQV','Westlake Village','Westlake Village','CA'),('US','WQW','Winlock','Winlock','WA'),('US','WQX','Williamston','Williamston','NC'),('US','WQY','Washington','Washington','NJ'),('US','WQZ','Wintersville','Wintersville','OH'),('US','WRA','Warrington','Warrington','PA'),('US','WRB','Warner Robins','Warner Robins','GA'),('US','WRC','Warwick','Warwick','MA'),('US','WRD','West Redding','West Redding','CT'),('US','WRE','Warrenton','Warrenton','GA'),('US','WRF','Wethersfield','Wethersfield','CT'),('US','WRG','Wrangell','Wrangell','AK'),('US','WRH','Worth','Worth','IL'),('US','WRI','Fort Dix','Fort Dix','NJ'),('US','WRJ','Wray','Wray','GA'),('US','WRK','Warwick','Warwick','NY'),('US','WRL','Worland','Worland','WY'),('US','WRM','Warminster','Warminster','PA'),('US','WRN','Warren','Warren','OH'),('US','WRO','Westborough','Westborough','MA'),('US','WRP','Winterthur','Winterthur','DE'),('US','WRQ','Woodridge','Woodridge','DC'),('US','WRR','Warrendale','Warrendale','PA'),('US','WRS','Warners','Warners','NY'),('US','WRT','Warrenton','Warrenton','MO'),('US','WRU','Willow Run','Willow Run','MI'),('US','WRV','Wood River','Wood River','IL'),('US','WRW','Wedron','Wedron','IL'),('US','WRX','Wortham','Wortham','TX'),('US','WRY','West Roxbury','West Roxbury','MA'),('US','WRZ','Warrick','Warrick','IN'),('US','WS2','West Sayville','West Sayville','IN'),('US','WSA','West Seneca','West Seneca','NY'),('US','WSB','Steamboat Bay','Steamboat Bay','AK'),('US','WSC','Weston','Weston','CT'),('US','WSD','White Sands','White Sands','NM'),('US','WSE','Winslow','Winslow','ME'),('US','WSF','Sarichef','Sarichef','AK'),('US','WSG','Washington','Washington','PA'),('US','WSH','Shirley','Shirley','NY'),('US','WSI','Willsboro','Willsboro','NY'),('US','WSJ','San Juan','San Juan','AK'),('US','WSK','Washington','Washington','MO'),('US','WSL','Washingtonville','Washingtonville','NY'),('US','WSM','West Sacramento','West Sacramento','CA'),('US','WSN','South Naknek','South Naknek','AK'),('US','WSO','Wilson','Wilson','NC'),('US','WSP','West Springfield','West Springfield','MA'),('US','WSQ','Washington','Washington','IN'),('US','WSR','Windsor','Windsor','CO'),('US','WSS','West Salem','West Salem','WI'),('US','WST','Westerly','Westerly','RI'),('US','WSU','West Springfield','West Springfield','IL'),('US','WSV','Wellsville','Wellsville','KS'),('US','WSW','Warsaw','Warsaw','NC'),('US','WSX','West Sound','West Sound','WA'),('US','WSY','Weston','Weston','MO'),('US','WSZ','Westport','Westport','WA'),('US','WT2','Webster','Webster','SD'),('US','WT3','Washington','Washington','CA'),('US','WT4','West Trenton','West Trenton','NJ'),('US','WTA','Waterman','Waterman','IL'),('US','WTB','Westbrook','Westbrook','ME'),('US','WTC','Watson','Watson','CA'),('US','WTD','Westland','Westland','MI'),('US','WTE','White Bear Lake','White Bear Lake','MN'),('US','WTF','Waterford','Waterford','MI'),('US','WTG','Winter Garden','Winter Garden','FL'),('US','WTH','White Springs','White Springs','FL'),('US','WTI','Whiting','Whiting','WI'),('US','WTJ','Wittmann','Wittmann','AZ'),('US','WTK','Noatak','Noatak','AK'),('US','WTL','Tuntutuliak','Tuntutuliak','AK'),('US','WTM','Waterford','Waterford','ME'),('US','WTN','Wilmington','Wilmington','CA'),('US','WTO','Warrenton','Warrenton','OR'),('US','WTP','West Point','West Point','PA'),('US','WTQ','Wharton','Wharton','NJ'),('US','WTR','White River','White River','AZ'),('US','WTS','White Plains','White Plains','NY'),('US','WTT','Watertown','Watertown','CT'),('US','WTU','Wartburg','Wartburg','TN'),('US','WTV','Watervliet','Watervliet','MI'),('US','WTW','Watertown','Watertown','MA'),('US','WTX','White Oak','White Oak','TX'),('US','WTY','Westerville','Westerville','OH'),('US','WTZ','Wentzville','Wentzville','MO'),('US','WUA','Walkertown','Walkertown','PA'),('US','WUB','Woodburn','Woodburn','IN'),('US','WUC','Walnut Creek','Walnut Creek','OH'),('US','WUD','Woodstock','Woodstock','TN'),('US','WUF','Woodway','Woodway','WA'),('US','WUG','Whittington','Whittington','IL'),('US','WUI','West Union','West Union','IA'),('US','WUL','Woodlake','Woodlake','CA'),('US','WUN','Wauseon','Wauseon','OH'),('US','WUO','Warrenton','Warrenton','OH'),('US','WUP','Waupaca','Waupaca','WI'),('US','WUQ','West Union','West Union','OR'),('US','WUR','Wurtland','Wurtland','KY'),('US','WUS','Williamsburg','Williamsburg','IA'),('US','WUT','West Unity','West Unity','OH'),('US','WUU','Waupun','Waupun','WI'),('US','WUV','Wood Village','Wood Village','OR'),('US','WUW','Wallula','Wallula','WA'),('US','WUX','Woodland','Woodland','WA'),('US','WUZ','Williamsburg','Williamsburg','OH'),('US','WVA','Water Valley','Water Valley','MS'),('US','WVB','Waverly','Waverly','NE'),('US','WVC','West Valley City','West Valley City','UT'),('US','WVD','Waterford','Waterford','CA'),('US','WVE','Westville','Westville','NJ'),('US','WVF','Wrightsville','Wrightsville','GA'),('US','WVG','Whitesville','Whitesville','SC'),('US','WVH','Waverly','Waverly','MO'),('US','WVI','Watsonville','Watsonville','CA'),('US','WVJ','Warrenton','Warrenton','VA'),('US','WVK','Westville','Westville','IN'),('US','WVL','Waterville','Waterville','ME'),('US','WVM','Wellsville','Wellsville','MO'),('US','WVN','Whiteville','Whiteville','NC'),('US','WVO','Wernersville','Wernersville','PA'),('US','WVP','Spencer','Spencer','WV'),('US','WVQ','Waverly','Waverly','TN'),('US','WVR','West Hanover','West Hanover','MA'),('US','WVS','Waterville','Waterville','MA'),('US','WVT','White River Junction','White River Junction','VT'),('US','WVV','Weaverville','Weaverville','NC'),('US','WVW','Willowbrook','Willowbrook','CA'),('US','WVX','Wyoming','Wyoming','DE'),('US','WVY','Waverly','Waverly','IA'),('US','WVZ','West Bath','West Bath','ME'),('US','WW2','Wentworth','Wentworth','SD'),('US','WWA','Wasilla','Wasilla','AK'),('US','WWB','South Webster','South Webster','OH'),('US','WWC','Warsaw','Warsaw','MO'),('US','WWD','Wildwood','Wildwood','NJ'),('US','WWE','Sweetwater','Sweetwater','TN'),('US','WWF','Wildwood','Wildwood','FL'),('US','WWG','Warsaw','Warsaw','OH'),('US','WWH','West Wareham','West Wareham','MA'),('US','WWI','Weyauwega','Weyauwega','WI'),('US','WWJ','West Windsor','West Windsor','NJ'),('US','WWK','Waldwick','Waldwick','NJ'),('US','WWL','Williamston','Williamston','SC'),('US','WWM','White Marsh Station','White Marsh Station','MD'),('US','WWN','West Warren','West Warren','MA'),('US','WWO','Westwego','Westwego','LA'),('US','WWP','Whale Pass','Whale Pass','AK'),('US','WWQ','Whitewater','Whitewater','WI'),('US','WWR','Woodward','Woodward','OK'),('US','WWS','Whitehouse','Whitehouse','OH'),('US','WWT','Newtok','Newtok','AK'),('US','WWU','West Hollywood','West Hollywood','CA'),('US','WWV','Washington','Washington','WV'),('US','WWW','Weaver','Weaver','AL'),('US','WWX','Wautoma','Wautoma','WI'),('US','WWY','Willow Island','Willow Island','WV'),('US','WWZ','Watertown','Watertown','TN'),('US','WXA','Walthourville','Walthourville','GA'),('US','WXD','Wexford','Wexford','PA'),('US','WXG','Washougal','Washougal','WA'),('US','WXH','Waxhaw','Waxhaw','NC'),('US','WXI','Whitefish','Whitefish','MT'),('US','WXM','Whitinsville','Whitinsville','MA'),('US','WXN','Warren','Warren','MA'),('US','WXO','Westover','Westover','GA'),('US','WXP','West Portal','West Portal','NJ'),('US','WXQ','Wayland','Wayland','NY'),('US','WXR','Wilmer','Wilmer','TX'),('US','WXS','Wrightstown','Wrightstown','WI'),('US','WXT','Winston','Winston','NM'),('US','WXV','Waverly','Waverly','VA'),('US','WXW','Warsaw','Warsaw','IL'),('US','WXX','Waterford','Waterford','PA'),('US','WXY','Westfield','Westfield','NY'),('US','WXZ','Winton','Winton','CA'),('US','WY2','Wadley','Wadley','AL'),('US','WYA','Weatherford','Weatherford','OK'),('US','WYB','Waynesboro','Waynesboro','VA'),('US','WYC','Wyalusing','Wyalusing','PA'),('US','WYD','Wyandotte','Wyandotte','MI'),('US','WYE','Wayne','Wayne','OK'),('US','WYG','Waynesboro','Waynesboro','GA'),('US','WYH','Wylie','Wylie','TX'),('US','WYI','Wyemills','Wyemills','MD'),('US','WYJ','Wayne','Wayne','IN'),('US','WYL','Winnsboro','Winnsboro','LA'),('US','WYM','Wyoming','Wyoming','MI'),('US','WYN','Wayne','Wayne','NJ'),('US','WYO','Waynesboro','Waynesboro','PA'),('US','WYP','Wyoming','Wyoming','PA'),('US','WYQ','Wynne','Wynne','AR'),('US','WYR','Waymart','Waymart','PA'),('US','WYS','West Yellowstone','West Yellowstone','MT'),('US','WYT','Wilton','Wilton','ME'),('US','WYU','Waynesboro','Waynesboro','TN'),('US','WYV','Waynesville','Waynesville','NC'),('US','WYW','Wyoming','Wyoming','WI'),('US','WYX','Willis','Willis','TX'),('US','WZA','Wabasha','Wabasha','MN'),('US','WZC','West Chester','West Chester','OH'),('US','WZG','Willow Springs','Willow Springs','IL'),('US','WZI','Willits','Willits','CA'),('US','WZJ','Williamstown','Williamstown','NJ'),('US','WZK','Westbrook','Westbrook','CT'),('US','WZM','Wells','Wells','ME'),('US','WZN','West Hazelton','West Hazelton','PA'),('US','WZO','Wilson','Wilson','MI'),('US','WZP','Williamstown','Williamstown','PA'),('US','WZS','Warsaw','Warsaw','KY'),('US','WZT','Weston','Weston','WI'),('US','WZV','Wailuku (Maui)','Wailuku (Maui)','HI'),('US','WZW','White Swan','White Swan','WA'),('US','WZY','Waterville Valley','Waterville Valley','NH'),('US','WZZ','Wenonah','Wenonah','NJ'),('US','XAE','Camden','Camden','DE'),('US','XAI','Arlee','Arlee','MT'),('US','XAK','Alva','Alva','OK'),('US','XAL','Allen','Allen','TX'),('US','XAR','Starr','Starr','SC'),('US','XAT','Annandale','Annandale','MN'),('US','XAU','Apple Grove','Apple Grove','WV'),('US','XAV','Appalachia','Appalachia','VA'),('US','XAX','Appomattox','Appomattox','VA'),('US','XAY','Arcola','Arcola','LA'),('US','XAZ','Archdale','Archdale','NC'),('US','XBA','Aberdeen','Aberdeen','SC'),('US','XBB','Argo','Argo','IL'),('US','XBC','Arlington','Arlington','VT'),('US','XBD','Ampthill','Ampthill','VA'),('US','XBE','Allston','Allston','MA'),('US','XBF','Aston','Aston','PA'),('US','XBG','Blackshear','Blackshear','GA'),('US','XBH','Ashland','Ashland','PA'),('US','XBI','Au Gres','Au Gres','MI'),('US','XBJ','Austin','Austin','IN'),('US','XBK','Avard','Avard','OK'),('US','XBL','Agawam','Agawam','MA'),('US','XBM','Arlington','Arlington','WI'),('US','XBN','Ashland City','Ashland City','TN'),('US','XBO','Alta','Alta','UT'),('US','XBP','Bath','Bath','SC'),('US','XBQ','Baraboo','Baraboo','WI'),('US','XBR','Basin','Basin','WY'),('US','XBS','Balmat','Balmat','NY'),('US','XBT','Berlin','Berlin','NJ'),('US','XBU','Belvidere','Belvidere','NJ'),('US','XBV','Bethel','Bethel','VT'),('US','XBW','Webb City','Webb City','MO'),('US','XBX','Bellevue','Bellevue','OH'),('US','XBY','Bedford','Bedford','VA'),('US','XBZ','Bedford','Bedford','PA'),('US','XCA','Bedford','Bedford','OH'),('US','XCB','Bustleton','Bustleton','PA'),('US','XCC','Belding','Belding','MI'),('US','XCD','Big Island','Big Island','VA'),('US','XCE','Bridesburg','Bridesburg','PA'),('US','XCF','Bingen','Bingen','WA'),('US','XCG','Bird in Hand','Bird in Hand','PA'),('US','XCH','Brookfield','Brookfield','WI'),('US','XCJ','Brillion','Brillion','WI'),('US','XCL','Browns Summit','Browns Summit','NC'),('US','XCM','Broomall','Broomall','PA'),('US','XCN','Blue Mountain','Blue Mountain','MS'),('US','XCO','Brenham','Brenham','TX'),('US','XCP','Boone','Boone','NC'),('US','XCQ','Brown Deer','Brown Deer','WI'),('US','XCR','Bolivar','Bolivar','TN'),('US','XCS','Bridgeport','Bridgeport','PA'),('US','XCT','Bridgeville','Bridgeville','PA'),('US','XCU','Burlington','Burlington','WY'),('US','XCV','Bardstown','Bardstown','KY'),('US','XCX','Brooklyn Center','Brooklyn Center','MN'),('US','XCY','Bertram','Bertram','TX'),('US','XCZ','Belton','Belton','TX'),('US','XDA','Boothwyn','Boothwyn','PA'),('US','XDB','Bluff','Bluff','UT'),('US','XDC','Blue Ash','Blue Ash','OH'),('US','XDD','Burlington','Burlington','NC'),('US','XDE','Bellevue','Bellevue','KY'),('US','XDF','Beverly','Beverly','NJ'),('US','XDG','Butler','Butler','WI'),('US','XDH','Berwick','Berwick','PA'),('US','XDI','Brookshire','Brookshire','TX'),('US','XDJ','Bridgeport','Bridgeport','WV'),('US','XDK','Boyle Heights','Boyle Heights','CA'),('US','XDL','Brandywine','Brandywine','MD'),('US','XDM','Combined Locks','Combined Locks','WI'),('US','XDN','Cicero','Cicero','IL'),('US','XDO','Cedarville','Cedarville','OH'),('US','XDP','Cedar Falls','Cedar Falls','NC'),('US','XDQ','Cedarville','Cedarville','NJ'),('US','XDR','Chesterfield','Chesterfield','VA'),('US','XDT','Chatsworth','Chatsworth','GA'),('US','XDU','Cinnaminson','Cinnaminson','NJ'),('US','XDV','Chelan','Chelan','WA'),('US','XDX','Clewiston','Clewiston','FL'),('US','XDY','Caddo Mills','Caddo Mills','TX'),('US','XDZ','Camp Hill','Camp Hill','PA'),('US','XEA','Concord','Concord','NC'),('US','XEB','Connell','Connell','WA'),('US','XEC','Cando','Cando','ND'),('US','XEE','Colrain','Colrain','MA'),('US','XEF','Cohasset','Cohasset','MN'),('US','XEG','Coon Rapids','Coon Rapids','MN'),('US','XEH','Erie','Erie','CO'),('US','XEI','Cashmere','Cashmere','WA'),('US','XEJ','Catasauqua','Catasauqua','PA'),('US','XEK','Charlestown','Charlestown','IN'),('US','XEL','Catoosa','Catoosa','OK'),('US','XEM','Corinth','Corinth','TN'),('US','XEN','Caryville','Caryville','TN'),('US','XEO','Clarksville','Clarksville','TX'),('US','XEP','Clover','Clover','ID'),('US','XEQ','Canal Winchester','Canal Winchester','OH'),('US','XER','Cleona','Cleona','PA'),('US','XES','Lake Geneva','Lake Geneva','WI'),('US','XET','Dayton','Dayton','OR'),('US','XEU','Dodge Center','Dodge Center','MN'),('US','XEV','Dracut','Dracut','MA'),('US','XEW','Englewood','Englewood','FL'),('US','XEX','Decatur','Decatur','MI'),('US','XEY','Donna','Donna','TX'),('US','XEZ','Dover','Dover','DE'),('US','XFA','Deer Park','Deer Park','OH'),('US','XFB','Dexter','Dexter','ME'),('US','XFC','Doyle','Doyle','TN'),('US','XFD','Bellefontaine Neighbors','Bellefontaine Neighbors','MO'),('US','XFE','Encinitas','Encinitas','CA'),('US','XFF','Easton','Easton','ME'),('US','XFG','Flower Mound','Flower Mound','TX'),('US','XFH','Ellwood City','Ellwood City','PA'),('US','XFI','Fairmont','Fairmont','WV'),('US','XFJ','Feura Bush','Feura Bush','NY'),('US','XFK','Fremont','Fremont','OH'),('US','XFL','Finderne','Finderne','NJ'),('US','XFM','Falls Mills','Falls Mills','VA'),('US','XFN','Falkner','Falkner','MS'),('US','XFO','Fort Atkinson','Fort Atkinson','WI'),('US','XFP','Fairport','Fairport','NY'),('US','XFQ','Fraser','Fraser','MI'),('US','XFR','Fontana','Fontana','CA'),('US','XFS','Gastonia','Gastonia','NC'),('US','XFT','Gleed','Gleed','WA'),('US','XFU','Gering','Gering','NE'),('US','XFV','Green Island','Green Island','NY'),('US','XFX','Grants Pass','Grants Pass','OR'),('US','XFY','Gridley','Gridley','IL'),('US','XFZ','Garwood','Garwood','NJ'),('US','XGA','Hubbard','Hubbard','OH'),('US','XGB','Hoosick Falls','Hoosick Falls','NY'),('US','XGC','Hager City','Hager City','WI'),('US','XGD','Henderson','Henderson','KY'),('US','XGE','Highgate Center','Highgate Center','VT'),('US','XGF','Hahira','Hahira','GA'),('US','XGG','Berrysburg','Berrysburg','PA'),('US','XGH','Higbee','Higbee','MO'),('US','XGI','Hinkle','Hinkle','OR'),('US','XGJ','Holland','Holland','NY'),('US','XGK','Hamlin','Hamlin','TX'),('US','XGL','Hammonton','Hammonton','NJ'),('US','XGM','Hamilton','Hamilton','MO'),('US','XGN','Hondo','Hondo','TX'),('US','XGO','Howard Beach/Queens/New York','Howard Beach/Queens/New York','NY'),('US','XGP','Holliston','Holliston','MA'),('US','XGR','Hastings','Hastings','MN'),('US','XGS','Huntersville','Huntersville','NC'),('US','XGT','Heath','Heath','OH'),('US','XGU','Hamtramck','Hamtramck','MI'),('US','XGV','Hudson','Hudson','NC'),('US','XGW','Germantown','Germantown','TN'),('US','XGX','Hawarden','Hawarden','IA'),('US','XGY','Hawley','Hawley','MN'),('US','XGZ','Hyattsville','Hyattsville','MD'),('US','XHA','Haynesville','Haynesville','LA'),('US','XHB','Jessup','Jessup','MD'),('US','XHC','Johnson Creek','Johnson Creek','WI'),('US','XHE','Kearny','Kearny','NJ'),('US','XHF','Kirkland','Kirkland','WA'),('US','XHG','Lamesa','Lamesa','TX'),('US','XHH','Lawrenceburg','Lawrenceburg','TN'),('US','XHI','La Conner','La Conner','WA'),('US','XHJ','Lake City','Lake City','PA'),('US','XHK','Leeds','Leeds','MO'),('US','XHL','Lebanon','Lebanon','NJ'),('US','XHM','Lightfoot','Lightfoot','VA'),('US','XHN','Locust Grove','Locust Grove','OK'),('US','XHO','Long Island City/Queens/New York','Long Island City/Queens/New York','NY'),('US','XHP','Lackawanna','Lackawanna','NY'),('US','XHQ','Lake Mills','Lake Mills','WI'),('US','XHR','Lomira','Lomira','WI'),('US','XHS','Langhorne','Langhorne','PA'),('US','XHT','Loveland','Loveland','OH'),('US','XHU','Loudon','Loudon','TN'),('US','XHV','Largo','Largo','FL'),('US','XHX','Livingston','Livingston','MI'),('US','XHY','Locust Summit','Locust Summit','PA'),('US','XHZ','Litchfield','Litchfield','IL'),('US','XIA','Leavenworth','Leavenworth','KS'),('US','XIB','Langsville','Langsville','OH'),('US','XIC','Mabie','Mabie','WV'),('US','XID','Millbury','Millbury','OH'),('US','XIE','McBee','McBee','SC'),('US','XIF','Macedonia','Macedonia','OH'),('US','XIG','Macedon','Macedon','NY'),('US','XIH','Moorhead','Moorhead','MN'),('US','XII','Malden','Malden','MA'),('US','XIJ','Media','Media','PA'),('US','XIK','Milford','Milford','TX'),('US','XIL','Montgomery','Montgomery','IL'),('US','XIM','Mingo Junction','Mingo Junction','OH'),('US','XIN','Middletown','Middletown','CT'),('US','XIO','Morrisville','Morrisville','PA'),('US','XIQ','Mickleton','Mickleton','NJ'),('US','XIR','Millburn','Millburn','NJ'),('US','XIS','Mapleton','Mapleton','IL'),('US','XIT','Malott','Malott','WA'),('US','XIU','Magna','Magna','UT'),('US','XIX','Montpelier','Montpelier','VA'),('US','XIY','Monrovia','Monrovia','CA'),('US','XJA','Maple Shade','Maple Shade','NJ'),('US','XJB','Mars','Mars','PA'),('US','XJC','Marion','Marion','PA'),('US','XJD','Marion','Marion','VA'),('US','XJE','Martel','Martel','OH'),('US','XJF','Massillon','Massillon','OH'),('US','XJH','Mountville','Mountville','PA'),('US','XJI','Mountlake Terrace','Mountlake Terrace','WA'),('US','XJK','Mooresville','Mooresville','NC'),('US','XJL','Myrtle','Myrtle','MS'),('US','XJM','North Andover','North Andover','MA'),('US','XJN','North Branch','North Branch','NJ'),('US','XJO','Northfield','Northfield','IL'),('US','XJP','Nova','Nova','OH'),('US','XJQ','North Tonawanda','North Tonawanda','NY'),('US','XJR','Norwalk','Norwalk','OH'),('US','XJS','New Troy','New Troy','MI'),('US','XJU','Newport','Newport','KY'),('US','XJV','Oconto Falls','Oconto Falls','WI'),('US','XJX','Oceanside','Oceanside','NY'),('US','XJY','Orcas','Orcas','WA'),('US','XJZ','Old Forge','Old Forge','PA'),('US','XKA','Old Hickory','Old Hickory','TN'),('US','XKB','Oakland','Oakland','NJ'),('US','XKC','Orland Park','Orland Park','IL'),('US','XKD','Orefield','Orefield','PA'),('US','XKE','Orting','Orting','WA'),('US','XKF','Othello','Othello','WA'),('US','XKG','Paducah','Paducah','TX'),('US','XKH','Princeton','Princeton','MN'),('US','XKI','Palm Harbor','Palm Harbor','FL'),('US','XKJ','Perham','Perham','MN'),('US','XKK','Pennington Gap','Pennington Gap','VA'),('US','XKL','Parris Island','Parris Island','SC'),('US','XKM','Plainsboro','Plainsboro','NJ'),('US','XKN','Plymouth','Plymouth','NC'),('US','XKO','Pineville','Pineville','SC'),('US','XKP','Prosperity','Prosperity','SC'),('US','XKQ','Perrysburg','Perrysburg','OH'),('US','XKR','Prospect','Prospect','OR'),('US','XKS','Walnut Cove','Walnut Cove','NC'),('US','XKT','Pateros','Pateros','WA'),('US','XKU','Princeton','Princeton','FL'),('US','XKV','Plainville','Plainville','MA'),('US','XKW','Kirkwood','Kirkwood','MO'),('US','XKX','Portage','Portage','WI'),('US','XKY','Powers Lake','Powers Lake','WI'),('US','XKZ','Ralls','Ralls','TX'),('US','XLA','Richmond','Richmond','TX'),('US','XLB','Royal City','Royal City','WA'),('US','XLC','Redmond','Redmond','WA'),('US','XLD','Radford','Radford','VA'),('US','XLE','Ridgway','Ridgway','PA'),('US','XLF','Raynham','Raynham','MA'),('US','XLG','Richland Hills','Richland Hills','TX'),('US','XLI','Rockwall','Rockwall','TX'),('US','XLJ','Remington','Remington','VA'),('US','XLK','Rowesville','Rowesville','SC'),('US','XLL','Saegertown','Saegertown','PA'),('US','XLM','Saint Joseph','Saint Joseph','IL'),('US','XLN','South Brunswick','South Brunswick','NJ'),('US','XLO','Sebastopol','Sebastopol','MS'),('US','XLP','Silsbee','Silsbee','TX'),('US','XLQ','Scofield','Scofield','UT'),('US','XLR','Seadrift','Seadrift','TX'),('US','XLS','Sterling','Sterling','MA'),('US','XLT','Locust','Locust','NJ'),('US','XLU','Seaside','Seaside','CA'),('US','XLV','Suffield','Suffield','CT'),('US','XLX','Stamford','Stamford','CT'),('US','XLY','Savage','Savage','MN'),('US','XLZ','Shoreham','Shoreham','NY'),('US','XMA','Sharonville','Sharonville','OH'),('US','XMB','Sheldon','Sheldon','TX'),('US','XMC','Shellman','Shellman','GA'),('US','XMD','Madison','Madison','SD'),('US','XME','Slaton','Slaton','TX'),('US','XMF','South Miami','South Miami','FL'),('US','XMG','Maple Grove','Maple Grove','MN'),('US','XMH','Sumner','Sumner','WA'),('US','XMI','Seneca','Seneca','IL'),('US','XMJ','Senecaville','Senecaville','OH'),('US','XMK','Southport','Southport','NC'),('US','XML','Soddy-Daisy','Soddy-Daisy','TN'),('US','XMM','South Windsor','South Windsor','CT'),('US','XMN','Springville','Springville','TN'),('US','XMO','San Clemente','San Clemente','CA'),('US','XMP','Sherman','Sherman','CT'),('US','XMQ','Saratoga','Saratoga','CA'),('US','XMR','Southwark','Southwark','PA'),('US','XMS','Strinestown','Strinestown','PA'),('US','XMT','Startex','Startex','SC'),('US','XMU','Starke','Starke','FL'),('US','XMV','Summit','Summit','IL'),('US','XMX','Savannah','Savannah','NY'),('US','XMZ','Sylvania','Sylvania','GA'),('US','XNA','Sayreville','Sayreville','NJ'),('US','XNB','Sebastian','Sebastian','TX'),('US','XNC','Tabor','Tabor','IA'),('US','XND','Tuxedo Park','Tuxedo Park','NY'),('US','XNE','Taylor','Taylor','MI'),('US','XNF','Topton','Topton','PA'),('US','XNG','Trenton','Trenton','MI'),('US','XNH','Tuscola','Tuscola','IL'),('US','XNI','Tunnel Hill','Tunnel Hill','GA'),('US','XNJ','Travelers Rest','Travelers Rest','SC'),('US','XNK','Tyrone','Tyrone','PA'),('US','XNL','Venice','Venice','IL'),('US','XNM','Vinton','Vinton','VA'),('US','XNN','Wilburton','Wilburton','OK'),('US','XNO','Woodbury','Woodbury','CT'),('US','XNP','Westchester','Westchester','MA'),('US','XNR','Waxdale','Waxdale','WI'),('US','XNS','Windsor','Windsor','NY'),('US','XNT','Wildes Corner','Wildes Corner','RI'),('US','XNU','Wagner','Wagner','SD'),('US','XNV','West Jefferson','West Jefferson','NC'),('US','XNW','New Madrid','New Madrid','MO'),('US','XNX','Walkersville','Walkersville','MD'),('US','XNY','Woods Mill','Woods Mill','NY'),('US','XO2','Cooper','Cooper','TX'),('US','XOA','Westwood','Westwood','KS'),('US','XOB','Weston','Weston','OR'),('US','XOC','Windsor','Windsor','WI'),('US','XOD','Watseka','Watseka','IL'),('US','XOE','Watervliet','Watervliet','NY'),('US','XOF','Waverly','Waverly','TX'),('US','XOG','Wrightsville','Wrightsville','PA'),('US','XOH','Wauwatosa','Wauwatosa','WI'),('US','XOI','Westwood','Westwood','NJ'),('US','XOJ','West Warwick','West Warwick','RI'),('US','XOK','Crockett','Crockett','TX'),('US','XOL','Xenia','Xenia','OH'),('US','XOM','West Sedona','West Sedona','AZ'),('US','XON','Lexington','Lexington','OR'),('US','XOR','Oberlin','Oberlin','OH'),('US','XOT','Scott','Scott','MS'),('US','XOU','Plymouth','Plymouth','UT'),('US','XOX','Pleasant View, Weber','Pleasant View, Weber','UT'),('US','XPE','Perdue Hill','Perdue Hill','AL'),('US','XPI','Piedmont','Piedmont','AL'),('US','XPO','Portland','Portland','PA'),('US','XPP','Pleasant Prairie','Pleasant Prairie','IA'),('US','XPR','Pine Ridge','Pine Ridge','SD'),('US','XPT','Portola Valley','Portola Valley','CA'),('US','XPU','West Kuparuk','West Kuparuk','AK'),('US','XQM','McLean/Washington, D.C.','McLean/Washington, D.C.','VA'),('US','XRA','Ravena','Ravena','NY'),('US','XRC','Rainbow City','Rainbow City','AL'),('US','XRD','Crossroads','Crossroads','GA'),('US','XRE','Clare','Clare','MI'),('US','XRI','Morris','Morris','AL'),('US','XRL','Roseland','Roseland','LA'),('US','XRN','Rancocas','Rancocas','NJ'),('US','XRO','North Randall','North Randall','OH'),('US','XRS','Rock Springs','Rock Springs','GA'),('US','XRT','Rock Tavern','Rock Tavern','NY'),('US','XRY','Ridgeway','Ridgeway','CO'),('US','XSG','Sagola','Sagola','MI'),('US','XSH','Shingle Springs','Shingle Springs','CA'),('US','XSI','Shelter Island','Shelter Island','NY'),('US','XSJ','South Jordan','South Jordan','UT'),('US','XSK','Shaker Heights','Shaker Heights','OH'),('US','XSM','St Marys City','St Marys City','MD'),('US','XSO','La Crosse','La Crosse','VA'),('US','XSP','Sunland Park','Sunland Park','NM'),('US','XSR','Socorro','Socorro','TX'),('US','XSS','Cassville','Cassville','MO'),('US','XSU','Sunny Isles','Sunny Isles','FL'),('US','XSV','Sullivan','Sullivan','MO'),('US','XSW','Snow Hill','Snow Hill','NC'),('US','XSX','Sheppard','Sheppard','TX'),('US','XSY','Short Hills','Short Hills','NJ'),('US','XTA','Etna','Etna','OH'),('US','XTE','Timmonsville','Timmonsville','SC'),('US','XTK','Chetek','Chetek','WI'),('US','XTM','Saint Thomas','Saint Thomas','PA'),('US','XTN','Tiburon','Tiburon','CA'),('US','XTO','Trenton','Trenton','SC'),('US','XTR','West Rutland','West Rutland','VT'),('US','XTS','Tams','Tams','WV'),('US','XTT','Wilmette','Wilmette','IL'),('US','XTY','Tuckahoe','Tuckahoe','NY'),('US','XUB','Auburn','Auburn','GA'),('US','XUG','Union Grove','Union Grove','NC'),('US','XUI','Union, Neshaboa','Union, Neshaboa','MS'),('US','XUK','Mattituck','Mattituck','NY'),('US','XUL','Beulah','Beulah','ND'),('US','XUN','Sunrise','Sunrise','FL'),('US','XVE','Versailles','Versailles','OH'),('US','XVI','Sellersville','Sellersville','PA'),('US','XVN','Silverton','Silverton','OR'),('US','XVR','Clover','Clover','WI'),('US','XVT','Vincentown','Vincentown','NJ'),('US','XWE','White Lake','White Lake','WI'),('US','XWF','Waterford','Waterford','OH'),('US','XWG','Wingate','Wingate','NC'),('US','XWH','Whitesburg','Whitesburg','TN'),('US','XWL','Maxwell','Maxwell','AL'),('US','XWN','Windsor','Windsor','VA'),('US','XWO','Wolcott','Wolcott','CT'),('US','XWP','White Plains','White Plains','MD'),('US','XWR','Swarthmore/Philadelphia','Swarthmore/Philadelphia','PA'),('US','XWT','Whitestown','Whitestown','IN'),('US','XWV','Warrenville','Warrenville','IL'),('US','XWY','Wyandanch','Wyandanch','NY'),('US','XXB','Belmont','Belmont','WI'),('US','XXD','Middlefield','Middlefield','CT'),('US','XXE','Moxee City','Moxee City','WA'),('US','XXN','Rockville','Rockville','IN'),('US','XXZ','McCombs','McCombs','OH'),('US','XYB','Byron','Byron','IL'),('US','XYL','Los Alamos','Los Alamos','CA'),('US','XYS','Murrysville','Murrysville','PA'),('US','XYT','Wyatt','Wyatt','IN'),('US','XYV','Taylorsville','Taylorsville','GA'),('US','XZM','Morrisville','Morrisville','NC'),('US','XZV','Victoria','Victoria','VA'),('US','XZW','Willianstown','Willianstown','NY'),('US','YAB','Albion','Albion','IN'),('US','YAD','Yadkinville','Yadkinville','NC'),('US','YAF','American Falls','American Falls','ID'),('US','YAG','Algood','Algood','TN'),('US','YAH','Yarmouth','Yarmouth','MA'),('US','YAI','Addison','Addison','MI'),('US','YAK','Yakutat','Yakutat','AK'),('US','YAL','Yale','Yale','MI'),('US','YAM','Amherst','Amherst','MA'),('US','YAN','Alanson','Alanson','MI'),('US','YAO','Aurora','Aurora','IN'),('US','YAP','Yardley','Yardley','PA'),('US','YAR','Yarmouth','Yarmouth','ME'),('US','YAS','Aransas Pass','Aransas Pass','TX'),('US','YAT','Yatesboro','Yatesboro','PA'),('US','YAV','Yucca Valley','Yucca Valley','CA'),('US','YAW','Apple Valley','Apple Valley','MN'),('US','YAX','Alexander','Alexander','AR'),('US','YAZ','Yazoo City','Yazoo City','MS'),('US','YBC','Columbus','Columbus','NJ'),('US','YBD','Belden','Belden','MS'),('US','YBG','Bongards','Bongards','MN'),('US','YBK','Brick','Brick','NJ'),('US','YBL','Yorba Linda','Yorba Linda','CA'),('US','YBM','Bantam','Bantam','CT'),('US','YBN','Boylston','Boylston','MA'),('US','YBO','Byron','Byron','MN'),('US','YBP','Bayonet Point','Bayonet Point','FL'),('US','YBR','Blue Ridge','Blue Ridge','GA'),('US','YBS','Boston','Boston','NY'),('US','YBT','Belton','Belton','SC'),('US','YBY','Bonifay','Bonifay','FL'),('US','YCA','Camby','Camby','IN'),('US','YCB','Cuddy','Cuddy','PA'),('US','YCD','Cathedral City','Cathedral City','CA'),('US','YCE','Carver','Carver','MA'),('US','YCF','Litchfield','Litchfield','CT'),('US','YCG','Cedar Grove','Cedar Grove','NC'),('US','YCI','Century City','Century City','CA'),('US','YCK','Clatskanie','Clatskanie','OR'),('US','YCL','Collinsville','Collinsville','IL'),('US','YCM','Comstock Park','Comstock Park','MI'),('US','YCO','Coal Run, Northumberland','Coal Run, Northumberland','PA'),('US','YCP','Central Point','Central Point','OR'),('US','YCU','Columbia Falls','Columbia Falls','MT'),('US','YCV','Corvallis','Corvallis','MT'),('US','YCX','Colfax','Colfax','WA'),('US','YCY','Yanceyville','Yanceyville','NC'),('US','YCZ','Cadiz','Cadiz','KY'),('US','YDA','Dryden','Dryden','MI'),('US','YDD','Boyd','Boyd','WI'),('US','YDE','Dale','Dale','WI'),('US','YDG','Coolidge','Coolidge','AZ'),('US','YDI','Denair','Denair','CA'),('US','YDM','Stedman','Stedman','NC'),('US','YDN','Lyndon','Lyndon','KS'),('US','YDO','Orondo','Orondo','WA'),('US','YDP','Delhi','Delhi','NY'),('US','YDR','Yoder','Yoder','IN'),('US','YDV','Yardville','Yardville','NJ'),('US','YDW','Byrdstown','Byrdstown','TN'),('US','YDX','Dexter','Dexter','MI'),('US','YDY','Sydney','Sydney','ND'),('US','YEA','Eagle, Ada','Eagle, Ada','ID'),('US','YEB','Ellenboro','Ellenboro','NC'),('US','YEC','Winneconne','Winneconne','WI'),('US','YED','Eldon','Eldon','MO'),('US','YEG','Evergreen','Evergreen','CO'),('US','YEK','Elkton','Elkton','FL'),('US','YEL','Yellville','Yellville','AR'),('US','YEM','Emory','Emory','TX'),('US','YEP','East Palestine','East Palestine','OH'),('US','YER','Sisters','Sisters','OR'),('US','YES','Myerstown','Myerstown','PA'),('US','YEX','Dyer','Dyer','NV'),('US','YFA','Florida City','Florida City','FL'),('US','YFB','Fort Bliss','Fort Bliss','TX'),('US','YFD','Flandreau','Flandreau','SD'),('US','YFE','Fairfield','Fairfield','ME'),('US','YFG','Fort Gratiot','Fort Gratiot','MI'),('US','YFH','Fletcher','Fletcher','OH'),('US','YFL','Fairfield','Fairfield','IL'),('US','YFO','Fair Oaks','Fair Oaks','AR'),('US','YFR','Lyford','Lyford','TX'),('US','YFV','Fortville','Fortville','IN'),('US','YFX','Fox Lake','Fox Lake','WI'),('US','YFZ','Frazeysburg','Frazeysburg','OH'),('US','YGE','Genesee','Genesee','ID'),('US','YGL','Glennville','Glennville','GA'),('US','YGS','Groves','Groves','TX'),('US','YGV','Youngsville','Youngsville','LA'),('US','YGW','Youngwood','Youngwood','PA'),('US','YGY','Montgomery','Montgomery','TN'),('US','YHA','Haviland','Haviland','OH'),('US','YHB','Heyburn','Heyburn','ID'),('US','YHD','Hopland','Hopland','CA'),('US','YHE','Cowiche','Cowiche','WA'),('US','YHI','Hickory Flat, Benton','Hickory Flat, Benton','MS'),('US','YHJ','Yamhill','Yamhill','OR'),('US','YHM','Holmes','Holmes','NY'),('US','YHN','Hanrahan','Hanrahan','NC'),('US','YHP','Bishop','Bishop','GA'),('US','YHR','Hebron','Hebron','NE'),('US','YHS','Hubbardston','Hubbardston','MA'),('US','YHX','Halifax','Halifax','PA'),('US','YIA','Hayti','Hayti','MO'),('US','YIE','Islandia','Islandia','NY'),('US','YIG','Ingleside','Ingleside','TX'),('US','YIL','Indialantic','Indialantic','FL'),('US','YIP','Willow Run Apt/Detroit','Willow Run Apt/Detroit','MI'),('US','YIT','Plantation','Plantation','FL'),('US','YIV','Riverton','Riverton','UT'),('US','YJY','Jerseyville','Jerseyville','IL'),('US','YKB','York Beach','York Beach','ME'),('US','YKE','Lykens','Lykens','PA'),('US','YKH','Yorktown Heights','Yorktown Heights','NY'),('US','YKL','Hoyt Lakes','Hoyt Lakes','MN'),('US','YKM','Yakima','Yakima','WA'),('US','YKN','Yankton','Yankton','SD'),('US','YKO','Yukon','Yukon','OK'),('US','YKS','Boykins','Boykins','VA'),('US','YKV','Pickensville','Pickensville','AL'),('US','YKW','Yorktown','Yorktown','VA'),('US','YLA','Lakewood','Lakewood','WA'),('US','YLB','Lebec','Lebec','CA'),('US','YLC','Lackey','Lackey','MS'),('US','YLD','Lind','Lind','WA'),('US','YLE','Fort Lewis','Fort Lewis','WA'),('US','YLF','Alden','Alden','NY'),('US','YLL','Canyonville','Canyonville','OR'),('US','YLM','Mahanoy City','Mahanoy City','PA'),('US','YLO','Logan Township','Logan Township','NJ'),('US','YLP','Lake Providence','Lake Providence','LA'),('US','YLR','Littlerock','Littlerock','CA'),('US','YLS','Salisbury Mills','Salisbury Mills','NY'),('US','YLT','Lanett','Lanett','AL'),('US','YLU','Lula','Lula','GA'),('US','YLW','Linwood','Linwood','MI'),('US','YLX','Lenox','Lenox','IA'),('US','YMA','Yemassee','Yemassee','SC'),('US','YMB','Mabelvale','Mabelvale','AR'),('US','YMC','Manchester','Manchester','PA'),('US','YMD','Madison Park','Madison Park','WA'),('US','YMH','Mars Hill','Mars Hill','NC'),('US','YMI','Miles City','Miles City','FL'),('US','YMK','Murdock','Murdock','NE'),('US','YML','Midland','Midland','VA'),('US','YMM','Mayer','Mayer','MN'),('US','YMN','Manson','Manson','WA'),('US','YMO','Symsonia','Symsonia','KY'),('US','YMQ','Moweaqua','Moweaqua','IL'),('US','YMR','Mosier','Mosier','OR'),('US','YMS','Mount Sterling','Mount Sterling','OH'),('US','YMT','Middletown','Middletown','RI'),('US','YMU','Plymouth','Plymouth','CT'),('US','YMV','Mount Vernon','Mount Vernon','NY'),('US','YMY','Milroy','Milroy','IN'),('US','YMZ','Montezuma','Montezuma','IA'),('US','YNA','Naches','Naches','WA'),('US','YNC','Newcastle','Newcastle','UT'),('US','YND','Lyndon Station','Lyndon Station','WI'),('US','YNE','Wayne','Wayne','NY'),('US','YNG','Youngstown','Youngstown','OH'),('US','YNH','New Haven','New Haven','WV'),('US','YNK','Yaphank','Yaphank','NY'),('US','YNN','Glenndale','Glenndale','MD'),('US','YNO','North Woodstock','North Woodstock','NH'),('US','YNR','Tyner','Tyner','NC'),('US','YNS','Lyons','Lyons','CO'),('US','YNT','Bryant','Bryant','AR'),('US','YNV','Shippenville','Shippenville','PA'),('US','YNW','Norwood','Norwood','MN'),('US','YOA','Yoakum','Yoakum','TX'),('US','YOB','Oakboro','Oakboro','NC'),('US','YOF','Olmsted Falls','Olmsted Falls','OH'),('US','YOG','Gilberts','Gilberts','IL'),('US','YOK','Yoke Bay','Yoke Bay','AK'),('US','YON','Yonkers','Yonkers','NY'),('US','YOO','Yolo','Yolo','CA'),('US','YOQ','Ogunquit','Ogunquit','ME'),('US','YOR','York','York','SC'),('US','YOS','Lyons','Lyons','GA'),('US','YOU','Youngsville','Youngsville','PA'),('US','YOX','Crown Point','Crown Point','IN'),('US','YPA','Peabody','Peabody','KS'),('US','YPB','Peterborough','Peterborough','NH'),('US','YPC','Pasadena','Pasadena','MD'),('US','YPD','Plainfield','Plainfield','NH'),('US','YPF','Pigeon Forge','Pigeon Forge','TN'),('US','YPG','Pleasant Grove','Pleasant Grove','CA'),('US','YPH','Philomath','Philomath','OR'),('US','YPI','Pine Island','Pine Island','MN'),('US','YPN','Pine Bush','Pine Bush','NY'),('US','YPO','Claypool','Claypool','IN'),('US','YPP','Prospect','Prospect','NJ'),('US','YPR','Port Republic','Port Republic','VA'),('US','YPS','Ypsilanti','Ypsilanti','MI'),('US','YPT','Peyton','Peyton','CO'),('US','YPV','Poplarville','Poplarville','MS'),('US','YPW','Pownal','Pownal','VT'),('US','YRA','Syracuse','Syracuse','NE'),('US','YRB','Barry','Barry','IL'),('US','YRD','Runnemede','Runnemede','NJ'),('US','YRE','Morehouse','Morehouse','MO'),('US','YRF','Ruffin','Ruffin','SC'),('US','YRG','Ragland','Ragland','AL'),('US','YRI','Rainbow','Rainbow','AL'),('US','YRK','York','York','AL'),('US','YRL','Yorklyn','Yorklyn','DE'),('US','YRM','Byromville','Byromville','GA'),('US','YRN','York','York','NE'),('US','YRO','Raytown','Raytown','MO'),('US','YRP','Rapidan','Rapidan','VA'),('US','YRS','Riverside','Riverside','MO'),('US','YRT','Yorktown','Yorktown','IN'),('US','YRV','Yorkville','Yorkville','IL'),('US','YRW','Sherwood','Sherwood','AR'),('US','YRY','Reynoldsville','Reynoldsville','PA'),('US','YSB','Sebree','Sebree','KY'),('US','YSD','Shedd','Shedd','OR'),('US','YSE','Seaside','Seaside','OR'),('US','YSG','Sandy Springs','Sandy Springs','GA'),('US','YSH','Shamokin','Shamokin','PA'),('US','YSI','Maysville','Maysville','WV'),('US','YSJ','Saint Joseph','Saint Joseph','LA'),('US','YSK','Smokey Point','Smokey Point','WA'),('US','YSL','Maysville','Maysville','OK'),('US','YSM','Smithville','Smithville','TN'),('US','YSP','Sproul','Sproul','PA'),('US','YSR','Saint Marys','Saint Marys','KS'),('US','YSS','Soda Springs','Soda Springs','ID'),('US','YST','Winchester','Winchester','WA'),('US','YSU','South Union','South Union','KY'),('US','YSV','Smelterville','Smelterville','ID'),('US','YSW','Sewell','Sewell','NJ'),('US','YSZ','San Lorenzo','San Lorenzo','CA'),('US','YTA','Tallassee, Elmore','Tallassee, Elmore','AL'),('US','YTB','Tinker Air Force Base','Tinker Air Force Base','OK'),('US','YTC','Tri-Cities','Tri-Cities','WA'),('US','YTH','Bothell','Bothell','WA'),('US','YTK','Myrtle Creek','Myrtle Creek','OR'),('US','YTL','Talent','Talent','OR'),('US','YTN','Clayton','Clayton','MI'),('US','YTO','Tomhicken','Tomhicken','PA'),('US','YTP','Research Triangle Park','Research Triangle Park','NC'),('US','YTR','Trenton','Trenton','LA'),('US','YTS','Saint Marys','Saint Marys','KS'),('US','YTU','Turner','Turner','OR'),('US','YTV','Yountville','Yountville','CA'),('US','YTW','Youngstown','Youngstown','NY'),('US','YTY','Troy','Troy','PA'),('US','YUB','Yuba City','Yuba City','CA'),('US','YUC','Yucaipa','Yucaipa','CA'),('US','YUG','Union Gap','Union Gap','WA'),('US','YUL','Yulee','Yulee','FL'),('US','YUM','Yuma','Yuma','AZ'),('US','YUN','Union','Union','ME'),('US','YUP','Upper Brookville','Upper Brookville','NY'),('US','YUR','Gettysburg','Gettysburg','OH'),('US','YUU','Bingham Canyon','Bingham Canyon','UT'),('US','YVA','Vale','Vale','OR'),('US','YVB','Van Buren','Van Buren','MO'),('US','YVD','Selbyville','Selbyville','DE'),('US','YVE','Yalesville','Yalesville','CT'),('US','YVF','Maynardville','Maynardville','TN'),('US','YVI','Vashon Island','Vashon Island','WA'),('US','YVL','Youngsville','Youngsville','NC'),('US','YVP','Pinckneyville','Pinckneyville','IL'),('US','YVR','Varnell','Varnell','GA'),('US','YWA','Willacoochee','Willacoochee','GA'),('US','YWB','Webster','Webster','MN'),('US','YWD','Ward','Ward','SC'),('US','YWE','West Homestead','West Homestead','PA'),('US','YWF','Warfordsburg','Warfordsburg','PA'),('US','YWH','Whately','Whately','MA'),('US','YWI','Wilcox','Wilcox','PA'),('US','YWN','Wauna','Wauna','WA'),('US','YWQ','Watonga','Watonga','OK'),('US','YWR','Woolrich','Woolrich','PA'),('US','YWS','Williamstown','Williamstown','WV'),('US','YWT','Winthrop','Winthrop','IA'),('US','YXG','Walnut Grove','Walnut Grove','CA'),('US','YXV','Vincent','Vincent','AL'),('US','YYC','Sycamore','Sycamore','GA'),('US','YYT','West Tisbury','West Tisbury','MA'),('US','YYU','Richfield','Richfield','NC'),('US','YZA','Arringtom','Arringtom','VA'),('US','ZAD','Alvarado','Alvarado','TX'),('US','ZAE','Adel','Adel','IA'),('US','ZAF','American Fork','American Fork','UT'),('US','ZAH','Amherst','Amherst','OH'),('US','ZAL','Waverly Hall','Waverly Hall','GA'),('US','ZAN','Mabton','Mabton','WA'),('US','ZAO','Taintor','Taintor','IA'),('US','ZAP','Apollo','Apollo','PA'),('US','ZAT','Arlington','Arlington','MA'),('US','ZAY','Marcy','Marcy','NY'),('US','ZBB','Bald Knob','Bald Knob','AR'),('US','ZBC','Bala-Cynwyd','Bala-Cynwyd','PA'),('US','ZBE','Berlin, Holmes','Berlin, Holmes','OH'),('US','ZBF','Bellefonte','Bellefonte','PA'),('US','ZBH','Brookhaven','Brookhaven','NY'),('US','ZBI','Bolton Landing','Bolton Landing','NY'),('US','ZBK','Rhinebeck','Rhinebeck','NY'),('US','ZBL','Zebulon','Zebulon','NC'),('US','ZBM','Belmont','Belmont','PA'),('US','ZBN','Baldwin','Baldwin','IL'),('US','ZBO','Benton','Benton','KY'),('US','ZBP','Bastrop','Bastrop','TX'),('US','ZBR','S.Burlington','S.Burlington','VT'),('US','ZBT','Butner','Butner','NC'),('US','ZBU','Burley','Burley','ID'),('US','ZBV','Burkesville','Burkesville','KY'),('US','ZBW','Baldwin','Baldwin','WI'),('US','ZBY','Boyce','Boyce','VA'),('US','ZCA','Carmel','Carmel','CA'),('US','ZCB','Cibolo','Cibolo','TX'),('US','ZCC','Clara City','Clara City','MN'),('US','ZCD','Camden','Camden','NY'),('US','ZCE','Creedmoor','Creedmoor','NC'),('US','ZCG','Childersburg','Childersburg','AL'),('US','ZCH','Cedar Hill','Cedar Hill','TX'),('US','ZCL','Clearfield','Clearfield','PA'),('US','ZCM','Cameron','Cameron','WI'),('US','ZCP','Coopersville','Coopersville','MI'),('US','ZCR','Crane','Crane','IN'),('US','ZCS','Clawson','Clawson','MI'),('US','ZCT','Centralia','Centralia','MO'),('US','ZCU','Cumberland','Cumberland','WI'),('US','ZCV','Coal Valley','Coal Valley','IL'),('US','ZCX','Center, Limestone','Center, Limestone','TX'),('US','ZCY','Clancy','Clancy','MT'),('US','ZCZ','Cazenovia','Cazenovia','NY'),('US','ZDC','Clarendon Heights','Clarendon Heights','PA'),('US','ZDE','Dolores','Dolores','CO'),('US','ZDG','West Reading','West Reading','PA'),('US','ZDN','Denton','Denton','MD'),('US','ZDQ','Duquesne','Duquesne','PA'),('US','ZDS','Sands Point','Sands Point','NY'),('US','ZDZ','Dutzow','Dutzow','MO'),('US','ZEC','Commerce','Commerce','GA'),('US','ZEF','East Falmouth','East Falmouth','MA'),('US','ZEG','Elgin','Elgin','TX'),('US','ZEH','Helen','Helen','GA'),('US','ZEI','Berlin Corners','Berlin Corners','VT'),('US','ZEK','Marksville','Marksville','LA'),('US','ZEL','Zelienople','Zelienople','PA'),('US','ZEM','Elkmont','Elkmont','AL'),('US','ZEN','Ellettsville','Ellettsville','IN'),('US','ZEO','Excelsior Springs','Excelsior Springs','MO'),('US','ZEP','East Walpole','East Walpole','MA'),('US','ZER','Chester Center','Chester Center','MA'),('US','ZET','Ellington','Ellington','CT'),('US','ZEV','Ellaville','Ellaville','GA'),('US','ZEW','Ellenwood','Ellenwood','GA'),('US','ZFC','Zephyr Cove','Zephyr Cove','NV'),('US','ZFG','Fargo','Fargo','IL'),('US','ZFI','Fisher Island, Miami','Fisher Island, Miami','FL'),('US','ZFL','Fulton','Fulton','IL'),('US','ZFM','Fruitland','Fruitland','MD'),('US','ZFO','Franconia','Franconia','VA'),('US','ZFP','Friendship','Friendship','MD'),('US','ZFV','Fowlerville','Fowlerville','MI'),('US','ZFY','Fayette','Fayette','MO'),('US','ZGE','Glidden','Glidden','WI'),('US','ZGF','Peekskill','Peekskill','NY'),('US','ZGG','Beggs','Beggs','OK'),('US','ZGH','Greenbush','Greenbush','MN'),('US','ZGL','Zieglerville','Zieglerville','PA'),('US','ZGN','North Grosvenor Dale','North Grosvenor Dale','CT'),('US','ZGO','Groton','Groton','CT'),('US','ZGQ','Galeton','Galeton','PA'),('US','ZGR','Granger','Granger','IN'),('US','ZGS','Great Falls','Great Falls','VA'),('US','ZGT','Charleston Heights','Charleston Heights','SC'),('US','ZGU','Ferguson','Ferguson','MO'),('US','ZHB','Sabetha','Sabetha','KS'),('US','ZHE','Okarche','Okarche','OK'),('US','ZHG','Huntington Station','Huntington Station','NY'),('US','ZHK','Holbrook','Holbrook','NY'),('US','ZHM','Hilmar','Hilmar','CA'),('US','ZHO','China','China','TX'),('US','ZHS','Harrison','Harrison','NY'),('US','ZHT','Hoisington','Hoisington','KS'),('US','ZHU','Hasbrouck Heights','Hasbrouck Heights','NJ'),('US','ZHV','Hanover','Hanover','NH'),('US','ZHW','Harwood','Harwood','MD'),('US','ZHY','West Hurley','West Hurley','NY'),('US','ZHZ','Hope','Hope','MN'),('US','ZIC','Rickreall','Rickreall','OR'),('US','ZIE','Zimmerman','Zimmerman','MN'),('US','ZIF','Alturas','Alturas','CA'),('US','ZIK','Inkom','Inkom','ID'),('US','ZIL','Zillah','Zillah','WA'),('US','ZIO','Zion','Zion','IL'),('US','ZIR','Irondale','Irondale','AL'),('US','ZIW','Winter Springs','Winter Springs','FL'),('US','ZJP','Jasper','Jasper','GA'),('US','ZJS','Jersey Shore','Jersey Shore','PA'),('US','ZKB','Kings Bay','Kings Bay','GA'),('US','ZKN','Dickson','Dickson','TN'),('US','ZKR','Parker','Parker','CO'),('US','ZKT','Kouts','Kouts','IN'),('US','ZLB','Bartlett','Bartlett','NH'),('US','ZLC','Lincolnton','Lincolnton','GA'),('US','ZLD','Zeeland','Zeeland','MI'),('US','ZLE','Southlake','Southlake','TX'),('US','ZLF','Linfield','Linfield','PA'),('US','ZLG','Lake Garfield','Lake Garfield','FL'),('US','ZLI','Lancaster','Lancaster','WI'),('US','ZLM','Salem','Salem','UT'),('US','ZLN','Lindon','Lindon','UT'),('US','ZLP','Circle Pines','Circle Pines','MN'),('US','ZLT','League City','League City','TX'),('US','ZLV','Longview','Longview','TX'),('US','ZLW','Longmeadow','Longmeadow','MA'),('US','ZMC','Mendota','Mendota','CA'),('US','ZMD','Seminole','Seminole','OK'),('US','ZMG','Miami Gardens','Miami Gardens','FL'),('US','ZMI','Mathis','Mathis','TX'),('US','ZML','Mellen','Mellen','WI'),('US','ZMM','Mounts Mills','Mounts Mills','NJ'),('US','ZMN','Manchester','Manchester','MD'),('US','ZMO','Montecito','Montecito','CA'),('US','ZMP','Newburyport','Newburyport','MA'),('US','ZMQ','Manasquan','Manasquan','NJ'),('US','ZMU','Murphy','Murphy','NC'),('US','ZMV','Melville','Melville','NY'),('US','ZMW','Muldrow','Muldrow','OK'),('US','ZMX','Mission','Mission','TX'),('US','ZMY','Manheim Center','Manheim Center','NY'),('US','ZNA','Newark','Newark','MO'),('US','ZNC','Nyac','Nyac','AK'),('US','ZND','Woodland','Woodland','PA'),('US','ZNE','Newville','Newville','PA'),('US','ZNF','Newton Falls','Newton Falls','OH'),('US','ZNG','Lagrange','Lagrange','OH'),('US','ZNH','Tenants Harbour','Tenants Harbour','ME'),('US','ZNM','Milton','Milton','WV'),('US','ZNO','Norwood','Norwood','NY'),('US','ZNP','Newport','Newport','CA'),('US','ZNR','North Royalton','North Royalton','OH'),('US','ZNT','Tryon','Tryon','NC'),('US','ZNV','Nashville','Nashville','AR'),('US','ZOA','Odessa','Odessa','NE'),('US','ZOC','Oakland City','Oakland City','IN'),('US','ZOD','Oviedo','Oviedo','FL'),('US','ZOE','Owen','Owen','WI'),('US','ZOH','Mohnton','Mohnton','PA'),('US','ZOI','Charleroi','Charleroi','PA'),('US','ZOK','Onalaska','Onalaska','WI'),('US','ZON','Alorton','Alorton','IL'),('US','ZOO','Millbrook','Millbrook','NY'),('US','ZOP','Satsop','Satsop','WA'),('US','ZOR','Sarasota','Sarasota','FL'),('US','ZOS','Stockton','Stockton','NJ'),('US','ZOT','Olivette','Olivette','MO'),('US','ZOV','Oakwood Village','Oakwood Village','OH'),('US','ZOW','Ooltewah','Ooltewah','TN'),('US','ZPA','Patterson','Patterson','LA'),('US','ZPB','Pembroke Park','Pembroke Park','FL'),('US','ZPC','Philipsburg','Philipsburg','PA'),('US','ZPG','Phillipsburg','Phillipsburg','NY'),('US','ZPH','Zephyrhills','Zephyrhills','FL'),('US','ZPI','Pawleys Island','Pawleys Island','SC'),('US','ZPL','Spring Lake','Spring Lake','MI'),('US','ZPM','Primm','Primm','NV'),('US','ZPP','Hollsopple','Hollsopple','PA'),('US','ZPT','Portageville','Portageville','NY'),('US','ZPU','Maple Bluff','Maple Bluff','WI'),('US','ZPW','Powhatan','Powhatan','VA'),('US','ZPY','Palmyra','Palmyra','WI'),('US','ZQC','Clinchfield','Clinchfield','GA'),('US','ZQE','Quarryville','Quarryville','PA'),('US','ZQK','Zachary','Zachary','LA'),('US','ZQU','Queen City','Queen City','TX'),('US','ZQZ','Coalfield','Coalfield','TN'),('US','ZRB','Riverbank','Riverbank','CA'),('US','ZRC','Cramerton','Cramerton','NC'),('US','ZRE','Rowlett','Rowlett','TX'),('US','ZRH','Center Hill','Center Hill','FL'),('US','ZRK','Seal Rock','Seal Rock','OR'),('US','ZRM','Manchester','Manchester','MA'),('US','ZRN','Harrison','Harrison','OH'),('US','ZRO','Rochdale','Rochdale','MA'),('US','ZRR','Carrboro','Carrboro','NC'),('US','ZRU','Marmaduke','Marmaduke','AR'),('US','ZRW','Ridgeway','Ridgeway','SC'),('US','ZRY','Rye','Rye','NY'),('US','ZSA','Salem','Salem','AL'),('US','ZSB','Stevensburg','Stevensburg','VA'),('US','ZSD','Sutherland','Sutherland','VA'),('US','ZSE','Summerville','Summerville','GA'),('US','ZSG','Spring Grove','Spring Grove','PA'),('US','ZSH','St Stephen','St Stephen','SC'),('US','ZSI','San Acacio','San Acacio','CO'),('US','ZSM','Smiths','Smiths','NC'),('US','ZSO','Sherborn','Sherborn','MA'),('US','ZSP','Stephen','Stephen','MN'),('US','ZSR','Sparta','Sparta','NC'),('US','ZST','Stormville','Stormville','NY'),('US','ZSU','Sugarcreek','Sugarcreek','OH'),('US','ZTB','East Bloomfield','East Bloomfield','NY'),('US','ZTG','Tangent','Tangent','OR'),('US','ZTK','Winnetka','Winnetka','IL'),('US','ZTN','Stoughton','Stoughton','WI'),('US','ZTP','White Pine','White Pine','MI'),('US','ZTR','Tillar','Tillar','AR'),('US','ZTU','Toughkenamon','Toughkenamon','PA'),('US','ZUC','Union Center','Union Center','WI'),('US','ZUM','Zumbrota','Zumbrota','MN'),('US','ZUO','Codorus','Codorus','PA'),('US','ZUT','Rutherford','Rutherford','TN'),('US','ZVB','Brownsville','Brownsville','WI'),('US','ZVG','Granville','Granville','IL'),('US','ZVL','Seville','Seville','OH'),('US','ZVV','Valley View','Valley View','OH'),('US','ZVY','Eden Valley','Eden Valley','MN'),('US','ZWA','Waterloo','Waterloo','WI'),('US','ZWC','New Columbia','New Columbia','PA'),('US','ZWD','Zellwood','Zellwood','FL'),('US','ZWG','Worthington','Worthington','WV'),('US','ZWH','Whitehouse','Whitehouse','NJ'),('US','ZWK','Wyckoff','Wyckoff','NJ'),('US','ZWM','McEwen','McEwen','TN'),('US','ZWO','Willow Springs','Willow Springs','MO'),('US','ZWS','Whitestone','Whitestone','GA'),('US','ZWV','Wadesville','Wadesville','IN'),('US','ZXE','Mer Rouge','Mer Rouge','LA'),('US','ZXO','Oxford','Oxford','PA'),('US','ZXX','Colton','Colton','OR'),('US','ZYB','Woodbury','Woodbury','GA'),('US','ZYF','Forsyth','Forsyth','GA'),('US','ZYH','York Harbor','York Harbor','ME'),('US','ZYI','Tybee Island','Tybee Island','GA'),('US','ZYK','Keysville','Keysville','MD'),('US','ZYN','Cheyenne Wells','Cheyenne Wells','CO'),('US','ZYS','Salisbury','Salisbury','CT'),('US','ZYT','Ladysmith','Ladysmith','WI'),('US','ZYV','Zionsville','Zionsville','PA'),('US','ZYY','Suttons Bay','Suttons Bay','MI'),('US','ZZB','Bogart','Bogart','GA'),('US','ZZH','Northport','Northport','MI'),('US','ZZL','Zionsville','Zionsville','IN'),('US','ZZM','South Amboy','South Amboy','NJ'),('US','ZZR','Cedar Hill','Cedar Hill','TX'),('US','ZZV','Zanesville','Zanesville','OH'),('UY','','','',''),('UY','ATI','Artigas','Artigas',''),('UY','BUV','Bella Union','Bella Union',''),('UY','CAN','Canelones','Canelones',''),('UY','CAR','Carmelo','Carmelo',''),('UY','CDS','Colonia del Sacramento','Colonia del Sacramento',''),('UY','CHY','Chuy','Chuy',''),('UY','CLZ','Colonia Suiza','Colonia Suiza',''),('UY','CYR','Colonia','Colonia',''),('UY','DZO','Durazno','Durazno',''),('UY','FDA','Florida','Florida',''),('UY','FZB','Fray Bentos','Fray Bentos',''),('UY','JIT','Jose Ignacio Terminal','Jose Ignacio Terminal',''),('UY','LAG','Lagomar','Lagomar',''),('UY','LAP','La Paloma/Rocha','La Paloma/Rocha',''),('UY','LPS','Las Piedras','Las Piedras',''),('UY','LPZ','La Paz','La Paz',''),('UY','MDO','Maldonado','Maldonado',''),('UY','MER','Mercedes','Mercedes',''),('UY','MIN','Minas','Minas',''),('UY','MLZ','Melo','Melo',''),('UY','MVD','Montevideo','Montevideo',''),('UY','NVP','Nueva Palmira','Nueva Palmira',''),('UY','PDO','Pando','Pando',''),('UY','PDP','Punta del Este','Punta del Este',''),('UY','PDU','Paysandu','Paysandu',''),('UY','PRB','Poblado Rincon de la Bolsa','Poblado Rincon de la Bolsa',''),('UY','RCH','Rocha','Rocha',''),('UY','RVY','Rivera','Rivera',''),('UY','SJC','San Jose de Carrasco','San Jose de Carrasco',''),('UY','SJS','San Jose','San Jose',''),('UY','STY','Salto','Salto',''),('UY','SYM','Solymar','Solymar',''),('UY','TAW','Tacuarembo','Tacuarembo',''),('UY','TRI','Trinidad','Trinidad',''),('UY','TYT','Treinta y Tres','Treinta y Tres',''),('UY','VCH','Vichadero','Vichadero',''),('UZ','','','',''),('UZ','AGN','Oharangon','Oharangon',''),('UZ','AKT','Akaltyn','Akaltyn',''),('UZ','ALK','Almalyk','Almalyk',''),('UZ','AZN','Andizhan','Andizhan',''),('UZ','BHK','Bukhara','Bukhara',''),('UZ','CHU','Chukur-Say','Chukur-Say',''),('UZ','FEG','Fergana','Fergana',''),('UZ','GST','Guliston','Guliston',''),('UZ','JIZ','Jizzakh','Jizzakh',''),('UZ','KBZ','Karaulbazar','Karaulbazar',''),('UZ','KKH','Khanabad','Khanabad',''),('UZ','KOK','Kokand','Kokand',''),('UZ','KSQ','Karshi','Karshi',''),('UZ','MGN','Marghilon','Marghilon',''),('UZ','NCU','Nukus','Nukus',''),('UZ','NMA','Namangan','Namangan',''),('UZ','NWY','Nawoiy','Nawoiy',''),('UZ','SKD','Samarkand','Samarkand',''),('UZ','SYA','Sary-Assiya','Sary-Assiya',''),('UZ','TAS','Tashkent','Tashkent',''),('UZ','TER','Termez','Termez',''),('UZ','UGC','Urganch (Urgench)','Urganch (Urgench)',''),('UZ','ULU','Ulugbek','Ulugbek',''),('UZ','ZAR','Zarafshon','Zarafshon',''),('VA','','','',''),('VA','VAT','Vatican City','Vatican City',''),('VC','','','',''),('VC','BQU','Port Elizabeth, Bequia','Port Elizabeth, Bequia',''),('VC','CRP','Camden Park','Camden Park',''),('VC','GRG','Georgetown','Georgetown',''),('VC','KTN','Kingstown','Kingstown',''),('VC','MQS','Mustique Island','Mustique Island',''),('VC','SVD','St Vincent','St Vincent',''),('VC','UNI','Union Island','Union Island',''),('VE','','','',''),('VE','AAO','Anaco','Anaco',''),('VE','AGU','Aragua de Barcelona','Aragua de Barcelona',''),('VE','AGV','Acarigua','Acarigua',''),('VE','AMY','Amuay','Amuay',''),('VE','ANT','San Antonio de Los Altos','San Antonio de Los Altos',''),('VE','ARA','Araya','Araya',''),('VE','BAV','Bachaquero/Maracaibo L','Bachaquero/Maracaibo L',''),('VE','BJV','Bajo Grande/Maracaibo L','Bajo Grande/Maracaibo L',''),('VE','BLA','Barcelona','Barcelona',''),('VE','BNS','Barinas','Barinas',''),('VE','BRM','Barquisimeto','Barquisimeto',''),('VE','CAJ','Canaima','Canaima',''),('VE','CAR','Caripito','Caripito',''),('VE','CBL','Ciudad Bolivar','Ciudad Bolivar',''),('VE','CBS','Cabimas/Maracaibo L','Cabimas/Maracaibo L',''),('VE','CCS','Caracas','Caracas',''),('VE','CGU','Ciudad Guayana','Ciudad Guayana',''),('VE','CHV','Chichiriviche','Chichiriviche',''),('VE','CLM','Catia La Mar','Catia La Mar',''),('VE','CLZ','Calabozo','Calabozo',''),('VE','CMR','Cumarebo','Cumarebo',''),('VE','COL','Coloncha','Coloncha',''),('VE','CUM','Cumana','Cumana',''),('VE','CUP','Carupano','Carupano',''),('VE','CUV','Casigua','Casigua',''),('VE','CXA','Caicara de Orinoco','Caicara de Orinoco',''),('VE','CZE','Coro','Coro',''),('VE','EGU','El Guamache','El Guamache',''),('VE','ELP','El Palito','El Palito',''),('VE','ELX','El Tigre','El Tigre',''),('VE','EOR','El Dorado','El Dorado',''),('VE','EOZ','Elorza','Elorza',''),('VE','ETV','El Tablazo/Maracaibo L','El Tablazo/Maracaibo L',''),('VE','GCR','Guacara','Guacara',''),('VE','GDO','Guasdualito','Guasdualito',''),('VE','GGU','Guaraguao','Guaraguao',''),('VE','GUA','Guaranao','Guaranao',''),('VE','GUB','Guaranao Bay','Guaranao Bay',''),('VE','GUI','Guiria','Guiria',''),('VE','GUQ','Guanare','Guanare',''),('VE','GUT','Guanta','Guanta',''),('VE','ICA','Icabaru','Icabaru',''),('VE','IDM','Isla de Margarita','Isla de Margarita',''),('VE','JMV','Jose Maria Vargas','Jose Maria Vargas',''),('VE','JOT','Jose Terminal','Jose Terminal',''),('VE','KAV','Kanavayen','Kanavayen',''),('VE','KTV','Kamarata','Kamarata',''),('VE','LAG','La Guaira','La Guaira',''),('VE','LAM','Lama','Lama',''),('VE','LCV','La Ceiba/Maracaibo L','La Ceiba/Maracaibo L',''),('VE','LEC','La Estacada','La Estacada',''),('VE','LFR','La Fria','La Fria',''),('VE','LGY','Lagunillas','Lagunillas',''),('VE','LMA','Las Morochas','Las Morochas',''),('VE','LPJ','Los Pijiguaos','Los Pijiguaos',''),('VE','LRV','Los Roques','Los Roques',''),('VE','LSP','Las Piedras','Las Piedras',''),('VE','LSV','La Salina/Maracaibo L','La Salina/Maracaibo L',''),('VE','LTQ','Los Teques','Los Teques',''),('VE','LVL','La Vela de Coro','La Vela de Coro',''),('VE','MAI','Maiquetia','Maiquetia',''),('VE','MAR','Maracaibo','Maracaibo',''),('VE','MGT','Margarita','Margarita',''),('VE','MIV','Puerto Miranda/Maracaibo L.','Puerto Miranda/Maracaibo L.',''),('VE','MRD','Merida','Merida',''),('VE','MTV','Matanzas','Matanzas',''),('VE','MUN','Maturin','Maturin',''),('VE','MYC','Maracay','Maracay',''),('VE','PAM','Pamatacual','Pamatacual',''),('VE','PAR','Paradero','Paradero',''),('VE','PBL','Puerto Cabello','Puerto Cabello',''),('VE','PCA','Punta Camacho','Punta Camacho',''),('VE','PCN','Punta Cardon','Punta Cardon',''),('VE','PCO','Puerto Carenero','Puerto Carenero',''),('VE','PCU','Punta Cuchillo','Punta Cuchillo',''),('VE','PCZ','Puerto La Cruz','Puerto La Cruz',''),('VE','PFI','Punto Fijo','Punto Fijo',''),('VE','PHO','Puerto de Hierro','Puerto de Hierro',''),('VE','PLA','Palua','Palua',''),('VE','PLV','Punta de Palmas','Punta de Palmas',''),('VE','PMP','Pampatar','Pampatar',''),('VE','PMR','Palmarejo/Maracaibo L.','Palmarejo/Maracaibo L.',''),('VE','PMV','Porlamar','Porlamar',''),('VE','PPD','Punta de Piedra','Punta de Piedra',''),('VE','PPH','Parai-tepui','Parai-tepui',''),('VE','PPS','Punta de Piedras','Punta de Piedras',''),('VE','PPZ','Puerto Paez','Puerto Paez',''),('VE','PRG','Pertigalete','Pertigalete',''),('VE','PSU','Puerto Sucre','Puerto Sucre',''),('VE','PTM','Palmarito','Palmarito',''),('VE','PYH','Puerto Ayacucho','Puerto Ayacucho',''),('VE','PZO','Puerto Ordaz','Puerto Ordaz',''),('VE','QAA','Quanta','Quanta',''),('VE','SAT','San Antonio del Tachira','San Antonio del Tachira',''),('VE','SCA','San Carlos','San Carlos',''),('VE','SCI','San Cristobal','San Cristobal',''),('VE','SCR','Santa Cruz, Aragua','Santa Cruz, Aragua',''),('VE','SFD','San Fernando de Apure','San Fernando de Apure',''),('VE','SFX','San Felix','San Felix',''),('VE','SJM','San Juan de los Morros','San Juan de los Morros',''),('VE','SJQ','San Joaquin','San Joaquin',''),('VE','SLV','San Lorenzo/Maracaibo L','San Lorenzo/Maracaibo L',''),('VE','SNF','San Felipe','San Felipe',''),('VE','SNV','Santa Elena','Santa Elena',''),('VE','SOM','San Tome','San Tome',''),('VE','STB','Santa Cruz del Zulia','Santa Cruz del Zulia',''),('VE','STD','Santo Domingo','Santo Domingo',''),('VE','SVV','San Salvador de Paul Apt','San Salvador de Paul Apt',''),('VE','SVZ','San Antonio','San Antonio',''),('VE','TJV','Tia Juana/Maracaibo L','Tia Juana/Maracaibo L',''),('VE','TMO','Tumeremo','Tumeremo',''),('VE','TUR','Turiamo','Turiamo',''),('VE','TUV','Tucupita','Tucupita',''),('VE','URM','Uriman','Uriman',''),('VE','VCR','Carora','Carora',''),('VE','VDP','Valle De Pascua','Valle De Pascua',''),('VE','VIG','El Vigia','El Vigia',''),('VE','VLN','Valencia','Valencia',''),('VE','VLV','Valera','Valera',''),('VE','WOK','Wonken','Wonken',''),('VE','YUR','Urena','Urena',''),('VG','','','',''),('VG','EIS','Beef Island, Tortola','Beef Island, Tortola',''),('VG','NGD','Anegada','Anegada',''),('VG','NSX','N. Sound/Virgin Gorda','N. Sound/Virgin Gorda',''),('VG','RAD','Road Town, Tortola','Road Town, Tortola',''),('VG','TOV','Tortola','Tortola',''),('VG','VIJ','Virgin Gorda','Virgin Gorda',''),('VI','','','',''),('VI','AGL','Anguilla','Anguilla',''),('VI','CHA','Charlotte Amalie, St Thomas','Charlotte Amalie, St Thomas',''),('VI','CTD','Christiansted, St. Croix','Christiansted, St. Croix',''),('VI','CZB','Cruz Bay, St John','Cruz Bay, St John',''),('VI','FRD','Frederiksted, St. Croix','Frederiksted, St. Croix',''),('VI','HOC','Hovic','Hovic',''),('VI','LIB','Limetree Bay','Limetree Bay',''),('VI','PAX','Port Alucroix','Port Alucroix',''),('VI','SJN','St John, St Croix Is','St John, St Croix Is',''),('VI','STT','Saint Thomas','Saint Thomas',''),('VI','STX','Saint Croix','Saint Croix',''),('VN','','','',''),('VN','BAN','Cam Lam','Cam Lam',''),('VN','BEN','Benthuy','Benthuy',''),('VN','BHA','Bien Hoa','Bien Hoa',''),('VN','BIH','Binh Hoa','Binh Hoa',''),('VN','BNE','Ben Nghe','Ben Nghe',''),('VN','BNG','Ben Nghe','Ben Nghe',''),('VN','BSE','Bong Sen','Bong Sen',''),('VN','CLI','Cat Lai','Cat Lai',''),('VN','CLN','Cai Lan','Cai Lan',''),('VN','CLO','Culao','Culao',''),('VN','CPH','Cam Pha','Cam Pha',''),('VN','CRB','Camranh','Camranh',''),('VN','CUV','Cua Viet Port','Cua Viet Port',''),('VN','DAD','Da Nang','Da Nang',''),('VN','DNA','Dong Nai','Dong Nai',''),('VN','DOH','Dong Hoi','Dong Hoi',''),('VN','DTH','Dong Thap','Dong Thap',''),('VN','HAA','Hoai An','Hoai An',''),('VN','HAN','Hanoi','Hanoi',''),('VN','HAT','Ha Tinh','Ha Tinh',''),('VN','HCH','Hon Chong','Hon Chong',''),('VN','HIA','Hoi An','Hoi An',''),('VN','HNH','Bong Son','Bong Son',''),('VN','HON','Hongai','Hongai',''),('VN','HPH','Haiphong','Haiphong',''),('VN','HSN','Hai Son','Hai Son',''),('VN','HUI','Hue','Hue',''),('VN','IPH','Phuoc Long ICD','Phuoc Long ICD',''),('VN','ITX','Thu Duc/ICG Transimex','Thu Duc/ICG Transimex',''),('VN','KHI','Khanh Hoi','Khanh Hoi',''),('VN','KHU','Khonh Hung','Khonh Hung',''),('VN','LBT','Long Binh Tan','Long Binh Tan',''),('VN','MOC','Mong Cai','Mong Cai',''),('VN','MTH','My Thoi','My Thoi',''),('VN','MUT','My Tho','My Tho',''),('VN','NGH','Nghi Son','Nghi Son',''),('VN','NGT','Nghe Tinh','Nghe Tinh',''),('VN','NHA','Nha Trang','Nha Trang',''),('VN','NMD','Nam Dinh','Nam Dinh',''),('VN','NVT','Nguyen Van Troi Port','Nguyen Van Troi Port',''),('VN','PHA','Phan Rang','Phan Rang',''),('VN','PHG','Phuoc Long','Phuoc Long',''),('VN','PHH','Phan Thiet','Phan Thiet',''),('VN','PHL','Phuoe Le','Phuoe Le',''),('VN','PHU','Phu My','Phu My',''),('VN','QBH','Quang Binh','Quang Binh',''),('VN','QNH','Quang Ninh','Quang Ninh',''),('VN','QUL','Quang Long','Quang Long',''),('VN','QUT','Quang Tri','Quang Tri',''),('VN','RBE','Red Beach','Red Beach',''),('VN','RDG','Rang Dong','Rang Dong',''),('VN','RQU','Rao Qua','Rao Qua',''),('VN','SAD','Sa Dec','Sa Dec',''),('VN','SGN','Ho Chi Minh City','Ho Chi Minh City',''),('VN','SQH','Son La','Son La',''),('VN','TBB','Tuy Hoa','Tuy Hoa',''),('VN','TBH','Thai Binh','Thai Binh',''),('VN','TBI','Thang Binh','Thang Binh',''),('VN','TCG','Tan Cang','Tan Cang',''),('VN','TCN','Tan Canh','Tan Canh',''),('VN','THA','Thai Hoa','Thai Hoa',''),('VN','THO','Thanh Hoa','Thanh Hoa',''),('VN','THU','Thuan An','Thuan An',''),('VN','TNC','Tong Cang','Tong Cang',''),('VN','TNG','Thai Nguyen','Thai Nguyen',''),('VN','TTD','Tan Thuan Dong','Tan Thuan Dong',''),('VN','UIH','Qui Nhon','Qui Nhon',''),('VN','VCA','Can Tho','Can Tho',''),('VN','VIC','Ho Chi Minh, VICT','Ho Chi Minh, VICT',''),('VN','VLG','Vinh Long','Vinh Long',''),('VN','VLO','Vinh Loi','Vinh Loi',''),('VN','VNH','Vinh','Vinh',''),('VN','VPH','Van Phong','Van Phong',''),('VN','VUT','Vung Tau','Vung Tau',''),('VN','XNG','Quang Ngai','Quang Ngai',''),('VU','','','',''),('VU','AUY','Aneityum','Aneityum',''),('VU','AWD','Aniwa','Aniwa',''),('VU','CCV','Craig Cove','Craig Cove',''),('VU','DLY','Dillon\'s Bay','Dillon\'s Bay',''),('VU','EAE','Emae','Emae',''),('VU','EPI','Epi','Epi',''),('VU','FTA','Futuna Island','Futuna Island',''),('VU','GBA','Big Bay','Big Bay',''),('VU','IPA','Ipota','Ipota',''),('VU','LNB','Lamen Bay','Lamen Bay',''),('VU','LNE','Lonorore','Lonorore',''),('VU','LOD','Longana','Longana',''),('VU','LPM','Lamap','Lamap',''),('VU','MTV','Mota Lava','Mota Lava',''),('VU','MWF','Maewo','Maewo',''),('VU','NUS','Norsup','Norsup',''),('VU','OLJ','Olpoi','Olpoi',''),('VU','PBJ','Paama','Paama',''),('VU','PSA','Port Sandwich','Port Sandwich',''),('VU','RCL','Redcliffe','Redcliffe',''),('VU','SAN','Santo','Santo',''),('VU','SLH','Sola','Sola',''),('VU','SON','Espiritu Santo','Espiritu Santo',''),('VU','SSR','Sara','Sara',''),('VU','SWJ','South West Bay','South West Bay',''),('VU','TAH','Tanna','Tanna',''),('VU','TGH','Tongoa','Tongoa',''),('VU','TOH','Torres','Torres',''),('VU','UIQ','Quine Hill','Quine Hill',''),('VU','ULB','Ulei','Ulei',''),('VU','VLI','Port Vila','Port Vila',''),('VU','VLS','Valesdir','Valesdir',''),('VU','WLH','Walaha','Walaha',''),('VU','ZGU','Gaua','Gaua',''),('WF','','','',''),('WF','FUT','Futuna Island Apt','Futuna Island Apt',''),('WF','MAU','Mata\'utu','Mata\'utu',''),('WF','SIG','Sigave','Sigave',''),('WF','WLS','Wallis Island Apt','Wallis Island Apt',''),('WS','','','',''),('WS','AAU','Asau','Asau',''),('WS','APW','Apia','Apia',''),('WS','LAV','Lalomalava','Lalomalava',''),('WS','MXS','Maota Savaii Is','Maota Savaii Is',''),('WS','SAL','Salelologa','Salelologa',''),('WS','SAV','Savaii','Savaii',''),('XZ','','','',''),('XZ','AAD','Aasgard','Aasgard',''),('XZ','ANT','Ardjuna','Ardjuna',''),('XZ','ANU','Anoa Natuna','Anoa Natuna',''),('XZ','BUV','Buffalo Venture','Buffalo Venture',''),('XZ','CMT','Camar Marine Terminal','Camar Marine Terminal',''),('XZ','DHS','Dai Hung (STS Load)','Dai Hung (STS Load)',''),('XZ','DHT','Dai Hung (Tandem Load)','Dai Hung (Tandem Load)',''),('XZ','DRA','Draugen','Draugen',''),('XZ','DTL','Dulang Marine Terminal','Dulang Marine Terminal',''),('XZ','HEI','Heidrun','Heidrun',''),('XZ','KMT','Kakap Marine Terminal','Kakap Marine Terminal',''),('XZ','LAM','Laminaria Terminal','Laminaria Terminal',''),('XZ','LGT','Legendre Terminal','Legendre Terminal',''),('XZ','NJO','Njord','Njord',''),('XZ','NNE','Norne','Norne',''),('XZ','NTE','Northern Endevour','Northern Endevour',''),('XZ','OCA','Co-operation Zone A (AU,ID)','Co-operation Zone A (AU,ID)',''),('XZ','SBY','Sibuko Bay','Sibuko Bay',''),('XZ','SHA','Al Shaheen terminal','Al Shaheen terminal',''),('XZ','STP','Stage Platform','Stage Platform',''),('XZ','TGR','Tandjung Gerem','Tandjung Gerem',''),('XZ','WRT','Widuri Marine Terminal','Widuri Marine Terminal',''),('XZ','YET','Yetagun Field','Yetagun Field',''),('YE','','','',''),('YE','AAY','Al Ghaydah','Al Ghaydah',''),('YE','ADE','Aden','Aden',''),('YE','AHW','Ahwar','Ahwar',''),('YE','AJO','Aljouf','Aljouf',''),('YE','ASR','Ash Shihr','Ash Shihr',''),('YE','AXK','Ataq','Ataq',''),('YE','BHN','Beihan','Beihan',''),('YE','BOG','Bogoa','Bogoa',''),('YE','BUK','Albuq','Albuq',''),('YE','BYD','Beidah','Beidah',''),('YE','DAH','Dathina','Dathina',''),('YE','DHL','Dhala','Dhala',''),('YE','DMR','Dhamar','Dhamar',''),('YE','EAB','Abbse','Abbse',''),('YE','ELK','El Katieb','El Katieb',''),('YE','GXF','Seiyun','Seiyun',''),('YE','HAR','Harad','Harad',''),('YE','HAU','Haura','Haura',''),('YE','HOD','Hodeidah','Hodeidah',''),('YE','IBB','Ibb','Ibb',''),('YE','IHN','Qishn','Qishn',''),('YE','KAM','Kamaran','Kamaran',''),('YE','KHO','Khokha','Khokha',''),('YE','LAD','Little Aden','Little Aden',''),('YE','LAW','Lawdar','Lawdar',''),('YE','LDR','Lodar','Lodar',''),('YE','LOH','Loheiya','Loheiya',''),('YE','MFY','Mayfa\'ah','Mayfa\'ah',''),('YE','MKX','Mukalla','Mukalla',''),('YE','MOK','Mokha','Mokha',''),('YE','MYN','Mareb','Mareb',''),('YE','NIS','Nishtun','Nishtun',''),('YE','PRM','Perim I.','Perim I.',''),('YE','RAI','Ras Isa Terminal','Ras Isa Terminal',''),('YE','RAK','Ras Al Kalib','Ras Al Kalib',''),('YE','RIY','Riyan Mukalla','Riyan Mukalla',''),('YE','RXA','Raudha','Raudha',''),('YE','SAH','Sana\'a','Sana\'a',''),('YE','SAL','Saleef Port','Saleef Port',''),('YE','SCT','Suqutra','Suqutra',''),('YE','SYE','Sadah','Sadah',''),('YE','TAI','Taiz','Taiz',''),('YE','UKR','Mukeiras','Mukeiras',''),('YT','','','',''),('YT','BAN','Bandele','Bandele',''),('YT','DZA','Dzaoudzi','Dzaoudzi',''),('YT','LON','Longoni','Longoni',''),('YT','MAM','Mamoudzou','Mamoudzou',''),('YT','SAD','Sada','Sada',''),('ZA','','','',''),('ZA','AAM','Mala Mala','Mala Mala',''),('ZA','ABT','Alberton','Alberton',''),('ZA','ADY','Alldays','Alldays',''),('ZA','AFD','Port Alfred','Port Alfred',''),('ZA','AGZ','Aggeneys','Aggeneys',''),('ZA','ALJ','Alexander Bay','Alexander Bay',''),('ZA','ALR','Alrode','Alrode',''),('ZA','AMZ','Amanzimtoti','Amanzimtoti',''),('ZA','AOB','Algoa Bay','Algoa Bay',''),('ZA','ATL','Atlantis','Atlantis',''),('ZA','BAR','Barrydale','Barrydale',''),('ZA','BBR','Beit Bridge','Beit Bridge',''),('ZA','BEL','Bellville','Bellville',''),('ZA','BEW','Beaufort West','Beaufort West',''),('ZA','BFN','Bloemfontein','Bloemfontein',''),('ZA','BFV','Bedfordview','Bedfordview',''),('ZA','BHT','Bronkhorstspruit','Bronkhorstspruit',''),('ZA','BIY','Bisho','Bisho',''),('ZA','BNI','Benoni','Benoni',''),('ZA','BOK','Boksburg','Boksburg',''),('ZA','BOT','BotrivIer','BotrivIer',''),('ZA','BRK','Brakpan','Brakpan',''),('ZA','BRL','Berlin','Berlin',''),('ZA','BRT','Brits','Brits',''),('ZA','BSN','Bryanston','Bryanston',''),('ZA','BTH','Bethlehem','Bethlehem',''),('ZA','BTV','Bothaville','Bothaville',''),('ZA','BYS','Booysens','Booysens',''),('ZA','CAT','Cato Ridge','Cato Ridge',''),('ZA','CDO','Cradock','Cradock',''),('ZA','CGN','Congella','Congella',''),('ZA','CHP','Chloorkop','Chloorkop',''),('ZA','CIT','Citrusdal','Citrusdal',''),('ZA','CMN','Camperdown','Camperdown',''),('ZA','CNA','Cullinan','Cullinan',''),('ZA','CPT','Cape Town','Cape Town',''),('ZA','CRS','Ceres','Ceres',''),('ZA','CTD','City Deep','City Deep',''),('ZA','DCV','Duncanville/Vereeniging','Duncanville/Vereeniging',''),('ZA','DIU','Dimbaza','Dimbaza',''),('ZA','DLM','Delmas','Delmas',''),('ZA','DNN','Dunnottar','Dunnottar',''),('ZA','DON','Dalton','Dalton',''),('ZA','DUK','Dukuduk','Dukuduk',''),('ZA','DUN','Dunswart/Boksburg','Dunswart/Boksburg',''),('ZA','DUR','Durban','Durban',''),('ZA','DVI','Durbanville','Durbanville',''),('ZA','EDE','Edenvale','Edenvale',''),('ZA','ELA','Elandsfontein','Elandsfontein',''),('ZA','ELG','Elgin','Elgin',''),('ZA','ELL','Ellisras','Ellisras',''),('ZA','ELS','East London','East London',''),('ZA','EMG','Empangeni','Empangeni',''),('ZA','ERM','Ermelo','Ermelo',''),('ZA','EST','Estcourt','Estcourt',''),('ZA','FBE','Fort Beaufort','Fort Beaufort',''),('ZA','FBG','Fordsburg','Fordsburg',''),('ZA','FCB','Ficksburg','Ficksburg',''),('ZA','GBU','Groenbult','Groenbult',''),('ZA','GIY','Giyani','Giyani',''),('ZA','GRB','Grabouw','Grabouw',''),('ZA','GRJ','George','George',''),('ZA','GRM','Germiston','Germiston',''),('ZA','GRW','Graafwater','Graafwater',''),('ZA','GRY','Greytown','Greytown',''),('ZA','GSS','Sabi Sabi','Sabi Sabi',''),('ZA','HAL','Halfway House','Halfway House',''),('ZA','HBL','Babelegi','Babelegi',''),('ZA','HDL','Heriotdale/Johannesburg','Heriotdale/Johannesburg',''),('ZA','HDS','Hoedspruit','Hoedspruit',''),('ZA','HEI','Heidelberg','Heidelberg',''),('ZA','HGT','Huguenot','Huguenot',''),('ZA','HIL','Hillcrest','Hillcrest',''),('ZA','HLA','Lanseria','Lanseria',''),('ZA','HLW','Hluhluwe','Hluhluwe',''),('ZA','HMM','Hammarsdale','Hammarsdale',''),('ZA','HOW','Howick','Howick',''),('ZA','HRS','Harrismith','Harrismith',''),('ZA','HSL','Hammanskraal','Hammanskraal',''),('ZA','HZV','Hazyview','Hazyview',''),('ZA','INY','Inyati','Inyati',''),('ZA','ISB','Isithebe','Isithebe',''),('ZA','ISD','Isando','Isando',''),('ZA','ISP','Isipingo Beach','Isipingo Beach',''),('ZA','JEF','Jeffreys Bay','Jeffreys Bay',''),('ZA','JNB','Johannesburg','Johannesburg',''),('ZA','JOH','Port Saint John\'s','Port Saint John\'s',''),('ZA','KDB','Kidd\'s Beach','Kidd\'s Beach',''),('ZA','KDP','Krugersdorp','Krugersdorp',''),('ZA','KEW','Kew','Kew',''),('ZA','KHO','Khoka Moya','Khoka Moya',''),('ZA','KIG','Koiingnaas','Koiingnaas',''),('ZA','KIM','Kimberley','Kimberley',''),('ZA','KIR','Kirkwood','Kirkwood',''),('ZA','KLA','Klawer','Klawer',''),('ZA','KLZ','Kleinzee','Kleinzee',''),('ZA','KMH','Kuruman','Kuruman',''),('ZA','KMP','Kempton Park','Kempton Park',''),('ZA','KNY','Knysna','Knysna',''),('ZA','KOF','Komatipoort','Komatipoort',''),('ZA','KPM','Kaapmuiden','Kaapmuiden',''),('ZA','KST','Koster','Koster',''),('ZA','KTU','Kathu','Kathu',''),('ZA','KUI','Kuils River','Kuils River',''),('ZA','KWT','King William\'s Town','King William\'s Town',''),('ZA','KXE','Klerksdorp','Klerksdorp',''),('ZA','KYA','Kyalami','Kyalami',''),('ZA','LAY','Ladysmith','Ladysmith',''),('ZA','LCD','Louis Trichardt','Louis Trichardt',''),('ZA','LDE','Lansdowne','Lansdowne',''),('ZA','LDZ','Londolozi','Londolozi',''),('ZA','LLE','Malelane','Malelane',''),('ZA','LMR','Lime Acres','Lime Acres',''),('ZA','LTA','Tzaneen','Tzaneen',''),('ZA','LUJ','Lusikisiki','Lusikisiki',''),('ZA','MAH','Marble Hall','Marble Hall',''),('ZA','MAS','Maidstone','Maidstone',''),('ZA','MBD','Mmabatho','Mmabatho',''),('ZA','MBM','Mkambati','Mkambati',''),('ZA','MDB','Middelburg','Middelburg',''),('ZA','MEY','Meyerton','Meyerton',''),('ZA','MEZ','Messina','Messina',''),('ZA','MFK','Mafikeng','Mafikeng',''),('ZA','MGH','Margate','Margate',''),('ZA','MGL','Magaliesburg','Magaliesburg',''),('ZA','MND','Mandileni','Mandileni',''),('ZA','MOB','Mobeni','Mobeni',''),('ZA','MON','Montagu','Montagu',''),('ZA','MPA','Menlo Park','Menlo Park',''),('ZA','MRD','Midrand','Midrand',''),('ZA','MRH','Marianhill','Marianhill',''),('ZA','MWR','Motswari','Motswari',''),('ZA','MZF','Mzamba(Wild Coast Sun)','Mzamba(Wild Coast Sun)',''),('ZA','MZQ','Mkuze','Mkuze',''),('ZA','MZY','Mossel Bay','Mossel Bay',''),('ZA','NCF','Northcliff','Northcliff',''),('ZA','NCS','Newcastle','Newcastle',''),('ZA','NGL','Ngala','Ngala',''),('ZA','NLP','Nelspruit','Nelspruit',''),('ZA','NOL','Port Nolloth','Port Nolloth',''),('ZA','NTY','Sun City','Sun City',''),('ZA','NUF','Nuffield Springs','Nuffield Springs',''),('ZA','NYL','Nylstroom','Nylstroom',''),('ZA','OLI','Olifantsfontein','Olifantsfontein',''),('ZA','OSH','Oshoek','Oshoek',''),('ZA','OUH','Oudtshoorn','Oudtshoorn',''),('ZA','PAA','Paarl','Paarl',''),('ZA','PBZ','Plettenberg Bay','Plettenberg Bay',''),('ZA','PED','Port Edward','Port Edward',''),('ZA','PHU','Phuthaditjhaba','Phuthaditjhaba',''),('ZA','PHW','Phalaborwa','Phalaborwa',''),('ZA','PIK','Piketberg','Piketberg',''),('ZA','PLZ','Port Elizabeth','Port Elizabeth',''),('ZA','PNL','Paardeneiland','Paardeneiland',''),('ZA','PNT','Pinetown','Pinetown',''),('ZA','PON','Pongola','Pongola',''),('ZA','POR','Porterville','Porterville',''),('ZA','PRF','Piet Retief','Piet Retief',''),('ZA','PRK','Prieska','Prieska',''),('ZA','PRW','Parow','Parow',''),('ZA','PRY','Pretoria','Pretoria',''),('ZA','PTG','Pietersburg','Pietersburg',''),('ZA','PTN','Prospecton','Prospecton',''),('ZA','PZB','Pietermaritzburg','Pietermaritzburg',''),('ZA','RCB','Richards Bay','Richards Bay',''),('ZA','RDB','Randburg','Randburg',''),('ZA','RDP','Roodepoort','Roodepoort',''),('ZA','RFT','Randfontein','Randfontein',''),('ZA','RMB','Ramatlhabama','Ramatlhabama',''),('ZA','ROD','Robertson','Robertson',''),('ZA','ROS','Rosslyn','Rosslyn',''),('ZA','RSB','Rustenburg','Rustenburg',''),('ZA','RUS','Rustenburg','Rustenburg',''),('ZA','RVA','Rivonia','Rivonia',''),('ZA','RVO','Reivilo','Reivilo',''),('ZA','SAS','Sasolburg','Sasolburg',''),('ZA','SBU','Springbok','Springbok',''),('ZA','SCT','Scottburgh','Scottburgh',''),('ZA','SDB','Saldanha Bay','Saldanha Bay',''),('ZA','SDT','Sandton','Sandton',''),('ZA','SFB','St Francis Bay','St Francis Bay',''),('ZA','SGR','Stanger','Stanger',''),('ZA','SHS','Shakaskraal','Shakaskraal',''),('ZA','SIS','Sishen','Sishen',''),('ZA','SMN','Simon\'s Town','Simon\'s Town',''),('ZA','SOM','Somerset West','Somerset West',''),('ZA','SPR','Springs','Springs',''),('ZA','STC','Standerton','Standerton',''),('ZA','STD','Strand','Strand',''),('ZA','STH','Stellenbosch','Stellenbosch',''),('ZA','STN','Silverton','Silverton',''),('ZA','STU','Stutterheim','Stutterheim',''),('ZA','SWE','Swellendam','Swellendam',''),('ZA','SZK','Skukuza','Skukuza',''),('ZA','TCU','Thaba Nchu','Thaba Nchu',''),('ZA','TDT','Tanda Tula','Tanda Tula',''),('ZA','THY','Thohoyandou','Thohoyandou',''),('ZA','TNT','Tongaat','Tongaat',''),('ZA','TSD','Tshipise','Tshipise',''),('ZA','TUL','Tulbagh','Tulbagh',''),('ZA','UHG','Uitenhage','Uitenhage',''),('ZA','ULD','Ulundi','Ulundi',''),('ZA','ULX','Ulusaba','Ulusaba',''),('ZA','UMK','Umkomaas','Umkomaas',''),('ZA','UMR','Umhlanga Rocks','Umhlanga Rocks',''),('ZA','UMZ','Umzinto','Umzinto',''),('ZA','UTE','Butterworth','Butterworth',''),('ZA','UTN','Upington','Upington',''),('ZA','UTT','Umtata','Umtata',''),('ZA','UTW','Queenstown','Queenstown',''),('ZA','VAC','Vaalcon','Vaalcon',''),('ZA','VAL','Vaal','Vaal',''),('ZA','VDP','Vanderbijlpark','Vanderbijlpark',''),('ZA','VEU','Verulam','Verulam',''),('ZA','VGG','Vereeniging','Vereeniging',''),('ZA','VRE','Vredendal','Vredendal',''),('ZA','VRG','Vereeniging','Vereeniging',''),('ZA','VRU','Vryburg','Vryburg',''),('ZA','VXD','Viljoensdrif','Viljoensdrif',''),('ZA','VYD','Vryheid','Vryheid',''),('ZA','WDV','Wadeville','Wadeville',''),('ZA','WEL','Welkom','Welkom',''),('ZA','WFD','Witfield','Witfield',''),('ZA','WHR','White River','White River',''),('ZA','WIT','Witbank','Witbank',''),('ZA','WLT','Wellington','Wellington',''),('ZA','WNB','Wynberg','Wynberg',''),('ZA','WOR','Worcester','Worcester',''),('ZA','YFT','Yzerfontein','Yzerfontein',''),('ZA','ZEB','Zebediela','Zebediela',''),('ZA','ZEC','Secunda','Secunda',''),('ZM','','','',''),('ZM','BBZ','Zambezi','Zambezi',''),('ZM','CGJ','Chingola','Chingola',''),('ZM','CHA','Chachacha','Chachacha',''),('ZM','CHO','Choma','Choma',''),('ZM','CIP','Chipata','Chipata',''),('ZM','KAA','Kasama','Kasama',''),('ZM','KAF','Kafue','Kafue',''),('ZM','KAM','Kapiri Mposhi','Kapiri Mposhi',''),('ZM','KAO','Kalomo','Kalomo',''),('ZM','KIW','Kitwe','Kitwe',''),('ZM','KLB','Kalabo','Kalabo',''),('ZM','KMZ','Kaoma','Kaoma',''),('ZM','LUA','Luanshya','Luanshya',''),('ZM','LUM','Lumamba','Lumamba',''),('ZM','LUN','Lusaka','Lusaka',''),('ZM','LUZ','Lundazi','Lundazi',''),('ZM','LVI','Livingstone','Livingstone',''),('ZM','LXU','Lukulu','Lukulu',''),('ZM','MFR','Mufulira','Mufulira',''),('ZM','MFU','Mfuwe','Mfuwe',''),('ZM','MMQ','Mbala','Mbala',''),('ZM','MNR','Mongu','Mongu',''),('ZM','MNS','Mansa','Mansa',''),('ZM','MPU','Mpulungu','Mpulungu',''),('ZM','MRB','Maramba','Maramba',''),('ZM','MZE','Monze','Monze',''),('ZM','NLA','Ndola','Ndola',''),('ZM','QKE','Kabwe','Kabwe',''),('ZM','SJQ','Sesheke','Sesheke',''),('ZM','SLI','Solwezi','Solwezi',''),('ZM','SXG','Senanga','Senanga',''),('ZM','ZGM','Ngoma','Ngoma',''),('ZM','ZKB','Kasaba Bay','Kasaba Bay',''),('ZM','ZKP','Kasompe','Kasompe',''),('ZW','','','',''),('ZW','BAT','Bata','Bata',''),('ZW','BBG','Beitbridge','Beitbridge',''),('ZW','BFO','Buffalo Range','Buffalo Range',''),('ZW','BIN','Bindura','Bindura',''),('ZW','BUQ','Bulawayo','Bulawayo',''),('ZW','BZH','Bumi Hills','Bumi Hills',''),('ZW','CHI','Chiredzi','Chiredzi',''),('ZW','CHJ','Chipinge','Chipinge',''),('ZW','GWE','Gweru','Gweru',''),('ZW','HDL','Headlands','Headlands',''),('ZW','HRE','Harare','Harare',''),('ZW','HWN','Hwange National Park','Hwange National Park',''),('ZW','KAB','Kariba','Kariba',''),('ZW','KDM','Kadoma','Kadoma',''),('ZW','KWE','Kwekwe','Kwekwe',''),('ZW','MAD','Marondera','Marondera',''),('ZW','MJW','Mahenye','Mahenye',''),('ZW','MVZ','Masvingo','Masvingo',''),('ZW','STH','Southerton','Southerton',''),('ZW','UTA','Mutare','Mutare',''),('ZW','VFA','Victoria Falls','Victoria Falls',''),('ZW','WKI','Hwange','Hwange',''); +INSERT INTO `ISO_SUBDIVISION` VALUES ('AR','A','Salta\r'),('AR','B','Buenos Aires\r'),('AR','C','Distrito Federal\r'),('AR','D','San Luis\r'),('AR','E','Entre Ríos'),('AR','F','La Rioja\r'),('AR','G','Santiago del Estero\r'),('AR','H','Chaco\r'),('AR','J','San Juan\r'),('AR','K','Catamarca\r'),('AR','L','La Pampa\r'),('AR','M','Mendoza\r'),('AR','N','Misiones\r'),('AR','P','Formosa\r'),('AR','Q','Neuquén'),('AR','R','Río Negro'),('AR','S','Santa Fe\r'),('AR','T','Tucumán'),('AR','U','Chubut\r'),('AR','V','Tierra del Fuego\r'),('AR','W','Corrientes\r'),('AR','X','Córdoba'),('AR','Y','Jujuy\r'),('AR','Z','Santa Cruz\r'),('AU','CT','Australian Capital Territory\r'),('AU','NS','New South Wales\r'),('AU','NT','Northern Territory\r'),('AU','QL','Queensland\r'),('AU','SA','South Australia\r'),('AU','TS','Tasmania\r'),('AU','VI','Victoria\r'),('AU','WA','Western Australia\r'),('BE','BRU','Bruxelles-Capitale, Région de (fr), Brussels Hoofdstedelijk Gewest (nl)'),('BE','VAN','Antwerpen (VLG)\r'),('BE','VBR','Vlaams Brabant (VLG)\r'),('BE','VLG','Vlaamse Gewest (nl)\r'),('BE','VLI','Limburg (VLG)\r'),('BE','VOV','Oost-Vlaanderen (VLG)\r'),('BE','VWV','West-Vlaanderen (VLG)\r'),('BE','WAL','Wallonne, Région (fr)'),('BE','WBR','Brabant Wallon (WAL)\r'),('BE','WHT','Hainaut (WAL)\r'),('BE','WLG','Liège (WAL)'),('BE','WLX','Luxembourg (WAL)\r'),('BE','WNA','Namur (WAL)\r'),('BO','B','El Beni\r'),('BO','C','Cochabamba\r'),('BO','H','Chuquisaca\r'),('BO','L','La Paz\r'),('BO','N','Pando\r'),('BO','O','Oruro\r'),('BO','P','Potosí'),('BO','S','Santa Cruz\r'),('BO','T','Tarija\r'),('BR','AC','Acre\r'),('BR','AL','Alagoas\r'),('BR','AM','Amazonas\r'),('BR','AP','Amapá'),('BR','BA','Bahia\r'),('BR','CE','Ceará'),('BR','DF','Distrito Federal\r'),('BR','ES','Espírito Santo'),('BR','GO','Goiás'),('BR','MA','Maranhão'),('BR','MG','Minas Gerais\r'),('BR','MS','Mato Grosso do Sul\r'),('BR','MT','Mato Grosso\r'),('BR','PA','Pará'),('BR','PB','Paraíba'),('BR','PE','Pernambuco\r'),('BR','PI','Piauí'),('BR','PR','Paraná'),('BR','RJ','Rio de Janeiro\r'),('BR','RN','Rio Grande do Norte\r'),('BR','RO','Rondônia'),('BR','RR','Roraima\r'),('BR','RS','Rio Grande do Sul\r'),('BR','SC','Santa Catarina\r'),('BR','SE','Sergipe\r'),('BR','SP','São Paulo'),('BR','TO','Tocantins\r'),('CA','AB','Alberta\r'),('CA','BC','British Columbia\r'),('CA','MB','Manitoba\r'),('CA','NB','New Brunswick\r'),('CA','NL','Newfoundland and Labrador\r'),('CA','NS','Nova Scotia\r'),('CA','NT','Northwest Territories\r'),('CA','NU','Nunavut\r'),('CA','ON','Ontario\r'),('CA','PE','Prince Edward Island\r'),('CA','QC','Quebec\r'),('CA','SK','Saskatchewan\r'),('CA','YT','Yukon Territory\r'),('CH','AG','Aargau (de)\r'),('CH','AI','Appenzell Innerrhoden (de)\r'),('CH','AR','Appenzell Ausserrhoden (de)\r'),('CH','BE','Bern (de)\r'),('CH','BL','Basel-Landschaft (de)\r'),('CH','BS','Basel-Stadt (de)\r'),('CH','FR','Fribourg (fr)'),('CH','GE','Genève (fr)'),('CH','GL','Glarus (de)\r'),('CH','GR','Graubünden (de)'),('CH','JU','Jura (fr)\r'),('CH','LU','Luzern (de)\r'),('CH','NE','Neuchâtel (fr)'),('CH','NW','Nidwalden (de)\r'),('CH','OW','Obwalden (de)\r'),('CH','SG','Sankt Gallen (de)\r'),('CH','SH','Schaffhausen (de)\r'),('CH','SO','Solothurn (de)\r'),('CH','SZ','Schwyz (de)\r'),('CH','TG','Thurgau (de)\r'),('CH','TI','Ticino (it)\r'),('CH','UR','Uri (de)\r'),('CH','VD','Vaud (fr)\r'),('CH','VS','Valais (fr)\r'),('CH','ZG','Zug (de)\r'),('CH','ZH','Zürich (de)'),('CL','AI','Aisén del General Carlos Ibáñez del Campo'),('CL','AN','Antofagasta'),('CL','AR','La Araucanía'),('CL','AT','Atacama\r'),('CL','BI','Biobío'),('CL','CO','Coquimbo\r'),('CL','LI','Libertador General Bernardo O\'Higgins\r'),('CL','LL','Los Lagos\r'),('CL','MA','Magallanes\r'),('CL','ML','Maule\r'),('CL','RM','Regón Metropolitana de Santiago'),('CL','TA','Tarapacá'),('CL','VS','Valparaíso'),('CN','11','Beijing\r'),('CN','12','Tianjin\r'),('CN','13','Hebei\r'),('CN','14','Shanxi\r'),('CN','15','Nei Mongol (mn)\r'),('CN','21','Liaoning\r'),('CN','22','Jilin\r'),('CN','23','Heilongjiang\r'),('CN','31','Shanghai\r'),('CN','32','Jiangsu\r'),('CN','33','Zhejiang\r'),('CN','34','Anhui\r'),('CN','35','Fujian\r'),('CN','36','Jiangxi\r'),('CN','37','Shandong\r'),('CN','41','Henan\r'),('CN','42','Hubei\r'),('CN','43','Hunan\r'),('CN','44','Guangdong\r'),('CN','45','Guangxi\r'),('CN','46','Hainan\r'),('CN','50','Chongqing\r'),('CN','51','Sichuan\r'),('CN','52','Guizhou\r'),('CN','53','Yunnan\r'),('CN','54','Xizang\r'),('CN','61','Shaanxi\r'),('CN','62','Gansu\r'),('CN','63','Qinghai\r'),('CN','64','Ningxia\r'),('CN','65','Xinjiang\r'),('CN','71','Taiwan\r'),('CN','91','Xianggang\r'),('CN','92','Aomen\r'),('CR','A','Alajuela\r'),('CR','C','Cartago\r'),('CR','G','Guanacaste\r'),('CR','H','Heredia\r'),('CR','L','Limón'),('CR','P','Puntarenas\r'),('CR','SJ','San José'),('CS','CG','Crna Gora\r'),('CS','KM','Kosovo-Metohija\r'),('CS','SR','Srbija\r'),('CS','VO','Vojvodina\r'),('DE','BE','Berlin\r'),('DE','BR','Brandenburg\r'),('DE','BW','Baden-Württemberg'),('DE','BY','Bayern\r'),('DE','HB','Bremen (Hansestadt)\r'),('DE','HE','Hessen\r'),('DE','HH','Hamburg (Hansestadt)\r'),('DE','MV','Mecklenburg-Vorpommern\r'),('DE','NI','Niedersachsen\r'),('DE','NW','Nordrhein-Westfalen\r'),('DE','RP','Rheinland-Pfalz\r'),('DE','SH','Schleswig-Holstein\r'),('DE','SL','Saarland\r'),('DE','SN','Sachsen\r'),('DE','ST','Sachsen-Anhalt\r'),('DE','TH','Thüringen'),('EE','37','Harjumaa\r'),('EE','39','Hiiumaa\r'),('EE','44','Ida-Virumaa\r'),('EE','49','Jõgevamaa'),('EE','51','Järvamaa'),('EE','57','Läänemaa'),('EE','59','Lääne-Virumaa'),('EE','65','Põlvamaa'),('EE','67','Pärnumaa'),('EE','70','Raplamaa\r'),('EE','74','Saaremaa\r'),('EE','78','Tartumaa\r'),('EE','82','Valgamaa\r'),('EE','84','Viljandimaa\r'),('EE','86','Võrumaa'),('FI','AL','Ahvenanmaan Maakunta (fi)\r'),('FI','ES','Etelä-Suomen lääni (fi)'),('FI','IS','Itä-Suomen lääni (fi)'),('FI','LL','Lapin lääni (fi)'),('FI','LS','Länsi-Suomen lääni (fi)'),('FI','OL','Oulun lääni (fi)'),('FR','01','Ain\r'),('FR','02','Aisne\r'),('FR','03','Allier\r'),('FR','04','Alpes-de-Haute-Provence\r'),('FR','05','Hautes-Alpes\r'),('FR','06','Alpes-Maritimes\r'),('FR','07','Ardèche'),('FR','08','Ardennes\r'),('FR','09','Ariège'),('FR','10','Aube\r'),('FR','11','Aude\r'),('FR','12','Aveyron\r'),('FR','13','Bouches-du-Rhône'),('FR','14','Calvados\r'),('FR','15','Cantal\r'),('FR','16','Charente\r'),('FR','17','Charente-Maritime\r'),('FR','18','Cher\r'),('FR','19','Corrèze'),('FR','21','Côte-d\'Or'),('FR','22','Côtes-d\'Armor'),('FR','23','Creuse\r'),('FR','24','Dordogne\r'),('FR','25','Doubs\r'),('FR','26','Drôme'),('FR','27','Eure\r'),('FR','28','Eure-et-Loir'),('FR','29','Finistère'),('FR','2A','Corse-du-Sud\r'),('FR','2B','Haute-Corse\r'),('FR','30','Gard\r'),('FR','31','Haute-Garonne\r'),('FR','32','Gers\r'),('FR','33','Gironde\r'),('FR','34','Hérault'),('FR','35','Ille-et-Vilaine\r'),('FR','36','Indre\r'),('FR','37','Indre-et-Loire\r'),('FR','38','Isère'),('FR','39','Jura\r'),('FR','40','Landes\r'),('FR','41','Loir-et-Cher\r'),('FR','42','Loire\r'),('FR','43','Haute-Loire\r'),('FR','44','Loire-Atlantique\r'),('FR','45','Loiret\r'),('FR','46','Lot'),('FR','47','Lot-et-Garonne\r'),('FR','48','Lozère'),('FR','49','Maine-et-Loire\r'),('FR','50','Manche\r'),('FR','51','Marne\r'),('FR','52','Haute-Marne\r'),('FR','53','Mayenne\r'),('FR','54','Meurthe-et-Moselle\r'),('FR','55','Meuse\r'),('FR','56','Morbihan\r'),('FR','57','Moselle\r'),('FR','58','Nièvre'),('FR','59','Nord\r'),('FR','60','Oise\r'),('FR','61','Orne\r'),('FR','62','Pas-de-Calais\r'),('FR','63','Puy-de-Dôme'),('FR','64','Pyrénées-Atlantiques'),('FR','65','Hautes-Pyrénées'),('FR','66','Pyrénées-Orientales'),('FR','67','Bas-Rhin\r'),('FR','68','Haut-Rhin\r'),('FR','69','Rhône'),('FR','70','Haute-Saône'),('FR','71','Saône-et-Loire'),('FR','72','Sarthe\r'),('FR','73','Savoie\r'),('FR','74','Haute-Savoie\r'),('FR','75','Paris\r'),('FR','76','Seine-Maritime\r'),('FR','77','Seine-et-Marne\r'),('FR','78','Yvelines\r'),('FR','79','Deux-Sèvres'),('FR','80','Somme\r'),('FR','81','Tarn\r'),('FR','82','Tarn-et-Garonne\r'),('FR','83','Var\r'),('FR','84','Vaucluse\r'),('FR','85','Vendée'),('FR','86','Vienne\r'),('FR','87','Haute-Vienne\r'),('FR','88','Vosges\r'),('FR','89','Yonne\r'),('FR','90','Territoire de Belfort\r'),('FR','91','Essonne\r'),('FR','92','Hauts-de-Seine\r'),('FR','93','Seine-Saint-Denis\r'),('FR','94','Val-de-Marne\r'),('FR','95','Val-d\'Oise\r'),('GB','ABD','Aberdeenshire\r'),('GB','ABE','Aberdeen City\r'),('GB','AGB','Argyll and Bute\r'),('GB','AGY','Isle of Anglesey [ Sir Ynys Môn GB-YNM]'),('GB','ANS','Angus\r'),('GB','ANT','Antrim\r'),('GB','ARD','Ards\r'),('GB','ARM','Armagh\r'),('GB','BAS','Bath and North East Somerset\r'),('GB','BBD','Blackburn with Darwen\r'),('GB','BDF','Bedfordshire\r'),('GB','BDG','Barking and Dagenham\r'),('GB','BEN','Brent\r'),('GB','BEX','Bexley\r'),('GB','BFS','Belfast\r'),('GB','BGE','Bridgend [Pen-y-bont ar Ogwr GB-POG]\r'),('GB','BGW','Blaenau Gwent\r'),('GB','BIR','Birmingham\r'),('GB','BKM','Buckinghamshire\r'),('GB','BLA','Ballymena\r'),('GB','BLY','Ballymoney\r'),('GB','BMH','Bournemouth\r'),('GB','BNB','Banbridge\r'),('GB','BNE','Barnet\r'),('GB','BNH','Brighton and Hove\r'),('GB','BNS','Barnsley\r'),('GB','BOL','Bolton\r'),('GB','BOR','Borders Region\r'),('GB','BPL','Blackpool\r'),('GB','BRC','Bracknell Forest\r'),('GB','BRD','Bradford\r'),('GB','BRY','Bromley\r'),('GB','BST','Bristol, City of\r'),('GB','BUR','Bury\r'),('GB','CAM','Cambridgeshire\r'),('GB','CAY','Caerphilly [Caerffili GB-CAF]\r'),('GB','CGN','Ceredigion [Sir Ceredigion]\r'),('GB','CGV','Craigavon\r'),('GB','CHS','Cheshire\r'),('GB','CKF','Carrickfergus\r'),('GB','CKT','Cookstown\r'),('GB','CLD','Calderdale\r'),('GB','CLK','Clackmannanshire\r'),('GB','CLR','Coleraine\r'),('GB','CLV','Cleveland\r'),('GB','CMA','Cumbria\r'),('GB','CMD','Camden\r'),('GB','CMN','Carmarthenshire [Sir Gaerfyrddin GB-GFY]\r'),('GB','CON','Cornwall\r'),('GB','COV','Coventry\r'),('GB','CRF','Cardiff [Caerdydd GB-CRD]\r'),('GB','CRY','Croydon\r'),('GB','CSR','Castlereagh\r'),('GB','CWD','Clwyd\r'),('GB','CWY','Conwy\r'),('GB','DAL','Darlington\r'),('GB','DBY','Derbyshire\r'),('GB','DEN','Denbighshire [Sir Ddinbych GB-DDB]\r'),('GB','DER','Derby\r'),('GB','DEV','Devon\r'),('GB','DFD','Dyfed\r'),('GB','DGN','Dungannon\r'),('GB','DGY','Dumfries and Galloway\r'),('GB','DNC','Doncaster\r'),('GB','DND','Dundee City\r'),('GB','DOR','Dorset\r'),('GB','DOW','Down\r'),('GB','DRY','Derry\r'),('GB','DUD','Dudley\r'),('GB','DUR','Durham\r'),('GB','DVV','Devon\r'),('GB','EAL','Ealing\r'),('GB','EAY','East Ayrshire\r'),('GB','EDH','Edinburgh, City of\r'),('GB','EDU','East Dunbartonshire\r'),('GB','ELN','East Lothian\r'),('GB','ELS','Eilean Siar\r'),('GB','ENF','Enfield\r'),('GB','ENG','England\r'),('GB','ERW','East Renfrewshire\r'),('GB','ERY','East Riding of Yorkshire\r'),('GB','ESS','Essex\r'),('GB','ESX','East Sussex\r'),('GB','FAL','Falkirk\r'),('GB','FER','Fermanagh\r'),('GB','FIF','Fife\r'),('GB','FLN','Flintshire [Sir y Fflint GB-FFL]\r'),('GB','GAT','Gateshead\r'),('GB','GLG','Glasgow City\r'),('GB','GLS','Gloucestershire\r'),('GB','GMP','Grampian Region\r'),('GB','GNT','Gwent\r'),('GB','GRE','Greenwich\r'),('GB','GTL','Greater London\r'),('GB','GTM','Greater Manchester\r'),('GB','GWN','Gwynedd\r'),('GB','HAL','Halton\r'),('GB','HAM','Hampshire\r'),('GB','HAV','Havering\r'),('GB','HCK','Hackney\r'),('GB','HEF','Herefordshire, County of\r'),('GB','HIL','Hillingdon\r'),('GB','HLD','Highland\r'),('GB','HMF','Hammersmith and Fulham\r'),('GB','HNS','Hounslow\r'),('GB','HPL','Hartlepool\r'),('GB','HRT','Hertfordshire\r'),('GB','HRW','Harrow\r'),('GB','HRY','Haringey\r'),('GB','HUM','Humberside\r'),('GB','HWR','Hereford and Worcester\r'),('GB','IOS','Isles of Scilly\r'),('GB','IOW','Isle of Wight\r'),('GB','ISL','Islington\r'),('GB','IVC','Inverclyde\r'),('GB','KEC','Kensington and Chelsea\r'),('GB','KEN','Kent\r'),('GB','KHL','Kingston upon Hull, City of\r'),('GB','KIR','Kirklees\r'),('GB','KTT','Kingston upon Thames\r'),('GB','KWL','Knowsley\r'),('GB','LAN','Lancashire\r'),('GB','LBH','Lambeth\r'),('GB','LCE','Leicester\r'),('GB','LDS','Leeds\r'),('GB','LEC','Leicestershire\r'),('GB','LEW','Lewisham\r'),('GB','LIN','Lincolnshire\r'),('GB','LIV','Liverpool\r'),('GB','LMV','Limavady\r'),('GB','LND','London, City of\r'),('GB','LRN','Larne\r'),('GB','LSB','Lisburn\r'),('GB','LTN','Lothian Region\r'),('GB','LUT','Luton\r'),('GB','MAN','Manchester\r'),('GB','MDB','Middlesbrough\r'),('GB','MDW','Medway\r'),('GB','MFT','Magherafelt\r'),('GB','MGM','Mid Glamorgan\r'),('GB','MIK','Milton Keynes\r'),('GB','MLN','Midlothian\r'),('GB','MON','Monmouthshire [Sir Fynwy GB-FYN]\r'),('GB','MRT','Merton\r'),('GB','MRY','Moray\r'),('GB','MSY','Merseyside\r'),('GB','MTY','Merthyr Tydfil [Merthyr Tudful GB-MTU]\r'),('GB','MYL','Moyle\r'),('GB','NAY','North Ayrshire\r'),('GB','NBL','Northumberland\r'),('GB','NDN','North Down\r'),('GB','NEL','North East Lincolnshire\r'),('GB','NET','Newcastle upon Tyne\r'),('GB','NFK','Norfolk\r'),('GB','NGM','Nottingham\r'),('GB','NIR','Northern Ireland\r'),('GB','NLK','North Lanarkshire\r'),('GB','NLN','North Lincolnshire\r'),('GB','NSM','North Somerset\r'),('GB','NTA','Newtownabbey\r'),('GB','NTH','Northamptonshire\r'),('GB','NTL','Neath Port Talbot [Castell-nedd Port Talbot GB-CTL]\r'),('GB','NTT','Nottinghamshire\r'),('GB','NTY','North Tyneside\r'),('GB','NWM','Newham\r'),('GB','NWP','Newport [Casnewydd GB-CNW]\r'),('GB','NYK','North Yorkshire\r'),('GB','NYM','Newry and Mourne\r'),('GB','OLD','Oldham\r'),('GB','OMH','Omagh\r'),('GB','ORK','Orkney Islands\r'),('GB','OXF','Oxfordshire\r'),('GB','PEM','Pembrokeshire [Sir Benfro GB-BNF]\r'),('GB','PKN','Perth and Kinross\r'),('GB','PLY','Plymouth\r'),('GB','POL','Poole\r'),('GB','POR','Portsmouth\r'),('GB','POW','Powys\r'),('GB','PTE','Peterborough\r'),('GB','RCC','Redcar and Cleveland\r'),('GB','RCH','Rochdale\r'),('GB','RCT','Rhondda, Cynon, Taff [Rhondda, Cynon,Taf]\r'),('GB','RDB','Redbridge\r'),('GB','RDG','Reading\r'),('GB','RFW','Renfrewshire\r'),('GB','RIC','Richmond upon Thames\r'),('GB','ROT','Rotherham\r'),('GB','RUT','Rutland\r'),('GB','SAW','Sandwell\r'),('GB','SAY','South Ayrshire\r'),('GB','SCB','Scottish Borders, The\r'),('GB','SCT','Scotland\r'),('GB','SFK','Suffolk\r'),('GB','SFT','Sefton\r'),('GB','SGC','South Gloucestershire\r'),('GB','SGM','South Glamorgan\r'),('GB','SHF','Sheffield\r'),('GB','SHN','St. Helens\r'),('GB','SHR','Shropshire\r'),('GB','SKP','Stockport\r'),('GB','SLF','Salford\r'),('GB','SLG','Slough\r'),('GB','SLK','South Lanarkshire\r'),('GB','SND','Sunderland\r'),('GB','SOL','Solihull\r'),('GB','SOM','Somerset\r'),('GB','SOS','Southend-on-Sea\r'),('GB','SRY','Surrey\r'),('GB','STB','Strabane\r'),('GB','STD','Strathclyde Region\r'),('GB','STE','Stoke-on-Trent\r'),('GB','STG','Stirling\r'),('GB','STH','Southampton\r'),('GB','STN','Sutton\r'),('GB','STS','Staffordshire\r'),('GB','STT','Stockton-on-Tees\r'),('GB','STY','South Tyneside\r'),('GB','SWA','Swansea [Abertawe GB-ATA]\r'),('GB','SWD','Swindon\r'),('GB','SWK','Southwark\r'),('GB','SYK','South Yorkshire\r'),('GB','TAM','Tameside\r'),('GB','TAY','Tayside Region\r'),('GB','TFW','Telford and Wrekin\r'),('GB','THR','Thurrock\r'),('GB','TOB','Torbay\r'),('GB','TOF','Torfaen [Tor-faen]\r'),('GB','TRF','Trafford\r'),('GB','TWH','Tower Hamlets\r'),('GB','TWR','Tyne and Wear\r'),('GB','VGL','Vale of Glamorgan, The [Bro Morgannwg GB-BMG]\r'),('GB','WAR','Warwickshire\r'),('GB','WBK','West Berkshire\r'),('GB','WDU','West Dunbartonshire\r'),('GB','WFT','Waltham Forest\r'),('GB','WGM','West Glamorgan\r'),('GB','WGN','Wigan\r'),('GB','WIL','Wiltshire\r'),('GB','WIS','Western Isles\r'),('GB','WKF','Wakefield\r'),('GB','WLL','Walsall\r'),('GB','WLN','West Lothian\r'),('GB','WLS','Wales [Cymru GB-CYM]\r'),('GB','WLV','Wolverhampton\r'),('GB','WMD','West Midlands\r'),('GB','WND','Wandsworth\r'),('GB','WNM','Windsor and maidenhead\r'),('GB','WOK','Wokingham\r'),('GB','WOR','Worcestershire\r'),('GB','WRL','Wirral\r'),('GB','WRT','Warrington\r'),('GB','WRX','Wrexham [Wrecsam GB-WRC]\r'),('GB','WSM','Westminster\r'),('GB','WSX','West Sussex\r'),('GB','WYK','West Yorkshire\r'),('GB','YOR','York\r'),('GB','ZET','Shetland Islands\r'),('GM','B','Banjul\r'),('GM','L','Lower River\r'),('GM','M','MacCarthy Island\r'),('GM','N','North Bank\r'),('GM','U','Upper River\r'),('GM','W','Western\r'),('GW','BA','Bafatá'),('GW','BL','Bolama\r'),('GW','BM','Biombo\r'),('GW','BS','Bissau\r'),('GW','CA','Cacheu\r'),('GW','GA','Gabù'),('GW','OI','Oio\r'),('GW','QU','Quinara\r'),('GW','TO','Tombali\r'),('IN','AN','Andaman and Nicobar Islands\r'),('IN','AP','Andhra Pradesh\r'),('IN','AR','Arun?chal Pradesh\r'),('IN','AS','Assam\r'),('IN','BR','Bih?r'),('IN','CH','Chand?garh'),('IN','CT','Chhattisgarh'),('IN','DD','Damán y Diu'),('IN','DL','Delhi'),('IN','DN','Dadra y Nagar Haveli'),('IN','GA','Goa'),('IN','GJ','Gujarat'),('IN','HP','Himachal Pradesh'),('IN','HR','Haryana'),('IN','JH','Jharkhand\r'),('IN','JK','Jammu y Cachemira'),('IN','KA','Karnataka'),('IN','KL','Kerala\r'),('IN','LD','Lakshadweep\r'),('IN','MH','Maharashtra'),('IN','ML','Meghalaya\r'),('IN','MN','Manipur\r'),('IN','MP','Madhya Pradesh\r'),('IN','MZ','Mizoram\r'),('IN','NL','Nagland'),('IN','OR','Orissa\r'),('IN','PB','Punjab\r'),('IN','PY','Pondicherry\r'),('IN','RJ','Rajasthan'),('IN','SK','Sikkim\r'),('IN','TN','Tamil Nadu'),('IN','TR','Tripura\r'),('IN','UL','Uttaranchal\r'),('IN','UP','Uttar Pradesh\r'),('IN','WB','West Bengal\r'),('JP','01','Hokkaido\r'),('JP','02','Aomori\r'),('JP','03','Iwate\r'),('JP','04','Miyagi\r'),('JP','05','Akita\r'),('JP','06','Yamagata\r'),('JP','07','Hukusima [Fukushima]\r'),('JP','08','Ibaraki\r'),('JP','09','Totigi [Tochigi]\r'),('JP','10','Gunma\r'),('JP','11','Saitama\r'),('JP','12','Tiba [Chiba]\r'),('JP','13','Tokyo\r'),('JP','14','Kanagawa\r'),('JP','15','Niigata\r'),('JP','16','Toyama\r'),('JP','17','Isikawa [Ishikawa]\r'),('JP','18','Hukui [Fukui]\r'),('JP','19','Yamanasi [Yamanashi]\r'),('JP','20','Nagano\r'),('JP','21','Gihu [Gifu]\r'),('JP','22','Sizuoka [Shizuoka]\r'),('JP','23','Aiti [Aichi]\r'),('JP','24','Mie\r'),('JP','25','Siga [Shiga]\r'),('JP','26','Kyoto\r'),('JP','27','Osaka\r'),('JP','28','Hyogo\r'),('JP','29','Nara\r'),('JP','30','Wakayama\r'),('JP','31','Tottori\r'),('JP','32','Simane [Shimane]\r'),('JP','33','Okayama\r'),('JP','34','Hirosima [Hiroshima]\r'),('JP','35','Yamaguti [Yamaguchi]\r'),('JP','36','Tokusima [Tokushima]\r'),('JP','37','Kagawa\r'),('JP','38','Ehime\r'),('JP','39','Koti [Kochi]\r'),('JP','40','Hukuoka [Fukuoka]\r'),('JP','41','Saga\r'),('JP','42','Nagasaki\r'),('JP','43','Kumamoto'),('JP','44','Oita\r'),('JP','45','Miyazaki\r'),('JP','46','Kagosima [Kagoshima]\r'),('JP','47','Okinawa\r'),('KM','A','Anjouan\r'),('KM','G','Grande Comore\r'),('KM','M','Mohéli'),('KR','11','Seoul Teugbyeolsi [Seoul-T\' kpy lshi]'),('KR','26','Busan Gwang\'yeogsi [Pusan-Kwangy kshi]'),('KR','27','Daegu Gwang\'yeogsi [Taegu-Kwangy kshi]'),('KR','28','Incheon Gwang\'yeogsi [Inch n-Kwangy kshi]'),('KR','29','Gwangju Gwang\'yeogsi [Kwangju-Kwangy kshi]'),('KR','30','Daejeon Gwang\'yeogsi [Taej n-Kwangy kshi]'),('KR','31','Ulsan Gwang\'yeogsi [Ulsan-Kwangy kshi]'),('KR','41','Gyeonggido [Ky nggi-do]'),('KR','42','Gang\'weondo [Kang-won-do]'),('KR','43','Chungcheongbugdo [Ch\'ungch\' ngbuk-do]'),('KR','44','Chungcheongnamdo [Ch\'ungch\' ngnam-do]'),('KR','45','Jeonrabugdo [Ch llabuk-do]'),('KR','46','Jeonranamdo [Ch llanam-do]'),('KR','47','Gyeongsangbugdo [Gyeongsangbuk-do]'),('KR','48','Gyeongsangnamdo [Ky ngsangnam-do]'),('KR','49','Jejudo [Cheju-do]\r'),('LV','AI','Aizkraukles Apri'),('LV','AL','Al?kones Apri??is'),('LV','BL','Balvu Apri??is'),('LV','BU','Bauskas Apri??is'),('LV','CE','C?su Apri??is'),('LV','DA','Daugavpils Apri??is'),('LV','DO','Dobeles Apri??is\r'),('LV','DW','Daugavpils\r'),('LV','GU','Gulbenes Apri??is\r'),('LV','JEL','Jelgava\r'),('LV','JK','J?kabpils Apri??is\r'),('LV','JL','Jelgavas Apri??is\r'),('LV','JUR','J?rmala\r'),('LV','KR','Kr?slavas Apri??is\r'),('LV','KU','Kuld?gas Apri??is\r'),('LV','LE','Liepdj?s Apri??is\r'),('LV','LM','Limbažu Apri??is'),('LV','LPX','Liepdja\r'),('LV','LU','Ludzas Apri??is'),('LV','MA','Madonas Apri??is'),('LV','OG','Ogres Apri??is'),('LV','PR','Preilu Apri??is'),('LV','RE','R?zeknes Apri??is'),('LV','REZ','R?zekne'),('LV','RI','R?gas Apri??is'),('LV','RIX','R?ga'),('LV','SA','Saldus Apri??is'),('LV','TA','Talsu Apri??is'),('LV','TU','Tukuma Apri??is'),('LV','VE','Ventspils Apri??is'),('LV','VEN','Ventspils'),('LV','VK','Valkas Apri??is'),('LV','VM','Valmieras Apri??is'),('MX','AGU','Aguascalientes\r'),('MX','BCN','Baja California\r'),('MX','BCS','Baja California Sur\r'),('MX','CAM','Campeche\r'),('MX','CHH','Chihuahua\r'),('MX','CHP','Chiapas\r'),('MX','COA','Coahuila\r'),('MX','COL','Colima\r'),('MX','DF','Distrito Federal\r'),('MX','DUR','Durango\r'),('MX','GRO','Guerrero\r'),('MX','GUA','Guanajuato\r'),('MX','HID','Hidalgo\r'),('MX','JAL','Jalisco\r'),('MX','MEX','México '),('MX','MIC','Michoacán'),('MX','MOR','Morelos\r'),('MX','NAY','Nayarit\r'),('MX','NLE','Nuevo León'),('MX','OAX','Oaxaca\r'),('MX','PUE','Puebla\r'),('MX','QUE','Querétaro'),('MX','ROO','Quintana Roo\r'),('MX','SIN','Sinaloa'),('MX','SLP','San Luis Potosí '),('MX','SON','Sonora\r'),('MX','TAB','Tabasco\r'),('MX','TAM','Tamaulipas\r'),('MX','TLA','Tlaxcala\r'),('MX','VER','Veracruz\r'),('MX','YUC','Yucatán'),('MX','ZAC','Zacatecas\r'),('NO','01','Østfold'),('NO','02','Akershus\r'),('NO','03','Oslo\r'),('NO','04','Hedmark\r'),('NO','05','Oppland\r'),('NO','06','Buskerud\r'),('NO','07','Vestfold\r'),('NO','08','Telemark\r'),('NO','09','Aust-Agder\r'),('NO','10','Vest-Agder\r'),('NO','11','Rogaland\r'),('NO','12','Hordaland\r'),('NO','14','Sogn og Fjordane\r'),('NO','15','Møre og Romsdal'),('NO','16','Sør-Trøndelag'),('NO','17','Nord-Trøndelag'),('NO','18','Nordland\r'),('NO','19','Troms\r'),('NO','20','Finnmark\r'),('NZ','AUK','Auckland\r'),('NZ','BOP','Bay of Plenty\r'),('NZ','CAN','Canterbury\r'),('NZ','GIS','Gisborne\r'),('NZ','HKB','Hawkes\'s Bay\r'),('NZ','MBH','Marlborough\r'),('NZ','MWT','Manawatu-Wanganui\r'),('NZ','NSN','Nelson\r'),('NZ','NTL','Northland\r'),('NZ','OTA','Otago\r'),('NZ','STL','Southland\r'),('NZ','TAS','Tasman\r'),('NZ','TKI','Taranaki\r'),('NZ','WGN','Wellington\r'),('NZ','WKO','Waikato\r'),('NZ','WTC','West Coast\r'),('PT','01','Aveiro\r'),('PT','02','Beja\r'),('PT','03','Braga\r'),('PT','04','Braganza'),('PT','05','Castelo Branco'),('PT','06','Coimbra\r'),('PT','07','Évora'),('PT','08','Faro\r'),('PT','09','Guarda\r'),('PT','10','Leiria\r'),('PT','11','Lisboa\r'),('PT','12','Portalegre\r'),('PT','13','Porto\r'),('PT','14','Santarém'),('PT','15','Setúbal'),('PT','16','Viana do Castelo\r'),('PT','17','Vila Real\r'),('PT','18','Viseu\r'),('PT','20','Região Autónoma dos Açores'),('PT','30','Região Autónoma da Madeira'),('SE','AB','Stockholms Län'),('SE','AC','Västerbottens Län'),('SE','BD','Norrbottens län '),('SE','C','Uppsala län'),('SE','D','Södermanlands län'),('SE','E','Östergötlands län'),('SE','F','Jönköpings län'),('SE','G','Kronoborgs län'),('SE','H','Kalmar län'),('SE','I','Gotlands län'),('SE','K','Blekinge län'),('SE','M','SkÃ¥ne län'),('SE','N','Hallands län'),('SE','O','Västra Götalands län'),('SE','S','Värmlands län'),('SE','T','Örebro län'),('SE','U','Västmanlands län'),('SE','W','Dalarnes län'),('SE','X','Gävleborgs län'),('SE','Y','Västernorrlands län'),('SE','Z','Jämtlands län'),('TR','01','Adana\r'),('TR','02','Adiyaman\r'),('TR','03','Afyon\r'),('TR','04','Agri\r'),('TR','05','Amasya\r'),('TR','06','Ankara\r'),('TR','07','Antalya\r'),('TR','08','Artvin\r'),('TR','09','Aydin\r'),('TR','10','Balikesir\r'),('TR','11','Bilecik\r'),('TR','12','Bingol\r'),('TR','13','Bitlis\r'),('TR','14','Bolu\r'),('TR','15','Burdur\r'),('TR','16','Bursa\r'),('TR','17','Canakkale\r'),('TR','18','Cankiri\r'),('TR','19','Corum\r'),('TR','20','Denizli\r'),('TR','21','Diyarbakir\r'),('TR','22','Edirne\r'),('TR','23','Elazig\r'),('TR','24','Erzincan\r'),('TR','25','Erzurum\r'),('TR','26','Eskisehir\r'),('TR','27','Gaziantep\r'),('TR','28','Giresun\r'),('TR','29','Gümüşhane'),('TR','30','Hakkari\r'),('TR','31','Hatay\r'),('TR','32','Isparta\r'),('TR','33','Icel\r'),('TR','34','Istanbul\r'),('TR','35','Izmir\r'),('TR','36','Kars\r'),('TR','37','Kastamonu\r'),('TR','38','Kayseri\r'),('TR','39','Kirklareli\r'),('TR','40','Kirsehir\r'),('TR','41','Kocaeli\r'),('TR','42','Konya\r'),('TR','43','Kütahya'),('TR','44','Malatya\r'),('TR','45','Manisa\r'),('TR','46','Kahramanmaras\r'),('TR','47','Mardin\r'),('TR','48','Mugla\r'),('TR','49','Mus\r'),('TR','50','Nevsehir\r'),('TR','51','Nigde\r'),('TR','52','Ordu\r'),('TR','53','Rize\r'),('TR','54','Sakarya\r'),('TR','55','Samsun\r'),('TR','56','Siirt\r'),('TR','57','Sinop\r'),('TR','58','Sivas\r'),('TR','59','Tekirdag\r'),('TR','60','Tokat\r'),('TR','61','Trabzon\r'),('TR','62','Tunceli\r'),('TR','63','Sanliurfa\r'),('TR','64','Usak\r'),('TR','65','Van\r'),('TR','66','Yozgat\r'),('TR','67','Zonguldak\r'),('TR','68','Aksaray\r'),('TR','69','Bayburt\r'),('TR','70','Karaman\r'),('TR','71','Kirkkale\r'),('TR','72','Batman\r'),('TR','73','Sirnak\r'),('TR','74','Bartin\r'),('TR','75','Ardahan\r'),('TR','76','Igdir\r'),('TR','77','Yalova\r'),('TR','78','Karabuk\r'),('TR','79','Kilis\r'),('TR','80','Osmaniye\r'),('UM','67','Johnston Atoll (ISO reserved code = JT)\r'),('UM','71','Midway Islands (ISO reserved code = I)\r'),('UM','76','Navassa Island (ISO reserved code = NV)\r'),('UM','79','Wake Island (ISO reserved code = WK)\r'),('UM','81','Baker Island\r'),('UM','84','Howland Island\r'),('UM','86','Jarvis Island\r'),('UM','89','Kingman Reef\r'),('UM','95','Palmyra Atoll\r'),('US','AK','Alaska\r'),('US','AL','Alabama\r'),('US','AR','Arkansas\r'),('US','AS','American Samoa (see also separate entry under AS)\r'),('US','AZ','Arizona\r'),('US','CA','California\r'),('US','CO','Colorado\r'),('US','CT','Connecticut\r'),('US','DC','District of Columbia\r'),('US','DE','Delaware\r'),('US','FL','Florida\r'),('US','GA','Georgia\r'),('US','GU','Guam (see also separate entry under GU)\r'),('US','HI','Hawaii\r'),('US','IA','Iowa\r'),('US','ID','Idaho\r'),('US','IL','Illinois\r'),('US','IN','Indiana\r'),('US','KS','Kansas\r'),('US','KY','Kentucky\r'),('US','LA','Louisiana\r'),('US','MA','Massachusetts\r'),('US','MD','Maryland\r'),('US','ME','Maine\r'),('US','MI','Michigan\r'),('US','MN','Minnesota\r'),('US','MO','Missouri\r'),('US','MP','Northern Mariana Islands (see also separate entry MP)\r'),('US','MS','Mississippi\r'),('US','MT','Montana\r'),('US','NC','North Carolina\r'),('US','ND','North Dakota\r'),('US','NE','Nebraska\r'),('US','NH','New Hampshire\r'),('US','NJ','New Jersey\r'),('US','NM','New Mexico\r'),('US','NV','Nevada\r'),('US','NY','New York\r'),('US','OH','Ohio\r'),('US','OK','Oklahoma\r'),('US','OR','Oregon\r'),('US','PA','Pennsylvania\r'),('US','PR','Puerto Rico (see also separate entry under PR)\r'),('US','RI','Rhode Island\r'),('US','SC','South Carolina\r'),('US','SD','South Dakota\r'),('US','TN','Tennessee\r'),('US','TX','Texas\r'),('US','UM','U.S. Minor Outlying Islands (cf. separate entry UM)\r'),('US','UT','Utah\r'),('US','VA','Virginia\r'),('US','VI','Virgin Islands of the U.S. (see also separate entry VI)\r'),('US','VT','Vermont\r'),('US','WA','Washington\r'),('US','WI','Wisconsin\r'),('US','WV','West Virginia\r'),('US','WY','Wyoming\r'); +INSERT INTO `LANGUAGE` VALUES ('aa','Afar','','L',0,'0','GREGORIAN'),('ab','Abkhazian','','L',1,'0','GREGORIAN'),('af','Afrikaans','','L',2,'0','GREGORIAN'),('am','Amharic','','L',3,'0','GREGORIAN'),('ar','Arabic','','L',4,'0','GREGORIAN'),('as','Assamese','','L',5,'0','GREGORIAN'),('ay','Aymara','','L',6,'0','GREGORIAN'),('az','Azerbaijani','','L',7,'0','GREGORIAN'),('ba','Bashkir','','L',8,'0','GREGORIAN'),('be','Byelorussian','','L',9,'0','GREGORIAN'),('bg','Bulgarian','','L',10,'0','GREGORIAN'),('bh','Bihari','','L',11,'0','GREGORIAN'),('bi','Bislama','','L',12,'0','GREGORIAN'),('bn','Bengali','','L',13,'0','GREGORIAN'),('bo','Tibetan','','L',14,'0','GREGORIAN'),('br','Breton','','L',15,'0','GREGORIAN'),('ca','Catalan','','L',16,'0','GREGORIAN'),('co','Corsican','','L',17,'0','GREGORIAN'),('cs','Czech','','L',18,'0','GREGORIAN'),('cy','Welsh','','L',19,'0','GREGORIAN'),('da','Danish','','L',20,'0','GREGORIAN'),('de','German','','L',21,'0','GREGORIAN'),('dz','Bhutani','','L',22,'0','GREGORIAN'),('el','Greek','','L',23,'0','GREGORIAN'),('en','English','','L',24,'1','GREGORIAN'),('eo','Esperanto','','L',25,'0','GREGORIAN'),('es','Spanish','Español','L',26,'0','GREGORIAN'),('et','Estonian','','L',27,'0','GREGORIAN'),('eu','Basque','','L',28,'0','GREGORIAN'),('fa','Persian','','R',29,'0','PERSIAN'),('fi','Finnish','','L',30,'0','GREGORIAN'),('fj','Fiji','','L',31,'0','GREGORIAN'),('fo','Faeroese','','L',32,'0','GREGORIAN'),('fr','French','','L',33,'0','GREGORIAN'),('fy','Frisian','','L',34,'0','GREGORIAN'),('ga','Irish','','L',35,'0','GREGORIAN'),('gd','Gaelic','','L',36,'0','GREGORIAN'),('gl','Galician','','L',37,'0','GREGORIAN'),('gn','Guarani','','L',38,'0','GREGORIAN'),('gu','Gujarati','','L',39,'0','GREGORIAN'),('ha','Hausa','','L',40,'0','GREGORIAN'),('hi','Hindi','','L',41,'0','GREGORIAN'),('hr','Croatian','','L',42,'0','GREGORIAN'),('hu','Hungarian','','L',43,'0','GREGORIAN'),('hy','Armenian','','L',44,'0','GREGORIAN'),('ia','Interlingua','','L',45,'0','GREGORIAN'),('ie','Interlingue','','L',46,'0','GREGORIAN'),('ik','Inupiak','','L',47,'0','GREGORIAN'),('in','Indonesian','','L',48,'0','GREGORIAN'),('is','Icelandic','','L',49,'0','GREGORIAN'),('it','Italian','','L',50,'0','GREGORIAN'),('iw','Hebrew','','R',51,'0','GREGORIAN'),('ja','Japanese','','L',52,'0','GREGORIAN'),('ji','Yiddish','','L',53,'0','GREGORIAN'),('jw','Javanese','','L',54,'0','GREGORIAN'),('ka','Georgian','','L',55,'0','GREGORIAN'),('kk','Kazakh','','L',56,'0','GREGORIAN'),('kl','Greenlandic','','L',57,'0','GREGORIAN'),('km','Cambodian','','L',58,'0','GREGORIAN'),('kn','Kannada','','L',59,'0','GREGORIAN'),('ko','Korean','','L',60,'0','GREGORIAN'),('ks','Kashmiri','','L',61,'0','GREGORIAN'),('ku','Kurdish','','L',62,'0','GREGORIAN'),('ky','Kirghiz','','L',63,'0','GREGORIAN'),('la','Latin','','L',64,'0','GREGORIAN'),('ln','Lingala','','L',65,'0','GREGORIAN'),('lo','Laothian','','L',66,'0','GREGORIAN'),('lt','Lithuanian','','L',67,'0','GREGORIAN'),('lv','Latvian','','L',68,'0','GREGORIAN'),('mg','Malagasy','','L',69,'0','GREGORIAN'),('mi','Maori','','L',70,'0','GREGORIAN'),('mk','Macedonian','','L',71,'0','GREGORIAN'),('ml','Malayalam','','L',72,'0','GREGORIAN'),('mn','Mongolian','','L',73,'0','GREGORIAN'),('mo','Moldavian','','L',74,'0','GREGORIAN'),('mr','Marathi','','L',75,'0','GREGORIAN'),('ms','Malay','','L',76,'0','GREGORIAN'),('mt','Maltese','','L',77,'0','GREGORIAN'),('my','Burmese','','L',78,'0','GREGORIAN'),('na','Nauru','','L',79,'0','GREGORIAN'),('ne','Nepali','','L',80,'0','GREGORIAN'),('nl','Dutch','','L',81,'0','GREGORIAN'),('no','Norwegian','','L',82,'0','GREGORIAN'),('oc','Occitan','','L',83,'0','GREGORIAN'),('om','Oromo','','L',84,'0','GREGORIAN'),('or','Oriya','','L',85,'0','GREGORIAN'),('pa','Punjabi','','L',86,'0','GREGORIAN'),('pl','Polish','','L',87,'0','GREGORIAN'),('ps','Pashto','','L',88,'0','GREGORIAN'),('pt','Portuguese','','L',89,'0','GREGORIAN'),('qu','Quechua','','L',90,'0','GREGORIAN'),('rm','Rhaeto-Romance','','L',91,'0','GREGORIAN'),('rn','Kirundi','','L',92,'0','GREGORIAN'),('ro','Romanian','','L',93,'0','GREGORIAN'),('ru','Russian','','L',94,'0','GREGORIAN'),('rw','Kinyarwanda','','L',95,'0','GREGORIAN'),('sa','Sanskrit','','L',96,'0','GREGORIAN'),('sd','Sindhi','','L',97,'0','GREGORIAN'),('sg','Sangro','','L',98,'0','GREGORIAN'),('sh','Serbo-Croatian','','L',99,'0','GREGORIAN'),('si','Singhalese','','L',100,'0','GREGORIAN'),('sk','Slovak','','L',101,'0','GREGORIAN'),('sl','Slovenian','','L',102,'0','GREGORIAN'),('sm','Samoan','','L',103,'0','GREGORIAN'),('sn','Shona','','L',104,'0','GREGORIAN'),('so','Somali','','L',105,'0','GREGORIAN'),('sq','Albanian','','L',106,'0','GREGORIAN'),('sr','Serbian','','L',107,'0','GREGORIAN'),('ss','Siswati','','L',108,'0','GREGORIAN'),('st','Sesotho','','L',109,'0','GREGORIAN'),('su','Sudanese','','L',110,'0','GREGORIAN'),('sv','Swedish','','L',111,'0','GREGORIAN'),('sw','Swahili','','L',112,'0','GREGORIAN'),('ta','Tamil','','L',113,'0','GREGORIAN'),('te','Tegulu','','L',114,'0','GREGORIAN'),('tg','Tajik','','L',115,'0','GREGORIAN'),('th','Thai','','L',116,'0','GREGORIAN'),('ti','Tigrinya','','L',117,'0','GREGORIAN'),('tk','Turkmen','','L',118,'0','GREGORIAN'),('tl','Tagalog','','L',119,'0','GREGORIAN'),('tn','Setswana','','L',120,'0','GREGORIAN'),('to','Tonga','','L',121,'0','GREGORIAN'),('tr','Turkish','','L',122,'0','GREGORIAN'),('ts','Tsonga','','L',123,'0','GREGORIAN'),('tt','Tatar','','L',124,'0','GREGORIAN'),('tw','Twi','','L',125,'0','GREGORIAN'),('uk','Ukrainian','','L',126,'0','GREGORIAN'),('ur','Urdu','','L',127,'0','GREGORIAN'),('uz','Uzbek','','L',128,'0','GREGORIAN'),('vi','Vietnamese','','L',129,'0','GREGORIAN'),('vo','Volapuk','','L',130,'0','GREGORIAN'),('wo','Wolof','','L',131,'0','GREGORIAN'),('xh','Xhosa','','L',132,'0','GREGORIAN'),('yo','Yoruba','','L',133,'0','GREGORIAN'),('zh','Chinese','','L',134,'0','GREGORIAN'),('zu','Zulu','','L',135,'0','GREGORIAN'); +INSERT INTO `TRANSLATION` VALUES ('LABEL','LOGIN','en','Login'),('LABEL','CASES','en','Cases'),('LABEL','ID_USER_HAVENT_RIGHTS_PAGE','en','User does not have rights on this page.'),('LABEL','ID_WRONG_PASS','en','Wrong password'),('LABEL','ABOUT','en','About'),('LABEL','ID_PROCESSMAP_MESSAGES','en','Messages'),('JAVASCRIPT','demo','en','test javaScript'),('LABEL','ID_AVAILABLE_TRIGGERS','en','Available Triggers'),('LABEL','ID_LOGOUT','en','Logout'),('LABEL','ID_MY_ACCOUNT','en','My account'),('LABEL','ID_USERS','en','Users'),('LABEL','ID_CASES','en','Cases'),('LABEL','ID_APPLICATIONS','en','Processes'),('LABEL','ID_RULES_AND_USER_GROUPS','en','Rules and user groups'),('LABEL','ID_ADD_USER_OF_TASK','en','Last executor of the task'),('LABEL','ID_END_OF_PROCESS','en','End of process'),('LABEL','ID_TAREA_COLGANTE','en','Leaf task'),('LABEL','ID_OUTPUT_DOCUMENTS','en','Output Documents'),('LABEL','ID_MSG_CONFIRM_DELETE_OUTDOC','en','Do you want to delete this output document ?'),('LABEL','ID_NO_RECORDS_FOUND','en','No records found'),('LABEL','ID_DYNAFORMS','en','DynaForms'),('LABEL','ID_DYNAFORM_EDITOR','en','DynaForm Editor'),('LABEL','ID_MSG_CONFIRM_RESET_TEMPLATE','en','Are you sure you want to restore the default template ?'),('LABEL','ID_ADD_FIELD','en','Add field'),('LABEL','ID_EDIT_FIELD','en','Edit Field'),('LABEL','ID_DELETE_FIELD_SURE','en','Are you sure you want to delete this field?'),('LABEL','ID_EDIT','en','Edit'),('LABEL','ID_DELETE','en','Delete'),('LABEL','ID_UP','en','Up'),('LABEL','ID_DOWN','en','Down'),('LABEL','ID_PAGE','en','Page'),('LABEL','ID_NEW_DYNAFORM','en','New dynaform'),('LABEL','ID_EDIT_DYNAFORM','en','Edit DynaForm'),('LABEL','ID_MSG_CONFIRM_DELETE_DYNAFORM','en','Do you want to delete this DynaForm ?'),('LABEL','ID_ADD_MESSAGE','en','Add message'),('LABEL','ID_MESSAGES','en','Messages'),('LABEL','ID_MSG_CONFIRM_DELETE_MESSAGE','en','Do you want to delete this message?'),('LABEL','ID_ACTIVE','en','Active'),('LABEL','ID_INACTIVE','en','Inactive'),('LABEL','ID_MSG_CONFIRM_DELETE_PROCESS','en','Do you want to delete this process ?'),('LABEL','ID_VIEW','en','View'),('LABEL','ID_MSG_CONFIRM_DELETE_USER','en','Do you want to delete this user ?'),('LABEL','ID_USERS_LIST','en','Users List'),('LABEL','ID_GROUP_USERS','en','Groups'),('LABEL','ID_USER_REGISTERED','en','User name already exists'),('LABEL','ID_MSG_ERROR_USR_USERNAME','en','User name required!'),('LABEL','ID_MSG_ERROR_DUE_DATE','en','Due date required!'),('LABEL','ID_NEW_PASS_SAME_OLD_PASS','en','The confirm Password fields must be the same!'),('LABEL','ID_NEW_INPUTDOCS','en','New input document'),('LABEL','ID_EDIT_INPUTDOCS','en','Edit input document'),('LABEL','ID_MSG_CONFIRM_DELETE_DOCUMENT','en','Do you want to delete this document ?'),('LABEL','ID_NEW_TRIGGERS','en','New Trigger'),('LABEL','ID_EDIT_TRIGGERS','en','Edit Trigger'),('LABEL','ID_MSG_CONFIRM_DELETE_TRIGGER','en','Do you want to delete this trigger?'),('LABEL','ID_GROUP','en','Group'),('LABEL','ID_DE_ASSIGN','en','Remove'),('LABEL','ID_MSG_CONFIRM_DEASIGN_USER_MESSAGE','en','Are you sure you want to remove this user?'),('LABEL','ID_MSG_ERROR_PRO_TITLE','en','Process title required!'),('LABEL','ID_TASK','en','Task'),('LABEL','ID_CONDITION','en','Condition'),('LABEL','ID_MSG_CONFIRM_DELETE_WEBBOT','en','Are you sure you want to delete this webbot?'),('LABEL','ID_DYNAFORM_EDITOR_SAVE_CHANGES','en','Do you want to save changes?'),('LABEL','ID_REQUEST_DOCUMENTS','en','Input Documents'),('LABEL','ID_WEBBOT','en','Webbots'),('LABEL','ID_ADD','en','Add'),('LABEL','ID_USER_HAVENT_RIGHTS_SYSTEM','en','User does not have access to the system'),('LABEL','ID_START_CASE','en','New'),('LABEL','ID_NEW_GROUP','en','New'),('LABEL','ID_MEMBERS','en','Members'),('LABEL','ID_MSG_CONFIRM_DELETE_GROUP','en','Do you want to delete this group ?'),('APP_STATUS','DRAFT','en','Draft'),('LABEL','ID_INCORRECT_EMAIL','en','Your E-mail address is not valid.'),('LABEL','ID_USER_NOT_REGISTERED','en','User not registered!'),('LABEL','ID_USER_INACTIVE','en','User inactive!'),('LABEL','ID_CANNOT_CHANGE_STATUS_ADMIN_USER','en','Can\'t change the status of administrator!'),('LABEL','ID_CANNOT_DELETE_ADMIN_USER','en','Can\'t delete the administrator!'),('LABEL','ID_ASSIGN','en','Assign'),('LABEL','ID_ASSIGN_SCREEN','en','Assign Screen'),('LABEL','ID_ASSIGN_TASK','en','Assign Task'),('LABEL','ID_UPLOAD','en','Upload'),('LABEL','ID_GENERATE','en','Generate'),('LABEL','ID_CONFIRM_DELETE_ELEMENT','en','Do you want to delete this element?'),('DASHBOARD','7','en','Approval of consolidated tasks'),('JAVASCRIPT','ID_PROCESSMAP_TRIGGERS','en','Triggers'),('JAVASCRIPT','ID_PROCESSMAP_OUTPUT_DOCUMENTS','en','Output Documents'),('LABEL','DRAFT','en','Draft'),('DEL_PRIORITY','0','en','Low'),('DEL_PRIORITY','1','en','Medium'),('DEL_PRIORITY','2','en','High'),('LABEL','ID_PROCESSMAP_DYNAFORMS','en','DynaForms'),('LABEL','ID_ATTACH','en','Attach'),('LABEL','ID_MSG_CONFIRM_DELETE_CASES','en','Are you sure you want to delete this case?'),('LABEL','ID_ALL','en','All'),('LABEL','ID_CANCELLED','en','Canceled'),('LABEL','ID_FINISHED','en','Finished'),('LABEL','ID_PAUSED','en','Paused'),('LABEL','ID_DERIVED','en','Sent'),('LABEL','ID_NOT_SENT','en','Not sent'),('LABEL','ID_DRAFT','en','Draft'),('LABEL','ID_COMPLETED','en','Completed'),('LABEL','ID_TO_DO','en','To do'),('LABEL','ID_PLEASE_ENTER_COMMENTS','en','Please enter comments!'),('LABEL','ID_PLEASE_SELECT_FILE','en','Please select the file to attach!'),('LABEL','ID_PROPERTIES','en','Properties'),('LABEL','ID_EMPTY','en','empty'),('LABEL','ID_SELECT','en','Select'),('LABEL','ID_SEARCH','en','Search'),('LABEL','ID_REQUIRED_FIELD','en','Required Field'),('LABEL','ID_TRIGGERS','en','Triggers'),('LABEL','ID_OPEN','en','Open'),('LABEL','ID_STEPS','en','Steps'),('LABEL','ID_INFORMATION','en','Information'),('LABEL','ID_ACTIONS','en','Actions'),('LABEL','ID_PROCESS_INFORMATION','en','Process Information'),('LABEL','ID_TASK_INFORMATION','en','Task Information'),('LABEL','ID_CANCEL_CASE','en','Cancel Case'),('LABEL','ID_YOU_ARE_FIRST_STEP','en','You are in the first step!'),('JAVASCRIPT','EDIT_PROCESS','en','Edit process'),('JAVASCRIPT','curriculum','en','Resume'),('JAVASCRIPT','ID_OPEN_SEARCH','en','Advanced Search'),('JAVASCRIPT','ID_CLOSE_SEARCH','en','Close Search'),('JAVASCRIPT','ID_URL_OF_LINK','en','Enter the URL for the link'),('JAVASCRIPT','ID_FONT_COLOR','en','Change text color'),('JAVASCRIPT','ID_HILITE_COLOR','en','Highlight Color'),('JAVASCRIPT','ID_INSERT_HTML','en','Insert HTML code'),('JAVASCRIPT','ID_IMAGE_URI','en','Image URI'),('JAVASCRIPT','ID_FONT_NAME','en','Font Name'),('JAVASCRIPT','ID_FONT_SIZE','en','Font Size'),('JAVASCRIPT','ID_BACKGROUND_COLOR','en','Background color'),('JAVASCRIPT','ID_WHICH_BLOCK','en','Block'),('JAVASCRIPT','ID_PROCESSMAP_SEQUENTIAL','en','Sequential'),('JAVASCRIPT','ID_PROCESSMAP_SELECTION','en','Selection'),('JAVASCRIPT','ID_PROCESSMAP_EVALUATION','en','Evaluation'),('JAVASCRIPT','ID_PROCESSMAP_PARALLEL_FORK','en','Parallel (fork)'),('JAVASCRIPT','ID_PROCESSMAP_PARALLEL_EVALUATION_FORK','en','Parallel by Evaluation (fork)'),('JAVASCRIPT','ID_PROCESSMAP_PARALLEL_JOIN','en','Parallel (join)'),('JAVASCRIPT','ID_PROCESSMAP_INPUT_DOCUMENTS','en','Input Documents'),('JAVASCRIPT','ID_PROCESSMAP_LOADING','en','Loading......'),('JAVASCRIPT','ID_PROCESSMAP_EDIT_PROCESS','en','Edit process'),('JAVASCRIPT','ID_PROCESSMAP_ADD_TASK','en','Add task'),('JAVASCRIPT','ID_PROCESSMAP_ADD_TEXT','en','Add text'),('JAVASCRIPT','ID_PROCESSMAP_HORIZONTAL_LINE','en','Horizontal line'),('JAVASCRIPT','ID_PROCESSMAP_VERTICAL_LINE','en','Vertical line'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_ALL_LINES','en','Delete all lines'),('JAVASCRIPT','ID_PROCESSMAP_CONFIRM_DELETE_ALL_LINES','en','Do you want to delete the guide lines?'),('JAVASCRIPT','ID_PROCESSMAP_PROMPT_RENAME_TEXT','en','Rename to:'),('JAVASCRIPT','ID_PROCESSMAP_STEPS','en','Steps'),('JAVASCRIPT','ID_PROCESSMAP_TASK_STEPS','en','Steps of:'),('JAVASCRIPT','ID_PROCESSMAP_CONDITIONS','en','Conditions'),('JAVASCRIPT','ID_PROCESSMAP_USERS_AND_GROUPS','en','Users & User Groups'),('JAVASCRIPT','ID_PROCESSMAP_WORKFLOW_PATTERNS','en','Routing rule'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_TASK','en','Delete task'),('JAVASCRIPT','ID_PROCESSMAP_CONFIRM_DELETE_TASK','en','Do you want to delete the task:'),('JAVASCRIPT','ID_PROCESSMAP_PROPERTIES','en','Properties'),('JAVASCRIPT','ID_PROCESSMAP_TASK','en','Task'),('JAVASCRIPT','ID_PROCESSMAP_SUBMIT','en','Save'),('JAVASCRIPT','ID_PROCESSMAP_CANCEL','en','Cancel'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_DEFINITION','en','Definition'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_ASSIGNMENTS','en','Designation rules'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_TIMING','en','Timing control'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_PERMISSIONS','en','Permissions'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_LABELS','en','Case Labels'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_GUIDE','en','Delete line'),('JAVASCRIPT','ID_PROCESSMAP_EDIT_TEXT','en','Edit text'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_TEXT','en','Delete text'),('JAVASCRIPT','ID_PROCESSMAP_EDIT_TEXT_CHANGE_TO','en','Change to:'),('JAVASCRIPT','ID_PROCESSMAP_CONFIRM_WORKFLOW_PATTERN_CHANGE','en','Are you sure you want to change the routing rule?'),('JAVASCRIPT','ID_PROCESSMAP_NEW_TASK','en','New task'),('JAVASCRIPT','ID_PROCESSMAP_TEXT','en','Text:'),('LABEL','ID_NEW_STEP','en','New Step'),('JAVASCRIPT','ID_SAVED','en','DynaForm is now saved'),('JAVASCRIPT','ID_EXIT_WITHOUT_SAVING','en','Exit without saving?'),('LABEL','ID_GROUP_CHART','en','Group Chart'),('LABEL','ID_WITHOUT_RESUME','en','Without resume!'),('LABEL','ID_NO_RESUME','en','The user doesn\'t have a resume.'),('LABEL','ID_NO_DERIVATION_RULE','en','Process definition error: All conditions in parallel evaluation routing rule evaluated to false, so workflow has stopped. Please change the definition of the parallel evaluation routing rule.'),('LABEL','ID_NO_USERS','en','The task doesn\'t have any users.'),('LABEL','ID_CANCEL','en','Cancel'),('LABEL','ID_PROCESS_MAP','en','Process Map'),('LABEL','ID_BEFORE_ASSIGNMENT','en','Before Assignment'),('LABEL','ID_BEFORE_DERIVATION','en','Before Derivation'),('LABEL','ID_AFTER_DERIVATION','en','After Derivation'),('LABEL','ID_BEFORE','en','Before'),('LABEL','ID_AFTER','en','After'),('JAVASCRIPT','ID_TRANSFER_HISTORY','en','Transfer History'),('LABEL','ID_TRANSFER_HISTORY','en','Transfer History'),('LABEL','ID_ENABLED','en','Enabled'),('JAVASCRIPT','ID_NO_DERIVATIONS_DEFINED','en','No derivations were defined.'),('LABEL','ID_ROWS','en','Rows'),('LABEL','ID_MEMBER','en','Member'),('LABEL','ID_USER','en','User'),('LABEL','ID_FILE_TOO_BIG','en','The file is too big to upload!'),('LABEL','ID_EDIT_CONDITIONS_OF_STEP','en','Edit step conditions'),('LABEL','ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING','en','Save changes to the routing rules before closing?'),('JAVASCRIPT','ID_SAVE_DERIVATION_RULES_BEFORE_CLOSING','en','Save changes to the routing rules before closing?'),('JAVASCRIPT','ID_PROCESSMAP_WORKFLOW_DELETE_PATTERNS','en','Delete Routing rule'),('JAVASCRIPT','ID_PROCESSMAP_WORKFLOW_CONFIRM_DELETE_PATTERNS','en','Are you sure you want to delete the routing rules?'),('JAVASCRIPT','ID_END_OF_PROCESS','en','End of process'),('JAVASCRIPT','ACCEPT','en','Accept'),('JAVASCRIPT','CANCEL','en','Cancel'),('LABEL','ID_GROUP_INACTIVE','en','Group inactive'),('LABEL','ID_JUMP','en','Jump'),('LABEL','ID_CASE_HISTORY','en','Case History'),('JAVASCRIPT','ID_CASE_HISTORY','en','Case History'),('JAVASCRIPT','ID_COLOR_LEYENDS','en','Key'),('LABEL','ID_PREVIEW','en','Preview'),('LABEL','ID_XML','en','XML'),('LABEL','ID_HTML','en','HTML'),('LABEL','ID_FIELDS_LIST','en','Fields handler'),('LABEL','ID_JAVASCRIPTS','en','JavaScripts'),('LABEL','ID_TASK_IN_PROGRESS','en','Task in Progress'),('LABEL','ID_COMPLETED_TASK','en','Completed Task'),('LABEL','ID_PENDING_TASK','en','Pending Task / Not Executed'),('LABEL','ID_PARALLEL_TASK','en','Parallel Task'),('JAVASCRIPT','ID_CLICK_VIEW_MORE_INFO','en','Click here to view more info'),('LABEL','TO_DO','en','To Do'),('LABEL','PAUSED','en','Pause'),('LABEL','COMPLETED','en','Completed'),('LABEL','CANCELLED','en','Canceled'),('LABEL','ID_NOT_FINISHED','en','Not finished'),('LABEL','ID_HOUR','en','Hour'),('LABEL','ID_HOURS','en','Hours'),('LABEL','ID_MINUTE','en','Minute'),('LABEL','ID_MINUTES','en','Minutes'),('LABEL','ID_SECOND','en','Second'),('LABEL','ID_SECONDS','en','Seconds'),('LABEL','ID_NONE','en','None'),('LABEL','ID_CASE_NOT_YET_STARTED','en','Case not yet started'),('JAVASCRIPT','ID_CONFIRM_CANCEL_CASE','en','Are you sure you want to cancel this case?'),('LABEL','ID_SETUP','en','Admin'),('LABEL','ID_PREVIOUS_STEP','en','Previous Step'),('LABEL','ID_MSG_CONFIRM_REMOVE_USER','en','Are you sure you want to remove this user?'),('LABEL','ID_MSG_CONFIRM_DEASIGN_USER_GROUP_MESSAGE','en','Are you sure you want to remove this user or group?'),('LABEL','ID_DASHBOARD','en','DASHBOARD'),('LABEL','ID_MSG_CONFIRM_REMOVE_TRIGGER','en','Are you sure you want to remove this trigger?'),('JAVASCRIPT','ID_MSG_CONFIRM_REMOVE_TRIGGER','en','Are you sure you want to remove this trigger?'),('LABEL','ID_NEW','en','New'),('JAVASCRIPT','ID_CONFIRM_REMOVE_TRIGGER','en','Are you sure you want to remove this trigger?'),('JAVASCRIPT','ID_PROCESSMAP_EXPORT_PROCESS','en','Export Process'),('JAVASCRIPT','ID_INVALID_EMAIL','en','The E-mail address is not valid.'),('LABEL','ID_NOT_WORKSPACE','en','You have specified an unavailable workspace.'),('LABEL','ID_REPORT_TABLES','en','Report Tables'),('JAVASCRIPT','ID_PROCESSMAP_REPORT_TABLES','en','Report Tables'),('LABEL','ID_NEW_REPORT_TABLE','en','New Report Table'),('LABEL','ID_EDIT_REPORT_TABLE','en','Edit Report Table'),('LABEL','ID_MSG_CONFIRM_DELETE_REPORT_TABLE','en','Do you want to delete this report table?'),('LABEL','ID_PLEASE_ENTER_REQUIRED_FIELDS','en','Please enter the required fields'),('LABEL','ID_TABLE_ALREADY_EXISTS','en','Table already exists'),('LABEL','ID_LANGUAGES','en','Language'),('LABEL','ID_EXPORT','en','Export'),('LABEL','ID_MSG_CONFIRM_REMOVE_LANGUAGE','en','Are you sure you want to remove this language?'),('LABEL','ID_MSG_CANNOT_REMOVE_LANGUAGE','en','You cannot delete the default language'),('LABEL','ID_PLEASE_SELECT_PO_FILE','en','Please select a .po file'),('LABEL','ID_EMAIL','en','Email'),('LABEL','ID_REPORT3','en','Number of cases per month'),('JAVASCRIPT','ID_ROLES_CAN_NOT_DELETE','en','This role cannot be deleted while it still has some assigned users.'),('LABEL','ID_PERMISSIONS','en','Permissions'),('LABEL','ID_MESSAGE_SUBJECT_DERIVATION','en','Notification for task assignment'),('LABEL','ID_PERMITIONS','en','Permissions'),('LABEL','ID_ASSIGN_ROLE','en','Assign user'),('JAVASCRIPT','ID_MSG_CONFIRM_DELETE_SUPERVISOR_PROCESSUSER','en','Do you want to delete this supervisor?'),('LABEL','ID_REMOVE','en','Remove'),('JAVASCRIPT','ID_MSG_CONFIRM','en','Are you sure?'),('JAVASCRIPT','ID_ROLES_MSG2','en','Role already exists! Please choose another.'),('LABEL','ID_FOLDERS','en','Documents'),('JAVASCRIPT','ID_ROLES_MSG1','en','You must specify a role code!'),('JAVASCRIPT','ID_REMOVE_ROLE','en','Are you sure you want to delete this role?'),('LABEL','ID_MSG_CONFIRM_DELETE_SUPERVISOR_DYNAFORM','en','Do you want to remove this DynaForm?'),('LABEL','VIEW_ROLE_USERS','en','Users'),('LABEL','ID_ROLES','en','ROLES'),('JAVASCRIPT','ID_PROCESSMAP_TASK_PROPERTIES_NOTIFICATIONS','en','Notifications'),('JAVASCRIPT','ID_PROCESSMAP_SUPERVISORS_DYNAFORMS','en','DynaForms'),('JAVASCRIPT','ID_ASSIGN_DYNAFORM','en','Assign DynaForm'),('LABEL','ID_TO_REVISE','en','Review'),('LABEL','ID_MESS_ENGINE_TYPE_3','en','SMTP (OpenMail)'),('LABEL','ID_MESS_TEST_MESSAGE_ERROR_PHP_MAIL','en','Test message send failed, error:'),('LABEL','ID_MESS_TEST_MESSAGE_SENDED','en','Test message sent successfully'),('LABEL','ID_MESS_ENGINE_TYPE_2','en','SMTP (PHPMailer)'),('LABEL','ID_MESS_ENGINE_TYPE_1','en','Mail (PHP)'),('LABEL','ID_MESS_TEST_BODY','en','ProcessMaker Test Email'),('LABEL','ID_MESS_TEST_SUBJECT','en','Test Email'),('JAVASCRIPT','ID_MESS_TEST_FROM_EMAIL','en','The \'From Email\' field is required'),('JAVASCRIPT','ID_MESS_TEST_TO','en','The \'To\' field is required'),('LABEL','ID_MESS_SEND_MAX_REQUIRED','en','The maximum number of attempts to send mail is a required field.'),('JAVASCRIPT','ID_MESS_EXECUTE_EVERY_REQUIRED','en','The \'Execute Every\' field is required'),('JAVASCRIPT','ID_MESS_ACCOUNT_REQUIRED','en','The email account is required'),('JAVASCRIPT','ID_DBS_EDIT','en','Edit the current Database Source'),('JAVASCRIPT','ID_PROCESSMAP_PROCESS_SUPERVISORS','en','Supervisors'),('JAVASCRIPT','ID_MESS_SERVER_REQUIRED','en','The email server is required'),('LABEL','ID_DBS_EDIT','en','Edit the current Database Source'),('JAVASCRIPT','ID_DBS_NEW','en','Add new Database Source'),('JAVASCRIPT','ID_DBS_LIST','en','Databases Source List'),('LABEL','ID_CHANGES_SAVED','en','Changes saved'),('LABEL','ID_EMAILS','en','EMAILS'),('LABEL','ID_REPORT2','en','Number of cases per process'),('LABEL','ID_REPORT1','en','Case duration by process and task'),('LABEL','ID_IUD','en','#'),('LABEL','ID_REPORTS','en','Reports'),('JAVASCRIPT','ID_MSG_CONFIRM_REMOVE_DBS','en','Are you sure you want to remove this DB Connection?'),('JAVASCRIPT','DBCONNECTIONS_MSG6','en','You must specify a user!'),('JAVASCRIPT','DBCONNECTIONS_MSG7','en','Loading test, please wait!...'),('JAVASCRIPT','DBCONNECTIONS_MSG5','en','You must specify a data base name!'),('JAVASCRIPT','DBCONNECTIONS_MSG4','en','Please specify a database server!'),('JAVASCRIPT','DBCONNECTIONS_MSG3','en','Testing'),('JAVASCRIPT','DBCONNECTIONS_MSG2','en','Failed'),('LABEL','DBCONNECTIOS_MSG2','en','FAILED'),('JAVASCRIPT','DBCONNECTIONS_MSG1','en','DONE'),('JAVASCRIPT','DBCONNECTIOS_MSG1','en','DONE'),('JAVASCRIPT','ID_NEW_DBC','en','New Database Connection'),('LABEL','ID_EDIT_DBC','en','Edit Database Connection'),('LABEL','ID_DB_CONNECTIONS','en','Database Connections'),('LABEL','ID_PRIORITY_N','en','NORMAL'),('LABEL','ID_PRIORITY_L','en','LOW'),('LABEL','ID_PRIORITY_VL','en','VERY LOW'),('LABEL','ID_PRIORITY_H','en','HIGH'),('LABEL','ID_GENERAL','en','General'),('LABEL','ID_REASSIGN','en','Reassign'),('LABEL','ID_PRIORITY_VH','en','VERY HIGH'),('LABEL','ID_GROUPS','en','Groups'),('LABEL','ID_CONFIRM_DELETE_CASE','en','Are you sure you want to delete this case?'),('JAVASCRIPT','ID_CONFIRM_DELETE_CASE','en','Are you sure you want to delete this case?'),('LABEL','ID_ACTIVATE','en','Activate'),('LABEL','ID_DEACTIVATE','en','Deactivate'),('LABEL','ID_CASECANCEL','en','No actions available for this case.'),('LABEL','ID_UNPAUSE','en','Unpause'),('JAVASCRIPT','ID_CONFIRM_PAUSE_CASE','en','Are you sure you want to pause this case?'),('JAVASCRIPT','ID_MSG_CONFIRM_REMOVE_USERGROUP','en','Are you sure you want to remove this user group?'),('LABEL','ID_MSG_CONFIRM_REMOVE_USERGROUP','en','Are you sure you want to remove this user group?'),('LABEL','ID_MSG_ASSIGN_DONE','en','User successfully assigned to group'),('LABEL','ID_ASSIGN_GROUP','en','Assign group'),('LABEL','ID_BACK_TO_GROUP_LIST','en','Back to user groups'),('LABEL','ID_ASSIGN_GROUP_TO','en','Assign group to'),('LABEL','ID_PAUSED_CASE','en','Pause'),('LABEL','ID_VIEW_USER_GROUP','en','Groups'),('LABEL','ID_EDIT_VIEW_USER_GROUP','en','View user groups'),('JAVASCRIPT','ID_MSJ','en','Group name already exists!'),('LABEL','ID_REACTIVATE','en','Reactivate'),('LABEL','ID_USER_GROUPS','en','Groups for'),('LABEL','ID_FUNCTION','en','@function() It evaluates the value, then executes a PHP function'),('JAVASCRIPT','ID_MSG_CONFIRM_REACTIVATE_CASES','en','Are you sure you want to reactivate this case?'),('LABEL','ID_CONFIRM_REACTIVATE_CASE','en','Are you sure you want to reactivate this case?'),('LABEL','ID_ESCSJS','en','@@ It replaces the value in single quotation marks to use it in JavaScript sentences.'),('LABEL','ID_ESCJS','en','@@ It replaces the value in quotation marks to use it in JavaScript sentences'),('LABEL','ID_ESC','en','@@ Replace the value in quotes'),('LABEL','ID_NONEC','en','@# Replace the value with no change'),('LABEL','ID_EURL','en','@% It replaces the value for the assignment with a GET variable in the URL'),('LABEL','ID_EVAL','en','@! It evaluates the value, then replaces it'),('LABEL','ID_NCAMBIO','en','@#, Replaces the value without any change.'),('LABEL','ID_DOCLICK','en','Double click to insert'),('LABEL','ID_CASE_IS_CURRENTLY_WITH_ANOTHER_USER','en','The case is currently opened by another user'),('LABEL','ID_IN','en','in'),('LABEL','ID_CASE_DOES_NOT_EXISTS','en','This case does not exist'),('LABEL','ID_PLEASE_SELECT_UPGRADE_FILE','en','Please select the upgrade file'),('LABEL','ID_PLEASE_SELECT_MAX_X_FIELDS','en','Please select 80 fields at most'),('LABEL','ID_UPGRADE_READY','en','System upgraded from revision'),('LABEL','ID_UPGRADE','en','Upgrade System'),('LABEL','ID_UPLOADED_DOCUMENTS','en','Uploaded Documents'),('JAVASCRIPT','ID_TASK_INFORMATION','en','Task Information'),('JAVASCRIPT','ID_UPLOADED_DOCUMENTS','en','Uploaded Documents'),('LABEL','ID_GENERATED_DOCUMENTS','en','Generated Documents'),('JAVASCRIPT','ID_GENERATED_DOCUMENTS','en','Generated Documents'),('LABEL','ID_REPORT4','en','Number of cases per starting user'),('LABEL','ID_REPORT5','en','Number of cases per executing user'),('JAVASCRIPT','ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC','en','Users & User Groups (Ad hoc)'),('LABEL','ID_SETUP_WEBSERVICES','en','Setup'),('LABEL','ID_WEB_SERVICES','en','Web Services Test'),('JAVASCRIPT','ID_PROCESS_INFORMATION','en','Process Information'),('JAVASCRIPT','ID_INFORMATION','en','Information'),('JAVASCRIPT','ID_ACTIONS','en','Actions'),('JAVASCRIPT','ID_PROCESS_MAP','en','Process Map'),('JAVASCRIPT','ID_ADHOC_ASSIGNMENT','en','Ad Hoc Assignment'),('LABEL','ID_ADHOC_ASSIGNMENT','en','Adhoc Assignment'),('JAVASCRIPT','ID_DYNAFORMS','en','DynaForms'),('LABEL','ID_TEST','en','Test'),('LABEL','ID_MONTH_1','en','January'),('LABEL','ID_MONTH_2','en','February'),('LABEL','ID_MONTH_3','en','March'),('LABEL','ID_MONTH_4','en','April'),('LABEL','ID_MONTH_5','en','May'),('LABEL','ID_MONTH_6','en','June'),('LABEL','ID_MONTH_7','en','July'),('LABEL','ID_MONTH_8','en','August'),('LABEL','ID_MONTH_9','en','September'),('LABEL','ID_MONTH_10','en','October'),('LABEL','ID_MONTH_11','en','November'),('LABEL','ID_MONTH_12','en','December'),('LABEL','ID_TO_STRING','en','Replace the value in quotes'),('LABEL','ID_TO_FLOAT','en','Replace the value converted to float'),('LABEL','ID_TO_INTEGER','en','Replace the value converted to integer'),('LABEL','ID_TO_URL','en','Replace the value with URL encoding'),('LABEL','ID_SQL_ESCAPE','en','Replace the value for use in SQL sentences'),('LABEL','ID_REPLACE_WITHOUT_CHANGES','en','Replace the value without changes'),('JAVASCRIPT','ID_REMOVE','en','Remove'),('JAVASCRIPT','ID_CONFIRM_REMOVE_DASHBOARD','en','Are you sure you want to remove this dashboard?'),('LABEL','ID_MSG_NORESULTS_USERGROUP','en','This user is not assigned to a group'),('LABEL','ID_WSDL','en','The Server Host or Workspace is blank'),('JAVASCRIPT','ID_OBJECT_PERMISSIONS','en','Process Permissions'),('LABEL','ID_YES','en','Yes'),('LABEL','ID_NO','en','No'),('LABEL','ID_ANY_TASK','en','All Tasks'),('LABEL','ID_REGENERATE','en','Regenerate'),('LABEL','ID_BLOCK','en','Block'),('LABEL','ID_ANY','en','Any'),('LABEL','ID_DISABLED','en','Disabled'),('LABEL','ID_DYNAFORM','en','DynaForm'),('LABEL','ID_INPUT_DOCUMENT','en','Input Document'),('LABEL','ID_OUTPUT_DOCUMENT','en','Output Document'),('JAVASCRIPT','ID_PLEASE_SELECT_OTHER_OBJECT_TYPE','en','Please select other object type'),('JAVASCRIPT','ID_REQUIRED_FIELDS','en','The following fields are required'),('JAVASCRIPT','ID_MSG_CONFIRM_DELETE_OBJECT_PERMISSION','en','Do you want to delete this permission ?'),('JAVASCRIPT','ID_WEB_ENTRY','en','Web Entry'),('JAVASCRIPT','ID_CASE_TRACKER','en','Case Tracker'),('JAVASCRIPT','ID_CASE_TRACKER_OBJECTS','en','Objects'),('LABEL','ID_MSG_CONFIRM_DELETE_CASE_TRACKER_OBJECT','en','Do you want to delete this object?'),('LABEL','ID_CASE_NOT_EXISTS','en','The case not exist'),('LABEL','ID_PIN_INVALID','en','The PIN is invalid'),('LABEL','ID_MAP','en','Where is my Case?'),('LABEL','ID_DYNADOC','en','My Case Forms and Documents'),('LABEL','ID_HISTORY','en','My Case History'),('JAVASCRIPT','ID_FILEGENERATED','en','Filename generated, is required!'),('JAVASCRIPT','ID_WEBENTRY','en','In order to use the Web Entry Feature, you must first create a S'),('LABEL','ID_DOWNLOAD','en','Download'),('JAVASCRIPT','ID_MSG_CONFIRM_DELETE_DIRECTORY','en','Do you want to delete this directory and delete all its contents?'),('JAVASCRIPT','ID_MSG_CONFIRM_DELETE_FILE','en','Do you want to delete this file?'),('LABEL','ID_PLEASE_SELECT_FILES_TO_UPLOAD','en','Please select the files to upload'),('JAVASCRIPT','ID_PROCESS_FILES_MANAGER','en','Process Files Manager'),('LABEL','ID_WORKSPACE','en','Workspace'),('LABEL','ID_SITE','en','Site'),('LABEL','ID_CASE','en','Case'),('LABEL','ID_TITLE','en','Title'),('LABEL','ID_FINISH_WITH_OPTION','en','Finish with option'),('LABEL','ID_CONTINUE_WITH_OPTION','en','Continue with option'),('LABEL','ID_CONTINUE','en','Continue'),('LABEL','ID_OPTION','en','Option'),('LABEL','ID_LAST_EMPLOYEE','en','Last Employee'),('LABEL','ID_EMPLOYEE','en','Employee'),('LABEL','ID_SESSION','en','Session'),('LABEL','ID_NEXT_TASK','en','Next Task'),('LABEL','ID_PERMISSIONS_FOR_THE_ROL','en','Permissions for the role'),('LABEL','ID_BACK_TO_USERS_LIST','en','Back to Users List'),('LABEL','ID_ASSIGN_THE_ROLE','en','Assign the role'),('LABEL','ID_USER_WITH_ROLE','en','Users with role'),('JAVASCRIPT','ID_EDIT_STAGES_MAP','en','Edit Stages Map'),('JAVASCRIPT','ID_PROCESSMAP_ADD_STAGE','en','Add Stage'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_STAGE','en','Delete Stage'),('LABEL','ID_HISTORY_MESSAGES','en','My History Messages'),('LABEL','ID_STAGE','en','Stage'),('JAVASCRIPT','ID_PROCESSMAP_CONFIRM_DELETE_STAGE','en','Do you want to delete the stage:'),('JAVASCRIPT','ID_PROCESSMAP_EDIT','en','Edit'),('LABEL','ID_HISTORY_MESSAGE_CASE','en','Messages History'),('JAVASCRIPT','ID_HISTORY_MESSAGE_CASE','en','Messages History'),('JAVASCRIPT','ID_PROCESSMAP_TASKS_ASSIGNED','en','Tasks Assigned'),('JAVASCRIPT','ID_PROCESSMAP_TASKS_ASSIGNED_FOR','en','Tasks Assigned For'),('JAVASCRIPT','ID_MSG_CONFIRM_REMOVE_TASK','en','Do you want to remove this task?'),('JAVASCRIPT','ID_PROCESSMAP_ADD_SUBPROCESS','en','Add Sub-Process'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_SUBPROCESS','en','Delete Sub-Process'),('JAVASCRIPT','ID_PROCESSMAP_CONFIRM_DELETE_SUBPROCESS','en','Do you want to delete the Sub-Process:'),('JAVASCRIPT','ID_CASE_TRACKER_PROPERTIES','en','Properties'),('JAVASCRIPT','ID_PROCESSMAP_PSUPERVISORS','en','Process Supervisors'),('LABEL','INVALID_FILE','en','Invalid file!'),('LABEL','ID_GET_EXTERNAL_FILE','en','Get'),('LABEL','ID_FIELD_NAME','en','Field Name'),('LABEL','ID_PREV_VALUES','en','Previous Values'),('LABEL','ID_CURRENT_VALUES','en','Current Values'),('LABEL','ID_FIELDS_CHANGED_NUMBER','en','Fields changed'),('LABEL','ID_DATA','en','Data'),('LABEL','ID_SAVE_CHANGES','en','Save Changes'),('LABEL','ID_CLASS_ALREADY_EXISTS','en','Class already exists'),('LABEL','ID_FIELD_KEY_TABLE','en','Please select one or more fields to be primary keys.'),('LABEL','ID_FIELD_FOREIGN_TABLE','en','Field \\\"table\\\" is required'),('LABEL','ID_FIELD_NAME_REQUIRED','en','Field name is required'),('LABEL','ID_FIELD_SIZE_REQUIRED','en','Field size is required'),('JAVASCRIPT','DYNAFIELD_ALREADY_EXIST','en','The field name already exists!'),('LABEL','ID_DYNAFORM_HISTORY','en','Change Log'),('LABEL','ID_CASEDEMO','en','Case Demo'),('LABEL','ID_NEED_REGISTER','en','You need to be registered to download this process. Register NOW!'),('JAVASCRIPT','ID_INCORRECT_USER_OR_PASS','en','Incorrect username or password'),('LABEL','ID_CASESREASSIGN','en','You still have cases to reassign.'),('LABEL','ID_TO_REASSIGN','en','Reassign'),('LABEL','ID_SELF_SERVICE','en','Self Service'),('LABEL','ID_TAKE','en','Take'),('LABEL','ID_STAGES','en','Stages'),('LABEL','ID_STATUS','en','Status'),('LABEL','ID_REASSIGN_TO','en','Reassign'),('LABEL','ID_NO_REASSIGN','en','Do not reassign'),('LABEL','ID_PROCESS','en','Process'),('LABEL','ID_REASSIGN_CASES','en','Reassign Cases'),('LABEL','ID_ALERT_MESSAGE','en','Alert Message'),('LABEL','ID_MSG_ERROR_USR_LASTNAME','en','Last name is required'),('LABEL','ID_MSG_ERROR_USR_FIRSTNAME','en','First name is required'),('LABEL','ID_STARTED_CASES','en','My Started Cases'),('LABEL','ID_LOGGED','en','Logged on'),('LABEL','ID_OPTIONS','en','Options'),('LABEL','ID_SKINS','en','Skins'),('LABEL','ID_ERROR_INSERT_LINE','en','Error trying to insert the line'),('JAVASCRIPT','ID_CONFIRM_PAUSE_CASE_ALERT','en','You should specify an unpause date.'),('JAVASCRIPT','CONDITIONAL_ALERT1','en','Some fields have not been filled.'),('JAVASCRIPT','CONDITIONAL_NOFIELDS_IN_CONDITION','en','No records found for conditions setup'),('LABEL','IMPORT_LANGUAGE_ERR_NO_WRITABLE','en','The XML forms directory is not writable'),('JAVASCRIPT','CONDITIONAL_ALERT2','en','You should select at least one event (OnChange or OnLoad )'),('JAVASCRIPT','CONDITIONAL_TITLE','en','CONDITIONAL SHOW/HIDE EDITOR'),('LABEL','ID_DISB_WORKSPACE','en','This site is disabled'),('LABEL','ID_WORKSPACES','en','WORKSPACES'),('LABEL','ID_MORE_INFO','en','More Info'),('LABEL','ID_CASE_ALREADY_DERIVATED','en','Case already routed'),('JAVASCRIPT','EVENT_EMAILEXISTS','en','The user or group is already in the list!'),('LABEL','ID_PENDING','en','Pending'),('JAVASCRIPT','USERS_DELETE_WITH_HISTORY','en','The user has some completed or canceled tasks (which may be useful for historical records). Do you want to delete this user anyway?'),('LABEL','ID_MSG_REMOVE_PLUGIN','en','Are you sure that you want to remove this plugin?'),('JAVASCRIPT','USERS_REASSIGN','en','This user cannot be deleted because he/she still has some pending tasks. <br/><br/>Do you want to reassign these tasks to another user now?'),('LABEL','LOGIN_VERIFY_MSG','en','Verifying...'),('LABEL','ID_ACTION','en','Action'),('LABEL','ID_EDIT_ACTION','en','Edit Action'),('LABEL','ID_PROCESSING','en','Processing, please wait...'),('LABEL','ID_FIELD_CANNOT_BE_PRIMARY_KEY','en','The type of field \'TEXT\' can\'t be a primary key'),('LABEL','ID_DYNAFORM_HASNOSUBMITBTN','en','Warning: This DynaForm does not include a [Submit] or [Button] field to save any entered data.'),('LABEL','ID_UPLOAD_VALID_CSV_FILE','en','Please upload a valid CSV file'),('JAVASCRIPT','ID_MSG_DELETE_GRID_ITEM','en','Are you sure you want to delete this row?'),('JAVASCRIPT','ID_MSG_NODELETE_GRID_ITEM','en','Can\'t delete the first row!'),('JAVASCRIPT','ID_MSG_GROUPS_ADDCONFIRM','en','At least one user must be selected.'),('LABEL','ID_DEBUG','en','Debugger'),('LABEL','ID_MSG_CONFIRM_DELETE_EVENT','en','Do you want to delete this event?'),('JAVASCRIPT','ID_MSG_CONFIRM_RESENDMSG','en','Are you sure that you want to resend this message?'),('LABEL','ID_RESEND','en','Resend'),('LABEL','ID_EDIT_EVENT','en','Edit Event'),('LABEL','ID_NEW_EVENT','en','New Event'),('JAVASCRIPT','ID_EVENTS','en','Events'),('LABEL','ID_TO','en','To'),('LABEL','ID_LINE','en','Line'),('JAVASCRIPT','ID_REQUIRED','en','The condition is required'),('LABEL','ID_DUPLICATE_ENTRY_PRIMARY_KEY','en','Duplicate entry for primary key'),('LABEL','ID_ADDITIONAL_TABLES','en','PM Tables'),('LABEL','ID_REQUEST_SENT','en','Request sent.'),('LABEL','ID_DYNAFORM_SAVE_CHANGES','en','Do you want to save changes?'),('LABEL','ID_IMPORT_USERS','en','Import Users'),('LABEL','ID_MSG_CONFIRM_DELETE_STEP','en','Are you sure you want to eliminate this step from the task?'),('LABEL','ID_AUTHENTICATION','en','Authentication'),('LABEL','ID_AUTHENTICATION_SOURCE_INVALID','en','Authentication Source for this user is invalid'),('LABEL','ID_USER_INACTIVE_BY_DATE','en','User not allowed access past due date'),('LABEL','ID_MSG_CONFIRM_DELETE_AUTH_SOURCE','en','Do you want to delete this authentication source?'),('LABEL','ID_ERROR_OBJECT_NOT_EXISTS','en','Error: Object does not exist.'),('LABEL','ID_AUTH_SOURCES','en','Authentication Sources'),('JAVASCRIPT','ID_ROLES_MSG','en','You cannot modify this role.'),('JAVASCRIPT','ID_PROCESSMAP_SUPERVISORS_INPUTS','en','Input Documents'),('JAVASCRIPT','ID_ASSIGN_INPUT_DOCUMENT','en','Assign Input Document'),('LABEL','ID_NOT_DERIVATED','en','The case couldn\'t be routed. Consult the system administrator'),('LABEL','ID_MSG_CONFIRM_DELETE_SUPERVISOR_INPUT','en','Do you want to remove this Input Document?'),('LABEL','ID_ADVANCEDSEARCH','en','Advanced Search'),('LABEL','ID_POLICY_ALERT','en','Your password does not meet the following password policies'),('LABEL','ID_PLEASE_CHANGE_PASSWORD_POLICY','en','Please change your password to one that complies with these policies.'),('LABEL','ID_PPP_MINIMUN_LENGTH','en','Minimum length'),('LABEL','ID_PPP_MAXIMUN_LENGTH','en','Maximum length'),('LABEL','ID_PPP_NUMERICAL_CHARACTER_REQUIRED','en','Numerical Character is required'),('LABEL','ID_PPP_UPPERCASE_CHARACTER_REQUIRED','en','Uppercase Character is required'),('LABEL','ID_PPP_SPECIAL_CHARACTER_REQUIRED','en','Special Character is required'),('LABEL','ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN','en','User must change his password after next login'),('LABEL','ID_PPP_EXPIRATION_IN','en','Password Expiration in'),('LABEL','ID_DAYS','en','Days'),('LABEL','ID_ACCOUNT','en','Account'),('LABEL','ID_ACCOUNT_DISABLED_CONTACT_ADMIN','en','disabled, please contact with the system administrator'),('LABEL','ID_WORKSPACE_USING','en','Using workspace'),('JAVASCRIPT','ID_REASSIGN_BYUSER_CONFIRM','en','Are you sure that you want to reassign the cases?'),('JAVASCRIPT','ID_REASSIGN_BYUSER','en','At least one item from the list must be selected.'),('JAVASCRIPT','ID_MSG_RESSIGN_BYUSER_PANEL','en','Users selection interface'),('JAVASCRIPT','ID_MSG_RESSIGN_B','en','At least one item from the list must be selected.'),('LABEL','ID_DETAILS_WEBSERVICES','en','Details'),('LABEL','ID_ERROR_STREAMING_FILE','en','doesn\'t exist. It should be saved by a plugin to a different place. Please review the configuration'),('LABEL','ID_UPLOAD_ERR_UNKNOWN','en','Unknown upload error'),('LABEL','ID_UPLOAD_ERR_EXTENSION','en','File upload stopped by extension'),('LABEL','ID_UPLOAD_ERR_CANT_WRITE','en','Failed to write file to disk'),('LABEL','ID_UPLOAD_ERR_NO_TMP_DIR','en','Missing a temporary folder'),('LABEL','ID_UPLOAD_ERR_NO_FILE','en','No file was uploaded'),('LABEL','ID_UPLOAD_ERR_PARTIAL','en','The uploaded file was only partially uploaded'),('LABEL','ID_UPLOAD_ERR_FORM_SIZE','en','The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'),('LABEL','ID_UPLOAD_ERR_INI_SIZE','en','The uploaded file exceeds the upload_max_filesize directive in php.ini'),('LABEL','ID_NOT_PROCESS_RELATED','en','Not from a Process'),('LABEL','ID_EXTERNAL_FILE','en','External'),('LABEL','ID_INFO','en','Info'),('LABEL','ID_CONFIRM_DELETE_INPUT_AND_HISTORY','en','This action will delete the current document and all its versions'),('JAVASCRIPT','ID_CONFIRM_DELETE_INPUT_AND_HISTORY','en','This will delete the current document and its past versions.'),('LABEL','ID_SETUP_MAILCONF_TITLE','en','Test SMTP Connection'),('LABEL','DBCONNECTIONS_TITLE','en','Testing database server configuration'),('LABEL','ID_DBCNN_TITLE','en','Checking server configuration'),('LABEL','ID_NOT_IN_FOLDER','en','Not in folder'),('LABEL','ID_NEW_FOLDER','en','New Folder'),('LABEL','ID_NEXT_STEP','en','Next Step'),('LABEL','ID_PM_FOLDER','en','ProcessMaker Folder'),('JAVASCRIPT','ID_INPUT_DOCUMENT_HISTORY','en','Input Document History'),('JAVASCRIPT','ID_UPLOAD_REPLACE_INPUT','en','Replace Input Document'),('JAVASCRIPT','ID_UPLOAD_NEW_INPUT_VERSION','en','Upload New Input Document Version'),('LABEL','ID_VERSION_HISTORY','en','Version History'),('JAVASCRIPT','ID_UPLOAD_NEW_INPUT','en','Upload New Input Document'),('LABEL','ID_NEW_VERSION','en','New Version'),('JAVASCRIPT','ID_ROLES_MSG3','en','You must specify a role name!'),('JAVASCRIPT','ID_PROCESSMAP_DELETE_LINE','en','Delete line'),('LABEL','ID_FIELD_HANDLER_HELP1','en','About the feature'),('LABEL','ID_FIELD_HANDLER_HELP2','en','Drag & Drop to move and reorder the fields.'),('LABEL','ID_FIELD_HANDLER_HELP3','en','Bring the mouse pointer near tool icon and the corresponding options (Edit, Delete) will be shown.'),('JAVASCRIPT','ID_CONFIRM_WEBENTRY_DELETE','en','Are you sure you want to delete this web entry?'),('LABEL','ID_CHANGE_VIEW','en','Change view'),('LABEL','ID_REMOVE_FIELD','en','Remove field'),('LABEL','ID_VISIBLE','en','Visible'),('LABEL','ID_TYPE','en','Type'),('LABEL','ID_LABEL','en','Label'),('LABEL','ID_NAME','en','Name'),('LABEL','WEBEN_ONLY_BALANCED','en','Web Entry only works with tasks which have Cyclical Assignment.<br/> Please change the Assignment Rules'),('LABEL','ID_DETAIL','en','Detail'),('LABEL','HTML_FILES','en','You can open only files with the .html extension'),('JAVASCRIPT','WEBEN_ONLY_BALANCEDJS','en','Web Entry only works with tasks which have Cyclical Assignment. Please change the Assignment Rules'),('JAVASCRIPT','HTML_FILES','en','Make sure your uploaded file has extension html or txt'),('LABEL','ID_SEARCH_RESULT','en','Search results'),('JAVASCRIPT','ID_MSG_REMOVE_PLUGIN','en','Are you sure that you want to remove this plugin?'),('LABEL','ID_MSG_REMOVE_PLUGIN_SUCCESS','en','Plugin successfully removed!'),('LABEL','CANT_DEL_LANGUAGE','en','This language cannot be deleted because it is currently being used.'),('JAVASCRIPT','ID_ADD','en','Add'),('JAVASCRIPT','CONDITIONAL_ALERT3','en','You have not tested the condition, do you want save anyway?'),('JAVASCRIPT','CONDITIONAL_ALERT4','en','You have an error in the condition, do you want save anyway?'),('LABEL','ID_ERROR','en','ERROR'),('LABEL','ID_REQUIRED_FIELDS_ERROR','en','Some required fields were not filled'),('LABEL','IMPORT_LANGUAGE_SUCCESS','en','The translation file was successfully imported.'),('JAVASCRIPT','ID_PROCESSMAP_REPORT_TO','en','Report to'),('LABEL','UID_UNDEFINED_USER','en','Undefined user'),('LABEL','ID_DEPARTAMENT_USERS','en','Departments'),('LABEL','ID_DEPARTMENTS_USERS','en','Departments'),('LABEL','ID_NEW_DEPARTMENT','en','New'),('LABEL','ID_MSG_CONFIRM_DELETE_DEPARTMENT','en','Do you want to delete this department?'),('JAVASCRIPT','ID_MSJ_DEPTO','en','Department name already exists!'),('LABEL','ID_MSJ_REPORSTO','en','The current user does not have a valid Reports To user. Please contact the administrator.'),('LABEL','ID_REMOVE_LOGO','en','Are you sure you want to delete this Logo?'),('LABEL','ID_REPLACED_LOGO','en','The logo was replaced'),('JAVASCRIPT','ID_REMOVE_LOGO','en','Are you sure you want to delete this Logo?'),('LABEL','ID_LOGO','en','Logo'),('LABEL','ID_INBOX','en','Inbox'),('LABEL','ID_OUTBOX','en','Outbox'),('LABEL','ID_CASES_MENU_FOLDERS','en','Folders'),('LABEL','ID_CASES_MENU_SEARCH','en','Search'),('LABEL','ID_CASES_MENU_ADMIN','en','Process Supervisor'),('LABEL','ID_SENT','en','Participated'),('LABEL','ID_CALENDAR','en','Calendar'),('LABEL','ID_MSG_CONFIRM_DELETE_CASE_SCHEDULER','en','Are you sure you want to delete this scheduled case?'),('LABEL','ID_SCHEDULER_LIST','en','New cases scheduler'),('LABEL','ID_SCHEDULER_LOG','en','Cases Scheduler Logs'),('LABEL','ID_MSG_CONFIRM_DELETE_IDOCUMENT','en','This object is being used in some steps. Are you sure you want to delete it?'),('JAVASCRIPT','ID_FIELD_FOREIGN_TABLE','en','Field \\\"table\\\" is required'),('JAVASCRIPT','ID_ASSIGN_RULES','en','Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn\'t be used with subprocesses'),('LABEL','ID_FIELD_INVALID','en','Field Invalid'),('LABEL','ID_WARNING','en','WARNING'),('LABEL','ID_SAVED','en','Saved'),('LABEL','ID_ASSIGN_RULES','en','Error: There is a problem with next tasks of this process, one of them have manual assignment. Manual assignment shouldn\'t be used with subprocesses'),('LABEL','ID_SELECT_OPTION_TABLE','en','Select a option to export schema or data from the selected table(s).'),('LABEL','ID_SELECT_TABLE','en','Please select a table to export.'),('LABEL','ID_TASK_WAS_ASSIGNED_TO_USER','en','Manual assignment shouldn\'t be used with subprocesses.<br>The task \\\"{0}\\\" from case {1} was assigned to user <b>{2}</b> ( {3} {4} )'),('LABEL','ID_USER_ONVACATION','en','User on vacation! Contact to your System Administrator if you want to login. please'),('LABEL','PASSWORD_HISTORY','en','Password history'),('JAVASCRIPT','ID_EMAIL_REQUIRED','en','The mail to is required, or uncheck the send a test mail'),('JAVASCRIPT','ID_PASSWORD_REQUIRED','en','The password is required, or uncheck the option Require Authentification'),('JAVASCRIPT','ID_SERVER_REQUIRED','en','You must specify a server!'),('JAVASCRIPT','ID_FILL_SERVER','en','You must specify a server!'),('LABEL','ID_CONDITIONS_EDITOR','en','Conditions editor'),('LABEL','ID_SELECT_FILE_PMT_IMPORT','en','Please select a .pmt file'),('LABEL','ID_SELECT_FILE_PM_IMPORT','en','Please select a .pm file'),('LABEL','ID_PLEASE_SELECT_PLUGIN','en','Please select the plugin'),('LABEL','ID_NO_FIELD_FOUND','en','No fields found!'),('LABEL','ID_UNASSIGNED','en','Unassigned'),('LABEL','ID_CLAIM','en','Claim'),('LABEL','ID_TABLE_INVALID_SYNTAX','en','Invalid syntax'),('LABEL','ID_NO_PERMISSION_NO_PARTICIPATED','en','You do not have permission to see this case or you have not participated in it.'),('JAVASCRIPT','ID_EMPTY_NODENAME','en','The field name contains spaces or it\'s empty!'),('JAVASCRIPT','ID_SUGGEST_NEW_ENTRIES_ALERT','en','You should set all options for new entries.'),('LABEL','ID_ISNT_LICENSE','en','This isn\'t the correct license.'),('JAVASCRIPT','ID_TABLE_RESERVED_WORDS','en','This table name is reserved. Please set another for'),('LABEL','ID_START_NEW_CASE','en','Start a new case'),('LABEL','ID_PROCESS_NOCATEGORY','en','No Category'),('LABEL','ID_PLEASE_SELECT_LOGO','en','Please Select Logo'),('LABEL','ID_TASK_NO_STEPS','en','The task doesn\'t have any steps'),('JAVASCRIPT','ID_FIELDS_RESERVED_WORDS','en','The following fields cannot have these names because they are reserved words'),('LABEL','ID_PROCESS_CATEGORY','en','Process category'),('JAVASCRIPT','ID_GROUP','en','Group'),('JAVASCRIPT','ID_DEPARTMENT','en','Department'),('LABEL','ID_BACK_PERMISSIONS_LIST','en','Back to permissions list'),('LABEL','ID_REASSIGNMENT','en','REASSIGNMENT'),('LABEL','ID_FILL_PRIMARY_KEYS','en','Please fill all the primary key fields'),('LABEL','ID_TRIGGER_SOURCE_LINK','en','Edit Source Code'),('JAVASCRIPT','ID_ASSIGN_SUPERVISOR','en','Assign Process Supervisor'),('LABEL','ADD_USERS_TO_DEPARTMENT','en','Add users to department'),('JAVASCRIPT','ID_RESET','en','Reset'),('JAVASCRIPT','ID_CREATE','en','Create'),('JAVASCRIPT','ID_DISABLE_WORKSPACE_CONFIRM','en','Do you want to disable the selected workspace?'),('JAVASCRIPT','ID_ENABLE_WORKSPACE_CONFIRM','en','Do you want enable the selected workspace?'),('LABEL','ID_ENABLE_WORKSPACE','en','Enable Workspace'),('JAVASCRIPT','DBCONNECTIONS_ALERT','en','You forgot to fill a required field!'),('LABEL','ID_DISABLE_WORKSPACE','en','Disable Workspace'),('JAVASCRIPT','NEW_SITE_SUCCESS_CONFIRMNOTE','en','Note.- If you open the new site your current session will be closed.'),('JAVASCRIPT','NEW_SITE_SUCCESS_CONFIRM','en','Do you want open the new site?'),('JAVASCRIPT','NEW_SITE_SUCCESS','en','Your new site was successfully created with name:'),('LABEL','DBCONNECTIONS_MSGR','en','Server Response'),('JAVASCRIPT','DBCONNECTIONS_MSGR','en','Server Response'),('LABEL','ID_CUSTOM_TRIGGER_DESCRIPTION','en','Custom Trigger'),('JAVASCRIPT','DBCONNECTIONS_MSGA','en','Database Connections Test was aborted'),('LABEL','ID_CUSTOM_TRIGGER','en','Custom Trigger'),('LABEL','ID_TRIGGERS_VALIDATION_ERR3','en','* The {Object} {Description} depends.'),('LABEL','ID_TRIGGERS_VALIDATION_ERR2','en','({N}) Dependencies were found for this trigger in {Object} objects'),('LABEL','ID_TRIGGERS_VALIDATION','en','No Dependencies were found for this trigger in {Object} definitions'),('JAVASCRIPT','ID_TRIGGERS_VALIDATE_EERR1','en','This trigger can\'t be deleted due to dependencies.'),('LABEL','ID_CONTACT_ADMIN','en','Please contact your system administrator'),('LABEL','ID_USER_ON_VACATIONS','en','User on vacation was replaced'),('LABEL','ID_PROCESS_DEF_PROBLEM','en','There is a problem in the process definition and/or an exception error ocurred.'),('LABEL','ID_COPY_OF','en','Copy of'),('LABEL','ID_COPY','en','Copy'),('LABEL','ID_LOADING','en','Loading, please wait...'),('LABEL','ID_CLEAR_CACHE','en','Clear Cache'),('LABEL','ID_RESTORE_LOGO','en','Restore the default logo'),('JAVASCRIPT','ID_APPLY_LOGO','en','Do you want to apply the selected Logo?'),('LABEL','ID_CLEAR_CACHE_CONFIRM1','en','Clear all cache files now?'),('LABEL','ID_SELFSERVICE','en','Self Service'),('LABEL','ID_PROCESSES','en','Processes'),('LABEL','ID_ENTER_SEARCH_TERM','en','Enter search term'),('LABEL','ID_DETAILS','en','Details'),('LABEL','ID_METHOD','en','Method'),('JAVASCRIPT','ID_FIELD_DUPLICATE','en','Duplicate Field'),('LABEL','ID_DESCRIPTION','en','Description'),('LABEL','ID_PARAMETERS','en','Parameters'),('LABEL','ID_TRIGGER_RETURN_TITLE','en','Return value'),('LABEL','ID_TRIGGER_RETURN_LABEL','en','Variable to hold return value'),('LABEL','ID_SAVE','en','Save'),('LABEL','ID_LOG_CASE_SCHEDULER','en','Case Scheduler Log'),('LABEL','ID_CASE_SCHEDULER','en','Cases Scheduler'),('LABEL','ID_NEW_CASE','en','New case'),('LABEL','OPEN_NEW_WS','en','Open new site'),('JAVASCRIPT','ERROR_NEW_WS','en','You have some mistakes, please try again'),('JAVASCRIPT','ID_ASSIGN_CASE_TO_USER','en','You have to select one employee. Select one from the dropdown list please.'),('JAVASCRIPT','DBCONNECTIONS_MSGT','en','The test has'),('JAVASCRIPT','DBCONNECTIONS_MSGS','en','Successful'),('JAVASCRIPT','DBCONNECTIONS_TEST','en','TESTING SERVER CONNECTION'),('LABEL','ID_DBC_CHECK','en','Checking server parameters'),('LABEL','ID_HOST_NAME','en','Resolving Host Name'),('LABEL','ID_CHECK_PORT','en','Checking port'),('LABEL','ID_CONNECT_HOST','en','Trying to connect to host'),('LABEL','ID_OPEN_DB','en','Trying to open database'),('LABEL','ID_SERVICE','en','Service'),('JAVASCRIPT','ID_ABORT','en','Abort'),('LABEL','ID_UNASSIGNED_USERS','en','Unassigned Users'),('LABEL','CHECK_ALL','en','Check All'),('LABEL','UNCHECK_ALL','en','Uncheck All'),('JAVASCRIPT','ID_EVENT_MULTIPLE','en','Multiple Event'),('JAVASCRIPT','ID_EVENT_MESSAGE','en','Message Event'),('JAVASCRIPT','ID_EVENT_CONDITIONAL','en','Conditional Event'),('LABEL','ID_CASES_START_PAGE','en','Home'),('LABEL','ID_PROCESS_NO_CATEGORY','en','No Category'),('LABEL','ID_USER_TO_REASSIGN','en','Reassign to:'),('LABEL','ID_REASSIGN_USERS','en','User Reassignment'),('LABEL','ID_CASES_LIST_SETUP','en','Cases Lists'),('LABEL','ID_APPCACHE_SETUP','en','Workflow Applications Cache'),('LABEL','ID_CLEAR_CACHE_MSG1','en','All cache data was deleted'),('LABEL','ID_CLEAR_CACHE_MSG2','en','The cache directory is empty'),('LABEL','ID_CASESLIST_APP_UID','en','Case Id'),('LABEL','ID_CASESLIST_DEL_INDEX','en','Case Index'),('LABEL','ID_CASESLIST_APP_NUMBER','en','#'),('LABEL','ID_CASESLIST_APP_STATUS','en','Status'),('LABEL','ID_CASESLIST_APP_TITLE','en','Case'),('LABEL','ID_CASESLIST_APP_PRO_TITLE','en','Process'),('LABEL','ID_CASESLIST_APP_TAS_TITLE','en','Task'),('LABEL','ID_CASESLIST_APP_DEL_PREVIOUS_USER','en','Sent by'),('LABEL','ID_CASESLIST_APP_CURRENT_USER','en','Current User'),('LABEL','ID_CASESLIST_DEL_TASK_DUE_DATE','en','Due Date'),('LABEL','ID_CASESLIST_APP_UPDATE_DATE','en','Last Modify'),('LABEL','ID_CASESLIST_DEL_PRIORITY','en','Priority'),('LABEL','ID_CASESLIST_APP_FINISH_DATE','en','Finish Date'),('LABEL','ID_MAINTENANCE','en','Maintenance'),('LABEL','ID_SETTINGS','en','Settings'),('LABEL','ID_TOOLS','en','Tools'),('LABEL','ID_CASES_LIST_GRID_LOADING','en','Loading Cases List, please wait...'),('LABEL','ID_CASESLIST_APP_THREAD_INDEX','en','Thread Index'),('LABEL','ID_CASESLIST_APP_DEL_INDEX','en','Del Index'),('LABEL','ID_TRIGGERS_VALIDATE_EERR1','en','* The {Object} {Description} depends.'),('LABEL','ID_CASES_STATUS_TO_DO','en','To Do'),('JAVASCRIPT','ID_DONT_SAVE_XMLFORM','en','This form has not a submit action. Do you want to continue anyway?'),('LABEL','ID_CASES_STATUS_COMPLETED','en','Completed'),('LABEL','ID_CASES_STATUS_DRAFT','en','Draft'),('LABEL','ID_PM_ENV_SETTINGS_TITLE','en','Processmaker Environment Settings'),('LABEL','ID_PM_ENV_SETTINGS_USERFIELDSET_TITLE','en','User Info. Display Settings'),('LABEL','IS_USER_NAME_DISPLAY_FORMAT','en','User Name Display Format'),('LABEL','ID_SAVE_SETTINGS','en','Save Settings'),('LABEL','ID_SAVING_ENVIRONMENT_SETTINGS','en','Saving Environment Settings'),('LABEL','ID_ENVIRONMENT_SETTINGS_MSG_1','en','You should to select a format from the list.'),('LABEL','ID_ENVIRONMENT_SETTINGS','en','Environment'),('LABEL','ID_LANG_INSTALL_UPDATE','en','Install / Update'),('LABEL','ID_LAN_LANGUAGE','en','Language'),('LABEL','ID_LAN_COUNTRY','en','Country'),('LABEL','ID_LAN_UPDATE_DATE','en','Update Date'),('LABEL','ID_LAN_REV_DATE','en','Revision Date'),('LABEL','ID_LAN_VERSION','en','Version'),('LABEL','ID_LAN_UPLOAD_TITLE','en','Upload translation file'),('LABEL','ID_LAN_FILE','en','File'),('LABEL','ID_LAN_FILE_WATER_LABEL','en','Select a translation file'),('LABEL','ID_REFRESH_LABEL','en','Refresh'),('LABEL','ID_REFRESH_MESSAGE','en','You clicked Ctrl + F5'),('LABEL','ID_OPT_READ','en','Read'),('LABEL','ID_OPT_UNREAD','en','Unread'),('LABEL','ID_OPT_ALL','en','All'),('LABEL','ID_OPT_STARTED','en','Started'),('LABEL','ID_OPT_COMPLETED','en','Completed'),('LABEL','ID_EMPTY_PROCESSES','en','Select a Process...'),('LABEL','ID_EMPTY_SEARCH','en','Search ...'),('LABEL','ID_EMPTY_CASE','en','Search Case...'),('LABEL','ID_OPT_JUMP','en','Jump To'),('LABEL','ID_DISPLAY_ITEMS','en','Display Items {0} - {1} of {2}'),('LABEL','ID_DISPLAY_EMPTY','en','Displaying Empty'),('LABEL','ID_EMPTY_PMTABLE','en','Select a PM Table...'),('LABEL','ID_HEADER_NUMBER','en','#'),('LABEL','ID_HEADER_FIELD_NAME','en','Field Name'),('LABEL','ID_HEADER_FIELD_TYPE','en','Field Type'),('LABEL','ID_HEADER_LABEL','en','Label'),('LABEL','ID_HEADER_WIDTH','en','Width'),('LABEL','ID_HEADER_ALIGN','en','Align'),('LABEL','ID_SELECTED_FIELD','en','selected field'),('LABEL','ID_AVAILABLE_FIELDS','en','Available Fields'),('LABEL','ID_CASES_LIST_FIELDS','en','Cases List Fields'),('LABEL','ID_TITLE_INBOX','en','Inbox'),('LABEL','ID_TITLE_DRAFT','en','Draft'),('LABEL','ID_TITLE_PARTICIPATED','en','Participated'),('LABEL','ID_TITLE_UNASSIGNED','en','Unassigned'),('LABEL','ID_TITLE_PAUSED','en','Paused'),('LABEL','ID_TITLE_COMPLETED','en','Completed'),('LABEL','ID_TITLE_CANCELLED','en','Cancelled'),('LABEL','ID_PM_TABLE','en','PM Table'),('LABEL','ID_ROWS_PER_PAGE','en','Rows per Page'),('LABEL','ID_DATE_FORMAT','en','Date Format'),('LABEL','ID_RESET','en','Reset'),('LABEL','ID_APPLY_CHANGES','en','Apply changes'),('LABEL','ID_INTERNATIONAL','en','International'),('LABEL','ID_BREAK_DW_PROCESS','en','were lost by a connection problem.'),('LABEL','ID_CATEGORY','en','Category'),('LABEL','ID_BROWSE_LIBRARY','en','Browse Library'),('LABEL','ID_IMPORT','en','Import'),('LABEL','ID_PRO_TITLE','en','Process Title'),('LABEL','ID_DISPLAY_OF','en','of'),('LABEL','ID_DELETE_LANGUAGE_WARNING','en','To delete a language you should select a item from the list first.'),('LABEL','ID_DELETE_LANGUAGE_CONFIRM','en','Do you want remove the language \\\"{0}\\\" ?'),('LABEL','ID_DELETE_LANGUAGE','en','Remove'),('LABEL','ID_LANGUAGE_DELETED_SUCCESSFULLY','en','Language deleted successfully!'),('LABEL','ID_LANGUAGE_CANT_DELETE','en','There is {0} cases started with this language, delete action canceled!'),('LABEL','ID_TOTAL_CASES','en','Total Cases'),('LABEL','ID_HEARTBEAT_CONFIG','en','Heart Beat'),('LABEL','ID_PM_HEARTBEAT_SETTINGS_TITLE','en','Heart Beat Configuration'),('LABEL','ID_SETTINGS_HEARTBEAT_TITLE','en','Display Setting'),('LABEL','ID_HEARTBEAT_DISPLAY','en','Heart Beat'),('JAVASCRIPT','ID_MAIL_SUCESSFULLY','en','Test message sent successfully'),('JAVASCRIPT','ID_MAIL_FAILED','en','The test failure, you must configure your\\r\\nserver to send messages'),('LABEL','ID_CACHE_DIR_ISNOT_WRITABLE','en','The cache directory is not writable, change permissions please!'),('LABEL','ID_CACHE_DELETED_SUCCESS','en','All cache data was deleted successfully'),('JAVASCRIPT','ID_EMAIL_INVALID','en','The mail is invalid'),('LABEL','MSG_CONDITION_NOT_DEFINED','en','Condition variable not defined'),('JAVASCRIPT','ID_RSTDATAFIELD','en','Reset Data Field'),('LABEL','ID_OPEN_IN_:POPUP','en','Open in a popup'),('LABEL','ID_DEATACH','en','Deatach'),('LABEL','ID_PRO_USER','en','User Owner'),('LABEL','ID_SYSTEM','en','System'),('LABEL','ID_VARIABLES','en','Variables'),('LABEL','ID_OPEN_CASE','en','Opening case :'),('LABEL','ID_CASES_STATUS_CANCELLED','en','Cancelled'),('LABEL','ID_CASES_STATUS_PAUSED','en','Paused'),('LABEL','ID_ALL_PROCESS','en','All Processes'),('LABEL','ID_ALL_USERS','en','All Users'),('LABEL','ID_ALL_STATUS','en','All Status'),('LABEL','ID_CONFIRM','en','Confirm'),('LABEL','ID_CONFIRM_UNPAUSE_CASE','en','Are you sure you want to unpause this case?'),('LABEL','ID_PRO_DESCRIPTION','en','Process Description'),('LABEL','ID_PRO_DEBUG','en','Debug'),('LABEL','ID_PRO_CREATE_DATE','en','Create Date'),('LABEL','ID_ON','en','On'),('LABEL','ID_OFF','en','Off'),('LABEL','ID_NO_SELECTION_WARNING','en','Select a item from the list please.'),('JAVASCRIPT','ID_REQUIRED_NAME_TRIGGERS','en','You forgot the title of the trigger'),('JAVASCRIPT','ID_EXIST_PROCESS','en','There is a process with the same name. this process will not save'),('JAVASCRIPT','ID_EXIST_DYNAFORM','en','There is a Dynaform with the same name in this process. It is not saving '),('LABEL','ID_CLASS_TABLE_DOESNT_EXIST','en','This Class Table doesn\'t exists! '),('JAVASCRIPT','ID_EXIST_INPUTDOCUMENT','en','There is an Input Document with the same name in this process. It is not saving '),('JAVASCRIPT','ID_EXIST_OUTPUTDOCUMENT','en','There is an Output Document with the same name in this process. It is not saving '),('LABEL','ID_DELEGATE_DATE_FROM','en','Delegated date from'),('JAVASCRIPT','ID_DUPLICATE_CATEGORY_NAME','en','Duplicate category name.'),('LABEL','ID_DELEGATE_DATE_TO','en','to'),('LABEL','ID_FILTER_BY_DELEGATED_DATE','en','Filter'),('LABEL','ID_PM_ENV_SETTINGS_REGIONFIELDSET_TITLE','en','Regional Settings'),('LABEL','ID_GLOBAL_DATE_MASK','en','Global date mask'),('LABEL','ID_SAVED_SUCCESSFULLY','en','Saved Successfully'),('LABEL','PENTAHO_LABEL_CONFIGURATION','en','Configuration'),('LABEL','PENTAHO_LABEL_DATASOURCE','en','Datasource Name'),('LABEL','PENTAHO_LABEL_DB_EXISTS','en','Datasource already exist'),('LABEL','PENTAHO_LABEL_DB_SUCCESS','en','Datasource created successfully'),('LABEL','PENTAHO_LABEL_DRIVER_CLASS','en','Driver Class'),('LABEL','PENTAHO_LABEL_JNDI_CONNECTION','en','JNDI Connection'),('LABEL','PENTAHO_LABEL_JNDI_INFORMATION','en','JNDI Information'),('LABEL','PENTAHO_LABEL_PASSWORD','en','Password'),('LABEL','PENTAHO_LABEL_REBUILD','en','Rebuild'),('LABEL','PENTAHO_LABEL_ROLES_MANAGER','en','Roles Manager'),('LABEL','PENTAHO_LABEL_SERVER','en','Pentaho Server (URL)'),('LABEL','PENTAHO_LABEL_SHOW_JNDI_INFORMATION','en','Show Jndi Info'),('LABEL','PENTAHO_LABEL_SYNC','en','Sync to Pentaho Solution'),('LABEL','PENTAHO_LABEL_TABLE_ALREADY_SYNCH','en','Workspace already synchronized with Pentaho Solution'),('LABEL','PENTAHO_LABEL_TABLE_SUCCESS','en','Table APP_CACHE_VIEW and triggers are installed successfully'),('LABEL','PENTAHO_LABEL_TABLE_SYNCHED','en','Workspace synchronized with Pentaho Solution'),('LABEL','PENTAHO_LABEL_TABLE_TRIGGERS','en','Database tables and triggers'),('LABEL','PENTAHO_LABEL_URL','en','URL'),('LABEL','PENTAHO_LABEL_USER_CONSOLE','en','Pentaho User Console'),('LABEL','PENTAHO_LABEL_USER_CREATE','en','Create user in Pentaho'),('LABEL','PENTAHO_LABEL_USER_CREATED','en','User created successfully'),('LABEL','PENTAHO_LABEL_USER_EXIST','en','User already exist'),('LABEL','PENTAHO_LABEL_USER_NAME','en','User Name'),('LABEL','PENTAHO_LABEL_WS_SYNCHED','en','Workspace synchronized with Pentaho Solution'),('LABEL','PENTAHO_LABEL_WS_USER_PASSWORD','en','Pentaho Workspace User and Password'),('LABEL','PENTAHO_TABLES_TRIGGERS','en','Database tables and triggers'),('JAVASCRIPT','ID_EXIST_TRIGGERS','en','There is a triggers with the same name in this process.'),('LABEL','ID_SELECT_ONE_AT_LEAST','en','Select at least one item from the list'),('LABEL','ID_MSG_CONFIRM_DELETE_CASES2','en','Are you sure you want to delete all selected case?'),('LABEL','ID_PAUSE_CASE_TO_DATE','en','Do you want to pause the case to date: '); +INSERT INTO `USERS` VALUES ('00000000000000000000000000000001','admin','21232f297a57a5a743894a0e4a801fc3','Administrator','','admin@processmaker.com','2020-01-01','1999-11-30 00:00:00','2008-05-23 18:36:19','ACTIVE','US','FL','MMK','','','1-305-402-0282','1-305-675-1400','','','Administrator','','1999-02-25','PROCESSMAKER_ADMIN',NULL,NULL); diff --git a/workflow/engine/data/mysql/schema.sql b/workflow/engine/data/mysql/schema.sql new file mode 100644 index 000000000..e4cf23fa0 --- /dev/null +++ b/workflow/engine/data/mysql/schema.sql @@ -0,0 +1,1294 @@ + +# This is a fix for InnoDB in MySQL >= 4.1.x +# It "suspends judgement" for fkey relationships until are tables are set. +SET FOREIGN_KEY_CHECKS = 0; + +#----------------------------------------------------------------------------- +#-- APPLICATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APPLICATION`; + + +CREATE TABLE `APPLICATION` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `APP_NUMBER` INTEGER default 0 NOT NULL, + `APP_PARENT` VARCHAR(32) default '0' NOT NULL, + `APP_STATUS` VARCHAR(100) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `APP_PROC_STATUS` VARCHAR(100) default '' NOT NULL, + `APP_PROC_CODE` VARCHAR(100) default '' NOT NULL, + `APP_PARALLEL` VARCHAR(32) default 'NO' NOT NULL, + `APP_INIT_USER` VARCHAR(32) default '' NOT NULL, + `APP_CUR_USER` VARCHAR(32) default '' NOT NULL, + `APP_CREATE_DATE` DATETIME NOT NULL, + `APP_INIT_DATE` DATETIME NOT NULL, + `APP_FINISH_DATE` DATETIME NOT NULL, + `APP_UPDATE_DATE` DATETIME NOT NULL, + `APP_DATA` TEXT NOT NULL, + `APP_PIN` VARCHAR(32) default '', + PRIMARY KEY (`APP_UID`), + KEY `indexApp`(`PRO_UID`, `APP_STATUS`, `APP_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='The application'; +#----------------------------------------------------------------------------- +#-- APP_DELEGATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_DELEGATION`; + + +CREATE TABLE `APP_DELEGATION` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `DEL_PREVIOUS` INTEGER default 0 NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `DEL_TYPE` VARCHAR(32) default 'NORMAL' NOT NULL, + `DEL_THREAD` INTEGER default 0 NOT NULL, + `DEL_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `DEL_PRIORITY` VARCHAR(32) default '3' NOT NULL, + `DEL_DELEGATE_DATE` DATETIME NOT NULL, + `DEL_INIT_DATE` DATETIME, + `DEL_TASK_DUE_DATE` DATETIME, + `DEL_FINISH_DATE` DATETIME, + `DEL_DURATION` DOUBLE default 0, + `DEL_QUEUE_DURATION` DOUBLE default 0, + `DEL_DELAY_DURATION` DOUBLE default 0, + `DEL_STARTED` TINYINT default 0, + `DEL_FINISHED` TINYINT default 0, + `DEL_DELAYED` TINYINT default 0, + `DEL_DATA` TEXT NOT NULL, + `APP_OVERDUE_PERCENTAGE` DOUBLE default 0 NOT NULL, + PRIMARY KEY (`APP_UID`,`DEL_INDEX`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Delegation a task to user'; +#----------------------------------------------------------------------------- +#-- APP_DOCUMENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_DOCUMENT`; + + +CREATE TABLE `APP_DOCUMENT` +( + `APP_DOC_UID` VARCHAR(32) default '' NOT NULL, + `DOC_VERSION` INTEGER default 1 NOT NULL, + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `DOC_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `APP_DOC_TYPE` VARCHAR(32) default '' NOT NULL, + `APP_DOC_CREATE_DATE` DATETIME NOT NULL, + `APP_DOC_INDEX` INTEGER NOT NULL, + `FOLDER_UID` VARCHAR(32) default '', + `APP_DOC_PLUGIN` VARCHAR(150) default '', + `APP_DOC_TAGS` TEXT, + `APP_DOC_STATUS` VARCHAR(32) default 'ACTIVE' NOT NULL, + `APP_DOC_STATUS_DATE` DATETIME, + PRIMARY KEY (`APP_DOC_UID`,`DOC_VERSION`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Documents in an Application'; +#----------------------------------------------------------------------------- +#-- APP_MESSAGE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_MESSAGE`; + + +CREATE TABLE `APP_MESSAGE` +( + `APP_MSG_UID` VARCHAR(32) NOT NULL, + `MSG_UID` VARCHAR(32), + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `APP_MSG_TYPE` VARCHAR(100) default '' NOT NULL, + `APP_MSG_SUBJECT` VARCHAR(150) default '' NOT NULL, + `APP_MSG_FROM` VARCHAR(100) default '' NOT NULL, + `APP_MSG_TO` TEXT NOT NULL, + `APP_MSG_BODY` TEXT NOT NULL, + `APP_MSG_DATE` DATETIME NOT NULL, + `APP_MSG_CC` TEXT, + `APP_MSG_BCC` TEXT, + `APP_MSG_TEMPLATE` TEXT, + `APP_MSG_STATUS` VARCHAR(20), + `APP_MSG_ATTACH` TEXT, + `APP_MSG_SEND_DATE` DATETIME NOT NULL, + PRIMARY KEY (`APP_MSG_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Messages in an Application'; +#----------------------------------------------------------------------------- +#-- APP_OWNER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_OWNER`; + + +CREATE TABLE `APP_OWNER` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `OWN_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`APP_UID`,`OWN_UID`,`USR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- CONFIGURATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CONFIGURATION`; + + +CREATE TABLE `CONFIGURATION` +( + `CFG_UID` VARCHAR(32) default '' NOT NULL, + `OBJ_UID` VARCHAR(128) default '' NOT NULL, + `CFG_VALUE` TEXT NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `APP_UID` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`CFG_UID`,`OBJ_UID`,`PRO_UID`,`USR_UID`,`APP_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Stores the users, processes and/or applications configuratio'; +#----------------------------------------------------------------------------- +#-- CONTENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CONTENT`; + + +CREATE TABLE `CONTENT` +( + `CON_CATEGORY` VARCHAR(30) default '' NOT NULL, + `CON_PARENT` VARCHAR(32) default '' NOT NULL, + `CON_ID` VARCHAR(100) default '' NOT NULL, + `CON_LANG` VARCHAR(10) default '' NOT NULL, + `CON_VALUE` TEXT NOT NULL, + PRIMARY KEY (`CON_CATEGORY`,`CON_PARENT`,`CON_ID`,`CON_LANG`), + KEY `indexUid`(`CON_ID`, `CON_CATEGORY`, `CON_LANG`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- DEPARTMENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `DEPARTMENT`; + + +CREATE TABLE `DEPARTMENT` +( + `DEP_UID` VARCHAR(32) default '' NOT NULL, + `DEP_PARENT` VARCHAR(32) default '' NOT NULL, + `DEP_MANAGER` VARCHAR(32) default '' NOT NULL, + `DEP_LOCATION` INTEGER default 0 NOT NULL, + `DEP_STATUS` VARCHAR(10) default 'ACTIVE' NOT NULL, + `DEP_REF_CODE` VARCHAR(50) default '' NOT NULL, + `DEP_LDAP_DN` VARCHAR(255) default '' NOT NULL, + PRIMARY KEY (`DEP_UID`), + KEY `DEP_BYPARENT`(`DEP_PARENT`), + KEY `BY_DEP_LDAP_DN`(`DEP_LDAP_DN`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Departments'; +#----------------------------------------------------------------------------- +#-- DYNAFORM +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `DYNAFORM`; + + +CREATE TABLE `DYNAFORM` +( + `DYN_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `DYN_TYPE` VARCHAR(20) default 'xmlform' NOT NULL, + `DYN_FILENAME` VARCHAR(100) default '' NOT NULL, + PRIMARY KEY (`DYN_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Forms required'; +#----------------------------------------------------------------------------- +#-- GROUPWF +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `GROUPWF`; + + +CREATE TABLE `GROUPWF` +( + `GRP_UID` VARCHAR(32) default '' NOT NULL, + `GRP_STATUS` CHAR(8) default 'ACTIVE' NOT NULL, + PRIMARY KEY (`GRP_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- GROUP_USER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `GROUP_USER`; + + +CREATE TABLE `GROUP_USER` +( + `GRP_UID` VARCHAR(32) default '0' NOT NULL, + `USR_UID` VARCHAR(32) default '0' NOT NULL, + PRIMARY KEY (`GRP_UID`,`USR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- HOLIDAY +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `HOLIDAY`; + + +CREATE TABLE `HOLIDAY` +( + `HLD_UID` INTEGER NOT NULL AUTO_INCREMENT, + `HLD_DATE` VARCHAR(10) default '0000-00-00' NOT NULL, + `HLD_DESCRIPTION` VARCHAR(200) default '' NOT NULL, + PRIMARY KEY (`HLD_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- INPUT_DOCUMENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `INPUT_DOCUMENT`; + + +CREATE TABLE `INPUT_DOCUMENT` +( + `INP_DOC_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `INP_DOC_FORM_NEEDED` VARCHAR(20) default 'REAL' NOT NULL, + `INP_DOC_ORIGINAL` VARCHAR(20) default 'COPY' NOT NULL, + `INP_DOC_PUBLISHED` VARCHAR(20) default 'PRIVATE' NOT NULL, + `INP_DOC_VERSIONING` TINYINT default 0 NOT NULL, + `INP_DOC_DESTINATION_PATH` TEXT, + `INP_DOC_TAGS` TEXT, + PRIMARY KEY (`INP_DOC_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Documentation required'; +#----------------------------------------------------------------------------- +#-- ISO_COUNTRY +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `ISO_COUNTRY`; + + +CREATE TABLE `ISO_COUNTRY` +( + `IC_UID` VARCHAR(2) default '' NOT NULL, + `IC_NAME` VARCHAR(255), + `IC_SORT_ORDER` VARCHAR(255), + PRIMARY KEY (`IC_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- ISO_LOCATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `ISO_LOCATION`; + + +CREATE TABLE `ISO_LOCATION` +( + `IC_UID` VARCHAR(2) default '' NOT NULL, + `IL_UID` VARCHAR(5) default '' NOT NULL, + `IL_NAME` VARCHAR(255), + `IL_NORMAL_NAME` VARCHAR(255), + `IS_UID` VARCHAR(4), + PRIMARY KEY (`IC_UID`,`IL_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- ISO_SUBDIVISION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `ISO_SUBDIVISION`; + + +CREATE TABLE `ISO_SUBDIVISION` +( + `IC_UID` VARCHAR(2) default '' NOT NULL, + `IS_UID` VARCHAR(4) default '' NOT NULL, + `IS_NAME` VARCHAR(255) default '' NOT NULL, + PRIMARY KEY (`IC_UID`,`IS_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- LANGUAGE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `LANGUAGE`; + + +CREATE TABLE `LANGUAGE` +( + `LAN_ID` VARCHAR(4) default '' NOT NULL, + `LAN_NAME` VARCHAR(30) default '' NOT NULL, + `LAN_NATIVE_NAME` VARCHAR(30) default '' NOT NULL, + `LAN_DIRECTION` CHAR(1) default 'L' NOT NULL, + `LAN_WEIGHT` INTEGER default 0 NOT NULL, + `LAN_ENABLED` CHAR(1) default '1' NOT NULL, + `LAN_CALENDAR` VARCHAR(30) default 'GREGORIAN' NOT NULL, + PRIMARY KEY (`LAN_ID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- LEXICO +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `LEXICO`; + + +CREATE TABLE `LEXICO` +( + `LEX_TOPIC` VARCHAR(64) default '' NOT NULL, + `LEX_KEY` VARCHAR(128) default '' NOT NULL, + `LEX_VALUE` VARCHAR(128) default '' NOT NULL, + `LEX_CAPTION` VARCHAR(128) default '' NOT NULL, + PRIMARY KEY (`LEX_TOPIC`,`LEX_KEY`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='LEXICOS, una tabla que contiene tablas'; +#----------------------------------------------------------------------------- +#-- OUTPUT_DOCUMENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `OUTPUT_DOCUMENT`; + + +CREATE TABLE `OUTPUT_DOCUMENT` +( + `OUT_DOC_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `OUT_DOC_LANDSCAPE` TINYINT default 0 NOT NULL, + `OUT_DOC_MEDIA` VARCHAR(10) default 'Letter' NOT NULL, + `OUT_DOC_LEFT_MARGIN` INTEGER default 30, + `OUT_DOC_RIGHT_MARGIN` INTEGER default 15, + `OUT_DOC_TOP_MARGIN` INTEGER default 15, + `OUT_DOC_BOTTOM_MARGIN` INTEGER default 15, + `OUT_DOC_GENERATE` VARCHAR(10) default 'BOTH' NOT NULL, + `OUT_DOC_TYPE` VARCHAR(32) default 'HTML' NOT NULL, + `OUT_DOC_CURRENT_REVISION` INTEGER default 0, + `OUT_DOC_FIELD_MAPPING` TEXT, + `OUT_DOC_VERSIONING` TINYINT default 0 NOT NULL, + `OUT_DOC_DESTINATION_PATH` TEXT, + `OUT_DOC_TAGS` TEXT, + PRIMARY KEY (`OUT_DOC_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- PROCESS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `PROCESS`; + + +CREATE TABLE `PROCESS` +( + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `PRO_PARENT` VARCHAR(32) default '0' NOT NULL, + `PRO_TIME` DOUBLE default 1 NOT NULL, + `PRO_TIMEUNIT` VARCHAR(20) default 'DAYS' NOT NULL, + `PRO_STATUS` VARCHAR(20) default 'ACTIVE' NOT NULL, + `PRO_TYPE_DAY` CHAR(1) default '0' NOT NULL, + `PRO_TYPE` VARCHAR(20) default 'NORMAL' NOT NULL, + `PRO_ASSIGNMENT` VARCHAR(20) default 'FALSE' NOT NULL, + `PRO_SHOW_MAP` TINYINT default 1 NOT NULL, + `PRO_SHOW_MESSAGE` TINYINT default 1 NOT NULL, + `PRO_SHOW_DELEGATE` TINYINT default 1 NOT NULL, + `PRO_SHOW_DYNAFORM` TINYINT default 0 NOT NULL, + `PRO_CATEGORY` VARCHAR(48) default '' NOT NULL, + `PRO_SUB_CATEGORY` VARCHAR(48) default '' NOT NULL, + `PRO_INDUSTRY` INTEGER default 1 NOT NULL, + `PRO_UPDATE_DATE` DATETIME, + `PRO_CREATE_DATE` DATETIME NOT NULL, + `PRO_CREATE_USER` VARCHAR(32) default '' NOT NULL, + `PRO_HEIGHT` INTEGER default 5000 NOT NULL, + `PRO_WIDTH` INTEGER default 10000 NOT NULL, + `PRO_TITLE_X` INTEGER default 0 NOT NULL, + `PRO_TITLE_Y` INTEGER default 6 NOT NULL, + `PRO_DEBUG` INTEGER default 0 NOT NULL, + PRIMARY KEY (`PRO_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Store process Information'; +#----------------------------------------------------------------------------- +#-- PROCESS_OWNER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `PROCESS_OWNER`; + + +CREATE TABLE `PROCESS_OWNER` +( + `OWN_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`OWN_UID`,`PRO_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- REPORT_TABLE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `REPORT_TABLE`; + + +CREATE TABLE `REPORT_TABLE` +( + `REP_TAB_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `REP_TAB_NAME` VARCHAR(100) default '' NOT NULL, + `REP_TAB_TYPE` VARCHAR(6) default '' NOT NULL, + `REP_TAB_GRID` VARCHAR(150) default '', + `REP_TAB_CONNECTION` VARCHAR(32) default '' NOT NULL, + `REP_TAB_CREATE_DATE` DATETIME NOT NULL, + `REP_TAB_STATUS` CHAR(8) default 'ACTIVE' NOT NULL, + PRIMARY KEY (`REP_TAB_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- REPORT_VAR +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `REPORT_VAR`; + + +CREATE TABLE `REPORT_VAR` +( + `REP_VAR_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `REP_TAB_UID` VARCHAR(32) default '' NOT NULL, + `REP_VAR_NAME` VARCHAR(255) default '' NOT NULL, + `REP_VAR_TYPE` VARCHAR(20) default '' NOT NULL, + PRIMARY KEY (`REP_VAR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- ROUTE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `ROUTE`; + + +CREATE TABLE `ROUTE` +( + `ROU_UID` VARCHAR(32) default '' NOT NULL, + `ROU_PARENT` VARCHAR(32) default '0' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `ROU_NEXT_TASK` VARCHAR(32) default '0' NOT NULL, + `ROU_CASE` INTEGER default 0 NOT NULL, + `ROU_TYPE` VARCHAR(25) default 'SEQUENTIAL' NOT NULL, + `ROU_CONDITION` VARCHAR(255) default '' NOT NULL, + `ROU_TO_LAST_USER` VARCHAR(20) default 'FALSE' NOT NULL, + `ROU_OPTIONAL` VARCHAR(20) default 'FALSE' NOT NULL, + `ROU_SEND_EMAIL` VARCHAR(20) default 'TRUE' NOT NULL, + `ROU_SOURCEANCHOR` INTEGER default 1, + `ROU_TARGETANCHOR` INTEGER default 0, + PRIMARY KEY (`ROU_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Differents flows for a flow in business process'; +#----------------------------------------------------------------------------- +#-- STEP +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `STEP`; + + +CREATE TABLE `STEP` +( + `STEP_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `TAS_UID` VARCHAR(32) default '0' NOT NULL, + `STEP_TYPE_OBJ` VARCHAR(20) default 'DYNAFORM' NOT NULL, + `STEP_UID_OBJ` VARCHAR(32) default '0' NOT NULL, + `STEP_CONDITION` TEXT NOT NULL, + `STEP_POSITION` INTEGER default 0 NOT NULL, + `STEP_MODE` VARCHAR(10) default 'EDIT', + PRIMARY KEY (`STEP_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- STEP_TRIGGER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `STEP_TRIGGER`; + + +CREATE TABLE `STEP_TRIGGER` +( + `STEP_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `TRI_UID` VARCHAR(32) default '' NOT NULL, + `ST_TYPE` VARCHAR(20) default '' NOT NULL, + `ST_CONDITION` VARCHAR(255) default '' NOT NULL, + `ST_POSITION` INTEGER default 0 NOT NULL, + PRIMARY KEY (`STEP_UID`,`TAS_UID`,`TRI_UID`,`ST_TYPE`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- SWIMLANES_ELEMENTS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `SWIMLANES_ELEMENTS`; + + +CREATE TABLE `SWIMLANES_ELEMENTS` +( + `SWI_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `SWI_TYPE` VARCHAR(20) default 'LINE' NOT NULL, + `SWI_X` INTEGER default 0 NOT NULL, + `SWI_Y` INTEGER default 0 NOT NULL, + PRIMARY KEY (`SWI_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- TASK +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `TASK`; + + +CREATE TABLE `TASK` +( + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `TAS_TYPE` VARCHAR(20) default 'NORMAL' NOT NULL, + `TAS_DURATION` DOUBLE default 0 NOT NULL, + `TAS_DELAY_TYPE` VARCHAR(30) default '' NOT NULL, + `TAS_TEMPORIZER` DOUBLE default 0 NOT NULL, + `TAS_TYPE_DAY` CHAR(1) default '1' NOT NULL, + `TAS_TIMEUNIT` VARCHAR(20) default 'DAYS' NOT NULL, + `TAS_ALERT` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_PRIORITY_VARIABLE` VARCHAR(100) default '' NOT NULL, + `TAS_ASSIGN_TYPE` VARCHAR(30) default 'BALANCED' NOT NULL, + `TAS_ASSIGN_VARIABLE` VARCHAR(100) default '@@SYS_NEXT_USER_TO_BE_ASSIGNED' NOT NULL, + `TAS_ASSIGN_LOCATION` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_ASSIGN_LOCATION_ADHOC` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_TRANSFER_FLY` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_LAST_ASSIGNED` VARCHAR(32) default '0' NOT NULL, + `TAS_USER` VARCHAR(32) default '0' NOT NULL, + `TAS_CAN_UPLOAD` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_VIEW_UPLOAD` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_VIEW_ADDITIONAL_DOCUMENTATION` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_CAN_CANCEL` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_OWNER_APP` VARCHAR(32) default '' NOT NULL, + `STG_UID` VARCHAR(32) default '' NOT NULL, + `TAS_CAN_PAUSE` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_CAN_SEND_MESSAGE` VARCHAR(20) default 'TRUE' NOT NULL, + `TAS_CAN_DELETE_DOCS` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_SELF_SERVICE` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_START` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_TO_LAST_USER` VARCHAR(20) default 'FALSE' NOT NULL, + `TAS_SEND_LAST_EMAIL` VARCHAR(20) default 'TRUE' NOT NULL, + `TAS_DERIVATION` VARCHAR(100) default 'NORMAL' NOT NULL, + `TAS_POSX` INTEGER default 0 NOT NULL, + `TAS_POSY` INTEGER default 0 NOT NULL, + `TAS_COLOR` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`TAS_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Task of workflow'; +#----------------------------------------------------------------------------- +#-- TASK_USER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `TASK_USER`; + + +CREATE TABLE `TASK_USER` +( + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `TU_TYPE` INTEGER default 1 NOT NULL, + `TU_RELATION` INTEGER default 0 NOT NULL, + PRIMARY KEY (`TAS_UID`,`USR_UID`,`TU_TYPE`,`TU_RELATION`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- TRANSLATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `TRANSLATION`; + + +CREATE TABLE `TRANSLATION` +( + `TRN_CATEGORY` VARCHAR(100) default '' NOT NULL, + `TRN_ID` VARCHAR(100) default '' NOT NULL, + `TRN_LANG` VARCHAR(10) default 'en' NOT NULL, + `TRN_VALUE` VARCHAR(200) default '' NOT NULL, + PRIMARY KEY (`TRN_CATEGORY`,`TRN_ID`,`TRN_LANG`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- TRIGGERS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `TRIGGERS`; + + +CREATE TABLE `TRIGGERS` +( + `TRI_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TRI_TYPE` VARCHAR(20) default 'SCRIPT' NOT NULL, + `TRI_WEBBOT` TEXT NOT NULL, + `TRI_PARAM` TEXT, + PRIMARY KEY (`TRI_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- USERS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `USERS`; + + +CREATE TABLE `USERS` +( + `USR_UID` VARCHAR(32) default '' NOT NULL, + `USR_USERNAME` VARCHAR(100) default '' NOT NULL, + `USR_PASSWORD` VARCHAR(32) default '' NOT NULL, + `USR_FIRSTNAME` VARCHAR(50) default '' NOT NULL, + `USR_LASTNAME` VARCHAR(50) default '' NOT NULL, + `USR_EMAIL` VARCHAR(100) default '' NOT NULL, + `USR_DUE_DATE` DATE NOT NULL, + `USR_CREATE_DATE` DATETIME NOT NULL, + `USR_UPDATE_DATE` DATETIME NOT NULL, + `USR_STATUS` VARCHAR(32) default 'ACTIVE' NOT NULL, + `USR_COUNTRY` VARCHAR(3) default '' NOT NULL, + `USR_CITY` VARCHAR(3) default '' NOT NULL, + `USR_LOCATION` VARCHAR(3) default '' NOT NULL, + `USR_ADDRESS` VARCHAR(255) default '' NOT NULL, + `USR_PHONE` VARCHAR(24) default '' NOT NULL, + `USR_FAX` VARCHAR(24) default '' NOT NULL, + `USR_CELLULAR` VARCHAR(24) default '' NOT NULL, + `USR_ZIP_CODE` VARCHAR(16) default '' NOT NULL, + `DEP_UID` VARCHAR(32) default '' NOT NULL, + `USR_POSITION` VARCHAR(100) default '' NOT NULL, + `USR_RESUME` VARCHAR(100) default '' NOT NULL, + `USR_BIRTHDAY` DATE NOT NULL, + `USR_ROLE` VARCHAR(32) default 'PROCESSMAKER_ADMIN', + `USR_REPORTS_TO` VARCHAR(32) default '', + `USR_REPLACED_BY` VARCHAR(32) default '', + PRIMARY KEY (`USR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Users'; +#----------------------------------------------------------------------------- +#-- APP_THREAD +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_THREAD`; + + +CREATE TABLE `APP_THREAD` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `APP_THREAD_INDEX` INTEGER default 0 NOT NULL, + `APP_THREAD_PARENT` INTEGER default 0 NOT NULL, + `APP_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + PRIMARY KEY (`APP_UID`,`APP_THREAD_INDEX`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='APP_THREAD'; +#----------------------------------------------------------------------------- +#-- APP_DELAY +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_DELAY`; + + +CREATE TABLE `APP_DELAY` +( + `APP_DELAY_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `APP_UID` VARCHAR(32) default '0' NOT NULL, + `APP_THREAD_INDEX` INTEGER default 0 NOT NULL, + `APP_DEL_INDEX` INTEGER default 0 NOT NULL, + `APP_TYPE` VARCHAR(20) default '0' NOT NULL, + `APP_STATUS` VARCHAR(20) default '0' NOT NULL, + `APP_NEXT_TASK` VARCHAR(32) default '0', + `APP_DELEGATION_USER` VARCHAR(32) default '0', + `APP_ENABLE_ACTION_USER` VARCHAR(32) default '0' NOT NULL, + `APP_ENABLE_ACTION_DATE` DATETIME NOT NULL, + `APP_DISABLE_ACTION_USER` VARCHAR(32) default '0', + `APP_DISABLE_ACTION_DATE` DATETIME, + `APP_AUTOMATIC_DISABLED_DATE` DATETIME, + PRIMARY KEY (`APP_DELAY_UID`), + KEY `indexAppDelay`(`PRO_UID`, `APP_UID`, `APP_THREAD_INDEX`, `APP_DEL_INDEX`, `APP_NEXT_TASK`, `APP_DELEGATION_USER`, `APP_DISABLE_ACTION_USER`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='APP_DELAY'; +#----------------------------------------------------------------------------- +#-- PROCESS_USER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `PROCESS_USER`; + + +CREATE TABLE `PROCESS_USER` +( + `PU_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `PU_TYPE` VARCHAR(20) default '' NOT NULL, + PRIMARY KEY (`PU_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- SESSION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `SESSION`; + + +CREATE TABLE `SESSION` +( + `SES_UID` VARCHAR(32) default '' NOT NULL, + `SES_STATUS` VARCHAR(16) default 'ACTIVE' NOT NULL, + `USR_UID` VARCHAR(32) default 'ACTIVE' NOT NULL, + `SES_REMOTE_IP` VARCHAR(32) default '0.0.0.0' NOT NULL, + `SES_INIT_DATE` VARCHAR(19) default '' NOT NULL, + `SES_DUE_DATE` VARCHAR(19) default '' NOT NULL, + `SES_END_DATE` VARCHAR(19) default '' NOT NULL, + PRIMARY KEY (`SES_UID`), + KEY `indexSession`(`SES_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='SESSION'; +#----------------------------------------------------------------------------- +#-- DB_SOURCE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `DB_SOURCE`; + + +CREATE TABLE `DB_SOURCE` +( + `DBS_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `DBS_TYPE` VARCHAR(8) default '0' NOT NULL, + `DBS_SERVER` VARCHAR(100) default '0' NOT NULL, + `DBS_DATABASE_NAME` VARCHAR(100) default '0' NOT NULL, + `DBS_USERNAME` VARCHAR(32) default '0' NOT NULL, + `DBS_PASSWORD` VARCHAR(32) default '', + `DBS_PORT` INTEGER default 0, + `DBS_ENCODE` VARCHAR(32) default '', + PRIMARY KEY (`DBS_UID`), + KEY `indexDBSource`(`PRO_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='DB_SOURCE'; +#----------------------------------------------------------------------------- +#-- STEP_SUPERVISOR +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `STEP_SUPERVISOR`; + + +CREATE TABLE `STEP_SUPERVISOR` +( + `STEP_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `STEP_TYPE_OBJ` VARCHAR(20) default 'DYNAFORM' NOT NULL, + `STEP_UID_OBJ` VARCHAR(32) default '0' NOT NULL, + `STEP_POSITION` INTEGER default 0 NOT NULL, + PRIMARY KEY (`STEP_UID`), + KEY `indexStepSupervisor`(`PRO_UID`, `STEP_TYPE_OBJ`, `STEP_UID_OBJ`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='STEP_SUPERVISOR'; +#----------------------------------------------------------------------------- +#-- OBJECT_PERMISSION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `OBJECT_PERMISSION`; + + +CREATE TABLE `OBJECT_PERMISSION` +( + `OP_UID` VARCHAR(32) default '0' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `TAS_UID` VARCHAR(32) default '0' NOT NULL, + `USR_UID` VARCHAR(32) default '0' NOT NULL, + `OP_USER_RELATION` INTEGER default 0 NOT NULL, + `OP_TASK_SOURCE` VARCHAR(32) default '0', + `OP_PARTICIPATE` INTEGER default 0 NOT NULL, + `OP_OBJ_TYPE` VARCHAR(15) default '0' NOT NULL, + `OP_OBJ_UID` VARCHAR(32) default '0' NOT NULL, + `OP_ACTION` VARCHAR(10) default '0' NOT NULL, + `OP_CASE_STATUS` VARCHAR(10) default '0', + PRIMARY KEY (`OP_UID`), + KEY `indexObjctPermission`(`PRO_UID`, `TAS_UID`, `USR_UID`, `OP_TASK_SOURCE`, `OP_OBJ_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='OBJECT_PERMISSION'; +#----------------------------------------------------------------------------- +#-- CASE_TRACKER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CASE_TRACKER`; + + +CREATE TABLE `CASE_TRACKER` +( + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `CT_MAP_TYPE` VARCHAR(10) default '0' NOT NULL, + `CT_DERIVATION_HISTORY` INTEGER default 0 NOT NULL, + `CT_MESSAGE_HISTORY` INTEGER default 0 NOT NULL, + PRIMARY KEY (`PRO_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='CASE_TRACKER'; +#----------------------------------------------------------------------------- +#-- CASE_TRACKER_OBJECT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CASE_TRACKER_OBJECT`; + + +CREATE TABLE `CASE_TRACKER_OBJECT` +( + `CTO_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '0' NOT NULL, + `CTO_TYPE_OBJ` VARCHAR(20) default 'DYNAFORM' NOT NULL, + `CTO_UID_OBJ` VARCHAR(32) default '0' NOT NULL, + `CTO_CONDITION` TEXT NOT NULL, + `CTO_POSITION` INTEGER default 0 NOT NULL, + PRIMARY KEY (`CTO_UID`), + KEY `indexCaseTrackerObject`(`PRO_UID`, `CTO_UID_OBJ`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- STAGE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `STAGE`; + + +CREATE TABLE `STAGE` +( + `STG_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `STG_POSX` INTEGER default 0 NOT NULL, + `STG_POSY` INTEGER default 0 NOT NULL, + `STG_INDEX` INTEGER default 0 NOT NULL, + PRIMARY KEY (`STG_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- SUB_PROCESS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `SUB_PROCESS`; + + +CREATE TABLE `SUB_PROCESS` +( + `SP_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `PRO_PARENT` VARCHAR(32) default '' NOT NULL, + `TAS_PARENT` VARCHAR(32) default '' NOT NULL, + `SP_TYPE` VARCHAR(20) default '' NOT NULL, + `SP_SYNCHRONOUS` INTEGER default 0 NOT NULL, + `SP_SYNCHRONOUS_TYPE` VARCHAR(20) default '' NOT NULL, + `SP_SYNCHRONOUS_WAIT` INTEGER default 0 NOT NULL, + `SP_VARIABLES_OUT` TEXT NOT NULL, + `SP_VARIABLES_IN` TEXT NOT NULL, + `SP_GRID_IN` VARCHAR(50) default '' NOT NULL, + PRIMARY KEY (`SP_UID`), + KEY `indexSubProcess`(`PRO_UID`, `PRO_PARENT`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- SUB_APPLICATION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `SUB_APPLICATION`; + + +CREATE TABLE `SUB_APPLICATION` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `APP_PARENT` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX_PARENT` INTEGER default 0 NOT NULL, + `DEL_THREAD_PARENT` INTEGER default 0 NOT NULL, + `SA_STATUS` VARCHAR(32) default '' NOT NULL, + `SA_VALUES_OUT` TEXT NOT NULL, + `SA_VALUES_IN` TEXT NOT NULL, + `SA_INIT_DATE` DATETIME, + `SA_FINISH_DATE` DATETIME, + PRIMARY KEY (`APP_UID`,`APP_PARENT`,`DEL_INDEX_PARENT`,`DEL_THREAD_PARENT`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- LOGIN_LOG +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `LOGIN_LOG`; + + +CREATE TABLE `LOGIN_LOG` +( + `LOG_UID` VARCHAR(32) default '' NOT NULL, + `LOG_STATUS` VARCHAR(100) default '' NOT NULL, + `LOG_IP` VARCHAR(15) default '' NOT NULL, + `LOG_SID` VARCHAR(100) default '' NOT NULL, + `LOG_INIT_DATE` DATETIME, + `LOG_END_DATE` DATETIME, + `LOG_CLIENT_HOSTNAME` VARCHAR(100) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`LOG_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- USERS_PROPERTIES +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `USERS_PROPERTIES`; + + +CREATE TABLE `USERS_PROPERTIES` +( + `USR_UID` VARCHAR(32) default '' NOT NULL, + `USR_LAST_UPDATE_DATE` DATETIME, + `USR_LOGGED_NEXT_TIME` INTEGER default 0, + `USR_PASSWORD_HISTORY` TEXT, + PRIMARY KEY (`USR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- ADDITIONAL_TABLES +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `ADDITIONAL_TABLES`; + + +CREATE TABLE `ADDITIONAL_TABLES` +( + `ADD_TAB_UID` VARCHAR(32) default '' NOT NULL, + `ADD_TAB_NAME` VARCHAR(60) default '' NOT NULL, + `ADD_TAB_CLASS_NAME` VARCHAR(100) default '' NOT NULL, + `ADD_TAB_DESCRIPTION` TEXT NOT NULL, + `ADD_TAB_SDW_LOG_INSERT` TINYINT default 1 NOT NULL, + `ADD_TAB_SDW_LOG_UPDATE` TINYINT default 1 NOT NULL, + `ADD_TAB_SDW_LOG_DELETE` TINYINT default 1 NOT NULL, + `ADD_TAB_SDW_LOG_SELECT` TINYINT default 0 NOT NULL, + `ADD_TAB_SDW_MAX_LENGTH` INTEGER default -1 NOT NULL, + `ADD_TAB_SDW_AUTO_DELETE` TINYINT default 0 NOT NULL, + `ADD_TAB_PLG_UID` VARCHAR(32) default '' NOT NULL, + `DBS_UID` VARCHAR(32) default '0', + PRIMARY KEY (`ADD_TAB_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- FIELDS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `FIELDS`; + + +CREATE TABLE `FIELDS` +( + `FLD_UID` VARCHAR(32) default '' NOT NULL, + `ADD_TAB_UID` VARCHAR(32) default '' NOT NULL, + `FLD_INDEX` INTEGER default 1 NOT NULL, + `FLD_NAME` VARCHAR(60) default '' NOT NULL, + `FLD_DESCRIPTION` TEXT NOT NULL, + `FLD_TYPE` VARCHAR(10) default '' NOT NULL, + `FLD_SIZE` INTEGER default 1 NOT NULL, + `FLD_NULL` TINYINT default 1 NOT NULL, + `FLD_AUTO_INCREMENT` TINYINT default 0 NOT NULL, + `FLD_KEY` TINYINT default 0 NOT NULL, + `FLD_FOREIGN_KEY` TINYINT default 0 NOT NULL, + `FLD_FOREIGN_KEY_TABLE` VARCHAR(32) default '' NOT NULL, + PRIMARY KEY (`FLD_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- SHADOW_TABLE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `SHADOW_TABLE`; + + +CREATE TABLE `SHADOW_TABLE` +( + `SHD_UID` VARCHAR(32) default '' NOT NULL, + `ADD_TAB_UID` VARCHAR(32) default '' NOT NULL, + `SHD_ACTION` VARCHAR(10) default '' NOT NULL, + `SHD_DETAILS` TEXT NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `APP_UID` VARCHAR(32) default '' NOT NULL, + `SHD_DATE` DATETIME, + PRIMARY KEY (`SHD_UID`), + KEY `indexShadowTable`(`SHD_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- EVENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `EVENT`; + + +CREATE TABLE `EVENT` +( + `EVN_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `EVN_STATUS` VARCHAR(16) default 'OPEN' NOT NULL, + `EVN_WHEN_OCCURS` VARCHAR(32) default 'SINGLE', + `EVN_RELATED_TO` VARCHAR(16) default 'SINGLE', + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `EVN_TAS_UID_FROM` VARCHAR(32) default '', + `EVN_TAS_UID_TO` VARCHAR(32) default '', + `EVN_TAS_ESTIMATED_DURATION` DOUBLE default 0, + `EVN_WHEN` DOUBLE default 0 NOT NULL, + `EVN_MAX_ATTEMPTS` TINYINT default 3 NOT NULL, + `EVN_ACTION` VARCHAR(50) default '' NOT NULL, + `EVN_CONDITIONS` TEXT, + `EVN_ACTION_PARAMETERS` TEXT, + `TRI_UID` VARCHAR(32) default '', + PRIMARY KEY (`EVN_UID`), + KEY `indexEventTable`(`EVN_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- APP_EVENT +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_EVENT`; + + +CREATE TABLE `APP_EVENT` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `EVN_UID` VARCHAR(32) default '' NOT NULL, + `APP_EVN_ACTION_DATE` DATETIME NOT NULL, + `APP_EVN_ATTEMPTS` TINYINT default 0 NOT NULL, + `APP_EVN_LAST_EXECUTION_DATE` DATETIME, + `APP_EVN_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + PRIMARY KEY (`APP_UID`,`DEL_INDEX`,`EVN_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8'; +#----------------------------------------------------------------------------- +#-- APP_CACHE_VIEW +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_CACHE_VIEW`; + + +CREATE TABLE `APP_CACHE_VIEW` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `APP_NUMBER` INTEGER default 0 NOT NULL, + `APP_STATUS` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `PREVIOUS_USR_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `DEL_DELEGATE_DATE` DATETIME NOT NULL, + `DEL_INIT_DATE` DATETIME, + `DEL_TASK_DUE_DATE` DATETIME, + `DEL_FINISH_DATE` DATETIME, + `DEL_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `APP_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `APP_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_PRO_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_TAS_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_CURRENT_USER` VARCHAR(128) default '' NOT NULL, + `APP_DEL_PREVIOUS_USER` VARCHAR(128) default '' NOT NULL, + `DEL_PRIORITY` VARCHAR(32) default '3' NOT NULL, + `DEL_DURATION` DOUBLE default 0, + `DEL_QUEUE_DURATION` DOUBLE default 0, + `DEL_DELAY_DURATION` DOUBLE default 0, + `DEL_STARTED` TINYINT default 0, + `DEL_FINISHED` TINYINT default 0, + `DEL_DELAYED` TINYINT default 0, + `APP_CREATE_DATE` DATETIME NOT NULL, + `APP_FINISH_DATE` DATETIME, + `APP_UPDATE_DATE` DATETIME NOT NULL, + `APP_OVERDUE_PERCENTAGE` DOUBLE NOT NULL, + PRIMARY KEY (`APP_UID`,`DEL_INDEX`), + KEY `indexAppNumber`(`APP_NUMBER`), + KEY `indexAppUser`(`USR_UID`, `APP_STATUS`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Delegation a task to user'; +#----------------------------------------------------------------------------- +#-- DIM_TIME_DELEGATE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `DIM_TIME_DELEGATE`; + + +CREATE TABLE `DIM_TIME_DELEGATE` +( + `TIME_ID` VARCHAR(10) default '' NOT NULL, + `MONTH_ID` INTEGER default 0 NOT NULL, + `QTR_ID` INTEGER default 0 NOT NULL, + `YEAR_ID` INTEGER default 0 NOT NULL, + `MONTH_NAME` VARCHAR(3) default '0' NOT NULL, + `MONTH_DESC` VARCHAR(9) default '' NOT NULL, + `QTR_NAME` VARCHAR(4) default '' NOT NULL, + `QTR_DESC` VARCHAR(9) default '' NOT NULL, + PRIMARY KEY (`TIME_ID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='The application'; +#----------------------------------------------------------------------------- +#-- DIM_TIME_COMPLETE +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `DIM_TIME_COMPLETE`; + + +CREATE TABLE `DIM_TIME_COMPLETE` +( + `TIME_ID` VARCHAR(10) default '' NOT NULL, + `MONTH_ID` INTEGER default 0 NOT NULL, + `QTR_ID` INTEGER default 0 NOT NULL, + `YEAR_ID` INTEGER default 0 NOT NULL, + `MONTH_NAME` VARCHAR(3) default '0' NOT NULL, + `MONTH_DESC` VARCHAR(9) default '' NOT NULL, + `QTR_NAME` VARCHAR(4) default '' NOT NULL, + `QTR_DESC` VARCHAR(9) default '' NOT NULL, + PRIMARY KEY (`TIME_ID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='The application'; +#----------------------------------------------------------------------------- +#-- APP_HISTORY +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_HISTORY`; + + +CREATE TABLE `APP_HISTORY` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `DYN_UID` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `APP_STATUS` VARCHAR(100) default '' NOT NULL, + `HISTORY_DATE` DATETIME, + `HISTORY_DATA` TEXT NOT NULL, + KEY `indexAppHistory`(`APP_UID`, `TAS_UID`, `USR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='History table for Dynaforms'; +#----------------------------------------------------------------------------- +#-- APP_FOLDER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `APP_FOLDER`; + + +CREATE TABLE `APP_FOLDER` +( + `FOLDER_UID` VARCHAR(32) default '' NOT NULL, + `FOLDER_PARENT_UID` VARCHAR(32) default '' NOT NULL, + `FOLDER_NAME` TEXT NOT NULL, + `FOLDER_CREATE_DATE` DATETIME NOT NULL, + `FOLDER_UPDATE_DATE` DATETIME NOT NULL, + PRIMARY KEY (`FOLDER_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Folder System PM Documents'; +#----------------------------------------------------------------------------- +#-- FIELD_CONDITION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `FIELD_CONDITION`; + + +CREATE TABLE `FIELD_CONDITION` +( + `FCD_UID` VARCHAR(32) default '' NOT NULL, + `FCD_FUNCTION` VARCHAR(50) NOT NULL, + `FCD_FIELDS` TEXT, + `FCD_CONDITION` TEXT, + `FCD_EVENTS` TEXT, + `FCD_EVENT_OWNERS` TEXT, + `FCD_STATUS` VARCHAR(10), + `FCD_DYN_UID` VARCHAR(32) NOT NULL, + PRIMARY KEY (`FCD_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Conditions store to show or hide dynaform fields..'; +#----------------------------------------------------------------------------- +#-- LOG_CASES_SCHEDULER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `LOG_CASES_SCHEDULER`; + + +CREATE TABLE `LOG_CASES_SCHEDULER` +( + `LOG_CASE_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `USR_NAME` VARCHAR(32) default '' NOT NULL, + `EXEC_DATE` DATE NOT NULL, + `EXEC_HOUR` VARCHAR(32) default '12:00' NOT NULL, + `RESULT` VARCHAR(32) default 'SUCCESS' NOT NULL, + `SCH_UID` VARCHAR(32) default 'OPEN' NOT NULL, + `WS_CREATE_CASE_STATUS` TEXT NOT NULL, + `WS_ROUTE_CASE_STATUS` TEXT NOT NULL, + PRIMARY KEY (`LOG_CASE_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Cases Launched with Case Scheduler'; +#----------------------------------------------------------------------------- +#-- CASE_SCHEDULER +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CASE_SCHEDULER`; + + +CREATE TABLE `CASE_SCHEDULER` +( + `SCH_UID` VARCHAR(32) NOT NULL, + `SCH_DEL_USER_NAME` VARCHAR(100) NOT NULL, + `SCH_DEL_USER_PASS` VARCHAR(100) NOT NULL, + `SCH_DEL_USER_UID` VARCHAR(100) NOT NULL, + `SCH_NAME` VARCHAR(100) NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `SCH_TIME_NEXT_RUN` DATETIME NOT NULL, + `SCH_LAST_RUN_TIME` DATETIME, + `SCH_STATE` VARCHAR(15) default 'ACTIVE' NOT NULL, + `SCH_LAST_STATE` VARCHAR(60) NOT NULL, + `USR_UID` VARCHAR(32) NOT NULL, + `SCH_OPTION` TINYINT default 0 NOT NULL, + `SCH_START_TIME` DATETIME NOT NULL, + `SCH_START_DATE` DATETIME NOT NULL, + `SCH_DAYS_PERFORM_TASK` CHAR(5) NOT NULL, + `SCH_EVERY_DAYS` TINYINT default 0, + `SCH_WEEK_DAYS` CHAR(14) default '0|0|0|0|0|0|0' NOT NULL, + `SCH_START_DAY` CHAR(6) NOT NULL, + `SCH_MONTHS` CHAR(24) default '0|0|0|0|0|0|0|0|0|0|0|0' NOT NULL, + `SCH_END_DATE` DATETIME, + `SCH_REPEAT_EVERY` VARCHAR(15) NOT NULL, + `SCH_REPEAT_UNTIL` VARCHAR(15) NOT NULL, + `SCH_REPEAT_STOP_IF_RUNNING` TINYINT default 0, + `CASE_SH_PLUGIN_UID` VARCHAR(100), + PRIMARY KEY (`SCH_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Conditions store to show or hide dynaform fields..'; +#----------------------------------------------------------------------------- +#-- CALENDAR_DEFINITION +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CALENDAR_DEFINITION`; + + +CREATE TABLE `CALENDAR_DEFINITION` +( + `CALENDAR_UID` VARCHAR(32) default '' NOT NULL, + `CALENDAR_NAME` VARCHAR(100) default '' NOT NULL, + `CALENDAR_CREATE_DATE` DATETIME NOT NULL, + `CALENDAR_UPDATE_DATE` DATETIME, + `CALENDAR_WORK_DAYS` VARCHAR(100) default '' NOT NULL, + `CALENDAR_DESCRIPTION` TEXT NOT NULL, + `CALENDAR_STATUS` VARCHAR(8) default 'ACTIVE' NOT NULL, + PRIMARY KEY (`CALENDAR_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Calendar Definition used by PM'; +#----------------------------------------------------------------------------- +#-- CALENDAR_BUSINESS_HOURS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CALENDAR_BUSINESS_HOURS`; + + +CREATE TABLE `CALENDAR_BUSINESS_HOURS` +( + `CALENDAR_UID` VARCHAR(32) default '' NOT NULL, + `CALENDAR_BUSINESS_DAY` VARCHAR(10) default '' NOT NULL, + `CALENDAR_BUSINESS_START` VARCHAR(10) default '' NOT NULL, + `CALENDAR_BUSINESS_END` VARCHAR(10) default '' NOT NULL, + PRIMARY KEY (`CALENDAR_UID`,`CALENDAR_BUSINESS_DAY`,`CALENDAR_BUSINESS_START`,`CALENDAR_BUSINESS_END`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Calendar Business Hours'; +#----------------------------------------------------------------------------- +#-- CALENDAR_HOLIDAYS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CALENDAR_HOLIDAYS`; + + +CREATE TABLE `CALENDAR_HOLIDAYS` +( + `CALENDAR_UID` VARCHAR(32) default '' NOT NULL, + `CALENDAR_HOLIDAY_NAME` VARCHAR(100) default '' NOT NULL, + `CALENDAR_HOLIDAY_START` DATETIME NOT NULL, + `CALENDAR_HOLIDAY_END` DATETIME NOT NULL, + PRIMARY KEY (`CALENDAR_UID`,`CALENDAR_HOLIDAY_NAME`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Calendar Holidays'; +#----------------------------------------------------------------------------- +#-- CALENDAR_ASSIGNMENTS +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `CALENDAR_ASSIGNMENTS`; + + +CREATE TABLE `CALENDAR_ASSIGNMENTS` +( + `OBJECT_UID` VARCHAR(32) default '' NOT NULL, + `CALENDAR_UID` VARCHAR(32) default '' NOT NULL, + `OBJECT_TYPE` VARCHAR(100) default '' NOT NULL, + PRIMARY KEY (`OBJECT_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Calendar Holidays'; +#----------------------------------------------------------------------------- +#-- PROCESS_CATEGORY +#----------------------------------------------------------------------------- + +DROP TABLE IF EXISTS `PROCESS_CATEGORY`; + + +CREATE TABLE `PROCESS_CATEGORY` +( + `CATEGORY_UID` VARCHAR(32) default '' NOT NULL, + `CATEGORY_PARENT` VARCHAR(32) default '0' NOT NULL, + `CATEGORY_NAME` VARCHAR(100) default '' NOT NULL, + `CATEGORY_ICON` VARCHAR(100) default '', + PRIMARY KEY (`CATEGORY_UID`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Calendar Holidays'; +# This restores the fkey checks, after having unset them earlier +SET FOREIGN_KEY_CHECKS = 1; diff --git a/workflow/engine/data/mysql/sqldb.map b/workflow/engine/data/mysql/sqldb.map new file mode 100644 index 000000000..fc15b9e86 --- /dev/null +++ b/workflow/engine/data/mysql/sqldb.map @@ -0,0 +1,2 @@ +# Sqlfile -> Database map +schema.sql=workflow diff --git a/workflow/engine/data/oracle/create-db.sql b/workflow/engine/data/oracle/create-db.sql new file mode 100644 index 000000000..174843acc --- /dev/null +++ b/workflow/engine/data/oracle/create-db.sql @@ -0,0 +1,4 @@ +-- foreach ($databaseName in $databaseNames) +-- drop database $databaseName; +-- create database $databaseName; +-- end diff --git a/workflow/engine/data/oracle/schema.sql b/workflow/engine/data/oracle/schema.sql new file mode 100644 index 000000000..1fb04caaf --- /dev/null +++ b/workflow/engine/data/oracle/schema.sql @@ -0,0 +1,769 @@ + + +/* ----------------------------------------------------------------------- + APPLICATION + ----------------------------------------------------------------------- */ + +DROP TABLE "APPLICATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "APPLICATION" +( + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "APP_NUMBER" NUMBER default 0 NOT NULL, + "APP_PARENT" VARCHAR2(32) default '0' NOT NULL, + "APP_STATUS" VARCHAR2(100) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "APP_PROC_STATUS" VARCHAR2(100) default '' NOT NULL, + "APP_PROC_CODE" VARCHAR2(100) default '' NOT NULL, + "APP_PARALLEL" VARCHAR2(32) default 'NO' NOT NULL, + "APP_INIT_USER" VARCHAR2(32) default '' NOT NULL, + "APP_CUR_USER" VARCHAR2(32) default '' NOT NULL, + "APP_CREATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "APP_INIT_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "APP_FINISH_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "APP_UPDATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "APP_DATA" VARCHAR2(2000) NOT NULL +); + + ALTER TABLE "APPLICATION" + ADD CONSTRAINT "APPLICATION_PK" + PRIMARY KEY ("APP_UID"); +CREATE INDEX "indexApp" ON "APPLICATION" ("PRO_UID","APP_UID"); +CREATE INDEX "indexApp" ON "APPLICATION" ("PRO_UID","APP_UID"); + + +/* ----------------------------------------------------------------------- + APP_DELEGATION + ----------------------------------------------------------------------- */ + +DROP TABLE "APP_DELEGATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "APP_DELEGATION" +( + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "DEL_INDEX" NUMBER default 0 NOT NULL, + "DEL_PREVIOUS" NUMBER default 0 NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_UID" VARCHAR2(32) default '' NOT NULL, + "USR_UID" VARCHAR2(32) default '' NOT NULL, + "DEL_TYPE" VARCHAR2(32) default 'NORMAL' NOT NULL, + "DEL_THREAD" NUMBER default 0 NOT NULL, + "DEL_THREAD_STATUS" VARCHAR2(32) default 'OPEN' NOT NULL, + "DEL_PRIORITY" VARCHAR2(32) default '0' NOT NULL, + "DEL_DELEGATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "DEL_INIT_DATE" DATE NOT NULL, + "DEL_TASK_DUE_DATE" DATE default '' NOT NULL, + "DEL_FINISH_DATE" DATE +); + + ALTER TABLE "APP_DELEGATION" + ADD CONSTRAINT "APP_DELEGATION_PK" + PRIMARY KEY ("APP_UID","DEL_INDEX"); + + +/* ----------------------------------------------------------------------- + APP_DOCUMENT + ----------------------------------------------------------------------- */ + +DROP TABLE "APP_DOCUMENT" CASCADE CONSTRAINTS; + + +CREATE TABLE "APP_DOCUMENT" +( + "APP_DOC_UID" VARCHAR2(32) default '' NOT NULL, + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "DEL_INDEX" NUMBER default 0 NOT NULL, + "DOC_UID" VARCHAR2(32) default '' NOT NULL, + "USR_UID" VARCHAR2(32) default '' NOT NULL, + "APP_DOC_TYPE" VARCHAR2(32) default '' NOT NULL, + "APP_DOC_CREATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL +); + + ALTER TABLE "APP_DOCUMENT" + ADD CONSTRAINT "APP_DOCUMENT_PK" + PRIMARY KEY ("APP_DOC_UID"); + + +/* ----------------------------------------------------------------------- + APP_MESSAGE + ----------------------------------------------------------------------- */ + +DROP TABLE "APP_MESSAGE" CASCADE CONSTRAINTS; + + +CREATE TABLE "APP_MESSAGE" +( + "APP_MSG_UID" VARCHAR2(32) default '' NOT NULL, + "MSG_UID" VARCHAR2(32), + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "DEL_INDEX" NUMBER default 0 NOT NULL, + "APP_MSG_TYPE" VARCHAR2(100) default 'CUSTOM_MESSAGE' NOT NULL, + "APP_MSG_SUBJECT" VARCHAR2(150) default '' NOT NULL, + "APP_MSG_FROM" VARCHAR2(100) default '' NOT NULL, + "APP_MSG_TO" VARCHAR2(2000) NOT NULL, + "APP_MSG_BODY" VARCHAR2(2000) NOT NULL, + "APP_MSG_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "APP_MSG_CC" VARCHAR2(2000), + "APP_MSG_BCC" VARCHAR2(2000), + "APP_MSG_ATTACH" VARCHAR2(2000) +); + + ALTER TABLE "APP_MESSAGE" + ADD CONSTRAINT "APP_MESSAGE_PK" + PRIMARY KEY ("APP_MSG_UID"); + + +/* ----------------------------------------------------------------------- + APP_OWNER + ----------------------------------------------------------------------- */ + +DROP TABLE "APP_OWNER" CASCADE CONSTRAINTS; + + +CREATE TABLE "APP_OWNER" +( + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "OWN_UID" VARCHAR2(32) default '' NOT NULL, + "USR_UID" VARCHAR2(32) default '' NOT NULL +); + + ALTER TABLE "APP_OWNER" + ADD CONSTRAINT "APP_OWNER_PK" + PRIMARY KEY ("APP_UID","OWN_UID","USR_UID"); + + +/* ----------------------------------------------------------------------- + CONFIGURATION + ----------------------------------------------------------------------- */ + +DROP TABLE "CONFIGURATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "CONFIGURATION" +( + "CFG_UID" VARCHAR2(32) default '' NOT NULL, + "OBJ_UID" VARCHAR2(128) default '' NOT NULL, + "CFG_VALUE" VARCHAR2(2000) NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "USR_UID" VARCHAR2(32) default '' NOT NULL, + "APP_UID" VARCHAR2(32) default '' NOT NULL +); + + ALTER TABLE "CONFIGURATION" + ADD CONSTRAINT "CONFIGURATION_PK" + PRIMARY KEY ("CFG_UID","OBJ_UID","PRO_UID","USR_UID","APP_UID"); + + +/* ----------------------------------------------------------------------- + CONTENT + ----------------------------------------------------------------------- */ + +DROP TABLE "CONTENT" CASCADE CONSTRAINTS; + + +CREATE TABLE "CONTENT" +( + "CON_CATEGORY" VARCHAR2(30) default '' NOT NULL, + "CON_PARENT" VARCHAR2(32) default '' NOT NULL, + "CON_ID" VARCHAR2(100) default '' NOT NULL, + "CON_LANG" VARCHAR2(10) default '' NOT NULL, + "CON_VALUE" VARCHAR2(2000) NOT NULL +); + + ALTER TABLE "CONTENT" + ADD CONSTRAINT "CONTENT_PK" + PRIMARY KEY ("CON_CATEGORY","CON_PARENT","CON_ID","CON_LANG"); + + +/* ----------------------------------------------------------------------- + DEPARTMENT + ----------------------------------------------------------------------- */ + +DROP TABLE "DEPARTMENT" CASCADE CONSTRAINTS; + + +CREATE TABLE "DEPARTMENT" +( + "DEP_UID" VARCHAR2(32) default '' NOT NULL, + "DEP_PARENT" VARCHAR2(32) default '' NOT NULL, + "DEP_MANAGER" VARCHAR2(32) default '' NOT NULL, + "DEP_LOCATION" NUMBER default 0 NOT NULL, + "DEP_STATUS" CHAR(1) default 'A' NOT NULL, + "DEP_TYPE" VARCHAR2(5) default 'INTER' NOT NULL, + "DEP_REF_CODE" VARCHAR2(10) default '' NOT NULL +); + + ALTER TABLE "DEPARTMENT" + ADD CONSTRAINT "DEPARTMENT_PK" + PRIMARY KEY ("DEP_UID"); +CREATE INDEX "DEP_BYPARENT" ON "DEPARTMENT" ("DEP_PARENT"); +CREATE INDEX "DEP_BYPARENT" ON "DEPARTMENT" ("DEP_PARENT"); + + +/* ----------------------------------------------------------------------- + DYNAFORM + ----------------------------------------------------------------------- */ + +DROP TABLE "DYNAFORM" CASCADE CONSTRAINTS; + + +CREATE TABLE "DYNAFORM" +( + "DYN_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '0' NOT NULL, + "DYN_TYPE" VARCHAR2(20) default 'xmlform' NOT NULL, + "DYN_FILENAME" VARCHAR2(100) default '' NOT NULL +); + + ALTER TABLE "DYNAFORM" + ADD CONSTRAINT "DYNAFORM_PK" + PRIMARY KEY ("DYN_UID"); + + +/* ----------------------------------------------------------------------- + GROUPWF + ----------------------------------------------------------------------- */ + +DROP TABLE "GROUPWF" CASCADE CONSTRAINTS; + + +CREATE TABLE "GROUPWF" +( + "GRP_UID" VARCHAR2(32) default '' NOT NULL, + "GRP_STATUS" CHAR(8) default 'ACTIVE' NOT NULL +); + + ALTER TABLE "GROUPWF" + ADD CONSTRAINT "GROUPWF_PK" + PRIMARY KEY ("GRP_UID"); + + +/* ----------------------------------------------------------------------- + GROUP_USER + ----------------------------------------------------------------------- */ + +DROP TABLE "GROUP_USER" CASCADE CONSTRAINTS; + + +CREATE TABLE "GROUP_USER" +( + "GRP_UID" VARCHAR2(32) default '0' NOT NULL, + "USR_UID" VARCHAR2(32) default '0' NOT NULL +); + + ALTER TABLE "GROUP_USER" + ADD CONSTRAINT "GROUP_USER_PK" + PRIMARY KEY ("GRP_UID","USR_UID"); + + +/* ----------------------------------------------------------------------- + HOLIDAY + ----------------------------------------------------------------------- */ + +DROP TABLE "HOLIDAY" CASCADE CONSTRAINTS; + +DROP SEQUENCE "HOLIDAY_SEQ"; + + +CREATE TABLE "HOLIDAY" +( + "HLD_UID" NUMBER NOT NULL, + "HLD_DATE" VARCHAR2(10) default '0000-00-00' NOT NULL, + "HLD_DESCRIPTION" VARCHAR2(200) default '' NOT NULL +); + + ALTER TABLE "HOLIDAY" + ADD CONSTRAINT "HOLIDAY_PK" + PRIMARY KEY ("HLD_UID"); +CREATE SEQUENCE "HOLIDAY_SEQ" INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER; + + +/* ----------------------------------------------------------------------- + INPUT_DOCUMENT + ----------------------------------------------------------------------- */ + +DROP TABLE "INPUT_DOCUMENT" CASCADE CONSTRAINTS; + + +CREATE TABLE "INPUT_DOCUMENT" +( + "INP_DOC_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '0' NOT NULL, + "INP_DOC_FORM_NEEDED" VARCHAR2(20) default 'REAL' NOT NULL, + "INP_DOC_ORIGINAL" VARCHAR2(20) default 'COPY' NOT NULL, + "INP_DOC_PUBLISHED" VARCHAR2(20) default 'PRIVATE' NOT NULL +); + + ALTER TABLE "INPUT_DOCUMENT" + ADD CONSTRAINT "INPUT_DOCUMENT_PK" + PRIMARY KEY ("INP_DOC_UID"); + + +/* ----------------------------------------------------------------------- + ISO_COUNTRY + ----------------------------------------------------------------------- */ + +DROP TABLE "ISO_COUNTRY" CASCADE CONSTRAINTS; + + +CREATE TABLE "ISO_COUNTRY" +( + "IC_UID" VARCHAR2(2) default '' NOT NULL, + "IC_NAME" VARCHAR2(255), + "IC_SORT_ORDER" VARCHAR2(255) +); + + ALTER TABLE "ISO_COUNTRY" + ADD CONSTRAINT "ISO_COUNTRY_PK" + PRIMARY KEY ("IC_UID"); + + +/* ----------------------------------------------------------------------- + ISO_LOCATION + ----------------------------------------------------------------------- */ + +DROP TABLE "ISO_LOCATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "ISO_LOCATION" +( + "IC_UID" VARCHAR2(2) default '' NOT NULL, + "IL_UID" VARCHAR2(5) default '' NOT NULL, + "IL_NAME" VARCHAR2(255), + "IL_NORMAL_NAME" VARCHAR2(255), + "IS_UID" VARCHAR2(4) +); + + ALTER TABLE "ISO_LOCATION" + ADD CONSTRAINT "ISO_LOCATION_PK" + PRIMARY KEY ("IC_UID","IL_UID"); + + +/* ----------------------------------------------------------------------- + ISO_SUBDIVISION + ----------------------------------------------------------------------- */ + +DROP TABLE "ISO_SUBDIVISION" CASCADE CONSTRAINTS; + + +CREATE TABLE "ISO_SUBDIVISION" +( + "IC_UID" VARCHAR2(2) default '' NOT NULL, + "IS_UID" VARCHAR2(4) default '' NOT NULL, + "IS_NAME" VARCHAR2(255) default '' NOT NULL +); + + ALTER TABLE "ISO_SUBDIVISION" + ADD CONSTRAINT "ISO_SUBDIVISION_PK" + PRIMARY KEY ("IC_UID","IS_UID"); + + +/* ----------------------------------------------------------------------- + KT_APPLICATION + ----------------------------------------------------------------------- */ + +DROP TABLE "KT_APPLICATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "KT_APPLICATION" +( + "APP_UID" VARCHAR2(32) default '' NOT NULL, + "KT_FOLDER_ID" NUMBER default 0 NOT NULL, + "KT_PARENT_ID" NUMBER default 0 NOT NULL, + "KT_FOLDER_NAME" VARCHAR2(100) default '' NOT NULL, + "KT_FULL_PATH" VARCHAR2(255) default '' NOT NULL, + "KT_CREATE_USER" VARCHAR2(32) default '' NOT NULL, + "KT_CREATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "KT_UPDATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL +); + + ALTER TABLE "KT_APPLICATION" + ADD CONSTRAINT "KT_APPLICATION_PK" + PRIMARY KEY ("APP_UID"); +CREATE INDEX "indexApp" ON "KT_APPLICATION" ("KT_FOLDER_ID"); +CREATE INDEX "indexApp" ON "KT_APPLICATION" ("KT_FOLDER_ID"); + + +/* ----------------------------------------------------------------------- + KT_PROCESS + ----------------------------------------------------------------------- */ + +DROP TABLE "KT_PROCESS" CASCADE CONSTRAINTS; + + +CREATE TABLE "KT_PROCESS" +( + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "KT_FOLDER_ID" NUMBER default 0 NOT NULL, + "KT_PARENT_ID" NUMBER default 0 NOT NULL, + "KT_FOLDER_NAME" VARCHAR2(100) default '' NOT NULL, + "KT_FULL_PATH" VARCHAR2(255) default '' NOT NULL, + "KT_CREATE_USER" VARCHAR2(32) default '' NOT NULL, + "KT_CREATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "KT_UPDATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL +); + + ALTER TABLE "KT_PROCESS" + ADD CONSTRAINT "KT_PROCESS_PK" + PRIMARY KEY ("PRO_UID"); +CREATE INDEX "indexApp" ON "KT_PROCESS" ("KT_FOLDER_ID"); +CREATE INDEX "indexApp" ON "KT_PROCESS" ("KT_FOLDER_ID"); + + +/* ----------------------------------------------------------------------- + LANGUAGE + ----------------------------------------------------------------------- */ + +DROP TABLE "LANGUAGE" CASCADE CONSTRAINTS; + + +CREATE TABLE "LANGUAGE" +( + "LAN_ID" VARCHAR2(4) default '' NOT NULL, + "LAN_NAME" VARCHAR2(30) default '' NOT NULL, + "LAN_NATIVE_NAME" VARCHAR2(30) default '' NOT NULL, + "LAN_DIRECTION" CHAR(1) default 'L' NOT NULL, + "LAN_WEIGHT" NUMBER default 0 NOT NULL, + "LAN_ENABLED" CHAR(1) default '1' NOT NULL, + "LAN_CALENDAR" VARCHAR2(30) default 'GREGORIAN' NOT NULL +); + + +/* ----------------------------------------------------------------------- + LEXICO + ----------------------------------------------------------------------- */ + +DROP TABLE "LEXICO" CASCADE CONSTRAINTS; + + +CREATE TABLE "LEXICO" +( + "LEX_TOPIC" VARCHAR2(64) default '' NOT NULL, + "LEX_KEY" VARCHAR2(128) default '' NOT NULL, + "LEX_VALUE" VARCHAR2(128) default '' NOT NULL, + "LEX_CAPTION" VARCHAR2(128) default '' NOT NULL +); + + ALTER TABLE "LEXICO" + ADD CONSTRAINT "LEXICO_PK" + PRIMARY KEY ("LEX_TOPIC","LEX_KEY"); + + +/* ----------------------------------------------------------------------- + OUTPUT_DOCUMENT + ----------------------------------------------------------------------- */ + +DROP TABLE "OUTPUT_DOCUMENT" CASCADE CONSTRAINTS; + + +CREATE TABLE "OUTPUT_DOCUMENT" +( + "OUT_DOC_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL +); + + ALTER TABLE "OUTPUT_DOCUMENT" + ADD CONSTRAINT "OUTPUT_DOCUMENT_PK" + PRIMARY KEY ("OUT_DOC_UID"); + + +/* ----------------------------------------------------------------------- + PROCESS + ----------------------------------------------------------------------- */ + +DROP TABLE "PROCESS" CASCADE CONSTRAINTS; + + +CREATE TABLE "PROCESS" +( + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_PARENT" VARCHAR2(32) default '0' NOT NULL, + "PRO_TIME" FLOAT default 1 NOT NULL, + "PRO_TIMEUNIT" VARCHAR2(20) default 'DAYS' NOT NULL, + "PRO_STATUS" VARCHAR2(20) default 'ACTIVE' NOT NULL, + "PRO_TYPE_DAY" CHAR(1) default '0' NOT NULL, + "PRO_TYPE" VARCHAR2(20) default 'NORMAL' NOT NULL, + "PRO_ASSIGNMENT" VARCHAR2(20) default 'FALSE' NOT NULL, + "PRO_SHOW_MAP" NUMBER(3,0) default 1 NOT NULL, + "PRO_SHOW_MESSAGE" NUMBER(3,0) default 1 NOT NULL, + "PRO_SHOW_DELEGATE" NUMBER(3,0) default 1 NOT NULL, + "PRO_SHOW_DYNAFORM" NUMBER(3,0) default 0 NOT NULL, + "PRO_CATEGORY" VARCHAR2(48) default '' NOT NULL, + "PRO_SUB_CATEGORY" VARCHAR2(48) default '' NOT NULL, + "PRO_INDUSTRY" NUMBER default 1 NOT NULL, + "PRO_UPDATE_DATE" DATE default '', + "PRO_CREATE_DATE" DATE default '' NOT NULL, + "PRO_CREATE_USER" VARCHAR2(32) default '' NOT NULL, + "PRO_HEIGHT" NUMBER default 5000 NOT NULL, + "PRO_WIDTH" NUMBER default 10000 NOT NULL, + "PRO_TITLE_X" NUMBER default 0 NOT NULL, + "PRO_TITLE_Y" NUMBER default 6 NOT NULL +); + + ALTER TABLE "PROCESS" + ADD CONSTRAINT "PROCESS_PK" + PRIMARY KEY ("PRO_UID"); + + +/* ----------------------------------------------------------------------- + PROCESS_OWNER + ----------------------------------------------------------------------- */ + +DROP TABLE "PROCESS_OWNER" CASCADE CONSTRAINTS; + + +CREATE TABLE "PROCESS_OWNER" +( + "OWN_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL +); + + ALTER TABLE "PROCESS_OWNER" + ADD CONSTRAINT "PROCESS_OWNER_PK" + PRIMARY KEY ("OWN_UID","PRO_UID"); + + +/* ----------------------------------------------------------------------- + ROUTE + ----------------------------------------------------------------------- */ + +DROP TABLE "ROUTE" CASCADE CONSTRAINTS; + + +CREATE TABLE "ROUTE" +( + "ROU_UID" VARCHAR2(32) default '' NOT NULL, + "ROU_PARENT" VARCHAR2(32) default '0' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_UID" VARCHAR2(32) default '' NOT NULL, + "ROU_NEXT_TASK" VARCHAR2(32) default '0' NOT NULL, + "ROU_CASE" NUMBER default 0 NOT NULL, + "ROU_TYPE" VARCHAR2(25) default 'SEQUENTIAL' NOT NULL, + "ROU_CONDITION" VARCHAR2(255) default '' NOT NULL, + "ROU_TO_LAST_USER" VARCHAR2(20) default 'FALSE' NOT NULL, + "ROU_OPTIONAL" VARCHAR2(20) default 'FALSE' NOT NULL, + "ROU_SEND_EMAIL" VARCHAR2(20) default 'TRUE' NOT NULL, + "ROU_SOURCEANCHOR" NUMBER default 1, + "ROU_TARGETANCHOR" NUMBER default 0 +); + + ALTER TABLE "ROUTE" + ADD CONSTRAINT "ROUTE_PK" + PRIMARY KEY ("ROU_UID"); + + +/* ----------------------------------------------------------------------- + STEP + ----------------------------------------------------------------------- */ + +DROP TABLE "STEP" CASCADE CONSTRAINTS; + + +CREATE TABLE "STEP" +( + "STEP_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '0' NOT NULL, + "TAS_UID" VARCHAR2(32) default '0' NOT NULL, + "STEP_TYPE_OBJ" VARCHAR2(20) default 'DYNAFORM' NOT NULL, + "STEP_UID_OBJ" VARCHAR2(32) default '0' NOT NULL, + "STEP_CONDITION" VARCHAR2(2000) NOT NULL, + "STEP_POSITION" NUMBER default 0 NOT NULL +); + + ALTER TABLE "STEP" + ADD CONSTRAINT "STEP_PK" + PRIMARY KEY ("STEP_UID"); + + +/* ----------------------------------------------------------------------- + STEP_TRIGGER + ----------------------------------------------------------------------- */ + +DROP TABLE "STEP_TRIGGER" CASCADE CONSTRAINTS; + + +CREATE TABLE "STEP_TRIGGER" +( + "STEP_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_UID" VARCHAR2(32) default '' NOT NULL, + "TRI_UID" VARCHAR2(32) default '' NOT NULL, + "ST_TYPE" VARCHAR2(20) default '' NOT NULL, + "ST_CONDITION" VARCHAR2(255) default '' NOT NULL, + "ST_POSITION" NUMBER default 0 NOT NULL +); + + ALTER TABLE "STEP_TRIGGER" + ADD CONSTRAINT "STEP_TRIGGER_PK" + PRIMARY KEY ("STEP_UID","TAS_UID","TRI_UID","ST_TYPE"); + + +/* ----------------------------------------------------------------------- + SWIMLANES_ELEMENTS + ----------------------------------------------------------------------- */ + +DROP TABLE "SWIMLANES_ELEMENTS" CASCADE CONSTRAINTS; + + +CREATE TABLE "SWIMLANES_ELEMENTS" +( + "SWI_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "SWI_TYPE" VARCHAR2(20) default 'LINE' NOT NULL, + "SWI_X" NUMBER default 0 NOT NULL, + "SWI_Y" NUMBER default 0 NOT NULL +); + + ALTER TABLE "SWIMLANES_ELEMENTS" + ADD CONSTRAINT "SWIMLANES_ELEMENTS_PK" + PRIMARY KEY ("SWI_UID"); + + +/* ----------------------------------------------------------------------- + TASK + ----------------------------------------------------------------------- */ + +DROP TABLE "TASK" CASCADE CONSTRAINTS; + + +CREATE TABLE "TASK" +( + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_TYPE" VARCHAR2(20) default 'NORMAL' NOT NULL, + "TAS_DURATION" FLOAT default 0 NOT NULL, + "TAS_DELAY_TYPE" VARCHAR2(30) default '' NOT NULL, + "TAS_TEMPORIZER" FLOAT default 0 NOT NULL, + "TAS_TYPE_DAY" CHAR(1) default '1' NOT NULL, + "TAS_TIMEUNIT" VARCHAR2(20) default 'DAYS' NOT NULL, + "TAS_ALERT" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_PRIORITY_VARIABLE" VARCHAR2(100) default '' NOT NULL, + "TAS_ASSIGN_TYPE" VARCHAR2(30) default 'BALANCED' NOT NULL, + "TAS_ASSIGN_VARIABLE" VARCHAR2(100) default '@@SYS_NEXT_USER_TO_BE_ASSIGNED' NOT NULL, + "TAS_ASSIGN_LOCATION" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_ASSIGN_LOCATION_ADHOC" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_TRANSFER_FLY" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_LAST_ASSIGNED" VARCHAR2(32) default '0' NOT NULL, + "TAS_USER" VARCHAR2(32) default '0' NOT NULL, + "TAS_CAN_UPLOAD" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_VIEW_UPLOAD" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_VIEW_ADDITIONAL_DOCUMENTATION" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_CAN_CANCEL" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_OWNER_APP" VARCHAR2(32) default '' NOT NULL, + "STG_UID" VARCHAR2(32) default '' NOT NULL, + "TAS_CAN_PAUSE" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_CAN_SEND_MESSAGE" VARCHAR2(20) default 'TRUE' NOT NULL, + "TAS_CAN_DELETE_DOCS" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_SELF_SERVICE" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_START" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_TO_LAST_USER" VARCHAR2(20) default 'FALSE' NOT NULL, + "TAS_SEND_LAST_EMAIL" VARCHAR2(20) default 'TRUE' NOT NULL, + "TAS_DERIVATION" VARCHAR2(100) default 'NORMAL' NOT NULL, + "TAS_POSX" NUMBER default 0 NOT NULL, + "TAS_POSY" NUMBER default 0 NOT NULL, + "TAS_COLOR" VARCHAR2(32) default '' NOT NULL +); + + ALTER TABLE "TASK" + ADD CONSTRAINT "TASK_PK" + PRIMARY KEY ("TAS_UID"); + + +/* ----------------------------------------------------------------------- + TASK_USER + ----------------------------------------------------------------------- */ + +DROP TABLE "TASK_USER" CASCADE CONSTRAINTS; + + +CREATE TABLE "TASK_USER" +( + "TAS_UID" VARCHAR2(32) default '' NOT NULL, + "USR_UID" VARCHAR2(32) default '' NOT NULL, + "TU_TYPE" NUMBER default 1 NOT NULL, + "TU_RELATION" NUMBER default 0 NOT NULL +); + + ALTER TABLE "TASK_USER" + ADD CONSTRAINT "TASK_USER_PK" + PRIMARY KEY ("TAS_UID","USR_UID","TU_TYPE","TU_RELATION"); + + +/* ----------------------------------------------------------------------- + TRANSLATION + ----------------------------------------------------------------------- */ + +DROP TABLE "TRANSLATION" CASCADE CONSTRAINTS; + + +CREATE TABLE "TRANSLATION" +( + "TRN_CATEGORY" VARCHAR2(100) default '' NOT NULL, + "TRN_ID" VARCHAR2(100) default '' NOT NULL, + "TRN_LANG" VARCHAR2(10) default 'en' NOT NULL, + "TRN_VALUE" VARCHAR2(200) default '' NOT NULL +); + + ALTER TABLE "TRANSLATION" + ADD CONSTRAINT "TRANSLATION_PK" + PRIMARY KEY ("TRN_CATEGORY","TRN_ID","TRN_LANG"); + + +/* ----------------------------------------------------------------------- + TRIGGERS + ----------------------------------------------------------------------- */ + +DROP TABLE "TRIGGERS" CASCADE CONSTRAINTS; + + +CREATE TABLE "TRIGGERS" +( + "TRI_UID" VARCHAR2(32) default '' NOT NULL, + "PRO_UID" VARCHAR2(32) default '' NOT NULL, + "TRI_TYPE" VARCHAR2(20) default 'SCRIPT' NOT NULL, + "TRI_WEBBOT" VARCHAR2(2000) NOT NULL +); + + ALTER TABLE "TRIGGERS" + ADD CONSTRAINT "TRIGGERS_PK" + PRIMARY KEY ("TRI_UID"); + + +/* ----------------------------------------------------------------------- + USERS + ----------------------------------------------------------------------- */ + +DROP TABLE "USERS" CASCADE CONSTRAINTS; + + +CREATE TABLE "USERS" +( + "USR_UID" VARCHAR2(32) default '' NOT NULL, + "USR_USERNAME" VARCHAR2(100) default '' NOT NULL, + "USR_PASSWORD" VARCHAR2(32) default '' NOT NULL, + "USR_FIRSTNAME" VARCHAR2(50) default '' NOT NULL, + "USR_LASTNAME" VARCHAR2(50) default '' NOT NULL, + "USR_EMAIL" VARCHAR2(100) default '' NOT NULL, + "USR_DUE_DATE" DATE default '0000-00-00' NOT NULL, + "USR_CREATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "USR_UPDATE_DATE" DATE default '0000-00-00 00:00:00' NOT NULL, + "USR_STATUS" NUMBER default 1 NOT NULL, + "USR_COUNTRY" VARCHAR2(3) default '' NOT NULL, + "USR_CITY" VARCHAR2(3) default '' NOT NULL, + "USR_LOCATION" VARCHAR2(3) default '' NOT NULL, + "USR_ADDRESS" VARCHAR2(255) default '' NOT NULL, + "USR_PHONE" VARCHAR2(24) default '' NOT NULL, + "USR_FAX" VARCHAR2(24) default '' NOT NULL, + "USR_CELLULAR" VARCHAR2(24) default '' NOT NULL, + "USR_ZIP_CODE" VARCHAR2(16) default '' NOT NULL, + "USR_DEPARTMENT" NUMBER default 0 NOT NULL, + "USR_POSITION" VARCHAR2(100) default '' NOT NULL, + "USR_RESUME" VARCHAR2(100) default '' NOT NULL, + "USR_BIRTHDAY" DATE default '0000-00-00' NOT NULL, + "USR_ROLE" VARCHAR2(32) default 'PROCESSMAKER_ADMIN' +); + + ALTER TABLE "USERS" + ADD CONSTRAINT "USERS_PK" + PRIMARY KEY ("USR_UID"); diff --git a/workflow/engine/data/oracle/sqldb.map b/workflow/engine/data/oracle/sqldb.map new file mode 100644 index 000000000..fc15b9e86 --- /dev/null +++ b/workflow/engine/data/oracle/sqldb.map @@ -0,0 +1,2 @@ +# Sqlfile -> Database map +schema.sql=workflow diff --git a/workflow/engine/data/pgsql/create-db.sql b/workflow/engine/data/pgsql/create-db.sql new file mode 100644 index 000000000..caed8867d --- /dev/null +++ b/workflow/engine/data/pgsql/create-db.sql @@ -0,0 +1,2 @@ +drop database workflow; +create database workflow; diff --git a/workflow/engine/data/pgsql/sqldb.map b/workflow/engine/data/pgsql/sqldb.map new file mode 100644 index 000000000..fc15b9e86 --- /dev/null +++ b/workflow/engine/data/pgsql/sqldb.map @@ -0,0 +1,2 @@ +# Sqlfile -> Database map +schema.sql=workflow diff --git a/workflow/engine/gulliver-win.bat b/workflow/engine/gulliver-win.bat new file mode 100644 index 000000000..a104036e6 --- /dev/null +++ b/workflow/engine/gulliver-win.bat @@ -0,0 +1,9 @@ +@ECHO OFF +for %%F in (%0) do set dirname=%%~dpF +SET PHP_PATH="%dirname%..\..\..\php" +SET PHP_BIN="%dirname%..\..\..\php\php.exe" +SET GULLIVER_PATH="%dirname%..\..\gulliver" +SET GULLIVER_BIN="%dirname%..\..\gulliver\bin\gulliver" +SET PATH=%PATH%;%PHP_PATH%;%GULLIVER_PATH% +%PHP_BIN% %GULLIVER_BIN% %1 %2 %3 %4 %5 %6 %7 %8 %9 +pause diff --git a/workflow/engine/includes/inc.JSForms.php b/workflow/engine/includes/inc.JSForms.php new file mode 100644 index 000000000..1d173adea --- /dev/null +++ b/workflow/engine/includes/inc.JSForms.php @@ -0,0 +1,122 @@ +<? +/** + * inc.JSForms.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $HTTP_SESSION_VARS; +global $G_FORM; +$path = ''; +$showFieldAjax = 'showFieldAjax.php'; + +$serverAjax = G::encryptLink($path.$showFieldAjax); + +?> +<script language="JavaScript"> +function RefreshDependentFields(ObjectName, Fields, InitValue) { + +<? + //global $G_FORM; + $HTTP_SESSION_VARS['INIT_VALUES'] = $G_FORM->Values; + global $HTTP_GET_VARS; + if ($HTTP_SESSION_VARS['CURRENT_APPLICATION'] == '') $HTTP_SESSION_VARS['CURRENT_APPLICATION'] = '0'; + $appid = $HTTP_SESSION_VARS['CURRENT_APPLICATION']; + if ($HTTP_GET_VARS['dynaform'] != '') + $Dynaform = '&__dynaform__=' . $HTTP_GET_VARS['dynaform']; + if ($HTTP_GET_VARS['filename'] != '') + $Dynaform = '&__filename__=' . $HTTP_GET_VARS['filename']; + +?> + + if (getField) + TheObject = getField(ObjectName); + + if (TheObject) { + Fields = Fields.split(','); + for (i=0; i<Fields.length; i++) { + DivObj = document.getElementById('FLD_' + Fields[i]); + FldObj = document.getElementById('form[' + Fields[i] + ']'); + + if(FldObj){ + if(FldObj.type == 'text'){ + refillText( Fields[i],'<?=$serverAjax?>', 'function=text&field=' + Fields[i] + '&parent=' + ObjectName + '&value=' + TheObject.value + '<?=$Dynaform?>'+ '&application=' + '<?=$appid?>'+ '&Dynaform=' + '<?=$Dynaform?>' ); + } + if(FldObj.type == 'hidden'){ + refillText( Fields[i],'<?=$serverAjax?>', 'function=text&field=' + Fields[i] + '&parent=' + ObjectName + '&value=' + TheObject.value + '<?=$Dynaform?>'+ '&application=' + '<?=$appid?>'+ '&Dynaform=' + '<?=$Dynaform?>' ); + } + + if(FldObj.type == 'select-one') { + refillDropdown( Fields[i],'<?=$serverAjax?>', 'function=dropdown&field=' + Fields[i] + '&parent=' + ObjectName + '&value=' + TheObject.value + '<?=$Dynaform?>'+ '&application=' + '<?=$appid?>'+ '&Dynaform=' + '<?=$Dynaform?>'+ '&InitValue=' + InitValue , InitValue); + } + }else{ + if(DivObj) + refillCaption( Fields[i],'<?=$serverAjax?>', 'function=text&field=' + Fields[i] + '&parent=' + ObjectName + '&value=' + TheObject.value + '<?=$Dynaform?>'+ '&application=' + '<?=$appid?>'+ '&Dynaform=' + '<?=$Dynaform?>' ); + } + } + } +<? + // } +?> +} + +function registerDate ( field, options ) { + var opts = options.split(','); + var fieldName = 'form['+field+']'; + var divName = 'DIV['+field+']'; + Obj = getField( divName); + value = Obj.value; + myDatePicker = new Bs_DatePicker(); +<? +global $G_DATE_FORMAT; +global $HTTP_SESSION_VARS; + +$classfile = PATH_CORE . 'classes/class.user.php'; +if(file_exists($classfile)) +{ + G::LoadClass('user'); + $DateFormat = User::Get_User_Date_Format($HTTP_SESSION_VARS['USER_LOGGED']); +} + +if ($DateFormat == '') + if (defined('DATE_FORMAT')) + $TheDateFormat = DATE_FORMAT; + else + $TheDateFormat = $G_DATE_FORMAT; +else + switch ($DateFormat) { + case 'en': + $TheDateFormat = 'us'; + break; + case 'es': + $TheDateFormat = 'es'; + break; + } +?> + myDatePicker.displayDateFormat = '<?=$TheDateFormat?>'; + myDatePicker.fieldName = fieldName; + myDatePicker.loadSkin('win2k'); + myDatePicker.daysNumChars = 2; + myDatePicker.setDateByIso( value); + myDatePicker.drawInto(divName); +} +</script> +<script language="JavaScript" src="/skins/JSForms.js"></script> \ No newline at end of file diff --git a/workflow/engine/includes/inc.application.php b/workflow/engine/includes/inc.application.php new file mode 100644 index 000000000..fec753d80 --- /dev/null +++ b/workflow/engine/includes/inc.application.php @@ -0,0 +1,118 @@ +<?php +/** + * inc.application.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +class App +{ + function ForceLogin() + { + global $HTTP_SESSION_VARS; + global $G_MAIN_MENU; + global $G_SUB_MENU; + if( $HTTP_SESSION_VARS['LOGGED_IN'] == false) + { + header( "location: /sys/" . SYS_LANG . "/" . SYS_SKIN . "/login/login.html" ); + die(); + } + else + { + $cmptype = $HTTP_SESSION_VARS['USER_TYPE']; + switch( $cmptype ) + { + case 'BUYER': + $G_MAIN_MENU = "buyer"; + $G_SUB_MENU = ""; + break; + case 'PROVIDER': + $G_MAIN_MENU = "provider"; + $G_SUB_MENU = ""; + break; + case 'REINSURANCE': + $G_MAIN_MENU = "reinsurance"; + $G_SUB_MENU = ""; + break; + case 'ADMIN': + $G_MAIN_MENU = "admin"; + $G_SUB_MENU = ""; + break; + case '': + header( "location: /sys/" . SYS_LANG . "/" . SYS_SKIN . "/login/login.html" ); + die(); + break; + default: + $G_MAIN_MENU = "default"; + $G_SUB_MENU = ""; + break; + } + } + } + + function GetPartnerStatus() + { + global $HTTP_SESSION_VARS; + $slipid = $HTTP_SESSION_VARS['CURRENT_SLIP']; + $partnerid = $HTTP_SESSION_VARS['CURRENT_PARTNER']; + + $mdbc = new DBConnection(); + G::LoadClass( "slip" ); + $slip = new Slip; + $slip->SetTo( $mdbc ); + $slip->Load( $slipid ); + $partner = $slip->GetPartner( $partnerid ); + + $res = $partner->Fields['SLP_PARTNER_STATUS']; + unset( $partner ); + unset( $slip ); + unset( $mdbc ); + return $res; + } + + function SetPartnerStatus( $intStatus = 0 ) + { + global $HTTP_SESSION_VARS; + $slipid = $HTTP_SESSION_VARS['CURRENT_SLIP']; + $partnerid = $HTTP_SESSION_VARS['CURRENT_PARTNER']; + + $mdbc = new DBConnection(); + G::LoadClass( "slip" ); + $slip = new Slip; + $slip->SetTo( $mdbc ); + $slip->Load( $slipid ); + $partner = $slip->GetPartner( $partnerid ); + + $partner->Fields = NULL; + $partner->Fields['UID_SLIP'] = $slipid; + $partner->Fields['UID_REINSURANCE'] = $partnerid; + $partner->Fields['SLP_PARTNER_STATUS'] = $intStatus; + $partner->Fields['SLP_PARTNER_UPDATED'] = G::CurDate(); + $partner->Save(); + + unset( $partner ); + unset( $slip ); + unset( $mdbc ); + } + +} + +?> \ No newline at end of file diff --git a/workflow/engine/includes/inc.dynaForms.php b/workflow/engine/includes/inc.dynaForms.php new file mode 100644 index 000000000..1c5854e09 --- /dev/null +++ b/workflow/engine/includes/inc.dynaForms.php @@ -0,0 +1,224 @@ +<? +/** + * inc.dynaForms.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +class Node { + var $name = ""; + var $attribute = NULL; + var $value = NULL; + var $children = NULL; +} + +$header = ""; +$tree = NULL; + +function read_config_file(){ + global $home; + $directory = PATH_DYNAFORM; + $car = substr ($directory, strlen ($directory)-1, 1); + if ($car=='/' ) $directory = substr( $directory, 0, strlen($directory)- 1 ); + $home = $directory; + + global $showlang; + $showlang = "es,en"; +} + +function parseNodo1 ( $token ) { + //parse de <name atr=1 attr=2 ... > en un nuevo nodo. + $nodo = new Node; + $nodo->children = NULL; + $tok = ""; $n = 0; + for ($i=0; $i<strlen ($token); $i++) { + $car = $token[$i]; + if ($car == ' ' || $car == "=") { + if (strlen($tok) > 0 ) { $tokens [$n++] = $tok; $tok = ""; } + if ($car == '=' ) { $tokens [$n++] = $car; } + } + else{ + $tok .= $car; + } + } + if (strlen($tok) > 0 ) { $tokens [$n++] = $tok; $tok = ""; } + + //asignar los valores para el nombre del nodo y sus attributos + $nodo->name = trim($tokens[0]); + for ($i=1; $i< $n; $i++ ) { + $aux = $tokens[$i+2]; + if ($aux[0] == $aux[strlen($aux)-1] || $aux[0] == '"') $aux = substr ($aux,1,strlen($aux)-2); + $key = $tokens[$i]; $val = "true"; + if ($tokens[$i+1]== "=") {$val = $aux; $i+=2;} +// $nodo->attribute = array_merge ( $nodo->attribute, array ( $key => $val ) ); + $nodo->attribute[$key] = $val; + } + return $nodo; +} + +function getTag () { + global $buffer; + global $bufIndex; + global $size; + global $header; + global $tree; + $token = ""; + + //PRIMER BUCLE buscar tag > + while ($bufIndex <= $size && $car !='>') { + $token .= $car; + $car = $buffer [$bufIndex++]; + } + if ($token[0] == "?") { + $header = $token; + return; + } + $nodo = parseNodo1 ($token); + + //SEGUNDO BUCLE buscar VALUE + $car = $buffer [$bufIndex++]; $token = ""; + while ($bufIndex <= $size && $car !='<') { + $token .= $car; + $car = $buffer [$bufIndex++]; + } + $nodo->value = trim($token); + + + //TERCER BUCLE buscar </tag> + $res = 0; + while ($res == 0) { + if ($car != "<") while ( ($car = trim( $buffer [$bufIndex++] )) == ""); + if ($car=="<") { + $res = 0; + $car = $buffer [$bufIndex++]; + //ADDCHILD nodo recien creado + if ($car != "/") { + $bufIndex --; + $n = count($nodo->children); + $nodo->children[$n] = getTag (); + } else $res = 1; + } + else die ("se esperaba '<' y se encontro $car"); + } + + //se supone que se ha leido "</" y continuamos con el nombre + $token = ""; + $car = $buffer [$bufIndex++]; + while ($bufIndex <= $size && $car !='>') { + $token .= $car; + $car = $buffer [$bufIndex++]; + } + if ( strcmp ($nodo->name, trim($token)) != 0) die ("no corresponde fin de tag </$token> con <" . $nodo->name. ">"); + + return $nodo; +} + +function parseFile ($filename) { + global $tree; + global $buffer; + global $bufIndex; + global $size; + + if (strlen($filename) <= 0) die ("invalid filename"); + + if ( ! file_exists ( $filename) ) die ("This file $filename does not exist"); + if ( ! is_file ( $filename) ) die ("$filename is not a file"); + + $size = filesize ($filename); + $fp = fopen ($filename, "rb"); + $i = 0; + + $aux = fread($fp, $size); + $buffer = ""; + for ($i = 0; $i < $size; $i++) { + if (!($aux[$i] == "\n" || $aux[$i] == "\r" || $aux[$i] == "\t")) $buffer .= $aux[$i]; + } + fclose ($fp); + $bufIndex = 0; + + $size = strlen ($buffer); + + while ( $bufIndex <= $size ) { + $car = $buffer [$bufIndex++]; + if ($car == '<' ) + $tree = getTag(); + } +} + + + +function saveXml(){ + global $tree; + global $header; + global $filename; + global $HTTP_POST_VARS; + global $curDir; + global $onlyName; + + //crear el archivo Xml +// print "$filename <br>"; + + $fp = fopen ($filename, "w+"); + fputs ($fp,"<$header>\n"); + + $aux = explode ( '/', $filename); + $onlyName = $aux[count($aux)-1]; + $curDir = $HTTP_POST_VARS['curDir']; + + fputs ($fp,"<dynaForm name=\"$onlyName\" basedir=\"$curDir\">$tree->value\n"); + + for ($i = 0; $i < count($tree->children); $i++) { + $nodo = $tree->children[$i]; + + fputs ($fp,"<$nodo->name "); + if ( is_array ($nodo->attribute) ) + foreach ( $nodo->attribute as $attr=>$attrValue ) + fputs ($fp,"$attr=\"$attrValue\" "); + fputs ($fp,">\n"); + + //si es un dropdown-SQL la sentencia select va como valor del nodo + if (strlen ($nodo->value) > 0) { + fputs ($fp,"$nodo->value\n"); + } + + for ($j = 0; $j < count($nodo->children); $j++) { + $lang = $nodo->children[$j]; + fputs ($fp, " <$lang->name>$lang->value"); + + //si tiene etiquetas del tipo option + if (is_array($lang->children)) { + fputs ($fp, "\n"); + for ($k = 0; $k < count($lang->children); $k++) { + $option = $lang->children[$k]; + fputs ($fp, "<option name=\"" . $option->attribute['name'] . "\">$option->value</option>\n"); + } + } //if tiene etiquetas del tipo opcion. + fputs ($fp, "</$lang->name>\n"); + + } //for j + fputs ($fp,"</$nodo->name>\n"); + + } //for i + fputs ($fp,"</dynaForm>\n"); + fclose ($fp); +} + +?> diff --git a/workflow/engine/js/appFolder/core/appFolderList.js b/workflow/engine/js/appFolder/core/appFolderList.js new file mode 100755 index 000000000..9a5182485 --- /dev/null +++ b/workflow/engine/js/appFolder/core/appFolderList.js @@ -0,0 +1,297 @@ +function openPMFolder( uid, rootfolder ){ + + currentFolder = uid; + if((document.getElementById('child_'+uid).innerHTML!="")&&(uid!=rootfolder)){ + document.getElementById('child_'+uid).innerHTML=""; + getPMFolderContent(uid); + return; + } + document.getElementById('child_'+uid).innerHTML = "<img src='/js/maborak/core/images/loader_B.gif' >";//<div style="background: transparent url(http://hugo.opensource.colosa.net/js/maborak/core/images/loader_B.gif) no-repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; width: 32px; height: 32px; position: absolute; display: none; top: 514.5px; left: 609.5px;" class="panel_loader___processmaker"></div><div style="" class="panel_statusBar___processmaker"><div style="position: relative; text-align: center; display: none;" class="panel_statusButtons___processmaker"></div>'; + + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : true, + method: 'POST', + args : 'action=openPMFolder&folderID=' + uid+'&rootfolder='+rootfolder + }); + oRPC.callback = function(rpc) { + document.getElementById('child_'+uid).innerHTML = rpc.xmlhttp.responseText; + var scs = rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + getPMFolderContent(uid); + }.extend(this); + oRPC.make(); + + if(uid==rootfolder){//Only refresh tags cloud if we are loading the root folder + getPMFolderTags(rootfolder); + } +} + +function getPMFolderContent(uid){ + document.getElementById('spanFolderContent').innerHTML = "<img src='/js/maborak/core/images/loader_B.gif' >";//"Loading.."; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : true, + method: 'POST', + args : 'action=getPMFolderContent&folderID=' + uid + }); + oRPC.callback = function(rpc) { + document.getElementById('spanFolderContent').innerHTML = oRPC.xmlhttp.responseText; + var scs = oRPC.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + + }.extend(this); + oRPC.make(); + + + +} + +function getPMFolderSearchResult(searchKeyword,type){ + document.getElementById('spanFolderContent').innerHTML = "<img src='/js/maborak/core/images/loader_B.gif' >";//"Loading.."; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : true, + method: 'POST', + args : 'action=getPMFolderContent&searchKeyword=' + searchKeyword + '&type=' + type + }); + oRPC.callback = function(rpc) { + document.getElementById('spanFolderContent').innerHTML = oRPC.xmlhttp.responseText; + var scs = oRPC.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + + }.extend(this); + oRPC.make(); + + + + } + +function getPMFolderTags(rootfolder){ + document.getElementById('tags_cloud').innerHTML = "<img src='/js/maborak/core/images/loader_B.gif' >";//"Loading.."; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : false, + method: 'POST', + args : 'action=getPMFolderTags&rootFolder=' + rootfolder + }); + oRPC.make(); + document.getElementById('tags_cloud').innerHTML = oRPC.xmlhttp.responseText; + var scs = oRPC.xmlhttp.responseText.extractScript(); + scs.evalScript(); + +} + +var uploadDocument = function(docID,appDocId,docVersion,actionType,appId,docType){ + if(actionType){ + if(actionType=="R"){ + windowTitle=G_STRINGS.ID_UPLOAD_REPLACE_INPUT; + } + if(actionType=="NV"){ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT_VERSION; + } + }else{ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT; + docVersion=1; + actionType=""; + appDocId=""; + } + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:300}, + position:{x:0,y:0,center:true}, + title :windowTitle, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + args: "action=uploadDocument&docID="+docID+"&appDocId="+appDocId+"&docVersion="+docVersion+"&actionType="+actionType+"&appId="+appId+"&docType="+docType + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var oPanel; +var gUSER_UID; +var uploadExternalDocument = function(folderID){ + gUSER_UID = folderID; + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:300}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_UPLOAD_EXTERNAL_DOCUMENT, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + args: "action=uploadExternalDocument&folderID="+folderID + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var oPanel; +var gUSER_UID; +var newFolder = function(folderID){ + gUSER_UID = folderID; + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:250}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_NEW_FOLDER, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + args: "action=newFolder&folderID="+folderID + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var documentVersionHistory = function(folderID,appDocId){ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:300}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_INPUT_DOCUMENT_HISTORY, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + args: "action=documentVersionHistory&folderID="+folderID+"&appDocId="+appDocId + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var documentInfo = function(docID,appDocId,docVersion,actionType,appId,docType,usrUid){ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:400,h:270}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_DOCUMENT_INFO, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + args: "action=documentInfo&docID="+docID+"&appDocId="+appDocId+"&docVersion="+docVersion+"&actionType="+actionType+"&appId="+appId+"&docType="+docType+"&usrUid="+usrUid + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var documentdelete = function(docID,appDocId,docVersion,actionType,appId,docType,usrUid){ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_DELETE_FILE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : true, + method:'POST', + args: 'action=documentdelete&sFileUID='+appDocId+'&docVersion='+docVersion + + }); + oRPC.callback = function(oRPC) { + window.location = 'appFolderList'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); + + + //ajax_function('appFolderAjax','documentdelete','sFileUID='+encodeURIComponent(appDocId),'POST'); + //window.location = 'appFolderList'; + +}; + + +function deletePMFolder( uid, rootfolder ){ + + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_DELETE_FILE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'appFolderAjax', + async : true, + method:'POST', + args: 'action=deletePMFolder&sFileUID='+uid+'&rootfolder='+rootfolder + + }); + oRPC.callback = function(oRPC) { + window.location = 'appFolderList'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); + +} \ No newline at end of file diff --git a/workflow/engine/js/cases/core/cases.js b/workflow/engine/js/cases/core/cases.js new file mode 100644 index 000000000..2bd8313aa --- /dev/null +++ b/workflow/engine/js/cases/core/cases.js @@ -0,0 +1,72 @@ +var cases=function() +{ + this.parent = leimnud; + this.panels = {}; + this.make=function(options) + { + this.options.target = this.parent.dom.element(this.options.target); + var panel; + /* Panel list Begin */ + this.panels.list = panel = new leimnud.module.panel(); + panel.options={ + size :{w:310,h:250}, + position:{x:50,y:50}, + title :"List", + theme :"processmaker", + target :this.options.target, + statusBar:true, + limit :true, + control :{resize:false,close:true,roll:false}, + fx :{opacity:true,rollWidth:150,fadeIn:false} + }; + + /* Panel list End */ + /* Panel step Begin */ + this.panels.step = panel = new this.parent.module.panel(); + this.panels.step.options={ + size:{w:260,h:550}, + title :this.options.title, + //headerBar:true, + //titleBar:false, + //elementToDrag:"headerBar", + target:this.options.target, + cursorToDrag:"move", + position:{x:5,y:5}, + limit:true, + fx:{shadow:false,modal:false,opacity:false} + }; + this.panels.step.setStyle={ + statusBar:{ + } + }; + this.panels.step.styles.fx.opacityModal.Static=0; + this.panels.step.make(); + this.panels.step.events = { + remove:[function() { delete(this.panels.step); }.extend(this)] + }; + panel.events.remove.push(function() + { + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"showWindow=false" + }); + r.make(); + }.extend(this)); + /* Load data BEGIN */ + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action="+this.options.action+"&showWindow="+this.options.action + }); + r.callback=function(rpc){ + this.panels.step.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + this.panels.step.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + r.make(); + /* Load data END */ + //this.panels.list.make(); + } + this.expand(this); +}; \ No newline at end of file diff --git a/workflow/engine/js/cases/core/cases_Step.js b/workflow/engine/js/cases/core/cases_Step.js new file mode 100644 index 000000000..17c871f2e --- /dev/null +++ b/workflow/engine/js/cases/core/cases_Step.js @@ -0,0 +1,1031 @@ +var oLeyendsPanel; + +var showInformation = function() +{ + if (!Cse.panels.step) + { + Cse=new cases(); + Cse.options = { + target : "cases_target", + dataServer : "cases_Ajax", + action : "information", + title : G_STRINGS.ID_INFORMATION, + lang : "en", + theme : "processmaker", + images_dir :leimnud.path_root + "cases/core/images/" + } + Cse.make(); + } + else + { + Cse.panels.step.events.remove[1]=function() + { + var r = new leimnud.module.rpc.xmlhttp({ + url:"cases_Ajax", + args:"showWindow=false" + }); + r.make(); + }; + Cse.panels.step.elements.title.innerHTML = G_STRINGS.ID_INFORMATION; + Cse.panels.step.clearContent(); + Cse.panels.step.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: "cases_Ajax", + args: "action=information&showWindow=information" + }); + oRPC.callback = function(rpc){ + Cse.panels.step.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + Cse.panels.step.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } +}; +var showActions = function() +{ + if (!Cse.panels.step) + { + Cse=new cases(); + Cse.options = { + target : "cases_target", + dataServer : "cases_Ajax", + action : "actions", + title : G_STRINGS.ID_ACTIONS, + lang : "en", + theme : "processmaker", + images_dir :leimnud.path_root + "cases/core/images/" + } + Cse.make(); + } + else + { + Cse.panels.step.events.remove[1]=function() + { + var r = new leimnud.module.rpc.xmlhttp({ + url :"casesAjax", + args :"showWindow=false" + }); + r.make(); + }; + Cse.panels.step.elements.title.innerHTML = G_STRINGS.ID_ACTIONS; + Cse.panels.step.clearContent(); + Cse.panels.step.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: "cases_Ajax", + args: "action=actions&showWindow=actions" + }); + oRPC.callback = function(rpc){ + Cse.panels.step.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + Cse.panels.step.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } +}; +/*var showKT = function() +{ + if (!Cse.panels.step) + { + Cse=new cases(); + Cse.options = { + target : "cases_target", + dataServer : "cases_Ajax", + action : "KT", + title : "Knowledge Tree", + lang : "en", + theme : "processmaker", + images_dir :leimnud.path_rofile:///rodimus.erik/processmaker/trunk/workflow/engine/js/cases/core/cases_Step.jsot + "cases/core/images/" + } + Cse.make(); + } + else + { + Cse.panels.step.elements.title.innerHTML = "Knowledge Tree"; + Cse.panels.step.clearContent(); + Cse.panels.step.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: "cases_Ajax", + args: "action=KT" + }); + oRPC.callback = function(rpc){ + Cse.panels.step.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + Cse.panels.step.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } +};*/ +var showProcessMap = function () +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:(document.body.clientWidth * 95) / 100,h:(document.body.clientHeight * 95) / 100}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_PROCESS_MAP, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:false}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:false} + }; + oPanel.events = { + remove: function() {oLeyendsPanel.remove();delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "cases_Ajax", + args: "action=showProcessMap" + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + oLeyendsPanel = new leimnud.module.panel(); + oLeyendsPanel.options = { + size :{w:160,h:140}, + position:{x:((document.body.clientWidth * 95) / 100) - ((document.body.clientWidth * 95) / 100 - (((document.body.clientWidth * 95) / 100) - 160)),y:45,center:false}, + title :G_STRINGS.ID_COLOR_LEYENDS, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true,close:false}, + fx :{modal:false,opacity:false,blinkToFront:true,fadeIn:false,drag:false} + }; + oLeyendsPanel.setStyle = { + content:{overflow:'hidden'} + }; + oLeyendsPanel.events = { + remove: function() {delete(oLeyendsPanel);}.extend(this) + }; + oLeyendsPanel.make(); + oLeyendsPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "cases_Ajax", + args: "action=showLeyends" + }); + oRPC.callback = function(rpc){ + oLeyendsPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oLeyendsPanel.addContent(rpc.xmlhttp.responseText); + }.extend(this); + oRPC.make(); + }.extend(this); + oRPC.make(); +}; +var showProcessInformation = function() +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:450,h:260}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_PROCESS_INFORMATION, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "cases_Ajax", + args: "action=showProcessInformation" + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; +var showTransferHistory = function() +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:900,h:520}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_CASE_HISTORY, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "cases_Ajax", + args: "action=showTransferHistory" + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +function dynaformHistory(PRO_UID,APP_UID,TAS_UID, DYN_UID) +{ + if(!DYN_UID) DYN_UID=""; + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:900,h:520}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showDynaformListHistory&PRO_UID='+PRO_UID+'&APP_UID='+APP_UID+'&TAS_UID='+TAS_UID+'&DYN_UID='+DYN_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +} +function toggleTable(tablename){ + table=getElementByName(tablename); + if(table.style.display == ''){ + table.style.display = 'none'; + }else{ + table.style.display = ''; + } +} + +var showTaskInformation = function() +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:450,h:322}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_TASK_INFORMATION, + theme :"processmaker", + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "cases_Ajax", + args: "action=showTaskInformation" + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; +var cancelCase = function() +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_CANCEL_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=cancelCase' + }); + oRPC.callback = function(oRPC) { + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; +var reactivateCase = function() +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_REACTIVATE_CASES, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=reactivateCase' + }); + oRPC.callback = function(oRPC) { + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var pausecasePanel; + +var pauseCase = function() { + var oPauseDiv = document.getElementById('pausediv'); + document.getElementById('spause').style.display = 'none'; + document.getElementById('scpause').style.display = 'block'; + + oPauseDiv.style.display = 'block'; + + /*pausecasePanel = new leimnud.module.panel(); + + pausecasePanel.options = { + size :{w:400,h:150}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:false, + control :{drag: false, resize:false,roll:false,close:true}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + pausecasePanel.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + pausecasePanel.make(); + pausecasePanel.loader.show(); + */ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showPauseCaseInput' + }); + oRPC.callback = function(rpc){ + /*erikpausecasePanel.loader.hide();*/ + //var scs=rpc.xmlhttp.responseText.extractScript(); + /*pausecasePanel.addContent(rpc.xmlhttp.responseText);*/ + + //scs.evalScript(); + + oPauseDiv.innerHTML = rpc.xmlhttp.responseText; + }.extend(this); + oRPC.make(); +}; + +function cancelPauseCase(){ + document.getElementById('spause').style.display = 'block'; + document.getElementById('scpause').style.display = 'none'; + document.getElementById('pausediv').style.display = 'none'; +} + +function toPause() +{ + unpausedate = document.getElementById('form[unpause_date]').value; + + if(unpausedate.trim() == ''){ + msgBox(G_STRINGS.ID_CONFIRM_PAUSE_CASE_ALERT, 'alert'); + return 0; + } + + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_PAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=pauseCase&unpausedate='+unpausedate + }); + oRPC.callback = function(oRPC) { + //pausecasePanel.remove(); + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); +} + +var deleteCase = function(sApplicationUID) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_DELETE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=deleteCase&sApplicationUID='+sApplicationUID + }); + oRPC.callback = function(oRPC) { + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var unpauseCase = function() +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_UNPAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=unpauseCase' + }); + oRPC.callback = function(oRPC) { + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var view_reassignCase = function() +{ + var panel =new leimnud.module.panel(); + panel.options={ + size :{w:450,h:450}, + position:{x:50,y:50,center:true}, + /*statusBarButtons:[ + {value:G_STRINGS.ID_DELETE}, + {value:G_STRINGS.CANCEL} + ],*/ + title :'', + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + /*panel.elements.statusBarButtons[0].onmouseup=function() + { + window.location="processes_Delete.php?PRO_UID="+uid; + }; + panel.elements.statusBarButtons[1].onmouseup=panel.remove;*/ + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:"cases_Ajax", + args:"action=view_reassignCase" + }); + r.callback=function(rpc) + { + panel.loader.hide(); + panel.addContent(rpc.xmlhttp.responseText); + var scs=rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + }; + r.make(); + +}; + +var reassignCase = function(USR_UID, THETYPE) +{ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=reassignCase'+'&USR_UID='+USR_UID + '&THETYPE=' + THETYPE + }); + + oRPC.callback = function(oRPC) { + window.location = 'casesListExtJs'; + }.extend(this); + oRPC.make(); +}; + +var adhocAssignmentUsers = function () { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:450,h:450}, + position:{x:0,y:0,center:true}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=adhocAssignmentUsers' + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showUploadedDocuments = function() +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:700,h:350}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_UPLOADED_DOCUMENTS, + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showUploadedDocuments' + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showUploadedDocument = function(APP_DOC_UID) { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:300,h:300}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showUploadedDocument&APP_DOC_UID=' + APP_DOC_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showGeneratedDocuments = function() +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:700,h:350}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_GENERATED_DOCUMENTS, + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showGeneratedDocuments' + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showGeneratedDocument = function(APP_DOC_UID) { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:300,h:250}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showGeneratedDocument&APP_DOC_UID=' + APP_DOC_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showDynaforms = function() { + + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:400,h:300}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_DYNAFORMS, + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showDynaformList' + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + }; + + function showDynaform(DYN_UID) + { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:600,h:400}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showDynaform&DYN_UID='+DYN_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + function showDynaformHistory(DYN_UID,HISTORY_ID) + { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:550,h:400}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showDynaformHistory&DYN_UID='+DYN_UID+'&HISTORY_ID='+HISTORY_ID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + +var messagesListPanel; +var showHistoryMessages = function() + { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:800,h:420}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_HISTORY_MESSAGE_CASE, + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showHistoryMessages' + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + messagesListPanel = oPanel; +}; + +function showHistoryMessage(APP_UID, APP_MSG_UID) + { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:600,h:400}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() {delete(oPanel2);}.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showHistoryMessage&APP_UID='+APP_UID+'&APP_MSG_UID='+APP_MSG_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + +var deleteUploadedDocument = function(APP_DOC_UID) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_DELETE_FILE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=deleteUploadedDocument&DOC=' + APP_DOC_UID + }); + oRPC.callback = function(oRPC) { + if ((window.location.href.indexOf('/cases/cases_Step') > -1) && + (window.location.href.indexOf('?TYPE=INPUT_DOCUMENT&UID=') > -1) && + (window.location.href.indexOf('&ACTION=VIEW&') > -1) && + (window.location.href.indexOf('&DOC=' + APP_DOC_UID) > -1)) { + window.location = getField('DYN_FORWARD'); + } + else { + cases_AllInputdocsList.refresh(); + } + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var deleteGeneratedDocument = function(APP_DOC_UID) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_DELETE_FILE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=deleteGeneratedDocument&DOC=' + APP_DOC_UID + }); + oRPC.callback = function(oRPC) { + if ((window.location.href.indexOf('/cases/cases_Step') > -1) && + (window.location.href.indexOf('?TYPE=OUTPUT_DOCUMENT&UID=') > -1) && + (window.location.href.indexOf('&ACTION=VIEW&') > -1) && + (window.location.href.indexOf('&DOC=' + APP_DOC_UID) > -1)) { + window.location = getField('DYN_FORWARD'); + } + else { + cases_AllOutputdocsList.refresh(); + } + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +/** + * Resend the message that was sent. + * + * @Param Application ID + * @Param Message ID + * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com> + */ +var resendMessage = function(APP_UID, APP_MSG_UID) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_RESENDMSG, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=resendMessage&APP_UID='+APP_UID+'&APP_MSG_UID='+APP_MSG_UID + }); + oRPC.callback = function(rpc){ + //var scs=rpc.xmlhttp.responseText.extractScript(); + //alert(rpc.xmlhttp.responseText); + //scs.evalScript(); + messagesListPanel.clearContent(); + messagesListPanel.loader.show(); + var oRPC2 = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showHistoryMessages' + }); + oRPC2.callback = function(rpc){ + messagesListPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + messagesListPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC2.make(); + + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + + +function showdebug(){ + try{ + if( !parent.PANEL_EAST_OPEN ){ + parent.PANEL_EAST_OPEN = true; + var w = parent.Ext.getCmp('debugPanel'); + + /**show*/ + w.show(); + w.ownerCt.doLayout(); + w.expand(); + + parent.propStore.load(); + parent.triggerStore.load(); + + } + } catch(e){ + alert("Error: "+e) + } + return; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=showdebug' + }); + parent.document.getElementById('paneEastNorthContent').innerHTML = '<center><img src="/images/ajax-loader.gif" border="0"></center>'; + parent.document.getElementById('paneEastCenterContent').innerHTML = '<center><img src="/images/ajax-loader.gif" border="0"></center>';; + parent.document.getElementById('paneEastSouthContent').innerHTML = '<center><img src="/images/ajax-loader.gif" border="0"></center>';; + oRPC.callback = function(rpc){ + var scs=rpc.xmlhttp.responseText.extractScript(); + htmlResp = rpc.xmlhttp.responseText; + Sections = htmlResp.split('<!---->'); + parent.document.getElementById('paneEastNorthContent').innerHTML = Sections[0]; + parent.document.getElementById('paneEastCenterContent').innerHTML = Sections[1]; + parent.document.getElementById('paneEastSouthContent').innerHTML = Sections[2]; + scs.evalScript(); + }.extend(this); + oRPC.make(); +} + +var uploadInputDocument = function(docID,appDocId,docVersion,actionType){ + if(actionType){ + if(actionType=="R"){ + windowTitle=G_STRINGS.ID_UPLOAD_REPLACE_INPUT; + } + if(actionType=="NV"){ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT_VERSION; + } + }else{ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT; + docVersion=1; + actionType=""; + appDocId=""; + } + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:300}, + position:{x:0,y:0,center:true}, + title :windowTitle, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: "action=uploadInputDocument&docID="+docID+"&appDocId="+appDocId+"&docVersion="+docVersion+"&actionType="+actionType + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var uploadToReviseInputDocument = function(docID,appDocId,docVersion,actionType){ + if(actionType){ + if(actionType=="R"){ + windowTitle=G_STRINGS.ID_UPLOAD_REPLACE_INPUT; + } + if(actionType=="NV"){ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT_VERSION; + } + }else{ + windowTitle=G_STRINGS.ID_UPLOAD_NEW_INPUT; + docVersion=1; + actionType=""; + } + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:300}, + position:{x:0,y:0,center:true}, + title :windowTitle, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: "action=uploadToReviseInputDocument&docID="+docID+"&appDocId="+appDocId+"&docVersion="+docVersion+"&actionType="+actionType + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var inputDocumentVersionHistory = function(docID,appDocId){ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:550,h:400}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_INPUT_DOCUMENT_HISTORY, + theme :"processmaker", + statusBar:false, + control :{resize:true,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: "action=inputDocumentVersionHistory&docID="+docID+"&appDocId="+appDocId + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; \ No newline at end of file diff --git a/workflow/engine/js/cases/reassignByUser.js b/workflow/engine/js/cases/reassignByUser.js new file mode 100755 index 000000000..2d279e469 --- /dev/null +++ b/workflow/engine/js/cases/reassignByUser.js @@ -0,0 +1,140 @@ +/** + * Reassign ByUser routines + * Author Erik Amaru Ortiz <erik@colosa.com> + */ + +var reassignPanel; + +function toReassignPanel(){ + if( checks_selected_ids.length == 0 ){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_REASSIGN_BYUSER}); + return 0; + } + + /*oPanel = new leimnud.module.panel(); + oPanel.options = { + size : { w:1000, h:600 }, + position: { x:0,y:0,center:true }, + title : G_STRINGS.ID_MSG_RESSIGN_BYUSER_PANEL, + statusBar: false, + control : {resize:false,roll:false,drag:true}, + fx : { modal:true, opacity:true, blinkToFront:false, fadeIn:false, drag:true} + }; + oPanel.events = { + remove: function() { + delete(oPanel); + //resetChecks(); + //window.location = 'cases_ReassignByUser?REASSIGN_USER=' + getField('REASSIGN_USER').value; + }.extend(this) + };*/ + //oPanel.make(); + //oPanel.loader.show(); + + var USER_SELETED = getField('REASSIGN_USER').value; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=reassignByUserList&APP_UIDS='+checks_selected_ids+'&FROM_USR_ID='+USER_SELETED + }); + oRPC.callback = function(rpc) { + //oPanel.loader.hide(); + //var scs=rpc.xmlhttp.responseText.extractScript(); + //oPanel.addContent(rpc.xmlhttp.responseText); + //scs.evalScript(); + document.getElementById("publisherContent[0]").style.display = 'none'; + document.getElementById("publisherContent[1]").style.display = 'none'; + document.getElementById("publisherContent[10]").style.display = 'block'; + document.getElementById("publisherContent[10]").innerHTML = rpc.xmlhttp.responseText; + + }.extend(this); + oRPC.make(); + + //reassignPanel = oPanel; +} + +function toReassign(){ + var selects = document.getElementsByName('form[USERS]'); + var USER_SELETED = getField('REASSIGN_USER').value; + var items = ''; + for(i=0; i<selects.length; i++){ + if( selects[i].value != "0" ){ + if( items != '') items += ','; + id = selects[i].id; + id = id.trim(); + items += selects[i].id.substring(5, selects[i].id.length-1) +'|'+ selects[i].value; + } + } + + if( items.trim() == '' ){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_REASSIGN_BYUSER}); + return 0; + } + + new leimnud.module.app.confirm().make({ + label:G_STRINGS.ID_REASSIGN_BYUSER_CONFIRM, + action:function(){ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + args: 'action=reassignByUser&items='+items+'&USR_UID='+USER_SELETED + }); + //reassignPanel.loader.show(); + oRPC.callback = function(rpc) { + //reassignPanel.loader.hide(); + //reassignPanel.clearContent(); + /*reassignPanel.events = { + remove: function() { + delete(oPanel); + window.location = 'cases_ReassignByUser?REASSIGN_USER=' + getField('REASSIGN_USER').value; + }.extend(this) + };*/ + var scs=rpc.xmlhttp.responseText.extractScript(); + //reassignPanel.addContent(rpc.xmlhttp.responseText); + document.getElementById("publisherContent[10]").innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + oRPC.make(); + + }.extend(this) + }); +} + +function cancelReassign(){ + document.getElementById("publisherContent[0]").style.display = 'block'; + document.getElementById("publisherContent[1]").style.display = 'block'; + document.getElementById("publisherContent[10]").style.display = 'none'; + document.getElementById("publisherContent[10]").innerHTML = ''; +} + +function resetChecks(){ + checks_selected_ids.length = 0; +} + + +function WindowSize() { + var wSize = [0, 0]; + if (typeof window.innerWidth != 'undefined') + { + wSize = [ + window.innerWidth, + window.innerHeight + ]; + } + else if (typeof document.documentElement != 'undefined' + && typeof document.documentElement.clientWidth != + 'undefined' && document.documentElement.clientWidth != 0) + { + wSize = [ + document.documentElement.clientWidth, + document.documentElement.clientHeight + ]; + } + else { + wSize = [ + document.getElementsByTagName('body')[0].clientWidth, + document.getElementsByTagName('body')[0].clientHeight + ]; + } + return wSize; +} + + \ No newline at end of file diff --git a/workflow/engine/js/controls/varsAjax.js b/workflow/engine/js/controls/varsAjax.js new file mode 100644 index 000000000..f783810a6 --- /dev/null +++ b/workflow/engine/js/controls/varsAjax.js @@ -0,0 +1,31 @@ +/* function changeVariables + * @param varType variable type + * @param proUid process uid + * @param field process uid + * @param symbol process uid + * @param target target Element + * @desc a rpc call to change the variables that are show in the dynaform window + * sorted by the type of the variable + */ +var changeVariables = function(varType,proUid,field,symbol,target) { +// document.getElementById(target).innerHTML = "response test"; +// alert (document.getElementById(target).innerHTML); + //G.alert(PRO_UID); + //G.alert(getField('DYNAFORM').value); + //G.alert(getField('TASKS').value); + varType = varType.toLowerCase(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../controls/varsAjaxByType', + async : true, + method: 'POST', + args : "type="+varType+"&sProcess="+proUid+"&sFieldName="+field+"&sSymbol="+symbol + }); + + oRPC.callback = function(rpc){ + var scs=rpc.xmlhttp.responseText.extractScript(); + document.getElementById(target).innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + oRPC.make(); +} diff --git a/workflow/engine/js/dashboard/core/dashboard.js b/workflow/engine/js/dashboard/core/dashboard.js new file mode 100644 index 000000000..5207ca7f4 --- /dev/null +++ b/workflow/engine/js/dashboard/core/dashboard.js @@ -0,0 +1,61 @@ +var oPanel; +var oDashboards = {}; +var newDashboard = function() { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size : {w:500,h:205}, + position : {x:0,y:0,center:true}, + title : '', + theme : 'processmaker', + statusBar: true, + control : {resize:false, roll:false}, + fx : {modal:true, opacity:true, blinkToFront:true, fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'dashboardAjax', + args: 'action=showAvailableDashboards' + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var addDashboard = function(aDashboard) { + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'dashboardAjax', + args: 'action=addDashboard&sDashboardClass=' + aDashboard[0] + '&sElement=' + aDashboard[1] + '&sType=' + aDashboard[2] + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + oPanel.remove(); + eval(rpc.xmlhttp.responseText); + $("dashboard").innerHTML = ''; + window.Da=new leimnud.module.dashboard(); + Da.make({target:$("dashboard"),data:oDashboards}); + }.extend(this); + oRPC.make(); +}; + +var removeDashboard = function(sClass, sType, sElement) { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'dashboardAjax', + args: 'action=removeDashboard&sDashboardClass=' + sClass + '&sType=' + sType + '&sElement=' + sElement + }); + oRPC.callback = function(rpc){ + eval(rpc.xmlhttp.responseText); + $("dashboard").innerHTML = ''; + window.Da=new leimnud.module.dashboard(); + Da.make({target:$("dashboard"),data:oDashboards}); + }.extend(this); + oRPC.make(); +}; \ No newline at end of file diff --git a/workflow/engine/js/dbConnections/main.js b/workflow/engine/js/dbConnections/main.js new file mode 100755 index 000000000..8d490c1ae --- /dev/null +++ b/workflow/engine/js/dbConnections/main.js @@ -0,0 +1,497 @@ +/* + * Data base connection javascript routines + * @Author Erik Amatu Ortiz <erik@colosa.com> + * @Update date May 20th, 2009 + */ + +var PROCESS_REQUEST_FILE = '../dbConnections/dbConnectionsAjax'; + +String.prototype.trim = function() +{ + return this.replace(/^\s+|\s+get/g,""); +} + +var oPanel; +function newDbConnection() { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:450,h:380}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_DBS_NEW, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: 'action=newDdConnection' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + $('form[CREATE]').disabled = true; + }.extend(this); + oRPC.make(); +}; + +var saveDBConnection = function() { + if( getField('DBS_PORT').value.trim() == '' || getField('DBS_PORT').value.trim() == '0' ) { + onChangeType(); + } + + var type = $('form[DBS_TYPE]').value; + var server = $('form[DBS_SERVER]').value; + var db_name = $('form[DBS_DATABASE_NAME]').value; + var user = $('form[DBS_USERNAME]').value; + var passwd = $('form[DBS_PASSWORD]').value; + var port = $('form[DBS_PORT]').value; + var desc = $('form[DBS_DESCRIPTION]').value; + var enc = $('form[DBS_ENCODE]').value; + + var uri = 'action=saveConnection&type='+type+'&server='+server+'&db_name='+db_name+'&user='+user+'&passwd='+passwd+'&port='+port+'&desc='+desc+'&enc='+enc; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: uri + }); + + oRPC.callback = function(rpc){ + oPanel.clearContent(); + oPanel.addContent(rpc.xmlhttp.responseText); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + async : false, + method: 'POST', + args : 'action=showConnections' + }); + oRPC.make(); + mainPanel.clearContent(); + mainPanel.addContent(oRPC.xmlhttp.responseText); + oPanel.remove(); + }.extend(this); + oRPC.make(); +}; + +function saveEditDBConnection() +{ + if( getField('DBS_PORT').value.trim() == '' || getField('DBS_PORT').value.trim() == '0' ) { + onChangeType(); + } + + var dbs_uid = currentEditDBS_UID; + var type = $('form[DBS_TYPE]').value; + var server = $('form[DBS_SERVER]').value; + var db_name = $('form[DBS_DATABASE_NAME]').value; + var user = $('form[DBS_USERNAME]').value; + var passwd = $('form[DBS_PASSWORD]').value; + var port = $('form[DBS_PORT]').value; + var desc = $('form[DBS_DESCRIPTION]').value; + var enc = $('form[DBS_ENCODE]').value; + + var uri = 'action=saveEditConnection&type='+type+'&server='+server+'&db_name='+db_name+'&user='+user+'&passwd='+passwd+'&port='+port+'&dbs_uid='+dbs_uid+'&desc='+desc+'&enc='+enc; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: uri + }); + + oRPC.callback = function(rpc){ + oPanel.clearContent(); + oPanel.addContent(rpc.xmlhttp.responseText); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + async : false, + method: 'POST', + args : 'action=showConnections' + }); + oRPC.make(); + mainPanel.clearContent(); + mainPanel.addContent(oRPC.xmlhttp.responseText); + oPanel.remove(); + }.extend(this); + oRPC.make(); +} + +var currentEditDBS_UID; + +function editDbConnection(DBS_UID) +{ + currentEditDBS_UID = DBS_UID; + + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:450,h:380}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_DBS_EDIT, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:false}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: 'action=editDdConnection&DBS_UID=' + DBS_UID + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + $('form[CREATE]').disabled = true; + }.extend(this); + oRPC.make(); +} + +function deleteDbConnection(DBS_UID) +{ + new leimnud.module.app.confirm().make({ + label:G_STRINGS.ID_MSG_CONFIRM_REMOVE_DBS, + action:function(){ + + var uri = 'action=deleteDbConnection&dbs_uid='+DBS_UID; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: uri + }); + + oRPC.callback = function(rpc){ + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + async : false, + method: 'POST', + args : 'action=showConnections' + }); + oRPC.make(); + mainPanel.clearContent(); + mainPanel.addContent(oRPC.xmlhttp.responseText); + + }.extend(this); + oRPC.make(); + + }.extend(this) + }); +} + +function $(id){ + return document.getElementById(id); +} + +function AJAX() +{ + try { + xmlhttp = new XMLHttpRequest(); + } + catch(generic_error) { + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (microsoft_old_error) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (microsoft_error) { + xmlhttp = false; + } + } + } + return xmlhttp; +} + +var currentPopupWindow; + +function testDBConnection() +{ + if(validateFields()) { + var type = $('form[DBS_TYPE]').value; + var server= $('form[DBS_SERVER]').value; + var db_name = $('form[DBS_DATABASE_NAME]').value; + var user = $('form[DBS_USERNAME]').value; + var passwd = $('form[DBS_PASSWORD]').value; + var port = $('form[DBS_PORT]').value; + if(port.trim() == ''){ + port = 'default'; + } + var myPanel = new leimnud.module.panel(); + currentPopupWindow = myPanel; + myPanel.options = { + size:{w:500,h:400}, + position:{center:true}, + title: G_STRINGS.DBCONNECTIONS_TEST, + theme: "processmaker", + control: { close: false, roll: false, drag: true, resize: false}, + fx: { + shadow :true, + blinkToFront:true, + opacity :true, + drag:true, + modal: true + } + }; + + myPanel.make(); + myPanel.loader.show(); + + var requestfile = PROCESS_REQUEST_FILE; + var uri = 'action=showTestConnection&type='+type+'&server='+server+'&db_name='+db_name+'&user='+user+'&passwd='+passwd+'&port='+port; + + var ajax = AJAX(); + ajax.open("POST", requestfile, true); + ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); + ajax.onreadystatechange = function() { + if(ajax.readyState == 4) { + currentPopupWindow.clearContent(); + currentPopupWindow.addContent(ajax.responseText); + myPanel.command(myPanel.loader.hide); + testHost(1); + } + } + ajax.send(uri); + } +} + +var resultset = true; +var mainRequest; +mainRequestAbort=false; +function testHost(step) +{ + mainRequestAbort = false; + $("test_"+step).style.display = "block"; + + var type = $('form[DBS_TYPE]').value; + var server= $('form[DBS_SERVER]').value; + var db_name = $('form[DBS_DATABASE_NAME]').value; + var user = $('form[DBS_USERNAME]').value; + + if($('form[DBS_PASSWORD]').value != '') { + var passwd = $('form[DBS_PASSWORD]').value; + } else { + var passwd = 'none'; + } + + if($('form[DBS_PORT]').value.trim() != '') { + var port = $('form[DBS_PORT]').value; + } else { + var port = 'none'; + } + + var requestfile = PROCESS_REQUEST_FILE; + var uri = 'action=testConnection&step='+step+'&type='+type+'&server='+server+'&db_name='+db_name+'&user='+user+'&port='+port+'&passwd='+passwd; + + var ajax = AJAX(); + mainRequest = ajax; + ajax.open("POST", requestfile, true); + ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); + ajax.onreadystatechange = function() { + if(ajax.readyState == 4) { + try{ + response = ajax.responseText.trim(); + oresp = response.split(','); + result = oresp[0].trim(); + msg = oresp[1].trim(); + + if( result == 'SUCCESSFULL' ) { + $('status_'+step).innerHTML = ''; + if(msg != '') { + $('status_'+step).innerHTML = '<img src="/images/row_down.png" width="15" height="11" align="left" border="0"/><b>'+G_STRINGS.DBCONNECTIONS_MSGR+'<font color=#000>'+msg+'</b></font><br/>'; + } + $('status_'+step).innerHTML += '<img src="/images/ok.png" width="13" height="13" align="left" border="0"/><b>'+G_STRINGS.DBCONNECTIONS_MSGT+' <font color="#749AF9">'+G_STRINGS.DBCONNECTIONS_MSGS+'</b></font>'; + } + else { + if( result == 'FAILED' ) { + $('status_'+step).innerHTML = '<img src="/images/alert.gif" width="12" height="12" align="left" border="0"/><b>'+G_STRINGS.DBCONNECTIONS_MSGR+' <font color=red>'+msg+'</b></font><br/>'; + $('status_'+step).innerHTML += '<img src="/images/cross.gif" width="12" height="12" align="left" border="0"/><b>'+G_STRINGS.DBCONNECTIONS_MSGT+' <font color=red>'+G_STRINGS.DBCONNECTIONS_MSG2+'</b></font>'; + resultset = false; + } else { + alert(response); + return; + } + } + step += 1; + if(!mainRequestAbort) { + testHost(step); + } else { + return; + } + } catch (e) { + if(resultset){ + $('form[CREATE]').disabled = false; + } + else { + resultset = true; + $('form[CREATE]').disabled = true; + } + $('bnt_abort').style.display = 'none'; + $('bnt_ok').style.display = 'block'; + return; + }; + } else { + var html = "<img src='/images/activityanimation.gif'><br/><center>"+G_STRINGS.DBCONNECTIONS_MSG3+"....</center>"; // + $('status_'+step).innerHTML = html; + } + } + ajax.send(uri); +} + +function abortTestConnection() +{ + mainRequestAbort = true; + mainRequest.abort(); + currentPopupWindow.clearContent(); + currentPopupWindow.addContent("<br/><br/><center><font color=red><b>"+G_STRINGS.DBCONNECTIONS_MSGA+"</b></font></center>"); + setTimeout("currentPopupWindow.remove()",2000); +} + +function cancelTestConnection() +{ + currentPopupWindow.remove(); +} + + + +function validateFields() +{ + if( getField('DBS_PORT').value.trim() == '' || getField('DBS_PORT').value.trim() == '0' ) { + onChangeType(); + } + + var res = true; + var o = new input(getField('DBS_SERVER')); + if($('form[DBS_SERVER]').value == '') { + //new leimnud.module.app.alert().make({label: G_STRINGS.DBCONNECTIONS_MSG4}); + o.failed(); + res = false; + } else + o.passed(); + + var o = new input(getField('DBS_DATABASE_NAME')); + if($('form[DBS_DATABASE_NAME]').value == '') { + //new leimnud.module.app.alert().make({label: G_STRINGS.DBCONNECTIONS_MSG5}); + o.failed(); + res = false; + } else + o.passed(); + + var o = new input(getField('DBS_USERNAME')); + if($('form[DBS_USERNAME]').value == '') { + //new leimnud.module.app.alert().make({label: G_STRINGS.DBCONNECTIONS_MSG6}); + o.failed(); + res = false; + } else + o.passed(); + + /*var o = new input(getField('DBS_PORT')); + if($('form[DBS_PORT]').value == '') { + o.failed(); + res = false; + } else + o.passed();*/ + + var o = new input(getField('DBS_TYPE')); + if($('form[DBS_TYPE]').value == '0') { + o.failed(); + res = false; + } else + o.passed(); + + oType = getField('DBS_TYPE'); + if( oType.value != 'mssql' && oType.value != 'oracle' ){ + var o = new input(getField('DBS_ENCODE')); + if($('form[DBS_ENCODE]').value == '0') { + o.failed(); + res = false; + } else + o.passed(); + } + + + if(!res){ + new leimnud.module.app.alert().make({label: G_STRINGS.DBCONNECTIONS_ALERT}); + } + return res; +} + +var onChangeType = function() { + var oAux = getField('DBS_PORT'); + + switch(getField('DBS_TYPE').value) { + case 'mysql': + oAux.value = '3306'; + break; + case 'pgsql': + oAux.value = '5432'; + break; + case 'mssql': + oAux.value = '1433'; + break; + case 'oracle': + oAux.value = '1521'; + break; + default: + oAux.value = ''; + } + +}; + +function showEncodes(pre){ + oType = getField('DBS_TYPE'); + //if( oType.value != 'mssql' && oType.value != 'oracle' ){ + if( oType.value != 'oracle' ){ + showRowById('DBS_ENCODE'); + var o = new input(getField('DBS_TYPE')); + if($('form[DBS_TYPE]').value == '0') { + o.failed(); + res = false; + } else + o.passed(); + + var o = getField('DBS_TYPE'); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : PROCESS_REQUEST_FILE, + args: 'action=showEncodes&engine='+o.value + }); + + oRPC.callback = function(rpc){ + var oEnc = getField('DBS_ENCODE'); + response = eval('{'+oRPC.xmlhttp.responseText+'}'); + + oEnc.options.length = 0; + //set news + for(i=0; i<response.length; i++){ + var newOption = new Option(response[i][1], response[i][0]); + oEnc.options[i] = newOption; + } + + if(pre != null) + oEnc.value = pre; + + + var o = new input(getField('DBS_ENCODE')); + if($('form[DBS_ENCODE]').value == '0') { + o.failed(); + res = false; + } else + o.passed(); + }.extend(this); + oRPC.make(); + } else { + hideRowById('DBS_ENCODE'); + } +} + + diff --git a/workflow/engine/js/departments/departments.js b/workflow/engine/js/departments/departments.js new file mode 100644 index 000000000..72a09c50b --- /dev/null +++ b/workflow/engine/js/departments/departments.js @@ -0,0 +1,65 @@ +function saveUserGroup(sUser) { + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../groups/groups_Ajax', + async : false, + method: 'POST', + args : 'action=assignUser&GRP_UID=' + currentGroup + '&USR_UID=' + sUser + }); + oRPC.make(); + currentPopupWindow.remove(); + selectGroup(currentGroup); + } + + +function saveUsers(){ + if( checks_selected_ids.length == 0 ){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_MSG_GROUPS_ADDCONFIRM}); + return 0; + } + //alert('action=assignAllUsers&DEP_UID=' + currentGroup + '&aUsers=' + checks_selected_ids);return; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : false, + method: 'POST', + args : 'action=assignAllUsers&DEP_UID=' + currentGroup + '&aUsers=' + checks_selected_ids + }); + resetChecks(); + oRPC.make(); + currentPopupWindow.remove(); + selectDpto(currentGroup); +} + +function resetChecks(){ + checks_selected_ids.length = 0; +} + + +function WindowSize() { + var wSize = [0, 0]; + if (typeof window.innerWidth != 'undefined') + { + wSize = [ + window.innerWidth, + window.innerHeight + ]; + } + else if (typeof document.documentElement != 'undefined' + && typeof document.documentElement.clientWidth != + 'undefined' && document.documentElement.clientWidth != 0) + { + wSize = [ + document.documentElement.clientWidth, + document.documentElement.clientHeight + ]; + } + else { + wSize = [ + document.getElementsByTagName('body')[0].clientWidth, + document.getElementsByTagName('body')[0].clientHeight + ]; + } + return wSize; + } + + \ No newline at end of file diff --git a/workflow/engine/js/dynaformEditor/core/dynaformEditor.js b/workflow/engine/js/dynaformEditor/core/dynaformEditor.js new file mode 100755 index 000000000..e1c2ebdeb --- /dev/null +++ b/workflow/engine/js/dynaformEditor/core/dynaformEditor.js @@ -0,0 +1,567 @@ +if (typeof(dynaformEditor)==="undefined") +{ +var dynaformEditor={ + A:"", + dynUid:"", + ajax:"", + currentView:"preview", + views:{}, + toolbar:{}, + htmlEditorLoaded:false, + loadPressLoaded:true, + codePressLoaded:false, + currentJS:false, + _run:function() + { + //LOADING PARTS + this.toolbar = document.getElementById("fields_Toolbar") + mainPanel.elements.headerBar.style.backgroundColor="#CBDAEF"; + mainPanel.elements.headerBar.style.borderBottom="1px solid #808080"; + mainPanel.elements.headerBar.appendChild(this.toolbar); + mainPanel.events.remove = function(){ + } + this.refresh_preview(); + }, + _review:function() + { + + }, + save:function(){ + /*this.saveProperties();*/ + try { + this.saveCurrentView(); + } catch (e) { + alert(e); + } + res=this.ajax.save(this.A,this.dynUid); + if(res=='noSub'){ + alert(G_STRINGS.ID_DONT_SAVE_XMLFORM); + return false; + } + if (res==0) { + alert(G_STRINGS.ID_SAVED); + } + else + { + G.alert(res["*message"]); + } + }, + save_as:function(){ + /*this.saveProperties();*/ + try { + this.saveCurrentView(); + } catch (e) { + alert(e); + } + url='dynaforms_Saveas'; + popupWindow('Save as', url+'?DYN_UID='+this.dynUid+'&AA='+this.A , 500, 350); + }, + /* + * @function close + * @author unknow + * @modifier Gustavo Cruz + * @desc this function handles the close of a dynaform editor window + * now whenever a dynaform window is close, if the form wasn't + * saved the function also delete the temporal *_tmp0.xml files + * discarding all the changes that were made, bug 3861. + */ + close:function() + { + var modified=this.ajax.is_modified(this.A,this.dynUid); + if (typeof(modified)==="boolean") + { + if (!modified || confirm(G_STRINGS.ID_EXIT_WITHOUT_SAVING)) + { + res=this.ajax.close(this.A); + if (res==0) { + //alert(G_STRINGS.ID_DYNAFORM_NOT_SAVED); + } + else + { + //alert(res["response"]); + alert(res["*message"]); + } + return true; + } + else + { + return false; + } + } + else + { + if (typeof(modified["*message"])==="string") G.alert(modified["*message"]); + return false; + } + }, + // Save functions + saveCurrentView:function() + { + switch(this.currentView) + { + case "xmlcode": + this.saveXmlCode(); + break; + case "htmlcode": + this.saveHtmlCode(); + break; + case "javascripts": + this.saveJavascript(); + break; + case "properties": + this.saveProperties(); + break; + } + }, + saveXmlCode:function() + { +// var xmlCode = getField("XML").value; + var xmlCode = this.getXMLCode(); + var todoRefreshXmlCode = xmlCode === null; + if (todoRefreshXmlCode) return; + var res = this.ajax.set_xmlcode(this.A,xmlCode.replace(/\+/g, '%2B')); + if (res!=="") G.alert(res); + }, + saveHtmlCode:function() + { + var htmlCode = getField("HTML"); + todoRefreshHtmlCode = htmlCode === null; + if (todoRefreshHtmlCode) return; + var response=this.ajax.set_htmlcode(this.A,htmlCode.value); + if (response) G.alert(response["*message"],"Error"); + }, + saveJavascript:function() + { + var field=getField("JS_LIST","dynaforms_JSEditor"); + var code=this.getJSCode(); + if (field.value) + { + var res=this.ajax.set_javascript(this.A,field.value,code.replace(/\+/g, '%2B')); + if (typeof(res["*message"])==="string") + { + G.alert(res["*message"]); + } + } + }, + saveProperties:function() + { + var form=this.views["properties"].getElementsByTagName("form")[0]; + var post=ajax_getForm(form); + var response=this.ajax.set_properties(this.A,this.dynUid,post); + if (response!=0){ + G.alert(response["*message"]); + } + }, + // Change view point functions + changeToPreview:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + if (this.currentView!="preview")this.refresh_preview(); + this.currentView="preview"; + }, + changeToXmlCode:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + + this.refresh_xmlcode(); + this.currentView="xmlcode"; + if (this.loadPressLoaded && !XMLCodePress) + { + startXMLCodePress(); + } + }, + changeToHtmlCode:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + + this.refresh_htmlcode(); + this.currentView="htmlcode"; + }, + changeToFieldsList:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='visible'; + + this.refreshFieldsList(); + this.currentView="fieldslist"; + }, + changeToJavascripts:function() + { + var field=getField("JS_LIST","dynaforms_JSEditor"); + var res=this.ajax.get_javascripts(this.A,field.value); + + + this.currentView="javascripts"; + this.refreshJavascripts(); + if(field.value!='' || typeof(res.aOptions[0])!='undefined'){ + hideRowById('JS_TITLE'); + showRowById('JS'); + showRowById('JS_LIST'); + + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + + //this.currentView="javascripts"; + //this.refreshJavascripts(); + if (this.loadPressLoaded && !JSCodePress) + { + startJSCodePress(); + } + }else{ + showRowById('JS_TITLE'); + hideRowById('JS'); + hideRowById('JS_LIST'); + + } + }, + changeToProperties:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + + this.currentView="properties"; + this.refreshProperties(); + }, + changeToShowHide:function() + { + //to adecuate the view perspective @Neyek + content_div = getElementByPMClass('panel_content___processmaker') + content_div.style.overflow='auto'; + //alert('xxxxxx'); + this.currentView="showHide"; + this.refreshShowHide(); + }, + // Refresh functions + refreshCurrentView:function() + { + switch(this.currentView) + { + case "preview":this.refresh_preview();break; + case "htmlcode":this.refresh_htmlcode();break; + case "xmlcode":this.refresh_xmlcode();break; + case "fieldslist":this.refreshFieldsList();break; + case "javascripts":this.refreshJavascripts();break; + case "properties":this.refreshProperties();break; + } + }, + refresh_preview:function() + { + var editorPreview = document.getElementById("editorPreview"); + var todoRefreshPreview = editorPreview === null; + if (todoRefreshPreview) return; + editorPreview.innerHTML = this.ajax.render_preview(this.A); + var myScripts = editorPreview.getElementsByTagName("SCRIPT"); + this.runScripts(myScripts); + delete myScripts; + }, + refresh_htmlcode:function() + { + var dynaformEditorHTML = this.views["htmlcode"]; + if (this.htmlEditorLoaded) + { + var response=this.ajax.get_htmlcode(this.A); + response={"html":response, + "error":((typeof(response)==="string")?0:response)}; + } + else + { + var response=this.ajax.render_htmledit(this.A); + } + if ((response.error==0) && (this.htmlEditorLoaded)) + { + window._editorHTML.doc.body.innerHTML=response.html; + html_html2(); + html2_html(); + } + else if ((response.error==0) && (!this.htmlEditorLoaded)) + { + dynaformEditorHTML.innerHTML=response.html; + this.runScripts(dynaformEditorHTML.getElementsByTagName("SCRIPT")); + this.htmlEditorLoaded=true; + } + else + { + dynaformEditorHTML.innerHTML=response.html; + this.runScripts(dynaformEditorHTML.getElementsByTagName("SCRIPT")); + G.alert(response.error["*message"],"Error"); + return; + } + getField("PME_HTML_ENABLETEMPLATE","dynaforms_HtmlEditor").checked=this.getEnableTemplate(); + }, + refresh_xmlcode:function() + { + var response=this.ajax.get_xmlcode(this.A); + if (response.error===0) + { + //xmlCode.value = response.xmlcode; + this.setXMLCode(response.xmlcode); + } + else + { + G.alert(response.error["*message"],"Error"); + } + }, + refreshFieldsList:function() { + //fields_List.refresh(); return; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'fieldsHandler', + args: '' + }); + document.getElementById('dynaformEditor[6]').innerHTML = ''; + oRPC.callback = function(rpc) { + + var scs=rpc.xmlhttp.responseText.extractScript(); + document.getElementById('dynaformEditor[6]').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + + }.extend(this); + oRPC.make(); + }, + refreshShowHide:function() { + //fields_List.refresh(); return; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide', + args: '' + }); + document.getElementById('dynaformEditor[9]').innerHTML = ''; + + oRPC.callback = function(rpc) { + + var scs=rpc.xmlhttp.responseText.extractScript(); + document.getElementById('dynaformEditor[9]').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + + }.extend(this); + oRPC.make(); + }, + getJSCode:function() + { + if (JSCodePress) + { + return JSCodePress.getCode(); + } + else + { + return getField("JS","dynaforms_JSEditor").value; + } + }, + setJSCode:function(newCode) + { + if (JSCodePress) + { + JSCodePress.setCode(newCode); + //JSCodePress.edit(newCode,"javascript"); + } + else + { + var code=getField("JS","dynaforms_JSEditor"); + code.value=newCode; + } + }, + getXMLCode:function() + { + if (XMLCodePress) + { + return XMLCodePress.getCode(); + } + else + { + return getField("XML","dynaforms_XmlEditor").value; + } + }, + setXMLCode:function(newCode) + { + if (XMLCodePress) + { + XMLCodePress.setCode(newCode); + //XMLCodePress.edit(newCode,"xmlform"); + } + else + { + var code=getField("XML","dynaforms_XmlEditor"); + code.value=newCode; + } + }, + setEnableTemplate:function(value) + { + value = value ? "1" : "0"; + this.ajax.set_enabletemplate( this.A , value ); + }, + getEnableTemplate:function() + { + var value = this.ajax.get_enabletemplate( this.A ); + return value == "1"; + }, + refreshJavascripts:function() + { + var field=getField("JS_LIST","dynaforms_JSEditor"); + + for(j=0; j<field.options.length; j++) { + if( field.options[j].value == '___pm_boot_strap___' ){ + field.remove(j); + } + } + + this.currentJS=field.value; + var res=this.ajax.get_javascripts(this.A,field.value); + if(field.value == ''){ + if( typeof(res.aOptions[0]) !== "undefined" && res.aOptions[0].value != '___pm_boot_strap___'){ + res = this.ajax.get_javascripts(this.A, res.aOptions[0].value); + this.currentJS = res.aOptions[0].value; + } + } + + + if (typeof(res["*message"])==="undefined") + { + while(field.options.length>0) field.remove(0); + for(var i=0;i<res.aOptions.length;i++) + { + var optn = document.createElement ("OPTION"); + optn.text = res.aOptions[i].value; + optn.value = res.aOptions[i].key; + field.options[i]=optn; + } + field.value = this.currentJS; + this.setJSCode(res.sCode); + } + else + { + G.alert(response.error["*message"],"Error"); + } + + var field=getField("JS_LIST","dynaforms_JSEditor"); + for(j=0; j<field.options.length; j++) { + if( field.options[j].value == '___pm_boot_strap___' ){ + field.options[j].text = ''; + } + } + + if(field.options.length > 0 || typeof(res.aOptions[0])!== "undefined"){ + hideRowById('JS_TITLE'); + showRowById('JS'); + showRowById('JS_LIST'); + if (this.loadPressLoaded && !JSCodePress) + { + startJSCodePress(); + } + }else{ + showRowById('JS_TITLE');hideRowById('JS_LIST');hideRowById('JS');} + + }, + changeJavascriptCode:function() + { + var field=getField("JS_LIST","dynaforms_JSEditor"); + var value=field.value; + if (this.currentJS) + { + field.value=this.currentJS; + this.saveJavascript(); + field.value=value; + } + this.refreshJavascripts(); + }, + refreshProperties:function() + { + var form=this.views["properties"].getElementsByTagName("form")[0]; + var prop=this.ajax.get_properties(this.A,this.dynUid); + getField("A","dynaforms_Properties").value=prop.A; + getField("DYN_UID","dynaforms_Properties").value=prop.DYN_UID; + getField("PRO_UID","dynaforms_Properties").value=prop.PRO_UID; + getField("DYN_TITLE","dynaforms_Properties").value=prop.DYN_TITLE; + getField("DYN_TYPE","dynaforms_Properties").value=prop.DYN_TYPE; + getField("DYN_DESCRIPTION","dynaforms_Properties").value=prop.DYN_DESCRIPTION; + getField("WIDTH","dynaforms_Properties").value=prop.WIDTH; + /*getField("ENABLETEMPLATE","dynaforms_Properties").checked=(prop.ENABLETEMPLATE=="1");*/ + getField("MODE","dynaforms_Properties").value=prop.MODE; + }, + // Internal functions + runScripts:function(scripts) + { + var myScripts=[]; + for(var rr=0; rr < scripts.length ; rr++){ + myScripts.push(scripts[rr].innerHTML); + } + for(var rr=0; rr < myScripts.length ; rr++){ + try { + if (myScripts[rr]!=="") + if (window.execScript) { + window.execScript( myScripts[rr], "javascript" );} + else + window.setTimeout( "try{\n"+myScripts[rr]+"\n}catch(e){\ndynaformEditor.displayError(e,"+rr+")}", 0 ); + } catch (e) { + dynaformEditor.displayError(e,rr); + } + } + delete myScripts; + }, + restoreHTML:function() + { + window._editorHTML.doc.body.innerHTML = this.ajax.restore_html(this.A); + html_html2(); + html2_html(); + }, + displayError:function(err,rr) + { + G.alert(err.message.split("\n").join("<br />"),"Javascript Error"); + } +}; +} +else +{ + alert("Donde esta esto!!!"); +} + + +function getElementByPMClass(__class){ + divs = document.getElementsByTagName('div'); + for(i=0; i<divs.length; i++){ + if(divs[i].className == __class){ + return divs[i]; + } + } + return false; +} + + + /**/ + + function fieldsSave( form ) { + + var str = document.getElementById('form[PME_XMLNODE_NAME]').value; + str.split(" ").length; + if(str.split(" ").length>=2){ + msgBox(G_STRINGS.ID_EMPTY_NODENAME,"alert"); + return; + } + + if (pme_validating) { + validatingForm=form; + setTimeout('fieldsSave(validatingForm);',100); + return; + } + if (!G.getObject(form).verifyRequiredFields()){ + return; + } + //processbar.style.display = ''; + var res=ajax_post( form.action, form, 'POST' , null , false ); + currentPopupWindow.remove(); + dynaformEditor.refreshCurrentView(); + } + + function fieldsAdd( type,label ){ + if(!label){ + label=type; + } + popupWindow(G_STRINGS.ID_ADD + ' ' + label , '../dynaforms/fields_Edit?A='+DYNAFORM_URL+'&TYPE='+encodeURIComponent(type) , 510, 650, null,false,true); + } + diff --git a/workflow/engine/js/dynaforms/dynaforms_conditionalShowHide.js b/workflow/engine/js/dynaforms/dynaforms_conditionalShowHide.js new file mode 100755 index 000000000..cee9726a9 --- /dev/null +++ b/workflow/engine/js/dynaforms/dynaforms_conditionalShowHide.js @@ -0,0 +1,695 @@ +/** + * Conditional show hide class + * + * @Author Erik A. Ortiz. <erik@colosa.com, aortiz.erik@gmail.com> + * @date Feb 22, 2010 + */ + +var conditionEditorPanel; + +var Conditional = function(DYN_UID){ + + this.DYN_UID = DYN_UID; + this.client = getBrowserClient(); + + this.dynavarsPanel = null; + this.dynavarsPanelNew = null; + this.fields = Array(); + this.conditionVariables = new Object(); + this.conditionVariables.___IsSET___ = false; + this.conditionVariablesFromSetup = new Object(); + this.conditionVariablesFromSetup.___IsSET___ = false; + this.aConditionVariablesFromSetup = new Array(); + + this.canSave = false; + this.conditionTested = false; + + this.setDynUid = function(id){ + this.DYN_UID = id; + } + + this.showID = function(){ + alert('DYN_UID: '+this.DYN_UID); + } + + this.editor = function(sType){ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size : {w:730, h:595}, + position : {x:0, y:0, center:true}, + title : G_STRINGS.CONDITIONAL_TITLE, + statusBar: false, + control : {resize:false,roll:false,drag:true}, + fx : {modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() {delete(oPanel);}.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + sExtra = ''; + if(sType != 'new'){ + FCD_UID = sType; + sType = 'edit'; + sExtra = '&FCD_UID='+FCD_UID; + } + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request='+sType+sExtra + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + conditionEditorPanel = this.dynavarsPanelNew = oPanel; + } + + + this.populate = function(filter){ + + if( typeof(filter) != 'undefined' ){ + if( filter.IN ){ + // + } + } + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request=getDynaFieds' + }); + oRPC.callback = function(rpc) { + var scs = rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + oFields = getField('fields'); + oEventOwner = getField('event_owner'); + var response = eval(oRPC.xmlhttp.responseText); + + for(i=0; i<response.length; i++){ + this.fields[i] = response[i]; + var newOption = new Option(response[i], response[i]); + var newOption2 = new Option(response[i], response[i]); + + oFields.options[i] = newOption; + oEventOwner.options[i] = newOption2; + } + oFields[0].selected = true; + oEventOwner[0].selected = true; + }.extend(this); + oRPC.make(); + } + + this.populateEdit = function(){ + var oFCD_FIELDS = getField('FCD_FIELDS'); + var oFCD_EVENT_OWNERS = getField('FCD_EVENT_OWNERS'); + var oFCD_EVENTS = getField('FCD_EVENTS'); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request=getDynaFieds' + }); + oRPC.callback = function(rpc) { + var j, k; + + oFields = getField('fields'); + oEventOwner = getField('event_owner'); + oFieldsSelected = getField('fields_selected'); + oEventOwnerSelected = getField('event_owner_selected'); + oEventOnload = getField('eventOnload'); + oEventOnchange = getField('eventOnchange'); + + var response = eval(oRPC.xmlhttp.responseText); + + j = 0; + k = 0; + for(i=0; i<response.length; i++){ + this.fields[i] = response[i]; + if( oFCD_FIELDS.value.indexOf(response[i]) === -1 ){ + var newOption = new Option(response[i], response[i]); + oFields.options[j++] = newOption; + } else { + var newOption = new Option(response[i], response[i]); + oFieldsSelected.options[k++] = newOption; + } + } + + j = 0; + k = 0; + for(i=0; i<response.length; i++){ + this.fields[i] = response[i]; + if( oFCD_EVENT_OWNERS.value.indexOf(response[i]) === -1 ){ + var newOption = new Option(response[i], response[i]); + oEventOwner.options[j++] = newOption; + } else { + var newOption = new Option(response[i], response[i]); + oEventOwnerSelected.options[k++] = newOption; + } + } + + if( oFCD_EVENTS.value.indexOf('onload') !== -1 ){ + oEventOnload.checked = true; + } + + if( oFCD_EVENTS.value.indexOf('onchange') !== -1 ){ + oEventOnchange.checked = true; + } + + }.extend(this); + oRPC.make(); + } + + this.toSelect = function(target, target2){ + var oTarget = getField(target); + var oTargetSelected = getField(target2); + this.deselectAll(oTargetSelected); + + var aSelectedOptions = Array(); + + for (i = 0; i<oTarget.length; i++) { + if ( oTarget.options[i].selected ){ + aSelectedOptions.push(oTarget.options[i]); + } + } + + c = oTargetSelected.length; + for (i = 0; i<aSelectedOptions.length; i++) { + oTargetSelected.options[c] = new Option(aSelectedOptions[i].text, aSelectedOptions[i].value); + oTargetSelected.options[c].selected = true; + c++; + } + + this.dropSelectedOption(target); + } + + this.dropSelectedOption = function(target){ + var o = getField(target); + var Options = Array(); + var c = 0; + var selectedIndex = o.selectedIndex; + + if( o.options.length > 0 ){ + if(o.options.length == 0){ + return false; + } + + for(i=0; i<o.options.length; i++){ + Options.push(o.options[i]); + } + + o.options.length = 0; + + for(i=0; i<Options.length; i++){ + if( !Options[i].selected ){ + o.options[c++] = Options[i]; + } + } + + if( selectedIndex >= 0 && selectedIndex < o.options.length ){ + o.options[selectedIndex].selected = true; + } else if( selectedIndex >= 0 && o.options.length > 0 ){ + o.options[selectedIndex-1].selected = true; + } + } + } + + this.deselectAll = function(list){ + for(i=0; i<list.length; i++){ + list.options[i].selected = false; + } + } + + this.setCharacter = function(sItem){ + var f = getField('FCD_CONDITION'); + + switch(this.client.browser){ + case 'msie': + try{ + if(typeof document.selection != 'undefined' && document.selection) { + var str = document.selection.createRange().text; + f.focus(); + var sel = document.selection.createRange(); + sel.text = sItem; + sel.select(); + return; + }else if(typeof f.selectionStart != 'undefined'){ + var start = f.selectionStart; + var end = f.selectionEnd; + var insText = f.value.substring(start, end); + f.value = f.value.substr(0, start) + sItem + f.value.substr(end); + f.focus(); + f.setSelectionRange(start+2+tag.length+insText.length+3+tag.length,start+2+tag.length+insText.length+3+tag.length); + return; + }else{ + f.value+=sItem; + return; + } + alert(f.value); + }catch(e){ + alert(e+"_"); + } + break; + + case 'firefox': + + var _ini = f.selectionStart; + var _fin = f.selectionEnd; + var inicio = f.value.substr(0, _ini); + var fin = f.value.substr(_fin, f.value.length); + + f.value = inicio + sItem + fin; + if (_ini == _fin) { + f.selectionStart = inicio.length + sItem.length; + f.selectionEnd = f.selectionStart; + } + else { + f.selectionStart = inicio.length; + f.selectionEnd = inicio.length + sItem.length; + } + f.focus(); + break; + default: + } + } + + this.showDynavars = function(e){ + + if( this.dynavarsPanel !== null ){ + return false; + } + oPanel = new leimnud.module.panel(); + oPanel.options = { + size : {w:150, h:200}, + position : {x:e.clientX, y:e.clientY, center:false}, + title : '', + statusBar : false, + control : {resize:false,roll:false,drag:true}, + fx : {modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { + delete(oPanel); + this.dynavarsPanel = null; + }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + this.dynavarsPanel = oPanel; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request=getDynaFieds' + }); + + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + + response = eval(rpc.xmlhttp.responseText); + + sel = document.createElement('select'); + sel.id='vars'; + sel.size='11'; + sel.multiple='true'; + sel.style.className = ' module_app_input___gray'; + sel.style.fontSize = '11px'; + sel.style.width = '140px'; + + + sel.ondblclick = function(){ + oConditional.dynavarsPanel.remove(); + oConditional.dynavarsPanel = null; + + oConditional.setCharacter('@#'+sel.options[sel.selectedIndex].value); + } + + max = 0; + for (i=0, j=response.length; i<j; i++) { + x = response[i]; + sel.appendChild(document.createElement('option')); + sel.options[i].text = sel.options[i].value = x; + + if(x.length > max){ + max = x.length; + } + } + oPanel.resize({w:((max*10) ),h:200}); + oPanel.addContent(sel); + + }.extend(this); + oRPC.make(); + } + + this.testCondition = function(saving){ + var oCondition = getField('FCD_CONDITION'); + var sCondition = oCondition.value; + var sError; + var result; + sCondition = sCondition.replace(/@#/g, ''); + sCondition = sCondition.replace(/\n/gi, ''); + + saving = (typeof(saving) != 'undefined')? true: false; + + this.createConditionVariables(); + this.mergeConditionVariables(); + var aCVariables = this.getConditionVariables(); + + this.conditionTested = true; + + for(i=0; i<aCVariables.length; i++){ + try { + eval("var "+aCVariables[i]+" = (typeof(this.conditionVariables."+aCVariables[i]+")!='undefined')? this.conditionVariables."+aCVariables[i]+": '';"); + } catch(e) { + continue; + } + } + + try{ + eval('result = (' + sCondition + ')?1:0;'); + this.canSave = true; + } catch(e){ + sError = e; + this.canSave = false; + } + + if(this.canSave){ + if( saving != true ){ + bResult = (result)? 'TRUE': 'FALSE'; + oResultDiv = document.getElementById("ResultMessageTD"); + oResultDiv.style.display = 'block'; + oResultDiv.style.backgroundColor = '#BFCCC5'; + oResultDiv.style.color = '#000000'; + oResultDiv.innerHTML = '[Success] Evaluation result: '+bResult; + fade('ResultMessageTD', 'inOut'); + var o = new input(oResultDiv); + var oF = new input(getField('FCD_CONDITION')); + o.passed(); + oF.passed(); + } + } else{ + oResultDiv = document.getElementById("ResultMessageTD"); + oResultDiv.style.display = 'block'; + oResultDiv.style.backgroundColor = 'red'; + oResultDiv.style.color = '#fff'; + oResultDiv.innerHTML = '[Failed] '+sError; + fade('ResultMessageTD', 'inOut'); + var o = new input(oResultDiv); + var oF = new input(getField('FCD_CONDITION')); + o.failed(); + oF.failed(); + } + } + + + this.testConditionSetup = function(){ + var oCondition = getField('FCD_CONDITION'); + var sCondition = oCondition.value; + + var sFields = ''; + for(i=0; i<this.fields.length; i++){ + if( sCondition.indexOf(this.fields[i]) !== -1 ){ + sFields += (sFields == '')? this.fields[i]: ','+this.fields[i]; + } + } + + if( sFields != '' ){ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size : {w:420, h:400}, + position : {x:0, y:0, center:true}, + title : '', + control : {resize:false,roll:false,drag:true}, + fx : {modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { + delete(oPanel); + this.dynavarsPanel = null; + }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + this.dynavarsPanel = oPanel; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request=testSetup&sFields='+sFields + }); + + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs = rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + }.extend(this); + oRPC.make(); + } else { + msgBox(G_STRINGS.CONDITIONAL_NOFIELDS_IN_CONDITION, 'alert'); + } + + } + + this.getConditionVariables = function(){ + var oCondition = getField('FCD_CONDITION'); + var sCondition = oCondition.value; + var conditionVariables = new Array(); + var j=0; + + for(i=0; i<this.fields.length; i++){ + if( sCondition.indexOf(this.fields[i]) !== -1 ){ + conditionVariables[j++] = this.fields[i]; + } + } + + return conditionVariables; + } + + this.createConditionVariablesFromSetup = function(){ + var sName, sValue; + var i, j=0; + + for(i=1; i<Number.MAX_VALUE; i++){ + try{ + if( typeof(document.getElementById('form[gFields]['+i+'][dynaid]')) == 'undefined' ){ + break; + } + var oVar = new Object() + sName = document.getElementById('form[gFields]['+i+'][dynaid]').value; + sValue = document.getElementById('form[gFields]['+i+'][dynavalue]').value; + oVar.name = sName; + oVar.value = sValue; + this.aConditionVariablesFromSetup[j++] = oVar; + eval("this.conditionVariablesFromSetup."+sName+"='"+sValue+"';"); + } catch(e){ + break; + } + } + this.dynavarsPanel.remove(); + } + + this.createConditionVariables = function(){ + var conditionVariables = this.getConditionVariables(); + for(i=0; i<conditionVariables.length; i++){ + eval("this.conditionVariables."+conditionVariables[i]+"='';"); + } + this.conditionVariables.___IsSET___ = true; + } + + this.getConditionVariable = function (varname){ + var vVar = eval("this.conditionVariables."+conditionVariables+"='';"); + return vVar; + } + + this.mergeConditionVariables = function(){ + var aCV = this.getConditionVariables(); + for(i=0; i<aCV.length; i++){ + try { + eval("this.conditionVariables."+aCV[i]+"=(typeof(this.conditionVariablesFromSetup."+aCV[i]+")!='undefined')? this.conditionVariablesFromSetup."+aCV[i]+": '';"); + } catch(e) { + continue; + } + } + } + + this.populateTestConditionSetup = function(){ + var sName, sValue; + var i; + + for(i=1; i<Number.MAX_VALUE; i++){ + try{ + if( typeof(document.getElementById('form[gFields]['+i+'][dynaid]')) == 'undefined' ){ + break; + } + sName = document.getElementById('form[gFields]['+i+'][dynaid]').value; + + eval("document.getElementById('form[gFields]["+i+"][dynavalue]').value = (typeof(this.conditionVariablesFromSetup."+sName+") != 'undefined')? this.conditionVariablesFromSetup."+sName+": '';"); + } catch(e){ + break; + } + } + } + + this.saveCondition = function(){ + var oTmp; + this.canSave = true; + oUID = getField('FCD_UID'); + oFieldsSelected = getField('fields_selected'); + oEventOwnerSelected = getField('event_owner_selected'); + getField('FCD_CONDITION').value = getField('FCD_CONDITION').value.replace(/\n/gi, ''); + oCondition = getField('FCD_CONDITION'); + oFunction = getField('FCD_FUNCTION'); + sEvents = ''; + + oOnChange = getField('eventOnload'); + if(oOnChange.checked){ + sEvents = 'onload'; + } + + oOnLoad = getField('eventOnchange'); + if(oOnLoad.checked){ + sEvents += (sEvents != '')? ',onchange': 'onchange'; + } + oEnabled = getField('FCD_STATUS'); + sEnabled = (oEnabled.checked)? '1': '0'; + + //validations... + oTmp = new input(oFieldsSelected); + if( oFieldsSelected.length != 0 || oFunction.value == 'showAll' || oFunction.value == 'hideAll'){ + oTmp.passed(); + } else { + oTmp.failed(); + this.canSave = false; + } + + oTmp = new input(oEventOwnerSelected); + if( oEventOwnerSelected.length != 0 ){ + oTmp.passed(); + } else { + oTmp.failed(); + this.canSave = false; + } + + oTmp = new input(oCondition); + if( oCondition.value.trim() != '' ){ + oTmp.passed(); + } else { + oTmp.failed(); + oResultDiv = document.getElementById("ResultMessageTD"); + oResultDiv.style.display = 'none'; + this.canSave = false; + } + + + if( this.canSave ){ + //alert('ok'); + } else { + msgBox(G_STRINGS.CONDITIONAL_ALERT1, 'alert'); + return false; + } + + oTmp = new input(oOnChange); + if( oOnChange.checked || oOnLoad.checked ){ + oTmp.passed(); + } else { + msgBox(G_STRINGS.CONDITIONAL_ALERT2, 'alert'); + oTmp.failed(); + this.canSave = false; + return false; + } + + if( !this.conditionTested ){ + msgBox(G_STRINGS.CONDITIONAL_ALERT3, 'confirm', this.doSave, this.cancelSave); + } else{ + this.testCondition('saving'); + if( this.canSave ){ + this.doSave(); + } else { + msgBox(G_STRINGS.CONDITIONAL_ALERT4, 'confirm', this.doSave, this.cancelSave); + } + } + + } + + this.doSave = function(){ + + oUID = getField('FCD_UID'); + oFieldsSelected = getField('fields_selected'); + oEventOwnerSelected = getField('event_owner_selected'); + getField('FCD_CONDITION').value = getField('FCD_CONDITION').value.replace(/\n/gi, ''); + oCondition = getField('FCD_CONDITION'); + oFunction = getField('FCD_FUNCTION'); + sEvents = ''; + + oOnChange = getField('eventOnload'); + if(oOnChange.checked){ + sEvents = 'onload'; + } + + oOnLoad = getField('eventOnchange'); + if(oOnLoad.checked){ + sEvents += (sEvents != '')? ',onchange': 'onchange'; + } + oEnabled = getField('FCD_STATUS'); + sEnabled = (oEnabled.checked)? '1': '0'; + + fields_selected = ''; + for(i=0; i<oFieldsSelected.length; i++){ + fields_selected += (fields_selected == '')? oFieldsSelected[i].value: ','+oFieldsSelected[i].value; + } + event_owner_selected = ''; + for(i=0; i<oEventOwnerSelected.length; i++){ + event_owner_selected += (event_owner_selected == '')? oEventOwnerSelected[i].value: ','+oEventOwnerSelected[i].value; + } + sCondition = escape(oCondition.value); + sCondition = sCondition.replace(/\+/g, '%2B'); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'conditionalShowHide_Ajax', + args: 'request=save&fields_selected='+fields_selected+'&event_owner_selected='+event_owner_selected+'&function='+oFunction.value+'&condition='+sCondition+'&events='+sEvents+'&enabled='+sEnabled+'&FCD_UID='+oUID.value + }); + + + oRPC.callback = function(rpc) { + conditionEditorPanel.remove(); + var oRPC = new leimnud.module.rpc.xmlhttp({url: 'conditionalShowHide', args: ''}); + oRPC.callback = function(rpc) { + var scs=rpc.xmlhttp.responseText.extractScript(); + document.getElementById('dynaformEditor[9]').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + oRPC.make(); + }.extend(this); + oRPC.make(); + } + + this.cancelSave = function(){ + //alert('calcel'); + } + + this.remove = function(FCD_UID){ + msgBox('Are you sure to delete this condition?', 'confirm', function(){ + var oRPC = new leimnud.module.rpc.xmlhttp({url: 'conditionalShowHide_Ajax', args: 'request=delete&FCD_UID='+FCD_UID}); + + oRPC.callback = function(rpc) { + var oRPC = new leimnud.module.rpc.xmlhttp({url: 'conditionalShowHide', args: ''}); + oRPC.callback = function(rpc) { + var scs=rpc.xmlhttp.responseText.extractScript(); + document.getElementById('dynaformEditor[9]').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + oRPC.make(); + }.extend(this); + oRPC.make(); + }); + } + +} + +function conditionHasChanged(){ + oConditional.testSaveCondition(); +} diff --git a/workflow/engine/js/dynaforms/dynaforms_fieldsHandler.js b/workflow/engine/js/dynaforms/dynaforms_fieldsHandler.js new file mode 100755 index 000000000..0d2c69227 --- /dev/null +++ b/workflow/engine/js/dynaforms/dynaforms_fieldsHandler.js @@ -0,0 +1,151 @@ + eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(s($){3.1s.1k=s(j){j=3.1a({12:\'1m.1j\'},j);8 k=(n.P=="r 10 Z"&&U(n.v)==4&&n.v.E("14 5.5")!=-1);8 l=(n.P=="r 10 Z"&&U(n.v)==4&&n.v.E("14 6.0")!=-1);o(3.17.16&&(k||l)){3(2).L("1r[m$=.M]").z(s(){3(2).7(\'q\',3(2).q());3(2).7(\'p\',3(2).p());8 a=\'\';8 b=\'\';8 c=(3(2).7(\'K\'))?\'K="\'+3(2).7(\'K\')+\'" \':\'\';8 d=(3(2).7(\'A\'))?\'A="\'+3(2).7(\'A\')+\'" \':\'\';8 e=(3(2).7(\'C\'))?\'C="\'+3(2).7(\'C\')+\'" \':\'\';8 f=(3(2).7(\'B\'))?\'B="\'+3(2).7(\'B\')+\'" \':\'\';8 g=(3(2).7(\'R\'))?\'1d:\'+3(2).7(\'R\')+\';\':\'\';8 h=(3(2).1c().7(\'1b\'))?\'19:18;\':\'\';o(2.9.y){a+=\'y:\'+2.9.y+\';\';2.9.y=\'\'}o(2.9.t){a+=\'t:\'+2.9.t+\';\';2.9.t=\'\'}o(2.9.w){a+=\'w:\'+2.9.w+\';\';2.9.w=\'\'}8 i=(2.9.15);b+=\'<x \'+c+d+e+f;b+=\'9="13:11;1q-1p:1o-1n;O:W-V;N:1l;\'+g+h;b+=\'q:\'+3(2).q()+\'u;\'+\'p:\'+3(2).p()+\'u;\';b+=\'J:I:H.r.G\'+\'(m=\\\'\'+3(2).7(\'m\')+\'\\\', D=\\\'F\\\');\';b+=i+\'"></x>\';o(a!=\'\'){b=\'<x 9="13:11;O:W-V;\'+a+h+\'q:\'+3(2).q()+\'u;\'+\'p:\'+3(2).p()+\'u;\'+\'">\'+b+\'</x>\'}3(2).1i();3(2).1h(b)});3(2).L("*").z(s(){8 a=3(2).T(\'N-S\');o(a.E(".M")!=-1){8 b=a.X(\'1g("\')[1].X(\'")\')[0];3(2).T(\'N-S\',\'1f\');3(2).Q(0).Y.J="I:H.r.G(m=\'"+b+"\',D=\'F\')"}});3(2).L("1e[m$=.M]").z(s(){8 a=3(2).7(\'m\');3(2).Q(0).Y.J=\'I:H.r.G\'+\'(m=\\\'\'+a+\'\\\', D=\\\'F\\\');\';3(2).7(\'m\',j.12)})}1t 3}})(3);',62,92,'||this|jQuery||||attr|var|style|||||||||||||src|navigator|if|height|width|Microsoft|function|padding|px|appVersion|margin|span|border|each|class|alt|title|sizingMethod|indexOf|scale|AlphaImageLoader|DXImageTransform|progid|filter|id|find|png|background|display|appName|get|align|image|css|parseInt|block|inline|split|runtimeStyle|Explorer|Internet|relative|blankgif|position|MSIE|cssText|msie|browser|hand|cursor|extend|href|parent|float|input|none|url|after|hide|gif|pngFix|transparent|blank|line|pre|space|white|img|fn|return'.split('|'),0,{})) + + jQuery.fn.newWindow = function(){ + $(this).click(function(){ + var newWindow = window.open(jQuery(this).attr('href'), '_blank').focus(); + return false; + }); + jQuery(this).attr('title', '* This link opens in a new window'); + return jQuery(this); + } + + $.fn.equalHeights = function(px) { + $(this).each(function(){ + var currentTallest = 0; + $(this).children().each(function(i){ + if($(this).height() > currentTallest) { currentTallest = $(this).height(); } + }); + if(!px || !Number.prototype.pxToEm) currentTallest = currentTallest.pxToEm($(this)); //use ems unless px is specified or + // for ie6, set height since min-height isn't supported + var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1); + if ($.browser.msie && (ie6)) { $(this).children().css({'height': currentTallest}); } + $(this).children().css({'min-height': currentTallest}); + }); + return $(this); + }; + + $(function(){ + var client = parent.getBrowserClient(); + if(client.browser == 'msie'){ + timefade = 0; + } else { + timefade = 500; + } + + $('body').addClass('jq-enhanced'); //add enhanced class to body + $('#jq-secondaryNavigation a, #jq-footerNavigation a').each(function(){$(this).textDropShadow();}); //nav drop shads + /*$('#dynafields td.options').hover( + function(){ + $(this).find('div.jq-checkpointSubhead:hidden').fadeIn(timefade); + $(this).find('div.tool').fadeOut(0); + }, + function(){ + $(this).find('div.jq-checkpointSubhead:visible').fadeOut(timefade); + $(this).find('div.tool').fadeIn(0); + } + );*/ + if( !$.browser.msie ){ //interior content box heights + $('#jq-interior #jq-content').equalHeights(); + } + $(document).pngFix(); + }); + + + $(document).ready(function() { + $("#sortable").sortable({ + opacity: 0.6, + cursor: 'crosshair', + cursorAt: 'top', + placeholder: 'ui-state-highlight', + olerance: 'pointer', + update: fieldsHandlerSave + }); + $("#sortable").disableSelection(); + }); + function Ax(){ + $("#effect").animate({backgroundColor: 'orange', color: '#fff', width: 250}, 1000); + } + function Bx(){ + $("#effect").animate({backgroundColor: '#fff', color: '#000', width: 180}, 1000); + } + //setTimeout('Ax()', 1200); + + function fieldsHandlerSave(){ + items = $("#sortable").sortable('toArray'); + e = $('input:checkbox'); + hidden_elements = ''; + for(i=0; i<e.length; i++){ + if( !e[i].checked ){ + if(hidden_elements != '') + hidden_elements += ',' + hidden_elements += e[i].id; + } + } + + $.ajax({ + type: "POST", + url: "fieldsHandlerAjax", + data: "request=save&items="+items+"&hidden="+hidden_elements, + success: function(httpResponse){ + //alert( "Data Saved: " + httpResponse ); + } + }); + } + + function fieldsHandlerSaveHidden(){ + e = $('input:checkbox'); + hidden_elements = ''; + for(i=0; i<e.length; i++){ + if( !e[i].checked ){ + if(hidden_elements != '') + hidden_elements += ',' + hidden_elements += e[i].id; + } + } + $.ajax({ + type: "POST", + url: "fieldsHandlerAjax", + data: "request=saveHidden&hidden="+hidden_elements, + success: function(httpResponse){ + //alert( "Data Saved: " + httpResponse ); + } + }); + } + + function backImage(oImg,p){ + oImg.style.background=p; + } + + + var helpPanel = null; + function showHelp(e){ + if( typeof(helpPanel) != 'undefined'){ + helpPanel = new window.parent.leimnud.module.panel(); + xW = 400; + xH = 160; + helpPanel.options = { + size : {w:xW, h:xH}, + position : { x:e.clientX-xW, y:e.clientY+(xH/2), center:false }, + title : '', + theme : "processmaker", + statusBar : false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + helpPanel.events = { + remove: function() { helpPanel = null;} + }; + + helpPanel.make(); + helpPanel.addContent(document.getElementById('help').innerHTML); + } + } + + function setClass(o, xclass){ + try{ + o.className = xclass; + } catch(e){ + //alert(e); + } + } + \ No newline at end of file diff --git a/workflow/engine/js/events/events.js b/workflow/engine/js/events/events.js new file mode 100644 index 000000000..970520f80 --- /dev/null +++ b/workflow/engine/js/events/events.js @@ -0,0 +1,254 @@ +/** + * Main events routines + * @Autor Erik A.O. <erik@colosa.com> + **/ + +var eventsNewAction = function(oForm) { + if(getField('EVN_DESCRIPTION').value.trim() == ''){ + msgBox('Set a description please.', 'alert'); + return false; + } + + if (oForm.onsubmit()) { + oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../events/eventsNewAction', + method: 'POST', + args : 'PRO_UID=' + getField('PRO_UID').value + + '&EVN_DESCRIPTION=' + getField('EVN_DESCRIPTION').value + + '&EVN_STATUS=' + getField('EVN_STATUS').value + + '&EVN_WHEN=' + getField('EVN_WHEN').value + + '&EVN_WHEN_OCCURS=' + getField('EVN_WHEN_OCCURS').value + + '&EVN_RELATED_TO=' + getField('EVN_RELATED_TO').value + + '&TAS_UID=' + getField('TAS_UID').value + + '&EVN_TAS_UID_FROM=' + getField('EVN_TAS_UID_FROM').value + + '&EVN_TAS_UID_TO=' + getField('EVN_TAS_UID_TO').value + + '&EVN_TAS_ESTIMATED_DURATION=' + getField('EVN_TAS_ESTIMATED_DURATION').value + + '&EVN_ACTION=' + getField('EVN_ACTION').value + + '&EVN_CONDITIONS=' + getField('EVN_CONDITIONS').value + + '&TRI_UID=' + getField('TRI_UID').value + }); + oRPC.callback = function(oRPC) { + currentPopupWindow.clearContent(); + currentPopupWindow.addContent(oRPC.xmlhttp.responseText); + var scs = oRPC.xmlhttp.responseText.extractScript(); + scs.evalScript(); + refreshEventList(); + + currentPopupWindow.resize({w:620,h:500}); + + }.extend(this); + oRPC.make(); + } +}; + +/** Event Actions Composer **/ +var EventCompose = function(t){ + + this.ie = document.all ? true : false; + this.target = t; + + this.set= function(v){ + this.taget = v; + } + + this.add=function(){ + + this.deselectAll(); + o = getField(this.target); + val = getField(this.target+'_SIMPLEADD').value; + + + if(this.exists(val)) { + new leimnud.module.app.alert().make({label: G_STRINGS.EVENT_EMAILEXISTS}); + return false; + } + if(val == ''){ + return false; + } + if(!this.validEmail(val)){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_INVALID_EMAIL}); + return false; + } + + id = val; + id = id.replace('"', '"e;'); + id = id.replace('"', '"e;'); + + + var newOption = new Option(val, "ext|"+id); + newOption.selected=true; + o.options[o.options.length] = newOption; + + getField(this.target+'_SIMPLEADD').value = ''; + return false; + } + this.showUsers=function(e){ + + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:400,h:310}, + position:{x:e.clientX,y:e.clientY,center:false}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../events/eventsAjax', + args: 'request=showUsers' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + + this.showGroups=function(e){ + + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:350,h:310}, + position:{x:e.clientX,y:e.clientY,center:false}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../events/eventsAjax', + args: 'request=showGroups' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + + this.showDynavars=function(e){ + + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:350,h:310}, + position:{x:e.clientX,y:e.clientY,center:false}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../events/eventsAjax', + args: 'request=showDynavars' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + this.pos=function(e){ + var u = ie ? event.clientY + document.documentElement.scrollTop : e.pageY; + var l = ie ? event.clientX + document.documentElement.scrollLeft : e.pageX; + + return 0; + } + this.toAdd= function(id, value, prefix){ + + if(this.exists(id)) { + new leimnud.module.app.alert().make({label: G_STRINGS.EVENT_EMAILEXISTS}); + return false; + } + + this.deselectAll(); + o = getField(this.target); + + if(prefix == 'dyn'){ + var newOption = new Option('@#'+value, prefix+"|"+id); + } else { + var newOption = new Option(value, prefix+"|"+id); + } + + newOption.selected=true; + o.options[o.options.length] = newOption; + } + this.dropSel= function(){ + var o = getField(this.target); + c=0; + Options = Array(); + if(o.options.length == 0){ + return false; + } + for(i=0; i<o.options.length; i++){ + Options.push(o.options[i]); + } + o.options.length = 0; + for(i=0; i<Options.length; i++){ + + if(!Options[i].selected){ + //var newOption = new Option(id, value); + o.options[c++] = Options[i]; //newOption; + } + } + if(o.options.length>0){ + o.options[o.options.length-1].selected = true; + } + + } + this.deselectAll= function(){ + var o = getField(this.target); + for(i=0; i<o.options.length; i++){ + o.options[i].selected = false; + } + } + this.exists= function(value){ + var o = getField(this.target); + for(i=0; i<o.options.length; i++){ + v = o.options[i].value; + if(value == v.substr(4)){ + return true; + } + } + return false; + } + this.validEmail = function (val) { + if( val.indexOf('<') !=-1 && val.indexOf('>') !=-1 ){ + if (/^([\"\w@\.-_\s]*\s*)?<\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+>$/.test(val)){ + return true; + } else { + return false; + } + } else { + if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(val)){ + return true; + } else { + return false; + } + } + } + +} \ No newline at end of file diff --git a/workflow/engine/js/groups/groups.js b/workflow/engine/js/groups/groups.js new file mode 100755 index 000000000..72b7578a9 --- /dev/null +++ b/workflow/engine/js/groups/groups.js @@ -0,0 +1,64 @@ +function saveUserGroup(sUser) { + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../groups/groups_Ajax', + async : false, + method: 'POST', + args : 'action=assignUser&GRP_UID=' + currentGroup + '&USR_UID=' + sUser + }); + oRPC.make(); + currentPopupWindow.remove(); + selectGroup(currentGroup); + } + + +function saveUsers(){ + if( checks_selected_ids.length == 0 ){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_MSG_GROUPS_ADDCONFIRM}); + return 0; + } + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../groups/groups_Ajax', + async : false, + method: 'POST', + args : 'action=assignAllUsers&GRP_UID=' + currentGroup + '&aUsers=' + checks_selected_ids + }); + resetChecks(); + oRPC.make(); + currentPopupWindow.remove(); + selectGroup(currentGroup); +} + +function resetChecks(){ + checks_selected_ids.length = 0; +} + + +function WindowSize() { + var wSize = [0, 0]; + if (typeof window.innerWidth != 'undefined') + { + wSize = [ + window.innerWidth, + window.innerHeight + ]; + } + else if (typeof document.documentElement != 'undefined' + && typeof document.documentElement.clientWidth != + 'undefined' && document.documentElement.clientWidth != 0) + { + wSize = [ + document.documentElement.clientWidth, + document.documentElement.clientHeight + ]; + } + else { + wSize = [ + document.getElementsByTagName('body')[0].clientWidth, + document.getElementsByTagName('body')[0].clientHeight + ]; + } + return wSize; + } + + \ No newline at end of file diff --git a/workflow/engine/js/processes/main.js b/workflow/engine/js/processes/main.js new file mode 100755 index 000000000..728927e8c --- /dev/null +++ b/workflow/engine/js/processes/main.js @@ -0,0 +1,37 @@ +var panel; +var dropProcess=function(uid) +{ + panel =new leimnud.module.panel(); + panel.options={ + size :{w:450,h:250}, + position:{x:50,y:50,center:true}, + statusBarButtons:[ + {value:'Delete'}, + {value:G_STRINGS.CANCEL} + ], + title :G_STRINGS.ID_PROSESSESCASE, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + + panel.elements.statusBarButtons[0].onmouseup=function() + { + window.location="processes_Delete.php?PRO_UID="+uid; + }; + + panel.elements.statusBarButtons[1].onmouseup=panel.remove; + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:"process_DeleteCases.php", + method:"GET", + args:"PRO_UID="+uid + }); + r.callback=function(rpc) + { + panel.loader.hide(); + panel.addContent(rpc.xmlhttp.responseText); + }; + r.make(); +} \ No newline at end of file diff --git a/workflow/engine/js/processmap/core/images/-1.gif b/workflow/engine/js/processmap/core/images/-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..801df587625ec92b5d9e33071375a3023e750380 GIT binary patch literal 668 zcmZ?wbhEHblw^=(IF`e}oIc}!pUI~){h^)HulD->UmIgkHu>ef!y8YY=c+p1*I)f) zbM=nxGhZx9c>dsQVOvw{iq-#bFAbWqNu*%z*$r(^_xF69>2=`h?VdRkeJWc1zrFPT z+RR(4N_ewp{NI{a)Zc&W+JXN|gZ@vlELya|xM}(SLyePn9{>Mjw{pe&%gamOU0?VA z<K0brH*M%noYtE8e^24n{Zs$1h;nb4p;R<2Y3|nlFOSb#F)e-Syjh#p{Xg5B)H8)4 zZRXco>z$it9yqb*>xXB~mEHeOcK_d-{eQLxOUBH1a|7R<oU(EI8nN7|503V~e0n{q zx?%6pt^YSB{6AXz|5Bf9$($wYW|mBz%$hm7XvUoX-(Ff&O}V<cb^ndWQ<qG;x3PNG z-jhl5c7IqB_vL8M|0z!Y*Qflyzd@>KwsO@{$?Q2+t;>SiCWrLS70H`f+%x6g-YLbi z=KrSvDE?$&<YK62&|v@qP@FKZ|7@slYHq3L<ZSKiYHjcCYigf3siVJVa_`j6=`&j* zl9?kWMKB8|M@)?oj<#RZzGjVDa7>?2s+abTox8NXRD`-rQu(Bg96ffFPs5~DT$tVT z!o^FM6@<lGG%VC_-?@A5wtz-6M}SS@^A|5)J=aR&Xi_#8{QTwXx3B5SO}0GJ|Nb*D zGxc0@7GPlX7t)G3QIII4^m`G<9E}N%2kn*5-ML-yzHOg9$B`8g?nbiw8t+*aYMeCU z;VW#OwKb;vK$N1aaoVEGNe=Bw#$oGfKD#BhNxEBgBuG>(YMR1lC;xLsV_E~RglR&` a#KyEXe!u#NH7^+#<nU|hh_Ny;SOWk8sB<I$ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/-1b.gif b/workflow/engine/js/processmap/core/images/-1b.gif new file mode 100755 index 0000000000000000000000000000000000000000..8d5a462436018b018ddd10008c36dca4d8dbfe28 GIT binary patch literal 1061 zcmZ?wbhEHblw^=(_|Cw<oIc}!pUI~){h^)HulD->UmIgkHu>ef!y8YY=c+p1*I)f) zbM=nxGhZx9c>dsQVOvw{iq-#bFAbWqNu*%z*$r(^_xF69>2=`h?VdRkeJWc1zrFPT z+RR(4N_ewp{NI{a)Zc&W+JXN|gZ@vlELya|xM}(SLyePn9{>Mjw{pe&%gamOU0?VA z<K0brH*M%noYtE8e^24n{Zs$1h;nb4p;R<2Y3|nlFOSb#F)e-Syjh#p{Xg5B)H8)4 zZRXco>z$it9yqb*>xXB~mEHeOcK_d-{eQLxOUBH1a|7R<oU(EI8nN7|503V~e0n{q zx?%6pt^YSB{6AXz|5Bf9$($wYW|mBz%$hm7XvUoX-(Ff&O}V<cb^ndWQ<qG;x3PNG z-jhl5c7IqB_vL8M|0z!Y*Qflyzd@>KwsO@{$?Q2+t;>SiCWrLS70H`f+%x6g-YLbi z=KufypJ5aX%@EK5IUAH07&!hj+~kn)nBd#Q!YZt#Q&F(cxshGj%jL&}hez5(h2ze6 z2%Mh57@?9RX^_Y>tt&<?=jXvs3f|MymK79gEbN&iYEk?uW?@SUORLE#iwh20R$N@f z7jQwNBJoh8RKQ}dxm-zySerBo=G-{7b@lbN0s%ZO46W`nHfLO3WxLvmhpACH&t-=9 z_H}o6rMq#wIhfFVe}4lrbKfOr1qMccA?>&`6@@}d)r&di>CA9UG*doz=WfmSwm376 zBP$}jt#tV{@>v&YoVDWN+sHh7TU_;lEJs=6w8dAG9NL|X!`9V&^-64$Y`5x2kf>YK qG=*=U{I3~}X$`y*rU@w%8`IkO`*I@IaJ^()P{XgKBgV$UU=08Uqdj#1 literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/-1bb.jpg b/workflow/engine/js/processmap/core/images/-1bb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bdc1f71198f594af58ff952ee1ae9fe80f0e4022 GIT binary patch literal 828 zcmex=<NpH&0WUXCHwH#VCI%TGWcdG(LCm!xGmU}4*Ox(yfq{Voh=Jh$Z3brsR%R9! z7G_o;!OF_Y#?HgR4g~z%+?+gu{6a#4{DOkQVlv{wB2uD)f)a`nQnIr0^76vsN-9cn zDl&5Nav(z(fm+$w*!eg(_~b+cMdU~Z{|_(-axkbds4+7tF)#@-G7B>PKf)lzz{tSN z$jAtBEtmwlkdcK0C}$+Vz{t$Z%*e{Z4V7kOVrF4r6=V}qWEWO)3{2!OENm1}Q8O`1 zDcXGS@&}+ENsw90$i^|SFfy?+1EmxM8JL)u7+DdLz`$b`G-P2F5>^b{`2Q9I4^ShM zAhRHYJ;N`ZlJsSJ{?7jXugd*fxVzh~-1&zSeo1cP_<L&q<i=TNOb>6*EjhF}<L7to zB*nFfyEg}4JFKr$5Y6FM9g>n<dArGI(!wdLTDIP3h-ZFRs=8I%RYlGJ41e+cHy;cy z-WFh%uXwET_%&bQdD8_IVd9t8YOgElamy3FY*Z9^PkPg`56dncP?@S>#+Z9_by0`c z6b75gleo-eO>3H0=yuL$^uD=c;SpWyu*;nmL1Ob+nGebzWSg@zURxyLu(hy^wZxT$ zS5_YDnY>gp_|((*Rh#B_E?DQ?^Xf+Q!W~ba$cP2K?#%V$zcf{}W|f_!z@yDVIt90R z7V2(mnI|-*fq|v)!1*7~)^49&;=OlS?7HIEHIcrW(*x(EYDw7qsL8e}du#2h|HA6z z_JG^9*YtHagvxmpAB=FYo!ovzKzPoSIWpn)D}r-Z*rW&bnNGd-d{3S~r+<;z{0YZw z3j=?J9#8&i747>yYUgd2ogAM^w=UhX=BKEtOVzi!sSm27BIZV<o%+4~XP4}WZ%4#C zf2=4Ed==uRb#_6{bdIj+HT&9xD|Wo$Gdr)*cglF<l=(8Enl3+A{N(!Z@=x{E-)roa p{W-m=K-B!FZpl*Z^(tLKQ##MCeB5}nr10HRO+l}qiT3|*0sxps87}|; literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/-2.gif b/workflow/engine/js/processmap/core/images/-2.gif new file mode 100644 index 0000000000000000000000000000000000000000..bcd626aacf7b7e05020db83461dfebf9fd098dc9 GIT binary patch literal 796 zcmV+%1LOQhNk%w1VHp4!0OkMy0A`t%+;e8kGe^el?fK`+?ztR=vTEJ^wcYMepv4M$ z$IbBlkL3NB&gFU1Ogfdnx96YI>h)Hv&#UPD@B03N#NP~aq~`bDHJinw%-@i|)^X47 zx8(Ka_x}I?|2C@BE`zNWb)=)`{et2BY|QLpvD5SW@4D*zjM-)2`2T9nIKu0#x7X(C z_~T5Ky7&G6TGaTS-SsPnvYh4oOPj%9rN)iX?AG%AxbFUPx!9D|?`o~h18AEbiMJwp zrpD#+qu_)wj=0nC#6h;+fYnud((gc>#pd+-5O$~V`s?ri{~UOxwCMcD^8Q(#zntEC zm*@U-&_w(G`PlXTZP)i8fv<SV>2coui^bl~@4lVS<-X~tLaEWc*yRXpp3e9GjNbpf z@BYZ`wxZ(t!sYZzoV|V2QPS)7l)cuy==f;0){fa}VAJ(`xYZ+%yoT3Z@Bi-^eXM-W z?EnA&000000000000000000000000000000000000000000000A^8LW2LN*bEC2ui z02u%o000O7fOCR_gmVfCg^7xVhl`Gahmn$qkAq!4laV1lU6oED8b_HFM;bg%jxHb( z9UT;sFBB9VXCN+$P9Q%iDK8!#hrhqAKR&30EEZ%p9l|YQ5MnJ-!#4;aEQCvK3n{-B zZvx`tPXxay3p-1L86jy46dnXo<Mn129xn?VAsK=-G{W5QAZ1Oxg8_cs2=kzZpdb}a zG`n!{po%0OI-JN6L=b=&Onix{c(8y63QTnH@Hl3SuL30NtvCsW4FHcY4#dk6b6ge= zDGm&{Imf_|D+@eO?0L~clPez#2r}a4iU@)zdII?c<w_4Df+|>`GNPFY2PBEK06Kz- zmkNV<kZ>6>;a7_%D(XEkk#E8X3`htyu&{wam=}l%WZ5DFV?G=VNbqP-=mC-<P;hjh zChQl52~di}d7vmr6*)6R;Fuzd!VMfEW>`VeanS=F5@Lv$z`M5&BVI^9(h|Z#5H&Vp a*eD^xLI^FD24P7cgNJn)39u{*1OPirwuO@b literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/0.gif b/workflow/engine/js/processmap/core/images/0.gif new file mode 100644 index 0000000000000000000000000000000000000000..925e514b692d3b07cf99b43bbf39e0483d78f3e7 GIT binary patch literal 909 zcmZ?wbhEHblw=TR_|Cv!Y;1h_^3}b2559Qu^2d*#XU?3td-wjkckloI|9|-Kv1`}v zoj7s&!-o$HqhK@yhGPimfIJ1t3k)1Z43Zo&9vc=MY~~QwiaD`ip>s2Xl3Pv02F9jt zUJaofhXu)Qy-b!>ERvrZPWCHE^F(w8E%utGB57jauvyiafwxHO#!lmOW(HnH774E@ r8UgJLTpF=a4_-Jka4&Kz^%8VwS{-7_BrriV<@$_-!(FP90u0swecDKw literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/0t.gif b/workflow/engine/js/processmap/core/images/0t.gif new file mode 100644 index 0000000000000000000000000000000000000000..cfae0a317dc2ab14a994ae5cae6049c0196d07d9 GIT binary patch literal 13154 zcmeI3X>=1+7>1|FqQ!l$>vV9VHkrw!ZOE9UVrnU90BIG(bvkpCj!9<5$&{pV19!2C z6;UfLfVgjnyQqLWDkAQ?Qa7|JE~wxZ?ld7Ocn+TL2mih~ImykP=ex^u-@kX%=*AI# zxq_)+rZNmSeL*gltIQ3Z6dBJp$hJ&>1N9kGR^r5FTS-jQgWQ@$i#b+PgWSa0h!8Qu zq)lteTBJEUwnfRt6~D^WhspyPDU&pl#Fp7iGNGrWOpudRqm@Xs?R4`T+lSckAUD!^ z!8&t>4U4cfZjVb5yfti1om=#YeqUWR+brAc7+GgUA1ew1{SqawkAB#~!-dLeD`2Tn zX+lF|VNUul$hFzFDe-(dopz_aZo`W49>3qu3nDLyE=ssk9l9-NTzYC)evpmhG?0{H zX{N0iI_r!pw;JtskmH<*icev4vRRx+Pr3Ux>Q;;-pOH=8;}-bh$h0s(JEgEiWZSS> z3?mWBZ@*EqNZPRCDK^~f4LFsXK&4qr^@JV~2{}Gog5Tv4Td0*<pX3oI_p8rCo0Ufl zRf~4~r`#(E9;wz_DDMXq$^*P3qMw*P>&~7w>;FGts#5f2wp)q5V^I~JBuJ9zc8WUl zZ0bx^q^MyfWjmxL<rv{(S~S3yI=8sK{HkdzXe{|+E;lZ{c$8bEQS!c3hR+X*lYr!+ zF4P4w0D>`Hs0(BO1Y^2T7svnz#&n@BkO2^k=|Wu~10WdFg}OinKrp5Yb%6|kU`!Y4 z0vQ0om@d=>G5~@xU8oCW00d*YP#4Gm2*z}wE|38bjOjvMAOj#6(}lV~20$>T3w41E zfM84)>H--6!I&=81u_7FF<qz&WB>$Xx=<I$00`b<y2?v8J%~=Pccke(j<Vdp|NQ;e zpX=BC@%wLUfBog>pVs{N!}q=4eY^UbufO{8i=I`VfA;AoAAj`W2k*c4?mKV4_2$Yq zR=mFawO3zR_VP<FzVQ5W&n{iE_?f4lTJ+=-k3aV4BM(2c@WBNS+<)J__uPHgop;=R z+x%PS&7E`0%{SdR`-bl8ue)~EH8Zd7x@yLiS9D%J{jy6hx%i?BFF1eN)bq|g=j^kx z9hvl$b~|OAX&QPm5kEs~i$#g5w92QScIqi7pEUWzNfS>vzNLA>apT90jU0Q-n9)t6 z8jo%WA2ssG`cN>yNd6JNy4o7A=n;6gtNQS&;fEc1$iW8<<0{z$57>XdefO!@d#^qB z*nPKMciDNT9e3D%X!&;A4jDXX;5Gxw7^ZUlz_KAs8B@*B$GIlM45;p$F?iYX-kzCj rmsIgnvg1}vo4c;7DK>9@)xtTwOJ{ekoE2Hs-MzZ2zGryVAm)e-XZc)& literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/1.gif b/workflow/engine/js/processmap/core/images/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..fed801eaa8d429fd6c5245dee4a1d9e8e6a0a325 GIT binary patch literal 378 zcmZ?wbhEHblw=TRxXJ(m*REab=;&fCJCd1Qymsy8|NsAg|Nec?-b1fmy`C{^;nSy2 zOG<0coH?^}+4^bIX0)~S-oJl;^XBcxj~|~gbN;(`@0PAzd-T|u*>e`}*s<%zjoWLt zZk;-9-ppC^FI>3P-8=QehYw&&XhkUgWMO1yP+-sjSpf1A1KV_m2?ZWHQvD|yg-+^d zv7dcbEae-t+O6SXCPPAJ)ZwtrFX|j09!`8XVa4971xo}96VzTY&*3}~Z@|LGB3D^e z(<;Ov#~~xb*;<{@Dk{UCB+ipJ!M!$%k(Dh=lvQN5$6Q$<Ho<8Ul9dzZuro3Vujb+s t&5x+%=I4_a+SL|c%P7DrdTL`~>ydOPhEt+v(l1@TaO1-5JI;;_)&O*GfZPB8 literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/1t.gif b/workflow/engine/js/processmap/core/images/1t.gif new file mode 100644 index 0000000000000000000000000000000000000000..901e47cd2922220720ad8b99c55c9375879615f3 GIT binary patch literal 742 zcmZ?wbhEHblw^=(c*ejWP_SVAogdwOQ{&PLEjl+Z-?-!9!w1px4|7!=fB5;o^W?qf z?!8=g@M=y?ud91#&%zCImCN7%{D1!Cp9gQh1<c&P_412dyACW}w(j?@U+vRZ?tbv& z*okx5x#hVlkI!GY;=<!M&p&+AYFs;O*1|nc{$GFp|K!#C-@kv`e&F=t^?TND-7{tV z;pfkvdrjS&m0j}m>;E&)f2h~37A;v?S>2kl<Y@QIW%~~v?U*?K(8I3<CDrS9A1hmT z`rgNX|Ns9NE?Tr|)%vrq{~vz-KQSe1?TK4i%a6Z*|9;D%3)}B~@13^f%$YN5)^6Rp zeNV^i)#vWLzxMde_wWBz>ejw`_2%f&lar>*Iq>+`<rm-1U%R{e`pfyt)|ZqwR@QcA zuRRCU)W2fq-n~b&i>psQ`?2}N4WM-lGy{r1Ss2+F5*c(rHh|)Uf&G6&VpDTVB1d~` zXIHa)JBNJt#3p&$KHCYCI{RjK%<P#uhhzG@#3@#SbM#~vPnu$^C%B?rAyi@YjIJrN z8#b;G)Kt<Gc3#se&#+$al&Y^DtDNZ}PFaQ>lWmQyPwA-|g<A%hT5#SrzS?tw^VKVL z(;z-+84K>$D#nYCv#VJD`J)kSw<zX=!XY>NI_Fh_4Idvp;L~!~NqCTWD0Z6C?;oBG z4hlXTT>2gzDv7G6x#WbyuVgqTKM@yGWNS@OOjME3RPzxqY+UFzN!wKQfR4%MWBu|b zQ$84MNNVMjv&-<9;GmecNPw$PFO!kAxv^86En?=P1FIIzl*+T=C=%*q;B#`W<C)6h zd{9Iorl8`$q=ij_tOg#oiH1xaU2Htdd=fvlOj)4L#nf|w;Yoh-@qW=B2|<U0sb^+d T*R%b#IF@m#Nu+{{g~1vCRiRDr literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/2.gif b/workflow/engine/js/processmap/core/images/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..7177322e7de963ebe679d4f17e51384f199cf773 GIT binary patch literal 187 zcmZ?wbhEHblw=TR*vtR|`=9<|Ejx1e<DUy}en0*C_r%NJ?|%Hd_x=BscYn^j`u*+q zza!6oefaPJtd>FXCkrDx122OPhzl}<fhA+ZNzc`LBQnmc7K{Dfo9H%8Y(ouqL(r>D zr{3OXa9{U2uk-x@=YD1liT)Fh4W{NOO&30p;I%etc|hlvQ?e<GJ2zD5{5!<)V#}<A nbqpdOD)!7Zy78Xv7wdr+-@i&QFg7>1Ft*Ben05CEGFSrud8JzJ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/2t.gif b/workflow/engine/js/processmap/core/images/2t.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cfadfb73179649bbc5453d5787deaa67efbb198 GIT binary patch literal 13385 zcmeI3YgiOj9ES(vx=2y5TvTKjK$6&<*<}TG+l355q%dyft=q6WzyiCo%?|EDYFL?> zMFCQh*9Zkvykv!@Tnr6Ok*ts+BoLI+3i1+=+B6FY=m&ew2fv+p_Srpq=KY_`dwyTf zoVn3qa?%s=M2;Xx-w=2H8rOa0X2)f&wU2AM#5G;Kak6)?p_e;;Ven87SJO3E-7&Dc zeQ?RH6S~UAjPgcJ+0n(D8{$jqVvB1ci)zAF?+aW}<+r>lVEK;eIpsojs|!==Y}kS< zT*+~q59hcbE*^~{S(5)%MwktxI+J426e>-tS7Chz>o8QSQDO6E#Sw9aNGe?$lgm&^ zx$~0MxtVIY28#$6D9sA9&Y+`M5;g0x^hSkQg^?OMg;MZsOE-?8!w8$H!e(1upq4o! zX@){&Vu?si1j|rah*%mbm4}7|p-Ci*#*%te8j4B@g8z~#f<yTaI{IMY0=}hWG^vWj zsOZr-`F|=bon;LQ95<OvVpFh~X3}tpTrS56DK3?YctT{%(X*skq&NDG403CnD9Wg2 zv<6m7>ru<NWD1?lsxZtl(bzM(InppTk=`gC-l$kj>u@t^z$Ib=9~+r3RPvpQNQNR= znn|YVtniWTM{60%L^GL2G%_hzX{o#o8lQE%p5l*)3b*(W5fTw0OXjUe2t}}D(S-UD z=#KI@TBA+PnNThlNu-u?nM6UzN6RNbqvcB6B4UD=Ve6JX-O>Ml!ZhkJUxsWZYxr0+ zYMjcVbd;Vo^3Ei;JJYBYsWhV_*>J6nOr!8LZK@I<@4V~!Mpn(of{!IWmdjg9A3Mr> z(ir!CPlg{E6ixyp7wUq#fD8b^FkMg=kO3eVrVHu<G5`d_bU|G}27q9gE~pF001yn* z1$6-#0D@t<pe`T-Krl=f)CFV!2!`o`x_}G-!7yD=7mxuU7^VyA0x|#u!*oGiKn8$d zm@cRb$N&%w(*<<_832M|x}Yu~13)lL7t{r000@TZg1UeV0KqU_P#2H^AQ+|#>H;zV z1m87Xg7KRkl%BudVdC#`SaJW}ym9@Xp}~Q_uU)-z`LF)IKmYjs(#79??Y(fmr~6!2 z=Pw;++kbBR>BrVHEkAt!-RW<ePc@x9@y+pLjb9%<((u*c`nuYhLkGV+u)q3?&p+Gu z>E1oNcUA4&vAwdQeB0KtPf9=DvU$_S4eLKDS@+=w#cPWS3*LV(|J`@iyuJFZRd23* z<Mr28<h{Cl+0s{XbIhhC*{qRy*+A=cS(zEy^t4n;qfQ}TdhvzlpIf|W;ez?kK9ii3 zm=OQ;ytt>HjGY@ZC;Ew~$j4_t77?yeA_{p}Xvi#Cuv9|eVo}f|fioWtnBni|i}|45 z)4irmo#N@??k03~dFVms2kv*8>?m-sx3jgezHgEhg7^$sTiGGrND#t5mJ2wD&4JE< z{GQ&8)b_&i>RP{6roXKt-K#sGYRxn|#N9lYu^|Q_loG4x9`(>wrPZWkl9mM9+Rpxg z(+U0#=VW1tGqP>^_b(NrQTbjDWPRUtZkaRX=4qF=D$jO`o431*opnKB(b@tBS9f1` zSKH!E1-9$_*E`y5E3c?<DVgamtlVScDBKxXwzs^L@DvK{>+0<%3q2z|Tx$;tTs<N% g51~_iL({3|8iA9r<xFc^``PBHon4qv;e$N-A3MFx3IG5A literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/3.gif b/workflow/engine/js/processmap/core/images/3.gif new file mode 100644 index 0000000000000000000000000000000000000000..3a81652b9a100a832f689f548034005c899478eb GIT binary patch literal 90 zcmZ?wbhEHblw=TRn8?7uT6V<P*!aVT4-5<pia%Kx*%_D^bbxFIkURsE_LTmWr{D4~ t4q0$6^q}j`{L7j08NKZmtglXOduF}OXgBMI#QT<e?*HTGG2>#e1^}%x9^C){ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/3t.gif b/workflow/engine/js/processmap/core/images/3t.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d3f2258e3c14e90db658d38e73531c0ce0a6108 GIT binary patch literal 13456 zcmeI3dstIt9LJA^T!x}3a*?TrgBs$tvzvphZODcQB&aY&EyKfhHYVH7JUg@jmgYSY zG!%#kuft3wEz43wydil_3pGmZW_F=6%PyKlXMh9!!=AV2@xS-op6%@2=l5Pd@Auz# zVrp`{oQOaokn;%A(a~}4+RZ~(ZXCXH!?NR|ss0kVt!-9a+tdvgr`MiItG$p}b!<}A z32k+2+S(TRnzIvDAJMEjnp)Z@TXjlPdN5;Ied3C}!X*brE;}w;v}gSMEwRPBqY8FP z=hbkn?hso&*Ss!9zcNx^!JS<alv5R)y*zZ<LS*Jr|IFe+lU=?U3w)Dlb`8k?ZBZS8 zGt#G^Nd!Z%-^v7+ozUl#44O-t%r+Hvy`c$1%?1^gJuY3CZr74|=9D6u%qq&z>5KC9 zas!s2<|thXm(^}183J`#EjEY3rNRgUl}jqvXHPedp`8emufh^Nf1sW@wG>UFQh|uC z7fPh4R3;F|iRE!J9-2ikXc}Qd#c`-uC}cmx3P~LMM!OrP=CDsn+F(><CM9>z$^KGd zc?@G$;JDN26gVXUiZ<aQxm=D5#kg3^X9>Qe(8drhzReNcHOSp@l1PW1Hrp99WkWsV z61h|Xqrx!HMBdiDIl}Ip$mS4qZd9PBthkG?<063&_m0dKD%nnjmL>^?qIDEyQFm=W z*-Vp8iq3bS+AN9EQ+W^6Giy&h$sQ4@_W0lnMSP)D$665y6%x^`UiDqjedXzt!E7w- zRW9d?#5%D^A&yrFrQPMdpzd-d?h(;TOs93vp6=`aFJT6~*O$G3wsangL64Ib(n{JG z2kT69uQP*QVWem)!Klqv!bIXGvr&onbUtu>U8`ne!NwBz=JM{+y+`>_9(ue#l;OJu zg_8iug}R_FAOk=!Oc&GzWB>?;>4Lg|3;@9}T~HU00U#Kr3+e(g00hHyL0v!wfMA#| zs0+vd5De1=bpaUwf?>L#E+7LyFiaQJ1!MpShUtR3fD8b^FkMg=kO3eVrVHu<G5`d_ zbU|G}27q9gE~pF001yn*1$6-#0D@t<pe`T-Krl=f)CFV!2!`o`x_}G-!4FIqr{|^z zX=AT<IN5s~eLDX6`_5mtZ~ghl@4wyr^_LqzU;pXHAKJhF?%Qv!eSP(-FTeQwvn!V` zefmk;#}_Z0Z~f@Qb7wy|bNbZD6UX0gIo5pi$l*f=n+`PYZ`il@y?6J#^Y-qy-rTkG zjrtwix4pjgwJmk-&6_rESii3J)tXnTU#_aGSi7eDrPZs-N>{#E^1_Pc%a$%#yy*Fb z3!Zy+esNKu%lS+J<Dlo+DVx=jKi8aRGLi;;E-@$P>Df;`Icw&O?CH~VS(#I(OwLH3 z^h8=}%EaUeNm@<f_yn~|i74dpak6nziC84W1$^Gv*fBAWjUF{J8jC_l3?Igg92yZG z7CIzk@Sxy<1A_YZ3*-d&`}y|udGwJ!2oiP6r;i`PV_$6ZT<}4BH;k{erx<F>n%(6t zC4YVMXk9?~48POub7Fm@O*yu(JN;L*TtyJOvG8QO?6$jdaO2!PjSUwP2K4pgEMCI# zU+%wjasL6~8egA)pn+>Ef~qR2Ln64E!C~Ctn>M@aHlf(a;_cRji%NEttSsZLF0T&i zw{Ot?>VY-2y!9LFB14BpMPsOY>$a@GA<;WD!NW$i@*+o%ZR3u)+&UsAw#}4?JpL~> C>A|7^ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/4.gif b/workflow/engine/js/processmap/core/images/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..fa61127ae963c33c971bde4d855aa18dc927bdc9 GIT binary patch literal 189 zcmZ?wbhEHblw=TR*vtR|`=9<|Ejx1e<DUy}en0*C_r%NJ?|%Hd_x=BscYn^j`u*+q zza!6oefaPJtd>FXCkrD3122OPhzl}<fhB9hNzc`LBQnmc7K{Dfo9H%8Y(ouqL(r>D zr{3OXa9{U2uk-x@=YD1liT)Fh4N7G!r-~m)@LC(S{B&o@E1AH}8(J!S<eIe^nySvK n%?a+>5%aH4>RpAiEOWw-ztt{`&5g1QjID~DW<9;Uf(+IGyChfg literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/4t.gif b/workflow/engine/js/processmap/core/images/4t.gif new file mode 100644 index 0000000000000000000000000000000000000000..5850efefa67775f3c640f95fcd519b104479c29f GIT binary patch literal 13545 zcmeI3SyU5O9ET?hP;dnoL=lGp6@_Fn0fmeSVgm@YSQT1vY3q;-5J@uQWNZR$ako;f zwIYhvB4Sh&cigIiTBKmbjaFL~ySY$Xw^nPxF6jgi&<A^N&++Zf$w_YReE++A_xE~7 z$HzvfC?CWJIgcQB8XY$tI<DS#T)F4CaMyA6w&T>zziJyAD;peVuiiR-t?BSJN7<Fe z9rca;_FA^I#=N;YqvS;D`l`umE61;{9k=>u%!<<q`Q`C>RocArsKv)d<Q|F0EeoD^ zZ0PK5c+Q@{oNa@1O8v4n1@R^Q_+8%o`T%or53aa7TZB$4^hwR@KD7XuIN#xLAph&} zcXUcg9E(O%JSF_9N7`6Qmr3(zDxGdHYp}bAj$o)kufZk^OH?GXS~|lJm(9^h*<+G* z*_k?(9vd0yp|+7W6KkS*3bmPxW(#T4V3eLorAeXf?8Y&)8R0WE*eK@<)H$b?;b=5W zPRMkM&@eP?xLg^oRD}-@L6ayRO`y!EG8|PZ6vCI13=J1PXzPPTdI&8wr%xltN5{6# zDg4u589dLDIBvCC<<?L+!=>YdN~OXTN?fUw353j&W#%cH%xnp08RYRe(X>U!8Cc%H zm{I4rR4Oxr*I<})qPC}Xa}?V)k=Y_|-l$y1m~b1#;)Gm*w~Z_ms)bHc%h43iaLEi~ zjBMF{tbwDg43}v^wMn6BXXO)6`>gHtv~Wapq|=8?LC6$g$$}L^L532OI@Gs7Pn9P! zdP7=PhjNvSP$nx0GK?S<!&=KbK&|C!+$o}im}cwFJw4U`U&8ddHec)v&e(h`dL2$1 zX%lVcErK)RNoRT;nZ|G?ijOpysB{`nH>9cY_ReRnuVvLjEQDC%ZMl5B^tPjXE{%5Y z&t>?QLE$7oa-lA$3&;Qv4ATX50T}>-VY;9$AOk=!Oc&GzWB>?;>4Lg|3;@9}T~HU0 z0U#Kr3+e(g00hHyL0v!wfMA#|s0+vd5De1=bpaUwf?>L#E+7LyFiaQJ1!MpShUtR3 zfD8b^FkMg=kO3eVrVHu<G5`d_bU|G}27q9gE~pF001yn*1$6-#0D@t<pe`T-K=3ou z<<WlAgEkA-JFLPz4w2)ZzyJF4QB&g|4}X7f|F>W7-Mw@B)-ONb{Hfu_^=nsu{NelW zzP(a^`O?L2zP@n&t1s)$ojr5<RPD(xPSjL?UUj_kvtvh(RFoe+bnw#y`}ghLQ?`58 z&K=vgZ7tohxn$GE4fgfL>x$MEezNA{)vF3tuE<}Wx9p>(A1?V|@uK&07rwV({=B(! zX3v_L^X@xuXJ^^0Z_VH>+;o;Pn~a&$3>oQZv|g7=O?~r?*QZRLG%;nuYp*6JjUPAm zl`)AgzmyOkH##;ZTKnRtsF9HxHA1Q)!iNtF3sn*dTrLX<9y%mw@SuT#0hm8Jz^}h= zzrH?wynFZR*~81Td$+D#I(PDLf5FYwMJf@C5X8SpDsn?)NQm<)jq`#J;@Wg{1siAF zwWP|<6-4azI$5Ha&J`Bb*)5A|m8DZIoWER5BK3$qWJ7`&c|dfv?aa?zCK;1{P9*L& zFeN70bLK)`+|`;i*h?bn-Lp^Mek)fF2o#AtgXXyhd5Z1*2LucnvSrKAV7t^yx2}g& zBC*@o96TW2Cn<FI^>?e-f4I85!Ugk{`So&>?yab<+UMr&r}gu8t;@?VSQS|3dNJmV zhje2}>DFMWYp+Z3^)4=TO^>7=4GGB2JMO+IQ~hQIAvl^+!}`xPx|Pj3u(Qa2j*EBH pQcp1^ku2z}%&4y+D(AR#iCz|1M_jMT*G4V3xm)5~@lgme;$I$6@ZbOd literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/5.gif b/workflow/engine/js/processmap/core/images/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6830ef3a27371be3b8f6b38c3c8aa972392cd73 GIT binary patch literal 85 zcmZ?wbhEHblw=TRn8?6jY;64h|NjpkJ}@vaDE?$&WM^Pv&;ha;K=KSsYE$}Go_@=} oc+Qq6_D%PGhw(`$h;ls*ofr0MX42^@!(ZFJ^*-Mf%D`X^0Cck+mH+?% literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/5t.gif b/workflow/engine/js/processmap/core/images/5t.gif new file mode 100644 index 0000000000000000000000000000000000000000..a98a2243c622a75fd0444f745977a9a0061120e5 GIT binary patch literal 374 zcmZ?wbhEHblw^=(SZc+<5R}W)xtXDI5ktW=i}{D7V~aIs9Z+pu#*o}1TRcIeVTr|x za~k~{jb`nUEa)@sUM`Z=CfmQ&e)%be^e%?zDyg<rY!&mQC+{&?cvPW#o&4-0!u5-V z^7}-qW_ztWFPT`$5MH7&Wv5)#Osmxw7_$2q;_F@3oRe%`W-#xt&YVM5i;qc^Op@$b z%aA=qbK+*DN!z9Ky7($)bH-F~M-)nAw=q<&m93a&*}Y6Mt-)&Twf`7E@h1x-7lS>6 z4g(N?{KUXE`M~@F50O<}CsaPI$kCg7A!DPNgpWXki{|O4ejZGTPYMLqp6iQDnrpH9 zyjirH#itn|D{Q)!z54x8LqbAJP0h)wqqD2Kr=z`hLa$RuSd6NPiIswgNNjwfeR67E z<_s%~71?=(#rCD;Rn^O8@YXf9wE1l|3G&>%*JJ+ymqUk-1^OI!IeE(M?CJB)XU<+e Mb@ljlS4ReG0Qp{|CIA2c literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/6.gif b/workflow/engine/js/processmap/core/images/6.gif new file mode 100644 index 0000000000000000000000000000000000000000..2d5becdd41c4a65952ec3dbbd65f25ff6e69eb32 GIT binary patch literal 1057 zcmeHG+fR}K9Q`aqQD+aCwrb9_xmG@qtui&tODZ)>&2Gy%t94lqO-mepITFN)Waw8A z-cT1Q0haLLt&5T%id4=Fyl>$RZ<IHZZu6J?4ZU_=&(1m9IXf|w=%6E)y$~<NhS&iB zNSYQ&*CJFMlBpx09|&1`C-l8jRyQ%L%LVOnMZ3ZThI7vbJ<&Jb*^Mcp-g~&g7p;vg z!g(qqUu8I$D?ZAWQHm6Cm^|UJB2%iNO4Wh%%ELL85&0tW{nCp9JRjGPQ2u_DA50en zp%|G}6+|lzqw|uAo}I^PuU9CjHO+TL4Yb<k0;Psb=S8r}V)DwO8T>c~mckcb5j?*t z5ToKoUbDL7O=n`E@DfLGTPQ1k+j*8NJd@A6z<F{<SesE%!+Ft|QC_L~)JLzb*7Wu9 zUe>XzN=s$J`Zk<f&gBaqN|lxG)OCG5b)6cCUR46NAya>Y@x2UIhhQFuZ*5?f!d&z0 za1&UE;D;HeWH7CS`L>RRM=-DYF{^{Ir(hDnRQ+gY2}~)#jKj=pm~Dlx-8PHSX6c6^ z0SpV4dN43amPc@yZnX^5gQa`TqKBnH+v0@PPSwLW4iic+x5DDUpOs1YjDZ1z{&nqB z7?r>mIhYh+!k3MbC4&UUTVP^6MF$H5urRo0o%+2zY2WTY{-J?gKOG$qgpUN+J?x)A zoY#<j#GSG7>h@gcEqjx7X$;LKx6NeMwsarnMmKMNQhb7s;|3Q`4_dE+>E!25aK0(m zbU3=Y9$?1@5(`<*Ji<~q&WMO`3pQnAyZ1cU8jh`I7p#n{+ug&glZ>dwTgJoJ)6z(6 z^~oJEsTvN|VAkg|Nsn0J9ZfGrnv%IKKCzJxcSh1y=01jq^={1FzdU@STI6HuycwPk zO++k<EcQFe&GtXx&h%s6q;$Me-sqwCTiFS6t;Zn_`QAB$wt$cudMcH&67${n7*)qY ym~w(g$fZ$7G~-6$w$Rgw0m)-miCd$uZKqtml6ze18<~_-yo(jvwcy}@g!~2Y)}Xoo literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/7.gif b/workflow/engine/js/processmap/core/images/7.gif new file mode 100644 index 0000000000000000000000000000000000000000..9162f995584e3d1e9f0d66005e57353c109ec7d6 GIT binary patch literal 616 zcmZ?wbhEHb6lV};I9AM%mX@~X<oeRvY1P%$na8=V+&VY)LDS;p^Gm1ZUH`P_^|$-` zUe9lxS(`r9YW1CI&G(Aa%0rj#nQ-LVrg;~7@-HMk`g;EKyOp^mSqnDySM9YZ+@t>f z%j-Qi=P!BOzIo@G)#oO)bk|mH%fI{OSk+~v-UrpiwRzQdvR=G?_Vmm3^z7u#FXv2H zQoHHE(qr$|wsbb^-MhDNu|r;M;+NlVX3m`X;NiXElX6Sf&MPR(y!c^LLrYD|w4#ct zvdqee&KXt3b3M=8+57eD*Y-8lTdpoxw|&{3r&B9#WVhVQ-urrKR&GYaRqb03uGDOD zEpN)7_P9CkJm2PBYkK;+W~^#0s7om=Eq(apUiK8HjFQ;$^I45YZNL8bSaYzT<f6o) zEfcfa{FgoJS@nF%tFQOdvXT#6Sifz@mgbhGmMPT_Ufif}t(?1P=Hb`#w;o@z>gLp= z_qNWt)>F1$fB)0DZP!gJT60TUQ~nbN6o0ZXaxv61=r8~QC{7sIk2cgdHMg|3wKwY< zGczz7>vy!8qy!jEn{JenVluHln4N3kqD2|O6CIp2R;^y6Vdl`T&Y-kq>$a^7>TPlg zocs14*q`p-rVwLs;^e855(;e$r!SsjIDhHdl~x6bYo}w*wQkz}Xv@xacF`9vU%h1S za4=i@(Ro8haK_>v?91jlB&Q^YYzmNMPUYF_*Cb+C#KNh#kT+;r0^@?T=EIKmM~*Z+ tWNVNx6leYGanRYhS5GsjMP$mNE@5@vpg$3sm%66TG%<YCBf`O84FL9=R}TOH literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/arrowB.gif b/workflow/engine/js/processmap/core/images/arrowB.gif new file mode 100644 index 0000000000000000000000000000000000000000..df4833955daf3c2ce6ae2ab53694d63261683a73 GIT binary patch literal 13123 zcmeI3SC|u37=~vN#a%?Pcby$9sGCelcEgNGR?NDvXb{;5h;?@6Bs(UV8E0lqc5SGj zqBOf$u=m~zD%gAP1r>Y8uGqqvO-L3l;Q24O`{&7%oSb?8Q{MC4o-rNmqhz(7sb{7! z43nN;DwP^bL#HGsux+ZR(%)!n(N?uA@z^esG0YgZY~dn~HS`!axj88$?F8vI#`Za+ zvu}J#>&t4g&b7uHqD7^cxAVkP*<wCtx=Jy|sk+rg6x#N?d5-Nzyljjc?Z06CITMyc z*l<t`XhJB=hFgMCM3N&dO>C#?vEx*el_IPp2=q%*LJ|65D-RcMpslE*r<I9q?Ugy{ zzZlo;dA7pyg+d`%2n8)C!;7*k^Mb@nQh*Wxx7YO4V!(7qlm}TkP8)GG$FM!aGFg9I zwae=9VjSmBRDCL&Q|;<RrW@?vXi&5Ad{MP|F(~lWk!fL+b}9*nsGjAdEGri;Z@=Ae zNWpTlE}Q5KMg7WEpxUgpdP0wg#C;zDK@14t6tyA>N=TeKpuP;PR-UwUBi%coTn>m* zN)nW?q%_Nw@&Qn#Jj(kb28ijm?(b=}{<R6ywW=?>$I0~{i>~n`NAkq<T<T0*)tRm- zY0Js0Ufjs58Nz3bbd;}ku5o?kRnu6|Sn}0eu3UQcDA!4&=6#(EUmg@E0m(&Os0(BO z1Y^2T7svnz#&n@BkO2^k=|Wu~10WdFg}OinKrp5Yb%6|kU`!Y40vQ0om@d=>G5~@x zU8oCW00d*YP#4Gm2*z}wE|38bjOjvMAOj#6(}lV~20$>T3w41EfM84)>H--6!I&=8 z1u_7FF<qz&WB>$Xx=<I$00_o(p)QaC5WL28HPmi;5R+c-DA0Qxb*2CR`}d!}m;d$W zAHV<h>n}h5wCu+pzW?sqZ@&KO%P&6v?9-*6eEiXp4?lSSy?5Vv`>i+Mc>T3kUwQeZ z7hib(xo4kw`l%<Mc>J-&iynRC;e`)9_`v=5-Fwg7cinl%?YG@}%gs04c*FJAU3<;d zS6z9<<qIym^pcC`Uv%LG=bv}(IcLwCJ7@N+v(B7(#_6Zcn11RhCr>-+#1oD`uCKRP zIJU=gonvgv%;&O48{L^S(X}r1s3VU!{IEl(9x`R}q=QqP6Azkj;P~VL`;Y4wJEncV zw#2@p_i2sCqKqPsinKI`Ly{=)!9deqd+srE_uY2gWdzsA?!42EJ8Zw*w%csI)s|aq zzS*Y3H`#dDMnfCwHypCT`h(XSRL3xl%LmsDVd|JBdOL<*lBs8yLBnRv?OnWN>4KRZ LlV-RhnY~v4M2bn? literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/bg_pm.gif b/workflow/engine/js/processmap/core/images/bg_pm.gif new file mode 100644 index 0000000000000000000000000000000000000000..e68feb6a7d52804b5e83fe59835a4720a8e5be96 GIT binary patch literal 13253 zcmeI3dvw!O9LKXUMLHBwQJ4?1fH-k&+O%EQkaj@JfJqVQgjrw9(zFY0lbU9<8{msg zH&6jZM8K&i$kh4T(6K2fGDVpn3ckhRrZ^@bh{{x`$y(Zh=is@2@ZZhpX>V^nzx(*y z@4t8A<osMSO(7Jr1VN(FXj^-C+n#-LBQu&_<d}xqX^ED9sk}&#W_+xKmatxqw_t}_ zHeo2|wqP@j4y_|-V@tV76(Z}bm|DnG_!zSr%d@Je2pI_k1FS@&k$|5Mkr4|<yM+># zl-o)-j-kDX<g;MolozNnr%e!9)S%I+8Li%c8gev*i7=aTvQZ~3p#?OL5+;<;YUMA2 z)SKiF8h<dWN^Vi2+e1#b=f~%i|5>n7NeYrU9u9{!VZBBWy|~V7Hse|XCkVAns6*wv zL`T$oXhdv~ljGRg5F>Iyi4%BK8J8{*$|MVhDHA20_~z(fVj@1I>D{P?5dwIG4&pkE z7Eg>U7gBO3X%ksm62wA5@LOZs&*wxoEQr1kYIEu-rScRgIcu_>m5+$EDn8U&vsy<K z5?azokOsZ0PkjtJt=u8FIZye2%5|i{Na}R)@;*?!oWd0meZ=%ySN3#T|NjYdGYMb8 zGST0AEN%v8{cM2crI74Qcd9ctLwW=;KucCGKzmu-%Xug~*?GqG#a1oHLXIV#$mPkU zCyw&0G?L!W%J8v4;UqwEp)RNk$N&%w(*<<_832M|x}Yu~13)lL7t{r000@TZg1UeV z0KqU_P#2H^AQ+|#>H;zV1jBSeT|fqaV3;nb3&;Qv4ATX50T}>-VY;9$AOk=!Oc&Gz zWB>?;>4Lg|3;@9}T~HU00U#Kr3+e(g00hHyL0v!wfMA#|s0+vd5De1=bpaUwf?>L# zE+7Ly@EOykO5XHfdHH%rSiZ-R5<PMJpTGa=IrirtzaRbW$l+fP9X#+$_x`S*_x<!^ zXU7kF+rQuQ-M8O-{neLWe7<|vXP@r;WXJZ8+qQl5;nok{Z{70V=6B!OwDIk?TADXB zz4^xa#)j8ld-au<>tA~Dg}QamuU+%pv#XzZ`l;F{SFK#}#PY|NJ+}1GN0uyJ^zcIu zE?iJk{lNWImGker_ny1&nm2b&MR_DVyG#m+cLoJM;P=hqO1&P|&6Lo^ciev4t+%*t zE}A*xrb6fR8>ihc)iLGzg2|I6=1;KO#*Z7DXSGlWY0fp}7!7(tr^Pku?CVBfn{~~o zt4EH&GST5zU3taj8N-HNcIl8yF1~2+g@Z0Qe_*<5z<K@8JtwVSY6^m6_N1lsNBSYz zi2Nv*WsuaG%0+eC4h*eb)!4eAp{04w!Kxuy%U0IZcCA?K-@nn5y-+&7x4YguH!pR2 z<(lD#Y09<KymnNVf5JTHz(!TmjP*`_S9hAewcyCkDfaZ;V`uNEpWo4GY;HTTx#8%T z?5aT>rj+XOxg)D9m#=HuvbDIV^H|mfgtOHZ4_n<cxV>jU#%Qv@H7mn~AY=XoNVt&o literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/bg_pm.png b/workflow/engine/js/processmap/core/images/bg_pm.png new file mode 100644 index 0000000000000000000000000000000000000000..d6eaa721cf6f40e0f3f24676f3b8c6d82fa343df GIT binary patch literal 47393 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 literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/bg_task.gif b/workflow/engine/js/processmap/core/images/bg_task.gif new file mode 100644 index 0000000000000000000000000000000000000000..0387e6d42e9666a4628be924dc7a951c2ff3c54d GIT binary patch literal 550 zcmZ?wbhEHbT+N`taFv09!6`+gXdy$=WaqxkX^RgrM79bQF4%bfo@V{Z*(*0_#guBL zG%)xSF~oFTdh#}G)^5eBWwUpkWKEe|xAC-L%UZ4cNwc>eWN^=72(0ADp2CneQ@mu+ z>@{1oGTQIF`e@s}nmcFi|NsAi_Rt6@{$ycfXHaC&0htf-69e1-0}~27bfo%EEGasf zV>SQ6iW0B2QR{E$Ts4-g*#BTdg^%9s^Dnkkoz0sp-@fRvVZ)90Klap}fB*Y`Lt|5O zOKXj^q@W9nh=NrAgo%?TPnkMx`iz;gX3v>BZyK+t3kT!;Wy@ErT(x>Guf$@uHJdhX z*}7%jhHblc@7X(Hhcm~<eMgQSTf6??;p1n{o;~1n=-lNidoL(nx_ayO>gzY}Ja{<! z-swlro=<%8;`NJHZ{9z6_u=!EPhY+t|MuhewUZa0{$aXxNqvKYb`zWMJf{^K6xG}K zl;fH-HZD@>5;IOZ6H%yqyhG03j7QT*@#G{{|3y42ik|M9ruV*5TQqp_egS!vD_b-e z4l_9`3374BdTm*8ak0l_t=LmrR$g8nuvjaVp}|>@TUIaQ?y0S-udh!y+$HP1ZOzTi d8JC+vCpdK9-d^zd)LifF>+bG$X<}fo1^}|T=4}7~ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/bg_task2.gif b/workflow/engine/js/processmap/core/images/bg_task2.gif new file mode 100644 index 0000000000000000000000000000000000000000..cae4d04e5e9314855afd36e2e7e17b2212cd8ed7 GIT binary patch literal 13952 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 literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/cancel.gif b/workflow/engine/js/processmap/core/images/cancel.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3e1fb73d5460a585d49818473e5ea8df27c5bfb GIT binary patch literal 612 zcmZ?wbhEHb<Y(Y#c*Xz%_a;xi&dGUzf#H&)<9tuAKOa6E3k*!~^uDR4_Tl{b!_Lk( zQc|KEon5?qHpRxCF*d%Wto%ex?SQWClU1wU)YYYiN7e*~97{~RA|-X%+WNGD!q>ZZ zUn(iZ1_WO9^!)$-f0nD;WdVVAGSWvqJf6&(_i@{{=c%b*m6WoBqP|_f{@BZFV{-B} zBcpRpPUmA|&jkkl(AIv*$Cnrwe8$o;BRt~k(W5V0ThFPh7khhO4hp<)Yj-{=>5h%f z>wWvSq^5a!`uzR={ho%#Qg5HAu!w89xep~JpD$njDnI|6m(x8So(KH=A9Zz)Yid@6 zh9`RkowG8$r>OXB%9N7~48=iFZ=0HcE(8a|zz~W*Ss2+F!WeWw)`Q}Nf&E}ZSW_6E zX<Hj#bC-*~L|>o1OIMhSjurci8CE)zn#B06RJgg>7je%PYvGqy5#eGKwz1>VXW{1) zv(nRZbyQH5QE=aFAZKjA!s5%rrl1hyt0#YycelKNfYv#AW@%k3IbI7VCqXlXgEG3o zN&?0loJ^8x3TBe#3T(DaoE#1&MlB%@N-hl(g+s$mEMPoxij`M+nvS8;!4pEN$|f-q pPg2;s_!Jx$-FTQ1)F)>+V@1zJ<>M;a3{E_n4#gfEu8j-~)&L+RwB`T+ literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/inicio.gif b/workflow/engine/js/processmap/core/images/inicio.gif new file mode 100644 index 0000000000000000000000000000000000000000..a7d6d0a1083402016922d60a0b5f60b8a1192a3b GIT binary patch literal 722 zcmZ?wbhEHblw*)%I9AM%mX@~X<oeRvY1P%$na8=V+&VY)LDS;p^Gm1ZUH`P_^|$-` zUe9lxS(`r9YW1CI&G(Aa%0rj#nQ-LVrg;~7@-HMk`g;EKyOp^mSqnDySM9YZ+@t>f z%j-Qi=P!BOzIo@G)#oO)bk|mH%fI{OSk+~v-UrpiwRzQdvR=G?_Vmm3^z7u#FXv2H zQoHHE(qr$|wsbb^-MhDNu|r;M;+NlVX3m`X;NiXElX6Sf&MPR(y!c^LLrYD|w4#ct zvdqee&KXt3b3M=8+57eD*Y-8lTdpoxw|&{3r&B9#WVhVQ-urrKR&GYaRqb03uGDOD zEpN)7_P9CkJm2PBYkK;+W~^#0s7om=Eq(apUiK8HjFQ;$^I45YZNL8bSaYzT<f6o) zEfcfa{FgoJS@nF%tFQOdvXT#6Sifz@mgbhGmMPT_Ufif}t(?1P=Hb`#w;o@z>gLp= z_qNWt)>F1$fB)0DZP!gJT60TUQ~nbN6o0ZXaxv61=r8~QC{7sI|25P%HMg|3wRf~Q z=o>RLFfbeIJ9KtBBnJm1heSq(B&P%?Pnp_ck`mx$w0g~I)|3>JrA;Qm>|8r`?%I(N zylJX~wX?>NqsNY!Sug2e*AqQ|;o>DxOZMUpb%q?JJ9qEhR}x}S?~qgAeDU(t>zC>N z9SSiPpTB(l_C-RWL;U;SzaAY7KcqeQ9UPiic;%QH858aGe(~8_9$xpzN<eM{;{=9v z$>wH{g=9|{u2nG+XK#4Bp>R#=M#WQJSDiMmUe?6CFYT|T>oSMcVO|T4T+)1TNyKQj zRc(_}mgGhIZYkR?lb0(O@&-*iaFEI2EZge#CqFzUIV#?8v_I0($(Y<C&0vsqbk5(; z%C1~;QroV)NHRYZvrBW8h2$NDqy77vUYRLeIB+WQNatFI0-l){_)l3eGcs5M07k2a AGynhq literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/loader_B.gif b/workflow/engine/js/processmap/core/images/loader_B.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0e6e9760bc04861cc4771e327f22ed7962e0858 GIT binary patch literal 4178 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 literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/mail.gif b/workflow/engine/js/processmap/core/images/mail.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ce887c85eb6277b8a68cc87a7f2c0b06baa8a7d GIT binary patch literal 597 zcmZ?wbhEHb<Y(Y#c*ekBWNLBl#)*~dS2VYFzIp#5J|*eE;X^ZL&I}9-zjyckpFh8R zgF<rKV|MJ`cJ$o2uiroQPVKI&uJ$i8aP{=hh;3cGWXYy&>z=-Nc=7V3sQB3YqLO3h z_c^$_6;~9mUB7YSlqubPeS7!syLS7^y{9*R{r(*p7e8m&wDsH8T)BR6`T8a2&R(o) zsQmu@+wn6;4j()A@#Fiz@UWgKQ~v+|zjgbTGiT0RzkcoMv*!m79O>?uzINTZ_U`T( z3#L4Ld@nj7Vfo^<r_LR}c=dcpWYq41TfMx33QJ4ZZrwV6@q+q>MxY4{LjfrMWMO1y z@L<pZITjQr4D6d4Jerz?otxV`JeW*f1v}fdrBzfoE!{g=nKhM7ICYFnq?$$S%y}72 zO;)i;$XR$W$ch;|DQihc=yK|-8^{Q%3GuL)Y8^A(VJ)DlprWK{tY>;c(M`<8#@1>+ zm#L+tv8AFJKZ}N>75^(12RAD=Gkq3uhZkJ>x?+0s%@mF8#a&W<BrImMk>n6m<G8rM ql~IXJNFn6FqD4%SDp_Y71den}WR`d65c&DgfmNAXZY2*3gEascD84`d literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/parar.gif b/workflow/engine/js/processmap/core/images/parar.gif new file mode 100644 index 0000000000000000000000000000000000000000..678e028c1adfb9b2db7172fff646f1ce11812ff9 GIT binary patch literal 383 zcmV-_0f7ETNk%w1VGjTg0M!5h2wIcD+Vh2xoN;k+W@cu#&*<Oa;-I3WdVz@Q^ZT!` zvCi7(;OzO!;PsW4nQU%v!qw=gz0&dZ`E+@G*5>!&>hXn$i>s`y>h1Bm#?y<IqV@Ux znw_A>+waih_I!MOgp8DKaB<Y(@5<EPrKqcxo~Opo+2!r^@b>(Tl$(HsirL%Ui;IiE z%-W8dr|<Fe+v)hm-Slj3aC38ee}90Xp`n+XpTgMgt-aR&|Nj60000000000000000 z00000A^8LW2LL$$EC2ui01p5U000J@z??8wV+{xcR&6-E&}It5Yeo9dF3rI~vgvj) zoB=jRBPCGiG}=MSaVDok0wAZ$D<O`Bbm{~AeSJ0-AtMZj0EmZ&CLshOFp&U~k&z1o zAuSY}0Gykf88Rv*9;E=LrKKq<DH9zH4FIsRun;mSITIQ;F}=RMAQM6^G9UrR$ORw| dE<-L8G8z#D5gG#%%}hB02r>jR2m(w&06QGgvey6r literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/proceso.gif b/workflow/engine/js/processmap/core/images/proceso.gif new file mode 100644 index 0000000000000000000000000000000000000000..30cc26d64caeee5c6ecf9e4a6579e34f6522771c GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGjTg0M!5hW@ct?i>Ifz$4hF7I*Hg{Y<P*c<;K+DQIO9kebi!{ z)?#RFs>b4Pj;>35tZ;sefRdzZY;M@-_eg%Tq`lX=#?ftWadCEfLxRAa#OsokmvyV* z#N6{vmE2f@tzCGNTWEE8l&)iy$a;yGwY9aw(cS6s_-k%)k({S#a(rxomb=H(b8~a9 zz|neqeO89IWNUI|bc1$_pp2HEo1UO@f|62giNMU*tH<Pafs9IowR3xWf|slR|Nj60 z00000A^8LW2LL?)EC2ui01p5U000Jwz@BgjC=QRv2#JLxvMf8AN#nAx07q77b&z;( zl?rnhX>mBS2<j}b94{2cDFTSFaFmO%KFUB&WIP!;Cq*F!1`k+!HHb1rDJmNQ5o8S; zDk+OFA__4J01Gh+A}~iVFC7RTA07xD9;QPD6Al;zxEKx-1xG~-AT|j$3&o2~3j-ic KO-08;K>#~2@tB(c literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/images/puntito.gif b/workflow/engine/js/processmap/core/images/puntito.gif new file mode 100644 index 0000000000000000000000000000000000000000..963161004593e48a11371e0495ec64f0b32e22ea GIT binary patch literal 994 zcmb_b&r8&C5S@)8BM?IiA_*i9l_u1b6>UT*?wW|DdkPA)nu8UE1W~7jf`}|ImtYQ& z8G%|*Vh|;izo5iHi0BWfgVHI2AnY=|`TPwHEZ?1-nK$pf`EIVY<-o!2EM@5rMHJJg zm>xxB#fYh?DaY?lo*sDO8v?)mzhELEQX-2@$e4+RSc#3;qbN)wBuZi=9=*z>LaL-j z>M?3eCS*!xWWki2$%S0W4YUI|pn-*9bbIWH5N2gIW{<VVL|Bx?SUgyusKTnO#_B-| zy(VnRW^4|Q7-biBWjA(g1#5tTG+2TbYFG?xKm!ZI9)coAsECPp=)+oMs-h<9Ar~xA zG!-*3hkB4guegevIOM?((8M(CfPRpGLa+uHNP{I>!2^qd4QOC_I2UE)2vhYi68f+f znVFiySI7km6xB@~KEi1j0A6T^(NGI3;Rk498g_sa1VbTM0}P}w30mNR#lQx%$BCjF zW#kCQ#b6}#VJ$LCFIo7S?j6N+!mv4AC3=(5;d=5eMw1<JgrqQ#66v@};t{|J8m|Mc z1oNN?t7=wOXNW4OKHlp1Pf*zh@^#huS3}b`%PM!)<}W>&y<Jh+*q<LCp1HG$d*?>R z&o<xR+H|I>weQ^g;F_bu^`m{yK0RzWJk$SnU};_(>%QB{z;fH;nro|0Z@)Uy{B+;I zsrs?K=er(t?AUYf@8#aY^N#VxuVbaU&X+CI<r~+RUUW=kKQ9$74DM=wv-{h-(&U4N z<CFVGkIgM~{%m?*oAKXmr7PXDxeeQ@stdn*KCa!oaO>iUzTCo=u9IKv`o!|$(2=|4 N?KfWkSj=ST&_5ffv=;yX literal 0 HcmV?d00001 diff --git a/workflow/engine/js/processmap/core/processUser.js b/workflow/engine/js/processmap/core/processUser.js new file mode 100644 index 000000000..04a02422f --- /dev/null +++ b/workflow/engine/js/processmap/core/processUser.js @@ -0,0 +1,23 @@ +var panel; +var panDel=function(uid) +{ + panel =new leimnud.module.panel(); + panel.options={ + size :{w:500,h:400}, + position:{x:50,y:30,center:true}, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:"processes_AssigProcessUser.php" + }); + r.callback=function(rpc) + { + panel.loader.hide(); + panel.addContent(rpc.xmlhttp.responseText); + }; + r.make(); +} diff --git a/workflow/engine/js/processmap/core/processes_Map.js b/workflow/engine/js/processmap/core/processes_Map.js new file mode 100644 index 000000000..05d356f0a --- /dev/null +++ b/workflow/engine/js/processmap/core/processes_Map.js @@ -0,0 +1,211 @@ +var bFunctionAlreadyAssigned = false; +var aTaskFlag = [false,false,false,false,false,false]; +var iLastTab = -1; +var oTaskData = {}; + +var re = /&/g; +var re2 = /@amp@/g; + +var saveDataTaskTemporal = function(iForm) +{ + oAux = getField('TAS_UID'); + + if (oAux) + { + switch (iLastTab) + { + case 1: + case '1': + oTaskData.TAS_TITLE = getField('TAS_TITLE').value.replace(re, "@amp@"); + oTaskData.TAS_DESCRIPTION = getField('TAS_DESCRIPTION').value.replace(re, "@amp@"); + oTaskData.TAS_START = (getField('TAS_START').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_PRIORITY_VARIABLE = getField('TAS_PRIORITY_VARIABLE').value; + break; + case 2: + case '2': + if (getField('TAS_ASSIGN_TYPE][SELF_SERVICE').checked) + { + oTaskData.TAS_ASSIGN_TYPE = 'SELF_SERVICE'; + } + if (getField('TAS_ASSIGN_TYPE][REPORT_TO').checked) + { + oTaskData.TAS_ASSIGN_TYPE = 'REPORT_TO'; + } + if (getField('TAS_ASSIGN_TYPE][BALANCED').checked) + { + oTaskData.TAS_ASSIGN_TYPE = 'BALANCED'; + } + if (getField('TAS_ASSIGN_TYPE][MANUAL').checked) + { + oTaskData.TAS_ASSIGN_TYPE = 'MANUAL'; + } + if (getField('TAS_ASSIGN_TYPE][EVALUATE').checked) + { + oTaskData.TAS_ASSIGN_TYPE = 'EVALUATE'; + } + oTaskData.TAS_ASSIGN_VARIABLE = getField('TAS_ASSIGN_VARIABLE').value; + break; + case 3: + case '3': + oTaskData.TAS_DURATION = getField('TAS_DURATION').value; + oTaskData.TAS_TIMEUNIT = getField('TAS_TIMEUNIT').value; + oTaskData.TAS_TYPE_DAY = getField('TAS_TYPE_DAY').value; + oTaskData.TAS_CALENDAR = getField('TAS_CALENDAR').value; + //oTaskData.TAS_TRANSFER_FLY = (getField('TAS_TRANSFER_FLY').checked ? 'TRUE' : 'FALSE'); + break; + case 4: + case '4': + break; + case 5: + case '5': + /*oTaskData.TAS_CAN_CANCEL = (getField('TAS_CAN_CANCEL').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_CAN_PAUSE = (getField('TAS_CAN_PAUSE').checked ? 'TRUE' : 'FALSE');*/ + oTaskData.TAS_TYPE = (getField('TAS_TYPE').checked ? 'ADHOC' : 'NORMAL'); + /*oTaskData.TAS_CAN_SEND_MESSAGE = (getField('TAS_CAN_SEND_MESSAGE').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_CAN_UPLOAD = (getField('TAS_CAN_UPLOAD').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_VIEW_UPLOAD = (getField('TAS_VIEW_UPLOAD').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_VIEW_ADDITIONAL_DOCUMENTATION = (getField('TAS_VIEW_ADDITIONAL_DOCUMENTATION').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_CAN_DELETE_DOCS = getField('TAS_CAN_DELETE_DOCS').value;*/ + break; + case 6: + case '6': + oTaskData.TAS_DEF_TITLE = getField('TAS_DEF_TITLE').value; + oTaskData.TAS_DEF_DESCRIPTION = getField('TAS_DEF_DESCRIPTION').value; + //oTaskData.TAS_DEF_PROC_CODE = getField('TAS_DEF_PROC_CODE').value; + //oTaskData.SEND_EMAIL = (getField('SEND_EMAIL').checked ? 'TRUE' : 'FALSE'); + //oTaskData.TAS_DEF_MESSAGE = getField('TAS_DEF_MESSAGE').value; + break; + case 7: + case '7': + oTaskData.SEND_EMAIL = (getField('SEND_EMAIL').checked ? 'TRUE' : 'FALSE'); + oTaskData.TAS_DEF_MESSAGE = getField('TAS_DEF_MESSAGE').value; + break; + } + } + else + { + oTaskData = {}; + } + iLastTab = iForm; +}; + +var saveTaskData = function(oForm, iForm, iType) +{ + iLastTab = iForm; + saveDataTaskTemporal(iForm); + oTaskData.TAS_UID = getField('TAS_UID').value; + /* while (oTaskData.TAS_TITLE.charAt(0)==' '){ + oTaskData.TAS_TITLE = oTaskData.TAS_TITLE.substring(1,oTaskData.TAS_TITLE.length) ; + } */ + oTaskData.TAS_TITLE=oTaskData.TAS_TITLE.trim(); + if(oTaskData.TAS_TITLE==''){ + alert(G_STRINGS.ID_REQ_TITLE ); + return false; + } + if(oTaskData.TAS_DEF_MESSAGE) + oTaskData.TAS_DEF_MESSAGE=oTaskData.TAS_DEF_MESSAGE.replace(re,"@amp@"); + var sParameters = 'function=saveTaskData'; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../tasks/tasks_Ajax', + async : false, + method: 'POST', + args : sParameters + '&oData=' + oTaskData.toJSONString() + }); + oRPC.make(); + if (oTaskData.TAS_TITLE) + { + Pm.data.db.task[getField('INDEX').value].label = Pm.data.db.task[getField('INDEX').value].object.elements.label.innerHTML = oTaskData.TAS_TITLE.replace(re2, "&"); + } + if (oTaskData.TAS_START) + { + oTaskData.TAS_START = (oTaskData.TAS_START == 'TRUE' ? true : false); + Pm.data.render.setTaskINI({task: oTaskData.TAS_UID, value: oTaskData.TAS_START}); + } + + Pm.tmp.propertiesPanel.remove(); +}; + +var showTriggers = function(sStep, sType) +{ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../steps/steps_Ajax', + async : false, + method: 'POST', + args : 'action=showTriggers&sProcess=' + Pm.options.uid + '&sStep=' + sStep + '&sType=' + sType + }); + + oRPC.make(); + + document.getElementById('triggersSpan_' + sStep + '_' + sType).innerHTML = oRPC.xmlhttp.responseText; + scs = oRPC.xmlhttp.responseText.extractScript(); + scs.evalScript(); + + var tri = document.getElementById('TRIG_'+sStep+'_'+sType); + if (tri) { + oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../steps/steps_Ajax', + async : false, + method: 'POST', + args : 'action=counterTriggers&sStep='+sStep+'&sType='+sType + }); + oRPC.make(); + aAux = oRPC.xmlhttp.responseText.split('|'); + tri.innerHTML=aAux[1]; + var tri = document.getElementById('TRIG_'+sStep); + if (tri) { + tri.innerHTML=aAux[0]; + } + } +}; + +var editTriggerCondition = function(sStep, sTrigger, sType) +{ + popupWindow('', '../steps/steps_Ajax?action=editTriggerCondition&sStep=' + sStep + '&sTrigger=' + sTrigger + '&sType=' + sType, 500, 220); +}; + +var upTrigger = function(sStep, sTrigger, sType, iPosition) +{ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../steps/steps_Ajax', + async : false, + method: 'POST', + args : 'action=upTrigger&sStep=' + sStep + '&sTrigger=' + sTrigger + '&sType=' + sType + '&iPosition=' + iPosition + }); + oRPC.make(); + showTriggers(sStep, sType); +}; + +var downTrigger = function(sStep, sTrigger, sType, iPosition) +{ + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../steps/steps_Ajax', + async : false, + method: 'POST', + args : 'action=downTrigger&sStep=' + sStep + '&sTrigger=' + sTrigger + '&sType=' + sType + '&iPosition=' + iPosition + }); + oRPC.make(); + showTriggers(sStep, sType); +}; + +var availableTriggers = function(sStep, sType) +{ + popupWindow('', '../steps/steps_Ajax?action=availableTriggers&sProcess=' + Pm.options.uid + '&sStep=' + sStep + '&sType=' + sType, 500, 250); +}; + +var ofToAssignTrigger = function(sStep, sTrigger, sType, iPosition) +{ + new leimnud.module.app.confirm().make({ + label:G_STRINGS.ID_MSG_CONFIRM_REMOVE_TRIGGER, + action:function() + { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../steps/steps_Ajax', + async : false, + method: 'POST', + args : 'action=ofToAssignTrigger&sStep=' + sStep + '&sTrigger=' + sTrigger + '&sType=' + sType + '&iPosition=' + iPosition + }); + oRPC.make(); + showTriggers(sStep, sType); + }.extend(this) + }); +}; \ No newline at end of file diff --git a/workflow/engine/js/processmap/core/processmap.js b/workflow/engine/js/processmap/core/processmap.js new file mode 100644 index 000000000..fea159e4a --- /dev/null +++ b/workflow/engine/js/processmap/core/processmap.js @@ -0,0 +1,2592 @@ +var PROCESSMAP_STEP_EDIT = false; +var PROCESSMAP_USER_EDIT = false; + +var processmapOutputsPanel; + +var processmap=function(){ + this.data={ + load:function() + { + //setTimeout(this.parent.closure({instance:this,method:this.data.render.base}),1000); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=load&data="+{uid:this.options.uid,mode:this.options.rw,ct:this.options.ct}.toJSONString() + }); + r.callback=this.data.render.base + r.make(); + }, + render:{ + buildingBlocks:{ + injector:function(lanzado) + { + Wx = (lanzado=='dynaforms' || lanzado=='triggers' || lanzado=='outputs' ) ?600 : 500; + Hx = 460; + + var bbk = { + dynaforms:1, + messages:1, + inputs:1, + outputs:1, + webbots:1 + }; + this.observers.menu.update(); + if(!this.panels.buildingBlocks) + { + this.panels.buildingBlocks=new leimnud.module.panel(); + this.panels.buildingBlocks.options={ + limit :true, + size :{w:Wx,h:Hx}, + position:{x:0,y:10,center:true}, + title :"", + theme :"processmaker", + //target :this.options.target, + statusBar:false, + //titleBar:false, + control :{drag:false,resize:false,close:true, drag:true}, + fx :{opacity:false,rolled:false,modal:true, drag:true} + }; + this.panels.buildingBlocks.make(); + this.panels.buildingBlocks.events={ + remove:function() + { + delete this.panels.buildingBlocks; + }.extend(this) + }; + //this.panels.buildingBlocks.elements.modal.onmouseup=this.panels.buildingBlocks.remove; + } + else + { + this.panels.buildingBlocks.clearContent(); + } + var bbk ={ + outputs:function(){ + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_OUTPUT_DOCUMENTS) + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=outputs&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this); + r.make(); + + processmapOutputsPanel = panel; + }.extend(this), + inputs:function() + { + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_INPUT_DOCUMENTS); + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=inputs&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this); + r.make(); + }.extend(this), + triggers:function(){ + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_TRIGGERS); + panel.clearContent(); + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=triggers&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this); + r.make(); + }.extend(this), + messages:function(){ + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_MESSAGES); + panel.clearContent(); + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=messages&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this); + r.make(); + }.extend(this), + reportTables:function(){ + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_REPORT_TABLES); + panel.clearContent(); + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=reportTables&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this); + r.make(); + }.extend(this), + dynaforms:function(){ + var panel = this.panels.buildingBlocks; + panel.addContentTitle(G_STRINGS.ID_PROCESSMAP_DYNAFORMS); + panel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=dynaforms&data="+{pro_uid:this.options.uid}.toJSONString() + }); + r.callback=function(rpc){ + panel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + this.buildLoading=false; + }.extend(this) + r.make(); + }.extend(this) + }; + bbk[lanzado](); + }, + panel:function() + { + /* Toolbar Begin */ + var panel; + panel = this.panels.toolbar=new leimnud.module.panel(); + this.panels.toolbar.options={ + limit :true, + size :{w:230,h:31}, + position:{x:this.options.target.clientWidth-242,y:4}, + title :"", + theme :"processmaker", + target :this.options.target, + //limit :true, + titleBar:false, + statusBar:false, + elementToDrag:"content", + cursorToDrag:"default", + control :{drag:true,resize:false}, + fx :{opacity:true,shadow:false} + }; + panel.setStyle={ + containerWindow:{border:"1px solid buttonshadow"}, + frontend:{backgroundColor:"buttonface"}, + content:{border:"1px solid transparent",backgroundColor:"transparent",margin:0,overflow:"hidden",padding:1} + }; + this.panels.toolbar.make(); + var div = document.createElement("div"); + this.parent.dom.setStyle(div,{ + textAlign:"center" + }); + var dr1 = document.createElement("img"); + dr1.src = this.options.images_dir+"0.gif"; + dr1.title = G_STRINGS.ID_PROCESSMAP_SEQUENTIAL; + div.appendChild(dr1); + //dr1.style.marginTop=7; + //div.appendChild(document.createElement("p")); + var dr2 = document.createElement("img"); + //dr2.style.marginTop=7; + dr2.src = this.options.images_dir+"1.gif"; + dr2.title = G_STRINGS.ID_PROCESSMAP_SELECTION; + + div.appendChild(dr2); + //div.appendChild(document.createElement("p")); + var dr3 = document.createElement("img"); + dr3.src = this.options.images_dir+"2.gif"; + dr3.title = G_STRINGS.ID_PROCESSMAP_EVALUATION; + //dr3.style.marginTop=7; + div.appendChild(dr3); + //div.appendChild(document.createElement("p")); + var dr4 = document.createElement("img"); + dr4.src = this.options.images_dir+"3.gif"; + dr4.title = G_STRINGS.ID_PROCESSMAP_PARALLEL_FORK; + //dr4.style.marginTop=7; + div.appendChild(dr4); + //div.appendChild(document.createElement("p")); + var dr5 = document.createElement("img"); + dr5.src = this.options.images_dir+"4.gif"; + dr5.title = G_STRINGS.ID_PROCESSMAP_PARALLEL_EVALUATION_FORK; + //dr5.style.marginTop=7; + div.appendChild(dr5); + + var dr6 = document.createElement("img"); + dr6.src = this.options.images_dir+"5.gif"; + dr6.title = G_STRINGS.ID_PROCESSMAP_PARALLEL_JOIN; + div.appendChild(dr6); + + var fin = document.createElement("img"); + fin.src = this.options.images_dir+"6.gif"; + fin.title = G_STRINGS.ID_END_OF_PROCESS; + div.appendChild(fin); + + var ini = document.createElement("img"); + ini.src = this.options.images_dir+"7.gif"; + ini.title = "Starting task"; + div.appendChild(ini); + + + [dr1,dr2,dr3,dr4,dr5,dr6,fin,ini].map(function(el){ + el.className ="processmap_toolbarItem___"+this.options.theme + }.extend(this)); + this.dragables.derivation = new this.parent.module.drag({ + elements:[dr1,dr2,dr3,dr4,dr5,dr6,fin,ini], + fx:{ + type : "clone", + target : this.panels.editor.elements.content, + zIndex : 11 + } + }); + this.dragables.derivation.typesDerivation=["simple","double","conditional","conditional1","conditional2","conditional3","final","initial"]; + this.dragables.derivation.events={ + init :[function(){ + this.dragables.derivation.noDrag=true; + }.extend(this)], + move:this.dropables.derivation.capture.args(this.dragables.derivation), + finish : this.parent.closure({instance:this,method:function(){ + //clearInterval(this.timeToOutControl); + + this.parent.dom.remove(this.dropables.derivation.drag || this.dragables.derivation.currentElementDrag); + this.parent.dom.remove(this.dragables.derivation.currentElementDrag); + if(this.dropables.derivation.selected!==false) + { + this.dropables.derivation.launchEvents(this.dropables.derivation.elements[this.dropables.derivation.selected].events.out); + vAux = this.dropables.derivation.launchEvents(this.dropables.derivation.elements[this.dropables.derivation.selected].events.click); + this.dropables.derivation.selected = false; + return vAux; + } + else + { + this.dragables.derivation.noDrag=false; + } + }}) + }; + this.dragables.derivation.make(); + //drg.options.elements=[]; + this.parent.dom.setStyle([dr1,dr2,dr3,dr4,dr5,dr6,fin,ini],{ + cursor:"move" + }); + panel.loader.hide(); + panel.addContent(div); + + leimnud._panel=['O'],leimnud.ipanel=0; + /* Toolbar End */ + }, + components:{ + + } + }, + base:function(xml) + { + this.panels.editor.loader.hide(); + this.data.db=xml.xmlhttp.responseText.parseJSON().concat({ + //derivations :["Sequential","Evaluate (manual)","Evaluate (auto)","Parallel (fork)","Parallel by evaluation (fork)","Parallel (join)"], + }); + this.data.db.subprocess=[]; + + this.panels.editor.addContentStatus(G_STRINGS.ID_PROCESSMAP_LOADING); + if(this.options.rw===true) + { + this.menu = new this.parent.module.app.menuRight(); + this.menu.make({ + target:this.panels.editor.elements.content, + width:201, + theme:this.options.theme, + menu:[ + {image:"/images/edit.gif",text:G_STRINGS.ID_PROCESSMAP_EDIT_PROCESS,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:700,h:390}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_EDIT_PROCESS+": "+this.data.db.title.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=process_Edit&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/edit.gif",text:G_STRINGS.ID_PROCESSMAP_EXPORT_PROCESS,launch:function(event){ + this.tmp.exportProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:440,h:230}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_EXPORT_PROCESS+": "+this.data.db.title.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=process_Export&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this)}, + {separator:true}, + {image:"/images/add.png",text:G_STRINGS.ID_PROCESSMAP_ADD_TASK,launch:this.addTask.extend(this,{tp:'task'})}, + {image:"/images/subProcess.png",text:G_STRINGS.ID_PROCESSMAP_ADD_SUBPROCESS,launch:this.addTask.extend(this,{tp:'subprocess'})}, //add subprocess whith blabla + {image:"/images/addtext.png",text:G_STRINGS.ID_PROCESSMAP_ADD_TEXT,launch:this.addText.extend(this)}, + {image:"/images/linhori.png",text:G_STRINGS.ID_PROCESSMAP_HORIZONTAL_LINE,launch:this.addGuide.extend(this,"horizontal")}, + {image:"/images/linver.png",text:G_STRINGS.ID_PROCESSMAP_VERTICAL_LINE,launch:this.addGuide.extend(this,"vertical")}, + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_ALL_LINES,launch:function(event,index){ + index = this.parent.browser.isIE?event:index; + new leimnud.module.app.confirm().make({ + label:G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_ALL_LINES, + action:function() + { + for(var i=0;i<this.data.db.guide.length;i++) + { + this.parent.dom.remove(this.data.db.guide[i].object.elements.guide); + } + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteGuides&data="+{ + pro_uid:this.options.uid + }.toJSONString() + }); + r.make(); + }.extend(this) + }); + }.extend(this)}, + {separator:true}, + {image:"/images/object_permission.gif",text:G_STRINGS.ID_OBJECT_PERMISSIONS,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:850,h:480}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_OBJECT_PERMISSIONS, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=objectPermissions&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/users.png",text:G_STRINGS.ID_PROCESSMAP_PSUPERVISORS,submenu:[ + {image:"/images/users.png",text:G_STRINGS.ID_PROCESSMAP_PROCESS_SUPERVISORS,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:300}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_PROCESS_SUPERVISORS, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=process_User&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/dynaforms.gif",text:G_STRINGS.ID_PROCESSMAP_SUPERVISORS_DYNAFORMS,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_SUPERVISORS_DYNAFORMS, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=supervisorDynaforms&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/inputdocument.gif",text:G_STRINGS.ID_PROCESSMAP_SUPERVISORS_INPUTS,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_SUPERVISORS_INPUTS, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=supervisorInputs&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)} + ]}, + {separator:true}, + {image:"/images/dynaforms.gif",text:G_STRINGS.ID_WEB_ENTRY,launch:function(event){ + this.tmp.editProcessPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_WEB_ENTRY, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=webEntry&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/tracker.gif",text:G_STRINGS.ID_CASE_TRACKER,submenu:[ + {image:"/images/tracker.gif",text:G_STRINGS.ID_CASE_TRACKER_PROPERTIES,launch:function(event){ + this.tmp.caseTrackerPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:300,h:180}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_CASE_TRACKER, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=caseTracker&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + + {image:"/images/tracker.gif",text:G_STRINGS.ID_CASE_TRACKER_OBJECTS,launch:function(event){ + this.tmp.caseTrackerPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_CASE_TRACKER_OBJECTS, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=caseTrackerObjects&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)} + ]}, + {image:"/images/folder.gif",text:G_STRINGS.ID_PROCESS_FILES_MANAGER,launch:function(event){ + this.tmp.processFilesManagerPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:500,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESS_FILES_MANAGER, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=processFilesManager&data="+{ + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)} , + {image:"/images/events.gif",text:G_STRINGS.ID_EVENTS,submenu:[ + {image:"/images/event_message.png",text:"Message",launch:function(event){ + this.tmp.eventsPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:700,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_EVENT_MESSAGE, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=events&data="+{ + pro_uid :this.options.uid, + type:"message" + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + + {image:"/images/event_conditional.png",text:"Conditional",launch:function(event){ + this.tmp.eventsPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:700,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_EVENT_CONDITIONAL, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=events&data="+{ + pro_uid :this.options.uid, + type:"conditional" + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)}, + {image:"/images/event_multiple.png",text:"Multiple",launch:function(event){ + this.tmp.eventsPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:700,h:380}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_EVENT_MULTIPLE, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=events&data="+{ + pro_uid :this.options.uid, + type:"multiple" + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + //Pm.objeto.innerHTML="asdasd"; + }.extend(this,panel); + r.make(); + }.extend(this)} + + + ]} + + ] + }); + this.observers.menu.register(this.parent.closure({instance:this.menu,method:this.menu.remove}),this.menu); + } + this.data.render.task(); + }, + task:function() + { + var lngt = this.data.db.task.length; + for(var i =0;i<lngt;i++) + { + //console.log(this.data.db.task[i]); + var tt = ((this.data.db.task[i].task_type==='NORMAL') || (this.data.db.task[i].task_type==='ADHOC'))?'task':'subprocess'; + //this.parent.exec(this.data.build.task,[this.data.db.task[i],i],false,this); + this.data.build.task(i,{tp:tt}); + } + this.data.render.taskINI(); + this.data.render.guide(); + //this.parent.exec(this.data.build.derivation,false,false,this); + }, + taskINI:function() + { + var lngt = this.data.db.task.length; + for(var i =0;i<lngt;i++) + { + var task=this.data.db.task[i]; + if(task.taskINI===true) + { + this.parent.dom.setStyle(task.object.elements.init,{ + background:"url("+this.options.images_dir+"inicio.gif)" + }); + } + } + return true; + }, + setTaskINI:function(option) + { + var task = this.data.db.task[this.tools.getIndexOfUid(option.task)]; + task.taskINI=option.value; + this.parent.dom.setStyle(task.object.elements.init,{ + background:((task.taskINI===true)?"url("+this.options.images_dir+"inicio.gif)":"") + }); + }, + guide:function() + { + for(var i=0;i<this.data.db.guide.length;i++) + { + //this.parent.exec(this.data.build.guide,[this.data.db.guide[i],i],false,this); + //this.parent.exec(this.data.build.guide,[i],false,this); + this.data.build.guide(i); + //this.parent.exec(this.data.build.guide,[2],false,this); + } + this.data.render.title(); + }, + title:function() + { + this.data.build.title(); + this.data.render.text(); + }, + deleteDerivation:function(uid,rec,spec) + { + var task = this.data.db.task[this.tools.getIndexOfUid(uid)]; + spec = (typeof spec!=="number")?false:spec; + var deri = task.derivation; + for(var i=0;i<deri.to.length;i++) + { + if(spec===false || (spec!==false && spec===i)) + { + if(deri.to[i].task==="-1" || deri.to[i].task==="-2") + { + this.parent.dom.setStyle(task.object.elements[(deri.to.length>1)?'derivationBottom':'derivation'],{ + background:"" + }); + + } + else + { + deri.to[i].object.line.remove(); + this.observers.lineas.unregister(deri.to[i].object.indexObserver); + } + if(deri.type===5) + { + var toTask = this.data.db.task[this.tools.getIndexOfUid(deri.to[i].task)]; + toTask.object.inJoin = toTask.object.inJoin-1; + if(toTask.object.inJoin===0) + { + this.parent.dom.setStyle(toTask.object.elements.init,{ + backgroundPosition:"0 0", + background:"" + }); + } + } + } + } + this.parent.dom.setStyle(task.object.elements.derivation,{ + background:"" + }); + task.derivation={to:[]}; + + /* Delete derivation recursive */ + if(rec) + { + var tdb = this.data.db.task; + for(var i=0;i<tdb.length;i++) + { + var der = tdb[i].derivation.to || []; + for(var j=0;j<der.length;j++) + { + if(der[j].task===uid) + { + this.data.render.deleteDerivation(tdb[i].uid,false,j); + } + } + } + } + }, + preDerivation:function(uid) + { + var tmS; + var typeDerivation = this.dragables.derivation.currentElementInArray; + if(typeDerivation===6){ + + var vars=this.data.db.task[uid]; + var vtd = { + type:0, + tas_uid:vars.uid, + pro_uid:this.options.uid, + data:["-1"], + next_task:'-1' + } + this.data.build.derivation(vtd); + vtd['delete'] = true; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveNewPattern&data="+vtd.toJSONString() + }); + r.make(); + this.inDerivationDrag=false; + this.dragables.derivation.noDrag=false; + return false; + } + else if(typeDerivation===7) { + var vars=this.data.db.task[uid]; + if (vars.task_type != 'SUBPROCESS') { + this.data.render.setTaskINI({task:vars.uid,value:true}); + this.inDerivationDrag=false; + this.dragables.derivation.noDrag=false; + var r = new leimnud.module.rpc.xmlhttp({ + url:"../tasks/tasks_Ajax", + args:"function=saveTaskData&oData="+{ + TAS_START:"TRUE", + TAS_UID:vars.uid + }.toJSONString() + }); + r.make(); + } + else { + this.inDerivationDrag=false; + this.dragables.derivation.noDrag=false; + } + return false; + } + this.observers.menu.update(); + tmS = this.derivationArrowToDrop = document.createElement("div"); + this.parent.dom.setStyle(tmS,{ + position:"absolute", + width : 10, + height : 10, + zIndex : 12, + overflow: "hidden", + backgroundColor:"red" + }); + this.panels.editor.elements.content.appendChild(tmS); + var ln; + ln = this.derivationLineToDrop = new this.parent.module.app.line({ + elements :[this.data.db.task[uid].object.elements.task,tmS], + target :this.panels.editor.elements.content, + color :"green", + zIndex :15 + }); + ln.make(); + this.observers.lineas.register(this.parent.closure({instance:ln,method:ln.update}),ln); + this.parent.event.add(this.data.db.task[uid].object.elements.task,"mouseover",this.parent.closure({instance:this,method:function(evt,arrow,lin,evi) + { + var ec = this.parent.dom.position(this.panels.editor.elements.content); + var mou = this.parent.dom.mouse(window.event || evt); + this.parent.dom.setStyle(arrow,{ + left : mou.x-(ec.x+6), + top : mou.y-(ec.y+6) + }); + this.parent.exec(lin.update,false,false,lin); + this.parent.event.flushCollection([evi]); + },event:true,args:[tmS,ln,this.parent.event.db.length]})); + + if(this.parent.browser.isIE){this.data.db.task[uid].object.elements.task.fireEvent("onmouseover");} + var uidEventMMove=this.parent.event.db.length; + + this.parent.event.add(this.panels.editor.elements.content,"mousemove",function(evt,arrow,lin) + { + var ec = this.parent.dom.position(this.panels.editor.elements.content); + var mou = this.parent.dom.mouse(window.event || evt); + this.parent.dom.setStyle(arrow,{ + left : (mou.x-(ec.x+6)+(this.panels.editor.elements.content.scrollLeft || 0)), + top : (mou.y-(ec.y+6)+(this.panels.editor.elements.content.scrollTop || 0)) + }); + lin.update(); + this.parent.exec(this.dropables.derivation.capture,{currentElementDrag:arrow},false,this.dropables.derivation); + }.extend(this,tmS,ln)); + this.parent.event.add(tmS,"click",function(evt,options) + { + //options = (window.event)?evt:options; + this.dropables.derivation.capture({currentElementDrag:options.arrow}); + this.dragables.derivation.noDrag=false; + if(this.dropables.derivation.selected===false) + { + options.line.remove(); + } + else + { + options.line.remove(); + this.patternPanel(false,options.uid,{to:this.dropables.derivation.selected,type:this.dragables.derivation.currentElementInArray}); + if (this.dropables.derivation.elements[this.dropables.derivation.selected]) + { + this.dropables.derivation.launchEvents(this.dropables.derivation.elements[this.dropables.derivation.selected].events.out); + } + } + this.inDerivationDrag=false; + this.dropables.derivation.selected=false; + this.parent.event.flushCollection([options.ue,options.ua]); + this.parent.dom.remove(options.arrow); + }.extend(this,{uid:uid,arrow:tmS,line:ln,ue:this.parent.event.db.length,ua:uidEventMMove})); + }, + derivation:function(uid,type) + { + for(var i=0;i<this.data.db.task.length;i++) + { + this.data.render.lineDerivation(i); + } + return true; + }, + lineDerivation:function(index) + { + var task = this.data.db.task[index]; + for(var j=0;j<task.derivation.to.length;j++) + { + var derivation = task.derivation.to[j]; + //alert(derivation.task); + if(derivation.task==="-1" || derivation.task==="-2") + { + var target=(task.derivation.to.length>1)?'derivationBottom':'derivation'; + this.parent.dom.setStyle(task.object.elements[target],{ + // background:((task.derivation.type===0)?"":"url("+this.options.images_dir+task.derivation.type+"t.gif?aa="+Math.random()+")") + // background:"url("+this.options.images_dir+derivation.task+".gif?aa="+Math.random()+")" + background:"url("+this.options.images_dir+derivation.task+((target=="derivationBottom")?"bb.jpg":".gif")+"?aa="+Math.random()+")" + }); + + } + else + { + var uid = this.tools.getIndexOfUid(derivation.task); + //alert(this.tools.getIndexOfUid) + //alert(this.tools.getIndexOfUid(derivation.task)); + //var from = (task.derivation.type===0)?task.object.elements.task:task.object.elements.derivation; + var taskF= task.object.elements; + var taskT= this.data.db.task[uid].object.elements; + var from = task.object.elements.derivation; + var toTask=this.data.db.task[uid]; + var to = toTask.object.elements.task; + + if(task.derivation.type!==5) + { + this.parent.dom.setStyle(task.object.elements.derivation,{ + //background:((task.derivation.type===0)?"":"url("+this.options.images_dir+task.derivation.type+"t.gif?aa="+Math.random()+")") + background:"url("+this.options.images_dir+task.derivation.type+"t.gif?aa="+Math.random()+")" + }); + } + else + { + var ij = toTask.object.inJoin; + ij = (ij)?ij+1:1; + toTask.object.inJoin = ij; + this.parent.dom.setStyle(toTask.object.elements.init,{ + //background:((task.derivation.type===0)?"":"url("+this.options.images_dir+task.derivation.type+"t.gif?aa="+Math.random()+")") + background:"url("+this.options.images_dir+task.derivation.type+"t.gif?aa="+Math.random()+")", + backgroundPosition:"2 0", + backgroundRepeat:"no-repeat" + }); + } + + var line = new this.parent.module.app.line({ + indexRootSize:30, + indexRootLastSize:35, + elements:[taskF.task,taskT.task], + envolve:[ + [taskF.task], + [] + ], + target:this.panels.editor.elements.content, + color:"#228AB0", + startA:50, + zIndex:5 + }); + line.make(); + var cE=this.observers.lineas.register(line.update,line); + derivation.object={ + line : line, + indexObserver : cE + }; + } + } + }, + text:function() + { + var lngt = this.data.db.text.length; + for(var i =0;i<lngt;i++) + { + this.data.build.text(i); + } + this.panels.editor.clearContentStatus(); + this.data.render.derivation(); + } + }, + build:{ + task:function(index,options_task) + { + //console.log(index); + options_task = { + tp:'task' + }.concat(options_task || {}); + /*var options = { + color:((options_task.tp==='task')?"auto":"green") + }.concat(this.data.db[(options_task.tp=='task')?'task':'subprocess'][index] || {});*/ + //var options = this.data.db[(options_task.tp=='task')?'task':'subprocess'][index]; + var options = this.data.db['task'][index]; + + //options.color = ((options_task.tp==='task')?"auto":"#9B88CA"); + //options.color = "auto"; + //alert(this.options.rw); + + if (this.options.rw) { + options.color = ((options_task.tp==='task')?"auto":"#9B88CA"); + } + + var db = this.data.db, task=db.task[index]; + var derivation = task.derivation.to; + var a = document.createElement("div"); + a.className="processmap_task___"+this.options.theme; + this.parent.dom.setStyle(a,{ + top:options.position.y, + left:options.position.x, + cursor:((this.options.rw===true)?"move":"default"), + backgroundColor:(options.color ? options.color : 'auto') + }); + + var subp = ((options_task.tp==='task')?"":"url(/images/subp.png)"); + var b = document.createElement("div"); + b.className="processmap_task_label___"+this.options.theme; + this.parent.dom.setStyle(b,{ + cursor:((this.options.rw===true)?"move":"default"), + background:subp, + backgroundRepeat:"no-repeat", + backgroundPosition:"center", + height:40 + }); + b.innerHTML = options.label; + + var b1 = document.createElement("div"); + this.parent.dom.setStyle(b1,{ + top:'2', + left:'5', + border:"0px solid red", + height:13, + position:"absolute" + }); + if(task.statusIcons){ + + for(var i=0;i<task.statusIcons.length;i++){ + //alert(task.statusIcons[i].icon); + var icon = document.createElement("img"); + icon.src=task.statusIcons[i].icon; + icon.height='13'; + icon.width='13'; + icon.alt=task.statusIcons[i].message; + icon.title=task.statusIcons[i].message; + icon.style.cursor = "help"; + + icon.onmouseover=function(){ + //b11.innerHTML = this.alt; + } + icon.onmouseout=function(){ + //b11.innerHTML = ""; + } + + b1.appendChild(icon); + + } + } + //clip: "rect(0,0,0,0)" + /*if (task.derivation.type==5) { + for(var it=0;it< db.task.length;it++) + { + if ( db.task[it].uid == derivation[0].task ) + { + var joinPosX = db.task[it].position.x + 69; + var joinPosY = db.task[it].position.y - 30; + } + } + }*/ + + var c = document.createElement("div"); + this.parent.dom.setStyle(c,{ + position:"absolute", + top: /*task.derivation.type==5 ? joinPosY :*/ options.position.y+38, + left:/*task.derivation.type==5 ? joinPosX :*/ options.position.x+(81-12), + height:25, + width:25, + //backgroundColor:"black", + border:"0px solid black", + overflow:"hidden", + cursor:(this.options.rw===true ? "pointer" : 'default'), + zIndex:9 + }); + if (this.options.rw===true) { + /******************************neyek************************************** + * Compativility for IE 7, 8 + */ + if (navigator.appName == "Microsoft Internet Explorer"){ + c.onclick=this.patternPanel.args(1, index, null); + } else { + c.onclick=this.patternPanel.args(index); + } + } + var d = document.createElement("div"); + this.parent.dom.setStyle(d,{ + position:"absolute", + top: /*task.derivation.type==5 ? joinPosY :*/ options.position.y+49, + left:/*task.derivation.type==5 ? joinPosX :*/ options.position.x+(93), + height:38, + width:38, + //backgr1undColor:"black", + border:"0px solid black", + overflow:"hidden", + zIndex:9 + }); + + var t = document.createElement("div"); + + this.parent.dom.setStyle(t,{ + position:"absolute", + top:options.position.y-30, + left:options.position.x+(81-14), + height:30, + width:30, + //backgroundColor:"black", + //border:"1px solid black", + overflow:"hidden", + zIndex:9 + }); + if(this.options.rw===true) + { + /* Change label Begin */ +/* a.ondblclick=function(evt,index) + { + var text=this.data.db.task[(window.event)?evt:index]; + var t = prompt(G_STRINGS.ID_PROCESSMAP_PROMPT_RENAME_TEXT,text.label.unescapeHTML()); + if(t && t.trim()!=="" && t!==text.label) + { + text.label = text.object.elements.label.innerHTML=t.escapeHTML(); + var r = new leimnud.module.rpc.xmlhttp({ + url : this.options.dataServer, + args : "action=updateText&data="+{uid:text.uid,label:text.label.unescapeHTML()}.toJSONString() + }); + r.make(); + } + }.extend(this,index);*/ + /* Change label End */ + var menu = new this.parent.module.app.menuRight(); + var textMenu = G_STRINGS.ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC; + var lengthText = textMenu.length*5.5; + menu.make({ + target:a, + width:26+lengthText, + theme:this.options.theme, + menu:((options_task.tp=='task')? + [ + {image:"/images/steps.png",text:G_STRINGS.ID_PROCESSMAP_STEPS,launch:function(event,index){ + this.tmp.stepsPanel = panel =new leimnud.module.panel(); + var data = this.data.db.task[index]; + var iForm=function(panel,index,ifo){ + panel.command(panel.loader.show); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=steps&data="+{proUid:this.options.uid,tasUid:data.uid,option:ifo,index:index}.toJSONString() + }); + r.callback=this.parent.closure({instance:this,method:function(index,rpc,panel){ + panel.command(panel.loader.hide); + var scs=rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + },args:[index,r,panel]}); + r.make(); + } + panel.options={ + limit:true, + size:{w:670,h:410}, + position:{x:50,y:50,center:true}, + title: G_STRINGS.ID_PROCESSMAP_TASK_STEPS+" "+data.label, + theme:this.options.theme, + statusBar:false, + control:{ + close:true + }, + fx:{ + modal:true + }}; + panel.tab={ + width :300, + optWidth:120, + step :(this.parent.browser.isIE?3:4), + options:[{ + title :G_STRINGS.ID_PROCESSMAP_STEPS, + content :this.parent.closure({instance:this,method:iForm,args:[panel,index,1]}), + selected:true + },{ + title :G_STRINGS.ID_PROCESSMAP_CONDITIONS, + content :this.parent.closure({instance:this,method:iForm,args:[panel,index,2]}) + },{ + title :G_STRINGS.ID_PROCESSMAP_TRIGGERS, + content :this.parent.closure({instance:this,method:iForm,args:[panel,index,3]}) + }] + }; + panel.events = { + remove: function() { + if(PROCESSMAP_STEP_EDIT) + window.location.href = window.location; + }.extend(this) + }; + panel.make(); + }.extend(this,index)}, + {image:"/images/users.png",text:G_STRINGS.ID_PROCESSMAP_USERS_AND_GROUPS,launch:function(event,index){ + var panel; + this.tmp.usersPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:450,h:300}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_USERS_AND_GROUPS+": "+task.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{modal:true} + }; + panel.events = { //neyek + remove: function() { + if(PROCESSMAP_USER_EDIT) + window.location.href = window.location; + }.extend(this) + }; + panel.make(); + panel.loader.show(); + var r; + panel.currentRPC = r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=users&data="+{ + tas_uid :task.uid, + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this,index)}, + + {image:"/images/users.png",text:G_STRINGS.ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC,launch:function(event,index){ + var panel; + this.tmp.usersPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:450,h:300}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_USERS_AND_GROUPS_ADHOC+": "+task.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{modal:true} + }; + panel.make(); + panel.loader.show(); + var r; + panel.currentRPC = r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=users_adhoc&data="+{ + tas_uid :task.uid, + pro_uid :this.options.uid + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this,index)}, + + {image:"/images/rules.png",text:G_STRINGS.ID_PROCESSMAP_WORKFLOW_PATTERNS,launch:this.patternPanel.args(index)}, + {image:"/images/delete_rules.png",text:G_STRINGS.ID_PROCESSMAP_WORKFLOW_DELETE_PATTERNS,launch:this.parent.closure({instance:this,method:function() { + var data = this.data.db.task[index]; + if (typeof(data.derivation.type) != 'undefined') { + new this.parent.module.app.confirm().make({ + label : G_STRINGS.ID_PROCESSMAP_WORKFLOW_CONFIRM_DELETE_PATTERNS + '"' + data.label + '"?', + action: function() { + var db = this.data.db, task=db.task[index]; + var vars = { + tas_uid:task.uid, + pro_uid:this.options.uid + }; + var aData = {}; + aData.tas_uid = vars.tas_uid; + aData.data = []; + this.data.build.derivation(aData); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:'action=deleteAllRoutes&data='+vars.toJSONString() + }); + r.make(); + }.extend(this) + }); + } + else { + new leimnud.module.app.alert().make({ + label:G_STRINGS.ID_NO_DERIVATIONS_DEFINED + }); + } + },args:index})}, + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_TASK,launch:this.parent.closure({instance:this,method:function(index){ + var data = this.data.db.task[index]; + new this.parent.module.app.confirm().make({ + label:G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_TASK+data.label, + action:function() + { + data.object.drag.flush(); + this.dropables.derivation.unregister(data.object.dropIndex); + this.data.render.deleteDerivation(data.uid,true); + this.parent.dom.remove(data.object.elements); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteTask&data="+{pro_uid:this.options.uid,tas_uid:data.uid}.toJSONString() + }); + r.make(); + }.extend(this) + }); + return; + if(confirm(G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_TASK+data.label)) + { + data.object.drag.flush(); + this.dropables.derivation.unregister(data.object.dropIndex); + this.data.render.deleteDerivation(data.uid); + this.parent.dom.remove(data.object.elements); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteTask&data="+{pro_uid:this.options.uid,tas_uid:data.uid}.toJSONString() + }); + r.make(); + } + },args:index})}, + {simage:"/images/properties.png",text:G_STRINGS.ID_PROCESSMAP_PROPERTIES,launch:this.parent.closure({instance:this,method:function(index){ + var panel; + var iForm=function(panel,index,ifo){ + saveDataTaskTemporal(ifo); + panel.command(panel.loader.show); + var r = new this.parent.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=editTaskProperties&data="+{uid:data.uid,iForm:ifo,index:index}.toJSONString() + }); + r.callback=this.parent.closure({instance:this,method:function(index,rpc,panel){ + panel.command(panel.loader.hide); + panel.clearContent(); + var scs=rpc.xmlhttp.responseText.extractScript(); //capturamos los scripts + panel.addContent(rpc.xmlhttp.responseText.stripScript());//Eliminamos porque ya no los necesitamos + scs.evalScript(); //interpretamos los scripts + },args:[index,r,panel]}); + r.make(); + } + + this.tmp.propertiesPanel = panel =new leimnud.module.panel(); + var data = this.data.db.task[index]; + panel.options={ + limit:true, + size:{w:600,h:430}, + position:{x:50,y:50,center:true}, + title:G_STRINGS.ID_PROCESSMAP_TASK+": "+data.label, + theme:this.options.theme, + statusBar:true, + statusBarButtons:[ + {type:"button",value:G_STRINGS.ID_PROCESSMAP_SUBMIT}, + {type:"button",value:G_STRINGS.ID_PROCESSMAP_CANCEL} + ], + control:{ + close:true, + resize:false + }, + fx:{ + modal:true + } + }; + panel.tab={ + width :170, + optWidth:160, + widthFixed:false, + step :(this.parent.browser.isIE?3:4), + options:[{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_DEFINITION, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,1]}), + noClear : true, + selected: true + },{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_ASSIGNMENTS, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,2]}), + noClear : true + },{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_TIMING, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,3]}), + noClear : true + },{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_PERMISSIONS, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,5]}), + noClear : true + },{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_LABELS, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,6]}), + noClear : true + },{ + title : G_STRINGS.ID_PROCESSMAP_TASK_PROPERTIES_NOTIFICATIONS, + content : this.parent.closure({instance:this,method:iForm,args:[panel,index,7]}), + noClear : true + }] + }; + panel.make(); + },args:index})} + ]: + [ + {image:"/images/rules.png",text:G_STRINGS.ID_PROCESSMAP_WORKFLOW_PATTERNS,launch:this.patternPanel.args(index)}, + {image:"/images/delete_rules.png",text:G_STRINGS.ID_PROCESSMAP_WORKFLOW_DELETE_PATTERNS,launch:this.parent.closure({instance:this,method:function() { + var data = this.data.db.task[index]; + if (typeof(data.derivation.type) != 'undefined') { + new this.parent.module.app.confirm().make({ + label : G_STRINGS.ID_PROCESSMAP_WORKFLOW_CONFIRM_DELETE_PATTERNS + '"' + data.label + '"?', + action: function() { + var db = this.data.db, task=db.task[index]; + var vars = { + tas_uid:task.uid, + pro_uid:this.options.uid + }; + var aData = {}; + aData.tas_uid = vars.tas_uid; + aData.data = []; + this.data.build.derivation(aData); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:'action=deleteAllRoutes&data='+vars.toJSONString() + }); + r.make(); + }.extend(this) + }); + } + else { + new leimnud.module.app.alert().make({ + label:G_STRINGS.ID_NO_DERIVATIONS_DEFINED + }); + } + },args:index})}, + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_SUBPROCESS,launch:this.parent.closure({instance:this,method:function(index){ + var data = this.data.db.task[index]; + new this.parent.module.app.confirm().make({ + label:G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_SUBPROCESS+data.label, + action:function() + { + data.object.drag.flush(); + this.dropables.derivation.unregister(data.object.dropIndex); + this.data.render.deleteDerivation(data.uid,true); + this.parent.dom.remove(data.object.elements); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteSubProcess&data="+{pro_uid:this.options.uid,tas_uid:data.uid}.toJSONString() + }); + r.make(); + }.extend(this) + }); + return; + if(confirm(G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_TASK+data.label)) + { + data.object.drag.flush(); + this.dropables.derivation.unregister(data.object.dropIndex); + this.data.render.deleteDerivation(data.uid); + this.parent.dom.remove(data.object.elements); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteSubProcess="+{pro_uid:this.options.uid,tas_uid:data.uid}.toJSONString() + }); + r.make(); + } + },args:index})}, + {simage:"/images/properties.png",text:G_STRINGS.ID_PROCESSMAP_PROPERTIES,launch:function(event,index){ + var panel; + this.tmp.subProcessPanel = panel =new leimnud.module.panel(); + //alert(this.data.db.task[index].label);+": "+task.label + panel.options={ + limit :true, + size :{w:700,h:550}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_PROPERTIES, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{modal:true} + }; + panel.make(); + panel.loader.show(); + var r; + panel.currentRPC = r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=subProcess_Properties&data="+{ + tas_uid :task.uid, + pro_uid :this.options.uid, + index: index + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this,index)} + ]) + }); + this.observers.menu.register(menu.remove,menu); + } + else { + if (this.options.mi) { + this.parent.dom.setStyle(a,{ + cursor:('pointer') + }); + a.title = G_STRINGS.ID_CLICK_VIEW_MORE_INFO; + this.parent.dom.setStyle(b,{ + cursor:('pointer') + }); + /*b.title = G_STRINGS.ID_CLICK_VIEW_MORE_INFO; + this.parent.dom.setStyle(c,{ + cursor:('pointer') + }); + c.title = G_STRINGS.ID_CLICK_VIEW_MORE_INFO;*/ + this.parent.event.add(a, 'click', {instance:this,method:function(evt, index) + { + var data = this.data.db.task[index]; + this.oTaskDetailsPanel = new leimnud.module.panel(); + this.oTaskDetailsPanel.options = { + limit : true, + size : {w:300,h:227}, + position : {x:0,y:0,center:true}, + title : '', + theme : 'processmaker', + statusBar: false, + control : {drag:false,resize:false,close:true}, + fx : {opacity:true,rolled:false,modal:true} + }; + this.oTaskDetailsPanel.make(); + this.oTaskDetailsPanel.events = { + remove:function() { + delete this.oTaskDetailsPanel; + }.extend(this) + }; + this.oTaskDetailsPanel.loader.show(); + var r = new this.parent.module.rpc.xmlhttp({ + url :'cases_Ajax', + args:'action=showTaskDetails&sTaskUID=' + data.uid + }); + r.callback=function(rpc){ + this.oTaskDetailsPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + this.oTaskDetailsPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + r.make(); + }.extend(this,index)}); + } + } + this.panels.editor.elements.content.appendChild(a); + a.appendChild(b); + if(this.options.rw===true){ + a.appendChild(b1); + } + + this.panels.editor.elements.content.appendChild(c); + this.panels.editor.elements.content.appendChild(d); + this.panels.editor.elements.content.appendChild(t); + + options['object']={ + elements:{ + task : a, + label : b, + derivation: c, + derivationBottom: d, + init : t, + statusIcons:b1 + } + }; + //console.info(index) + options.object.dropIndex=this.dropables.derivation.register({ + element : a, + value : index, + events : { + over :this.parent.closure({instance:this.dropables.derivation,method:function(e,o,u){ + this.parent.dom.setStyle(e,{ + border:"1px solid #006699" + }); + },args:[a,options,index]}), + out :this.parent.closure({instance:this.dropables.derivation,method:function(e,o,u){ + this.parent.dom.setStyle(e,{ + border:"0px solid #006699" + }); + },args:[a,options,index]}), + click :this.data.render.preDerivation.args(index) + } + }); + if(this.options.rw===true) + { + options.object.drag = new this.parent.module.drag({ + //elements:a + link:{ + elements:a, + ref:[a,c,d,t] + }, + limit:true + //group:[a,c] + }); + this.observers.lineas.register(this.parent.closure({instance:options.object.drag,method:function(){}}),options.object.drag); + options.object.drag.events={ + //move :this.parent.closure({instance:options.object.drag,method:options.object.drag.observer.update}), + move :this.parent.closure({instance:this,method:function(div,divC,uid,drag) { + options.object.drag.observer.update(); + var db = this.data.db; + },args:[a,c,index,options.object.drag]}), + + finish :this.parent.closure({instance:this,method:function(div,divC,uid,drag){ + if(!drag.moved){return false;} + var pos = this.parent.dom.position(div); + var h=pos; + var data = this.data.db.task[uid]; + var db = this.data.db; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveTaskPosition&data="+{uid:data.uid,position:pos}.toJSONString() + }); + r.make(); + },args:[a,c,index,options.object.drag]}) + }; + options.object.drag.make(); + } + //alert(options.object); + }, + guide:function(index) + { + var options = this.data.db.guide[index]; + var scl = { + x:this.panels.editor.elements.content.scrollLeft, + y:this.panels.editor.elements.content.scrollTop + }; + var a =document.createElement("div"); + var pos = { + top:((options.direction==="vertical")?0+scl.y:options.position), + left:((options.direction==="horizontal")?0+scl.x:options.position) + }; + this.parent.dom.setStyle(a,{ + position:"absolute", + display :"", + visibility:"visible", + height :((options.direction==="vertical")?"100%":5), + width :((options.direction==="horizontal")?"100%":5), + backgroundColor:"transparent", + borderLeft:((options.direction==="vertical")?"1":"0")+"px solid #FE9F0D", + borderTop:((options.direction==="horizontal")?"1":"0")+"px solid #FE9F0D", + overflow:'hidden', + zIndex :1, + cursor :((this.options.rw===true)?"move":"default"), + left :pos.left, + top :pos.top + }); + //alert(pos.top+":"+pos.left) +/* if(options.direction==="vertical") + { + this.parent.dom.setStyle(a,{ + left:pos.left+1 + }); + } + else + { + + }*/ + var menu = new this.parent.module.app.menuRight(); + menu.make({ + target:a, + width:201, + theme:this.options.theme, + menu:[ + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_LINE,launch:this.parent.closure({instance:this,method:function(index){ + var data = this.data.db.guide[index]; + this.parent.dom.remove(data.object.elements); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteGuide&data="+{ + uid:data.uid + }.toJSONString() + }); + r.make(); + },args:index})} + ], + //onFocus: + //onBlur: + parent:this.parent + }); + this.observers.menu.register(this.parent.closure({instance:menu,method:menu.remove}),menu); + options.object={ + elements:{guide:a} + }; + var Gdrag=new this.parent.module.drag({ + elements:a, + limit:((options.direction==="horizontal")?"x":"y") + }); + Gdrag.events={ + finish:this.parent.closure({instance:this,method:function(index,drag){ + if(!drag.moved){return false;} + var data = this.data.db.guide[index]; + var pos = this.parent.dom.position(data.object.elements.guide); + data.position=(data.direction=="vertical")?pos.x:pos.y; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveGuidePosition&data="+{ + uid:data.uid, + position:data.position, + direction:data.direction + }.toJSONString() + }); + r.make(); + + },args:[index,Gdrag]}) + }; + Gdrag.make(); var guideObserver = this.observers.guideLines.register(this.parent.closure({instance:this,method:function(obj,direction){ + if(direction=="horizontal") + { + obj.style.left=parseInt(this.panels.editor.elements.content.scrollLeft,10); + } + else + { + obj.style.top=parseInt(this.panels.editor.elements.content.scrollTop,10); + } + },args:[a,options.direction]})); +// this.panels.editor.elements.content.onscroll = guideObserver.update; + this.panels.editor.elements.content.onscroll = this.observers.guideLines.update; + this.panels.editor.elements.content.appendChild(a); + }, + title:function(index) + { + if(this.data.db.title) + { + var title=this.data.db.title; + var t = document.createElement("div"); + t.className="processmap_title___"+this.options.theme; + this.parent.dom.setStyle(t,{ + top:title.position.y, + left:title.position.x, + cursor:((this.options.rw===true)?"move":"default") + }); + t.innerHTML=title.label; + if(this.options.rw===true) + { + /*t.ondblclick=function(evt,index) + { + var text=this.data.db.title.label; + var t = prompt(G_STRINGS.ID_PROCESSMAP_PROMPT_RENAME_TEXT,text.unescapeHTML()); + if(t && t.trim()!=="" && t!==text) + { + text.label = text.object.elements.label.innerHTML=t.escapeHTML(); + var r = new leimnud.module.rpc.xmlhttp({ + url : this.options.dataServer, + args : "action=updateText&data="+{uid:text.uid,label:text.label.unescapeHTML()}.toJSONString() + }); + r.make(); + } + }.extend(this,index);*/ + } + this.panels.editor.elements.content.appendChild(t); + title.object={ + elements:{ + label:t + } + }; + + if(this.options.rw===true) + { + title.object.drag = new this.parent.module.drag({ + elements:t, + limit:true + }); + title.object.drag.events={ + finish:function(drag) + { + if(!drag.moved){return false;} + var title = this.data.db.title; + var pos = this.parent.dom.position(title.object.elements.label); + title.position=pos; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveTitlePosition&data="+{ + pro_uid:this.options.uid, + position:title.position + }.toJSONString() + }); + r.make(); + + }.extend(this,title.object.drag) + }; + title.object.drag.make(); + } + } + }, + text:function(index) + { + var text = this.data.db.text[index]; + var a = document.createElement("div"); + a.className="processmap_text___"+this.options.theme; + this.parent.dom.setStyle(a,{ + top:text.position.y, + left:text.position.x, + cursor:((this.options.rw===true)?"move":"default") + }); + a.innerHTML=text.label; + this.panels.editor.elements.content.appendChild(a); + if(this.options.rw===true) + { + var menu = new this.parent.module.app.menuRight(); + menu.make({ + target:a, + width:201, + theme:this.options.theme, + menu:[ + {image:"/images/properties.png",text:G_STRINGS.ID_PROCESSMAP_EDIT_TEXT,launch:function(evt,index){ + var text=this.data.db.text[index]; + /*var t = prompt(G_STRINGS.ID_PROCESSMAP_EDIT_TEXT_CHANGE_TO,text.label.unescapeHTML()); + if(t && t.trim()!=="" && t!==text.label) + { + text.label = text.object.elements.label.innerHTML=t.escapeHTML(); + var r = new leimnud.module.rpc.xmlhttp({ + url : this.options.dataServer, + args : "action=updateText&data="+{uid:text.uid,label:text.label.unescapeHTML()}.toJSONString() + }); + r.make(); + }*/ + new this.parent.module.app.prompt().make({ + label:G_STRINGS.ID_PROCESSMAP_EDIT_TEXT_CHANGE_TO, + value:text.label.escapeHTML(), + action:function(text,tObj){ + if(text.trim()!=="" && tObj.label!=text) + { + tObj.label = tObj.object.elements.label.innerHTML=text.escapeHTML(); + var r = new leimnud.module.rpc.xmlhttp({ + url : this.options.dataServer, + args : "action=updateText&data="+{uid:tObj.uid,label:tObj.label.unescapeHTML()}.toJSONString() + }); + r.make(); + } + }.extend(this,text) + }); + }.extend(this,index)}, + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_TEXT,launch:function(evt,index){ + var text=this.data.db.text[index]; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteText&data="+{uid:text.uid}.toJSONString() + }); + r.make(); + this.parent.dom.remove(text.object.elements.label); + this.data.db.text[index]=null; + }.extend(this,index)} + ] + }); + this.observers.menu.register(menu.remove,menu); + text.object={ + elements:{ + label:a + } + }; + text.object.drag = new this.parent.module.drag({ + elements:a, + limit:true + }); + text.object.drag.events={ + finish:function(index,drag) + { + if(!drag.moved){return false;} + var text = this.data.db.text[index]; + var pos = this.parent.dom.position(text.object.elements.label); + text.position=pos; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveTextPosition&data="+{ + uid:text.uid, + position:text.position + }.toJSONString() + }); + r.make(); + + }.extend(this,index,text.object.drag) + }; + text.object.drag.make(); + } + }, + derivation:function(options) + { + tt=options; + var index=this.tools.getIndexOfUid(options.tas_uid); + var from=this.data.db.task[index]; + this.data.render.deleteDerivation(options.tas_uid); + var affe=options.data; + from.derivation.type=options.type; + for(var i=0;i<affe.length;i++) + { + from.derivation.to[i]={ + task:affe[i] + }; + } + this.data.render.lineDerivation(index); + + //is.parent.dom.remove(from.object.elements); + //alert(this.tools.getIndexOfUid(from)); + } + }, + save:function() + { + + } + /*,db:{ + task:[ + { + label:"Task1", + uid:"faa", + position:{x:100,y:100}, + derivation: + { + from:"faa", + type:0, + to:[ + { + task:"fbb", + condition:"asdasd", //blanco si no requiere o no tiene + executed_by:1, //si ese typo de derivacion no requiere esto entonces tendrá false + optional:true //si ese tipo de derivacion no requiere blablablabnalbalbalbal false + }, + { + task:"fbc", + condition:"44444", //blanco si no requiere o no tiene + executed_by:1, //si ese typo de derivacion no requiere esto entonces tendrá false + optional:true //si ese tipo de derivacion no requiere blablablabnalbalbalbal false + } + ] + }, + color:"#006699" + },{ + label:"Task2", + uid:"fbb", + position:{x:300,y:100}, + derivation:{ + to:[] + }, + color:"#006699" + },{ + label:"Task 3", + uid:"fbc", + position:{x:400,y:300}, + derivation:{ + to:[] + }, + color:"#006699" + }], + guide:[ + {position:100,direction:"vertical",uid:222}, + {position:100,direction:"vertical",uid:222}, + {position:100,direction:"vertical",uid:222} + ], + text:[ + {position:{x:22,y:22},uid:2323,label:"algo"} + ], + derivations:[ + "Simple","Conditional","Other" + ] + }*/ + }.expand(this,true); + this.patternPanel=function(event,index,din){ + + var options = this.data.db.task[index]; + var db = this.data.db, task=db.task[index]; + var derivation = task.derivation.to; + + var vars = { + tas_uid:task.uid, + pro_uid:this.options.uid + }.concat((din)?{ + type : din.type, + next_task: this.data.db.task[din.to].uid + }:{}); + /* + * Aca se definen TASK inicio y TASK a la que se deriva. + */ + + if (event) + { + if (typeof(this.data.db.task[index].derivation.type) == 'undefined') + { + new leimnud.module.app.alert().make( + { + label:G_STRINGS.ID_NO_DERIVATIONS_DEFINED + }); + return false; + } + var iWidth, iHeight; + switch(this.data.db.task[index].derivation.type) + { + case 0: + iWidth = 450; + iHeight = 205; + break; + case 1: + iWidth = 700; + iHeight = 350; + break; + case 2: + iWidth = 700; + iHeight = 350; + break; + case 3: + iWidth = 350; + iHeight = 350; + break; + case 4: + iWidth = 500; + iHeight = 350; + break; + case 5: + iWidth = 450; + iHeight = 205; + break; + } + + + this.tmp.derivationsPanel = panel =new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:iWidth,h:iHeight}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_WORKFLOW_PATTERNS+": "+task.label, + theme :this.options.theme, + control :{close:true,resize:false}, + fx :{modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=derivations&data="+vars.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + } + else + { + if ((this.data.db.task[index].derivation.type != vars.type) && (typeof(this.data.db.task[index].derivation.type) != 'undefined')) + { + if (typeof(this.data.db.task[index].derivation.type) != 'undefined') + { + new leimnud.module.app.confirm().make({ + label: G_STRINGS.ID_PROCESSMAP_CONFIRM_WORKFLOW_PATTERN_CHANGE, + action: function() { + var aData = {}; + aData.type = Number(vars.type); + aData.tas_uid = vars.tas_uid; + aData.data = []; + aData.data.push(vars.next_task); + this.data.build.derivation(aData); + vars['delete'] = true; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveNewPattern&data="+vars.toJSONString() + }); + r.make(); + }.extend(this) + }); + } + } + else + { + var aData = {}; + aData.type = vars.type; + aData.tas_uid = vars.tas_uid; + aData.data = []; + aData.data.push(vars.next_task); + if ((aData.type != 0) && (aData.type != 5)) + { + for (var i = 0; i < this.data.db.task[index].derivation.to.length; i++) + { + if (!aData.data.inArray(this.data.db.task[index].derivation.to[i].task)) + { + aData.data.push(this.data.db.task[index].derivation.to[i].task); + } + } + } + Pm.data.build.derivation(aData); + aData.data.push(vars.next_task); + vars['delete'] = false; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveNewPattern&data="+vars.toJSONString() + }); + r.make(); + } + } + }; + this.tools={ + getIndexOfUid:function(uid) + { + for(var i=0;i<this.data.db.task.length;i++) + { + if(this.data.db.task[i].uid===uid){return i;} + } + }, + getUidOfIndex:function(index) + { + return this.data.db.task[index].uid || false; + } + }.expand(this); + this.expand(this); +}; + +processmap.prototype={ + parent:leimnud, + tmp:{}, + info:{ + name : "processmap" + }, + panels:{},dragables:{},dropables:{}, + make:function() + { + this.options = { + theme :"firefox", + rw :true, + mi :true, + ct :false, + hideMenu:true + }.concat(this.options || {}); + this.options.target = this.parent.dom.element(this.options.target); + if(!this.validate()){return false;} + this.observers = { + menu : this.parent.factory(this.parent.pattern.observer,true), + lineas : this.parent.factory(this.parent.pattern.observer,true), + guideLines : this.parent.factory(this.parent.pattern.observer,true), + buildingLineGuides: this.parent.factory(this.parent.pattern.observer,true) + }; + this.dropables.derivation = new this.parent.module.drop(); + this.dropables.derivation.make(); + + /* Hidden processmaker menu-submenu BEGIN*/ + if(this.options.hideMenu===true) + { + var h = this.parent.dom.element("pm_header"); + var m = this.parent.dom.element("pm_menu"); + var s = this.parent.dom.element("pm_submenu"); + var sep = this.parent.dom.element("pm_separator"); + sep.className = "pm_separatorOff___"+this.options.theme; + this.menuRolled=false; + var dse = document.createElement("div"); + dse.className = "pm_separatorDOff___"+this.options.theme; + sep.appendChild(dse); + sep.onmouseup=function() + { + if(this.menuRolled===true) + { + sep.className="pm_separatorOff___"+this.options.theme; + dse.className="pm_separatorDOff___"+this.options.theme; + this.parent.dom.setStyle([h,m,s],{ + display:"" + }); + this.menuRolled=false; + } + else + { + sep.className="pm_separatorOn___"+this.options.theme; + dse.className="pm_separatorDOn___"+this.options.theme; + this.menuRolled=true; + this.parent.dom.setStyle([h,m,s],{ + display:"none" + }); + } + }.extend(this,sep); + dse.onmouseover=function() + { + if(this.menuRolled===true) + { + dse.className="pm_separatorDOn___"+this.options.theme+" pm_separatorOver___"+this.options.theme; + } + else + { + dse.className="pm_separatorDOff___"+this.options.theme+" pm_separatorOver___"+this.options.theme; + } + }.extend(this,dse); + dse.onmouseout=function() + { + if(this.menuRolled===true) + { + dse.className="pm_separatorDOn___"+this.options.theme+" pm_separatorOut___"+this.options.theme; + } + else + { + dse.className="pm_separatorDOff___"+this.options.theme+" pm_separatorOut___"+this.options.theme; + } + + }.extend(this,dse); + + } + /* Hidden processmaker menu-submenu END*/ + /* Change skin fro processmap BEGIN */ + if (this.options.rw === true) { + var bd = this.parent.dom.capture("tag.body 0"); + var sm = this.parent.dom.element("pm_submenu"); + this.parent.dom.setStyle(bd,{ + backgroundColor:"buttonface" + }); + this.parent.dom.setStyle(sm,{ + //height:(sm.offsetHeight-21) + height:25 + }); + } + + /* Change skin fro processmap END */ + + /* Panel editor */ + + this.panels.editor=new leimnud.module.panel(); + this.panels.editor.options={ + limit:true, + size:{w:this.options.size.w,h:this.options.size.h}, + position:{x:200,y:0,centerX:true}, + title:"", + titleBar:false, + control:{ + //drag :false, + resize:false + }, + fx:{ + opacity:false, + shadow:false, + blinkToFront:false + }, + theme:this.options.theme, + target:this.options.target, + modal:true, + limit:true + }; + this.panels.editor.setStyle={ + content:{ + background:"white url('"+this.options.images_dir+"bg_pm.gif') repeat fixed", + backgroundPosition:"10 0" + }, + containerWindow :{borderWidth:0,padding:0,backgroundColor:"buttonface"}, + titleBar :{background:"transparent",borderWidth:0,height:5}, + frontend :{backgroundColor:"buttonface"}, + backend :{backgroundColor:"buttonface"}, + //statusBar :{border:"0px solid red",position:"absolute",bottom:50,right:10}, + status :{textAlign:"center"} + }; + this.panels.editor.make(); + this.panels.editor.loader.show(); + this.panels.editor.addContentStatus(G_STRINGS.ID_PROCESSMAP_LOADING); + //this.panels.editor.command(); + //this.panels.editor.elements.content.onmousemove=function(){window.status="asdasd";} + //this.parent.exec(this.data.load,false,false,this); + this.data.load(); + if(this.options.rw===true) + { + this.data.render.buildingBlocks.panel(); + } + }, + validate:function() + { + return (!this.options.target || !this.options.dataServer || !this.options.lang)?false:true; + }, + addTask:function(evt,tp) + { + //alert(this.parent.dom.mouse(evt).y) + //alert(this.menu.cursor.x) + //var m = this.parent.dom.mouse(evt); + var options = tp; + var m = this.menu.cursor; + var cpos = this.parent.dom.position(this.panels.editor.elements.content); + + //var index = this.data.db[(options.tp=='task')?'task':'subprocess'].length; + var index = this.data.db['task'].length; + var scl = { + x:this.panels.editor.elements.content.scrollLeft, + y:this.panels.editor.elements.content.scrollTop + }; + var pos = {x:scl.x+(m.x-cpos.x),y:scl.y+(m.y-cpos.y)}; + this.data.db.task[index]={ + position:pos, + label :G_STRINGS.ID_PROCESSMAP_NEW_TASK, + uid :false, + //color :((options.tp=='task')?"#006699":"green"), + task_type:((options.tp=='task')?'NORMAL':'SUBPROCESS'), + derivation:{to:[]} + } + var data = this.data.db.task[index]; + + //this.parent.exec(this.data.build.task,[index],false,this); + + if(options.tp=='task') + { + //this.data.build.task(index,{tp:'task'}); + //console.log(index); + //console.log(this.data.db.task[index]); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=addTask&data="+{uid:this.options.uid,position:pos}.toJSONString() + }); + r.callback=this.parent.closure({instance:this,method:function(index,rpc){ + var rs = rpc.xmlhttp.responseText.parseJSON(); + var data = this.data.db.task[index]; + //console.log(data); + data.uid=rs.uid || false; + data.statusIcons=rs.statusIcons; + this.data.build.task(index,{tp:'task'}); + data.label=data.object.elements.label.innerHTML=rs.label || ""; + },args:[index,r]}); + r.make(); + } + else + { + this.data.build.task(index,{tp:'subprocess'}); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=addSubProcess&data="+{uid:this.options.uid,position:pos}.toJSONString() + }); + r.callback=this.parent.closure({instance:this,method:function(index,rpc){ + var rs = rpc.xmlhttp.responseText.parseJSON(); + var data = this.data.db.task[index]; + data.label=data.object.elements.label.innerHTML=rs.label || ""; + data.uid=rs.uid || false; + },args:[index,r]}); + r.make(); + } + + }, + addText:function(evt) + { + //var panel = + new this.parent.module.app.prompt().make({ + label:G_STRINGS.ID_PROCESSMAP_TEXT, + action:function(text){ + if(text && text.trim()!=="") + { + //var m = this.parent.dom.mouse(evt); + var m = this.menu.cursor; + var cpos = this.parent.dom.position(this.panels.editor.elements.content); + var index = this.data.db.task.length; + var scl = { + x:this.panels.editor.elements.content.scrollLeft, + y:this.panels.editor.elements.content.scrollTop + }; + var pos = {x:scl.x+(m.x-cpos.x),y:scl.y+(m.y-cpos.y)}; + + var index=this.data.db.text.length; + this.data.db.text[index]={ + label :text, + position:{x:pos.x,y:pos.y}, + uid:false + }; + this.data.build.text(index); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=addText&data="+{uid:this.options.uid,label:text,position:{x:pos.x,y:pos.y}}.toJSONString() + }); + r.callback=function(rpc,index){ + var rs = rpc.xmlhttp.responseText.parseJSON(); + this.data.db.text[index].uid=rs.uid; + }.extend(this,index); + r.make(); + } + + }.extend(this) + }); + }, + addGuide:function(evt,dir) + { + //var m = this.parent.dom.mouse(evt); + var m = this.menu.cursor; + var cpos = this.parent.dom.position(this.panels.editor.elements.content); + var index = this.data.db.guide.length; + var scl = { + x:this.panels.editor.elements.content.scrollLeft, + y:this.panels.editor.elements.content.scrollTop + }; + var pos = {x:(m.x-cpos.x),y:(m.y-cpos.y)}; + this.data.db.guide[index]={ + position:((dir==="horizontal")?pos.y+scl.y:pos.x+scl.x), + uid :false, + direction:dir + } + // alert(pos.x+":"+pos.y+":::"+scl.x+":"+scl.y) + var data = this.data.db.guide[index]; + + this.data.build.guide(index); + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=addGuide&data="+{ + uid:this.options.uid, + position:data.position, + direction:data.direction}.toJSONString() + }); + r.callback=function(rpc,index) + { + var rs = rpc.xmlhttp.responseText.parseJSON(); + var data = this.data.db.guide[index]; + data.uid=rs.uid || false; + }.extend(this,index); + r.make(); + } +}; + +/** +* Added By: Erik Amaru Ortiz <erik@colosa.com> +* Comment: This functionality make the window for panel DB Connection. +*/ +var mainPanel; + +function showDbConnectionsList(PRO_UID) +{ + mainPanel = new leimnud.module.panel(); + mainPanel.options = { + size :{w:640,h:450}, + position:{x:0,y:0,center:true}, + title :G_STRINGS.ID_DBS_LIST, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + mainPanel.events = { + remove: function() { delete(mainPanel); }.extend(this) + }; + mainPanel.make(); + mainPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../dbConnections/dbConnectionsAjax', + args: 'action=showDbConnectionsList&PRO_UID='+PRO_UID + }); + oRPC.callback = function(rpc) { + mainPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + mainPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +} + +function showCaseSchedulerList(PRO_UID) +{ + mainPanel = new leimnud.module.panel(); + mainPanel.options = { + size :{w:850,h:570}, + position:{x:0,y:0,center:true}, + title :"Case Scheduler List", + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + mainPanel.events = { + remove: function() { delete(mainPanel); }.extend(this) + }; + mainPanel.make(); + mainPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'processes_Ajax', + args: 'action=case_scheduler&PRO_UID='+PRO_UID + }); + oRPC.callback = function(rpc) { + mainPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + mainPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +} + +function showLogCaseSchedulerList(PRO_UID) +{ + mainPanel = new leimnud.module.panel(); + mainPanel.options = { + size :{w:640,h:450}, + position:{x:0,y:0,center:true}, + title :"Case Scheduler Log List", + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + mainPanel.events = { + remove: function() { delete(mainPanel); }.extend(this) + }; + mainPanel.make(); + mainPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'processes_Ajax', + args: 'action=log_case_scheduler&PRO_UID='+PRO_UID + }); + oRPC.callback = function(rpc) { + mainPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + mainPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +} diff --git a/workflow/engine/js/reports/reports.js b/workflow/engine/js/reports/reports.js new file mode 100644 index 000000000..5955393b9 --- /dev/null +++ b/workflow/engine/js/reports/reports.js @@ -0,0 +1,42 @@ +var panel; +var panDel=function(uid) +{ + panel =new leimnud.module.panel(); + panel.options={ + size :{w:800,h:400}, + position:{x:50,y:50,center:true}, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{shadow:true,modal:true} + }; + panel.make(); + panel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:"reports_Description.php", + method:"POST", + args:"PRO_UID="+uid + }); + r.callback=function(rpc) + { + panel.loader.hide(); + panel.addContent(rpc.xmlhttp.responseText); + }; + r.make(); +}; + + +var reports_Description_filter = function(sFrom, sTo, sStartedby, sProuid) { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../reports/reports_Description', + args : 'action=reports_Description_filter&FROM=' + sFrom + '&TO=' + sTo + '&STARTEDBY=' + sStartedby + '&PRO_UID=' + sProuid + }); + panel.clearContent(); + oRPC.callback=function(rpc) + { + //panel.loader.hide(); + panel.addContent(rpc.xmlhttp.responseText); + }; + oRPC.make(); + + +}; diff --git a/workflow/engine/js/setup/pluginList.js b/workflow/engine/js/setup/pluginList.js new file mode 100644 index 000000000..9facfb5fa --- /dev/null +++ b/workflow/engine/js/setup/pluginList.js @@ -0,0 +1,45 @@ +var plugin; + +/** + * function showMessage + * @author gustavo cruz gustavo-at-colosa-dot-com + * @param message the message to show + * @param pluginUid pluginUid or plugin name + * @desc function that invoques a msgBox call with the removePlugin function + * as argument. + **/ + +function showMessage(message, pluginUid){ + plugin = pluginUid; + msgBox(message, "confirm", removePlugin); +} + +/** + * function removePlugin + * @author gustavo cruz gustavo-at-colosa-dot-com + * @desc function that executes a rpc and takes the server response into + * another message. + **/ + +function removePlugin(){ + var callServer = new leimnud.module.rpc.xmlhttp({ + url : 'pluginsRemove', + async : false, + method : 'POST', + args : 'pluginUid=' + plugin + }); + callServer.make(); + var response = callServer.xmlhttp.responseText; + msgBox(response, 'alert', refresh); +} + +/** + * function refresh + * @author gustavo cruz gustavo-at-colosa-dot-com + * @desc a trivial but necesary function that reload a page, since the msgBox + * can only take functions with no arguments attached. + **/ + +function refresh(){ + location.href = "pluginsList"; +} \ No newline at end of file diff --git a/workflow/engine/js/setup/upgrade_System.js b/workflow/engine/js/setup/upgrade_System.js new file mode 100644 index 000000000..786fc250f --- /dev/null +++ b/workflow/engine/js/setup/upgrade_System.js @@ -0,0 +1,25 @@ +/*upgrade system routine*/ + +function upgradeSystem(wsCount) { + document.getElementById("form[THETITLE3]").innerHTML = wsCount + " workspaces to update."; + document.getElementById("form[SUBTITLE4]").innerHTML = "  <img src='/images/alert.gif' width='13' height='13' border='0'> Please wait..."; + updateWorkspace(wsCount); +}; + +function updateWorkspace(id) { + if(id < 0){ + return false; + } + + var oRPC = new leimnud.module.rpc.xmlhttp({ + async : true, + method: "POST", + url: "../setup/upgrade_SystemAjax", + args : "id=" + id + }); + oRPC.callback = function(rpc) { + document.getElementById("form[SUBTITLE4]").innerHTML = rpc.xmlhttp.responseText; + updateWorkspace(id-1) + }.extend(this); + oRPC.make(); +}; \ No newline at end of file diff --git a/workflow/engine/js/stagesmap/core/stagesmap.js b/workflow/engine/js/stagesmap/core/stagesmap.js new file mode 100644 index 000000000..2fb901a1a --- /dev/null +++ b/workflow/engine/js/stagesmap/core/stagesmap.js @@ -0,0 +1,508 @@ +var stagesmap=function(){ + this.data={ + load:function(){ + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=load&data="+{uid:this.options.uid,mode:this.options.rw}.toJSONString() + }); + r.callback=this.data.render.base; + r.make(); + }, + render:{ + base:function(xml) { + this.panels.editor.loader.hide(); + this.data.db=xml.xmlhttp.responseText.parseJSON().concat({}); + if (this.options.rw===true) { + this.menu = new this.parent.module.app.menuRight(); + this.menu.make({ + target:this.panels.editor.elements.content,//posiblemente hay que cambiar algo aqui para el menu contextual + width:150, + theme:this.options.theme, + menu:[ + {image:"/images/add.png",text:G_STRINGS.ID_PROCESSMAP_ADD_STAGE,launch:this.addStage.extend(this)} + ] + }); + this.observers.menu.register(this.parent.closure({instance:this.menu,method:this.menu.remove}),this.menu); + } + this.data.render.title(); + this.data.render.stage(); + this.data.render.derivation(); + }, + stage:function() { + var lngt = this.data.db.stages.length; + for(var i =0;i<lngt;i++) + { + this.data.build.stage(i); + } + }, + title:function() { + this.data.build.title(); + }, + derivation:function(uid,type) { + for(var i=0;i<this.data.db.stages.length;i++) + { + this.data.render.lineDerivation(i); + } + return true; + }, + lineDerivation:function(index) { + var stage = this.data.db.stages[index]; + for(var j=0;j<stage.derivation.to.length;j++) + { + var derivation = stage.derivation.to[j]; + if(derivation.stage==="-1" || derivation.stage==="-2") + { + var target=(stage.derivation.to.length>1)?'derivationBottom':'derivation'; + this.parent.dom.setStyle(stage.object.elements[target],{ + background:"url("+this.options.images_dir+derivation.stage+((target=="derivationBottom")?"bb.jpg":".gif")+"?aa="+Math.random()+")" + }); + } + else + { + var uid = this.tools.getIndexOfUid(derivation.stage); + var stageF= stage.object.elements; + var stageT= this.data.db.stages[uid].object.elements; + var from = stage.object.elements.derivation; + var toStage=this.data.db.stages[uid]; + var to = toStage.object.elements.stage; + if(stage.derivation.type!==5) + { + this.parent.dom.setStyle(stage.object.elements.derivation,{ + background:"url("+this.options.images_dir+stage.derivation.type+"t.gif?aa="+Math.random()+")" + }); + } + else + { + var ij = toStage.object.inJoin; + ij = (ij)?ij+1:1; + toStage.object.inJoin = ij; + this.parent.dom.setStyle(toStage.object.elements.init,{ + background:"url("+this.options.images_dir+stage.derivation.type+"t.gif?aa="+Math.random()+")", + backgroundPosition:"2 0", + backgroundRepeat:"no-repeat" + }); + } + var line = new this.parent.module.app.line({ + indexRootSize:30, + indexRootLastSize:35, + elements:[stageF.stage,stageT.stage], + envolve:[ + [stageF.stage], + [] + ], + target:this.panels.editor.elements.content, + color:"#228AB0", + startA:50, + zIndex:5 + }); + line.make(); + var cE=this.observers.lineas.register(line.update,line); + derivation.object={ + line : line, + indexObserver : cE + }; + } + } + }, + deleteDerivation:function(uid,rec,spec) { + var stage = this.data.db.stages[this.tools.getIndexOfUid(uid)]; + spec = (typeof spec!=="number")?false:spec; + var deri = stage.derivation; + for(var i=0;i<deri.to.length;i++) + { + if(spec===false || (spec!==false && spec===i)) + { + deri.to[i].object.line.remove(); + this.observers.lineas.unregister(deri.to[i].object.indexObserver); + if(deri.type===5) + { + var toStage = this.data.db.stages[this.tools.getIndexOfUid(deri.to[i].stage)]; + toStage.object.inJoin = toStage.object.inJoin-1; + if(toStage.object.inJoin===0) + { + this.parent.dom.setStyle(toStage.object.elements.init,{ + backgroundPosition:"0 0", + background:"" + }); + } + } + } + } + this.parent.dom.setStyle(stage.object.elements.derivation,{ + background:"" + }); + stage.derivation={to:[]}; + if(rec) + { + var tdb = this.data.db.stages; + for(var i=0;i<tdb.length;i++) + { + var der = tdb[i].derivation.to || []; + for(var j=0;j<der.length;j++) + { + if(der[j].stage===uid) + { + this.data.render.deleteDerivation(tdb[i].uid,false,j); + } + } + } + } + } + }, + build:{ + title:function(index) + { + if(this.data.db.title) + { + var title=this.data.db.title; + var t = document.createElement("div"); + t.className="processmap_title___"+this.options.theme; + this.parent.dom.setStyle(t,{ + top:title.position.y, + left:title.position.x, + cursor:"default" + }); + t.innerHTML=title.label; + this.panels.editor.elements.content.appendChild(t); + title.object={ + elements:{ + label:t + } + } + } + }, + stage:function(index) + { + var options = this.data.db.stages[index]; + var db = this.data.db, stage=db.stages[index]; + var derivation = stage.derivation.to; + var a = document.createElement("div"); + a.className="processmap_task___"+this.options.theme; + this.parent.dom.setStyle(a,{ + top:options.position.y, + left:options.position.x, + cursor:((this.options.rw===true)?"move":"default"), + backgroundColor:(options.color ? options.color : 'auto') + }); + var b = document.createElement("div"); + b.className="processmap_task_label___"+this.options.theme; + this.parent.dom.setStyle(b,{ + cursor:((this.options.rw===true)?"move":"default") + }); + b.innerHTML = options.label; + + var c = document.createElement("div"); + this.parent.dom.setStyle(c,{ + position:"absolute", + top: options.position.y+38, + left:options.position.x+(81-12), + height:25, + width:25, + border:"0px solid black", + overflow:"hidden", + cursor:'default', + zIndex:9 + }); + var d = document.createElement("div"); + this.parent.dom.setStyle(d,{ + position:"absolute", + top: options.position.y+49, + left:options.position.x+(93), + height:38, + width:38, + border:"0px solid black", + overflow:"hidden", + zIndex:9 + }); + var t = document.createElement("div"); + this.parent.dom.setStyle(t,{ + position:"absolute", + top:options.position.y-30, + left:options.position.x+(81-14), + height:30, + width:30, + overflow:"hidden", + zIndex:9 + }); + if(this.options.rw===true) + { + var menu = new this.parent.module.app.menuRight(); + menu.make({ + target:a, + width:201, + theme:this.options.theme, + menu:[ + {image:"/images/edit.gif",text:G_STRINGS.ID_PROCESSMAP_EDIT,launch:function(event,index){ + var panel; + this.tmp.stagePanel = panel = new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:450,h:160}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_EDIT+": "+stage.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{modal:true} + }; + panel.make(); + panel.loader.show(); + var r; + panel.currentRPC = r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=editStage&data="+{ + stg_uid :stage.uid, + pro_uid :this.options.uid, + theindex:index + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this,index)}, + {image:"/images/task.gif",text:G_STRINGS.ID_PROCESSMAP_TASKS_ASSIGNED,launch:function(event,index){ + var panel; + this.tmp.stagePanel = panel = new leimnud.module.panel(); + panel.options={ + limit :true, + size :{w:450,h:400}, + position:{x:50,y:50,center:true}, + title :G_STRINGS.ID_PROCESSMAP_TASKS_ASSIGNED_FOR+": "+stage.label, + theme :this.options.theme, + control :{close:true,resize:false},fx:{modal:true}, + statusBar:false, + fx :{modal:true} + }; + panel.make(); + panel.loader.show(); + var r; + panel.currentRPC = r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=tasksAssigned&data="+{ + stg_uid :stage.uid, + pro_uid :this.options.uid, + theindex:index + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + panel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + panel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + }.extend(this,index)}, + {image:"/images/delete.png",text:G_STRINGS.ID_PROCESSMAP_DELETE_STAGE,launch:this.parent.closure({instance:this,method:function(index){ + var data = this.data.db.stages[index]; + new this.parent.module.app.confirm().make({ + label:G_STRINGS.ID_PROCESSMAP_CONFIRM_DELETE_STAGE+data.label, + action:function() + { + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=deleteStage&data="+{pro_uid:this.options.uid,stg_uid:data.uid}.toJSONString() + }); + r.callback = function() { + this.panels.editor.clearContent(); + this.data.load(); + }.extend(this); + r.make(); + }.extend(this) + }); + },args:index})} + ] + }); + this.observers.menu.register(menu.remove,menu); + } + this.panels.editor.elements.content.appendChild(a); + a.appendChild(b); + this.panels.editor.elements.content.appendChild(c); + this.panels.editor.elements.content.appendChild(d); + this.panels.editor.elements.content.appendChild(t); + + options.object={ + elements:{ + stage : a, + label : b, + derivation: c, + derivationBottom: d, + init : t + } + }; + options.object.dropIndex=this.dropables.derivation.register({ + element : a, + value : index, + events : { + over :this.parent.closure({instance:this.dropables.derivation,method:function(e,o,u){ + this.parent.dom.setStyle(e,{ + border:"1px solid #006699" + }); + },args:[a,options,index]}), + out :this.parent.closure({instance:this.dropables.derivation,method:function(e,o,u){ + this.parent.dom.setStyle(e,{ + border:"0px solid #006699" + }); + },args:[a,options,index]}) + } + }); + if(this.options.rw===true) + { + options.object.drag = new this.parent.module.drag({ + link:{ + elements:a, + ref:[a,c,d,t] + }, + limit:true + }); + this.observers.lineas.register(this.parent.closure({instance:options.object.drag,method:function(){}}),options.object.drag); + options.object.drag.events={ + move :this.parent.closure({instance:this,method:function(div,divC,uid,drag) { + options.object.drag.observer.update(); + var db = this.data.db; + },args:[a,c,index,options.object.drag]}), + + finish :this.parent.closure({instance:this,method:function(div,divC,uid,drag){ + if(!drag.moved){return false;} + var pos = this.parent.dom.position(div); + var h=pos; + var data = this.data.db.stages[uid]; + var db = this.data.db; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=saveStagePosition&data="+{uid:data.uid,position:pos}.toJSONString() + }); + r.make(); + },args:[a,c,index,options.object.drag]}) + }; + options.object.drag.make(); + } + }, + derivation:function(options) + { + tt=options; + var index=this.tools.getIndexOfUid(options.stg_uid); + var from=this.data.db.stages[index]; + this.data.render.deleteDerivation(options.stg_uid); + var affe=options.data; + from.derivation.type=options.type; + for(var i=0;i<affe.length;i++) + { + from.derivation.to[i]={ + stage:affe[i] + }; + } + this.data.render.lineDerivation(index); + } + } + }.expand(this,true); + this.tools={ + getIndexOfUid:function(uid) + { + for(var i=0;i<this.data.db.stages.length;i++) + { + if(this.data.db.stages[i].uid===uid){return i;} + } + }, + getUidOfIndex:function(index) + { + return this.data.db.stages[index].uid || false; + } + }.expand(this); + this.expand(this); +}; + +stagesmap.prototype={ + parent:leimnud, + tmp:{}, + info:{ + name : "stagesmap" + }, + panels:{},dragables:{},dropables:{}, + make:function() { + this.options = { + theme :"firefox", + rw :true, + mi :true, + hideMenu:true + }.concat(this.options || {}); + this.options.target = this.parent.dom.element(this.options.target); + if(!this.validate()){return false;} + this.observers = { + menu : this.parent.factory(this.parent.pattern.observer,true), + lineas : this.parent.factory(this.parent.pattern.observer,true) + }; + this.dropables.derivation = new this.parent.module.drop(); + this.dropables.derivation.make(); + if (this.options.rw === true) { + var bd = this.parent.dom.capture("tag.body 0"); + var sm = this.parent.dom.element("pm_submenu"); + this.parent.dom.setStyle(bd,{ + backgroundColor:"buttonface" + }); + this.parent.dom.setStyle(sm,{ + height:25 + }); + } + this.panels.editor=new leimnud.module.panel(); + this.panels.editor.options={ + limit:true, + size:{w:this.options.size.w,h:this.options.size.h}, + position:{x:200,y:0,centerX:true}, + title:"", + titleBar:false, + control:{ + resize:false + }, + fx:{ + opacity:false, + shadow:false, + blinkToFront:false + }, + theme:this.options.theme, + target:this.options.target, + modal:true, + limit:true + }; + this.panels.editor.setStyle={ + content:{ + background:"white url('"+this.options.images_dir+"bg_pm.gif') repeat fixed", + backgroundPosition:"10 0" + }, + containerWindow :{borderWidth:0,padding:0,backgroundColor:"buttonface"}, + titleBar :{background:"transparent",borderWidth:0,height:5}, + frontend :{backgroundColor:"buttonface"}, + backend :{backgroundColor:"buttonface"}, + status :{textAlign:"center"} + }; + this.panels.editor.make(); + this.panels.editor.loader.show(); + this.data.load(); + }, + validate:function() { + return (!this.options.target || !this.options.dataServer || !this.options.lang)?false:true; + }, + addStage:function(evt) { + var m = this.menu.cursor; + var cpos = this.parent.dom.position($('sm_target')); + var scl = { + x:$('sm_target').scrollLeft, + y:$('sm_target').scrollTop + }; + var pos = {x:scl.x+(m.x-cpos.x)+100,y:scl.y+(m.y-cpos.y)}; + var r = new leimnud.module.rpc.xmlhttp({ + url:this.options.dataServer, + args:"action=addStage&data="+{uid:this.options.uid,position:pos}.toJSONString() + }); + r.callback = function() { + this.panels.editor.clearContent(); + this.data.load(); + }.extend(this); + r.make(); + } +}; \ No newline at end of file diff --git a/workflow/engine/js/tracker/tracker.js b/workflow/engine/js/tracker/tracker.js new file mode 100644 index 000000000..d4d42d007 --- /dev/null +++ b/workflow/engine/js/tracker/tracker.js @@ -0,0 +1,89 @@ +var oLeyendsPanel; + +var showUploadedDocumentTracker = function(APP_DOC_UID) { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:300,h:300}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() { delete(oPanel2); }.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'tracker_Ajax', + args: 'action=showUploadedDocumentTracker&APP_DOC_UID=' + APP_DOC_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var showGeneratedDocumentTracker = function(APP_DOC_UID) { + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:300,h:250}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() { delete(oPanel2); }.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'tracker_Ajax', + args: 'action=showGeneratedDocumentTracker&APP_DOC_UID=' + APP_DOC_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; +/* +var tracker_MessagesView = function(APP_UID) { alert(123); + oPanel2 = new leimnud.module.panel(); + oPanel2.options = { + size :{w:300,h:300}, + position:{x:0,y:0,center:true}, + title :'', + theme :'processmaker', + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel2.events = { + remove: function() { delete(oPanel2); }.extend(this) + }; + oPanel2.make(); + oPanel2.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'tracker_Ajax', + args: 'action=tracker_MessagesView&APP_UID=' + APP_UID + }); + oRPC.callback = function(rpc){ + oPanel2.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel2.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; +*/ \ No newline at end of file diff --git a/workflow/engine/menus/admin.php b/workflow/engine/menus/admin.php new file mode 100755 index 000000000..47da7fe20 --- /dev/null +++ b/workflow/engine/menus/admin.php @@ -0,0 +1,28 @@ +<?php +/** + * setup.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $G_TMP_MENU->AddIdRawOption('ADMIN', 'setup/setup', G::LoadTranslation('ID_ADMIN') ); + + diff --git a/workflow/engine/menus/appFolder.php b/workflow/engine/menus/appFolder.php new file mode 100644 index 000000000..5997e0412 --- /dev/null +++ b/workflow/engine/menus/appFolder.php @@ -0,0 +1,5 @@ +<?php + global $G_TMP_MENU; + $G_TMP_MENU->AddIdRawOption('', 'appFolder/appFolderList', "AppFolder" ); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/backApp.php b/workflow/engine/menus/backApp.php new file mode 100644 index 000000000..b5ba507a4 --- /dev/null +++ b/workflow/engine/menus/backApp.php @@ -0,0 +1,42 @@ +<?php +/** + * backApp.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $G_BACK_PAGE; + +$G_TMP_MENU->AddRawOption( $G_BACK_PAGE); + +switch ( SYS_LANG ) { + case "es" : + $G_TMP_MENU->Labels = Array ( + "Retornar al trámite" + ); + break; + default : + $G_TMP_MENU->Labels = Array ( + "Back to Application" + ); +} +?> diff --git a/workflow/engine/menus/cancel.php b/workflow/engine/menus/cancel.php new file mode 100644 index 000000000..23fccebec --- /dev/null +++ b/workflow/engine/menus/cancel.php @@ -0,0 +1,47 @@ +<?php +/** + * cancel.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $G_BACK_PAGE; + +$G_TMP_MENU->AddRawOption( $G_BACK_PAGE); + +switch ( SYS_LANG ) { + case "es" : + $G_TMP_MENU->Labels = Array ( + "Cancelar" + ); + break; + case "po" : + $G_TMP_MENU->Labels = Array ( + "Cancelar" + ); + break; + default : + $G_TMP_MENU->Labels = Array ( + "Cancel" + ); +} +?> diff --git a/workflow/engine/menus/caseOptions.php b/workflow/engine/menus/caseOptions.php new file mode 100644 index 000000000..9fdd381cd --- /dev/null +++ b/workflow/engine/menus/caseOptions.php @@ -0,0 +1,49 @@ +<?php +/** + * caseOptions.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $G_TMP_MENU; +global $sStatus; + +if ((($sStatus == 'DRAFT') || ($sStatus == 'TO_DO')) && ($_SESSION['TASK'] != -1)) { + if (isset($_SESSION['bNoShowSteps'])) { + unset($_SESSION['bNoShowSteps']); + } + else { + $G_TMP_MENU->AddIdOption('STEPS' , G::LoadTranslation('ID_STEPS') , 'javascript:showSteps();' , 'absolute'); + $G_TMP_MENU->AddIdOption('INFO' , G::LoadTranslation('ID_INFORMATION'), 'javascript:showInformation();', 'absolute'); + } + $G_TMP_MENU->AddIdOption('ACTIONS' , G::LoadTranslation('ID_ACTIONS') , 'javascript:showActions();' , 'absolute'); +} +else { + $G_TMP_MENU->AddIdOption('INFO' , G::LoadTranslation('ID_INFORMATION'), 'javascript:showInformation();', 'absolute'); +} +require_once 'classes/model/Process.php'; +$oProcess = new Process(); +$aProcess = $oProcess->Load($_SESSION['PROCESS']); + +/*if( isset($_SESSION['TRIGGER_DEBUG']['ISSET']) && !isset($_GET['breakpoint']) && $aProcess['PRO_DEBUG']){ + $G_TMP_MENU->AddIdOption('DEBUG' , G::LoadTranslation('ID_DEBUG'), 'javascript:showdebug();', 'absolute'); +}*/ + +?> \ No newline at end of file diff --git a/workflow/engine/menus/caseTracker.php b/workflow/engine/menus/caseTracker.php new file mode 100644 index 000000000..4d45d3eb0 --- /dev/null +++ b/workflow/engine/menus/caseTracker.php @@ -0,0 +1,76 @@ +<?php +/** + * processmaker.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + /* + * Case Tracker Menú + * + * @author Everth S. Berrios Morales <everth@colosa.com> + * + */ +global $G_TMP_MENU; +global $RBAC; + +$G_TMP_MENU->AddIdRawOption('MAP', 'tracker/tracker_ViewMap'); +$G_TMP_MENU->AddIdRawOption('DYNADOC', 'tracker/tracker_DynaDocs'); +$G_TMP_MENU->AddIdRawOption('HISTORY', 'tracker/tracker_History'); +$G_TMP_MENU->AddIdRawOption('MESSAGES', 'tracker/tracker_Messages'); + +$G_TMP_MENU->Labels = array( + G::LoadTranslation('ID_MAP'), + G::LoadTranslation('ID_DYNADOC'), + G::LoadTranslation('ID_HISTORY'), + G::LoadTranslation('ID_HISTORY_MESSAGES') +); + +if ( file_exists ( PATH_CORE . 'menus/plugin.php' ) ) { + require_once ( PATH_CORE . 'menus/plugin.php' ); +} + +G::LoadClass('case'); + $oCase = new Cases(); + $per = $oCase->Permisos( $_SESSION['PROCESS']); + + $p = explode('-', $per); + +if ($p[0] != 1) +{ + $G_TMP_MENU->DisableOptionId('MAP'); +} + +if ($p[1] != 1) +{ + $G_TMP_MENU->DisableOptionId('DYNADOC'); +} + +if ($p[2] != 1) +{ + $G_TMP_MENU->DisableOptionId('HISTORY'); +} + +if ($p[3] != 1) +{ + $G_TMP_MENU->DisableOptionId('MESSAGES'); +} + + diff --git a/workflow/engine/menus/cases.php b/workflow/engine/menus/cases.php new file mode 100644 index 000000000..b7cad9942 --- /dev/null +++ b/workflow/engine/menus/cases.php @@ -0,0 +1,77 @@ +<?php +/** + * cases.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $RBAC; + global $G_TMP_MENU; + + $G_TMP_MENU->AddIdRawOption('CASES_HOME', 'casesStartPage', G::LoadTranslation('ID_CASES_START_PAGE'), '', '', 'blockHeader'); + $G_TMP_MENU->AddIdRawOption('CASES_START_CASE', 'casesStartPage?action=startCase', G::LoadTranslation('ID_NEW_CASE'), '' ); + //$G_TMP_MENU->AddIdRawOption('CASES_FOLDERS', 'casesStartPage?action=documents', G::LoadTranslation('ID_FOLDERS'), 'folderV2.gif' ); + //$G_TMP_MENU->AddIdRawOption('CASES_START_PAGE', 'casesStartPage?action=mainDashboard', ucwords(strtolower(G::LoadTranslation('ID_DASHBOARD'))), '' ); + + //Load Other registered Dashboards (From plugins) + $oPluginRegistry = & PMPluginRegistry::getSingleton (); + $dashBoardPages = $oPluginRegistry->getDashboardPages (); + foreach($dashBoardPages as $key => $tabInfo) { + $tabNameSpace=$tabInfo->sNamespace; + $tabName=$tabInfo->sName; + $tabIcon=str_replace("ICON_","",$tabInfo->sIcon); + if ( $tabName!= "" ) { + $G_TMP_MENU->AddIdRawOption($tabIcon, 'casesStartPage?action='.$tabNameSpace.'-'.$tabName, ucwords(strtolower($tabName)), '' ); + } + } + + $G_TMP_MENU->AddIdRawOption('FOLDERS', '', G::LoadTranslation('ID_CASES_MENU_FOLDERS'), '', '', 'blockHeader'); + $G_TMP_MENU->AddIdRawOption('CASES_INBOX', 'casesListExtJs?action=todo', G::LoadTranslation('ID_INBOX'), 'icon-cases-inbox.png' ); + $G_TMP_MENU->AddIdRawOption('CASES_DRAFT', 'casesListExtJs?action=draft', G::LoadTranslation('ID_DRAFT'), 'mail-mark-task.png' ); + $G_TMP_MENU->AddIdRawOption('CASES_SENT', 'casesListExtJs?action=sent', G::LoadTranslation('ID_SENT'), 'icon-cases-outbox.png'); + $G_TMP_MENU->AddIdRawOption('CASES_SELFSERVICE', 'casesListExtJs?action=selfservice',G::LoadTranslation('ID_UNASSIGNED'), 'rotate_cw.png' ); + $G_TMP_MENU->AddIdRawOption('CASES_PAUSED', 'casesListExtJs?action=paused', G::LoadTranslation('ID_PAUSED'), 'mail-queue.png' ); + //$G_TMP_MENU->AddIdRawOption('CASES_CANCELLED', 'casesListExtJs?action=cancelled', G::LoadTranslation('ID_CANCELLED'), 'edit-clear-list.png' ); + //$G_TMP_MENU->AddIdRawOption('CASES_FOLDERS1', '../appFolder/appFolderList', G::LoadTranslation('ID_FOLDERS'), 'folderV2.gif' ); + + if ( $RBAC->userCanAccess('PM_ALLCASES') == 1 ) { + //$G_TMP_MENU->AddIdRawOption('CASES_GRAL', 'casesListExtJs?action=gral', G::LoadTranslation('ID_GENERAL')); + } + + $G_TMP_MENU->AddIdRawOption('SEARCHS', '', G::LoadTranslation('ID_CASES_MENU_SEARCH'), '', '', 'blockHeader'); + + if ( $RBAC->userCanAccess('PM_ALLCASES') == 1 ) { + $G_TMP_MENU->AddIdRawOption('CASES_SEARCH', 'casesListExtJs?action=search', G::LoadTranslation('ID_ADVANCEDSEARCH'), 'system-search.png' ); + } + + $G_TMP_MENU->AddIdRawOption('ADMIN', '', G::LoadTranslation('ID_CASES_MENU_ADMIN'), '', '', 'blockHeader'); + if ( $RBAC->userCanAccess('PM_SUPERVISOR') == 1 ) { + //$G_TMP_MENU->AddIdRawOption('CASES_TO_REVISE_NORMAL', 'cases_List?l=to_revise', G::LoadTranslation('ID_TO_REVISE'), 'document-review.png' ); + $G_TMP_MENU->AddIdRawOption('CASES_TO_REVISE', 'casesListExtJs?action=to_revise', G::LoadTranslation('ID_TO_REVISE'), 'document-review.png' ); + //$G_TMP_MENU->AddIdRawOption('CASES_SCHEDULER', 'cases_Scheduler_List', G::LoadTranslation('ID_SCHEDULER_LIST' )); + //$G_TMP_MENU->AddIdRawOption('CASES_SCHEDULER_LOG', 'cases_Scheduler_Log', G::LoadTranslation('ID_SCHEDULER_LOG' )); + } + + if ( $RBAC->userCanAccess('PM_REASSIGNCASE') == 1 ) { + //$G_TMP_MENU->AddIdRawOption('CASES_TO_REASSIGN_NORMAL', 'cases_List?l=to_reassign', G::LoadTranslation('ID_TO_REASSIGN'), 'reassing.png' ); + $G_TMP_MENU->AddIdRawOption('CASES_TO_REASSIGN', 'casesListExtJs?action=to_reassign', G::LoadTranslation('ID_TO_REASSIGN'), 'reassing.png' ); + } + + diff --git a/workflow/engine/menus/process.php b/workflow/engine/menus/process.php new file mode 100644 index 000000000..70ba12504 --- /dev/null +++ b/workflow/engine/menus/process.php @@ -0,0 +1,28 @@ +<?php +/** + * process.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +global $G_TMP_MENU; + +?> diff --git a/workflow/engine/menus/processes.php b/workflow/engine/menus/processes.php new file mode 100644 index 000000000..a7d330763 --- /dev/null +++ b/workflow/engine/menus/processes.php @@ -0,0 +1,52 @@ +<?php +/** + * processes.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * RS. + * + * Adicioné un nuevo parámetro en la clase AddIdRawOption en class.menu.php que me ayude + * a colocar una clase al elemento que se encuentra dentro de la lista (generada por el + * submenu). + * + * En este caso seguiremos con el uso del sprite. ss_sprite ss_nombre_archivo + */ +global $G_TMP_MENU; +$G_TMP_MENU_ALIGN = "left"; + +$G_TMP_MENU->AddIdRawOption('DYNAFORMS', '', G::LoadTranslation('ID_DYNAFORMS'),"",'Pm.data.render.buildingBlocks.injector(\'dynaforms\'); return false;','','ss_sprite ss_application_form'); +$G_TMP_MENU->AddIdRawOption('INPUTDOCS', '', G::LoadTranslation('ID_REQUEST_DOCUMENTS'),"",'Pm.data.render.buildingBlocks.injector(\'inputs\'); return false;','','ss_sprite ss_page_white_get'); +$G_TMP_MENU->AddIdRawOption('OUTPUTDOCS', '', G::LoadTranslation('ID_OUTPUT_DOCUMENTS'),"",'Pm.data.render.buildingBlocks.injector(\'outputs\'); return false;','','ss_sprite ss_page_white_put'); +$G_TMP_MENU->AddIdRawOption('TRIGGERS', '', G::LoadTranslation('ID_TRIGGERS'),"",'Pm.data.render.buildingBlocks.injector(\'triggers\'); return false;','','ss_sprite ss_cog'); + +//$G_TMP_MENU->AddIdRawOption('MESSAGES', '', G::LoadTranslation('ID_MESSAGES'),"/images/mail.gif",'Pm.data.render.buildingBlocks.injector(\'messages\'); return false;'); +G::LoadClass('reportTables'); +if (ReportTables::tableExist()) { + $G_TMP_MENU->AddIdRawOption('REPORT_TABLES', '', G::LoadTranslation('ID_REPORT_TABLES'),"",'Pm.data.render.buildingBlocks.injector(\'reportTables\'); return false;','','ss_sprite ss_table'); +} +$G_TMP_MENU->AddIdRawOption('DB_CONNECTIONS', '', G::LoadTranslation('ID_DB_CONNECTIONS'),"",'showDbConnectionsList(Pm.options.uid); return false;','','ss_sprite ss_database_connect'); +$G_TMP_MENU->AddIdRawOption('CASE_SCHEDULER', '', G::LoadTranslation('ID_CASE_SCHEDULER'), "", 'showCaseSchedulerList(Pm.options.uid); return false;','','ss_sprite ss_calendar_view_day'); + + +?> \ No newline at end of file diff --git a/workflow/engine/menus/processmaker.php b/workflow/engine/menus/processmaker.php new file mode 100644 index 000000000..754fae050 --- /dev/null +++ b/workflow/engine/menus/processmaker.php @@ -0,0 +1,60 @@ +<?php +/** + * processmaker.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +# +# ---= Processmaker main menu=--- +# + +global $G_TMP_MENU; +global $RBAC; + +if ($RBAC->userCanAccess('PM_DASHBOARD') == 1 ) { + //$G_TMP_MENU->AddIdRawOption('DASHBOARD', 'dashboard/dashboard', G::LoadTranslation('ID_DASHBOARD')); +} + +#CASES MODULE +if ($RBAC->userCanAccess('PM_CASES') == 1) { + $G_TMP_MENU->AddIdRawOption('CASES', 'cases/main', G::LoadTranslation('ID_CASES')); +} + +#PROCESSES MODULE +if ($RBAC->userCanAccess('PM_FACTORY') == 1 ) { + $G_TMP_MENU->AddIdRawOption('PROCESSES', 'processes/main', G::LoadTranslation('ID_APPLICATIONS')); +} + + +/*if ($RBAC->userCanAccess('PM_REPORTS') == 1 ) { + $G_TMP_MENU->AddIdRawOption('REPORTS', 'reports/reportsList'); +}*/ + +if ($RBAC->userCanAccess('PM_SETUP') == 1 ) { + $G_TMP_MENU->AddIdRawOption('SETUP', 'setup/main', G::LoadTranslation('ID_SETUP')); +} + + +if( file_exists(PATH_CORE . 'menus/plugin.php') ) { + require_once(PATH_CORE . 'menus/plugin.php'); +} \ No newline at end of file diff --git a/workflow/engine/menus/rbac.appEdit.php b/workflow/engine/menus/rbac.appEdit.php new file mode 100644 index 000000000..65c314f8a --- /dev/null +++ b/workflow/engine/menus/rbac.appEdit.php @@ -0,0 +1,64 @@ +<?php +/** + * rbac.appEdit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $HTTP_SESSION_VARS; +$appid = $HTTP_SESSION_VARS['CURRENT_APPLICATION']; + +$G_TMP_MENU->AddIdRawOption( "OP1", "rbac/appList.html" ); +$G_TMP_MENU->AddIdRawOption( "OP2", "rbac/appDel.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Cancelar", + "Eliminar Applicación" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Cancelar", + "Eliminar Application" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Cancel", + "Remove Application" + ); + break; +} + +//si no hay nada relacionado a esta aplicación se puede BORRAR!! +$dbc = new DBConnection(DB_HOST, DB_RBAC_USER, DB_RBAC_PASS, DB_RBAC_NAME ); +//G::LoadClassRBAC ("applications"); +$obj = New RBAC_Application; +$obj->SetTo ($dbc); +$sw = $obj->canRemoveApplication ($appid); +if ($sw > 0) + $G_TMP_MENU->disableOptionId ("OP2"); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.appView.php b/workflow/engine/menus/rbac.appView.php new file mode 100644 index 000000000..0beb33598 --- /dev/null +++ b/workflow/engine/menus/rbac.appView.php @@ -0,0 +1,57 @@ +<?php +/** + * rbac.appView.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $HTTP_SESSION_VARS; + +$G_TMP_MENU->AddIdRawOption( "OP1", "rbac/roleList.html" ); +$G_TMP_MENU->AddIdRawOption( "OP2", "rbac/permList.html" ); +$G_TMP_MENU->AddIdRawOption( "OP3", "rbac/appList.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Ver Roles", + "Ver Permisos", + "Lista de Aplicaciones" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Ver Roles", + "Ver Permisos", + "Lista de Aplicaciones" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "View Roles", + "View Permissions", + "Applications List" + ); + break; +} +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.application.php b/workflow/engine/menus/rbac.application.php new file mode 100644 index 000000000..a2d9100c9 --- /dev/null +++ b/workflow/engine/menus/rbac.application.php @@ -0,0 +1,34 @@ +<?php +/** + * rbac.application.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $canCreateApp; + +$G_TMP_MENU->AddOption( G::LoadMenuXml ('ID_NEW_APPLICATION'), "rbac/appNew.html" ); + +if ( $canCreateApp != 1 ) + $G_TMP_MENU->DisableOptionPos (0); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.authSource.php b/workflow/engine/menus/rbac.authSource.php new file mode 100644 index 000000000..e69b85a68 --- /dev/null +++ b/workflow/engine/menus/rbac.authSource.php @@ -0,0 +1,33 @@ +<?php +/** + * rbac.authSource.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $canCreateApp; + +$G_TMP_MENU->AddOption( G::LoadMenuXml ('ID_EDIT'), "rbac/authEdit.html" ); +$G_TMP_MENU->AddOption( G::LoadMenuXml ('ID_TEST'), "rbac/authTest.html" ); +$G_TMP_MENU->AddOption( G::LoadMenuXml ('ID_ADD_USERS'), "rbac/authAddUser.html" ); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.authentication.php b/workflow/engine/menus/rbac.authentication.php new file mode 100644 index 000000000..13624a6cb --- /dev/null +++ b/workflow/engine/menus/rbac.authentication.php @@ -0,0 +1,33 @@ +<?php +/** + * rbac.authentication.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $canCreateApp; + +$G_TMP_MENU->AddOption( G::LoadMenuXml ('ID_NEW_AUTH_SOURCE'), "rbac/authNew.html" ); + +if ( $canCreateApp != 1 ) + $G_TMP_MENU->DisableOptionPos (0); +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.permission.php b/workflow/engine/menus/rbac.permission.php new file mode 100644 index 000000000..2894cc0ce --- /dev/null +++ b/workflow/engine/menus/rbac.permission.php @@ -0,0 +1,48 @@ +<?php +/** + * rbac.permission.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddRawOption( "rbac/permNew.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Añadir Nuevo Permiso" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Inserir Novo Permisio" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Add New Permission" + ); + break; +} +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.php b/workflow/engine/menus/rbac.php new file mode 100644 index 000000000..d2102f273 --- /dev/null +++ b/workflow/engine/menus/rbac.php @@ -0,0 +1,66 @@ +<?php +/** + * rbac.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddRawOption( "rbac/userList.html" ); +$G_TMP_MENU->AddRawOption( "rbac/appList.html" ); +$G_TMP_MENU->AddRawOption( "rbac/authenticationList.html" ); +$G_TMP_MENU->AddRawOption( "rbac/dbInfo.html" ); +$G_TMP_MENU->AddRawOption( "login/login.html" ); + + +switch( SYS_LANG ) +{ +case 'po': + $G_TMP_MENU->Labels = array( + "Usuarios", + "Applicaciones", + "Authentication Sources", + "Info Database", + "Saír do Sistema" + ); + break; +case 'es': + $G_TMP_MENU->Labels = array( + "Usuarios", + "Applicaciones", + "Fuentes de Autenticación", + "Información de BD", + "Salir del Sistema" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Users", + "Applications", + "Authentication Sources", + "DB Info", + "Logout" + ); + break; +} + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.role.php b/workflow/engine/menus/rbac.role.php new file mode 100644 index 000000000..396d12ce1 --- /dev/null +++ b/workflow/engine/menus/rbac.role.php @@ -0,0 +1,65 @@ +<?php +/** + * rbac.role.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddIdRawOption( "OP1", "rbac/roleNew.html" ); +$G_TMP_MENU->AddIdRawOption( "OP2", "rbac/roleList.html" ); +$G_TMP_MENU->AddIdRawOption( "OP3", "rbac/permList.html" ); +$G_TMP_MENU->AddIdRawOption( "OP4", "rbac/appList.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Añadir Nuevo Rol", + "Ver Roles", + "Ver Permisos", + "Lista de Aplicaciones" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Inserir Novo Rol", + "Ver Roles", + "Ver Permisos", + "Lista de Aplicaciones" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Add New Role", + "View Roles", + "View Permissions", + "Applications List" + ); + break; +} + +global $canCreateRole; +if ($canCreateRole != 1) + $G_TMP_MENU->DisableOptionID ("OP1"); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.user.php b/workflow/engine/menus/rbac.user.php new file mode 100644 index 000000000..4df7f0501 --- /dev/null +++ b/workflow/engine/menus/rbac.user.php @@ -0,0 +1,52 @@ +<?php +/** + * rbac.user.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; +global $canCreateUsers; + +$G_TMP_MENU->AddRawOption( "rbac/userNew.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Añadir Nuevo Usuario" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Inserir Novo Usuario" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Add New User" + ); + break; +} + +if ($canCreateUsers != 1 ) + $G_TMP_MENU->DisableOptionPos(0); +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.userEdit.php b/workflow/engine/menus/rbac.userEdit.php new file mode 100644 index 000000000..350d0f02d --- /dev/null +++ b/workflow/engine/menus/rbac.userEdit.php @@ -0,0 +1,69 @@ +<?php +/** + * rbac.userEdit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddIdRawOption("OP2b", "rbac/userChangeLdap.html" ); +$G_TMP_MENU->AddIdRawOption("OP2c", "rbac/userTestLdap.html" ); +$G_TMP_MENU->AddIdRawOption("OP4", "Javascript:go();", 'absolute' ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "LDAP/AD", + 'Test Login', + "Asignar Roles" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "LDAP/AD", + 'Test Login', + "Asignar Roles" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "LDAP/AD", + 'Test Login', + "Assign Role" + ); + break; +} + +global $access; +global $useLdap; + +if ($access != 1) { + $G_TMP_MENU->DisableOptionId ("OP4"); +} + +if ( ! $useLdap ) { + $G_TMP_MENU->DisableOptionId ("OP2b"); + $G_TMP_MENU->DisableOptionId ("OP2c"); +} + +?> \ No newline at end of file diff --git a/workflow/engine/menus/rbac.userView.php b/workflow/engine/menus/rbac.userView.php new file mode 100644 index 000000000..7953cb89e --- /dev/null +++ b/workflow/engine/menus/rbac.userView.php @@ -0,0 +1,85 @@ +<?php +/** + * rbac.userView.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddIdRawOption("OP1", "rbac/userEdit.html" ); +$G_TMP_MENU->AddIdRawOption("OP2", "rbac/userChangePwd.html" ); +$G_TMP_MENU->AddIdRawOption("OP2b", "rbac/userChangeLdap.html" ); +$G_TMP_MENU->AddIdRawOption("OP2c", "rbac/userTestLdap.html" ); +$G_TMP_MENU->AddIdRawOption("OP3", "rbac/userViewRole.html" ); +$G_TMP_MENU->AddIdRawOption("OP4", "rbac/userAssignRole.html" ); + +switch( SYS_LANG ) +{ +case 'es': + $G_TMP_MENU->Labels = array( + "Editar Usuario", + "Reiniciar Password", + "LDAP/AD", + 'Test Login', + "Ver Roles", + "Asignar Roles" + ); + break; +case 'po': + $G_TMP_MENU->Labels = array( + "Editar Usuario", + "Reiniciar Password", + "LDAP/AD", + 'Test Login', + "Ver Roles", + "Asignar Roles" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "Edit User", + "Reset Password", + "LDAP/AD", + 'Test Login', + "View Roles", + "Assign Role" + ); + break; +} + +global $access; +global $useLdap; + +if ($access != 1) { + $G_TMP_MENU->DisableOptionId ("OP1"); + $G_TMP_MENU->DisableOptionId ("OP2"); + $G_TMP_MENU->DisableOptionId ("OP4"); +} + +if ( $useLdap ) + $G_TMP_MENU->DisableOptionId ("OP2"); +else { + $G_TMP_MENU->DisableOptionId ("OP2b"); + $G_TMP_MENU->DisableOptionId ("OP2c"); +} + +?> \ No newline at end of file diff --git a/workflow/engine/menus/setup.php b/workflow/engine/menus/setup.php new file mode 100644 index 000000000..a5163f7ed --- /dev/null +++ b/workflow/engine/menus/setup.php @@ -0,0 +1,61 @@ +<?php +/** + * setup.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $G_TMP_MENU; +global $RBAC; + +//settings options +$G_TMP_MENU->AddIdRawOption('LOGO', 'uplogo', G::LoadTranslation('ID_LOGO'), 'icon-pmlogo.png', '', 'settings'); +$G_TMP_MENU->AddIdRawOption('EMAILS','emails', G::LoadTranslation('ID_EMAIL'), 'icon-email-settings.png', '', 'settings'); +$G_TMP_MENU->AddIdRawOption('CALENDAR', 'calendarList', G::LoadTranslation('ID_CALENDAR'), 'icon-calendar.png', '', 'settings' ); +//if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) +// $G_TMP_MENU->AddIdRawOption('CASES_LIST_SETUP', '../cases/casesListSetup', G::LoadTranslation('ID_CASES_LIST_SETUP'), "",'', 'settings'); +$G_TMP_MENU->AddIdRawOption('PROCESS_CATEGORY', '../processCategory/processCategoryList', G::LoadTranslation('ID_PROCESS_CATEGORY'), "rules.png",'', 'settings'); +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) + $G_TMP_MENU->AddIdRawOption('LANGUAGES', 'languages', G::LoadTranslation('ID_LANGUAGES'), 'icon-language.png', '', 'settings'); +$G_TMP_MENU->AddIdRawOption('SKINS', 'skinsList', G::LoadTranslation('ID_SKINS'), 'icon-skins.png', '', 'settings'); +$G_TMP_MENU->AddIdRawOption('HEARTBEAT', 'processHeartBeatConfig', G::LoadTranslation('ID_HEARTBEAT_CONFIG'), "heartBeat.jpg",'', 'settings'); +$G_TMP_MENU->AddIdRawOption('ENVIRONMENT_SETTINGS', 'environmentSettings', G::LoadTranslation('ID_ENVIRONMENT_SETTINGS'), "",'', 'settings'); +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) + $G_TMP_MENU->AddIdRawOption('APPCACHEVIEW_SETUP', '../setup/appCacheViewConf', G::LoadTranslation('ID_APPCACHE_SETUP'), "",'', 'settings'); +$G_TMP_MENU->AddIdRawOption('CLEAR_CACHE', 'clearCompiled', G::LoadTranslation('ID_CLEAR_CACHE'), 'icon-rebuild-clean.png', "", 'settings' ); +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) + $G_TMP_MENU->AddIdRawOption('UPGRADE', 'upgrade', G::LoadTranslation('ID_UPGRADE'), 'icon-system-upgrade.png', '', 'settings'); + +if ($RBAC->userCanAccess('PM_SETUP') == 1) + $G_TMP_MENU->AddIdRawOption('ADDITIONAL_TABLES', '../additionalTables/additionalTablesList', G::LoadTranslation('ID_ADDITIONAL_TABLES'), 'icon-tables.png','', 'settings'); +$G_TMP_MENU->AddIdRawOption('WEBSERVICES', 'webServices', G::LoadTranslation('ID_WEB_SERVICES'), 'icon-webservices.png', '', 'settings'); +$G_TMP_MENU->AddIdRawOption('LOG_CASE_SCHEDULER', '../cases/cases_Scheduler_Log', G::LoadTranslation('ID_LOG_CASE_SCHEDULER'), "icon-logs-list.png",'', 'settings'); + + +//tools options +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) + $G_TMP_MENU->AddIdRawOption('PLUGINS', 'pluginsMain', 'Plugins Manager', 'icon-plugins.png', '', 'plugins'); + +//users options +$G_TMP_MENU->AddIdRawOption('USERS', '../users/users_List', G::LoadTranslation('ID_USERS_LIST'), 'icon-webservices.png', '', 'users'); +$G_TMP_MENU->AddIdRawOption('GROUPS', '../groups/groups', G::LoadTranslation('ID_GROUP_USERS'), '', '', 'users'); +$G_TMP_MENU->AddIdRawOption('DEPARTAMENTS', '../departments/departments', G::LoadTranslation('ID_DEPARTMENTS_USERS'), '', '', 'users'); +$G_TMP_MENU->AddIdRawOption('ROLES', '../roles/roles_List', G::LoadTranslation('ID_ROLES'), '', '', 'users'); +$G_TMP_MENU->AddIdRawOption('AUTHSOURCES', '../authSources/authSources_List', G::LoadTranslation('ID_AUTH_SOURCES'), '', '', 'users'); diff --git a/workflow/engine/menus/tools.php b/workflow/engine/menus/tools.php new file mode 100644 index 000000000..0682e259f --- /dev/null +++ b/workflow/engine/menus/tools.php @@ -0,0 +1,29 @@ +<?php +/** + * tools.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_TMP_MENU; + + $G_TMP_MENU->AddIdRawOption('TRANSLATION', 'tools/translations', 'Translations'); + + diff --git a/workflow/engine/menus/toolsTranslations.php b/workflow/engine/menus/toolsTranslations.php new file mode 100644 index 000000000..b0da7eb5c --- /dev/null +++ b/workflow/engine/menus/toolsTranslations.php @@ -0,0 +1,31 @@ +<?php +/** + * toolsTranslations.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_TMP_MENU; + + $G_TMP_MENU->AddIdRawOption('TRANSLATION_LIST', 'tools/translations', 'List'); + $G_TMP_MENU->AddIdRawOption('TRANSLATION_ADD', 'tools/translationsAdd', 'Add field'); + $G_TMP_MENU->AddIdRawOption('TRANSLATION_REBUILD', 'tools/updateTranslation', 'Rebuild'); + +?> \ No newline at end of file diff --git a/workflow/engine/menus/users.php b/workflow/engine/menus/users.php new file mode 100644 index 000000000..5c20f9038 --- /dev/null +++ b/workflow/engine/menus/users.php @@ -0,0 +1,46 @@ +<?php +/** + * users.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $G_TMP_MENU; + +$G_TMP_MENU->AddIdRawOption('USERS', 'users/users_List'); +//$G_TMP_MENU->AddIdRawOption('NEW_USER', 'users/users_New'); +//$G_TMP_MENU->AddIdRawOption('DEPARTMENTS', 'departments/departments_List'); +$G_TMP_MENU->AddIdRawOption('GROUPS', 'groups/groups'); +$G_TMP_MENU->AddIdRawOption('DEPARTMENTS', 'departments/departments'); +$G_TMP_MENU->AddIdRawOption('ROLES', 'roles/roles_List'); +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') == 1) { + $G_TMP_MENU->AddIdRawOption('AUTH_SOURCES', 'authSources/authSources_List'); +} + +$G_TMP_MENU->Labels = array( + G::LoadTranslation('ID_USERS_LIST'), + //G::LoadTranslation('ID_NEW'), + //G::LoadTranslation('ID_ORGANIZATIONAL_CHART'), + G::LoadTranslation('ID_GROUP_USERS'), + G::LoadTranslation('ID_DEPARTMENTS_USERS'), + G::LoadTranslation('ID_ROLES'), + G::LoadTranslation('ID_AUTH_SOURCES') +); \ No newline at end of file diff --git a/workflow/engine/menus/wf.login.php b/workflow/engine/menus/wf.login.php new file mode 100644 index 000000000..f3adba2e7 --- /dev/null +++ b/workflow/engine/menus/wf.login.php @@ -0,0 +1,57 @@ +<?php +/** + * wf.login.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $G_TMP_MENU; + +$G_TMP_MENU->AddRawOption( "login/login.html" ); +$G_TMP_MENU->AddRawOption( "login/dbInfo.html" ); +$G_TMP_MENU->AddRawOption( "login/dbInfo.html" ); + + +switch( SYS_LANG ) +{ +case 'po': + $G_TMP_MENU->Labels = array( + "Login", + "About", + "Case Tracker" + ); + break; +case 'es': + $G_TMP_MENU->Labels = array( + "Iniciar Sesión", + "Acerca de", + "Seguimiento de casos" + ); + break; +default: + $G_TMP_MENU->Labels = array( + "login", + "about" + ); + break; +} + +?> \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesAjax.php b/workflow/engine/methods/additionalTables/additionalTablesAjax.php new file mode 100644 index 000000000..cccad793d --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesAjax.php @@ -0,0 +1,275 @@ +<?php +/** + * additionalTablesAjax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if(isset($_POST['action'])) { + switch ($_POST['action']) { + case 'tableExists': + G::LoadSystem('database_' . strtolower(DB_ADAPTER)); + $oDataBase = new database(DB_ADAPTER, DB_HOST, DB_USER, DB_PASS, DB_NAME); + $oDataBase->iFetchType = MYSQL_NUM; + $oDataset = $oDataBase->executeQuery($oDataBase->generateShowTablesLikeSQL($_POST['sTableName'])); + echo $oDataBase->countResults($oDataset); + break; + case 'classExists': + $sClassName = strtolower(trim($_POST['sClassName'])); + $aDirectories = array(); + $aClasses = array(); + $aDirectories[] = PATH_GULLIVER; + $aDirectories[] = PATH_THIRDPARTY; + $aDirectories[] = PATH_RBAC; + $aDirectories[] = PATH_CORE . 'classes' . PATH_SEP; + foreach ($aDirectories as $sDirectory) { + includeClasses($sDirectory, $aClasses, true); + } + echo (int)class_exists($sClassName); + break; + + case 'exportexporView': + global $G_PUBLISH; + require_once ( 'classes/class.xmlfield_InputPM.php' ); + require_once 'classes/model/AdditionalTables.php'; + + $G_PUBLISH = new Publisher(); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_UID); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_NAME); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_DESCRIPTION); + $oCriteria->add(AdditionalTablesPeer::ADD_TAB_UID, '', Criteria::NOT_EQUAL); + + $G_PUBLISH->AddContent('propeltable', 'additionalTables/paged-table', 'additionalTables/additionalTablesExportList', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + + case 'doExport': + # @Author: Erik Amaru Ortiz <aortiz.erik@gmail.com> + + require_once 'classes/model/AdditionalTables.php'; + + $tables = explode(',', $_POST['tables']); + $schema = explode(',', $_POST['schema']); + $data = explode(',', $_POST['data']); + + G::LoadCLass('net'); + $net = new NET(G::getIpAddress()); + + if( !defined("PM_VERSION")){ + define('PM_VERSION', 'development'); + } + + $META = " \n-----== ProcessMaker Open Source Private Tables ==-----\n". + " @Ver: 1.0 Oct-2009\n". + " @Processmaker version: ".PM_VERSION."\n". + " -------------------------------------------------------\n". + " @Export Date: ".date("l jS \of F Y h:i:s A")."\n". + " @Server address: ".getenv('SERVER_NAME')." (".getenv('SERVER_ADDR').")\n". + " @Client address: ".$net->hostname."\n". + " @Workspace: ".SYS_SYS."\n". + " @Export trace back:\n\n"; + + + $EXPORT_TRACEBACK = Array(); + foreach ($tables as $uid) { + + $aTable = new additionalTables(); + $tRecord = $aTable->load($uid); + $oAdditionalTables = new additionalTables(); + $ocaux = $oAdditionalTables->getDataCriteria($uid); + + $rs = AdditionalTablesPeer::DoSelectRs ($ocaux); + $rs->setFetchmode (ResultSet::FETCHMODE_ASSOC); + + $rows = Array(); + while($rs->next()){ + $rows[] = $rs->getRow(); + } + + array_push($EXPORT_TRACEBACK, Array( + 'uid' => $uid, + 'name' => $tRecord['ADD_TAB_NAME'], + 'num_regs' => sizeof($rows), + 'schema' => in_array($uid, $schema)? 'yes': 'no', + 'data' => in_array($uid, $data)? 'yes': 'no' + )); + } + + $sTrace = "TABLE UID\t\t\t\tTABLE NAME\tREGS\tSCHEMA\tDATA\n"; + foreach($EXPORT_TRACEBACK as $row){ + $sTrace .= "{$row['uid']}\t{$row['name']}\t\t{$row['num_regs']}\t{$row['schema']}\t{$row['data']}\n"; + } + + $META .= $sTrace; + + ///////////////EXPORT PROCESS + $PUBLIC_ROOT_PATH = PATH_DATA.'sites'.PATH_SEP.SYS_SYS.PATH_SEP.'public'.PATH_SEP; + $filenameOnly = 'SYS-'.strtoupper(SYS_SYS)."_".date("Y-m-d").'_'.date("Hi").".pmt"; + $filename = $PUBLIC_ROOT_PATH . $filenameOnly; + $fp = fopen( $filename, "wb"); + $bytesSaved = 0; + + $bufferType = '@META'; + $fsData = sprintf("%09d", strlen($META)); + $fsbufferType = sprintf("%09d", strlen($bufferType)); + $bytesSaved += fwrite($fp, $fsbufferType); //writing the size of $oData + $bytesSaved += fwrite($fp, $bufferType); //writing the $oData + $bytesSaved += fwrite($fp, $fsData); //writing the size of $oData + $bytesSaved += fwrite($fp, $META); //writing the $oData + + foreach($EXPORT_TRACEBACK as $record){ + + if($record['schema'] == 'yes'){ + $oAdditionalTables = new AdditionalTables(); + $aData = $oAdditionalTables->load($record['uid'], true); + + $bufferType = '@SCHEMA'; + $SDATA = serialize($aData); + $fsUid = sprintf("%09d", strlen($record['uid'])); + $fsData = sprintf("%09d", strlen ($SDATA)); + $fsbufferType = sprintf("%09d", strlen($bufferType)); + + $bytesSaved += fwrite($fp, $fsbufferType); //writing the size of $oData + $bytesSaved += fwrite($fp, $bufferType); //writing the $oData + $bytesSaved += fwrite($fp, $fsUid ); //writing the size of xml file + $bytesSaved += fwrite($fp, $record['uid'] ); //writing the xmlfile + $bytesSaved += fwrite($fp, $fsData); //writing the size of xml file + $bytesSaved += fwrite($fp, $SDATA); //writing the xmlfile + } + + if($record['data'] == 'yes'){ + //export data + $oAdditionalTables = new additionalTables(); + $ocaux = $oAdditionalTables->getDataCriteria($record['uid']); + $rs = AdditionalTablesPeer::DoSelectRs ($ocaux); + $rs->setFetchmode (ResultSet::FETCHMODE_ASSOC); + $rows = Array(); + while($rs->next()) $rows[] = $rs->getRow(); + + $bufferType = '@DATA'; + $SDATA = serialize($rows); + $fsUid = sprintf("%09d", strlen($record['name'])); + $fsData = sprintf("%09d", strlen ($SDATA)); + $fsbufferType = sprintf("%09d", strlen($bufferType)); + + $bytesSaved += fwrite($fp, $fsbufferType); //writing the size of $oData + $bytesSaved += fwrite($fp, $bufferType); //writing the $oData + $bytesSaved += fwrite($fp, $fsUid ); //writing the size of xml file + $bytesSaved += fwrite($fp, $record['name'] ); //writing the xmlfile + $bytesSaved += fwrite($fp, $fsData); //writing the size of xml file + $bytesSaved += fwrite($fp, $SDATA); //writing the xmlfile + + } + } + + fclose ($fp); + + $filenameLink = "doExport?f={$filenameOnly}"; + $aFields['SIZE'] = round(($bytesSaved/1024), 2)." Kb"; + $aFields['META'] = "<pre>".$META."</pre>"; + $aFields['FILENAME'] = $filenameOnly; + $aFields['FILENAME_LINK'] = $filenameLink; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/doExport', '', $aFields, ''); + G::RenderPage('publish', 'raw'); + + break; + + } + +} + +if(isset($_POST['function'])) { + $sfunction = $_POST['function']; + switch($sfunction) { + case 'existClass' : + $result = ''; + require_once 'classes/model/AdditionalTables.php'; + $tables = explode(',', $_POST['tables']); + $schema = explode(',', $_POST['schema']); + $data = explode(',', $_POST['data']); + + G::LoadCLass('net'); + $net = new NET(G::getIpAddress()); + if( !defined("PM_VERSION")){ + define('PM_VERSION', 'development'); + } + $EXPORT_TRACEBACK = Array(); + foreach ($tables as $uid) { + $aTable = new additionalTables(); + $tRecord = $aTable->load($uid); + $oAdditionalTables = new additionalTables(); + $ocaux = $oAdditionalTables->checkClassNotExist($uid); + if($ocaux == null ){ + $result = $result . ' <br> ' . $tRecord['ADD_TAB_NAME']; + } + } + return print $result; + break; + } +} + +function includeClasses($sDirectory, &$aClasses, $bRecursive = false) { + $aClassesFilter = array('class.filterForm.php', + 'class.dvEditor.php', + 'class.htmlArea.php', + 'class.database_base.php', + 'class.error.php', + 'class.xmlMenu.php', + 'class.form.php', + 'class.xmlform.php', + 'class.xmlformExtension.php', + 'pakeFileTask.class.php', + 'class.groupUser.php', + 'class.xmlfield_InputPM.php', + 'class.dynaFormField.php', + 'class.toolBar.php'); + $oDirectory = dir($sDirectory); + while ($sObject = $oDirectory->read()) { + if (!in_array($sObject, array('.', '..'))) { + if (is_dir($sDirectory . PATH_SEP . $sObject)) { + if ($bRecursive && ($sObject != 'html2ps_pdf') && ($sObject == 'propel-generator')) { + includeClasses($sDirectory . PATH_SEP . $sObject, $aClasses, true); + } + } + else { + $aAux = pathinfo($sDirectory . PATH_SEP . $sObject); + if (!isset($aAux['extension'])) { + $aAux['extension'] = ''; + } + if (strtolower($aAux['extension']) == 'php') { + try { + if (!in_array($aAux['basename'], $aClassesFilter)) { + @include $sDirectory . PATH_SEP . $sObject; + } + } + catch (Exception $oError) { + //Nothing + } + $aClasses[] = $sObject; + } + } + } + } +} \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesData.php b/workflow/engine/methods/additionalTables/additionalTablesData.php new file mode 100644 index 000000000..48b2dac35 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesData.php @@ -0,0 +1,67 @@ +<?php +/** + * additionalTablesData.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$oAdditionalTables->createXmlList($_GET['sUID']); + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$ocaux = $oAdditionalTables->getDataCriteria($_GET['sUID']); + +$rs = AdditionalTablesPeer::DoSelectRs ($ocaux); +$rs->setFetchmode (ResultSet::FETCHMODE_ASSOC); + +$fieldN = Array('DUMMY'=>'char'); + +$rows = Array(); +while($rs->next()){ + $rows[] = $rs->getRow(); +} + +$rows = array_merge(Array($fieldN), $rows); + +global $_DBArray; +$_DBArray['virtual_pmtable'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; +G::LoadClass('ArrayPeer'); +$oCriteria = new Criteria('dbarray'); +$oCriteria->setDBArrayTable('virtual_pmtable'); + + +$G_PUBLISH = new Publisher; +//$G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesTitle', '', $oAdditionalTables->load($_GET['sUID'])); + +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'xmlLists/' . $_GET['sUID'], $oCriteria, array('ADD_TAB_UID' => $_GET['sUID']), '', '', '', PATH_DYNAFORM); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDataDelete.php b/workflow/engine/methods/additionalTables/additionalTablesDataDelete.php new file mode 100644 index 000000000..47d30902d --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDataDelete.php @@ -0,0 +1,40 @@ +<?php +/** + * additionalTablesDataDelete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$sUID = $_GET['sUID']; +unset($_GET['sUID']); + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +//$oAdditionalTables->deleteDataInTable($_POST['sUID'], $_POST['sPMUID']); +$oAdditionalTables->deleteDataInTable($sUID, $_GET); + +G::header('Location: additionalTablesData?sUID=' . $sUID); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDataEdit.php b/workflow/engine/methods/additionalTables/additionalTablesDataEdit.php new file mode 100644 index 000000000..077bd8e48 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDataEdit.php @@ -0,0 +1,46 @@ +<?php +/** + * additionalTablesDataEdit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$sUID = $_GET['sUID']; +unset($_GET['sUID']); + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$oAdditionalTables->createXmlEdit($sUID, false); + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'xmlLists/' . $sUID . 'Edit', '', $oAdditionalTables->getDataTable($sUID, $_GET), 'additionalTablesUpdateData?sUID=' . $sUID, '', '', PATH_DYNAFORM); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDataImport.php b/workflow/engine/methods/additionalTables/additionalTablesDataImport.php new file mode 100644 index 000000000..210221cf1 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDataImport.php @@ -0,0 +1,63 @@ +<?php +/** + * additionalTablesDataImport.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (preg_match('/[\x00-\x08\x0b-\x0c\x0e\x1f]/', file_get_contents($_FILES['form']['tmp_name']['CSV_FILE'])) === 0) { + if ($oFile = fopen($_FILES['form']['tmp_name']['CSV_FILE'], 'r')) { + require_once 'classes/model/AdditionalTables.php'; + $oAdditionalTables = new AdditionalTables(); + $aAdditionalTables = $oAdditionalTables->load($_POST['form']['ADD_TAB_UID'], true); + $sErrorMessages = ''; + $i = 1; + while (($aAux = fgetcsv($oFile, 4096, $_POST['form']['CSV_DELIMITER'])) !== false) { + if ($i > 1) { + $aData = array(); + $j = 0; + foreach ($aAdditionalTables['FIELDS'] as $aField) { + $aData[$aField['FLD_NAME']] = (isset($aAux[$j]) ? $aAux[$j] : ''); + $j++; + } + try { + if (!$oAdditionalTables->saveDataInTable($_POST['form']['ADD_TAB_UID'], $aData)) { + $sErrorMessages .= G::LoadTranslation('ID_DUPLICATE_ENTRY_PRIMARY_KEY') . ', ' . G::LoadTranslation('ID_LINE') . ' ' . $i . '<br />'; + } + } + catch (Exception $oError) { + $sErrorMessages .= G::LoadTranslation('ID_ERROR_INSERT_LINE') . ': ' . G::LoadTranslation('ID_LINE') . ' ' . $i . '<br />'; + } + } + $i++; + } + fclose($oFile); + } + if ($sErrorMessages != '') { + G::SendMessageText($sErrorMessages, 'warning'); + } + G::header('Location: additionalTablesData?sUID=' . $_POST['form']['ADD_TAB_UID']); + die; +} +else { + G::SendTemporalMessage('ID_UPLOAD_VALID_CSV_FILE', 'error', 'labels'); + G::header('Location: additionalTablesData?sUID=' . $_POST['form']['ADD_TAB_UID']); + die; +} diff --git a/workflow/engine/methods/additionalTables/additionalTablesDataImportForm.php b/workflow/engine/methods/additionalTables/additionalTablesDataImportForm.php new file mode 100644 index 000000000..7535c763e --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDataImportForm.php @@ -0,0 +1,43 @@ +<?php +/** + * additionalTablesDataImportForm.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesTitle', '', $oAdditionalTables->load($_GET['sUID'])); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesDataImportForm', '', array('ADD_TAB_UID' => $_GET['sUID']), '../additionalTables/additionalTablesDataImport'); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDataNew.php b/workflow/engine/methods/additionalTables/additionalTablesDataNew.php new file mode 100644 index 000000000..6ea0932f5 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDataNew.php @@ -0,0 +1,43 @@ +<?php +/** + * additionalTablesDataNew.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$oAdditionalTables->createXmlEdit($_GET['sUID'], true); + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'xmlLists/' . $_GET['sUID'] . 'Edit', '', '', 'additionalTablesSaveData?sUID=' . $_GET['sUID'], '', '', PATH_DYNAFORM); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDelete.php b/workflow/engine/methods/additionalTables/additionalTablesDelete.php new file mode 100644 index 000000000..fbe55d1b3 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDelete.php @@ -0,0 +1,42 @@ +<?php +/** + * additionalTablesDelete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +if (!isset($_POST['sUID'])) { + die; +} + +if ($_POST['sUID'] == '') { + die; +} + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$oAdditionalTables->deleteAll($_POST['sUID']); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesDoImport.php b/workflow/engine/methods/additionalTables/additionalTablesDoImport.php new file mode 100755 index 000000000..68b493da4 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesDoImport.php @@ -0,0 +1,203 @@ +<? +/** + * processes_ImportFile.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * @Author: Erik Amaru Ortiz <aortiz.erik@gmail.com, erik@colosa.com> + */ + +require_once 'classes/model/AdditionalTables.php'; + +try { + + echo '<pre>'; + //print_R($_POST['form']['OVERWRITE']); + + $overWrite = isset($_POST['form']['OVERWRITE'])? true: false; + + //save the file + if ($_FILES['form']['error']['FILENAME'] == 0) { + $PUBLIC_ROOT_PATH = PATH_DATA.'sites'.PATH_SEP.SYS_SYS.PATH_SEP.'public'.PATH_SEP; + + $filename = $_FILES['form']['name']['FILENAME']; + $tempName = $_FILES['form']['tmp_name']['FILENAME']; + G::uploadFile($tempName, $PUBLIC_ROOT_PATH, $filename ); + + $fileContent = file_get_contents($PUBLIC_ROOT_PATH.$filename); + + if(strpos($fileContent, '-----== ProcessMaker Open Source Private Tables ==-----') !== false){ + $oMap = new aTablesMap(); + + $fp = fopen($PUBLIC_ROOT_PATH.$filename, "rb"); + $fsData = intval(fread($fp, 9)); //reading the metadata + $sType = fread($fp, $fsData); //reading string $oData + + require_once 'classes/model/AdditionalTables.php'; + $oAdditionalTables = new AdditionalTables(); + require_once 'classes/model/Fields.php'; + $oFields = new Fields(); + + while ( !feof($fp) ) { + switch($sType){ + case '@META': + $fsData = intval(fread($fp, 9)); + $METADATA = fread($fp, $fsData); + //print_r($METADATA); + break; + case '@SCHEMA': + + $fsUid = intval(fread($fp, 9)); + $uid = fread($fp, $fsUid); + + $fsData = intval(fread($fp, 9)); + $schema = fread($fp, $fsData); + $contentSchema = unserialize($schema); + //print_r($contentSchema); + + if($overWrite){ + $aTable = new additionalTables(); + try{ + $tRecord = $aTable->load($uid); + $aTable->deleteAll($uid); + } catch(Exception $e){ + $tRecord = $aTable->loadByName($contentSchema['ADD_TAB_NAME']); + if($tRecord[0]){ + $aTable->deleteAll($tRecord[0]['ADD_TAB_UID']); + } + } + } else { + #verify if exists some table with the same name + $aTable = new additionalTables(); + $tRecord = $aTable->loadByName("{$contentSchema['ADD_TAB_NAME']}%"); + + if($tRecord){ + $tNameOld = $contentSchema['ADD_TAB_NAME']; + $contentSchema['ADD_TAB_NAME'] = "{$contentSchema['ADD_TAB_NAME']}".sizeof($tRecord); + $contentSchema['ADD_TAB_CLASS_NAME'] = "{$contentSchema['ADD_TAB_CLASS_NAME']}".sizeof($tRecord); + $oMap->addRoute($tNameOld, $contentSchema['ADD_TAB_NAME']); + } + + } + + $sAddTabUid = $oAdditionalTables->create( + array( + 'ADD_TAB_NAME' => $contentSchema['ADD_TAB_NAME'], + 'ADD_TAB_CLASS_NAME' => $contentSchema['ADD_TAB_CLASS_NAME'], + 'ADD_TAB_DESCRIPTION' => $contentSchema['ADD_TAB_DESCRIPTION'], + 'ADD_TAB_SDW_LOG_INSERT' => $contentSchema['ADD_TAB_SDW_LOG_INSERT'], + 'ADD_TAB_SDW_LOG_UPDATE' => $contentSchema['ADD_TAB_SDW_LOG_UPDATE'], + 'ADD_TAB_SDW_LOG_DELETE' => $contentSchema['ADD_TAB_SDW_LOG_DELETE'], + 'ADD_TAB_SDW_LOG_SELECT' => $contentSchema['ADD_TAB_SDW_LOG_SELECT'], + 'ADD_TAB_SDW_MAX_LENGTH' => $contentSchema['ADD_TAB_SDW_MAX_LENGTH'], + 'ADD_TAB_SDW_AUTO_DELETE' => $contentSchema['ADD_TAB_SDW_AUTO_DELETE'], + 'ADD_TAB_PLG_UID' => $contentSchema['ADD_TAB_PLG_UID'] + ), + $contentSchema['FIELDS'] + ); + + + $aFields = array(); + foreach( $contentSchema['FIELDS'] as $iRow => $aRow ){ + unset($aRow['FLD_UID']); + $aRow['ADD_TAB_UID'] = $sAddTabUid; + $oFields->create($aRow); +// print_R($aRow); die; + $aFields[] = array( + 'sType' => $contentSchema['FIELDS'][$iRow]['FLD_TYPE'], + 'iSize' => $contentSchema['FIELDS'][$iRow]['FLD_SIZE'], + 'sFieldName' => $contentSchema['FIELDS'][$iRow]['FLD_NAME'], + 'bNull' => $contentSchema['FIELDS'][$iRow]['FLD_NULL'], + 'bAI' => $contentSchema['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'], + 'bPrimaryKey' => $contentSchema['FIELDS'][$iRow]['FLD_KEY'] + ); + } + $oAdditionalTables->createTable($contentSchema['ADD_TAB_NAME'], 'wf', $aFields); + + for($i=1; $i <= count($contentSchema['FIELDS']); $i++){ + $contentSchema['FIELDS'][$i]['FLD_NULL'] = $contentSchema['FIELDS'][$i]['FLD_NULL'] == '1' ? 'on' : ''; + $contentSchema['FIELDS'][$i]['FLD_AUTO_INCREMENT'] = $contentSchema['FIELDS'][$i]['FLD_AUTO_INCREMENT'] == '1' ? 'on' : ''; + $contentSchema['FIELDS'][$i]['FLD_KEY'] = $contentSchema['FIELDS'][$i]['FLD_KEY'] == '1' ? 'on' : ''; + $contentSchema['FIELDS'][$i]['FLD_FOREIGN_KEY'] = $contentSchema['FIELDS'][$i]['FLD_FOREIGN_KEY'] == '1' ? 'on' : ''; + } + + $oAdditionalTables->createPropelClasses($contentSchema['ADD_TAB_NAME'], $contentSchema['ADD_TAB_CLASS_NAME'], $contentSchema['FIELDS'], $sAddTabUid); + + break; + case '@DATA': + $fstName = intval(fread($fp, 9)); + $tName = fread($fp, $fstName); + $fsData = intval(fread($fp, 9)); + $contentData = unserialize(fread($fp, $fsData)); + + $tName = $oMap->route($tName); + + $oAdditionalTables = new AdditionalTables(); + $tRecord = $oAdditionalTables->loadByName($tName); + + if($tRecord){ + foreach($contentData as $data){ + unset($data['DUMMY']); + $oAdditionalTables->saveDataInTable($tRecord[0]['ADD_TAB_UID'], $data); + } + } + break; + } + $fsData = intval(fread($fp, 9)); + if($fsData > 0){ + $sType = fread($fp, $fsData); + } else { + break; + } + } + + G::header("location: additionalTablesList"); + + } else { + G::SendTemporalMessage ('INVALID_FILE', "Error"); + G::header("location: additionalTablesToImport"); + } + + } +} catch(Exception $e){ + echo $e; +} + + +class aTablesMap{ + var $aMap; + + function route($uid){ + if( isset($this->aMap[$uid]) ){ + return $this->aMap[$uid]; + } else { + return $uid; + } + } + + function addRoute($item, $equal){ + $this->aMap[$item] = $equal; + } + +} + \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesEdit.php b/workflow/engine/methods/additionalTables/additionalTablesEdit.php new file mode 100644 index 000000000..6f6df4ce4 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesEdit.php @@ -0,0 +1,109 @@ +<?php +/** + * additionalTablesEdit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +if (!isset($_GET['sUID'])) { + G::header('Location: additionalTablesList'); + die; +} + +if ($_GET['sUID'] == '') { + G::header('Location: additionalTablesList'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$aData = $oAdditionalTables->load($_GET['sUID'], true); +if ($aData['ADD_TAB_SDW_LOG_INSERT'] == 1) { + $aData['ADD_TAB_SDW_LOG_INSERT'] = 'on'; +} +else { + $aData['ADD_TAB_SDW_LOG_INSERT'] = ''; +} +if ($aData['ADD_TAB_SDW_LOG_UPDATE'] == 1) { + $aData['ADD_TAB_SDW_LOG_UPDATE'] = 'on'; +} +else { + $aData['ADD_TAB_SDW_LOG_UPDATE'] = ''; +} +if ($aData['ADD_TAB_SDW_LOG_DELETE'] == 1) { + $aData['ADD_TAB_SDW_LOG_DELETE'] = 'on'; +} +else { + $aData['ADD_TAB_SDW_LOG_DELETE'] = ''; +} +if ($aData['ADD_TAB_SDW_LOG_SELECT'] == 1) { + $aData['ADD_TAB_SDW_LOG_SELECT'] = 'on'; +} +else { + $aData['ADD_TAB_SDW_LOG_SELECT'] = ''; +} +if ($aData['ADD_TAB_SDW_AUTO_DELETE'] == 1) { + $aData['ADD_TAB_SDW_AUTO_DELETE'] = 'on'; +} +else { + $aData['ADD_TAB_SDW_AUTO_DELETE'] = ''; +} +foreach ($aData['FIELDS'] as $iRow => $aRow) { + if ($aRow['FLD_NULL'] == 1) { + $aData['FIELDS'][$iRow]['FLD_NULL'] = 'on'; + } + else { + $aData['FIELDS'][$iRow]['FLD_NULL'] = ''; + } + if ($aRow['FLD_AUTO_INCREMENT'] == 1) { + $aData['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] = 'on'; + } + else { + $aData['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] = ''; + } + if ($aRow['FLD_KEY'] == 1) { + $aData['FIELDS'][$iRow]['FLD_KEY'] = 'on'; + } + else { + $aData['FIELDS'][$iRow]['FLD_KEY'] = ''; + } + if ($aRow['FLD_FOREIGN_KEY'] == 1) { + $aData['FIELDS'][$iRow]['FLD_FOREIGN_KEY'] = 'on'; + } + else { + $aData['FIELDS'][$iRow]['FLD_FOREIGN_KEY'] = ''; + } +} + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesEdit', '', $aData, '../additionalTables/additionalTablesSave'); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesList.php b/workflow/engine/methods/additionalTables/additionalTablesList.php new file mode 100644 index 000000000..129547be5 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesList.php @@ -0,0 +1,47 @@ +<?php +/** + * additionalTablesList.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AdditionalTables.php'; +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_UID); +$oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_NAME); +$oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_DESCRIPTION); +$oCriteria->add(AdditionalTablesPeer::ADD_TAB_UID, '', Criteria::NOT_EQUAL); + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'admin'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADMIN'; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'additionalTables/additionalTablesList', $oCriteria, '', ''); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesNew.php b/workflow/engine/methods/additionalTables/additionalTablesNew.php new file mode 100644 index 000000000..90670c040 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesNew.php @@ -0,0 +1,39 @@ +<?php +/** + * additionalTablesNew.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesNew', '', '', '../additionalTables/additionalTablesSave'); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesSave.php b/workflow/engine/methods/additionalTables/additionalTablesSave.php new file mode 100644 index 000000000..bd2b8b6a2 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesSave.php @@ -0,0 +1,198 @@ +<?php +/** + * additionalTablesSave.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +unset($_POST['form']['ADD_TAB_NAME_OLD']); +unset($_POST['form']['ADD_TAB_CLASS_NAME_OLD']); +if (!isset($_POST['form']['ADD_TAB_SDW_LOG_INSERT'])) { + $_POST['form']['ADD_TAB_SDW_LOG_INSERT'] = ''; +} +if (!isset($_POST['form']['ADD_TAB_SDW_LOG_UPDATE'])) { + $_POST['form']['ADD_TAB_SDW_LOG_UPDATE'] = ''; +} +if (!isset($_POST['form']['ADD_TAB_SDW_LOG_DELETE'])) { + $_POST['form']['ADD_TAB_SDW_LOG_DELETE'] = ''; +} +if (!isset($_POST['form']['ADD_TAB_SDW_LOG_SELECT'])) { + $_POST['form']['ADD_TAB_SDW_LOG_SELECT'] = ''; +} +if (!isset($_POST['form']['ADD_TAB_SDW_MAX_LENGTH'])) { + $_POST['form']['ADD_TAB_SDW_MAX_LENGTH'] = 0; +} +if (!isset($_POST['form']['ADD_TAB_SDW_AUTO_DELETE'])) { + $_POST['form']['ADD_TAB_SDW_AUTO_DELETE'] = ''; +} +foreach ($_POST['form']['FIELDS'] as $iRow => $aRow) { + if (!isset($_POST['form']['FIELDS'][$iRow]['FLD_NULL'])) { + $_POST['form']['FIELDS'][$iRow]['FLD_NULL'] = ''; + } + if (!isset($_POST['form']['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'])) { + $_POST['form']['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] = ''; + } + if (!isset($_POST['form']['FIELDS'][$iRow]['FLD_KEY'])) { + $_POST['form']['FIELDS'][$iRow]['FLD_KEY'] = ''; + } + if (!isset($_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY'])) { + $_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY'] = ''; + } + if (!isset($_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY_TABLE'])) { + $_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY_TABLE'] = ''; + } +} +$aKeys = array(); +$aDynavars = array(); +$aNoKeys = array(); +foreach ($_POST['form']['FIELDS'] as $aRow) { + if ($aRow['FLD_KEY'] == 'on') { + $aKeys[] = $aRow; + if(isset($aRow['CASE_VARIABLE'])) + $aDynavars[] = array('FLD_UID'=>$aRow['FLD_UID'],'CASE_VARIABLE'=>$aRow['CASE_VARIABLE']); + else + $aDynavars[] = array('FLD_UID'=>$aRow['FLD_UID'],'CASE_VARIABLE'=>''); + } + else { + $aNoKeys[] = $aRow; + } +} +//print_r($_POST); +$aDynavars = serialize($aDynavars); +//var_dump($aKeys); +//print_r($aDynavars); +//die; +$_POST['form']['FIELDS'] = array(); +$i = 1; +foreach ($aKeys as $aRow) { + $_POST['form']['FIELDS'][$i] = $aRow; + $i++; +} +foreach ($aNoKeys as $aRow) { + $_POST['form']['FIELDS'][$i] = $aRow; + $i++; +} + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +require_once 'classes/model/Fields.php'; +$oFields = new Fields(); + +if ($_POST['form']['ADD_TAB_UID'] == '') { + + // We verified that the table does not exist. + $aNameTable = $oAdditionalTables->loadByName($_POST['form']['ADD_TAB_NAME']); + if(is_array($aNameTable)) { + G::SendMessageText('There is already a table named "' . $_POST['form']['ADD_TAB_NAME'] . '" in the database. Table creation canceled.', 'warning'); + G::header('Location: additionalTablesList'); + die; + } + // Reserved Words + $aReservedWords = array ('ALTER', 'CLOSE', 'COMMIT', 'CREATE', 'DECLARE', + 'DELETE', 'DROP', 'FETCH', 'FUNCTION', 'GRANT', + 'INDEX', 'INSERT', 'OPEN', 'REVOKE', 'ROLLBACK', + 'SELECT', 'SYNONYM', 'TABLE', 'UPDATE', 'VIEW' ); + if (in_array(strtoupper($_POST['form']['ADD_TAB_NAME']), $aReservedWords) ) { + G::SendMessageText('Could not create the table with the name "' . $_POST['form']['ADD_TAB_NAME'] . '" because it is a reserved word.', 'warning'); + G::header('Location: additionalTablesList'); + die; + } + + $sAddTabUid = $oAdditionalTables->create(array('ADD_TAB_NAME' => $_POST['form']['ADD_TAB_NAME'], + 'ADD_TAB_CLASS_NAME' => $_POST['form']['ADD_TAB_CLASS_NAME'], + 'ADD_TAB_DESCRIPTION' => $_POST['form']['ADD_TAB_DESCRIPTION'], + 'ADD_TAB_SDW_LOG_INSERT' => ($_POST['form']['ADD_TAB_SDW_LOG_INSERT'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_UPDATE' => ($_POST['form']['ADD_TAB_SDW_LOG_UPDATE'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_DELETE' => ($_POST['form']['ADD_TAB_SDW_LOG_DELETE'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_SELECT' => ($_POST['form']['ADD_TAB_SDW_LOG_SELECT'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_MAX_LENGTH' => $_POST['form']['ADD_TAB_SDW_MAX_LENGTH'], + 'ADD_TAB_SDW_AUTO_DELETE' => ($_POST['form']['ADD_TAB_SDW_AUTO_DELETE'] == 'on' ? 1 : 0), + 'ADD_TAB_DYNAVARS' => $aDynavars, + 'ADD_TAB_PLG_UID' => ''), $_POST['form']['FIELDS']); + $aFields = array(); + /*$aFields[] = array('sType' => 'INT', + 'iSize' => '11', + 'sFieldName' => 'PM_UNIQUE_ID', + 'bNull' => 0, + 'bAI' => 1, + 'bPrimaryKey' => 1);*/ + foreach ($_POST['form']['FIELDS'] as $iRow => $aRow) { + $oFields->create(array('FLD_INDEX' => $iRow, + 'ADD_TAB_UID' => $sAddTabUid, + 'FLD_NAME' => $_POST['form']['FIELDS'][$iRow]['FLD_NAME'], + 'FLD_DESCRIPTION' => $_POST['form']['FIELDS'][$iRow]['FLD_DESCRIPTION'], + 'FLD_TYPE' => $_POST['form']['FIELDS'][$iRow]['FLD_TYPE'], + 'FLD_SIZE' => $_POST['form']['FIELDS'][$iRow]['FLD_SIZE'], + 'FLD_NULL' => ($_POST['form']['FIELDS'][$iRow]['FLD_NULL'] == 'on' ? 1 : 0), + 'FLD_AUTO_INCREMENT' => ($_POST['form']['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0), + 'FLD_KEY' => ($_POST['form']['FIELDS'][$iRow]['FLD_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY' => ($_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY_TABLE' => $_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY_TABLE'])); + $aFields[] = array('sType' => $_POST['form']['FIELDS'][$iRow]['FLD_TYPE'], + 'iSize' => $_POST['form']['FIELDS'][$iRow]['FLD_SIZE'], + 'sFieldName' => $_POST['form']['FIELDS'][$iRow]['FLD_NAME'], + 'bNull' => ($_POST['form']['FIELDS'][$iRow]['FLD_NULL'] == 'on' ? 1 : 0), + 'bAI' => ($_POST['form']['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0), + 'bPrimaryKey' => ($_POST['form']['FIELDS'][$iRow]['FLD_KEY'] == 'on' ? 1 : 0)); + } + $oAdditionalTables->createTable($_POST['form']['ADD_TAB_NAME'], 'wf', $aFields); + $oAdditionalTables->createPropelClasses($_POST['form']['ADD_TAB_NAME'], $_POST['form']['ADD_TAB_CLASS_NAME'], $_POST['form']['FIELDS'], $sAddTabUid); +} +else { + $aData = $oAdditionalTables->load($_POST['form']['ADD_TAB_UID'], true); + $oAdditionalTables->update(array('ADD_TAB_UID' => $_POST['form']['ADD_TAB_UID'], + 'ADD_TAB_NAME' => $_POST['form']['ADD_TAB_NAME'], + 'ADD_TAB_CLASS_NAME' => $_POST['form']['ADD_TAB_CLASS_NAME'], + 'ADD_TAB_DESCRIPTION' => $_POST['form']['ADD_TAB_DESCRIPTION'], + 'ADD_TAB_SDW_LOG_INSERT' => ($_POST['form']['ADD_TAB_SDW_LOG_INSERT'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_UPDATE' => ($_POST['form']['ADD_TAB_SDW_LOG_UPDATE'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_DELETE' => ($_POST['form']['ADD_TAB_SDW_LOG_DELETE'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_LOG_SELECT' => ($_POST['form']['ADD_TAB_SDW_LOG_SELECT'] == 'on' ? 1 : 0), + 'ADD_TAB_SDW_MAX_LENGTH' => $_POST['form']['ADD_TAB_SDW_MAX_LENGTH'], + 'ADD_TAB_SDW_AUTO_DELETE' => ($_POST['form']['ADD_TAB_SDW_AUTO_DELETE'] == 'on' ? 1 : 0), + 'ADD_TAB_DYNAVARS' => $aDynavars, + 'ADD_TAB_PLG_UID' => ''), $_POST['form']['FIELDS']); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(FieldsPeer::ADD_TAB_UID, $_POST['form']['ADD_TAB_UID']); + FieldsPeer::doDelete($oCriteria); + $aNewFields = array(); + foreach ($_POST['form']['FIELDS'] as $iRow => $aField) { + $sUID = $oFields->create(array('FLD_UID' => $_POST['form']['FIELDS'][$iRow]['FLD_UID'], + 'ADD_TAB_UID' => $_POST['form']['ADD_TAB_UID'], + 'FLD_INDEX' => $iRow, + 'FLD_NAME' => $_POST['form']['FIELDS'][$iRow]['FLD_NAME'], + 'FLD_DESCRIPTION' => $_POST['form']['FIELDS'][$iRow]['FLD_DESCRIPTION'], + 'FLD_TYPE' => $_POST['form']['FIELDS'][$iRow]['FLD_TYPE'], + 'FLD_SIZE' => $_POST['form']['FIELDS'][$iRow]['FLD_SIZE'], + 'FLD_NULL' => ($_POST['form']['FIELDS'][$iRow]['FLD_NULL'] == 'on' ? 1 : 0), + 'FLD_AUTO_INCREMENT' => ($_POST['form']['FIELDS'][$iRow]['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0), + 'FLD_KEY' => ($_POST['form']['FIELDS'][$iRow]['FLD_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY' => ($_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY_TABLE' => $_POST['form']['FIELDS'][$iRow]['FLD_FOREIGN_KEY_TABLE'])); + $aNewFields[$sUID] = $aField; + } + $aOldFields = array(); + foreach ($aData['FIELDS'] as $aField) { + $aOldFields[$aField['FLD_UID']] = $aField; + } + $oAdditionalTables->updateTable($_POST['form']['ADD_TAB_NAME'], 'wf', $aNewFields, $aOldFields); + $oAdditionalTables->createPropelClasses($_POST['form']['ADD_TAB_NAME'], $_POST['form']['ADD_TAB_CLASS_NAME'], $_POST['form']['FIELDS'], $aData['ADD_TAB_UID']); +} +G::header('Location: additionalTablesList'); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesSaveData.php b/workflow/engine/methods/additionalTables/additionalTablesSaveData.php new file mode 100644 index 000000000..374e2a911 --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesSaveData.php @@ -0,0 +1,34 @@ +<?php +/** + * additionalTablesSaveData.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +unset($_POST['form']['btnSave']); + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +if (!$oAdditionalTables->saveDataInTable($_GET['sUID'], $_POST['form'])) { + G::SendTemporalMessage('ID_DUPLICATE_ENTRY_PRIMARY_KEY', 'warning'); +} + +G::header('Location: additionalTablesData?sUID=' . $_GET['sUID']); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/additionalTablesToImport.php b/workflow/engine/methods/additionalTables/additionalTablesToImport.php new file mode 100755 index 000000000..87f93a31d --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesToImport.php @@ -0,0 +1,59 @@ +<?php +/** + * processes_DownloadFile.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //add more security, and catch any error or exception + +/* + * Author Erik Amaru Ortiz <aortiz.erik@gmail.com, erik@colosa.com> + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +//$G_ID_SUB_MENU_SELECTED = 'ADDITIONAL_TABLES'; + +$POST_MAX_SIZE = ini_get('post_max_size'); + $mul = substr($POST_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $postMaxSize = (int)$POST_MAX_SIZE * $mul; + + $UPLOAD_MAX_SIZE = ini_get('upload_max_filesize'); + $mul = substr($UPLOAD_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $uploadMaxSize = (int)$UPLOAD_MAX_SIZE * $mul; + + if ( $postMaxSize < $uploadMaxSize ) $uploadMaxSize = $postMaxSize; + $Fields['MAX_FILE_SIZE'] = $uploadMaxSize . " (" . $UPLOAD_MAX_SIZE . ") "; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'additionalTables/additionalTablesToImport.xml', '', $Fields, 'additionalTablesDoImport'); + G::RenderPage('publishBlank', 'blank'); diff --git a/workflow/engine/methods/additionalTables/additionalTablesUpdateData.php b/workflow/engine/methods/additionalTables/additionalTablesUpdateData.php new file mode 100644 index 000000000..a50b4e8ec --- /dev/null +++ b/workflow/engine/methods/additionalTables/additionalTablesUpdateData.php @@ -0,0 +1,32 @@ +<?php +/** + * additionalTablesUpdateData.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +unset($_POST['form']['btnSave']); + +require_once 'classes/model/AdditionalTables.php'; +$oAdditionalTables = new AdditionalTables(); +$oAdditionalTables->updateDataInTable($_GET['sUID'], $_POST['form']); + +G::header('Location: additionalTablesData?sUID=' . $_GET['sUID']. '&r='.rand()); \ No newline at end of file diff --git a/workflow/engine/methods/additionalTables/doExport.php b/workflow/engine/methods/additionalTables/doExport.php new file mode 100755 index 000000000..27443e34b --- /dev/null +++ b/workflow/engine/methods/additionalTables/doExport.php @@ -0,0 +1,37 @@ +<?php +/** + * processes_DownloadFile.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //add more security, and catch any error or exception + +/* + * Author Erik Amaru Ortiz <aortiz.erik@gmail.com, erik@colosa.com> + * + */ + + $PUBLIC_ROOT_PATH = PATH_DATA.'sites'.PATH_SEP.SYS_SYS.PATH_SEP.'public'.PATH_SEP; + $sFileName = $_GET['f']; + + $realPath = $PUBLIC_ROOT_PATH . $sFileName; + G::streamFile ( $realPath, true ); + unlink($realPath); \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderAjax.php b/workflow/engine/methods/appFolder/appFolderAjax.php new file mode 100755 index 000000000..b6106d8c1 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderAjax.php @@ -0,0 +1,305 @@ +<?php + +//if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; +G::LoadInclude ( 'ajax' ); +$_POST ['action'] = get_ajax_value ( 'action' ); + +require_once ("classes/model/AppFolder.php"); + +$oPMFolder = new AppFolder ( ); + +$rootFolder = "/"; +switch ($_POST ['action']) { + + case 'expandNode': + $folderList = $oPMFolder->getFolderList ( $_POST ['node'] != 'root' ? $_POST ['node'] == 'NA' ? "" : $_POST ['node'] : $rootFolder ); + $folderContent = $oPMFolder->getFolderContent ( $_POST ['node'] != 'root' ? $_POST ['node'] == 'NA' ? "" : $_POST ['node'] : $rootFolder ); + //G::pr($folderContent); + $processListTree=array(); + foreach ( $folderList as $key => $obj ) { + $tempTree ['text'] = $obj['FOLDER_NAME']; + $tempTree ['id'] = $obj['FOLDER_UID']; + $tempTree ['folderID'] = $obj['FOLDER_UID']; + $tempTree ['cls'] = 'folder'; + $tempTree ['draggable'] = true; + //$tempTree ['leaf'] = true; + //$tempTree ['optionType'] = "category"; + //$tempTree['allowDrop']=false; + $tempTree ['singleClickExpand'] = true; + /* + if ($key != "No Category") { + $tempTree ['expanded'] = true; + } else { + //$tempTree ['expanded'] = false; + $tempTree ['expanded'] = true; + } + */ + $processListTree [] = $tempTree; + } + foreach ( $folderContent as $key => $obj ) { + $tempTree ['text'] = $obj['APP_DOC_FILENAME']; + $tempTree ['id'] = $obj['APP_DOC_UID']; + + $tempTree ['cls'] = 'file'; + //$tempTree ['draggable'] = true; + $tempTree ['leaf'] = true; + //$tempTree ['optionType'] = "category"; + //$tempTree['allowDrop']=false; + //$tempTree ['singleClickExpand'] = true; + /* + if ($key != "No Category") { + $tempTree ['expanded'] = true; + } else { + //$tempTree ['expanded'] = false; + $tempTree ['expanded'] = true; + } + */ + $processListTree [] = $tempTree; + } + print G::json_encode ( $processListTree ); + break; + case 'openPMFolder' : + $WIDTH_PANEL = 350; + G::LoadClass ( 'tree' ); + $folderContent = $oPMFolder->getFolderList ( $_POST ['folderID'] != '0' ? $_POST ['folderID'] == 'NA' ? "" : $_POST ['folderID'] : $rootFolder ); + //krumo($folderContent); + if (! is_array ( $folderContent )) { + echo $folderContent; + exit (); + } + + $tree = new Tree ( ); + $tree->name = 'DMS'; + $tree->nodeType = "blank"; + + //$tree->width="350px"; + $tree->value = ''; + $tree->showSign = false; + + $i = 0; + foreach ( $folderContent as $key => $obj ) { + $i ++; + //if($obj->item_type=="F"){ + + + $RowClass = ($i % 2 == 0) ? 'Row1' : 'Row2'; + $id_delete = G::LoadTranslation('ID_DELETE'); + $id_edit = G::LoadTranslation('ID_EDIT'); + + $htmlGroup = <<<GHTML + <table cellspacing='0' cellpadding='0' border='1' style='border:0px;' width="100%" class="pagedTable"> + <tr id="{$i}" onmouseout="setRowClass(this, '{$RowClass}')" onmouseover="setRowClass(this, 'RowPointer' )" class="{$RowClass}" style="cursor:hand"> + <td width='' class='treeNode' style='border:0px;background-color:transparent;'><a href="#" onclick="focusRow(this, 'Selected');openPMFolder('{$obj['FOLDER_UID']}','{$_POST['rootfolder']}');"> + <img src="/images/folderV2.gif" border = "0" valign="middle" /> {$obj['FOLDER_NAME']}</a> + <a href="#" onclick="deletePMFolder('{$obj['FOLDER_UID']}','{$_POST['rootfolder']}');">  {$id_delete}</a> + </td> + </tr> + </table> + <div id="child_{$obj['FOLDER_UID']}"></div> +GHTML; + + $ch = & $tree->addChild ( $key, $htmlGroup, array ('nodeType' => 'child' ) ); + $ch->point = ' '; + + } + $RowClass = ($i % 2 == 0) ? 'Row1' : 'Row2'; + $key = 0; + if ($_POST ['folderID'] == '0') { + $notInFolderLabel = G::LoadTranslation ( 'ID_NOT_IN_FOLDER' ); + $htmlGroup = <<<GHTML + <table cellspacing='0' cellpadding='0' border='1' style='border:0px;' width="100%" class="pagedTable"> + <tr id="{$i}" onclick="focusRow(this, 'Selected');openPMFolder('NA');" onmouseout="setRowClass(this, '{$RowClass}')" onmouseover="setRowClass(this, 'RowPointer' )" class="{$RowClass}"> + <td width='' class='treeNode' style='border:0px;background-color:transparent;'><a href="#" onclick=""><img src="/images/folderV2.gif" border = "0" valign="middle" /> - {$notInFolderLabel} -</a> </td> + + </tr> + </table> + <div id="child_NA"></div> +GHTML; + + $ch = & $tree->addChild ( $key, $htmlGroup, array ('nodeType' => 'child' ) ); + $ch->point = ' '; + } + + print ($tree->render ()) ; + + break; + case 'getPMFolderContent' : + $swSearch = false; + + if (isset ( $_POST ['folderID'] )) { //Render content of a folder + $folderID = $_POST ['folderID'] != '0' ? $_POST ['folderID'] == 'NA' ? "" : $_POST ['folderID'] : $rootFolder; + $folderContent = $oPMFolder->getFolderContent ( $folderID ); + } else { // Perform a Search + $swSearch = true; + $folderContent = $oPMFolder->getFolderContent ( NULL, array (), $_POST ['searchKeyword'], $_POST ['type'] ); + } + array_unshift ( $folderContent, array ('id' => 'char' ) ); + if (! is_array ( $folderContent )) { + echo $folderContent; + exit (); + } + + $_DBArray ['PM_FOLDER_DOC'] = $folderContent; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'PM_FOLDER_DOC' ); + $c->addAscendingOrderByColumn ( 'id' ); + $G_PUBLISH = new Publisher ( ); + require_once ('classes/class.xmlfield_InputPM.php'); + + $labelFolderAddFile = ""; + $labelFolderAddFolder = ""; + if ($RBAC->userCanAccess ( 'PM_FOLDERS_ADD_FILE' ) == 1) { + $labelFolderAddFile = G::LoadTranslation ( 'ID_ATTACH' ); + } + if ($RBAC->userCanAccess ( 'PM_FOLDERS_ADD_FOLDER' ) == 1) { + $labelFolderAddFolder = G::LoadTranslation ( 'ID_NEW_FOLDER' ); + } + + if (! $swSearch) { + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'appFolder/appFolderDocumentList', $c, array ('folderID' => $_POST ['folderID'] != '0' ? $_POST ['folderID'] == 'NA' ? "/" : $_POST ['folderID'] : $rootFolder, 'labelFolderAddFile' => $labelFolderAddFile, 'labelFolderAddFolder' => $labelFolderAddFolder ) ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'appFolder/appFolderDocumentListHeader', '', array (), 'appFolderList?folderID=' . $_POST ['folderID'] ); + } else { + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'appFolder/appFolderDocumentListSearch', $c, array () ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'appFolder/appFolderDocumentListHeader', '', array (), 'appFolderList?folderID=/' ); + } + + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "getPMFolderTags" : + // Default font sizes + $min_font_size = 12; + $max_font_size = 30; + + $rootFolder = "/"; + $folderID = $_POST ['rootFolder'] != '0' ? $_POST ['rootFolder'] == 'NA' ? "" : $_POST ['rootFolder'] : $rootFolder; + $tags = $oPMFolder->getFolderTags ( $folderID ); + $minimum_count = 0; + $maximum_count = 0; + if ((is_array ( $tags )) && (count ( $tags ) > 0)) { + $minimum_count = min ( array_values ( $tags ) ); + $maximum_count = max ( array_values ( $tags ) ); + } + $spread = $maximum_count - $minimum_count; + + if ($spread == 0) { + $spread = 1; + } + + $cloud_html = ''; + $cloud_tags = array (); // create an array to hold tag code + foreach ( $tags as $tag => $count ) { + $href = "#"; + //$href="?q="$tag; + $size = $min_font_size + ($count - $minimum_count) * ($max_font_size - $min_font_size) / $spread; + $cloud_tags [] = '<a style="font-size: ' . floor ( $size ) . 'px' . '" class="tag_cloud" href="' . $href . '" onClick="getPMFolderSearchResult(\'' . $tag . '\',\'TAG\')"' . ' title="\'' . $tag . '\' returned a count of ' . $count . '">' . htmlspecialchars ( stripslashes ( $tag ) ) . '</a>'; + } + $cloud_html = join ( "\n", $cloud_tags ) . "\n"; + + print "$cloud_html"; + + break; + + case "uploadDocument" : + //krumo($_POST); + G::LoadClass ( 'case' ); + $oCase = new Cases ( ); + + $G_PUBLISH = new Publisher ( ); + $Fields ['DOC_UID'] = $_POST ['docID']; + $Fields ['APP_DOC_UID'] = $_POST ['appDocId']; + $Fields ['actionType'] = $_POST ['actionType']; + $Fields ['docVersion'] = $_POST ['docVersion']; + + $Fields ['appId'] = $_POST ['appId']; + $Fields ['docType'] = $_POST ['docType']; + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'cases/cases_AttachInputDocumentGeneral', '', $Fields, 'appFolderSaveDocument?UID=' . $_POST ['docID'] . '&appId=' . $_POST ['appId'] . '&docType=' . $_POST ['docType'] ); + G::RenderPage ( 'publish', 'raw' ); + + break; + case "documentVersionHistory" : + + $folderID = $_POST ['folderID'] != '0' ? $_POST ['folderID'] == 'NA' ? "" : $_POST ['folderID'] : $rootFolder; + $folderContent = $oPMFolder->getFolderContent ( $folderID, array ($_POST ['appDocId'] ) ); + + array_unshift ( $folderContent, array ('id' => 'char' ) ); + if (! is_array ( $folderContent )) { + echo $folderContent; + exit (); + } + + $_DBArray ['PM_FOLDER_DOC_HISTORY'] = $folderContent; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'PM_FOLDER_DOC_HISTORY' ); + $c->addAscendingOrderByColumn ( 'id' ); + $G_PUBLISH = new Publisher ( ); + require_once ('classes/class.xmlfield_InputPM.php'); + + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'appFolder/appFolderDocumentListHistory', $c, array ('folderID' => $_POST ['folderID'] != '0' ? $_POST ['folderID'] == 'NA' ? "/" : $_POST ['folderID'] : $rootFolder ) ); + + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "uploadExternalDocument" : + G::LoadClass ( 'case' ); + $oCase = new Cases ( ); + + $G_PUBLISH = new Publisher ( ); + $Fields ['DOC_UID'] = "-1"; + + $Fields ['appId'] = "00000000000000000000000000000000"; + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'cases/cases_AttachInputDocumentGeneral', '', $Fields, 'appFolderSaveDocument?UID=-1&appId=' . $Fields ['appId'] . "&folderId=" . $_POST ['folderID'] ); + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "newFolder" : + $oFolder = new AppFolder ( ); + $folderStructure = $oPMFolder->getFolderStructure ( $_POST ['folderID'] ); + $Fields ['FOLDER_PATH'] = $folderStructure ['PATH']; + $Fields ['FOLDER_PARENT_UID'] = $_POST ['folderID']; + $Fields ['FOLDER_UID'] = G::GenerateUniqueID (); + $G_PUBLISH = new Publisher ( ); + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'appFolder/appFolderEdit', '', $Fields, 'appFolderSave' ); + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "documentInfo" : + $oFolder = new AppFolder ( ); + $Fields = $oPMFolder->getCompleteDocumentInfo ( $_POST ['appId'], $_POST ['appDocId'], $_POST ['docVersion'], $_POST ['docID'], $_POST ['usrUid'] ); + $G_PUBLISH = new Publisher ( ); + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'appFolder/appFolderDocumentInfo', '', $Fields, '' ); + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "documentdelete": + include_once ("classes/model/AppDocument.php"); + $oAppDocument = new AppDocument ( ); + $oAppDocument->remove($_POST['sFileUID'],$_POST['docVersion']); + /*we need to delete fisicaly the file use the follow code + $appId= "00000000000000000000000000000000"; + $sPathName = PATH_DOCUMENT . $appId . PATH_SEP; + unlink($sPathName.$_POST['sFileUID'].'_1.jpg');*/ + break; + + case "deletePMFolder": + include_once ("classes/model/AppFolder.php"); + $oAppFoder = new AppFolder ( ); + $oAppFoder->remove($_POST['sFileUID'],$_POST['rootfolder']); + + break; + +} \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderDelete.php b/workflow/engine/methods/appFolder/appFolderDelete.php new file mode 100644 index 000000000..ed9ee949f --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderDelete.php @@ -0,0 +1,38 @@ +<?php + + //to do: improve the way to pass two or more parameters in the paged-table ( link ) + + $aux = explode ( '|', $_GET['id'] ); + $index=0; + $FolderUid = str_replace ( '"', '', $aux[$index++] ); + + + require_once ( "classes/model/AppFolder.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = AppFolderPeer::retrieveByPK( $FolderUid ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'AppFolder' ) ) { + $fields['FOLDER_UID'] = $tr->getFolderUid(); + $fields['LABEL_FOLDER_UID'] = $tr->getFolderUid(); + $fields['FOLDER_PARENT_UID'] = $tr->getFolderParentUid(); + $fields['LABEL_FOLDER_PARENT_UID'] = $tr->getFolderParentUid(); + $fields['FOLDER_NAME'] = $tr->getFolderName(); + $fields['LABEL_FOLDER_NAME'] = $tr->getFolderName(); + $fields['FOLDER_CREATE_DATE'] = $tr->getFolderCreateDate(); + $fields['LABEL_FOLDER_CREATE_DATE'] = $tr->getFolderCreateDate(); + $fields['FOLDER_UPDATE_DATE'] = $tr->getFolderUpdateDate(); + $fields['LABEL_FOLDER_UPDATE_DATE'] = $tr->getFolderUpdateDate(); + } + else + $fields = array(); + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'appFolder'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'appFolder/appFolderDelete', '', $fields, 'appFolderDeleteExec' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderDeleteExec.php b/workflow/engine/methods/appFolder/appFolderDeleteExec.php new file mode 100644 index 000000000..3612c7948 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderDeleteExec.php @@ -0,0 +1,25 @@ + <?php + try { + + $form = $_POST['form']; + $FolderUid = $form['FOLDER_UID']; + + + require_once ( "classes/model/AppFolder.php" ); + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = AppFolderPeer::retrieveByPK( $FolderUid ); + if ( ( is_object ( $tr ) && get_class ($tr) == 'AppFolder' ) ) { + $tr->delete(); + } + + G::Header('location: appFolderList'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderEdit.php b/workflow/engine/methods/appFolder/appFolderEdit.php new file mode 100644 index 000000000..67985442d --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderEdit.php @@ -0,0 +1,30 @@ +<?php + + $aux = explode ( '|', isset($_GET['id']) ? $_GET['id'] : '' ); + $FolderUid = str_replace ( '"', '', $aux[0] ); + + + require_once ( "classes/model/AppFolder.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = AppFolderPeer::retrieveByPK( $FolderUid ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'AppFolder' ) ) { + $fields['FOLDER_UID'] = $tr->getFolderUid(); + $fields['FOLDER_PARENT_UID'] = $tr->getFolderParentUid(); + $fields['FOLDER_NAME'] = $tr->getFolderName(); + $fields['FOLDER_CREATE_DATE'] = $tr->getFolderCreateDate(); + $fields['FOLDER_UPDATE_DATE'] = $tr->getFolderUpdateDate(); + } + else + $fields = array(); + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'appFolder'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'appFolder/appFolderEdit', '', $fields, 'appFolderSave' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderList.php b/workflow/engine/methods/appFolder/appFolderList.php new file mode 100644 index 000000000..0aec98a26 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderList.php @@ -0,0 +1,59 @@ +<?php + + try { + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = ''; + $G_ID_MENU_SELECTED = 'FOLDERS'; + $G_ID_SUB_MENU_SELECTED = ''; + + $G_PUBLISH = new Publisher; + + + if((isset($_POST['form']['FOLDER_UID']))&&(isset($_POST['form']['MOVE_FOLDER_PATH']))){ + require_once ( "classes/model/AppDocument.php" ); + $oAppDocument = new AppDocument(); + + //Move files to another FOLDER_UID' + $folderUid=$_POST['form']['FOLDER_UID']; + $filesArrayAux=explode(";",$_POST['form']['MOVE_FOLDER_PATH']); + $filesArray=array(); + foreach($filesArrayAux as $value){ + if($value!=""){ + $valueAux=explode("|",$value); + $filesArray[$valueAux[1]]=$valueAux[0]; + } + } + foreach($filesArray as $keyDoc => $sw){ + if($sw=="true"){ + $keyDocArray=explode("_",$keyDoc); + $aFields = array('APP_DOC_UID' => $keyDocArray[0], + 'DOC_VERSION' => $keyDocArray[1], + 'FOLDER_UID' => $folderUid); + $oAppDocument->update($aFields); + } + } + } + +//$rootFolder='5320083284b210ceb511e43070218744'; +$rootFolder='0'; +//$rootFolder='4977070264b54bf093aef68069996372'; + + + $G_PUBLISH->AddContent('view', 'appFolder/appFolderTree' ); + $G_PUBLISH->AddContent('smarty', 'appFolder/appFolderFileList', '', '', array()); + G::RenderPage( "publish-treeview" , 'blank'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + ?> +<script> + + + openPMFolder('<?php echo $rootFolder ?>','<?php echo $rootFolder ?>'); + </script> \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderNew.php b/workflow/engine/methods/appFolder/appFolderNew.php new file mode 100644 index 000000000..d61978ae6 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderNew.php @@ -0,0 +1,23 @@ +<?php + + + require_once ( "classes/model/AppFolder.php" ); + + + $fields['FOLDER_UID'] = G::GenerateUniqueID();; + + $fields['FOLDER_PARENT_UID'] = ''; + $fields['FOLDER_NAME'] = ''; + $fields['FOLDER_CREATE_DATE'] = ''; + $fields['FOLDER_UPDATE_DATE'] = ''; + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'appFolder'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'appFolder/appFolderEdit', '', $fields, 'appFolderSave' ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderSave.php b/workflow/engine/methods/appFolder/appFolderSave.php new file mode 100644 index 000000000..94e99c639 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderSave.php @@ -0,0 +1,53 @@ + <?php + try { + $form = $_POST['form']; + $FolderUid = $form['FOLDER_UID']; + $FolderParentUid = $form['FOLDER_PARENT_UID']; + $FolderName = $form['FOLDER_NAME']; + $FolderCreateDate = 'now'; + $FolderUpdateDate = 'now'; + + + require_once ( "classes/model/AppFolder.php" ); + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = AppFolderPeer::retrieveByPK( $FolderUid ); + if ( ! ( is_object ( $tr ) && get_class ($tr) == 'AppFolder' ) ) { + $tr = new AppFolder(); + } + $tr->setFolderUid( $FolderUid ); + $tr->setFolderParentUid( $FolderParentUid ); + $tr->setFolderName( $FolderName ); + $tr->setFolderCreateDate( $FolderCreateDate ); + $tr->setFolderUpdateDate( $FolderUpdateDate ); + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "<br/>"; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + //to do: uniform coderror structures for all classes + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + G::Header('location: appFolderList'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/appFolder/appFolderSaveDocument.php b/workflow/engine/methods/appFolder/appFolderSaveDocument.php new file mode 100755 index 000000000..c52bde7d3 --- /dev/null +++ b/workflow/engine/methods/appFolder/appFolderSaveDocument.php @@ -0,0 +1,165 @@ +<? +/** + * cases_SaveDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + try { + $docUid=$_POST['form']['DOC_UID']; + $appDocUid=$_POST['form']['APP_DOC_UID']; + $docVersion=$_POST['form']['docVersion']; + $actionType=$_POST['form']['actionType']; + + $appId=$_GET['appId']; + $docType=isset($_GET['docType'])?$_GET['docType']:""; + + //save info + + require_once ( "classes/model/AppDocument.php" ); + require_once ('classes/model/AppFolder.php'); + require_once ('classes/model/InputDocument.php'); + + $oInputDocument = new InputDocument(); + if($_GET['UID']!=-1){ + $aID = $oInputDocument->load($_GET['UID']); + }else{ + $oFolder=new AppFolder(); + $folderStructure=$oFolder->getFolderStructure(isset($_GET['folderId'])?$_GET['folderId']:"/"); + $aID=array('INP_DOC_DESTINATION_PATH'=>$folderStructure['PATH']); + } + + + $oAppDocument = new AppDocument(); + + + //Get the Custom Folder ID (create if necessary) + $oFolder=new AppFolder(); + if($_GET['UID']!=-1){ + //krumo("jhl"); + $folderId=$oFolder->createFromPath($aID['INP_DOC_DESTINATION_PATH'],$appId); + //Tags + $fileTags=$oFolder->parseTags($aID['INP_DOC_TAGS'],$appId); + }else{ + $folderId=isset($_GET['folderId'])?$_GET['folderId']:"/"; + $fileTags="EXTERNAL"; + } + switch($actionType){ + case "R": //replace + $aFields = array('APP_DOC_UID' => $appDocUid, + 'APP_UID' => $appId, + 'DOC_VERSION' => $docVersion, + 'DEL_INDEX' => 1, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + + $oAppDocument->update($aFields); + break; + case "NV": //New Version + + + $aFields = array('APP_DOC_UID' => $appDocUid, + 'APP_UID' => $appId, + + 'DEL_INDEX' => 1, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + $oAppDocument->create($aFields); + break; + default: //New + $aFields = array('APP_UID' => $appId, + 'DEL_INDEX' => isset($_SESSION['INDEX'])?$_SESSION['INDEX']:1, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + + $oAppDocument->create($aFields); + break; + } + + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $iDocVersion = $oAppDocument->getDocVersion(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + $ext = (isset($info['extension']) ? $info['extension'] : ''); + + //save the file + if (!empty($_FILES['form'])) { + if ($_FILES['form']['error']['APP_DOC_FILENAME'] == 0) { + $sPathName = PATH_DOCUMENT . $appId . PATH_SEP; + $sFileName = $sAppDocUid . "_".$iDocVersion. '.' . $ext; + G::uploadFile($_FILES['form']['tmp_name']['APP_DOC_FILENAME'], $sPathName, $sFileName ); + + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT ) && class_exists ('uploadDocumentData' ) ) { + + $oData['APP_UID'] = $appId; + $documentData = new uploadDocumentData ( + $appId, + $_SESSION['USER_LOGGED'], + $sPathName . $sFileName, + $aFields['APP_DOC_FILENAME'], + $sAppDocUid + ); + + $oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + unlink ( $sPathName . $sFileName ); + } + //end plugin + } + } + + + + G::header('location: appFolderList'); + die; + + + } catch ( Exception $e ) { + /* Render Error page */ + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_Ajax.php b/workflow/engine/methods/authSources/authSources_Ajax.php new file mode 100644 index 000000000..be2d8ce9b --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_Ajax.php @@ -0,0 +1,102 @@ +<?php +/** + * authSources_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + } + + switch ($_POST['action']) { + case 'searchUsers': + G::LoadThirdParty('pear/json','class.json'); + require_once 'classes/model/Users.php'; + $oJSON = new Services_JSON(); + $i = 0; + $oUser = new Users(); + $aAux = $RBAC->searchUsers($_POST['sUID'], $_POST['sKeyword']); + $aUsers = array(); + // note added by gustavo cruz gustavo-at-colosa.com + // changed the user data showed to accept FirstName and LastName variables + $aUsers[] = array('Checkbox' => 'char', + 'Username' => 'char', + 'FullName' => 'char', + 'FirstName' => 'char', + 'LastName' => 'char', + 'Email' => 'char', + 'DistinguishedName' => 'char'); + foreach ($aAux as $aUser) { + if (UsersPeer::doCount($oUser->loadByUsername($aUser['sUsername'])) == 0) { + // add replace to change D'Souza to D*Souza by krlos + $sCheckbox = '<input type="checkbox" name="aUsers[' . $i . ']" id="aUsers[' . $i . ']" value=\'' . str_replace( "\'","*", addslashes($oJSON->encode($aUser)) ) . '\' />'; + $i++; + } + else { + $sCheckbox = G::LoadTranslation('ID_USER_REGISTERED') . ':<br />(' . $aUser['sUsername'] . ')'; + } + // note added by gustavo cruz gustavo-at-colosa.com + // assign the user data to the DBArray variable. + $aUsers[] = array('Checkbox' => $sCheckbox, + 'Username' => $aUser['sUsername'], + 'FullName' => $aUser['sFullname'], + 'FirstName' => $aUser['sFirstname'], + 'LastName' => $aUser['sLastname'], + 'Email' => $aUser['sEmail'], + 'DistinguishedName' => $aUser['sDN']); + } + global $_DBArray; + $_DBArray['users'] = $aUsers; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('users'); + + $aFields = $RBAC->getAuthSource($_POST['sUID']); + + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + if ($aFields['AUTH_SOURCE_PROVIDER'] != 'ldap') { + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'authSources/ldapSearchResults', $oCriteria); + } + else { + if (file_exists(PATH_XMLFORM . 'authSources/' . $aFields['AUTH_SOURCE_PROVIDER'] . 'Edit.xml')) { + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'authSources/' . $aFields['AUTH_SOURCE_PROVIDER'] . 'SearchResults', $oCriteria); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', array('MESSAGE' => 'File: ' . $aFields['AUTH_SOURCE_PROVIDER'] . 'SearchResults.xml' . ' not exists.')); + } + } + G::RenderPage('publish', 'raw'); + break; + } +} +catch ( Exception $e ) { + $fields = array('MESSAGE' => $e->getMessage() ); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $fields ); + G::RenderPage('publish', 'blank'); +} diff --git a/workflow/engine/methods/authSources/authSources_Delete.php b/workflow/engine/methods/authSources/authSources_Delete.php new file mode 100644 index 000000000..05c580c24 --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_Delete.php @@ -0,0 +1,32 @@ +<?php +/** + * authSources_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$RBAC->removeAuthSource($_POST['AUTH_SOURCE_UID']); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_Edit.php b/workflow/engine/methods/authSources/authSources_Edit.php new file mode 100644 index 000000000..3d0a26d47 --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_Edit.php @@ -0,0 +1,69 @@ +<?php +/** + * authSources_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +if (!isset($_GET['sUID'])) { + G::SendTemporalMessage('ID_ERROR_OBJECT_NOT_EXISTS', 'error', 'labels'); + G::header('location: authSources_List'); + die; +} + +if ($_GET['sUID'] == '') { + G::SendTemporalMessage('ID_ERROR_OBJECT_NOT_EXISTS', 'error', 'labels'); + G::header('location: authSources_List'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'AUTH_SOURCES'; + +$aFields = $RBAC->getAuthSource($_GET['sUID']); +if (is_array($aFields['AUTH_SOURCE_DATA'])) { + foreach($aFields['AUTH_SOURCE_DATA'] as $sField => $sValue) { + $aFields[$sField] = $sValue; + } +} +unset($aFields['AUTH_SOURCE_DATA']); + +$G_PUBLISH = new Publisher(); +if ($aFields['AUTH_SOURCE_PROVIDER'] == 'ldap') { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/ldapEdit', '', $aFields, '../authSources/authSources_Save'); +} +else { + if (file_exists(PATH_XMLFORM . 'authSources/' . $aFields['AUTH_SOURCE_PROVIDER'] . 'Edit.xml')) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/' . $aFields['AUTH_SOURCE_PROVIDER'] . 'Edit', '', $aFields, '../authSources/authSources_Save'); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', array('MESSAGE' => 'File: ' . $aFields['AUTH_SOURCE_PROVIDER'] . 'Edit.xml' . ' not exists.')); + } +} +G::RenderPage('publish','blank'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_ImportUsers.php b/workflow/engine/methods/authSources/authSources_ImportUsers.php new file mode 100644 index 000000000..98d2299ae --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_ImportUsers.php @@ -0,0 +1,73 @@ +<?php +/** + * authSources_ImportUsers.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$aFields = $RBAC->getAuthSource($_POST['form']['AUTH_SOURCE_UID']); + +G::LoadThirdParty('pear/json','class.json'); +$oJSON = new Services_JSON(); + +foreach($_POST['aUsers'] as $sUser) { + $matches = array(); + $aUser = (array)$oJSON->decode(stripslashes($sUser)); + $aData['USR_USERNAME'] = str_replace("*","'",$aUser['sUsername']); + $aData['USR_PASSWORD'] = md5(str_replace("*","'",$aUser['sUsername'])); + // note added by gustavo gustavo-at-colosa.com + // asign the FirstName and LastName variables + // add replace to change D*Souza to D'Souza by krlos + $aData['USR_FIRSTNAME'] = str_replace("*","'",$aUser['sFirstname']); + $aData['USR_LASTNAME'] = str_replace("*","'",$aUser['sLastname'] ); + $aData['USR_EMAIL'] = $aUser['sEmail']; + $aData['USR_DUE_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 2)); + $aData['USR_CREATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_BIRTHDAY'] = date('Y-m-d'); + $aData['USR_STATUS'] = 1; + $aData['USR_AUTH_TYPE'] = strtolower($aFields['AUTH_SOURCE_PROVIDER']); + $aData['UID_AUTH_SOURCE'] = $aFields['AUTH_SOURCE_UID']; + // validating with regexp if there are some missing * inside the DN string + // if it's so the is changed to the ' character + preg_match('/[a-zA-Z]\*[a-zA-Z]/',$aUser['sDN'],$matches); + foreach ($matches as $key => $match){ + $newMatch = str_replace('*', '\'', $match); + $aUser['sDN'] = str_replace($match,$newMatch,$aUser['sDN']); + } + $aData['USR_AUTH_USER_DN'] = $aUser['sDN']; + $sUserUID = $RBAC->createUser($aData, 'PROCESSMAKER_OPERATOR'); + $aData['USR_STATUS'] = 'ACTIVE'; + $aData['USR_UID'] = $sUserUID; + $aData['USR_PASSWORD'] = md5($sUserUID);//fake :p + $aData['USR_ROLE'] = 'PROCESSMAKER_OPERATOR'; + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $oUser->create($aData); +} + +G::header('Location: ../users/users_List'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_List.php b/workflow/engine/methods/authSources/authSources_List.php new file mode 100644 index 000000000..41f8131d9 --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_List.php @@ -0,0 +1,40 @@ +<?php +/** + * authSources_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'AUTH_SOURCES'; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'authSources/authSources_List', $RBAC->getAllAuthSources(), '', ''); +G::RenderPage('publish','blank'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_New.php b/workflow/engine/methods/authSources/authSources_New.php new file mode 100644 index 000000000..e6619e8ea --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_New.php @@ -0,0 +1,51 @@ +<?php +/** + * authSources_New.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'AUTH_SOURCES'; + +$aFields = array('AUTH_SOURCE_PROVIDER' => $_POST['form']['AUTH_SOURCE_PROVIDER']); + +$G_PUBLISH = new Publisher(); +if ($_POST['form']['AUTH_SOURCE_PROVIDER'] == 'ldap') { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/ldapEdit', '', $aFields, '../authSources/authSources_Save'); +} +else { + if (file_exists(PATH_XMLFORM . 'authSources/' . $_POST['form']['AUTH_SOURCE_PROVIDER'] . 'Edit.xml')) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/' . $_POST['form']['AUTH_SOURCE_PROVIDER'] . 'Edit', '', $aFields, '../authSources/authSources_Save'); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', array('MESSAGE' => 'File: ' . $_POST['form']['AUTH_SOURCE_PROVIDER'] . 'Edit.xml' . ' not exists.')); + } +} +G::RenderPage('publish','blank'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_Save.php b/workflow/engine/methods/authSources/authSources_Save.php new file mode 100644 index 000000000..f34574146 --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_Save.php @@ -0,0 +1,65 @@ +<?php +/** + * authSources_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +unset($_POST['form']['btnSave']); + +$aCommonFields = array('AUTH_SOURCE_UID', + 'AUTH_SOURCE_NAME', + 'AUTH_SOURCE_PROVIDER', + 'AUTH_SOURCE_SERVER_NAME', + 'AUTH_SOURCE_PORT', + 'AUTH_SOURCE_ENABLED_TLS', + 'AUTH_ANONYMOUS', + 'AUTH_SOURCE_SEARCH_USER', + 'AUTH_SOURCE_PASSWORD', + 'AUTH_SOURCE_VERSION', + 'AUTH_SOURCE_BASE_DN', + 'AUTH_SOURCE_OBJECT_CLASSES', + 'AUTH_SOURCE_ATTRIBUTES'); +$aFields = $aData = array(); +foreach ($_POST['form'] as $sField => $sValue) { + if (in_array($sField, $aCommonFields)) { + $aFields[$sField] = $sValue; + } + else { + $aData[$sField] = $sValue; + } +} +$aFields['AUTH_SOURCE_DATA'] = $aData; + +if ($aFields['AUTH_SOURCE_UID'] == '') { + $RBAC->createAuthSource($aFields); +} +else { + $RBAC->updateAuthSource($aFields); +} + +G::header('location: authSources_List'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_SearchUsers.php b/workflow/engine/methods/authSources/authSources_SearchUsers.php new file mode 100644 index 000000000..accc8fc64 --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_SearchUsers.php @@ -0,0 +1,39 @@ +<?php +/** + * authSources_SearchUsers.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'AUTH_SOURCES'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/authSources_SearchUsers', '', array('AUTH_SOURCE_UID' => $_GET['sUID']), '../authSources/authSources_ImportUsers'); +G::RenderPage('publish','blank'); \ No newline at end of file diff --git a/workflow/engine/methods/authSources/authSources_SelectType.php b/workflow/engine/methods/authSources/authSources_SelectType.php new file mode 100644 index 000000000..cd2bc499e --- /dev/null +++ b/workflow/engine/methods/authSources/authSources_SelectType.php @@ -0,0 +1,53 @@ +<?php +/** + * authSources_SelectType.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'AUTH_SOURCES'; + +$aAuthSourceTypes = array(array('sType' => 'char', 'sLabel' => 'char')); +$oDirectory = dir(PATH_RBAC . 'plugins' . PATH_SEP); +while($sObject = $oDirectory->read()) { + if (($sObject != '.') && ($sObject != '..') && ($sObject != '.svn') && ($sObject != 'ldap')) { + if (is_file(PATH_RBAC . 'plugins' . PATH_SEP . $sObject)) { + $sType = trim(str_replace('class.', '', str_replace('.php', '', $sObject))); + $aAuthSourceTypes[] = array('sType' => $sType, 'sLabel' => $sType); + } + } +} +global $_DBArray; +$_DBArray['authSourceTypes'] = $aAuthSourceTypes; +$_SESSION['_DBArray'] = $_DBArray; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'authSources/authSources_SelectType', '', '', '../authSources/authSources_New'); +G::RenderPage('publish','blank'); diff --git a/workflow/engine/methods/cases/casesDemo.php b/workflow/engine/methods/cases/casesDemo.php new file mode 100644 index 000000000..6ac60175b --- /dev/null +++ b/workflow/engine/methods/cases/casesDemo.php @@ -0,0 +1,169 @@ +<?php +/** + * casesDemo.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + +$rows[] = array ( 'uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); +$rows[] = array ( 'uid' => 11, 'name' => 'john', 'age' => 44, 'balance' => 123423 ); +$rows[] = array ( 'uid' => 22, 'name' => 'bobby', 'age' => 33, 'balance' => 23456 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Dan', 'age' => 22, 'balance' => 34567 ); +$rows[] = array ( 'uid' => 33, 'name' => 'Mike', 'age' => 21, 'balance' => 4567 ); +$rows[] = array ( 'uid' => 44, 'name' => 'Paul', 'age' => 22, 'balance' => 567 ); +$rows[] = array ( 'uid' => 55, 'name' => 'Will', 'age' => 23, 'balance' => 67 ); +$rows[] = array ( 'uid' => 66, 'name' => 'Ernest', 'age' => 24, 'balance' => 7 ); +$rows[] = array ( 'uid' => 77, 'name' => 'Albert', 'age' => 25, 'balance' => 84567 ); +$rows[] = array ( 'uid' => 88, 'name' => 'Sue', 'age' => 26, 'balance' => 94567 ); +$rows[] = array ( 'uid' => 99, 'name' => 'Freddy', 'age' => 22, 'balance' => 04567 ); + +$_DBArray['user'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; +//krumo ( $_DBArray ); + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('user'); +// $c->add ( 'user.age', 22 , Criteria::GREATER_EQUAL ); +// $c->add ( 'user.age', 22 , Criteria::EQUAL ); + $c->add ( 'user.name', '%au%' , Criteria::LIKE ); +// $c->add ( 'user.balance', 3456 , Criteria::GREATER_EQUAL ); + $c->addAscendingOrderByColumn ('name'); + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_PUBLISH = new Publisher; +// $G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'cases/casesDemo', $c ); + //$G_PUBLISH->AddContent('smarty', 'cases/casesDemo', '', '', $Fields); +// G::RenderPage( "publish" ); +//die; + +/* Includes */ +G::LoadClass('pmScript'); +G::LoadClass('case'); +G::LoadClass('derivation'); +$oCase = new Cases (); +$appUid = isset ($_SESSION['APPLICATION']) ? $_SESSION['APPLICATION'] : ''; +$appFields = $oCase->loadCase( $appUid ); + +$Fields['APP_UID'] = $appFields['APP_UID']; +$Fields['APP_NUMBER'] = $appFields['APP_NUMBER']; +$Fields['APP_STATUS'] = $appFields['APP_STATUS']; +$Fields['STATUS'] = $appFields['STATUS']; +$Fields['APP_TITLE'] = $appFields['TITLE']; +$Fields['PRO_UID'] = $appFields['PRO_UID']; +$Fields['APP_PARALLEL'] = $appFields['APP_PARALLEL']; +$Fields['APP_INIT_USER'] = $appFields['APP_INIT_USER']; +$Fields['APP_CUR_USER'] = $appFields['APP_CUR_USER']; +$Fields['APP_DATA'] = $appFields['APP_DATA']; +$Fields['CREATOR'] = $appFields['CREATOR']; +$Fields['APP_PIN'] = $appFields['APP_PIN']; +$Fields['APP_PROC_CODE'] = $appFields['APP_PROC_CODE']; + +$Fields['PRO_TITLE'] = Content::load ( 'PRO_TITLE', '', $appFields['PRO_UID'], SYS_LANG ); +$oUser = new Users(); +$oUser->load( $appFields['APP_CUR_USER'] ); +$Fields['CUR_USER'] = $oUser->getUsrFirstname() . ' ' . $oUser->getUsrLastname(); + +$threads = $oCase->GetAllThreads ($appFields['APP_UID']); +$Fields['THREADS'] = $threads; +$Fields['CANT_THREADS'] = count($threads); + +$Fields['CANT_APP_DATA'] = count($Fields['APP_DATA']); +$delegations = $oCase->GetAllDelegations ($appFields['APP_UID']); +foreach ( $delegations as $key => $val ) { + $delegations[$key]['TAS_TITLE'] = Content::load ( 'TAS_TITLE', '', $val['TAS_UID'], SYS_LANG ); + if ($val['USR_UID'] != -1) { + $oUser->load( $val['USR_UID'] ); + $delegations[$key]['USR_NAME'] = $oUser->getUsrFirstname() . ' ' . $oUser->getUsrLastname(); + } + else { + $delegations[$key]['USR_NAME'] = 'Unknow user (Sub-Process User)'; + } +} +$Fields['CANT_DELEGATIONS'] = count($delegations); +$Fields['DELEGATIONS'] = $delegations; + +require_once 'classes/model/AppDelay.php'; +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(AppDelayPeer::APP_THREAD_INDEX); +$oCriteria->addSelectColumn(AppDelayPeer::APP_DEL_INDEX); +$oCriteria->addSelectColumn(AppDelayPeer::APP_TYPE); +$oCriteria->addSelectColumn(AppDelayPeer::APP_STATUS); +$oCriteria->addSelectColumn(AppDelayPeer::APP_ENABLE_ACTION_USER); +$oCriteria->addSelectColumn(AppDelayPeer::APP_ENABLE_ACTION_DATE); +$oCriteria->addSelectColumn(AppDelayPeer::APP_DISABLE_ACTION_USER); +$oCriteria->addSelectColumn(AppDelayPeer::APP_DISABLE_ACTION_DATE); +$oCriteria->add(AppDelayPeer::APP_UID, $appUid); +$oCriteria->addAscendingOrderByColumn(AppDelayPeer::APP_TYPE); +$oCriteria->addAscendingOrderByColumn(AppDelayPeer::APP_ENABLE_ACTION_DATE); +$oDataset = AppDelayPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$aDelays = array(); +while ($aRow = $oDataset->getRow()) { + $aDelays[] = $aRow; + $oDataset->next(); +} +$Fields['DELAYS'] = $aDelays; +$Fields['CANT_DELAYS'] = count($aDelays); + +require_once 'classes/model/SubApplication.php'; +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(SubApplicationPeer::APP_UID ); +$oCriteria->addSelectColumn(SubApplicationPeer::APP_PARENT ); +$oCriteria->addSelectColumn(SubApplicationPeer::DEL_INDEX_PARENT ); +$oCriteria->addSelectColumn(SubApplicationPeer::DEL_THREAD_PARENT); +$oCriteria->addSelectColumn(SubApplicationPeer::SA_STATUS ); +$oCriteria->addSelectColumn(SubApplicationPeer::SA_INIT_DATE ); +$oCriteria->addSelectColumn(SubApplicationPeer::SA_FINISH_DATE); +$oCriteria->addSelectColumn(ApplicationPeer::APP_NUMBER); +$oCriteria->add(SubApplicationPeer::APP_UID, $appUid); +$oCriteria->addJoin(ApplicationPeer::APP_UID, SubApplicationPeer::APP_PARENT, Criteria::LEFT_JOIN); +$oCriteria->addAscendingOrderByColumn(SubApplicationPeer::APP_UID); +$oDataset = SubApplicationPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$aSubprocess = array(); +while ($aRow = $oDataset->getRow()) { + $aSubprocess[] = $aRow; + $oDataset->next(); +} +$Fields['SUBAPPLICATIONS'] = $aSubprocess; +$Fields['CANT_SUBAPPLICATIONS'] = count($aSubprocess); + + /* Render page */ + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_PUBLISH = new Publisher; + //$G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'cases/casesDemo', $c ); + $G_PUBLISH->AddContent('smarty', 'cases/casesDemo', '', '', $Fields); + G::RenderPage( "publish" ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish'); +} diff --git a/workflow/engine/methods/cases/casesListExtJs.php b/workflow/engine/methods/cases/casesListExtJs.php new file mode 100755 index 000000000..2d59bdbf7 --- /dev/null +++ b/workflow/engine/methods/cases/casesListExtJs.php @@ -0,0 +1,762 @@ +<?php + //get the action from GET or POST, default is todo + $action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : 'todo'); + //fix a previous inconsistency + if ( $action == 'selfservice' ) $action = 'unassigned'; + + + G::LoadClass ( "BasePeer" ); + G::LoadClass ( 'configuration' ); + require_once ( "classes/model/Fields.php" ); + require_once ( "classes/model/AppCacheView.php" ); + require_once ( "classes/model/Process.php" ); + require_once ( "classes/model/Users.php" ); + + $oHeadPublisher =& headPublisher::getSingleton(); + // oHeadPublisher->setExtSkin( 'xtheme-blue'); + + //get the configuration for this action + $conf = new Configurations(); + try { + // the setup for search is the same as the Sent (participated) + $confCasesList = $conf->getConfiguration('casesList', ($action=='search'||$action=='simple_search') ? 'search': $action ); + $generalConfCasesList = $conf->getConfiguration('ENVIRONMENT_SETTINGS', '' ); + } + catch (Exception $e){ + $confCasesList = array(); + $generalConfCasesList = array(); + } + + // reassign header configuration + $confReassignList = getReassignList(); + + // evaluates an action and the configuration for the list that will be rendered + $config = getAdditionalFields($action, $confCasesList); + $columns = $config['caseColumns']; + $readerFields = $config['caseReaderFields']; + $reassignColumns = $confReassignList['caseColumns']; + $reassignReaderFields = $confReassignList['caseReaderFields']; + + // if the general settings has been set the pagesize values are extracted from that record + if (isset($generalConfCasesList['casesListRowNumber'])&&!empty($generalConfCasesList['casesListRowNumber'])){ + $pageSize = intval($generalConfCasesList['casesListRowNumber']); + } else { + $pageSize = intval($config['rowsperpage']); + } + + // if the general settings has been set the dateFormat values are extracted from that record + if (isset($generalConfCasesList['casesListDateFormat'])&&!empty($generalConfCasesList['casesListDateFormat'])){ + $dateFormat = $generalConfCasesList['casesListDateFormat']; + } else { + $dateFormat = $config['dateformat']; + } + + + + if ( $action == 'draft' /* && $action == 'cancelled' */) { + //array_unshift ( $columns, array( 'header'=> '', 'width'=> 50, 'sortable'=> false, 'id'=> 'deleteLink' ) ); + } + if ( $action == 'selfservice' ) { + array_unshift ( $columns, array( 'header'=> '', 'width'=> 50, 'sortable'=> false, 'id'=> 'viewLink' ) ); + } + + if ( $action == 'paused' ) { + //array_unshift ( $columns, array( 'header'=> '', 'width'=> 50, 'sortable'=> false, 'id'=> 'unpauseLink' ) ); + } +/* + if ( $action == 'to_reassign' ) { + array_unshift ( $columns, array( 'header'=> '', 'width'=> 50, 'sortable'=> false, 'id'=> 'reassignLink' ) ); + } +*/ +// if ( $action == 'cancelled' ) { +// array_unshift ( $columns, array( 'header'=> '', 'width'=> 50, 'sortable'=> false, 'id'=> 'reactivateLink' ) ); +// } + + $userUid = ( isset($_SESSION['USER_LOGGED'] ) && $_SESSION['USER_LOGGED'] != '' ) ? $_SESSION['USER_LOGGED'] : null; + $oAppCache = new AppCacheView(); + $oAppCache->confCasesList = $confCasesList; + + //get values for the comboBoxes + $processes = getProcessArray($action, $userUid ); + $status = getStatusArray($action, $userUid ); + $users = getUserArray($action, $userUid ); + $allUsers = getAllUsersArray($action); + + $oHeadPublisher->assign( 'reassignReaderFields', $reassignReaderFields ); //sending the fields to get from proxy + $oHeadPublisher->addExtJsScript('cases/reassignList', false ); + $oHeadPublisher->assign( 'pageSize', $pageSize ); //sending the page size + $oHeadPublisher->assign( 'columns', $columns ); //sending the columns to display in grid + $oHeadPublisher->assign( 'readerFields', $readerFields ); //sending the fields to get from proxy + $oHeadPublisher->assign( 'reassignColumns', $reassignColumns ); //sending the columns to display in grid + $oHeadPublisher->assign( 'action', $action ); //sending the fields to get from proxy + $oHeadPublisher->assign( 'PMDateFormat', $dateFormat ); //sending the fields to get from proxy + $oHeadPublisher->assign( 'statusValues', $status ); //sending the columns to display in grid + $oHeadPublisher->assign( 'processValues', $processes); //sending the columns to display in grid + $oHeadPublisher->assign( 'userValues', $users); //sending the columns to display in grid + $oHeadPublisher->assign( 'allUsersValues',$allUsers); //sending the columns to display in grid + + + $TRANSLATIONS['LABEL_GRID_LOADING'] = G::LoadTranslation('ID_CASES_LIST_GRID_LOADING'); + $TRANSLATIONS['LABEL_REFRESH'] = G::LoadTranslation('ID_REFRESH_LABEL'); + $TRANSLATIONS['MESSAGE_REFRESH'] = G::LoadTranslation('ID_REFRESH_MESSAGE'); + $TRANSLATIONS['LABEL_OPT_READ'] = G::LoadTranslation('ID_OPT_READ'); + $TRANSLATIONS['LABEL_OPT_UNREAD'] = G::LoadTranslation('ID_OPT_UNREAD'); + $TRANSLATIONS['LABEL_OPT_ALL'] = G::LoadTranslation('ID_OPT_ALL'); + $TRANSLATIONS['LABEL_OPT_STARTED'] = G::LoadTranslation('ID_OPT_STARTED'); + $TRANSLATIONS['LABEL_OPT_COMPLETED'] = G::LoadTranslation('ID_OPT_COMPLETED'); + $TRANSLATIONS['LABEL_EMPTY_PROCESSES'] = G::LoadTranslation('ID_EMPTY_PROCESSES'); + $TRANSLATIONS['LABEL_EMPTY_USERS'] = G::LoadTranslation('ID_EMPTY_USERS'); + $TRANSLATIONS['LABEL_EMPTY_SEARCH'] = G::LoadTranslation('ID_EMPTY_SEARCH'); + $TRANSLATIONS['LABEL_EMPTY_CASE'] = G::LoadTranslation('ID_EMPTY_CASE'); + $TRANSLATIONS['LABEL_SEARCH'] = G::LoadTranslation('ID_SEARCH'); + $TRANSLATIONS['LABEL_OPT_JUMP'] = G::LoadTranslation('ID_OPT_JUMP'); + $TRANSLATIONS['LABEL_DISPLAY_ITEMS'] = G::LoadTranslation('ID_DISPLAY_ITEMS'); + $TRANSLATIONS['LABEL_DISPLAY_EMPTY'] = G::LoadTranslation('ID_DISPLAY_EMPTY'); + $TRANSLATIONS['LABEL_OPEN_CASE'] = G::LoadTranslation('ID_OPEN_CASE'); + + + $TRANSLATIONS2 = G::getTranslations(Array( + 'ID_CASESLIST_APP_UID', 'ID_CONFIRM', 'ID_MSG_CONFIRM_DELETE_CASES', 'ID_DELETE', 'ID_REASSIGN', + 'ID_VIEW', 'ID_UNPAUSE', 'ID_PROCESSING', 'ID_CONFIRM_UNPAUSE_CASE', + 'ID_PROCESS', 'ID_STATUS', 'ID_USER', 'ID_DELEGATE_DATE_FROM', 'ID_TO', 'ID_FILTER_BY_DELEGATED_DATE', + 'ID_TO_DO', 'ID_DRAFT', 'ID_COMPLETED', 'ID_CANCELLED', 'ID_PAUSED', + 'ID_PRO_DESCRIPTION', 'ID_PRO_TITLE', 'ID_CATEGORY', 'ID_STATUS', 'ID_PRO_USER', 'ID_PRO_CREATE_DATE', 'ID_PRO_DEBUG', 'ID_INBOX', 'ID_DRAFT', + 'ID_COMPLETED', 'ID_CANCELLED', 'ID_TOTAL_CASES', 'ID_ENTER_SEARCH_TERM', 'ID_ACTIVATE', 'ID_DEACTIVATE', + 'ID_SELECT', 'ID_SEARCH', 'ID_NO_SELECTION_WARNING', 'ID_SELECT_ONE_AT_LEAST', 'ID_MSG_CONFIRM_DELETE_CASES2', + 'ID_PAUSE_CASE_TO_DATE', 'ID_DELETING_ELEMENTS', 'ID_MSG_CONFIRM_CANCEL_CASE', 'ID_MSG_CONFIRM_CANCEL_CASES', + 'ID_OPEN_CASE', 'ID_PAUSE_CASE', 'ID_REASSIGN', 'ID_DELETE', 'ID_CANCEL', 'ID_UNPAUSE_CASE','ID_MSG_CONFIRM_DELETE_CASE' + )); + + + //menu permissions + /*$c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn( AppThreadPeer::APP_THREAD_PARENT ); + $c->add(AppThreadPeer::APP_UID, $APP_UID ); + $c->add(AppThreadPeer::APP_THREAD_STATUS , 'OPEN' ); + $cnt = AppThreadPeer::doCount($c);*/ + $cnt = ''; + $menuPerms = ''; + $menuPerms = $menuPerms . ($RBAC->userCanAccess('PM_REASSIGNCASE') == 1) ? 'R': ''; //can reassign case + $menuPerms = $menuPerms . ($cnt == 1) ? 'C': ''; //can cancel case + + + $TRANSLATIONS = array_merge($TRANSLATIONS, $TRANSLATIONS2); + + $oHeadPublisher->assign( 'TRANSLATIONS', $TRANSLATIONS); //translations + $oHeadPublisher->assign( '___p34315105', $menuPerms); // user menu permissions + + $oHeadPublisher->addExtJsScript('cases/casesList', false ); //adding a javascript file .js + $oHeadPublisher->addContent( 'cases/casesListExtJs'); //adding a html file .html. + + G::RenderPage('publish', 'extJs'); + + //functions to fill the comboboxes in the case list page + function getProcessArray ( $action, $userUid ) { + global $oAppCache; + $processes = Array(); + $processes[] = array ( '', G::LoadTranslation('ID_ALL_PROCESS') ); + +//get the list based in the action provided + switch ( $action ) { + case 'draft' : + $cProcess = $oAppCache->getDraftListCriteria($userUid); //fast enough + break; + case 'sent' : + $cProcess = $oAppCache->getSentListProcessCriteria ($userUid); // fast enough + break; + case 'simple_search': + case 'search' : + //in search action, the query to obtain all process is too slow, so we need to query directly to + //process and content tables, and for that reason we need the current language in AppCacheView. + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'APP_CACHE_VIEW_ENGINE','','','',''); + $appCacheViewEngine = $oConf->aConfig; + $lang = isset($appCacheViewEngine['LANG']) ? $appCacheViewEngine['LANG'] : 'en'; + + $cProcess = new Criteria('workflow'); + $cProcess->clearSelectColumns ( ); + $cProcess->addSelectColumn ( ProcessPeer::PRO_UID ); + $cProcess->addSelectColumn ( ContentPeer::CON_VALUE ); + $del = DBAdapter::getStringDelimiter(); + $conds = array(); + $conds[] = array(ProcessPeer::PRO_UID, ContentPeer::CON_ID ); + $conds[] = array(ContentPeer::CON_CATEGORY, $del . 'PRO_TITLE' . $del); + $conds[] = array(ContentPeer::CON_LANG, $del . $lang . $del); + $cProcess->addJoinMC($conds, Criteria::LEFT_JOIN); + $cProcess->add(ProcessPeer::PRO_STATUS, 'ACTIVE'); + $oDataset = ProcessPeer::doSelectRS($cProcess); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while($aRow = $oDataset->getRow()){ + $processes[] = array ( $aRow['PRO_UID'], $aRow['CON_VALUE'] ); + $oDataset->next(); + } + + return $processes; + break; + case 'selfservice' : + $cProcess = $oAppCache->getUnassignedListCriteria($userUid); + break; + case 'paused' : + $cProcess = $oAppCache->getPausedListCriteria($userUid); + break; + case 'to_revise' : + $cProcess = $oAppCache->getToReviseListCriteria($userUid); + break; + case 'to_reassign' : + $cProcess = $oAppCache->getToReassignListCriteria(); + $cProcess->addAscendingOrderByColumn(AppCacheViewPeer::APP_PRO_TITLE); + break; + case 'gral' : + $cProcess = $oAppCache->getGeneralListCriteria(); + $cProcess->addAscendingOrderByColumn(AppCacheViewPeer::APP_PRO_TITLE); + break; + case 'todo' : + default: + $cProcess = $oAppCache->getToDoListCriteria($userUid); //fast enough + break; + } + + //get the processes for this user in this action + $cProcess->clearSelectColumns ( ); + $cProcess->setDistinct(); + $cProcess->addSelectColumn ( AppCacheViewPeer::PRO_UID ); + $cProcess->addSelectColumn ( AppCacheViewPeer::APP_PRO_TITLE ); + $oDataset = AppCacheViewPeer::doSelectRS($cProcess); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + while($aRow = $oDataset->getRow()){ + $processes[] = array ( $aRow['PRO_UID'], $aRow['APP_PRO_TITLE'] ); + $oDataset->next(); + } + + return $processes; + } + + function getUserArray ( $action, $userUid ) { + global $oAppCache; + $status = array(); + $users[] = array( '', G::LoadTranslation('ID_ALL_USERS') ); + //now get users, just for the Search action + switch ( $action ) { + case 'search_simple': + case 'search' : + $cUsers = new Criteria('workflow'); + $cUsers->clearSelectColumns ( ); + $cUsers->addSelectColumn ( UsersPeer::USR_UID ); + $cUsers->addSelectColumn ( UsersPeer::USR_FIRSTNAME ); + $cUsers->addSelectColumn ( UsersPeer::USR_LASTNAME ); + $oDataset = UsersPeer::doSelectRS($cUsers); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while($aRow = $oDataset->getRow()){ + $users[] = array( $aRow['USR_UID'], $aRow['USR_LASTNAME'] . ' ' . $aRow['USR_FIRSTNAME'] ); + $oDataset->next(); + } + break; + default: + return $users; + break; + } + return $users; + } + + function getAllUsersArray ( $action ) { + global $oAppCache; + $status = array(); + $users[] = array( '', G::LoadTranslation('ID_ALL_USERS') ); + if ($action=='to_reassign') { + //now get users, just for the Search action + $cUsers = $oAppCache->getToReassignListCriteria(); + $cUsers->addSelectColumn(AppCacheViewPeer::USR_UID); + $cUsers->addGroupByColumn(AppCacheViewPeer::USR_UID); + + $cUsers->addAscendingOrderByColumn ( AppCacheViewPeer::APP_CURRENT_USER ); + $oDataset = AppCacheViewPeer::doSelectRS($cUsers); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while($aRow = $oDataset->getRow()){ + $users[] = array( $aRow['USR_UID'], $aRow['APP_CURRENT_USER'] ); + $oDataset->next(); + } + } + return $users; + } + + function getStatusArray ( $action, $userUid ) { + global $oAppCache; + $status = array(); + $status[] = array( '', G::LoadTranslation('ID_ALL_STATUS') ); +//get the list based in the action provided + switch ( $action ) { + case 'sent' : + $cStatus = $oAppCache->getSentListProcessCriteria ($userUid); // a little slow + break; + case 'simple_search': + case 'search' : + $cStatus = new Criteria('workflow'); + $cStatus->clearSelectColumns ( ); + $cStatus->setDistinct(); + $cStatus->addSelectColumn ( ApplicationPeer::APP_STATUS ); + $oDataset = ApplicationPeer::doSelectRS($cStatus); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while($aRow = $oDataset->getRow()){ + $status[] = array( $aRow['APP_STATUS'], G::LoadTranslation('ID_CASES_STATUS_'.$aRow['APP_STATUS']) ); //here we can have a translation for the status ( the second param) + $oDataset->next(); + } + return $status; + break; + + case 'selfservice' : + $cStatus = $oAppCache->getUnassignedListCriteria($userUid); + break; + case 'paused' : + $cStatus = $oAppCache->getPausedListCriteria($userUid); + break; + case 'to_revise' : + $cStatus = $oAppCache->getToReviseListCriteria($userUid); +// $cStatus = $oAppCache->getPausedListCriteria($userUid); + break; + case 'to_reassign' : + $cStatus = $oAppCache->getToReassignListCriteria(); + break; + case 'todo' : + case 'draft' : + case 'gral' : +// case 'to_revise' : + default: + return $status; + break; + } + + //get the status for this user in this action only for participated, unassigned, paused +// if ( $action != 'todo' && $action != 'draft' && $action != 'to_revise') { + if ( $action != 'todo' && $action != 'draft' ) { + //$cStatus = new Criteria('workflow'); + $cStatus->clearSelectColumns ( ); + $cStatus->setDistinct(); + $cStatus->addSelectColumn ( AppCacheViewPeer::APP_STATUS ); + $oDataset = AppCacheViewPeer::doSelectRS($cStatus); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while($aRow = $oDataset->getRow()){ + $status[] = array( $aRow['APP_STATUS'], G::LoadTranslation('ID_CASES_STATUS_'.$aRow['APP_STATUS']) ); //here we can have a translation for the status ( the second param) + $oDataset->next(); + } + } + return $status; + } + + //these getXX function gets the default fields in casesListSetup + function getToDo() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Sent by', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'Due Date', 'dataIndex' => 'DEL_TASK_DUE_DATE', 'width' => 110); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Priority', 'dataIndex' => 'DEL_PRIORITY', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getDraft() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Due Date', 'dataIndex' => 'DEL_TASK_DUE_DATE', 'width' => 110); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Priority', 'dataIndex' => 'DEL_PRIORITY', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getParticipated() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Current User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 80 ); + $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getSearch() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 100 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Current User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 80 ); + $caseColumns[] = array( 'header' =>'Delegation Date', 'dataIndex' => 'DEL_DELEGATE_DATE','width' => 80 ); + $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_DELEGATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getUnassigned() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Completed By User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Finish Date', 'dataIndex' => 'APP_FINISH_DATE', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getPaused() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getToRevise() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Current User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 90 ); +// $caseColumns[] = array( 'header' =>'Sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Priority', 'dataIndex' => 'DEL_PRIORITY', 'width' => 50 ); + $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); +// $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'DEL_TASK_DUE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'DEL_PRIORITY' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'APP_FINISH_DATE' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getToReassign() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'TaskUid', 'dataIndex' => 'TAS_UID' , 'width' => 150 ,'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'DelIndex', 'dataIndex' => 'DEL_INDEX' , 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Current User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 90 ); +// $caseColumns[] = array( 'header' =>'Sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'TAS_UID' ); + $caseReaderFields[] = array( 'name' => 'DEL_INDEX' ); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); +// $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getGeneral() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 45, 'align' => 'center'); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 150 ); + $caseColumns[] = array( 'header' =>'UserUid', 'dataIndex' => 'USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'PreUsrUid', 'dataIndex' => 'PREVIOUS_USR_UID', 'width' => 50 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Current User', 'dataIndex' => 'APP_CURRENT_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'Sent By', 'dataIndex' => 'APP_DEL_PREVIOUS_USER', 'width' => 90 ); + $caseColumns[] = array( 'header' =>'Last Modify', 'dataIndex' => 'APP_UPDATE_DATE', 'width' => 110 ); + $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_CURRENT_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_DEL_PREVIOUS_USER' ); + $caseReaderFields[] = array( 'name' => 'APP_UPDATE_DATE' ); + $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'PREVIOUS_USR_UID' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + /** + * get the list configuration headers of the cases checked for reassign, for the + * reassign cases list. + */ + function getReassignList() { + $caseColumns = array (); + $caseColumns[] = array( 'header' =>'#', 'dataIndex' => 'APP_NUMBER', 'width' => 40 ); + $caseColumns[] = array( 'header' =>'Case', 'dataIndex' => 'APP_TITLE', 'width' => 100 , 'hidden'=> true); + $caseColumns[] = array( 'header' =>'CaseId', 'dataIndex' => 'APP_UID' , 'width' => 200 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'User', 'dataIndex' => 'USR_UID' , 'width' => 200 , 'hidden'=> true, 'hideable'=> false); + $caseColumns[] = array( 'header' =>'Task', 'dataIndex' => 'APP_TAS_TITLE', 'width' => 120 ); + $caseColumns[] = array( 'header' =>'Process', 'dataIndex' => 'APP_PRO_TITLE', 'width' => 120 ); +// $caseColumns[] = array( 'header' =>'Status', 'dataIndex' => 'APP_STATUS', 'width' => 50 ); + $caseColumns[] = array( 'header' =>'Reassigned Uid', 'dataIndex' => 'APP_REASSIGN_USER_UID', 'width' => 120, 'hidden'=> true ); + $caseColumns[] = array( 'header' =>'Reassigned Uid', 'dataIndex' => 'TAS_UID', 'width' => 120, 'hidden'=> true ); + $caseColumns[] = array( 'header' =>'Reassign To' , 'dataIndex' => 'APP_REASSIGN_USER', 'width' => 170 ); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'APP_NUMBER' ); + $caseReaderFields[] = array( 'name' => 'APP_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_UID' ); + $caseReaderFields[] = array( 'name' => 'USR_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_TAS_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_PRO_TITLE' ); + $caseReaderFields[] = array( 'name' => 'APP_REASSIGN_USER_UID' ); + $caseReaderFields[] = array( 'name' => 'TAS_UID' ); + $caseReaderFields[] = array( 'name' => 'APP_REASSIGN_USER' ); +// $caseReaderFields[] = array( 'name' => 'APP_STATUS' ); +// $caseReaderFields[] = array( 'name' => 'USERS' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + + function getReassignUsersList() { + $caseColumns = array (); + + $caseReaderFields = array(); + $caseReaderFields[] = array( 'name' => 'userUid' ); + $caseReaderFields[] = array( 'name' => 'userFullname' ); + + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => 20, 'dateformat' => 'M d, Y' ); + } + +// Ext.namespace("Ext.ux"); +// Ext.ux.comboBoxRenderer = function(combo) { +// return function(value) { +// var idx = combo.store.find(combo.valueField, value); +// var rec = combo.store.getAt(idx); +// return rec.get(combo.displayField); +// } +// } + /** + * loads the PM Table field list from the database based in an action parameter + * then assemble the List of fields with these data, for the configuration in cases list. + * @param String $action + * @return Array $config + */ +function getAdditionalFields($action, $confCasesList){ + $caseColumns = array(); + $caseReaderFields = array(); + + if ( !empty($confCasesList) && !empty($confCasesList['second']['data'])) { + foreach($confCasesList['second']['data'] as $fieldData){ + if ( $fieldData['fieldType']!='key' ) { +// $label = ($fieldData['fieldType']=='case field' ) ? G::loadTranslation('ID_CASESLIST_'.$fieldData['name']) : $fieldData['label']; + $label = $fieldData['label']; + $caseColumns[] = array( 'header' => $label, 'dataIndex' => $fieldData['name'], 'width' => $fieldData['width'], 'align' => $fieldData['align'] ); + $caseReaderFields[] = array( 'name' => $fieldData['name'] ); + } + } + return array ( 'caseColumns' => $caseColumns, 'caseReaderFields' => $caseReaderFields, 'rowsperpage' => $confCasesList['rowsperpage'], 'dateformat' => $confCasesList['dateformat'] ); + } + else { //seems this is only in case this user dont have the configuration for this action. + switch ( $action ) { + case 'draft' : + $config = getDraft(); + break; + case 'simple_search': + case 'search' : + $config = getSearch(); + break; + case 'participated' : + $config = getParticipated(); + break; + case 'unassigned' : + $config = getUnassigned(); + break; + case 'paused' : + $config = getPaused(); + break; + case 'to_revise' : + $config = getToRevise(); + break; + case 'to_reassign' : + $config = getToReassign(); + break; + case 'gral' : + $config = getGeneral(); + break; + case 'todo' : + default : + $action = 'todo'; + $config = getToDo(); + break; + } + return $config; + } +} + diff --git a/workflow/engine/methods/cases/casesMenuLoader.php b/workflow/engine/methods/cases/casesMenuLoader.php new file mode 100644 index 000000000..6c19e9be3 --- /dev/null +++ b/workflow/engine/methods/cases/casesMenuLoader.php @@ -0,0 +1,205 @@ +<?php + + $action = isset($_GET['action']) ? $_GET['action']: 'default'; + G::LoadClass('case'); + G::LoadClass('configuration'); + + $userId = isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : '00000000000000000000000000000000'; + switch($action) { + case 'getAllCounters': + getAllCounters(); + break; + case 'getProcess' : + getProcess(); + break; + default: //this is the starting call + getLoadTreeMenuData(); + break; + } + + + function getLoadTreeMenuData () { + header ("content-type: text/xml"); + + global $G_TMP_MENU; + $oMenu = new Menu(); + $oMenu->load('cases'); + + $oCases = new Cases(); + $aTypes = Array( + 'to_do', + 'draft', + 'cancelled', + 'sent', + 'paused', + 'completed', + 'selfservice', + //'to_revise', + //'to_reassign' + ); + $aTypesID = Array( + 'CASES_INBOX'=>'to_do', + 'CASES_DRAFT'=>'draft', + 'CASES_CANCELLED'=>'cancelled', + 'CASES_SENT'=>'sent', + 'CASES_PAUSED'=>'paused', + 'CASES_COMPLETED'=>'completed', + 'CASES_SELFSERVICE'=>'selfservice', + //'CASES_TO_REVISE'=>'to_revise', + //'CASES_TO_REASSIGN'=>'to_reassign' + ); + + $list = array(); + $list['count'] = ' '; + + $empty = array(); + foreach ( $aTypes as $key => $val ) { + $empty[$val] = $list; + } + + $aCount = $empty; //$oCases->getAllConditionCasesCount($aTypes, true); + $processNameMaxSize = 20; + + //now drawing the treeview using the menu options from menu/cases.php + $menuCases = array(); + foreach( $oMenu->Options as $i => $option ) { + if( $oMenu->Types[$i] == 'blockHeader' ) { + $CurrentBlockID = $oMenu->Id[$i]; + $menuCases[$CurrentBlockID]['blockTitle'] = $oMenu->Labels[$i]; + if($oMenu->Options[$i]!=""){ + $menuCases[$CurrentBlockID]['link'] = $oMenu->Options[$i]; + } + }elseif( $oMenu->Types[$i] == 'blockNestedTree' ){ + $CurrentBlockID = $oMenu->Id[$i]; + $menuCases[$CurrentBlockID]['blockTitle'] = $oMenu->Labels[$i]; + $menuCases[$CurrentBlockID]['blockType'] = $oMenu->Types[$i]; + $menuCases[$CurrentBlockID]['loaderurl'] = $oMenu->Options[$i]; + + + }else { + $menuCases[$CurrentBlockID]['blockItems'][$oMenu->Id[$i]] = Array ( + 'label' => $oMenu->Labels[$i], + 'link' => $oMenu->Options[$i], + 'icon' => (isset($oMenu->Icons[$i]) && $oMenu->Icons[$i] != '') ? $oMenu->Icons[$i] : 'kcmdf.png' + ); + + if( isset($aTypesID[$oMenu->Id[$i]]) ) { + $menuCases[$CurrentBlockID]['blockItems'][$oMenu->Id[$i]]['cases_count'] = $aCount[$aTypesID[$oMenu->Id[$i]]]['count']; + } + } + } + //now build the menu in xml format + $xml = '<menu_cases>'; + $i = 0; + foreach( $menuCases as $menu => $aMenuBlock ) { + if( isset($aMenuBlock['blockItems']) && sizeof($aMenuBlock['blockItems']) > 0 ) { + $urlProperty=""; + if((isset($aMenuBlock['link']))&&($aMenuBlock['link']!="")){ + $urlProperty="url='".$aMenuBlock['link']."'"; + } + $xml .= '<menu_block blockTitle="'.$aMenuBlock['blockTitle'].'" id="'.$menu.'" '.$urlProperty.'>'; + foreach( $aMenuBlock['blockItems'] as $id => $aMenu ) { + $i++; + if( isset($aMenu['cases_count']) && $aMenu['cases_count'] !== '') { + $nofifier = "cases_count=\"{$aMenu['cases_count']}\" "; + } + else { + $nofifier = ''; + } + $xml .= '<option title="'.$aMenu['label'].'" id="'.$id.'" '.$nofifier.' url="'.$aMenu['link'].'">'; + $xml .= '</option>'; + } + $xml .= '</menu_block>'; + }elseif( isset($aMenuBlock['blockType']) && $aMenuBlock['blockType']=="blockNestedTree" ) { + $xml .= '<menu_block blockTitle="'.$aMenuBlock['blockTitle'].'" blockNestedTree = "'.$aMenuBlock['loaderurl'].'" id="'.$menu.'" folderId="0">'; + $xml .= '</menu_block>'; + } + } + $xml .= '</menu_cases>'; + + print $xml; + } + + // get the process summary of specific case list type, + function getProcess () { + global $G_TMP_MENU; + global $userId; + if ( !isset($_GET['item']) ) { + die; + } + + $oMenu = new Menu(); + $oMenu->load('cases'); + $type = $_GET['item']; + $oCases = new AppCacheView(); + + $aTypesID = array(); + $aTypesID['CASES_INBOX'] = 'to_do'; + $aTypesID['CASES_DRAFT'] = 'draft'; + $aTypesID['CASES_CANCELLED'] = 'cancelled'; + $aTypesID['CASES_SENT'] = 'sent'; + $aTypesID['CASES_PAUSED'] = 'paused'; + $aTypesID['CASES_COMPLETED'] = 'completed'; + $aTypesID['CASES_SELFSERVICE'] = 'selfservice'; + //$aTypesID['CASES_TO_REVISE'] = 'to_revise'; + //$aTypesID['CASES_TO_REASSIGN'] = 'to_reassign'; + $aTypesID = Array('CASES_INBOX'=>'to_do', 'CASES_DRAFT'=>'draft', 'CASES_CANCELLED'=>'cancelled', 'CASES_SENT'=>'sent', 'CASES_PAUSED'=>'paused', 'CASES_COMPLETED'=>'completed','CASES_SELFSERVICE'=>'selfservice','CASES_TO_REVISE'=>'to_revise','CASES_TO_REASSIGN'=>'to_reassign'); + + $aCount = $oCases->getAllCounters(Array($aTypesID[$type]), $userId, true); + + $response = Array(); +//disabling the summary... +/* + $i=0; + foreach($aCount[$aTypesID[$type]]['sumary'] as $PRO_UID=>$process){ + //{"text":"state","id":"src\/state","cls":"folder", loaded:true}, + $response[$i] = new stdClass(); + $response[$i]->text = $process['name'] . ' ('.$process['count'].')'; + $response[$i]->id = $process['name']; + $response[$i]->cls = 'folder'; + $response[$i]->loaded = true; + $i++; + } +*/ + //ordering + /*for($i=0; $i<=count($response)-1; $i++){ + for($j=$i+1; $j<=count($response); $j++){ + + echo $response[$j]->text .'<'. $response[$i]->text; + if($response[$j]->text[0] < $response[$i]->text[0]){ + $x = $response[$i]; + $response[$i] = $response[$j]; + $response[$j] = $x; + } + } + }*/ + echo G::json_encode($response); + } + + function getAllCounters() { + $userUid = ( isset($_SESSION['USER_LOGGED'] ) && $_SESSION['USER_LOGGED'] != '' ) ? $_SESSION['USER_LOGGED'] : null; + $oAppCache = new AppCacheView(); + //$aTypes = Array('to_do', 'draft', 'cancelled', 'sent', 'paused', 'completed','selfservice','to_revise','to_reassign'); + $aTypes = Array(); + $aTypes['to_do'] = 'CASES_INBOX'; + $aTypes['draft'] = 'CASES_DRAFT'; + $aTypes['cancelled'] = 'CASES_CANCELLED'; + $aTypes['sent'] = 'CASES_SENT'; + $aTypes['paused'] = 'CASES_PAUSED'; + $aTypes['completed'] = 'CASES_COMPLETED'; + $aTypes['selfservice'] = 'CASES_SELFSERVICE'; + //$aTypes['to_revise'] = 'CASES_TO_REVISE'; + //$aTypes['to_reassign'] = 'CASES_TO_REASSIGN'; + + $aCount = $oAppCache->getAllCounters( array_keys($aTypes), $userUid ); + + $response = Array(); + $i = 0; + foreach ($aCount as $type=>$count) { + $response[$i]->item = $aTypes[$type]; + $response[$i]->count = $count; + $i++; + } + echo G::json_encode($response); + } + \ No newline at end of file diff --git a/workflow/engine/methods/cases/casesStartPage.php b/workflow/engine/methods/cases/casesStartPage.php new file mode 100644 index 000000000..57f27be5a --- /dev/null +++ b/workflow/engine/methods/cases/casesStartPage.php @@ -0,0 +1,11 @@ +<?php + unset($_SESSION['__currentTabDashboard']); + if(isset($_GET['t'])){ + $_SESSION['__currentTabDashboard']=$_GET['t']; + } + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addExtJsScript('cases/casesStartPage', false); //adding a javascript file .js + $oHeadPublisher->addContent( 'cases/casesStartPage'); //adding a html file .html. + + G::RenderPage('publish', 'extJs'); \ No newline at end of file diff --git a/workflow/engine/methods/cases/casesStartPage_Ajax.php b/workflow/engine/methods/cases/casesStartPage_Ajax.php new file mode 100755 index 000000000..a630b2a31 --- /dev/null +++ b/workflow/engine/methods/cases/casesStartPage_Ajax.php @@ -0,0 +1,268 @@ +<?php + +if (! isset ( $_REQUEST ['action'] )) { + $res ['success'] = 'failure'; + $res ['message'] = 'You may request an action'; + print G::json_encode ( $res); + die (); +} +if (! function_exists ( $_REQUEST ['action'] )) { + $res ['success'] = 'failure'; + $res ['message'] = 'The requested action doesn\'t exists'; + print G::json_encode ( $res ); + die (); +} + +$functionName = $_REQUEST ['action']; +$functionParams = isset ( $_REQUEST ['params'] ) ? $_REQUEST ['params'] : array (); + +$functionName ( $functionParams ); + +function getProcessList() { + G::LoadClass ( 'case' ); + G::LoadClass ( 'process' ); + G::LoadClass ( 'calendar' ); + $calendar = new Calendar ( ); + $oProcess = new Process ( ); + $oCase = new Cases ( ); + $bCanStart = $oCase->canStartCase ( $_SESSION ['USER_LOGGED'] ); + if ($bCanStart) { + $processListInitial = $oCase->getStartCasesPerType ( $_SESSION ['USER_LOGGED'], 'category' ); + $processList = array (); + foreach ( $processListInitial as $key => $procInfo ) { + if (isset ( $procInfo ['cat'] )) { + if (trim ( $procInfo ['cat'] ) == "") + $procInfo ['cat'] = "_OTHER_"; + $processList [$procInfo ['catname']] [$procInfo ['value']] = $procInfo; + } + } + ksort ( $processList ); + foreach ( $processList as $key => $processInfo ) { + ksort ( $processList [$key] ); + } + + if (! isset ( $_REQUEST ['node'] )) { + $node = 'root'; + } else { + $node = $_REQUEST ['node']; + } + + $processListTree = array (); + if ($node == 'root') { + foreach ( $processList as $key => $processInfo ) { + $tempTree ['text'] = $key; + $tempTree ['id'] = $key; + $tempTree ['cls'] = 'folder'; + $tempTree ['draggable'] = true; + $tempTree ['optionType'] = "category"; + //$tempTree['allowDrop']=false; + $tempTree ['singleClickExpand'] = true; + if ($key != "No Category") { + $tempTree ['expanded'] = true; + } else { + //$tempTree ['expanded'] = false; + $tempTree ['expanded'] = true; + } + $tempTreeChildren=array(); + foreach ( $processList [$key] as $keyChild => $processInfoChild ) { + //print_r($processInfo); + $tempTreeChild ['text'] = ellipsis ( $keyChild, 50 ); + //$tempTree['text']=$key; + $tempTreeChild ['id'] = $keyChild; + $tempTreeChild ['draggable'] = true; + $tempTreeChild ['leaf'] = true; + $tempTreeChild ['icon'] = '/images/icon.trigger.png'; + $tempTreeChild ['allowChildren'] = false; + $tempTreeChild ['optionType'] = "startProcess"; + $tempTreeChild ['pro_uid'] = $processInfoChild ['pro_uid']; + $tempTreeChild ['tas_uid'] = $processInfoChild ['uid']; + $processInfoChild ['myInbox']=0; + $processInfoChild ['totalInbox']=0; + $tempTreeChild ['otherAttributes'] = array_merge($processInfoChild,$oProcess->load ( $processInfoChild ['pro_uid'] ),$calendar->getCalendarFor ( $processInfoChild ['uid'], $processInfoChild ['uid'], $processInfoChild ['uid'] )); + $tempTreeChild ['qtip']=$tempTreeChild ['otherAttributes']['PRO_DESCRIPTION']; + + //$tempTree['cls']='file'; + + $tempTreeChildren [] = $tempTreeChild; + } + + $tempTree['children']=$tempTreeChildren; + + $processListTree [] = $tempTree; + } + } else { + foreach ( $processList [$node] as $key => $processInfo ) { + //print_r($processInfo); + $tempTree ['text'] = ellipsis ( $key, 50 ); + //$tempTree['text']=$key; + $tempTree ['id'] = $key; + $tempTree ['draggable'] = true; + $tempTree ['leaf'] = true; + $tempTree ['icon'] = '/images/icon.trigger.png'; + $tempTree ['allowChildren'] = false; + $tempTree ['optionType'] = "startProcess"; + $tempTree ['pro_uid'] = $processInfo ['pro_uid']; + $tempTree ['tas_uid'] = $processInfo ['uid']; + $processInfo ['myInbox']=0; + $processInfo ['totalInbox']=0; + $tempTree ['otherAttributes'] = array_merge($processInfo,$oProcess->load ( $processInfo ['pro_uid'] ),$calendar->getCalendarFor ( $processInfo ['uid'], $processInfo ['uid'], $processInfo ['uid'] )); + $tempTree ['qtip']=$tempTree ['otherAttributes']['PRO_DESCRIPTION']; + //$tempTree['cls']='file'; + $processListTree [] = $tempTree; + } + + } + $processList = $processListTree; + } else { + $processList ['success'] = 'failure'; + $processList ['message'] = 'User can\'t start process'; + } + print G::json_encode ( $processList ); + die (); +} + +function ellipsis($text, $numb) { + $text = html_entity_decode ( $text, ENT_QUOTES ); + if (strlen ( $text ) > $numb) { + $text = substr ( $text, 0, $numb ); + $text = substr ( $text, 0, strrpos ( $text, " " ) ); + //This strips the full stop: + if ((substr ( $text, - 1 )) == ".") { + $text = substr ( $text, 0, (strrpos ( $text, "." )) ); + } + $etc = "..."; + $text = $text . $etc; + } + + return $text; +} + +function startCase() { + G::LoadClass ( 'case' ); + + /* GET , POST & $_SESSION Vars */ + /* unset any variable, because we are starting a new case */ + if (isset ( $_SESSION ['APPLICATION'] )) unset ( $_SESSION ['APPLICATION'] ); + if (isset ( $_SESSION ['PROCESS'] )) unset ( $_SESSION ['PROCESS'] ); + if (isset ( $_SESSION ['TASK'] )) unset ( $_SESSION ['TASK'] ); + if (isset ( $_SESSION ['INDEX'] )) unset ( $_SESSION ['INDEX'] ); + if (isset ( $_SESSION ['STEP_POSITION'] )) unset ( $_SESSION ['STEP_POSITION'] ); + + /* Process */ + try { + $oCase = new Cases ( ); + $aData = $oCase->startCase ( $_REQUEST ['taskId'], $_SESSION ['USER_LOGGED'] ); + $_SESSION ['APPLICATION'] = $aData ['APPLICATION']; + $_SESSION ['INDEX'] = $aData ['INDEX']; + $_SESSION ['PROCESS'] = $aData ['PROCESS']; + $_SESSION ['TASK'] = $_REQUEST ['taskId']; + $_SESSION ['STEP_POSITION'] = 0; + + $_SESSION ['CASES_REFRESH'] = true; + + $oCase = new Cases ( ); + $aNextStep = $oCase->getNextStep ( $_SESSION ['PROCESS'], $_SESSION ['APPLICATION'], $_SESSION ['INDEX'], $_SESSION ['STEP_POSITION'] ); + $_SESSION ['BREAKSTEP'] ['NEXT_STEP'] = $aNextStep; + $aData ['openCase'] = $aNextStep; + + $aData ['status'] = 'success'; + print (G::json_encode ( $aData )) ; + } + catch ( Exception $e ) { + $aData ['status'] = 'failure'; + $aData ['message'] = $e->getMessage (); + print_r ( G::json_encode ( $aData ) ); + } +} + +function getSimpleDashboardData() { + G::LoadClass ( "BasePeer" ); + require_once ("classes/model/AppCacheView.php"); + require_once 'classes/model/Process.php'; + $sUIDUserLogged = $_SESSION ['USER_LOGGED']; + + $Criteria = new Criteria ( 'workflow' ); + + $Criteria->clearSelectColumns (); + + $Criteria->addSelectColumn ( AppCacheViewPeer::PRO_UID ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_UID ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_NUMBER ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_STATUS ); + $Criteria->addSelectColumn ( AppCacheViewPeer::DEL_INDEX ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_TITLE ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_PRO_TITLE ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_TAS_TITLE ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_DEL_PREVIOUS_USER ); + $Criteria->addSelectColumn ( AppCacheViewPeer::DEL_TASK_DUE_DATE ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_UPDATE_DATE ); + $Criteria->addSelectColumn ( AppCacheViewPeer::DEL_PRIORITY ); + $Criteria->addSelectColumn ( AppCacheViewPeer::DEL_DELAYED ); + $Criteria->addSelectColumn ( AppCacheViewPeer::USR_UID ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_THREAD_STATUS ); + + $Criteria->add ( AppCacheViewPeer::APP_STATUS, array ("TO_DO", "DRAFT" ), CRITERIA::IN ); + $Criteria->add ( AppCacheViewPeer::USR_UID, array ($sUIDUserLogged, "" ), CRITERIA::IN ); + + $Criteria->add ( AppCacheViewPeer::DEL_FINISH_DATE, null, Criteria::ISNULL ); + + //$Criteria->add ( AppCacheViewPeer::APP_THREAD_STATUS, 'OPEN' ); + + + $Criteria->add ( AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN' ); + + //execute the query + $oDataset = AppCacheViewPeer::doSelectRS ( $Criteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + + $oProcess = new Process ( ); + + $rows = array (); + $processNames = array (); + while ( $aRow = $oDataset->getRow () ) { + // G::pr($aRow); + if (! isset ( $processNames [$aRow ['PRO_UID']] )) { + $aProcess = $oProcess->load ( $aRow ['PRO_UID'] ); + $processNames [$aRow ['PRO_UID']] = $aProcess ['PRO_TITLE']; + } + + if ($aRow ['USR_UID'] == "") + $aRow ['APP_STATUS'] = "UNASSIGNED"; + if (((in_array ( $aRow ['APP_STATUS'], array ("TO_DO", "UNASSIGNED" ) )) && ($aRow ['APP_THREAD_STATUS'] == "OPEN")) || ($aRow ['APP_STATUS'] == "DRAFT")) { + $rows [$processNames [$aRow ['PRO_UID']]] [$aRow ['APP_STATUS']] [$aRow ['DEL_DELAYED']] [] = $aRow ['APP_UID']; + if(!isset($rows [$processNames [$aRow ['PRO_UID']]] [$aRow ['APP_STATUS']]['count'])) $rows [$processNames [$aRow ['PRO_UID']]] [$aRow ['APP_STATUS']]['count']=0; + $rows [$processNames [$aRow ['PRO_UID']]][$aRow ['APP_STATUS']]['count']++; + } + + $oDataset->next (); + } + //Generate different groups of data for graphs + $rowsResponse=array(); + $i=0; + foreach($rows as $processID => $processInfo){ + $i++; + if($i<=10){ + $rowsResponse['caseStatusByProcess'][]=array('process'=>$processID,'inbox'=>isset($processInfo['TO_DO']['count'])?$processInfo['TO_DO']['count']:0,'draft'=>isset($processInfo['DRAFT']['count'])?$processInfo['DRAFT']['count']:0,'unassigned'=>isset($processInfo['UNASSIGNED']['count'])?$processInfo['UNASSIGNED']['count']:0); + + } + } + $rowsResponse['caseDelayed'][]=array('delayed'=>'On Time','total'=>100); + $rowsResponse['caseDelayed'][]=array('delayed'=>'Delayed','total'=>50); + + print_r ( G::json_encode ( $rowsResponse ) ); +} + +function getRegisteredDashboards() { + $oPluginRegistry = & PMPluginRegistry::getSingleton (); + $dashBoardPages = $oPluginRegistry->getDashboardPages (); + print_r ( G::json_encode ( $dashBoardPages ) ); +} + +function getDefaultDashboard(){ + $defaultDashboard['defaultTab']="mainDashboard"; + if(isset($_SESSION['__currentTabDashboard'])){ + $defaultDashboard['defaultTab']=$_SESSION['__currentTabDashboard']; + } + print_r ( G::json_encode ( $defaultDashboard ) ); +} \ No newline at end of file diff --git a/workflow/engine/methods/cases/casesToRevisePanelExtJs.php b/workflow/engine/methods/cases/casesToRevisePanelExtJs.php new file mode 100644 index 000000000..24cd2f79c --- /dev/null +++ b/workflow/engine/methods/cases/casesToRevisePanelExtJs.php @@ -0,0 +1,15 @@ +<?php +// $oHeadPublisher =& headPublisher::getSingleton(); + +// $TRANSLATIONS = array_merge($TRANSLATIONS, $TRANSLATIONS2); + $delIndex = $_GET['DEL_INDEX']; + $appUid = $_GET['APP_UID']; +// $oHeadPublisher->assign( 'TRANSLATIONS', $TRANSLATIONS); //translations + $casesPanelUrl = 'casesToReviseTreeContent?APP_UID='.$appUid.'&DEL_INDEX='.$delIndex; + $oHeadPublisher->assign( 'casesPanelUrl', $casesPanelUrl); //translations + $oHeadPublisher->assign( 'treeTitle', G::loadtranslation('ID_STEP_LIST')); //translations + $oHeadPublisher->addExtJsScript('cases/casesToRevisePanel', false ); //adding a javascript file .js + $oHeadPublisher->addContent( 'cases/casesToRevisePanel'); //adding a html file .html. + + G::RenderPage('publish', 'extJs'); + \ No newline at end of file diff --git a/workflow/engine/methods/cases/casesToReviseTreeContent.php b/workflow/engine/methods/cases/casesToReviseTreeContent.php new file mode 100644 index 000000000..28dd8114b --- /dev/null +++ b/workflow/engine/methods/cases/casesToReviseTreeContent.php @@ -0,0 +1,102 @@ +<?php + +class TreeNode { + + public $text = ""; + public $id = ""; + public $iconCls = ""; + public $leaf = true; + public $draggable = false; + public $href = "#"; + public $hrefTarget = ""; + + function __construct($id,$text,$iconCls,$leaf,$draggable,$href,$hrefTarget) { + + $this->id = $id; + $this->text = $text; + $this->iconCls = $iconCls; + $this->leaf = $leaf; + $this->draggable = $draggable; + $this->href = $href; + $this->hrefTarget = $hrefTarget; + } + + function toJson() { + return G::json_encode($this); + } +} + +class ExtJsTreeNode extends TreeNode { + public $children = array(); + function add($object) { + $this->children[] = $object; + } + + function toJson() { + return G::json_encode($this); + } +} + +G::LoadClass('case'); + +$o = new Cases(); + +$PRO_UID = ''; + +$treeArray = array(); +//if (isset($_GET['action'])&&$_GET['action']=='test'){ + echo "["; + // dynaforms assemble + $extTreeDynaforms = new ExtJsTreeNode("node-dynaforms", G::loadtranslation('ID_DYNAFORMS'), "", false, false, "", ""); + $i = 0; + $APP_UID = $_GET['APP_UID']; + $DEL_INDEX = $_GET['DEL_INDEX']; + $steps = $o->getAllDynaformsStepsToRevise($_GET['APP_UID']); + foreach ($steps as $step) { + require_once 'classes/model/Dynaform.php'; + $od = new Dynaform(); + $dynaformF = $od->Load($step['STEP_UID_OBJ']); + + $n = $step['STEP_POSITION']; + $TITLE = " - ".$dynaformF['DYN_TITLE']; + $DYN_UID = $dynaformF['DYN_UID']; + $PRO_UID = $step['PRO_UID']; + $href = "cases_StepToRevise?type=DYNAFORM&ex=$i&PRO_UID=$PRO_UID&DYN_UID=$DYN_UID&APP_UID=$APP_UID&position=".$step['STEP_POSITION']."&DEL_INDEX=$DEL_INDEX"; + $extTreeDynaforms->add(new TreeNode($DYN_UID,$TITLE,"datasource",true,false,$href,"_parent")); + $i++; + } + echo $extTreeDynaforms->toJson(); + // end the dynaforms tree menu + echo ","; + // assembling the input documents tree menu + $extTreeInputDocs = new ExtJsTreeNode("node-input-documents", G::loadtranslation('ID_REQUEST_DOCUMENTS'), "", false, false, "", ""); + $i = 0; + $APP_UID = $_GET['APP_UID']; + $DEL_INDEX = $_GET['DEL_INDEX']; + $steps = $o->getAllInputsStepsToRevise($_GET['APP_UID']); + //$i=1; + foreach ($steps as $step) { + require_once 'classes/model/InputDocument.php'; + $od = new InputDocument(); + $IDF = $od->Load($step['STEP_UID_OBJ']); + + $n = $step['STEP_POSITION']; + $TITLE = " - ".$IDF['INP_DOC_TITLE']; + $INP_DOC_UID = $IDF['INP_DOC_UID']; + $PRO_UID = $step['PRO_UID']; + $href = "cases_StepToReviseInputs?type=INPUT_DOCUMENT&ex=$i&PRO_UID=$PRO_UID&INP_DOC_UID=$INP_DOC_UID&APP_UID=$APP_UID&position=".$step['STEP_POSITION']."&DEL_INDEX=$DEL_INDEX"; + $extTreeInputDocs->add(new TreeNode($INP_DOC_UID,$TITLE,"datasource",true,false,$href,"_parent")); + $i++; + } + echo $extTreeInputDocs->toJson(); + // end of the tree assembling input documents list + echo ","; + $i=0; + $APP_UID = $_GET['APP_UID']; + $DEL_INDEX = $_GET['DEL_INDEX']; + $outputHref = "cases_StepToReviseOutputs?ex=$i&PRO_UID=$PRO_UID&DEL_INDEX=$DEL_INDEX&APP_UID=$APP_UID"; + $ouputItem = new TreeNode ("node-output-documents",G::loadtranslation('ID_OUTPUT_DOCUMENTS'),"",true,false,$outputHref,"_parent"); + echo $ouputItem->toJson(); + echo "]"; + + diff --git a/workflow/engine/methods/cases/cases_Ajax.php b/workflow/engine/methods/cases/cases_Ajax.php new file mode 100644 index 000000000..a125ea92a --- /dev/null +++ b/workflow/engine/methods/cases/cases_Ajax.php @@ -0,0 +1,839 @@ +<? +/** + * cases_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadClass('case'); +$oCase = new Cases(); +//if($RBAC->userCanAccess('PM_ALLCASES') < 0) { +// $oCase->thisIsTheCurrentUser($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'SHOW_MESSAGE'); +//} + +if(($RBAC_Response = $RBAC->userCanAccess("PM_CASES")) != 1) + return $RBAC_Response; +if(isset($_POST['showWindow'])) { + if($_POST['showWindow'] == 'steps') { + $fn = 'showSteps();'; + } elseif($_POST['showWindow'] == 'information') { + $fn = 'showInformation();'; + } elseif($_POST['showWindow'] == 'actions') { + $fn = 'showActions();'; + } elseif($_POST['showWindow'] == 'false') { + $fn = ''; + } else { + if($_POST['showWindow'] != '') { + $fn = false; + } + } + $_SESSION['showCasesWindow'] = $fn; +} +if(! isset($_POST['action'])) { + $_POST['action'] = ''; +} +switch($_POST['action']) { + case 'steps': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('view', 'cases/cases_StepsTree'); + G::RenderPage('publish', 'raw'); + break; + case 'information': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('view', 'cases/cases_InformationTree'); + G::RenderPage('publish', 'raw'); + break; + case 'actions': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('view', 'cases/cases_ActionsTree'); + G::RenderPage('publish', 'raw'); + break; + case 'showProcessMap': + $oTemplatePower = new TemplatePower(PATH_TPL . 'processes/processes_Map.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + $oHeadPublisher = & headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + var pb=leimnud.dom.capture("tag.body 0"); + Pm=new processmap(); + + var params = "{\"uid\":\"' . $_SESSION['PROCESS'] . '\",\"mode\":false,\"ct\":false}"; + // maximun x and y position + var xPos = 0; + var yPos = 0; + + //obtaining the processmap object for the current process + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : "../processes/processes_Ajax", + async : false, + method: "POST", + args : "action=load&data="+params + }); + // make the ajax call + oRPC.make(); + var response = eval(\'(\' + oRPC.xmlhttp.responseText + \')\'); + //alert(response); + + for (var i in response){ + if (i==\'task\'){ + elements = response[i]; + for (var j in elements){ + if (elements[j].uid!=undefined){ + if (elements[j].position.x > xPos){ + xPos = elements[j].position.x; + } + if (elements[j].position.y > yPos){ + yPos = elements[j].position.y; + } + } + } + } + } + + Pm.options = { + target : "pm_target", + dataServer: "../processes/processes_Ajax", + uid : "' . $_SESSION['PROCESS'] . '", + lang : "' . SYS_LANG . '", + theme : "processmaker", + size : {w:xPos+200,h:yPos+150}, + images_dir: "/jscore/processmap/core/images/", + rw : false, + hideMenu : false + } + Pm.make();'); + G::RenderPage('publish', 'raw'); + break; + case 'showLeyends': + $aFields = array(); + $aFields['sLabel1'] = G::LoadTranslation('ID_TASK_IN_PROGRESS'); + $aFields['sLabel2'] = G::LoadTranslation('ID_COMPLETED_TASK'); + $aFields['sLabel3'] = G::LoadTranslation('ID_PENDING_TASK'); + $aFields['sLabel4'] = G::LoadTranslation('ID_PARALLEL_TASK'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('smarty', 'cases/cases_Leyends', '', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + case 'showProcessInformation': + require_once 'classes/model/Process.php'; + $oProcess = new Process(); + $aFields = $oProcess->load($_SESSION['PROCESS']); + require_once 'classes/model/Users.php'; + $oUser = new Users(); + try { + $aUser = $oUser->load($aFields['PRO_CREATE_USER']); + $aFields['PRO_AUTHOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + } catch ( Exception $oError ) { + $aFields['PRO_AUTHOR'] = '(USER DELETED)'; + } + $aFields['PRO_CREATE_DATE'] = date('F j, Y', strtotime($aFields['PRO_CREATE_DATE'])); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ProcessInformation', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + case 'showTransferHistory': + G::LoadClass("case"); + $c = Cases::getTransferHistoryCriteria($_SESSION['APPLICATION']); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_TransferHistory', $c, array()); + G::RenderPage('publish', 'raw'); + break; + case 'showDynaformListHistory': + require_once 'classes/model/AppHistory.php'; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('view', 'cases/cases_DynaformHistory'); + G::RenderPage('publish', 'raw'); + break; + case 'showTaskInformation': + require_once 'classes/model/AppDelegation.php'; + require_once 'classes/model/Task.php'; + $oTask = new Task(); + $aFields = $oTask->load($_SESSION['TASK']); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::APP_UID, $_SESSION['APPLICATION']); + $oCriteria->add(AppDelegationPeer::DEL_INDEX, $_SESSION['INDEX']); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aDelegation = $oDataset->getRow(); + $iDiff = strtotime($aDelegation['DEL_FINISH_DATE']) - strtotime($aDelegation['DEL_INIT_DATE']); + $aFields['INIT_DATE'] = ($aDelegation['DEL_INIT_DATE'] != null ? $aDelegation['DEL_INIT_DATE'] : G::LoadTranslation('ID_CASE_NOT_YET_STARTED')); + $aFields['DUE_DATE'] = ($aDelegation['DEL_TASK_DUE_DATE'] != null ? $aDelegation['DEL_TASK_DUE_DATE'] : G::LoadTranslation('ID_NOT_FINISHED')); + $aFields['FINISH'] = ($aDelegation['DEL_FINISH_DATE'] != null ? $aDelegation['DEL_FINISH_DATE'] : G::LoadTranslation('ID_NOT_FINISHED')); + $aFields['DURATION'] = ($aDelegation['DEL_FINISH_DATE'] != null ? (int) ($iDiff / 3600) . ' ' . ((int) ($iDiff / 3600) == 1 ? G::LoadTranslation('ID_HOUR') : G::LoadTranslation('ID_HOURS')) . ' ' . (int) (($iDiff % 3600) / 60) . ' ' . ((int) (($iDiff % 3600) / 60) == 1 ? G::LoadTranslation('ID_MINUTE') : G::LoadTranslation('ID_MINUTES')) . ' ' . (int) (($iDiff % 3600) % 60) . ' ' . ((int) (($iDiff % 3600) % 60) == 1 ? G::LoadTranslation('ID_SECOND') : G::LoadTranslation('ID_SECONDS')) : G::LoadTranslation('ID_NOT_FINISHED')); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_TaskInformation', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + case 'showTaskDetails': + require_once 'classes/model/AppDelegation.php'; + require_once 'classes/model/Task.php'; + require_once 'classes/model/Users.php'; + $oTask = new Task(); + $aRow = $oTask->load($_POST['sTaskUID']); + $sTitle = $aRow['TAS_TITLE']; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_TASK_DUE_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + $oCriteria->addJoin(AppDelegationPeer::USR_UID, UsersPeer::USR_UID, Criteria::LEFT_JOIN); + $oCriteria->add(AppDelegationPeer::APP_UID, $_SESSION['APPLICATION']); + $oCriteria->add(AppDelegationPeer::TAS_UID, $_POST['sTaskUID']); + $oCriteria->addDescendingOrderByColumn(AppDelegationPeer::DEL_INDEX); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $iDiff = strtotime($aRow['DEL_FINISH_DATE']) - strtotime($aRow['DEL_INIT_DATE']); + $aFields = array(); + $aFields['TASK'] = $sTitle; + $aFields['USER'] = ($aRow['USR_UID'] != null ? $aRow['USR_FIRSTNAME'] . ' ' . $aRow['USR_LASTNAME'] : G::LoadTranslation('ID_NONE')); + $aFields['INIT_DATE'] = ($aRow['DEL_INIT_DATE'] != null ? $aRow['DEL_INIT_DATE'] : G::LoadTranslation('ID_CASE_NOT_YET_STARTED')); + $aFields['DUE_DATE'] = ($aRow['DEL_TASK_DUE_DATE'] != null ? $aRow['DEL_TASK_DUE_DATE'] : G::LoadTranslation('ID_CASE_NOT_YET_STARTED')); + $aFields['FINISH'] = ($aRow['DEL_FINISH_DATE'] != null ? $aRow['DEL_FINISH_DATE'] : G::LoadTranslation('ID_NOT_FINISHED')); + $aFields['DURATION'] = ($aRow['DEL_FINISH_DATE'] != null ? (int) ($iDiff / 3600) . ' ' . ((int) ($iDiff / 3600) == 1 ? G::LoadTranslation('ID_HOUR') : G::LoadTranslation('ID_HOURS')) . ' ' . (int) (($iDiff % 3600) / 60) . ' ' . ((int) (($iDiff % 3600) / 60) == 1 ? G::LoadTranslation('ID_MINUTE') : G::LoadTranslation('ID_MINUTES')) . ' ' . (int) (($iDiff % 3600) % 60) . ' ' . ((int) (($iDiff % 3600) % 60) == 1 ? G::LoadTranslation('ID_SECOND') : G::LoadTranslation('ID_SECONDS')) : G::LoadTranslation('ID_NOT_FINISHED')); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_TaskDetails', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + case 'showUsers': + switch($_POST['TAS_ASSIGN_TYPE']) { + case 'BALANCED': + G::LoadClass('user'); + $oUser = new User(new DBConnection()); + $oUser->load($_POST['USR_UID']); + echo $oUser->Fields['USR_FIRSTNAME'] . ' ' . $oUser->Fields['USR_LASTNAME'] . '<input type="hidden" name="form[TASKS][1][USR_UID]" id="form[TASKS][1][USR_UID]" value="' . $_POST['USR_UID'] . '">'; + break; + case 'MANUAL': + $sAux = '<select name="form[TASKS][1][USR_UID]" id="form[TASKS][1][USR_UID]">'; + $oSession = new DBSession(new DBConnection()); + $oDataset = $oSession->Execute("SELECT + TU.USR_UID AS USR_UID, + CONCAT(U.USR_LASTNAME, ' ', U.USR_FIRSTNAME) AS USR_FULLNAME + FROM + TASK_USER AS TU + LEFT JOIN + USERS AS U + ON ( + TU.USR_UID = U.USR_UID + ) + WHERE + TU.TAS_UID = '" . $_POST['TAS_UID'] . "' AND + TU.TU_TYPE = 1 AND + TU.TU_RELATION = 1 AND + U.USR_STATUS = 1"); + while($aRow = $oDataset->Read()) { + $sAux .= '<option value="' . $aRow['USR_UID'] . '">' . $aRow['USR_FULLNAME'] . '</option>'; + } + $sAux .= '</select>'; + echo $sAux; + break; + case 'EVALUATE': + G::LoadClass('application'); + $oApplication = new Application(new DBConnection()); + $oApplication->load($_SESSION['APPLICATION']); + $sUser = ''; + if($_POST['TAS_ASSIGN_VARIABLE'] != '') { + if(isset($oApplication->Fields['APP_DATA'][str_replace('@@', '', $_POST['TAS_ASSIGN_VARIABLE'])])) { + $sUser = $oApplication->Fields['APP_DATA'][str_replace('@@', '', $_POST['TAS_ASSIGN_VARIABLE'])]; + } + } + if($sUser != '') { + G::LoadClass('user'); + $oUser = new User(new DBConnection()); + $oUser->load($sUser); + echo $oUser->Fields['USR_FIRSTNAME'] . ' ' . $oUser->Fields['USR_LASTNAME'] . '<input type="hidden" name="form[TASKS][1][USR_UID]" id="form[TASKS][1][USR_UID]" value="' . $sUser . '">'; + } else { + echo '<strong>Error: </strong>' . $_POST['TAS_ASSIGN_VARIABLE'] . ' ' . G::LoadTranslation('ID_EMPTY'); + echo '<input type="hidden" name="_ERROR_" id="_ERROR_" value="">'; + } + break; + case 'SELFSERVICE': + //Next release + break; + } + break; + + case 'cancelCase': + $oCase = new Cases(); + $multiple = false; + + if( isset($_POST['APP_UID']) && isset($_POST['DEL_INDEX']) ) { + $APP_UID = $_POST['APP_UID']; + $DEL_INDEX = $_POST['DEL_INDEX']; + + $appUids = explode(',', $APP_UID); + $delIndexes = explode(',', $DEL_INDEX); + if( count($appUids) > 1 && count($delIndexes) > 1 ) + $multiple = true; + } else if( isset($_POST['sApplicationUID']) && isset($_POST['iIndex']) ){ + $APP_UID = $_POST['sApplicationUID']; + $DEL_INDEX = $_POST['iIndex']; + } else { + $APP_UID = $_SESSION['APPLICATION']; + $DEL_INDEX = $_SESSION['INDEX']; + } + + if( $multiple ) { + foreach($appUids as $i=>$appUid) + $oCase->cancelCase($appUid, $delIndexes[$i], $_SESSION['USER_LOGGED']); + } else + $oCase->cancelCase($APP_UID, $DEL_INDEX, $_SESSION['USER_LOGGED']); + break; + + case 'reactivateCase': + $sApplicationUID = isset($_POST['sApplicationUID']) ? $_POST['sApplicationUID'] : $_SESSION['APPLICATION']; + $iIndex = (isset($_POST['sApplicationUID'])) ? $_POST['iIndex'] : $_SESSION['INDEX']; + $oCase = new Cases(); + $oCase->reactivateCase($sApplicationUID, $iIndex, $_SESSION['USER_LOGGED']); + break; + case 'showPauseCaseInput': + //echo '<input type=button onclick="close_pauseCase()" value="Cancel">'; + $aFields = Array(); + $G_PUBLISH = new Publisher(); + + $aFields['TIME_STAMP'] = G::getformatedDate(date('Y-m-d'), 'M d, yyyy', SYS_LANG); + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_UnpauseDateInput', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + + case 'pauseCase': + $unpausedate = $_POST['unpausedate']; + $oCase = new Cases(); + if( isset($_POST['APP_UID']) && isset($_POST['DEL_INDEX']) ) { + $APP_UID = $_POST['APP_UID']; + $DEL_INDEX = $_POST['DEL_INDEX']; + } else if( isset($_POST['sApplicationUID']) && isset($_POST['iIndex']) ){ + $APP_UID = $_POST['sApplicationUID']; + $DEL_INDEX = $_POST['iIndex']; + } else { + $APP_UID = $_SESSION['APPLICATION']; + $DEL_INDEX = $_SESSION['INDEX']; + } + + $oCase->pauseCase($APP_UID, $DEL_INDEX, $_SESSION['USER_LOGGED'], $unpauseDate); + break; + + case 'unpauseCase': + $sApplicationUID = (isset($_POST['sApplicationUID'])) ? $_POST['sApplicationUID'] : $_SESSION['APPLICATION']; + $iIndex = (isset($_POST['sApplicationUID'])) ? $_POST['iIndex'] : $_SESSION['INDEX']; + $oCase = new Cases(); + $oCase->unpauseCase($sApplicationUID, $iIndex, $_SESSION['USER_LOGGED']); + break; + case 'deleteCase': + $oCase = new Cases(); + $sApplicationUID = (isset($_POST['sApplicationUID'])) ? $_POST['sApplicationUID'] : $_SESSION['APPLICATION']; + $oCase->removeCase($sApplicationUID); + break; + case 'view_reassignCase': + G::LoadClass('groups'); + G::LoadClass('tasks'); + + $oTasks = new Tasks(); + $aAux = $oTasks->getGroupsOfTask($_SESSION['TASK'], 1); + $row = array(); + + $groups = new Groups(); + foreach($aAux as $aGroup) { + $aUsers = $groups->getUsersOfGroup($aGroup['GRP_UID']); + foreach($aUsers as $aUser) { + if($aUser['USR_UID'] != $_SESSION['USER_LOGGED']) { + $row[] = $aUser['USR_UID']; + } + } + } + + $aAux = $oTasks->getUsersOfTask($_SESSION['TASK'], 1); + foreach($aAux as $aUser) { + if($aUser['USR_UID'] != $_SESSION['USER_LOGGED']) { + $row[] = $aUser['USR_UID']; + } + } + + require_once 'classes/model/Users.php'; + $c = new Criteria('workflow'); + $c->addSelectColumn(UsersPeer::USR_UID); + $c->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $c->addSelectColumn(UsersPeer::USR_LASTNAME); + $c->add(UsersPeer::USR_UID, $row, Criteria::IN); + + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_viewreassignCase', $c); + G::RenderPage('publish', 'raw'); + break; + case 'reassignCase': + $cases = new Cases(); + $cases->reassignCase($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], $_POST['USR_UID'], $_POST['THETYPE']); + break; + case 'toRevisePanel': + $_GET['APP_UID'] = $_POST['APP_UID']; + $_GET['DEL_INDEX'] = $_POST['DEL_INDEX']; + $G_PUBLISH = new Publisher(); + + echo "<iframe scrolling='no' style='border:none;height=300px;width:240px;' src='casesToRevisePanelExtJs?APP_UID={$_GET['APP_UID']}&DEL_INDEX={$_GET['DEL_INDEX']}'></iframe>"; +// $G_PUBLISH->AddContent( 'smarty', 'cases/cases_toRevise' ); +// $G_PUBLISH->AddContent('smarty', 'cases/cases_toReviseIn', '', '', array()); + G::RenderPage('publish', 'raw'); + break; + case 'showUploadedDocuments': + $oCase = new Cases(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_AllInputdocsList', $oCase->getAllUploadedDocumentsCriteria($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['TASK'], $_SESSION['USER_LOGGED'])); + G::RenderPage('publish', 'raw'); + break; + case 'showUploadedDocument': + require_once 'classes/model/AppDocument.php'; + require_once 'classes/model/AppDelegation.php'; + require_once 'classes/model/InputDocument.php'; + require_once 'classes/model/Users.php'; + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_POST['APP_DOC_UID']); + $oInputDocument = new InputDocument(); + if($oAppDocument->Fields['DOC_UID'] != - 1) { + $Fields = $oInputDocument->load($oAppDocument->Fields['DOC_UID']); + } else { + $Fields = array('INP_DOC_FORM_NEEDED'=>'', 'FILENAME'=>$oAppDocument->Fields['APP_DOC_FILENAME']); + } + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::APP_UID, $oAppDocument->Fields['APP_UID']); + $oCriteria->add(AppDelegationPeer::DEL_INDEX, $oAppDocument->Fields['DEL_INDEX']); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $oTask = new Task(); + try { + $aTask = $oTask->load($aRow['TAS_UID']); + $Fields['ORIGIN'] = $aTask['TAS_TITLE']; + $oAppDocument->Fields['VIEW'] = G::LoadTranslation('ID_OPEN'); + } catch ( Exception $oException ) { + $Fields['ORIGIN'] = '(TASK DELETED)'; + } + + try { + $oUser = new Users(); + $aUser = $oUser->load($oAppDocument->Fields['USR_UID']); + $Fields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + } catch ( Exception $e ) { + $Fields['CREATOR'] = '***'; + } + switch($Fields['INP_DOC_FORM_NEEDED']) { + case 'REAL': + $sXmlForm = 'cases/cases_ViewAnyInputDocument2'; + break; + case 'VIRTUAL': + $sXmlForm = 'cases/cases_ViewAnyInputDocument1'; + break; + case 'VREAL': + $sXmlForm = 'cases/cases_ViewAnyInputDocument3'; + break; + default: + $sXmlForm = 'cases/cases_ViewAnyInputDocument'; + break; + } + //$oAppDocument->Fields['VIEW'] = G::LoadTranslation('ID_OPEN'); + $oAppDocument->Fields['FILE'] = 'cases_ShowDocument?a=' . $_POST['APP_DOC_UID'] . '&r=' . rand(); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', G::array_merges($Fields, $oAppDocument->Fields), ''); + G::RenderPage('publish', 'raw'); + break; + case 'showGeneratedDocuments': + $oCase = new Cases(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_AllOutputdocsList', $oCase->getAllGeneratedDocumentsCriteria($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['TASK'], $_SESSION['USER_LOGGED'])); + G::RenderPage('publish', 'raw'); + break; + case 'showGeneratedDocument': + require_once 'classes/model/AppDocument.php'; + require_once 'classes/model/AppDelegation.php'; + $oAppDocument = new AppDocument(); + $aFields = $oAppDocument->load($_POST['APP_DOC_UID']); + require_once 'classes/model/OutputDocument.php'; + $oOutputDocument = new OutputDocument(); + $aOD = $oOutputDocument->load($aFields['DOC_UID']); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::APP_UID, $aFields['APP_UID']); + $oCriteria->add(AppDelegationPeer::DEL_INDEX, $aFields['DEL_INDEX']); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $oTask = new Task(); + $aTask = $oTask->load($aRow['TAS_UID']); + $aFields['ORIGIN'] = $aTask['TAS_TITLE']; + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $aUser = $oUser->load($aFields['USR_UID']); + $aFields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + $aFields['VIEW'] = G::LoadTranslation('ID_OPEN'); + $aFields['FILE1'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=doc&random=' . rand(); + $aFields['FILE2'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=pdf&random=' . rand(); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewAnyOutputDocument', '', G::array_merges($aOD, $aFields), ''); + G::RenderPage('publish', 'raw'); + break; + + case 'showDynaformList': + $oCase = new Cases(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_AllDynaformsList', $oCase->getallDynaformsCriteria($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['TASK'], $_SESSION['USER_LOGGED'])); + G::RenderPage('publish', 'raw'); + break; + + case 'showDynaform': + $G_PUBLISH = new Publisher(); + $oCase = new Cases(); + $Fields = $oCase->loadCase($_SESSION['APPLICATION']); + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = '#'; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_ACTION'] = 'return false;'; + $_SESSION['DYN_UID_PRINT'] = $_POST['DYN_UID']; + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS'] . '/' . $_POST['DYN_UID'], '', $Fields['APP_DATA'], '', '', 'view'); + G::RenderPage('publish', 'raw'); + break; + case 'showDynaformHistory': + $G_PUBLISH = new Publisher(); + $FieldsHistory=unserialize($_SESSION['HISTORY_DATA']); + $Fields['APP_DATA'] = $FieldsHistory[$_POST['HISTORY_ID']]; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = '#'; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_ACTION'] = 'return false;'; + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS'] . '/' . $_POST['DYN_UID'], '', $Fields['APP_DATA'], '', '', 'view'); + G::RenderPage('publish', 'raw'); + break; + + case 'adhocAssignmentUsers': + G::LoadClass('groups'); + G::LoadClass('tasks'); + $oTasks = new Tasks(); + $aAux = $oTasks->getGroupsOfTask($_SESSION['TASK'], 2); + $aAdhocUsers = array(); + $oGroups = new Groups(); + foreach($aAux as $aGroup) { + $aUsers = $oGroups->getUsersOfGroup($aGroup['GRP_UID']); + foreach($aUsers as $aUser) { + if($aUser['USR_UID'] != $_SESSION['USER_LOGGED']) { + $aAdhocUsers[] = $aUser['USR_UID']; + } + } + } + $aAux = $oTasks->getUsersOfTask($_SESSION['TASK'], 2); + foreach($aAux as $aUser) { + if($aUser['USR_UID'] != $_SESSION['USER_LOGGED']) { + $aAdhocUsers[] = $aUser['USR_UID']; + } + } + require_once 'classes/model/Users.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->add(UsersPeer::USR_UID, $aAdhocUsers, Criteria::IN); + + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_viewreassignCase', $oCriteria, array('THETYPE'=>'ADHOC')); + G::RenderPage('publish', 'raw'); + break; + + case 'showHistoryMessages': + $oCase = new Cases(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_Messages', $oCase->getHistoryMessagesTracker($_SESSION['APPLICATION'])); + G::RenderPage('publish', 'raw'); + break; + + case 'showHistoryMessage': + $G_PUBLISH = new Publisher(); + $oCase = new Cases(); + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_MessagesView', '', $oCase->getHistoryMessagesTrackerView($_POST['APP_UID'], $_POST['APP_MSG_UID'])); + G::RenderPage('publish', 'raw'); + break; + + case 'deleteUploadedDocument': + require_once 'classes/model/AppDocument.php'; + $oAppDocument = new AppDocument(); + $oAppDocument->remove($_POST['DOC']); + $oCase = new Cases(); + $oCase->getAllUploadedDocumentsCriteria($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['TASK'], $_SESSION['USER_LOGGED']); + break; + + case 'deleteGeneratedDocument': + require_once 'classes/model/AppDocument.php'; + $oAppDocument = new AppDocument(); + //$oAppDocument->remove($_POST['DOC']); + $oCase = new Cases(); + $oCase->getAllGeneratedDocumentsCriteria($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['TASK'], $_SESSION['USER_LOGGED']); + break; + + /* @Author Erik Amaru Ortiz <erik@colosa.com> */ + case 'resendMessage': + require_once 'classes/model/Configuration.php'; + G::LoadClass('spool'); + + $oCase = new Cases(); + $data = $oCase->getHistoryMessagesTrackerView($_POST['APP_UID'], $_POST['APP_MSG_UID']); + //print_r($data); + + $oConfiguration = new Configuration(); + $sDelimiter = DBAdapter::getStringDelimiter(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ConfigurationPeer::CFG_UID, 'Emails'); + $oCriteria->add(ConfigurationPeer::OBJ_UID, ''); + $oCriteria->add(ConfigurationPeer::PRO_UID, ''); + $oCriteria->add(ConfigurationPeer::USR_UID, ''); + $oCriteria->add(ConfigurationPeer::APP_UID, ''); + if(ConfigurationPeer::doCount($oCriteria) == 0) { + $oConfiguration->create(array('CFG_UID'=>'Emails', 'OBJ_UID'=>'', 'CFG_VALUE'=>'', 'PRO_UID'=>'', 'USR_UID'=>'', 'APP_UID'=>'')); + $aConfiguration = array(); + } else { + $aConfiguration = $oConfiguration->load('Emails', '', '', '', ''); + if($aConfiguration['CFG_VALUE'] != '') { + $aConfiguration = unserialize($aConfiguration['CFG_VALUE']); + } else { + $aConfiguration = array(); + } + } + + $oSpool = new spoolRun(); + $oSpool->setConfig(array( + 'MESS_ENGINE' => $aConfiguration['MESS_ENGINE'], + 'MESS_SERVER' => $aConfiguration['MESS_SERVER'], + 'MESS_PORT' => $aConfiguration['MESS_PORT'], + 'MESS_ACCOUNT' => $aConfiguration['MESS_ACCOUNT'], + 'MESS_PASSWORD' => $aConfiguration['MESS_PASSWORD'], + 'SMTPAuth' => $aConfiguration['MESS_RAUTH'] + )); + + $oSpool->create(array( + 'msg_uid' => $data['MSG_UID'], + 'app_uid' => $data['APP_UID'], + 'del_index' => $data['DEL_INDEX'], + 'app_msg_type' => $data['APP_MSG_TYPE'], + 'app_msg_subject'=> $data['APP_MSG_SUBJECT'], + 'app_msg_from' => $data['APP_MSG_FROM'], + 'app_msg_to' => $data['APP_MSG_TO'], + 'app_msg_body' => $data['APP_MSG_BODY'], + 'app_msg_cc' => $data['APP_MSG_CC'], + 'app_msg_bcc' => $data['APP_MSG_BCC'], + 'app_msg_attach'=> $data['APP_MSG_ATTACH'], + 'app_msg_template'=>$data['APP_MSG_TEMPLATE'], + 'app_msg_status'=> 'pending' + )); + $oSpool->sendMail(); + + break; + + /* @Author Erik Amaru Ortiz <erik@colosa.com> */ + case 'showdebug': + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('view', 'cases/showDebugFrame'); + G::RenderPage('publish', 'raw'); + break; + + /* @Author Erik Amaru Ortiz <erik@colosa.com> */ + case 'reassignByUserList': + $APP_UIDS = explode(',', $_POST['APP_UIDS']); + $sReassignFromUser = $_POST['FROM_USR_ID']; + + G::LoadClass('tasks'); + G::LoadClass('groups'); + G::LoadClass('case'); + + $oTasks = new Tasks(); + $oGroups = new Groups(); + $oUser = new Users(); + $oCases = new Cases(); + + $aCasesList = Array(); + + foreach ( $APP_UIDS as $APP_UID ) { + $aCase = $oCases->loadCaseInCurrentDelegation($APP_UID); + + $aUsersInvolved = Array(); + $aCaseGroups = $oTasks->getGroupsOfTask($aCase['TAS_UID'], 1); + + foreach ( $aCaseGroups as $aCaseGroup ) { + $aCaseUsers = $oGroups->getUsersOfGroup($aCaseGroup['GRP_UID']); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); + $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } + } + + $aCaseUsers = $oTasks->getUsersOfTask($aCase['TAS_UID'], 1); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); + $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } + $oTmp = new stdClass(); + $oTmp->items = $aUsersInvolved; + $oTmp->id = $aCase['APP_UID']; + $aCase['USERS'] = $oTmp; + array_push($aCasesList, $aCase); + } + + $filedNames = Array ( + "APP_UID", + "APP_NUMBER", + "APP_UPDATE_DATE", + "DEL_PRIORITY", + "DEL_INDEX", + "TAS_UID", + "DEL_INIT_DATE", + "DEL_FINISH_DATE", + "USR_UID", + "APP_STATUS", + "DEL_TASK_DUE_DATE", + "APP_CURRENT_USER", + "APP_TITLE", + "APP_PRO_TITLE", + "APP_TAS_TITLE", + "APP_DEL_PREVIOUS_USER", + "USERS" + ); + + $aCasesList = array_merge(Array($filedNames), $aCasesList); + + global $_DBArray; + $_DBArray['reassign_byuser'] = $aCasesList; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('reassign_byuser'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-reassigByUser2', 'cases/cases_ToReassignByUserList2', $oCriteria); + G::RenderPage('publish', 'raw'); + + break; + + /* @Author Erik Amaru Ortiz <erik@colosa.com> */ + case 'reassignByUser': + G::LoadClass('case'); + + $oCases = new Cases(); + $aCases = Array(); + + if( isset($_POST['items']) && trim($_POST['items']) != '' ){ + $sItems = $_POST['items']; + $aItems = explode(',', $sItems); + $FROM_USR_UID = $_POST['USR_UID']; + + foreach($aItems as $item){ + list($APP_UID, $USR_UID) = explode('|', $item); + $aCase = $oCases->loadCaseInCurrentDelegation($APP_UID); + $oCase->reassignCase($aCase['APP_UID'], $aCase['DEL_INDEX'], $FROM_USR_UID, $USR_UID); + array_push($aCases, $aCase); + } + //G::pr($aCases); + + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $sText = ''; + foreach ($aCases as $aCase) { + $aCaseUpdated = $oCases->loadCaseInCurrentDelegation($aCase['APP_UID']); + $aUser = $oUser->load($aCaseUpdated['USR_UID']); + $sText .= $aCaseUpdated['APP_PRO_TITLE'] .' - '. ' Case: ' . $aCaseUpdated['APP_NUMBER'] . '# (' . $aCaseUpdated['APP_TAS_TITLE'] . ') <b> => Reassigned to => </b> <font color="blue">' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . ' [' . $aUser['USR_USERNAME'] . ']' . '</font><br />'; + } + + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $sText; + $aMessage['URL'] = 'cases_ReassignByUser?REASSIGN_USER=' . $_POST['USR_UID']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ReassignShowInfo', '', $aMessage); + G::RenderPage('publish', 'raw'); + } + break; + case "uploadInputDocument": + //krumo($_POST); + $G_PUBLISH = new Publisher; + $Fields['DOC_UID']=$_POST['docID']; + $Fields['APP_DOC_UID']=$_POST['appDocId']; + $Fields['actionType']=$_POST['actionType']; + $Fields['docVersion']=$_POST['docVersion']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_AttachInputDocumentGeneral', '', $Fields, 'cases_SaveDocument?UID=' . $_POST['docID']); + G::RenderPage('publish', 'raw'); + + break; + case "uploadToReviseInputDocument": + //krumo($_POST); + $G_PUBLISH = new Publisher; + $Fields['DOC_UID']=$_POST['docID']; + $Fields['APP_DOC_UID']=$_POST['appDocId']; + $Fields['actionType']=$_POST['actionType']; + $Fields['docVersion']=$_POST['docVersion']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_AttachInputDocumentGeneral', '', $Fields, 'cases_SupervisorSaveDocument?UID=' . $_POST['docID'] . '&APP_UID=' . $_POST['appDocId']); + G::RenderPage('publish', 'raw'); + + break; + case "inputDocumentVersionHistory": + //krumo($_POST); + $G_PUBLISH = new Publisher; + $Fields['DOC_UID']=$_POST['docID']; + $Fields['APP_DOC_UID']=$_POST['appDocId']; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_InputdocsListHistory', $oCase->getInputDocumentsCriteria($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_POST['docID'],$_POST['appDocId']), array());//$aFields + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_AttachInputDocumentGeneral', '', $Fields, 'cases_SaveDocument?UID=' . $_POST['docID']); + G::RenderPage('publish', 'raw'); + + break; + case "getCountCasesFolder": + + $json = new Services_JSON(); + $aTypes = Array('to_do', 'draft', 'cancelled', 'sent', 'paused', 'completed','selfservice','to_revise','to_reassign'); + $aTypesID = Array('to_do'=>'CASES_INBOX', 'draft'=>'CASES_DRAFT', 'cancelled'=>'CASES_CANCELLED', 'sent'=>'CASES_SENT', 'paused'=>'CASES_PAUSED', 'completed'=>'CASES_COMPLETED','selfservice'=>'CASES_SELFSERVICE','to_revise'=>'CASES_TO_REVISE','to_reassign'=>'CASES_TO_REASSIGN'); + + if(!isset($_POST['A'])){ + $oCases = new Cases(); + $aCount = $oCases->getAllConditionCasesCount($aTypes, true); + echo $json->encode($aCount); + }else{ + echo $json->encode($aTypesID); + } + break; + + default: + echo 'default'; +} +function getCasesTypeIDs(){ + $aTypes = Array('to_do', 'draft', 'cancelled', 'sent', 'paused', 'completed','selfservice','to_revise','to_reassign'); + return $aTypesID; +} diff --git a/workflow/engine/methods/cases/cases_CatchExecute.php b/workflow/engine/methods/cases/cases_CatchExecute.php new file mode 100644 index 000000000..b6176f75a --- /dev/null +++ b/workflow/engine/methods/cases/cases_CatchExecute.php @@ -0,0 +1,68 @@ +<? +/** + * cases_CatchExecute.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +/* Permissions */ +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + + + if ( isset ( $_POST['form']['BTN_CANCEL'] ) ) { + header ( "Location: ../cases/main"); + die; + } + + /* Includes */ + G::LoadClass('case'); + + $oCase = new Cases(); + $sAppUid = $_SESSION['APPLICATION']; + $iDelIndex = $_SESSION['INDEX']; + + $oAppDelegation = new AppDelegation(); + $aDelegation = $oAppDelegation->load($sAppUid, $iDelIndex); + + //if there are no user in the delegation row, this case is still in selfservice + if ( $aDelegation['USR_UID'] == "" ) { + $oCase->setCatchUser( $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'] ); + } + else { + G::SendMessageText(G::LoadTranslation('ID_CASE_ALREADY_DERIVATED'), 'error'); + } + + //if the case is already derivated this link still works, and the case_Open will show only the cases Resume + $url = "../cases/cases_Open?APP_UID=". $_SESSION['APPLICATION'] . "&DEL_INDEX=". $_SESSION['INDEX']; + header ( "Location: $url"); diff --git a/workflow/engine/methods/cases/cases_CatchSelfService.php b/workflow/engine/methods/cases/cases_CatchSelfService.php new file mode 100644 index 000000000..cefba1c93 --- /dev/null +++ b/workflow/engine/methods/cases/cases_CatchSelfService.php @@ -0,0 +1,104 @@ +<?php +/** + * cases_Resume.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* Permissions */ +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('case'); + +$oCase = new Cases(); +$Fields = $oCase->loadCase( $_SESSION['APPLICATION'], $_SESSION['INDEX'] ); + + +/* Render page */ +require_once 'classes/model/Process.php'; +require_once 'classes/model/Task.php'; + +$objProc = new Process(); +$aProc = $objProc->load($Fields['PRO_UID' ] ); +$Fields['PRO_TITLE'] = $aProc['PRO_TITLE']; + +$objTask = new Task(); +$aTask = $objTask->load($Fields['TAS_UID' ] ); +$Fields['TAS_TITLE'] = $aTask['TAS_TITLE']; + +$Fields['STATUS'] .= ' ( '. G::LoadTranslation('ID_UNASSIGNED') . ' )'; + +//now getting information about the PREVIOUS task. If is the first task then no preious, use 1 +$oAppDel = new AppDelegation(); +$oAppDel->Load($Fields['APP_UID'], ($Fields['DEL_PREVIOUS']==0 ? $Fields['DEL_PREVIOUS'] = 1 : $Fields['DEL_PREVIOUS']) ); + +$aAppDel = $oAppDel->toArray(BasePeer::TYPE_FIELDNAME); +try { + $oCurUser = new Users(); + $oCurUser->load($aAppDel['USR_UID']); + $Fields['PREVIOUS_USER'] = $oCurUser->getUsrFirstname() . ' ' . $oCurUser->getUsrLastname(); +} +catch (Exception $oError) { + $Fields['PREVIOUS_USER'] = ''; +} + +$objTask = new Task(); +$aTask = $objTask->load($aAppDel['TAS_UID' ] ); +$Fields['PREVIOUS_TASK'] = $aTask['TAS_TITLE']; + +//To enable information (dynaforms, steps) before claim a case +$_SESSION['bNoShowSteps'] = true; +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'caseOptions'; +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = '_'; +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptCode(' + var Cse = {}; + Cse.panels = {}; + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.Package.Load("json",{Type:"file"}); + leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); + leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); + leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); + leimnud.exec(leimnud.fix.memoryLeak); + '); +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptFile('/jscore/cases/core/cases_Step.js'); + + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_CatchSelfService.xml', '', $Fields, 'cases_CatchExecute'); +G::RenderPage( 'publish', 'green-submenu'); diff --git a/workflow/engine/methods/cases/cases_Delete.php b/workflow/engine/methods/cases/cases_Delete.php new file mode 100644 index 000000000..68cfa3dd7 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Delete.php @@ -0,0 +1,60 @@ +<?php +/** + * cases_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* Permissions */ +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('case'); + +/* Process the info */ +try{ + $oCase = new Cases(); + if( isset($_POST['APP_UIDS']) ){ + $ids = explode(',', $_POST['APP_UIDS']); + foreach($ids as $id) + $oCase->removeCase($id); + + if( count($_POST['APP_UIDS']) > 1) + echo 'The Case was deleted successfully'; + else + echo 'All Cases were deleted successfully'; + } +} catch(Exception $e){ + echo $e->getMessage(); +} + + diff --git a/workflow/engine/methods/cases/cases_DeleteDocument.php b/workflow/engine/methods/cases/cases_DeleteDocument.php new file mode 100644 index 000000000..980f79da6 --- /dev/null +++ b/workflow/engine/methods/cases/cases_DeleteDocument.php @@ -0,0 +1,63 @@ +<?php +/** + * cases_DeleteDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* Permissions */ +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +require_once ( "classes/model/AppDocumentPeer.php" ); +G::LoadClass('case'); + +/* GET , POST & $_SESSION Vars */ + +/* Process the info */ +$oAppDocument = new AppDocument(); +$oAppDocument->remove($_GET['DOC']); +$oCase = new Cases(); +$oCase->thisIsTheCurrentUser($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'REDIRECT', 'cases_List'); +if ($_GET['TYPE'] == 'INPUT') +{ + $aNextStep = $oCase->getNextStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION'] - 1); +} +if ($_GET['TYPE'] == 'OUTPUT') +{ + $aNextStep = $oCase->getNextStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); +} +$_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; + +/* Redirect */ +G::header('location: ' . $aNextStep['PAGE']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Derivate.php b/workflow/engine/methods/cases/cases_Derivate.php new file mode 100644 index 000000000..024252d29 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Derivate.php @@ -0,0 +1,159 @@ +<? +/** + * cases_Derivate.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +/* Permissions */ +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('pmScript'); +G::LoadClass('case'); +G::LoadClass('derivation'); + +require_once 'classes/model/Event.php'; + +/* GET , POST & $_SESSION Vars */ +/* Process the info */ +$sStatus = 'TO_DO'; +foreach ($_POST['form']['TASKS'] as $aValues){ +} + +try { + //load data + $oCase = new Cases (); + //warning: we are not using the result value of function thisIsTheCurrentUser, so I'm commenting to optimize speed. + //$oCase->thisIsTheCurrentUser( $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'REDIRECT', 'cases_List'); + $appFields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $appFields['APP_DATA'] = array_merge($appFields['APP_DATA'], G::getSystemConstants()); + //cleaning debug variables + $_SESSION['TRIGGER_DEBUG']['DATA'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = Array(); + + $triggers = $oCase->loadTriggers( $_SESSION['TASK'], 'ASSIGN_TASK', -2, 'BEFORE'); + + //if there are some triggers to execute + if( sizeof($triggers) > 0) { + //Execute triggers before derivation + $appFields['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION['TASK'], 'ASSIGN_TASK', -2, 'BEFORE', $appFields['APP_DATA'] ); + + //save trigger variables for debugger + $_SESSION['TRIGGER_DEBUG']['info'][0]['NUM_TRIGGERS'] = sizeof($triggers); + $_SESSION['TRIGGER_DEBUG']['info'][0]['TIME'] = 'BEFORE'; + $_SESSION['TRIGGER_DEBUG']['info'][0]['TRIGGERS_NAMES'] = $oCase->getTriggerNames($triggers); + $_SESSION['TRIGGER_DEBUG']['info'][0]['TRIGGERS_VALUES'] = $triggers; + } + + $appFields['DEL_INDEX'] = $_SESSION['INDEX']; + $appFields['TAS_UID'] = $_SESSION['TASK']; + + $oCase->updateCase ( $_SESSION['APPLICATION'], $appFields); //Save data + + //derivate case + $oDerivation = new Derivation(); + $aCurrentDerivation = array( + 'APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX'], + 'APP_STATUS' => $sStatus, + 'TAS_UID' => $_SESSION['TASK'], + 'ROU_TYPE' => $_POST['form']['ROU_TYPE'] + ); + + $oDerivation->derivate( $aCurrentDerivation, $_POST['form']['TASKS'] ); + + $appFields = $oCase->loadCase( $_SESSION['APPLICATION'] ); //refresh appFields, because in derivations should change some values + $triggers = $oCase->loadTriggers( $_SESSION['TASK'], 'ASSIGN_TASK', -2, 'AFTER'); //load the triggers after derivation + if( sizeof($triggers) > 0 ) { + $appFields['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION['TASK'], 'ASSIGN_TASK', -2, 'AFTER', $appFields['APP_DATA'] ); //Execute triggers after derivation + + $_SESSION['TRIGGER_DEBUG']['info'][1]['NUM_TRIGGERS'] = sizeof($triggers); + $_SESSION['TRIGGER_DEBUG']['info'][1]['TIME'] = 'AFTER'; + $_SESSION['TRIGGER_DEBUG']['info'][1]['TRIGGERS_NAMES'] = $oCase->getTriggerNames($triggers); + $_SESSION['TRIGGER_DEBUG']['info'][1]['TRIGGERS_VALUES'] = $triggers; + } + $oCase->updateCase ( $_SESSION['APPLICATION'], $appFields); + + // Send notifications - Start + $oUser = new Users(); + $aUser = $oUser->load($_SESSION['USER_LOGGED']); + $sFromName = '"' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . '"'; + $oCase->sendNotifications($_SESSION['TASK'], $_POST['form']['TASKS'], $appFields['APP_DATA'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $sFromName); + // Send notifications - End + + // Events - Start + $oEvent = new Event(); + + $oEvent->closeAppEvents($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['TASK']); + $oCurrentAppDel = AppDelegationPeer::retrieveByPk($_SESSION['APPLICATION'], $_SESSION['INDEX']+1 ); + $multipleDelegation = false; + // check if there are multiple derivations + if( count($_POST['form']['TASKS'] ) >1 ) { + $multipleDelegation = true; + } + // If the case has been delegated + if ( isset($oCurrentAppDel) ) { + // if there is just a single derivation the TASK_UID can be set by the delegation data + if ( !$multipleDelegation ){ + $aCurrentAppDel = $oCurrentAppDel->toArray( BasePeer::TYPE_FIELDNAME); + $oEvent->createAppEvents($aCurrentAppDel['PRO_UID'], $aCurrentAppDel['APP_UID'], $aCurrentAppDel['DEL_INDEX'], $aCurrentAppDel['TAS_UID']); + } + else { + // else we need to check every task and create the events if it have any + foreach ( $_POST['form']['TASKS'] as $taskDelegated ){ + $aCurrentAppDel = $oCurrentAppDel->toArray( BasePeer::TYPE_FIELDNAME); + $oEvent->createAppEvents($aCurrentAppDel['PRO_UID'], $aCurrentAppDel['APP_UID'], $aCurrentAppDel['DEL_INDEX'], $taskDelegated['TAS_UID']); + } + } + } + //Events - End + + $aNextStep['PAGE'] = 'casesListExtJs'; + if( isset($_SESSION['PMDEBUGGER']) && $_SESSION['PMDEBUGGER'] ){ + $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $aNextStep['PAGE']; + G::header('location: ' . 'cases_Step?' .'breakpoint=triggerdebug'); + } + else { + G::header('location: casesListExtJs'); + } +} +catch ( Exception $e ){ + $aMessage = array(); + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank'); +} diff --git a/workflow/engine/methods/cases/cases_List.php b/workflow/engine/methods/cases/cases_List.php new file mode 100644 index 000000000..f002ba38c --- /dev/null +++ b/workflow/engine/methods/cases/cases_List.php @@ -0,0 +1,187 @@ +<?php +/** + * cases_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * Cases list (Refactored) + * By Erik A. O. <erik@colosa.com, aortiz.erik@gmail.com> + */ + +/* Permissions */ +if (($RBAC_Response = $RBAC->userCanAccess("PM_CASES"))!=1) return $RBAC_Response; + +/* Includes */ +G::LoadClass('case'); +G::LoadClass('configuration'); + +// $_GET['l'] has the type of cases list like todo,pause,cancel, all + +$conf = new Configurations(); +if (!isset($_GET['l'])) { + $confCasesList = $conf->loadObject('ProcessMaker','cases_List','',$_SESSION['USER_LOGGED'],''); + if (is_array($confCasesList)) { + $sTypeList = $confCasesList['sTypeList']; + } + else { + $sTypeList = 'to_do'; + } +} +else { + $sTypeList = $_GET['l']; + $confCasesList=array('sTypeList'=>$sTypeList); + $conf->saveObject($confCasesList,'ProcessMaker','cases_List','',$_SESSION['USER_LOGGED'],''); +} + +$sUIDUserLogged = $_SESSION['USER_LOGGED']; +$_SESSION['CASES_MENU_OPTION'] = $sTypeList; + +$oCases = new Cases(); + +/** here we verify if there is a any case with a unpause on this day*/ +if( $sTypeList === 'to_do' or $sTypeList === 'draft' or $sTypeList === 'paused') { + $oCases->ThrowUnpauseDaemon(); +} + +/* * + * Prepare the addtional filters before to show + * By Erik + */ + +$aAdditionalFilter = Array(); + + +if( isset($_GET['PROCESS_UID']) and $_GET['PROCESS_UID'] != "0" && $_GET['PROCESS_UID'] != ""){ + $PRO_UID = $_GET['PROCESS_UID']; + $aAdditionalFilter['PRO_UID'] = $PRO_UID; +} else { + $PRO_UID = "0"; +} +if( isset($_GET['READ']) and $_GET['READ'] == "1" ){ + $aAdditionalFilter['READ'] = $_GET['READ']; +} +if( isset($_GET['UNREAD']) and $_GET['UNREAD'] == "1" ){ + $aAdditionalFilter['UNREAD'] = $_GET['UNREAD']; +} + +if( isset($_GET['APP_STATUS_FILTER']) and $_GET['APP_STATUS_FILTER'] != "ALL" ){ + $aAdditionalFilter['APP_STATUS_FILTER'] = $_GET['APP_STATUS_FILTER']; +} + +if( isset($_GET['MINE']) and $_GET['MINE'] == "1" ){ + $aAdditionalFilter['MINE'] = $_GET['MINE']; +} + + + + +switch ( $sTypeList ) { + case 'to_do' : + if ( defined( 'ENABLE_CASE_LIST_OPTIMIZATION' ) ) { + $aCriteria = $oCases->prepareCriteriaForToDo($sUIDUserLogged); + $xmlfile = 'cases/cases_ListTodoNew'; + } + else + list($aCriteria, $xmlfile) = $oCases->getConditionCasesList( $sTypeList, $sUIDUserLogged, true, $aAdditionalFilter); + break; + default : + list($aCriteria, $xmlfile) = $oCases->getConditionCasesList( $sTypeList, $sUIDUserLogged, true, $aAdditionalFilter); +} + +/* +$rs = ApplicationPeer::doSelectRS($aCriteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $aRows1 = Array(); + while($rs->next()) { + $aRows1[] = $rs->getRow(); + + } + +g::pr($aRows1);die;*/ +/* GET , POST & $_SESSION Vars */ + +if( !isset($_GET['PROCESS_UID']) ) { + $oCase = new Cases(); + $rs = ApplicationPeer::doSelectRS($aCriteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aProcess = Array(); + while($rs->next()) { + $aRow = $rs->getRow(); + //g::pr($aRow); die; + if( !InAssocArray($aRow, 'PRO_UID', $aRow['PRO_UID']) ){ + array_push($aProcess, Array('PRO_UID'=>$aRow['PRO_UID'], 'PRO_TITLE'=>$aRow['APP_PRO_TITLE'])); + } + } + + $_DBArray['_PROCESSES'] = array_merge(Array(Array('PRO_UID'=>'char', 'PRO_TITLE'=>'char')), $aProcess); + $_SESSION['_DBArray'] = $_DBArray; +} else { + $_DBArray = $_SESSION['_DBArray']; +} + + +/* Render page */ +$G_PUBLISH = new Publisher; +$G_PUBLISH->ROWS_PER_PAGE = 12; + +if ($sTypeList == 'to_reassign') { + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', 'cases/cases_ReassignBy', '', array('REASSIGN_BY' => 1)); +} + +$aData = Array( + 'PROCESS_FILTER'=>$PRO_UID, + 'APP_STATUS_FILTER'=>(isset($_GET['APP_STATUS_FILTER'])?$_GET['APP_STATUS_FILTER']:'0') +); + +$G_PUBLISH->AddContent('propeltable', 'paged-table', $xmlfile, $aCriteria, $aData); + +G::RenderPage('publish', 'blank'); + + + +function InAssocArray($a, $k, $v){ + foreach($a as $item){ + if( isset($item[$k]) && $v == $item[$k]) return true; + } + return false; +} + + +?> + +<script> + try{ + oPropelTable = document.getElementById('publisherContent[0]'); + oTable = oPropelTable.getElementsByTagName('table'); + oTable[0].style.width = '98%'; + oTable[1].style.width = '98%'; + + parent.outerLayout.hide('east'); + parent.PANEL_EAST_OPEN = false; +if(parent.refreshCountFolders) parent.refreshCountFolders(); + }catch(e){} + +</script> + + diff --git a/workflow/engine/methods/cases/cases_New.php b/workflow/engine/methods/cases/cases_New.php new file mode 100644 index 000000000..ea1987596 --- /dev/null +++ b/workflow/engine/methods/cases/cases_New.php @@ -0,0 +1,162 @@ +<?php +/** + * cases_New.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //we're looking for the type of view + function putTypeView(){ + require_once 'classes/model/Configuration.php'; + $oConfiguration = new Configuration(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ConfigurationPeer::CFG_UID, 'StartNewCase'); + $oCriteria->add(ConfigurationPeer::USR_UID, $_SESSION['USER_LOGGED']); + + if(ConfigurationPeer::doCount($oCriteria)) { + $conf = ConfigurationPeer::doSelect($oCriteria); + return $conf[0]->getCfgValue(); + } else { + return 'dropdown'; + } + } + +$_GET['change']=(isset($_GET['change']))?$_GET['change']:putTypeView(); + + /* Permissions */ + switch ($RBAC->userCanAccess('PM_CASES')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + /* Includes */ + G::LoadClass('case'); + + /* GET , POST & $_SESSION Vars */ + + /* Menues */ + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_DRAFT'; + + /* Prepare page before to show */ + $aFields = array(); + $oCase = new Cases(); + $bCanStart = $oCase->canStartCase( $_SESSION['USER_LOGGED'] ); + if ($bCanStart) + { + $aFields['LANG'] = SYS_LANG; + $aFields['USER'] = $_SESSION['USER_LOGGED']; + $sXmlForm = 'cases/cases_New.xml'; + //$_DBArray['NewCase'] = $oCase->getStartCases( $_SESSION['USER_LOGGED'] ); + $_DBArray['NewCase'] = $oCase->getStartCasesPerType( $_SESSION['USER_LOGGED'], $_GET['change'] ); + + } + else { + $sXmlForm = 'cases/cases_CannotInitiateCase.xml'; + } + + if ( isset( $_SESSION['G_MESSAGE']) && strlen($_SESSION['G_MESSAGE']) > 0 ) { + $aMessage = array(); + $aMessage['MESSAGE'] = $_SESSION['G_MESSAGE']; + //$_SESSION['G_MESSAGE_TYPE']; + unset($_SESSION['G_MESSAGE']); + unset($_SESSION['G_MESSAGE_TYPE']); + } + + //get the config parameter to show in dropdown or list + require_once 'classes/model/Configuration.php'; + $oConfiguration = new Configuration(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ConfigurationPeer::CFG_UID, 'StartNewCase'); + $oCriteria->add(ConfigurationPeer::USR_UID, $_SESSION['USER_LOGGED']); + + if( ConfigurationPeer::doCount($oCriteria) == 0) { + $aData['CFG_UID'] = 'StartNewCase'; + $aData['OBJ_UID'] = ''; + $aData['CFG_VALUE'] = 'dropdown'; + $aData['PRO_UID'] = ''; + $aData['USR_UID'] = $_SESSION['USER_LOGGED']; + $aData['APP_UID'] = ''; + + $oConfig = new Configuration(); + $oConfig->create($aData); + $listType = 'dropdown'; + } + else { + $oConfiguration = new Configuration(); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ConfigurationPeer::CFG_UID, 'StartNewCase'); + $oCriteria->add(ConfigurationPeer::USR_UID, $_SESSION['USER_LOGGED']); + $conf = ConfigurationPeer::doSelect($oCriteria); + + $listType = $conf[0]->getCfgValue(); + } + if ( isset($_GET['change'] ) ) { + $listType= $_GET['change']; + $aData['CFG_UID'] = 'StartNewCase'; + $aData['OBJ_UID'] = ''; + $aData['CFG_VALUE'] = $listType; + $aData['PRO_UID'] = ''; + $aData['USR_UID'] = $_SESSION['USER_LOGGED']; + $aData['APP_UID'] = ''; + + $oConfig = new Configuration(); + $oConfig->update($aData); + } + + /* Render page */ + $G_PUBLISH = new Publisher; + $aFields['CHANGE_LINK'] = G::LoadTranslation( 'ID_CHANGE_VIEW' ); + + if ( isset ( $aMessage ) ) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + } + if ( $listType == 'dropdown' ) + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', $aFields, 'cases_Save'); + + if ( $listType == 'link' ) { + if ($bCanStart) $sXmlForm = 'cases/cases_NewRadioGroup.xml'; + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', $aFields, 'cases_Save'); + } + + if ( $listType == 'category' ) { + if ($bCanStart) $sXmlForm = 'cases/cases_NewCategory.xml'; + $G_PUBLISH->AddContent('view', 'cases/cases_NewCategory'); + } + + G::RenderPage( 'publish', 'blank' ); + +?> +<script> + parent.outerLayout.hide('east'); + parent.PANEL_EAST_OPEN = false; +</script> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_NextStep.php b/workflow/engine/methods/cases/cases_NextStep.php new file mode 100644 index 000000000..b11738ce5 --- /dev/null +++ b/workflow/engine/methods/cases/cases_NextStep.php @@ -0,0 +1,32 @@ +<?php +/** + * cases_NextStep.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_CASES"))!=1) return $RBAC_Response; +//go to the next step +G::LoadClass('case'); +$oCase = new Cases(); +$aNextStep = $oCase->getNextStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); +$_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; +G::header('location: ' . $aNextStep['PAGE']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Open.php b/workflow/engine/methods/cases/cases_Open.php new file mode 100644 index 000000000..c2d01d39f --- /dev/null +++ b/workflow/engine/methods/cases/cases_Open.php @@ -0,0 +1,166 @@ +<?php +/** + * cases_Open.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* Permissions */ +if( $RBAC->userCanAccess('PM_CASES') != 1 ) { + switch( $RBAC->userCanAccess('PM_CASES') ) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + break; + case - 1: + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + break; + } +} + +/* Includes */ +require_once 'classes/model/AppDelay.php'; +G::LoadClass('case'); + +$oCase = new Cases(); + +//cleaning the case session data +Cases::clearCaseSessionData(); + +try { + //Loading data for a Jump request + if( ! isset($_GET['APP_UID']) && isset($_GET['APP_NUMBER']) ) { + $_GET['APP_UID'] = $oCase->getApplicationUIDByNumber($_GET['APP_NUMBER']); + $_GET['DEL_INDEX'] = $oCase->getCurrentDelegation($_GET['APP_UID'], $_SESSION['USER_LOGGED']); + + //if the application doesn't exist + if( is_null($_GET['APP_UID']) ) { + G::SendMessageText(G::LoadTranslation('ID_CASE_DOES_NOT_EXISTS'), 'info'); + G::header('location: casesListExtJs'); + exit; + } + + //if the application exists but the + if( is_null($_GET['DEL_INDEX']) ) { + G::SendMessageText(G::LoadTranslation('ID_CASE_IS_CURRENTLY_WITH_ANOTHER_USER'), 'info'); + G::header('location: casesListExtJs'); + exit; + } + //wrong implemented, need refactored + //$participated = $oCase->userParticipatedInCase($_GET['APP_UID'], $_SESSION['USER_LOGGED']); ??????? + } + + $sAppUid = $_GET['APP_UID']; + $iDelIndex = $_GET['DEL_INDEX']; + $_action = isset($_GET['action'])? $_GET['action']: ''; + + //loading application data + $aFields = $oCase->loadCase($sAppUid, $iDelIndex); + + switch($aFields['APP_STATUS']){ + case 'DRAFT': + case 'TO_DO': + //check if the case is in pause, check a valid record in table APP_DELAY + if( AppDelay::isPaused($sAppUid, $iDelIndex) ) { + //the case is paused show only the resume + $_SESSION['APPLICATION'] = $sAppUid; + $_SESSION['INDEX'] = $iDelIndex; + $_SESSION['PROCESS'] = $aFields['PRO_UID']; + $_SESSION['TASK'] = -1; + $_SESSION['STEP_POSITION'] = 0; + + require_once (PATH_METHODS . 'cases' . PATH_SEP . 'cases_Resume.php'); + exit; + } + + //proceed and try to open the case + $oAppDelegation = new AppDelegation(); + $aDelegation = $oAppDelegation->load($sAppUid, $iDelIndex); + + //if there are no user in the delegation row, this case is in selfservice + if( $aDelegation['USR_UID'] == "" /*&& $aDelegation['DEL_THREAD_STATUS'] == 'SELFSERVICE'*/ ) { + + $_SESSION['APPLICATION'] = $sAppUid; + $_SESSION['INDEX'] = $iDelIndex; + $_SESSION['PROCESS'] = $aFields['PRO_UID']; + $_SESSION['TASK'] = -1; + $_SESSION['STEP_POSITION'] = 0; + + //if the task is in the valid selfservice tasks for this user, then catch the case, else just view the resume + if( $oCase->isSelfService($_SESSION['USER_LOGGED'], $aFields['TAS_UID']) ) { + require_once (PATH_METHODS . 'cases' . PATH_SEP . 'cases_CatchSelfService.php'); + } else + require_once (PATH_METHODS . 'cases' . PATH_SEP . 'cases_Resume.php'); + + exit; + } + + //if the current users is in the AppDelegation row, then open the case + if( ($aDelegation['USR_UID'] == $_SESSION['USER_LOGGED']) && $_action != 'sent' ) { + $_SESSION['APPLICATION'] = $sAppUid; + $_SESSION['INDEX'] = $iDelIndex; + + if( is_null($aFields['DEL_INIT_DATE']) ) { + $oCase->setDelInitDate($sAppUid, $iDelIndex); + $aFields = $oCase->loadCase($sAppUid, $iDelIndex); + } + + $_SESSION['PROCESS'] = $aFields['PRO_UID']; + $_SESSION['TASK'] = $aFields['TAS_UID']; + $_SESSION['STEP_POSITION'] = 0; + + /* Redirect to next step */ + unset($_SESSION['bNoShowSteps']); + $aNextStep = $oCase->getNextStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); + $sPage = $aNextStep['PAGE']; + + G::header('location: ' . $sPage); + + } else { + //when the case have another user or current user doesnt have rights to this selfservice, + //just view the case Resume + $_SESSION['APPLICATION'] = $sAppUid; + $_SESSION['INDEX'] = $iDelIndex; + $_SESSION['PROCESS'] = $aFields['PRO_UID']; + $_SESSION['TASK'] = -1; + $_SESSION['STEP_POSITION'] = 0; + require_once (PATH_METHODS . 'cases' . PATH_SEP . 'cases_Resume.php'); + } + break; + + default: //APP_STATUS <> DRAFT and TO_DO + $_SESSION['APPLICATION'] = $sAppUid; + $_SESSION['INDEX'] = $iDelIndex != "" ? $iDelIndex : $oCase->getCurrentDelegationCase($_GET['APP_UID']); + $_SESSION['PROCESS'] = $aFields['PRO_UID']; + $_SESSION['TASK'] = -1; + $_SESSION['STEP_POSITION'] = 0; + + require_once (PATH_METHODS . 'cases' . PATH_SEP . 'cases_Resume.php'); + } +} catch( Exception $e ) { + $aMessage = array (); + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage); + G::RenderPage('publishBlank', 'blank'); +} diff --git a/workflow/engine/methods/cases/cases_OpenToRevise.php b/workflow/engine/methods/cases/cases_OpenToRevise.php new file mode 100644 index 000000000..6de2d8a62 --- /dev/null +++ b/workflow/engine/methods/cases/cases_OpenToRevise.php @@ -0,0 +1,79 @@ +<?php +/** + * cases_Open.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* Permissions */ + +if( $RBAC->userCanAccess('PM_SUPERVISOR') != 1 ) + switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('case'); + +/* GET , POST & $_SESSION Vars */ +if (isset($_SESSION['APPLICATION'])) { + unset($_SESSION['APPLICATION']); +} +if (isset($_SESSION['PROCESS'])) { + unset($_SESSION['PROCESS']); +} +if (isset($_SESSION['INDEX'])) { + unset($_SESSION['INDEX']); +} +if (isset($_SESSION['STEP_POSITION'])) { + unset($_SESSION['STEP_POSITION']); +} + +/* Process the info */ +$oCase = new Cases(); +$sAppUid = $_GET['APP_UID']; +$iDelIndex = $_GET['DEL_INDEX']; + + +$_SESSION['APPLICATION'] = $_GET['APP_UID']; +$_SESSION['INDEX'] = $_GET['DEL_INDEX']; + +$aFields = $oCase->loadCase($sAppUid, $iDelIndex); + +$_SESSION['PROCESS'] = $aFields['PRO_UID']; +$_SESSION['TASK'] = $aFields['TAS_UID']; +$_SESSION['STEP_POSITION'] = 0; + +/* Redirect to next step */ +$aNextStep = $oCase->getNextSupervisorStep($_SESSION['PROCESS'],0); +$sPage = "cases_StepToRevise?type=DYNAFORM&PRO_UID=".$aFields['PRO_UID']."&DYN_UID=".$aNextStep['UID']."&APP_UID=$sAppUid&DEL_INDEX=$iDelIndex&position=1";//$aNextStep['PAGE']; +G::header('location: ' . $sPage); + + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_PrintView.php b/workflow/engine/methods/cases/cases_PrintView.php new file mode 100644 index 000000000..a16348d09 --- /dev/null +++ b/workflow/engine/methods/cases/cases_PrintView.php @@ -0,0 +1,113 @@ +<?php +/** + * Cases_PrintPreview.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + + require_once 'classes/model/Dynaform.php'; + require_once 'classes/model/Process.php'; + // g::pr($_SESSION); die; + + + $oDynaform = new Dynaform(); + $aDyn = $oDynaform->load($_SESSION['CURRENT_DYN_UID']); + G::LoadClass('case'); + $oCase = new Cases(); + + if( isset($_SESSION['APPLICATION']) ){ + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $Fields['APP_DATA'] = array_merge($Fields['APP_DATA'], G::getSystemConstants()); + } else { + $Fields['APP_DATA'] = Array(); + } + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_PUBLISH = new Publisher; + + $idProcess = (isset($Fields['APP_DATA']['PROCESS']))?$Fields['APP_DATA']['PROCESS']:$_SESSION['PROCESS']; + $oProcess = new Process(); + $oProcess->load($idProcess); + $sProcess = $oProcess->getProTitle(); + + //Add content content step - Start + if(isset($_SESSION['APPLICATION'])){ + $array['CASE'] = G::LoadTranslation('ID_CASE'); + $array['USER'] = G::LoadTranslation('ID_USER'); + $array['WORKSPACE'] = G::LoadTranslation('ID_WORKSPACE'); + $array['APP_NUMBER'] = $Fields['APP_NUMBER']; + $array['APP_TITLE'] = $Fields['TITLE']; + $array['USR_USERNAME'] = $Fields['APP_DATA']['USR_USERNAME']; + $array['USER_ENV'] = $Fields['APP_DATA']['SYS_SYS']; + $array['DATEPRINT'] = date('Y-m-d H:m:s'); + } + $array['APP_PROCESS'] = $sProcess; + + if(isset($Fields['TITLE'])&& strlen($Fields['TITLE'])>0) + $array['TITLE'] = G::LoadTranslation('ID_TITLE'); + else + $array['TITLE'] = ''; + $array['PROCESS'] = G::LoadTranslation('ID_PROCESS'); + $array['DATELABEL'] = G::LoadTranslation('DATE_LABEL'); + + $aDyn['DYN_UID']=(isset($_SESSION['DYN_UID_PRINT']) && $_SESSION['DYN_UID_PRINT']!='')?$_SESSION['DYN_UID_PRINT']:$aDyn['DYN_UID']; + $G_PUBLISH->AddContent('smarty', 'cases/cases_PrintViewTitle', '', '', $array); + + $G_PUBLISH->AddContent('dynaform', 'xmlform', $aDyn['PRO_UID']. '/' . $aDyn['DYN_UID'], '', $Fields['APP_DATA'], '', '', ''); + G::RenderPage('publish', 'blank'); + + +} catch (Exception $oException) { + die($oException->getMessage()); +} +?> + +<script> + try{ + oFields = document.getElementsByTagName('input'); + for(i=0; i<oFields.length; i++){ + if(oFields[i].type == 'button' || oFields[i].type == 'submit') + oFields[i].style.display="none"; + else + oFields[i].disabled="true"; + } + oFields = document.getElementsByTagName('textarea'); + for(i=0; i<oFields.length; i++){ + oFields[i].disabled="true"; + } + oFields = document.getElementsByTagName('select'); + for(i=0; i<oFields.length; i++){ + oFields[i].disabled="true"; + } + + oFields = document.getElementsByTagName('td'); + for(i=0; i<oFields.length; i++){ + if(oFields[i].className == 'withoutLabel' ){ + oFields[i].style.display="none"; + break; + } + } + + window.print(); + } catch(e){} +</script> diff --git a/workflow/engine/methods/cases/cases_Reassign.php b/workflow/engine/methods/cases/cases_Reassign.php new file mode 100644 index 000000000..e1df7dfe2 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Reassign.php @@ -0,0 +1,121 @@ +<?php +/** + * cases_Reassign.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + +G::LoadSystem('templatePower'); +$tpl = new TemplatePower(PATH_TPL ."cases/cases_Reassign.html"); +$tpl->prepare(); + +require_once 'classes/model/AppDelegation.php'; +$oCriteria = new Criteria('workflow'); +$oCriteria->add(AppDelegationPeer::APP_UID, $_GET['APP_UID']); +$oCriteria->add(AppDelegationPeer::DEL_INDEX, $_GET['DEL_INDEX']); +$oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null); +$oDataset = AppDelegationPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$c=0; +G::LoadClass('tasks'); +$oTasks=new Tasks(); +G::LoadClass('groups'); +$oGroups = new Groups(); +require_once 'classes/model/Users.php'; +$oUser = new Users(); +$name = ''; + while ($aRow = $oDataset->getRow()) { + $c++; + + $aUsr=array(); + $aUsrUid=array(); + $aAux1 = $oTasks->getGroupsOfTask($aRow['TAS_UID'], 1); + foreach ($aAux1 as $value1) { + $aAux2 = $oGroups->getUsersOfGroup($value1['GRP_UID']); + foreach ($aAux2 as $value2) { + if($aRow['USR_UID']!=$value2['USR_UID']) { + if(!in_array($value2['USR_UID'], $aUsrUid)) {//var_dump($aRow['USR_UID'], $value2['USR_UID']);echo '<br /><br />'; + $aAux = $oUser->load($value2['USR_UID']); + $aUsr[$aAux['USR_FIRSTNAME'] . ' ' . $aAux['USR_LASTNAME']] = $aAux; + $aUsrUid[]=$value2['USR_UID']; + } + } + } + } + + $aUsers=$oTasks->getUsersOfTask($aRow['TAS_UID'], 1); + foreach($aUsers as $key => $value) + { + if($aRow['USR_UID']!=$value['USR_UID']) + { if(!in_array($value['USR_UID'], $aUsrUid)) + $aUsr[$value['USR_FIRSTNAME'] . ' ' . $value['USR_LASTNAME']]=$value; + } + } + ksort($aUsr); + //$users=''; + //$users='<select name="USERS"><option value="">Seleccione</option>'; + foreach($aUsr as $key => $value) + { $tpl->newBlock( "users" ); + $name=$value['USR_FIRSTNAME'].' '.$value['USR_LASTNAME'].' ('.$value['USR_USERNAME'].')'; + //$users=$users."<option value='".$value['USR_UID']."'>". $name ."</option>"; + $tpl->assign( "USR_UID", $value['USR_UID'] ); + $tpl->assign( "USERS", $name ); + } + //$users=$users.' </select>'; + + //$tpl->assign( "USERS", $users ); + + $oDataset->next(); + } + $tpl->gotoBlock('_ROOT'); + $tpl->assign( "US", $name ); + $tpl->assign( "ID_NO_REASSIGN", '-'); + $tpl->assign( "APP_UID", $_GET['APP_UID']); + $tpl->assign( "DEL_INDEX", $_GET['DEL_INDEX']); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REASSIGN'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('template', '', '', '', $tpl); + G::RenderPage('publish', 'blank'); + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_ReassignByUser.php b/workflow/engine/methods/cases/cases_ReassignByUser.php new file mode 100644 index 000000000..537df26da --- /dev/null +++ b/workflow/engine/methods/cases/cases_ReassignByUser.php @@ -0,0 +1,166 @@ +<?php +/** + * cases_ReassignByUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * Reassign ByUser routines + * Author Erik Amaru Ortiz <erik@colosa.com> + */ + +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + if (!isset($_GET['REASSIGN_USER'])) { + $_GET['REASSIGN_USER'] = ''; + } + $_GET['REASSIGN_BY'] = 2; + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REASSIGN'; + ////////////////// + ///SELECT USR_UID, CONCAT(USR_FIRSTNAME, ' ', USR_LASTNAME, ' (', USR_USERNAME, ')') AS USER_FULLNAME FROM USERS WHERE USR_STATUS <> 'CLOSED'////// + require_once 'classes/model/Users.php'; + $oCriteria=new Criteria(); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_USERNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_EMAIL); + $oCriteria->add(UsersPeer::USR_STATUS,'', Criteria::NOT_EQUAL); + $oDataset=UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + /////////////////////// + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($obj, 'ENVIRONMENT_SETTINGS',''); + + $defaultOption = isset($oConf->aConfig['format'])? $oConf->aConfig['format']: ''; + $aUserInfo = array(); + $aUserInfo[] = array('USR_UID' => 'char','USER_FULLNAME' => 'char'); + while( $oDataset->next()){ + $aRow1 = $oDataset->getRow(); + $infoUser = G::getFormatUserList($defaultOption,$aRow1); + $aUserInfo[]=array( + 'USR_UID' => $aRow1['USR_UID'], + 'USER_FULLNAME' => $infoUser + ); + } + global $_DBArray; + $_DBArray['aUserInfo'] = $aUserInfo; + $_SESSION['_DBArray'] = $_DBArray; + ////////////////// + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', 'cases/cases_ReassignBy', '', $_GET); + + $sUserToReassign = trim($_GET['REASSIGN_USER']); + + if ($_GET['REASSIGN_USER'] != '') { + + G::LoadClass('tasks'); + G::LoadClass('groups'); + $oTasks = new Tasks(); + $oGroups = new Groups(); + $oUser = new Users(); + G::LoadClass('case'); + $oCases = new Cases(); + + list($oCriteriaToDo,$sXMLFile) = $oCases->getConditionCasesList('to_do', $sUserToReassign); + list($oCriteriaDraft,$sXMLFile) = $oCases->getConditionCasesList('draft', $sUserToReassign); + + $aCasesList = Array(); + + $oDataset = ApplicationPeer::doSelectRS($oCriteriaToDo); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + while ( $oDataset->next() ) { + array_push($aCasesList, $oDataset->getRow()); + } + + $oDataset = ApplicationPeer::doSelectRS($oCriteriaDraft); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + while ( $oDataset->next() ) { + array_push($aCasesList, $oDataset->getRow()); + } + + $filedNames = Array ( + "APP_UID", + "APP_NUMBER", + "APP_UPDATE_DATE", + "DEL_PRIORITY", + "DEL_INDEX", + "TAS_UID", + "DEL_INIT_DATE", + "DEL_FINISH_DATE", + "USR_UID", + "APP_STATUS", + "DEL_TASK_DUE_DATE", + "APP_CURRENT_USER", + "APP_TITLE", + "APP_PRO_TITLE", + "APP_TAS_TITLE", + "APP_DEL_PREVIOUS_USER", + ); + + $aCasesList = array_merge(Array($filedNames), $aCasesList); + + // G::pr($aCasesList); die; + + + require_once ( 'classes/class.xmlfield_InputPM.php' ); + + global $_DBArray; + $_DBArray['reassign_byuser'] = $aCasesList; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('reassign_byuser'); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile ( '/jscore/cases/reassignByUser.js' ); + $G_PUBLISH->ROWS_PER_PAGE = 12; + $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-reassigByUser', 'cases/cases_ToReassignByUserList', $oCriteria, Array('FROM_USR_UID'=>$sUserToReassign)); + + } + + G::RenderPage('publish', 'blank'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> +<div id="publisherContent[10]" style="display:none"></div> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Reassign_save.php b/workflow/engine/methods/cases/cases_Reassign_save.php new file mode 100644 index 000000000..b4747a639 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Reassign_save.php @@ -0,0 +1,79 @@ +<? +/** + *cases_Reassign_save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + //print_r($_POST); die; + G::LoadClass('case'); + $oCase = new Cases(); + + if ($_POST['USERS'] != '') { + $oCase->reassignCase($_POST['APP_UID'], $_POST['DEL_INDEX'], $_SESSION['USER_LOGGED'], $_POST['USERS']); + + } + + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $aUser = $oUser->load($_POST['USERS']); + + $Fields=array(); + + $Fields['USERS'] = $aUser['USR_FIRSTNAME'].' '.$aUser['USR_LASTNAME'].' ('.$aUser['USR_USERNAME'].')'; + + + + G::LoadClass('case'); + $oCases=new Cases(); + $aCases=$oCases->loadCase($_POST['APP_UID'], $_POST['DEL_INDEX'] ); + + $Fields['APP_NUMBER']=$aCases['APP_NUMBER']; + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REASSIGN'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_Reassign.xml', '', $Fields, ''); + G::RenderPage( 'publish', 'blank' ); + //G::SendMessageText(G::LoadTranslation('ID_FINISHED'), 'info'); + //G::header('Location: cases_List'); + +} +catch (Exception $oException) { + die($oException->getMessage()); +} + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Redirect.php b/workflow/engine/methods/cases/cases_Redirect.php new file mode 100644 index 000000000..2343ed102 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Redirect.php @@ -0,0 +1,41 @@ +<? +/** + * cases_Redirect.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 19-03-2009 + * + * @author Everth S . Berrios <everth@colosa.com> + */ +require_once 'classes/model/AppDocument.php'; +$oAppDocument = new AppDocument(); +$aFields = $oAppDocument->load($_GET['a']); +require_once 'classes/model/OutputDocument.php'; +$oOutputDocument = new OutputDocument(); +$aOD = $oOutputDocument->load($aFields['DOC_UID']); +$a = $_GET['a']; +$ext = strtolower($aOD['OUT_DOC_GENERATE']); + + +G::header('location: cases_ShowOutputDocument?a='.$a.'&ext='.$ext ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Resume.php b/workflow/engine/methods/cases/cases_Resume.php new file mode 100644 index 000000000..36806a8a6 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Resume.php @@ -0,0 +1,108 @@ +<?php +/** + * cases_Resume.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + /* Permissions */ + switch ($RBAC->userCanAccess('PM_CASES')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + /* Includes */ + G::LoadClass('case'); + + /* GET , POST & $_SESSION Vars */ + + /* Menues */ + $_SESSION['bNoShowSteps'] = true; + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'caseOptions'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = '_'; + + /* Prepare page before to show */ + $oCase = new Cases(); + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'], $_SESSION['INDEX'] ); + $participated = $oCase->userParticipatedInCase($_GET['APP_UID'], $_SESSION['USER_LOGGED']); + + if ($RBAC->userCanAccess('PM_ALLCASES') < 0 && $participated == 0) { + /*if (strtoupper($Fields['APP_STATUS']) != 'COMPLETED') { + $oCase->thisIsTheCurrentUser($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'SHOW_MESSAGE'); + }*/ + $aMessage['MESSAGE'] = G::LoadTranslation('ID_NO_PERMISSION_NO_PARTICIPATED '); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage); + G::RenderPage('publishBlank', 'blank'); + die; + } + if (isset($aRow['APP_TYPE'])) { + switch ($aRow['APP_TYPE']) { + case 'PAUSE': + $Fields['STATUS'] = ucfirst(strtolower(G::LoadTranslation('ID_PAUSED'))); + break; + case 'CANCEL': + $Fields['STATUS'] = ucfirst(strtolower(G::LoadTranslation('ID_CANCELLED'))); + break; + } + //$Fields['STATUS'] = $aRow['APP_TYPE']; + } + + /* Render page */ + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + var Cse = {}; + Cse.panels = {}; + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.Package.Load("json",{Type:"file"}); + leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); + leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); + leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); + leimnud.exec(leimnud.fix.memoryLeak); + '); + + require_once 'classes/model/Process.php'; + + $objProc = new Process(); + $aProc = $objProc->load($Fields['PRO_UID' ] ); + $Fields['PRO_TITLE'] = $aProc['PRO_TITLE']; + + $objTask = new Task(); + $aTask = $objTask->load($Fields['TAS_UID' ] ); + $Fields['TAS_TITLE'] = $aTask['TAS_TITLE']; + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/cases/core/cases_Step.js'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_Resume.xml', '', $Fields, ''); + G::RenderPage( 'publish', 'green-submenu'); diff --git a/workflow/engine/methods/cases/cases_Save.php b/workflow/engine/methods/cases/cases_Save.php new file mode 100644 index 000000000..59326afad --- /dev/null +++ b/workflow/engine/methods/cases/cases_Save.php @@ -0,0 +1,76 @@ +<?php +/** + * cases_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + /* Permissions */ + switch ($RBAC->userCanAccess('PM_CASES')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + /* Includes */ + G::LoadClass('case'); + + /* GET , POST & $_SESSION Vars */ + + /* unset any variable, because we are starting a new case */ + if (isset($_SESSION['APPLICATION'])) unset($_SESSION['APPLICATION']); + if (isset($_SESSION['PROCESS'])) unset($_SESSION['PROCESS']); + if (isset($_SESSION['TASK'])) unset($_SESSION['TASK']); + if (isset($_SESSION['INDEX'])) unset($_SESSION['INDEX']); + if (isset($_SESSION['STEP_POSITION'])) unset($_SESSION['STEP_POSITION']); + + /* Process */ + try { + $oCase = new Cases(); + $aData = $oCase->startCase( $_POST['form']['TAS_UID'], $_SESSION['USER_LOGGED'] ); + $_SESSION['APPLICATION'] = $aData['APPLICATION']; + $_SESSION['INDEX'] = $aData['INDEX']; + $_SESSION['PROCESS'] = $aData['PROCESS']; + $_SESSION['TASK'] = $_POST['form']['TAS_UID']; + $_SESSION['STEP_POSITION'] = 0; + + $_SESSION['CASES_REFRESH'] = true; + + $oCase = new Cases(); + $aNextStep = $oCase->getNextStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); + $_SESSION['BREAKSTEP']['NEXT_STEP'] = $aNextStep; + + G::header('location: ' . $aNextStep['PAGE']); + } + catch ( Exception $e ) { + $_SESSION['G_MESSAGE'] = $e->getMessage(); + $_SESSION['G_MESSAGE_TYPE'] = 'error'; + G::header('location: cases_New' ); + } +?> diff --git a/workflow/engine/methods/cases/cases_SaveData.php b/workflow/engine/methods/cases/cases_SaveData.php new file mode 100644 index 000000000..6d860ce71 --- /dev/null +++ b/workflow/engine/methods/cases/cases_SaveData.php @@ -0,0 +1,233 @@ +<? +/** + * cases_SaveData.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +//validate the data post +$oForm = new Form ( $_SESSION ['PROCESS'] . '/' . $_GET ['UID'], PATH_DYNAFORM ); +$oForm->validatePost (); + +/* Includes */ +G::LoadClass ( 'case' ); + +//load the variables +$oCase = new Cases ( ); +$oCase->thisIsTheCurrentUser ( $_SESSION ['APPLICATION'], $_SESSION ['INDEX'], $_SESSION ['USER_LOGGED'], 'REDIRECT', 'cases_List' ); +$Fields = $oCase->loadCase ( $_SESSION ['APPLICATION'] ); +$Fields ['APP_DATA'] = array_merge ( $Fields ['APP_DATA'], G::getSystemConstants () ); +$Fields ['APP_DATA'] = array_merge ( $Fields ['APP_DATA'], ( array ) $_POST ['form'] ); + +#here we must verify if is a debug session +$trigger_debug_session = $_SESSION ['TRIGGER_DEBUG'] ['ISSET']; #here we must verify if is a debugg session + + +#trigger debug routines... + + +//cleaning debug variables +$_SESSION ['TRIGGER_DEBUG'] ['ERRORS'] = Array (); +$_SESSION ['TRIGGER_DEBUG'] ['DATA'] = Array (); +$_SESSION ['TRIGGER_DEBUG'] ['TRIGGERS_NAMES'] = Array (); +$_SESSION ['TRIGGER_DEBUG'] ['TRIGGERS_VALUES'] = Array (); + +$triggers = $oCase->loadTriggers ( $_SESSION ['TASK'], 'DYNAFORM', $_GET ['UID'], 'AFTER' ); + +$_SESSION ['TRIGGER_DEBUG'] ['NUM_TRIGGERS'] = count ( $triggers ); +$_SESSION ['TRIGGER_DEBUG'] ['TIME'] = 'AFTER'; +if ($_SESSION ['TRIGGER_DEBUG'] ['NUM_TRIGGERS'] != 0) { + $_SESSION ['TRIGGER_DEBUG'] ['TRIGGERS_NAMES'] = $oCase->getTriggerNames ( $triggers ); + $_SESSION ['TRIGGER_DEBUG'] ['TRIGGERS_VALUES'] = $triggers; +} + +if ($_SESSION ['TRIGGER_DEBUG'] ['NUM_TRIGGERS'] != 0) { + //Execute after triggers - Start + $Fields ['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION ['TASK'], 'DYNAFORM', $_GET ['UID'], 'AFTER', $Fields ['APP_DATA'] ); + //Execute after triggers - End +} + +//save data in PM Tables if necessary +foreach ( $_POST ['form'] as $sField => $sAux ) { + if (isset ( $oForm->fields [$sField]->pmconnection ) && isset ( $oForm->fields [$sField]->pmfield )) { + if (($oForm->fields [$sField]->pmconnection != '') && ($oForm->fields [$sField]->pmfield != '')) { + if (isset ( $oForm->fields [$oForm->fields [$sField]->pmconnection] )) { + require_once PATH_CORE . 'classes' . PATH_SEP . 'model' . PATH_SEP . 'AdditionalTables.php'; + $oAdditionalTables = new AdditionalTables ( ); + try { + $aData = $oAdditionalTables->load ( $oForm->fields [$oForm->fields [$sField]->pmconnection]->pmtable, true ); + } catch ( Exception $oError ) { + $aData = array ('FIELDS' => array () ); + } + $aKeys = array (); + $aAux = explode ( '|', $oForm->fields [$oForm->fields [$sField]->pmconnection]->keys ); + $i = 0; + $aValues = array (); + foreach ( $aData ['FIELDS'] as $aField ) { + if ($aField ['FLD_KEY'] == '1') { + $aKeys [$aField ['FLD_NAME']] = (isset ( $aAux [$i] ) ? G::replaceDataField ( $aAux [$i], $Fields ['APP_DATA'] ) : ''); + $i ++; + } + if ($aField ['FLD_NAME'] == $oForm->fields [$sField]->pmfield) { + $aValues [$aField ['FLD_NAME']] = $Fields ['APP_DATA'] [$sField]; + } else { + $aValues [$aField ['FLD_NAME']] = ''; + } + } + try { + $aRow = $oAdditionalTables->getDataTable ( $oForm->fields [$oForm->fields [$sField]->pmconnection]->pmtable, $aKeys ); + } catch ( Exception $oError ) { + $aRow = false; + } + if ($aRow) { + foreach ( $aValues as $sKey => $sValue ) { + if ($sKey != $oForm->fields [$sField]->pmfield) { + $aValues [$sKey] = $aRow [$sKey]; + } + } + try { + $oAdditionalTables->updateDataInTable ( $oForm->fields [$oForm->fields [$sField]->pmconnection]->pmtable, $aValues ); + } catch ( Exception $oError ) { + //Nothing + } + } else { + try { + $oAdditionalTables->saveDataInTable ( $oForm->fields [$oForm->fields [$sField]->pmconnection]->pmtable, $aValues ); + } catch ( Exception $oError ) { + //Nothing + } + } + } + } + } +} + +//save data +$aData = array (); +$aData ['APP_NUMBER'] = $Fields ['APP_NUMBER']; +$aData ['APP_PROC_STATUS'] = $Fields ['APP_PROC_STATUS']; +$aData ['APP_DATA'] = $Fields ['APP_DATA']; +$aData ['DEL_INDEX'] = $_SESSION ['INDEX']; +$aData ['TAS_UID'] = $_SESSION ['TASK']; +$aData ['CURRENT_DYNAFORM'] = $_GET ['UID']; +$aData ['USER_UID'] = $_SESSION ['USER_LOGGED']; +$aData ['APP_STATUS'] = $Fields ['APP_STATUS']; +$aData ['PRO_UID'] = $_SESSION ['PROCESS']; + +$oCase->updateCase ( $_SESSION ['APPLICATION'], $aData ); +//save files +require_once 'classes/model/AppDocument.php'; +if (isset ( $_FILES ['form'] )) { + foreach ( $_FILES ['form'] ['name'] as $sFieldName => $vValue ) { + if ($_FILES ['form'] ['error'] [$sFieldName] == 0) { + $oAppDocument = new AppDocument ( ); + + + + if ( isset ( $_POST ['INPUTS'] [$sFieldName] ) && $_POST ['INPUTS'] [$sFieldName] != '' ) { + require_once ('classes/model/AppFolder.php'); + require_once ('classes/model/InputDocument.php'); + + $oInputDocument = new InputDocument(); + $aID = $oInputDocument->load($_POST ['INPUTS'] [$sFieldName]); + + //Get the Custom Folder ID (create if necessary) + $oFolder=new AppFolder(); + $folderId=$oFolder->createFromPath($aID['INP_DOC_DESTINATION_PATH']); + + //Tags + $fileTags=$oFolder->parseTags($aID['INP_DOC_TAGS']); + + $aFields = array ( + 'APP_UID' => $_SESSION ['APPLICATION'], + 'DEL_INDEX' => $_SESSION ['INDEX'], + 'USR_UID' => $_SESSION ['USER_LOGGED'], + 'DOC_UID' => $_POST ['INPUTS'] [$sFieldName], + 'APP_DOC_TYPE' => 'INPUT', + 'APP_DOC_CREATE_DATE' => date ( 'Y-m-d H:i:s' ), + 'APP_DOC_COMMENT' => '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => $_FILES ['form'] ['name'] [$sFieldName], + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags + ); + } else { + $aFields = array ( + 'APP_UID' => $_SESSION ['APPLICATION'], + 'DEL_INDEX' => $_SESSION ['INDEX'], + 'USR_UID' => $_SESSION ['USER_LOGGED'], + 'DOC_UID' => - 1, + 'APP_DOC_TYPE' => 'ATTACHED', + 'APP_DOC_CREATE_DATE' => date ( 'Y-m-d H:i:s' ), + 'APP_DOC_COMMENT' => '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => $_FILES ['form'] ['name'] [$sFieldName] + ); + } + + $oAppDocument->create ( $aFields ); + $iDocVersion = $oAppDocument->getDocVersion(); + $sAppDocUid = $oAppDocument->getAppDocUid (); + $aInfo = pathinfo ( $oAppDocument->getAppDocFilename () ); + $sExtension = (isset ( $aInfo ['extension'] ) ? $aInfo ['extension'] : ''); + $sPathName = PATH_DOCUMENT . $_SESSION ['APPLICATION'] . PATH_SEP; + $sFileName = $sAppDocUid . '_'.$iDocVersion.'.' . $sExtension; + G::uploadFile ( $_FILES ['form'] ['tmp_name'] [$sFieldName], $sPathName, $sFileName ); + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry = & PMPluginRegistry::getSingleton (); + if ($oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT ) && class_exists ( 'uploadDocumentData' )) { + $documentData = new uploadDocumentData ( $_SESSION ['APPLICATION'], $_SESSION ['USER_LOGGED'], $sPathName . $sFileName, $aFields ['APP_DOC_FILENAME'], $sAppDocUid ); + $oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT, $documentData ); + unlink ( $sPathName . $sFileName ); + } + } + } +} + +//go to the next step +$aNextStep = $oCase->getNextStep ( $_SESSION ['PROCESS'], $_SESSION ['APPLICATION'], $_SESSION ['INDEX'], $_SESSION ['STEP_POSITION'] ); +if (isset ( $_GET ['_REFRESH_'] )) { + G::header ( 'location: ' . $_SERVER ['HTTP_REFERER'] ); + die (); +} +$_SESSION ['STEP_POSITION'] = $aNextStep ['POSITION']; + +$_SESSION['BREAKSTEP']['NEXT_STEP'] = $aNextStep ['PAGE']; + +if ($trigger_debug_session) { + $_SESSION ['TRIGGER_DEBUG'] ['BREAKPAGE'] = $aNextStep ['PAGE']; + $aNextStep ['PAGE'] = $aNextStep ['PAGE'] . '&breakpoint=triggerdebug'; +} + +$oForm->validatePost (); +$oJSON = new Services_JSON ( ); +$_POST ['__notValidateThisFields__'] = (isset($_POST ['__notValidateThisFields__']) && $_POST ['__notValidateThisFields__']!='')?$_POST ['__notValidateThisFields__']:$_POST ['DynaformRequiredFields']; +if ($missing_req_values = $oForm->validateRequiredFields ( $_POST ['form'], $oJSON->decode ( stripslashes ( $_POST ['__notValidateThisFields__'] ) ) )) { + $_POST ['next_step'] = $aNextStep; + $_POST ['previous_step'] = $oCase->getPreviousStep ( $_SESSION ['PROCESS'], $_SESSION ['APPLICATION'], $_SESSION ['INDEX'], $_SESSION ['STEP_POSITION'] ); + $_POST ['req_val'] = $missing_req_values; + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'view', 'cases/missRequiredFields' ); + G::RenderPage ( 'publish', 'blank' ); + exit ( 0 ); +} + +G::header ( 'location: ' . $aNextStep ['PAGE'] ); + diff --git a/workflow/engine/methods/cases/cases_SaveDataSupervisor.php b/workflow/engine/methods/cases/cases_SaveDataSupervisor.php new file mode 100644 index 000000000..1e9ba861b --- /dev/null +++ b/workflow/engine/methods/cases/cases_SaveDataSupervisor.php @@ -0,0 +1,52 @@ +<? +/** + * cases_SaveData.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //validate the data post + $oForm = new Form($_SESSION['PROCESS']. '/' . $_GET['UID'], PATH_DYNAFORM); + $oForm->validatePost(); + + /* Includes */ + G::LoadClass('case'); + + //load the variables + $oCase = new Cases(); + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $Fields['APP_DATA'] = array_merge( $Fields['APP_DATA'], $_POST['form']); + + //save data + $aData = array(); + $aData['APP_NUMBER'] = $Fields['APP_NUMBER']; + $aData['APP_PROC_STATUS'] = $Fields['APP_PROC_STATUS']; + $aData['APP_DATA'] = $Fields['APP_DATA']; + $aData['DEL_INDEX'] = $_SESSION['INDEX']; + $aData['TAS_UID'] = $_SESSION['TASK']; + //$aData = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $oCase->updateCase( $_SESSION['APPLICATION'], $aData ); + + //go to the next step + $aNextStep = $oCase->getNextSupervisorStep($_SESSION['PROCESS'], $_SESSION['STEP_POSITION']); + $_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; + G::header('location: cases_StepToRevise?DYN_UID='.$aNextStep['UID'].'&APP_UID='.$_SESSION['APPLICATION'].'&DEL_INDEX='.$_SESSION['INDEX']); + + \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_SaveDocument.php b/workflow/engine/methods/cases/cases_SaveDocument.php new file mode 100644 index 000000000..f4506076c --- /dev/null +++ b/workflow/engine/methods/cases/cases_SaveDocument.php @@ -0,0 +1,287 @@ +<? +/** + * cases_SaveDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + try { + + //First review if there is no error with the uploaded document + if ((isset($_FILES['form']))&&($_FILES['form']['error']['APP_DOC_FILENAME'] != 0)) { + $code=$_FILES['form']['error']['APP_DOC_FILENAME']; + switch ($code) { + case UPLOAD_ERR_INI_SIZE: + $message = G::LoadTranslation('ID_UPLOAD_ERR_INI_SIZE'); + break; + case UPLOAD_ERR_FORM_SIZE: + $message = G::LoadTranslation('ID_UPLOAD_ERR_FORM_SIZE'); + break; + case UPLOAD_ERR_PARTIAL: + $message = G::LoadTranslation('ID_UPLOAD_ERR_PARTIAL'); + break; + case UPLOAD_ERR_NO_FILE: + $message = G::LoadTranslation('ID_UPLOAD_ERR_NO_FILE'); + break; + case UPLOAD_ERR_NO_TMP_DIR: + $message = G::LoadTranslation('ID_UPLOAD_ERR_NO_TMP_DIR'); + break; + case UPLOAD_ERR_CANT_WRITE: + $message = G::LoadTranslation('ID_UPLOAD_ERR_CANT_WRITE'); + break; + case UPLOAD_ERR_EXTENSION: + $message = G::LoadTranslation('ID_UPLOAD_ERR_EXTENSION'); + break; + + default: + $message = G::LoadTranslation('ID_UPLOAD_ERR_UNKNOWN'); + break; + } + G::SendMessageText($message, "ERROR"); + $backUrlObj=explode("sys".SYS_SYS,$_SERVER['HTTP_REFERER']); + G::header("location: "."/sys".SYS_SYS.$backUrlObj[1]); + die; + } + + + $docUid=$_POST['form']['DOC_UID']; + $appDocUid=$_POST['form']['APP_DOC_UID']; + $docVersion=$_POST['form']['docVersion']; + $actionType=$_POST['form']['actionType']; + + + //load the variables + G::LoadClass('case'); + $oCase = new Cases(); + $oCase->thisIsTheCurrentUser($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'REDIRECT', 'cases_List'); + $Fields = $oCase->loadCase($_SESSION['APPLICATION']); + $Fields['APP_DATA'] = array_merge($Fields['APP_DATA'], G::getSystemConstants()); + + #trigger debug routines... + + //cleaning debug variables + $_SESSION['TRIGGER_DEBUG']['ERRORS'] = Array(); + $_SESSION['TRIGGER_DEBUG']['DATA'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = Array(); + + $triggers = $oCase->loadTriggers( $_SESSION['TASK'], 'INPUT_DOCUMENT', $_GET['UID'], 'AFTER'); + + $_SESSION['TRIGGER_DEBUG']['NUM_TRIGGERS'] = count($triggers); + $_SESSION['TRIGGER_DEBUG']['TIME'] = 'AFTER'; + if($_SESSION['TRIGGER_DEBUG']['NUM_TRIGGERS'] != 0){ + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = $oCase->getTriggerNames($triggers); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = $triggers; + } + + if( $_SESSION['TRIGGER_DEBUG']['NUM_TRIGGERS'] != 0 ) { + //Execute after triggers - Start + $Fields['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION['TASK'], 'INPUT_DOCUMENT', $_GET['UID'], 'AFTER', $Fields['APP_DATA'] ); + //Execute after triggers - End + } + + + //save data + $aData = array(); + $aData['APP_NUMBER'] = $Fields['APP_NUMBER']; + $aData['APP_PROC_STATUS'] = $Fields['APP_PROC_STATUS']; + $aData['APP_DATA'] = $Fields['APP_DATA']; + $aData['DEL_INDEX'] = $_SESSION['INDEX']; + $aData['TAS_UID'] = $_SESSION['TASK']; + //$aData = $oCase->loadCase($_SESSION['APPLICATION']); + $oCase->updateCase( $_SESSION['APPLICATION'], $aData ); + + //save info + + require_once ( "classes/model/AppDocument.php" ); + require_once ('classes/model/AppFolder.php'); + require_once ('classes/model/InputDocument.php'); + + $oInputDocument = new InputDocument(); + $aID = $oInputDocument->load($_GET['UID']); + + + $oAppDocument = new AppDocument(); + + + //Get the Custom Folder ID (create if necessary) + $oFolder=new AppFolder(); + $folderId=$oFolder->createFromPath($aID['INP_DOC_DESTINATION_PATH']); + + //Tags + $fileTags=$oFolder->parseTags($aID['INP_DOC_TAGS']); + + switch($actionType){ + case "R": //replace + $aFields = array('APP_DOC_UID' => $appDocUid, + 'APP_UID' => $_SESSION['APPLICATION'], + 'DOC_VERSION' => $docVersion, + 'DEL_INDEX' => $_SESSION['INDEX'], + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + + $oAppDocument->update($aFields); + break; + case "NV": //New Version + + + $aFields = array('APP_DOC_UID' => $appDocUid, + 'APP_UID' => $_SESSION['APPLICATION'], + + 'DEL_INDEX' => $_SESSION['INDEX'], + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + $oAppDocument->create($aFields); + break; + default: //New + $aFields = array('APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX'], + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $docUid, + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + + + $oAppDocument->create($aFields); + break; + } + + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $iDocVersion = $oAppDocument->getDocVersion(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + $ext = (isset($info['extension']) ? $info['extension'] : ''); + + //save the file + if (!empty($_FILES['form'])) { + if ($_FILES['form']['error']['APP_DOC_FILENAME'] == 0) { + $sPathName = PATH_DOCUMENT . $_SESSION['APPLICATION'] . PATH_SEP; + $sFileName = $sAppDocUid . "_".$iDocVersion. '.' . $ext; + G::uploadFile($_FILES['form']['tmp_name']['APP_DOC_FILENAME'], $sPathName, $sFileName ); + + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT ) && class_exists ('uploadDocumentData' ) ) { + + $oData['APP_UID'] = $_SESSION['APPLICATION']; + $documentData = new uploadDocumentData ( + $_SESSION['APPLICATION'], + $_SESSION['USER_LOGGED'], + $sPathName . $sFileName, + $aFields['APP_DOC_FILENAME'], + $sAppDocUid, + $iDocVersion + ); + + $uploadReturn=$oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + if($uploadReturn){ + unlink ( $sPathName . $sFileName ); + } + } + //end plugin + } + } + + //go to the next step + //if (!isset($_POST['form']['MORE'])) { + if (false) { + $aNextStep = $oCase->getNextStep( $_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); + $_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; + + if($_SESSION['TRIGGER_DEBUG']['ISSET']){ + $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $aNextStep['PAGE']; + G::header('location: ' . $aNextStep['PAGE'].'&breakpoint=triggerdebug'); + die; + } + + G::header('location: ' . $aNextStep['PAGE']); + die; + } + else { + if (isset($_SERVER['HTTP_REFERER'])) { + if ($_SERVER['HTTP_REFERER'] != '') { + + if($_SESSION['TRIGGER_DEBUG']['ISSET']){ + $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $_SERVER['HTTP_REFERER']; + G::header('location: ' . $_SERVER['HTTP_REFERER'].'&breakpoint=triggerdebug'); + die; + } + + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; + } + else { + $aNextStep = $oCase->getNextStep( $_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION'] - 1); + $_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; + + if($_SESSION['TRIGGER_DEBUG']['ISSET']){ + $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $aNextStep['PAGE']; + G::header('location: ' . $aNextStep['PAGE'].'&breakpoint=triggerdebug'); + die; + } + + G::header('location: ' . $aNextStep['PAGE']); + die; + } + } + else { + $aNextStep = $oCase->getNextStep( $_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION'] - 1); + $_SESSION['STEP_POSITION'] = $aNextStep['POSITION']; + + if($_SESSION['TRIGGER_DEBUG']['ISSET']){ + $_SESSION['TRIGGER_DEBUG']['BREAKPAGE'] = $aNextStep['PAGE']; + G::header('location: ' . $aNextStep['PAGE'].'&breakpoint=triggerdebug'); + die; + } + + G::header('location: ' . $aNextStep['PAGE']); + die; + } + } + $_SESSION['BREAKSTEP']['NEXT_STEP'] = $aNextStep; + + } catch ( Exception $e ) { + /* Render Error page */ + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_SchedulerGetPlugins.php b/workflow/engine/methods/cases/cases_SchedulerGetPlugins.php new file mode 100644 index 000000000..015504f20 --- /dev/null +++ b/workflow/engine/methods/cases/cases_SchedulerGetPlugins.php @@ -0,0 +1,71 @@ +<?php + +if (! isset ( $_REQUEST ['action'] )) { + $return ['success'] = 'failure'; + $return ['message'] = 'You may request an action'; + print G::json_encode ( $return ); + die (); +} +if (! function_exists ( $_REQUEST ['action'] )) { + $return ['success'] = 'failure'; + $return ['message'] = 'The requested action doesn\'t exists'; + print G::json_encode ( $return ); + die (); +} + +$functionName = $_REQUEST ['action']; +//var_dump($functionName); +$functionParams = isset($_REQUEST ['params'] ) ? $_REQUEST ['params'] : array (); + +$functionName ( $functionParams ); + +function searchSavedJob($schUid){ + +} + +function pluginsList(){ +$oPluginRegistry =& PMPluginRegistry::getSingleton(); +$activePluginsForCaseScheduler=$oPluginRegistry->getCaseSchedulerPlugins(); +$selectedPlugin=""; +if((isset($_REQUEST['plg_uid']))&&($_REQUEST['plg_uid']!="")) $selectedPlugin=$_REQUEST['plg_uid']; +if(!empty($activePluginsForCaseScheduler)){ + echo '<select style="width: 300px;" name="form[CASE_SH_PLUGIN_UID]" id="form[CASE_SH_PLUGIN_UID]" class="module_app_input___gray" required="1" onChange="showPluginSelection(this.options[this.selectedIndex].value,getField(\'PRO_UID\').value)">'; + echo "<option value=\"\">- Select -</option>"; + foreach($activePluginsForCaseScheduler as $key => $caseSchedulerPluginDetail){ + $sActionId=$caseSchedulerPluginDetail->sActionId; + $sNamespace=$caseSchedulerPluginDetail->sNamespace; + $optionId=$sNamespace."--".$sActionId; + $selectedOption=""; + if($selectedPlugin==$optionId) $selectedOption="selected"; + echo "<option value=\"$optionId\" $selectedOption>".$sActionId."</option>"; + } + echo '</select>'; + //G::pr($activePlugnsForCaseScheduler); +} +} +function pluginCaseSchedulerForm(){ + if(!isset($_REQUEST ['selectedOption'])) die; + $G_PUBLISH = new Publisher; + $params=explode("--",$_REQUEST ['selectedOption']); + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $activePluginsForCaseScheduler=$oPluginRegistry->getCaseSchedulerPlugins(); + + foreach($activePluginsForCaseScheduler as $key => $caseSchedulerPluginDetail){ + if(($caseSchedulerPluginDetail->sNamespace==$params[0])&&($caseSchedulerPluginDetail->sActionId==$params[1])){ + $caseSchedulerSelected=$caseSchedulerPluginDetail; + } + } + if((isset($caseSchedulerSelected))&&(is_object($caseSchedulerSelected))){ + //Render the form + if((isset($_REQUEST['sch_uid']))&&($_REQUEST['sch_uid']!="")){ + //$oData=$oPluginRegistry->executeMethod( $caseSchedulerPluginDetail->sNamespace, $caseSchedulerPluginDetail->sActionGetFields, array("SCH_UID"=>$_REQUEST['sch_uid']) ); + $oData=array("SCH_UID"=>$_REQUEST['sch_uid'],"PRO_UID"=>$_REQUEST['pro_uid']); + }else{ + $oData=array("PRO_UID"=>$_REQUEST['pro_uid']); + } + + $oPluginRegistry->executeMethod( $caseSchedulerPluginDetail->sNamespace, $caseSchedulerPluginDetail->sActionForm, $oData ); + } + +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_SchedulerGetProcesses.php b/workflow/engine/methods/cases/cases_SchedulerGetProcesses.php new file mode 100644 index 000000000..41841a8f2 --- /dev/null +++ b/workflow/engine/methods/cases/cases_SchedulerGetProcesses.php @@ -0,0 +1,38 @@ + +<?php +//$oUserId = '2963666854afbb1cea372c4011254883'; +$oUserId = $_POST['USR_UID']; +$process = isset($_POST['PRO_UID'])?$_POST['PRO_UID']:$_SESSION['PROCESS']; +//echo '<select style="width: 300px;" readOnly name="form[PRO_UID]" id="form[PRO_UID]" class="module_app_input___gray" required="1" onChange="loadTasksDropdown(this.value,\''.$oUserId.'\');">'; + +require_once ("classes/model/TaskPeer.php"); +require_once ("classes/model/ProcessPeer.php"); +require_once ("classes/model/TaskUserPeer.php"); +G::LoadClass ( 'Content' ); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(ProcessPeer::PRO_UID); + $oCriteria->setDistinct(); + $oCriteria->addSelectColumn(ContentPeer::CON_VALUE); + $oCriteria->addJoin(ProcessPeer::PRO_UID, TaskPeer::PRO_UID, Criteria::LEFT_JOIN); + $oCriteria->addJoin(ProcessPeer::PRO_UID, ContentPeer::CON_ID, Criteria::LEFT_JOIN); + $oCriteria->addJoin(TaskPeer::TAS_UID, TaskUserPeer::TAS_UID, Criteria::LEFT_JOIN); + $oCriteria->add(TaskUserPeer::USR_UID, $oUserId); + $oCriteria->add(TaskPeer::TAS_START, 'true'); + $oCriteria->add(ContentPeer::CON_CATEGORY, 'PRO_TITLE'); + $oCriteria->add(ContentPeer::CON_LANG, SYS_LANG); + $oCriteria->addAnd(ProcessPeer::PRO_UID, $process); + + $resultSet = TaskUserPeer::doSelectRS($oCriteria); + while ($resultSet->next()){ + $row = $resultSet->getRow(); + + echo $row[1]; + echo "<input name=\"form[PRO_UID]\" id=\"form[PRO_UID]\" type=\"hidden\" value=\"".$row[0]."\"></input>"; + //var_dump($row); + } + +//echo "</select>"; +?> + + diff --git a/workflow/engine/methods/cases/cases_SchedulerGetTasks.php b/workflow/engine/methods/cases/cases_SchedulerGetTasks.php new file mode 100644 index 000000000..43f43717b --- /dev/null +++ b/workflow/engine/methods/cases/cases_SchedulerGetTasks.php @@ -0,0 +1,25 @@ +<select style="width: 300px;" name="form[TAS_UID]" id="form[TAS_UID]" class="module_app_input___gray" required="1"> + +<?php +//$oUserId = '2963666854afbb1cea372c4011254883'; +//$oProcessId = '9977730834afd2a0deecaf3040551794'; +$oUserId = $_POST['USR_UID']; +$oProcessId = $_POST['PRO_UID']; + +G::LoadClass('case'); +$oCase = new Cases(); +$startTasks = $oCase->getStartCases( $oUserId ); + +foreach($startTasks as $task){ + if((isset($task['pro_uid']))&&($task['pro_uid'] == $oProcessId)){ + $taskValue = explode('(',$task['value']); + $tasksLastIndex = count($taskValue)-1; + $taskValue = explode(')',$taskValue[$tasksLastIndex]); + + echo "<option value=\"".$task['uid']."\">".$taskValue[0]."</option>"; + } +} +//print_r($startTasks); +// echo "<option value=\"".$value."\">".$label."</option>"; +?> +</select> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_SchedulerValidateUser.php b/workflow/engine/methods/cases/cases_SchedulerValidateUser.php new file mode 100644 index 000000000..ecfd290dd --- /dev/null +++ b/workflow/engine/methods/cases/cases_SchedulerValidateUser.php @@ -0,0 +1,73 @@ +<?php +/** + * cases_SchedulerValidateUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +/** + * process_SchedulerValidate_User + * validates if the username and password are valid data and if the user assigned + * to the process and task has the rights and persmissions required to create a cron task + */ + + +$sWS_USER = trim($_POST['USERNAME']); +$sWS_PASS = trim($_POST['PASSWORD']); + +if (G::is_https ()) + $http = 'https://'; + else + $http = 'http://'; + +$endpoint = $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/wsdl2'; +@$client = new SoapClient ( $endpoint ); + +$user = $sWS_USER; +$pass = $sWS_PASS; + +$params = array ('userid' => $user, 'password' => $pass ); +$result = $client->__SoapCall ( 'login', array ($params ) ); + + + +$fields ['status_code'] = $result->status_code; +$fields ['message'] = 'ProcessMaker WebService version: ' . $result->version . "\n" . $result->message; +$fields ['version'] = $result->version; +$fields ['time_stamp'] = $result->timestamp; +$messageCode = $result->message; +if($result->status_code == 0){ + if(!class_exists('Users')) { + require ("classes/model/UsersPeer.php"); + } + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('USR_UID'); + $oCriteria->add(UsersPeer::USR_USERNAME, $sWS_USER); + $resultSet = UsersPeer::doSelectRS($oCriteria); + $resultSet->next(); + $user_id = $resultSet->getRow(); + + $messageCode = $user_id[0]; + } +echo ($messageCode); +?> diff --git a/workflow/engine/methods/cases/cases_Scheduler_ChangeStatus.php b/workflow/engine/methods/cases/cases_Scheduler_ChangeStatus.php new file mode 100755 index 000000000..a4774d3a3 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_ChangeStatus.php @@ -0,0 +1,56 @@ +<?php +/** + * cases_Scheduler_ChangeStatus.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +/* +switch ($RBAC->userCanAccess('PM_FACTORY')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +*/ +/* + G::LoadClass('cases_Scheduler'); + $oCases_Scheduler= new Cases_Scheduler(); + $oCases_Scheduler->changeStatus ( $_GET['SCH_UID'] ); + G::header('location: ' . $_SERVER['HTTP_REFERER']); +*/ + + require_once 'classes/model/CaseScheduler.php'; + +// G::LoadClass('CaseScheduler'); + $oCaseScheduler= new CaseScheduler(); + $oCaseScheduler->changeStatus ( $_GET['SCH_UID'] ); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + + \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_Delete.php b/workflow/engine/methods/cases/cases_Scheduler_Delete.php new file mode 100755 index 000000000..9fdfde099 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Delete.php @@ -0,0 +1,53 @@ +<?php +/** + * cases_Scheduler_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* Permissions */ + +/* +switch ($RBAC->userCanAccess('PM_CASES')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} +*/ + + // print_r($_GET); print_r($_POST); die; + + + require_once 'classes/model/CaseScheduler.php'; + $oCaseScheduler = new CaseScheduler(); + if ( !isset($_GET['SCH_UID'] ) ) return; + $oCaseScheduler->remove($_GET['SCH_UID']); + + +/* Redirect */ +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_Edit.php b/workflow/engine/methods/cases/cases_Scheduler_Edit.php new file mode 100644 index 000000000..244eba7a2 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Edit.php @@ -0,0 +1,138 @@ +<?php +/** + * cases_SchedulerNew.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + +/* + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +*/ + + require_once 'classes/model/CaseScheduler.php'; + require_once 'classes/model/Process.php'; + require_once 'classes/model/Task.php'; + +// $G_MAIN_MENU = 'processmaker'; +// $G_ID_MENU_SELECTED = 'CASES'; + $G_PUBLISH = new Publisher; + + G::LoadClass('case'); + + /* Prepare page before to show */ + + + $oCaseScheduler = new CaseScheduler(); + $aFields = $oCaseScheduler->load($_GET['SCH_UID']); + + + $aFields['UID_SCHEDULER'] ="scheduler" ; + + // load according the scheduler option selected daily/weekly/monthly/one time + $nOpt = $aFields['SCH_OPTION']; + switch($nOpt){ + case 1 : $aStartDay = explode('|', $aFields['SCH_DAYS_PERFORM_TASK']); + if($aStartDay[0] != 3) { + $aFields['SCH_DAYS_PERFORM_TASK'] = $aStartDay[0]; + } else { + $aFields['SCH_DAYS_PERFORM_TASK'] = $aStartDay[0]; + $aFields['SCH_DAYS_PERFORM_TASK_OPT_3'] = $aStartDay[1]; + } + + break; + case 2 : + $aFields['SCH_WEEK_DAYS_2'] = $aFields['SCH_WEEK_DAYS']; + break; + case 3 : // $nStartDay = $aFields['SCH_START_DAY']; + $aStartDay = explode('|', $aFields['SCH_START_DAY']); + if($aStartDay[0] == 1){ + $aFields['SCH_START_DAY_OPT_1'] = $aStartDay[1]; + } else { + $aFields['SCH_START_DAY_OPT_2_WEEKS'] = $aStartDay[1]; + $aFields['SCH_START_DAY_OPT_2_DAYS_WEEK'] = $aStartDay[2]; + } + $aFields['SCH_START_DAY'] = $aStartDay[0]; + $aFields['SCH_MONTHS_2'] = $aFields['SCH_MONTHS']; + $aFields['SCH_MONTHS_3'] = $aFields['SCH_MONTHS']; + break; + case 4 : + + break; + } + + $aFields['SCH_START_TIME'] = date('H:i' , strtotime($aFields['SCH_START_TIME'])); + $aFields['PREV_SCH_START_TIME'] = $aFields['SCH_START_TIME']; + + $aFields['SCH_START_DATE'] = date('Y-m-d', strtotime($aFields['SCH_START_DATE'])); + $aFields['PREV_SCH_START_DATE'] = $aFields['SCH_START_DATE']; + + if(!empty($aFields['SCH_END_DATE'])){ + $aFields['SCH_END_DATE'] = date('Y-m-d', strtotime($aFields['SCH_END_DATE'])); + $aFields['PREV_SCH_END_DATE'] = date('Y-m-d', strtotime($aFields['SCH_END_DATE'])); + } + if($aFields['SCH_REPEAT_STOP_IF_RUNNING']==0 || $aFields['SCH_REPEAT_STOP_IF_RUNNING']==null){ + $aFields['SCH_REPEAT_STOP_IF_RUNNING']=null; + }else { + $aFields['SCH_REPEAT_STOP_IF_RUNNING']='On'; + } + + $aFields['SCH_USER_NAME'] = $aFields['SCH_DEL_USER_NAME']; + $aFields['SCH_USER_PASSWORD'] = 'DefaultPM'; + $aFields['SCH_USER_UID'] = $aFields['SCH_DEL_USER_UID']; + $aFields['SCH_START_DATE'] = date ("Y-m-d",strtotime($aFields['SCH_START_DATE'])); + + // validating if any of the advanced fields is non empty +// var_dump($aFields['SCH_END_DATE']); +// var_dump($aFields['SCH_REPEAT_EVERY']); +// die(); + if ($aFields['SCH_END_DATE']!=NULL||trim($aFields['SCH_REPEAT_EVERY'])!=''){ + $aFields['SCH_ADVANCED'] = 'true'; + } else { + $aFields['SCH_ADVANCED'] = 'false'; + } + + $aFields['PRO_UID_TMP'] = isset($_GET['PRO_UID'])?$_GET['PRO_UID']:$_SESSION['PROCESS']; + $aFields['PHP_START_DATE'] = date('Y-m-d'); + $aFields['PHP_END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_Scheduler_Edit.xml', '', $aFields, 'cases_Scheduler_Update'); + + G::RenderPage('publishBlank','blank'); + +} catch (Exception $oException) { + die($oException->getMessage()); +} + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_List.php b/workflow/engine/methods/cases/cases_Scheduler_List.php new file mode 100644 index 000000000..191c3de46 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_List.php @@ -0,0 +1,171 @@ +<?php +/** + * cases_Scheduler_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; +global $RBAC; +/*switch ($RBAC->userCanAccess('PM_USERS')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +}*/ + + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; + +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_SCHEDULER'; +require_once 'classes/model/CaseScheduler.php'; +$process = isset($_GET['PRO_UID'])?$_GET['PRO_UID']:$_SESSION['PROCESS']; +$sDelimiter = DBAdapter::getStringDelimiter(); + + $oCaseScheduler = new CaseScheduler(); + $aRows = $oCaseScheduler->getAllByProcess($process); + + //$oCaseScheduler->caseSchedulerCron(); + // g::pr($aRows); die; + +$fieldNames = Array( + 'SCH_UID' => 'char', + 'SCH_NAME' => 'char', + 'PRO_UID' => 'char', + 'TAS_UID' => 'char', + 'SCH_TIME_NEXT_RUN' => 'char', + 'SCH_LAST_RUN_TIME' => 'char', + 'SCH_STATE' => 'char', + 'SCH_LAST_STATE' => 'char', + 'USR_UID' => 'char', + 'SCH_OPTION' => 'char', + 'SCH_START_TIME' => 'char', + 'SCH_START_DATE' => 'char', + 'SCH_DAYS_PERFORM_TASK' => 'char', + 'SCH_EVERY_DAYS' => 'char', + 'SCH_WEEK_DAYS' => 'char', + 'SCH_START_DAY' => 'char', + 'SCH_MONTHS' => 'char', + 'SCH_END_DATE' => 'char', + 'SCH_REPEAT_EVERY' => 'char', + 'SCH_REPEAT_UNTIL' => 'char', + 'SCH_REPEAT_STOP_IF_RUNNING' => 'char', + 'PRO_PARENT' => 'char', + 'PRO_TIME' => 'char', + 'PRO_TIMEUNIT' => 'char', + 'PRO_STATUS' => 'char', + 'PRO_TYPE_DAY' => 'char', + 'PRO_TYPE' => 'char', + 'PRO_ASSIGNMENT' => 'char', + 'PRO_SHOW_MAP' => 'char', + 'PRO_SHOW_MESSAGE' => 'char', + 'PRO_SHOW_DELEGATE' => 'char', + 'PRO_SHOW_DYNAFORM' => 'char', + 'PRO_CATEGORY' => 'char', + 'PRO_SUB_CATEGORY' => 'char', + 'PRO_INDUSTRY' => 'char', + 'PRO_UPDATE_DATE' => 'char', + 'PRO_CREATE_DATE' => 'char', + 'PRO_CREATE_USER' => 'char', + 'PRO_HEIGHT' => 'char', + 'PRO_WIDTH' => 'char', + 'PRO_TITLE_X' => 'char', + 'PRO_TITLE_Y' => 'char', + 'PRO_DEBUG' => 'char', + 'PRO_TITLE' => 'char', + 'PRO_DESCRIPTION' => 'char', + 'TAS_TYPE' => 'char', + 'TAS_DURATION' => 'char', + 'TAS_DELAY_TYPE' => 'char', + 'TAS_TEMPORIZER' => 'char', + 'TAS_TYPE_DAY' => 'char', + 'TAS_TIMEUNIT' => 'char', + 'TAS_ALERT' => 'char', + 'TAS_PRIORITY_VARIABLE' => 'char', + 'TAS_ASSIGN_TYPE' => 'char', + 'TAS_ASSIGN_VARIABLE' => 'char', + 'TAS_ASSIGN_LOCATION' => 'char', + 'TAS_ASSIGN_LOCATION_ADHOC' => 'char', + 'TAS_TRANSFER_FLY' => 'char', + 'TAS_LAST_ASSIGNED' => 'char', + 'TAS_USER' => 'char', + 'TAS_CAN_UPLOAD' => 'char', + 'TAS_VIEW_UPLOAD' => 'char', + 'TAS_VIEW_ADDITIONAL_DOCUMENTATION' => 'char', + 'TAS_CAN_CANCEL' => 'char', + 'TAS_OWNER_APP' => 'char', + 'STG_UID' => 'char', + 'TAS_CAN_PAUSE' => 'char', + 'TAS_CAN_SEND_MESSAGE' => 'char', + 'TAS_CAN_DELETE_DOCS' => 'char', + 'TAS_SELF_SERVICE' => 'char', + 'TAS_START' => 'char', + 'TAS_TO_LAST_USER' => 'char', + 'TAS_SEND_LAST_EMAIL' => 'char', + 'TAS_DERIVATION' => 'char', + 'TAS_POSX' => 'char', + 'TAS_POSY' => 'char', + 'TAS_COLOR' => 'char', + 'TAS_TITLE' => 'char', + 'TAS_DESCRIPTION' => 'char', + 'TAS_DEF_TITLE' => 'char', + 'TAS_DEF_DESCRIPTION' => 'char', + 'TAS_DEF_PROC_CODE' => 'char', + 'TAS_DEF_MESSAGE' => 'char' +); + + +$aRows = array_merge(Array($fieldNames), $aRows); +//krumo ($aRows); +for($j=0;$j<count($aRows);$j++){ + if ($aRows[$j]['SCH_STATE'] == 'PROCESSED'){ + $aRows[$j]['SCH_TIME_NEXT_RUN'] = ''; + } +} +// g::pr($aRows); die; + +global $_DBArray; +$_DBArray['cases_scheduler'] = $aRows; +$_SESSION['_DBArray'] = $_DBArray; +G::LoadClass('ArrayPeer'); +$oCriteria = new Criteria('dbarray'); +$oCriteria->setDBArrayTable('cases_scheduler'); +//krumo ($oCriteria); +//var_dump ($oCriteria); +//$oCriteria->add('PRO_UID', $_SESSION['PROCESS']); +//krumo($_SESSION); + + +$G_PUBLISH = new Publisher; +$G_PUBLISH->ROWS_PER_PAGE = 10; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_Scheduler_List', $oCriteria, array('CONFIRM' => G::LoadTranslation('ID_MSG_CONFIRM_DELETE_CASE_SCHEDULER'))); +$G_PUBLISH->oPropelTable->rowsPerPage = 10; +G::RenderPage('publishBlank', 'blank'); + diff --git a/workflow/engine/methods/cases/cases_Scheduler_Log.php b/workflow/engine/methods/cases/cases_Scheduler_Log.php new file mode 100644 index 000000000..278372a22 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Log.php @@ -0,0 +1,70 @@ +<?php + +/** + * cases_Scheduler_Log.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; +global $RBAC; + +if (!class_exists('LogCasesSchedulerPeer')){ +require ("classes/model/LogCasesSchedulerPeer.php"); +} + +$oLogCaseScheduler = new LogCasesScheduler(); +$aRows = $oLogCaseScheduler->getAll(); + +$fieldNames = Array( + 'LOG_CASE_UID' => 'char', + 'PRO_UID' => 'char', + 'TAS_UID' => 'char', + 'USR_NAME' => 'char', + 'EXEC_DATE' => 'char', + 'EXEC_HOUR' => 'char', + 'RESULT' => 'char', + 'SCH_UID' => 'char', + 'WS_CREATE_CASE_STATUS' => 'char', + 'WS_ROUTE_CASE_STATUS' => 'char', +); + +$aRows = array_merge(Array($fieldNames), $aRows); + + +$_DBArray['log_cases_scheduler'] = $aRows; +$_SESSION['_DBArray'] = $_DBArray; + +$oCriteria = new Criteria('dbarray'); +$oCriteria->setDBArrayTable('log_cases_scheduler'); +//krumo($oCriteria); +//$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'cases'; +// +//$G_ID_MENU_SELECTED = 'CASES'; +//$G_ID_SUB_MENU_SELECTED = 'CASES_SCHEDULER_LOG'; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->ROWS_PER_PAGE = 10; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_Scheduler_Log', $oCriteria); +$G_PUBLISH->oPropelTable->rowsPerPage = 10; +G::RenderPage('publishBlank', 'blank'); + +?> diff --git a/workflow/engine/methods/cases/cases_Scheduler_Log_Detail.php b/workflow/engine/methods/cases/cases_Scheduler_Log_Detail.php new file mode 100644 index 000000000..1841b29f2 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Log_Detail.php @@ -0,0 +1,94 @@ +<?php +/** + * cases_Scheduler_Log_Detail.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + +/* + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +*/ + +/* + $aFields['MESSAGE0'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_USER_REGISTERED')) . '!'; + $aFields['MESSAGE1'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME')); + $aFields['MESSAGE2'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_DUE_DATE')); + $aFields['MESSAGE3'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS')); + $aFields['MESSAGE4'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME')); + $aFields['MESSAGE5'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME')); + // the default role variable sets the value that will be showed as the default for the role field. + $aFields['DEFAULT_ROLE'] = 'PROCESSMAKER_OPERATOR'; + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['USR_DUE_DATE']= date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 1)); +*/ + if (!class_exists('LogCasesSchedulerPeer')){ + require_once('classes/model/LogCasesScheduler.php'); + } + + $G_PUBLISH = new Publisher; + + $oCriteria = new Criteria ('workflow'); +// var_dump(htmlspecialchars($_GET['WS_ROUTE'])); +// var_dump(htmlentities($_GET['WS_ROUTE'])); + + $oCriteria->add(LogCasesSchedulerPeer::LOG_CASE_UID,$_GET['LOG_CASE_UID']); + + $result = LogCasesSchedulerPeer::doSelectRS($oCriteria); + $result->next(); + $row = $result->getRow(); + $aFields['PRO_UID'] = $row[1]; + $aFields['TAS_UID'] = $row[2]; + $aFields['SCH_UID'] = $row[7]; + $aFields['USR_NAME'] = $row[3]; + $aFields['EXEC_DATE'] = $row[4]; + $aFields['EXEC_HOUR'] = $row[5]; + $aFields['RESULT'] = $row[6]; + $aFields['WS_CREATE_CASE_STATUS'] = $row[8]; + $aFields['WS_ROUTE_CASE_STATUS'] = htmlentities($row[9]); +//var_dump($aFields); +//$aFields = $_GET; + + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_Scheduler_Log_Detail.xml', '', $aFields, ''); + G::RenderPage('publishBlank', 'blank'); + + + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_New.php b/workflow/engine/methods/cases/cases_Scheduler_New.php new file mode 100644 index 000000000..35395fe43 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_New.php @@ -0,0 +1,101 @@ +<?php +/** + * cases_SchedulerNew.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + +/* + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +*/ + +/* + $aFields['MESSAGE0'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_USER_REGISTERED')) . '!'; + $aFields['MESSAGE1'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME')); + $aFields['MESSAGE2'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_DUE_DATE')); + $aFields['MESSAGE3'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS')); + $aFields['MESSAGE4'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME')); + $aFields['MESSAGE5'] = str_replace("\r\n","<br>",G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME')); + // the default role variable sets the value that will be showed as the default for the role field. + $aFields['DEFAULT_ROLE'] = 'PROCESSMAKER_OPERATOR'; + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['USR_DUE_DATE']= date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 1)); +*/ + + require_once 'classes/model/CaseScheduler.php'; + require_once 'classes/model/Process.php'; + require_once 'classes/model/Task.php'; + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; + +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_SCHEDULER'; + + $G_PUBLISH = new Publisher; + + G::LoadClass('case'); + $aFields['PHP_START_DATE'] = date('Y-m-d'); + $aFields['PRO_UID'] = isset($_GET['PRO_UID'])?$_GET['PRO_UID']:$_SESSION['PROCESS']; + $aFields['PHP_CURRENT_DATE'] = $aFields['PHP_START_DATE']; + $aFields['PHP_END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + + /* Prepare page before to show */ + + /*-- Base + $aFields = array(); + $oCase = new Cases(); + $_DBArray['NewCase'] = $oCase->getStartCases( $_SESSION['USER_LOGGED'] ); + */ + + + $oCaseScheduler = new CaseScheduler(); + //$_DBArray['NewProcess'] = $oCaseScheduler->getProcessDescription(); + //$_DBArray['NewTask'] = $oCaseScheduler->getTaskDescription(); + + // var_dump($oCaseScheduler->getAllProcess()); die; + + $aFields['UID_SCHEDULER'] ="scheduler" ; + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_Scheduler_New.xml', '', $aFields, 'cases_Scheduler_Save'); + G::RenderPage('publishBlank', 'blank'); + + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_Save.php b/workflow/engine/methods/cases/cases_Scheduler_Save.php new file mode 100644 index 000000000..bf4fc0130 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Save.php @@ -0,0 +1,238 @@ +<?php +/** + * cases_Scheduler_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + /* + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + */ + + + require_once 'classes/model/CaseScheduler.php'; + $oCaseScheduler = new CaseScheduler(); + + if (empty($_POST)) { + die('The information sended is empty!'); + } + + $aData['SCH_UID'] = G::generateUniqueID(); + $aData['SCH_NAME'] = $_POST['form']['SCH_NAME']; + $aData['SCH_DEL_USER_NAME'] = $_POST['form']['SCH_USER_NAME']; + $aData['SCH_DEL_USER_PASS'] = md5($_POST['form']['SCH_USER_PASSWORD']); + $aData['SCH_DEL_USER_UID'] = $_POST['form']['SCH_USER_UID']; + $aData['PRO_UID'] = $_POST['form']['PRO_UID']; + $aData['TAS_UID'] = $_POST['form']['TAS_UID']; + + $aData['SCH_STATE'] = 'ACTIVE'; + $aData['SCH_LAST_STATE'] = 'CREATED'; // 'ACTIVE'; + $aData['USR_UID'] = $_SESSION['USER_LOGGED']; + + $sOption = $_POST['form']['SCH_OPTION']; + $aData['SCH_OPTION'] = $sOption; + + if ($_POST['form']['SCH_START_DATE']!=''){ + $sDateTmp = $_POST['form']['SCH_START_DATE']; + } else { + $sDateTmp = date('Y-m-d'); + } + $sTimeTmp = $_POST['form']['SCH_START_TIME']; + $aData['SCH_START_TIME'] = date('Y-m-d', strtotime($sDateTmp)) . ' ' . date('H:i:s', strtotime($sTimeTmp)); + $aData['SCH_START_DATE'] = date('Y-m-d', strtotime($sDateTmp)) . ' ' . date('H:i:s', strtotime($sTimeTmp)); + + $nActualTime = $_POST['form']['SCH_START_TIME']; // time(); + // $nActualDate = date("Y-m-d H:i:s", $nActualTime); + + $sValue = ''; + $sDaysPerformTask = ''; + $sWeeks = ''; + $sMonths = ''; + $sMonths = ''; + $sStartDay = ''; + $nSW = 0; + + switch($sOption){ + case '1' : // Option 1 + $sValue = $_POST['form']['SCH_DAYS_PERFORM_TASK']; + switch($sValue){ + case '1' : $aData['SCH_DAYS_PERFORM_TASK'] = $_POST['form']['SCH_DAYS_PERFORM_TASK'] . '|1'; + break; + case '2' : + $aData['SCH_OPTION'] = '2'; + $aData['SCH_EVERY_DAYS'] = '1'; + $aData['SCH_WEEK_DAYS'] = '1|2|3|4|5|'; + break; + case '3' : // Every [n] Days + $sDaysPerformTask = $_POST['form']['SCH_DAYS_PERFORM_TASK_OPT_3']; + $aData['SCH_DAYS_PERFORM_TASK'] = $_POST['form']['SCH_DAYS_PERFORM_TASK'] . '|' . $_POST['form']['SCH_DAYS_PERFORM_TASK_OPT_3']; + break; + } + break; + + case '2' : // If the option is zero, set by default 1 + if(empty($_POST['form']['SCH_EVERY_DAYS'])) + $nEveryDays = 1; + else + $nEveryDays = $_POST['form']['SCH_EVERY_DAYS']; + $aData['SCH_EVERY_DAYS'] = $nEveryDays; + $sWeeks = ''; + if(!empty($_POST['form']['SCH_WEEK_DAYS'])){ + $aWeekDays = $_POST['form']['SCH_WEEK_DAYS']; + foreach($aWeekDays as $value) { + $sWeeks = $sWeeks . $value . '|'; + } + } + if(!empty($_POST['form']['SCH_WEEK_DAYS_2'])){ + $aWeekDays2 = $_POST['form']['SCH_WEEK_DAYS_2']; + foreach($aWeekDays2 as $value) { + $sWeeks = $sWeeks . $value . '|'; + } + } + $sStartTime = $_POST['form']['SCH_START_TIME']; + $aData['SCH_WEEK_DAYS'] = $sWeeks; + + break; + case '3' : + $nStartDay = $_POST['form']['SCH_START_DAY']; + if($nStartDay == 1){ + $aData['SCH_START_DAY'] = $nStartDay . '|' . $_POST['form']['SCH_START_DAY_OPT_1']; + } else { + $aData['SCH_START_DAY'] = $nStartDay . '|' . $_POST['form']['SCH_START_DAY_OPT_2_WEEKS'] . '|' . $_POST['form']['SCH_START_DAY_OPT_2_DAYS_WEEK']; + } + + $sMonths = ''; + if(!empty($_POST['form']['SCH_MONTHS'])){ + $aMonths = $_POST['form']['SCH_MONTHS']; + foreach($aMonths as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + if(!empty($_POST['form']['SCH_MONTHS_2'])){ + $aMonths2 = $_POST['form']['SCH_MONTHS_2']; + foreach($aMonths2 as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + if(!empty($_POST['form']['SCH_MONTHS_3'])){ + $aMonths3 = $_POST['form']['SCH_MONTHS_3']; + foreach($aMonths3 as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + $aData['SCH_MONTHS'] = $sMonths; + $sStartDay = $aData['SCH_START_DAY']; + $sValue = $nStartDay; + break; + + + } + if(($sOption!='1') && ($sOption!='4')) { + if ($sStartDay==''){ + $sStartDay = date('Y-m-d'); + } + // echo $sOption."*". $sValue."*". $nActualTime."*". $sDaysPerformTask."*". $sWeeks."*". $sStartDay ."*". $sMonths."<br>"; + $dCurrentDay = date("d"); + $dCurrentMonth = date("m"); + $aStartDay = explode( "|" , $aData['SCH_START_DAY'] ); + if($sOption=='3'&&$aStartDay[0]=='1'){ + $monthsArray = explode("|",$sMonths); + foreach ($monthsArray as $row){ + if ( $dCurrentMonth == $row && $dCurrentDay<$aStartDay[1] ){ + $startTime = $_POST['form']['SCH_START_TIME'].":00"; + $aData['SCH_TIME_NEXT_RUN'] = date('Y') . '-' . $row . '-' . $aStartDay[1] . ' ' . $startTime; + break; + } else { + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->updateNextRun($sOption, $sValue, $nActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths, $sDateTmp); + } + } + } else { + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->updateNextRun($sOption, $sValue, $nActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths, $sDateTmp); + } + // print_r ($aData['SCH_TIME_NEXT_RUN']); + // die; + } else { + if ($sOption=='4'){ + $aData['SCH_END_DATE'] = $aData['SCH_START_TIME']; + } + $aData['SCH_TIME_NEXT_RUN'] = $aData['SCH_START_TIME']; + } + + if(trim($_POST['form']['SCH_END_DATE'])!=''){ + $aData['SCH_END_DATE'] = $_POST['form']['SCH_END_DATE']; + } + + if(!empty($_POST['form']['SCH_REPEAT_TASK_CHK'])){ + $nOptEvery = $_POST['form']['SCH_REPEAT_EVERY_OPT']; + if($nOptEvery ==2) + $aData['SCH_REPEAT_EVERY'] = $_POST['form']['SCH_REPEAT_EVERY'] * 60; + else + $aData['SCH_REPEAT_EVERY'] = $_POST['form']['SCH_REPEAT_EVERY']; + + + } + + if((isset($_POST['form']['CASE_SH_PLUGIN_UID']))&&($_POST['form']['CASE_SH_PLUGIN_UID']!="")){ + $aData['CASE_SH_PLUGIN_UID'] = $_POST['form']['CASE_SH_PLUGIN_UID']; + } + //$aData['SCH_END_DATE'] = "2020-12-30"; + $oCaseScheduler->create($aData); + if((isset($_POST['form']['CASE_SH_PLUGIN_UID']))&&($_POST['form']['CASE_SH_PLUGIN_UID']!="")){ + $params=explode("--",$_REQUEST ['form']['CASE_SH_PLUGIN_UID']); + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $activePluginsForCaseScheduler=$oPluginRegistry->getCaseSchedulerPlugins(); + + foreach($activePluginsForCaseScheduler as $key => $caseSchedulerPluginDetail){ + if(($caseSchedulerPluginDetail->sNamespace==$params[0])&&($caseSchedulerPluginDetail->sActionId==$params[1])){ + $caseSchedulerSelected=$caseSchedulerPluginDetail; + + } + } + if((isset($caseSchedulerSelected))&&(is_object($caseSchedulerSelected))){ + //Save the form + $oData=$_POST['pluginFields']; + $oData['SCH_UID'] =$aData['SCH_UID']; + $oPluginRegistry->executeMethod( $caseSchedulerPluginDetail->sNamespace, $caseSchedulerPluginDetail->sActionSave, $oData ); + } + } + + G::header('location: cases_Scheduler_List?PRO_UID='.$_POST['form']['PRO_UID']); + + +} +catch (Exception $oException) { + die($oException->getMessage()); +} + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Scheduler_Update.php b/workflow/engine/methods/cases/cases_Scheduler_Update.php new file mode 100644 index 000000000..46ffbf845 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Scheduler_Update.php @@ -0,0 +1,273 @@ +<?php +/** + * cases_Scheduler_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { +/* + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + */ + + require_once 'classes/model/CaseScheduler.php'; + + + if (empty($_POST)) { + die('The information sended is empty!'); + } + + $aData['SCH_UID'] = $_POST['form']['SCH_UID']; + $aData['SCH_NAME'] = $_POST['form']['SCH_NAME']; + $aData['PRO_UID'] = $_POST['form']['PRO_UID']; + $aData['TAS_UID'] = $_POST['form']['TAS_UID']; + + $oCaseScheduler = new CaseScheduler(); + $oCaseScheduler->Load($aData['SCH_UID']); + + $aData['SCH_DEL_USER_NAME'] = $_POST['form']['SCH_USER_NAME']; + if ($_POST['form']['SCH_USER_PASSWORD'] != 'DefaultPM'){ + $aData['SCH_DEL_USER_PASS'] = md5($_POST['form']['SCH_USER_PASSWORD']); + } + $aData['SCH_DEL_USER_UID'] = $_POST['form']['SCH_USER_UID']; + +// $aData['SCH_TIME_NEXT_RUN'] = time(); + //$aData['SCH_LAST_RUN_TIME'] = time(); +// $aData['SCH_STATE'] = 'ACTIVE'; +// $aData['SCH_LAST_STATE'] = 'ACTIVE'; + $aData['USR_UID'] = $_SESSION['USER_LOGGED']; + + $sOption = $_POST['form']['SCH_OPTION']; + $aData['SCH_OPTION'] = $sOption; + + $sDateTmp = $_POST['form']['SCH_START_DATE']; + $sTimeTmp = $_POST['form']['SCH_START_TIME']; + $aData['SCH_START_TIME'] = date('Y-m-d', strtotime($sDateTmp)) . ' ' . date('H:i:s', strtotime($sTimeTmp)); + $aData['SCH_START_DATE'] = date('Y-m-d', strtotime($sDateTmp)) . ' ' . date('H:i:s', strtotime($sTimeTmp)); + $previousStartTime = date('Y-m-d', strtotime($_POST['form']['PREV_SCH_START_DATE'])) . ' ' . date('H:i:s', strtotime($_POST['form']['PREV_SCH_START_TIME'])); + $previousStartDate = date('Y-m-d', strtotime($_POST['form']['PREV_SCH_START_DATE'])) . ' ' . date('H:i:s', strtotime($_POST['form']['PREV_SCH_START_TIME'])); + + $sValue = ''; + $sDaysPerformTask = ''; + $sWeeks = ''; + $sMonths = ''; + $sMonths = ''; + $sStartDay = ''; + $nSW = 0; + + switch($sOption){ + case '1' : // Option 1 + $sValue = $_POST['form']['SCH_DAYS_PERFORM_TASK']; + switch($sValue){ + case '1' : $aData['SCH_DAYS_PERFORM_TASK'] = $_POST['form']['SCH_DAYS_PERFORM_TASK'] . '|1'; + break; + case '2' : + $aData['SCH_OPTION'] = '2'; + $aData['SCH_EVERY_DAYS'] = '1'; + $aData['SCH_WEEK_DAYS'] = '1|2|3|4|5|'; + break; + case '3' : // Every [n] Days + $sDaysPerformTask = $_POST['form']['SCH_DAYS_PERFORM_TASK_OPT_3']; + $aData['SCH_DAYS_PERFORM_TASK'] = $_POST['form']['SCH_DAYS_PERFORM_TASK'] . '|' . $_POST['form']['SCH_DAYS_PERFORM_TASK_OPT_3']; + break; + } + break; + case '2' : // If the option is zero, set by default 1 + if(empty($_POST['form']['SCH_EVERY_DAYS'])) + $nEveryDays = 1; + else + $nEveryDays = $_POST['form']['SCH_EVERY_DAYS']; + $aData['SCH_EVERY_DAYS'] = $nEveryDays; + $sWeeks = ''; + if(!empty($_POST['form']['SCH_WEEK_DAYS'])){ + $aWeekDays = $_POST['form']['SCH_WEEK_DAYS']; + foreach($aWeekDays as $value) { + $sWeeks = $sWeeks . $value . '|'; + } + } + if(!empty($_POST['form']['SCH_WEEK_DAYS_2'])){ + $aWeekDays2 = $_POST['form']['SCH_WEEK_DAYS_2']; + foreach($aWeekDays2 as $value) { + $sWeeks = $sWeeks . $value . '|'; + } + } + $sStartTime = $_POST['form']['SCH_START_TIME']; + $aData['SCH_WEEK_DAYS'] = $sWeeks; + break; + + case '3' : + $nStartDay = $_POST['form']['SCH_START_DAY']; + if($nStartDay == 1){ + $aData['SCH_START_DAY'] = $nStartDay . '|' . $_POST['form']['SCH_START_DAY_OPT_1']; + } else { + $aData['SCH_START_DAY'] = $nStartDay . '|' . $_POST['form']['SCH_START_DAY_OPT_2_WEEKS'] . '|' . $_POST['form']['SCH_START_DAY_OPT_2_DAYS_WEEK']; + } + + $sMonths = ''; + if(!empty($_POST['form']['SCH_MONTHS'])){ + $aMonths = $_POST['form']['SCH_MONTHS']; + foreach($aMonths as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + if(!empty($_POST['form']['SCH_MONTHS_2'])){ + $aMonths2 = $_POST['form']['SCH_MONTHS_2']; + foreach($aMonths2 as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + if(!empty($_POST['form']['SCH_MONTHS_3'])){ + $aMonths3 = $_POST['form']['SCH_MONTHS_3']; + foreach($aMonths3 as $value) { + $sMonths = $sMonths . $value . '|' ; + } + } + $aData['SCH_MONTHS'] = $sMonths; + $sStartDay = $aData['SCH_START_DAY']; + $sValue = $nStartDay; + break; + + } + if(trim($_POST['form']['SCH_END_DATE'])!=''){ + $aData['SCH_END_DATE'] = $_POST['form']['SCH_END_DATE']; + } +// if the start date has changed then recalculate the next run time + if ($_POST['form']['SCH_START_DATE']==$_POST['form']['PREV_SCH_START_DATE']){ + $recalculateDate = false; + } else { + $recalculateDate = true; + } + if (date('H:i:s', strtotime($_POST['form']['SCH_START_TIME']))==date('H:i:s', strtotime($_POST['form']['PREV_SCH_START_TIME']))){ + $recalculateTime = false; + } else { + $recalculateTime = true; + } +// if the start date has changed then recalculate the next run time + +// var_dump($recalculateTime); +// die(); + $nActualTime = $_POST['form']['SCH_START_TIME']; + if(($sOption!='1') && ($sOption!='4')) { + if ($sStartDay==''){ + $sStartDay = date('Y-m-d'); + } +// echo $sOption."*". $sValue."*". $nActualTime."*". $sDaysPerformTask."*". $sWeeks."*". $sStartDay ."*". $sMonths."<br>"; + $dCurrentDay = date("d"); + $dCurrentMonth = date("m"); + $aStartDay = explode( "|" , $aData['SCH_START_DAY'] ); + if($sOption=='3'&&$aStartDay[0]=='1'){ + $monthsArray = explode("|",$sMonths); + foreach ($monthsArray as $row){ + if ( $dCurrentMonth == $row && $dCurrentDay<$aStartDay[1] ){ + $startTime = $_POST['form']['SCH_START_TIME'].":00"; + if ($recalculateDate) { + $aData['SCH_TIME_NEXT_RUN'] = date('Y') . '-' . $row . '-' . $aStartDay[1] . ' ' . $startTime; + } else if ($recalculateTime){ + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->getSchTimeNextRun("Y-m-d"). " " . $_POST['form']['SCH_START_TIME'] . ":00"; + } + break; + } else { + if ($recalculateDate) { + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->updateNextRun($sOption, $sValue, $nActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths, $sDateTmp); + } else if ($recalculateTime){ + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->getSchTimeNextRun("Y-m-d"). " " . $_POST['form']['SCH_START_TIME'] . ":00"; + } + } + } + } else { + if ($recalculateDate) { + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->updateNextRun($sOption, $sValue, $nActualTime, $sDaysPerformTask, $sWeeks, $sStartDay, $sMonths, $sDateTmp); + } else if ($recalculateTime){ + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->getSchTimeNextRun("Y-m-d"). " " . $_POST['form']['SCH_START_TIME'] . ":00"; + } + } +// print_r ($aData['SCH_TIME_NEXT_RUN']); +// die; + } else { + if ($sOption=='4'){ + $aData['SCH_END_DATE'] = $aData['SCH_START_TIME']; + } + if ($recalculateDate) { + $aData['SCH_TIME_NEXT_RUN'] = $aData['SCH_START_TIME']; + } else if ($recalculateTime){ + +// $Fields = $oCaseScheduler->Load($aData['SCH_UID']); +// $Fields['SCH_LAST_STATE'] = $aRow['SCH_STATE']; +// $Fields['SCH_STATE'] = 'PROCESSED'; +// $this->Update($Fields); + $aData['SCH_TIME_NEXT_RUN'] = $oCaseScheduler->getSchTimeNextRun("Y-m-d"). " " . $_POST['form']['SCH_START_TIME'] . ":00"; + } +// var_dump($recalculateTime); +// var_dump($aData['SCH_TIME_NEXT_RUN']); +// die; + } + + if(!empty($_POST['form']['SCH_REPEAT_TASK_CHK'])){ + $nOptEvery = $_POST['form']['SCH_REPEAT_EVERY_OPT']; + if($nOptEvery ==2) + $aData['SCH_REPEAT_EVERY'] = $_POST['form']['SCH_REPEAT_EVERY'] * 60; + else + $aData['SCH_REPEAT_EVERY'] = $_POST['form']['SCH_REPEAT_EVERY']; + + + } +// var_dump ($aData['SCH_TIME_NEXT_RUN']); +// die; + $oCaseScheduler ->Update($aData); + if((isset($_POST['form']['CASE_SH_PLUGIN_UID']))&&($_POST['form']['CASE_SH_PLUGIN_UID']!="")){ + $params=explode("--",$_REQUEST ['form']['CASE_SH_PLUGIN_UID']); + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $activePluginsForCaseScheduler=$oPluginRegistry->getCaseSchedulerPlugins(); + + foreach($activePluginsForCaseScheduler as $key => $caseSchedulerPluginDetail){ + if(($caseSchedulerPluginDetail->sNamespace==$params[0])&&($caseSchedulerPluginDetail->sActionId==$params[1])){ + $caseSchedulerSelected=$caseSchedulerPluginDetail; + + } + } + if((isset($caseSchedulerSelected))&&(is_object($caseSchedulerSelected))){ + //Save the form + $oData=$_POST['pluginFields']; + $oData['SCH_UID'] =$aData['SCH_UID']; + $oPluginRegistry->executeMethod( $caseSchedulerPluginDetail->sNamespace, $caseSchedulerPluginDetail->sActionSave, $oData ); + } + } + + G::header('location: cases_Scheduler_List?PRO_UID='.$_POST['form']['PRO_UID']); + + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_ShowDocument.php b/workflow/engine/methods/cases/cases_ShowDocument.php new file mode 100644 index 000000000..c74e67c65 --- /dev/null +++ b/workflow/engine/methods/cases/cases_ShowDocument.php @@ -0,0 +1,65 @@ +<?php +/** + * cases_ShowDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 13-02-2008 + * + * @author David Callizaya <davidsantos@colosa.com> + */ + + require_once ( "classes/model/AppDocumentPeer.php" ); + + $oAppDocument = new AppDocument(); + if(!isset($_GET['v'])){//Load last version of the document + $docVersion=$oAppDocument->getLastAppDocVersion($_GET['a']); + }else{ + $docVersion=$_GET['v']; + } + $oAppDocument->Fields = $oAppDocument->load($_GET['a'],$docVersion); + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $iDocVersion = $oAppDocument->getDocVersion(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + $ext = $info['extension']; + + if (isset($_GET['b'])) { + if ($_GET['b'] == '0') { + $bDownload = false; + } + else { + $bDownload = true; + } + } + else { + $bDownload = true; + } + + $realPath = PATH_DOCUMENT . $oAppDocument->Fields['APP_UID'] . '/' . $sAppDocUid .'_'.$iDocVersion . '.' . $ext ; + if(!file_exists ( $realPath )){//For Backward compatibility + $realPath = PATH_DOCUMENT . $oAppDocument->Fields['APP_UID'] . '/' . $sAppDocUid . '.' . $ext ; + } + + G::streamFile ( $realPath, $bDownload, $oAppDocument->Fields['APP_DOC_FILENAME'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_ShowOutputDocument.php b/workflow/engine/methods/cases/cases_ShowOutputDocument.php new file mode 100644 index 000000000..285741634 --- /dev/null +++ b/workflow/engine/methods/cases/cases_ShowOutputDocument.php @@ -0,0 +1,53 @@ +<?php +/** + * cases_ShowOutputDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 13-02-2008 + * + * @author David Callizaya <davidsantos@colosa.com> + */ + + require_once ( "classes/model/AppDocumentPeer.php" ); + + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_GET['a'],(isset($_GET['v']) )? $_GET['v'] : NULL ); + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + if (!isset($_GET['ext'])) { + $ext = $info['extension']; + } + else { + if ($_GET['ext'] != '') { + $ext = $_GET['ext']; + } + else { + $ext = $info['extension']; + } + } + $ver= (isset($_GET['v']) && $_GET['v']!='') ? '_'.$_GET['v'] : ''; + $realPath = PATH_DOCUMENT . $oAppDocument->Fields['APP_UID'] . '/outdocs/' . $info['basename'] .$ver. '.' . $ext ; + G::streamFile ( $realPath, true ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_ShowToReviseOutputDocument.php b/workflow/engine/methods/cases/cases_ShowToReviseOutputDocument.php new file mode 100644 index 000000000..b1a0036c6 --- /dev/null +++ b/workflow/engine/methods/cases/cases_ShowToReviseOutputDocument.php @@ -0,0 +1,66 @@ +<?php +/** + * cases_ShowOutputDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 13-02-2008 + * + * @author David Callizaya <davidsantos@colosa.com> + */ + + switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + require_once ( "classes/model/AppDocumentPeer.php" ); + + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_GET['a']); + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + if (!isset($_GET['ext'])) { + $ext = $info['extension']; + } + else { + if ($_GET['ext'] != '') { + $ext = $_GET['ext']; + } + else { + $ext = $info['extension']; + } + } + + $realPath = PATH_DOCUMENT . $_SESSION['APPLICATION'] . '/outdocs/' . $info['basename'] . '.' . $ext ; + G::streamFile ( $realPath, true ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_Step.php b/workflow/engine/methods/cases/cases_Step.php new file mode 100644 index 000000000..4f46b7ee7 --- /dev/null +++ b/workflow/engine/methods/cases/cases_Step.php @@ -0,0 +1,875 @@ +<?php +/** + * cases_Step.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* Permissions */ + switch ($RBAC->userCanAccess('PM_CASES')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + if ( (int)$_SESSION['INDEX'] < 1 ) + { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; + } + global $_DBArray; + if (!isset($_DBArray)) { + $_DBArray = array(); + } + + /* Includes */ + G::LoadClass('case'); + G::LoadClass('derivation'); + + /* GET , POST & $_SESSION Vars */ + if(isset($_GET['POSITION'])) { + $_SESSION['STEP_POSITION'] = (int)$_GET['POSITION']; + } + if(isset($_SESSION['CASES_REFRESH'])){ + unset($_SESSION['CASES_REFRESH']); + echo "<script language='javascript'>if(parent.refreshCountFolders) parent.refreshCountFolders();</script>"; + } + + /* Menues */ + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_SUB_MENU = 'caseOptions'; + $G_ID_SUB_MENU_SELECTED = '_'; + + /* Prepare page before to show */ + $oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + var Cse = {}; + Cse.panels = {}; + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.exec(leimnud.fix.memoryLeak); + leimnud.event.add(window,"load",function(){ + '.(isset($_SESSION['showCasesWindow'])?'try{'.$_SESSION['showCasesWindow'].'}catch(e){}':'').' + }); + '); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + + $oCase = new Cases(); + + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $Fields['APP_DATA'] = array_merge($Fields['APP_DATA'], G::getSystemConstants()); + $sStatus = $Fields['APP_STATUS']; + + $APP_NUMBER = $Fields['APP_NUMBER']; + $APP_TITLE = $Fields['TITLE']; + + //optimize for speed, we are reading process info once + //$oProcess = new Process(); + //$oProcessFields = $oProcess->Load($_SESSION['PROCESS']); + $oProcess = ProcessPeer::retrieveByPk( $_SESSION['PROCESS'] ); + $oProcessFields = $oProcess->toArray(BasePeer::TYPE_FIELDNAME); + + #trigger debug routines... + + if( isset($oProcessFields['PRO_DEBUG']) && $oProcessFields['PRO_DEBUG'] ) { #here we must verify if is a debugg session + $_SESSION['TRIGGER_DEBUG']['ISSET'] = 1; + $_SESSION['PMDEBUGGER']= true; + } + else { + $_SESSION['TRIGGER_DEBUG']['ISSET'] = 0; + $_SESSION['PMDEBUGGER']= false; + } + + //cleaning debug variables + if( !isset($_GET['breakpoint']) ) { + if( isset($_SESSION['TRIGGER_DEBUG']['info']) ) unset($_SESSION['TRIGGER_DEBUG']['info']); + + if (!isset($_SESSION['_NO_EXECUTE_TRIGGERS_'])) { + $_SESSION['TRIGGER_DEBUG']['ERRORS'] = Array(); + } + $_SESSION['TRIGGER_DEBUG']['DATA'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = Array(); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = Array(); + + $triggers = $oCase->loadTriggers( $_SESSION['TASK'], $_GET['TYPE'], $_GET['UID'], 'BEFORE'); + + $_SESSION['TRIGGER_DEBUG']['NUM_TRIGGERS'] = count($triggers); + $_SESSION['TRIGGER_DEBUG']['TIME'] = 'BEFORE'; + if($_SESSION['TRIGGER_DEBUG']['NUM_TRIGGERS'] != 0) { + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_NAMES'] = $oCase->getTriggerNames($triggers); + $_SESSION['TRIGGER_DEBUG']['TRIGGERS_VALUES'] = $triggers; + } + + if (!isset($_SESSION['_NO_EXECUTE_TRIGGERS_'])) { + //Execute before triggers - Start + $Fields['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION['TASK'], $_GET['TYPE'], $_GET['UID'], 'BEFORE', $Fields['APP_DATA'] ); + $Fields['DEL_INDEX']= $_SESSION['INDEX']; + $Fields['TAS_UID'] = $_SESSION['TASK']; + //Execute before triggers - End + } + else { + unset($_SESSION['_NO_EXECUTE_TRIGGERS_']); + $Fields['DEL_INDEX']= $_SESSION['INDEX']; + $Fields['TAS_UID'] = $_SESSION['TASK']; + } + } + + if( isset($_GET['breakpoint']) ) { + $_POST['NextStep'] = $_SESSION['TRIGGER_DEBUG']['BREAKPAGE']; + } + + /** + * Here we throw the debug view + */ + if ( isset($_GET['breakpoint']) ) { + + $G_PUBLISH->AddContent('view', 'cases/showDebugFrameLoader'); + $G_PUBLISH->AddContent('view', 'cases/showDebugFrameBreaker'); + G::RenderPage('publish', 'blank'); + exit(); + } + #end trigger debug session....... + + $oCase->thisIsTheCurrentUser($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['USER_LOGGED'], 'REDIRECT', 'cases_List'); + + //Save data - Start + $oCase->updateCase ( $_SESSION['APPLICATION'], $Fields ); + //Save data - End + + //Obtain previous and next step - Start + try { + $oCase = new Cases(); + $aNextStep = $oCase->getNextStep( $_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); + $aPreviousStep = $oCase->getPreviousStep($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['STEP_POSITION']); + } + catch ( Exception $e ) { + } + //Obtain previous and next step - End + + try { + //Add content content step - Start + $array['APP_NUMBER'] = $APP_NUMBER; + $array['APP_TITLE'] = $APP_TITLE; + $array['CASE'] = G::LoadTranslation('ID_CASE'); + $array['TITLE'] = G::LoadTranslation('ID_TITLE'); + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $array); + + switch ($_GET['TYPE']) + { + case 'DYNAFORM': + if (!$aPreviousStep) { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + } + else { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = $aPreviousStep['PAGE']; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = $aNextStep['PAGE']; + + $oStep = new Step(); + $oStep = $oStep->loadByProcessTaskPosition($_SESSION['PROCESS'], $_SESSION['TASK'], $_GET['POSITION']); + + /** Added By erik 16-05-08 + * Description: this was added for the additional database connections */ + G::LoadClass ('dbConnections'); + $oDbConnections = new dbConnections(NULL); + $oDbConnections->loadAdditionalConnections(); + $_SESSION['CURRENT_DYN_UID'] = $_GET['UID']; + + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS']. '/' . $_GET['UID'], '', $Fields['APP_DATA'], 'cases_SaveData?UID=' . $_GET['UID'], '', (strtolower($oStep->getStepMode()) != 'edit' ? strtolower($oStep->getStepMode()) : '')); + break; + + case 'INPUT_DOCUMENT': + $oInputDocument = new InputDocument(); + $Fields = $oInputDocument->load($_GET['UID']); + if (!$aPreviousStep) { + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + $Fields['PREVIOUS_STEP_LABEL'] = ''; + } + else { + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = $aPreviousStep['PAGE']; + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + + $Fields['PREVIOUS_STEP'] = $aPreviousStep['PAGE']; + $Fields['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + $Fields['NEXT_STEP'] = $aNextStep['PAGE']; + $Fields['NEXT_STEP_LABEL'] = G::loadTranslation("ID_NEXT_STEP"); + switch ($_GET['ACTION']) + { + case 'ATTACH': + switch ($Fields['INP_DOC_FORM_NEEDED']) { + case 'REAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_NEW'); + $sXmlForm = 'cases/cases_AttachInputDocument2'; + break; + case 'VIRTUAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_ATTACH'); + $sXmlForm = 'cases/cases_AttachInputDocument1'; + break; + case 'VREAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_ATTACH'); + $sXmlForm = 'cases/cases_AttachInputDocument3'; + break; + } + $Fields['MESSAGE1'] = G::LoadTranslation('ID_PLEASE_ENTER_COMMENTS'); + $Fields['MESSAGE2'] = G::LoadTranslation('ID_PLEASE_SELECT_FILE'); + //START: If there is a Break Step registered from Plugin Similar as a Trigger debug + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT_BEFORE ) ) {//If a Plugin has registered a Break Page Evaluator + $oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT_BEFORE , array('USR_UID'=>$_SESSION['USER_LOGGED']) ); + } + //END: If there is a Break Step registered from Plugin + + $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-inputDocuments', 'cases/cases_InputdocsList', $oCase->getInputDocumentsCriteria($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_GET['UID']), array_merge(array('DOC_UID'=>$_GET['UID']),$Fields));//$aFields + + //call plugin + //if ( $oPluginRegistry->existsTrigger ( PM_CASE_DOCUMENT_LIST ) ) { + // $folderData = new folderData (null, null, $_SESSION['APPLICATION'], null, $_SESSION['USER_LOGGED'] ); + // $oPluginRegistry =& PMPluginRegistry::getSingleton(); + // $oPluginRegistry->executeTriggers ( PM_CASE_DOCUMENT_LIST , $folderData ); + // //end plugin + //} + //else + // $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-inputDocuments', 'cases/cases_InputdocsList', $oCase->getInputDocumentsCriteria($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_GET['UID']), array_merge(array('DOC_UID'=>$_GET['UID']),$Fields));//$aFields + + $oHeadPublisher =& headPublisher::getSingleton(); + $titleDocument="<h3>".$Fields['INP_DOC_TITLE']."<br><small>".G::LoadTranslation('ID_INPUT_DOCUMENT')."</small></h3>"; + if($Fields['INP_DOC_DESCRIPTION']) $titleDocument.= " ".str_replace("\n","",str_replace("'","\'",nl2br(htmlentities(utf8_decode($Fields['INP_DOC_DESCRIPTION']))))).""; + + $oHeadPublisher->addScriptCode("documentName='{$titleDocument}';"); + break; + + case 'VIEW': + require_once 'classes/model/AppDocument.php'; + require_once 'classes/model/Users.php'; + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_GET['DOC'],$_GET['VERSION']); + $Fields['POSITION'] = $_SESSION['STEP_POSITION']; + $oUser = new Users(); + $aUser = $oUser->load($oAppDocument->Fields['USR_UID']); + $Fields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + switch ($Fields['INP_DOC_FORM_NEEDED']) + { + case 'REAL': + $sXmlForm = 'cases/cases_ViewInputDocument2'; + break; + case 'VIRTUAL': + $sXmlForm = 'cases/cases_ViewInputDocument1'; + break; + case 'VREAL': + $sXmlForm = 'cases/cases_ViewInputDocument3'; + break; + } + $oAppDocument->Fields['VIEW'] = G::LoadTranslation('ID_OPEN'); + $oAppDocument->Fields['FILE'] = 'cases_ShowDocument?a=' . $_GET['DOC'] . '&r=' . rand(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', G::array_merges($Fields, $oAppDocument->Fields), ''); + break; + } + break; + + case 'OUTPUT_DOCUMENT': + require_once 'classes/model/OutputDocument.php'; + $oOutputDocument = new OutputDocument(); + $aOD = $oOutputDocument->load( $_GET['UID'] ); + + if (!$aPreviousStep) { + $aOD['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + } + else { + $aOD['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = $aPreviousStep['PAGE']; + $aOD['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + $aOD['__DYNAFORM_OPTIONS']['NEXT_STEP'] = $aNextStep['PAGE']; + + switch ($_GET['ACTION']) + { + case 'GENERATE': + //START: If there is a Break Step registered from Plugin Similar as a Trigger debug + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT_BEFORE ) ) {//If a Plugin has registered a Break Page Evaluator + $oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT_BEFORE , array('USR_UID'=>$_SESSION['USER_LOGGED'],'DOC_UID'=>$_GET['UID'],'PRO_UID'=>$_SESSION['PROCESS']) ); + } + //END: If there is a Break Step registered from Plugin + + $sFilename = ereg_replace('[^A-Za-z0-9_]', '_', G::replaceDataField($aOD['OUT_DOC_FILENAME'], $Fields['APP_DATA'])); + if ( $sFilename == '' ) $sFilename='_'; + $pathOutput = PATH_DOCUMENT . $_SESSION['APPLICATION'] . PATH_SEP . 'outdocs'. PATH_SEP ; + G::mk_dir ( $pathOutput ); + switch ( $aOD['OUT_DOC_TYPE'] ) { + case 'HTML' : + $aProperties = array(); //maui + + if(!isset($aOD['OUT_DOC_MEDIA'])) + $aOD['OUT_DOC_MEDIA'] = 'Letter'; + if(!isset($aOD['OUT_DOC_LEFT_MARGIN'])) + $aOD['OUT_DOC_LEFT_MARGIN'] = '15'; + if(!isset($aOD['OUT_DOC_RIGHT_MARGIN'])) + $aOD['OUT_DOC_RIGHT_MARGIN'] = '15'; + if(!isset($aOD['OUT_DOC_TOP_MARGIN'])) + $aOD['OUT_DOC_TOP_MARGIN'] = '15'; + if(!isset($aOD['OUT_DOC_BOTTOM_MARGIN'])) + $aOD['OUT_DOC_BOTTOM_MARGIN'] = '15'; + + if(isset($aOD['OUT_DOC_VERSIONING']) && $aOD['OUT_DOC_VERSIONING']!=0){ + $oAppDocument= new AppDocument(); + $lastDocVersion=$oAppDocument->getLastDocVersion($_GET['UID'],$_SESSION['APPLICATION']); + $lastDocVersion = $lastDocVersion +1; + $lastDocVersion = '_'.$lastDocVersion; + }else { + $lastDocVersion=''; + } + + $aProperties['media']=$aOD['OUT_DOC_MEDIA']; + $aProperties['margins']=array('left' => $aOD['OUT_DOC_LEFT_MARGIN'], 'right' => $aOD['OUT_DOC_RIGHT_MARGIN'], 'top' => $aOD['OUT_DOC_TOP_MARGIN'], 'bottom' => $aOD['OUT_DOC_BOTTOM_MARGIN'],); + $oOutputDocument->generate( $_GET['UID'], $Fields['APP_DATA'], $pathOutput, + $sFilename.$lastDocVersion, $aOD['OUT_DOC_TEMPLATE'], (boolean)$aOD['OUT_DOC_LANDSCAPE'], $aOD['OUT_DOC_GENERATE'],$aProperties ); + break; + case 'JRXML' : + //creating the xml with the application data; + $xmlData = "<dynaform>\n"; + foreach ( $Fields['APP_DATA'] as $key => $val ) { + $xmlData .= " <$key>$val</$key>\n"; + } + $xmlData .= "</dynaform>\n"; + $iSize = file_put_contents ( $javaOutput . 'addressBook.xml' , $xmlData ); + + G::LoadClass ('javaBridgePM'); + $JBPM = new JavaBridgePM(); + $JBPM->checkJavaExtension(); + + $util = new Java("com.processmaker.util.pmutils"); + $util->setInputPath( $javaInput ); + $util->setOutputPath( $javaOutput ); + + //$content = file_get_contents ( PATH_DYNAFORM . $aOD['PRO_UID'] . PATH_SEP . $aOD['OUT_DOC_UID'] . '.jrxml' ); + //$iSize = file_put_contents ( $javaInput . $aOD['OUT_DOC_UID'] . '.jrxml', $content ); + copy ( PATH_DYNAFORM . $aOD['PRO_UID'] . PATH_SEP . $aOD['OUT_DOC_UID'] . '.jrxml', $javaInput . $aOD['OUT_DOC_UID'] . '.jrxml' ); + + $outputFile = $javaOutput . $sFilename . '.pdf' ; + print $util->jrxml2pdf( $aOD['OUT_DOC_UID'] . '.jrxml' , basename($outputFile) ); + + //$content = file_get_contents ( $outputFile ); + //$iSize = file_put_contents ( $pathOutput . $sFilename . '.pdf' , $content ); + copy ( $outputFile, $pathOutput . $sFilename . '.pdf' ); + //die; + break; + case 'ACROFORM' : + //creating the xml with the application data; + $xmlData = "<dynaform>\n"; + foreach ( $Fields['APP_DATA'] as $key => $val ) { + $xmlData .= " <$key>$val</$key>\n"; + } + $xmlData .= "</dynaform>\n"; + //$iSize = file_put_contents ( $javaOutput . 'addressBook.xml' , $xmlData ); + + G::LoadClass ('javaBridgePM'); + $JBPM = new JavaBridgePM(); + $JBPM->checkJavaExtension(); + + $util = new Java("com.processmaker.util.pmutils"); + $util->setInputPath( $javaInput ); + $util->setOutputPath( $javaOutput ); + + copy ( PATH_DYNAFORM . $aOD['PRO_UID'] . PATH_SEP . $aOD['OUT_DOC_UID'] . '.pdf', $javaInput . $aOD['OUT_DOC_UID'] . '.pdf' ); + + $outputFile = $javaOutput . $sFilename . '.pdf' ; + print $util->writeVarsToAcroFields( $aOD['OUT_DOC_UID'] . '.pdf' , $xmlData ); + + copy ( $javaOutput. $aOD['OUT_DOC_UID'] . '.pdf', $pathOutput . $sFilename . '.pdf' ); + + break; + default : + throw ( new Exception ('invalid output document' )); + } + + require_once 'classes/model/AppFolder.php'; + require_once 'classes/model/AppDocument.php'; + + //Get the Custom Folder ID (create if necessary) + $oFolder=new AppFolder(); + $folderId=$oFolder->createFromPath($aOD['OUT_DOC_DESTINATION_PATH']); + + //Tags + $fileTags=$oFolder->parseTags($aOD['OUT_DOC_TAGS']); + + //Get last Document Version and apply versioning if is enabled + + $oAppDocument= new AppDocument(); + $lastDocVersion=$oAppDocument->getLastDocVersion($_GET['UID'],$_SESSION['APPLICATION']); + + //if(($aOD['OUT_DOC_VERSIONING'])||($lastDocVersion==0)){ + // $lastDocVersion++; + //} + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDocumentPeer::APP_UID, $_SESSION['APPLICATION']); + //$oCriteria->add(AppDocumentPeer::DEL_INDEX, $_SESSION['INDEX']); + $oCriteria->add(AppDocumentPeer::DOC_UID, $_GET['UID']); + $oCriteria->add(AppDocumentPeer::DOC_VERSION, $lastDocVersion); + $oCriteria->add(AppDocumentPeer::APP_DOC_TYPE, 'OUTPUT'); + $oDataset = AppDocumentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + if(($aOD['OUT_DOC_VERSIONING'])&&($lastDocVersion!=0)){//Create new Version of current output + if ($aRow = $oDataset->getRow()) { + $aFields = array('APP_DOC_UID' => $aRow['APP_DOC_UID'], + 'APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX'], + 'DOC_UID' => $_GET['UID'], + 'DOC_VERSION' => $lastDocVersion+1, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'APP_DOC_TYPE' => 'OUTPUT', + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_FILENAME' => $sFilename, + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + $oAppDocument = new AppDocument(); + $oAppDocument->create($aFields); + $sDocUID = $aRow['APP_DOC_UID']; + } + }else{//No versioning so Update a current Output or Create new if no exist + if ($aRow = $oDataset->getRow()) { //Update + $aFields = array('APP_DOC_UID' => $aRow['APP_DOC_UID'], + 'APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX'], + 'DOC_UID' => $_GET['UID'], + 'DOC_VERSION' => $lastDocVersion, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'APP_DOC_TYPE' => 'OUTPUT', + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_FILENAME' => $sFilename, + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + $oAppDocument = new AppDocument(); + $oAppDocument->update($aFields); + $sDocUID = $aRow['APP_DOC_UID']; + }else{ //create + if($lastDocVersion==0) $lastDocVersion++; + $aFields = array('APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX'], + 'DOC_UID' => $_GET['UID'], + 'DOC_VERSION' => $lastDocVersion, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'APP_DOC_TYPE' => 'OUTPUT', + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_FILENAME' => $sFilename, + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags); + $oAppDocument = new AppDocument(); + $aFields['APP_DOC_UID']=$sDocUID = $oAppDocument->create($aFields); + + } + } + + //Execute after triggers - Start + $Fields['APP_DATA'] = $oCase->ExecuteTriggers ( $_SESSION['TASK'], 'OUTPUT_DOCUMENT', $_GET['UID'], 'AFTER', $Fields['APP_DATA'] ); + $Fields['DEL_INDEX']= $_SESSION['INDEX']; + $Fields['TAS_UID'] = $_SESSION['TASK']; + //Execute after triggers - End + + //Save data - Start + $oCase->updateCase ( $_SESSION['APPLICATION'], $Fields ); + //Save data - End + + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT ) && class_exists ('uploadDocumentData' ) ) { + $triggerDetail=$oPluginRegistry->getTriggerInfo( PM_UPLOAD_DOCUMENT ); + $aFields['APP_DOC_PLUGIN']=$triggerDetail->sNamespace; + + $oAppDocument1 = new AppDocument(); + $oAppDocument1->update($aFields); + + $sPathName = PATH_DOCUMENT . $_SESSION['APPLICATION'] . PATH_SEP; + + $oData['APP_UID'] = $_SESSION['APPLICATION']; + $oData['ATTACHMENT_FOLDER'] = true; + switch($aOD['OUT_DOC_GENERATE']){ + case "BOTH": + $documentData = new uploadDocumentData ( + $_SESSION['APPLICATION'], + $_SESSION['USER_LOGGED'], + $pathOutput . $sFilename . '.pdf', + $sFilename. '.pdf', + $sDocUID, + $oAppDocument->getDocVersion() + ); + + $documentData->sFileType = "PDF"; + $documentData->bUseOutputFolder = true; + $uploadReturn=$oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + if($uploadReturn){//Only delete if the file was saved correctly + unlink ( $pathOutput . $sFilename. '.pdf' ); + } + + + + $documentData = new uploadDocumentData ( + $_SESSION['APPLICATION'], + $_SESSION['USER_LOGGED'], + $pathOutput . $sFilename . '.doc', + $sFilename. '.doc', + $sDocUID, + $oAppDocument->getDocVersion() + ); + + $documentData->sFileType = "DOC"; + $documentData->bUseOutputFolder = true; + $uploadReturn=$oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + if($uploadReturn){//Only delete if the file was saved correctly + unlink ( $pathOutput . $sFilename. '.doc' ); + } + + break; + case "PDF": + $documentData = new uploadDocumentData ( + $_SESSION['APPLICATION'], + $_SESSION['USER_LOGGED'], + $pathOutput . $sFilename . '.pdf', + $sFilename. '.pdf', + $sDocUID, + $oAppDocument->getDocVersion() + ); + + + $documentData->sFileType = "PDF"; + $documentData->bUseOutputFolder = true; + $uploadReturn=$oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + if($uploadReturn){//Only delete if the file was saved correctly + unlink ( $pathOutput . $sFilename. '.pdf' ); + } + break; + case "DOC": + $documentData = new uploadDocumentData ( + $_SESSION['APPLICATION'], + $_SESSION['USER_LOGGED'], + $pathOutput . $sFilename . '.doc', + $sFilename. '.doc', + $sDocUID, + $oAppDocument->getDocVersion() + ); + + $documentData->sFileType = "DOC"; + $documentData->bUseOutputFolder = true; + $uploadReturn=$oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + if($uploadReturn){//Only delete if the file was saved correctly + unlink ( $pathOutput . $sFilename. '.doc' ); + } + break; + } + + } + + $outputNextStep = 'cases_Step?TYPE=OUTPUT_DOCUMENT&UID=' . $_GET['UID'] . '&POSITION=' . $_SESSION['STEP_POSITION'] . '&ACTION=VIEW&DOC=' . $sDocUID; + G::header('location: '.$outputNextStep); + die; + break; + case 'VIEW': + require_once 'classes/model/AppDocument.php'; + $oAppDocument = new AppDocument(); + $lastVersion=$oAppDocument->getLastAppDocVersion($_GET['DOC'],$_SESSION['APPLICATION']); + $aFields = $oAppDocument->load($_GET['DOC'],$lastVersion); + $listing=false; + $oPluginRegistry = & PMPluginRegistry::getSingleton(); + if($oPluginRegistry->existsTrigger(PM_CASE_DOCUMENT_LIST)) { + $folderData = new folderData(null, null, $_SESSION['APPLICATION'], null, $_SESSION['USER_LOGGED']); + $folderData->PMType = "OUTPUT"; + $folderData->returnList = true; + $listing=$oPluginRegistry->executeTriggers(PM_CASE_DOCUMENT_LIST, $folderData); + } + + + require_once 'classes/model/OutputDocument.php'; + $oOutputDocument = new OutputDocument(); + $aGields = $oOutputDocument->load($aFields['DOC_UID']); + + if(isset($aGields['OUT_DOC_VERSIONING']) && $aGields['OUT_DOC_VERSIONING']!=0){ + $oAppDocument= new AppDocument(); + $lastDocVersion=$oAppDocument->getLastDocVersion($_GET['UID'],$_SESSION['APPLICATION']); + }else { + $lastDocVersion=''; + } + $aFields['VIEW1'] = G::LoadTranslation('ID_OPEN'); + + $aFields['VIEW2'] = G::LoadTranslation('ID_OPEN'); + + $aFields['FILE1'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&v='.$lastDocVersion . '&ext=doc&random=' . rand(); + + $aFields['FILE2'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&v='.$lastDocVersion . '&ext=pdf&random=' . rand(); + + + if ( is_array ($listing) ){//If exist in Plugin Document List + foreach($listing as $folderitem) { + if(($folderitem->filename==$aFields['APP_DOC_UID'])&&($folderitem->type=='DOC')){ + $aFields['VIEW1'] = G::LoadTranslation('ID_GET_EXTERNAL_FILE'); + $aFields['FILE1'] = $folderitem->downloadScript; + continue; + } + if(($folderitem->filename==$aFields['APP_DOC_UID'])&&($folderitem->type=='PDF')){ + $aFields['VIEW2'] = G::LoadTranslation('ID_GET_EXTERNAL_FILE'); + $aFields['FILE2'] = $folderitem->downloadScript; + continue; + } + } + } + + if(($aGields['OUT_DOC_GENERATE']=='BOTH')||($aGields['OUT_DOC_GENERATE']=='')) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewOutputDocument1', '', G::array_merges($aOD, $aFields), ''); + + if($aGields['OUT_DOC_GENERATE']=='DOC') + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewOutputDocument2', '', G::array_merges($aOD, $aFields), ''); + + if($aGields['OUT_DOC_GENERATE']=='PDF') + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewOutputDocument3', '', G::array_merges($aOD, $aFields), ''); + + + break; + } + break; + + case 'ASSIGN_TASK': + $oDerivation = new Derivation(); + //$oProcess = new Process(); //optimized for speed, we already load process row + $aData = $oCase->loadCase($_SESSION['APPLICATION']); + //$aFields['PROCESS'] = $oProcess->load($_SESSION['PROCESS']); + $aFields['PROCESS'] = $oProcessFields; + $aFields['PREVIOUS_PAGE'] = $aPreviousStep['PAGE']; + $aFields['PREVIOUS_PAGE_LABEL'] = G::LoadTranslation('ID_PREVIOUS_STEP'); + $aFields['ASSIGN_TASK'] = G::LoadTranslation('ID_ASSIGN_TASK'); + $aFields['END_OF_PROCESS'] = G::LoadTranslation('ID_END_OF_PROCESS'); + $aFields['NEXT_TASK_LABEL'] = G::LoadTranslation('ID_NEXT_TASK'); + $aFields['EMPLOYEE'] = G::LoadTranslation('ID_EMPLOYEE'); + $aFields['LAST_EMPLOYEE'] = G::LoadTranslation('ID_LAST_EMPLOYEE'); + $aFields['OPTION_LABEL'] = G::LoadTranslation('ID_OPTION'); + $aFields['CONTINUE'] = G::LoadTranslation('ID_CONTINUE'); + $aFields['CONTINUE_WITH_OPTION'] = G::LoadTranslation('ID_CONTINUE_WITH_OPTION'); + $aFields['FINISH_WITH_OPTION'] = G::LoadTranslation('ID_FINISH_WITH_OPTION'); + $aFields['TASK'] = $oDerivation->prepareInformation( + array( 'USER_UID' => $_SESSION['USER_LOGGED'], + 'APP_UID' => $_SESSION['APPLICATION'], + 'DEL_INDEX' => $_SESSION['INDEX']) + ); + if ( empty($aFields['TASK']) ) { + throw ( new Exception ( G::LoadTranslation ( 'ID_NO_DERIVATION_RULE') ) ); + } + //take the first derivation rule as the task derivation rule type. + $aFields['PROCESS']['ROU_TYPE'] = $aFields['TASK'][1]['ROU_TYPE']; + $aFields['PROCESS']['ROU_FINISH_FLAG'] = false; + + foreach ( $aFields['TASK'] as $sKey => &$aValues) + { + $sPriority = '';//set priority value + if ($aFields['TASK'][$sKey]['NEXT_TASK']['TAS_PRIORITY_VARIABLE'] != '') { + //TO DO: review this type of assignment + if (isset($aData['APP_DATA'][str_replace('@@', '', $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_PRIORITY_VARIABLE'])])) + { + $sPriority = $aData['APP_DATA'][str_replace('@@', '', $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_PRIORITY_VARIABLE'])]; + } + }//set priority value + + $sTask = $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_UID']; + + //TAS_UID has a hidden field to store the TAS_UID + $hiddenName = "form[TASKS][" . $sKey . "][TAS_UID]"; + $hiddenField = '<input type="hidden" name="' . $hiddenName . '" id="' . $hiddenName . '" value="' . $aValues['NEXT_TASK']['TAS_UID'] . '">'; + $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_HIDDEN_FIELD'] = $hiddenField; + //print "<hr>".$aValues['NEXT_TASK']['TAS_ASSIGN_TYPE']."<hr>"; + switch ($aValues['NEXT_TASK']['TAS_ASSIGN_TYPE']) { + case 'EVALUATE': + case 'REPORT_TO': + case 'BALANCED': + case 'SELF_SERVICE': + $hiddenName = "form[TASKS][" . $sKey . "][USR_UID]"; + $aFields['TASK'][$sKey]['NEXT_TASK']['USR_UID'] = $aFields['TASK'][$sKey]['NEXT_TASK']['USER_ASSIGNED']['USR_FULLNAME']; + $aFields['TASK'][$sKey]['NEXT_TASK']['USR_HIDDEN_FIELD'] = '<input type="hidden" name="' . $hiddenName . '" id="' . $hiddenName . '" value="' . $aValues['NEXT_TASK']['USER_ASSIGNED']['USR_UID'] . '">'; + + //there is a error with reportsTo, when the USR_UID is empty means there are no manager for this user, so we are disabling buttons + //but this validation is not for SELF_SERVICE + if ( $aValues['NEXT_TASK']['TAS_ASSIGN_TYPE'] != 'SELF_SERVICE' ) + if ( $aFields['TASK'][$sKey]['NEXT_TASK']['USER_ASSIGNED']['USR_UID'] == '' ) + $aFields['PROCESS']['ERROR'] = $aFields['TASK'][$sKey]['NEXT_TASK']['USER_ASSIGNED']['USR_FULLNAME']; + break; + case 'MANUAL': + $Aux = array(); + foreach ($aValues['NEXT_TASK']['USER_ASSIGNED'] as $aUser) + { + $Aux[$aUser['USR_UID']] = $aUser['USR_FULLNAME']; + } + asort($Aux); + $sAux = '<select name="form[TASKS][' . $sKey . '][USR_UID]" id="form[TASKS][' . $sKey . '][USR_UID]">'; + $sAux .= '<option value="" enabled>'.G::LoadTranslation('ID_SELECT').'</option>'; + foreach ($Aux as $key => $value) + { + $sAux .= '<option value="' . $key . '">' . $value . '</option>'; + } + $sAux .= '</select>'; + + $aFields['TASK'][$sKey]['NEXT_TASK']['USR_UID'] = $sAux; + break; + case '': //when this task is the Finish process + $userFields = $oDerivation->getUsersFullNameFromArray ( $aFields['TASK'][$sKey]['USER_UID'] ); + $aFields['TASK'][$sKey]['NEXT_TASK']['USR_UID'] = $userFields['USR_FULLNAME']; + $aFields['TASK'][$sKey]['NEXT_TASK']['ROU_FINISH_FLAG'] = true; + $aFields['PROCESS']['ROU_FINISH_FLAG'] = true; + break; + } + $hiddenName = 'form[TASKS][' . $sKey . ']'; + $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_ASSIGN_TYPE'] = '<input type="hidden" name="' . $hiddenName . '[TAS_ASSIGN_TYPE]" id="' . $hiddenName . '[TAS_ASSIGN_TYPE]" value="' . $aValues['NEXT_TASK']['TAS_ASSIGN_TYPE'] . '">'; + if (isset ($aValues['NEXT_TASK']['TAS_DEF_PROC_CODE'])){ + $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_DEF_PROC_CODE'] = '<input type="hidden" name="' . $hiddenName . '[TAS_DEF_PROC_CODE]" id="' . $hiddenName . '[TAS_DEF_PROC_CODE]" value="' . $aValues['NEXT_TASK']['TAS_DEF_PROC_CODE'] . '">'; + } else { + $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_DEF_PROC_CODE'] = '<input type="hidden" name="' . $hiddenName . '[TAS_DEF_PROC_CODE]" id="' . $hiddenName . '[TAS_DEF_PROC_CODE]" value="">'; + } + $aFields['TASK'][$sKey]['NEXT_TASK']['DEL_PRIORITY'] = '<input type="hidden" name="' . $hiddenName . '[DEL_PRIORITY]" id="' . $hiddenName . '[DEL_PRIORITY]" value="' . $sPriority . '">'; + $aFields['TASK'][$sKey]['NEXT_TASK']['TAS_PARENT'] = '<input type="hidden" name="' . $hiddenName . '[TAS_PARENT]" id="' . $hiddenName . '[TAS_PARENT]" value="' . $aValues['NEXT_TASK']['TAS_PARENT'] . '">'; + } + + $aFields['PROCESSING_MESSAGE'] = G::loadTranslation('ID_PROCESSING'); + + $G_PUBLISH->AddContent('smarty', 'cases/cases_ScreenDerivation', '', '', $aFields); +/* + if (isset( $aFields['TASK'][1]['NEXT_TASK']['USER_ASSIGNED'])){ + if($aFields['TASK'][1]['NEXT_TASK']['USER_ASSIGNED']!="ERROR" && is_array($aFields['TASK'][1]['NEXT_TASK']['USER_ASSIGNED'])){ + $G_PUBLISH->AddContent('smarty', 'cases/cases_ScreenDerivation', '', '', $aFields); + } + else { + $sMessageError = "The current user does not have a valid Reports To user. Please contact administrator."; + //$aFields['TASK'][$sKey]['NEXT_TASK']['USR_HIDDEN_FIELD'] = '<input type="hidden" name="' . $hiddenName . '" id="' . $hiddenName . '" value="' . $sMessageError . '">'; + G::SendTemporalMessage ('UID_UNDEFINED_USER', "Error"); + $aFields['ERROR_REPORTSTO']= "Error"; + $aFields['MESSAGE_ERROR_REPORTSTO']=G::loadTranslation("ID_MSJ_REPORSTO");; + $G_PUBLISH->AddContent('smarty', 'cases/cases_ShowE_Reportsto', '', '', $aFields); + } + }else{ + $G_PUBLISH->AddContent('smarty', 'cases/cases_ScreenDerivation', '', '', $aFields); + } +*/ + break; + case 'EXTERNAL': + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $externalSteps = $oPluginRegistry->getSteps(); + + $sNamespace = ''; + $sStepName = ''; + foreach ( $externalSteps as $key=>$val ) { + if ( $val->sStepId == $_GET['UID'] ) { + $sNamespace = $val->sNamespace; + $sStepName = $val->sStepName; + } + } + if (!$aPreviousStep) { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + } + else { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = $aPreviousStep['PAGE']; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = $aNextStep['PAGE']; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP_LABEL'] = G::loadTranslation("ID_NEXT_STEP"); + + /** Added By erik date: 16-05-08 + * Description: this was added for the additional database connections */ + G::LoadClass ('dbConnections'); + $oDbConnections = new dbConnections(NULL); + $oDbConnections->loadAdditionalConnections(); + $stepFilename = "$sNamespace/$sStepName"; + $G_PUBLISH->AddContent('content', $stepFilename ); + break; + + } + //Add content content step - End + } + catch ( Exception $e ) { + G::SendTemporalMessage($e->getMessage(), 'error', 'string', 3, 100); + $aMessage = array(); + $aMessage['MESSAGE'] = G::LoadTranslation('ID_PROCESS_DEF_PROBLEM').'<br/>'.G::LoadTranslation('ID_CONTACT_ADMIN'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + die; + } + + /* Render page */ + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + var showSteps = function() + { + if (!Cse.panels.step) + { + Cse=new cases(); + Cse.options = { + target : "cases_target", + dataServer : "cases_Ajax?TYPE=' . (isset($_GET['TYPE']) ? $_GET['TYPE'] : '') . '&UID=' . (isset($_GET['UID']) ? $_GET['UID'] : '') . '&POSITION=' . (isset($_GET['POSITION']) ? $_GET['POSITION'] : '') . '&ACTION=' . (isset($_GET['ACTION']) ? $_GET['ACTION'] : '') . '&DOC=' . (isset($_GET['DOC']) ? $_GET['DOC'] : '') . '", + action : "steps", + title : "Steps", + lang : "' . SYS_LANG . '", + theme : "processmaker", + images_dir :leimnud.path_root + "cases/core/images/" + } + Cse.make(); + } + else + { + Cse.panels.step.elements.title.innerHTML = "Steps"; + Cse.panels.step.clearContent(); + Cse.panels.step.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: "cases_Ajax?TYPE=' . (isset($_GET['TYPE']) ? $_GET['TYPE'] : '') . '&UID=' . (isset($_GET['UID']) ? $_GET['UID'] : '') . '&POSITION=' . (isset($_GET['POSITION']) ? $_GET['POSITION'] : '') . '&ACTION=' . (isset($_GET['ACTION']) ? $_GET['ACTION'] : '') . '&DOC=' . (isset($_GET['DOC']) ? $_GET['DOC'] : '') . '", + args: "action=steps&showWindow=steps" + }); + oRPC.callback = function(rpc){ + Cse.panels.step.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + Cse.panels.step.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + }; + '); + + if( defined('SYS_SKIN') ) + $skin = SYS_SKIN; + else + $skin = "green"; + + G::RenderPage('publish', $skin . '-submenu'); + + if( $_SESSION['TRIGGER_DEBUG']['ISSET'] ){ + G::evalJScript('showdebug();'); + } + + diff --git a/workflow/engine/methods/cases/cases_StepToRevise.php b/workflow/engine/methods/cases/cases_StepToRevise.php new file mode 100644 index 000000000..126fcf191 --- /dev/null +++ b/workflow/engine/methods/cases/cases_StepToRevise.php @@ -0,0 +1,184 @@ +<?php +/** + * cases_Step.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +// die("first"); + /* Permissions */ + switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + if ((int)$_SESSION['INDEX'] < 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; + } + /* Includes */ + G::LoadClass('case'); + G::LoadClass('derivation'); + + /* GET , POST & $_SESSION Vars */ + //$_SESSION['STEP_POSITION'] = (int)$_GET['POSITION']; + + /* Menues */ + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + + + /* Prepare page before to show */ + $oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; + +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptCode(' + var Cse = {}; + Cse.panels = {}; + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.Package.Load("json",{Type:"file"}); + leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); + leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); + leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); + leimnud.exec(leimnud.fix.memoryLeak); + leimnud.event.add(window,"load",function(){ + '.(isset($_SESSION['showCasesWindow'])?'try{'.$_SESSION['showCasesWindow'].'}catch(e){}':'').' + }); + '); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + //die(); + if(!isset($_GET['type'])) $_GET['type'] = 'DYNAFORM'; + if(!isset($_GET['position'])) $_GET['position'] = 1; + + $_SESSION['STEP_POSITION'] = (int)$_GET['position']; + $oCase = new Cases(); + $Fields = $oCase->loadCase($_SESSION['APPLICATION']); + + + //Obtain previous and next step - Start + try { + $aNextStep = $oCase->getNextSupervisorStep($_SESSION['PROCESS'], $_SESSION['STEP_POSITION'], $_GET['type']); + $aPreviousStep = $oCase->getPreviousSupervisorStep($_SESSION['PROCESS'], $_SESSION['STEP_POSITION'], $_GET['type']); + } + catch (exception $e) { + + } + + if (!$aPreviousStep) { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + } else { + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = 'cases_StepToRevise?type=DYNAFORM&DYN_UID='.$aPreviousStep['UID'].'&position='.$aPreviousStep['POSITION'].'&APP_UID='.$_GET['APP_UID'].'&DEL_INDEX='.$_GET['DEL_INDEX']; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = 'cases_StepToRevise?type=DYNAFORM&DYN_UID='.$aNextStep['UID'].'&position='.$aNextStep['POSITION'].'&APP_UID='.$_GET['APP_UID'].'&DEL_INDEX='.$_GET['DEL_INDEX']; + + + /** Added By erik + * date: 16-05-08 + * Description: this was added for the additional database connections */ + G::LoadClass('dbConnections'); + $oDbConnections = new dbConnections($_SESSION['PROCESS']); + $oDbConnections->loadAdditionalConnections(); + + + $G_PUBLISH = new Publisher; + if ($_GET['DYN_UID'] != '') { + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS'] . '/' . $_GET['DYN_UID'], '', $Fields['APP_DATA'], 'cases_SaveDataSupervisor?UID='.$_GET['DYN_UID']); + } + + G::RenderPage('publish', 'blank'); + + if(!isset($_GET['ex'])) $_GET['ex']=$_GET['position']; +?> + +<script> +/*------------------------------ To Revise Routines ---------------------------*/ + +function setSelect() +{ + var ex=<?=$_GET['ex']?>; + try{ + for(i=1; i<50; i++) + { + if(i == ex){ + document.getElementById('focus'+i).innerHTML = '<img src="/images/bulletButton.gif" />'; + } + else{ + document.getElementById('focus'+i).innerHTML = ''; + } + } + } catch (e){ + return 0; + } +} + +function toRevisePanel(APP_UID,DEL_INDEX) +{ + + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:250,h:450}, + position:{x:0,y:0}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,close:false,drag:true}, + fx :{modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + method:'post', + args: 'action=toRevisePanel&APP_UID='+APP_UID+'&DEL_INDEX='+DEL_INDEX + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + setSelect(); + + }.extend(this); + oRPC.make(); +} + +toRevisePanel('<?=$_GET['APP_UID']?>','<?=$_GET['DEL_INDEX']?>'); +</script> + + diff --git a/workflow/engine/methods/cases/cases_StepToReviseInputs.php b/workflow/engine/methods/cases/cases_StepToReviseInputs.php new file mode 100644 index 000000000..112fa016d --- /dev/null +++ b/workflow/engine/methods/cases/cases_StepToReviseInputs.php @@ -0,0 +1,199 @@ +<?php +/** + * cases_Step.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +//die("second"); +/* Permissions */ +switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +if ((int)$_SESSION['INDEX'] < 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; +} +/* Includes */ +G::LoadClass('case'); +G::LoadClass('derivation'); + +/* GET , POST & $_SESSION Vars */ +//$_SESSION['STEP_POSITION'] = (int)$_GET['POSITION']; + +/* Menues */ +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + + + /* Prepare page before to show */ + $oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptCode(' + var Cse = {}; + Cse.panels = {}; + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.Package.Load("json",{Type:"file"}); + leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); + leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); + leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); + leimnud.exec(leimnud.fix.memoryLeak); + leimnud.event.add(window,"load",function(){ + '.(isset($_SESSION['showCasesWindow'])?'try{'.$_SESSION['showCasesWindow'].'}catch(e){}':'').' +}); + '); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + +if(!isset($_GET['position'])) $_GET['position'] = 1; + +$_SESSION['STEP_POSITION'] = (int)$_GET['position']; +$oCase = new Cases(); +$Fields = $oCase->loadCase($_SESSION['APPLICATION']); + +$G_PUBLISH = new Publisher; + +if(!isset($_GET['ex'])) $_GET['ex']=0; + +if (!isset($_GET['INP_DOC_UID'])) { + G::LoadClass('case'); + $oCase = new Cases(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_InputdocsListToRevise', $oCase->getInputDocumentsCriteriaToRevise($_SESSION['APPLICATION']), ''); +} +else { + $oInputDocument = new InputDocument(); + $Fields = $oInputDocument->load($_GET['INP_DOC_UID']); + //Obtain previous and next step - Start + try { + $aNextStep = $oCase->getNextSupervisorStep($_SESSION['PROCESS'], $_SESSION['STEP_POSITION'], $_GET['type']); + $aPreviousStep = $oCase->getPreviousSupervisorStep($_SESSION['PROCESS'], $_SESSION['STEP_POSITION'], $_GET['type']); + if (!$aPreviousStep) { + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + } + else { + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP'] = 'cases_StepToReviseInputs?type=INPUT_DOCUMENT&INP_DOC_UID='.$aNextStep['UID'].'&position='.$aNextStep['POSITION'].'&APP_UID='.$_GET['APP_UID'].'&DEL_INDEX='.$_GET['DEL_INDEX']; + $Fields['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = G::loadTranslation("ID_PREVIOUS_STEP"); + } + $Fields['__DYNAFORM_OPTIONS']['NEXT_STEP'] = 'cases_StepToReviseInputs?type=INPUT_DOCUMENT&INP_DOC_UID='.$aNextStep['UID'].'&position='.$aNextStep['POSITION'].'&APP_UID='.$_GET['APP_UID'].'&DEL_INDEX='.$_GET['DEL_INDEX']; + } + catch (exception $e) { + + } + + switch ($Fields['INP_DOC_FORM_NEEDED']) { + case 'REAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_NEW'); + $sXmlForm = 'cases/cases_AttachInputDocument2'; + break; + case 'VIRTUAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_ATTACH'); + $sXmlForm = 'cases/cases_AttachInputDocument1'; + break; + case 'VREAL': + $Fields['TYPE_LABEL'] = G::LoadTranslation('ID_ATTACH'); + $sXmlForm = 'cases/cases_AttachInputDocument3'; + break; + } + $Fields['MESSAGE1'] = G::LoadTranslation('ID_PLEASE_ENTER_COMMENTS'); + $Fields['MESSAGE2'] = G::LoadTranslation('ID_PLEASE_SELECT_FILE'); + $docName = $Fields['INP_DOC_TITLE']; + $Fields['NEXT_STEP_LABEL'] = G::loadtranslation('ID_NEXT_STEP'); + $Fields['PREVIOUS_STEP_LABEL'] = G::loadtranslation('ID_PREVIOUS_STEP'); + $oHeadPublisher->addScriptCode('var documentName=\'Reviewing Input Document<br>'.$docName.'\';'); +// $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', $Fields, 'cases_SupervisorSaveDocument?UID=' . $_GET['INP_DOC_UID'] . '&APP_UID=' . $_GET['APP_UID'] . '&position=' . $_GET['position']); + $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-inputDocuments', 'cases/cases_ToReviseInputdocsList', $oCase->getInputDocumentsCriteria($_SESSION['APPLICATION'], $_SESSION['INDEX'], $_GET['INP_DOC_UID']), array_merge(array('DOC_UID'=>$_GET['INP_DOC_UID']),$Fields));//$aFields +// $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-inputDocuments', 'cases/cases_InputdocsList', $oCase->getInputDocumentsCriteria($_SESSION['APPLICATION']));//$aFields +} + +G::RenderPage('publish', 'blank'); + +?> + +<script> +/*------------------------------ To Revise Routines ---------------------------*/ +function setSelect() +{ + var ex=<?=$_GET['ex']?>; + + try{ + for(i=1; i<50; i++) + { + if(i == ex){ + document.getElementById('focus'+i).innerHTML = '<img src="/images/bulletButton.gif" />'; + } + else{ + document.getElementById('focus'+i).innerHTML = ''; + } + } + } catch (e){ + return 0; + } +} + +function toRevisePanel(APP_UID,DEL_INDEX) +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:250,h:450}, + position:{x:0,y:0}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,close:false,drag:true}, + fx :{modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + method:'post', + args: 'action=toRevisePanel&APP_UID='+APP_UID+'&DEL_INDEX='+DEL_INDEX + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + //setSelect(); + + }.extend(this); + oRPC.make(); +} + +toRevisePanel('<?=$_GET['APP_UID']?>','<?=$_GET['DEL_INDEX']?>'); +</script> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_StepToReviseOutputs.php b/workflow/engine/methods/cases/cases_StepToReviseOutputs.php new file mode 100644 index 000000000..0d71e420f --- /dev/null +++ b/workflow/engine/methods/cases/cases_StepToReviseOutputs.php @@ -0,0 +1,130 @@ +<?php +/** + * cases_StepToReviseOutputs.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* Permissions */ +switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('case'); + +/* Menues */ +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + + +/* Prepare page before to show */ +$oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html'); +$oTemplatePower->prepare(); +$G_PUBLISH = new Publisher; +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptCode(' +var Cse = {}; +Cse.panels = {}; +var leimnud = new maborak(); +leimnud.make(); +leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); +leimnud.Package.Load("json",{Type:"file"}); +leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); +leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); +leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); +leimnud.exec(leimnud.fix.memoryLeak); +leimnud.event.add(window,"load",function(){ + '.(isset($_SESSION['showCasesWindow'])?'try{'.$_SESSION['showCasesWindow'].'}catch(e){}':'').'}); +'); +$G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); +$oCase = new Cases(); +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_OutputdocsListToRevise', $oCase->getOutputDocumentsCriteriaToRevise($_SESSION['APPLICATION']), ''); +G::RenderPage('publish', 'blank'); + +if(!isset($_GET['ex'])) $_GET['ex']=0; + +?> +<script type="text/javascript"> +/*------------------------------ To Revise Routines ---------------------------*/ +function setSelect() +{ + var ex=<?=$_GET['ex']?>; + + try{ + for(i=1; i<50; i++) + { + if(i == ex){ + document.getElementById('focus'+i).innerHTML = '<img src="/images/bulletButton.gif" />'; + } + else{ + document.getElementById('focus'+i).innerHTML = ''; + } + } + } catch (e){ + return 0; + } +} +function toRevisePanel(APP_UID,DEL_INDEX) +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:250,h:450}, + position:{x:0,y:0}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,close:false,drag:true}, + fx :{modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + method:'post', + args: 'action=toRevisePanel&APP_UID='+APP_UID+'&DEL_INDEX='+DEL_INDEX + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + setSelect(); + + }.extend(this); + oRPC.make(); +} + +toRevisePanel('<?=$_GET['APP_UID']?>','<?=$_GET['DEL_INDEX']?>'); +</script> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_SupervisorSaveDocument.php b/workflow/engine/methods/cases/cases_SupervisorSaveDocument.php new file mode 100644 index 000000000..f3d6c2282 --- /dev/null +++ b/workflow/engine/methods/cases/cases_SupervisorSaveDocument.php @@ -0,0 +1,86 @@ +<? +/** + * cases_SupervisorSaveDocument.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + try { + //save info + G::LoadClass('case'); + + $oAppDocument = new AppDocument(); + $aFields = array('APP_UID' => $_GET['APP_UID'], + 'DEL_INDEX' => 100000, + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'DOC_UID' => $_GET['UID'], + 'APP_DOC_TYPE' => $_POST['form']['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['form']['APP_DOC_COMMENT']) ? $_POST['form']['APP_DOC_COMMENT'] : '', + 'APP_DOC_TITLE' => '', + 'APP_DOC_FILENAME' => isset($_FILES['form']['name']['APP_DOC_FILENAME']) ? $_FILES['form']['name']['APP_DOC_FILENAME'] : ''); + $oAppDocument->create($aFields); + $sAppDocUid = $oAppDocument->getAppDocUid(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + $ext = (isset($info['extension']) ? $info['extension'] : ''); + //save the file + if (!empty($_FILES['form'])) { + if ($_FILES['form']['error']['APP_DOC_FILENAME'] == 0) { + $sPathName = PATH_DOCUMENT . $_GET['APP_UID'] . PATH_SEP; + $sFileName = $sAppDocUid . '.' . $ext; + G::uploadFile($_FILES['form']['tmp_name']['APP_DOC_FILENAME'], $sPathName, $sFileName ); + + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_UPLOAD_DOCUMENT ) && class_exists ('uploadDocumentData' ) ) { + $oData['APP_UID'] = $_GET['APP_UID']; + $documentData = new uploadDocumentData ( + $_GET['APP_UID'], + $_SESSION['USER_LOGGED'], + $sPathName . $sFileName, + $aFields['APP_DOC_FILENAME'], + $sAppDocUid + ); + $oPluginRegistry->executeTriggers ( PM_UPLOAD_DOCUMENT , $documentData ); + unlink ( $sPathName . $sFileName ); + } + //end plugin + } + } + //go to the next step + if (!isset($_POST['form']['MORE'])) { + $oCase = new Cases(); + $aFields = $oCase->loadCase($_GET['APP_UID']); + $aNextStep = $oCase->getNextSupervisorStep($aFields['PRO_UID'], $_GET['position'], 'INPUT_DOCUMENT'); + G::header('location: ' . 'cases_StepToReviseInputs?type=INPUT_DOCUMENT&INP_DOC_UID='.$aNextStep['UID'].'&position='.$aNextStep['POSITION'].'&APP_UID='.$_GET['APP_UID'].'&DEL_INDEX='); + die; + } + else { + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; + } + } catch ( Exception $e ) { + /* Render Error page */ + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_ToReviseInputDocView.php b/workflow/engine/methods/cases/cases_ToReviseInputDocView.php new file mode 100644 index 000000000..4785bdf55 --- /dev/null +++ b/workflow/engine/methods/cases/cases_ToReviseInputDocView.php @@ -0,0 +1,82 @@ +<?php +/** + * cases_Step.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* Permissions */ +switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +if ((int)$_SESSION['INDEX'] < 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; +} +/* Includes */ +G::LoadClass('case'); +G::LoadClass('derivation'); + +/* GET , POST & $_SESSION Vars */ +//$_SESSION['STEP_POSITION'] = (int)$_GET['POSITION']; + +/* Menues */ +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + +$oCase = new Cases(); +$Fields = $oCase->loadCase($_SESSION['APPLICATION']); + +require_once 'classes/model/AppDocument.php'; +require_once 'classes/model/Users.php'; + +$G_PUBLISH = new Publisher; + +$oAppDocument = new AppDocument(); +$oAppDocument->Fields = $oAppDocument->load($_GET['DOC']); +$oo = $oAppDocument->load($_GET['DOC']); + +$oUser = new Users(); +$aUser = $oUser->load($oAppDocument->Fields['USR_UID']); +$Fields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + +$oAppDocument->Fields['VIEW'] = G::LoadTranslation('ID_OPEN'); +$oAppDocument->Fields['FILE'] = 'cases_ShowDocument?a=' . $_GET['DOC'] . '&r=' . rand(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewInputDocumentToRevise', '', G::array_merges($Fields, $oAppDocument->Fields), ''); + +G::RenderPage( 'publish' ); + +?> + + diff --git a/workflow/engine/methods/cases/cases_ToReviseOutputDocView.php b/workflow/engine/methods/cases/cases_ToReviseOutputDocView.php new file mode 100644 index 000000000..f16ea9937 --- /dev/null +++ b/workflow/engine/methods/cases/cases_ToReviseOutputDocView.php @@ -0,0 +1,143 @@ +<?php +/** + * cases_ToReviseOutputDocView.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* Permissions */ +switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +/* Includes */ +G::LoadClass('case'); + +/* Menues */ +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'cases'; +$G_ID_MENU_SELECTED = 'CASES'; +$G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + + +/* Prepare page before to show */ +$oTemplatePower = new TemplatePower(PATH_TPL . 'cases/cases_Step.html'); +$oTemplatePower->prepare(); +$G_PUBLISH = new Publisher; + +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptCode(' +var Cse = {}; +Cse.panels = {}; +var leimnud = new maborak(); +leimnud.make(); +leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); +leimnud.Package.Load("json",{Type:"file"}); +leimnud.Package.Load("cases",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases.js"}); +leimnud.Package.Load("cases_Step",{Type:"file",Absolute:true,Path:"/jscore/cases/core/cases_Step.js"}); +leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); +leimnud.exec(leimnud.fix.memoryLeak); +leimnud.event.add(window,"load",function(){ + '.(isset($_SESSION['showCasesWindow'])?'try{'.$_SESSION['showCasesWindow'].'}catch(e){}':'').'}); +'); +$G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); +// +require_once 'classes/model/OutputDocument.php'; +$oOutputDocument = new OutputDocument(); +$aOD = $oOutputDocument->load($_GET['UID']); +require_once 'classes/model/AppDocument.php'; +$oAppDocument = new AppDocument(); +$aFields = $oAppDocument->load($_GET['DOC']); +$aFields['VIEW'] = G::LoadTranslation('ID_OPEN'); +$aFields['FILE1'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=doc&random=' . rand(); +$aFields['FILE2'] = 'cases_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=pdf&random=' . rand(); +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ViewOutputDocumentToRevise', '', G::array_merges($aOD, $aFields), ''); +// +G::RenderPage('publish'); + +if(!isset($_GET['ex'])) $_GET['ex']=0; + +?> +<script type="text/javascript"> +/*------------------------------ To Revise Routines ---------------------------*/ +function setSelect() +{ + var ex=<?=$_GET['ex']?>; + + try{ + for(i=1; i<50; i++) + { + if(i == ex){ + document.getElementById('focus'+i).innerHTML = '<img src="/images/bulletButton.gif" />'; + } + else{ + document.getElementById('focus'+i).innerHTML = ''; + } + } + } catch (e){ + return 0; + } +} + +function toRevisePanel(APP_UID,DEL_INDEX) +{ + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:250,h:450}, + position:{x:0,y:100}, + title :'', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,close:false,drag:true}, + fx :{modal:false,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'cases_Ajax', + method:'post', + args: 'action=toRevisePanel&APP_UID='+APP_UID+'&DEL_INDEX='+DEL_INDEX + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + setSelect(); + + }.extend(this); + oRPC.make(); +} + +toRevisePanel('<?=$_SESSION['APPLICATION']?>','<?=$_SESSION['INDEX']?>'); +</script> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_UsersReassign.php b/workflow/engine/methods/cases/cases_UsersReassign.php new file mode 100644 index 000000000..efdf9f183 --- /dev/null +++ b/workflow/engine/methods/cases/cases_UsersReassign.php @@ -0,0 +1,75 @@ +<?php +/** + * cases_UsersReassign.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + G::LoadClass('case'); + $oCase = new Cases(); + $aCases = array(); + $aUsers = array(); + if (isset($_POST['USERS']) && is_array($_POST['USERS'])) { + foreach ($_POST['USERS'] as $sKey => $sUser) { + if ($sUser != '') { + $oCase->reassignCase($_POST['APPLICATIONS'][$sKey], $_POST['INDEXES'][$sKey], $_POST['USR_UID'], $sUser); + $aCases[] = $_POST['APPLICATIONS'][$sKey]; + $aUsers[] = $sUser; + } + } + } + G::LoadClass('case'); + $oCase = new Cases(); + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $sText = ''; + foreach ($aCases as $sKey => $sCase) { + $aCase = $oCase->loadCase($sCase); + $aUser = $oUser->load($aUsers[$sKey]); + $sText .= '(' . $aCase['APP_NUMBER'] . ') ' . $aCase['TITLE'] . ' => ' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . ' (' . $aUser['USR_USERNAME'] . ')' . '<br />'; + } + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REASSIGN'; + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $sText; + $aMessage['URL'] = 'cases_ReassignByUser?REASSIGN_USER=' . $_POST['USR_UID']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ReassignShowInfo', '', $aMessage); + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} diff --git a/workflow/engine/methods/cases/cases_advancedSearch.php b/workflow/engine/methods/cases/cases_advancedSearch.php new file mode 100644 index 000000000..e41859b10 --- /dev/null +++ b/workflow/engine/methods/cases/cases_advancedSearch.php @@ -0,0 +1,85 @@ +<?php +/** + * cases_advancedSearch.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * by The Answer + */ + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_ADVANCEDSEARCH'; + $G_PUBLISH = new Publisher; + + global $RBAC; + $permisse = $RBAC->userCanAccess('PM_ALLCASES'); + $userlogged = $_SESSION['USER_LOGGED']; + + require_once ( "classes/model/ProcessUser.php" ); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(ProcessUserPeer::PU_UID); + $oCriteria->addSelectColumn(ProcessUserPeer::PRO_UID); + $oCriteria->add(ProcessUserPeer::USR_UID, $userlogged); + $oCriteria->add(ProcessUserPeer::PU_TYPE, "SUPERVISOR"); + + $oDataset = ProcessUserPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + $aSupervisor = array(); + while ($aRow = $oDataset->getRow()) + { + $aSupervisor[] = $aRow['PRO_UID']; + $oDataset->next(); + } + + + G::LoadClass('case'); + $oCases = new Cases(); + + if (isset($_POST['form'])) + { + $fields['CASE_NUMBER'] = $_POST['form']['CASE_NUMBER']; + $fields['PROCESS'] = $_POST['form']['PROCESS']; + $fields['TASKS'] = $_POST['form']['TASKS']; + $fields['CURRENT_USER'] = $_POST['form']['CURRENT_USER']; + $fields['SENT_BY'] = $_POST['form']['SENT_BY']; + $fields['LAST_MODIFICATION_F'] = $_POST['form']['LAST_MODIFICATION_F']; + $fields['LAST_MODIFICATION_T'] = $_POST['form']['LAST_MODIFICATION_T']; + $fields['APP_STATUS'] = $_POST['form']['APP_STATUS']; + + $Criteria = $oCases->getAdvancedSearch($fields['CASE_NUMBER'], $fields['PROCESS'], $fields['TASKS'], $fields['CURRENT_USER'], $fields['SENT_BY'], $fields['LAST_MODIFICATION_F'], $fields['LAST_MODIFICATION_T'], $fields['APP_STATUS'], $permisse, $userlogged, $aSupervisor); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_advancedSearchFilter', '', $fields); + } + else + { + //list($Criteria,$xmlform) = $oCases->getConditionCasesList('gral'); + $Criteria = $oCases->getAdvancedSearch('', '', '', '', '', '', '', '', $permisse, $userlogged, $aSupervisor); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_advancedSearchFilter'); + } + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'cases/cases_advancedSearch', $Criteria); + + G::RenderPage('publish', 'blank'); +?> +<script> + parent.outerLayout.hide('east'); + parent.PANEL_EAST_OPEN = false; +</script> \ No newline at end of file diff --git a/workflow/engine/methods/cases/cases_generatePMTable.php b/workflow/engine/methods/cases/cases_generatePMTable.php new file mode 100644 index 000000000..02eb685f9 --- /dev/null +++ b/workflow/engine/methods/cases/cases_generatePMTable.php @@ -0,0 +1,110 @@ +<?php +/** + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +require_once ( "classes/model/AdditionalTables.php" ); +require_once ( "classes/model/Fields.php" ); +// passing the parameters +$pmTableName = (isset($_POST['tableName'])) ? $_POST['tableName'] : 'contenders'; +$pmTableFields = (isset($_POST['tableFields'])) ? json_decode($_POST['tableFields']) : array(); + +// default parameters +//$pmTableName = 'Sender'; +$pmTableFields = array(array('FLD_NAME'=>'APP_UID'),array('FLD_NAME'=>'CON_NAME'),array('FLD_NAME'=>'CON_ADDR'),array('FLD_NAME'=>'_cedula')); + +// setting the data to assemble the table +$aData = array(); +$aData['ADD_TAB_NAME'] = $pmTableName; +// creating the objects to create the table and records +$oFields = new Fields(); +$oAdditionalTables = new AdditionalTables(); + +$sAddTabUid = $oAdditionalTables->create($aData, $pmTableFields); + +foreach ($pmTableFields as $iRow => $aRow) { + $pmTableFields[$iRow]['FLD_NAME'] = strtoupper($aRow['FLD_NAME']); + $pmTableFields[$iRow]['FLD_DESCRIPTION'] = isset($aRow['FLD_DESCRIPTION']) ? $aRow['FLD_DESCRIPTION'] : $aRow['FLD_NAME']; + $pmTableFields[$iRow]['FLD_TYPE'] = isset($aRow['FLD_TYPE']) ? $aRow['FLD_TYPE'] : 'VARCHAR'; + $pmTableFields[$iRow]['FLD_SIZE'] = isset($aRow['FLD_SIZE']) ? $aRow['FLD_SIZE'] : '32'; + $pmTableFields[$iRow]['FLD_NULL'] = isset($aRow['FLD_NULL']) ? $aRow['FLD_NULL'] : 'off'; + $pmTableFields[$iRow]['FLD_AUTO_INCREMENT'] = isset($aRow['FLD_AUTO_INCREMENT']) ? $aRow['FLD_AUTO_INCREMENT'] : 'off'; + $pmTableFields[$iRow]['FLD_KEY'] = isset($aRow['FLD_KEY']) ? $aRow['FLD_KEY'] : 'off'; + $pmTableFields[$iRow]['FLD_FOREIGN_KEY'] = isset($aRow['FLD_FOREIGN_KEY']) ? $aRow['FLD_FOREIGN_KEY'] : 'off'; + $pmTableFields[$iRow]['FLD_FOREIGN_KEY_TABLE'] = isset($aRow['FLD_FOREIGN_KEY_TABLE']) ? $aRow['FLD_FOREIGN_KEY_TABLE'] : ''; +} + +foreach ($pmTableFields as $iRow => $aRow) { + + $oFields->create(array('FLD_INDEX' => $iRow+1, + 'ADD_TAB_UID' => $sAddTabUid, + 'FLD_NAME' => $aRow['FLD_NAME'], + 'FLD_DESCRIPTION' => isset($aRow['FLD_DESCRIPTION']) ? $aRow['FLD_DESCRIPTION'] : '', + 'FLD_TYPE' => isset($aRow['FLD_TYPE']) ? $aRow['FLD_TYPE'] : 'VARCHAR', + 'FLD_SIZE' => isset($aRow['FLD_SIZE']) ? $aRow['FLD_SIZE'] : '32', + 'FLD_NULL' => ($aRow['FLD_NULL'] == 'on' ? 1 : 0), + 'FLD_AUTO_INCREMENT' => ($aRow['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0), + 'FLD_KEY' => ($aRow['FLD_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY' => ($aRow['FLD_FOREIGN_KEY'] == 'on' ? 1 : 0), + 'FLD_FOREIGN_KEY_TABLE' => isset($aRow['FLD_FOREIGN_KEY_TABLE']) ? $aRow['FLD_FOREIGN_KEY_TABLE'] : '')); + + $aFields[] = array('sType' => isset($aRow['FLD_TYPE']) ? $aRow['FLD_TYPE'] : 'VARCHAR', + 'iSize' => isset($aRow['FLD_SIZE']) ? $aRow['FLD_SIZE'] : '32', + 'sFieldName' => $aRow['FLD_NAME'], + 'bNull' => ($aRow['FLD_NULL'] == 'on' ? 1 : 0), + 'bAI' => ($aRow['FLD_AUTO_INCREMENT'] == 'on' ? 1 : 0), + 'bPrimaryKey' => ($aRow['FLD_KEY'] == 'on' ? 1 : 0)); +} + +$oAdditionalTables->createTable(strtoupper($pmTableName), 'wf', $aFields); +$oAdditionalTables->createPropelClasses(strtoupper($pmTableName), $pmTableName, $pmTableFields, $sAddTabUid); + +require_once ( "classes/model/Application.php" ); +require_once ( "classes/model/AdditionalTables.php" ); +require_once ( "classes/model/Fields.php" ); + + +$Criteria = new Criteria('workflow'); +$Criteria->addSelectColumn (ApplicationPeer::APP_UID); +$Criteria->addSelectColumn (ApplicationPeer::APP_DATA); + +// $Criteria->add (AppCacheViewPeer::DEL_THREAD_STATUS, 'OPEN'); +$oDataset = ApplicationPeer::doSelectRS($Criteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$aProcesses = array(); +$i = 0; +while ($aRow = $oDataset->getRow()) { + $appuid = $aRow['APP_UID']; + $data = unserialize ( $aRow['APP_DATA'] ); +$cedula = '234'. rand (1000,999999); +$nombre = 'nombre '. rand (1000,999999); +$direccion = 'direccion '. rand (1000,999999); + if ( isset ( $data['_cedula'] ) ) { + $cedula = $data['_cedula']; + $nombre = isset($data['_nombre']) ? $data['_nombre'] : ''; + $direccion = isset($data['_direccion']) ? $data['_direccion'] : ''; + print "$i $appuid $cedula <br>"; + } +// print_r ( $aRow); + $sql = "insert CONTENDERS VALUES ( '$appuid', '$nombre', '$direccion', '$cedula' )"; + + $con = Propel::getConnection('workflow'); + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + + $i++; +// if ( $i == 100 ) die; +/* if ( strpos ( $aRow['APP_DATA'], 'cedula' ) !== false ) { + print_r ( $aRow ); + print "<hr>"; + $i++; + if ( $i == 10 ) die; + } +*/ + $oDataset->next(); +} +print "--$i--"; + +?> diff --git a/workflow/engine/methods/cases/cases_toRevise.php b/workflow/engine/methods/cases/cases_toRevise.php new file mode 100644 index 000000000..b8360d721 --- /dev/null +++ b/workflow/engine/methods/cases/cases_toRevise.php @@ -0,0 +1,29 @@ +<? + +switch ($RBAC->userCanAccess('PM_SUPERVISOR')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +if (($RBAC_Response = $RBAC->userCanAccess("PM_USERS")) != 1) + return $RBAC_Response; + + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'cases'; + $G_ID_MENU_SELECTED = 'CASES'; + $G_ID_SUB_MENU_SELECTED = 'CASES_TO_REVISE'; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'cases/cases_toRevise'); + $G_PUBLISH->AddContent('smarty', 'cases/cases_toReviseIn', '', '', array()); + + G::RenderPage("publish-treeview"); diff --git a/workflow/engine/methods/cases/debug_triggers.php b/workflow/engine/methods/cases/debug_triggers.php new file mode 100755 index 000000000..9862358bd --- /dev/null +++ b/workflow/engine/methods/cases/debug_triggers.php @@ -0,0 +1,72 @@ +<?php +if( isset($_SESSION['TRIGGER_DEBUG']['info']) ) { + $aTriggers = $_SESSION['TRIGGER_DEBUG']['info']; +} else { + $aTriggers[0] = $_SESSION['TRIGGER_DEBUG']; +} + +//print_r($aTriggers);die; +$triggersList = Array(); + +$i = 0; +foreach($aTriggers as $aTrigger) { + + if($aTrigger['NUM_TRIGGERS'] != 0) { + + foreach($aTrigger['TRIGGERS_NAMES'] as $index=>$name) { + + $triggersList[$i]['name'] = $name; + $triggersList[$i]['execution_time'] = strtolower($aTrigger['TIME']); + //$t_code = $aTrigger['TRIGGERS_VALUES'][$index]['TRI_WEBBOT']; + //$t_code = str_replace('"', '\'',$t_code); + //$t_code = addslashes($t_code); + //$t_code = Only1br($t_code); + + //highlighting the trigger code using the geshi third party library + G::LoadThirdParty('geshi', 'geshi'); + $geshi = new GeSHi($aTrigger['TRIGGERS_VALUES'][$index]['TRI_WEBBOT'], 'php'); + $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 2); + $geshi->set_line_style('background: #f0f0f0;'); + + $triggersList[$i]['code'] = $geshi->parse_code(); //$aTrigger['TRIGGERS_VALUES'][$index]['TRI_WEBBOT']; + $i++; + } + } else { + + } +} + +//print_r($_SESSION['TRIGGER_DEBUG']['ERRORS']); die; +$DEBUG_ERRORS = array_unique($_SESSION['TRIGGER_DEBUG']['ERRORS']); + +foreach($DEBUG_ERRORS as $error){ + if(isset($error['ERROR']) and $error['ERROR'] != ''){ + $triggersList[$i]['name'] = 'Error'; + $triggersList[$i]['execution_time'] = 'error'; + $triggersList[$i]['code'] = $error['ERROR']; + $i++; + } + + if(isset($error['FATAL']) and $error['FATAL'] != ''){ + $error['FATAL'] = str_replace("<br />", "\n", $error['FATAL']); + $tmp = explode("\n", $error['FATAL']); + $triggersList[$i]['name'] = isset($tmp[0])? $tmp[0]: 'Fatal Error in trigger'; + $triggersList[$i]['execution_time'] = 'Fatal error'; + $triggersList[$i]['code'] = $error['FATAL']; + $i++; + } +} + + +/*echo '{total:5, data:[ + {name:"trigger1", execution_time:"after"}, + {name:"trigger2", execution_time:"before"}, + {name:"trigger13", execution_time:"before"}, + ]}'; + + */ + +$triggersRet->total = count($triggersList); +$triggersRet->data = $triggersList; + +echo G::json_encode($triggersRet); \ No newline at end of file diff --git a/workflow/engine/methods/cases/debug_vars.php b/workflow/engine/methods/cases/debug_vars.php new file mode 100755 index 000000000..32b8b3a28 --- /dev/null +++ b/workflow/engine/methods/cases/debug_vars.php @@ -0,0 +1,97 @@ +<?php +$request = isset($_POST['request']) ? $_POST['request'] : ''; +switch($request){ + case 'getRows': + + $fieldname = $_POST['fieldname']; + + G::LoadClass('case'); + $oApp= new Cases(); + $aFields = $oApp->loadCase($_SESSION['APPLICATION']); + + $aVariables = Array(); + for($i=0; $i<count($_SESSION['TRIGGER_DEBUG']['DATA']); $i++) { + $aVariables[$_SESSION['TRIGGER_DEBUG']['DATA'][$i]['key']] = $_SESSION['TRIGGER_DEBUG']['DATA'][$i]['value']; + } + + $aVariables = array_merge($aFields['APP_DATA'], $aVariables); + + $field = $aVariables[$fieldname]; + $response->headers = Array(); + $response->columns = Array(); + $response->rows = Array(); + + $sw = true; + $j = 0; + if(is_array($field)){ + foreach ($field as $row) { + if($sw){ + foreach ($row as $key=>$value) { + $response->headers[] = Array('name'=>$key); + $response->columns[] = Array('header'=>$key, 'width'=>100, 'dataIndex'=>$key); + } + $sw = false; + } + + + $tmp = Array(); + foreach ($row as $key=>$value) { + $tmp[] = $value; + } + $response->rows[$j++] = $tmp; + } + } else if( is_object($field) ) { + $response->headers = Array(Array('name'=>'name'), Array('name'=>'value')); + $response->columns = Array(Array('header'=>'Property', 'width'=>100, 'dataIndex'=>'name'), Array('header'=>'Value', 'width'=>100, 'dataIndex'=>'value')); + + foreach ($field as $key => $value) { + $response->rows[] = Array($key, $value); + } + } + + echo G::json_encode($response); + break; + + default: + G::LoadClass('case'); + $oApp= new Cases(); + $aFields = $oApp->loadCase($_SESSION['APPLICATION']); + + $aVariables = Array(); + for($i=0; $i<count($_SESSION['TRIGGER_DEBUG']['DATA']); $i++) { + $aVariables[$_SESSION['TRIGGER_DEBUG']['DATA'][$i]['key']] = $_SESSION['TRIGGER_DEBUG']['DATA'][$i]['value']; + } + + $aVariables = array_merge($aFields['APP_DATA'], $aVariables); + + + if( isset($_POST['filter']) && $_POST['filter'] == 'dyn' ){ + $sysVars = array_keys(G::getSystemConstants()); + $varNames = array_keys($aVariables); + foreach($varNames as $var){ + if( in_array($var, $sysVars) ){ + unset($aVariables[$var]); + } + } + } + if( isset($_POST['filter']) && $_POST['filter'] == 'sys' ){ + $aVariables = G::getSystemConstants(); + } + + ksort($aVariables); + $return_object->totalCount=1; + + foreach ($aVariables as $i=>$var) { + if( is_object($var) ){ + $aVariables[$i] = '<object>'; + } + if( is_array($var) ){ + $aVariables[$i] = '<array>'; + } + } + + $return_object->data[0]=$aVariables; + + echo G::json_encode($return_object); + break; +} \ No newline at end of file diff --git a/workflow/engine/methods/cases/index.php b/workflow/engine/methods/cases/index.php new file mode 100644 index 000000000..68141865d --- /dev/null +++ b/workflow/engine/methods/cases/index.php @@ -0,0 +1,29 @@ +<?php +/** + * index.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //$newFile = str_replace ( 'index.php', 'cases_List.php' , __FILE__ ) ; + $newFile = str_replace ( 'index.php', 'main.php' , __FILE__ ) ; + return $newFile; + + \ No newline at end of file diff --git a/workflow/engine/methods/cases/main.php b/workflow/engine/methods/cases/main.php new file mode 100755 index 000000000..71073bc07 --- /dev/null +++ b/workflow/engine/methods/cases/main.php @@ -0,0 +1,34 @@ +<?php +/** + * main.php Cases List main processor + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$RBAC->requirePermissions('PM_CASES'); + +$G_MAIN_MENU = 'processmaker'; +$G_ID_MENU_SELECTED = 'CASES'; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('view', 'cases/cases_Load'); +G::RenderPage('publish'); + diff --git a/workflow/engine/methods/cases/main_init.php b/workflow/engine/methods/cases/main_init.php new file mode 100644 index 000000000..c0e2e84e7 --- /dev/null +++ b/workflow/engine/methods/cases/main_init.php @@ -0,0 +1,63 @@ +<?php +/** + * main.php Cases List main processor + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $oHeadPublisher =& headPublisher::getSingleton(); + //$oHeadPublisher->usingExtJs('ux/XmlTreeLoader'); + $oHeadPublisher->addExtJsScript('cases/main', false ); //adding a javascript file .js + $oHeadPublisher->addContent( 'cases/main'); //adding a html file .html. + + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'USER_PREFERENCES','','',$_SESSION['USER_LOGGED'],''); + $confDefaultOption=''; + if( sizeof($oConf->Fields) > 0 && isset($oConf->aConfig['DEFAULT_CASES_MENU']) ){ #this user has a configuration record + $confDefaultOption = $oConf->aConfig['DEFAULT_CASES_MENU']; + global $G_TMP_MENU; + $oMenu = new Menu(); + $oMenu->load('cases'); + $defaultOption = ''; + //g::pr($oMenu); die; + foreach($oMenu->Id as $i=>$id){ + if( $id == $confDefaultOption ){ + $defaultOption = $oMenu->Options[$i]; + break; + } + } + $defaultOption = $defaultOption != '' ? $defaultOption : 'casesListExtJs'; + + } else { + $defaultOption = 'casesListExtJs'; + $confDefaultOption = 'CASES_INBOX'; + } + + $oHeadPublisher->assign( 'defaultOption', $defaultOption); // user menu permissions + $oHeadPublisher->assign( '_nodeId', isset($confDefaultOption)?$confDefaultOption:'PM_USERS'); // user menu permissions + + $translations = G::getTranslations(Array( + 'ID_DEATACH', 'ID_ALL', 'ID_DYNAFORM', 'ID_SYSTEM', 'ID_VARIABLES', 'ID_TRIGGERS', 'ID_OPEN_IN_POPUP' + )); + $oHeadPublisher->assign('TRANSLATIONS', $translations); + G::RenderPage('publish', 'extJs'); + diff --git a/workflow/engine/methods/cases/proxyCasesList.php b/workflow/engine/methods/cases/proxyCasesList.php new file mode 100755 index 000000000..b4973fffc --- /dev/null +++ b/workflow/engine/methods/cases/proxyCasesList.php @@ -0,0 +1,600 @@ +<?php + + // getting the extJs parameters + $callback = isset($_POST['callback']) ? $_POST['callback'] : 'stcCallback1001'; + $dir = isset($_POST['dir']) ? $_POST['dir'] : 'DESC'; + $sort = isset($_POST['sort']) ? $_POST['sort'] : ''; + $start = isset($_POST['start']) ? $_POST['start'] : '0'; + $limit = isset($_POST['limit']) ? $_POST['limit'] : '25'; + $filter = isset($_POST['filter']) ? $_POST['filter'] : ''; + $search = isset($_POST['search']) ? $_POST['search'] : ''; + $process = isset($_POST['process']) ? $_POST['process'] : ''; + $user = isset($_POST['user']) ? $_POST['user'] : ''; + $status = isset($_POST['status']) ? strtoupper($_POST['status']) : ''; + $action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : 'todo'); + $type = isset($_GET['type']) ? $_GET['type'] : (isset($_POST['type']) ? $_POST['type'] : 'extjs'); + $user = isset($_POST['user']) ? $_POST['user'] : ''; + $dateFrom = isset($_POST['dateFrom'])? substr($_POST['dateFrom'],0,10) : ''; + $dateTo = isset($_POST['dateTo']) ? substr($_POST['dateTo'],0,10) : ''; + + try { + + G::LoadClass("BasePeer" ); + G::LoadClass ( 'configuration' ); + require_once ( "classes/model/AppCacheView.php" ); + require_once ( "classes/model/AppDelegation.php" ); + require_once ( "classes/model/AdditionalTables.php" ); + require_once ( "classes/model/AppDelay.php" ); + require_once ( "classes/model/Fields.php" ); + + $userUid = ( isset($_SESSION['USER_LOGGED'] ) && $_SESSION['USER_LOGGED'] != '' ) ? $_SESSION['USER_LOGGED'] : null; + $oAppCache = new AppCacheView(); + + //get data configuration + $conf = new Configurations(); + $confCasesList = $conf->getConfiguration('casesList',($action=='search'||$action=='simple_search')?'sent':$action ); +// var_dump($confCasesList); + $oAppCache->confCasesList = $confCasesList; + +// get the action based list + switch ( $action ) { + case 'draft' : + $Criteria = $oAppCache->getDraftListCriteria($userUid); + $CriteriaCount = $oAppCache->getDraftCountCriteria($userUid); + break; + case 'sent' : + $Criteria = $oAppCache->getSentListCriteria($userUid); + $CriteriaCount = $oAppCache->getSentCountCriteria($userUid); +// var_dump($Criteria); + break; + case 'selfservice' : + case 'unassigned': + $Criteria = $oAppCache->getUnassignedListCriteria($userUid); + $CriteriaCount = $oAppCache->getUnassignedCountCriteria($userUid); + break; + case 'paused' : + $Criteria = $oAppCache->getPausedListCriteria($userUid); + $CriteriaCount = $oAppCache->getPausedCountCriteria($userUid); + break; + case 'completed' : + $Criteria = $oAppCache->getCompletedListCriteria($userUid); + $CriteriaCount = $oAppCache->getCompletedCountCriteria($userUid); + break; + case 'cancelled' : + $Criteria = $oAppCache->getCancelledListCriteria($userUid); + $CriteriaCount = $oAppCache->getCancelledCountCriteria($userUid); + break; + case 'search' : + $Criteria = $oAppCache->getSearchListCriteria(); + $CriteriaCount = $oAppCache->getSearchCountCriteria(); + break; + case 'simple_search' : + $Criteria = $oAppCache->getSimpleSearchListCriteria(); + $CriteriaCount = $oAppCache->getSimpleSearchCountCriteria(); + break; + case 'to_revise' : + $Criteria = $oAppCache->getToReviseListCriteria($userUid); + $CriteriaCount = $oAppCache->getToReviseCountCriteria($userUid); + break; + case 'to_reassign' : + $Criteria = $oAppCache->getToReassignListCriteria(); + $CriteriaCount = $oAppCache->getToReassignCountCriteria(); + break; + case 'all' : + $Criteria = $oAppCache->getAllCasesListCriteria($userUid); + $CriteriaCount = $oAppCache->getAllCasesCountCriteria($userUid); + break; + // general criteria probably will be deprecated + case 'gral' : + $Criteria = $oAppCache->getGeneralListCriteria(); + $CriteriaCount = $oAppCache->getGeneralCountCriteria(); + break; + case 'todo' : + default: + $Criteria = $oAppCache->getToDoListCriteria($userUid); + $CriteriaCount = $oAppCache->getToDoCountCriteria($userUid); + break; + } + + if ( !is_array($confCasesList) ) { + $rows = getDefaultFields( $action ); + $result = genericJsonResponse( '', array(), $rows , 20, '' ); + $conf->saveObject($result,'casesList',$action,'','',''); + } + + // add the process filter + if ( $process != '' ) { + $Criteria->add (AppCacheViewPeer::PRO_UID, $process, Criteria::EQUAL ); + $CriteriaCount->add (AppCacheViewPeer::PRO_UID, $process, Criteria::EQUAL ); + } + + // add the user filter + if ( $user != '' ) { + $Criteria->add (AppCacheViewPeer::USR_UID, $user, Criteria::EQUAL ); + $CriteriaCount->add (AppCacheViewPeer::USR_UID, $user, Criteria::EQUAL ); + } + + if ( $status != '' ) { + $Criteria->add (AppCacheViewPeer::APP_STATUS, $status, Criteria::EQUAL ); + $CriteriaCount->add (AppCacheViewPeer::APP_STATUS, $status, Criteria::EQUAL ); + } + + if ( $dateFrom != '' ) { + if( $dateTo != '' ){ + $Criteria->add( + $Criteria->getNewCriterion( + AppCacheViewPeer::DEL_DELEGATE_DATE, + $dateFrom, Criteria::GREATER_EQUAL + )->addAnd($Criteria->getNewCriterion( + AppCacheViewPeer::DEL_DELEGATE_DATE, + $dateTo, Criteria::LESS_EQUAL + )) + ); + $CriteriaCount->add( + $CriteriaCount->getNewCriterion( + AppCacheViewPeer::DEL_DELEGATE_DATE, + $dateFrom, Criteria::GREATER_EQUAL + )->addAnd($Criteria->getNewCriterion( + AppCacheViewPeer::DEL_DELEGATE_DATE, + $dateTo, Criteria::LESS_EQUAL + )) + ); + } else { + $Criteria->add (AppCacheViewPeer::DEL_DELEGATE_DATE, $dateFrom, Criteria::GREATER_EQUAL ); + $CriteriaCount->add (AppCacheViewPeer::DEL_DELEGATE_DATE, $dateFrom, Criteria::GREATER_EQUAL ); + } + } else if ( $dateTo != '' ) { + $Criteria->add (AppCacheViewPeer::DEL_DELEGATE_DATE, $dateTo, Criteria::LESS_EQUAL ); + $CriteriaCount->add (AppCacheViewPeer::DEL_DELEGATE_DATE, $dateTo, Criteria::LESS_EQUAL ); + } + + //add the filter + if ( $filter != '' ) { + switch ( $filter ) { + case 'read' : + $Criteria->add (AppCacheViewPeer::DEL_INIT_DATE, null, Criteria::ISNOTNULL); + $CriteriaCount->add (AppCacheViewPeer::DEL_INIT_DATE, null, Criteria::ISNOTNULL); + break; + case 'unread' : + $Criteria->add (AppCacheViewPeer::DEL_INIT_DATE, null, Criteria::ISNULL); + $CriteriaCount->add (AppCacheViewPeer::DEL_INIT_DATE, null, Criteria::ISNULL); + break; + case 'started' : + $Criteria->add (AppCacheViewPeer::DEL_INDEX, 1, Criteria::EQUAL); + $CriteriaCount->add (AppCacheViewPeer::DEL_INDEX, 1, Criteria::EQUAL); + break; + case 'completed' : + $Criteria->add (AppCacheViewPeer::APP_STATUS, 'COMPLETED', Criteria::EQUAL); + $CriteriaCount->add (AppCacheViewPeer::APP_STATUS, 'COMPLETED', Criteria::EQUAL); + break; + } + } + + //add the search filter + if ( $search != '' ) { + + $defaultFields = $oAppCache->getDefaultFields(); + $oTmpCriteria = ''; + // if there is PMTABLE for this case list: + if ( !empty($oAppCache->confCasesList) && isset($oAppCache->confCasesList['PMTable']) && trim($oAppCache->confCasesList['PMTable'])!='' ) { + // getting the table name + $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($oAppCache->confCasesList['PMTable']); + $tableName = $oAdditionalTables->getAddTabName(); + $oNewCriteria = new Criteria( 'workflow' ); + $counter = 0; + foreach($oAppCache->confCasesList['second']['data'] as $fieldData){ + if ( !in_array($fieldData['name'],$defaultFields) ){ + $fieldName = $tableName.'.'.$fieldData['name']; + if ( $counter == 0 ) { + $oTmpCriteria = $oNewCriteria->getNewCriterion ( $fieldName, '%' . $search . '%', Criteria::LIKE ); + } else { + $oTmpCriteria = $oNewCriteria->getNewCriterion ( $fieldName, '%' . $search . '%', Criteria::LIKE )->addOr($oTmpCriteria); + } + $counter++; + } + } + //add the default and hidden DEL_INIT_DATE + } + + // the criteria adds new fields if there are defined PM Table Fields in the cases list + if ($oTmpCriteria!='') { + $Criteria->add( + $Criteria->getNewCriterion( + AppCacheViewPeer::APP_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($Criteria->getNewCriterion( + AppCacheViewPeer::APP_TAS_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($Criteria->getNewCriterion( + AppCacheViewPeer::APP_NUMBER, $search, Criteria::LIKE + )->addOr($oTmpCriteria)) + )); + } else { + $Criteria->add( + $Criteria->getNewCriterion( + AppCacheViewPeer::APP_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($Criteria->getNewCriterion( + AppCacheViewPeer::APP_TAS_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($Criteria->getNewCriterion( + AppCacheViewPeer::APP_NUMBER, $search, Criteria::LIKE + )) + )); + } + + // the count query needs to be the normal criteria query if there are defined PM Table Fields in the cases list + if ($oTmpCriteria!='') { + $CriteriaCount = $Criteria; + } else { + $CriteriaCount->add( + $CriteriaCount->getNewCriterion( + AppCacheViewPeer::APP_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($CriteriaCount->getNewCriterion( + AppCacheViewPeer::APP_TAS_TITLE, '%' . $search . '%', Criteria::LIKE + )->addOr($CriteriaCount->getNewCriterion( + AppCacheViewPeer::APP_NUMBER, $search, Criteria::LIKE + )) + )); + } + } + + //here we count how many records exists for this criteria. + //BUT there are some special cases, and if we dont optimize them the server will crash. + $doCountAlreadyExecuted = false; + //case 1. when the SEARCH action is selected and none filter, search criteria is defined, + //we need to count using the table APPLICATION, because APP_CACHE_VIEW takes 3 seconds + + if ( $action == 'search' && $filter == '' && $search == '' && $process == '' && $status == '' && $dateFrom == '' && $dateTo == '') { + $totalCount = $oAppCache->getSearchAllCount(); + $doCountAlreadyExecuted = true; + } + + if ( $doCountAlreadyExecuted == false ) { + // in the case of reassign the distinct attribute shows a diferent count result comparing to the + // original list + if ($action == 'to_reassign' || $action == 'todo'){ + $distinct = false; + } else{ + $distinct = true; + } + // needs a litle bit of analysis to understant whats going on + // first check if there is a PMTable defined within the list maybe this code will be deprecated + // the issue that brokes the normal criteria query seems to be fixed +// if (isset($oAppCache->confCasesList['PMTable']) && !empty($oAppCache->confCasesList['PMTable'])){ +// // then +// $oAdditionalTables = AdditionalTablesPeer::retrieveByPK($oAppCache->confCasesList['PMTable']); +// $tableName = $oAdditionalTables->getAddTabName(); +// $tableName = strtolower($tableName); +// $tableNameArray = explode('_',$tableName); +// foreach ($tableNameArray as $item){ +// $newTableName[] = ucfirst($item); +// } +// $tableName = implode('',$newTableName); +//// +// if (!class_exists($tableName)){ +// require_once(PATH_DB.SYS_SYS.PATH_SEP."classes".PATH_SEP.$tableName.".php"); +// } +// eval ("\$totalCount=".$tableName."Peer::doCount( \$CriteriaCount, \$distinct );"); +// +// } else { +// $totalCount = AppCacheViewPeer::doCount( $CriteriaCount, $distinct ); +// } + $totalCount = AppCacheViewPeer::doCount( $CriteriaCount, $distinct ); + + } + + //add sortable options + if ( $sort != '' ) { + if ( $dir == 'DESC' ) + $Criteria->addDescendingOrderByColumn( $sort ); + else + $Criteria->addAscendingOrderByColumn( $sort ); + } + + //limit the results according the interface + $Criteria->setLimit( $limit ); + $Criteria->setOffset( $start ); + + $params = array(); + $sSql = BasePeer::createSelectSql($Criteria, $params); +// var_dump($sSql); + + //execute the query + $oDataset = AppCacheViewPeer::doSelectRS($Criteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + $result = array(); + $result['totalCount'] = $totalCount; + $rows = array(); + $aPriorities = array('1'=>'VL', '2'=>'L', '3'=>'N', '4'=>'H', '5'=>'VH'); + $index = $start; + while($aRow = $oDataset->getRow()){ + //$aRow = $oAppCache->replaceRowUserData($aRow); + // replacing the status data with their respective translation + if( isset($aRow['APP_STATUS']) ){ + $aRow['APP_STATUS'] = G::LoadTranslation("ID_{$aRow['APP_STATUS']}"); + } + // replacing the priority data with their respective translation + if( isset($aRow['DEL_PRIORITY']) ){ + $aRow['DEL_PRIORITY'] = G::LoadTranslation("ID_PRIORITY_{$aPriorities[$aRow['DEL_PRIORITY']]}"); + } + $rows[] = $aRow; + $oDataset->next(); + } + $result['data'] = $rows; +//print the result in json format + print G::json_encode( $result ) ; + + } + catch ( Exception $e ) { + $msg = array ( 'error' => $e->getMessage() ); + print G::json_encode( $msg ) ; + } + + + + //TODO: Encapsulates these and another default generation functions inside a class + /** + * generate all the default fields + * @return Array $fields + */ + function setDefaultFields() { + $fields = array(); + $fields['APP_NUMBER'] = array( 'name' => 'APP_NUMBER' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_NUMBER') , 'width' => 40, 'align' => 'left'); + $fields['APP_UID'] = array( 'name' => 'APP_UID' , 'fieldType' => 'key', 'label' => G::loadTranslation('ID_CASESLIST_APP_UID'), 'width' => 80, 'align' => 'left'); + $fields['DEL_INDEX'] = array( 'name' => 'DEL_INDEX' , 'fieldType' => 'key' , 'label' => G::loadTranslation('ID_CASESLIST_DEL_INDEX') , 'width' => 50, 'align' => 'left'); + $fields['TAS_UID'] = array( 'name' => 'TAS_UID' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_TAS_UID') , 'width' => 80, 'align' => 'left'); + $fields['USR_UID'] = array( 'name' => 'USR_UID' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_USR_UID') , 'width' => 80, 'align' => 'left', 'hidden' => true); + $fields['PREVIOUS_USR_UID'] = array( 'name' => 'PREVIOUS_USR_UID' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_PREVIOUS_USR_UID') , 'width' => 80, 'align' => 'left', 'hidden' => true); + $fields['APP_TITLE'] = array( 'name' => 'APP_TITLE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_TITLE') , 'width' => 140, 'align' => 'left'); + $fields['APP_PRO_TITLE'] = array( 'name' => 'APP_PRO_TITLE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_PRO_TITLE') , 'width' => 140, 'align' => 'left'); + $fields['APP_TAS_TITLE'] = array( 'name' => 'APP_TAS_TITLE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_TAS_TITLE') , 'width' => 140, 'align' => 'left'); + $fields['APP_DEL_PREVIOUS_USER'] = array( 'name' => 'APP_DEL_PREVIOUS_USER' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DEL_PREVIOUS_USER') , 'width' => 120, 'align' => 'left'); + $fields['APP_CURRENT_USER'] = array( 'name' => 'APP_CURRENT_USER' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_CURRENT_USER') , 'width' => 120, 'align' => 'left'); + $fields['DEL_TASK_DUE_DATE'] = array( 'name' => 'DEL_TASK_DUE_DATE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_DEL_TASK_DUE_DATE') , 'width' => 100, 'align' => 'left'); + $fields['APP_UPDATE_DATE'] = array( 'name' => 'APP_UPDATE_DATE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_UPDATE_DATE') , 'width' => 100, 'align' => 'left'); + $fields['DEL_PRIORITY'] = array( 'name' => 'DEL_PRIORITY' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_DEL_PRIORITY') , 'width' => 80, 'align' => 'left'); + $fields['APP_STATUS'] = array( 'name' => 'APP_STATUS' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_STATUS') , 'width' => 80, 'align' => 'left'); + $fields['APP_FINISH_DATE'] = array( 'name' => 'APP_FINISH_DATE' , 'fieldType' => 'case field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_FINISH_DATE') , 'width' => 100, 'align' => 'left'); + $fields['APP_DELAY_UID'] = array( 'name' => 'APP_DELAY_UID' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DELAY_UID') , 'width' => 100, 'align' => 'left'); + $fields['APP_THREAD_INDEX'] = array( 'name' => 'APP_THREAD_INDEX' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_THREAD_INDEX') , 'width' => 100, 'align' => 'left'); + $fields['APP_DEL_INDEX'] = array( 'name' => 'APP_DEL_INDEX' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DEL_INDEX') , 'width' => 100, 'align' => 'left'); + $fields['APP_TYPE'] = array( 'name' => 'APP_TYPE' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_TYPE') , 'width' => 100, 'align' => 'left'); + $fields['APP_DELEGATION_USER'] = array( 'name' => 'APP_DELEGATION_USER' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DELEGATION_USER') , 'width' => 100, 'align' => 'left'); + $fields['APP_ENABLE_ACTION_USER'] = array( 'name' => 'APP_ENABLE_ACTION_USER' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_ENABLE_ACTION_USER') , 'width' => 100, 'align' => 'left'); + $fields['APP_ENABLE_ACTION_DATE'] = array( 'name' => 'APP_ENABLE_ACTION_DATE' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_AAPP_ENABLE_ACTION_DATE') , 'width' => 100, 'align' => 'left'); + $fields['APP_DISABLE_ACTION_USER'] = array( 'name' => 'APP_DISABLE_ACTION_USER', 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DISABLE_ACTION_USER') , 'width' => 100, 'align' => 'left'); + $fields['APP_DISABLE_ACTION_DATE'] = array( 'name' => 'APP_DISABLE_ACTION_DATE', 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_DISABLE_ACTION_DATE') , 'width' => 100, 'align' => 'left'); + $fields['APP_AUTOMATIC_DISABLED_DATE'] = array( 'name' => 'APP_AUTOMATIC_DISABLED_DATE' , 'fieldType' => 'delay field' , 'label' => G::loadTranslation('ID_CASESLIST_APP_AUTOMATIC_DISABLED_DATE') , 'width' => 100, 'align' => 'left'); + return $fields; + + } + + /** + * this function return the default fields for a default case list + * @param $action + * @return an array with the default fields for an specific case list (action) + */ + function getDefaultFields ( $action ) { + $rows = array(); + switch ( $action ) { + case 'todo' : // #, Case, task, process, sent by, due date, Last Modify, Priority + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['DEL_TASK_DUE_DATE']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['DEL_PRIORITY']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + + case 'draft' : //#, Case, task, process, due date, Last Modify, Priority }, + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['DEL_TASK_DUE_DATE']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['DEL_PRIORITY']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + case 'sent' : // #, Case, task, process, current user, sent by, Last Modify, Status + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_CURRENT_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['APP_STATUS']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + case 'unassigned' : //#, Case, task, process, completed by user, finish date + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + case 'paused' : //#, Case, task, process, sent by + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['APP_THREAD_INDEX']; + $rows[] = $fields['APP_DEL_INDEX']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + case 'completed' : //#, Case, task, process, completed by user, finish date + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + + case 'cancelled' : //#, Case, task, process, due date, Last Modify + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + + case 'to_revise' : //#, Case, task, process, due date, Last Modify + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_CURRENT_USER']; + $rows[] = $fields['DEL_PRIORITY']; + $rows[] = $fields['APP_STATUS']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + + case 'to_reassign' : //#, Case, task, process, due date, Last Modify + $fields = setDefaultFields(); + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['TAS_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_UID']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_CURRENT_USER']; +// $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['APP_STATUS']; +// $rows[] = $fields['USR_UID']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + + break; + + case 'all' : //#, Case, task, process, due date, Last Modify + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_CURRENT_USER']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['APP_STATUS']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + + case 'gral' : //#, Case, task, process, due date, Last Modify + $fields = setDefaultFields(); + $rows[] = $fields['APP_UID']; + $rows[] = $fields['DEL_INDEX']; + $rows[] = $fields['APP_NUMBER']; + $rows[] = $fields['APP_TITLE']; + $rows[] = $fields['APP_PRO_TITLE']; + $rows[] = $fields['APP_TAS_TITLE']; + $rows[] = $fields['APP_CURRENT_USER']; + $rows[] = $fields['APP_DEL_PREVIOUS_USER']; + $rows[] = $fields['APP_UPDATE_DATE']; + $rows[] = $fields['APP_STATUS']; + $rows[] = $fields['USR_UID']; + $rows[] = $fields['PREVIOUS_USR_UID']; + break; + } + return $rows; + } + + /** + * set the generic Json Response, using two array for the grid stores and a string for the pmtable name + * @param string $pmtable + * @param array $first + * @param array $second + * @return $response a json string + */ + function genericJsonResponse($pmtable, $first, $second, $rowsperpage, $dateFormat ) { + $firstGrid['totalCount'] = count($first); + $firstGrid['data'] = $first; + $secondGrid['totalCount'] = count($second); + $secondGrid['data'] = $second; + $result = array(); + $result['first'] = $firstGrid; + $result['second'] = $secondGrid; + $result['PMTable'] = isset($pmtable) ? $pmtable : ''; + $result['rowsperpage'] = isset($rowsperpage) ? $rowsperpage : 20; + $result['dateformat'] = isset($dateFormat) && $dateFormat != '' ? $dateFormat : 'M d, Y'; + return $result; + } + + /** + * + * @param String $itemKey + * @param array $fields + * @return Boolean + */ + function removeItem($itemKey,$fields) { + $removedField = false; + for ($i=0;$i<count($fields);$i++){ + if ($fields[$i]['name']==$itemKey){ + unset($fields[$i]); + $removedField = true; + } + } + $fields = array_values($fields); + //$fields = calculateGridIndex( $fields ); + return ( $fields ); + } + + /** + * + * @param Array $fields + * @return Array + * + */ + function calculateGridIndex( $fields ) { + for ( $i=0;$i<count( $fields );$i++ ) { + $fields[$i]['gridIndex']=$i+1; + } + return ( $fields ); + } \ No newline at end of file diff --git a/workflow/engine/methods/cases/proxyProcessList.php b/workflow/engine/methods/cases/proxyProcessList.php new file mode 100755 index 000000000..c0d85ac06 --- /dev/null +++ b/workflow/engine/methods/cases/proxyProcessList.php @@ -0,0 +1,67 @@ +<?php + $callback = isset($_POST['callback']) ? $_POST['callback'] : 'stcCallback1001'; + $dir = isset($_POST['dir']) ? $_POST['dir'] : 'DESC'; + $sort = isset($_POST['sort']) ? $_POST['sort'] : ''; + $query = isset($_POST['query']) ? $_POST['query'] : ''; + //$action = isset($_GET['action']) ? $_GET['action'] : 'read'; + $option = ''; + if ( isset($_GET['t'] ) ) $option = $_GET['t']; + try { + + G::LoadClass("BasePeer" ); + require_once ( "classes/model/Process.php" ); + require_once ( "classes/model/AppCacheView.php" ); + + $sUIDUserLogged = $_SESSION['USER_LOGGED']; + + $Criteria = new Criteria('workflow'); + + $Criteria->clearSelectColumns ( ); + $Criteria->setDistinct(); + $Criteria->addSelectColumn ( AppCacheViewPeer::PRO_UID ); + $Criteria->addSelectColumn ( AppCacheViewPeer::APP_PRO_TITLE ); + + if ( $query != '' ) { + $Criteria->add (AppCacheViewPeer::APP_PRO_TITLE, $query . '%', Criteria::LIKE); + } + + $Criteria->add (AppCacheViewPeer::APP_STATUS, "TO_DO" , CRITERIA::EQUAL ); + $Criteria->add (AppCacheViewPeer::USR_UID, $sUIDUserLogged); + + + //$totalCount = AppCacheViewPeer::doCount( $Criteria ); + + if ( isset($limit) ) $Criteria->setLimit( $limit ); + if ( isset($start) ) $Criteria->setOffset( $start ); + + if ( $sort != '' ) { + if ( $dir == 'DESC' ) + $Criteria->addDescendingOrderByColumn( $sort ); + else + $Criteria->addAscendingOrderByColumn( $sort ); + } + $oDataset = AppCacheViewPeer::doSelectRS($Criteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + + $result = array(); + $rows = array(); + $index = isset($start) ? $start : 0; + while($aRow = $oDataset->getRow()){ + $aRow['index'] = ++$index; + $rows[] = $aRow; + + $oDataset->next(); + } + $result['totalCount'] = count($rows); + $result['data'] = $rows; + + print G::json_encode( $result ) ; + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } diff --git a/workflow/engine/methods/cases/proxyReassignCasesList.php b/workflow/engine/methods/cases/proxyReassignCasesList.php new file mode 100644 index 000000000..14156552d --- /dev/null +++ b/workflow/engine/methods/cases/proxyReassignCasesList.php @@ -0,0 +1,143 @@ +<?php + $callback = isset($_POST['callback']) ? $_POST['callback'] : 'stcCallback1001'; + $dir = isset($_POST['dir']) ? $_POST['dir'] : 'DESC'; + $sort = isset($_POST['sort']) ? $_POST['sort'] : ''; + $start = isset($_POST['start']) ? $_POST['start'] : '0'; + $limit = isset($_POST['limit']) ? $_POST['limit'] : '25'; + $filter = isset($_POST['filter']) ? $_POST['filter'] : ''; + $search = isset($_POST['search']) ? $_POST['search'] : ''; + $process = isset($_POST['process']) ? $_POST['process'] : ''; + $user = isset($_POST['user']) ? $_POST['user'] : ''; + $status = isset($_POST['status']) ? strtoupper($_POST['status']) : ''; + $action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : 'todo'); + $type = isset($_GET['type']) ? $_GET['type'] : (isset($_POST['type']) ? $_POST['type'] : 'extjs'); + $user = isset($_POST['user']) ? $_POST['user'] : ''; + + $sentUids = explode( ',', $_POST['APP_UIDS'] ); + + $allUidsRecords = array(); + $allTasUids = array(); + $nonDuplicateAppUids = array(); + // getting all App Uids and task Uids + foreach ($sentUids as $sentUid){ + $aItem = explode('|',$sentUid); + $allUidsRecords[] = array ( 'APP_UID' => $aItem[0] , 'TAS_UID' => $aItem[1], 'DEL_INDEX' => $aItem[2]); +// $allUidsRecords[] = array ( 'APP_UID' => $aItem[0] , 'TAS_UID' => $aItem[1] ); + } + // filtering the cases with duplicated TasUids + foreach ($sentUids as $sentUid){ + $aItem = explode('|',$sentUid); + if (!in_array($aItem[1],$allTasUids)){ + $nonDuplicateAppUids[] = array ( 'APP_UID' => $aItem[0] , 'TAS_UID' => $aItem[1], 'DEL_INDEX' => $aItem[2]); + $allTasUids[] = $aItem[1]; + } + } + + $sReassignFromUser = isset($_POST['user']) ? $_POST['user'] : ''; + $sProcessUid = isset($_POST['process']) ? $_POST['process'] : ''; + + G::LoadClass( 'tasks' ); + G::LoadClass( 'groups' ); + G::LoadClass( 'case' ); + G::LoadClass( 'users' ); + require_once ( "classes/model/AppCacheView.php" ); + + $oTasks = new Tasks (); + $oGroups = new Groups (); + $oUser = new Users (); + $oCases = new Cases (); + +// $oAppCache = new AppCacheView(); +// $oCriteria = $oAppCache->getToReassignListCriteria(); +//// $oCriteria->( AppCacheViewPeer::APP_TAS_TITLE ); +// $oCriteria->add(AppCacheViewPeer::PRO_UID, $sProcessUid); +// $oCriteria->add(AppCacheViewPeer::USR_UID, $sReassignFromUser); +// $oCriteria->addGroupByColumn(AppCacheViewPeer::APP_TAS_TITLE); +//// $oCriteria->setDistinct(); +// +// $oDataset = AppCacheViewPeer::doSelectRS($oCriteria); +// $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +// $oDataset->next(); +// $APP_UIDS = array(); +// +// while($aRow = $oDataset->getRow()){ +// $APP_UIDS[] = $aRow['APP_UID']; +// $oDataset->next(); +// } + $aCasesList = Array(); + + foreach ( $nonDuplicateAppUids as $aRecord ) { + $APP_UID = $aRecord['APP_UID']; + $delIndex = $aRecord['DEL_INDEX']; + $aCase = $oCases->loadCaseByDelegation($APP_UID,$delIndex); + + $aUsersInvolved = Array(); + $aCaseGroups = $oTasks->getGroupsOfTask($aCase['TAS_UID'], 1); + + foreach ( $aCaseGroups as $aCaseGroup ) { + $aCaseUsers = $oGroups->getUsersOfGroup($aCaseGroup['GRP_UID']); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); + $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; +// $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; +// $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } + } + + $aCaseUsers = $oTasks->getUsersOfTask($aCase['TAS_UID'], 1); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); +// $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; +// $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; +// $aUsersInvolved[$aCaseUser['USR_UID']] = $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']; // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } +// $oTmp = new stdClass(); +// $oTmp->items = $aUsersInvolved; + $oTmp = $aUsersInvolved; +// $oTmp->id = $aCase['APP_UID']; + $aCase['USERS'] = $oTmp; + array_push($aCasesList, $aCase); + } + + $filedNames = Array ( + "APP_UID", + "APP_NUMBER", + "APP_UPDATE_DATE", + "DEL_PRIORITY", + "DEL_INDEX", + "TAS_UID", + "DEL_INIT_DATE", + "DEL_FINISH_DATE", + "USR_UID", + "APP_STATUS", + "DEL_TASK_DUE_DATE", + "APP_CURRENT_USER", + "APP_TITLE", + "APP_PRO_TITLE", + "APP_TAS_TITLE", + "APP_DEL_PREVIOUS_USER", + "USERS" + ); + + $aCasesList = array_merge(Array($filedNames), $aCasesList); + $rows = array(); + $i = $start; + for ($j=0;$j<$limit;$j++){ + $i++; + if (isset($aCasesList[$i])){ + $rows[] = $aCasesList[$i]; + } + } + $totalCount = count($aCasesList)-1; + $result = array(); + $result['totalCount'] = $totalCount; + + $index = $start; + $result['data'] = $rows; + //print the result in json format + print G::json_encode( $result ) ; diff --git a/workflow/engine/methods/cases/proxyReassignUsersList.php b/workflow/engine/methods/cases/proxyReassignUsersList.php new file mode 100644 index 000000000..baaabd03f --- /dev/null +++ b/workflow/engine/methods/cases/proxyReassignUsersList.php @@ -0,0 +1,77 @@ +<?php + $callback = isset($_POST['callback']) ? $_POST['callback'] : 'stcCallback1001'; + $dir = isset($_POST['dir']) ? $_POST['dir'] : 'DESC'; + $sort = isset($_POST['sort']) ? $_POST['sort'] : ''; + $start = isset($_POST['start']) ? $_POST['start'] : '0'; + $limit = isset($_POST['limit']) ? $_POST['limit'] : '25'; + $filter = isset($_POST['filter']) ? $_POST['filter'] : ''; + $search = isset($_POST['search']) ? $_POST['search'] : ''; + $process = isset($_POST['process']) ? $_POST['process'] : ''; + $user = isset($_POST['user']) ? $_POST['user'] : ''; + $status = isset($_POST['status']) ? strtoupper($_POST['status']) : ''; + $action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : 'todo'); + $type = isset($_GET['type']) ? $_GET['type'] : (isset($_POST['type']) ? $_POST['type'] : 'extjs'); + $user = isset($_POST['user']) ? $_POST['user'] : ''; + +// $APP_UIDS = explode(',', $_POST['APP_UID']); + + $appUid = isset($_POST['application']) ? $_POST['application'] : ''; +// $processUid = isset($_POST['process']) ? $_POST['process'] : ''; +// $TaskUid = isset($_POST['task']) ? $_POST['task'] : ''; + $sReassignFromUser = isset($_POST['user']) ? $_POST['user'] : ''; + + G::LoadClass('tasks'); + G::LoadClass('groups'); + G::LoadClass('case'); + G::LoadClass('users'); + + $oTasks = new Tasks(); + $oGroups = new Groups(); + $oUser = new Users(); + $oCases = new Cases(); + + $aCasesList = Array(); + +// foreach ( $APP_UIDS as $APP_UID ) { + $aCase = $oCases->loadCaseInCurrentDelegation($appUid); + + $aUsersInvolved = Array(); + $aCaseGroups = $oTasks->getGroupsOfTask($aCase['TAS_UID'], 1); + + G::loadClass('configuration'); + $oConfig = new Configuration(); + try { + $aConfig = $oConfig->load('ENVIRONMENT_SETTINGS'); + $aConfig = unserialize($aConfig['CFG_VALUE']); + } catch (Exception $e){ + // if there is no configuration record then. + $aConfig['format'] = '@userName'; + } + +// var_dump($aConfig); + foreach ( $aCaseGroups as $aCaseGroup ) { + $aCaseUsers = $oGroups->getUsersOfGroup($aCaseGroup['GRP_UID']); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); + $sCaseUser = G::getFormatUserList ($aConfig['format'],$aCaseUserRecord); +// $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $sCaseUser); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } + } + + $aCaseUsers = $oTasks->getUsersOfTask($aCase['TAS_UID'], 1); + foreach ( $aCaseUsers as $aCaseUser ) { + if ( $aCaseUser['USR_UID'] != $sReassignFromUser ) { + $aCaseUserRecord = $oUser->load($aCaseUser['USR_UID']); + $sCaseUser = G::getFormatUserList ($aConfig['format'],$aCaseUserRecord); +// $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $aCaseUserRecord['USR_FIRSTNAME'] . ' ' . $aCaseUserRecord['USR_LASTNAME']); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + $aUsersInvolved[] = array ( 'userUid' => $aCaseUser['USR_UID'] , 'userFullname' => $sCaseUser); // . ' (' . $aCaseUserRecord['USR_USERNAME'] . ')'; + } + } +// $oTmp = new stdClass(); +// $oTmp->items = $aUsersInvolved; + $result = array(); + $result['data'] = $aUsersInvolved; + print G::json_encode( $result ) ; diff --git a/workflow/engine/methods/cases/proxySaveReassignCasesList.php b/workflow/engine/methods/cases/proxySaveReassignCasesList.php new file mode 100644 index 000000000..0e906177b --- /dev/null +++ b/workflow/engine/methods/cases/proxySaveReassignCasesList.php @@ -0,0 +1,131 @@ +<?php +/** + * proxySaveReassignCasesList.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $aData = json_decode($_POST['data']); + $appSelectedUids = array (); + $items = explode(",",$_POST['APP_UIDS']); + foreach ($items as $item) { + $dataUids = explode("|",$item); + $appSelectedUids[] = $dataUids[0]; + } + +// var_dump($aData); +//var_dump($appSelectedUids); + $casesReassignedCount = 0; + $serverResponse = array(); + G::LoadClass ('case'); + $oCases = new Cases(); + require_once ('classes/model/Task.php'); + require_once ('classes/model/AppCacheView.php'); + $oAppCacheView = new AppCacheView(); + $oCasesReassignList = $oAppCacheView->getToReassignListCriteria(); + if (isset($_POST['selected'])&&$_POST['selected']=='true'){ + $oCasesReassignList->add(AppCacheViewPeer::APP_UID,$appSelectedUids,Criteria::IN); + } + // if there are no records to save return -1 + if (empty($aData)){ + $serverResponse['TOTAL']=-1; + echo G::json_encode($serverResponse); + die(); + } +// $params = array (); +// $sql = BasePeer::createSelectSql($oCasesReassignList, $params); +// var_dump($sql); + if (is_array($aData)){ + foreach ($aData as $data){ + $oTmpReassignCriteria = $oCasesReassignList; + $oTmpReassignCriteria->add(AppCacheViewPeer::TAS_UID,$data->TAS_UID); + $rs = AppCacheViewPeer::doSelectRS($oTmpReassignCriteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $currentCasesReassigned=0; + while (is_array($row)) { + $APP_UID = $row['APP_UID']; + $aCase = $oCases->loadCaseInCurrentDelegation($APP_UID); + $oCases->reassignCase($aCase['APP_UID'], $aCase['DEL_INDEX'], $aCase['USR_UID'], $data->APP_REASSIGN_USER_UID); +// var_dump($aCase); +// echo ("<br>"); + $currentCasesReassigned++; + $casesReassignedCount++; + $rs->next(); + $row = $rs->getRow(); + } + $serverResponse[] = array ('TAS_TITLE'=>$data->APP_TAS_TITLE,'REASSIGNED_CASES'=>$currentCasesReassigned); + } + } else { + $oTmpReassignCriteria = $oCasesReassignList; + $oTmpReassignCriteria->add(AppCacheViewPeer::TAS_UID,$aData->TAS_UID); + $rs = AppCacheViewPeer::doSelectRS($oTmpReassignCriteria); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $currentCasesReassigned=0; + while (is_array($row)) { + $APP_UID = $row['APP_UID']; + $aCase = $oCases->loadCaseInCurrentDelegation($APP_UID); + $oCases->reassignCase($aCase['APP_UID'], $aCase['DEL_INDEX'], $aCase['USR_UID'], $aData->APP_REASSIGN_USER_UID); + $currentCasesReassigned++; + $casesReassignedCount++; +// var_dump($aCase); +// echo ("<br>"); + $rs->next(); + $row = $rs->getRow(); + } + $serverResponse[] = array ('TAS_TITLE'=>$aData->APP_TAS_TITLE,'REASSIGNED_CASES'=>$currentCasesReassigned); + } + + $serverResponse['TOTAL'] = $casesReassignedCount; + echo G::json_encode($serverResponse); +// $oTask = new Task(); +// $oCases = new Cases(); +// $aCases = Array(); +// +// if( isset($_POST['items']) && trim($_POST['items']) != '' ){ +// $sItems = $_POST['items']; +// $aItems = explode(',', $sItems); +// $FROM_USR_UID = $_POST['USR_UID']; +// +// foreach($aItems as $item){ +// list($APP_UID, $USR_UID) = explode('|', $item); +// $aCase = $oCases->loadCaseInCurrentDelegation($APP_UID); +// $oCase->reassignCase($aCase['APP_UID'], $aCase['DEL_INDEX'], $FROM_USR_UID, $USR_UID); +// array_push($aCases, $aCase); +// } +// require_once 'classes/model/Users.php'; +// $oUser = new Users(); +// $sText = ''; +// foreach ($aCases as $aCase) { +// $aCaseUpdated = $oCases->loadCaseInCurrentDelegation($aCase['APP_UID']); +// $aUser = $oUser->load($aCaseUpdated['USR_UID']); +// $sText .= $aCaseUpdated['APP_PRO_TITLE'] .' - '. ' Case: ' . $aCaseUpdated['APP_NUMBER'] . '# (' . $aCaseUpdated['APP_TAS_TITLE'] . ') <b> => Reassigned to => </b> <font color="blue">' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . ' [' . $aUser['USR_USERNAME'] . ']' . '</font><br />'; +// } +// +// $G_PUBLISH = new Publisher; +// $aMessage['MESSAGE'] = $sText; +// $aMessage['URL'] = 'cases_ReassignByUser?REASSIGN_USER=' . $_POST['USR_UID']; +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'cases/cases_ReassignShowInfo', '', $aMessage); +// G::RenderPage('publish', 'raw'); +// } +?> diff --git a/workflow/engine/methods/controls/buscador.php b/workflow/engine/methods/controls/buscador.php new file mode 100644 index 000000000..fd1845d73 --- /dev/null +++ b/workflow/engine/methods/controls/buscador.php @@ -0,0 +1,50 @@ +<? +/** + * buscador.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $frm = $HTTP_GET_VARS; + +?> + +<h1>demo de buscador</h1> +<form method=post action="buscador2.php"> +<input type=hidden name=ticket value="<?= $frm['ticket'] ?>" > +<input type=hidden name=tipo value="<?= $frm['tipo'] ?>" > +Buscador tipo : <?= $frm['tipo'] ?><br> + +<table><tr><td> + curso</td><td> + <select name=curso> + <option value="curso1">Curso 1</option> + <option value="curso2">Curso 2</option> + <option value="curso3">Curso 3</option> + <option value="curso4">Curso 4</4option> + <option value="curso5">Curso 5</option> +</td></tr> +<tr><td colspan=2> +<input type=submit ></td></tr> +</table> +</form> +</body> +</html> + diff --git a/workflow/engine/methods/controls/buscador2.php b/workflow/engine/methods/controls/buscador2.php new file mode 100644 index 000000000..2f151c148 --- /dev/null +++ b/workflow/engine/methods/controls/buscador2.php @@ -0,0 +1,38 @@ +demo de buscador<br> +/** + * buscador2.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +<? + $frm = $HTTP_POST_VARS; + + $dbc = new dbconnection(); + $ses = new DBSession($dbc); + $sql = "update tickets set tipo = ' " . $frm['tipo'] ."', resultado = ' " . $frm['curso'] . "' where ticket = '" . $frm['ticket'] ."' "; + $ses->Execute ( $sql ); +?> +<script language = "JavaScript"> + window.close(); + +</script> + + diff --git a/workflow/engine/methods/controls/calendar.js b/workflow/engine/methods/controls/calendar.js new file mode 100644 index 000000000..699b00378 --- /dev/null +++ b/workflow/engine/methods/controls/calendar.js @@ -0,0 +1,162 @@ +// Title: Tigra Calendar +// URL: http://www.softcomplex.com/products/tigra_calendar/ +// Version: 3.2 (European date format) +// Date: 10/14/2002 (mm/dd/yyyy) +// Feedback: feedback@softcomplex.com (specify product title in the subject) +// Note: Permission given to use this script in ANY kind of applications if +// header lines are left unchanged. +// Note: Script consists of two files: calendar?.js and calendar.html +// About us: Our company provides offshore IT consulting services. +// Contact us at sales@softcomplex.com if you have any programming task you +// want to be handled by professionals. Our typical hourly rate is $20. + +// if two digit year input dates after this year considered 20 century. +var NUM_CENTYEAR = 30; +// is time input control required by default +var BUL_TIMECOMPONENT = false; +// are year scrolling buttons required by default +var BUL_YEARSCROLL = true; + +var calendars = []; +var RE_NUM = /^\-?\d+$/; + +function calendar1(obj_target) { + + // assing methods + this.gen_date = cal_gen_date1; + this.gen_time = cal_gen_time1; + this.gen_tsmp = cal_gen_tsmp1; + this.prs_date = cal_prs_date1; + this.prs_time = cal_prs_time1; + this.prs_tsmp = cal_prs_tsmp1; + this.popup = cal_popup1; + this.fecha = "0"; + + // validate input parameters + if (!obj_target) + return cal_error("Error calling the calendar: no target control specified"); + if (obj_target.value == null) + return cal_error("Error calling the calendar: parameter specified is not valid tardet control"); + this.target = obj_target; + this.time_comp = BUL_TIMECOMPONENT; + this.year_scroll = BUL_YEARSCROLL; + + // register in global collections + this.id = calendars.length; + calendars[this.id] = this; +} + +function cal_popup1 (str_datetime) { + this.dt_current = this.prs_tsmp(str_datetime ? str_datetime : this.target.value); + if (!this.dt_current) return; + + var obj_calwindow = window.open( + 'calendar.html?datetime=' + this.dt_current.valueOf()+ '&id=' + this.id, + 'Calendar', 'width=200,height='+(this.time_comp ? 215 : 190)+ + ',status=no,resizable=no,top=200,left=200,dependent=yes,alwaysRaised=yes' + ); + obj_calwindow.opener = window; + obj_calwindow.focus(); + + + +} + +// timestamp generating function +function cal_gen_tsmp1 (dt_datetime) { + return(this.gen_date(dt_datetime) + ' ' + this.gen_time(dt_datetime)); +} + +// date generating function +function cal_gen_date1 (dt_datetime) { + return ( + (dt_datetime.getDate() < 10 ? '0' : '') + dt_datetime.getDate() + "-" + + (dt_datetime.getMonth() < 9 ? '0' : '') + (dt_datetime.getMonth() + 1) + "-" + + dt_datetime.getFullYear() + ); +} +// time generating function +function cal_gen_time1 (dt_datetime) { + return ( + (dt_datetime.getHours() < 10 ? '0' : '') + dt_datetime.getHours() + ":" + + (dt_datetime.getMinutes() < 10 ? '0' : '') + (dt_datetime.getMinutes()) + ":" + + (dt_datetime.getSeconds() < 10 ? '0' : '') + (dt_datetime.getSeconds()) + ); +} + +// timestamp parsing function +function cal_prs_tsmp1 (str_datetime) { + // if no parameter specified return current timestamp + if (!str_datetime) + return (new Date()); + + // if positive integer treat as milliseconds from epoch + if (RE_NUM.exec(str_datetime)) + return new Date(str_datetime); + + // else treat as date in string format + var arr_datetime = str_datetime.split(' '); + return this.prs_time(arr_datetime[1], this.prs_date(arr_datetime[0])); +} + +// date parsing function +function cal_prs_date1 (str_date) { + + var arr_date = str_date.split('-'); + + if (arr_date.length != 3) return cal_error ("Invalid date format: '" + str_date + "'.\nFormat accepted is dd-mm-yyyy."); + if (!arr_date[0]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo day of month value can be found."); + if (!RE_NUM.exec(arr_date[0])) return cal_error ("Invalid day of month value: '" + arr_date[0] + "'.\nAllowed values are unsigned integers."); + if (!arr_date[1]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo month value can be found."); + if (!RE_NUM.exec(arr_date[1])) return cal_error ("Invalid month value: '" + arr_date[1] + "'.\nAllowed values are unsigned integers."); + if (!arr_date[2]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo year value can be found."); + if (!RE_NUM.exec(arr_date[2])) return cal_error ("Invalid year value: '" + arr_date[2] + "'.\nAllowed values are unsigned integers."); + + var dt_date = new Date(); + dt_date.setDate(1); + + if (arr_date[1] < 1 || arr_date[1] > 12) return cal_error ("Invalid month value: '" + arr_date[1] + "'.\nAllowed range is 01-12."); + dt_date.setMonth(arr_date[1]-1); + + if (arr_date[2] < 100) arr_date[2] = Number(arr_date[2]) + (arr_date[2] < NUM_CENTYEAR ? 2000 : 1900); + dt_date.setFullYear(arr_date[2]); + + var dt_numdays = new Date(arr_date[2], arr_date[1], 0); + dt_date.setDate(arr_date[0]); + if (dt_date.getMonth() != (arr_date[1]-1)) return cal_error ("Invalid day of month value: '" + arr_date[0] + "'.\nAllowed range is 01-"+dt_numdays.getDate()+"."); + + return (dt_date) +} + +// time parsing function +function cal_prs_time1 (str_time, dt_date) { + + if (!dt_date) return null; + var arr_time = String(str_time ? str_time : '').split(':'); + + if (!arr_time[0]) dt_date.setHours(0); + else if (RE_NUM.exec(arr_time[0])) + if (arr_time[0] < 24) dt_date.setHours(arr_time[0]); + else return cal_error ("Invalid hours value: '" + arr_time[0] + "'.\nAllowed range is 00-23."); + else return cal_error ("Invalid hours value: '" + arr_time[0] + "'.\nAllowed values are unsigned integers."); + + if (!arr_time[1]) dt_date.setMinutes(0); + else if (RE_NUM.exec(arr_time[1])) + if (arr_time[1] < 60) dt_date.setMinutes(arr_time[1]); + else return cal_error ("Invalid minutes value: '" + arr_time[1] + "'.\nAllowed range is 00-59."); + else return cal_error ("Invalid minutes value: '" + arr_time[1] + "'.\nAllowed values are unsigned integers."); + + if (!arr_time[2]) dt_date.setSeconds(0); + else if (RE_NUM.exec(arr_time[2])) + if (arr_time[2] < 60) dt_date.setSeconds(arr_time[2]); + else return cal_error ("Invalid seconds value: '" + arr_time[2] + "'.\nAllowed range is 00-59."); + else return cal_error ("Invalid seconds value: '" + arr_time[2] + "'.\nAllowed values are unsigned integers."); + + dt_date.setMilliseconds(0); + return dt_date; +} + +function cal_error (str_message) { + alert (str_message); + return null; +} diff --git a/workflow/engine/methods/controls/calendar.php b/workflow/engine/methods/controls/calendar.php new file mode 100644 index 000000000..f96d1b780 --- /dev/null +++ b/workflow/engine/methods/controls/calendar.php @@ -0,0 +1,185 @@ +<style> +/** + * calendar.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + td {font-family: Tahoma, Verdana, sans-serif; font-size: 12px;} +</style> +<script language="JavaScript"> + +// months as they appear in the calendar's title +var ARR_MONTHS = ["January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"]; +// week day titles as they appear on the calendar +var ARR_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; +// day week starts from (normally 0-Su or 1-Mo) +var NUM_WEEKSTART = 1; +// path to the directory where calendar images are stored. trailing slash req. +var STR_ICONPATH = '/images/calendar/'; + +var re_url = new RegExp('datetime=(\\-?\\d+)'); +var dt_current = (re_url.exec(String(window.location)) + ? new Date(new Number(RegExp.$1)) : new Date()); +var re_id = new RegExp('id=(\\d+)'); +var num_id = (re_id.exec(String(window.location)) + ? new Number(RegExp.$1) : 0); +var obj_caller = (window.opener ? window.opener.calendars[num_id] : null); + +if (obj_caller && obj_caller.year_scroll) { + // get same date in the previous year + var dt_prev_year = new Date(dt_current); + dt_prev_year.setFullYear(dt_prev_year.getFullYear() - 1); + if (dt_prev_year.getDate() != dt_current.getDate()) + dt_prev_year.setDate(0); + + // get same date in the next year + var dt_next_year = new Date(dt_current); + dt_next_year.setFullYear(dt_next_year.getFullYear() + 1); + if (dt_next_year.getDate() != dt_current.getDate()) + dt_next_year.setDate(0); +} + +// get same date in the previous month +var dt_prev_month = new Date(dt_current); +dt_prev_month.setMonth(dt_prev_month.getMonth() - 1); +if (dt_prev_month.getDate() != dt_current.getDate()) + dt_prev_month.setDate(0); + +// get same date in the next month +var dt_next_month = new Date(dt_current); +dt_next_month.setMonth(dt_next_month.getMonth() + 1); +if (dt_next_month.getDate() != dt_current.getDate()) + dt_next_month.setDate(0); + +// get first day to display in the grid for current month +var dt_firstday = new Date(dt_current); +dt_firstday.setDate(1); +dt_firstday.setDate(1 - (7 + dt_firstday.getDay() - NUM_WEEKSTART) % 7); + +// function passing selected date to calling window +function set_datetime(n_datetime, b_close) { + if (!obj_caller) return; + + var dt_datetime = obj_caller.prs_time( + (document.cal ? document.cal.time.value : ''), + new Date(n_datetime) + ); + + if (!dt_datetime) return; + if (b_close) { + window.close(); + obj_caller.fecha = (document.cal + ? obj_caller.gen_tsmp(dt_datetime) + : obj_caller.gen_date(dt_datetime) + ); + var arr_date = obj_caller.fecha.split('-'); + obj_caller.date1.value = arr_date[0]; + obj_caller.date2.value = arr_date[1]; + obj_caller.date3.value = arr_date[2]; + } + else obj_caller.popup(dt_datetime.valueOf()); +} + +</script> + +<php + $ARR_MONTHS = array ( "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"); + $ARR_WEEKDAYS = array ( "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ); + $NUM_WEEKSTART = 1; //day week starts from (normally 0-Su or 1-Mo) + +?> +<table class="clsOTable" cellspacing="0" border="0" width="100%"> +<tr><td bgcolor="#4682B4"> +<table cellspacing="1" cellpadding="3" border="0" width="100%"> +<tr><td colspan="7"><table cellspacing="0" cellpadding="0" border="0" width="100%"> +<tr> + <td> +(obj_caller&&obj_caller.year_scroll?'<a href="javascript:set_datetime('+dt_prev_year.valueOf()+')"> + <img src="'+STR_ICONPATH+'prev_year.gif" width="16" height="16" border="0" alt="previous year"></a> ':'')+' + <a href="javascript:set_datetime('+dt_prev_month.valueOf()+')"> + <img src="'+STR_ICONPATH+'prev.gif" width="16" height="16" border="0" alt="previous month"></a> + </td> + + <td align="center" width="100%"> + <font color="#ffffff"> +ARR_MONTHS[dt_current.getMonth()]+' '+dt_current.getFullYear() </font></td> + <td><a href="javascript:set_datetime('+dt_next_month.valueOf()+')"> + <img src="'+STR_ICONPATH+'next.gif" width="16" height="16" border="0" alt="next month"></a> + '+(obj_caller && obj_caller.year_scroll?'  + <a href="javascript:set_datetime('+dt_next_year.valueOf()+')"> + <img src="'+STR_ICONPATH+'next_year.gif" width="16" height="16" border="0" alt="next year"> + </a>':'')+' + </td>' +); + +</tr> +</table></td></tr> +<tr> +<script language="JavaScript"> +<? + // print weekdays titles + for ($n=0; $n<7; $n++) + print "<td bgcolor='#87cefa' align='center'><font color='#ffffff'>" . $ARR_WEEKDAYS[ (NUM_WEEKSTART+n)%7] . "</font></td>"; + print "</tr>"; + +?> +// print calendar table + +var dt_current_day = new Date(dt_firstday); +while (dt_current_day.getMonth() == dt_current.getMonth() || + dt_current_day.getMonth() == dt_firstday.getMonth()) { + // print row heder + document.write('<tr>'); + for (var n_current_wday=0; n_current_wday<7; n_current_wday++) { + if (dt_current_day.getDate() == dt_current.getDate() && + dt_current_day.getMonth() == dt_current.getMonth()) + // print current date + document.write('<td bgcolor="#ffb6c1" align="center" width="14%">'); + else if (dt_current_day.getDay() == 0 || dt_current_day.getDay() == 6) + // weekend days + document.write('<td bgcolor="#dbeaf5" align="center" width="14%">'); + else + // print working days of current month + document.write('<td bgcolor="#ffffff" align="center" width="14%">'); + + document.write('<a href="javascript:set_datetime('+dt_current_day.valueOf() +', true);">'); + + if (dt_current_day.getMonth() == this.dt_current.getMonth()) + // print days of current month + document.write('<font color="#000000">'); + else + // print days of other months + document.write('<font color="#606060">'); + + document.write(dt_current_day.getDate()+'</font></a></td>'); + dt_current_day.setDate(dt_current_day.getDate()+1); + } + // print row footer + document.write('</tr>'); +} +if (obj_caller && obj_caller.time_comp) + document.write('<form onsubmit="javascript:set_datetime('+dt_current.valueOf()+', true)" name="cal"><tr><td colspan="7" bgcolor="#87CEFA"><font color="White" face="tahoma, verdana" size="2">Time: <input type="text" name="time" value="'+obj_caller.gen_time(this.dt_current)+'" size="8" maxlength="8"></font></td></tr></form>'); +</script> +</table></tr></td> +</table> +</body> +</html> + diff --git a/workflow/engine/methods/controls/img/cal.gif b/workflow/engine/methods/controls/img/cal.gif new file mode 100644 index 0000000000000000000000000000000000000000..8526cf5d19a915aa8073cf344873c4505491970d GIT binary patch literal 127 zcmZ?wbhEHb6krfwSj51v)Yr?)cd3`J*V1K6uU)?O9}E~67!-f9FfuT(G3Wr<K$QXv z49qSWyY847oYHjLVc`>De9t*l<VeJ%XBvy%RED|e9CzS7vf7$yx78AzI7g1zCv(i5 d_*Q7^L?2jGxayDN`t#4c54^3~-^9XT4FGnKF-ZUb literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/logo.gif b/workflow/engine/methods/controls/img/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..6b5397dd3184a4c4da9381063e5ef322fd0a8d2b GIT binary patch literal 660 zcmV;F0&D$8Nk%w1VX^=o0FeLy|NsBY%*<wHW&i*HEC2ui0I~oc00092gpaAq?KYyE zwAzca-n{$qgyOh-=82|iMz(IV#_~*q?|s+$&Rh83>IsLlMc^0!8j+%m;7N>1B?!Sq zpafVc$wL5(s0g}<@3aOsY=?&pa6R#E6I@5&JWFe%>W$uI0R~4WLFRxLqX*Xma5sVF zIAKT<8DU64IPlj{iD;t8x9C;3G&w5qhZz>3ur`SS^%48H2wSUJbv3K9_t=HRRAzB` z(JKaln=5H>v}oF?IHqh^87=&%j5=wCn&2wjcy+|!)K+|(9Fa<~+YRH+yda$rsb>m+ zeE@gQyu519%GiZT=-gotn9tHRKOx|~aLAxuHh!l9>a%eXV?lNQ6%}?$QtOG9MNhye z?3jVt$$rVoEb+!M*SeOy0IoFl$IzOE1N#)p7_(X?i^x=R;7MrRpDj9LvZT2M)Bs{s zI&ON3QO+%sajasUNfh5yo~YPm8+%b|R<Tf>;=Cr61gW7}$Dy>L>Z{&WRn3778ue^b zwV9-<wHbGWS$bUNB1G0VoI9a>!@5PNQZ3p(g!vlIhFF=mlB9QC70A}DD1l_)fT3(I zGFyT_Wg`8Tt*|niZF@H@JM0}RlFb%>lw2D&WRH+fD~M#&Xy@3UZSTG=M-v%tG`}oF zuHkGTuaynfevt2wYS|70KadENBK2#(vGy##crVbd`N{QdSCF1Dx@F`XP@2it)qJ^R zH=Yq<Y!jeQ{IPRSC;o^xU31u}VN`qnVfEWhca$Pu8Ft|SOl*O)<HSaZ?B-&NF}jgO ujU{-Zf@U~YU}KN??bv~iK+5K07DJvO<dH@Cc;qMIHMwMuO-@Ne0RTG_u0rzw literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/next.gif b/workflow/engine/methods/controls/img/next.gif new file mode 100644 index 0000000000000000000000000000000000000000..bf0215277434ed78f8099712c46eb55cc5f606fa GIT binary patch literal 214 zcmZ?wbhEHb6krfw*v!DN>dvp0Q(yhMc2(_uJnPDj&YkyiR$Y#mcBFXYt;9Jec0T-7 zci?5y(f4VK&vl>w>DIJG@h1xd2<U(akQodt%^yxq=L&3?VzOMrK_ji>L8IRSE53)* zgd}9n8tC{Ouwt94tLDg5c$!s${mKCoNioUZu!NfvWdyoe51FQh$zNwYcyK|TeDBc) zN3&{yg$zuNZ1Y4Ujw=;f7&Wn0NHRvLu~~{XB?oiJ@H4gR>S<>6#xa>jW-)WHvBwFs ObFwYroi8iMU=09xqE7k% literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/next_year.gif b/workflow/engine/methods/controls/img/next_year.gif new file mode 100644 index 0000000000000000000000000000000000000000..ac12ea1307e4d35ee401f358372b5c69c06fae88 GIT binary patch literal 256 zcmV+b0ssC-Nk%w1VGsZi0J8u9s@(d7%Joi)x_Z0gn$-A-x!!E5(^!_obFtcCoXEN1 z`hLLag2nG<qt1)Z`9^}YA^8Le000jFEC2ui01yBW000QB03Qf^ke~no1po*XNHB1q zfC2y_N=%4AfJ1{02m}b=AR_?+6$KhRP#^#U2MZVo>}Y@>00$NYAYi~z;6?@{0Wh#Q zaHc>43>Y-XxU*ryjvzl4H7fAH#{mRT@?=^d<A9S3rV8X4F#rMt4wgO;5K-XE1qlwA zj2TgZ0-Fm$8em|+0RXoN9RwJFfZ^D=9-{_Wz&F8E0SyK$SUiBQfdg8bCNMy`0px}O G0RTI#(phc* literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/pixel.gif b/workflow/engine/methods/controls/img/pixel.gif new file mode 100644 index 0000000000000000000000000000000000000000..46a2cf086ca4829b2afacec093d4562ec6c16f59 GIT binary patch literal 67 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3{X<>KewZczmuz#XON+u0n@#=42nNl7#SFt7<7PY Nfa*bPrVvI3YXHjL5YGSr literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/prev.gif b/workflow/engine/methods/controls/img/prev.gif new file mode 100644 index 0000000000000000000000000000000000000000..211e1faba1e22b37a9b329a020be9ce08999dfc9 GIT binary patch literal 212 zcmZ?wbhEHb6krfw*v!B%{nC#O_kOpW{NmreyJXX?s$GvFrXEROe6I2Eo7`2G+jrib zdHi|Lg<pwtj?cRG+pTGf;!hR^5YPb;ATt<P8b6%8F2a$x((HMF#Iqg-!;0<`9866d zJ(`UNyF^$DC3q$WFuHS3&zQqz+t{d}B4x#V{M837m3edBOI#U5Hbk!d@{BcoI|oye zibc!CPQ8RD9&=Oz9Tz4x7(P>Gb?3`e=hQK1V3g*muHe+`u+^?Ek78$?Im^N=k&Ty~ Mlhb+{zaWD(0895#mjD0& literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/prev_year.gif b/workflow/engine/methods/controls/img/prev_year.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8145d598f2651f4066f94885eec0c5525f7250a GIT binary patch literal 259 zcmV+e0sQ_)Nk%w1VGsZi0J8u9s@(d7%Joi)x_Z0gn$-A-x!!E5(^!_obFtcCoXEN1 z`hLLag2nG<qt1)Z`9^}YA^8Le000jFEC2ui01yBW000QE03Qf^ke~no015~cNHB1q z00ajCNSs(efJ2A`2sm&MAb>`N79SYcD3HMd2MhufIH2&sfs_FRa%6zOq5uZ~5;S1I zfIvwE4Fxa&Pyiyyh7Nl=7?AM*(xe%gIw<f|pn#JE5Co8D73o!!2~GkKC^6&%p$=*y zSP=7p0tIEyrgWMB!GHh`4!#B8zyJdSR_hL6n>Qm$17-yrFkpA^f&~K_n00udfq}~j JoDK{K06QEwT@wHR literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/img/tc.gif b/workflow/engine/methods/controls/img/tc.gif new file mode 100644 index 0000000000000000000000000000000000000000..576e14879b0a76f6a04c1bb694d1d067f3263621 GIT binary patch literal 8301 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ⅇ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 L7hVVhfY$#3MtD_> literal 0 HcmV?d00001 diff --git a/workflow/engine/methods/controls/varsAjax.php b/workflow/engine/methods/controls/varsAjax.php new file mode 100644 index 000000000..5cd0eb884 --- /dev/null +++ b/workflow/engine/methods/controls/varsAjax.php @@ -0,0 +1,162 @@ +<?php +/** + * varsAjax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadClass('xmlfield_InputPM'); +$aFields = getDynaformsVars($_POST['sProcess']); + +$sHTML = '<select name="_Var_Form_" id="_Var_Form_" size="' . count($aFields) . '" style="width:100%;' . (! isset($_POST['sNoShowLeyend']) ? 'height:50%;' : '') . '" ondblclick="insertFormVar(\'' . $_POST['sFieldName'] . '\', this.value);">'; +foreach ( $aFields as $aField ) { + $sHTML .= '<option value="' . $_POST['sSymbol'] . $aField['sName'] . '">' . $_POST['sSymbol'] . $aField['sName'] . ' (' . $aField['sType'] . ')</option>'; +} + +$aRows[0] = Array ( + 'fieldname' => 'char', + 'variable' => 'char', + 'type' => 'type', + 'label' => 'char' +); +foreach ( $aFields as $aField ) { + $aRows[] = Array ( + 'fieldname' => $_POST['sFieldName'], + 'variable' => $_POST['sSymbol'] . $aField['sName'], + 'variable_label' => '<div class="pm__dynavars"> <a id="dynalink" href=# onclick="insertFormVar(\''.$_POST['sFieldName'].'\',\''.$_POST['sSymbol'] . $aField['sName'].'\');">'.$_POST['sSymbol'] . $aField['sName'].'</a></div>', + 'type' => $aField['sType'], + 'label' => $aField['sLabel'] + ); +} + +$sHTML .= '</select>'; +$sHTML = ''; + +if (! isset($_POST['sNoShowLeyend'])) { + $sHTML = '<table width="100%">'; + $sHTML .= '<tr><td align="center" class="module_app_input___gray" colspan="2"><b>Variables cast prefix</b></td></tr>'; + if (isset($_POST['sType'])) { + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_ESC') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_NONEC') . '</td></tr>'; + /*$sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_EURL') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_EVAL') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_ESCJS') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_ESCSJS') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray">' . G::LoadTranslation('ID_FUNCTION') . '</td></tr>';*/ + } else { + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@@</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_TO_STRING') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@#</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_TO_FLOAT') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@%</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_TO_INTEGER') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@?</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_TO_URL') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@$</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_SQL_ESCAPE') . '</td></tr>'; + $sHTML .= '<tr><td class="module_app_input___gray" width="5%">@=</td><td class="module_app_input___gray">' . G::LoadTranslation('ID_REPLACE_WITHOUT_CHANGES') . '</td></tr>'; + } + $sHTML .= '<tr><td align="center" class="module_app_input___gray" colspan="2"> </td></tr>'; + //$sHTML .= '<tr><td align="center" class="module_app_input___gray" colspan="2">' . G::LoadTranslation('ID_DOCLICK') . '</td></tr>'; + $sHTML .= '</table>'; +} else { + // please don't remove this definition if there isn't some sort of html tags before the css styles aren't loaded in IE + $sHTML = '<table width="100%">'; + $sHTML .= '</table>'; +} +$sStyle = " <style type=\"text/css\"> + +.pm__dynavars a#dynalink{color:#000000;} + +/* begin css tabs */ +ul#tabnav { /* general settings */ +text-align: left; /* set to left, right or center */ +margin: 1em 0 1em 0; /* set margins as desired */ +font: bold 11px verdana, arial, sans-serif; /* set font as desired */ +border-bottom: 1px solid #ccc; /* set border COLOR as desired */ +list-style-type: none; +padding: 3px 10px 3px 10px; /* THIRD number must change with respect to padding-top (X) below */ +} + +ul#tabnav li { /* do not change */ +display: inline; +} + +div#all li.all, div#system li.system, div#process li.process, div#tab4 li.tab4 { /* settings for selected tab */ +border-bottom: 1px solid #fff; /* set border color to page background color */ +background-color: #fff; /* set background color to match above border color */ +} + +div#all li.all a, div#system li.system a, div#process li.process a, div#tab4 li.tab4 a { /* settings for selected tab link */ +background-color: #fff; /* set selected tab background color as desired */ +color: #000; /* set selected tab link color as desired */ +position: relative; +top: 1px; +padding-top: 4px; /* must change with respect to padding (X) above and below */ +} + +ul#tabnav li a { /* settings for all tab links */ +padding: 3px 4px; /* set padding (tab size) as desired; FIRST number must change with respect to padding-top (X) above */ +border: 1px solid #aaa; /* set border COLOR as desired; usually matches border color specified in #tabnav */ +background-color: #ccc; /* set unselected tab background color as desired */ +color: #666; /* set unselected tab link color as desired */ +margin-right: 10px; /* set additional spacing between tabs as desired */ +text-decoration: none; +border-bottom: none; +} + +ul#tabnav a:hover { /* settings for hover effect */ +background: #fff; /* set desired hover color */ +} + +/* end css tabs */ + +</style>"; +$cssTabs = "<div id=\"all\"> + <ul id=\"tabnav\"> + <li class=\"all\"><a href=\"#\" onclick=\"changeVariables('all','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">All variables</a></li> + <li class=\"system\"><a href=\"#\" onclick=\"changeVariables('system','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">System</a></li> + <li class=\"process\"><a href=\"#\" onclick=\"changeVariables('process','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">Process</a></li> + </ul> + </div> + "; +echo $sHTML; +echo $sStyle; + + +//////////////////////////////////////////////////////// + +echo "<div id=\"processVariablesContent\">"; +echo $cssTabs; +G::LoadClass('ArrayPeer'); + +global $_DBArray; +$_DBArray['dynavars'] = $aRows; +$_SESSION['_DBArray'] = $_DBArray; + +G::LoadClass('ArrayPeer'); +$oCriteria = new Criteria('dbarray'); +$oCriteria->setDBArrayTable('dynavars'); + +$aFields = array (); + +$G_PUBLISH = new Publisher(); +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptFile( "/jscore/controls/varsAjax.js" ); +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'triggers/dynavars', $oCriteria); +G::RenderPage('publish', 'raw'); + +echo "</div>"; +?> \ No newline at end of file diff --git a/workflow/engine/methods/controls/varsAjaxByType.php b/workflow/engine/methods/controls/varsAjaxByType.php new file mode 100644 index 000000000..e84f4c835 --- /dev/null +++ b/workflow/engine/methods/controls/varsAjaxByType.php @@ -0,0 +1,109 @@ +<?php +/** + * varsAjax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * @author Gustavo Cruz gustavo-at-colosa.com + * @param $_POST variables + * @desc the varAjaxByType file as the varAjax.php handle the render of the diferent + * types of dynaform variables there are 3 of them system, process, and the default + * that show both system and process variables. + * uses almost the same variables passed to varsAjax, plus $_POST['type'] that is the + * type of the variables. Then it render a propel table with all the variables + * loaded for that type. + */ + +G::LoadClass('xmlfield_InputPM'); +$aFields = getDynaformsVars($_POST['sProcess']); +$aType = $_POST['type']; + +$aRows[0] = Array ( + 'fieldname' => 'char', + 'variable' => 'char', + 'type' => 'type', + 'label' => 'char' +); +foreach ( $aFields as $aField ) { + switch ($aType){ + case "system": + if($aField['sType']=="system"){ + $aRows[] = Array ( + 'fieldname' => $_POST['sFieldName'], + 'variable' => $_POST['sSymbol'] . $aField['sName'], + 'variable_label' => '<div class="pm__dynavars"> <a id="dynalink" href=# onclick="insertFormVar(\''.$_POST['sFieldName'].'\',\''.$_POST['sSymbol'] . $aField['sName'].'\');">'.$_POST['sSymbol'] . $aField['sName'].'</a></div>', + 'type' => $aField['sType'], + 'label' => $aField['sLabel'] + ); + } + break; + case "process": + if($aField['sType']!="system"){ + $aRows[] = Array ( + 'fieldname' => $_POST['sFieldName'], + 'variable' => $_POST['sSymbol'] . $aField['sName'], + 'variable_label' => '<div class="pm__dynavars"> <a id="dynalink" href=# onclick="insertFormVar(\''.$_POST['sFieldName'].'\',\''.$_POST['sSymbol'] . $aField['sName'].'\');">'.$_POST['sSymbol'] . $aField['sName'].'</a></div>', + 'type' => $aField['sType'], + 'label' => $aField['sLabel'] + ); + } + break; + default: + $aRows[] = Array ( + 'fieldname' => $_POST['sFieldName'], + 'variable' => $_POST['sSymbol'] . $aField['sName'], + 'variable_label' => '<div class="pm__dynavars"> <a id="dynalink" href=# onclick="insertFormVar(\''.$_POST['sFieldName'].'\',\''.$_POST['sSymbol'] . $aField['sName'].'\');">'.$_POST['sSymbol'] . $aField['sName'].'</a></div>', + 'type' => $aField['sType'], + 'label' => $aField['sLabel'] + ); + break; + } + +} +// Use and make a load translation variable call to the titles of the tabs +$cssTabs = "<div id=\"".strtolower($_POST['type'])."\"> + <ul id=\"tabnav\"> + <li class=\"all\"><a href=\"#\" onclick=\"changeVariables('all','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">All variables</a></li> + <li class=\"system\"><a href=\"#\" onclick=\"changeVariables('system','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">System</a></li> + <li class=\"process\"><a href=\"#\" onclick=\"changeVariables('process','".$_POST['sProcess']."','".$_POST['sFieldName']."','".$_POST['sSymbol']."','processVariablesContent');\">Process</a></li> + </ul> + </div> + "; + +echo $cssTabs; +G::LoadClass('ArrayPeer'); + +global $_DBArray; +$_DBArray['dynavars'] = $aRows; +$_SESSION['_DBArray'] = $_DBArray; + +G::LoadClass('ArrayPeer'); +$oCriteria = new Criteria('dbarray'); +$oCriteria->setDBArrayTable('dynavars'); + +$aFields = array (); +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'triggers/dynavars', $oCriteria); +G::RenderPage('publish', 'raw'); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dashboard/dashboard.php b/workflow/engine/methods/dashboard/dashboard.php new file mode 100755 index 000000000..333e8ed01 --- /dev/null +++ b/workflow/engine/methods/dashboard/dashboard.php @@ -0,0 +1,76 @@ +<?php +/** + * dashboard.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess('PM_LOGIN'))!=1) return $RBAC_Response; + +global $RBAC; + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +try { + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'dashboard'; + $G_ID_MENU_SELECTED = 'DASHBOARD'; + + //Load dashboards class + G::LoadClass('dashboards'); + $oDashboards = new Dashboards(); + + //Show dashboards + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('smarty', 'dashboard/frontend', '', '', array('ID_NEW' => G::LoadTranslation('ID_NEW'))); + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/dashboard/core/dashboard.js'); + $oHeadPublisher->addInstanceModule('leimnud', 'dashboard'); + $oHeadPublisher->addScriptCode('leimnud.event.add(window,"load",function(){window.Da=new leimnud.module.dashboard();Da.make({target:$("dashboard"),data:' . $oDashboards->getDashboardsObject($_SESSION['USER_LOGGED']) . '});});'); + G::RenderPage('publish'); +} +catch ( Exception $e ) { + $aMessage = array(); + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage); + G::RenderPage('publish'); +} diff --git a/workflow/engine/methods/dashboard/dashboardAjax.php b/workflow/engine/methods/dashboard/dashboardAjax.php new file mode 100644 index 000000000..1c0246732 --- /dev/null +++ b/workflow/engine/methods/dashboard/dashboardAjax.php @@ -0,0 +1,168 @@ +<?php +/** + * dashboardAjax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess('PM_LOGIN'))!=1) return $RBAC_Response; + +G::LoadClass('dashboards'); +$oDashboards = new Dashboards(); + +switch ($_POST['action']) { + case 'showAvailableDashboards': + $aConfiguration = $oDashboards->getConfiguration($_SESSION['USER_LOGGED']); + $aShowAvailableDashboards = array(); + $aShowAvailableDashboards[] = array('DASH_CODE' => 'char', + 'DASH_LABEL' => 'char'); + //Load available ProcessMaker reports + G::LoadClass('report'); + $oReport = new Report(); + $aReports = $oReport->getAvailableReports(); + foreach ($aReports as $sReport) { + $bFree = true; + foreach ($aConfiguration as $aDashboard) { + if (($aDashboard['class'] == 'PM_Reports') && ($aDashboard['element'] == $sReport)) { + $bFree = false; + } + } + if ($bFree) { + $aShowAvailableDashboards[] = array('DASH_CODE' => 'PM_Reports^' . $sReport . '^REPORT', + 'DASH_LABEL' => 'PM_Reports - ' . G::LoadTranslation($sReport)); + } + } + //Load available charts + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $aAvailableDashboards = $oPluginRegistry->getDashboards(); + foreach ($aAvailableDashboards as $sDashboardClass) { + require_once PATH_PLUGINS. $sDashboardClass . PATH_SEP . 'class.' . $sDashboardClass . '.php'; + $sClassName = $sDashboardClass . 'Class'; + $oInstance = new $sClassName(); + $aCharts = $oInstance->getAvailableCharts(); + foreach ($aCharts as $sChart) { + $bFree = true; + foreach ($aConfiguration as $aDashboard) { + if (($aDashboard['class'] == $sDashboardClass) && ($aDashboard['element'] == $sChart)) { + $bFree = false; + } + } + if ($bFree) { + $oChart = $oInstance->getChart($sChart); + $aShowAvailableDashboards[] = array('DASH_CODE' => $sDashboardClass . '^' . $sChart . '^CHART', + 'DASH_LABEL' => $sDashboardClass . ' - ' . $oChart->title); + } + } + if (method_exists($oInstance, 'getAvailablePages')) { + $aPages = $oInstance->getAvailablePages(); + foreach ($aPages as $sPage) { + $bFree = true; + foreach ($aConfiguration as $aDashboard) { + if (($aDashboard['class'] == $sDashboardClass) && ($aDashboard['element'] == $sPage)) { + $bFree = false; + } + } + if ($bFree) { + if (method_exists($oInstance, 'getPage')) { + $oPage = $oInstance->getPage($sPage); + $aShowAvailableDashboards[] = array('DASH_CODE' => $sDashboardClass . '^' . $sPage . '^PAGE', + 'DASH_LABEL' => $sDashboardClass . ' - ' . $oPage->title); + } + } + } + } + } + //Set DBArray + global $_DBArray; + $_DBArray['AvailableDashboards'] = $aShowAvailableDashboards; + $_SESSION['_DBArray'] = $_DBArray; + //Show form + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + if (count($aShowAvailableDashboards) > 1) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dashboard/dashboard_AvailableDashboards'); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dashboard/dashboard_NoAvailableDashboards'); + } + G::RenderPage('publish', 'raw'); + break; + case 'addDashboard': + if ($_POST['sDashboardClass'] == 'PM_Reports') { + $oObject = new StdClass(); + $oObject->title = G::LoadTranslation($_POST['sElement']); + $oObject->height = 220; + $oObject->url = '/sys' . SYS_SYS . '/' . SYS_LANG . '/blank/reports/reports_Dashboard?sType=' . $_POST['sElement']; + $aConfiguration = $oDashboards->getConfiguration($_SESSION['USER_LOGGED']); + $aConfiguration[] = array('class' => $_POST['sDashboardClass'], + 'type' => $_POST['sType'], + 'element' => $_POST['sElement'], + 'object' => $oObject, + 'config' => ''); + } + else { + require_once PATH_PLUGINS. $_POST['sDashboardClass'] . PATH_SEP . 'class.' . $_POST['sDashboardClass'] . '.php'; + $sClassName = $_POST['sDashboardClass'] . 'Class'; + $oInstance = new $sClassName(); + $aConfiguration = $oDashboards->getConfiguration($_SESSION['USER_LOGGED']); + print_r ($_POST); + switch ($_POST['sType']) { + case 'REPORT': + $aConfiguration[] = array('class' => $_POST['sDashboardClass'], + 'type' => $_POST['sType'], + 'element' => $_POST['sElement'], + 'object' => $oInstance->getReport($_POST['sElement']), + 'config' => ''); + break; + case 'CHART': + $aConfiguration[] = array('class' => $_POST['sDashboardClass'], + 'type' => $_POST['sType'], + 'element' => $_POST['sElement'], + 'object' => $oInstance->getChart($_POST['sElement']), + 'config' => ''); + break; + case 'PAGE': + $aConfiguration[] = array('class' => $_POST['sDashboardClass'], + 'type' => $_POST['sType'], + 'element' => $_POST['sElement'], + 'object' => $oInstance->getPage($_POST['sElement']), + 'config' => ''); + break; + } + } + $oDashboards->saveConfiguration($_SESSION['USER_LOGGED'], $aConfiguration); + echo 'oDashboards = ' . $oDashboards->getDashboardsObject($_SESSION['USER_LOGGED']) . ';'; + break; + case 'removeDashboard': + $aConfiguration = $oDashboards->getConfiguration($_SESSION['USER_LOGGED']); + $aNewConfiguration = array(); + foreach ($aConfiguration as $aDashboard) { + if (($aDashboard['class'] == $_POST['sDashboardClass']) && ($aDashboard['element'] == $_POST['sElement'])) { + //Nothing + } + else { + $aNewConfiguration[] = $aDashboard; + } + } + $oDashboards->saveConfiguration($_SESSION['USER_LOGGED'], $aNewConfiguration); + echo 'oDashboards = ' . $oDashboards->getDashboardsObject($_SESSION['USER_LOGGED']) . ';'; + break; +} \ No newline at end of file diff --git a/workflow/engine/methods/dbConnections/dbConnections.php b/workflow/engine/methods/dbConnections/dbConnections.php new file mode 100644 index 000000000..64fa19c55 --- /dev/null +++ b/workflow/engine/methods/dbConnections/dbConnections.php @@ -0,0 +1,77 @@ +<?php +/** + * upgrade.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* +global $RBAC; +switch ($RBAC->userCanAccess('PM_FACTORY')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} +*/ + +/*$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'processes'; +$G_ID_MENU_SELECTED = 'PROCESSES'; +$G_ID_SUB_MENU_SELECTED = 'DB_CONNECTIONS'; +*/ + +$G_PUBLISH = new Publisher; + +G::LoadClass('processMap'); +$oProcess = new processMap(); +$oCriteria = $oProcess->getConditionProcessList(); +if (ProcessPeer::doCount($oCriteria) > 0) { + $aProcesses = array(); + $aProcesses[] = array('PRO_UID' => 'char', 'PRO_TITLE' => 'char'); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $sProcessUID = ''; + while ($aRow = $oDataset->getRow()) { + if ($sProcessUID == '') { + $sProcessUID = $aRow['PRO_UID']; + } + $aProcesses[] = array('PRO_UID' => $aRow['PRO_UID'], 'PRO_TITLE' => $aRow['PRO_TITLE']); + $oDataset->next(); + } + global $_DBArray; + $_DBArray['PROCESSES'] = $aProcesses; + $_SESSION['_DBArray'] = $_DBArray; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dbConnections/dbConnections_Events'); + require_once 'classes/model/DbSource.php'; + $oDBSource = new DbSource(); + $oCriteria = $oDBSource->getCriteriaDBSList($sProcessUID); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'dbConnections/dbConnections', $oCriteria); +} else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/noProcesses'); +} +G::RenderPage('publish'); diff --git a/workflow/engine/methods/dbConnections/dbConnectionsAjax.php b/workflow/engine/methods/dbConnections/dbConnectionsAjax.php new file mode 100644 index 000000000..c232ed9af --- /dev/null +++ b/workflow/engine/methods/dbConnections/dbConnectionsAjax.php @@ -0,0 +1,290 @@ +<?php +/** + * upgrade.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * Data base connections routines for ajax request + * @Author Erik Amaru Ortiz <erik@colosa.com> + * @Last update May 20th, 2009 + * @Param var action from POST request + */ + +if( isset($_POST['action']) ){ + $action = $_POST['action']; +} else { + throw new Exception('dbconnections Fatal error, No action defined!...'); +} + +#Global Definitions +require_once 'classes/model/DbSource.php'; +require_once 'classes/model/Content.php'; + +$G_PUBLISH = new Publisher; +G::LoadClass('processMap'); +G::LoadClass('ArrayPeer'); +G::LoadClass ('dbConnections'); +global $_DBArray; + +switch ( $action ){ + + case 'showDbConnectionsList': + + $oProcess = new processMap(); + $oCriteria = $oProcess->getConditionProcessList(); + if( ProcessPeer::doCount($oCriteria) > 0 ){ + $aProcesses = array(); + $aProcesses[] = array('PRO_UID' => 'char', 'PRO_TITLE' => 'char'); + $oDataset = ArrayBasePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $sProcessUID = ''; + while( $aRow = $oDataset->getRow() ){ + if( $sProcessUID == '' ){ + $sProcessUID = $aRow['PRO_UID']; + } + $aProcesses[] = array('PRO_UID' => (isset($aRow['PRO_UID']) ? $aRow['PRO_UID'] : ''), 'PRO_TITLE' => (isset($aRow['PRO_TITLE']) ? $aRow['PRO_TITLE'] : '')); + $oDataset->next(); + } + + $_DBArray['PROCESSES'] = $aProcesses; + $_SESSION['_DBArray'] = $_DBArray; + $_SESSION['PROCESS'] = (isset($_POST['PRO_UID']) ? $_POST['PRO_UID'] : ''); + + $oDBSource = new DbSource(); + $oCriteria = $oDBSource->getCriteriaDBSList($_SESSION['PROCESS']); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'dbConnections/dbConnections', $oCriteria); + } + G::RenderPage('publish', 'raw'); + break; + + case 'showConnections': + + $oDBSource = new DbSource(); + $oCriteria = $oDBSource->getCriteriaDBSList($_SESSION['PROCESS']); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'dbConnections/dbConnections', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + + case 'newDdConnection': + + + $dbs = new dbConnections($_SESSION['PROCESS']); + $dbServices = $dbs->getDbServicesAvailables(); + $dbService = $dbs->getEncondeList(); + + + $rows[] = array('uid' => 'char', 'name' => 'char'); + + foreach($dbServices as $srv) { + $rows[] = array('uid' => $srv['id'], 'name' => $srv['name']); + } + + $_DBArray['BDCONNECTIONS'] = $rows; + + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dbConnections/dbConnections_New', '', ''); + G::RenderPage('publish', 'raw'); + break; + + case 'editDdConnection': + + $dbs = new dbConnections($_SESSION['PROCESS']); + $dbServices = $dbs->getDbServicesAvailables(); + + $rows[] = array('uid' => 'char', 'name' => 'char'); + foreach($dbServices as $srv) { + $rows[] = array('uid' => $srv['id'], 'name' => $srv['name']); + } + + $_DBArray['BDCONNECTIONS'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + + $o = new DbSource(); + $aFields = $o->load($_POST['DBS_UID']); + if ($aFields['DBS_PORT'] == '0') { + $aFields['DBS_PORT'] = ''; + } + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dbConnections/dbConnections_Edit', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + + case 'saveEditConnection': + + $oDBSource = new DbSource(); + $oContent = new Content(); + $aData = Array( + 'DBS_UID' => $_POST['dbs_uid'], + 'PRO_UID' => $_SESSION['PROCESS'], + 'DBS_TYPE' => $_POST['type'], + 'DBS_SERVER' => $_POST['server'], + 'DBS_DATABASE_NAME' => $_POST['db_name'], + 'DBS_USERNAME' => $_POST['user'], + 'DBS_PASSWORD' => (($_POST['passwd'] == 'none') ? "": $_POST['passwd']), + 'DBS_PORT' => (($_POST['port'] == 'none') ? "": $_POST['port']), + 'DBS_ENCODE' => $_POST['enc'] + ); + + $oDBSource->update($aData); + $oContent->addContent('DBS_DESCRIPTION', '', $_POST['dbs_uid'], SYS_LANG, $_POST['desc']); + + break; + + case 'saveConnection': + + $oDBSource = new DbSource(); + $oContent = new Content(); + $aData = Array( + 'PRO_UID' => $_SESSION['PROCESS'], + 'DBS_TYPE' => $_POST['type'], + 'DBS_SERVER' => $_POST['server'], + 'DBS_DATABASE_NAME' => $_POST['db_name'], + 'DBS_USERNAME' => $_POST['user'], + 'DBS_PASSWORD' => (($_POST['passwd'] == 'none') ? "": $_POST['passwd']), + 'DBS_PORT' => (($_POST['port'] == 'none') ? "": $_POST['port']), + 'DBS_ENCODE' => $_POST['enc'] + ); + $newid = $oDBSource->create($aData); + $sDelimiter = DBAdapter::getStringDelimiter(); + $oContent->addContent('DBS_DESCRIPTION', '', $newid, SYS_LANG, $_POST['desc']); + + break; + + case 'deleteDbConnection': + + $oDBSource = new DbSource(); + $oContent = new Content(); + + $DBS_UID = $_POST['dbs_uid']; + $oDBSource->remove($DBS_UID); + $oContent->removeContent('DBS_DESCRIPTION', "", $DBS_UID); + break; + + case 'showTestConnection': + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'dbConnections/dbConnections'); + G::RenderPage('publish', 'raw'); + break; + + case 'testConnection': + sleep(0); + $step = $_POST['step']; + $type = $_POST['type']; + $server = $_POST['server']; + $db_name = $_POST['db_name']; + $user = $_POST['user']; + $passwd = ($_POST['passwd'] == 'none') ? "": $_POST['passwd']; + $port = $_POST['port']; + + if( ($port == 'none') || ($port == 0) ){ + //setting defaults ports + switch ($type){ + case 'mysql': $port = 3306; break; + case 'pgsql': $port = 5432; break; + case 'mssql': $port = 1433; break; + case 'oracle': $port = 1521; break; + } + } + + G::LoadClass('net'); + $Server = new NET($server); + + define("SUCCESSFULL", 'SUCCESSFULL'); + define("FAILED", 'FAILED'); + + switch ($step) { + case 1: + if ($Server->getErrno() == 0) { + print (SUCCESSFULL.','); + } else { + print (FAILED.','.$Server->error); + } + break; + + case 2: + $Server->scannPort($port); + if ($Server->getErrno() == 0) { + print (SUCCESSFULL.','); + } else { + print (FAILED.','.$Server->error); + } + break; + + case 3: + $Server->loginDbServer($user, $passwd); + $Server->setDataBase($db_name, $port); + + if($Server->errno == 0){ + $response = $Server->tryConnectServer($type); + if($response->status == 'SUCCESS') { + print (SUCCESSFULL.','); + } else { + print (FAILED.','.$Server->error); + } + } else { + print (FAILED.','.$Server->error); + } + break; + + case 4: + $Server->loginDbServer($user, $passwd); + $Server->setDataBase($db_name, $port); + if($Server->errno == 0){ + $response = $Server->tryConnectServer($type); + if($response->status == 'SUCCESS') { + $response = $Server->tryOpenDataBase($type); + if($response->status == 'SUCCESS') { + print (SUCCESSFULL.','.$Server->error); + } else { + print (FAILED.','.$Server->error); + } + } else { + print (FAILED.','.$Server->error); + } + } else { + print (FAILED.','.$Server->error); + } + break; + + default: + print('finished'); + } + break; + + case 'showEncodes': + G::LoadThirdParty('pear/json','class.json'); + $oJSON = new Services_JSON(); + $engine = $_POST['engine']; + + if($engine != "0"){ + $dbs = new dbConnections(); + echo $oJSON->encode($dbs->getEncondeList($engine)); + + } else { + echo '[["0","..."]]'; + } + break; +} diff --git a/workflow/engine/methods/dbConnections/genericDbConnections.php b/workflow/engine/methods/dbConnections/genericDbConnections.php new file mode 100644 index 000000000..c24ae2dc9 --- /dev/null +++ b/workflow/engine/methods/dbConnections/genericDbConnections.php @@ -0,0 +1,20 @@ +<?php +/** + * @Author: Erik Amaru Ortiz <erik@colosa.com> + * @Description:This is a additional configuration for load all connections; if exist in a particular proccess + * @Date: 15-05-2008 + */ +if( isset($_SESSION['PROCESS']) ){ + $pro = include (PATH_CORE . "config/databases.php"); + G::LoadClass('dbConnections'); + $oDbConnections = new dbConnections($_SESSION['PROCESS']); + foreach( $oDbConnections->connections as $db ) { + $dbsPort = ($db['DBS_PORT'] == '') ? ('') : (':'.$db['DBS_PORT']); + $ENCODE = (trim($db['DBS_ENCODE']) == '')? '': '?encoding=' . $db['DBS_ENCODE']; + $pro['datasources'][$db['DBS_UID']]['connection'] = $db['DBS_TYPE'] . '://' . $db['DBS_USERNAME'] . ':' . $db['DBS_PASSWORD'] . '@' . $db['DBS_SERVER'] .$dbsPort. '/' . $db['DBS_DATABASE_NAME'] . $ENCODE; + $pro['datasources'][$db['DBS_UID']]['adapter'] = $db['DBS_TYPE']; + } + return $pro; +} + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dbConnections/rootDbConnections.php b/workflow/engine/methods/dbConnections/rootDbConnections.php new file mode 100644 index 000000000..0b88cfb16 --- /dev/null +++ b/workflow/engine/methods/dbConnections/rootDbConnections.php @@ -0,0 +1,21 @@ +<?php +/** + * @Author: Erik Amaru Ortiz <erik@colosa.com> + * @Description:This is a additional configuration for load all connections; if exist in a particular proccess + * @Date: 15-05-2008 + */ + + $dbHash = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH)); + + $host = $dbHash[0]; + $user = $dbHash[1]; + $pass = $dbHash[2]; + $dbName = DB_NAME; + + $pro = include (PATH_CORE . "config/databases.php"); + + $pro['datasources']['root'] = Array (); + $pro['datasources']['root']['connection'] = "mysql://$user:$pass@$host/$dbName?encoding=utf8"; + $pro['datasources']['root']['adapter'] = "mysql"; + + return $pro; diff --git a/workflow/engine/methods/departments/departments.php b/workflow/engine/methods/departments/departments.php new file mode 100644 index 000000000..52c594c95 --- /dev/null +++ b/workflow/engine/methods/departments/departments.php @@ -0,0 +1,362 @@ +<?php +/** + * departments.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'DEPARTMENTS'; + + $G_PUBLISH = new Publisher; + $oHeadPublisher =& headPublisher::getSingleton(); + //$oHeadPublisher->addScriptFile('/jscore/departments/departments.js'); + + $G_PUBLISH->AddContent('view', 'departments/departments_Tree' ); + $G_PUBLISH->AddContent('smarty', 'departments/departments_userList', '', '', array()); + + G::RenderPage( "publish-treeview",'blank' ); + + $departments_New = G::encryptlink('departments_New'); + $departments_Edit = G::encryptlink('departments_Edit'); + $departments_Delete = G::encryptlink('departments_Delete'); + $departments_List = G::encryptlink('departments_List'); + $departments_AddUser = G::encryptlink('departments_AddUser'); + $departments_AddManager = G::encryptlink('departments_AddManager'); + $subdep_Edit = G::encryptlink('subdep_Edit'); + $subdep_Delete = G::encryptlink('subdep_Delete'); +?> +<script> + + + var oAux = document.getElementById("publisherContent[0]"); + oAux.id = "publisherContent[666]"; + var currentGroup=false; + +function saveUserGroup(sUser) { + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../groups/groups_Ajax', + async : false, + method: 'POST', + args : 'action=assignUser&GRP_UID=' + currentGroup + '&USR_UID=' + sUser + }); + oRPC.make(); + currentPopupWindow.remove(); + selectGroup(currentGroup); + } + + +function saveUsers(){ + if( checks_selected_ids.length == 0 ){ + new leimnud.module.app.alert().make({label: G_STRINGS.ID_MSG_GROUPS_ADDCONFIRM}); + return 0; + } + //alert('action=assignAllUsers&DEP_UID=' + currentGroup + '&aUsers=' + checks_selected_ids);return; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : false, + method: 'POST', + args : 'action=assignAllUsers&DEP_UID=' + currentGroup + '&aUsers=' + checks_selected_ids + }); + resetChecks(); + oRPC.make(); + currentPopupWindow.remove(); + selectDpto(currentGroup); +} + +function resetChecks(){ + checks_selected_ids.length = 0; +} + + function selectDpto( uid ){ + currentGroup = uid; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'departments_Ajax', + args : 'action=showUsers&sDptoUID=' + uid + }); + oRPC.callback = function(rpc) { + var scs = rpc.xmlhttp.responseText.extractScript(); + document.getElementById('spanUsersList').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + + oRPC.make(); + } + + function addDepto() { + popupWindow('' , '<?=$departments_New?>' , 500 , 200 ); + } + + function addSubDepto(depUid){ + popupWindow('' , '<?= $departments_New ?>?DEP_UID=' + encodeURIComponent( depUid ) , 500 , 200 ); + } + + function deleteDpto( uid ){ + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_DELETE_DEPARTMENT')?>", + action:function() + { + ajax_function('<?=$departments_Delete?>', 'empty', 'DEP_UID='+uid, "POST" ); + refreshTree(); + document.getElementById('spanUsersList').innerHTML = ''; + }.extend(this) + }); + } + + function addUserDpto( uid ) { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:400,h:512}, + position:{x:0,y:0,center:true}, + title : 'Add users to department ' + groupname, + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { + delete(oPanel); + //resetChecks(); + }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + currentPopupWindow = oPanel; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '<?=$departments_AddUser?>?UID='+uid, + args: '' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + var inputs = document.getElementsByTagName("input"); + for(i=0; i<inputs.length; i++){ + if( inputs[i].type == "checkbox" ){ + try{ + inputs[i].onclick = function(){ + if(this.checked){ + checks_selected_ids.push(this.value); + } else { + checks_selected_ids.deleteByValue(this.value); + } + }; + }catch(e){alert(e)} + } + } + }.extend(this); + oRPC.make(); + } + + function addDepManager(suid, sDepParent){ + var k = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : true, + method: 'POST', + args : 'action=getDepManager&sDptoUID=' + suid + + }); + + k.callback = function(rpc){ + if(rpc.xmlhttp.responseText>0){ + msgBox("this department has its manager","alert");return false; + }else{ + popupWindow('' , '<?=$departments_AddManager?>?SUID=' + encodeURIComponent( suid )+'&SDEPPARENT=' + encodeURIComponent( sDepParent )+ '+&nobug' , 500 , 200 ); + } + }.extend(this); + k.make(); + } + + + function savedepto( form ) { + var actionform='departments_Save'; + ajax_post( actionform, form, 'POST' ); + currentPopupWindow.remove(); + refreshTree(); + } + + function savedeptomain( form ) {//alert(form.action);return; + var formAction ='departments_Save'; + ajax_post( formAction, form, 'POST' ); + selectDpto(getField('DEP_UID').value); + refreshTree(); + } + + function savedeptoManager( form ) { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : false, + method: 'POST', + args : 'action=assignAllUsers&DEP_UID=' + getField('DEP_UID').value + '&aUsers=' + getField('DEP_MANAGER').value + }); + //resetChecks(); + oRPC.make(); + + ajax_post( form.action, form, 'POST' ); + currentPopupWindow.remove(); + //refreshTree(); + selectDpto(getField('DEP_UID').value); + } + + function savesubdepto( form ) { + ajax_post( form.action, form, 'POST' ); + currentPopupWindow.remove(); + refreshSubTree(); + } + + function AddUnassignedUser( uid ){//alert(uid); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'departments_Ajax', + args : 'action=showUnAssignedUsers&UID=' + uid + }); + oRPC.callback = function(rpc) { + var scs = rpc.xmlhttp.responseText.extractScript(); + document.getElementById('spanUsersList').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + + oRPC.make(); + } + + function sselectDpto( suid, sDepParent ) { + currentGroup = suid; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'departments_Ajax', + args : 'action=subshowUsers&sDptoUID=' + suid +'&sDepParent=' + sDepParent + }); + oRPC.callback = function(rpc) { + var scs = rpc.xmlhttp.responseText.extractScript(); + document.getElementById('spanUsersList').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + + oRPC.make(); + } + + + function sdeleteDpto( suid, sDepParent ){ + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_DELETE_DEPARTMENT')?>", + action:function() + { + ajax_function('<?=$subdep_Delete?>', 'asdxxx', 'DEP_UID=' +suid+ '&DEP_PARENT=' +sDepParent, "POST" ); + refreshTree(); + document.getElementById('spanUsersList').innerHTML = ''; + }.extend(this) + }); + } + + + function refreshTree(){ + tree.refresh( document.getElementById("publisherContent[666]") , '<?=$departments_List?>'); + } + + function refreshSubTree(){ + tree.refresh( document.getElementById("publisherContent[666]") , '<?=$departments_List?>'); + } + + var removeUserFromDepartment = function(sDpto, sUser) + { + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_REMOVE_USER')?>", + action:function() + { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : false, + method: 'POST', + args : 'action=removeUserFromDepartment&DEP_UID=' + sDpto + '&USR_UID=' + sUser + }); + oRPC.make(); + currentDept = sDpto; + selectDpto(currentDept); + }.extend(this) + }); + }; + + var removeUserManager = function(sDpto, sUser) + { + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_REMOVE_USER')?>", + action:function() + { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : false, + method: 'POST', + args : 'action=removeUserManager&DEP_UID=' + sDpto + '&USR_UID=' + sUser + }); + oRPC.make(); + currentGroup = sDpto; + selectDpto(currentGroup); + }.extend(this) + }); + }; + + function DeleteManager(suid, sDepParent){ + var k = new leimnud.module.rpc.xmlhttp({ + url : '../departments/departments_Ajax', + async : true, + method: 'POST', + args : 'action=getDepManageruid&sDptoUID=' + suid + + }); + k.callback = function(rpc){ + sUser= rpc.xmlhttp.responseText; + + if(rpc.xmlhttp.responseText!=''){ + removeUserManager(suid, sUser); + }else{ + msgBox("this department doesn't has its manager","alert");return false; + } + }.extend(this); + k.make(); + } + +</script> diff --git a/workflow/engine/methods/departments/departments_AddManager.php b/workflow/engine/methods/departments/departments_AddManager.php new file mode 100644 index 000000000..abe5c7c9a --- /dev/null +++ b/workflow/engine/methods/departments/departments_AddManager.php @@ -0,0 +1,61 @@ +<?php +/** + * departments_AddManager.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + + G::LoadClass('departos'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //print_r($_GET); + $oDpto = new Departos(); + //$DptoUid = (isset($_GET['UID'])) ? urldecode($_GET['UID']):''; + $aUser=Array(); + $aUser[]= Array ('USR_UID'=>'char', 'USR_FIRSTNAME'=>'char', 'USR_LASTNAME'=>'char'); + + $aUserManagers=$oDpto->getUsersManagers(); + $aUser_Manager= array_merge($aUser,$aUserManagers); + //print_r($aUser_Manager); + /* + global $_DBArray; + $_DBArray['aManager'] = $aUser_Manager; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('aManager'); + + */ + + $aFields=array(); + $aFields['DEP_UID']= $_GET['SUID']; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/departments_AddManager', '', $aFields , 'departments_SaveManager'); + + G::RenderPage( "publish" , "raw" ); + + + +?> \ No newline at end of file diff --git a/workflow/engine/methods/departments/departments_AddUser.php b/workflow/engine/methods/departments/departments_AddUser.php new file mode 100644 index 000000000..3fdb06a52 --- /dev/null +++ b/workflow/engine/methods/departments/departments_AddUser.php @@ -0,0 +1,56 @@ +<?php +/** + * groups_AddUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + require_once ( 'classes/class.xmlfield_InputPM.php' ); + require_once ( 'classes/model/Department.php' ); + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + $oDept = new Department(); + $aFields = $oDept->load($_GET['UID']); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'departments/paged-table', 'departments/departments_AvailableUsers', $oDept->getAvailableUsersCriteria($_GET['UID'])); + G::RenderPage('publish', 'raw'); \ No newline at end of file diff --git a/workflow/engine/methods/departments/departments_Ajax.php b/workflow/engine/methods/departments/departments_Ajax.php new file mode 100644 index 000000000..ed491860c --- /dev/null +++ b/workflow/engine/methods/departments/departments_Ajax.php @@ -0,0 +1,114 @@ +<?php +/** + * departments_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; +G::LoadInclude('ajax'); +$_POST['action'] = get_ajax_value('action'); + +require_once 'classes/model/Department.php'; + +switch ($_POST['action']) +{ + case 'showUsers': + global $G_PUBLISH; + $oDept = new Department(); + $aFields = $oDept->load($_POST['sDptoUID']); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/departments_Edit', '', $aFields , ''); + + $criteria = $oDept->getUsersFromDepartment( $_POST['sDptoUID'], $aFields ['DEP_MANAGER'] ); + + $G_PUBLISH->AddContent('propeltable', 'departments/paged-table2', 'departments/departments_UsersList', $criteria, $aFields ); + //$G_PUBLISH->AddContent('propeltable', 'paged-table', 'departments/departments_UsersList', $criteria, $aFields); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode("groupname='{$aFields["DEPO_TITLE"]}';"); + $oHeadPublisher->addScriptCode("depUid='{$aFields["DEP_UID"]}';"); + + G::RenderPage('publish', 'raw'); + break; + + case 'assignAllUsers': + $aUsers = explode(',', $_POST['aUsers']); + $oDept = new Department(); + $depUid = $_POST['DEP_UID']; + $cant = $oDept->cantUsersInDepartment( $depUid); + + if ( $cant == 0 ) $manager = true; + + for( $i=0; $i<count($aUsers); $i++) { + $oDept->addUserToDepartment( $depUid, $aUsers[$i], $manager, false ); + $manager = false; + } + $oDept->updateDepartmentManager( $depUid ); + + break; + + case 'removeUserFromDepartment': + $oDept = new Department(); + $oDept->removeUserFromDepartment($_POST['DEP_UID'], $_POST['USR_UID']); + break; + + case 'verifyDptoname': + $_POST['sOriginalGroupname'] = get_ajax_value('sOriginalGroupname'); + $_POST['sGroupname'] = get_ajax_value('sGroupname'); + if ($_POST['sOriginalGroupname'] == $_POST['sGroupname']) + { + echo '0'; + } + else + { + $oDpto = new Department(); + $oCriteria=$oDpto->loadByGroupname($_POST['sGroupname']); + $oDataset = DepartmentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if (!$aRow) + { + echo '0'; + } + else + { + echo '1'; + } + } + break; + + + case 'showUnAssignedUsers': + $_POST['UID'] = get_ajax_value('UID'); + require_once ( 'classes/class.xmlfield_InputPM.php' ); + + if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + G::LoadClass ( 'departments'); + $oDept = new Department(); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'departments/paged-table3', 'departments/departments_AddUnAssignedUsers', $oDept->getAvailableUsersCriteria('')); + G::RenderPage('publish', 'raw'); + + break; + +} diff --git a/workflow/engine/methods/departments/departments_Delete.php b/workflow/engine/methods/departments/departments_Delete.php new file mode 100644 index 000000000..15ee9b318 --- /dev/null +++ b/workflow/engine/methods/departments/departments_Delete.php @@ -0,0 +1,58 @@ +<?php +/** + * departments_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + require_once 'classes/model/Department.php'; + require_once 'classes/model/Users.php'; + + $oDpto = new Department(); + + if (!isset($_POST['DEP_UID'])) return; + + + $ocriteria = new Criteria('workflow'); + $ocriteria->addSelectColumn(DepartmentPeer::DEP_MANAGER); + $ocriteria->add(DepartmentPeer::DEP_UID,$_POST['DEP_UID']); + $oDataset = DepartmentPeer::doSelectRS($ocriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(UsersPeer::USR_REPORTS_TO, $aRow['DEP_MANAGER'], Criteria::EQUAL); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(UsersPeer::USR_REPORTS_TO, ''); + BasePeer::doUpdate($oCriteria1, $oCriteria2, Propel::getConnection('workflow')); + + $oCriteriaA = new Criteria('workflow'); + $oCriteriaA->add(UsersPeer::DEP_UID, $_POST['DEP_UID'], Criteria::EQUAL); + $oCriteriaB = new Criteria('workflow'); + $oCriteriaB->add(UsersPeer::DEP_UID, ''); + BasePeer::doUpdate($oCriteriaA, $oCriteriaB, Propel::getConnection('workflow')); + + $oDpto->remove(urldecode($_POST['DEP_UID'])); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/departments/departments_Edit.php b/workflow/engine/methods/departments/departments_Edit.php new file mode 100644 index 000000000..1eccf481d --- /dev/null +++ b/workflow/engine/methods/departments/departments_Edit.php @@ -0,0 +1,64 @@ +<?php +/** + * departments_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + $dept = new Department(); + $DptoUid = (isset($_GET['UID'])) ? urldecode($_GET['UID']):''; + + if ($DptoUid) { + $aFields = $dept->Load( $DptoUid ); + } + else { + $aFields=array(); + } + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/departments_Edit', '', $aFields , 'departments_Save'); + + G::RenderPage( "publish" , "raw" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/departments/departments_List.php b/workflow/engine/methods/departments/departments_List.php new file mode 100644 index 000000000..be08dce3b --- /dev/null +++ b/workflow/engine/methods/departments/departments_List.php @@ -0,0 +1,53 @@ +<?php +/** + * groups_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + +$G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'view', 'departments/departments_Tree' ); + G::RenderPage( "publish-raw" , "raw" ); +?> diff --git a/workflow/engine/methods/departments/departments_New.php b/workflow/engine/methods/departments/departments_New.php new file mode 100644 index 000000000..e80491e47 --- /dev/null +++ b/workflow/engine/methods/departments/departments_New.php @@ -0,0 +1,65 @@ +<?php +/** + * departments_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + require_once 'classes/model/Department.php'; + + $oDept = new Department(); + $parentUid = (isset($_GET['DEP_UID'])) ? urldecode($_GET['DEP_UID']) : '' ; + $Fields['DEP_STATUS'] = 'ACTIVE'; + + $G_PUBLISH = new Publisher(); + if ( strlen( $parentUid) > 0 ) { + $Fields['DEP_PARENT'] = $parentUid; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/departments_SubNew', '', $Fields , 'departments_Save'); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/departments_New', '', null, ''); + } + + G::RenderPage( "publish" , "raw" ); diff --git a/workflow/engine/methods/departments/departments_Save.php b/workflow/engine/methods/departments/departments_Save.php new file mode 100644 index 000000000..c31d85a5e --- /dev/null +++ b/workflow/engine/methods/departments/departments_Save.php @@ -0,0 +1,42 @@ +<?php +/** + * groups_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if ( ( $RBAC_Response=$RBAC->userCanAccess("PM_USERS") ) !=1 ) return $RBAC_Response; + + require_once 'classes/model/Department.php'; + + $oDept = new Department(); + $depRow = $_POST['form']; + + if( $_POST['form']['DEP_UID'] === '' ) { + unset ( $depRow['DEP_UID'] ); + $oDept->create( $depRow ); + } + else { +// $oDeptos->updateUsers($depRow); + $oDept->update($depRow); + $oDept->updateDepartmentManager($depRow['DEP_UID'] ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/departments/subdep_Delete.php b/workflow/engine/methods/departments/subdep_Delete.php new file mode 100644 index 000000000..50983a05d --- /dev/null +++ b/workflow/engine/methods/departments/subdep_Delete.php @@ -0,0 +1,44 @@ +<?php +/** + * departments_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + //G::LoadClass('groups'); + G::LoadClass('departos'); + + //$group = new Groupwf(); + $oDpto = new Department(); + + if (!isset($_POST['DEP_UID'])) return; + + $oDpto->remove(urldecode($_POST['DEP_UID'])); + + require_once 'classes/model/TaskUser.php'; + $oProcess = new TaskUser(); + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(TaskUserPeer::USR_UID, $_POST['DEP_UID']); + TaskUserPeer::doDelete($oCriteria); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/departments/subdep_Edit.php b/workflow/engine/methods/departments/subdep_Edit.php new file mode 100644 index 000000000..c8e7f9f01 --- /dev/null +++ b/workflow/engine/methods/departments/subdep_Edit.php @@ -0,0 +1,71 @@ +<?php +/** + * departments_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + G::LoadClass('departments'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $Dpto = new Department(); + $DptoUid = (isset($_GET['SUID'])) ? urldecode($_GET['SUID']):''; + $DepParent = (isset($_GET['SDEPPARENT'])) ? urldecode($_GET['SDEPPARENT']):''; + + if (strlen($DptoUid) > 1 && strlen($DepParent)>1) + { + $aFields=$Dpto->Load( $DptoUid ); + } + else + {$infosubDto = $Dpto->Load( $DptoUid );//print_r($infosubDto); + $aFields=array('SUID'=>$DptoUid,'SDEPPARENT'=>$DepParent);//print_r($aFields);print"<hr>"; + } + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'departments/subdep_Edit', '', $aFields , 'subdep_Save'); + + G::RenderPage( "publish" , "raw" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/departments/subdep_Save.php b/workflow/engine/methods/departments/subdep_Save.php new file mode 100644 index 000000000..79792538b --- /dev/null +++ b/workflow/engine/methods/departments/subdep_Save.php @@ -0,0 +1,68 @@ +<?php +/** + * groups_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //print_r($_POST);die; + +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + //G::LoadClass('groups'); + G::LoadClass('departments'); + + + + $G_MAIN_MENU = 'wf.login'; + $G_MENU_SELECTED = ''; + +//$oDepto = new Departos(); + + +//$oDepto->saveNewDepto($_POST['form']); + +//print_r($_GET); + $oDepto = new Department(); + + $depRow = $_POST['form']; + + $DptoUid = (isset($_POST ['form']['SUID'])) ? urldecode($_POST['form']['SUID']):''; + $DepParent = (isset($_POST['form']['SDEPPARENT'])) ? urldecode($_POST['form']['SDEPPARENT']):''; + + + //if($_POST['form']['SDEP_UID']==='' && $_POST['form']['SDEP_UID'] ==='') + //if($_POST['form']['SUID']!=='' && $_POST['form']['SDEPPARENT'] ==='') + if (strlen($DptoUid) > 1 && strlen($DepParent)==1) + { + $oDepto->subcreate( $depRow ); + //unset ( $depRow['DEP_UID'] ); + //$oDepto->subcreate( $depRow ); + //$_POST['form']['GRP_UID']=$group->getGrpUid(); + //$group->update($_POST['form']); + } + else + {// 1ro + + ////////$oDepto->subcreate( $depRow ); + $oDepto->subupdate($depRow); + } + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/conditionalShowHide.php b/workflow/engine/methods/dynaforms/conditionalShowHide.php new file mode 100755 index 000000000..03047c2b9 --- /dev/null +++ b/workflow/engine/methods/dynaforms/conditionalShowHide.php @@ -0,0 +1,96 @@ +<? +/** + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz <erik@colosa.com> + * @Date Aug 26th, 2009 + */ + require_once "classes/model/FieldCondition.php"; + G::LoadClass('ArrayPeer'); + + $G_PUBLISH = new Publisher; + $oHeadPublisher =& headPublisher::getSingleton(); + $DISPLAY_MAX_SIZE = 25; + global $_DBArray; + + $oFieldCondition = new FieldCondition; + $DYN_UID = $_SESSION['Current_Dynafom']['Parameters']['DYN_UID']; + $aRows = $oFieldCondition->getAllByDynUid($DYN_UID); + + $aFieldNames = Array( + 'FCD_NRO', + 'FCD_UID', + 'FCD_FUNCTION', + 'FCD_FIELDS', + 'FCD_CONDITION', + 'FCD_EVENTS', + 'FCD_EVENT_OWNERS', + 'FCD_STATUS', + 'FCD_DYN_UID' + ); + + //Routines to limit the show in list max size for some fields that can have large size + $inndex = 0; + $aRowsTmp = Array(); + foreach($aRows as $aRow){ + $aRow['FCD_NRO'] = ++$inndex; + if( strlen($aRow['FCD_FIELDS']) > $DISPLAY_MAX_SIZE ){ + $aRow['FCD_FIELDS'] = substr($aRow['FCD_FIELDS'], 0, $DISPLAY_MAX_SIZE) . '...'; + } + + if( $aRow['FCD_FUNCTION'] == 'showAll' || $aRow['FCD_FUNCTION'] == 'hideAll' ){ + $aRow['FCD_FIELDS'] = 'ALL'; + } + + if( strlen($aRow['FCD_CONDITION']) > $DISPLAY_MAX_SIZE ){ + $aRow['FCD_CONDITION'] = substr($aRow['FCD_CONDITION'], 0, $DISPLAY_MAX_SIZE) . '...'; + } + if( strlen($aRow['FCD_EVENT_OWNERS']) > $DISPLAY_MAX_SIZE ){ + $aRow['FCD_EVENT_OWNERS'] = substr($aRow['FCD_EVENT_OWNERS'], 0, $DISPLAY_MAX_SIZE) . '...'; + } + array_push($aRowsTmp, $aRow); + } + + $aRows = array_merge(Array($aFieldNames), $aRowsTmp); + + $_DBArray['virtual_pmtable'] = $aRows; + $_SESSION['_DBArray'] = $_DBArray; + + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('virtual_pmtable'); + + $oHeadPublisher->addScriptFile('/jscore/dynaforms/dynaforms_conditionalShowHide.js'); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'dynaforms/dynaforms_ConditionalShowHideList', $oCriteria, Array('DYN_UID'=>$DYN_UID), ''); + G::RenderPage('publish', 'raw'); + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/conditionalShowHide_Ajax.php b/workflow/engine/methods/dynaforms/conditionalShowHide_Ajax.php new file mode 100755 index 000000000..e65a8dbda --- /dev/null +++ b/workflow/engine/methods/dynaforms/conditionalShowHide_Ajax.php @@ -0,0 +1,205 @@ +<? +/** + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * @Author Erik A. Ortiz <erik@colosa.com> + * @Date Feb 12th, 2010 + */ +try { + if(!isset($_POST['request'])) { + throw new Exception('No request set'); + } + $request = $_POST['request']; + $G_PUBLISH = new Publisher(); + + switch($request) { + case 'new': + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_ConditionalShowHide', '', ''); + G::RenderPage('publish', 'raw'); + break; + + case 'edit': + require_once 'classes/model/FieldCondition.php'; + $oFieldCondition = new FieldCondition(); + $aRow = $oFieldCondition->get($_POST['FCD_UID']); + $aData = Array(); + $aData['condition'] = 'neyek'; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_ConditionalShowHide', '', $aRow); + G::RenderPage('publish', 'raw'); + + //echo '<script>+alert(getField("FCD_CONDITION").value)</script>'; + break; + + case 'getDynaFieds': + G::LoadThirdParty('pear/json', 'class.json'); + G::LoadSystem('dynaformhandler'); + + $_DYN_FILENAME = $_SESSION['Current_Dynafom']['Parameters']['FILE']; + $sFilter = isset($_POST['filter']) ? $_POST['filter'] : ''; + + $oJSON = new Services_JSON(); + $oDynaformHandler = new dynaFormHandler(PATH_DYNAFORM . $_DYN_FILENAME . '.xml'); + + $aFilter = explode(',', $sFilter); + + $aAvailableFields = $oDynaformHandler->getFieldNames($aFilter); + + print($oJSON->encode($aAvailableFields)); + break; + + case 'showDynavars': + G::LoadSystem('dynaformhandler'); + + $_DYN_FILENAME = $_SESSION['Current_Dynafom']['Parameters']['FILE']; + $sFilter = isset($_POST['filter']) ? $_POST['filter'] : ''; + + $oDynaformHandler = new dynaFormHandler(PATH_DYNAFORM . $_DYN_FILENAME . '.xml'); + $aFilter = explode(',', $sFilter); + $aAvailableFields = $oDynaformHandler->getFieldNames($aFilter); + + $aFieldNames = Array( + 'id' => 'char', + 'name' => 'char' + ); + + $aRows = Array(); + foreach( $aAvailableFields as $sFieldname ) { + array_push($aRows, Array( + 'id' => $sFieldname, + 'name' => $sFieldname + )); + } + + $rows = array_merge(Array( + $aFieldNames + ), $aRows); + + global $_DBArray; + $_DBArray['DYNAFIELDS'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('DYNAFIELDS'); + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_vars', '', ''); + G::RenderPage('publish', 'raw'); + + break; + + case 'testSetup': + $sFields = $_POST['sFields']; + $aFields = Array(); + $aFieldsTmp = ($sFields == '') ? Array() : explode(',', $sFields); + + $i = 1; + foreach( $aFieldsTmp as $aField ) { + $aFields['gFields'][$i ++] = Array( + 'dynaid' => $aField, + 'dynafield' => $aField, + 'dynavalue' => '' + ); + } + + if(sizeof($aFields) > 0) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_ConditionalShowHideTest', '', $aFields); + G::RenderPage('publish', 'raw'); + } else { + print('false'); + } + break; + + case 'save': + require_once 'classes/model/FieldCondition.php'; + $oFieldCondition = new FieldCondition(); + $aDYN = $_SESSION['Current_Dynafom']['Parameters']; + $_POST['FCD_UID'] = ($_POST['FCD_UID']=='0') ? '' : $_POST['FCD_UID']; + $aData = Array( + 'FCD_UID' => Isset($_POST['FCD_UID'])?$_POST['FCD_UID']:'', + 'FCD_FUNCTION' => $_POST['function'], + 'FCD_FIELDS' => $_POST['fields_selected'], + 'FCD_CONDITION' => $_POST['condition'], + 'FCD_EVENTS' => $_POST['events'], + 'FCD_EVENT_OWNERS'=>$_POST['event_owner_selected'], + 'FCD_STATUS' => $_POST['enabled'], + 'FCD_DYN_UID' => $aDYN['DYN_UID'] + ); + + $oFieldCondition->quickSave($aData); + break; + + case 'delete': + require_once 'classes/model/FieldCondition.php'; + $oFieldCondition = FieldConditionPeer::retrieveByPk($_POST['FCD_UID']); + if( is_object($oFieldCondition) ){ + $oFieldCondition->delete(); + } + break; + + } +} catch( Exception $e) { + print($e->getMessage()); +} + +/* + * <pre>Array +( + [request] => save + [fields_selected] => name + [event_owner_selected] => name + [function] => show + [condition] => (@#aaa @#ccc)/2 >=100 + [load] => 1 + [change] => 1 +) +</pre><pre>Array +( + [SYS_LANG] => en + [URL] => aZNhn2OsaGClqJLQpZprpJOgZseTpGmjaWilpmSfpWtop2SeaZVmomapaJHTpJagqJZu1ZefZZdgnmGmbWilq2jM6aKpog + [DYN_UID] => 5316266664ac0e33a5cf224021398577 + [PRO_UID] => 6013394054ac0e22b33dc89058523206 + [DYNAFORM_NAME] => main + [FILE] => 6013394054ac0e22b33dc89058523206/5316266664ac0e33a5cf224021398577_tmp0 +) +</pre> + */ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/datemask.php b/workflow/engine/methods/dynaforms/datemask.php new file mode 100755 index 000000000..ef824c352 --- /dev/null +++ b/workflow/engine/methods/dynaforms/datemask.php @@ -0,0 +1,41 @@ +<?php +/** + * fields_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +//if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('dynaFormField'); + + // if (!(isset($_GET['A']) && $_GET['A']!=='')) return; + + // $file = G::decrypt( $_GET['A'] , URL_KEY ); + $file='datemask'; + + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/datemask','',''); + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/fields/' . $type, '', $Fields , SYS_URI.'dynaforms/fields_Save', SYS_URI.'dynaforms/fields_Ajax'); + G::RenderPage( "publish" , "raw" ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaform_Fields.php b/workflow/engine/methods/dynaforms/dynaform_Fields.php new file mode 100644 index 000000000..a85bbbc51 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaform_Fields.php @@ -0,0 +1,60 @@ +<?php +/** + * dynaform_Fields.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('xmlDb'); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'DYNAFORMS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $xdbc = new DBConnection( PATH_XMLFORM . 'dynaforms/dynaform_Fields.xml' ,'','','','myxml' ); + $xses = new DBSession($xdbc); + + $res = $xses->execute('SELECT * FROM dynaForm'); + for($r=0 ; $r < $res->count() ; $r ++ ){ + $row = $res->read(); +// var_dump( $row );echo('<br/>'); + } + + define('DB_XMLDB_HOST', PATH_XMLFORM . 'dynaforms/dynaforms_List.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + + + $G_PUBLISH = new Publisher; + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/dynaform_Fields', '', array('SYS_LANG' => SYS_LANG) , 'dynaforms_Save', 'dynaforms_PagedTableAjax'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Ajax.php b/workflow/engine/methods/dynaforms/dynaforms_Ajax.php new file mode 100644 index 000000000..0eb34d50b --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Ajax.php @@ -0,0 +1,229 @@ +<?php +/** + * dynaforms_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 07/01/2008 + * + * @author David Callizaya <davidsantos@colosa.com> + */ +global $_DBArray; +if (!isset($_DBArray)) { + $_DBArray = array(); +} +G::LoadClass('dynaformEditor'); +$oDynaformEditorAjax = new dynaformEditorAjax($_POST); + +//if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +// +// //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); +// +// G::LoadInclude('ajax'); +// G::LoadClass('toolBar'); +// G::LoadClass('dynaFormField'); +// G::LoadClass('dynaform'); +// +// if (!((isset($_POST['A']) && $_POST['A']!=='')||(isset($_GET['A']) && $_GET['A']!==''))) return; +// +// $file = G::decrypt( get_ajax_value('A') , URL_KEY ); +// +// $function=get_ajax_value('function'); +// +// switch ( $function ) { +// case 'saveDyna': +// /*Save register*/ +// $DYN_UID=get_ajax_value('DYN_UID'); +// if (isset($_SESSION['CURRENT_DYNAFORM']) +// && $_SESSION['CURRENT_DYNAFORM']['DYN_UID']===$DYN_UID) { +// $dbc = new DBConnection(); +// $ses = new DBSession($dbc); +// $dynaform = new dynaform( $dbc ); +// $Fields=$_SESSION['CURRENT_DYNAFORM']; +// //$dynaform->Fields=$Fields; +// $dynaform->Save( $Fields ); +// unset($dynaform->Fields); +// $dynaform->Fields['DYN_UID']=$DYN_UID; +// $dynaform->Load( $_SESSION['CURRENT_DYNAFORM']['DYN_UID'] ); +// $_SESSION['CURRENT_DYNAFORM']=$dynaform->Fields; +// } +// break; +// /*Save file*/ +// $copy = implode('',file(PATH_DYNAFORM . $file . '.xml')); +// $copyHtml = implode('',file(PATH_DYNAFORM . $file . '.html')); +// $file = (strcasecmp(substr($file,-5),'_tmp0')==0)? substr($file,0,strlen($file)-5) : $file; +// $fcopy=fopen(PATH_DYNAFORM . $file . '.xml',"w"); +// fwrite($fcopy, $copy); +// fclose($fcopy); +// $fcopy=fopen(PATH_DYNAFORM . $file . '.html',"w"); +// fwrite($fcopy, $copyHtml); +// fclose($fcopy); +// /*TODO: Delete temporal file*/ +// break; +// case 'closeDyna': +// unset($_SESSION['CURRENT_DYNAFORM']); +// /*TODO: Delete temporal file*/ +// break; +// case 'isModified': +// $DYN_UID=get_ajax_value('DYN_UID'); +// $modified = false; +// if (isset($_SESSION['CURRENT_DYNAFORM']) +// && $_SESSION['CURRENT_DYNAFORM']['DYN_UID']===$DYN_UID) { +// $dbc = new DBConnection(); +// $ses = new DBSession($dbc); +// $dynaform = new dynaform( $dbc ); +// $dynaform->Fields['DYN_UID']=$DYN_UID; +// $dynaform->Load( $dynaform->Fields['DYN_UID'] ); +// $modified = $modified || ($_SESSION['CURRENT_DYNAFORM']!==$dynaform->Fields); +// } +// $copy = implode('',file(PATH_DYNAFORM . $file . '.xml')); +// $fileOrigen = (strcasecmp(substr($file,-5),'_tmp0')==0)? substr($file,0,strlen($file)-5) : $file; +// $origen = implode('',file(PATH_DYNAFORM . $fileOrigen . '.xml')); +// $modified = $modified || ($copy!==$origen); +// print($modified?'true':'false'); +// break; +// case 'preview': +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// print($form->render( $form->template , $script )); +// break; +// case 'xmlcode': +// $openDoc = new Xml_Document(); +// $openDoc->parseXmlFile(PATH_DYNAFORM . $file . '.xml'); +// print($openDoc->getXml()); +// break; +// case 'htmlcode': +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// $G_PUBLISH = new Publisher; +// $G_PUBLISH->publisherId=''; +// /* Navigation Bar */ +// $form->fields=G::array_merges( +// array('__DYNAFORM_OPTIONS' => new XmlForm_Field_XmlMenu( +// new Xml_Node( +// '__DYNAFORM_OPTIONS', +// 'complete', +// '', +// array('type'=>'xmlmenu','xmlfile'=>'gulliver/dynaforms_Options') +// ),SYS_LANG,PATH_XMLFORM,$form) ), +// $form->fields); +// +// /**/ +// $html=$form->printTemplate( $form->template , $script ); +// $html=str_replace('{$form_className}','formDefault', $html ); +// $HtmlEditor = array( +// 'URL'=> G::encrypt( $file , URL_KEY ), +// 'HTML'=> $html +// ); +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_HtmlEditor', '', $HtmlEditor , '', ''); +// G::RenderPage( "publish", 'raw' ); +// break; +// case 'xmlcodeSave': +// //BUG::var_dump("Saving xml code ..."); +// //BUG::var_dump($_POST); +// //BUG::var_dump($_GET); +// $xmlcode = stripslashes(urldecode(get_ajax_value('xmlcode'))); +// $fp=fopen(PATH_DYNAFORM . $file . '.xml', 'w'); +// fwrite($fp, $xmlcode ); +// fclose($fp); +// break; +// case 'htmlcodeSave': +// $htmlcode = stripslashes(urldecode(get_ajax_value('htmlcode'))); +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// $filename = substr($form->fileName , 0, -3) . +// ( $form->type==='xmlform' ? '' : '.' . $form->type ) . 'html'; +// $fp=fopen($filename, 'w'); +// fwrite($fp, $htmlcode ); +// fclose($fp); +// break; +// case 'resetTemplate': +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// $filename = substr($form->fileName , 0, -3) . +// ( $form->type==='xmlform' ? '' : '.' . $form->type ) . 'html'; +// $fp=fopen($filename, 'w'); +// fwrite($fp, $htmlcode ); +// fclose($fp); +// break; +// case 'javascripts': +// $dbc = new DBConnection(); +// $ses = new DBSession($dbc); +// $dynaform = new dynaform( $dbc ); +// $dynaform->Fields['DYN_UID']=get_ajax_value('DYN_UID'); +// $dynaform->Load( $dynaform->Fields['DYN_UID'] ); +// +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// $Properties=array( +// 'A'=>G::encrypt( $file , URL_KEY ), +// 'DYN_UID'=>$dynaform->Fields['DYN_UID'], +// 'PRO_UID'=>$dynaform->Fields['PRO_UID'], +// 'DYN_TITLE'=>$dynaform->Fields['DYN_TITLE'], +// 'DYN_TYPE'=>$dynaform->Fields['DYN_TYPE'], +// 'DYN_DESCRIPTION'=>$dynaform->Fields['DYN_DESCRIPTION'], +// 'WIDTH'=>$form->width, +// 'ENABLETEMPLATE'=>$form->enableTemplate, +// 'MODE'=>$form->mode +// ); +// +// define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); +// define('DB_XMLDB_USER',''); +// define('DB_XMLDB_PASS',''); +// define('DB_XMLDB_NAME',''); +// define('DB_XMLDB_TYPE','myxml'); +// +// $G_PUBLISH = new Publisher; +// $G_PUBLISH->publisherId=''; +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_JSEditor', '', $Properties , '', ''); +// G::RenderPage( "publish" , "raw" ); +// break; +// case 'properties': +// $dbc = new DBConnection(); +// $ses = new DBSession($dbc); +// $DYN_UID=get_ajax_value('DYN_UID'); +// if (isset($_SESSION['CURRENT_DYNAFORM']) +// && $_SESSION['CURRENT_DYNAFORM']['DYN_UID']===$DYN_UID) { +// $dynaform = new dynaform( $dbc ); +// $dynaform->Fields=$_SESSION['CURRENT_DYNAFORM']; +// }else{ +// $dynaform = new dynaform( $dbc ); +// $dynaform->Fields['DYN_UID']=$DYN_UID; +// $dynaform->Load( $dynaform->Fields['DYN_UID'] ); +// $_SESSION['CURRENT_DYNAFORM']=$dynaform->Fields; +// } +// +// $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); +// $Properties=array( +// 'A'=>G::encrypt( $file , URL_KEY ), +// 'DYN_UID'=>$dynaform->Fields['DYN_UID'], +// 'PRO_UID'=>$dynaform->Fields['PRO_UID'], +// 'DYN_TITLE'=>$dynaform->Fields['DYN_TITLE'], +// 'DYN_TYPE'=>$dynaform->Fields['DYN_TYPE'], +// 'DYN_DESCRIPTION'=>$dynaform->Fields['DYN_DESCRIPTION'], +// 'WIDTH'=>$form->width, +// 'ENABLETEMPLATE'=>$form->enableTemplate, +// 'MODE'=>$form->mode +// ); +// $G_PUBLISH = new Publisher; +// $G_PUBLISH->publisherId=''; +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Properties', 'visivility:hidden', $Properties , SYS_URI.'dynaforms/dynaforms_SaveProperties'); +// G::RenderPage( "publish" , "raw" ); +// break; +// } +// +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_AssignVariables.php b/workflow/engine/methods/dynaforms/dynaforms_AssignVariables.php new file mode 100644 index 000000000..248fad359 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_AssignVariables.php @@ -0,0 +1,28 @@ +<?php +require_once('classes/model/AdditionalTables.php'); + + $oAdditionalTables = new AdditionalTables(); + $aData = $oAdditionalTables->load($_POST['ADD_TABLE'], true); + $addTabName = $aData['ADD_TAB_NAME']; + foreach ($aData['FIELDS'] as $iRow => $aRow) { + if ($aRow['FLD_KEY'] == 1) { + $aFields['FIELDS'][$iRow] = $aRow; + } + } + + $aFields['DYN_UID'] = $_POST['DYN_UID']; + $aFields['ADD_TABLE'] = $_POST['ADD_TABLE']; + $aFields['PRO_UID'] = $_POST['PRO_UID']; + $aFields['DYN_TITLE'] = $_POST['DYN_TITLE']; + $aFields['DYN_TYPE'] = $_POST['DYN_TYPE']; + $aFields['DYN_DESCRIPTION'] = $_POST['DYN_DESCRIPTION']; + $aFields['VALIDATION_MESSAGE'] = G::LoadTranslation('ID_FILL_PRIMARY_KEYS'); + + + G::LoadClass('xmlfield_InputPM'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_AssignVariables', '', $aFields , SYS_URI.'dynaforms/dynaforms_Save'); + + G::RenderPage( "publish-raw" , "raw" ); +?> diff --git a/workflow/engine/methods/dynaforms/dynaforms_ChoseType.php b/workflow/engine/methods/dynaforms/dynaforms_ChoseType.php new file mode 100644 index 000000000..b5a285753 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_ChoseType.php @@ -0,0 +1,9 @@ +<?php + + $aFields['PRO_UID'] = isset($_GET['PRO_UID'])?$_GET['PRO_UID']:''; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_ChoseType', '', $aFields , SYS_URI.'dynaforms/dynaforms_Edit'); + + G::RenderPage( "publish-raw" , "raw" ); +?> diff --git a/workflow/engine/methods/dynaforms/dynaforms_Delete.php b/workflow/engine/methods/dynaforms/dynaforms_Delete.php new file mode 100644 index 000000000..913fc1304 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Delete.php @@ -0,0 +1,84 @@ +<?php +/** + * dynaforms_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + +require_once('classes/model/Dynaform.php'); +require_once 'classes/model/ObjectPermission.php'; +require_once 'classes/model/Step.php'; +require_once 'classes/model/StepSupervisor.php'; +require_once 'classes/model/CaseTrackerObject.php'; + +/* +In here we are deleting all datas about this Dynaform into DB +*/ + +$sfunction =$_POST['function']; + + switch($sfunction){ + + case 'getRelationInfDynaform': + $oStepSupervisor = new StepSupervisor(); + $fields2=$oStepSupervisor->loadInfo($_POST['DYN_UID']); + $result=false; + if(is_array($fields2)){ + $result=true; + } + return print $result; + break; + + case 'getDynaformAssign': + $oStep = new Step(); + $aDependent=$oStep->loadInfoAssigDynaform($_POST['PRO_UID'],$_POST['DYN_UID']); + $result=false; + if(is_array($aDependent)){ + $result=true; + } + return print $result; + break; + + case 'deleteDynaform': + $dynaform = new dynaform(); + + if (!isset($_POST['DYN_UID'])) return; + //in table dynaform + $dynaform->remove( $_POST['DYN_UID'] ); + + //in table Step + $oStep = new Step(); + $oStep->removeStep('DYNAFORM', $_POST['DYN_UID']); + + //in table ObjectPermission + $oOP = new ObjectPermission(); + $oOP->removeByObject('DYNAFORM', $_POST['DYN_UID']); + + //in table Step_supervisor + $oSS = new StepSupervisor(); + $oSS->removeByObject('DYNAFORM', $_POST['DYN_UID']); + + //in table case_tracker_object + $oCTO = new CaseTrackerObject(); + $oCTO->removeByObject('DYNAFORM', $_POST['DYN_UID']); + break; + } \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Edit.php b/workflow/engine/methods/dynaforms/dynaforms_Edit.php new file mode 100644 index 000000000..747a1cd9b --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Edit.php @@ -0,0 +1,74 @@ +<?php +/** + * dynaforms_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + require_once('classes/model/Dynaform.php'); + require_once('classes/model/AdditionalTables.php'); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_UID); + $oCriteria->addSelectColumn(AdditionalTablesPeer::ADD_TAB_NAME); + $oCriteria->add(AdditionalTablesPeer::ADD_TAB_UID, '', Criteria::NOT_EQUAL); + + $oDataset = AdditionalTablesPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + $aTablesList = Array(); + array_push($aTablesList, array('ADD_TAB_UID'=>'','ADD_TAB_NAME'=>'----------------')); + while ( $oDataset->next() ) { + array_push($aTablesList, $oDataset->getRow()); + } + + $filedNames = Array ( + "ADD_TAB_UID", + "ADD_TAB_NAME", + ); + + $aTablesList = array_merge(Array($filedNames), $aTablesList); + + $_DBArray ['ADDITIONAL_TABLES'] = $aTablesList; + $_SESSION['_DBArray'] = $_DBArray; + + $dynUid=(isset($_GET['DYN_UID'])) ? urldecode($_GET['DYN_UID']):''; + $dynaform = new dynaform(); + if ($dynUid=='') + { + $aFields['DYN_UID']= $dynUid ; + } + else + { + $aFields=$dynaform->load( $dynUid ); + } + $aFields['PRO_UID'] = isset($dynaform->Fields['PRO_UID'])?$dynaform->Fields['PRO_UID']:$_GET['PRO_UID']; + + $aFields['ACTION'] = isset($_GET['ACTION'])?$_GET['ACTION']:''; + //$aFields['READ_ONLY'] = ($_GET['ACTION']=='normal')?0:1; + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Edit', '', $aFields , SYS_URI.'dynaforms/dynaforms_Save'); + + G::RenderPage( "publish-raw" , "raw" ); diff --git a/workflow/engine/methods/dynaforms/dynaforms_Editor.php b/workflow/engine/methods/dynaforms/dynaforms_Editor.php new file mode 100644 index 000000000..e9eb3a445 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Editor.php @@ -0,0 +1,85 @@ +<?php +/** + * dynaforms_Editor.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +/* + * Created on 21/12/2007 + * + */ + G::LoadClass('dynaformEditor'); + G::LoadClass('toolBar'); + G::LoadClass('dynaFormField'); + + //G::LoadClass('configuration'); + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'FIELDS'; + + $PRO_UID=isset($_GET['PRO_UID'])?$_GET['PRO_UID']:'0'; + $DYN_UID=(isset($_GET['DYN_UID'])) ? urldecode($_GET['DYN_UID']):'0'; + $_SESSION['PROCESS'] = $_GET['PRO_UID']; + + + if ($PRO_UID==='0') return; + $process = new Process; + if ($process->exists($PRO_UID)) + { + $process->load( $PRO_UID ); + } + else + { + //TODO + print("$PRO_UID doesn't exist, continue? yes"); + } + + + $dynaform = new dynaform; + + if ($dynaform->exists($DYN_UID)) + { + $dynaform->load( $DYN_UID ); + $_SESSION['CURRENT_DYN_UID'] = $DYN_UID; + } + else + { + /* New Dynaform + * + */ + $dynaform->create(array('PRO_UID'=>$PRO_UID)); + } + + $editor=new dynaformEditor($_POST); + $editor->file=$dynaform->getDynFilename(); + $editor->home=PATH_DYNAFORM; + $editor->title=$dynaform->getDynTitle(); + $editor->dyn_uid=$dynaform->getDynUid(); + $editor->pro_uid=$dynaform->getProUid(); + $editor->dyn_type=$dynaform->getDynType(); + $editor->dyn_title=$dynaform->getDynTitle(); + $editor->dyn_description=$dynaform->getDynDescription(); + $editor->_setUseTemporalCopy(true); + $editor->_render(); + +?> diff --git a/workflow/engine/methods/dynaforms/dynaforms_FlatEditor.php b/workflow/engine/methods/dynaforms/dynaforms_FlatEditor.php new file mode 100644 index 000000000..328f0d15e --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_FlatEditor.php @@ -0,0 +1,240 @@ +<?php +/** + * dynaforms_FlatEditor.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('toolBar'); + G::LoadClass('dynaFormField'); + G::LoadClass('process'); + G::LoadClass('dynaform'); + //G::LoadClass('configuration'); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'FIELDS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //Hardcode: UID of the library by default + $PRO_UID=isset($_POST['PRO_UID'])?$_POST['PRO_UID']:'746B734DC23311'; + + $process = new Process( $dbc ); + $process->Load($PRO_UID); + + $dynaform = new dynaform( $dbc ); + $dynaform->Fields['DYN_UID']=(isset($_POST['DYN_UID'])) ? urldecode($_POST['DYN_UID']):'0'; + $dynaform->Load( $dynaform->Fields['DYN_UID'] ); + + if (isset($_POST['DYN_UID']) && ($_POST['DYN_UID']!=='')) + $file = $dynaform->Fields['DYN_FILENAME']; + else + //Hardcode: Sample of xmlform. + $file = $PRO_UID . '/' . 'myInfo'; + + /* Start Comment: If file doesn't exists, it is created */ + if (!file_exists( PATH_DYNAFORM . $file . '.xml' )) { + $newDoc = new Xml_Document(); + $newDoc->addChildNode( + new Xml_Node( 'dynaForm', 'open', '', + array( 'type'=>'xmlform', 'name' => $file ) ) ); + $newDoc->children[0]->addChildNode( + new Xml_Node( '', 'cdata', "\n" ) ); + G::verifyPath( dirname(PATH_DYNAFORM . $file . '.xml') , true ); + $newDoc->save( PATH_DYNAFORM . $file . '.xml' ); + unset( $newDoc ); + } + /* End Comment */ + + /* Start Comment: Create and temporal copy. */ + $copy = implode('',file(PATH_DYNAFORM . $file . '.xml')); + $file.='_tmp0'; + $fcopy=fopen(PATH_DYNAFORM . $file . '.xml',"w"); + fwrite($fcopy, $copy); + fclose($fcopy); + /* End Comment */ + //Removes any other CURRENT_DYNAFORM that could be pending because of a page refresh or a failure + unset($_SESSION['CURRENT_DYNAFORM']); + + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + + $title = $process->Fields['PRO_TITLE'] .' : '.$dynaform->Fields['DYN_TITLE']; + + $Parameters = array( + 'SYS_LANG' => SYS_LANG, + 'URL'=> G::encrypt( $file , URL_KEY ), + 'DYN_UID'=> $dynaform->Fields['DYN_UID'], + 'DYNAFORM_NAME'=>$title + ); + + $openDoc = new Xml_Document(); + $openDoc->parseXmlFile(PATH_DYNAFORM . $file . '.xml'); + $XmlEditor = array( + 'URL'=> G::encrypt( $file , URL_KEY ), + 'XML'=> $openDoc->getXml() + ); + + $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); + $HtmlEditor = array( + 'URL'=> G::encrypt( $file , URL_KEY ), + 'HTML'=> $form->printTemplate( $form->template , $script ) + ); + $JSEditor = array( + 'URL'=> G::encrypt( $file , URL_KEY ), + 'HTML'=> $form->printTemplate( $form->template , $script ) + ); + + /* Block : Loads the Editor configuration */ + $defaultConfig = array( + 'Editor'=>array( + 'left'=>'0',//'getAbsoluteLeft(document.getElementById("dynaformEditor[0]"))', + 'top'=>'0',//'getAbsoluteTop(document.getElementById("dynaformEditor[0]"))', + 'width'=>'document.body.clientWidth-4', + 'height'=>'document.body.clientHeight-2'//'3/4*(document.body.clientWidth-getAbsoluteLeft(document.getElementById("dynaformEditor[0]"))*2)', + ), + 'Toolbar'=>array( + 'left'=>'document.body.clientWidth-2-toolbar.clientWidth-24-3+7',//'getAbsoluteLeft(document.getElementById("dynaformEditor[0]"))', + 'top'=>'52'//'getAbsoluteTop(document.getElementById("dynaformEditor[0]"))', + ), + 'FieldsList'=>array( + 'left'=>'4+toolbar.clientWidth+24', + 'top'=>'getAbsoluteTop(document.getElementById("dynaformEditor[0]"))', + 'width'=>268-24, + 'height'=>400, + ) + ); + /*$configuration = new Configuration($dbc); + $configuration->load( array('CFG_UID'=>'DynaformEditor') ); + if ($configuration->is_new) { + $config = $defaultConfig; + $configuration->Fields['CFG_UID']='DynaformEditor'; + $configuration->Fields['CFG_VALUE']=serialize( $config ); + //$configuration->Save(); + } else { + $config = unserialize( $configuration->Fields['CFG_VALUE'] ); + $config = G::array_merges( $defaultConfig , $config ); + }*/ + $config=$defaultConfig; + /* End Block */ + + $G_PUBLISH = new Publisher; + $G_PUBLISH->publisherId='dynaformEditor'; + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->setTitle("Dynaform Editor"); + + //$G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/fields_ShortList', '', $Parameters , '', SYS_URI.'dynaforms/dynaforms_PagedTableAjax'); + $G_PUBLISH->AddContent('blank'); + + $panelConf = array( + 'title'=>G::LoadTranslation('ID_DYNAFORM_EDITOR').' - ['.$title.']', + 'style'=>array( + 'title'=>array('textAlign'=>'left') + ), + 'width'=>700, + 'height'=>600, + 'tabWidth'=>120, + 'modal'=>true, + 'drag'=>false, + 'resize'=>false, + 'blinkToFront'=>false + ); + $panelConf = array_merge( $panelConf , $config['Editor'] ); + + $G_PUBLISH->AddContent('panel-init', 'mainPanel', $panelConf ); + $G_PUBLISH->AddContent('xmlform', 'toolbar', 'dynaforms/fields_Toolbar', '', $Parameters , '', ''); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Editor', '', $Parameters , '', ''); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_XmlEditor', '', $XmlEditor , '', ''); + //This space will be loaded dynamically by el js function: "changoToHtmlCode" + $G_PUBLISH->AddContent('blank'); + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/fields_List', '', $Parameters , '', SYS_URI.'dynaforms/dynaforms_PagedTableAjax'); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_JSEditor', '', $JSEditor , '', ''); + $G_PUBLISH->AddContent('blank'); +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Properties', '', $JSEditor , '', ''); + + $G_PUBLISH->AddContent('panel-tab','Preview','dynaformEditor[3]','changoToPreview','saveCurrentView'); + $G_PUBLISH->AddContent('panel-tab','XML Code','dynaformEditor[4]','changoToXmlCode','saveCurrentView'); + $G_PUBLISH->AddContent('panel-tab','HTML Template','dynaformEditor[5]','changoToHtmlCode','saveCurrentView'); + $G_PUBLISH->AddContent('panel-tab','Fields List','dynaformEditor[6]','changoToFieldsList','saveCurrentView'); + $G_PUBLISH->AddContent('panel-tab','JavaScripts','dynaformEditor[7]','changoToJavascripts','saveCurrentView'); + $G_PUBLISH->AddContent('panel-tab','Properties','dynaformEditor[8]','changoToProperties','saveCurrentView'); + $G_PUBLISH->AddContent('panel-close'); + + G::RenderPage( "publish", "raw" ); + +?> +<script> + var toolbar = document.getElementById('fields_Toolbar') + var fieldsList = document.getElementById('dynaformEditor[0]') + var tableHeight=<?= $config['FieldsList']['height'] ?>; + var tableWidth=<?= $config['FieldsList']['width'] ?>; + var toolbarTop=<?= $config['Toolbar']['top'] ?>; + var toolbarLeft=<?= $config['Toolbar']['left'] ?>; + var fieldsListTop=<?= $config['FieldsList']['top'] ?>//(toolbarTop+toolbar.clientHeight+44+8 ); + var fieldsListLeft=<?= $config['FieldsList']['left'] ?>; + mainPanel.elements.headerBar.style.backgroundColor='#CBDAEF'; + mainPanel.elements.headerBar.style.borderBottom='1px solid #808080'; + mainPanel.elements.headerBar.appendChild(toolbar); + //var fieldsListToolBar = toolbarWindow('Fields list', fieldsList , fieldsListLeft, fieldsListTop, tableWidth+24, tableHeight+44 ); + //var fieldsToolBar = toolbarWindow('Toolbar', toolbar, toolbarLeft, toolbarTop, toolbar.clientWidth+10, toolbar.clientHeight+44+4 ); + mainPanel.events.remove = function(){ + closeDyna(); + //fieldsListToolBar.remove(); + //fieldsToolBar.remove(); + } + resizeXmlEditor(); + + + function toolbarWindow ( title , element, x, y, width, height, callbackFn ) { + var myPanel = new leimnud.module.panel(); + myPanel.options = { + size:{w:width,h:height}, + position:{x:x,y:y}, + title: title, + theme: "processmaker", + control: { close :false, roll :false, drag :true, resize :false}, + fx: { + //shadow :true, + blinkToFront:true, + opacity :true, + drag:true, + modal: false, + rolled:false + } + }; + myPanel.setStyle={ + modal:{backgroundColor:"transparent"}, + content:{'border':'0px solid white','backgroundColor':'transparent'} + }; + myPanel.make(); + myPanel.addContent(element); + return myPanel; + } +</script> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_List.php b/workflow/engine/methods/dynaforms/dynaforms_List.php new file mode 100644 index 000000000..615453bab --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_List.php @@ -0,0 +1,46 @@ +<?php +/** + * dynaforms_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'DYNAFORMS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //Hardcode: UID of the library by default + $PRO_UID='746B734DC23311'; + $Fields['PRO_UID'] = $PRO_UID; + $Fields['SYS_LANG'] = SYS_LANG; + $G_PUBLISH = new Publisher; + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/dynaforms_List', '', $Fields , 'dynaforms_Save'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_NewPlugin.php b/workflow/engine/methods/dynaforms/dynaforms_NewPlugin.php new file mode 100644 index 000000000..ddd0650b6 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_NewPlugin.php @@ -0,0 +1,67 @@ +<?php +/** + * dynaforms_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //call plugin + // $oPluginRegistry = &PMPluginRegistry::getSingleton(); + // $existsDynaforms = $oPluginRegistry->existsTrigger(PM_NEW_DYNAFORM_LIST ); + +//for now, we are going with the default list, because the plugin is not complete +include ('dynaforms_Edit.php'); +die; + +//---***************** + + if ( !$existsDynaforms ) { + include ('dynaforms_Edit.php'); + die; + } + print "Existe"; + print (class_exists('folderData')); + + die; + //end plugin +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin =n 'login/login' ); + + require_once('classes/model/Dynaform.php'); + + $dynUid=(isset($_GET['DYN_UID'])) ? urldecode($_GET['DYN_UID']):''; + $dynaform = new dynaform(); + if ($dynUid=='') + { + $aFields['DYN_UID']= $dynUid ; + } + else + { + $aFields=$dynaform->load( $dynUid ); + } + $aFields['PRO_UID'] = isset($dynaform->Fields['PRO_UID'])?$dynaform->Fields['PRO_UID']:$_GET['PRO_UID']; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Edit', '', $aFields , SYS_URI.'dynaforms/dynaforms_Save'); + + G::RenderPage( "publish-raw" , "raw" ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_PagedTableAjax.php b/workflow/engine/methods/dynaforms/dynaforms_PagedTableAjax.php new file mode 100644 index 000000000..c8adc53c1 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_PagedTableAjax.php @@ -0,0 +1,125 @@ +<?php +/** + * dynaforms_PagedTableAjax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + function pagedTable_BeforeQuery(&$ntable) + { + $file = G::decrypt( $ntable->xmlForm->values['URL'] , URL_KEY ); + /* Start Block: Defines the virtual XMLDB*/ + G::LoadClass('xmlDb'); + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + /* End Block*/ + } + require_once(PATH_GULLIVER_HOME.'methods/pagedTableAjax.php'); +die; + G::LoadSystem('pagedTable'); + G::LoadInclude('ajax'); + + $id=get_ajax_value('ptID'); + $ntable= unserialize($_SESSION['pagedTable['.$id.']']); + $page=get_ajax_value('page'); + $function=get_ajax_value('function'); + + if (isset($ntable->filterForm_Id) && ($ntable->filterForm_Id!=='')) { + $filterForm=new filterForm(G::getUIDName( $ntable->filterForm_Id )); + $filterForm->values=$_SESSION[$filterForm->id]; + parse_str( urldecode(get_ajax_value('filter')) , $newValues); + if (isset($newValues['form'])) { + $filterForm->setValues($newValues['form']); + $filter = array(); + foreach($filterForm->fields as $fieldName => $field ){ + if (($field->dataCompareField!=='') && (isset($newValues['form'][$fieldName]))) + $filter[$field->dataCompareField] = $filterForm->values[$fieldName]; + $ntable->filterType[$field->dataCompareField] = $field->dataCompareType; + } + $ntable->filter = $filter;//G::http_build_query($filter); + } + } + $fastSearch=get_ajax_value('fastSearch'); + if (isset($fastSearch)) $ntable->fastSearch= urldecode($fastSearch); + $orderBy=get_ajax_value('order'); + if (isset($orderBy)) { + $orderBy=urldecode($orderBy); + $ntable->orderBy=$orderBy; + } + if (isset($page) && $page!=='') $ntable->currentPage=(int) $page; + + $file = G::decrypt( $ntable->xmlForm->values['URL'] , URL_KEY ); + /* Start Block: Defines the virtual XMLDB*/ + G::LoadClass('xmlDb'); + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + /* End Block*/ + + $ntable->prepareQuery(); + switch ($function) + { + case "showHideField": + $field=get_ajax_value('field'); + $ntable->style[$field]['showInTable']= + ($ntable->style[$field]['showInTable']==='0')?'1':'0'; + break; + case "paint": + break; + case "delete": + $ntable->prepareQuery(); + parse_str(get_ajax_value('field'),$field); + foreach($field as $key => $value) $field[$key]=urldecode($value); + $ntable->ses->execute($ntable->replaceDataField($ntable->sqlDelete,$field)); + break; + case "update": + $ntable->prepareQuery(); + parse_str(get_ajax_value('field'),$field); + foreach($field as $key => $value) $field[$key]=urldecode($value); + parse_str(get_ajax_value('update'),$fieldup); + foreach($fieldup as $key => $value) $field['new'.$key]=urldecode($value); //join + $ntable->ses->execute($ntable->replaceDataField($ntable->sqlUpdate,$field)); + break; + case "insert": + $ntable->prepareQuery(); + parse_str(get_ajax_value('field'),$field); + foreach($field as $key => $value) $field[$key]=urldecode($value); + $ntable->ses->execute($ntable->replaceDataField($ntable->sqlInsert,$field)); + break; + case "printForm": + parse_str(get_ajax_value('field'),$field); + parse_str(get_ajax_value('field'),$field); + foreach($field as $key => $value) $field[$key]=urldecode($value); + $ntable->printForm(get_ajax_value('filename'),$field); + return ; + } + $ntable->renderTable( 'content' ); + G::LoadClass('configuration'); + $dbc = new DBConnection(); + $conf = new Configuration( $dbc , $ntable ); + $conf->setConfig($ntable->__Configuration,$ntable,$conf->aConfig); + $conf->saveConfig('pagedTable',$ntable->__OBJ_UID,'',$_SESSION['USER_LOGGED'],''); +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Preview.php b/workflow/engine/methods/dynaforms/dynaforms_Preview.php new file mode 100644 index 000000000..1f029e4da --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Preview.php @@ -0,0 +1,66 @@ +<?php +/** + * dynaforms_Preview.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('toolBar'); + G::LoadClass('dynaFormField'); + + if (!(isset($_POST['A']) && $_POST['A']!=='')) return; + + $file = G::decrypt( $_POST['A'] , URL_KEY ); + + $G_PUBLISH = new Publisher; + $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); + switch(basename($form->template,'.html')) + { + case 'grid': $template='grid';break; + default: $template='xmlform'; + } + $G_PUBLISH->AddContent('dynaform', $template , $file, '', + array( + '__DYNAFORM_OPTIONS'=> array( + 'PREVIOUS_STEP' => '#', + 'NEXT_STEP' => '#', + 'PREVIOUS_ACTION' => 'return false;', + 'NEXT_ACTION' => 'return false;' + ) + ), ''); + G::RenderPage('publish','raw'); + + + /* $toolbar = new ToolBar( '/dynaforms/dynaforms_Toolbar' , PATH_XMLFORM, SYS_LANG, false ); + + print($toolbar->render( $toolbar->template , $script ));*/ + + + //$form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); + + //print($form->render( $form->template , $script )); + + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Save.php b/workflow/engine/methods/dynaforms/dynaforms_Save.php new file mode 100644 index 000000000..e394d4114 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Save.php @@ -0,0 +1,82 @@ +<?php +/** + * dynaforms_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + require_once('classes/model/Dynaform.php'); + require_once('classes/model/Content.php'); + + if(isset($_POST['function']) && $_POST['function']=='lookforNameDynaform'){ + $snameDyanform=urldecode($_POST['NAMEDYNAFORM']); + $sPRO_UID=urldecode($_POST['proUid']); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn ( DynaformPeer::DYN_UID ); + $oCriteria->add(DynaformPeer::PRO_UID, $sPRO_UID); + $oDataset = DynaformPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $flag=true; + while ($oDataset->next() && $flag) { + $aRow = $oDataset->getRow(); + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->addSelectColumn('COUNT(*) AS DYNAFORMS'); + $oCriteria1->add(ContentPeer::CON_CATEGORY, 'DYN_TITLE'); + $oCriteria1->add(ContentPeer::CON_ID, $aRow['DYN_UID']); + $oCriteria1->add(ContentPeer::CON_VALUE, $snameDyanform); + $oCriteria1->add(ContentPeer::CON_LANG, SYS_LANG); + $oDataset1 = ContentPeer::doSelectRS($oCriteria1); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aRow1 = $oDataset1->getRow(); + + if($aRow1['DYNAFORMS'])$flag=false; + + + } + print $flag; + + } else { + $dynaform = new dynaform(); + + if ($_POST['form']['DYN_UID']==='') unset($_POST['form']['DYN_UID']); + + if (isset($_POST['form']['DYN_UID'])) + { + $dynaform->Save( $_POST['form'] ); + } + else + { + if (!isset($_POST['form']['ADD_TABLE'])||$_POST['form']['ADD_TABLE']==""){ + $aFields=$dynaform->create( $_POST['form'] ); + } else { + $aFields=$dynaform->createFromPMTable( $_POST['form'], $_POST['form']['ADD_TABLE']); + } + $_POST['form']['DYN_UID']=$dynaform->getDynUid(); + $dynaform->update( $_POST['form'] ); + } + echo $dynaform->getDynUid(); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_SaveProperties.php b/workflow/engine/methods/dynaforms/dynaforms_SaveProperties.php new file mode 100644 index 000000000..26623ecca --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_SaveProperties.php @@ -0,0 +1,55 @@ +<?php +/** + * dynaforms_SaveProperties.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadInclude('ajax'); + G::LoadClass('dynaform'); + G::LoadClass('xmlDb'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //$dynaform = new dynaform( $dbc ); + + if ($_POST['form']['DYN_UID']==='') unset($_POST['form']['DYN_UID']); + $Fields = $_POST['form']; + if (!isset($Fields['DYN_UID'])) return; + $file = G::decrypt( $Fields['A'] , URL_KEY ); + $Fields['DYN_FILENAME'] = (strcasecmp(substr($file,-5),'_tmp0')==0)? substr($file,0,strlen($file)-5) : $file; + $_SESSION['CURRENT_DYNAFORM']=$Fields; + //$dynaform->Save( $Fields ); + + $dbc2 = new DBConnection( PATH_DYNAFORM . $file . '.xml' ,'','','','myxml' ); + $ses2 = new DBSession($dbc2); + + + if (!isset($Fields['ENABLETEMPLATE'])) $Fields['ENABLETEMPLATE'] ="0"; + + $ses2->execute(G::replaceDataField("UPDATE . SET WIDTH = @@WIDTH WHERE XMLNODE_NAME = 'dynaForm' ", $Fields)); + $ses2->execute(G::replaceDataField("UPDATE . SET ENABLETEMPLATE = @@ENABLETEMPLATE WHERE XMLNODE_NAME = 'dynaForm' ", $Fields)); + $ses2->execute(G::replaceDataField("UPDATE . SET MODE = @@MODE WHERE XMLNODE_NAME = 'dynaForm' ", $Fields)); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Save_as.php b/workflow/engine/methods/dynaforms/dynaforms_Save_as.php new file mode 100644 index 000000000..c83e3b9a0 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Save_as.php @@ -0,0 +1,109 @@ +<?php +/** + * dynaforms_Save_as.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * dynaforms_Save_as.php + * script that handles the save-as functionality of a dynaform + * replicates the dynaform structure and content physical and in DB + * also handles the complete copy of field-events related and + * the html template if its required too. + */ + require_once('classes/model/Dynaform.php'); + if (!class_exists("FieldCondition")){ + require_once "classes/model/FieldCondition.php"; + } + + try + { + $con = Propel::getConnection( DynaformPeer::DATABASE_NAME ); + $frm=$_POST['form']; + $PRO_UID=$frm['PRO_UID']; + $DYN_UID=$frm['DYN_UID']; + $DYN_TYPE=$frm['DYN_TYPE']; + + // checks if there are conditions attached to the dynaform + $oFieldCondition = new FieldCondition(); + $aConditions = $oFieldCondition->getAllByDynUid($DYN_UID); + + $dynaform = new dynaform; + /*Save Register*/ + + $dynUid = ( G::generateUniqueID() ); + + $dynaform->setDynUid ( $dynUid ); + $dynaform->setProUid ( $PRO_UID ); + $dynaform->setDynType ( $DYN_TYPE ); + $dynaform->setDynFilename ( $PRO_UID . PATH_SEP . $dynUid ); + + $con->begin(); + $res = $dynaform->save(); + $dynaform->setDynTitle ( $frm['DYN_TITLENEW'] ); + $dynaform->setDynDescription ((!$frm['DYN_DESCRIPTIONNEW'])?'Default Dynaform Description':$frm['DYN_DESCRIPTIONNEW']); + + //$con->commit(); + + $hd = fopen(PATH_DYNAFORM . $PRO_UID . '/' . $DYN_UID . '.xml',"r"); + $hd1 = fopen (PATH_DYNAFORM . $PRO_UID . '/' . $dynUid . '.xml' ,"w"); + $templateFilename = PATH_DYNAFORM . $PRO_UID . '/' . $DYN_UID . '.html'; + + // also make a copy of the template file in case that the html edition is enabled + if(file_exists($templateFilename)){ + $templateHd = fopen($templateFilename,"r"); + $templateHd1 = fopen(PATH_DYNAFORM . $PRO_UID . '/' . $dynUid . '.html' ,"w"); + } + + // also copy all the necessarily conditions if there are any + foreach ($aConditions as $condition){ + $condition['FCD_UID'] = ( G::generateUniqueID() ); + $condition['FCD_DYN_UID'] = $dynUid; + $oFieldCondition->quickSave($condition); + } + // checks if the physical dynaform file exists and copy the contents + if($hd){ + while(!feof($hd)){ + $line=fgets($hd,4096); + fwrite($hd1,str_replace($DYN_UID,$dynUid,$line)); + } + } + + fclose($hd); + fclose($hd1); + + // check if the template file also exists + if(isset($templateHd)){ + while(!feof($templateHd)){ + $line=fgets($templateHd,4096); + fwrite($templateHd1,str_replace($DYN_UID,$dynUid,$line)); + } + fclose($templateHd); + fclose($templateHd1); + } + + } + catch(Exception $e) + { + return (array) $e; + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_Saveas.php b/workflow/engine/methods/dynaforms/dynaforms_Saveas.php new file mode 100644 index 000000000..d8f499be9 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_Saveas.php @@ -0,0 +1,44 @@ +<?php +/** + * dynaforms_Saveas.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + require_once('classes/model/Dynaform.php'); + + $dynUid=(isset($_GET['DYN_UID'])) ? urldecode($_GET['DYN_UID']):''; + $dynaform = new dynaform(); + + + + $aFields=$dynaform->load( $dynUid ); + //print_r($aFields); + +//$aFields['PRO_UID'] = isset($dynaform->Fields['PRO_UID'])?$dynaform->Fields['PRO_UID']:$_GET['PRO_UID']; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/dynaforms_Saveas', '', $aFields , SYS_URI.'dynaforms/dynaforms_Save_as'); + + G::RenderPage( "publish-raw" , "raw" ); diff --git a/workflow/engine/methods/dynaforms/dynaforms_ToolbarAjax.php b/workflow/engine/methods/dynaforms/dynaforms_ToolbarAjax.php new file mode 100644 index 000000000..32310e2d8 --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_ToolbarAjax.php @@ -0,0 +1,34 @@ +<?php + +/** + * @author gustavo cruz gustavo-at-colosa.com + * @param POST + * @desc evaluates the dynaform type and other parameters in order to + * render the correct toolbar in each case + * + */ + +G::LoadClass('toolBar'); + + + global $G_PUBLISH; + $script=''; + $G_PUBLISH = new Publisher; + $Parameters = array( + 'SYS_LANG' => SYS_LANG, + 'URL'=> G::encrypt( $_POST['FILE'] , URL_KEY ), + 'DYN_UID'=> $_POST['DYN_UID'], + 'PRO_UID'=> $_POST['PRO_UID'], + 'DYNAFORM_NAME'=>$_POST['DYN_TITLE'], + 'FILE'=>$_POST['FILE'], + ); +//$Parameters = ""; + + if($_POST['TOOLBAR']=="grid"){ + $G_PUBLISH->AddContent('xmlform', 'toolbar', 'dynaforms/fields_ToolbarGrid', 'display:none', $Parameters , '', ''); + } else { + $G_PUBLISH->AddContent('xmlform', 'toolbar', 'dynaforms/fields_Toolbar', 'display:none', $Parameters , '', ''); + } + + G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/dynaforms_checkDependentFields.php b/workflow/engine/methods/dynaforms/dynaforms_checkDependentFields.php new file mode 100644 index 000000000..b97233adf --- /dev/null +++ b/workflow/engine/methods/dynaforms/dynaforms_checkDependentFields.php @@ -0,0 +1,134 @@ +<?php +/** + * dynaforms_checkDependentFields.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2010 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * this file is a fix to a dependency bug it was just a minor improvement, + * also the functionality of dependent fields in grids doesn't depends in this + * file so this is somewhat expendable. + * + */ + function subDependencies( $k , &$G_FORM , &$aux, $grid = '') { + $myDependentFields = ''; + if (array_search( $k, $aux )!==FALSE) return array(); + if ($grid == '') { + if (!array_key_exists( $k , $G_FORM->fields )) return array(); + if (!isset($G_FORM->fields[$k]->dependentFields)) return array(); + $aux[] = $k; + $mydependentFields = $G_FORM->fields[$k]->dependentFields; + + } + else { + if (!array_key_exists( $k , $G_FORM->fields[$grid]->fields )) return array(); + if (!isset($G_FORM->fields[$grid]->fields[$k]->dependentFields)) return array(); + $myDependentFields = $G_FORM->fields[$grid]->fields[$k]->dependentFields; + $myDependentFields = explode( ',', $G_FORM->fields[$grid]->fields[$k]->dependentFields); + + } + return $myDependentFields; + } + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + +$sDynUid = G::getUIDName(urlDecode($_POST['DYN_UID'])); +$json=new Services_JSON(); +$formValues=($json->decode($_POST['fields'])); +$sFieldName = $_POST['fieldName']; +$sMasterField = ''; +$sPath = PATH_DYNAFORM; +$G_FORM = new form( $sDynUid , $sPath ); +$aux = array(); +//g::pr($newValues); +$newValues=$json->decode(urlDecode(stripslashes($_POST['form']))); +//g::pr($formValues); + + if (isset($_POST['grid'])) { +// echo ("is grid"); +// die(); + $_POST['row'] = (int)$_POST['row']; + $aAux = array(); + foreach ($newValues as $sKey => $newValue) { + $newValue = (array)$newValue; + $aKeys = array_keys($newValue); + $aValues = array(); + for ($i = 1; $i <= ($_POST['row'] - 1); $i++) { + $aValues[$i] = array($aKeys[0] => ''); + } + $aValues[$_POST['row']] = array($aKeys[0] => $newValue[$aKeys[0]]); + $newValues[$sKey]->$_POST['grid'] = $aValues; + unset($newValues[$sKey]->$aKeys[0]); + //echo "<pre>"; + + //echo "</pre>"; + } + } + + $dependentFields = array(); + $aux = array(); + $found =false; + for($r=0;$r<sizeof($newValues);$r++) { + $newValues[$r]=(array)$newValues[$r]; + $G_FORM->setValues($newValues[$r]); + //Search dependent fields + foreach($newValues[$r] as $k => $v) { + if (!is_array($v)) { + $myDependentFields = subDependencies( $k , $G_FORM , $aux ); + if(!$found){ + if (in_array($sFieldName,$myDependentFields)){ + $sMasterField = $k; + $found=true; + } + } + $_SESSION[$G_FORM->id][$k] = $v; + } + else { +// echo "-$r-"; +// g::pr($v); +// echo "--"; + foreach($v[$_POST['row']] as $k1 => $v1) { + $myDependentFields = subDependencies( $k1 , $G_FORM , $aux, $_POST['grid'] ); + if(!$found){ + if (in_array($sFieldName,$myDependentFields)){ + $sMasterField = $k1; + $found=true; + } + } + $_SESSION[$G_FORM->id][$_POST['grid']][$_POST['row']][$k1] = $v1; + } + } + $dependentFields=array_merge($dependentFields, $myDependentFields); + } + } + switch ($_POST['function']){ + case 'showDependentFields': + echo $json->encode(array_unique($dependentFields)); + break; + case 'showDependentOf': + echo $sMasterField; + break; + } + +//echo "one<br>"; + +?> diff --git a/workflow/engine/methods/dynaforms/fieldsGetterAjax.php b/workflow/engine/methods/dynaforms/fieldsGetterAjax.php new file mode 100644 index 000000000..441e90ace --- /dev/null +++ b/workflow/engine/methods/dynaforms/fieldsGetterAjax.php @@ -0,0 +1,110 @@ +<?php +// added by gustavo cruz gustavo-at-colosa.com +/** + * @name apply_properties + * @author gustavo cruz + * @access public + * @param $gridFields + * @return $invalidFields + * @desc this function validates which fields cannot be part of a + * grid dynaform those are: password, title, subtitle, button, submit, + * reset, listbox, checkbox, check group, radio group, file, javascript + * and obviously grid. + * + **/ +G::LoadClass('xmlDb'); + + function validateGridConversion ($gridFields){ + $invalidFields = array(); + foreach($gridFields as $value){ + + switch($value['TYPE']){ + case 'title': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'checkbox': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'radiogroup': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'submit': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'password': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'subtitle': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'button': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'reset': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'listbox': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'checkgroup': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'file': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'javascript': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + case 'grid': + $invalidFields[] = $value['XMLNODE_NAME']; + break; + } + } + return $invalidFields; + } + // end + + // added by gustavo cruz gustavo-at-colosa.com + /** + * @name getTemporalFields + * @author gustavo cruz + * @access public + * @param $file - the name of the dynaform file + * @return invalidFields string + * @desc this function get the fields that are part of the temporal + * dynaform file. + **/ + function getTemporalFields($file){ + try { + //$G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/fields_List', 'display:none', $Parameters , '', SYS_URI.'dynaforms/dynaforms_PagedTableAjax'); + $i = 0; + $aFields = array(); + $aFields[] = array('XMLNODE_NAME' => 'char', + 'TYPE' => 'char', + 'UP' => 'char', + 'DOWN' => 'char'); + $oSession = new DBSession(new DBConnection(PATH_DYNAFORM . $file . '_tmp0.xml', '', '', '', 'myxml')); + $oDataset = $oSession->Execute('SELECT * FROM dynaForm WHERE NOT( XMLNODE_NAME = "" ) AND TYPE <> "pmconnection"'); + $iMaximun = $oDataset->count(); + while ($aRow = $oDataset->Read()) { + $aFields[] = array('XMLNODE_NAME' => $aRow['XMLNODE_NAME'], + 'TYPE' => $aRow['TYPE'], + 'UP' => ($i > 0 ? G::LoadTranslation('ID_UP') : ''), + 'DOWN' => ($i < $iMaximun-1 ? G::LoadTranslation('ID_DOWN') : ''), + 'row__' => ($i + 1)); + $i++; + } + // print_r($aFields); + // die; + } catch (Exception $e) {} + $invalidFields = validateGridConversion($aFields); + if (count($invalidFields)> 0){ + return (implode(", " , $invalidFields)); + } else { + return "ok"; + } + } + // here make a response of the invalid fields for the Ajax request + echo getTemporalFields($_POST['FILENAME']); +// end +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fieldsHandler.php b/workflow/engine/methods/dynaforms/fieldsHandler.php new file mode 100755 index 000000000..a10c66c80 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fieldsHandler.php @@ -0,0 +1,32 @@ +<? +/** + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz <erik@colosa.com> + * @Date Aug 26th, 2009 + */ + + $G_PUBLISH = new Publisher(); + $oHeadPublisher =& headPublisher::getSingleton(); + $G_PUBLISH->AddContent('view', 'dynaforms/fieldsHandlerViewer'); + G::RenderPage( "publish" , "raw" ); diff --git a/workflow/engine/methods/dynaforms/fieldsHandlerAjax.php b/workflow/engine/methods/dynaforms/fieldsHandlerAjax.php new file mode 100755 index 000000000..6449230ca --- /dev/null +++ b/workflow/engine/methods/dynaforms/fieldsHandlerAjax.php @@ -0,0 +1,113 @@ +<?/** + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz <erik@colosa.com> + * @Date Aug 26th, 2009 + */ + + $request = $_POST['request']; + + switch($request){ + case 'save': + if( isset($_POST['items']) ){ + $items = $_POST['items']; + $tmpfilename = $_SESSION['Current_Dynafom']['Parameters']['FILE']; + G::LoadSystem('dynaformhandler'); + + $o = new dynaFormHandler(PATH_DYNAFORM."{$tmpfilename}.xml"); + + $list_elements = explode(',', $items); + + $e = Array(); + foreach($list_elements as $element){ + $e[] = $o->getNode($element); + } + + $o->__cloneEmpty(); + + foreach($e as $e1){ + $o->setNode($e1); + } + + + } + break; + + case 'saveHidden': + $tmpfilename = $_SESSION['Current_Dynafom']['Parameters']['FILE']; + G::LoadSystem('dynaformhandler'); + $o = new dynaFormHandler(PATH_DYNAFORM."{$tmpfilename}.xml"); + $hidden_items = Array(); + + $has_hidden_items = false; + if( isset($_POST['hidden']) ){ + if( $_POST['hidden'] != '' ){ + $has_hidden_items = true; + + $hidden_items = explode(',', $_POST['hidden']); + $hidden_items_tmp = $hidden_items; + $hidden_items = Array(); + foreach($hidden_items_tmp as $hItem){ + $tmp = explode("@", $hItem); + $hidden_items[] = $tmp[1]; + } + $hidden_items_tmp = implode(',', $hidden_items); + } + } + + if( $has_hidden_items ){ + $hStr = ''; + foreach($hidden_items as $hItem){ + $hStr .= "hideRowById('$hItem'); "; + } + //echo 'something todo'; + //print_r($hidden_items); + $msg = " @! Autogenerated by Processmaker weboot; Do not modify this content, this is autogenerated alway when dynaform is updated "; + + if( $o->nodeExists('___pm_boot_strap___') ){ + $o->remove('___pm_boot_strap___'); + } + $o->add('___pm_boot_strap___', Array('type'=>'javascript', "meta"=>G::encrypt($hidden_items_tmp, 'dynafieldsHandler')), "/*$msg*/ $hStr"); + + } else { //we must to remove the boot strap node; + $o->remove('___pm_boot_strap___'); + } + break; + default: + echo 'no request param.'; + } + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fieldsHandlerViewer.php b/workflow/engine/methods/dynaforms/fieldsHandlerViewer.php new file mode 100755 index 000000000..260750655 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fieldsHandlerViewer.php @@ -0,0 +1,36 @@ +<? +/** + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz <erik@colosa.com> + * @Date Aug 26th, 2009 + */ + + $G_PUBLISH = new Publisher(); + + $_POST['fieldsList'] = Array('button', 'checkbox', 'checkgroup', 'currency', 'date', 'dropdown', 'file', 'grid', 'hidden', 'javascript', + 'link', 'listbox', 'password', 'percentage', 'radiogroup', 'radiogroupview', 'reset', 'submit', 'subtitle', 'suggest', 'text', + 'textarea', 'title', 'yesno'); + + $G_PUBLISH->AddContent('view', 'dynaforms/fieldsHandler'); + G::RenderPage( "publish" , "raw" ); diff --git a/workflow/engine/methods/dynaforms/fields_Ajax.php b/workflow/engine/methods/dynaforms/fields_Ajax.php new file mode 100644 index 000000000..b0437aa77 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_Ajax.php @@ -0,0 +1,110 @@ +<?php +/** + * fields_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +/*NEXT LINE: Runs any configuration defined to be executed before dependent fields recalc*/ +if (isset($_SESSION['CURRENT_PAGE_INITILIZATION'])) eval($_SESSION['CURRENT_PAGE_INITILIZATION']); +//G::LoadSystem('json'); +require_once(PATH_THIRDPARTY . 'pear/json/class.json.php'); +$json=new Services_JSON(); +$G_FORM=new form(G::getUIDName(urlDecode($_POST['form']))); +$G_FORM->id=urlDecode($_POST['form']); +$G_FORM->values=$_SESSION[$G_FORM->id]; + +G::LoadClass('xmlDb'); +$file = G::decrypt( $G_FORM->values['PME_A'] , URL_KEY ); +define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); +define('DB_XMLDB_USER',''); +define('DB_XMLDB_PASS',''); +define('DB_XMLDB_NAME',''); +define('DB_XMLDB_TYPE','myxml'); + +$newValues=($json->decode(urlDecode(stripslashes($_POST['fields'])))); +//Resolve dependencies +//Returns an array ($dependentFields) with the names of the fields +//that depends of fields passed through AJAX ($_GET/$_POST) +$dependentFields=array(); $aux=array(); +for($r=0;$r<sizeof($newValues);$r++) { + $newValues[$r]=(array)$newValues[$r]; + $G_FORM->setValues($newValues[$r]); + //Search dependent fields + foreach($newValues[$r] as $k => $v) { + $myDependentFields = subDependencies( $k , $G_FORM , $aux ); + $dependentFields=array_merge($dependentFields, $myDependentFields); + } +} +$dependentFields=array_unique($dependentFields); + +//Parse and update the new content +$template = PATH_CORE . 'templates/xmlform.html'; +$newContent=$G_FORM->getFields($template); + +//Returns the dependentFields's content +$sendContent=array(); +$r=0; +foreach($dependentFields as $d) { + $sendContent[$r]->name=$d; + $sendContent[$r]->content=NULL; + foreach($G_FORM->fields[$d] as $attribute => $value) { + switch($attribute) { + case 'type': + $sendContent[$r]->content->{$attribute}=$value; break; + case 'options': + $sendContent[$r]->content->{$attribute}=toJSArray($value); break; + } + } + $sendContent[$r]->value=$G_FORM->values[$d]; + $r++; +} +echo($json->encode($sendContent)); + +function toJSArray($array) +{ + $result=array(); + foreach($array as $k => $v){ + $o=NULL; + $o->key=$k; + $o->value=$v; + $result[]=$o; + } + return $result; +} + +function subDependencies( $k , &$G_FORM , &$aux ) { + if (array_search( $k, $aux )!==FALSE) return array(); + if (!array_key_exists( $k , $G_FORM->fields )) return array(); + if (!isset($G_FORM->fields[$k]->dependentFields)) return array(); + $aux[] = $k; + $myDependentFields = explode( ',', $G_FORM->fields[$k]->dependentFields); + for( $r=0 ; $r < sizeof($myDependentFields) ; $r++ ) { + if ($myDependentFields[$r]=="") unset($myDependentFields[$r]); + } + $mD = $myDependentFields; + foreach( $mD as $ki) { + $myDependentFields = array_merge( $myDependentFields , subDependencies( $ki , $G_FORM , $aux ) ); + } + return $myDependentFields; +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fields_Delete.php b/workflow/engine/methods/dynaforms/fields_Delete.php new file mode 100644 index 000000000..6b12b492e --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_Delete.php @@ -0,0 +1,64 @@ +<?php +/** + * fields_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('dynaFormField'); + + if (!(isset($_POST['A']) && $_POST['A']!=='')) return; + + $file = G::decrypt( $_POST['A'] , URL_KEY ); + + $dbc = new DBConnection( PATH_DYNAFORM . $file . '.xml' ,'','','','myxml' ); + $ses = new DBSession($dbc); + + $fields = new DynaFormField( $dbc ); + + if (!isset($_POST['XMLNODE_NAME'])) return; + + $fields->Delete( $_POST['XMLNODE_NAME'] ); + + G::LoadClass('xmlDb'); + $i = 0; + $aFields = array(); + $aFields[] = array('XMLNODE_NAME' => 'char', + 'TYPE' => 'char', + 'UP' => 'char', + 'DOWN' => 'char'); + $oSession = new DBSession(new DBConnection(PATH_DYNAFORM . $file . '.xml', '', '', '', 'myxml')); + $oDataset = $oSession->Execute('SELECT * FROM dynaForm WHERE NOT( XMLNODE_NAME = "" )'); + $iMaximun = $oDataset->count(); + while ($aRow = $oDataset->Read()) { + $aFields[] = array('XMLNODE_NAME' => $aRow['XMLNODE_NAME'], + 'TYPE' => $aRow['TYPE'], + 'UP' => ($i > 0 ? G::LoadTranslation('ID_UP') : ''), + 'DOWN' => ($i < $iMaximun-1 ? G::LoadTranslation('ID_DOWN') : '')); + $i++; + } + global $_DBArray; + $_DBArray['fields'] = $aFields; + $_SESSION['_DBArray'] = $_DBArray; +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fields_Edit.php b/workflow/engine/methods/dynaforms/fields_Edit.php new file mode 100644 index 000000000..7429df4d2 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_Edit.php @@ -0,0 +1,182 @@ +<?php +/** + * fields_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('dynaFormField'); + + if (!(isset($_GET['A']) && $_GET['A']!=='')) return; + + $file = G::decrypt( $_GET['A'] , URL_KEY ); + + $dbc = new DBConnection( PATH_DYNAFORM . $file . '.xml' ,'','','','myxml' ); + $ses = new DBSession($dbc); + + //TODO: Improve how to obtain the PRO_UID. + $aFile=explode('/',str_replace('\\','/',$file)); + $proUid=$aFile[0]; + $dynUid=str_replace("_tmp0","",$aFile[1]); + + require_once 'classes/model/Dynaform.php'; + $k=new Criteria('workflow'); + $k->addSelectColumn(DynaformPeer::DYN_TYPE); + $k->add(DynaformPeer::DYN_UID,$dynUid); + $ods=DynaformPeer::doSelectRS($k); + $ods->next(); + $row=$ods->getRow(); + $dynType=$row[0]; + + $Fields['PME_DYN_TYPE']=$dynType; + + $fields = new DynaFormField( $dbc ); + $fields->Fields['XMLNODE_NAME']=(isset($_GET['XMLNODE_NAME'])) ? urldecode($_GET['XMLNODE_NAME']):''; + $fields->Load( $fields->Fields['XMLNODE_NAME'] ); + + /* Start Comment: Modify the options grid to set dynamically the language + * label columns. + */ +// $dbc2 = new DBConnection( PATH_XMLFORM . 'dynaforms/fields/_options.xml' ,'','','','myxml' ); +// $ses2 = new DBSession($dbc2); +// $ses2->execute("DELETE FROM dynaForm WHERE XMLNODE_NAME like 'LABEL_%' "); +// $ses2->execute("DELETE FROM dynaForm WHERE XMLNODE_NAME = '' "); +// $langs=array(SYS_LANG/*,'es','fa'*/); +// foreach( $langs as $lang ) { +// $LANG = strtoupper($lang); +// $Label = 'Label'; +// $ses2->execute("INSERT INTO dynaForm (XMLNODE_NAME,XMLNODE_TYPE,XMLNODE_VALUE) VALUES ('', 'cdata', '\n') "); +// $ses2->execute("INSERT INTO dynaForm (XMLNODE_NAME,TYPE) VALUES ('LABEL_{$LANG}', 'text') "); +// $ses2->execute("INSERT INTO dynaForm.LABEL_{$LANG} (XMLNODE_NAME,XMLNODE_VALUE) VALUES ('".SYS_LANG."', '{$Label} ({$lang})') "); +// $ses2->execute("INSERT INTO dynaForm (XMLNODE_NAME,XMLNODE_TYPE,XMLNODE_VALUE) VALUES ('', 'cdata', '\n') "); +// } + /* End Comment: */ + + + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + + $form = new Form( $file , PATH_DYNAFORM, SYS_LANG, true ); + + if (is_array($fields->Fields)) { + foreach( $fields->Fields as $key => $value ) { + $Fields['PME_'.$key] = $value; + } + } + + $Fields['PME_A'] = $_GET['A']; + $Fields['PME_PRO_UID'] = $proUid; + $Fields['PME_XMLNODE_NAME_OLD'] = (isset($Fields['PME_XMLNODE_NAME']) ? $Fields['PME_XMLNODE_NAME'] : ''); + + $G_PUBLISH = new Publisher(); + + if ( !( isset($fields->Fields['XMLNODE_NAME']) && ($fields->Fields['XMLNODE_NAME']!=='') ) ) { + $type = strtolower( $_GET['TYPE'] ); + } else { + $type = strtolower( $fields->Fields['TYPE'] ); + } + + if( $type == 'suggest' || + $type == 'checkgroup' || + $type == 'dropdown' || + $type == 'radiogroup' || + $type == 'text' || + $type == 'listbox' || + $type == 'currency' || + $type == 'percentage' || + $type == 'textarea' || + $type == 'hidden' ) { + + $aDefaultConnections = array(); + $aDBConn = array(); + G::LoadClass ( 'dbConnections'); + $oDBConn = new DbConnections (); + $aDefaultConnections = array ( + array('DBS_UID' => '', 'DBS_NAME' => ''), + array('DBS_UID' => 'workflow', 'DBS_NAME' => 'Workflow'), + array('DBS_UID' => 'rbac', 'DBS_NAME' => 'RBAC'), + array('DBS_UID' => 'rp', 'DBS_NAME' => 'REPORT') + ); + $aDBConn = $oDBConn->getConnectionsProUid($proUid); + $aDbConnections = array_merge($aDefaultConnections, $aDBConn ); + $_DBArray ['DB_CONNECTIONS'] = $aDbConnections; + $_SESSION['_DBArray'] = $_DBArray; + } + + if ( !( isset($fields->Fields['XMLNODE_NAME']) && + ($fields->Fields['XMLNODE_NAME']!=='') ) ) { + $type = strtolower( $_GET['TYPE'] ); + $Fields['PME_TYPE'] = $type; + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/fields/' . $type, '', $Fields , SYS_URI.'dynaforms/fields_Save', SYS_URI.'dynaforms/fields_Ajax'); + } else { + $Fields['PME_LABEL'] = $form->fields[$fields->Fields['XMLNODE_NAME']]->label; + if (isset($form->fields[$fields->Fields['XMLNODE_NAME']]->code)) $Fields['PME_CODE'] = $form->fields[$fields->Fields['XMLNODE_NAME']]->code; + $options=isset($form->fields[$fields->Fields['XMLNODE_NAME']]->option)? + $form->fields[$fields->Fields['XMLNODE_NAME']]->option:array(); + if (!is_array($options)) $options =array(); + $Fields['PME_OPTIONS'] = array( + 'NAME' => array_keys($options), + 'LABEL' => array_values($options) + ); + $type = strtolower( $fields->Fields['TYPE'] ); + if ($type==='checkbox') { + if ($Fields['PME_DEFAULTVALUE']===$Fields['PME_VALUE']) { + $Fields['PME_DEFAULTVALUE']='On'; + } else { + $Fields['PME_DEFAULTVALUE']='Off'; + } + } + + if( $type == 'suggest' && isset($Fields['PME_SQLCONNECTION']) && $Fields['PME_SQLCONNECTION']!='') { + //define the dbArray with the table fields + //g::pr($Fields); + $con = Propel::getConnection($Fields['PME_SQLCONNECTION']); + $rs = $con->executeQuery("SHOW COLUMNS FROM USERS"); + $result = Array(); + $i=0; + while ($rs->next()) { + $result[$i++] = $rs->getRow(); + } + //g::pr($result); + } + + + if( isset($Fields['PME_HINT']) ) { + $Fields['PME_HINT'] = str_replace("\'", "'", $Fields['PME_HINT']); + $Fields['PME_HINT'] = str_replace("&", "&", $Fields['PME_HINT']); + } + + if (file_exists( PATH_XMLFORM . 'dynaforms/fields/' . $type . '.xml')) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'dynaforms/fields/' . $type, '', $Fields , SYS_URI.'dynaforms/fields_Save', SYS_URI.'dynaforms/fields_Ajax'); + } else { + print(G::LoadTranslation('ID_UNKNOWN_FIELD_TYPE')); + } + } + + G::RenderPage( "publish" , "raw" ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fields_List.php b/workflow/engine/methods/dynaforms/fields_List.php new file mode 100644 index 000000000..cb05c0d96 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_List.php @@ -0,0 +1,55 @@ +<?php +/** + * fields_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('dynaFormField'); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'FIELDS'; + + $PRO_UID='746B734DC23311'; + $file = $PRO_UID . '/' . 'myInfo'; + + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + + $G_PUBLISH = new Publisher; + + $Parameters = array( + 'SYS_LANG' => SYS_LANG, + 'URL'=> G::encrypt( $file , URL_KEY ) ); + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'dynaforms/fields_List', '', $Parameters , '', 'dynaforms_PagedTableAjax'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fields_Order.php b/workflow/engine/methods/dynaforms/fields_Order.php new file mode 100644 index 000000000..f304278d6 --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_Order.php @@ -0,0 +1,99 @@ +<?php +/** + * fields_Order.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + + if (!(isset($_POST['A']) && $_POST['A']!=='')) return; + if (!(isset($_POST['XMLNODE_NAME']) && $_POST['XMLNODE_NAME']!=='')) return; + if (!(isset($_POST['NEW_POS']) && $_POST['NEW_POS']!=='')) return; + + $file = PATH_DYNAFORM . G::decrypt( $_POST['A'] , URL_KEY ) . '.xml'; + $fieldName = $_POST['XMLNODE_NAME']; + $newPos = intval($_POST['NEW_POS']); + + if (!file_exists($file)) return; + + $xmldoc = new Xml_Document(); + $xmldoc->parseXmlFile( $file ); + + $node =& $xmldoc->findNode( '/dynaForm/' . $fieldName ); + + if (!isset( $node )) return; + $numFields = 0; + foreach( $xmldoc->children[0]->children as $child ) + $numFields += ($child->name!=='')? 1 : 0; + + $newPos = ($newPos<1) ? 1 : $newPos; + $newPos = ($newPos>$numFields) ? $numFields : $newPos; + + $rowCounter = (int) 0; + $newOrder = array(); + foreach( $xmldoc->children[0]->children as $index => $child ) { + if ($child->name!=='') $rowCounter++; + if ($rowCounter==$newPos) { + $newOrder[] = $node; + $rowCounter++; + $newPos=-1; + } + if ( $child->name !== $node->name ){ + $newOrder[] = $xmldoc->children[0]->children[$index]; + } + else + $rowCounter--; + } + if ($rowCounter < $newPos) { + $newOrder[] = $node; + $rowCounter++; + $newPos=-1; + } + $xmldoc->children[0]->children = $newOrder; + + $xmldoc->save( $file ); + + G::LoadClass('xmlDb'); + $i = 0; + $aFields = array(); + $aFields[] = array('XMLNODE_NAME' => 'char', + 'TYPE' => 'char', + 'UP' => 'char', + 'DOWN' => 'char', + 'row__' => 'integer'); + $oSession = new DBSession(new DBConnection($file, '', '', '', 'myxml')); + $oDataset = $oSession->Execute('SELECT * FROM dynaForm WHERE NOT( XMLNODE_NAME = "" )'); + $iMaximun = $oDataset->count(); + while ($aRow = $oDataset->Read()) { + $aFields[] = array('XMLNODE_NAME' => $aRow['XMLNODE_NAME'], + 'TYPE' => $aRow['TYPE'], + 'UP' => ($i > 0 ? G::LoadTranslation('ID_UP') : ''), + 'DOWN' => ($i < $iMaximun-1 ? G::LoadTranslation('ID_DOWN') : ''), + 'row__' => ($i + 1)); + $i++; + } + global $_DBArray; + $_DBArray['fields'] = $aFields; + $_SESSION['_DBArray'] = $_DBArray; +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/fields_Save.php b/workflow/engine/methods/dynaforms/fields_Save.php new file mode 100644 index 000000000..26f4a27cb --- /dev/null +++ b/workflow/engine/methods/dynaforms/fields_Save.php @@ -0,0 +1,196 @@ +<?php +//print_r( $_POST); die; +/** + * fields_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('dynaFormField'); + + $type=strtolower($_POST['form']['PME_TYPE']); + if (!(isset($_POST['form']['PME_A']) && $_POST['form']['PME_A']!=='')) return; + + if (isset($_POST['form']['PME_REQUIRED'])) { + if ($_POST['form']['PME_REQUIRED'] == '') { + $_POST['form']['PME_REQUIRED'] = 0; + } + } + else { + $_POST['form']['PME_REQUIRED'] = 0; + } + + if (isset($_POST['form']['PME_READONLY'])) { + if ($_POST['form']['PME_READONLY'] == '') { + $_POST['form']['PME_READONLY'] = 0; + } + } + else { + $_POST['form']['PME_READONLY'] = 0; + } + + if (isset($_POST['form']['PME_SAVELABEL'])) { + if ($_POST['form']['PME_SAVELABEL'] == '') { + $_POST['form']['PME_SAVELABEL'] = 0; + } + } + else { + $_POST['form']['PME_SAVELABEL'] = 0; + } + + $file = G::decrypt( $_POST['form']['PME_A'] , URL_KEY ); + define('DB_XMLDB_HOST', PATH_DYNAFORM . $file . '.xml' ); + define('DB_XMLDB_USER',''); + define('DB_XMLDB_PASS',''); + define('DB_XMLDB_NAME',''); + define('DB_XMLDB_TYPE','myxml'); + + + if (file_exists( PATH_XMLFORM . 'dynaforms/fields/' . $type . '.xml')) { + $form=new Form('dynaforms/fields/' . $type , PATH_XMLFORM); + //TODO: Verify why validatePost removes PME_XMLGRID. + $isGrid=isset($_POST['form']['PME_XMLGRID']); + if ($isGrid) $xmlGrid=$_POST['form']['PME_XMLGRID']; + //$form->validatePost(); + if ($isGrid) $_POST['form']['PME_XMLGRID']=$xmlGrid; + if ($type==='checkbox') { + // added by Gustavo Cruz + if ($_POST['form']['PME_DEFAULTVALUE']==="1") { + $_POST['form']['PME_DEFAULTVALUE']=$_POST['form']['PME_VALUE']; + } else { + $_POST['form']['PME_DEFAULTVALUE']=$_POST['form']['PME_FALSEVALUE']; + } + // end added code +// verify why $form->fields['PME_DEFAULTVALUE']->value doesn't capture the value 1 +// if ($_POST['form']['PME_DEFAULTVALUE']===$form->fields['PME_DEFAULTVALUE']->value) { +// $_POST['form']['PME_DEFAULTVALUE']=$_POST['form']['PME_VALUE']; +// } else { +// $_POST['form']['PME_DEFAULTVALUE']=$_POST['form']['PME_FALSEVALUE']; +// } + } + if ($type==='grid') { + if (!isset($_POST['form']['PME_ADDROW'])) { + $_POST['form']['PME_ADDROW'] = '0'; + } + if (!isset($_POST['form']['PME_DELETEROW'])) { + $_POST['form']['PME_DELETEROW'] = '0'; + } + } + } + foreach($_POST['form'] as $key => $value){ + if (substr($key,0,4)==='PME_') + $res[substr($key,4)]=$value; + else + $res[$key]=$value; + } + $_POST['form']=$res; + + $dbc = new DBConnection( PATH_DYNAFORM . $file . '.xml' ,'','','','myxml' ); + $ses = new DBSession($dbc); + + $fields = new DynaFormField( $dbc ); + + if ($_POST['form']['XMLNODE_NAME']==='') return; + + + $attributes = $_POST['form']; + if (isset($attributes['CODE'])) $attributes['XMLNODE_VALUE'] = ($attributes['CODE']); + + $labels = array(); + if (isset($attributes['LABEL'])) $labels = array ( SYS_LANG => $attributes['LABEL'] ); + + unset($attributes['A']); + unset($attributes['ACCEPT']); + unset($attributes['LABEL']); + unset($attributes['PRO_UID']); + + $options = NULL; + foreach($attributes as $key => $value ) { + if ($key==='OPTIONS') { + if (is_array($value)){ + if (is_array(reset($value))) { + $langs = array(); + $options = array(); + $langs[] = SYS_LANG; + $options[SYS_LANG]=array(); + foreach( $value as $row ) { + foreach( $langs as $lang ) { + $LANG = strtoupper($lang); + if (isset($row['LABEL'])) + $options[$lang][$row['NAME']]=$row['LABEL']; + } + } + /*$first = reset($value); + foreach( $first as $optKey => $optValue ) { + if (substr($optKey,0,6)==='LABEL_') { + $langs[]=strtolower(substr($optKey,6)); + $options[strtolower(substr($optKey,6))]=array(); + } + } + foreach( $value as $row ) { + foreach( $langs as $lang ) { + $LANG = strtoupper($lang); + if (isset($row['LABEL_'.$LANG])) + $options[$lang][$row['NAME']]=$row['LABEL_'.$LANG]; + } + }*/ + } + } + } else { + if (is_array($value)){ + //Is a list: + if (is_string(reset($value))) { + $attributes[$key] = implode(',',$value); + } else { + //Is a grid. + } + } + } + } + unset($attributes['VALIDATE_NAME']); + $fields->Save( $attributes , $labels , $options ); + + G::LoadClass('xmlDb'); + $i = 0; + $aFields = array(); + $aFields[] = array('XMLNODE_NAME' => 'char', + 'TYPE' => 'char', + 'UP' => 'char', + 'DOWN' => 'char', + 'row__' => 'integer'); + $oSession = new DBSession(new DBConnection(PATH_DYNAFORM . $file . '.xml', '', '', '', 'myxml')); + $oDataset = $oSession->Execute('SELECT * FROM dynaForm WHERE NOT( XMLNODE_NAME = "" )'); + $iMaximun = $oDataset->count(); + while ($aRow = $oDataset->Read()) { + $aFields[] = array('XMLNODE_NAME' => $aRow['XMLNODE_NAME'], + 'TYPE' => $aRow['TYPE'], + 'UP' => ($i > 0 ? G::LoadTranslation('ID_UP') : ''), + 'DOWN' => ($i < $iMaximun-1 ? G::LoadTranslation('ID_DOWN') : ''), + 'row__' => ($i + 1)); + $i++; + } + global $_DBArray; + $_DBArray['fields'] = $aFields; + $_SESSION['_DBArray'] = $_DBArray; +?> \ No newline at end of file diff --git a/workflow/engine/methods/dynaforms/test.php b/workflow/engine/methods/dynaforms/test.php new file mode 100644 index 000000000..044e0f523 --- /dev/null +++ b/workflow/engine/methods/dynaforms/test.php @@ -0,0 +1,58 @@ +<?php +/** + * test.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +/* START BOCK: DAVID CALLIZAYA: PLEASE NO BORRAR ESTE BLOQUE.*/ + for($r=1;$r<10;$r++){ +/* The timestamp is a 60-bit value. For UUID version 1, this is + * represented by Coordinated Universal Time (UTC) as a count of 100- + * nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of + * Gregorian reform to the Christian calendar). + */ + $t=explode(' ',microtime()); + $ts=$t[1].substr($t[0],2,7); + $t[0]=substr('00'.base_convert($ts,10,16),-15); + var_dump($ts); + print("\n<br/>"); + var_dump($t); + print("\n<br/>"); + } +/* START BOCK: DAVID CALLIZAYA: PLEASE NO BORRAR ESTE BLOQUE.*/ +?> +<form action="test" method="post"> +<select name="form[test][]" multiple="multiple"> + <option value="one">one</option> + <option value="two">two</option> + <option value="three">three</option> + <option value="four">four</option> + <option value="five">five</option> +</select> +<input type="submit" value="Send" /> +</form> +<?php + $test=$_POST['form']['test']; + if ($test){ + foreach ($test as $t){echo 'You selected ',$t,'<br />';} + } +?> diff --git a/workflow/engine/methods/events/eventsAjax.php b/workflow/engine/methods/events/eventsAjax.php new file mode 100644 index 000000000..40c4db138 --- /dev/null +++ b/workflow/engine/methods/events/eventsAjax.php @@ -0,0 +1,112 @@ +<?php +$req = $_POST['request']; + +switch($req){ + case 'showUsers': + + /* + $sql = "SELECT USR_UID, USR_EMAIL, CONCAT(USR_FIRSTNAME, ' ' , USR_LASTNAME) AS USR_FULLNAME FROM USERS WHERE USR_STATUS = 'ACTIVE' AND USR_EMAIL <> ''"; + */ + $sDataBase = 'database_' . strtolower(DB_ADAPTER); + if(G::LoadSystemExist($sDataBase)){ + G::LoadSystem($sDataBase); + $oDataBase = new database(); + $sConcat = $oDataBase->concatString("USR_FIRSTNAME", "' '" , "USR_LASTNAME") ; + } + $sql = " SELECT USR_UID, USR_EMAIL, " . + $sConcat . + " AS USR_FULLNAME FROM USERS " . + " WHERE USR_STATUS = 'ACTIVE' AND USR_EMAIL <> ''"; + + $oCriteria = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $con = Propel::getConnection("workflow"); + $stmt = $con->prepareStatement($sql); + $rs = $stmt->executeQuery(); + + $aRows[] = array('USR_UID'=>'char', 'USR_EMAIL'=>'char', 'USR_FULLNAME'=>'char'); + while($rs->next()){ + $aRows[] = array('USR_UID'=>$rs->getString('USR_UID'), 'USR_EMAIL'=>$rs->getString('USR_EMAIL'), 'USR_FULLNAME'=>$rs->getString('USR_FULLNAME')); + } + //echo '<pre>'; print_r($aRows); + + global $_DBArray; + $_DBArray['virtualtable'] = $aRows; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('virtualtable'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'events/usermailList', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + + case 'showGroups': + + G::LoadClass('groups'); + $groups = new Groups(); + $allGroups= $groups->getAllGroups(); + + $aRows[] = array('GRP_UID' => 'char', 'GROUP_TITLE' => 'char'); + foreach($allGroups as $group) { + $UID = htmlentities($group->getGrpUid()); + $GROUP_TITLE = strip_tags($group->getGrpTitle()); + $aRows[] = array('GRP_UID'=>$UID, 'GROUP_TITLE'=>$GROUP_TITLE); + } + + global $_DBArray; + $_DBArray['virtualtable'] = $aRows; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('virtualtable'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'events/groupmailList', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + + case 'showDynavars': + G::LoadClass('processMap'); + $oProcessMap = new processMap(); + $aDynaforms = $oProcessMap->getDynaformsList($_SESSION['PROCESS']); + //g::pr($aDynaforms); + G::LoadSystem('dynaformhandler'); + $aDynaformFields = Array(); + foreach($aDynaforms as $dyn){ + if( $dyn['DYN_TYPE'] == 'xmlform' ){ + if( is_file(PATH_DYNAFORM . "{$_SESSION['PROCESS']}/{$dyn['DYN_UID']}" . '.xml') ){ + $oDynaformHandler = new dynaFormHandler(PATH_DYNAFORM . "{$_SESSION['PROCESS']}/{$dyn['DYN_UID']}" . '.xml'); + $aDynaformFields[$dyn['DYN_TITLE']] = $oDynaformHandler->getFieldNames(); + + } else { + continue; + } + } + } + + + //G::pr($aDynaformFields); die; + $aRows = Array(); + $aRows[0] = Array('id'=>'char', 'dynaform'=>'char', 'name'=>'char'); + foreach($aDynaformFields as $dynName=>$aFields){ + foreach($aFields as $sField){ + array_push($aRows, Array('id'=>$sField, 'dynaform'=>$dynName, 'name'=>$sField)); + } + } + //g::pr($aRows); die; + global $_DBArray; + $_DBArray['virtualtable'] = $aRows; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('virtualtable'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'events/dynavarsList', $oCriteria); + G::RenderPage('publish', 'raw'); + + break; +} diff --git a/workflow/engine/methods/events/eventsCompleted.php b/workflow/engine/methods/events/eventsCompleted.php new file mode 100644 index 000000000..baaf787d3 --- /dev/null +++ b/workflow/engine/methods/events/eventsCompleted.php @@ -0,0 +1,38 @@ +<?php +/** + * eventsCompleted.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AppEvent.php'; +$oAppEvent = new AppEvent(); + +global $G_PUBLISH; +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'events/appEventsListCompleted', $oAppEvent->getAppEventsCriteria($_GET['PRO_UID'], 'COMPLETED', $_GET['EVN_TYPE'])); +G::RenderPage('publish', 'raw'); diff --git a/workflow/engine/methods/events/eventsDelete.php b/workflow/engine/methods/events/eventsDelete.php new file mode 100644 index 000000000..dd77c3bc9 --- /dev/null +++ b/workflow/engine/methods/events/eventsDelete.php @@ -0,0 +1,35 @@ +<?php +/** + * events_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$evnUid = $_POST['EVN_UID']; +require_once 'classes/model/Event.php'; +$oEvent = new Event(); +$oEvent->remove( $evnUid ); \ No newline at end of file diff --git a/workflow/engine/methods/events/eventsEdit.php b/workflow/engine/methods/events/eventsEdit.php new file mode 100644 index 000000000..092e09119 --- /dev/null +++ b/workflow/engine/methods/events/eventsEdit.php @@ -0,0 +1,79 @@ +<?php +/** + * events_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +G::LoadClass('tasks'); +G::LoadClass('processMap'); +global $_DBArray; + +if (isset($_GET['EVN_UID'])) { + require_once 'classes/model/Event.php'; + $oEvent = new Event(); + $aFields = $oEvent->load($_GET['EVN_UID']); +} +else { + $aFields = array('PRO_UID' => $_GET['PRO_UID']); +} + + +$oTasks = new Tasks(); +$aAux1 = $oTasks->getAllTasks($aFields['PRO_UID']); +$aTasks = array(); +$aTasks[] = array('TAS_UID' => 'char', + 'TAS_TITLE' => 'char'); +foreach ($aAux1 as $aAux2) { + if ($aAux2['TAS_TYPE'] != 'SUBPROCESS' && $aAux2['TAS_START'] != 'TRUE') { + $aTasks[] = array('TAS_UID' => $aAux2['TAS_UID'], 'TAS_TITLE' => $aAux2['TAS_TITLE']); + } +} + + +$oProcessMap = new processMap(new DBConnection); +$aTriggersList = $oProcessMap->getTriggers($_SESSION['PROCESS']); +$aTriggersFileds = Array('TRI_UID'=>'char', 'TRI_TITLE'=>'char'); + +foreach($aTriggersList as $i=>$v){ + unset($aTriggersList[$i]['PRO_UID']); + unset($aTriggersList[$i]['TRI_DESCRIPTION']); + $aTriggersList[$i]['TRI_TITLE'] = (strlen($aTriggersList[$i]['TRI_TITLE'])>32)? substr($aTriggersList[$i]['TRI_TITLE'], 0, 32).'...': $aTriggersList[$i]['TRI_TITLE']; +} + +$aTriggersList = array_merge(Array($aTriggersFileds), $aTriggersList); + +$_DBArray['tasks'] = $aTasks; +$_DBArray['TMP_TRIGGERS'] = $aTriggersList; + + +$_SESSION['_DBArray'] = $_DBArray; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'events/eventsEdit', '', $aFields, '../events/eventsSave'); +G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/events/eventsEditAction.php b/workflow/engine/methods/events/eventsEditAction.php new file mode 100644 index 000000000..23589f4a4 --- /dev/null +++ b/workflow/engine/methods/events/eventsEditAction.php @@ -0,0 +1,249 @@ +<?php +/** + * events_EditAction.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +global $_DBArray; + +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} +if ( isset ($_SESSION['EVN_UID']) ) { + $evnUid = $_SESSION['EVN_UID']; + unset ( $_SESSION['EVN_UID'] ); +} +else + $evnUid = $_GET['EVN_UID']; + +require_once 'classes/model/Event.php'; +require_once 'classes/model/Triggers.php'; +$oEvent = new Event(); +$oTrigger = new Triggers(); +$aFields = $oEvent->load( $evnUid ); +$parameters = unserialize ( $oEvent->getEvnActionParameters() ); +//g::pr($parameters); die; +$aTrigger = $oTrigger->load($aFields['TRI_UID']); + +$hash = md5 ( $oTrigger->getTriWebbot() ); +//var_dump($hash,$parameters->hash);die; +//if the hash is different, the script was edited , so we will show the trigger editor. +if ( ( isset($parameters->hash) && $hash <> $parameters->hash ) || $aFields['EVN_ACTION'] == 'EXECUTE_TRIGGER' || $aFields['EVN_ACTION'] == 'EXECUTE_CONDITIONAL_TRIGGER' ) { + $oTriggerParams = unserialize($aTrigger['TRI_PARAM']); + // check again a hash, this time to check the trigger itself integrity + if ($oTriggerParams['hash']!=$hash){ + // if has changed edit manually + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'triggers/triggersNarrowEdit', '', $aTrigger, '../events/triggersSave'); + G::RenderPage('publish', 'raw'); + die; + } else { + // if not launch the wizard view. + $triUid = $aFields['TRI_UID']; + $_GET = $oTriggerParams['params']; + $_GET['TRI_UID'] = $triUid; + require_once(PATH_METHODS.'triggers/triggers_EditWizard.php'); + die; + } +} + +$aFields['EVN_MESSAGE_SUBJECT'] = (isset($parameters->SUBJECT) ? $parameters->SUBJECT : ''); + +if(isset($parameters->TO)){ + $paramTO[] = Array('id'=>'char', 'name'=>'char'); + + //echo '<pre>';print_r($parameters->TO); + foreach($parameters->TO as $item){ + $row = explode('|', $item); + switch($row[0]){ + case 'usr': + require_once('classes/model/Users.php'); + $user = new Users(); + + if($row[1] == '-1'){ + $value = '(Current Task User)'; + } else { + $rec = $user->load($row[1]); + $value = $rec['USR_FIRSTNAME'].' '.$rec['USR_LASTNAME']; + } + break; + + case 'grp': + G::LoadClass('groups'); + $group = new Groups(); + $rec = $group->load($row[1]); + + $value = strip_tags($rec->getGrpTitle()); + break; + + case 'ext': + $value = htmlentities($row[1]); + break; + + case 'dyn': + $value = htmlentities('@#'.$row[1]); + break; + + default: + echo '->'.$row[0]; + } + $paramTO[] = Array('id'=>replaceQuotes($item), 'name'=>$value); + } +} else { + $paramTO[] = Array('id'=>'char', 'name'=>'char'); + $paramTO[] = Array('id'=>'usr|-1', 'name'=>'(Current Task User)'); +} +$_DBArray['eventomsgto'] = $paramTO; + +if(isset($parameters->CC)){ + $paramCC[] = Array('id'=>'char', 'name'=>'char'); + foreach($parameters->CC as $item){ + $row = explode('|', $item); + switch($row[0]){ + case 'usr': + require_once('classes/model/Users.php'); + $user = new Users(); + + if($row[1] == '-1'){ + $value = '(Current Task User)'; + } else { + $rec = $user->load($row[1]); + $value = $rec['USR_FIRSTNAME'].' '.$rec['USR_LASTNAME']; + } + break; + + case 'grp': + G::LoadClass('groups'); + $group = new Groups(); + $rec = $group->load($row[1]); + + $value = strip_tags($rec->getGrpTitle()); + break; + + case 'ext': + $value = htmlentities($row[1]); + break; + + case 'dyn': + $value = htmlentities('@#'.$row[1]); + break; + } + $paramCC[] = Array('id'=>replaceQuotes($item), 'name'=>$value); + } + + $_DBArray['eventomsgcc'] = $paramCC; + +} else { + $_DBArray['eventomsgcc'] = Array(); +} + +if(isset($parameters->BCC)){ + $paramBCC[] = Array('id'=>'char', 'name'=>'char'); + foreach($parameters->BCC as $item){ + $row = explode('|', $item); + switch($row[0]){ + case 'usr': + require_once('classes/model/Users.php'); + $user = new Users(); + + if($row[1] == '-1'){ + $value = '(Current Task User)'; + } else { + $rec = $user->load($row[1]); + $value = $rec['USR_FIRSTNAME'].' '.$rec['USR_LASTNAME']; + } + break; + + case 'grp': + G::LoadClass('groups'); + $group = new Groups(); + $rec = $group->load($row[1]); + + $value = strip_tags($rec->getGrpTitle()); + break; + + case 'ext': + $value = htmlentities($row[1]); + break; + + case 'dyn': + $value = htmlentities('@#'.$row[1]); + break; + } + $paramBCC[] = Array('id'=>replaceQuotes($item), 'name'=>$value); + } + + $_DBArray['eventomsgbcc'] = $paramBCC; + +} else { + $_DBArray['eventomsgbcc'] = Array(); +} +$aFields['EVN_MESSAGE_TO_TO'] = $paramTO; +$aFields['EVN_MESSAGE_TO_CC'] = (isset($parameters->CC) ? $paramCC : ''); +$aFields['EVN_MESSAGE_TO_BCC'] = (isset($parameters->BCC) ? $paramBCC : ''); +$aFields['EVN_MESSAGE_TEMPLATE'] = (isset($parameters->TEMPLATE) ? $parameters->TEMPLATE : ''); + + +$aTemplates = array(); +$aTemplates[] = array('TEMPLATE1' => 'char', + 'TEMPLATE2' => 'char'); +$sDirectory = PATH_DATA_MAILTEMPLATES . $aFields['PRO_UID'] . PATH_SEP; +G::verifyPath($sDirectory, true); +if (!file_exists($sDirectory . 'alert_message.html')) { + @copy(PATH_TPL . 'mails' . PATH_SEP . 'alert_message.html', $sDirectory . 'alert_message.html'); +} +$oDirectory = dir($sDirectory); +while ($sObject = $oDirectory->read()) { + if (($sObject !== '.') && ($sObject !== '..') && ($sObject !== 'alert_message.html')) { + $aTemplates[] = array('TEMPLATE1' => $sObject, + 'TEMPLATE2' => $sObject); + } +} +$_DBArray['templates'] = $aTemplates; + +$aTriggers[] = array('TRI_UID' => 'char', + 'TRI_TITLE' => 'char'); +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); +$oDataset = TriggersPeer::doSelectRS($oProcessMap->getTriggersCriteria($aFields['PRO_UID'])); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +while ($aRow = $oDataset->getRow()) { + $aTriggers[] = array('TRI_UID' => $aRow['TRI_UID'], + 'TRI_TITLE' => $aRow['TRI_TITLE']); + $oDataset->next(); +} +$_DBArray['triggers'] = $aTriggers; + +$_SESSION['_DBArray'] = $_DBArray; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'events/eventsEditAction', '', $aFields, '../events/eventsSave'); +//$G_PUBLISH->AddContent('xmlform', 'xmlform', 'events/eventsEditAction', '', $aFields, '../events/eventsSave'); +G::RenderPage('publish', 'raw'); + +function replaceQuotes($aData){ + return str_replace('"', '"e;', $aData); +} diff --git a/workflow/engine/methods/events/eventsNew.php b/workflow/engine/methods/events/eventsNew.php new file mode 100644 index 000000000..f7a8cd6fb --- /dev/null +++ b/workflow/engine/methods/events/eventsNew.php @@ -0,0 +1,68 @@ +<?php +/** + * events_New.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +global $_DBArray; +G::LoadClass('tasks'); +G::LoadClass('processMap'); + +$oTasks = new Tasks(); +$aAux1 = $oTasks->getAllTasks($_GET['PRO_UID']); +$aTasks = array(); +$aTasks[] = array('TAS_UID' => 'char', 'TAS_TITLE' => 'char'); + +//g::pr($aAux1);die; +foreach ($aAux1 as $aAux2) { + if ($aAux2['TAS_TYPE'] != 'SUBPROCESS' && $aAux2['TAS_START'] != 'TRUE') { + $aTasks[] = array('TAS_UID' => $aAux2['TAS_UID'], 'TAS_TITLE' => $aAux2['TAS_TITLE']); + } +} + +$oProcessMap = new processMap(new DBConnection); +$aTriggersList = $oProcessMap->getTriggers($_SESSION['PROCESS']); +$aTriggersFileds = Array('TRI_UID'=>'char', 'TRI_TITLE'=>'char'); + +foreach($aTriggersList as $i=>$v){ + unset($aTriggersList[$i]['PRO_UID']); + unset($aTriggersList[$i]['TRI_DESCRIPTION']); + $aTriggersList[$i]['TRI_TITLE'] = (strlen($aTriggersList[$i]['TRI_TITLE'])>32)? substr($aTriggersList[$i]['TRI_TITLE'], 0, 32).'...': $aTriggersList[$i]['TRI_TITLE']; +} + +$aTriggersList = array_merge(Array($aTriggersFileds), $aTriggersList); + +$_DBArray['tasks'] = $aTasks; +$_DBArray['TMP_TRIGGERS'] = $aTriggersList; + +$_SESSION['_DBArray'] = $_DBArray; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'events/eventsNew', '', array('PRO_UID' => $_GET['PRO_UID'], 'EVN_ACTION' => $_GET['EVN_TYPE']), ''); +G::RenderPage('publish', 'raw'); + diff --git a/workflow/engine/methods/events/eventsNewAction.php b/workflow/engine/methods/events/eventsNewAction.php new file mode 100644 index 000000000..c63fd3bc1 --- /dev/null +++ b/workflow/engine/methods/events/eventsNewAction.php @@ -0,0 +1,83 @@ +<?php +/** + * events_NewAction.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +global $_DBArray; + +//get the posted fields of new Event and create a new record of that +require_once 'classes/model/Event.php'; + +$oEvent = new Event(); +$envUId = $oEvent->create($_POST); + +$_SESSION['EVN_UID'] = $envUId; +require_once ( 'eventsEditAction.php' ); +die; + +/* +//this page is showing the parameters for setup email messages and triggers, +//probably this will be changed soon. + +$aTemplates = array(); +$aTemplates[] = array('TEMPLATE1' => 'char', + 'TEMPLATE2' => 'char'); +$sDirectory = PATH_DATA_MAILTEMPLATES . $_POST['PRO_UID'] . PATH_SEP; +G::verifyPath($sDirectory, true); +$oDirectory = dir($sDirectory); +while ($sObject = $oDirectory->read()) { + if (($sObject !== '.') && ($sObject !== '..')) { + $aTemplates[] = array('TEMPLATE1' => $sObject, + 'TEMPLATE2' => $sObject); + } +} +$_DBArray['templates'] = $aTemplates; + +$aTriggers[] = array('TRI_UID' => 'char', + 'TRI_TITLE' => 'char'); +require_once 'classes/model/Triggers.php'; +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); +$oDataset = TriggersPeer::doSelectRS($oProcessMap->getTriggersCriteria($_POST['PRO_UID'])); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +while ($aRow = $oDataset->getRow()) { + $aTriggers[] = array('TRI_UID' => $aRow['TRI_UID'], + 'TRI_TITLE' => $aRow['TRI_TITLE']); + $oDataset->next(); +} +$_DBArray['triggers'] = $aTriggers; + +$_SESSION['_DBArray'] = $_DBArray; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'events/events_EditAction', '', $_POST, '../events/eventsSave'); +G::RenderPage('publish', 'raw'); + +*/ \ No newline at end of file diff --git a/workflow/engine/methods/events/eventsPending.php b/workflow/engine/methods/events/eventsPending.php new file mode 100644 index 000000000..253c1c49a --- /dev/null +++ b/workflow/engine/methods/events/eventsPending.php @@ -0,0 +1,38 @@ +<?php +/** + * eventsPending.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +require_once 'classes/model/AppEvent.php'; +$oAppEvent = new AppEvent(); + +global $G_PUBLISH; +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'events/appEventsList', $oAppEvent->getAppEventsCriteria($_GET['PRO_UID'], 'PENDING', $_GET['EVN_TYPE'])); +G::RenderPage('publish', 'raw'); diff --git a/workflow/engine/methods/events/eventsSave.php b/workflow/engine/methods/events/eventsSave.php new file mode 100644 index 000000000..2b4105353 --- /dev/null +++ b/workflow/engine/methods/events/eventsSave.php @@ -0,0 +1,77 @@ +<?php +/** + * events_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} +$EVN_MESSAGE_TO_TO = isset($_POST['form']['EVN_MESSAGE_TO_TO'])? replaceQuotes($_POST['form']['EVN_MESSAGE_TO_TO']): Array(); +$EVN_MESSAGE_TO_CC = isset($_POST['form']['EVN_MESSAGE_TO_CC'])? replaceQuotes($_POST['form']['EVN_MESSAGE_TO_CC']): Array(); +$EVN_MESSAGE_TO_BCC = isset($_POST['form']['EVN_MESSAGE_TO_BCC'])? replaceQuotes($_POST['form']['EVN_MESSAGE_TO_BCC']): Array(); + +if (isset($_POST['form']['EVN_MESSAGE_SUBJECT'])) { + $_POST['form']['EVN_ACTION_PARAMETERS'] = array( + 'SUBJECT' => $_POST['form']['EVN_MESSAGE_SUBJECT'], + 'TO' => $EVN_MESSAGE_TO_TO, + 'CC' => $EVN_MESSAGE_TO_CC, + 'BCC' => $EVN_MESSAGE_TO_BCC, + 'TEMPLATE' => $_POST['form']['EVN_MESSAGE_TEMPLATE'] + ); + + unset($_POST['form']['EVN_MESSAGE_SUBJECT']); + unset($_POST['form']['EVN_MESSAGE_TO_TO']); + unset($_POST['form']['EVN_MESSAGE_TO_CC']); + unset($_POST['form']['EVN_MESSAGE_TO_BCC']); + unset($_POST['form']['EVN_MESSAGE_TEMPLATE']); +} +unset($_POST['form']['SAVE']); + +require_once 'classes/model/Event.php'; +$oEvent = new Event(); +if ($_POST['form']['EVN_UID'] == '') { + //this is probably not used, because the creation of one Event is done directly in EventsNewAction + $oEvent->create($_POST['form']); +} +else { + /* + *if($_POST['form']['EVN_ACTION'] == 'SEND_MESSAGE' && $ev->getTriUid() != trim($_POST['form']['TRI_UID']) ){ + $oEvnActionParameters = unserialize($ev->getEvnActionParameters()); + prit_r($oEvnActionParameters); + if( isset($oEvnActionParameters->TRI_UID) ){ + $_POST['form']['TRI_UID'] = $oEvnActionParameters->TRI_UID; + } + + } + */ + $oEvent->update($_POST['form']); +} + +function replaceQuotes($aData){ + for($i=0; $i<sizeof($aData); $i++){ + $aData[$i] = str_replace(""e;", '"', $aData[$i]); + } + return $aData; +} \ No newline at end of file diff --git a/workflow/engine/methods/events/eventsSetupGraph.php b/workflow/engine/methods/events/eventsSetupGraph.php new file mode 100644 index 000000000..240b2b227 --- /dev/null +++ b/workflow/engine/methods/events/eventsSetupGraph.php @@ -0,0 +1,211 @@ +<? + + $w = 350; + $h = 90; + + //how many task, single task or multiple + $t = isset( $_GET['t'] ) ? $_GET['t'] : 's'; + if ( $t != 's' ) $t = 'm'; + + //when occurs, after time elapses or when starting + $o = isset( $_GET['o'] ) ? $_GET['o'] : 's'; + if ( $t != 's' ) $t = 'a'; + + //status + $s = isset( $_GET['s'] ) ? $_GET['s'] : 'a'; + if ( $s != 'a' ) $s = 'i'; + + //estimated + $estimated = abs( isset( $_GET['e'] ) ? $_GET['e'] : '1' ); + + //when + $when = isset( $_GET['w'] ) ? $_GET['w'] : '0'; + + $im = imagecreate($w,$h); + $bg = imagecolorallocate ($im, 0xFF, 0xFF, 0xFF); + $fg = imagecolorallocate ($im, 0x00, 200, 0x00); + $sc = imagecolorallocate ($im, 200, 0, 0); + $gray = imagecolorallocate ($im, 180,180,180); + $red = imagecolorallocate ($im, 200, 0, 0); + $green = imagecolorallocate ($im, 0, 200, 0); + $blue = imagecolorallocate ($im, 0, 0, 200); + $black = imagecolorallocate ($im, 0, 0, 0); + + imagerectangle($im, 0, 0, $w-1, $h-1, $gray); + +// $incM = $media/60; + +// $mean = 60*$incM; +// $d = $varianza; +// if ( $d == 0 ) $d = 0.0001; + +// $val1 = 1 / ( sqrt( 2*pi() *$d*$d )); +// $val2 = -( pow($mean-$mean,2) )/ (pow($d,2)); +// $y = $val1 * exp ( $val2 ); +// $incY = 80/$y; + +// $range = 90/ $d; +// $offsetX = 100 - $mean; +// $antY = null; +// for ( $x = $mean -$range*$d ; $x <= $mean +$range*$d; $x++ ) { +// $val1 = 1 / ( sqrt( 2*pi() *$d*$d )); +// $val2 = -( pow($x-$mean,2) )/ (pow($d,2)); +// $y = $val1 * exp ( $val2 )*$incY; +// if ( $antY != null ) +// imageline($im, $x-1+$offsetX, $h - $antY-15, $x+$offsetX, $h-$y-15, $blue); +// $antY = $y; +// imageline($im, $x +$mean, $h , $x + $mean, $h-1, $red); +// } + + function drawTask ( $im, $x1, $x2, $y, $h ) { + global $w; + $blue = imagecolorallocate ($im, 160, 160, 180); + $gray = imagecolorallocate ($im, 100, 100, 100); + $black = imagecolorallocate ($im, 0, 0, 0); + + for ( $i = $y; $i < $h ; $i+= 2 ) { + imageline($im, $x1, $i, $x1 , $i, $gray); + imageline($im, $x2, $i, $x2 , $i, $gray); + } + + for ( $i = $x1; $i < $x2; $i+= 2 ) { + imageline($im, $i, $y-10 , $i, $y, $blue); + } + imagerectangle($im, $x1, $y - 10, $x2, $y, $black); + }; + + function smallTask ($im, $x1, $x2, $y ) { + $blue = imagecolorallocate ($im, 160, 160, 180); + $black = imagecolorallocate ($im, 0, 0, 0); + + for ( $i = $x1; $i < $x2; $i+= 2 ) { + imageline($im, $i, $y-8 , $i, $y, $blue); + } + imagerectangle($im, $x1, $y - 9, $x2 - 1, $y, $black); + } + + function drawMultipleTask ( $im, $x1, $x2, $y, $h ) { + global $w; + $terca = ($x2 - $x1 ) / 3; + $blue = imagecolorallocate ($im, 160, 160, 180); + $gray = imagecolorallocate ($im, 100, 100, 100); + $black = imagecolorallocate ($im, 0, 0, 0); + + for ( $i = $y; $i < $h ; $i+= 2 ) { + imageline($im, $x2, $i, $x2 , $i, $gray); + } + for ( $i = $y-10; $i < $h ; $i+= 2 ) { + imageline($im, $x1, $i, $x1 , $i, $gray); + } + + smallTask ( $im, $x1 + 0*$terca, $x1 + 1*$terca, $y -12 ); + smallTask ( $im, $x1 + 1*$terca, $x1 + 2*$terca, $y -6 ); + smallTask ( $im, $x1 + 2*$terca, $x1 + 3*$terca, $y ); + }; + + function drawTimerEvent ( $im, $x1, $y1, $h ) { + $blue = imagecolorallocate ($im, 160, 160, 180); + $red = imagecolorallocate ($im, 200, 100, 0); + $gray = imagecolorallocate ($im, 100, 100, 100); + $black = imagecolorallocate ($im, 0, 0, 0); + $yellow = imagecolorallocate ($im, 240, 240, 220); + + for ( $i = $y1 + 15; $i < $h ; $i+= 2 ) { + imageline($im, $x1, $i, $x1 , $i, $gray); + } + + ImageEllipse($im, $x1, $y1, 26, 26, $black); + ImageEllipse($im, $x1, $y1, 22, 22, $black); + ImageFilledEllipse($im, $x1, $y1, 16, 16, $yellow ); + ImageEllipse($im, $x1, $y1, 16, 16, $red); + imageline($im, $x1 , $y1-8 , $x1, $y1+8, $red); + //imageline($im, $x1 , $y1+8 , $x1, $y1+6, $red); + imageline($im, $x1-8 , $y1 , $x1+8 , $y1, $red); + imageline($im, $x1-7 , $y1-4 , $x1+7 , $y1+4, $red); + imageline($im, $x1-4 , $y1-7 , $x1+4 , $y1+7, $red); + imageline($im, $x1+7 , $y1-4 , $x1-7 , $y1+4, $red); + imageline($im, $x1+4 , $y1-7 , $x1-4 , $y1+7, $red); + ImageFilledEllipse($im, $x1, $y1, 10, 10, $yellow ); + imageline($im, $x1-1 , $y1+1 , $x1+1, $y1 - 5, $red); + imageline($im, $x1-1 , $y1+1 , $x1+3, $y1+1 , $red); + + + } + + imageline($im, 15, $h-19 , $w -15, $h-19, $red); + imageline($im, $w - 23, $h-23 , $w -15, $h-19, $red); + imageline($im, $w - 23, $h-15 , $w -15, $h-19, $red); + imagestring ($im, 2, $w -30 , $h -37, 'days', $red); + + if ( $estimated == 0 ) { + $s = 'i'; + header("Content-Type: image/png"); + imagepng($im); + die; + } + + if ( $t == 's' ) + drawTask ( $im, 80, 220, $h - 30 , $h -15); + else + drawMultipleTask( $im, 80, 220, $h - 30 , $h -15); + + //the zero + imagestring ($im, 3, 80 -4 , $h -16, '0', $black); + //the estimated + imagestring ($im, 2, 220 -4 , $h -16, $estimated, $black); + + + //when is negative and the event occurs at starting, then this event never will occurs + if ( $when < 0 && $o == 's' ) { + $xTimer = 30; + imagestring ($im, 2, $xTimer -8 , $h -16, $when, $black); + $s = 'i'; + } + + //when is negative and the event occurs after, then this event will occurs + if ( $when < 0 && $o == 'a' ) { + if ( abs($when) > abs($estimated) ) { //this event is before the start of the task, so will never occurs + $xTimer = 30; + $sWhen = abs($when) - abs($estimated); + imagestring ($im, 2, $xTimer -8 , $h -16, $sWhen, $black); + $s = 'i'; + } + if ( abs($when) < abs($estimated) ) { //this event is after the start of the task, drawing + $xTimer = 170; + $sWhen = $estimated + $when; + imagestring ($im, 2, $xTimer -4 , $h -16, $sWhen, $black); + } + if ( abs($when) == abs($estimated) ) { //this event is exactly at starting + $xTimer = 80; + $sWhen = $estimated + $when; + imagestring ($im, 2, $xTimer -4 , $h -16, $sWhen, $black); + } + } + + //when is positive and the event occurs after, then this event will occurs + if ( $when > 0 && $o == 'a' ) { + $xTimer = 270; + $sWhen = $estimated + $when; + imagestring ($im, 2, $xTimer -4 , $h -16, $sWhen, $black); + } + + //when is positive and the event occurs starting, then this event will occurs + if ( $when > 0 && $o == 's' ) { + if ( abs($when) < abs($estimated) ) $xTimer = 140; + if ( abs($when) > abs($estimated) ) $xTimer = 270; + if ( abs($when) == abs($estimated) ) $xTimer = 220; + + imagestring ($im, 2, $xTimer -4 , $h -16, $when, $black); + } + + if ( $when == 0 ) { + $xTimer = ( $o == 's' ) ? 80: 220 ; + } + + if ( $s == 'a' ) { + drawTimerEvent ( $im, $xTimer, $h -70 , $h -15); + } + + header("Content-Type: image/png"); + imagepng($im); +die; diff --git a/workflow/engine/methods/events/triggersSave.php b/workflow/engine/methods/events/triggersSave.php new file mode 100755 index 000000000..fc98ebf57 --- /dev/null +++ b/workflow/engine/methods/events/triggersSave.php @@ -0,0 +1,40 @@ +<?php +/** + * triggers_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); +$oTrigger = new Triggers(); +if ($_POST['form']['TRI_UID'] != '') +{ + $oTrigger->load($_POST['form']['TRI_UID']); +} +else +{ + $oTrigger->create($_POST['form']); + $_POST['form']['TRI_UID']=$oTrigger->getTriUid(); +} + +$oTrigger->update($_POST['form']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/groups/groups.php b/workflow/engine/methods/groups/groups.php new file mode 100644 index 000000000..f2b2dd3a3 --- /dev/null +++ b/workflow/engine/methods/groups/groups.php @@ -0,0 +1,188 @@ +<?php +/** + * groups.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'GROUPS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $Fields['WHERE'] = ''; + + $G_PUBLISH = new Publisher; + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/groups/groups.js'); + + $G_PUBLISH->AddContent('view', 'groups/groups_Tree' ); + $G_PUBLISH->AddContent('smarty', 'groups/groups_usersList', '', '', array()); + + G::RenderPage( "publish-treeview",'blank' ); + + $groups_Edit = G::encryptlink('groups_Edit'); + $groups_Delete = G::encryptlink('groups_Delete'); + $groups_List = G::encryptlink('groups_List'); + $groups_AddUser = G::encryptlink('groups_AddUser'); +?> +<script> + + + var oAux = document.getElementById("publisherContent[0]"); + oAux.id = "publisherContent[666]"; + var currentGroup=false; + function editGroup( uid ) { + popupWindow('' , '<?=$groups_Edit?>?UID=' + encodeURIComponent( uid )+'&nobug' , 500 , 200 ); + refreshTree(); + } + function addGroup(){ + popupWindow('' , '<?=$groups_Edit?>' , 500 , 200 ); + } + function addUserGroup( uid ){ + //popupWindow('' , '<?=$groups_AddUser?>?UID='+uid, 500 , 520 ); + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:400,h:512}, + position:{x:0,y:0,center:true}, + title : 'Add users to '+groupname+' group', + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:true} + }; + oPanel.events = { + remove: function() { + delete(oPanel); + resetChecks(); + }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + currentPopupWindow = oPanel; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '<?=$groups_AddUser?>?UID='+uid, + args: '' + }); + oRPC.callback = function(rpc) { + oPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + var inputs = document.getElementsByTagName("input"); + for(i=0; i<inputs.length; i++){ + if( inputs[i].type == "checkbox" ){ + try{ + inputs[i].onclick = function(){ + if(this.checked){ + checks_selected_ids.push(this.value); + } else { + checks_selected_ids.deleteByValue(this.value); + } + }; + }catch(e){alert(e)} + } + } + }.extend(this); + oRPC.make(); + } + function saveGroup( form ) { + ajax_post( form.action, form, 'POST' ); + currentPopupWindow.remove(); + refreshTree(); + } + + function selectGroup( uid ){ + currentGroup = uid; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'groups_Ajax', + args : 'action=showUsers&sGroupUID=' + uid + }); + oRPC.callback = function(rpc) { + var scs = rpc.xmlhttp.responseText.extractScript(); + document.getElementById('spanUsersList').innerHTML = rpc.xmlhttp.responseText; + scs.evalScript(); + }.extend(this); + + oRPC.make(); + } + function deleteGroup( uid ){ + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_DELETE_GROUP')?>", + action:function() + { + ajax_function('<?=$groups_Delete?>', 'asdxxx', 'GRP_UID='+uid, "POST" ); + refreshTree(); + document.getElementById('spanUsersList').innerHTML = ''; + }.extend(this) + }); + } + function refreshTree(){ + tree.refresh( document.getElementById("publisherContent[666]") , '<?=$groups_List?>'); + } + + var ofToAssignUser = function(sGroup, sUser) + { + new leimnud.module.app.confirm().make({ + label:"<?=G::LoadTranslation('ID_MSG_CONFIRM_REMOVE_USER')?>", + action:function() + { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../groups/groups_Ajax', + async : false, + method: 'POST', + args : 'action=ofToAssignUser&GRP_UID=' + sGroup + '&USR_UID=' + sUser + }); + oRPC.make(); + currentGroup = sGroup; + selectGroup(currentGroup); + }.extend(this) + }); + }; + +</script> diff --git a/workflow/engine/methods/groups/groups_AddUser.php b/workflow/engine/methods/groups/groups_AddUser.php new file mode 100644 index 000000000..a44c0ba23 --- /dev/null +++ b/workflow/engine/methods/groups/groups_AddUser.php @@ -0,0 +1,57 @@ +<?php +/** + * groups_AddUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + require_once ( 'classes/class.xmlfield_InputPM.php' ); + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + G::LoadClass('groups'); + $oGroups = new Groups(); + $oGroup = new Groupwf(); + $aFields = $oGroup->load($_GET['UID']); + $G_PUBLISH = new Publisher(); + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'groups/groups_UsersListTitle', '', array('GRP_NAME' => $aFields['GRP_TITLE'])); + $G_PUBLISH->AddContent('propeltable', 'groups/paged-table', 'groups/groups_AvailableUsers', $oGroups->getAvailableUsersCriteria($_GET['UID'])); + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'groups/groups_SelectUsers','', '','save' ); + G::RenderPage('publish', 'raw'); \ No newline at end of file diff --git a/workflow/engine/methods/groups/groups_Ajax.php b/workflow/engine/methods/groups/groups_Ajax.php new file mode 100644 index 000000000..5862b8553 --- /dev/null +++ b/workflow/engine/methods/groups/groups_Ajax.php @@ -0,0 +1,97 @@ +<?php +/** + * groups_Ajax.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; +G::LoadInclude('ajax'); +$_POST['action'] = get_ajax_value('action'); + +switch ($_POST['action']) +{ + case 'showUsers': + G::LoadClass('groups'); + $oGroups = new Groups(); + $oGroup = new Groupwf(); + $aFields = $oGroup->load($_POST['sGroupUID']); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'groups/groups_UsersListTitle', '', array('GRP_NAME' => $aFields['GRP_TITLE'])); + $G_PUBLISH->AddContent('propeltable', 'groups/paged-table2', 'groups/groups_UsersList', $oGroups->getUsersGroupCriteria($_POST['sGroupUID']), array('GRP_UID' => $_POST['sGroupUID'], 'GRP_NAME' => $aFields['GRP_TITLE'])); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode("groupname=\"{$aFields["GRP_TITLE"]}\";"); + + G::RenderPage('publish', 'raw'); + break; + + case 'assignUser': + G::LoadClass('groups'); + $oGroup = new Groups(); + $oGroup->addUserToGroup($_POST['GRP_UID'], $_POST['USR_UID']); + break; + + case 'assignAllUsers': + G::LoadClass('groups'); + $oGroup = new Groups(); + $aUsers=explode(',', $_POST['aUsers']); + + for($i=0; $i<count($aUsers); $i++) + { + $oGroup->addUserToGroup($_POST['GRP_UID'], $aUsers[$i]); + } + break; + + case 'ofToAssignUser': + G::LoadClass('groups'); + $oGroup = new Groups(); + $oGroup->removeUserOfGroup($_POST['GRP_UID'], $_POST['USR_UID']); + break; + + case 'verifyGroupname': + $_POST['sOriginalGroupname'] = get_ajax_value('sOriginalGroupname'); + $_POST['sGroupname'] = get_ajax_value('sGroupname'); + if ($_POST['sOriginalGroupname'] == $_POST['sGroupname']) + { + echo '0'; + } + else + { + require_once 'classes/model/Groupwf.php'; + G::LoadClass('Groupswf'); + $oGroup = new Groupwf(); + $oCriteria=$oGroup->loadByGroupname($_POST['sGroupname']); + $oDataset = GroupwfPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if (!$aRow) + { + echo '0'; + } + else + { + echo '1'; + } + } + break; +} diff --git a/workflow/engine/methods/groups/groups_Delete.php b/workflow/engine/methods/groups/groups_Delete.php new file mode 100644 index 000000000..23d3eda92 --- /dev/null +++ b/workflow/engine/methods/groups/groups_Delete.php @@ -0,0 +1,64 @@ +<?php +/** + * groups_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + G::LoadClass('groups'); + + $group = new Groupwf(); + + if (!isset($_POST['GRP_UID'])) return; + + $group->remove(urldecode($_POST['GRP_UID'])); + + require_once 'classes/model/TaskUser.php'; + $oProcess = new TaskUser(); + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(TaskUserPeer::USR_UID, $_POST['GRP_UID']); + TaskUserPeer::doDelete($oCriteria); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/groups/groups_Edit.php b/workflow/engine/methods/groups/groups_Edit.php new file mode 100644 index 000000000..c7fdbb1e6 --- /dev/null +++ b/workflow/engine/methods/groups/groups_Edit.php @@ -0,0 +1,70 @@ +<?php +/** + * groups_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + G::LoadClass('groups'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $group = new Groupwf(); + $GrpUid = (isset($_GET['UID'])) ? urldecode($_GET['UID']):''; + if ($GrpUid) + { + $aFields=$group->Load( $GrpUid ); + } + else + { + $aFields=array(); + } + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'groups/groups_Edit', '', $aFields , 'groups_Save'); + + G::RenderPage( "publish" , "raw" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/groups/groups_List.php b/workflow/engine/methods/groups/groups_List.php new file mode 100644 index 000000000..6da3cb32d --- /dev/null +++ b/workflow/engine/methods/groups/groups_List.php @@ -0,0 +1,55 @@ +<?php +/** + * groups_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + +$G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( 'view', 'groups/groups_Tree' ); + G::RenderPage( "publish-raw" , "raw" ); +?> diff --git a/workflow/engine/methods/groups/groups_Save.php b/workflow/engine/methods/groups/groups_Save.php new file mode 100644 index 000000000..0332a8655 --- /dev/null +++ b/workflow/engine/methods/groups/groups_Save.php @@ -0,0 +1,69 @@ +<?php +/** + * groups_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + G::LoadClass('groups'); + + $G_MAIN_MENU = 'wf.login'; + $G_MENU_SELECTED = ''; + + $group = new Groupwf(); + if($_POST['form']['GRP_UID']==='') + { + $grpRow = $_POST['form']; + unset ( $grpRow['GRP_UID'] ); + $group->create( $grpRow ); + + //$_POST['form']['GRP_UID']=$group->getGrpUid(); + //$group->update($_POST['form']); + } + else + { + $group->update($_POST['form']); + } + +?> \ No newline at end of file diff --git a/workflow/engine/methods/groups/groups_SaveAddUser.php b/workflow/engine/methods/groups/groups_SaveAddUser.php new file mode 100644 index 000000000..00e00ee3a --- /dev/null +++ b/workflow/engine/methods/groups/groups_SaveAddUser.php @@ -0,0 +1,29 @@ +<?php +/** + * groups_SaveAddUser.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_USERS"))!=1) return $RBAC_Response; + + G::LoadClass('groups'); + $groups = new Groups; + $groups->addUserToGroup( $_GET['GRP_UID'], $_POST['form']['USR_UID'] ); diff --git a/workflow/engine/methods/inputdocs/inputdocs_Delete.php b/workflow/engine/methods/inputdocs/inputdocs_Delete.php new file mode 100644 index 000000000..339ded311 --- /dev/null +++ b/workflow/engine/methods/inputdocs/inputdocs_Delete.php @@ -0,0 +1,91 @@ +<?php +/** + * inputdocs_Delete.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + require_once 'classes/model/StepSupervisor.php'; + require_once 'classes/model/ObjectPermission.php'; + require_once 'classes/model/InputDocument.php'; + require_once 'classes/model/Step.php'; + require_once 'classes/model/ObjectPermission.php'; + G::LoadClass( 'processMap' ); + + $sfunction =$_POST['function']; + + switch($sfunction){ + case 'getRelationInfDoc': + $oStepSupervisor = new StepSupervisor(); + $fields2=$oStepSupervisor->loadInfo($_POST['INP_DOC_UID']); + $result=false; + if(is_array($fields2)){ + $result=true; + } + + return print $result; + break; + case 'deleteInputDocument': + + $oStepSupervisor = new StepSupervisor(); + $fields2=$oStepSupervisor->loadInfo($_POST['INP_DOC_UID']); + $oStepSupervisor->remove($fields2['STEP_UID']); + + $oPermission = new ObjectPermission(); + $fields3=$oPermission->loadInfo($_POST['INP_DOC_UID']); + if(is_array($fields3)) + $oPermission->remove($fields3['OP_UID']); + + $oInputDocument = new InputDocument(); + $fields = $oInputDocument->load($_POST['INP_DOC_UID']); + + $oInputDocument->remove($_POST['INP_DOC_UID']); + + $oStep = new Step(); + $oStep->removeStep('INPUT_DOCUMENT', $_POST['INP_DOC_UID']); + + $oOP = new ObjectPermission(); + $oOP->removeByObject('INPUT', $_POST['INP_DOC_UID']); + + //refresh dbarray with the last change in inputDocument + $oMap = new processMap(); + $oCriteria = $oMap->getInputDocumentsCriteria($fields['PRO_UID']); + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/inputdocs/inputdocs_Edit.php b/workflow/engine/methods/inputdocs/inputdocs_Edit.php new file mode 100644 index 000000000..243ccb9ff --- /dev/null +++ b/workflow/engine/methods/inputdocs/inputdocs_Edit.php @@ -0,0 +1,58 @@ +<?php +/** + * inputdocs_Edit.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/InputDocument.php'; + $oInputDocument = new InputDocument(); + if (isset($_GET['INP_DOC_UID'])) { + $aFields = $oInputDocument->load($_GET['INP_DOC_UID']); + } + else { + $aFields = array(); + $aFields['PRO_UID'] = $_GET['PRO_UID']; + } + $aFields['INP_DOC_TAGS'] = isset ( $aFields['INP_DOC_TAGS']) ? $aFields['INP_DOC_TAGS'] : 'INPUT'; + $aFields['INP_DOC_VERSIONING'] = strval(isset($aFields['INP_DOC_VERSIONING'])?$aFields['INP_DOC_VERSIONING']:''); + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'inputdocs/inputdocs_Edit', '', $aFields , '../inputdocs/inputdocs_Save'); + G::RenderPage('publish', 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/inputdocs/inputdocs_List.php b/workflow/engine/methods/inputdocs/inputdocs_List.php new file mode 100644 index 000000000..978889e71 --- /dev/null +++ b/workflow/engine/methods/inputdocs/inputdocs_List.php @@ -0,0 +1,43 @@ +<?php +/** + * inputdocs_List.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'INPUTDOCS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $G_PUBLISH = new Publisher; + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'inputdocs/inputdocs_List', '', array('SYS_LANG' => SYS_LANG) , 'inputdocs_Save'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/inputdocs/inputdocs_Save.php b/workflow/engine/methods/inputdocs/inputdocs_Save.php new file mode 100644 index 000000000..619f3a789 --- /dev/null +++ b/workflow/engine/methods/inputdocs/inputdocs_Save.php @@ -0,0 +1,99 @@ +<?php +/** + * inputdocs_Save.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + + $sfunction =$_POST['function']; + + switch($sfunction){ + case 'lookForNameInput': + require_once('classes/model/Content.php'); + require_once ( "classes/model/InputDocument.php" ); + + $snameInput=urldecode($_POST['NAMEINPUT']); + $sPRO_UID=urldecode($_POST['proUid']); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn ( InputDocumentPeer::INP_DOC_UID ); + $oCriteria->add(InputDocumentPeer::PRO_UID, $sPRO_UID); + $oDataset = InputDocumentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $flag=true; + while ($oDataset->next() && $flag) { + $aRow = $oDataset->getRow(); + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->addSelectColumn('COUNT(*) AS INPUTS'); + $oCriteria1->add(ContentPeer::CON_CATEGORY, 'INP_DOC_TITLE'); + $oCriteria1->add(ContentPeer::CON_ID, $aRow['INP_DOC_UID']); + $oCriteria1->add(ContentPeer::CON_VALUE, $snameInput); + $oCriteria1->add(ContentPeer::CON_LANG, SYS_LANG); + $oDataset1 = ContentPeer::doSelectRS($oCriteria1); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aRow1 = $oDataset1->getRow(); + + if($aRow1['INPUTS'])$flag=false; + } + print $flag; + break; + + default: + + require_once 'classes/model/InputDocument.php'; + G::LoadClass( 'processMap' ); + + $oInputDocument = new InputDocument(); + if ($_POST['form']['INP_DOC_UID'] == '') { + unset($_POST['form']['INP_DOC_UID']); + $oInputDocument->create($_POST['form']); + } + else { + $oInputDocument->update($_POST['form']); + } + + //refresh dbarray with the last change in inputDocument + $oMap = new processMap(); + $oCriteria = $oMap->getInputDocumentsCriteria($_POST['form']['PRO_UID']); + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/install/autoinstallPlugins.php b/workflow/engine/methods/install/autoinstallPlugins.php new file mode 100644 index 000000000..26703c235 --- /dev/null +++ b/workflow/engine/methods/install/autoinstallPlugins.php @@ -0,0 +1,82 @@ +<?php +/** + * autoinstallProcess.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + G::LoadClass('Installer'); + $inst = new Installer(); + + G::LoadClass('processes'); + $oProcess = new Processes(); + + //Get Available autoinstall process + $availablePlugins = $inst->getDirectoryFiles(PATH_OUTTRUNK."autoinstall","tar"); + + rsort($availablePlugins); + + $path=PATH_OUTTRUNK."autoinstall".PATH_SEP; + $message=""; + foreach($availablePlugins as $filename){ + + + G::LoadThirdParty( 'pear/Archive','Tar'); + $tar = new Archive_Tar ( $path. $filename); + $sFileName = substr($filename,0,strrpos($filename, '.' )); + $sClassName = substr($filename,0,strpos($filename, '-' )); + + $aFiles = $tar->listContent(); + $bMainFile = false; + $bClassFile = false; + foreach ( $aFiles as $key => $val ) { + if ( $val['filename'] == $sClassName . '.php' ) $bMainFile = true; + if ( $val['filename'] == $sClassName . PATH_SEP . 'class.' . $sClassName . '.php' ) $bClassFile = true; + } + if ( $bMainFile && $bClassFile ) { + $res = $tar->extract ( PATH_PLUGINS ); + } + else + throw ( new Exception ( "The file $filename doesn't contain class: $sClassName ") ) ; + + //print "change to ENABLED"; + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + + $pluginFile = $sClassName . '.php'; + if ( !file_exists ( PATH_PLUGINS . $sClassName . '.php' ) ) throw ( new Exception( "File '$pluginFile' doesn't exist ") ); + + require_once ( PATH_PLUGINS . $pluginFile ); + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + + $oPluginRegistry->installPlugin( $details->sNamespace); + $oPluginRegistry->enablePlugin( $details->sNamespace); + $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + $size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); + + $message.="$filename - OK<br>"; + + } + + echo $message; + + + + +?> diff --git a/workflow/engine/methods/install/autoinstallProcesses.php b/workflow/engine/methods/install/autoinstallProcesses.php new file mode 100644 index 000000000..496b5bbe6 --- /dev/null +++ b/workflow/engine/methods/install/autoinstallProcesses.php @@ -0,0 +1,58 @@ +<?php +/** + * autoinstallProcess.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + G::LoadClass('Installer'); + $inst = new Installer(); + + G::LoadClass('processes'); + $oProcess = new Processes(); + + //Get Available autoinstall process + $availableProcess = $inst->getDirectoryFiles(PATH_OUTTRUNK."autoinstall","pm"); + + + + $path=PATH_OUTTRUNK."autoinstall".PATH_SEP; + $message=""; + foreach($availableProcess as $processfile){ + + $oData = $oProcess->getProcessData ( $path . $processfile ); + $Fields['PRO_FILENAME'] = $processfile; + $Fields['IMPORT_OPTION'] = 2; + $sProUid = $oData->process['PRO_UID']; + if ( $oProcess->processExists ( $sProUid ) ) { + $message.="$processfile - Not imported (process exist)<br>"; + + }else{ + $oProcess->createProcessFromData ($oData, $path . $processfile ); + $message.="$processfile - OK<br>"; + } + } + + echo $message; + + + + +?> \ No newline at end of file diff --git a/workflow/engine/methods/install/heartbeatStatus.php b/workflow/engine/methods/install/heartbeatStatus.php new file mode 100644 index 000000000..84ad58acd --- /dev/null +++ b/workflow/engine/methods/install/heartbeatStatus.php @@ -0,0 +1,24 @@ +<?php +try { + if(isset($_REQUEST['status'])){ + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + /*you can use SYS_TEMP or SYS_SYS ON HEAR_BEAT_CONF to save for each workspace*/ + + + if($_REQUEST['status']){ + echo "ACTIVE (Thanks!)"; + $oServerConf->setHeartbeatProperty('HB_OPTION',1,'HEART_BEAT_CONF'); + $oServerConf->unsetHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + }else{ + echo "INACTIVE"; + $oServerConf->setHeartbeatProperty('HB_OPTION',0,'HEART_BEAT_CONF'); + $oServerConf->unsetHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + } + }else{ + echo "Nothing to do"; + } +} +catch ( Exception $e ) { + echo $e->getMessage(); +} diff --git a/workflow/engine/methods/install/install.js b/workflow/engine/methods/install/install.js new file mode 100644 index 000000000..dda271d52 --- /dev/null +++ b/workflow/engine/methods/install/install.js @@ -0,0 +1,676 @@ +var installer=function() +{ + this.make=function(options) + { + this.options={ + target:inst.elements.content, + vdef:{ + wf:'wf_workflow', + rb:'rb_workflow', + rp:'rp_workflow' + } + }.concat(options || {}); + this.html(); + this.check(); + }; + this.html=function() + { + this.titleBar = document.createElement("div"); + this.titleBar.className="app_grid_headerBar___gray"; + leimnud.dom.setStyle(this.titleBar,{ + height:"auto", + textAlign:"right" + }); + this.options.target.appendChild(this.titleBar); + + this.options.button0 = document.createElement("input"); + this.options.button0.type="button"; + this.options.button0.value="Test"; + this.titleBar.appendChild(this.options.button0); + + this.options.button1 = document.createElement("input"); + this.options.button1.type="button"; + this.options.button1.value="Install"; + this.titleBar.appendChild(this.options.button1); + + this.options.button2 = document.createElement("input"); + this.options.button2.type="button"; + this.options.button2.value="Reset"; + this.titleBar.appendChild(this.options.button2); + + this.options.phpinfo = document.createElement("input"); + this.options.phpinfo.type="button"; + this.options.phpinfo.style.fontWeight="bold"; + this.options.phpinfo.value="phpinfo()"; + this.titleBar.appendChild(this.options.phpinfo); + this.options.phpinfo.onmouseup=this.showPhpinfo; + + + this.options.button1.disabled=true; + this.options.button0.onmouseup=this.check; + this.options.button1.onmouseup=function(){inst.selectTab(1);}.extend(this); + this.options.button2.onmouseup=this.reset; + + this.buttonFun(this.options.button0); + this.buttonFun(this.options.button1); + this.buttonFun(this.options.button2); + this.buttonFun(this.options.phpinfo); + + + + //this.phpVersion = + this.table = $(document.createElement("table")); +/* this.table.setStyle({ + cellpadding:23 + });*/ + this.table.className="inst_table"; + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>Requirements</b>",className:"app_grid_title___gray title",colSpan:4}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"PHP Version >= 5.1.x and PHP Version < 5.3.0",className:"inst_td0",colSpan:2}), + this.phpVersion = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"MySQL",className:"inst_td0",colSpan:2}), + this.mysqlVersion = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Maximum amount of memory a script may consume (memory_limit) >= 40M",className:"inst_td0",colSpan:2}), + this.checkMemory = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Directory "+this.options.path_trunk+"config/<br> permissions: <b>writable</b>",className:"inst_td0",colSpan:2}), + this.checkPI = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Directory "+this.options.path_trunk+"content/languages/<br> permissions: <b>writable</b>",className:"inst_td0",colSpan:2}), + this.checkDL = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"File "+this.options.path_trunk+"js/labels/<br> permissions: <b>writable</b>",className:"inst_td0",colSpan:2}), + this.checkDLJ = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"File "+this.options.path_trunk+"plugins/<br> permissions: <b>writable</b>",className:"inst_td0",colSpan:2}), + this.checkPL = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"File "+this.options.path_trunk+"xmlform/<br> permissions: <b>writable</b>",className:"inst_td0",colSpan:2}), + this.checkXF = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + + /* Database */ + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>Database</b>",className:"app_grid_title___gray title",colSpan:2}), + new DOM('td',{className:"app_grid_title___gray title",colSpan:2}).append( + this.select_ao_db = new select({data:[ + {value:1,text:"Advanced options by default"}, + {value:2,text:"Change Advanced options"} + ], + style:{width:"100%",border:"1px solid #919B9C"}, + properties:{onchange:function(){ + if(this.select_ao_db.selected().value==1) + { + this.ed_advanced_options({ + sta:"disabled", + act:'usr', + def:true + }); + this.ao_db_wf.passed().value=this.options.vdef.wf; + this.ao_db_rb.passed().value=this.options.vdef.rb; + this.ao_db_rp.passed().value=this.options.vdef.rp; + this.ao_db_drop.checked=false; + } + else + { + this.ed_advanced_options({ + act:'usr', + sta:"enabled" + }); + this.ao_db_wf.focus(); + } + }.extend(this)} + }) + ) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Database server Hostname",className:"inst_td0"},{width:"30%"}), + new DOM('td',{className:"inst_td1"},{width:"30%"}).append( +// this.databaseHostname =new DOM("input",{value:'localhost',type:"text",onkeyup:this.submit,className:"inputNormal"}) + this.databaseHostname = new input({label:'localhost',properties:{onkeyup:this.submit},style:{width:"100%"}}) + ), + new DOM('td',{innerHTML:"Workflow Database:",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_db_wf = new input({label:this.options.vdef.wf,properties:{onkeyup:this.submit},style:{width:"100%"},maxlength:16}).passed().disable() + ) + + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Username",className:"inst_td0"},{width:"30%"}), + new DOM('td',{className:"inst_td1"},{width:"30%"}).append( +// this.databaseUsername =new DOM("input",{value:'root',type:"text",onkeyup:this.submit,className:"inputNormal"}) + this.databaseUsername = new input({label:'root',properties:{onkeyup:this.submit},style:{width:"100%"}}) + ), + new DOM('td',{innerHTML:"Rbac Database:",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_db_rb = new input({label:this.options.vdef.rb,properties:{onkeyup:this.submit},style:{width:"100%"},maxlength:16}).passed().disable() + ) + + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Password",className:"inst_td0"},{width:"30%"}), + new DOM('td',{className:"inst_td1"},{width:"30%"}).append( +// this.databasePassword =new DOM("input",{type:"text",onkeyup:this.submit,className:"inputNormal"}) + this.databasePassword = new input({properties:{type:'password',onkeyup:this.submit},style:{width:"100%"}}) + ), + new DOM('td',{innerHTML:"Report Database:",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_db_rp = new input({label:this.options.vdef.rp,properties:{onkeyup:this.submit},style:{width:"100%"},maxlength:16}).passed().disable() + ) + + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Database Access",className:"inst_td0"},{width:"30%"}), + this.databaseGrant = new DOM('td',{className:"inst_td1"},{width:"30%"}), + + new DOM('td',{innerHTML:"DROP DATABASE IF EXISTS",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td0"},{width:"20%",textAlign:'left'}).append( + this.ao_db_drop = new input({ + properties:{type:'checkbox',disabled:true,className:''},style:{border:"1px solid #666"} + }) + ) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + this.databaseStatus = new DOM('td',{innerHTML:"<br>",className:"tdNormal",colSpan:4},{height:50}) + ); + + /* Database End */ + + + + /* Directories Begin */ + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>Processmaker Configuration</b>",className:"app_grid_title___gray title",colSpan:2}), + new DOM('td',{className:"app_grid_title___gray title",colSpan:2}).append( + + this.select_ao_pm = new select({data:[ + {value:1,text:"Advanced options by default"}, + {value:2,text:"Change Advanced options"} + ], + style:{width:"100%",border:"1px solid #919B9C"}, + properties:{onchange:function(){ + if(this.select_ao_pm.selected().value==1) + { + this.ed_advanced_options({ + act:'pm', + sta:"disabled", + def:true + }); + this.ao_admin.passed().value="admin"; + this.ao_admin_pass1.passed().value="admin"; + this.ao_admin_pass2.passed().value="admin"; + + } + else + { + this.ed_advanced_options({ + act:'pm', + sta:"enabled" + }); + this.ao_admin.focus(); + } + }.extend(this)} + }) + ) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"Workflow Data Directory: ",className:"inst_td0"},{width:"30%"}), + new DOM('td',{className:"inst_td1"},{width:"30%"}).append( + this.workflowData = new input({label:this.options.path_data,properties:{onkeyup:this.submit},style:{width:"100%"},maxlength:200}) + ), + new DOM('td',{innerHTML:"Username (Default: admin):",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_admin = new input({label:'admin',properties:{onkeyup:this.submit},style:{width:"100%"}}).passed().disable() + ) + + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"",className:"inst_td0"},{width:"30%"}), + new DOM('td',{className:"inst_td1"},{width:"30%"}).append( + this.compiled = new input({label:this.options.path_compiled,properties:{onkeyup:this.submit},style:{width:"100%", display:'none'},maxlength:200}) + ), + new DOM('td',{innerHTML:"Username (Default: admin):",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_admin_pass1 = new input({label:'admin',properties:{onkeyup:this.submit,type:'password'},style:{width:"100%"}}).passed().disable() + ) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{className:"inst_td0",colSpan:2}), + new DOM('td',{innerHTML:"Re-type Password:",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td1"},{width:"20%"}).append( + this.ao_admin_pass2 = new input({label:'admin',properties:{onkeyup:this.submit,type:'password'},style:{width:"100%"}}).passed().disable() + ) + ); + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>HeartBeat Configuration</b><br><i>Heartbeat is a anonymous statistics collector for ProcessMaker. It runs in the background and if you have internet enabled, it will periodically send anonymous information to ProcessMaker servers.<br />No sensitive or private information is collected.<br /><br /> The information collected will allow us to keep improving our software to offer everyone a better user experience</i>",className:"app_grid_title___gray title",colSpan:4}) + ); + this.heartBeatTitle=tr; + + var tr = this.table.insertRow(-1); + $(tr).append( + + this.heartBeat = + + new DOM('td',{innerHTML:"Enable HeartBeat",className:"inst_td0"},{width:"20%"}), + new DOM('td',{className:"inst_td0",colSpan:2},{textAlign:'left'}).append( + this.ao_hb_status = new input({ + properties:{type:'checkbox',disabled:false,checked:true,className:''},style:{border:"1px solid #666"} + }) + ) + ); + + + this.heartBeatRow=tr; + + + //alert(this.options.availableProcess); + //alert(this.options.availableProcess.length); + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>Available Processes (auto install)</b>",className:"app_grid_title___gray title",colSpan:4}) + ); + this.availableProcessTitle=tr; + + var tr = this.table.insertRow(-1); + $(tr).append( + this.availableProcess = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + this.availableProcessRow=tr; + + var tr = this.table.insertRow(-1); + $(tr).append( + new DOM('td',{innerHTML:"<b>Available Plugins (auto install)</b>",className:"app_grid_title___gray title",colSpan:4}) + ); + this.availablePluginsTitle=tr; + + var tr = this.table.insertRow(-1); + $(tr).append( + this.availablePlugins = new DOM('td',{innerHTML:'Loading...',className:"inst_td1",colSpan:2}) + ); + this.availablePluginsRow=tr; + + + leimnud.dom.setStyle([this.workflowData,this.compiled],{ + textAlign:"left" + }); + this.options.target.appendChild(this.table); + }; + this.formData=function() + { + //alert(this.databaseExe.value.eplace("\\","/")) + return { + mysqlH :escape(this.databaseHostname.value), + mysqlU :escape(this.databaseUsername.value), + mysqlP :escape(this.databasePassword.value), +// port :this.port.value, + path_data:this.workflowData.value, + path_compiled:this.compiled.value, + ao_admin :escape(this.ao_admin.value), + ao_admin_pass1 :escape(this.ao_admin_pass1.value), + ao_admin_pass2 :escape(this.ao_admin_pass2.value), + ao_db_wf :this.ao_db_wf.value, + ao_db_rb :this.ao_db_rb.value, + ao_db_rp :this.ao_db_rp.value, + ao_db :parseInt(this.select_ao_db.selected().value), + ao_pm :parseInt(this.select_ao_pm.selected().value), + ao_db_drop :this.ao_db_drop.checked, + heartbeatEnabled :this.ao_hb_status.checked + }; + }; + this.check=function() + { + inst.loader.show(); + this.disabled(true); + this.ed_advanced_options({sta:'disabled',act:'all'}); + var r = new leimnud.module.rpc.xmlhttp({ + url :this.options.server, + method :"POST", + args :"action=check&data="+this.formData().toJSONString() + }); + r.callback=function(rpc) + { + try + { + this.cstatus = rpc.xmlhttp.responseText.parseJSON(); + } + catch(e) + { + this.cstatus={ + ao_db_wf:false, + ao_db_rb:false, + ao_db_rp:false + }; + } + this.phpVersion.className = (!this.cstatus.phpVersion)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.phpVersion.innerHTML = (!this.cstatus.phpVersion)?"FAILED":"PASSED"; + + this.mysqlVersion.className = (!this.cstatus.mysqlVersion)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.mysqlVersion.innerHTML = (!this.cstatus.mysqlVersion)?"FAILED":"PASSED"; + + this.checkMemory.className = (!this.cstatus.checkMemory)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkMemory.innerHTML = (!this.cstatus.checkMemory)?"FAILED":"PASSED"; + +// this.checkmqgpc.className = (!this.cstatus.checkmqgpc)?"inst_td1 tdFailed":"inst_td1 tdOk"; +// this.checkmqgpc.innerHTML = (!this.cstatus.checkmqgpc)?"FAILED":"PASSED"; + + this.checkPI.className = (!this.cstatus.checkPI)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkPI.innerHTML = (!this.cstatus.checkPI)?"FAILED":"PASSED"; + + this.checkDL.className = (!this.cstatus.checkDL)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkDL.innerHTML = (!this.cstatus.checkDL)?"FAILED":"PASSED"; + + this.checkDLJ.className = (!this.cstatus.checkDLJ)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkDLJ.innerHTML = (!this.cstatus.checkDLJ)?"FAILED":"PASSED"; + + this.checkPL.className = (!this.cstatus.checkPL)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkPL.innerHTML = (!this.cstatus.checkPL)?"FAILED":"PASSED"; + + this.checkXF.className = (!this.cstatus.checkXF)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.checkXF.innerHTML = (!this.cstatus.checkXF)?"FAILED":"PASSED"; + + this.databaseHostname[(!this.cstatus.mysqlConnection)?"failed":"passed"](); + this.databaseUsername[(!this.cstatus.mysqlConnection)?"failed":"passed"](); + this.databasePassword[(!this.cstatus.mysqlConnection)?"failed":"passed"](); + + this.databaseGrant.className = (!this.cstatus.grantPriv && this.select_ao_db.selected().value==1)?"inst_td1 tdFailed":"inst_td1 tdOk"; + this.databaseGrant.innerHTML = (!this.cstatus.grantPriv)?"FAILED":((this.cstatus.grantPriv==1)?'ALL PRIVILEGES':'USAGE'); + + this.databaseStatus.className = (!this.cstatus.grantPriv || !this.cstatus.mysqlConnection)?"tdFailed":"tdOk"; + this.databaseStatus.innerHTML = this.cstatus.databaseMessage; + + this.workflowData[(!this.cstatus.path_data)?"failed":"passed"](); + this.compiled[(!this.cstatus.path_compiled)?"failed":"passed"](); + + + this.ao_db_wf[((!this.cstatus.ao_db_wf['status'])?"failed":"passed")](); + this.ao_db_rb[((!this.cstatus.ao_db_rb['status'])?"failed":"passed")](); + this.ao_db_rp[((!this.cstatus.ao_db_rp['status'])?"failed":"passed")](); + + this.ao_admin[(!this.cstatus.ao_admin && this.select_ao_pm.selected().value==2)?"failed":"passed"](); + this.ao_admin_pass1[(!this.cstatus.ao_admin_pass && this.select_ao_pm.selected().value==2)?"failed":"passed"](); + this.ao_admin_pass2[(!this.cstatus.ao_admin_pass && this.select_ao_pm.selected().value==2)?"failed":"passed"](); + + if(this.cstatus.ao_db_wf['status'] && this.cstatus.ao_db_rb['status'] && this.cstatus.ao_db_rp['status'] && this.cstatus.ao_admin && this.cstatus.ao_admin_pass && this.cstatus.checkMemory && this.cstatus.checkPI && this.cstatus.checkDL && this.cstatus.checkDLJ && this.cstatus.checkPL && this.cstatus.checkXF && this.cstatus.phpVersion && this.cstatus.mysqlVersion && this.cstatus.mysqlConnection && this.cstatus.grantPriv && this.cstatus.path_data && this.cstatus.path_compiled) + { + this.options.button0.disabled=true; + this.options.button1.disabled=false; + this.disabled(true); + } + else + { + this.options.button0.disabled=false; + this.options.button1.disabled=true; + this.disabled(false); + this.compiled.focus(); + + this.ed_advanced_options({sta:((this.select_ao_db.selected().value==2)?'enabled':'disabled'),act:'usr'}); + this.ed_advanced_options({sta:((this.select_ao_pm.selected().value==2)?'enabled':'disabled'),act:'pm'}); + } + this.buttonFun(this.options.button0); + this.buttonFun(this.options.button1); + + this.ao_db_wf.title=this.cstatus.ao_db_wf.message; + this.ao_db_rb.title=this.cstatus.ao_db_rb.message; + this.ao_db_rp.title=this.cstatus.ao_db_rp.message; + + this.ao_admin.title=(this.cstatus.ao_admin)?'Username invalid':'PASSED'; + + + //*Autoinstall Process and Plugins. By JHL + // March 11th. 2009 + // To enable the way of aoutoinstall process and/or plugins + // at same time of initial PM setup + if(this.cstatus.availableProcess.length>0){ + this.availableProcess.className = "inst_td1 tdOk"; + this.availableProcess.innerHTML=""; + for(i_process=0;i_process<this.cstatus.availableProcess.length;i_process++){ + this.availableProcess.innerHTML+=this.cstatus.availableProcess[i_process]+"<br />"; + } + }else{ + //Hide entire Group + this.availableProcessTitle.style.display="none"; + this.availableProcessRow.style.display="none"; + } + + if(this.cstatus.availablePlugins.length>0){ + this.availablePlugins.className = "inst_td1 tdOk"; + this.availablePlugins.innerHTML=""; + for(i_plugin=0;i_plugin<this.cstatus.availablePlugins.length;i_plugin++){ + this.availablePlugins.innerHTML+=this.cstatus.availablePlugins[i_plugin]+"<br />"; + } + }else{ + //Hide entire Group + this.availablePluginsTitle.style.display="none"; + this.availablePluginsRow.style.display="none"; + } + //End Autoinstall + + inst.loader.hide(); + }.extend(this); + r.make(); + }; + this.reset=function() + { + this.options.button1.disabled=true; + this.buttonFun(this.options.button1); + this.disabled(false); + }; + this.disabled=function(dis) + { + this.databaseHostname[(dis===true)?'disable':'enable'](); + this.databaseUsername[(dis===true)?'disable':'enable'](); + this.databasePassword[(dis===true)?'disable':'enable'](); + this.workflowData[(dis===true)?'disable':'enable'](); + this.compiled[(dis===true)?'disable':'enable'](); + if(this.compiled.disabled===false) + { + this.compiled.focus(); + } + this.options.button0.disabled=dis; + this.buttonFun(this.options.button0); + }; + this.ed_advanced_options=function(options) + { + options = { + sta:"disabled", + act:"all", + def:false + }.concat(options || {}); + + if(options.act=='pm' || options.act=="all") + { + this.ao_admin[(options.sta=="disabled")?'disable':'enable'](); + this.ao_admin_pass1[(options.sta=="disabled")?'disable':'enable'](); + this.ao_admin_pass2[(options.sta=="disabled")?'disable':'enable'](); + } + if(options.act=='usr' || options.act=="all") + { + this.ao_db_wf[(options.sta=="disabled")?'disable':'enable'](); + this.ao_db_rb[(options.sta=="disabled")?'disable':'enable'](); + this.ao_db_rp[(options.sta=="disabled")?'disable':'enable'](); + this.ao_db_drop.disabled=(options.sta=="disabled")?true:false; + } + }; + this.submit=function(evt) + { + var evt = (window.event)?window.event:evt; + var key = (evt.which)?evt.which:evt.keyCode; + if(key==13) + { + this.check(); + } + return false; + }; + this.install=function() + { + this.values = this.formData(); + inst.clearContent(); + inst.loader.show(); + this.options.button2.disabled=true; + this.options.button1.disabled=true; + var r = new leimnud.module.rpc.xmlhttp({ + url :this.options.server, + method :"POST", + args :"action=install&data="+this.values.toJSONString() + }); + r.callback=this.installation; + r.make(); + }; + this.installation=function(rpc) + { +/* var r = new leimnud.module.rpc.xmlhttp({ + url :"/sysworkflow/en/green/tools/updateTranslation", + method :"GET" + }); + r.callback=function(rpc) + {*/ + inst.loader.hide(); + this.table = document.createElement("table"); + this.table.className="inst_table"; + + var tr = this.table.insertRow(-1); + var tdtitle = tr.insertCell(0); + tdtitle.innerHTML="Directories"; + tdtitle.className="app_grid_title___gray title"; + + var tr = this.table.insertRow(-1); + var td0 = tr.insertCell(0); + td0.innerHTML="SUCCESS"; + td0.className="tdOk"; + + var tr = this.table.insertRow(-1); + var tdtitle = tr.insertCell(0); + tdtitle.innerHTML="New Workspace"; + tdtitle.className="app_grid_title___gray title"; + + var tr = this.table.insertRow(-1); + var td0 = tr.insertCell(0); + td0.innerHTML="SUCCESS"; + td0.className="tdOk"; + this.options.target.appendChild(this.table); + + var tr = this.table.insertRow(-1); + var tdS = tr.insertCell(0); + tdS.colSpan = 2; + tdS.innerHTML="<br><br>"; + tdS.className="tdNormal"; + + + this.options.buttong = document.createElement("input"); + this.options.buttong.type="button"; + this.options.buttong.value="Finish Installation"; + this.options.buttong.onmouseup=function() + { + window.location = "/sysworkflow/en/green/login/login"; + }.extend(this); + tdS.appendChild(this.options.buttong); + this.buttonFun(this.options.buttong); + tdS.appendChild(document.createElement("br")); + tdS.appendChild(document.createElement("br")); + + var tr = this.table.insertRow(-1); + var tdtitle = tr.insertCell(0); + tdtitle.innerHTML="Installation Log"; + tdtitle.className="app_grid_title___gray title"; + + var tr = this.table.insertRow(-1); + var td0 = tr.insertCell(0); + var pre = document.createElement('pre'); + pre.style.overflow='scroll'; + pre.style.width=(this.options.target.clientWidth-10)+"px"; + pre.style.height=((this.options.target.clientHeight-this.table.clientHeight)-15)+'px'; + pre.innerHTML=rpc.xmlhttp.responseText; + td0.appendChild(pre); +// }.extend(this); +// r.make(); + }; + this.buttonFun=function(but) + { + if(but.disabled==true) + { + but.className="app_grid_title___gray button buttonDisabled"; + but.onmouseover=function(){ this.className="app_grid_title___gray button buttonDisabled"}; + but.onmouseout=function(){ this.className="app_grid_title___gray button buttonDisabled"}; + but.onblur=function(){ this.className="app_grid_title___gray button buttonDisabled"}; + } + else + { + but.className="app_grid_title___gray button"; + but.onmouseover=function(){ this.className="app_grid_title___gray button buttonHover"}; + but.onmouseout=function(){ this.className="app_grid_title___gray button"}; + but.onblur=function(){ this.className="app_grid_title___gray button"}; + } + }; + this.showPhpinfo=function() + { + var panel = new leimnud.module.panel(); + panel.options={ + title:"PHP info", + position:{center:true}, + size:{w:700,h:document.body.clientHeight-50}, + fx:{modal:true} + }; + panel.make(); + var r = new leimnud.module.rpc.xmlhttp({ + url :"install.php", + method :"POST", + args :"phpinfo=true" + }); + r.callback=function(rpc) + { + panel.addContent(rpc.xmlhttp.responseText); + }; + r.make(); + }; + this.expand(this); +} diff --git a/workflow/engine/methods/install/install.php b/workflow/engine/methods/install/install.php new file mode 100644 index 000000000..f397fedbe --- /dev/null +++ b/workflow/engine/methods/install/install.php @@ -0,0 +1,203 @@ +<?php +/** + * install.php + * + * ProcessMaker Open Source Edition + * Copyright (C) 2004 - 2008 Colosa Inc.23 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * Default home page view + * + * @author MaBoRaK + * @version 0.1 + */ +if($_POST && $_POST['phpinfo']) +{ + phpinfo(); + die(); +} +echo '<?xml version="1.0" encoding="UTF-8" ?>'; +?> +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>Processmaker Installer + + + + + + + + + + + + + diff --git a/workflow/engine/methods/install/installServer.php b/workflow/engine/methods/install/installServer.php new file mode 100644 index 000000000..ff1c5b45b --- /dev/null +++ b/workflow/engine/methods/install/installServer.php @@ -0,0 +1,295 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$isWindows = PHP_OS == 'WINNT' ? true : false; + +$oJSON = new Services_JSON(); +$action = $_POST['action']; +$dataClient = $oJSON->decode(stripslashes($_POST['data'])); +function find_SQL_Version($my = 'mysql',$infExe) +{ + if(PHP_OS=="WINNT" && !$infExe) + { + return false; + } + $output = shell_exec($my.' -V'); + preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version); + return $version[0]; +} +if($action==="check") +{ + /* TODO: Check if this space is required */ + print " "; + G::LoadClass('Installer'); + $inst = new Installer(); + $siteName="workflow"; + $p1 = (isset($dataClient->ao_admin_pass1))?$dataClient->ao_admin_pass1:'admin'; + $p2 = (isset($dataClient->ao_admin_pass2))?$dataClient->ao_admin_pass2:'admin'; + $s = $inst->create_site(Array( + 'name' =>'workflow', + 'path_data'=>$dataClient->path_data, + 'path_compiled'=>$dataClient->path_compiled, + 'admin'=>Array('username'=>(isset($dataClient->ao_admin))?$dataClient->ao_admin:'admin','password'=>$p1), + 'advanced'=>Array( + 'ao_db'=>(isset($dataClient->ao_db) && $dataClient->ao_db===2)?false:true, + 'ao_db_drop'=>(isset($dataClient->ao_db_drop) && $dataClient->ao_db_drop===true)?true:false, + 'ao_db_wf'=>(isset($dataClient->ao_db_wf))?$dataClient->ao_db_wf:'wf_'.$siteName, + 'ao_db_rb'=>(isset($dataClient->ao_db_rb))?$dataClient->ao_db_rb:'rb_'.$siteName, + 'ao_db_rp'=>(isset($dataClient->ao_db_rp))?$dataClient->ao_db_rp:'rp_'.$siteName + ), + 'database'=>Array( + 'hostname'=>$dataClient->mysqlH, + 'username'=>$dataClient->mysqlU, + 'password'=>$dataClient->mysqlP + ) + )); + $data=null; + $data->phpVersion =(version_compare(PHP_VERSION,"5.1.0",">=") && version_compare(PHP_VERSION,"5.3.0","<") )?true:false; + if(trim($dataClient->mysqlH)=='' || trim($dataClient->mysqlU)=='') + { + $con = array('connection'=>false,'grant'=>false,'message'=>'Please complete the input fields (Hostname/Username)'); + } + $data->mysqlConnection =$s['result']['database']['connection']; + $data->grantPriv =$s['result']['database']['grant']; + $data->databaseMessage =$s['result']['database']['message']; + $data->mysqlVersion =$s['result']['database']['version']; + $data->path_data =$s['result']['path_data']; + $data->path_compiled =$s['result']['path_compiled']; + $data->checkMemory =(((int)ini_get("memory_limit"))>=40)?true:false; + #$data->checkmqgpc =(get_magic_quotes_gpc())?false:true; + $data->checkPI =$inst->is_dir_writable(PATH_CORE."config/"); + $data->checkDL =$inst->is_dir_writable(PATH_CORE."content/languages/"); + $data->checkDLJ =$inst->is_dir_writable(PATH_CORE."js/labels/"); + $data->checkPL =$inst->is_dir_writable(PATH_CORE."plugins/"); + $data->checkXF =$inst->is_dir_writable(PATH_CORE."xmlform/"); + $data->ao_db_wf =$s['result']['database']['ao']['ao_db_wf']; + $data->ao_db_rb =$s['result']['database']['ao']['ao_db_rb']; + $data->ao_db_rp =$s['result']['database']['ao']['ao_db_rp']; + + $data->ao_admin =$s['result']['admin']['username']; + $data->ao_admin_pass=($p1!==$p2)?false:true; + + //*Autoinstall Process and Plugins. By JHL + // March 11th. 2009 + // To enable the way of aoutoinstall process and/or plugins + // at same time of initial PM setup + + //Get Available autoinstall process + $data->availableProcess = $inst->getDirectoryFiles(PATH_OUTTRUNK."autoinstall","pm"); + + //Get Available autoinstall plugins + $data->availablePlugins = $inst->getDirectoryFiles(PATH_OUTTRUNK."autoinstall","tar"); + + //End autoinstall + + $data->microtime =microtime(true); + echo $oJSON->encode($data); +} +else if($action==="install") +{ + /* + * Installation with SIMPLE POST + * + * Data necessary for the POST: + * + * + * action=install + * data= {"mysqlE":"Path/to/mysql.exe", + * "mysqlH":"Mysqlhostname", + * "mysqlU":"mysqlUsername", + * "mysqlP":"mysqlPassword", + * "path_data":"/path/to/workflow_data/", + * "path_compiled":"/path/to/compiled/", + * "heartbeatEnabled":"1"} + * + *-------------------------------------------------------------------------------------------------------------- + * + * Steps to install. + * 1) This data is required: + * $HOSTNAME + * $USERNAME + * $PASSWORD + * $PATH_TO_WORKFLOW_DATA + * $PATH_TO_COMPILED DATA + * 2) create $PATH_TO_WORKFLOW_DATA + * 3) create $PATH_TO_COMPILED_DATA + * 4) Create the site workflow + * + * 4.1 Create user (mysql) wf_workflow , password: sample + * 4.1.1 Create database wf_workflow with user wf_workflow + * 4.1.2 Give all priviledges to database wf_workflow for user wf_workflow + * 4.1.3 Dump file processmaker/workflow/engine/data/mysql/schema.sql + * 4.1.4 Dump file processmaker/workflow/engine/data/mysql/insert.sql + * + * 4.2 Create user (mysql) wf_rbac, password: sample + * 4.2.1 Create database wf_rbac with user wf_rbac + * 4.2.2 Give all priviledges to databse wf_rbac for user wf_rbac + * 4.2.3 Dump file processmaker/rbac/engine/data/mysql/schema.sql + * 4.2.4 Dump file processmaker/rbac/engine/data/mysql/insert.sql + * + * 4.3 Create configuratoin file and directories to site workflow + * + * 4.3.1 Create directories: + * + * $PATH_TO_WORKFLOW_DATA./sites/workflow/ + * $PATH_TO_WORKFLOW_DATA./sites/workflow/cutomFunctions/ + * $PATH_TO_WORKFLOW_DATA./sites/workflow/rtfs/ + * $PATH_TO_WORKFLOW_DATA./sites/workflow/xmlforms/ + * $PATH_TO_WORKFLOW_DATA./sites/workflow/processesImages/ + * $PATH_TO_WORKFLOW_DATA./sites/workflow/files/ + * 4.3.2 Create file. + * + * $PATH_TO_WORKFLOW_DATA./sites/workflow/db.php + * + * with these contents replacing $HOSTNAME. + * + + + * 4.4 Create file workflow/engine/config/paths_installed.php with these contents. + * + * + + Restarting: + * $PATH_TO_WORKFLOW_DATA + * $PATH_TO_COMPILED DATA + * + * 4.2 Update translation from this url (background) + * + * http://ProcessmakerHostname/sysworkflow/en/green/tools/updateTranslation + * + * + * + * + *5) Auto install processes and plugins + *5.1 Install processes + *5.2 Install plugins + * */ + + $sp = "/"; + $dir_data = $dataClient->path_data; + //$dir_compiled = $dataClient->path_compiled; + + $dir_data = (substr($dir_data,-1)==$sp)?$dir_data:$dir_data."/"; + $dir_compiled = $dir_data . "compiled/"; //(substr($dir_compiled,-1)==$sp)?$dir_compiled:$dir_compiled."/"; + global $isWindows; + + @mkdir($dir_data."sites",0777,true); + @mkdir($dir_compiled,0777,true); + + $create_db ="create-db.sql"; + $schema ="schema.sql"; + + G::LoadClass('Installer'); + + /* Create default workspace called workflow */ + $inst = new Installer(); + $siteName="workflow"; + $p1 = (isset($dataClient->ao_admin_pass1))?$dataClient->ao_admin_pass1:'admin'; + $p2 = (isset($dataClient->ao_admin_pass2))?$dataClient->ao_admin_pass2:'admin'; + $s = $inst->create_site(Array( + 'name' =>'workflow', + 'path_data'=>$dataClient->path_data, + 'path_compiled'=>$dataClient->path_compiled, + 'admin'=>Array('username'=>(isset($dataClient->ao_admin))?$dataClient->ao_admin:'admin','password'=>$p1), + 'advanced'=>Array( + 'ao_db'=>(isset($dataClient->ao_db) && $dataClient->ao_db===2)?false:true, + 'ao_db_drop'=>(isset($dataClient->ao_db_drop) && $dataClient->ao_db_drop===true)?true:false, + 'ao_db_wf'=>(isset($dataClient->ao_db_wf))?$dataClient->ao_db_wf:'wf_'.$siteName, + 'ao_db_rb'=>(isset($dataClient->ao_db_rb))?$dataClient->ao_db_rb:'rb_'.$siteName, + 'ao_db_rp'=>(isset($dataClient->ao_db_rp))?$dataClient->ao_db_rp:'rp_'.$siteName + ), + 'database'=>Array( + 'hostname'=>$dataClient->mysqlH, + 'username'=>$dataClient->mysqlU, + 'password'=>$dataClient->mysqlP + ) + ),true); + + /* Status is used in the Windows installer, do not change this */ + print_r("Status: ".($s['created'] ? 'SUCCESS':'FAILED')."\n\n"); + print_r("Installation arguments:\n"); + print_r($dataClient); + print_r("\n"); + if (!$s['created']) { + /* On a failed install, $inst->report is blank because the + * installation didnt occured at all. So we use the test report + * instead. + */ + print_r("Installation report:\n"); + print_r($s['result']); + die(); + } + + print_r("Installation report:\n"); + print_r($inst->report); + + $sh=md5(filemtime(PATH_GULLIVER."/class.g.php")); + $h=G::encrypt($dataClient->mysqlH.$sh.$dataClient->mysqlU.$sh.$dataClient->mysqlP.$sh.$inst->cc_status,$sh); + $db_text = ""; + $fp = fopen(FILE_PATHS_INSTALLED, "w"); + fputs( $fp, $db_text, strlen($db_text)); + fclose( $fp ); + + /* Update languages */ + $update = file_get_contents("http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/sysworkflow/en/green/tools/updateTranslation"); + print_r("Update language => ".((!$update)?$update:"OK")."\n"); + + /* Heartbeat Enable/Disable */ + if(!isset($dataClient->heartbeatEnabled)) $dataClient->heartbeatEnabled=true; + $update = file_get_contents("http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/sysworkflow/en/green/install/heartbeatStatus?status=".$dataClient->heartbeatEnabled); + print_r("Heartbeat Status => ".str_replace("
    ","\n",$update)."\n"); + + /* Autoinstall Process */ + $update = file_get_contents("http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/sysworkflow/en/green/install/autoinstallProcesses"); + if (trim(str_replace("
    ","",$update)) == "") + $update = "Nothing to do."; + print_r("Process AutoInstall => ".str_replace("
    ","\n",$update)."\n"); + + /* Autoinstall Plugins */ + $update = file_get_contents("http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/sysworkflow/en/green/install/autoinstallPlugins"); + if (trim(str_replace("
    ","",$update)) == "") + $update = "Nothing to do."; + print_r("Plugin AutoInstall => ".str_replace("
    ","\n",$update)."\n"); +} +?> diff --git a/workflow/engine/methods/install/newSite.php b/workflow/engine/methods/install/newSite.php new file mode 100644 index 000000000..860c56980 --- /dev/null +++ b/workflow/engine/methods/install/newSite.php @@ -0,0 +1,96 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +if(isset($_POST['form']['NW_TITLE'])) +{ + $action = (isset($_POST['form']['ACTION']))?trim($_POST['form']['ACTION']):'test'; + G::LoadClass('Installer'); + G::LoadClass('json'); + $name = trim($_POST['form']['NW_TITLE']); + $inst = new Installer(); + + $isset = $inst->isset_site($name); + + $new = ((!$isset))?true:false; + $user = (isset($_POST['form']['NW_USERNAME']))?trim($_POST['form']['NW_USERNAME']):'admin'; + $pass = (isset($_POST['form']['NW_PASSWORD']))?$_POST['form']['NW_PASSWORD']:'admin'; + $pass1 = (isset($_POST['form']['NW_PASSWORD2']))?$_POST['form']['NW_PASSWORD2']:'admin'; + + $ao_db_drop = (isset($_POST['form']['AO_DB_DROP']))?true:false; + + $ao_db_wf = (isset($_POST['form']['AO_DB_WF']))?$_POST['form']['AO_DB_WF']:false; + $ao_db_rb = (isset($_POST['form']['AO_DB_RB']))?$_POST['form']['AO_DB_RB']:false; + $ao_db_rp = (isset($_POST['form']['AO_DB_RP']))?$_POST['form']['AO_DB_RP']:false; + + $result = $inst->create_site(Array( + 'isset'=>true, + 'name' =>$name, + 'admin'=>Array('username'=>$user,'password'=>$pass), + 'advanced'=>Array( + 'ao_db_drop'=>$ao_db_drop, + 'ao_db_wf'=>$ao_db_wf, + 'ao_db_rb'=>$ao_db_rb, + 'ao_db_rp'=>$ao_db_rp + ) + ),($action==='create')?true:false); + $result['result']['admin']['password']=($pass===$pass1)?true:false; + $result['result']['action']=$action; + //print_r($inst); + $json = new Services_JSON(); + /*$ec; + $ec->created=($new)?true:false; + $ec->name=$name; + $ec->message=($new)?"Workspace created":"Workspace already exists or Name invalid";*/ + echo $json->encode($result); +} +else +{ + global $RBAC; + switch ($RBAC->userCanAccess('PM_SETUP_ADVANCE')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -3: + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/newSite', '', '', '/sys/en/green/install/newSite'); + + if( isset($_GET['type']) ) + G::RenderPage( "publishBlank", "blank"); + else + G::RenderPage( "publish" ); + + +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/install/r.php b/workflow/engine/methods/install/r.php new file mode 100644 index 000000000..5ac6226c1 --- /dev/null +++ b/workflow/engine/methods/install/r.php @@ -0,0 +1,8 @@ + diff --git a/workflow/engine/methods/login/authentication.php b/workflow/engine/methods/login/authentication.php new file mode 100644 index 000000000..782ca9487 --- /dev/null +++ b/workflow/engine/methods/login/authentication.php @@ -0,0 +1,263 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + + if (!isset($_POST['form']) ) { + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); + G::header ("location: login.html");die; + } + + +try { + $frm = $_POST['form']; + $usr = ''; + $pwd = ''; + if (isset($frm['USR_USERNAME'])) { + $usr = strtolower(trim($frm['USR_USERNAME'])); + $pwd = trim($frm['USR_PASSWORD']); + } + $uid = $RBAC->VerifyLogin($usr , $pwd); + $sPwd = 'currentPwd'; + switch ($uid) { + //The user does not exist + case -1: + G::SendTemporalMessage ('ID_USER_NOT_REGISTERED', "warning"); + break; + //The password is incorrect + case -2: + G::SendTemporalMessage ('ID_WRONG_PASS', "warning"); + if(isset($_SESSION['__AUTH_ERROR__'])){ + G::SendMessageText($_SESSION['__AUTH_ERROR__'], "warning"); + unset($_SESSION['__AUTH_ERROR__']); + } + break; + //The user is inactive + case -3: + require_once 'classes/model/Users.php'; + $user = new Users; + $aUser = $user->loadByUsernameInArray($usr); + switch($aUser['USR_STATUS']){ + case 'VACATION': + G::SendTemporalMessage ('ID_USER_ONVACATION', "warning"); + break; + CASE 'INACTIVE': + G::SendTemporalMessage ('ID_USER_INACTIVE', "warning"); + break; + } + break; + //The Due date is finished + case -4: + G::SendTemporalMessage ('ID_USER_INACTIVE_BY_DATE', "warning"); + break; + case -5: + G::SendTemporalMessage ('ID_AUTHENTICATION_SOURCE_INVALID', "warning"); + break; + } + $$sPwd= $pwd; + + //to avoid empty string in user field. This will avoid a weird message "this row doesn't exist" + if ( !isset($uid) ) { + $uid = -1; + G::SendTemporalMessage ('ID_USER_NOT_REGISTERED', "warning"); + } + + if ( !isset($uid) || $uid < 0 ) { + if(isset($_SESSION['FAILED_LOGINS'])) + $_SESSION['FAILED_LOGINS']++; + if (!defined('PPP_FAILED_LOGINS')) { + define('PPP_FAILED_LOGINS', 0); + } + if (PPP_FAILED_LOGINS > 0) { + if ($_SESSION['FAILED_LOGINS'] >= PPP_FAILED_LOGINS) { + $oConnection = Propel::getConnection('rbac'); + $oStatement = $oConnection->prepareStatement("SELECT USR_UID FROM USERS WHERE USR_USERNAME = '" . $usr . "'"); + $oDataset = $oStatement->executeQuery(); + if ($oDataset->next()) { + $sUserUID = $oDataset->getString('USR_UID'); + $oConnection = Propel::getConnection('rbac'); + $oStatement = $oConnection->prepareStatement("UPDATE USERS SET USR_STATUS = 0 WHERE USR_UID = '" . $sUserUID . "'"); + $oStatement->executeQuery(); + $oConnection = Propel::getConnection('workflow'); + $oStatement = $oConnection->prepareStatement("UPDATE USERS SET USR_STATUS = 'INACTIVE' WHERE USR_UID = '" . $sUserUID . "'"); + $oStatement->executeQuery(); + unset($_SESSION['FAILED_LOGINS']); + G::SendMessageText(G::LoadTranslation('ID_ACCOUNT') . ' "' . $usr . '" ' . G::LoadTranslation('ID_ACCOUNT_DISABLED_CONTACT_ADMIN'), 'warning'); + } + else { + //Nothing + } + } + } + G::header ("location: login.html"); + die; + } + if(!isset( $_SESSION['WORKSPACE'] ) ) $_SESSION['WORKSPACE'] = SYS_SYS; + + //Execute the SSO Script from plugin + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( $oPluginRegistry->existsTrigger ( PM_LOGIN ) ) { + $lSession=""; + $loginInfo = new loginInfo ($usr, $pwd, $lSession ); + $oPluginRegistry->executeTriggers ( PM_LOGIN , $loginInfo ); + } + + $_SESSION['USER_LOGGED'] = $uid; + $_SESSION['USR_USERNAME'] = $usr; + $aUser = $RBAC->userObj->load($_SESSION['USER_LOGGED']); + $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); + //$rol = $RBAC->rolesObj->load($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_UID']); + $_SESSION['USR_FULLNAME'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + //$_SESSION['USR_ROLENAME'] = $rol['ROL_NAME']; + + unset($_SESSION['FAILED_LOGINS']); + + // increment logins in heartbeat + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + $oServerConf->sucessfulLogin(); + + // Assign the uid of user to userloggedobj + $RBAC->loadUserRolePermission($RBAC->sSystem, $uid); + $res = $RBAC->userCanAccess('PM_LOGIN'); + if ($res != 1 ) { + if ($res == -2) + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); + else + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_PAGE', "error"); + G::header ("location: login.html"); + die; + } + + if (isset($frm['USER_LANG'])) { + if ($frm['USER_LANG'] != '') { + $lang = $frm['USER_LANG']; + } + } + else { + if (defined('SYS_LANG')) { + $lang = SYS_LANG; + } + else { + $lang = 'en'; + } + } + + /**log in table Login**/ + require_once 'classes/model/LoginLog.php'; + $weblog=new LoginLog(); + $aLog['LOG_UID'] = G::generateUniqueID(); + $aLog['LOG_STATUS'] = 'ACTIVE'; + $aLog['LOG_IP'] = $_SERVER['REMOTE_ADDR']; + $aLog['LOG_SID'] = session_id(); + $aLog['LOG_INIT_DATE'] = date('Y-m-d H:i:s'); + //$aLog['LOG_END_DATE'] = '0000-00-00 00:00:00'; + $aLog['LOG_CLIENT_HOSTNAME']= $_SERVER['HTTP_HOST']; + $aLog['USR_UID'] = $_SESSION['USER_LOGGED']; + $weblog->create($aLog); + /**end log**/ + +//************** background processes, here we are putting some back office routines ********** + $oServerConf->setWsInfo(SYS_SYS,$oServerConf->getWorkspaceInfo(SYS_SYS) ); + +//**** defining and saving server info, this file has the values of the global array $_SERVER **** +//this file is useful for command line environment (no Browser), I mean for triggers, crons and other executed over command line + + $_CSERVER = $_SERVER; + unset($_CSERVER['REQUEST_TIME']); + unset($_CSERVER['REMOTE_PORT']); + $cput = serialize($_CSERVER); + if( !is_file(PATH_DATA_SITE . PATH_SEP . '.server_info') ){ + file_put_contents(PATH_DATA_SITE . PATH_SEP . '.server_info', $cput); + } + else { + $c = file_get_contents(PATH_DATA_SITE . PATH_SEP . '.server_info'); + if(md5($c) != md5($cput)){ + file_put_contents(PATH_DATA_SITE . PATH_SEP . '.server_info', $cput); + } + } + + /* Check password using policy - Start */ + require_once 'classes/model/UsersProperties.php'; + $oUserProperty = new UsersProperties(); + $aUserProperty = $oUserProperty->loadOrCreateIfNotExists($_SESSION['USER_LOGGED'], array('USR_PASSWORD_HISTORY' => serialize(array(md5($currentPwd))))); + $aErrors = $oUserProperty->validatePassword($_POST['form']['USR_PASSWORD'], $aUserProperty['USR_LAST_UPDATE_DATE'], $aUserProperty['USR_LOGGED_NEXT_TIME']); + if (!empty($aErrors)) { + if (!defined('NO_DISPLAY_USERNAME')) { + define('NO_DISPLAY_USERNAME', 1); + } + $aFields = array(); + $aFields['DESCRIPTION'] = ''; + $aFields['DESCRIPTION'] .= G::LoadTranslation('ID_POLICY_ALERT').':

    '; + foreach ($aErrors as $sError) { + switch ($sError) { + case 'ID_PPP_MINIMUN_LENGTH': + $aFields['DESCRIPTION'] .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MINIMUN_LENGTH . '
    '; + $aFields[substr($sError, 3)] = PPP_MINIMUN_LENGTH; + break; + case 'ID_PPP_MAXIMUN_LENGTH': + $aFields['DESCRIPTION'] .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MAXIMUN_LENGTH . '
    '; + $aFields[substr($sError, 3)] = PPP_MAXIMUN_LENGTH; + break; + case 'ID_PPP_EXPIRATION_IN': + $aFields['DESCRIPTION'] .= ' - ' . G::LoadTranslation($sError).' ' . PPP_EXPIRATION_IN . ' ' . G::LoadTranslation('ID_DAYS') . '
    '; + $aFields[substr($sError, 3)] = PPP_EXPIRATION_IN; + break; + default: + $aFields['DESCRIPTION'] .= ' - ' . G::LoadTranslation($sError).'
    '; + $aFields[substr($sError, 3)] = 1; + break; + } + } + $aFields['DESCRIPTION'] .= '
    ' . G::LoadTranslation('ID_PLEASE_CHANGE_PASSWORD_POLICY') . '

    '; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/changePassword', '', $aFields, 'changePassword'); + G::RenderPage('publish'); + die; + } + /* Check password using policy - End */ + if ( isset($_POST['form']['URL']) && $_POST['form']['URL'] != '') { + $sLocation = $_POST['form']['URL']; + } + else { + $sLocation = $oUserProperty->redirectTo($_SESSION['USER_LOGGED'], $lang); + } + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->extJsInit = true; + + $oHeadPublisher->addExtJsScript('login/init', false); //adding a javascript file .js + $oHeadPublisher->assign('uriReq', $sLocation); + G::RenderPage('publish', 'extJs'); + //G::header('Location: ' . $sLocation); + die; + +} +catch ( Exception $e ) { + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; +} diff --git a/workflow/engine/methods/login/changePassword.php b/workflow/engine/methods/login/changePassword.php new file mode 100644 index 000000000..518a10fd1 --- /dev/null +++ b/workflow/engine/methods/login/changePassword.php @@ -0,0 +1,86 @@ +load($_SESSION['USER_LOGGED']); +global $RBAC; +$aData['USR_UID'] = $aUser['USR_UID']; +$aData['USR_USERNAME'] = $aUser['USR_USERNAME']; +$aData['USR_PASSWORD'] = md5($_POST['form']['USR_PASSWORD']); +$aData['USR_FIRSTNAME'] = $aUser['USR_FIRSTNAME']; +$aData['USR_LASTNAME'] = $aUser['USR_LASTNAME']; +$aData['USR_EMAIL'] = $aUser['USR_EMAIL']; +$aData['USR_DUE_DATE'] = $aUser['USR_DUE_DATE']; +$aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); +$RBAC->updateUser($aData, $aUser['USR_ROLE']); +$aData['USR_COUNTRY'] = $aUser['USR_COUNTRY']; +$aData['USR_CITY'] = $aUser['USR_CITY']; +$aData['USR_LOCATION'] = $aUser['USR_LOCATION']; +$aData['USR_ADDRESS'] = $aUser['USR_ADDRESS']; +$aData['USR_PHONE'] = $aUser['USR_PHONE']; +$aData['USR_ZIP_CODE'] = $aUser['USR_ZIP_CODE']; +$aData['USR_POSITION'] = $aUser['USR_POSITION']; +$oUser->update($aData); +require_once 'classes/model/UsersProperties.php'; +$oUserProperty = new UsersProperties(); +$aUserProperty = $oUserProperty->load($_SESSION['USER_LOGGED']); +$aHistory = unserialize($aUserProperty['USR_PASSWORD_HISTORY']); +if (!is_array($aHistory)) { + $aHistory = array(); +} +if (!defined('PPP_PASSWORD_HISTORY')) { + define('PPP_PASSWORD_HISTORY', 0); +} +if (PPP_PASSWORD_HISTORY > 0) { + if (count($aHistory) >= PPP_PASSWORD_HISTORY) { + array_shift($aHistory); + } + $aHistory[] = $_POST['form']['USR_PASSWORD']; +} +$aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s'); +$aUserProperty['USR_LOGGED_NEXT_TIME'] = 0; +$aUserProperty['USR_PASSWORD_HISTORY'] = serialize($aHistory); +$oUserProperty->update($aUserProperty); +if ( class_exists('redirectDetail')) { + //falta validar... + if(isset($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'])) + $userRole = $RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE']; + + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + //$oPluginRegistry->showArrays(); + $aRedirectLogin = $oPluginRegistry->getRedirectLogins(); + if(isset($aRedirectLogin)) + { if(is_array($aRedirectLogin)) + { + foreach ( $aRedirectLogin as $key=>$detail ) { + if(isset($detail->sPathMethod)) + { + if ( $detail->sRoleCode == $userRole ) { + G::header('location: /sys' . SYS_TEMP . '/' . SYS_LANG . '/' . SYS_SKIN . '/' . $detail->sPathMethod ); + die; + } + } + } + } + } +} +//end plugin + + + if (isset($frm['USER_LANG'])) { + if ($frm['USER_LANG'] != '') { + $lang = $frm['USER_LANG']; + } + } + else { + if (defined('SYS_LANG')) { + $lang = SYS_LANG; + } + else { + $lang = 'en'; + } + } + $sLocation = $oUserProperty->redirectTo($_SESSION['USER_LOGGED'], $lang); + G::header('Location: ' . $sLocation); + die; + +?> \ No newline at end of file diff --git a/workflow/engine/methods/login/dbInfo.php b/workflow/engine/methods/login/dbInfo.php new file mode 100644 index 000000000..e4da659bd --- /dev/null +++ b/workflow/engine/methods/login/dbInfo.php @@ -0,0 +1,126 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +function lookup( $target ) { + global $ntarget; + $msg = $target . ' => '; + //if (eregi ( '[a-zA-Z]', $target )) + if (preg_match( '[a-zA-Z]', $target )) + $ntarget = gethostbyname ( $target ); + else + $ntarget = gethostbyaddr ( $target ); + $msg .= $ntarget; + return ($msg); +} + +if (! defined ( 'PM_VERSION' )) { + if (file_exists ( PATH_METHODS . 'login/version-pmos.php' )) { + include (PATH_METHODS . 'login/version-pmos.php'); + } + else { + define ( 'PM_VERSION', 'Development Version' ); + } +} + +if (getenv ( 'HTTP_CLIENT_IP' )) { + $ip = getenv ( 'HTTP_CLIENT_IP' ); +} +else { + if (getenv ( 'HTTP_X_FORWARDED_FOR' )) { + $ip = getenv ( 'HTTP_X_FORWARDED_FOR' ); + } + else { + $ip = getenv ( 'REMOTE_ADDR' ); + } +} + +$redhat = ''; +if (file_exists ( '/etc/redhat-release' )) { + $fnewsize = filesize ( '/etc/redhat-release' ); + $fp = fopen ( '/etc/redhat-release', 'r' ); + $redhat = trim ( fread ( $fp, $fnewsize ) ); + fclose ( $fp ); +} + +$redhat .= " (" . PHP_OS . ")"; +if (defined ( "DB_HOST" )) { + G::LoadClass ( 'net' ); + G::LoadClass ( 'dbConnections' ); + $dbNetView = new NET ( DB_HOST ); + $dbNetView->loginDbServer ( DB_USER, DB_PASS ); + + $dbConns = new dbConnections ( '' ); + $availdb = ''; + foreach ( $dbConns->getDbServicesAvailables () as $key => $val ) { + if ($availdb != '') + $availdb .= ', '; + $availdb .= $val ['name']; + } + + try { + + $sMySQLVersion = $dbNetView->getDbServerVersion ( DB_ADAPTER ); + + } + catch ( Exception $oException ) { + $sMySQLVersion = '?????'; + } +} + +$Fields ['SYSTEM'] = $redhat; +if (defined ( "DB_HOST" )) { + $Fields ['DATABASE'] = $dbNetView->dbName ( DB_ADAPTER ) . ' (Version ' . $sMySQLVersion . ')'; + $Fields ['DATABASE_SERVER'] = DB_HOST; + $Fields ['DATABASE_NAME'] = DB_NAME; + $Fields ['AVAILABLE_DB'] = $availdb; +} +else { + $Fields ['DATABASE'] = "Not defined"; + $Fields ['DATABASE_SERVER'] = "Not defined"; + $Fields ['DATABASE_NAME'] = "Not defined"; + $Fields ['AVAILABLE_DB'] = "Not defined"; +} +$eeT=""; + if(class_exists('pmLicenseManager')){ + $eeT=" - Enterprise Edition"; + } +$Fields ['PHP'] = phpversion (); +$Fields ['FLUID'] = PM_VERSION.$eeT; +$Fields ['IP'] = lookup ( $ip ); +$Fields ['ENVIRONMENT'] = defined ( "SYS_SYS" ) ? SYS_SYS : "Not defined"; +$Fields ['SERVER_SOFTWARE'] = getenv ( 'SERVER_SOFTWARE' ); +$Fields ['SERVER_NAME'] = getenv ( 'SERVER_NAME' ); +$Fields ['SERVER_PROTOCOL'] = getenv ( 'SERVER_PROTOCOL' ); +$Fields ['SERVER_PORT'] = getenv ( 'SERVER_PORT' ); +$Fields ['REMOTE_HOST'] = getenv ( 'REMOTE_HOST' ); +$Fields ['SERVER_ADDR'] = getenv ( 'SERVER_ADDR' ); +$Fields ['HTTP_USER_AGENT'] = getenv ( 'HTTP_USER_AGENT' ); + +if (! defined ( 'SKIP_RENDER_SYSTEM_INFORMATION' )) { + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/dbInfo', '', $Fields, 'appNew2' ); + G::RenderPage ( 'publish', 'raw' ); +} \ No newline at end of file diff --git a/workflow/engine/methods/login/index.php b/workflow/engine/methods/login/index.php new file mode 100644 index 000000000..86dc1a932 --- /dev/null +++ b/workflow/engine/methods/login/index.php @@ -0,0 +1,28 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $newFile = str_replace ( 'index.php', 'login.php' , __FILE__ ) ; + return $newFile; + + \ No newline at end of file diff --git a/workflow/engine/methods/login/login.php b/workflow/engine/methods/login/login.php new file mode 100644 index 000000000..5cf063831 --- /dev/null +++ b/workflow/engine/methods/login/login.php @@ -0,0 +1,148 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if (! isset ( $_GET ['u'] )) { + $aFields ['URL'] = ''; + } + else { + $aFields ['URL'] = urldecode ( $_GET ['u'] ); + } + if (! isset ( $_SESSION ['G_MESSAGE'] )) { + $_SESSION ['G_MESSAGE'] = ''; + } + if (! isset ( $_SESSION ['G_MESSAGE_TYPE'] )) { + $_SESSION ['G_MESSAGE_TYPE'] = ''; + } + + $msg = $_SESSION ['G_MESSAGE']; + $msgType = $_SESSION ['G_MESSAGE_TYPE']; + + if (! isset ( $_SESSION ['FAILED_LOGINS'] )) { + $_SESSION ['FAILED_LOGINS'] = 0; + } + $sFailedLogins = $_SESSION ['FAILED_LOGINS']; + + require_once 'classes/model/LoginLog.php'; + + $aFields ['LOGIN_VERIFY_MSG'] = G::loadTranslation ( 'LOGIN_VERIFY_MSG' ); + + if ( isset ($_SESSION ['USER_LOGGED']) ) { + //close the session, if the current session_id was used in PM. + $oCriteria = new Criteria ( 'workflow' ); + $oCriteria->add ( LoginLogPeer::LOG_SID, session_id () ); + $oCriteria->add ( LoginLogPeer::USR_UID, isset ( $_SESSION ['USER_LOGGED'] ) ? $_SESSION ['USER_LOGGED'] : '-' ); + $oCriteria->add ( LoginLogPeer::LOG_STATUS, 'ACTIVE' ); + $oCriteria->add ( LoginLogPeer::LOG_END_DATE, NULL, Criteria::ISNULL ); + $oDataset = LoginLogPeer::doSelectRS ( $oCriteria ); + $oDataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $oDataset->next (); + $aRow = $oDataset->getRow (); + if ($aRow) { + if ($aRow ['LOG_STATUS'] != 'CLOSED' && $aRow ['LOG_END_DATE'] == NULL) { + $weblog = new LoginLog ( ); + $aLog ['LOG_UID'] = $aRow ['LOG_UID']; + $aLog ['LOG_STATUS'] = 'CLOSED'; + $aLog ['LOG_IP'] = $aRow ['LOG_IP']; + $aLog ['LOG_SID'] = session_id (); + $aLog ['LOG_INIT_DATE'] = $aRow ['LOG_INIT_DATE']; + $aLog ['LOG_END_DATE'] = date ( 'Y-m-d H:i:s' ); + $aLog ['LOG_CLIENT_HOSTNAME'] = $aRow ['LOG_CLIENT_HOSTNAME']; + $aLog ['USR_UID'] = $aRow ['USR_UID']; + $weblog->update ( $aLog ); + } + } + } + //end log + + //start new session + session_destroy (); + session_start (); + session_regenerate_id (); + + if (strlen ( $msg ) > 0) { + $_SESSION ['G_MESSAGE'] = $msg; + } + if (strlen ( $msgType ) > 0) { + $_SESSION ['G_MESSAGE_TYPE'] = $msgType; + } + $_SESSION ['FAILED_LOGINS'] = $sFailedLogins; + + //translation + require_once "classes/model/Translation.php"; + $translationsTable = Translation::getTranslationEnvironments(); + $availableLangArray = array (); + $availableLangArray [] = array ('LANG_ID' => 'char', 'LANG_NAME' => 'char' ); + foreach ( $translationsTable as $locale ) { + $row['LANG_ID'] = $locale['LOCALE']; + if( $locale['COUNTRY'] != '.' ) + $row['LANG_NAME'] = $locale['LANGUAGE'] . ' (' . (ucwords(strtolower($locale['COUNTRY']))) . ')'; + else + $row['LANG_NAME'] = $locale['LANGUAGE']; + + $availableLangArray [] = $row; + } + global $_DBArray; + $_DBArray ['langOptions'] = $availableLangArray; + + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/login', '', $aFields, SYS_URI . 'login/authentication.php' ); + G::LoadClass ( 'serverConfiguration' ); + + //get the serverconf singleton, and check if we can send the heartbeat + $oServerConf = & serverConf::getSingleton (); + + $sflag = $oServerConf->getHeartbeatProperty('HB_OPTION','HEART_BEAT_CONF'); + $sflag = (trim($sflag)!='')?$sflag:'1'; + + //get date of next beat + $nextBeatDate = $oServerConf->getHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + $sflag = 1; + //if flag to send heartbeat is enabled, and it is time to send heartbeat, sent it using asynchronous beat. + if( ($sflag=="1") && ((strtotime ( "now" ) > $nextBeatDate) || is_null($nextBeatDate) ) ){ + $oHeadPublisher =& headPublisher::getSingleton(); + //To do: we need to change to ExtJs + $oHeadPublisher->addScriptCode( 'var flagHeartBeat = 1; '); + } + else + $oHeadPublisher->addScriptCode( 'var flagHeartBeat = 0; '); + + //check if we show the panel with the getting started info + + require_once 'classes/model/Configuration.php'; + $oConfiguration = new Configuration ( ); + $oCriteria = new Criteria ( 'workflow' ); + $oCriteria->add ( ConfigurationPeer::CFG_UID, 'getStarted' ); + $oCriteria->add ( ConfigurationPeer::OBJ_UID, '' ); + $oCriteria->add ( ConfigurationPeer::CFG_VALUE, '1' ); + $oCriteria->add ( ConfigurationPeer::PRO_UID, '' ); + $oCriteria->add ( ConfigurationPeer::USR_UID, '' ); + $oCriteria->add ( ConfigurationPeer::APP_UID, '' ); + $flagGettingStarted = ConfigurationPeer::doCount ( $oCriteria ); + if( $flagGettingStarted == 0 ) { + $oHeadPublisher->addScriptCode( 'var flagGettingStarted = 1; '); + } + else + $oHeadPublisher->addScriptCode( 'var flagGettingStarted = 0; '); + + G::RenderPage ( "publish" ); diff --git a/workflow/engine/methods/login/login_Ajax.php b/workflow/engine/methods/login/login_Ajax.php new file mode 100644 index 000000000..b9ad4c349 --- /dev/null +++ b/workflow/engine/methods/login/login_Ajax.php @@ -0,0 +1,50 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + + G::LoadInclude ( 'ajax' ); + if (isset ( $_POST ['form'] )) { + $_POST = $_POST ['form']; + } + $_POST ['function'] = get_ajax_value ( 'function' ); + switch ($_POST ['function']) { + case 'getStarted_save' : + require_once 'classes/model/Configuration.php'; + $aData ['CFG_UID'] = 'getStarted'; + $aData ['OBJ_UID'] = ''; + $aData ['CFG_VALUE'] = '1'; + $aData ['PRO_UID'] = ''; + $aData ['USR_UID'] = ''; + $aData ['APP_UID'] = ''; + + $oConfig = new Configuration ( ); + + $oConfig->create ( $aData ); + break; + } +} +catch ( Exception $oException ) { + die ( $oException->getMessage () ); +} diff --git a/workflow/engine/methods/login/noViewPage.php b/workflow/engine/methods/login/noViewPage.php new file mode 100644 index 000000000..92323c55a --- /dev/null +++ b/workflow/engine/methods/login/noViewPage.php @@ -0,0 +1,36 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$G_MENU_SELECTED = 0; +$G_MAIN_MENU = "empty"; +$G_SUB_MENU = "empty"; + +$referer = $_SERVER ['HTTP_REFERER']; +$dbc = new DBConnection ( ); +$G_PUBLISH = new Publisher ( ); +$G_PUBLISH->AddContent ( "xmlform", "xmlform", "login/noViewPage", "", NULL ); + +G::RenderPage ( "publish" ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/login/sysLogin.php b/workflow/engine/methods/login/sysLogin.php new file mode 100644 index 000000000..9f9447308 --- /dev/null +++ b/workflow/engine/methods/login/sysLogin.php @@ -0,0 +1,162 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (isset ( $_POST ['form'] ['USER_ENV'] )) { + session_start (); + $_SESSION ['sysLogin'] = $_POST ['form']; + G::header ( 'location: /sys' . $_POST ['form'] ['USER_ENV'] . '/' . SYS_LANG . '/' . SYS_SKIN . '/login/sysLoginVerify' ); + die (); +} + +//Required classes for dbArray work +require_once ("propel/Propel.php"); +require_once ("creole/Creole.php"); +G::LoadThirdParty ( "pake", "pakeColor.class" ); +Propel::init ( PATH_CORE . "config/databases.php" ); +Creole::registerDriver ( 'dbarray', 'creole.contrib.DBArrayConnection' ); + +function getLangFiles() { + $dir = PATH_LANGUAGECONT; + $filesArray = array (); + if (file_exists ( $dir )) { + if ($handle = opendir ( $dir )) { + while ( false !== ($file = readdir ( $handle )) ) { + + $fileParts = explode ( ".", $file ); + if ($fileParts [0] == "translation") { + $filesArray [$fileParts [1]] = $file; + } + } + closedir ( $handle ); + } + } + return $filesArray; +} + +function getWorkspacesAvailable() { + G::LoadClass ( 'serverConfiguration' ); + $oServerConf = & serverConf::getSingleton (); + $dir = PATH_DB; + $filesArray = array (); + if (file_exists ( $dir )) { + if ($handle = opendir ( $dir )) { + while ( false !== ($file = readdir ( $handle )) ) { + if (($file != ".") && ($file != "..")) { + if (file_exists ( PATH_DB . $file . '/db.php' )) { + if (! $oServerConf->isWSDisabled ( $file )) + $filesArray [] = $file; + } + } + } + closedir ( $handle ); + } + } + sort ( $filesArray, SORT_STRING ); + return $filesArray; +} +$availableWorkspace = getWorkspacesAvailable (); + +require_once "classes/model/Translation.php"; + +$translationsTable = Translation::getTranslationEnvironments(); +//g::pr($translationsTable); die; +//$availableLang = getLangFiles (); + +$availableLangArray = array (); +$availableLangArray [] = array ('LANG_ID' => 'char', 'LANG_NAME' => 'char' ); + +foreach ( $translationsTable as $locale ) { + $aFields['LANG_ID'] = $locale['LOCALE']; + if( $locale['COUNTRY'] != '.' ) + $aFields['LANG_NAME'] = $locale['LANGUAGE'] . ' (' . (ucwords(strtolower($locale['COUNTRY']))) . ')'; + else + $aFields['LANG_NAME'] = $locale['LANGUAGE']; + + $availableLangArray [] = $aFields; +} + + +$availableWorkspaceArray = array (); +$availableWorkspaceArray [] = array ('ENV_ID' => 'char', 'ENV_NAME' => 'char' ); +foreach ( $availableWorkspace as $envKey => $envName ) { + $aFields = array ('ENV_ID' => $envName, 'ENV_NAME' => $envName ); + $availableWorkspaceArray [] = $aFields; +} + +global $_DBArray; + +$_DBArray ['langOptions'] = $availableLangArray; +$_DBArray ['availableWorkspace'] = $availableWorkspaceArray; + +$_SESSION ['_DBArray'] = $_DBArray; + +$aField ['LOGIN_VERIFY_MSG'] = G::loadTranslation ( 'LOGIN_VERIFY_MSG' ); +//Get Server Configuration +G::LoadClass ( 'serverConfiguration' ); +$oServerConf = & serverConf::getSingleton (); + +$G_PUBLISH = new Publisher ( ); +if ($oServerConf->getProperty ( 'LOGIN_NO_WS' )) { + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/sysLoginNoWS', '', $aField, 'sysLogin' ); +} +else { + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/sysLogin', '', $aField, 'sysLogin' ); +} + +G::RenderPage ( "publish" ); + + + +?> + \ No newline at end of file diff --git a/workflow/engine/methods/login/sysLoginVerify.php b/workflow/engine/methods/login/sysLoginVerify.php new file mode 100644 index 000000000..a49b41028 --- /dev/null +++ b/workflow/engine/methods/login/sysLoginVerify.php @@ -0,0 +1,31 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (! isset ( $_POST )) + G::header ( 'location: /sys/' . $lang . '/' . SYS_SKIN . '/' . 'login/login' ); + +if (isset ( $_SESSION ['sysLogin'] )) + $_POST ['form'] = $_SESSION ['sysLogin']; +require_once ('authentication.php'); \ No newline at end of file diff --git a/workflow/engine/methods/messages/messages_Delete.php b/workflow/engine/methods/messages/messages_Delete.php new file mode 100644 index 000000000..2375b4eab --- /dev/null +++ b/workflow/engine/methods/messages/messages_Delete.php @@ -0,0 +1,40 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('message'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $messages = new Message( $dbc ); + + if (!isset($_POST['MESS_UID'])) return; + + $messages->Delete( $_POST['MESS_UID'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/messages/messages_Edit.php b/workflow/engine/methods/messages/messages_Edit.php new file mode 100644 index 000000000..68e8a51a4 --- /dev/null +++ b/workflow/engine/methods/messages/messages_Edit.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('message'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $messages = new Message( $dbc ); + $messages->Fields['MESS_UID']=(isset($_GET['MESS_UID'])) ? urldecode($_GET['MESS_UID']):'0'; + $messages->Load( $messages->Fields['MESS_UID'] ); + $messages->Fields['PRO_UID'] = isset($messages->Fields['PRO_UID'])?$messages->Fields['PRO_UID']:$_GET['PRO_UID']; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'messages/messages_Edit', '', $messages->Fields , SYS_URI . 'messages/messages_Save'); + + G::RenderPage( "publish" , "raw" ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/messages/messages_List.php b/workflow/engine/methods/messages/messages_List.php new file mode 100644 index 000000000..6fb697513 --- /dev/null +++ b/workflow/engine/methods/messages/messages_List.php @@ -0,0 +1,47 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'MESSAGES'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //Hardcode: UID of the library by default + $PRO_UID='746B734DC23311'; + $G_PUBLISH = new Publisher; + $Fields=array( 'SYS_LANG' => SYS_LANG, + 'PRO_UID' => $PRO_UID ); + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'messages/messages_List', '', $Fields , 'messages_Save'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/messages/messages_Save.php b/workflow/engine/methods/messages/messages_Save.php new file mode 100644 index 000000000..2dc0864b3 --- /dev/null +++ b/workflow/engine/methods/messages/messages_Save.php @@ -0,0 +1,39 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('message'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $messages = new Message( $dbc ); + + if ($_POST['form']['MESS_UID']==='') unset($_POST['form']['MESS_UID']); + $messages->Save( $_POST['form'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/outputdocs/downloadFile.php b/workflow/engine/methods/outputdocs/downloadFile.php new file mode 100644 index 000000000..d2d493c2f --- /dev/null +++ b/workflow/engine/methods/outputdocs/downloadFile.php @@ -0,0 +1,15 @@ +load($uid); + $type = $aFields['OUT_DOC_TYPE']; + + if ( $type == 'JRXML') $extension = 'jrxml'; + if ( $type == 'ACROFORM') $extension = 'pdf'; + + $fileJrxml = PATH_DYNAFORM . $aFields['PRO_UID'] . PATH_SEP . $aFields['OUT_DOC_UID'] . '.' . $extension ; + + $bDownload = true; + $downFileName = ereg_replace('[^A-Za-z0-9_]', '_', $aFields['OUT_DOC_TITLE'] ) . '.' . $extension; + G::streamFile ( $fileJrxml, $bDownload, $downFileName ); diff --git a/workflow/engine/methods/outputdocs/outputdocs_Ajax.php b/workflow/engine/methods/outputdocs/outputdocs_Ajax.php new file mode 100644 index 000000000..08aa4ccba --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_Ajax.php @@ -0,0 +1,39 @@ +success = true; + $result->msg = 'success - saved '. $_SESSION['outpudocs_tmpFile']; + echo G::json_encode($result); + break; + + case 'getTemplateFile': + $aExtensions = array ( "exe", "com", "dll", "ocx", "fon", "ttf", "doc", "xls", "mdb", "rtf", + "jpeg", "jpg", "jif", "jfif", "gif", "tif", "tiff", "png", "bmp", "pdf", + "aac", "mp3", "mp3pro", "vorbis", "realaudio", "vqf", "wma", + "aiff", "flac", "wav", "midi", "mka", "ogg", "jpeg", "ilbm", + "tar", "zip", "rar", "arj", "gzip", "bzip2", "afio", "kgb", + "asf", "avi", "mov", "iff", "ogg", "ogm", "mkv", "3gp" ); + $sFileName = strtolower($_SESSION['outpudocs_tmpFile']); + $sExtension = substr($sFileName, strpos($sFileName,'.') + 1, strlen($sFileName)); + if(! in_array($sExtension, $aExtensions)) + echo $content = file_get_contents($_SESSION['outpudocs_tmpFile']); + break; + + case 'loadTemplateContent': + require_once 'classes/model/OutputDocument.php'; + $ooutputDocument = new OutputDocument(); + if (isset($_POST['OUT_DOC_UID'])) { + $aFields = $ooutputDocument->load($_POST['OUT_DOC_UID']); + + echo $aFields['OUT_DOC_TEMPLATE']; + } + break; +} diff --git a/workflow/engine/methods/outputdocs/outputdocs_Delete.php b/workflow/engine/methods/outputdocs/outputdocs_Delete.php new file mode 100644 index 000000000..a7b6ad035 --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_Delete.php @@ -0,0 +1,62 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/OutputDocument.php'; + require_once 'classes/model/ObjectPermission.php'; + require_once 'classes/model/Step.php'; + G::LoadClass( 'processMap' ); + + $oOutputDocument = new OutputDocument(); + $fields = $oOutputDocument->load($_POST['OUT_DOC_UID']); + $oOutputDocument->remove($_POST['OUT_DOC_UID']); + + $oStep = new Step(); + $oStep->removeStep('OUTPUT_DOCUMENT', $_POST['OUT_DOC_UID']); + + $oOP = new ObjectPermission(); + $oOP->removeByObject('OUTPUT', $_POST['OUT_DOC_UID']); + + //refresh dbarray with the last change in outputDocument + $oMap = new processMap(); + $oCriteria = $oMap->getOutputDocumentsCriteria($fields['PRO_UID'] ); + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/outputdocs/outputdocs_Edit.php b/workflow/engine/methods/outputdocs/outputdocs_Edit.php new file mode 100644 index 000000000..118e4d69c --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_Edit.php @@ -0,0 +1,103 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + require_once 'classes/model/OutputDocument.php'; + $ooutputDocument = new OutputDocument(); + if (isset($_GET['OUT_DOC_UID'])) { + $aFields = $ooutputDocument->load($_GET['OUT_DOC_UID']); + } + else { + $aFields = array(); + $aFields['PRO_UID'] = $_GET['PRO_UID']; + } + + require_once 'classes/model/OutputDocument.php'; + $ooutputDocument = new OutputDocument(); + if (isset($_GET['OUT_DOC_UID'])) { + $aFields = $ooutputDocument->load($_GET['OUT_DOC_UID']); + } + else { + $aFields = array(); + $aFields['PRO_UID'] = $_GET['PRO_UID']; + } + + $type = isset ( $aFields['OUT_DOC_TYPE']) ? $aFields['OUT_DOC_TYPE'] : 'HTML'; + + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + + switch ( $type ) { + case 'HTML' : + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocs_Edit', '', $aFields , '../outputdocs/outputdocs_Save'); + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->assign('OUT_DOC_UID', $_GET['OUT_DOC_UID']); + $translations = G::getTranslations(Array( + 'ID_FILE', 'ID_OUT_PUT_DOC_UPLOAD_TITLE', 'ID_UPLOADING_FILE', 'ID_UPLOAD', 'ID_CANCEL', + 'ID_SAVE', 'ID_LOAD_FROM_FILE', 'ID_SELECT_TEMPLATE_FILE', 'ID_ALERT_MESSAGE', 'ID_INVALID_FILE' + )); + $oHeadPublisher->assign('TRANSLATIONS', $translations); + $oHeadPublisher->addExtJsScript('outputdocs/htmlEditor', false ); //adding a javascript file .js + G::RenderPage('publish', 'extJs'); + die; + break; + + case 'JRXML' : + case 'ACROFORM' : + $type = $aFields['OUT_DOC_TYPE']; + if ( $type == 'JRXML') $extension = 'jrxml'; + if ( $type == 'ACROFORM') $extension = 'pdf'; + + $downFileName = ereg_replace('[^A-Za-z0-9_]', '_', $aFields['OUT_DOC_TITLE'] ) . '.' . $extension; + $filename = PATH_DYNAFORM . $aFields['PRO_UID'] . PATH_SEP . $aFields['OUT_DOC_UID'] . '.' . $extension ; + if ( file_exists ( $filename) ) + $aFields['FILENAME'] = $downFileName; + else + $aFields['FILENAME'] = ''; + + $aFields['FILELINK'] = '../outputdocs/downloadFile?' . $aFields['OUT_DOC_UID']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocsUploadFile', '', $aFields , '../outputdocs/uploadFile'); + $G_PUBLISH->AddContent('view', 'outputdocs/editJrxml' ); + break; + } + G::RenderPage('publish', 'raw'); + +} +catch (Exception $oException) { + die($oException->getMessage()); +} diff --git a/workflow/engine/methods/outputdocs/outputdocs_List.php b/workflow/engine/methods/outputdocs/outputdocs_List.php new file mode 100644 index 000000000..d5265a3c3 --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_List.php @@ -0,0 +1,45 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = 'OUTPUTDOCS'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + $G_PUBLISH = new Publisher; + $Fields=array( 'SYS_LANG' => SYS_LANG, + ); + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'outputdocs/outputdocs_List', '', $Fields , 'outputdocs_Save'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/outputdocs/outputdocs_New.php b/workflow/engine/methods/outputdocs/outputdocs_New.php new file mode 100644 index 000000000..07e55b64b --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_New.php @@ -0,0 +1,82 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/OutputDocument.php'; + $ooutputDocument = new OutputDocument(); + if (isset($_GET['OUT_DOC_UID'])) { + $aFields = $ooutputDocument->load($_GET['OUT_DOC_UID']); + } + else { + $aFields = array(); + $aFields['PRO_UID'] = $_GET['PRO_UID']; + } + $aFields['OUT_DOC_TYPE'] = 'HTML'; + + + $enabledJavaBridge = false; + G::LoadClass ('javaBridgePM'); + if ( class_exists ( 'javaBridgePM' ) ) { + $JBPM = new JavaBridgePM(); + try { + $JBPM->checkJavaExtension(); + $util = new Java("com.processmaker.util.pmutils"); + $enabledJavaBridge = true; + } catch ( Exception $e ) { + + } + //$util->setInputPath( JAVATEST_PATH ); + //$util->setOutputPath( JAVATEST_PATH ); + } + + + + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + if ( ! $enabledJavaBridge ) { + $xmlform = 'outputdocs/outputdocs_Properties'; + $G_PUBLISH->AddContent('xmlform', 'xmlform', $xmlform, '', $aFields , '../outputdocs/outputdocs_Save'); + } + else { + $xmlform = 'outputdocs/outputdocs_New'; + $G_PUBLISH->AddContent('xmlform', 'xmlform', $xmlform, '', $aFields , '../outputdocs/outputdocs_Save'); + } + G::RenderPage('publish', 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} diff --git a/workflow/engine/methods/outputdocs/outputdocs_Properties.php b/workflow/engine/methods/outputdocs/outputdocs_Properties.php new file mode 100644 index 000000000..7bac49142 --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_Properties.php @@ -0,0 +1,82 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + require_once 'classes/model/OutputDocument.php'; + $ooutputDocument = new OutputDocument(); + if (isset($_GET['OUT_DOC_UID'])) { + $aFields = $ooutputDocument->load($_GET['OUT_DOC_UID']); + } + else { + $aFields = array(); + $aFields['PRO_UID'] = $_GET['PRO_UID']; + } + + $type = isset ( $aFields['OUT_DOC_TYPE']) ? $aFields['OUT_DOC_TYPE'] : 'HTML'; + + $aFields['OUT_DOC_TAGS'] = isset ( $aFields['OUT_DOC_TAGS']) ? $aFields['OUT_DOC_TAGS'] : 'OUTPUT'; + $aFields['OUT_DOC_VERSIONING'] = strval($aFields['OUT_DOC_VERSIONING']); + $aFields['OUT_DOC_LANDSCAPE'] = strval($aFields['OUT_DOC_LANDSCAPE']); + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + switch ( $type ) { + case 'HTML' : + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocs_Properties', '', $aFields , '../outputdocs/outputdocs_Save'); + break; + case 'JRXML' : + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocs_Properties', '', $aFields , '../outputdocs/outputdocs_Save'); +/* +// $G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocsDynaformList', '', $aFields , '../outputdocs/outputdocs_Save'); + require_once 'classes/model/Process.php'; + G::LoadClass( 'processMap'); + $sProcessUID = $aFields['PRO_UID']; + $oProcess = new Process(); + $oProcessMap = new ProcessMap(); + $aFields = $oProcess->load($sProcessUID); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'dynaforms/dynaforms_ShortList', $oProcessMap->getDynaformsCriteria($sProcessUID), $aFields); +*/ + break; + case 'ACROFORM' : + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'outputdocs/outputdocs_Properties', '', $aFields , '../outputdocs/outputdocs_Save'); + break; + } + G::RenderPage('publish', 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} diff --git a/workflow/engine/methods/outputdocs/outputdocs_Save.php b/workflow/engine/methods/outputdocs/outputdocs_Save.php new file mode 100644 index 000000000..c6a0c7a00 --- /dev/null +++ b/workflow/engine/methods/outputdocs/outputdocs_Save.php @@ -0,0 +1,110 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + + //$sfunction =$_POST['function']; + + if(isset($_POST['function']) && $_POST['function']=='lookForNameOutput'){ + + require_once('classes/model/Content.php'); + require_once ( "classes/model/OutputDocument.php" ); + + $snameInput=urldecode($_POST['NAMEOUTPUT']); + $sPRO_UID=urldecode($_POST['proUid']); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn ( OutputDocumentPeer::OUT_DOC_UID ); + $oCriteria->add(OutputDocumentPeer::PRO_UID, $sPRO_UID); + $oDataset = OutputDocumentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $flag=true; + while ($oDataset->next() && $flag) { + $aRow = $oDataset->getRow(); + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->addSelectColumn('COUNT(*) AS OUTPUTS'); + $oCriteria1->add(ContentPeer::CON_CATEGORY, 'OUT_DOC_TITLE'); + $oCriteria1->add(ContentPeer::CON_ID, $aRow['OUT_DOC_UID']); + $oCriteria1->add(ContentPeer::CON_VALUE, $snameInput); + $oCriteria1->add(ContentPeer::CON_LANG, SYS_LANG); + $oDataset1 = ContentPeer::doSelectRS($oCriteria1); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aRow1 = $oDataset1->getRow(); + + if($aRow1['OUTPUTS'])$flag=false; + } + print $flag; + + } else { + //default: + + require_once 'classes/model/OutputDocument.php'; + G::LoadClass( 'processMap' ); + + $oOutputDocument = new OutputDocument(); + + if ($_POST['form']['OUT_DOC_UID'] == '') { + if ((isset($_POST['form']['OUT_DOC_TYPE']))&&( $_POST['form']['OUT_DOC_TYPE'] == 'JRXML' )) { + $dynaformUid = $_POST['form']['DYN_UID']; + + $outDocUid = $oOutputDocument->create($_POST['form']); + G::LoadClass ('javaBridgePM'); + $jbpm = new JavaBridgePM (); + print $jbpm->generateJrxmlFromDynaform ( $outDocUid, $dynaformUid, 'classic' ); + + } + else { + $outDocUid = $oOutputDocument->create($_POST['form']); + } + } + else { + $oOutputDocument->update($_POST['form']); + } + + if( isset($_POST['form']['PRO_UID']) ){ + //refresh dbarray with the last change in outputDocument + $oMap = new processMap(); + $oCriteria = $oMap->getOutputDocumentsCriteria($_POST['form']['PRO_UID']); + } + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} diff --git a/workflow/engine/methods/outputdocs/uploadFile.php b/workflow/engine/methods/outputdocs/uploadFile.php new file mode 100644 index 000000000..0a43144a2 --- /dev/null +++ b/workflow/engine/methods/outputdocs/uploadFile.php @@ -0,0 +1,32 @@ +load($uid); + $type = $aFields['OUT_DOC_TYPE']; + + $aExtension = explode ('.', strtolower(basename( $_FILES['form']['name']['OUT_DOC_FILE'] ))); + $extension = $aExtension[ count($aExtension) -1 ]; + if ( $extension != 'jrxml' && $type == 'JRXML') + throw ( new Exception ( "'$extension' is not a valid extension, you must upload a .jrxml file." ) ); + + if ( $extension != 'pdf' && $type == 'ACROFORM') + throw ( new Exception ( "'$extension' is not a valid extension, you must upload a .pdf file." ) ); + + $fileJrxml = PATH_DYNAFORM . $aFields['PRO_UID'] . PATH_SEP . $aFields['OUT_DOC_UID'] . '.' . $extension; + if (!empty($_FILES['form'])) { + if ($_FILES['form']['error']['OUT_DOC_FILE'] == 0) { + G::uploadFile($_FILES['form']['tmp_name']['OUT_DOC_FILE'], dirname($fileJrxml), basename($fileJrxml) ); + } + } + print "File uploaded."; + +} +catch ( Exception $e ) { + print "Error: " . $e->getMessage() . ""; +} \ No newline at end of file diff --git a/workflow/engine/methods/patterns/patterns_Ajax.php b/workflow/engine/methods/patterns/patterns_Ajax.php new file mode 100644 index 000000000..1a54fa392 --- /dev/null +++ b/workflow/engine/methods/patterns/patterns_Ajax.php @@ -0,0 +1,123 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadInclude('ajax'); +$aData = urldecode_values($_POST['form']); +switch ($aData['action']) { + case 'savePattern': + G::LoadClass('tasks'); + $oTasks = new Tasks(); + //if ($aData['ROU_TYPE'] != $aData['ROU_TYPE_OLD']) + //{ + $oTasks->deleteAllRoutesOfTask($aData['PROCESS'], $aData['TASK']); + //} + require_once 'classes/model/Route.php'; + $oRoute = new Route(); + switch ($aData['ROU_TYPE']) { + case 'SEQUENTIAL': + case 'SEC-JOIN': + /*if ($aData['ROU_UID'] != '') + { + $aFields['ROU_UID'] = $aData['ROU_UID']; + }*/ + $aFields['PRO_UID'] = $aData['PROCESS']; + $aFields['TAS_UID'] = $aData['TASK']; + $aFields['ROU_NEXT_TASK'] = $aData['ROU_NEXT_TASK']; + $aFields['ROU_TYPE'] = $aData['ROU_TYPE']; + //$aFields['ROU_TO_LAST_USER'] = $aData['ROU_TO_LAST_USER']; + $oRoute->create($aFields); + break; + case 'SELECT': + foreach ($aData['GRID_SELECT_TYPE'] as $iKey => $aRow) + { + /*if ($aRow['ROU_UID'] != '') + { + $aFields['ROU_UID'] = $aRow['ROU_UID']; + }*/ + $aFields['PRO_UID'] = $aData['PROCESS']; + $aFields['TAS_UID'] = $aData['TASK']; + $aFields['ROU_NEXT_TASK'] = $aRow['ROU_NEXT_TASK']; + $aFields['ROU_CASE'] = $iKey; + $aFields['ROU_TYPE'] = $aData['ROU_TYPE']; + $aFields['ROU_CONDITION'] = $aRow['ROU_CONDITION']; + //$aFields['ROU_TO_LAST_USER'] = $aRow['ROU_TO_LAST_USER']; + $oRoute->create($aFields); + unset($aFields); + } + break; + case 'EVALUATE': + foreach ($aData['GRID_EVALUATE_TYPE'] as $iKey => $aRow) + { + /*if ($aRow['ROU_UID'] != '') + { + $aFields['ROU_UID'] = $aRow['ROU_UID']; + }*/ + $aFields['PRO_UID'] = $aData['PROCESS']; + $aFields['TAS_UID'] = $aData['TASK']; + $aFields['ROU_NEXT_TASK'] = $aRow['ROU_NEXT_TASK']; + $aFields['ROU_CASE'] = $iKey; + $aFields['ROU_TYPE'] = $aData['ROU_TYPE']; + $aFields['ROU_CONDITION'] = $aRow['ROU_CONDITION']; + //$aFields['ROU_TO_LAST_USER'] = $aRow['ROU_TO_LAST_USER']; + $oRoute->create($aFields); + unset($aFields); + } + break; + case 'PARALLEL': + foreach ($aData['GRID_PARALLEL_TYPE'] as $iKey => $aRow) + { + /*if ($aRow['ROU_UID'] != '') + { + $aFields['ROU_UID'] = $aRow['ROU_UID']; + }*/ + $aFields['PRO_UID'] = $aData['PROCESS']; + $aFields['TAS_UID'] = $aData['TASK']; + $aFields['ROU_NEXT_TASK'] = $aRow['ROU_NEXT_TASK']; + $aFields['ROU_CASE'] = $iKey; + $aFields['ROU_TYPE'] = $aData['ROU_TYPE']; + $oRoute->create($aFields); + unset($aFields); + } + break; + case 'PARALLEL-BY-EVALUATION': + foreach ($aData['GRID_PARALLEL_EVALUATION_TYPE'] as $iKey => $aRow) + { + /*if ($aRow['ROU_UID'] != '') + { + $aFields['ROU_UID'] = $aRow['ROU_UID']; + }*/ + $aFields['PRO_UID'] = $aData['PROCESS']; + $aFields['TAS_UID'] = $aData['TASK']; + $aFields['ROU_NEXT_TASK'] = $aRow['ROU_NEXT_TASK']; + $aFields['ROU_CASE'] = $iKey; + $aFields['ROU_TYPE'] = $aData['ROU_TYPE']; + $aFields['ROU_CONDITION'] = $aRow['ROU_CONDITION']; + $oRoute->create($aFields); + unset($aFields); + } + break; + } + break; +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/processCategory/processCategoryAjax.php b/workflow/engine/methods/processCategory/processCategoryAjax.php new file mode 100644 index 000000000..18287453f --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryAjax.php @@ -0,0 +1,47 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +if(isset($_POST['function'])) { + + switch($_POST['function']) { + + case 'checkCategoryName': + + $CategoryName = $_POST['CategoryName']; + require_once ( "classes/model/ProcessCategory.php" ); + $processCategory = new ProcessCategory(); + $aProcessCategory = $processCategory->loadByCategoryName($CategoryName); + if( is_array($aProcessCategory)) { + return print '1'; + } else { + return print '0'; + } + break; + + default: echo 'default'; + } + +} diff --git a/workflow/engine/methods/processCategory/processCategoryDelete.php b/workflow/engine/methods/processCategory/processCategoryDelete.php new file mode 100755 index 000000000..10333a065 --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryDelete.php @@ -0,0 +1,41 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + //to do: improve the way to pass two or more parameters in the paged-table ( link ) + + $aux = explode ( '|', $_GET['id'] ); + $index=0; + $CategoryUid = str_replace ( '"', '', $aux[$index++] ); + + + require_once ( "classes/model/ProcessCategory.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = ProcessCategoryPeer::retrieveByPK( $CategoryUid ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'ProcessCategory' ) ) { + $fields['CATEGORY_UID'] = $tr->getCategoryUid(); + $fields['LABEL_CATEGORY_UID'] = $tr->getCategoryUid(); + $fields['CATEGORY_PARENT'] = $tr->getCategoryParent(); + $fields['LABEL_CATEGORY_PARENT'] = $tr->getCategoryParent(); + $fields['CATEGORY_NAME'] = $tr->getCategoryName(); + $fields['LABEL_CATEGORY_NAME'] = $tr->getCategoryName(); + $fields['CATEGORY_ICON'] = $tr->getCategoryIcon(); + $fields['LABEL_CATEGORY_ICON'] = $tr->getCategoryIcon(); + } + else + $fields = array(); + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'processCategory'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processCategory/processCategoryDelete', '', $fields, 'processCategoryDeleteExec' ); + G::RenderPage('publishBlank', 'blank'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/processCategory/processCategoryDeleteExec.php b/workflow/engine/methods/processCategory/processCategoryDeleteExec.php new file mode 100755 index 000000000..a725f652d --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryDeleteExec.php @@ -0,0 +1,46 @@ + userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + try { + + $form = $_POST['form']; + $CategoryUid = $form['CATEGORY_UID']; + require_once ( "classes/model/ProcessCategory.php" ); + + require_once 'classes/model/Process.php'; + + //we'are looking for data into process with this CategoryUid + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ProcessPeer::PRO_CATEGORY, $CategoryUid); + $oDataset = ProcessPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + while ($oDataset->next()) { + $aDataProcess = $oDataset->getRow(); + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(ProcessPeer::PRO_CATEGORY, ''); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(ProcessPeer::PRO_UID, $aDataProcess['PRO_UID']); + BasePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + + } + + //if exists the row in the database propel will update it, otherwise will insert. + $tr = ProcessCategoryPeer::retrieveByPK( $CategoryUid ); + if ( ( is_object ( $tr ) && get_class ($tr) == 'ProcessCategory' ) ) { + $tr->delete(); + } + + G::Header('location: processCategoryList'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/processCategory/processCategoryEdit.php b/workflow/engine/methods/processCategory/processCategoryEdit.php new file mode 100755 index 000000000..db668a7f2 --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryEdit.php @@ -0,0 +1,35 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + $aux = explode ( '|', isset($_GET['id']) ? $_GET['id'] : '' ); + $CategoryUid = str_replace ( '"', '', $aux[0] ); + + + require_once ( "classes/model/ProcessCategory.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = ProcessCategoryPeer::retrieveByPK( $CategoryUid ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'ProcessCategory' ) ) { + $fields['CATEGORY_UID'] = $tr->getCategoryUid(); + $fields['CATEGORY_PARENT'] = $tr->getCategoryParent(); + $fields['CATEGORY_NAME'] = $tr->getCategoryName(); + $fields['CATEGORY_ICON'] = $tr->getCategoryIcon(); + } + else + $fields = array(); + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'processCategory'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processCategory/processCategoryEdit', '', $fields, 'processCategorySave' ); + G::RenderPage('publishBlank', 'blank'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/processCategory/processCategoryList.php b/workflow/engine/methods/processCategory/processCategoryList.php new file mode 100755 index 000000000..dfa3c3f63 --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryList.php @@ -0,0 +1,40 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('krlos', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + try { + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'processCategory'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + $G_PUBLISH = new Publisher; + + + require_once ( "classes/model/ProcessCategory.php" ); + + $Criteria = new Criteria('workflow'); + $Criteria->clearSelectColumns ( ); + + $Criteria->addSelectColumn ( ProcessCategoryPeer::CATEGORY_UID ); + $Criteria->addSelectColumn ( ProcessCategoryPeer::CATEGORY_PARENT ); + $Criteria->addSelectColumn ( ProcessCategoryPeer::CATEGORY_NAME ); + $Criteria->addSelectColumn ( ProcessCategoryPeer::CATEGORY_ICON ); + + $Criteria->add ( processCategoryPeer::CATEGORY_UID, "xx" , CRITERIA::NOT_EQUAL ); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processCategory/processCategoryList', $Criteria , array(),''); + G::RenderPage('publishBlank', 'blank'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publishBlank', 'blank' ); + } diff --git a/workflow/engine/methods/processCategory/processCategoryNew.php b/workflow/engine/methods/processCategory/processCategoryNew.php new file mode 100755 index 000000000..93d02b78e --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategoryNew.php @@ -0,0 +1,27 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + require_once ( "classes/model/ProcessCategory.php" ); + + + $fields['CATEGORY_UID'] = G::GenerateUniqueID();; + + $fields['CATEGORY_PARENT'] = ''; + $fields['CATEGORY_NAME'] = ''; + $fields['CATEGORY_ICON'] = ''; + + $G_MAIN_MENU = 'workflow'; + $G_SUB_MENU = 'processCategory'; + $G_ID_MENU_SELECTED = ''; + $G_ID_SUB_MENU_SELECTED = ''; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processCategory/processCategoryEdit', '', $fields, 'processCategorySave' ); + G::RenderPage('publishBlank', 'blank'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/processCategory/processCategorySave.php b/workflow/engine/methods/processCategory/processCategorySave.php new file mode 100755 index 000000000..255b59d00 --- /dev/null +++ b/workflow/engine/methods/processCategory/processCategorySave.php @@ -0,0 +1,59 @@ + loadByCategoryName($CategoryName); + if(! is_array($aProcessCategory)) { + + if ( ! ( is_object ( $tr ) && get_class ($tr) == 'ProcessCategory' ) ) { + $tr = new ProcessCategory(); + } + $tr->setCategoryUid( $CategoryUid ); + $tr->setCategoryParent( $CategoryParent ); + $tr->setCategoryName( $CategoryName ); + $tr->setCategoryIcon( $CategoryIcon ); + + if ($tr->validate() ) { + // we save it, since we get no validation errors, or do whatever else you like. + $res = $tr->save(); + } + else { + // Something went wrong. We can now get the validationFailures and handle them. + $msg = ''; + $validationFailuresArray = $tr->getValidationFailures(); + foreach($validationFailuresArray as $objValidationFailure) { + $msg .= $objValidationFailure->getMessage() . "
    "; + } + //return array ( 'codError' => -100, 'rowsAffected' => 0, 'message' => $msg ); + } + //return array ( 'codError' => 0, 'rowsAffected' => $res, 'message' => ''); + + //to do: uniform coderror structures for all classes + + //if ( $res['codError'] < 0 ) { + // G::SendMessageText ( $res['message'] , 'error' ); + //} + G::Header('location: processCategoryList'); + } else { + // G::SendTemporalMessage("El registro ya existe", "warning", 'labels'); + G::Header('location: processCategoryList'); + die; + + } + } catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/processes/clases_Test.php b/workflow/engine/methods/processes/clases_Test.php new file mode 100644 index 000000000..3077414d7 --- /dev/null +++ b/workflow/engine/methods/processes/clases_Test.php @@ -0,0 +1,163 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + G::LoadClass( "derivation" ); + + $dbc = new DBConnection; + $obj = new Derivation; + +/* derivando el primer caso */ + + $frm['APP_UID'] ='44706CAEA62AE0'; + $frm['DEL_INDEX'] ='1'; + $obj->executeDerivation($frm); + die; + +/* derivando el primer caso */ + +/* CREANDO UN NUEVO CASO */ +/* + $frm['TAS_UID'] ='246F2CD0D4C79E'; + $frm['USER_UID'] ='00000000000000000000000000000001'; + $obj->startCase($frm); + die; + +*/ +/* CREANDO UN NUEVO CASO END */ + /** Application */ + + //$frm['PRO_UID'] ='ssddsfse32dd23s'; +/* $frm['APP_PARENT'] ='135165FDS54654FD'; + $frm['PRO_UID'] ='SSDDSFSE32DD23S'; + $frm['APP_STATUS'] ='DRAFT'; + $frm['APP_PROC_STATUS']='TEST'; + $frm['APP_PARALLEL']='NO'; + $frm['APP_TITLE']='MAUI'; +*/ + + + + +/* $translation2 = $obj->generateFileTranslation(); + print_r($translation2);*/ + + + + /*step */ + /*$frm['TAS_UID'] ='sss'; + $frm['STEP_NAME_OBJ'] ='DYNA'; +*/ + /*ReqDynaform */ +/* $frm['REQ_DYN_TITLE'] ='sss'; + $frm['REQ_DYN_DESCRIPTION'] ='eee'; + $frm['REQ_DYN_FILENAME'] ='33'; + $frm['REQ_DYN_UID']='346BB3D981FD9E';*/ + + + + /*ReqDocument */ +/* $frm['REQ_DOC_TITLE'] ='titulosssss'; + $frm['REQ_DOC_DESCRIPTION'] ='descripcions'; + //$frm['REQ_DOC_ORIGINAL'] ='1'; + $frm['REQ_DOC_UID']='646BB2F6BB2037'; +*/ + /*Task*/ + /*$frm['TAS_UID']='846BB16A0D9C7A'; + $frm['PRO_UID']='746B67A9CC9A0E'; + //$frm['TAS_TYPE'] ='332'; + $frm['TAS_TITLE'] ='titulito MAUI13ss'; + $frm['TAS_DESCRIPTION'] ='Descripción MAUI13'; + $frm['TAS_DEF_TITLE'] = "13"; + $frm['TAS_DEF_DESCRIPTION'] = "23"; + $frm['TAS_DEF_PROC_CODE'] = "33"; + $frm['TAS_DEF_MESSAGE'] = "43";*/ + + /** SwimlanesElements*/ +/* + $frm['PRO_UID'] ='ssddsfse32dd23s'; + $frm['SWI_TEXT'] ='maui'; + $frm['SWI_TYPE'] ='TEXT'; + $frm['SWI_X'] ='2'; + $frm['SWI_UID']='746BB217D7805E'; + +*/ + /** Route */ +/* + $frm['PRO_UID'] ='ssddsfse32dd23s'; + $frm['TAS_UID'] ='cooo'; + $frm['ROU_NEXT_TASK'] ='654FD65S4F65SD'; + $frm['ROU_SOURCEANCHOR'] ='2'; + $frm['ROU_UID']='746BB8411A9C14'; +*/ + + + + /*PROCESS*/ + /*$frm['PRO_UID'] = '446BB1B36E17FE'; + $frm['PRO_TITLE'] = 'PERDERD'; + $frm['PRO_PARENT']='746B67A9CC9ADDDDDDDD0E';*/ + + /** END PROCESS*/ + + /*MESSAGE*/ +/* + $frm['PRO_UID'] = '446BB1B36E17FE'; + $frm['MESS_UID'] = '146CDAC097D35A'; + $frm['MESS_TYPE'] = 'HTMLS'; + $frm['MESS_TITLE'] = 'título del mensaje'; + $frm['MESS_DESCRIPTION'] = 'estimado SrS.'; + + /** END MESSAGE*/ + /*STEP*/ +/* + $frm['PRO_UID'] = '446BB1B36E17FE'; + $frm['TAS_UID'] = '146CDAC097D35A'; + $frm['STEP_NAME_OBJ'] = 'HTM'; + $frm['STEP_TYPE_OBJ'] = 'OUTPUT_DOCUMENT'; + $frm['STEP_UID_OBJ'] = 'estimado SrS.'; +*/ + /** END MESSAGE*/ + + /** Delegation */ + + //$frm['PRO_UID'] ='ssddsfse32dd23s'; + /*$frm['APP_UID'] ='135165FDS54654FD'; + $frm['APP_PARENT'] ='135165FDS54654FD'; + $frm['PRO_UID'] ='SSDDSFSE32DD23S'; + $frm['APP_STATUS'] ='DRAFT'; + $frm['APP_PROC_STATUS']='TEST'; + $frm['APP_PARALLEL']='NO'; + $frm['APP_TITLE']='MAUI'; + + + + $prouid = $obj->Save ($frm); + //$obj->load('746E99F0D23189'); print_r($obj->Fields); + $obj->delete('046E99A56954AE'); + + +die("eliminado YA - ".$prouid); +*/ +?> \ No newline at end of file diff --git a/workflow/engine/methods/processes/downloadPML.php b/workflow/engine/methods/processes/downloadPML.php new file mode 100644 index 000000000..aa27cacbb --- /dev/null +++ b/workflow/engine/methods/processes/downloadPML.php @@ -0,0 +1,72 @@ +$downloadUrl
    ";die; + + G::LoadClass('processes'); + $oProcess = new Processes(); + $oProcess->downloadFile( $downloadUrl, $localPath, $newfilename); + + //getting the ProUid from the file recently downloaded + $oData = $oProcess->getProcessData ( $localPath . $newfilename ); + if (is_null($oData)) { + throw new Exception('Error'); + } + $Fields['IMPORT_OPTION'] = 2; + $Fields['PRO_FILENAME'] = $newfilename; + $Fields['OBJ_UID'] = $ObjUid ; + $sProUid = $oData->process['PRO_UID']; + $oData->process['PRO_UID_OLD']=$sProUid; +//print $sProUid;die; + //if the process exists, we need to ask what kind of re-import the user wants, + if ( $oProcess->processExists ( $sProUid ) ) { + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_ImportExisting', '', $Fields, 'downloadPML_ImportExisting' ); + G::RenderPage('publish', 'blank'); + die; + } + + //creating the process + $oProcess->createProcessFromData ($oData, $localPath . $newfilename ); + + //show the info after the imported process + G::LoadClass('processes'); + $oProcess = new Processes(); + $oProcess->ws_open_public (); + $processData = $oProcess->ws_processGetData ( $ObjUid ); + + $Fields['pro_title'] = $processData->title; + $Fields['installSteps'] = nl2br($processData->installSteps); + $Fields['category'] = (isset($processData->category) ? $processData->category : ''); + $Fields['version'] = $processData->version; + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $Fields['PRO_UID'] = $sProUid; + $processmapLink = "processes_Map?PRO_UID=$sProUid"; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_ImportSucessful', '', $Fields, $processmapLink ); + G::RenderPage('publish', 'blank'); + die; + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } diff --git a/workflow/engine/methods/processes/downloadPML_ImportExisting.php b/workflow/engine/methods/processes/downloadPML_ImportExisting.php new file mode 100644 index 000000000..eb623d2ea --- /dev/null +++ b/workflow/engine/methods/processes/downloadPML_ImportExisting.php @@ -0,0 +1,100 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + try { + //load the variables + G::LoadClass('processes'); + $oProcess = new Processes(); + + if ( !isset ($_POST['form']['IMPORT_OPTION'] ) ) { + throw ( new Exception ('Please select an option before to continue')) ; + } + + $option = $_POST['form']['IMPORT_OPTION']; + $filename = $_POST['form']['PRO_FILENAME']; + $ObjUid = $_POST['form']['OBJ_UID']; + + $path = PATH_DOCUMENT . 'input' . PATH_SEP ; + $oData = $oProcess->getProcessData ( $path . $filename ); + + $Fields['PRO_FILENAME'] = $filename; + $sProUid = $oData->process['PRO_UID']; + $oData->process['PRO_UID_OLD']=$sProUid; + + //Update the current Process, overwriting all tasks and steps + if ( $option == 1 ) { + $oProcess->updateProcessFromData ($oData, $path . $filename ); + if (file_exists(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid)) { + $oDirectory = dir(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid); + while($sObjectName = $oDirectory->read()) { + if (($sObjectName != '.') && ($sObjectName != '..')) { + unlink(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid . PATH_SEP . $sObjectName); + } + } + $oDirectory->close(); + } + $sNewProUid = $sProUid; + } + + //Disable current Process and create a new version of the Process + if ( $option == 2 ) { + $oProcess->disablePreviousProcesses( $sProUid ); + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess->setProcessGuid ( $oData, $sNewProUid ); + $oProcess->setProcessParent( $oData, $sProUid ); + $oData->process['PRO_TITLE'] = "New - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess->renewAllTaskGuid ( $oData ); + $oProcess->renewAllDynaformGuid ( $oData ); + $oProcess->renewAllInputGuid ( $oData ); + $oProcess->renewAllOutputGuid ( $oData ); + $oProcess->renewAllStepGuid ( $oData ); + $oProcess->renewAllTriggerGuid ( $oData ); + $oProcess->renewAllSubProcessGuid ( $oData ); + $oProcess->createProcessFromData ($oData, $path . $filename ); + } + + //Create a completely new Process without change the current Process + if ( $option == 3 ) { + //krumo ($oData); + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess->setProcessGuid ( $oData, $sNewProUid ); + $oData->process['PRO_TITLE'] = "Copy of - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess->renewAllTaskGuid ( $oData ); + $oProcess->renewAllDynaformGuid ( $oData ); + $oProcess->renewAllInputGuid ( $oData ); + $oProcess->renewAllOutputGuid ( $oData ); + $oProcess->renewAllStepGuid ( $oData ); + $oProcess->renewAllTriggerGuid ( $oData ); + $oProcess->renewAllSubProcessGuid ( $oData ); + $oProcess->createProcessFromData ($oData, $path . $filename ); + } + G::header('Location: processes_Map?PRO_UID=' . $sNewProUid); +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', 'blank'); +} diff --git a/workflow/engine/methods/processes/index.php b/workflow/engine/methods/processes/index.php new file mode 100644 index 000000000..e7e70d0a2 --- /dev/null +++ b/workflow/engine/methods/processes/index.php @@ -0,0 +1,28 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $newFile = str_replace ( 'index.php', 'processes_List.php' , __FILE__ ) ; + return $newFile; + + \ No newline at end of file diff --git a/workflow/engine/methods/processes/main.php b/workflow/engine/methods/processes/main.php new file mode 100755 index 000000000..766e50242 --- /dev/null +++ b/workflow/engine/methods/processes/main.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/*$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ) { + switch ($access) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + break; + case -1: + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + break; + } + exit(); +}*/ + +$RBAC->requirePermissions('PM_FACTORY'); + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'process'; +$G_ID_MENU_SELECTED = 'PROCESSES'; +$G_ID_SUB_MENU_SELECTED = '-'; + +$G_PUBLISH = new Publisher; +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptFile('/jscore/processes/main.js'); +$G_PUBLISH->AddContent('view', 'processes/mainLoad'); +//G::RenderPage('publish'); +if( isset($_GET['type']) ) + G::RenderPage( "publishBlank", "blank"); + else + G::RenderPage( "publish" ); + \ No newline at end of file diff --git a/workflow/engine/methods/processes/mainAjax.php b/workflow/engine/methods/processes/mainAjax.php new file mode 100644 index 000000000..07e52b2ab --- /dev/null +++ b/workflow/engine/methods/processes/mainAjax.php @@ -0,0 +1,19 @@ +'', 'CATEGORY_NAME'=>G::LoadTranslation('ID_ALL')); + $defaultOption[] = Array('CATEGORY_UID'=>'', 'CATEGORY_NAME'=>G::LoadTranslation('ID_PROCESS_NO_CATEGORY')); + + $response->rows = array_merge($defaultOption, $processCategory->getAll('array')); + + echo G::json_encode($response); + + break; +} \ No newline at end of file diff --git a/workflow/engine/methods/processes/mainInit.php b/workflow/engine/methods/processes/mainInit.php new file mode 100755 index 000000000..c31519657 --- /dev/null +++ b/workflow/engine/methods/processes/mainInit.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $oHeadPublisher =& headPublisher::getSingleton(); + + $oHeadPublisher->addExtJsScript('processes/main', false ); //adding a javascript file .js + $oHeadPublisher->addContent('processes/main'); //adding a html file .html. + + $translations = G::getTranslations(Array( + 'ID_NEW', 'ID_EDIT', 'ID_STATUS', 'ID_DELETE', 'ID_IMPORT', 'ID_BROWSE_LIBRARY', 'ID_CATEGORY', 'ID_SELECT', + 'ID_PRO_DESCRIPTION', 'ID_PRO_TITLE', 'ID_CATEGORY', 'ID_STATUS', 'ID_PRO_USER', 'ID_PRO_CREATE_DATE', 'ID_PRO_DEBUG', 'ID_INBOX', 'ID_DRAFT', + 'ID_COMPLETED', 'ID_CANCELLED', 'ID_TOTAL_CASES', 'ID_ENTER_SEARCH_TERM', 'ID_ACTIVATE', 'ID_DEACTIVATE', + 'ID_SELECT', 'ID_SEARCH', 'ID_NO_SELECTION_WARNING', 'ID_PROCESS_DELETE_LABEL', 'ID_PROCESS_DELETE_ALL_LABEL', + 'ID_PROCESS_CANT_DELETE' + )); + $oHeadPublisher->assign('TRANSLATIONS', $translations); + G::RenderPage('publish', 'extJs'); + + + + + diff --git a/workflow/engine/methods/processes/process_DeleteCases.php b/workflow/engine/methods/processes/process_DeleteCases.php new file mode 100644 index 000000000..3881c05a7 --- /dev/null +++ b/workflow/engine/methods/processes/process_DeleteCases.php @@ -0,0 +1,68 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* +global $RBAC; +switch ($RBAC->userCanAccess('PM_FACTORY')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} +*/ + $PRO_UID = $_GET['PRO_UID']; + require_once 'classes/model/Process.php'; + G::LoadClass('case'); + $oProcessMap = new Cases(); + + $process = new Process(); + $processData = $process->load($PRO_UID); + + $c = $oProcessMap->getCriteriaProcessCases('TO_DO', $PRO_UID); + $processData["TO_DO"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaProcessCases('COMPLETED', $PRO_UID); + $processData["COMPLETED"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaProcessCases('DRAFT', $PRO_UID); + $processData["DRAFT"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaProcessCases('CANCELLED', $PRO_UID); + $processData["CANCELLED"] = ApplicationPeer::doCount($c); + + $processData["PRO_UID"] = $PRO_UID; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_DeleteCases', '', $processData, 'processes_Delete.php'); + G::RenderPage('publish', 'raw'); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/processes/processesList.php b/workflow/engine/methods/processes/processesList.php new file mode 100644 index 000000000..282502016 --- /dev/null +++ b/workflow/engine/methods/processes/processesList.php @@ -0,0 +1,51 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/Process.php'; + +$start = isset($_POST['start'])? $_POST['start']: 0; +$limit = isset($_POST['limit'])? $_POST['limit']: ''; + +$oProcess = new Process(); + +if( isset($_POST['category']) && $_POST['category'] !== '' ){ + if( isset($_POST['processName']) ) + $proData = $oProcess->getAllProcesses($start, $limit, $_POST['category'], $_POST['processName']); + else + $proData = $oProcess->getAllProcesses($start, $limit, $_POST['category']); +} else { + if( isset($_POST['processName']) ) + $proData = $oProcess->getAllProcesses($start, $limit, null, $_POST['processName']); + else + $proData = $oProcess->getAllProcesses($start, $limit); +} +$r->data = $proData; + +$r->totalCount = 0; //$oProcess->getAllProcessesCount(); + +//print_R($r) +echo G::json_encode($r); + + diff --git a/workflow/engine/methods/processes/processes_Ajax.php b/workflow/engine/methods/processes/processes_Ajax.php new file mode 100644 index 000000000..51f0f9d0e --- /dev/null +++ b/workflow/engine/methods/processes/processes_Ajax.php @@ -0,0 +1,473 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + /*global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + }*/ + $oJSON = new Services_JSON(); + if ( isset ($_POST['data']) ) { + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $sOutput = ''; + } + + G::LoadClass('processMap'); + $oProcessMap = new processMap(new DBConnection); + + switch($_POST['action']) + { + case 'load': + if ($oData->ct) { + $sOutput = $oProcessMap->load($oData->uid, true, $_SESSION['APPLICATION'], -1, $_SESSION['TASK'], $oData->ct); + } + else { + if ($oData->mode) { + $sOutput = $oProcessMap->load($oData->uid); + } + else { + $sOutput = $oProcessMap->load($oData->uid, true, $_SESSION['APPLICATION'], $_SESSION['INDEX'], $_SESSION['TASK']); + } + } + break; + case 'process_Edit': + $oProcessMap->editProcess($oData->pro_uid); + break; + case 'process_Export': + include(PATH_METHODS . 'processes/processes_Export.php'); + break; + case 'process_User': + include(PATH_METHODS . 'processes/processes_User.php'); + break; + case 'availableProcessesUser': + include(PATH_METHODS . 'processes/processes_availableProcessesUser.php'); + break; + case 'webEntry_generate': + include(PATH_METHODS . 'processes/processes_webEntryGenerate.php'); + break; + // add this event to validate de data to create a Web Entry + case 'webEntry_validate': + include(PATH_METHODS . 'processes/processes_webEntryValidate.php'); + break; + case 'webEntry_delete': + $form=$_POST; + unlink(PATH_DATA ."sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP. $form['PRO_UID']. PATH_SEP.$form['FILENAME']); + unlink(PATH_DATA ."sites" . PATH_SEP . SYS_SYS . PATH_SEP . "public" . PATH_SEP. $form['PRO_UID']. PATH_SEP .str_replace(".php","Post",$form['FILENAME']).".php"); + $oProcessMap->webEntry($_POST['PRO_UID']); + break; + + case 'webEntry_new': + $oProcessMap->webEntry_new($oData->PRO_UID); + break; + case 'assignProcessUser': + $oProcessMap->assignProcessUser($oData->PRO_UID, $oData->USR_UID); + break; + case 'removeProcessUser': + $oProcessMap->removeProcessUser($oData->PU_UID); + break; + case 'supervisorDynaforms': + $oProcessMap->supervisorDynaforms($oData->pro_uid); + break; + case 'supervisorInputs': + $oProcessMap->supervisorInputs($oData->pro_uid); + break; + case 'webEntry': + $oProcessMap->webEntry($oData->pro_uid); + break; + + case 'webEntry_Val_Assig': + include(PATH_METHODS . 'processes/webEntry_Val_Assig.php'); + break; + + case 'saveTitlePosition': + $sOutput = $oProcessMap->saveTitlePosition($oData->pro_uid, $oData->position->x, $oData->position->y); + break; + case 'steps': + switch ($oData->option) + { + case 1: + $oProcessMap->steps($oData->proUid, $oData->tasUid); + break; + case 2: + $oProcessMap->stepsConditions($oData->proUid, $oData->tasUid); + break; + case 3: + $oProcessMap->stepsTriggers($oData->proUid, $oData->tasUid); + break; + } + break; + case 'users': + $oProcessMap->users($oData->pro_uid, $oData->tas_uid); + break; + + case 'users_adhoc': + $oProcessMap->users_adhoc($oData->pro_uid, $oData->tas_uid); + break; + + case 'addTask': + $sOutput = $oProcessMap->addTask($oData->uid, $oData->position->x, $oData->position->y); + break; + + case 'addSubProcess': + $sOutput = $oProcessMap->addSubProcess($oData->uid, $oData->position->x, $oData->position->y); + break; + + case 'editTaskProperties': + $oProcessMap->editTaskProperties($oData->uid, (isset($oData->iForm) ? $oData->iForm : 1), $oData->index); + break; + case 'saveTaskPosition': + $sOutput = $oProcessMap->saveTaskPosition($oData->uid, $oData->position->x, $oData->position->y); + break; + case 'deleteTask': + $sOutput = $oProcessMap->deleteTask($oData->tas_uid); + break; + case 'addGuide': + $sOutput = $oProcessMap->addGuide($oData->uid, $oData->position, $oData->direction); + break; + case 'saveGuidePosition': + $sOutput = $oProcessMap->saveGuidePosition($oData->uid, $oData->position, $oData->direction); + break; + case 'deleteGuide': + $sOutput = $oProcessMap->deleteGuide($oData->uid); + break; + case 'deleteGuides': + $sOutput = $oProcessMap->deleteGuides($oData->pro_uid); + break; + case 'addText': + $sOutput = $oProcessMap->addText($oData->uid, $oData->label, $oData->position->x, $oData->position->y); + break; + case 'updateText': + $sOutput = $oProcessMap->updateText($oData->uid, $oData->label); + break; + case 'saveTextPosition': + $sOutput = $oProcessMap->saveTextPosition($oData->uid, $oData->position->x, $oData->position->y); + break; + case 'deleteText': + $sOutput = $oProcessMap->deleteText($oData->uid); + break; + case 'dynaforms': + $oProcessMap->dynaformsList($oData->pro_uid); + break; + case 'inputs': + $oProcessMap->inputdocsList($oData->pro_uid); + break; + case 'outputs': + $oProcessMap->outputdocsList($oData->pro_uid); + break; + case 'triggers': + $oProcessMap->triggersList($oData->pro_uid); + break; + case 'case_scheduler': + if(isset($_POST['PRO_UID'])){ + $oProcessMap->caseSchedulerList($_POST['PRO_UID']); + } + break; + case 'log_case_scheduler': + if(isset($_POST['PRO_UID'])){ + $oProcessMap->logCaseSchedulerList($_POST['PRO_UID']); + } + break; + case 'messages': + $oProcessMap->messagesList($oData->pro_uid); + break; + case 'reportTables': + $oProcessMap->reportTablesList($oData->pro_uid); + break; + case 'derivations': + if (!isset($oData->type)) { + $oProcessMap->currentPattern($oData->pro_uid, $oData->tas_uid); + } + else { + switch ($oData->type) { + case 0: + $oData->type = 'SEQUENTIAL'; + break; + case 1: + $oData->type = 'SELECT'; + break; + case 2: + $oData->type = 'EVALUATE'; + break; + case 3: + $oData->type = 'PARALLEL'; + break; + case 4: + $oData->type = 'PARALLEL-BY-EVALUATION'; + break; + case 5: + $oData->type = 'SEC-JOIN'; + break; + } + $oProcessMap->newPattern($oData->pro_uid, $oData->tas_uid, $oData->next_task, $oData->type); + } + break; + case 'saveNewPattern': + switch ($oData->type) + { + case 0: + $sType = 'SEQUENTIAL'; + break; + case 1: + $sType = 'SELECT'; + break; + case 2: + $sType = 'EVALUATE'; + break; + case 3: + $sType = 'PARALLEL'; + break; + case 4: + $sType = 'PARALLEL-BY-EVALUATION'; + break; + case 5: + $sType = 'SEC-JOIN'; + break; + } + if (($oData->type != 0) && ($oData->type != 5)) { + if ($oProcessMap->getNumberOfRoutes($oData->pro_uid, $oData->tas_uid, $oData->next_task, $sType) > 0) { + die; + } + unset($aRow); + } + if (($oData->delete) || ($oData->type == 0) || ($oData->type == 5)) { + G::LoadClass('tasks'); + $oTasks = new Tasks(); + $oTasks->deleteAllRoutesOfTask($oData->pro_uid, $oData->tas_uid); + } + $oProcessMap->saveNewPattern($oData->pro_uid, $oData->tas_uid, $oData->next_task, $sType); + break; + case 'deleteAllRoutes': + G::LoadClass('tasks'); + $oTasks = new Tasks(); + $oTasks->deleteAllRoutesOfTask($oData->pro_uid, $oData->tas_uid); + break; + case 'objectPermissions': + $oProcessMap->objectsPermissionsList($oData->pro_uid); + break; + case 'newObjectPermission': + $oProcessMap->newObjectPermission($oData->pro_uid); + break; + case 'editObjectPermission': + // we also need the process uid variable for the function. + $oProcessMap->editObjectPermission($oData->op_uid,$oData->pro_uid); + break; + case 'caseTracker': + $oProcessMap->caseTracker($oData->pro_uid); + break; + case 'caseTrackerObjects': + $oProcessMap->caseTrackerObjects($oData->pro_uid); + break; + case 'processFilesManager': + $oProcessMap->processFilesManager($oData->pro_uid); + break; + case 'exploreDirectory': + $oProcessMap->exploreDirectory($oData->pro_uid, $oData->main_directory, $oData->directory); + break; + case 'deleteFile': + $oProcessMap->deleteFile($oData->pro_uid, $oData->main_directory, $oData->directory, $oData->file); + break; + case 'deleteDirectory': + $oProcessMap->deleteDirectory($oData->pro_uid, $oData->main_directory, $oData->directory, $oData->dir_to_delete); + break; + case 'downloadFile': + $oProcessMap->downloadFile($oData->pro_uid, $oData->main_directory, $oData->directory, $oData->file); + break; + case 'deleteSubProcess': + $sOutput = $oProcessMap->deleteSubProcess($oData->pro_uid, $oData->tas_uid); + break; + case 'subProcess_Properties': + $oProcessMap->subProcess_Properties($oData->pro_uid, $oData->tas_uid, $oData->index); + break; + case 'showDetailsPMDWL': + G::LoadClass('processes'); + $oProcesses = new Processes(); + $oProcesses->ws_open_public(); + $aFields = get_object_vars($oProcesses->ws_processGetData($oData->pro_uid)); + + $aFields['description'] = nl2br ($aFields['description']); + $aFields['installSteps'] = nl2br ($aFields['installSteps']); + switch ($aFields['privacy']) { + case 'FREE': + $aFields['link_label'] = G::LoadTranslation('ID_DOWNLOAD'); + $aFields['link_href'] = '../processes/downloadPML?id=' . $oData->pro_uid; + break; + case 'PUBLIC': + require_once 'classes/model/Configuration.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(ConfigurationPeer::CFG_VALUE); + $oCriteria->add(ConfigurationPeer::CFG_UID, 'REGISTER_INFORMATION'); + $oCriteria->add(ConfigurationPeer::USR_UID, $_SESSION['USER_LOGGED']); + if (ConfigurationPeer::doCount($oCriteria) > 0) { + $oDataset = ConfigurationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $aRI = unserialize($aRow['CFG_VALUE']); + try { + if ($oProcesses->ws_open($aRI['u'], $aRI['p']) == 1) { + $bExists = true; + } + else { + $bExists = false; + } + } + catch (Exception $oException) { + $bExists = false; + } + if ($bExists) { + $aFields['link_label'] = G::LoadTranslation('ID_DOWNLOAD'); + $aFields['link_href'] = '../processes/downloadPML?id=' . $oData->pro_uid . '&s=' . $sessionId; + } + else { + $aFields['link_label'] = G::LoadTranslation('ID_NEED_REGISTER'); + $aFields['link_href'] = "javascript:registerPML('" . $oData->pro_uid . "');"; + } + } + else { + $aFields['link_label'] = G::LoadTranslation('ID_NEED_REGISTER'); + $aFields['link_href'] = "javascript:registerPML('" . $oData->pro_uid . "');"; + } + break; + } + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/objectpmView', '', $aFields, ''); + G::RenderPage('publish', 'raw'); + break; + case 'registerPML': + $aFields = array(); + $aFields['pro_uid'] = $oData->pro_uid; + $aFields['link_create_account'] = PML_SERVER; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/registerPML', '', $aFields, ''); + G::RenderPage('publish', 'raw'); + break; + case 'loginPML': + G::LoadClass('processes'); + G::LoadThirdParty('pear/json','class.json'); + $oProcesses = new Processes(); + try { + if ($oProcesses->ws_open($oData->u, $oData->p) == 1) { + $bExists = true; + } + else { + $bExists = false; + } + } + catch (Exception $oException) { + $bExists = false; + } + $oResponse = new stdclass(); + if ($bExists) { + require_once 'classes/model/Configuration.php'; + $oConfiguration = new Configuration(); + $oConfiguration->create(array('CFG_UID' => 'REGISTER_INFORMATION', + 'OBJ_UID' => '', + 'CFG_VALUE' => serialize(array('u' => $oData->u, 'p' => $oData->p)), + 'PRO_UID' => '', + 'USR_UID' => $_SESSION['USER_LOGGED'], + 'APP_UID' => '')); + $oResponse->sLabel = G::LoadTranslation('ID_DOWNLOAD'); + $oResponse->sLink = '../processes/downloadPML?id=' . $oData->pro_uid . '&s=' . $sessionId; + } + $oResponse->bExists = $bExists; + $oJSON = new Services_JSON(); + echo $oJSON->encode($oResponse); + break; + + case 'editFile': + //echo $_POST['filename']; + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $sDirectory = PATH_DATA_MAILTEMPLATES . $_POST['pro_uid'] . PATH_SEP . $_POST['filename']; + + $fcontent = file_get_contents($sDirectory); + $extion=explode(".",$_POST['filename']); + + //if($extion[count($extion)-1]=='html' || $extion[count($extion)-1]=='txt'){ + $aData = Array( + 'pro_uid'=>$_POST['pro_uid'], + 'fcontent'=>$fcontent, + 'filename'=>$_POST['filename'], + ); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_FileEdit', '', $aData); + G::RenderPage('publish', 'raw'); + /*}else{ echo 'krlos'; + $aMessage['MESSAGE'] = G::loadTranslation( 'HTML_FILES' ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/showMessage', '',$aMessage ); + }*/ + + break; + case 'saveFile': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $sDirectory = PATH_DATA_MAILTEMPLATES . $_POST['pro_uid'] . PATH_SEP . $_POST['filename']; + + $fp = fopen($sDirectory, 'w'); + $content = stripslashes($_POST['fcontent']); + $content = str_replace("@amp@", "&", $content); + fwrite($fp, $content); + fclose($fp); + echo 'saved: '. $sDirectory; + break; + case 'events': + $oProcessMap->eventsList($oData->pro_uid, $oData->type); + break; + + case 'saveFile': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $sDirectory = PATH_DATA_MAILTEMPLATES . $_POST['pro_uid'] . PATH_SEP . $_POST['filename']; + + $fp = fopen($sDirectory, 'w'); + $content = stripslashes($_POST['fcontent']); + $content = str_replace("@amp@", "&", $content); + fwrite($fp, $content); + fclose($fp); + echo 'saved: '. $sDirectory; + break; + + case 'emptyFileOptions': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_FileEditCreateEmpty', ''); + G::RenderPage('publish', 'raw'); + break; + } + if( isset($sOutput) ) + die($sOutput); +} +catch (Exception $oException) { + die($oException->getMessage() . "\n" . $oException->getTraceAsString()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_ChangeStatus.php b/workflow/engine/methods/processes/processes_ChangeStatus.php new file mode 100644 index 000000000..d9a682976 --- /dev/null +++ b/workflow/engine/methods/processes/processes_ChangeStatus.php @@ -0,0 +1,48 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +switch ($RBAC->userCanAccess('PM_FACTORY')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + $ids = explode(',', $_GET['UIDS']); + + G::LoadClass('processes'); + $oProcess = new Processes(); + if( count($ids) > 0 ){ + foreach($ids as $id) + $oProcess->changeStatus ($id); + } + //G::header('location: ' . $_SERVER['HTTP_REFERER']); + \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_Delete.php b/workflow/engine/methods/processes/processes_Delete.php new file mode 100644 index 000000000..6929aa5a8 --- /dev/null +++ b/workflow/engine/methods/processes/processes_Delete.php @@ -0,0 +1,62 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access){ + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); + +$UIDS = explode(',', $_POST['PRO_UIDS']); + +try{ + + foreach($UIDS as $UID){ + $oProcessMap->deleteProcess($UID); + } + $resp->status = 0; + $resp->msg = 'All process was deleted successfully'; + echo G::json_encode($resp); +} catch(Exception $e){ + $resp->status = 1; + $resp->msg = $e->getMessage(); + echo G::json_encode($resp); +} + + + \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_DeleteObjectPermission.php b/workflow/engine/methods/processes/processes_DeleteObjectPermission.php new file mode 100644 index 000000000..8fb6466ed --- /dev/null +++ b/workflow/engine/methods/processes/processes_DeleteObjectPermission.php @@ -0,0 +1,54 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +require_once 'classes/model/ObjectPermission.php'; +$oOP = new ObjectPermission(); +$oOP = ObjectPermissionPeer::retrieveByPK($_GET['OP_UID']); +$sProcessUID = $oOP->getProUid(); +$oOP->delete(); +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); +$oProcessMap->getObjectsPermissionsCriteria($sProcessUID); \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_DownloadFile.php b/workflow/engine/methods/processes/processes_DownloadFile.php new file mode 100644 index 000000000..3520a1e26 --- /dev/null +++ b/workflow/engine/methods/processes/processes_DownloadFile.php @@ -0,0 +1,37 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //add more security, and catch any error or exception + + $sFileName = $_GET['p'] . '.pm'; + $file=PATH_DOCUMENT . 'output'. PATH_SEP. $sFileName.'tpm'; + $filex=PATH_DOCUMENT . 'output'. PATH_SEP. $sFileName; + + if(file_exists($file)) + { + rename($file, $filex); + } + + $realPath = PATH_DOCUMENT . 'output'. PATH_SEP. $sFileName; + G::streamFile ( $realPath, true ); diff --git a/workflow/engine/methods/processes/processes_Export.php b/workflow/engine/methods/processes/processes_Export.php new file mode 100644 index 000000000..0963fce43 --- /dev/null +++ b/workflow/engine/methods/processes/processes_Export.php @@ -0,0 +1,54 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +G::LoadThirdParty('pear/json','class.json'); + +try { + + $oJSON = new Services_JSON(); + $stdObj = $oJSON->decode( $_POST['data'] ); + if ( isset ($stdObj->pro_uid ) ) + $sProUid = $stdObj->pro_uid; + else + throw ( new Exception ( 'the process uid is not defined!.' ) ); + +/* Includes */ +G::LoadClass('processes'); +$oProcess = new Processes(); +$proFields = $oProcess->serializeProcess( $sProUid ); +$Fields = $oProcess->saveSerializedProcess ( $proFields ); + + /* Render page */ + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_Export', '', $Fields ); + G::RenderPage( 'publish', 'raw' ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', 'raw' ); +} diff --git a/workflow/engine/methods/processes/processes_GetFile.php b/workflow/engine/methods/processes/processes_GetFile.php new file mode 100644 index 000000000..4a8373a03 --- /dev/null +++ b/workflow/engine/methods/processes/processes_GetFile.php @@ -0,0 +1,15 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +try { + +/* Includes */ +G::LoadClass('processes'); + + /* Render page */ + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_Import', '', NULL, 'processes_ImportFile' ); + G::RenderPage( "publish", "blank"); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', "blank"); +} diff --git a/workflow/engine/methods/processes/processes_ImportExisting.php b/workflow/engine/methods/processes/processes_ImportExisting.php new file mode 100644 index 000000000..ff8f6d37c --- /dev/null +++ b/workflow/engine/methods/processes/processes_ImportExisting.php @@ -0,0 +1,132 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + try { + //load the variables + G::LoadClass('processes'); + $oProcess = new Processes(); + + if ( !isset ($_POST['form']['IMPORT_OPTION'] ) ) { + throw ( new Exception ('Please select an option before to continue')) ; + } + + if ( !isset ($_POST['form']['GROUP_IMPORT_OPTION']) ) { + $action = "none" ; + } else { + $action = $_POST['form']['GROUP_IMPORT_OPTION']; + } + + $option = $_POST['form']['IMPORT_OPTION']; + $filename = $_POST['form']['PRO_FILENAME']; + $ObjUid = $_POST['form']['OBJ_UID']; + + $path = PATH_DOCUMENT . 'input' . PATH_SEP ; + $oData = $oProcess->getProcessData ( $path . $filename ); + + $Fields['PRO_FILENAME'] = $filename; + $sProUid = $oData->process['PRO_UID']; + + $oData->process['PRO_UID_OLD']=$sProUid; + + // code added by gustavo cruz gustavo-at-colosa-dot-com + // evaluate actions or import options + switch($action){ + case "none": + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + case "rename": + $oData->groupwfs = $oProcess->renameExistingGroups($oData->groupwfs); + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + case "merge": + $oBaseGroup = $oData->groupwfs; + $oNewGroup = $oProcess->mergeExistingGroups($oData->groupwfs); + $oData->groupwfs = $oNewGroup; + $oData->taskusers = $oProcess->mergeExistingUsers($oBaseGroup, $oNewGroup, $oData->taskusers); + + break; + default: + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + } + + // if there are duplicated groups render the group importing options + if($groupsDuplicated>0){ + $Fields['PRO_FILENAME'] = $filename; + $Fields['PRO_PATH'] = $path; + $Fields['IMPORT_OPTION'] = $option; + $Fields['OBJ_UID'] = $ObjUid; + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_ValidatingGroups', '', $Fields, 'processes_ImportExisting' ); + G::RenderPage('publish', 'blank'); + die; + } + //end added code + + //Update the current Process, overwriting all tasks and steps + if ( $option == 1 ) { + $oProcess->updateProcessFromData ($oData, $path . $filename ); + if (file_exists(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid)) { + $oDirectory = dir(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid); + while($sObjectName = $oDirectory->read()) { + if (($sObjectName != '.') && ($sObjectName != '..')) { + unlink(PATH_OUTTRUNK . 'compiled' . PATH_SEP . 'xmlform' . PATH_SEP . $sProUid . PATH_SEP . $sObjectName); + } + } + $oDirectory->close(); + } + $sNewProUid = $sProUid; + } + + //Disable current Process and create a new version of the Process + if ( $option == 2 ) { + $oProcess->disablePreviousProcesses( $sProUid ); + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess->setProcessGuid ( $oData, $sNewProUid ); + $oProcess->setProcessParent( $oData, $sProUid ); + $oData->process['PRO_TITLE'] = "New - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess->renewAll ( $oData ); + $oProcess->createProcessFromData ($oData, $path . $filename ); + } + + //Create a completely new Process without change the current Process + if ( $option == 3 ) { + //krumo ($oData); die; + $sNewProUid = $oProcess->getUnusedProcessGUID() ; + $oProcess->setProcessGuid ( $oData, $sNewProUid ); + $oData->process['PRO_TITLE'] = "Copy of - " . $oData->process['PRO_TITLE'] . ' - ' . date ( 'M d, H:i' ); + $oProcess->renewAll ( $oData ); + $oProcess->createProcessFromData ($oData, $path . $filename ); + } + G::header('Location: processes_Map?PRO_UID=' . $sNewProUid); +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', 'blank'); +} diff --git a/workflow/engine/methods/processes/processes_ImportFile.php b/workflow/engine/methods/processes/processes_ImportFile.php new file mode 100644 index 000000000..c847fe3b5 --- /dev/null +++ b/workflow/engine/methods/processes/processes_ImportFile.php @@ -0,0 +1,112 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + try { + //load the variables + G::LoadClass('processes'); + $oProcess = new Processes(); + +// if ( isset ($_POST) ) { +// krumo ( $_POST ); +// } + + if (isset($_POST['form']['PRO_FILENAME'])){ + $path = $_POST['form']['PRO_PATH']; + $filename = $_POST['form']['PRO_FILENAME']; + $action = $_POST['form']['GROUP_IMPORT_OPTION']; + } else { + //save the file, if it's not saved + if ($_FILES['form']['error']['PROCESS_FILENAME'] == 0) { + $filename = $_FILES['form']['name']['PROCESS_FILENAME']; + $path = PATH_DOCUMENT . 'input' . PATH_SEP ; + $tempName = $_FILES['form']['tmp_name']['PROCESS_FILENAME']; + $action = "none"; + G::uploadFile($tempName, $path, $filename ); + } + } + + $oData = $oProcess->getProcessData ( $path . $filename ); + + $Fields['PRO_FILENAME'] = $filename; + $Fields['IMPORT_OPTION'] = 2; + + $sProUid = $oData->process['PRO_UID']; + + $oData->process['PRO_UID_OLD']=$sProUid; + + if ( $oProcess->processExists ( $sProUid ) ) { + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_ImportExisting', '', $Fields, 'processes_ImportExisting' ); + G::RenderPage('publish', 'blank'); + die; + } + // code added by gustavo cruz gustavo-at-colosa-dot-com + // evaluate actions or import options + switch($action){ + case "none": + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + case "rename": + $oData->groupwfs = $oProcess->renameExistingGroups($oData->groupwfs); + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + case "merge": + + $oBaseGroup = $oData->groupwfs; + $oNewGroup = $oProcess->mergeExistingGroups($oData->groupwfs); + $oData->groupwfs = $oNewGroup; + $oData->taskusers = $oProcess->mergeExistingUsers($oBaseGroup, $oNewGroup, $oData->taskusers); + + break; + default: + $groupsDuplicated = $oProcess->checkExistingGroups($oData->groupwfs); + break; + } + + // if there are duplicated groups render the group importing options + if($groupsDuplicated>0){ + $Fields['PRO_FILENAME'] = $filename; + $Fields['PRO_PATH'] = $path; + $Fields['IMPORT_OPTION'] = 2; + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_ValidatingGroups', '', $Fields, 'processes_ImportFile' ); + G::RenderPage('publish', 'blank'); + die; + } + // end added code + $oProcess->createProcessFromData ($oData, $path . $filename ); + G::header('Location: processes_Map?PRO_UID=' . $sProUid); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', 'blank'); +} diff --git a/workflow/engine/methods/processes/processes_Library.php b/workflow/engine/methods/processes/processes_Library.php new file mode 100755 index 000000000..1b1592939 --- /dev/null +++ b/workflow/engine/methods/processes/processes_Library.php @@ -0,0 +1,138 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +/**************************/ + + function parseItemArray( $array ) { + if (!isset ($array->item) && !is_array($array) ) { + return null; + } + + $result = array(); + if ( isset ( $array->item ) ) { + foreach ($array->item as $key => $value) { + $result[$value->key] = $value->value; + } + } + else { + foreach ($array as $key => $value) { + $result[$value->key] = $value->value; + } + } + return $result; + } + + +try { + G::LoadClass('processes'); + $oProcess = new Processes(); + $oProcess->ws_open_public (); + + $result = $oProcess->ws_ProcessList ( ); + $processes[] = array ( 'uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); + + if ( $result->status_code == 0 && isset($result->processes) ) { + foreach ( $result->processes as $key => $val ) { + $process = parseItemArray($val); + $processes[] = $process; + } + } + $_DBArray['processes'] = $processes; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('processes'); + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_ListPublic', $c); + $oHeadPublisher =& headPublisher::getSingleton(); + //$oHeadPublisher->addScriptCode('leimnud.Package.Load("newAccount",{Type:"file",Absolute:true,Path:"/jscore/newAccount.js"});'); + $oHeadPublisher->addScriptCode(" + var oPanel; + var oPanel2; + var showDetails = function(sUID) { + oPanel = new leimnud.module.panel(); + oPanel.options = { + size:{w:650,h:550}, + position:{x:0,y:0,center:true}, + title:'', + theme:'firefox', + statusBar:true, + control :{resize:false,roll:false,drag:true}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'processes_Ajax', + args: 'action=showDetailsPMDWL&data=' + {pro_uid:sUID}.toJSONString() + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + oPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + }; + "); + G::RenderPage('publish', 'blank'); + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_List.php b/workflow/engine/methods/processes/processes_List.php new file mode 100644 index 000000000..d0862c37e --- /dev/null +++ b/workflow/engine/methods/processes/processes_List.php @@ -0,0 +1,73 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'process'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = '-'; + + + $aLabels['LANG'] = SYS_LANG; + $aLabels['PRO_EDIT'] = G::LoadTranslation('ID_EDIT'); + $aLabels['PRO_DELETE']= G::LoadTranslation('ID_DELETE'); + $aLabels['ACTIVE'] = G::LoadTranslation('ID_ACTIVE'); + $aLabels['INACTIVE'] = G::LoadTranslation('ID_INACTIVE'); + $aLabels['CONFIRM'] = G::LoadTranslation('ID_MSG_CONFIRM_DELETE_PROCESS'); + + + G::LoadClass ( 'processMap'); + $oProcess = new processMap(); + $c = $oProcess->getConditionProcessList(); + +function activeFalse($value) +{ + return $value=="ACTIVE"?"ID_ACTIVE":"ID_INACTIVE"; +} + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_List', $c, $aLabels, '' ); +G::RenderPage('publish'); diff --git a/workflow/engine/methods/processes/processes_Map.php b/workflow/engine/methods/processes/processes_Map.php new file mode 100644 index 000000000..41e0258b0 --- /dev/null +++ b/workflow/engine/methods/processes/processes_Map.php @@ -0,0 +1,92 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +$processUID = $_GET['PRO_UID']; +$_SESSION['PROCESS'] = $processUID; + +$oTemplatePower = new TemplatePower(PATH_TPL . 'processes/processes_Map.html'); +$oTemplatePower->prepare(); + +$G_MAIN_MENU = 'processmaker'; +$G_ID_MENU_SELECTED = 'PROCESSES'; +$G_SUB_MENU = 'processes'; +$G_ID_SUB_MENU_SELECTED = '_'; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + +$oHeadPublisher =& headPublisher::getSingleton(); +$oHeadPublisher->addScriptFile('/jscore/dbConnections/main.js'); + +//$oHeadPublisher->addScriptFile('/htmlarea/editor.js'); +$oHeadPublisher->addScriptCode( ' + var leimnud = new maborak(); + leimnud.make(); + leimnud.Package.Load("rpc,drag,drop,panel,app,validator,fx,dom,abbr",{Instance:leimnud,Type:"module"}); + leimnud.Package.Load("json",{Type:"file"}); + leimnud.Package.Load("processmap",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processmap.js"}); + leimnud.Package.Load("processes_Map",{Type:"file",Absolute:true,Path:"/jscore/processmap/core/processes_Map.js"}); + leimnud.Package.Load("stagesmap",{Type:"file",Absolute:true,Path:"/jscore/stagesmap/core/stagesmap.js"}); + leimnud.exec(leimnud.fix.memoryLeak); + leimnud.event.add(window,"load",function(){ + var pb=leimnud.dom.capture("tag.body 0"); + Pm=new processmap(); + Pm.options={ + target :"pm_target", + dataServer :"processes_Ajax.php", + uid :"' . $processUID . '", + lang :"' . SYS_LANG . '", + theme :"processmaker", + size :{w:pb.offsetWidth-10,h:pb.offsetHeight}, + images_dir :"/jscore/processmap/core/images/" + } + Pm.make(); + });' ); + +if( ! isset($_GET['raw']) ) + G::RenderPage('publish', 'green-submenu'); +else + G::RenderPage('publish', 'raw'); diff --git a/workflow/engine/methods/processes/processes_New.php b/workflow/engine/methods/processes/processes_New.php new file mode 100644 index 000000000..1e60686c1 --- /dev/null +++ b/workflow/engine/methods/processes/processes_New.php @@ -0,0 +1,63 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + + //call plugins + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->executeTriggers ( PM_NEW_PROCESS_LIST , NULL ); + + + $aFields['MESSAGE1'] = G::LoadTranslation('ID_MSG_ERROR_PRO_TITLE'); + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_PUBLISH = new Publisher; + if ( isset ( $_DBArray['ProcessesNew']) ) { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_New', '', $aFields, 'processes_Save'); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'processes/processes_NewSimple', '', $aFields, 'processes_Save'); + } + G::RenderPage( 'publish', 'blank'); diff --git a/workflow/engine/methods/processes/processes_Save.php b/workflow/engine/methods/processes/processes_Save.php new file mode 100644 index 000000000..ab308042c --- /dev/null +++ b/workflow/engine/methods/processes/processes_Save.php @@ -0,0 +1,90 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * This is a ajax response file + * + */ + +G::LoadThirdParty('pear/json','class.json'); + +$function = isset($_POST['function']) ? $_POST['function']: ''; + +switch($function){ + case 'lookForNameProcess': + require_once 'classes/model/Content.php'; + $snameProcess=urldecode($_POST['NAMEPROCESS']); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT(*) AS PROCESS'); + $oCriteria->add(ContentPeer::CON_CATEGORY, 'PRO_TITLE'); + $oCriteria->add(ContentPeer::CON_LANG, SYS_LANG); + $oCriteria->add(ContentPeer::CON_VALUE, $snameProcess); + $oDataset = ContentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + print ($aRow['PROCESS']?true:false); + break; + + default: + if ( isset($_GET['PRO_UID'])) { + $_POST['form']['PRO_UID'] = $_GET['PRO_UID']; + } + + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + if( !isset($_POST['form']['PRO_UID']) ) { + $_POST['form']['USR_UID'] = $_SESSION['USER_LOGGED']; + $oJSON = new Services_JSON(); + require_once 'classes/model/Task.php'; + + $sProUid = $oProcessMap->createProcess($_POST['form']); + + //call plugins + $oData['PRO_UID'] = $sProUid; + $oData['PRO_TEMPLATE'] = (isset($_POST['form']['PRO_TEMPLATE']) && $_POST['form']['PRO_TEMPLATE']!='')?$_POST['form']['PRO_TEMPLATE']:''; + $oData['PROCESSMAP'] = $oProcessMap; + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->executeTriggers ( PM_NEW_PROCESS_SAVE , $oData ); + + G::header('location: processes_Map?PRO_UID='. $sProUid ); + die; + } else { + $oProcessMap->updateProcess($_POST['form']); + $sProUid = $_POST['form']['PRO_UID']; + } + + //Save Calendar ID for this process + G::LoadClass("calendar"); + $calendarObj=new Calendar(); + $calendarObj->assignCalendarTo($sProUid,$_POST['form']['PRO_CALENDAR'],'PROCESS'); + + if ($_POST['form']['THETYPE'] == ''){ + G::header('location: main'); + } + break; + +} \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_SaveEditObjectPermission.php b/workflow/engine/methods/processes/processes_SaveEditObjectPermission.php new file mode 100644 index 000000000..4085a3ca3 --- /dev/null +++ b/workflow/engine/methods/processes/processes_SaveEditObjectPermission.php @@ -0,0 +1,84 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +list($iRelation, $sUserGroup) = explode('|', $_POST['form']['GROUP_USER']); +$sObjectUID = ''; +switch ($_POST['form']['OP_OBJ_TYPE']) { + case 'ANY': + $sObjectUID = ''; + break; + case 'DYNAFORM': + $sObjectUID = $_POST['form']['DYNAFORMS']; + break; + case 'INPUT': + $sObjectUID = $_POST['form']['INPUTS']; + break; + case 'OUTPUT': + $sObjectUID = $_POST['form']['OUTPUTS']; + break; +} +require_once 'classes/model/ObjectPermission.php'; +$oOP = new ObjectPermission(); +$aData = array('OP_UID' => $_POST['form']['OP_UID'], + 'PRO_UID' => $_POST['form']['PRO_UID'], + 'TAS_UID' => $_POST['form']['TAS_UID']!='' ? $_POST['form']['TAS_UID'] : '0' , + 'USR_UID' => (string)$sUserGroup, + 'OP_USER_RELATION' => $iRelation, + 'OP_TASK_SOURCE' => $_POST['form']['OP_TASK_SOURCE']!='' ? $_POST['form']['OP_TASK_SOURCE'] : '0', + 'OP_PARTICIPATE' => $_POST['form']['OP_PARTICIPATE']!='' ? $_POST['form']['OP_PARTICIPATE'] : 0, + 'OP_OBJ_TYPE' => $_POST['form']['OP_OBJ_TYPE']!='' ? $_POST['form']['OP_OBJ_TYPE'] : '0', + 'OP_OBJ_UID' => $sObjectUID!='' ? $sObjectUID : '0', + 'OP_ACTION' => $_POST['form']['OP_ACTION']!='' ? $_POST['form']['OP_ACTION'] : '0', + 'OP_CASE_STATUS' => $_POST['form']['OP_CASE_STATUS']!='' ? $_POST['form']['OP_CASE_STATUS'] : '0' + ); + +$oObj = new ObjectPermission(); +$oObj->update($aData); + +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); +$oProcessMap->getObjectsPermissionsCriteria($_POST['form']['PRO_UID']); diff --git a/workflow/engine/methods/processes/processes_SaveObjectPermission.php b/workflow/engine/methods/processes/processes_SaveObjectPermission.php new file mode 100644 index 000000000..1ac43df15 --- /dev/null +++ b/workflow/engine/methods/processes/processes_SaveObjectPermission.php @@ -0,0 +1,83 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +list($iRelation, $sUserGroup) = explode('|', $_POST['form']['GROUP_USER']); +$sObjectUID = ''; +switch ($_POST['form']['OP_OBJ_TYPE']) { + case 'ANY': + /*case 'ANY_DYNAFORM': + case 'ANY_INPUT': + case 'ANY_OUTPUT':*/ + $sObjectUID = ''; + break; + case 'DYNAFORM': + $sObjectUID = $_POST['form']['DYNAFORMS']; + break; + case 'INPUT': + $sObjectUID = $_POST['form']['INPUTS']; + break; + case 'OUTPUT': + $sObjectUID = $_POST['form']['OUTPUTS']; + break; +} +require_once 'classes/model/ObjectPermission.php'; +$oOP = new ObjectPermission(); +$aData = array('OP_UID' => G::generateUniqueID(), + 'PRO_UID' => $_POST['form']['PRO_UID'], + 'TAS_UID' => $_POST['form']['TAS_UID'], + 'USR_UID' => (string)$sUserGroup, + 'OP_USER_RELATION' => $iRelation, + 'OP_TASK_SOURCE' => $_POST['form']['OP_TASK_SOURCE'], + 'OP_PARTICIPATE' => $_POST['form']['OP_PARTICIPATE'], + 'OP_OBJ_TYPE' => $_POST['form']['OP_OBJ_TYPE'], + 'OP_OBJ_UID' => $sObjectUID, + 'OP_ACTION' => $_POST['form']['OP_ACTION'], + 'OP_CASE_STATUS' => $_POST['form']['OP_CASE_STATUS']); +$oOP->fromArray($aData,BasePeer::TYPE_FIELDNAME); +$oOP->save(); +G::LoadClass('processMap'); +$oProcessMap = new ProcessMap(); +$oProcessMap->getObjectsPermissionsCriteria($_POST['form']['PRO_UID']); diff --git a/workflow/engine/methods/processes/processes_UploadFiles.php b/workflow/engine/methods/processes/processes_UploadFiles.php new file mode 100644 index 000000000..94a69bc82 --- /dev/null +++ b/workflow/engine/methods/processes/processes_UploadFiles.php @@ -0,0 +1,18 @@ +parent.goToDirectory(\'' . $_POST['form']['PRO_UID'] . '\', \'' . $_POST['form']['MAIN_DIRECTORY'] . '\', \'' . $_POST['form']['CURRENT_DIRECTORY'] . '\');'); \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_UploadFilesForm.php b/workflow/engine/methods/processes/processes_UploadFilesForm.php new file mode 100644 index 000000000..3062f3d0a --- /dev/null +++ b/workflow/engine/methods/processes/processes_UploadFilesForm.php @@ -0,0 +1,56 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +/* +$oForm = new Form('processes/processes_UploadFilesForm', '', SYS_LANG); +$oForm->action = 'processes_UploadFiles'; +$oForm->values = array('PRO_UID' => $_GET['PRO_UID'], + 'MAIN_DIRECTORY' => $_GET['MAIN_DIRECTORY'], + 'CURRENT_DIRECTORY' => $_GET['CURRENT_DIRECTORY']); +echo '' . + $oForm->render(PATH_CORE . 'templates/xmlform.html', $scriptCode = ''); + +*/ + + $params = Array('PRO_UID' => $_GET['PRO_UID'], + 'MAIN_DIRECTORY' => $_GET['MAIN_DIRECTORY'], + 'CURRENT_DIRECTORY' => $_GET['CURRENT_DIRECTORY']); + + $_SESSION['processes_upload'] = $params; + $G_PUBLISH = new Publisher(); + $oHeadPublisher =& headPublisher::getSingleton(); + $G_PUBLISH->AddContent('view', 'processes/processes_Upload'); + G::RenderPage( "publish" , "raw" ); + + + + + + + + + + diff --git a/workflow/engine/methods/processes/processes_User.php b/workflow/engine/methods/processes/processes_User.php new file mode 100644 index 000000000..5a3554ca3 --- /dev/null +++ b/workflow/engine/methods/processes/processes_User.php @@ -0,0 +1,59 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is a callback for the View of all groups from a determinated user + * @author Everth S. Berrios Morales + * @Date 16/05/2008 + * @LastModification none + */ +G::LoadThirdParty('pear/json','class.json'); +try { + $oJSON = new Services_JSON(); + $stdObj = $oJSON->decode(stripslashes($_POST['data'])); + if ( isset ($stdObj->pro_uid ) ) + $sProUid = $stdObj->pro_uid; + else + throw ( new Exception ( 'the process uid is not defined!.' ) ); + + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $c = $oProcessMap->listProcessesUser($sProUid); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/processmap/core/processUser.js'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_User', $c, array('PRO_UID' => $sProUid)); + G::RenderPage( 'publish', 'raw' ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage); + G::RenderPage('publish', 'raw' ); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_availableProcessesUser.php b/workflow/engine/methods/processes/processes_availableProcessesUser.php new file mode 100644 index 000000000..88df5999a --- /dev/null +++ b/workflow/engine/methods/processes/processes_availableProcessesUser.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is a callback for the View of all groups from a determinated user + * @author Everth S. Berrios Morales + * @Date 19/05/2008 + * @LastModification none + */ +try { + $sProUid=$oData->PRO_UID; + + require_once 'classes/model/Users.php'; + require_once 'classes/model/ProcessUser.php'; + + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $c = $oProcessMap->listNoProcessesUser($sProUid); + global $RBAC; + $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'processes/processes_availableProcessesUser', $c, array('PRO_UID' => $sProUid)); + G::RenderPage( 'publish', 'raw' ); + +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish', 'raw' ); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_checkProperties.php b/workflow/engine/methods/processes/processes_checkProperties.php new file mode 100755 index 000000000..233e20214 --- /dev/null +++ b/workflow/engine/methods/processes/processes_checkProperties.php @@ -0,0 +1,90 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; + +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +$form = $_POST ['form']; + +//$tasUid = $form['TASKS']; +$tasUid = $form['TAS_PARENT']; +$spSynchronous = $form['SP_SYNCHRONOUS']; + +require_once 'classes/model/Route.php'; +require_once 'classes/model/Task.php'; + +$oRoute= new Route(); +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(RoutePeer::ROU_NEXT_TASK); +$oCriteria->add(RoutePeer::TAS_UID, $tasUid); +$oDataset = RoutePeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + +$sw=1; +// if there are more step we're looking them and we're checking TAS_ASSIGN_TYPE field +while ($oDataset->next() && $sw){ + $aRow = $oDataset->getRow(); + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->addSelectColumn(TaskPeer::TAS_ASSIGN_TYPE); + $oCriteria1->add(TaskPeer::PRO_UID, $form['PRO_PARENT']); + $oCriteria1->add(TaskPeer::TAS_UID, $aRow['ROU_NEXT_TASK']); + $oDataset1 = TaskPeer::doSelectRS($oCriteria1); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aRow1 = $oDataset1->getRow(); + + if($spSynchronous && $aRow1['TAS_ASSIGN_TYPE']=='MANUAL') + $sw=0; + +} +///If there are at least one TAS_ASSIGN_TYPE field with MANUAL it returns 1 +if(!$sw) + return print $spSynchronous; +else + return print '0'; + + diff --git a/workflow/engine/methods/processes/processes_doUpload.php b/workflow/engine/methods/processes/processes_doUpload.php new file mode 100644 index 000000000..7c1799d0f --- /dev/null +++ b/workflow/engine/methods/processes/processes_doUpload.php @@ -0,0 +1,29 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +$access = $RBAC->userCanAccess('PM_FACTORY'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + +//print_r($_POST); die; + +$out = array(); +for($i=1; $i<=count($_POST['form']['grid1']); $i++) +{ + $out[$_POST['form']['grid1'][$i]['VAR_OUT1']]= $_POST['form']['grid1'][$i]['VAR_OUT2']; +} + +$in = array(); +for($j=1; $j<=count($_POST['form']['grid2']); $j++) +{ + $in[$_POST['form']['grid2'][$j]['VAR_IN1']] = $_POST['form']['grid2'][$j]['VAR_IN2']; +} + +require_once 'classes/model/Task.php'; +$oTask= new Task(); +//$aTask=$oTask->load($_POST['form']['TASKS']); +//$aTask=$oTask->load($_POST['form']['PRO_UID']); +$aTask=($_POST['form']['TASKS']!=0)?$oTask->load($_POST['form']['TASKS']):0; +//$aTask['PRO_UID']=0; + +if ( isset ( $_POST['form']['SP_SYNCHRONOUS']) && $_POST['form']['SP_SYNCHRONOUS'] == '' ) { + $_POST['form']['SP_SYNCHRONOUS'] = '0'; +} + +if ( !isset ( $_POST['form']['SP_SYNCHRONOUS']) ) { + $_POST['form']['SP_SYNCHRONOUS'] = '0'; +} + +require_once 'classes/model/SubProcess.php'; +$oOP = new SubProcess(); +$aData = array('SP_UID' => $_POST['form']['SP_UID'],//G::generateUniqueID(), + 'PRO_UID' => $aTask['PRO_UID'], + 'TAS_UID' => $_POST['form']['TASKS'], + 'PRO_PARENT' => $_POST['form']['PRO_PARENT'], + 'TAS_PARENT' => $_POST['form']['TAS_PARENT'], + 'SP_TYPE' => 'SIMPLE', + 'SP_SYNCHRONOUS' => $_POST['form']['SP_SYNCHRONOUS'], + 'SP_SYNCHRONOUS_TYPE' => 'ALL', + 'SP_SYNCHRONOUS_WAIT' => 0, + 'SP_VARIABLES_OUT' => serialize($out), + 'SP_VARIABLES_IN' => serialize($in), + 'SP_GRID_IN' => ''); + + +$oOP->update($aData); + +require_once 'classes/model/Content.php'; +$lang = defined ( 'SYS_LANG') ? SYS_LANG : 'en'; +//$cont = Content::addContent( 'SP_TITLE', '', $_POST['form']['SP_UID'], $lang, $_POST['form']['SPROCESS_NAME'] ); +$cont = Content::addContent( 'TAS_TITLE', '', $_POST['form']['TAS_PARENT'], $lang, $_POST['form']['SPROCESS_NAME'] ); +//$cont = Content::addContent( 'TAS_TITLE', '', $_POST['form']['SP_UID'], $lang, $_POST['form']['SPROCESS_NAME'] ); +//G::header('location: processes_Map?PRO_UID='. $_POST['form']['PRO_UID']); +die; diff --git a/workflow/engine/methods/processes/processes_webEntryGenerate.php b/workflow/engine/methods/processes/processes_webEntryGenerate.php new file mode 100644 index 000000000..7e44bc6b2 --- /dev/null +++ b/workflow/engine/methods/processes/processes_webEntryGenerate.php @@ -0,0 +1,150 @@ +PRO_UID; +$sTASKS = $oData->TASKS; +$sDYNAFORM = $oData->DYNAFORM; +$sWE_TYPE = $oData->WE_TYPE; +$sWS_USER = $oData->WS_USER; +$sWS_PASS = $oData->WS_PASS; +$sWS_ROUNDROBIN = $oData->WS_ROUNDROBIN; +$sWE_USR = $oData->WE_USR; + +$withWS = $sWE_TYPE == 'WS'; + +if (file_exists ( PATH_METHODS . 'login/version-pmos.php' )) { + include_once (PATH_METHODS . 'login/version-pmos.php'); +} else { + define ( 'PM_VERSION', 'Dev.' ); +} + +try { + $pathProcess = PATH_DATA_SITE . 'public' . PATH_SEP . $sPRO_UID . PATH_SEP; + G::mk_dir ( $pathProcess, 0777 ); + + $oTask = new Task ( ); + $TaskFields = $oTask->load ( $sTASKS ); + if ($TaskFields['TAS_ASSIGN_TYPE'] != 'BALANCED') { + throw (new Exception ( "The task '" . $TaskFields['TAS_TITLE'] . "' doesn't have a valid assignment type. The task needs to have a 'Cyclical Assignment'." )); + } + + G::LoadClass ( 'tasks' ); + $oTask = new Tasks ( ); + $user = $oTask->assignUsertoTask ( $sTASKS ); + + if ($user == 0) { + throw (new Exception ( "The task '" . $TaskFields['TAS_TITLE'] . "' doesn't have users." )); + } + + if (G::is_https ()) + $http = 'https://'; + else + $http = 'http://'; + + $sContent = ''; + + if ($withWS) { + //creating sys.info; + $SITE_PUBLIC_PATH = ''; + if (file_exists ( $SITE_PUBLIC_PATH . '' )) {} + + //creating the first file + require_once 'classes/model/Dynaform.php'; + $oDynaform = new Dynaform ( ); + $aDynaform = $oDynaform->load ( $sDYNAFORM ); + $dynTitle = str_replace ( ' ', '_', str_replace ( '/', '_', $aDynaform['DYN_TITLE'] ) ); + $sContent = "AddContent('dynaform', 'xmlform', '" . $sPRO_UID . '/' . $sDYNAFORM . "', '', array(), '" . $dynTitle . 'Post.php' . "');\n"; + $sContent .= "G::RenderPage('publish', 'blank');"; + file_put_contents ( $pathProcess . $dynTitle . '.php', $sContent ); + //creating the second file, the post file who receive the post form. + $pluginTpl = PATH_CORE . 'templates' . PATH_SEP . 'processes' . PATH_SEP . 'webentryPost.tpl'; + $template = new TemplatePower ( $pluginTpl ); + $template->prepare (); + $template->assign ( 'wsdlUrl', $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/wsdl2' ); + $template->assign ( 'wsUploadUrl', $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/upload' ); + $template->assign ( 'processUid', $sPRO_UID ); + $template->assign ( 'dynaformUid', $sDYNAFORM ); + $template->assign ( 'taskUid', $sTASKS ); + $template->assign ( 'wsUser', $sWS_USER ); + $template->assign ( 'wsPass', 'md5:' . md5 ( $sWS_PASS ) ); + $template->assign ( 'wsRoundRobin', $sWS_ROUNDROBIN ); + + if($sWE_USR == "2"){ + $template->assign ( 'USR_VAR', "\$cInfo = ws_getCaseInfo(\$caseId);\n\t \$USR_UID = \$cInfo->currentUsers->userId;" ); + } else { + $template->assign ( 'USR_VAR', '$USR_UID = -1;' ); + } + + + $template->assign ( 'dynaform', $dynTitle ); + $template->assign ( 'timestamp', date ( 'l jS \of F Y h:i:s A' ) ); + $template->assign ( 'ws', SYS_SYS ); + $template->assign ( 'version', PM_VERSION ); + + $fileName = $pathProcess . $dynTitle . 'Post.php'; + file_put_contents ( $fileName, $template->getOutputContent () ); + //creating the third file, only if this wsClient.php file doesn't exists. + $fileName = $pathProcess . 'wsClient.php'; + $pluginTpl = PATH_CORE . 'test' . PATH_SEP . 'unit' . PATH_SEP . 'ws' . PATH_SEP . 'wsClient.php'; + + if ( file_exists ($fileName) ) { + if( filesize($fileName) != filesize($pluginTpl) ){ + @copy($fileName, $pathProcess . 'wsClient.php.bck'); + @unlink($fileName); + + $template = new TemplatePower ( $pluginTpl ); + $template->prepare (); + file_put_contents ( $fileName, $template->getOutputContent () ); + } + } else { + $template = new TemplatePower ( $pluginTpl ); + $template->prepare (); + file_put_contents ( $fileName, $template->getOutputContent () ); + } + + //Show link + $link = $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/' . $sPRO_UID . '/' . $dynTitle . '.php'; + //print "\n $link "; + + + } else { + $G_FORM = new Form ( $sPRO_UID . '/' . $sDYNAFORM, PATH_DYNAFORM, SYS_LANG, false ); + $G_FORM->action = $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/cases_StartExternal.php'; + + $scriptCode = ''; + $scriptCode = $G_FORM->render ( PATH_CORE . 'templates/' . 'xmlform' . '.html', $scriptCode ); + $scriptCode = str_replace ( '/controls/', $http . $_SERVER['HTTP_HOST'] . '/controls/', $scriptCode ); + $scriptCode = str_replace ( '/js/maborak/core/images/', $http . $_SERVER['HTTP_HOST'] . '/js/maborak/core/images/', $scriptCode ); + + //render the template + $pluginTpl = PATH_CORE . 'templates' . PATH_SEP . 'processes' . PATH_SEP . 'webentry.tpl'; + $template = new TemplatePower ( $pluginTpl ); + $template->prepare (); + + $template->assign ( 'siteUrl', $http . $_SERVER['HTTP_HOST'] ); + $template->assign ( 'sysSys', SYS_SYS ); + $template->assign ( 'sysLang', SYS_LANG ); + $template->assign ( 'sysSkin', SYS_SKIN ); + $template->assign ( 'processUid', $sPRO_UID ); + $template->assign ( 'dynaformUid', $sDYNAFORM ); + $template->assign ( 'taskUid', $sTASKS ); + $template->assign ( 'dynFileName', $sPRO_UID . '/' . $sDYNAFORM ); + $template->assign ( 'formId', $G_FORM->id ); + $template->assign ( 'scriptCode', $scriptCode ); + + print_r ( '' ); + } + +} catch ( Exception $e ) { + $G_PUBLISH = new Publisher ( ); + $aMessage['MESSAGE'] = $e->getMessage (); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage ( 'publish', 'raw' ); +} \ No newline at end of file diff --git a/workflow/engine/methods/processes/processes_webEntryValidate.php b/workflow/engine/methods/processes/processes_webEntryValidate.php new file mode 100644 index 000000000..46ffd6059 --- /dev/null +++ b/workflow/engine/methods/processes/processes_webEntryValidate.php @@ -0,0 +1,96 @@ +PRO_UID; +$sTASKS = $oData->TASKS; +$sTASKS_SEL = $oData->TASKS_NAME; +//echo $sTASKS."
    "; +$sDYNAFORM = $oData->DYNAFORM; +$sWE_TYPE = $oData->WE_TYPE; +$sWS_USER = trim($oData->WS_USER); +$sWS_PASS = trim($oData->WS_PASS); +$sWS_ROUNDROBIN = $oData->WS_ROUNDROBIN; +$sWE_USR = $oData->WE_USR; + +//echo ($sPRO_UID."
    "); +//echo ($sTASKS."
    "); +//echo ($sDYNAFORM."
    "); + +if (G::is_https ()) + $http = 'https://'; + else + $http = 'http://'; + +$endpoint = $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/wsdl2'; +@$client = new SoapClient ( $endpoint ); + +$user = $sWS_USER; +$pass = $sWS_PASS; + +$params = array ('userid' => $user, 'password' => $pass ); +$result = $client->__SoapCall ( 'login', array ($params ) ); + +//$_SESSION ['WS_SESSION_ID'] = ''; + +//if ($result->status_code == 0) { +// $_SESSION ['WS_SESSION_ID'] = $result->message; +//} + +$fields ['status_code'] = $result->status_code; +$fields ['message'] = 'ProcessMaker WebService version: ' . $result->version . "\n" . $result->message; +$fields ['version'] = $result->version; +$fields ['time_stamp'] = $result->timestamp; +$messageCode = 1; + + +G::LoadClass ( 'Task' ); +G::LoadClass ( 'User' ); +G::LoadClass ( 'TaskUser' ); +G::LoadClass ( 'Groupwf' ); +/** + * note added by gustavo cruz gustavo-at-colosa-dot-com + * This is a little check to see if the GroupUser class has been declared or not. + * Seems that the problem its present in a windows installation of PM however. + * It's seems that could be replicated in a Linux server easily. + * I recomend that in some way check already if a imported class is declared + * somewhere else or maybe delegate the task to the G Class LoadClass method. + **/ +if(!class_exists('GroupUser')) { + G::LoadClass ( 'GroupUser' ); +} + // if the user has been authenticated, then check if has the rights or + // permissions to create the webentry + if ($result->status_code == 0) { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(TaskUserPeer::USR_UID); + $oCriteria->addSelectColumn(TaskUserPeer::TAS_UID); + $oCriteria->addJoin(TaskUserPeer::USR_UID, UsersPeer::USR_UID, Criteria::LEFT_JOIN); + $oCriteria->add(TaskUserPeer::TAS_UID, $sTASKS); + $oCriteria->add(UsersPeer::USR_USERNAME, $sWS_USER); + //$oCriteria->add(TaskUserPeer::TU_RELATION,1); + $userIsAssigned = TaskUserPeer::doCount($oCriteria); + // if the user is not assigned directly, maybe a have the task a group with the user + if($userIsAssigned<1) { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addJoin(UsersPeer::USR_UID, GroupUserPeer::USR_UID, Criteria::LEFT_JOIN); + $oCriteria->addJoin(GroupUserPeer::GRP_UID, TaskUserPeer::USR_UID, Criteria::LEFT_JOIN); + $oCriteria->add(TaskUserPeer::TAS_UID, $sTASKS); + $oCriteria->add(UsersPeer::USR_USERNAME, $sWS_USER); + $userIsAssigned = GroupUserPeer::doCount($oCriteria); + if (!($userIsAssigned>=1)) { + $messageCode = "The User \"".$sWS_USER."\" doesn't have the task \"".$sTASKS_SEL."\" assigned"; + } + } + + } else { + $messageCode = $result->message; + } + +echo ($messageCode); +?> diff --git a/workflow/engine/methods/processes/webEntry_Val_Assig.php b/workflow/engine/methods/processes/webEntry_Val_Assig.php new file mode 100644 index 000000000..e7f1fcfc0 --- /dev/null +++ b/workflow/engine/methods/processes/webEntry_Val_Assig.php @@ -0,0 +1,32 @@ +PRO_UID; +$sTASKS = $oData->TASKS; +$sDYNAFORM = $oData->DYNAFORM; + + +if (G::is_https ()) + $http = 'https://'; + else + $http = 'http://'; + +$endpoint = $http . $_SERVER['HTTP_HOST'] . '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/services/wsdl2'; +@$client = new SoapClient ( $endpoint ); + + +G::LoadClass ( 'Task' ); +G::LoadClass ( 'User' ); +G::LoadClass ( 'TaskUser' ); + +$oTask = new Task ( ); + $TaskFields = $oTask->kgetassigType ( $sPRO_UID, $sTASKS ); + +if ($TaskFields['TAS_ASSIGN_TYPE'] == 'BALANCED')echo 1; +else echo 0; + +?> diff --git a/workflow/engine/methods/reportTables/reportTables_Ajax.php b/workflow/engine/methods/reportTables/reportTables_Ajax.php new file mode 100644 index 000000000..1e2db9af7 --- /dev/null +++ b/workflow/engine/methods/reportTables/reportTables_Ajax.php @@ -0,0 +1,41 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadClass('case'); +switch($_POST['action']) { + case 'tableExists': + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ReportTablePeer::REP_TAB_NAME, $_POST['sTableName']); + $oDataset = ReportTablePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + if ($aRow = $oDataset->getRow()) { + echo '0'; + } + else { + echo '1'; + } + break; +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/reportTables/reportTables_Delete.php b/workflow/engine/methods/reportTables/reportTables_Delete.php new file mode 100644 index 000000000..46088a47f --- /dev/null +++ b/workflow/engine/methods/reportTables/reportTables_Delete.php @@ -0,0 +1,29 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +G::LoadClass('reportTables'); +$oReportTables = new ReportTables(); +$oReportTables->deleteReportTable($_POST['REP_TAB_UID']); +?> diff --git a/workflow/engine/methods/reportTables/reportTables_Edit.php b/workflow/engine/methods/reportTables/reportTables_Edit.php new file mode 100644 index 000000000..f9efa4f64 --- /dev/null +++ b/workflow/engine/methods/reportTables/reportTables_Edit.php @@ -0,0 +1,72 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +G::LoadClass('reportTables'); +G::LoadClass('xmlfield_InputPM'); +$aFields['FIELDS'] = array(); +if (isset($_GET['REP_TAB_UID'])) +{ + $oReportTable = new ReportTable(); + $aFields = $oReportTable->load($_GET['REP_TAB_UID']); + $aTheFields = getDynaformsVars($aFields['PRO_UID'], false); + $oReportTables = new ReportTables(); + $aVars = $oReportTables->getTableVars($_GET['REP_TAB_UID']); + $aFields['FIELDS'] = array(); + foreach ($aTheFields as $aField) { + if (in_array($aField['sName'], $aVars)) { + $aFields['FIELDS'][] = $aField['sName'] . '-' . $aField['sType']; + } + } +} +else +{ + $aFields['PRO_UID'] = $_GET['PRO_UID']; + $aFields['FIELDS'] = array(); + $aTheFields = getDynaformsVars($aFields['PRO_UID'], false); +} +$aProcessFields[] = array('FIELD_UID' => 'char', + 'FIELD_NAME' => 'char'); +$aTheFields = getDynaformsVars($aFields['PRO_UID'], false); +foreach ($aTheFields as $aField) { + $aProcessFields[] = array('FIELD_UID' => $aField['sName'] . '-' . $aField['sType'], + 'FIELD_NAME' => $aField['sName']); +} +$aProcessGridFields[] = array('FIELD_UID' => 'char', + 'FIELD_NAME' => 'char'); +$aTheFields = getGridsVars($aFields['PRO_UID']); +foreach ($aTheFields as $aField) { + $aProcessGridFields[] = array('FIELD_UID' => $aField['sName'] . '-' . $aField['sXmlForm'], + 'FIELD_NAME' => $aField['sName']); +} +global $_DBArray; +$_DBArray['processFields'] = $aProcessFields; +$_DBArray['processGridFields'] = $aProcessGridFields; +$_SESSION['_DBArray'] = $_DBArray; + +$aFields['LANG'] = SYS_LANG; +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'reportTables/reportTables_Edit', '', $aFields, '../reportTables/reportTables_Save'); +G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/reportTables/reportTables_Save.php b/workflow/engine/methods/reportTables/reportTables_Save.php new file mode 100644 index 000000000..1fa3c7a86 --- /dev/null +++ b/workflow/engine/methods/reportTables/reportTables_Save.php @@ -0,0 +1,94 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + +G::LoadClass('reportTables'); + +$oReportTable = new ReportTable(); +if (!isset($_POST['form']['REP_TAB_CONNECTION'])) { + $_POST['form']['REP_TAB_CONNECTION'] = 'report'; +} +if ($_POST['form']['REP_TAB_UID'] != '') { + $aReportTable = $oReportTable->load($_POST['form']['REP_TAB_UID']); + $sOldTableName = $aReportTable['REP_TAB_NAME']; + $sOldConnection = $aReportTable['REP_TAB_CONNECTION']; +} +else { + $sOldTableName = $_POST['form']['REP_TAB_NAME']; + $sOldConnection = $_POST['form']['REP_TAB_CONNECTION']; + $oReportTable->create($_POST['form']); + $_POST['form']['REP_TAB_UID'] = $oReportTable->getRepTabUid(); +} + +$oReportTable->update($_POST['form']); +$oReportVar = new ReportVar(); +$oReportTables = new ReportTables(); +$oReportTables->deleteAllReportVars($_POST['form']['REP_TAB_UID']); +$aFields = array(); +if ($_POST['form']['REP_TAB_TYPE'] == 'GRID') { + $aAux = explode('-', $_POST['form']['REP_TAB_GRID']); + global $G_FORM; + $G_FORM = new Form($_POST['form']['PRO_UID'] . '/' . $aAux[1], PATH_DYNAFORM, SYS_LANG, false); + $aAux = $G_FORM->getVars(false); + foreach ($aAux as $aField) { + $_POST['form']['FIELDS'][] = $aField['sName'] . '-' . $aField['sType']; + } +} +foreach ($_POST['form']['FIELDS'] as $sField) { + $aField = explode('-', $sField); + switch ($aField[1]) { + case 'currency': + case 'percentage': + $sType = 'number'; + break; + case 'text': + case 'password': + case 'dropdown': + case 'yesno': + case 'checkbox': + case 'radiogroup': + case 'hidden': + $sType = 'char'; + break; + case 'textarea': + $sType = 'text'; + break; + case 'date': + $sType = 'date'; + break; + default: + $sType = 'char'; + break; + } + $oReportVar->create(array('REP_TAB_UID' => $_POST['form']['REP_TAB_UID'], + 'PRO_UID' => $_POST['form']['PRO_UID'], + 'REP_VAR_NAME' => $aField[0], + 'REP_VAR_TYPE' => $sType)); + $aFields[] = array('sFieldName' => $aField[0], 'sType' => $sType); +} +$oReportTables->dropTable($sOldTableName, $sOldConnection); +$oReportTables->createTable($_POST['form']['REP_TAB_NAME'], $_POST['form']['REP_TAB_CONNECTION'], $_POST['form']['REP_TAB_TYPE'], $aFields); +$oReportTables->populateTable($_POST['form']['REP_TAB_NAME'], $_POST['form']['REP_TAB_CONNECTION'], $_POST['form']['REP_TAB_TYPE'], $aFields, $_POST['form']['PRO_UID'], $_POST['form']['REP_TAB_GRID']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/reports/reportsList.php b/workflow/engine/methods/reports/reportsList.php new file mode 100644 index 000000000..716848da5 --- /dev/null +++ b/workflow/engine/methods/reports/reportsList.php @@ -0,0 +1,144 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +switch ($RBAC->userCanAccess('PM_REPORTS')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'REPORTS'; + + $reports= array(); + + $reports[] = array('RPT_UID' => '', + 'RPT_TITLE' => '', + 'VIEW' => ''); + + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => 1, + 'RPT_TITLE' => G::LoadTranslation('ID_REPORT1'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => 2, + 'RPT_TITLE' => G::LoadTranslation('ID_REPORT2'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => 3, + 'RPT_TITLE' => G::LoadTranslation('ID_REPORT3'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => 4, + 'RPT_TITLE' => G::LoadTranslation('ID_REPORT4'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => 5, + 'RPT_TITLE' => G::LoadTranslation('ID_REPORT5'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + /*$reports[] = array('RPT_UID' => 6, + 'RPT_TITLE' => "Report 6",//G::LoadTranslation('ID_REPORT6'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_UID' => 7, + 'RPT_TITLE' => "Report 7",//G::LoadTranslation('ID_REPORT6'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_UID' => 8, + 'RPT_TITLE' => "Report 8",//G::LoadTranslation('ID_REPORT6'), + 'VIEW' => G::LoadTranslation('ID_VIEW')); + + $reports[] = array('RPT_UID' => 9, + 'RPT_TITLE' => "Report 9",//G::LoadTranslation('ID_REPORT6'), + 'VIEW' => G::LoadTranslation('ID_VIEW'));*/ + + + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $aAvailableReports = $oPluginRegistry->getReports(); + + //$aReports = array(); + foreach ($aAvailableReports as $sReportClass) { + + require_once PATH_PLUGINS. $sReportClass . PATH_SEP . 'class.' . $sReportClass . '.php'; + $sClassName = $sReportClass . 'Class'; + $oInstance = new $sClassName(); + $aReports = $oInstance->getAvailableReports(); + foreach ($aReports as $oReport ) { + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => $oReport['uid'], + 'RPT_TITLE' => $oReport['title'], + 'VIEW' => G::LoadTranslation('ID_VIEW')); + } + } + + //now check if there are customized reports inside the processes + if ( file_exists ( PATH_DATA_PUBLIC) && is_dir (PATH_DATA_PUBLIC) ) { + if ($handle = opendir( PATH_DATA_PUBLIC ) ) { + while ( false !== ($dir = readdir($handle)) ) { + if ( $dir[0] != '.' && file_exists( PATH_DATA_PUBLIC.$dir.PATH_SEP.'reports.php' ) ) { + include_once (PATH_DATA_PUBLIC.$dir.PATH_SEP.'reports.php'); + $className = 'report' . $dir; + if (class_exists ( $className )) { + $oReport = new $className(); + $aReports = $oReport->getAvailableReports(); + foreach ($aReports as $oReport ) { + $reports[] = array('RPT_NUMBER' => count($reports), + 'RPT_UID' => $oReport['uid'], + 'RPT_TITLE' => $oReport['title'], + 'VIEW' => G::LoadTranslation('ID_VIEW')); + } + } + } + } + } + closedir($handle); + } + + + global $_DBArray; + $_DBArray['reports'] = $reports; + + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('reports'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/reportsList', $oCriteria ); + G::RenderPage('publish'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/reports/reports_Dashboard.php b/workflow/engine/methods/reports/reports_Dashboard.php new file mode 100644 index 000000000..edb3c3cd5 --- /dev/null +++ b/workflow/engine/methods/reports/reports_Dashboard.php @@ -0,0 +1,62 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$_GET['sType'] = str_replace('?', '', $_GET['sType']); + +G::LoadClass('report'); +$oReport = new Report(); +switch($_GET['sType']) { + case 'ID_REPORT1': + $oCriteria = $oReport->generatedReport1(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report1_dashboard', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + case 'ID_REPORT2': + $oCriteria = $oReport->generatedReport2(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report2_dashboard', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + case 'ID_REPORT3': + $oCriteria = $oReport->generatedReport3(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report3_dashboard', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + case 'ID_REPORT4': + $oCriteria = $oReport->generatedReport4(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report4_dashboard', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + case 'ID_REPORT5': + $oCriteria = $oReport->generatedReport5(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report5_dashboard', $oCriteria); + G::RenderPage('publish', 'raw'); + break; +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/reports/reports_Description.php b/workflow/engine/methods/reports/reports_Description.php new file mode 100644 index 000000000..ea10f4107 --- /dev/null +++ b/workflow/engine/methods/reports/reports_Description.php @@ -0,0 +1,70 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +switch ($RBAC->userCanAccess('PM_REPORTS')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +G::LoadClass('xmlfield_InputPM'); + +$G_MAIN_MENU = 'processmaker'; +$G_ID_MENU_SELECTED = 'REPORTS'; + +$PRO_UID = $_POST['PRO_UID']; + +G::LoadClass('report'); +$oReport= new Report(); + +/* +$sw=0; +if(isset($_POST['FROM']) && isset($_POST['TO'])&& isset($_POST['STARTEDBY'])) +{ + if($_POST['FROM']!='0000-00-00' || $_POST['TO']!='0000-00-00')$sw=1; +} + +if($sw==0)*/ + $c = $oReport->descriptionReport1($PRO_UID); +/* +else + $c = $oReport->reports_Description_filter($_POST['FROM'], $_POST['TO'], $_POST['STARTEDBY'], $PRO_UID); +*/ +$fields['PRO_UID']=$PRO_UID; + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/reports_Description', $c ); +//$G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/reports_Description_search', '', $fields); +G::RenderPage('publish','raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/reports/reports_Duration.php b/workflow/engine/methods/reports/reports_Duration.php new file mode 100644 index 000000000..2d4f3fa09 --- /dev/null +++ b/workflow/engine/methods/reports/reports_Duration.php @@ -0,0 +1,98 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + + require_once 'classes/model/AppDelegation.php'; + + G::LoadClass('dates'); + $oDates = new dates(); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->addSelectColumn(AppDelegationPeer::TAS_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INIT_DATE); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_FINISH_DATE); + + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TaskPeer::TAS_UID); + $oCriteria->add(TaskPeer::TAS_UID, $aRow['TAS_UID']); + $oDataseti = TaskPeer::doSelectRS($oCriteria); + $oDataseti->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataseti->next(); + $b=0; + while ($aRows = $oDataseti->getRow()) { + if(TaskPeer::doCount($oCriteria) == 1) + $b=1; + $oDataseti->next(); + } + + if($b==1) + { + if($aRow['DEL_INIT_DATE']!=null && $aRow['DEL_FINISH_DATE']!=null) + { $fDuration = $oDates->calculateDuration($aRow['DEL_INIT_DATE'], $aRow['DEL_FINISH_DATE'], null, null, $aRow['TAS_UID']); + + $oCriteria = new Criteria('workflow'); + $sql = "UPDATE APP_DELEGATION SET DEL_DURATION='".$fDuration."' + WHERE APP_UID='".$aRow['APP_UID']."' AND DEL_INDEX='".$aRow['DEL_INDEX']."'"; + + + $con = Propel::getConnection("workflow"); + $stmt = $con->prepareStatement($sql); + $rs = $stmt->executeQuery(); + } + else + { + $oCriteria = new Criteria('workflow'); + $sql = "UPDATE APP_DELEGATION SET DEL_DURATION=0 + WHERE APP_UID='".$aRow['APP_UID']."' AND DEL_INDEX='".$aRow['DEL_INDEX']."'"; + + $con = Propel::getConnection("workflow"); + $stmt = $con->prepareStatement($sql); + $rs = $stmt->executeQuery(); + } + } + else + { + $oCriteria = new Criteria('workflow'); + $sql = "UPDATE APP_DELEGATION SET DEL_DURATION=0 + WHERE APP_UID='".$aRow['APP_UID']."' AND DEL_INDEX='".$aRow['DEL_INDEX']."'"; + + $con = Propel::getConnection("workflow"); + $stmt = $con->prepareStatement($sql); + $rs = $stmt->executeQuery(); + } + + $oDataset->next(); + } + +//G::header('location: reportsList'); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/reports/reports_View.php b/workflow/engine/methods/reports/reports_View.php new file mode 100644 index 000000000..3e3c10e11 --- /dev/null +++ b/workflow/engine/methods/reports/reports_View.php @@ -0,0 +1,278 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * Report - Report view + * @package ProcessMaker + * @author Everth S. Berrios Morales + * @copyright 2008 COLOSA + */ + +global $RBAC; +switch ($RBAC->userCanAccess('PM_REPORTS')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +try { + +//form type format hours in the form xml +G::LoadClass('xmlfield_InputPM'); + +$G_MAIN_MENU = 'processmaker'; +$G_ID_MENU_SELECTED = 'REPORTS'; + +$RPT_UID = $_GET['RPT_UID']; + + +switch($RPT_UID) +{ + case 1: + $sw=0; + if (isset($_POST['form'])) + { if($_POST['form']['FROM']!='0000-00-00' || $_POST['form']['TO']!='0000-00-00') $sw=1; + $fields['FROM']=$_POST['form']['FROM']; + $fields['TO']=$_POST['form']['TO']; + $fields['STARTEDBY']= $_POST['form']['STARTEDBY']; + } + else + { $fields['FROM']=date('Y-m-d'); + $fields['TO']=date('Y-m-d'); + } + + G::LoadClass('report'); + $oReport= new Report(); + if($sw==0) + $c = $oReport->generatedReport1(); + else + $c = $oReport->generatedReport1_filter($_POST['form']['FROM'], $_POST['form']['TO'], $_POST['form']['STARTEDBY']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/reports/reports.js'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report1', $c); + + if(isset($_POST['form'])) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report1_search', '', $fields); + else + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report1_search'); + + G::RenderPage('publish'); + break; + + case 2: + $sw=0; + if (isset($_POST['form'])) + { if($_POST['form']['FROM']!='0000-00-00' || $_POST['form']['TO']!='0000-00-00') $sw=1; + $fields['FROM']=$_POST['form']['FROM']; + $fields['TO']=$_POST['form']['TO']; + $fields['STARTEDBY']= $_POST['form']['STARTEDBY']; + } + else + { $fields['FROM']=date('Y-m-d'); + $fields['TO']=date('Y-m-d'); + } + + G::LoadClass('report'); + $oReport= new Report(); + + if($sw==0) + $c = $oReport->generatedReport2(); + else + $c = $oReport->generatedReport2_filter($_POST['form']['FROM'], $_POST['form']['TO'], $_POST['form']['STARTEDBY']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/reports/reports.js'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report2', $c ); + + if(isset($_POST['form'])) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report1_search', '', $fields); + else + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report1_search'); + G::RenderPage('publish'); + break; + + case 3: + $sw=0; + if (isset($_POST['form'])) + { + $sw=1; + $fields['PROCESS']=$_POST['form']['PROCESS']; + $fields['TASKS']=$_POST['form']['TASKS']; + } + else + { $fields['FROM']=date('Y-m-d'); + $fields['TO']=date('Y-m-d'); + } + + G::LoadClass('report'); + $oReport= new Report(); + + if($sw==0) + $c = $oReport->generatedReport3(); + else + $c = $oReport->generatedReport3_filter($_POST['form']['PROCESS'], $_POST['form']['TASKS']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/reports/reports.js'); + $G_PUBLISH = new Publisher; + + if(isset($_POST['form'])) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter', '', $fields); + else + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter'); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report3', $c); + + G::RenderPage('publish'); + break; + + case 4: + $sw=0; + if (isset($_POST['form'])) + { + $sw=1; + $fields['PROCESS']=$_POST['form']['PROCESS']; + $fields['TASKS']=$_POST['form']['TASKS']; + } + + G::LoadClass('report'); + $oReport= new Report(); + + if($sw==0) + $c = $oReport->generatedReport4(); + else + $c = $oReport->generatedReport4_filter($_POST['form']['PROCESS'], $_POST['form']['TASKS']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/reports/reports.js'); + $G_PUBLISH = new Publisher; + + if(isset($_POST['form'])) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter', '', $fields); + else + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter'); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report4', $c); + + G::RenderPage('publish'); + break; + + case 5: + $sw=0; + if (isset($_POST['form'])) + { + $sw=1; + $fields['PROCESS']=$_POST['form']['PROCESS']; + $fields['TASKS']=$_POST['form']['TASKS']; + } + + G::LoadClass('report'); + $oReport= new Report(); + + if($sw==0) + $c = $oReport->generatedReport5(); + else + $c = $oReport->generatedReport5_filter($_POST['form']['PROCESS'], $_POST['form']['TASKS']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/reports/reports.js'); + $G_PUBLISH = new Publisher; + + if(isset($_POST['form'])) + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter', '', $fields); + else + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'reports/report_filter'); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'reports/report5', $c); + + G::RenderPage('publish'); + break; + + default : + $foundReport = false; + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $aAvailableReports = $oPluginRegistry->getReports(); + foreach ($aAvailableReports as $sReportClass) { + + require_once PATH_PLUGINS. $sReportClass . PATH_SEP . 'class.' . $sReportClass . '.php'; + $sClassName = $sReportClass . 'Class'; + $oInstance = new $sClassName(); + $aReports = $oInstance->getAvailableReports(); + foreach ($aReports as $oReport) { + if ( $RPT_UID == $oReport['uid'] && method_exists( $oInstance, $RPT_UID )) { + $foundReport = true; + $result = $oInstance->{$RPT_UID} (); + + } + } + } + + //now check if there are customized reports inside the processes + if ( file_exists ( PATH_DATA_PUBLIC) && is_dir (PATH_DATA_PUBLIC) ) { + if ($handle = opendir( PATH_DATA_PUBLIC ) ) { + while ( false !== ($dir = readdir($handle)) ) { + if ( $dir[0] != '.' && file_exists( PATH_DATA_PUBLIC.$dir.PATH_SEP.'reports.php' ) ) { + include_once (PATH_DATA_PUBLIC.$dir.PATH_SEP.'reports.php'); + $className = 'report' . $dir; + if (class_exists ( $className )) { + $oInstance = new $className(); + $aReports = $oInstance->getAvailableReports(); + foreach ($aReports as $oReport ) { + if ( $RPT_UID == $oReport['uid'] && method_exists( $oInstance, $RPT_UID ) ) { + $foundReport = true; + $result = $oInstance->{$RPT_UID} (); + } + } + } + } + } + } + closedir($handle); + } + if ( !$foundReport ) + throw ( new Exception ( "Call to an nonexistent member function " . $RPT_UID . "() ") ); +} + +} +catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); +} + diff --git a/workflow/engine/methods/roles/roles_Ajax.php b/workflow/engine/methods/roles/roles_Ajax.php new file mode 100644 index 000000000..4c4cd8a2b --- /dev/null +++ b/workflow/engine/methods/roles/roles_Ajax.php @@ -0,0 +1,226 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$REQUEST = (isset($_GET['request']))?$_GET['request']:$_POST['request']; + +switch ($REQUEST) { + + case 'newRole': + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'roles/roles_New', '', ''); + G::RenderPage('publish', 'raw'); + break; + + case 'saveNewRole': + + $newid = md5($_POST['code'].date("d-M-Y_H:i:s")); + g::pr($_POST); + $aData['ROL_UID'] = $newid; + //$aData['ROL_PARENT'] = $_POST['parent']; + $aData['ROL_SYSTEM'] = '00000000000000000000000000000002'; + $aData['ROL_CODE'] = $_POST['code']; + $aData['ROL_NAME'] = $_POST['name']; + $aData['ROL_CREATE_DATE'] = date("Y-M-d H:i:s"); + $aData['ROL_UPDATE_DATE'] = date("Y-M-d H:i:s"); + $aData['ROL_STATUS'] = $_POST['status']; + $oCriteria = $RBAC->createRole($aData); + break; + + case 'editRole': + + $ROL_UID = $_GET['ROL_UID']; + $aFields = $RBAC->loadById($ROL_UID); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'roles/roles_Edit', '', $aFields); + G::RenderPage('publish', 'raw'); + break; + + case 'updateRole': + + $aData['ROL_UID'] = $_POST['rol_uid']; + //$aData['ROL_PARENT'] = $_POST['parent']; + $aData['ROL_CODE'] = $_POST['code']; + $aData['ROL_NAME'] = $_POST['name']; + $aData['ROL_UPDATE_DATE'] = date("Y-M-d H:i:s"); + $aData['ROL_STATUS'] = $_POST['status']; + $oCriteria = $RBAC->updateRole($aData); + break; + + case 'show': + G::LoadClass('ArrayPeer'); + $aRoles = $RBAC->getAllRoles(); + + $fields = Array( + 'ROL_UID'=>'char', + 'ROL_PARENT'=>'char', + 'ROL_SYSTEM'=>'char', + 'ROL_CREATE_DATE'=>'char', + 'ROL_UPDATE_DATE'=>'char', + 'ROL_STATUS'=>'char' + ); + + $rows = array_merge(Array($fields), $aRoles); + + global $_DBArray; + $_DBArray['virtual_roles'] = $rows; + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('virtual_roles'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'roles/roles_List', $oCriteria); + G::RenderPage('publish', 'raw'); + break; + + case 'deleteRole': + $oCriteria = $RBAC->removeRole($_POST['ROL_UID']); + break; + + case 'canDeleteRole': + + if($RBAC->numUsersWithRole($_POST['ROL_UID']) == 0){ + echo 'true'; + } else { + echo 'false'; + } + + break; + + case 'verifyNewRole': + $response = ($RBAC->verifyNewRole($_POST['code']))?'true':'false'; + print($response); + break; + + case 'updateDataRole': + $response = ($RBAC->verifyNewRole($_GET['code']))?'true':'false'; + print($response); + break; + + case 'usersIntoRole': + + $_GET['ROL_UID'] = (isset($_GET['ROL_UID']))?$_GET['ROL_UID']:$_POST['ROL_UID']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_Tree' ); + G::RenderPage('publish', 'raw'); + break; + + + + case 'deleteUserRole': + $USR_UID = $_POST['USR_UID']; + $ROL_UID = $_POST['ROL_UID']; + $RBAC->deleteUserRole($ROL_UID, $USR_UID); + + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_Tree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'showUsers': + $ROL_UID = $_POST['ROL_UID']; + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_AssignRole' ); + G::RenderPage('publish', 'raw'); + break; + + case 'showPermissions': + $ROL_UID = $_POST['ROL_UID']; + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_AssignPermissions' ); + G::RenderPage('publish', 'raw'); + break; + + case 'assignUserToRole': + $USR_UID = $_POST['USR_UID']; + $ROL_UID = $_POST['ROL_UID']; + $sData['USR_UID'] = $USR_UID; + $sData['ROL_UID'] = $ROL_UID; + $RBAC->assignUserToRole($sData); + + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_Tree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'assignPermissionToRole': + $USR_UID = $_POST['PER_UID']; + $ROL_UID = $_POST['ROL_UID']; + $sData['PER_UID'] = $USR_UID; + $sData['ROL_UID'] = $ROL_UID; + $RBAC->assignPermissionRole($sData); + + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_permissionsTree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'viewPermitions': + + $_GET['ROL_UID'] = (isset($_GET['ROL_UID']))?$_GET['ROL_UID']:$_POST['ROL_UID']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_permissionsTree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'deletePermissionRole': + $PER_UID = $_POST['PER_UID']; + $ROL_UID = $_POST['ROL_UID']; + $RBAC->deletePermissionRole($ROL_UID, $PER_UID); + + $_GET['ROL_UID'] = $ROL_UID; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'roles/roles_permissionsTree'); + G::RenderPage('publish', 'raw'); + break; + + default: echo 'default'; +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/methods/roles/roles_List.php b/workflow/engine/methods/roles/roles_List.php new file mode 100644 index 000000000..36938ae65 --- /dev/null +++ b/workflow/engine/methods/roles/roles_List.php @@ -0,0 +1,77 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $RBAC; + switch ($RBAC->userCanAccess('PM_USERS')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -3: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'ROLES'; + + require_once (PATH_RBAC . "model/RolesPeer.php"); + G::LoadClass('ArrayPeer'); + $aRoles = $RBAC->getAllRoles(); + + $fields = Array( + 'ROL_UID'=>'char', + 'ROL_PARENT'=>'char', + 'ROL_SYSTEM'=>'char', + 'ROL_CREATE_DATE'=>'char', + 'ROL_UPDATE_DATE'=>'char', + 'ROL_STATUS'=>'char' + ); + + $rows = array_merge(Array($fields), $aRoles); + + global $_DBArray; + $_DBArray['roles'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('roles'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'roles/roles_List', $oCriteria); + + G::RenderPage('publish','blank'); +?> + + + diff --git a/workflow/engine/methods/services/ColosaSchema.xsd b/workflow/engine/methods/services/ColosaSchema.xsd new file mode 100644 index 000000000..a61d8678f --- /dev/null +++ b/workflow/engine/methods/services/ColosaSchema.xsd @@ -0,0 +1,821 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + what goes here?? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + what type should Link be?? + + + + + Used with Link. What Type?? + + + + + if this can be a list of fields we may have to represent this as an element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Did not include properties for Grid Field: Grid,AddnewRows,DeleteRows + + + + + + + + + + + + Used for JavaScript field + + + + + + The last item in the enumeration is 'Grid'. Grid fields dont seem to work. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Instead of designing attribute sets for each field type, I have a generic attribute set for all fields. This could be further refined. + + + + + + + + + + + + + + + + + + + + + + + + + It is possible to have a list of all the users who are members of this group + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Comment describing your root element + + + + + + We will initially focus on a single process + + + + + This info is really separate from the Process Definitions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + could be simply string or string derived by restriction with an enumeration + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Here as a convenience to support access to all the Dynaforms in a Process. Each Dynamform will be referenced as a step in a task. I assume a Dynaform is re-usable. + + + + + Same comment as in Dynaforms + + + + + Same comment as in Dynaforms + + + + + Again a convenience to support access to all triggers in the process. Triggers are directly associated with steps. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Each Task has one derivation rule. A task with nothing else is a BPMN Gateway + + + + + + + + + + + + + + + + + + + + + + + Refers to a Field + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/methods/services/cases_StartExternal.php b/workflow/engine/methods/services/cases_StartExternal.php new file mode 100644 index 000000000..d2f231f43 --- /dev/null +++ b/workflow/engine/methods/services/cases_StartExternal.php @@ -0,0 +1,66 @@ +load( $_POST['TASKS'] ); + + $aDerivation['NEXT_TASK'] = $TaskFields; + $oDerivation = new Derivation(); + $deriva = $oDerivation->getNextAssignedUser($aDerivation); + + $oCase = new Cases(); + $aData = $oCase->startCase( $_POST['TASKS'], $deriva['USR_UID'] ); + + + $case = $oCase->loadCase($aData['APPLICATION'], 1); + + $Fields = array(); + $Fields['APP_NUMBER'] = $case['APP_NUMBER']; + $Fields['APP_PROC_STATUS'] = 'draft'; + $Fields['APP_DATA'] = $_POST['form']; + $Fields['DEL_INDEX'] = 1; + $Fields['TAS_UID'] = $_POST['TASKS']; + //$Fields = $oCase->loadCase($aData['APPLICATION'], 1); + $oCase->updateCase( $aData['APPLICATION'], $Fields ); + + $s=0; + if(isset($_SERVER['HTTP_REFERER'])) + { + $dir = explode('?', $_SERVER['HTTP_REFERER']); + if($dir[1]=='__flag__=1') + { $s=1; + } + else + { + $dire = explode('&', $dir[1]); + for($i=0; $i<=count($dire); $i++) + { + if($dire[$i]=='__flag__=1') + $s=1; + } + } + + //if(strpos($_SERVER['HTTP_REFERER'],'?') !== false) + if($s==1) + { G::header('location: ' . $_SERVER['HTTP_REFERER']); + } + else + { G::header('location: ' . $_SERVER['HTTP_REFERER'] . '?__flag__=1'); + } + } + else + echo G::LoadTranslation('ID_REQUEST_SENT'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + } + +?> \ No newline at end of file diff --git a/workflow/engine/methods/services/demoSoap.php b/workflow/engine/methods/services/demoSoap.php new file mode 100644 index 000000000..4c961d3be --- /dev/null +++ b/workflow/engine/methods/services/demoSoap.php @@ -0,0 +1,258 @@ + + + SugarCRM test webservices + + + +
    + +
    +
      +
      + End Point + +
      +
    +
    +
    + +
    +
    + login +
      +
      + User Id + Password + +
      +
    +
    +
    + +
    +
    + createUser +
      +
      + Session Id +
      +
      + User Id + + First Name + + Last Name + + Email + + Role + + +
      +
    +
    +
    + +
    +
    + assignUserToGroup +
      +
      + Session Id +
      +
      + User Id + + Group Id + +
      +
    +
    +
    + + +
    +
    + newCase +
      +
      + Session Id +
      +
      + Process Id + + Variables + +
      +
    +
    +
    + + $endpoint, + 'uri' => 'http://www.sugarcrm.com/sugarcrm', + 'soap_version' => SOAP_1_1, //SOAP_1_2 - 1.2 not supported by sugar nusoap + 'trace' => 1, + 'exceptions' => 0, + 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5 ) ); + + $params = array('user_name'=>$user, 'password'=>$pass , 'version'=>'1' ); + $result = $client->__SoapCall('login', array('user_auth'=>$params, 'application_name'=>'ProcessMaker')); + if ( $result->error->number == 0 ) { + $_SESSION['SESSION_ID'] = $result->id; + $session = $result->id; + + $res = $client->__getFunctions(); + krumo ( $res ); + + $params = array('session'=>$result->id); + $res = $client->__SoapCall('is_user_admin', array($session) ); + if ( $res == 1 ) print "is Administrator user"; + + + $first_name = 'juan'; + $last_name = 'perez'; + $phone = '7235131'; + $fax = '2454545'; + $companyname = 'ABC company'; + $prod_desc = 'descripcion del prod 1 '; + $user_guid = ''; + $set_entry_params = array( + 'session' => $session, + 'module_name' => 'Leads', + 'name_value_list'=>array( + array('name'=>'last_name', 'value'=> $last_name ), + array('name'=>'status', 'value'=> 'New' ), + array('name'=>'phone_work', 'value'=> $phone ), + array('name'=>'phone_fax', 'value'=> $fax ), + array('name'=>'account_name', 'value'=> $companyname ), + array('name'=>'lead_source', 'value'=> 'Web Site' ), + array('name'=>'description', 'value'=> $prod_desc ), + array('name'=>'email1', 'value'=> 'juan@colosa.com' ), + array('name'=>'assigned_user_id', 'value'=> $user_guid ))); + $res = $client->__SoapCall('set_entry', $set_entry_params ); + krumo ( $res ); + + //$query = "contacts.email1 != '' "; + //$orderby = 'email1 desc '; + $query = ''; + $orderby = ''; + $fields = array('id','first_name','last_name','account_name','account_id','email1','phone_work' ); + $params = array($session, 'Leads', $query, $orderby, 0, $fields, 100, false ); + $res = $client->__SoapCall('get_entry_list', $params ); + krumo ($res); + } + break; + case 'processList' : + $wsdl = PATH_METHODS . "services" . PATH_SEP . "pmos.wsdl"; + $endpoint = $wsdl; + $client = new SoapClient( $endpoint ); + $params = array('sessionId'=> $sessionId ); + $result = $client->__SoapCall('processesList', array($params)); + + krumo ( $result ); + die; + break; + default : + krumo ( $_POST );die; + } + +?> +
    +
      +
    • +
      + status_code + (Integer) + error->number ?> +
      +
      + message + (string) + error->name ?> +
      +
      + timestamp + (string) + error->description ?> +
      +
    • +
    +
    + + + diff --git a/workflow/engine/methods/services/login_getStarted.php b/workflow/engine/methods/services/login_getStarted.php new file mode 100644 index 000000000..948f87a21 --- /dev/null +++ b/workflow/engine/methods/services/login_getStarted.php @@ -0,0 +1,37 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$G_PUBLISH = new Publisher; +$oTemplatePower = new TemplatePower(PATH_TPL . 'services/login_getStarted.html'); +$oTemplatePower->prepare(); +/* +$oTemplatePower->newBlock('users'); +$oTemplatePower->assign('USR_UID', $aUser['USR_UID']); +$oTemplatePower->assign('USR_FULLNAME', $aData['USR_FIRSTNAME'] . ' ' . $aData['USR_LASTNAME'] . ' (' . $aData['USR_USERNAME'] . ')'); +*/ +$G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + +G::RenderPage('publish','raw'); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/services/pmos.wsdl b/workflow/engine/methods/services/pmos.wsdl new file mode 100644 index 000000000..cb1fc1ab7 --- /dev/null +++ b/workflow/engine/methods/services/pmos.wsdl @@ -0,0 +1,733 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/methods/services/pmos2.wsdl b/workflow/engine/methods/services/pmos2.wsdl new file mode 100755 index 000000000..c5c41ffdc --- /dev/null +++ b/workflow/engine/methods/services/pmos2.wsdl @@ -0,0 +1,1192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProcessMaker Web Service + + + + + diff --git a/workflow/engine/methods/services/processHeartBeat_Ajax.php b/workflow/engine/methods/services/processHeartBeat_Ajax.php new file mode 100644 index 000000000..1894d2a59 --- /dev/null +++ b/workflow/engine/methods/services/processHeartBeat_Ajax.php @@ -0,0 +1,213 @@ +setHeartbeatProperty('HB_BEAT_URL','http://heartbeat.processmaker.com/syspmLicenseSrv/en/green/services/beat','HEART_BEAT_CONF'); +switch ($request) { + case 'processInformation': + try{ + $heartBeatUrl = $oServerConf->getHeartbeatProperty('HB_BEAT_URL','HEART_BEAT_CONF'); + //Test connection + if(!(validateConnectivity($heartBeatUrl))){ + $oServerConf->setHeartbeatProperty('HB_NEXT_BEAT_DATE',strtotime ( "+1 day" ),'HEART_BEAT_CONF'); + throw new Exception("Heartbeat::No connection"); + } + //Build Data to be sent + $params=buildData(); + + //Send the information + postHeartBeat($params); + } catch (Exception $e) { + G::pr($e->getMessage()); + } + break; + +} + +function validateConnectivity($url){ + ini_set('allow_url_fopen', 1); + $sContent = file_get_conditional_contents($url); + $sw_connect=true; + //if ($sContent == '' || $sContent === false || strpos ( $sContent, 'address location' ) === false ) { 4 + if ($sContent == '' || $sContent === false ) { + $sw_connect=false; + } + return $sw_connect; +} +function file_get_conditional_contents($szURL){ + + + $pCurl = curl_init (); + curl_setopt ( $pCurl, CURLOPT_URL, $szURL ); + curl_setopt ( $pCurl, CURLOPT_RETURNTRANSFER, true ); + curl_setopt ( $pCurl, CURLOPT_HEADER, true ); + curl_setopt ( $pCurl, CURLOPT_FOLLOWLOCATION, false ); + curl_setopt ( $pCurl, CURLOPT_AUTOREFERER, true ); + //To avoid SSL error + curl_setopt ( $pCurl, CURLOPT_SSL_VERIFYHOST, 0 ); + curl_setopt ( $pCurl, CURLOPT_SSL_VERIFYPEER, 0); + + //To avoid timeouts + curl_setopt ( $pCurl, CURLOPT_CONNECTTIMEOUT, 10 ); + curl_setopt ( $pCurl, CURLOPT_TIMEOUT, 20 ); + + curl_setopt ( $pCurl, CURLOPT_NOPROGRESS, FALSE); + curl_setopt ( $pCurl, CURLOPT_VERBOSE, TRUE); + + + + $szContents = curl_exec($pCurl); + $aInfo = curl_getinfo($pCurl); + + $curl_session = curl_getinfo($pCurl, CURLINFO_HTTP_CODE); + $headers = curl_getinfo ( $pCurl ); + $header = substr ( $szContents, 0, $headers ['header_size'] ); + $content = substr ( $szContents, $headers ['header_size'] ); + + + if($aInfo['http_code'] === 200) + { + return $content; + } + + return false; +} +function buildData(){ +G::LoadClass ( 'serverConfiguration' ); +$oServerConf = & serverConf::getSingleton (); + if (! defined ( 'PM_VERSION' )) { + if (file_exists ( PATH_METHODS . 'login/version-pmos.php' )) { + require_once (PATH_METHODS . 'login/version-pmos.php'); + } else { + define ( 'PM_VERSION', 'Development Version' ); + } + } + + $os = ''; + if (file_exists ( '/etc/redhat-release' )) { + $fnewsize = filesize ( '/etc/redhat-release' ); + $fp = fopen ( '/etc/redhat-release', 'r' ); + $os = trim ( fread ( $fp, $fnewsize ) ); + fclose ( $fp ); + } + $os .= " (" . PHP_OS . ")"; + + + + + $params = array (); + $params ['ip'] = getenv ( 'SERVER_ADDR' ); + $oServerConf->setHeartbeatProperty('HB_BEAT_INDEX',intval($oServerConf->getHeartbeatProperty('HB_BEAT_INDEX','HEART_BEAT_CONF'))+1,'HEART_BEAT_CONF'); + + $params ['index'] = $oServerConf->getHeartbeatProperty('HB_BEAT_INDEX','HEART_BEAT_CONF');//$this->index; + $params ['beatType'] = is_null($oServerConf->getHeartbeatProperty('HB_BEAT_TYPE','HEART_BEAT_CONF'))?"starting":$oServerConf->getHeartbeatProperty('HB_BEAT_TYPE','HEART_BEAT_CONF');//1;//$this->beatType; + $params ['date'] = date ( 'Y-m-d H:i:s' ); + $params ['host'] = getenv ( 'SERVER_NAME' ); + $params ['os'] = $os; + $params ['webserver'] = getenv ( 'SERVER_SOFTWARE' ); + $params ['php'] = phpversion (); + $params ['pmVersion'] = PM_VERSION; + if(class_exists('pmLicenseManager')){ + $params ['pmProduct'] = 'PMEE'; + }else{ + $params ['pmProduct'] = 'PMCE'; + } + + $params ['logins'] = $oServerConf->logins; + $params ['workspaces'] = serialize ( $oServerConf->getWSList () ); + $params ['plugins'] = serialize ( $oServerConf->getPluginsList () ); + $params ['dbVersion'] = $oServerConf->getDBVersion(); + //$params ['errors'] = serialize( $oServerConf->errors ); + if($licInfo=$oServerConf->getProperty('LICENSE_INFO')){ + $params ['license'] = serialize ( $licInfo ); + } + return $params; +} + function postHeartBeat($params) { + if(is_array($params)){ + //No matter what happens with the result let's set the nextBeat to 2 hours from now + G::LoadClass ( 'serverConfiguration' ); + $oServerConf = & serverConf::getSingleton (); + $oServerConf->setHeartbeatProperty('HB_NEXT_BEAT_DATE',strtotime ( "+2 hour" ),'HEART_BEAT_CONF'); + $nextBeatDate = $oServerConf->getHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + + $heartBeatUrl = $oServerConf->getHeartbeatProperty('HB_BEAT_URL','HEART_BEAT_CONF'); + + $ch = curl_init (); + curl_setopt ( $ch, CURLOPT_URL, $heartBeatUrl ); + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); + curl_setopt ( $ch, CURLOPT_HEADER, true ); + curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, false ); + curl_setopt ( $ch, CURLOPT_AUTOREFERER, true ); + //To avoid SSL error + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, 0 ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); + + curl_setopt ( $ch, CURLOPT_POST, 1 ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $params ); + + //To avoid timeouts + curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); + curl_setopt ( $ch, CURLOPT_TIMEOUT, 20 ); + + $response = curl_exec ( $ch ); + $curl_session = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $headers = curl_getinfo ( $ch ); + $header = substr ( $response, 0, $headers ['header_size'] ); + $content = substr ( $response, $headers ['header_size'] ); + curl_close ( $ch ); + + if ($headers ['http_code'] == 200) { + $oServerConf->setHeartbeatProperty('HB_BEAT_TYPE','beat','HEART_BEAT_CONF'); + $oServerConf->resetLogins (); + $oServerConf->setHeartbeatProperty('HB_NEXT_BEAT_DATE',strtotime ( "+7 day" ),'HEART_BEAT_CONF'); + //Reset Errors + + } else { + //Catch the error + + $oServerConf->setHeartbeatProperty('HB_NEXT_BEAT_DATE',strtotime ( "+1 day" ),'HEART_BEAT_CONF'); + } + + } + /* + + $ch = curl_init (); + curl_setopt ( $ch, CURLOPT_URL, $heartBeatUrl ); + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); + curl_setopt ( $ch, CURLOPT_HEADER, true ); + curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, false ); + curl_setopt ( $ch, CURLOPT_AUTOREFERER, true ); + //To avoid SSL error + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, 0 ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); + + curl_setopt ( $ch, CURLOPT_POST, 1 ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $params ); + + //To avoid timeouts + curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); + curl_setopt ( $ch, CURLOPT_TIMEOUT, 20 ); + + $response = curl_exec ( $ch ); + $curl_session = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $headers = curl_getinfo ( $ch ); + $header = substr ( $response, 0, $headers ['header_size'] ); + $content = substr ( $response, $headers ['header_size'] ); + curl_close ( $ch ); + + if ($headers ['http_code'] == 200) { + $this->beatType = 'beat'; + $this->resetLogins (); + $this->nextBeatDate = strtotime ( "+7 day" ); //next beat in 7 days + //Reset Errors + $this->errors=array(); + } else { + //Catch the error + $this->errors[]=$curl_session; + $this->nextBeatDate = strtotime ( "+1 day" ); //retry in 30 mins + } + + $this->saveSingleton (); + */ + } \ No newline at end of file diff --git a/workflow/engine/methods/services/soap.php b/workflow/engine/methods/services/soap.php new file mode 100644 index 000000000..c8c5cb83d --- /dev/null +++ b/workflow/engine/methods/services/soap.php @@ -0,0 +1,449 @@ +login( $params->userid, $params->password ); + return $res->getPayloadArray ( ); + } + + function ProcessList( $params ) { + $x = ifPermission( $params->sessionId, 'PM_FACTORY'); + //if you are not an admin user, then this function will return only + //your valid process + if ( $x==0 ) { + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->processListVerified( $userId ); + return $res; + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->processList( ); + return array("processes" => $res ); + } + + function RoleList( $params ) { + $x = ifPermission( $params->sessionId, 'PM_USERS'); + if($x==0) + { + $result[] = array ( 'guid' => 24, 'name' => 'You do not have privileges' ); + return $result; + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->roleList( ); + return array("roles" => $res ); + } + + function GroupList( $params ) { + $x = ifPermission( $params->sessionId, 'PM_USERS'); + if($x==0) + { + $result[] = array ( 'guid' => 24, 'name' => 'You do not have privileges' ); + return $result; + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->groupList( ); + return array("groups" => $res ); + } + + function CaseList( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { + G::LoadClass('wsResponse'); + return new wsResponse (9, 'Session expired'); + } + + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->caseList( $userId ); + return array("cases" => $res ); + } + + function UserList( $params ) { + $x = ifPermission( $params->sessionId, 'PM_USERS'); + if($x==0) + { + $result[] = array ( 'guid' => 24, 'name' => 'You do not have privileges' ); + return $result; + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->userList( ); + return array("users" => $res ); + } + + function SendMessage( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->sendMessage( $params->caseId, + $params->from, + $params->to, + $params->cc, + $params->bcc, + $params->subject, + $params->template); + return $res->getPayloadArray ( ) ; + } + + function getCaseInfo( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->getCaseInfo( $params->caseId, $params->delIndex ); + return $res; + } + + function SendVariables( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $variables = $params->variables; + if ( is_object ($variables) ) { + $Fields[ $variables->name ]= $variables->value ; + } + + if ( is_array ( $variables) ) { + foreach ( $variables as $key=>$val ){ + $name = $val->name; + $value = $val->value; + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + } + $params->variables = $Fields; + $res = $ws->sendVariables($params->caseId, $params->variables); + return $res->getPayloadArray ( ) ; + } + + function GetVariables( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + + $res = $ws->getVariables($params->caseId, $params->variables); + return array("variables" => $res ); + } + + function DerivateCase( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + + $oSession = new Sessions(); + $user = $oSession->getSessionUser($params->sessionId); + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->derivateCase($user['USR_UID'], $params->caseId, $params->delIndex); + return $res; + + //return $res->getPayloadArray ( ); + } + + function executeTrigger ( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + + $oSession = new Sessions(); + $user = $oSession->getSessionUser($params->sessionId); + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $delIndex = ( isset ( $params->delIndex ) ) ? $params->delIndex : 1 ; + $res = $ws->executeTrigger( $user['USR_UID'], $params->caseId, $params->triggerIndex, $delIndex); + return $res->getPayloadArray ( ); + } + + function NewCaseImpersonate( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $variables = $params->variables; + foreach ( $variables as $key=>$val ){ + $name = $val->name; + $value = $val->value; + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + $params->variables = $Fields; + $res = $ws->newCaseImpersonate($params->processId, $params->userId, $params->variables); + return $res->getPayloadArray ( ) ; + } + + function NewCase( $params ) { + G::LoadClass('wsBase'); + G::LoadClass('sessions'); + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { + G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + $variables = $params->variables; + + if (!isset($params->variables) ) { + $variables = array(); + $Fields = array(); + } + else { + if ( is_object ($variables) ) { + /*foreach ( $variables as $key=>$val ) { + $name = $val->name; + $value = $val->value; + $Fields[ $val->name ]= $val->value ; + }*/ + $Fields[ $variables->name ]= $variables->value ; + } + + if ( is_array ( $variables) ) { + foreach ( $variables as $key=>$val ) { + $name = $val->name; + $value = $val->value; + if (!is_object($val->value)) + { + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + else + { + if (is_array($val->value->item)) { + $i = 1; + foreach ($val->value->item as $key1 => $val1) { + if (isset($val1->value)) { + if (is_array($val1->value->item)) { + foreach ($val1->value->item as $key2 => $val2) { + $Fields[$val->name][$i][$val2->key] = $val2->value; + } + } + } + $i++; + } + } + } + } + } + } + + $params->variables = $Fields; + //$result = new wsResponse (900, print_r($params->variables,1)); + //return $result; + $ws = new wsBase (); + $res = $ws->newCase($params->processId, $userId, $params->taskId, $params->variables); + return $res; + } + + function AssignUserToGroup( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_USERS'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('sessions'); + $sessions = new Sessions; + $user=$sessions->getSessionUser($params->sessionId); + if(!is_array($user)) + { G::LoadClass('wsResponse'); + return new wsResponse (3, 'User not registered in the system'); + } + + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->assignUserToGroup( $params->userId, $params->groupId); + return $res->getPayloadArray ( ) ; + } + + function CreateUser( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_USERS'); + if($x==0) + { G::LoadClass('wsResponse'); + $result = new wsResponse (24, "You do not have privileges"); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->createUser( $params->userId, $params->firstname, $params->lastname, $params->email, $params->role, $params->password); + return $res->getPayloadArray ( ) ; + } + + function TaskList( $params ) { + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { + $result[] = array ( 'guid' => 24, 'name' => 'You do not have privileges' ); + return $result; + } + G::LoadClass('wsBase'); + G::LoadClass('sessions'); + $ws = new wsBase (); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + $res = $ws->taskList( $userId ); + return array("tasks" => $res ); + } + + function TaskCase( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + $x = ifPermission( $params->sessionId, 'PM_CASES'); + if($x==0) + { + $result[] = array ( 'guid' => 24, 'name' => 'You do not have privileges' ); + return $result; + } + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->taskCase( $params->caseId ); + return array("taskCases" => $res ); + } + + function ReassignCase( $params ) { + ifSessionExpiredBreakThis($params->sessionId); + //G::LoadClass('wsResponse'); + //return new wsResponse (1, print_r($params,1)); + G::LoadClass('wsBase'); + $ws = new wsBase (); + $res = $ws->reassignCase($params->sessionId, $params->caseId, $params->delIndex, $params->userIdSource, $params->userIdTarget ); + return $res ; + } + + function ifSessionExpiredBreakThis($sessionId){ #added By Erik AO in datetime 26.06.2008 10:00:00 + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->verifySession($sessionId); + if($session == '') { + G::LoadClass('wsResponse'); + return new wsResponse (9, 'Session expired'); + } + } + + function ifPermission( $sessionId, $permission ){ + global $RBAC; + $RBAC->initRBAC(); + G::LoadClass('sessions'); + $oSession = new Sessions(); + $user = $oSession->getSessionUser($sessionId); + + $oRBAC = RBAC::getSingleton(); + $oRBAC->loadUserRolePermission($oRBAC->sSystem, $user['USR_UID']); + $aPermissions = $oRBAC->aUserInfo[$oRBAC->sSystem]['PERMISSIONS']; + $sw=0; + foreach ($aPermissions as $aPermission) { + if ($aPermission['PER_CODE'] == $permission) + { + $sw=1; + } + } + return $sw; + } +$server = new SoapServer( $wsdl ); +$server->addFunction("Login"); +$server->addFunction("ProcessList"); +$server->addFunction("CaseList"); +$server->addFunction("RoleList"); +$server->addFunction("GroupList"); +$server->addFunction("UserList"); +$server->addFunction("SendMessage"); +$server->addFunction("SendVariables"); +$server->addFunction("GetVariables"); +$server->addFunction("DerivateCase"); +$server->addFunction("executeTrigger"); +$server->addFunction("NewCaseImpersonate"); +$server->addFunction("NewCase"); +$server->addFunction("AssignUserToGroup"); +$server->addFunction("CreateUser"); +$server->addFunction("getCaseInfo"); +$server->addFunction("TaskList"); +$server->addFunction("TaskCase"); +$server->addFunction("ReassignCase"); + +$server->handle(); + diff --git a/workflow/engine/methods/services/soap2.php b/workflow/engine/methods/services/soap2.php new file mode 100644 index 000000000..21fce5036 --- /dev/null +++ b/workflow/engine/methods/services/soap2.php @@ -0,0 +1,821 @@ +login( $params->userid, $params->password ); + return array( + 'status_code' => $res->status_code , + 'message' => $res->message, + 'version' => WEB_SERVICE_VERSION, + 'timestamp' => $res->timestamp + ); + } + + function ProcessList( $params ) { + + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("processes" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_FACTORY') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("processes" => $o); + } + + /** if you are not an admin user, then this function will return only your valid process **/ + if ( ifPermission( $params->sessionId, 'PM_FACTORY') == 0 ) { + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + $ws = new wsBase (); + $res = $ws->processListVerified( $userId ); + return array("processes" => $res ); + } + + $ws = new wsBase(); + $res = $ws->processList(); + return array("processes" => $res ); + } + + function RoleList( $params ) { + + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("roles" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("roles" => $o); + } + + $ws = new wsBase (); + $res = $ws->roleList(); + return array("roles" => $res ); + } + + function GroupList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("groups" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("groups" => $o); + } + + $ws = new wsBase (); + $res = $ws->groupList(); + return array("groups" => $res ); + } + + function DepartmentList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("departments" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("departments" => $o); + } + + $ws = new wsBase (); + $res = $ws->departmentList(); + return array("departments" => $res ); + } + + function CaseList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + $o->status = ''; + $o->delIndex = ''; + return array("cases" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + $o->status = ''; + $o->delIndex = ''; + return array("cases" => $o); + } + + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + $ws = new wsBase (); + $res = $ws->caseList( $userId ); + return array("cases" => $res ); + } + + function UserList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("users" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("users" => $o); + } + + $ws = new wsBase (); + $res = $ws->userList(); + return array("users" => $res ); + } + + function triggerList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + $o->processId = ''; + return array("triggers" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + $o->processId = ''; + return array("triggers" => $o); + } + + $ws = new wsBase (); + $res = $ws->triggerList(); + return array("triggers" => $res ); + } + + function outputDocumentList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->filename = ''; + $o->docId = ''; + $o->version = ''; + $o->createDate = ''; + $o->createBy = ''; + $o->type = ''; + $o->index = ''; + $o->link = ''; + return array("documents" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->filename = ''; + $o->docId = ''; + $o->version = ''; + $o->createDate = ''; + $o->createBy = ''; + $o->type = ''; + $o->index = ''; + $o->link = ''; + return array("documents" => $o); + } + + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + + $ws = new wsBase (); + $res = $ws->outputDocumentList( $params->caseId, $userId ); + return array("documents" => $res ); + } + + function inputDocumentList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->filename = ''; + $o->docId = ''; + $o->version = ''; + $o->createDate = ''; + $o->createBy = ''; + $o->type = ''; + $o->index = ''; + $o->link = ''; + return array("documents" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->filename = ''; + $o->docId = ''; + $o->version = ''; + $o->createDate = ''; + $o->createBy = ''; + $o->type = ''; + $o->index = ''; + $o->link = ''; + return array("documents" => $o); + } + + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + + $ws = new wsBase (); + $res = $ws->inputDocumentList( $params->caseId, $userId ); + return array("documents" => $res ); + } + + function inputDocumentProcessList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + $o->description = ''; + return array("documents" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + $o->description = ''; + return array("documents" => $o); + } + + $ws = new wsBase (); + $res = $ws->inputDocumentProcessList( $params->processId ); + return array("documents" => $res); + } + + function removeDocument( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You have not privileges to execute this function"); + return $result; + } + + $ws = new wsBase (); + $res = $ws->removeDocument( $params->appDocUid ); + return $res; + } + + function SendMessage( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult->getPayloadArray(); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ) { + $result = new wsResponse (2, "You do not have privileges"); + return $result->getPayloadArray(); + } + + $ws = new wsBase (); + $res = $ws->sendMessage( + $params->caseId, + $params->from, + $params->to, + $params->cc, + $params->bcc, + $params->subject, + $params->template + ); + return $res->getPayloadArray() ; + } + + function getCaseInfo( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ) { + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $ws = new wsBase (); + $res = $ws->getCaseInfo( $params->caseId, $params->delIndex ); + return $res; + } + + function SendVariables( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ) { + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $ws = new wsBase(); + $variables = $params->variables; + $Fields = Array(); + if ( is_object($variables) ) { + $Fields[$variables->name] = $variables->value; + } else if ( is_array($variables) ) { + foreach ( $variables as $index=>$obj ) { + if ( is_object($obj) && isset($obj->name) && isset($obj->value)){ + $Fields[$obj->name] = $obj->value; + } + } + } + + $params->variables = $Fields; + $res = $ws->sendVariables($params->caseId, $params->variables); + + return $res->getPayloadArray(); + + } + + function GetVariables( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsGetVariableResponse (2, "You do not have privileges", NULL ); + return $result; + } + + $ws = new wsBase (); + + $res = $ws->getVariables($params->caseId, $params->variables); + return $res; + } + + function DerivateCase( $params ) { + $oSession = new Sessions(); + + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $user = $oSession->getSessionUser($params->sessionId); + + $oStd->stored_system_variables = true; + $oStd->wsSessionId = $params->sessionId; + $ws = new wsBase($oStd); + $res = $ws->derivateCase($user['USR_UID'], $params->caseId, $params->delIndex); + return $res; + } + + function RouteCase( $params ) { + $oSession = new Sessions(); + + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $user = $oSession->getSessionUser($params->sessionId); + + $oStd->stored_system_variables = true; + $oStd->wsSessionId = $params->sessionId; + $ws = new wsBase($oStd); + $res = $ws->derivateCase($user['USR_UID'], $params->caseId, $params->delIndex); + return $res; + + //return $res->getPayloadArray ( ); + } + + function executeTrigger ( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $oSession = new Sessions(); + $user = $oSession->getSessionUser($params->sessionId); + + + $ws = new wsBase (); + $delIndex = ( isset ( $params->delIndex ) ) ? $params->delIndex : 1 ; + $res = $ws->executeTrigger( $user['USR_UID'], $params->caseId, $params->triggerIndex, $delIndex); + return $res->getPayloadArray ( ); + } + + function NewCaseImpersonate( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $ws = new wsBase (); + $variables = $params->variables; + foreach ( $variables as $key=>$val ){ + $name = $val->name; + $value = $val->value; + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + $params->variables = $Fields; + $res = $ws->newCaseImpersonate($params->processId, $params->userId, $params->variables); + return $res->getPayloadArray ( ) ; + } + + function NewCase( $params ) { + + G::LoadClass('sessions'); + + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if ( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result; + } + + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + $variables = $params->variables; + +/* this code is for previous version of ws, and apparently this will work for grids inside the variables.. + if (!isset($params->variables) ) { + $variables = array(); + $Fields = array(); + } + else { + if ( is_object ($variables) ) { + $Fields[ $variables->name ]= $variables->value ; + } + + if ( is_array ( $variables) ) { + foreach ( $variables as $key=>$val ) { + $name = $val->name; + $value = $val->value; + if (!is_object($val->value)) + { + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + else + { + if (is_array($val->value->item)) { + $i = 1; + foreach ($val->value->item as $key1 => $val1) { + if (isset($val1->value)) { + if (is_array($val1->value->item)) { + foreach ($val1->value->item as $key2 => $val2) { + $Fields[$val->name][$i][$val2->key] = $val2->value; + } + } + } + $i++; + } + } + } + } + } + } +*/ + $variables = $params->variables; + + + if ( is_object ($variables) ) { + $Fields[ $variables->name ]= $variables->value ; + } + if ( is_array ( $variables) ) { + foreach ( $variables as $key=>$val ) { + if (!is_object($val->value)){ + eval('$Fields[ ' . $val->name . ' ]= $val->value ;'); + } + } + } + $params->variables = $Fields; + $ws = new wsBase (); + $res = $ws->newCase($params->processId, $userId, $params->taskId, $params->variables); + + ###################################################################### + # we need to register the case id for a stored session variable. like a normal Session. + ###################################################################### + $oSessions->registerGlobal('APPLICATION', $res->caseId); + ###################################################################### + + return $res; + } + + function AssignUserToGroup( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult->getPayloadArray(); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result->getPayloadArray(); + } + G::LoadClass('sessions'); + $sessions = new Sessions; + $user=$sessions->getSessionUser($params->sessionId); + + if(!is_array($user)){ + return new wsResponse (3, 'User not registered in the system'); + } + + + $ws = new wsBase (); + $res = $ws->assignUserToGroup( $params->userId, $params->groupId); + return $res->getPayloadArray(); + } + + function AssignUserToDepartment( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult->getPayloadArray(); + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ){ + $result = new wsResponse (2, "You do not have privileges"); + return $result->getPayloadArray(); + } + G::LoadClass('sessions'); + $sessions = new Sessions; + $user=$sessions->getSessionUser($params->sessionId); + + if(!is_array($user)){ + return new wsResponse (3, 'User not registered in the system'); + } + + + $ws = new wsBase (); + $res = $ws->AssignUserToDepartment( $params->userId, $params->departmentId, $params->manager ); + return $res->getPayloadArray(); + } + + function CreateUser( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0){ + $result = new wsCreateUserResponse (2, "You do not have privileges"); + return $result; + } + + $ws = new wsBase (); + $res = $ws->createUser( $params->userId, $params->firstname, $params->lastname, $params->email, $params->role, $params->password); + return $res; + } + + function CreateGroup( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $result = new wsCreateGroupResponse ($vsResult->status_code , $vsResult->message, '' ); + return $result; + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0 ) { + $result = new wsCreateGroupResponse (2, "You do not have privileges", ''); + return $result; + } + + $ws = new wsBase (); + $res = $ws->createGroup( $params->name ); + return $res; + } + + function CreateDepartment( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + if( ifPermission( $params->sessionId, 'PM_USERS') == 0){ + $result = new wsCreateUserResponse (2, "You do not have privileges"); + return $result; + } + + $ws = new wsBase (); + $res = $ws->CreateDepartment( $params->name, $params->parentUID ); + return $res; + } + + function TaskList( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("tasks" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("tasks" => $o); + } + + G::LoadClass('sessions'); + $ws = new wsBase (); + $oSessions = new Sessions(); + $session = $oSessions->getSessionUser($params->sessionId); + $userId = $session['USR_UID']; + $res = $ws->taskList( $userId ); + return array("tasks" => $res ); + } + + function TaskCase( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + $o->guid = $vsResult->status_code. ' ' . $vsResult->message; + $o->name = ''; + return array("taskCases" => $o); + } + + if( ifPermission( $params->sessionId, 'PM_CASES') == 0 ){ + $o->guid = "2 You have not privileges to execute this function"; + $o->name = ''; + return array("taskCases" => $o); + } + + $ws = new wsBase (); + $res = $ws->taskCase( $params->caseId ); + return array("taskCases" => $res ); + } + + function ReassignCase( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + $ws = new wsBase (); + $res = $ws->reassignCase($params->sessionId, $params->caseId, $params->delIndex, $params->userIdSource, $params->userIdTarget ); + return $res ; + } + + function systemInformation( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + $ws = new wsBase (); + $res = $ws->systemInformation( ); + return $res; + } + + function importProcessFromLibrary( $params ) { + $vsResult = isValidSession($params->sessionId); + if( $vsResult->status_code !== 0 ){ + return $vsResult; + } + + $ws = new wsBase (); + $res = $ws->importProcessFromLibrary( $params->processId ,$params->version ,$params->importOption ,$params->usernameLibrary ,$params->passwordLibrary ); + return $res; + } + + /*************/ + + #added By Erik AO in datetime 26.06.2008 10:00:00 + # modified 12-01-2010 by erik + + function isValidSession($sessionId){ + G::LoadClass('sessions'); + $oSessions = new Sessions(); + $session = $oSessions->verifySession($sessionId); + if( is_array($session) ) { + return new wsResponse (0, 'Session active'); + } else { + + return new wsResponse (9, 'Session expired'); + } + } + + function ifPermission( $sessionId, $permission ){ + global $RBAC; + $RBAC->initRBAC(); + G::LoadClass('sessions'); + $oSession = new Sessions(); + $user = $oSession->getSessionUser($sessionId); + + $oRBAC = RBAC::getSingleton(); + $oRBAC->loadUserRolePermission($oRBAC->sSystem, $user['USR_UID']); + $aPermissions = $oRBAC->aUserInfo[$oRBAC->sSystem]['PERMISSIONS']; + $sw=0; + foreach ($aPermissions as $aPermission) { + if ($aPermission['PER_CODE'] == $permission) + { + $sw=1; + } + } + return $sw; + } + + +$server = new SoapServer( $wsdl ); +$server->addFunction("Login"); +$server->addFunction("ProcessList"); +$server->addFunction("CaseList"); +$server->addFunction("RoleList"); +$server->addFunction("GroupList"); +$server->addFunction("DepartmentList"); +$server->addFunction("UserList"); +$server->addFunction("TriggerList"); +$server->addFunction("outputDocumentList"); +$server->addFunction("inputDocumentList"); +$server->addFunction("inputDocumentProcessList"); +$server->addFunction("removeDocument"); +$server->addFunction("SendMessage"); +$server->addFunction("SendVariables"); +$server->addFunction("GetVariables"); +$server->addFunction("DerivateCase"); +$server->addFunction("RouteCase"); +$server->addFunction("executeTrigger"); +$server->addFunction("NewCaseImpersonate"); +$server->addFunction("NewCase"); +$server->addFunction("AssignUserToGroup"); +$server->addFunction("AssignUserToDepartment"); +$server->addFunction("CreateGroup"); +$server->addFunction("CreateDepartment"); +$server->addFunction("CreateUser"); +$server->addFunction("getCaseInfo"); +$server->addFunction("TaskList"); +$server->addFunction("TaskCase"); +$server->addFunction("ReassignCase"); +$server->addFunction("systemInformation"); +$server->addFunction("importProcessFromLibrary"); + +$server->handle(); + diff --git a/workflow/engine/methods/services/upload.php b/workflow/engine/methods/services/upload.php new file mode 100644 index 000000000..f3455ec9d --- /dev/null +++ b/workflow/engine/methods/services/upload.php @@ -0,0 +1,126 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * @Updated Dec 14, 2009 by Erik + * + * The point of this application is upload the file and create the input document record + * + * if the post attached file has error code 0 continue in other case nothing to do. */ + +if (isset($_FILES) && $_FILES['ATTACH_FILE']['error'] == 0) { + try{ + G::loadClass('case'); + $folderId = $fileTags = ""; + if ( isset($_POST['DOC_UID']) && $_POST['DOC_UID'] != - 1) { + /* the document is of an Specific Input Document. Get path and Tag information*/ + + require_once ('classes/model/AppFolder.php'); + require_once ('classes/model/InputDocument.php'); + + $oInputDocument = new InputDocument(); + $aID = $oInputDocument->load($_POST['DOC_UID']); + + //Get the Custom Folder ID (create if necessary) + $oFolder = new AppFolder(); + $folderId = $oFolder->createFromPath($aID['INP_DOC_DESTINATION_PATH'], $_POST['APPLICATION']); + + //Tags + $fileTags = $oFolder->parseTags($aID['INP_DOC_TAGS'], $_POST['APPLICATION']); + } + + $oAppDocument = new AppDocument(); + if (isset($_POST['APP_DOC_UID']) && trim($_POST['APP_DOC_UID']) != '') { //is update + echo '[update]'; + $aFields['APP_DOC_UID'] = $_POST['APP_DOC_UID']; + $aFields['DOC_VERSION'] = $_POST['DOC_VERSION']; + $aFields['APP_DOC_FILENAME'] = $_FILES['ATTACH_FILE']['name']; + + if( isset($_POST['APPLICATION']) ) + $aFields['APP_UID'] = $_POST['APPLICATION']; + if( isset($_POST['INDEX']) ) + $aFields['DEL_INDEX'] = $_POST['INDEX']; + if( isset($_POST['USR_UID']) ) + $aFields['USR_UID'] = $_POST['USR_UID']; + if( isset($_POST['DOC_UID']) ) + $aFields['DOC_UID'] = $_POST['DOC_UID']; + if( isset($_POST['APP_DOC_TYPE']) ) + $aFields['APP_DOC_TYPE']= $_POST['APP_DOC_TYPE']; + $aFields['APP_DOC_CREATE_DATE'] = date('Y-m-d H:i:s'); + + $aFields['APP_DOC_COMMENT'] = isset($_POST['COMMENT']) ? $_POST['COMMENT'] : ''; + $aFields['APP_DOC_TITLE'] = isset($_POST['TITLE']) ? $_POST['TITLE'] : ''; + + //$aFields['FOLDER_UID'] = $folderId, + //$aFields['APP_DOC_TAGS']= $fileTags + + $oAppDocument->create($aFields); + + } else { //new record + $aFields = array ( + 'APP_UID' => $_POST['APPLICATION'], + 'DEL_INDEX' => $_POST['INDEX'], + 'USR_UID' => $_POST['USR_UID'], + 'DOC_UID' => $_POST['DOC_UID'], + 'APP_DOC_TYPE' => $_POST['APP_DOC_TYPE'], + 'APP_DOC_CREATE_DATE' => date('Y-m-d H:i:s'), + 'APP_DOC_COMMENT' => isset($_POST['COMMENT']) ? $_POST['COMMENT'] : '', + 'APP_DOC_TITLE' => isset($_POST['TITLE']) ? $_POST['TITLE'] : '', + 'APP_DOC_FILENAME' => isset($_FILES['ATTACH_FILE']['name']) ? $_FILES['ATTACH_FILE']['name'] : '', + 'FOLDER_UID' => $folderId, + 'APP_DOC_TAGS' => $fileTags + ); + + $oAppDocument->create($aFields); + } + + $sAppUid = $oAppDocument->getAppUid(); + $sAppDocUid = $oAppDocument->getAppDocUid(); + $iDocVersion = $oAppDocument->getDocVersion(); + $info = pathinfo($oAppDocument->getAppDocFilename()); + $ext = (isset($info['extension']) ? $info['extension'] : ''); + + //save the file + echo $sPathName = PATH_DOCUMENT . $sAppUid . PATH_SEP; + echo $sFileName = $sAppDocUid . '_' . $iDocVersion . '.' . $ext; + print G::uploadFile($_FILES['ATTACH_FILE']['tmp_name'], $sPathName, $sFileName); + print("* The file {$_FILES['ATTACH_FILE']['name']} was uploaded successfully in case {$sAppUid} as input document..\n"); + + //Plugin Hook PM_UPLOAD_DOCUMENT for upload document + $oPluginRegistry = & PMPluginRegistry::getSingleton(); + if ($oPluginRegistry->existsTrigger(PM_UPLOAD_DOCUMENT) && class_exists('uploadDocumentData')) { + $oData['APP_UID'] = $_POST['APPLICATION']; + $documentData = new uploadDocumentData($_POST['APPLICATION'], $_POST['USR_UID'], $sPathName . $sFileName, $aFields['APP_DOC_FILENAME'], $sAppDocUid); + + $oPluginRegistry->executeTriggers(PM_UPLOAD_DOCUMENT, $documentData); + unlink($sPathName . $sFileName); + } + /*end plugin*/ + } catch ( Exception $e) { + print( $e->getMessage() ); + } +} + + diff --git a/workflow/engine/methods/services/webdav.php b/workflow/engine/methods/services/webdav.php new file mode 100644 index 000000000..8848b30d0 --- /dev/null +++ b/workflow/engine/methods/services/webdav.php @@ -0,0 +1,51 @@ +VerifyLogin($_SERVER['PHP_AUTH_USER'] , $_SERVER['PHP_AUTH_PW'] ); + if ( $uid > 0 ) { + // Asign the uid of user to userloggedobj + $RBAC->loadUserRolePermission($RBAC->sSystem, $uid); + $res = $RBAC->userCanAccess('PM_WEBDAV'); + if ($res != 1 ) { + if ($res == -2) + $msg = G::LoadTranslation ('ID_USER_HAVENT_RIGHTS_SYSTEM'); + else + $msg = G::LoadTranslation ('ID_USER_HAVENT_RIGHTS_PAGE'); + header('WWW-Authenticate: Basic realm="'.$realm.'"'); + header('HTTP/1.0 401 ' . $msg ); + die('401 ' . $msg); + return FALSE; + die; + } + + return TRUE; + } + + header('WWW-Authenticate: Basic realm="'.$realm.'"'); + header('HTTP/1.0 401 Unauthorized'); + die('401 Unauthorized'); + return FALSE; +} + + $realm = 'ProcessMaker Filesystem for Workspace ' . SYS_SYS; + + # Choice an authentification type Digest or Basic + //AuthenticationDigestHTTP($realm, $users, $phpcgi); + AuthenticationBasicHTTP($realm ); + + G::LoadClass ( "webdav" ); + + $server = new ProcessMakerWebDav(); + + # Real path of your site + $server->ServeRequest( ""); + diff --git a/workflow/engine/methods/services/wsdl.php b/workflow/engine/methods/services/wsdl.php new file mode 100644 index 000000000..5cc9d11d6 --- /dev/null +++ b/workflow/engine/methods/services/wsdl.php @@ -0,0 +1,14 @@ +login( $username, $password ); + return $res->getPayloadArray ( ) ; + } + + function wsBaseProcessList( $studentName ) { + G::LoadClass('wsBase'); + $ws = new wsBase (); + $result = $ws->processList (); + //$result[] = array ( 'guid' => 'a' . $studentName , 'name' => 'bc' ); + //$result[] = array ( 'guid' => '2a' , 'name' => '2bc' . $studentName ); + //$result[] = array ( 'guid' => '2a' , 'name' => '2bc' . $studentName ); + return array("processes"=> $result); + //return array ( "status_code" => 12, "message" => 'abx', "timestamp" => 'aa' ); + } + + +/* Map of the service operation "ExamResult" to php function "ExamResult" */ +$operations = array( "processesList" => "wsBaseProcessList", + "login" => "wsBaseLogin" + ); + +/* just tell your function parameters should be in mixed format, + that is here parameter will be the string with the name in it*/ + +$opParams = array("wsBaseProcessList" => "MIXED", + "wsBaseLogin" => "MIXED"); + +//$wsdl = PATH_METHODS . "services" . PATH_SEP . "pmos.wsdl"; +$wsdl = "/home/fernando/processmaker/trunk/workflow/engine/methods/services/pmos.wsdl"; +echo $wsdl; +echo file_get_contents($wsdl); +die(); +/* Created the WSService */ +$svr = new WSService(array("wsdl" => $wsdl , + "operations" => $operations, + "opParams" => $opParams)); + +/* Reply the client */ +$svr->reply(); + +die; + +?> +str); + $username = (string)$simplexml->username; + $password = (string)$simplexml->password; + + $wsResponse = $ws->login ( $username, $password ); + $res = $wsResponse->getPayloadString( 'loginResponse' ); + return new WSMessage($res); + } + + function wsBaseListOfProcess( $inMessage ) { + + G::LoadClass('wsBase'); + $ws = new wsBase (); + + $simplexml = new SimpleXMLElement($inMessage->str); + //$username = (string)$simplexml->username; + //$password = (string)$simplexml->password; + + $wsResponse = $ws->listOfProcess ( ); + $res = $wsResponse->getPayloadString( 'listOfProcessResponse' ); + + return array("result"=> 1); + + //return new WSMessage ( array ( "status_code" => 12, "message" => 'abx', "timestamp" => 'aa' ) ); + //return array ( "status_code" => 12, "message" => 'abx', "timestamp" => 'aa' ); + + return new WSMessage($res); + } + + $operations = array( + "login" => "wsBaseLogin", + "listOfProcess" => "wsBaseListOfProcess", + ); + + $actions = array( "pmLogin" => "login", + "pmListOfProcess" => "listOfProcess", + ); + + $opParams = array( "listOfProcess" => "MIXED"); + + + $svr = new WSService( array("operations" => $operations, + "actions" => $actions, + "opParams" => $opParams, + "serviceName" => "ProcessMaker WS" + ) + ); + + $svr->reply(); +*/ diff --git a/workflow/engine/methods/services/xpdl.php b/workflow/engine/methods/services/xpdl.php new file mode 100644 index 000000000..9d2e1aba3 --- /dev/null +++ b/workflow/engine/methods/services/xpdl.php @@ -0,0 +1,184 @@ +createElement($indice); + else + $nodo = $obj->createElement($indice, $contenido); + + $padre->appendChild($nodo); + } + else + { if($contenido=='') + $nodo = $obj->createElement($indice); + else + $nodo = $obj->createElement($indice, $contenido); + + $obj->appendChild($nodo); + } + if(is_array($atributos)) + { + foreach($atributos as $key => $value) + { + $atributo = $obj->createAttribute($key); + $nodo->appendChild($atributo); + + $texto = $obj->createTextNode($value); + $atributo->appendChild($texto); + } + } + return $nodo; +} + +function derivationRules($aRoute, $doc, $nodo_derivationrule) +{ $tam = count($aRoute); + $c=0; + switch($aRoute[$c]['ROU_TYPE']) + { + case 'SEQUENTIAL': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'Sequential', '', ''); + $nodo_nexttask = addNodox($doc, $nodo_routeType, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + break; + case 'EVALUATE': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'Evaluations', '', ''); + while($c < $tam) + { + $nodo_evaluation= addNodox($doc, $nodo_routeType, 'Evaluation', '', array('Condition'=> $aRoute[$c]['ROU_CONDITION'])); + $nodo_nexttask = addNodox($doc, $nodo_evaluation, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + $c++; + } + break; + case 'SELECT': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'Selections', '', ''); + while($c < $tam) + { + $nodo_selection= addNodox($doc, $nodo_routeType, 'Selection', '', array('Description'=> $aRoute[$c]['ROU_CONDITION'])); + $nodo_nexttask = addNodox($doc, $nodo_selection, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + $c++; + } + break; + case 'PARALLEL': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'ParallelForks', '', ''); + while($c < $tam) + { + $nodo_parallelfork= addNodox($doc, $nodo_routeType, 'ParallelFork', '', ''); + $nodo_nexttask = addNodox($doc, $nodo_parallelfork, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + $c++; + } + break; + case 'PARALLEL-BY-EVALUATION': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'ParallelForksByEvaluation', '', ''); + while($c < $tam) + { + $nodo_evaluation= addNodox($doc, $nodo_routeType, 'Evaluation', '', array('Condition'=> $aRoute[$c]['ROU_CONDITION'])); + $nodo_nexttask = addNodox($doc, $nodo_evaluation, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + $c++; + } + break; + case 'SEC-JOIN': + $nodo_routeType = addNodox($doc, $nodo_derivationrule, 'ParallelJoin', '', ''); + $nodo_nexttask = addNodox($doc, $nodo_routeType, 'NextTask', '', ''); + if($aRoute[$c]['ROU_NEXT_TASK'] != -1) + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'TaskRef', '', array('TaskId'=> 'ID'.$aRoute[$c]['ROU_NEXT_TASK'])); + else + $nodo_taskref = addNodox($doc, $nodo_nexttask, 'End', '', ''); + break; + } +} + +/****-_--__---___----___---__--_-****/ + +G::LoadClass('tasks'); +require_once 'classes/model/Process.php'; + +$doc = new DOMDocument('1.0', 'UTF-8'); +$nodo_padre = addNodox($doc, '', 'Processes', '', array('xmlns:xsi'=>'http://www.w3.org/2001/XMLSchema-instance','xsi:noNamespaceSchemaLocation'=>'ColosaSchema.xsd')); + +$aProcesses = array(); +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(ProcessPeer::PRO_UID); +//$oCriteria->add(ProcessPeer::PRO_STATUS, 'DISABLED', Criteria::NOT_EQUAL); +//$oCriteria->add(ProcessPeer::PRO_UID, '946679494980c3d0ba0814088444708'); +$oDataset = ProcessPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$oProcess = new Process(); + +while ($aRow = $oDataset->getRow()) { + $aProcess = $oProcess->load($aRow['PRO_UID']); + $nodo_process = addNodox($doc, $nodo_padre, 'Process', '', array('Title'=> $aProcess['PRO_TITLE'],'Description'=> $aProcess['PRO_DESCRIPTION'])); + $nodo_tasks = addNodox($doc, $nodo_process, 'Tasks', '', ''); + + $oTask = new Tasks(); + $aTasks= $oTask->getAllTasks($aProcess['PRO_UID']); + foreach($aTasks as $key => $value) + { //print_r($value); echo "
    "; + $aRoute = $oTask->getRoute($aProcess['PRO_UID'], $value['TAS_UID']); + //print_r($aRoute[0]['ROU_UID']); echo "
    "; + /*foreach($aRoute as $k => $v) + echo $k."-->".$v."
    "; + */ + if($value['TAS_TYPE']=='NORMAL') + { + $ini = ($value['TAS_START']=='TRUE') ? 'true' : 'false'; + + $nodo_task = addNodox($doc, $nodo_tasks, 'Task', '', array('Title'=> $value['TAS_TITLE'],'Description'=> $value['TAS_DESCRIPTION'],'Id'=> 'ID'.$value['TAS_UID'],'StartingTask'=> $ini)); + $nodo_coordinates = addNodox($doc, $nodo_task, 'Coordinates', '', array('XCoordinate'=> $value['TAS_POSX'],'YCoordinate'=> $value['TAS_POSY'])); + $nodo_derivationrule = addNodox($doc, $nodo_task, 'DerivationRule', '', ''); + + derivationRules($aRoute, $doc, $nodo_derivationrule); + + $nodo_assignmentrules = addNodox($doc, $nodo_task, 'AssignmentRules', '', ''); + $nodo_cyclicalassignment = addNodox($doc, $nodo_assignmentrules, 'CyclicalAssignment', '', ''); + $nodo_timingcontrol = addNodox($doc, $nodo_task, 'TimingControl', '', array('TaskDuration'=> $value['TAS_DURATION'])); + $nodo_permissions = addNodox($doc, $nodo_task, 'Permissions', '', ''); + $nodo_caselabels = addNodox($doc, $nodo_task, 'CaseLabels', '', ''); + $nodo_notifications = addNodox($doc, $nodo_task, 'Notifications', '', ''); + } + else + { require_once ( "classes/model/SubProcess.php" ); + $oCriteria = new Criteria('workflow'); + $oCriteria->add(SubProcessPeer::PRO_PARENT, $value['PRO_UID']); + $oCriteria->add(SubProcessPeer::TAS_PARENT, $value['TAS_UID']); + $oDataset = SubProcessPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $nodo_task = addNodox($doc, $nodo_tasks, 'SubProcess', '', array('Title'=> $value['TAS_TITLE'],'Description'=> $value['TAS_DESCRIPTION'],'Id'=> 'ID'.$value['TAS_UID'], 'ProcessRef'=>$aRow['PRO_UID'])); + $nodo_coordinates = addNodox($doc, $nodo_task, 'Coordinates', '', array('XCoordinate'=> $value['TAS_POSX'],'YCoordinate'=> $value['TAS_POSY'])); + $nodo_derivationrule = addNodox($doc, $nodo_task, 'DerivationRule', '', ''); + + derivationRules($aRoute, $doc, $nodo_derivationrule); + } + } + $oDataset->next(); +} +//die; +$doc->preserveWhiteSpace = false; +$doc->formatOutput = true; +$doc->save(PATH_METHODS.'services/test_xpdl.xml'); +echo "xml for xpdl creado!!!
    "; + +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/appCacheViewAjax.php b/workflow/engine/methods/setup/appCacheViewAjax.php new file mode 100755 index 000000000..8be1d01a1 --- /dev/null +++ b/workflow/engine/methods/setup/appCacheViewAjax.php @@ -0,0 +1,218 @@ +info = Array(); + + //check the language, if no info in config about language, the default is 'en' + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'APP_CACHE_VIEW_ENGINE','','','',''); + $appCacheViewEngine = $oConf->aConfig; + + if( isset($appCacheViewEngine['LANG']) ) { + $lang = $appCacheViewEngine['LANG']; + $status = strtoupper($appCacheViewEngine['STATUS']); + } + else { + $confParams = Array( + 'LANG' => 'en', + 'STATUS'=> '' + ); + $oConf->aConfig = $confParams; + $oConf->saveConfig('APP_CACHE_VIEW_ENGINE', '', '', ''); + $lang = 'en'; + $status = ''; + } + + //get user Root from hash + $result->info = array (); + $result->error = false; + + //setup the appcacheview object, and the path for the sql files + $appCache = new AppCacheView(); + $appCache->setPathToAppCacheFiles ( PATH_METHODS . 'setup' . PATH_SEP .'setupSchemas'. PATH_SEP ); + + $res = $appCache->getMySQLVersion(); + $result->info[] = array ('name' => 'MySQL Version', 'value'=> $res ); + + $res = $appCache->checkGrantsForUser( false ); + $currentUser = $res['user']; + $currentUserIsSuper = $res['super']; + $result->info[] = array ('name' => 'Current User', 'value'=> $currentUser ); + $result->info[] = array ('name' => 'Current User has SUPER privilege', 'value'=> $currentUserIsSuper ); + + try { + PROPEL::Init ( PATH_METHODS.'dbConnections/rootDbConnections.php' ); + $con = Propel::getConnection("root"); + } + catch ( Exception $e ) { + $result->info[] = array ('name' => 'Checking MySql Root user', 'value'=> 'failed' ); + $result->error = true; + $result->errorMsg = $e->getMessage(); + } + + //if user does not have the SUPER privilege we need to use the root user and grant the SUPER priv. to normal user. + if ( ! $currentUserIsSuper && !$result->error ) { + $res = $appCache->checkGrantsForUser( true ); + if ( !isset( $res['error'] ) ) { + $result->info[] = array ('name' => 'Root User', 'value'=> $res['user'] ); + $result->info[] = array ('name' => 'Root User has SUPER privilege', 'value'=> $res['super'] ); + } + else { + $result->info[] = array ('name' => 'Error', 'value'=> $res['msg'] ); + } + + $res = $appCache->setSuperForUser( $currentUser ); + if ( !isset( $res['error'] ) ) { + $result->info[] = array ('name' => 'Setting SUPER privilege', 'value'=> 'Successfully' ); + } + else { + $result->error = true; + $result->errorMsg = $res['msg']; + } + $currentUserIsSuper = true; + + } + + //now check if table APPCACHEVIEW exists, and it have correct number of fields, etc. + $res = $appCache->checkAppCacheView(); + $result->info[] = array ('name' => 'Table APP_CACHE_VIEW', 'value'=> $res['found']); + if ( $res['recreated'] ) + $result->info[] = array ('name' => 'Table APP_CACHE_VIEW recreated', 'value'=> $res['recreated']); + + $result->info[] = array ('name' => 'Rows in APP_CACHE_VIEW', 'value'=> $res['count']); + + //now check if we have the triggers installed + //APP_DELEGATION INSERT + $res = $appCache->triggerAppDelegationInsert($lang, false); + $result->info[] = array ('name' => 'Trigger APP_DELEGATION INSERT', 'value'=> $res); + + //APP_DELEGATION Update + $res = $appCache->triggerAppDelegationUpdate($lang, false); + $result->info[] = array ('name' => 'Trigger APP_DELEGATION UPDATE', 'value'=> $res); + + //APPLICATION UPDATE + $res = $appCache->triggerApplicationUpdate($lang, false); + $result->info[] = array ('name' => 'Trigger APPLICATION UPDATE', 'value'=> $res); + + //APPLICATION DELETE + $res = $appCache->triggerApplicationDelete($lang, false); + $result->info[] = array ('name' => 'Trigger APPLICATION DELETE', 'value'=> $res); + + //show language + $result->info[] = array ('name' => 'Language', 'value'=> $lang ); + + echo G::json_encode($result); + break; + + case 'getLangList': + + require_once 'classes/model/Translation.php'; + $result = new stdClass(); + $result->rows = Array(); + + + $langs = Translation::getTranslationEnvironments(); + foreach($langs as $lang){ + $result->rows[] = Array('LAN_ID'=>$lang['LOCALE'], 'LAN_NAME'=>$lang['LANGUAGE']); + } + //print_r($langs); + //$result->rows = $lang->getActiveLanguages(); + + print(G::json_encode($result)); + break; + + case 'build': + $sqlToExe = Array(); + G::LoadClass('configuration'); + $conf = new Configurations; + + $lang = $_POST['lang']; + + try { + //setup the appcacheview object, and the path for the sql files + $appCache = new AppCacheView(); + $appCache->setPathToAppCacheFiles ( PATH_METHODS . 'setup' . PATH_SEP .'setupSchemas'. PATH_SEP ); + + //APP_DELEGATION INSERT + $res = $appCache->triggerAppDelegationInsert($lang, true); + //$result->info[] = array ('name' => 'Trigger APP_DELEGATION INSERT', 'value'=> $res); + + //APP_DELEGATION Update + $res = $appCache->triggerAppDelegationUpdate($lang, true); + //$result->info[] = array ('name' => 'Trigger APP_DELEGATION UPDATE', 'value'=> $res); + + //APPLICATION UPDATE + $res = $appCache->triggerApplicationUpdate($lang, true); + //$result->info[] = array ('name' => 'Trigger APPLICATION UPDATE', 'value'=> $res); + + //APPLICATION DELETE + $res = $appCache->triggerApplicationDelete($lang, true); + //$result->info[] = array ('name' => 'Trigger APPLICATION DELETE', 'value'=> $res); + + + //build using the method in AppCacheView Class + $res = $appCache->fillAppCacheView($lang); + //$result->info[] = array ('name' => 'build APP_CACHE_VIEW', 'value'=> $res); + + //set status in config table + $confParams = Array( + 'LANG' => $lang, + 'STATUS'=> 'active' + ); + $conf->aConfig = $confParams; + $conf->saveConfig('APP_CACHE_VIEW_ENGINE', '', '', ''); + + // removing casesList configuration records. TODO: removing these lines that resets all the configurations records + $oCriteria = new Criteria(); + $oCriteria->add(ConfigurationPeer::CFG_UID,'casesList'); + ConfigurationPeer::doDelete($oCriteria); + // end of reset + + $response = new StdClass(); + $result->success = true; + $result->msg = "Completed successfully"; + + echo G::json_encode($result); + + } + catch (Exception $e) { + $confParams = Array( + 'lang'=>$lang, + 'status'=> 'failed' + ); + $appCacheViewEngine = $oServerConf->setProperty('APP_CACHE_VIEW_ENGINE', $confParams); + + echo '{success: false, msg:"'.$e->getMessage().'"}'; + } + break; + case 'recreate-root': + $sh=md5(filemtime(PATH_GULLIVER."/class.g.php")); + $h=G::encrypt($_POST['host'].$sh.$_POST['user'].$sh.$_POST['password'].$sh.(1),$sh); + $insertStatements = "define ( 'HASH_INSTALLATION','{$h}' ); \ndefine ( 'SYSTEM_HASH', '{$sh}' ); \n"; + $lines = array(); + $content = ''; + $filename = PATH_HOME.'engine'.PATH_SEP.'config'.PATH_SEP.'paths_installed.php'; + $lines = file($filename); + + foreach ($lines as $line_num => $line) { + if ($line_num<5){ + $content = $content. $line; + } + } + $content = $content.$insertStatements."\n"; + if (file_put_contents($filename, $content)!=false){ + echo G::loadTranslation('ID_MESSAGE_ROOT_CHANGE_SUCESS'); + } else { + echo G::loadTranslation('ID_MESSAGE_ROOT_CHANGE_FAILURE'); + } + break; + } + + \ No newline at end of file diff --git a/workflow/engine/methods/setup/appCacheViewConf.php b/workflow/engine/methods/setup/appCacheViewConf.php new file mode 100755 index 000000000..1f2b4b4fa --- /dev/null +++ b/workflow/engine/methods/setup/appCacheViewConf.php @@ -0,0 +1,31 @@ +setExtSkin( 'xtheme-blue'); + //$oHeadPublisher->usingExtJs('ux/Ext.ux.codepress'); + + $oHeadPublisher->addExtJsScript('setup/appCacheViewConf', false); //adding a javascript file .js + $oHeadPublisher->addContent('setup/appCacheViewConf'); //adding a html file .html. + + require_once('classes/model/AppCacheView.php'); + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'APP_CACHE_VIEW_ENGINE','','','',''); + + //first check about APP_CACHE_VIEW is enabled or not, + if ( isset($oConf->aConfig['LANG']) && isset($oConf->aConfig['STATUS']) && $oConf->aConfig['STATUS'] == 'active'){ + $appCacheViewEnabled = true; + } + else { + $appCacheViewEnabled = false; + } + $lang = isset($oConf->aConfig['LANG']) ? $oConf->aConfig['LANG'] : 'en'; + + //$oHeadPublisher->assign('appCacheViewEnabled', $appCacheViewEnabled); + $TRANSLATIONS->ID_PROCESSING = G::LoadTranslation('ID_PROCESSING'); + $oHeadPublisher->assign( 'TRANSLATIONS', $TRANSLATIONS); //translations + $oHeadPublisher->assign( 'currentLang', $lang); //current language + + G::RenderPage('publish', 'extJs'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/appearance.php b/workflow/engine/methods/setup/appearance.php new file mode 100644 index 000000000..aa109d607 --- /dev/null +++ b/workflow/engine/methods/setup/appearance.php @@ -0,0 +1,45 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent("content", "setup/company_template"); + G::RenderPage( 'publish' ); +?>company logo + + \ No newline at end of file diff --git a/workflow/engine/methods/setup/calendarDelete.php b/workflow/engine/methods/setup/calendarDelete.php new file mode 100644 index 000000000..2a7c4bcb6 --- /dev/null +++ b/workflow/engine/methods/setup/calendarDelete.php @@ -0,0 +1,20 @@ + deleteCalendar($CalendarUid); + + G::Header('location: calendarList'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + \ No newline at end of file diff --git a/workflow/engine/methods/setup/calendarEdit.php b/workflow/engine/methods/setup/calendarEdit.php new file mode 100644 index 000000000..c4c2030b1 --- /dev/null +++ b/workflow/engine/methods/setup/calendarEdit.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'CALENDAR'; + +$CalendarUid = str_replace ( '"', '', isset ( $_GET ['id'] ) ? $_GET ['id'] : G::GenerateUniqueID () ); +//TODO: Add validation before save for all fields +G::LoadClass ( 'calendar' ); +$calendarObj = new calendar ( ); +if ((isset ( $_GET ['id'] )) && ($_GET ['id'] != "")) { + $fields = $calendarObj->getCalendarInfo ( $CalendarUid ); +} + +if (! (isset ( $fields ['CALENDAR_UID'] ))) { //For a new Calendar + $fields ['CALENDAR_UID'] = $CalendarUid; + //Default Business Hour + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_DAY'] = 7; + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_START'] = "09:00"; + $fields ['BUSINESS_DAY'] [1] ['CALENDAR_BUSINESS_END'] = "17:00"; +} +if ((isset ( $_GET ['cp'] )) && ($_GET ['cp'] == 1)) { // Copy Calendar + $fields ['CALENDAR_UID'] = G::GenerateUniqueID (); + $fields ['CALENDAR_NAME'] = G::LoadTranslation ( "ID_COPY_OF" ) . " " . $fields ['CALENDAR_NAME']; +} +$G_PUBLISH = new Publisher ( ); +$G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/calendarEdit', '', $fields, 'calendarSave' ); +G::RenderPage ( 'publishBlank', 'blank' ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/calendarList.php b/workflow/engine/methods/setup/calendarList.php new file mode 100644 index 000000000..a5d81ca42 --- /dev/null +++ b/workflow/engine/methods/setup/calendarList.php @@ -0,0 +1,57 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + +if(class_exists('pmLicenseManager')){ + $pmLicenseManagerO =& pmLicenseManager::getSingleton(); + $expireIn=$pmLicenseManagerO->getExpireIn(); + if($expireIn<=0){ + G::header("location: calendarEdit?id=00000000000000000000000000000001"); + } + }else{ + G::header("location: calendarEdit?id=00000000000000000000000000000001"); + } +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'CALENDAR'; + +$dbc = new DBConnection ( ); +$G_PUBLISH = new Publisher ( ); + +G::LoadClass ( "calendar" ); +$Calendar = new Calendar ( ); +$Criteria = $Calendar->getCalendarList ();//List all calendars (ACTIVE and INACTIVE) + +$G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/calendarList', $Criteria, array (), '' ); + +G::RenderPage ( 'publishBlank','blank' ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/calendarSave.php b/workflow/engine/methods/setup/calendarSave.php new file mode 100644 index 000000000..55c688634 --- /dev/null +++ b/workflow/engine/methods/setup/calendarSave.php @@ -0,0 +1,54 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +switch ($RBAC->userCanAccess('PM_SETUP_ADVANCE')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + + try { + $form = $_POST['form']; + + G::LoadClass('calendar'); + $calendarObj=new calendar(); + $calendarObj->saveCalendarInfo($form); + + G::Header('location: calendarList'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/setup/clearCompiled.php b/workflow/engine/methods/setup/clearCompiled.php new file mode 100755 index 000000000..0d1d66f0f --- /dev/null +++ b/workflow/engine/methods/setup/clearCompiled.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try{ + if( isset($_GET['result']) && $_GET['result'] == 'done') { + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'setup/clearCompiledResult'); + G::RenderPage('publish', 'blank'); + } else { + if( isset($_GET['result']) && $_GET['result'] == 'confirm' ){ + if( defined('PATH_C') ){ + G::rm_dir(PATH_C); + G::SendTemporalMessage('ID_CLEAR_CACHE_MSG1', 'tmp-info', 'label'); + G::header('location: clearCompiled?result=done'); + } + } else { + echo ''; + } + } +} catch(Exception $e){ + G::SendTemporalMessage($oError->getMessage(), 'error', 'string'); +} \ No newline at end of file diff --git a/workflow/engine/methods/setup/connectionDB.php b/workflow/engine/methods/setup/connectionDB.php new file mode 100644 index 000000000..2abdfb22e --- /dev/null +++ b/workflow/engine/methods/setup/connectionDB.php @@ -0,0 +1,32 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( "xmlform", "pagedTable", "setup/connection_db","","", "" ); + G::RenderPage( 'publish' ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/connectionWS.php b/workflow/engine/methods/setup/connectionWS.php new file mode 100644 index 000000000..824adbeb9 --- /dev/null +++ b/workflow/engine/methods/setup/connectionWS.php @@ -0,0 +1,32 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( "xmlform", "pagedTable", "setup/connection_ws","","", "" ); + G::RenderPage( 'publish' ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/customFunctions.php b/workflow/engine/methods/setup/customFunctions.php new file mode 100644 index 000000000..72c8ba700 --- /dev/null +++ b/workflow/engine/methods/setup/customFunctions.php @@ -0,0 +1,33 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('table', 'paged-table2', 'setup/Custom_Functions', '', '', ''); + G::RenderPage( 'publish-treeview' ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/debug.php b/workflow/engine/methods/setup/debug.php new file mode 100644 index 000000000..817fb0683 --- /dev/null +++ b/workflow/engine/methods/setup/debug.php @@ -0,0 +1,40 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + + G::LoadClass ( 'lexico' ); + $lex = new Lexico( $dbc ); + $Fields['SESSION_PC'] = $lex->getFluidValue ( 'SESSION_PC', 'Y' ); + $Fields['SESSION_BROWSER'] = $lex->getFluidValue ( 'SESSION_BROWSER', 'Y' ); + + $G_PUBLISH->AddContent( "xmlform", "xmlform", "setup/session","", $Fields , "session2" ); + + G::RenderPage( 'publish-treeview' ); + +?> diff --git a/workflow/engine/methods/setup/emailSystemCron.php b/workflow/engine/methods/setup/emailSystemCron.php new file mode 100755 index 000000000..1879c1b21 --- /dev/null +++ b/workflow/engine/methods/setup/emailSystemCron.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'MAILSYSTEM'; + + + G::LoadClass('package'); + G::LoadClass('smtp'); + G::LoadClass('spool'); + + $run = new spoolRun(); + unset($run); + +$Fields['MESSAGE'] = 'Hello world, this is my first email ... '; + + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $Fields, ''); +G::RenderPage('publish'); diff --git a/workflow/engine/methods/setup/emailSystemSpool.php b/workflow/engine/methods/setup/emailSystemSpool.php new file mode 100755 index 000000000..30188d0ab --- /dev/null +++ b/workflow/engine/methods/setup/emailSystemSpool.php @@ -0,0 +1,68 @@ + + * @copyright Copyright (c) 2007, Ian K Armstrong + * @license http://www.opensource.org/licenses/gpl-3.0.html GNU Public License + * @link http://www.openmail.cc + * + * @category web_mail + * @subpackage spool + * @filesource + * @version + * + * @file tom_spool.php + * + */ + + if( isset ( $_POST['form']) ) + { + $frm = "{$_POST['form']}"; + + G::LoadClass('insert'); + + $db_spool = array(); + + $db_spool['msg_uid'] = 'msg_uid'; + $db_spool['app_uid'] = 'app_uid'; + $db_spool['del_index'] = 99; // random number + $db_spool['app_msg_type'] = 'email message'; + $db_spool['app_msg_subject'] = 'subject field'; //"{$frm['subject']}"; + $db_spool['app_msg_from'] = '"ian armstrong" ';//"{$frm['from_email']}"; + $db_spool['app_msg_to'] = ''; //"{$frm['to_email']}"; + $db_spool['app_msg_body'] = 'body field'; //"{$frm['body']}"; + $db_spool['app_msg_date'] = time(); + $db_spool['app_msg_cc'] = ''; + $db_spool['app_msg_bcc'] = ''; + $db_spool['app_msg_template'] = "/path/to/template"; + $db_spool['app_msg_status'] = "pending"; + + $db_spool['app_msg_attach'] = serialize(array('attachment_1','attachment_2')); + + /* + if(isset($frm['attachments']) && count($frm['attachments']) >0 ) + { + foreach($frm['attachments'] as $attchment) + { + $db_spool['app_msg_attach'][] = "$attchment"; + + } + + }*/ + + $insert = new insert($db_spool); + $status = $insert->returnStatus(); + unset($insert); + + } + + $Fields['MESSAGE'] = $status; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $Fields, 'emailSystemSpool'); + G::RenderPage('publish'); + + +?> diff --git a/workflow/engine/methods/setup/emailSystemTest.php b/workflow/engine/methods/setup/emailSystemTest.php new file mode 100644 index 000000000..a397c6aa0 --- /dev/null +++ b/workflow/engine/methods/setup/emailSystemTest.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +switch ($RBAC->userCanAccess('PM_FACTORY')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'MAILSYSTEM'; + +$Fields['domain'] = 'colosa.com'; +$Fields['to_email'] = '"Ian" , "fernando" '; +$Fields['from_name'] = 'testsystem'; +$Fields['from_email'] = 'ian@colosa.com'; +$Fields['subject'] = 'Test email'; +$Fields['body'] = 'Hello world, this is my first email ... '; + + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/emailSetupTest', '', $Fields, 'emailSystemSpool'); +G::RenderPage('publish'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/emails.php b/workflow/engine/methods/setup/emails.php new file mode 100644 index 000000000..b0e07c74c --- /dev/null +++ b/workflow/engine/methods/setup/emails.php @@ -0,0 +1,74 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_FACTORY') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'EMAILS'; + +require_once 'classes/model/Configuration.php'; +$oConfiguration = new Configuration(); +$sDelimiter = DBAdapter::getStringDelimiter(); +$oCriteria = new Criteria('workflow'); +$oCriteria->add(ConfigurationPeer::CFG_UID, 'Emails'); +$oCriteria->add(ConfigurationPeer::OBJ_UID, ''); +$oCriteria->add(ConfigurationPeer::PRO_UID, ''); +$oCriteria->add(ConfigurationPeer::USR_UID, ''); +$oCriteria->add(ConfigurationPeer::APP_UID, ''); + +if (ConfigurationPeer::doCount($oCriteria) == 0) { + $oConfiguration->create(array('CFG_UID' => 'Emails', 'OBJ_UID' => '', 'CFG_VALUE' => '', 'PRO_UID' => '', 'USR_UID' => '', 'APP_UID' => '', 'MESS_RAUTH' => '')); + $aFields = array(); +} +else { + $aFields = $oConfiguration->load('Emails', '', '', '', ''); + if (trim($aFields['CFG_VALUE']) != '') { + $aFields = unserialize($aFields['CFG_VALUE']); + } + else { + $aFields = array(); + } +} + +$rows[] = array ( 'uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); +$rows[] = array ( 'uid' => 'PHPMAILER', 'name' => 'SMTP (PHPMailer)' ); +// ending OpenMail support +// $rows[] = array ( 'uid' => 'OPENMAIL', 'name' => 'SMTP (OpenMail)' ); +$rows[] = array ( 'uid' => 'MAIL', 'name' => 'Mail (PHP)' ); + +$_DBArray['mails'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; + + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/emails', '', $aFields, 'emails_Save'); +G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/emails_Ajax.php b/workflow/engine/methods/setup/emails_Ajax.php new file mode 100644 index 000000000..24664ffa7 --- /dev/null +++ b/workflow/engine/methods/setup/emails_Ajax.php @@ -0,0 +1,347 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +switch ($RBAC->userCanAccess('PM_FACTORY')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + +$request = (isset($_POST['action']))?$_POST['action']:$_POST['request']; + +switch ($request) { + case 'testEmailConfiguration': + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $aFields['FROM_EMAIL'] = $_POST['usermail']; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/emails_TestForm','', $aFields); + G::RenderPage('publish', 'raw'); + break; + case 'sendTestMail': + $sFrom = ($_POST['FROM_NAME'] != '' ? $_POST['FROM_NAME'] . ' ' : '') . '<' . $_POST['FROM_EMAIL'] . '>'; + $sSubject = G::LoadTranslation('ID_MESS_TEST_SUBJECT'); + $msg = G::LoadTranslation('ID_MESS_TEST_BODY'); + switch ($_POST['MESS_ENGINE']) { + case 'MAIL': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_1'); + break; + case 'PHPMAILER': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_2'); + break; + case 'OPENMAIL': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_3'); + break; + } + $colosa_msg = "This Business Process is powered by ProcessMaker."; + $sBody = " + + + + +
    $msg $engine [".date('H:i:s')."]
    +

    This Business Process is powered by ProcessMaker.
    + www.processmaker.com
    "; + + G::LoadClass('spool'); + $oSpool = new spoolRun(); + $oSpool->setConfig( array( + 'MESS_ENGINE' => $_POST['MESS_ENGINE'], + 'MESS_SERVER' => $_POST['MESS_SERVER'], + 'MESS_PORT' => $_POST['MESS_PORT'], + 'MESS_ACCOUNT' => $_POST['MESS_ACCOUNT'], + 'MESS_PASSWORD' => $_POST['MESS_PASSWORD'] + )); + $oSpool->create(array( + 'msg_uid' => '', + 'app_uid' => '', + 'del_index' => 0, + 'app_msg_type' => 'TEST', + 'app_msg_subject' => $sSubject, + 'app_msg_from' => $sFrom, + 'app_msg_to' => $_POST['TO'], + 'app_msg_body' => $sBody, + 'app_msg_cc' => '', + 'app_msg_bcc' => '', + 'app_msg_attach' => '', + 'app_msg_template' => '', + 'app_msg_status' => 'pending' + )); + $oSpool->sendMail(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + if ($oSpool->status == 'sent') { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/emails_Sended', '', array('MESSAGE_VALUE' => G::LoadTranslation('ID_MESS_TEST_MESSAGE_SENDED'))); + } + else { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/emails_Sended', '', array('MESSAGE_VALUE' => G::LoadTranslation('ID_MESS_TEST_MESSAGE_ERROR_PHP_MAIL') . $oSpool->error)); + } + G::RenderPage('publish', 'raw'); + break; + + /**********************************************************************************/ + + case 'mailTest_Show': + $srv = $_POST['srv']; + $port = $_POST['port']; + $account = $_POST['account']; + $passwd = $_POST['passwd']; + $auth_required = $_POST['auth_required']; + $send_test_mail = $_POST['send_test_mail']; + $mail_to = $_POST['mail_to']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'setup/mailConnectiontest'); + G::RenderPage('publish', 'raw'); + break; + + case 'mailTestMail_Show': + define("SUCCESSFUL", 'SUCCESSFUL'); + define("FAILED", 'FAILED'); + $mail_to = $_POST['mail_to']; + $send_test_mail = $_POST['send_test_mail']; + $_POST['FROM_NAME'] = $mail_to; + $_POST['FROM_EMAIL'] = $mail_to; + $_POST['MESS_ENGINE'] = 'MAIL'; + $_POST['MESS_SERVER'] = 'localhost'; + $_POST['MESS_PORT'] = 25; + $_POST['MESS_ACCOUNT'] = $mail_to; + $_POST['MESS_PASSWORD'] = ''; + $_POST['TO'] = $mail_to; + $_POST['SMTPAuth'] = true; + $resp = sendTestMail(); + if($resp->status){ + print(SUCCESSFUL.','.$resp->msg); + } + else { + print(FAILED.','.$resp->msg); + } + break; + case 'testConnection': + G::LoadClass('net'); + require_once('classes/class.smtp.rfc-821.php'); + define("SUCCESSFUL", 'SUCCESSFUL'); + define("FAILED", 'FAILED'); + //$host = 'smtp.bizmail.yahoo.com'; + $tld = ereg("([^//]*$)", $_POST['srv'], $regs); + $srv1 = $regs[1]; + $srv = $_POST['srv']; + $port = ($_POST['port'] == 'default')? 25: $_POST['port']; + $user = $_POST['account']; + $passwd = $_POST['passwd']; + $step = $_POST['step']; + $auth_required = $_POST['auth_required']; + $send_test_mail = $_POST['send_test_mail']; + $mail_to = $_POST['mail_to']; + $Server = new NET($srv1); + $oSMTP = new ESMTP; + switch ($step) { + case 1: + if ($Server->getErrno() == 0) { + print(SUCCESSFUL.','); + } else { + print(FAILED.','.$Server->error); + } + break; + case 2: + if($port == 0){ + $port = $oSMTP->SMTP_PORT; + } + $Server->scannPort($port); + if ($Server->getErrno() == 0) { + print(SUCCESSFUL.','); + } else { + print(FAILED.','.$Server->error); + } + break; + #try to connect to host + case 3: + if($port == 0){ + $resp = $oSMTP->Connect($srv); + } else { + $resp = $oSMTP->Connect($srv, $port); + } + if( !$resp) { + print(FAILED.','.$oSMTP->error['error']); + } else { + print(SUCCESSFUL.','.$oSMTP->status); + } + break; + #try login to host + case 4: + if($auth_required == 'yes'){ + if($port == 0){ + $resp = $oSMTP->Connect($srv); + } else { + $resp = $oSMTP->Connect($srv, $port); + } + if($resp) { + $oSMTP->do_debug = false; + $oSMTP->Hello($srv); + if( !$oSMTP->Authenticate($user, $passwd) ) { + print(FAILED.','.$oSMTP->error['error']); + } else { + print(SUCCESSFUL.','.$oSMTP->status); + } + } else { + print(FAILED.','.$oSMTP->error['error']); + } + } else { + print(SUCCESSFUL.', No authentication required!'); + } + break; + case 5: + if($send_test_mail == 'yes'){ + //print(SUCCESSFUL.',ok'); + $_POST['FROM_NAME'] = 'Process Maker O.S. [Test mail]'; + $_POST['FROM_EMAIL'] = $user; + $_POST['MESS_ENGINE'] = 'PHPMAILER'; + $_POST['MESS_SERVER'] = $srv; + $_POST['MESS_PORT'] = $port; + $_POST['MESS_ACCOUNT'] = $user; + $_POST['MESS_PASSWORD'] = $passwd; + $_POST['TO'] = $mail_to; + if($auth_required == 'yes'){ + $_POST['SMTPAuth'] = true; + } else { + $_POST['SMTPAuth'] = false; + } + $resp = sendTestMail(); + if($resp->status){ + print(SUCCESSFUL.','.$resp->msg); + } else { + print(FAILED.','.$resp->msg); + } + } else { + print('jump this step'); + } + break; + default: + print('test finished!'); + } + break; +} + +function sendTestMail() { + + $sFrom = ($_POST['FROM_NAME'] != '' ? $_POST['FROM_NAME'] . ' ' : '') . '<' . $_POST['FROM_EMAIL'] . '>'; + $sSubject = G::LoadTranslation('ID_MESS_TEST_SUBJECT'); + $msg = G::LoadTranslation('ID_MESS_TEST_BODY'); + + switch ($_POST['MESS_ENGINE']) { + case 'MAIL': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_1'); + break; + case 'PHPMAILER': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_2'); + break; + case 'OPENMAIL': + $engine = G::LoadTranslation('ID_MESS_ENGINE_TYPE_3'); + break; + } + + $colosa_msg = "This Business Process is powered by ProcessMaker."; + $sBody = " + + + + +
    $msg [".date('H:i:s')."] - $engine
    +

    This Business Process is powered by ProcessMaker.
    + www.processmaker.com
    "; + + G::LoadClass('spool'); + $oSpool = new spoolRun(); + + + $oSpool->setConfig( array( + 'MESS_ENGINE' => $_POST['MESS_ENGINE'], + 'MESS_SERVER' => $_POST['MESS_SERVER'], + 'MESS_PORT' => $_POST['MESS_PORT'], + 'MESS_ACCOUNT' => $_POST['MESS_ACCOUNT'], + 'MESS_PASSWORD' => $_POST['MESS_PASSWORD'], + 'SMTPAuth' => $_POST['SMTPAuth'] + )); + + $oSpool->create(array( + 'msg_uid' => '', + 'app_uid' => '', + 'del_index' => 0, + 'app_msg_type' => 'TEST', + 'app_msg_subject' => $sSubject, + 'app_msg_from' => $sFrom, + 'app_msg_to' => $_POST['TO'], + 'app_msg_body' => $sBody, + 'app_msg_cc' => '', + 'app_msg_bcc' => '', + 'app_msg_attach' => '', + 'app_msg_template' => '', + 'app_msg_status' => 'pending' + )); + + $oSpool->sendMail(); + + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + if ($oSpool->status == 'sent') { + $o->status = true; + $o->msg = G::LoadTranslation('ID_MESS_TEST_MESSAGE_SENDED'); + } + else { + $o->status = false; + $o->msg = $oSpool->error; + } + return $o; +} + + +function e_utf8_encode($input) { + $utftext = null; + + for ($n = 0; $n < strlen($input); $n++) { + + $c = ord($input[$n]); + + if ($c < 128) { + $utftext .= chr($c); + } else if (($c > 128) && ($c < 2048)) { + $utftext .= chr(($c >> 6) | 192); + $utftext .= chr(($c & 63) | 128); + } else { + $utftext .= chr(($c >> 12) | 224); + $utftext .= chr((($c & 6) & 63) | 128); + $utftext .= chr(($c & 63) | 128); + } + } + + return $utftext; +} \ No newline at end of file diff --git a/workflow/engine/methods/setup/emails_Save.php b/workflow/engine/methods/setup/emails_Save.php new file mode 100644 index 000000000..a0a5b33d3 --- /dev/null +++ b/workflow/engine/methods/setup/emails_Save.php @@ -0,0 +1,46 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +require_once 'classes/model/Configuration.php'; +$oConfiguration = new Configuration(); +$aFields['MESS_ENABLED'] = isset($_POST['form']['MESS_ENABLED']) ? $_POST['form']['MESS_ENABLED'] : ''; +$aFields['MESS_ENGINE'] = $_POST['form']['MESS_ENGINE']; +$aFields['MESS_SERVER'] = $_POST['form']['MESS_SERVER']; +$aFields['MESS_RAUTH'] = isset($_POST['form']['MESS_RAUTH']) ? $_POST['form']['MESS_RAUTH'] : ''; +$aFields['MESS_PORT'] = $_POST['form']['MESS_PORT']; +$aFields['MESS_ACCOUNT'] = $_POST['form']['MESS_ACCOUNT']; +$aFields['MESS_PASSWORD'] = $_POST['form']['MESS_PASSWORD']; +$aFields['MESS_BACKGROUND'] = isset($_POST['form']['MESS_BACKGROUND']) ? $_POST['form']['MESS_BACKGROUND'] : ''; +$aFields['MESS_EXECUTE_EVERY'] = $_POST['form']['MESS_EXECUTE_EVERY']; +$aFields['MESS_SEND_MAX'] = $_POST['form']['MESS_SEND_MAX']; +$aFields['MESS_TRY_SEND_INMEDIATLY'] = isset($_POST['form']['MESS_TRY_SEND_INMEDIATLY']) ? $_POST['form']['MESS_TRY_SEND_INMEDIATLY'] : ''; +$oConfiguration->update(array('CFG_UID' => 'Emails', + 'OBJ_UID' => '', + 'CFG_VALUE' => serialize($aFields), + 'PRO_UID' => '', + 'USR_UID' => '', + 'APP_UID' => '')); +G::SendMessageText(G::LoadTranslation('ID_CHANGES_SAVED'), 'info'); +G::header('location: emails'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/environmentSettings.php b/workflow/engine/methods/setup/environmentSettings.php new file mode 100755 index 000000000..6c0335795 --- /dev/null +++ b/workflow/engine/methods/setup/environmentSettings.php @@ -0,0 +1,30 @@ +loadConfig($obj, 'ENVIRONMENT_SETTINGS',''); + + //translations array + $translations = G::getTranslations(Array( + 'ID_PM_ENV_SETTINGS_TITLE', 'ID_PM_ENV_SETTINGS_USERFIELDSET_TITLE', 'IS_USER_NAME_DISPLAY_FORMAT', 'ID_SAVE_SETTINGS', + 'ID_LAN_UPDATE_DATE', 'ID_SAVING_ENVIRONMENT_SETTINGS', 'ID_ENVIRONMENT_SETTINGS_MSG_1', + 'ID_PM_ENV_SETTINGS_REGIONFIELDSET_TITLE', 'ID_GLOBAL_DATE_FORMAT', 'ID_PM_ENV_SETTINGS_CASESLIST_TITLE', 'ID_CASES_ROW_NUMBER', 'ID_CASES_DATE_MASK' + )); + $defaultOption = isset($oConf->aConfig['format'])? $oConf->aConfig['format']: ''; + $defaultDateOption = isset($oConf->aConfig['dateFormat'])? $oConf->aConfig['dateFormat']: ''; + $defaultCasesListDateOption = isset($oConf->aConfig['casesListDateFormat'])? $oConf->aConfig['casesListDateFormat']: ''; + $defaultCasesListRowOption = isset($oConf->aConfig['casesListRowNumber']) ? $oConf->aConfig['casesListRowNumber'] : ''; + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addExtJsScript('setup/environmentSettings', false ); + + $oHeadPublisher->assign('default_format', $defaultOption); + $oHeadPublisher->assign('default_date_format', $defaultDateOption); + $oHeadPublisher->assign('default_caseslist_date_format', $defaultCasesListDateOption); + $oHeadPublisher->assign('default_caseslist_row_number', $defaultCasesListRowOption); + + + + $oHeadPublisher->assign('dateFormatsList', Configurations::getDateFormats()); + + $oHeadPublisher->assign('TRANSLATIONS', $translations); + G::RenderPage('publish', 'extJs'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/environmentSettingsAjax.php b/workflow/engine/methods/setup/environmentSettingsAjax.php new file mode 100755 index 000000000..3ce5dc045 --- /dev/null +++ b/workflow/engine/methods/setup/environmentSettingsAjax.php @@ -0,0 +1,56 @@ + + * @date Sept 13th, 2010 + */ + + $request = isset($_POST['request'])? $_POST['request']: (isset($_GET['request'])? $_GET['request']: null); + + switch($request){ + case 'getUserMaskList': + G::loadClass('configuration'); + $result->rows = Configurations::getUserNameFormats(); + print(G::json_encode($result)); + break; + + case 'getDateFormats': + G::loadClass('configuration'); + $result->rows = Configurations::getDateFormats(); + print(G::json_encode($result)); + break; + + case 'getCasesListDateFormat': + G::loadClass('configuration'); + $result->rows = Configurations::getDateFormats();; + print(G::json_encode($result)); + break; + + case 'getCasesListRowNumber': + for($i=10; $i<=50; $i+=5){ + $formats[] = Array('id'=>"$i", 'name'=>"$i"); + } + $result->rows = $formats; + print(G::json_encode($result)); + break; + + case 'save': + + G::LoadClass('configuration'); + $conf = new Configurations; + $conf->aConfig = Array( + 'format'=>$_POST['userFormat'], + 'dateFormat'=>$_POST['dateFormat'], + 'casesListDateFormat' =>$_POST['casesListDateFormat'], + 'casesListRowNumber' =>$_POST['casesListRowNumber'] + ); + $conf->saveConfig('ENVIRONMENT_SETTINGS', ''); + + $response = new StdClass(); + $response->success = true; + $response->msg = G::LoadTranslation('ID_SAVED_SUCCESSFULLY'); + + echo G::json_encode($response); + break; + } + + \ No newline at end of file diff --git a/workflow/engine/methods/setup/holiday.php b/workflow/engine/methods/setup/holiday.php new file mode 100644 index 000000000..1b9476661 --- /dev/null +++ b/workflow/engine/methods/setup/holiday.php @@ -0,0 +1,35 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + + $G_PUBLISH->AddContent( 'pagedtable', 'paged-table', "setup/holidayList" ); + + G::RenderPage( 'publish' ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/holidayNew.php b/workflow/engine/methods/setup/holidayNew.php new file mode 100644 index 000000000..16f8562d7 --- /dev/null +++ b/workflow/engine/methods/setup/holidayNew.php @@ -0,0 +1,36 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + + $fields['DATE'] = date('Y-m-d'); + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', "setup/holiday", '', $fields, "holidaySave"); + + G::RenderPage( 'publish' ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/index.php b/workflow/engine/methods/setup/index.php new file mode 100644 index 000000000..845c3d0d1 --- /dev/null +++ b/workflow/engine/methods/setup/index.php @@ -0,0 +1,28 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $newFile = str_replace ( 'index.php', 'setup.php' , __FILE__ ) ; + return $newFile; + + diff --git a/workflow/engine/methods/setup/jasper.php b/workflow/engine/methods/setup/jasper.php new file mode 100644 index 000000000..dd2c1ee0f --- /dev/null +++ b/workflow/engine/methods/setup/jasper.php @@ -0,0 +1,139 @@ +ws_list("/"); + + if (get_class($response) == 'SOAP_Fault') { + $errorMessage = $response->getFault()->faultstring; + } + else { + $folders = $oJasper->getResourceDescriptors($response); + } + + //$result = $oJasper->ws_put(); + krumo ($response); + + //execute a report + + $currentUri = "/reports/samples/Employees"; + $result = $oJasper->ws_get($currentUri); + + $folders = $oJasper->getResourceDescriptors($result); + + if (count($folders) != 1 || $folders[0]['type'] != 'reportUnit') + { + echo "

    Invalid RU ($currentUri)

    "; + echo "
    $result
    "; + exit(); + } + + $reportUnit = $folders[0]; + + // 2. Prepare the parameters array looking in the $_GET for params + // starting with PARAM_ ... + // + + $report_params = array(); + + $moveToPage = "jasper?uri=$currentUri"; + + foreach (array_keys($_GET) AS $param_name) { + if (strncmp("PARAM_", $param_name,6) == 0) { + $report_params[substr($param_name,6)] = $_GET[$param_name]; + } + +// if ($param_name != "page" && $param_name != "uri") { +// $moveToPage .= "&".urlencode($param_name)."=". urlencode($_GET[$param_name]); +// } + } + + $formatReport = RUN_OUTPUT_FORMAT_XML; + $formatReport = RUN_OUTPUT_FORMAT_CSV; + $formatReport = RUN_OUTPUT_FORMAT_RTF; + $formatReport = RUN_OUTPUT_FORMAT_PDF; + $formatReport = RUN_OUTPUT_FORMAT_HTML; + $moveToPage .="&page="; + + // 3. Execute the report + $output_params = array(); + $output_params[RUN_OUTPUT_FORMAT] = $formatReport; + + if ( $formatReport == RUN_OUTPUT_FORMAT_HTML) { + //$pageReport = isset ( $_GET['page'] ) ? $_GET['page'] : 1; + //$output_params[RUN_OUTPUT_PAGE] = $pageReport; + //$output_params[RUN_OUTPUT_IMAGES_URI] = '/sysos/en/green/'; + } + + $result = $oJasper->ws_runReport($currentUri, $report_params, $output_params, $attachments); + + // 4. + if (get_class($result) == 'SOAP_Fault') { + $errorMessage = $result->getFault()->faultstring; + + echo $errorMessage; + exit(); + } + + $operationResult = $oJasper->getOperationResult($result); + + if ($operationResult['returnCode'] != '0') { + echo "Error executing the report:
    ".$operationResult['returnMessage'].""; + exit(); + } + + if (is_array($attachments)) + { + //krumo ($attachments); + + switch ($formatReport) { + case RUN_OUTPUT_FORMAT_PDF : + header ( "Content-type: application/pdf" ); + echo( $attachments["cid:report"]); + break; + + case RUN_OUTPUT_FORMAT_HTML : + // 1. Save attachments.... + // 2. Print the report.... + header ( "Content-type: text/html"); + foreach (array_keys($attachments) as $key) { + if ($key != "cid:report") { + $f = fopen("images/".substr($key,4),"w"); + fwrite($f, $attachments[$key]); + fclose($f); + } + } + + echo "
    "; + $prevpage = ($pageReport > 0) ? $pageReport - 1 : 0; + $nextpage = $pageReport + 1; + + echo "Prev page | Next page"; + echo "

    "; + + echo $attachments["cid:report"]; + //print_r(array_keys($attachments)); + break; + + case RUN_OUTPUT_FORMAT_CSV : + case RUN_OUTPUT_FORMAT_XLS : + header ( 'Content-type: application/xls' ); + header ( 'Content-Disposition: attachment; filename="report.xls"'); + echo( $attachments["cid:report"]); + break; + + case RUN_OUTPUT_FORMAT_RTF : + header ( 'Content-type: text/rtf' ); + header ( 'Content-Disposition: attachment; filename="report.rtf"'); + echo( $attachments["cid:report"]); + break; + + default : + //header ( 'Content-type: application/xls' ); + //header ( 'Content-Disposition: attachment; filename="report.xls"'); + echo( $attachments["cid:report"]); + break; + } + exit(); + } + else echo "No attachment found!"; diff --git a/workflow/engine/methods/setup/language.php b/workflow/engine/methods/setup/language.php new file mode 100644 index 000000000..6104ef27b --- /dev/null +++ b/workflow/engine/methods/setup/language.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( "xmlform", "xmlform", "setup/language","", "" , "language_save" ); + $G_PUBLISH->AddContent( "xmlform", "pagedTable", "setup/language_table","","", "../setup/languageAjax.php" ); + G::RenderPage( 'publish' ); +?> + + diff --git a/workflow/engine/methods/setup/language_Ajax.php b/workflow/engine/methods/setup/language_Ajax.php new file mode 100644 index 000000000..52c9e203b --- /dev/null +++ b/workflow/engine/methods/setup/language_Ajax.php @@ -0,0 +1,170 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + + G::LoadInclude('ajax'); + if(isset($_POST['form'])) { + $_POST = $_POST['form']; + } + $_POST['function'] = get_ajax_value('function'); + switch($_POST['function']) { + case 'savePredetermined': + require_once "classes/model/Translation.php"; + $tranlationsList = Translation::getTranslationEnvironments(); + g::pr($tranlationsList); die; + if( isset($meta['LAN_ID']) && $meta['LAN_ID'] == $_POST['lang'] ){ + echo 'The Setting was saved successfully!'; + } else { + echo 'Some error occured while the setting was being save, try later please.'; + } + break; + + case 'languagesList': + require_once 'classes/model/Language.php'; + require_once 'classes/model/IsoCountry.php'; + require_once 'classes/model/Translation.php'; + G::loadClass('configuration'); + + $isoCountry = new isoCountry(); + $translationRow = new Translation(); + $response = new stdClass(); + $translationsEnvList = $translationRow->getTranslationEnvironments(); + + $i = 0; + foreach( $translationsEnvList as $locale=>$translationRow) { + + $COUNTRY_ID = $translationRow['IC_UID']; + if( $COUNTRY_ID != '' ) { + $isoCountryRecord = $isoCountry->findById(strtoupper($COUNTRY_ID)); + $flag = strtolower($isoCountryRecord['IC_UID']); + $countryName = $translationRow['HEADERS']['X-Poedit-Country']; + } else { + $flag = 'international'; + $countryName = G::LoadTranslation('ID_INTERNATIONAL'); + } + + G::LoadClass ( 'configuration' ); + + $conf = new Configurations(); + $confCasesList = $conf->getConfiguration('casesList','todo'); + //echo date($confCasesList['dateformat'], '2010-01-01'); + + if( isset($confCasesList['dateformat']) ){ + $datetime = explode(' ', $translationRow['DATE']); + + $date = explode('-', $datetime[0]); + if( count($datetime) == 2 ) + $time = explode(':', $datetime[1]); + + if( count($date) == 3 ){ + if( count($time) >= 2 ){ + $DATE = date($confCasesList['dateformat'], mktime($time[0], $time[1], 0, $date[1], $date[2], $date[0])); + } else { + $DATE = date($confCasesList['dateformat'], mktime(0, 0, 0, $date[1], $date[2], $date[0])); + } + } else { + $DATE = $translationRow['DATE']; + } + + $datetime = explode(' ', $translationRow['HEADERS']['PO-Revision-Date']); + + $date = explode('-', $datetime[0]); + if( count($datetime) == 2 ) + $time = explode(':', $datetime[1]); + + if( count($date) == 3 ){ + if( count($time) >= 2 ){ + $REV_DATE = date($confCasesList['dateformat'], mktime($time[0], substr($time[1],0,2), 0, $date[1], $date[2], $date[0])); + } else { + $REV_DATE = date($confCasesList['dateformat'], mktime(0, 0, 0, $date[1], $date[2], $date[0])); + } + } else { + $REV_DATE = $translationRow['HEADERS']['PO-Revision-Date']; + } + } else { + $DATE = $translationRow['DATE']; + $REV_DATE = $translationRow['HEADERS']['PO-Revision-Date']; + } + + $languagesList[$i]['LAN_ID'] = $translationRow['LAN_ID']; + $languagesList[$i]['LOCALE'] = $translationRow['LOCALE']; + $languagesList[$i]['LAN_FLAG'] = $flag; + $languagesList[$i]['NUM_RECORDS'] = $translationRow['NUM_RECORDS']; + $languagesList[$i]['DATE'] = $DATE; + $languagesList[$i]['LAN_NAME'] = $translationRow['HEADERS']['X-Poedit-Language']; + $languagesList[$i]['COUNTRY_NAME'] = $countryName; + $languagesList[$i]['TRANSLATOR'] = htmlentities($translationRow['HEADERS']['Last-Translator']); + $languagesList[$i]['REV_DATE'] = $REV_DATE; + $languagesList[$i]['VERSION'] = $translationRow['HEADERS']['Project-Id-Version']; + + $i++; + } + $translationRow = new Translation(); + + $response->data = $languagesList; + + print(G::json_encode($response)); + break; + + case 'delete': + include_once 'classes/model/Translation.php'; + include_once 'classes/model/Content.php'; + $locale = $_POST['LOCALE']; + + if( strpos($locale, Translation::$localeSeparator) ) + list($LAN_ID, $IC_UID) = explode(Translation::$localeSeparator, $locale); + else { + $LAN_ID = $locale; + $LAN_ID = ''; + } + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT('.ContentPeer::CON_CATEGORY.')'); + $oCriteria->add(ContentPeer::CON_LANG, $locale); + $oCriteria->add(ContentPeer::CON_CATEGORY, 'APP_TITLE', Criteria::EQUAL ); + $oDataset = ContentPeer::doSelectRS($oCriteria); + + $oDataset->next(); + $oContent = new Content(); + $aRow = $oDataset->getRow(); + + //THERE IS NO ANY CASE STARTED FROM THES LANGUAGE + if( $aRow[0] == 0 ) { //so we can delete this language + try{ + Content::removeLanguageContent($locale); + Translation::removeTranslationEnvironment($locale); + echo G::LoadTranslation('ID_LANGUAGE_DELETED_SUCCESSFULLY'); + } catch (Exception $e){ + echo $e->getMessage(); + } + } else { + echo str_replace('{0}', $aRow[0], G::LoadTranslation('ID_LANGUAGE_CANT_DELETE')); + } + break; + } +} catch ( Exception $oException ) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/languages.php b/workflow/engine/methods/setup/languages.php new file mode 100644 index 000000000..59caa1601 --- /dev/null +++ b/workflow/engine/methods/setup/languages.php @@ -0,0 +1,39 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$RBAC->requirePermissions('PM_SETUP_ADVANCE'); + +//$oHeadPublisher->usingExtJs('ux/Ext.ux.fileUploadField'); +$oHeadPublisher->addExtJsScript('setup/languages', false); //adding a javascript file .js +$oHeadPublisher->addContent('setup/languages'); //adding a html file .html. + +$labels = G::getTranslations(Array( + 'ID_LAN_PREDETERMINED', 'ID_LANG_INSTALL_UPDATE', 'ID_LAN_LANGUAGE', 'ID_LAN_COUNTRY', 'ID_LAN_UPDATE_DATE', + 'ID_LAN_REV_DATE', 'ID_LAN_FILE', 'ID_LAN_REV_DATE', 'ID_LAN_VERSION', 'ID_LAN_GRID_TITLE', 'ID_LAN_UPLOAD_TITLE', + 'ID_LAN_FILE_WATER_LABEL', 'ID_EXPORT', 'ID_UPLOAD', 'ID_CANCEL', 'ID_DELETE_LANGUAGE', 'ID_DELETE_LANGUAGE_CONFIRM', + 'ID_DELETE_LANGUAGE_WARNING', 'ID_ACTIONS', 'ID_LAN_TRANSLATOR', 'ID_LAN_NUM_RECORDS' +)); + +$oHeadPublisher->assign('TRANSLATIONS', $labels); +G::RenderPage('publish', 'extJs'); diff --git a/workflow/engine/methods/setup/languages_Delete.php b/workflow/engine/methods/setup/languages_Delete.php new file mode 100644 index 000000000..02dae752a --- /dev/null +++ b/workflow/engine/methods/setup/languages_Delete.php @@ -0,0 +1,73 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +//print_r($_GET['LAN_ID']); + +require_once 'classes/model/Language.php'; +require_once 'classes/model/Content.php'; + + +$kk=new Criteria(); +$kk->add(ContentPeer::CON_LANG, $_GET['LAN_ID']); +$oDataset=ContentPeer::doSelectRS($kk); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); + +$aRow1 = $oDataset->getRow(); + +if(is_array($aRow1)) { + + $G_PUBLISH = new Publisher; + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'LANGUAGES'; + + //$aMessage['MESSAGE'] = G::LoadTranslation('CANT_DEL_LANGUAGE');//"you can't delete this language is in use"; + //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/showMessage', '', $aMessage ); + //G::RenderPage('publishBlank', 'blank'); + G::SendTemporalMessage('CANT_DEL_LANGUAGE', 'error', 'labels'); + G::header('location: languages'); +}else { + + /*the reason why comment it was because when delete some language,we're losing some labels about this language*/ + $oCriteria = new Criteria('workflow'); + $oCriteria->add(ContentPeer::CON_LANG, $_GET['LAN_ID']); + ContentPeer::doDelete($oCriteria); + + /* + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(LanguagePeer::LAN_ENABLED, 0); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(LanguagePeer::LAN_ID, $_GET['LAN_ID']); + LanguagePeer::doUpdate($oCriteria2, $oCriteria1, Propel::getConnection('workflow')); + */ + $aLanguage['LAN_ID'] =$_GET['LAN_ID']; + $aLanguage['LAN_ENABLED']=0; + + $oLanguage = new Language(); + $oLanguage->update($aLanguage); + + G::header('Location: languages'); +} diff --git a/workflow/engine/methods/setup/languages_Export.php b/workflow/engine/methods/setup/languages_Export.php new file mode 100644 index 000000000..bfa73a196 --- /dev/null +++ b/workflow/engine/methods/setup/languages_Export.php @@ -0,0 +1,288 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +require_once 'classes/model/IsoCountry.php'; +require_once 'classes/model/Language.php'; +require_once 'classes/model/Translation.php'; + +//G::LoadThirdParty('pear', 'Benchmark/Timer'); +G::LoadSystem('i18n_po'); + +//echo G::getMemoryUsage(); +//$timer = new Benchmark_Timer(); +//$timer->start(); + +//creating the .po file + +if( ! isset($_GET['LOCALE']) ) + throw new Exception('Language Target ID was not set!'); + +$sPOFile = PATH_CORE . 'content' . PATH_SEP . 'translations' . PATH_SEP . MAIN_POFILE . '.' . $_GET['LOCALE'] . '.po'; +$poFile = new i18n_PO($sPOFile); +$poFile->buildInit(); +$locale = $_GET['LOCALE']; +$language = new Language(); + +if( strpos($locale, Translation::$localeSeparator) !== false ) { + list($LAN_ID, $IC_UID) = explode(Translation::$localeSeparator, $_GET['LOCALE']); + $iCountry = new IsoCountry(); + $iCountryRecord = $iCountry->findById($IC_UID); + + if( ! isset($iCountryRecord['IC_UID']) ) + throw new Exception("Country Target ID '{$_GET['LAN_ID']}' doesn't exist!"); + + $sCountry = $iCountryRecord['IC_NAME']; +} else { + $LAN_ID = $locale; + $sCountry = $IC_UID = ''; +} + +$langRecord = $language->findById($LAN_ID); + +if( ! isset($langRecord['LAN_NAME']) ) + throw new Exception("Language Target ID \"{$LAN_ID}\" doesn't exist!"); + +$sLanguage = $langRecord['LAN_NAME']; + +//setting headers +$poFile->addHeader('Project-Id-Version' , PO_SYSTEM_VERSION); +$poFile->addHeader('POT-Creation-Date' , ''); +$poFile->addHeader('PO-Revision-Date' , date('Y-m-d H:i+0100')); +$poFile->addHeader('Last-Translator' , ''); +$poFile->addHeader('Language-Team' , 'Colosa Developers Team '); +$poFile->addHeader('MIME-Version' , '1.0'); +$poFile->addHeader('Content-Type' , 'text/plain; charset=utf-8'); +$poFile->addHeader('Content-Transfer_Encoding' , '8bit'); +$poFile->addHeader('X-Poedit-Language' , ucwords($sLanguage)); +$poFile->addHeader('X-Poedit-Country' , ucwords($sCountry)); +$poFile->addHeader('X-Poedit-SourceCharset' , 'utf-8'); +$poFile->addHeader('Content-Transfer-Encoding' , '8bit'); + +//$timer->setMarker('end making po headers'); +//export translation + +$aLabels = array(); +$aMsgids = array(); +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(TranslationPeer::TRN_CATEGORY); +$oCriteria->addSelectColumn(TranslationPeer::TRN_ID); +$oCriteria->addSelectColumn(TranslationPeer::TRN_VALUE); +$oCriteria->add(TranslationPeer::TRN_LANG, 'en'); +$oDataset = TranslationPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); + +while ($aRow1 = $oDataset->getRow()) { + if( $LAN_ID != 'en' ){ + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TranslationPeer::TRN_VALUE); + $oCriteria->add(TranslationPeer::TRN_CATEGORY, $aRow1['TRN_CATEGORY']); + $oCriteria->add(TranslationPeer::TRN_ID, $aRow1['TRN_ID']); + $oCriteria->add(TranslationPeer::TRN_LANG, $_GET['LOCALE']); + $oDataset2 = TranslationPeer::doSelectRS($oCriteria); + $oDataset2->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset2->next(); + $aRow2 = $oDataset2->getRow(); + } else { + $aRow2 = $aRow1; + } + $aRow1['TRN_CATEGORY'] = trim($aRow1['TRN_CATEGORY']); + + # Validation + # implemented to validate that the TRN_CATEGORY field into TRANSLALTION table is valid + # By Erik A. Ortiz on Thu Feb 4, 2010 + preg_match("/^[0-9a-zA-Z_-]+/", $aRow1['TRN_CATEGORY'], $sTestResult); + + if( $sTestResult[0] === $aRow1['TRN_CATEGORY']){ #the regular expr. evaluated ()$sTestResult) for $aRow1['TRN_CATEGORY'] must be the same + $msgid = trim($aRow1['TRN_VALUE']); + + if ( isset($aMsgids[$msgid]) ) + $msgid = '[' . $aRow1['TRN_CATEGORY'] . '/' . $aRow1['TRN_ID'] . '] ' . $msgid; + + $poFile->addTranslatorComment('TRANSLATION'); + $poFile->addTranslatorComment($aRow1['TRN_CATEGORY'] . '/' . $aRow1['TRN_ID']); + $poFile->addReference($aRow1['TRN_CATEGORY'] . '/' . $aRow1['TRN_ID']); + + $msgstr = ($aRow2 && $aRow2['TRN_VALUE'] != '' ) ? $aRow2['TRN_VALUE'] : $aRow1['TRN_VALUE']; + $poFile->addTranslation($msgid, $msgstr); + $aMsgids[$msgid] = true; + } else { #Autocleaning, delete the inconsistant data + $oTranslation = new Translation; + $oTranslation->remove($aRow1['TRN_CATEGORY'], $aRow1['TRN_ID'], $_GET['LAN_ID']); + } + $oDataset->next(); +} + +//$timer->setMarker('end making 1th .po from db'); + +//now find labels in xmlforms +/************/ +$aExceptionFields = array('', 'javascript', 'hidden', 'phpvariable', 'private', 'toolbar', 'xmlmenu', 'toolbutton', 'cellmark', 'grid'); + +//find all xml files into PATH_XMLFORM +$aXMLForms = glob(PATH_XMLFORM . '*/*.xml'); +//from a sublevel to +$aXMLForms2 = glob(PATH_XMLFORM . '*/*/*.xml'); +$aXMLForms = array_merge($aXMLForms, $aXMLForms2); + +$aEnglishLabel = array(); +$aOptions = array(); + +foreach ($aXMLForms as $sXmlForm) { + $sXmlForm = str_replace( chr(92), '/', $sXmlForm); + $sXmlForm = str_replace( PATH_XMLFORM, '', $sXmlForm); + $oForm = new Form( $sXmlForm, '', 'en'); + + //get all fields of each xmlform + foreach ($oForm->fields as $sNodeName => $oNode) { + if (is_object($oNode)) { + if (trim($oNode->label) != '') { + //$aEnglishLabel[$oNode->name] = str_replace('"', '\"', stripslashes(ltrim(str_replace(chr(10), '', $oNode->label)))); + $aEnglishLabel[$oNode->name] = stripslashes(trim(str_replace(chr(10), '', $oNode->label))); + $aOptions[$sXmlForm . '?' . $oNode->name] = $aEnglishLabel[$oNode->name]; + } + if (isset($oNode->options)) { + if (!empty($oNode->options)) { + foreach ($oNode->options as $sKey => $sValue) { + //$aEnglishLabel[$oNode->name . '-' . $sKey] = str_replace('"', '\"', stripslashes(ltrim(str_replace(chr(10), '', $sValue)))); + $aEnglishLabel[$oNode->name . '-' . $sKey] = stripslashes(ltrim(str_replace(chr(10), '', $sValue))); + if (isset($aOptions[$sXmlForm . '?' . $oNode->name])) { + if (!is_array($aOptions[$sXmlForm . '?' . $oNode->name])) { + $sAux = $aOptions[$sXmlForm . '?' . $oNode->name]; + $aOptions[$sXmlForm . '?' . $oNode->name] = array(); + } + } + $aOptions[$sXmlForm . '?' . $oNode->name][$sKey] = $aEnglishLabel[$oNode->name . '-' . $sKey]; + } + } + } + } + } //end foreach + unset($oForm->fields); + unset($oForm->tree); + unset($oForm); + + //now go to the fields array + $oForm = new Form($sXmlForm, '', $_GET['LOCALE']); + $i = 1; + $iNumberOfFields = count($oForm->fields); + foreach ($oForm->fields as $sNodeName => $oNode) { + if (is_object($oNode)) { + if ( isset($aEnglishLabel[$oNode->name]) ) { + $msgid = $aEnglishLabel[$oNode->name]; + //$oNode->label = str_replace('"', '\"', stripslashes(ltrim(str_replace(chr(10), '', $oNode->label)))); + $oNode->label = stripslashes(ltrim(str_replace(chr(10), '', $oNode->label))); + } else + $msgid = ''; + + if ( !in_array(strtolower($oNode->type), $aExceptionFields)) { + if ((strpos($msgid, '@G::LoadTranslation') === false) && (strpos($oNode->label, '@G::LoadTranslation') === false)) { + //if (in_array($msgid, $aMsgids)) { + if ( isset($aMsgids[$msgid]) ) { + $msgid = trim ( '[' . $sXmlForm . '?' . $oNode->name . '] ' . $oNode->label ); + } + /*$aLabels[] = array( + 0 => '# ' . $sXmlForm . '?' . $sNodeName, + 1 => '# ' . $sXmlForm, + 2 => '#: ' . $oNode->type . ' - ' . $sNodeName, + 3 => 'msgid "' . $msgid . '"', + 4 => 'msgstr "' . trim($oNode->label) . '"' + );*/ + + $poFile->addTranslatorComment($sXmlForm . '?' . $sNodeName); + $poFile->addTranslatorComment($sXmlForm); + $poFile->addReference($oNode->type . ' - ' . $sNodeName); + $poFile->addTranslation($msgid, trim($oNode->label)); + + //$aMsgids[] = $msgid; + $aMsgids[$msgid] = 1; + + if (isset($oNode->options)) { + if (!empty($oNode->options)) { + foreach ($oNode->options as $sKey => $sValue) { + if ($sKey === '') { + $sKey = "''"; + } + $msgid = '[' . $sXmlForm . '?' . $oNode->name . '-' . $sKey . ']'; + $poFile->addTranslatorComment($sXmlForm . '?' . $sNodeName . '-'. $sKey); + $poFile->addTranslatorComment($sXmlForm); + $poFile->addReference($oNode->type . ' - ' . $sNodeName . ' - ' . $sKey); + $poFile->addTranslation($msgid, $sValue); + + $aMsgids[$msgid] = true; + } + } else { + if (isset($aOptions[$sXmlForm . '?' . $sNodeName])) { + if (is_array($aOptions[$sXmlForm . '?' . $sNodeName])) { + foreach ($aOptions[$sXmlForm . '?' . $sNodeName] as $sKey => $sValue) { + if ($sKey === '') + $sKey = "''"; + + $msgid = '[' . $sXmlForm . '?' . $oNode->name . '-' . $sKey . ']'; + $poFile->addTranslatorComment($sXmlForm . '?' . $sNodeName . '-'. $sKey); + $poFile->addTranslatorComment($sXmlForm); + $poFile->addReference($oNode->type . ' - ' . $sNodeName . ' - ' . $sKey); + $poFile->addTranslation($msgid, $sValue); + $aMsgids[$msgid] = true; + } + } + } + } + } else { + if (isset($aOptions[$sXmlForm . '?' . $sNodeName])) { + if (is_array($aOptions[$sXmlForm . '?' . $sNodeName])) { + foreach ($aOptions[$sXmlForm . '?' . $sNodeName] as $sKey => $sValue) { + if ($sKey === '') + $sKey = "''"; + + $msgid = '[' . $sXmlForm . '?' . $oNode->name . '-' . $sKey . ']'; + $poFile->addTranslatorComment($sXmlForm . '?' . $sNodeName . '-'. $sKey); + $poFile->addTranslatorComment($sXmlForm); + $poFile->addReference($oNode->type . ' - ' . $sNodeName . ' - ' . $sKey); + $poFile->addTranslation($msgid, $sValue); + $aMsgids[$msgid] = true; + } + } + } + } + } + } + } + $i++; + } + unset($oForm->fields); + unset($oForm->tree); + unset($oForm); +} +/*******************/ +// +//$timer->setMarker('end xml files processed'); +//$profiling = $timer->getProfiling(); +//$timer->stop(); $timer->display(); +//echo G::getMemoryUsage(); +//die; +//g::pr($profiling); + +G::streamFile($sPOFile, true); + diff --git a/workflow/engine/methods/setup/languages_Import.php b/workflow/engine/methods/setup/languages_Import.php new file mode 100644 index 000000000..ddab2fbd8 --- /dev/null +++ b/workflow/engine/methods/setup/languages_Import.php @@ -0,0 +1,85 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); + +if( $access != 1 ) { + switch( $access ) { + case -1: G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); break; + case -2: G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); break; + default: G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); break; + } + G::header('location: ../login/login'); + exit(0); +} + +$result = new stdClass(); + +try { + if(!is_writable(PATH_XMLFORM)) + throw new Exception(G::LoadTranslation('IMPORT_LANGUAGE_ERR_NO_WRITABLE')); + + $sMaxExecutionTime = ini_get('max_execution_time'); + ini_set('max_execution_time', '0'); + G::LoadClass('languages'); + G::LoadClass('configuration'); + + $languages = new languages(); + $configuration = new Configurations; + $importResults = $languages->importLanguage($_FILES['form']['tmp_name']['LANGUAGE_FILENAME']); + + //G::SendTemporalMessage('IMPORT_LANGUAGE_SUCCESS', 'info', 'labels'); + //G::header('location: languages'); + + $result->msg = G::LoadTranslation('IMPORT_LANGUAGE_SUCCESS') . "\n"; + $result->msg .= "PO File num. records: " . $importResults->recordsCount . "\n"; + $result->msg .= "Records registered successfully : " . $importResults->recordsCountSuccess . "\n"; + //$result->msg = htmlentities($result->msg); + $result->success = true; + + //saving metadata + $configuration->aConfig = Array( + 'headers' => $importResults->headers, + 'language' => $importResults->lang, + 'import-date' => date('Y-m-d H:i:s'), + 'user' => '', + 'version' => '1.0' + ); + $configuration->saveConfig('LANGUAGE_META', $importResults->lang); + + ini_set('max_execution_time', $sMaxExecutionTime); + +} catch (Exception $oError) { + $result->msg = $oError->getMessage(); + //print_r($oError->getTrace()); + $result->success = false; + //G::SendTemporalMessage($oError->getMessage(), 'error', 'string'); + //G::header('location: languages_ImportForm'); +} +echo G::json_encode($result); + + + + diff --git a/workflow/engine/methods/setup/languages_ImportForm.php b/workflow/engine/methods/setup/languages_ImportForm.php new file mode 100644 index 000000000..d90f92324 --- /dev/null +++ b/workflow/engine/methods/setup/languages_ImportForm.php @@ -0,0 +1,66 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'LANGUAGES'; + +/* +$oForm = new Form('setup/languages_ImportForm', '', SYS_LANG); +$oForm->action = 'languages_Import'; +echo '' . +$oForm->render(PATH_CORE . 'templates/xmlform.html', $scriptCode = ''); +*/ + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/languages_ImportForm', '', '', 'languages_Import'); +G::RenderPage('publishBlank', 'blank'); + + + + + diff --git a/workflow/engine/methods/setup/location.php b/workflow/engine/methods/setup/location.php new file mode 100644 index 000000000..d4acd0f10 --- /dev/null +++ b/workflow/engine/methods/setup/location.php @@ -0,0 +1,162 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + + $G_ENABLE_BLANK_SKIN = true; + + $uid = $_SESSION['USER_LOGGED']; + + $dbc = new DBConnection; + $ses = new DBSession($dbc); + + G::LoadClass ( 'templateTable' ); + + $query=$ses->execute('select USR_COUNTRY ,USR_CITY ,USR_LOCATION from USER where UID = "'.$uid.'"'); + $param=$query->read(); + + $city=$param['USR_CITY']; + $query=$ses->execute('SELECT UID,CAPTION FROM TERRITORY WHERE TERRITORY="LOCATION" AND RELATION="'.$city.'"'); +/* +$table=new templateTable('list_template.html','DIV_LOCATIONS'); + $table->formatTitleCol(0,'width="80%"'); + $table->formatTitleCol(1,'align="center"'); + $table->formatCol(0,'width="80%" '); + $table->formatCol(1,'align="center"'); + +$table->addTitle(array(G::LoadTranslation('ID_LOCATION'),'')); +for($r=0;$r<$query->count();$r++) +{ + $row=$query->read(); + $vrow=array($row['CAPTION']); + $vrow[]=''.G::LoadTranslation('ID_DELETE').''; + $table->addRow($r,$vrow); +} +$table->addRowTag($r,'lastRow','',''); + $table->addRow($r, + array( + $table->getBlock('text',array('value' => '', 'properties' => 'id="newLocation"')), + ''.G::LoadTranslation('ID_ADD').'' + )); +*/ + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent( 'xmlform', 'xmlform', 'setup/location', '', $param ); +//$G_PUBLISH->AddContent('template', '', '', '', $table->tpl); + +G::RenderPage( 'publish' ); + +?> + + diff --git a/workflow/engine/methods/setup/logo_Delete.php b/workflow/engine/methods/setup/logo_Delete.php new file mode 100644 index 000000000..38232eac4 --- /dev/null +++ b/workflow/engine/methods/setup/logo_Delete.php @@ -0,0 +1,51 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + $snameLogo =trim($_GET['NAMELOGO']); + $ainfoSite = explode("/",$_SERVER["REQUEST_URI"]); + $dir=PATH_DATA."sites".PATH_SEP.str_replace("sys","",$ainfoSite[1]).PATH_SEP."files/logos"; + $sfileDir=$dir.PATH_SEP.$snameLogo; + unlink($sfileDir); + //header('location: uplogo.php'); + +} catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/main.php b/workflow/engine/methods/setup/main.php new file mode 100755 index 000000000..4895d61f6 --- /dev/null +++ b/workflow/engine/methods/setup/main.php @@ -0,0 +1,40 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$RBAC->requirePermissions('PM_SETUP'); + +$G_MAIN_MENU = 'processmaker'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_PUBLISH = new Publisher; + +if( isset($_GET['i18']) ) + $_SESSION['DEV_FLAG'] = $_SESSION['TOOLS_VIEWTYPE'] = isset($_GET['i18']); +else { + unset($_SESSION['DEV_FLAG']); + unset($_SESSION['TOOLS_VIEWTYPE']); +} +$G_PUBLISH->AddContent('view', 'setup/main_Load'); +G::RenderPage('publish'); + diff --git a/workflow/engine/methods/setup/mainAjax.php b/workflow/engine/methods/setup/mainAjax.php new file mode 100755 index 000000000..02d86eb82 --- /dev/null +++ b/workflow/engine/methods/setup/mainAjax.php @@ -0,0 +1,64 @@ +load('setup'); + $items = Array(); + + foreach( $oMenu->Options as $i=>$option) { + if( $oMenu->Types[$i] == $_GET['menu'] ){ + $items[] = Array( + 'id' => $oMenu->Id[$i], + 'url' => ($oMenu->Options[$i]!='')? $oMenu->Options[$i]: '#', + //'onclick' => ($oMenu->JS[$i]!='')? $oMenu->JS[$i]: '', + 'text' => $oMenu->Labels[$i], + //'icon' => ($oMenu->Icons[$i]!='')? $oMenu->Icons[$i]: 'icon-pmlogo.png', + //'target'=> ($oMenu->Types[$i]=='admToolsContent')? 'admToolsContent': '' + 'loaded' => true, + 'leaf' => true, + 'cls' => 'pm-tree-node', + 'iconCls'=> 'ICON_'.$oMenu->Id[$i] + ); + } else if( in_array($oMenu->Types[$i], Array('', 'admToolsContent')) && $_GET['menu'] == 'plugins' ){ + $items[] = Array( + 'id' => $oMenu->Id[$i], + 'url' => ($oMenu->Options[$i]!='')? $oMenu->Options[$i]: '#', + //'onclick' => ($oMenu->JS[$i]!='')? $oMenu->JS[$i]: '', + 'text' => $oMenu->Labels[$i], + //'icon' => ($oMenu->Icons[$i]!='')? $oMenu->Icons[$i]: 'icon-pmlogo.png', + //'target'=> ($oMenu->Types[$i]=='admToolsContent')? 'admToolsContent': '' + 'loaded' => true, + 'leaf' => true, + 'cls' => 'pm-tree-node', + 'iconCls'=> 'ICON_'.$oMenu->Id[$i] + ); + } + } + + if( isset($_SESSION['DEV_FLAG']) && $_SESSION['DEV_FLAG'] && $_GET['menu'] == 'settings' ){ + $items[] = Array( + 'id' => 'translations', + 'url' => '../tools/translations', + 'text' => 'Translations', + 'loaded' => true, + 'leaf' => true, + 'cls' => 'pm-tree-node', + 'iconCls'=> 'ICON_' + ); + } + $x = ob_get_contents(); + ob_end_clean(); + echo G::json_encode($items); + break; + +} \ No newline at end of file diff --git a/workflow/engine/methods/setup/main_init.php b/workflow/engine/methods/setup/main_init.php new file mode 100755 index 000000000..5f3b61f24 --- /dev/null +++ b/workflow/engine/methods/setup/main_init.php @@ -0,0 +1,71 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $RBAC->requirePermissions('PM_SETUP'); + + $oHeadPublisher =& headPublisher::getSingleton(); + + global $G_TMP_MENU; + $oMenu = new Menu(); + $oMenu->load('setup'); + $items = Array(); + + $menuTypes = array_unique($oMenu->Types); + foreach($menuTypes as $i=>$v){ + if( $v == 'admToolsContent'){ + unset($menuTypes[$i]); + break; + } + } + //sort($menuTypes); + + $tabItems = Array(); + $i=0; + foreach( $menuTypes as $menuType ){ + $tabItems[$i]->id = $menuType; + $LABEL_TRANSLATION = G::LoadTranslation("ID_".strtoupper($menuType)); + + if( substr($LABEL_TRANSLATION,0,2) !== '**' ){ + $title = $LABEL_TRANSLATION; + } else { + $title = str_replace('_', ' ', ucwords($menuType)); + } + $tabItems[$i]->title = $title; + $i++; + } + + $oHeadPublisher->addExtJsScript('setup/main', false); //adding a javascript file .js + $oHeadPublisher->addContent('setup/main'); //adding a html file .html. + $oHeadPublisher->assign('tabItems', $tabItems); + + G::RenderPage('publish', 'extJs'); + // this patch enables the load of the plugin list panel inside de main admin panel iframe + if (isset($_GET['action'])&&$_GET['action']=='pluginsList'){ + print " + + "; + } \ No newline at end of file diff --git a/workflow/engine/methods/setup/pluginsChange.php b/workflow/engine/methods/setup/pluginsChange.php new file mode 100755 index 000000000..e43bf158e --- /dev/null +++ b/workflow/engine/methods/setup/pluginsChange.php @@ -0,0 +1,62 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +// lets display the items + $pluginFile = $_GET['id']; + $pluginStatus = $_GET['status']; + + $items = array (); + G::LoadClass('plugin'); + //here we are enabling or disabling the plugin and all related options registered. + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + + if ($handle = opendir( PATH_PLUGINS )) { + while ( false !== ($file = readdir($handle))) { + if ( strpos($file, '.php', 1 ) && $file == $pluginFile) { + + if ( $pluginStatus == '1' ) { + //print "change to disable"; + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + $oPluginRegistry->disablePlugin( $details->sNamespace ); + $size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); + print "size saved : $size
    "; + } else { + //print "change to ENABLED"; + require_once ( PATH_PLUGINS . $pluginFile ); + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + $oPluginRegistry->enablePlugin( $details->sNamespace); + $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + $size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); + print "size saved : $size
    "; + } + } + } + closedir($handle); + } + + //$oPluginRegistry->showArrays(); + //G::Header('location: pluginsList'); + diff --git a/workflow/engine/methods/setup/pluginsImport.php b/workflow/engine/methods/setup/pluginsImport.php new file mode 100644 index 000000000..419867293 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsImport.php @@ -0,0 +1,78 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + G::LoadClass('plugin'); + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'PLUGINS'; + + + //calculating the max upload file size; + $POST_MAX_SIZE = ini_get('post_max_size'); + $mul = substr($POST_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $postMaxSize = (int)$POST_MAX_SIZE * $mul; + + $UPLOAD_MAX_SIZE = ini_get('upload_max_filesize'); + $mul = substr($UPLOAD_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $uploadMaxSize = (int)$UPLOAD_MAX_SIZE * $mul; + + if ( $postMaxSize < $uploadMaxSize ) $uploadMaxSize = $postMaxSize; + $Fields['MAX_FILE_SIZE'] = $uploadMaxSize . " (" . $UPLOAD_MAX_SIZE . ") "; + + $G_PUBLISH = new Publisher; + try { + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', 'setup/pluginImport', '',$Fields ,'pluginsImportFile' ); + } + catch ( Exception $e ){ + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + } + G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/pluginsImportFile.php b/workflow/engine/methods/setup/pluginsImportFile.php new file mode 100644 index 000000000..7eb10c714 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsImportFile.php @@ -0,0 +1,143 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +global $RBAC; +$RBAC->requirePermissions('PM_SETUP_ADVANCE'); + +try { + //load the variables + G::LoadClass('plugin'); + if ( ! isset($_FILES['form']['error']['PLUGIN_FILENAME'] ) || $_FILES['form']['error']['PLUGIN_FILENAME'] == 1 ) { + throw ( new Exception ("There was an error uploading the file, probably the file size if greater than upload_max_filesize parameter in php.ini, please check this parameter and try again." ) ); + } + + //save the file + if ($_FILES['form']['error']['PLUGIN_FILENAME'] == 0) { + $filename = $_FILES['form']['name']['PLUGIN_FILENAME']; + $path = PATH_DOCUMENT . 'input' . PATH_SEP ; + $tempName = $_FILES['form']['tmp_name']['PLUGIN_FILENAME']; + G::uploadFile($tempName, $path, $filename ); + } + if ( ! $_FILES['form']['type']['PLUGIN_FILENAME'] == 'application/octet-stream') + throw ( new Exception ( "the uploaded files are invalid, expected 'application/octect-stream mime type file (". $_FILES['form']['type']['PLUGIN_FILENAME'] . ")" )); + + + G::LoadThirdParty( 'pear/Archive','Tar'); + $tar = new Archive_Tar ( $path. $filename); + $sFileName = substr($filename,0,strrpos($filename, '.' )); + $sClassName = substr($filename,0,strpos($filename, '-' )); + + $aFiles = $tar->listContent(); + $bMainFile = false; + $bClassFile = false; + foreach ( $aFiles as $key => $val ) { + if ( $val['filename'] == $sClassName . '.php' ) $bMainFile = true; + if ( $val['filename'] == $sClassName . PATH_SEP . 'class.' . $sClassName . '.php' ) $bClassFile = true; + } + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $pluginFile = $sClassName . '.php'; + + if ( $bMainFile && $bClassFile ) { + $sAux = $sClassName . 'Plugin'; + $fVersionOld = 0.0; + if (file_exists(PATH_PLUGINS . $pluginFile)) { + if (!class_exists($sAux) && !class_exists($sClassName . 'plugin')) { + include PATH_PLUGINS . $pluginFile; + } + if (!class_exists($sAux)) { + $sAux = $sClassName . 'plugin'; + } + $oClass = new $sAux($sClassName); + $fVersionOld = $oClass->iVersion; + unset($oClass); + } + $res = $tar->extract ( $path ); + $sContent = file_get_contents($path . PATH_SEP . $pluginFile); + $sContent = str_ireplace($sAux, $sAux . '_', $sContent); + $sContent = str_ireplace('$oPluginRegistry =& PMPluginRegistry::getSingleton();', '', $sContent); + $sContent = str_ireplace('$oPluginRegistry->registerPlugin(\'' . $sClassName . '\', __FILE__);', '', $sContent); + //header('Content-Type: text/plain');var_dump($sClassName, $sContent);die; + file_put_contents($path . PATH_SEP . $pluginFile, $sContent); + $sAux = $sAux . '_'; + include $path . PATH_SEP . $pluginFile; + $oClass = new $sAux($sClassName); + $fVersionNew = $oClass->iVersion; + if (!isset($oClass->iPMVersion)) { + $oClass->iPMVersion = 0; + } + if ($oClass->iPMVersion > 0) { + if (!defined('PM_VERSION')) { + define('PM_VERSION', 0); + } + if (PM_VERSION > 0) { + if ($oClass->iPMVersion > PM_VERSION) { + //throw new Exception('This plugin needs version ' . $oClass->iPMVersion . ' or higher of ProcessMaker'); + } + } + } + if (!isset($oClass->aDependences)) { + $oClass->aDependences = null; + } + if (!empty($oClass->aDependences)) { + foreach ($oClass->aDependences as $aDependence) { + if (file_exists(PATH_PLUGINS . $aDependence['sClassName'] . '.php')) { + require_once PATH_PLUGINS . $aDependence['sClassName'] . '.php'; + if (!$oPluginRegistry->getPluginDetails($aDependence['sClassName'] . '.php')) { + throw new Exception('This plugin needs "' . $aDependence['sClassName'] . '" plugin'); + } + } + else { + throw new Exception('This plugin needs "' . $aDependence['sClassName'] . '" plugin'); + } + } + } + unset($oClass); + if ($fVersionOld > $fVersionNew) { + throw new Exception('A recent version of this plugin was already installed.'); + } + $res = $tar->extract ( PATH_PLUGINS ); + } + else + throw ( new Exception ( "The file $filename doesn't contain class: $sClassName ") ) ; + + if ( !file_exists ( PATH_PLUGINS . $sClassName . '.php' ) ) throw ( new Exception( "File '$pluginFile' doesn't exists ") ); + + require_once ( PATH_PLUGINS . $pluginFile ); + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + + $oPluginRegistry->installPlugin( $details->sNamespace); + $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + $size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); + + G::header ( 'Location: pluginsMain'); + die; +} +catch ( Exception $e ){ + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publishBlank', 'blank'); +} diff --git a/workflow/engine/methods/setup/pluginsList.php b/workflow/engine/methods/setup/pluginsList.php new file mode 100644 index 000000000..cac8b1c23 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsList.php @@ -0,0 +1,125 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$RBAC->requirePermissions('PM_SETUP_ADVANCE'); + +// lets display the items +//$items = array ( 'id' => 'char', 'title' => 'char', 'type' => 'char', 'creator' => 'char' , 'modifiedBy' => 'char', 'filename' => 'char', 'size' => 'char', 'mime' => 'char'); + + +$items = Array(); +//***************** Plugins ************************** + G::LoadClass('plugin'); + //here we are loading all plugins registered +//krumo ($items); die; + $aPluginsPP = array(); + if (is_file(PATH_PLUGINS . 'enterprise/data/data')) { + $aPlugins = unserialize(trim(file_get_contents(PATH_PLUGINS . 'enterprise/data/data'))); + foreach ($aPlugins as $aPlugin) { + $aPluginsPP[] = substr($aPlugin['sFilename'], 0, strpos($aPlugin['sFilename'], '-')) . '.php'; + } + } + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ($handle = opendir( PATH_PLUGINS )) { + while ( false !== ($file = readdir($handle))) { + + if (in_array($file, $aPluginsPP)) { + continue; + } + if ( strpos($file, '.php',1) && is_file(PATH_PLUGINS . $file) ) { + include_once ( PATH_PLUGINS . $file ); + $pluginDetail = $oPluginRegistry->getPluginDetails ( $file ); + //print_R ($pluginDetail ); + //die; + //$status = $pluginDetail->enabled ? 'Enabled' : 'Disabled'; + if($pluginDetail==NULL) continue; //When for some reason we gen NULL plugin + $status_label = $pluginDetail->enabled ? G::LoadTranslation('ID_ENABLED') : G::LoadTranslation('ID_DISABLED'); + $status = $pluginDetail->enabled ? 1: 0; + if ( isset ($pluginDetail->aWorkspaces ) ) { + if ( ! in_array ( SYS_SYS, $pluginDetail->aWorkspaces) ) + continue; + } + $linkEditValue = $pluginDetail->sSetupPage != '' && $pluginDetail->enabled ? G::LoadTranslation('ID_SETUP') : ' '; + //g::pr($pluginDetail->sSetupPage); + $setup = $pluginDetail->sSetupPage != '' && $pluginDetail->enabled ? '1' : '0'; + + $link = 'pluginsChange?id=' . $file . '&status=' . $pluginDetail->enabled; + $linkEdit = 'pluginsSetup?id=' . $file ; + $pluginName = $pluginDetail->sFriendlyName; + $pluginId = $pluginDetail->sNamespace; + $removePluginMsg = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_REMOVE_PLUGIN')); + $linkRemove = 'javascript:showMessage(\''.$removePluginMsg .'
    '.$pluginName.' \',\''.$pluginId.'\')'; +// $linkRemove = 'pluginsRemove?id='.$pluginId.'.php&status=1'; + if ( isset ($pluginDetail) ){ + if(!$pluginDetail->bPrivate){ + $items[] = array ( + 'id' => (count($items) + 1), + 'namespace'=>$pluginDetail->sNamespace, + 'title'=>$pluginDetail->sFriendlyName . "\n(" . $pluginDetail->sNamespace . '.php)', + 'className' => $pluginDetail->sNamespace, + 'description' => $pluginDetail->sDescription, + 'version' => $pluginDetail->iVersion, + 'setupPage' => $pluginDetail->sSetupPage, + 'status_label'=> $status_label, + 'status'=> $status, + 'setup'=>$setup, + + 'sFile' => $file, + 'sStatusFile' => $pluginDetail->enabled + ); + } + } + + } + } + closedir($handle); + } + + $folders['items'] = $items; + //g::pr($items); + echo G::json_encode($items); + die; + $_DBArray['plugins'] = $items; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('plugins'); + //$c->addAscendingOrderByColumn ('id'); + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'PLUGINS'; + + $G_PUBLISH = new Publisher; + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/setup/pluginList.js'); + + $G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'setup/pluginList', $c ); + G::RenderPage('publishBlank', 'blank'); + +?> diff --git a/workflow/engine/methods/setup/pluginsMain.php b/workflow/engine/methods/setup/pluginsMain.php new file mode 100755 index 000000000..fc7fb7b79 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsMain.php @@ -0,0 +1,41 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$oHeadPublisher =& headPublisher::getSingleton(); + + $oHeadPublisher->addExtJsScript('setup/pluginsMain', false ); //adding a javascript file .js + //$oHeadPublisher->addContent('setup/main'); //adding a html file .html. + + $translations = G::getTranslations(Array( + 'ID_CONFIGURE', 'ID_STATUS', 'ID_DELETE', 'ID_IMPORT', 'ID_SELECT', + 'ID_STATUS', 'ID_ACTIVATE', 'ID_DEACTIVATE', + 'ID_SELECT', 'ID_NO_SELECTION_WARNING', 'ID_MSG_REMOVE_PLUGIN', + 'ID_TITLE', 'ID_VERSION', 'ID_STATUS', 'ID_TITLE', 'ID_VERSION', 'ID_DESCRIPTION', 'ID_STATUS' + )); + $oHeadPublisher->assign('TRANSLATIONS', $translations); + G::RenderPage('publish', 'extJs'); + + + diff --git a/workflow/engine/methods/setup/pluginsRemove.php b/workflow/engine/methods/setup/pluginsRemove.php new file mode 100644 index 000000000..af00dd291 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsRemove.php @@ -0,0 +1,102 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* +global $RBAC; +switch ($RBAC->userCanAccess('PM_SETUP_ADVANCE')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +}*/ + +/** + * function rmdir_recursive + * @author gustavo cruz gustavo-at-colosa-dot-com + * @param $dir directory to be erased + * @desc Fork of the rmdir native command this one also erase + * the content of the directory recursively. + */ +function rmdir_recursive($dir) { + $files = scandir($dir); + array_shift($files); // remove '.' from array + array_shift($files); // remove '..' from array + + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (is_dir($file)) { + rmdir_recursive($file); +// rmdir($file); + } else { + unlink($file); + } + } + //rmdir($dir); +} + +G::LoadClass('plugin'); +$oPluginRegistry =& PMPluginRegistry::getSingleton(); + +$oDir = PATH_PLUGINS.trim($_POST['pluginUid']); +$oFile = PATH_PLUGINS.$_POST['pluginUid'].".php"; +$pluginFile = $_POST['pluginUid'].".php"; +//G::pr($pluginFile); +//G::pr($oFile); +if ($handle = opendir( PATH_PLUGINS )) { + while ( false !== ($file = readdir($handle))) { + if ( strpos($file, '.php',1) ) { + if ( $file == $pluginFile ) { + require_once ( PATH_PLUGINS . $pluginFile ); + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + $oPluginRegistry->enablePlugin( $details->sNamespace); + $oPluginRegistry->disablePlugin( $details->sNamespace ); + $size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); + } + } + } + closedir($handle); +} + +//$details = $oPluginRegistry->getPluginDetails( $oFile ); +//G::pr($details); +//$oPluginRegistry->disablePlugin( $details->sNamespace ); +//$size = file_put_contents ( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); +if ($oDir!=""&&$oFile!=""){ + if (is_dir($oDir)) { + rmdir_recursive($oDir); + } + if (file_exists($oFile)){ + unlink($oFile); + } +} + +echo $_POST['pluginUid']." ".str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_REMOVE_PLUGIN_SUCCESS')); + diff --git a/workflow/engine/methods/setup/pluginsSetup.php b/workflow/engine/methods/setup/pluginsSetup.php new file mode 100644 index 000000000..cffb20f89 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsSetup.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $pluginFile = $_GET['id']; + + G::LoadClass('plugin'); + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + $xmlform = isset($details->sPluginFolder) ? $details->sPluginFolder . '/' . $details->sSetupPage : ''; + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'PLUGINS'; + $G_PUBLISH = new Publisher; + try { + //the setup page is a special page + if ( substr($xmlform,-4) == '.php' && file_exists ( PATH_PLUGINS . $xmlform ) ) { + require_once ( PATH_PLUGINS . $xmlform ); + die; + } + + //the setup page is a xmlform and using the default showform and saveform function to serialize data + if ( !file_exists ( PATH_PLUGINS.$xmlform.'.xml' ) ) throw ( new Exception ('setup .xml file is not defined for this plugin') ); + + + $Fields = $oPluginRegistry->getFieldsForPageSetup( $details->sNamespace ); + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', $xmlform, '',$Fields ,'pluginsSetupSave?id='.$pluginFile ); + } + catch ( Exception $e ){ + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + } + G::RenderPage('publishBlank', 'blank'); \ No newline at end of file diff --git a/workflow/engine/methods/setup/pluginsSetupSave.php b/workflow/engine/methods/setup/pluginsSetupSave.php new file mode 100644 index 000000000..0f27a7be7 --- /dev/null +++ b/workflow/engine/methods/setup/pluginsSetupSave.php @@ -0,0 +1,48 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $pluginFile = $_GET['id']; + G::LoadClass('plugin'); + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + + $details = $oPluginRegistry->getPluginDetails( $pluginFile ); + try { + $Fields = $oPluginRegistry->updateFieldsForPageSetup( $details->sNamespace, $_POST ); + $str = "$Fields fields saved successfully!"; + G::SendTemporalMessage($str, 'info', 'string', 3, 100); + G::Header("location: pluginsSetup?id=$pluginFile"); + } catch ( Exception $e ){ + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'PLUGINS'; + + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage('publish'); + } + diff --git a/workflow/engine/methods/setup/processHeartBeatConfig.php b/workflow/engine/methods/setup/processHeartBeatConfig.php new file mode 100755 index 000000000..04e7a2b3c --- /dev/null +++ b/workflow/engine/methods/setup/processHeartBeatConfig.php @@ -0,0 +1,61 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + try { + + $G_PUBLISH = new Publisher; + + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + /*you can use SYS_TEMP or SYS_SYS ON HEAR_BEAT_CONF to save for each workspace*/ + $sflag = $oServerConf->getHeartbeatProperty('HB_OPTION','HEART_BEAT_CONF'); + if(($sflag)||(is_null($sflag))){ + $aRow['HB_OPTION']='1'; + + $nextBeatDate = $oServerConf->getHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + $nextBeatMessage=" ".G::LoadTranslation("ID_NEXT_BEAT"); + + if(is_null($nextBeatDate)){ + $nextBeatMessage.=" ".G::LoadTranslation("ID_NEXT_BEAT_LOGIN"); + }else{ + $nextBeatMessage.=" ".date("Y-m-d H:i:s",$nextBeatDate); + } + $aRow['HB_MESSAGE']=$nextBeatMessage; + }else{ + $aRow['HB_OPTION']='0'; + $aRow['HB_MESSAGE']=""; + } + + + if($oServerConf->getHeartbeatProperty('HB_BEAT_TYPE','HEART_BEAT_CONF')=="endbeat"){ + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + + function processHbInfo(){ + ajax_server="../services/processHeartBeat_Ajax.php"; + parameters="action=processInformation"; + method="POST"; + callback=""; + asynchronous=true; + ajax_post(ajax_server, parameters, method, callback, asynchronous ); + } + processHbInfo(); + '); + } + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/processHeartBeatConfig', '', $aRow, 'processHeartBeatSave' ); + + G::RenderPage('publishBlank', 'blank'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publishBlank', 'blank' ); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/processHeartBeatSave.php b/workflow/engine/methods/setup/processHeartBeatSave.php new file mode 100755 index 000000000..c5faa71d5 --- /dev/null +++ b/workflow/engine/methods/setup/processHeartBeatSave.php @@ -0,0 +1,35 @@ +userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + try { + + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + /*you can use SYS_TEMP or SYS_SYS ON HEAR_BEAT_CONF to save for each workspace*/ + $sflag = $_POST['HB_OPTION']; + $oServerConf->unsetHeartbeatProperty('HB_BEAT_TYPE','HEART_BEAT_CONF'); + if($sflag){ + $oServerConf->setHeartbeatProperty('HB_OPTION',1,'HEART_BEAT_CONF'); + $oServerConf->unsetHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + echo "active"; + }else{ + $oServerConf->setHeartbeatProperty('HB_OPTION',0,'HEART_BEAT_CONF'); + $oServerConf->unsetHeartbeatProperty('HB_NEXT_BEAT_DATE','HEART_BEAT_CONF'); + $oServerConf->setHeartbeatProperty('HB_BEAT_TYPE','endbeat','HEART_BEAT_CONF'); + echo "inactive"; + + +} + //$oServerConf->setHeartbeatProperty('HB_OPTION',$_POST['HB_OPTION'],'HEART_BEAT_CONF'); + + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publishBlank', 'blank' ); + } \ No newline at end of file diff --git a/workflow/engine/methods/setup/replacementLogo.php b/workflow/engine/methods/setup/replacementLogo.php new file mode 100755 index 000000000..daf9de197 --- /dev/null +++ b/workflow/engine/methods/setup/replacementLogo.php @@ -0,0 +1,84 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try {//ini_set('display_errors','1'); + global $RBAC; + switch ($RBAC->userCanAccess('PM_LOGIN')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + + $sfunction =$_GET['function']; + switch($sfunction){ + case 'replacementLogo': + $snameLogo=urldecode($_GET['NAMELOGO']); + G::loadClass('configuration'); + $oConf = new Configurations; + $aConf = Array( + 'WORKSPACE_LOGO_NAME' => SYS_SYS, + 'DEFAULT_LOGO_NAME' => $snameLogo + ); + + $oConf->aConfig = $aConf; + $oConf->saveConfig('USER_LOGO_REPLACEMENT', '', '',$_SESSION['USER_LOGGED']); + + G::SendTemporalMessage('ID_REPLACED_LOGO', 'tmp-info', 'labels'); + //header('location: uplogo.php'); + //G::header('location: uplogo'); + break; + case 'restoreLogo': + $snameLogo=$_GET['NAMELOGO']; + G::loadClass('configuration'); + $oConf = new Configurations; + $aConf = Array( + 'WORKSPACE_LOGO_NAME' => '', + 'DEFAULT_LOGO_NAME' => '' + ); + + $oConf->aConfig = $aConf; + $oConf->saveConfig('USER_LOGO_REPLACEMENT', '', '',$_SESSION['USER_LOGGED']); + + + G::SendTemporalMessage('ID_REPLACED_LOGO', 'tmp-info', 'labels'); + //header('location: uplogo.php'); + //G::header('location: uplogo'); + break; + + } + +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/setup.js b/workflow/engine/methods/setup/setup.js new file mode 100644 index 000000000..2faaf5fda --- /dev/null +++ b/workflow/engine/methods/setup/setup.js @@ -0,0 +1,73 @@ + +function abc( panel, txt ) { +/* commonDialog ( '', 'saved' , 'saved', {}, '' ) ; + setTimeout ( leimnud.closure({instance:myDialog,method:function(panel){ + + myDialog.remove(); + panel.tabLastSelected=false; + panel.tabSelected=1; + panel.makeTab(); + },args:panel}) , 1000 ); +*/ + var img = document.getElementById( 'workPeriodGraph' ); + img.src = 'workPeriodGraph?b=' + Math.random() ; + +// panel.clearContent(); +// panel.addContent ( txt ); + return false; +} + +function showHideFilterForm( divName) +{ + if (document.getElementById( divName ).style.display==='none') + document.getElementById( divName).style.display = ''; + else + document.getElementById( divName).style.display = 'none'; +} + + + + +function newHoliday(ev) { + var coor = leimnud.dom.mouse(ev); + var myPanel=new leimnud.module.panel(); + myPanel.options={ + size:{w:500,h:200}, + position:{x:coor.x-200,y:coor.y}, + title:"New Holiday", + theme:"panel", + control:{ + close:true, + drag:true + }, + fx: { modal:true } + }; + + myPanel.make(); + + var r = new leimnud.module.rpc.xmlhttp({url:"holidayNew.php"}); + r.callback=leimnud.closure({Function:function(rpc){ + myPanel.addContent(rpc.xmlhttp.responseText); + },args:r}) + r.make(); + +} + +function deleteHoliday( uid ) { + url = "setupAjax.php?action=deleteHoliday&uid=" + uid; + var r = new leimnud.module.rpc.xmlhttp({url: url }); + r.callback=leimnud.closure({Function:function(rpc){ + //myPanel.addContent(rpc.xmlhttp.responseText); + myPanel = setupPanel.panels.control; + myPanel.tabLastSelected=false; + myPanel.tabSelected=0; + myPanel.makeTab(); + + },args:r}) + r.make(); + + +// myPanel.clearContent(); +// myPanel.addContent ( uid ); + +} \ No newline at end of file diff --git a/workflow/engine/methods/setup/setup.php b/workflow/engine/methods/setup/setup.php new file mode 100644 index 000000000..d14deb371 --- /dev/null +++ b/workflow/engine/methods/setup/setup.php @@ -0,0 +1,87 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * New Admin User interface + * @author Erik A. O. + * @date Apr 5th, 2010 + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + +$G_MAIN_MENU = "processmaker"; +$G_ID_MENU_SELECTED = "SETUP"; +$G_PUBLISH = new Publisher; +global $G_TMP_MENU; +$oMenu = new Menu(); +$oMenu->load('setup'); +$toolItems = Array(); + +foreach( $oMenu->Options as $i=>$option) { + $toolItems[] = Array( + 'id' => $oMenu->Id[$i], + 'link' => ($oMenu->Options[$i]!='')? $oMenu->Options[$i]: '#', + 'onclick' => ($oMenu->JS[$i]!='')? $oMenu->JS[$i]: '', + 'label' => $oMenu->Labels[$i], + 'icon' => ($oMenu->Icons[$i]!='')? $oMenu->Icons[$i]: 'icon-pmlogo.png', + 'target'=> ($oMenu->JS[$i]!='')? '': 'admToolsContent' + ); +} + +$template = new TemplatePower( PATH_TPL . 'setup' . PATH_SEP . 'tools.html' ); +$template->prepare(); + +$template->assign ('LeftWidth', '230'); +$template->assign ('contentHeight', '520'); + +if( isset($_GET['i18']) ){ + $_SESSION['TOOLS_VIEWTYPE'] = true; + $template->assign ('displayLanguageTool', 'block'); +} else { + $template->assign ('displayLanguageTool', 'none'); +} +if( isset($_GET['newSite']) ){ + $template->assign ('displayNewSiteTool', 'block'); +} else { + $template->assign ('displayNewSiteTool', 'none'); +} + + +foreach($toolItems as $item) { + $template->newBlock( 'tool_options'); + foreach($item as $propertyName=>$propertyValue) + $template->assign ($propertyName, $propertyValue); +} + +$G_PUBLISH->AddContent('template', '', '', '', $template ); +G::RenderPage('publish'); +if(isset($_GET['module'])){ + + print " + + "; +} \ No newline at end of file diff --git a/workflow/engine/methods/setup/setupAjax.php b/workflow/engine/methods/setup/setupAjax.php new file mode 100644 index 000000000..b5f11bcfa --- /dev/null +++ b/workflow/engine/methods/setup/setupAjax.php @@ -0,0 +1,41 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; +//$oSMTPJSON = new Services_JSON(); +//$oSMTPData = $oSMTPJSON->decode(stripslashes($_POST['data'])); +//$sOutput = ''; + G::LoadClass('setup'); + + $oSMTPSetup = new Setup(new DBConnection); + + $action = strtolower ( $_GET['action'] ); + $data = $_GET; + + $arr = get_class_methods( get_class($oSMTPSetup) ); + foreach ($arr as $method) { + if ( $method == $action ) + $oSMTPSetup->{$action} ( $_GET ); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/setupSchemas/app_cache_view.sql b/workflow/engine/methods/setup/setupSchemas/app_cache_view.sql new file mode 100755 index 000000000..e8935b5d8 --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/app_cache_view.sql @@ -0,0 +1,38 @@ +CREATE TABLE `APP_CACHE_VIEW` +( + `APP_UID` VARCHAR(32) default '' NOT NULL, + `DEL_INDEX` INTEGER default 0 NOT NULL, + `APP_NUMBER` INTEGER default 0 NOT NULL, + `APP_STATUS` VARCHAR(32) default '' NOT NULL, + `USR_UID` VARCHAR(32) default '' NOT NULL, + `PREVIOUS_USR_UID` VARCHAR(32) default '' NOT NULL, + `TAS_UID` VARCHAR(32) default '' NOT NULL, + `PRO_UID` VARCHAR(32) default '' NOT NULL, + `DEL_DELEGATE_DATE` VARCHAR(10) default '' NOT NULL, + `DEL_INIT_DATE` DATETIME, + `DEL_TASK_DUE_DATE` DATETIME, + `DEL_FINISH_DATE` DATETIME, + `DEL_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `APP_THREAD_STATUS` VARCHAR(32) default 'OPEN' NOT NULL, + `APP_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_PRO_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_TAS_TITLE` VARCHAR(255) default '' NOT NULL, + `APP_CURRENT_USER` VARCHAR(128) default '' NOT NULL, + `APP_DEL_PREVIOUS_USER` VARCHAR(128) default '' NOT NULL, + `DEL_PRIORITY` VARCHAR(32) default '3' NOT NULL, + `DEL_DURATION` DOUBLE default 0, + `DEL_QUEUE_DURATION` DOUBLE default 0, + `DEL_DELAY_DURATION` DOUBLE default 0, + `DEL_STARTED` TINYINT default 0, + `DEL_FINISHED` TINYINT default 0, + `DEL_DELAYED` TINYINT default 0, + `APP_CREATE_DATE` DATETIME NOT NULL, + `APP_FINISH_DATE` DATETIME NULL, + `APP_UPDATE_DATE` DATETIME NOT NULL, + APP_OVERDUE_PERCENTAGE DOUBLE NOT NULL default 0, + APP_LAST_USER VARCHAR(128) default '' NOT NULL, + PRIMARY KEY (`APP_UID`,`DEL_INDEX`), + KEY `indexAppNumber`(`APP_NUMBER`), + KEY `indexAppUser`(`USR_UID`, `APP_STATUS`) +)Type=MyISAM DEFAULT CHARSET='utf8' COMMENT='Application cache view'; + diff --git a/workflow/engine/methods/setup/setupSchemas/app_cache_view_insert.sql b/workflow/engine/methods/setup/setupSchemas/app_cache_view_insert.sql new file mode 100755 index 000000000..c95b3b1a1 --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/app_cache_view_insert.sql @@ -0,0 +1,50 @@ +TRUNCATE TABLE APP_CACHE_VIEW; + +SET @DEFAULT_LANG = '{lang}'; + +INSERT INTO APP_CACHE_VIEW +SELECT + APPLICATION.APP_UID, + APP_DELEGATION.DEL_INDEX, + APPLICATION.APP_NUMBER, + APPLICATION.APP_STATUS, + APP_DELEGATION.USR_UID, + APP_LAST_USER.USR_UID, + APP_DELEGATION.TAS_UID, + APP_DELEGATION.PRO_UID, + substring(APP_DELEGATION.DEL_DELEGATE_DATE,1,10), + substring(APP_DELEGATION.DEL_INIT_DATE,1,10), + substring(APP_DELEGATION.DEL_TASK_DUE_DATE,1,10), + substring(APP_DELEGATION.DEL_FINISH_DATE,1,10), + APP_DELEGATION.DEL_THREAD_STATUS, + APP_THREAD.APP_THREAD_STATUS, + APP_TITLE.CON_VALUE AS APP_TITLE, + PRO_TITLE.CON_VALUE AS APP_PRO_TITLE, + TAS_TITLE.CON_VALUE AS APP_TAS_TITLE, + CONCAT(USERS.USR_LASTNAME, ' ', USERS.USR_FIRSTNAME) AS APP_CURRENT_USER, + CONCAT(APP_LAST_USER.USR_LASTNAME, ' ', APP_LAST_USER.USR_FIRSTNAME) AS APP_DEL_PREVIOUS_USER, + APP_DELEGATION.DEL_PRIORITY, + APP_DELEGATION.DEL_DURATION, + APP_DELEGATION.DEL_QUEUE_DURATION, + APP_DELEGATION.DEL_DELAY_DURATION, + if( APP_DELEGATION.DEL_INIT_DATE IS NULL , 0 , 1 ), + if( APP_DELEGATION.DEL_FINISH_DATE IS NULL , 0 , 1 ), + APP_DELEGATION.DEL_DELAYED, + APPLICATION.APP_CREATE_DATE, + NULL, + APPLICATION.APP_UPDATE_DATE, + APP_DELEGATION.APP_OVERDUE_PERCENTAGE, + '-' +FROM + APPLICATION + LEFT JOIN APP_DELEGATION ON (APPLICATION.APP_UID=APP_DELEGATION.APP_UID) + LEFT JOIN TASK ON (APP_DELEGATION.TAS_UID=TASK.TAS_UID) + LEFT JOIN USERS ON (APP_DELEGATION.USR_UID=USERS.USR_UID) + LEFT JOIN APP_THREAD ON (APPLICATION.APP_UID=APP_THREAD.APP_UID AND APP_DELEGATION.DEL_INDEX=APP_THREAD.DEL_INDEX) + LEFT JOIN CONTENT APP_TITLE ON (APPLICATION.APP_UID=APP_TITLE.CON_ID AND APP_TITLE.CON_CATEGORY='APP_TITLE' AND APP_TITLE.CON_LANG = @DEFAULT_LANG) + LEFT JOIN CONTENT PRO_TITLE ON (APPLICATION.PRO_UID=PRO_TITLE.CON_ID AND PRO_TITLE.CON_CATEGORY='PRO_TITLE' AND PRO_TITLE.CON_LANG = @DEFAULT_LANG) + LEFT JOIN CONTENT TAS_TITLE ON (APP_DELEGATION.TAS_UID=TAS_TITLE.CON_ID AND TAS_TITLE.CON_CATEGORY='TAS_TITLE' AND TAS_TITLE.CON_LANG = @DEFAULT_LANG) + LEFT JOIN APP_DELEGATION APP_PREV_DEL ON (APPLICATION.APP_UID=APP_PREV_DEL.APP_UID AND APP_PREV_DEL.DEL_INDEX=APP_DELEGATION.DEL_PREVIOUS) + LEFT JOIN USERS APP_LAST_USER ON (APP_PREV_DEL.USR_UID=APP_LAST_USER.USR_UID) +WHERE + TASK.TAS_TYPE<>'SUBPROCESS' diff --git a/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationInsert.sql b/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationInsert.sql new file mode 100755 index 000000000..75967910c --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationInsert.sql @@ -0,0 +1,110 @@ +CREATE TRIGGER APP_DELEGATION_INSERT BEFORE INSERT ON APP_DELEGATION +FOR EACH ROW +BEGIN + DECLARE DEFAULT_LANG VARCHAR(2); + DECLARE APP_NUMBER INT; + DECLARE APP_STATUS VARCHAR(32); + DECLARE APP_CREATE_DATE DATETIME; + DECLARE APP_TITLE VARCHAR(255); + DECLARE APP_PRO_TITLE VARCHAR(255); + DECLARE APP_TAS_TITLE VARCHAR(255); + DECLARE APP_CURRENT_USER VARCHAR(255); + DECLARE PREVIOUS_USR_UID VARCHAR(32); + DECLARE APP_DEL_PREVIOUS_USER VARCHAR(255); + DECLARE APP_THREAD_STATUS VARCHAR(32); + SET @DEFAULT_LANG = '{lang}'; + SELECT APPLICATION.APP_NUMBER into @APP_NUMBER FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT APPLICATION.APP_STATUS into @APP_STATUS FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT APPLICATION.APP_CREATE_DATE into @APP_CREATE_DATE FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT CONTENT.CON_VALUE into @APP_TITLE FROM CONTENT WHERE NEW.APP_UID=CON_ID AND CON_CATEGORY='APP_TITLE' and CON_LANG = '{lang}' LIMIT 1; + IF ( @APP_TITLE IS NULL ) THEN + SET @APP_TITLE = ''; + END IF; + SELECT CONTENT.CON_VALUE into @APP_PRO_TITLE FROM CONTENT WHERE NEW.PRO_UID=CON_ID AND CON_CATEGORY='PRO_TITLE' and CON_LANG = '{lang}' LIMIT 1; + SELECT CONTENT.CON_VALUE into @APP_TAS_TITLE FROM CONTENT WHERE NEW.TAS_UID=CON_ID AND CON_CATEGORY='TAS_TITLE' and CON_LANG = '{lang}' LIMIT 1; + SELECT CONCAT(USERS.USR_LASTNAME, ' ', USERS.USR_FIRSTNAME) INTO @APP_CURRENT_USER FROM USERS WHERE USR_UID = NEW.USR_UID LIMIT 1; + IF ( @APP_CURRENT_USER IS NULL ) THEN + SET @APP_CURRENT_USER = ''; + END IF; + IF ( NEW.DEL_PREVIOUS > 0 ) THEN + SELECT USR_UID INTO @PREVIOUS_USR_UID FROM APP_DELEGATION WHERE APP_UID = NEW.APP_UID AND DEL_INDEX = NEW.DEL_PREVIOUS LIMIT 1; + SELECT CONCAT(USERS.USR_LASTNAME, ' ', USERS.USR_FIRSTNAME) INTO @APP_DEL_PREVIOUS_USER FROM USERS WHERE USR_UID = @PREVIOUS_USR_UID LIMIT 1; + IF ( @APP_DEL_PREVIOUS_USER IS NULL ) THEN + SET @APP_DEL_PREVIOUS_USER = ''; + END IF; + ELSE + SET @APP_DEL_PREVIOUS_USER = ''; + SET @PREVIOUS_USR_UID = ''; + END IF; + SELECT APP_THREAD_STATUS INTO @APP_THREAD_STATUS FROM APP_THREAD WHERE APP_UID = NEW.APP_UID AND DEL_INDEX = NEW.DEL_PREVIOUS LIMIT 1; + IF ( @APP_THREAD_STATUS IS NULL ) THEN + SET @APP_THREAD_STATUS = 'OPEN'; + END IF; + + INSERT INTO `APP_CACHE_VIEW` ( + APP_UID, + DEL_INDEX, + APP_NUMBER, + APP_STATUS, + USR_UID, + PREVIOUS_USR_UID, + TAS_UID, + PRO_UID, + DEL_DELEGATE_DATE, + DEL_INIT_DATE, + DEL_TASK_DUE_DATE, + DEL_FINISH_DATE, + DEL_THREAD_STATUS, + APP_THREAD_STATUS, + APP_TITLE, + APP_PRO_TITLE, + APP_TAS_TITLE, + APP_CURRENT_USER, + APP_DEL_PREVIOUS_USER, + DEL_PRIORITY, + DEL_DURATION, + DEL_QUEUE_DURATION, + DEL_DELAY_DURATION, + DEL_STARTED, + DEL_FINISHED, + DEL_DELAYED, + APP_CREATE_DATE, + APP_FINISH_DATE, + APP_UPDATE_DATE, + APP_OVERDUE_PERCENTAGE + +) +VALUES ( + NEW.APP_UID, + NEW.DEL_INDEX, + @APP_NUMBER, + @APP_STATUS, + NEW.USR_UID, + @PREVIOUS_USR_UID, + NEW.TAS_UID, + NEW.PRO_UID, + substring(NEW.DEL_DELEGATE_DATE,1,10), + substring(NEW.DEL_INIT_DATE, 1,10), + substring(NEW.DEL_TASK_DUE_DATE,1,10), + substring(NEW.DEL_FINISH_DATE, 1,10), + NEW.DEL_THREAD_STATUS, + @APP_THREAD_STATUS, + @APP_TITLE, + @APP_PRO_TITLE, + @APP_TAS_TITLE, + @APP_CURRENT_USER, + @APP_DEL_PREVIOUS_USER, + NEW.DEL_PRIORITY, + NEW.DEL_DURATION, + NEW.DEL_QUEUE_DURATION, + NEW.DEL_DELAY_DURATION, + NEW.DEL_STARTED, + NEW.DEL_FINISHED, + NEW.DEL_DELAYED, + @APP_CREATE_DATE, + NULL, + NOW(), + NEW.APP_OVERDUE_PERCENTAGE +); +END + diff --git a/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationUpdate.sql b/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationUpdate.sql new file mode 100755 index 000000000..1c49aa880 --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/triggerAppDelegationUpdate.sql @@ -0,0 +1,75 @@ +CREATE TRIGGER APP_DELEGATION_UPDATE BEFORE UPDATE ON APP_DELEGATION +FOR EACH ROW +BEGIN + DECLARE DEFAULT_LANG VARCHAR(2); + DECLARE APP_NUMBER INT; + DECLARE APP_STATUS VARCHAR(32); + DECLARE APP_CREATE_DATE DATETIME; + DECLARE APP_TITLE VARCHAR(255); + DECLARE APP_PRO_TITLE VARCHAR(255); + DECLARE APP_TAS_TITLE VARCHAR(255); + DECLARE APP_CURRENT_USER VARCHAR(255); + DECLARE PREVIOUS_USR_UID VARCHAR(32); + DECLARE APP_DEL_PREVIOUS_USER VARCHAR(255); + DECLARE APP_THREAD_STATUS VARCHAR(32); + SET @DEFAULT_LANG = '{lang}'; + SELECT APPLICATION.APP_NUMBER into @APP_NUMBER FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT APPLICATION.APP_STATUS into @APP_STATUS FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT APPLICATION.APP_CREATE_DATE into @APP_CREATE_DATE FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + SELECT CONTENT.CON_VALUE into @APP_TITLE FROM CONTENT WHERE NEW.APP_UID=CON_ID AND CON_CATEGORY='APP_TITLE' and CON_LANG = '{lang}' LIMIT 1; + IF ( @APP_TITLE IS NULL ) THEN + SET @APP_TITLE = ''; + END IF; + SELECT CONTENT.CON_VALUE into @APP_PRO_TITLE FROM CONTENT WHERE NEW.PRO_UID=CON_ID AND CON_CATEGORY='PRO_TITLE' and CON_LANG = '{lang}' LIMIT 1; + SELECT CONTENT.CON_VALUE into @APP_TAS_TITLE FROM CONTENT WHERE NEW.TAS_UID=CON_ID AND CON_CATEGORY='TAS_TITLE' and CON_LANG = '{lang}' LIMIT 1; + SELECT CONCAT(USERS.USR_LASTNAME, ' ', USERS.USR_FIRSTNAME) INTO @APP_CURRENT_USER FROM USERS WHERE USR_UID = NEW.USR_UID LIMIT 1; + IF ( @APP_CURRENT_USER IS NULL ) THEN + SET @APP_CURRENT_USER = ''; + END IF; + IF ( NEW.DEL_PREVIOUS > 0 ) THEN + SELECT USR_UID INTO @PREVIOUS_USR_UID FROM APP_DELEGATION WHERE APP_UID = NEW.APP_UID AND DEL_INDEX = NEW.DEL_PREVIOUS LIMIT 1; + SELECT CONCAT(USERS.USR_LASTNAME, ' ', USERS.USR_FIRSTNAME) INTO @APP_DEL_PREVIOUS_USER FROM USERS WHERE USR_UID = @PREVIOUS_USR_UID LIMIT 1; + IF ( @APP_DEL_PREVIOUS_USER IS NULL ) THEN + SET @APP_DEL_PREVIOUS_USER = ''; + END IF; + ELSE + SET @APP_DEL_PREVIOUS_USER = ''; + SET @PREVIOUS_USR_UID = ''; + END IF; + SELECT APP_THREAD_STATUS INTO @APP_THREAD_STATUS FROM APP_THREAD WHERE APP_UID = NEW.APP_UID AND DEL_INDEX = NEW.DEL_PREVIOUS LIMIT 1; + IF ( @APP_THREAD_STATUS IS NULL ) THEN + SET @APP_THREAD_STATUS = 'OPEN'; + END IF; + UPDATE `APP_CACHE_VIEW` + SET + APP_NUMBER = @APP_NUMBER, + APP_STATUS = @APP_STATUS, + USR_UID = NEW.USR_UID, + PREVIOUS_USR_UID = @PREVIOUS_USR_UID, + TAS_UID = NEW.TAS_UID, + PRO_UID = NEW.PRO_UID, + DEL_DELEGATE_DATE = substring(NEW.DEL_DELEGATE_DATE,1,10), + DEL_INIT_DATE = substring(NEW.DEL_INIT_DATE,1,10), + DEL_TASK_DUE_DATE = substring(NEW.DEL_TASK_DUE_DATE,1,10), + DEL_FINISH_DATE = substring(NEW.DEL_FINISH_DATE,1,10), + DEL_THREAD_STATUS = NEW.DEL_THREAD_STATUS, + APP_THREAD_STATUS = @APP_THREAD_STATUS, + APP_TITLE = @APP_TITLE, + APP_PRO_TITLE = @APP_PRO_TITLE, + APP_TAS_TITLE = @APP_TAS_TITLE, + APP_CURRENT_USER = @APP_CURRENT_USER, + APP_DEL_PREVIOUS_USER = @APP_DEL_PREVIOUS_USER, + DEL_PRIORITY = NEW.DEL_PRIORITY, + DEL_DURATION = NEW.DEL_DURATION, + DEL_QUEUE_DURATION = NEW.DEL_QUEUE_DURATION, + DEL_DELAY_DURATION = NEW.DEL_DELAY_DURATION, + DEL_STARTED = NEW.DEL_STARTED, + DEL_FINISHED = NEW.DEL_FINISHED, + DEL_DELAYED = NEW.DEL_DELAYED, + APP_FINISH_DATE = NULL, + APP_UPDATE_DATE = NOW(), + APP_OVERDUE_PERCENTAGE = NEW.APP_OVERDUE_PERCENTAGE +WHERE + APP_UID = NEW.APP_UID + AND DEL_INDEX = NEW.DEL_INDEX; +END \ No newline at end of file diff --git a/workflow/engine/methods/setup/setupSchemas/triggerApplicationDelete.sql b/workflow/engine/methods/setup/setupSchemas/triggerApplicationDelete.sql new file mode 100644 index 000000000..aa834eae0 --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/triggerApplicationDelete.sql @@ -0,0 +1,4 @@ +CREATE TRIGGER APPLICATION_DELETE BEFORE DELETE ON APPLICATION + FOR EACH ROW BEGIN + DELETE FROM APP_CACHE_VIEW WHERE APP_UID = OLD.APP_UID; +END \ No newline at end of file diff --git a/workflow/engine/methods/setup/setupSchemas/triggerApplicationUpdate.sql b/workflow/engine/methods/setup/setupSchemas/triggerApplicationUpdate.sql new file mode 100755 index 000000000..3f17cfde5 --- /dev/null +++ b/workflow/engine/methods/setup/setupSchemas/triggerApplicationUpdate.sql @@ -0,0 +1,16 @@ +CREATE TRIGGER APPLICATION_UPDATE BEFORE UPDATE ON APPLICATION + +FOR EACH ROW + +BEGIN + DECLARE APP_STATUS VARCHAR(32); + SELECT APPLICATION.APP_STATUS into @APP_STATUS FROM APPLICATION WHERE APP_UID = NEW.APP_UID LIMIT 1; + + IF(OLD.APP_STATUS<>NEW.APP_STATUS) THEN + + SET @APP_STATUS = NEW.APP_STATUS; + UPDATE APP_CACHE_VIEW SET APP_STATUS = @APP_STATUS WHERE APP_UID = NEW.APP_UID; + + END IF; + +END diff --git a/workflow/engine/methods/setup/showLogoFile.php b/workflow/engine/methods/setup/showLogoFile.php new file mode 100644 index 000000000..3cf5376ee --- /dev/null +++ b/workflow/engine/methods/setup/showLogoFile.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if (($RBAC_Response = $RBAC->userCanAccess("PM_CASES"))!=1) return $RBAC_Response; + + $ainfoSite = explode("/",$_SERVER["REQUEST_URI"]); + $dir=PATH_DATA."sites".PATH_SEP.str_replace("sys","",$ainfoSite[1]).PATH_SEP."files/logos"; + $imagen = $dir .PATH_SEP.G::decrypt($_GET['id'],'imagen'); + if (is_file($imagen)) + { + $ext = substr($imagen, strrpos($imagen, '.') + 1); // extension + + header('content-type: image/'.$ext); + readfile($imagen); + exit; + } + +die; + +?> + diff --git a/workflow/engine/methods/setup/skinsExport.php b/workflow/engine/methods/setup/skinsExport.php new file mode 100755 index 000000000..7c7f183a1 --- /dev/null +++ b/workflow/engine/methods/setup/skinsExport.php @@ -0,0 +1,191 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + function copyFile ( $input, $output ) { + $content = file_get_contents ( $input ); + $filename = $output . PATH_SEP . basename ( $input ); + return file_put_contents ( $filename, $content ); + } + + function savePluginFile ( $tplName, $fileName, $fields ) { + $pluginTpl = PATH_GULLIVER_HOME . 'bin' . PATH_SEP . 'tasks' .PATH_SEP . 'templates' . PATH_SEP . $tplName . '.tpl'; + $template = new TemplatePower( $pluginTpl ); + $template->prepare(); + + if ( is_array ($fields) ) { + foreach ( $fields as $block => $data ) { + $template->gotoBlock( "_ROOT" ); + if ( is_array( $data) ) + foreach ( $data as $rowId => $row ) { + $template->newBlock( $block ); + foreach ( $row as $key => $val ) + $template->assign( $key, $val ); + } + else + $template->assign( $block, $data ); + } + } + + $content = $template->getOutputContent(); + $iSize = file_put_contents ( $fileName, $content ); + return $iSize; + } + + function addTarFolder ( $tar, $pathBase,$pluginHome ) { + $aux = explode( PATH_SEP, $pathBase); + if ( $aux[count($aux) -2 ] == '.svn' ) return; + + if ($handle = opendir( $pathBase )) { + while ( false !== ($file = readdir($handle))) { + if ( is_file ( $pathBase . $file ) ) { + //print "file $file \n"; + $tar->addModify( $pathBase . $file,'', $pluginHome); + } + if ( is_dir ( $pathBase . $file ) && $file != '..' && $file != '.' ) { + //print "dir $pathBase$file \n"; + addTarFolder ( $tar, $pathBase . $file . PATH_SEP ,$pluginHome); + } + } + closedir($handle); + } + } + + + function packPlugin ( $pluginName, $version ) { + + $pathBase = PATH_DATA . 'skins' . PATH_SEP . $pluginName . PATH_SEP; + $pathHome = PATH_DATA . 'skins' . PATH_SEP . $pluginName ; + $fileTar = PATH_DATA . 'skins' . PATH_SEP . $pluginName . '-' . $version . '.tar'; + + G::LoadSystem ('templatePower'); +/* + $pluginDirectory = PATH_PLUGINS . $pluginName; + $pluginOutDirectory = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName; + $pluginHome = PATH_OUTTRUNK . 'plugins' . PATH_SEP . $pluginName; + + //verify if plugin exists, + $pluginClassFilename = PATH_PLUGINS . $pluginName . PATH_SEP . 'class.' . $pluginName . '.php'; + if ( !is_file ( $pluginClassFilename ) ) { + printf("The plugin %s does not exist in this file %s \n", pakeColor::colorize( $pluginName, 'ERROR'), pakeColor::colorize( $pluginClassFilename, 'INFO') ); + die ; + } + */ + G::LoadThirdParty( 'pear/Archive','Tar'); + $tar = new Archive_Tar ( $fileTar); + $tar->_compress=false; + + //$tar->createModify( $pathHome . PATH_SEP . $pluginName . '.php' ,'', $pathHome); + addTarFolder ( $tar, $pathBase, $pathHome ); + $aFiles = $tar->listContent(); + return $fileTar; + } + +global $RBAC; +switch ($RBAC->userCanAccess('PM_SETUP')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + + //get the current process + if (file_exists(PATH_METHODS . 'login/version-pmos.php')) + { + include(PATH_METHODS . 'login/version-pmos.php'); + } + else { + define('PM_VERSION', '1.2.2740'); + } + + $id = $_GET['id']; + + $fileObj = PATH_SKINS . $id . '.cnf'; + + if ( !file_exists($fileObj) ) { + $oConf = new stdClass(); + $oConf->name = $id; + $oConf->description = "description of skin $id "; + $oConf->version = 1; + file_put_contents ( $fileObj, serialize ( $oConf) ); + } + + $oConf = unserialize ( file_get_contents ( $fileObj )); + $oConf->version += 1; + file_put_contents ( $fileObj, serialize ( $oConf) ); + + $pathHome = PATH_DATA . 'skins' . PATH_SEP . $id . PATH_SEP; + $pathBase = PATH_DATA . 'skins' . PATH_SEP . $id . PATH_SEP . $id . PATH_SEP; + $pathPublic = $pathBase . 'data' . PATH_SEP . 'public_html' . PATH_SEP ; + $pathImages = PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP . 'images' . PATH_SEP; + + G::mk_dir ( $pathBase ); + G::mk_dir ( $pathBase . 'data' ); + G::mk_dir ( $pathPublic ); + G::mk_dir ( $pathPublic . 'images' ); + +// file_put_contents ( PATH_DATA . 'skins' . PATH_SEP . $id , "hello world" ); + $fields['className'] = $id; + $fields['version'] = $oConf->version; + $fields['description'] = $oConf->description; + $fields['PMversion'] = PM_VERSION; + savePluginFile ( 'skinPluginMainClass' , $pathHome . $id . '.php', $fields ); + + savePluginFile ( 'skinPluginClass' , $pathBase . 'class.' . $id . '.php', $fields ); + + copyFile ( PATH_SKINS . $id . '.php' , $pathBase . 'data' ); + copyFile ( PATH_SKINS . $id . '.html' , $pathBase . 'data' ); + copyFile ( PATH_SKINS . $id . '.cnf' , $pathBase . 'data' ); + + copyFile ( PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP . 'iepngfix.htc' , $pathPublic ); + copyFile ( PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP . 'style.css' , $pathPublic ); + + + $aFiles = array (); + if ($handle = opendir( $pathImages )) { + while ( false !== ($file = readdir($handle))) { + if ( substr($file,0,1) != '.' ) { + if ( isset($aFiles[ $file ]) ) $aFiles[$file] = 0; + copyFile ( $pathImages. $file , $pathPublic . 'images' . PATH_SEP ); + + } + } + closedir($handle); + } + + $fileTar = packPlugin ( $id, $oConf->version ); + + + $bDownload = true; + G::streamFile ( $fileTar, $bDownload, basename($fileTar) ); + + @G::rm_dir ($pathHome); + @unlink ($fileTar); diff --git a/workflow/engine/methods/setup/skinsList.php b/workflow/engine/methods/setup/skinsList.php new file mode 100755 index 000000000..e70053252 --- /dev/null +++ b/workflow/engine/methods/setup/skinsList.php @@ -0,0 +1,121 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_SETUP'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} + // lets display the items + $items[] = array ( 'id' => 'char', 'title' => 'char', 'type' => 'char', 'creator' => 'char' , + 'modifiedBy' => 'char', 'filename' => 'char', 'size' => 'char', 'mime' => 'char'); + + //***************** Skins ************************** + $aFiles = array (); + if ($handle = opendir( PATH_SKINS )) { + while ( false !== ($file = readdir($handle))) { + $filename = substr ( $file,0, strrpos($file, '.')); + + // list of no complete skins + $aFilterSkinsList = Array('blank', 'green', 'raw', 'tracker', 'iphone', 'green-submenu', 'extJsInitLoad', 'extJs' ); + + if ( !is_dir(PATH_SKINS. $file) ) { + if ( !in_array($filename, $aFilterSkinsList) /*&& /*/ && !strpos($file, '.tar', 1) ) { + if ( !isset($aFiles[ $filename ]) ) $aFiles[$filename] = 0; + if ( strpos($file, '.php', 1) ) $aFiles[ $filename ] += 1; + if ( strpos($file, '.html',1) ) $aFiles[ $filename ] += 2; + } + } + } + + closedir($handle); + + + //now walk in the array to get the .cnf file and display properties + foreach ( $aFiles as $key => $val ) { + $description = ''; + $version = ''; + if ( file_exists ( PATH_SKINS . $key . '.cnf' ) ) { + $serial = file_get_contents ( PATH_SKINS . $key . '.cnf' ); + $previousErrorRep = ini_get("error_reporting"); + error_reporting( E_ERROR ) ; + $prop = unserialize ( $serial ); + error_reporting( $previousErrorRep ); + if ( !is_object( $prop ) ) { + @unlink ( PATH_SKINS . $key . '.cnf'); + } + if ( isset ( $prop) && isset($prop->description) ) $description = $prop->description; + if ( isset ( $prop) && isset($prop->version ) ) $version = $prop->version; + } + + $linkPackValue = G::LoadTranslation('ID_EXPORT') ; + $link = 'skinsExport?id=' . $key ; + $items[] = array ( + 'id' => count($items), + 'name' => $key, + 'filename' => $key, + 'description' => $description, + 'version' => $version, + 'url' => $link, + 'linkPackValue' => $linkPackValue + ); + } + $folders['items'] = $items; + } + + $_DBArray['plugins'] = $items; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass( 'ArrayPeer'); + $c = new Criteria ('dbarray'); + $c->setDBArrayTable('plugins'); + //$c->addAscendingOrderByColumn ('id'); + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'SKINS'; + + $G_PUBLISH = new Publisher; + + $G_PUBLISH->AddContent( 'propeltable', 'paged-table', 'setup/skinsList', $c ); + G::RenderPage('publishBlank', 'blank'); + diff --git a/workflow/engine/methods/setup/skinsNew.php b/workflow/engine/methods/setup/skinsNew.php new file mode 100644 index 000000000..7875f9dd3 --- /dev/null +++ b/workflow/engine/methods/setup/skinsNew.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$access = $RBAC->userCanAccess('PM_SETUP'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + + $dbc = new DBConnection; + $G_PUBLISH = new Publisher; + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_SUB_MENU = 'setup'; + $G_ID_SUB_MENU_SELECTED = 'SKINS'; + + $G_PUBLISH->AddContent( 'xmlform', 'xmlform', "setup/skinsNew", '', null, "skinsSave"); + G::RenderPage( 'publishBlank', 'blank' ); + \ No newline at end of file diff --git a/workflow/engine/methods/setup/skinsSave.php b/workflow/engine/methods/setup/skinsSave.php new file mode 100644 index 000000000..e5e9f7341 --- /dev/null +++ b/workflow/engine/methods/setup/skinsSave.php @@ -0,0 +1,102 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + + function xcopy ( $pathSource, $pathTarget ) { + G::mk_dir ($pathTarget); + if ($handle = opendir( $pathSource )) { + while ( false !== ($file = readdir($handle))) { + if ( substr($file,0,1) != '.' && !is_dir ($file) ) { + $content = file_get_contents ( $pathSource . $file ); + $filename = $pathTarget . $file ; + file_put_contents ( $filename, $content ); + } + } + closedir($handle); + } + } + + +global $RBAC; +switch ($RBAC->userCanAccess('PM_SETUP')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} + + //get the current process + if (file_exists(PATH_METHODS . 'login/version-pmos.php')) + { + include('version-pmos.php'); + } + else { + define('PM_VERSION', '1.8.320'); + } + + $id = strip_tags ( str_replace ( ' ', '_', trim ($_POST['form']['NAME']) ) ); + $desc = $_POST['form']['DESCRIPTION']; + + $fileObj = PATH_SKINS . $id . '.cnf'; + + if ( !file_exists($fileObj) ) { + $oConf = new stdClass(); + $oConf->name = $id; + $oConf->description = $desc; + $oConf->version = 1; + file_put_contents ( $fileObj, serialize ( $oConf) ); + } + + $oConf = unserialize ( file_get_contents ( $fileObj )); + + $contentPHP = file_get_contents ( PATH_SKINS . 'green.php' ); + $contentPHP = str_replace ( 'green.html', $id.'.html', $contentPHP ); + file_put_contents ( PATH_SKINS . $id . '.php', $contentPHP ); + + $contentHTML = file_get_contents ( PATH_SKINS . 'green.html' ); + $contentHTML = str_replace ( 'green', $id , $contentHTML ); + file_put_contents ( PATH_SKINS . $id . '.html', $contentHTML ); + + $pathImages = PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP . 'images' . PATH_SEP; + G::mk_dir ( $pathImages ); + + xcopy ( + PATH_HTML . 'skins' . PATH_SEP . 'green' . PATH_SEP , + PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP + ); + + xcopy ( + PATH_HTML . 'skins' . PATH_SEP . 'green' . PATH_SEP . 'images'. PATH_SEP, + PATH_HTML . 'skins' . PATH_SEP . $id . PATH_SEP . 'images'. PATH_SEP + ); + + G::Header ( 'Location: ../../' . $id . '/setup/skinsList' ); \ No newline at end of file diff --git a/workflow/engine/methods/setup/upgrade.php b/workflow/engine/methods/setup/upgrade.php new file mode 100644 index 000000000..fa9d50922 --- /dev/null +++ b/workflow/engine/methods/setup/upgrade.php @@ -0,0 +1,81 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +$access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +//calculating the max upload file size; + $POST_MAX_SIZE = ini_get('post_max_size'); + $mul = substr($POST_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $postMaxSize = (int)$POST_MAX_SIZE * $mul; + + $UPLOAD_MAX_SIZE = ini_get('upload_max_filesize'); + $mul = substr($UPLOAD_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $uploadMaxSize = (int)$UPLOAD_MAX_SIZE * $mul; + + if ( $postMaxSize < $uploadMaxSize ) $uploadMaxSize = $postMaxSize; + + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'setup'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_ID_SUB_MENU_SELECTED = 'UPGRADE'; + + if ( !defined ( 'PM_VERSION' ) ) { + if (file_exists(PATH_METHODS . 'login/version-pmos.php')) { + include(PATH_METHODS . 'login/version-pmos.php'); + } + else { + define('PM_VERSION', 'Development Version'); + } + } + + $Fields['PM_VERSION'] = PM_VERSION; + $Fields['MAX_FILE_SIZE'] = $uploadMaxSize . " (" . $UPLOAD_MAX_SIZE . ") "; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/upgrade', '', $Fields, 'upgrade_System'); + G::RenderPage('publishBlank', 'blank'); + \ No newline at end of file diff --git a/workflow/engine/methods/setup/upgrade_RBAC.php b/workflow/engine/methods/setup/upgrade_RBAC.php new file mode 100644 index 000000000..647b39652 --- /dev/null +++ b/workflow/engine/methods/setup/upgrade_RBAC.php @@ -0,0 +1,42 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$aRequiredPermissions = array('PM_LOGIN', + 'PM_SETUP', + 'PM_USERS', + 'PM_FACTORY', + 'PM_CASES', + 'PM_ALLCASES', + 'PM_REASSIGNCASE', + 'PM_REPORTS', + 'PM_SUPERVISOR', + 'PM_SETUP_ADVANCE', + 'PM_DASHBOARD', + 'PM_WEBDAV', + 'PM_DELETECASE', + 'PM_EDITPERSONALINFO', + 'PM_FOLDERS_VIEW', + 'PM_FOLDERS_ADD_FOLDER', + 'PM_FOLDERS_ADD_FILE' + ); \ No newline at end of file diff --git a/workflow/engine/methods/setup/upgrade_System.php b/workflow/engine/methods/setup/upgrade_System.php new file mode 100644 index 000000000..96db604be --- /dev/null +++ b/workflow/engine/methods/setup/upgrade_System.php @@ -0,0 +1,110 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * New System Upgrade controller + * + * @author Erik A. O. + * @date May 12th, 2010 + */ +global $RBAC; +switch ($RBAC->userCanAccess('PM_SETUP_ADVANCE')) +{ + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; +} +set_time_limit(0); + +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'setup'; +$G_ID_MENU_SELECTED = 'SETUP'; +$G_ID_SUB_MENU_SELECTED = 'UPGRADE'; + +require_once "classes/class.system.php"; +$oSystem = new System(); + +try { + if( ! $oSystem->verifyFileForUpgrade() ){ + throw ( new Exception ("There was an error uploading the file, probably the file size if greater than upload_max_filesize parameter in php.ini, please check this parameter and try again." ) ); + } + $oSystem->cleanupUpgradeDirectory(); + $oSystem->getUpgradedFilesList(); + + $ver = $oSystem->upgrade(); + $G_PUBLISH = new Publisher; + $aMessage['THEMESSAGE1'] = G::LoadTranslation('ID_UPGRADE_READY') ." ". $ver[0] ." ". G::LoadTranslation('ID_TO') ." ". $ver[1] .""; + $aMessage['THEMESSAGE2'] = file_get_contents($oSystem->sUpgradeFileList); + $aMessage['THEMESSAGE3'] = ''; + + if ( !is_Array($oSystem->aErrors) || count($oSystem->aErrors) == 0 ) + $aMessage['THEMESSAGE4'] = G::LoadTranslation('ID_NONE'); + else + $aMessage['THEMESSAGE4'] = implode( "\n", $oSystem->aErrors) ; + + $oHeadPublisher =& headPublisher::getSingleton(); + if( file_exists(PATH_CORE . 'js' . PATH_SEP . 'setup' . PATH_SEP . 'upgrade_System.js') ){ + $oHeadPublisher->addScriptFile('/jscore/setup/upgrade_System.js'); + } else { + $oHeadPublisher->addScriptCode("function upgradeSystem(wsCount) { + document.getElementById('form[THETITLE3]').innerHTML = wsCount + ' workspaces to update.'; + document.getElementById('form[SUBTITLE4]').innerHTML = '   Please wait...'; + updateWorkspace(wsCount); + }; + function updateWorkspace(id) { + if(id < 0) return false; + var oRPC = new leimnud.module.rpc.xmlhttp({ + async : true, + method: 'POST', + url: '../setup/upgrade_SystemAjax', + args : 'id=' + id + }); + oRPC.callback = function(rpc) { + document.getElementById('form[SUBTITLE4]').innerHTML = rpc.xmlhttp.responseText; + updateWorkspace(id-1); + }.extend(this); + oRPC.make(); + };"); + } + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showInfoUpdate', '', $aMessage ); + + G::RenderPage( 'publishBlank', 'blank' ); + G::evalJScript('upgradeSystem('.count($oSystem->aWorkspaces).')'); + exit(0); +} +catch (Exception $e) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publishBlank', 'blank' ); + exit(0); +} diff --git a/workflow/engine/methods/setup/upgrade_SystemAjax.php b/workflow/engine/methods/setup/upgrade_SystemAjax.php new file mode 100644 index 000000000..d97090a61 --- /dev/null +++ b/workflow/engine/methods/setup/upgrade_SystemAjax.php @@ -0,0 +1,389 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $DB_ADAPTER; + global $DB_HOST; + global $DB_USER; + global $DB_PASS; + global $DB_NAME; + set_time_limit (0); + + $id = ''; + if ( isset($_POST['id'] ) ) $id = $_POST['id']; + + G::LoadClass('languages'); + G::LoadSystem('database_mysql'); + + $aUpgradeData = unserialize( file_get_contents (PATH_DATA . 'log' . PATH_SEP . "upgrade.data.bin" )); + $aWorkspaces = $aUpgradeData['workspaces']; + + if ( is_array ( $aWorkspaces ) && count($aWorkspaces) > 0 ) { + $workspace = array_shift ( $aUpgradeData['workspaces']); + + eval ( getDatabaseCredentials(PATH_DB . $workspace . PATH_SEP . 'db.php')) ; + $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); + $oDataBase->iFetchType = MYSQL_NUM; + + //processing .po file + if ( $aUpgradeData['sPoFile'] != '' ) { + $oLanguages = new languages(); + $oLanguages->importLanguage($aUpgradeData['sPoFile'], $aUpgradeData['bForceXmlPoFile'] ); + $aUpgradeData['bForceXmlPoFile'] = false; + } + + if ($aUpgradeData['sSchemaFile'] != '') + processMasterSchemaFile( $aUpgradeData['sSchemaFile'] ); + + + //draw a gauge control indicating the progress in workspaces + $gauge = intval( (( $aUpgradeData['wsQuantity'] - count($aWorkspaces) + 1 ) / $aUpgradeData['wsQuantity'] ) * 301 ); + print "
    "; + print "
    "; + print "
    "; + print "
    Upgrading the workspace $workspace| $id Remaining
    "; + file_put_contents (PATH_DATA . 'log' . PATH_SEP . "upgrade.data.bin", serialize($aUpgradeData) ); + } + else { + print "
        "; + print "
    "; + print "
    "; + print "
    Finished! All workspaces were upgraded successfully.
    "; + } + +die; + +function getDatabaseCredentials ( $dbFile ) { + $sContent = file_get_contents( $dbFile ); + $sContent = str_replace('', '', $sContent); + $sContent = str_replace('define', '', $sContent); + $sContent = str_replace("('", '$', $sContent); + $sContent = str_replace("',", '=', $sContent); + $sContent = str_replace(");", ';', $sContent); + return $sContent; +} + +function processMasterSchemaFile ( $sSchemaFile ) { + global $DB_ADAPTER; + global $DB_HOST; + global $DB_USER; + global $DB_PASS; + global $DB_NAME; + global $aUpgradeData; + + //convert newSchema to array + if ( isset($aUpgradeData['aNewSchema']) ) { + $aNewSchema = $aUpgradeData['aNewSchema']; + } + else { + $aNewSchema = schemaToArray($sSchemaFile); + $aUpgradeData['aNewSchema'] = $aNewSchema; + } + $aOldSchema = processSchemaFile(); + if ( is_null($aOldSchema) ) { + return; + } + $aChanges = obtainChanges($aOldSchema, $aNewSchema); + + $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); + if ( !$oDataBase->isConnected() ) { + return; + } + $oDataBase->iFetchType = MYSQL_NUM; + + $oDataBase->logQuery ( count ($aChanges ) ); + + foreach ($aChanges['tablesToAdd'] as $sTable => $aColumns) { + $oDataBase->executeQuery($oDataBase->generateCreateTableSQL($sTable, $aColumns)); + if (isset($aChanges['tablesToAdd'][$sTable]['INDEXES'])) { + foreach ($aChanges['tablesToAdd'][$sTable]['INDEXES'] as $indexName => $aIndex) { + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $indexName, $aIndex ) ); + } + } + } + + foreach ($aChanges['tablesToAlter'] as $sTable => $aActions) { + foreach ($aActions as $sAction => $aAction) { + foreach ($aAction as $sColumn => $vData) { + switch ($sAction) { + case 'DROP': + $oDataBase->executeQuery($oDataBase->generateDropColumnSQL($sTable, $vData)); + break; + case 'ADD': + $oDataBase->executeQuery($oDataBase->generateAddColumnSQL($sTable, $sColumn, $vData)); + break; + case 'CHANGE': + $oDataBase->executeQuery($oDataBase->generateChangeColumnSQL($sTable, $sColumn, $vData)); + break; + } + } + } + } + + foreach ($aChanges['tablesWithNewIndex'] as $sTable => $aIndexes) { + foreach ($aIndexes as $sIndexName => $aIndexFields ) { + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); + } + } + + foreach ($aChanges['tablesToAlterIndex'] as $sTable => $aIndexes) { + foreach ($aIndexes as $sIndexName => $aIndexFields ) { + $oDataBase->executeQuery($oDataBase->generateDropKeySQL($sTable, $sIndexName )); + $oDataBase->executeQuery($oDataBase->generateAddKeysSQL($sTable, $sIndexName, $aIndexFields )); + } + } + $oDataBase->close(); +} + + +function processSchemaFile( ) { + global $DB_ADAPTER; + global $DB_HOST; + global $DB_USER; + global $DB_PASS; + global $DB_NAME; + + try { + G::LoadSystem( 'database_' . strtolower($DB_ADAPTER)); + + $aOldSchema = array(); + $oDataBase = new database($DB_ADAPTER, $DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); + + if ( !$oDataBase->isConnected() ) { + $oDataBase->logQuery ('Not exists an available connection!'); + return NULL; + } + + $oDataBase->iFetchType = MYSQL_NUM; + $oDataset1 = $oDataBase->executeQuery($oDataBase->generateShowTablesSQL()); + + } catch ( Exception $e ) { + $oDataBase->logQuery ( $e->getmessage() ); + return NULL; + } + + //going thru all tables in current WF_ database + while ($aRow1 = $oDataBase->getRegistry( $oDataset1) ) { + $aPrimaryKeys = array(); + $sTable = strtoupper($aRow1[0]); + + //get description of each table, ( column and primary keys ) + //$oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL($aRow1[0]) ); + $oDataset2 = $oDataBase->executeQuery( $oDataBase->generateDescTableSQL($sTable ) ); + $aOldSchema[ $sTable ] = array(); + $oDataBase->iFetchType = MYSQL_ASSOC; + while ($aRow2 = $oDataBase->getRegistry($oDataset2)) { + $aOldSchema[$sTable][$aRow2['Field']]['Field'] = $aRow2['Field']; + $aOldSchema[$sTable][$aRow2['Field']]['Type'] = $aRow2['Type']; + $aOldSchema[$sTable][$aRow2['Field']]['Null'] = $aRow2['Null']; + $aOldSchema[$sTable][$aRow2['Field']]['Default'] = $aRow2['Default']; + } + + //get indexes of each table SHOW INDEX FROM `ADDITIONAL_TABLES`; -- WHERE Key_name <> 'PRIMARY' + $oDataset2 = $oDataBase->executeQuery($oDataBase->generateTableIndexSQL($aRow1[0])); + $oDataBase->iFetchType = MYSQL_ASSOC; + while ($aRow2 = $oDataBase->getRegistry($oDataset2)) { + if ( !isset($aOldSchema[$sTable]['INDEXES']) ) { + $aOldSchema[$sTable]['INDEXES'] = array(); + } + if (!isset($aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] ) ) { + $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']] = array(); + } + $aOldSchema[$sTable]['INDEXES'][$aRow2['Key_name']][] = $aRow2['Column_name']; + } + + $oDataBase->iFetchType = MYSQL_NUM; //this line is neccesary because the next fetch needs to be with MYSQL_NUM + } + //finally return the array with old schema obtained from the Database + if ( count($aOldSchema) == 0 ) $aOldSchema = null; + return $aOldSchema; +} + +//process the schema file in the patch file, and obtain an array +function schemaToArray($sSchemaFile) { + try { + $aSchema = array(); + $oXml = new DomDocument(); + $oXml->load($sSchemaFile); + $aTables = $oXml->getElementsByTagName('table'); + foreach ($aTables as $oTable) { + $aPrimaryKeys = array(); + $sTableName = $oTable->getAttribute('name'); + $aSchema[$sTableName] = array(); + $aColumns = $oTable->getElementsByTagName('column'); + foreach ($aColumns as $oColumn) { + $sColumName = $oColumn->getAttribute('name'); + $aSchema[$sTableName][$sColumName] = array(); + $aVendors = $oColumn->getElementsByTagName('vendor'); + foreach ($aVendors as $oVendor) { + if ($oVendor->getAttribute('type') == DB_ADAPTER) { + break; + } + } + $aParameters = $oColumn->getElementsByTagName('parameter'); + foreach ($aParameters as $oParameter) { + $parameterName = ucwords($oParameter->getAttribute('name')); + if ( $parameterName == 'Key' && strtoupper($oParameter->getAttribute('value')) == 'PRI' ) { + $aPrimaryKeys[] = $oColumn->getAttribute('name'); + } + + if ( in_array ( $parameterName, array('Field','Type','Null','Default') ) ) { + $aSchema[$sTableName][$sColumName][$parameterName] = $oParameter->getAttribute('value'); + } + } + } + + if ( is_array($aPrimaryKeys) && count($aPrimaryKeys) > 0 ) { + $aSchema[$sTableName]['INDEXES']['PRIMARY'] = $aPrimaryKeys; + } + $aIndexes = $oTable->getElementsByTagName('index'); + foreach ($aIndexes as $oIndex) { + $aIndex = array(); + $aIndexesColumns = $oIndex->getElementsByTagName('index-column'); + foreach ($aIndexesColumns as $oIndexColumn) { + $aIndex[] = $oIndexColumn->getAttribute('name'); + } + $aSchema[$sTableName]['INDEXES'][ $oIndex->getAttribute('name') ] = $aIndex; + } + } + return $aSchema; + } + catch (Exception $oError) { + throw $oError; + } +} + +function obtainChanges($aOldSchema, $aNewSchema) { + //$aChanges = array('tablesToDelete' => array(), 'tablesToAdd' => array(), 'tablesToAlter' => array()); + //Tables to delete, but this is disabled + //foreach ($aOldSchema as $sTableName => $aColumns) { + // if ( !isset($aNewSchema[$sTableName])) { + // if (!in_array($sTableName, array('KT_APPLICATION', 'KT_DOCUMENT', 'KT_PROCESS'))) { + // $aChanges['tablesToDelete'][] = $sTableName; + // } + // } + //} + + $aChanges = array('tablesToAdd' => array(), 'tablesToAlter' => array(), 'tablesWithNewIndex' => array(), 'tablesToAlterIndex'=> array()); + + //new tables to create and alter + foreach ($aNewSchema as $sTableName => $aColumns) { + if (!isset($aOldSchema[$sTableName])) { + $aChanges['tablesToAdd'][$sTableName] = $aColumns; + } + else { + //drop old columns + foreach ($aOldSchema[$sTableName] as $sColumName => $aParameters) { + if (!isset($aNewSchema[$sTableName][$sColumName])) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['DROP'][$sColumName] = $sColumName; + } + } + + //create new columns + //foreach ($aNewSchema[$sTableName] as $sColumName => $aParameters) { + foreach ($aColumns as $sColumName => $aParameters) { + if ($sColumName != 'INDEXES') { + if (!isset($aOldSchema[$sTableName][$sColumName])) { //this column doesnt exist in oldschema + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['ADD'][$sColumName] = $aParameters; + } + else { //the column exists + $newField = $aNewSchema[$sTableName][$sColumName]; + $oldField = $aOldSchema[$sTableName][$sColumName]; + //both are null, no change is required + if ( !isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = false; + //one of them is null, change IS required + if ( !isset($newField['Default']) && isset($oldField['Default']) && $oldField['Default']!= '') $changeDefaultAttr = true; + if ( isset($newField['Default']) && !isset($oldField['Default'])) $changeDefaultAttr = true; + //both are defined and they are different. + if ( isset($newField['Default']) && isset($oldField['Default']) ) { + if ( $newField['Default'] != $oldField['Default'] ) + $changeDefaultAttr = true; + else + $changeDefaultAttr = false; + } + //special cases + // BLOB and TEXT columns cannot have DEFAULT values. http://dev.mysql.com/doc/refman/5.0/en/blob.html + if ( in_array(strtolower($newField['Type']), array('text','mediumtext') ) ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for datetime field + if ( in_array($newField['Type'], array('datetime')) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //#1067 - Invalid default value for int field + if ( substr($newField['Type'], 0, 3 ) && isset($newField['Default']) && $newField['Default']== '' ) + $changeDefaultAttr = false; + + //if any difference exists, then insert the difference in aChanges + if ( $newField['Field'] != $oldField['Field'] || + $newField['Type'] != $oldField['Type'] || + $newField['Null'] != $oldField['Null'] || + $changeDefaultAttr ) { + if (!isset($aChanges['tablesToAlter'][$sTableName])) { + $aChanges['tablesToAlter'][$sTableName] = array('DROP' => array(), 'ADD' => array(), 'CHANGE' => array()); + } + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Field'] = $newField['Field']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Type'] = $newField['Type']; + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Null'] = $newField['Null']; + if ( isset($newField['Default']) ) + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = $newField['Default']; + else + $aChanges['tablesToAlter'][$sTableName]['CHANGE'][$sColumName]['Default'] = null; + + } + } + } //only columns, no the indexes column + }//foreach $aColumns + + //now check the indexes of table + if ( isset($aNewSchema[$sTableName]['INDEXES']) ) { + foreach ( $aNewSchema[$sTableName]['INDEXES'] as $indexName => $indexFields ) { + if (!isset( $aOldSchema[$sTableName]['INDEXES'][$indexName]) ) { + if (!isset($aChanges['tablesWithNewIndex'][$sTableName])) { + $aChanges['tablesWithNewIndex'][$sTableName] = array(); + } + $aChanges['tablesWithNewIndex'][$sTableName][$indexName] = $indexFields; + } + else { + if ( $aOldSchema[$sTableName]['INDEXES'][$indexName] != $indexFields ) { + if (!isset($aChanges['tablesToAlterIndex'][$sTableName])) { + $aChanges['tablesToAlterIndex'][$sTableName] = array(); + } + $aChanges['tablesToAlterIndex'][$sTableName][$indexName] = $indexFields; + } + } + } + } + } //for-else table exists + } //for new schema + return $aChanges; +} + diff --git a/workflow/engine/methods/setup/uplogo.php b/workflow/engine/methods/setup/uplogo.php new file mode 100644 index 000000000..6ebac25c0 --- /dev/null +++ b/workflow/engine/methods/setup/uplogo.php @@ -0,0 +1,117 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + global $RBAC; + G::LoadClass('replacementLogo'); + + if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + die; + } + + //calculating the max upload file size; + $POST_MAX_SIZE = ini_get('post_max_size'); + $mul = substr($POST_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $postMaxSize = (int)$POST_MAX_SIZE * $mul; + + $UPLOAD_MAX_SIZE = ini_get('upload_max_filesize'); + $mul = substr($UPLOAD_MAX_SIZE, -1); + $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1))); + $uploadMaxSize = (int)$UPLOAD_MAX_SIZE * $mul; + + if ( $postMaxSize < $uploadMaxSize ) $uploadMaxSize = $postMaxSize; + $Fields['MAX_FILE_SIZE'] = $uploadMaxSize . " (" . $UPLOAD_MAX_SIZE . ") "; + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'setup'; + $G_ID_MENU_SELECTED = 'SETUP'; + $G_ID_SUB_MENU_SELECTED = 'LOGO'; + + $G_PUBLISH = new Publisher; + $oHeadPublisher =& headPublisher::getSingleton(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/uplogo', '', $Fields ); + + $G_PUBLISH->AddContent('view', 'setup/uplogo' ); + G::RenderPage( "publishBlank", "blank"); + +?> + diff --git a/workflow/engine/methods/setup/webServices.php b/workflow/engine/methods/setup/webServices.php new file mode 100644 index 000000000..da38cb276 --- /dev/null +++ b/workflow/engine/methods/setup/webServices.php @@ -0,0 +1,161 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_FACTORY') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + $G_MAIN_MENU = 'processmaker'; + //$G_SUB_MENU = 'setup'; + $G_ID_MENU_SELECTED = 'SETUP'; + //$G_ID_SUB_MENU_SELECTED = 'WEBSERVICES'; + + if (!extension_loaded('soap')) { + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/wsMessage'); + G::RenderPage( "publish" ); + } + else + { + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'setup/webServicesTree' ); + $G_PUBLISH->AddContent('smarty', 'groups/groups_usersList', '', '', array()); + + G::RenderPage( "publish-treeview", 'blank'); + } + + $link_Edit = G::encryptlink('webServicesSetup'); + $link_List = G::encryptlink('webServicesList'); + + +?> + \ No newline at end of file diff --git a/workflow/engine/methods/setup/webServicesAjax.php b/workflow/engine/methods/setup/webServicesAjax.php new file mode 100644 index 000000000..b83d8b4c6 --- /dev/null +++ b/workflow/engine/methods/setup/webServicesAjax.php @@ -0,0 +1,1238 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +ini_set ( "soap.wsdl_cache_enabled", "0" ); // enabling WSDL cache + +G::LoadClass ( 'ArrayPeer' ); +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_FACTORY') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + +G::LoadInclude ( 'ajax' ); +//G::pr($_SESSION); +$_POST['action'] = get_ajax_value ( 'action' ); +if( $_POST['action'] == '' ){ + $_POST['action'] = (isset($_GET['action']))?$_GET['action']: ''; +} + +switch ($_POST ['action']) { + case 'showForm' : + global $G_PUBLISH; + $xmlform = isset ( $_POST ['wsID'] ) ? 'setup/ws' . $_POST ['wsID'] : ''; + if (file_exists ( PATH_XMLFORM . $xmlform . '.xml' )) { + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $G_PUBLISH = new Publisher ( ); + $fields ['SESSION_ID'] = isset ( $_SESSION ['WS_SESSION_ID'] ) ? $_SESSION ['WS_SESSION_ID'] : ''; + $fields ['ACTION'] = $_POST ['wsID']; + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', $xmlform, '', $fields, '../setup/webServicesAjax' ); + G::RenderPage ( 'publish', 'raw' ); + } + break; + + case 'showDetails' : + G::LoadClass ( 'groups' ); + + $dbc = new DBConnection ( ); + $ses = new DBSession ( $dbc ); + + if (! isset ( $_SESSION ['END_POINT'] )) { + $aFields ['WS_HOST'] = $_SERVER ['HTTP_HOST']; + $aFields ['WS_WORKSPACE'] = SYS_SYS; + } else { + if (strpos ( $_SESSION ['END_POINT'], 'https' ) !== false) { + preg_match ( '@^(?:https://)?([^/]+)@i', $_SESSION ['END_POINT'], $coincidencias ); + } else { + preg_match ( '@^(?:http://)?([^/]+)@i', $_SESSION ['END_POINT'], $coincidencias ); + } + $aAux = explode ( ':', $coincidencias [1] ); + $aFields ['WS_HOST'] = $aAux [0]; + $aFields ['WS_PORT'] = (isset ( $aAux [1] ) ? $aAux [1] : ''); + $aAux = explode ( $aAux [0] . (isset ( $aAux [1] ) ? ':' . $aAux [1] : ''), $_SESSION ['END_POINT'] ); + $aAux = explode ( '/', $aAux [1] ); + $aFields ['WS_WORKSPACE'] = substr ( $aAux [1], 3 ); + } + + $rows [] = array ('uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); + $rows [] = array ('uid' => 'http', 'name' => 'http' ); + $rows [] = array ('uid' => 'https', 'name' => 'https' ); + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['protocol'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + if (! isset ( $_SESSION ['END_POINT'] )) { + //$wsdl = 'http://'.$_SERVER['HTTP_HOST'].'/sys'.SYS_SYS.'/en/green/services/wsdl'; + $wsdl = 'http://' . $_SERVER ['HTTP_HOST']; + $workspace = SYS_SYS; + } else { + $wsdl = $_SESSION ['END_POINT']; + $workspace = $_SESSION ['WS_WORKSPACE']; + } + + $defaultEndpoint = 'http://' . $_SERVER ['SERVER_NAME'] . ':' . $_SERVER ['SERVER_PORT'] . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + + $wsdl = isset ( $_SESSION ['END_POINT'] ) ? $_SESSION ['END_POINT'] : $defaultEndpoint; + + $wsSessionId = ''; + if (isset ( $_SESSION ['WS_SESSION_ID'] )) { + $wsSessionId = $_SESSION ['WS_SESSION_ID']; + } + + $aFields ['WSDL'] = $wsdl; + $aFields ['OS'] = $workspace; + $aFields ['WSID'] = $wsSessionId; + + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/webServicesDetails', '', $aFields, 'webServicesSetupSave' ); + + G::RenderPage ( "publish", "raw" ); + + break; + case 'showUploadFilesForm': + global $G_PUBLISH; + $xmlform = 'setup/wsSendFiles'; + if (file_exists ( PATH_XMLFORM . $xmlform . '.xml' )) { + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + + $G_PUBLISH = new Publisher ( ); + $fields ['SESSION_ID'] = isset ( $_SESSION ['WS_SESSION_ID'] ) ? $_SESSION ['WS_SESSION_ID'] : ''; + $fields ['ACTION'] = 'wsSendFiles'; + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', $xmlform, '', $fields, '../setup/webServicesAjax'); + G::RenderPage ( 'publish', 'blank' ); + } + break; + }try { + global $G_PUBLISH; + if (isset ( $_POST ['form'] ['ACTION'] )) { + $frm = $_POST ['form']; + $action = $frm ['ACTION']; + if (isset ( $_POST ["epr"] )) { + $_SESSION ['END_POINT'] = $_POST ["epr"]; + } + $defaultEndpoint = 'http://' . $_SERVER ['SERVER_NAME'] . ':' . $_SERVER ['SERVER_PORT'] . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + + $endpoint = isset ( $_SESSION ['END_POINT'] ) ? $_SESSION ['END_POINT'] : $defaultEndpoint; + + $sessionId = isset ( $_SESSION ['SESSION_ID'] ) ? $_SESSION ['SESSION_ID'] : ''; + @$client = new SoapClient ( $endpoint ); + + switch ($action) { + case "Login" : + $user = $frm ["USER_ID"]; + $pass = $frm ["PASSWORD"]; + $params = array ('userid' => $user, 'password' => $pass ); + $result = $client->__SoapCall ( 'login', array ($params ) ); + $_SESSION ['WS_SESSION_ID'] = ''; + if ($result->status_code == 0) { + $_SESSION ['WS_SESSION_ID'] = $result->message; + } + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = 'ProcessMaker WebService version: ' . $result->version . "\n" . $result->message; + $fields ['version'] = $result->version; + $fields ['time_stamp'] = $result->timestamp; + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + case "ProcessList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + + $wsResponse = $client->__SoapCall ( 'ProcessList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'processes'); + + $G_PUBLISH = new Publisher(); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + + if( is_array($result) ){ + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['process'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'process' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrProcessList', $c ); + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + case "RoleList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + $wsResponse = $client->__SoapCall ( 'RoleList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'roles'); + + $G_PUBLISH = new Publisher (); + + $rows [] = array ('guid' => 'char', 'name' => 'char'); + if ( is_array ( $result )){ + + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['role'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'role' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrRoleList', $c ); + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "GroupList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + $wsResponse = $client->__SoapCall ( 'GroupList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'groups'); + + $G_PUBLISH = new Publisher ( ); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + if (is_array ( $result )){ + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['group'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'group' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrGroupList', $c ); + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "CaseList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + $wsResponse = $client->__SoapCall ( 'CaseList', array ($params ) ); + + $G_PUBLISH = new Publisher ( ); + $rows [] = array ('guid' => 'char', 'name' => 'char', 'status' => 'char', 'delIndex' => 'char' ); + + $result = G::PMWSCompositeResponse($wsResponse, 'cases'); + + if ( is_array( $result )) { + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'status') + $status = $val->value; + if ($val->key == 'delIndex') + $delIndex = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'status') + $status = $val->value; + if ($val->key == 'delIndex') + $delIndex = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + if (isset ( $item->status )) + $status = $item->status; + if (isset ( $item->delIndex )) + $delIndex = $item->delIndex; + + } + $rows [] = array ('guid' => $guid, 'name' => $name, 'status' => $status, 'delIndex' => $delIndex ); + + } + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['case'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'case' ); + //$c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrCaseList', $c ); + + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "UserList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + $wsResponse = $client->__SoapCall ( 'UserList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'users'); + + $G_PUBLISH = new Publisher(); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + if (is_array ( $result )){ + + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['user'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'user' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrUserList', $c ); + + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + G::RenderPage ( 'publish', 'raw' ); + break; + + case "SendMessage" : + require_once('classes/model/Application.php'); + $sessionId = $frm ["SESSION_ID"]; + $from = $frm ["FROM"]; + $to = $frm ["TO_EMAIL"]; + $cc = isset($frm ["CC_MAIL"]) ?$frm ["CC_MAIL"] :''; + $bcc = isset($frm ["BCC_MAIL"])?$frm ["BCC_MAIL"] :''; + $caseId = $frm ["CASE_ID"]; + $subject = $frm ["SUBJECT"]; + $message = $frm ["MESSAGE"]; + // getting the proUid variable + $oCases = new Application(); + $oCases->load($caseId); + $proUid = $oCases->getProUid(); + $caseNumber = $oCases->getAppNumber(); + + // generating the path for the template msj + $templateFile = PATH_DB.SYS_SYS.PATH_SEP.'mailTemplates'.PATH_SEP.$proUid.PATH_SEP.'tempTemplate.hml'; + // generating the file adding the msj variable + $messageBody = "message for case: ".$caseNumber. "
    " . $message; + file_put_contents($templateFile, $messageBody); + + $params = array ( 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'from' => $from, + 'to' => $to, + 'cc' => $cc, + 'bcc' => $bcc, + 'subject' => $subject, + 'template' => 'tempTemplate.hml' ); + $result = $client->__SoapCall ( 'sendMessage', array ($params ) ); + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "SendVariables" : + $sessionId = $frm ["SESSION_ID"]; + $caseId = $frm ["CASE_ID"]; + $variables = Array(); + + $o = new stdClass(); + $o->name = $frm ["NAME1"]; + $o->value = $frm ["VALUE1"]; + array_push($variables, $o); + $o = new stdClass(); + $o->name = $frm ["NAME2"]; + $o->value = $frm ["VALUE2"]; + array_push($variables, $o); + + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId, 'variables' => $variables ); + $result = $client->__SoapCall ( 'SendVariables', array ($params ) ); + $G_PUBLISH = new Publisher(); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "DerivateCase" : + $sessionId = $frm ["SESSION_ID"]; + $caseId = $frm ["CASE_ID"]; + $delIndex = $frm ["DEL_INDEX"]; + + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId, 'delIndex' => $delIndex ); + $result = $client->__SoapCall ( 'RouteCase', array ($params ) ); + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "ReassignCase" : + $sessionId = $frm ["SESSION_ID"]; + $caseId = $frm ["CASE_ID"]; + $delIndex = $frm ["DEL_INDEX"]; + $userIdSource = $frm ['USERIDSOURCE']; + $userIdTarget = $frm ['USERIDTARGET']; + + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId, 'delIndex' => $delIndex, 'userIdSource' => $userIdSource, 'userIdTarget' => $userIdTarget ); + $result = $client->__SoapCall ( 'reassignCase', array ($params ) ); + + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "NewCaseImpersonate" : + $sessionId = $frm ["SESSION_ID"]; + $processId = $frm ["PROCESS_ID"]; + $userId = $frm ["USER_ID"]; + $variables = Array(); + foreach ( $frm ['VARIABLES'] as $iRow => $aRow ) { + $o = new stdClass(); + $o->name = $aRow ['NAME']; + $o->value = $aRow ['VALUE']; + array_push($variables, $o); + } + $params = array ('sessionId' => $sessionId, 'processId' => $processId, 'userId' => $userId, 'variables' => $variables ); + $result = $client->__SoapCall ( 'NewCaseImpersonate', array ($params ) ); + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "NewCase" : + $sessionId = $frm ["SESSION_ID"]; + $processId = $frm ["PROCESS_ID"]; + $taskId = $frm ["TASK_ID"]; + + $variables = Array(); + foreach ( $frm ['VARIABLES'] as $iRow => $aRow ) { + $o = new stdClass(); + $o->name = $aRow ['NAME']; + $o->value = $aRow ['VALUE']; + array_push($variables, $o); + } + $params = array ('sessionId' => $sessionId, 'processId' => $processId, 'taskId' => $taskId, 'variables' => $variables ); + $result = $client->__SoapCall ( 'NewCase', array ($params ) ); + + $G_PUBLISH = new Publisher ( ); + + $fields ['status_code'] = $result->status_code; + $fields ['time_stamp'] = $result->timestamp; + if( isset($result->caseId) ){ + $fields ['message'] = "Case ID: ".$result->caseId."\nCase Number: ".$result->caseNumber."\n".$result->message; + } else { + $fields ['message'] = ''; + } + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "AssignUserToGroup" : + $sessionId = $frm ["SESSION_ID"]; + $userId = $frm ["USER_ID"]; + $groupId = $frm ["GROUP_ID"]; + $params = array ('sessionId' => $sessionId, 'userId' => $userId, 'groupId' => $groupId ); + $result = $client->__SoapCall ( 'AssignUserToGroup', array ($params ) ); + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "CreateUser" : + $sessionId = $frm ["SESSION_ID"]; + $userId = $frm ["USER_ID"]; + $firstname = $frm ["FIRST_NAME"]; + $lastname = $frm ["LAST_NAME"]; + $email = $frm ["EMAIL"]; + $role = $frm ["ROLE"]; + $password = $frm ["PASSWORD"]; + + $params = array ('sessionId' => $sessionId, 'userId' => $userId, 'firstname' => $firstname, 'lastname' => $lastname, 'email' => $email, 'role' => $role, 'password' => $password ); + $result = $client->__SoapCall ( 'CreateUser', array ($params ) ); + $G_PUBLISH = new Publisher ( ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "TaskList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + $wsResponse = $client->__SoapCall ( 'TaskList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'tasks'); + + $G_PUBLISH = new Publisher ( ); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + + if (is_array ( $result )){ + + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['task'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'task' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrTaskList', $c ); + } else if( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + G::RenderPage ( 'publish', 'raw' ); + break; + + case "TriggerList" : + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId ); + + $wsResponse = $client->__SoapCall ( 'triggerList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'triggers'); + + $G_PUBLISH = new Publisher (); + $rows [] = array ('guid' => 'char', 'name' => 'char', 'processId' => 'char' ); + + if (is_array ( $result )){ + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'processId') + $processId = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'processId') + $processId = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + if (isset ( $item->processId )) + $processId = $item->processId; + } + $rows [] = array ('guid' => $guid, 'name' => $name, 'processId' => $processId ); + } + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + + foreach ( $rows as $key => $row ) { + $proId = $row['processId']; + if ( isset ($_DBArray ['process']) && is_array ($_DBArray ['process']) ) + foreach ( $_DBArray ['process'] as $pkey => $prow ) { + if ( $proId == $prow['guid'] ) { + $rows[ $key ]['processId'] = $prow['name']; + } + } + } + + $_DBArray ['triggers'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'triggers' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrTriggerList', $c ); + + } else if ( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "InputDocumentList" : + $caseId = $frm ["CASE_ID"]; + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId ); + + $wsResponse = $client->__SoapCall ( 'InputDocumentList', array ($params ) ); + + //g::pr($wsResponse); + $result = G::PMWSCompositeResponse($wsResponse, 'documents'); + + $G_PUBLISH = new Publisher ( ); + $rows [] = array ('guid' => 'char', 'name' => 'char', 'processId' => 'char' ); + + if (is_array( $result )){ + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'filename') + $filename = $val->value; + if ($val->key == 'docId') + $docId = $val->value; + if ($val->key == 'version') + $version = $val->value; + if ($val->key == 'createDate') + $createDate = $val->value; + if ($val->key == 'createBy') + $createBy = $val->value; + if ($val->key == 'type') + $type = $val->value; + if ($val->key == 'link') + $link = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'filename') + $filename = $val->value; + if ($val->key == 'docId') + $docId = $val->value; + if ($val->key == 'version') + $version = $val->value; + if ($val->key == 'createDate') + $createDate = $val->value; + if ($val->key == 'createBy') + $createBy = $val->value; + if ($val->key == 'type') + $type = $val->value; + if ($val->key == 'link') + $link = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->filename )) + $filename = $item->filename; + if (isset ( $item->docId )) + $docId = $item->docId; + if (isset ( $item->version )) + $version = $item->version; + if (isset ( $item->createDate )) + $createDate = $item->createDate; + if (isset ( $item->createBy )) + $createBy = $item->createBy; + if (isset ( $item->type )) + $type = $item->type; + if (isset ( $item->link )) + $link = $item->link; + } + $rows [] = array ('guid' => $guid, 'filename' => $filename, 'docId' => $docId, 'version' => $version, + 'createDate' => $createDate, 'createBy' => $createBy, 'type' => $type, 'link' => $link ); + } + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['inputDocument'] = $rows; + $documentArray = array(); + $documentArray[] = array ('guid' => 'char', 'filename' => 'char' ); + if ( isset($_DBArray ['inputDocument']) ) + foreach ( $_DBArray ['inputDocument'] as $key => $val ) + if ( $key != 0 && isset ($val['filename']) ) + $documentArray[] = array ('guid' => $val['guid'], 'filename' => $val['filename'] ); + if ( isset($_DBArray ['outputDocument']) ) + foreach ( $_DBArray ['outputDocument'] as $key => $val ) + if ( $key != 0 && isset ($val['filename']) ) + $documentArray[] = array ('guid' => $val['guid'], 'filename' => $val['filename'] ); + $_DBArray ['documents'] = $documentArray; + $_DBArray ['WS_TMP_CASE_UID'] = $frm ["CASE_ID"]; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'inputDocument' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrInputDocumentList', $c ); + + } else if ( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + G::RenderPage ( 'publish', 'raw' ); + + break; + + case "InputDocumentProcessList" : + $processId = $frm ["PROCESS_ID"]; + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId, 'processId' => $processId ); + + $wsResponse = $client->__SoapCall ( 'InputDocumentProcessList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'documents'); + + $G_PUBLISH = new Publisher(); + $rows [] = array ('guid' => 'char', 'name' => 'char', 'description' => 'char' ); + if (is_array ( $result )){ + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'description') + $description = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + if ($val->key == 'description') + $description = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + if (isset ( $item->description )) + $description = $item->description; + } + $rows [] = array ('guid' => $guid, 'name' => $name, 'description' => $description ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['inputDocuments'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'inputDocuments' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrInputDocumentProcessList', $c ); + } else if ( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + G::RenderPage ( 'publish', 'raw' ); + break; + + + case "OutputDocumentList" : + $caseId = $frm ["CASE_ID"]; + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId ); + + $wsResponse = $client->__SoapCall ( 'outputDocumentList', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'documents'); + + $G_PUBLISH = new Publisher ( ); + $rows = array(); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + if (is_array ( $result )){ + + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'filename') + $filename = $val->value; + if ($val->key == 'docId') + $docId = $val->value; + if ($val->key == 'version') + $version = $val->value; + if ($val->key == 'createDate') + $createDate = $val->value; + if ($val->key == 'createBy') + $createBy = $val->value; + if ($val->key == 'type') + $type = $val->value; + if ($val->key == 'link') + $link = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'filename') + $filename = $val->value; + if ($val->key == 'docId') + $docId = $val->value; + if ($val->key == 'version') + $version = $val->value; + if ($val->key == 'createDate') + $createDate = $val->value; + if ($val->key == 'createBy') + $createBy = $val->value; + if ($val->key == 'type') + $type = $val->value; + if ($val->key == 'link') + $link = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->filename )) + $filename = $item->filename; + if (isset ( $item->docId )) + $docId = $item->docId; + if (isset ( $item->version )) + $version = $item->version; + if (isset ( $item->createDate )) + $createDate = $item->createDate; + if (isset ( $item->createBy )) + $createBy = $item->createBy; + if (isset ( $item->type )) + $type = $item->type; + if (isset ( $item->link )) + $link = $item->link; + } + $rows [] = array ('guid' => $guid, 'filename' => $filename, 'docId' => $docId, 'version' => $version, + 'createDate' => $createDate, 'createBy' => $createBy, 'type' => $type, 'link' => $link ); + } + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['outputDocument'] = $rows; + $documentArray = array(); + $documentArray[] = array ('guid' => 'char', 'filename' => 'char' ); + if ( isset($_DBArray ['inputDocument']) ) + foreach ( $_DBArray ['inputDocument'] as $key => $val ) + if ( $key != 0 && isset ($val['filename']) ) + $documentArray[] = array ('guid' => $val['guid'], 'filename' => $val['filename'] ); + if ( isset($_DBArray ['outputDocument']) ) + foreach ( $_DBArray ['outputDocument'] as $key => $val ) + if ( $key != 0 && isset ($val['filename']) ) + $documentArray[] = array ('guid' => $val['guid'], 'filename' => $val['filename'] ); + $_DBArray ['documents'] = $documentArray; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'outputDocument' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrOutputDocumentList', $c ); + } else if ( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "RemoveDocument" : + $appDocUid = $frm ["APP_DOC_UID"]; + $sessionId = $frm ["SESSION_ID"]; + $params = array ('sessionId' => $sessionId, 'appDocUid' => $appDocUid ); + $result = $client->__SoapCall ( 'RemoveDocument', array ($params ) ); + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = $result->timestamp; + + if( $result->status_code == 9 ){ + $_SESSION ['WS_SESSION_ID'] = ''; + } + + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'raw' ); + break; + + case "TaskCase" : + $sessionId = $frm ["SESSION_ID"]; + $caseId = $frm ["CASE_ID"]; + + $params = array ('sessionId' => $sessionId, 'caseId' => $caseId ); + $wsResponse = $client->__SoapCall ( 'TaskCase', array ($params ) ); + $result = G::PMWSCompositeResponse($wsResponse, 'taskCases'); + + $G_PUBLISH = new Publisher ( ); + $rows [] = array ('guid' => 'char', 'name' => 'char' ); + + if (is_array ( $result )){ + + foreach ( $result as $key => $item ) { + if (isset ( $item->item )) + foreach ( $item->item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else if (is_array ( $item )) + foreach ( $item as $index => $val ) { + if ($val->key == 'guid') + $guid = $val->value; + if ($val->key == 'name') + $name = $val->value; + } + else { + if (isset ( $item->guid )) + $guid = $item->guid; + if (isset ( $item->name )) + $name = $item->name; + } + + $rows [] = array ('guid' => $guid, 'name' => $name ); + } + + global $_DBArray; + $_DBArray = (isset ( $_SESSION ['_DBArray'] ) ? $_SESSION ['_DBArray'] : ''); + $_DBArray ['taskCases'] = $rows; + $_SESSION ['_DBArray'] = $_DBArray; + + G::LoadClass ( 'ArrayPeer' ); + $c = new Criteria ( 'dbarray' ); + $c->setDBArrayTable ( 'taskCases' ); + $c->addAscendingOrderByColumn ( 'name' ); + $G_PUBLISH->AddContent ( 'propeltable', 'paged-table', 'setup/wsrTaskCase', $c ); + } else if ( is_object($result) ){ + $_SESSION ['WS_SESSION_ID'] = ''; + $fields ['status_code'] = $result->status_code; + $fields ['message'] = $result->message; + $fields ['time_stamp'] = date("Y-m-d H:i:s"); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + } + + G::RenderPage ( 'publish', 'raw' ); + break; + + case "wsSendFiles" : + if ( isset($_FILES['form']) ) { + foreach ($_FILES['form']['name'] as $sFieldName => $vValue) { + if ( $_FILES['form']['error'][$sFieldName] == 0 ){ + file_put_contents(G::getSysTemDir().PATH_SEP.$_FILES['form']['name'][$sFieldName], file_get_contents($_FILES['form']['tmp_name'][$sFieldName])); + $filename = G::getSysTemDir().PATH_SEP.$_FILES['form']['name'][$sFieldName]; + } + } + } + +// G::pr ( $_SESSION ); + if (isset($_SESSION['_DBArray']['inputDocument'])){ + foreach($_SESSION['_DBArray']['inputDocument'] as $inputDocument){ + if ($inputDocument['guid']==$_POST['form']['INPUT_DOCUMENT']){ + $doc_uid = $inputDocument['docId']; + } + } + } else { + $doc_uid = "default"; + } + $usr_uid = $_SESSION['USER_LOGGED']; + $app_uid = $_SESSION['_DBArray']['WS_TMP_CASE_UID']; + $del_index = 1; + + function sendFile($FILENAME, $USR_UID, $APP_UID, $DEL_INDEX = 1, $DOC_UID = NULL, $title = NULL, $comment = NULL) { + $defaultEndpoint = 'http://' . $_SERVER ['SERVER_NAME'] . ':' . $_SERVER ['SERVER_PORT'] . '/sys' . SYS_SYS . '/en/green/services/upload'; + $upload = isset ( $_SESSION ['END_POINT'] ) ? $_SESSION ['END_POINT'] : $defaultEndpoint; + + $DOC_UID = ($DOC_UID != NULL) ? $DOC_UID : - 1; + $APP_DOC_TYPE = ($DOC_UID == - 1) ? 'ATTACHED' : 'INPUT'; + $title = ($title != NULL) ? $title : $FILENAME; + $comment = ($comment != NULL) ? $comment : ''; + + $params = array ( + 'ATTACH_FILE' => "@$FILENAME", + 'APPLICATION' => $APP_UID, + 'INDEX' => $DEL_INDEX, + 'USR_UID' => $USR_UID, + 'DOC_UID' => $DOC_UID, + 'APP_DOC_TYPE' => $APP_DOC_TYPE, + 'TITLE' => $title, + 'COMMENT' => $comment + ); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $defaultEndpoint); + //curl_setopt($ch, CURLOPT_VERBOSE, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + $response = curl_exec($ch); + curl_close($ch); + return $response; + } + + $fields ['status_code'] = 0; + $fields ['time_stamp'] = date( "Y-m-d H:i:s" ); + if ($_POST['form']['UPLOAD_OPTION']=='1'){ + // G::pr($doc_uid); + $fields ['message'] = sendFile($filename, $usr_uid, $app_uid, 1, $doc_uid); + + } else { + $fields ['message'] = sendFile($filename, $usr_uid, $app_uid); + } + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'setup/wsShowResult', null, $fields ); + G::RenderPage ( 'publish', 'blank' ); + die (); + break; + default : + print_r ( $_POST ); + } + } + global $_DBArray; + + +} catch ( Exception $e ) { + $G_PUBLISH = new Publisher ( ); + $aMessage ['MESSAGE'] = $e->getMessage (); + $G_PUBLISH->AddContent ( 'xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage ( 'publish', 'raw' ); +} + diff --git a/workflow/engine/methods/setup/webServicesList.php b/workflow/engine/methods/setup/webServicesList.php new file mode 100644 index 000000000..665b34163 --- /dev/null +++ b/workflow/engine/methods/setup/webServicesList.php @@ -0,0 +1,36 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if($RBAC->userCanAccess('PM_SETUP') != 1 && $RBAC->userCanAccess('PM_FACTORY') != 1){ + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + //G::header('location: ../login/login'); + die; +} + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'setup/webServicesTree' ); + G::RenderPage( "publish-raw" , "raw" ); +?> diff --git a/workflow/engine/methods/setup/webServicesSetup.php b/workflow/engine/methods/setup/webServicesSetup.php new file mode 100644 index 000000000..36cc27741 --- /dev/null +++ b/workflow/engine/methods/setup/webServicesSetup.php @@ -0,0 +1,63 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + + G::LoadClass('groups'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + if (!isset($_SESSION['END_POINT'])) { + $aFields['WS_HOST'] = $_SERVER['HTTP_HOST']; + $aFields['WS_WORKSPACE'] = SYS_SYS; + } + else { + if (strpos($_SESSION['END_POINT'], 'https') !== false) { + preg_match('@^(?:https://)?([^/]+)@i', $_SESSION['END_POINT'], $coincidencias); + } + else { + preg_match('@^(?:http://)?([^/]+)@i', $_SESSION['END_POINT'], $coincidencias); + } + $aAux = explode(':', $coincidencias[1]); + $aFields['WS_HOST'] = $aAux[0]; + $aFields['WS_PORT'] = (isset($aAux[1]) ? $aAux[1] : ''); + $aAux = explode($aAux[0] . (isset($aAux[1]) ? ':' . $aAux[1] : ''), $_SESSION['END_POINT']); + $aAux = explode('/', $aAux[1]); + $aFields['WS_WORKSPACE'] = substr($aAux[1], 3); + } + +$rows[] = array ( 'uid' => 'char', 'name' => 'char', 'age' => 'integer', 'balance' => 'float' ); +$rows[] = array ( 'uid' => 'http', 'name' => 'http' ); +$rows[] = array ( 'uid' => 'https', 'name' => 'https' ); + +$_DBArray['protocol'] = $rows; +$_SESSION['_DBArray'] = $_DBArray; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/webServicesSetup', '', $aFields , 'webServicesSetupSave'); + + G::RenderPage( "publish" , "raw" ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/webServicesSetupSave.php b/workflow/engine/methods/setup/webServicesSetupSave.php new file mode 100644 index 000000000..3949503cc --- /dev/null +++ b/workflow/engine/methods/setup/webServicesSetupSave.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/workflow/engine/methods/setup/weekend.php b/workflow/engine/methods/setup/weekend.php new file mode 100644 index 000000000..804d72ab7 --- /dev/null +++ b/workflow/engine/methods/setup/weekend.php @@ -0,0 +1,93 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; +G::LoadInclude('ajax'); + + $G_ENABLE_BLANK_SKIN = true; + +$ARR_WEEKDAYS[0] = array('SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'); +$ARR_WEEKDAYS['es'] = array("Domingo?", "Lunes?", "Martes?", "Miércoles?", "Jueves?", "Viernes?", "Sábado?"); +$ARR_WEEKDAYS['en'] = array("Sunday?", "Monday?", "Tuesday?", "Wednesday?", "Thursday?", "Friday?", "Saturday?"); +$ARR_WEEKDAYS['fa'] = array('یکشنبه','دوشنبه','سه شنبه','چهارشنبه','پنجشنبه ','جمعه','آدینه'); + +$dbc = new DBConnection; +$ses = new DBSession($dbc); + +$holidays=$ses->execute( "SELECT LEX_VALUE FROM LEXICO WHERE LEX_TOPIC ='NOWORKINGDAY' "); + +$config=array(); +for($id=0;$id<7;$id++) +{ + $res=$ses->execute(" SELECT * FROM LEXICO WHERE LEX_KEY = '".$ARR_WEEKDAYS[0][$id]."' AND LEX_TOPIC ='HOLIDAY' "); + $res=$res->read(); + $config[$ARR_WEEKDAYS[0][$id]]=$res['LEX_VALUE']; +} +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'setup/weekend', '',$config ,'' ); +G::RenderPage( 'publish' ); +?> + \ No newline at end of file diff --git a/workflow/engine/methods/setup/weekendAjax.php b/workflow/engine/methods/setup/weekendAjax.php new file mode 100644 index 000000000..7f384f6fd --- /dev/null +++ b/workflow/engine/methods/setup/weekendAjax.php @@ -0,0 +1,70 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; +G::ForceLogin( 'WF_PROCESS' ); +G::LoadInclude('ajax'); + +$G_HELP_PAGE = "setup-environment-time-controls-weekend"; + +$G_MAIN_MENU = "processmaker"; +$G_SUB_MENU = "setupPM"; +$G_THIRD_MENU = "workingTime"; + +$G_ID_MENU_SELECTED = "SETUP"; +$G_ID_SUB_MENU_SELECTED = "ENVIRONMENT"; +$G_ID_THIRD_MENU_SELECTED = "WEEKEND"; + +$dbc = new DBConnection; +$ses = new DBSession($dbc); + +$holidays=$ses->execute('SELECT LEX_VALUE FROM LEXICO WHERE LEX_TOPIC ="HOLIDAY"'); + +$funcion=strtolower(get_ajax_value('function')); +$funcions=get_defined_functions(); +if (in_array($funcion,$funcions['user'])) eval($funcion.'();'); + +function setDays() +{ + $days=get_ajax_value('days'); + $values=get_ajax_value('values'); + $days=explode(',',$days); + $values=explode(',',$values); + for($r=1;$rexecute(" SELECT * FROM LEXICO WHERE LEX_KEY = '$day' AND LEX_TOPIC ='HOLIDAY' "); + if ($res->count()==0) + $res=$ses->execute(" INSERT INTO LEXICO (LEX_TOPIC, LEX_KEY, LEX_VALUE) VALUES ('HOLIDAY', '$day', $dayValue) "); + else + $res=$ses->execute(" UPDATE LEXICO SET LEX_VALUE = $dayValue WHERE LEX_KEY = '$day' AND LEX_TOPIC ='HOLIDAY' "); + $res=$ses->execute(" SELECT * FROM LEXICO WHERE LEX_KEY = '$day' AND LEX_TOPIC ='HOLIDAY' "); + $res=$res->read(); + echo ($res['LEX_VALUE']=='1')?'true':'false'; +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/workPeriod.js b/workflow/engine/methods/setup/workPeriod.js new file mode 100644 index 000000000..e0f6f0711 --- /dev/null +++ b/workflow/engine/methods/setup/workPeriod.js @@ -0,0 +1,20 @@ + +function abc( panel, txt ) { +/* commonDialog ( '', 'saved' , 'saved', {}, '' ) ; + setTimeout ( leimnud.closure({instance:myDialog,method:function(panel){ + + myDialog.remove(); + panel.tabLastSelected=false; + panel.tabSelected=1; + panel.makeTab(); + },args:panel}) , 1000 ); +*/ + var img = document.getElementById( 'workPeriodGraph' ); + img.src = 'workPeriodGraph?b=' + Math.random() ; + +// panel.clearContent(); +// panel.addContent ( txt ); + return false; +} + + \ No newline at end of file diff --git a/workflow/engine/methods/setup/workPeriod.php b/workflow/engine/methods/setup/workPeriod.php new file mode 100644 index 000000000..6d1bc7967 --- /dev/null +++ b/workflow/engine/methods/setup/workPeriod.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + $G_ENABLE_BLANK_SKIN = true; + + G::LoadClass( "workPeriod" ); + + $dbc = new DBConnection; + $ses = new DBSession( $dbc ); + $obj = new workPeriod( $dbc ); + + $row = $obj->Load (); + + $row['SUNDAY'] = $row['noWorkingDays'][0]; + $row['MONDAY'] = $row['noWorkingDays'][1]; + $row['TUESDAY'] = $row['noWorkingDays'][2]; + $row['WEDNESDAY'] = $row['noWorkingDays'][3]; + $row['THURSDAY'] = $row['noWorkingDays'][4]; + $row['FRIDAY'] = $row['noWorkingDays'][5]; + $row['SATURDAY'] = $row['noWorkingDays'][6]; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent( "image", "image", "workPeriodGraph" ); + $G_PUBLISH->AddContent( "xmlform", "xmlform", "setup/workPeriod","", $row , "workPeriodSave" ); + + G::RenderPage( 'publish' ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/workPeriodGraph.php b/workflow/engine/methods/setup/workPeriodGraph.php new file mode 100644 index 000000000..dda6f9596 --- /dev/null +++ b/workflow/engine/methods/setup/workPeriodGraph.php @@ -0,0 +1,102 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + Header("Content-type: image/jpeg"); + + G::LoadClass( "workPeriod" ); + + $dbc = new DBConnection; + $ses = new DBSession( $dbc ); + $obj = new workPeriod( $dbc ); + + $row = $obj->Load (); + + $initPeriod1 = $row['initPeriod1']/ 60; + $endPeriod1 = $row['endPeriod1'] / 60; + $initPeriod2 = $row['initPeriod2']/ 60; + $endPeriod2 = $row['endPeriod2'] / 60; + $noWorkingDays = $row['noWorkingDays']; + + $cant = 7; + + $w = 660; + $h = $cant*18 + 20; + $im= ImageCreate($w, $h); + $width = $w; + $height = $h; + $center_x = intval($width / 2); + $center_y = intval($height / 2); + + $bgcolor = ImageColorAllocate($im, 250, 250, 255); + $plomo = ImageColorAllocate($im, 220, 220, 220); + $orange = ImageColorAllocate($im, 255, 64, 64); + $gris = ImageColorAllocate($im, 150, 150, 155); + $white = ImageColorAllocate($im, 255, 255, 255); + $red = ImageColorAllocate($im, 255, 0, 0); + $brown = ImageColorAllocate($im, 160, 80, 0); + $black = ImageColorAllocate($im, 0,0,0); + ImageFilledRectangle($im, 0, 0, $width-1, $height-1, $bgcolor); + ImageRectangle ($im, 0, 0, $width-1, $height-1, $black); + + + $x = 10; $y = 20; + $x1 = 78; + $x2 = $x1 + 2*6; + + $weekday[0] = 'Sunday'; + $weekday[1] = 'Monday'; + $weekday[2] = 'Tuesday'; + $weekday[3] = 'Wednesday'; + $weekday[4] = 'Thursday'; + $weekday[5] = 'Friday'; + $weekday[6] = 'Saturday'; + + for ( $day = 0; $day < count ($weekday ); $day ++ ) { + ImageString($im, 2, $x, $y, $weekday[$day], $black); + for ($i = 0; $i < 24*6; $i++) { + ImageRectangle($im, $x1+$i* 4, $y, $x1+ ($i+1)*4, $y+12, $plomo ); + if ( $i >= $initPeriod1 * 6 && $i < $endPeriod2 * 6 && ( $i < $endPeriod1 * 6 || $i >= $initPeriod2 * 6 ) ) + $color = $orange; + else + $color = $white; + if ( isset ( $noWorkingDays[ $day ]) && $noWorkingDays[ $day ] ) $color = $white; + ImageFillToBorder($im, $x1+$i*4+1, $y+1, $plomo, $color ); + } + + $y+=18; + } + + $y = 20; + for ($i = 0; $i <= 24; $i++) { + ImageLine($im, $x1+$i* 4*6, $y-5, $x1+ $i*4*6, $y-5+18*$cant, $gris); + if ( $i < 24 ) { + ImageLine($im, $x2+$i* 4*6, $y-5, $x2+ $i*4*6, $y-5+18*$cant, $plomo); + ImageString($im, 1, $x1+$i* 4*6, $y-10, $i, $black); + } + } + //ImageString($im, 2, 5, 5, $initPeriod1*6 . ", $endPeriod1, $initPeriod2, $endPeriod2 ", $black); + + ImageJpeg($im); +?> \ No newline at end of file diff --git a/workflow/engine/methods/setup/workPeriodSave.php b/workflow/engine/methods/setup/workPeriodSave.php new file mode 100644 index 000000000..cdf27dc58 --- /dev/null +++ b/workflow/engine/methods/setup/workPeriodSave.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + G::LoadClass( "workPeriod" ); + + $frm = $_POST['form']; + $noWorkingDays[0] = isset ( $frm['SUNDAY'] ) && $frm['SUNDAY'] != ''; + $noWorkingDays[1] = isset ( $frm['MONDAY'] ) && $frm['MONDAY'] != ''; + $noWorkingDays[2] = isset ( $frm['TUESDAY'] ) && $frm['TUESDAY'] != ''; + $noWorkingDays[3] = isset ( $frm['WEDNESDAY']) && $frm['WEDNESDAY'] != ''; + $noWorkingDays[4] = isset ( $frm['THURSDAY'] ) && $frm['THURSDAY'] != ''; + $noWorkingDays[5] = isset ( $frm['FRIDAY'] ) && $frm['FRIDAY'] != ''; + $noWorkingDays[6] = isset ( $frm['SATURDAY'] ) && $frm['SATURDAY'] != ''; + + $dbc = new DBConnection(); + $obj = new workPeriod( $dbc ); + $obj->Save ( $frm['initPeriod1'], $frm['endPeriod1'], $frm['initPeriod2'], $frm['endPeriod2'], $noWorkingDays ); + + print "ok"; + die; +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/conditions_Edit.php b/workflow/engine/methods/steps/conditions_Edit.php new file mode 100644 index 000000000..cf499c796 --- /dev/null +++ b/workflow/engine/methods/steps/conditions_Edit.php @@ -0,0 +1,50 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $aFields = $oStep->load($_GET['UID']); + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'steps/conditions_Edit', '', $aFields, '../steps/conditions_Save'); + G::RenderPage('publish-raw' , 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/conditions_Save.php b/workflow/engine/methods/steps/conditions_Save.php new file mode 100644 index 000000000..03123b503 --- /dev/null +++ b/workflow/engine/methods/steps/conditions_Save.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $oStep->update(array('STEP_UID' => $_POST['form']['STEP_UID'], 'STEP_CONDITION' => $_POST['form']['STEP_CONDITION'])); + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->getStepsCriteria($_POST['form']['TAS_UID']); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_Ajax.php b/workflow/engine/methods/steps/steps_Ajax.php new file mode 100644 index 000000000..281c399ef --- /dev/null +++ b/workflow/engine/methods/steps/steps_Ajax.php @@ -0,0 +1,182 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + require_once 'classes/model/StepTrigger.php'; + require_once 'classes/model/Triggers.php'; + G::LoadInclude('ajax'); + if (!empty($_GET)) { + $aData = urldecode_values($_GET); + } + else { + if (!isset($_POST['form'])) { + $aData = urldecode_values($_POST); + } + else { + $aData = urldecode_values($_POST['form']); + } + } + switch ($aData['action']) { + case 'showTriggers': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + if ($aData['sType'] == 'BEFORE') { + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'steps/triggersBefore_List', $oProcessMap->getStepTriggersCriteria($aData['sStep'], $_SESSION['TASK'], $aData['sType']), array('STEP' => $aData['sStep'])); + } + else { + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'steps/triggersAfter_List', $oProcessMap->getStepTriggersCriteria($aData['sStep'], $_SESSION['TASK'], $aData['sType']), array('STEP' => $aData['sStep'])); + } + G::RenderPage('publish-twocolumns', 'raw'); + break; + case 'availableTriggers': + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('TRI_UID'); + $oCriteria->add(StepTriggerPeer::TAS_UID , $_SESSION['TASK']); + $oCriteria->add(StepTriggerPeer::STEP_UID, $aData['sStep']); + $oCriteria->add(StepTriggerPeer::ST_TYPE , $aData['sType']); + $oDataset = StepTriggerPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $sUIDs = "'0'"; + $aUIDs = array(); + while ($aRow = $oDataset->getRow()) { + $sUIDs .= ",'" . $aRow['TRI_UID'] . "'"; + $aUIDs[] = $aRow['TRI_UID']; + $oDataset->next(); + } + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT(TRI_UID) AS CANTITY'); + $oCriteria->add(TriggersPeer::TRI_UID, $aUIDs, Criteria::NOT_IN); + $oCriteria->add(TriggersPeer::PRO_UID, $aData['sProcess']); + $oDataset = TriggersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if ((int)$aRow['CANTITY'] > 0) { + $aFields['LANG'] = SYS_LANG; + $aFields['UIDS'] = $sUIDs; + $aFields['PROCESS'] = $aData['sProcess']; + $aFields['action'] = 'assignTrigger'; + $aFields['STEP_UID'] = $aData['sStep']; + $aFields['ST_TYPE'] = $aData['sType']; + global $G_PUBLISH; + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'steps/triggers_Assign', '', $aFields, '../steps/steps_Ajax'); + G::RenderPage('publish', 'raw'); + } + else { + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'steps/triggers_NoAssign', ''); + G::RenderPage('publish', 'raw'); + } + break; + case 'assignTrigger': + $aFields = array('STEP_UID' => $aData['STEP_UID'], 'TAS_UID' => $_SESSION['TASK'], 'TRI_UID' => $aData['TRI_UID'], 'ST_TYPE' => $aData['ST_TYPE']); + $oStepTrigger = new StepTrigger(); + $oStepTrigger->create($aFields); + $aFields['ST_CONDITION'] = $aData['ST_CONDITION']; + $aFields['ST_POSITION'] = ($oStepTrigger->getNextPosition($aData['STEP_UID'], $aData['ST_TYPE']) - 1); + $oStepTrigger->update($aFields); + break; + case 'editTriggerCondition': + require_once 'classes/model/Step.php'; + require_once 'classes/model/Triggers.php'; + $oStep = new Step(); + + $aFields['STEP_UID'] = $aData['sStep']; + $aFields['TRI_UID'] = $aData['sTrigger']; + $aFields['ST_TYPE'] = $aData['sType']; + + $Trigger = new Triggers(); + $aRow = $Trigger->load($aData['sTrigger']); + + $oStepTrigger = new StepTrigger(); + $aFields = $oStepTrigger->load($aFields['STEP_UID'], $_SESSION['TASK'], $aFields['TRI_UID'], $aFields['ST_TYPE']); + $aFields['action'] = 'saveTriggerCondition'; + $aFields['PROCESS'] = $aRow['PRO_UID']; + global $G_PUBLISH; + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'steps/triggersCondition_Edit', '', $aFields, '../steps/steps_Ajax'); + G::RenderPage('publish', 'raw'); + break; + case 'saveTriggerCondition': + $oStepTrigger = new StepTrigger(); + $oStepTrigger->update(array('STEP_UID' => $aData['STEP_UID'], 'TAS_UID' => $_SESSION['TASK'], 'TRI_UID' => $aData['TRI_UID'], 'ST_TYPE' => $aData['ST_TYPE'], 'ST_CONDITION' => $aData['ST_CONDITION'])); + break; + case 'upTrigger': + $aData['iPosition'] = (int)$aData['iPosition']; + $oStepTrigger = new StepTrigger(); + $oStepTrigger->up($aData['sStep'], $_SESSION['TASK'], $aData['sTrigger'], $aData['sType'], $aData['iPosition']); + break; + case 'downTrigger': + $aData['iPosition'] = (int)$aData['iPosition']; + $oStepTrigger = new StepTrigger(); + $oStepTrigger->down($aData['sStep'], $_SESSION['TASK'], $aData['sTrigger'], $aData['sType'], $aData['iPosition']); + break; + case 'ofToAssignTrigger': + $oStepTrigger = new StepTrigger(); + $oStepTrigger->reOrder($aData['sStep'], $_SESSION['TASK'], $aData['sType'], $aData['iPosition']); + $oStepTrigger->remove($aData['sStep'], $_SESSION['TASK'], $aData['sTrigger'], $aData['sType']); + break; + + case 'counterTriggers': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oCriteria1 = $oProcessMap->getStepTriggersCriteria($aData['sStep'], $_SESSION['TASK'], $aData['sType']); + if ($aData['sType'] == 'BEFORE') { + $oCriteria2 = $oProcessMap->getStepTriggersCriteria($aData['sStep'], $_SESSION['TASK'], 'AFTER'); + } + else { + $oCriteria2 = $oProcessMap->getStepTriggersCriteria($aData['sStep'], $_SESSION['TASK'], 'BEFORE'); + } + $iCantity = StepTriggerPeer::doCount($oCriteria1); + $iTotal = $iCantity + StepTriggerPeer::doCount($oCriteria2); + echo $iTotal . '|' . $iCantity; + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_Delete.php b/workflow/engine/methods/steps/steps_Delete.php new file mode 100644 index 000000000..5ee58aba9 --- /dev/null +++ b/workflow/engine/methods/steps/steps_Delete.php @@ -0,0 +1,51 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $oStep->reOrder($_POST['STEP_UID'], $_POST['STEP_POSITION']); + $oStep->remove($_POST['STEP_UID']); + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->getStepsCriteria($_POST['TASK']); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_Down.php b/workflow/engine/methods/steps/steps_Down.php new file mode 100644 index 000000000..3d56bca7e --- /dev/null +++ b/workflow/engine/methods/steps/steps_Down.php @@ -0,0 +1,50 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $oStep->down($_POST['STEP_UID'], $_POST['TASK'] ,$_POST['STEP_POSITION']); + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->getStepsCriteria($_POST['TASK']); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_New.php b/workflow/engine/methods/steps/steps_New.php new file mode 100644 index 000000000..b88f410a5 --- /dev/null +++ b/workflow/engine/methods/steps/steps_New.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $G_PUBLISH = new Publisher(); + + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'steps/steps_availableBB', $oProcessMap->getAvailableBBCriteria($_GET['PROCESS'], $_GET['TASK']), $_GET); + G::RenderPage('publish-raw', 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_Save.php b/workflow/engine/methods/steps/steps_Save.php new file mode 100644 index 000000000..2ad3f912a --- /dev/null +++ b/workflow/engine/methods/steps/steps_Save.php @@ -0,0 +1,54 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $sStepUID = $oStep->create(array('PRO_UID' => $_POST['sProcess'], 'TAS_UID' => $_POST['sTask'])); + $oStep->update(array('STEP_UID' => $sStepUID, + 'STEP_TYPE_OBJ' => $_POST['sType'], + 'STEP_UID_OBJ' => $_POST['sUID'], + 'STEP_POSITION' => ($oStep->getNextPosition($_POST['sTask']) - 1), + 'STEP_MODE' => (isset($_POST['sMode'])) ? $_POST['sMode'] : 'EDIT')); + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->getStepsCriteria($_POST['sTask']); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_SupervisorAjax.php b/workflow/engine/methods/steps/steps_SupervisorAjax.php new file mode 100644 index 000000000..09be6c198 --- /dev/null +++ b/workflow/engine/methods/steps/steps_SupervisorAjax.php @@ -0,0 +1,70 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + //srequire_once 'classes/model/StepTrigger.php'; + + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + + switch ($_POST['action']) { + case 'availableSupervisorDynaforms': + $oProcessMap->availableSupervisorDynaforms($_POST['PRO_UID']); + break; + case 'assignSupervisorDynaform': + $oProcessMap->assignSupervisorStep($_POST['PRO_UID'], 'DYNAFORM', $_POST['DYN_UID']); + break; + case 'removeSupervisorDynaform': + $oProcessMap->removeSupervisorStep($_POST['STEP_UID'], $_POST['PRO_UID'], 'DYNAFORM', $_POST['DYN_UID'], $_POST['STEP_POSITION']); + break; + case 'availableSupervisorInputs': + $oProcessMap->availableSupervisorInputs($_POST['PRO_UID']); + break; + case 'assignSupervisorInput': + $oProcessMap->assignSupervisorStep($_POST['PRO_UID'], 'INPUT_DOCUMENT', $_POST['INP_DOC_UID']); + break; + case 'removeSupervisorInput': + $oProcessMap->removeSupervisorStep($_POST['STEP_UID'], $_POST['PRO_UID'], 'INPUT_DOCUMENT', $_POST['INP_DOC_UID'], $_POST['STEP_POSITION']); + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/steps/steps_Up.php b/workflow/engine/methods/steps/steps_Up.php new file mode 100644 index 000000000..5ef6e0d88 --- /dev/null +++ b/workflow/engine/methods/steps/steps_Up.php @@ -0,0 +1,50 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/Step.php'; + $oStep = new Step(); + $oStep->up($_POST['STEP_UID'], $_POST['TASK'] ,$_POST['STEP_POSITION']); + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->getStepsCriteria($_POST['TASK']); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/tasks/tasks_Ajax.php b/workflow/engine/methods/tasks/tasks_Ajax.php new file mode 100644 index 000000000..772b88c24 --- /dev/null +++ b/workflow/engine/methods/tasks/tasks_Ajax.php @@ -0,0 +1,88 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + $oJSON = new Services_JSON(); + + + $aData = get_object_vars($oJSON->decode($_POST['oData'])); + + switch ($_POST['function']) { + case 'saveTaskData': + require_once 'classes/model/Task.php'; + $oTask = new Task(); + + /* + * Fixed: October 22th, 2009 + * + * NOTE By Neyek + * This replacing is because the ampersand characters were replaced with JS routines for @amp@ + * this solve the problem when the task labels have a character & that cause that the url passed by POST or GET broke + * + * Involved lines: 52 to 58 + */ + + if( isset($aData['TAS_TITLE']) ){ + $aData['TAS_TITLE'] = str_replace('@amp@', '&', $aData['TAS_TITLE']); + } + + if( isset($aData['TAS_DESCRIPTION']) ){ + $aData['TAS_DESCRIPTION'] = str_replace('@amp@', '&', $aData['TAS_DESCRIPTION']); + } + + if (isset($aData['SEND_EMAIL'])) { + if( $aData['SEND_EMAIL'] == 'TRUE' ) { + $aData['TAS_SEND_LAST_EMAIL'] = 'TRUE'; + } else { + $aData['TAS_SEND_LAST_EMAIL'] = 'FALSE'; + } + } + else { + $aData['TAS_SEND_LAST_EMAIL'] = 'FALSE'; + } + //added by krlos + if( isset($aData['TAS_DEF_MESSAGE']) ){ + $aData['TAS_DEF_MESSAGE'] = str_replace('@amp@', '&', $aData['TAS_DEF_MESSAGE']); + } + $oTask->update($aData); + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/dvServices.php b/workflow/engine/methods/tools/dvServices.php new file mode 100755 index 000000000..264403ed6 --- /dev/null +++ b/workflow/engine/methods/tools/dvServices.php @@ -0,0 +1,83 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 11-02-2008 + * + * @author David Callizaya + */ +G::LoadSystem("webResource"); +class dvServices extends WebResource +{ + function get_session_vars() + { + $cur=array_keys($_SESSION); + $res=''; + foreach($cur as $key) + { + $res.='* '.$key.'
    '; + } + return $res; + } + function get_session_xmlforms() + { + $cur=array_keys($_SESSION); + $res=''; + $colors=array('white','#EEFFFF'); + $colori=0;$count=0; + //Get xmlforms in session + foreach($cur as $key) + { + $res.='
    '; + $xml=G::getUIDName($key,''); + if (strpos($xml,'.xml')!==false) + { + $res.='FORM: '.$xml; + $colori=$colori ^ 1; + $count++; + } + $res.='
    '; + } + //Get pagedTable in session + foreach($cur as $key) + { + $res.='
    '; + if (substr($key,0,11)==="pagedTable[") + { + $xml=G::getUIDName(substr($key,11,-1),''); + $res.='TABLE: '.$xml; + $colori=$colori ^ 1; + $count++; + } + $res.='
    '; + } + return array("count"=>$count,"html"=>$res); + } +} +$o=new dvServices($_SERVER['REQUEST_URI'],$_POST); +//av.buenos aires maxparedes +//tienda viva. +//122 + +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/index.php b/workflow/engine/methods/tools/index.php new file mode 100644 index 000000000..069b0449e --- /dev/null +++ b/workflow/engine/methods/tools/index.php @@ -0,0 +1,29 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + unset($_SESSION['TOOLS_VIEWTYPE']); + $newFile = str_replace ( 'index.php', 'translations.php' , __FILE__ ) ; + return $newFile; + + \ No newline at end of file diff --git a/workflow/engine/methods/tools/methodsPermissions.php b/workflow/engine/methods/tools/methodsPermissions.php new file mode 100644 index 000000000..abb9b5cc7 --- /dev/null +++ b/workflow/engine/methods/tools/methodsPermissions.php @@ -0,0 +1,31 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'tools/methodsPermissions' ); + + G::RenderPage( 'publish' ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/methodsPermissions_Ajax.php b/workflow/engine/methods/tools/methodsPermissions_Ajax.php new file mode 100644 index 000000000..35c41478a --- /dev/null +++ b/workflow/engine/methods/tools/methodsPermissions_Ajax.php @@ -0,0 +1,287 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + G::LoadClass("webResource"); + define('GET_PERMISSION_REG_EXP','/(G::\\s*genericForceLogin\\s*\\(\\s*[\'"])(\\w+)([\'"]\\s*,\\s*[\'"].+[\'"],.+\\)\\s*)|(\\$RBAC->userCanAccess\\s*\\(\\s*[\'"])(\\w+)([\'"]\\s*\\))/i'); + define('GET_PERMISSION_REG_EXP2','/\\s*if\\s*\\(\\s*\\(\\s*\\$RBAC_Response\\s*=\\s*\\$RBAC->userCanAccess\\s*\\(\\s*[\'"]\\w+[\'"]\\s*\\)\\s*\\)\\s*!=1\\s*\\)\\s*return(?:.*)?;\\s*/i'); + class phpFile extends webResource + { + function _get_permissions($filename) + { + $aSource = file( $filename); + $aOutSource = array(); + $source = implode( '', $aSource ); + $regExp=GET_PERMISSION_REG_EXP; + $permissions=array(); + $lines=array(); + $len=preg_match_all($regExp,$source,$matches,PREG_OFFSET_CAPTURE); + for($r=0; $r < $len; $r++) + { + $match=$matches[0][$r][0]; + $permission=($matches[2][$r][0]!='') ? $matches[2][$r][0]:$matches[5][$r][0]; + $toPrint=($matches[2][$r][0]!='') ? + ( + htmlentities($matches[1][$r][0],ENT_QUOTES,'utf-8'). + ''.htmlentities($matches[2][$r][0],ENT_QUOTES,'utf-8').''. + htmlentities($matches[3][$r][0],ENT_QUOTES,'utf-8') + ) + : + ( + htmlentities($matches[4][$r][0],ENT_QUOTES,'utf-8'). + ''.htmlentities($matches[5][$r][0],ENT_QUOTES,'utf-8').''. + htmlentities($matches[6][$r][0],ENT_QUOTES,'utf-8') + ); + $row = $this->_getLine($aSource,$matches[0][$r][1]); + if (array_search($permission,$permissions)===FALSE) + { + $permissions[]=$permission; + $lines[]=$row; + } + //TODO: Need to htmlencode the rest of the line that is not in match. Ex. < ? php + if ($row>0) $aOutSource[$row-1]=str_replace($match,$toPrint,isset($aOutSource[$row-1])?$aOutSource[$row-1]:$aSource[$row-1]); + $aOutSource[$row]=str_replace($match,$toPrint,isset($aOutSource[$row])?$aOutSource[$row]:$aSource[$row]); + if ($row<(sizeof($aSource)-1)) $aOutSource[$row+1]=str_replace($match,$toPrint,isset($aOutSource[$row+1])?$aOutSource[$row+1]:$aSource[$row+1]); + } + ksort($aOutSource); + $row0=0;$html=''; + foreach($aOutSource as $row => $line) + { + if (($row-1) > $row0) $html.=$this->_printLine($row,'...'); + $html.=$this->_printLine($row+1,$line,true,$aSource[$row],$filename.'?'.$row); + $row0=$row; + } + return array ( + ($html==='')?'Dont have RBAC validation!':(''.$html.'
    '), + $permissions, + $lines + ); + } + function get_permissions($filename) + { + $res=$this->_get_permissions($filename); + return $res[0]; + } + function modify_line($filename,$row,$value) + { + $aSource = file( $filename); + $line=$aSource[$row]; + $nl=(strlen($line)>=2)&&(substr($line,-2,2)=="\r\n")? + "\r\n": + ((strlen($line)>=1)&&(substr($line,-1,1)=="\n")?"\n":""); + $aSource[$row]=$value.$nl; + /*Save change*/ + $fp=fopen($filename,'w'); + fwrite($fp,implode('',$aSource)); + fclose($fp); + /*Format line*/ + $regExp=GET_PERMISSION_REG_EXP; + $line=$aSource[$row]; + $len=preg_match_all($regExp,$line,$matches,PREG_OFFSET_CAPTURE); + for($r=0; $r < $len; $r++) + { + $match=$matches[0][$r][0]; + $toPrint=($matches[2][$r][0]!='') ? + ( + htmlentities($matches[1][$r][0],ENT_QUOTES,'utf-8'). + ''.htmlentities($matches[2][$r][0],ENT_QUOTES,'utf-8').''. + htmlentities($matches[3][$r][0],ENT_QUOTES,'utf-8') + ) + : + ( + htmlentities($matches[4][$r][0],ENT_QUOTES,'utf-8'). + ''.htmlentities($matches[5][$r][0],ENT_QUOTES,'utf-8').''. + htmlentities($matches[6][$r][0],ENT_QUOTES,'utf-8') + ); + $line=str_replace($match,$toPrint,$line); + } + return array($line,$aSource[$row]); + } + function set_header($filename,$value) + { + $aFields=array("_FILENAME_"=>basename( $filename ) ); + $value = G::replaceDataField( $value , $aFields ); + $aOrigin = file( $filename); + //It suposse that allway start with =2)&&(substr($line,-2,2)=="\r\n")? + "\r\n": + ((strlen($line)>=1)&&(substr($line,-1,1)=="\n")?"\n":""); + + $codigo = implode('',$aOrigin); + $pattern='/\/\*[\w\W]+\* '.'ProcessMaker Open Source'.'[\w\W]+?\*\//i'; + if (preg_match($pattern,$codigo)) + { + $codigo=preg_replace( $pattern, $value , $codigo ); + } + else + { + $aSource=array(); + $aSource[0]=$aOrigin[0]; + $aSource[1]=$value.$nl; + for($r=1;$rget_permissions($filename); + } + function add_permission($filename,$value) + { + $aOrigin = file( $filename); + //It suposse that allway start with =2)&&(substr($line,-2,2)=="\r\n")? + "\r\n": + ((strlen($line)>=1)&&(substr($line,-1,1)=="\n")?"\n":""); + $aSource[1]=$value.$nl; + for($r=1;$rget_permissions($filename); + } + function _getLine(&$aSource,$pos) + { + $i=1; + while ($pos>sizeof($aSource[$i])) + { + $pos-=strlen($aSource[$i]); + $i++; + } + return $i-1; + } + function _printLine($row,$txt,$editable=false,$editValue='',$name='') + { + if ($editable) + { + return ''. + ''.$row.' + '. + $txt.''. + ''; + } + else + { + return ''. + ''.$row.''. + ''.$txt.''; + } + } + function set_permission($filename,$permission) + { + list($html,$permissions)=$this->_get_permissions($filename); + if (array_search($permission,$permissions)===FALSE) + { + $this->add_permission + ( + $filename, + 'if (($RBAC_Response=$RBAC->userCanAccess("'.$permission.'"))!=1) return $RBAC_Response;' + ); + } + return $this->get_permissions($filename); + } + function set_path_permission($path,$permission) + { + $files=glob($path.'*.php'); + foreach($files as $file) + { + $this->set_permission($file,$permission); + } + } + function set_path_header($path,$header) + { + $files=glob($path.'*.php'); + $filesMod=array(); + foreach($files as $file) + { + $filesMod[]=$file; + $this->set_header($file,$header); + } + $dirs=glob($path.'*', GLOB_MARK ); + foreach($dirs as $dir) + { + if (substr( $dir , -1 , 1 )=='/') $this->set_path_header($dir,$header); + } + return $filesMod; + } + function remove_path_permission($path,$permission) + { + $files=glob($path.'*.php'); + foreach($files as $file) + { + $this->remove_permission($file,$permission); + } + } + function remove_line($filename,$line) + { + $aSource = file($filename); + unset($aSource[$line]); + /*Save change*/ + $fp=fopen($filename,'w'); + fwrite($fp,implode('',$aSource)); + fclose($fp); + return $this->get_permissions($filename); + } + function remove_permission($filename,$permission) + { + $aSource = file( $filename); + list($html,$permissions,$lines) = $this->_get_permissions($filename); + if (($row=array_search($permission,$permissions))!==FALSE) + { + $line=$lines[$row]; + if (preg_match(GET_PERMISSION_REG_EXP2,$aSource[$line])) + { + unset($aSource[$line]); + $msg="Removed."; + } + else + { + $msg="Can not be removed!"; + } + } + /*Save change*/ + $fp=fopen($filename,'w'); + fwrite($fp,implode('',$aSource)); + fclose($fp); + return $this->get_permissions($filename); + } + } + $phpFile=new phpFile('methodsPermissions_Ajax',$_POST); +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/translations.php b/workflow/engine/methods/tools/translations.php new file mode 100644 index 000000000..9e4dc2ed1 --- /dev/null +++ b/workflow/engine/methods/tools/translations.php @@ -0,0 +1,45 @@ + +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $G_MAIN_MENU = 'tools'; + $G_SUB_MENU = 'toolsTranslations'; + $G_ID_MENU_SELECTED = 'TRANSLATION'; + $G_ID_SUB_MENU_SELECTED = 'TRANSLATION_LIST'; + + $table="TRANSLATION"; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('pagedtable', 'paged-table', 'tools/translationsList', '', array() , ''); + if( isset($_SESSION['TOOLS_VIEWTYPE']) ) { + G::RenderPage('publishBlank', 'green-submenu'); + } else { + G::RenderPage('publish'); + } + diff --git a/workflow/engine/methods/tools/translationsAdd.php b/workflow/engine/methods/tools/translationsAdd.php new file mode 100644 index 000000000..925bb86bd --- /dev/null +++ b/workflow/engine/methods/tools/translationsAdd.php @@ -0,0 +1,38 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $G_MAIN_MENU = 'tools'; + $G_SUB_MENU = 'toolsTranslations'; + $G_ID_MENU_SELECTED = 'TRANSLATION'; + $G_ID_SUB_MENU_SELECTED = 'TRANSLATION_ADD'; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tools/translationAdd', '', null, 'translationsSave' ); + + if( isset($_SESSION['TOOLS_VIEWTYPE']) && $_SESSION['TOOLS_VIEWTYPE'] == 'blank') { + G::RenderPage('publishBlank', 'green-submenu'); + } else { + G::RenderPage('publish'); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/translationsAjax.php b/workflow/engine/methods/tools/translationsAjax.php new file mode 100644 index 000000000..7a921b1fa --- /dev/null +++ b/workflow/engine/methods/tools/translationsAjax.php @@ -0,0 +1,217 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + ini_set('display_errors','off'); + G::LoadInclude('ajax'); + $function = get_ajax_value('function'); + $cat = get_ajax_value('cat'); + $node = get_ajax_value('node'); + $lang = get_ajax_value('lang'); + $langLabel = get_ajax_value('langLabel'); + $text = get_ajax_value('text'); + $table="TRANSLATION"; + $dbc = new DBConnection; + $ses = new DBSession($dbc); +switch($function) +{ + case "editLabel": + case "changeLabel": + $query=$ses->execute("select * from $table where TRN_CATEGORY='$cat' and TRN_ID='$node' and TRN_LANG='$lang'",false); + if ($query->count()===0) {echo("Not found $cat:$node:$lang in table '$table'");return;} + if ($query->count()>1) {echo("The $cat:$node:$lang in table '$table' is not unique");return;} + $res=$query->read(); + switch($function) + { + case "editLabel": + $myID="input_".$cat."_".$node."_".$lang; + $myID='aux'; + echo(""); + break; + case "changeLabel": + $update=$ses->execute("update $table set TRN_VALUE='$langLabel' where TRN_CATEGORY='$cat' and TRN_ID='$node' and TRN_LANG='$lang'",false); + $query=$ses->execute("select * from $table where TRN_CATEGORY='$cat' and TRN_ID='$node' and TRN_LANG='$lang'",false); + if ($query->count()===0) {echo("Not found $cat:$node:$lang in table '$table'");return;} + if ($query->count()>1) {echo("The $cat:$node:$lang in table '$table' is not unique");return;} + $res=$query->read(); + echo(htmlspecialchars($res['TRN_VALUE'])); + break; + break; + } + G::LoadClass( "translation" ); + + $dbc = new DBConnection; + $obj = new Translation; + $obj->SetTo($dbc ); + $translation2 = $obj->generateFileTranslation(); + break; + case "listLanguage": + $query=$ses->execute("select distinct TRN_LANG from $table",false); + $template = new TemplatePower(PATH_CORE . 'templates/tools/translationsTP.html'); + $template->prepare(); + $template->newBlock("languageList"); + $template->assign("ajaxDelLang",ajax_event("onclick","translationsAjax","showSpace", + "'function=delLanguage&lang='+encodeURI(getElementById('language').value)",'hideLangBar')); + + for($r=1;$r<=$query->count();$r++) + { + $res=$query->read(); + $template->newBlock("languageItem"); + $template->assign("langIdRadio",$res['TRN_LANG']); + } + $template->printToScreen(); + break; + case "show": + case "search": + case "addField": + case "addLanguage": + case "delLanguage": + case "delField": + switch($function) + { + case "show": + $query=$ses->execute("select * from $table ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + case "search": + $query=$ses->execute("select * from $table where (TRN_CATEGORY like '%$text%') or (TRN_ID like '%$text%') or (TRN_LANG like '%$text%') or (TRN_VALUE like '%$text%') ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + case "addField": + if (!defined('LANGUAGES')) define('LANGUAGES',SYS_LANG); + $languages=explode(",",LANGUAGES); + foreach($languages as $lang) + { + //$langLabel=$cat; +/* $update=$ses->execute("insert into $table(TRN_CATEGORY , TRN_ID , TRN_LANG , TRN_VALUE ) + values ('$cat','$node','$lang','$langLabel')",false);*/ + $update=$ses->execute("insert into $table(TRN_CATEGORY , TRN_ID , TRN_LANG , TRN_VALUE ) + values ('LABEL','$node','$lang','$langLabel')",false); + } + $query=$ses->execute("select * from $table ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + case "addLanguage": +//SELECT distinct TRN_CATEGORY, TRN_ID, 'ne', 'new value' FROM TRANSLATION WHERE TRN_LANG<>'ne' +//INSERT INTO TRANSLATION(TRN_CATEGORY, TRN_ID, TRN_LANG , TRN_VALUE ) SELECT distinct TRN_CATEGORY, TRN_ID, 'ne', TRN_VALUE FROM TRANSLATION WHERE TRN_LANG<>'ne' + $query1=$ses->execute("select * from $table where TRN_LANG='$lang'",false); + $query2=$ses->execute("select distinct TRN_CATEGORY, TRN_ID from $table",false); + $existe=array(); + for($r=1;$r<=$query1->count();$r++) + { + $res=$query1->read(); + $existe[$res['TRN_CATEGORY']."_".$res['TRN_ID']]=$res; + } + for($r=1;$r<=$query2->count();$r++) + { + $res=$query2->read(); + $cat=$res['TRN_CATEGORY']; + $node=$res['TRN_ID']; + $langLabel=$res['TRN_CATEGORY']; + if (!array_key_exists($cat."_".$node,$existe)) +/* $update=$ses->execute("insert into $table(TRN_CATEGORY , TRN_ID , TRN_LANG , TRN_VALUE ) + values ('$cat','$node','$lang','$langLabel')",false);*/ + $update=$ses->execute("insert into $table(TRN_CATEGORY , TRN_ID , TRN_LANG , TRN_VALUE ) + values ('LABELS','$node','en','$langLabel')",false); + unset($update); + } + unset($existe); + unset($query1);unset($query2); + $query=$ses->execute("select * from $table ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + case "delLanguage": + $update=$ses->execute("delete from $table where TRN_LANG='$lang'",false); + $query=$ses->execute("select * from $table ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + case "delField": + $update=$ses->execute("delete from $table where TRN_CATEGORY='$cat' and TRN_ID='$node' and TRN_LANG='$lang'",false); + //echo("delete from $table where TRN_CATEGORY='$cat' and TRN_ID='$node' and TRN_LANG='$lang'"); + $query=$ses->execute("select * from $table ORDER BY TRN_CATEGORY ASC , TRN_ID ASC , TRN_LANG ASC ",false); + break; + } + $template = new TemplatePower(PATH_CORE . 'templates/tools/translationsTP.html'); + $template->prepare(); + $template->newBlock("CONTENT"); + $template->newBlock("table"); + $aCat="";$aNode=""; + for($i=1;$i<=$query->count();$i++) + { + $template->newBlock("row"); + $res=$query->read(); + $cat=$res['TRN_CATEGORY']; + $node=$res['TRN_ID']; + $lang=$res['TRN_LANG']; + $langLabel=$res['TRN_VALUE']; + if ($cat!=$aCat) + { + $template->newBlock("TDcat"); + $template->assign("catId",$res['TRN_CATEGORY']); + $template->assign("ajaxDelField", + ajax_event('onclick','translationsAjax','showSpace', + "'function=delField". + "&cat=".urlencode($cat). + "&node=".urlencode($node). + "&lang=".urlencode($lang)."'",'')); + } + if (($cat!=$aCat) || + ($node!=$aNode)) + { + $template->newBlock("TDnode"); + $template->assign("nodeId",$res['TRN_ID']); + } + //$aCat=$cat; + //$aNode=$node; + $template->goToBlock("row"); + $template->assign("catId",$res['TRN_CATEGORY']); + $template->assign("nodeId",$res['TRN_ID']); + $template->assign("langId",$lang); + $template->assign("langLabel",$langLabel); + $template->assign("ajaxLabel","onclick=\"if (!document.getElementById('aux'))". + ajax_init('translationsAjax.php', + 'lang_'.$cat.'_'.$node.'_'.$lang, + "'function=editLabel". + "&cat=".urlencode($cat). + "&node=".urlencode($node). + "&lang=".urlencode($lang)."'",'focusInputLabel') + .'"'); + } + $template->printToScreen(); + break; +} +?> + diff --git a/workflow/engine/methods/tools/translationsDelete.php b/workflow/engine/methods/tools/translationsDelete.php new file mode 100644 index 000000000..c0501df5a --- /dev/null +++ b/workflow/engine/methods/tools/translationsDelete.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //to do: improve the way to pass two or more parameters in the paged-table ( link ) + + $aux = explode ( '|', $_GET['id'] ); + $category = str_replace ( '"', '', $aux[0] ); + $id = str_replace ( '"', '', $aux[1] ); + + + require_once ( "classes/model/Translation.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = TranslationPeer::retrieveByPK( $category, $id, 'en' ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'Translation' ) ) { + $tr->delete(); + } +// else + + G::Header('location: translations'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/translationsEdit.php b/workflow/engine/methods/tools/translationsEdit.php new file mode 100644 index 000000000..0480765d1 --- /dev/null +++ b/workflow/engine/methods/tools/translationsEdit.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //to do: improve the way to pass two or more parameters in the paged-table ( link ) + + $aux = explode ( '|', $_GET['id'] ); + $category = str_replace ( '"', '', $aux[0] ); + $id = str_replace ( '"', '', $aux[1] ); + + + require_once ( "classes/model/Translation.php" ); + //if exists the row in the database propel will update it, otherwise will insert. + $tr = TranslationPeer::retrieveByPK( $category, $id, 'en' ); + + if ( ( is_object ( $tr ) && get_class ($tr) == 'Translation' ) ) { + $fields['trn_category'] = $tr->getTrnCategory(); + $fields['trn_id'] = $tr->getTrnId(); + $fields['trn_value'] = $tr->getTrnValue(); + } + else + $fields = array(); + + $G_MAIN_MENU = 'tools'; + $G_SUB_MENU = 'toolsTranslations'; + $G_ID_MENU_SELECTED = 'TOOLS'; + $G_ID_SUB_MENU_SELECTED = 'ADD_TRANSLATION'; + + $G_PUBLISH = new Publisher; + $dbc = new DBConnection; + $ses = new DBSession($dbc); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tools/translationAdd', '', $fields, 'translationsSave' ); + if( isset($_SESSION['TOOLS_VIEWTYPE']) && $_SESSION['TOOLS_VIEWTYPE'] == 'blank') { + G::RenderPage('publishBlank', 'green-submenu'); + } else { + G::RenderPage('publish'); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/translationsSave.php b/workflow/engine/methods/tools/translationsSave.php new file mode 100644 index 000000000..caedd99e4 --- /dev/null +++ b/workflow/engine/methods/tools/translationsSave.php @@ -0,0 +1,36 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $form = $_POST['form']; + require_once ( "classes/model/Translation.php" ); + $form['trn_value'] = preg_replace("[\n|\r|\n\r]", ' ', $form['trn_value']); + + //$t = new Translation; + $res = Translation::addTranslation( $form['trn_category'], $form['trn_id'], 'en' , $form['trn_value'] ); + if ( $res['codError'] < 0 ) { + G::SendMessageText ( $res['message'] , 'error' ); + } + G::Header('location: translations'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/tools/updateTranslation.php b/workflow/engine/methods/tools/updateTranslation.php new file mode 100644 index 000000000..98be99214 --- /dev/null +++ b/workflow/engine/methods/tools/updateTranslation.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + require_once ( "classes/model/Translation.php" ); + + $t = new Translation; + $fields = Translation::generateFileTranslation('en'); + + $G_MAIN_MENU = 'tools'; + $G_SUB_MENU = 'toolsTranslations'; + $G_ID_MENU_SELECTED = 'TRANSLATION'; + $G_ID_SUB_MENU_SELECTED = 'TRANSLATION_REBUILD'; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tools/updateTranslation', '', $fields); + if( isset($_SESSION['TOOLS_VIEWTYPE']) && $_SESSION['TOOLS_VIEWTYPE'] == 'blank') { + G::RenderPage('publishBlank', 'green-submenu'); + } else { + G::RenderPage('publish'); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/authentication.php b/workflow/engine/methods/tracker/authentication.php new file mode 100644 index 000000000..39ecabf6a --- /dev/null +++ b/workflow/engine/methods/tracker/authentication.php @@ -0,0 +1,130 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + /* + * Authentication for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + + + if (!isset($_POST['form']) ) { + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); + G::header ("location: login.php");die; + } + + +try { + $frm = $_POST['form']; + $case = ''; + $pin = ''; + + if (isset($frm['CASE'])) { + $case = strtolower(trim($frm['CASE'])); + $pin = trim($frm['PIN']); + } + + G::LoadClass('case'); + $oCase = new Cases(); + + $uid = $oCase->verifyCaseTracker($case, $pin); + //print_r($uid); die; + switch ($uid) { + //The case not exists + case -1: + G::SendTemporalMessage ('ID_CASE_NOT_EXISTS', "error"); + break; + //The pin is invalid + case -2: + G::SendTemporalMessage ('ID_PIN_INVALID', "error"); + break; + } + + if ($uid < 0 ) { + G::header ("location: login.php"); + die; + } + + if(is_array($uid)) + { + require_once ("classes/model/CaseTracker.php"); + require_once ("classes/model/CaseTrackerObject.php"); + $_SESSION['CASE']=$case; + $_SESSION['PIN']=$pin; + $_SESSION['PROCESS']=$uid['PRO_UID']; + $_SESSION['APPLICATION']=$uid['APP_UID']; + $_SESSION['TASK']=-1; + $_SESSION['INDEX']=-1; + $a=0; + $b=0; + $c=0; + $oCriteria = new Criteria(); + $oCriteria->add(CaseTrackerPeer::PRO_UID, $_SESSION['PROCESS']); + $oCaseTracker = new CaseTracker(); + if (CaseTrackerPeer::doCount($oCriteria) === 0) { + $aCaseTracker = array('PRO_UID' => $_SESSION['PROCESS'], + 'CT_MAP_TYPE' => 'PROCESSMAP', + 'CT_DERIVATION_HISTORY' => 1, + 'CT_MESSAGE_HISTORY' => 1); + $oCaseTracker->create($aCaseTracker); + } + else { + $aCaseTracker = $oCaseTracker->load($_SESSION['PROCESS']); + } + + if(is_array($aCaseTracker)) + { if($aCaseTracker['CT_MAP_TYPE']!='NONE') + { $a=1; + G::header ('location: tracker_ViewMap'); + die; + } + + $oCriteria = new Criteria(); + $oCriteria->add(CaseTrackerObjectPeer::PRO_UID, $_SESSION['PROCESS']); + if (CaseTrackerObjectPeer::doCount($oCriteria) > 0) + { $b=1; + G::header ("location: tracker_DynaDocs"); + die; + } + + if($aCaseTracker['CT_DERIVATION_HISTORY']==1) + { $c=1; + G::header ("location: tracker_History"); + die; + } + + G::header ("location: tracker_No"); + } + } + +} + +catch ( Exception $e ) { + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; +} \ No newline at end of file diff --git a/workflow/engine/methods/tracker/login.php b/workflow/engine/methods/tracker/login.php new file mode 100644 index 000000000..2bb6283ac --- /dev/null +++ b/workflow/engine/methods/tracker/login.php @@ -0,0 +1,45 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * Login for authentication of Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + + +$G_PUBLISH = new Publisher; +//echo G::generateUniqueNumber(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/login', '', '', SYS_URI.'tracker/authentication.php'); + +G::RenderPage( "publish" ); +session_destroy(); +session_start(); + + + + + \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_Ajax.php b/workflow/engine/methods/tracker/tracker_Ajax.php new file mode 100644 index 000000000..6b699a788 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_Ajax.php @@ -0,0 +1,427 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + if (isset($_POST['form']['action'])) { + $_POST['action'] = $_POST['form']['action']; + } + switch ($_POST['action']) { + case 'availableCaseTrackerObjects': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->availableCaseTrackerObjects($_POST['PRO_UID']); + break; + case 'assignCaseTrackerObject': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->assignCaseTrackerObject($_POST['PRO_UID'], $_POST['OBJECT_TYPE'], $_POST['OBJECT_UID']); + $oProcessMap->getCaseTrackerObjectsCriteria($_POST['PRO_UID']); + break; + case 'removeCaseTrackerObject': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->removeCaseTrackerObject($_POST['CTO_UID'], $_POST['PRO_UID'], $_POST['STEP_POSITION']); + $oProcessMap->getCaseTrackerObjectsCriteria($_POST['PRO_UID']); + break; + case 'upCaseTrackerObject': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->upCaseTrackerObject($_POST['CTO_UID'], $_POST['PRO_UID'], $_POST['STEP_POSITION']); + $oProcessMap->getCaseTrackerObjectsCriteria($_POST['PRO_UID']); + break; + case 'downCaseTrackerObject': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + $oProcessMap->downCaseTrackerObject($_POST['CTO_UID'], $_POST['PRO_UID'], $_POST['STEP_POSITION']); + $oProcessMap->getCaseTrackerObjectsCriteria($_POST['PRO_UID']); + break; + case 'editStagesMap': + $oTemplatePower = new TemplatePower(PATH_TPL . 'tracker/stages_Map.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + var pb=leimnud.dom.capture("tag.body 0"); + Sm=new stagesmap(); + Sm.options = { + target : "sm_target", + dataServer: "../tracker/tracker_Ajax", + uid : "' . $_POST['PRO_UID'] . '", + lang : "' . SYS_LANG . '", + theme : "processmaker", + size : {w:"780",h:"540"}, + images_dir: "/jscore/processmap/core/images/", + rw : true, + hideMenu : false + }; + Sm.make();'); + G::RenderPage('publish', 'raw'); + break; + case 'showUploadedDocumentTracker': + require_once 'classes/model/AppDocument.php'; + require_once 'classes/model/AppDelegation.php'; + require_once 'classes/model/InputDocument.php'; + require_once 'classes/model/Users.php'; + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_POST['APP_DOC_UID']); + + $oInputDocument = new InputDocument(); + if ($oAppDocument->Fields['DOC_UID'] != -1) { + $Fields = $oInputDocument->load($oAppDocument->Fields['DOC_UID']); + } + else { + $Fields = array('INP_DOC_FORM_NEEDED' => '', 'FILENAME' => $oAppDocument->Fields['APP_DOC_FILENAME']); + } + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::DEL_INDEX, $oAppDocument->Fields['DEL_INDEX']); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $oTask = new Task(); + $aTask = $oTask->load($aRow['TAS_UID']); + $Fields['ORIGIN'] = $aTask['TAS_TITLE']; + $oUser = new Users(); + $aUser = $oUser->load($oAppDocument->Fields['USR_UID']); + $Fields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + switch ($Fields['INP_DOC_FORM_NEEDED']) + { + case 'REAL': + $sXmlForm = 'tracker/tracker_ViewAnyInputDocument2'; + break; + case 'VIRTUAL': + $sXmlForm = 'tracker/tracker_ViewAnyInputDocument1'; + break; + case 'VREAL': + $sXmlForm = 'tracker/tracker_ViewAnyInputDocument3'; + break; + default: + $sXmlForm = 'tracker/tracker_ViewAnyInputDocument'; + break; + } + $oAppDocument->Fields['VIEW'] = G::LoadTranslation('ID_OPEN'); + $oAppDocument->Fields['FILE'] = 'tracker_ShowDocument?a=' . $_POST['APP_DOC_UID'] . '&r=' . rand(); + + //If plugin and trigger are defined for listing + if ( $oPluginRegistry->existsTrigger ( PM_CASE_DOCUMENT_LIST_ARR ) ) { + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $filesPluginArray=$oPluginRegistry->executeTriggers ( PM_CASE_DOCUMENT_LIST_ARR , $_SESSION['APPLICATION'] ); + //Now search for the file, if exists the change the download URL + foreach($filesPluginArray as $file){ + if($file->filename==$_POST['APP_DOC_UID']){ + $oAppDocument->Fields['FILE'] = $file->downloadScript; + } + } + } + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', $sXmlForm, '', G::array_merges($Fields, $oAppDocument->Fields), ''); + G::RenderPage('publish', 'raw'); + break; + case 'showGeneratedDocumentTracker': + require_once 'classes/model/AppDocument.php'; + require_once 'classes/model/AppDelegation.php'; + $oAppDocument = new AppDocument(); + $aFields = $oAppDocument->load($_POST['APP_DOC_UID']); + require_once 'classes/model/OutputDocument.php'; + $oOutputDocument = new OutputDocument(); + $aOD = $oOutputDocument->load($aFields['DOC_UID']); + + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::DEL_INDEX, $aFields['DEL_INDEX']); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + $oTask = new Task(); + $aTask = $oTask->load($aRow['TAS_UID']); + $aFields['ORIGIN'] = $aTask['TAS_TITLE']; + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $aUser = $oUser->load($aFields['USR_UID']); + $aFields['CREATOR'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + $aFields['VIEW'] = G::LoadTranslation('ID_OPEN'); + $aFields['FILE1'] = 'tracker_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=doc&random=' . rand(); + $aFields['FILE2'] = 'tracker_ShowOutputDocument?a=' . $aFields['APP_DOC_UID'] . '&ext=pdf&random=' . rand(); + + + //If plugin and trigger are defined for listing + if ( $oPluginRegistry->existsTrigger ( PM_CASE_DOCUMENT_LIST_ARR ) ) { + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $filesPluginArray=$oPluginRegistry->executeTriggers ( PM_CASE_DOCUMENT_LIST_ARR , $aFields['APP_UID'] ); + //Now search for the file, if exists the change the download URL + foreach($filesPluginArray as $file){ + if($file->filename==$_POST['APP_DOC_UID']){ + $aFields['FILE2'] = $file->downloadScript;// The PDF is the only one uploaded to KT + } + } + } + + + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/tracker_ViewAnyOutputDocument', '', G::array_merges($aOD, $aFields), ''); + G::RenderPage('publish', 'raw'); + break; + case 'load': + $oConnection = Propel::getConnection('workflow'); + $oStatement = $oConnection->prepareStatement("CREATE TABLE IF NOT EXISTS `STAGE` ( + `STG_UID` VARCHAR( 32 ) NOT NULL , + `PRO_UID` VARCHAR( 32 ) NOT NULL , + `STG_POSX` INT( 11 ) NOT NULL DEFAULT '0', + `STG_POSY` INT( 11 ) NOT NULL DEFAULT '0', + `STG_INDEX` INT( 11 ) NOT NULL DEFAULT '0', + PRIMARY KEY ( `STG_UID` ) + );"); + $oStatement->executeQuery(); + /***************************************************************************************************************/ + require_once 'classes/model/Stage.php'; + require_once 'classes/model/Process.php'; + require_once 'classes/model/Task.php'; + require_once 'classes/model/AppDelegation.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oProcess = new Process(); + $aRow = $oProcess->load($oData->uid); + $oSM->title->label = strip_tags($aRow['PRO_TITLE']); + //$oSM->title->position->x = $aRow['PRO_TITLE_X']; + //$oSM->title->position->y = $aRow['PRO_TITLE_Y']; + $oSM->title->position->x = 10; + $oSM->title->position->y = 10; + $oSM->stages = array(); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(StagePeer::STG_UID); + $oCriteria->addSelectColumn(ContentPeer::CON_VALUE); + $oCriteria->addSelectColumn(StagePeer::STG_POSX); + $oCriteria->addSelectColumn(StagePeer::STG_POSY); + $aConditions = array(); + $aConditions[] = array(0 => StagePeer::STG_UID, 1 => ContentPeer::CON_ID); + $aConditions[] = array(0 => ContentPeer::CON_CATEGORY, 1 => DBAdapter::getStringDelimiter() . 'STG_TITLE' . DBAdapter::getStringDelimiter()); + $aConditions[] = array(0 => ContentPeer::CON_LANG, 1 => DBAdapter::getStringDelimiter() . SYS_LANG . DBAdapter::getStringDelimiter()); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(StagePeer::PRO_UID, $oData->uid); + $oCriteria->addAscendingOrderByColumn(StagePeer::STG_INDEX); + $oDataset = StagePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow1 = $oDataset->getRow()) { + $oStage = null; + $oStage->uid = $aRow1['STG_UID']; + $oStage->label = strip_tags($aRow1['CON_VALUE']); + $oStage->position->x = (int)$aRow1['STG_POSX']; + $oStage->position->y = (int)$aRow1['STG_POSY']; + $oStage->derivation = null; + $oStage->derivation->to = array(); + if (!$oData->mode) { + $oCriteria = new Criteria('workflow'); + $oCriteria->add(TaskPeer::STG_UID, $aRow1['STG_UID']); + $oDataset1 = TaskPeer::doSelectRS($oCriteria); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aTasks = array(); + while ($aRow2 = $oDataset1->getRow()) { + $aTasks[] = $aRow2['TAS_UID']; + $oDataset1->next(); + } + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDelegationPeer::APP_UID, $_SESSION['APPLICATION']); + $oCriteria->add(AppDelegationPeer::TAS_UID, $aTasks, Criteria::IN); + $oCriteria->add($oCriteria->getNewCriterion(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL)->addOr($oCriteria->getNewCriterion(AppDelegationPeer::DEL_FINISH_DATE, ''))); + if (AppDelegationPeer::doCount($oCriteria) > 0) { + $oStage->color = '#FF0000'; + } + } + $oSM->stages[] = $oStage; + $oDataset->next(); + } + foreach ($oSM->stages as $iKey => $oStage) { + if (isset($oSM->stages[$iKey + 1])) { + $oDerivation = new StdClass(); + $oDerivation->stage = $oSM->stages[$iKey + 1]->uid; + $oSM->stages[$iKey]->derivation->to = array($oDerivation); + $oSM->stages[$iKey]->derivation->type = 0; + } + } + $oJSON = new Services_JSON(); + echo $oJSON->encode($oSM); + break; + case 'addStage': + require_once 'classes/model/Stage.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('STG_UID'); + $oCriteria->add(StagePeer::PRO_UID, $oData->uid); + $oDataset = StagePeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aStages = array(); + $iStageNumber = 0; + while ($aRow = $oDataset->getRow()) { + $aStages[] = $aRow['STG_UID']; + $iStageNumber++; + $oDataset->next(); + } + if ($iStageNumber == 0) { + $iStageNumber = 1; + } + $iIndex = $iStageNumber + 1; + $bContinue = false; + while (!$bContinue) { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn('COUNT(*) AS TIMES'); + $oCriteria->add(ContentPeer::CON_ID, $aStages, Criteria::IN); + $oCriteria->add(ContentPeer::CON_CATEGORY, 'STG_TITLE'); + $oCriteria->add(ContentPeer::CON_LANG, SYS_LANG); + $oCriteria->add(ContentPeer::CON_VALUE, G::LoadTranslation('ID_STAGE') . ' ' . $iStageNumber); + $oDataset = ContentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + if ((int)$aRow['TIMES'] > 0) { + $iStageNumber += 1; + } + else { + $bContinue = true; + } + } + $oStage = new Stage(); + $oNewStage->label = G::LoadTranslation('ID_STAGE') . ' ' . $iStageNumber; + + if($oData->position->x < 0) $oData->position->x *= -1; + if($oData->position->y < 0) $oData->position->y *= -1; + + $oNewStage->uid = $oStage->create(array('PRO_UID' => $oData->uid, 'STG_TITLE' => $oNewStage->label, 'STG_POSX' => $oData->position->x, 'STG_POSY' => $oData->position->y, 'STG_INDEX' => $iIndex)); + $oJSON = new Services_JSON(); + echo $oJSON->encode($oNewStage); + break; + case 'saveStagePosition': + require_once 'classes/model/Stage.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oStage = new Stage(); + $aFields = $oStage->load($oData->uid); + $aFields['STG_UID'] = $oData->uid; + $aFields['STG_POSX'] = $oData->position->x; + $aFields['STG_POSY'] = $oData->position->y; + $oStage->update($aFields); + break; + case 'deleteStage': + require_once 'classes/model/Stage.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oStage = new Stage(); + $aFields = $oStage->load($oData->stg_uid); + $oStage->remove($oData->stg_uid); + $oStage->reorderPositions($aFields['PRO_UID'], $aFields['STG_INDEX']); + require_once 'classes/model/Task.php'; + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(TaskPeer::STG_UID, $oData->stg_uid); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(TaskPeer::STG_UID, ''); + BasePeer::doUpdate($oCriteria1, $oCriteria2, Propel::getConnection('workflow')); + break; + case 'editStage': + require_once 'classes/model/Stage.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oStage = new Stage(); + $aFields = $oStage->load($oData->stg_uid); + $aFields['THEINDEX'] = $oData->theindex; + $aFields['action'] = 'updateStage'; + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/tracker_StageEdit', '', $aFields, '../tracker/tracker_Ajax'); + G::RenderPage('publish', 'raw'); + break; + case 'updateStage': + require_once 'classes/model/Stage.php'; + $oStage = new Stage(); + $aFields = $oStage->load($_POST['form']['STG_UID']); + $aFields['STG_TITLE'] = $_POST['form']['STG_TITLE']; + $oStage->update($aFields); + break; + case 'tasksAssigned': + require_once 'classes/model/Stage.php'; + require_once 'classes/model/Task.php'; + $oJSON = new Services_JSON(); + $oData = $oJSON->decode(stripslashes($_POST['data'])); + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TaskPeer::TAS_UID); + $oCriteria->addAsColumn('TAS_TITLE', ContentPeer::CON_VALUE); + $aConditions = array(); + $aConditions[] = array(0 => TaskPeer::TAS_UID, 1 => ContentPeer::CON_ID); + $aConditions[] = array(0 => ContentPeer::CON_CATEGORY, 1 => DBAdapter::getStringDelimiter() . 'TAS_TITLE' . DBAdapter::getStringDelimiter()); + $aConditions[] = array(0 => ContentPeer::CON_LANG, 1 => DBAdapter::getStringDelimiter() . SYS_LANG . DBAdapter::getStringDelimiter()); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(TaskPeer::STG_UID, $oData->stg_uid); + $oCriteria->addAscendingOrderByColumn('TAS_TITLE'); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_StageTasks', $oCriteria, array('PRO_UID' => $oData->pro_uid, 'STG_UID' => $oData->stg_uid)); + G::RenderPage('publish', 'raw'); + break; + case 'availableTasksForTheStage': + require_once 'classes/model/Process.php'; + require_once 'classes/model/Task.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(TaskPeer::TAS_UID); + $oCriteria->addAsColumn('TAS_TITLE', ContentPeer::CON_VALUE); + $aConditions = array(); + $aConditions[] = array(0 => TaskPeer::TAS_UID, 1 => ContentPeer::CON_ID); + $aConditions[] = array(0 => ContentPeer::CON_CATEGORY, 1 => DBAdapter::getStringDelimiter() . 'TAS_TITLE' . DBAdapter::getStringDelimiter()); + $aConditions[] = array(0 => ContentPeer::CON_LANG, 1 => DBAdapter::getStringDelimiter() . SYS_LANG . DBAdapter::getStringDelimiter()); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(TaskPeer::PRO_UID, $_POST['PRO_UID']); + $oCriteria->add(TaskPeer::STG_UID, ''); + $oCriteria->addAscendingOrderByColumn('TAS_TITLE'); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_AvailableStageTasks', $oCriteria, array('STG_UID' => $_POST['STG_UID'])); + G::RenderPage('publish', 'raw'); + break; + case 'assignTaskToStage': + require_once 'classes/model/Task.php'; + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(TaskPeer::TAS_UID, $_POST['TAS_UID']); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(TaskPeer::STG_UID, $_POST['STG_UID']); + BasePeer::doUpdate($oCriteria1, $oCriteria2, Propel::getConnection('workflow')); + break; + case 'removeTaskFromTheStage': + require_once 'classes/model/Task.php'; + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->add(TaskPeer::TAS_UID, $_POST['TAS_UID']); + $oCriteria2 = new Criteria('workflow'); + $oCriteria2->add(TaskPeer::STG_UID, ''); + BasePeer::doUpdate($oCriteria1, $oCriteria2, Propel::getConnection('workflow')); + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_ConditionsEdit.php b/workflow/engine/methods/tracker/tracker_ConditionsEdit.php new file mode 100644 index 000000000..292f2e827 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_ConditionsEdit.php @@ -0,0 +1,54 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/CaseTrackerObject.php'; + $oCaseTrackerObject = new CaseTrackerObject(); + $aFields = $oCaseTrackerObject->load($_GET['CTO_UID']); + G::LoadClass('xmlfield_InputPM'); + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/tracker_ConditionsEdit', '', $aFields, '../tracker/tracker_ConditionsSave'); + G::RenderPage('publish-raw' , 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_ConditionsSave.php b/workflow/engine/methods/tracker/tracker_ConditionsSave.php new file mode 100644 index 000000000..dd1084b54 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_ConditionsSave.php @@ -0,0 +1,52 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + require_once 'classes/model/CaseTrackerObject.php'; + $oCaseTrackerObject = new CaseTrackerObject(); + $aFields = $oCaseTrackerObject->load($_POST['form']['CTO_UID']); + $aFields['CTO_CONDITION'] = $_POST['form']['CTO_CONDITION']; + $oCaseTrackerObject->update($aFields); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_DynaDocs.php b/workflow/engine/methods/tracker/tracker_DynaDocs.php new file mode 100644 index 000000000..50dc36fb6 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_DynaDocs.php @@ -0,0 +1,61 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * dynaforms & documents for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'DYNADOC'; + + G::LoadClass('processMap'); + $oProcessMap = new processMap(); + + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($_SESSION['APPLICATION']); + if (isset($aFields['TITLE'])) { + $aFields['APP_TITLE'] = $aFields['TITLE']; + } + if ($aFields['APP_PROC_CODE'] != '') { + $aFields['APP_NUMBER'] = $aFields['APP_PROC_CODE']; + } + $aFields['CASE'] = G::LoadTranslation('ID_CASE'); + $aFields['TITLE'] = G::LoadTranslation('ID_TITLE'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $aFields); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_DynaDocs', $oProcessMap->getCaseTrackerObjectsCriteria($_SESSION['PROCESS']), array('VIEW'=>G::LoadTranslation('ID_VIEW'))); + + + + + G::RenderPage('publish'); diff --git a/workflow/engine/methods/tracker/tracker_History.php b/workflow/engine/methods/tracker/tracker_History.php new file mode 100644 index 000000000..1bd93891f --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_History.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * Hystory case for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'HISTORY'; + + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($_SESSION['APPLICATION']); + if (isset($aFields['TITLE'])) { + $aFields['APP_TITLE'] = $aFields['TITLE']; + } + if ($aFields['APP_PROC_CODE'] != '') { + $aFields['APP_NUMBER'] = $aFields['APP_PROC_CODE']; + } + $aFields['CASE'] = G::LoadTranslation('ID_CASE'); + $aFields['TITLE'] = G::LoadTranslation('ID_TITLE'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $aFields); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_TransferHistory', Cases::getTransferHistoryCriteria($_SESSION['APPLICATION']), array()); + G::RenderPage('publish'); \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_Messages.php b/workflow/engine/methods/tracker/tracker_Messages.php new file mode 100644 index 000000000..a3fdcb265 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_Messages.php @@ -0,0 +1,56 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * History messages for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'MESSAGES'; + + $oHeadPublisher->addScriptFile('/jscore/tracker/tracker.js'); + + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($_SESSION['APPLICATION']); + if (isset($aFields['TITLE'])) { + $aFields['APP_TITLE'] = $aFields['TITLE']; + } + if ($aFields['APP_PROC_CODE'] != '') { + $aFields['APP_NUMBER'] = $aFields['APP_PROC_CODE']; + } + $aFields['CASE'] = G::LoadTranslation('ID_CASE'); + $aFields['TITLE'] = G::LoadTranslation('ID_TITLE'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $aFields); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_Messages', Cases::getHistoryMessagesTracker($_SESSION['APPLICATION']), array('VIEW'=>G::LoadTranslation('ID_VIEW'))); + G::RenderPage('publish'); diff --git a/workflow/engine/methods/tracker/tracker_MessagesView.php b/workflow/engine/methods/tracker/tracker_MessagesView.php new file mode 100644 index 000000000..bf4b9d1e3 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_MessagesView.php @@ -0,0 +1,45 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * Messages for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'MESSAGES'; + + G::LoadClass("case"); + $Fields = Cases::getHistoryMessagesTrackerView($_GET['APP_UID'], $_GET['APP_MSG_UID']); + + $G_PUBLISH = new Publisher(); + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/tracker_MessagesView', '',$Fields); + G::RenderPage('publish'); \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_No.php b/workflow/engine/methods/tracker/tracker_No.php new file mode 100644 index 000000000..aa60e4354 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_No.php @@ -0,0 +1,45 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * message for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + $G_MAIN_MENU = 'caseTracker'; + //$G_ID_MENU_SELECTED = 'DYNADOC'; + + G::LoadClass('processMap'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'tracker/tracker_No', '', ''); + + G::RenderPage('publish'); + \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_Save.php b/workflow/engine/methods/tracker/tracker_Save.php new file mode 100644 index 000000000..edca2e6ee --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_Save.php @@ -0,0 +1,11 @@ +update($_POST['form']); \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_Show.php b/workflow/engine/methods/tracker/tracker_Show.php new file mode 100644 index 000000000..a0599d1f7 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_Show.php @@ -0,0 +1,89 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * dynaforms & documents for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + + if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + + global $_DBArray; + if (!isset($_DBArray)) { + $_DBArray = array(); + } + + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'DYNADOC'; + global $G_PUBLISH; + + switch ($_GET['CTO_TYPE_OBJ']) + { + case 'DYNAFORM': + G::LoadClass('case'); + $oCase = new Cases(); + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['PREVIOUS_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP_LABEL'] = ''; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_STEP'] = '#'; + $Fields['APP_DATA']['__DYNAFORM_OPTIONS']['NEXT_ACTION'] = 'return false;'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('dynaform', 'xmlform', $_SESSION['PROCESS']. '/' . $_GET['CTO_UID_OBJ'], '', $Fields['APP_DATA'],'','','view'); + G::RenderPage('publish'); + break; + + case 'INPUT_DOCUMENT': + G::LoadClass('case'); + $oCase = new Cases(); + $c = $oCase->getAllUploadedDocumentsCriteriaTracker($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_GET['CTO_UID_OBJ']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/tracker/tracker.js'); + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_Inputdocs', $c); + G::RenderPage('publish'); + break; + + case 'OUTPUT_DOCUMENT': + G::LoadClass('case'); + $oCase = new Cases(); + $c = $oCase->getAllGeneratedDocumentsCriteriaTracker($_SESSION['PROCESS'], $_SESSION['APPLICATION'], $_GET['CTO_UID_OBJ']); + + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptFile('/jscore/tracker/tracker.js'); + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'tracker/tracker_Outputdocs', $c); + G::RenderPage('publish'); + break; + } + +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_ShowDocument.php b/workflow/engine/methods/tracker/tracker_ShowDocument.php new file mode 100644 index 000000000..d81969eb9 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_ShowDocument.php @@ -0,0 +1,47 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 13-02-2008 + * + * @author David Callizaya + */ +if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + + require_once ( "classes/model/AppDocumentPeer.php" ); + + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_GET['a']); + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + $ext = $info['extension']; + + $realPath = PATH_DOCUMENT . $_SESSION['APPLICATION'] . '/' . $sAppDocUid . '.' . $ext ; + G::streamFile ( $realPath, true, $oAppDocument->Fields['APP_DOC_FILENAME'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_ShowOutputDocument.php b/workflow/engine/methods/tracker/tracker_ShowOutputDocument.php new file mode 100644 index 000000000..cad352093 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_ShowOutputDocument.php @@ -0,0 +1,57 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +/* + * Created on 13-02-2008 + * + * @author David Callizaya + */ +if (!isset($_SESSION['PROCESS'])) + { + G::header('location: login'); + } + + require_once ( "classes/model/AppDocumentPeer.php" ); + + $oAppDocument = new AppDocument(); + $oAppDocument->Fields = $oAppDocument->load($_GET['a']); + + $sAppDocUid = $oAppDocument->getAppDocUid(); + $info = pathinfo( $oAppDocument->getAppDocFilename() ); + if (!isset($_GET['ext'])) { + $ext = $info['extension']; + } + else { + if ($_GET['ext'] != '') { + $ext = $_GET['ext']; + } + else { + $ext = $info['extension']; + } + } + + $realPath = PATH_DOCUMENT . $_SESSION['APPLICATION'] . '/outdocs/' . $info['basename'] . '.' . $ext ; + G::streamFile ( $realPath, true ); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/tracker/tracker_ViewMap.php b/workflow/engine/methods/tracker/tracker_ViewMap.php new file mode 100644 index 000000000..17d29fb12 --- /dev/null +++ b/workflow/engine/methods/tracker/tracker_ViewMap.php @@ -0,0 +1,123 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * Map for Case Tracker + * + * @author Everth S. Berrios Morales + * + */ + if (!isset($_SESSION['PROCESS'])) { + G::header('location: login'); + } + $G_MAIN_MENU = 'caseTracker'; + $G_ID_MENU_SELECTED = 'MAP'; + + require_once 'classes/model/CaseTracker.php'; + $oCaseTracker = new CaseTracker(); + $aCaseTracker = $oCaseTracker->load($_SESSION['PROCESS']); + switch (($aCaseTracker['CT_MAP_TYPE'])) { + case 'NONE': + //Nothing + break; + case 'PROCESSMAP': + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($_SESSION['APPLICATION']); + if (isset($aFields['TITLE'])) { + $aFields['APP_TITLE'] = $aFields['TITLE']; + } + if ($aFields['APP_PROC_CODE'] != '') { + $aFields['APP_NUMBER'] = $aFields['APP_PROC_CODE']; + } + $aFields['CASE'] = G::LoadTranslation('ID_CASE'); + $aFields['TITLE'] = G::LoadTranslation('ID_TITLE'); + $oTemplatePower = new TemplatePower(PATH_TPL . 'processes/processes_Map.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $aFields); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + leimnud.event.add(window,"load",function(){ + var pb=leimnud.dom.capture("tag.body 0"); + Pm=new processmap(); + Pm.options = { + target : "pm_target", + dataServer: "../processes/processes_Ajax", + uid : "' . $_SESSION['PROCESS'] . '", + lang : "' . SYS_LANG . '", + theme : "processmaker", + size : {w:pb.offsetWidth-10,h:pb.offsetHeight}, + images_dir: "/jscore/processmap/core/images/", + rw : false, + mi : false, + ct : true, + hideMenu : false + } + Pm.make(); + });'); + G::RenderPage('publish'); + break; + case 'STAGES': + G::LoadClass('case'); + $oCase = new Cases(); + $aFields = $oCase->loadCase($_SESSION['APPLICATION']); + if (isset($aFields['TITLE'])) { + $aFields['APP_TITLE'] = $aFields['TITLE']; + } + if ($aFields['APP_PROC_CODE'] != '') { + $aFields['APP_NUMBER'] = $aFields['APP_PROC_CODE']; + } + $aFields['CASE'] = G::LoadTranslation('ID_CASE'); + $aFields['TITLE'] = G::LoadTranslation('ID_TITLE'); + $oTemplatePower = new TemplatePower(PATH_TPL . 'tracker/stages_Map.html'); + $oTemplatePower->prepare(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('smarty', 'cases/cases_title', '', '', $aFields); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + $oHeadPublisher =& headPublisher::getSingleton(); + $oHeadPublisher->addScriptCode(' + leimnud.Package.Load("stagesmap",{Type:"file",Absolute:true,Path:"/jscore/stagesmap/core/stagesmap.js"}); + leimnud.event.add(window,"load",function(){ + var pb=leimnud.dom.capture("tag.body 0"); + Sm=new stagesmap(); + Sm.options = { + target : "sm_target", + dataServer: "../tracker/tracker_Ajax", + uid : "' . $_SESSION['PROCESS'] . '", + lang : "' . SYS_LANG . '", + theme : "processmaker", + size : {w:"780",h:"540"}, + //size : {w:pb.offsetWidth-10,h:pb.offsetHeight}, + images_dir: "/jscore/processmap/core/images/", + rw : false, + hideMenu : false + }; + Sm.make(); + });'); + G::RenderPage('publish'); + break; +} diff --git a/workflow/engine/methods/triggers/triggersProperties.php b/workflow/engine/methods/triggers/triggersProperties.php new file mode 100644 index 000000000..075b44544 --- /dev/null +++ b/workflow/engine/methods/triggers/triggersProperties.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); + +if (isset($_GET['TRI_UID'])) +{ + $oTrigger = new Triggers(); + $aFields = $oTrigger->load($_GET['TRI_UID']); +} +else +{ + $aFields['PRO_UID'] = $_GET['PRO_UID']; + //$aFields['PRO_UID'] = (isset($_SESSION['PROCESS']) ? $_SESSION['PROCESS'] : ''); + $aFields['TRI_TYPE'] = 'SCRIPT'; +} + +G::LoadClass('xmlfield_InputPM'); +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'triggers/triggersProperties', '', $aFields, '../triggers/triggers_Save'); +G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggersTree.php b/workflow/engine/methods/triggers/triggersTree.php new file mode 100755 index 000000000..2df8be752 --- /dev/null +++ b/workflow/engine/methods/triggers/triggersTree.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); +require_once('classes/model/Process.php'); + + + +$sProcessUID=$_GET['PRO_UID']; + + + $oProcess = new Process ( ); + $aFields = $oProcess->load ( $sProcessUID ); + + $_SESSION['PROCESS'] = $sProcessUID; + + + $G_PUBLISH = new Publisher ( ); + $G_PUBLISH->AddContent ( 'view', 'triggers/triggersTree' ); + G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_Ajax.php b/workflow/engine/methods/triggers/triggers_Ajax.php new file mode 100755 index 000000000..1a1a33b01 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_Ajax.php @@ -0,0 +1,88 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * Triggers Ajax Request HAndler + * + * @author Erik A.O. + * @date Apr 29th, 2010 + */ + +$request = isset($_POST['request'])? $_POST['request']: ''; + + +switch($request){ + case 'verifyDependencies': + require_once 'classes/model/Triggers.php'; + + if( !isset($_POST['TRI_UID']) ) { + throw new Exception('Missing trigger ID for the request [verifyDependencies]'); + exit(0); + } + + $oTrigger = new Triggers; + $oResult = $oTrigger->verifyDependecies($_POST['TRI_UID']); + + if($oResult->code == 0){ + $oResult->message = G::LoadTranslation('ID_TRIGGERS_VALIDATION'); //"No Dependencies were found for this trigger in Events definitions\n"; + } else { + $oResult->message = ''; + foreach($oResult->dependencies as $Object=>$aDeps){ + $nDeps = count($aDeps); + $message = str_replace('{N}', $nDeps, G::LoadTranslation('ID_TRIGGERS_VALIDATION_ERR2')); + $message = str_replace('{Object}', $Object, $message); + $oResult->message .= $message . "\n"; + foreach($aDeps as $dep){ + if( substr($Object, -1) == 's') $Object = substr($Object, 0, strlen($Object)-1); + $message = str_replace('{Object}', $Object, G::LoadTranslation('ID_TRIGGERS_VALIDATION_ERR3')); + $message = str_replace('{Description}', '"'.$dep['DESCRIPTION'].'"', $message); + $oResult->message .= $message . "\n"; + } + $oResult->message .= "\n"; + } + } + //print_r($oResult); + print G::json_encode($oResult); + break; + default: echo 'default'; +} + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/methods/triggers/triggers_CreateWizard.php b/workflow/engine/methods/triggers/triggers_CreateWizard.php new file mode 100755 index 000000000..d19326253 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_CreateWizard.php @@ -0,0 +1,92 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); + +$G_PUBLISH = new Publisher ( ); +$G_PUBLISH->AddContent ( 'view', 'triggers/triggers_CreateWizard', '', '', $_GET, '' ); +G::RenderPage('publish', 'raw'); + + +?> + + \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_Delete.php b/workflow/engine/methods/triggers/triggers_Delete.php new file mode 100644 index 000000000..f7de62b71 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_Delete.php @@ -0,0 +1,43 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; + +require_once('classes/model/Triggers.php'); +$oTrigger = new Triggers(); +$triggerObj=$oTrigger->load($_POST['TRI_UID']); + + +$oTrigger->remove($_POST['TRI_UID']); +require_once('classes/model/StepTrigger.php'); +$oStepTrigger = new StepTrigger(); +$oStepTrigger->removeTrigger($_POST['TRI_UID']); + +G::LoadClass('processMap'); +$oProcessMap = new processMap(new DBConnection); +//Update Trigger Array +$oProcessMap->triggersList($triggerObj['PRO_UID']); + + +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_Edit.php b/workflow/engine/methods/triggers/triggers_Edit.php new file mode 100644 index 000000000..8f7ebf0c4 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_Edit.php @@ -0,0 +1,73 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); + +if (isset($_GET['TRI_UID'])) +{ + $oTrigger = new Triggers(); + // check if its necessary bypass the wizard editor + if (isset($_GET['BYPASS'])&&$_GET['BYPASS']=='1'){ + $editWizardSource = true; + } else { + $editWizardSource = false; + } + $aFields = $oTrigger->load($_GET['TRI_UID']); + $aTriggerData = unserialize($aFields['TRI_PARAM']); + // if trigger has been created with the wizard the TRI_PARAM field cant be empty + if($aFields['TRI_PARAM']!=''&&!$editWizardSource){ + $aTriggerData = unserialize($aFields['TRI_PARAM']); + // if the trigger has been modified manually, it cant be edited with the wizard. + if (md5($aFields['TRI_WEBBOT'])==$aTriggerData['hash']){ + $triUid = $_GET['TRI_UID']; + $_GET = $aTriggerData['params']; + $_GET['TRI_UID'] = $triUid; + require_once('triggers_EditWizard.php'); + die; + } else { + // custom trigger edit + $xmlform = 'triggers/triggers_Edit'; + $xmlform_action = '../triggers/triggers_Save'; + } + }else{ + // custom trigger edit + $xmlform = 'triggers/triggers_Edit'; + $xmlform_action = '../triggers/triggers_Save'; + } +} +else +{ + //if its a new trigger + $aFields['PRO_UID'] = $_GET['PRO_UID']; + $aFields['TRI_TYPE'] = 'SCRIPT'; + $xmlform = 'triggers/triggersProperties'; + $xmlform_action = '../triggers/triggers_Save'; +} + +G::LoadClass('xmlfield_InputPM'); +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', $xmlform , '', $aFields, $xmlform_action); +G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_EditCustom.php b/workflow/engine/methods/triggers/triggers_EditCustom.php new file mode 100644 index 000000000..62a0ae8be --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_EditCustom.php @@ -0,0 +1,40 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); + + $aFields['PRO_UID'] = $_GET['PRO_UID']; + $aFields['TRI_TYPE'] = 'SCRIPT'; +if(isset($_GET['TRI_UID'])&&($_GET['TRI_UID']!="")){ + $oTrigger = new Triggers(); + $aFields = $oTrigger->load($_GET['TRI_UID']); +} + $xmlform = 'triggers/triggersCustom'; + +G::LoadClass('xmlfield_InputPM'); +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', $xmlform , '', $aFields, '../triggers/triggers_Save'); +G::RenderPage('publish', 'raw'); +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_EditWizard.php b/workflow/engine/methods/triggers/triggers_EditWizard.php new file mode 100644 index 000000000..def592b00 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_EditWizard.php @@ -0,0 +1,95 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +// this script calls the template that constructs the wizard form for a trigger + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +if (!class_exists('Triggers')){ + require_once('classes/model/Triggers.php'); +} +$G_PUBLISH = new Publisher ( ); +$G_PUBLISH->AddContent ( 'view', 'triggers/triggers_EditWizard', '', '', $_GET, '' ); +G::RenderPage('publish', 'raw'); + +?> + + \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_Save.php b/workflow/engine/methods/triggers/triggers_Save.php new file mode 100644 index 000000000..6f41602d2 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_Save.php @@ -0,0 +1,81 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response=$RBAC->userCanAccess("PM_FACTORY"))!=1) return $RBAC_Response; +require_once('classes/model/Triggers.php'); +require_once('classes/model/Content.php'); + + if(isset($_POST['function']) && $_POST['function']=='lookforNameTrigger'){ + $snameTrigger=urldecode($_POST['NAMETRIGGER']); + $sPRO_UID=urldecode($_POST['proUid']); + + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn ( TriggersPeer::TRI_UID ); + $oCriteria->add(TriggersPeer::PRO_UID, $sPRO_UID); + $oDataset = TriggersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $flag=true; + while ($oDataset->next() && $flag) { + $aRow = $oDataset->getRow(); + + $oCriteria1 = new Criteria('workflow'); + $oCriteria1->addSelectColumn('COUNT(*) AS TRIGGERS'); + $oCriteria1->add(ContentPeer::CON_CATEGORY, 'TRI_TITLE'); + $oCriteria1->add(ContentPeer::CON_ID, $aRow['TRI_UID']); + $oCriteria1->add(ContentPeer::CON_VALUE, $snameTrigger); + $oCriteria1->add(ContentPeer::CON_LANG, SYS_LANG); + $oDataset1 = ContentPeer::doSelectRS($oCriteria1); + $oDataset1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset1->next(); + $aRow1 = $oDataset1->getRow(); + + if($aRow1['TRIGGERS'])$flag=false; + + + } + print $flag; + //print'krlos';return ; + } else { + + $oTrigger = new Triggers(); + + G::LoadClass('processMap'); + $oProcessMap = new processMap(new DBConnection); + + if ($_POST['form']['TRI_UID'] != '') + { + $oTrigger->load($_POST['form']['TRI_UID']); + } + else + { + $oTrigger->create($_POST['form']); + $_POST['form']['TRI_UID']=$oTrigger->getTriUid(); + } + //print_r($_POST['form']);die; + $oTrigger->update($_POST['form']); + + $oProcessMap->triggersList($_POST['form']['PRO_UID']); + } +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_WizardSave.php b/workflow/engine/methods/triggers/triggers_WizardSave.php new file mode 100755 index 000000000..5a8b9dba5 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_WizardSave.php @@ -0,0 +1,95 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response = $RBAC->userCanAccess ( "PM_FACTORY" )) != 1) + return $RBAC_Response; +require_once ('classes/model/Triggers.php'); +$oTrigger = new Triggers ( ); + +G::LoadClass('processMap'); +$oProcessMap = new processMap(new DBConnection); + +$aDataTriggers = $_POST; + +$aInfoFunction = explode ( ",", $aDataTriggers ['ALLFUNCTION'] ); + +$sPMfunction = " +/*************************************************** + * + * Generated by ProcessMaker Trigger Wizard + * Library: " . $aDataTriggers ['LIBRARY_NAME'] . " + * Method: " . $aDataTriggers ['PMFUNTION_LABEL'] . " + * Date: " . date ( "Y-m-d H:i:s" ) . " + * + * ProcessMaker " . date ( "Y" ) . " + * + ****************************************************/ + +"; + +$methodParamsFinal = array (); +//Generate params to send +foreach ( $aInfoFunction as $k => $v ) { + if ($v != '') { + + $sOptionTrigger = trim ( str_replace ( "$", "", $v ) ); + if (strstr ( $sOptionTrigger, "=" )) { + $aOptionParameters = explode ( "=", $sOptionTrigger ); + $sOptionTrigger = trim ( $aOptionParameters [0] ); + } + if ($aDataTriggers [$sOptionTrigger] != '') { + + if ((strstr ( $aDataTriggers [$sOptionTrigger], "@@" ))) { + $option = $aDataTriggers [$sOptionTrigger]; + } else { + $option = "'" . $aDataTriggers [$sOptionTrigger] . "'"; + } + } else { + $option = "' '"; + } + $methodParamsFinal [] = $option; + + } + +} +$sPMfunction .= (isset ( $aDataTriggers ['TRI_ANSWER'] ) && $aDataTriggers ['TRI_ANSWER'] != '') ? $aDataTriggers ['TRI_ANSWER'] . " = " : ""; +$sPMfunction .= $aDataTriggers ['PMFUNTION_NAME'] . " (" . implode ( ",", $methodParamsFinal ) . ");"; + +//Create Trigger +$aDataTriggers ['TRI_WEBBOT'] = $sPMfunction; +$aDataTriggersParams = array(); +$aDataTriggersParams['hash'] = md5 ($sPMfunction); +$aDataTriggersParams['params'] = $aDataTriggers; + +$aDataTriggers ['TRI_PARAM'] = serialize($aDataTriggersParams); +$oTrigger->create ( $aDataTriggers ); + +//Update Info +$aDataTriggers ['TRI_UID'] = $oTrigger->getTriUid (); +$oTrigger->update ( $aDataTriggers ); + +//Update Trigger Array +$oProcessMap->triggersList($aDataTriggers['PRO_UID']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/triggers/triggers_WizardUpdate.php b/workflow/engine/methods/triggers/triggers_WizardUpdate.php new file mode 100644 index 000000000..3200f3c87 --- /dev/null +++ b/workflow/engine/methods/triggers/triggers_WizardUpdate.php @@ -0,0 +1,100 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +if (($RBAC_Response = $RBAC->userCanAccess ( "PM_FACTORY" )) != 1) + return $RBAC_Response; +if (!class_exists('Triggers')){ + require_once ('classes/model/Triggers.php'); +} +$oTrigger = new Triggers ( ); + +G::LoadClass('processMap'); +$oProcessMap = new processMap(new DBConnection); + +$aDataTriggers = $_POST; +$triUid = $_POST['TRI_UID']; + +$aInfoFunction = explode ( ",", $aDataTriggers ['ALLFUNCTION'] ); + +$sPMfunction = " +/*************************************************** + * + * Generated by ProcessMaker Trigger Wizard + * Library: " . $aDataTriggers ['LIBRARY_NAME'] . " + * Method: " . $aDataTriggers ['PMFUNTION_LABEL'] . " + * Date: " . date ( "Y-m-d H:i:s" ) . " + * + * ProcessMaker " . date ( "Y" ) . " + * + ****************************************************/ + +"; + +$methodParamsFinal = array (); +//Generate params to send +foreach ( $aInfoFunction as $k => $v ) { + if ($v != '') { + + $sOptionTrigger = trim ( str_replace ( "$", "", $v ) ); + if (strstr ( $sOptionTrigger, "=" )) { + $aOptionParameters = explode ( "=", $sOptionTrigger ); + $sOptionTrigger = trim ( $aOptionParameters [0] ); + } + if ($aDataTriggers [$sOptionTrigger] != '') { + + if ((strstr ( $aDataTriggers [$sOptionTrigger], "@@" ))) { + $option = $aDataTriggers [$sOptionTrigger]; + } else { + $option = "'" . $aDataTriggers [$sOptionTrigger] . "'"; + } + } else { + $option = "' '"; + } + $methodParamsFinal [] = $option; + + } + +} +$sPMfunction .= (isset ( $aDataTriggers ['TRI_ANSWER'] ) && $aDataTriggers ['TRI_ANSWER'] != '') ? $aDataTriggers ['TRI_ANSWER'] . " = " : ""; +$sPMfunction .= $aDataTriggers ['PMFUNTION_NAME'] . " (" . implode ( ",", $methodParamsFinal ) . ");"; + +//Create Trigger +$aDataTriggers ['TRI_WEBBOT'] = $sPMfunction; +$aDataTriggersParams = array(); +$aDataTriggersParams['hash'] = md5 ($sPMfunction); +$aDataTriggersParams['params'] = $aDataTriggers; + +$aDataTriggers ['TRI_PARAM'] = serialize($aDataTriggersParams); +//$oTrigger->create ( $aDataTriggers ); +$aDataTriggerLoaded = $oTrigger->load($triUid); +//var_dump($aDataTriggerLoaded); +//die; +//Update Info +$aDataTriggers ['TRI_UID'] = $oTrigger->getTriUid (); +$oTrigger->update ( $aDataTriggers ); + +//Update Trigger Array +$oProcessMap->triggersList($aDataTriggers['PRO_UID']); +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/index.php b/workflow/engine/methods/users/index.php new file mode 100644 index 000000000..7fae54b36 --- /dev/null +++ b/workflow/engine/methods/users/index.php @@ -0,0 +1,28 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $newFile = str_replace ( 'index.php', 'users_List.php' , __FILE__ ) ; + return $newFile; + + \ No newline at end of file diff --git a/workflow/engine/methods/users/myInfo.php b/workflow/engine/methods/users/myInfo.php new file mode 100644 index 000000000..283226ea7 --- /dev/null +++ b/workflow/engine/methods/users/myInfo.php @@ -0,0 +1,178 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_LOGIN')){ + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + // deprecated the class XmlForm_Field_Image is currently part of the class.xmlform.php package + // the use of the external xmlfield_Image is highly discouraged + if (!class_exists('XmlForm_Field_Image')){ + G::LoadClass('xmlfield_Image'); + } +// G::LoadClass('xmlfield_Department'); + require_once 'classes/model/Users.php'; + require_once 'classes/model/Department.php'; + unset($_SESSION['CURRENT_USER']); + $oUser = new Users(); + $aFields = $oUser->load($_SESSION['USER_LOGGED']); + $aFields['USR_PASSWORD'] = '********'; + $aFields['MESSAGE0'] = G::LoadTranslation('ID_USER_REGISTERED') . '!'; + $aFields['MESSAGE1'] = G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME'); + $aFields['MESSAGE2'] = G::LoadTranslation('ID_MSG_ERROR_DUE_DATE'); + $aFields['MESSAGE3'] = G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS'); + $aFields['MESSAGE4'] = G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME'); + $aFields['MESSAGE5'] = G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME'); + $aFields['NO_RESUME'] = G::LoadTranslation('ID_NO_RESUME'); + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['RANDOM'] = rand(); + + //getting the user and department + $oDepInfo = new Department(); + $oUser = UsersPeer::retrieveByPk( $aFields['USR_REPORTS_TO'] ); + if ( get_class ($oUser) == 'Users' ) { + $userFields = $oUser->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['USR_REPORTS_TO'] = $userFields['USR_FIRSTNAME'] . ' ' . $userFields['USR_LASTNAME']; + try { + $depFields = $oDepInfo->load($userFields['DEP_UID'] ); + $aFields['USR_REPORTS_TO'] .= " (" . $depFields['DEPO_TITLE'] . ")"; + } + catch( Exception $e ) { + } + } + else{ + $aFields['USR_REPORTS_TO'] = ' '; + } + + try { + $depFields = $oDepInfo->load($aFields['DEP_UID']); + $aFields['USR_DEPARTMENT'] = $depFields['DEPO_TITLE']; + } + catch( Exception $e ) { + $oUser = UsersPeer::retrieveByPk( $_SESSION['USER_LOGGED'] ); + $oUser->setDepUid( '' ); + $aFields['USR_DEPARTMENT'] = ' '; + } + + $G_MAIN_MENU = 'processmaker'; + + $G_ID_MENU_SELECTED = 'MY_ACCOUNT'; + $G_PUBLISH = new Publisher; + + + #verifying if it has any preferences on the configurations table + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'USER_PREFERENCES','','',$_SESSION['USER_LOGGED'],''); + + if( sizeof($oConf->Fields) > 0){ #this user has a configuration record + $aFields['PREF_DEFAULT_LANG'] = $oConf->aConfig['DEFAULT_LANG']; + $aFields['PREF_DEFAULT_MENUSELECTED'] = isset($oConf->aConfig['DEFAULT_MENU']) ? $oConf->aConfig['DEFAULT_MENU']: ''; + $aFields['PREF_DEFAULT_CASES_MENUSELECTED'] = isset($oConf->aConfig['DEFAULT_CASES_MENU']) ? $oConf->aConfig['DEFAULT_CASES_MENU']: ''; + } else { + switch($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE']){ + case 'PROCESSMAKER_ADMIN': + $aFields['PREF_DEFAULT_MENUSELECTED'] = 'PM_USERS'; + break; + + case 'PROCESSMAKER_OPERATOR': + $aFields['PREF_DEFAULT_MENUSELECTED'] = 'PM_CASES'; + break; + + } + $aFields['PREF_DEFAULT_LANG'] = SYS_LANG; + } + $rows[] = Array('id'=>'char', 'name'=>'char'); + + + foreach($RBAC->aUserInfo['PROCESSMAKER']['PERMISSIONS'] as $permission){ + + switch($permission['PER_CODE']){ + case 'PM_USERS': + $rows[] = Array('id'=>'PM_USERS', 'name'=>strtoupper(G::LoadTranslation('ID_USERS'))); + break; + case 'PM_CASES': + $rows[] = Array('id'=>'PM_CASES', 'name'=>strtoupper(G::LoadTranslation('ID_CASES'))); + break; + case 'PM_FACTORY': + $rows[] = Array('id'=>'PM_FACTORY', 'name'=>strtoupper(G::LoadTranslation('ID_APPLICATIONS'))); + break; + case 'PM_DASHBOARD': + $rows[] = Array('id'=>'PM_DASHBOARD', 'name'=>strtoupper(G::LoadTranslation('ID_DASHBOARD'))); + break; + case 'PM_SETUP': + $rows[] = Array('id'=>'PM_SETUP', 'name'=>strtoupper(G::LoadTranslation('ID_SETUP'))); + break; + } + } + + global $G_TMP_MENU; + $oMenu = new Menu(); + $oMenu->load('cases'); + + $rowsCasesMenu[] = Array('id'=>'char', 'name'=>'char'); + + foreach($oMenu->Id as $i=>$item){ + if( $oMenu->Types[$i] != 'blockHeader' ){ + $rowsCasesMenu[] = Array('id'=>$item, 'name'=>$oMenu->Labels[$i]); + } + } + + //G::pr($rows); die; + global $_DBArray; + $_DBArray['menutab'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + $_DBArray['CASES_MENU'] = $rowsCasesMenu; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('menutab'); + $oCriteria2 = new Criteria('dbarray'); + $oCriteria2->setDBArrayTable('CASES_MENU'); + + if ($RBAC->userCanAccess('PM_EDITPERSONALINFO') == 1) { //he has permitions for edit his profile + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/myInfoView.xml', '', $aFields); + } else { //he has not permitions for edit his profile, so just view mode will be displayed + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/myInfoView2.xml', '', $aFields); + } + + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/myInfo_Ajax.php b/workflow/engine/methods/users/myInfo_Ajax.php new file mode 100644 index 000000000..f9c4eb917 --- /dev/null +++ b/workflow/engine/methods/users/myInfo_Ajax.php @@ -0,0 +1,32 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; +G::LoadClass("xmlMenu"); +$form = new Form ( 'myInfo/myInfoAEdit.xml' , PATH_XMLFORM ); +$form->action = urlencode( G::encrypt( '' ,URL_KEY ) ); +$form->ajaxServer = urlencode( G::encrypt( SYS_URI . '/gulliver/defaultAjax' ,URL_KEY ) ); +$template = PATH_CORE . 'templates/xmlform.html'; +print $G_FORM->render( $template , $scriptCode ); +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/myInfo_Edit.php b/workflow/engine/methods/users/myInfo_Edit.php new file mode 100755 index 000000000..b452d4b56 --- /dev/null +++ b/workflow/engine/methods/users/myInfo_Edit.php @@ -0,0 +1,168 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + $RBAC->requirePermissions('PM_LOGIN'); + + // deprecated the class XmlForm_Field_Image is currently part of the class.xmlform.php package + // the use of the external xmlfield_Image is highly discouraged + if (!class_exists('XmlForm_Field_Image')){ + G::LoadClass('xmlfield_Image'); + } + require_once 'classes/model/Users.php'; + require_once 'classes/model/Department.php'; + + unset($_SESSION['CURRENT_USER']); + $oUser = new Users(); + $aFields = $oUser->load($_SESSION['USER_LOGGED']); + $aFields['USR_PASSWORD'] = '********'; + $aFields['MESSAGE0'] = G::LoadTranslation('ID_USER_REGISTERED') . '!'; + $aFields['MESSAGE1'] = G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME'); + $aFields['MESSAGE2'] = G::LoadTranslation('ID_MSG_ERROR_DUE_DATE'); + $aFields['MESSAGE3'] = G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS'); + $aFields['MESSAGE4'] = G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME'); + $aFields['MESSAGE5'] = G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME'); + $aFields['NO_RESUME'] = G::LoadTranslation('ID_NO_RESUME'); + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['RANDOM'] = rand(); + + //getting the user and department + $oDepInfo = new Department(); + $oUser = UsersPeer::retrieveByPk( $aFields['USR_REPORTS_TO'] ); + if ( get_class ($oUser) == 'Users' ) { + $userFields = $oUser->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['USR_REPORTS_TO'] = $userFields['USR_FIRSTNAME'] . ' ' . $userFields['USR_LASTNAME']; + try { + $depFields = $oDepInfo->load($userFields['DEP_UID'] . 'xy<'); + $aFields['USR_REPORTS_TO'] .= " (" . $depFields['DEPO_TITLE'] . ")"; + } + catch( Exception $e ) { + } + } + else{ + $aFields['USR_REPORTS_TO'] = ' '; + } + + try { + $depFields = $oDepInfo->load($aFields['DEP_UID']); + $aFields['USR_DEPARTMENT'] = $depFields['DEPO_TITLE']; + } + catch( Exception $e ) { + $oUser = UsersPeer::retrieveByPk( $_SESSION['USER_LOGGED'] ); + $oUser->setDepUid( '' ); + $oUser->save(); + $aFields['USR_DEPARTMENT'] = ' '; + } + + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'MY_ACCOUNT'; + $G_PUBLISH = new Publisher; + + + //$RBAC->systemObj->loadByCode('PROCESSMAKER');//('PROCESSMAKER', $_SESSION['USER_LOGGED']); + + #verifying if it has any preferences on the configurations table + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($x, 'USER_PREFERENCES','','',$_SESSION['USER_LOGGED'],''); + + //echo $RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE']; + //G::pr($RBAC->userObj->load($_SESSION['USER_LOGGED'])); + if( sizeof($oConf->Fields) > 0){ #this user has a configuration record + $aFields['PREF_DEFAULT_LANG'] = $oConf->aConfig['DEFAULT_LANG']; + $aFields['PREF_DEFAULT_MENUSELECTED'] = isset($oConf->aConfig['DEFAULT_MENU']) ? $oConf->aConfig['DEFAULT_MENU']: ''; + $aFields['PREF_DEFAULT_CASES_MENUSELECTED'] = isset($oConf->aConfig['DEFAULT_CASES_MENU']) ? $oConf->aConfig['DEFAULT_CASES_MENU']: ''; + } else { + switch($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE']){ + case 'PROCESSMAKER_ADMIN': + $aFields['PREF_DEFAULT_MENUSELECTED'] = 'PM_USERS'; + break; + + case 'PROCESSMAKER_OPERATOR': + $aFields['PREF_DEFAULT_MENUSELECTED'] = 'PM_CASES'; + break; + + } + $aFields['PREF_DEFAULT_LANG'] = SYS_LANG; + } + //G::pr($RBAC->aUserInfo); + $rows[] = Array('id'=>'char', 'name'=>'char'); + + + foreach($RBAC->aUserInfo['PROCESSMAKER']['PERMISSIONS'] as $permission){ + + switch($permission['PER_CODE']){ + case 'PM_USERS': + case 'PM_SETUP': + $rows[] = Array('id'=>'PM_SETUP', 'name'=>strtoupper(G::LoadTranslation('ID_SETUP'))); + break; + case 'PM_CASES': + $rows[] = Array('id'=>'PM_CASES', 'name'=>strtoupper(G::LoadTranslation('ID_CASES'))); + break; + case 'PM_FACTORY': + $rows[] = Array('id'=>'PM_FACTORY', 'name'=>strtoupper(G::LoadTranslation('ID_APPLICATIONS'))); + break; + } + } + + global $G_TMP_MENU; + $oMenu = new Menu(); + $oMenu->load('cases'); + + $rowsCasesMenu[] = Array('id'=>'char', 'name'=>'char'); + + foreach($oMenu->Id as $i=>$item){ + if( $oMenu->Types[$i] != 'blockHeader' ){ + $rowsCasesMenu[] = Array('id'=>$item, 'name'=>$oMenu->Labels[$i]); + } + } + + //G::pr($rows); die; + global $_DBArray; + $_DBArray['menutab'] = $rows; + $_SESSION['_DBArray'] = $_DBArray; + $_DBArray['CASES_MENU'] = $rowsCasesMenu; + $_SESSION['_DBArray'] = $_DBArray; + + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('menutab'); + + $oCriteria2 = new Criteria('dbarray'); + $oCriteria2->setDBArrayTable('CASES_MENU'); + + if ($RBAC->userCanAccess('PM_EDITPERSONALINFO') == 1) { //he has permitions for edit his profile + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/myInfo.xml', '', $aFields, 'myInfo_Save'); + } else { //he has not permitions for edit his profile, so just view mode will be displayed + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/myInfo2.xml', '', $aFields, ''); + } + + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/myInfo_Save.php b/workflow/engine/methods/users/myInfo_Save.php new file mode 100644 index 000000000..0588c776c --- /dev/null +++ b/workflow/engine/methods/users/myInfo_Save.php @@ -0,0 +1,171 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try {ini_set('display_errors','1'); + global $RBAC; + switch ($RBAC->userCanAccess('PM_LOGIN')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + if (isset($_FILES['form']['name']['USR_RESUME'])) { + $_POST['form']['USR_RESUME'] = $_FILES['form']['name']['USR_RESUME']; + } + if ($_POST['form']['USR_EMAIL'] != '') { + if (!ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$", $_POST['form']['USR_EMAIL'])) { + G::SendTemporalMessage ('ID_INCORRECT_EMAIL', 'error'); + } + } + if (!isset($_POST['form']['USR_NEW_PASS'])) { + $_POST['form']['USR_NEW_PASS'] = ''; + } + if ($_POST['form']['USR_NEW_PASS'] != '') { + $_POST['form']['USR_PASSWORD'] = md5($_POST['form']['USR_NEW_PASS']); + } + if (!isset($_POST['form']['USR_CITY'])) { + $_POST['form']['USR_CITY'] = ''; + } + if (!isset($_POST['form']['USR_LOCATION'])) { + $_POST['form']['USR_LOCATION'] = ''; + } + if (!isset($_POST['form']['USR_ROLE'])) { + $_POST['form']['USR_ROLE'] = ''; + } + $aData['USR_UID'] = $_POST['form']['USR_UID']; + $aData['USR_USERNAME'] = $_POST['form']['USR_USERNAME']; + if (isset($_POST['form']['USR_PASSWORD'])) { + if ($_POST['form']['USR_PASSWORD'] != '') { + $aData['USR_PASSWORD'] = $_POST['form']['USR_PASSWORD']; + require_once 'classes/model/UsersProperties.php'; + $oUserProperty = new UsersProperties(); + $aUserProperty = $oUserProperty->loadOrCreateIfNotExists($_POST['form']['USR_UID'], array('USR_PASSWORD_HISTORY' => serialize(array($_POST['form']['USR_NEW_PASS'])))); + $aErrors = $oUserProperty->validatePassword($_POST['form']['USR_NEW_PASS'], $aUserProperty['USR_LAST_UPDATE_DATE'], $aUserProperty['USR_LOGGED_NEXT_TIME']); + if (count($aErrors) > 0) { + $sDescription = G::LoadTranslation('ID_POLICY_ALERT').':

    '; + foreach ($aErrors as $sError) { + switch ($sError) { + case 'ID_PPP_MINIMUN_LENGTH': + $sDescription .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MINIMUN_LENGTH . '
    '; + break; + case 'ID_PPP_MAXIMUN_LENGTH': + $sDescription .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MAXIMUN_LENGTH . '
    '; + break; + case 'ID_PPP_EXPIRATION_IN': + $sDescription .= ' - ' . G::LoadTranslation($sError).' ' . PPP_EXPIRATION_IN . ' ' . G::LoadTranslation('ID_DAYS') . '
    '; + break; + default: + $sDescription .= ' - ' . G::LoadTranslation($sError).'
    '; + break; + } + } + $sDescription .= '
    ' . G::LoadTranslation('ID_PLEASE_CHANGE_PASSWORD_POLICY'); + G::SendMessageText($sDescription, 'warning'); + G::header('Location: ' . $_SERVER['HTTP_REFERER']); + die; + } + $aHistory = unserialize($aUserProperty['USR_PASSWORD_HISTORY']); + if (!is_array($aHistory)) { + $aHistory = array(); + } + if (!defined('PPP_PASSWORD_HISTORY')) { + define('PPP_PASSWORD_HISTORY', 0); + } + if (PPP_PASSWORD_HISTORY > 0) { + if (count($aHistory) >= PPP_PASSWORD_HISTORY) { + array_shift($aHistory); + } + $aHistory[] = $_POST['form']['USR_NEW_PASS']; + } + $aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aUserProperty['USR_LOGGED_NEXT_TIME'] = 1; + $aUserProperty['USR_PASSWORD_HISTORY'] = serialize($aHistory); + $oUserProperty->update($aUserProperty); + } + } + $aData['USR_FIRSTNAME'] = $_POST['form']['USR_FIRSTNAME']; + $aData['USR_LASTNAME'] = $_POST['form']['USR_LASTNAME']; + $aData['USR_EMAIL'] = $_POST['form']['USR_EMAIL']; + $aData['USR_DUE_DATE'] = $_POST['form']['USR_DUE_DATE']; + $aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $RBAC->updateUser($aData); + $aData['USR_PASSWORD'] = md5($_POST['form']['USR_USERNAME']);//fake :p + $aData['USR_COUNTRY'] = $_POST['form']['USR_COUNTRY']; + $aData['USR_CITY'] = $_POST['form']['USR_CITY']; + $aData['USR_LOCATION'] = $_POST['form']['USR_LOCATION']; + $aData['USR_ADDRESS'] = $_POST['form']['USR_ADDRESS']; + $aData['USR_PHONE'] = $_POST['form']['USR_PHONE']; + $aData['USR_ZIP_CODE'] = $_POST['form']['USR_ZIP_CODE']; + $aData['USR_POSITION'] = $_POST['form']['USR_POSITION']; + if ($_POST['form']['USR_RESUME'] != '') { + $aData['USR_RESUME'] = $_POST['form']['USR_RESUME']; + } + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $oUser->update($aData); + if ($_FILES['form']['tmp_name']['USR_PHOTO'] != '') { + $aAux = explode('.', $_FILES['form']['name']['USR_PHOTO']); + G::uploadFile($_FILES['form']['tmp_name']['USR_PHOTO'], PATH_IMAGES_ENVIRONMENT_USERS, $aData['USR_UID'] . '.' . $aAux[1]); + G::resizeImage(PATH_IMAGES_ENVIRONMENT_USERS . $aData['USR_UID'] . '.' . $aAux[1], 96, 96, PATH_IMAGES_ENVIRONMENT_USERS . $aData['USR_UID'] . '.gif'); + } + if ($_FILES['form']['tmp_name']['USR_RESUME'] != '') { + G::uploadFile($_FILES['form']['tmp_name']['USR_RESUME'], PATH_IMAGES_ENVIRONMENT_FILES . $aData['USR_UID'] . '/', $_FILES['form']['name']['USR_RESUME']); + } + + /* Saving preferences */ + $def_lang = $_POST['form']['PREF_DEFAULT_LANG']; + $def_menu = $_POST['form']['PREF_DEFAULT_MENUSELECTED']; + $def_cases_menu = $_POST['form']['PREF_DEFAULT_CASES_MENUSELECTED']; + + G::loadClass('configuration'); + + $oConf = new Configurations; + $aConf = Array( + 'DEFAULT_LANG'=>$def_lang, + 'DEFAULT_MENU'=>$def_menu, + 'DEFAULT_CASES_MENU'=>$def_cases_menu + ); + + /*UPDATING SESSION VARIABLES*/ + $aUser = $RBAC->userObj->load($_SESSION['USER_LOGGED']); + $_SESSION['USR_FULLNAME'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + + + $oConf->aConfig = $aConf; + $oConf->saveConfig('USER_PREFERENCES', '', '',$_SESSION['USER_LOGGED']); + + G::SendTemporalMessage('ID_CHANGES_SAVED', 'info', 'labels'); + G::header('location: myInfo'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Ajax.php b/workflow/engine/methods/users/users_Ajax.php new file mode 100644 index 000000000..8b7a16f55 --- /dev/null +++ b/workflow/engine/methods/users/users_Ajax.php @@ -0,0 +1,158 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_LOGIN')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + G::LoadInclude('ajax'); + if (isset($_POST['form'])) + { + $_POST = $_POST['form']; + } + $_POST['function'] = get_ajax_value('function'); + switch ($_POST['function']) + { + case 'verifyUsername': + //print_r($_POST); die; + $_POST['sOriginalUsername'] = get_ajax_value('sOriginalUsername'); + $_POST['sUsername'] = get_ajax_value('sUsername'); + if ($_POST['sOriginalUsername'] == $_POST['sUsername']) + { + echo '0'; + } + else + { + require_once 'classes/model/Users.php'; + G::LoadClass('Users'); + $oUser = new Users(); + $oCriteria=$oUser->loadByUsername($_POST['sUsername']); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + //print_r($aRow); die; + //if (!$aRow) + if (!is_array($aRow)) + { + echo '0'; + } + else + { + echo '1'; + } + } + break; + case 'availableUsers': + G::LoadClass('processMap'); + $oProcessMap = new ProcessMap(); + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('propeltable', 'paged-table', 'users/users_AvailableUsers', $oProcessMap->getAvailableUsersCriteria($_GET['sTask'], $_GET['iType'])); + G::RenderPage('publish', 'raw'); + break; + case 'assign': + G::LoadClass('tasks'); + $oTasks = new Tasks(); + switch ((int)$_POST['TU_RELATION']) { + case 1: + echo $oTasks->assignUser($_POST['TAS_UID'], $_POST['USR_UID'], $_POST['TU_TYPE']); + break; + case 2: + echo $oTasks->assignGroup($_POST['TAS_UID'], $_POST['USR_UID'], $_POST['TU_TYPE']); + break; + } + break; + case 'ofToAssign': + G::LoadClass('tasks'); + $oTasks = new Tasks(); + switch ((int)$_POST['TU_RELATION']) { + case 1: + echo $oTasks->ofToAssignUser($_POST['TAS_UID'], $_POST['USR_UID'], $_POST['TU_TYPE']); + break; + case 2: + echo $oTasks->ofToAssignGroup($_POST['TAS_UID'], $_POST['USR_UID'], $_POST['TU_TYPE']); + break; + } + break; + case 'changeView': + $_SESSION['iType'] = $_POST['TU_TYPE']; + break; + + case 'deleteGroup': + G::LoadClass('groups'); + $oGroup = new Groups(); + $oGroup->removeUserOfGroup($_POST['GRP_UID'], $_POST['USR_UID']); + $_GET['sUserUID'] = $_POST['USR_UID']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'users/users_Tree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'showUserGroupInterface': + $_GET['sUserUID'] = $_POST['sUserUID']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'users/users_AssignGroup' ); + G::RenderPage('publish', 'raw'); + break; + + case 'showUserGroups': + $_GET['sUserUID'] = $_POST['sUserUID']; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'users/users_Tree' ); + G::RenderPage('publish', 'raw'); + break; + + case 'assignUserToGroup': + G::LoadClass('groups'); + $oGroup = new Groups(); + $oGroup->addUserToGroup($_POST['GRP_UID'], $_POST['USR_UID']); + echo '

    '.G::LoadTranslation('ID_MSG_ASSIGN_DONE').'

    '; + break; + + case 'usersGroup': + G::LoadClass('groups'); + $oGroup = new Groups(); + $aGroup = $oGroup->getUsersOfGroup($_POST['GRP_UID']); + foreach ($aGroup as $iIndex => $aValues) { + echo $aValues['USR_FIRSTNAME'] . ' ' . $aValues['USR_LASTNAME'] . '
    '; + } + break; + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_AuthSource.php b/workflow/engine/methods/users/users_AuthSource.php new file mode 100644 index 000000000..fdaa04e77 --- /dev/null +++ b/workflow/engine/methods/users/users_AuthSource.php @@ -0,0 +1,39 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$G_MAIN_MENU = 'processmaker'; +//$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +//$G_ID_SUB_MENU_SELECTED = '-'; + +$G_PUBLISH = new Publisher(); +$G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_AuthSource', '', $RBAC->load($_GET['USR_UID']), '../users/users_AuthSourceSave'); +G::RenderPage('publish','blank'); \ No newline at end of file diff --git a/workflow/engine/methods/users/users_AuthSourceSave.php b/workflow/engine/methods/users/users_AuthSourceSave.php new file mode 100644 index 000000000..8eeccf5e9 --- /dev/null +++ b/workflow/engine/methods/users/users_AuthSourceSave.php @@ -0,0 +1,46 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +global $RBAC; +if ($RBAC->userCanAccess('PM_SETUP_ADVANCE') != 1) { + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; +} + +$aData = $RBAC->load($_POST['form']['USR_UID']); +unset($aData['USR_ROLE']); +if ($_POST['form']['UID_AUTH_SOURCE'] == 'MYSQL') { + $aData['USR_AUTH_TYPE'] = 'MYSQL'; + $aData['UID_AUTH_SOURCE'] = ''; +} +else { + $aFields = $RBAC->getAuthSource($_POST['form']['UID_AUTH_SOURCE']); + $aData['USR_AUTH_TYPE'] = $aFields['AUTH_SOURCE_PROVIDER']; + $aData['UID_AUTH_SOURCE'] = $_POST['form']['UID_AUTH_SOURCE']; +} +$aData['USR_AUTH_USER_DN'] = $_POST['form']['USR_AUTH_USER_DN']; +$RBAC->updateUser($aData); + +G::header('location: users_List'); \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Delete.php b/workflow/engine/methods/users/users_Delete.php new file mode 100644 index 000000000..4572ed101 --- /dev/null +++ b/workflow/engine/methods/users/users_Delete.php @@ -0,0 +1,73 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + if ($_GET['USR_UID'] == '00000000000000000000000000000001') { + G::SendTemporalMessage('ID_CANNOT_CHANGE_STATUS_ADMIN_USER', 'error', 'usersLabels'); + G::header('location: ' . $_SERVER['HTTP_REFERER']); + die; + } + /*$RBAC->removeUser($_GET['USR_UID']); + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $oUser->remove($_GET['USR_UID']);*/ + + //print_r($_GET['USR_UID']); die + G::LoadClass('tasks'); + $oTasks = new Tasks(); + $oTasks->ofToAssignUserOfAllTasks($_GET['USR_UID']); + G::LoadClass('groups'); + $oGroups = new Groups(); + $oGroups->removeUserOfAllGroups($_GET['USR_UID']); + $RBAC->changeUserStatus($_GET['USR_UID'], 'CLOSED'); + $_GET['USR_USERNAME']=''; + $RBAC->updateUser(array('USR_UID' => $_GET['USR_UID'], 'USR_USERNAME' => $_GET['USR_USERNAME']),''); + + + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $aFields = $oUser->load($_GET['USR_UID']); + $aFields['USR_STATUS'] = 'CLOSED'; + $aFields['USR_USERNAME'] = ''; + $oUser->update($aFields); + G::header('location: users_List'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_DeleteAssign.php b/workflow/engine/methods/users/users_DeleteAssign.php new file mode 100644 index 000000000..c228b6d11 --- /dev/null +++ b/workflow/engine/methods/users/users_DeleteAssign.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $USR_UID=$_GET['USR_UID']; + + G::LoadClass('case'); + $oProcessMap = new Cases(); + + $c = $oProcessMap->getCriteriaUsersCases('TO_DO', $USR_UID); + $array["TO_DO"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaUsersCases('COMPLETED', $USR_UID); + $array["COMPLETED"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaUsersCases('DRAFT', $USR_UID); + $array["DRAFT"] = ApplicationPeer::doCount($c); + + $c = $oProcessMap->getCriteriaUsersCases('CANCELLED', $USR_UID); + $array["CANCELLED"] = ApplicationPeer::doCount($c); + + $array["USR_UID"]=$USR_UID; + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_DeleteAssign', '', $array, ''); + G::RenderPage('publish', 'raw'); + +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_DeleteReassign.php b/workflow/engine/methods/users/users_DeleteReassign.php new file mode 100644 index 000000000..68af07477 --- /dev/null +++ b/workflow/engine/methods/users/users_DeleteReassign.php @@ -0,0 +1,164 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + if (!isset($_GET['USR_UID'])) { + $_GET['USR_UID'] = ''; + } + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'USERS'; + $G_PUBLISH = new Publisher; + + if ($_GET['USR_UID'] != '') { + $c=0; + $oTemplatePower = new TemplatePower(PATH_TPL . 'users/users_DeleteReassign.html'); + $oTemplatePower->prepare(); + G::LoadClass('tasks'); + G::LoadClass('groups'); + $oTasks = new Tasks(); + $oGroups = new Groups(); + $oUser = new Users(); + G::LoadClass('case'); + $oCases = new Cases(); + $USR_UID=$_GET['USR_UID']; + list($oCriteriaToDo,$sXMLFile) = $oCases->getConditionCasesList('to_do', $_GET['USR_UID']); + list($oCriteriaDraft,$sXMLFile) = $oCases->getConditionCasesList('draft', $_GET['USR_UID']); + + if(ApplicationPeer::doCount($oCriteriaToDo)==0 && ApplicationPeer::doCount($oCriteriaDraft)==0); + G::header('location: users_Delete?USR_UID='.$USR_UID); + + $oDataset = ApplicationPeer::doSelectRS($oCriteriaToDo); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $c++; + $oTemplatePower->newBlock('cases'); + $aKeys = array_keys($aRow); + foreach ($aKeys as $sKey) { + $oTemplatePower->assign($sKey, $aRow[$sKey]); + } + $aUsers = array($_GET['USR_UID']); + $aAux1 = $oTasks->getGroupsOfTask($aRow['TAS_UID'], 1); + foreach ($aAux1 as $aGroup) { + $aAux2 = $oGroups->getUsersOfGroup($aGroup['GRP_UID']); + foreach ($aAux2 as $aUser) { + if (!in_array($aUser['USR_UID'], $aUsers)) { + $aUsers[] = $aUser['USR_UID']; + $aData = $oUser->load($aUser['USR_UID']); + $oTemplatePower->newBlock('users'); + $oTemplatePower->assign('USR_UID', $aUser['USR_UID']); + $oTemplatePower->assign('USR_FULLNAME', $aData['USR_FIRSTNAME'] . ' ' . $aData['USR_LASTNAME'] . ' (' . $aData['USR_USERNAME'] . ')'); + } + } + } + $aAux1 = $oTasks->getUsersOfTask($aRow['TAS_UID'], 1); + foreach ($aAux1 as $aUser) { + if (!in_array($aUser['USR_UID'], $aUsers)) { + $aUsers[] = $aUser['USR_UID']; + $aData = $oUser->load($aUser['USR_UID']); + $oTemplatePower->newBlock('users'); + $oTemplatePower->assign('USR_UID', $aUser['USR_UID']); + $oTemplatePower->assign('USR_FULLNAME', $aData['USR_FIRSTNAME'] . ' ' . $aData['USR_LASTNAME'] . ' (' . $aData['USR_USERNAME'] . ')'); + } + } + $oTemplatePower->gotoBlock('cases'); + $oTemplatePower->assign('ID_STATUS', G::LoadTranslation('ID_TO_DO')); + $oTemplatePower->assign('ID_NO_REASSIGN', G::LoadTranslation('ID_NO_REASSIGN')); + $oDataset->next(); + } + $oDataset = ApplicationPeer::doSelectRS($oCriteriaDraft); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $c++; + $oTemplatePower->newBlock('cases'); + $aKeys = array_keys($aRow); + foreach ($aKeys as $sKey) { + $oTemplatePower->assign($sKey, $aRow[$sKey]); + } + $aUsers = array($_GET['USR_UID']); + $aAux1 = $oTasks->getGroupsOfTask($aRow['TAS_UID'], 1); + foreach ($aAux1 as $aGroup) { + $aAux2 = $oGroups->getUsersOfGroup($aGroup['GRP_UID']); + foreach ($aAux2 as $aUser) { + if (!in_array($aUser['USR_UID'], $aUsers)) { + $aUsers[] = $aUser['USR_UID']; + $aData = $oUser->load($aUser['USR_UID']); + $oTemplatePower->newBlock('users'); + $oTemplatePower->assign('USR_UID', $aUser['USR_UID']); + $oTemplatePower->assign('USR_FULLNAME', $aData['USR_FIRSTNAME'] . ' ' . $aData['USR_LASTNAME'] . ' (' . $aData['USR_USERNAME'] . ')'); + } + } + } + $aAux1 = $oTasks->getUsersOfTask($aRow['TAS_UID'], 1); + foreach ($aAux1 as $aUser) { + if (!in_array($aUser['USR_UID'], $aUsers)) { + $aUsers[] = $aUser['USR_UID']; + $aData = $oUser->load($aUser['USR_UID']); + $oTemplatePower->newBlock('users'); + $oTemplatePower->assign('USR_UID', $aUser['USR_UID']); + $oTemplatePower->assign('USR_FULLNAME', $aData['USR_FIRSTNAME'] . ' ' . $aData['USR_LASTNAME'] . ' (' . $aData['USR_USERNAME'] . ')'); + } + } + $oTemplatePower->gotoBlock('cases'); + $oTemplatePower->assign('ID_STATUS', G::LoadTranslation('ID_DRAFT')); + $oTemplatePower->assign('ID_NO_REASSIGN', G::LoadTranslation('ID_NO_REASSIGN')); + $oDataset->next(); + } + $oTemplatePower->gotoBlock('_ROOT'); + $oTemplatePower->assign('ID_NUMBER', '#'); + $oTemplatePower->assign('ID_CASE', G::LoadTranslation('ID_CASE')); + $oTemplatePower->assign('ID_TASK', G::LoadTranslation('ID_TASK')); + $oTemplatePower->assign('ID_PROCESS', G::LoadTranslation('ID_PROCESS')); + $oTemplatePower->assign('ID_STATUS', G::LoadTranslation('ID_STATUS')); + $oTemplatePower->assign('ID_REASSIGN_TO', G::LoadTranslation('ID_REASSIGN_TO')); + $oTemplatePower->assign('ID_REASSIGN', G::LoadTranslation('ID_REASSIGN')); + $oTemplatePower->assign('USR_UID', $_GET['USR_UID']); + $oTemplatePower->assign('CONT', $c); + $G_PUBLISH->AddContent('template', '', '', '', $oTemplatePower); + } + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_DeleteReassignEnd.php b/workflow/engine/methods/users/users_DeleteReassignEnd.php new file mode 100644 index 000000000..06f85f2c7 --- /dev/null +++ b/workflow/engine/methods/users/users_DeleteReassignEnd.php @@ -0,0 +1,90 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_REASSIGNCASE')) { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + G::LoadClass('case'); + $oCase = new Cases(); + $aCases = array(); + $aUsers = array(); + $c=0; + if(isset($_POST['USERS'])) + { if (is_array($_POST['USERS'])) { + foreach ($_POST['USERS'] as $sKey => $sUser) { + if ($sUser != '') { + $c++; + $oCase->reassignCase($_POST['APPLICATIONS'][$sKey], $_POST['INDEXES'][$sKey], $_POST['USR_UID'], $sUser); + $aCases[] = $_POST['APPLICATIONS'][$sKey]; + $aUsers[] = $sUser; + } + } + } + } + G::LoadClass('case'); + $oCase = new Cases(); + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $sText = ''; + foreach ($aCases as $sKey => $sCase) { + $aCase = $oCase->loadCase($sCase); + $aUser = $oUser->load($aUsers[$sKey]); + $sText .= $aCase['TITLE'] . ' => ' . $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME'] . ' (' . $aUser['USR_USERNAME'] . ')' . '
    '; + } + + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'USERS'; + $G_PUBLISH = new Publisher; + + $aMessage['USR_UID'] = $_POST['USR_UID']; + + $aMessage['MESSAGE'] = $sText; + if($_POST['CONT']!=$c) + $aMessage['EVA']=G::LoadTranslation('ID_CASESREASSIGN');// + else + $aMessage['EVA']=''; + + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_ReassignShowInfo', '', $aMessage); + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Edit.php b/workflow/engine/methods/users/users_Edit.php new file mode 100644 index 000000000..694aea025 --- /dev/null +++ b/workflow/engine/methods/users/users_Edit.php @@ -0,0 +1,144 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + $RBAC->requirePermissions('PM_USERS'); + + // deprecated the class XmlForm_Field_Image is currently part of the class.xmlform.php package + // the use of the external xmlfield_Image is highly discouraged + if (!class_exists('XmlForm_Field_Image')){ + G::LoadClass('xmlfield_Image'); + } + require_once 'classes/model/Users.php'; + require_once 'classes/model/Department.php'; + + $_SESSION['CURRENT_USER'] = $_GET['USR_UID']; + $oUser = new Users(); + $aFields = $oUser->load($_GET['USR_UID']); + $aFields['USR_PASSWORD'] = '********'; + $aFields['MESSAGE0'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_USER_REGISTERED')) . '!'; + $aFields['MESSAGE1'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME')); + $aFields['MESSAGE2'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_DUE_DATE')); + $aFields['MESSAGE3'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS')); + $aFields['MESSAGE4'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME')); + $aFields['MESSAGE5'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME')); + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'USERS'; + + $G_PUBLISH = new Publisher; + + //getting the user and department + $oDepInfo = new Department(); + $oUser = UsersPeer::retrieveByPk( $aFields['USR_REPORTS_TO'] ); + if ( get_class ($oUser) == 'Users' ) { + $userFields = $oUser->toArray(BasePeer::TYPE_FIELDNAME); + $aFields['USR_REPORTS_TO'] = $userFields['USR_FIRSTNAME'] . ' ' . $userFields['USR_LASTNAME']; + try { + $depFields = $oDepInfo->load($userFields['DEP_UID'] ); + $aFields['USR_REPORTS_TO'] .= " (" . $depFields['DEPO_TITLE'] . ")"; + } + catch( Exception $e ) { + } + } + else{ + $aFields['USR_REPORTS_TO'] = ' '; + } + + try { + $depFields = $oDepInfo->load($aFields['DEP_UID']); + $aFields['USR_DEPARTMENT'] = $depFields['DEPO_TITLE']; + } + catch( Exception $e ) { + $oUser = UsersPeer::retrieveByPk( $_GET['USR_UID'] ); + $oUser->setDepUid( '' ); + $oUser->save(); + } + + //Load Calendar options and falue for this user + G::LoadClass ( 'calendar' ); + $calendar = new Calendar ( ); + $calendarObj = $calendar->getCalendarList ( true, true ); + global $_DBArray; + $_DBArray ['availableCalendars'] = $calendarObj ['array']; + $_SESSION ['_DBArray'] = $_DBArray; + $calendarInfo = $calendar->getCalendarFor ( $_GET['USR_UID'], $_GET['USR_UID'], $_GET['USR_UID'] ); + //If the function returns a DEFAULT calendar it means that this object doesn't have assigned any calendar + $aFields ['USR_CALENDAR'] = $calendarInfo ['CALENDAR_APPLIED']!='DEFAULT'? $calendarInfo ['CALENDAR_UID']:""; + $aFields['RANDOM'] = rand(); + + ///////////////////////// + //SELECT USR_UID, CONCAT(USR_LASTNAME, " ", USR_FIRSTNAME) FROM USERS WHERE USR_STATUS = 1 AND USR_UID!= "@#USR_UID" ORDER BY USR_LASTNAME + require_once 'classes/model/Users.php'; + $oCriteria=new Criteria(); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_USERNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_EMAIL); + $oCriteria->add(UsersPeer::USR_STATUS,'ACTIVE'); + $oCriteria->add(UsersPeer::USR_UID,$_GET['USR_UID'], Criteria::NOT_EQUAL); + $oDataset=UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + /////////////////////// + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($obj, 'ENVIRONMENT_SETTINGS',''); + + $defaultOption = isset($oConf->aConfig['format'])? $oConf->aConfig['format']: ''; + + $aUserInfo = array(); + $aUserInfo[] = array('USR_UID' => 'char','USER_FULLNAME' => 'char'); + while( $oDataset->next()){ + $aRow1 = $oDataset->getRow(); + + $infoUser = G::getFormatUserList($defaultOption,$aRow1); + $aUserInfo[]=array( + 'USR_UID' => $aRow1['USR_UID'], + 'USER_FULLNAME' => $infoUser + ); + } + //print_r($aUserInfo); + global $_DBArray; + $_DBArray['aUserInfo'] = $aUserInfo; + $_SESSION['_DBArray'] = $_DBArray; + + //always show this form users_EditRT.xml. + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_EditRT.xml', '', $aFields, 'users_Save?USR_UID=' . $_SESSION['CURRENT_USER']); + //if (isset($aFields['DEP_UID']) && isset($aFields['USR_REPORTS_TO']) && $aFields['DEP_UID']!='' && $aFields['USR_REPORTS_TO']!='') + // $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_EditRT.xml', '', $aFields, 'users_Save?USR_UID=' . $_SESSION['CURRENT_USER']); + //else + // $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_Edit.xml', '', $aFields, 'users_Save?USR_UID=' . $_SESSION['CURRENT_USER']); + + G::RenderPage('publish','blank'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Groups.php b/workflow/engine/methods/users/users_Groups.php new file mode 100644 index 000000000..5545c4fc0 --- /dev/null +++ b/workflow/engine/methods/users/users_Groups.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is a callback for the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) { + case - 2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case - 1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('view', 'users/users_Tree' ); + G::RenderPage('publish', 'raw'); +} +catch (exception $oException) { + die($oException->getMessage()); +} +?> + diff --git a/workflow/engine/methods/users/users_List.php b/workflow/engine/methods/users/users_List.php new file mode 100644 index 000000000..8f0bfd1ca --- /dev/null +++ b/workflow/engine/methods/users/users_List.php @@ -0,0 +1,80 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; +global $RBAC; + +$access = $RBAC->userCanAccess('PM_USERS'); +if( $access != 1 ){ + switch ($access) + { + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + default: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } +} +$G_MAIN_MENU = 'processmaker'; +$G_SUB_MENU = 'users'; +$G_ID_MENU_SELECTED = 'USERS'; +$G_ID_SUB_MENU_SELECTED = 'USERS'; + +$sDelimiter = DBAdapter::getStringDelimiter(); +require_once 'classes/model/Users.php'; +$oCriteria = new Criteria('workflow'); +$oCriteria->addSelectColumn(UsersPeer::USR_UID); + +$sDataBase = 'database_' . strtolower(DB_ADAPTER); +if(G::LoadSystemExist($sDataBase)){ + G::LoadSystem($sDataBase); + $oDataBase = new database(); + $oCriteria->addAsColumn('USR_COMPLETENAME', $oDataBase->concatString("USR_LASTNAME", "' '", "USR_FIRSTNAME")); +} + +$oCriteria->addSelectColumn(UsersPeer::USR_USERNAME); +$oCriteria->addSelectColumn(UsersPeer::USR_EMAIL); +$oCriteria->addSelectColumn(UsersPeer::USR_ROLE); +$oCriteria->addSelectColumn(UsersPeer::USR_DUE_DATE); +$oCriteria->addAsColumn('USR_VIEW', $sDelimiter . G::LoadTranslation('ID_DETAIL') . $sDelimiter); +$oCriteria->addAsColumn('USR_EDIT', $sDelimiter . G::LoadTranslation('ID_EDIT') . $sDelimiter); +$oCriteria->addAsColumn('USR_DELETE', $sDelimiter . G::LoadTranslation('ID_DELETE') . $sDelimiter); +$oCriteria->addAsColumn('USR_AUTH', $sDelimiter . G::LoadTranslation('ID_AUTHENTICATION') . $sDelimiter); +$oCriteria->addAsColumn('USR_REASSIGN', $sDelimiter . G::LoadTranslation('ID_REASSIGN_CASES') . $sDelimiter); +$oCriteria->add(UsersPeer::USR_STATUS, array('CLOSED'), Criteria::NOT_IN); + +$G_PUBLISH = new Publisher; +$G_PUBLISH->AddContent('propeltable', 'paged-table', 'users/users_List', $oCriteria, array('CONFIRM' => G::LoadTranslation('ID_MSG_CONFIRM_DELETE_USER'))); +G::RenderPage('publish', 'blank'); + diff --git a/workflow/engine/methods/users/users_New.php b/workflow/engine/methods/users/users_New.php new file mode 100644 index 000000000..ab2e90ce6 --- /dev/null +++ b/workflow/engine/methods/users/users_New.php @@ -0,0 +1,102 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + $RBAC->requirePermissions('PM_USERS'); + + $aFields['MESSAGE0'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_USER_REGISTERED')) . '!'; + $aFields['MESSAGE1'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME')); + $aFields['MESSAGE2'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_DUE_DATE')); + $aFields['MESSAGE3'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS')); + $aFields['MESSAGE4'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME')); + $aFields['MESSAGE5'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME')); + // the default role variable sets the value that will be showed as the default for the role field. + $aFields['DEFAULT_ROLE'] = 'PROCESSMAKER_OPERATOR'; + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['USR_DUE_DATE']= date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 1)); + + //Load Calendar options and falue for this user + G::LoadClass ( 'calendar' ); + $calendar = new Calendar ( ); + $calendarObj = $calendar->getCalendarList ( true, true ); + global $_DBArray; + $_DBArray ['availableCalendars'] = $calendarObj ['array']; + $_SESSION ['_DBArray'] = $_DBArray; + +// $G_MAIN_MENU = 'processmaker'; +// $G_ID_MENU_SELECTED = 'USERS'; + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = 'USERS'; + +///////////////////////////// +//SELECT USR_UID, CONCAT(USR_LASTNAME, " ", USR_FIRSTNAME) FROM USERS WHERE USR_STATUS = 1 ORDER BY USR_LASTNAME + require_once 'classes/model/Users.php'; + $oCriteria=new Criteria(); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + $oCriteria->addSelectColumn(UsersPeer::USR_USERNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_EMAIL); + $oCriteria->add(UsersPeer::USR_STATUS,'ACTIVE'); + //$oCriteria->add(UsersPeer::USR_UID,$_GET['USR_UID'], Criteria::NOT_EQUAL); + $oDataset=UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + /////////////////////// + G::loadClass('configuration'); + $oConf = new Configurations; + $oConf->loadConfig($obj, 'ENVIRONMENT_SETTINGS',''); + + $defaultOption = isset($oConf->aConfig['format'])? $oConf->aConfig['format']: ''; + + $aUserInfo = array(); + $aUserInfo[] = array('USR_UID' => 'char','USER_FULLNAME' => 'char'); + while( $oDataset->next()){ + $aRow1 = $oDataset->getRow(); + + $infoUser = G::getFormatUserList($defaultOption,$aRow1); + $aUserInfo[]=array( + 'USR_UID' => $aRow1['USR_UID'], + 'USER_FULLNAME' => $infoUser + ); + } + //print_r($aUserInfo); + global $_DBArray; + $_DBArray['aUserInfo'] = $aUserInfo; + $_SESSION['_DBArray'] = $_DBArray; +///////////////////////////// + + + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_New.xml', '', $aFields, 'users_Save'); + G::RenderPage('publish','blank'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Reassign.php b/workflow/engine/methods/users/users_Reassign.php new file mode 100644 index 000000000..fa6f4f100 --- /dev/null +++ b/workflow/engine/methods/users/users_Reassign.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + G::LoadClass('case'); + $oCase = new Cases(); + foreach($_POST['USER'] as $sProcessUID => $sUserUID) { + if ($sUserUID != '') { + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::APP_UID); + $oCriteria->addSelectColumn(AppDelegationPeer::DEL_INDEX); + $oCriteria->add(AppDelegationPeer::PRO_UID, $sProcessUID); + $oCriteria->add(AppDelegationPeer::USR_UID, $_POST['USR_UID']); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $oCase->reassignCase($aRow['APP_UID'], $aRow['DEL_INDEX'], $_SESSION['USER_LOGGED'], $sUserUID); + $oDataset->next(); + } + } + } +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_ReassignCases.php b/workflow/engine/methods/users/users_ReassignCases.php new file mode 100644 index 000000000..bd598e5bf --- /dev/null +++ b/workflow/engine/methods/users/users_ReassignCases.php @@ -0,0 +1,119 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $G_PUBLISH; + $G_PUBLISH = new Publisher(); + $_GET['iStep'] = (int)$_GET['iStep']; + switch ($_GET['iStep']) { + case 1: + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_ReassignSelectType', '', array('USR_UID' => $_GET['USR_UID']), ''); + break; + case 2: + switch ($_POST['TYPE']) { + case 'ANY_USER': + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_ReassignSelectSubType', '', $_POST, ''); + break; + } + break; + case 3: + switch ($_POST['SUB_TYPE']) { + case 'PROCESS': + require_once 'classes/model/Users.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(UsersPeer::USR_UID); + /* + $usr_completename_col = "CONCAT(USR_LASTNAME, ' ', USR_FIRSTNAME, ' (', USR_USERNAME, ')')"; + */ + $sDataBase = 'database_' . strtolower(DB_ADAPTER); + if(G::LoadSystemExist($sDataBase)){ + G::LoadSystem($sDataBase); + $oDataBase = new database(); + $usr_completename_col = $oDataBase->concatString("USR_LASTNAME", "' '", "USR_FIRSTNAME", " '('", "USR_USERNAME", "')'"); + } + + $oCriteria->addAsColumn('USR_COMPLETENAME', $usr_completename_col); + + $oCriteria->add(UsersPeer::USR_UID, $_POST['USR_UID'], Criteria::NOT_EQUAL); + $oCriteria->add(UsersPeer::USR_STATUS, array('CLOSED'), Criteria::NOT_IN); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $sUsers = ''; + while ($aRow = $oDataset->getRow()) { + $sUsers .= ''; + $oDataset->next(); + } + $aProcesses = array(); + $aProcesses[] = array('CHECKBOX' => 'char', + 'PROCESS' => 'char', + 'CANTITY' => 'char', + 'USERS' => 'char'); + $del = DBAdapter::getStringDelimiter(); + require_once 'classes/model/AppDelegation.php'; + $oCriteria = new Criteria('workflow'); + $oCriteria->addSelectColumn(AppDelegationPeer::PRO_UID); + $oCriteria->addSelectColumn('COUNT(' . AppDelegationPeer::PRO_UID . ') AS CANTITY'); + $oCriteria->addAsColumn('PRO_TITLE', ContentPeer::CON_VALUE); + $aConditions = array(); + $aConditions[] = array(AppDelegationPeer::PRO_UID, ContentPeer::CON_ID); + $aConditions[] = array(ContentPeer::CON_CATEGORY, $del . 'PRO_TITLE' . $del); + $aConditions[] = array(ContentPeer::CON_LANG, $del . SYS_LANG . $del); + $oCriteria->addJoinMC($aConditions, Criteria::LEFT_JOIN); + $oCriteria->add(AppDelegationPeer::USR_UID, $_POST['USR_UID']); + $oCriteria->add(AppDelegationPeer::DEL_FINISH_DATE, null, Criteria::ISNULL); + $oCriteria->addGroupByColumn(AppDelegationPeer::PRO_UID); + + /* + * Adding grouped by standardization. + */ + $oCriteria->addGroupByColumn(ContentPeer::CON_VALUE); + + $oDataset = AppDelegationPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $aProcesses[] = array('CHECKBOX' => '', + 'PROCESS' => $aRow['PRO_TITLE'], + 'CANTITY' => $aRow['CANTITY'], + 'USERS' => ''); + $oDataset->next(); + } + global $_DBArray; + $_DBArray['processesToReassign'] = $aProcesses; + $_SESSION['_DBArray'] = $_DBArray; + G::LoadClass('ArrayPeer'); + $oCriteria = new Criteria('dbarray'); + $oCriteria->setDBArrayTable('processesToReassign'); + $G_PUBLISH->AddContent('propeltable', 'cases/paged-table-reassign', 'users/users_ReassignCases', $oCriteria, $_POST); + break; + } + break; + } + G::RenderPage('publish', 'raw'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_Save.php b/workflow/engine/methods/users/users_Save.php new file mode 100644 index 000000000..1e119e8ec --- /dev/null +++ b/workflow/engine/methods/users/users_Save.php @@ -0,0 +1,286 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + if ( empty($_POST) || !isset($_POST['form'])) { + throw ( new Exception ('Posted data is empty!') ); + } + + $form = $_POST['form']; + + if ( isset($_GET['USR_UID'])) { + $form['USR_UID'] = $_GET['USR_UID']; + } + else { + $form['USR_UID'] = ''; + } + + if ( isset($_FILES['form']['name']['USR_RESUME']) ) { + if ($_FILES['form']['tmp_name']['USR_RESUME'] != '') { + $form['USR_RESUME'] = $_FILES['form']['name']['USR_RESUME']; + } + else { + $form['USR_RESUME'] = ''; + } + } + + if (!isset($form['USR_NEW_PASS'])) { + $form['USR_NEW_PASS'] = ''; + } + if ($form['USR_NEW_PASS'] != '') { + $form['USR_PASSWORD'] = md5($form['USR_NEW_PASS']); + } + if (!isset($form['USR_CITY'])) { + $form['USR_CITY'] = ''; + } + if (!isset($form['USR_LOCATION'])) { + $form['USR_LOCATION'] = ''; + } + if ($form['USR_UID'] == '') { + $aData['USR_USERNAME'] = $form['USR_USERNAME']; + $aData['USR_PASSWORD'] = $form['USR_PASSWORD']; + $aData['USR_FIRSTNAME'] = $form['USR_FIRSTNAME']; + $aData['USR_LASTNAME'] = $form['USR_LASTNAME']; + $aData['USR_EMAIL'] = $form['USR_EMAIL']; + $aData['USR_DUE_DATE'] = $form['USR_DUE_DATE']; + $aData['USR_CREATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aData['USR_BIRTHDAY'] = date('Y-m-d'); + //fixing bug in inactive user when the admin create a new user. + $statusWF = $form['USR_STATUS']; + $aData['USR_STATUS'] = $form['USR_STATUS'] == 'ACTIVE' ? 1 : 0; + $sUserUID = $RBAC->createUser($aData, $form['USR_ROLE'] ); + $aData['USR_STATUS'] = $statusWF; + $aData['USR_UID'] = $sUserUID; + $aData['USR_PASSWORD'] = md5($sUserUID);//fake :p + $aData['USR_COUNTRY'] = $form['USR_COUNTRY']; + $aData['USR_CITY'] = $form['USR_CITY']; + $aData['USR_LOCATION'] = $form['USR_LOCATION']; + $aData['USR_ADDRESS'] = $form['USR_ADDRESS']; + $aData['USR_PHONE'] = $form['USR_PHONE']; + $aData['USR_ZIP_CODE'] = $form['USR_ZIP_CODE']; + $aData['USR_POSITION'] = $form['USR_POSITION']; + $aData['USR_RESUME'] = $form['USR_RESUME']; + $aData['USR_ROLE'] = $form['USR_ROLE']; + $aData['USR_REPLACED_BY'] = $form['USR_REPLACED_BY']; + + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $oUser->create($aData); + if ($_FILES['form']['error']['USR_PHOTO'] != 1) { + if ($_FILES['form']['tmp_name']['USR_PHOTO'] != '') { + G::uploadFile($_FILES['form']['tmp_name']['USR_PHOTO'], PATH_IMAGES_ENVIRONMENT_USERS, $sUserUID . '.gif'); + } + } + else { + G::SendTemporalMessage ('ID_FILE_TOO_BIG', 'error'); + } + if ($_FILES['form']['error']['USR_RESUME'] != 1) { + if ($_FILES['form']['tmp_name']['USR_RESUME'] != '') { + G::uploadFile($_FILES['form']['tmp_name']['USR_RESUME'], PATH_IMAGES_ENVIRONMENT_FILES . $sUserUID . '/', $_FILES['form']['name']['USR_RESUME']); + } + } + else { + G::SendTemporalMessage ('ID_FILE_TOO_BIG', 'error'); + } + } + else { + $aData['USR_UID'] = $form['USR_UID']; + $aData['USR_USERNAME'] = $form['USR_USERNAME']; + + if (isset($form['USR_PASSWORD'])) { + if ($form['USR_PASSWORD'] != '') { + $aData['USR_PASSWORD'] = $form['USR_PASSWORD']; + require_once 'classes/model/UsersProperties.php'; + $oUserProperty = new UsersProperties(); + $aUserProperty = $oUserProperty->loadOrCreateIfNotExists($form['USR_UID'], array('USR_PASSWORD_HISTORY' => serialize(array($form['USR_PASSWORD'])))); + + $RBAC->loadUserRolePermission( 'PROCESSMAKER', $_SESSION['USER_LOGGED'] ); + if( $RBAC->aUserInfo[ 'PROCESSMAKER' ]['ROLE']['ROL_CODE']=='PROCESSMAKER_ADMIN'){ + $aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aUserProperty['USR_LOGGED_NEXT_TIME'] = 1; + $oUserProperty->update($aUserProperty); + } + + $aErrors = $oUserProperty->validatePassword($form['USR_NEW_PASS'], $aUserProperty['USR_LAST_UPDATE_DATE'], 0); + if (count($aErrors) > 0) { + $sDescription = G::LoadTranslation('ID_POLICY_ALERT').':

    '; + foreach ($aErrors as $sError) { + switch ($sError) { + case 'ID_PPP_MINIMUN_LENGTH': + $sDescription .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MINIMUN_LENGTH . '
    '; + break; + case 'ID_PPP_MAXIMUN_LENGTH': + $sDescription .= ' - ' . G::LoadTranslation($sError).': ' . PPP_MAXIMUN_LENGTH . '
    '; + break; + case 'ID_PPP_EXPIRATION_IN': + $sDescription .= ' - ' . G::LoadTranslation($sError).' ' . PPP_EXPIRATION_IN . ' ' . G::LoadTranslation('ID_DAYS') . '
    '; + break; + default: + $sDescription .= ' - ' . G::LoadTranslation($sError).'
    '; + break; + } + } + $sDescription .= '
    ' . G::LoadTranslation('ID_PLEASE_CHANGE_PASSWORD_POLICY'); + G::SendMessageText($sDescription, 'warning'); + G::header('Location: ' . $_SERVER['HTTP_REFERER']); + die; + } + $aHistory = unserialize($aUserProperty['USR_PASSWORD_HISTORY']); + if (!is_array($aHistory)) { + $aHistory = array(); + } + if (!defined('PPP_PASSWORD_HISTORY')) { + define('PPP_PASSWORD_HISTORY', 0); + } + if (PPP_PASSWORD_HISTORY > 0) { + //it's looking a password igual into aHistory array that was send for post in md5 way + $c=0;$sw=1; + while(count($aHistory) >= 1 && count($aHistory)>$c && $sw ){ + if(strcmp(trim($aHistory[$c]),trim($form['USR_PASSWORD'])) == 0){ + $sw=0; + } + $c++; + } + if($sw == 0){ + $sDescription = G::LoadTranslation('ID_POLICY_ALERT').':

    '; + $sDescription .= ' - ' . G::LoadTranslation('PASSWORD_HISTORY').': ' . PPP_PASSWORD_HISTORY . '
    '; + $sDescription .= '
    ' . G::LoadTranslation('ID_PLEASE_CHANGE_PASSWORD_POLICY').''; + G::SendMessageText($sDescription, 'warning'); + G::header('Location: ' . $_SERVER['HTTP_REFERER']); + die; + } + // + if (count($aHistory) >= PPP_PASSWORD_HISTORY) { + $sLastPassw=array_shift($aHistory); + } + $aHistory[] = $form['USR_PASSWORD']; + } + $aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $aUserProperty['USR_LOGGED_NEXT_TIME'] = 1; + $aUserProperty['USR_PASSWORD_HISTORY'] = serialize($aHistory); + $oUserProperty->update($aUserProperty); + } + } + $aData['USR_FIRSTNAME'] = $form['USR_FIRSTNAME']; + $aData['USR_LASTNAME'] = $form['USR_LASTNAME']; + $aData['USR_EMAIL'] = $form['USR_EMAIL']; + $aData['USR_DUE_DATE'] = $form['USR_DUE_DATE']; + $aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + if (isset($form['USR_STATUS'])) { + $aData['USR_STATUS'] = $form['USR_STATUS']; + } + if (isset($form['USR_ROLE'])) { + $RBAC->updateUser($aData, $form['USR_ROLE']); + } + else { + $RBAC->updateUser($aData); + } + $aData['USR_COUNTRY'] = $form['USR_COUNTRY']; + $aData['USR_CITY'] = $form['USR_CITY']; + $aData['USR_LOCATION'] = $form['USR_LOCATION']; + $aData['USR_ADDRESS'] = $form['USR_ADDRESS']; + $aData['USR_PHONE'] = $form['USR_PHONE']; + $aData['USR_ZIP_CODE'] = $form['USR_ZIP_CODE']; + $aData['USR_POSITION'] = $form['USR_POSITION']; + + if ($form['USR_RESUME'] != '') { + $aData['USR_RESUME'] = $form['USR_RESUME']; + } + if (isset($form['USR_ROLE'])) { + $aData['USR_ROLE'] = $form['USR_ROLE']; + } + + if(isset($form['USR_REPLACED_BY'])){ + $aData['USR_REPLACED_BY'] = $form['USR_REPLACED_BY']; + } + + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $oUser->update($aData); + if ($_FILES['form']['error']['USR_PHOTO'] != 1) { + if ($_FILES['form']['tmp_name']['USR_PHOTO'] != '') { + $aAux = explode('.', $_FILES['form']['name']['USR_PHOTO']); + G::uploadFile($_FILES['form']['tmp_name']['USR_PHOTO'], PATH_IMAGES_ENVIRONMENT_USERS, $aData['USR_UID'] . '.' . $aAux[1]); + G::resizeImage(PATH_IMAGES_ENVIRONMENT_USERS . $aData['USR_UID'] . '.' . $aAux[1], 96, 96, PATH_IMAGES_ENVIRONMENT_USERS . $aData['USR_UID'] . '.gif'); + } + } + else { + G::SendTemporalMessage ('ID_FILE_TOO_BIG', 'error'); + } + if ($_FILES['form']['error']['USR_RESUME'] != 1) { + if ($_FILES['form']['tmp_name']['USR_RESUME'] != '') { + G::uploadFile($_FILES['form']['tmp_name']['USR_RESUME'], PATH_IMAGES_ENVIRONMENT_FILES . $aData['USR_UID'] . '/', $_FILES['form']['name']['USR_RESUME']); + } + } + else { + G::SendTemporalMessage ('ID_FILE_TOO_BIG', 'error'); + } + } + + if($_SESSION['USER_LOGGED'] == $form['USR_UID']){ + /*UPDATING SESSION VARIABLES*/ + $aUser = $RBAC->userObj->load($_SESSION['USER_LOGGED']); + $_SESSION['USR_FULLNAME'] = $aUser['USR_FIRSTNAME'] . ' ' . $aUser['USR_LASTNAME']; + } + + + //Save Calendar assigment + if((isset($form['USR_CALENDAR']))){ + //Save Calendar ID for this user + G::LoadClass("calendar"); + $calendarObj=new Calendar(); + $calendarObj->assignCalendarTo($aData['USR_UID'],$form['USR_CALENDAR'],'USER'); + } + + G::header('location: users_List'); +} +catch (Exception $e) { + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'users'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_ID_SUB_MENU_SELECTED = ''; + + $aMessage = array(); + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish'); +} diff --git a/workflow/engine/methods/users/users_View.php b/workflow/engine/methods/users/users_View.php new file mode 100644 index 000000000..f46128aef --- /dev/null +++ b/workflow/engine/methods/users/users_View.php @@ -0,0 +1,81 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +try { + global $RBAC; + switch ($RBAC->userCanAccess('PM_FACTORY')) + { + case -2: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_SYSTEM', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + case -1: + G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels'); + G::header('location: ../login/login'); + die; + break; + } + // deprecated the class XmlForm_Field_Image is currently part of the class.xmlform.php package + // the use of the external xmlfield_Image is highly discouraged + if (!class_exists('XmlForm_Field_Image')){ + G::LoadClass('xmlfield_Image'); + } + require_once 'classes/model/Users.php'; + $_SESSION['CURRENT_USER'] = $_GET['USR_UID']; + $oUser = new Users(); + $aFields = $oUser->load($_GET['USR_UID']); + $aFields['USR_PASSWORD'] = '********'; + $aFields['MESSAGE0'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_USER_REGISTERED')) . '!'; + $aFields['MESSAGE1'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_USERNAME')); + $aFields['MESSAGE2'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_DUE_DATE')); + $aFields['MESSAGE3'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_NEW_PASS_SAME_OLD_PASS')); + $aFields['MESSAGE4'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_FIRSTNAME')); + $aFields['MESSAGE5'] = str_replace("\r\n","
    ",G::LoadTranslation('ID_MSG_ERROR_USR_LASTNAME')); + $aFields['NO_RESUME'] = G::LoadTranslation('ID_NO_RESUME'); + $aFields['START_DATE'] = date('Y-m-d'); + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 5)); + $aFields['RANDOM'] = rand(); + $G_MAIN_MENU = 'processmaker'; + $G_ID_MENU_SELECTED = 'USERS'; + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_View.xml', '', $aFields); +krumo($_SESSION); + if($_GET['USR_UID']=='00000000000000000000000000000001') + { //$G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_ViewAdmin.xml', '', $aFields); + // administrator due date must have a longer range + $aFields['END_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 10)); + krumo("asdasd"); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_EditAdmin.xml', 'display:none', $aFields, 'users_Save?USR_UID=' . $_SESSION['CURRENT_USER']); + } + else + { + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'users/users_Edit.xml', 'display:none', $aFields, 'users_Save?USR_UID=' . $_SESSION['CURRENT_USER']); + } + G::RenderPage('publish'); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_ViewPhoto.php b/workflow/engine/methods/users/users_ViewPhoto.php new file mode 100644 index 000000000..73161c2f1 --- /dev/null +++ b/workflow/engine/methods/users/users_ViewPhoto.php @@ -0,0 +1,100 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; + + $direction = PATH_IMAGES_ENVIRONMENT_USERS . $uid = (isset($_SESSION['CURRENT_USER']) ? $_SESSION['CURRENT_USER'] : $_SESSION['USER_LOGGED']).".gif"; +// header('Pragma: '); +// header('Cache-Control: cache'); + + if (!file_exists($direction)) + { + $direction = PATH_HOME . 'public_html/images/user.gif'; + } + G::sendHeaders( $direction ); + +DumpHeaders($direction); + + +/* + * This function is verified to work with Netscape and the *very latest* + * version of IE. I don't know if it works with Opera, but it should now. + */ +function DumpHeaders($filename) +{ + + global $root_path; + + if (!$filename) return; + + $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT']; + + $isIE = 0; + + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !== false && + strstr($HTTP_USER_AGENT, 'Opera') === false) { + $isIE = 1; + } + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !== false && + strstr($HTTP_USER_AGENT, 'Opera') === false) { + $isIE6 = 1; + } + + $aux = ereg_replace('[^-a-zA-Z0-9\.]', '_', $filename); + $aux = explode ('_', $aux); + $downloadName = $aux[ count($aux)-1 ]; + // $downloadName = $filename; + + //$downloadName = ereg_replace('[^-a-zA-Z0-9\.]', '_', $filename); + + if ($isIE && !isset($isIE6)) { + // http://support.microsoft.com/support/kb/articles/Q182/3/15.asp + // Do not have quotes around filename, but that applied to + // "attachment"... does it apply to inline too? + + // This combination seems to work mostly. IE 5.5 SP 1 has + // known issues (see the Microsoft Knowledge Base) + header("Content-Disposition: inline; filename=$downloadName"); + + // This works for most types, but doesn't work with Word files + header("Content-Type: application/download; name=\"$downloadName\""); + + //header("Content-Type: $type0/$type1; name=\"$downloadName\""); + //header("Content-Type: application/x-msdownload; name=\"$downloadName\""); + //header("Content-Type: application/octet-stream; name=\"$downloadName\""); + } + else { + header("Content-Disposition: attachment; filename=\"$downloadName\""); + header("Content-Type: application/octet-stream; name=\"$downloadName\""); + } + + //$filename = PATH_UPLOAD . "$filename"; + readfile($filename); +} + + +//G::header2( "location: /files/" .$_SESSION['ENVIRONMENT']. "/" .$appid, $filename); +?> \ No newline at end of file diff --git a/workflow/engine/methods/users/users_ViewResume.php b/workflow/engine/methods/users/users_ViewResume.php new file mode 100644 index 000000000..c8fd6dc47 --- /dev/null +++ b/workflow/engine/methods/users/users_ViewResume.php @@ -0,0 +1,106 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +if (($RBAC_Response=$RBAC->userCanAccess("PM_LOGIN"))!=1) return $RBAC_Response; +G::LoadClass( "user" ); + +$uid = (isset($_SESSION['CURRENT_USER']) ? $_SESSION['CURRENT_USER'] : $_SESSION['USER_LOGGED']); +require_once 'classes/model/Users.php'; +$oUser = new Users(); +$form = $oUser->load($uid); +if (!isset($form['USR_RESUME']) || $form['USR_RESUME']==='') die(G::LoadTranslation('ID_WITHOUT_RESUME')); + $direction = PATH_IMAGES_ENVIRONMENT_FILES.$uid."/".$form['USR_RESUME']; +if (!file_exists($direction)) { + die('The file "' . $direction . '"does not exist in the server!'); +} +// echo $direction ; + header('Pragma: '); + header('Cache-Control: cache'); + + +G::sendHeaders($direction); +readfile($direction); +//DumpHeaders($direction); + +/* + * This function is verified to work with Netscape and the *very latest* + * version of IE. I don't know if it works with Opera, but it should now. + */ +function DumpHeaders($filename) +{ + + global $root_path; + + if (!$filename) return; + + $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT']; + + $isIE = 0; + + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !== false && + strstr($HTTP_USER_AGENT, 'Opera') === false) { + $isIE = 1; + } + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !== false && + strstr($HTTP_USER_AGENT, 'Opera') === false) { + $isIE6 = 1; + } + + $aux = ereg_replace('[^-a-zA-Z0-9\.]', '_', $filename); + $aux = explode ('_', $aux); + $downloadName = $aux[ count($aux)-1 ]; + // $downloadName = $filename; + + //$downloadName = ereg_replace('[^-a-zA-Z0-9\.]', '_', $filename); + + if ($isIE && !isset($isIE6)) { + // http://support.microsoft.com/support/kb/articles/Q182/3/15.asp + // Do not have quotes around filename, but that applied to + // "attachment"... does it apply to inline too? + + // This combination seems to work mostly. IE 5.5 SP 1 has + // known issues (see the Microsoft Knowledge Base) + header("Content-Disposition: inline; filename=$downloadName"); + + // This works for most types, but doesn't work with Word files + header("Content-Type: application/download; name=\"$downloadName\""); + + //header("Content-Type: $type0/$type1; name=\"$downloadName\""); + //header("Content-Type: application/x-msdownload; name=\"$downloadName\""); + //header("Content-Type: application/octet-stream; name=\"$downloadName\""); + } + else { + header("Content-Disposition: attachment; filename=\"$downloadName\""); + header("Content-Type: application/octet-stream; name=\"$downloadName\""); + } + + //$filename = PATH_UPLOAD . "$filename"; + readfile($filename); +} + + +//G::header2( "location: /files/" .$_SESSION['ENVIRONMENT']. "/" .$appid, $filename); +?> diff --git a/workflow/engine/plugins/charts.php b/workflow/engine/plugins/charts.php new file mode 100644 index 000000000..64b6a236b --- /dev/null +++ b/workflow/engine/plugins/charts.php @@ -0,0 +1,35 @@ +sFriendlyName = 'Charts Plugin'; + $this->sDescription = 'This plugin shows generic charts for ProcessMaker'; + $this->sPluginFolder = 'charts'; + $this->sSetupPage = 'setupPage'; + $this->aWorkspaces = array ( ); + $this->iVersion = 0.45; + return $res; + } + + function setup() + { + $this->registerTrigger( 10000, 'createCaseFolder' ); + } + + function install() + { + + } + } + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->registerPlugin('charts', __FILE__); + + + + + diff --git a/workflow/engine/plugins/charts/class.charts.php b/workflow/engine/plugins/charts/class.charts.php new file mode 100644 index 000000000..295871341 --- /dev/null +++ b/workflow/engine/plugins/charts/class.charts.php @@ -0,0 +1,106 @@ +sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !file_exists( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + if ( file_exists ( $fileConf ) ) { + $content = file_get_contents ( $fileConf); + $fields = unserialize ($content); + } + else + $fields = array(); + return $fields; + } + + function updateFieldsForPageSetup ( $oData) { + $content = serialize ($oData['form']); + $fileConf = PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !is_writable( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist or this directory is not writable." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + file_put_contents ( $fileConf, $content); + return true; + } + + function setup() { + } + + function getDatasetCasesByStatus ( ) { + $dataSet = new XYDataSet(); + + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn ( ApplicationPeer::APP_STATUS ); + $c->addSelectColumn ( 'COUNT(*) AS CANT') ; + $c->addGroupByColumn(ApplicationPeer::APP_STATUS); + $rs = ApplicationPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label = $row['APP_STATUS']; + $value = $row['CANT']; + $dataSet->addPoint(new Point($label , (int)$value ) ); + $rs->next(); + $row = $rs->getRow(); + } + return $dataSet; + } + + //we are trying to obtain the process title thru the long way, using the process object. + //there is a short way, if you use a more complex query joining Content Table. + function getDatasetCasesByProcess ( ) { + $dataSet = new XYDataSet(); + $processObj = new Process; + + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn ( ApplicationPeer::PRO_UID ); + $c->addSelectColumn ( 'COUNT(*) AS CANT') ; + //$c->addJoin( ProcessPeer::PRO_UID, ProcessPeer::PRO_UID, Criteria::LEFT_JOIN); + $c->addGroupByColumn(ApplicationPeer::PRO_UID); + $rs = ApplicationPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $processObj->load ( $row['PRO_UID'] ); + $label = $processObj->getProTitle(); + $value = $row['CANT']; + $dataSet->addPoint(new Point($label , (int)$value) ); + $rs->next(); + $row = $rs->getRow(); + } + return $dataSet; + } + + } diff --git a/workflow/engine/plugins/charts/config/setup.conf b/workflow/engine/plugins/charts/config/setup.conf new file mode 100644 index 000000000..70cf5bfbf --- /dev/null +++ b/workflow/engine/plugins/charts/config/setup.conf @@ -0,0 +1 @@ +a:1:{s:6:"ACCEPT";s:4:"Save";} \ No newline at end of file diff --git a/workflow/engine/plugins/charts/genericCharts.php b/workflow/engine/plugins/charts/genericCharts.php new file mode 100644 index 000000000..855690836 --- /dev/null +++ b/workflow/engine/plugins/charts/genericCharts.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //if (($RBAC_Response=$RBAC->userCanAccess("PM_SETUP"))!=1) return $RBAC_Response; + + require_once ( "class.charts.php" ); + + + G::LoadThirdParty("libchart/classes", "libchart" ); + + header("Content-type: image/png"); + //type of chart, pie, vertical bar, horizontal, etc. + $type = isset ( $_GET['type']) ? $_GET['type'] : '1' ; + $chartType = isset ( $_GET['chart']) ? $_GET['chart'] : '1' ; + $user = isset ( $_GET['user']) ? $_GET['user'] : $_SESSION['USER_LOGGED'] ; + $chartsObj = new chartsClass(); + + //$chart = new PieChart(450,300); + switch ( $type ) { + case '1' : + $chart = new VerticalBarChart(430, 280); break; + case '2' : + $chart = new HorizontalBarChart(430, 200); break; + case '3' : + $chart = new LineChart(430, 280); break; + case '4' : + $chart = new PieChart(430, 200 ); break; + } + + switch ( $chartType ) { + case '1' : + $dataSet = $chartsObj->getDatasetCasesByStatus(); break; + default : + $dataSet = $chartsObj->getDatasetCasesByProcess(); break; + } + $chart->setDataSet($dataSet); + $chart->setTitle( "Cases list" ); + $chart->render(); + diff --git a/workflow/engine/plugins/charts/setupPage.xml b/workflow/engine/plugins/charts/setupPage.xml new file mode 100644 index 000000000..9e6c83779 --- /dev/null +++ b/workflow/engine/plugins/charts/setupPage.xml @@ -0,0 +1,20 @@ + + + + + <en>About charts Plugin</en> + + + + This is the Charts Plugin, with this plugin you can see many differents charts + + + + + Save + + \ No newline at end of file diff --git a/workflow/engine/plugins/openFlash.php b/workflow/engine/plugins/openFlash.php new file mode 100644 index 000000000..794431380 --- /dev/null +++ b/workflow/engine/plugins/openFlash.php @@ -0,0 +1,36 @@ +sFriendlyName = 'openFlash Plugin'; + $this->sDescription = 'Charts Plugin, with this plugin you can see many differents charts using interactive flash charts for ProcessMaker'; + $this->sPluginFolder = 'openFlash'; + $this->sSetupPage = 'setupPage'; + $this->aWorkspaces = array ( ); + $this->aWorkspaces = array ( 'dev'); + $this->iVersion = 0.45; + return $res; + } + + function setup() + { + $this->registerDashboard(); + } + + function install() + { + + } + } + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->registerPlugin('openFlash', __FILE__); + + + + + diff --git a/workflow/engine/plugins/openFlash/chart-data.php b/workflow/engine/plugins/openFlash/chart-data.php new file mode 100644 index 000000000..a0dbb6a22 --- /dev/null +++ b/workflow/engine/plugins/openFlash/chart-data.php @@ -0,0 +1,14 @@ +{$chartType}(); + die; + } + diff --git a/workflow/engine/plugins/openFlash/chart.php b/workflow/engine/plugins/openFlash/chart.php new file mode 100644 index 000000000..78d8c1975 --- /dev/null +++ b/workflow/engine/plugins/openFlash/chart.php @@ -0,0 +1,11 @@ +sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !file_exists( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + if ( file_exists ( $fileConf ) ) { + $content = file_get_contents ( $fileConf); + $fields = unserialize ($content); + } + else + $fields = array(); + return $fields; + } + + function updateFieldsForPageSetup ( $oData) { + $content = serialize ($oData['form']); + $fileConf = PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !is_writable( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist or this directory is not writable." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + file_put_contents ( $fileConf, $content); + return true; + } + + function setup() { + } + + function getChart( $chartName ) { + $this->readConfig(); + $prePath = '/sys' . SYS_SYS . '/' . SYS_LANG . '/blank/'; + $obj = new StdClass(); + $obj->title = 'Standard ProcessMaker Reports'; + $obj->height = 220; + $obj->open->url = $prePath . 'openFlash/chart?chart=' . $chartName . "&u="; + return $obj; + } + + //here we are defining the available charts, the dashboard setup will call this function to know the charts + function getAvailableCharts( ) { + return array ( + 'CasesByStatus', + 'CasesByStatusPie', + 'CasesByProcess', + 'CasesByProcessPie' + ); + } + + /* definition of all charts */ + /* that definition comes in two parts : + /* 1. the getXX () function to get the data from the databases + /* 2. the XX () function to draw the graph + */ + + /** chart getCasesByStatus ***/ + /** to show the Cases grouped by Status*/ + function getCasesByStatus ( ) { + $dataSet = array(); + + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn ( ApplicationPeer::APP_STATUS ); + $c->addSelectColumn ( 'COUNT(*) AS CANT') ; + $c->addGroupByColumn(ApplicationPeer::APP_STATUS); + $rs = ApplicationPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = $row['APP_STATUS']; + $data[] = (int)$row['CANT']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $aux = intval($max / 6 ) * 6 + 6; + $dataSet['max'] = $aux; + return $dataSet; + } + + function CasesByStatus( ) { + $dataSet = $this->getCasesByStatus(); + $data = $dataSet['data']; + //$series2 = $dataSet['series2']; + $g = new graph(); + $g->title( ' Cases by Status ', '{font-size: 14px;}' ); + $bar_red = new bar_3d( 50, '#3334AD' ); + $bar_red->key( 'cases', 10 ); + $bar_red->data = $data; + + $g->data_sets[] = $bar_red; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $dataSet['max'] ); + $g->y_label_steps( 6 ); + //$g->set_y_legend( 'Posts', 12, '#736AFF' ); + echo $g->render(); + } + + function CasesByStatusPie ( ) { + $g->bg_colour = '#FFFFFF'; + $dataSet = $this->getCasesByStatus(); + $data = $dataSet['data']; + $g = new graph(); + $g->pie(80,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810','#D54C78') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Cases by Status', '{font-size:18px; color: #d01f3c}' ); + echo $g->render(); + } + + /** chart CasesByProcess ***/ + /** to show the cases grouped by Process */ + function getCasesByProcess ( ) { + $dataSet = array(); + $processObj = new Process; + + $c = new Criteria('workflow'); + $c->clearSelectColumns(); + $c->addSelectColumn ( ApplicationPeer::PRO_UID ); + $c->addSelectColumn ( 'COUNT(*) AS CANT') ; + //$c->addJoin( ProcessPeer::PRO_UID, ProcessPeer::PRO_UID, Criteria::LEFT_JOIN); + $c->addGroupByColumn(ApplicationPeer::PRO_UID); + $rs = ApplicationPeer::doSelectRS( $c ); + $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $processObj->load ( $row['PRO_UID'] ); + $label[] = $processObj->getProTitle(); + $labelPie[] = substr ( $processObj->getProTitle(),0,16 ); + $data[] = (int)$row['CANT']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + $dataSet['labelPie'] = $labelPie; + + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $aux = intval($max / 6 ) * 6 + 6; + $dataSet['max'] = $aux; + return $dataSet; + } + + function CasesByProcess( ) { + $dataSet = $this->getCasesByProcess(); + $data = $dataSet['data']; + //$series2 = $dataSet['series2']; + $g = new graph(); + $g->title( ' Cases by Process ', '{font-size: 14px;}' ); + $bar_red = new bar_3d( 50, '#3334AD' ); + $bar_red->key( 'cases', 10 ); + $bar_red->data = $data; + + $g->data_sets[] = $bar_red; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $dataSet['max'] ); + $g->y_label_steps( 6 ); + echo $g->render(); + } + + function CasesByProcessPie ( ) { + $g->bg_colour = '#FFFFFF'; + $dataSet = $this->getCasesByProcess(); + $data = $dataSet['data']; + $g = new graph(); + $g->pie(80,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['labelPie'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810','#D54C78') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Cases by Process', '{font-size:16px; color: #d01f3c}' ); + echo $g->render(); + } +/* + function getForumWeek ( ) { + $databases = PATH_PLUGINS . "/openFlash/config/databases.php"; + Propel::init( $databases ); + + $dataSet = array(); + $processObj = new Process; + $past2months = mktime(0, 0, 0, date("m") -2 , date("d"), date("Y")); + + $con = Propel::getConnection('forum'); + $sql = "select week(FROM_UNIXTIME(post_time )) as week ,count(*) as cant from phpbb_posts where post_time > $past2months group by week " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = date ( 'M d', mktime(0, 0, 0, 1 , $row['week']*7, date("Y")) ); + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function ForumWeek ( ) { + $dataSet = $this->getForumWeek(); + $data = $dataSet['data']; + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $g = new graph(); + $g->title( ' Posts by Week ', '{font-size: 16px;}' ); + $bar_red = new bar_3d( 50, '#3334AD' ); + $bar_red->key( 'week', 10 ); + $bar_red->data = $data; + + $g->data_sets[] = $bar_red; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $max ); + $g->y_label_steps( 5 ); + $g->set_y_legend( 'Posts', 12, '#736AFF' ); + echo $g->render(); + } + + /** chart PostByUser ***/ + /** to show the last 7 days grouped by user * / + function getPostByUser ( ) { + $databases = PATH_PLUGINS . "/openFlash/config/databases.php"; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('forum'); + + $past7days = mktime(0, 0, 0, date("m") , date("d")-7, date("Y")); + $sql = "select username, count(*) as cant from phpbb_posts left join phpbb_users on ( poster_id = user_id ) where post_time > $past7days group by username " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = $row['username']; + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + //$dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function PostByUser ( ) { + $dataSet = $this->getPostByUser(); + $data = $dataSet['data']; + $g = new graph(); + $g->title( ' Posts by User last week '. date("Y-m-d"), '{font-size: 16px;}' ); + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $max = intval($max / 4 ) * 4 + 4; + + $bar_red = new bar_3d( 50, '#356aa0' ); + $bar_red->key( 'posts', 10 ); + $bar_red->data = $data; + + $bar_blue = new bar_3d( 75, '#D54C78' ); + $bar_blue->key( 'completed', 10 ); + $bar_blue->data = $data; + + $g->data_sets[] = $bar_red; + //$g->data_sets[] = $bar_blue; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $max ); + $g->y_label_steps( 4 ); + $g->set_y_legend( 'Processmaker', 12, '#736AFF' ); + echo $g->render(); + } + + /** chart BugsByStatus ***/ + /** to show the bugs by status resolved, open, closed * / + function getBugsByStatus ( ) { + $databases = PATH_PLUGINS . "/openFlash/config/databases.php"; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('bugs'); + + //open + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status in (20,30,40,50) " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'open'; + $data[] = $row['cant']; + + //resolved + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status = 80" ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'resolved'; + $data[] = $row['cant']; + + //closed + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status = 90" ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'closed'; + $data[] = $row['cant']; + + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function BugsByStatus ( ) { + $dataSet = $this->getBugsByStatus(); + $data = $dataSet['data']; + $g = new graph(); + $g->title( ' Posts by User last week '. date("Y-m-d"), '{font-size: 16px;}' ); + + $g->pie(70,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Bugs by Status', '{font-size:18px; color: #d01f3c}' ); + echo $g->render(); + } + + /** chart BugsOpenByUser ***/ + /** to show the bugs in OPEN status by user * / + function getBugsOpenByUser ( ) { + $databases = PATH_PLUGINS . "/openFlash/config/databases.php"; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('bugs'); + + $sql = "SELECT username, count(*) as cant FROM mantis_bug_table left join mantis_user_table on ( mantis_user_table.id = handler_id) where project_id = 31 and status in (20,30,40,50) group by username " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = $row['username']; + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function BugsOpenByUser ( ) { + $g->bg_colour = '#EFFFEF'; + $dataSet = $this->getBugsOpenByUser(); + $data = $dataSet['data']; + $g = new graph(); + $g->pie(80,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810','#D54C78') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Open Bugs by User', '{font-size:18px; color: #d01f3c}' ); + echo $g->render(); + } + +/*******/ + + + + + + + + +} diff --git a/workflow/engine/plugins/openFlash/open-flash-chart.php b/workflow/engine/plugins/openFlash/open-flash-chart.php new file mode 100644 index 000000000..b1cd90627 --- /dev/null +++ b/workflow/engine/plugins/openFlash/open-flash-chart.php @@ -0,0 +1,1769 @@ +data_sets = array(); + + + $this->data = array(); + $this->links = array(); + $this->width = 250; + $this->height = 200; + $this->js_path = '/images/'; + $this->swf_path = ''; + $this->x_labels = array(); + $this->y_min = ''; + $this->y_max = ''; + $this->x_min = ''; + $this->x_max = ''; + $this->y_steps = ''; + $this->title = ''; + $this->title_style = ''; + $this->occurence = 0; + + $this->x_offset = ''; + + $this->x_tick_size = -1; + + $this->y2_max = ''; + $this->y2_min = ''; + + // GRID styles: + $this->x_axis_colour = ''; + $this->x_axis_3d = ''; + $this->x_grid_colour = ''; + $this->x_axis_steps = 1; + $this->y_axis_colour = ''; + $this->y_grid_colour = ''; + $this->y2_axis_colour = ''; + + // AXIS LABEL styles: + $this->x_label_style = ''; + $this->y_label_style = ''; + $this->y_label_style_right = ''; + + + // AXIS LEGEND styles: + $this->x_legend = ''; + $this->x_legend_size = 20; + $this->x_legend_colour = '#000000'; + + $this->y_legend = ''; + $this->y_legend_right = ''; + //$this->y_legend_size = 20; + //$this->y_legend_colour = '#000000'; + + $this->lines = array(); + $this->line_default['type'] = 'line'; + $this->line_default['values'] = '3,#87421F'; + $this->js_line_default = 'so.addVariable("line","3,#87421F");'; + + $this->bg_colour = ''; + $this->bg_image = ''; + + $this->inner_bg_colour = ''; + $this->inner_bg_colour_2 = ''; + $this->inner_bg_angle = ''; + + // PIE chart ------------ + $this->pie = ''; + $this->pie_values = ''; + $this->pie_colours = ''; + $this->pie_labels = ''; + + $this->tool_tip = ''; + + // which data lines are attached to the + // right Y axis? + $this->y2_lines = array(); + + // Number formatting: + $this->y_format=''; + $this->num_decimals=''; + $this->is_fixed_num_decimals_forced=''; + $this->is_decimal_separator_comma=''; + $this->is_thousand_separator_disabled=''; + + $this->output_type = ''; + + // + // set some default value incase the user forgets + // to set them, so at least they see *something* + // even is it is only the axis and some ticks + // + $this->set_y_min( 0 ); + $this->set_y_max( 20 ); + $this->set_x_axis_steps( 1 ); + $this->y_label_steps( 5 ); + } + + /** + * Set the unique_id to use for the flash object id. + */ + function set_unique_id() + { + $this->unique_id = uniqid(rand(), true); + } + + /** + * Get the flash object ID for the last rendered object. + */ + function get_unique_id() + { + return ($this->unique_id); + } + + /** + * Set the base path for the swfobject.js + * + * @param base_path a string argument. + * The path to the swfobject.js file + */ + function set_js_path($path) + { + $this->js_path = $path; + } + + /** + * Set the base path for the open-flash-chart.swf + * + * @param path a string argument. + * The path to the open-flash-chart.swf file + */ + function set_swf_path($path) + { + $this->swf_path = $path; + } + + /** + * Set the type of output data. + * + * @param type a string argument. + * The type of data. Currently only type is js, or nothing. + */ + function set_output_type($type) + { + $this->output_type = $type; + } + + /** + * returns the next line label for multiple lines. + */ + function next_line() + { + $line_num = ''; + if( count( $this->lines ) > 0 ) + $line_num = '_'. (count( $this->lines )+1); + + return $line_num; + } + + // escape commas (,) + function esc( $text ) + { + // we replace the comma so it is not URL escaped + // if it is, flash just thinks it is a comma + // which is no good if we are splitting the + // string on commas. + $tmp = str_replace( ',', '#comma#', $text ); + //$tmp = utf8_encode( $tmp ); + // now we urlescape all dodgy characters (like & % $ etc..) + return urlencode( $tmp ); + } + + /** + * Format the text to the type of output. + */ + function format_output($function,$values) + { + if($this->output_type == 'js') + { + $tmp = 'so.addVariable("'. $function .'","'. $values . '");'; + } + else + { + $tmp = '&'. $function .'='. $values .'&'; + } + + return $tmp; + } + + /** + * Set the text and style of the title. + * + * @param title a string argument. + * The text of the title. + * @param style a string. + * CSS styling of the title. + */ + function set_title( $title, $style='' ) + { + $this->title = $this->esc( $title ); + if( strlen( $style ) > 0 ) + $this->title_style = $style; + } + + /** + * Set the width of the chart. + * + * @param width an int argument. + * The width of the chart frame. + */ + function set_width( $width ) + { + $this->width = $width; + } + + /** + * Set the height of the chart. + * + * @param height an int argument. + * The height of the chart frame. + */ + function set_height( $height ) + { + $this->height = $height; + } + + /** + * Set the base path of the swfobject. + * + * @param base a string argument. + * The base path of the swfobject. + */ + function set_base( $base='/images/' ) + { + $this->base = $base; + } + + // Number formatting: + function set_y_format( $val ) + { + $this->y_format = $val; + } + + function set_num_decimals( $val ) + { + $this->num_decimals = $val; + } + + function set_is_fixed_num_decimals_forced( $val ) + { + $this->is_fixed_num_decimals_forced = $val?'true':'false'; + } + + function set_is_decimal_separator_comma( $val ) + { + $this->is_decimal_separator_comma = $val?'true':'false'; + } + + function set_is_thousand_separator_disabled( $val ) + { + $this->is_thousand_separator_disabled = $val?'true':'false'; + } + + /** + * Set the data for the chart + * @param a an array argument. + * An array of the data to add to the chart. + */ + function set_data( $a ) + { + $this->data[] = implode(',',$a); + } + + // UGH, these evil functions are making me fell ill + function set_links( $links ) + { + // TO DO escape commas: + $this->links[] = implode(',',$links); + } + + // $val is a boolean + function set_x_offset( $val ) + { + $this->x_offset = $val?'true':'false'; + } + + /** + * Set the tooltip to be displayed on each chart item.\n + * \n + * Replaceable tokens that can be used in the string include: \n + * #val# - The actual value of whatever the mouse is over. \n + * #key# - The key string. \n + * \
    - New line. \n + * #x_label# - The X label string. \n + * #x_legend# - The X axis legend text. \n + * Default string is: "#x_label#
    #val#" \n + * + * @param tip a string argument. + * A formatted string to show as the tooltip. + */ + function set_tool_tip( $tip ) + { + $this->tool_tip = $this->esc( $tip ); + } + + /** + * Set the x axis labels + * + * @param a an array argument. + * An array of the x axis labels. + */ + function set_x_labels( $a ) + { + $tmp = array(); + foreach( $a as $item ) + $tmp[] = $this->esc( $item ); + $this->x_labels = $tmp; + } + + /** + * Set the look and feel of the x axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + * @param orientation an int argument. + * The orientation of the x-axis text. + * 0 - Horizontal + * 1 - Vertical + * 2 - 45 degrees + * @param step an int argument. + * Show the label on every $step label. + * @param grid_colour a string argument. + */ + function set_x_label_style( $size, $colour='', $orientation=0, $step=-1, $grid_colour='' ) + { + $this->x_label_style = $size; + + if( strlen( $colour ) > 0 ) + $this->x_label_style .= ','. $colour; + + if( $orientation > -1 ) + $this->x_label_style .= ','. $orientation; + + if( $step > 0 ) + $this->x_label_style .= ','. $step; + + if( strlen( $grid_colour ) > 0 ) + $this->x_label_style .= ','. $grid_colour; + } + + /** + * Set the background colour. + * @param colour a string argument. + * The hex colour value. + */ + function set_bg_colour( $colour ) + { + $this->bg_colour = $colour; + } + + /** + * Set a background image. + * @param url a string argument. + * The location of the image. + * @param x a string argument. + * The x location of the image. 'Right', 'Left', 'Center' + * @param y a string argument. + * The y location of the image. 'Top', 'Bottom', 'Middle' + */ + function set_bg_image( $url, $x='center', $y='center' ) + { + $this->bg_image = $url; + $this->bg_image_x = $x; + $this->bg_image_y = $y; + } + + /** + * Attach a set of data (a line, area or bar chart) to the right Y axis. + * @param data_number an int argument. + * The numbered order the data was attached using set_data. + */ + function attach_to_y_right_axis( $data_number ) + { + $this->y2_lines[] = $data_number; + } + + /** + * Set the background colour of the grid portion of the chart. + * @param col a string argument. + * The hex colour value of the background. + * @param col2 a string argument. + * The hex colour value of the second colour if you want a gradient. + * @param angle an int argument. + * The angle in degrees to make the gradient. + */ + function set_inner_background( $col, $col2='', $angle=-1 ) + { + $this->inner_bg_colour = $col; + + if( strlen($col2) > 0 ) + $this->inner_bg_colour_2 = $col2; + + if( $angle != -1 ) + $this->inner_bg_angle = $angle; + } + + /** + * Internal function to build the y label style for y and y2 + */ + function _set_y_label_style( $size, $colour ) + { + $tmp = $size; + + if( strlen( $colour ) > 0 ) + $tmp .= ','. $colour; + return $tmp; + } + + /** + * Set the look and feel of the y axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + */ + function set_y_label_style( $size, $colour='' ) + { + $this->y_label_style = $this->_set_y_label_style( $size, $colour ); + } + + /** + * Set the look and feel of the right y axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + */ + function set_y_right_label_style( $size, $colour='' ) + { + $this->y_label_style_right = $this->_set_y_label_style( $size, $colour ); + } + + function set_x_max( $max ) + { + $this->x_max = floatval( $max ); + } + + function set_x_min( $min ) + { + $this->x_min = floatval( $min ); + } + + /** + * Set the maximum value of the y axis. + * + * @param max an float argument. + * The maximum value. + */ + function set_y_max( $max ) + { + $this->y_max = floatval( $max ); + } + + /** + * Set the minimum value of the y axis. + * + * @param min an float argument. + * The minimum value. + */ + function set_y_min( $min ) + { + $this->y_min = floatval( $min ); + } + + /** + * Set the maximum value of the right y axis. + * + * @param max an float argument. + * The maximum value. + */ + function set_y_right_max( $max ) + { + $this->y2_max = floatval($max); + } + + /** + * Set the minimum value of the right y axis. + * + * @param min an float argument. + * The minimum value. + */ + function set_y_right_min( $min ) + { + $this->y2_min = floatval($min); + } + + /** + * Show the y label on every $step label. + * + * @param val an int argument. + * Show the label on every $step label. + */ + function y_label_steps( $val ) + { + $this->y_steps = intval( $val ); + } + + function title( $title, $style='' ) + { + $this->title = $this->esc( $title ); + if( strlen( $style ) > 0 ) + $this->title_style = $style; + } + + /** + * Set the parameters of the x legend. + * + * @param text a string argument. + * The text of the x legend. + * @param font_size an int argument. + * The font size of the x legend text. + * @param colour a string argument + * The hex value of the font colour. + */ + function set_x_legend( $text, $size=-1, $colour='' ) + { + $this->x_legend = $this->esc( $text ); + if( $size > -1 ) + $this->x_legend_size = $size; + + if( strlen( $colour )>0 ) + $this->x_legend_colour = $colour; + } + + /** + * Set the size of the x label ticks. + * + * @param size an int argument. + * The size of the ticks in pixels. + */ + function set_x_tick_size( $size ) + { + if( $size > 0 ) + $this->x_tick_size = $size; + } + + /** + * Set how often you would like to show a tick on the x axis. + * + * @param steps an int argument. + * Show a tick ever $steps. + */ + function set_x_axis_steps( $steps ) + { + if ( $steps > 0 ) + $this->x_axis_steps = $steps; + } + + /** + * Set the depth in pixels of the 3D X axis slab. + * + * @param size an int argument. + * The depth in pixels of the 3D X axis. + */ + function set_x_axis_3d( $size ) + { + if( $size > 0 ) + $this->x_axis_3d = intval($size); + } + + /** + * The private method of building the y legend output. + */ + function _set_y_legend( $text, $size, $colour ) + { + $tmp = $text; + + if( $size > -1 ) + $tmp .= ','. $size; + + if( strlen( $colour )>0 ) + $tmp .= ','. $colour; + + return $tmp; + } + + /** + * Set the parameters of the y legend. + * + * @param text a string argument. + * The text of the y legend. + * @param font_size an int argument. + * The font size of the y legend text. + * @param colour a string argument + * The hex colour value of the font colour. + */ + function set_y_legend( $text, $size=-1, $colour='' ) + { + $this->y_legend = $this->_set_y_legend( $text, $size, $colour ); + } + + /** + * Set the parameters of the right y legend. + * + * @param text a string argument. + * The text of the right y legend. + * @param font_size an int argument. + * The font size of the right y legend text. + * @param colour a string argument + * The hex value of the font colour. + */ + function set_y_right_legend( $text, $size=-1, $colour='' ) + { + $this->y_legend_right = $this->_set_y_legend( $text, $size, $colour ); + } + + /** + * Set the colour of the x axis line and grid. + * + * @param axis a string argument. + * The hex colour value of the x axis line. + * @param grid a string argument. + * The hex colour value of the x axis grid. + */ + function x_axis_colour( $axis, $grid='' ) + { + $this->x_axis_colour = $axis; + $this->x_grid_colour = $grid; + } + + /** + * Set the colour of the y axis line and grid. + * + * @param axis a string argument. + * The hex colour value of the y axis line. + * @param grid a string argument. + * The hex colour value of the y axis grid. + */ + function y_axis_colour( $axis, $grid='' ) + { + $this->y_axis_colour = $axis; + + if( strlen( $grid ) > 0 ) + $this->y_grid_colour = $grid; + } + + /** + * Set the colour of the right y axis line. + * + * @param colour a string argument. + * The hex colour value of the right y axis line. + */ + function y_right_axis_colour( $colour ) + { + $this->y2_axis_colour = $colour; + } + + /** + * Draw a line without markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label + * @param circles an int argument + * Need to find out. + */ + function line( $width, $colour='', $text='', $size=-1, $circles=-1 ) + { + $type = 'line'. $this->next_line(); + + $description = ''; + if( $width > 0 ) + { + $description .= $width; + $description .= ','. $colour; + } + + if( strlen( $text ) > 0 ) + { + $description.= ','. $text; + $description .= ','. $size; + } + + if( $circles > 0 ) + $description .= ','. $circles; + + $this->lines[$type] = $description; + } + + /** + * Draw a line with solid dot markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function line_dot( $width, $dot_size, $colour, $text='', $font_size='' ) + { + $type = 'line_dot'. $this->next_line(); + + $description = "$width,$colour,$text"; + + if( strlen( $font_size ) > 0 ) + $description .= ",$font_size,$dot_size"; + + $this->lines[$type] = $description; + } + + /** + * Draw a line with hollow dot markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function line_hollow( $width, $dot_size, $colour, $text='', $font_size='' ) + { + $type = 'line_hollow'. $this->next_line(); + + $description = "$width,$colour,$text"; + + if( strlen( $font_size ) > 0 ) + $description .= ",$font_size,$dot_size"; + + $this->lines[$type] = $description; + } + + /** + * Draw an area chart. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param alpha an int argument. + * The percentage of transparency of the fill colour. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + * @param fill_colour a string argument. + * The hex colour value of the fill colour. + */ + function area_hollow( $width, $dot_size, $colour, $alpha, $text='', $font_size='', $fill_colour='' ) + { + $type = 'area_hollow'. $this->next_line(); + + $description = "$width,$dot_size,$colour,$alpha"; + + if( strlen( $text ) > 0 ) + $description .= ",$text,$font_size"; + + if( strlen( $fill_colour ) > 0 ) + $description .= ','. $fill_colour; + + $this->lines[$type] = $description; + } + + /** + * Draw a bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a bar chart with an outline. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param colour_outline a strng argument. + * The hex colour value of the outline. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_filled( $alpha, $colour, $colour_outline, $text='', $size=-1 ) + { + $type = 'filled_bar'. $this->next_line(); + + $description = "$alpha,$colour,$colour_outline,$text,$size"; + + $this->lines[$type] = $description; + } + + function bar_sketch( $alpha, $offset, $colour, $colour_outline, $text='', $size=-1 ) + { + $type = 'bar_sketch'. $this->next_line(); + + $description = "$alpha,$offset,$colour,$colour_outline,$text,$size"; + + $this->lines[$type] = $description; + } + + /** + * Draw a 3D bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_3D( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar_3d'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a 3D bar chart that looks like glass. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param outline_colour a string argument. + * The hex colour value of the outline. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_glass( $alpha, $colour, $outline_colour, $text='', $size=-1 ) + { + $type = 'bar_glass'. $this->next_line(); + + $description = $alpha .','. $colour .','. $outline_colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a faded bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_fade( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar_fade'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + function candle( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'candle'. $this->next_line(); + + $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + function hlc( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'hlc'. $this->next_line(); + + $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + function scatter( $data, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'scatter'. $this->next_line(); + + $description = $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + + // + // Patch by, Jeremy Miller (14th Nov, 2007) + // + /** + * Draw a pie chart. + * + * @param alpha an int argument. + * The percentage of transparency of the pie colour. + * @param $style a string argument. + * CSS style string + * @param label_colour a string argument. + * The hex colour value of the label. + * @param gradient a boolean argument. + * Use a gradient true or false. + * @param border_size an int argument. + * Size of the border in pixels. + */ + function pie( $alpha, $line_colour, $style, $gradient = true, $border_size = false ) + { + $this->pie = $alpha.','.$line_colour.','.$style; + if( !$gradient ) + { + $this->pie .= ','.!$gradient; + } + if ($border_size) + { + if ($gradient === false) + { + $this->pie .= ','; + } + $this->pie .= ','.$border_size; + } + } + + /** + * Set the values of the pie chart. + * + * @param values an array argument. + * An array of the values for the pie chart. + * @param labels an array argument. + * An array of the labels for the pie pieces. + * @param links an array argument. + * An array of the links to the pie pieces. + */ + function pie_values( $values, $labels=array(), $links=array() ) + { + $this->pie_values = implode(',',$values); + $this->pie_labels = implode(',',$labels); + $this->pie_links = implode(",",$links); + } + + /** + * Set the pie slice colours. + * + * @param colours an array argument. + * The hex colour values of the pie pieces. + */ + function pie_slice_colours( $colours ) + { + $this->pie_colours = implode(',',$colours); + } + + + /** + * Render the output. + */ + function render() + { + $tmp = array(); + + //echo headers_sent() ?'yes':'no'; + if( !headers_sent() ) + header('content-type: text; charset: utf-8'); + + if($this->output_type == 'js') + { + $this->set_unique_id(); + + $tmp[] = '
    '; + $tmp[] = ''; + $tmp[] = ''; + } + + return implode("\r\n",$tmp); + } +} + +class line +{ + var $line_width; + var $colour; + var $_key; + var $key; + var $key_size; + // hold the data + var $data; + // extra tool tip info: + var $tips; + + function line( $line_width, $colour ) + { + $this->var = 'line'; + + $this->line_width = $line_width; + $this->colour = $colour; + $this->data = array(); + $this->links = array(); + $this->tips = array(); + $this->_key = false; + } + + + function key( $key, $size ) + { + $this->_key = true; + $this->key = graph::esc( $key ); + $this->key_size = $size; + } + + function add( $data ) + { + $this->data[] = $data; + } + + function add_link( $data, $link ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + } + + function add_data_tip( $data, $tip ) + { + $this->data[] = $data; + $this->tips[] = graph::esc( $tip ); + } + + function add_data_link_tip( $data, $link, $tip ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + $this->tips[] = graph::esc( $tip ); + } + + // return the variables for this chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->line_width; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } + + function toString( $output_type, $set_num ) + { + $values = implode( ',', $this->_get_variable_list() ); + + $tmp = array(); + + if( $output_type == 'js' ) + { + $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; + + $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; + + if( count( $this->links ) > 0 ) + $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; + + if( count( $this->tips ) > 0 ) + $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; + + } + else + { + $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; + $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; + + if( count( $this->links ) > 0 ) + $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; + + if( count( $this->tips ) > 0 ) + $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; + } + + return implode( "\r\n", $tmp ); + } +} + +class line_hollow extends line +{ + var $dot_size; + + function line_hollow( $line_width, $dot_size, $colour ) + { + parent::line( $line_width, $colour ); + $this->var = 'line_hollow'; + $this->dot_size = $dot_size; + } + + // return the variables for this chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->line_width; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + else + { + $values[] = ''; + $values[] = ''; + } + $values[] = $this->dot_size; + + return $values; + } +} + +class line_dot extends line_hollow +{ + function line_dot( $line_width, $dot_size, $colour ) + { + parent::line_dot( $line_width, $colour ); + $this->var = 'line_dot'; + } +} + +class bar +{ + var $colour; + var $alpha; + var $data; + var $links; + var $_key; + var $key; + var $key_size; + var $var; + // extra tool tip info: + var $tips; + + function bar( $alpha, $colour ) + { + $this->var = 'bar'; + + $this->alpha = $alpha; + $this->colour = $colour; + $this->data = array(); + $this->links = array(); + $this->tips = array(); + $this->_key = false; + } + + function key( $key, $size ) + { + $this->_key = true; + $this->key = graph::esc( $key ); + $this->key_size = $size; + } + + function add( $data ) + { + $this->data[] = $data; + } + + function add_link( $data, $link ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + } + + function add_data_tip( $data, $tip ) + { + $this->data[] = $data; + $this->tips[] = graph::esc( $tip ); + } + + // return the variables for this + // bar chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } + + function toString( $output_type, $set_num ) + { + $values = implode( ',', $this->_get_variable_list() ); + + $tmp = array(); + + if( $output_type == 'js' ) + { + $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; + + $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; + + if( count( $this->links ) > 0 ) + $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; + + if( count( $this->tips ) > 0 ) + $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; + + } + else + { + $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; + $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; + + if( count( $this->links ) > 0 ) + $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; + + if( count( $this->tips ) > 0 ) + $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; + } + + return implode( "\r\n", $tmp ); + } + +} + +class bar_3d extends bar +{ + function bar_3d( $alpha, $colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'bar_3d'; + } +} + +class bar_fade extends bar +{ + function bar_fade( $alpha, $colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'bar_fade'; + } +} + +class bar_outline extends bar +{ + var $outline_colour; + + function bar_outline( $alpha, $colour, $outline_colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'filled_bar'; + $this->outline_colour = $outline_colour; + } + + // override the base method + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->colour; + $values[] = $this->outline_colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } +} + +class bar_glass extends bar_outline +{ + function bar_glass( $alpha, $colour, $outline_colour ) + { + parent::bar_outline( $alpha, $colour, $outline_colour ); + $this->var = 'bar_glass'; + } +} + +// +// this has an outline colour and a 'jiggle' parameter +// called offset +// +class bar_sketch extends bar_outline +{ + var $offset; + + function bar_sketch( $alpha, $offset, $colour, $outline_colour ) + { + parent::bar_outline( $alpha, $colour, $outline_colour ); + $this->var = 'bar_sketch'; + $this->offset = $offset; + } + + // override the base method + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->offset; + $values[] = $this->colour; + $values[] = $this->outline_colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } +} + +class candle +{ + var $out; + + function candle( $high, $open, $close, $low ) + { + $this->out = array(); + $this->out[] = $high; + $this->out[] = $open; + $this->out[] = $close; + $this->out[] = $low; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + +class hlc +{ + var $out; + + function hlc( $high, $low, $close ) + { + $this->out = array(); + $this->out[] = $high; + $this->out[] = $low; + $this->out[] = $close; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + +class point +{ + var $out; + + function point( $x, $y, $size_px ) + { + $this->out = array(); + $this->out[] = $x; + $this->out[] = $y; + $this->out[] = $size_px; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + + +function open_flash_chart_object_str( $width, $height, $url, $use_swfobject=true, $base='' ) +{ + // + // return the HTML as a string + // + return _ofc( $width, $height, $url, $use_swfobject, $base ); +} + +function open_flash_chart_object( $width, $height, $url, $use_swfobject=true, $base='' ) +{ + // + // stream the HTML into the page + // + echo _ofc( $width, $height, $url, $use_swfobject, $base ); +} + +function _ofc( $width, $height, $url, $use_swfobject, $base ) +{ + // + // I think we may use swfobject for all browsers, + // not JUST for IE... + // + //$ie = strstr(getenv('HTTP_USER_AGENT'), 'MSIE'); + + // + // escape the & and stuff: + // + $url = urlencode($url); + + // + // output buffer + // + $out = array(); + + // + // check for http or https: + // + if (isset ($_SERVER['HTTPS'])) + { + if (strtoupper ($_SERVER['HTTPS']) == 'ON') + { + $protocol = 'https'; + } + else + { + $protocol = 'http'; + } + } + else + { + $protocol = 'http'; + } + + // + // if there are more than one charts on the + // page, give each a different ID + // + global $open_flash_chart_seqno; + $obj_id = 'chart'; + $div_name = 'flashcontent'; + + //$out[] = ''; + + if( !isset( $open_flash_chart_seqno ) ) + { + $open_flash_chart_seqno = 1; + $out[] = ''; + } + else + { + $open_flash_chart_seqno++; + $obj_id .= '_'. $open_flash_chart_seqno; + $div_name .= '_'. $open_flash_chart_seqno; + } + + if( $use_swfobject ) + { + // Using library for auto-enabling Flash object on IE, disabled-Javascript proof + $out[] = '
    '; + $out[] = ''; + $out[] = ''; + } + + return implode("\n",$out); +} + +$x = open_flash_chart_object( 300,300,"/images/open-flash-chart.swf", true); + +?> + + + +
    + + diff --git a/workflow/engine/plugins/openFlash/open_flash_chart_object.php b/workflow/engine/plugins/openFlash/open_flash_chart_object.php new file mode 100644 index 000000000..5cf831634 --- /dev/null +++ b/workflow/engine/plugins/openFlash/open_flash_chart_object.php @@ -0,0 +1,109 @@ +'; + + if( !isset( $open_flash_chart_seqno ) ) + { + $open_flash_chart_seqno = 1; + $out[] = ''; + } + else + { + $open_flash_chart_seqno++; + $obj_id .= '_'. $open_flash_chart_seqno; + $div_name .= '_'. $open_flash_chart_seqno; + } + + if( $use_swfobject ) + { + // Using library for auto-enabling Flash object on IE, disabled-Javascript proof + $out[] = '
    '; + $out[] = ''; + $out[] = ''; + } + + return implode("\n",$out); +} +?> \ No newline at end of file diff --git a/workflow/engine/plugins/openFlash/public_html/open-flash-chart.swf b/workflow/engine/plugins/openFlash/public_html/open-flash-chart.swf new file mode 100644 index 0000000000000000000000000000000000000000..85b590a28f4a5cea29eefa8c7cad6b551e29de4a GIT binary patch literal 64600 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 HtI>lMRC*G= literal 0 HcmV?d00001 diff --git a/workflow/engine/plugins/openFlash/public_html/swfobject.js b/workflow/engine/plugins/openFlash/public_html/swfobject.js new file mode 100644 index 000000000..02ca073dc --- /dev/null +++ b/workflow/engine/plugins/openFlash/public_html/swfobject.js @@ -0,0 +1,233 @@ +/** + * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ + * + * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ +if(typeof deconcept == "undefined") var deconcept = new Object(); +if(typeof deconcept.util == "undefined") deconcept.util = new Object(); +if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object(); +deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) { + if (!document.getElementById) { return; } + this.DETECT_KEY = detectKey ? detectKey : 'detectflash'; + this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY); + this.params = new Object(); + this.variables = new Object(); + this.attributes = new Array(); + if(swf) { this.setAttribute('swf', swf); } + if(id) { this.setAttribute('id', id); } + if(w) { this.setAttribute('width', w); } + if(h) { this.setAttribute('height', h); } + if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); } + this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion(); + if (!window.opera && document.all && this.installedVer.major > 7) { + // only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE + deconcept.SWFObject.doPrepUnload = true; + } + if(c) { this.addParam('bgcolor', c); } + var q = quality ? quality : 'high'; + this.addParam('quality', q); + this.setAttribute('useExpressInstall', false); + this.setAttribute('doExpressInstall', false); + var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location; + this.setAttribute('xiRedirectUrl', xir); + this.setAttribute('redirectUrl', ''); + if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); } +} +deconcept.SWFObject.prototype = { + useExpressInstall: function(path) { + this.xiSWFPath = !path ? "expressinstall.swf" : path; + this.setAttribute('useExpressInstall', true); + }, + setAttribute: function(name, value){ + this.attributes[name] = value; + }, + getAttribute: function(name){ + return this.attributes[name]; + }, + addParam: function(name, value){ + this.params[name] = value; + }, + getParams: function(){ + return this.params; + }, + addVariable: function(name, value){ + this.variables[name] = value; + }, + getVariable: function(name){ + return this.variables[name]; + }, + getVariables: function(){ + return this.variables; + }, + getVariablePairs: function(){ + var variablePairs = new Array(); + var key; + var variables = this.getVariables(); + for(key in variables){ + variablePairs[variablePairs.length] = key +"="+ variables[key]; + } + return variablePairs; + }, + getSWFHTML: function() { + var swfNode = ""; + if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture + if (this.getAttribute("doExpressInstall")) { + this.addVariable("MMplayerType", "PlugIn"); + this.setAttribute('swf', this.xiSWFPath); + } + swfNode = ' 0){ swfNode += 'flashvars="'+ pairs +'"'; } + swfNode += '/>'; + } else { // PC IE + if (this.getAttribute("doExpressInstall")) { + this.addVariable("MMplayerType", "ActiveX"); + this.setAttribute('swf', this.xiSWFPath); + } + swfNode = ''; + swfNode += ''; + var params = this.getParams(); + for(var key in params) { + swfNode += ''; + } + var pairs = this.getVariablePairs().join("&"); + if(pairs.length > 0) {swfNode += '';} + swfNode += ""; + } + return swfNode; + }, + write: function(elementId){ + if(this.getAttribute('useExpressInstall')) { + // check to see if we need to do an express install + var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]); + if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) { + this.setAttribute('doExpressInstall', true); + this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl'))); + document.title = document.title.slice(0, 47) + " - Flash Player Installation"; + this.addVariable("MMdoctitle", document.title); + } + } + if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){ + var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId; + n.innerHTML = this.getSWFHTML(); + return true; + }else{ + if(this.getAttribute('redirectUrl') != "") { + document.location.replace(this.getAttribute('redirectUrl')); + } + } + return false; + } +} + +/* ---- detection functions ---- */ +deconcept.SWFObjectUtil.getPlayerVersion = function(){ + var PlayerVersion = new deconcept.PlayerVersion([0,0,0]); + if(navigator.plugins && navigator.mimeTypes.length){ + var x = navigator.plugins["Shockwave Flash"]; + if(x && x.description) { + PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".")); + } + }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE + var axo = 1; + var counter = 3; + while(axo) { + try { + counter++; + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter); +// document.write("player v: "+ counter); + PlayerVersion = new deconcept.PlayerVersion([counter,0,0]); + } catch (e) { + axo = null; + } + } + } else { // Win IE (non mobile) + // do minor version lookup in IE, but avoid fp6 crashing issues + // see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ + try{ + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + }catch(e){ + try { + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + PlayerVersion = new deconcept.PlayerVersion([6,0,21]); + axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code) + } catch(e) { + if (PlayerVersion.major == 6) { + return PlayerVersion; + } + } + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + } catch(e) {} + } + if (axo != null) { + PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); + } + } + return PlayerVersion; +} +deconcept.PlayerVersion = function(arrVersion){ + this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0; + this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0; + this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0; +} +deconcept.PlayerVersion.prototype.versionIsValid = function(fv){ + if(this.major < fv.major) return false; + if(this.major > fv.major) return true; + if(this.minor < fv.minor) return false; + if(this.minor > fv.minor) return true; + if(this.rev < fv.rev) return false; + return true; +} +/* ---- get value of query string param ---- */ +deconcept.util = { + getRequestParameter: function(param) { + var q = document.location.search || document.location.hash; + if (param == null) { return q; } + if(q) { + var pairs = q.substring(1).split("&"); + for (var i=0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return pairs[i].substring((pairs[i].indexOf("=")+1)); + } + } + } + return ""; + } +} +/* fix for video streaming bug */ +deconcept.SWFObjectUtil.cleanupSWFs = function() { + var objects = document.getElementsByTagName("OBJECT"); + for (var i = objects.length - 1; i >= 0; i--) { + objects[i].style.display = 'none'; + for (var x in objects[i]) { + if (typeof objects[i][x] == 'function') { + objects[i][x] = function(){}; + } + } + } +} +// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/ +if (deconcept.SWFObject.doPrepUnload) { + if (!deconcept.unloadSet) { + deconcept.SWFObjectUtil.prepUnload = function() { + __flash_unloadHandler = function(){}; + __flash_savedUnloadHandler = function(){}; + window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs); + } + window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload); + deconcept.unloadSet = true; + } +} +/* add document.getElementById if needed (mobile IE < 5) */ +if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }} + +/* add some aliases for ease of use/backwards compatibility */ +var getQueryParamValue = deconcept.util.getRequestParameter; +var FlashObject = deconcept.SWFObject; // for legacy support +var SWFObject = deconcept.SWFObject; diff --git a/workflow/engine/plugins/openFlash/setupPage.xml b/workflow/engine/plugins/openFlash/setupPage.xml new file mode 100644 index 000000000..a5a5000c1 --- /dev/null +++ b/workflow/engine/plugins/openFlash/setupPage.xml @@ -0,0 +1,20 @@ + + + + + <en>Open Flash Charts Plugin</en> + + + + Open Charts Plugin, with this plugin you can see many differents charts using interative flash charts + + + + + Save + + \ No newline at end of file diff --git a/workflow/engine/plugins/pmosCommunity.php b/workflow/engine/plugins/pmosCommunity.php new file mode 100644 index 000000000..d3f6fca21 --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity.php @@ -0,0 +1,36 @@ +sFriendlyName = 'PMOS Community Plugin'; + $this->sDescription = 'Community Charts Plugin, with this plugin you can see many differents charts related to ProcessMaker Open Source Community'; + $this->sPluginFolder = 'pmosCommunity'; + $this->sSetupPage = 'setupPage'; + $this->iVersion = 0.45; + $this->aWorkspaces = array ( 'os' ); + return $res; + } + + function setup() + { + //$this->registerTrigger( 10000, 'createCaseFolder' ); + $this->registerDashboard(); + } + + function install() + { + + } + } + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->registerPlugin('pmosCommunity', __FILE__); + + + + + diff --git a/workflow/engine/plugins/pmosCommunity/chart-data.php b/workflow/engine/plugins/pmosCommunity/chart-data.php new file mode 100644 index 000000000..033686972 --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/chart-data.php @@ -0,0 +1,14 @@ +{$chartType}(); + die; + } + diff --git a/workflow/engine/plugins/pmosCommunity/chart.php b/workflow/engine/plugins/pmosCommunity/chart.php new file mode 100644 index 000000000..691953f8c --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/chart.php @@ -0,0 +1,11 @@ +sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !file_exists( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + if ( file_exists ( $fileConf ) ) { + $content = file_get_contents ( $fileConf); + $fields = unserialize ($content); + } + else + $fields = array(); + return $fields; + } + + function updateFieldsForPageSetup ( $oData) { + $content = serialize ($oData['form']); + $fileConf = PATH_PLUGINS . $this->sPluginFolder . PATH_SEP . 'config' . PATH_SEP . 'setup.conf'; + if ( !is_writable( dirname($fileConf) ) ) + throw ( new Exception ("The directory " . dirname($fileConf) . " doesn't exist or this directory is not writable." ) ); + + if ( file_exists ( $fileConf ) && !is_writable( $fileConf ) ) + throw ( new Exception ("The file $fileConf doesn't exist or this file is not writable." ) ); + + file_put_contents ( $fileConf, $content); + return true; + } + + function setup() { + } + + function getChart( $chartName ) { + $this->readConfig(); + $prePath = '/sys' . SYS_SYS . '/' . SYS_LANG . '/blank/'; + $obj = new StdClass(); + switch ($chartName) { + case 'PostByForum': + $obj->title = 'Community ProcessMaker Forum - Per Forum'; + break; + case 'ForumWeek': + $obj->title = 'Community ProcessMaker Forum - Per Week'; + break; + case 'PostByUser': + $obj->title = 'Community ProcessMaker Forum - Per User'; + break; + case 'BugsOpenByUser': + $obj->title = 'Community ProcessMaker Forum - Per Post Author'; + break; + case 'BugsByStatus': + $obj->title = 'Community ProcessMaker Forum - Bugs'; + break; + } + $obj->height = 220; + $obj->image = $prePath . 'pmosCommunity/drawChart?chart=' . $chartName . "&u="; + return $obj; + } + + //here we are defining the available charts, the dashboard setup will call this function to know the charts + function getAvailableCharts( ) { + return array ( + 'PostByForum', + 'ForumWeek', + 'PostByUser', + 'BugsOpenByUser', + 'BugsByStatus' + ); + } + + /* definition of all charts */ + /* that definition comes in two parts : + /* 1. the getXX () function to get the data from the databases + /* 2. the XX () function to draw the graph + */ + + /** chart PostByForum ***/ + /** to show the last 2 months post grouped by forum and for topic */ + function getPostByForum ( ) { + $dataSet = array(); + $past1months = mktime(0, 0, 0, date("m") -1 , date("d"), date("Y")); + + $databases = PATH_PLUGINS . 'pmosCommunity' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'; + Propel::init( $databases ); + + $con = Propel::getConnection('forum'); + $sql = "select forum_name, count(*) as cant from phpbb_posts left join phpbb_forums on ( phpbb_posts.forum_id = phpbb_forums.forum_id ) where post_time > $past1months group by forum_name " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + if ( strlen ( trim ($row['forum_name']) ) > 0 ) { + $label[] = $row['forum_name']; + $data[] = $row['cant']; + } + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + + $sql = "select forum_name, count( distinct( topic_id)) as cant from phpbb_posts left join phpbb_forums on ( phpbb_posts.forum_id = phpbb_forums.forum_id ) where post_time > $past1months group by forum_name " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + if ( strlen ( trim ($row['forum_name']) ) > 0 ) { + //$label[] = $row['forum_name']; + $series2[] = $row['cant']; + } + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['series2'] = $series2; + + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $aux = intval($max / 6 ) * 6 + 6; + $dataSet['max'] = $aux; + + return $dataSet; + } + + function PostByForum( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + + $dataSet = $this->getPostByForum(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + $dataTopicSet->addPoint(new Point( $label, $dataSet['series2'][$key] )) ; + } + + $multidataSet = new XYSeriesDataSet(); + $multidataSet->addSerie("Posts", $dataPostSet); + $multidataSet->addSerie("Topics", $dataTopicSet); + + $chart->setDataSet($multidataSet); + $chart->setTitle( "Posts by Forum ( last month ) " ); + $chart->render(); + } + + function PostByForumFlash( ) { + $dataSet = $this->getPostByForum(); + $data = $dataSet['data']; + $series2 = $dataSet['series2']; + $g = new graph(); + $g->title( ' Posts by Forum ( last month )', '{font-size: 16px;}' ); + $bar_red = new bar_3d( 50, '#3334AD' ); + $bar_red->key( 'posts', 10 ); + $bar_red->data = $data; + + $bar_blue = new bar_3d( 75, '#D54C78' ); + $bar_blue->key( 'topics', 11 ); + $bar_blue->data = $series2; + + $g->data_sets[] = $bar_red; + $g->data_sets[] = $bar_blue; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $dataSet['max'] ); + $g->y_label_steps( 6 ); + //$g->set_y_legend( 'Posts', 12, '#736AFF' ); + echo $g->render(); + } + + /** chart ForumWeek ***/ + /** to show the last 2 months post grouped by week */ + function getForumWeek ( ) { + $databases = PATH_PLUGINS . 'pmosCommunity' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'; + Propel::init( $databases ); + + $dataSet = array(); + $processObj = new Process; + $past2months = mktime(0, 0, 0, date("m") -2 , date("d"), date("Y")); + + $con = Propel::getConnection('forum'); + $sql = "select week(FROM_UNIXTIME(post_time )) as week ,count(*) as cant from phpbb_posts where post_time > $past2months group by week " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = date ( 'M d', mktime(0, 0, 0, 1 , $row['week']*7, date("Y")) ); + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function ForumWeek( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + + $dataSet = $this->getForumWeek(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + } + + $chart->setDataSet($dataPostSet); + $chart->setTitle( " Posts by Week " ); + $chart->render(); + } + + function ForumWeekFlash ( ) { + $dataSet = $this->getForumWeek(); + $data = $dataSet['data']; + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $g = new graph(); + $g->title( ' Posts by Week ', '{font-size: 16px;}' ); + $bar_red = new bar_3d( 50, '#3334AD' ); + $bar_red->key( 'week', 10 ); + $bar_red->data = $data; + + $g->data_sets[] = $bar_red; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $max ); + $g->y_label_steps( 5 ); + $g->set_y_legend( 'Posts', 12, '#736AFF' ); + echo $g->render(); + } + + /** chart PostByUser ***/ + /** to show the last 7 days grouped by user */ + function getPostByUser ( ) { + $databases = PATH_PLUGINS . 'pmosCommunity' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('forum'); + + $past7days = mktime(0, 0, 0, date("m") , date("d")-7, date("Y")); + $sql = "select username, count(*) as cant from phpbb_posts left join phpbb_users on ( poster_id = user_id ) where post_time > $past7days group by username " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = $row['username']; + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + //$dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function PostByUser ( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + + $dataSet = $this->getPostByUser(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + } + + $chart->setDataSet($dataPostSet); + //$chart->setTitle( " Posts by User" ); + $chart->render(); + } + + function PostByUserFlash ( ) { + $dataSet = $this->getPostByUser(); + $data = $dataSet['data']; + $g = new graph(); + $g->title( ' Posts by User last week '. date("Y-m-d"), '{font-size: 16px;}' ); + $max = 1; + foreach ( $dataSet['data'] as $k => $val ) if ( $val > $max ) $max = $val; + $max = intval($max / 4 ) * 4 + 4; + + $bar_red = new bar_3d( 50, '#356aa0' ); + $bar_red->key( 'posts', 10 ); + $bar_red->data = $data; + + $bar_blue = new bar_3d( 75, '#D54C78' ); + $bar_blue->key( 'completed', 10 ); + $bar_blue->data = $data; + + $g->data_sets[] = $bar_red; + //$g->data_sets[] = $bar_blue; + + $g->set_x_axis_3d( 12 ); + $g->x_axis_colour( '#909090', '#ADB5C7' ); + $g->y_axis_colour( '#909090', '#ADB5C7' ); + $g->set_x_labels( $dataSet['label'] ); + + $g->set_y_max( $max ); + $g->y_label_steps( 4 ); + $g->set_y_legend( 'Processmaker', 12, '#736AFF' ); + echo $g->render(); + } + + /** chart BugsByStatus ***/ + /** to show the bugs by status resolved, open, closed */ + function getBugsByStatus ( ) { + $databases = PATH_PLUGINS . 'pmosCommunity' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('bugs'); + + //open + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status in (20,30,40,50) " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'open'; + $data[] = $row['cant']; + + //resolved + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status = 80" ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'resolved'; + $data[] = $row['cant']; + + //closed + $sql = "SELECT count(*) as cant FROM mantis_bug_table where project_id = 31 and status = 90" ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + $label[] = 'closed'; + $data[] = $row['cant']; + + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function BugsByStatus ( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + + $dataSet = $this->getBugsByStatus(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + } + + $chart->setDataSet($dataPostSet); + //$chart->setTitle( " Posts by User" ); + $chart->render(); + } + + function BugsByStatusFlash ( ) { + $dataSet = $this->getBugsByStatus(); + $data = $dataSet['data']; + $g = new graph(); + $g->title( ' Posts by User last week '. date("Y-m-d"), '{font-size: 16px;}' ); + + $g->pie(70,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Bugs by Status', '{font-size:18px; color: #d01f3c}' ); + echo $g->render(); + } + + /** chart BugsOpenByUser ***/ + /** to show the bugs in OPEN status by user */ + function getBugsOpenByUser ( ) { + $databases = PATH_PLUGINS . 'pmosCommunity' . PATH_SEP . 'config' . PATH_SEP . 'databases.php'; + Propel::init( $databases ); + + $dataSet = array(); + $con = Propel::getConnection('bugs'); + + $sql = "SELECT username, count(*) as cant FROM mantis_bug_table left join mantis_user_table on ( mantis_user_table.id = handler_id) where project_id = 31 and status in (20,30,40,50) group by username " ; + $stmt = $con->createStatement(); + $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_ASSOC); + $rs->next(); + $row = $rs->getRow(); + while ( is_array ( $row ) ) { + $label[] = $row['username']; + $data[] = $row['cant']; + $rs->next(); + $row = $rs->getRow(); + } + $dataSet['data'] = $data; + $dataSet['label'] = $label; + return $dataSet; + } + + function BugsOpenByUser ( ) { + G::LoadThirdParty("libchart/classes", "libchart" ); + $chart = new VerticalBarChart(430, 220); + + $dataSet = $this->getBugsOpenByUser(); + $dataPostSet = new XYDataSet(); + $dataTopicSet = new XYDataSet(); + foreach ( $dataSet['label'] as $key => $label ) { + $dataPostSet->addPoint(new Point( $label, $dataSet['data'][$key] )) ; + } + + $chart->setDataSet($dataPostSet); + //$chart->setTitle( " Posts by User" ); + $chart->render(); + + } + + function BugsOpenByUserFlash ( ) { + $dataSet = $this->getBugsOpenByUser(); + $data = $dataSet['data']; + $g = new graph(); + $g->bg_colour = '#EFFFEF'; + $g->title( ' Posts by User last week '. date("Y-m-d"), '{font-size: 16px;}' ); + + $g->pie(70,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Bugs by Status', '{font-size:18px; color: #d01f3c}' ); + echo $g->render(); + /* + $dataSet = $this->getBugsOpenByUser(); + $data = $dataSet['data']; + $g = new graph(); + $g->pie(80,'#505050','{font-size: 12px; color: #404040;'); + $g->pie_values( $data, $dataSet['label'] ); + $g->pie_slice_colours( array('#d01f3c','#356aa0','#C79810','#D54C78') ); + $g->set_tool_tip( '#val# #x_label#' ); + $g->title( 'Open Bugs by User', '{font-size:18px; color: #d01f3c}' ); + echo $g->render();*/ + } + +} diff --git a/workflow/engine/plugins/pmosCommunity/config/databases.php b/workflow/engine/plugins/pmosCommunity/config/databases.php new file mode 100644 index 000000000..091d2768a --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/config/databases.php @@ -0,0 +1,9 @@ + diff --git a/workflow/engine/plugins/pmosCommunity/config/setup.conf b/workflow/engine/plugins/pmosCommunity/config/setup.conf new file mode 100644 index 000000000..70cf5bfbf --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/config/setup.conf @@ -0,0 +1 @@ +a:1:{s:6:"ACCEPT";s:4:"Save";} \ No newline at end of file diff --git a/workflow/engine/plugins/pmosCommunity/drawChart.php b/workflow/engine/plugins/pmosCommunity/drawChart.php new file mode 100644 index 000000000..48500961f --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/drawChart.php @@ -0,0 +1,14 @@ +{$chartType}(); + die; + } + \ No newline at end of file diff --git a/workflow/engine/plugins/pmosCommunity/open-flash-chart.php b/workflow/engine/plugins/pmosCommunity/open-flash-chart.php new file mode 100644 index 000000000..b1cd90627 --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/open-flash-chart.php @@ -0,0 +1,1769 @@ +data_sets = array(); + + + $this->data = array(); + $this->links = array(); + $this->width = 250; + $this->height = 200; + $this->js_path = '/images/'; + $this->swf_path = ''; + $this->x_labels = array(); + $this->y_min = ''; + $this->y_max = ''; + $this->x_min = ''; + $this->x_max = ''; + $this->y_steps = ''; + $this->title = ''; + $this->title_style = ''; + $this->occurence = 0; + + $this->x_offset = ''; + + $this->x_tick_size = -1; + + $this->y2_max = ''; + $this->y2_min = ''; + + // GRID styles: + $this->x_axis_colour = ''; + $this->x_axis_3d = ''; + $this->x_grid_colour = ''; + $this->x_axis_steps = 1; + $this->y_axis_colour = ''; + $this->y_grid_colour = ''; + $this->y2_axis_colour = ''; + + // AXIS LABEL styles: + $this->x_label_style = ''; + $this->y_label_style = ''; + $this->y_label_style_right = ''; + + + // AXIS LEGEND styles: + $this->x_legend = ''; + $this->x_legend_size = 20; + $this->x_legend_colour = '#000000'; + + $this->y_legend = ''; + $this->y_legend_right = ''; + //$this->y_legend_size = 20; + //$this->y_legend_colour = '#000000'; + + $this->lines = array(); + $this->line_default['type'] = 'line'; + $this->line_default['values'] = '3,#87421F'; + $this->js_line_default = 'so.addVariable("line","3,#87421F");'; + + $this->bg_colour = ''; + $this->bg_image = ''; + + $this->inner_bg_colour = ''; + $this->inner_bg_colour_2 = ''; + $this->inner_bg_angle = ''; + + // PIE chart ------------ + $this->pie = ''; + $this->pie_values = ''; + $this->pie_colours = ''; + $this->pie_labels = ''; + + $this->tool_tip = ''; + + // which data lines are attached to the + // right Y axis? + $this->y2_lines = array(); + + // Number formatting: + $this->y_format=''; + $this->num_decimals=''; + $this->is_fixed_num_decimals_forced=''; + $this->is_decimal_separator_comma=''; + $this->is_thousand_separator_disabled=''; + + $this->output_type = ''; + + // + // set some default value incase the user forgets + // to set them, so at least they see *something* + // even is it is only the axis and some ticks + // + $this->set_y_min( 0 ); + $this->set_y_max( 20 ); + $this->set_x_axis_steps( 1 ); + $this->y_label_steps( 5 ); + } + + /** + * Set the unique_id to use for the flash object id. + */ + function set_unique_id() + { + $this->unique_id = uniqid(rand(), true); + } + + /** + * Get the flash object ID for the last rendered object. + */ + function get_unique_id() + { + return ($this->unique_id); + } + + /** + * Set the base path for the swfobject.js + * + * @param base_path a string argument. + * The path to the swfobject.js file + */ + function set_js_path($path) + { + $this->js_path = $path; + } + + /** + * Set the base path for the open-flash-chart.swf + * + * @param path a string argument. + * The path to the open-flash-chart.swf file + */ + function set_swf_path($path) + { + $this->swf_path = $path; + } + + /** + * Set the type of output data. + * + * @param type a string argument. + * The type of data. Currently only type is js, or nothing. + */ + function set_output_type($type) + { + $this->output_type = $type; + } + + /** + * returns the next line label for multiple lines. + */ + function next_line() + { + $line_num = ''; + if( count( $this->lines ) > 0 ) + $line_num = '_'. (count( $this->lines )+1); + + return $line_num; + } + + // escape commas (,) + function esc( $text ) + { + // we replace the comma so it is not URL escaped + // if it is, flash just thinks it is a comma + // which is no good if we are splitting the + // string on commas. + $tmp = str_replace( ',', '#comma#', $text ); + //$tmp = utf8_encode( $tmp ); + // now we urlescape all dodgy characters (like & % $ etc..) + return urlencode( $tmp ); + } + + /** + * Format the text to the type of output. + */ + function format_output($function,$values) + { + if($this->output_type == 'js') + { + $tmp = 'so.addVariable("'. $function .'","'. $values . '");'; + } + else + { + $tmp = '&'. $function .'='. $values .'&'; + } + + return $tmp; + } + + /** + * Set the text and style of the title. + * + * @param title a string argument. + * The text of the title. + * @param style a string. + * CSS styling of the title. + */ + function set_title( $title, $style='' ) + { + $this->title = $this->esc( $title ); + if( strlen( $style ) > 0 ) + $this->title_style = $style; + } + + /** + * Set the width of the chart. + * + * @param width an int argument. + * The width of the chart frame. + */ + function set_width( $width ) + { + $this->width = $width; + } + + /** + * Set the height of the chart. + * + * @param height an int argument. + * The height of the chart frame. + */ + function set_height( $height ) + { + $this->height = $height; + } + + /** + * Set the base path of the swfobject. + * + * @param base a string argument. + * The base path of the swfobject. + */ + function set_base( $base='/images/' ) + { + $this->base = $base; + } + + // Number formatting: + function set_y_format( $val ) + { + $this->y_format = $val; + } + + function set_num_decimals( $val ) + { + $this->num_decimals = $val; + } + + function set_is_fixed_num_decimals_forced( $val ) + { + $this->is_fixed_num_decimals_forced = $val?'true':'false'; + } + + function set_is_decimal_separator_comma( $val ) + { + $this->is_decimal_separator_comma = $val?'true':'false'; + } + + function set_is_thousand_separator_disabled( $val ) + { + $this->is_thousand_separator_disabled = $val?'true':'false'; + } + + /** + * Set the data for the chart + * @param a an array argument. + * An array of the data to add to the chart. + */ + function set_data( $a ) + { + $this->data[] = implode(',',$a); + } + + // UGH, these evil functions are making me fell ill + function set_links( $links ) + { + // TO DO escape commas: + $this->links[] = implode(',',$links); + } + + // $val is a boolean + function set_x_offset( $val ) + { + $this->x_offset = $val?'true':'false'; + } + + /** + * Set the tooltip to be displayed on each chart item.\n + * \n + * Replaceable tokens that can be used in the string include: \n + * #val# - The actual value of whatever the mouse is over. \n + * #key# - The key string. \n + * \
    - New line. \n + * #x_label# - The X label string. \n + * #x_legend# - The X axis legend text. \n + * Default string is: "#x_label#
    #val#" \n + * + * @param tip a string argument. + * A formatted string to show as the tooltip. + */ + function set_tool_tip( $tip ) + { + $this->tool_tip = $this->esc( $tip ); + } + + /** + * Set the x axis labels + * + * @param a an array argument. + * An array of the x axis labels. + */ + function set_x_labels( $a ) + { + $tmp = array(); + foreach( $a as $item ) + $tmp[] = $this->esc( $item ); + $this->x_labels = $tmp; + } + + /** + * Set the look and feel of the x axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + * @param orientation an int argument. + * The orientation of the x-axis text. + * 0 - Horizontal + * 1 - Vertical + * 2 - 45 degrees + * @param step an int argument. + * Show the label on every $step label. + * @param grid_colour a string argument. + */ + function set_x_label_style( $size, $colour='', $orientation=0, $step=-1, $grid_colour='' ) + { + $this->x_label_style = $size; + + if( strlen( $colour ) > 0 ) + $this->x_label_style .= ','. $colour; + + if( $orientation > -1 ) + $this->x_label_style .= ','. $orientation; + + if( $step > 0 ) + $this->x_label_style .= ','. $step; + + if( strlen( $grid_colour ) > 0 ) + $this->x_label_style .= ','. $grid_colour; + } + + /** + * Set the background colour. + * @param colour a string argument. + * The hex colour value. + */ + function set_bg_colour( $colour ) + { + $this->bg_colour = $colour; + } + + /** + * Set a background image. + * @param url a string argument. + * The location of the image. + * @param x a string argument. + * The x location of the image. 'Right', 'Left', 'Center' + * @param y a string argument. + * The y location of the image. 'Top', 'Bottom', 'Middle' + */ + function set_bg_image( $url, $x='center', $y='center' ) + { + $this->bg_image = $url; + $this->bg_image_x = $x; + $this->bg_image_y = $y; + } + + /** + * Attach a set of data (a line, area or bar chart) to the right Y axis. + * @param data_number an int argument. + * The numbered order the data was attached using set_data. + */ + function attach_to_y_right_axis( $data_number ) + { + $this->y2_lines[] = $data_number; + } + + /** + * Set the background colour of the grid portion of the chart. + * @param col a string argument. + * The hex colour value of the background. + * @param col2 a string argument. + * The hex colour value of the second colour if you want a gradient. + * @param angle an int argument. + * The angle in degrees to make the gradient. + */ + function set_inner_background( $col, $col2='', $angle=-1 ) + { + $this->inner_bg_colour = $col; + + if( strlen($col2) > 0 ) + $this->inner_bg_colour_2 = $col2; + + if( $angle != -1 ) + $this->inner_bg_angle = $angle; + } + + /** + * Internal function to build the y label style for y and y2 + */ + function _set_y_label_style( $size, $colour ) + { + $tmp = $size; + + if( strlen( $colour ) > 0 ) + $tmp .= ','. $colour; + return $tmp; + } + + /** + * Set the look and feel of the y axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + */ + function set_y_label_style( $size, $colour='' ) + { + $this->y_label_style = $this->_set_y_label_style( $size, $colour ); + } + + /** + * Set the look and feel of the right y axis labels + * + * @param font_size an int argument. + * The font size. + * @param colour a string argument. + * The hex colour value. + */ + function set_y_right_label_style( $size, $colour='' ) + { + $this->y_label_style_right = $this->_set_y_label_style( $size, $colour ); + } + + function set_x_max( $max ) + { + $this->x_max = floatval( $max ); + } + + function set_x_min( $min ) + { + $this->x_min = floatval( $min ); + } + + /** + * Set the maximum value of the y axis. + * + * @param max an float argument. + * The maximum value. + */ + function set_y_max( $max ) + { + $this->y_max = floatval( $max ); + } + + /** + * Set the minimum value of the y axis. + * + * @param min an float argument. + * The minimum value. + */ + function set_y_min( $min ) + { + $this->y_min = floatval( $min ); + } + + /** + * Set the maximum value of the right y axis. + * + * @param max an float argument. + * The maximum value. + */ + function set_y_right_max( $max ) + { + $this->y2_max = floatval($max); + } + + /** + * Set the minimum value of the right y axis. + * + * @param min an float argument. + * The minimum value. + */ + function set_y_right_min( $min ) + { + $this->y2_min = floatval($min); + } + + /** + * Show the y label on every $step label. + * + * @param val an int argument. + * Show the label on every $step label. + */ + function y_label_steps( $val ) + { + $this->y_steps = intval( $val ); + } + + function title( $title, $style='' ) + { + $this->title = $this->esc( $title ); + if( strlen( $style ) > 0 ) + $this->title_style = $style; + } + + /** + * Set the parameters of the x legend. + * + * @param text a string argument. + * The text of the x legend. + * @param font_size an int argument. + * The font size of the x legend text. + * @param colour a string argument + * The hex value of the font colour. + */ + function set_x_legend( $text, $size=-1, $colour='' ) + { + $this->x_legend = $this->esc( $text ); + if( $size > -1 ) + $this->x_legend_size = $size; + + if( strlen( $colour )>0 ) + $this->x_legend_colour = $colour; + } + + /** + * Set the size of the x label ticks. + * + * @param size an int argument. + * The size of the ticks in pixels. + */ + function set_x_tick_size( $size ) + { + if( $size > 0 ) + $this->x_tick_size = $size; + } + + /** + * Set how often you would like to show a tick on the x axis. + * + * @param steps an int argument. + * Show a tick ever $steps. + */ + function set_x_axis_steps( $steps ) + { + if ( $steps > 0 ) + $this->x_axis_steps = $steps; + } + + /** + * Set the depth in pixels of the 3D X axis slab. + * + * @param size an int argument. + * The depth in pixels of the 3D X axis. + */ + function set_x_axis_3d( $size ) + { + if( $size > 0 ) + $this->x_axis_3d = intval($size); + } + + /** + * The private method of building the y legend output. + */ + function _set_y_legend( $text, $size, $colour ) + { + $tmp = $text; + + if( $size > -1 ) + $tmp .= ','. $size; + + if( strlen( $colour )>0 ) + $tmp .= ','. $colour; + + return $tmp; + } + + /** + * Set the parameters of the y legend. + * + * @param text a string argument. + * The text of the y legend. + * @param font_size an int argument. + * The font size of the y legend text. + * @param colour a string argument + * The hex colour value of the font colour. + */ + function set_y_legend( $text, $size=-1, $colour='' ) + { + $this->y_legend = $this->_set_y_legend( $text, $size, $colour ); + } + + /** + * Set the parameters of the right y legend. + * + * @param text a string argument. + * The text of the right y legend. + * @param font_size an int argument. + * The font size of the right y legend text. + * @param colour a string argument + * The hex value of the font colour. + */ + function set_y_right_legend( $text, $size=-1, $colour='' ) + { + $this->y_legend_right = $this->_set_y_legend( $text, $size, $colour ); + } + + /** + * Set the colour of the x axis line and grid. + * + * @param axis a string argument. + * The hex colour value of the x axis line. + * @param grid a string argument. + * The hex colour value of the x axis grid. + */ + function x_axis_colour( $axis, $grid='' ) + { + $this->x_axis_colour = $axis; + $this->x_grid_colour = $grid; + } + + /** + * Set the colour of the y axis line and grid. + * + * @param axis a string argument. + * The hex colour value of the y axis line. + * @param grid a string argument. + * The hex colour value of the y axis grid. + */ + function y_axis_colour( $axis, $grid='' ) + { + $this->y_axis_colour = $axis; + + if( strlen( $grid ) > 0 ) + $this->y_grid_colour = $grid; + } + + /** + * Set the colour of the right y axis line. + * + * @param colour a string argument. + * The hex colour value of the right y axis line. + */ + function y_right_axis_colour( $colour ) + { + $this->y2_axis_colour = $colour; + } + + /** + * Draw a line without markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label + * @param circles an int argument + * Need to find out. + */ + function line( $width, $colour='', $text='', $size=-1, $circles=-1 ) + { + $type = 'line'. $this->next_line(); + + $description = ''; + if( $width > 0 ) + { + $description .= $width; + $description .= ','. $colour; + } + + if( strlen( $text ) > 0 ) + { + $description.= ','. $text; + $description .= ','. $size; + } + + if( $circles > 0 ) + $description .= ','. $circles; + + $this->lines[$type] = $description; + } + + /** + * Draw a line with solid dot markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function line_dot( $width, $dot_size, $colour, $text='', $font_size='' ) + { + $type = 'line_dot'. $this->next_line(); + + $description = "$width,$colour,$text"; + + if( strlen( $font_size ) > 0 ) + $description .= ",$font_size,$dot_size"; + + $this->lines[$type] = $description; + } + + /** + * Draw a line with hollow dot markers on values. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function line_hollow( $width, $dot_size, $colour, $text='', $font_size='' ) + { + $type = 'line_hollow'. $this->next_line(); + + $description = "$width,$colour,$text"; + + if( strlen( $font_size ) > 0 ) + $description .= ",$font_size,$dot_size"; + + $this->lines[$type] = $description; + } + + /** + * Draw an area chart. + * + * @param width an int argument. + * The width of the line in pixels. + * @param dot_size an int argument. + * Size in pixels of the dot. + * @param colour a string argument. + * The hex colour value of the line. + * @param alpha an int argument. + * The percentage of transparency of the fill colour. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + * @param fill_colour a string argument. + * The hex colour value of the fill colour. + */ + function area_hollow( $width, $dot_size, $colour, $alpha, $text='', $font_size='', $fill_colour='' ) + { + $type = 'area_hollow'. $this->next_line(); + + $description = "$width,$dot_size,$colour,$alpha"; + + if( strlen( $text ) > 0 ) + $description .= ",$text,$font_size"; + + if( strlen( $fill_colour ) > 0 ) + $description .= ','. $fill_colour; + + $this->lines[$type] = $description; + } + + /** + * Draw a bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a bar chart with an outline. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param colour_outline a strng argument. + * The hex colour value of the outline. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_filled( $alpha, $colour, $colour_outline, $text='', $size=-1 ) + { + $type = 'filled_bar'. $this->next_line(); + + $description = "$alpha,$colour,$colour_outline,$text,$size"; + + $this->lines[$type] = $description; + } + + function bar_sketch( $alpha, $offset, $colour, $colour_outline, $text='', $size=-1 ) + { + $type = 'bar_sketch'. $this->next_line(); + + $description = "$alpha,$offset,$colour,$colour_outline,$text,$size"; + + $this->lines[$type] = $description; + } + + /** + * Draw a 3D bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_3D( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar_3d'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a 3D bar chart that looks like glass. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param outline_colour a string argument. + * The hex colour value of the outline. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_glass( $alpha, $colour, $outline_colour, $text='', $size=-1 ) + { + $type = 'bar_glass'. $this->next_line(); + + $description = $alpha .','. $colour .','. $outline_colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + /** + * Draw a faded bar chart. + * + * @param alpha an int argument. + * The percentage of transparency of the bar colour. + * @param colour a string argument. + * The hex colour value of the line. + * @param text a string argument. + * The label of the line. + * @param font_size an int argument. + * Font size of the label. + */ + function bar_fade( $alpha, $colour='', $text='', $size=-1 ) + { + $type = 'bar_fade'. $this->next_line(); + + $description = $alpha .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + } + + function candle( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'candle'. $this->next_line(); + + $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + function hlc( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'hlc'. $this->next_line(); + + $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + function scatter( $data, $line_width, $colour, $text='', $size=-1 ) + { + $type = 'scatter'. $this->next_line(); + + $description = $line_width .','. $colour .','. $text .','. $size; + + $this->lines[$type] = $description; + + $a = array(); + foreach( $data as $can ) + $a[] = $can->toString(); + + $this->data[] = implode(',',$a); + } + + + // + // Patch by, Jeremy Miller (14th Nov, 2007) + // + /** + * Draw a pie chart. + * + * @param alpha an int argument. + * The percentage of transparency of the pie colour. + * @param $style a string argument. + * CSS style string + * @param label_colour a string argument. + * The hex colour value of the label. + * @param gradient a boolean argument. + * Use a gradient true or false. + * @param border_size an int argument. + * Size of the border in pixels. + */ + function pie( $alpha, $line_colour, $style, $gradient = true, $border_size = false ) + { + $this->pie = $alpha.','.$line_colour.','.$style; + if( !$gradient ) + { + $this->pie .= ','.!$gradient; + } + if ($border_size) + { + if ($gradient === false) + { + $this->pie .= ','; + } + $this->pie .= ','.$border_size; + } + } + + /** + * Set the values of the pie chart. + * + * @param values an array argument. + * An array of the values for the pie chart. + * @param labels an array argument. + * An array of the labels for the pie pieces. + * @param links an array argument. + * An array of the links to the pie pieces. + */ + function pie_values( $values, $labels=array(), $links=array() ) + { + $this->pie_values = implode(',',$values); + $this->pie_labels = implode(',',$labels); + $this->pie_links = implode(",",$links); + } + + /** + * Set the pie slice colours. + * + * @param colours an array argument. + * The hex colour values of the pie pieces. + */ + function pie_slice_colours( $colours ) + { + $this->pie_colours = implode(',',$colours); + } + + + /** + * Render the output. + */ + function render() + { + $tmp = array(); + + //echo headers_sent() ?'yes':'no'; + if( !headers_sent() ) + header('content-type: text; charset: utf-8'); + + if($this->output_type == 'js') + { + $this->set_unique_id(); + + $tmp[] = '
    '; + $tmp[] = ''; + $tmp[] = ''; + } + + return implode("\r\n",$tmp); + } +} + +class line +{ + var $line_width; + var $colour; + var $_key; + var $key; + var $key_size; + // hold the data + var $data; + // extra tool tip info: + var $tips; + + function line( $line_width, $colour ) + { + $this->var = 'line'; + + $this->line_width = $line_width; + $this->colour = $colour; + $this->data = array(); + $this->links = array(); + $this->tips = array(); + $this->_key = false; + } + + + function key( $key, $size ) + { + $this->_key = true; + $this->key = graph::esc( $key ); + $this->key_size = $size; + } + + function add( $data ) + { + $this->data[] = $data; + } + + function add_link( $data, $link ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + } + + function add_data_tip( $data, $tip ) + { + $this->data[] = $data; + $this->tips[] = graph::esc( $tip ); + } + + function add_data_link_tip( $data, $link, $tip ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + $this->tips[] = graph::esc( $tip ); + } + + // return the variables for this chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->line_width; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } + + function toString( $output_type, $set_num ) + { + $values = implode( ',', $this->_get_variable_list() ); + + $tmp = array(); + + if( $output_type == 'js' ) + { + $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; + + $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; + + if( count( $this->links ) > 0 ) + $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; + + if( count( $this->tips ) > 0 ) + $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; + + } + else + { + $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; + $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; + + if( count( $this->links ) > 0 ) + $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; + + if( count( $this->tips ) > 0 ) + $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; + } + + return implode( "\r\n", $tmp ); + } +} + +class line_hollow extends line +{ + var $dot_size; + + function line_hollow( $line_width, $dot_size, $colour ) + { + parent::line( $line_width, $colour ); + $this->var = 'line_hollow'; + $this->dot_size = $dot_size; + } + + // return the variables for this chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->line_width; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + else + { + $values[] = ''; + $values[] = ''; + } + $values[] = $this->dot_size; + + return $values; + } +} + +class line_dot extends line_hollow +{ + function line_dot( $line_width, $dot_size, $colour ) + { + parent::line_dot( $line_width, $colour ); + $this->var = 'line_dot'; + } +} + +class bar +{ + var $colour; + var $alpha; + var $data; + var $links; + var $_key; + var $key; + var $key_size; + var $var; + // extra tool tip info: + var $tips; + + function bar( $alpha, $colour ) + { + $this->var = 'bar'; + + $this->alpha = $alpha; + $this->colour = $colour; + $this->data = array(); + $this->links = array(); + $this->tips = array(); + $this->_key = false; + } + + function key( $key, $size ) + { + $this->_key = true; + $this->key = graph::esc( $key ); + $this->key_size = $size; + } + + function add( $data ) + { + $this->data[] = $data; + } + + function add_link( $data, $link ) + { + $this->data[] = $data; + $this->links[] = graph::esc( $link ); + } + + function add_data_tip( $data, $tip ) + { + $this->data[] = $data; + $this->tips[] = graph::esc( $tip ); + } + + // return the variables for this + // bar chart + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } + + function toString( $output_type, $set_num ) + { + $values = implode( ',', $this->_get_variable_list() ); + + $tmp = array(); + + if( $output_type == 'js' ) + { + $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; + + $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; + + if( count( $this->links ) > 0 ) + $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; + + if( count( $this->tips ) > 0 ) + $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; + + } + else + { + $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; + $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; + + if( count( $this->links ) > 0 ) + $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; + + if( count( $this->tips ) > 0 ) + $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; + } + + return implode( "\r\n", $tmp ); + } + +} + +class bar_3d extends bar +{ + function bar_3d( $alpha, $colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'bar_3d'; + } +} + +class bar_fade extends bar +{ + function bar_fade( $alpha, $colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'bar_fade'; + } +} + +class bar_outline extends bar +{ + var $outline_colour; + + function bar_outline( $alpha, $colour, $outline_colour ) + { + parent::bar( $alpha, $colour ); + $this->var = 'filled_bar'; + $this->outline_colour = $outline_colour; + } + + // override the base method + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->colour; + $values[] = $this->outline_colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } +} + +class bar_glass extends bar_outline +{ + function bar_glass( $alpha, $colour, $outline_colour ) + { + parent::bar_outline( $alpha, $colour, $outline_colour ); + $this->var = 'bar_glass'; + } +} + +// +// this has an outline colour and a 'jiggle' parameter +// called offset +// +class bar_sketch extends bar_outline +{ + var $offset; + + function bar_sketch( $alpha, $offset, $colour, $outline_colour ) + { + parent::bar_outline( $alpha, $colour, $outline_colour ); + $this->var = 'bar_sketch'; + $this->offset = $offset; + } + + // override the base method + function _get_variable_list() + { + $values = array(); + $values[] = $this->alpha; + $values[] = $this->offset; + $values[] = $this->colour; + $values[] = $this->outline_colour; + + if( $this->_key ) + { + $values[] = $this->key; + $values[] = $this->key_size; + } + + return $values; + } +} + +class candle +{ + var $out; + + function candle( $high, $open, $close, $low ) + { + $this->out = array(); + $this->out[] = $high; + $this->out[] = $open; + $this->out[] = $close; + $this->out[] = $low; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + +class hlc +{ + var $out; + + function hlc( $high, $low, $close ) + { + $this->out = array(); + $this->out[] = $high; + $this->out[] = $low; + $this->out[] = $close; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + +class point +{ + var $out; + + function point( $x, $y, $size_px ) + { + $this->out = array(); + $this->out[] = $x; + $this->out[] = $y; + $this->out[] = $size_px; + } + + function toString() + { + return '['. implode( ',', $this->out ) .']'; + } +} + + +function open_flash_chart_object_str( $width, $height, $url, $use_swfobject=true, $base='' ) +{ + // + // return the HTML as a string + // + return _ofc( $width, $height, $url, $use_swfobject, $base ); +} + +function open_flash_chart_object( $width, $height, $url, $use_swfobject=true, $base='' ) +{ + // + // stream the HTML into the page + // + echo _ofc( $width, $height, $url, $use_swfobject, $base ); +} + +function _ofc( $width, $height, $url, $use_swfobject, $base ) +{ + // + // I think we may use swfobject for all browsers, + // not JUST for IE... + // + //$ie = strstr(getenv('HTTP_USER_AGENT'), 'MSIE'); + + // + // escape the & and stuff: + // + $url = urlencode($url); + + // + // output buffer + // + $out = array(); + + // + // check for http or https: + // + if (isset ($_SERVER['HTTPS'])) + { + if (strtoupper ($_SERVER['HTTPS']) == 'ON') + { + $protocol = 'https'; + } + else + { + $protocol = 'http'; + } + } + else + { + $protocol = 'http'; + } + + // + // if there are more than one charts on the + // page, give each a different ID + // + global $open_flash_chart_seqno; + $obj_id = 'chart'; + $div_name = 'flashcontent'; + + //$out[] = ''; + + if( !isset( $open_flash_chart_seqno ) ) + { + $open_flash_chart_seqno = 1; + $out[] = ''; + } + else + { + $open_flash_chart_seqno++; + $obj_id .= '_'. $open_flash_chart_seqno; + $div_name .= '_'. $open_flash_chart_seqno; + } + + if( $use_swfobject ) + { + // Using library for auto-enabling Flash object on IE, disabled-Javascript proof + $out[] = '
    '; + $out[] = ''; + $out[] = ''; + } + + return implode("\n",$out); +} + +$x = open_flash_chart_object( 300,300,"/images/open-flash-chart.swf", true); + +?> + + + +
    + + diff --git a/workflow/engine/plugins/pmosCommunity/open_flash_chart_object.php b/workflow/engine/plugins/pmosCommunity/open_flash_chart_object.php new file mode 100644 index 000000000..5cf831634 --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/open_flash_chart_object.php @@ -0,0 +1,109 @@ +'; + + if( !isset( $open_flash_chart_seqno ) ) + { + $open_flash_chart_seqno = 1; + $out[] = ''; + } + else + { + $open_flash_chart_seqno++; + $obj_id .= '_'. $open_flash_chart_seqno; + $div_name .= '_'. $open_flash_chart_seqno; + } + + if( $use_swfobject ) + { + // Using library for auto-enabling Flash object on IE, disabled-Javascript proof + $out[] = '
    '; + $out[] = ''; + $out[] = ''; + } + + return implode("\n",$out); +} +?> \ No newline at end of file diff --git a/workflow/engine/plugins/pmosCommunity/public_html/open-flash-chart.swf b/workflow/engine/plugins/pmosCommunity/public_html/open-flash-chart.swf new file mode 100644 index 0000000000000000000000000000000000000000..85b590a28f4a5cea29eefa8c7cad6b551e29de4a GIT binary patch literal 64600 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 HtI>lMRC*G= literal 0 HcmV?d00001 diff --git a/workflow/engine/plugins/pmosCommunity/public_html/swfobject.js b/workflow/engine/plugins/pmosCommunity/public_html/swfobject.js new file mode 100644 index 000000000..02ca073dc --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/public_html/swfobject.js @@ -0,0 +1,233 @@ +/** + * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ + * + * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ +if(typeof deconcept == "undefined") var deconcept = new Object(); +if(typeof deconcept.util == "undefined") deconcept.util = new Object(); +if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object(); +deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) { + if (!document.getElementById) { return; } + this.DETECT_KEY = detectKey ? detectKey : 'detectflash'; + this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY); + this.params = new Object(); + this.variables = new Object(); + this.attributes = new Array(); + if(swf) { this.setAttribute('swf', swf); } + if(id) { this.setAttribute('id', id); } + if(w) { this.setAttribute('width', w); } + if(h) { this.setAttribute('height', h); } + if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); } + this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion(); + if (!window.opera && document.all && this.installedVer.major > 7) { + // only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE + deconcept.SWFObject.doPrepUnload = true; + } + if(c) { this.addParam('bgcolor', c); } + var q = quality ? quality : 'high'; + this.addParam('quality', q); + this.setAttribute('useExpressInstall', false); + this.setAttribute('doExpressInstall', false); + var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location; + this.setAttribute('xiRedirectUrl', xir); + this.setAttribute('redirectUrl', ''); + if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); } +} +deconcept.SWFObject.prototype = { + useExpressInstall: function(path) { + this.xiSWFPath = !path ? "expressinstall.swf" : path; + this.setAttribute('useExpressInstall', true); + }, + setAttribute: function(name, value){ + this.attributes[name] = value; + }, + getAttribute: function(name){ + return this.attributes[name]; + }, + addParam: function(name, value){ + this.params[name] = value; + }, + getParams: function(){ + return this.params; + }, + addVariable: function(name, value){ + this.variables[name] = value; + }, + getVariable: function(name){ + return this.variables[name]; + }, + getVariables: function(){ + return this.variables; + }, + getVariablePairs: function(){ + var variablePairs = new Array(); + var key; + var variables = this.getVariables(); + for(key in variables){ + variablePairs[variablePairs.length] = key +"="+ variables[key]; + } + return variablePairs; + }, + getSWFHTML: function() { + var swfNode = ""; + if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture + if (this.getAttribute("doExpressInstall")) { + this.addVariable("MMplayerType", "PlugIn"); + this.setAttribute('swf', this.xiSWFPath); + } + swfNode = ' 0){ swfNode += 'flashvars="'+ pairs +'"'; } + swfNode += '/>'; + } else { // PC IE + if (this.getAttribute("doExpressInstall")) { + this.addVariable("MMplayerType", "ActiveX"); + this.setAttribute('swf', this.xiSWFPath); + } + swfNode = ''; + swfNode += ''; + var params = this.getParams(); + for(var key in params) { + swfNode += ''; + } + var pairs = this.getVariablePairs().join("&"); + if(pairs.length > 0) {swfNode += '';} + swfNode += ""; + } + return swfNode; + }, + write: function(elementId){ + if(this.getAttribute('useExpressInstall')) { + // check to see if we need to do an express install + var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]); + if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) { + this.setAttribute('doExpressInstall', true); + this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl'))); + document.title = document.title.slice(0, 47) + " - Flash Player Installation"; + this.addVariable("MMdoctitle", document.title); + } + } + if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){ + var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId; + n.innerHTML = this.getSWFHTML(); + return true; + }else{ + if(this.getAttribute('redirectUrl') != "") { + document.location.replace(this.getAttribute('redirectUrl')); + } + } + return false; + } +} + +/* ---- detection functions ---- */ +deconcept.SWFObjectUtil.getPlayerVersion = function(){ + var PlayerVersion = new deconcept.PlayerVersion([0,0,0]); + if(navigator.plugins && navigator.mimeTypes.length){ + var x = navigator.plugins["Shockwave Flash"]; + if(x && x.description) { + PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".")); + } + }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE + var axo = 1; + var counter = 3; + while(axo) { + try { + counter++; + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter); +// document.write("player v: "+ counter); + PlayerVersion = new deconcept.PlayerVersion([counter,0,0]); + } catch (e) { + axo = null; + } + } + } else { // Win IE (non mobile) + // do minor version lookup in IE, but avoid fp6 crashing issues + // see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ + try{ + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + }catch(e){ + try { + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + PlayerVersion = new deconcept.PlayerVersion([6,0,21]); + axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code) + } catch(e) { + if (PlayerVersion.major == 6) { + return PlayerVersion; + } + } + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + } catch(e) {} + } + if (axo != null) { + PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); + } + } + return PlayerVersion; +} +deconcept.PlayerVersion = function(arrVersion){ + this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0; + this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0; + this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0; +} +deconcept.PlayerVersion.prototype.versionIsValid = function(fv){ + if(this.major < fv.major) return false; + if(this.major > fv.major) return true; + if(this.minor < fv.minor) return false; + if(this.minor > fv.minor) return true; + if(this.rev < fv.rev) return false; + return true; +} +/* ---- get value of query string param ---- */ +deconcept.util = { + getRequestParameter: function(param) { + var q = document.location.search || document.location.hash; + if (param == null) { return q; } + if(q) { + var pairs = q.substring(1).split("&"); + for (var i=0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return pairs[i].substring((pairs[i].indexOf("=")+1)); + } + } + } + return ""; + } +} +/* fix for video streaming bug */ +deconcept.SWFObjectUtil.cleanupSWFs = function() { + var objects = document.getElementsByTagName("OBJECT"); + for (var i = objects.length - 1; i >= 0; i--) { + objects[i].style.display = 'none'; + for (var x in objects[i]) { + if (typeof objects[i][x] == 'function') { + objects[i][x] = function(){}; + } + } + } +} +// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/ +if (deconcept.SWFObject.doPrepUnload) { + if (!deconcept.unloadSet) { + deconcept.SWFObjectUtil.prepUnload = function() { + __flash_unloadHandler = function(){}; + __flash_savedUnloadHandler = function(){}; + window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs); + } + window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload); + deconcept.unloadSet = true; + } +} +/* add document.getElementById if needed (mobile IE < 5) */ +if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }} + +/* add some aliases for ease of use/backwards compatibility */ +var getQueryParamValue = deconcept.util.getRequestParameter; +var FlashObject = deconcept.SWFObject; // for legacy support +var SWFObject = deconcept.SWFObject; diff --git a/workflow/engine/plugins/pmosCommunity/setupPage.xml b/workflow/engine/plugins/pmosCommunity/setupPage.xml new file mode 100644 index 000000000..3cf13ba37 --- /dev/null +++ b/workflow/engine/plugins/pmosCommunity/setupPage.xml @@ -0,0 +1,20 @@ + + + + + <en>ProcessMaker Open Source Plugin</en> + + + + ProcessMaker Open Source Plugin, with this plugin you can see many differents charts related to the ProcessMaker Community web sites + + + + + Save + + \ No newline at end of file diff --git a/workflow/engine/plugins/processTemplate.php b/workflow/engine/plugins/processTemplate.php new file mode 100644 index 000000000..0d7614ac2 --- /dev/null +++ b/workflow/engine/plugins/processTemplate.php @@ -0,0 +1,69 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + G::LoadClass( "plugin"); + + + class processTemplatePlugin extends PMPlugin + { + function processTemplatePlugin($sNamespace, $sFilename = null) + { + $res = parent::PMPlugin($sNamespace, $sFilename); + $this->sFriendlyName = 'Process Map Templates'; + $this->sDescription = 'This plugin includes various templates for quick and easy Process Map creation. Users can customize Process Maps based on pre-defined templates of common process designs (including Parallel, Dual Start Task, and Selection).'; + $this->sPluginFolder = 'processTemplate'; + $this->sSetupPage = null; + $this->iVersion = 0.78; + $this->bPrivate = true; + $this->aWorkspaces = array ( '__' ); + return $res; + } + + function setup() + { + //$this->registerTrigger( PM_NEW_PROCESS_LIST, 'getNewProcessTemplateList' ); + //$this->registerTrigger( PM_NEW_PROCESS_SAVE, 'saveNewProcess' ); + //$this->registerTrigger( PM_NEW_DYNAFORM_LIST, 'getNewDynaformTemplateList' ); + //$this->registerTrigger( PM_NEW_DYNAFORM_SAVE, 'saveNewDynaform' ); + } + + function install() + { + + } + function enable(){ + + } + function disable(){ + + } + } + + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + $oPluginRegistry->registerPlugin('processTemplate', __FILE__); + + + + + diff --git a/workflow/engine/plugins/processTemplate/class.processTemplate.php b/workflow/engine/plugins/processTemplate/class.processTemplate.php new file mode 100644 index 000000000..da3e94ea7 --- /dev/null +++ b/workflow/engine/plugins/processTemplate/class.processTemplate.php @@ -0,0 +1,195 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + class processTemplateClass extends PMPlugin { + + function __construct ( ) { + } + + function getNewProcessTemplateList ( $oData ) { + global $_DBArray; + $rows[] = array ( 'uid' => 'char', 'name' => 'char', ); + $rows[] = array ( 'uid' => '', 'name' => 'blank process' ); + $rows[] = array ( 'uid' => 1, 'name' => 'simple process, three tasks' ); + $rows[] = array ( 'uid' => 2, 'name' => 'simple parallel process' ); + $rows[] = array ( 'uid' => 3, 'name' => 'conditional process' ); + $rows[] = array ( 'uid' => 4, 'name' => 'double starting task' ); + $rows[] = array ( 'uid' => 5, 'name' => 'advanced parallel process' ); + + $_DBArray['ProcessesNew'] = $rows; + } + + function saveNewProcess ( $oData ) { + + switch ($oData['PRO_TEMPLATE']) { + case 1 : $this->simpleProcess ( $oData); + break; + case 2 : $this->simpleParallel ( $oData); + break; + case 3 : $this->conditional ( $oData); + break; + case 4 : $this->doubleStart ( $oData); + break; + case 5 : $this->fullParallel ( $oData); + break; + default : + + } + + + } + + function simpleProcess ($oData ) { + $oJSON = new Services_JSON(); + $sProUid = $oData['PRO_UID']; + $sTemplate = $oData['PRO_TEMPLATE']; + $oProcessMap = $oData['PROCESSMAP']; + + $t1 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 70) ); + $t2 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 160) ); + $t3 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 250) ); + $task1 = $t1->uid; + $task2 = $t2->uid; + $task3 = $t3->uid; + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$task1); + $oTask = new Task(); + $oTask->update($aData); + + $oProcessMap->saveNewPattern($sProUid, $task1, $task2, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task2, $task3, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task3, -1, 'SEQUENTIAL' ); + } + + function simpleParallel ($oData ) { + $oJSON = new Services_JSON(); + $sProUid = $oData['PRO_UID']; + $sTemplate = $oData['PRO_TEMPLATE']; + $oProcessMap = $oData['PROCESSMAP']; + + $t1 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 70) ); + $t2 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 200, 160) ); + $t3 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 400, 160) ); + $t5 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 250) ); + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$t1->uid); + $oTask = new Task(); + $oTask->update($aData); + + $oProcessMap->saveNewPattern($sProUid, $t1->uid, $t2->uid, 'PARALLEL' ); + $oProcessMap->saveNewPattern($sProUid, $t1->uid, $t3->uid, 'PARALLEL' ); + $oProcessMap->saveNewPattern($sProUid, $t2->uid, $t5->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t3->uid, $t5->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t5->uid, -1, 'SEQUENTIAL' ); + } + + function fullParallel ($oData ) { + $oJSON = new Services_JSON(); + $sProUid = $oData['PRO_UID']; + $sTemplate = $oData['PRO_TEMPLATE']; + $oProcessMap = $oData['PROCESSMAP']; + + $t1 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 70) ); + $t2 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 100, 160) ); + $t3 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 160) ); + $t4 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 500, 160) ); + $t5 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 200, 250) ); + $t6 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 500, 250) ); + $t7 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 350, 340) ); + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$t1->uid); + $oTask = new Task(); + $oTask->update($aData); + + $oProcessMap->saveNewPattern($sProUid, $t1->uid, $t2->uid, 'PARALLEL' ); + $oProcessMap->saveNewPattern($sProUid, $t1->uid, $t3->uid, 'PARALLEL' ); + $oProcessMap->saveNewPattern($sProUid, $t1->uid, $t4->uid, 'PARALLEL' ); + $oProcessMap->saveNewPattern($sProUid, $t2->uid, $t5->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t3->uid, $t5->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t4->uid, $t6->uid, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $t5->uid, $t7->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t6->uid, $t7->uid, 'SEC-JOIN' ); + $oProcessMap->saveNewPattern($sProUid, $t7->uid, -1, 'SEQUENTIAL' ); + } + + + function conditional ($oData ) { + $oJSON = new Services_JSON(); + $sProUid = $oData['PRO_UID']; + $sTemplate = $oData['PRO_TEMPLATE']; + $oProcessMap = $oData['PROCESSMAP']; + + $t1 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 70) ); + $t2 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 200, 160) ); + $t3 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 400, 160) ); + $t4 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 250) ); + $task1 = $t1->uid; + $task2 = $t2->uid; + $task3 = $t3->uid; + $task4 = $t4->uid; + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$task1); + $oTask = new Task(); + $oTask->update($aData); + + $oProcessMap->saveNewPattern($sProUid, $task1, $task2, 'SELECT' ); + $oProcessMap->saveNewPattern($sProUid, $task1, $task3, 'SELECT' ); + $oProcessMap->saveNewPattern($sProUid, $task2, $task4, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task3, $task4, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task4, -1, 'SEQUENTIAL' ); + } + + + function doubleStart ($oData ) { + $oJSON = new Services_JSON(); + $sProUid = $oData['PRO_UID']; + $sTemplate = $oData['PRO_TEMPLATE']; + $oProcessMap = $oData['PROCESSMAP']; + + $t1 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 200, 70) ); + $t2 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 400, 70) ); + $t3 = $oJSON->decode( $oProcessMap->addTask( $sProUid, 300, 160) ); + $task1 = $t1->uid; + $task2 = $t2->uid; + $task3 = $t3->uid; + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$task1); + $oTask = new Task(); + $oTask->update($aData); + + $aData = array("TAS_START"=>"TRUE","TAS_UID"=>$task2); + $oTask = new Task(); + $oTask->update($aData); + + $oProcessMap->saveNewPattern($sProUid, $task1, $task3, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task2, $task3, 'SEQUENTIAL' ); + $oProcessMap->saveNewPattern($sProUid, $task3, -1, 'SEQUENTIAL' ); + } + + + function setup() + { + } + } \ No newline at end of file diff --git a/workflow/engine/skins/blank.html b/workflow/engine/skins/blank.html new file mode 100644 index 000000000..f71bc654f --- /dev/null +++ b/workflow/engine/skins/blank.html @@ -0,0 +1,30 @@ + + + + + + + {$header} + + + + + + + + + + +
    + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') + { + G::LoadTemplate($G_TEMPLATE); + } + {/php} +
    + + diff --git a/workflow/engine/skins/blank.php b/workflow/engine/skins/blank.php new file mode 100644 index 000000000..acaba8550 --- /dev/null +++ b/workflow/engine/skins/blank.php @@ -0,0 +1,47 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + G::verifyPath ( PATH_SMARTY_C, true ); + G::verifyPath ( PATH_SMARTY_CACHE, true ); + + // put full path to Smarty.class.php + require_once(PATH_THIRDPARTY . 'smarty/libs/Smarty.class.php'); + + +$smarty = new Smarty(); + +$smarty->template_dir = PATH_SKINS; +$smarty->compile_dir = PATH_SMARTY_C; +$smarty->cache_dir = PATH_SMARTY_CACHE; +$smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + +$oHeadPublisher =& headPublisher::getSingleton(); +if (isset($oHeadPublisher)) $header = $oHeadPublisher->printHeader(); +$smarty->assign('username', (isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : '') ); +$smarty->assign('header', $header ); +//$smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html' ); +//$smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html' ); +$smarty->display('blank.html'); +?> \ No newline at end of file diff --git a/workflow/engine/skins/extJs.html b/workflow/engine/skins/extJs.html new file mode 100755 index 000000000..74cd269db --- /dev/null +++ b/workflow/engine/skins/extJs.html @@ -0,0 +1,10 @@ + + + + +{header} + + +{bodyTemplate} + + diff --git a/workflow/engine/skins/extJs.php b/workflow/engine/skins/extJs.php new file mode 100755 index 000000000..4dde68a29 --- /dev/null +++ b/workflow/engine/skins/extJs.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +// G::LoadSystem('templatePower'); + + + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + + $oHeadPublisher =& headPublisher::getSingleton(); + + $extSkin=$oServerConf->getProperty("extSkin"); + if(isset($extSkin[SYS_SKIN])){ + $oHeadPublisher->setExtSkin( $extSkin[SYS_SKIN]); + } + + if( $oHeadPublisher->extJsInit === true){ + $header = $oHeadPublisher->getExtJsVariablesScript(); + $styles = $oHeadPublisher->getExtJsStylesheets(); + $body = $oHeadPublisher->getExtJsScripts(); + + $templateFile = 'extJsInitLoad.html'; + } else { + $header = $oHeadPublisher->includeExtJs(); + $styles = ''; + $body = $oHeadPublisher->renderExtJs(); + + $templateFile = 'extJs.html'; + } + $template = new TemplatePower( PATH_SKINS . $templateFile ); + $template->prepare(); + $template->assign( 'header', $header ); + $template->assign( 'styles', $styles ); + $template->assign( 'bodyTemplate', $body); + $content = $template->getOutputContent(); + + print $content; + \ No newline at end of file diff --git a/workflow/engine/skins/extJsInitLoad.html b/workflow/engine/skins/extJsInitLoad.html new file mode 100644 index 000000000..54508395d --- /dev/null +++ b/workflow/engine/skins/extJsInitLoad.html @@ -0,0 +1,68 @@ + + + + + {header} + + + +
    +
    +
    +
    +
    + Loading styles and images...
    + + + +
    +
    +
    + + + + + + + + + + + {styles} + + {bodyTemplate} + + diff --git a/workflow/engine/skins/green-submenu.html b/workflow/engine/skins/green-submenu.html new file mode 100755 index 000000000..699e8d768 --- /dev/null +++ b/workflow/engine/skins/green-submenu.html @@ -0,0 +1,49 @@ + + + + + + {$header} + + + + + + + + + + + + +
    + + + {if (count($subMenus)>0) } + + + + {/if} + + + + +
    + + +
    +
    + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') G::LoadTemplate($G_TEMPLATE); + {/php} +
    +
    + +
    + + \ No newline at end of file diff --git a/workflow/engine/skins/green-submenu.php b/workflow/engine/skins/green-submenu.php new file mode 100755 index 000000000..f84b31828 --- /dev/null +++ b/workflow/engine/skins/green-submenu.php @@ -0,0 +1,95 @@ +template_dir = PATH_SKINS; +$smarty->compile_dir = PATH_SMARTY_C; +$smarty->cache_dir = PATH_SMARTY_CACHE; +$smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + +$oHeadPublisher = & headPublisher::getSingleton(); +global $G_ENABLE_BLANK_SKIN; + +if (isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN) { + $smarty->display('blank.html'); +} else { + + $header = ''; + if (isset($oHeadPublisher)) { + $oHeadPublisher->title = isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : ''; + $header = $oHeadPublisher->printHeader(); + } + $footer = ''; + if (strpos($_SERVER['REQUEST_URI'], '/login/login') !== false) { + if (DB_SYSTEM_INFORMATION == 1) { + $footer = "| System Information |
    "; + } + + $freeOfChargeText = ""; + if (! defined('SKIP_FREE_OF_CHARGE_TEXT')) + $freeOfChargeText = "Supplied free of charge with no support, certification, warranty,
    maintenance nor indemnity by Colosa and its Certified Partners."; + $footer .= "
    Copyright © 2003-" . date('Y') . " Colosa, Inc. All rights reserved.
    $freeOfChargeText " . "

    "; + } + + //menu + global $G_MAIN_MENU; + global $G_SUB_MENU; + global $G_MENU_SELECTED; + global $G_SUB_MENU_SELECTED; + global $G_ID_MENU_SELECTED; + global $G_ID_SUB_MENU_SELECTED; + + $oMenu = new Menu(); + $menus = $oMenu->generateArrayForTemplate($G_MAIN_MENU, 'SelectedMenu', 'mainMenu', $G_MENU_SELECTED, $G_ID_MENU_SELECTED); + $smarty->assign('menus', $menus); + + $oSubMenu = new Menu(); + $subMenus = $oSubMenu->generateArrayForTemplate($G_SUB_MENU, 'selectedSubMenu', 'subMenu', $G_SUB_MENU_SELECTED, $G_ID_SUB_MENU_SELECTED); + $smarty->assign('subMenus', $subMenus); + + if (! defined('NO_DISPLAY_USERNAME')) { + define('NO_DISPLAY_USERNAME', 0); + } + if (NO_DISPLAY_USERNAME == 0) { + $smarty->assign('userfullname', isset($_SESSION['USR_FULLNAME']) ? $_SESSION['USR_FULLNAME'] : ''); + $smarty->assign('user', isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ')' : ''); + $smarty->assign('rolename', isset($_SESSION['USR_ROLENAME']) ? $_SESSION['USR_ROLENAME'] . '' : ''); + $smarty->assign('pipe', isset($_SESSION['USR_USERNAME']) ? ' | ' : ''); + $smarty->assign('logout', G::LoadTranslation('ID_LOGOUT')); + $smarty->assign('workspace', defined('SYS_SYS')?SYS_SYS: ''); + $uws = (isset($_SESSION['USR_ROLENAME']) && $_SESSION['USR_ROLENAME'] != '')? strtolower(G::LoadTranslation('ID_WORKSPACE_USING')): G::LoadTranslation('ID_WORKSPACE_USING'); + $smarty->assign('workspace_label', $uws); + $smarty->assign('udate', G::getformatedDate(date('Y-m-d'), 'M d, yyyy', SYS_LANG)); + + } + if (defined('SYS_SYS')) + $logout = '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/login/login'; + else + $logout = '/sys/' . SYS_LANG . '/' . SYS_SKIN . '/login/login'; + $smarty->assign('linklogout', $logout); + $smarty->assign('header', $header); + $smarty->assign('footer', $footer); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html'); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html'); + + if (class_exists('PMPluginRegistry')) { + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $sCompanyLogo = $oPluginRegistry->getCompanyLogo('/images/processmaker.logo.jpg'); + } else + $sCompanyLogo = '/images/processmaker.logo.jpg'; + + $smarty->assign('logo_company', $sCompanyLogo); + $smarty->display('green-submenu.html'); +} diff --git a/workflow/engine/skins/green.html b/workflow/engine/skins/green.html new file mode 100644 index 000000000..92bc85dc8 --- /dev/null +++ b/workflow/engine/skins/green.html @@ -0,0 +1,79 @@ + + + + + + + {$header} + + + + + + + + + + + + + + +
    + + + + + + + + +
    +
    + + {php}if ((int)$_SESSION['USER_LOGGED'] != 0) {{/php} + + {$logout}  
    +    {$msgVer} + {php}}{/php} +
    +
    +
    +
    +
    +
    + + + + + {if (count($subMenus)>0) } + + + + {/if} + + + + +
    + + +
    +
    + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') G::LoadTemplate($G_TEMPLATE); + {/php} +
    +
    + +
    + + \ No newline at end of file diff --git a/workflow/engine/skins/green.php b/workflow/engine/skins/green.php new file mode 100644 index 000000000..f9f90a2d8 --- /dev/null +++ b/workflow/engine/skins/green.php @@ -0,0 +1,135 @@ +template_dir = PATH_SKINS; +$smarty->compile_dir = PATH_SMARTY_C; +$smarty->cache_dir = PATH_SMARTY_CACHE; +$smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + +$oHeadPublisher = & headPublisher::getSingleton(); + +global $G_ENABLE_BLANK_SKIN; + +//To setup en extJS Theme for this Skin +G::LoadClass('serverConfiguration'); +$oServerConf =& serverConf::getSingleton(); +$extSkin=$oServerConf->getProperty("extSkin"); +if(!$extSkin) $extSkin=array(); +$extSkin[SYS_SKIN]="xtheme-gray"; +$oServerConf->setProperty("extSkin",$extSkin); +//End of extJS Theme setup + +//G::pr($oHeadPublisher); + if (isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN) { + $smarty->display('blank.html'); + } + else { + + $header = ''; + if (isset($oHeadPublisher)) { + $oHeadPublisher->title = isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : ''; + $header = $oHeadPublisher->printHeader(); + } + $footer = ''; + if (strpos($_SERVER['REQUEST_URI'], '/login/login') !== false) { + if (DB_SYSTEM_INFORMATION == 1) { + $footer = "| System Information |
    "; + } + + $freeOfChargeText = ""; + if (! defined('SKIP_FREE_OF_CHARGE_TEXT')) + $freeOfChargeText = "Supplied free of charge with no support, certification, warranty,
    maintenance nor indemnity by Colosa and its Certified Partners."; + if(class_exists('pmLicenseManager')) $freeOfChargeText=""; + $footer .= "
    Copyright © 2003-" . date('Y') . " Colosa, Inc. All rights reserved.
    $freeOfChargeText " . "

    "; + } + + //menu + global $G_MAIN_MENU; + global $G_SUB_MENU; + global $G_MENU_SELECTED; + global $G_SUB_MENU_SELECTED; + global $G_ID_MENU_SELECTED; + global $G_ID_SUB_MENU_SELECTED; + + $oMenu = new Menu(); + $menus = $oMenu->generateArrayForTemplate($G_MAIN_MENU, 'SelectedMenu', 'mainMenu', $G_MENU_SELECTED, $G_ID_MENU_SELECTED); + $smarty->assign('menus', $menus); + + $oSubMenu = new Menu(); + $subMenus = $oSubMenu->generateArrayForTemplate($G_SUB_MENU, 'selectedSubMenu', 'subMenu', $G_SUB_MENU_SELECTED, $G_ID_SUB_MENU_SELECTED); + $smarty->assign('subMenus', $subMenus); + + if (! defined('NO_DISPLAY_USERNAME')) { + define('NO_DISPLAY_USERNAME', 0); + } + if (NO_DISPLAY_USERNAME == 0) { + $smarty->assign('userfullname', isset($_SESSION['USR_FULLNAME']) ? $_SESSION['USR_FULLNAME'] : ''); + $smarty->assign('user', isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ')' : ''); + $smarty->assign('rolename', isset($_SESSION['USR_ROLENAME']) ? $_SESSION['USR_ROLENAME'] . '' : ''); + $smarty->assign('pipe', isset($_SESSION['USR_USERNAME']) ? ' | ' : ''); + $smarty->assign('logout', G::LoadTranslation('ID_LOGOUT')); + $smarty->assign('workspace', defined('SYS_SYS')?SYS_SYS: ''); + $uws = (isset($_SESSION['USR_ROLENAME']) && $_SESSION['USR_ROLENAME'] != '')? strtolower(G::LoadTranslation('ID_WORKSPACE_USING')): G::LoadTranslation('ID_WORKSPACE_USING'); + $smarty->assign('workspace_label', $uws); + $smarty->assign('udate', G::getformatedDate(date('Y-m-d'), 'M d, yyyy', SYS_LANG)); + + } + if(class_exists('pmLicenseManager')){ + $pmLicenseManagerO =& pmLicenseManager::getSingleton(); + $expireIn=$pmLicenseManagerO->getExpireIn(); + $expireInLabel=$pmLicenseManagerO->getExpireInLabel(); + if($expireIn<=30){ + $smarty->assign('msgVer', '
      '); + } + } + + if (defined('SYS_SYS')) + $logout = '/sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/login/login'; + else + $logout = '/sys/' . SYS_LANG . '/' . SYS_SKIN . '/login/login'; + + $smarty->assign('linklogout', $logout); + $smarty->assign('header', $header); + $smarty->assign('footer', $footer); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html'); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html'); + G::LoadClass( 'replacementLogo' ); + $oLogoR = new replacementLogo(); + if(isset($_SESSION['USER_LOGGED'])){ + $aFotoSelect = $oLogoR->getNameLogo((isset($_SESSION['USER_LOGGED']))?$_SESSION['USER_LOGGED']:''); + if ( is_array ( $aFotoSelect ) ) { + $sFotoSelect = trim($aFotoSelect['DEFAULT_LOGO_NAME']); + $sWspaceSelect = trim($aFotoSelect['WORKSPACE_LOGO_NAME']); + } + } + + if (class_exists('PMPluginRegistry')) { + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + if ( isset($sFotoSelect) && $sFotoSelect!='' && !(strcmp($sWspaceSelect,SYS_SYS)) ){ + $sCompanyLogo = $oPluginRegistry->getCompanyLogo($sFotoSelect); + $sCompanyLogo= "../setup/showLogoFile.php?id=".G::encrypt($sCompanyLogo,"imagen"); + } + else { + $sCompanyLogo = $oPluginRegistry->getCompanyLogo('/images/processmaker.logo.jpg'); + } + } + else { + $sCompanyLogo = '/images/processmaker.logo.jpg'; + } + + $smarty->assign('logo_company', $sCompanyLogo); + $smarty->display('green.html'); +} diff --git a/workflow/engine/skins/iphone.html b/workflow/engine/skins/iphone.html new file mode 100755 index 000000000..35bde6c1e --- /dev/null +++ b/workflow/engine/skins/iphone.html @@ -0,0 +1,102 @@ + + + {$username} + + + + + {$header} + + + + + + + +
    + + + + + + {php} + global $G_TMP_MENU_ALIGN; + {/php} + + + + + + + + +
    +
    + + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') + { + G::LoadTemplate($G_TEMPLATE); + } + {/php} +
    +
    + +{php}if ((int)$_SESSION['USER_LOGGED'] != 0) +{ +{/php} + +{php} +} +{/php} + + + diff --git a/workflow/engine/skins/iphone.php b/workflow/engine/skins/iphone.php new file mode 100755 index 000000000..50ad3b6e8 --- /dev/null +++ b/workflow/engine/skins/iphone.php @@ -0,0 +1,61 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + G::verifyPath ( PATH_SMARTY_C, true ); + G::verifyPath ( PATH_SMARTY_CACHE, true ); + + // put full path to Smarty.class.php + require_once(PATH_THIRDPARTY . 'smarty/libs/Smarty.class.php'); + + + $smarty = new Smarty(); + + $smarty->template_dir = PATH_SKINS; + $smarty->compile_dir = PATH_SMARTY_C; + $smarty->cache_dir = PATH_SMARTY_CACHE; + $smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + + global $G_ENABLE_BLANK_SKIN; + + if ( isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN ) { + $smarty->display('blank.html'); + } + else { + $oHeadPublisher =& headPublisher::getSingleton(); + if (isset($oHeadPublisher)) $header = $oHeadPublisher->printHeader(); + $smarty->assign('user', isset($_SESSION['USR_USERNAME']) ? $_SESSION['USR_USERNAME'] : ''); + $smarty->assign('username', (isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : '') ); + if(defined('SYS_SYS')) + $logout='/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.'/login/login'; + else + $logout='/sys/'.SYS_LANG.'/'.SYS_SKIN.'/login/login'; + $smarty->assign('linklogout', $logout ); + $smarty->assign('header', $header ); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html' ); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html' ); + $smarty->display('iphone.html'); + } +//print_r($_SERVER); +?> diff --git a/workflow/engine/skins/raw.html b/workflow/engine/skins/raw.html new file mode 100644 index 000000000..94f5ebc0d --- /dev/null +++ b/workflow/engine/skins/raw.html @@ -0,0 +1,16 @@ + + + + +
    + + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') + { + G::LoadTemplate($G_TEMPLATE); + } + {/php} +
    diff --git a/workflow/engine/skins/raw.php b/workflow/engine/skins/raw.php new file mode 100644 index 000000000..738d6cecd --- /dev/null +++ b/workflow/engine/skins/raw.php @@ -0,0 +1,24 @@ +template_dir = PATH_SKINS; +$smarty->compile_dir = PATH_SMARTY_C; +$smarty->cache_dir = PATH_SMARTY_CACHE; +$smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + +$oHeadPublisher =& headPublisher::getSingleton(); +if (isset($oHeadPublisher)) $header = $oHeadPublisher->printRawHeader(); +$smarty->assign('header', $header ); +$smarty->display('raw.html'); diff --git a/workflow/engine/skins/rtl.cnf b/workflow/engine/skins/rtl.cnf new file mode 100644 index 000000000..e404b8506 --- /dev/null +++ b/workflow/engine/skins/rtl.cnf @@ -0,0 +1 @@ +O:8:"stdClass":3:{s:4:"name";s:3:"rtl";s:11:"description";s:40:"Skin for Right-To-Left languages (Hebrew, Arabic, etc.)";s:7:"version";i:1;} \ No newline at end of file diff --git a/workflow/engine/skins/rtl.html b/workflow/engine/skins/rtl.html new file mode 100644 index 000000000..026cf9c6a --- /dev/null +++ b/workflow/engine/skins/rtl.html @@ -0,0 +1,72 @@ + + + + + + {$header} + + + + + + + + + + + + +
    + + + + + + + + +
    + +
    + + {php}if ((int)$_SESSION['USER_LOGGED'] != 0) {{/php} + {$user} | + {php}echo G::LoadTranslation('ID_LOGOUT');{/php}{php}}{/php} +    
    +
    +
    +
    +
    + + + + + + + + + + + +
    + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') G::LoadTemplate($G_TEMPLATE); + {/php} +
    +
    + +
    + + \ No newline at end of file diff --git a/workflow/engine/skins/rtl.php b/workflow/engine/skins/rtl.php new file mode 100644 index 000000000..e63c425ac --- /dev/null +++ b/workflow/engine/skins/rtl.php @@ -0,0 +1,91 @@ +template_dir = PATH_SKINS; + $smarty->compile_dir = PATH_SMARTY_C; + $smarty->cache_dir = PATH_SMARTY_CACHE; + $smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + + $oHeadPublisher =& headPublisher::getSingleton(); + global $G_ENABLE_BLANK_SKIN; + + if ( isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN ) { + $smarty->display('blank.html'); + } + else { + + $header = ''; + if (isset($oHeadPublisher)) { + $oHeadPublisher->title = isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : ''; + $header = $oHeadPublisher->printHeader(); + } + $footer = ''; + if (strpos($_SERVER['REQUEST_URI'], '/login/login') !== false) { + if ( DB_SYSTEM_INFORMATION==1) { + $footer = " בית ספר
    "; + } + + $freeOfChargeText = ""; + if ( !defined ( 'SKIP_FREE_OF_CHARGE_TEXT' ) ) + $freeOfChargeText = "Supplied free of charge with no support, certification, warranty,
    maintenance nor indemnity by Colosa and its Certified Partners."; + $footer .= "
    Copyright © 2003-" . date('Y') . " Colosa, Inc. All rights reserved.
    $freeOfChargeText " + . "

    "; + } + + //menu + global $G_MAIN_MENU; + global $G_SUB_MENU; + global $G_MENU_SELECTED; + global $G_SUB_MENU_SELECTED; + global $G_ID_MENU_SELECTED; + global $G_ID_SUB_MENU_SELECTED; + + $oMenu = new Menu(); + $menus = $oMenu->generateArrayForTemplate ( $G_MAIN_MENU,'SelectedMenu', 'mainMenu',$G_MENU_SELECTED, $G_ID_MENU_SELECTED ); + $smarty->assign('menus', $menus ); + + $oSubMenu = new Menu(); + $subMenus = $oSubMenu->generateArrayForTemplate ( $G_SUB_MENU,'selectedSubMenu', 'subMenu',$G_SUB_MENU_SELECTED, $G_ID_SUB_MENU_SELECTED ); + $smarty->assign('subMenus', $subMenus ); + + if (!defined('NO_DISPLAY_USERNAME')) { + define('NO_DISPLAY_USERNAME', 0); + } + if (NO_DISPLAY_USERNAME == 0) { + $smarty->assign('user', isset($_SESSION['USR_USERNAME']) ? $_SESSION['USR_USERNAME'] : ''); + $smarty->assign('pipe', isset($_SESSION['USR_USERNAME']) ? ' | ' : ''); + $smarty->assign('logout', G::LoadTranslation('ID_LOGOUT')); + } + if(defined('SYS_SYS')) + $logout='/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.'/login/login'; + else + $logout='/sys/'.SYS_LANG.'/'.SYS_SKIN.'/login/login'; + $smarty->assign('linklogout', $logout ); + $smarty->assign('header', $header ); + $smarty->assign('footer', $footer); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html' ); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html' ); + + if (class_exists('PMPluginRegistry')) { + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $sCompanyLogo = $oPluginRegistry->getCompanyLogo ( '/images/processmaker.logo.jpg' ); + } + else + $sCompanyLogo = '/images/processmaker.logo.jpg'; + + $smarty->assign('logo_company', $sCompanyLogo ); + $smarty->display('rtl.html'); + } diff --git a/workflow/engine/skins/tracker.html b/workflow/engine/skins/tracker.html new file mode 100644 index 000000000..b63f7b46a --- /dev/null +++ b/workflow/engine/skins/tracker.html @@ -0,0 +1,64 @@ + + + + + {$header} + + + + + + + + + + + + +
    + + + + + + + + +
    +
    {php}if ((int)$_SESSION['CASE'] != 0) {{/php}{php}echo G::LoadTranslation('ID_LOGOUT');{/php}{php}}{/php}    
    +
    +
    +
    +
    + + + + + + + + + + + +
    + {php} + global $G_TEMPLATE; + if ($G_TEMPLATE != '') G::LoadTemplate($G_TEMPLATE); + {/php} +
    +
    + +
    + + \ No newline at end of file diff --git a/workflow/engine/skins/tracker.php b/workflow/engine/skins/tracker.php new file mode 100644 index 000000000..b052f18ee --- /dev/null +++ b/workflow/engine/skins/tracker.php @@ -0,0 +1,75 @@ +template_dir = PATH_SKINS; + $smarty->compile_dir = PATH_SMARTY_C; + $smarty->cache_dir = PATH_SMARTY_CACHE; + $smarty->config_dir = PATH_THIRDPARTY . 'smarty/configs'; + + $oHeadPublisher =& headPublisher::getSingleton(); + global $G_ENABLE_BLANK_SKIN; + + if ( isset($G_ENABLE_BLANK_SKIN) && $G_ENABLE_BLANK_SKIN ) { + $smarty->display('blank.html'); + } + else { + + $header = ''; + if (isset($oHeadPublisher)) { + $oHeadPublisher->title = isset($_SESSION['USR_USERNAME']) ? '(' . $_SESSION['USR_USERNAME'] . ' ' . G::LoadTranslation('ID_IN') . ' ' . SYS_SYS . ')' : ''; + $header = $oHeadPublisher->printHeader(); + } + $footer = ''; + if (strpos($_SERVER['REQUEST_URI'], '/login/login') !== false) { + if ( defined('SYS_SYS') ) { + $footer = "| System Information |
    "; + } + $footer .= "
    Copyright © 2003-2008 Colosa, Inc. All rights reserved."; + } + + //menu + global $G_MAIN_MENU; + global $G_SUB_MENU; + global $G_MENU_SELECTED; + global $G_SUB_MENU_SELECTED; + global $G_ID_MENU_SELECTED; + global $G_ID_SUB_MENU_SELECTED; + + $oMenu = new Menu(); + $menus = $oMenu->generateArrayForTemplate ( $G_MAIN_MENU,'SelectedMenu', 'mainMenu',$G_MENU_SELECTED, $G_ID_MENU_SELECTED ); + $smarty->assign('menus', $menus ); + + $oSubMenu = new Menu(); + $subMenus = $oSubMenu->generateArrayForTemplate ( $G_SUB_MENU,'selectedSubMenu', 'subMenu',$G_SUB_MENU_SELECTED, $G_ID_SUB_MENU_SELECTED ); + $smarty->assign('subMenus', $subMenus ); + + $smarty->assign('user', isset($_SESSION['USR_USERNAME']) ? $_SESSION['USR_USERNAME'] : ''); + $smarty->assign('pipe', isset($_SESSION['USR_USERNAME']) ? ' | ' : ''); + $smarty->assign('logout', G::LoadTranslation('ID_LOGOUT')); + $smarty->assign('header', $header ); + $smarty->assign('tpl_menu', PATH_TEMPLATE . 'menu.html' ); + $smarty->assign('tpl_submenu', PATH_TEMPLATE . 'submenu.html' ); + + if (class_exists('PMPluginRegistry')) { + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $sCompanyLogo = $oPluginRegistry->getCompanyLogo ( '/images/processmaker.logo.jpg' ); + } + else + $sCompanyLogo = '/images/processmaker.logo.jpg'; + + $smarty->assign('logo_company', $sCompanyLogo ); + $smarty->display('tracker.html'); + } + diff --git a/workflow/engine/templates/additionalTables/Table.tpl b/workflow/engine/templates/additionalTables/Table.tpl new file mode 100644 index 000000000..8be3cc4aa --- /dev/null +++ b/workflow/engine/templates/additionalTables/Table.tpl @@ -0,0 +1,19 @@ +dbMap !== null); + } + + /** + * Gets the databasemap this map builder built. + * + * @return the databasemap + */ + public function getDatabaseMap() + { + return $this->dbMap; + } + + /** + * The doBuild() method builds the DatabaseMap + * + * @return void + * @throws PropelException + */ + public function doBuild() + { + $this->dbMap = Propel::getDatabaseMap('workflow'); + + $tMap = $this->dbMap->addTable('{tableName}'); + + $tMap->setPhpName('{className}'); + + $tMap->setUseIdGenerator({useIdGenerator}); + + + $tMap->addPrimaryKey('{name}', '{phpName}', '{type}', CreoleTypes::{creoleType}, {notNull}, {size}); + + + + $tMap->addColumn('{name}', '{phpName}', '{type}', CreoleTypes::{creoleType}, {notNull}, {size}); + + + } // doBuild() + +} // {className}MapBuilder diff --git a/workflow/engine/templates/additionalTables/om/BaseTable.tpl b/workflow/engine/templates/additionalTables/om/BaseTable.tpl new file mode 100644 index 000000000..cba356cf5 --- /dev/null +++ b/workflow/engine/templates/additionalTables/om/BaseTable.tpl @@ -0,0 +1,530 @@ + + /** + * The value for the {var} field. + * @var {type} + */ + protected {attribute}; + + + /** + * Flag to prevent endless save loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInSave = false; + + /** + * Flag to prevent endless validation loop, if this object is referenced + * by another object which falls in this transaction. + * @var boolean + */ + protected $alreadyInValidation = false; + + + {getFunction} + + + + /** + * Set the value of [{var}] column. + * + * @param {type} $v new value + * @return void + */ + public function set{phpName}($v) + { + {setFunction} + } // set{phpName}() + + + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (1-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param ResultSet $rs The ResultSet class with cursor advanced to desired record pos. + * @param int $startcol 1-based offset column which indicates which restultset column to start with. + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate(ResultSet $rs, $startcol = 1) + { + try { + + $this->{var} = $rs->get{type2}($startcol + {index}); + + + $this->resetModified(); + + $this->setNew(false); + + // FIXME - using NUM_COLUMNS may be clearer. + return $startcol + {totalColumns}; // {totalColumns} = {className}Peer::NUM_COLUMNS - {className}Peer::NUM_LAZY_LOAD_COLUMNS). + + } catch (Exception $e) { + throw new PropelException("Error populating {className} object", $e); + } + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param Connection $con + * @return void + * @throws PropelException + * @see BaseObject::setDeleted() + * @see BaseObject::isDeleted() + */ + public function delete($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection({className}Peer::DATABASE_NAME); + } + + try { + $con->begin(); + {className}Peer::doDelete($this, $con); + $this->setDeleted(true); + $con->commit(); + require_once 'classes/model/AdditionalTables.php'; + $oAdditionalTables = new AdditionalTables(); + $aAdditionalTables = $oAdditionalTables->load({className}Peer::__UID__); + if ($aAdditionalTables['ADD_TAB_SDW_LOG_DELETE'] == 1) { + require_once 'classes/model/ShadowTable.php'; + $oShadowTable = new ShadowTable(); + $oShadowTable->create(array('ADD_TAB_UID' => {className}Peer::__UID__, + 'SHD_ACTION' => 'DELETE', + 'SHD_DETAILS' => serialize($this->toArray(BasePeer::TYPE_FIELDNAME)), + 'USR_UID' => (isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : ''), + 'APP_UID' => (isset($_SESSION['APPLICATION']) ? $_SESSION['APPLICATION'] : ''), + 'SHD_DATE' => date('Y-m-d H:i:s'))); + } + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. If the object is new, + * it inserts it; otherwise an update is performed. This method + * wraps the doSave() worker method in a transaction. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save($con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getConnection({className}Peer::DATABASE_NAME); + } + + try { + $con->begin(); + $affectedRows = $this->doSave($con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Stores the object in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param Connection $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave($con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + + // If this object has been modified, then save it to the database. + if ($this->isModified()) { + if ($this->isNew()) { + $pk = {className}Peer::doInsert($this, $con); + $affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which + // should always be true here (even though technically + // BasePeer::doInsert() can insert multiple rows). + + $this->setNew(false); + $sAction = 'INSERT'; + $sField = 'ADD_TAB_SDW_LOG_INSERT'; + } else { + $affectedRows += {className}Peer::doUpdate($this, $con); + $sAction = 'UPDATE'; + $sField = 'ADD_TAB_SDW_LOG_UPDATE'; + } + require_once 'classes/model/AdditionalTables.php'; + $oAdditionalTables = new AdditionalTables(); + $aAdditionalTables = $oAdditionalTables->load({className}Peer::__UID__); + if ($aAdditionalTables[$sField] == 1) { + require_once 'classes/model/ShadowTable.php'; + $oShadowTable = new ShadowTable(); + $oShadowTable->create(array('ADD_TAB_UID' => {className}Peer::__UID__, + 'SHD_ACTION' => $sAction, + 'SHD_DETAILS' => serialize($this->toArray(BasePeer::TYPE_FIELDNAME)), + 'USR_UID' => (isset($_SESSION['USER_LOGGED']) ? $_SESSION['USER_LOGGED'] : ''), + 'APP_UID' => (isset($_SESSION['APPLICATION']) ? $_SESSION['APPLICATION'] : ''), + 'SHD_DATE' => date('Y-m-d H:i:s'))); + } + $this->resetModified(); // [HL] After being saved an object is no longer 'modified' + } + + $this->alreadyInSave = false; + } + return $affectedRows; + } // doSave() + + /** + * Array of ValidationFailed objects. + * @var array ValidationFailed[] + */ + protected $validationFailures = array(); + + /** + * Gets any ValidationFailed objects that resulted from last call to validate(). + * + * + * @return array ValidationFailed[] + * @see validate() + */ + public function getValidationFailures() + { + return $this->validationFailures; + } + + /** + * Validates the objects modified field values and all objects related to this table. + * + * If $columns is either a column name or an array of column names + * only those columns are validated. + * + * @param mixed $columns Column name or an array of column names. + * @return boolean Whether all columns pass validation. + * @see doValidate() + * @see getValidationFailures() + */ + public function validate($columns = null) + { + $res = $this->doValidate($columns); + if ($res === true) { + $this->validationFailures = array(); + return true; + } else { + $this->validationFailures = $res; + return false; + } + } + + /** + * This function performs the validation work for complex object models. + * + * In addition to checking the current object, all related objects will + * also be validated. If all pass then true is returned; otherwise + * an aggreagated array of ValidationFailed objects will be returned. + * + * @param array $columns Array of column names to validate. + * @return mixed true if all validations pass; array of ValidationFailed objets otherwise. + */ + protected function doValidate($columns = null) + { + if (!$this->alreadyInValidation) { + $this->alreadyInValidation = true; + $retval = null; + + $failureMap = array(); + + + if (($retval = {className}Peer::doValidate($this, $columns)) !== true) { + $failureMap = array_merge($failureMap, $retval); + } + + + + $this->alreadyInValidation = false; + } + + return (!empty($failureMap) ? $failureMap : true); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return mixed Value of field. + */ + public function getByName($name, $type = BasePeer::TYPE_PHPNAME) + { + $pos = {className}Peer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->getByPosition($pos); + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch($pos) { + + case {index}: + return $this->get{phpName}(); + break; + + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = BasePeer::TYPE_PHPNAME) + { + $keys = {className}Peer::getFieldNames($keyType); + $result = array( + + $keys[{index}] => $this->get{phpName}(), + + ); + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name peer name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return void + */ + public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME) + { + $pos = {className}Peer::translateFieldName($name, $type, BasePeer::TYPE_NUM); + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch($pos) { + + case {index}: + $this->set{phpName}($value); + break; + + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, + * TYPE_NUM. The default key type is the column's phpname (e.g. 'authorId') + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME) + { + $keys = {className}Peer::getFieldNames($keyType); + + if (array_key_exists($keys[{index}], $arr)) $this->set{phpName}($arr[$keys[{index}]]); + + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria({className}Peer::DATABASE_NAME); + + if ($this->isColumnModified({className}Peer::{name})) $criteria->add({className}Peer::{name}, $this->{var}); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria({className}Peer::DATABASE_NAME); + + $criteria->add({className}Peer::{name}, $this->{var}); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return string + */ + public function getPrimaryKey() + { + {getPrimaryKeyFunction} + } + + /** + * Generic method to set the primary key (add_tab_uid column). + * + * @param string $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + {setPrimaryKeyFunction} + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of {className} (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false) + { + + $copyObj->set{phpName}($this->{var}); + + + $copyObj->setNew(true); + + $copyObj->set{phpName}({defaultValue}); // this is a pkey column, so set to default value + + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return {className} Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + return $copyObj; + } + + /** + * Returns a peer instance associated with this om. + * + * Since Peer classes are not to have any instance attributes, this method returns the + * same instance for all member of this class. The method could therefore + * be static, but this would prevent one from overriding the behavior. + * + * @return {className}Peer + */ + public function getPeer() + { + if (self::$peer === null) { + self::$peer = new {className}Peer(); + } + return self::$peer; + } + +} // Base{className} diff --git a/workflow/engine/templates/additionalTables/om/BaseTablePeer.tpl b/workflow/engine/templates/additionalTables/om/BaseTablePeer.tpl new file mode 100644 index 000000000..dedf3615f --- /dev/null +++ b/workflow/engine/templates/additionalTables/om/BaseTablePeer.tpl @@ -0,0 +1,584 @@ + + /** the column name for the {name} field */ + const {name} = '{tableName}.{name}'; + + + /** The PHP to DB Name Mapping */ + private static $phpNameMap = null; + + + /** + * holds an array of fieldnames + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' + */ + private static $fieldNames = array ( + BasePeer::TYPE_PHPNAME => array ( + +'{phpName}', + +), + BasePeer::TYPE_COLNAME => array ( + +{className}Peer::{name}, + +), + BasePeer::TYPE_FIELDNAME => array ( + +'{name}', + +), + BasePeer::TYPE_NUM => array ( + +{index}, + +)); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 + */ + private static $fieldKeys = array ( + BasePeer::TYPE_PHPNAME => array ( + +'{phpName}' => {index}, + +), + BasePeer::TYPE_COLNAME => array ( + +{className}Peer::{name} => {index}, + +), + BasePeer::TYPE_FIELDNAME => array ( + +'{name}' => {index}, + +), + BasePeer::TYPE_NUM => array ( + +{index}, + +)); + + /** + * @return MapBuilder the map builder for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getMapBuilder() + { + include_once '{pathClasses}/' . SYS_SYS . '/classes/map/{className}MapBuilder.php'; + return BasePeer::getMapBuilder('classes.model.map.{className}MapBuilder'); + } + /** + * Gets a map (hash) of PHP names to DB column names. + * + * @return array The PHP to DB name map for this peer + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @deprecated Use the getFieldNames() and translateFieldName() methods instead of this. + */ + public static function getPhpNameMap() + { + if (self::$phpNameMap === null) { + $map = {className}Peer::getTableMap(); + $columns = $map->getColumns(); + $nameMap = array(); + foreach ($columns as $column) { + $nameMap[$column->getPhpName()] = $column->getColumnName(); + } + self::$phpNameMap = $nameMap; + } + return self::$phpNameMap; + } + /** + * Translates a fieldname to another type + * + * @param string $name field name + * @param string $fromType One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @param string $toType One of the class type constants + * @return string translated name of the field. + */ + static public function translateFieldName($name, $fromType, $toType) + { + $toNames = self::getFieldNames($toType); + $key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null; + if ($key === null) { + throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true)); + } + return $toNames[$key]; + } + + /** + * Returns an array of of field names. + * + * @param string $type The type of fieldnames to return: + * One of the class type constants TYPE_PHPNAME, + * TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM + * @return array A list of field names + */ + + static public function getFieldNames($type = BasePeer::TYPE_PHPNAME) + { + if (!array_key_exists($type, self::$fieldNames)) { + throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.'); + } + return self::$fieldNames[$type]; + } + + /** + * Convenience method which changes table.column to alias.column. + * + * Using this method you can maintain SQL abstraction while using column aliases. + * + * $c->addAlias("alias1", TablePeer::TABLE_NAME); + * $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN); + * + * @param string $alias The alias for the current table. + * @param string $column The column name for current table. (i.e. {className}Peer::COLUMN_NAME). + * @return string + */ + public static function alias($alias, $column) + { + return str_replace({className}Peer::TABLE_NAME.'.', $alias.'.', $column); + } + + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param criteria object containing the columns to add. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria) + { + + $criteria->addSelectColumn({className}Peer::{name}); + + } + + const COUNT = 'COUNT({tableName}.{firstColumn})'; + const COUNT_DISTINCT = 'COUNT(DISTINCT {tableName}.{firstColumn})'; + + /** + * Returns the number of rows matching criteria. + * + * @param Criteria $criteria + * @param boolean $distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria). + * @param Connection $con + * @return int Number of matching rows. + */ + public static function doCount(Criteria $criteria, $distinct = false, $con = null) + { + // we're going to modify criteria, so copy it first + $criteria = clone $criteria; + + // clear out anything that might confuse the ORDER BY clause + $criteria->clearSelectColumns()->clearOrderByColumns(); + if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) { + $criteria->addSelectColumn({className}Peer::COUNT_DISTINCT); + } else { + $criteria->addSelectColumn({className}Peer::COUNT); + } + + // just in case we're grouping: add those columns to the select statement + foreach($criteria->getGroupByColumns() as $column) + { + $criteria->addSelectColumn($column); + } + + $rs = {className}Peer::doSelectRS($criteria, $con); + if ($rs->next()) { + return $rs->getInt(1); + } else { + // no rows returned; we infer that means 0 matches. + return 0; + } + } + /** + * Method to select one object from the DB. + * + * @param Criteria $criteria object used to create the SELECT statement. + * @param Connection $con + * @return {className} + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelectOne(Criteria $criteria, $con = null) + { + $critcopy = clone $criteria; + $critcopy->setLimit(1); + $objects = {className}Peer::doSelect($critcopy, $con); + if ($objects) { + return $objects[0]; + } + return null; + } + /** + * Method to do selects. + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con + * @return array Array of selected Objects + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doSelect(Criteria $criteria, $con = null) + { + return {className}Peer::populateObjects({className}Peer::doSelectRS($criteria, $con)); + } + /** + * Prepares the Criteria object and uses the parent doSelect() + * method to get a ResultSet. + * + * Use this method directly if you want to just get the resultset + * (instead of an array of objects). + * + * @param Criteria $criteria The Criteria object used to build the SELECT statement. + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return ResultSet The resultset object with numerically-indexed fields. + * @see BasePeer::doSelect() + */ + public static function doSelectRS(Criteria $criteria, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if (!$criteria->getSelectColumns()) { + $criteria = clone $criteria; + {className}Peer::addSelectColumns($criteria); + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + // BasePeer returns a Creole ResultSet, set to return + // rows indexed numerically. + return BasePeer::doSelect($criteria, $con); + } + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(ResultSet $rs) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = {className}Peer::getOMClass(); + $cls = Propel::import($cls); + // populate the object(s) + while($rs->next()) { + + $obj = new $cls(); + $obj->hydrate($rs); + $results[] = $obj; + + } + return $results; + } + /** + * Returns the TableMap related to this peer. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME); + } + + /** + * The class that the Peer will make instances of. + * + * This uses a dot-path notation which is tranalted into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @return string path.to.ClassName + */ + public static function getOMClass() + { + return {className}Peer::CLASS_DEFAULT; + } + + /** + * Method perform an INSERT on the database, given a {className} or Criteria object. + * + * @param mixed $values Criteria or {className} object containing data that is used to create the INSERT statement. + * @param Connection $con the connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } else { + $criteria = $values->buildCriteria(); // build Criteria from {className} object + } + + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->begin(); + $pk = BasePeer::doInsert($criteria, $con); + $con->commit(); + } catch(PropelException $e) { + $con->rollback(); + throw $e; + } + + return $pk; + } + + /** + * Method perform an UPDATE on the database, given a {className} or Criteria object. + * + * @param mixed $values Criteria or {className} object containing data that is used to create the UPDATE statement. + * @param Connection $con The connection to use (specify Connection object to exert more control over transactions). + * @return int The number of affected rows (if supported by underlying database driver). + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doUpdate($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + + $selectCriteria = new Criteria(self::DATABASE_NAME); + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + + $comparison = $criteria->getComparison({className}Peer::{name}); + $selectCriteria->add({className}Peer::{name}, $criteria->remove({className}Peer::{name}), $comparison); + + } else { // $values is {className} object + $criteria = $values->buildCriteria(); // gets full criteria + $selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s) + } + + // set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + return BasePeer::doUpdate($selectCriteria, $criteria, $con); + } + + /** + * Method to DELETE all rows from the {tableName} table. + * + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll($con = null) + { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + $affectedRows += BasePeer::doDeleteAll({className}Peer::TABLE_NAME, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Method perform a DELETE on the database, given a {className} or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or {className} object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param Connection $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, $con = null) + { + if ($con === null) { + $con = Propel::getConnection({className}Peer::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + $criteria = clone $values; // rename for clarity + } elseif ($values instanceof {className}) { + + $criteria = $values->buildPkeyCriteria(); + } else { + // it must be the primary key + $criteria = new Criteria(self::DATABASE_NAME); + {forDoDeleteFunction} + } + + // Set the correct dbName + $criteria->setDbName(self::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->begin(); + + $affectedRows += BasePeer::doDelete($criteria, $con); + $con->commit(); + return $affectedRows; + } catch (PropelException $e) { + $con->rollback(); + throw $e; + } + } + + /** + * Validates all modified columns of given {className} object. + * If parameter $columns is either a single column name or an array of column names + * than only those columns are validated. + * + * NOTICE: This does not apply to primary or foreign keys for now. + * + * @param {className} $obj The object to validate. + * @param mixed $cols Column name or array of column names. + * + * @return mixed TRUE if all columns are valid or the error message of the first invalid column. + */ + public static function doValidate({className} $obj, $cols = null) + { + $columns = array(); + + if ($cols) { + $dbMap = Propel::getDatabaseMap({className}Peer::DATABASE_NAME); + $tableMap = $dbMap->getTable({className}Peer::TABLE_NAME); + + if (! is_array($cols)) { + $cols = array($cols); + } + + foreach($cols as $colName) { + if ($tableMap->containsColumn($colName)) { + $get = 'get' . $tableMap->getColumn($colName)->getPhpName(); + $columns[$colName] = $obj->$get(); + } + } + } else { + + } + + return BasePeer::doValidate({className}Peer::DATABASE_NAME, {className}Peer::TABLE_NAME, $columns); + } + + /** + * Retrieve a single object by pkey. + * + * @param mixed $pk the primary key. + * @param Connection $con the connection to use + * @return {className} + */ + public static function retrieveByPK( {sKeys}, $con = null) { + if ($con === null) { + $con = Propel::getConnection(self::DATABASE_NAME); + } + $criteria = new Criteria(); + + + $criteria->add({className}Peer::{name}, ${var}); + + + //$criteria->add({className}Peer::PM_UNIQUE_ID, $pm_unique_id); + $v = {className}Peer::doSelect($criteria, $con); + + return !empty($v) ? $v[0] : null; + } + + /** + * Retrieve multiple objects by pkey. + * + * @param array $pks List of primary keys + * @param Connection $con the connection to use + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + {retrieveByPKsFunction} + +} // Base{className}Peer + +// static code to register the map builder for this Peer with the main Propel class +if (Propel::isInit()) { + // the MapBuilder classes register themselves with Propel during initialization + // so we need to load them here. + try { + Base{className}Peer::getMapBuilder(); + } catch (Exception $e) { + Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR); + } +} else { + // even if Propel is not yet initialized, the map builder class can be registered + // now and then it will be loaded when Propel initializes. + require_once '{pathClasses}/' . SYS_SYS . '/classes/map/{className}MapBuilder.php'; + Propel::registerMapBuilder('classes.model.map.{className}MapBuilder'); +} diff --git a/workflow/engine/templates/additionalTables/paged-table.html b/workflow/engine/templates/additionalTables/paged-table.html new file mode 100755 index 000000000..cde0e60bb --- /dev/null +++ b/workflow/engine/templates/additionalTables/paged-table.html @@ -0,0 +1,222 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + {labels:CHECK_ALL} /  + {labels:UNCHECK_ALL} /  + {labels:ID_EXPORT} + +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/additionalTables/paged-table2.html b/workflow/engine/templates/additionalTables/paged-table2.html new file mode 100755 index 000000000..c3853bfb8 --- /dev/null +++ b/workflow/engine/templates/additionalTables/paged-table2.html @@ -0,0 +1,137 @@ + +
    +
    +
    + + + + +
    + {title} +

    + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/appFolder/appFolderFileList.html b/workflow/engine/templates/appFolder/appFolderFileList.html new file mode 100755 index 000000000..10c5cc443 --- /dev/null +++ b/workflow/engine/templates/appFolder/appFolderFileList.html @@ -0,0 +1 @@ +File List \ No newline at end of file diff --git a/workflow/engine/templates/appFolder/appFolderTree.php b/workflow/engine/templates/appFolder/appFolderTree.php new file mode 100755 index 000000000..8e37a2f00 --- /dev/null +++ b/workflow/engine/templates/appFolder/appFolderTree.php @@ -0,0 +1,118 @@ +getFolderStructure($rootFolder); +} + +$html = ' +
    + +
    +
    + + + + + +
    +
    +
    + + '; + $html.='
    +
    +
    +
    +
    +
    + + '; + + //add alvaro + function looking_for_browser($user_agent) { + $browsers = array( + 'Opera' => 'Opera', + 'Mozilla Firefox'=> '(Firebird)|(Firefox)', + 'Galeon' => 'Galeon', + 'Mozilla'=>'Gecko', + 'MyIE'=>'MyIE', + 'Lynx' => 'Lynx', + 'Netscape' => '(Mozilla/4\.75)|(Netscape6)|(Mozilla/4\.08)|(Mozilla/4\.5)|(Mozilla/4\.6)|(Mozilla/4\.79)', + 'Konqueror'=>'Konqueror', + 'Internet Explorer 8' => '(MSIE 8\.[0-9]+)', + 'Internet Explorer 7' => '(MSIE 7\.[0-9]+)', + 'Internet Explorer 6' => '(MSIE 6\.[0-9]+)', + 'Internet Explorer 5' => '(MSIE 5\.[0-9]+)', + 'Internet Explorer 4' => '(MSIE 4\.[0-9]+)', + ); + foreach($browsers as $browser=>$pattern){ + if (eregi($pattern, $user_agent)) + return $browser; + } + return 'Unknown'; + } + +if((looking_for_browser($_SERVER['HTTP_USER_AGENT'])=='Internet Explorer 8')||(looking_for_browser($_SERVER['HTTP_USER_AGENT'])=='Internet Explorer 7')||(looking_for_browser($_SERVER['HTTP_USER_AGENT'])=='Internet Explorer 6')){ + $html.=" +
    +
    +
    + "; + + $html.=' +
    +
    +
    +
    +
    +
    '; + +}else{ + $html.=" +
    +
    +
    + "; + $html.=' +
    +
    +
    +
    +
    + '; + +} + + + //end add + + + + $html.='
    +
    +
    +
    +
    +
    + +
    '; + $html.="
    +
    + "; + $html.=' +
    +
    +
    +
    +
    +
    '; + + + + echo $html; + ?> \ No newline at end of file diff --git a/workflow/engine/templates/authListUsers.html b/workflow/engine/templates/authListUsers.html new file mode 100644 index 000000000..6e575bbb6 --- /dev/null +++ b/workflow/engine/templates/authListUsers.html @@ -0,0 +1,71 @@ +
    + + + + '); + echo('
    + + + + + + +
    {title} +
    + + +
    {text}

    +
    + + + + + + + + + + + + +
    + + + + + + +
    {title} +
    + + +
    {empty-rows-text}

    +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    User{title} User IdRoles{title}
    {index}{dn}
    {fullname} ( {email} )
    {checkbox}{input}{options}
     
    +
    + diff --git a/workflow/engine/templates/cases/casesDemo.html b/workflow/engine/templates/cases/casesDemo.html new file mode 100644 index 000000000..976dccbff --- /dev/null +++ b/workflow/engine/templates/cases/casesDemo.html @@ -0,0 +1,562 @@ +{literal} + +{/literal} + +
    +
      +
    • + +
      + Application + ({$APP_UID}) + {$APP_STATUS} + {$APP_NUMBER} + +
      + +
      +
        +
      • + +
        + properties + (Array, 7 elements) +
        + +
      • + +
      • +
        + delegations + (Array, {$CANT_DELEGATIONS} elements) +
        +
        +
          + {foreach key=id item=data from=$DELEGATIONS} +
        • +
          + {$data.DEL_INDEX} + [thread: + {$data.DEL_THREAD}] + [thread status: + {$data.DEL_THREAD_STATUS}] + [type: + {$data.DEL_TYPE}] + [user: + {$data.USR_NAME}] + [task: + {$data.TAS_TITLE}] +
          + +
        • + {/foreach} + +
        +
        + +
      • +
        + threads + (Array, {$CANT_THREADS} elements) +
        +
        +
          + {foreach key=id item=data from=$THREADS} +
        • +
          + {$data.APP_THREAD_INDEX} + [thread status: + {$data.APP_THREAD_STATUS}] + [thread parent: + {$data.APP_THREAD_PARENT}] + [del_index: + {$data.DEL_INDEX}] +
          +
        • + {/foreach} +
        +
        +
      • + +
      • +
        + actions (APP_DELAY) + (Array, {$CANT_DELAYS} elements) +
        +
        +
          + {foreach key=id item=data from=$DELAYS} +
        • +
          + {$data.APP_TYPE} + [thread index:{$data.APP_THREAD_INDEX}] + [delegation index:{$data.APP_DEL_INDEX}] + [application status:{$data.APP_STATUS}]
          + [enable action user:{$data.APP_ENABLE_ACTION_USER}] + [enable action date:{$data.APP_ENABLE_ACTION_DATE}]
          + [disable action user:{$data.APP_DISABLE_ACTION_USER}] + [disable action date:{$data.APP_DISABLE_ACTION_DATE}] +
          +
        • + {/foreach} +
        +
        +
      • + +
      • +
        + Sub Cases(SUB_APPLICATION) + (Array, {$CANT_SUBAPPLICATIONS} elements) +
        +
        +
          + {foreach key=id item=data from=$SUBAPPLICATIONS} +
        • +
          + {$data.APP_TYPE} + [case parent:{$data.APP_PARENT} Case Number: {$data.APP_NUMBER}]
          + [del index parent:{$data.DEL_INDEX_PARENT}]
          + [del thread parent:{$data.DEL_THREAD_PARENT}]
          + [SubCase Status:{$data.SA_STATUS}]
          + [Starting Date:{$data.SA_INIT_DATE}] + [Finish Date:{$data.SA_FINISH_DATE}] +
          +
        • + {/foreach} +
        +
        +
      • + +
      • +
        + APP_DATA + (Array, {$CANT_APP_DATA} elements) +
        +
        +
          + {foreach key=id item=data from=$APP_DATA} +
        • +
          + {$id}  + {$data} +
          +
        • + {/foreach} +
        +
        +
      • + + +
      +
      + +{literal} + + +{/literal} diff --git a/workflow/engine/templates/cases/casesList.js b/workflow/engine/templates/cases/casesList.js new file mode 100755 index 000000000..f50da37d3 --- /dev/null +++ b/workflow/engine/templates/cases/casesList.js @@ -0,0 +1,1543 @@ +new Ext.KeyMap(document, { + key: Ext.EventObject.F5, + fn: function(keycode, e) { + if (! e.ctrlKey) { + if (Ext.isIE) { + // IE6 doesn't allow cancellation of the F5 key, so trick it into + // thinking some other key was pressed (backspace in this case) + e.browserEvent.keyCode = 8; + } + e.stopEvent(); + //document.location = document.location; + storeCases.reload(); + } + else + Ext.Msg.alert(TRANSLATIONS.LABEL_REFRESH, TRANSLATIONS.MESSAGE_REFRESH); + } +}); + +/*** global variables **/ +var storeCases; +var storeReassignCases; +var grid; +var textJump; + +/** */ + +function openCase(){ + + var rowModel = grid.getSelectionModel().getSelected(); + if(rowModel){ + var appUid = rowModel.data.APP_UID; + var delIndex = rowModel.data.DEL_INDEX; + var caseTitle = (rowModel.data.APP_TITLE) ? rowModel.data.APP_TITLE : rowModel.data.APP_UID; + + Ext.Msg.show({ + msg: TRANSLATIONS.LABEL_OPEN_CASE + ' ' + caseTitle, + width:300, + wait:true, + waitConfig: {interval:200} + }); + params = ''; + switch(action){ + case 'to_revise': + params += 'APP_UID=' + appUid; + params += '&DEL_INDEX=' + delIndex; + requestFile = '../cases/cases_OpenToRevise'; + break; + case 'sent': // = participated + params += 'APP_UID=' + appUid; + params += '&DEL_INDEX=' + delIndex; + requestFile = '../cases/cases_Open'; + break; + case 'todo': + case 'draft': + case 'paused': + case 'unassigned': + default: + params += 'APP_UID=' + appUid; + params += '&DEL_INDEX=' + delIndex; + requestFile = '../cases/cases_Open'; + break; + } + + params += '&action=' + action; + redirect(requestFile + '?' + params); + + } else + msgBox('Information', TRANSLATIONS.ID_SELECT_ONE_AT_LEAST); +} + +function jumpToCase(appNumber){ + params = 'APP_NUMBER=' + appNumber; + params += '&action=jump'; + requestFile = '../cases/cases_Open'; + redirect(requestFile + '?' + params); +} + +function deleteCase() { + var rows = grid.getSelectionModel().getSelections(); + if( rows.length > 0 ) { + ids = Array(); + for(i=0; i 0 ) { + app_uid = Array(); + del_index = Array(); + + for(i=0; i" + TRANSLATIONS.ID_VIEW + "", r.data['APP_UID'], r.data['DEL_INDEX'], r.data['APP_TITLE']); + } + + function deleteLink(value, p, r){ + return String.format("" + TRANSLATIONS.ID_DELETE + "", r.data['APP_UID'] ); + } + + function viewLink(value, p, r){ + return String.format("" + TRANSLATIONS.ID_VIEW + "", r.data['APP_UID'], r.data['DEL_INDEX'], r.data['APP_TITLE']); + } + + function unpauseLink(value, p, r){ + return String.format("" + TRANSLATIONS.ID_UNPAUSE + "", r.data['APP_UID'], r.data['DEL_INDEX'] ); + } + + function convertDate ( value ) { + myDate = new Date( 1900,0,1,0,0,0); + try{ + if(!Ext.isDate( value )){ + var myArray = value.split(' '); + var myArrayDate = myArray[0].split('-'); + if ( myArray.length > 1 ) + var myArrayHour = myArray[1].split(':'); + else + var myArrayHour = new Array('0','0','0'); + var myDate = new Date( myArrayDate[0], myArrayDate[1]-1, myArrayDate[2], myArrayHour[0], myArrayHour[1], myArrayHour[2] ); + } + } + catch(e){}; + + return myDate; + } + function showDate (value,p,r) { + var myDate = convertDate( value ); + return String.format("{0}", myDate.dateFormat( PMDateFormat )); + } + + function dueDate(value, p, r){ + var myDate = convertDate( value ); + var myColor = (myDate < new Date()) ? " color:red;" : 'color:green;'; + return String.format("{0}", myDate.dateFormat(PMDateFormat), myColor ); + } + + function showField (value,p,r) { + if ( r.data['DEL_INIT_DATE'] ) + return String.format("{0}", value ); + else + return String.format("{0}", value ); + } + + for(var i = 0, len = columns.length; i < len; i++){ + var c = columns[i]; + c.renderer = showField; + if( c.dataIndex == 'DEL_TASK_DUE_DATE') c.renderer = dueDate; + if( c.dataIndex == 'APP_UPDATE_DATE') c.renderer = showDate; + if( c.id == 'deleteLink') c.renderer = deleteLink; + if( c.id == 'viewLink') c.renderer = viewLink; + if( c.id == 'unpauseLink') c.renderer = unpauseLink; + } + + //adding the hidden field DEL_INIT_DATE + readerFields.push ( {name: "DEL_INIT_DATE"}); + readerFields.push ( {name: "APP_UID"}); + readerFields.push ( {name: "DEL_INDEX"}); + + + var cm = new Ext.grid.ColumnModel({ + defaults: { + sortable: true // columns are sortable by default + }, + columns: columns + }); + + var reassignCm = new Ext.grid.ColumnModel({ + defaults: { + sortable: true // columns are sortable by default + }, + columns: reassignColumns + }); + + var newPopUp = new Ext.Window({ + id : Ext.id(), + el : 'reassign-panel', + title : 'Reassign All Cases by Task', + width : 750, + height : 350, + frame : true, + closable: false + }); + + var btnCloseReassign = new Ext.Button ({ + text: 'Close', + // text: TRANSLATIONS.LABEL_SELECT_ALL, + handler: function(){ + newPopUp.hide(); + } + }); + + var btnExecReassign = new Ext.Button ({ + text: 'Reassign All', + // text: TRANSLATIONS.LABEL_SELECT_ALL, + handler: function(){ + + var rs = storeReassignCases.getModifiedRecords(); + var sv = []; + for(var i = 0; i <= rs.length-1; i++){ + //sv[i]= rs[i].data['name']; + sv[i]= rs[i].data; + } + var gridData = storeReassignCases.getModifiedRecords(); + + Ext.Ajax.request({ + url: 'proxySaveReassignCasesList', + success: function(response) { + newPopUp.hide(); + storeCases.reload(); + }, + params: { APP_UIDS:ids, data:Ext.util.JSON.encode(sv), selected:false } + }); + + /* + storeReassignCases.setBaseParam('selected', false); + var result = storeReassignCases.save(); + newPopUp.hide(); + storeCases.reload(); + */ + //storeReassignCases.reload(); + } + }); + + var btnExecReassignSelected = new Ext.Button ({ + text: 'Reassign', + // text: TRANSLATIONS.LABEL_SELECT_ALL, + handler: function(){ + newPopUp.hide(); + var rs = storeReassignCases.getModifiedRecords(); + var sv = []; + for(var i = 0; i <= rs.length-1; i++){ + //sv[i]= rs[i].data['name']; + sv[i]= rs[i].data; + } + var gridData = storeReassignCases.getModifiedRecords(); + Ext.MessageBox.show({ msg: TRANSLATIONS.ID_PROCESSING, wait:true,waitConfig: {interval:200} }); + Ext.Ajax.request({ + url: 'proxySaveReassignCasesList', + success: function(response) { + Ext.MessageBox.hide(); + storeCases.reload(); + var ajaxServerResponse = Ext.util.JSON.decode(response.responseText); + var count; + var message = ''; + + for (count in ajaxServerResponse) { + if ( ajaxServerResponse[count]['TAS_TITLE'] != undefined ){ + message = message + "Task: " + ajaxServerResponse[count]['TAS_TITLE'] + " - Reassigned Cases: " + ajaxServerResponse[count]['REASSIGNED_CASES'] + "
      " ; + }; + } + + if (ajaxServerResponse['TOTAL']!=undefined&&ajaxServerResponse['TOTAL']!=-1){ + message = message + "Total Cases Reassigned: " + ajaxServerResponse['TOTAL']; + } else { + message = ""; + }; + + if (message!=""){ + Ext.MessageBox.alert( 'Status Reassignment', message, '' ); + } + }, + params: { APP_UIDS:ids, data:Ext.util.JSON.encode(sv), selected:true } + }); + + /*storeReassignCases.setBaseParam('selected', true); + var result = storeReassignCases.save(); + //storeCases.load({params:{process: filterProcess, start : 0 , limit : pageSize}}); + newPopUp.hide(); + storeCases.reload(); + //storeReassignCases.reload(); + */ + } + }); + + // Create HttpProxy instance, all CRUD requests will be directed to single proxy url. + var proxyCasesList = new Ext.data.HttpProxy({ + api: { + read : 'proxyCasesList' + } + }); + + // Typical JsonReader with additional meta-data params for defining the core attributes of your json-response + // the readerFields is defined in PHP server side + var readerCasesList = new Ext.data.JsonReader({ + totalProperty: 'totalCount', + successProperty: 'success', + idProperty: 'index', + root: 'data', + messageProperty: 'message' + }, + readerFields + ); + + // The new DataWriter component. + //currently we are not using this in casesList, but it is here just for complete definition + var writerCasesList = new Ext.data.JsonWriter({ + encode: true, + writeAllFields: true + }); + + var proxyReassignCasesList = new Ext.data.HttpProxy({ + api: { + read : 'proxyReassignCasesList' + //create : 'proxySaveReassignCasesList', + //update : 'proxySaveReassignCasesList', + //destroy : 'proxyReassignCasesList' + } + }); + + var readerReassignCasesList = new Ext.data.JsonReader({ + totalProperty: 'totalCount', + successProperty: 'success', + idProperty: 'index', + root: 'data', + messageProperty: 'message' + }, + reassignReaderFields + ); + + // The new DataWriter component. + //currently we are not using this in casesList, but it is here just for complete definition + var writerReassignCasesList = new Ext.data.JsonWriter({ + encode: true, + writeAllFields: true + }); + + + + // Typical Store collecting the Proxy, Reader and Writer together. + // This is the store for Cases List + storeCases = new Ext.data.Store({ + remoteSort: true, + proxy: proxyCasesList, + reader: readerCasesList, + writer: writerCasesList, // <-- plug a DataWriter into the store just as you would a Reader + autoSave: true, // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton. + sortInfo:{field: 'APP_CACHE_VIEW.APP_NUMBER', direction: "DESC"} + }); + + storeReassignCases = new Ext.data.Store({ + remoteSort: false, + proxy : proxyReassignCasesList, + reader: readerReassignCasesList + //writer: writerReassignCasesList, // <-- plug a DataWriter into the store just as you would a Reader + //autoSave: false // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton. + }); + + //Layout Resizing + storeCases.on('load',function(){var viewport = Ext.getCmp("viewportcases");viewport.doLayout();}) + + // create the Data Store for processes + var storeProcesses = new Ext.data.JsonStore({ + root: 'data', + totalProperty: 'totalCount', + idProperty: 'index', + remoteSort: true, + fields: [ + 'PRO_UID', 'APP_PRO_TITLE' + ], + proxy: new Ext.data.HttpProxy({ + url: 'proxyProcessList?t=new' + }) + }); + storeProcesses.setDefaultSort('APP_PRO_TITLE', 'asc'); + + // creating the button for filters + var btnRead = new Ext.Button ({ + id: 'read', + text: TRANSLATIONS.LABEL_OPT_READ, + enableToggle: true, + toggleHandler: onItemToggle, + allowDepress: false, + pressed: false + }); + + var btnUnread = new Ext.Button ({ + id: 'unread', + text: TRANSLATIONS.LABEL_OPT_UNREAD, + enableToggle: true, + toggleHandler: onItemToggle, + allowDepress: false, + pressed: false + }); + + var btnAll = new Ext.Button ({ + id: 'all', + text: TRANSLATIONS.LABEL_OPT_ALL, + enableToggle: true, + toggleHandler: onItemToggle, + allowDepress: false, + pressed: true + }); + + var btnStarted = new Ext.Button ({ + id: 'started', +// text: 'started by me', + text: TRANSLATIONS.LABEL_OPT_STARTED, + enableToggle: true, + toggleHandler: onItemToggle, + allowDepress: true, + pressed: false + }); + + var btnCompleted = new Ext.Button ({ + id: 'completed', +// text: 'Completed by me', + text: TRANSLATIONS.LABEL_OPT_COMPLETED, + enableToggle: true, + toggleHandler: onItemToggle, + allowDepress: true, + pressed: false + }); + + // ComboBox creation processValues + var comboProcess = new Ext.form.ComboBox({ + width : 180, + boxMaxWidth : 180, + editable : true, + displayField : 'APP_PRO_TITLE', + valueField : 'PRO_UID', + forceSelection: false, + emptyText: TRANSLATIONS.LABEL_EMPTY_PROCESSES, + selectOnFocus: true, + + + typeAhead: true, + mode: 'local', + autocomplete: true, + triggerAction: 'all', + + store : new Ext.data.ArrayStore({ + fields : ['PRO_UID','APP_PRO_TITLE'], + data : processValues + }), + listeners:{ + scope: this, + 'select': function() { + filterProcess = comboProcess.value; + if ( action == 'search' ){ + storeCases.setBaseParam('dateFrom', dateFrom.getValue()); + storeCases.setBaseParam('dateTo', dateTo.getValue()); + } + storeCases.setBaseParam('process', filterProcess); + storeCases.load({params:{process: filterProcess, start : 0 , limit : pageSize}}); + }}, + iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu + }); + + var comboAllUsers = new Ext.form.ComboBox({ + width : 180, + boxMaxWidth : 180, + editable : false, + displayField : 'USR_FULLNAME', + valueField : 'USR_UID', + //typeAhead : true, + mode : 'local', + forceSelection: true, + triggerAction: 'all', + + emptyText: TRANSLATIONS.LABEL_EMPTY_USERS, + selectOnFocus: true, + //getListParent: function() { + // return this.el.up('.x-menu'); + //}, + store : new Ext.data.ArrayStore({ + fields: ['USR_UID','USR_FULLNAME'], + data : allUsersValues + }), + listeners:{ + scope: this, + 'select': function() { + filterProcess = comboAllUsers.value; + + if (filterProcess==''){ + btnSelectAll.hide(); + btnUnSelectAll.hide(); + btnReassign.hide(); + } + else { + btnSelectAll.show(); + btnUnSelectAll.show(); + btnReassign.show(); + } + storeCases.setBaseParam( 'user', filterProcess); + storeCases.load({params:{user: filterProcess, start : 0 , limit : pageSize}}); + }}, + iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu + }); + + var btnSelectAll = new Ext.Button ({ + text: 'Check All', +// text: TRANSLATIONS.LABEL_SELECT_ALL, + handler: function(){ + grid.getSelectionModel().selectAll(); + } + }); + + var btnUnSelectAll = new Ext.Button ({ + text: 'Un-Check All', +// text: TRANSLATIONS.LABEL_UNSELECT_ALL, + handler: function(){ + grid.getSelectionModel().clearSelections(); + } + }); + + var btnReassign = new Ext.Button ({ + text: 'Reassign', +// text: TRANSLATIONS.LABEL_UNSELECT_ALL, + handler: function(){ + reassign(); + } + }); + +// var conn = new Ext.data.Connection(); + var nav = new Ext.FormPanel({ + labelWidth:100, + frame:true, + width:300, + collapsible:true, + defaultType:'textfield', + items:[{ + fieldLabel:'Reassign To', + name:'txt_stock_in', + allowBlank:true + }] + }); + + var reassignPopup = new Ext.Window({ + el:'reassign-panel', + modal:true, + layout:'fit', + width:300, + height:300, + closable:false, + resizable:false, + plain:true, + items:[nav], + buttons:[{ + text:'submit', + handler:function(){ + Ext.Msg.alert('OK','save ?'); + Ext.Msg.prompt('Name','please enter your name: ',function(btn,text){ + if(btn=='ok') { + alert('ok'); + } + }); + } + }, { + text:'close', + handler:function() { + reassignPopup.hide(); + } + }] + }); + // ComboBox creation + var comboStatus = new Ext.form.ComboBox({ + width : 90, + boxMaxWidth : 90, + editable : false, + mode : 'local', + store : new Ext.data.ArrayStore({ + fields: ['id', 'value'], + data : statusValues + }), + valueField : 'id', + displayField : 'value', + triggerAction : 'all', + + //typeAhead: true, + //forceSelection: true, + //emptyText: 'Select a status...', + //selectOnFocus: true, + //getListParent: function() { + // return this.el.up('.x-menu'); + //}, + listeners:{ + scope: this, + 'select': function() { + filterStatus = comboStatus.value; + storeCases.setBaseParam( 'status', filterStatus); + storeCases.setBaseParam( 'start', 0); + storeCases.setBaseParam( 'limit', pageSize); + storeCases.load(); + }}, + iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu + }); + + // ComboBox creation processValues + var comboUser = new Ext.form.ComboBox({ + width : 160, + boxMaxWidth : 180, + editable : true, + displayField : 'USR_FULLNAME', + valueField : 'USR_UID', + mode : 'local', + forceSelection: false, + emptyText: 'Select', + selectOnFocus: true, + + typeAhead: true, + mode: 'local', + autocomplete: true, + triggerAction: 'all', + + store : new Ext.data.ArrayStore({ + fields: ['USR_UID','USR_FULLNAME'], + data : userValues + }), + listeners:{ + scope: this, + 'select': function() { + filterUser = comboUser.value; + storeCases.setBaseParam( 'user', filterUser); + storeCases.setBaseParam( 'start', 0); + storeCases.setBaseParam( 'limit', pageSize); + storeCases.load(); + }}, + iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu + }); + + + var textSearch = new Ext.form.TextField ({ + allowBlank: true, + ctCls:'pm_search_text_field', + width: 150, + emptyText: TRANSLATIONS.LABEL_EMPTY_SEARCH, + listeners: { + specialkey: function(f,e){ + if (e.getKey() == e.ENTER) { + doSearch(); + } + } + } + }); + + var btnSearch = new Ext.Button ({ + text: TRANSLATIONS.LABEL_SEARCH, + handler: doSearch + }); + + function doSearch(){ + searchText = textSearch.getValue(); + storeCases.setBaseParam( 'search', searchText); + storeCases.load({params:{ start : 0 , limit : pageSize }}); + } + + var resetSearchButton = { + text:'X', + ctCls:'pm_search_x_button', + handler: function(){ + textSearch.setValue(''); + doSearch(); + } + } + + textJump = { + xtype: 'numberfield', + allowBlank: true, + width: 50, + emptyText: TRANSLATIONS.ID_CASESLIST_APP_UID, + listeners: { + specialkey: function(f,e){ + if (e.getKey() == e.ENTER) { + caseNumber = parseFloat(Ext.util.Format.trim(textJump.getValue())); + if( caseNumber ) + jumpToCase(caseNumber); + else + msgBox('Input Error', 'You have set a invalid Application Number', 'error'); + } + } + } + }; + + var btnJump = new Ext.Button ({ + text: TRANSLATIONS.LABEL_OPT_JUMP, + handler: function(){ + caseNumber = parseFloat(Ext.util.Format.trim(textJump.getValue())); + caseNumber = parseFloat(Ext.util.Format.trim(textJump.getValue())); + if( caseNumber ) + jumpToCase(caseNumber); + else + msgBox('Input Error', 'You have set a invalid Application Number', 'error'); + } + }); + + /*** menu and toolbars **/ + + function onMessageContextMenu(grid, rowIndex, e) { + e.stopEvent(); + var coords = e.getXY(); + messageContextMenu.showAt([coords[0], coords[1]]); + enableDisableMenuOption(); + } + + function enableDisableMenuOption(){ + var rows = grid.getSelectionModel().getSelections(); + switch(action){ + case 'todo': + if( rows.length == 0 ) { + optionMenuOpen.setDisabled(true); + optionMenuPause.setDisabled(true); + optionMenuReassign.setDisabled(true); + optionMenuCancel.setDisabled(true); + } else if( rows.length == 1 ) { + optionMenuOpen.setDisabled(false); + optionMenuPause.setDisabled(false); + optionMenuReassign.setDisabled(false); + optionMenuCancel.setDisabled(false); + } else { + optionMenuOpen.setDisabled(true); + optionMenuPause.setDisabled(true); + optionMenuReassign.setDisabled(true); + optionMenuCancel.setDisabled(false); + } + break; + case 'draft': + if( rows.length == 0 ) { + optionMenuOpen.setDisabled(true); + optionMenuPause.setDisabled(true); + optionMenuReassign.setDisabled(true); + optionMenuDelete.setDisabled(true); + } else if( rows.length == 1 ) { + optionMenuOpen.setDisabled(false); + optionMenuPause.setDisabled(false); + optionMenuReassign.setDisabled(false); + optionMenuDelete.setDisabled(false); + } else { + optionMenuOpen.setDisabled(true); + optionMenuPause.setDisabled(true); + optionMenuReassign.setDisabled(true); + optionMenuDelete.setDisabled(false); + } + break; + } + } + + var menuItems; + //alert(action); + optionMenuOpen = new Ext.Action({ + text: TRANSLATIONS.ID_OPEN_CASE, + iconCls: 'ICON_CASES_OPEN', + handler: openCase + }); + + optionMenuUnpause = new Ext.Action({ + text: TRANSLATIONS.ID_UNPAUSE_CASE, + iconCls: 'ICON_CASES_UNPAUSE', + handler: unpauseCase + }); + + optionMenuPause = new Ext.Action({ + text: TRANSLATIONS.ID_PAUSE_CASE, + iconCls: 'ICON_CASES_PAUSED', + menu: new Ext.menu.DateMenu({ + //vtype: 'daterange', + handler: function(dp, date){ + pauseCase(date); + } + }) + + }); + + //optionMenuPause.setMinValue('2010-11-04'); + optionMenuReassign = new Ext.Action({ + text: TRANSLATIONS.ID_REASSIGN, + iconCls: 'ICON_CASES_TO_REASSIGN', + handler: function(){} + }); + optionMenuDelete = new Ext.Action({ + text: TRANSLATIONS.ID_DELETE, + iconCls: 'ICON_CASES_DELETE', + handler: deleteCase + }); + optionMenuCancel = new Ext.Action({ + text: TRANSLATIONS.ID_CANCEL, + iconCls: 'ICON_CASES_CANCEL', + handler: cancelCase + }); + + + switch(action){ + case 'todo': + menuItems = [optionMenuOpen, optionMenuPause]; + + if( ___p34315105.search('R') > 0 ) + menuItems.push(optionMenuReassign); + if( ___p34315105.search('C') > 0 ) + menuItems.push(optionMenuCancel); + + break; + + case 'draft': + menuItems = [optionMenuOpen, optionMenuPause]; + if( ___p34315105.search('R') > 0 ) + menuItems.push(optionMenuReassign); + menuItems.push(optionMenuDelete); + + break; + + case 'paused': + menuItems = [optionMenuUnpause]; + break; + + default: + menuItems = [] + } + + var messageContextMenu = new Ext.menu.Menu({ + id: 'messageContextMenu', + items: menuItems + }); + + // + + var dateFrom = new Ext.form.DateField({ + id:'dateFrom', + format: 'Y-m-d', + width: 120, + value: '' + }); + + var dateTo = new Ext.form.DateField({ + id:'dateTo', + format: 'Y-m-d', + width: 120, + value: '' + }); + + var toolbarTodo = [ + { + xtype: 'tbsplit', + text: 'Actions', + menu: menuItems, + listeners: { menushow: enableDisableMenuOption } + }, + + '-', + btnRead, + '-', + btnUnread, + '-', + btnAll, + '->', // begin using the right-justified button container + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + var toolbarGeneral = [ + btnRead, + '-', + btnUnread, + '-', + btnAll, + '->', // begin using the right-justified button container + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + var toolbarUnassigned = [ + btnRead, + '-', + btnUnread, + '-', + btnAll, + '->', // begin using the right-justified button container + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + + + var toolbarDraft = [ + { + xtype: 'tbsplit', + text: 'Actions', + menu: menuItems, + listeners: { menushow: enableDisableMenuOption } + }, + '->', + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + var toolbarToRevise = [ + TRANSLATIONS.ID_PROCESS, + comboProcess, + '->', // begin using the right-justified button container + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + var toolbarToReassign = [ + 'user', + comboAllUsers, + '-', + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + btnSelectAll, + '-', + btnUnSelectAll, + '-', + btnReassign, + '->', + textSearch, + resetSearchButton, + btnSearch, + ' ', + ' ' + ]; + + var toolbarSent = [ + btnStarted, + '-', + btnCompleted, + '-', + btnAll, + '->', // begin using the right-justified button container + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + TRANSLATIONS.ID_STATUS, + comboStatus, + '-', + textSearch, + resetSearchButton, + btnSearch, + '-', + textJump, + btnJump, + ' ', + ' ' + ]; + + var toolbarSearch = [ + ' ', + TRANSLATIONS.ID_DELEGATE_DATE_FROM, + dateFrom, + ' ', + TRANSLATIONS.ID_TO, + dateTo, + new Ext.Button ({ + text: TRANSLATIONS.ID_FILTER_BY_DELEGATED_DATE, + handler: function(){ + storeCases.setBaseParam('dateFrom', dateFrom.getValue()); + storeCases.setBaseParam('dateTo', dateTo.getValue()); + storeCases.load({params:{ start : 0 , limit : pageSize }}); + } + }), + '-' + ]; + + var firstToolbarSearch = new Ext.Toolbar({ + region: 'north', + width: '100%', + autoHeight: true, + items: [ + ' ', + TRANSLATIONS.ID_PROCESS, + comboProcess, + '-', + TRANSLATIONS.ID_STATUS, + comboStatus, + '-', + TRANSLATIONS.ID_USER, + comboUser, + '->', + textSearch, + resetSearchButton, + btnSearch + ] + }); + //alert(action); + switch (action) { + case 'draft' : itemToolbar = toolbarDraft; break; + case 'sent' : itemToolbar = toolbarSent; break; + case 'to_revise' : itemToolbar = toolbarToRevise; break; + case 'to_reassign': itemToolbar = toolbarToReassign; break; + case 'search' : itemToolbar = toolbarSearch; break; + case 'unassigned' : itemToolbar = toolbarUnassigned; break; + case 'gral' : itemToolbar = toolbarGeneral; break; + default : itemToolbar = toolbarTodo; break; + } + + var tb = new Ext.Toolbar({ + height: 33, + items: itemToolbar + }); + + // create the editor grid + grid = new Ext.grid.GridPanel({ + region: 'center', + id: 'casesGrid', + store: storeCases, + cm: cm, + //autoHeight: true, + layout: 'fit', + viewConfig: { + forceFit:true + }, + listeners: { + rowdblclick: openCase, + render: function(){ + //this.loadMask = new Ext.LoadMask(this.body, {msg:TRANSLATIONS.LABEL_GRID_LOADING}); + //this.ownerCt.doLayout(); + } + }, + + tbar: tb, + // paging bar on the bottom + bbar: new Ext.PagingToolbar({ + pageSize: pageSize, + store: storeCases, + displayInfo: true, + //displayMsg: 'Displaying items {0} - {1} of {2} ' + '   ' , + displayMsg: TRANSLATIONS.LABEL_DISPLAY_ITEMS + '   ', + emptyMsg: TRANSLATIONS.LABEL_DISPLAY_EMPTY + }) + }); + + + grid.on('rowcontextmenu', function (grid, rowIndex, evt) { + var sm = grid.getSelectionModel(); + sm.selectRow(rowIndex, sm.isSelected(rowIndex)); + }, this); + grid.on('contextmenu', function (evt) { + evt.preventDefault(); + }, this); + + grid.addListener('rowcontextmenu', onMessageContextMenu,this); + + // patch in order to hide the USR_UIR and PREVIOUS_USR_UID columns + var userIndex = grid.getColumnModel().findColumnIndex('USR_UID'); + if ( userIndex >= 0 ) grid.getColumnModel().setHidden(userIndex, true); + var prevUserIndex = grid.getColumnModel().findColumnIndex('PREVIOUS_USR_UID'); + if ( prevUserIndex >= 0 ) grid.getColumnModel().setHidden(prevUserIndex, true); + + if (action=='to_reassign'){ + //grid.getColumnModel().setHidden(0, true); + grid.getColumnModel().setHidden(1, true); + } + + // create reusable renderer + + + // create the editor grid + var reassignGrid = new Ext.grid.EditorGridPanel({ + id : Ext.id(), + region: 'center', + store: storeReassignCases, + cm: reassignCm, + autoHeight: true, + viewConfig: { + forceFit:true + } +/* + listeners: { + rowdblclick: function(grid, n,e){ + var appUid = grid.store.data.items[n].data.APP_UID; + var delIndex = grid.store.data.items[n].data.DEL_INDEX; + var caseTitle = (grid.store.data.items[n].data.APP_TITLE) ? grid.store.data.items[n].data.APP_TITLE : grid.store.data.items[n].data.APP_UID; + //Ext.Msg.alert (TRANSLATIONS.LABEL_OPEN_CASE , caseTitle ); + Ext.Msg.show({ + msg: TRANSLATIONS.LABEL_OPEN_CASE + ' ' + caseTitle, + width:300, + wait:true, + waitConfig: {interval:200} + }); + window.location = '../cases/cases_Open?APP_UID=' + appUid + '&DEL_INDEX='+delIndex+'&content=inner'; + }, + render: function(){ + //this.loadMask = new Ext.LoadMask(this.body, {msg:TRANSLATIONS.LABEL_GRID_LOADING}); + //this.ownerCt.doLayout(); + } + }, + */ + //tbar: tb, + + }); + + +var gridForm = new Ext.FormPanel({ + id: 'reassign-form', + frame: true, + labelAlign: 'left', + //title: 'Company data', + bodyStyle:'padding:5px', + width: 750, + layout: 'column', // Specifies that the items will now be arranged in columns + items: [{ + id : 'tasksGrid', + columnWidth: 0.60, + layout: 'fit', + items: { + id: 'TasksToReassign', + xtype: 'grid', + ds: storeReassignCases, + cm: reassignCm, + sm: new Ext.grid.RowSelectionModel({ + singleSelect: true + /*listeners: { + rowselect: function(sm, row, rec) { + Ext.getCmp("reassign-form").getForm().loadRecord(rec); + } + }*/ + }), + //autoExpandColumn: 'company', + height: 350, + title : 'Cases to reassign - Task List', + border : true, + listeners: { + click: function() { + rows = this.getSelectionModel().getSelections(); + var application = ''; + if( rows.length > 0 ) { + var ids = ''; + for(i=0; i 0 ) { + ids = ''; + for(i=0; i
    +
    +
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/cases/casesStartPage.html b/workflow/engine/templates/cases/casesStartPage.html new file mode 100644 index 000000000..db98529e3 --- /dev/null +++ b/workflow/engine/templates/cases/casesStartPage.html @@ -0,0 +1,47 @@ + + +
    + + + + +
    + +
    + +
    +
    +
    diff --git a/workflow/engine/templates/cases/casesStartPage.js b/workflow/engine/templates/cases/casesStartPage.js new file mode 100644 index 000000000..11d107769 --- /dev/null +++ b/workflow/engine/templates/cases/casesStartPage.js @@ -0,0 +1,1278 @@ +//Ext.BLANK_IMAGE_URL = 'resources/s.gif'; + +var startCaseFilter; + +Ext.chart.Chart.CHART_URL = '/images/charts.swf'; +Ext.FlashComponent.EXPRESS_INSTALL_URL = '/images/expressinstall.swf'; + +var conn = new Ext.data.Connection(); + +var caseStatusByProcess = new Ext.data.JsonStore({ + fields : [ 'process', 'inbox', 'draft', 'unassigned' ], + root : 'caseStatusByProcess' +}); + +var caseDelayed = new Ext.data.JsonStore({ + fields : [ 'delayed', 'total' ], + root : 'caseDelayed' +}); + +function getDashboardData() { + + var parameters = { + action : 'getSimpleDashboardData' + }; + conn.request({ + url : 'casesStartPage_Ajax.php', + method : 'POST', + params : { + "action" : 'getSimpleDashboardData' + }, + success : function(responseObject) { + var responseData = Ext.decode(responseObject.responseText); + + // Load store from here + caseStatusByProcess.loadData(responseData); + caseDelayed.loadData(responseData); + }, + failure : function() { + Ext.Msg.alert('Status', 'Unable to get list of Process'); + } + }); +} + +function getOtherDashboards(dashboardTabPanels) { + conn.request({ + url : 'casesStartPage_Ajax.php', + method : 'POST', + params : { + "action" : 'getRegisteredDashboards' + }, + success : function(responseObject) { + + var response = Ext.util.JSON.decode(responseObject.responseText); + for ( var i = 0; i < response.length; i++) { + tabInfo = response[i]; + if (tabInfo.sName) { + dashboardTabPanels.add({ + title : tabInfo.sName, + id : tabInfo.sNamespace + "-" + tabInfo.sName, + iconCls : tabInfo.sIcon,// 'ICON_CASES_START_PAGE', + autoLoad : { + url : tabInfo.sPage, + scripts : true + } + // disabled:true, + }); + } + } + getDefaultDashboard(dashboardTabPanels); + }, + failure : function() { + // grid.getGridEl().unmask(true); + getDefaultDashboard(dashboardTabPanels); + Ext.Msg.alert('Status', 'Unable to get Dashboards'); + } + }); +} + +function getDashboardItems() { + dashboardItems = [ { + store : caseDelayed, + xtype : 'piechart', + dataField : 'total', + categoryField : 'delayed', + width : 250, + height : 250, + draggable : true, + disableCaching : true, + expressInstall : true, + // extra styles get applied to the chart defaults + extraStyle : { + legend : { + display : 'bottom', + padding : 5, + font : { + family : 'Tahoma', + size : 13 + } + } + } + + }, { + title : 'Status by Process', + xtype : 'columnchart', + store : caseStatusByProcess, + width : 450, + height : 400, + series : [ { + yField : 'inbox', + displayName : 'Inbox' + }, { + yField : 'draft', + displayName : 'Draft' + }, { + yField : 'unassigned', + displayName : 'Unassigned' + } ], + xField : 'process', + draggable : true, + xAxis : new Ext.chart.CategoryAxis({ + // title : 'Case Status', + labelRenderer : this.customFormat + }), + customFormat : function(value) { + return 'Year: '; + }, + yAxis : new Ext.chart.NumericAxis({ + title : 'Total' + }), + extraStyle : { + xAxis : { + labelRotation : -45 + }, + legend : { + display : 'right' + } + } + } ]; + getDashboardData(); + return dashboardItems; +} + +function getDefaultDashboard(dashboardTabPanels) { + defaultDashboard = "mainDashboard"; + dashboardTabPanels.setActiveTab(defaultDashboard); + Ext.getCmp("dashboardTabPanels").getEl() + .mask("Please wait, retrieving data...", + "ext-el-mask-msg x-mask-loading"); + + var parameters = { + action : 'getDefaultDashboard' + }; + conn.request({ + url : 'casesStartPage_Ajax.php', + method : 'POST', + params : { + "action" : 'getDefaultDashboard' + }, + success : function(responseObject) { + // showHistoryDialog(responseObject.responseText); + // grid.getGridEl().unmask(true); + // Ext.Msg.alert('Status', responseObject.responseText); + var responseData = Ext.decode(responseObject.responseText); + // console.log(responseData); + // console.log(responseData.defaultTab); + if (responseData.defaultTab) { + defaultDashboard = responseData.defaultTab; + } + if (dashboardTabPanels.getItem(defaultDashboard)) { + dashboardTabPanels.setActiveTab(defaultDashboard); + } + Ext.getCmp("dashboardTabPanels").getEl().unmask(); + + }, + failure : function() { + Ext.getCmp("dashboardTabPanels").getEl().unmask(); + // grid.getGridEl().unmask(true); + // Ext.Msg.alert('Status', 'Unable to get list of Process'); + } + }); + + // Get User Dashbaord Default if allowed + return defaultDashboard; +} + +Docs = {}; +// console.info("Doc Panel - Start"); + +DocPanel = Ext.extend(Ext.Panel, { + closable : true, + autoScroll : true, + + initComponent : function() { + // var ps = this.cclass.split('.'); + // this.title = ps[ps.length-1]; + Ext.apply(this, { + tbar : [ + '->', + { + text : 'Config Options', + handler : this.scrollToMember.createDelegate( + this, [ 'configs' ]), + iconCls : 'icon-config' + }, + '-', + { + text : 'Properties', + handler : this.scrollToMember.createDelegate( + this, [ 'props' ]), + iconCls : 'icon-prop' + }, + '-', + { + text : 'Methods', + handler : this.scrollToMember.createDelegate( + this, [ 'methods' ]), + iconCls : 'icon-method' + }, + '-', + { + text : 'Events', + handler : this.scrollToMember.createDelegate( + this, [ 'events' ]), + iconCls : 'icon-event' + }, + '-', + { + text : 'Direct Link', + handler : this.directLink, + scope : this, + iconCls : 'icon-fav' + }, + '-', + { + tooltip : 'Hide Inherited Members', + iconCls : 'icon-hide-inherited', + enableToggle : true, + scope : this, + toggleHandler : function(b, pressed) { + this.body[pressed ? 'addClass' + : 'removeClass']('hide-inherited'); + } + }, + '-', + { + tooltip : 'Expand All Members', + iconCls : 'icon-expand-members', + enableToggle : true, + scope : this, + toggleHandler : function(b, pressed) { + this.body[pressed ? 'addClass' + : 'removeClass']('full-details'); + } + } ] + }); + DocPanel.superclass.initComponent.call(this); + }, + + directLink : function() { + var link = String.format( + "{0}", + document.location.href + '?class=' + this.cclass); + Ext.Msg.alert('Direct Link to ' + this.cclass, link); + }, + + scrollToMember : function(member) { + var el = Ext.fly(this.cclass + '-' + member); + if (el) { + var top = (el.getOffsetsTo(this.body)[1]) + + this.body.dom.scrollTop; + this.body.scrollTo('top', top - 25, { + duration : 0.75, + callback : this.hlMember.createDelegate(this, + [ member ]) + }); + } + }, + + scrollToSection : function(id) { + var el = Ext.getDom(id); + if (el) { + var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + + this.body.dom.scrollTop; + this.body.scrollTo('top', top - 25, { + duration : 0.5, + callback : function() { + Ext.fly(el).next('h2').pause(0.2).highlight( + '#8DB2E3', { + attr : 'color' + }); + } + }); + } + }, + + hlMember : function(member) { + var el = Ext.fly(this.cclass + '-' + member); + if (el) { + if (tr = el.up('tr')) { + tr.highlight('#cadaf9'); + } + } + } +}); + + +var newCaseTree = { + xtype : 'treepanel', + id : 'processTree', + style : { + height : '100%', + overflow : 'auto' + }, + useArrows : true, + border : false, + split : true, + itemId : 'startCaseTreePanel', + id : 'startCaseTreePanel', + rootVisible : false, + treePanel : this, + clearOnReLoad : false, + loader : new Ext.tree.TreeLoader({ + preloadChildren : true, + dataUrl : 'casesStartPage_Ajax.php', + baseParams : { + action : 'getProcessList' + } + }), + listeners : { + dblclick : function(n) { + if (n.attributes.optionType == "startProcess") { + Ext.Msg.show({ + title : 'Start Case', + msg : 'Starting new case

    ' + + n.attributes.text + + '', + icon : Ext.MessageBox.INFO + }); + Ext.Ajax.request({ + url : 'casesStartPage_Ajax.php', + params : { + action : 'startCase', + processId : n.attributes.pro_uid, + taskId : n.attributes.tas_uid + }, + success : function(response) { + var res = Ext.util.JSON.decode(response.responseText); + if (res.openCase) { + window.location = res.openCase.PAGE; + } else { + Ext.Msg.show({ + title : 'Error creating a new Case', + msg : '', + icon : Ext.MessageBox.ERROR, + buttons : Ext.Msg.OK + }); + } + }, + failure : function() { + // grid.getGridEl().unmask(true); + Ext.Msg.alert('Error', 'Unable to start a case'); + } + }); + } + }, + click : function(n) { + mainPanel.showDetails(n); + } + }, + root : { + nodeType : 'async', + draggable : false, + id : 'root', + expanded : true + } +}; + +var startCaseTab = { + id : 'startCase', + title : 'Start Case', + iconCls : 'ICON_CASES_START_CASE', + layout : 'border', + items : [ + { + id : 'img-chooser-view', + region : 'center', + style : { + width : '50%' + + }, + // autoScroll: true, + items : [ newCaseTree ] + }, { + xtype:'form', + id : 'process-detail-panel', + region : 'east', + //autoHeight : true, + split : true, + style : { + width : '50%' + + }, + +// minWidth : 150, + frame: true, + labelAlign: 'right', + labelWidth: 85, + // width:340, + waitMsgTarget: true, + title:'Process Information', + layout:'form', + defaults: {width: 350}, + defaultType: 'textfield', + + + items: [{ + fieldLabel: 'Process', + name: 'processName', + allowBlank:false, + value: '', + disabled: true, + //readonly:true, + id:"processName" + },{ + fieldLabel: 'Task', + name: 'taskName', + allowBlank:false, + value: '', + disabled: true, + id:"taskName" + },{ + xtype:'textarea', + fieldLabel: 'Description', + name: 'processDescription', + value: '', + disabled: true, + id:"processDescription" + },{ + fieldLabel: 'Category', + name: 'processCategory', + value: '', + disabled: true, + id:"processCategory" + }, { + fieldLabel: 'Calendar', + name: 'calendarName', + disabled: true, + id:"calendarName" + },{ + xtype:'textarea', + fieldLabel: 'Calendar Description', + name: 'calendarDescription', + value: '', + disabled: true, + id:"calendarDescription" + },{ + xtype:'checkboxgroup', + fieldLabel: 'Working days', + name: 'calendarWorkDays', + disabled: true, + id:"calendarWorkDays", + columns: 7, + items: [ + {boxLabel: 'Sun', name: '0'}, + {boxLabel: 'Mon', name: '1'}, + {boxLabel: 'Tue', name: '2'}, + {boxLabel: 'Wen', name: '3'}, + {boxLabel: 'Thu', name: '4'}, + {boxLabel: 'Fri', name: '5'}, + {boxLabel: 'Sat', name: '6'} + ] + + }, { + xtype:'checkbox', + fieldLabel: 'Debug Mode', + name: 'debugMode', + disabled: true, + id:"debugMode" + }] + } + ], + + tbar : [ + { + xtype : 'textfield', + name : 'processesFilter', + id: 'processesFilter', + emptyText : 'Find a Process', + enableKeyEvents : true, + listeners : { + render : function(f) { + /*Ext.getCmp("startCaseTreePanel").filter = new Ext.tree.TreeFilter( + this, + { + clearBlank : true, + autoClear : true + } + );*/ + + startCaseFilter = new Ext.ux.tree.TreeFilterX(Ext.getCmp('startCaseTreePanel')); + }, /* + keydown : function(t, e) { + treeFiltered = Ext.getCmp("startCaseTreePanel"); + //console.log(treeFiltered); + + var text = t.getValue(); + + //console.log(text); + if (!text) { + treeFiltered.filter.clear(); + return; + } + treeFiltered.expandAll(); + + var re = new RegExp('^'+ Ext.escapeRe(text), 'i'); + console.log(re); + treeFiltered.filter.filterBy(function(n) { + return !n.attributes.isClass || re.test(n.text); + }); + },*/ + specialkey: function(f,e){ + if (e.getKey() == e.ENTER) { + txt = Ext.getCmp('processesFilter').getValue(); + startCaseFilter.clear(); + var re = new RegExp('.*' + txt + '.*', 'i'); + startCaseFilter.filter(re, 'text'); + } + }, + scope : this + } + }, + { + text:'X', + ctCls:'pm_search_x_button', + handler: function(){ + Ext.getCmp('processesFilter').setValue(''); + startCaseFilter.clear(); + } + }, + ' ', + ' ', + { + iconCls : 'icon-expand-all', + tooltip : 'Expand All', + handler : function() { + Ext.getCmp("startCaseTreePanel").root.expand(true); + }, + scope : this + }, + '-', + { + iconCls : 'icon-collapse-all', + tooltip : 'Collapse All', + handler : function() { + Ext.getCmp("startCaseTreePanel").root.collapse(true); + }, + scope : this + }, + ' ', + ' ', + { + xtype : 'tbbutton', + cls : 'x-btn-icon', + icon : '/images/refresh.gif', + + handler : function() { + tree = Ext + .getCmp('startCaseTreePanel'); + tree.getLoader().load( + tree.root); + } + } + ] +}; + +var documentsTab = { + id : 'documents', + title : 'Documents', + iconCls : 'ICON_FOLDERS', + layout : 'border', + items : [ { + id : 'documentsView', + region : 'center', + // autoScroll: true, + items : [ { + xtype : 'treepanel', + id : 'documentsTree', + style : { + // width: '50%', + height : '100%', + overflow : 'auto' + }, + useArrows : true, + border : false, + split : true, + itemId : 'documentsTreePanel', + id : 'documentsTreePanel', + rootVisible : true, + treePanel : this, + clearOnReLoad : false, + loader : new Ext.tree.TreeLoader( + { + dataUrl : '../appFolder/appFolderAjax.php', + baseParams : { + action : 'expandNode' + } + } + ), + listeners : { + dblclick : function(n) { + if (n.attributes.optionType == "startProcess") { + Ext.Msg.show({ + title : 'Start Case', + msg : 'Starting new case

    ' + + n.attributes.text + + '', + icon : Ext.MessageBox.INFO + }); + Ext.Ajax.request({ + url : 'casesStartPage_Ajax.php', + params : { + action : 'startCase', + processId : n.attributes.pro_uid, + taskId : n.attributes.tas_uid + }, + success : function( + response) { + var res = Ext.util.JSON + .decode(response.responseText); + if (res.openCase) { + window.location = res.openCase.PAGE; + } else { + Ext.Msg.show({ + title : 'Error creating a new Case', + msg : '', + icon : Ext.MessageBox.ERROR, + buttons : Ext.Msg.OK + }); + } + }, + failure : function() { + // grid.getGridEl().unmask(true); + Ext.Msg.alert('Error', 'Unable to start a case'); + } + }); + } + }, + click : function(n) { + mainPanel.showDetails(n); + } + }, + root : { + nodeType : 'async', + draggable : false, + id : 'root', + expanded : true + } + } ] + // items + } ], + + tbar : [ + { + xtype : 'textfield', + name : 'field1', + emptyText : 'Filter', + enableKeyEvents : true, + listeners : { + render : function(f) { + Ext.getCmp("documentsTreePanel").filter = new Ext.tree.TreeFilter( + this, + { + clearBlank : true, + autoClear : true + } + ); + }, + keydown : function(t, e) { + treeFiltered = Ext.getCmp("documentsTreePanel"); + var text = t.getValue(); + if (!text) { + treeFiltered.filter + .clear(); + return; + } + treeFiltered + .expandAll(); + + var re = new RegExp( + '^' + + Ext + .escapeRe(text), + 'i'); + treeFiltered.filter + .filterBy(function( + n) { + // return + // !n.attributes.isClass + // || + // re.test(n.text); + }); + /* + * // hide empty + * packages that weren't + * filtered + * this.hiddenPkgs = []; + * var me = this; + * this.root.cascade(function(n){ + * if(!n.attributes.isClass && + * n.ui.ctNode.offsetHeight < + * 3){ n.ui.hide(); + * me.hiddenPkgs.push(n); } + * }); + */ + }, + scope : this + } + }, + ' ', + ' ', + { + iconCls : 'icon-expand-all', + tooltip : 'Expand All', + handler : function() { + Ext + .getCmp("documentsTreePanel").root + .expand(true); + }, + scope : this + }, + '-', + { + iconCls : 'icon-collapse-all', + tooltip : 'Collapse All', + handler : function() { + Ext + .getCmp("documentsTreePanel").root + .collapse(true); + }, + scope : this + }, + ' ', + ' ', + { + xtype : 'tbbutton', + cls : 'x-btn-icon', + icon : '/images/refresh.gif', + + handler : function() { + tree = Ext + .getCmp('documentsTreePanel'); + tree.getLoader().load( + tree.root); + } + } + ] +}; +/* +var dashboardTab = { + title : 'Dashboard', + id : 'mainDashboard', + iconCls : 'ICON_CASES_START_PAGE', + xtype : 'container', + autoHeight : true, + enableDD : false, + items : getDashboardItems() +}; +*/ +var MainPanel = function() { + MainPanel.superclass.constructor.call(this, { + id : 'doc-body', + region : 'center', + resizeTabs : true, + minTabWidth : 135, + tabWidth : 135, + plugins : new Ext.ux.TabCloseMenu(), + enableTabScroll : true, + activeTab : 0, + items : [startCaseTab/*, documentsTab, dashboardTab*/] + }); +}; + +// console.info("Main Panel - End"); +Ext.extend( + MainPanel, + Ext.TabPanel, + { + initEvents : function() { + MainPanel.superclass.initEvents.call(this); + // this.body.on('click', this.onClick, this); + + }, + + onClick : function(e, target, elementselected) { + return; + if (target = e.getTarget('a:not(.exi)', 3)) { + var cls = Ext.fly(target).getAttributeNS('ext', + 'cls'); + e.stopEvent(); + if (cls) { + var member = Ext.fly(target).getAttributeNS( + 'ext', 'member'); + this.loadClass(target.href, cls, member); + } else if (target.className == 'inner-link') { + this.getActiveTab().scrollToSection( + target.href.split('#')[1]); + } else { + window.open(target.href); + } + } else if (target = e.getTarget('.micon', 2)) { + e.stopEvent(); + var tr = Ext.fly(target.parentNode); + if (tr.hasClass('expandable')) { + tr.toggleClass('expanded'); + } + } + }, + + loadClass : function(href, cls, member) { + var id = 'docs-' + cls; + var tab = this.getComponent(id); + if (tab) { + this.setActiveTab(tab); + if (member) { + tab.scrollToMember(member); + } + } else { + var autoLoad = { + url : href + }; + if (member) { + autoLoad.callback = function() { + Ext.getCmp(id).scrollToMember(member); + }; + } + var p = this.add(new DocPanel({ + id : id, + cclass : cls, + autoLoad : autoLoad + })); + this.setActiveTab(p); + } + }, + + initTemplates : function() { + + this.detailsTemplate = new Ext.XTemplate( + '
    ', + '', + '', + '
    ', + + '', + '

    {taskName}


    ', + 'Process Name:', + '{processName}', + 'Description: ', + '{processDescription}', + '', + '', + '', + '', + '', + '', + '
    ', + 'Category: ', + + '{processCategory}', + + '', + 'Calendar: ', + '{calendarName} ({calendarDescription})', + '', + 'Working Days: ', + '{calendarWorkDays}', + '', + 'Debug mode: ', + '{processDebug}', + '
    ', + 'Statistics: ', + 'Active Cases (Mine/Total):{myInbox} / {totalInbox}', + + '
    Double click to start any Process/Case', + '', + + '', '
    '); + this.detailsTemplate.compile(); + }, + + showDetails : function(selectedNode) { + + // console.log(selectedNode); + var detailEl = Ext.getCmp('process-detail-panel').body; + if (selectedNode) { + + //this.initTemplates(); + //detailEl.hide(); + // detailEl.sequenceFx(); + // detailEl.slideOut('l', + // {stopFx:true,duration:.9}); + + + + otherAttributes = selectedNode.attributes.otherAttributes; + + + + Ext.getCmp('process-detail-panel').getForm().setValues({ + processName : otherAttributes.PRO_TITLE, + taskName : selectedNode.attributes.text, + calendarName : otherAttributes.CALENDAR_NAME, + calendarDescription : otherAttributes.CALENDAR_DESCRIPTION, + processCalendar:otherAttributes.CALENDAR_NAME+" "+otherAttributes.CALENDAR_DESCRIPTION, + calendarWorkDays : (otherAttributes.CALENDAR_WORK_DAYS).split("|"), + processCategory : otherAttributes.PRO_CATEGORY_LABEL, + processDebug : otherAttributes.PRO_DEBUG, + processDescription : otherAttributes.PRO_DESCRIPTION, + myInbox : otherAttributes.myInbox, + totalInbox : otherAttributes.totalInbox + + }); + + + + + + //this.detailsTemplate.overwrite(detailEl, data); + //detailEl.slideIn('t', {stopFx:true,duration:.0}); + //detailEl.highlight('#000', { + // block : true + //}); + } else { + detailEl.update(''); + } + + return; + // var selNode = this.getSelectedNodes(); + + }, + /* + * startNewCase:function(){ alert("asdasdasd"); }, + */ + loadOtherDashboards : function() { + // console.info("Getting other Dashboards"); + dashboardTabPanels = this; + // console.log(dashboardTabPanels); + conn.request({ + url : 'casesStartPage_Ajax.php', + method : 'POST', + params : { + "action" : 'getRegisteredDashboards' + }, + success : function(responseObject) { + + var response = Ext.util.JSON + .decode(responseObject.responseText); + for ( var i = 0; i < response.length; i++) { + tabInfo = response[i]; + if (tabInfo.sName) { + dashboardTabPanels.add({ + title : tabInfo.sName, + id : tabInfo.sNamespace + "-" + + tabInfo.sName, + iconCls : tabInfo.sIcon,// 'ICON_CASES_START_PAGE', + autoLoad : { + url : tabInfo.sPage, + scripts : true + } + // disabled:true, + }); + } + } + // getDefaultDashboard(dashboardTabPanels); + dashboardTabPanels.activateDefaultTab(); + }, + failure : function() { + // grid.getGridEl().unmask(true); + // getDefaultDashboard(dashboardTabPanels); + dashboardTabPanels.activateDefaultTab(); + Ext.Msg.alert('Status', + 'Unable to get Dashboards'); + } + }); + }, + activateDefaultTab : function() { + // api.expandPath('/root/apidocs'); + // allow for link in + var page = window.location.href.split('?')[1]; + // console.info("page : "+page); + if (page) { + var ps = Ext.urlDecode(page); + // console.log(ps.action); + if (ps.action) { + defaultDashboard = ps.action; + if (this.getItem(defaultDashboard)) { + // console.info("Setting the new default + // dashboard: + // "+defaultDashboard); + this.setActiveTab(defaultDashboard); + } + + } + // var cls = ps['class']; + // mainPanel.loadClass('output/' + cls + '.html', + // cls, ps.member); + } + } + + }); + +var mainPanel = new MainPanel(); + +Ext.onReady(function() { + var Cookies = {}; + Cookies.set = function(name, value) { + var argv = arguments; + var argc = arguments.length; + var expires = (argc > 2) ? argv[2] : null; + var path = (argc > 3) ? argv[3] : '/'; + var domain = (argc > 4) ? argv[4] : null; + var secure = (argc > 5) ? argv[5] : false; + document.cookie = name + + "=" + + escape(value) + + ((expires == null) ? "" : ("; expires=" + expires + .toGMTString())) + + ((path == null) ? "" : ("; path=" + path)) + + ((domain == null) ? "" : ("; domain=" + domain)) + + ((secure == true) ? "; secure" : ""); + }; + + Cookies.get = function(name) { + var arg = name + "="; + var alen = arg.length; + var clen = document.cookie.length; + var i = 0; + var j = 0; + while (i < clen) { + j = i + alen; + if (document.cookie.substring(i, j) == arg) + return Cookies.getCookieVal(j); + i = document.cookie.indexOf(" ", i) + 1; + if (i == 0) + break; + } + return null; + }; + + Cookies.clear = function(name) { + if (Cookies.get(name)) { + document.cookie = name + "=" + + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; + } + }; + + Cookies.getCookieVal = function(offset) { + var endstr = document.cookie.indexOf(";", offset); + if (endstr == -1) { + endstr = document.cookie.length; + } + return unescape(document.cookie.substring(offset, endstr)); + }; + + // function that loads store when it is called + function getDashboardData() { + var parameters = { + action : 'getSimpleDashboardData' + }; + conn.request({ + url : 'casesStartPage_Ajax.php', + method : 'POST', + params : { + "action" : 'getSimpleDashboardData' + }, + success : function(responseObject) { + var responseData = Ext.decode(responseObject.responseText); + + // Load store from here + caseStatusByProcess.loadData(responseData); + caseDelayed.loadData(responseData); + }, + failure : function() { + Ext.Msg.alert('Status', 'Unable to get list of Process'); + } + }); + } + + Ext.QuickTips.init(); + + mainPanel.on('tabchange', function(tp, tab) { + if (tab.getUpdater) { + var thisObj = tab.getUpdater(); + if (thisObj) { + thisObj.refresh(); + } + } + }); + + var viewport = new Ext.Viewport({ + layout : 'border', + items : [ + /* + * { // cls: 'docs-header', // height: 36, region:'north', xtype:'box', + * el:'header', border:false// , // margins: '0 0 5 0' }, + */ + mainPanel ] + }); + + mainPanel.loadOtherDashboards(); + + // console.info("viewport -end"); + + viewport.doLayout(); + + + //routine to hide the debug panel if it is open + if( parent.PANEL_EAST_OPEN ){ + parent.PANEL_EAST_OPEN = false; + var debugPanel = parent.Ext.getCmp('debugPanel'); + debugPanel.hide(); + debugPanel.ownerCt.doLayout(); + } + +}); + + + + + + +// vim: ts=4:sw=4:nu:fdc=4:nospell +/*global Ext */ +/** + * @class Ext.ux.tree.TreeFilterX + * @extends Ext.tree.TreeFilter + * + *

    + * Shows also parents of matching nodes as opposed to default TreeFilter. In other words + * this filter works "deep way". + *

    + * + * @author Ing. Jozef Sakáloš + * @version 1.0 + * @date 17. December 2008 + * @revision $Id: Ext.ux.tree.TreeFilterX.js 589 2009-02-21 23:30:18Z jozo $ + * @see http://extjs.com/forum/showthread.php?p=252709 + * + * @license Ext.ux.tree.CheckTreePanel is licensed under the terms of + * the Open Source LGPL 3.0 license. Commercial use is permitted to the extent + * that the code/component(s) do NOT become part of another Open Source or Commercially + * licensed development library or toolkit without explicit permission. + * + *

    License details: http://www.gnu.org/licenses/lgpl.html

    + * + * @forum 55489 + * @demo http://remotetree.extjs.eu + * + * @donate + *
    + * + * + * + * + *
    + */ + +Ext.ns('Ext.ux.tree'); + +/** + * Creates new TreeFilterX + * @constructor + * @param {Ext.tree.TreePanel} tree The tree panel to attach this filter to + * @param {Object} config A config object of this filter + */ +Ext.ux.tree.TreeFilterX = Ext.extend(Ext.tree.TreeFilter, { + /** + * @cfg {Boolean} expandOnFilter Deeply expands startNode before filtering (defaults to true) + */ + expandOnFilter:true + + // {{{ + /** + * Filter the data by a specific attribute. + * + * @param {String/RegExp} value Either string that the attribute value + * should start with or a RegExp to test against the attribute + * @param {String} attr (optional) The attribute passed in your node's attributes collection. Defaults to "text". + * @param {TreeNode} startNode (optional) The node to start the filter at. + */ + ,filter:function(value, attr, startNode) { + + // expand start node + if(false !== this.expandOnFilter) { + startNode = startNode || this.tree.root; + var animate = this.tree.animate; + this.tree.animate = false; + startNode.expand(true, false, function() { + + // call parent after expand + Ext.ux.tree.TreeFilterX.superclass.filter.call(this, value, attr, startNode); + + }.createDelegate(this)); + this.tree.animate = animate; + } + else { + // call parent + Ext.ux.tree.TreeFilterX.superclass.filter.apply(this, arguments); + } + + } // eo function filter + // }}} + // {{{ + /** + * Filter by a function. The passed function will be called with each + * node in the tree (or from the startNode). If the function returns true, the node is kept + * otherwise it is filtered. If a node is filtered, its children are also filtered. + * Shows parents of matching nodes. + * + * @param {Function} fn The filter function + * @param {Object} scope (optional) The scope of the function (defaults to the current node) + */ + ,filterBy:function(fn, scope, startNode) { + startNode = startNode || this.tree.root; + if(this.autoClear) { + this.clear(); + } + var af = this.filtered, rv = this.reverse; + + var f = function(n) { + if(n === startNode) { + return true; + } + if(af[n.id]) { + return false; + } + var m = fn.call(scope || n, n); + if(!m || rv) { + af[n.id] = n; + n.ui.hide(); + return true; + } + else { + n.ui.show(); + var p = n.parentNode; + while(p && p !== this.root) { + p.ui.show(); + p = p.parentNode; + } + return true; + } + return true; + }; + startNode.cascade(f); + + if(this.remove){ + for(var id in af) { + if(typeof id != "function") { + var n = af[id]; + if(n && n.parentNode) { + n.parentNode.removeChild(n); + } + } + } + } + } // eo function filterBy + // }}} + +}); // eo extend + +// eof + + diff --git a/workflow/engine/templates/cases/casesToRevisePanel.html b/workflow/engine/templates/cases/casesToRevisePanel.html new file mode 100644 index 000000000..603321bec --- /dev/null +++ b/workflow/engine/templates/cases/casesToRevisePanel.html @@ -0,0 +1,2 @@ +
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/cases/casesToRevisePanel.js b/workflow/engine/templates/cases/casesToRevisePanel.js new file mode 100644 index 000000000..ed739b915 --- /dev/null +++ b/workflow/engine/templates/cases/casesToRevisePanel.js @@ -0,0 +1,42 @@ +clickListener = function (node,event){ + if (node.attributes.href){ + parent.location.href = node.attributes.href; +// Ext.get('casesSubFrame').src=node.attributes.href; + } +}; + +Ext.onReady(function() { + +var tree = new Ext.tree.TreePanel({ + renderTo: Ext.getBody(), + title: treeTitle, + width: 250, + height: 250, + userArrows: true, + animate: true, + autoScroll: true, + rootVisible: false, +// dataUrl: 'casesToReviseTreeContent?APP_UID=4425000044ce3eda54f6d41019986116&DEL_INDEX=3', + dataUrl: casesPanelUrl, + root: { + nodeType : 'async', + text : 'To Revise', + id : 'node-root' + }, + listeners: { + render: function() { +// this.getRootNode().expand(); + this.expandAll(); +// this.getNodeById('node-dynaforms').expand(); +// this.getNodeById('node-input-documents').expand(); + }, + click: { + fn:clickListener + } + } +}) + tree.render(); +// tree.expandAll(); +// tree.getNodeById('node-dynaforms').expand(); +// tree.getNodeById('node-input-documents').expand(); +}); \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_ActionsTree.php b/workflow/engine/templates/cases/cases_ActionsTree.php new file mode 100644 index 000000000..10af45a16 --- /dev/null +++ b/workflow/engine/templates/cases/cases_ActionsTree.php @@ -0,0 +1,103 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +require_once 'classes/model/AppThread.php'; +require_once 'classes/model/AppDelay.php'; +G::LoadClass('tree'); +G::LoadClass('case'); + +$APP_UID = $_SESSION['APPLICATION']; + +$c = new Criteria('workflow'); +$c->clearSelectColumns(); +$c->addSelectColumn( AppThreadPeer::APP_THREAD_PARENT ); +$c->add(AppThreadPeer::APP_UID, $APP_UID ); +$c->add(AppThreadPeer::APP_THREAD_STATUS , 'OPEN' ); +$cant = AppThreadPeer::doCount($c); + +$oTree = new Tree(); +$oTree->nodeType = "blank"; +$oTree->name = 'Actions'; +$oTree->showSign = false; + +$oCase = new Cases(); +$aFields = $oCase->loadCase( $_SESSION['APPLICATION'], $_SESSION['INDEX'] ); + +$oCriteria = new Criteria('workflow'); +$oCriteria->add(AppDelayPeer::APP_UID, $_SESSION['APPLICATION']); +$oCriteria->add(AppDelayPeer::APP_DEL_INDEX, $_SESSION['INDEX']); +$oCriteria->add(AppDelayPeer::APP_TYPE, 'PAUSE'); +$oCriteria->add(AppDelayPeer::APP_DISABLE_ACTION_USER, null); + +$oDataset = AppDelayPeer::doSelectRS($oCriteria); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$aRow = $oDataset->getRow(); +GLOBAL $RBAC; +switch($aFields['APP_STATUS']) +{ + case 'DRAFT': + if(!$aRow) { + $oNode = &$oTree->addChild('1', '' . G::LoadTranslation('ID_PAUSED_CASE') . '', array('nodeType' => 'parentBlue')); + } + else { + $oNode = &$oTree->addChild('1', '' . G::LoadTranslation('ID_UNPAUSE') . '', array('nodeType' => 'parentBlue')); + } + $oNode = &$oTree->addChild('2', '' . G::LoadTranslation('ID_DELETE') . '', array('nodeType' => 'parentBlue')); + if($RBAC->userCanAccess('PM_REASSIGNCASE')==1) { + $oNode = &$oTree->addChild('3', '' . G::LoadTranslation('ID_REASSIGN') . '', array('nodeType' => 'parentBlue')); + } + break; + case 'TO_DO': + if(!$aRow) { + $oNode = &$oTree->addChild('1', '' . G::LoadTranslation('ID_PAUSED_CASE') . '', array('nodeType' => 'parentBlue')); + if ($cant == 1) { + $oNode = & $oTree->addChild('2', '' . G::LoadTranslation('ID_CANCEL') . '', array('nodeType'=>'parentBlue')); + } + } + else { + $oNode = &$oTree->addChild('1', '' . G::LoadTranslation('ID_UNPAUSE') . '', array('nodeType' => 'parentBlue')); + } + if($RBAC->userCanAccess('PM_REASSIGNCASE')==1) { + $oNode = &$oTree->addChild('3', '' . G::LoadTranslation('ID_REASSIGN') . '', array('nodeType' => 'parentBlue')); + } + break; + + case 'CANCELLED': + $oNode = &$oTree->addChild('1', '' . G::LoadTranslation('ID_REACTIVATE') . '', array('nodeType' => 'parentBlue')); + break; +} + +$oTask = new Task(); +$aTask = $oTask->load($_SESSION['TASK']); +if ($aTask['TAS_TYPE'] == 'ADHOC') { + $oNode = &$oTree->addChild('4', '' . G::LoadTranslation('ID_ADHOC_ASSIGNMENT') . '', array('nodeType' => 'parentBlue')); +} + +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +echo $oTree->render(); +?> diff --git a/workflow/engine/templates/cases/cases_DynaformHistory.html b/workflow/engine/templates/cases/cases_DynaformHistory.html new file mode 100644 index 000000000..4b9364976 --- /dev/null +++ b/workflow/engine/templates/cases/cases_DynaformHistory.html @@ -0,0 +1,116 @@ + + + + +
    +
    +
    +
    +
    +
    + {noResults} +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    + + + + +
    + + + + + + + + + +
    {dynTitle}{dynDate}{dynUser}
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_DynaformHistory.php b/workflow/engine/templates/cases/cases_DynaformHistory.php new file mode 100644 index 000000000..eed7f4033 --- /dev/null +++ b/workflow/engine/templates/cases/cases_DynaformHistory.php @@ -0,0 +1,167 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +$tpl = new TemplatePower( PATH_TPL . 'cases/cases_DynaformHistory.html' ); + +$tpl->prepare(); + +G::LoadClass('case'); +$oCase = new Cases(); +$Fields = $oCase->loadCase($_SESSION['APPLICATION']); + +$historyData=array(); +$historyDataAux=array(); +require_once 'classes/model/AppHistory.php'; +$appHistory = new AppHistory(); +$c=$appHistory->getDynaformHistory($_REQUEST['PRO_UID'],$_REQUEST['TAS_UID'],$_REQUEST['APP_UID'],$_REQUEST['DYN_UID']); + +$oDataset = ArrayBasePeer::doSelectRs ( $c); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); + +$changeCount=0; +while ($aRow = $oDataset->getRow()) { + $changeCount++; + + $changedValues=unserialize($aRow['HISTORY_DATA']); + $tableName="_TCHANGE_".$changeCount; + $historyDataAux[$tableName]=$changedValues; + $oDataset->next(); +} + +$historyData=array_reverse($historyDataAux); +$changeCount=count($historyData); +foreach($historyData as $key => $value){ + $tableName="_TCHANGE_".$changeCount; + $changeCountA=$changeCount+1; + $tableNameA="_TCHANGE_".$changeCountA; + + if(isset($historyData[$tableNameA])){ + //$historyData[$key]=array_merge($historyData[$tableNameA],$value); + //Array merge recursive doesn't work. So here is an own procedure + $historyData[$key]=$historyData[$tableNameA]; + foreach($value as $key1 => $value2){ + if(!is_array($value2)){ + $historyData[$key][$key1]=$value2; + }else{ + foreach($value2 as $key3 => $value3){ + if(is_array($value3)){ + foreach($value3 as $key4 => $value4){ + $historyData[$key][$key1][$key3][$key4]=$value4; + } + } + } + } + + } + } + + + $changeCount--; +} + + + + +$oDataset = ArrayBasePeer::doSelectRs ( $c); +$oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); +$oDataset->next(); +$changeCount=0; + +while ($aRow = $oDataset->getRow()) { + $changeCount++; + + + $changedValues=unserialize($aRow['HISTORY_DATA']); + + $tpl->newBlock( "DYNLOG" ); + $tableName="_TCHANGE_".$changeCount; + $changeCountA=$changeCount+1; + $tableNameA="_TCHANGE_".$changeCountA; + + $tpl->assign( "dynTitle" , $aRow['DYN_TITLE'] ); + $tpl->assign( "dynDate" , $aRow['HISTORY_DATE'] ); + $tpl->assign( "dynUser" , $aRow['USR_NAME'] ); + $tpl->assign( "changes" , G::LoadTranslation("ID_CHANGES") ); + $tpl->assign( "dynUID" , $aRow['DYN_UID'] ); + $tpl->assign( "tablename" , $tableName ); + + + $tpl->assign( "viewForm" , G::LoadTranslation("ID_VIEW") ); + $tpl->assign( "dynaform" , G::LoadTranslation("ID_DYNAFORM") ); + $tpl->assign( "date" , G::LoadTranslation("ID_DATE") ); + $tpl->assign( "user" , G::LoadTranslation("ID_USER") ); + + $tpl->assign( "fieldNameLabel" , G::LoadTranslation("ID_FIELD_NAME") ); + $tpl->assign( "previousValuesLabel" , G::LoadTranslation("ID_PREV_VALUES") ); + $tpl->assign( "currentValuesLabel" , G::LoadTranslation("ID_CURRENT_VALUES") ); + + + + + $count=0; + foreach($changedValues as $key =>$value){ + if(($value!=NULL)&&(!is_array($value))){ + + $tpl->newBlock( "FIELDLOG" ); + $tpl->assign( "fieldName" , $key ); + $tpl->assign( "previous" , isset($historyData[$tableNameA][$key])?$historyData[$tableNameA][$key]:"" ); + $tpl->assign( "actual" , $value ); + $count++; + } + if(is_array($value)){ + foreach($value as $key1 =>$value1){ + if(is_array($value1)){ + foreach($value1 as $key2 =>$value2){ + $name=$key."[".$key1."]"."[".$key2."]"; + $tpl->newBlock( "FIELDLOG" ); + $tpl->assign( "fieldName" , $name ); + $tpl->assign( "previous" , isset($historyData[$tableNameA][$key][$key1][$key2])?$historyData[$tableNameA][$key][$key1][$key2]:"" ); + $tpl->assign( "actual" , $value2 ); + $count++; + } + } + } + } + } + $tpl->gotoBlock( "DYNLOG" ); + + $tpl->assign( "dynChanges" , G::LoadTranslation("ID_FIELDS_CHANGED_NUMBER")." (".$count.")" ); + $tpl->assign( "count" , $count+1 ); + + $oDataset->next(); + +} +if(!isset($changedValues)){ + $tpl->newBlock( "NORESULTS" ); + $tpl->assign( "noResults" , G::LoadTranslation("ID_NO_RECORDS_FOUND")); +} + + $_SESSION['HISTORY_DATA']=serialize($historyData); + $tpl->gotoBlock( "_ROOT" ); + + $tpl->printToScreen(); + +?> \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_InformationTree.php b/workflow/engine/templates/cases/cases_InformationTree.php new file mode 100644 index 000000000..43620f224 --- /dev/null +++ b/workflow/engine/templates/cases/cases_InformationTree.php @@ -0,0 +1,91 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadClass('tree'); +$oTree = new Tree(); +$oTree->nodeType ="blank"; +$oTree->name = 'Information'; +$oTree->showSign = false; + +$oNode =& $oTree->addChild('1', '' . G::LoadTranslation('ID_PROCESS_MAP') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +$oNode =& $oTree->addChild('2', '' . G::LoadTranslation('ID_PROCESS_INFORMATION') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +if ($_SESSION['TASK'] != -1) { + $oNode =& $oTree->addChild('3', '' . G::LoadTranslation('ID_TASK_INFORMATION') . '', array('nodeType'=>'parentBlue')); + $oNode->plus = ''; + $oNode->minus = ''; + $oNode->point = ''; +} + +$oNode =& $oTree->addChild('4', '' . G::LoadTranslation('ID_CASE_HISTORY') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +$oNode =& $oTree->addChild('6', '' . G::LoadTranslation('ID_HISTORY_MESSAGE_CASE') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +$oNode =& $oTree->addChild('6', '' . G::LoadTranslation('ID_DYNAFORMS') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +$oNode =& $oTree->addChild('5', '' . G::LoadTranslation('ID_UPLOADED_DOCUMENTS') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; + +$oNode =& $oTree->addChild('6', '' . G::LoadTranslation('ID_GENERATED_DOCUMENTS') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; +/* +$oNode =& $oTree->addChild('6', '' . G::LoadTranslation('ID_STAGES') . '', array('nodeType'=>'parentBlue')); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = ''; +*/ +/* +require_once 'classes/model/Process.php'; +$oProcess = new Process(); +$Fields = $oProcess->Load( $_SESSION['PROCESS'] ); +if($Fields['PRO_DEBUG']==1) +{ + $oNode =& $oTree->addChild('7', '' . G::LoadTranslation('ID_CASEDEMO') . '', array('nodeType'=>'parentBlue')); + $oNode->plus = ''; + $oNode->minus = ''; + $oNode->point = ''; +} +*/ +echo $oTree->render(); +?> diff --git a/workflow/engine/templates/cases/cases_KTTree.php b/workflow/engine/templates/cases/cases_KTTree.php new file mode 100644 index 000000000..ee011a4a3 --- /dev/null +++ b/workflow/engine/templates/cases/cases_KTTree.php @@ -0,0 +1,36 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +G::LoadClass('tree'); +$oTree = new Tree(); +$oTree->name = 'KT'; +$oTree->showSign = false; + +/*$oNode =& $oTree->addChild('1', '' . G::LoadTranslation('ID_PROCESS_INFORMATION') . ''); +$oNode->plus = ''; +$oNode->minus = ''; +$oNode->point = '';*/ + +echo $oTree->render(); +?> \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_Leyends.html b/workflow/engine/templates/cases/cases_Leyends.html new file mode 100644 index 000000000..463bec559 --- /dev/null +++ b/workflow/engine/templates/cases/cases_Leyends.html @@ -0,0 +1,8 @@ +
    + + + + + +
    {$sLabel1}
    {$sLabel2}
    {$sLabel3}
    {$sLabel4}
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_Load.php b/workflow/engine/templates/cases/cases_Load.php new file mode 100755 index 000000000..f682ee8a9 --- /dev/null +++ b/workflow/engine/templates/cases/cases_Load.php @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_NewCategory.html b/workflow/engine/templates/cases/cases_NewCategory.html new file mode 100755 index 000000000..b445ce2e0 --- /dev/null +++ b/workflow/engine/templates/cases/cases_NewCategory.html @@ -0,0 +1,77 @@ + + + + + + + krlos + + + + + + + +
    + + + + + + +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + +
    {START_NEW_CASE}{CHANGE_LINK}
    + +
    + {CATEGORY_NAME}
    +
    + + + {CATEGORY_ELEMENT}
    + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_NewCategory.php b/workflow/engine/templates/cases/cases_NewCategory.php new file mode 100755 index 000000000..f096cd798 --- /dev/null +++ b/workflow/engine/templates/cases/cases_NewCategory.php @@ -0,0 +1,34 @@ +getStartCasesPerType( $_SESSION['USER_LOGGED'], $_GET['change'] ); + + + $uplogo = PATH_TPL . 'cases' . PATH_SEP . 'cases_NewCategory.html' ; + $template = new TemplatePower( $uplogo ); + $template->prepare(); + $template->assign ('CHANGE_LINK', G::LoadTranslation('ID_CHANGE_VIEW')); + $template->assign ('START_NEW_CASE', G::LoadTranslation('ID_START_NEW_CASE')); + + $newArrayPerCategory=array(); + $i=1; + //we put in order per category + while($i $_DBArray['NewCase'][$i]['uid'], 'value'=> $_DBArray['NewCase'][$i]['value'] ); + $i++; + } + //we show the categories names and wich element + foreach($newArrayPerCategory as $kk => $vv){ + $template->newBlock( 'CATEGORY_NAME'); + $template->assign ('CATEGORY_NAME', $kk); + foreach($vv as $k => $v) { + $template->newBlock( 'CATEGORY_ELEMENT'); + $template->assign ('CATEGORY_UID', $v['uid']); + $template->assign ('CATEGORY_ELEMENT', $v['value']); + } + } + $content = $template->getOutputContent(); + print $content; +?> + diff --git a/workflow/engine/templates/cases/cases_PrintViewTitle.html b/workflow/engine/templates/cases/cases_PrintViewTitle.html new file mode 100644 index 000000000..b1fab5ac1 --- /dev/null +++ b/workflow/engine/templates/cases/cases_PrintViewTitle.html @@ -0,0 +1,9 @@ + + + + + + + + +
    {$CASE}: {$APP_NUMBER}     {$TITLE}: {$APP_TITLE}       {$PROCESS}: {$APP_PROCESS}
    {$USER}: {$USR_USERNAME}     {$WORKSPACE}: {$USER_ENV}       {$DATELABEL}: {$DATEPRINT}
    \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_Reassign.html b/workflow/engine/templates/cases/cases_Reassign.html new file mode 100644 index 000000000..63dab6446 --- /dev/null +++ b/workflow/engine/templates/cases/cases_Reassign.html @@ -0,0 +1,58 @@ + + + Cases Reassign + + +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    {labels:ID_REASSIGN_USERS}
    .
    {labels:ID_USER_TO_REASSIGN} + +
    .
    + + + + +
    + +
    +
    +
    + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_ScreenDerivation.html b/workflow/engine/templates/cases/cases_ScreenDerivation.html new file mode 100644 index 000000000..1c7a1528d --- /dev/null +++ b/workflow/engine/templates/cases/cases_ScreenDerivation.html @@ -0,0 +1,164 @@ +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + + +
    + + + + + + + {if $PROCESS.ERROR eq '' && $PROCESS.ROU_TYPE neq 'SELECT' && $PROCESS.ROU_FINISH_FLAG } + + {else} + + {/if} + + + {foreach key=id item=data from=$TASK} + + + + + + {if $PROCESS.ROU_TYPE eq 'SELECT'} + + + + + + {/if} + {if $PROCESS.ERROR eq '' } + + + + + {/if} + {if not $data.NEXT_TASK.ROU_FINISH_FLAG } + + + + + {else} + + + + + {/if} + + + + + + {if $PROCESS.ROU_TYPE eq 'SELECT'} + + + + + + {/if} + {/foreach} + {if $PROCESS.ERROR eq '' && $PROCESS.ROU_TYPE neq 'SELECT' && ! $PROCESS.ROU_FINISH_FLAG } + + + + {/if} + {if $PROCESS.ERROR eq '' && $PROCESS.ROU_TYPE neq 'SELECT' && $PROCESS.ROU_FINISH_FLAG } + + + + {/if} +
    + + + + + + +
    + + + + + +
      {$PREVIOUS_PAGE_LABEL} 
    +
    + + + + +
    .
    +
    +
    {$END_OF_PROCESS}{$ASSIGN_TASK}
      
    {$OPTION_LABEL} {$id}:{$data.ROU_CONDITION }
    {$NEXT_TASK_LABEL}:{$data.NEXT_TASK.TAS_TITLE}{$data.NEXT_TASK.TAS_HIDDEN_FIELD}
    {$EMPLOYEE}:{$data.NEXT_TASK.USR_UID}{$data.NEXT_TASK.USR_HIDDEN_FIELD}
    {$LAST_EMPLOYEE}:{$data.NEXT_TASK.USR_UID}{$data.NEXT_TASK.USR_HIDDEN_FIELD}
    + {$data.NEXT_TASK.TAS_ASSIGN_TYPE}{$data.NEXT_TASK.TAS_DEF_PROC_CODE}{$data.NEXT_TASK.DEL_PRIORITY}{$data.NEXT_TASK.TAS_PARENT} +
    + {if $data.NEXT_TASK.TAS_ASSIGN_TYPE neq '' && not $data.NEXT_TASK.ROU_FINISH_FLAG } + + {/if} {if $data.NEXT_TASK.TAS_ASSIGN_TYPE neq '' && $data.NEXT_TASK.ROU_FINISH_FLAG } + + {$data.NEXT_TASK.TAS_ASSIGN_TYPE} + {/if} +
    + +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + {if $PROCESS.ROU_TYPE neq 'SELECT'} + +{/if} +
    + + + diff --git a/workflow/engine/templates/cases/cases_Step.html b/workflow/engine/templates/cases/cases_Step.html new file mode 100644 index 000000000..b146f18f8 --- /dev/null +++ b/workflow/engine/templates/cases/cases_Step.html @@ -0,0 +1 @@ +
    diff --git a/workflow/engine/templates/cases/cases_StepsTree.php b/workflow/engine/templates/cases/cases_StepsTree.php new file mode 100644 index 000000000..777d4b8c9 --- /dev/null +++ b/workflow/engine/templates/cases/cases_StepsTree.php @@ -0,0 +1,241 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + require_once ( "classes/model/Step.php" ); + require_once ( "classes/model/Content.php" ); + require_once ( "classes/model/AppDocumentPeer.php" ); + require_once ( "classes/model/InputDocumentPeer.php" ); + require_once ( "classes/model/OutputDocumentPeer.php" ); + require_once ( "classes/model/DynaformPeer.php" ); + $c = new Criteria(); + $c->add ( StepPeer::PRO_UID, $_SESSION['PROCESS'] ); + $c->add ( StepPeer::TAS_UID, $_SESSION['TASK'] ); + $c->addAscendingOrderByColumn ( StepPeer::STEP_POSITION ); + + // classes + G::LoadClass('tree'); + G::LoadClass('pmScript'); + G::LoadClass('case'); + + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $externalSteps = $oPluginRegistry->getSteps(); + + $oTree = new Tree(); + $oTree->nodeType = "blank"; + $oTree->name = 'Steps'; + $oTree->showSign = false; + + $tasUid = $_SESSION['TASK']; + $rs = StepPeer::doSelect( $c ); + + $oCase = new Cases(); + $Fields = $oCase->loadCase( $_SESSION['APPLICATION'] ); + $oPMScript = new PMScript(); + $oPMScript->setFields($Fields['APP_DATA'] ); + foreach ( $rs as $key => $aRow ) + { + $bAccessStep = false; + if ($aRow->getStepCondition() != '') { + $oPMScript->setScript( $aRow->getStepCondition() ); + $bAccessStep = $oPMScript->evaluate(); + } + else { + $bAccessStep = true; + } + + if ($bAccessStep) + { + switch( $aRow->getStepTypeObj() ) + { + case 'DYNAFORM': + $oDocument = DynaformPeer::retrieveByPK($aRow->getStepUidObj()); + $stepTitle = $oDocument->getDynTitle(); break; + case 'OUTPUT_DOCUMENT': + $oDocument = OutputDocumentPeer::retrieveByPK($aRow->getStepUidObj()); + $stepTitle = $oDocument->getOutDocTitle(); break; + case 'INPUT_DOCUMENT': + $oDocument = InputDocumentPeer::retrieveByPK($aRow->getStepUidObj()); + $stepTitle = $oDocument->getInpDocTitle(); + $sType = $oDocument->getInpDocFormNeeded(); break; + case 'EXTERNAL': + $stepTitle = 'unknown ' . $aRow->getStepUidObj(); + $oPluginRegistry = &PMPluginRegistry::getSingleton (); + foreach ( $externalSteps as $key=>$val ) { + if ( $val->sStepId == $aRow->getStepUidObj() ) { + $stepTitle = $val->sStepTitle; //default title + $sNamespace = $val->sNamespace; + $oPlugin =& $oPluginRegistry->getPlugin($sNamespace); + $classFile = PATH_PLUGINS . $oPlugin->sNamespace . PATH_SEP . 'class.' . $oPlugin->sNamespace .'.php'; + if ( file_exists ( $classFile ) ) { + require_once ( $classFile ); + $sClassName = $sNamespace . 'class'; + $obj = new $sClassName( ); + if (method_exists($obj, 'getExternalStepTitle')) { + $stepTitle = $obj->getExternalStepTitle( $aRow->getStepUidObj(), $tasUid, $aRow->getStepPosition()); + } + } + } + } + break; + + default: + $stepTitle = $aRow->getStepUid(); + } + + //$oNode =& $oTree->addChild($aRow->getStepUid(), ' ' . $aRow->getStepNameObj(), array('nodeType'=>'parent') ); + $oNode =& $oTree->addChild($aRow->getStepUid(), ' ' . $stepTitle, array('nodeType'=>'parent') ); + $oNode->plus = ''; + $oNode->minus = ''; + switch( $aRow->getStepTypeObj() ) + { + case 'DYNAFORM': + $sOptions = ''; + $sOptions .= ''; + $sOptions .= '
    ' . G::LoadTranslation('ID_EDIT') . '
    '; + $oAux =& $oNode->addChild($aRow->getStepUid() . '_node', $sOptions, array('nodeType'=>'child')); + break; + case 'OUTPUT_DOCUMENT': + $sOptions = ''; + $oCriteria = new Criteria('workflow'); + $oCriteria->add(AppDocumentPeer::APP_UID, $_SESSION['APPLICATION']); + $oCriteria->add(AppDocumentPeer::DEL_INDEX, $_SESSION['INDEX']); + $oCriteria->add(AppDocumentPeer::DOC_UID, $aRow->getStepUidObj()); + $oCriteria->add(AppDocumentPeer::APP_DOC_TYPE, 'OUTPUT'); + $oDataset = AppDocumentPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + if ($aRow2 = $oDataset->getRow()) { + $sOptions .= ''; + $sOptions .= ''; + $sOptions .= ''; + } + else { + $sOptions .= ''; + } + $sOptions .= '
    ' . G::LoadTranslation('ID_VIEW') . '' . G::LoadTranslation('ID_GENERATE') . '' . G::LoadTranslation('ID_DELETE') . '' . G::LoadTranslation('ID_GENERATE') . '
    '; + $oAux =& $oNode->addChild($aRow->getStepUid() . '_node', $sOptions, array('nodeType'=>'child')); + break; + case 'INPUT_DOCUMENT': + $sOptions = ''; + $sOptions .= ''; + $sOptions .= '
    ' . ($sType == 'REAL' ? G::LoadTranslation('ID_NEW') : G::LoadTranslation('ID_ATTACH')) . '
    '; + $oCri = new Criteria; + $oCri->add( AppDocumentPeer::APP_UID , $_SESSION['APPLICATION'] ); + $oCri->add( AppDocumentPeer::DEL_INDEX , $_SESSION['INDEX'] ); + $oCri->add( AppDocumentPeer::DOC_UID , $aRow->getStepUidObj() ); + $oCri->add( AppDocumentPeer::APP_DOC_TYPE , 'INPUT' ); + $oCri->addAscendingOrderByColumn(AppDocumentPeer::APP_DOC_INDEX); + $aDocuments = AppDocumentPeer::doSelect($oCri); + if (sizeof($aDocuments) !== 0) + { + $i = 1; + $sOptions .= ''; + reset($aDocuments); + while ($oDocument = current($aDocuments)) + { + $aRow2 = $oDocument->toArray(BasePeer::TYPE_FIELDNAME); + $oAux1 = new AppDocument(); + $aAux = $oAux1->load($aRow2['APP_DOC_UID']); + $sOptions .= ''; + if ($aAux['APP_DOC_FILENAME'] != '') { + $sAux = $aAux['APP_DOC_FILENAME']; + } + else { + $sAux = $aAux['APP_DOC_COMMENT']; + } + $sOptions .= ''; + global $oPluginRegistry; + if (!$oPluginRegistry->existsTrigger ( PM_CASE_DOCUMENT_LIST )) { + if (isset($_GET['DOC'])) + { + $sOptions .= ''; + } + else + { + $sOptions .= ''; + } + $sOptions .= ''; + } + $sOptions .= ''; + $i++; + next($aDocuments); + } + $sOptions .= '
    ' . $i . '.' . G::LoadTranslation('ID_VIEW') . '' . G::LoadTranslation('ID_VIEW') . '' . G::LoadTranslation('ID_DELETE') . '
    '; + } + $oAux =& $oNode->addChild($aRow->getStepUid() . '_node', $sOptions, array('nodeType'=>'child')); + + break; + case 'MESSAGE': + $sOptions = ''; + $sOptions .= ''; + $sOptions .= '
    '; + $oAux =& $oNode->addChild($aRow['STEP_UID'] . '_node', $sOptions, array('nodeType'=>'child')); + break; + case 'EXTERNAL': + $aActions = array ('action' => 'label' ); + $oPluginRegistry = &PMPluginRegistry::getSingleton (); + foreach ( $externalSteps as $key=>$val ) { + if ( $val->sStepId == $aRow->getStepUidObj() ) { + $stepTitle = $val->sStepTitle; //default title + $sNamespace = $val->sNamespace; + $oPlugin =& $oPluginRegistry->getPlugin($sNamespace); + $classFile = PATH_PLUGINS . $oPlugin->sNamespace . PATH_SEP . 'class.' . $oPlugin->sNamespace .'.php'; + if ( file_exists ( $classFile ) ) { + require_once ( $classFile ); + $sClassName = $sNamespace . 'class'; + $obj = new $sClassName( ); + if (method_exists($obj, 'getExternalStepAction')) { + $aActions = $obj->getExternalStepAction( $aRow->getStepUidObj(), $aRow->getStepPosition()); + } + } + } + } + + $sOptions = ""; + $sOptions .= "
    "; + foreach ( $aActions as $action => $label ) { + $styleAction = $_GET['UID'] == $aRow->getStepUidObj() && + $_GET['POSITION'] == $aRow->getStepPosition() && + $_GET['ACTION'] == $action ? 'background-color:orange;color:white;padding-left:5px;padding-right:5px; ' : ''; + $sOptions .= " " . $label . ""; + } + $sOptions .= '
    '; + + $oAux =& $oNode->addChild($aRow->getStepUid() . '_node', $sOptions, array('nodeType'=>'child')); + } + $oAux->point = ''; + } + } + +$oNode =& $oTree->addChild('-1', '[ ' . G::LoadTranslation('ID_ASSIGN_TASK') . ' ]', array('nodeType'=>'parent')); +$oNode->plus = ''; +$oNode->minus = ''; +/*$sOptions = ''; +$sOptions .= ''; +$sOptions .= '
    ' . G::LoadTranslation('ID_ASSIGN_SCREEN') . '
    '; +$oAux =& $oNode->addChild('-1_node', $sOptions, array('nodeType'=>'child')); +$oAux->point = '';*/ +echo $oTree->render(); diff --git a/workflow/engine/templates/cases/cases_UsersReassignCases.html b/workflow/engine/templates/cases/cases_UsersReassignCases.html new file mode 100644 index 000000000..c24bfbbcd --- /dev/null +++ b/workflow/engine/templates/cases/cases_UsersReassignCases.html @@ -0,0 +1,41 @@ +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    {ID_NUMBER}{ID_CASE}{ID_TASK}{ID_PROCESS}{ID_STATUS}{ID_REASSIGN_TO}
    {APP_NUMBER}{APP_TITLE}{APP_TAS_TITLE}{APP_PRO_TITLE}{ID_STATUS} + + + +
    + + +
    +
    +
    + \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_title.html b/workflow/engine/templates/cases/cases_title.html new file mode 100644 index 000000000..4d69a79f7 --- /dev/null +++ b/workflow/engine/templates/cases/cases_title.html @@ -0,0 +1,5 @@ + + + + +
    {$CASE} #: {$APP_NUMBER}     {$TITLE}: {$APP_TITLE}
    \ No newline at end of file diff --git a/workflow/engine/templates/cases/cases_toRevise.php b/workflow/engine/templates/cases/cases_toRevise.php new file mode 100644 index 000000000..a289ca112 --- /dev/null +++ b/workflow/engine/templates/cases/cases_toRevise.php @@ -0,0 +1,151 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + +G::LoadClass('groups'); +G::LoadClass('tree'); + +$tree = new Tree(); +$tree->name = 'Groups'; +$tree->nodeType = "base"; +$tree->width = "200px"; +$tree->contentWidth = "220"; +$tree->value = ' +
    +
    + + + + + +
    Steps List
    +
    +
    + '; +$tree->showSign = false; + +G::LoadClass('case'); + +$o = new Cases(); +$steps = $o->getAllDynaformsStepsToRevise($_GET['APP_UID']); +$APP_UID = $_GET['APP_UID']; +$DEL_INDEX = $_GET['DEL_INDEX']; + + +$html = " + + + + +
    Dynaforms
    "; + + $ch = &$tree->addChild("", $html, array('nodeType' => 'child')); + $ch->point = ''; + $i=1; + $PRO_UID=''; + $DYN_UID=''; +foreach ($steps as $step) { + require_once 'classes/model/Dynaform.php'; + $od = new Dynaform(); + $dynaformF = $od->Load($step['STEP_UID_OBJ']); + + $n = $step['STEP_POSITION']; + $TITLE = " - ".$dynaformF['DYN_TITLE']; + $DYN_UID = $dynaformF['DYN_UID']; + $PRO_UID = $step['PRO_UID']; + + $html = " + + + + + + +
      $n   + {$TITLE} +
    "; + + $ch = &$tree->addChild("", $html, array('nodeType' => 'child')); + $ch->point = ''; + $i++; +} + +$html = " + + + + + +
    +   Input Documents +
    "; + $ch = &$tree->addChild("", $html, array('nodeType' => 'child')); + $ch->point = ''; + +$steps = $o->getAllInputsStepsToRevise($_GET['APP_UID']); +//$i=1; + +foreach ($steps as $step) { + require_once 'classes/model/InputDocument.php'; + $od = new InputDocument(); + $IDF = $od->Load($step['STEP_UID_OBJ']); + + $n = $step['STEP_POSITION']; + $TITLE = " - ".$IDF['INP_DOC_TITLE']; + $INP_DOC_UID = $IDF['INP_DOC_UID']; + $PRO_UID = $step['PRO_UID']; + + $html = " + + + + + + +
      $n   + {$TITLE} +
    "; + + $ch = &$tree->addChild("", $html, array('nodeType' => 'child')); + $ch->point = ''; + $i++; +} + +$i++; +$html = " + + + + + +
    +   Output Documents +
    "; + + $ch = &$tree->addChild("", $html, array('nodeType' => 'child')); + $ch->point = ''; + +print ($tree->render()); +// diff --git a/workflow/engine/templates/cases/cases_toReviseIn.html b/workflow/engine/templates/cases/cases_toReviseIn.html new file mode 100644 index 000000000..23b0a5416 --- /dev/null +++ b/workflow/engine/templates/cases/cases_toReviseIn.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/workflow/engine/templates/cases/css/extjs-extend/xtheme-gray.css b/workflow/engine/templates/cases/css/extjs-extend/xtheme-gray.css new file mode 100755 index 000000000..cb8ae17be --- /dev/null +++ b/workflow/engine/templates/cases/css/extjs-extend/xtheme-gray.css @@ -0,0 +1,386 @@ +@import url("/images/icons_silk/sprite.css"); +/** + * Cases Interface styles + */ + +#details-panel .x-panel-body { + padding: 10px; + background: #eee; + color: #555; +} +#details-panel a:link, #details-panel a:visited { + color: #369; +} +#details-panel h2 { + color: #369; + font-size: 15px; +} +#details-panel p { + margin-bottom: 5px; +} + +.x-tree-node-icon{ + width:18px !important; + background-image:url( /images/icons_silk/sprites.gif.png); + height:18px; +} + + +.ICON_FOLDERS { + /*.ss_folder_explore*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -7777px !important; +} + +.x-tab-strip-text.ICON_FOLDERS{ + /*.ss_folder_explore*/ + background-position:0 -7776px !important; +} +.x-tab-strip-inner .x-tab-strip-text.ICON_FOLDERS{ + background-position:0 -7775px !important; +} + +.ICON_CASES_FOLDERS { + /*background-image: url(/images/icons_silk/cases-inbox.png) !important;*/ +} + +.ICON_CASES_INBOX { + /*ss_folder_page*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -7957px !important; +} + +.ICON_CASES_DRAFT { + /*ss_pencil*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -12439px !important; +} + +.ICON_CASES_SENT { + /*ss_page_white_go*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -11773px !important; +} + +.ICON_CASES_SELFSERVICE { + /*ss_arrow_rotate_anticlockwise */ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -955px !important; +} + +.ICON_CASES_PAUSED { + /*ss_clock*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -4033px !important; +} + +.ICON_CASES_COMPLETED { + background-image: url(/images/cases-completed1.png) !important; +} + +.ICON_CASES_CANCELLED { + background-image: url(/images/cases-cancelled.png) !important; +} + +.ICON_CASES_FOLDERS { + /*ss_report */ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -13213px !important; +} + +.ICON_SEARCHS { + background-image: url(/images/cases-search.png) !important; + /*ss_find*/ + /*background-position:0 -7453px !important;*/ +} +.ICON_CASES_SEARCH { + /*ss_page_find*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -11089px !important; +} + +.ICON_ADMIN { + /*ss_user_suit*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -17371px !important; +} + +.ICON_CASES_TO_REVISE { + /*ss_page_white_magnify*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -11881px !important; +} + +.ICON_CASES_TO_REASSIGN { + /*ss_arrow_rotate_clockwise*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -973px !important; +} + +.ICON_CASES_START_PAGE { + /*ss_chart_pie*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -3925px !important; +} +.ICON_CASES_START_CASE { + /*ss_add*/ + background-image:url( /images/icons_silk/sprites.gif.png) !important; + background-position:0 -19px !important; +} +.ICON_CASES_HOME { + /*ss_house*/ + background-image:url(/images/icons_silk/sprites.gif.png) !important; + background-position:0 -8497px !important; +} + +.ICON_CASES_DELETE { + background-image:url(/images/delete-16x16.gif) !important; +} + +.ICON_CASES_CANCEL { + background-image:url(/images/deactivate.png) !important; +} + +.ICON_CASES_UNPAUSE { + background-image:url(/images/activate.png) !important; +} + +.ICON_CASES_OPEN { + background-image:url(/images/edit.gif) !important; +} + + + +/** + * style for case list grid + */ +.x-grid3-col-openLink { + padding: 1px; + background: #eee; + text-align: center; +} + +.x-grid3-col-openLink a { + color: black; + border-color:#ff0; +} + +.x-grid3-col-openLink a:hover { + background: #0ee; +} + + + + +/*Tables*/ +.x-grid3-cell-inner{} +.x-grid3-row-table{ + padding:0px 0; +} +.x-grid3-row:nth-child(odd) { background-color:#FFF; } +.x-grid3-row:nth-child(even) { background-color:#F6F6F6; } +.x-grid3-row-over{ + background: #E0EAEF !important; + cursor: pointer; +} +.x-grid3-hd-inner{ + font-size:11px; + font-weight: bold; + color:#333; + text-shadow:#fff 0px 1px 1px; +} +.x-grid3-col-openLink,.x-grid3-col-deleteLink{ + background:none; + height: 18px; +} +.x-grid3-col-openLink a:after{ + content:''; +} + +.x-grid3-row-selected{ + background-color:#F6E095 !important; +} +/*Checkboxes*/ +.grid_with_checkbox .x-grid3-header-offset{ + padding-left:18px !important; +} +.grid_with_checkbox .x-grid3-row{ + background-image:url(/images/icons_silk/unchecked.png) !important; + background-repeat: no-repeat !important; + padding-left:18px !important; +} + +.grid_with_checkbox .x-grid3-row.x-grid3-row-selected{ + background-image:url(/images/icons_silk/checked.png) !important; + background-repeat: no-repeat !important; + padding-left:18px !important; +} + + +/* +Pone en mayúsuclas el texto que se encuentra en el toolbar de arriba +*/ +.x-panel-tbar .x-toolbar-cell{ + text-transform: capitalize; +} + +/*TREE*/ +#ext-gen38.x-tree-root-ct .x-tree-node{ +} + +#ext-gen38.x-tree-root-ct .x-tree-node-el{ + background:#eee; + padding-top:4px; + padding-bottom:4px; + cursor: auto; + border-bottom:1px solid #ddd; + border-top:1px solid #ddd; +} +#ext-gen38.x-tree-root-ct .x-tree-node-leaf{ + background:#fff; + padding-top:0; + padding-bottom:0; + cursor: pointer; + border-bottom:none; + border-top:none; +} +#ext-gen38.x-tree-root-ct .x-tree-node .x-tree-node{ + padding-bottom:0; +} +#ext-gen38.x-tree-root-ct .x-tree-node-over +{ + background:#eee; +} +#ext-gen38.x-tree-root-ct .x-tree-node-leaf{ + padding-left:16px; +} +/*Eliminamos los restos del tree*/ +#ext-gen38.x-tree-root-ct .x-tree-elbow,#ext-gen38.x-tree-root-ct .x-tree-elbow-line,#ext-gen38.x-tree-root-ct .x-tree-elbow-end, +#ext-gen38.x-tree-root-ct .x-tree-node-indent img{ + background:none; + width:0px; +} +/*Cambiamos el menos y más*/ +#ext-gen38.x-tree-root-ct .x-tree-elbow-minus,#ext-gen38.x-tree-root-ct .x-tree-elbow-end-minus{ + background-image:url(/images/icons_silk/sprites.gif.png) !important; + background-position:0 -2395px !important; +} +#ext-gen38.x-tree-root-ct .x-tree-elbow-plus,#ext-gen38.x-tree-root-ct .x-tree-elbow-end-plus{ + background-image:url(/images/icons_silk/sprites.gif.png) !important; + background-position:0 -2359px !important; +} +/*Item selecciondo en el TREE*/ +.x-tree-root-ct .x-tree-selected{ + background:#C3D7DF !important; +} + +/*REFRESHER*/ +#ext-gen38.x-tree-root-ct .x-tree-node-ct b{ + /*background:#FFFADF;*/ +} +#refreshNotifiers.x-btn{ +} +#ext-gen35.x-panel-tbar-noheader{ + position:absolute; + top:1px; + right:1px; + height:27px; + z-index:1000 !important; + width:28px !important; + border-bottom:1px #ccc solid; +} +#ext-gen35.x-panel-tbar-noheader .x-toolbar-layout-ct{ + width:28px !important; +} +#ext-gen35.x-panel-tbar-noheader .x-toolbar-left{ + display:none; +} +#ext-gen35.x-panel-tbar-noheader .x-toolbar-right{ + text-align: left !important; +} + +/*StartCase*/ +.x-tab-strip-text.ICON_CASES_START_CASE{ + background-position:0px -17px !important; +} +/*Dashboard*/ +.x-tab-strip-text.ICON_CASES_START_PAGE{ + background-position:0px -3923px !important; +} + + +.row_updated{ + /*background:#FFFDEF;*/ + font-weight: bold; +} + +/*STARTCASE RIGHT PANEL*/ + +#process-detail-panel .details{ + +} +#process-detail-panel .details .details-info{ + padding:10px; +} +#process-detail-panel .details .details-info table td{ + padding:5px; +} + +.icon-expand-all{ + /*ss_bullet_toggle_plus*/ + background-image:url(/images/icons_silk/sprites.gif.png) !important; + background-position:0 -2359px !important; +} +.icon-collapse-all{ + /*ss_bullet_toggle_minus*/ + background-image:url(/images/icons_silk/sprites.gif.png) !important; + background-position:0 -2395px !important; +} +#startCaseTreePanel .x-tree-elbow-end-minus, +#startCaseTreePanel .x-tree-elbow-end-plus, +#startCaseTreePanel .x-tree-elbow-minus, +#startCaseTreePanel .x-tree-elbow-plus, +#startCaseTreePanel .x-tree-elbow-line, +#startCaseTreePanel .x-tree-node-indent{ + display:none; +} + + +/*Search Button*/ +.pm_search_x_button{ + /*margin-left:-21px;*/ + display:block; + width:16px; + height:20px; + margin-top:1px; + margin-right:3px; +} +.ext-ie .pm_search_x_button {margin-top:0px !important} +.pm_search_x_button .x-btn-over .x-btn-mc +{ + background:transparent; +} +.pm_search_x_button .x-btn-ml,.pm_search_x_button .x-btn-mr, +.pm_search_x_button .x-btn-tc,.pm_search_x_button .x-btn-tl,.pm_search_x_button .x-btn-tr, +.pm_search_x_button .x-btn-bc,.pm_search_x_button .x-btn-bl,.pm_search_x_button .x-btn-br +{ + display:none !important; +} +.pm_search_x_button button{ + background:url(/images/icons_silk/search_x_button.png) no-repeat; + text-indent: -10000px; + width:16px !important; + height:20px !important; + display:block; + margin:0; + padding:0; +} +.pm_search_text_field input{ + border-right:none !important; +} +.ext-ie8 .pm_search_text_field input {margin-top:1px !important} + +.pm_search_text_field input:focus,.pm_search_text_field .x-form-focus{ + border:1px solid #c1c1c1 !important; + border-right:none !important; +} \ No newline at end of file diff --git a/workflow/engine/templates/cases/main.html b/workflow/engine/templates/cases/main.html new file mode 100755 index 000000000..1531acb3a --- /dev/null +++ b/workflow/engine/templates/cases/main.html @@ -0,0 +1,7 @@ +
    +
    +
    + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/main.js b/workflow/engine/templates/cases/main.js new file mode 100755 index 000000000..b9d830a57 --- /dev/null +++ b/workflow/engine/templates/cases/main.js @@ -0,0 +1,701 @@ +var PANEL_EAST_OPEN = false; +var timerMinutes = 2*60*1000; //every 2 minutes, this should be customized also, + +var currentSelectedTreeMenuItem = null; +var centerPanel; + +var menuTree; + +var winSize = parent.getClientWindowSize(); + +var detailsMenuTreePanelHeight = winSize.height - 420; +var detailsdebugVariablesHeight = winSize.height - 200; + +var debugVarTpl = new Ext.Template('{value}'); +debugVarTpl.compile(); + +var detailsText = ''; + +var debugTriggersDetailTpl = new Ext.Template('
    {code}
    '); +debugTriggersDetailTpl.compile(); + +var propStore; +var triggerStore; + +var debugVariablesFilter; +var ReloadTreeMenuItemDetail; +var NOTIFIER_FLAG = false; +var result; + +var _action = ''; + +new Ext.KeyMap(document, { + key: Ext.EventObject.F5, + fn: function(keycode, e) { + if (! e.ctrlKey) { + if (Ext.isIE) { + e.browserEvent.keyCode = 8; + } + e.stopEvent(); + updateCasesTree(); + } + else + Ext.Msg.alert('Refresh', 'You clicked: CTRL-F5'); + } +}); + +Ext.onReady(function(){ + + Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + + var resetGrid = function() { + propStore.load(); + }; + + var debugVariablesFilterDynaform = function(){ + propStore.load({params:{filter:'dyn'}}); + } + + var debugVariablesFilterSystem = function(){ + propStore.load({params:{filter:'sys'}}); + } + + var resetTriggers = function(){ + triggerStore.load(); + } + + propStore = new Ext.data.Store({ + proxy: new Ext.data.HttpProxy({url: 'debug_vars'}), + reader: new Ext.data.DynamicJsonReader({root: 'data'}) + }); + + propStore.on('load', function(){ + propStore.fields = propStore.recordType.prototype.fields; + debugVariables.setSource(propStore.getAt(0).data); + }); + + + var debugVariables = new Ext.grid.PropertyGrid({ + id: 'debugVariables', + title:TRANSLATIONS.ID_VARIABLES, + autoHeight: false, + height: 300, + width: 400, + region: 'center', + margins: '2 2 0 2', + + border: true, + stripeRows: true, + listeners: { + beforeedit: function(event) { //Cancel editing - read only + event.cancel = true; + } + }, + tbar: [ + {text: TRANSLATIONS.ID_ALL, handler: resetGrid}, + {text: TRANSLATIONS.ID_DYNAFORM, handler: debugVariablesFilterDynaform}, + {text: TRANSLATIONS.ID_SYSTEM, handler: debugVariablesFilterSystem} + ], + sm: new Ext.grid.RowSelectionModel({singleSelect: true}), + viewConfig: { + forceFit: true + } + + }); + + //set debug variable details + debugVariables.getSelectionModel().on('rowselect', function(sm, rowIdx, r) { + var detailPanel = Ext.getCmp('debug-details-panel'); + debugVarTpl.overwrite(detailPanel.body, r.data); + detailPanel.setTitle(r.data.name); + //alert(r.data.name+' '+r.data.value); + + // + if(r.data.value == '' || r.data.value == '' ){ + deatachAction.setDisabled(false); + Ext.Ajax.request({ + url: 'debug_vars?r='+Math.random(), + success: function(response){ + try{ + result = eval('('+response.responseText+')'); + + var store1a = new Ext.data.ArrayStore({fields: result.headers}); + // manually load local data + store1a.loadData(result.rows); + + var myGridPanel = new Ext.grid.GridPanel({ + store: store1a, + height: 200, + border : false, + columns: result.columns, + stripeRows : true, + layout: 'fit', + viewConfig:{forceFit:true, scrollOffset:0}, + listeners: { + rowdblclick: function(grid, n,e){ + + }, + render: function(){ + this.loadMask = new Ext.LoadMask(this.body, { msg:'Loading...' }); + } + } + }); + + Ext.each(detailPanel.items.items, function(childPanel) { + detailPanel.remove(childPanel, true); + + }); + + detailPanel.add(myGridPanel); + detailPanel.doLayout(); + } catch (e){ + //alert(""+e); + } + }, + failure: function(){}, + params: {request: 'getRows', fieldname:r.data.name} + }); + + + } else + deatachAction.setDisabled(true); + + }); + + centerPanel = { + region: 'center', // a center region is ALWAYS required for border layout + xtype:'panel', + deferredRender: false, + contentEl:'casesSubFrame' + } + + + /** + * Menu Panel + */ + var treeMenuItems = new Ext.tree.TreePanel({ + xtype: 'treepanel', + height: 350, + id: 'tree-panel', + region: 'center', + margins: '0 0 0 0', + tbar: [ + { + xtype: 'tbfill' + }, + { + id:'refreshNotifiers', + xtype: 'tbbutton', + cls: 'x-btn-icon', + icon: '/images/refresh.gif', + /*text: 'Reload notifiers',*/ + handler: function(){ + updateCasesTree(); + updateCasesView(); + } + } + ], + animate:true, + autoScroll: true, + rootVisible: false, + clearOnReLoad: false, + root: new Ext.tree.AsyncTreeNode(), + + // Our custom TreeLoader: + loader: new Ext.app.menuLoader({ + dataUrl:'casesMenuLoader', + clearOnLoad: false + }), + + listeners: { + 'click': function(tp) { + if( tp.attributes.url ){ + document.getElementById('casesSubFrame').src = tp.attributes.url; + } + } , + 'render': function(tp){ + /*tp.getSelectionModel().on('selectionchange', function(tree, node){ + + if( node.attributes.url ){ + document.getElementById('casesSubFrame').src = node.attributes.url; + } + //var el = Ext.getCmp('details-panel').body; + if(node.attributes.tagName == 'option' && node.attributes.cases_count ){ + ReloadTreeMenuItemDetail({item:node.attributes.id}); + currentSelectedTreeMenuItem = node.attributes.id; + Ext.getCmp('tree_menuItem_detail').setTitle(node.attributes.title.toUpperCase() + ' - Related processes: '+node.attributes.processes_count); + } else { + //el.update(detailsText); + Ext.getCmp('tree_menuItem_detail').setTitle(''); + currentSelectedTreeMenuItem = null; + ReloadTreeMenuItemDetail({item:''}); + } + })*/ + + }/*, + 'afterrender': { + fn: setNode, + scope: this + }*/ + + } + }); + + var loader = treeMenuItems.getLoader(); + loader.on("load", function(){ + document.getElementById('casesSubFrame').src = defaultOption; + + if( _nodeId != '' ){ + treePanel1 = Ext.getCmp('tree-panel') + if(treePanel1) + node = treePanel1.getNodeById(_nodeId); + if(node) + node.select(); + + } + }); + + + + var treeMenuItemDetail = new Ext.tree.TreePanel({ + id: 'tree_menuItem_detail', + region: 'south', + animate:true, + autoScroll:true, + loader: new Ext.tree.TreeLoader({ + dataUrl:'casesMenuLoader?action=getProcess' + }), + enableDD:true, + containerScroll: true, + border: false, + width: 250, + height: 120, + dropConfig: {appendOnly:true}, + collapsible: true, + split: true, + margins: '0 2 2 2', + cmargins: '2 2 2 2', + rootVisible: false, + root: new Ext.tree.AsyncTreeNode()/*, + tbar: [{ + text: 'reload', + handler: ReloadTreeMenuItemDetail + }]*/ + }); + + ReloadTreeMenuItemDetail = function(params){ + treeMenuItemDetail.loader.dataUrl = 'casesMenuLoader?action=getProcess&item='+params.item; + treeMenuItemDetail.root.reload(); + } + + // set the root node + var root = new Ext.tree.AsyncTreeNode({ + text: 'Ext JS', + draggable:false, // disable root node dragging + id:'src', + loaded:false, + expanded:true + }); + + treeMenuItemDetail.setRootNode(root); + + mainMenu = new Ext.Panel({ + id:'menuTreePanel', + title: '', + region: 'west', + layout: 'border', + width: 200, + height: 500, + minSize: 175, + maxSize: 400, + split: true, + collapsible: true, + collapseMode: 'mini', + margins: '0 0 0 2', + items: [ + treeMenuItems, + treeMenuItemDetail + ] + }); + + /** + * Triggers Panel + */ + Ext.QuickTips.init(); + + var xg = Ext.grid; + + var reader = new Ext.data.JsonReader( + { + root: 'data', + totalProperty: 'total', + id: 'name' + }, + [ + {name: 'name'}, + {name: 'execution_time'}, + {name: 'code'} + ] + ); + + triggerStore = new Ext.data.GroupingStore({ + reader: reader, + sortInfo:{field: 'name', direction: "ASC"}, + groupField:'execution_time', + proxy: new Ext.data.HttpProxy({url: 'debug_triggers?r='+Math.random()}) + }); + + var debugTriggers = new xg.GridPanel({ + store: triggerStore, + + columns: [ + {id:'name',header: "Name", width: 60, sortable: true, dataIndex: 'name'}, + {header: "Execution", width: 30, sortable: true, dataIndex: 'execution_time'}, + {header: "Code", width: 30, sortable: false, dataIndex: 'code', hidden: true} + ], + + view: new Ext.grid.GroupingView({ + forceFit:true, + groupTextTpl: '{text} ({[values.rs.length]} {[ values.rs[0].data.execution_time=="error" || values.rs[0].data.execution_time=="Fatal error"? ""+values.rs[0].data.execution_time+"": values.rs.length > 1 ? "Triggers" : "Trigger"]})' + }), + + width: 700, + height: 450, + title: TRANSLATIONS.ID_TRIGGERS, + iconCls: 'icon-grid', + tbar: [ + {text: TRANSLATIONS.ID_OPEN_IN_POPUP, handler: triggerWindow} + ], + sm: new Ext.grid.RowSelectionModel({singleSelect: true}), + viewConfig: { + forceFit: true + }, + listeners: { + rowdblclick: function(grid, n,e){ + triggerWindow(); + } + } + }); + + debugTriggers.getSelectionModel().on('rowselect', function(sm, rowIdx, r) { + var detailPanel = Ext.getCmp('debug-details-panel'); + debugTriggersDetailTpl.overwrite(detailPanel.body, r.data); + }); + + function triggerWindow() { + var r = debugTriggers.getSelectionModel().getSelected(); + if(r){ + var w = new Ext.Window({ + title: r.data.name, + width: 500, + height: 400, + modal: true, + autoScroll: true, + maximizable: true, + items: [], + listeners:{ + show:function() { + this.loadMask = new Ext.LoadMask(this.body, { msg:'Loading. Please wait...' }); + } + } + }); + w.show(); + + debugTriggersDetailTpl.overwrite(w.body, r.data); + } + }; + + + var deatachAction = new Ext.Action({ + text: TRANSLATIONS.ID_DEATACH, + handler: function(){ + var store1a = new Ext.data.ArrayStore({fields: result.headers}); + store1a.loadData(result.rows); + + for(i=0; i', ''); + oldValue = oldValue.replace('', ''); + + newValue = result[i].count; + + if( oldValue != newValue && oldValue != 0 ){ + document.getElementById('NOTIFIER_'+result[i].item).innerHTML = '' + result[i].count + ''; + //NOTIFIER_FLAG = true; + } else { + //if(NOTIFIER_FLAG === false){ + document.getElementById('NOTIFIER_'+result[i].item).innerHTML = result[i].count; + //} + } + } + else continue; + } + Ext.getCmp('refreshNotifiers').setIcon('/images/refresh.gif'); + } catch (e){ + //alert(""+e); + } + }, + failure: function(){}, + params: {'updateCasesTree': true} + }); + } catch(e){alert(' '+e)} +} + +//the timer function will be called after 2 minutes; +function Timer(){ + updateCasesView(); + setTimeout('Timer()', timerMinutes); +} + +Ext.data.DynamicJsonReader = function(config){ + Ext.data.DynamicJsonReader.superclass.constructor.call(this, config, []); +}; + +Ext.extend(Ext.data.DynamicJsonReader, Ext.data.JsonReader, { + getRecordType : function(data) { + var i = 0, arr = []; + + for (var name in data[0]) { + arr[i++] = name; + } // is there a built-in to do this? + this.recordType = Ext.data.Record.create(arr); + return this.recordType; + }, + readRecords : function(o){ // this is just the same as base class, with call to getRecordType injected + + this.jsonData = o; + var s = this.meta; + var sid = s.id; + var totalRecords = 0; + if(s.totalProperty){ + var v = parseInt(eval("o." + s.totalProperty), 10); + if(!isNaN(v)){ + totalRecords = v; + } + } + + var root = s.root ? eval("o." + s.root) : o; + var recordType = this.getRecordType(root); + var fields = recordType.prototype.fields; + var records = []; + + for(var i = 0; i < root.length; i++){ + var n = root[i]; + var values = {}; + var id = (n[sid] !== undefined && n[sid] !== "" ? n[sid] : null); + for(var j = 0, jlen = fields.length; j < jlen; j++){ + var f = fields.items[j]; + var map = f.mapping || f.name; + var v = n[map] !== undefined ? n[map] : f.defaultValue; + v = f.convert(v); + values[f.name] = v; + } + var record = new recordType(values, id); + record.json = n; + records[records.length] = record; + } + + return { + records : records, + totalRecords : totalRecords || records.length + }; + } +}); + +Ext.app.menuLoader = Ext.extend(Ext.ux.tree.XmlTreeLoader, { + processAttributes : function(attr){ + + if(attr.blockNestedTree){ + //console.log(attr); + attr.text = attr.blockTitle; + attr.iconCls = 'ICON_' + attr.id; + attr.loaded = false; + attr.expanded = false; + attr.xtype = 'treepanel'; + attr.rootVisible = true, + attr.singleClickExpand=true, + attr.animate = true, + attr.nodeType = 'async', + attr.clearOnReLoad= false, + + attr.loader = new Ext.tree.TreeLoader( { + dataUrl : attr.blockNestedTree, + baseParams : { + action : 'expandNode', + folderID: attr.folderId + }}); + attr.style= { + // width: '50%', + height: '50px', + // marginBottom: '10px', + overflow:'auto' + }; + + + }else if(attr.blockTitle){ + attr.text = attr.blockTitle; + attr.iconCls = 'ICON_' + attr.id; + attr.loaded = true; + //if((attr.url)&&(attr.url!="")){ + // attr.expanded = false; + //}else{ + attr.expanded = true; + //} + }else if(attr.title){ + attr.text = attr.title; + if( attr.cases_count ) + attr.text += ' ()'; + + attr.iconCls = 'ICON_' + attr.id; + attr.loaded = true; + attr.expanded = false; + + } else if(attr.PRO_UID){ + attr.loaded = true; + attr.leaf = true; + } + } +}); + +function setDefaultOption(){ + //document.getElementById('casesSubFrame').src = "casesListExtJs"; +} + diff --git a/workflow/engine/templates/cases/missRequiredFields.php b/workflow/engine/templates/cases/missRequiredFields.php new file mode 100644 index 000000000..9832af781 --- /dev/null +++ b/workflow/engine/templates/cases/missRequiredFields.php @@ -0,0 +1,82 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification 30/05/2008 + */ + + + + $width_content = '430px'; + + $html = ' +
    +
    + + + + +
    '.G::LoadTranslation('ID_ERROR').'! '.G::LoadTranslation('ID_REQUIRED_FIELDS_ERROR').'
    +
    +
    '; + + $rq = $_POST['req_val']; + foreach( $rq as $field) { + $html .= " + +
    + (*) The field $field is required! +
    "; + } + + $netxpage = $_POST['next_step']['PAGE']; + $previouspage = $_POST['previous_step']['PAGE']; + + $html .= '
    '; + $html .= ''; + $html .= ''; + + + echo '
    +
    +
    + + + + +
    + '.$html.' +
    +
    +
    +
    '; + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/paged-table-inputDocuments.html b/workflow/engine/templates/cases/paged-table-inputDocuments.html new file mode 100755 index 000000000..49a3991b5 --- /dev/null +++ b/workflow/engine/templates/cases/paged-table-inputDocuments.html @@ -0,0 +1,186 @@ + +
    +
    +
    + + + + +
    + + +
    + +
    +
    + + + + +
    + + + + +
    + + + + +
    +
    + + {PREVIOUS_STEP_LABEL} +
    +
    +
    + + {NEXT_STEP_LABEL} +
    + +
    +
    +
    +
    + +
    + +
    + + + + + {title} +

    + + + + + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/paged-table-reassigByUser.html b/workflow/engine/templates/cases/paged-table-reassigByUser.html new file mode 100755 index 000000000..653160bc9 --- /dev/null +++ b/workflow/engine/templates/cases/paged-table-reassigByUser.html @@ -0,0 +1,157 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + {labels:CHECK_ALL} /  + {labels:UNCHECK_ALL} /  + {labels:ID_REASSIGN} + +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/paged-table-reassigByUser2.html b/workflow/engine/templates/cases/paged-table-reassigByUser2.html new file mode 100755 index 000000000..e9d20bd70 --- /dev/null +++ b/workflow/engine/templates/cases/paged-table-reassigByUser2.html @@ -0,0 +1,158 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    +
    +
    +
    + + + + + + + +
    + {labels:ID_ROWS} {totalRows}  + + {first}{prev}{next}{last} + + + + +
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/paged-table-reassign.html b/workflow/engine/templates/cases/paged-table-reassign.html new file mode 100644 index 000000000..512ab07a3 --- /dev/null +++ b/workflow/engine/templates/cases/paged-table-reassign.html @@ -0,0 +1,164 @@ +
    + +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +   + +
    + +
    +
    +
    +
    + + + + +
    + + + + \ No newline at end of file diff --git a/workflow/engine/templates/cases/reassignList.js b/workflow/engine/templates/cases/reassignList.js new file mode 100644 index 000000000..450f0731d --- /dev/null +++ b/workflow/engine/templates/cases/reassignList.js @@ -0,0 +1,77 @@ + + var proxyUsersToReassignList = new Ext.data.HttpProxy({ + api: { + read : 'proxyReassignUsersList' + } + }); + + var readerUsersToReassignList = new Ext.data.JsonReader({ + //totalProperty: 'totalCount', + //successProperty: 'success', + //idProperty: 'index', + root: 'data', + fields: [ + // map Record's 'firstname' field to data object's key of same name + {name: 'userUid', mapping: 'userUid'}, + // map Record's 'job' field to data object's 'occupation' key + {name: 'userFullname', mapping: 'userFullname'} + ] + + //messageProperty: 'message' + } + ); + + + // The new DataWriter component. + //currently we are not using this in casesList, but it is here just for complete definition + var writerUsersToReassignList = new Ext.data.JsonWriter({ + encode: true, + writeAllFields: true + }); + + + var storeUsersToReassign = new Ext.data.Store({ + remoteSort: false, + proxy : proxyUsersToReassignList, + reader: readerUsersToReassignList, + writer: writerUsersToReassignList, // <-- plug a DataWriter into the store just as you would a Reader + autoSave: false // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton. + }); + + Ext.util.Format.comboRenderer = function(combo){ + return function(value){ + var record = combo.findRecord(combo.valueField, value); + //getting the parent gridpanel. + /*var gp = combo.findParentBy ( + function (ct, cmt) {return (ct instanceof Ext.grid.GridPanel) ? true : false;} + );*/ + + //storeUsersToReassign.load(); + //alert(gp); + // var record = array(); + return record ? record.get(combo.displayField) : combo.valueNotFoundText; + } + } + + // create the combo instance + var comboUsersToReassign = new Ext.form.ComboBox({ + //typeAhead : true, + fieldLabel : 'Reassign to', + triggerAction : 'all', + width : '150', + //lazyRender : true, +// store : new Ext.data.Store(), + store : storeUsersToReassign, + listeners:{ + 'select': function(comp, record, index) { + var row = Ext.getCmp('TasksToReassign').getSelectionModel().getSelected(); + row.set('APP_REASSIGN_USER_UID', record.get('userUid')); + row.set('APP_REASSIGN_USER', record.get('userFullname')); + this.setValue(record.get('userFullname')); + } + }, + valueField : 'userId', + displayField : 'userFullname' + }); + +//alert (this.fields.); \ No newline at end of file diff --git a/workflow/engine/templates/cases/showDebugFrame.php b/workflow/engine/templates/cases/showDebugFrame.php new file mode 100644 index 000000000..8327a02f8 --- /dev/null +++ b/workflow/engine/templates/cases/showDebugFrame.php @@ -0,0 +1,261 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * New Debugger interface + * + * @author Erik A. O. + * @Date Wed Mar 17th. 2010 + */ + +G::LoadClass('case'); + +//variables +$oApp= new Cases(); +$aFields = $oApp->loadCase($_SESSION['APPLICATION']); +$aStoredVarNames = array_keys($aFields['APP_DATA']); + +$aVariables = Array(); +for($i=0; $i".strtolower($aTrigger['TIME'])."
    "; + + $cnt = 0; + if(isset($aTrigger['TRIGGERS_NAMES'])) { + foreach($aTrigger['TRIGGERS_NAMES'] as $name) { + $t_code = $aTrigger['TRIGGERS_VALUES'][$cnt]['TRI_WEBBOT']; + //$t_code = str_replace('"', '\'',$t_code); + //$t_code = addslashes($t_code); + $t_code = Only1br($t_code); + + $triggers_name[] = $name; + $triggers_code[] = $t_code; + $cnt++; + } + } + } else { + $triggers_onfly = " No triggers found ".strtolower($t_time).""; + } +} + +//errors +$DEBUG_POST = array_unique($_SESSION['TRIGGER_DEBUG']['ERRORS']); + +///// + +function Only1br($string) { + return preg_replace("/(\r\n)+|(\n|\r)+/", "
    ", $string); +} + +?> + + + +
    Processmaker - Debugger
    + +
    Triggers
    +
    + + + + +
    +
    + 0 ) {?> + + + + + $trigger) {?> + + + + + + +
    #Name 
       +   +
    +
    + + + +
    + +
    +
    + + +
    Variables
    +
    + + + + + $aVariable) {?> + + + + + + + + + +
    NameValue
      
    +
    + + + 0 ) {?> +
    Errors
    +
    + + + + Error + ', '',$DEBUG_POST[$i]['ERROR'])?> +
    + + + + Fatal error + ', '',$DEBUG_POST[$i]['FATAL'])?> +
    + +
    No errors reported
    + +
    + + + + + + + + +
    "; + foreach($a as $k=>$v) { + echo ""; + } + echo "
     $k"; + expandVarView($v, "{$name}_{$k}"); + echo "
    "; + } else { + echo ($a=='')? ' ': " $a"; + } + +} + +?> \ No newline at end of file diff --git a/workflow/engine/templates/cases/showDebugFrameBreaker.php b/workflow/engine/templates/cases/showDebugFrameBreaker.php new file mode 100644 index 000000000..27185fd4d --- /dev/null +++ b/workflow/engine/templates/cases/showDebugFrameBreaker.php @@ -0,0 +1,4 @@ + +
    Processmaker - Debugger (Break Point)     +
    + diff --git a/workflow/engine/templates/cases/showDebugFrameLoader.php b/workflow/engine/templates/cases/showDebugFrameLoader.php new file mode 100644 index 000000000..2a54ba723 --- /dev/null +++ b/workflow/engine/templates/cases/showDebugFrameLoader.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/workflow/engine/templates/cases/showStep.html b/workflow/engine/templates/cases/showStep.html new file mode 100644 index 000000000..ef6d79dd6 --- /dev/null +++ b/workflow/engine/templates/cases/showStep.html @@ -0,0 +1,2 @@ +
    +
    diff --git a/workflow/engine/templates/dashboard/frontend.html b/workflow/engine/templates/dashboard/frontend.html new file mode 100755 index 000000000..e09f6520f --- /dev/null +++ b/workflow/engine/templates/dashboard/frontend.html @@ -0,0 +1,35 @@ +
    +
    +
    +
    +
    +
    +
    + + + + +
    + + + + +
    + + + + +
    + + {$ID_NEW} +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/workflow/engine/templates/dbConnections/dbConnections.php b/workflow/engine/templates/dbConnections/dbConnections.php new file mode 100644 index 000000000..9c22aaf1a --- /dev/null +++ b/workflow/engine/templates/dbConnections/dbConnections.php @@ -0,0 +1,113 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification 30/05/2008 + */ + + G::LoadClass('tree'); + G::LoadClass('net'); + $host = new net($_POST['server']); + $width_content = '430px'; + + $html = ' +
    +
    + + + + +
    '.G::loadTranslation('DBCONNECTIONS_TITLE').'
    +
    +
    + '; + + $port = $_POST['port']; + if( $port == 'default' ){ + //setting defaults ports + switch ($_POST['type']){ + case 'mysql': $port = 3306; break; + case 'pgsql': $port = 5432; break; + case 'mssql': $port = 1433; break; + case 'oracle': $port = 1521; break; + } + $_POST['port'] = $port; + $port = "default ($port)"; + } + + $tests = Array('', + G::loadTranslation('ID_HOST_NAME').' '.$_POST['server'].'', + G::loadTranslation('ID_CHECK_PORT').' '.$port.'', + G::loadTranslation('ID_CONNECT_HOST').' '.$host->ip.':'.$_POST['port'].'', + G::loadTranslation('ID_OPEN_DB').'['.$_POST['db_name'].'] '.G::loadTranslation('ID_IN').' '.$_POST['type'].' '.G::loadTranslation('ID_SERVICE') + ); + + $n = Array('','uno','dos','tres','cuatro','cinco'); + + for($i=1; $i +
    +
    $tests[$i]
    +
    + +
    +
    + "; + } + + echo '
    +
    +
    + + + + +
    + '.$html.' +
    +
    +
    +
    '; + + + print ("
    "); + print (""); + \ No newline at end of file diff --git a/workflow/engine/templates/departments/departments_Tree.html b/workflow/engine/templates/departments/departments_Tree.html new file mode 100644 index 000000000..bbc5cd559 --- /dev/null +++ b/workflow/engine/templates/departments/departments_Tree.html @@ -0,0 +1,91 @@ + +
    +
    + +
    + + + + +
    +
    +
    + + + + +
    {ID_DEPARTMENTS_USERS}
    +
    +
    + +
    + + + + + + + + + +
    + + + + + + + + +
    + + {DEPO_TITLE}
    +
     [{ID_EDIT}] [{ID_NEW}]   + + [{ID_DELETE}] + +
    +
    +
    +
    + +
    +
    + + diff --git a/workflow/engine/templates/departments/departments_Tree.php b/workflow/engine/templates/departments/departments_Tree.php new file mode 100644 index 000000000..5254a9f00 --- /dev/null +++ b/workflow/engine/templates/departments/departments_Tree.php @@ -0,0 +1,101 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + require_once 'classes/model/Department.php'; + + $WIDTH_PANEL = 380; + global $xVar; + global $template; + global $lastDept; + + $xVar = 1; + $lastDept = array(); + + $departmentsTreeTemplate = PATH_TPL . 'departments' . PATH_SEP . 'departments_Tree.html' ; + $template = new TemplatePower( $departmentsTreeTemplate ); + $template->prepare(); + $template->assign( 'WIDTH_PANEL', $WIDTH_PANEL ); + $template->assign( 'WIDTH_PANEL_20', $WIDTH_PANEL - 10 ); + $template->assign( 'ID_DEPARTMENTS_USERS', G::loadTranslation("ID_DEPARTMENTS_USERS") ); + $template->assign( 'ID_NEW_DEPARTMENT', G::loadTranslation("ID_NEW") ); + + + + //this is to show the link Unassigned Users + $template->assign( 'ADD_UNASSIGNEDUSER', G::loadTranslation("ID_UNASSIGNED_USERS") ); + + $htmlDpto = lookforchildren( '' , 0); + + $content = $template->getOutputContent(); + print $content; + +//function lookforchildren( $level, $template, $alloDeptos){ +function lookforchildren( $parent, $level){ + global $xVar; + global $template; + global $lastDept; + $oDept = new Department(); + $allDepartments = $oDept->getDepartments ( $parent ); + + $level = $level + 1; + if (!isset($lastDept[$level] ) ) $lastDept[$level] = true; + $lastDept[$level] = true; + + foreach( $allDepartments as $department ) { + $xVar++; + $depUID = htmlentities( $department['DEP_UID'] ); + $depTitle = strip_tags( $department['DEP_TITLE'] ); + + $template->newBlock( 'department'); + $template->assign( 'xVar', $xVar ); + $template->assign( 'UID', $depUID ); + $template->assign( 'DEPO_TITLE', $depTitle ); + $template->assign( 'ID_EDIT', G::LoadTranslation('ID_EDIT') ); + $template->assign( 'ID_MEMBERS', G::LoadTranslation('ID_MEMBERS') ); + $template->assign( 'ID_NEW', G::loadTranslation("ID_NEW") ); + for ($iLevel = 2; $iLevel <= $level; $iLevel ++ ) { + $template->newBlock( 'level'); + $template->assign( 'UID', $iLevel); + if ( $iLevel == $level ) { + if ( $department['DEP_LAST'] ) $lastDept[ $level] = false; + $template->assign( 'image', $department['DEP_LAST'] == 0 ? 'ftv2node' : 'ftv2lastnode'); + $template->assign( 'background', $department['DEP_LAST'] == 0 ? 'ftv2vertline' : 'ftv2blank'); + } + else { + $template->assign( 'image', 'ftv2blank'); + $template->assign( 'background', $lastDept[$iLevel] ? 'ftv2vertline' : 'ftv2blank'); + } + } + if ( $department['HAS_CHILDREN'] == 0) { + $template->newBlock( 'delete'); + $template->assign( 'UID', $depUID ); + $template->assign( 'ID_DELETE', G::LoadTranslation('ID_DELETE') ); + } + lookforchildren( $depUID, $level); + } + + return ; +} diff --git a/workflow/engine/templates/departments/departments_userList.html b/workflow/engine/templates/departments/departments_userList.html new file mode 100644 index 000000000..82fb15cdb --- /dev/null +++ b/workflow/engine/templates/departments/departments_userList.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/workflow/engine/templates/departments/paged-table.html b/workflow/engine/templates/departments/paged-table.html new file mode 100644 index 000000000..5bdbd923f --- /dev/null +++ b/workflow/engine/templates/departments/paged-table.html @@ -0,0 +1,201 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + {labels:CHECK_ALL} /  + {labels:UNCHECK_ALL} /  + {labels:ID_ASSIGN} + +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + diff --git a/workflow/engine/templates/departments/paged-table2.html b/workflow/engine/templates/departments/paged-table2.html new file mode 100644 index 000000000..9a08ce73e --- /dev/null +++ b/workflow/engine/templates/departments/paged-table2.html @@ -0,0 +1,138 @@ + +
    +
    +
    + + + + +
    + {title} +

    + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/departments/paged-table3.html b/workflow/engine/templates/departments/paged-table3.html new file mode 100755 index 000000000..9b72f53f7 --- /dev/null +++ b/workflow/engine/templates/departments/paged-table3.html @@ -0,0 +1,201 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/dummyTemplate.html b/workflow/engine/templates/dummyTemplate.html new file mode 100755 index 000000000..c6d8d0c2f --- /dev/null +++ b/workflow/engine/templates/dummyTemplate.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/workflow/engine/templates/dynaforms/fieldsHandler.php b/workflow/engine/templates/dynaforms/fieldsHandler.php new file mode 100755 index 000000000..09c4fe476 --- /dev/null +++ b/workflow/engine/templates/dynaforms/fieldsHandler.php @@ -0,0 +1,218 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz + * @Date Aug 26th, 2009 + */ +?> + + + + + + + + + +result['dynaForm']['__CONTENT__']) ){ +?> +
    +
    + +
    + +result['dynaForm']['__CONTENT__']; + $dynaformAttributes = $oXxml->result['dynaForm']['__ATTRIBUTES__']; + + $dynaformType = $dynaformAttributes['type']; + + foreach($elements as $node_name=>$node){ + if( $node_name == "___pm_boot_strap___"){ + $boot_strap = $elements[$node_name]; + $hidden_fields = G::decrypt($boot_strap['__ATTRIBUTES__']['meta'], 'dynafieldsHandler'); + //echo $hidden_fields; + $hidden_fields_list = explode(',', $hidden_fields); + unset($elements[$node_name]); + } + } +?> + + + + + + + +
    + + + +
    + +
    +
    + + + + + +
     
     
     
     
    +
    +
    +
    +
      + $node){ + if( isset($hidden_fields_list) ){ + $checked = !(in_array($node_name, $hidden_fields_list))? 'checked="checked"': ''; + } else { + $checked = 'checked="checked"'; + } + ?> +
    • + + + + + + + + + +
      + + /> + +   + + + + + + + + + +   + +   +

      + 30 ){ + $label = substr(trim(strip_tags(G::stripCDATA($node['__CONTENT__'][SYS_LANG]['__VALUE__']))), 0, 30 ) . '...'; + } else { + $label = $node['__CONTENT__'][SYS_LANG]['__VALUE__']; + } + print($label); + } else { + print(" "); + } + ?>

      +
      + + +
      + + +
      + +
      + + +
      +
    • + +
    +
    +
    +

    +
    + +
    + + + + diff --git a/workflow/engine/templates/dynaforms/fieldsHandlerViewer.php b/workflow/engine/templates/dynaforms/fieldsHandlerViewer.php new file mode 100755 index 000000000..b18d0f9da --- /dev/null +++ b/workflow/engine/templates/dynaforms/fieldsHandlerViewer.php @@ -0,0 +1,112 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /* + * @Author Erik Amaru Ortiz + * @Date Aug 26th, 2009 + */ + +?> + + +
    + +
    + + + diff --git a/workflow/engine/templates/events/sendMessage.tpl b/workflow/engine/templates/events/sendMessage.tpl new file mode 100644 index 000000000..f3fa7a1cc --- /dev/null +++ b/workflow/engine/templates/events/sendMessage.tpl @@ -0,0 +1,21 @@ +/* + * Autogenerated by Processmaker Daemon System + * + * Generic Send Message trigger + * {timestamp} + */ + +$sRecipientTO = "{TO}"; +$sRecipientCC = "{CC}"; +$sRecipientBCC = "{BCC}"; + +/*Composing the message using PMFgetUserEmailAddress() PM function*/ +$from = '{from}'; +$to = PMFgetUserEmailAddress($sRecipientTO, @@APPLICATION); +$cc = PMFgetUserEmailAddress($sRecipientCC, @@APPLICATION); +$bcc = PMFgetUserEmailAddress($sRecipientBCC, @@APPLICATION); +$subject = '{subject}'; +$template = '{template}'; + +/*send using PMFSendMessage() PM function*/ +PMFSendMessage(@@APPLICATION, $from, $to, $cc, $bcc, $subject, $template); \ No newline at end of file diff --git a/workflow/engine/templates/filterform.html b/workflow/engine/templates/filterform.html new file mode 100644 index 000000000..dc39fd299 --- /dev/null +++ b/workflow/engine/templates/filterform.html @@ -0,0 +1,129 @@ +{if $printTemplate} +{* this is the xmlform template *} +
    + + + + +{foreach from=$form->fields item=field} +{if ($field->type==='hidden')} + {$field->field} +{elseif ($field->type==='javascript')} + +{/if} +{/foreach} +
    +{/if} +{if $printJSFile} +var form_{$form->id}; +var i; +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('form[{$form->id}]'),'{$form->id}'); + var myForm=form_{$form->id}; + myForm.ajaxServer=ajaxServer; + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if ($field->type==='dropdown')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} +{/if} +{if $printJavaScript} +leimnud.event.add(window,'load',function(){literal}{{/literal}loadForm_{$form->id}('{$form->ajaxServer}');{literal}}{/literal}); +{/if} diff --git a/workflow/engine/templates/form.html b/workflow/engine/templates/form.html new file mode 100644 index 000000000..6b491379d --- /dev/null +++ b/workflow/engine/templates/form.html @@ -0,0 +1,152 @@ +{if $printTemplate} +{* this is the xmlform template *} +
    + + +
    + + +
    +{if isset($form->title) && $form->title !=='' } + + + + +
    {$form->title}
    +{/if} + +{foreach from=$form->fields item=field} +{if ($field->type==='title')} + + + +{elseif ($field->type==='subtitle')} + + + +{elseif ($field->type==='button') || ($field->type==='submit') || ($field->type==='reset')} +{elseif ($field->type==='grid')} + + + +{elseif ($field->type==='checkbox')} + + + + +{elseif ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} + + + +{elseif ($field->type==='')} +{elseif ($field->withoutLabel)} + + + +{else} + + + + +{/if} +{/foreach} +
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->label}{$field->field}
    +
    +
    + + {foreach from=$form->fields item=field} + {if ($field->type==='button') || ($field->type==='submit') || ($field->type==='reset')} + + + + {/if} + {/foreach} +
    {$field->field}
    +
    +{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +
    +{/if} +{if $printJSFile} +var form_{$form->id}; +var i; +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('{$form->id}'),'{$form->id}'); + var myForm=form_{$form->id}; + myForm.ajaxServer=ajaxServer; + //{$form->ajaxSubmit} + {if isset($form->ajaxSubmit) && ($form->ajaxSubmit)} + {literal} + var sub = new leimnud.module.app.submit({ + form : myForm.element + }); + sub.sendObj = false; + {/literal} + {/if} + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if ($field->type==='dropdown')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='hidden')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} +{/if} +{if $printJavaScript} +leimnud.event.add(window,'load',function(){literal}{{/literal}loadForm_{$form->id}('{$form->ajaxServer}');{literal}}{/literal}); +{/if} diff --git a/workflow/engine/templates/grid.html b/workflow/engine/templates/grid.html new file mode 100644 index 000000000..021929090 --- /dev/null +++ b/workflow/engine/templates/grid.html @@ -0,0 +1,113 @@ +{if $printTemplate} +{* this is the grid template *} +
    +
    +
    + + + + +
    {$form->label} +
    + + +
    +{if ($form->addRow) } + + + + +
     {$form->NewLabel}
    +{/if} + + + +{foreach from=$form->fields item=field} + +{/foreach} + +{literal} +{section name=row loop=$form_rows} +{if ($smarty.section.row.index==0)} + +{else} + +{/if} + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} +{if $form->deleteRow == '1' } + +{/if} +{if ($form->editRow=='1')} + +{/if} +{literal} + +{/section} +{* TOTALIZABLE ROW *} + + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} +{literal} + +{/literal} +
    {if (isset($field->required)&&$field->required&&$field->mode==='edit')}* {/if}{$field->label}
    {$smarty.section.row.index+1} {$field->field}{$form->DeleteLabel} edit"{$form->editRow}"
    + {if isset($field->function) && $field->function!=='' } + {if $field->function=='sum'} + Σ = {$field->aggregate} + {elseif $field->function=='avg'} + x = {$field->aggregate} + {/if} + {/if} +
    +
    +
    +
    +
    +{/if} +{if $printJSFile} +function grid_{$form->id}(myGrid) +{literal}{{/literal} + {* setFunctions: Define the aggregate functions *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFunctions([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->function)&& $field->function!==''} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sFunction: '{$field->function}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/if} + {/foreach} + ]); + {* setFormulas: Define the customs formulas *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFormulas([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->formula)} + {foreach from=$field->dependentOf() item=dependentOf name=foreachDependent} + {if !$firstfield},{/if} + {literal}{{/literal} sDependentOf: '{$dependentOf}', sFieldName: '{$field->name}', sFormula: '{$field->formula}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + {/if} + {/foreach} + ]); + {* setFields: Define the controles's javascript *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFields([ + {foreach from=$form->fields item=field name=foreachField} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sType: '{$field->type}', oProperties:{$field->getAttributes()}, oEvents:{$field->getEvents()}{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + ]); +{literal}}{/literal} +{/if} +{if $printJavaScript} +{/if} diff --git a/workflow/engine/templates/grid_preview.html b/workflow/engine/templates/grid_preview.html new file mode 100755 index 000000000..950010a9c --- /dev/null +++ b/workflow/engine/templates/grid_preview.html @@ -0,0 +1,114 @@ +{if $printTemplate} +{* this is the grid template *} +
    +
    +
    + + + + +
    {$form->label} +
    + + +
    +{if ($form->addRow) } + + + + +
     {$form->NewLabel}
    +{/if} + + + +{foreach from=$form->fields item=field} + + +{/foreach} + +{literal} +{section name=row loop=$form_rows} +{if ($smarty.section.row.index==0)} + +{else} + +{/if} + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} +{if $form->deleteRow == '1' } + +{/if} +{if ($form->editRow=='1')} + +{/if} +{literal} + +{/section} +{* TOTALIZABLE ROW *} + + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} +{literal} + +{/literal} +
    {if (isset($field->required)&&$field->required&&$field->mode==='edit')}* {/if}{$field->label}
    {$smarty.section.row.index+1} {$field->field}{$form->DeleteLabel} edit"{$form->editRow}"
    + {if isset($field->function) && $field->function!=='' } + {if $field->function=='sum'} + Σ = {$field->aggregate} + {elseif $field->function=='avg'} + ¯X = {$field->aggregate} + {/if} + {/if} +
    +
    +
    +
    +
    +{/if} +{if $printJSFile} +function grid_{$form->id}(myGrid) +{literal}{{/literal} + {* setFunctions: Define the aggregate functions *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFunctions([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->function)&& $field->function!==''} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sFunction: '{$field->function}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/if} + {/foreach} + ]); + {* setFormulas: Define the customs formulas *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFormulas([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->formula)} + {foreach from=$field->dependentOf() item=dependentOf name=foreachDependent} + {if !$firstfield},{/if} + {literal}{{/literal} sDependentOf: '{$dependentOf}', sFieldName: '{$field->name}', sFormula: '{$field->formula}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + {/if} + {/foreach} + ]); + {* setFields: Define the controles's javascript *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFields([ + {foreach from=$form->fields item=field name=foreachField} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sType: '{$field->type}', oProperties:{$field->getAttributes()}, oEvents:{$field->getEvents()}{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + ]); +{literal}}{/literal} +{/if} +{if $printJavaScript} +{/if} diff --git a/workflow/engine/templates/grid_view.html b/workflow/engine/templates/grid_view.html new file mode 100755 index 000000000..8aca285c5 --- /dev/null +++ b/workflow/engine/templates/grid_view.html @@ -0,0 +1,108 @@ +{if $printTemplate} +{* this is the grid template *} +
    +
    +
    + + + + +
    {$form->label} +
    + + +
    +{if ($form->addRow) } + + + + +
    +{/if} + + + +{foreach from=$form->fields item=field} + +{/foreach} + +{literal} +{section name=row loop=$form_rows} +{if ($smarty.section.row.index==0)} + +{else} + +{/if} + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} + +{literal} + +{/section} +{* TOTALIZABLE ROW *} + + +{/literal} +{foreach from=$form->fields item=field} + +{/foreach} +{literal} + +{/literal} +
       {$field->label}
    {$smarty.section.row.index+1}  {$field->field}
    + {if isset($field->function) && $field->function!=='' } + {if $field->function=='sum'} + Σ = {$field->aggregate} + {elseif $field->function=='avg'} + ¯X = {$field->aggregate} + {/if} + {/if} +
    +
    +
    +
    +
    +{/if} +{if $printJSFile} +function grid_{$form->id}(myGrid) +{literal}{{/literal} + {* setFunctions: Define the aggregate functions *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFunctions([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->function)&& $field->function!==''} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sFunction: '{$field->function}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/if} + {/foreach} + ]); + {* setFormulas: Define the customs formulas *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFormulas([ + {foreach from=$form->fields item=field name=foreachField} + {if isset($field->formula)} + {foreach from=$field->dependentOf() item=dependentOf name=foreachDependent} + {if !$firstfield},{/if} + {literal}{{/literal} sDependentOf: '{$dependentOf}', sFieldName: '{$field->name}', sFormula: '{$field->formula}'{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + {/if} + {/foreach} + ]); + {* setFields: Define the controles's javascript *} + {php}$this->assign('firstfield', true);{/php} + myGrid.setFields([ + {foreach from=$form->fields item=field name=foreachField} + {if !$firstfield},{/if} + {literal}{{/literal}sFieldName: '{$field->name}', sType: '{$field->type}', oProperties:{$field->getAttributes()}, oEvents:{$field->getEvents()}{literal}}{/literal} + {php}$this->assign('firstfield', false);{/php} + {/foreach} + ]); +{literal}}{/literal} +{/if} +{if $printJavaScript} +{/if} diff --git a/workflow/engine/templates/groups/groups_Tree.php b/workflow/engine/templates/groups/groups_Tree.php new file mode 100644 index 000000000..53a2edc13 --- /dev/null +++ b/workflow/engine/templates/groups/groups_Tree.php @@ -0,0 +1,97 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + //G::LoadClass('group'); + + $WIDTH_PANEL = 350; + + G::LoadClass('groups'); + + $groups = new Groups(); + + $allGroups= $groups->getAllGroups(); + $xVar = 1; + $html = ''; + $htmlGroup = ""; + foreach($allGroups as $group) { + + $RowClass = ($xVar%2==0)? 'Row1': 'Row2'; + $xVar++; + $ID_EDIT = G::LoadTranslation('ID_EDIT'); + $ID_MEMBERS = G::LoadTranslation('ID_MEMBERS'); + $ID_DELETE = G::LoadTranslation('ID_DELETE'); + $UID = htmlentities($group->getGrpUid()); + //$GROUP_TITLE = htmlentities($group->getGrpTitle()); + $GROUP_TITLE = strip_tags($group->getGrpTitle()); + $htmlGroup .=" + + + + + + + "; + } + $htmlGroup .= "
    {$GROUP_TITLE}[{$ID_EDIT}][{$ID_MEMBERS}][{$ID_DELETE}]
    "; + + echo '
    +
    +
    + + + + +
    +
    +
    + + + + +
    '.G::loadTranslation("ID_GROUPS").'
    +
    +
    + + + +
    +
    ' + .$htmlGroup. + '
    +
    +
    +
    +
    +
    '; + ?> + diff --git a/workflow/engine/templates/groups/groups_usersList.html b/workflow/engine/templates/groups/groups_usersList.html new file mode 100644 index 000000000..82fb15cdb --- /dev/null +++ b/workflow/engine/templates/groups/groups_usersList.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/workflow/engine/templates/groups/paged-table.html b/workflow/engine/templates/groups/paged-table.html new file mode 100755 index 000000000..5bdbd923f --- /dev/null +++ b/workflow/engine/templates/groups/paged-table.html @@ -0,0 +1,201 @@ + +
    +
    +
    +
    + + + + +
    + + {title} + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + {labels:CHECK_ALL} /  + {labels:UNCHECK_ALL} /  + {labels:ID_ASSIGN} + +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + diff --git a/workflow/engine/templates/groups/paged-table2.html b/workflow/engine/templates/groups/paged-table2.html new file mode 100755 index 000000000..5fe8bc95e --- /dev/null +++ b/workflow/engine/templates/groups/paged-table2.html @@ -0,0 +1,138 @@ + +
    +
    +
    + + + + +
    + {title} +

    + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/image.php b/workflow/engine/templates/image.php new file mode 100644 index 000000000..807f4ea89 --- /dev/null +++ b/workflow/engine/templates/image.php @@ -0,0 +1,35 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //usado en workflows... + global $G_IMAGE_FILENAME; + global $CURRENT_PAGE; + global $links; + global $G_CONTENT; + $aux = explode ( '/', $_SERVER['REQUEST_URI'] ); + $aux[ count($aux) -1 ] = $G_IMAGE_FILENAME; + $imgFile = implode ( '/', $aux ) ; + print ""; +?> + diff --git a/workflow/engine/templates/javaBridgePM/classic.xml b/workflow/engine/templates/javaBridgePM/classic.xml new file mode 100755 index 000000000..522d8bca4 --- /dev/null +++ b/workflow/engine/templates/javaBridgePM/classic.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + <band height="50" > + <line> + <reportElement x="0" y="6" width="555" height="1"/> + </line> + <line> + <reportElement positionType="FixRelativeToBottom" x="0" y="47" width="555" height="1"/> + </line> + <image> + <reportElement x="2" y="13" width="152" height="28"/> + <imageExpression class="java.lang.String"><![CDATA["{logoReporte}"]]></imageExpression> + </image> + <staticText> + <reportElement x="110" y="10" width="424" height="35"/> + <textElement textAlignment="Center"> + <font size="26" isBold="true"/> + </textElement> + <text><![CDATA[{tableName} Report]]></text> + </staticText> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/templates/javaBridgePM/out.jrxml b/workflow/engine/templates/javaBridgePM/out.jrxml new file mode 100644 index 000000000..701f1a32b --- /dev/null +++ b/workflow/engine/templates/javaBridgePM/out.jrxml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + <band height="50" > + <line> + <reportElement x="0" y="6" width="555" height="1"/> + </line> + <line> + <reportElement positionType="FixRelativeToBottom" x="0" y="47" width="555" height="1"/> + </line> + <image> + <reportElement x="2" y="13" width="152" height="28"/> + <imageExpression class="java.lang.String"><![CDATA["http://fernando.opensource.colosa.net/images/processmaker.logo.jpg"]]></imageExpression> + </image> + <staticText> + <reportElement x="110" y="10" width="424" height="35"/> + <textElement textAlignment="Center"> + <font size="26" isBold="true"/> + </textElement> + <text><![CDATA[Credit Card Application Form Report]]></text> + </staticText> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/templates/login/init.js b/workflow/engine/templates/login/init.js new file mode 100644 index 000000000..c0f129a4d --- /dev/null +++ b/workflow/engine/templates/login/init.js @@ -0,0 +1,14 @@ +Ext.onReady(function(){ + location.href = uriReq; + + var hideMask = function () { + Ext.get('loading').remove(); + Ext.fly('loading-mask').fadeOut({ + remove:true, + callback : '' + }); + } + + hideMask.defer(250); + +}); diff --git a/workflow/engine/templates/login/showDBFiles.php b/workflow/engine/templates/login/showDBFiles.php new file mode 100644 index 000000000..31682bdd9 --- /dev/null +++ b/workflow/engine/templates/login/showDBFiles.php @@ -0,0 +1,113 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $path = PATH_DB; + //using the opendir function + if ( ! $dir_handle = @opendir( PATH_DB )) + { + header ("location: /errors/error704.php"); + die; + } + + + echo ""; + echo ""; + echo ""; + $curPage = getenv( "REQUEST_URI" ); + //running the while loop + $first = 0; + while ($file = readdir($dir_handle)) + { + if ( substr($file,0,3) == 'db_' ) { + if ( $first == 0 ) { + echo ""; + + $second = 0; + if ( ! $dir_handle = @opendir( PATH_DB )) + { + header ("location: /errors/error704.php"); + die; + } + + $DB_INDEX = 0; + $DB_MODULE = array(); + + while ($file = readdir($dir_handle)) + { + if ( substr($file,0,9) == 'dbmodule_' ) { + $module = substr ( substr($file,0, strlen($file)-4) , 9 ); + require_once ( PATH_DB . $file ); + $moduleName = $DB_MODULE[$DB_INDEX]['name']; + echo ""; + } + } + //closing the directory + closedir($dir_handle); + + print "
    Please select a valid workspace to continue
    "; + $first = 1; + } + $name = substr ( substr($file,0, strlen($file)-4) , 3 ); + $link = str_replace ( "/sys/", "/sys$name/" , $curPage ); + echo ""; + } + } + //closing the directory + closedir($dir_handle); + if ( $first != 0 ) print "
    RBAC built-in workspaces
  • $name

  • "; + + if ( $DB_MODULE[$DB_INDEX]['type'] == 'single-file' ) { + $third = 0; + if ( ! $module_handle = @opendir( $DB_MODULE[$DB_INDEX]['path'] )) { + echo ( 'error in this path ' . $DB_MODULE[$DB_INDEX]['path'] ); + } + else { + while ($moduleFile = readdir($module_handle)) { + if ( substr($moduleFile,0,3) == 'db_' ) { + $name = substr ( substr($moduleFile,0, strlen($moduleFile)-4) , 3 ); + $link = str_replace ( "/sys/", "/sys-$module-$name/" , $curPage ); + echo ""; + } + } + } + } + else { + $third = 0; + if ( ! $module_handle = @opendir( $DB_MODULE[$DB_INDEX]['path'] )) { + echo ( "" ); + } + else { + while ($moduleFile = readdir($module_handle)) { + $dbFile = $DB_MODULE[$DB_INDEX]['path'] . $moduleFile . '/db.php'; + if ( file_exists ($dbFile) && substr($moduleFile,0,1) != '.' ) { + $name = $moduleFile; + $link = str_replace ( "/sys/", "/sys-$module-$name/" , $curPage ); + echo ""; + } + } + } + } + print "
    RBAC Module : $moduleName
  • $name
  • Path invalid: " . $DB_MODULE[$DB_INDEX]['path'] ."
  • $name

  • "; + +?> \ No newline at end of file diff --git a/workflow/engine/templates/mails/alert_message.html b/workflow/engine/templates/mails/alert_message.html new file mode 100644 index 000000000..713d22388 --- /dev/null +++ b/workflow/engine/templates/mails/alert_message.html @@ -0,0 +1,16 @@ + + + + + + +
    ALERT MESSAGE
    +
    +
    + The Case @#APP_NUMBER, currently in the task @#TAS_TITLE, expired on @#DEL_TASK_DUE_DATE. +
    +
    +
    This Business Process is powered by ProcessMaker.
    + www.processmaker.com +
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/outputdocs/editJrxml.php b/workflow/engine/templates/outputdocs/editJrxml.php new file mode 100755 index 000000000..efb927841 --- /dev/null +++ b/workflow/engine/templates/outputdocs/editJrxml.php @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/outputdocs/htmlEditor.js b/workflow/engine/templates/outputdocs/htmlEditor.js new file mode 100644 index 000000000..0f94bb0c7 --- /dev/null +++ b/workflow/engine/templates/outputdocs/htmlEditor.js @@ -0,0 +1,164 @@ +var importOption; + +Ext.onReady(function(){ + + Ext.QuickTips.init(); + + // turn on validation errors beside the field globally + Ext.form.Field.prototype.msgTarget = 'side'; + + var bd = Ext.getBody(); + + importOption = new Ext.Action({ + text: _('ID_LOAD_FROM_FILE'), + iconCls: 'silk-add', + icon: '/images/import.gif', + handler: function(){ + var w = new Ext.Window({ + title: '', + width: 420, + height: 140, + modal: true, + autoScroll: false, + maximizable: false, + resizable: false, + + items: [ + new Ext.FormPanel({ + /*renderTo: 'form-panel',*/ + id:'uploader', + fileUpload: true, + width: 400, + frame: true, + title: _('ID_OUT_PUT_DOC_UPLOAD_TITLE'), + autoHeight: false, + bodyStyle: 'padding: 10px 10px 0 10px;', + labelWidth: 50, + defaults: { + anchor: '90%', + allowBlank: false, + msgTarget: 'side' + }, + items: [{ + xtype: 'fileuploadfield', + id: 'form-file', + emptyText: _('ID_SELECT_TEMPLATE_FILE'), + fieldLabel: _('ID_FILE'), + name: 'templateFile', + buttonText: '', + buttonCfg: { + iconCls: 'upload-icon' + } + }], + buttons: [{ + text: _('ID_UPLOAD'), + handler: function(){ + var uploader = Ext.getCmp('uploader'); + if(uploader.getForm().isValid()){ + uploader.getForm().submit({ + url: 'outputdocs_Ajax?action=setTemplateFile', + waitMsg: _('ID_UPLOADING_FILE'), + success: function(o, resp){ + w.close(); + + Ext.Ajax.request({ + url: 'outputdocs_Ajax?action=getTemplateFile&r='+Math.random(), + success: function(response){ + Ext.getCmp('OUT_DOC_TEMPLATE').setValue(response.responseText); + if(Ext.getCmp('OUT_DOC_TEMPLATE').getValue(response.responseText)=='') + Ext.Msg.alert(_('ID_ALERT_MESSAGE'), _('ID_INVALID_FILE')); + }, + failure: function(){}, + params: {request: 'getRows'} + }); + + }, + failure: function(o, resp){ + w.close(); + //alert('ERROR "'+resp.result.msg+'"'); + Ext.MessageBox.show({title: '', msg: resp.result.msg, buttons: + Ext.MessageBox.OK, animEl: 'mb9', fn: function(){}, icon: + Ext.MessageBox.ERROR}); + //setTimeout(function(){Ext.MessageBox.hide(); }, 2000); + } + }); + } + } + },{ + text: _('ID_CANCEL'), + handler: function(){ w.close(); } + }] + }) + ] + }); + w.show(); + } + }); + + + var top = new Ext.FormPanel({ + labelAlign: 'top', + frame:true, + title: '', + bodyStyle:'padding:5px 5px 0', + width: 790, + tbar:[importOption], + items: [ + { + xtype:'htmleditor', + id:'OUT_DOC_TEMPLATE', + fieldLabel:'Output Document Template', + height:300, + anchor:'98%' + }], + + buttons: [{ + text: _('ID_SAVE'), + handler: function(){ + Ext.Ajax.request({ + url: 'outputdocs_Save', + success: function(response){ + Ext.Msg.show({ + title: '', + msg: 'Saved Successfully', + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + }, + failure: function(){}, + params: { + 'form[OUT_DOC_UID]': OUT_DOC_UID, + 'form[OUT_DOC_TEMPLATE]':Ext.getCmp('OUT_DOC_TEMPLATE').getValue() + } + }); + } + },{ + text: 'Cancel', + handler: function(){ + var sInfo = navigator.userAgent.toLowerCase(); + if ( sInfo.indexOf('msie') != -1 ) + self.close(); + else + parent.outputdocsEditor.remove(); + } + }] + }); + + top.render(document.body); + + Ext.Ajax.request({ + url: 'outputdocs_Ajax?action=loadTemplateContent&r='+Math.random(), + success: function(response){ + Ext.getCmp('OUT_DOC_TEMPLATE').setValue(response.responseText); + }, + failure: function(){}, + params: {OUT_DOC_UID: OUT_DOC_UID} + }); + +}); + +function _(ID){ + return TRANSLATIONS[ID]; +} diff --git a/workflow/engine/templates/packCreator/methods/packCreator_Delete.php b/workflow/engine/templates/packCreator/methods/packCreator_Delete.php new file mode 100644 index 000000000..c7352ceda --- /dev/null +++ b/workflow/engine/templates/packCreator/methods/packCreator_Delete.php @@ -0,0 +1,39 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('{$pack->classFile}'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + ${$pack->name} = new {$pack->class}( $dbc ); + + if (!isset($_POST['{$pack->key}'])) return; + + ${$pack->name}->Delete( $_POST['{$pack->key}'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/methods/packCreator_Edit.php b/workflow/engine/templates/packCreator/methods/packCreator_Edit.php new file mode 100644 index 000000000..6f8b25dd4 --- /dev/null +++ b/workflow/engine/templates/packCreator/methods/packCreator_Edit.php @@ -0,0 +1,42 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('{$pack->classFile}'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + ${$pack->name} = new {$pack->class}( $dbc ); + ${$pack->name}->Fields['{$pack->key}']=(isset($_GET['{$pack->key}'])) ? urldecode($_GET['{$pack->key}']):'0'; + ${$pack->name}->Load( ${$pack->name}->Fields['{$pack->key}'] ); + ${$pack->name}->Fields['PRO_UID'] = isset(${$pack->name}->Fields['PRO_UID'])?${$pack->name}->Fields['PRO_UID']:$_GET['PRO_UID']; + + $G_PUBLISH = new Publisher(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', '{$pack->name}/{$pack->name}_Edit', '', ${$pack->name}->Fields , SYS_URI.'{$pack->name}/{$pack->name}_Save'); + + G::RenderPage( "publish" , "blank" ); +?> \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/methods/packCreator_List.php b/workflow/engine/templates/packCreator/methods/packCreator_List.php new file mode 100644 index 000000000..f197353d0 --- /dev/null +++ b/workflow/engine/templates/packCreator/methods/packCreator_List.php @@ -0,0 +1,46 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + $G_MAIN_MENU = 'processmaker'; + $G_SUB_MENU = 'processes'; + $G_ID_MENU_SELECTED = 'PROCESSES'; + $G_ID_SUB_MENU_SELECTED = '{$pack->name|upper}'; + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + //Hardcode: UID of the library by default + $PRO_UID='746B734DC23311'; + $G_PUBLISH = new Publisher; + $Fields=array( 'SYS_LANG' => SYS_LANG, + 'PRO_UID' => $PRO_UID ); + + $G_PUBLISH->AddContent('pagedtable', 'paged-table', '{$pack->name}/{$pack->name}_List', '', $Fields , '{$pack->name}_Save'); + + G::RenderPage( "publish" ); + +?> \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/methods/packCreator_Save.php b/workflow/engine/templates/packCreator/methods/packCreator_Save.php new file mode 100644 index 000000000..2b399607a --- /dev/null +++ b/workflow/engine/templates/packCreator/methods/packCreator_Save.php @@ -0,0 +1,38 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + //G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + + G::LoadClass('{$pack->classFile}'); + + $dbc = new DBConnection(); + $ses = new DBSession($dbc); + + ${$pack->name} = new {$pack->class}( $dbc ); + + if ($_POST['form']['{$pack->key}']==='') unset($_POST['form']['{$pack->key}']); + ${$pack->name}->Save( $_POST['form'] ); + +?> \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/xmlforms/packCreator_Edit.xml b/workflow/engine/templates/packCreator/xmlforms/packCreator_Edit.xml new file mode 100644 index 000000000..a6492440f --- /dev/null +++ b/workflow/engine/templates/packCreator/xmlforms/packCreator_Edit.xml @@ -0,0 +1,24 @@ + + + +{foreach from=$pack->fields item=field} +{if $field->type==='hidden'} +<{$field->name} type="hidden" showInTable="0"/> +{else} +<{$field->name} type="{$field->type}" {foreach from=$field->attributes item=attribute key=atribName}{$atribName}="{$attribute}" {/foreach}> +{$field->sql} + {$field->labelEN} + {$field->labelES} +name}> +{/if} +{/foreach} + + + Save + Guardar + + \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/xmlforms/packCreator_List.xml b/workflow/engine/templates/packCreator/xmlforms/packCreator_List.xml new file mode 100644 index 000000000..60d41d0e4 --- /dev/null +++ b/workflow/engine/templates/packCreator/xmlforms/packCreator_List.xml @@ -0,0 +1,37 @@ + + +{foreach from=$pack->fields item=field} +{if $field->showInTable}{if $field->type==='hidden'} +<{$field->name} type="hidden" showInTable="0"/> +{else} +<{$field->name} type="{$field->type}" {foreach from=$field->attributes item=attribute key=atribName}{$atribName}="{$attribute}" {/foreach}> +{$field->sql} + {$field->labelEN} + {$field->labelES} +name}> +{/if}{/if} +{/foreach} + + + + + + + Apply Filter + Filtrar + + + +function pagedTableFilter( form ) {literal}{{/literal} + @#PAGED_TABLE_ID.doFilter( form ); +{literal}}{/literal} + + \ No newline at end of file diff --git a/workflow/engine/templates/packCreator/xmlforms/packCreator_Options.xml b/workflow/engine/templates/packCreator/xmlforms/packCreator_Options.xml new file mode 100644 index 000000000..8f29e234a --- /dev/null +++ b/workflow/engine/templates/packCreator/xmlforms/packCreator_Options.xml @@ -0,0 +1,36 @@ + + + + + New + Nuevo + + +<{$pack->name}_Edit type="private" defaultValue="../{$pack->name}/{$pack->name}_Edit"/> +<{$pack->name}_Delete type="private" defaultValue="../{$pack->name}/{$pack->name}_Delete"/> + + +var currentPagedTable = @#PAGED_TABLE_ID; + function {$pack->name}Add(){literal}{{/literal} + popupWindow('@G::LoadXmlLabel(ID_NEW_{$pack->name|upper})', '@G::encryptlink(@#{$pack->name}_Edit)?PRO_UID=@%PRO_UID' , 500, 400); + {literal}}{/literal} + function {$pack->name}Edit( uid ) {literal}{{/literal} + popupWindow('@G::LoadXmlLabel(ID_EDIT_{$pack->name|upper})', '@G::encryptlink(@#{$pack->name}_Edit)?{$pack->key}='+ uid , 500, 400); + {literal}}{/literal} + function {$pack->name}Save( form ) {literal}{{/literal} + ajax_post( form.action, form, 'POST' ); + currentPopupWindow.remove(); + @#PAGED_TABLE_ID.refresh(); + {literal}}{/literal} + function {$pack->name}Delete( uid ) {literal}{{/literal} + ajax_function('@G::encryptlink(@#{$pack->name}_Delete)','','{$pack->key}='+uid,'POST'); + @#PAGED_TABLE_ID.refresh(); + {literal}}{/literal} + + + + + Search + Buscar + + \ No newline at end of file diff --git a/workflow/engine/templates/paged-table.html b/workflow/engine/templates/paged-table.html new file mode 100644 index 000000000..cebb842bc --- /dev/null +++ b/workflow/engine/templates/paged-table.html @@ -0,0 +1,143 @@ + +
    +
    +
    + + + + +
    + +
    {title}
    + + + + +
    {content}
    + + + + + + + + + + + + + + + + + + + + + + + + + + {value} + + + + + + + + + + + + + + + + + + + + + +
    + {header} +
    {value1}{value} 
      + {noRecordsFound}
      +
    + + + + + + + +
    + {labels:ID_ROWS} {firstRow}-{lastRow}/{totalRows}  + + {first}{prev}{next}{last} + {labels:ID_PAGE} {currentPage}/{totalPages}
    +
    + +
    +
    +
    +
    + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/popupMenu.html b/workflow/engine/templates/popupMenu.html new file mode 100644 index 000000000..12c5de466 --- /dev/null +++ b/workflow/engine/templates/popupMenu.html @@ -0,0 +1,49 @@ +{if $printTemplate} +{* Javascript TAGs *} +{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +{/if} +{if $printJavaScript} +var oPopupMenu_{$form->name}; +function popupMenu_{$form->name}( target ) +{literal} +{ + try { + {/literal} + var menuObserver=leimnud.factory(leimnud.pattern.observer,true); + leimnud.event.add(document.body,"click",menuObserver.update); + + oPopupMenu_{$form->name} = new leimnud.module.app.menuRight(); + oPopupMenu_{$form->name}.make( + {literal} + { + target: target, + {/literal} + theme: "{$form->theme}", + menu:[ + {php}$this->assign('firstfield', true);{/php} + {foreach from=$form->fields item=field key=name} + {if $field->type==='popupoption'} + {if !$firstfield},{/if} + {$field->getEvents()} + {php}$this->assign('firstfield', false);{/php} + {/if} + {/foreach} + {literal} + ], + parent:leimnud + }); + {/literal} + menuObserver.register(oPopupMenu_{$form->name}.remove,oPopupMenu_{$form->name}); + {literal} + + } catch (e) { + } +} +{/literal} +{/if} \ No newline at end of file diff --git a/workflow/engine/templates/processes/main.html b/workflow/engine/templates/processes/main.html new file mode 100755 index 000000000..65591b403 --- /dev/null +++ b/workflow/engine/templates/processes/main.html @@ -0,0 +1,2 @@ +
    + diff --git a/workflow/engine/templates/processes/main.js b/workflow/engine/templates/processes/main.js new file mode 100755 index 000000000..d3884b6e9 --- /dev/null +++ b/workflow/engine/templates/processes/main.js @@ -0,0 +1,476 @@ +/* + * @author: Erik A. Ortiz + * Aug 20th, 2010 + */ +var processesGrid; +var store; +var comboCategory; + +new Ext.KeyMap(document, { + key: Ext.EventObject.F5, + fn: function(keycode, e) { + if (! e.ctrlKey) { + if (Ext.isIE) + e.browserEvent.keyCode = 8; + e.stopEvent(); + document.location = document.location; + } + else + Ext.Msg.alert('Refresh', 'You clicked: CTRL-F5'); + } +}); + + +Ext.onReady(function(){ + //Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + Ext.QuickTips.init(); + + store = new Ext.data.GroupingStore( { + //var store = new Ext.data.Store( { + proxy : new Ext.data.HttpProxy({ + url: 'processesList' + }), + + reader : new Ext.data.JsonReader( { + totalProperty: 'totalCount', + root: 'data', + fields : [ + {name : 'PRO_DESCRIPTION'}, + {name : 'PRO_UID'}, + {name : 'PRO_CATEGORY_LABEL'}, + {name : 'PRO_TITLE'}, + {name : 'PRO_STATUS'}, + {name : 'PRO_STATUS_LABEL'}, + {name : 'PRO_CREATE_DATE'}, + {name : 'PRO_DEBUG_LABEL'}, + {name : 'PRO_CREATE_USER_LABEL'}, + {name : 'CASES_COUNT', type:'float'}, + {name : 'CASES_COUNT_DRAFT', type:'float'}, + {name : 'CASES_COUNT_TO_DO', type:'float'}, + {name : 'CASES_COUNT_COMPLETED', type:'float'}, + {name : 'CASES_COUNT_CANCELLED', type:'float'} + ] + })//, + //sortInfo:{field: 'PRO_TITLE', direction: "ASC"} + //groupField:'PRO_CATEGORY_LABEL' + + }); + + + var expander = new Ext.ux.grid.RowExpander({ + tpl : new Ext.Template( + '

    '+TRANSLATIONS.ID_PRO_DESCRIPTION+': {PRO_DESCRIPTION}


    ' + ) + }); + + comboCategory = new Ext.form.ComboBox({ + fieldLabel : 'Categoty', + hiddenName : 'category', + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'mainAjax', + method : 'POST' + }), + baseParams : { + request : 'categoriesList' + }, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ { + name : 'CATEGORY_UID' + }, { + name : 'CATEGORY_NAME' + } ] + }) + }), + valueField : 'CATEGORY_UID', + displayField : 'CATEGORY_NAME', + triggerAction : 'all', + emptyText : TRANSLATIONS.ID_SELECT, + selectOnFocus : true, + editable : true, + width: 180, + allowBlank : true, + autocomplete: true, + typeAhead: true, + allowBlankText : 'You should to select a language from the list.', + listeners:{ + scope: this, + 'select': function() { + filter = comboCategory.value; + store.setBaseParam( 'category', filter); + var searchTxt = Ext.util.Format.trim(Ext.getCmp('searchTxt').getValue()); + + if( searchTxt == '' ){ + store.setBaseParam( 'processName', ''); + } + store.load({params:{category: filter, start : 0 , limit : 25 }}); + }} + }) + + processesGrid = new Ext.grid.GridPanel( { + region: 'center', + layout: 'fit', + id: 'processesGrid', + height:500, + //autoWidth : true, + width:'', + title : '', + stateful : true, + stateId : 'grid', + enableColumnResize: true, + enableHdMenu: true, + frame:false, + plugins: expander, + cls : 'grid_with_checkbox', + columnLines: true, + + + /*view: new Ext.grid.GroupingView({ + //forceFit:true, + //groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})' + groupTextTpl: '{text}' + }),*/ + viewConfig: { + forceFit:true + }, + cm: new Ext.grid.ColumnModel({ + defaults: { + width: 200, + sortable: true + }, + columns: [ + expander, + {id:'PRO_UID', dataIndex: 'PRO_UID', hidden:true, hideable:false}, + {header: "", dataIndex: 'PRO_STATUS', width: 50, hidden:true, hideable:false}, + {header: TRANSLATIONS.ID_PRO_DESCRIPTION, dataIndex: 'PRO_DESCRIPTION',hidden:true, hideable:false}, + {header: TRANSLATIONS.ID_PRO_TITLE, dataIndex: 'PRO_TITLE', width: 300}, + {header: TRANSLATIONS.ID_CATEGORY, dataIndex: 'PRO_CATEGORY_LABEL', width: 100, hidden:false}, + {header: TRANSLATIONS.ID_STATUS, dataIndex: 'PRO_STATUS_LABEL', width: 50, renderer:function(v,p,r){ + color = r.get('PRO_STATUS') == 'ACTIVE'? 'green': 'red'; + return String.format("{1}", color, v); + }}, + {header: TRANSLATIONS.ID_PRO_USER, dataIndex: 'PRO_CREATE_USER_LABEL', width: 150}, + {header: TRANSLATIONS.ID_PRO_CREATE_DATE, dataIndex: 'PRO_CREATE_DATE', width: 90}, + {header: TRANSLATIONS.ID_INBOX, dataIndex: 'CASES_COUNT_TO_DO', width: 50, align:'right'}, + {header: TRANSLATIONS.ID_DRAFT, dataIndex: 'CASES_COUNT_DRAFT', width: 50, align:'right'}, + {header: TRANSLATIONS.ID_COMPLETED, dataIndex: 'CASES_COUNT_COMPLETED', width: 70, align:'right'}, + {header: TRANSLATIONS.ID_CANCELLED, dataIndex: 'CASES_COUNT_CANCELLED', width: 70, align:'right'}, + {header: TRANSLATIONS.ID_TOTAL_CASES, dataIndex: 'CASES_COUNT', width: 80,renderer:function(v){return ""+v+"";}, align:'right'}, + {header: TRANSLATIONS.ID_PRO_DEBUG, dataIndex: 'PRO_DEBUG_LABEL', width: 50, align:'center'} + ] + }), + + store: store, + + tbar:[ + { + text:TRANSLATIONS.ID_NEW, + iconCls: 'silk-add', + icon: '/images/addc.png', + handler: newProcess + }, + '-' + ,{ + text:TRANSLATIONS.ID_EDIT, + iconCls: 'silk-add', + icon: '/images/edit.gif', + handler: editProcess + },{ + text:TRANSLATIONS.ID_STATUS, + id:'activator', + icon: '', + iconCls: 'silk-add', + handler: activeDeactive, + disabled:true + },{ + text:TRANSLATIONS.ID_DELETE, + iconCls: 'silk-add', + icon: '/images/delete-16x16.gif', + handler:deleteProcess + },{ + xtype: 'tbseparator' + },{ + text:TRANSLATIONS.ID_IMPORT, + iconCls: 'silk-add', + icon: '/images/import.gif', + handler:importProcess + },/*{ + text:'Export', + iconCls: 'silk-add', + icon: '/images/export.png', + },*/{ + text:TRANSLATIONS.ID_BROWSE_LIBRARY, + iconCls: 'silk-add', + icon: '/images/icon-pmwebservices.png', + handler: browseLibrary + }, + { + xtype: 'tbfill' + },{ + xtype: 'tbseparator' + }, + TRANSLATIONS.ID_CATEGORY, + comboCategory,{ + xtype: 'tbseparator' + },new Ext.form.TextField ({ + id: 'searchTxt', + ctCls:'pm_search_text_field', + allowBlank: true, + width: 150, + emptyText: TRANSLATIONS.ID_ENTER_SEARCH_TERM,//'enter search term', + listeners: { + specialkey: function(f,e){ + if (e.getKey() == e.ENTER) { + doSearch(); + } + } + } + }),{ + text:'X', + ctCls:'pm_search_x_button', + handler: function(){ + //store.setBaseParam( 'category', ''); + store.setBaseParam( 'processName', ''); + store.load({params:{start : 0 , limit : '' }}); + Ext.getCmp('searchTxt').setValue(''); + //comboCategory.setValue(''); + //store.reload(); + } + },{ + text:TRANSLATIONS.ID_SEARCH, + handler: doSearch + } + ], + // paging bar on the bottom + /*bbar: new Ext.PagingToolbar({ + pageSize: 15, + store: store, + displayInfo: true, + displayMsg: 'Displaying topics {0} - {1} of {2}', + emptyMsg: "No topics to display", + items:[] + }),*/ + listeners: { + rowdblclick: editProcess, + rowclick: function(){ + //var rowSelected = processesGrid.getSelectionModel().getSelected(); + //alert(rowSelected.PRO_UID); + //Ext.getCmp('activator').setIcon(); + }, + render: function(){ + this.loadMask = new Ext.LoadMask(this.body, {msg:'Loading...'}); + //this.ownerCt.doLayout(); + processesGrid.getSelectionModel().on('rowselect', function(){ + var rowSelected = processesGrid.getSelectionModel().getSelected(); + //alert(rowSelected.data.PRO_STATUS); + var activator = Ext.getCmp('activator'); + activator.setDisabled(false); + if( rowSelected.data.PRO_STATUS == 'ACTIVE' ){ + activator.setIcon('/images/deactivate.png'); + activator.setText(TRANSLATIONS.ID_DEACTIVATE); + } else { + activator.setIcon('/images/activate.png'); + activator.setText(TRANSLATIONS.ID_ACTIVATE); + } + + }); + } + } + + }); + + processesGrid.store.load({params: {"function":"languagesList"}}); + + //////////////////////store.load({params: {"function":"xml"}}); + + + //processesGrid.render('processes-panel'); + + //processesGrid.render(document.body); + //fp.render('form-panel'); + + + var viewport = new Ext.Viewport({ + layout: 'border', + autoScroll: true, + items: [ + processesGrid + ] + }); +}); + + +function newProcess(){ + window.location = 'processes_New'; +} + +function doSearch(){ + if(comboCategory.getValue() == '') + store.setBaseParam( 'category', ''); + filter = Ext.getCmp('searchTxt').getValue(); + + store.setBaseParam('processName', filter); + store.load({params:{processName: filter, start : 0 , limit : 25 }}); +} + +editProcess = function(){ + var rowSelected = processesGrid.getSelectionModel().getSelected(); + if( rowSelected ) { + location.href = 'processes_Map?PRO_UID='+rowSelected.data.PRO_UID+'&rand='+Math.random() + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_NO_SELECTION_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } +} + +deleteProcess = function(){ + //var rowSelected = processesGrid.getSelectionModel().getSelected(); + var rows = processesGrid.getSelectionModel().getSelections(); + if( rows.length > 0 ) { + //parent.dropProcess(rowSelected.data.PRO_UID); + + isValid = true; + errLog = Array(); + //verify if the selected rows have not any started or delegated cases + for(i=0; i'; + e = TRANSLATIONS.ID_PROCESS_CANT_DELETE; + e = e.replace('{0}', rows[errLog[i]].get('PRO_TITLE')); + e = e.replace('{1}', rows[errLog[i]].get('CASES_COUNT')); + errMsg += e + '
    '; + } + Ext.MessageBox.show({ + title: 'Error', + msg: errMsg, + buttons: Ext.MessageBox.OK, + icon: Ext.MessageBox.ERROR + }); + } + + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_NO_SELECTION_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } +} + +importProcess = function(){ + window.location = 'processes_Import'; +} + +browseLibrary = function(){ + window.location = 'processes_Library'; +} + +function activeDeactive(){ + //var rowSelected = processesGrid.getSelectionModel().getSelected(); + var rows = processesGrid.getSelectionModel().getSelections(); + + if( rows.length > 0 ) { + var ids = ''; + for(i=0; i + + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/processes/processes_Map.html b/workflow/engine/templates/processes/processes_Map.html new file mode 100644 index 000000000..8bf7dbf8d --- /dev/null +++ b/workflow/engine/templates/processes/processes_Map.html @@ -0,0 +1,2 @@ +
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/processes/processes_Upload.php b/workflow/engine/templates/processes/processes_Upload.php new file mode 100644 index 000000000..25f05dd70 --- /dev/null +++ b/workflow/engine/templates/processes/processes_Upload.php @@ -0,0 +1,141 @@ + + +Ajax upload demo + + + + + + + + + + + + + + + +
    +
  • +
    + + + +
     
    +
    +
  • +
    + +
    + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/templates/processes/webentry.tpl b/workflow/engine/templates/processes/webentry.tpl new file mode 100644 index 000000000..2351ff32b --- /dev/null +++ b/workflow/engine/templates/processes/webentry.tpl @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + +{scriptCode} + + + + + + + \ No newline at end of file diff --git a/workflow/engine/templates/processes/webentryPost.tpl b/workflow/engine/templates/processes/webentryPost.tpl new file mode 100644 index 000000000..0f8610ed7 --- /dev/null +++ b/workflow/engine/templates/processes/webentryPost.tpl @@ -0,0 +1,80 @@ +validatePost(); + + ws_open (); + $result = ws_newCase ( '{processUid}', '{taskUid}', convertFormToWSObjects($_POST['form']) ); + + if( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNr = $result->caseNumber; + {USR_VAR} + + #save files + if ( isset($_FILES['form']) ) { + foreach ($_FILES['form']['name'] as $sFieldName => $vValue) { + if ( $_FILES['form']['error'][$sFieldName] == 0 ){ + file_put_contents(G::getSysTemDir().PATH_SEP.$_FILES['form']['name'][$sFieldName], file_get_contents($_FILES['form']['tmp_name'][$sFieldName])); + $fpath = G::getSysTemDir().PATH_SEP.$_FILES['form']['name'][$sFieldName]; + + if( isset($_POST['INPUTS'][$sFieldName]) && $_POST['INPUTS'][$sFieldName] != '' ){ #input file type + ws_sendFile($fpath, $USR_UID, $caseId, 1, $_POST['INPUTS'][$sFieldName]); + } else { #attached file type + ws_sendFile($fpath, $USR_UID, $caseId); + } + } + } + } + + $result = ws_routeCase ($caseId, 1); + $assign = $result->message; + + $aMessage['MESSAGE'] = "Case created in ProcessMaker
    Case Number:$caseNr
    Case Id:$caseId
    Case derivated to: $assign"; + + } else { + $aMessage['MESSAGE'] = 'An error occurred while the application was being processed.
    + Error code: '.$result->status_code.'
    + Error message: '.$result->message.'


    + please contact to your system administrator.'; + } + + + /** + * by default show the case info, for the recently created case + * you can change it or redirect to another page + * i.e. G::header( 'Location: http://www.processmaker.com' ); + */ + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showInfo', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + catch ( Exception $e ) { + $G_PUBLISH = new Publisher; + $suggest_message = "This web entry should be regenerated, please contact to your system administrator."; + $aMessage['MESSAGE'] = '
    '.$e->getMessage().'
    '.$suggest_message .'
    '; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish', 'blank' ); + } + diff --git a/workflow/engine/templates/publish-raw.php b/workflow/engine/templates/publish-raw.php new file mode 100644 index 000000000..754b24127 --- /dev/null +++ b/workflow/engine/templates/publish-raw.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_PUBLISH; + global $G_CONTENT; + global $G_FORM; + global $G_TABLE; + global $RBAC; + if ( !is_object( $G_PUBLISH ) ) die ("Publisher object is required by this template!"); + + + if (isset($_SESSION['G_MESSAGE_TYPE']) && isset($_SESSION['G_MESSAGE'])) { + $messageTypes=array("INFO","WARNING","ERROR"); + if(in_array(strtoupper($_SESSION['G_MESSAGE_TYPE']),$messageTypes)){ + $msgType=strtoupper($_SESSION['G_MESSAGE_TYPE']); + }else{ + $msgType="WARNING"; + } + echo(''); + echo(''); + echo('
    ' . G::capitalize($_SESSION['G_MESSAGE_TYPE']) . ' : ' . $_SESSION['G_MESSAGE'] . '
    '); + + + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); + } + + + if( is_array( $G_PUBLISH->Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + for( $npcount = 0; $npcount < $nplim; $npcount++ ) + { + if (isset($RBAC->userObj)) + $G_PUBLISH->RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + else + $G_PUBLISH->RenderContent( $npcount ); + } + } diff --git a/workflow/engine/templates/publish-treeview.php b/workflow/engine/templates/publish-treeview.php new file mode 100644 index 000000000..dba668599 --- /dev/null +++ b/workflow/engine/templates/publish-treeview.php @@ -0,0 +1,74 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_PUBLISH; + global $G_CONTENT; + global $G_FORM; + global $G_TABLE; + global $RBAC; + if ( !is_object( $G_PUBLISH ) ) die ("Publisher object is required by this template!"); +?> +'); + echo('
    ' . G::capitalize($_SESSION['G_MESSAGE_TYPE']) . ' : ' . $_SESSION['G_MESSAGE'] . '
    '); + + + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); + } + ?> + +Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + print ""; + print ""; + print ""; + print ""; + } +?> +
    "; + $G_PUBLISH->RenderContent( 0, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + print ""; + print ""; + for( $npcount = 1; $npcount < $nplim; $npcount++ ) { + print( "\n\n" ); + } + print "
    \n" ); + ?> + RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + ?> + \n
    "; + print "
    diff --git a/workflow/engine/templates/publish-twocolumns.php b/workflow/engine/templates/publish-twocolumns.php new file mode 100644 index 000000000..d96037bd1 --- /dev/null +++ b/workflow/engine/templates/publish-twocolumns.php @@ -0,0 +1,81 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_PUBLISH; + global $G_CONTENT; + global $G_FORM; + global $G_TABLE; + global $RBAC; + if ( !is_object( $G_PUBLISH ) ) die ("Publisher object is required by this template!"); + + + +?> +'); + echo('
    ' . G::capitalize($_SESSION['G_MESSAGE_TYPE']) . ' : ' . $_SESSION['G_MESSAGE'] . '
    '); + echo(''); + + + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); + } + ?> + +Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + for( $npcount = 0; $npcount < $nplim; $npcount++ ) + { + if ((($npcount + 1) % 2) != 0) + { + print("\n"); + } + print( "\n" ); + if ((($npcount + 1) % 2) == 0) + { + print("\n"); + } + } + if ((($npcount + 1) % 2) == 0) + { + print("\n"); + } + } +?> +
    \n" ); + if (isset($RBAC->userObj)) + $G_PUBLISH->RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + else + $G_PUBLISH->RenderContent( $npcount ); + print( "
    diff --git a/workflow/engine/templates/publish.php b/workflow/engine/templates/publish.php new file mode 100644 index 000000000..d7412f968 --- /dev/null +++ b/workflow/engine/templates/publish.php @@ -0,0 +1,100 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_PUBLISH; + global $G_CONTENT; + global $G_FORM; + global $G_TABLE; + global $RBAC; + if ( !is_object( $G_PUBLISH ) ) die ("Publisher object is required by this template!"); +?> +'); + echo('
    ' . G::capitalize($msg) . ': ' . $_SESSION['G_MESSAGE'] . '
    '); + echo(''); + + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); +} +?> + + +Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + for( $npcount = 0; $npcount < $nplim; $npcount++ ) + { + print( "\n\n\n" ); + } + } +?> +
    \n" ); + if (isset($RBAC->userObj)) + $G_PUBLISH->RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + else + $G_PUBLISH->RenderContent( $npcount ); + print( "
    diff --git a/workflow/engine/templates/publishBlank.php b/workflow/engine/templates/publishBlank.php new file mode 100755 index 000000000..bdef9455a --- /dev/null +++ b/workflow/engine/templates/publishBlank.php @@ -0,0 +1,105 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + global $G_PUBLISH; + global $G_CONTENT; + global $G_FORM; + global $G_TABLE; + global $RBAC; + if ( !is_object( $G_PUBLISH ) ) die ("Publisher object is required by this template!"); +?> + +'); + echo('
    ' . G::capitalize($msg) . ': ' . $_SESSION['G_MESSAGE'] . '
    '); + echo(''); + + unset($_SESSION['G_MESSAGE_TYPE']); + unset($_SESSION['G_MESSAGE']); +} +?> + + +Parts ) ) + { + $nplim = count( $G_PUBLISH->Parts ); + for( $npcount = 0; $npcount < $nplim; $npcount++ ) + { + print( "\n\n\n" ); + } + } +?> +
    \n" ); + if (isset($RBAC->userObj)) + $G_PUBLISH->RenderContent( $npcount, ($RBAC->userCanAccess('WF_SHOW_XMLFORM_NAME')==1?true:false) ); + else + $G_PUBLISH->RenderContent( $npcount ); + print( "
    diff --git a/workflow/engine/templates/roles/roles_AssignPermissions.php b/workflow/engine/templates/roles/roles_AssignPermissions.php new file mode 100644 index 000000000..94bb446a3 --- /dev/null +++ b/workflow/engine/templates/roles/roles_AssignPermissions.php @@ -0,0 +1,79 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + $ROL_UID = $_GET['ROL_UID']; + global $RBAC; + $oDataset = $RBAC->getAllPermissions($ROL_UID,$RBAC->sSystem); + $roleCode = $RBAC->getRoleCode($ROL_UID); + G::LoadClass('tree'); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::LoadTranslation('ID_ASSIGN_THE_ROLE') . ': '.$roleCode.'
    +
    +
    + '; + + $tree->showSign = false; + + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $ID_ASSIGN = G::LoadTranslation('ID_ASSIGN'); + + $CODE = $aRow['PER_CODE']; + $UID = $aRow['PER_UID']; + + $html = " + + + + + +
    {$CODE}[{$ID_ASSIGN}]
    "; + + $ch = &$tree->addChild('', $html, array('nodeType' => 'child')); + $ch->point = ''; + + $oDataset->next(); + } + + + print ($tree->render()); diff --git a/workflow/engine/templates/roles/roles_AssignRole.php b/workflow/engine/templates/roles/roles_AssignRole.php new file mode 100644 index 000000000..d7b2308a3 --- /dev/null +++ b/workflow/engine/templates/roles/roles_AssignRole.php @@ -0,0 +1,80 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + $ROL_UID = $_GET['ROL_UID']; + global $RBAC; + $oDataset = $RBAC->getAllUsers($ROL_UID); + $roleCode = $RBAC->getRoleCode($ROL_UID); + + G::LoadClass('tree'); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::LoadTranslation('ID_ASSIGN_THE_ROLE') . ': '.$roleCode.'
    +
    +
    + '; + + $tree->showSign = false; + + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $ID_ASSIGN = G::LoadTranslation('ID_ASSIGN'); + + $user = '['.$aRow['USR_USERNAME'].'] '.$aRow['USR_FIRSTNAME'].' '.$aRow['USR_LASTNAME']; + $USR_UID = $aRow['USR_UID']; + + $html = " + + + + + +
    {$user}[{$ID_ASSIGN}]
    "; + + $ch = &$tree->addChild('', $html, array('nodeType' => 'child')); + $ch->point = ''; + + $oDataset->next(); + } + + + print ($tree->render()); diff --git a/workflow/engine/templates/roles/roles_Tree.php b/workflow/engine/templates/roles/roles_Tree.php new file mode 100644 index 000000000..091992ddb --- /dev/null +++ b/workflow/engine/templates/roles/roles_Tree.php @@ -0,0 +1,86 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + $ROL_UID = $_GET['ROL_UID']; + global $RBAC; + $oDataset = $RBAC->getRoleUsers($ROL_UID); + $roleCode = $RBAC->getRoleCode($ROL_UID); + + G::LoadClass('tree'); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::LoadTranslation('ID_USER_WITH_ROLE') . ': '.$roleCode.'
    +
    +
    + '; + + $tree->showSign = false; + + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $ID_DELETE = G::LoadTranslation('ID_REMOVE'); + $un = ($aRow['USR_USERNAME'] != '')?$aRow['USR_USERNAME']:'none'; + $user = '['.$un.'] '.$aRow['USR_FIRSTNAME'].' '.$aRow['USR_LASTNAME']; + $USR_UID = $aRow['USR_UID']; + + if($USR_UID != "00000000000000000000000000000001") { #because the admin remove rol it doesn't posible + $refer = "{$ID_DELETE}"; + } else { + $refer = "{$ID_DELETE}"; + } + + $html = " + + + + + +
    {$user}[$refer]
    "; + + $ch = &$tree->addChild('', $html, array('nodeType' => 'child')); + $ch->point = ''; + + $oDataset->next(); + } + + + print ($tree->render()); diff --git a/workflow/engine/templates/roles/roles_permissionsTree.php b/workflow/engine/templates/roles/roles_permissionsTree.php new file mode 100644 index 000000000..b3bc0ec43 --- /dev/null +++ b/workflow/engine/templates/roles/roles_permissionsTree.php @@ -0,0 +1,85 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + $ROL_UID = $_GET['ROL_UID']; + global $RBAC; + $oDataset = $RBAC->getRolePermissions($ROL_UID); + $roleCode = $RBAC->getRoleCode($ROL_UID); + + G::LoadClass('tree'); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::LoadTranslation('ID_PERMISSIONS_FOR_THE_ROL') . ': '.$roleCode.'
    +
    +
    + '; + + $tree->showSign = false; + + $oDataset->next(); + while ($aRow = $oDataset->getRow()) { + $ID_REMOVE = G::LoadTranslation('ID_REMOVE'); + + $CODE = $aRow['PER_CODE']; + $UID = $aRow['PER_UID']; + if($ROL_UID != "00000000000000000000000000000002") { #because the admin remove permitions it doesn't posible + $refer = "{$ID_REMOVE}"; + } else { + $refer = "{$ID_REMOVE}"; + } + + $html = " + + + + + +
    {$CODE}[$refer]
    "; + + $ch = &$tree->addChild('', $html, array('nodeType' => 'child')); + $ch->point = ''; + + $oDataset->next(); + } + + + print ($tree->render()); diff --git a/workflow/engine/templates/services/login_getStarted.html b/workflow/engine/templates/services/login_getStarted.html new file mode 100644 index 000000000..213988956 --- /dev/null +++ b/workflow/engine/templates/services/login_getStarted.html @@ -0,0 +1,66 @@ + + + + +Get Started + + + + + + + + + + + + + + + + +
    +

    Get Started

    +

    Welcome to ProcessMaker!

    +

    To get started, log in using the following credentials. You can change them later:

    + Username: admin
    + Password: admin + + +

    We suggest you follow our 7 easy videos to automate your workflow. You can see a demo of each step at http://www.processmaker.com/demos/

    +

    Other Resources:

    +

    PM Library - Import Templates
    +

    PM Wiki - Manuals
    +

    PM Forum - Ask Questions
    +

    We hope you enjoy using ProcessMaker. For more information about our enterprise support and consulting services contact us. +

    +

    The ProcessMaker Team

    +

    Don't show me again

    + +
    \ No newline at end of file diff --git a/workflow/engine/templates/setup/appCacheViewConf.html b/workflow/engine/templates/setup/appCacheViewConf.html new file mode 100755 index 000000000..5c22c101a --- /dev/null +++ b/workflow/engine/templates/setup/appCacheViewConf.html @@ -0,0 +1,5 @@ +
    +
    +
    +
    +
    diff --git a/workflow/engine/templates/setup/appCacheViewConf.js b/workflow/engine/templates/setup/appCacheViewConf.js new file mode 100755 index 000000000..ac932ea1a --- /dev/null +++ b/workflow/engine/templates/setup/appCacheViewConf.js @@ -0,0 +1,219 @@ +Ext.onReady(function() { + + Ext.QuickTips.init(); + + // turn on validation errors beside the field globally + Ext.form.Field.prototype.msgTarget = 'side'; + + var bd = Ext.getBody(); + + // bd.createChild({tag: 'h2', html: 'Form 2 - Adding fieldsets'}); + + + // Store + var store = new Ext.data.Store( { + proxy: new Ext.data.HttpProxy({ + url: 'appCacheViewAjax', + method: 'POST' + }), + baseParams : { request : 'info'}, + reader : new Ext.data.JsonReader( { + root : 'info', + fields : [ {name : 'name'}, {name : 'value'} ] + }) + }); + + // create the Grid + var infoGrid = new Ext.grid.GridPanel( { + store : store, + columns : [{ + id : 'name', + header : '', + width : 210, + sortable : false, + dataIndex : 'name' + }, + { + header : '', + width : 190, + sortable : false, + dataIndex : 'value' + } + ], + stripeRows : true, + autoHeight : true, + width : 400, + title : 'Workflow Applications Cache Info', + // config options for stateful behavior + stateful : true, + stateId : 'grid', + enableColumnHide: false, + enableColumnResize: false, + enableHdMenu: false + }); + + // render the grid to the specified div in the page + infoGrid.render('info-panel'); + + + var fsf = new Ext.FormPanel( { + labelWidth : 105, // label settings here cascade unless overridden + url : '', + frame : true, + title : ' ', + bodyStyle : 'padding:5px 5px 0', + width : 400, + items : [ ] + }); + + var fieldset; + + var cmbLanguages = new Ext.form.ComboBox({ + fieldLabel : 'Language', + hiddenName : 'lang', + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'appCacheViewAjax', + method : 'POST' + }), + baseParams : {request : 'getLangList'}, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ {name : 'LAN_ID'}, {name : 'LAN_NAME'} ] + }) + }), + valueField : 'LAN_ID', + displayField : 'LAN_NAME', + //triggerAction : 'all', + emptyText : 'Select', + selectOnFocus : true, + editable : false, + allowBlank : false + }) + + var txtUser = { + id : 'txtUser', + xtype: 'textfield', + fieldLabel: 'User', + disabled: false, + name: 'user', + value: '' + }; + + var txtHost = { + id : 'txtHost', + xtype: 'textfield', + fieldLabel: 'Host', + disabled: false, + name: 'host', + value: '' + }; + + var txtPasswd = { + id : 'txtPasswd', + inputType: 'password', + xtype:'textfield', + fieldLabel: 'Password', + disabled: false, + hidden: false, + value: '' + } + + fieldset = { + xtype : 'fieldset', + title : 'Rebuild Workflow Application Cache', + collapsible : false, + autoHeight : true, + defaults : { width : 170 }, + defaultType : 'textfield', + items : [cmbLanguages], + buttons : [{ + text : 'Build Cache', + handler : function() { + Ext.Msg.show ({ msg : TRANSLATIONS.ID_PROCESSING, wait:true,waitConfig: {interval:400} }); + Ext.Ajax.request({ + url: 'appCacheViewAjax', + success: function(response) { + store.reload(); + Ext.MessageBox.hide(); + res = Ext.decode ( response.responseText ); + Ext.Msg.alert ( '', res.msg ); + + }, + failure : function(response) { + Ext.Msg.hide(); + Ext.Msg.alert ( 'Error', response.responseText ); + }, + params: {request: 'build', lang: 'en' }, + waitMsg : 'Building Workflow Application Cache...', + timeout : 1000*60*30 //30 mins + }); + } + }] + } + + + fieldsetRoot = { + xtype : 'fieldset', + title : 'Setup MySql Root Password', + collapsible : false, + autoHeight : true, + defaults : { width : 170 }, + defaultType : 'textfield', + items : [txtHost, txtUser, txtPasswd ], + buttons : [{ + text : 'Setup Password', + handler : function() { + Ext.Msg.show ({ msg : TRANSLATIONS.ID_PROCESSING, wait:true,waitConfig: {interval:400} }); + Ext.Ajax.request({ + url: 'appCacheViewAjax', + success: function(response) { + store.reload(); + Ext.MessageBox.hide(); + Ext.Msg.alert ( '', response.responseText ); + }, + failure : function(response) { + Ext.Msg.hide(); + Ext.Msg.alert ( 'Error', response.responseText ); + }, + params: { request: 'recreate-root', lang: 'en', host: Ext.getCmp('txtHost').getValue(), user: Ext.getCmp('txtUser').getValue(), password: Ext.getCmp('txtPasswd').getValue() }, + // timeout : 1000 + // 30 mins + timeout : 1000*60*30 //30 mins + }); + } + }] + } + fsf.add(fieldset); + fsf.add(fieldsetRoot); + fsf.render(document.getElementById('main-panel')); + + //set the current language + cmbLanguages.store.on('load',function(){ cmbLanguages.setValue ( currentLang ) }); + cmbLanguages.store.load(); + + //store.load(); instead call standard proxy we are calling ajax request, because we need to catch any error + Ext.Ajax.request({ + url: 'appCacheViewAjax', + success: function(response) { + myData = Ext.decode ( response.responseText ); + store.loadData(myData); + if ( myData.error ) { + Warning( 'error', myData.errorMsg ); + } + }, + failure : function(response) { + Ext.Msg.alert ( 'Error', response.responseText ); + }, + params: {request: 'info' } + }); + + }); //ExtReady + +var Warning = function( msgTitle, msgError ) { + tplEl = Ext.get ('errorMsg'); + + tplText = '
    ' + msgTitle + ': ' + msgError + '
    '; + tplEl.update ( tplText ); + +} diff --git a/workflow/engine/templates/setup/clearCompiledResult.php b/workflow/engine/templates/setup/clearCompiledResult.php new file mode 100644 index 000000000..845c22d0f --- /dev/null +++ b/workflow/engine/templates/setup/clearCompiledResult.php @@ -0,0 +1,16 @@ + +
    +
    + + + + +
    + '.G::LoadTranslation('ID_CLEAR_CACHE_MSG2').' ('.PATH_C .') +
    +
    +
    + '; +?> diff --git a/workflow/engine/templates/setup/css/extjs-extend/xtheme-gray.css b/workflow/engine/templates/setup/css/extjs-extend/xtheme-gray.css new file mode 100755 index 000000000..257050b7d --- /dev/null +++ b/workflow/engine/templates/setup/css/extjs-extend/xtheme-gray.css @@ -0,0 +1,148 @@ +.pm-tree-node1 { + font: normal 11px Verdana,Arial,Helvetica,sans-serif !important; + + + border: 1px solid #CACACA; + height: 20px; + width: 99%; + color: #666; + vertical-align: middle; + text-decoration: none; + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} + +.ICON_CASES_LIST_SETUP{ + background-image: url(/images/icon-pmcaseslist-conf.png) !important; + width:15px !important; + height:15px !important; +} + + +.ICON_APPCACHEVIEW_SETUP{ + background-image: url(/images/icon-pmappcacheview-rebuild.png) !important; + width:15px !important; + height:15px !important; +} + +.ICON_ADDITIONAL_TABLES{ + /*ss_database_table*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -5815px !important; +} + +.ICON_LANGUAGES{ + /*ss_text_dropcaps*/ + background-image: url(/images/icon-languages.png) !important; + width:18px !important; + height:15px !important; +} + + +.ICON_PLUGINS{ + /*ss_plugin*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -12961px !important; +} + +.ICON_UPGRADE{ + /*ss_package_go*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -10873px !important; +} + +.ICON_EMAILS{ + /*ss_email_edit*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -6715px !important; +} + +.ICON_WEBSERVICES{ + /*ss_server_connect*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -14095px !important; +} + +.ICON_SKINS{ + background-image: url(/images/icon-pmskins.png) !important; + width:15px !important; + height:15px !important; +} + +.ICON_LOGO{ + background-image: url(/images/icon-pmlogo-15x15.png) !important; + width:15px !important; + height:15px !important; +} + +.ICON_CLEAR_CACHE{ + background-image: url(/images/icon-pmclear-cache.png) !important; + width:15px !important; + height:15px !important; +} + +.ICON_CALENDAR{ + /*ss_calendar*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -2899px !important; +} + +.ICON_LOG_CASE_SCHEDULER{ + /*ss_timeline_marker*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -17011px !important; +} + +.ICON_PROCESS_CATEGORY{ + /*ss_sitemap_color*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -14833px !important; +} + +/* Language Support module styles*/ +.upload-icon { + background: url('/images/cases-documents.png') no-repeat 0 0 !important; +} + +#fi-button-msg { + border: 2px solid #ccc; + padding: 5px 10px; + background: #eee; + margin: 5px; + float: left; +} + +.ICON_HEARTBEAT{ + /*ss_heart*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -8335px !important; +} + +/*icons add alvaro*/ +.ICON_USERS{ + /*ss_user*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -17173px !important; +} + +.ICON_ROLES{ + /*ss_application_key*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -325px !important; +} + +.ICON_GROUPS{ + /*ss_group*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -8173px !important; +} + +.ICON_DEPARTAMENTS{ + /*ss_chart_organisation*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -3871px !important; +} +.ICON_AUTHSOURCES{ + /*ss_key*/ + background-image:url( /images/icons_silk/sprites.png) !important; + background-position:0 -8929px !important; +} diff --git a/workflow/engine/templates/setup/environmentSettings.js b/workflow/engine/templates/setup/environmentSettings.js new file mode 100755 index 000000000..0bc8b0d0c --- /dev/null +++ b/workflow/engine/templates/setup/environmentSettings.js @@ -0,0 +1,310 @@ +Ext.onReady(function() { + + Ext.QuickTips.init(); + Ext.form.Field.prototype.msgTarget = 'side'; + + var fsf = new Ext.FormPanel( { + labelWidth : 170, // label settings here cascade unless overridden + labelAlign: 'right', + url : '', + frame : true, + title : TRANSLATIONS.ID_PM_ENV_SETTINGS_TITLE, + bodyStyle : 'padding:5px 5px 0', + width : 500, + + items : [], + buttons : [ + { + text : TRANSLATIONS.ID_SAVE_SETTINGS, + disabled : false, + handler : function() { + fsf.getForm().submit( { + url : 'environmentSettingsAjax?request=save&r=' + Math.random(), + waitMsg : TRANSLATIONS.ID_SAVING_ENVIRONMENT_SETTINGS+'...', + timeout : 36000, + success : function(res, req) { + Ext.MessageBox.show({ title: '', msg: req.result.msg, buttons: + Ext.MessageBox.OK, animEl: 'mb9', fn: function(){}, icon: + Ext.MessageBox.INFO }); setTimeout(function(){ + Ext.MessageBox.hide(); }, 2000); + } + }); + } + } + ] + }); + var fieldset; + var fieldsetCasesList; + + var cmbUsernameFormats = new Ext.form.ComboBox({ + fieldLabel : TRANSLATIONS.IS_USER_NAME_DISPLAY_FORMAT, + hiddenName : 'userFormat', + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'environmentSettingsAjax', + method : 'POST' + }), + baseParams : { + request : 'getUserMaskList' + }, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ { + name : 'id' + }, { + name : 'name' + } ] + }), + listeners:{ + load: function(){ + i = cmbUsernameFormats.store.findExact('id', default_format, 0); + cmbUsernameFormats.setValue(cmbUsernameFormats.store.getAt(i).data.id); + cmbUsernameFormats.setRawValue(cmbUsernameFormats.store.getAt(i).data.name); + } + } + }), + + valueField : 'id', + displayField : 'name', + triggerAction : 'all', + emptyText : 'Select', + selectOnFocus : true, + editable : false, + allowBlank : false, + allowBlankText : TRANSLATIONS.ID_ENVIRONMENT_SETTINGS_MSG_1, + mode:'local', + listeners:{ + afterrender:function(){ + cmbUsernameFormats.store.load(); + } + } + }); + + var cmbDateFormats = new Ext.form.ComboBox({ + fieldLabel : TRANSLATIONS.ID_GLOBAL_DATE_FORMAT, + hiddenName : 'dateFormat', + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'environmentSettingsAjax', + method : 'POST' + }), + baseParams : { + request : 'getDateFormats' + }, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ { + name : 'id' + }, { + name : 'name' + } ] + }), + listeners:{ + load: function(){ + i = cmbDateFormats.store.findExact('id', default_date_format, 0); + cmbDateFormats.setValue(cmbDateFormats.store.getAt(i).data.id); + cmbDateFormats.setRawValue(cmbDateFormats.store.getAt(i).data.name); + } + } + }), + mode: 'remote', + valueField : 'id', + displayField : 'name', + triggerAction : 'all', + emptyText : 'Select', + selectOnFocus : true, + editable : false, + allowBlank : false, + allowBlankText : TRANSLATIONS.ID_ENVIRONMENT_SETTINGS_MSG_1, + mode:'local', + listeners:{ + afterrender:function(){ + cmbDateFormats.store.load(); + } + } + }); + + var cmbCasesDateFormats = new Ext.form.ComboBox({ + fieldLabel : TRANSLATIONS.ID_CASES_DATE_MASK, + hiddenName : 'casesListDateFormat', + + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'environmentSettingsAjax', + method : 'POST' + }), + baseParams : { + request : 'getCasesListDateFormat' + }, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ { + name : 'id' + }, { + name : 'name' + } ] + }), + listeners:{ + load: function(){ + i = cmbCasesDateFormats.store.findExact('id', default_caseslist_date_format, 0); + cmbCasesDateFormats.setValue(cmbCasesDateFormats.store.getAt(i).data.id); + cmbCasesDateFormats.setRawValue(cmbCasesDateFormats.store.getAt(i).data.name); + } + } + }), + + valueField : 'id', + displayField : 'name', + triggerAction : 'all', + emptyText : 'Select', + selectOnFocus : true, + editable : false, + allowBlank : false, + + allowBlankText : TRANSLATIONS.ID_ENVIRONMENT_SETTINGS_MSG_1, + mode:'local', + listeners:{ + afterrender:function(){ + cmbCasesDateFormats.store.load(); + } + } + }); + + var cmbCasesRowsPerPage = new Ext.form.ComboBox({ + fieldLabel : TRANSLATIONS.ID_CASES_ROW_NUMBER, + hiddenName : 'casesListRowNumber', + store : new Ext.data.Store( { + proxy : new Ext.data.HttpProxy( { + url : 'environmentSettingsAjax', + method : 'POST' + }), + baseParams : { + request : 'getCasesListRowNumber' + }, + reader : new Ext.data.JsonReader( { + root : 'rows', + fields : [ { + name : 'id' + }, { + name : 'name' + } ] + }), + listeners:{ + load: function(){ + i = cmbCasesRowsPerPage.store.findExact('id', default_caseslist_row_number, 0); + if( i != -1 ){ + cmbCasesRowsPerPage.setValue(cmbCasesRowsPerPage.store.getAt(i).data.id); + cmbCasesRowsPerPage.setRawValue(cmbCasesRowsPerPage.store.getAt(i).data.name); + } + } + } + }), + + valueField : 'id', + displayField : 'name', + triggerAction : 'all', + emptyText : 'Select', + selectOnFocus : true, + editable : true, + allowBlank : false, + allowBlankText : TRANSLATIONS.ID_ENVIRONMENT_SETTINGS_MSG_1, + mode:'local', + vtype: 'numeric', + listeners:{ + afterrender:function(){ + cmbCasesRowsPerPage.store.load(); + } + } + }); + + + fieldset = { + xtype : 'fieldset', + title : TRANSLATIONS.ID_PM_ENV_SETTINGS_USERFIELDSET_TITLE, + collapsible : false, + autoHeight : true, + defaults : { + width : 250 + }, + defaultType : 'textfield', + items : [cmbUsernameFormats] + } + fieldset2 = { + xtype : 'fieldset', + title : TRANSLATIONS.ID_PM_ENV_SETTINGS_REGIONFIELDSET_TITLE, + collapsible : false, + autoHeight : true, + defaults : { + width : 250 + }, + defaultType : 'textfield', + items : [cmbDateFormats] + } + + fieldsetCasesList = { + xtype : 'fieldset', + title : TRANSLATIONS.ID_PM_ENV_SETTINGS_CASESLIST_TITLE, + collapsible : false, + autoHeight : true, + defaults : { + width : 250 + }, + defaultType : 'textfield', + items : [cmbCasesDateFormats,cmbCasesRowsPerPage] + } + + fsf.add(fieldset); + fsf.add(fieldset2); + fsf.add(fieldsetCasesList); + cmbUsernameFormats.setValue(default_format); + cmbDateFormats.selectByValue(default_date_format); + cmbCasesDateFormats.setValue(default_caseslist_date_format); + cmbCasesRowsPerPage.setValue(default_caseslist_row_number); + + fsf.render(document.body); +}); + + + +Ext.apply(Ext.form.VTypes, { + // Password Check + passwordText: 'The passwords entered do not match.', + password: function(value, field) { + var valid = false; + if (field.matches) { + var otherField = Ext.getCmp(field.matches); + if (value == otherField.getValue()) { + otherField.clearInvalid(); + valid = true; + } + } + return valid; + }, + // Phone Number check + phoneText: "Not a valid phone number. Must be in the following format: 123-4567 or 123-456-7890.", + phoneMask: /[d-]/, + phoneRe: /^(d{3}[-]?){1,2}(d{4})$/, + phone: function(v) { + return this.phoneRe.test(v); + }, + // Email address check + emailText: "Not a valid email address. Must be in the following format: yourname@company.domain", + emailRe: /^(\s*[a-zA-Z0-9\._%-]+@[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4})\s*$/, + email: function(v) { + return this.emailRe.test(v); + }, + // Numeric check + numericText: "Only numbers are allowed.", + numericMask: /[0-9]/, + numericRe: /[0-9]/, + numeric: function(v) { + return this.numericRe.test(v); + }, + // Decimal Number check + decNumText: "Only decimal numbers are allowed.", + decNumMask: /(d|.)/, + decNumRe: /d+.d+|d+/, + decNum: function(v) { + return this.decNumRe.test(v); + } + }); \ No newline at end of file diff --git a/workflow/engine/templates/setup/languages.html b/workflow/engine/templates/setup/languages.html new file mode 100755 index 000000000..432f567b5 --- /dev/null +++ b/workflow/engine/templates/setup/languages.html @@ -0,0 +1,3 @@ +
    +
    +
    diff --git a/workflow/engine/templates/setup/languages.js b/workflow/engine/templates/setup/languages.js new file mode 100755 index 000000000..fdfd5bfdd --- /dev/null +++ b/workflow/engine/templates/setup/languages.js @@ -0,0 +1,381 @@ +/* + * @author: Erik A. Ortiz + * Aug 20th, 2010 + */ + +new Ext.KeyMap(document, { + key: Ext.EventObject.F5, + fn: function(keycode, e) { + if (! e.ctrlKey) { + if (Ext.isIE) { + // IE6 doesn't allow cancellation of the F5 key, so trick it into + // thinking some other key was pressed (backspace in this case) + e.browserEvent.keyCode = 8; + } + e.stopEvent(); + document.location = document.location; + } + else + Ext.Msg.alert('Refresh', 'You clicked: CTRL-F5'); + } +}); + +var removeOption; +var installOption; +var exportOption; + + +Ext.onReady(function(){ + + //Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + Ext.QuickTips.init(); + + installOption = new Ext.Action({ + text: TRANSLATIONS.ID_LANG_INSTALL_UPDATE, + iconCls: 'silk-add', + icon: '/images/import.gif', + handler: function(){ + var w = new Ext.Window({ + title: '', + width: 420, + height: 140, + modal: true, + autoScroll: false, + maximizable: false, + resizable: false, + items: [ + new Ext.FormPanel({ + /*renderTo: 'form-panel',*/ + id:'uploader', + fileUpload: true, + width: 400, + frame: true, + title: TRANSLATIONS.ID_LAN_UPLOAD_TITLE, + autoHeight: false, + bodyStyle: 'padding: 10px 10px 0 10px;', + labelWidth: 50, + defaults: { + anchor: '90%', + allowBlank: false, + msgTarget: 'side' + }, + items: [{ + xtype: 'fileuploadfield', + id: 'form-file', + emptyText: TRANSLATIONS.ID_LAN_FILE_WATER_LABEL, + fieldLabel: TRANSLATIONS.ID_LAN_FILE, + name: 'form[LANGUAGE_FILENAME]', + buttonText: '', + buttonCfg: { + iconCls: 'upload-icon' + } + }], + buttons: [{ + text: TRANSLATIONS.ID_UPLOAD, + handler: function(){ + uploader = Ext.getCmp('uploader'); + + if(uploader.getForm().isValid()){ + uploader.getForm().submit({ + url: 'languages_Import', + waitMsg: 'Uploading the translation file...', + success: function(o, resp){ + w.close(); + infoGrid.store.reload(); + + Ext.MessageBox.show({ + title: '', + width: 500, + height: 500, + msg: "
    "+resp.result.msg+"
    ", + buttons: Ext.MessageBox.OK, + animEl: 'mb9', + fn: function(){}, + icon: Ext.MessageBox.INFO + }); + }, + failure: function(o, resp){ + w.close(); + //alert('ERROR "'+resp.result.msg+'"'); + Ext.MessageBox.show({title: '', msg: resp.result.msg, buttons: + Ext.MessageBox.OK, animEl: 'mb9', fn: function(){}, icon: + Ext.MessageBox.ERROR}); + //setTimeout(function(){Ext.MessageBox.hide(); }, 2000); + } + }); + } + } + }/*,{ + text: 'Reset', + handler: function(){ + uploader = Ext.getCmp('uploader'); + uploader.getForm().reset(); + } + }*/,{ + text: TRANSLATIONS.ID_CANCEL, + handler: function(){ + w.close(); + } + }] + }) + ]/*, + listeners:{ + show:function() { + this.loadMask = new Ext.LoadMask(this.body, { + msg:'Loading. Please wait...' + }); + } + }*/ + }); + w.show(); + } + }); + + exportOption = new Ext.Action({ + text: TRANSLATIONS.ID_EXPORT, + iconCls: 'silk-add', + icon: '/images/export.png', + handler: function(){ + iGrid = Ext.getCmp('infoGrid'); + var rowSelected = iGrid.getSelectionModel().getSelected(); + if( rowSelected ) { + location.href = 'languages_Export?LOCALE='+rowSelected.data.LOCALE+'&rand='+Math.random() + } else { + Ext.Msg.show({ + title:'', + msg: 'first select a language from the list please.', + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } + } + }); + + + removeOption = new Ext.Action({ + text: TRANSLATIONS.ID_DELETE_LANGUAGE, + iconCls: 'silk-add', + icon: '/images/delete-16x16.gif', + handler: function(){ + iGrid = Ext.getCmp('infoGrid'); + var rowSelected = iGrid.getSelectionModel().getSelected(); + if( rowSelected ) { + langId = rowSelected.data.LAN_ID; + langName = rowSelected.data.LAN_NAME; + countryName = rowSelected.data.COUNTRY_NAME; + locale = rowSelected.data.LOCALE; + + confirmMsg = TRANSLATIONS.ID_DELETE_LANGUAGE_CONFIRM; + confirmMsg = confirmMsg.replace('{0}', locale); + Ext.Msg.show({ + title:'', + msg: confirmMsg, + buttons: Ext.Msg.YESNO, + fn: function(btn){ + if( btn == 'yes' ) { + Ext.Ajax.request({ + url: 'language_Ajax', + success: function(response){ + infoGrid.store.reload(); + + Ext.Msg.show({ + title:'', + msg: response.responseText, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + }, + failure: function(){}, + params: { + 'function': 'delete', + 'LOCALE': locale, + 'LAN_ID': langId + } + }); + } + }, + animEl: 'elId', + icon: Ext.MessageBox.QUESTION + }); + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_DELETE_LANGUAGE_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } + + } + }); + + var infoGrid = new Ext.grid.GridPanel( { + /*renderTo: 'list-panel',*/ + region: 'center', + layout: 'fit', + id: 'infoGrid', + stripeRows : true, + autoHeight : true, + autoWidth : true, + title : '', + stateful : true, + stateId : 'grid', + enableColumnHide: false, + enableColumnResize: true, + enableHdMenu: false, + collapsible: false, + animCollapse: false, + + view: new Ext.grid.GroupingView({ + forceFit:true, + //groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})' + groupTextTpl: '{text}' + }), + + + columns : [ + { + dataIndex : 'LAN_FLAG', + id : 'LAN_FLAG', + header : '', + width : 30, + sortable : false, + renderer: function (value, p, r){ + //return String.format("{0}", value, 'color:green;' ); + var e = (value == 'international') ? 'png': 'gif'; + return String.format("", value, e); + } + }, { + dataIndex : 'LAN_ID', + id : 'LAN_ID', + header : '', + width : 35, + sortable : false, + hidden: true + }, { + dataIndex : 'LOCALE', + id : 'LOCALE', + header : 'Locale', + width : 60, + sortable : false + }, { + dataIndex : 'LAN_NAME', + header : TRANSLATIONS.ID_LAN_LANGUAGE, + width : 120, + sortable : false, + hidden: true, + renderer: function (value, p, r){ + if( r.data.DEFAULT == '1' ) + return String.format( + "{0} ({1})", + value, + TRANSLATIONS.ID_LANG_PREDETERMINED + ); + else + return value; + } + }, { + dataIndex : 'COUNTRY_NAME', + header : TRANSLATIONS.ID_LAN_COUNTRY, + width : 120, + sortable : false, + renderer: function (value, p, r){ + if( r.data.LAN_FLAG == 'international' ) + return String.format("({0})", value); + else + return value; + } + }, { + dataIndex : 'DATE', + header : TRANSLATIONS.ID_LAN_UPDATE_DATE, + width : 120, + sortable : false + }, { + dataIndex : 'REV_DATE', + header : TRANSLATIONS.ID_LAN_REV_DATE, + width : 110, + sortable : false + }, { + dataIndex : 'VERSION', + header : TRANSLATIONS.ID_LAN_VERSION, + width : 40, + sortable : false + }, { + dataIndex : 'TRANSLATOR', + header : TRANSLATIONS.ID_LAN_TRANSLATOR, + width : 150, + sortable : false, + hidden: false + }, { + dataIndex : 'NUM_RECORDS', + header : TRANSLATIONS.ID_LAN_NUM_RECORDS, + width : 60, + sortable : false + } + ], + + store: new Ext.data.GroupingStore( { + proxy : new Ext.data.HttpProxy({ + url: 'language_Ajax' + }), + + reader : new Ext.data.JsonReader( { + root : 'data', + fields : [ + {name : 'LAN_FLAG'}, + {name : 'LAN_ID'}, + {name : 'LOCALE'}, + {name : 'LAN_NAME'}, + {name : 'COUNTRY_NAME'}, + {name : 'DATE'}, + {name : 'REV_DATE'}, + {name : 'VERSION'}, + {name : 'TRANSLATOR'}, + {name : 'NUM_RECORDS'} + ] + }), + groupField:'LAN_NAME' + + }), + + tbar:[{ + xtype: 'tbsplit', + text: TRANSLATIONS.ID_ACTIONS, + menu: [removeOption] + }, '-', installOption, exportOption] + + }); + + infoGrid.store.load({params: {"function":"languagesList"}}); + + //////////////////////store.load({params: {"function":"xml"}}); + + //infoGrid.render('list-panel'); + //infoGrid.render(document.body); + //fp.render('form-panel'); + + + var viewport = new Ext.Viewport({ + layout: 'fit', + autoScroll: true, + items: [ + infoGrid + ] + }); + +}); + + +capitalize = function(s){ + s = s.toLowerCase(); + return s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); +}; \ No newline at end of file diff --git a/workflow/engine/templates/setup/mailConnectiontest.php b/workflow/engine/templates/setup/mailConnectiontest.php new file mode 100644 index 000000000..32bef33e1 --- /dev/null +++ b/workflow/engine/templates/setup/mailConnectiontest.php @@ -0,0 +1,104 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification 30/05/2008 + * @Updated Nov 6th, 2009 bye Eriknyk + */ + + + G::LoadClass('net'); + $host = new net($_POST['srv']); + $width_content = '550px'; + + $html = ' +
    +
    + + + + +
    '.G::loadTranslation('ID_SETUP_MAILCONF_TITLE').'
    +
    +
    '; + + $tests = Array( + '', + 'Resolve host name '.$_POST['srv'], + 'Checking port '.$_POST['port'].'', + 'Establishing connection to host '.$host->hostname.'' + ); + $tests[] = 'Login as '.$_POST['account'].' on '.$host->hostname.' SMTP Server'; +// if($_POST['auth_required'] == 'yes'){ +// $tests[] = 'Login as '.$_POST['account'].' on '.$host->hostname.' SMTP Server'; +// } else { +// $tests[] = 'Without autentification!'; +// } + + if($_POST['send_test_mail'] == 'yes'){ + $tests[] = 'Sending a test mail from '.$_POST['account'].' to '.$_POST['mail_to'].'...'; + } + $tree->showSign = false; + $n = Array('','uno','dos','tres','cuatro','cinco'); + for($i=1; $i + + +
    $tests[$i]
    + + + + + + +
    + + + + "; + } + echo '
    +
    +
    + + + + +
    + '.$html.' +
    +
    +
    +
    '; + print (""); diff --git a/workflow/engine/templates/setup/main.html b/workflow/engine/templates/setup/main.html new file mode 100755 index 000000000..af8a2cfb8 --- /dev/null +++ b/workflow/engine/templates/setup/main.html @@ -0,0 +1,24 @@ + + +
    +

    Hi. I'm the west panel.

    +
    +
    + center 2 +
    +
    + center 1 +
    +
    +
    +
    +

    north - generally for informational stuff, also could be for status bar

    +
    +
    +

    south - generally for informational stuff, also could be for status bar

    +
    + + + diff --git a/workflow/engine/templates/setup/main.js b/workflow/engine/templates/setup/main.js new file mode 100755 index 000000000..dd019c064 --- /dev/null +++ b/workflow/engine/templates/setup/main.js @@ -0,0 +1,97 @@ +/* + * @author: Erik A. Ortiz + * Aug 20th, 2010 + */ + +var main = function(){ + Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + + items = Array(); + + for(i=0; i + + + + \ No newline at end of file diff --git a/workflow/engine/templates/setup/pluginsMain.js b/workflow/engine/templates/setup/pluginsMain.js new file mode 100755 index 000000000..e60373167 --- /dev/null +++ b/workflow/engine/templates/setup/pluginsMain.js @@ -0,0 +1,316 @@ +/* + * @author: Erik A. Ortiz + * Aug 20th, 2010 + */ +var processesGrid; +var store; +var comboCategory; + +new Ext.KeyMap(document, { + key: Ext.EventObject.F5, + fn: function(keycode, e) { + if (! e.ctrlKey) { + if (Ext.isIE) + e.browserEvent.keyCode = 8; + e.stopEvent(); + document.location = document.location; + } + else + Ext.Msg.alert('Refresh', 'You clicked: CTRL-F5'); + } +}); + + +Ext.onReady(function(){ + //Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + Ext.QuickTips.init(); + + store = new Ext.data.GroupingStore( { + //var store = new Ext.data.Store( { + proxy : new Ext.data.HttpProxy({ + url: 'pluginsList' + }), + + reader : new Ext.data.JsonReader( { + fields : [ + {name : 'id'}, + {name : 'namespace'}, + {name : 'title'}, + {name : 'className'}, + {name : 'description'}, + {name : 'version'}, + {name : 'setupPage'}, + {name : 'status'}, + {name : 'status_label'}, + {name : 'setup'}, + + {name : 'sFile'}, + {name : 'sStatusFile'} + ] + })//, + //sortInfo:{field: 'PRO_TITLE', direction: "ASC"} + //groupField:'PRO_CATEGORY_LABEL' + + }); + + + var expander = new Ext.ux.grid.RowExpander({ + tpl : new Ext.Template( + '

    '+TRANSLATIONS.ID_DESCRIPTION+': {description}


    ' + ) + }); + + var selModel = new Ext.grid.RowSelectionModel({ + singleSelect : true + }) + + Grid = new Ext.grid.GridPanel( { + region: 'center', + layout: 'fit', + id: 'processesGrid', + height:500, + //autoWidth : true, + width:'', + title : '', + stateful : true, + stateId : 'grid', + enableColumnResize: true, + enableHdMenu: true, + frame:false, + plugins: expander, + cls : '', + columnLines: true, + + + /*view: new Ext.grid.GroupingView({ + //forceFit:true, + //groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})' + groupTextTpl: '{text}' + }),*/ + viewConfig: { + forceFit:true + }, + cm: new Ext.grid.ColumnModel({ + defaults: { + width: 200, + sortable: true + }, + columns: [ + expander, + {id:'id', dataIndex: 'id', hidden:true, hideable:false}, + {header: TRANSLATIONS.ID_DESCRIPTION, dataIndex: 'description', width: 100, hidden:true, hideable:false}, + {header: '', dataIndex: 'namespace', width: 100, hidden:true, hideable:false}, + {header: 'classname', dataIndex: 'className', width: 300, hidden:true, hideable:false}, + {header: TRANSLATIONS.ID_TITLE, dataIndex: 'title'}, + {header: TRANSLATIONS.ID_VERSION, dataIndex: 'version', width: 50}, + {header: TRANSLATIONS.ID_STATUS, dataIndex: 'status_label', width: 40, renderer:function(v,p,r){ + color = r.get('status') == '1'? 'green': 'red'; + return String.format("{1}", color, v); + }}, + + {header: '', dataIndex: 'setup' , hidden:true, hideable:false}, + + {header: '', dataIndex: 'sFile', hidden:true, hideable:false }, + {header: '', dataIndex: 'sStatusFile', hidden:true, hideable:false} + ] + }), + + selModel:selModel, + store: store, + + tbar:[{ + text:TRANSLATIONS.ID_IMPORT, + iconCls: 'silk-add', + icon: '/images/import.gif', + handler:importProcess + },{ + xtype: 'tbseparator' + }, + { + id:'setup', + text:TRANSLATIONS.ID_CONFIGURE, + iconCls: 'silk-add', + icon: '/images/options.png', + handler:configure + }, + { + text:TRANSLATIONS.ID_STATUS, + id:'activator', + icon: '', + iconCls: 'silk-add', + handler: activeDeactive, + disabled:true + },{ + text:TRANSLATIONS.ID_DELETE, + iconCls: 'silk-add', + icon: '/images/delete-16x16.gif', + handler:deletePlugin + } + ], + listeners: { + render: function(){ + this.loadMask = new Ext.LoadMask(this.body, {msg:'Loading...'}); + //this.ownerCt.doLayout(); + Grid.getSelectionModel().on('rowselect', function(){ + + var rowSelected = Grid.getSelectionModel().getSelected(); + //alert(rowSelected.data.PRO_STATUS); + var activator = Ext.getCmp('activator'); + var setup = Ext.getCmp('setup'); + activator.setDisabled(false); + + if( rowSelected.data.status == 1 ){ + activator.setIcon('/images/deactivate.png'); + activator.setText('Deactivate'); + } else { + activator.setIcon('/images/activate.png'); + activator.setText('Activate'); + } + //alert(rowSelected.data.setup); + if( rowSelected.data.setup == 1 ){ + setup.setDisabled(false); + } else { + setup.setDisabled(true); + } + + }); + } + } + + }); + + Grid.store.load({params: {"function":"pluginsList"}}); + + //////////////////////store.load({params: {"function":"xml"}}); + + + //processesGrid.render('processes-panel'); + + //processesGrid.render(document.body); + //fp.render('form-panel'); + + + var viewport = new Ext.Viewport({ + layout: 'border', + autoScroll: true, + items: [ + Grid + ] + }); +}); + + +deletePlugin = function(){ + var rowSelected = Grid.getSelectionModel().getSelected(); + //var rows = processesGrid.getSelectionModel().getSelections(); + if( rowSelected ) { + namespace = rowSelected.get('namespace'); + Ext.Msg.confirm( + TRANSLATIONS.ID_CONFIRM, TRANSLATIONS.ID_MSG_REMOVE_PLUGIN, + function(btn, text){ + if ( btn == 'yes' ){ + Ext.MessageBox.show({ msg: TRANSLATIONS.ID_DELETING_ELEMENTS, wait:true,waitConfig: {interval:200} }); + Ext.Ajax.request({ + url: 'pluginsRemove', + success: function(response) { + Ext.MessageBox.hide(); + Grid.store.reload(); + }, + params: {pluginUid:namespace} + }); + } + } + ); + + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_NO_SELECTION_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } +} + +importProcess = function(){ + window.location = 'pluginsImport'; +} + +browseLibrary = function(){ + window.location = 'processes_Library'; +} + +function activeDeactive(){ + var rowSelected = Grid.getSelectionModel().getSelected(); + //var rows = Grid.getSelectionModel().getSelections(); + + if( rowSelected ) { + var ids = ''; + + status = rowSelected.get('status'); + file = rowSelected.get('sFile'); + + Ext.Ajax.request({ + url : 'pluginsChange?id='+file+'&status='+status , + params : { UIDS : ids }, + method: 'GET', + success: function ( result, request ) { + //Ext.MessageBox.alert('Success', 'Data return from the server: '+ result.responseText); + store.reload(); + + plugins = parent.Ext.getCmp('plugins'); + + plugins.root.reload(); + + var activator = Ext.getCmp('activator'); + activator.setDisabled(true); + activator.setText('Status'); + activator.setIcon(''); + }, + failure: function ( result, request) { + Ext.MessageBox.alert('Failed', result.responseText); + } + }); + + //window.location = 'processes_ChangeStatus?PRO_UID='+rowSelected.data.PRO_UID; + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_NO_SELECTION_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } +} + +var configure = function(){ + var rowSelected = Grid.getSelectionModel().getSelected(); + //var rows = Grid.getSelectionModel().getSelections(); + + if( rowSelected ) { + file = rowSelected.get('sFile'); + window.location = 'pluginsSetup?id='+file; + + } else { + Ext.Msg.show({ + title:'', + msg: TRANSLATIONS.ID_NO_SELECTION_WARNING, + buttons: Ext.Msg.INFO, + fn: function(){}, + animEl: 'elId', + icon: Ext.MessageBox.INFO, + buttons: Ext.MessageBox.OK + }); + } +} + +capitalize = function(s){ + s = s.toLowerCase(); + return s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); +}; diff --git a/workflow/engine/templates/setup/tools.html b/workflow/engine/templates/setup/tools.html new file mode 100755 index 000000000..cdc04bc47 --- /dev/null +++ b/workflow/engine/templates/setup/tools.html @@ -0,0 +1,76 @@ + + + + + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/workflow/engine/templates/setup/uplogo.html b/workflow/engine/templates/setup/uplogo.html new file mode 100755 index 000000000..3e9b982b7 --- /dev/null +++ b/workflow/engine/templates/setup/uplogo.html @@ -0,0 +1,36 @@ +
    + +
    + + + + +
    +
    + + +
    + +
    +
    diff --git a/workflow/engine/templates/setup/uplogo.php b/workflow/engine/templates/setup/uplogo.php new file mode 100755 index 000000000..f90b46f6a --- /dev/null +++ b/workflow/engine/templates/setup/uplogo.php @@ -0,0 +1,127 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + G::LoadClass('replacementLogo'); + $uplogo = PATH_TPL . 'setup' . PATH_SEP . 'uplogo.html' ; + $template = new TemplatePower( $uplogo ); + $template->prepare(); + $width="100%"; + + $template->assign ('WIDTH_PANEL' ,$width); + $template->assign ('WIDTH_PANEL_20' ,$width-20); + + $upload = new replacementLogo(); + $aFotoSelect = $upload->getNameLogo($_SESSION['USER_LOGGED']); + $sFotoSelect = trim($aFotoSelect['DEFAULT_LOGO_NAME']); + $check =''; + $ainfoSite = explode("/",$_SERVER["REQUEST_URI"]); + $dir=PATH_DATA."sites".PATH_SEP.str_replace("sys","",$ainfoSite[1]).PATH_SEP."files/logos"; + G::mk_dir ( $dir ); + $i=0; + + /** if we have at least one image it's load */ + if (file_exists($dir)) { + if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if(($file!=".")&&($file!="..")) { + $extention=explode(".", $file); + $aImageProp=getimagesize($dir.'/'.$file, $info); + $sfileExtention = strtoupper($extention[count($extention)-1]); +// if( $sfileExtention == 'JPG' || $sfileExtention == 'PNG' || $sfileExtention == 'GIF' ) { + if( in_array($sfileExtention, array('JPG','JPEG','PNG','GIF') ) ) { + + $check = (!strcmp($file,$sFotoSelect))?'/images/toadd.png':'/images/delete.png'; + $onclick = (strcmp($file,$sFotoSelect))? "onclick ='deleteLogo(\" $file \");return false;'":''; + /** if we have at least one image we show the restore image */ + if($i==0){ + $template->newBlock( 'logo_Detail'); + $template->assign ('TR1' , ($i%3==0)?'':'' ); + $template->assign ('TR2' , ($i%3==2)?'':''); + $template->assign ('LOG0_IMAGE' , "/images/processmaker.logo.jpg"); + $logopm="Restore_the_default_logo"; + //$template->assign ('LOG0_NAME' , str_replace("_"," ",$logopm)); + $template->assign ('LOGO_WIDTH' , "200"); + $template->assign ('LOGO_HEIGHT' , "80" ); + $template->assign ('LOG0_SIZE' , "15.36"); + $template->assign ('LOG0_DELETE' , "onclick ='changeLogo(\" \");return false;'"); + $template->assign ('LOG0_CHECK' , "/images/favicon.ico"); + + $i++; + } + $template->newBlock( 'logo_Detail'); + $template->assign ('TR1' , ($i%3==0)?'':'' ); + $template->assign ('TR2' , ($i%3==2)?'':'' ); + $template->assign ('LOG0_IMAGE' , "showLogoFile.php?id=".G::encrypt($file,'imagen') ); + $template->assign ('LOG0_NAME' , $file ); + $template->assign ('LOG0_DESCRIPTION', $extention[count($extention)-1] ); + $template->assign ('LOGO_CHARACT' , $aImageProp[3] ); + $template->assign ('LOGO_WIDTH' , $aImageProp[0] ); + $template->assign ('LOGO_HEIGHT' , $aImageProp[1] ); + $template->assign ('LOG0_SIZE' , round( (filesize($dir.'/'.$file) / 1024) *100)/100 ); + $template->assign ('LOG0_DELETE' , $onclick ); + $template->assign ('LOG0_CHECK' , $check ); + $i++; + } + } + } + closedir($handle); + } + } + + // if we have at least one image we show the restore image + /*if($i>0) { + $template->gotoBlock( "_ROOT" ); + $restoreLogo =" + +
    + ".G::LoadTranslation('ID_RESTORE_LOGO')." +
    "; + $template->assign ('SET_LOGO_PM' ,$restoreLogo); + }*/ + if (sizeof($_POST)>0) { + //G::SendTemporalMessage('ID_CHANGES_SAVED', 'info', 'labels'); + $formf = $_FILES['form']; + $namefile = $formf['name']['LOGO_FILENAME']; + $typefile = $formf['type']['LOGO_FILENAME']; + $errorfile = $formf['error']['LOGO_FILENAME']; + $tpnfile = $formf['tmp_name']['LOGO_FILENAME']; + $aMessage1 = array(); + $fileName = trim(str_replace(' ','_', $namefile)); + G::uploadFile( $tpnfile, $dir . '/', 'tmp'.$fileName ); + G::resizeImage($dir . '/tmp' . $fileName, 200, 80, $dir . '/' .$fileName); + unlink ($dir . '/tmp' . $fileName); + header('location: uplogo.php'); + } + $content = $template->getOutputContent(); + print $content; +} +catch (Exception $e) { + $G_PUBLISH = new Publisher; + $aMessage['MESSAGE'] = $e->getMessage(); + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publishBlank', 'blank' ); + die(); +} diff --git a/workflow/engine/templates/setup/webServicesTree.php b/workflow/engine/templates/setup/webServicesTree.php new file mode 100644 index 000000000..0dbef99db --- /dev/null +++ b/workflow/engine/templates/setup/webServicesTree.php @@ -0,0 +1,133 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +//G::genericForceLogin( 'WF_MYINFO' , 'login/noViewPage', $urlLogin = 'login/login' ); + +G::LoadClass ( 'tree' ); + +$wsSessionId = ''; +if (isset ( $_SESSION ['WS_SESSION_ID'] )) { + $wsSessionId = $_SESSION ['WS_SESSION_ID']; +} + +if (isset ( $_GET ['x'] )) { + if ($_GET ['x'] == 1) { + $wsdl = $_SESSION ['END_POINT']; + $workspace = $_SESSION ['WS_WORKSPACE']; + } else { + $wsdl = '' . G::LoadTranslation ( 'ID_WSDL' ) . ''; + $workspace = ''; + } +} else { + if (! isset ( $_SESSION ['END_POINT'] )) { + //$wsdl = 'http://'.$_SERVER['HTTP_HOST'].'/sys'.SYS_SYS.'/en/green/services/wsdl'; + $wsdl = 'http://' . $_SERVER ['HTTP_HOST']; + $workspace = SYS_SYS; + } else { + $wsdl = $_SESSION ['END_POINT']; + $workspace = $_SESSION ['WS_WORKSPACE']; + } +} + +$defaultEndpoint = 'http://' . $_SERVER ['SERVER_NAME'] . ':' . $_SERVER ['SERVER_PORT'] . '/sys' . SYS_SYS . '/en/green/services/wsdl2'; + +$wsdl = isset ( $_SESSION ['END_POINT'] ) ? $_SESSION ['END_POINT'] : $defaultEndpoint; + +$tree = new Tree ( ); +$tree->name = 'WebServices'; +$tree->nodeType = "base"; +$tree->contentWidth = "310"; +$tree->width = "280px"; +$tree->value = ' +
    +
    + + + + + +
    ' . G::loadTranslation ( "ID_WEB_SERVICES" ) . '
    +
    +
    + + + + '; + +$tree->showSign = false; + +$allWebservices = array (); +$allWebservices [] = 'Login'; +$allWebservices [] = 'CreateUser'; +$allWebservices [] = 'AssignUserToGroup'; +$allWebservices [] = 'NewCase'; +$allWebservices [] = 'NewCaseImpersonate'; +$allWebservices [] = 'DerivateCase'; +$allWebservices [] = 'SendVariables'; +$allWebservices [] = 'SendMessage'; +$allWebservices [] = 'ProcessList'; +$allWebservices [] = 'CaseList'; +$allWebservices [] = 'RoleList'; +$allWebservices [] = 'GroupList'; +$allWebservices [] = 'UserList'; +$allWebservices [] = 'TaskList'; +$allWebservices [] = 'TriggerList'; +$allWebservices [] = 'InputDocumentList'; +$allWebservices [] = 'SendFiles'; +$allWebservices [] = 'InputDocumentProcessList'; +$allWebservices [] = 'OutputDocumentList'; +$allWebservices [] = 'RemoveDocument'; +$allWebservices [] = 'TaskCase'; +$allWebservices [] = 'ReassignCase'; + +foreach ( $allWebservices as $ws ) { + $ID_TEST = G::LoadTranslation ( 'ID_TEST' ); + $UID = htmlentities ( $ws ); + $WS_TITLE = strip_tags ( $ws ); + + $htmlGroup = ''; + $htmlGroup .= ""; + $htmlGroup .= ""; + $htmlGroup .= ""; + $htmlGroup .= "
    {$WS_TITLE}"; + + if($WS_TITLE !='SendFiles'){ + if ($WS_TITLE == 'Login' || $wsSessionId != '') + $htmlGroup .= "[{$ID_TEST}]"; + } else { + if(isset($_SESSION ['WS_SESSION_ID'])&&$_SESSION ['WS_SESSION_ID']!=''){ + $htmlGroup .= "[{$ID_TEST}]"; + } + } + $htmlGroup .= "
    "; + + $ch = & $tree->addChild ( $ws, $htmlGroup, array ('nodeType' => 'child' ) ); + $ch->point = ''; +} +print ($tree->render ()) ; + diff --git a/workflow/engine/templates/steps/triggers_Tree.php b/workflow/engine/templates/steps/triggers_Tree.php new file mode 100644 index 000000000..4ab0bda78 --- /dev/null +++ b/workflow/engine/templates/steps/triggers_Tree.php @@ -0,0 +1,116 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + G::LoadClass('tree'); + G::LoadClass('processMap'); + //call plugin + $oPluginRegistry = &PMPluginRegistry::getSingleton(); + $externalSteps = $oPluginRegistry->getSteps(); + + $oProcessMap = new ProcessMap(); + $oTree = new Tree(); + $oTree->nodeType = 'blank'; + $oTree->name = 'Triggers'; + $oTree->showSign = false; + $oCriteria = new Criteria('workflow'); + $oCriteria->add(StepPeer::PRO_UID, $_SESSION['PROCESS']); + $oCriteria->add(StepPeer::TAS_UID, $_SESSION['TASK']); + $oCriteria->addAscendingOrderByColumn(StepPeer::STEP_POSITION); + $oDataset = StepPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $i = 0; + while ($aRow = $oDataset->getRow()) { + switch ($aRow['STEP_TYPE_OBJ']) { + case 'DYNAFORM': + require_once 'classes/model/Dynaform.php'; + $oObject = new Dynaform(); + $aFields = $oObject->load($aRow['STEP_UID_OBJ']); + $aRow['STEP_NAME'] = $aFields['DYN_TITLE']; + break; + case 'INPUT_DOCUMENT': + require_once 'classes/model/InputDocument.php'; + $oObject = new InputDocument(); + $aFields = $oObject->load($aRow['STEP_UID_OBJ']); + $aRow['STEP_NAME'] = $aFields['INP_DOC_TITLE']; + break; + case 'OUTPUT_DOCUMENT': + require_once 'classes/model/OutputDocument.php'; + $oObject = new OutputDocument(); + $aFields = $oObject->load($aRow['STEP_UID_OBJ']); + $aRow['STEP_NAME'] = $aFields['OUT_DOC_TITLE']; + break; + case 'EXTERNAL': + $aRow['STEP_NAME'] = 'unknown ' . $aRow['STEP_UID']; + foreach ( $externalSteps as $key=>$val ) { + if ( $val->sStepId == $aRow['STEP_UID_OBJ'] ) + $aRow['STEP_NAME'] = $val->sStepTitle; + } + break; + } + $oCriteria = $oProcessMap->getStepTriggersCriteria($aRow['STEP_UID'], $_SESSION['TASK'], 'BEFORE'); + $iCantidad1 = StepTriggerPeer::doCount($oCriteria); + $oCriteria = $oProcessMap->getStepTriggersCriteria($aRow['STEP_UID'], $_SESSION['TASK'], 'AFTER'); + $iCantidad2 = StepTriggerPeer::doCount($oCriteria); + $oNode =& $oTree->addChild($aRow['STEP_UID'], '  ' . $aRow['STEP_NAME'] . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' (' . ($iCantidad1 + $iCantidad2) . ')' . '', array('nodeType'=>'parent')); + $oNode->contracted = true; + $oAux1 =& $oNode->addChild('before_node', '' . G::LoadTranslation('ID_BEFORE') . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' ('. $iCantidad1 .') ', array('nodeType'=>'parent')); + $oAux1->plus = ""; + $oAux1->contracted = true; + $oAux2 =& $oAux1->addChild($aRow['STEP_UID'] . '_before_node', '', array('nodeType'=>'parentBlue')); + $oAux1 =& $oNode->addChild('after_node', '' . G::LoadTranslation('ID_AFTER') . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' ('. $iCantidad2 .') ', array('nodeType'=>'parent')); + $oAux1->plus = ""; + $oAux1->contracted = true; + $oAux2 =& $oAux1->addChild($aRow['STEP_UID'] . '_after_node', '', array('nodeType'=>'parentBlue')); + $oDataset->next(); + } + $oCriteria = $oProcessMap->getStepTriggersCriteria(-1, $_SESSION['TASK'], 'BEFORE'); + $iCantidad1 = StepTriggerPeer::doCount($oCriteria); + $oCriteria = $oProcessMap->getStepTriggersCriteria(-2, $_SESSION['TASK'], 'BEFORE'); + $iCantidad2 = StepTriggerPeer::doCount($oCriteria); + $oCriteria = $oProcessMap->getStepTriggersCriteria(-2, $_SESSION['TASK'], 'AFTER'); + $iCantidad3 = StepTriggerPeer::doCount($oCriteria); + $oNode =& $oTree->addChild('-1', '  [ ' . G::LoadTranslation('ID_ASSIGN_TASK') . ' ] ' . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' (' . ($iCantidad1 + $iCantidad2 + $iCantidad3) . ')' . '', array('nodeType'=>'parent')); + $oNode->contracted = true; + $oAux1 =& $oNode->addChild('before_node', '' . G::LoadTranslation('ID_BEFORE_ASSIGNMENT') . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' ('. $iCantidad1 .') ', array('nodeType'=>'parent')); + $oAux1->plus = ""; + $oAux1->contracted = true; + $oAux2 =& $oAux1->addChild('-1_before_node', '', array('nodeType'=>'parentBlue')); + $oAux1 =& $oNode->addChild('before_node', '' . G::LoadTranslation('ID_BEFORE_DERIVATION') . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' ('. $iCantidad2 .') ', array('nodeType'=>'parent')); + $oAux1->plus = ""; + $oAux1->contracted = true; + $oAux2 =& $oAux1->addChild('-2_before_node', '', array('nodeType'=>'parentBlue')); + $oAux1 =& $oNode->addChild('after_node', '' . G::LoadTranslation('ID_AFTER_DERIVATION') . ' - ' . G::LoadTranslation('ID_TRIGGERS'). ' ('. $iCantidad3 .') ', array('nodeType'=>'parent')); + $oAux1->plus = ""; + $oAux1->contracted = true; + $oAux2 =& $oAux1->addChild('-2_after_node', '', array('nodeType'=>'parentBlue')); + echo $oTree->render(); +} +catch (Exception $oException) { + die($oException->getMessage()); +} +unset($_SESSION['PROCESS']); +?> \ No newline at end of file diff --git a/workflow/engine/templates/testAuthenticationSource.html b/workflow/engine/templates/testAuthenticationSource.html new file mode 100644 index 000000000..231054607 --- /dev/null +++ b/workflow/engine/templates/testAuthenticationSource.html @@ -0,0 +1,17 @@ + + +
    + + + + + + + + +
    Testing Log
    + + +
    + {text}
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/testAuthenticationUser.php b/workflow/engine/templates/testAuthenticationUser.php new file mode 100644 index 000000000..f22b244e9 --- /dev/null +++ b/workflow/engine/templates/testAuthenticationUser.php @@ -0,0 +1,66 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + $strPass = $_POST['form'][PASS]; + + if ( $strPass == '' ) + return; + + $userId = $_SESSION['CURRENT_USER']; + + $tpl = new TemplatePower( PATH_TPL . 'testAuthenticationSource.html' ); + $tpl->prepare(); + $tpl->assign( "STYLE_CSS" , STYLE_CSS ); + $tpl->assign( "title" , $G_TABLE->title ); + + $curAuthSource = $HTTP_SESSION_VARS['CURRENT_AUTH_SOURCE']; + $dbc = new DBConnection(DB_HOST, DB_RBAC_USER, DB_RBAC_PASS, DB_RBAC_NAME ); + + //Class user + G::LoadClassRBAC ("user"); + $user = new RBAC_User; + $user->SetTo ($dbc); + $user->Load ($userId); + + //crear nueva authentication source + G::LoadClassRBAC ('authentication'); + $obj = new authenticationSource; + $obj->SetTo( $dbc ); + $res = $obj->verifyPassword ( $userId, $user->Fields['USR_LDAP_DN'] , $strPass, $user->Fields['USR_LDAP_SOURCE'] ); + +//print ""; + + foreach ( $obj->vlog as $line ) { + if ( stristr ($line, 'error' ) !== false ) $line = "" . $line . ''; + if ( stristr ($line, 'sucess' ) !== false ) $line = "" . $line . ''; + + $tpl->newBlock( "lines" ); + $tpl->assign( "text" , $line ); + } + $tpl->gotoBlock( "_ROOT" ); + $tpl->printToScreen(); + +?> \ No newline at end of file diff --git a/workflow/engine/templates/toolbar.html b/workflow/engine/templates/toolbar.html new file mode 100644 index 000000000..f174cb04d --- /dev/null +++ b/workflow/engine/templates/toolbar.html @@ -0,0 +1,32 @@ +{if $printTemplate} +{* this is the xmlform template *} + + +{* LEFT MENU *} + + +
    +{php}$this->assign('cols', 0);{/php} +{foreach from=$form->fields item=field index=abc} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='')} +{else} +{* elseif ($field->type==='link') || ($field->type==='menu') *}{$field->field}{/if} +{/foreach} + +{php} +//This will add registered HTML toolbar options from plugins +$oPluginRegistry =& PMPluginRegistry::getSingleton(); +$oPluginRegistry->getToolbarOptions("NORMAL"); +{/php} +
    +{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +{/if} \ No newline at end of file diff --git a/workflow/engine/templates/tools/methodsPermissions.php b/workflow/engine/templates/tools/methodsPermissions.php new file mode 100644 index 000000000..055df6e90 --- /dev/null +++ b/workflow/engine/templates/tools/methodsPermissions.php @@ -0,0 +1,144 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + G::LoadClass('tree'); + /* + * Esto no deberias borrarlo + */ + $tree = new Tree(); + + reView(PATH_TRUNK,$tree); + print( $tree->render() ); + + function reView($path,&$tree) + { + $tree->name = $path; + $tree->value = $path . ' '. + setHeader('Set Header','setDirHeader("'.$path.'",this);'). + selectPermissions('Set Permission','setDirPermission("'.$path.'",this);'). + selectPermissions('Remove Permission','removeDirPermission("'.$path.'",this);'); + $tree->contracted = true; + foreach(glob($path.'*',GLOB_MARK) as $file) + { + if (is_dir($file)) + { + reView($file,$tree->addChild($file, $file )); + } + elseif (substr($file,-4,4)==='.php') + { + $nodeFile=&$tree->addChild + ( + $file, $file . ' '. + selectPermissions('Set Permission','setPermission("'.$file.'",this);'). + selectPermissions('Remove Permission','removePermission("'.$file.'",this);') + ); + $nodeFile->addChild("View Permissions",'
    View Permissions
    '); + $nodeFile->addChild("Add Line",'Add Permission
    '); + $nodeFile->contracted = true; + } + } + } + function selectPermissions($label,$onchange) + { + return ''; + } + function setHeader($label,$onchange) + { + return ''; + } +?> + + \ No newline at end of file diff --git a/workflow/engine/templates/tracker/stages_Map.html b/workflow/engine/templates/tracker/stages_Map.html new file mode 100644 index 000000000..9adfbab65 --- /dev/null +++ b/workflow/engine/templates/tracker/stages_Map.html @@ -0,0 +1,2 @@ +
    +
    \ No newline at end of file diff --git a/workflow/engine/templates/tree.html b/workflow/engine/templates/tree.html new file mode 100644 index 000000000..f96d38b60 --- /dev/null +++ b/workflow/engine/templates/tree.html @@ -0,0 +1,127 @@ +{if ($node->nodeType==='base')} +{* This is the default "html" for any type of node *} +
    +
    +
    +
    +
    +
    + +
    + + value==''}style="display:none"{/if}> + + + + contracted}style="display:none"{/if}> + + + +
    + {$node->printPlus()} + + {$node->printLabel()} +
    + {$node->printContent()} +
    +
    + +
    +
    +
    +
    +
    +
    +{elseif ($node->nodeType==='parent')} +{* This is the default "html" for node with nodeType="parent" *} +
    + + value==''}style="display:none"{/if}> + + + + contracted}style="display:none"{/if}> + + + +
    + {$node->printPlus()} + + {$node->printLabel()} +
    + {$node->printContent()} +
    +
    +{elseif ($node->nodeType==='parentBlue')} +{* This is the default "html" for node with nodeType="parent" *} +
    +
    +
    +
    +
    +
    +
    + + value==''}style="display:none"{/if}> + + + + contracted}style="display:none"{/if}> + + + +
    + {$node->printPlus()} + + {$node->printLabel()} +
    + {$node->printContent()} +
    +
    +
    +
    +
    +
    +
    +
    +{elseif ($node->nodeType==='child')} +{* This is the default "html" for node with nodeType="child" *} +
    + + value==''}style="display:none"{/if}> + + + + contracted}style="display:none"{/if}> + + + +
    + {$node->printPlus()} + + {$node->printLabel()} +
    + {$node->printContent()} +
    +
    +{elseif ($node->nodeType==='blank')} +{* This is the default "html" for node with nodeType="child" *} +
    + + value==''}style="display:none"{/if}> + + + + contracted}style="display:none"{/if}> + + + +
    + {$node->printPlus()} + + {$node->printLabel()} +
    + {$node->printContent()} +
    +
    +{/if} diff --git a/workflow/engine/templates/triggers/triggersTree.php b/workflow/engine/templates/triggers/triggersTree.php new file mode 100644 index 000000000..db2343fe9 --- /dev/null +++ b/workflow/engine/templates/triggers/triggersTree.php @@ -0,0 +1,77 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + G::LoadClass ( 'tree' ); + + G::LoadClass ( 'triggerLibrary' ); + $triggerLibrary = triggerLibrary::getSingleton (); + $triggerLibraryO = $triggerLibrary->getRegisteredClasses (); + $oTree = new Tree ( ); + $oTree->nodeType = 'blank'; + $oTree->name = 'Triggers'; + $oTree->showSign = false; + + $oNode = & $oTree->addChild ( 'TRI_CUSTOM', '  
    ' . "  " .G::LoadTranslation('ID_CUSTOM_TRIGGER') . " 
    ".G::LoadTranslation('ID_CUSTOM_TRIGGER_DESCRIPTION')."
    ", array ('nodeType' => 'parent' ) ); + + $triggerLibraryOCount=count($triggerLibraryO); + foreach ( $triggerLibraryO as $keyLibrary => $libraryObj ) { + $libraryName = $libraryObj->info ['name']; + $libraryIcon = isset ( $libraryObj->info ['icon'] ) && ($libraryObj->info ['icon'] != "") ? $libraryObj->info ['icon'] : "/images/browse.gif"; + $libraryDescription = trim ( str_replace ( "*", "", implode ( " ", $libraryObj->info ['description'] ) ) ); + $triggerCount = count ( $libraryObj->methods ); + if ($triggerCount > 0) { + //Sort alpha + ksort($libraryObj->methods,SORT_STRING); + //Now the Triggers + //Library Father (Name + Description) + $oNode = & $oTree->addChild ( $keyLibrary, '  
    ' . "  " . $libraryName . " ($triggerCount)
    $libraryDescription
    ", array ('nodeType' => 'parent' ) ); + $oNode->contracted = $triggerLibraryOCount==1?false:true; + //Library Childs (available methods) + foreach ( $libraryObj->methods as $methodName => $methodObject ) { + + $methodName = $methodObject->info ['name']; + $methodLabel = $methodObject->info ['label']; + $methodDescription = trim ( str_replace ( "*", "", implode ( " ", $methodObject->info ['description'] ) ) ); + + $oAux1 = & $oNode->addChild ( $keyLibrary . "-" . $methodName, '
    ' . " " . $methodLabel . ' (' . $methodName . ')' . '
    ' . $methodDescription . '
    ', array ('nodeType' => 'child' ) ); + //$oAux1->plus = ""; + + + //$oAux2 =& $oAux1->addChild($keyLibrary."-".$methodName."-desc", "$methodParameters", array('nodeType'=>'parent')); + + + } + } + + } + echo $oTree->render (); + + +} catch ( Exception $oException ) { + die ( $oException->getMessage () ); +} +unset ( $_SESSION ['PROCESS'] ); +?> \ No newline at end of file diff --git a/workflow/engine/templates/triggers/triggers_CreateWizard.html b/workflow/engine/templates/triggers/triggers_CreateWizard.html new file mode 100755 index 000000000..422318f11 --- /dev/null +++ b/workflow/engine/templates/triggers/triggers_CreateWizard.html @@ -0,0 +1,171 @@ + + + + + + + + +
    + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + {METHOD_LABEL} {PMFUNTION_LABEL} ({PMFUNTION}) +
    + {PMFUNTION_DESCRIPTION} + + +   (More Info) + + + +
     
    + {DETAILS_LABEL} +
    {TITLE}
    {DESCRIPTION}
    + {PARAMETERS_LABEL} +
    {LABEL_PARAMETER} {ADD_TRI_VARIABLE} +
      + {ADD_TRI_DESCRIPTION} + +
    + {RETURN_TITLE} +
    {RETURN_LABEL} +
      + {RETURN_DESCRIPTION} +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    diff --git a/workflow/engine/templates/triggers/triggers_CreateWizard.php b/workflow/engine/templates/triggers/triggers_CreateWizard.php new file mode 100755 index 000000000..bc210bbde --- /dev/null +++ b/workflow/engine/templates/triggers/triggers_CreateWizard.php @@ -0,0 +1,134 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + + G::LoadClass ( 'triggerLibrary' ); + $triggerLibrary = triggerLibrary::getSingleton (); + $libraryClassName = $_GET ['LIBRARY']; + $libraryMethod = $_GET ['NAME_FUN']; + $sProUid = $_GET ['PRO_UID']; + $libraryO = $triggerLibrary->getLibraryDefinition ( $libraryClassName ); + + $libraryName = $libraryO->info ['name']; + $libraryDescription = trim ( str_replace ( "*", "", implode ( " ", $libraryO->info ['description'] ) ) ); + $libraryIcon = isset ( $libraryO->info ['icon'] ) && ($libraryO->info ['icon'] != "") ? $libraryO->info ['icon'] : "/images/browse.gif"; + $aDataTrigger = $_GET; + + $sProUid = $aDataTrigger ['PRO_UID']; + $sNameFun = $aDataTrigger ['NAME_FUN']; + + $methodObject = $libraryO->methods [$sNameFun]; + + $methodName = $methodObject->info ['name']; + $methodLabel = $methodObject->info ['label']; + $methodDescription = trim ( str_replace ( "*", "", implode ( " ", $methodObject->info ['description'] ) ) ); + $methodReturn = $methodObject->info ['return']; + $methodParameters = array_keys ( $methodObject->params ); + $methodLink = isset ( $methodObject->info ['link'] ) && ($methodObject->info ['link'] != "") ? $methodObject->info ['link'] : ""; + $methodreturnA = explode ( "|", $methodReturn ); + $methodReturnLabel = isset ( $methodreturnA [3] ) ? $methodreturnA [3] : $methodReturn; + + $aParametersFun = $methodParameters; + $triggerWizardTemplate = PATH_TPL . 'triggers' . PATH_SEP . 'triggers_CreateWizard.html'; + $template = new TemplatePower ( $triggerWizardTemplate ); + $template->prepare (); + + $tds = ''; + $nrows = 2; + + $template->assign ( 'LIBRARY_NAME', $libraryName ); + $template->assign ( 'LIBRARY_DESCRIPTION', $libraryDescription ); + $template->assign ( 'LIBRARY_ICON', $libraryIcon ); + $template->assign ( 'LIBRARY_CLASS', $libraryClassName ); + if ($methodLink != "") { + $template->newBlock ( 'methodLink' ); + $template->assign ( 'LIBRARY_METHOD_LINK', $methodLink ); + $template->gotoBlock ( '_ROOT' ); + } + + $template->assign ( 'PMFUNTION', $sNameFun ); + $template->assign ( 'PMFUNTION_LABEL', $methodLabel ); + $template->assign ( 'PMFUNTION_DESCRIPTION', $methodDescription ); + $template->assign ( 'TITLE', G::LoadTranslation ( 'ID_TITLE' ) ); + $template->assign ( 'DESCRIPTION', G::LoadTranslation ( 'ID_DESCRIPTION' ) ); + $template->assign ( 'DETAILS_LABEL', G::LoadTranslation ( 'ID_DETAILS' ) ); + $template->assign ( 'RETURN_TITLE', G::LoadTranslation ( 'ID_TRIGGER_RETURN_TITLE' ) ); + $template->assign ( 'RETURN_LABEL', G::LoadTranslation ( 'ID_TRIGGER_RETURN_LABEL' ) ); + $template->assign ( 'METHOD_LABEL', G::LoadTranslation ( 'ID_METHOD' ) ); + $template->assign ( 'ROWS', sizeof ( $aParametersFun ) + 3 ); + $template->assign ( 'TRIGGER_INFORMATION', 'Trigger Information' ); + $template->assign ( 'TRIGGER_ACTION', '../triggers/triggers_WizardSave' ); + $template->assign ( 'PRO_UID', $sProUid ); + $template->assign ( 'PAGED_TABLE_ID', $aDataTrigger ['PAGED_TABLE_ID'] ); + $template->assign ( 'RETURN_DESCRIPTION', $methodReturnLabel ); + $template->assign ( 'ID_SAVE', G::LoadTranslation ( 'ID_SAVE' ) ); + $template->assign ( 'ID_CANCEL', G::LoadTranslation ( 'ID_CANCEL' ) ); + + $sPMfunction = $sNameFun . " ("; + $methodParametersOnlyNames = array (); + if (count ( $aParametersFun ) > 0) { + $template->newBlock ( 'paremetersTriggersGroup' ); + $template->assign ( 'PARAMETERS_LABEL', G::LoadTranslation ( 'ID_PARAMETERS' ) ); + foreach ( $aParametersFun as $k => $v ) { + if ($v != '') { + $aParametersFunA = explode ( "|", $v ); + $paramType = $aParametersFunA [0]; + $paramDefinition = $aParametersFunA [1]; + $paramDefinitionA = explode ( "=", $paramDefinition ); + $paramName = $paramDefinitionA [0]; + $methodParametersOnlyNames [] = $paramName; + $paramDefaultValue = isset ( $paramDefinitionA [1] ) ? $paramDefinitionA [1] : ""; + $paramLabel = isset ( $aParametersFunA [2] ) ? $aParametersFunA [2] : $paramName; + $paramDescription = isset ( $aParametersFunA [3] ) ? $aParametersFunA [3] : ""; + $sPMfunction .= ($nrows != 2) ? ', "' . trim ( str_replace ( "$", "", $paramName ) ) . '"' : '"' . trim ( str_replace ( "$", "", $paramName ) . '"' ); + $template->newBlock ( 'paremetersTriggers' ); + $template->assign ( 'LABEL_PARAMETER', $paramLabel ); + $template->assign ( 'OPT_PARAMETER', trim ( str_replace ( "$", "", $paramName ) ) ); + $sNameTag = 'form.' . trim ( str_replace ( "$", "", $paramName ) ) . '.name'; + $sNameTag = trim ( $sNameTag ); + $template->assign ( 'SNAMETAG', $sNameTag ); + $tri_Button = ""; + $template->assign ( 'ADD_TRI_VARIABLE', $tri_Button ); + $template->assign ( 'ADD_TRI_VALUE', str_replace ( "'", "", str_replace ( '"', '', $paramDefaultValue ) ) ); + $fieldDescription = ($paramDescription!="")?$paramDescription . "
    ":""; + $fieldDescription .= $paramDefaultValue != "" ? $paramDefaultValue . " | " . $paramType : G::LoadTranslation ( "ID_REQUIRED_FIELD" ) . " | " . $paramType; + $template->assign ( 'ADD_TRI_DESCRIPTION', $fieldDescription ); + $nrows ++; + } + } + + } + $template->gotoBlock ( '_ROOT' ); + $template->assign ( 'ALLFUNCTION', implode ( ",", $methodParametersOnlyNames ) ); + $sPMfunction .= ");"; + $content = $template->getOutputContent (); + print $content; + +} catch ( Exception $oException ) { + die ( $oException->getMessage () ); +} +unset ( $_SESSION ['PROCESS'] ); +?> \ No newline at end of file diff --git a/workflow/engine/templates/triggers/triggers_EditWizard.html b/workflow/engine/templates/triggers/triggers_EditWizard.html new file mode 100644 index 000000000..0b79325c2 --- /dev/null +++ b/workflow/engine/templates/triggers/triggers_EditWizard.html @@ -0,0 +1,178 @@ + + + + + + + + +
    + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
      {SOURCE_LINK}
    +
     {LIBRARY_NAME} +
    {LIBRARY_DESCRIPTION} +
    + {METHOD_LABEL} {PMFUNTION_LABEL} ({PMFUNTION}) +
    + {PMFUNTION_DESCRIPTION} + + +   (More Info) + + + +
     
    + {DETAILS_LABEL} +
    {TITLE} + +
    {DESCRIPTION}
    + {PARAMETERS_LABEL} +
    {LABEL_PARAMETER} {ADD_TRI_VARIABLE} +
      + {ADD_TRI_DESCRIPTION} + +
    + {RETURN_TITLE} +
    {RETURN_LABEL} +
      + {RETURN_DESCRIPTION} +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    diff --git a/workflow/engine/templates/triggers/triggers_EditWizard.php b/workflow/engine/templates/triggers/triggers_EditWizard.php new file mode 100644 index 000000000..a47f8cfa0 --- /dev/null +++ b/workflow/engine/templates/triggers/triggers_EditWizard.php @@ -0,0 +1,139 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +try { + G::LoadClass ( 'triggerLibrary' ); + $triggerLibrary = triggerLibrary::getSingleton (); + $libraryClassName = $_GET ['LIBRARY_CLASS']; + $libraryMethod = $_GET ['PMFUNTION_NAME']; + $sProUid = $_GET ['PRO_UID']; + $libraryO = $triggerLibrary->getLibraryDefinition ( $libraryClassName ); + + $libraryName = $libraryO->info ['name']; + $libraryDescription = trim ( str_replace ( "*", "", implode ( " ", $libraryO->info ['description'] ) ) ); + $libraryIcon = isset ( $libraryO->info ['icon'] ) && ($libraryO->info ['icon'] != "") ? $libraryO->info ['icon'] : "/images/browse.gif"; + $aDataTrigger = $_GET; + + $sProUid = $aDataTrigger ['PRO_UID']; + $sNameFun = $aDataTrigger ['PMFUNTION_NAME']; + + $methodObject = $libraryO->methods [$sNameFun]; + + $methodName = $methodObject->info ['name']; + $methodLabel = $methodObject->info ['label']; + $methodDescription = trim ( str_replace ( "*", "", implode ( " ", $methodObject->info ['description'] ) ) ); + $methodReturn = $methodObject->info ['return']; + $methodParameters = array_keys ( $methodObject->params ); + $methodLink = isset ( $methodObject->info ['link'] ) && ($methodObject->info ['link'] != "") ? $methodObject->info ['link'] : ""; + $methodreturnA = explode ( "|", $methodReturn ); + $methodReturnLabel = isset ( $methodreturnA [3] ) ? $methodreturnA [3] : $methodReturn; + + $aParametersFun = $methodParameters; + $triggerWizardTemplate = PATH_TPL . 'triggers' . PATH_SEP . 'triggers_EditWizard.html'; + $template = new TemplatePower ( $triggerWizardTemplate ); + $template->prepare (); + + $tds = ''; + $nrows = 2; + + $template->assign ( 'LIBRARY_NAME', $libraryName ); + $template->assign ( 'LIBRARY_DESCRIPTION', $libraryDescription ); + $template->assign ( 'LIBRARY_ICON', $libraryIcon ); + $template->assign ( 'LIBRARY_CLASS', $libraryClassName ); + if ($methodLink != "") { + $template->newBlock ( 'methodLink' ); + $template->assign ( 'LIBRARY_METHOD_LINK', $methodLink ); + $template->gotoBlock ( '_ROOT' ); + } + + $template->assign ( 'PMFUNTION', $sNameFun ); + $template->assign ( 'PMFUNTION_LABEL', $methodLabel ); + $template->assign ( 'PMFUNTION_DESCRIPTION', $methodDescription ); + $template->assign ( 'TITLE', G::LoadTranslation ( 'ID_TITLE' ) ); + $template->assign ( 'TITLE_CONTENT', $_GET['TRI_TITLE'] ); + $template->assign ( 'TRI_UID', $_GET['TRI_UID'] ); + $template->assign ( 'SOURCE_LINK', G::LoadTranslation ( 'ID_TRIGGER_SOURCE_LINK' ) ); + $template->assign ( 'DESCRIPTION', G::LoadTranslation ( 'ID_DESCRIPTION' ) ); + $template->assign ( 'DESCRIPTION_CONTENT', $_GET['TRI_DESCRIPTION'] ); + $template->assign ( 'DETAILS_LABEL', G::LoadTranslation ( 'ID_DETAILS' ) ); + $template->assign ( 'RETURN_TITLE', G::LoadTranslation ( 'ID_TRIGGER_RETURN_TITLE' ) ); + $template->assign ( 'RETURN_LABEL', G::LoadTranslation ( 'ID_TRIGGER_RETURN_LABEL' ) ); + $template->assign ( 'RETURN_VALUE', $_GET['TRI_ANSWER'] ); + $template->assign ( 'METHOD_LABEL', G::LoadTranslation ( 'ID_METHOD' ) ); + $template->assign ( 'ROWS', sizeof ( $aParametersFun ) + 3 ); + $template->assign ( 'TRIGGER_INFORMATION', 'Triggers Edit Form' ); + $template->assign ( 'TRIGGER_ACTION', '../triggers/triggers_WizardUpdate' ); + $template->assign ( 'PRO_UID', $sProUid ); + $template->assign ( 'PAGED_TABLE_ID', $aDataTrigger ['PAGED_TABLE_ID'] ); + $template->assign ( 'RETURN_DESCRIPTION', $methodReturnLabel ); + $template->assign ( 'ID_SAVE', G::LoadTranslation ( 'ID_SAVE' ) ); + $template->assign ( 'ID_CANCEL', G::LoadTranslation ( 'ID_CANCEL' ) ); + + $sPMfunction = $sNameFun . " ("; + $methodParametersOnlyNames = array (); + if (count ( $aParametersFun ) > 0) { + $template->newBlock ( 'paremetersTriggersGroup' ); + $template->assign ( 'PARAMETERS_LABEL', G::LoadTranslation ( 'ID_PARAMETERS' ) ); + foreach ( $aParametersFun as $k => $v ) { + if ($v != '') { + $aParametersFunA = explode ( "|", $v ); + $paramType = $aParametersFunA [0]; + $paramDefinition = $aParametersFunA [1]; + $paramDefinitionA = explode ( "=", $paramDefinition ); + $paramName = $paramDefinitionA [0]; + $methodParametersOnlyNames [] = $paramName; + $paramDefaultValue = isset ( $paramDefinitionA [1] ) ? $paramDefinitionA [1] : ""; + $paramLabel = isset ( $aParametersFunA [2] ) ? $aParametersFunA [2] : $paramName; + $paramDescription = isset ( $aParametersFunA [3] ) ? $aParametersFunA [3] : ""; + $sPMfunction .= ($nrows != 2) ? ', "' . trim ( str_replace ( "$", "", $paramName ) ) . '"' : '"' . trim ( str_replace ( "$", "", $paramName ) . '"' ); + $template->newBlock ( 'paremetersTriggers' ); + $template->assign ( 'LABEL_PARAMETER', $paramLabel ); + $template->assign ( 'OPT_PARAMETER', trim ( str_replace ( "$", "", $paramName ) ) ); + $sNameTag = 'form.' . trim ( str_replace ( "$", "", $paramName ) ) . '.name'; + $sNameTag = trim ( $sNameTag ); + $template->assign ( 'SNAMETAG', $sNameTag ); + $tri_Button = ""; + $template->assign ( 'ADD_TRI_VARIABLE', $tri_Button ); +// $template->assign ( 'ADD_TRI_VALUE', str_replace ( "'", "", str_replace ( '"', '', $paramDefaultValue ) ) ); + $template->assign ( 'ADD_TRI_VALUE', $_GET[trim( str_replace( "$", "", $paramName ) )] ); + $fieldDescription = ($paramDescription!="")?$paramDescription . "
    ":""; + $fieldDescription .= $paramDefaultValue != "" ? $paramDefaultValue . " | " . $paramType : G::LoadTranslation ( "ID_REQUIRED_FIELD" ) . " | " . $paramType; + $template->assign ( 'ADD_TRI_DESCRIPTION', $fieldDescription ); + $nrows ++; + } + } + + } + $template->gotoBlock ( '_ROOT' ); + $template->assign ( 'ALLFUNCTION', implode ( ",", $methodParametersOnlyNames ) ); + $sPMfunction .= ");"; + $content = $template->getOutputContent (); + print $content; + +} catch ( Exception $oException ) { + die ( $oException->getMessage () ); +} +unset ( $_SESSION ['PROCESS'] ); +?> \ No newline at end of file diff --git a/workflow/engine/templates/users/users_AssignGroup.php b/workflow/engine/templates/users/users_AssignGroup.php new file mode 100644 index 000000000..c0af5514b --- /dev/null +++ b/workflow/engine/templates/users/users_AssignGroup.php @@ -0,0 +1,86 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + require_once 'classes/model/Users.php'; + + $oCriteria = new Criteria(); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->add(UsersPeer::USR_UID, $_GET['sUserUID']); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + G::LoadClass('groups'); + G::LoadClass('tree'); + + $groups = new Groups(); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::loadTranslation("ID_ASSIGN_GROUP_TO") . ' ' . $aRow['USR_FIRSTNAME'] . ' ' . $aRow['USR_LASTNAME'] . '
    +
    +
    + '; + + $tree->showSign = false; + $allGroups = $groups->getAllGroups(); + + foreach ($allGroups as $group) { + $ID_ASSIGN = G::LoadTranslation('ID_ASSIGN'); + $groupUID = htmlentities($group->getGrpUid()); + $userUID = $_GET['sUserUID']; + $GROUP_TITLE = strip_tags($group->getGrpTitle()); + $html = <<< innerHTML + + + + + +
    {$GROUP_TITLE}[{$ID_ASSIGN}]
    +innerHTML; + $ch = &$tree->addChild($group->getGrpUid(), $html, array('nodeType' => 'child')); + $ch->point = ''; + } + + + print ($tree->render()); diff --git a/workflow/engine/templates/users/users_DeleteReassign.html b/workflow/engine/templates/users/users_DeleteReassign.html new file mode 100644 index 000000000..662cdc639 --- /dev/null +++ b/workflow/engine/templates/users/users_DeleteReassign.html @@ -0,0 +1,42 @@ +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    {ID_NUMBER}{ID_CASE}{ID_TASK}{ID_PROCESS}{ID_STATUS}{ID_REASSIGN_TO}
    {APP_NUMBER}{APP_TITLE}{APP_TAS_TITLE}{APP_PRO_TITLE}{ID_STATUS} + + + +
    + + + +
    +
    +
    + \ No newline at end of file diff --git a/workflow/engine/templates/users/users_ReassignCases.html b/workflow/engine/templates/users/users_ReassignCases.html new file mode 100644 index 000000000..a836625f4 --- /dev/null +++ b/workflow/engine/templates/users/users_ReassignCases.html @@ -0,0 +1,42 @@ +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    {ID_NUMBER}{ID_CASE}{ID_TASK}{ID_PROCESS}{ID_STATUS}{ID_REASSIGN_TO}
    {APP_NUMBER}{APP_TITLE}{APP_TAS_TITLE}{APP_PRO_TITLE}{ID_STATUS} + + + +
    + + +
    +
    +
    +
    + \ No newline at end of file diff --git a/workflow/engine/templates/users/users_Tree.php b/workflow/engine/templates/users/users_Tree.php new file mode 100644 index 000000000..f6f6fc3e2 --- /dev/null +++ b/workflow/engine/templates/users/users_Tree.php @@ -0,0 +1,88 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + /** + * @Description This is the View of all groups from a determinated user + * @author Erik Amaru Ortiz + * @Date 24/04/2008 + * @LastModification none + */ + + require_once 'classes/model/Users.php'; + + $oCriteria = new Criteria(); + $oCriteria->addSelectColumn(UsersPeer::USR_FIRSTNAME); + $oCriteria->addSelectColumn(UsersPeer::USR_LASTNAME); + $oCriteria->add(UsersPeer::USR_UID, $_GET['sUserUID']); + $oDataset = UsersPeer::doSelectRS($oCriteria); + $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $oDataset->next(); + $aRow = $oDataset->getRow(); + + G::LoadClass('groups'); + G::LoadClass('tree'); + + $groups = new Groups(); + + $tree = new Tree(); + $tree->name = 'Users'; + $tree->nodeType = "base"; + $tree->width = "350px"; + $tree->value = ' +
    +
    + + + + +
    ' . G::loadTranslation("ID_USER_GROUPS") . ' ' . $aRow['USR_FIRSTNAME'] . ' ' . $aRow['USR_LASTNAME'] . '
    +
    +
    + '; + + $tree->showSign = false; + $allGroups = $groups->getUserGroups($_GET['sUserUID']); + + foreach ($allGroups as $group) { + $ID_DELETE = G::LoadTranslation('ID_DELETE'); + $groupUID = htmlentities($group->getGrpUid()); + $userUID = $_GET['sUserUID']; + $GROUP_TITLE = strip_tags($group->getGrpTitle()); + $html = <<< innerHTML + + + + + +
    {$GROUP_TITLE}[{$ID_DELETE}]
    +innerHTML; + $ch = &$tree->addChild($group->getGrpUid(), $html, array('nodeType' => 'child')); + $ch->point = ''; + } + if($groups->getNumberGroups($_GET['sUserUID']) == 0){ + $ch = &$tree->addChild('', G::LoadTranslation('ID_MSG_NORESULTS_USERGROUP'), array('nodeType' => 'child')); + } + + print ($tree->render()); diff --git a/workflow/engine/templates/xmlform.html b/workflow/engine/templates/xmlform.html new file mode 100644 index 000000000..0c8054094 --- /dev/null +++ b/workflow/engine/templates/xmlform.html @@ -0,0 +1,177 @@ +{if $printTemplate} +{* this is the xmlform template *} +
    +
    +
    + + + + +
    + + + + {foreach from=$form->fields item=field} + {if ($field->type==='title')} + + + + {elseif ($field->type==='subtitle')} + + + + {elseif ($field->type==='button') || ($field->type==='submit') || ($field->type==='reset')} + + + + {elseif ($field->type==='grid')} + + + + {elseif ($field->type==='checkbox') && ($field->labelOnRight)} + + + + + {elseif ($field->type==='phpvariable')} + {elseif ($field->type==='private')} + {elseif ($field->type==='javascript')} + {elseif ($field->type==='pmconnection')} + {elseif ($field->type==='hidden')} + + + + {elseif ($field->type==='')} + {elseif ($field->withoutLabel)} + + + + {elseif (isset($field->withoutValue) && $field->withoutValue)} + + + + {else} + + + + + + {/if} + {/foreach} +
    {$field->field}
    + {$field->field} + {if (isset($field->showHide) && $field->showHide)} + Hide + {/if} +
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->label}
    {if (isset($field->required)&&$field->required&&$field->mode==='edit')}* {/if}{$field->label}width y=$form->labelWidth}" *}>{$field->field}
    +
    + {if $hasRequiredFields}
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    {/if} +
    +
    +
    +{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +
    + + + + +{/if} +{if $printJSFile} +{* TODO: include file='xmlformScript.html' *} +var form_{$form->id}; +var object_{$form->name}; +var i; +if (typeof(__aObjects__) === 'undefined') {literal}{{/literal} + var __aObjects__ = []; +{literal}}{/literal} +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('{$form->id}'),'{$form->id}'); + object_{$form->name} = form_{$form->id}; + __aObjects__.push(object_{$form->name}); + var myForm=form_{$form->id}; + if (myForm.aElements===undefined) alert("{$form->name}"); + myForm.ajaxServer=ajaxServer; + //{$form->ajaxSubmit} + {if isset($form->ajaxSubmit) && ($form->ajaxSubmit)} + {literal} + var sub = new leimnud.module.app.submit({ + form : myForm.element,{/literal} + inProgress: {$form->in_progress}, + callback: {$form->callback} + {literal} + }); + sub.sendObj = false; + {/literal} + {/if} + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if (($field->type==='dropdown') || $field->type==='listbox')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + //alert('{$field->getAttributes()}'); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + myForm.aElements[i].mask = 'yyyy-mm-dd'; + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='hidden')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + grid_{$name} = myForm.aElements[i]; + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='date')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} +{/if} +{if $printJavaScript} +leimnud.event.add(window,'load',function(){literal}{{/literal}loadForm_{$form->id}('{$form->ajaxServer}');if (typeof(dynaformOnload) !== 'undefined') {literal}{dynaformOnload();}}{/literal}); +{/if} diff --git a/workflow/engine/templates/xmlformScript.html b/workflow/engine/templates/xmlformScript.html new file mode 100644 index 000000000..b36629d64 --- /dev/null +++ b/workflow/engine/templates/xmlformScript.html @@ -0,0 +1,69 @@ +var form_{$form->id}; +var i; +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('{$form->id}'),'{$form->id}'); + var myForm=form_{$form->id}; + myForm.ajaxServer=ajaxServer; + {if isset($form->ajaxSubmit) && ($form->ajaxSubmit)} + {literal} + var sub = new leimnud.module.app.submit({ + form : myForm.element + }); + sub.sendObj = false; + {/literal} + {/if} + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if ($field->type==='dropdown')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='hidden')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} \ No newline at end of file diff --git a/workflow/engine/templates/xmlform_preview.html b/workflow/engine/templates/xmlform_preview.html new file mode 100755 index 000000000..e41071d1b --- /dev/null +++ b/workflow/engine/templates/xmlform_preview.html @@ -0,0 +1,175 @@ +{if $printTemplate} +{* this is the xmlform template *} + + + + + +
    +
    +
    +
    + + + + +
    + + {foreach from=$form->fields item=field} + {if ($field->type==='title')} + + + + {elseif ($field->type==='subtitle')} + + + + {elseif ($field->type==='button') || ($field->type==='submit') || ($field->type==='reset')} + + + + {elseif ($field->type==='grid')} + + + + {elseif ($field->type==='checkbox') && ($field->labelOnRight)} + + + + + {elseif ($field->type==='phpvariable')} + {elseif ($field->type==='private')} + {elseif ($field->type==='javascript')} + {elseif ($field->type==='pmconnection')} + {elseif ($field->type==='hidden')} + + + + {elseif ($field->type==='')} + {elseif ($field->withoutLabel)} + + + + {elseif (isset($field->withoutValue) && $field->withoutValue)} + + + + {else} + + + + + {/if} + {/foreach} +
    {$field->field}
    + {$field->field} + {if (isset($field->showHide) && $field->showHide)} + Hide + {/if} +
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->field}
    {$field->label}
    {if (isset($field->required)&&$field->required&&$field->mode==='edit')}* {/if}{$field->label}width y=$form->labelWidth}" *}>{$field->field}
    +
    + {if $hasRequiredFields}
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    {/if} +
    +
    +
    +{foreach from=$form->fields item=field} + {if ($field->type==='javascript')} + + {/if} +{/foreach} +
    +{/if} +{if $printJSFile} +{* TODO: include file='xmlformScript.html' *} +var form_{$form->id}; +var object_{$form->name}; +var i; +if (typeof(__aObjects__) === 'undefined') {literal}{{/literal} + var __aObjects__ = []; +{literal}}{/literal} +function loadForm_{$form->id}(ajaxServer) +{literal}{{/literal} +if (typeof(G_Form)==='undefined') return alert('form.js was not loaded'); + form_{$form->id}=new G_Form(document.getElementById('{$form->id}'),'{$form->id}'); + object_{$form->name} = form_{$form->id}; + __aObjects__.push(object_{$form->name}); + var myForm=form_{$form->id}; + if (myForm.aElements===undefined) alert("{$form->name}"); + myForm.ajaxServer=ajaxServer; + //{$form->ajaxSubmit} + {if isset($form->ajaxSubmit) && ($form->ajaxSubmit)} + {literal} + var sub = new leimnud.module.app.submit({ + form : myForm.element,{/literal} + inProgress: {$form->in_progress}, + callback: {$form->callback} + {literal} + }); + sub.sendObj = false; + {/literal} + {/if} + {foreach from=$form->fields item=field key=name} + i = myForm.aElements.length; + {if (($field->type==='dropdown') || $field->type==='listbox')} + myForm.aElements[i] = new G_DropDown(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='text')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='percentage')} + myForm.aElements[i] = new G_Percentage(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='currency')} + myForm.aElements[i] = new G_Currency(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='textarea')} + myForm.aElements[i] = new G_TextArea(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='date')} + myForm.aElements[i] = new G_Date(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + myForm.aElements[i].mask = 'yyyy-mm-dd'; + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='hidden')} + myForm.aElements[i] = new G_Text(myForm, myForm.element.elements['form[{$name}]'],'{$name}'); + myForm.aElements[i].setAttributes({$field->getAttributes()}); + {$field->attachEvents("myForm.aElements[i].element")} + {elseif ($field->type==='grid')} + myForm.aElements[i] = new G_Grid(myForm, '{$name}'); + grid_{$field->id}(myForm.aElements[i]); + grid_{$name} = myForm.aElements[i]; + {$field->attachEvents("myForm.aElements[i].element")} + {else} + var element = getField("{$name}"); + {$field->attachEvents("element")} + {/if} + {/foreach} + {foreach from=$form->fields item=field key=name} + {if isset($field->dependentFields) && ($field->dependentFields!='')} + {if ($field->type==='dropdown')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='text')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='percentage')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='currency')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {elseif ($field->type==='date')} + myForm.getElementByName('{$name}').setDependentFields('{$field->dependentFields}'); + {/if} + {/if} + {/foreach} +{literal}}{/literal} +{/if} +{if $printJavaScript} +leimnud.event.add(window,'load',function(){literal}{{/literal}loadForm_{$form->id}('{$form->ajaxServer}');if (typeof(dynaformOnload) !== 'undefined') {literal}{dynaformOnload();}}{/literal}); +{/if} diff --git a/workflow/engine/templates/xmlmenu.html b/workflow/engine/templates/xmlmenu.html new file mode 100644 index 000000000..0809ab1c5 --- /dev/null +++ b/workflow/engine/templates/xmlmenu.html @@ -0,0 +1,117 @@ +{if $printTemplate} + + +{* LEFT MENU *} + +{* CENTER MENU *} + +{* RIGHT MENU *} + + + +{* BOTTOM MENU *} + + + + +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'left')===0) || ($field->colAlign==='')} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='print')} + +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + + +
    {$field->field}{$field->field} {$field->field} {$field->label} {$field->field} 
    +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'center')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + +
    {$field->field}{$field->field} {$field->label} {$field->field}
    +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'right')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + +
    {$field->field} {$field->field} {$field->label} {$field->field}
    +
    + + + + +
    +{foreach from=$form->fields item=field} + +{if (strcasecmp($field->colAlign,'bottom')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + {$field->field} +{elseif ($field->type==='link') || ($field->type==='menu')} +
    {$field->field}
    +{else} +  {$field->label} {$field->field} +{/if} +{/if} +{/foreach} +
    +
    + +{/if} \ No newline at end of file diff --git a/workflow/engine/templates/xmlmenuDyn.html b/workflow/engine/templates/xmlmenuDyn.html new file mode 100644 index 000000000..658a76eb0 --- /dev/null +++ b/workflow/engine/templates/xmlmenuDyn.html @@ -0,0 +1,117 @@ +{if $printTemplate} + + +{* LEFT MENU *} + +{* CENTER MENU *} + +{* RIGHT MENU *} + + + +{* BOTTOM MENU *} + + + + +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'left')===0) || ($field->colAlign==='')} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='print')} + +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + + +
    {$field->field}{$field->field} {$field->field} {$field->label} {$field->field} 
    +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'center')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + +
    {$field->field}{$field->field} {$field->label} {$field->field}
    +
    + + +{foreach from=$form->fields item=field} +{if (strcasecmp($field->colAlign,'right')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + +{elseif ($field->type==='link') || ($field->type==='menu')} + +{else} + +{/if} +{/if} +{/foreach} + +
    {$field->field} {$field->field} {$field->label} {$field->field}
    +
    + + + + +
    +{foreach from=$form->fields item=field} + +{if (strcasecmp($field->colAlign,'bottom')===0)} +{if ($field->type==='javascript')} +{elseif ($field->type==='phpvariable')} +{elseif ($field->type==='private')} +{elseif ($field->type==='hidden')} +{elseif ($field->type==='')} +{elseif ($field->type==='button')} + {$field->field} +{elseif ($field->type==='link') || ($field->type==='menu')} +
    {$field->field}
    +{else} +  {$field->label} {$field->field} +{/if} +{/if} +{/foreach} +
    +
    + +{/if} \ No newline at end of file diff --git a/workflow/engine/test/bootstrap/functional.php b/workflow/engine/test/bootstrap/functional.php new file mode 100644 index 000000000..1a0472416 --- /dev/null +++ b/workflow/engine/test/bootstrap/functional.php @@ -0,0 +1,52 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +/* + * This file is part of the symfony package. + * (c) 2004-2006 Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +// guess current application +if (!isset($app)) +{ + $traces = debug_backtrace(); + $caller = $traces[0]; + $app = array_pop(explode(DIRECTORY_SEPARATOR, dirname($caller['file']))); +} + +// define symfony constant +define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/../..')); +define('SF_APP', $app); +define('SF_ENVIRONMENT', 'test'); +define('SF_DEBUG', true); + +// initialize symfony +require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); + +// remove all cache +sfToolkit::clearDirectory(sfConfig::get('sf_cache_dir')); diff --git a/workflow/engine/test/bootstrap/gulliverConstants.php b/workflow/engine/test/bootstrap/gulliverConstants.php new file mode 100644 index 000000000..2acea2faa --- /dev/null +++ b/workflow/engine/test/bootstrap/gulliverConstants.php @@ -0,0 +1,103 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + +//***************** URL KEY ********************************************* + define("URL_KEY", 'c0l0s40pt1mu59r1m3' ); + +//***************** System Directories & Paths ************************** + define('PATH_SEP', '/'); + + define( 'PATH_HOME', '/opt/processmaker/trunk/workflow/' ); + define( 'PATH_GULLIVER_HOME', '/opt/processmaker/trunk/gulliver' . PATH_SEP ); + //define( 'PATH_GULLIVER_HOME', $pathTrunk . 'gulliver' . PATH_SEP ); + define( 'PATH_RBAC_HOME', $pathTrunk . 'rbac' . PATH_SEP ); + define( 'PATH_DATA', '/shared/workflow_data/'); + +// the other directories + define( 'PATH_GULLIVER', PATH_GULLIVER_HOME . 'system' . PATH_SEP ); //gulliver system classes + define( 'PATH_TEMPLATE', PATH_GULLIVER_HOME . 'templates' . PATH_SEP ); + define( 'PATH_THIRDPARTY', PATH_GULLIVER_HOME . 'thirdparty' . PATH_SEP ); + define( 'PATH_RBAC', PATH_RBAC_HOME . 'engine/classes' . PATH_SEP ); //to enable rbac version 2 + define( 'PATH_HTML', PATH_HOME . 'public_html' . PATH_SEP ); + + // Application's General Directories + define( 'PATH_CORE', PATH_HOME . 'engine' . PATH_SEP ); + define( 'PATH_SKINS', PATH_CORE . 'skins' . PATH_SEP ); + define( 'PATH_METHODS', PATH_CORE . 'methods' . PATH_SEP ); + define( 'PATH_XMLFORM', PATH_CORE . 'xmlform' . PATH_SEP ); + +//************ include Gulliver Class ************** + require_once( PATH_GULLIVER . PATH_SEP . 'class.g.php'); + +// the Compiled Directories + define( 'PATH_C', $pathOutTrunk . 'compiled/'); + +// the Smarty Directories + if ( strstr ( getenv ( 'OS' ), 'Windows' ) ) { + define( 'PATH_SMARTY_C', 'c:/tmp/smarty/c' ); + define( 'PATH_SMARTY_CACHE', 'c:/tmp/smarty/cache' ); + } + else { + define( 'PATH_SMARTY_C', PATH_C . 'smarty/c' ); + define( 'PATH_SMARTY_CACHE', PATH_C . 'smarty/cache' ); + } + + if (!is_dir(PATH_SMARTY_C)) G::mk_dir(PATH_SMARTY_C); + if (!is_dir(PATH_SMARTY_CACHE)) G::mk_dir(PATH_SMARTY_CACHE); + + + // Other Paths + //define( 'PATH_DB' , PATH_HOME . 'engine' . PATH_SEP . 'db' . PATH_SEP); + define( 'PATH_DB' , PATH_DATA . 'sites' . PATH_SEP ); + define( 'PATH_RTFDOCS' , PATH_CORE . 'rtf_templates' . PATH_SEP ); + define( 'PATH_HTMLMAIL', PATH_CORE . 'html_templates' . PATH_SEP ); + define( 'PATH_TPL' , PATH_CORE . 'templates' . PATH_SEP ); + define( 'PATH_DYNACONT', PATH_CORE . 'content' . PATH_SEP . 'dynaform' . PATH_SEP ); + define( 'PATH_LANGUAGECONT', PATH_CORE . 'content' . PATH_SEP . 'languages' . PATH_SEP ); + define( 'SYS_UPLOAD_PATH', PATH_HOME . "public_html/files/" ); + define( 'PATH_UPLOAD', PATH_HTML . 'files/'); + + +define ('DB_HOST', '192.168.0.10' ); +define ('DB_NAME', 'wf_opensource' ); +define ('DB_USER', 'fluid' ); +define ('DB_PASS', 'fluid2000' ); +define ('DB_RBAC_NAME', 'rbac_os' ); +define ('DB_RBAC_USER', 'rbac_os' ); +define ('DB_RBAC_PASS', '873821w3n2u719tx' ); +define ('DB_WIZARD_REPORT_SYS', 'report_os' ); +define ('DB_WIZARD_REPORT_USER', 'rep_os' ); +define ('DB_WIZARD_REPORT_PASS', '3r357ichy6b95s88' ); + +define ( 'SF_ROOT_DIR', PATH_CORE ); +define ( 'SF_APP', 'app' ); +define ( 'SF_ENVIRONMENT', 'env' ); + + set_include_path( + PATH_THIRDPARTY . PATH_SEPARATOR . + PATH_THIRDPARTY . 'pear' . PATH_SEPARATOR . + get_include_path() + ); + diff --git a/workflow/engine/test/bootstrap/unit.php b/workflow/engine/test/bootstrap/unit.php new file mode 100644 index 000000000..135b26154 --- /dev/null +++ b/workflow/engine/test/bootstrap/unit.php @@ -0,0 +1,71 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + ini_set('short_open_tag', 'on'); + ini_set('asp_tags', 'on'); + ini_set('memory_limit', '80M'); + + if ( PHP_OS == 'WINNT' ) + define('PATH_SEP', '\\'); + else + define('PATH_SEP', '/'); + + + //***************** Defining the Home Directory ********************************* + $docuroot = explode ( PATH_SEP , $_SERVER['PWD'] ); + array_pop($docuroot); + $pathhome = implode( PATH_SEP, $docuroot ); + define('PATH_HOME', $pathhome . PATH_SEP ); + $gulliverConfig = PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php'; + $definesConfig = PATH_HOME . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'defines.php'; + + //try to find automatically the trunk directory where are placed the RBAC and Gulliver directories + //in a normal installation you don't need to change it. + array_pop($docuroot); + $pathTrunk = implode( PATH_SEP, $docuroot ) . PATH_SEP ; + array_pop($docuroot); + $pathOutTrunk = implode( PATH_SEP, $docuroot ) . PATH_SEP ; + // to do: check previous algorith for Windows $pathTrunk = "c:/home/"; + + define('PATH_TRUNK', $pathTrunk ); + define('PATH_OUTTRUNK', $pathOutTrunk ); + + if (file_exists( $gulliverConfig )) { + include ( $gulliverConfig ); + } + + if (file_exists( $definesConfig )) { + include ( $definesConfig ); + } + + //$_test_dir = realpath(dirname(__FILE__).'/..'); + //require_once( 'lime/lime.php'); + + require_once( PATH_THIRDPARTY . 'pake' . PATH_SEP . 'pakeFunction.php'); + require_once( PATH_THIRDPARTY . 'pake' . PATH_SEP . 'pakeGetopt.class.php'); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + if ( !defined ( 'G_ENVIRONMENT') ) + define ( 'G_ENVIRONMENT', G_TEST_ENV ); + diff --git a/workflow/engine/test/fixtures/appDelegation.yml b/workflow/engine/test/fixtures/appDelegation.yml new file mode 100755 index 000000000..4635150f9 --- /dev/null +++ b/workflow/engine/test/fixtures/appDelegation.yml @@ -0,0 +1,40 @@ +CreateAppDelegations: + - + Title: "Create AppDelegation with Empty $Fields" + Function: "CreateEmptyAppDelegation" + Input: + Output: + Type: "G_Error" + - + Title: "Create Duplicated AppDelegation" + Function: "CreateDuplicated" + Input: + APP_UID: "1DUPLICATED1" + DEL_INDEX: 2 + PRO_UID[]: "guid.pm" + TAS_UID[]: "guid.pm" + Output: + Type: "G_Error" + - + TODO: "Review: Error catch in CreateAppDelegation capture Propel Errors but return the same G_Error information." + - + Title: "Create random new AppDelegation" + Function: "CreateNewAppDelegation" + Input: + APP_UID[]: "guid.pm" + DEL_INDEX[]: "rand.number" + PRO_UID[]: "guid.pm" + TAS_UID[]: "guid.pm" + DEL_TYPE[]: "*.DEL_TYPE.pm" + DEL_THREAD_STATUS[]: "*.DEL_THREAD_STATUS.pm" + Output: + Type: "string" + - + TODO: "Review: There isn't a 'function delete'. Is it required?" +DeleteCretedAppDelegations: + - + Title: "Deleting created AppDelegations" + Input: + Fields[]:"*.createdAppDel" + Output: + Value: "true" diff --git a/workflow/engine/test/fixtures/appDocument.yml b/workflow/engine/test/fixtures/appDocument.yml new file mode 100644 index 000000000..22ec3d154 --- /dev/null +++ b/workflow/engine/test/fixtures/appDocument.yml @@ -0,0 +1,100 @@ +load1: + - + Title: "Obtain the application document data" + Function: "loadTest" + Input: + APP_DOC_UID: "1" + Output: + Type: "array" +load2: + - + Title: "Obtain the application document data (not existent)" + Function: "loadTest" + Input: + APP_DOC_UID: "111111111111" + Output: + Type: "Exception" +create1: + - + Title: "Create the application document data" + Function: "createTest" + Input: + APP_DOC_UID: "2" + APP_UID: "2" + DEL_INDEX: "2" + DOC_UID: "2" + USR_UID: "2" + APP_DOC_TYPE: "INPUT" + APP_DOC_CREATE_DATE: "2007-12-31 23:59:59" + APP_DOC_TITLE: "APP_DOC_TITLE" + APP_DOC_COMMENT: "APP_DOC_COMMENT" + APP_DOC_FILENAME: "APP_DOC_FILENAME" + Output: + Type: "integer" +create2: + - + Title: "Create the application document data (whit incomplete data)" + Function: "createTest" + Input: + APP_DOC_UID: "" + APP_UID: "2" + DEL_INDEX: "2" + DOC_UID: "2" + USR_UID: "2" + APP_DOC_TYPE: "INPUT" + APP_DOC_CREATE_DATE: "2007-12-31 23:59:59" + APP_DOC_TITLE: "APP_DOC_TITLE" + APP_DOC_COMMENT: "APP_DOC_COMMENT" + APP_DOC_FILENAME: "APP_DOC_FILENAME" + Output: + Type: "Exception" +update1: + - + Title: "Update the application document data" + Function: "updateTest" + Input: + APP_DOC_UID: "1" + APP_UID: "2" + DEL_INDEX: "2" + DOC_UID: "2" + USR_UID: "2" + APP_DOC_TYPE: "OUTPUT" + APP_DOC_CREATE_DATE: "2008-01-01 00:00:00" + APP_DOC_TITLE: "APP_DOC_TITLE1" + APP_DOC_COMMENT: "APP_DOC_COMMENT1" + APP_DOC_FILENAME: "APP_DOC_FILENAME1" + Output: + Type: "integer" +update2: + - + Title: "Update the application document data (not existent)" + Function: "updateTest" + Input: + APP_DOC_UID: "111111111111" + APP_UID: "2" + DEL_INDEX: "2" + DOC_UID: "2" + USR_UID: "2" + APP_DOC_TYPE: "OUTPUT" + APP_DOC_CREATE_DATE: "2008-01-01 00:00:00" + APP_DOC_TITLE: "APP_DOC_TITLE1" + APP_DOC_COMMENT: "APP_DOC_COMMENT1" + APP_DOC_FILENAME: "APP_DOC_FILENAME1" + Output: + Type: "Exception" +remove1: + - + Title: "Remove the application document data" + Function: "removeTest" + Input: + APP_DOC_UID: "2" + Output: + Type: "NULL" +remove2: + - + Title: "Remove the application document data (not existent)" + Function: "removeTest" + Input: + APP_DOC_UID: "111111111111" + Output: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/application.yml b/workflow/engine/test/fixtures/application.yml new file mode 100644 index 000000000..8e37444ac --- /dev/null +++ b/workflow/engine/test/fixtures/application.yml @@ -0,0 +1,10 @@ +fields: + PRO_UID: '346FAE3953CC69' + APP_PARENT: '' + APP_STATUS: 'DRAFT' + APP_PROC_STATUS: 'STATUS' + APP_PROC_CODE: '12345678' + APP_PARALLEL: 'N' + APP_INIT_USER: 'ABC123' + APP_CUR_USER: 'ABC123' + \ No newline at end of file diff --git a/workflow/engine/test/fixtures/applicationInput.yml b/workflow/engine/test/fixtures/applicationInput.yml new file mode 100644 index 000000000..2412268a8 --- /dev/null +++ b/workflow/engine/test/fixtures/applicationInput.yml @@ -0,0 +1,75 @@ +FirstStepTestCases: + - + Title: "@#Function(): Create some non Parallel Cases" + Class: "applicationTest" + Instance: $obj + Function: "SaveTest" + Input: + PRO_UID: "8475E6C841051A" + APP_PARALLEL: "N" + APP_INIT_USER: "@G::generateUniqueID()" + APP_CUR_USER: "@G::generateUniqueID()" + APP_CREATE_DATE: "@date(Y-m-d)" + APP_INIT_DATE: "0000-00-00" + APP_FINISH_DATE: "0000-00-00" + APP_UPDATE_DATE: "@date(Y-m-d)" + APP_STATUS[]:"*.nonParallelStatus.applicationInput" + APP_PARENT: "0" + APP_PROC_STATUS: "" + APP_PROC_CODE: "" + Output: + Type: "string" + - + Title: "@#Function(): Create one parallel Case (Force to be parallel)" + Class: "applicationTest" + Instance: $obj + Function: "SaveTest" + Input: + PRO_UID: "8475E6C841051A" + APP_PARALLEL: "Y" + APP_STATUS: "PARALLEL" + APP_PARENT: "0" + APP_PROC_STATUS: "" + APP_PROC_CODE: "" + APP_INIT_USER: "@G::generateUniqueID()" + APP_CUR_USER: "@G::generateUniqueID()" + APP_CREATE_DATE: "@date(Y-m-d)" + APP_INIT_DATE: "0000-00-00" + APP_FINISH_DATE: "0000-00-00" + Output: + Type: "string" +SecondStepTestCases: + - + Title: "@#Function(): Update one of LastCreatedCases with all diferent types of status" + Class: "applicationTest" + Instance: $obj + Function: "UpdateTest" + Input: + PRO_UID: "8475E6C841051A" + APP_UID[]: "LAST_CREATED_CASE" + APP_STATUS[]: "*.APP_STATUS.pm" + Output: + Type: "string" + - + Title: "@#Function(): Loads all LastCreatedCases" + Class: "applicationTest" + Instance: $obj + Function: "LoadTest" + Input: + PRO_UID: "8475E6C841051A" + APP_UID[]: "*.LAST_CREATED_CASE" + Output: + Type: "NULL" + - + Title: "@#Function(): Delete all LastCreatedCases" + Class: "applicationTest" + Instance: $obj + Function: "DeleteTest" + Input: + PRO_UID: "8475E6C841051A" + APP_UID[]: "*.LAST_CREATED_CASE" + Output: + Type: "NULL" +nonParallelStatus: + - "DRAFT" + - "CANCEL" \ No newline at end of file diff --git a/workflow/engine/test/fixtures/configuration.yml b/workflow/engine/test/fixtures/configuration.yml new file mode 100755 index 000000000..d06de134f --- /dev/null +++ b/workflow/engine/test/fixtures/configuration.yml @@ -0,0 +1,47 @@ +CreateTestConfigurations: + - + Title:"Creating new Configurations" + Function:"CreateConfiguration" + Input: + CFG_UID[]:"guid.pm" + OBJ_UID[]:"guid.pm" + PRO_UID[]:"guid.pm" + USR_UID[]:"guid.pm" + APP_UID:"" + Output: + Value: 1 +ConfigurationUnitTest: + - + Title:"Updating Configurations" + Function:"UpdateConfiguration" + Input: + CFG_UID[]:"CREATED_UID" + OBJ_UID[]:"CREATED_OBJ" + PRO_UID[]:"CREATED_PRO" + USR_UID[]:"CREATED_USR" + APP_UID:"" + CFG_VALUE[]:"*.text.es" + Output: + Value: 1 + - + Title:"Loading Configurations" + Function:"LoadConfiguration" + Input: + CFG_UID[]:"CREATED_UID" + OBJ_UID[]:"CREATED_OBJ" + PRO_UID[]:"CREATED_PRO" + USR_UID[]:"CREATED_USR" + APP_UID:"" + Output: + Type: "array" + - + Title:"Removing Configurations" + Function:"RemoveConfiguration" + Input: + CFG_UID[]:"CREATED_UID" + OBJ_UID[]:"CREATED_OBJ" + PRO_UID[]:"CREATED_PRO" + USR_UID[]:"CREATED_USR" + APP_UID:"" + Output: + Type: "NULL" diff --git a/workflow/engine/test/fixtures/content.yml b/workflow/engine/test/fixtures/content.yml new file mode 100644 index 000000000..bc2b82b83 --- /dev/null +++ b/workflow/engine/test/fixtures/content.yml @@ -0,0 +1,71 @@ +loadContent: + - + Title: "LoadContent method" + Function: "loadContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '6475576C725EA4' + CON_LANG: 'it' + CON_VALUE: 'Content Example' + Output: + Type: "string" +deleteContent: + - + Title: "delete a row " + Function: "deleteContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '6475576C725EA4' + CON_LANG: 'it' + Output: + Type: "NULL" + - + Title: "delete a row " + Function: "deleteContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '9876543210' + CON_LANG: 'it' + Output: + Type: "NULL" +addContent1: + - + Title: "addContent method, calling the first time" + Function: "addContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '9876543210' + CON_LANG: 'it' + CON_VALUE: 'addContent method, calling the first time' + Output: + Type: integer +addContentTwice: + - + Title: "validate duplicate row, with the addContent method" + Function: "addContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '9876543210' + CON_LANG: 'it' + CON_VALUE: 'validate duplicate row, now update the row' + Output: + Type: "integer" +addContentAcentos: + - + Title: "add content with acentos" + Function: "addContent" + Input: + CON_CATEGORY: 'ABC_CATEGORY' + CON_PARENT: '1234567890' + CON_ID: '6475576C725EA4' + CON_LANG: 'it' + CON_VALUE: 'áéíóúñÑ' + Output: + Type: "integer" + + \ No newline at end of file diff --git a/workflow/engine/test/fixtures/departments.txt b/workflow/engine/test/fixtures/departments.txt new file mode 100644 index 000000000..e1ba14ee0 --- /dev/null +++ b/workflow/engine/test/fixtures/departments.txt @@ -0,0 +1,34 @@ +ExecutivePresident| +Marketing|ExecutivePresident +SalesDivision|ExecutivePresident +RiskManager|Sales +NationalSales|Sales +InternationalSales|Sales +EuropeSales|InternationalSales +USASales|InternationalSales +JapanSales|InternationalSales +InternetSales|Sales +AdministrativeDivision|ExecutivePresident +Accounting|AdministrativeDivision +HumanResources|AdministrativeDivision +InfraestructureManagement|AdministrativeDivision +Facilities|InfraestructureManagement +VehicleMaintenance|InfraestructureManagement +InvestigativeDivision|ExecutivePresident +Legal|InvestigativeDivision +DetectiveSection|InvestigativeDivision +Records|InvestigativeDivision +EuropeRegional| +SupportServiceDivision|ExecutivePresident +InformationDesk|SupportServiceDivision +TechnologicalResearch|SupportServiceDivision +Landlinetelephony|SupportServiceDivision +MobileServices|SupportServiceDivision +FinanceDivision|ExecutivePresident +PlanningandResearch|FinanceDivision +DeputyDirector|FinanceDivision +OperacionDivision|ExecutivePresident +SystemAdministration|OperacionDivision +SecurityOfficer|OperacionDivision +OperationandBusiness|OperacionDivision +SpecialOperations|OperationandBusiness \ No newline at end of file diff --git a/workflow/engine/test/fixtures/derivation.yml b/workflow/engine/test/fixtures/derivation.yml new file mode 100644 index 000000000..e42e2fdd7 --- /dev/null +++ b/workflow/engine/test/fixtures/derivation.yml @@ -0,0 +1,28 @@ +StartCase1: + - + Title: "Start a new application @#Function()" + Function: "StartCaseTest" + Input: + TAS_UID: "4475E6C8E10346" + USR_UID: "4475E6E07C261E" + firstname[]: "@@SYS_LANG" + lastname[]: "last.name.es" + Output: + Type: "array" +StartCase2: + - + Title: "Start a new application (pseudo derivate)" + Function: "StartCaseTest" + Input: + TAS_UID: "4475E6C8E10346" + USR_UID: "4475E6E07C261E" + Output: + Type: "array" +DeleteCreatedApplications: + - + Title: "Delete created applications" + Function: "DeleteCase" + Input: + APP_UID[]: "*.CREATED_APPLICATIONS" + Output: + Type: "array" diff --git a/workflow/engine/test/fixtures/domain.yml b/workflow/engine/test/fixtures/domain.yml new file mode 100644 index 000000000..d76cccb7a --- /dev/null +++ b/workflow/engine/test/fixtures/domain.yml @@ -0,0 +1,34 @@ +pm: + APP_STATUS: + - "DRAFT" + - "CANCEL" + - "PARALLEL" + DEL_TYPE: + - "NORMAL" + DEL_THREAD_STATUS: + - "OPEN" + - "CLOSED" + yesno: + - "Y" + - "N" + guid: + - "@G::generateUniqueID()" + stepUidObj: + - "DYNAFORM" + - "INPUT_DOCUMENT" + - "MESSAGE" + - "OUTPUT_DOCUMENT" +date: + today: + - "@date(Y-m-d)" +time: + today: + - "@date(H:i:s)" +datetime: + today: + - "@date(Y-m-d H:i:s)" +number: + percentage: + - "@eval(return rand(0,100\))" + rand: + -"@rand()" diff --git a/workflow/engine/test/fixtures/es.yml b/workflow/engine/test/fixtures/es.yml new file mode 100644 index 000000000..bc74ef1e1 --- /dev/null +++ b/workflow/engine/test/fixtures/es.yml @@ -0,0 +1,59 @@ +name: + first: + - David + - Julio + - Mauricio + - Wilmer + - Fernando + - Hugo + - Ramiro + last: + - Callizaya + - Avendaño + - Veliz + - Maborak + - Ontiveros + - Loza + - Cuentas + group: + - Administración + - Consultores + - Desarrollo + - Gerencia + - Ventas + - Business Development + - Redes y Servidores + - Soporte y Entrenamiento + - Otros +text: + - ¿Por qué la ciencia se empeña en comprender el universo si todavia no comprende al ser humano? + - Tengo una demostración maravillosa... + - La ciencia es la verdadera sabiduría. + - El verdadero amante de la vida es el cientifico, pues es el único que se ocupa de descubrir sus misterios. + - El conocimiento es patrimonio de la humanidad, no es solo tuyo, trasmítelo para beneficio de toda la humanidad. + - La ciencia es la necesidad de demostrar lo que nos acontece. + - Cada uno de nosotros es un modelo totalmente nuevo, parecido a otros modelos pero totalmente diferente. + - ¿Por qué las moras negras están rojas cuando están verdes? + - La ciencia es la manera estadísticamente correcta de contar novelas. + - La ciencia de vivir es el arte de amar. + - La ciencia es la explicación de lo inexplicable. + - Un ser humano es algo más que la suma de sus genes. + - La ciencia es el idioma del hombre. + - La ciencia me dió lo que soy, un buen hombre. La ciencia me ayudará a ayudar a las personas. + - Para ser científico debo afirmar lo que veo y negar lo que creo. + - La ciencia es el arte de bosquejar para los demás los fenómenos de la naturaleza... + - La ciencia es el instrumento más poderoso de la humanidad. +html: + - "

     Hola Mundo!!

    " + - "

     áéíóú

    " + - "

    'hola Mundo!!'

    " +email: + - "davidsantos@colosa.com" + - "juliocesar@colosa.com" + - "mauricio@colosa.com" + - "wilmer@colosa.com" +address: + - "Dom - 2453416 Dom. Padres" +zip: + - "00000" + - "52412" diff --git a/workflow/engine/test/fixtures/firstname.txt b/workflow/engine/test/fixtures/firstname.txt new file mode 100644 index 000000000..af7a40551 --- /dev/null +++ b/workflow/engine/test/fixtures/firstname.txt @@ -0,0 +1,501 @@ + +Amy +Sidney +Matt +Robert +Michael +Josh +Lori +Dorothy +Tavon +Corey +Clarissa +Tony +Terry +Arlene +Alex +Jim +mike +max +Jacob +Armand +Joshua +Ava +Olivia +Sophia +William +Christopher +Matthew +Samantha +Andrew +Joseph +David +Alexis +Alyssa +James +Ryan +Ella +Sarah +Taylor +Lily +Benjamin +Nathan +Ulices +Grace +Brianna +Gavin +Dylan +Brandon +Caleb +Mason +Angel +Isaac +Evan +Jack +Kevin +Jose +Isaiah +Luke +Landon +Justin +Lucas +Zachary +Jordan +Arthur +Aaron +Brayden +Thomas +Cameron +Hunter +Austin +Adrian +Connor +Owen +Aidan +Jason +Julian +Wyatt +Charles +Carter +Juan +Chase +Diego +Jeremiah +Brody +Xavier +Adam +Sebastian +Haydens +Nathaniel +Jesus +Ian +Tristan +Bryan +Sean +Cole +Jennifer +Melanie +Gianna +Charlotte +Paige +Isabel +Gracie +Haley +Mya +Michelle +Molly +Stephanie +Nicole +Jenna +Natalia +Sadie +Jada +Ruby +Jayla +Lydia +Bella +Haydden +Miley +Laila +Reagan +Collin +Gage +Emmanuel +Kendall +Liliana +Jacqueline +Reese +Marissa +Juliana +Tanner +Malachi +Fernando +Cesar +Javier +Miles +Jaiden +Edwin +Travis +Bryson +Jace +Kaiden +Wesley +Jeffrey +Roman +Brendan +Maddox +Donovan +Rylan +Dalton +Harrison +Andre +Keegan +Sawyer +Clayton +Zane +Gregory +Rafael +Ezekiel +Griffin +ny +Mateo +Braylon +Cash +Maximus +Simon +Corbin +Brennan +Skylers +Xander +Jaxson +Kameron +Kyler +Elias +Harper +Ivy +Camille +Savanna +Emely +Kiley +Kailey +Miriam +Rihanna +Georgia +Harmony +Kiera +Monica +Bethany +Kaylie +Camron +Alice +Maddison +Ximena +April +Marely +Julie +Danica +Presley +Brielle +Julissa +Angie +Hazel +Rose +Malia +Shayla +Fiona +Phoebe +Nayeli +Jaya +Ruth +Janiya +Denise +Holly +Hanna +Tatum +Marlee +Nataly +Lizbeth +Serena +Anya +Jaslene +Kaylin +Greyson +Jameson +Everett +Jayce +Darren +Elliott +Uriel +Hugo +Marshall +Nickolas +Bryant +Maurice +Russell +Leland +Davis +Reed +Kade +Reece +Morgan +Ramon +Rocco +Orlando +Ryker +Brodie +Paxton +Jacoby +Macie +Lyric +Logan +Lana +Kaned +Alvin +Shaun +Eddie +Kane +Davion +Zachariah +Dorian +Kellen +Micaela +Isiah +Javon +Nasir +Milo +Anahi +Alissa +Anaya +Ainsley +Noelle +Meredith +Kailyn +Johanna +Evangeline +Kathleen +Juliet +Meghan +Paisley +Athena +Hailee +Emilee +Sage +Alanna +Elaina +Nia +Kasey +Paris +Casey +Dana +Aubrie +Kaitlin +Norah +Lauryn +Perla +Amiyah +Lillie +Danika +Heather +Kassidy +Taryn +Tori +Francesca +Kristen +Amya +Elle +Craig +Ibrahim +Osvaldo +Wade +Harley +Steve +Davin +Deshawn +Kason +Damion +Jaylon +Jefferson +Aron +Brooks +Darian +Gerald +Rolando +Terrence +Enzo +Kian +Ryland +Barrett +Jaeden +Ben +Bradyn +Giovani +Blaine +Madden +Jerome +Muhamma +Ronnie +Layne +Kolby +Leonard +Vicente +Cale +Alessandro +Zachery +Gavyn +Aydin +Xzavier +Malakai +Raphael +Cannon +Rudy +Asa +Darrell +Giancarlo +Elisha +Junior +Zackery +Alvaro +Lewis +Valentin +Deacon +Jase +Harry +Rashad +Finnegan +Mohammed +Ramiro +Cedric +Brennen +Santino +Stanley +Tyrone +Chace +Francis +athon +Teagan +Zechariah +Alonso +Kaeden +Kamden +Gilberto +Ray +Karter +Luciano +Nico +Kole +Aryan +Draven +Jamie +Misael +Lee +Alexzanders +Camren +Giovanny +Amare +Rhett +Rhys +Rodolfo +Nash +Markus +Deven +Mohammad +Moshe +Quintin +Dwayne +Memphis +Atticus +Davian +Eugene +Jax +Antoine +Wayne +Randall +Semaj +Uriah +Clark +Aidyn +Jorden +Maxim +Aditya +Lawson +Messiah +Korbin +Sullivan +Freddy +Demarcus +Neil +Brice +King +Davon +Elvis +Ace +Dexter +Heath +Duncan +Jamar +Sincere +Irvin +Remingtons +Kadin +Soren +Tyree +Damarion +Talan +Adrien +Gilbert +Keenan +Darnell +Adolfo +Tristian +Derick +Isai +Rylee +Gauge +Harold +Kareem +Deangelo +Agustin +Coleman +Zavier +Lamar +Emery +Jaydin +Devan +Jordyn +Mathias +Prince +Seamus +Jasiah +Efrain +Darryl +Arjun +Miguel +Roland +Conrad +Kamron +Hamza +Santos +Frankie +Dominique +Marley +Vance +Dax +Jamir +Kylan +Todd +Maximo +Jabari +Matthias +Haiden +Luka +Marcelo +Keon +Layton +Tyrell +Kash +Laney +Isis +Marcela +Dave +Amos +Grover \ No newline at end of file diff --git a/workflow/engine/test/fixtures/fixtures.yml b/workflow/engine/test/fixtures/fixtures.yml new file mode 100644 index 000000000..532b28453 --- /dev/null +++ b/workflow/engine/test/fixtures/fixtures.yml @@ -0,0 +1,29 @@ +- + input: '/test' + output: true + comment: isPathAbsolute() returns true if path is absolute +- + input: '\\test' + output: true + comment: isPathAbsolute() returns true if path is absolute +- + input: 'C:\\test' + output: true + comment: isPathAbsolute() returns true if path is absolute +- + input: 'd:/test' + output: true + comment: isPathAbsolute() returns true if path is absolute +- + input: 'test' + output: false + comment: isPathAbsolute() returns false if path is relative +- + input: '../test' + output: false + comment: isPathAbsolute() returns false if path is relative +- + input: '..\\test' + output: false + comment: isPathAbsolute() returns false if path is relative + \ No newline at end of file diff --git a/workflow/engine/test/fixtures/groupUser.yml b/workflow/engine/test/fixtures/groupUser.yml new file mode 100644 index 000000000..96cee81d8 --- /dev/null +++ b/workflow/engine/test/fixtures/groupUser.yml @@ -0,0 +1,36 @@ +create1: + - + Title: "Create the group user row" + Function: "createTest" + Input: + GRP_UID: "2" + USR_UID: "2" + input: + Type: "integer" +create2: + - + Title: "Create the group user row (whit incomplete data)" + Function: "createTest" + Input: + GRP_UID: "" + USR_UID: "2" + input: + Type: "Exception" +remove1: + - + Title: "Remove the group user row" + Function: "removeTest" + Input: + GRP_UID: "2" + USR_UID: "2" + input: + Type: "NULL" +remove2: + - + Title: "Remove the group user row (not existent)" + Function: "removeTest" + Input: + GRP_UID: "111111111111" + USR_UID: "222222222222" + input: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/groups.txt b/workflow/engine/test/fixtures/groups.txt new file mode 100644 index 000000000..d590c6548 --- /dev/null +++ b/workflow/engine/test/fixtures/groups.txt @@ -0,0 +1,32 @@ +Marketing Users +Operators +Accounters +Lawyers +Operators +Salespersons +Team A +Team B +Team C +Team D +Team E +Team F +Team G +Team H +Team I +Team J +Team K +Team L +Team M +Team N +Team O +Team P +Team Q +Team R +Team S +Team T +Team U +Team V +Team W +Team X +Team Y +Team Z diff --git a/workflow/engine/test/fixtures/inputDocument.yml b/workflow/engine/test/fixtures/inputDocument.yml new file mode 100644 index 000000000..37ed10add --- /dev/null +++ b/workflow/engine/test/fixtures/inputDocument.yml @@ -0,0 +1,88 @@ +load1: + - + Title: "Obtain the input document data" + Function: "loadTest" + Input: + INP_DOC_UID: "1" + input: + Type: "array" +load2: + - + Title: "Obtain the input document data (not existent)" + Function: "loadTest" + Input: + INP_DOC_UID: "111111111111" + input: + Type: "Exception" +create1: + - + Title: "Create the input document data" + Function: "createTest" + Input: + INP_DOC_UID: "2" + PRO_UID: "2" + INP_DOC_FORM_NEEDED: "VREAL" + INP_DOC_ORIGINAL: "ORIGINAL" + INP_DOC_PUBLISHED: "PUBLIC" + INP_DOC_TITLE: "INP_DOC_TITLE" + INP_DOC_DESCRIPTION: "INP_DOC_DESCRIPTION" + input: + Type: "integer" +create2: + - + Title: "Create the input document data (whit incomplete data)" + Function: "createTest" + Input: + INP_DOC_UID: "" + PRO_UID: "2" + INP_DOC_FORM_NEEDED: "VREAL" + INP_DOC_ORIGINAL: "ORIGINAL" + INP_DOC_PUBLISHED: "PUBLIC" + INP_DOC_TITLE: "INP_DOC_TITLE" + INP_DOC_DESCRIPTION: "INP_DOC_DESCRIPTION" + input: + Type: "Exception" +update1: + - + Title: "Update the input document data" + Function: "updateTest" + Input: + INP_DOC_UID: "1" + PRO_UID: "2" + INP_DOC_FORM_NEEDED: "VREAL" + INP_DOC_ORIGINAL: "ORIGINAL" + INP_DOC_PUBLISHED: "PUBLIC" + INP_DOC_TITLE: "INP_DOC_TITLE1" + INP_DOC_DESCRIPTION: "INP_DOC_DESCRIPTION1" + input: + Type: "integer" +update2: + - + Title: "Update the input document data (not existent)" + Function: "updateTest" + Input: + INP_DOC_UID: "111111111111" + PRO_UID: "2" + INP_DOC_FORM_NEEDED: "VREAL" + INP_DOC_ORIGINAL: "ORIGINAL" + INP_DOC_PUBLISHED: "PUBLIC" + INP_DOC_TITLE: "INP_DOC_TITLE1" + INP_DOC_DESCRIPTION: "INP_DOC_DESCRIPTION1" + input: + Type: "Exception" +remove1: + - + Title: "Remove the input document data" + Function: "removeTest" + Input: + INP_DOC_UID: "2" + input: + Type: "NULL" +remove2: + - + Title: "Remove the input document data (not existent)" + Function: "removeTest" + Input: + INP_DOC_UID: "111111111111" + input: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/lastname.txt b/workflow/engine/test/fixtures/lastname.txt new file mode 100644 index 000000000..8aca0d14a --- /dev/null +++ b/workflow/engine/test/fixtures/lastname.txt @@ -0,0 +1,222 @@ +Agnes +Ahearn +Amadon +Anderson +Arbouet +Arinello +Austin +Balisi +barkle +Barrett +Basili +Beam +Beccia +Bechtel +Bendis +Bittner +Bittner +Black +Blackshear +Boria +Bosworth +Bourgeous +Broderick +Brown +Brule +Burns +Cagley +Champagne +Charette +Ching +Ciarleglio +Cifrino +Cifuni +Cleveland +Cole +Connelly +Connolly +Corleone +Cook +Corey +Corey +Cowell +Creelman +Cremins +Crowley +Daley +Debrosse +Debrosse-Saint-Louis +Deleskey +Demers +Dempsey +Diehl +Dobbie +Dockstader +Doe +Downey +Dribin +Ducharme +Duphily +Eckstein +Ericson +Evans +Fabel +Farrell +Favreau +Favreau +Foley +Follett +Forrest +Gack +Galorath +Garmus +Gehly +Gendron +Gladney +Glanville +Goldsmith +Gottesdiener +Grealish +Haaigis +Hacker +Hacker-LeCount +Haddad +Haigis +Hamel +Harrington +Henderson +Hennessey +Herron +Hessmiller +Hill +Hillier +Hobbs +Hobbs +Hobbs +Ierardi +Isaacs +Jones +Kappelman +Karem +Karten +Keith +Kelly +Kenny +Killilea +Krasner +LaFrance +Lawhorn +Layman +LeBlanc +Legarz +Leo +Leonard +Lewis +Lokinger +Lovering +Lusk +MacDonald +Maciewicz +Maguire +Mahoney +Mariani +McCarthy +McCauley +McDonald +McGarry +McMahon +Menard +Minkiewicz +Moe +Morrison +Motyka +Murphy +Nemes +Newman +Newman +Nickels +Nye +Nyman +OConnor +Orr +Palmer-Erbs +Palmieri +Panagiotes +Parker +Parks +Parks +Pelletier +PelletierRutkowski +Penn +Peters +Pfannkoch +Pinchera +Planansky +Plasse +Poillucci +Pomerleau +Potter +Powers +Primas +Pritchard +Quenga +Rancourt +Rearick +Reifer +Rice +rogers +Rooney +Rosoff +Roy +Ruhe +Russac +Russell +Ryan +Sahely +Sak +Salvaggio +Santiano +Sassenburg +Scanlon +Schall +Scopetski +Searfos +Sergio +Sergio +Shapiro +Sharpe +Silck +Silveri +Simmons +Simons +Skirvin-Leclair +Smalarz +Smith +Smith-Burke +Sullivan +Swansburg +Sweeney +Talley +Taylor +Tebbetts +Thaxton +Tiberio +tillman +Tilton(Cuttino) +Toronto +Tull +Vernon +VonHalle +Walendziewicz +Walker +Walsh +Wei +Welsh +Wiegers +Wilkins +Williams +Wright +Wyron +Young +Yourdon +Zentis \ No newline at end of file diff --git a/workflow/engine/test/fixtures/outputDocument.yml b/workflow/engine/test/fixtures/outputDocument.yml new file mode 100644 index 000000000..8b124b8a7 --- /dev/null +++ b/workflow/engine/test/fixtures/outputDocument.yml @@ -0,0 +1,84 @@ +load1: + - + Title: "Obtain the output document data" + Function: "loadTest" + Input: + OUT_DOC_UID: "1" + Output: + Type: "array" +load2: + - + Title: "Obtain the output document data (not existent)" + Function: "loadTest" + Input: + OUT_DOC_UID: "111111111111" + Output: + Type: "Exception" +create1: + - + Title: "Create the output document data" + Function: "createTest" + Input: + OUT_DOC_UID: "2" + PRO_UID: "2" + OUT_DOC_TITLE: "OUT_DOC_TITLE" + OUT_DOC_DESCRIPTION: "OUT_DOC_DESCRIPTION" + OUT_DOC_FILENAME: "OUT_DOC_FILENAME" + OUT_DOC_TEMPLATE: "OUT_DOC_TEMPLATE" + Output: + Type: "integer" +create2: + - + Title: "Create the output document data (whit incomplete data)" + Function: "createTest" + Input: + OUT_DOC_UID: "" + PRO_UID: "2" + OUT_DOC_TITLE: "OUT_DOC_TITLE" + OUT_DOC_DESCRIPTION: "OUT_DOC_DESCRIPTION" + OUT_DOC_FILENAME: "OUT_DOC_FILENAME" + OUT_DOC_TEMPLATE: "OUT_DOC_TEMPLATE" + Output: + Type: "Exception" +update1: + - + Title: "Update the output document data" + Function: "updateTest" + Input: + OUT_DOC_UID: "1" + PRO_UID: "2" + OUT_DOC_TITLE: "OUT_DOC_TITLE1" + OUT_DOC_DESCRIPTION: "OUT_DOC_DESCRIPTION1" + OUT_DOC_FILENAME: "OUT_DOC_FILENAME1" + OUT_DOC_TEMPLATE: "OUT_DOC_TEMPLATE1" + Output: + Type: "integer" +update2: + - + Title: "Update the output document data (not existent)" + Function: "updateTest" + Input: + OUT_DOC_UID: "111111111111" + PRO_UID: "2" + OUT_DOC_TITLE: "OUT_DOC_TITLE1" + OUT_DOC_DESCRIPTION: "OUT_DOC_DESCRIPTION1" + OUT_DOC_FILENAME: "OUT_DOC_FILENAME1" + OUT_DOC_TEMPLATE: "OUT_DOC_TEMPLATE1" + Output: + Type: "Exception" +remove1: + - + Title: "Remove the output document data" + Function: "removeTest" + Input: + OUT_DOC_UID: "2" + Output: + Type: "NULL" +remove2: + - + Title: "Remove the output document data (not existent)" + Function: "removeTest" + Input: + OUT_DOC_UID: "111111111111" + Output: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/processMap.yml b/workflow/engine/test/fixtures/processMap.yml new file mode 100644 index 000000000..ed03fa1a9 --- /dev/null +++ b/workflow/engine/test/fixtures/processMap.yml @@ -0,0 +1,494 @@ +load1: + - + Title: "Obtain the processmap data" + Function: "loadTest" + Input: + PRO_UID: "1" + Output: + Type: "string" +load2: + - + Title: "Obtain the processmap data (not existent)" + Function: "loadTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +createProcess1: + - + Title: "Create a process" + Function: "createProcessTest" + Input: + USR_UID: "1" + Output: + Type: "boolean" +updateProcess1: + - + Title: "Update a process" + Function: "updateProcessTest" + Input: + PRO_UID: "1" + PRO_TITLE_X: 100 + PRO_TITLE_Y: 100 + Output: + Type: "integer" +updateProcess2: + - + Title: "Update a process (not existent)" + Function: "updateProcessTest" + Input: + PRO_UID: "111111111111" + PRO_TITLE_X: 100 + PRO_TITLE_Y: 100 + Output: + Type: "Exception" +editProcess1: + - + Title: "Edit the process info" + Function: "editProcessTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +editProcess2: + - + Title: "Edit the process info (not existent)" + Function: "editProcessTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +saveTitlePosition1: + - + Title: "Save the title position" + Function: "saveTitlePositionTest" + Input: + PRO_UID: "1" + PRO_X: 100 + PRO_Y: 100 + Output: + Type: "boolean" +saveTitlePosition2: + - + Title: "Save the title position (not existent)" + Function: "saveTitlePositionTest" + Input: + PRO_UID: "111111111111" + PRO_X: 100 + PRO_Y: 100 + Output: + Type: "Exception" +steps1: + - + Title: "Show the task steps" + Function: "stepsTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + Output: + Type: "boolean" +steps2: + - + Title: "Show the task steps (not existent)" + Function: "stepsTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + Output: + Type: "Exception" +users1: + - + Title: "Show the task users" + Function: "usersTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + Output: + Type: "boolean" +users2: + - + Title: "Show the task users (not existent)" + Function: "usersTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + Output: + Type: "Exception" +stepsConditions1: + - + Title: "Show the step conditions of the task" + Function: "stepsConditionsTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + Output: + Type: "boolean" +stepsConditions2: + - + Title: "Show the step conditions of the task (not existent)" + Function: "stepsConditionsTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + Output: + Type: "Exception" +stepsTriggers1: + - + Title: "Show the step triggers of the task" + Function: "stepsTriggersTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + Output: + Type: "boolean" +stepsTriggers2: + - + Title: "Show the step triggers of the task (not existent)" + Function: "stepsTriggersTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + Output: + Type: "Exception" +addTask1: + - + Title: "Add a task to process" + Function: "addTaskTest" + Input: + PRO_UID: "1" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "boolean" +addTask2: + - + Title: "Add a task to process (not existent)" + Function: "addTaskTest" + Input: + PRO_UID: "111111111111" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "Exception" +editTaskProperties1: + - + Title: "Edit the task properties" + Function: "editTaskPropertiesTest" + Input: + TAS_UID: "1" + iForm: 1 + iIndex: 0 + Output: + Type: "boolean" +editTaskProperties2: + - + Title: "Edit the task properties (not existent)" + Function: "editTaskPropertiesTest" + Input: + TAS_UID: "111111111111" + iForm: 1 + iIndex: 0 + Output: + Type: "Exception" +saveTaskPosition1: + - + Title: "Save the task position" + Function: "saveTaskPositionTest" + Input: + TAS_UID: "1" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "integer" +saveTaskPosition2: + - + Title: "Save the task position (not existent)" + Function: "saveTaskPositionTest" + Input: + TAS_UID: "111111111111" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "Exception" +deleteTask1: + - + Title: "Delete a task" + Function: "deleteTaskTest" + Input: + TAS_UID: "1" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "boolean" +deleteTask2: + - + Title: "Delete a task (not existent)" + Function: "deleteTaskTest" + Input: + TAS_UID: "111111111111" + TAS_X: 100 + TAS_Y: 100 + Output: + Type: "Exception" +addGuide1: + - + Title: "Add a new guide" + Function: "addGuideTest" + Input: + PRO_UID: "1" + iPosition: 100 + sDirection: "vertical" + Output: + Type: "string" +addGuide2: + - + Title: "Add a new guide (not existent)" + Function: "addGuideTest" + Input: + PRO_UID: "111111111111" + iPosition: 100 + sDirection: "vertical" + Output: + Type: "Exception" +saveGuidePosition1: + - + Title: "Save de guide position" + Function: "saveGuidePositionTest" + Input: + SWI_UID: "1" + iPosition: 100 + sDirection: "vertical" + Output: + Type: "integer" +saveGuidePosition2: + - + Title: "Save de guide position (not existent)" + Function: "saveGuidePositionTest" + Input: + SWI_UID: "111111111111" + iPosition: 100 + sDirection: "vertical" + Output: + Type: "Exception" +deleteGuide1: + - + Title: "Delete a guide" + Function: "deleteGuideTest" + Input: + SWI_UID: "1" + Output: + Type: "boolean" +deleteGuide2: + - + Title: "Delete a guide (not existent)" + Function: "deleteGuideTest" + Input: + SWI_UID: "111111111111" + Output: + Type: "Exception" +deleteGuides1: + - + Title: "Delete all guides" + Function: "deleteGuidesTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +deleteGuides2: + - + Title: "Delete all guides (not existent)" + Function: "deleteGuidesTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +updateText1: + - + Title: "Update a text" + Function: "updateTextTest" + Input: + SWI_UID: "1" + SWI_TEXT: "text1" + Output: + Type: "integer" +updateText2: + - + Title: "Update a text (not existent)" + Function: "updateTextTest" + Input: + SWI_UID: "111111111111" + SWI_TEXT: "text1" + Output: + Type: "Exception" +saveTextPosition1: + - + Title: "Update a text position" + Function: "saveTextPositionTest" + Input: + SWI_UID: "1" + SWI_X: 100 + SWI_Y: 100 + Output: + Type: "integer" +saveTextPosition2: + - + Title: "Update a text position (not existent)" + Function: "saveTextPositionTest" + Input: + SWI_UID: "111111111111" + SWI_X: 100 + SWI_Y: 100 + Output: + Type: "Exception" +deleteText1: + - + Title: "Delete a text" + Function: "deleteTextTest" + Input: + SWI_UID: "2" + Output: + Type: "boolean" +deleteText2: + - + Title: "Delete a text (not existent)" + Function: "deleteTextTest" + Input: + SWI_UID: "111111111111" + Output: + Type: "Exception" +dynaformsList1: + - + Title: "Show the dynaforms list" + Function: "dynaformsListTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +dynaformsList2: + - + Title: "Show the dynaforms list (not existent)" + Function: "dynaformsListTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +outputdocsList1: + - + Title: "Show the output documents list" + Function: "outputdocsListTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +outputdocsList2: + - + Title: "Show the output documents list (not existent)" + Function: "outputdocsListTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +inputdocsList1: + - + Title: "Show the input documents list" + Function: "inputdocsListTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +inputdocsList2: + - + Title: "Show the input documents list (not existent)" + Function: "inputdocsListTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +triggersList1: + - + Title: "Show the triggers list" + Function: "triggersListTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +triggersList2: + - + Title: "Show the triggers list (not existent)" + Function: "triggersListTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +messagesList1: + - + Title: "Show the messages list" + Function: "messagesListTest" + Input: + PRO_UID: "1" + Output: + Type: "boolean" +messagesList2: + - + Title: "Show the messages list (not existent)" + Function: "messagesListTest" + Input: + PRO_UID: "111111111111" + Output: + Type: "Exception" +currentPattern1: + - + Title: "Show the current pattern" + Function: "currentPatternTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + Output: + Type: "boolean" +currentPattern2: + - + Title: "Show the current pattern (not existent)" + Function: "currentPatternTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + Output: + Type: "Exception" +newPattern1: + - + Title: "New pattern" + Function: "newPatternTest" + Input: + PRO_UID: "1" + TAS_UID: "1" + ROU_NEXT_TASK: "2" + ROU_TYPE: "SEQUENTIAL" + Output: + Type: "boolean" +newPattern2: + - + Title: "New pattern (not existent)" + Function: "newPatternTest" + Input: + PRO_UID: "111111111111" + TAS_UID: "1" + ROU_NEXT_TASK: "2" + ROU_TYPE: "SEQUENTIAL" + Output: + Type: "Exception" +deleteDerivation1: + - + Title: "Delete a derivation rule" + Function: "deleteDerivationTest" + Input: + TAS_UID: "1" + Output: + Type: "boolean" +deleteDerivation2: + - + Title: "Delete a derivation rule (not existent)" + Function: "deleteDerivationTest" + Input: + TAS_UID: "111111111111" + Output: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/route.yml b/workflow/engine/test/fixtures/route.yml new file mode 100644 index 000000000..cf7d98305 --- /dev/null +++ b/workflow/engine/test/fixtures/route.yml @@ -0,0 +1,112 @@ +load1: + - + Title: "Obtain the route data" + Function: "loadTest" + Input: + ROU_UID: "1" + Output: + Type: "array" +load2: + - + Title: "Obtain the route data (not existent)" + Function: "loadTest" + Input: + ROU_UID: "111111111111" + Output: + Type: "Exception" +create1: + - + Title: "Create the route data" + Function: "createTest" + Input: + ROU_UID: "2" + ROU_PARENT: "" + PRO_UID: "2" + TAS_UID: "2" + ROU_NEXT_TAK: "2" + ROU_CASE: "0" + ROU_TYPE: "SEQUENTIAL" + ROU_CONDITION: "" + ROU_TO_LAST_USER: "FALSE" + ROU_OPTIONAL: "FALSE" + ROU_SEND_EMAIL: "TRUE" + ROU_SOURCEANCHOR: "1" + ROU_TARGETANCHOR: "0" + Output: + Type: "integer" +create2: + - + Title: "Create the route data (whit incomplete data)" + Function: "createTest" + Input: + ROU_UID: "" + ROU_PARENT: "" + PRO_UID: "2" + TAS_UID: "2" + ROU_NEXT_TAK: "2" + ROU_CASE: "0" + ROU_TYPE: "SEQUENTIAL" + ROU_CONDITION: "" + ROU_TO_LAST_USER: "FALSE" + ROU_OPTIONAL: "FALSE" + ROU_SEND_EMAIL: "TRUE" + ROU_SOURCEANCHOR: "1" + ROU_TARGETANCHOR: "0" + Output: + Type: "Exception" +update1: + - + Title: "Update the route data" + Function: "updateTest" + Input: + ROU_UID: "1" + ROU_PARENT: "" + PRO_UID: "2" + TAS_UID: "2" + ROU_NEXT_TAK: "2" + ROU_CASE: "0" + ROU_TYPE: "SEQUENTIAL" + ROU_CONDITION: "" + ROU_TO_LAST_USER: "FALSE" + ROU_OPTIONAL: "FALSE" + ROU_SEND_EMAIL: "TRUE" + ROU_SOURCEANCHOR: "1" + ROU_TARGETANCHOR: "0" + Output: + Type: "integer" +update2: + - + Title: "Update the route data (not existent)" + Function: "updateTest" + Input: + ROU_UID: "111111111111" + ROU_PARENT: "" + PRO_UID: "2" + TAS_UID: "2" + ROU_NEXT_TAK: "2" + ROU_CASE: "0" + ROU_TYPE: "SEQUENTIAL" + ROU_CONDITION: "" + ROU_TO_LAST_USER: "FALSE" + ROU_OPTIONAL: "FALSE" + ROU_SEND_EMAIL: "TRUE" + ROU_SOURCEANCHOR: "1" + ROU_TARGETANCHOR: "0" + Output: + Type: "Exception" +remove1: + - + Title: "Remove the route data" + Function: "removeTest" + Input: + ROU_UID: "2" + Output: + Type: "NULL" +remove2: + - + Title: "Remove the route data (not existent)" + Function: "removeTest" + Input: + ROU_UID: "111111111111" + Output: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/step.yml b/workflow/engine/test/fixtures/step.yml new file mode 100755 index 000000000..3a51086f2 --- /dev/null +++ b/workflow/engine/test/fixtures/step.yml @@ -0,0 +1,35 @@ +CreateTestSteps: + - + Title:"Creating new Steps" + Function:"CreateStep" + Input: + PRO_UID[]:"guid.pm" + TAS_UID[]:"guid.pm" + Output: + Value: 1 +StepUnitTest: + - + Title:"Updating Steps" + Function:"UpdateStep" + Input: + STEP_UID[]:"*.CREATED" + PRO_UID[]:"guid.pm" + TAS_UID[]:"guid.pm" + STEP_OBJ_UID[]:"stepUidObj.pm" + STEP_POSITION[]:"rand.number" + Output: + Value: 1 + - + Title:"Loading Steps" + Function:"LoadStep" + Input: + STEP_UID[]:"*.CREATED" + Output: + Type: "array" + - + Title:"Removing Steps" + Function:"RemoveStep" + Input: + STEP_UID[]:"*.CREATED" + Output: + Type: "NULL" diff --git a/workflow/engine/test/fixtures/stepTrigger.yml b/workflow/engine/test/fixtures/stepTrigger.yml new file mode 100755 index 000000000..69a6c71b0 --- /dev/null +++ b/workflow/engine/test/fixtures/stepTrigger.yml @@ -0,0 +1,43 @@ +CreateTestSteps: + - + Title:"Creating new Steps" + Function:"CreateStep" + Input: + STEP_UID[]:"guid.pm" + TAS_UID[]:"guid.pm" + TRI_UID[]:"guid.pm" + ST_TYPE:"Step Type" + Output: + Value: 1 +StepUnitTest: + - + Title:"Updating Steps" + Function:"UpdateStep" + Input: + STEP_UID[]:"CREATED" + TAS_UID[]:"CREATED_TAS" + TRI_UID[]:"CREATED_TRI" + ST_TYPE[]:"CREATED_TYPE" + ST_CONDITION[]:"*.text.es" + Output: + Value: 1 + - + Title:"Loading Steps" + Function:"LoadStep" + Input: + STEP_UID[]:"CREATED" + TAS_UID[]:"CREATED_TAS" + TRI_UID[]:"CREATED_TRI" + ST_TYPE[]:"CREATED_TYPE" + Output: + Type: "array" + - + Title:"Removing Steps" + Function:"RemoveStep" + Input: + STEP_UID[]:"CREATED" + TAS_UID[]:"CREATED_TAS" + TRI_UID[]:"CREATED_TRI" + ST_TYPE[]:"CREATED_TYPE" + Output: + Type: "NULL" diff --git a/workflow/engine/test/fixtures/swimlanesElements.yml b/workflow/engine/test/fixtures/swimlanesElements.yml new file mode 100644 index 000000000..b55875dd1 --- /dev/null +++ b/workflow/engine/test/fixtures/swimlanesElements.yml @@ -0,0 +1,84 @@ +load1: + - + Title: "Obtain the swimlane element data" + Function: "loadTest" + Input: + SWI_UID: "1" + input: + Type: "array" +load2: + - + Title: "Obtain the swimlane element data (not existent)" + Function: "loadTest" + Input: + SWI_UID: "111111111111" + input: + Type: "Exception" +create1: + - + Title: "Create the swimlane element data" + Function: "createTest" + Input: + SWI_UID: "2" + PRO_UID: "2" + SWI_TYPE: "LINE" + SWI_X: "100" + SWI_Y: "0" + SWI_TEXT: "SWI_TEXT" + input: + Type: "integer" +create2: + - + Title: "Create the swimlane element data (whit incomplete data)" + Function: "createTest" + Input: + SWI_UID: "" + PRO_UID: "2" + SWI_TYPE: "LINE" + SWI_X: "100" + SWI_Y: "0" + SWI_TEXT: "SWI_TEXT" + input: + Type: "Exception" +update1: + - + Title: "Update the swimlane element data" + Function: "updateTest" + Input: + SWI_UID: "1" + PRO_UID: "2" + SWI_TYPE: "LINE" + SWI_X: "100" + SWI_Y: "0" + SWI_TEXT: "SWI_TEXT1" + input: + Type: "integer" +update2: + - + Title: "Update the swimlane element data (not existent)" + Function: "updateTest" + Input: + SWI_UID: "111111111111" + PRO_UID: "2" + SWI_TYPE: "LINE" + SWI_X: "100" + SWI_Y: "0" + SWI_TEXT: "SWI_TEXT1" + input: + Type: "Exception" +remove1: + - + Title: "Remove the swimlane element data" + Function: "removeTest" + Input: + SWI_UID: "2" + input: + Type: "NULL" +remove2: + - + Title: "Remove the swimlane element data (not existent)" + Function: "removeTest" + Input: + SWI_UID: "111111111111" + input: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/task.yml b/workflow/engine/test/fixtures/task.yml new file mode 100755 index 000000000..6bb277c6f --- /dev/null +++ b/workflow/engine/test/fixtures/task.yml @@ -0,0 +1,32 @@ +CreateTestTasks: + - + Title:"Creating new tasks" + Function:"CreateTask" + Input: + PRO_UID[]:"guid.pm" + Output: + Value: 1 +TaskUnitTest: + - + Title:"Updating tasks" + Function:"UpdateTask" + Input: + TAS_UID[]: "*.CREATED" + TAS_DESCRIPTION[]: "text.es" + TAS_TITLE[]: "*.html.es" + Output: + Value: 1 + - + Title:"Loading tasks" + Function:"LoadTask" + Input: + TAS_UID[]: "*.CREATED" + Output: + Type: "array" + - + Title:"Removing tasks" + Function:"RemoveTask" + Input: + TAS_UID[]: "*.CREATED" + Output: + Type: "NULL" diff --git a/workflow/engine/test/fixtures/taskUser.yml b/workflow/engine/test/fixtures/taskUser.yml new file mode 100644 index 000000000..3e345b4aa --- /dev/null +++ b/workflow/engine/test/fixtures/taskUser.yml @@ -0,0 +1,44 @@ +create1: + - + Title: "Create the group user row" + Function: "createTest" + Input: + TAS_UID: "2" + USR_UID: "2" + TU_TYPE: "2" + TU_RELATION: "2" + input: + Type: "integer" +create2: + - + Title: "Create the group user row (whit incomplete data)" + Function: "createTest" + Input: + TAS_UID: "" + USR_UID: "2" + TU_TYPE: "2" + TU_RELATION: "2" + input: + Type: "Exception" +remove1: + - + Title: "Remove the group user row" + Function: "removeTest" + Input: + TAS_UID: "2" + USR_UID: "2" + TU_TYPE: "2" + TU_RELATION: "2" + input: + Type: "NULL" +remove2: + - + Title: "Remove the group user row (not existent)" + Function: "removeTest" + Input: + TAS_UID: "111111111111" + USR_UID: "2" + TU_TYPE: "2" + TU_RELATION: "2" + input: + Type: "Exception" diff --git a/workflow/engine/test/fixtures/trigger.yml b/workflow/engine/test/fixtures/trigger.yml new file mode 100755 index 000000000..6c70f54b4 --- /dev/null +++ b/workflow/engine/test/fixtures/trigger.yml @@ -0,0 +1,32 @@ +CreateTestTriggers: + - + Title:"Creating new Triggers" + Function:"CreateTrigger" + Input: + PRO_UID[]:"guid.pm" + Output: + Value: 1 +TriggerUnitTest: + - + Title:"Updating Triggers" + Function:"UpdateTrigger" + Input: + TRI_UID[]:"*.CREATED" + TRI_TITLE[]:"first.name.es" + TRI_DESCRIPTION[]:"*.text.es" + Output: + Value: 1 + - + Title:"Loading Triggers" + Function:"LoadTrigger" + Input: + TRI_UID[]:"*.CREATED" + Output: + Type: "array" + - + Title:"Removing Triggers" + Function:"RemoveTrigger" + Input: + TRI_UID[]:"*.CREATED" + Output: + Type: "NULL" diff --git a/workflow/engine/test/fixtures/user.yml b/workflow/engine/test/fixtures/user.yml new file mode 100755 index 000000000..6ac454c5f --- /dev/null +++ b/workflow/engine/test/fixtures/user.yml @@ -0,0 +1,34 @@ +CreateTestUsers: + - + Title:"Creating new Users" + Function:"CreateUser" + Input: + USR_UID[]:"guid.pm" + Output: + Value: 1 +UserUnitTest: + - + Title:"Updating Users" + Function:"UpdateUser" + Input: + USR_UID[]: "*.CREATED" + USR_EMAIL[]: "*.email.es" + USR_USRNAME[]: "first.name.es" + USR_FIRSTNAME[]: "first.name.es" + USR_LASTNAME[]: "last.name.es" + Output: + Value: 1 + - + Title:"Loading Users" + Function:"LoadUser" + Input: + USR_UID[]: "*.CREATED" + Output: + Type: "array" + - + Title:"Removing Users" + Function:"RemoveUser" + Input: + USR_UID[]: "*.CREATED" + Output: + Type: "NULL" diff --git a/workflow/engine/test/unit/gulliver/classDBConnectionTest.php b/workflow/engine/test/unit/gulliver/classDBConnectionTest.php new file mode 100644 index 000000000..76161f6d3 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDBConnectionTest.php @@ -0,0 +1,74 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + global $G_ENVIRONMENTS; + $counter =1; + $testItems = 0; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + }else + include ( $dbfile ); + }else + exit (201); + require_once( PATH_GULLIVER . 'class.dbconnection.php'); + $obj = new DBConnection(); + $method = array ( ); + $methods = get_class_methods('DBConnection'); + + $t = new lime_test( 20 , new lime_output_color()); + $t->diag('class DBConnection' ); + + /* Listing Method */ + $t->is( count( $methods ) , 8, "class DBConnection " . 8 . " methods." ); + $t->todo ( 'Listing Method' ); + $t->is( $methods[0] , 'DBConnection', $counter++.' DBConnection'); + $t->is( $methods[1] , 'Reset' , $counter++.' Reset'); + $t->is( $methods[2] , 'Free' , $counter++.' Free'); + $t->is( $methods[3] , 'Close' , $counter++.' Close'); + $t->is( $methods[4] , 'logError' , $counter++.' logError'); + $t->is( $methods[5] , 'traceError' , $counter++.' traceError'); + $t->is( $methods[6] , 'printArgs' , $counter++.' printArgs'); + $t->is( $methods[7] , 'GetLastID' , $counter++.' GetLastID'); + + /* checking methods */ + $t->todo( 'checking methods' ); + $t->can_ok( $obj, 'DBConnection', 'DBConnection()'); + $t->can_ok( $obj, 'Reset' , 'Reset()'); + $t->can_ok( $obj, 'Free' , 'Free()'); + $t->can_ok( $obj, 'Close' , 'Close()'); + $t->can_ok( $obj, 'logError' , 'logError()'); + $t->can_ok( $obj, 'traceError' , 'traceError()'); + $t->can_ok( $obj, 'printArgs' , 'printArgs()'); + $t->can_ok( $obj, 'GetLastID' , 'GetLastID()'); + $t->todo ( 'Review, specific examples.'); \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classDBRecordsetTest.php b/workflow/engine/test/unit/gulliver/classDBRecordsetTest.php new file mode 100644 index 000000000..25db3dfb8 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDBRecordsetTest.php @@ -0,0 +1,66 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + require_once( PATH_GULLIVER . 'class.dbconnection.php'); + require_once( PATH_GULLIVER . 'class.dbsession.php'); + require_once( PATH_GULLIVER . 'class.dbrecordset.php'); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $dset = $ses->Execute ( "SELECT * from APPLICATION" ); + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('DBRecordSet'); + $t = new lime_test( 8, new lime_output_color()); + + $t->diag('class DBRecordset' ); + $t->is( count($methods) , 6, "class G " . count($methods) . " methods." ); + $t->isa_ok( $dset , 'DBRecordSet' , 'class DBRecordset created'); + $t->can_ok( $dset , 'SetTo' , 'SetTo()' ); + $t->can_ok( $dset , 'Free' , 'Free()' ); + $t->can_ok( $dset , 'Count' , 'Count()' ); + $t->can_ok( $dset , 'Read' , 'Read()' ); + $t->can_ok( $dset , 'ReadAbsolute', 'ReadAbsolute()'); + $t->todo( 'review all pendings in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classDBSessionTest.php b/workflow/engine/test/unit/gulliver/classDBSessionTest.php new file mode 100644 index 000000000..56f747e45 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDBSessionTest.php @@ -0,0 +1,67 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + require_once( PATH_GULLIVER . 'class.dbconnection.php'); + require_once( PATH_GULLIVER . 'class.dbsession.php'); + require_once( PATH_GULLIVER . 'class.dbrecordset.php'); + $counter =1; + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $dset = $ses->Execute ( "SELECT * from APPLICATION" ); + $method = array( ); + $testItems = 0; + $methods = get_class_methods('DBSession'); + $t = new lime_test(8, new lime_output_color()); + + $t->diag('class DBSession' ); + $t->is( count($methods) , 5, "class classDBSession " . 5 . " methods." ); + $t->isa_ok( $ses , 'DBSession', 'class DBSession created'); + + $t->can_ok( $ses, 'DBSession', $counter++.' DBSession()'); + $t->can_ok( $ses, 'setTo', $counter++.' Free()'); + $t->can_ok( $ses, 'UseDB', $counter++.' UseDB()'); + $t->can_ok( $ses, 'Execute', $counter++.' Execute()'); + $t->can_ok( $ses, 'Free', $counter++.' Free()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classDBTableTest.php b/workflow/engine/test/unit/gulliver/classDBTableTest.php new file mode 100644 index 000000000..d10f4a822 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDBTableTest.php @@ -0,0 +1,71 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * +*/ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + }else + include ( $dbfile ); + }else + exit (201); + + require_once( PATH_GULLIVER . 'class.dbconnection.php'); + require_once( PATH_GULLIVER . 'class.dbsession.php'); + require_once( PATH_GULLIVER . 'class.dbtable.php'); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $obj = new DBTable ( $dbc, "APPLICATION" , array ( 'APP_UID' ) ); + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('DBTable'); + $t = new lime_test(13, new lime_output_color()); + + $t->diag('class DBTable' ); + $t->is( count($methods) , 11, "class DBTable " . 11 . " methods." ); + $t->isa_ok( $obj, 'DBTable' , 'class DBTable created'); + $t->can_ok( $obj, 'SetTo' , 'SetTo()'); + $t->can_ok( $obj, 'loadEmpty' , 'loadEmpty()'); + $t->can_ok( $obj, 'loadWhere' , 'loadWhere()'); + $t->can_ok( $obj, 'load' , 'load()'); + $t->can_ok( $obj, 'nextvalPGSql', 'nextvalPGSql()'); + $t->can_ok( $obj, 'insert' , 'insert()'); + $t->can_ok( $obj, 'update' , 'update()'); + $t->can_ok( $obj, 'save' , 'save()'); + $t->can_ok( $obj, 'delete' , 'delete()'); + $t->can_ok( $obj, 'next' , 'next()'); + + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classDatabase_baseTest.php b/workflow/engine/test/unit/gulliver/classDatabase_baseTest.php new file mode 100644 index 000000000..43c277cf2 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDatabase_baseTest.php @@ -0,0 +1,59 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * +*/ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'database_base'); + $counter=1; + $t = new lime_test( 12, new lime_output_color()); + $obj = new database_base(); + $methods = get_class_methods('database_base'); + + $t->diag('class database_base' ); + + /* Listing Method */ + + $t->isa_ok( $obj , 'database_base', 'class database_base created'); + $t->todo ( 'Listing Method' ); + $t->is( count ( $methods ) , 8, "class database_base " . count ( $methods ) . " methods." ); + /* checking methods */ + + $t->can_ok( $obj, '__construct' , $counter++.' __construct()'); + $t->can_ok( $obj, 'generateDropTableSQL' , $counter++.' generateDropTableSQL()'); + $t->can_ok( $obj, 'generateCreateTableSQL' , $counter++.' generateCreateTableSQL()'); + $t->can_ok( $obj, 'generateDropColumnSQL' , $counter++.' generateDropColumnSQL()'); + $t->can_ok( $obj, 'generateAddColumnSQL' , $counter++.' generateAddColumnSQL()'); + $t->can_ok( $obj, 'generateChangeColumnSQL', $counter++.' generateChangeColumnSQL()'); + $t->can_ok( $obj, 'executeQuery' , $counter++.' executeQuery()'); + $t->can_ok( $obj, 'close' , $counter++.' close()'); + + $t->todo ( 'Review, specific examples.'); \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classDatabase_mysqlTest.php b/workflow/engine/test/unit/gulliver/classDatabase_mysqlTest.php new file mode 100644 index 000000000..13ec91481 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDatabase_mysqlTest.php @@ -0,0 +1,65 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * +*/ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'database_mysql'); + $t = new lime_test( 24, new lime_output_color()); + $obj = new database_base(); + $method = array (); + $testItems = 0; + $methods = get_class_methods('database'); + $t->diag('class database' ); + $t->is( count($methods) , 21, "class database " . count($methods) . " methods." ); + $t->is( $methods[0] , '__construct', '__construct'); + $t->is( $methods[1] , 'generateCreateTableSQL' , 'generateCreateTableSQL'); + $t->is( $methods[2] , 'generateDropTableSQL' , 'generateDropTableSQL'); + $t->is( $methods[3] , 'generateDropColumnSQL' , 'generateDropColumnSQL'); + $t->is( $methods[4] , 'generateAddColumnSQL' , 'generateAddColumnSQL'); + $t->is( $methods[5] , 'generateChangeColumnSQL' , 'generateChangeColumnSQL'); + $t->is( $methods[6] , 'generateGetPrimaryKeysSQL' , 'generateGetPrimaryKeysSQL'); + $t->is( $methods[7] , 'generateDropPrimaryKeysSQL', 'generateDropPrimaryKeysSQL'); + $t->is( $methods[8] , 'generateAddPrimaryKeysSQL' , 'generateAddPrimaryKeysSQL'); + $t->is( $methods[9] , 'generateDropKeySQL' , 'generateDropKeySQL'); + $t->is( $methods[10] , 'generateAddKeysSQL' , 'generateAddKeysSQL'); + $t->is( $methods[11] , 'generateShowTablesSQL' , 'generateShowTablesSQL'); + $t->is( $methods[12] , 'generateShowTablesLikeSQL' , 'generateShowTablesLikeSQL'); + $t->is( $methods[13] , 'generateDescTableSQL' , 'generateDescTableSQL'); + $t->is( $methods[14] , 'generateTableIndexSQL' , 'generateTableIndexSQL'); + $t->is( $methods[15] , 'isConnected' , 'isConnected'); + $t->is( $methods[16] , 'logQuery' , 'logQuery'); + $t->is( $methods[17] , 'executeQuery' , 'executeQuery'); + $t->is( $methods[18] , 'countResults' , 'countResults'); + $t->is( $methods[19] , 'getRegistry' , 'getRegistry'); + $t->is( $methods[20] , 'close' , 'close'); + $t->isa_ok( $obj , 'database_base', 'class database_base created'); + $t->todo( 'Examples'); \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classDvEditorTest.php b/workflow/engine/test/unit/gulliver/classDvEditorTest.php new file mode 100644 index 000000000..91671baa6 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDvEditorTest.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * +*/ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dvEditor'); + + $t = new lime_test( 3, new lime_output_color()); + $obj = "XmlForm_Field_HTML"; + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('XmlForm_Field_HTML'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class XmlForm_Field_HTML' ); + $t->is( $testItems , 18, "class XmlForm_Field_HTML " . $testItems . " methods." ); + $t->is( $obj , 'XmlForm_Field_HTML', 'class XmlForm_Field_HTML created'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classDynaformhandlerTest.php b/workflow/engine/test/unit/gulliver/classDynaformhandlerTest.php new file mode 100644 index 000000000..b7c626ddc --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classDynaformhandlerTest.php @@ -0,0 +1,44 @@ +diag('class dynaFormHandler' ); + $t->is( $testItems , 18, "class database " . $testItems . " methods." ); + $t->is( $methods[0] , '__construct' , '__construct'); + $t->is( $methods[1] , '__cloneEmpty' , '__cloneEmpty'); + $t->is( $methods[2] , 'toString' , 'toString'); + $t->is( $methods[3] , 'getNode' , 'getNode'); + $t->is( $methods[4] , 'setNode' , 'setNode'); + $t->is( $methods[5] , 'add' , 'add'); + $t->is( $methods[6] , 'replace' , 'replace'); + $t->is( $methods[7] , 'save' , 'save'); + $t->is( $methods[8] , 'fixXmlFile' , 'fixXmlFile'); + $t->is( $methods[9] , 'setHeaderAttribute' , 'setHeaderAttribute'); + $t->is( $methods[10] , 'modifyHeaderAttribute' , 'modifyHeaderAttribute'); + $t->is( $methods[11] , 'updateAttribute' , 'updateAttribute'); + $t->is( $methods[12] , 'remove' , 'remove'); + $t->is( $methods[13] , 'nodeExists' , 'nodeExists'); + $t->is( $methods[14] , 'moveUp' , 'moveUp'); + $t->is( $methods[15] , 'moveDown' , 'moveDown'); + $t->is( $methods[16] , 'getFields' , 'getFields'); + $t->is( $methods[17] , 'getFieldNames' , 'getFieldNames'); + $t->todo( 'review all pendings in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classErrorTest.php b/workflow/engine/test/unit/gulliver/classErrorTest.php new file mode 100644 index 000000000..a3e4b80b0 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classErrorTest.php @@ -0,0 +1,79 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + require_once( PATH_GULLIVER . 'class.dbconnection.php'); + require_once( PATH_GULLIVER . 'class.error.php'); + +$obj = new G_Error(); +$method = array ( ); +$testItems = 0; +$class_methods = get_class_methods('G_Error'); +foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; +} + +$t = new lime_test(11, new lime_output_color()); + +$t->diag('class error' ); + // + $t->is( $testItems , 13, "class G_Error " . 13 . " methods." ); +$t->isa_ok( $obj , 'G_Error', 'class G_Error created'); +$t->is( G_ERROR , -100, 'G_ERROR constant defined'); +$t->is( G_ERROR_ALREADY_ASSIGNED , -118, 'G_ERROR_ALREADY_ASSIGNED defined'); + +$obj = new G_Error( "string" ); +$t->is( $obj->code, -1, 'default code error'); +$t->is( $obj->message, "G Error: string", 'default message error'); +$t->is( $obj->level, E_USER_NOTICE, 'default level error'); + +$obj = new G_Error( G_ERROR_SYSTEM_UID ); +$t->is( $obj->code, -105, 'code error'); +$t->is( $obj->message, "G Error: ", 'message error'); + +$t->can_ok( $obj, "errorMessage", "exists method errorMessage"); +$msg = $obj->errorMessage ( G_ERROR ); +//$t->is( $msg->code, -100, 'fail in method errorMessage'); +$t->todo( 'fail in method errorMessage'); diff --git a/workflow/engine/test/unit/gulliver/classFckEditorTest.php b/workflow/engine/test/unit/gulliver/classFckEditorTest.php new file mode 100644 index 000000000..5c3618fb1 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classFckEditorTest.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * +*/ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'fckEditor'); + + $t = new lime_test( 2, new lime_output_color()); + $obj = "fckEditor"; + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('fckEditor'); + $t->diag('class fckEditor' ); + $t->is( count($methods) , 0, "class fckEditor " . count($methods) . " methods." ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classFilterFormTest.php b/workflow/engine/test/unit/gulliver/classFilterFormTest.php new file mode 100644 index 000000000..fc292f813 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classFilterFormTest.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'filterForm'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + $obj = new filterForm ( 'login/login'); + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('filterForm'); + $t = new lime_test(4, new lime_output_color()); + $t->diag('class filterForm' ); + $t->is( count($methods) , 12, "class filterForm " . count($methods) . " methods." ); + $t->isa_ok( $obj , 'filterForm', 'class filterForm created'); + $t->can_ok( $obj, 'render', 'render()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classFormTest.php b/workflow/engine/test/unit/gulliver/classFormTest.php new file mode 100644 index 000000000..a6c9a7a95 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classFormTest.php @@ -0,0 +1,59 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + $counter=1; + $obj = new Form ( 'login/login'); + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('Form'); + $t = new lime_test(15, new lime_output_color()); + $t->diag('class Form' ); + $t->is( count($methods) , 12, "class Form " . count($methods) . " methods." ); + $t->can_ok( $obj, 'Form',$counter++.' Form()'); + $t->can_ok( $obj, 'setDefaultValues',$counter++.' setDefaultValues()'); + $t->can_ok( $obj, 'printTemplate', $counter++.' printTemplate()'); + $t->can_ok( $obj, 'render', $counter++.' render()'); + $t->can_ok( $obj, 'setValues', $counter++.' setValues()'); + $t->can_ok( $obj, 'getFields', $counter++.' getFields()'); + $t->can_ok( $obj, 'validatePost', $counter++.' validatePost()'); + $t->can_ok( $obj, 'validateArray', $counter++.' validateArray()'); + $t->can_ok( $obj, 'getVars', $counter++.' getVars()'); + $t->can_ok( $obj, 'validateRequiredFields', $counter++.' validateRequiredFields()'); + $t->can_ok( $obj, 'parseFile', $counter++.' parseFile()'); + $t->can_ok( $obj, 'cloneObject', $counter++.' cloneObject()'); + $t->is( count($methods) , --$counter , "ok"); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classGTest.php b/workflow/engine/test/unit/gulliver/classGTest.php new file mode 100644 index 000000000..a4686524d --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classGTest.php @@ -0,0 +1,274 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( PATH_GULLIVER .'class.g.php'); + $obj = new G(); + $methods = get_class_methods('G'); + $t = new lime_test( 223, new lime_output_color()); + $t->diag('class G' ); + $t->is( count($methods) , 95, "class G " . 95 . " methods." ); + $t->isa_ok( $obj , 'G', 'class G created'); + $t->todo( 'review which PHP version is the minimum for Gulliver'); + $t->is( G::getVersion() , '3.0-1', 'Gulliver version'); + $t->todo( 'store the version in a file'); + $t->is( $obj->getIpAddress() , false, 'getIpAddress()'); + $t->isnt( $obj->getMacAddress() , '', 'getMacAddress()'); + $t->can_ok( $obj, 'microtime_float', 'microtime_float()'); + $t->can_ok( $obj, 'setFatalErrorHandler' , 'setFatalErrorHandler()'); + $t->can_ok( $obj, 'setErrorHandler', 'setErrorHandler()'); + $t->is( $obj->fatalErrorHandler( 'Fatal error') , 'Fatal error', 'fatalErrorHandler()'); + $like = '
    ERROR CAUGHT check log file
    IP address:
    '; + $t->is( $obj->fatalErrorHandler( 'error:abc
    ') , $like, 'fatalErrorHandler()'); + $t->can_ok( $obj, 'customErrorHandler', 'customErrorHandler()'); + + G::customErrorHandler ( G_DB_ERROR, "message error", "filename", 10, "context" ) ; + $t->can_ok( $obj, 'showErrorSource', 'showErrorSource()'); + $t->can_ok( $obj, 'customErrorLog', 'customErrorLog()'); + $t->can_ok( $obj, 'verboseError', 'verboseError()'); + $t->can_ok( $obj, 'encrypt', 'encrypt()'); + $k = URL_KEY; + $t->is( G::encrypt ("/sysOpenSource", $k), 'Ytap33°jmZ7D46bf2Jo', 'encrypt only workspace'); + $t->is( G::encrypt ("/sysOpenSource/", $k), 'Ytap33°jmZ7D46bf2Jpo', 'encrypt terminal slash'); + $t->is( G::encrypt ("/sysOpenSource/en", $k), 'Ytap33°jmZ7D46bf2Jpo158', 'encrypt two levels'); + $t->is( G::encrypt ("/sysOpenSource/en/test/login/login", $k), 'Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4A', 'encrypt normal page'); + $t->is( G::encrypt ("/sysOpenSource/en/test/login/login/demo", $k), 'Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4GDRmNCf', 'encrypt additional level'); + $t->is( G::encrypt ("/sysOpenSource/en/test/login/login?a=1&b=2", $k), 'Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4HDOcJRWzm2l', 'encrypt normal query string'); + $t->todo( 'encrypt query string plus pipe'); + $t->todo("encrypt query string plus pipe"); + $t->can_ok( $obj, 'decrypt', 'decrypt()'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jo', $k), "/sysOpenSource", 'decrypt only workspace'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jpo', $k), "/sysOpenSource/", 'decrypt terminal slash'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jpo158', $k), "/sysOpenSource/en", 'decrypt two levels'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4A', $k), "/sysOpenSource/en/test/login/login", 'decrypt normal page'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4GDRmNCf', $k), "/sysOpenSource/en/test/login/login/demo", 'decrypt additional level'); + $t->is( G::decrypt ('Ytap33°jmZ7D46bf2Jpo15+cp8ij4F°fo5fZ4mDZ5Jyi4HDOcJRWzm2l', $k) , "/sysOpenSource/en/test/login/login?a=1&b=2",'decrypt normal query string'); + $t->todo( 'decrypt query string plus pipe'); + $t->can_ok( $obj, 'lookup', 'lookup()'); + $t->is( G::lookup ('optimusprime.colosa.net'), "192.168.1.22", 'lookup any address'); + $t->can_ok( $obj, 'mk_dir', 'mk_dir()'); + $newDir = '/tmp/test/directory'; + $r = G::verifyPath ( $newDir ); + + if ( $r ) rmdir ( $newDir ); + $r = G::mk_dir ( $newDir ); + $r = G::verifyPath ( $newDir); + $t->is( $r, true, "mk_dir() $newDir"); + $t->can_ok( $obj, 'verifyPath', "verifyPath() $newDir"); + $t->isnt( PATH_CORE, 'PATH_CORE', 'Constant PATH_CORE'); + $t->isnt( PATH_GULLIVER, 'PATH_GULLIVER', 'Constant PATH_GULLIVER'); + $phatSitio = "/home/arturo/processmaker/trunk/workflow/engine/class.x.php/"; + $phatBuscar = "/processmaker/trunk/workflow/engine/class.x.php/"; + $t->is(( ereg( $phatBuscar , $phatSitio ) ), 1 , 'expandPath()'); + $t->is( G::LoadSystem("error"), NULL, 'LoadSystem()'); + $t->can_ok( $obj, 'RenderPage', 'RenderPage()'); + $t->can_ok( $obj, 'LoadSkin', 'LoadSkin()'); + $t->can_ok( $obj, 'LoadInclude', 'LoadInclude()'); + $t->can_ok( $obj, 'LoadTemplate', 'LoadTemplate()'); + $t->can_ok( $obj, 'LoadClassRBAC', 'LoadClassRBAC()'); + $t->can_ok( $obj, 'LoadClass', 'LoadClass()'); + $t->can_ok( $obj, 'LoadThirdParty', 'LoadThirdParty()'); + $t->can_ok( $obj, 'encryptlink', 'encryptlink()'); + $t->is( G::encryptlink("normal url"), "normal url", 'encryptlink() normal url'); + $t->todo( 'more tests with encryplink and remove ENABLE_ENCRYPT dependency'); + $t->can_ok( $obj, 'parseURI', 'parseURI()'); + + G::parseURI("http:/192.168.0.9/sysos/en/wf5/login/login/abc?ab=123&bc=zy"); + $t->todo( 'more tests with parseURI'); + $t->can_ok( $obj, 'streamFile', 'streamFile()'); + $t->can_ok( $obj, 'sendHeaders', 'sendHeaders()'); + $t->todo( 'more tests with sendHeaders'); + $t->can_ok( $obj, 'virtualURI', 'virtualURI()'); + $t->can_ok( $obj, 'createUID', 'createUID()'); + $t->is( G::createUID('directory','filename'), 'bDh5aTBaUG5vNkxwMnByWjJxT2EzNVk___', 'createUID() normal'); + $t->can_ok( $obj, 'getUIDName', 'getUIDName()'); + $t->is( G::getUIDName('bDh5aTBaUG5vNkxwMnByWjJxT2EzNVk___','12345678901234567890'), false, 'getUIDName() normal?'); + $t->can_ok( $obj, 'formatNumber', 'formatNumber()'); + $t->is( G::formatNumber('100000'), '100000', 'formatNumber() normal'); + $t->todo( 'is useful the function formatNumber??'); + $t->can_ok( $obj, 'formatDate', 'formatDate()'); + $t->is( G::formatDate( '2001-02-29' ), '2001-02-29', 'formatDate() '); + $t->is( G::formatDate( '2001-02-29', 'F d, Y' ), 'Februar01 29, 2001', 'formatDate() '); //is not working + $t->is( G::formatDate( '2001-02-29', 'd.m.Y' ), '29.02.2001', 'formatDate() '); + $t->todo( " the month literal text is defined here!! "); + $t->todo( 'review all methods in class G'); + $i=1; + $t->diag('class G' ); + $t->is( count($methods) , 95, "class database " . count($methods) . " methods." ); + $t->is( $methods[0] , 'is_https' ,$i++.' is_https'); + $t->is( $methods[1] , 'array_fill_value' ,$i++.' array_fill_value'); + $t->is( $methods[2] , 'generate_password' ,$i++.' generate_password'); + $t->is( $methods[3] , 'array_concat' ,$i++.' array_concat'); + $t->is( $methods[4] , 'var_compare' ,$i++.' var_compare'); + $t->is( $methods[5] , 'var_probe' ,$i++.' var_probe'); + $t->is( $methods[6] , 'getVersion' ,$i++.' getVersion'); + $t->is( G::getVersion() , '3.0-1', 'Gulliver version 3.0-1'); + $t->is( $methods[7] , 'getIpAddress' ,$i++.' getIpAddress'); + $t->is( $obj->getIpAddress() , false, 'getIpAddress()'); + $t->is( $methods[8] , 'getMacAddress' ,$i++.' getMacAddress'); + $t->isnt( $obj->getMacAddress() , '', 'getMacAddress()'); + $t->is( $methods[9] , 'microtime_float' ,$i++.' microtime_float'); + $t->can_ok( $obj, 'microtime_float', 'microtime_float()'); + $t->is( $methods[10] , 'setFatalErrorHandler',$i++.' setFatalErrorHandler'); + $t->can_ok( $obj, 'setFatalErrorHandler' , 'setFatalErrorHandler()'); + $t->is( $methods[11] , 'setErrorHandler' ,$i++.' setErrorHandler'); + $t->can_ok( $obj, 'setErrorHandler', 'setErrorHandler()'); + $t->is( $methods[12] , 'fatalErrorHandler' ,$i++.' fatalErrorHandler'); + $t->is( $methods[13] , 'customErrorHandler' ,$i++.' customErrorHandler'); + $t->is( $methods[14] , 'showErrorSource' ,$i++.' showErrorSource'); + $t->is( $methods[15] , 'customErrorLog' ,$i++.' customErrorLog'); + $t->is( $methods[16] , 'verboseError' ,$i++.' verboseError'); + $t->is( $methods[17] , 'encrypt' ,$i++.' encrypt'); + $t->is( $methods[18] , 'decrypt' ,$i++.' decrypt'); + $t->is( $methods[19] , 'lookup' ,$i++.' lookup'); + $t->is( $methods[20] , 'mk_dir' ,$i++.' mk_dir'); + $t->is( $methods[21] , 'rm_dir' ,$i++.' rm_dir'); + $t->is( $methods[22] , 'verifyPath' ,$i++.' verifyPath'); + $t->is( $methods[23] , 'expandPath' ,$i++.' expandPath'); + $t->is( $methods[24] , 'LoadSystem' ,$i++.' LoadSystem'); + $t->is( $methods[25] , 'RenderPage' ,$i++.' RenderPage'); + $t->is( $methods[26] , 'LoadSkin' ,$i++.' LoadSkin'); + $t->is( $methods[27] , 'LoadInclude' ,$i++. ' LoadInclude'); + $t->is( $methods[28] , 'LoadAllModelClasses',$i++. ' LoadAllModelClasses'); + $t->is( $methods[29] , 'LoadAllPluginModelClasses',$i++. ' LoadAllPluginModelClasses'); + $t->is( $methods[30] , 'LoadTemplate' ,$i++. ' LoadTemplate'); + $t->is( $methods[31] , 'LoadClassRBAC' ,$i++. ' LoadClassRBAC'); + $t->is( $methods[32] , 'LoadClass' ,$i++. ' LoadClass'); + $t->is( $methods[33] , 'LoadThirdParty' ,$i++. ' LoadThirdParty'); + $t->is( $methods[34] , 'encryptlink' ,$i++. ' encryptlink'); + $t->is( $methods[35] , 'parseURI' ,$i++. ' parseURI'); + $t->is( $methods[36] , 'streamFile' ,$i++. ' streamFile'); + $t->is( $methods[37] , 'trimSourceCodeFile' ,$i++. ' trimSourceCodeFile'); + $t->is( $methods[38] , 'sendHeaders' ,$i++. ' sendHeaders'); + $t->is( $methods[39] , 'virtualURI' ,$i++. ' virtualURI'); + $t->is( $methods[40] , 'createUID' ,$i++. ' createUID'); + $t->is( $methods[41] , 'getUIDName' ,$i++. ' getUIDName'); + $t->is( $methods[42] , 'formatNumber' ,$i++. ' formatNumber'); + $t->is( $methods[43] , 'formatDate' ,$i++. ' formatDate'); + $t->is( $methods[44] , 'getformatedDate' ,$i++. ' getformatedDate'); + $t->is( $methods[45] , 'arrayDiff' ,$i++. ' arrayDiff'); + $t->is( $methods[46] , 'complete_field' ,$i++. ' complete_field'); + $t->is( $methods[47] , 'sqlEscape' ,$i++. ' sqlEscape'); + $t->is( $methods[48] , 'replaceDataField' ,$i++. ' replaceDataField'); + $t->can_ok( $obj, 'replaceDataField', 'replaceDataField()'); + $t->todo( 'improve the function replaceDataField !!'); + $t->is( $methods[49] , 'loadLanguageFile' ,$i++. ' loadLanguageFile'); + $t->can_ok( $obj, 'loadLanguageFile', 'loadLanguageFile()'); + $t->todo( 'more tests with the function loadLanguageFile !!'); + $t->is( $methods[50] , 'registerLabel' ,$i++. ' registerLabel'); + $t->can_ok( $obj, 'registerLabel', 'registerLabel()'); + $t->todo( 'more tests with the function registerLabel !!'); + $t->is( $methods[51] , 'LoadMenuXml' ,$i++. ' LoadMenuXml'); + $t->can_ok( $obj, 'LoadMenuXml', 'LoadMenuXml()'); + $t->todo( 'more tests with the function LoadMenuXml !!'); + $t->is( $methods[52] , 'SendMessageXml' ,$i++. ' SendMessageXml'); + $t->can_ok( $obj, 'SendMessageXml', 'SendMessageXml()'); + $t->todo( 'more tests with the function SendMessageXml !!'); + $t->is( $methods[53] , 'SendTemporalMessage',$i++. ' SendTemporalMessage'); + $t->is( $methods[54] , 'SendMessage' ,$i++. ' SendMessage'); + $t->can_ok( $obj, 'SendTemporalMessage', 'SendTemporalMessage()'); + $t->todo( 'more tests with the function SendTemporalMessage !!'); + $t->can_ok( $obj, 'SendMessage', 'SendMessage()'); + $t->todo( 'more tests with the function SendMessage !!'); + $t->is( $methods[55] , 'SendMessageText' ,$i++. ' SendMessageText'); + $t->is( $methods[56] , 'LoadMessage' ,$i++. ' LoadMessage'); + $t->can_ok( $obj, 'LoadMessage', 'LoadMessage()'); + $t->todo( 'more tests with the function LoadMessage !!'); + $t->is( $methods[57] , 'LoadXmlLabel' ,$i++. ' LoadXmlLabel'); + $t->can_ok( $obj, 'LoadXmlLabel', 'LoadXmlLabel()'); + $t->todo( 'is useful the function LoadXmlLabel ??? delete it!!'); + $t->is( $methods[58] , 'LoadMessageXml' ,$i++. ' LoadMessageXml'); + $t->can_ok( $obj, 'LoadMessageXml', 'LoadMessageXml()'); + $t->todo( 'more tests with the function LoadMessageXml !!'); + $t->is( $methods[59] , 'LoadTranslationObject',$i++. ' LoadTranslationObject'); + $t->can_ok( $obj, 'LoadTranslation', 'LoadTranslation()'); + $t->todo( 'more tests with the function LoadTranslation !!'); + $t->is( $methods[60] , 'LoadTranslation' ,$i++. ' LoadTranslation'); + $t->is( $methods[61] , 'LoadArrayFile' ,$i++. ' LoadArrayFile'); + $t->can_ok( $obj, 'LoadArrayFile', 'LoadArrayFile()'); + $t->todo( 'more tests with the function LoadArrayFile !!'); + $t->is( $methods[62] , 'expandUri' ,$i++. ' expandUri'); + $t->can_ok( $obj, 'expandUri', 'expandUri()'); + $t->todo( 'more tests with the function expandUri !!'); + $t->is( $methods[63] , 'genericForceLogin' ,$i++. ' genericForceLogin'); + $t->can_ok( $obj, 'genericForceLogin', 'genericForceLogin()'); + $t->todo( 'more tests with the function genericForceLogin !!'); + $t->is( $methods[64] , 'capitalize' ,$i++. ' capitalize'); + $t->is( $methods[65] , 'toUpper' ,$i++. ' toUpper'); + $t->is( $methods[66] , 'toLower' ,$i++. ' toLower'); + $t->is( $methods[67] , 'http_build_query' ,$i++. ' http_build_query'); + $t->is( $methods[68] , 'header' ,$i++. ' header'); + $t->can_ok( $obj, 'http_build_query', 'http_build_query()'); + $t->todo( 'more tests with the function http_build_query !!'); + $t->can_ok( $obj, 'header', 'header()'); + $t->todo( 'more tests with the function header !!'); + $t->is( $methods[69] , 'forceLogin' ,$i++. ' forceLogin'); + $t->can_ok( $obj, 'forceLogin', 'forceLogin()'); + $t->todo( 'more tests with the function forceLogin , DELETE IT!!'); + $t->is( $methods[70] , 'add_slashes' ,$i++. ' add_slashes'); + $t->can_ok( $obj, 'add_slashes', 'add_slashes()'); + $t->todo( 'more tests with the function add_slashes !!'); + $t->is( $methods[71] , 'uploadFile' ,$i++. ' uploadFile'); + $t->can_ok( $obj, 'uploadFile', 'uploadFile()'); + $t->todo( 'more tests with the function uploadFile !!'); + $t->is( $methods[72] , 'resizeImage' ,$i++. ' resizeImage'); + $t->is( $methods[73] , 'array_merges' ,$i++. ' array_merges'); + $t->can_ok( $obj, 'array_merges', 'array_merges()'); + $t->todo( 'more tests with the function array_merges !!'); + $t->is( $methods[74] , 'array_merge_2' ,$i++. ' array_merge_2'); + $t->can_ok( $obj, 'array_merge_2', 'array_merge_2()'); + $t->todo( 'more tests with the function array_merge_2 !!'); + $t->is( $methods[75] , 'generateUniqueID' ,$i++. ' generateUniqueID'); + $t->can_ok( $obj, 'generateUniqueID', 'generateUniqueID()'); + $t->todo( 'more tests with the function sqlEscape !! is useful? delete it !!'); + $t->can_ok( $obj, 'generateUniqueID', 'generateUniqueID()'); + $t->todo( 'more tests with the function sqlEscape !! is useful? delete it !!'); + $t->is( $methods[76] , 'generateCode' ,$i++. ' generateCode'); + $t->is( $methods[77] , 'verifyUniqueID' ,$i++. ' verifyUniqueID'); + $t->is( $methods[78] , 'is_utf8' ,$i++. ' is_utf8'); + $t->is( $methods[79] , 'CurDate' ,$i++. ' CurDate'); + $t->can_ok( $obj, 'CurDate', 'CurDate()'); + $t->todo( 'more tests with the function sqlEscape !!'); + $t->is( $methods[80] , 'getSystemConstants',$i++. ' getSystemConstants'); + $t->is( $methods[81] , 'capitalizeWords' ,$i++. ' capitalizeWords'); + $t->is( $methods[82] , 'unhtmlentities' ,$i++. ' unhtmlentities'); + $t->is( $methods[83] , 'xmlParser' ,$i++. ' xmlParser'); + $t->is( $methods[84] , '_del_p' ,$i++. ' _del_p'); + $t->is( $methods[85] , 'ary2xml' ,$i++. ' ary2xml'); + $t->is( $methods[86] , 'ins2ary' ,$i++. ' ins2ary'); + $t->is( $methods[87] , 'evalJScript' ,$i++. ' evalJScript'); + $t->is( $methods[88] , 'inflect' ,$i++. ' inflect'); + $t->is( $methods[89] , 'pr' ,$i++. ' pr'); + $t->is( $methods[90] , 'dump' ,$i++. ' dump'); + $t->is( $methods[91] , 'stripCDATA' ,$i++. ' stripCDATA'); + $t->is( $methods[92] , 'getSysTemDir' ,$i++. ' getSysTemDir'); + $t->is( $methods[93] , 'PMWSCompositeResponse' ,$i++. ' PMWSCompositeResponse'); + $t->is( $methods[94] , 'emailAddress' ,$i++. ' emailAddress'); + $t->is( count( $methods ) , --$i , count( $methods ).' = '.$i.' ok'); + $t->todo( 'review all pendings in this class'); + \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classHeadPublisherTest.php b/workflow/engine/test/unit/gulliver/classHeadPublisherTest.php new file mode 100644 index 000000000..f4346391c --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classHeadPublisherTest.php @@ -0,0 +1,73 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'headPublisher'); + $counter=1; + $t = new lime_test( 13 , new lime_output_color()); + + $obj =& headPublisher::getSingleton(); + + $method = array ( ); + $testItems = 0; + $methods = get_class_methods('headPublisher'); + + $t->diag('class headPublisher' ); + $t->is( 10 ,count($methods) , "class headPublisher " . count($methods) . " methods." ); + $t->isa_ok( $obj, 'headPublisher', $counter++.' class headPublisher created'); + $t->can_ok( $obj, 'getSingleton', $counter++.' getSingleton()'); + $t->can_ok( $obj, 'setTitle', $counter++.' setTitle()'); + $t->can_ok( $obj, 'addScriptFile', $counter++.' addScriptFile()'); + $t->can_ok( $obj, 'addInstanceModule',$counter++.' addInstanceModule()'); + $t->can_ok( $obj, 'addClassModule', $counter++.' addClassModule()'); + $t->can_ok( $obj, 'addScriptCode', $counter++.' addScriptCode()'); + $t->can_ok( $obj, 'printHeader', $counter++.' printHeader()'); + $t->can_ok( $obj, 'printRawHeader', $counter++.' printRawHeader()'); + $t->can_ok( $obj, 'clearScripts', $counter++.' clearScripts()'); + $t->is( count($methods) ,--$counter , " methods ". $counter." OK" ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classHtmlAreaTest.php b/workflow/engine/test/unit/gulliver/classHtmlAreaTest.php new file mode 100644 index 000000000..a23488463 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classHtmlAreaTest.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'htmlArea'); + $method = array ( ); + $method = get_class_methods('XmlForm_Field_HTML'); + $t = new lime_test( 3, new lime_output_color()); + $t->diag('class XmlForm_Field_HTML' ); + $t->is( count($method) , 18, "class XmlForm_Field_HTML " . count($method) . " methods." ); + $t->todo( 'seems this class is unused. Fatal error: Call to a member function findNode()'); + $t->todo( 'is this class an useful class, or we can delete it ???'); + \ No newline at end of file diff --git a/workflow/engine/test/unit/gulliver/classMailerTest.php b/workflow/engine/test/unit/gulliver/classMailerTest.php new file mode 100644 index 000000000..4104735e8 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classMailerTest.php @@ -0,0 +1,67 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'mailer'); + $obj = new mailer (); + $testItems = 0; + $method = get_class_methods('mailer'); + $t = new lime_test(11, new lime_output_color()); + $t->diag('class mailer' ); + $t->is( count($method) , 7, "class mailer " . count($method) . " methods." ); + $t->isa_ok( $obj , 'mailer', 'class mailer created'); + $t->can_ok( $obj, 'instanceMailer', 'instanceMailer()'); + $t->can_ok( $obj, 'arpaEMAIL', 'arpaEMAIL()'); + $t->can_ok( $obj, 'sendTemplate', 'sendTemplate()'); + $t->can_ok( $obj, 'sendHtml', 'sendHtml()'); + $t->can_ok( $obj, 'sendText', 'sendText()'); + $t->can_ok( $obj, 'replaceFields', 'replaceFields()'); + $t->can_ok( $obj, 'html2text', 'html2text()'); + $t->todo( 'delete function html2text !!!'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classMenuTest.php b/workflow/engine/test/unit/gulliver/classMenuTest.php new file mode 100644 index 000000000..6e5ff9d17 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classMenuTest.php @@ -0,0 +1,72 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'menu'); + + $obj = new Menu (); + $counter=1; + $method = get_class_methods('Menu');print_r($class_methods); + $t = new lime_test(15, new lime_output_color()); + $t->diag('class Menu' ); + $t->is( count($method) , 11, "class Menu " . count($method) . " methods." ); + $t->isa_ok( $obj , 'Menu', 'class Menu created'); + $t->can_ok( $obj, 'SetClass' , $counter++.' SetClass()'); + $t->can_ok( $obj, 'Load' , $counter++.' Load()'); + $t->can_ok( $obj, 'OptionCount' , $counter++.' OptionCount()'); + $t->can_ok( $obj, 'AddOption' , $counter++.' AddOption()'); + $t->can_ok( $obj, 'AddIdOption' , $counter++.' AddIdOption()'); + $t->can_ok( $obj, 'AddRawOption' , $counter++.' AddRawOption()'); + $t->can_ok( $obj, 'AddIdRawOption' , $counter++.' AddIdRawOption()'); + $t->can_ok( $obj, 'DisableOptionPos', $counter++.' DisableOptionPos()'); + $t->can_ok( $obj, 'DisableOptionId' , $counter++.' DisableOptionId()'); + $t->can_ok( $obj, 'RenderOption' , $counter++.' RenderOption()'); + $t->can_ok( $obj, 'generateArrayForTemplate', $counter++.' generateArrayForTemplate()'); + $t->is( count($method) , --$counter , " methods " ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classObjectTemplateTest.php b/workflow/engine/test/unit/gulliver/classObjectTemplateTest.php new file mode 100644 index 000000000..4469d19fe --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classObjectTemplateTest.php @@ -0,0 +1,58 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'objectTemplate'); + + $obj = new objectTemplate ( ''); + $method = get_class_methods('objectTemplate'); + $t = new lime_test( 4, new lime_output_color()); + $t->diag('class objectTemplate' ); + $t->is( count($method ) , 60, "class objectTemplate " . count($method ) . " methods." ); + $t->isa_ok( $obj , 'objectTemplate', 'class objectTemplate created'); + $t->can_ok( $obj, 'printObject', 'printObject()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classPagedTableTest.php b/workflow/engine/test/unit/gulliver/classPagedTableTest.php new file mode 100644 index 000000000..690ae0030 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classPagedTableTest.php @@ -0,0 +1,44 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'pagedTable'); + + $t = new lime_test( 2, new lime_output_color()); + $obj = "pagedTable"; + $method = array ( ); + $testItems = 0; + $method = get_class_methods('pagedTable'); + $t->diag('class pagedTable' ); + $t->is( count($method) , 10, "class pagedTable " . $testItems . " methods." ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classPublisherTest.php b/workflow/engine/test/unit/gulliver/classPublisherTest.php new file mode 100644 index 000000000..4da9a5b41 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classPublisherTest.php @@ -0,0 +1,63 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'publisher'); + $method = array ( ); + $testItems = 0; + $method = get_class_methods('publisher'); + $t = new lime_test( 6, new lime_output_color()); + $obj = new Publisher ( 'field' ); + $t->diag('class Publisher' ); + $t->is( count($method) , 3, "class publisher " . count($method) . " methods." ); + $t->isa_ok( $obj , 'Publisher' , 'class Publisher created'); + $t->can_ok( $obj , 'AddContent' , 'AddContent()'); + $t->can_ok( $obj , 'RenderContent' , 'RenderContent()'); + $t->can_ok( $obj , 'RenderContent0', 'RenderContent0()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classRbacTest.php b/workflow/engine/test/unit/gulliver/classRbacTest.php new file mode 100644 index 000000000..78893b422 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classRbacTest.php @@ -0,0 +1,66 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'rbac'); + + $method = array ( ); + $method = get_class_methods('RBAC'); + $t = new lime_test( 8, new lime_output_color()); + $obj =& RBAC::getSingleton(); + $t->diag('class RBAC' ); + $t->is( count($method), 46, "class RBAC " . count($method) . " methods." ); + $t->isa_ok( $obj, 'RBAC', 'class RBAC created'); + $t->can_ok( $obj, 'VerifyLogin', 'VerifyLogin()'); + $t->can_ok( $obj, 'userCanAccess', 'userCanAccess()'); + $t->can_ok( $obj, 'load', 'load()'); + $t->can_ok( $obj, 'createUser', 'createUser()'); + $t->can_ok( $obj, 'listAllRoles', 'listAllRoles()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classTableTest.php b/workflow/engine/test/unit/gulliver/classTableTest.php new file mode 100644 index 000000000..6f93b8f5d --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classTableTest.php @@ -0,0 +1,81 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + +G::LoadThirdParty('pear/json','class.json'); +G::LoadThirdParty('smarty/libs','Smarty.class'); +G::LoadSystem ( 'xmlform'); +G::LoadSystem ( 'xmlDocument'); +G::LoadSystem ( 'form'); +G::LoadSystem ( 'table'); + +$t = new lime_test(24, new lime_output_color()); +$obj = new Table(); +$method = get_class_methods('Table'); +$t->diag('class Table' ); +$t->is( count($method) , 23, "class Table " . count($method). " methods." ); +$t->isa_ok( $obj, 'Table', 'class Table created'); +$t->can_ok( $obj, 'SetTo', 'SetTo()'); +$t->can_ok( $obj, 'SetSource', 'SetSource()'); +$t->can_ok( $obj, 'GetSource', 'GetSource()'); +$t->can_ok( $obj, 'TotalCount', 'TotalCount()'); +$t->can_ok( $obj, 'Count', 'Count()'); +$t->can_ok( $obj, 'CurRow', 'CurRow()'); +$t->can_ok( $obj, 'ColumnCount', 'ColumnCount()'); +$t->can_ok( $obj, 'Read', 'Read()'); +$t->can_ok( $obj, 'Seek', 'Seek()'); +$t->can_ok( $obj, 'MoveFirst', 'MoveFirst()'); +$t->can_ok( $obj, 'EOF', 'EOF()'); +$t->can_ok( $obj, 'AddColumn', 'AddColumn()'); +$t->can_ok( $obj, 'AddRawColumn', 'AddRawColumn()'); +$t->can_ok( $obj, 'RenderTitle_ajax', 'RenderTitle_ajax()'); +$t->can_ok( $obj, 'RenderTitle2', 'RenderTitle2()'); +$t->can_ok( $obj, 'RenderColumn', 'RenderColumn()'); +$t->can_ok( $obj, 'SetAction', 'SetAction()'); +$t->can_ok( $obj, 'setTranslate', 'setTranslate()'); +$t->can_ok( $obj, 'translateValue', 'translateValue()'); +$t->can_ok( $obj, 'setContext', 'setContext()'); +$t->can_ok( $obj, 'ParsingFromHtml', 'ParsingFromHtml()'); + +$t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classTemplatePowerTest.php b/workflow/engine/test/unit/gulliver/classTemplatePowerTest.php new file mode 100644 index 000000000..30fb59c5e --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classTemplatePowerTest.php @@ -0,0 +1,77 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'templatePower'); + $t = new lime_test(16, new lime_output_color()); + $obj = new TemplatePowerParser( 'a', 'b' ); + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('TemplatePowerParser'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class TemplatePowerParser' ); + $t->is( $testItems , 8, "class TemplatePowerParser " . $testItems . " methods." ); + $t->isa_ok( $obj , 'TemplatePowerParser', 'class TemplatePowerParser created'); + $t->can_ok( $obj, '__prepare', '__prepare()'); + $t->can_ok( $obj, '__prepareTemplate', '__prepareTemplate()'); + $t->can_ok( $obj, '__parseTemplate', '__parseTemplate()'); + $obj = new TemplatePower( ); + $t->can_ok( $obj, '__outputContent', '__outputContent()'); + $t->can_ok( $obj, '__printVars', '__printVars()'); + $t->can_ok( $obj, 'prepare', 'prepare()'); + $t->can_ok( $obj, 'newBlock', 'newBlock()'); + $t->can_ok( $obj, 'assignGlobal', 'assignGlobal()'); + $t->can_ok( $obj, 'assign', 'assign()'); + $t->can_ok( $obj, 'gotoBlock', 'gotoBlock()'); + $t->can_ok( $obj, 'getVarValue', 'getVarValue()'); + $t->can_ok( $obj, 'printToScreen', 'printToScreen()'); + $t->can_ok( $obj, 'getOutputContent', 'getOutputContent()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classTestToolsTest.php b/workflow/engine/test/unit/gulliver/classTestToolsTest.php new file mode 100644 index 000000000..08be0c545 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classTestToolsTest.php @@ -0,0 +1,42 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'testTools'); + + $t = new lime_test( 2, new lime_output_color()); + $obj = "testTools"; + $method = get_class_methods('testTools'); + $t->diag('class testTools' ); + $t->is( count($method) , 7, "class testTools " . count($method) . " methods." ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classTreeTest.php b/workflow/engine/test/unit/gulliver/classTreeTest.php new file mode 100644 index 000000000..157db3667 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classTreeTest.php @@ -0,0 +1,67 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'tree'); + $t = new lime_test(7, new lime_output_color()); + $obj = new Tree( array ('name' => 'value' ) ); + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('Tree'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class Tree' ); + $t->is( $testItems , 14, "class Tree " . $testItems . " methods." ); + $t->isa_ok( $obj , 'Tree', 'class Tree created'); + $t->can_ok( $obj, 'addChild', 'addChild()'); + $t->can_ok( $obj, 'printPlus', 'printPlus()'); + $t->can_ok( $obj, 'printContent', 'printContent()'); + $t->can_ok( $obj, 'render', 'render()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classWebResourceTest.php b/workflow/engine/test/unit/gulliver/classWebResourceTest.php new file mode 100644 index 000000000..c45361d2d --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classWebResourceTest.php @@ -0,0 +1,48 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'webResource'); + + $t = new lime_test( 2, new lime_output_color()); + $obj = "WebResource"; + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('WebResource'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class WebResource' ); + $t->is( $testItems , 2, "class WebResource " . $testItems . " methods." ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classXmlDocumentTest.php b/workflow/engine/test/unit/gulliver/classXmlDocumentTest.php new file mode 100644 index 000000000..3947a01f7 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classXmlDocumentTest.php @@ -0,0 +1,74 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'xmlDocument'); + $t = new lime_test(11, new lime_output_color()); + $obj = new Xml_Node( 'name', 'type', 'value' ); + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('Xml_Node'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class Xml_Node' ); + $t->is( $testItems , 8, "class Xml_Node " . $testItems . " methods." ); + + $t->isa_ok( $obj , 'Xml_Node' , 'class Xml_Node created'); + $t->can_ok( $obj , 'addAttribute', 'addAttribute()'); + $t->can_ok( $obj , 'addChildNode', 'addChildNode()'); + $t->can_ok( $obj , 'toTree' , 'toTree()'); + $t->can_ok( $obj , 'findNode' , 'findNode()'); + $t->can_ok( $obj , 'getXML' , 'getXML()'); + $obj = new Xml_document( 'name', 'type', 'value' ); + $t->diag('class Xml_document' ); + $t->isa_ok( $obj , 'Xml_document', 'class Xml_document created'); + $t->can_ok( $obj , 'parseXmlFile', 'parseXmlFile()'); + $t->can_ok( $obj , 'getXML' , 'getXML()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classXmlMenuTest.php b/workflow/engine/test/unit/gulliver/classXmlMenuTest.php new file mode 100644 index 000000000..90f4e174f --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classXmlMenuTest.php @@ -0,0 +1,65 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + require_once( PATH_CORE . 'config' . PATH_SEP . 'environments.php'); + + global $G_ENVIRONMENTS; + if ( isset ( $G_ENVIRONMENTS ) ) { + $dbfile = $G_ENVIRONMENTS[ G_TEST_ENV ][ 'dbfile']; + if ( !file_exists ( $dbfile ) ) { + printf("%s \n", pakeColor::colorize( "dbfile $dbfile doesn't exist for environment " . G_ENVIRONMENT , 'ERROR')); + exit (200); + } + else + include ( $dbfile ); + } + else + exit (201); + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'xmlMenu'); + $t = new lime_test(4, new lime_output_color()); + $obj = new xmlMenu( 'login/login' ); + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('xmlMenu'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class xmlMenu' ); + $t->is( $testItems , 12, "class xmlMenu " . $testItems . " methods." ); + $t->isa_ok( $obj , 'xmlMenu', 'class xmlMenu created'); + $t->can_ok( $obj, 'render', 'render()'); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/gulliver/classXmlformExtensionTest.php b/workflow/engine/test/unit/gulliver/classXmlformExtensionTest.php new file mode 100644 index 000000000..fc265e2b7 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classXmlformExtensionTest.php @@ -0,0 +1,49 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'xmlformExtension'); + + $t = new lime_test( 2, new lime_output_color()); + $obj ="database_base"; + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('XmlForm_Field_Label'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class XmlForm_Field_Label' ); + $t->is( $testItems , 18, "class XmlForm_Field_Label " . $testItems . " methods." ); + $t->todo( 'review all pendings in this class'); + diff --git a/workflow/engine/test/unit/gulliver/classXmlformTest.php b/workflow/engine/test/unit/gulliver/classXmlformTest.php new file mode 100644 index 000000000..d692e4132 --- /dev/null +++ b/workflow/engine/test/unit/gulliver/classXmlformTest.php @@ -0,0 +1,46 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . 'lime/lime.php'); + define ( 'G_ENVIRONMENT', G_TEST_ENV); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'xmlform'); + $t = new lime_test( 2, new lime_output_color()); + $obj = "XmlForm_Field"; + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods('XmlForm_Field'); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + $t->diag('class XmlForm_Field' ); + $t->is( $testItems , 18, "class XmlForm_Field " . $testItems . " methods." ); + $t->todo( 'review all pendings in this class'); diff --git a/workflow/engine/test/unit/processmaker/classAppDelegationTest.php b/workflow/engine/test/unit/processmaker/classAppDelegationTest.php new file mode 100644 index 000000000..d7dd2cc4d --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classAppDelegationTest.php @@ -0,0 +1,92 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadSystem ( 'testTools'); + G::LoadClass ( 'appDelegation'); + require_once(PATH_CORE.'/classes/model/AppDelegation.php'); + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $obj = new AppDelegation ($dbc); + $t = new lime_test( 1, new lime_output_color() ); + $t->diag('class AppDelegation' ); + $t->isa_ok( $obj , 'AppDelegation', 'class AppDelegation created'); + class AppDel extends unitTest + { + function CreateEmptyAppDelegation($data,$fields) + { + $obj=new AppDelegation(); + $res=$obj->createAppDelegation($fields); + return $res; + } + function CreateDuplicated($data,$fields) + { + $obj1=new AppDelegation(); + $res=$obj1->createAppDelegation($fields); + $this->domain->addDomainValue('createdAppDel',serialize($fields)); + $obj2=new AppDelegation(); + $res=$obj2->createAppDelegation($fields); + $this->domain->addDomainValue(serialize($fields)); + return $res; + } + function CreateNewAppDelegation($data,$fields) + { + $obj=new AppDelegation(); + $res=$obj->createAppDelegation($fields); + $this->domain->addDomainValue('createdAppDel',serialize($fields)); + return $res; + } + function DeleteAppDelegation($data,$fields) + { + $obj=new AppDelegation(); + $fields=unserialize($fields['Fields']); + $obj->setAppUid($fields['APP_UID']); + $obj->setDelIndex($fields['DEL_INDEX']); + $res=$obj->delete(); + return $res; + } + } + $tt=new AppDel('appDelegation.yml',$t,$domain); + $domain->addDomain("createdAppDel"); + $tt->load('CreateDelApplication'); + $tt->runAll(); + $tt->load('DeleteCretedAppDelegations'); + $tt->runAll(); + +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classAppDocumentTest.php b/workflow/engine/test/unit/processmaker/classAppDocumentTest.php new file mode 100644 index 000000000..dc37d77b2 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classAppDocumentTest.php @@ -0,0 +1,153 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once(PATH_THIRDPARTY . '/lime/lime.php'); + require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + + require_once(PATH_CORE . 'config/databases.php'); + require_once('propel/Propel.php'); + Propel::init(PATH_CORE . 'config/databases.php'); + + G::LoadThirdParty('smarty/libs', 'Smarty.class'); + G::LoadSystem('error'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('form'); + G::LoadSystem('dbtable'); + G::LoadSystem('testTools'); + require_once(PATH_CORE . 'classes/model/AppDocument.php'); + + $obj = new AppDocument(); + $t = new lime_test(19, new lime_output_color()); + + $t->diag('Class AppDocument'); + + //class AppDocument + $t->isa_ok($obj, 'AppDocument', 'Class AppDocument created!'); + + //method load + $t->can_ok($obj, 'load', 'load() is callable!'); + + //method create + $t->can_ok($obj, 'create', 'create() is callable!'); + + //method update + $t->can_ok($obj, 'update', 'update() is callable!'); + + //method remove + $t->can_ok($obj, 'remove', 'remove() is callable!'); + + //method getAppDocTitle + $t->can_ok($obj, 'getAppDocTitle', 'getAppDocTitle() is callable!'); + + //method setAppDocTitle + $t->can_ok($obj, 'setAppDocTitle', 'setAppDocTitle() is callable!'); + + //method getAppDocComment + $t->can_ok($obj, 'getAppDocComment', 'getAppDocComment() is callable!'); + + //method setAppDocComment + $t->can_ok($obj, 'setAppDocComment', 'setAppDocComment() is callable!'); + + //method getAppDocFilename + $t->can_ok($obj, 'getAppDocFilename', 'getAppDocFilename() is callable!'); + + //method setAppDocFilename + $t->can_ok($obj, 'setAppDocFilename', 'setAppDocFilename() is callable!'); + /***** TEST CLASS APPDOCUMENT *****/ + ///////// INITIAL VALUES ///////// + define('SYS_LANG', 'en'); + //Test class + class appDocumentTest extends unitTest + { + function loadTest($aTestData, $aFields) + { + $oAppDocument = new AppDocument(); + try { + return $oAppDocument->load($aFields['APP_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createTest($aTestData, $aFields) + { + $oAppDocument = new AppDocument(); + try { + return $oAppDocument->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTest($aTestData, $aFields) + { + $oAppDocument = new AppDocument(); + try { + return $oAppDocument->update($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oAppDocument = new AppDocument(); + try { + return $oAppDocument->remove($aFields['APP_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + } + //Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) + $oAppDocumentTest = new appDocumentTest('appDocument.yml', $t, new ymlDomain()); + $oAppDocumentTest->load('load1'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('load2'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('create1'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('create2'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('update1'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('update2'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('remove1'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oAppDocumentTest->load('remove2'); + $vAux = $oAppDocumentTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + ?> diff --git a/workflow/engine/test/unit/processmaker/classApplicationTest.php b/workflow/engine/test/unit/processmaker/classApplicationTest.php new file mode 100644 index 000000000..eb739ea8f --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classApplicationTest.php @@ -0,0 +1,217 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + Propel::init( PATH_CORE . "config/databases.php"); + + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'testTools'); + + require_once( PATH_CORE.'/classes/model/Application.php'); + + $obj = new Application (); + $t = new lime_test( 23, new lime_output_color() ); + + $t->diag('class Application' ); + $t->isa_ok( $obj , 'Application', 'class Application created'); + + //method load + //#2 + $t->can_ok( $obj, 'getAppTitle', 'getAppTitle() is callable' ); + //#3 + $t->can_ok( $obj, 'setAppTitle', 'setAppTitle() is callable' ); + //#4 + $t->can_ok( $obj, 'create', 'create() is callable' ); + //#5 + $t->can_ok( $obj, 'update', 'update() is callable' ); + //#6 + $t->can_ok( $obj, 'load', 'load() is callable' ); + //#7 + $t->can_ok( $obj, 'remove', 'remove() is callable' ); + //#8 + $t->can_ok( $obj, 'createApplication', 'createApplication() is callable' ); + + //getAppUid + //#9 + $t->is( $obj->getAppUid(), '', 'getAppUid() return empty, when the instance doesnt have any row' ); + + //getAppTitle + try { + $obj = new Application (); + $res = $obj->getAppTitle(); + } + catch ( Exception $e ) { + //#10 + $t->isa_ok( $e, 'Exception', 'getAppTitle() return error when APP_UID is not defined' ); + //#11 + $t->is ( $e->getMessage(), "Error in getAppTitle, the APP_UID can't be blank", 'getAppTitle() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //setAppTitle + try { + $obj = new Application (); + $obj->setAppTitle('x'); + } + catch ( Exception $e ) { + //#12 + $t->isa_ok( $e, 'Exception', 'setAppTitle() return error when APP_UID is not defined' ); + //#13 + $t->is ( $e->getMessage(), "Error in setAppTitle, the APP_UID can't be blank", 'setAppTitle() return Error in getAppTitle, the APP_UID cant be blank' ); + } + //create + try { + $obj = new Application (); + $res = $obj->create(); + } + catch ( Exception $e ) { + //#14 + $t->isa_ok( $e, 'PropelException', 'create() return error when APP_UID is not defined' ); + //#15 + $t->like ( $e->getMessage(), "%Unable to execute INSERT statement%", 'getAppTitle() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //create + try { + $obj = new Application (); + $appUid = $obj->create( '1' ); + //#16 + $t->isa_ok( $appUid, 'string', 'create(), creates a new application' ); + //#17 + $t->is ( strlen($appUid), 14, 'create(), creates a new application, Guid lenth=14 chars' ); + $res = $obj->load( $appUid ); + //#18 + $t->isa_ok( $res, 'array', 'load(), loads a new application' ); + //#19 + $t->is ( $res['APP_UID'], $appUid, 'load(), loads a new application, valid APP_UID' ); + //#20 + $t->is ( $res['APP_FINISH_DATE'],'1902-01-01 00:00:00', 'load(), loads a new application, valid FINISH_DATE' ); + //#21 + $t->like ( $res['APP_TITLE'], '%#%', 'load(), loads a new application, valid APP_TITLE' ); + //#22 + $t->is ( $res['APP_PARENT'], '', 'load(), loads a new application, valid APP_PARENT' ); + + } + catch ( Exception $e ) { + $t->like ( $e->getMessage(), "%Unable to execute INSERT statement%", 'create() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //update with empty + try { + $obj = new Application (); + $res = $obj->update( NULL ); + } + catch ( Exception $e ) { + //#23 + $t->isa_ok( $e, 'Exception', 'update() returns error when APP_UID is not defined' ); + //#24 + + $t->is ( $e->getMessage(), "The row '' in table APPLICATION doesn't exist!", "update() This row doesn't exist!" ); + + } + + //update with $fields + $newTitle = 'new title'; + $Fields['APP_UID'] = $appUid; + $Fields['APP_TITLE'] = $newTitle; + $Fields['APP_PARENT'] = rand( 1000, 5000); + $Fields['APP_INIT_DATE'] = 'now'; + try { + $obj = new Application (); + $res = $obj->update( $Fields); + //#25 + $t->is ( $res, 1, "update() update 1 row" ); + $Fields = $obj->Load ( $appUid ); + //#26 + $t->is ( $obj->getAppUid(), $appUid, "update() APP_UID = ". $appUid ); + //#27 + $t->is ( $obj->getAppTitle(), $newTitle, "update() getAppTitle" ); + //#28 + $t->is ( $Fields['APP_TITLE'], $newTitle, "update() APP_TITLE= ". $newTitle ); + //#29 + $t->is ( $Fields['APP_INIT_DATE'], date('Y-m-d H:i:s'), "update() APP_INIT_DATE= ". date('Y-m-d H:i:s') ); + } + catch ( Exception $e ) { + //#14 + // $t->isa_ok( $e, 'PropelException', 'update() return error ' . $e->getMessage() ); + $t->isa_ok( $e, 'Exception', 'update() return error ' . $e->getMessage() ); + } + +//remove with empty + try { + $obj = new Application (); + $res = $obj->remove( NULL ); + } + catch ( Exception $e ) { + //#30 + $t->isa_ok( $e, 'Exception', 'remove() returns error when APP_UID is not defined' ); + //#31 + $t->is ( $e->getMessage(), "The row '' in table Application doesn't exist!", "remove() This row doesn't exist!" ); + } +/* + //remove with $fields + $Fields['APP_UID'] = $appUid; + try { + $obj = new Application (); + //$res = $obj->remove( $Fields ); + $t->todo ( "check why this sentence is not working : $res = $obj->remove( $Fields ); " ); + + //#32 + $t->is ( $res, NULL, "remove() remove row $appUid" ); + } + catch ( Exception $e ) { + //#14 + // $t->isa_ok( $e, 'PropelException', 'remove() return error ' . $e->getMessage() ); + $t->isa_ok( $e, 'Exception', 'remove() return error ' . $e->getMessage() ); + } + + //remove with $appUid + $obj = new Application (); + $appUid = $obj->create( '1' ); + try { + $obj = new Application (); + //$res = $obj->remove ($appUid ); + //#33 + //$t->is ( $res, NULL, "remove() remove row $appUid" ); + } + catch ( Exception $e ) { + //#14 + $t->isa_ok( $e, 'PropelException', 'remove() return error ' . $e->getMessage() ); + } +*/ + + $t->todo( 'Test to verify if delete works correctly :p ...'); + $t->todo( 'how can I change dynamically the Case Title based in a definition, right now the case title is the same as the process title. We need another field in process to have the case title definition'); + +?> + diff --git a/workflow/engine/test/unit/processmaker/classArchiveTest.php b/workflow/engine/test/unit/processmaker/classArchiveTest.php new file mode 100644 index 000000000..4ce88bba1 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classArchiveTest.php @@ -0,0 +1,167 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'archive'); + + $obj = new Archive ($dbc); + $t = new lime_test( 27, new lime_output_color() ); + + $className = Archive; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag( "class $className " ); + $t->isa_ok( $obj , $className, "class $className created" ); + + $t->is( count($methods) , 12, "class $className have " . 12 . ' methods.' ); + + //checking method 'archive' + $t->can_ok( $obj, 'archive', 'archive() is callable' ); + + //$result = $obj->archive ( $name); + //$t->isa_ok( $result, 'NULL', 'call to method archive '); + $t->todo( "call to method archive using $name "); + + + //checking method 'set_options' + $t->can_ok( $obj, 'set_options', 'set_options() is callable' ); + + //$result = $obj->set_options ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method set_options '); + $t->todo( "call to method set_options using $options "); + + + //checking method 'create_archive' + $t->can_ok( $obj, 'create_archive', 'create_archive() is callable' ); + + //$result = $obj->create_archive ( ); + //$t->isa_ok( $result, 'NULL', 'call to method create_archive '); + $t->todo( "call to method create_archive using "); + + + //checking method 'add_data' + $t->can_ok( $obj, 'add_data', 'add_data() is callable' ); + + //$result = $obj->add_data ( $data); + //$t->isa_ok( $result, 'NULL', 'call to method add_data '); + $t->todo( "call to method add_data using $data "); + + + //checking method 'make_list' + $t->can_ok( $obj, 'make_list', 'make_list() is callable' ); + + //$result = $obj->make_list ( ); + //$t->isa_ok( $result, 'NULL', 'call to method make_list '); + $t->todo( "call to method make_list using "); + + + //checking method 'add_files' + $t->can_ok( $obj, 'add_files', 'add_files() is callable' ); + + //$result = $obj->add_files ( $list); + //$t->isa_ok( $result, 'NULL', 'call to method add_files '); + $t->todo( "call to method add_files using $list "); + + + //checking method 'exclude_files' + $t->can_ok( $obj, 'exclude_files', 'exclude_files() is callable' ); + + //$result = $obj->exclude_files ( $list); + //$t->isa_ok( $result, 'NULL', 'call to method exclude_files '); + $t->todo( "call to method exclude_files using $list "); + + + //checking method 'store_files' + $t->can_ok( $obj, 'store_files', 'store_files() is callable' ); + + //$result = $obj->store_files ( $list); + //$t->isa_ok( $result, 'NULL', 'call to method store_files '); + $t->todo( "call to method store_files using $list "); + + + //checking method 'list_files' + $t->can_ok( $obj, 'list_files', 'list_files() is callable' ); + + //$result = $obj->list_files ( $list); + //$t->isa_ok( $result, 'NULL', 'call to method list_files '); + $t->todo( "call to method list_files using $list "); + + + //checking method 'parse_dir' + $t->can_ok( $obj, 'parse_dir', 'parse_dir() is callable' ); + + //$result = $obj->parse_dir ( $dirname); + //$t->isa_ok( $result, 'NULL', 'call to method parse_dir '); + $t->todo( "call to method parse_dir using $dirname "); + + + //checking method 'sort_files' + $t->can_ok( $obj, 'sort_files', 'sort_files() is callable' ); + + //$result = $obj->sort_files ( $a, $b); + //$t->isa_ok( $result, 'NULL', 'call to method sort_files '); + $t->todo( "call to method sort_files using $a, $b "); + + + //checking method 'download_file' + $t->can_ok( $obj, 'download_file', 'download_file() is callable' ); + + //$result = $obj->download_file ( ); + //$t->isa_ok( $result, 'NULL', 'call to method download_file '); + $t->todo( "call to method download_file using "); + + $t->todo ( 'review all pendings methods in this class'); + + ?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classArrayBasePeerTest.php b/workflow/engine/test/unit/processmaker/classArrayBasePeerTest.php new file mode 100644 index 000000000..8e10d29c2 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classArrayBasePeerTest.php @@ -0,0 +1,229 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'ArrayPeer'); + + $t = new lime_test( 44, new lime_output_color() ); + $className = "ArrayBasePeer"; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + $t->diag("class $className" ); + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 21, "class $className have " . 21 . ' methods.' ); + $aMethods = array_keys ( $methods ); + + //checking method 'getMapBuilder' + $t->is ( $aMethods[0], 'getMapBuilder', 'getMapBuilder() is callable' ); + + //$result = $obj->getMapBuilder ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getMapBuilder '); + $t->todo( "call to method getMapBuilder using "); + + + //checking method 'getPhpNameMap' + $t->is ( $aMethods[1], 'getPhpNameMap', 'getPhpNameMap() is callable' ); + + //$result = $obj->getPhpNameMap ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getPhpNameMap '); + $t->todo( "call to method getPhpNameMap using "); + + //checking method 'translateFieldName' + $t->is ( $aMethods[2], 'translateFieldName', 'translateFieldName() is callable' ); + + //$result = $obj->translateFieldName ( $name, $fromType, $toType); + //$t->isa_ok( $result, 'NULL', 'call to method translateFieldName '); + $t->todo( "call to method translateFieldName using $name, $fromType, $toType "); + + + //checking method 'getFieldNames' + $t->is ( $aMethods[3], 'getFieldNames', 'getFieldNames() is callable' ); + + //$result = $obj->getFieldNames ( $type); + //$t->isa_ok( $result, 'NULL', 'call to method getFieldNames '); + $t->todo( "call to method getFieldNames using $type "); + + + //checking method 'alias' + $t->is ( $aMethods[4], 'alias', 'alias() is callable' ); + + //$result = $obj->alias ( $alias, $column); + //$t->isa_ok( $result, 'NULL', 'call to method alias '); + $t->todo( "call to method alias using $alias, $column "); + + //checking method 'addSelectColumns' + $t->is ( $aMethods[5], 'addSelectColumns', 'addSelectColumns() is callable' ); + + //$result = $obj->addSelectColumns ( $criteria); + //$t->isa_ok( $result, 'NULL', 'call to method addSelectColumns '); + $t->todo( "call to method addSelectColumns using $criteria "); + + + //checking method 'doCount' + $t->is ( $aMethods[6], 'doCount', 'doCount() is callable' ); + + //$result = $obj->doCount ( $criteria, $distinct, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doCount '); + $t->todo( "call to method doCount using $criteria, $distinct, $con "); + + + //checking method 'doSelectOne' + $t->is ( $aMethods[7], 'doSelectOne', 'doSelectOne() is callable' ); + + //$result = $obj->doSelectOne ( $criteria, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doSelectOne '); + $t->todo( "call to method doSelectOne using $criteria, $con "); + + + //checking method 'createSelectSql' + $t->is ( $aMethods[8], 'createSelectSql', 'createSelectSql() is callable' ); + + //$result = $obj->createSelectSql ( $criteria, $tableName, $params); + //$t->isa_ok( $result, 'NULL', 'call to method createSelectSql '); + $t->todo( "call to method createSelectSql using $criteria, $tableName, $params "); + + + //checking method 'doSelect' + $t->is ( $aMethods[9], 'doSelect', 'doSelect() is callable' ); + + //$result = $obj->doSelect ( $criteria, $tableName, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doSelect '); + $t->todo( "call to method doSelect using $criteria, $tableName, $con "); + + + //checking method 'doSelectRS' + $t->is ( $aMethods[10], 'doSelectRS', 'doSelectRS() is callable' ); + + //$result = $obj->doSelectRS ( $criteria, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doSelectRS '); + $t->todo( "call to method doSelectRS using $criteria, $con "); + + + //checking method 'populateObjects' + $t->is ( $aMethods[11], 'populateObjects', 'populateObjects() is callable' ); + + //$result = $obj->populateObjects ( $rs); + //$t->isa_ok( $result, 'NULL', 'call to method populateObjects '); + $t->todo( "call to method populateObjects using $rs "); + + + //checking method 'getTableMap' + $t->is ( $aMethods[12], 'getTableMap', 'getTableMap() is callable' ); + + //$result = $obj->getTableMap ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getTableMap '); + $t->todo( "call to method getTableMap using "); + + + //checking method 'getOMClass' + $t->is ( $aMethods[13], 'getOMClass', 'getOMClass() is callable' ); + + //$result = $obj->getOMClass ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getOMClass '); + $t->todo( "call to method getOMClass using "); + + + //checking method 'doInsert' + $t->is ( $aMethods[14], 'doInsert', 'doInsert() is callable' ); + + //$result = $obj->doInsert ( $values, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doInsert '); + $t->todo( "call to method doInsert using $values, $con "); + + + //checking method 'doUpdate' + $t->is ( $aMethods[15], 'doUpdate', 'doUpdate() is callable' ); + + //$result = $obj->doUpdate ( $values, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doUpdate '); + $t->todo( "call to method doUpdate using $values, $con "); + + + //checking method 'doDeleteAll' + $t->is ( $aMethods[16], 'doDeleteAll', 'doDeleteAll() is callable' ); + + //$result = $obj->doDeleteAll ( $con); + //$t->isa_ok( $result, 'NULL', 'call to method doDeleteAll '); + $t->todo( "call to method doDeleteAll using $con "); + + + //checking method 'doDelete' + $t->is ( $aMethods[17], 'doDelete', 'doDelete() is callable' ); + + //$result = $obj->doDelete ( $values, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doDelete '); + $t->todo( "call to method doDelete using $values, $con "); + + + //checking method 'doValidate' + $t->is ( $aMethods[18], 'doValidate', 'doValidate() is callable' ); + + //$result = $obj->doValidate ( $obj, $cols); + //$t->isa_ok( $result, 'NULL', 'call to method doValidate '); + $t->todo( "call to method doValidate using $obj, $cols "); + + + //checking method 'retrieveByPK' + $t->is ( $aMethods[19], 'retrieveByPK', 'retrieveByPK() is callable' ); + + //$result = $obj->retrieveByPK ( $pk, $con); + //$t->isa_ok( $result, 'NULL', 'call to method retrieveByPK '); + $t->todo( "call to method retrieveByPK using $pk, $con "); + + + //checking method 'retrieveByPKs' + $t->is ( $aMethods[20], 'retrieveByPKs', 'retrieveByPKs() is callable' ); + + //$result = $obj->retrieveByPKs ( $pks, $con); + //$t->isa_ok( $result, 'NULL', 'call to method retrieveByPKs '); + $t->todo( "call to method retrieveByPKs using $pks, $con "); + + + + $t->todo ( 'review all pendings methods in this class'); + diff --git a/workflow/engine/test/unit/processmaker/classBasePeerTest.php b/workflow/engine/test/unit/processmaker/classBasePeerTest.php new file mode 100644 index 000000000..659f2fd32 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classBasePeerTest.php @@ -0,0 +1,183 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'BasePeer'); + + + $obj = new BasePeer ($dbc); + $t = new lime_test( 31, new lime_output_color() ); + + $className = BasePeer; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 14, "class $className have " . 14 . ' methods.' ); + + //checking method 'getFieldnames' + $t->can_ok( $obj, 'getFieldnames', 'getFieldnames() is callable' ); + + //$result = $obj->getFieldnames ( $classname, $type); + //$t->isa_ok( $result, 'NULL', 'call to method getFieldnames '); + $t->todo( "call to method getFieldnames using $classname, $type "); + + + //checking method 'translateFieldname' + $t->can_ok( $obj, 'translateFieldname', 'translateFieldname() is callable' ); + + //$result = $obj->translateFieldname ( $classname, $fieldname, $fromType, $toType); + //$t->isa_ok( $result, 'NULL', 'call to method translateFieldname '); + $t->todo( "call to method translateFieldname using $classname, $fieldname, $fromType, $toType "); + + + //checking method 'doDelete' + $t->can_ok( $obj, 'doDelete', 'doDelete() is callable' ); + + //$result = $obj->doDelete ( $criteria, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doDelete '); + $t->todo( "call to method doDelete using $criteria, $con "); + + + //checking method 'doDeleteAll' + $t->can_ok( $obj, 'doDeleteAll', 'doDeleteAll() is callable' ); + + //$result = $obj->doDeleteAll ( $tableName, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doDeleteAll '); + $t->todo( "call to method doDeleteAll using $tableName, $con "); + + + //checking method 'doInsert' + $t->can_ok( $obj, 'doInsert', 'doInsert() is callable' ); + + //$result = $obj->doInsert ( $criteria, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doInsert '); + $t->todo( "call to method doInsert using $criteria, $con "); + + + //checking method 'doUpdate' + $t->can_ok( $obj, 'doUpdate', 'doUpdate() is callable' ); + + //$result = $obj->doUpdate ( $selectCriteria, $updateValues, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doUpdate '); + $t->todo( "call to method doUpdate using $selectCriteria, $updateValues, $con "); + + + //checking method 'doSelect' + $t->can_ok( $obj, 'doSelect', 'doSelect() is callable' ); + + //$result = $obj->doSelect ( $criteria, $con); + //$t->isa_ok( $result, 'NULL', 'call to method doSelect '); + $t->todo( "call to method doSelect using $criteria, $con "); + + + //checking method 'doValidate' + $t->can_ok( $obj, 'doValidate', 'doValidate() is callable' ); + + //$result = $obj->doValidate ( $dbName, $tableName, $columns); + //$t->isa_ok( $result, 'NULL', 'call to method doValidate '); + $t->todo( "call to method doValidate using $dbName, $tableName, $columns "); + + + //checking method 'getPrimaryKey' + $t->can_ok( $obj, 'getPrimaryKey', 'getPrimaryKey() is callable' ); + + //$result = $obj->getPrimaryKey ( $criteria); + //$t->isa_ok( $result, 'NULL', 'call to method getPrimaryKey '); + $t->todo( "call to method getPrimaryKey using $criteria "); + + + //checking method 'createSelectSql' + $t->can_ok( $obj, 'createSelectSql', 'createSelectSql() is callable' ); + + //$result = $obj->createSelectSql ( $criteria, $params); + //$t->isa_ok( $result, 'NULL', 'call to method createSelectSql '); + $t->todo( "call to method createSelectSql using $criteria, $params "); + + + //checking method 'buildParams' + $t->can_ok( $obj, 'buildParams', 'buildParams() is callable' ); + + //$result = $obj->buildParams ( $columns, $values); + //$t->isa_ok( $result, 'NULL', 'call to method buildParams '); + $t->todo( "call to method buildParams using $columns, $values "); + + + //checking method 'populateStmtValues' + $t->can_ok( $obj, 'populateStmtValues', 'populateStmtValues() is callable' ); + + //$result = $obj->populateStmtValues ( $stmt, $params, $dbMap); + //$t->isa_ok( $result, 'NULL', 'call to method populateStmtValues '); + $t->todo( "call to method populateStmtValues using $stmt, $params, $dbMap "); + + + //checking method 'getValidator' + $t->can_ok( $obj, 'getValidator', 'getValidator() is callable' ); + + //$result = $obj->getValidator ( $classname); + //$t->isa_ok( $result, 'NULL', 'call to method getValidator '); + $t->todo( "call to method getValidator using $classname "); + + + //checking method 'getMapBuilder' + $t->can_ok( $obj, 'getMapBuilder', 'getMapBuilder() is callable' ); + + //$result = $obj->getMapBuilder ( $classname); + //$t->isa_ok( $result, 'NULL', 'call to method getMapBuilder '); + $t->todo( "call to method getMapBuilder using $classname "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classCasesTest.php b/workflow/engine/test/unit/processmaker/classCasesTest.php new file mode 100644 index 000000000..1a07b5d1c --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classCasesTest.php @@ -0,0 +1,638 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php'; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'case'); + + + //$obj = new Cases ($dbc); + $t = new lime_test( 3, new lime_output_color() ); + + $className = "Cases"; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $className = ucwords($className); + $t->diag("class $className" ); + + $t->is( count($methods) , 75, "class $className have " . 73 . ' methods.' ); + + // Methods + $aMethods = array_keys ( $methods ); + + + /* + //checking method 'canStartCase' + $t->is ( $aMethods[0], 'canStartCase', 'canStartCase() is callable' ); + + //$result = $obj->canStartCase ( $sUIDUser); + //$t->isa_ok( $result, 'NULL', 'call to method canStartCase '); + $t->todo( "call to method canStartCase using $sUIDUser "); + + + //checking method 'getStartCases' + $t->is ( $aMethods[1], 'getStartCases', 'getStartCases() is callable' ); + + //$result = $obj->getStartCases ( $sUIDUser); + //$t->isa_ok( $result, 'NULL', 'call to method getStartCases '); + $t->todo( "call to method getStartCases using $sUIDUser "); + + //checking method 'loadCase' + $t->is ( $aMethods[2], 'loadCase', 'loadCase() is callable' ); + + //$result = $obj->loadCase ( $sAppUid, $iDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method loadCase '); + $t->todo( "call to method loadCase using $sAppUid, $iDelIndex "); + + + //checking method 'loadCaseByNumber' + $t->is ( $aMethods[3], 'loadCaseByNumber', 'loadCaseByNumber() is callable' ); + + //$result = $obj->loadCaseByNumber ( $sCaseNumber); + //$t->isa_ok( $result, 'NULL', 'call to method loadCaseByNumber '); + $t->todo( "call to method loadCaseByNumber using $sCaseNumber "); + + + //checking method 'refreshCaseLabel' + $t->is ( $aMethods[4], 'refreshCaseLabel', 'refreshCaseLabel() is callable' ); + + //$result = $obj->refreshCaseLabel ( $sAppUid, $aAppData, $sLabel); + //$t->isa_ok( $result, 'NULL', 'call to method refreshCaseLabel '); + $t->todo( "call to method refreshCaseLabel using $sAppUid, $aAppData, $sLabel "); + + + //checking method 'refreshCaseTitle' + $t->is ( $aMethods[5], 'refreshCaseTitle', 'refreshCaseTitle() is callable' ); + + //$result = $obj->refreshCaseTitle ( $sAppUid, $aAppData); + //$t->isa_ok( $result, 'NULL', 'call to method refreshCaseTitle '); + $t->todo( "call to method refreshCaseTitle using $sAppUid, $aAppData "); + + + //checking method 'refreshCaseDescription' + $t->is ( $aMethods[6], 'refreshCaseDescription', 'refreshCaseDescription() is callable' ); + + //$result = $obj->refreshCaseDescription ( $sAppUid, $aAppData); + //$t->isa_ok( $result, 'NULL', 'call to method refreshCaseDescription '); + $t->todo( "call to method refreshCaseDescription using $sAppUid, $aAppData "); + + + //checking method 'refreshCaseStatusCode' + $t->is ( $aMethods[7], 'refreshCaseStatusCode', 'refreshCaseStatusCode() is callable' ); + + //$result = $obj->refreshCaseStatusCode ( $sAppUid, $aAppData); + //$t->isa_ok( $result, 'NULL', 'call to method refreshCaseStatusCode '); + $t->todo( "call to method refreshCaseStatusCode using $sAppUid, $aAppData "); + + + //checking method 'updateCase' + $t->is ( $aMethods[8], 'updateCase', 'updateCase() is callable' ); + + //$result = $obj->updateCase ( $sAppUid, $Fields); + //$t->isa_ok( $result, 'NULL', 'call to method updateCase '); + $t->todo( "call to method updateCase using $sAppUid, $Fields "); + + + //checking method 'removeCase' + $t->is ( $aMethods[9], 'removeCase', 'removeCase() is callable' ); + + //$result = $obj->removeCase ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method removeCase '); + $t->todo( "call to method removeCase using $sAppUid "); + + + //checking method 'setDelInitDate' + $t->is ( $aMethods[10], 'setDelInitDate', 'setDelInitDate() is callable' ); + + //$result = $obj->setDelInitDate ( $sAppUid, $iDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method setDelInitDate '); + $t->todo( "call to method setDelInitDate using $sAppUid, $iDelIndex "); + + + //checking method 'GetOpenThreads' + $t->is ( $aMethods[11], 'GetOpenThreads', 'GetOpenThreads() is callable' ); + + //$result = $obj->GetOpenThreads ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method GetOpenThreads '); + $t->todo( "call to method GetOpenThreads using $sAppUid "); + + + //checking method 'getSiblingThreads' + $t->is ( $aMethods[12], 'getSiblingThreads', 'getSiblingThreads() is callable' ); + + //$result = $obj->getSiblingThreads ( $sAppUid, $iDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method getSiblingThreads '); + $t->todo( "call to method getSiblingThreads using $sAppUid, $iDelIndex "); + + + //checking method 'getOpenSiblingThreads' + $t->is ( $aMethods[13], 'getOpenSiblingThreads', 'getOpenSiblingThreads() is callable' ); + + //$result = $obj->getOpenSiblingThreads ( $sNextTask, $sAppUid, $iDelIndex, $sCurrentTask); + //$t->isa_ok( $result, 'NULL', 'call to method getOpenSiblingThreads '); + $t->todo( "call to method getOpenSiblingThreads using $sNextTask, $sAppUid, $iDelIndex, $sCurrentTask "); + + + //checking method 'CountTotalPreviousTasks' + $t->is ( $aMethods[14], 'CountTotalPreviousTasks', 'CountTotalPreviousTasks() is callable' ); + + //$result = $obj->CountTotalPreviousTasks ( $sTasUid); + //$t->isa_ok( $result, 'NULL', 'call to method CountTotalPreviousTasks '); + $t->todo( "call to method CountTotalPreviousTasks using $sTasUid "); + + + //checking method 'getOpenNullDelegations' + $t->is ( $aMethods[15], 'getOpenNullDelegations', 'getOpenNullDelegations() is callable' ); + + //$result = $obj->getOpenNullDelegations ( $sAppUid, $sTasUid); + //$t->isa_ok( $result, 'NULL', 'call to method getOpenNullDelegations '); + $t->todo( "call to method getOpenNullDelegations using $sAppUid, $sTasUid "); + + + //checking method 'isRouteOpen' + $t->is ( $aMethods[16], 'isRouteOpen', 'isRouteOpen() is callable' ); + + //$result = $obj->isRouteOpen ( $sAppUid, $sTasUid); + //$t->isa_ok( $result, 'NULL', 'call to method isRouteOpen '); + $t->todo( "call to method isRouteOpen using $sAppUid, $sTasUid "); + + + //checking method 'newAppDelegation' + $t->is ( $aMethods[17], 'newAppDelegation', 'newAppDelegation() is callable' ); + + //$result = $obj->newAppDelegation ( $sProUid, $sAppUid, $sTasUid, $sUsrUid, $sPrevious, $iPriority, $sDelType, $iAppThreadIndex); + //$t->isa_ok( $result, 'NULL', 'call to method newAppDelegation '); + $t->todo( "call to method newAppDelegation using $sProUid, $sAppUid, $sTasUid, $sUsrUid, $sPrevious, $iPriority, $sDelType, $iAppThreadIndex "); + + + //checking method 'updateAppDelegation' + $t->is ( $aMethods[18], 'updateAppDelegation', 'updateAppDelegation() is callable' ); + + //$result = $obj->updateAppDelegation ( $sAppUid, $iDelIndex, $iAppThreadIndex); + //$t->isa_ok( $result, 'NULL', 'call to method updateAppDelegation '); + $t->todo( "call to method updateAppDelegation using $sAppUid, $iDelIndex, $iAppThreadIndex "); + + + //checking method 'GetAllDelegations' + $t->is ( $aMethods[19], 'GetAllDelegations', 'GetAllDelegations() is callable' ); + + //$result = $obj->GetAllDelegations ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method GetAllDelegations '); + $t->todo( "call to method GetAllDelegations using $sAppUid "); + + + //checking method 'GetAllThreads' + $t->is ( $aMethods[20], 'GetAllThreads', 'GetAllThreads() is callable' ); + + //$result = $obj->GetAllThreads ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method GetAllThreads '); + $t->todo( "call to method GetAllThreads using $sAppUid "); + + + //checking method 'updateAppThread' + $t->is ( $aMethods[21], 'updateAppThread', 'updateAppThread() is callable' ); + + //$result = $obj->updateAppThread ( $sAppUid, $iAppThreadIndex, $iNewDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method updateAppThread '); + $t->todo( "call to method updateAppThread using $sAppUid, $iAppThreadIndex, $iNewDelIndex "); + + + //checking method 'closeAppThread' + $t->is ( $aMethods[22], 'closeAppThread', 'closeAppThread() is callable' ); + + //$result = $obj->closeAppThread ( $sAppUid, $iAppThreadIndex); + //$t->isa_ok( $result, 'NULL', 'call to method closeAppThread '); + $t->todo( "call to method closeAppThread using $sAppUid, $iAppThreadIndex "); + + + //checking method 'closeAllThreads' + $t->is ( $aMethods[23], 'closeAllThreads', 'closeAllThreads() is callable' ); + + //$result = $obj->closeAllThreads ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method closeAllThreads '); + $t->todo( "call to method closeAllThreads using $sAppUid "); + + + //checking method 'newAppThread' + $t->is ( $aMethods[24], 'newAppThread', 'newAppThread() is callable' ); + + //$result = $obj->newAppThread ( $sAppUid, $iNewDelIndex, $iAppParent); + //$t->isa_ok( $result, 'NULL', 'call to method newAppThread '); + $t->todo( "call to method newAppThread using $sAppUid, $iNewDelIndex, $iAppParent "); + + + //checking method 'closeAllDelegations' + $t->is ( $aMethods[25], 'closeAllDelegations', 'closeAllDelegations() is callable' ); + + //$result = $obj->closeAllDelegations ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method closeAllDelegations '); + $t->todo( "call to method closeAllDelegations using $sAppUid "); + + + //checking method 'CloseCurrentDelegation' + $t->is ( $aMethods[26], 'CloseCurrentDelegation', 'CloseCurrentDelegation() is callable' ); + + //$result = $obj->CloseCurrentDelegation ( $sAppUid, $iDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method CloseCurrentDelegation '); + $t->todo( "call to method CloseCurrentDelegation using $sAppUid, $iDelIndex "); + + + //checking method 'ReactivateCurrentDelegation' + $t->is ( $aMethods[27], 'ReactivateCurrentDelegation', 'ReactivateCurrentDelegation() is callable' ); + + //$result = $obj->ReactivateCurrentDelegation ( $sAppUid, $iDelegation); + //$t->isa_ok( $result, 'NULL', 'call to method ReactivateCurrentDelegation '); + $t->todo( "call to method ReactivateCurrentDelegation using $sAppUid, $iDelegation "); + + + //checking method 'startCase' + $t->is ( $aMethods[28], 'startCase', 'startCase() is callable' ); + + //$result = $obj->startCase ( $sTasUid, $sUsrUid); + //$t->isa_ok( $result, 'NULL', 'call to method startCase '); + $t->todo( "call to method startCase using $sTasUid, $sUsrUid "); + + + //checking method 'getNextStep' + $t->is ( $aMethods[29], 'getNextStep', 'getNextStep() is callable' ); + + //$result = $obj->getNextStep ( $sProUid, $sAppUid, $iDelIndex, $iPosition); + //$t->isa_ok( $result, 'NULL', 'call to method getNextStep '); + $t->todo( "call to method getNextStep using $sProUid, $sAppUid, $iDelIndex, $iPosition "); + + + //checking method 'getPreviousStep' + $t->is ( $aMethods[30], 'getPreviousStep', 'getPreviousStep() is callable' ); + + //$result = $obj->getPreviousStep ( $sProUid, $sAppUid, $iDelIndex, $iPosition); + //$t->isa_ok( $result, 'NULL', 'call to method getPreviousStep '); + $t->todo( "call to method getPreviousStep using $sProUid, $sAppUid, $iDelIndex, $iPosition "); + + + //checking method 'getNextSupervisorStep' + $t->is ( $aMethods[31], 'getNextSupervisorStep', 'getNextSupervisorStep() is callable' ); + + //$result = $obj->getNextSupervisorStep ( $sProcessUID, $iPosition, $sType); + //$t->isa_ok( $result, 'NULL', 'call to method getNextSupervisorStep '); + $t->todo( "call to method getNextSupervisorStep using $sProcessUID, $iPosition, $sType "); + + + //checking method 'getPreviousSupervisorStep' + $t->is ( $aMethods[32], 'getPreviousSupervisorStep', 'getPreviousSupervisorStep() is callable' ); + + //$result = $obj->getPreviousSupervisorStep ( $sProcessUID, $iPosition, $sType); + //$t->isa_ok( $result, 'NULL', 'call to method getPreviousSupervisorStep '); + $t->todo( "call to method getPreviousSupervisorStep using $sProcessUID, $iPosition, $sType "); + + + //checking method 'getTransferHistoryCriteria' + $t->is ( $aMethods[33], 'getTransferHistoryCriteria', 'getTransferHistoryCriteria() is callable' ); + + //$result = $obj->getTransferHistoryCriteria ( $sAppUid); + //$t->isa_ok( $result, 'NULL', 'call to method getTransferHistoryCriteria '); + $t->todo( "call to method getTransferHistoryCriteria using $sAppUid "); + + //checking method 'prepareCriteriaForToDo' + $t->is ( $aMethods[34], 'prepareCriteriaForToDo', 'prepareCriteriaForToDo() is callable' ); + + //$result = $obj->getConditionCasesList ( $sTypeList, $sUIDUserLogged); + //$t->isa_ok( $result, 'NULL', 'call to method getConditionCasesList '); + $t->todo( "call to method prepareCriteriaForToDo using $sTypeList, $sUIDUserLogged "); + + + //checking method 'getConditionCasesList' + $t->is ( $aMethods[35], 'getConditionCasesList', 'getConditionCasesList() is callable' ); + + //$result = $obj->getConditionCasesList ( $sTypeList, $sUIDUserLogged); + //$t->isa_ok( $result, 'NULL', 'call to method getConditionCasesList '); + $t->todo( "call to method getConditionCasesList using $sTypeList, $sUIDUserLogged "); + + + //checking method 'ThrowUnpauseDaemon' + $t->is ( $aMethods[36], 'ThrowUnpauseDaemon', 'ThrowUnpauseDaemon() is callable' ); + + //$result = $obj->ThrowUnpauseDaemon ( ); + //$t->isa_ok( $result, 'NULL', 'call to method ThrowUnpauseDaemon '); + $t->todo( "call to method ThrowUnpauseDaemon using "); + + + //checking method 'getApplicationUIDByNumber' + $t->is ( $aMethods[37], 'getApplicationUIDByNumber', 'getApplicationUIDByNumber() is callable' ); + + //$result = $obj->getApplicationUIDByNumber ( $iApplicationNumber); + //$t->isa_ok( $result, 'NULL', 'call to method getApplicationUIDByNumber '); + $t->todo( "call to method getApplicationUIDByNumber using $iApplicationNumber "); + + + //checking method 'getCurrentDelegation' + $t->is ( $aMethods[38], 'getCurrentDelegation', 'getCurrentDelegation() is callable' ); + + //$result = $obj->getCurrentDelegation ( $sApplicationUID, $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getCurrentDelegation '); + $t->todo( "call to method getCurrentDelegation using $sApplicationUID, $sUserUID "); + + + //checking method 'loadTriggers' + $t->is ( $aMethods[39], 'loadTriggers', 'loadTriggers() is callable' ); + + //$result = $obj->loadTriggers ( $sTasUid, $sStepType, $sStepUidObj, $sTriggerType); + //$t->isa_ok( $result, 'NULL', 'call to method loadTriggers '); + $t->todo( "call to method loadTriggers using $sTasUid, $sStepType, $sStepUidObj, $sTriggerType "); + + + //checking method 'executeTriggers' + $t->is ( $aMethods[40], 'executeTriggers', 'executeTriggers() is callable' ); + + //$result = $obj->executeTriggers ( $sTasUid, $sStepType, $sStepUidObj, $sTriggerType, $aFields); + //$t->isa_ok( $result, 'NULL', 'call to method executeTriggers '); + $t->todo( "call to method executeTriggers using $sTasUid, $sStepType, $sStepUidObj, $sTriggerType, $aFields "); + + + //checking method 'getTriggerNames' + $t->is ( $aMethods[41], 'getTriggerNames', 'getTriggerNames() is callable' ); + + //$result = $obj->getTriggerNames ( $triggers); + //$t->isa_ok( $result, 'NULL', 'call to method getTriggerNames '); + $t->todo( "call to method getTriggerNames using $triggers "); + + + //checking method 'getInputDocumentsCriteria' + $t->is ( $aMethods[42], 'getInputDocumentsCriteria', 'getInputDocumentsCriteria() is callable' ); + + //$result = $obj->getInputDocumentsCriteria ( $sApplicationUID, $iDelegation, $sDocumentUID); + //$t->isa_ok( $result, 'NULL', 'call to method getInputDocumentsCriteria '); + $t->todo( "call to method getInputDocumentsCriteria using $sApplicationUID, $iDelegation, $sDocumentUID "); + + //checking method 'getInputDocumentsCriteriaToRevise' + $t->is ( $aMethods[43], 'getInputDocumentsCriteriaToRevise', 'getInputDocumentsCriteriaToRevise() is callable' ); + + //$result = $obj->getInputDocumentsCriteriaToRevise ( $sApplicationUID); + //$t->isa_ok( $result, 'NULL', 'call to method getInputDocumentsCriteriaToRevise '); + $t->todo( "call to method getInputDocumentsCriteriaToRevise using $sApplicationUID "); + + + //checking method 'getOutputDocumentsCriteriaToRevise' + $t->is ( $aMethods[44], 'getOutputDocumentsCriteriaToRevise', 'getOutputDocumentsCriteriaToRevise() is callable' ); + + //$result = $obj->getOutputDocumentsCriteriaToRevise ( $sApplicationUID); + //$t->isa_ok( $result, 'NULL', 'call to method getOutputDocumentsCriteriaToRevise '); + $t->todo( "call to method getOutputDocumentsCriteriaToRevise using $sApplicationUID "); + + + //checking method 'getCriteriaProcessCases' + $t->is ( $aMethods[45], 'getCriteriaProcessCases', 'getCriteriaProcessCases() is callable' ); + + //$result = $obj->getCriteriaProcessCases ( $status, $PRO_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getCriteriaProcessCases '); + $t->todo( "call to method getCriteriaProcessCases using $status, $PRO_UID "); + + + //checking method 'pauseCase' + $t->is ( $aMethods[46], 'pauseCase', 'pauseCase() is callable' ); + + //$result = $obj->pauseCase ( $sApplicationUID, $iDelegation, $sUserUID, $sUnpauseDate); + //$t->isa_ok( $result, 'NULL', 'call to method pauseCase '); + $t->todo( "call to method pauseCase using $sApplicationUID, $iDelegation, $sUserUID, $sUnpauseDate "); + + + //checking method 'unpauseCase' + $t->is ( $aMethods[47], 'unpauseCase', 'unpauseCase() is callable' ); + + //$result = $obj->unpauseCase ( $sApplicationUID, $iDelegation, $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method unpauseCase '); + $t->todo( "call to method unpauseCase using $sApplicationUID, $iDelegation, $sUserUID "); + + + //checking method 'cancelCase' + $t->is ( $aMethods[48], 'cancelCase', 'cancelCase() is callable' ); + + //$result = $obj->cancelCase ( $sApplicationUID, $iIndex, $user_logged); + //$t->isa_ok( $result, 'NULL', 'call to method cancelCase '); + $t->todo( "call to method cancelCase using $sApplicationUID, $iIndex, $user_logged "); + + + //checking method 'reactivateCase' + $t->is ( $aMethods[49], 'reactivateCase', 'reactivateCase() is callable' ); + + //$result = $obj->reactivateCase ( $sApplicationUID, $iIndex, $user_logged); + //$t->isa_ok( $result, 'NULL', 'call to method reactivateCase '); + $t->todo( "call to method reactivateCase using $sApplicationUID, $iIndex, $user_logged "); + + + //checking method 'reassignCase' + $t->is ( $aMethods[50], 'reassignCase', 'reassignCase() is callable' ); + + //$result = $obj->reassignCase ( $sApplicationUID, $iDelegation, $sUserUID, $newUserUID, $sType); + //$t->isa_ok( $result, 'NULL', 'call to method reassignCase '); + $t->todo( "call to method reassignCase using $sApplicationUID, $iDelegation, $sUserUID, $newUserUID, $sType "); + + + //checking method 'getAllDynaformsStepsToRevise' + $t->is ( $aMethods[51], 'getAllDynaformsStepsToRevise', 'getAllDynaformsStepsToRevise() is callable' ); + + //$result = $obj->getAllDynaformsStepsToRevise ( $APP_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllDynaformsStepsToRevise '); + $t->todo( "call to method getAllDynaformsStepsToRevise using $APP_UID "); + + + //checking method 'getAllInputsStepsToRevise' + $t->is ( $aMethods[52], 'getAllInputsStepsToRevise', 'getAllInputsStepsToRevise() is callable' ); + + //$result = $obj->getAllInputsStepsToRevise ( $APP_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllInputsStepsToRevise '); + $t->todo( "call to method getAllInputsStepsToRevise using $APP_UID "); + + + //checking method 'getAllUploadedDocumentsCriteria' + $t->is ( $aMethods[53], 'getAllUploadedDocumentsCriteria', 'getAllUploadedDocumentsCriteria() is callable' ); + + //$result = $obj->getAllUploadedDocumentsCriteria ( $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllUploadedDocumentsCriteria '); + $t->todo( "call to method getAllUploadedDocumentsCriteria using $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID "); + + + //checking method 'getAllGeneratedDocumentsCriteria' + $t->is ( $aMethods[54], 'getAllGeneratedDocumentsCriteria', 'getAllGeneratedDocumentsCriteria() is callable' ); + + //$result = $obj->getAllGeneratedDocumentsCriteria ( $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllGeneratedDocumentsCriteria '); + $t->todo( "call to method getAllGeneratedDocumentsCriteria using $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID "); + + + //checking method 'getallDynaformsCriteria' + $t->is ( $aMethods[55], 'getallDynaformsCriteria', 'getallDynaformsCriteria() is callable' ); + + //$result = $obj->getallDynaformsCriteria ( $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getallDynaformsCriteria '); + $t->todo( "call to method getallDynaformsCriteria using $sProcessUID, $sApplicationUID, $sTasKUID, $sUserUID "); + + + //checking method 'sendNotifications' + $t->is ( $aMethods[56], 'sendNotifications', 'sendNotifications() is callable' ); + + //$result = $obj->sendNotifications ( $sCurrentTask, $aTasks, $aFields, $sApplicationUID, $iDelegation, $sFrom); + //$t->isa_ok( $result, 'NULL', 'call to method sendNotifications '); + $t->todo( "call to method sendNotifications using $sCurrentTask, $aTasks, $aFields, $sApplicationUID, $iDelegation, $sFrom "); + + + //checking method 'getAllObjects' + $t->is ( $aMethods[57], 'getAllObjects', 'getAllObjects() is callable' ); + + //$result = $obj->getAllObjects ( $PRO_UID, $APP_UID, $TAS_UID, $USR_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllObjects '); + $t->todo( "call to method getAllObjects using $PRO_UID, $APP_UID, $TAS_UID, $USR_UID "); + + + //checking method 'getAllObjectsFrom' + $t->is ( $aMethods[58], 'getAllObjectsFrom', 'getAllObjectsFrom() is callable' ); + + //$result = $obj->getAllObjectsFrom ( $PRO_UID, $APP_UID, $TAS_UID, $USR_UID, $ACTION); + //$t->isa_ok( $result, 'NULL', 'call to method getAllObjectsFrom '); + $t->todo( "call to method getAllObjectsFrom using $PRO_UID, $APP_UID, $TAS_UID, $USR_UID, $ACTION "); + + + //checking method 'verifyCaseTracker' + $t->is ( $aMethods[59], 'verifyCaseTracker', 'verifyCaseTracker() is callable' ); + + //$result = $obj->verifyCaseTracker ( $case, $pin); + //$t->isa_ok( $result, 'NULL', 'call to method verifyCaseTracker '); + $t->todo( "call to method verifyCaseTracker using $case, $pin "); + + + //checking method 'Permisos' + $t->is ( $aMethods[60], 'Permisos', 'Permisos() is callable' ); + + //$result = $obj->Permisos ( $PRO_UID); + //$t->isa_ok( $result, 'NULL', 'call to method Permisos '); + $t->todo( "call to method Permisos using $PRO_UID "); + + + //checking method 'verifyTable' + $t->is ( $aMethods[61], 'verifyTable', 'verifyTable() is callable' ); + + //$result = $obj->verifyTable ( ); + //$t->isa_ok( $result, 'NULL', 'call to method verifyTable '); + $t->todo( "call to method verifyTable using "); + + + //checking method 'getAllUploadedDocumentsCriteriaTracker' + $t->is ( $aMethods[62], 'getAllUploadedDocumentsCriteriaTracker', 'getAllUploadedDocumentsCriteriaTracker() is callable' ); + + //$result = $obj->getAllUploadedDocumentsCriteriaTracker ( $sProcessUID, $sApplicationUID, $sDocUID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllUploadedDocumentsCriteriaTracker '); + $t->todo( "call to method getAllUploadedDocumentsCriteriaTracker using $sProcessUID, $sApplicationUID, $sDocUID "); + + + //checking method 'getAllGeneratedDocumentsCriteriaTracker' + $t->is ( $aMethods[63], 'getAllGeneratedDocumentsCriteriaTracker', 'getAllGeneratedDocumentsCriteriaTracker() is callable' ); + + //$result = $obj->getAllGeneratedDocumentsCriteriaTracker ( $sProcessUID, $sApplicationUID, $sDocUID); + //$t->isa_ok( $result, 'NULL', 'call to method getAllGeneratedDocumentsCriteriaTracker '); + $t->todo( "call to method getAllGeneratedDocumentsCriteriaTracker using $sProcessUID, $sApplicationUID, $sDocUID "); + + + //checking method 'getHistoryMessagesTracker' + $t->is ( $aMethods[64], 'getHistoryMessagesTracker', 'getHistoryMessagesTracker() is callable' ); + + //$result = $obj->getHistoryMessagesTracker ( $sApplicationUID); + //$t->isa_ok( $result, 'NULL', 'call to method getHistoryMessagesTracker '); + $t->todo( "call to method getHistoryMessagesTracker using $sApplicationUID "); + + + //checking method 'getHistoryMessagesTrackerView' + $t->is ( $aMethods[65], 'getHistoryMessagesTrackerView', 'getHistoryMessagesTrackerView() is callable' ); + + //$result = $obj->getHistoryMessagesTrackerView ( $sApplicationUID, $Msg_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getHistoryMessagesTrackerView '); + $t->todo( "call to method getHistoryMessagesTrackerView using $sApplicationUID, $Msg_UID "); + + + //checking method 'getAllObjectsFromProcess' + $t->is ( $aMethods[66], 'getAllObjectsFromProcess', 'getAllObjectsFromProcess() is callable' ); + + //$result = $obj->getAllObjectsFromProcess ( $PRO_UID, $OBJ_TYPE); + //$t->isa_ok( $result, 'NULL', 'call to method getAllObjectsFromProcess '); + $t->todo( "call to method getAllObjectsFromProcess using $PRO_UID, $OBJ_TYPE "); + + + //checking method 'executeTriggersAfterExternal' + $t->is ( $aMethods[67], 'executeTriggersAfterExternal', 'executeTriggersAfterExternal() is callable' ); + + //$result = $obj->executeTriggersAfterExternal ( $sProcess, $sTask, $sApplication, $iIndex, $iStepPosition, $aNewData); + //$t->isa_ok( $result, 'NULL', 'call to method executeTriggersAfterExternal '); + $t->todo( "call to method executeTriggersAfterExternal using $sProcess, $sTask, $sApplication, $iIndex, $iStepPosition, $aNewData "); + + + //checking method 'thisIsTheCurrentUser' + $t->is ( $aMethods[68], 'thisIsTheCurrentUser', 'thisIsTheCurrentUser() is callable' ); + + //$result = $obj->thisIsTheCurrentUser ( $sApplicationUID, $iIndex, $sUserUID, $sAction, $sURL); + //$t->isa_ok( $result, 'NULL', 'call to method thisIsTheCurrentUser '); + $t->todo( "call to method thisIsTheCurrentUser using $sApplicationUID, $iIndex, $sUserUID, $sAction, $sURL "); + + + //checking method 'getCriteriaUsersCases' + $t->is ( $aMethods[69], 'getCriteriaUsersCases', 'getCriteriaUsersCases() is callable' ); + + //$result = $obj->getCriteriaUsersCases ( $status, $USR_UID); + //$t->isa_ok( $result, 'NULL', 'call to method getCriteriaUsersCases '); + $t->todo( "call to method getCriteriaUsersCases using $status, $USR_UID "); + + + //checking method 'getAdvancedSearch' + $t->is ( $aMethods[70], 'getAdvancedSearch', 'getAdvancedSearch() is callable' ); + + //$result = $obj->getAdvancedSearch ( $sCase, $sProcess, $sTask, $sCurrentUser, $sSentby, $sLastModFrom, $sLastModTo, $sStatus, $permisse, $userlogged, $aSupervisor); + //$t->isa_ok( $result, 'NULL', 'call to method getAdvancedSearch '); + + */ + $t->todo( "call to method getAdvancedSearch using $sCase, $sProcess, $sTask, $sCurrentUser, $sSentby, $sLastModFrom, $sLastModTo, $sStatus, $permisse, $userlogged, $aSupervisor "); + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classConfigurationTest.php b/workflow/engine/test/unit/processmaker/classConfigurationTest.php new file mode 100644 index 000000000..a921598ce --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classConfigurationTest.php @@ -0,0 +1,135 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + //G::LoadClass ( 'user'); + G::LoadSystem ( 'testTools'); + require_once(PATH_CORE.'/classes/model/Configuration.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Configuration ($dbc); + $t = new lime_test( 25, new lime_output_color() ); + + $t->diag('class Configuration' ); + $t->isa_ok( $obj , 'Configuration', 'class Configuration created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class ConfigurationTest extends UnitTest + { + function CreateConfiguration($data,$fields) + { + try + { + $Configuration=new Configuration(); + $result=$Configuration->create($fields); + $this->domain->addDomainValue('CREATED_UID',$Configuration->getCfgUid()); + $this->domain->addDomainValue('CREATED_OBJ',$Configuration->getObjUid()); + $this->domain->addDomainValue('CREATED_PRO',$Configuration->getProUid()); + $this->domain->addDomainValue('CREATED_USR',$Configuration->getUsrUid()); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function UpdateConfiguration($data,$fields) + { + try + { + $Configuration=new Configuration(); + $result=$Configuration->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadConfiguration($data,$fields) + { + try + { + $Configuration=new Configuration(); + $result=$Configuration->load($fields['CFG_UID'], $fields['OBJ_UID'], $fields['PRO_UID'], $fields['USR_UID'], $fields['APP_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveConfiguration($data,$fields) + { + try + { + $Configuration=new Configuration(); + $result=$Configuration->remove($fields['CFG_UID'], $fields['OBJ_UID'], $fields['PRO_UID'], $fields['USR_UID'], $fields['APP_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new ConfigurationTest('configuration.yml',$t); + $test->domain->addDomain('CREATED_UID'); + $test->domain->addDomain('CREATED_OBJ'); + $test->domain->addDomain('CREATED_PRO'); + $test->domain->addDomain('CREATED_USR'); + $test->load('CreateTestConfigurations'); + $test->runAll(); + $test->load('ConfigurationUnitTest'); + $test->runAll(); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classContentTest.php b/workflow/engine/test/unit/processmaker/classContentTest.php new file mode 100644 index 000000000..36b570d9a --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classContentTest.php @@ -0,0 +1,149 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( PATH_CORE . "config/databases.php"); + require_once( 'propel/Propel.php' ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadSystem ( 'testTools'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + + require_once(PATH_CORE.'/classes/model/Content.php'); + +class ContentTest extends unitTest + { + + function LoadContent($data, $fields) + { + $obj = new Content(); + $ConCategory = $fields['CON_CATEGORY']; + $ConParent = $fields['CON_PARENT']; + $ConId = $fields['CON_ID']; + $ConLang = $fields['CON_LANG']; + $ConValue = $fields['CON_VALUE']; + try { + $res = $obj->load($ConCategory, $ConParent, $ConId, $ConLang ); + if ( $res == '' ) { + $this->testLime->is ( $res, '', 'Load Empty Content ' ); + } + else + $this->testLime->is ( $ConValue, $ConValue, 'correct value from Content->Load ' ); + } + catch ( Exception $e) { + return $e; + } + return $res; + } + + function deleteContent($data, $fields) + { + $obj = new Content(); + $ConCategory = $fields['CON_CATEGORY']; + $ConParent = $fields['CON_PARENT']; + $ConId = $fields['CON_ID']; + $ConLang = $fields['CON_LANG']; + try { + //$res = $obj->load($ConCategory, $ConParent, $ConId, $ConLang ); + $content = ContentPeer::retrieveByPK( $ConCategory, $ConParent, $ConId, $ConLang ); + if ( $content ) + $content->delete( ); + } + catch ( Exception $e) { + return $e; + } + return $res; + } + + + function addContent($data, $fields) + { + $obj=new Content(); + $ConCategory = $fields['CON_CATEGORY']; + $ConParent = $fields['CON_PARENT']; + $ConId = $fields['CON_ID']; + $ConLang = $fields['CON_LANG']; + $ConValue = $fields['CON_VALUE']; + try { + $res = $obj->addContent($ConCategory, $ConParent, $ConId, $ConLang, $ConValue ); + } + catch ( Exception $e) { + return $e; + } + return $res; + } + + } + + + + $obj = new Content(); + //$t = new lime_test( 5, new lime_output_color() ); + $t = new lime_test( 12, new lime_output_color() ); + + $t->diag('class Content' ); + $t->isa_ok( $obj , 'Content', 'class Content created'); + + $t->todo( 'review all combinations of is_utf8 '); + $t->todo( 'review is_utf8 should be in another class'); + + //Initialize the global domain (It is optional) + $testDomain = new ymlDomain(); + + $test = new ContentTest ('content.yml', $t, $testDomain ); + + //check if an row exists, + $test->load('loadContent'); + $test->runSingle(); + + //check if an row exists, + $test->load('deleteContent'); + $test->runAll(); + + $test->load('addContentAcentos'); + $test->runSingle(); + + //add the same row twice, the first time goes good, but the second the class throw an error + $test->load('addContent1'); + $test->runSingle(); + + $test->load('addContentTwice'); + $test->runSingle(); + + $test->load('loadContent'); + $test->runSingle(); + + $obj = new Content(); + $res = $obj->addContent ('1','2','3','en','language1'); + $res = $obj->addContent ('1','2','3','es','language2'); + $res = $obj->addContent ('1','2','3','pt','language3'); + $res = $obj->addContent ('1','2','3','fr','language4'); + $res = $obj->addContent ('1','2','3','it','language5'); + $res = $obj->removeContent ('1','2','3'); + //$t->can_ok( $res, 'getAppTitle', 'removeContent.' ); diff --git a/workflow/engine/test/unit/processmaker/classDashboardsTest.php b/workflow/engine/test/unit/processmaker/classDashboardsTest.php new file mode 100644 index 000000000..ba93ac0a1 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDashboardsTest.php @@ -0,0 +1,96 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'dashboards'); + + $obj = new Dashboards ($dbc); + $t = new lime_test( 9, new lime_output_color() ); + + $className = Dashboards; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , 'Dashboards', 'class $className created'); + + $t->is( count($methods) , 3, "class $className have " . 3 . ' methods.' ); + + //checking method 'getConfiguration' + $t->can_ok( $obj, 'getConfiguration', 'getConfiguration() is callable' ); + + //$result = $obj->getConfiguration ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getConfiguration '); + $t->todo( "call to method getConfiguration using $sUserUID "); + + + //checking method 'saveConfiguration' + $t->can_ok( $obj, 'saveConfiguration', 'saveConfiguration() is callable' ); + + //$result = $obj->saveConfiguration ( $sUserUID, $aConfiguration); + //$t->isa_ok( $result, 'NULL', 'call to method saveConfiguration '); + $t->todo( "call to method saveConfiguration using $sUserUID, $aConfiguration "); + + + //checking method 'getDashboardsObject' + $t->can_ok( $obj, 'getDashboardsObject', 'getDashboardsObject() is callable' ); + + //$result = $obj->getDashboardsObject ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getDashboardsObject '); + $t->todo( "call to method getDashboardsObject using $sUserUID "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classDatesTest.php b/workflow/engine/test/unit/processmaker/classDatesTest.php new file mode 100644 index 000000000..ffb79c191 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDatesTest.php @@ -0,0 +1,207 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'dates'); + + + $obj = new Dates ($dbc); + $t = new lime_test( 37, new lime_output_color() ); + + $className = Dates; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + //$className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 17, "class $className have " . 17 . ' methods.' ); + + //checking method 'calculateDate' + $t->can_ok( $obj, 'calculateDate', 'calculateDate() is callable' ); + + //$result = $obj->calculateDate ( $sInitDate, $iDuration, $sTimeUnit, $iTypeDay, $UsrUid, $ProUid, $TasUid); + //$t->isa_ok( $result, 'NULL', 'call to method calculateDate '); + $t->todo( "call to method calculateDate using $sInitDate, $iDuration, $sTimeUnit, $iTypeDay, $UsrUid, $ProUid, $TasUid "); + + + //checking method 'calculateDuration' + $t->can_ok( $obj, 'calculateDuration', 'calculateDuration() is callable' ); + + //$result = $obj->calculateDuration ( $sInitDate, $sEndDate, $UsrUid, $ProUid, $TasUid); + //$t->isa_ok( $result, 'NULL', 'call to method calculateDuration '); + $t->todo( "call to method calculateDuration using $sInitDate, $sEndDate, $UsrUid, $ProUid, $TasUid "); + + + //checking method 'prepareInformation' + $t->can_ok( $obj, 'prepareInformation', 'prepareInformation() is callable' ); + + //$result = $obj->prepareInformation ( $UsrUid, $ProUid, $TasUid); + //$t->isa_ok( $result, 'NULL', 'call to method prepareInformation '); + $t->todo( "call to method prepareInformation using $UsrUid, $ProUid, $TasUid "); + + + //checking method 'setSkipEveryYear' + $t->can_ok( $obj, 'setSkipEveryYear', 'setSkipEveryYear() is callable' ); + + //$result = $obj->setSkipEveryYear ( $bSkipEveryYear); + //$t->isa_ok( $result, 'NULL', 'call to method setSkipEveryYear '); + $t->todo( "call to method setSkipEveryYear using $bSkipEveryYear "); + + + //checking method 'addHoliday' + $t->can_ok( $obj, 'addHoliday', 'addHoliday() is callable' ); + + //$result = $obj->addHoliday ( $sDate); + //$t->isa_ok( $result, 'NULL', 'call to method addHoliday '); + $t->todo( "call to method addHoliday using $sDate "); + + + //checking method 'setHolidays' + $t->can_ok( $obj, 'setHolidays', 'setHolidays() is callable' ); + + //$result = $obj->setHolidays ( $aDates); + //$t->isa_ok( $result, 'NULL', 'call to method setHolidays '); + $t->todo( "call to method setHolidays using $aDates "); + + + //checking method 'setWeekends' + $t->can_ok( $obj, 'setWeekends', 'setWeekends() is callable' ); + + //$result = $obj->setWeekends ( $aWeekends); + //$t->isa_ok( $result, 'NULL', 'call to method setWeekends '); + $t->todo( "call to method setWeekends using $aWeekends "); + + + //checking method 'skipDayOfWeek' + $t->can_ok( $obj, 'skipDayOfWeek', 'skipDayOfWeek() is callable' ); + + //$result = $obj->skipDayOfWeek ( $iDayNumber); + //$t->isa_ok( $result, 'NULL', 'call to method skipDayOfWeek '); + $t->todo( "call to method skipDayOfWeek using $iDayNumber "); + + + //checking method 'addNonWorkingRange' + $t->can_ok( $obj, 'addNonWorkingRange', 'addNonWorkingRange() is callable' ); + + //$result = $obj->addNonWorkingRange ( $sDateA, $sDateB); + //$t->isa_ok( $result, 'NULL', 'call to method addNonWorkingRange '); + $t->todo( "call to method addNonWorkingRange using $sDateA, $sDateB "); + + + //checking method 'addDays' + $t->can_ok( $obj, 'addDays', 'addDays() is callable' ); + + //$result = $obj->addDays ( $iInitDate, $iDaysCount, $addSign); + //$t->isa_ok( $result, 'NULL', 'call to method addDays '); + $t->todo( "call to method addDays using $iInitDate, $iDaysCount, $addSign "); + + + //checking method 'addHours' + $t->can_ok( $obj, 'addHours', 'addHours() is callable' ); + + //$result = $obj->addHours ( $sInitDate, $iHoursCount, $addSign); + //$t->isa_ok( $result, 'NULL', 'call to method addHours '); + $t->todo( "call to method addHours using $sInitDate, $iHoursCount, $addSign "); + + + //checking method 'inRange' + $t->can_ok( $obj, 'inRange', 'inRange() is callable' ); + + //$result = $obj->inRange ( $iDate); + //$t->isa_ok( $result, 'NULL', 'call to method inRange '); + $t->todo( "call to method inRange using $iDate "); + + + //checking method 'truncateTime' + $t->can_ok( $obj, 'truncateTime', 'truncateTime() is callable' ); + + //$result = $obj->truncateTime ( $iDate); + //$t->isa_ok( $result, 'NULL', 'call to method truncateTime '); + $t->todo( "call to method truncateTime using $iDate "); + + + //checking method 'getTime' + $t->can_ok( $obj, 'getTime', 'getTime() is callable' ); + + //$result = $obj->getTime ( $iDate); + //$t->isa_ok( $result, 'NULL', 'call to method getTime '); + $t->todo( "call to method getTime using $iDate "); + + + //checking method 'setTime' + $t->can_ok( $obj, 'setTime', 'setTime() is callable' ); + + //$result = $obj->setTime ( $iDate, $aTime); + //$t->isa_ok( $result, 'NULL', 'call to method setTime '); + $t->todo( "call to method setTime using $iDate, $aTime "); + + + //checking method 'listForYear' + $t->can_ok( $obj, 'listForYear', 'listForYear() is callable' ); + + //$result = $obj->listForYear ( $iYear); + //$t->isa_ok( $result, 'NULL', 'call to method listForYear '); + $t->todo( "call to method listForYear using $iYear "); + + + //checking method 'changeYear' + $t->can_ok( $obj, 'changeYear', 'changeYear() is callable' ); + + //$result = $obj->changeYear ( $iDate, $iYear); + //$t->isa_ok( $result, 'NULL', 'call to method changeYear '); + $t->todo( "call to method changeYear using $iDate, $iYear "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classDbConnectionsTest.php b/workflow/engine/test/unit/processmaker/classDbConnectionsTest.php new file mode 100644 index 000000000..b8e20cdcd --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDbConnectionsTest.php @@ -0,0 +1,151 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'dbConnections'); + + + $obj = new DbConnections ($dbc); + $t = new lime_test( 23, new lime_output_color() ); + + $className = DbConnections; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + //$className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 10, "class $className have " . 10 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $pPRO_UID); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $pPRO_UID "); + + + //checking method 'getAllConnections' + $t->can_ok( $obj, 'getAllConnections', 'getAllConnections() is callable' ); + + //$result = $obj->getAllConnections ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getAllConnections '); + $t->todo( "call to method getAllConnections using "); + + + //checking method 'getConnections' + $t->can_ok( $obj, 'getConnections', 'getConnections() is callable' ); + + //$result = $obj->getConnections ( $pType); + //$t->isa_ok( $result, 'NULL', 'call to method getConnections '); + $t->todo( "call to method getConnections using $pType "); + + + //checking method 'loadAdditionalConnections' + $t->can_ok( $obj, 'loadAdditionalConnections', 'loadAdditionalConnections() is callable' ); + + //$result = $obj->loadAdditionalConnections ( ); + //$t->isa_ok( $result, 'NULL', 'call to method loadAdditionalConnections '); + $t->todo( "call to method loadAdditionalConnections using "); + + + //checking method 'getDbServicesAvailables' + $t->can_ok( $obj, 'getDbServicesAvailables', 'getDbServicesAvailables() is callable' ); + + //$result = $obj->getDbServicesAvailables ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getDbServicesAvailables '); + $t->todo( "call to method getDbServicesAvailables using "); + + + //checking method 'showMsg' + $t->can_ok( $obj, 'showMsg', 'showMsg() is callable' ); + + //$result = $obj->showMsg ( ); + //$t->isa_ok( $result, 'NULL', 'call to method showMsg '); + $t->todo( "call to method showMsg using "); + + + //checking method 'getEncondeList' + $t->can_ok( $obj, 'getEncondeList', 'getEncondeList() is callable' ); + + //$result = $obj->getEncondeList ( $engine); + //$t->isa_ok( $result, 'NULL', 'call to method getEncondeList '); + $t->todo( "call to method getEncondeList using $engine "); + + + //checking method 'getErrno' + $t->can_ok( $obj, 'getErrno', 'getErrno() is callable' ); + + //$result = $obj->getErrno ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getErrno '); + $t->todo( "call to method getErrno using "); + + + //checking method 'getErrmsg' + $t->can_ok( $obj, 'getErrmsg', 'getErrmsg() is callable' ); + + //$result = $obj->getErrmsg ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getErrmsg '); + $t->todo( "call to method getErrmsg using "); + + + //checking method 'ordx' + $t->can_ok( $obj, 'ordx', 'ordx() is callable' ); + + //$result = $obj->ordx ( $m); + //$t->isa_ok( $result, 'NULL', 'call to method ordx '); + $t->todo( "call to method ordx using $m "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classDerivationTest.php b/workflow/engine/test/unit/processmaker/classDerivationTest.php new file mode 100644 index 000000000..5648ab493 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDerivationTest.php @@ -0,0 +1,149 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadSystem ( 'testTools'); + G::LoadClass ( 'derivation'); + //G::LoadClass('task'); + //G::LoadClass('application'); + + global $dbc; + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Derivation ($dbc); + $t = new lime_test( 1 , new lime_output_color() ); + + $t->diag('class Derivation' ); + $t->isa_ok( $obj , 'Derivation', 'class Derivation created'); +/* + + //method startCase + //$t->can_ok( $obj, 'startCase', 'startCase() is callable' ); + $t->todo ( $obj ." --> startCase " ); + +// $result = $obj->startCase ( $aData); +// $t->isa_ok( $result, 'NULL', 'call to method startCase '); + + + //method prepareInformation + $t->can_ok( $obj, 'prepareInformation', 'prepareInformation() is callable' ); + +// $result = $obj->prepareInformation ( $aData); +// $t->isa_ok( $result, 'NULL', 'call to method prepareInformation '); + + + //method getNextAssignedUser + $t->can_ok( $obj, 'getNextAssignedUser', 'getNextAssignedUser() is callable' ); + +// $result = $obj->getNextAssignedUser ( $tasInfo); +// $t->isa_ok( $result, 'NULL', 'call to method getNextAssignedUser '); + + + //method derivate + $t->can_ok( $obj, 'derivate', 'derivate() is callable' ); + +// $result = $obj->derivate ( $currentDelegation, $nextDelegations); +// $t->isa_ok( $result, 'NULL', 'call to method derivate '); + + + //method isOpen + //$t->can_ok( $obj, 'isOpen', 'isOpen() is callable' ); + $t->todo( $obj ."not --> isOpen() is callable" ); + +// $result = $obj->isOpen ( $appUID, $tasUID); +// $t->isa_ok( $result, 'NULL', 'call to method isOpen '); + + + + + //$t->fail( 'review all pendings methods in this class'); + + +/***** TEST CLASS DERIVATION *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG','en'); +//Test Class +class derivationTest extends unitTest +{ + function StartCaseTest( $testCase, $Fields ) + { + global $dbc; + $der = new Derivation( $dbc ); + $result = $der->startCase( $Fields ); + return $result; + } + function DeleteCase( $testCase, $Fields ) + { + global $dbc; + $app= new Application( $dbc ); + return $app->delete( $Fields['APP_UID'] ); + } + function derivate( $testCase, &$testDomain, &$t ) + { + + } +} + +/***************************/ +die; +/***************************/ + +//Initialize the global domain (It is optional) +$testDomain = new ymlDomain(); +//Initialize the testClass ( ymlTestDefinitionFile, limeTestObject, testDomain ) +$test = new derivationTest('derivation.yml', $t, $testDomain ); +$test->load('StartCase1'); +$vAux = $test->runSingle();//var_dump($vAux);die; +$t->isa_ok( $vAux['APPLICATION'], 'string', 'Verify if APPLICATION is a string' ); +$t->is( $vAux['INDEX'], 1, 'Verify if DEL_INDEX is 1' ); +$t->isa_ok( $vAux['PROCESS'], 'string', 'Verify if PROCESS is a string' ); +/*$test->load('StartCase2'); +$test->runSingle(); +$test->load('StartCase3'); +$test->runSingle(); +$test->load('StartCase4'); +$test->runSingle(); +$test->load('StartCase5'); +$test->runSingle();*/ +//$test->load('DeleteCreatedApplications'); +//$test->runAll(); diff --git a/workflow/engine/test/unit/processmaker/classDynaFormFieldTest.php b/workflow/engine/test/unit/processmaker/classDynaFormFieldTest.php new file mode 100644 index 000000000..982478260 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDynaFormFieldTest.php @@ -0,0 +1,82 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadClass ( 'dynaFormField'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new DynaFormField ($dbc); + $t = new lime_test( 6, new lime_output_color() ); + + $t->diag('class DynaFormField' ); + $t->isa_ok( $obj , 'DynaFormField', 'class DynaFormField created'); + + //method Load + $t->can_ok( $obj, 'Load', 'Load() is callable' ); + + // $result = $obj->Load ( $sUID); + // $t->isa_ok( $result, 'NULL', 'call to method Load '); + + + //method Delete + $t->can_ok( $obj, 'Delete', 'Delete() is callable' ); + + // $result = $obj->Delete ( $uid); + // $t->isa_ok( $result, 'NULL', 'call to method Delete '); + + + //method Save + $t->can_ok( $obj, 'Save', 'Save() is callable' ); + + // $result = $obj->Save ( $Fields, $labels, $options); + // $t->isa_ok( $result, 'NULL', 'call to method Save '); + + + //method isNew + $t->can_ok( $obj, 'isNew', 'isNew() is callable' ); + + // $result = $obj->isNew ( ); + // $t->isa_ok( $result, 'NULL', 'call to method isNew '); + + + //$t->fail( 'review all pendings methods in this class'); + $t->todo( "review all pendings methods in this class" ); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classDynaformTest.php b/workflow/engine/test/unit/processmaker/classDynaformTest.php new file mode 100644 index 000000000..79eae77eb --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classDynaformTest.php @@ -0,0 +1,120 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + Propel::init( PATH_CORE . "config/databases.php"); + + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'testTools'); + + require_once( PATH_CORE.'/classes/model/Dynaform.php'); + + $obj = new Dynaform (); + $t = new lime_test( 18, new lime_output_color() ); + + $t->diag('class Dynaform' ); + $t->isa_ok( $obj , 'Dynaform', 'class Dynaform created'); + + //method load + //#2 + $t->can_ok( $obj, 'getDynTitle', 'getDynTitle() is callable' ); + //#3 + $t->can_ok( $obj, 'setDynTitle', 'setDynTitle() is callable' ); + //#4 + $t->can_ok( $obj, 'getDynDescription', 'getDynDescription() is callable' ); + //#5 + $t->can_ok( $obj, 'setDynDescription', 'setDynDescription() is callable' ); + //#6 + $t->can_ok( $obj, 'create', 'create() is callable' ); + //#7 + $t->can_ok( $obj, 'update', 'update() is callable' ); + //#8 + $t->can_ok( $obj, 'load', 'load() is callable' ); + //#9 + $t->can_ok( $obj, 'remove', 'remove() is callable' ); + + //getDynUid + //#10 + $t->is( $obj->getDynUid(), '', 'getDynUid() return empty, when the instance doesnt have any row' ); + + //getDynTitle + try { + $obj = new Dynaform (); + $res = $obj->getDynTitle(); + } + catch ( Exception $e ) { + //#11 + $t->isa_ok( $e, 'Exception', 'getDynTitle() return error when DYN_UID is not defined' ); + //#12 + $t->is ( $e->getMessage(), "Error in getDynTitle, the DYN_UID can't be blank", 'getDynTitle() return Error in getDynTitle, the DYN_UID cant be blank' ); + } + + //setDynDescription + try { + $obj = new Dynaform (); + $obj->setDynDescription('x'); + } + catch ( Exception $e ) { + //#13 + $t->isa_ok( $e, 'Exception', 'setDynDescription() return error when DYN_UID is not defined' ); + //#14 + $t->is ( $e->getMessage(), "Error in setDynDescription, the DYN_UID can't be blank", 'setDynDescription() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //getDynDescription + try { + $obj = new Dynaform (); + $res = $obj->getDynDescription(); + } + catch ( Exception $e ) { + //#15 + $t->isa_ok( $e, 'Exception', 'getDynDescription() return error when DYN_UID is not defined' ); + //#16 + $t->is ( $e->getMessage(), "Error in getDynDescription, the DYN_UID can't be blank", 'getDynDescription() return Error in getDynDescription, the DYN_UID cant be blank' ); + } + + //setAppDescription + try { + $obj = new Dynaform (); + $obj->setDynDescription('x'); + } + catch ( Exception $e ) { + //#17 + $t->isa_ok( $e, 'Exception', 'setAppDescription() return error when DYN_UID is not defined' ); + //#18 + $t->is ( $e->getMessage(), "Error in setDynDescription, the DYN_UID can't be blank", 'setAppDescription() return Error in getAppDescription, the APP_UID cant be blank' ); + } + + + diff --git a/workflow/engine/test/unit/processmaker/classESMTPTest.php b/workflow/engine/test/unit/processmaker/classESMTPTest.php new file mode 100644 index 000000000..81ec6eb6f --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classESMTPTest.php @@ -0,0 +1,242 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'smtp.rfc-821'); + + + //$obj = new ESMTP ($dbc); + $t = new lime_test( 44, new lime_output_color() ); + + $className = ESMTP; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 21, "class $className have " . 21 . ' methods.' ); + + // Methods $t->is ( $aMethods[0], + $aMethods = array_keys ( $methods ); + + //checking method 'ESMTP' + $t->is ( $aMethods[0], 'ESMTP', 'ESMTP() is callable' ); + + //$result = $obj->ESMTP ( ); + //$t->isa_ok( $result, 'NULL', 'call to method ESMTP '); + $t->todo( "call to method ESMTP using "); + + + //checking method 'Connect' + $t->is ( $aMethods[1], 'Connect', 'Connect() is callable' ); + + //$result = $obj->Connect ( $host, $port, $tval); + //$t->isa_ok( $result, 'NULL', 'call to method Connect '); + $t->todo( "call to method Connect using $host, $port, $tval "); + + + //checking method 'Authenticate' + $t->is ( $aMethods[2], 'Authenticate', 'Authenticate() is callable' ); + + //$result = $obj->Authenticate ( $username, $password); + //$t->isa_ok( $result, 'NULL', 'call to method Authenticate '); + $t->todo( "call to method Authenticate using $username, $password "); + + + //checking method 'Connected' + $t->is ( $aMethods[3], 'Connected', 'Connected() is callable' ); + + //$result = $obj->Connected ( ); + //$t->isa_ok( $result, 'NULL', 'call to method Connected '); + $t->todo( "call to method Connected using "); + + + //checking method 'Close' + $t->is ( $aMethods[4], 'Close', 'Close() is callable' ); + + //$result = $obj->Close ( ); + //$t->isa_ok( $result, 'NULL', 'call to method Close '); + $t->todo( "call to method Close using "); + + + //checking method 'Data' + $t->is ( $aMethods[5], 'Data', 'Data() is callable' ); + + //$result = $obj->Data ( $msg_data); + //$t->isa_ok( $result, 'NULL', 'call to method Data '); + $t->todo( "call to method Data using $msg_data "); + + + //checking method 'Expand' + $t->is ( $aMethods[6], 'Expand', 'Expand() is callable' ); + + //$result = $obj->Expand ( $name); + //$t->isa_ok( $result, 'NULL', 'call to method Expand '); + $t->todo( "call to method Expand using $name "); + + + //checking method 'Hello' + $t->is ( $aMethods[7], 'Hello', 'Hello() is callable' ); + + //$result = $obj->Hello ( $host); + //$t->isa_ok( $result, 'NULL', 'call to method Hello '); + $t->todo( "call to method Hello using $host "); + + + //checking method 'SendHello' + $t->is ( $aMethods[8], 'SendHello', 'SendHello() is callable' ); + + //$result = $obj->SendHello ( $hello, $host); + //$t->isa_ok( $result, 'NULL', 'call to method SendHello '); + $t->todo( "call to method SendHello using $hello, $host "); + + + //checking method 'Help' + $t->is ( $aMethods[9], 'Help', 'Help() is callable' ); + + //$result = $obj->Help ( $keyword); + //$t->isa_ok( $result, 'NULL', 'call to method Help '); + $t->todo( "call to method Help using $keyword "); + + + //checking method 'Mail' + $t->is ( $aMethods[10], 'Mail', 'Mail() is callable' ); + + //$result = $obj->Mail ( $from); + //$t->isa_ok( $result, 'NULL', 'call to method Mail '); + $t->todo( "call to method Mail using $from "); + + + //checking method 'Noop' + $t->is ( $aMethods[11], 'Noop', 'Noop() is callable' ); + + //$result = $obj->Noop ( ); + //$t->isa_ok( $result, 'NULL', 'call to method Noop '); + $t->todo( "call to method Noop using "); + + + //checking method 'Quit' + $t->is ( $aMethods[12], 'Quit', 'Quit() is callable' ); + + //$result = $obj->Quit ( $close_on_error); + //$t->isa_ok( $result, 'NULL', 'call to method Quit '); + $t->todo( "call to method Quit using $close_on_error "); + + + //checking method 'Recipient' + $t->is ( $aMethods[13], 'Recipient', 'Recipient() is callable' ); + + //$result = $obj->Recipient ( $to); + //$t->isa_ok( $result, 'NULL', 'call to method Recipient '); + $t->todo( "call to method Recipient using $to "); + + + //checking method 'Reset' + $t->is ( $aMethods[14], 'Reset', 'Reset() is callable' ); + + //$result = $obj->Reset ( ); + //$t->isa_ok( $result, 'NULL', 'call to method Reset '); + $t->todo( "call to method Reset using "); + + + //checking method 'Send' + $t->is ( $aMethods[15], 'Send', 'Send() is callable' ); + + //$result = $obj->Send ( $from); + //$t->isa_ok( $result, 'NULL', 'call to method Send '); + $t->todo( "call to method Send using $from "); + + + //checking method 'SendAndMail' + $t->is ( $aMethods[16], 'SendAndMail', 'SendAndMail() is callable' ); + + //$result = $obj->SendAndMail ( $from); + //$t->isa_ok( $result, 'NULL', 'call to method SendAndMail '); + $t->todo( "call to method SendAndMail using $from "); + + + //checking method 'SendOrMail' + $t->is ( $aMethods[17], 'SendOrMail', 'SendOrMail() is callable' ); + + //$result = $obj->SendOrMail ( $from); + //$t->isa_ok( $result, 'NULL', 'call to method SendOrMail '); + $t->todo( "call to method SendOrMail using $from "); + + + //checking method 'Turn' + $t->is ( $aMethods[18], 'Turn', 'Turn() is callable' ); + + //$result = $obj->Turn ( ); + //$t->isa_ok( $result, 'NULL', 'call to method Turn '); + $t->todo( "call to method Turn using "); + + + //checking method 'Verify' + $t->is ( $aMethods[19], 'Verify', 'Verify() is callable' ); + + //$result = $obj->Verify ( $name); + //$t->isa_ok( $result, 'NULL', 'call to method Verify '); + $t->todo( "call to method Verify using $name "); + + + //checking method 'get_lines' + $t->is ( $aMethods[20], 'get_lines', 'get_lines() is callable' ); + + //$result = $obj->get_lines ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_lines '); + $t->todo( "call to method get_lines using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classGroupTest.php b/workflow/engine/test/unit/processmaker/classGroupTest.php new file mode 100644 index 000000000..d23e63794 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classGroupTest.php @@ -0,0 +1,77 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + Propel::init( PATH_CORE . "config/databases.php"); + + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'testTools'); + + require_once( PATH_CORE.'/classes/model/Groupwf.php'); + + $obj = new Groupwf (); + $t = new lime_test( 10, new lime_output_color() ); + + $t->diag('class Groupwf' ); + $t->isa_ok( $obj , 'Groupwf', 'class Groupwf created'); + + //method load + //#2 + $t->can_ok( $obj, 'getGrpTitle', 'getGrpTitle() is callable' ); + //#3 + $t->can_ok( $obj, 'setGrpTitle', 'setGrpTitle() is callable' ); + //#4 + $t->can_ok( $obj, 'create', 'create() is callable' ); + //#5 + $t->can_ok( $obj, 'update', 'update() is callable' ); + //#6 + $t->can_ok( $obj, 'load', 'load() is callable' ); + //#7 + $t->can_ok( $obj, 'remove', 'remove() is callable' ); + + //getGrpUid + //#8 + $t->is( $obj->getGrpUid(), '', 'getGrpUid() return empty, when the instance doesnt have any row' ); + + //getGrpTitle + try { + $obj = new Groupwf (); + $res = $obj->getGrpTitle(); + } + catch ( Exception $e ) { + //#9 + $t->isa_ok( $e, 'Exception', 'getGrpTitle() return error when GRP_UID is not defined' ); + //#10 + $t->is ( $e->getMessage(), "Error in getGrpTitle, the GRP_UID can't be blank", 'getGrpTitle() return Error in getGrpTitle, the GRP_UID cant be blank' ); + } diff --git a/workflow/engine/test/unit/processmaker/classGroupUserTest.php b/workflow/engine/test/unit/processmaker/classGroupUserTest.php new file mode 100644 index 000000000..60c00f9fb --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classGroupUserTest.php @@ -0,0 +1,98 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once(PATH_THIRDPARTY . '/lime/lime.php'); + require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + + require_once(PATH_CORE . 'config/databases.php'); + require_once('propel/Propel.php'); + Propel::init(PATH_CORE . 'config/databases.php'); + + G::LoadThirdParty('smarty/libs', 'Smarty.class'); + G::LoadSystem('error'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('form'); + G::LoadSystem('dbtable'); + G::LoadSystem('testTools'); + require_once(PATH_CORE . 'classes/model/GroupUser.php'); + + $obj = new GroupUser(); + $t = new lime_test(3, new lime_output_color()); + + $t->diag('Class GroupUser'); + + //class GroupUser + $t->isa_ok($obj, 'GroupUser', 'Class GroupUser created!'); + + //method create + $t->can_ok($obj, 'create', 'create() is callable!'); + + //method remove + $t->can_ok($obj, 'remove', 'remove() is callable!'); + + /***** TEST CLASS GROUPUSER *****/ + ///////// INITIAL VALUES ///////// + define('SYS_LANG', 'en'); + //Test class + class GroupUserTest extends unitTest + { + function createTest($aTestData, $aFields) + { + $oGroupUser = new GroupUser(); + try { + return $oGroupUser->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oGroupUser = new GroupUser(); + try { + return $oGroupUser->remove($aFields['GRP_UID'], $aFields['USR_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + } + //Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) + $oGroupUserTest = new GroupUserTest('groupUser.yml', $t, new ymlDomain()); + $oGroupUserTest->load('create1'); + $vAux = $oGroupUserTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oGroupUserTest->load('create2'); + $vAux = $oGroupUserTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oGroupUserTest->load('remove1'); + $vAux = $oGroupUserTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + $oGroupUserTest->load('remove2'); + $vAux = $oGroupUserTest->runSingle(); + //var_dump($vAux);echo "\n\n"; + ?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classGroupsTest.php b/workflow/engine/test/unit/processmaker/classGroupsTest.php new file mode 100644 index 000000000..8c6349685 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classGroupsTest.php @@ -0,0 +1,175 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'groups'); + + + $obj = new Groups ($dbc); + $t = new lime_test( 29, new lime_output_color() ); + + $className = Groups; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 14, "class $className have " . 14 . ' methods.' ); + + //checking method 'getUsersOfGroup' + $t->can_ok( $obj, 'getUsersOfGroup', 'getUsersOfGroup() is callable' ); + + //$result = $obj->getUsersOfGroup ( $sGroupUID); + //$t->isa_ok( $result, 'NULL', 'call to method getUsersOfGroup '); + $t->todo( "call to method getUsersOfGroup using $sGroupUID "); + + + //checking method 'getActiveGroupsForAnUser' + $t->can_ok( $obj, 'getActiveGroupsForAnUser', 'getActiveGroupsForAnUser() is callable' ); + + //$result = $obj->getActiveGroupsForAnUser ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getActiveGroupsForAnUser '); + $t->todo( "call to method getActiveGroupsForAnUser using $sUserUID "); + + + //checking method 'addUserToGroup' + $t->can_ok( $obj, 'addUserToGroup', 'addUserToGroup() is callable' ); + + //$result = $obj->addUserToGroup ( $GrpUid, $UsrUid); + //$t->isa_ok( $result, 'NULL', 'call to method addUserToGroup '); + $t->todo( "call to method addUserToGroup using $GrpUid, $UsrUid "); + + + //checking method 'removeUserOfGroup' + $t->can_ok( $obj, 'removeUserOfGroup', 'removeUserOfGroup() is callable' ); + + //$result = $obj->removeUserOfGroup ( $GrpUid, $UsrUid); + //$t->isa_ok( $result, 'NULL', 'call to method removeUserOfGroup '); + $t->todo( "call to method removeUserOfGroup using $GrpUid, $UsrUid "); + + + //checking method 'getAllGroups' + $t->can_ok( $obj, 'getAllGroups', 'getAllGroups() is callable' ); + + //$result = $obj->getAllGroups ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getAllGroups '); + $t->todo( "call to method getAllGroups using "); + + + //checking method 'getUserGroups' + $t->can_ok( $obj, 'getUserGroups', 'getUserGroups() is callable' ); + + //$result = $obj->getUserGroups ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getUserGroups '); + $t->todo( "call to method getUserGroups using $sUserUID "); + + + //checking method 'removeUserOfAllGroups' + $t->can_ok( $obj, 'removeUserOfAllGroups', 'removeUserOfAllGroups() is callable' ); + + //$result = $obj->removeUserOfAllGroups ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method removeUserOfAllGroups '); + $t->todo( "call to method removeUserOfAllGroups using $sUserUID "); + + + //checking method 'getUsersGroupCriteria' + $t->can_ok( $obj, 'getUsersGroupCriteria', 'getUsersGroupCriteria() is callable' ); + + //$result = $obj->getUsersGroupCriteria ( $sGroupUID); + //$t->isa_ok( $result, 'NULL', 'call to method getUsersGroupCriteria '); + $t->todo( "call to method getUsersGroupCriteria using $sGroupUID "); + + + //checking method 'getUserGroupsCriteria' + $t->can_ok( $obj, 'getUserGroupsCriteria', 'getUserGroupsCriteria() is callable' ); + + //$result = $obj->getUserGroupsCriteria ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getUserGroupsCriteria '); + $t->todo( "call to method getUserGroupsCriteria using $sUserUID "); + + + //checking method 'getNumberGroups' + $t->can_ok( $obj, 'getNumberGroups', 'getNumberGroups() is callable' ); + + //$result = $obj->getNumberGroups ( $sUserUID); + //$t->isa_ok( $result, 'NULL', 'call to method getNumberGroups '); + $t->todo( "call to method getNumberGroups using $sUserUID "); + + + //checking method 'getAvailableUsersCriteria' + $t->can_ok( $obj, 'getAvailableUsersCriteria', 'getAvailableUsersCriteria() is callable' ); + + //$result = $obj->getAvailableUsersCriteria ( $sGroupUID); + //$t->isa_ok( $result, 'NULL', 'call to method getAvailableUsersCriteria '); + $t->todo( "call to method getAvailableUsersCriteria using $sGroupUID "); + + + //checking method 'verifyUsertoGroup' + $t->can_ok( $obj, 'verifyUsertoGroup', 'verifyUsertoGroup() is callable' ); + + //$result = $obj->verifyUsertoGroup ( $GrpUid, $UsrUid); + //$t->isa_ok( $result, 'NULL', 'call to method verifyUsertoGroup '); + $t->todo( "call to method verifyUsertoGroup using $GrpUid, $UsrUid "); + + + //checking method 'verifyGroup' + $t->can_ok( $obj, 'verifyGroup', 'verifyGroup() is callable' ); + + //$result = $obj->verifyGroup ( $sGroupUID); + //$t->isa_ok( $result, 'NULL', 'call to method verifyGroup '); + $t->todo( "call to method verifyGroup using $sGroupUID "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classInputDocumentTest.php b/workflow/engine/test/unit/processmaker/classInputDocumentTest.php new file mode 100644 index 000000000..0a8047c3f --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classInputDocumentTest.php @@ -0,0 +1,148 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . '/lime/lime.php'); +require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadSystem('testTools'); +require_once(PATH_CORE . 'classes/model/InputDocument.php'); + +$obj = new InputDocument(); +$t = new lime_test(9, new lime_output_color()); + +$t->diag('Class InputDocument'); + +//class InputDocument +$t->isa_ok($obj, 'InputDocument', 'Class InputDocument created!'); + +//method load +$t->can_ok($obj, 'load', 'load() is callable!'); + +//method create +$t->can_ok($obj, 'create', 'create() is callable!'); + +//method update +$t->can_ok($obj, 'update', 'update() is callable!'); + +//method remove +$t->can_ok($obj, 'remove', 'remove() is callable!'); + +//method getInpDocTitle +$t->can_ok($obj, 'getInpDocTitle', 'getInpDocTitle() is callable!'); + +//method setInpDocTitle +$t->can_ok($obj, 'setInpDocTitle', 'setInpDocTitle() is callable!'); + +//method getInpDocComment +$t->can_ok($obj, 'getInpDocDescription', 'getInpDocDescription() is callable!'); + +//method setInpDocComment +$t->can_ok($obj, 'setInpDocDescription', 'setInpDocDescription() is callable!'); + +/***** TEST CLASS INPUTDOCUMENT *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class InputDocumentTest extends unitTest +{ + function loadTest($aTestData, $aFields) + { + $oInputDocument = new InputDocument(); + try { + return $oInputDocument->load($aFields['INP_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createTest($aTestData, $aFields) + { + $oInputDocument = new InputDocument(); + try { + return $oInputDocument->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTest($aTestData, $aFields) + { + $oInputDocument = new InputDocument(); + try { + return $oInputDocument->update($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oInputDocument = new InputDocument(); + try { + return $oInputDocument->remove($aFields['INP_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oInputDocumentTest = new InputDocumentTest('inputDocument.yml', $t, new ymlDomain()); +$oInputDocumentTest->load('load1'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('load2'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('create1'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('create2'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('update1'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('update2'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('remove1'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oInputDocumentTest->load('remove2'); +$vAux = $oInputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classInsertTest.php b/workflow/engine/test/unit/processmaker/classInsertTest.php new file mode 100644 index 000000000..e5ad39f25 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classInsertTest.php @@ -0,0 +1,72 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + //$className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 3, "class $className have " . 3 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $db_spool); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $db_spool "); + + + //checking method 'returnStatus' + $t->can_ok( $obj, 'returnStatus', 'returnStatus() is callable' ); + + //$result = $obj->returnStatus ( ); + //$t->isa_ok( $result, 'NULL', 'call to method returnStatus '); + $t->todo( "call to method returnStatus using "); + + + //checking method 'db_insert' + $t->can_ok( $obj, 'db_insert', 'db_insert() is callable' ); + + //$result = $obj->db_insert ( $db_spool); + //$t->isa_ok( $result, 'NULL', 'call to method db_insert '); + $t->todo( "call to method db_insert using $db_spool "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classInstallerTest.php b/workflow/engine/test/unit/processmaker/classInstallerTest.php new file mode 100644 index 000000000..5222f913c --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classInstallerTest.php @@ -0,0 +1,178 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag( '$className' ); + + $t->isa_ok( $obj , 'Installer', 'class $className created'); + + $t->is( count($methods) , 16, "class $className have " . 16 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( ); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using "); + + + //checking method 'create_site' + $t->can_ok( $obj, 'create_site', 'create_site() is callable' ); + + //$result = $obj->create_site ( $config, $confirmed); + //$t->isa_ok( $result, 'NULL', 'call to method create_site '); + $t->todo( "call to method create_site using $config, $confirmed "); + + + //checking method 'isset_site' + $t->can_ok( $obj, 'isset_site', 'isset_site() is callable' ); + + //$result = $obj->isset_site ( $name); + //$t->isa_ok( $result, 'NULL', 'call to method isset_site '); + $t->todo( "call to method isset_site using $name "); + + + //checking method 'create_site_test' + $t->can_ok( $obj, 'create_site_test', 'create_site_test() is callable' ); + + //$result = $obj->create_site_test ( ); + //$t->isa_ok( $result, 'NULL', 'call to method create_site_test '); + $t->todo( "call to method create_site_test using "); + + + //checking method 'make_site' + $t->can_ok( $obj, 'make_site', 'make_site() is callable' ); + + //$result = $obj->make_site ( ); + //$t->isa_ok( $result, 'NULL', 'call to method make_site '); + $t->todo( "call to method make_site using "); + + + //checking method 'set_admin' + $t->can_ok( $obj, 'set_admin', 'set_admin() is callable' ); + + //$result = $obj->set_admin ( ); + //$t->isa_ok( $result, 'NULL', 'call to method set_admin '); + $t->todo( "call to method set_admin using "); + + + //checking method 'query_sql_file' + $t->can_ok( $obj, 'query_sql_file', 'query_sql_file() is callable' ); + + //$result = $obj->query_sql_file ( $file, $connection); + //$t->isa_ok( $result, 'NULL', 'call to method query_sql_file '); + $t->todo( "call to method query_sql_file using $file, $connection "); + + + //checking method 'check_path' + $t->can_ok( $obj, 'check_path', 'check_path() is callable' ); + + //$result = $obj->check_path ( ); + //$t->isa_ok( $result, 'NULL', 'call to method check_path '); + $t->todo( "call to method check_path using "); + + + //checking method 'find_root_path' + $t->can_ok( $obj, 'find_root_path', 'find_root_path() is callable' ); + + //$result = $obj->find_root_path ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method find_root_path '); + $t->todo( "call to method find_root_path using $path "); + + + //checking method 'file_permisions' + $t->can_ok( $obj, 'file_permisions', 'file_permisions() is callable' ); + + //$result = $obj->file_permisions ( $file, $def); + //$t->isa_ok( $result, 'NULL', 'call to method file_permisions '); + $t->todo( "call to method file_permisions using $file, $def "); + + + //checking method 'is_dir_writable' + $t->can_ok( $obj, 'is_dir_writable', 'is_dir_writable() is callable' ); + + //$result = $obj->is_dir_writable ( $dir); + //$t->isa_ok( $result, 'NULL', 'call to method is_dir_writable '); + $t->todo( "call to method is_dir_writable using $dir "); + + + //checking method 'getDirectoryFiles' + $t->can_ok( $obj, 'getDirectoryFiles', 'getDirectoryFiles() is callable' ); + + //$result = $obj->getDirectoryFiles ( $dir, $extension); + //$t->isa_ok( $result, 'NULL', 'call to method getDirectoryFiles '); + $t->todo( "call to method getDirectoryFiles using $dir, $extension "); + + + //checking method 'check_db_empty' + $t->can_ok( $obj, 'check_db_empty', 'check_db_empty() is callable' ); + + //$result = $obj->check_db_empty ( $dbName); + //$t->isa_ok( $result, 'NULL', 'call to method check_db_empty '); + $t->todo( "call to method check_db_empty using $dbName "); + + + //checking method 'check_db' + $t->can_ok( $obj, 'check_db', 'check_db() is callable' ); + + //$result = $obj->check_db ( $dbName); + //$t->isa_ok( $result, 'NULL', 'call to method check_db '); + $t->todo( "call to method check_db using $dbName "); + + + //checking method 'check_connection' + $t->can_ok( $obj, 'check_connection', 'check_connection() is callable' ); + + //$result = $obj->check_connection ( ); + //$t->isa_ok( $result, 'NULL', 'call to method check_connection '); + $t->todo( "call to method check_connection using "); + + + //checking method 'log' + $t->can_ok( $obj, 'log', 'log() is callable' ); + + //$result = $obj->log ( $text); + //$t->isa_ok( $result, 'NULL', 'call to method log '); + $t->todo( "call to method log using $text "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classJavaBridgePMTest.php b/workflow/engine/test/unit/processmaker/classJavaBridgePMTest.php new file mode 100644 index 000000000..feac82fda --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classJavaBridgePMTest.php @@ -0,0 +1,73 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , 'JavaBridgePM', 'class $className created'); + + $t->is( count($methods) , 3, "class $className have " . 3 . ' methods.' ); + + //checking method 'checkJavaExtension' + $t->can_ok( $obj, 'checkJavaExtension', 'checkJavaExtension() is callable' ); + + //$result = $obj->checkJavaExtension ( ); + //$t->isa_ok( $result, 'NULL', 'call to method checkJavaExtension '); + $t->todo( "call to method checkJavaExtension using "); + + + //checking method 'convertValue' + $t->can_ok( $obj, 'convertValue', 'convertValue() is callable' ); + + //$result = $obj->convertValue ( $value, $className); + //$t->isa_ok( $result, 'NULL', 'call to method convertValue '); + $t->todo( "call to method convertValue using $value, $className "); + + + //checking method 'generateJrxmlFromDynaform' + $t->can_ok( $obj, 'generateJrxmlFromDynaform', 'generateJrxmlFromDynaform() is callable' ); + + //$result = $obj->generateJrxmlFromDynaform ( $outDocUid, $dynaformUid, $template); + //$t->isa_ok( $result, 'NULL', 'call to method generateJrxmlFromDynaform '); + $t->todo( "call to method generateJrxmlFromDynaform using $outDocUid, $dynaformUid, $template "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classJrmlTest.php b/workflow/engine/test/unit/processmaker/classJrmlTest.php new file mode 100644 index 000000000..46daa8692 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classJrmlTest.php @@ -0,0 +1,113 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , 'Jrml', 'class $className created'); + + $t->is( count($methods) , 8, "class $className have " . 8 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $data); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $data "); + + + //checking method 'get_rows' + $t->can_ok( $obj, 'get_rows', 'get_rows() is callable' ); + + //$result = $obj->get_rows ( $a); + //$t->isa_ok( $result, 'NULL', 'call to method get_rows '); + $t->todo( "call to method get_rows using $a "); + + + //checking method 'get_md' + $t->can_ok( $obj, 'get_md', 'get_md() is callable' ); + + //$result = $obj->get_md ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_md '); + $t->todo( "call to method get_md using "); + + + //checking method 'get_header' + $t->can_ok( $obj, 'get_header', 'get_header() is callable' ); + + //$result = $obj->get_header ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_header '); + $t->todo( "call to method get_header using "); + + + //checking method 'get_column_header' + $t->can_ok( $obj, 'get_column_header', 'get_column_header() is callable' ); + + //$result = $obj->get_column_header ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_column_header '); + $t->todo( "call to method get_column_header using "); + + + //checking method 'get_detail' + $t->can_ok( $obj, 'get_detail', 'get_detail() is callable' ); + + //$result = $obj->get_detail ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_detail '); + $t->todo( "call to method get_detail using "); + + + //checking method 'get_footer' + $t->can_ok( $obj, 'get_footer', 'get_footer() is callable' ); + + //$result = $obj->get_footer ( ); + //$t->isa_ok( $result, 'NULL', 'call to method get_footer '); + $t->todo( "call to method get_footer using "); + + + //checking method 'export' + $t->can_ok( $obj, 'export', 'export() is callable' ); + + //$result = $obj->export ( ); + //$t->isa_ok( $result, 'NULL', 'call to method export '); + $t->todo( "call to method export using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classLanguagesTest.php b/workflow/engine/test/unit/processmaker/classLanguagesTest.php new file mode 100644 index 000000000..91f2c8f9f --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classLanguagesTest.php @@ -0,0 +1,56 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , "languages", "class $className created"); + + $t->is( count($methods) , 1, "class $className have " . 1 . ' methods.' ); + + //checking method 'importLanguage' + $t->can_ok( $obj, 'importLanguage', 'importLanguage() is callable' ); + + //$result = $obj->importLanguage ( $sLanguageFile, $bXml); + //$t->isa_ok( $result, 'NULL', 'call to method importLanguage '); + $t->todo( "call to method importLanguage using $sLanguageFile, $bXml "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classMenuDetailTest.php b/workflow/engine/test/unit/processmaker/classMenuDetailTest.php new file mode 100644 index 000000000..994f1a608 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classMenuDetailTest.php @@ -0,0 +1,57 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 1, "class $className have " . 1 . ' methods.' ); + // Methods + $aMethods = array_keys ( $methods ); + //checking method '__construct' + $t->is ( $aMethods[0], '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $sNamespace, $sMenuId, $sFilename); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $sNamespace, $sMenuId, $sFilename "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classNetTest.php b/workflow/engine/test/unit/processmaker/classNetTest.php new file mode 100644 index 000000000..38e210696 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classNetTest.php @@ -0,0 +1,161 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , 'NET', 'class $className created'); + + $t->is( count($methods) , 14, "class $className have " . 14 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $pHost); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $pHost "); + + + //checking method 'resolv' + $t->can_ok( $obj, 'resolv', 'resolv() is callable' ); + + //$result = $obj->resolv ( $pHost); + //$t->isa_ok( $result, 'NULL', 'call to method resolv '); + $t->todo( "call to method resolv using $pHost "); + + + //checking method 'scannPort' + $t->can_ok( $obj, 'scannPort', 'scannPort() is callable' ); + + //$result = $obj->scannPort ( $pPort); + //$t->isa_ok( $result, 'NULL', 'call to method scannPort '); + $t->todo( "call to method scannPort using $pPort "); + + + //checking method 'is_ipaddress' + $t->can_ok( $obj, 'is_ipaddress', 'is_ipaddress() is callable' ); + + //$result = $obj->is_ipaddress ( $pHost); + //$t->isa_ok( $result, 'NULL', 'call to method is_ipaddress '); + $t->todo( "call to method is_ipaddress using $pHost "); + + + //checking method 'ping' + $t->can_ok( $obj, 'ping', 'ping() is callable' ); + + //$result = $obj->ping ( $pTTL); + //$t->isa_ok( $result, 'NULL', 'call to method ping '); + $t->todo( "call to method ping using $pTTL "); + + + //checking method 'loginDbServer' + $t->can_ok( $obj, 'loginDbServer', 'loginDbServer() is callable' ); + + //$result = $obj->loginDbServer ( $pUser, $pPasswd); + //$t->isa_ok( $result, 'NULL', 'call to method loginDbServer '); + $t->todo( "call to method loginDbServer using $pUser, $pPasswd "); + + + //checking method 'setDataBase' + $t->can_ok( $obj, 'setDataBase', 'setDataBase() is callable' ); + + //$result = $obj->setDataBase ( $pDb, $pPort); + //$t->isa_ok( $result, 'NULL', 'call to method setDataBase '); + $t->todo( "call to method setDataBase using $pDb, $pPort "); + + + //checking method 'tryConnectServer' + $t->can_ok( $obj, 'tryConnectServer', 'tryConnectServer() is callable' ); + + //$result = $obj->tryConnectServer ( $pDbDriver); + //$t->isa_ok( $result, 'NULL', 'call to method tryConnectServer '); + $t->todo( "call to method tryConnectServer using $pDbDriver "); + + + //checking method 'tryOpenDataBase' + $t->can_ok( $obj, 'tryOpenDataBase', 'tryOpenDataBase() is callable' ); + + //$result = $obj->tryOpenDataBase ( $pDbDriver); + //$t->isa_ok( $result, 'NULL', 'call to method tryOpenDataBase '); + $t->todo( "call to method tryOpenDataBase using $pDbDriver "); + + + //checking method 'getDbServerVersion' + $t->can_ok( $obj, 'getDbServerVersion', 'getDbServerVersion() is callable' ); + + //$result = $obj->getDbServerVersion ( $driver); + //$t->isa_ok( $result, 'NULL', 'call to method getDbServerVersion '); + $t->todo( "call to method getDbServerVersion using $driver "); + + + //checking method 'dbName' + $t->can_ok( $obj, 'dbName', 'dbName() is callable' ); + + //$result = $obj->dbName ( $pAdapter); + //$t->isa_ok( $result, 'NULL', 'call to method dbName '); + $t->todo( "call to method dbName using $pAdapter "); + + + //checking method 'showMsg' + $t->can_ok( $obj, 'showMsg', 'showMsg() is callable' ); + + //$result = $obj->showMsg ( ); + //$t->isa_ok( $result, 'NULL', 'call to method showMsg '); + $t->todo( "call to method showMsg using "); + + + //checking method 'getErrno' + $t->can_ok( $obj, 'getErrno', 'getErrno() is callable' ); + + //$result = $obj->getErrno ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getErrno '); + $t->todo( "call to method getErrno using "); + + + //checking method 'getErrmsg' + $t->can_ok( $obj, 'getErrmsg', 'getErrmsg() is callable' ); + + //$result = $obj->getErrmsg ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getErrmsg '); + $t->todo( "call to method getErrmsg using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classOutputDocumentTest.php b/workflow/engine/test/unit/processmaker/classOutputDocumentTest.php new file mode 100644 index 000000000..a9fa293f4 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classOutputDocumentTest.php @@ -0,0 +1,160 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . '/lime/lime.php'); +require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadSystem('testTools'); +require_once(PATH_CORE . 'classes/model/OutputDocument.php'); + +$obj = new OutputDocument(); +$t = new lime_test(21, new lime_output_color()); + +$t->diag('Class OutputDocument'); + +//class OutputDocument +$t->isa_ok($obj, 'OutputDocument', 'Class OutputDocument created!'); + +//method load +$t->can_ok($obj, 'load', 'load() is callable!'); + +//method create +$t->can_ok($obj, 'create', 'create() is callable!'); + +//method update +$t->can_ok($obj, 'update', 'update() is callable!'); + +//method remove +$t->can_ok($obj, 'remove', 'remove() is callable!'); + +//method getOutDocTitle +$t->can_ok($obj, 'getOutDocTitle', 'getOutDocTitle() is callable!'); + +//method setOutDocTitle +$t->can_ok($obj, 'setOutDocTitle', 'setOutDocTitle() is callable!'); + +//method getOutDocComment +$t->can_ok($obj, 'getOutDocDescription', 'getOutDocDescription() is callable!'); + +//method setOutDocComment +$t->can_ok($obj, 'setOutDocDescription', 'setOutDocDescription() is callable!'); + +//method getOutDocFilename +$t->can_ok($obj, 'getOutDocFilename', 'getOutDocFilename() is callable!'); + +//method setOutDocFilename +$t->can_ok($obj, 'setOutDocFilename', 'setOutDocFilename() is callable!'); + +//method getOutDocTemplate +$t->can_ok($obj, 'getOutDocTemplate', 'getOutDocTemplate() is callable!'); + +//method setOutDocTemplate +$t->can_ok($obj, 'setOutDocTemplate', 'setOutDocTemplate() is callable!'); + +/***** TEST CLASS OUTPUTDOCUMENT *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class OutputDocumentTest extends unitTest +{ + function loadTest($aTestData, $aFields) + { + $oOutputDocument = new OutputDocument(); + try { + return $oOutputDocument->load($aFields['OUT_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createTest($aTestData, $aFields) + { + $oOutputDocument = new OutputDocument(); + try { + return $oOutputDocument->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTest($aTestData, $aFields) + { + $oOutputDocument = new OutputDocument(); + try { + return $oOutputDocument->update($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oOutputDocument = new OutputDocument(); + try { + return $oOutputDocument->remove($aFields['OUT_DOC_UID']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oOutputDocumentTest = new OutputDocumentTest('outputDocument.yml', $t, new ymlDomain()); +$oOutputDocumentTest->load('load1'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('load2'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('create1'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('create2'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('update1'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('update2'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('remove1'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oOutputDocumentTest->load('remove2'); +$vAux = $oOutputDocumentTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classPackageTest.php b/workflow/engine/test/unit/processmaker/classPackageTest.php new file mode 100644 index 000000000..401873ae4 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classPackageTest.php @@ -0,0 +1,113 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , $className, 'class $className created'); + + $t->is( count($methods) , 8, "class $className have " . 8 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $fileData); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $fileData "); + + + //checking method 'returnHeader' + $t->can_ok( $obj, 'returnHeader', 'returnHeader() is callable' ); + + //$result = $obj->returnHeader ( ); + //$t->isa_ok( $result, 'NULL', 'call to method returnHeader '); + $t->todo( "call to method returnHeader using "); + + + //checking method 'returnBody' + $t->can_ok( $obj, 'returnBody', 'returnBody() is callable' ); + + //$result = $obj->returnBody ( ); + //$t->isa_ok( $result, 'NULL', 'call to method returnBody '); + $t->todo( "call to method returnBody using "); + + + //checking method 'returnErrors' + $t->can_ok( $obj, 'returnErrors', 'returnErrors() is callable' ); + + //$result = $obj->returnErrors ( $error); + //$t->isa_ok( $result, 'NULL', 'call to method returnErrors '); + $t->todo( "call to method returnErrors using $error "); + + + //checking method 'addHeaders' + $t->can_ok( $obj, 'addHeaders', 'addHeaders() is callable' ); + + //$result = $obj->addHeaders ( ); + //$t->isa_ok( $result, 'NULL', 'call to method addHeaders '); + $t->todo( "call to method addHeaders using "); + + + //checking method 'addAttachment' + $t->can_ok( $obj, 'addAttachment', 'addAttachment() is callable' ); + + //$result = $obj->addAttachment ( $data); + //$t->isa_ok( $result, 'NULL', 'call to method addAttachment '); + $t->todo( "call to method addAttachment using $data "); + + + //checking method 'fixbody' + $t->can_ok( $obj, 'fixbody', 'fixbody() is callable' ); + + //$result = $obj->fixbody ( ); + //$t->isa_ok( $result, 'NULL', 'call to method fixbody '); + $t->todo( "call to method fixbody using "); + + + //checking method 'compileBody' + $t->can_ok( $obj, 'compileBody', 'compileBody() is callable' ); + + //$result = $obj->compileBody ( ); + //$t->isa_ok( $result, 'NULL', 'call to method compileBody '); + $t->todo( "call to method compileBody using "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classPluginDetailTest.php b/workflow/engine/test/unit/processmaker/classPluginDetailTest.php new file mode 100644 index 000000000..317383583 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classPluginDetailTest.php @@ -0,0 +1,57 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 1, "class $className have " . 1 . ' methods.' ); + // Methods + $aMethods = array_keys ( $methods ); + //checking method '__construct' + $t->is ( $aMethods[0], '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $sNamespace, $sClassName, $sFilename, $sFriendlyName, $sPluginFolder, $sDescription, $sSetupPage, $iVersion); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $sNamespace, $sClassName, $sFilename, $sFriendlyName, $sPluginFolder, $sDescription, $sSetupPage, $iVersion "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classPmScriptTest.php b/workflow/engine/test/unit/processmaker/classPmScriptTest.php new file mode 100644 index 000000000..d8dc707e5 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classPmScriptTest.php @@ -0,0 +1,89 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadClass ( 'pmScript'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new PmScript ($dbc); + $t = new lime_test( 7, new lime_output_color() ); + + $t->diag('class PmScript' ); + $t->isa_ok( $obj , 'PMScript', 'class PmScript created'); + + //method setFields + $t->can_ok( $obj, 'setFields', 'setFields() is callable' ); + +// $result = $obj->setFields ( $aFields); +// $t->isa_ok( $result, 'NULL', 'call to method setFields '); + + + //method setScript + $t->can_ok( $obj, 'setScript', 'setScript() is callable' ); + +// $result = $obj->setScript ( $sScript); +// $t->isa_ok( $result, 'NULL', 'call to method setScript '); + + + //method validSyntax + $t->can_ok( $obj, 'validSyntax', 'validSyntax() is callable' ); + +// $result = $obj->validSyntax ( $sScript); +// $t->isa_ok( $result, 'NULL', 'call to method validSyntax '); + + + //method execute + $t->can_ok( $obj, 'execute', 'execute() is callable' ); + +// $result = $obj->execute ( ); +// $t->isa_ok( $result, 'NULL', 'call to method execute '); + + + //method evaluate + $t->can_ok( $obj, 'evaluate', 'evaluate() is callable' ); + +// $result = $obj->evaluate ( ); +// $t->isa_ok( $result, 'NULL', 'call to method evaluate '); + + + // $t->fail( 'review all pendings methods in this class'); +$t->todo ( "review all pendings methods in this class" ); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classPopupMenuTest.php b/workflow/engine/test/unit/processmaker/classPopupMenuTest.php new file mode 100644 index 000000000..390828f28 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classPopupMenuTest.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadClass ( 'popupMenu'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $file = 'login/login'; + + $obj = new PopupMenu ($file); + $t = new lime_test( 2, new lime_output_color() ); + + $t->diag('class PopupMenu' ); + $t->isa_ok( $obj , 'popupMenu', 'class PopupMenu created'); + +// $t->fail( 'review all pendings methods in this class'); + $t->todo( "review all pendings methods in this class"); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classProcessMakerWebDavTest.php b/workflow/engine/test/unit/processmaker/classProcessMakerWebDavTest.php new file mode 100644 index 000000000..256438ec5 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classProcessMakerWebDavTest.php @@ -0,0 +1,465 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 52, "class $className have " . 52 . ' methods.' ); + // Methods + $aMethods = array_keys ( $methods ); + //checking method 'ServeRequest' + $t->is ( $aMethods[0], 'ServeRequest', 'ServeRequest() is callable' ); + + //$result = $obj->ServeRequest ( $base); + //$t->isa_ok( $result, 'NULL', 'call to method ServeRequest '); + $t->todo( "call to method ServeRequest using $base "); + + + //checking method 'check_auth' + $t->is ( $aMethods[1], 'check_auth', 'check_auth() is callable' ); + + //$result = $obj->check_auth ( $type, $user, $pass); + //$t->isa_ok( $result, 'NULL', 'call to method check_auth '); + $t->todo( "call to method check_auth using $type, $user, $pass "); + + + //checking method 'PROPFIND' + $t->is ( $aMethods[2], 'PROPFIND', 'PROPFIND() is callable' ); + + //$result = $obj->PROPFIND ( $options, $files); + //$t->isa_ok( $result, 'NULL', 'call to method PROPFIND '); + $t->todo( "call to method PROPFIND using $options, $files "); + + + //checking method '_can_execute' + $t->is ( $aMethods[3], '_can_execute', '_can_execute() is callable' ); + + //$result = $obj->_can_execute ( $name, $path); + //$t->isa_ok( $result, 'NULL', 'call to method _can_execute '); + $t->todo( "call to method _can_execute using $name, $path "); + + + //checking method '_mimetype' + $t->is ( $aMethods[4], '_mimetype', '_mimetype() is callable' ); + + //$result = $obj->_mimetype ( $fspath); + //$t->isa_ok( $result, 'NULL', 'call to method _mimetype '); + $t->todo( "call to method _mimetype using $fspath "); + + + //checking method 'GET' + $t->is ( $aMethods[5], 'GET', 'GET() is callable' ); + + //$result = $obj->GET ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method GET '); + $t->todo( "call to method GET using $options "); + + + //checking method 'getRoot' + $t->is ( $aMethods[6], 'getRoot', 'getRoot() is callable' ); + + //$result = $obj->getRoot ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method getRoot '); + $t->todo( "call to method getRoot using $options "); + + + //checking method 'GetDir' + $t->is ( $aMethods[7], 'GetDir', 'GetDir() is callable' ); + + //$result = $obj->GetDir ( $fspath, $options); + //$t->isa_ok( $result, 'NULL', 'call to method GetDir '); + $t->todo( "call to method GetDir using $fspath, $options "); + + + //checking method 'PUT' + $t->is ( $aMethods[8], 'PUT', 'PUT() is callable' ); + + //$result = $obj->PUT ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method PUT '); + $t->todo( "call to method PUT using $options "); + + + //checking method 'MKCOL' + $t->is ( $aMethods[9], 'MKCOL', 'MKCOL() is callable' ); + + //$result = $obj->MKCOL ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method MKCOL '); + $t->todo( "call to method MKCOL using $options "); + + + //checking method 'DELETE' + $t->is ( $aMethods[10], 'DELETE', 'DELETE() is callable' ); + + //$result = $obj->DELETE ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method DELETE '); + $t->todo( "call to method DELETE using $options "); + + + //checking method 'MOVE' + $t->is ( $aMethods[11], 'MOVE', 'MOVE() is callable' ); + + //$result = $obj->MOVE ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method MOVE '); + $t->todo( "call to method MOVE using $options "); + + + //checking method 'COPY' + $t->is ( $aMethods[12], 'COPY', 'COPY() is callable' ); + + //$result = $obj->COPY ( $options, $del); + //$t->isa_ok( $result, 'NULL', 'call to method COPY '); + $t->todo( "call to method COPY using $options, $del "); + + + //checking method 'PROPPATCH' + $t->is ( $aMethods[13], 'PROPPATCH', 'PROPPATCH() is callable' ); + + //$result = $obj->PROPPATCH ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method PROPPATCH '); + $t->todo( "call to method PROPPATCH using $options "); + + + //checking method 'LOCK' + $t->is ( $aMethods[14], 'LOCK', 'LOCK() is callable' ); + + //$result = $obj->LOCK ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method LOCK '); + $t->todo( "call to method LOCK using $options "); + + + //checking method 'UNLOCK' + $t->is ( $aMethods[15], 'UNLOCK', 'UNLOCK() is callable' ); + + //$result = $obj->UNLOCK ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method UNLOCK '); + $t->todo( "call to method UNLOCK using $options "); + + + //checking method 'checkLock' + $t->is ( $aMethods[16], 'checkLock', 'checkLock() is callable' ); + + //$result = $obj->checkLock ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method checkLock '); + $t->todo( "call to method checkLock using $path "); + + + //checking method 'create_database' + $t->is ( $aMethods[17], 'create_database', 'create_database() is callable' ); + + //$result = $obj->create_database ( ); + //$t->isa_ok( $result, 'NULL', 'call to method create_database '); + $t->todo( "call to method create_database using "); + + + //checking method 'HTTP_WebDAV_Server' + $t->is ( $aMethods[18], 'HTTP_WebDAV_Server', 'HTTP_WebDAV_Server() is callable' ); + + //$result = $obj->HTTP_WebDAV_Server ( ); + //$t->isa_ok( $result, 'NULL', 'call to method HTTP_WebDAV_Server '); + $t->todo( "call to method HTTP_WebDAV_Server using "); + + + //checking method 'http_OPTIONS' + $t->is ( $aMethods[19], 'http_OPTIONS', 'http_OPTIONS() is callable' ); + + //$result = $obj->http_OPTIONS ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_OPTIONS '); + $t->todo( "call to method http_OPTIONS using "); + + + //checking method 'http_PROPFIND' + $t->is ( $aMethods[20], 'http_PROPFIND', 'http_PROPFIND() is callable' ); + + //$result = $obj->http_PROPFIND ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_PROPFIND '); + $t->todo( "call to method http_PROPFIND using "); + + + //checking method 'http_PROPPATCH' + $t->is ( $aMethods[21], 'http_PROPPATCH', 'http_PROPPATCH() is callable' ); + + //$result = $obj->http_PROPPATCH ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_PROPPATCH '); + $t->todo( "call to method http_PROPPATCH using "); + + + //checking method 'http_MKCOL' + $t->is ( $aMethods[22], 'http_MKCOL', 'http_MKCOL() is callable' ); + + //$result = $obj->http_MKCOL ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_MKCOL '); + $t->todo( "call to method http_MKCOL using "); + + + //checking method 'http_GET' + $t->is ( $aMethods[23], 'http_GET', 'http_GET() is callable' ); + + //$result = $obj->http_GET ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_GET '); + $t->todo( "call to method http_GET using "); + + + //checking method '_get_ranges' + $t->is ( $aMethods[24], '_get_ranges', '_get_ranges() is callable' ); + + //$result = $obj->_get_ranges ( $options); + //$t->isa_ok( $result, 'NULL', 'call to method _get_ranges '); + $t->todo( "call to method _get_ranges using $options "); + + + //checking method '_multipart_byterange_header' + $t->is ( $aMethods[25], '_multipart_byterange_header', '_multipart_byterange_header() is callable' ); + + //$result = $obj->_multipart_byterange_header ( $mimetype, $from, $to, $total); + //$t->isa_ok( $result, 'NULL', 'call to method _multipart_byterange_header '); + $t->todo( "call to method _multipart_byterange_header using $mimetype, $from, $to, $total "); + + + //checking method 'http_HEAD' + $t->is ( $aMethods[26], 'http_HEAD', 'http_HEAD() is callable' ); + + //$result = $obj->http_HEAD ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_HEAD '); + $t->todo( "call to method http_HEAD using "); + + + //checking method 'http_PUT' + $t->is ( $aMethods[27], 'http_PUT', 'http_PUT() is callable' ); + + //$result = $obj->http_PUT ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_PUT '); + $t->todo( "call to method http_PUT using "); + + + //checking method 'http_DELETE' + $t->is ( $aMethods[28], 'http_DELETE', 'http_DELETE() is callable' ); + + //$result = $obj->http_DELETE ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_DELETE '); + $t->todo( "call to method http_DELETE using "); + + + //checking method 'http_COPY' + $t->is ( $aMethods[29], 'http_COPY', 'http_COPY() is callable' ); + + //$result = $obj->http_COPY ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_COPY '); + $t->todo( "call to method http_COPY using "); + + + //checking method 'http_MOVE' + $t->is ( $aMethods[30], 'http_MOVE', 'http_MOVE() is callable' ); + + //$result = $obj->http_MOVE ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_MOVE '); + $t->todo( "call to method http_MOVE using "); + + + //checking method 'http_LOCK' + $t->is ( $aMethods[31], 'http_LOCK', 'http_LOCK() is callable' ); + + //$result = $obj->http_LOCK ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_LOCK '); + $t->todo( "call to method http_LOCK using "); + + + //checking method 'http_UNLOCK' + $t->is ( $aMethods[32], 'http_UNLOCK', 'http_UNLOCK() is callable' ); + + //$result = $obj->http_UNLOCK ( ); + //$t->isa_ok( $result, 'NULL', 'call to method http_UNLOCK '); + $t->todo( "call to method http_UNLOCK using "); + + + //checking method '_copymove' + $t->is ( $aMethods[33], '_copymove', '_copymove() is callable' ); + + //$result = $obj->_copymove ( $what); + //$t->isa_ok( $result, 'NULL', 'call to method _copymove '); + $t->todo( "call to method _copymove using $what "); + + + //checking method '_allow' + $t->is ( $aMethods[34], '_allow', '_allow() is callable' ); + + //$result = $obj->_allow ( ); + //$t->isa_ok( $result, 'NULL', 'call to method _allow '); + $t->todo( "call to method _allow using "); + + + //checking method 'mkprop' + $t->is ( $aMethods[35], 'mkprop', 'mkprop() is callable' ); + + //$result = $obj->mkprop ( ); + //$t->isa_ok( $result, 'NULL', 'call to method mkprop '); + $t->todo( "call to method mkprop using "); + + + //checking method '_check_auth' + $t->is ( $aMethods[36], '_check_auth', '_check_auth() is callable' ); + + //$result = $obj->_check_auth ( ); + //$t->isa_ok( $result, 'NULL', 'call to method _check_auth '); + $t->todo( "call to method _check_auth using "); + + + //checking method '_new_uuid' + $t->is ( $aMethods[37], '_new_uuid', '_new_uuid() is callable' ); + + //$result = $obj->_new_uuid ( ); + //$t->isa_ok( $result, 'NULL', 'call to method _new_uuid '); + $t->todo( "call to method _new_uuid using "); + + + //checking method '_new_locktoken' + $t->is ( $aMethods[38], '_new_locktoken', '_new_locktoken() is callable' ); + + //$result = $obj->_new_locktoken ( ); + //$t->isa_ok( $result, 'NULL', 'call to method _new_locktoken '); + $t->todo( "call to method _new_locktoken using "); + + + //checking method '_if_header_lexer' + $t->is ( $aMethods[39], '_if_header_lexer', '_if_header_lexer() is callable' ); + + //$result = $obj->_if_header_lexer ( $string, $pos); + //$t->isa_ok( $result, 'NULL', 'call to method _if_header_lexer '); + $t->todo( "call to method _if_header_lexer using $string, $pos "); + + + //checking method '_if_header_parser' + $t->is ( $aMethods[40], '_if_header_parser', '_if_header_parser() is callable' ); + + //$result = $obj->_if_header_parser ( $str); + //$t->isa_ok( $result, 'NULL', 'call to method _if_header_parser '); + $t->todo( "call to method _if_header_parser using $str "); + + + //checking method '_check_if_header_conditions' + $t->is ( $aMethods[41], '_check_if_header_conditions', '_check_if_header_conditions() is callable' ); + + //$result = $obj->_check_if_header_conditions ( ); + //$t->isa_ok( $result, 'NULL', 'call to method _check_if_header_conditions '); + $t->todo( "call to method _check_if_header_conditions using "); + + + //checking method '_check_uri_condition' + $t->is ( $aMethods[42], '_check_uri_condition', '_check_uri_condition() is callable' ); + + //$result = $obj->_check_uri_condition ( $uri, $condition); + //$t->isa_ok( $result, 'NULL', 'call to method _check_uri_condition '); + $t->todo( "call to method _check_uri_condition using $uri, $condition "); + + + //checking method '_check_lock_status' + $t->is ( $aMethods[43], '_check_lock_status', '_check_lock_status() is callable' ); + + //$result = $obj->_check_lock_status ( $path, $exclusive_only); + //$t->isa_ok( $result, 'NULL', 'call to method _check_lock_status '); + $t->todo( "call to method _check_lock_status using $path, $exclusive_only "); + + + //checking method 'lockdiscovery' + $t->is ( $aMethods[44], 'lockdiscovery', 'lockdiscovery() is callable' ); + + //$result = $obj->lockdiscovery ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method lockdiscovery '); + $t->todo( "call to method lockdiscovery using $path "); + + + //checking method 'http_status' + $t->is ( $aMethods[45], 'http_status', 'http_status() is callable' ); + + //$result = $obj->http_status ( $status); + //$t->isa_ok( $result, 'NULL', 'call to method http_status '); + $t->todo( "call to method http_status using $status "); + + + //checking method '_urlencode' + $t->is ( $aMethods[46], '_urlencode', '_urlencode() is callable' ); + + //$result = $obj->_urlencode ( $url); + //$t->isa_ok( $result, 'NULL', 'call to method _urlencode '); + $t->todo( "call to method _urlencode using $url "); + + + //checking method '_urldecode' + $t->is ( $aMethods[47], '_urldecode', '_urldecode() is callable' ); + + //$result = $obj->_urldecode ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method _urldecode '); + $t->todo( "call to method _urldecode using $path "); + + + //checking method '_prop_encode' + $t->is ( $aMethods[48], '_prop_encode', '_prop_encode() is callable' ); + + //$result = $obj->_prop_encode ( $text); + //$t->isa_ok( $result, 'NULL', 'call to method _prop_encode '); + $t->todo( "call to method _prop_encode using $text "); + + + //checking method '_slashify' + $t->is ( $aMethods[49], '_slashify', '_slashify() is callable' ); + + //$result = $obj->_slashify ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method _slashify '); + $t->todo( "call to method _slashify using $path "); + + + //checking method '_unslashify' + $t->is ( $aMethods[50], '_unslashify', '_unslashify() is callable' ); + + //$result = $obj->_unslashify ( $path); + //$t->isa_ok( $result, 'NULL', 'call to method _unslashify '); + $t->todo( "call to method _unslashify using $path "); + + + //checking method '_mergePathes' + $t->is ( $aMethods[51], '_mergePathes', '_mergePathes() is callable' ); + + //$result = $obj->_mergePathes ( $parent, $child); + //$t->isa_ok( $result, 'NULL', 'call to method _mergePathes '); + $t->todo( "call to method _mergePathes using $parent, $child "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classProcessMapTest.php b/workflow/engine/test/unit/processmaker/classProcessMapTest.php new file mode 100644 index 000000000..fef6053ca --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classProcessMapTest.php @@ -0,0 +1,587 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . 'lime/lime.php'); +require_once(PATH_THIRDPARTY . 'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadClass('plugin'); +G::LoadSystem('dbconnection'); +G::LoadSystem('dbsession'); +G::LoadSystem('dbrecordset'); +G::LoadSystem('templatePower'); +G::LoadSystem('publisher'); +G::LoadSystem('headPublisher'); +G::LoadSystem('pagedTable'); + $oHeadPublisher =& headPublisher::getSingleton(); +G::LoadSystem('testTools'); +G::LoadClass('processMap'); + +$obj = new processMap(); +$t = new lime_test(30, new lime_output_color()); + +$t->diag('Class processMap'); + +//class processMap +$t->isa_ok($obj, 'processMap', 'Class processMap created!'); + +//method load +$t->can_ok($obj, 'load', 'load() is callable!'); + +//method createProcess +$t->can_ok($obj, 'createProcess', 'createProcess() is callable!'); + +//method updateProcess +$t->can_ok($obj, 'updateProcess', 'updateProcess() is callable!'); + +//method editProcess +$t->can_ok($obj, 'editProcess', 'editProcess() is callable!'); + +//method saveTitlePosition +$t->can_ok($obj, 'saveTitlePosition', 'saveTitlePosition() is callable!'); + +//method steps +$t->can_ok($obj, 'steps', 'steps() is callable!'); + +//method users +$t->can_ok($obj, 'users', 'users() is callable!'); + +//method stepsConditions +$t->can_ok($obj, 'stepsConditions', 'stepsConditions() is callable!'); + +//method stepsTriggers +$t->can_ok($obj, 'stepsTriggers', 'stepsTriggers() is callable!'); + +//method addTask +$t->can_ok($obj, 'addTask', 'addTask() is callable!'); + +//method editTaskProperties +$t->can_ok($obj, 'editTaskProperties', 'editTaskProperties() is callable!'); + +//method saveTaskPosition +$t->can_ok($obj, 'saveTaskPosition', 'saveTaskPosition() is callable!'); + +//method deleteTask +$t->can_ok($obj, 'deleteTask', 'deleteTask() is callable!'); + +//method addGuide +$t->can_ok($obj, 'addGuide', 'addGuide() is callable!'); + +//method saveGuidePosition +$t->can_ok($obj, 'saveGuidePosition', 'saveGuidePosition() is callable!'); + +//method deleteGuide +$t->can_ok($obj, 'deleteGuide', 'deleteGuide() is callable!'); + +//method deleteGuides +$t->can_ok($obj, 'deleteGuides', 'deleteGuides() is callable!'); + +//method addText +$t->can_ok($obj, 'addText', 'addText() is callable!'); + +//method updateText +$t->can_ok($obj, 'updateText', 'updateText() is callable!'); + +//method saveTextPosition +$t->can_ok($obj, 'saveTextPosition', 'saveTextPosition() is callable!'); + +//method deleteText +$t->can_ok($obj, 'deleteText', 'deleteText() is callable!'); + +//method dynaformsList +$t->can_ok($obj, 'dynaformsList', 'dynaformsList() is callable!'); + +//method outputdocsList +$t->can_ok($obj, 'outputdocsList', 'outputdocsList() is callable!'); + +//method inputdocsList +$t->can_ok($obj, 'inputdocsList', 'inputdocsList() is callable!'); + +//method triggersList +$t->can_ok($obj, 'triggersList', 'triggersList() is callable!'); + +//method messagesList +$t->can_ok($obj, 'messagesList', 'messagesList() is callable!'); + +//method currentPattern +$t->can_ok($obj, 'currentPattern', 'currentPattern() is callable!'); + +//method newPattern +$t->can_ok($obj, 'newPattern', 'newPattern() is callable!'); + +//method deleteDerivation +$t->can_ok($obj, 'deleteDerivation', 'deleteDerivation() is callable!'); + +/***** TEST CLASS PROCESSMAP *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class processMapTest extends unitTest { + function loadTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->load($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createProcessTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->createProcess($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateProcessTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->updateProcess($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function editProcessTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->editProcess($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function saveTitlePositionTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->saveTitlePosition($aFields['PRO_UID'], $aFields['PRO_X'], $aFields['PRO_Y']); + } + catch (Exception $oError) { + return $oError; + } + } + function stepsTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->steps($aFields['PRO_UID'], $aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function usersTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->users($aFields['PRO_UID'], $aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function stepsConditionsTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->stepsConditions($aFields['PRO_UID'], $aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function stepsTriggersTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->stepsTriggers($aFields['PRO_UID'], $aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function addTaskTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->addTask($aFields['PRO_UID'], $aFields['TAS_X'], $aFields['TAS_Y']); + } + catch (Exception $oError) { + return $oError; + } + } + function editTaskPropertiesTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->editTaskProperties($aFields['TAS_UID'], $aFields['iForm'], $aFields['iIndex']); + } + catch (Exception $oError) { + return $oError; + } + } + function saveTaskPositionTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->saveTaskPosition($aFields['TAS_UID'], $aFields['TAS_X'], $aFields['TAS_Y']); + } + catch (Exception $oError) { + return $oError; + } + } + function deleteTaskTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->deleteTask($aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function addGuideTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->addGuide($aFields['PRO_UID'], $aFields['iPosition'], $aFields['sDirection']); + } + catch (Exception $oError) { + return $oError; + } + } + function saveGuidePositionTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->saveGuidePosition($aFields['SWI_UID'], $aFields['iPosition'], $aFields['sDirection']); + } + catch (Exception $oError) { + return $oError; + } + } + function deleteGuideTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->deleteGuide($aFields['SWI_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function deleteGuidesTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->deleteGuides($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function addTextTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->addText($aFields['PRO_UID'], $aFields['SWI_TEXT'], $aFields['SWI_X'], $aFields['SWI_Y']); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTextTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->updateText($aFields['SWI_UID'], $aFields['SWI_TEXT']); + } + catch (Exception $oError) { + return $oError; + } + } + function saveTextPositionTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->saveTextPosition($aFields['SWI_UID'], $aFields['SWI_X'], $aFields['SWI_X']); + } + catch (Exception $oError) { + return $oError; + } + } + function deleteTextTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->deleteText($aFields['SWI_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function dynaformsListTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->dynaformsList($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function outputdocsListTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->outputdocsList($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function inputdocsListTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->inputdocsList($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function triggersListTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->triggersList($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function messagesListTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->messagesList($aFields['PRO_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function currentPatternTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->currentPattern($aFields['PRO_UID'], $aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function newPatternTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->newPattern($aFields['PRO_UID'], $aFields['TAS_UID'], $aFields['ROU_NEXT_TASK'], $aRow['ROU_TYPE']); + } + catch (Exception $oError) { + return $oError; + } + } + function deleteDerivationTest($aTestData, $aFields) { + $oProcessMap = new processMap(); + try { + return $oProcessMap->deleteDerivation($aFields['TAS_UID']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oProcessMapTest = new processMapTest('processMap.yml', $t, new ymlDomain()); +/*$oProcessMapTest->load('load1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('load2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oProcessMapTest->load('createProcess1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oProcessMapTest->load('updateProcess1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oProcessMapTest->load('updateProcess2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oProcessMapTest->load('editProcess1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('editProcess2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTitlePosition1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTitlePosition2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('steps1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('steps2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('users1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('users2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('stepsConditions1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('stepsConditions2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('stepsTriggers1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('stepsTriggers2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addTask1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addTask2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('editTaskProperties1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('editTaskProperties2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTaskPosition1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTaskPosition2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteTask1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteTask2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addGuide1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addGuide2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveGuidePosition1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveGuidePosition2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteGuide1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteGuide2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteGuides1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteGuides2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addText1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('addText2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('updateText1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('updateText2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTextPosition1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('saveTextPosition2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteText1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteText2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('dynaformsList1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('dynaformsList2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('outputdocsList1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('outputdocsList2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('inputdocsList1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('inputdocsList2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('triggersList1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('triggersList2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('messagesList1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('messagesList2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('currentPattern1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('currentPattern2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('newPattern1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('newPattern2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteDerivation1'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die; +$oProcessMapTest->load('deleteDerivation2'); +$vAux = $oProcessMapTest->runSingle(); +//var_dump($vAux);echo "\n\n";die;*/ +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classProcessTest.php b/workflow/engine/test/unit/processmaker/classProcessTest.php new file mode 100644 index 000000000..654a1eed6 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classProcessTest.php @@ -0,0 +1,247 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once( 'propel/Propel.php' ); + Propel::init( PATH_CORE . "config/databases.php"); + + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'testTools'); + + require_once( PATH_CORE.'/classes/model/Process.php'); + + $obj = new Process (); + $t = new lime_test( 40, new lime_output_color() ); + + $t->diag('class Process' ); + $t->isa_ok( $obj , 'Process', 'class Process created'); + + //method load + //#2 + $t->can_ok( $obj, 'getProTitle', 'getProTitle() is callable' ); + //#3 + $t->can_ok( $obj, 'setProTitle', 'setProTitle() is callable' ); + //#4 + $t->can_ok( $obj, 'getProDescription', 'getProDescription() is callable' ); + //#5 + $t->can_ok( $obj, 'setProDescription', 'setProDescription() is callable' ); + //#6 + $t->can_ok( $obj, 'create', 'create() is callable' ); + //#7 + $t->can_ok( $obj, 'update', 'update() is callable' ); + //#8 + $t->can_ok( $obj, 'load', 'load() is callable' ); + //#9 + $t->can_ok( $obj, 'remove', 'remove() is callable' ); + + //getProUid + //#10 + $t->is( $obj->getProUid(), '', 'getProUid() return empty, when the instance doesnt have any row' ); + + //getProTitle + try { + $obj = new Process (); + $res = $obj->getProTitle(); + } + catch ( Exception $e ) { + //#11 + $t->isa_ok( $e, 'Exception', 'getProTitle() return error when PRO_UID is not defined' ); + //#12 + $t->is ( $e->getMessage(), "Error in getProTitle, the PRO_UID can't be blank", 'getProTitle() return Error in getProTitle, the PRO_UID cant be blank' ); + } + + //setProDescription + try { + $obj = new Process (); + $obj->setProDescription('x'); + } + catch ( Exception $e ) { + //#13 + $t->isa_ok( $e, 'Exception', 'setProDescription() return error when PRO_UID is not defined' ); + //#14 + $t->is ( $e->getMessage(), "Error in setProDescription, the PRO_UID can't be blank", 'setProDescription() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //getProDescription + try { + $obj = new Process (); + $res = $obj->getProDescription(); + } + catch ( Exception $e ) { + //#15 + $t->isa_ok( $e, 'Exception', 'getProDescription() return error when PRO_UID is not defined' ); + //#16 + $t->is ( $e->getMessage(), "Error in getProDescription, the PRO_UID can't be blank", 'getProDescription() return Error in getProDescription, the PRO_UID cant be blank' ); + } + + //setAppDescription + try { + $obj = new Process (); + $obj->setProDescription('x'); + } + catch ( Exception $e ) { + //#17 + $t->isa_ok( $e, 'Exception', 'setAppDescription() return error when PRO_UID is not defined' ); + //#18 + $t->is ( $e->getMessage(), "Error in setProDescription, the PRO_UID can't be blank", 'setAppDescription() return Error in getAppDescription, the APP_UID cant be blank' ); + } + + + + //create new row + try { + $obj = new Process (); + $res = $obj->create(); + } + catch ( Exception $e ) { + //#19 + $t->isa_ok( $e, 'PropelException', 'create() return error when PRO_UID is not defined' ); + //#20 + $t->like ( $e->getMessage(), "%The process cannot be created. The USR_UID is empty.%", 'create() return The process cannot be created. The USR_UID is empty.' ); + } + + //create + try { + $Fields['USR_UID'] = '1'; // we need a valid user + $obj = new Process (); + $proUid = $obj->create( $Fields ); + //#21 + $t->isa_ok( $proUid, 'string', 'create(), creates a new Process' ); + //#22 + //$t->is ( strlen($proUid), 14, 'create(), creates a new Process, Guid lenth=14 chars' ); + $t->diag ( "strlen($proUid), 14, 'create(), creates a new Process, Guid lenth=14 chars' " ); + $t->is ( strlen($proUid), 32, 'create(), creates a new Process, Guid lenth=32 chars' ); + $res = $obj->load( $proUid ); + //#23 + $t->isa_ok( $res, 'array', 'load(), loads a new Process' ); + //#24 + $t->is ( $res['PRO_UID'], $proUid, 'load(), loads a new Process, valid PRO_UID' ); + //#25 + $t->is ( strlen($res['PRO_CREATE_DATE']) ,19, 'load(), loads a new Process, valid CREATE_DATE' ); + //#26 + $t->like ( $res['PRO_TITLE'], '%Default Process%', 'load(), loads a new Process, valid PRO_TITLE' ); + //#27 + $t->is ( $res['PRO_DESCRIPTION'], 'Default Process Description', 'load(), loads a new Process, valid PRO_DESCRIPTION' ); + + } + catch ( Exception $e ) { + $t->like ( $e->getMessage(), "%Unable to execute INSERT statement%", 'create() return Error in getAppTitle, the APP_UID cant be blank' ); + } + + //update with empty + try { + $obj = new Process (); + $res = $obj->update( NULL ); + } + catch ( Exception $e ) { + //#28 + $t->isa_ok( $e, 'Exception', 'update() returns error when PRO_UID is not defined' ); + //#29 + // $t->is ( $e->getMessage(), "This row doesn't exist!", "update() This row doesn't exist!" ); + $t->todo ( " $e->getMessage() This row doesn't exist! <> The row '' in table Process doesn't exist! " . " line 171"); + } + + + //update with $fields + $newTitle = 'new title ' . rand( 1000, 5000); + $newDescription = 'new Description '. rand( 1000, 5000); + $Fields['PRO_UID'] = $proUid; + $Fields['PRO_TITLE'] = $newTitle; + $Fields['PRO_PARENT'] = rand( 1000, 5000); + $Fields['PRO_CREATE_DATE'] = 'now'; + try { + $obj = new Process (); + $res = $obj->update( $Fields); + //#30 + $t->is ( $res, 1, "update() update 1 row" ); + $Fields = $obj->Load ( $proUid ); + //#26 + $t->is ( $obj->getproUid(), $proUid, "update() APP_UID = ". $proUid ); + //#27 + $t->is ( $obj->getProTitle(), $newTitle, "update() getAppTitle" ); + //#28 + $t->is ( $Fields['PRO_TITLE'], $newTitle, "update() PRO_TITLE= ". $newTitle ); + //#29 + $t->is ( $Fields['PRO_CREATE_DATE'], date('Y-m-d H:i:s'), "update() PRO_CREATE_DATE= ". date('Y-m-d H:i:s') ); + } + catch ( Exception $e ) { + //#14 + $t->isa_ok( $e, 'PropelException', 'update() return error ' . $e->getMessage() ); + print $e->getMessage(); + } + +//remove with empty + try { + $obj = new Process (); + $res = $obj->remove( NULL ); + } + catch ( Exception $e ) { + //#30 + $t->isa_ok( $e, 'Exception', 'remove() returns error when UID is not defined' ); + //#31 + //$t->is ( $e->getMessage(), "This row doesn't exist!", "remove() This row doesn't exist!" ); + $t->todo ( $e->getMessage() . " <> The row ''in table Process doesn't exist! " . " line 213" ); + } + + //remove with $fields + $Fields['PRO_UID'] = $proUid; + try { + $obj = new Process (); + $res = $obj->remove( $Fields ); + //#32 + $t->is ( $res, NULL, "remove() remove row $proUid" ); + } + catch ( Exception $e ) { + //#14 + $t->isa_ok( $e, 'PropelException', 'remove() return error ' . $e->getMessage() ); + } + + //remove with $proUid + $obj = new Process (); + $proUid = $obj->create( '1' ); + try { + $obj = new Process (); + $res = $obj->remove ($proUid ); + //#33 + $t->is ( $res, NULL, "remove() remove row $proUid" ); + } + catch ( Exception $e ) { + //#14 + $t->isa_ok( $e, 'PropelException', 'remove() return error ' . $e->getMessage() ); + } + + + $t->todo( 'Test to verify if delete works correctly :p ...'); + $t->todo( 'how can I change dynamically the Case Title based in a definition, right now the case title is the same as the process title. We need another field in process to have the case title definition'); + +?> diff --git a/workflow/engine/test/unit/processmaker/classProcessesTest.php b/workflow/engine/test/unit/processmaker/classProcessesTest.php new file mode 100644 index 000000000..61eadd99c --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classProcessesTest.php @@ -0,0 +1,985 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'processes'); + + + $obj = new Processes ($dbc); + $t = new lime_test( 231, new lime_output_color() ); + + $className = Processes; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + //$t->is( count($methods) , 116, "class $className have " . 116 . ' methods.' ); + $t->is( count($methods) , 120, "class $className have " . 120 . ' methods.' ); + + //checking method 'changeStatus' + $t->can_ok( $obj, 'changeStatus', 'changeStatus() is callable' ); + + //$result = $obj->changeStatus ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method changeStatus '); + $t->todo( "call to method changeStatus using $sProUid "); + + + //checking method 'changeProcessParent' + $t->can_ok( $obj, 'changeProcessParent', 'changeProcessParent() is callable' ); + + //$result = $obj->changeProcessParent ( $sProUid, $sParentUid); + //$t->isa_ok( $result, 'NULL', 'call to method changeProcessParent '); + $t->todo( "call to method changeProcessParent using $sProUid, $sParentUid "); + + + //checking method 'processExists' + $t->can_ok( $obj, 'processExists', 'processExists() is callable' ); + + //$result = $obj->processExists ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method processExists '); + $t->todo( "call to method processExists using $sProUid "); + + + //checking method 'getUnusedProcessGUID' + $t->can_ok( $obj, 'getUnusedProcessGUID', 'getUnusedProcessGUID() is callable' ); + + //$result = $obj->getUnusedProcessGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedProcessGUID '); + $t->todo( "call to method getUnusedProcessGUID using "); + + + //checking method 'taskExists' + $t->can_ok( $obj, 'taskExists', 'taskExists() is callable' ); + + //$result = $obj->taskExists ( $sTasUid); + //$t->isa_ok( $result, 'NULL', 'call to method taskExists '); + $t->todo( "call to method taskExists using $sTasUid "); + + + //checking method 'getUnusedTaskGUID' + $t->can_ok( $obj, 'getUnusedTaskGUID', 'getUnusedTaskGUID() is callable' ); + + //$result = $obj->getUnusedTaskGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedTaskGUID '); + $t->todo( "call to method getUnusedTaskGUID using "); + + + //checking method 'dynaformExists' + $t->can_ok( $obj, 'dynaformExists', 'dynaformExists() is callable' ); + + //$result = $obj->dynaformExists ( $sDynUid); + //$t->isa_ok( $result, 'NULL', 'call to method dynaformExists '); + $t->todo( "call to method dynaformExists using $sDynUid "); + + + //checking method 'inputExists' + $t->can_ok( $obj, 'inputExists', 'inputExists() is callable' ); + + //$result = $obj->inputExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method inputExists '); + $t->todo( "call to method inputExists using $sUid "); + + + //checking method 'outputExists' + $t->can_ok( $obj, 'outputExists', 'outputExists() is callable' ); + + //$result = $obj->outputExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method outputExists '); + $t->todo( "call to method outputExists using $sUid "); + + + //checking method 'triggerExists' + $t->can_ok( $obj, 'triggerExists', 'triggerExists() is callable' ); + + //$result = $obj->triggerExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method triggerExists '); + $t->todo( "call to method triggerExists using $sUid "); + + + //checking method 'SubProcessExists' + $t->can_ok( $obj, 'SubProcessExists', 'SubProcessExists() is callable' ); + + //$result = $obj->SubProcessExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method SubProcessExists '); + $t->todo( "call to method SubProcessExists using $sUid "); + + + //checking method 'caseTrackerObjectExists' + $t->can_ok( $obj, 'caseTrackerObjectExists', 'caseTrackerObjectExists() is callable' ); + + //$result = $obj->caseTrackerObjectExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method caseTrackerObjectExists '); + $t->todo( "call to method caseTrackerObjectExists using $sUid "); + + + //checking method 'caseTrackerExists' + $t->can_ok( $obj, 'caseTrackerExists', 'caseTrackerExists() is callable' ); + + //$result = $obj->caseTrackerExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method caseTrackerExists '); + $t->todo( "call to method caseTrackerExists using $sUid "); + + + //checking method 'dbConnectionExists' + $t->can_ok( $obj, 'dbConnectionExists', 'dbConnectionExists() is callable' ); + + //$result = $obj->dbConnectionExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method dbConnectionExists '); + $t->todo( "call to method dbConnectionExists using $sUid "); + + + //checking method 'objectPermissionExists' + $t->can_ok( $obj, 'objectPermissionExists', 'objectPermissionExists() is callable' ); + + //$result = $obj->objectPermissionExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method objectPermissionExists '); + $t->todo( "call to method objectPermissionExists using $sUid "); + + + //checking method 'routeExists' + $t->can_ok( $obj, 'routeExists', 'routeExists() is callable' ); + + //$result = $obj->routeExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method routeExists '); + $t->todo( "call to method routeExists using $sUid "); + + + //checking method 'stageExists' + $t->can_ok( $obj, 'stageExists', 'stageExists() is callable' ); + + //$result = $obj->stageExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method stageExists '); + $t->todo( "call to method stageExists using $sUid "); + + + //checking method 'slExists' + $t->can_ok( $obj, 'slExists', 'slExists() is callable' ); + + //$result = $obj->slExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method slExists '); + $t->todo( "call to method slExists using $sUid "); + + + //checking method 'reportTableExists' + $t->can_ok( $obj, 'reportTableExists', 'reportTableExists() is callable' ); + + //$result = $obj->reportTableExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method reportTableExists '); + $t->todo( "call to method reportTableExists using $sUid "); + + + //checking method 'reportVarExists' + $t->can_ok( $obj, 'reportVarExists', 'reportVarExists() is callable' ); + + //$result = $obj->reportVarExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method reportVarExists '); + $t->todo( "call to method reportVarExists using $sUid "); + + + //checking method 'getUnusedInputGUID' + $t->can_ok( $obj, 'getUnusedInputGUID', 'getUnusedInputGUID() is callable' ); + + //$result = $obj->getUnusedInputGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedInputGUID '); + $t->todo( "call to method getUnusedInputGUID using "); + + + //checking method 'getUnusedOutputGUID' + $t->can_ok( $obj, 'getUnusedOutputGUID', 'getUnusedOutputGUID() is callable' ); + + //$result = $obj->getUnusedOutputGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedOutputGUID '); + $t->todo( "call to method getUnusedOutputGUID using "); + + + //checking method 'getUnusedTriggerGUID' + $t->can_ok( $obj, 'getUnusedTriggerGUID', 'getUnusedTriggerGUID() is callable' ); + + //$result = $obj->getUnusedTriggerGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedTriggerGUID '); + $t->todo( "call to method getUnusedTriggerGUID using "); + + + //checking method 'getUnusedSubProcessGUID' + $t->can_ok( $obj, 'getUnusedSubProcessGUID', 'getUnusedSubProcessGUID() is callable' ); + + //$result = $obj->getUnusedSubProcessGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedSubProcessGUID '); + $t->todo( "call to method getUnusedSubProcessGUID using "); + + + //checking method 'getUnusedCaseTrackerObjectGUID' + $t->can_ok( $obj, 'getUnusedCaseTrackerObjectGUID', 'getUnusedCaseTrackerObjectGUID() is callable' ); + + //$result = $obj->getUnusedCaseTrackerObjectGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedCaseTrackerObjectGUID '); + $t->todo( "call to method getUnusedCaseTrackerObjectGUID using "); + + + //checking method 'getUnusedDBSourceGUID' + $t->can_ok( $obj, 'getUnusedDBSourceGUID', 'getUnusedDBSourceGUID() is callable' ); + + //$result = $obj->getUnusedDBSourceGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedDBSourceGUID '); + $t->todo( "call to method getUnusedDBSourceGUID using "); + + + //checking method 'getUnusedObjectPermissionGUID' + $t->can_ok( $obj, 'getUnusedObjectPermissionGUID', 'getUnusedObjectPermissionGUID() is callable' ); + + //$result = $obj->getUnusedObjectPermissionGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedObjectPermissionGUID '); + $t->todo( "call to method getUnusedObjectPermissionGUID using "); + + + //checking method 'getUnusedRouteGUID' + $t->can_ok( $obj, 'getUnusedRouteGUID', 'getUnusedRouteGUID() is callable' ); + + //$result = $obj->getUnusedRouteGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedRouteGUID '); + $t->todo( "call to method getUnusedRouteGUID using "); + + + //checking method 'getUnusedStageGUID' + $t->can_ok( $obj, 'getUnusedStageGUID', 'getUnusedStageGUID() is callable' ); + + //$result = $obj->getUnusedStageGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedStageGUID '); + $t->todo( "call to method getUnusedStageGUID using "); + + + //checking method 'getUnusedSLGUID' + $t->can_ok( $obj, 'getUnusedSLGUID', 'getUnusedSLGUID() is callable' ); + + //$result = $obj->getUnusedSLGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedSLGUID '); + $t->todo( "call to method getUnusedSLGUID using "); + + + //checking method 'getUnusedRTGUID' + $t->can_ok( $obj, 'getUnusedRTGUID', 'getUnusedRTGUID() is callable' ); + + //$result = $obj->getUnusedRTGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedRTGUID '); + $t->todo( "call to method getUnusedRTGUID using "); + + + //checking method 'getUnusedRTVGUID' + $t->can_ok( $obj, 'getUnusedRTVGUID', 'getUnusedRTVGUID() is callable' ); + + //$result = $obj->getUnusedRTVGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedRTVGUID '); + $t->todo( "call to method getUnusedRTVGUID using "); + + + //checking method 'stepExists' + $t->can_ok( $obj, 'stepExists', 'stepExists() is callable' ); + + //$result = $obj->stepExists ( $sUid); + //$t->isa_ok( $result, 'NULL', 'call to method stepExists '); + $t->todo( "call to method stepExists using $sUid "); + + + //checking method 'getUnusedStepGUID' + $t->can_ok( $obj, 'getUnusedStepGUID', 'getUnusedStepGUID() is callable' ); + + //$result = $obj->getUnusedStepGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedStepGUID '); + $t->todo( "call to method getUnusedStepGUID using "); + + + //checking method 'getUnusedDynaformGUID' + $t->can_ok( $obj, 'getUnusedDynaformGUID', 'getUnusedDynaformGUID() is callable' ); + + //$result = $obj->getUnusedDynaformGUID ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getUnusedDynaformGUID '); + $t->todo( "call to method getUnusedDynaformGUID using "); + + + //checking method 'setProcessGUID' + $t->can_ok( $obj, 'setProcessGUID', 'setProcessGUID() is callable' ); + + //$result = $obj->setProcessGUID ( $oData, $sNewProUid); + //$t->isa_ok( $result, 'NULL', 'call to method setProcessGUID '); + $t->todo( "call to method setProcessGUID using $oData, $sNewProUid "); + + + //checking method 'setProcessParent' + $t->can_ok( $obj, 'setProcessParent', 'setProcessParent() is callable' ); + + //$result = $obj->setProcessParent ( $oData, $sParentUid); + //$t->isa_ok( $result, 'NULL', 'call to method setProcessParent '); + $t->todo( "call to method setProcessParent using $oData, $sParentUid "); + + + //checking method 'renewAllTaskGuid' + $t->can_ok( $obj, 'renewAllTaskGuid', 'renewAllTaskGuid() is callable' ); + + //$result = $obj->renewAllTaskGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllTaskGuid '); + $t->todo( "call to method renewAllTaskGuid using $oData "); + + + //checking method 'renewAllDynaformGuid' + $t->can_ok( $obj, 'renewAllDynaformGuid', 'renewAllDynaformGuid() is callable' ); + + //$result = $obj->renewAllDynaformGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllDynaformGuid '); + $t->todo( "call to method renewAllDynaformGuid using $oData "); + + + //checking method 'getProcessRow' + $t->can_ok( $obj, 'getProcessRow', 'getProcessRow() is callable' ); + + //$result = $obj->getProcessRow ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getProcessRow '); + $t->todo( "call to method getProcessRow using $sProUid "); + + + //checking method 'createProcessRow' + $t->can_ok( $obj, 'createProcessRow', 'createProcessRow() is callable' ); + + //$result = $obj->createProcessRow ( $row); + //$t->isa_ok( $result, 'NULL', 'call to method createProcessRow '); + $t->todo( "call to method createProcessRow using $row "); + + + //checking method 'updateProcessRow' + $t->can_ok( $obj, 'updateProcessRow', 'updateProcessRow() is callable' ); + + //$result = $obj->updateProcessRow ( $row); + //$t->isa_ok( $result, 'NULL', 'call to method updateProcessRow '); + $t->todo( "call to method updateProcessRow using $row "); + + + //checking method 'getSubProcessRow' + $t->can_ok( $obj, 'getSubProcessRow', 'getSubProcessRow() is callable' ); + + //$result = $obj->getSubProcessRow ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getSubProcessRow '); + $t->todo( "call to method getSubProcessRow using $sProUid "); + + + //checking method 'getCaseTrackerRow' + $t->can_ok( $obj, 'getCaseTrackerRow', 'getCaseTrackerRow() is callable' ); + + //$result = $obj->getCaseTrackerRow ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getCaseTrackerRow '); + $t->todo( "call to method getCaseTrackerRow using $sProUid "); + + + //checking method 'getCaseTrackerObjectRow' + $t->can_ok( $obj, 'getCaseTrackerObjectRow', 'getCaseTrackerObjectRow() is callable' ); + + //$result = $obj->getCaseTrackerObjectRow ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getCaseTrackerObjectRow '); + $t->todo( "call to method getCaseTrackerObjectRow using $sProUid "); + + + //checking method 'getStageRow' + $t->can_ok( $obj, 'getStageRow', 'getStageRow() is callable' ); + + //$result = $obj->getStageRow ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getStageRow '); + $t->todo( "call to method getStageRow using $sProUid "); + + + //checking method 'getAllLanes' + $t->can_ok( $obj, 'getAllLanes', 'getAllLanes() is callable' ); + + //$result = $obj->getAllLanes ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getAllLanes '); + $t->todo( "call to method getAllLanes using $sProUid "); + + + //checking method 'getTaskRows' + $t->can_ok( $obj, 'getTaskRows', 'getTaskRows() is callable' ); + + //$result = $obj->getTaskRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getTaskRows '); + $t->todo( "call to method getTaskRows using $sProUid "); + + + //checking method 'createTaskRows' + $t->can_ok( $obj, 'createTaskRows', 'createTaskRows() is callable' ); + + //$result = $obj->createTaskRows ( $aTasks); + //$t->isa_ok( $result, 'NULL', 'call to method createTaskRows '); + $t->todo( "call to method createTaskRows using $aTasks "); + + + //checking method 'updateTaskRows' + $t->can_ok( $obj, 'updateTaskRows', 'updateTaskRows() is callable' ); + + //$result = $obj->updateTaskRows ( $aTasks); + //$t->isa_ok( $result, 'NULL', 'call to method updateTaskRows '); + $t->todo( "call to method updateTaskRows using $aTasks "); + + + //checking method 'getRouteRows' + $t->can_ok( $obj, 'getRouteRows', 'getRouteRows() is callable' ); + + //$result = $obj->getRouteRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getRouteRows '); + $t->todo( "call to method getRouteRows using $sProUid "); + + + //checking method 'createRouteRows' + $t->can_ok( $obj, 'createRouteRows', 'createRouteRows() is callable' ); + + //$result = $obj->createRouteRows ( $aRoutes); + //$t->isa_ok( $result, 'NULL', 'call to method createRouteRows '); + $t->todo( "call to method createRouteRows using $aRoutes "); + + + //checking method 'updateRouteRows' + $t->can_ok( $obj, 'updateRouteRows', 'updateRouteRows() is callable' ); + + //$result = $obj->updateRouteRows ( $aRoutes); + //$t->isa_ok( $result, 'NULL', 'call to method updateRouteRows '); + $t->todo( "call to method updateRouteRows using $aRoutes "); + + + //checking method 'getLaneRows' + $t->can_ok( $obj, 'getLaneRows', 'getLaneRows() is callable' ); + + //$result = $obj->getLaneRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getLaneRows '); + $t->todo( "call to method getLaneRows using $sProUid "); + + + //checking method 'createLaneRows' + $t->can_ok( $obj, 'createLaneRows', 'createLaneRows() is callable' ); + + //$result = $obj->createLaneRows ( $aLanes); + //$t->isa_ok( $result, 'NULL', 'call to method createLaneRows '); + $t->todo( "call to method createLaneRows using $aLanes "); + + + //checking method 'createSubProcessRows' + $t->can_ok( $obj, 'createSubProcessRows', 'createSubProcessRows() is callable' ); + + //$result = $obj->createSubProcessRows ( $SubProcess); + //$t->isa_ok( $result, 'NULL', 'call to method createSubProcessRows '); + $t->todo( "call to method createSubProcessRows using $SubProcess "); + + + //checking method 'createCaseTrackerRows' + $t->can_ok( $obj, 'createCaseTrackerRows', 'createCaseTrackerRows() is callable' ); + + //$result = $obj->createCaseTrackerRows ( $CaseTracker); + //$t->isa_ok( $result, 'NULL', 'call to method createCaseTrackerRows '); + $t->todo( "call to method createCaseTrackerRows using $CaseTracker "); + + + //checking method 'createCaseTrackerObjectRows' + $t->can_ok( $obj, 'createCaseTrackerObjectRows', 'createCaseTrackerObjectRows() is callable' ); + + //$result = $obj->createCaseTrackerObjectRows ( $CaseTrackerObject); + //$t->isa_ok( $result, 'NULL', 'call to method createCaseTrackerObjectRows '); + $t->todo( "call to method createCaseTrackerObjectRows using $CaseTrackerObject "); + + + //checking method 'createObjectPermissionsRows' + $t->can_ok( $obj, 'createObjectPermissionsRows', 'createObjectPermissionsRows() is callable' ); + + //$result = $obj->createObjectPermissionsRows ( $ObjectPermissions); + //$t->isa_ok( $result, 'NULL', 'call to method createObjectPermissionsRows '); + $t->todo( "call to method createObjectPermissionsRows using $ObjectPermissions "); + + + //checking method 'createStageRows' + $t->can_ok( $obj, 'createStageRows', 'createStageRows() is callable' ); + + //$result = $obj->createStageRows ( $Stage); + //$t->isa_ok( $result, 'NULL', 'call to method createStageRows '); + $t->todo( "call to method createStageRows using $Stage "); + + + //checking method 'getInputRows' + $t->can_ok( $obj, 'getInputRows', 'getInputRows() is callable' ); + + //$result = $obj->getInputRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getInputRows '); + $t->todo( "call to method getInputRows using $sProUid "); + + + //checking method 'createInputRows' + $t->can_ok( $obj, 'createInputRows', 'createInputRows() is callable' ); + + //$result = $obj->createInputRows ( $aInput); + //$t->isa_ok( $result, 'NULL', 'call to method createInputRows '); + $t->todo( "call to method createInputRows using $aInput "); + + + //checking method 'renewAllInputGuid' + $t->can_ok( $obj, 'renewAllInputGuid', 'renewAllInputGuid() is callable' ); + + //$result = $obj->renewAllInputGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllInputGuid '); + $t->todo( "call to method renewAllInputGuid using $oData "); + + + //checking method 'getOutputRows' + $t->can_ok( $obj, 'getOutputRows', 'getOutputRows() is callable' ); + + //$result = $obj->getOutputRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getOutputRows '); + $t->todo( "call to method getOutputRows using $sProUid "); + + + //checking method 'createOutputRows' + $t->can_ok( $obj, 'createOutputRows', 'createOutputRows() is callable' ); + + //$result = $obj->createOutputRows ( $aOutput); + //$t->isa_ok( $result, 'NULL', 'call to method createOutputRows '); + $t->todo( "call to method createOutputRows using $aOutput "); + + + //checking method 'renewAllOutputGuid' + $t->can_ok( $obj, 'renewAllOutputGuid', 'renewAllOutputGuid() is callable' ); + + //$result = $obj->renewAllOutputGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllOutputGuid '); + $t->todo( "call to method renewAllOutputGuid using $oData "); + + + //checking method 'renewAllTriggerGuid' + $t->can_ok( $obj, 'renewAllTriggerGuid', 'renewAllTriggerGuid() is callable' ); + + //$result = $obj->renewAllTriggerGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllTriggerGuid '); + $t->todo( "call to method renewAllTriggerGuid using $oData "); + + + //checking method 'renewAllSubProcessGuid' + $t->can_ok( $obj, 'renewAllSubProcessGuid', 'renewAllSubProcessGuid() is callable' ); + + //$result = $obj->renewAllSubProcessGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllSubProcessGuid '); + $t->todo( "call to method renewAllSubProcessGuid using $oData "); + + + //checking method 'renewAllCaseTrackerObjectGuid' + $t->can_ok( $obj, 'renewAllCaseTrackerObjectGuid', 'renewAllCaseTrackerObjectGuid() is callable' ); + + //$result = $obj->renewAllCaseTrackerObjectGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllCaseTrackerObjectGuid '); + $t->todo( "call to method renewAllCaseTrackerObjectGuid using $oData "); + + + //checking method 'renewAllDBSourceGuid' + $t->can_ok( $obj, 'renewAllDBSourceGuid', 'renewAllDBSourceGuid() is callable' ); + + //$result = $obj->renewAllDBSourceGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllDBSourceGuid '); + $t->todo( "call to method renewAllDBSourceGuid using $oData "); + + + //checking method 'renewAllObjectPermissionGuid' + $t->can_ok( $obj, 'renewAllObjectPermissionGuid', 'renewAllObjectPermissionGuid() is callable' ); + + //$result = $obj->renewAllObjectPermissionGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllObjectPermissionGuid '); + $t->todo( "call to method renewAllObjectPermissionGuid using $oData "); + + + //checking method 'renewAllRouteGuid' + $t->can_ok( $obj, 'renewAllRouteGuid', 'renewAllRouteGuid() is callable' ); + + //$result = $obj->renewAllRouteGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllRouteGuid '); + $t->todo( "call to method renewAllRouteGuid using $oData "); + + + //checking method 'renewAllStageGuid' + $t->can_ok( $obj, 'renewAllStageGuid', 'renewAllStageGuid() is callable' ); + + //$result = $obj->renewAllStageGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllStageGuid '); + $t->todo( "call to method renewAllStageGuid using $oData "); + + + //checking method 'renewAllSwimlanesElementsGuid' + $t->can_ok( $obj, 'renewAllSwimlanesElementsGuid', 'renewAllSwimlanesElementsGuid() is callable' ); + + //$result = $obj->renewAllSwimlanesElementsGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllSwimlanesElementsGuid '); + $t->todo( "call to method renewAllSwimlanesElementsGuid using $oData "); + + + //checking method 'renewAllReportTableGuid' + $t->can_ok( $obj, 'renewAllReportTableGuid', 'renewAllReportTableGuid() is callable' ); + + //$result = $obj->renewAllReportTableGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllReportTableGuid '); + $t->todo( "call to method renewAllReportTableGuid using $oData "); + + + //checking method 'renewAllReportVarGuid' + $t->can_ok( $obj, 'renewAllReportVarGuid', 'renewAllReportVarGuid() is callable' ); + + //$result = $obj->renewAllReportVarGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllReportVarGuid '); + $t->todo( "call to method renewAllReportVarGuid using $oData "); + + + //checking method 'getStepRows' + $t->can_ok( $obj, 'getStepRows', 'getStepRows() is callable' ); + + //$result = $obj->getStepRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getStepRows '); + $t->todo( "call to method getStepRows using $sProUid "); + + + //checking method 'createStepRows' + $t->can_ok( $obj, 'createStepRows', 'createStepRows() is callable' ); + + //$result = $obj->createStepRows ( $aStep); + //$t->isa_ok( $result, 'NULL', 'call to method createStepRows '); + $t->todo( "call to method createStepRows using $aStep "); + + + //checking method 'createStepSupervisorRows' + $t->can_ok( $obj, 'createStepSupervisorRows', 'createStepSupervisorRows() is callable' ); + + //$result = $obj->createStepSupervisorRows ( $aStepSupervisor); + //$t->isa_ok( $result, 'NULL', 'call to method createStepSupervisorRows '); + $t->todo( "call to method createStepSupervisorRows using $aStepSupervisor "); + + + //checking method 'renewAllStepGuid' + $t->can_ok( $obj, 'renewAllStepGuid', 'renewAllStepGuid() is callable' ); + + //$result = $obj->renewAllStepGuid ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method renewAllStepGuid '); + $t->todo( "call to method renewAllStepGuid using $oData "); + + + //checking method 'getDynaformRows' + $t->can_ok( $obj, 'getDynaformRows', 'getDynaformRows() is callable' ); + + //$result = $obj->getDynaformRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getDynaformRows '); + $t->todo( "call to method getDynaformRows using $sProUid "); + + + //checking method 'getObjectPermissionRows' + $t->can_ok( $obj, 'getObjectPermissionRows', 'getObjectPermissionRows() is callable' ); + + //$result = $obj->getObjectPermissionRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getObjectPermissionRows '); + $t->todo( "call to method getObjectPermissionRows using $sProUid "); + + + //checking method 'createDynaformRows' + $t->can_ok( $obj, 'createDynaformRows', 'createDynaformRows() is callable' ); + + //$result = $obj->createDynaformRows ( $aDynaform); + //$t->isa_ok( $result, 'NULL', 'call to method createDynaformRows '); + $t->todo( "call to method createDynaformRows using $aDynaform "); + + + //checking method 'createStepTriggerRows' + $t->can_ok( $obj, 'createStepTriggerRows', 'createStepTriggerRows() is callable' ); + + //$result = $obj->createStepTriggerRows ( $aStepTrigger); + //$t->isa_ok( $result, 'NULL', 'call to method createStepTriggerRows '); + $t->todo( "call to method createStepTriggerRows using $aStepTrigger "); + + + //checking method 'getStepTriggerRows' + $t->can_ok( $obj, 'getStepTriggerRows', 'getStepTriggerRows() is callable' ); + + //$result = $obj->getStepTriggerRows ( $aTask); + //$t->isa_ok( $result, 'NULL', 'call to method getStepTriggerRows '); + $t->todo( "call to method getStepTriggerRows using $aTask "); + + + //checking method 'getTriggerRows' + $t->can_ok( $obj, 'getTriggerRows', 'getTriggerRows() is callable' ); + + //$result = $obj->getTriggerRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getTriggerRows '); + $t->todo( "call to method getTriggerRows using $sProUid "); + + + //checking method 'createTriggerRows' + $t->can_ok( $obj, 'createTriggerRows', 'createTriggerRows() is callable' ); + + //$result = $obj->createTriggerRows ( $aTrigger); + //$t->isa_ok( $result, 'NULL', 'call to method createTriggerRows '); + $t->todo( "call to method createTriggerRows using $aTrigger "); + + + //checking method 'getGroupwfRows' + $t->can_ok( $obj, 'getGroupwfRows', 'getGroupwfRows() is callable' ); + + //$result = $obj->getGroupwfRows ( $aGroups); + //$t->isa_ok( $result, 'NULL', 'call to method getGroupwfRows '); + $t->todo( "call to method getGroupwfRows using $aGroups "); + + + //checking method 'getDBConnectionsRows' + $t->can_ok( $obj, 'getDBConnectionsRows', 'getDBConnectionsRows() is callable' ); + + //$result = $obj->getDBConnectionsRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getDBConnectionsRows '); + $t->todo( "call to method getDBConnectionsRows using $sProUid "); + + + //checking method 'getStepSupervisorRows' + $t->can_ok( $obj, 'getStepSupervisorRows', 'getStepSupervisorRows() is callable' ); + + //$result = $obj->getStepSupervisorRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getStepSupervisorRows '); + $t->todo( "call to method getStepSupervisorRows using $sProUid "); + + + //checking method 'getReportTablesRows' + $t->can_ok( $obj, 'getReportTablesRows', 'getReportTablesRows() is callable' ); + + //$result = $obj->getReportTablesRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getReportTablesRows '); + $t->todo( "call to method getReportTablesRows using $sProUid "); + + + //checking method 'getReportTablesVarsRows' + $t->can_ok( $obj, 'getReportTablesVarsRows', 'getReportTablesVarsRows() is callable' ); + + //$result = $obj->getReportTablesVarsRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method getReportTablesVarsRows '); + $t->todo( "call to method getReportTablesVarsRows using $sProUid "); + + + //checking method 'getTaskUserRows' + $t->can_ok( $obj, 'getTaskUserRows', 'getTaskUserRows() is callable' ); + + //$result = $obj->getTaskUserRows ( $aTask); + //$t->isa_ok( $result, 'NULL', 'call to method getTaskUserRows '); + $t->todo( "call to method getTaskUserRows using $aTask "); + + + //checking method 'createTaskUserRows' + $t->can_ok( $obj, 'createTaskUserRows', 'createTaskUserRows() is callable' ); + + //$result = $obj->createTaskUserRows ( $aTaskUser); + //$t->isa_ok( $result, 'NULL', 'call to method createTaskUserRows '); + $t->todo( "call to method createTaskUserRows using $aTaskUser "); + + + //checking method 'createGroupRow' + $t->can_ok( $obj, 'createGroupRow', 'createGroupRow() is callable' ); + + //$result = $obj->createGroupRow ( $aGroupwf); + //$t->isa_ok( $result, 'NULL', 'call to method createGroupRow '); + $t->todo( "call to method createGroupRow using $aGroupwf "); + + + //checking method 'createDBConnectionsRows' + $t->can_ok( $obj, 'createDBConnectionsRows', 'createDBConnectionsRows() is callable' ); + + //$result = $obj->createDBConnectionsRows ( $aConnections); + //$t->isa_ok( $result, 'NULL', 'call to method createDBConnectionsRows '); + $t->todo( "call to method createDBConnectionsRows using $aConnections "); + + + //checking method 'createReportTables' + $t->can_ok( $obj, 'createReportTables', 'createReportTables() is callable' ); + + //$result = $obj->createReportTables ( $aReportTables, $aReportTablesVars); + //$t->isa_ok( $result, 'NULL', 'call to method createReportTables '); + $t->todo( "call to method createReportTables using $aReportTables, $aReportTablesVars "); + + + //checking method 'updateReportTables' + $t->can_ok( $obj, 'updateReportTables', 'updateReportTables() is callable' ); + + //$result = $obj->updateReportTables ( $aReportTables, $aReportTablesVars); + //$t->isa_ok( $result, 'NULL', 'call to method updateReportTables '); + $t->todo( "call to method updateReportTables using $aReportTables, $aReportTablesVars "); + + + //checking method 'createReportTablesVars' + $t->can_ok( $obj, 'createReportTablesVars', 'createReportTablesVars() is callable' ); + + //$result = $obj->createReportTablesVars ( $aReportTablesVars); + //$t->isa_ok( $result, 'NULL', 'call to method createReportTablesVars '); + $t->todo( "call to method createReportTablesVars using $aReportTablesVars "); + + + //checking method 'cleanupReportTablesReferences' + $t->can_ok( $obj, 'cleanupReportTablesReferences', 'cleanupReportTablesReferences() is callable' ); + + //$result = $obj->cleanupReportTablesReferences ( $aReportTables); + //$t->isa_ok( $result, 'NULL', 'call to method cleanupReportTablesReferences '); + $t->todo( "call to method cleanupReportTablesReferences using $aReportTables "); + + + //checking method 'serializeProcess' + $t->can_ok( $obj, 'serializeProcess', 'serializeProcess() is callable' ); + + //$result = $obj->serializeProcess ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method serializeProcess '); + $t->todo( "call to method serializeProcess using $sProUid "); + + + //checking method 'saveSerializedProcess' + $t->can_ok( $obj, 'saveSerializedProcess', 'saveSerializedProcess() is callable' ); + + //$result = $obj->saveSerializedProcess ( $oData); + //$t->isa_ok( $result, 'NULL', 'call to method saveSerializedProcess '); + $t->todo( "call to method saveSerializedProcess using $oData "); + + + //checking method 'getProcessData' + $t->can_ok( $obj, 'getProcessData', 'getProcessData() is callable' ); + + //$result = $obj->getProcessData ( $pmFilename); + //$t->isa_ok( $result, 'NULL', 'call to method getProcessData '); + $t->todo( "call to method getProcessData using $pmFilename "); + + + //checking method 'disablePreviousProcesses' + $t->can_ok( $obj, 'disablePreviousProcesses', 'disablePreviousProcesses() is callable' ); + + //$result = $obj->disablePreviousProcesses ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method disablePreviousProcesses '); + $t->todo( "call to method disablePreviousProcesses using $sProUid "); + + + //checking method 'createFiles' + $t->can_ok( $obj, 'createFiles', 'createFiles() is callable' ); + + //$result = $obj->createFiles ( $oData, $pmFilename); + //$t->isa_ok( $result, 'NULL', 'call to method createFiles '); + $t->todo( "call to method createFiles using $oData, $pmFilename "); + + + //checking method 'removeProcessRows' + $t->can_ok( $obj, 'removeProcessRows', 'removeProcessRows() is callable' ); + + //$result = $obj->removeProcessRows ( $sProUid); + //$t->isa_ok( $result, 'NULL', 'call to method removeProcessRows '); + $t->todo( "call to method removeProcessRows using $sProUid "); + + + //checking method 'createProcessFromData' + $t->can_ok( $obj, 'createProcessFromData', 'createProcessFromData() is callable' ); + + //$result = $obj->createProcessFromData ( $oData, $pmFilename); + //$t->isa_ok( $result, 'NULL', 'call to method createProcessFromData '); + $t->todo( "call to method createProcessFromData using $oData, $pmFilename "); + + + //checking method 'updateProcessFromData' + $t->can_ok( $obj, 'updateProcessFromData', 'updateProcessFromData() is callable' ); + + //$result = $obj->updateProcessFromData ( $oData, $pmFilename); + //$t->isa_ok( $result, 'NULL', 'call to method updateProcessFromData '); + $t->todo( "call to method updateProcessFromData using $oData, $pmFilename "); + + + //checking method 'getStartingTaskForUser' + $t->can_ok( $obj, 'getStartingTaskForUser', 'getStartingTaskForUser() is callable' ); + + //$result = $obj->getStartingTaskForUser ( $sProUid, $sUsrUid); + //$t->isa_ok( $result, 'NULL', 'call to method getStartingTaskForUser '); + $t->todo( "call to method getStartingTaskForUser using $sProUid, $sUsrUid "); + + + //checking method 'ws_open' + $t->can_ok( $obj, 'ws_open', 'ws_open() is callable' ); + + //$result = $obj->ws_open ( $user, $pass); + //$t->isa_ok( $result, 'NULL', 'call to method ws_open '); + $t->todo( "call to method ws_open using $user, $pass "); + + + //checking method 'ws_open_public' + $t->can_ok( $obj, 'ws_open_public', 'ws_open_public() is callable' ); + + //$result = $obj->ws_open_public ( ); + //$t->isa_ok( $result, 'NULL', 'call to method ws_open_public '); + $t->todo( "call to method ws_open_public using "); + + + //checking method 'ws_processList' + $t->can_ok( $obj, 'ws_processList', 'ws_processList() is callable' ); + + //$result = $obj->ws_processList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method ws_processList '); + $t->todo( "call to method ws_processList using "); + + + //checking method 'downloadFile' + $t->can_ok( $obj, 'downloadFile', 'downloadFile() is callable' ); + + //$result = $obj->downloadFile ( $file, $local_path, $newfilename); + //$t->isa_ok( $result, 'NULL', 'call to method downloadFile '); + $t->todo( "call to method downloadFile using $file, $local_path, $newfilename "); + + + //checking method 'ws_processGetData' + $t->can_ok( $obj, 'ws_processGetData', 'ws_processGetData() is callable' ); + + //$result = $obj->ws_processGetData ( $proId); + //$t->isa_ok( $result, 'NULL', 'call to method ws_processGetData '); + $t->todo( "call to method ws_processGetData using $proId "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classPropelTableTest.php b/workflow/engine/test/unit/processmaker/classPropelTableTest.php new file mode 100644 index 000000000..fb4eeb599 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classPropelTableTest.php @@ -0,0 +1,112 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + //$className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 8, "class $className have " . 8 . ' methods.' ); + + //checking method 'prepareQuery' + $t->can_ok( $obj, 'prepareQuery', 'prepareQuery() is callable' ); + + //$result = $obj->prepareQuery ( $limitPage); + //$t->isa_ok( $result, 'NULL', 'call to method prepareQuery '); + $t->todo( "call to method prepareQuery using $limitPage "); + + + //checking method 'setupFromXmlform' + $t->can_ok( $obj, 'setupFromXmlform', 'setupFromXmlform() is callable' ); + + //$result = $obj->setupFromXmlform ( $xmlForm); + //$t->isa_ok( $result, 'NULL', 'call to method setupFromXmlform '); + $t->todo( "call to method setupFromXmlform using $xmlForm "); + + + //checking method 'count' + $t->can_ok( $obj, 'count', 'count() is callable' ); + + //$result = $obj->count ( ); + //$t->isa_ok( $result, 'NULL', 'call to method count '); + $t->todo( "call to method count using "); + + + //checking method 'renderTitle' + $t->can_ok( $obj, 'renderTitle', 'renderTitle() is callable' ); + + //$result = $obj->renderTitle ( ); + //$t->isa_ok( $result, 'NULL', 'call to method renderTitle '); + $t->todo( "call to method renderTitle using "); + + + //checking method 'renderField' + $t->can_ok( $obj, 'renderField', 'renderField() is callable' ); + + //$result = $obj->renderField ( $row, $r, $result); + //$t->isa_ok( $result, 'NULL', 'call to method renderField '); + $t->todo( "call to method renderField using $row, $r, $result "); + + + //checking method 'defaultStyle' + $t->can_ok( $obj, 'defaultStyle', 'defaultStyle() is callable' ); + + //$result = $obj->defaultStyle ( ); + //$t->isa_ok( $result, 'NULL', 'call to method defaultStyle '); + $t->todo( "call to method defaultStyle using "); + + + //checking method 'renderTable' + $t->can_ok( $obj, 'renderTable', 'renderTable() is callable' ); + + //$result = $obj->renderTable ( $block, $fields); + //$t->isa_ok( $result, 'NULL', 'call to method renderTable '); + $t->todo( "call to method renderTable using $block, $fields "); + + + //checking method 'printForm' + $t->can_ok( $obj, 'printForm', 'printForm() is callable' ); + + //$result = $obj->printForm ( $filename, $data); + //$t->isa_ok( $result, 'NULL', 'call to method printForm '); + $t->todo( "call to method printForm using $filename, $data "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classReportTablesTest.php b/workflow/engine/test/unit/processmaker/classReportTablesTest.php new file mode 100644 index 000000000..392bbcbbc --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classReportTablesTest.php @@ -0,0 +1,112 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 11, "class $className have " . 11 . ' methods.' ); + + //checking method 'deleteAllReportVars' + $t->can_ok( $obj, 'deleteAllReportVars', 'deleteAllReportVars() is callable' ); + + //$result = $obj->deleteAllReportVars ( $sRepTabUid); + //$t->isa_ok( $result, 'NULL', 'call to method deleteAllReportVars '); + $t->todo( "call to method deleteAllReportVars using $sRepTabUid "); + + + //checking method 'dropTable' + $t->can_ok( $obj, 'dropTable', 'dropTable() is callable' ); + + //$result = $obj->dropTable ( $sTableName, $sConnection); + //$t->isa_ok( $result, 'NULL', 'call to method dropTable '); + $t->todo( "call to method dropTable using $sTableName, $sConnection "); + + + //checking method 'createTable' + $t->can_ok( $obj, 'createTable', 'createTable() is callable' ); + + //$result = $obj->createTable ( $sTableName, $sConnection, $sType, $aFields, $bDefaultFields); + //$t->isa_ok( $result, 'NULL', 'call to method createTable '); + $t->todo( "call to method createTable using $sTableName, $sConnection, $sType, $aFields, $bDefaultFields "); + + + //checking method 'populateTable' + $t->can_ok( $obj, 'populateTable', 'populateTable() is callable' ); + + //$result = $obj->populateTable ( $sTableName, $sConnection, $sType, $aFields, $sProcessUid, $sGrid); + //$t->isa_ok( $result, 'NULL', 'call to method populateTable '); + $t->todo( "call to method populateTable using $sTableName, $sConnection, $sType, $aFields, $sProcessUid, $sGrid "); + + + //checking method 'getTableVars' + $t->can_ok( $obj, 'getTableVars', 'getTableVars() is callable' ); + + //$result = $obj->getTableVars ( $sRepTabUid, $bWhitType); + //$t->isa_ok( $result, 'NULL', 'call to method getTableVars '); + $t->todo( "call to method getTableVars using $sRepTabUid, $bWhitType "); + + + //checking method 'deleteReportTable' + $t->can_ok( $obj, 'deleteReportTable', 'deleteReportTable() is callable' ); + + //$result = $obj->deleteReportTable ( $sRepTabUid); + //$t->isa_ok( $result, 'NULL', 'call to method deleteReportTable '); + $t->todo( "call to method deleteReportTable using $sRepTabUid "); + + + //checking method 'updateTables' + $t->can_ok( $obj, 'updateTables', 'updateTables() is callable' ); + + //$result = $obj->updateTables ( $sProcessUid, $sApplicationUid, $iApplicationNumber, $aFields); + //$t->isa_ok( $result, 'NULL', 'call to method updateTables '); + $t->todo( "call to method updateTables using $sProcessUid, $sApplicationUid, $iApplicationNumber, $aFields "); + + + //checking method 'tableExist' + $t->can_ok( $obj, 'tableExist', 'tableExist() is callable' ); + + //$result = $obj->tableExist ( ); + //$t->isa_ok( $result, 'NULL', 'call to method tableExist '); + $t->todo( "call to method tableExist using "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classReportTest.php b/workflow/engine/test/unit/processmaker/classReportTest.php new file mode 100644 index 000000000..c5f01ecd4 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classReportTest.php @@ -0,0 +1,162 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , 'Report', 'class $className created'); + + $t->is( count($methods) , 14, "class $className have " . 14 . ' methods.' ); + + //checking method 'generatedReport1' + $t->can_ok( $obj, 'generatedReport1', 'generatedReport1() is callable' ); + + //$result = $obj->generatedReport1 ( ); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport1 '); + $t->todo( "call to method generatedReport1 using "); + + + //checking method 'generatedReport1_filter' + $t->can_ok( $obj, 'generatedReport1_filter', 'generatedReport1_filter() is callable' ); + + //$result = $obj->generatedReport1_filter ( $from, $to, $startedby); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport1_filter '); + $t->todo( "call to method generatedReport1_filter using $from, $to, $startedby "); + + + //checking method 'descriptionReport1' + $t->can_ok( $obj, 'descriptionReport1', 'descriptionReport1() is callable' ); + + //$result = $obj->descriptionReport1 ( $PRO_UID); + //$t->isa_ok( $result, 'NULL', 'call to method descriptionReport1 '); + $t->todo( "call to method descriptionReport1 using $PRO_UID "); + + + //checking method 'generatedReport2' + $t->can_ok( $obj, 'generatedReport2', 'generatedReport2() is callable' ); + + //$result = $obj->generatedReport2 ( ); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport2 '); + $t->todo( "call to method generatedReport2 using "); + + + //checking method 'reports_Description_filter' + $t->can_ok( $obj, 'reports_Description_filter', 'reports_Description_filter() is callable' ); + + //$result = $obj->reports_Description_filter ( $from, $to, $startedby, $PRO_UID); + //$t->isa_ok( $result, 'NULL', 'call to method reports_Description_filter '); + $t->todo( "call to method reports_Description_filter using $from, $to, $startedby, $PRO_UID "); + + + //checking method 'generatedReport2_filter' + $t->can_ok( $obj, 'generatedReport2_filter', 'generatedReport2_filter() is callable' ); + + //$result = $obj->generatedReport2_filter ( $from, $to, $startedby); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport2_filter '); + $t->todo( "call to method generatedReport2_filter using $from, $to, $startedby "); + + + //checking method 'generatedReport3' + $t->can_ok( $obj, 'generatedReport3', 'generatedReport3() is callable' ); + + //$result = $obj->generatedReport3 ( ); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport3 '); + $t->todo( "call to method generatedReport3 using "); + + + //checking method 'generatedReport3_filter' + $t->can_ok( $obj, 'generatedReport3_filter', 'generatedReport3_filter() is callable' ); + + //$result = $obj->generatedReport3_filter ( $process, $task); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport3_filter '); + $t->todo( "call to method generatedReport3_filter using $process, $task "); + + + //checking method 'generatedReport4' + $t->can_ok( $obj, 'generatedReport4', 'generatedReport4() is callable' ); + + //$result = $obj->generatedReport4 ( ); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport4 '); + $t->todo( "call to method generatedReport4 using "); + + + //checking method 'generatedReport4_filter' + $t->can_ok( $obj, 'generatedReport4_filter', 'generatedReport4_filter() is callable' ); + + //$result = $obj->generatedReport4_filter ( $process, $task); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport4_filter '); + $t->todo( "call to method generatedReport4_filter using $process, $task "); + + + //checking method 'generatedReport5' + $t->can_ok( $obj, 'generatedReport5', 'generatedReport5() is callable' ); + + //$result = $obj->generatedReport5 ( ); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport5 '); + $t->todo( "call to method generatedReport5 using "); + + + //checking method 'generatedReport5_filter' + $t->can_ok( $obj, 'generatedReport5_filter', 'generatedReport5_filter() is callable' ); + + //$result = $obj->generatedReport5_filter ( $process, $task); + //$t->isa_ok( $result, 'NULL', 'call to method generatedReport5_filter '); + $t->todo( "call to method generatedReport5_filter using $process, $task "); + + + //checking method 'getAvailableReports' + $t->can_ok( $obj, 'getAvailableReports', 'getAvailableReports() is callable' ); + + //$result = $obj->getAvailableReports ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getAvailableReports '); + $t->todo( "call to method getAvailableReports using "); + + + //checking method 'reportsPatch' + $t->can_ok( $obj, 'reportsPatch', 'reportsPatch() is callable' ); + + //$result = $obj->reportsPatch ( ); + //$t->isa_ok( $result, 'NULL', 'call to method reportsPatch '); + $t->todo( "call to method reportsPatch using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classRouteTest.php b/workflow/engine/test/unit/processmaker/classRouteTest.php new file mode 100644 index 000000000..19d29529c --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classRouteTest.php @@ -0,0 +1,136 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . '/lime/lime.php'); +require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadSystem('testTools'); +require_once(PATH_CORE . 'classes/model/Route.php'); + +$obj = new Route(); +$t = new lime_test(13, new lime_output_color()); + +$t->diag('Class Route'); + +//class Route +$t->isa_ok($obj, 'Route', 'Class Route created!'); + +//method load +$t->can_ok($obj, 'load', 'load() is callable!'); + +//method create +$t->can_ok($obj, 'create', 'create() is callable!'); + +//method update +$t->can_ok($obj, 'update', 'update() is callable!'); + +//method remove +$t->can_ok($obj, 'remove', 'remove() is callable!'); + +/***** TEST CLASS ROUTE *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class RouteTest extends unitTest +{ + function loadTest($aTestData, $aFields) + { + $oRoute = new Route(); + try { + return $oRoute->load($aFields['ROU_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createTest($aTestData, $aFields) + { + $oRoute = new Route(); + try { + return $oRoute->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTest($aTestData, $aFields) + { + $oRoute = new Route(); + try { + return $oRoute->update($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oRoute = new Route(); + try { + return $oRoute->remove($aFields['ROU_UID']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oRouteTest = new RouteTest('route.yml', $t, new ymlDomain()); +$oRouteTest->load('load1'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('load2'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('create1'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('create2'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('update1'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('update2'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('remove1'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oRouteTest->load('remove2'); +$vAux = $oRouteTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classSessionsTest.php b/workflow/engine/test/unit/processmaker/classSessionsTest.php new file mode 100644 index 000000000..3ddfab181 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classSessionsTest.php @@ -0,0 +1,65 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , $className, "class $className created"); + + //$t->is( count($methods) , 2, "class $className have " . 2 . ' methods.' ); + $t->is( count($methods) , 7, "class $className have " . 7 . ' methods.' ); + + //checking method 'getSessionUser' + $t->can_ok( $obj, 'getSessionUser', 'getSessionUser() is callable' ); + + //$result = $obj->getSessionUser ( $sSessionId); + //$t->isa_ok( $result, 'NULL', 'call to method getSessionUser '); + $t->todo( "call to method getSessionUser using $sSessionId "); + + + //checking method 'verifySession' + $t->can_ok( $obj, 'verifySession', 'verifySession() is callable' ); + + //$result = $obj->verifySession ( $sSessionId); + //$t->isa_ok( $result, 'NULL', 'call to method verifySession '); + $t->todo( "call to method verifySession using $sSessionId "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classSmtpTest.php b/workflow/engine/test/unit/processmaker/classSmtpTest.php new file mode 100644 index 000000000..6569f42a9 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classSmtpTest.php @@ -0,0 +1,153 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , $className, 'class $className created'); + + $t->is( count($methods) , 13, "class $className have " . 13 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( ); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using "); + + + //checking method 'setServer' + $t->can_ok( $obj, 'setServer', 'setServer() is callable' ); + + //$result = $obj->setServer ( $sServer); + //$t->isa_ok( $result, 'NULL', 'call to method setServer '); + $t->todo( "call to method setServer using $sServer "); + + + //checking method 'setPort' + $t->can_ok( $obj, 'setPort', 'setPort() is callable' ); + + //$result = $obj->setPort ( $iPort); + //$t->isa_ok( $result, 'NULL', 'call to method setPort '); + $t->todo( "call to method setPort using $iPort "); + + + //checking method 'setReturnPath' + $t->can_ok( $obj, 'setReturnPath', 'setReturnPath() is callable' ); + + //$result = $obj->setReturnPath ( $sReturnPath); + //$t->isa_ok( $result, 'NULL', 'call to method setReturnPath '); + $t->todo( "call to method setReturnPath using $sReturnPath "); + + + //checking method 'setHeaders' + $t->can_ok( $obj, 'setHeaders', 'setHeaders() is callable' ); + + //$result = $obj->setHeaders ( $sHeaders); + //$t->isa_ok( $result, 'NULL', 'call to method setHeaders '); + $t->todo( "call to method setHeaders using $sHeaders "); + + + //checking method 'setBody' + $t->can_ok( $obj, 'setBody', 'setBody() is callable' ); + + //$result = $obj->setBody ( $sBody); + //$t->isa_ok( $result, 'NULL', 'call to method setBody '); + $t->todo( "call to method setBody using $sBody "); + + + //checking method 'setSmtpAuthentication' + $t->can_ok( $obj, 'setSmtpAuthentication', 'setSmtpAuthentication() is callable' ); + + //$result = $obj->setSmtpAuthentication ( $sAuth); + //$t->isa_ok( $result, 'NULL', 'call to method setSmtpAuthentication '); + $t->todo( "call to method setSmtpAuthentication using $sAuth "); + + + //checking method 'setUsername' + $t->can_ok( $obj, 'setUsername', 'setUsername() is callable' ); + + //$result = $obj->setUsername ( $sName); + //$t->isa_ok( $result, 'NULL', 'call to method setUsername '); + $t->todo( "call to method setUsername using $sName "); + + + //checking method 'setPassword' + $t->can_ok( $obj, 'setPassword', 'setPassword() is callable' ); + + //$result = $obj->setPassword ( $sPass); + //$t->isa_ok( $result, 'NULL', 'call to method setPassword '); + $t->todo( "call to method setPassword using $sPass "); + + + //checking method 'returnErrors' + $t->can_ok( $obj, 'returnErrors', 'returnErrors() is callable' ); + + //$result = $obj->returnErrors ( ); + //$t->isa_ok( $result, 'NULL', 'call to method returnErrors '); + $t->todo( "call to method returnErrors using "); + + + //checking method 'returnStatus' + $t->can_ok( $obj, 'returnStatus', 'returnStatus() is callable' ); + + //$result = $obj->returnStatus ( ); + //$t->isa_ok( $result, 'NULL', 'call to method returnStatus '); + $t->todo( "call to method returnStatus using "); + + + //checking method 'setEnvelopeTo' + $t->can_ok( $obj, 'setEnvelopeTo', 'setEnvelopeTo() is callable' ); + + //$result = $obj->setEnvelopeTo ( $env_to); + //$t->isa_ok( $result, 'NULL', 'call to method setEnvelopeTo '); + $t->todo( "call to method setEnvelopeTo using $env_to "); + + + //checking method 'sendMessage' + $t->can_ok( $obj, 'sendMessage', 'sendMessage() is callable' ); + + //$result = $obj->sendMessage ( ); + //$t->isa_ok( $result, 'NULL', 'call to method sendMessage '); + $t->todo( "call to method sendMessage using "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classSpoolRunTest.php b/workflow/engine/test/unit/processmaker/classSpoolRunTest.php new file mode 100644 index 000000000..30316a88d --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classSpoolRunTest.php @@ -0,0 +1,160 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + require_once( 'propel/Propel.php' ); + require_once ( "creole/Creole.php" ); + require_once ( PATH_CORE . "config/databases.php"); + + G::LoadClass ( 'spool'); + + +// $obj = new SpoolRun ($dbc); + $t = new lime_test( 24, new lime_output_color() ); + + $className = SpoolRun; + $className = strtolower ( substr ($className, 0,1) ) . substr ($className, 1 ); + + $reflect = new ReflectionClass( $className ); + $method = array ( ); + $testItems = 0; + + foreach ( $reflect->getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 12, "class $className have " . 12 . ' methods.' ); + // Methods + $aMethods = array_keys ( $methods ); + //checking method '__construct' + $t->is ( $aMethods[0], '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( ); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using "); + + + //checking method 'getSpoolFilesList' + $t->is ( $aMethods[1], 'getSpoolFilesList', 'getSpoolFilesList() is callable' ); + + //$result = $obj->getSpoolFilesList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getSpoolFilesList '); + $t->todo( "call to method getSpoolFilesList using "); + + + //checking method 'create' + $t->is ( $aMethods[2], 'create', 'create() is callable' ); + + //$result = $obj->create ( $aData); + //$t->isa_ok( $result, 'NULL', 'call to method create '); + $t->todo( "call to method create using $aData "); + + + //checking method 'setConfig' + $t->is ( $aMethods[3], 'setConfig', 'setConfig() is callable' ); + + //$result = $obj->setConfig ( $aConfig); + //$t->isa_ok( $result, 'NULL', 'call to method setConfig '); + $t->todo( "call to method setConfig using $aConfig "); + + + //checking method 'setData' + $t->is ( $aMethods[4], 'setData', 'setData() is callable' ); + + //$result = $obj->setData ( $sAppMsgUid, $sSubject, $sFrom, $sTo, $sBody, $sDate, $sCC, $sBCC, $sTemplate); + //$t->isa_ok( $result, 'NULL', 'call to method setData '); + $t->todo( "call to method setData using $sAppMsgUid, $sSubject, $sFrom, $sTo, $sBody, $sDate, $sCC, $sBCC, $sTemplate "); + + + //checking method 'sendMail' + $t->is ( $aMethods[5], 'sendMail', 'sendMail() is callable' ); + + //$result = $obj->sendMail ( ); + //$t->isa_ok( $result, 'NULL', 'call to method sendMail '); + $t->todo( "call to method sendMail using "); + + + //checking method 'updateSpoolStatus' + $t->is ( $aMethods[6], 'updateSpoolStatus', 'updateSpoolStatus() is callable' ); + + //$result = $obj->updateSpoolStatus ( ); + //$t->isa_ok( $result, 'NULL', 'call to method updateSpoolStatus '); + $t->todo( "call to method updateSpoolStatus using "); + + + //checking method 'handleFrom' + $t->is ( $aMethods[7], 'handleFrom', 'handleFrom() is callable' ); + + //$result = $obj->handleFrom ( ); + //$t->isa_ok( $result, 'NULL', 'call to method handleFrom '); + $t->todo( "call to method handleFrom using "); + + + //checking method 'handleEnvelopeTo' + $t->is ( $aMethods[8], 'handleEnvelopeTo', 'handleEnvelopeTo() is callable' ); + + //$result = $obj->handleEnvelopeTo ( ); + //$t->isa_ok( $result, 'NULL', 'call to method handleEnvelopeTo '); + $t->todo( "call to method handleEnvelopeTo using "); + + + //checking method 'handleMail' + $t->is ( $aMethods[9], 'handleMail', 'handleMail() is callable' ); + + //$result = $obj->handleMail ( ); + //$t->isa_ok( $result, 'NULL', 'call to method handleMail '); + $t->todo( "call to method handleMail using "); + + + //checking method 'resendEmails' + $t->is ( $aMethods[10], 'resendEmails', 'resendEmails() is callable' ); + + //$result = $obj->resendEmails ( ); + //$t->isa_ok( $result, 'NULL', 'call to method resendEmails '); + $t->todo( "call to method resendEmails using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classStepTest.php b/workflow/engine/test/unit/processmaker/classStepTest.php new file mode 100755 index 000000000..86cac80d8 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classStepTest.php @@ -0,0 +1,132 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + //G::LoadClass ( 'user'); + G::LoadSystem ( 'testTools'); + require_once(PATH_CORE.'/classes/model/Step.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Step ($dbc); + $t = new lime_test( 9, new lime_output_color() ); + + $t->diag('class Step' ); + $t->isa_ok( $obj , 'Step', 'class Step created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class StepTest extends UnitTest + { + function CreateStep($data,$fields) + { + try + { + $Step=new Step(); + $result=$Step->create($fields); + $this->domain->addDomainValue('CREATED',$Step->getStepUid()); + return $result; + } + catch(Exception $e) + { + $result=array('Exception!! '=> $e->getMessage()); + if(isset($e->aValidationFailures)) + $result['ValidationFailures'] = $e->aValidationFailures; + return $result; + } + } + function UpdateStep($data,$fields) + { + try + { + $Step=new Step(); + $result=$Step->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadStep($data,$fields) + { + try + { + $Step=new Step(); + $result=$Step->load($fields['STEP_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveStep($data,$fields) + { + try + { + $Step=new Step(); + $result=$Step->remove($fields['STEP_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new StepTest('step.yml',$t); + $test->domain->addDomain('CREATED'); + $test->load('CreateTestSteps'); + $test->runAll(); + $test->load('StepUnitTest'); + $test->runAll(); diff --git a/workflow/engine/test/unit/processmaker/classStepTriggerTest.php b/workflow/engine/test/unit/processmaker/classStepTriggerTest.php new file mode 100644 index 000000000..1afd57b93 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classStepTriggerTest.php @@ -0,0 +1,137 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + //G::LoadClass ( 'user'); + G::LoadSystem ( 'testTools'); + require_once(PATH_CORE.'/classes/model/StepTrigger.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new StepTrigger ($dbc); + $t = new lime_test( 5, new lime_output_color() ); + + $t->diag('class StepTrigger' ); + $t->isa_ok( $obj , 'StepTrigger', 'class StepTrigger created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class StepTriggerTest extends UnitTest + { + function CreateStepTrigger($data,$fields) + { + try + { + $StepTrigger=new StepTrigger(); + $result=$StepTrigger->create($fields); + $this->domain->addDomainValue('CREATED',$StepTrigger->getStepUid()); + $this->domain->addDomainValue('CREATED_TAS',$StepTrigger->getTasUid()); + $this->domain->addDomainValue('CREATED_TRI',$StepTrigger->getTriUid()); + $this->domain->addDomainValue('CREATED_TYPE',$StepTrigger->getStType()); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function UpdateStepTrigger($data,$fields) + { + try + { + $StepTrigger=new StepTrigger(); + $result=$StepTrigger->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadStepTrigger($data,$fields) + { + try + { + $StepTrigger=new StepTrigger(); + $result=$StepTrigger->load($fields['STEP_UID'],$fields['TAS_UID'],$fields['TRI_UID'],$fields['ST_TYPE']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveStepTrigger($data,$fields) + { + try + { + $StepTrigger=new StepTrigger(); + $result=$StepTrigger->remove($fields['STEP_UID'],$fields['TAS_UID'],$fields['TRI_UID'],$fields['ST_TYPE']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new StepTriggerTest('StepTrigger.yml',$t); + /* + $this->domain->addDomainValue('CREATED'); + $this->domain->addDomainValue('CREATED_TAS'); + $this->domain->addDomainValue('CREATED_TRI'); + $this->domain->addDomainValue('CREATED_TYPE'); + */ + $test->load('CreateTestStepTriggers'); + $test->runAll(); + $test->load('StepTriggerUnitTest'); + $test->runAll(); diff --git a/workflow/engine/test/unit/processmaker/classSwimlanesElementsTest.php b/workflow/engine/test/unit/processmaker/classSwimlanesElementsTest.php new file mode 100644 index 000000000..0ca26d080 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classSwimlanesElementsTest.php @@ -0,0 +1,142 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . '/lime/lime.php'); +require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadSystem('testTools'); +require_once(PATH_CORE . 'classes/model/SwimlanesElements.php'); + +$obj = new SwimlanesElements(); +$t = new lime_test(7, new lime_output_color()); + +$t->diag('Class SwimlanesElements'); + +//class SwimlanesElements +$t->isa_ok($obj, 'SwimlanesElements', 'Class SwimlanesElements created!'); + +//method load +$t->can_ok($obj, 'load', 'load() is callable!'); + +//method create +$t->can_ok($obj, 'create', 'create() is callable!'); + +//method update +$t->can_ok($obj, 'update', 'update() is callable!'); + +//method remove +$t->can_ok($obj, 'remove', 'remove() is callable!'); + +//method getSwiEleText +$t->can_ok($obj, 'getSwiEleText', 'getSwiEleText() is callable!'); + +//method setSwiEleText +$t->can_ok($obj, 'setSwiEleText', 'setSwiEleText() is callable!'); + +/***** TEST CLASS SWIMLANESELEMENTS *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class SwimlanesElementsTest extends unitTest +{ + function loadTest($aTestData, $aFields) + { + $oSwimlanesElements = new SwimlanesElements(); + try { + return $oSwimlanesElements->load($aFields['SWI_UID']); + } + catch (Exception $oError) { + return $oError; + } + } + function createTest($aTestData, $aFields) + { + $oSwimlanesElements = new SwimlanesElements(); + try { + return $oSwimlanesElements->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function updateTest($aTestData, $aFields) + { + $oSwimlanesElements = new SwimlanesElements(); + try { + return $oSwimlanesElements->update($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oSwimlanesElements = new SwimlanesElements(); + try { + return $oSwimlanesElements->remove($aFields['SWI_UID']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oSwimlanesElementsTest = new SwimlanesElementsTest('swimlanesElements.yml', $t, new ymlDomain()); +$oSwimlanesElementsTest->load('load1'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('load2'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('create1'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('create2'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n";*/ +$oSwimlanesElementsTest->load('update1'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('update2'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('remove1'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oSwimlanesElementsTest->load('remove2'); +$vAux = $oSwimlanesElementsTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classTaskTest.php b/workflow/engine/test/unit/processmaker/classTaskTest.php new file mode 100644 index 000000000..81b312b92 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classTaskTest.php @@ -0,0 +1,132 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadSystem ( 'testTools'); + //G::LoadClass ( 'task'); + require_once(PATH_CORE.'/classes/model/Task.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Task ($dbc); + $t = new lime_test( 11, new lime_output_color() ); + + $t->diag('class Task' ); + $t->isa_ok( $obj , 'Task', 'class Task created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class TaskTest extends UnitTest + { + function CreateTask($data,$fields) + { + try + { + $task=new Task(); + $result=$task->create($fields); + $this->domain->addDomainValue('CREATED',$task->getTasUid()); + return $result; + } + catch(Exception $e) + { + $result=array('Exception!! '=> $e->getMessage()); + if(isset($e->aValidationFailures)) + $result['ValidationFailures'] = $e->aValidationFailures; + return $result; + } + } + function UpdateTask($data,$fields) + { + try + { + $task=new Task(); + $result=$task->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadTask($data,$fields) + { + try + { + $task=new Task(); + $result=$task->load($fields['TAS_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveTask($data,$fields) + { + try + { + $task=new Task(); + $result=$task->remove($fields['TAS_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new TaskTest('task.yml',$t); + $test->domain->addDomain('CREATED'); + $test->load('CreateTestTasks'); + $test->runAll(); + $test->load('TaskUnitTest'); + $test->runAll(); diff --git a/workflow/engine/test/unit/processmaker/classTaskUserTest.php b/workflow/engine/test/unit/processmaker/classTaskUserTest.php new file mode 100644 index 000000000..70be4f0c7 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classTaskUserTest.php @@ -0,0 +1,98 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ +$unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; +require_once( $unitFilename ); +require_once(PATH_THIRDPARTY . '/lime/lime.php'); +require_once(PATH_THIRDPARTY.'lime/yaml.class.php'); + +require_once(PATH_CORE . 'config/databases.php'); +require_once('propel/Propel.php'); +Propel::init(PATH_CORE . 'config/databases.php'); + +G::LoadThirdParty('smarty/libs', 'Smarty.class'); +G::LoadSystem('error'); +G::LoadSystem('xmlform'); +G::LoadSystem('xmlDocument'); +G::LoadSystem('form'); +G::LoadSystem('dbtable'); +G::LoadSystem('testTools'); +require_once(PATH_CORE . 'classes/model/TaskUser.php'); + +$obj = new TaskUser(); +$t = new lime_test(3, new lime_output_color()); + +$t->diag('Class TaskUser'); + +//class TaskUser +$t->isa_ok($obj, 'TaskUser', 'Class TaskUser created!'); + +//method create +$t->can_ok($obj, 'create', 'create() is callable!'); + +//method remove +$t->can_ok($obj, 'remove', 'remove() is callable!'); + +/***** TEST CLASS TASKUSER *****/ +///////// INITIAL VALUES ///////// +define('SYS_LANG', 'en'); +//Test class +class TaskUserTest extends unitTest +{ + function createTest($aTestData, $aFields) + { + $oTaskUser = new TaskUser(); + try { + return $oTaskUser->create($aFields); + } + catch (Exception $oError) { + return $oError; + } + } + function removeTest($aTestData, $aFields) + { + $oTaskUser = new TaskUser(); + try { + return $oTaskUser->remove($aFields['TAS_UID'], $aFields['USR_UID'], $aFields['TU_TYPE'], $aFields['TU_RELATION']); + } + catch (Exception $oError) { + return $oError; + } + } +} +//Initialize the test class (ymlTestDefinitionFile, limeTestObject, testDomain) +$oTaskUserTest = new TaskUserTest('taskUser.yml', $t, new ymlDomain()); +$oTaskUserTest->load('create1'); +$vAux = $oTaskUserTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oTaskUserTest->load('create2'); +$vAux = $oTaskUserTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oTaskUserTest->load('remove1'); +$vAux = $oTaskUserTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +$oTaskUserTest->load('remove2'); +$vAux = $oTaskUserTest->runSingle(); +//var_dump($vAux);echo "\n\n"; +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classToolBarTest.php b/workflow/engine/test/unit/processmaker/classToolBarTest.php new file mode 100644 index 000000000..7b4c8496d --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classToolBarTest.php @@ -0,0 +1,60 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + G::LoadClass ( 'toolBar'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + $file = 'login/login'; + $arg1 = ''; + $arg2 = ''; + $arg3 = ''; + + $obj = new ToolBar ( $file ); + $t = new lime_test( 1, new lime_output_color() ); + + $t->diag('class ToolBar' ); + $t->isa_ok( $obj , 'ToolBar', 'class ToolBar created'); + + $t->diag(' XmlForm_Field_toolbar' ); + + //$t->fail( 'review all pendings methods and CLASSES in this class'); + +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classTranslationTest.php b/workflow/engine/test/unit/processmaker/classTranslationTest.php new file mode 100644 index 000000000..1067c5619 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classTranslationTest.php @@ -0,0 +1,55 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + require_once ( 'classes/model/Translation.php'); + + require_once ( PATH_CORE . "config/databases.php"); + $obj = new Translation (); + $obj = new Translation (); + $method = array ( ); + $testItems = 0; + $class_methods = get_class_methods($obj); + foreach ($class_methods as $method_name) { + $methods[ $testItems ] = $method_name; + $testItems++; + } + + $t = new lime_test( 2, new lime_output_color()); + + $t->diag('class filterForm' ); + $t->is( $testItems , 38, "class Translation " . $testItems . " methods." ); + $t->todo( 'review all pendings in this class'); + diff --git a/workflow/engine/test/unit/processmaker/classTriggerTest.php b/workflow/engine/test/unit/processmaker/classTriggerTest.php new file mode 100644 index 000000000..23aabbf4e --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classTriggerTest.php @@ -0,0 +1,129 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + //G::LoadClass ( 'user'); + G::LoadSystem ( 'testTools'); + require_once(PATH_CORE.'/classes/model/Triggers.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Triggers ($dbc); + $t = new lime_test( 25, new lime_output_color() ); + + $t->diag('class Trigger' ); + $t->isa_ok( $obj , 'Triggers', 'class Trigger created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class TriggerTest extends UnitTest + { + function CreateTrigger($data,$fields) + { + try + { + $Trigger=new Triggers(); + $result=$Trigger->create($fields); + $this->domain->addDomainValue('CREATED',$Trigger->getTriUid()); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function UpdateTrigger($data,$fields) + { + try + { + $Trigger=new Triggers(); + $result=$Trigger->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadTrigger($data,$fields) + { + try + { + $Trigger=new Triggers(); + $result=$Trigger->load($fields['TRI_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveTrigger($data,$fields) + { + try + { + $Trigger=new Triggers(); + $result=$Trigger->remove($fields['TRI_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new TriggerTest('trigger.yml',$t); + $test->domain->addDomain('CREATED'); + $test->load('CreateTestTriggers'); + $test->runAll(); + $test->load('TriggerUnitTest'); + $test->runAll(); +?> \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classUserTest.php b/workflow/engine/test/unit/processmaker/classUserTest.php new file mode 100644 index 000000000..b5b8e13af --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classUserTest.php @@ -0,0 +1,132 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + $unitFilename = $_SERVER['PWD'] . '/test/bootstrap/unit.php' ; + require_once( $unitFilename ); + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + require_once ( PATH_CORE . "config/databases.php"); + require_once ( "propel/Propel.php" ); + Propel::init( PATH_CORE . "config/databases.php"); + + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem ( 'error'); + G::LoadSystem ( 'xmlform'); + G::LoadSystem ( 'xmlDocument'); + G::LoadSystem ( 'form'); + G::LoadSystem ( 'dbconnection'); + G::LoadSystem ( 'dbsession'); + G::LoadSystem ( 'dbrecordset'); + G::LoadSystem ( 'dbtable'); + //G::LoadClass ( 'user'); + G::LoadSystem ( 'testTools'); + require_once(PATH_CORE.'/classes/model/Users.php'); + + require_once ( PATH_CORE . "config/databases.php"); + + $dbc = new DBConnection(); + $ses = new DBSession( $dbc); + + $obj = new Users ($dbc); + $t = new lime_test( 12, new lime_output_color() ); + + $t->diag('class User' ); + $t->isa_ok( $obj , 'Users', 'class User created'); + + //method load + $t->can_ok( $obj, 'load', 'load() is callable' ); + //method save + $t->can_ok( $obj, 'update', 'update() is callable' ); + //method delete + $t->can_ok( $obj, 'delete', 'delete() is callable' ); + //method create + $t->can_ok( $obj, 'create', 'create() is callable' ); + + + class UserTest extends UnitTest + { + function CreateUser($data,$fields) + { + try + { + $User=new Users(); + $result=$User->create($fields); + $this->domain->addDomainValue('CREATED',$User->getUsrUid()); + return $result; + } + catch(Exception $e) + { + $result=array('Exception!! '=> $e->getMessage()); + if(isset($e->aValidationFailures)) + $result['ValidationFailures'] = $e->aValidationFailures; + return $result; + } + } + function UpdateUser($data,$fields) + { + try + { + $User=new Users(); + $result=$User->update($fields); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function LoadUser($data,$fields) + { + try + { + $User=new Users(); + $result=$User->load($fields['USR_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + function RemoveUser($data,$fields) + { + try + { + $User=new Users(); + $result=$User->remove($fields['USR_UID']); + return $result; + } + catch(Exception $e) + { + return array('Exception!! '=> $e->getMessage()); + } + } + } + $test=new UserTest('user.yml',$t); + $test->domain->addDomain('CREATED'); + $test->load('CreateTestUsers'); + $test->runAll(); + $test->load('UserUnitTest'); + $test->runAll(); diff --git a/workflow/engine/test/unit/processmaker/classWsBaseTest.php b/workflow/engine/test/unit/processmaker/classWsBaseTest.php new file mode 100644 index 000000000..2769d1d64 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classWsBaseTest.php @@ -0,0 +1,233 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , "wsBase", "class $className created"); + + //$t->is( count($methods) , 26, "class $className have " . 26 . ' methods.' ); + + $t->is( count($methods) , 28, "class $className have " . 28 . ' methods.' ); + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( ); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using "); + + + //checking method 'login' + $t->can_ok( $obj, 'login', 'login() is callable' ); + + //$result = $obj->login ( $userid, $password); + //$t->isa_ok( $result, 'NULL', 'call to method login '); + $t->todo( "call to method login using $userid, $password "); + + + //checking method 'processList' + $t->can_ok( $obj, 'processList', 'processList() is callable' ); + + //$result = $obj->processList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method processList '); + $t->todo( "call to method processList using "); + + + //checking method 'roleList' + $t->can_ok( $obj, 'roleList', 'roleList() is callable' ); + + //$result = $obj->roleList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method roleList '); + $t->todo( "call to method roleList using "); + + + //checking method 'groupList' + $t->can_ok( $obj, 'groupList', 'groupList() is callable' ); + + //$result = $obj->groupList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method groupList '); + $t->todo( "call to method groupList using "); + + + //checking method 'caseList' + $t->can_ok( $obj, 'caseList', 'caseList() is callable' ); + + //$result = $obj->caseList ( $userId); + //$t->isa_ok( $result, 'NULL', 'call to method caseList '); + $t->todo( "call to method caseList using $userId "); + + + //checking method 'userList' + $t->can_ok( $obj, 'userList', 'userList() is callable' ); + + //$result = $obj->userList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method userList '); + $t->todo( "call to method userList using "); + + + //checking method 'triggerList' + $t->can_ok( $obj, 'triggerList', 'triggerList() is callable' ); + + //$result = $obj->triggerList ( ); + //$t->isa_ok( $result, 'NULL', 'call to method triggerList '); + $t->todo( "call to method triggerList using "); + + + //checking method 'taskList' + $t->can_ok( $obj, 'taskList', 'taskList() is callable' ); + + //$result = $obj->taskList ( $userId); + //$t->isa_ok( $result, 'NULL', 'call to method taskList '); + $t->todo( "call to method taskList using $userId "); + + + //checking method 'sendMessage' + $t->can_ok( $obj, 'sendMessage', 'sendMessage() is callable' ); + + //$result = $obj->sendMessage ( $caseId, $sFrom, $sTo, $sCc, $sBcc, $sSubject, $sTemplate, $appFields); + //$t->isa_ok( $result, 'NULL', 'call to method sendMessage '); + $t->todo( "call to method sendMessage using $caseId, $sFrom, $sTo, $sCc, $sBcc, $sSubject, $sTemplate, $appFields "); + + + //checking method 'getCaseInfo' + $t->can_ok( $obj, 'getCaseInfo', 'getCaseInfo() is callable' ); + + //$result = $obj->getCaseInfo ( $caseId, $iDelIndex); + //$t->isa_ok( $result, 'NULL', 'call to method getCaseInfo '); + $t->todo( "call to method getCaseInfo using $caseId, $iDelIndex "); + + + //checking method 'createUser' + $t->can_ok( $obj, 'createUser', 'createUser() is callable' ); + + //$result = $obj->createUser ( $userId, $firstname, $lastname, $email, $role, $password); + //$t->isa_ok( $result, 'NULL', 'call to method createUser '); + $t->todo( "call to method createUser using $userId, $firstname, $lastname, $email, $role, $password "); + + + //checking method 'assignUserToGroup' + $t->can_ok( $obj, 'assignUserToGroup', 'assignUserToGroup() is callable' ); + + //$result = $obj->assignUserToGroup ( $userId, $groupId); + //$t->isa_ok( $result, 'NULL', 'call to method assignUserToGroup '); + $t->todo( "call to method assignUserToGroup using $userId, $groupId "); + + + //checking method 'sendVariables' + $t->can_ok( $obj, 'sendVariables', 'sendVariables() is callable' ); + + //$result = $obj->sendVariables ( $caseId, $variables); + //$t->isa_ok( $result, 'NULL', 'call to method sendVariables '); + $t->todo( "call to method sendVariables using $caseId, $variables "); + + + //checking method 'getVariables' + $t->can_ok( $obj, 'getVariables', 'getVariables() is callable' ); + + //$result = $obj->getVariables ( $caseId, $variables); + //$t->isa_ok( $result, 'NULL', 'call to method getVariables '); + $t->todo( "call to method getVariables using $caseId, $variables "); + + + //checking method 'newCase' + $t->can_ok( $obj, 'newCase', 'newCase() is callable' ); + + //$result = $obj->newCase ( $processId, $userId, $taskId, $variables); + //$t->isa_ok( $result, 'NULL', 'call to method newCase '); + $t->todo( "call to method newCase using $processId, $userId, $taskId, $variables "); + + + //checking method 'newCaseImpersonate' + $t->can_ok( $obj, 'newCaseImpersonate', 'newCaseImpersonate() is callable' ); + + //$result = $obj->newCaseImpersonate ( $processId, $userId, $variables); + //$t->isa_ok( $result, 'NULL', 'call to method newCaseImpersonate '); + $t->todo( "call to method newCaseImpersonate using $processId, $userId, $variables "); + + + //checking method 'derivateCase' + $t->can_ok( $obj, 'derivateCase', 'derivateCase() is callable' ); + + //$result = $obj->derivateCase ( $userId, $caseId, $delIndex, $bExecuteTriggersBeforeAssignment); + //$t->isa_ok( $result, 'NULL', 'call to method derivateCase '); + $t->todo( "call to method derivateCase using $userId, $caseId, $delIndex, $bExecuteTriggersBeforeAssignment "); + + + //checking method 'executeTrigger' + $t->can_ok( $obj, 'executeTrigger', 'executeTrigger() is callable' ); + + //$result = $obj->executeTrigger ( $userId, $caseId, $triggerIndex, $delIndex); + //$t->isa_ok( $result, 'NULL', 'call to method executeTrigger '); + $t->todo( "call to method executeTrigger using $userId, $caseId, $triggerIndex, $delIndex "); + + + //checking method 'taskCase' + $t->can_ok( $obj, 'taskCase', 'taskCase() is callable' ); + + //$result = $obj->taskCase ( $caseId); + //$t->isa_ok( $result, 'NULL', 'call to method taskCase '); + $t->todo( "call to method taskCase using $caseId "); + + + //checking method 'processListVerified' + $t->can_ok( $obj, 'processListVerified', 'processListVerified() is callable' ); + + //$result = $obj->processListVerified ( $userId); + //$t->isa_ok( $result, 'NULL', 'call to method processListVerified '); + $t->todo( "call to method processListVerified using $userId "); + + + //checking method 'reassignCase' + $t->can_ok( $obj, 'reassignCase', 'reassignCase() is callable' ); + + //$result = $obj->reassignCase ( $sessionId, $caseId, $delIndex, $userIdSource, $userIdTarget); + //$t->isa_ok( $result, 'NULL', 'call to method reassignCase '); + $t->todo( "call to method reassignCase using $sessionId, $caseId, $delIndex, $userIdSource, $userIdTarget "); + + + //checking method 'systemInformation' + $t->can_ok( $obj, 'systemInformation', 'systemInformation() is callable' ); + + //$result = $obj->systemInformation ( ); + //$t->isa_ok( $result, 'NULL', 'call to method systemInformation '); + $t->todo( "call to method systemInformation using "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classWsResponseTest.php b/workflow/engine/test/unit/processmaker/classWsResponseTest.php new file mode 100644 index 000000000..facb2b1ad --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classWsResponseTest.php @@ -0,0 +1,73 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + + $t->diag('class $className' ); + $t->isa_ok( $obj , $className, 'class $className created'); + + $t->is( count($methods) , 3, "class $className have " . 3 . ' methods.' ); + + //checking method '__construct' + $t->can_ok( $obj, '__construct', '__construct() is callable' ); + + //$result = $obj->__construct ( $status, $message); + //$t->isa_ok( $result, 'NULL', 'call to method __construct '); + $t->todo( "call to method __construct using $status, $message "); + + + //checking method 'getPayloadString' + $t->can_ok( $obj, 'getPayloadString', 'getPayloadString() is callable' ); + + //$result = $obj->getPayloadString ( $operation); + //$t->isa_ok( $result, 'NULL', 'call to method getPayloadString '); + $t->todo( "call to method getPayloadString using $operation "); + + + //checking method 'getPayloadArray' + $t->can_ok( $obj, 'getPayloadArray', 'getPayloadArray() is callable' ); + + //$result = $obj->getPayloadArray ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getPayloadArray '); + $t->todo( "call to method getPayloadArray using "); + + + + $t->todo ( 'review all pendings methods in this class'); \ No newline at end of file diff --git a/workflow/engine/test/unit/processmaker/classXmlDbTest.php b/workflow/engine/test/unit/processmaker/classXmlDbTest.php new file mode 100644 index 000000000..9e4a5a564 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classXmlDbTest.php @@ -0,0 +1,64 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + $t->isa_ok( $obj , "XMLDB", "class $className created"); + + $t->is( count($methods) , 2, "class $className have " . 2 . ' methods.' ); + + //checking method 'connect' + $t->can_ok( $obj, 'connect', 'connect() is callable' ); + + //$result = $obj->connect ( $dsn, $options); + //$t->isa_ok( $result, 'NULL', 'call to method connect '); + $t->todo( "call to method connect using $dsn, $options "); + + + //checking method 'isError' + $t->can_ok( $obj, 'isError', 'isError() is callable' ); + + //$result = $obj->isError ( $result); + //$t->isa_ok( $result, 'NULL', 'call to method isError '); + $t->todo( "call to method isError using $result "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classXmlForm_Field_ImageTest.php b/workflow/engine/test/unit/processmaker/classXmlForm_Field_ImageTest.php new file mode 100644 index 000000000..ca6385a69 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classXmlForm_Field_ImageTest.php @@ -0,0 +1,209 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + + $t->is( count($methods) , 20, "class $className have " . 20 . ' methods.' ); + // Methods + $aMethods = array_keys ( $methods ); + //checking method 'render' + $t->is ( $aMethods[0], 'render', 'render() is callable' ); + + //$result = $obj->render ( $value, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method render '); + $t->todo( "call to method render using $value, $owner "); + + + //checking method 'XmlForm_Field' + $t->is ( $aMethods[1], 'XmlForm_Field', 'XmlForm_Field() is callable' ); + + //$result = $obj->XmlForm_Field ( $xmlNode, $lang, $home, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method XmlForm_Field '); + $t->todo( "call to method XmlForm_Field using $xmlNode, $lang, $home, $owner "); + + + //checking method 'validateValue' + $t->is ( $aMethods[2], 'validateValue', 'validateValue() is callable' ); + + //$result = $obj->validateValue ( $value); + //$t->isa_ok( $result, 'NULL', 'call to method validateValue '); + $t->todo( "call to method validateValue using $value "); + + + //checking method 'executeXmlDB' + $t->is ( $aMethods[3], 'executeXmlDB', 'executeXmlDB() is callable' ); + + //$result = $obj->executeXmlDB ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executeXmlDB '); + $t->todo( "call to method executeXmlDB using $owner, $row "); + + + //checking method 'executePropel' + $t->is ( $aMethods[4], 'executePropel', 'executePropel() is callable' ); + + //$result = $obj->executePropel ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executePropel '); + $t->todo( "call to method executePropel using $owner, $row "); + + + //checking method 'executeSQL' + $t->is ( $aMethods[5], 'executeSQL', 'executeSQL() is callable' ); + + //$result = $obj->executeSQL ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executeSQL '); + $t->todo( "call to method executeSQL using $owner, $row "); + + + //checking method 'htmlentities' + $t->is ( $aMethods[6], 'htmlentities', 'htmlentities() is callable' ); + + //$result = $obj->htmlentities ( $value, $flags, $encoding); + //$t->isa_ok( $result, 'NULL', 'call to method htmlentities '); + $t->todo( "call to method htmlentities using $value, $flags, $encoding "); + + + //checking method 'renderGrid' + $t->is ( $aMethods[7], 'renderGrid', 'renderGrid() is callable' ); + + //$result = $obj->renderGrid ( $values, $owner, $onlyValue, $therow); + //$t->isa_ok( $result, 'NULL', 'call to method renderGrid '); + $t->todo( "call to method renderGrid using $values, $owner, $onlyValue, $therow "); + + + //checking method 'renderTable' + $t->is ( $aMethods[8], 'renderTable', 'renderTable() is callable' ); + + //$result = $obj->renderTable ( $values, $owner, $onlyValue); + //$t->isa_ok( $result, 'NULL', 'call to method renderTable '); + $t->todo( "call to method renderTable using $values, $owner, $onlyValue "); + + + //checking method 'dependentOf' + $t->is ( $aMethods[9], 'dependentOf', 'dependentOf() is callable' ); + + //$result = $obj->dependentOf ( ); + //$t->isa_ok( $result, 'NULL', 'call to method dependentOf '); + $t->todo( "call to method dependentOf using "); + + + //checking method 'mask' + $t->is ( $aMethods[10], 'mask', 'mask() is callable' ); + + //$result = $obj->mask ( $format, $value); + //$t->isa_ok( $result, 'NULL', 'call to method mask '); + $t->todo( "call to method mask using $format, $value "); + + + //checking method 'getAttributes' + $t->is ( $aMethods[11], 'getAttributes', 'getAttributes() is callable' ); + + //$result = $obj->getAttributes ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getAttributes '); + $t->todo( "call to method getAttributes using "); + + + //checking method 'getEvents' + $t->is ( $aMethods[12], 'getEvents', 'getEvents() is callable' ); + + //$result = $obj->getEvents ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getEvents '); + $t->todo( "call to method getEvents using "); + + + //checking method 'attachEvents' + $t->is ( $aMethods[13], 'attachEvents', 'attachEvents() is callable' ); + + //$result = $obj->attachEvents ( $elementRef); + //$t->isa_ok( $result, 'NULL', 'call to method attachEvents '); + $t->todo( "call to method attachEvents using $elementRef "); + + + //checking method 'createXmlNode' + $t->is ( $aMethods[14], 'createXmlNode', 'createXmlNode() is callable' ); + + //$result = $obj->createXmlNode ( $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method createXmlNode '); + $t->todo( "call to method createXmlNode using $includeDefaultValues "); + + + //checking method 'updateXmlNode' + $t->is ( $aMethods[15], 'updateXmlNode', 'updateXmlNode() is callable' ); + + //$result = $obj->updateXmlNode ( $node, $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method updateXmlNode '); + $t->todo( "call to method updateXmlNode using $node, $includeDefaultValues "); + + + //checking method 'getXmlAttributes' + $t->is ( $aMethods[16], 'getXmlAttributes', 'getXmlAttributes() is callable' ); + + //$result = $obj->getXmlAttributes ( $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method getXmlAttributes '); + $t->todo( "call to method getXmlAttributes using $includeDefaultValues "); + + + //checking method 'maskValue' + $t->is ( $aMethods[17], 'maskValue', 'maskValue() is callable' ); + + //$result = $obj->maskValue ( $value, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method maskValue '); + $t->todo( "call to method maskValue using $value, $owner "); + + + //checking method 'cloneObject' + $t->is ( $aMethods[18], 'cloneObject', 'cloneObject() is callable' ); + + //$result = $obj->cloneObject ( ); + //$t->isa_ok( $result, 'NULL', 'call to method cloneObject '); + $t->todo( "call to method cloneObject using "); + + + //checking method 'getPMTableValue' + $t->is ( $aMethods[19], 'getPMTableValue', 'getPMTableValue() is callable' ); + + //$result = $obj->getPMTableValue ( $oOwner); + //$t->isa_ok( $result, 'NULL', 'call to method getPMTableValue '); + $t->todo( "call to method getPMTableValue using $oOwner "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/processmaker/classXmlForm_Field_TextPMTest.php b/workflow/engine/test/unit/processmaker/classXmlForm_Field_TextPMTest.php new file mode 100644 index 000000000..2784caaa6 --- /dev/null +++ b/workflow/engine/test/unit/processmaker/classXmlForm_Field_TextPMTest.php @@ -0,0 +1,210 @@ +getMethods() as $reflectmethod ) { + $params = ''; + foreach ( $reflectmethod->getParameters() as $key => $row ) { + if ( $params != '' ) $params .= ', '; + $params .= '$' . $row->name; + } + + $testItems++; + $methods[ $reflectmethod->getName() ] = $params; + } + //To change the case only the first letter of each word, TIA + $className = ucwords($className); + $t->diag("class $className" ); + + //$t->isa_ok( $obj , $className, "class $className created"); + $t->is( count($methods) , 20, "class $className have " . 20 . ' methods.' ); + + //Methods + $aMethods = array_keys ( $methods ); + + //checking method 'render' + $t->is ( $aMethods[0], 'render', 'render() is callable' ); + + //$result = $obj->render ( $value, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method render '); + $t->todo( "call to method render using $value, $owner "); + + + //checking method 'renderGrid' + $t->is ( $aMethods[1], 'renderGrid', 'renderGrid() is callable' ); + + //$result = $obj->renderGrid ( $values, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method renderGrid '); + $t->todo( "call to method renderGrid using $values, $owner "); + + + //checking method 'attachEvents' + $t->is ( $aMethods[2], 'attachEvents', 'attachEvents() is callable' ); + + //$result = $obj->attachEvents ( $element); + //$t->isa_ok( $result, 'NULL', 'call to method attachEvents '); + $t->todo( "call to method attachEvents using $element "); + + + //checking method 'XmlForm_Field' + $t->is ( $aMethods[3], 'XmlForm_Field', 'XmlForm_Field() is callable' ); + + //$result = $obj->XmlForm_Field ( $xmlNode, $lang, $home, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method XmlForm_Field '); + $t->todo( "call to method XmlForm_Field using $xmlNode, $lang, $home, $owner "); + + + //checking method 'validateValue' + $t->is ( $aMethods[4], 'validateValue', 'validateValue() is callable' ); + + //$result = $obj->validateValue ( $value); + //$t->isa_ok( $result, 'NULL', 'call to method validateValue '); + $t->todo( "call to method validateValue using $value "); + + + //checking method 'executeXmlDB' + $t->is ( $aMethods[5], 'executeXmlDB', 'executeXmlDB() is callable' ); + + //$result = $obj->executeXmlDB ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executeXmlDB '); + $t->todo( "call to method executeXmlDB using $owner, $row "); + + + //checking method 'executePropel' + $t->is ( $aMethods[6], 'executePropel', 'executePropel() is callable' ); + + //$result = $obj->executePropel ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executePropel '); + $t->todo( "call to method executePropel using $owner, $row "); + + + //checking method 'executeSQL' + $t->is ( $aMethods[7], 'executeSQL', 'executeSQL() is callable' ); + + //$result = $obj->executeSQL ( $owner, $row); + //$t->isa_ok( $result, 'NULL', 'call to method executeSQL '); + $t->todo( "call to method executeSQL using $owner, $row "); + + + //checking method 'htmlentities' + $t->is ( $aMethods[8], 'htmlentities', 'htmlentities() is callable' ); + + //$result = $obj->htmlentities ( $value, $flags, $encoding); + //$t->isa_ok( $result, 'NULL', 'call to method htmlentities '); + $t->todo( "call to method htmlentities using $value, $flags, $encoding "); + + + //checking method 'renderTable' + $t->is ( $aMethods[9], 'renderTable', 'renderTable() is callable' ); + + //$result = $obj->renderTable ( $values, $owner, $onlyValue); + //$t->isa_ok( $result, 'NULL', 'call to method renderTable '); + $t->todo( "call to method renderTable using $values, $owner, $onlyValue "); + + + //checking method 'dependentOf' + $t->is ( $aMethods[10], 'dependentOf', 'dependentOf() is callable' ); + + //$result = $obj->dependentOf ( ); + //$t->isa_ok( $result, 'NULL', 'call to method dependentOf '); + $t->todo( "call to method dependentOf using "); + + + //checking method 'mask' + $t->is ( $aMethods[11], 'mask', 'mask() is callable' ); + + //$result = $obj->mask ( $format, $value); + //$t->isa_ok( $result, 'NULL', 'call to method mask '); + $t->todo( "call to method mask using $format, $value "); + + + //checking method 'getAttributes' + $t->is ( $aMethods[12], 'getAttributes', 'getAttributes() is callable' ); + + //$result = $obj->getAttributes ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getAttributes '); + $t->todo( "call to method getAttributes using "); + + + //checking method 'getEvents' + $t->is ( $aMethods[13], 'getEvents', 'getEvents() is callable' ); + + //$result = $obj->getEvents ( ); + //$t->isa_ok( $result, 'NULL', 'call to method getEvents '); + $t->todo( "call to method getEvents using "); + + + //checking method 'createXmlNode' + $t->is ( $aMethods[14], 'createXmlNode', 'createXmlNode() is callable' ); + + //$result = $obj->createXmlNode ( $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method createXmlNode '); + $t->todo( "call to method createXmlNode using $includeDefaultValues "); + + + //checking method 'updateXmlNode' + $t->is ( $aMethods[15], 'updateXmlNode', 'updateXmlNode() is callable' ); + + //$result = $obj->updateXmlNode ( $node, $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method updateXmlNode '); + $t->todo( "call to method updateXmlNode using $node, $includeDefaultValues "); + + + //checking method 'getXmlAttributes' + $t->is ( $aMethods[16], 'getXmlAttributes', 'getXmlAttributes() is callable' ); + + //$result = $obj->getXmlAttributes ( $includeDefaultValues); + //$t->isa_ok( $result, 'NULL', 'call to method getXmlAttributes '); + $t->todo( "call to method getXmlAttributes using $includeDefaultValues "); + + + //checking method 'maskValue' + $t->is ( $aMethods[17], 'maskValue', 'maskValue() is callable' ); + + //$result = $obj->maskValue ( $value, $owner); + //$t->isa_ok( $result, 'NULL', 'call to method maskValue '); + $t->todo( "call to method maskValue using $value, $owner "); + + + //checking method 'cloneObject' + $t->is ( $aMethods[18], 'cloneObject', 'cloneObject() is callable' ); + + //$result = $obj->cloneObject ( ); + //$t->isa_ok( $result, 'NULL', 'call to method cloneObject '); + $t->todo( "call to method cloneObject using "); + + + //checking method 'getPMTableValue' + $t->is ( $aMethods[19], 'getPMTableValue', 'getPMTableValue() is callable' ); + + //$result = $obj->getPMTableValue ( $oOwner); + //$t->isa_ok( $result, 'NULL', 'call to method getPMTableValue '); + $t->todo( "call to method getPMTableValue using $oOwner "); + + + + $t->todo ( 'review all pendings methods in this class'); diff --git a/workflow/engine/test/unit/ws/EvaluationDerivationTest.php b/workflow/engine/test/unit/ws/EvaluationDerivationTest.php new file mode 100644 index 000000000..c9195bdb8 --- /dev/null +++ b/workflow/engine/test/unit/ws/EvaluationDerivationTest.php @@ -0,0 +1,182 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + $t = new lime_test( 34, new lime_output_color()); + $t->diag('Evaluation Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_EVALUATION', '62540106148bd5278cafec4025395237'); + define ( 'START_EVA_CYCLICAL_TASK', '61213500548bd52a7587928010684501'); + define ( 'START_EVA_MANUAL_TASK', '11768216248bd52ae02ced4099046337'); + define ( 'START_EVA_VALUE_TASK', '18044058448bd52f9b9a5e7001261804'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Evaluation Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_EVALUATION ); + $t->diag('Starting Task: ' . START_EVA_CYCLICAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_EVALUATION, START_EVA_CYCLICAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $amount = rand( 1, 200 ); + $variables = array ( 'amount' => $amount ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "1 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $t->todo( 'Check if the above user is changing according the Group in cyclical order'); + $t->diag( "Check if the case was derivated according the amount = \033[2;31;32m" . $amount . "\033[0m "); + + $result = ws_derivateCase ($caseId, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + if ( $result->status_code == 17 ) { + $t->is( $result->status_code, 17, 'ws_derivateCase status_code = 17'); + $t->diag($result->message ); + $msg = trim ( sprintf ( "Check the case: \033[0;31;32m%s\033[1;32m is in the user To Do List", $caseNumber)); + $t->todo( $msg); + } + else { + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $msg = trim ( sprintf ( "Check that case: \033[0;31;32m%s\033[1;32m is in your Completed List", $caseNumber)); + $t->todo( $msg); + } + } + + $t->diag('---------------------------------' ); + $t->diag('Manual Evaluation Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_EVALUATION ); + $t->diag('Starting Task: ' . START_EVA_MANUAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_EVALUATION, START_EVA_MANUAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code , 0, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $amount = rand( 1, 200 ); + $variables = array ( 'amount' => $amount ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "1 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code , 15, 'ws_derivateCase status_code = 15'); + $t->is( $result->message , 'The task is defined for Manual assignment', 'Task defined for Manual Assignment'); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + //$t->todo( 'Check if the above user is changing according the Group in cyclical order'); + } + + $t->diag('-----------------------------------' ); + $t->diag('Value Evaluation Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_EVALUATION ); + $t->diag('Starting Task: ' . START_EVA_VALUE_TASK ); + + $result = ws_newCase ( PROCESS_UID_EVALUATION, START_EVA_VALUE_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 100 , true, 'ws_derivateCase status_code = 100'); + $msg1 = "Task doesn't have a valid user in variable SYS_NEXT_USER_TO_BE_ASSIGNED or this variable doesn't exist."; + $t->is( $result->message , $msg1, $msg1 ); + + $amount = rand( 1, 200 ); + $variables = array ( 'SYS_NEXT_USER_TO_BE_ASSIGNED' => '00000000000000000000000000000001', 'amount' => $amount ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "2 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 0 , true, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + if ( $amount > 100 ) + $msg1 = "Task 2 - Value Assign(admin)"; + else + $msg1 = "Task 3 - Value Assign(admin)"; + $t->is( trim( $result->message) , $msg1, $msg1 ); + + } + */ diff --git a/workflow/engine/test/unit/ws/OtherMethodsTest.php b/workflow/engine/test/unit/ws/OtherMethodsTest.php new file mode 100644 index 000000000..a0befb1c9 --- /dev/null +++ b/workflow/engine/test/unit/ws/OtherMethodsTest.php @@ -0,0 +1,83 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + + $t = new lime_test( 12, new lime_output_color()); + $t->diag('Sequential Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_SEQUENTIAL', '34537126948bc50f6dc0ad8058165755'); + define ( 'START_SEQ_CYCLICAL_TASK', '31132134648bc50fb7afa90020304752'); + define ( 'START_SEQ_MANUAL_TASK', '58845888048bc514a9ca3f6076028720'); + define ( 'START_REQ_VALUE_TASK', '42952443148bc515a7aae98069470300'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + $t->is( function_exists('ws_open'),true, 'ws_open()'); + $t->is( function_exists('ws_newCase'),true, 'ws_newCase()'); + $t->is( function_exists('ws_getCaseInfo'),true, 'ws_getCaseInfo()'); + $t->is( function_exists('ws_derivateCase'),true, 'ws_derivateCase()'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $t->diag('-----------------------------------' ); + $t->diag('Other Methods Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SEQUENTIAL ); + $t->diag('Starting Task: ' . START_SEQ_CYCLICAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_SEQUENTIAL, START_SEQ_CYCLICAL_TASK, array('A'=>'aaa','B'=>'bbb','C'=>'ccc')); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $result = ws_getCaseInfo($result->caseId, 1); + $t->isa_ok( $result, 'stdClass', 'executed ws_getCaseInfo'); + $t->is( $result->caseStatus, 'DRAFT', 'status is DRAFT'); + } + +*/ \ No newline at end of file diff --git a/workflow/engine/test/unit/ws/ParallelDerivation2Test.php b/workflow/engine/test/unit/ws/ParallelDerivation2Test.php new file mode 100644 index 000000000..5b3de3035 --- /dev/null +++ b/workflow/engine/test/unit/ws/ParallelDerivation2Test.php @@ -0,0 +1,206 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + + /* + $t = new lime_test( 39, new lime_output_color()); + $t->diag('Parallel Derivation Test (Variation 1)' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define('PROCESS_UID', '4494018554909d147000020046858161'); + define('START_TASK', '8112792964909d1579896b1090244999'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $users = ws_userList (); + + $t->diag('-----------------------------------' ); + $t->diag('Parallel Derivation Test (Variation 1)' ); + $t->diag('Process Guid: ' . PROCESS_UID); + $t->diag('Starting Task: ' . START_TASK ); + + //First variant + $result = ws_newCase ( PROCESS_UID, START_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + + $variables = array('TASK4' => '0'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $variables = array('TASK6' => '1'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 3 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 4 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 5 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 6 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 7 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 8 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + } + + //Second variant + $result = ws_newCase ( PROCESS_UID, START_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + + $variables = array('TASK4' => '0'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $variables = array('TASK6' => '0'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 3 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 4 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 5 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 6 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 7 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 8 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + } + + //Third variant + $result = ws_newCase ( PROCESS_UID, START_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + + $variables = array('TASK4' => '1'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 4 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $variables = array('TASK4' => '0'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 5 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $variables = array('TASK6' => '1'); + $result = ws_sendVariables ($caseId, $variables ); + $result = ws_derivateCase ($caseId, 3 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 6 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 7 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 8 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 9 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + + $result = ws_derivateCase ($caseId, 10 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + } + + + */ \ No newline at end of file diff --git a/workflow/engine/test/unit/ws/ParallelDerivationTest.php b/workflow/engine/test/unit/ws/ParallelDerivationTest.php new file mode 100644 index 000000000..93dd2b265 --- /dev/null +++ b/workflow/engine/test/unit/ws/ParallelDerivationTest.php @@ -0,0 +1,172 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + + $t = new lime_test( 28, new lime_output_color()); + $t->diag('Parallel Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_PARALLEL', '44326695648bd573b100c74003649014'); + define ( 'START_PAR_CYCLICAL_TASK', '34868254848bd57718bb733027805100'); + define ( 'START_PAR_MANUAL_TASK', '74379238448bd5785506e34066123807'); + define ( 'START_PAR_VALUE_TASK', '28967746348bd57906ff834047943521'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $users = ws_userList (); + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Parallel Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_PARALLEL ); + $t->diag('Starting Task: ' . START_PAR_CYCLICAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_PARALLEL, START_PAR_CYCLICAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $t->todo( 'Check if the above user is changing according the Group in cyclical order'); + + $result = ws_derivateCase ($caseId, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + if ( $result->status_code == 17 ) { + $t->is( $result->status_code, 17, 'ws_derivateCase status_code = 17'); + $t->diag($result->message ); + $msg = trim ( sprintf ( "Check the case: \033[0;31;32m%s\033[1;32m is in the user To Do List", $caseNumber)); + $t->todo( $msg); + } + else { + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $msg = trim ( sprintf ( "Check that case: \033[0;31;32m%s\033[1;32m is in your Completed List", $caseNumber)); + $t->todo( $msg); + } + } + + $t->diag('---------------------------------' ); + $t->diag('Manual Parallel Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_PARALLEL ); + $t->diag('Starting Task: ' . START_PAR_MANUAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_PARALLEL, START_PAR_MANUAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code , 0, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code , 15, 'ws_derivateCase status_code = 15'); + $t->is( $result->message , 'The task is defined for Manual assignment', 'Task defined for Manual Assignment'); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + + $t->diag('-----------------------------------' ); + $t->diag('Value Parallel Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_PARALLEL ); + $t->diag('Starting Task: ' . START_PAR_VALUE_TASK ); + + $result = ws_newCase ( PROCESS_UID_PARALLEL, START_PAR_VALUE_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 100 , true, 'ws_derivateCase status_code = 100'); + $msg1 = "Task doesn't have a valid user in variable leftUser or this variable doesn't exist."; + $t->is( $result->message , $msg1, $msg1 ); + + $user1 = rand(0, count($users)-1 ); + $user2 = rand(0, count($users)-1 ); + $userGuid1 = $users[$user1]['guid']; + $userName1 = $users[$user1]['name']; + $userGuid2 = $users[$user2]['guid']; + $userName2 = $users[$user2]['name']; + $variables = array ( 'leftUser' => $userGuid1, 'rightUser' => $userGuid2 ); + print_r ($variables); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "2 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $msg1 = "Left Task - Value Assign($userName1),Right Task - Value Assign($userName2)"; + $t->is( trim( $result->message) , $msg1, $msg1 ); + + } + +*/ diff --git a/workflow/engine/test/unit/ws/ProcessWithSubprocess.php b/workflow/engine/test/unit/ws/ProcessWithSubprocess.php new file mode 100644 index 000000000..19d61237c --- /dev/null +++ b/workflow/engine/test/unit/ws/ProcessWithSubprocess.php @@ -0,0 +1,108 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + $t = new lime_test( 25, new lime_output_color()); + $t->diag('Selection Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_SELECTION', '324304616490b213ae38690016293793'); + define ( 'START_CYCLICAL_TASK', '917060771490b214838edb9072930947'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Selection Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_CYCLICAL_TASK ); + for($i=0;$i<1;$i++) + { + $result = ws_newCase ( PROCESS_UID_SELECTION, START_CYCLICAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 21, 'ws_derivateCase status_code = 21'); + $msg1 = "Cannot derivate a \"Manual\" derivation using webservices."; + $t->is( $result->message , $msg1, $msg1 ); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + + $t->diag('-----------------------------------' ); + $t->diag('Manual Selection Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_MANUAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_SELECTION, START_MANUAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 21, 'ws_derivateCase status_code = 21'); + $msg1 = "Cannot derivate a \"Manual\" derivation using webservices."; + $t->is( $result->message , $msg1, $msg1 ); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + +*/ \ No newline at end of file diff --git a/workflow/engine/test/unit/ws/SelectionDerivationTest.php b/workflow/engine/test/unit/ws/SelectionDerivationTest.php new file mode 100755 index 000000000..350f852ed --- /dev/null +++ b/workflow/engine/test/unit/ws/SelectionDerivationTest.php @@ -0,0 +1,152 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + $t = new lime_test( 25, new lime_output_color()); + $t->diag('Selection Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_SELECTION', '29881714148bd4b985432e5088934432'); + define ( 'START_CYCLICAL_TASK', '53023950248bd4c14e5f337057096979'); + define ( 'START_MANUAL_TASK', '7820297748bd4c185f5f64009218065'); + define ( 'START_VALUE_TASK', '87978806148bd4c1b01e1f2068245917'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Selection Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_CYCLICAL_TASK ); + + //for($i=0;$i<80;$i++) + //{ + $result = ws_newCase ( PROCESS_UID_SELECTION, START_CYCLICAL_TASK, array('A'=>'aaa','B'=>'bbb','C'=>'ccc')); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 21, 'ws_derivateCase status_code = 21'); + $msg1 = "Cannot derivate a \"Manual\" derivation using webservices."; + $t->is( $result->message , $msg1, $msg1 ); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + + $t->diag('-----------------------------------' ); + $t->diag('Manual Selection Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_MANUAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_SELECTION, START_MANUAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 21, 'ws_derivateCase status_code = 21'); + $msg1 = "Cannot derivate a \"Manual\" derivation using webservices."; + $t->is( $result->message , $msg1, $msg1 ); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + + $t->diag('-----------------------------------' ); + $t->diag('Manual Selection Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_VALUE_TASK ); + + $result = ws_newCase ( PROCESS_UID_SELECTION, START_VALUE_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 100 , true, 'ws_derivateCase status_code = 100'); + $msg1 = "Task doesn't have a valid user in variable SYS_NEXT_USER_TO_BE_ASSIGNED or this variable doesn't exist."; + $t->is( $result->message , $msg1, $msg1 ); + + $variables = array ( 'SYS_NEXT_USER_TO_BE_ASSIGNED' => '00000000000000000000000000000001' ); + //$variables = array ( 'SYS_NEXT_USER_TO_BE_ASSIGNED' => '20212274648f60fc8a575d7042794581' ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "1 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 21, 'ws_derivateCase status_code = 21'); + $msg1 = "Cannot derivate a \"Manual\" derivation using webservices."; + $t->is( $result->message , $msg1, $msg1 ); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + } + //} + +*/ diff --git a/workflow/engine/test/unit/ws/SequentialDerivationTest.php b/workflow/engine/test/unit/ws/SequentialDerivationTest.php new file mode 100644 index 000000000..ac6ca0126 --- /dev/null +++ b/workflow/engine/test/unit/ws/SequentialDerivationTest.php @@ -0,0 +1,156 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + $t = new lime_test( 32, new lime_output_color()); + $t->diag('Sequential Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_SEQUENTIAL', '34537126948bc50f6dc0ad8058165755'); + define ( 'START_SEQ_CYCLICAL_TASK', '31132134648bc50fb7afa90020304752'); + define ( 'START_SEQ_MANUAL_TASK', '58845888048bc514a9ca3f6076028720'); + define ( 'START_REQ_VALUE_TASK', '42952443148bc515a7aae98069470300'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + $t->is( function_exists('ws_open'),true, 'ws_open()'); + $t->is( function_exists('ws_newCase'),true, 'ws_newCase()'); + $t->is( function_exists('ws_sendEmailMessage'),true, 'ws_sendEmailMessage()'); + $t->is( function_exists('ws_getVariables'),true, 'ws_getVariables()'); + $t->is( function_exists('ws_sendVariables'),true, 'ws_sendVariables()'); + $t->is( function_exists('ws_executeTrigger'),true, 'ws_executeTrigger()'); + $t->is( function_exists('ws_derivateCase'),true, 'ws_derivateCase()'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Sequential Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SEQUENTIAL ); + $t->diag('Starting Task: ' . START_SEQ_CYCLICAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_SEQUENTIAL, START_SEQ_CYCLICAL_TASK, array('A'=>'aaa','B'=>'bbb','C'=>'ccc')); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0'); + $assign = $result->message; + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $t->todo( 'Check if the above user is changing according the Group in cyclical order'); + } + + + $t->diag('---------------------------------' ); + $t->diag('Manual Sequential Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SEQUENTIAL ); + $t->diag('Starting Task: ' . START_SEQ_MANUAL_TASK ); + + $result = ws_newCase ( PROCESS_UID_SEQUENTIAL, START_SEQ_MANUAL_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code , 0, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code , 15, 'ws_derivateCase status_code = 15'); + $t->is( $result->message , 'The task is defined for Manual assignment', 'Task defined for Manual Assignment'); + $assign = $result->message; + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + //$t->todo( 'Check if the above user is changing according the Group in cyclical order'); + } + + $t->diag('-----------------------------------' ); + $t->diag('Value Sequential Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SEQUENTIAL ); + $t->diag('Starting Task: ' . START_REQ_VALUE_TASK ); + + $result = ws_newCase ( PROCESS_UID_SEQUENTIAL, START_REQ_VALUE_TASK, array()); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 100 , true, 'ws_derivateCase status_code = 100'); + $msg1 = "Task doesn't have a valid user in variable SYS_NEXT_USER_TO_BE_ASSIGNED or this variable doesn't exist."; + $t->is( $result->message , $msg1, $msg1 ); + + $variables = array ( 'SYS_NEXT_USER_TO_BE_ASSIGNED' => '00000000000000000000000000000001' ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "1 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code == 0 , true, 'ws_derivateCase status_code = 0'); + $assign = $result->message; + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + $msg1 = "Task 2 - Value Assign(admin)"; + $t->is( trim( $result->message) , $msg1, $msg1 ); + + } + + + +*/ diff --git a/workflow/engine/test/unit/ws/SubprocessTest.php b/workflow/engine/test/unit/ws/SubprocessTest.php new file mode 100644 index 000000000..d97596971 --- /dev/null +++ b/workflow/engine/test/unit/ws/SubprocessTest.php @@ -0,0 +1,166 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + $t = new lime_test( 2, new lime_output_color()); + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->todo( 'complete this test'); + +/* + + $t = new lime_test( 39, new lime_output_color()); + $t->diag('Selection Derivation Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID_SELECTION', '324304616490b213ae38690016293793'); + define ( 'START_CYCLICAL_TASK', '917060771490b214838edb9072930947'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php'); + $t->is( function_exists ('ws_open') , true, 'include wsClient.php'); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + + ws_open (); + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->is( strlen ($sessionId) > 10 , true, 'get a valid SessionId'); + $t->diag('Session Id: ' . $sessionId ); + + $t->diag('-----------------------------------' ); + $t->diag('Initial Subprocess Test' ); + $t->diag('Process Guid: ' . PROCESS_UID_SELECTION ); + $t->diag('Starting Task: ' . START_CYCLICAL_TASK ); + for($i=0;$i<1;$i++) + { + $result = ws_newCase ( PROCESS_UID_SELECTION, START_CYCLICAL_TASK, array()); + + //se crea el proceso padre + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + $t->is( $result->status_code == 0 , true, 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) + { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + + //se envia valor para el dynaform de la primera tarea + $variables = array ( 'name' => 'Pepes' ); + $result = ws_sendVariables ($caseId, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg1 = "1 variables received."; + $t->is( $result->message , $msg1, $msg1 ); + + //se deriva y esto ocasiona que se el proceso HIJO sea creado, + $result = ws_derivateCase ($caseId, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0 '); //verificar tipo de derivaciopn s/ws + $t->diag( 'Case number--> ' . $result->derivation['caseNumber'] ); + //deberiamos obtener de alguna forma el UID del proceso HIJO + $caseIdHijo = $result->derivation['caseId']; + $t->diag( 'child caseid ' . $caseIdHijo ); + + //verificar que el proceso hijo tiene la variable names, con el valor que nosotros enviamos al proceso PADRE + $variables = array ( 'names', 'SYS_LANG', 'SYS_APPLICATION'); + $result = ws_getVariables ( $caseIdHijo, $variables ); + + $t->is( $result->variables['names'] , 'Pepes', 'variables[names] should be constant'); + $t->is( $result->variables['SYS_LANG'] , 'en', 'variables[SYS_LANG] should be constant en'); + + //derivar a la siguiente tarea del proceso hijo + $result = ws_derivateCase ($caseIdHijo, 1 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase : from first to second task in child Case'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0 '); //verificar tipo de derivaciopn s/ws + + + // enviar valores para las variables A y B, para realizar las operaciones aritmeticas. + $variables = array ( 'NUMX' => '4', 'NUMY' => '2' ); + $result = ws_sendVariables ($caseIdHijo, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_sendVariables in child process'); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0'); + $msg2 = "2 variables received."; + $t->is( $result->message , $msg2, $msg2 ); + $t->diag('Execute Triggers.....'); + + //execute triggers + $result = ws_executeTrigger ( $caseIdHijo, '613346661490b60f7b7e4f3014763320', 2 ); + $t->is( $result->status_code == 0 , true, 'ws_sendVariables status_code = 0, execute trigrer succesfull '); + $t->diag($result->message); + $t->diag('Execute Triggers end.....'); + + //verificar que el proceso hijo ha terminado + $variables = array ( 'SUM', 'RES', 'MUL', 'DIV'); + $result = ws_getVariables ( $caseIdHijo, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_getVariables in child process'); + $t->is( $result->variables['SUM'] , 6, 'variables[SUM] should be 6'); + $t->is( $result->variables['RES'] , 2, 'variables[RES] should be 2'); + $t->is( $result->variables['MUL'] , 8, 'variables[MUL] should be 8'); //derivar el proceso HIJO al padre, + $t->is( $result->variables['DIV'] , 2, 'variables[DIV] should be 2'); $result = ws_derivateCase ($caseIdHijo, 2 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase : from second to third(end) task in child Case'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0 from second to third(end) task in child Case'); + + //verificar en el proceso PADRE que llegaron las variables resultado de las operaciones matematicas + $variables = array ( 'sum', 'res', 'mul', 'div'); + $result = ws_getVariables ( $caseId, $variables ); + $t->is( $result->variables['sum'] , 6, 'variables[SUM] should be 6'); + $t->is( $result->variables['res'] , 2, 'variables[RES] should be 2'); + $t->is( $result->variables['mul'] , 8, 'variables[MUL] should be 8'); + $t->is( $result->variables['div'] , 2, 'variables[DIV] should be 2'); + + //derivar el proceso PADRE a su ultima tarea + $result = ws_derivateCase ($caseId, 3 ); + $t->isa_ok( $result, 'stdClass', 'executed ws_derivateCase : from second to third(end) task in child Case'); + $t->is( $result->status_code, 0, 'ws_derivateCase status_code = 0 from second to third(end) task in child Case'); + + //verificar que el proceso PADRE ha terminado + $result = ws_getCaseInfo ($caseId, 0); print_r($result); + $t->isa_ok( $result, 'stdClass', 'Finish process to testing'); + $t->is( $result->status_code, 0, 'ws_getCaseInfo status_code = 0 '); + $t->is( $result->message, 'case found', 'ws_getCaseInfo message case found'); + $t->is( $result->caseId, $caseId, 'ws_getCaseInfo caseId ox'); + $t->is( $result->caseNumber, $caseNumber, 'ws_getCaseInfo caseNumber ox'); + $t->is( $result->caseStatus, 'COMPLETED', 'ws_getCaseInfo caseStatus ox'); + $t->is( $result->caseParalell, 'N', 'ws_getCaseInfo caseParalell ox'); + $msg = sprintf ( "Check the case \033[0;31;32m%s\033[0m in the Draft List", $caseNumber); + $t->diag($msg ); + + } + + } + + +*/ \ No newline at end of file diff --git a/workflow/engine/test/unit/ws/basicMethodsTest.php b/workflow/engine/test/unit/ws/basicMethodsTest.php new file mode 100644 index 000000000..9d07a9326 --- /dev/null +++ b/workflow/engine/test/unit/ws/basicMethodsTest.php @@ -0,0 +1,512 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + + $t = new lime_test( 153, new lime_output_color()); + $t->diag('Basic Web Services Methods Test' ); + + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + define ( 'PROCESS_UID', '34537126948bc50f6dc0ad8058165755'); + define ( 'PROCESS_UID_LIBRARY', '45325906448e0e237986394052497623'); + define ( 'START_SEQ_CYCLICAL_TASK', '31132134648bc50fb7afa90020304752'); + define ( 'START_SEQ_MANUAL_TASK', '58845888048bc514a9ca3f6076028720'); + define ( 'START_REQ_VALUE_TASK', '42952443148bc515a7aae98069470300'); + define ( 'STARTERS_GROUP', '4466311448bd9a5788a892004431840'); + define ( 'DERIVATORS_GROUP', '24537073048ee0d6fc69088047537069'); + define ( 'TEST_TRIGGER', '6421002784aa91b4fced632057479964'); + + global $sessionId; + global $client; + + $t->is( strlen (WS_WSDL_URL) > 10 , true, 'include wsConfig.php' ); + $t->is( function_exists('ws_open') , true, 'include wsClient.php' ); + $t->diag('--------------- wsClient functions --------------------' ); + $t->is( function_exists('ws_open'), true, 'ws_open()' ); + $t->is( function_exists('ws_open_with_params'), true, 'ws_open_with_params()' ); + $t->is( function_exists('ws_newCase'), true, 'ws_newCase()' ); + $t->is( function_exists('ws_sendEmailMessage'), true, 'ws_sendEmailMessage()' ); + $t->is( function_exists('ws_getVariables'), true, 'ws_getVariables()' ); + $t->is( function_exists('ws_sendVariables'), true, 'ws_sendVariables()' ); + $t->is( function_exists('ws_executeTrigger'), true, 'ws_executeTrigger()' ); + $t->is( function_exists('ws_routeCase'), true, 'ws_routeCase()' ); + $t->is( function_exists('ws_processList'), true, 'ws_processList()' ); + $t->is( function_exists('ws_getCaseInfo'), true, 'ws_getCaseInfo()' ); + $t->is( function_exists('ws_reassignCase'), true, 'ws_reassignCase()' ); + $t->is( function_exists('ws_userList'), true, 'ws_userList()' ); + $t->is( function_exists('ws_groupList'), true, 'ws_groupList()' ); + $t->is( function_exists('ws_caseList'), true, 'ws_caseList()' ); + $t->is( function_exists('ws_roleList'), true, 'ws_roleList()' ); + $t->is( function_exists('ws_taskCase'), true, 'ws_taskCase()' ); + //$t->is( function_exists('ws_sendFileByCurl'), true, 'ws_sendFileByCurl()' ); + $t->is( function_exists('ws_createUser'), true, 'ws_createUser()' ); + $t->is( function_exists('ws_assignUserToGroup'),true, 'ws_assignUserToGroup()' ); + $t->is( function_exists('ws_systemInformation'),true, 'ws_systemInformation()' ); + $t->is( function_exists('ws_triggerList') ,true, 'ws_triggerList()' ); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + ws_open (); + + $t->diag('--------------- defined WSDL functions --------------------' ); + $methods = $client->__getFunctions(); + $types = $client->__getTypes(); + + $t->is( count($methods) , 22, '22 functions in the wsdl file'); + $t->is( $methods[0] , 'loginResponse login(login $parameters)', 'login'); + $t->is( $methods[1] , 'processListResponse processList(processListRequest $parameters)' , 'processList'); + $t->is( $methods[2] , 'roleListResponse roleList(roleListRequest $parameters)' , 'roleList'); + $t->is( $methods[3] , 'groupListResponse groupList(groupListRequest $parameters)' , 'groupList'); + $t->is( $methods[4] , 'userListResponse userList(userListRequest $parameters)' , 'userList'); + $t->is( $methods[5] , 'caseListResponse caseList(caseListRequest $parameters)' , 'caseList'); + $t->is( $methods[6] , 'createUserResponse createUser(createUserRequest $parameters)' , 'createUser'); + $t->is( $methods[7] , 'pmResponse assignUserToGroup(assignUserToGroupRequest $parameters)' , 'assignUserToGroup'); + $t->is( $methods[8] , 'newCaseResponse newCase(newCaseRequest $parameters)' , 'newCase'); + $t->is( $methods[9] , 'pmResponse reassignCase(reassignCaseRequest $parameters)' , 'reassignCase'); + $t->is( $methods[10] , 'pmResponse newCaseImpersonate(newCaseImpersonateRequest $parameters)', 'newCaseImpersonate'); + $t->is( $methods[11] , 'routeCaseResponse routeCase(routeCaseRequest $parameters)' , 'routeCase'); + $t->is( $methods[12] , 'pmResponse executeTrigger(executeTriggerRequest $parameters)' , 'executeTrigger'); + $t->is( $methods[13] , 'pmResponse sendVariables(sendVariablesRequest $parameters)' , 'sendVariables'); + $t->is( $methods[14] , 'getVariablesResponse getVariables(getVariablesRequest $parameters)' , 'getVariables'); + $t->is( $methods[15] , 'pmResponse sendMessage(sendMessageRequest $parameters)' , 'sendMessage'); + $t->is( $methods[16] , 'getCaseInfoResponse getCaseInfo(getCaseInfoRequest $parameters)' , 'getCaseInfo'); + $t->is( $methods[17] , 'taskListResponse taskList(taskListRequest $parameters)' , 'taskList'); + $t->is( $methods[18] , 'taskCaseResponse taskCase(taskCaseRequest $parameters)' , 'taskCase'); + $t->is( $methods[19] , 'systemInformationResponse systemInformation(systemInformationRequest $parameters)', 'systemInformation'); + $t->is( $methods[20] , 'triggerListResponse triggerList(triggerListRequest $parameters)' , 'triggerList'); + $t->is( $methods[21] , 'importProcessFromLibraryResponse importProcessFromLibrary(importProcessFromLibraryRequest $parameters)' , 'importProcessFromLibraryRequest'); + + $t->diag('--------------- defined WSDL types --------------------' ); + + $t->is( count($types) , 52, '52 types in the wsdl file'); + + $type0 = "struct login {\n string userid;\n string password;\n}"; + $type1 = "struct loginResponse {\n integer status_code;\n string message;\n string version;\n string timestamp;\n}" ; + $type2 = "struct pmResponse {\n integer status_code;\n string message;\n string timestamp;\n}" ; + $type3 = "struct processListRequest {\n string sessionId;\n}" ; + $type4 = "struct processListStruct {\n string guid;\n string name;\n}" ; + $type5 = "struct processListResponse {\n processListStruct processes;\n}" ; + $type6 = "struct roleListStruct {\n string guid;\n string name;\n}" ; + $type7 = "struct roleListRequest {\n string sessionId;\n}" ; + $type8 = "struct roleListResponse {\n roleListStruct roles;\n}" ; + $type9 = "struct groupListStruct {\n string guid;\n string name;\n}" ; + $type10 = "struct groupListRequest {\n string sessionId;\n}" ; + $type11 = "struct groupListResponse {\n groupListStruct groups;\n}" ; + $type12 = "struct userListStruct {\n string guid;\n string name;\n}" ; + $type13 = "struct userListRequest {\n string sessionId;\n}" ; + $type14 = "struct userListResponse {\n userListStruct users;\n}" ; + $type15 = "struct caseListStruct {\n string guid;\n string name;\n string status;\n string delIndex;\n}" ; + $type16 = "struct caseListRequest {\n string sessionId;\n}" ; + $type17 = "struct caseListResponse {\n caseListStruct cases;\n}" ; + $type18 = "struct createUserRequest {\n string sessionId;\n string userId;\n string firstname;\n string lastname;\n string email;\n string role;\n string password;\n}" ; + $type19 = "struct createUserResponse {\n integer status_code;\n string message;\n string userUID;\n string timestamp;\n}" ; + $type20 = "struct assignUserToGroupRequest {\n string sessionId;\n string userId;\n string groupId;\n}" ; + $type21 = "struct variableStruct {\n string name;\n}" ; + $type22 = "struct sendVariablesRequest {\n string sessionId;\n string caseId;\n variableListStruct variables;\n}" ; + $type23 = "struct variableListStruct {\n string name;\n string value;\n}" ; + $type24 = "struct variableListRequest {\n variableListStruct variables;\n}" ; + $type25 = "struct getVariablesResponse {\n integer status_code;\n string message;\n string timestamp;\n variableListStruct variables;\n}" ; + $type26 = "struct getVariablesRequest {\n string sessionId;\n string caseId;\n variableStruct variables;\n}" ; + $type27 = "struct newCaseRequest {\n string sessionId;\n string processId;\n string taskId;\n variableListStruct variables;\n}" ; + $type28 = "struct newCaseResponse {\n integer status_code;\n string message;\n string caseId;\n string caseNumber;\n string timestamp;\n}" ; + $type29 = "struct reassignCaseRequest {\n string sessionId;\n string caseId;\n string delIndex;\n string userIdSource;\n string userIdTarget;\n}" ; + $type30 = "struct newCaseImpersonateRequest {\n string sessionId;\n string processId;\n string userId;\n variableStruct variables;\n}" ; + $type31 = "struct routeListStruct {\n string userId;\n string userName;\n string taskId;\n string taskName;\n integer delIndex;\n integer delThread;\n string delThreadStatus;\n}" ; + $type32 = "struct routeCaseRequest {\n string sessionId;\n string caseId;\n string delIndex;\n}" ; + $type33 = "struct routeCaseResponse {\n integer status_code;\n string message;\n string timestamp;\n routeListStruct routing;\n}" ; + $type34 = "struct executeTriggerRequest {\n string sessionId;\n string caseId;\n string triggerIndex;\n string delIndex;\n}" ; + $type35 = "struct sendMessageRequest {\n string sessionId;\n string caseId;\n string from;\n string to;\n string cc;\n string bcc;\n string subject;\n string template;\n}" ; + $type36 = "struct getCaseInfoRequest {\n string sessionId;\n string caseId;\n string delIndex;\n}" ; + $type37 = "struct getCaseInfoStruct {\n string userId;\n string userName;\n string taskId;\n string taskName;\n integer delIndex;\n integer delThread;\n string delThreadStatus;\n}"; + $type38 = "struct getCaseInfoResponse {\n integer status_code;\n string message;\n string caseId;\n string caseNumber;\n string caseName;\n string caseStatus;\n string caseParalell;\n string caseCreatorUser;\n string caseCreatorUserName;\n string processId;\n string processName;\n string createDate;\n getCaseInfoStruct currentUsers;\n}"; + $type39 = "struct taskListRequest {\n string sessionId;\n}" ; + $type40 = "struct taskListStruct {\n string guid;\n string name;\n}" ; + $type41 = "struct taskListResponse {\n taskListStruct tasks;\n}" ; + $type42 = "struct taskCaseStruct {\n string guid;\n string name;\n}" ; + $type43 = "struct taskCaseRequest {\n string sessionId;\n string caseId;\n}" ; + $type44 = "struct taskCaseResponse {\n taskCaseStruct taskCases;\n}"; + $type45 = "struct systemInformationRequest {\n string sessionId;\n}"; + $type46 = "struct systemInformationResponse {\n integer status_code;\n string message;\n string timestamp;\n string version;\n string operatingSystem;\n string webServer;\n string serverName;\n string serverIp;\n string phpVersion;\n string databaseVersion;\n string databaseServerIp;\n string databaseName;\n string availableDatabases;\n string userBrowser;\n string userIp;\n}"; + $type47 = "struct triggerListRequest {\n string sessionId;\n}"; + $type48 = "struct triggerListStruct {\n string guid;\n string name;\n string processId;\n}"; + $type49 = "struct triggerListResponse {\n triggerListStruct triggers;\n}"; + $type50 = "struct importProcessFromLibraryRequest {\n string sessionId;\n string processId;\n string version;\n string importOption;\n string usernameLibrary;\n string passwordLibrary;\n}"; + $type51 = "struct importProcessFromLibraryResponse {\n integer status_code;\n string message;\n string processId;\n string processTitle;\n string category;\n string version;\n}"; + + $t->is( $types[0 ] , $type0 , 'login ' ); + $t->is( $types[1 ] , $type1 , 'loginResponse ' ); + $t->is( $types[2 ] , $type2 , 'pmResponse ' ); + $t->is( $types[3 ] , $type3 , 'processListRequest ' ); + $t->is( $types[4 ] , $type4 , 'processListStruct ' ); + $t->is( $types[5 ] , $type5 , 'processListResponse ' ); + $t->is( $types[6 ] , $type6 , 'processListStruct ' ); + $t->is( $types[7 ] , $type7 , 'roleListStruct ' ); + $t->is( $types[8 ] , $type8 , 'roleListRequest ' ); + $t->is( $types[9 ] , $type9 , 'roleListResponse ' ); + $t->is( $types[10] , $type10 , 'groupListStruct ' ); + $t->is( $types[11] , $type11 , 'groupListRequest ' ); + $t->is( $types[12] , $type12 , 'groupListResponse ' ); + $t->is( $types[13] , $type13 , 'userListStruct ' ); + $t->is( $types[14] , $type14 , 'userListRequest ' ); + $t->is( $types[15] , $type15 , 'userListResponse ' ); + $t->is( $types[16] , $type16 , 'caseListStruct ' ); + $t->is( $types[17] , $type17 , 'caseListRequest ' ); + $t->is( $types[18] , $type18 , 'caseListResponse ' ); + $t->is( $types[19] , $type19 , 'createUserRequest ' ); + $t->is( $types[20] , $type20 , 'createUserResponse ' ); + $t->is( $types[21] , $type21 , 'assignUserToGroupRequest ' ); + $t->is( $types[22] , $type22 , 'variableStruct ' ); + $t->is( $types[23] , $type23 , 'sendVariablesRequest ' ); + $t->is( $types[24] , $type24 , 'variableListStruct ' ); + $t->is( $types[25] , $type25 , 'variableListRequest ' ); + $t->is( $types[26] , $type26 , 'variableListResponse ' ); + $t->is( $types[27] , $type27 , 'getVariablesRequest ' ); + $t->is( $types[28] , $type28 , 'newCaseRequest ' ); + $t->is( $types[29] , $type29 , 'newCaseResponse ' ); + $t->is( $types[30] , $type30 , 'reassignCaseRequest ' ); + $t->is( $types[31] , $type31 , 'newCaseImpersonateRequest ' ); + $t->is( $types[32] , $type32 , 'derivateListStruct ' ); + $t->is( $types[33] , $type33 , 'routeCaseRequest ' ); + $t->is( $types[34] , $type34 , 'routeCaseResponse ' ); + $t->is( $types[35] , $type35 , 'executeTriggerRequest ' ); + $t->is( $types[36] , $type36 , 'sendMessageRequest ' ); + $t->is( $types[37] , $type37 , 'getCaseInfoRequest ' ); + $t->is( $types[38] , $type38 , 'getCaseInfoStruct ' ); + $t->is( $types[39] , $type39 , 'getCaseInfoResponse ' ); + $t->is( $types[40] , $type40 , 'taskListRequest ' ); + $t->is( $types[41] , $type41 , 'taskListStruct ' ); + $t->is( $types[42] , $type42 , 'taskListResponse ' ); + $t->is( $types[43] , $type43 , 'taskCaseStruct ' ); + $t->is( $types[44] , $type44 , 'taskCaseRequest ' ); + $t->is( $types[45] , $type45 , 'taskCaseResponse ' ); + $t->is( $types[46] , $type46 , 'systemInformationRequest ' ); + $t->is( $types[47] , $type47 , 'systemInformationResponse ' ); + $t->is( $types[48] , $type48 , 'triggerListRequest ' ); + $t->is( $types[49] , $type49 , 'triggerListStruct ' ); + $t->is( $types[50] , $type50 , 'triggerListResponse ' ); + $t->is( $types[51] , $type51 , 'triggerListResponse ' ); + $t->is( $types[52] , $type52 , 'triggerListResponse ' ); + + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + $t->diag('--------------- now will check every method of wsdl and soap --------------------' ); + + $info = ws_systemInformation(); + + $t->is( $info->status_code , 0 , 'ws_systemInformation status_code = 0'); + $t->diag( ' version ' . $info->version ); + $t->diag( ' operatingSystem ' . $info->operatingSystem ); + $t->diag( ' webServer ' . $info->webServer ); + $t->diag( ' serverName ' . $info->serverName ); + $t->diag( ' serverIp ' . $info->serverIp ); + $t->diag( ' phpVersion ' . $info->phpVersion ); + $t->diag( ' databaseVersion ' . $info->databaseVersion ); + $t->diag( ' databaseServerIp ' . $info->databaseServerIp ); + $t->diag( ' databaseName ' . $info->databaseName ); + $t->diag( ' availableDatabases ' . $info->availableDatabases ); + $t->diag( ' userBrowser ' . $info->userBrowser ); + $t->diag( ' userIp ' . $info->userIp ); + + $t->is( strlen ($sessionId) > 30 , true, 'getting a valid SessionId'); + $t->is( strlen ($sessionId) > 30 , true, 'ws_open works fine'); + $t->diag('Session Id: ' . $sessionId ); + + //checking the processList + $processes = ws_processList(); + $t->is( count ($processes->processes) >= 0 , true, 'ws_processList works fine'); + + $foundProcess = false; + if ( is_array ($processes->processes ) ) { + foreach ( $processes->processes as $key => $val ) { + if ( $val->guid == PROCESS_UID ) $foundProcess = true; + } + } + else + if ( $processes->processes->guid == PROCESS_UID ) $foundProcess = true; + + if ( $foundProcess ) { + $t->is( $foundProcess, true, 'Sequential Process is present in this Workspace'); + } + else { + $res = ws_importProcessFromLibrary ( PROCESS_UID_LIBRARY , '' ); + if ( $res->status_code == 0 ) { + $t->is( $res->status_code, 0, 'Process imported from Library successfully'); + $t->diag( ' processTitle ' . $res->processTitle ); + $t->diag( ' category ' . $res->category ); + $t->diag( ' version ' . $res->version ); + } + else + throw ( new Exception ( $res->message . ". Process '". PROCESS_UID ."' ") ); + } + + //checking the groupList + $groups = ws_groupList() ; + $t->is( count ($groups->groups) >= 2 , true, 'ws_groupList works fine'); + $foundGroup1 = false; + $foundGroup2 = false; + foreach ( $groups->groups as $key => $val ) { + if ( $val->guid == STARTERS_GROUP ) $foundGroup1 = true; + if ( $val->guid == DERIVATORS_GROUP ) $foundGroup2 = true; + } + $t->is( $foundGroup1, true, 'Starter grous is present in Workspace'); + $t->is( $foundGroup2, true, 'derivators grous is present in Workspace'); + + //checking user list + $users = ws_userList() ; + $t->is( count ($users->users) >= 1 , true, 'ws_userList works fine'); + $foundUser1 = false; + foreach ( $users->users as $key => $val ) { + if ( $val->guid == '00000000000000000000000000000001' ) $foundUser1 = true; + } + $t->is( $foundUser1, true, 'Admin user is present in Workspace'); + + //checking roles + $roles = ws_roleList() ; + $t->is( count ($roles->roles) >= 2 , true, 'ws_roleList works fine'); + $roleOperator = ''; + foreach ( $roles->roles as $key => $val ) { + if ( $val->name == 'PROCESSMAKER_OPERATOR' ) + $roleOperator = $val->guid; + } + $t->is( strlen( $roleOperator ) >= 30 , true, 'role PROCESSMAKER_OPERATOR exists'); + + //checking the triggerList + $triggers = ws_triggerList(); + $t->is( count ($triggers->triggers) >= 1 , true, 'ws_triggerList there are ' . count ($triggers->triggers) . ' triggers in this workspace' ); + + $foundTrigger = false; + if ( is_array ( $triggers->triggers ) ) + foreach ( $triggers->triggers as $key => $val ) { + if ( $val->guid == TEST_TRIGGER )$foundTrigger = true; + } + else { + if ( $triggers->triggers->guid == TEST_TRIGGER )$foundTrigger = true; + } + $t->is( $foundTrigger, true, 'the test trigger is present in Workspace'); + + $t->diag('-----------------------------------' ); + $t->diag('Cyclical Sequential Derivation Test' ); + $t->diag('Process Guid: ' . PROCESS_UID ); + $t->diag('Starting Task: ' . START_SEQ_CYCLICAL_TASK ); + + //creating two new users for the starters and derivations groups' + $dateNow = date ( 'H-m-d H:i:s' ); + $dateDay = date ( 'W' ); + $dateYear = date ( 'Y' ); + + $user1Id = 'John' . date ( 'mdHi' ); + $firstname = 'John ' . date ( 'mdHi' ); + $lastname = 'Doe'; + $email = 'John' . date ( 'mdHi' ) . '@colosa.com'; + $role = $roleOperator; + $password = 'sample'; + $res = ws_createUser ( $user1Id, $firstname, $lastname, $email, $roleOperator, $password ); + $t->isa_ok( $res, 'stdClass', 'executed ws_createUser'); + if( $res->status_code == 0 ) + {$t->is( $res->status_code,0, 'ws_createUser status_code = 0'); + } + else{$t->is( $res->status_code,7, 'ws_createUser status_code = 7'); + } + $t->diag( $res->message ); + $t->diag( 'UserUID = ' . $res->userUID); + $user1Uid = $res->userUID; + $res = ws_assignUserToGroup ( $user1Uid, STARTERS_GROUP ); + + $user2Id = 'Mary' . date ( 'mdHi' ); + $firstname = 'Mary ' . date ( 'mdHi' ); + $lastname = 'Smith'; + $email = 'Mary' . date ( 'mdHi' ) . '@colosa.com'; + $role = $roleOperator; + $password = 'sample'; + $res = ws_createUser ( $user2Id, $firstname, $lastname, $email, $roleOperator, $password ); + $t->isa_ok( $res, 'stdClass', 'executed ws_createUser'); + if( $res->status_code == 0 ){ + $t->is( $res->status_code , 0 , 'ws_createUser status_code = 0'); + }else{ + $t->is( $res->status_code , 7 , 'ws_createUser status_code = 7'); + } + + $t->diag( $res->message ); + $t->diag( 'UserUID = ' . $res->userUID); + $user2Uid = $res->userUID; + $res = ws_assignUserToGroup ( $user2Uid, DERIVATORS_GROUP ); + + $res = ws_open_with_params ( WS_WSDL_URL, $user1Id, 'sample'); + + //create a case with John + $variables = array(); + $variables[] = array ( 'name' => 'webServer', 'value' => $info->webServer ); + $variables[] = array ( 'name' => 'phpVersion', 'value' => $info->phpVersion ); + + $result = ws_newCase ( PROCESS_UID, START_SEQ_CYCLICAL_TASK, $variables ); + $t->isa_ok( $result, 'stdClass', 'executed ws_newCase'); + + $t->is( $result->status_code , 0 , 'ws_newCase status_code = 0'); + if ( $result->status_code == 0 ) { + $caseId = $result->caseId; + $caseNumber = $result->caseNumber; + $msg = sprintf ( "New Case created: \033[0;31;32m%s %s\033[0m", $caseNumber, $caseId ); + $t->diag($msg ); + } + else { + $t->diag('------------ Error executing newCase ---------------------' ); + $t->diag(' status code : ' . $result->status_code ); + $t->diag(' message : ' . $result->message ); + $t->diag(' timestamp : ' . $result->timestamp ); + die; + } + + + //check caseList as the newCase was succesful, there are at least one case for this user + $cases = ws_caseList() ; + $t->is( count ($cases->cases ) >= 1 , true, 'ws_caseList works fine'); + + //getCaseInfo + $delIndex = 1; + $res = ws_getCaseInfo ($caseId, $delIndex); + $t->is( $res->status_code , 0 , 'ws_getCaseInfo status_code = 0'); + $t->is( $res->message , 'Command executed successfully', 'ws_getCaseInfo message '); + $t->is( $res->caseId , $caseId , 'ws_getCaseInfo caseId = ' . $caseId); + $t->is( $res->caseStatus , 'DRAFT' , 'ws_getCaseInfo caseStatus = ' . $res->caseStatus ); + if( $res->caseCreatorUser == '3454143534b144c02717596034198392'){ + $t->is( $res->caseCreatorUser , $user1Uid , 'ws_getCaseInfo caseCreatorUser = ' . $user1Id ); + } + $routedUser = $res->caseCurrentUser; + $t->diag('ws_getCaseInfo caseNumber: ' . $res->caseNumber ); + $t->diag('ws_getCaseInfo caseName: ' . $res->caseName ); + $t->diag('ws_getCaseInfo caseStatus: ' . $res->caseStatus ); + $t->diag('ws_getCaseInfo caseParalell: ' . $res->caseParalell ); + $t->diag('ws_getCaseInfo caseCreatorUser: ' . $res->caseCreatorUser ); + $t->diag('ws_getCaseInfo caseCreatorUserName: ' . $res->caseCreatorUserName ); + $t->diag('ws_getCaseInfo processId: ' . $res->processId ); + $t->diag('ws_getCaseInfo processName: ' . $res->processName ); + $t->diag('ws_getCaseInfo createDate: ' . $res->createDate ); + $t->diag('ws_getCaseInfo currentUsers: ' . $res->currentUsers); + + //sending two variables to this case + $variables = array(); + $variables[] = array ( 'name' => 'firstString', 'value' => $user1Id ); + $variables[] = array ( 'name' => 'secondString', 'value' => PHP_OS ); + $res = ws_sendVariables ($caseId, $variables ); + $t->is( $res->status_code , 0 , "ws_sendVariables status_code = 0 "); + $t->is( $res->message, '2 variables received' , "ws_sendVariables 2 variables received"); + + //execute trigger to concatenate previous strings + $res = ws_executeTrigger ($caseId, TEST_TRIGGER ,$delIndex ); + $t->is( $res->status_code , 0 , 'ws_executeTrigger status_code = 0'); + $t->diag( "trigger source code: \n" . $res->message); + + //get variables and check results + $getVariables = array( 'PIN', 'firstString', 'secondString', 'result', 'today', 'webServer', 'phpVersion' ); + $res = ws_getVariables ($caseId, $getVariables ); + $t->is( $res->status_code , 0 , 'ws_getVariables status_code = 0'); + $t->is( $res->message, '7 variables sent' , "ws_getVariables 7 variables received"); + $t->is( strlen($res->variables[0]->value), 4 , "variable PIN received ok (" . $res->variables[0]->value . ")" ); + $t->is( $res->variables[1]->value, $user1Id , "variable firstString received ok (" . $res->variables[1]->value . ")" ); + $t->is( $res->variables[2]->value, PHP_OS , "variable secondString received ok (" . $res->variables[2]->value . ")" ); + $t->is( $res->variables[3]->value,$user1Id.' '.PHP_OS, "variable result received ok (" . $res->variables[3]->value . ")" ); + $t->is( substr($res->variables[4]->value,0,10),date('Y-m-d'),"variable today received ok (" . $res->variables[4]->value . ")" ); + $t->is( $res->variables[5]->value, $info->webServer , "variable webServer received ok (" . $res->variables[5]->value . ")" ); + $t->is( $res->variables[6]->value, $info->phpVersion , "variable phpVersion received ok (" . $res->variables[6]->value . ")" ); + + //Get case info for invalid case + $res = ws_getCaseInfo ('123456', $delIndex); + $t->is( $res->status_code , 100 , "ws_getCaseInfo status_code = 100 Case doesn't exist."); + $t->diag('ws_getCaseInfo for invalid case is : '. $res->message ); + + //routing a case from John to Mary + $delIndex = 1; + $result = ws_routeCase ($caseId, $delIndex ); + $t->isa_ok( $result, 'stdClass', 'executed ws_routeCase'); + $t->is( $result->status_code, 0, 'ws_routeCase status_code = 0'); + $t->diag ( 'route case message: ' . $result->message ); + $t->is( $result->routing->delIndex, 2 , "delIndex = 2" ); + $t->is( $result->routing->delThread, 1 , "delThread = 1" ); + $t->is( $result->routing->delThreadStatus, 'OPEN', "delThreadStatus = OPEN" ); + + $msg = trim ( sprintf ( "Case Routed to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + + //getCaseInfo to get the current user + $delIndex = 2; + $res = ws_getCaseInfo ($caseId, $delIndex); + $t->is( $res->status_code , 0 , 'ws_getCaseInfo status_code = 0'); + $routedUser = $res->currentUsers->userId; + $routedUserName = $res->currentUsers->userName; + $delIndex = $res->currentUsers->delIndex; + $t->diag( 'ws_getCaseInfo Routed user is ' . $routedUser ); + $t->diag( 'ws_getCaseInfo Routed user is ' . $routedUserName ); + $t->is( $res->caseStatus , 'TO_DO' , 'ws_getCaseInfo caseStatus = ' . $res->caseStatus ); + + + //reassign this case to Mary + $res = ws_open( ); + + $result = ws_reassignCase ($caseId, $delIndex, $routedUser, $user2Uid); + $t->isa_ok( $result, 'stdClass', 'executed ws_reassignCase'); + if ( $result->status_code == 0 ) { + $t->is( $result->status_code, 0, 'ws_reassignCase status_code = 0'); + $t->diag( 'ws_reassignCase message: ' . $result->message ); + } + else { + $t->is( $result->status_code, 30, 'ws_reassignCase status_code = 30'); + $t->diag( 'ws_reassignCase message: ' . $result->message ); + } + //update delIndex after reassign + $res = ws_getCaseInfo ($caseId, $delIndex); + $t->is( $res->status_code , 0 , 'ws_getCaseInfo status_code = 0'); + $routedUser = $res->currentUsers->userId; + $routedUserName = $res->currentUsers->userName; + $delIndex = $res->currentUsers->delIndex; + $t->diag( 'ws_getCaseInfo Reassigned user is ' . $routedUser ); + $t->diag( 'ws_getCaseInfo Reassigned user is ' . $routedUserName ); + + //finishing a case from Mary + $res = ws_open_with_params ( WS_WSDL_URL, $user2Id, 'sample'); + $result = ws_routeCase ($caseId, $delIndex ); + $t->isa_ok( $result, 'stdClass', 'executed ws_routeCase'); + $t->is( $result->status_code, 0, 'ws_routeCase status_code = 0'); + $assign = $result->message; + + $msg = trim ( sprintf ( "Case Derivated to: \033[0;31;32m%s\033[0m", $result->message)); + $t->diag($msg ); + + //check if the case is closed + $res = ws_getCaseInfo ($caseId, $delIndex); + $t->is( $res->status_code , 0 , 'ws_getCaseInfo status_code = 0'); + $t->is( $res->caseStatus , 'COMPLETED' , 'ws_getCaseInfo caseStatus = ' . $res->caseStatus ); + + + + + + diff --git a/workflow/engine/test/unit/ws/bugRelease09Test.php b/workflow/engine/test/unit/ws/bugRelease09Test.php new file mode 100644 index 000000000..eaa1ebaf1 --- /dev/null +++ b/workflow/engine/test/unit/ws/bugRelease09Test.php @@ -0,0 +1,346 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //checking the processList + + function processList($t, $uid_Process,$process_uid_library ) + { + $processes = ws_processList(); + $t->is( count ($processes->processes) >= 0 , true, 'ws_processList works fine'); + + $foundProcess = false; + if ( is_array ($processes->processes ) ) { + foreach ( $processes->processes as $key => $val ) { + if ( $val->guid == $uid_Process ){ + $foundProcess = true; + + } + } + } + else + if ( $processes->processes->guid == $uid_Process ){ + $foundProcess = true; + } + + if ( $foundProcess ) { + $t->is( $foundProcess, true, 'Process for' .$uidName[1]. 'is present in this Workspace'); + } + else { + $res = ws_importProcessFromLibrary ( $process_uid_library , '' , 3, PML_USER_ID, PML_USER_PASS ); + if ( $res->status_code == 0 ) { + $t->is( $res->status_code, 0, 'Process imported from Library successfully'); + $t->diag( ' processTitle ' . $res->processTitle ); + $t->diag( ' category ' . $res->category ); + $t->diag( ' version ' . $res->version ); + } + else + throw ( new Exception ( $res->message . ". Process '". $uid_Process ."' ") ); + } + + } + //creating an user, if this user exists just skip this lines + function verifyUserExists ( $t, $username ) { + global $roleOperator; + + $firstname = $username ; + $lastname = 'Doe'; + $email = $username . '@colosa.com'; + $role = $roleOperator; + $password = 'sample'; + + $res = ws_createUser ( $username, $firstname, $lastname, $email, $roleOperator, $password ); + $t->isa_ok( $res, 'stdClass', 'executed ws_createUser'); + if ($res->status_code == 7 ) { + $t->is( $res->status_code , 7 , $username . ' is already created '); + } + + if ($res->status_code == 0 ) { + $t->is( $res->status_code , 0 , 'ws_createUser status_code = 0 for user ' . $username ); + $t->diag( $res->message ); + $t->diag( 'UserUID = ' . $res->userUID); + } + + } + + //Archivos requeridos + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + //******* Constates Procesos Release 09 ******* // + //Constates Procesos Bug 3947 + define ( 'PROCESS_UID', '5041008614abc53492778f2062174269'); + define ( 'PROCESS_UID_LIBRARY', '4024267104ac4af2771b844012334031'); + define ( 'START_TASK_UID', '2376437854abc5355ba93e8020811984'); + + //Constates Procesos Bug 3500 + define ( 'PROCESS_UID3500', '5492768614ad6a341a8d302080479261'); + define ( 'PROCESS_UID_LIBRARY3500', '7048004704ac6834046dff5024006812'); + define ( 'START_TASK_UID3500', '2225149194ad6a34a675960047603206'); + + //Constates Procesos Bug 3948 + define ( 'PROCESS_UID3948', '67593524648f370c469c043033436171'); + define ( 'PROCESS_UID_LIBRARY3948', '3779354504ad72506358ef5025405839'); + define ( 'START_TASK_UID3948', '2225149194ad6a34a675960047603206'); + + //Constates Procesos Bug 3757 + define ( 'PROCESS_UID3757', '7019135294acd8f11cc1275089288026'); + define ( 'PROCESS_UID_LIBRARY3757', '8470043374ad729196bc233052722688'); + define ( 'START_TASK_UID3757', '8783364554acd8f2f5aa371001390670'); + + + //******* Constates Procesos Release 11 *************// + + //Constates Procesos Bug 4138 + define ( 'PROCESS_UID4138', '7403318024afbd568328557093846607'); + define ( 'PROCESS_UID_LIBRARY4138', '618889924b0d72ee1e8d48041492421'); + define ( 'START_TASK_UID4138', ''); + + //Constates Procesos Bug 3227 + define ( 'PROCESS_UID3227', '5961202124afbbb96071641087311915'); + define ( 'PROCESS_UID_LIBRARY3227', '2341590934afc26725dae19067296505'); + define ( 'START_TASK_UID3227', '8985149674afbbb9f5e7b02093180322'); + + //Constates Procesos Bug 4025 + define ( 'PROCESS_UID4025', '7226950814af80ca8482ea8038668461'); + define ( 'PROCESS_UID_LIBRARY4025', '8185117214af9c139378dc8084788430'); + define ( 'START_TASK_UID4025', '8326587904af80cad7f72c8087571555'); + + //Constates Procesos Bug 3216 + define ( 'PROCESS_UID3216', '3182159894ade14309d0151096572870'); + define ( 'PROCESS_UID_LIBRARY3216', '3990660714af9baeb8d04a6038902756'); + define ( 'START_TASK_UID3216', '7099649794ade14365e5a55015058276'); + + //Constates Procesos Bug 3495 + define ( 'PROCESS_UID3495', '5384638834af26792c75720068072932'); + define ( 'PROCESS_UID_LIBRARY3495', '6443124704afc8405bae5c6095427535'); + define ( 'START_TASK_UID3495', '8345191624af2679a6b74a5066292659'); + + //Constates Procesos Bug 3943 + define ( 'PROCESS_UID3943', '447CEAF7BE6AEB'); + define ( 'PROCESS_UID_LIBRARY3943', '23310008148f211b3abef31074370823'); + define ( 'START_TASK_UID3943', '447CEAF7BE6AEB'); + + + //Constates Procesos Bug 3904 + define ( 'PROCESS_UID3904', '6863908894afd6a750802b7096073967'); + define ( 'PROCESS_UID_LIBRARY3904', '190051244b01c27c5d3bc4073716555'); + define ( 'START_TASK_UID3904', '8489595944afd6a7f062852065972316'); + + //Constates Procesos Bug 3903 + define ( 'PROCESS_UID3903', '8320886204b031419a70f84016574892'); + define ( 'PROCESS_UID_LIBRARY3903', '5651557564b05d34f0c6a54085262893'); + define ( 'START_TASK_UID3903', ''); + //Constates Procesos Bug 4120 + define ( 'PROCESS_UID4120', '3393197484afd256abf8111021901109'); + define ( 'PROCESS_UID_LIBRARY4120', '6544108344b06d0b55f8c44001258903'); + define ( 'START_TASK_UID4120', ''); + + + //**********************************************************************// + + global $sessionId; + global $client; + global $roleOperator; + + + + $t = new lime_test( 66, new lime_output_color()); + $t->diag('Basic Web Services Methods Test' ); + + + $t->is( function_exists('ws_open') , true, 'include wsClient.php' ); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + ws_open (); + + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + //Creación importación de procesos de la librería 09 + processList($t, PROCESS_UID , PROCESS_UID_LIBRARY ); + processList($t, PROCESS_UID3500, PROCESS_UID_LIBRARY3500 ); + processList($t, PROCESS_UID3948, PROCESS_UID_LIBRARY3948 ); + processList($t, PROCESS_UID3757, PROCESS_UID_LIBRARY3757 ); + + //Creación importación de procesos de la librería 11 + processList($t, PROCESS_UID4138, PROCESS_UID_LIBRARY4138 ); + processList($t, PROCESS_UID3227, PROCESS_UID_LIBRARY3227 ); + processList($t, PROCESS_UID4025, PROCESS_UID_LIBRARY4025 ); + processList($t, PROCESS_UID3216, PROCESS_UID_LIBRARY3216 ); + processList($t, PROCESS_UID3495, PROCESS_UID_LIBRARY3495 ); + processList($t, PROCESS_UID3943, PROCESS_UID_LIBRARY3943 ); + processList($t, PROCESS_UID3904, PROCESS_UID_LIBRARY3904 ); + processList($t, PROCESS_UID3903, PROCESS_UID_LIBRARY3903 ); + processList($t, PROCESS_UID4120, PROCESS_UID_LIBRARY4120 ); + + + //checking the groupList + $groups = ws_groupList() ; + $t->is( count ($groups->groups) >= 0 , true, 'ws_groupList works fine'); + $foundGroup1 = false; + $foundGroup2 = false; + $foundGroup3 = false; + $foundGroup4 = false; + $foundGroup5 = false; + $foundGroup6 = false; + $foundGroup7 = false; + $employees = false; + $supervisors = false; + $finance = false; + + foreach ( $groups->groups as $key => $val ) { + + if ( $val->name == "Group One" ) $foundGroup1 = true; + if ( $val->name == "Group Two" ) $foundGroup2 = true; + if ( $val->name == "Group Three") $foundGroup3 = true; + if ( $val->name == "Group Four" ) $foundGroup1 = true; + if ( $val->name == "Group Five" ) $foundGroup2 = true; + if ( $val->name == "Group Six" ) $foundGroup3 = true; + if ( $val->name == "Group Seven" ) $foundGroup1 = true; + if ( $val->name == "Employees" ) $employees = true; + if ( $val->name == "supervisors" ) $supervisors = true; + if ( $val->name == "employees" ) $finance = true; + + } + $t->is( $foundGroup1, true, 'ONE grous is present in Workspace'); + $t->is( $foundGroup2, true, 'TWO grous is present in Workspace'); + $t->is( $foundGroup2, true, 'THREE grous is present in Workspace'); + $t->is( $foundGroup2, true, 'FOUR grous is present in Workspace'); + $t->is( $foundGroup2, true, 'FIVE grous is present in Workspace'); + $t->is( $foundGroup2, true, 'SIX grous is present in Workspace'); + $t->is( $foundGroup2, true, 'SEVEN grous is present in Workspace'); + $t->is( $foundGroup2, true, 'employees grous is present in Workspace'); + $t->is( $foundGroup2, true, 'supervisors grous is present in Workspace'); + $t->is( $foundGroup2, true, 'finance grous is present in Workspace'); + + //checking roles + $roles = ws_roleList() ; + $t->is( count ($roles->roles) >= 2 , true, 'ws_roleList works fine'); + $roleOperator = ''; + foreach ( $roles->roles as $key => $val ) { + if ( $val->name == 'PROCESSMAKER_OPERATOR' ) + $roleOperator = $val->guid; + } + $t->is( strlen( $roleOperator ) >= 30 , true, 'role PROCESSMAKER_OPERATOR exists'); + + + //crear los 3 usuarios + + verifyUserExists ( $t, 'user1' ); + verifyUserExists ( $t, 'user2' ); + verifyUserExists ( $t, 'user3' ); + verifyUserExists ( $t, 'user4' ); + verifyUserExists ( $t, 'user5' ); + verifyUserExists ( $t, 'user6' ); + verifyUserExists ( $t, 'user7' ); + + + //checking user list and verify the three users are created + $users = ws_userList() ; + + $t->is( count ($users->users) >= 1 , true, 'ws_userList works fine'); + + $foundUser1 = false; + $foundUser2 = false; + $foundUser3 = false; + $foundUser4 = false; + $foundUser5 = false; + $foundUser6 = false; + $foundUser7 = false; + + $foundGroup1 = false; + $foundGroup2 = false; + $foundGroup3 = false; + $foundGroup4 = false; + $foundGroup5 = false; + $foundGroup6 = false; + $foundGroup7 = false; + + $supervisors = false; + $employees = false; + $finance = false; + // + $users = ws_userList(); + foreach ( $users->users as $key => $valuser ) { + if ( $valuser->name == 'user1' ) {$valuser1=$valuser->guid; $foundUser1 = true;} + if ( $valuser->name == 'user2' ) {$valuser2=$valuser->guid; $foundUser2 = true;} + if ( $valuser->name == 'user3' ) {$valuser3=$valuser->guid; $foundUser3 = true;} + if ( $valuser->name == 'user4' ) {$valuser4=$valuser->guid; $foundUser4 = true;} + if ( $valuser->name == 'user5' ) {$valuser5=$valuser->guid; $foundUser5 = true;} + if ( $valuser->name == 'user6' ) {$valuser6=$valuser->guid; $foundUser6 = true;} + if ( $valuser->name == 'user7' ) {$valuser7=$valuser->guid; $foundUser7 = true;} + + } + + $groups = ws_groupList(); + foreach ( $groups->groups as $key => $valgroups ) { + + if ( $valgroups ->name == 'Group One' ){$valgroups1=$valgroups->guid; $foundGroup1 = true;} + if ( $valgroups ->name == 'Group Two' ){$valgroups2=$valgroups->guid; $foundGroup2 = true;} + if ( $valgroups ->name == 'Group Three'){$valgroups3=$valgroups->guid; $foundGroup3 = true;} + if ( $valgroups ->name == 'Group Four' ){$valgroups4=$valgroups->guid; $foundGroup4 = true;} + if ( $valgroups ->name == 'Group Five' ){$valgroups5=$valgroups->guid; $foundGroup5 = true;} + if ( $valgroups ->name == 'Group Six' ){$valgroups6=$valgroups->guid; $foundGroup6 = true;} + if ( $valgroups ->name == 'Group Seven'){$valgroups7=$valgroups->guid; $foundGroup7 = true;} + + if ( $valgroups ->name == 'supervisors'){$valgroupsSupervisors =$valgroups->guid; $supervisors = true;} + if ( $valgroups ->name == 'employees') {$valgroupsEmployees =$valgroups->guid; $employees = true;} + if ( $valgroups ->name == 'finance') {$valgroupsFinance =$valgroups->guid; $finance = true;} + } + //Test unit + $groups= ws_assignUserToGroup ( $valuser1, $valgroups1 ); + $groups= ws_assignUserToGroup ( $valuser2, $valgroups2 ); + $groups= ws_assignUserToGroup ( $valuser3, $valgroups3 ); + $groups= ws_assignUserToGroup ( $valuser4, $valgroups4 ); + $groups= ws_assignUserToGroup ( $valuser5, $valgroups5 ); + $groups= ws_assignUserToGroup ( $valuser6, $valgroups6 ); + $groups= ws_assignUserToGroup ( $valuser7, $valgroups7 ); + + + + + // Expend report + $groups= ws_assignUserToGroup ( $valuser1, $valgroupsSupervisors); + $groups= ws_assignUserToGroup ( $valuser2, $valgroupsEmployees ); + $groups= ws_assignUserToGroup ( $valuser3, $valgroupsFinance ); + + $t->is( $foundUser1, true, 'user1 is present in Group One'); + $t->is( $foundUser2, true, 'user2 is present in Group Two'); + $t->is( $foundUser3, true, 'user3 is present in Group Three'); + $t->is( $foundUser3, true, 'user4 is present in Group Four'); + $t->is( $foundUser3, true, 'user5 is present in Group Five'); + $t->is( $foundUser3, true, 'user6 is present in Group Six'); + $t->is( $foundUser3, true, 'user7 is present in Group Seven'); + + $t->is( $foundUser1, true, 'user1 is present in Group supervisors'); + $t->is( $foundUser2, true, 'user2 is present in Group employees'); + $t->is( $foundUser3, true, 'user3 is present in Group finance'); + + \ No newline at end of file diff --git a/workflow/engine/test/unit/ws/reportsToTest.php b/workflow/engine/test/unit/ws/reportsToTest.php new file mode 100755 index 000000000..8de45408e --- /dev/null +++ b/workflow/engine/test/unit/ws/reportsToTest.php @@ -0,0 +1,260 @@ +. + * + * For more information, contact Colosa Inc, 2566 Le Jeune Rd., + * Coral Gables, FL, 33134, USA, or email info@colosa.com. + * + */ + //checking the processList + + //Archivos requeridos + if ( !defined ('PATH_THIRDPARTY') ) { + require_once( $_SERVER['PWD']. '/test/bootstrap/unit.php'); + } + require_once( PATH_THIRDPARTY . '/lime/lime.php'); + require_once( PATH_THIRDPARTY.'lime/yaml.class.php'); + include_once ( "wsConfig.php" ); + include_once ( "wsClient.php" ); + + $aGroups = file_get_values ( 'groups.txt' ); + $aFirstname = file_get_values ( 'firstname.txt' ); + $aLastname = file_get_values ( 'lastname.txt' ); + $aDepartments = file_get_departments ( 'departments.txt' ); + + $iGroups = count ( $aGroups ); + $iFirstname = count ( $aFirstname ); + $iLastname = count ( $aLastname ); + $iDepartments = count ( $aDepartments ); + + global $sessionId; + global $client; + global $roleOperator; + + $t = new lime_test( 570, new lime_output_color()); + $t = new lime_test( 7 + $iGroups*2 + $iFirstname*5 + $iDepartments*2, new lime_output_color()); + $t->diag('Reports To Test' ); + + + $t->is( function_exists('ws_open') , true, 'include wsClient.php' ); + + $t->diag('WS WSDL URL ' . WS_WSDL_URL ); + $t->diag('WS_USER_ID ' . WS_USER_ID ); + $t->diag('WS_USER_PASS ' . WS_USER_PASS ); + ws_open (); + + $t->isa_ok( $client , 'SoapClient', 'class SoapClient created'); + + //checking the groupList + $groups = ws_groupList() ; + $t->is( count ($groups->groups) >= 0 , true, 'ws_groupList works fine'); + + $groupId = array(); + foreach ( $aGroups as $key => $val ) { + $groupId[] = group_exists ( $t, $groups, $val ); + } + + //checking roles + $roles = ws_roleList() ; + $t->is( count ($roles->roles) >= 2 , true, 'ws_roleList works fine'); + + $roleOperator = ''; + foreach ( $roles->roles as $key => $val ) { + if ( $val->name == 'PROCESSMAKER_OPERATOR' ) + $roleOperator = $val->guid; + } + $t->is( strlen( $roleOperator ) >= 30 , true, 'role PROCESSMAKER_OPERATOR exists'); + if ( $roleOperator == '' ) + throw ( new Exception ( "role PROCESSMAKER_OPERATOR does not exist" ) ); + + //checking user list + $users = ws_userList(); + $t->is( count ($users->users) >= 1 , true, 'ws_userList works fine'); + + //create users + $userId = array(); + foreach ( $aFirstname as $key => $val ) { + $lastname = $aLastname [ rand( 0, $iLastname ) ]; + $userId[] = user_exists ( $t, $users, $val, $lastname,$roleOperator ); + } + + //assign groups + for ( $i = 0; $i < count( $userId ); $i++ ) { + $userUid = $userId [ $i ]; + $groupUid = $groupId [ rand( 0, count( $groupId )-1 ) ]; + assignUserToGroup ( $t, $userUid, $groupUid); + $groupUid = $groupId [ rand( 0, count( $groupId )-1 ) ]; + assignUserToGroup ( $t, $userUid, $groupUid); + } + + //checking the departmentList + $deps = ws_departmentList() ; + $t->is( count ($deps->departments) >= 0 , true, 'ws_departmentList works fine'); + + $depId = array(); + foreach ( $aDepartments as $key => $val ) { + $depId[] = department_exists ( $t, $val[0], $val[1] ); + } + + //assign departments + for ( $i = 0; $i < count( $userId ); $i++ ) { + $usrUid = $userId [ $i ]; + $depUid = $depId [ rand( 0, count( $depId )-1 ) ]; + assignUserToDepartment ( $t, $usrUid, $depUid, true ); + } + + function assignUserToGroup ( $t, $userId, $groupId ) { + $result = ws_assignUserToGroup ( $userId, $groupId ); + if ( $result->status_code == 8 ) { + $t->pass( "User $userId already exists in the group"); + return; + } + if ( $result->status_code != 0 ) { + throw ( new Exception ( $result->message ) ); + } + $t->pass( "assigned $userId to group $groupId"); + } + + function assignUserToDepartment ( $t, $userId, $depId, $manager ) { + $result = ws_assignUserToDepartment ( $userId, $depId, $manager ); +/* if ( $result->status_code == 8 ) { + $t->pass( "User $userId already exists in the group"); + return; + } +*/ + if ( $result->status_code != 0 ) { + throw ( new Exception ( $result->message ) ); + } + $t->pass( "assigned $userId to dep $depId"); + } + + //check if the group exists, if not, create it and returns the guid + function group_exists ( $t, $groups, $groupName ) { + $groupId = ''; + foreach ( $groups->groups as $key => $val ) { + if ( $val->name == $groupName ) $groupId = $val->guid ; + } + + //creates group + if ( $groupId == '' ) { + $result = ws_createGroup ( $groupName ); + if ( $result->status_code != 0 ) { + throw ( new Exception ( $result->message ) ); + } + $groupId = $result->groupUID; + $t->pass( "Group $groupName created successfully"); + } + else + $t->pass( 'Not necessary create the group ' . $groupName ); + + $t->pass ( "$groupName group exists with UID = $groupId"); + + return $groupId; + } + + //check if the department exists, if not, create it and returns the guid + function department_exists ( $t, $depName, $depParentName ) { + $deps = ws_departmentList() ; + $depId = ''; + foreach ( $deps->departments as $key => $val ) { + if ( $val->name == $depName ) $depId = $val->guid ; + } + + $depParentId = ''; + foreach ( $deps->departments as $key => $val ) { + if ( $val->name == $depParentName ) $depParentId = $val->guid ; + } + + //creates department + if ( $depId == '' ) { + $result = ws_createDepartment ( $depName, $depParentId ); + if ( $result->status_code != 0 ) { + throw ( new Exception ( $result->message ) ); + } + $depId = $result->departmentUID; + $t->pass( "Department $depName created successfully"); + } + else + $t->pass( "Not necessary create the Department $depName" ); + + $t->pass ( "$depName department exists with UID = $depId"); + + return $depId; + } + + //check if the user exists, if not, create it and returns the guid + function user_exists ( $t, $users, $firstname, $lastname, $roleOperator ) { + $userId = ''; + $username = strtolower ($firstname); + foreach ( $users->users as $key => $val ) { + if ( strtolower($val->name) == $username ) $userId = $val->guid ; + } + //creates user + if ( $userId == '' ) { + $firstname = ucwords( $firstname ); + $lasstname = ucwords( $lasstname ); + $email = $username . '@colosa.com'; + $password = 'sample'; + $result = ws_createUser ( $username, $firstname, $lastname, $email, $roleOperator, $password ); + if ( $result->status_code != 0 ) { + throw ( new Exception ( $result->message ) ); + } + $userId = $result->userUID; + $t->pass( "User $username created successfully"); + } + else + $t->pass( 'Not necessary create the user ' . $username ); + + $t->pass ( "$username exists with UID = $userId"); + + return $userId; + } + + function file_get_values ( $fileName ) { + $fName = PATH_CORE. 'test'.PATH_SEP.'fixtures'.PATH_SEP. $fileName; + $array = array(); + if ( !file_exists($fName) ) + throw (new Exception ( "file $fName doesn't exist." ) ); + + $fp = fopen ( $fName, 'r' ); + $i = 0; + while ( !feof( $fp ) ) { + $line = trim(fgets ( $fp )); + if ( /*$i++ < 10 && */ $line != '' ) $array[] = $line; + } + return $array; + } + + function file_get_departments ( $fileName ) { + $fName = PATH_CORE. 'test'.PATH_SEP.'fixtures'.PATH_SEP. $fileName; + $array = array(); + if ( !file_exists($fName) ) + throw (new Exception ( "file $fName doesn't exist." ) ); + + $fp = fopen ( $fName, 'r' ); + $i = 0; + while ( !feof( $fp ) ) { + $line = trim(fgets ( $fp ) ); + if ( /*$i++ < 10 &&*/ $line != '' ) { + $aux = explode('|', $line ); + $array[] = array ( trim($aux[0]) , trim($aux[1]) ); + } + } + return $array; + } diff --git a/workflow/engine/test/unit/ws/wsClient.php b/workflow/engine/test/unit/ws/wsClient.php new file mode 100644 index 000000000..274aa9f3c --- /dev/null +++ b/workflow/engine/test/unit/ws/wsClient.php @@ -0,0 +1,674 @@ +item) && ! is_array($array)) { + return null; + } + + $result = array (); + if (isset($array->item)) { + foreach ( $array->item as $key => $value ) { + $result[$value->key] = $value->value; + } + } else { + foreach ( $array as $key => $value ) { + $result[$value->key] = $value->value; + } + } + return $result; +} + +/** + * function convertFormToWSObjects + * @param $form + * Convert a normal POST form into the correspondent valid structure for webservice + * @return array of objects + */ +function convertFormToWSObjects($form) { + + foreach ( $form as $key => $val ) { + if (! is_array($val)) { //Normal Variables + $obj = new stdClass(); + $obj->name = $key; + $obj->value = $val; + $aVariables[] = $obj; + } else { + foreach ( $val as $gridKey => $gridRow ) { //Sp�cial Variables like grids or checkgroups + if (is_array($gridRow)) { //Grids + foreach ( $gridRow as $col => $colValue ) { + $obj = new stdClass(); + $obj->name = $key . "][" . $gridKey . "][" . $col; + $obj->value = $colValue; + $aVariables[] = $obj; + } + } else { //Checkgroups, Radiogroups + $obj = new stdClass(); + $obj->name = $key; + $obj->value = implode("|", $val); + $aVariables[] = $obj; + } + } + } + } + + return $aVariables; +} + +//this function is not necesary for version 2 of PM webservices +function convertSoapArrayToArray($object) { + $result = array (); + $properties = get_object_vars($object); + + foreach ( $properties as $keyProperties => $valProperties ) { + $array = array (); + foreach ( $valProperties as $keyItems => $valItems ) { + $node = array (); + if (isset($valItems->item)) { + foreach ( $valItems->item as $keyNode => $valNode ) { + $node[$valNode->key] = $valNode->value; + } + } + if (is_array($valItems)) { + foreach ( $valItems as $keyNode => $valNode ) { + $node[$valNode->key] = $valNode->value; + } + } + $array[] = $node; + } + $result[$keyProperties] = $array; + } + return $result; +} + +function ws_parser($result) { + $rows = array (); + if (isset($result->derivation)) + if (is_array($result->derivation->item)) { + foreach ( $result->derivation->item as $index => $val ) { + $rows[$val->key] = $val->value; + } + } else { + $rows[$result->derivation->item->key] = $result->derivation->item->value; + } + + return $rows; +} + +function ws_open() { + global $sessionId; + global $client; + $endpoint = WS_WSDL_URL; + $sessionId = ''; + @$client = new SoapClient($endpoint); + + $user = WS_USER_ID; + $pass = WS_USER_PASS; + + $params = array ( + 'userid' => $user, + 'password' => $pass + ); + $result = $client->__SoapCall('login', array ( + $params + )); + + if ($result->status_code == 0) { + $sessionId = $result->message; + return 1; + } + throw (new Exception($result->message)); +} + +function ws_open_with_params($endpoint, $user, $pass) { + global $sessionId; + global $client; + $sessionId = ''; + @$client = new SoapClient($endpoint); + + $params = array ( + 'userid' => $user, + 'password' => $pass + ); + $result = $client->__SoapCall('login', array ( + $params + )); + + if ($result->status_code == 0) { + $sessionId = $result->message; + return 1; + } + throw (new Exception($result->message)); +} + +function ws_sendEmailMessage($caseId, $toEmail, $sSubject, $ccEmail, $bccEmail, $sBody) { + global $sessionId; + global $client; + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'from' => 'soporte ', + 'to' => $toEmail, + 'cc' => $ccEmail, + 'bcc' => $bccEmail, + 'subject' => $sSubject, + 'message' => $sBody + ); + $result = $client->__SoapCall('sendMessage', array ( + $params + )); + return $result; +} + +function ws_sendMessage($caseId, $toEmail, $sSubject, $ccEmail, $bccEmail, $template) { + global $sessionId; + global $client; + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'from' => 'soporte ', + 'to' => $toEmail, + 'cc' => $ccEmail, + 'bcc' => $bccEmail, + 'subject' => $sSubject, + 'message' => $template + ); + $result = $client->__SoapCall('sendMessage', array ( + $params + )); + return $result; +} + +function ws_getVariables($caseId, $variables) { + global $sessionId; + global $client; + + $aVariables = array (); + foreach ( $variables as $key => $val ) { + $obj = new stdClass(); + $obj->name = $val; + $aVariables[] = $obj; + } + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'variables' => $aVariables + ); + $result = $client->__SoapCall('getVariables', array ( + $params + )); + return $result; +} + +function ws_newCase($proUid, $taskUid, $variables) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'processId' => $proUid, + 'taskId' => $taskUid, + 'variables' => $variables + ); + + $result = $client->__SoapCall('newCase', array ( + $params + )); + + return $result; +} + +function ws_sendVariables($caseId, $variables) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'variables' => $variables + ); + $result = $client->__SoapCall('sendVariables', array ( + $params + )); + + return $result; +} + +function ws_executeTrigger($caseId, $triggerId, $delIndex) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'triggerIndex' => $triggerId, + 'delIndex' => $delIndex + ); + $result = $client->__SoapCall('executeTrigger', array ( + $params + )); + return $result; +} + +//only for backward compatibility +function ws_derivateCase($caseId, $delId) { + global $sessionId; + global $client; + + $rows = array (); + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => $delId + ); + $result = $client->__SoapCall('derivateCase', array ( + $params + )); + $rows = ws_parser($result); + + $result->derivation = $rows; + //print_r($result); + return $result; +} + +function ws_routeCase($caseId, $delId) { + global $sessionId; + global $client; + + $rows = array (); + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => $delId + ); + $result = $client->__SoapCall('routeCase', array ( + $params + )); + return $result; +} + +function ws_processList() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('processList', array ( + $params + )); + //if ( $result->status_code == 0 ) { + return $result; + //} +//throw ( new Exception ( $result->message ) ); +} + +function ws_groupList() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('groupList', array ( + $params + )); + return $result; +} + +function ws_departmentList() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('departmentList', array ( + $params + )); + + if ( !is_array($result->departments) ) { + $res = new StdClass(); + $res->departments[0] = $result->departments; + return $res; + } + + return $result; +} + +function ws_roleList() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('roleList', array ( + $params + )); + return $result; +} + +function ws_caseList() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('caseList', array ( + $params + )); + return $result; +} + +function ws_userList() { + global $sessionId; + global $client; + + $users = array (); + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('userList', array ( + $params + )); + return $result; +} + +function ws_triggerList() { + global $sessionId; + global $client; + + $users = array (); + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('triggerList', array ( + $params + )); + return $result; +} + +function ws_getCaseInfo($caseId, $delIndex = NULL) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => $delIndex + ); + $result = $client->__SoapCall('getCaseInfo', array ( + $params + )); + return $result; +} + +function ws_reassignCase($caseId, $delIndex, $userIdSource, $userIdTarget) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId, + 'delIndex' => $delIndex, + 'userIdSource' => $userIdSource, + 'userIdTarget' => $userIdTarget + ); + $result = $client->__SoapCall('reassignCase', array ( + $params + )); + //if ( $result->status_code == 0 ) { + // return $result; + //} + return $result; + //throw ( new Exception ( $result->message ) ); +} + +function ws_taskCase($caseId) { + global $sessionId; + global $client; + + $params = array ( + 'caseId' => $caseId + ); + //$result = $client->__SoapCall( 'sessionId' => $sessionId, 'taskCase', array($params) ); + // $result = $client->__SoapCall( 'sessionId' => $sessionId, 'taskCase', array($params) ); + if ($result->status_code == 0) { + return $result; + } + throw (new Exception($result->message)); +} + +function ws_sendFile($FILENAME, $USR_UID, $APP_UID, $DEL_INDEX = 1, $DOC_UID = NULL, $title = NULL, $comment = NULL) { + + $DOC_UID = ($DOC_UID != NULL) ? $DOC_UID : - 1; + $APP_DOC_TYPE = ($DOC_UID == - 1) ? 'ATTACHED' : 'INPUT'; + $title = ($title != NULL) ? $title : $FILENAME; + $comment = ($comment != NULL) ? $comment : ''; + + $params = array ( + 'ATTACH_FILE' => "@$FILENAME", + 'APPLICATION' => $APP_UID, + 'INDEX' => $DEL_INDEX, + 'USR_UID' => $USR_UID, + 'DOC_UID' => $DOC_UID, + 'APP_DOC_TYPE' => $APP_DOC_TYPE, + 'TITLE' => $title, + 'COMMENT' => $comment + ); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, WS_UPLOAD_URL); + //curl_setopt($ch, CURLOPT_VERBOSE, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); + $response = curl_exec($ch); + curl_close($ch); + + return $response; +} + +function ws_updateFile($APP_DOC_UID, $FILENAME, $DOC_VERSION, $APP_DOC_TYPE=NULL, $USR_UID=NULL, $APP_UID=NULL, $DEL_INDEX=NULL, $DOC_UID=NULL, $title=NULL, $comment=NULL) { + + $params = array ( + 'APP_DOC_UID' => $APP_DOC_UID, + 'DOC_VERSION' => $DOC_VERSION, + 'ATTACH_FILE' => "@$FILENAME" + ); + + if( $APP_UID != NULL) + $params['APPLICATION'] = $APP_UID; + if( $DEL_INDEX != NULL) + $params['INDEX'] = $DEL_INDEX; + if( $USR_UID != NULL) + $params['USR_UID'] = $USR_UID; + if( $DOC_UID != NULL) + $params['DOC_UID'] = $DOC_UID; + if( $APP_DOC_TYPE != NULL) + $params['APP_DOC_TYPE'] = $APP_DOC_TYPE; + if( $title != NULL) + $params['TITLE'] = $title; + if( $comment != NULL) + $params['COMMENT'] = $comment; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, WS_UPLOAD_URL); + //curl_setopt($ch, CURLOPT_VERBOSE, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + $response = curl_exec($ch); + curl_close($ch); + + return $response; +} + +//create a new user +function ws_createUser($userId, $firstname, $lastname, $email, $role, $password) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'userId' => $userId, + 'firstname' => $firstname, + 'lastname' => $lastname, + 'email' => $email, + 'role' => $role, + 'password' => $password + ); + + $result = $client->__SoapCall('createUser', array ( + $params + )); + + return $result; +} + +//create a new group +function ws_createGroup( $groupName ) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'name' => $groupName + ); + $result = $client->__SoapCall('createGroup', array ( $params )); + return $result; +} + +//create a new group +function ws_createDepartment( $depName, $depParentId ) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'name' => $depName, + 'parentUID' => $depParentId + ); + $result = $client->__SoapCall('createDepartment', array ( $params )); + return $result; +} + +//assignUserToGroup +function ws_assignUserToGroup($userId, $groupId) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'userId' => $userId, + 'groupId' => $groupId + ); + + $result = $client->__SoapCall('assignUserToGroup', array ( + $params + )); + return $result; +} + +//assignUserToGroup +function ws_assignUserToDepartment($userId, $depId, $manager ) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'userId' => $userId, + 'departmentId' => $depId, + 'manager' => $manager + ); + + $result = $client->__SoapCall('assignUserToDepartment', array ( + $params + )); + return $result; +} + +function ws_systemInformation() { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId + ); + $result = $client->__SoapCall('systemInformation', array ( + $params + )); + return $result; +} + +function ws_importProcessFromLibrary($processId, $version = '', $importOption = '', $usernameLibrary = '', $passwordLibrary = '') { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'processId' => $processId, + 'version' => $version, + 'importOption' => $importOption, + 'usernameLibrary' => $usernameLibrary, + 'passwordLibrary' => $passwordLibrary + ); + $result = $client->__SoapCall('importProcessFromLibrary', array ( + $params + )); + return $result; +} + +function ws_InputDocumentList($caseId) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId + ); + + $result = $client->__SoapCall('InputDocumentList', array ( + $params + )); + + return $result; +} + +function ws_outputDocumentList($caseId) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'caseId' => $caseId + ); + + $result = $client->__SoapCall('outputDocumentList', array ( + $params + )); + + return $result; +} + +function ws_removeDocument($appDocUid) { + global $sessionId; + global $client; + + $params = array ( + 'sessionId' => $sessionId, + 'appDocUid' => $appDocUid + ); + + $result = $client->__SoapCall('RemoveDocument', array ( + $params + )); + + return $result; +} diff --git a/workflow/engine/test/unit/ws/wsConfig.php.example b/workflow/engine/test/unit/ws/wsConfig.php.example new file mode 100644 index 000000000..3f1e95973 --- /dev/null +++ b/workflow/engine/test/unit/ws/wsConfig.php.example @@ -0,0 +1,9 @@ + + + + + + + Name + + + + Description + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.html b/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.html new file mode 100644 index 000000000..ff510d49b --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.html @@ -0,0 +1,40 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.ADD_TAB_UID}
    * {$CSV_FILE}{$form.CSV_FILE}

    {$form.CSV_DELIMITER }
    {$form.btnSave}   {$form.BTN_CANCEL}
    +
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.xml b/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.xml new file mode 100644 index 000000000..e4d4c4627 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesDataImportForm.xml @@ -0,0 +1,31 @@ + + + + + <en>Import Data from CSV file</en> + + + + + + CSV File + + + + Delimited by + + + + Save + + + Cancel + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesEdit.html b/workflow/engine/xmlform/additionalTables/additionalTablesEdit.html new file mode 100644 index 000000000..77f50a2b4 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesEdit.html @@ -0,0 +1,69 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.ADD_TAB_UID}
    {$ADD_TAB_NAME}{$form.ADD_TAB_NAME}
    {$form.ADD_TAB_CLASS_NAME}
    {$ADD_TAB_DESCRIPTION}{$form.ADD_TAB_DESCRIPTION}
    {$form.TITLE2}

    {$form.ADD_TAB_SDW_LOG_INSERT}

    {$form.ADD_TAB_SDW_LOG_UPDATE}

    {$form.ADD_TAB_SDW_LOG_DELETE}

    {$form.ADD_TAB_SDW_AUTO_DELETE}
    {$form.TITLE3}
    {$form.FIELDS}
    {$form.btnSave}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesEdit.xml b/workflow/engine/xmlform/additionalTables/additionalTablesEdit.xml new file mode 100644 index 000000000..b1c639d27 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesEdit.xml @@ -0,0 +1,426 @@ + + + + + Table Information + + + + + + Table Name + + + + PHP Class Name + + + + Description + + + + Log Configuration + + + + Save log for insert actions + + + + Save log for update actions + + + + Save log for delete actions + + + + + + Delete related log when table is deleted + + + + + + Fields + + + + + + Save + + + + Cancel + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesExportList.xml b/workflow/engine/xmlform/additionalTables/additionalTablesExportList.xml new file mode 100755 index 000000000..1b22e5da4 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesExportList.xml @@ -0,0 +1,32 @@ + + + + + + + + + Name + + + + Description + + + + + + + + + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesFields.xml b/workflow/engine/xmlform/additionalTables/additionalTablesFields.xml new file mode 100644 index 000000000..4f814b5a6 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesFields.xml @@ -0,0 +1,32 @@ + + + + + + + Field Name + + + + Field Label + + + + Type + + + + Size + + + + Null + + + + + + Primary Key + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesFields2.xml b/workflow/engine/xmlform/additionalTables/additionalTablesFields2.xml new file mode 100644 index 000000000..cd20eea96 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesFields2.xml @@ -0,0 +1,36 @@ + + + + + + + Field Name + + + + Field Label + + + + Type + + + + Size + + + + Null + + + + + + Primary Key + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesList.xml b/workflow/engine/xmlform/additionalTables/additionalTablesList.xml new file mode 100644 index 000000000..aea67eaa6 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesList.xml @@ -0,0 +1,20 @@ + + + + + + + Name + + + + Description + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesNew.html b/workflow/engine/xmlform/additionalTables/additionalTablesNew.html new file mode 100644 index 000000000..6ec73c80e --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesNew.html @@ -0,0 +1,74 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.ADD_TAB_UID}
    * {$ADD_TAB_NAME}{$form.ADD_TAB_NAME}
    {$form.ADD_TAB_NAME_OLD}
    {$form.ADD_TAB_CLASS_NAME}
    {$form.ADD_TAB_CLASS_NAME_OLD}
    {$ADD_TAB_DESCRIPTION}{$form.ADD_TAB_DESCRIPTION}
    {$form.TITLE2}

    {$form.ADD_TAB_SDW_LOG_INSERT}

    {$form.ADD_TAB_SDW_LOG_UPDATE}

    {$form.ADD_TAB_SDW_LOG_DELETE}

    {$form.ADD_TAB_SDW_AUTO_DELETE}
    {$form.TITLE3}
    {$form.FIELDS}
    {$form.btnSave}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesNew.xml b/workflow/engine/xmlform/additionalTables/additionalTablesNew.xml new file mode 100644 index 000000000..a7cdb7521 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesNew.xml @@ -0,0 +1,475 @@ + + + + + Table Information + + + + + + Table Name + + + + + + PHP Class Name + + + + + + Description + + + + Log configuration + + + + Save log for insert actions + + + + Save log for update actions + + + + Save log for delete actions + + + + + + Delete related log when table is deleted + + + + + + Fields + + + + + + Save + + + + Cancel + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesOptions.xml b/workflow/engine/xmlform/additionalTables/additionalTablesOptions.xml new file mode 100644 index 000000000..cc77bbd49 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesOptions.xml @@ -0,0 +1,119 @@ + + + + + New + + + Import + + + Export + + + + + 1){ + alert(G_STRINGS.ID_CLASS_TABLE_DOESNT_EXIST);return false; + //new leimnud.module.app.alert().make({label: '@G::LoadTranslation(ID_CLASS_TABLE_DOESNT_EXIST)' + answer }); + //return 0; + } + + + exportPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'additionalTablesAjax', + args : 'action=doExport&tables='+checks_selected_ids+'&schema='+checks_selected_schema+"&data="+checks_selected_data + }); + exportPanel.clearContent(); + exportPanel.loader.show(); + oRPC.callback = function(rpc) { + exportPanel.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + exportPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + resetChecks(); + oRPC.make(); +} + +function in_arrayx(a, e){ + for(j=0; j + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesTitle.xml b/workflow/engine/xmlform/additionalTables/additionalTablesTitle.xml new file mode 100644 index 000000000..6a42da9e2 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesTitle.xml @@ -0,0 +1,8 @@ + + + + + +<en>@#ADD_TAB_NAME</en> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesToImport.html b/workflow/engine/xmlform/additionalTables/additionalTablesToImport.html new file mode 100644 index 000000000..1ce8bc3a4 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesToImport.html @@ -0,0 +1,40 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$MAX_FILE_SIZE}{$form.MAX_FILE_SIZE}
    {$FILENAME}{$form.FILENAME}

    {$form.OVERWRITE}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/additionalTablesToImport.xml b/workflow/engine/xmlform/additionalTables/additionalTablesToImport.xml new file mode 100755 index 000000000..45b471d3f --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/additionalTablesToImport.xml @@ -0,0 +1,44 @@ + + + + + Import PMTables + + + + Max upload file size in bytes + + + + File + + + + Overwrite if exists + + + + Import + + + + Cancel + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/additionalTables/doExport.xml b/workflow/engine/xmlform/additionalTables/doExport.xml new file mode 100755 index 000000000..e8d711c71 --- /dev/null +++ b/workflow/engine/xmlform/additionalTables/doExport.xml @@ -0,0 +1,19 @@ + + + + + <en>Processmaker Tables export</en> + + + + + + File + + + File size + + + Sumary + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolder.xml b/workflow/engine/xmlform/appFolder/appFolder.xml new file mode 100644 index 000000000..4bf0cea67 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolder.xml @@ -0,0 +1,32 @@ + + + + + AppFolder form + + + + Er Uid + + + + Er Parent Uid + + + + Er Name + + + + Er Create Date + + + + Er Update Date + + + + save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDelete.xml b/workflow/engine/xmlform/appFolder/appFolderDelete.xml new file mode 100644 index 000000000..373385e31 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDelete.xml @@ -0,0 +1,21 @@ + + + + + Delete AppFolder + + + + + Er Uid + + + + + + + + delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocsListOptions.xml b/workflow/engine/xmlform/appFolder/appFolderDocsListOptions.xml new file mode 100755 index 000000000..47f19b0ad --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocsListOptions.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + +@#labelFolderAddFolder + + +@#labelFolderAddFile + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocsListSearchOptions.xml b/workflow/engine/xmlform/appFolder/appFolderDocsListSearchOptions.xml new file mode 100755 index 000000000..0fb057603 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocsListSearchOptions.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocumentInfo.xml b/workflow/engine/xmlform/appFolder/appFolderDocumentInfo.xml new file mode 100755 index 000000000..fe2360295 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocumentInfo.xml @@ -0,0 +1,27 @@ + + + + + Process + + + Case Title + + + File Name + + + Version + + + Type + + + + Creator + + + Created + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocumentList.xml b/workflow/engine/xmlform/appFolder/appFolderDocumentList.xml new file mode 100755 index 000000000..2270948e7 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocumentList.xml @@ -0,0 +1,61 @@ + + + + + Process + + + Case Title + + + File Name + + + Version + + + Type + + + + Creator + + + Created + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocumentListHeader.xml b/workflow/engine/xmlform/appFolder/appFolderDocumentListHeader.xml new file mode 100755 index 000000000..cc9e00ea6 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocumentListHeader.xml @@ -0,0 +1,18 @@ + + + + + + SELECT FOLDER_UID, FOLDER_NAME FROM APP_FOLDER + Move selected to: + + + + + + + + Move + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocumentListHistory.xml b/workflow/engine/xmlform/appFolder/appFolderDocumentListHistory.xml new file mode 100755 index 000000000..675fed50b --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocumentListHistory.xml @@ -0,0 +1,43 @@ + + + + + Process + + + Case Title + + + File Name + + + Version + + + Type + + + + Creator + + + Created + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderDocumentListSearch.xml b/workflow/engine/xmlform/appFolder/appFolderDocumentListSearch.xml new file mode 100755 index 000000000..87c916598 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderDocumentListSearch.xml @@ -0,0 +1,54 @@ + + + + + Process + + + Case Title + + + File Name + + + Version + + + Type + + + + Creator + + + Created + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderEdit.html b/workflow/engine/xmlform/appFolder/appFolderEdit.html new file mode 100644 index 000000000..94b39cf80 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderEdit.html @@ -0,0 +1,45 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title1}
    {$FOLDER_PATH}{$form.FOLDER_PATH}
    {$form.FOLDER_UID}
    {$form.FOLDER_PARENT_UID}
    {$FOLDER_NAME}{$form.FOLDER_NAME}

    {$form.BTN_SUBMIT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderEdit.xml b/workflow/engine/xmlform/appFolder/appFolderEdit.xml new file mode 100644 index 000000000..3213fe049 --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderEdit.xml @@ -0,0 +1,43 @@ + + + + + New Folder + + + + + Path + + + + folder Uid + + + + + Parent Parent Uid + + + + + Folder Name + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderList.xml b/workflow/engine/xmlform/appFolder/appFolderList.xml new file mode 100644 index 000000000..92848802f --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderList.xml @@ -0,0 +1,25 @@ + + + + + Er Parent Uid + + + + Er Create Date + + + + Er Update Date + + + + + Edit + + + + Delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/appFolder/appFolderOptions.xml b/workflow/engine/xmlform/appFolder/appFolderOptions.xml new file mode 100644 index 000000000..baeb572dd --- /dev/null +++ b/workflow/engine/xmlform/appFolder/appFolderOptions.xml @@ -0,0 +1,8 @@ + + + + + + New + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_List.xml b/workflow/engine/xmlform/authSources/authSources_List.xml new file mode 100644 index 000000000..2849c19db --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_List.xml @@ -0,0 +1,28 @@ + + + + + + + Name + + + + Provider + + + + Server Name + + + + Port + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_Options.xml b/workflow/engine/xmlform/authSources/authSources_Options.xml new file mode 100644 index 000000000..a50fe9c29 --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_Options.xml @@ -0,0 +1,23 @@ + + + + + New + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_SearchUsers.html b/workflow/engine/xmlform/authSources/authSources_SearchUsers.html new file mode 100644 index 000000000..454f14e24 --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_SearchUsers.html @@ -0,0 +1,39 @@ +
    +
    +
    + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.AUTH_SOURCE_UID}
    {$KEYWORD}{$form.KEYWORD}
    {$form.btnSearch}   {$form.BTN_CANCEL}
    +
    + +
    {$form.btnImport}
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_SearchUsers.xml b/workflow/engine/xmlform/authSources/authSources_SearchUsers.xml new file mode 100644 index 000000000..83e9ed4a5 --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_SearchUsers.xml @@ -0,0 +1,82 @@ + + + + + <en>Search for user</en> + + + + + + Keyword + + + + Search + + + + Import + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_SelectType.html b/workflow/engine/xmlform/authSources/authSources_SelectType.html new file mode 100644 index 000000000..71640021a --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_SelectType.html @@ -0,0 +1,32 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + +
    {$form.TITLE}
    * {$AUTH_SOURCE_PROVIDER}{$form.AUTH_SOURCE_PROVIDER}
    {$form.btnContinue}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/authSources_SelectType.xml b/workflow/engine/xmlform/authSources/authSources_SelectType.xml new file mode 100644 index 000000000..bbe8f96f5 --- /dev/null +++ b/workflow/engine/xmlform/authSources/authSources_SelectType.xml @@ -0,0 +1,31 @@ + + + + + <en>Available Authentication Source Types</en> + + + +SELECT sType, sLabel FROM authSourceTypes + Provider + + + + Continue + + + + Cancel + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/ldapEdit.html b/workflow/engine/xmlform/authSources/ldapEdit.html new file mode 100644 index 000000000..cf495bd39 --- /dev/null +++ b/workflow/engine/xmlform/authSources/ldapEdit.html @@ -0,0 +1,103 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.AUTH_SOURCE_UID}
    * {$AUTH_SOURCE_NAME}{$form.AUTH_SOURCE_NAME}
    {$form.AUTH_SOURCE_PROVIDER}
    {$LDAP_TYPE}{$form.LDAP_TYPE}
    * {$AUTH_SOURCE_SERVER_NAME}{$form.AUTH_SOURCE_SERVER_NAME}
    * {$AUTH_SOURCE_PORT}{$form.AUTH_SOURCE_PORT}
    {$AUTH_SOURCE_ENABLED_TLS}{$form.AUTH_SOURCE_ENABLED_TLS}
    {$AUTH_SOURCE_VERSION}{$form.AUTH_SOURCE_VERSION}
    * {$AUTH_SOURCE_BASE_DN}{$form.AUTH_SOURCE_BASE_DN}
    {$AUTH_ANONYMOUS}{$form.AUTH_ANONYMOUS}
    {$AUTH_SOURCE_SEARCH_USER}{$form.AUTH_SOURCE_SEARCH_USER}
    {$AUTH_SOURCE_PASSWORD}{$form.AUTH_SOURCE_PASSWORD}
    * {$AUTH_SOURCE_IDENTIFIER_FOR_USER}{$form.AUTH_SOURCE_IDENTIFIER_FOR_USER}
    * {$AUTH_SOURCE_OBJECT_CLASSES}{$form.AUTH_SOURCE_OBJECT_CLASSES}
    {$AUTH_SOURCE_ADDITIONAL_FILTER}{$form.AUTH_SOURCE_ADDITIONAL_FILTER}
    * {$AUTH_SOURCE_ATTRIBUTES}{$form.AUTH_SOURCE_ATTRIBUTES}
    {$form.btnSave}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/ldapEdit.xml b/workflow/engine/xmlform/authSources/ldapEdit.xml new file mode 100644 index 000000000..1551a4850 --- /dev/null +++ b/workflow/engine/xmlform/authSources/ldapEdit.xml @@ -0,0 +1,116 @@ + + + + + <en>Authentication Source Information</en> + + + + + + Name + + + + + + Type + + + + Server Name + + + + Port + + + + Enabled TLS + + + + Version + + + + Base DN + + + + Anonymous + + + + Search User + + + + Password + + + + Identifier for a imported user + + + + Object Classes + + + + Additional Filter + + + + Attributes + + + + Save + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/authSources/ldapSearchResults.xml b/workflow/engine/xmlform/authSources/ldapSearchResults.xml new file mode 100644 index 000000000..16ae35614 --- /dev/null +++ b/workflow/engine/xmlform/authSources/ldapSearchResults.xml @@ -0,0 +1,20 @@ + + + + + [SELECT-ALL]]]> + + + + Name + + + + E-Mail + + + + Distinguished Name + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/casesDemo.xml b/workflow/engine/xmlform/cases/casesDemo.xml new file mode 100644 index 000000000..544c6f443 --- /dev/null +++ b/workflow/engine/xmlform/cases/casesDemo.xml @@ -0,0 +1,19 @@ + + + + # + + + + name + + + + Task + + + + balance + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AllDynaformsList.xml b/workflow/engine/xmlform/cases/cases_AllDynaformsList.xml new file mode 100644 index 000000000..540d2f258 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AllDynaformsList.xml @@ -0,0 +1,13 @@ + + + + + + + Title + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AllInputdocsList.xml b/workflow/engine/xmlform/cases/cases_AllInputdocsList.xml new file mode 100644 index 000000000..ab00b7e36 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AllInputdocsList.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + <en>Filename</en> + + + + Comments + + + + Type + + + + Version + + + + Origin Task + + + + Created By + + + + Create Date + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AllOutputdocsList.xml b/workflow/engine/xmlform/cases/cases_AllOutputdocsList.xml new file mode 100644 index 000000000..a8771c5ed --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AllOutputdocsList.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + <en>Title</en> +<es><![CDATA[Título]]></es><pt><![CDATA[Título]]></pt> + + + Output Document +Documento GeneradoDocumento Generado + + + Origin Task +Tarefa Origem + + + Created By +Creado por + + + Create Date + + + + + +Download + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocument1.xml b/workflow/engine/xmlform/cases/cases_AttachInputDocument1.xml new file mode 100644 index 000000000..8cf4fd2de --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocument1.xml @@ -0,0 +1,73 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options" colWidth="200px"> + + + + + + + Attach Input document + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + + + + File + + + + Comments + + + + Upload Multiple Input Documents + + + + Save + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocument2.xml b/workflow/engine/xmlform/cases/cases_AttachInputDocument2.xml new file mode 100644 index 000000000..924bd9f7d --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocument2.xml @@ -0,0 +1,69 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + + + New Input document + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + + + + Comments + + + + Upload Multiple Input Documents + + + + Save + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocument3.xml b/workflow/engine/xmlform/cases/cases_AttachInputDocument3.xml new file mode 100644 index 000000000..08ef34c93 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocument3.xml @@ -0,0 +1,80 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + + + Attach Input document + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + + + + File + + + + Comments + + + + Upload Multiple Input Documents + + + + Save + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.html b/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.html new file mode 100644 index 000000000..89fa31ce7 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.html @@ -0,0 +1,53 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.APP_DOC_TYPE}
    {$form.DOC_UID}
    {$form.APP_DOC_UID}
    {$form.actionType}
    {$form.docVersion}
    {$APP_DOC_FILENAME}{$form.APP_DOC_FILENAME}
    {$APP_DOC_COMMENT}{$form.APP_DOC_COMMENT}
    {$form.MORE}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.xml b/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.xml new file mode 100755 index 000000000..e7585a88f --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocumentGeneral.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + File + + + + Comments + + + + Upload Multiple Input Documents + + + + Cancel + + + + Save + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_AttachInputDocumentInfo.xml b/workflow/engine/xmlform/cases/cases_AttachInputDocumentInfo.xml new file mode 100755 index 000000000..dd8de511e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_AttachInputDocumentInfo.xml @@ -0,0 +1,14 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options" colWidth='200px'> + + + + diff --git a/workflow/engine/xmlform/cases/cases_CannotInitiateCase.xml b/workflow/engine/xmlform/cases/cases_CannotInitiateCase.xml new file mode 100644 index 000000000..df56a3b1d --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_CannotInitiateCase.xml @@ -0,0 +1,12 @@ + + + + + <en>Start a new case</en> + + + + You cannot initiate a new case. + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_CatchSelfService.html b/workflow/engine/xmlform/cases/cases_CatchSelfService.html new file mode 100644 index 000000000..7b4f7da70 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_CatchSelfService.html @@ -0,0 +1,76 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$PRO_TITLE}{$form.PRO_TITLE}
    {$STATUS}{$form.STATUS}
    {$TITLE}{$form.TITLE}
    {$APP_NUMBER}{$form.APP_NUMBER}
    {$APP_UID}{$form.APP_UID}
    {$TAS_TITLE}{$form.TAS_TITLE}
    {$DEL_DELEGATE_DATE}{$form.DEL_DELEGATE_DATE}
    {$DEL_TASK_DUE_DATE}{$form.DEL_TASK_DUE_DATE}
    {$PREVIOUS_TASK}{$form.PREVIOUS_TASK}
    {$PREVIOUS_USER}{$form.PREVIOUS_USER}
    {$form.BTN_CATCH} {$form.BTN_CANCEL}
    +
    +
    +
    +
    +
    + + diff --git a/workflow/engine/xmlform/cases/cases_CatchSelfService.xml b/workflow/engine/xmlform/cases/cases_CatchSelfService.xml new file mode 100644 index 000000000..6803e2b20 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_CatchSelfService.xml @@ -0,0 +1,63 @@ + + + + + Claim Case + + + + Process + + + + Case Status + + + + <en>Case Title</en> + + + + Case Number + + + + Case Uid + + + + Task + + + + Task Delegate Date + + + + Task Due Date + + + + + Previous Task + + + + Previous User + + + + Claim this case + + + + Cancel + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_DynaformHistory.xml b/workflow/engine/xmlform/cases/cases_DynaformHistory.xml new file mode 100644 index 000000000..587f5027e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_DynaformHistory.xml @@ -0,0 +1,19 @@ + + + + Dynaform + + + Dynaform + + + Update Date + + + User + + + Fields + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_InputdocsList.xml b/workflow/engine/xmlform/cases/cases_InputdocsList.xml new file mode 100644 index 000000000..e2579567e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_InputdocsList.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + <en>Title</en> + + + + Version + + + + Creator + + + + Comment + + + + Created Date + + + + + + + + + + + + +Eliminar + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_InputdocsListHistory.xml b/workflow/engine/xmlform/cases/cases_InputdocsListHistory.xml new file mode 100644 index 000000000..91ef8095e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_InputdocsListHistory.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + <en>Title</en> + + + + Version + + + + Creator + + + + + Created Date + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_InputdocsListOptions.xml b/workflow/engine/xmlform/cases/cases_InputdocsListOptions.xml new file mode 100755 index 000000000..1959f8552 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_InputdocsListOptions.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_InputdocsListToRevise.xml b/workflow/engine/xmlform/cases/cases_InputdocsListToRevise.xml new file mode 100644 index 000000000..c3746e8b1 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_InputdocsListToRevise.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + <en>Type</en> +<es>Tipo</es> + + + Type +Tipo + + + Create Date +Crear Fecha + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_List.xml b/workflow/engine/xmlform/cases/cases_List.xml new file mode 100644 index 000000000..bd5fe818f --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_List.xml @@ -0,0 +1,58 @@ + + + + + + + + # +## + + Case +CasoCaso + + Task +TareaTarefa + + Process +ProcesoProcesso + + Sent by +Enviado porEnviado por + + Due Date +Fecha de vencimientoData-limite + + Last Modify + + + + Finish Date +Fecha finalData-limite + + + Start Date +Fechas inicial del casoData Inicial + + + + + + + + +Eliminar + + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListAll.xml b/workflow/engine/xmlform/cases/cases_ListAll.xml new file mode 100755 index 000000000..bbee2f841 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListAll.xml @@ -0,0 +1,72 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Current User +Usuario Actual + + + Sent by +Enviado porEnviado por + + + Due Date +Fecha de vencimientoData-limite + + + Last Modify + + + + Start Date +Fechas inicial del casoData Inicial + + + Finish Date +Fecha finalData Final + + + + Status +EstadoEstado + + + + + + + + + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListAllDelete.xml b/workflow/engine/xmlform/cases/cases_ListAllDelete.xml new file mode 100644 index 000000000..5a470bcb5 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListAllDelete.xml @@ -0,0 +1,73 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Current User +Usuario Actual + + + Sent by +Enviado porEnviado por + + + Due Date +Fecha de vencimientoData-limite + + + Last Modify + + + + Start Date +Fechas inicial del casoData Inicial + + + Finish Date +Fecha finalData Final + + + + Status +EstadoEstado + + + + + + + + +Eliminar + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListAll_Reassign.xml b/workflow/engine/xmlform/cases/cases_ListAll_Reassign.xml new file mode 100644 index 000000000..b336f81ad --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListAll_Reassign.xml @@ -0,0 +1,79 @@ + + + + + + + + + + # +# + + + Case +Caso + + + Task +Tarea + + + Process +Proceso + + + Current User +Usuario actual + + + Sent by +Enviado por + + + Due Date + + + + Last Modify + + + + Start Date +Fecha inicial + + + Finish Date +Finalizar fecha + + + + Status +Estado + + + + + + + + + + + + + + + + + Apply Filter +Aplicar filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListCancelled.xml b/workflow/engine/xmlform/cases/cases_ListCancelled.xml new file mode 100755 index 000000000..4581bd3b3 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListCancelled.xml @@ -0,0 +1,71 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Sent by +Enviado porEnviado por + + + Due Date +Fecha de vencimientoData-limite + + + Last Modify + + + + Start Date +Fechas inicial del casoData Inicial + + + Finish Date +Fecha finalData Final + + + + + + + + + + + + + + + +reactivateCase + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListCompleted.xml b/workflow/engine/xmlform/cases/cases_ListCompleted.xml new file mode 100755 index 000000000..c040e79d9 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListCompleted.xml @@ -0,0 +1,87 @@ + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + + + Completed by user + + + + Due Date + + + + Last Modify + + + + Start Date + + + + Finish Date + + + + + + + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + diff --git a/workflow/engine/xmlform/cases/cases_ListDraft.xml b/workflow/engine/xmlform/cases/cases_ListDraft.xml new file mode 100755 index 000000000..330ca6754 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListDraft.xml @@ -0,0 +1,61 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Due Date +Fecha de vencimientoData-limite + + + Last Modify + + + + Start Date +Fechas inicial del casoData Inicial + + + + + + + + + + + + +Eliminar + + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListOnHold.xml b/workflow/engine/xmlform/cases/cases_ListOnHold.xml new file mode 100755 index 000000000..9e1df587b --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListOnHold.xml @@ -0,0 +1,74 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Sent by +Enviado porEnviado por + + + Last Modify +Last Modification + + + + Due Date +Fecha de vencimientoData-limite + + + + + + Start Date +Fechas inicial del casoData Inicial + + + Finish Date +Fecha finalData Final + + + + + + + + + + + + + + +reactivateCase + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListSelfService.xml b/workflow/engine/xmlform/cases/cases_ListSelfService.xml new file mode 100755 index 000000000..77f39fff4 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListSelfService.xml @@ -0,0 +1,87 @@ + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + + + Completed by user + + + + Due Date + + + + Last Modify + + + + Start Date + + + + Finish Date + + + + + + + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + diff --git a/workflow/engine/xmlform/cases/cases_ListSent.xml b/workflow/engine/xmlform/cases/cases_ListSent.xml new file mode 100755 index 000000000..4146abea6 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListSent.xml @@ -0,0 +1,73 @@ + + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + Current User + + + + Sent by + + + + Due Date + + + + Last Modify + + + + Start Date + + + + Finish Date + + + + + Status + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListStarted.xml b/workflow/engine/xmlform/cases/cases_ListStarted.xml new file mode 100644 index 000000000..7f72d53eb --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListStarted.xml @@ -0,0 +1,73 @@ + + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + Current User + + + + Sent by + + + + Due Date + + + + Last Modify + + + + Start Date + + + + Finish Date + + + + + Status + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListToRevise.xml b/workflow/engine/xmlform/cases/cases_ListToRevise.xml new file mode 100644 index 000000000..47ed7c93d --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListToRevise.xml @@ -0,0 +1,94 @@ + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + Current User + + + + Sent by + + + + Due Date + + + + Last Modify + + + + Priority + + + + + + + + + + Start Date + + + + Status + + + + + + + + + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + diff --git a/workflow/engine/xmlform/cases/cases_ListTodo.xml b/workflow/engine/xmlform/cases/cases_ListTodo.xml new file mode 100755 index 000000000..3a6ac7280 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListTodo.xml @@ -0,0 +1,63 @@ + + + + + + + + + # + + + + Case + + + + Task + + + + Process + + + + Sent by + + + + Due Date + + + + Last Modify + + + + Priority + + + + Start Date + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ListTodoNew.xml b/workflow/engine/xmlform/cases/cases_ListTodoNew.xml new file mode 100755 index 000000000..88fc7fdb3 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ListTodoNew.xml @@ -0,0 +1,68 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarea + + + Process +ProcesoProcesso + + + Sent by +Enviado porEnviado por + + + Due Date +Fecha de vencimientoData-limite + + + Last Modify + + + + Priority +PrioridadPrioridade + + + Start Date +Fecha inicial del casoData Inicial + + + + + + + + + + + + + + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Messages.xml b/workflow/engine/xmlform/cases/cases_Messages.xml new file mode 100644 index 000000000..a6a623746 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Messages.xml @@ -0,0 +1,34 @@ + + + + + + + + Type + + + + Date + + + + Subject + + + + From + + + + To + + + + Status + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_MessagesView.xml b/workflow/engine/xmlform/cases/cases_MessagesView.xml new file mode 100644 index 000000000..fce19fe92 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_MessagesView.xml @@ -0,0 +1,27 @@ + + + + + <en>MESSAGE</en> + + + + SUBJECT + + + + FROM + + + + TO + + + + DATE + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_New.html b/workflow/engine/xmlform/cases/cases_New.html new file mode 100755 index 000000000..5b0ccd015 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_New.html @@ -0,0 +1,39 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}{$form.DESCRIPTION}
     
    {$TAS_UID}{$form.TAS_UID}{$form.START}
     
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/cases/cases_New.xml b/workflow/engine/xmlform/cases/cases_New.xml new file mode 100644 index 000000000..b133a5a2e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_New.xml @@ -0,0 +1,22 @@ + + + + + + + <en>Start a new case</en> + + + + + + + + SELECT * FROM NewCase + Process + + + + Start + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_NewRadioGroup.html b/workflow/engine/xmlform/cases/cases_NewRadioGroup.html new file mode 100755 index 000000000..b24673952 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_NewRadioGroup.html @@ -0,0 +1,32 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + +
    {$form.TITLE}{$form.DESCRIPTION}
    {$TAS_UID}
    {$form.TAS_UID}
    {$form.START}
    +
    +
    +
    +
    +
    + + diff --git a/workflow/engine/xmlform/cases/cases_NewRadioGroup.xml b/workflow/engine/xmlform/cases/cases_NewRadioGroup.xml new file mode 100644 index 000000000..e6e1d477c --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_NewRadioGroup.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + <en>Start a new case</en> + + + + + + + + SELECT * FROM NewCase + + + + + Start + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Options.xml b/workflow/engine/xmlform/cases/cases_Options.xml new file mode 100644 index 000000000..72f72388a --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Options.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + select PRO_UID, APP_PRO_TITLE from _PROCESSES + Process + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_OptionsSent.xml b/workflow/engine/xmlform/cases/cases_OptionsSent.xml new file mode 100755 index 000000000..a4130a514 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_OptionsSent.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + select PRO_UID, APP_PRO_TITLE from _PROCESSES + Process + + + + + + Status + + + + + + + + + Started by me + + + + Read + + + + Unread + + + + All + + + + + + + + + + + + -1 ){ + var strQueryString = strHref.substr(strHref.indexOf("&")).toLowerCase(); + var aQueryString = strQueryString.split("&"); + for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){ + if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){ + var aParam = aQueryString[iParam].split("="); + strReturn = aParam[1]; + break; + } + } + } + return strReturn; +} + +function casesDelete(app) { + ajax_function('cases_Delete','','APP_UID='+encodeURIComponent(app)); + @#PAGED_TABLE_ID.refresh(); +} + +var cancelCase = function(sUID, iIndex) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_CANCEL_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=cancelCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var pauseCase = function(sUID, iIndex) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_PAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=pauseCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var reactivateCase = function(sUID, iIndex) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_REACTIVATE_CASES, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=reactivateCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var unpauseCase = function(sUID, iIndex) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_UNPAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=unpauseCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +getField("PAGED_TABLE_JUMP").onkeypress = function(event) { + event = window.event ? window.event : event; + if (event.keyCode===13) Jump(); +}; + +function Jump(){ + window.location.href='@#cases_Open?APP_NUMBER='+encodeURIComponent(getField('PAGED_TABLE_JUMP').value)+"&content=inner"; +} + +// Additional filter -- By Erik +leimnud.event.add(getField('PROCESS_FILTER'), 'change', function() { + loc = new String(window.location); + tmp = (loc.indexOf('&') != -1 )? loc.indexOf('&'): loc.length; + uri = loc.substring(0, tmp); + location.href = uri + '&PROCESS_UID='+this.value+'&APP_STATUS_FILTER='+getField('APP_STATUS_FILTER').value+'&r='+Math.floor(Math.random()*999999); +}.extend(getField('PROCESS_FILTER'))); + +leimnud.event.add(getField('APP_STATUS_FILTER'), 'change', function() { + loc = new String(window.location); + tmp = (loc.indexOf('&') != -1 )? loc.indexOf('&'): loc.length; + uri = loc.substring(0, tmp); + location.href = uri + '&PROCESS_UID='+getField('PROCESS_FILTER').value+'&APP_STATUS_FILTER='+this.value+'&r='+Math.floor(Math.random()*999999); +}.extend(getField('APP_STATUS_FILTER'))); + +function selectionHighlight(filter) { + + switch (filter.toUpperCase()) { + case 'MINE' : getField("MINE").style.fontWeight = 'bold'; + getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'normal'; + break; + case 'READ' : getField("MINE").style.fontWeight = 'normal'; + getField("READ_FILTER").style.fontWeight = 'bold'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'normal'; + break; + case 'UNREAD': getField("MINE").style.fontWeight = 'normal'; + getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'bold'; + getField("ALL_FILTER").style.fontWeight = 'normal'; + break; + case 'ALL' : getField("MINE").style.fontWeight = 'normal'; + getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'bold'; + break; + } + +} + +function applyAdditionalFilter(filter){ + selectionHighlight(filter); + loc = new String(window.location); + tmp = (loc.indexOf('&') != -1 )? loc.indexOf('&'): loc.length; + uri = loc.substring(0, tmp); + + location.href = uri + '&APP_STATUS_FILTER='+getField('APP_STATUS_FILTER').value + '&PROCESS_UID='+getField('PROCESS_FILTER').value + '&' + filter + '=1'+'&r='+Math.floor(Math.random()*999999) + '&filterTit=' + filter; +} + +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_OptionsToDo.xml b/workflow/engine/xmlform/cases/cases_OptionsToDo.xml new file mode 100755 index 000000000..77447e0da --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_OptionsToDo.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + select PRO_UID, APP_PRO_TITLE from _PROCESSES + Process + + + + + + Read + + + + Unread + + + + All + + + + + + + + + + + + + + -1 ){ + var strQueryString = strHref.substr(strHref.indexOf("&")).toLowerCase(); + var aQueryString = strQueryString.split("&"); + for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){ + if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){ + var aParam = aQueryString[iParam].split("="); + strReturn = aParam[1]; + break; + } + } + } + return strReturn; +} + +function casesDelete(app) { + ajax_function('cases_Delete','','APP_UID='+encodeURIComponent(app)); + @#PAGED_TABLE_ID.refresh(); +} + +var cancelCase = function(sUID, iIndex) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_CANCEL_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=cancelCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var pauseCase = function(sUID, iIndex) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_PAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=pauseCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var reactivateCase = function(sUID, iIndex) { + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_MSG_CONFIRM_REACTIVATE_CASES, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=reactivateCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +var unpauseCase = function(sUID, iIndex) +{ + new leimnud.module.app.confirm().make({ + label : G_STRINGS.ID_CONFIRM_UNPAUSE_CASE, + action: function() { + var oRPC = new leimnud.module.rpc.xmlhttp({ + url: 'cases_Ajax', + args: 'action=unpauseCase&sApplicationUID=' + sUID + '&iIndex=' + iIndex + }); + oRPC.callback = function(oRPC) { + @#PAGED_TABLE_ID.refresh(); + }.extend(this); + oRPC.make(); + }.extend(this) + }); +}; + +getField("PAGED_TABLE_JUMP").onkeypress = function(event) { + event = window.event ? window.event : event; + if (event.keyCode===13) Jump(); +}; + +function Jump(){ + window.location.href='@#cases_Open?APP_NUMBER='+encodeURIComponent(getField('PAGED_TABLE_JUMP').value)+"&content=inner"; +} + +// Additional filter -- By Erik +leimnud.event.add(getField('PROCESS_FILTER'), 'change', function() { + loc = new String(window.location); + tmp = (loc.indexOf('&') != -1 )? loc.indexOf('&'): loc.length; + uri = loc.substring(0, tmp); + + if(uri.indexOf('?l=to_do')==-1) uri=uri+'?l=to_do'; + + document.location.href = uri + '&PROCESS_UID='+this.value+'&r='+Math.floor(Math.random()*999999); +}.extend(getField('PROCESS_FILTER'))); + +function selectionHighlight(filter) { + switch (param.toUpperCase()) { + case 'READ' : getField("READ_FILTER").style.fontWeight = 'bold'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'normal'; + break; + case 'UNREAD': getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'bold'; + getField("ALL_FILTER").style.fontWeight = 'normal'; + break; + case 'ALL' : getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'bold'; + break; + default : getField("READ_FILTER").style.fontWeight = 'normal'; + getField("UNREAD_FILTER").style.fontWeight = 'normal'; + getField("ALL_FILTER").style.fontWeight = 'bold'; + break; + } +} + +function applyAdditionalFilter(filter){ + selectionHighlight(filter); + loc = new String(window.location); + tmp = (loc.indexOf('&') != -1 )? loc.indexOf('&'): loc.length; + uri = loc.substring(0, tmp); + + location.href = uri + '&PROCESS_UID='+getField('PROCESS_FILTER').value + '&' + filter + '=1'+'&r='+Math.floor(Math.random()*999999) + '&filter=' + filter; +} + +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_OutputdocsListToRevise.xml b/workflow/engine/xmlform/cases/cases_OutputdocsListToRevise.xml new file mode 100644 index 000000000..c5752a273 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_OutputdocsListToRevise.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + <en>Title</en> + + + + Create Date + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ProcessInformation.xml b/workflow/engine/xmlform/cases/cases_ProcessInformation.xml new file mode 100644 index 000000000..9267a2145 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ProcessInformation.xml @@ -0,0 +1,21 @@ + + + + + + + Title + + + + Description + + + + Author + + + + Create Date + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Reassign.xml b/workflow/engine/xmlform/cases/cases_Reassign.xml new file mode 100644 index 000000000..1488e73dc --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Reassign.xml @@ -0,0 +1,26 @@ + + + + + <en>Finish Reassigned</en> + + + + Case # + + + + Reassigned to + + + + BACK + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ReassignBy.html b/workflow/engine/xmlform/cases/cases_ReassignBy.html new file mode 100755 index 000000000..536cd4a21 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ReassignBy.html @@ -0,0 +1,34 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + +
    {$form.title}
    {$REASSIGN_BY}{$form.REASSIGN_BY}
    {$form.REASSIGN_USER}
    +
    +
    +
    +
    + +
    + + + + diff --git a/workflow/engine/xmlform/cases/cases_ReassignBy.xml b/workflow/engine/xmlform/cases/cases_ReassignBy.xml new file mode 100644 index 000000000..066baeff0 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ReassignBy.xml @@ -0,0 +1,76 @@ + + + + + <en><![CDATA[<center>Reassignment of Cases</center>]]></en> + + + + Reassign By + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ReassignShowInfo.xml b/workflow/engine/xmlform/cases/cases_ReassignShowInfo.xml new file mode 100644 index 000000000..b7564c4e6 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ReassignShowInfo.xml @@ -0,0 +1,19 @@ + + + + <en><![CDATA[<center>Reassigned Cases Resume</center>]]></en> + + + + + + BACK + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ReassignUsers.xml b/workflow/engine/xmlform/cases/cases_ReassignUsers.xml new file mode 100644 index 000000000..2e82b71f4 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ReassignUsers.xml @@ -0,0 +1,7 @@ + + + 'CLOSED' + ]]>User + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Resume.xml b/workflow/engine/xmlform/cases/cases_Resume.xml new file mode 100644 index 000000000..df1fc06e5 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Resume.xml @@ -0,0 +1,81 @@ + + + + + Case Properties + + + + Process + + + + Case Status + + + + <en>Case Title</en> + + + + Case Number + + + + Case Uid + + + + Creator + + + + Create Date + + + + Last Update + + + + Current Task Properties + + + + Task + + + + Current User + + + + Task Delegate Date + + + + Task Init Date + + + + Task Due Date + + + + Finish Date + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_Edit.html b/workflow/engine/xmlform/cases/cases_Scheduler_Edit.html new file mode 100644 index 000000000..1abfd454e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_Edit.html @@ -0,0 +1,251 @@ +
    +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.GENERAL_INF}
    {$form.PROPERTIES_INF}
    {$form.SCH_UID}
    {$form.SCH_ADVANCED}
    {$form.SCH_USER_UID}
    {$form.PREV_SCH_END_DATE}
    {$form.PREV_SCH_START_DATE}
    {$form.PREV_SCH_START_TIME}
    {$form.PRO_UID_TMP}
    * {$SCH_USER_NAME}{$form.SCH_USER_NAME}
    * {$SCH_USER_PASSWORD}{$form.SCH_USER_PASSWORD}
    {$form.TEST_CONNECTION}
    {$form.EDIT_USER}
    + {$form.PERFORM_TASK} +
    * {$TAS_UID}
    {$form.TAS_UID}
    * {$SCH_NAME}{$form.SCH_NAME}
    * {$SCH_OPTION_VIEW}{$form.SCH_OPTION} {$form.SCH_OPTION_VIEW}
    + {$form.SELECT_TIME_DAY} +
    * {$SCH_START_DATE} {$form.SCH_START_DATE} + + + + + +
    {$SCH_END_DATE} End Date{$form.SCH_END_DATE}
    +
    * {$SCH_START_TIME} {$form.SCH_START_TIME}
    + {$form.SELECT_DATE} +
    + {$form.SELECT_1} +
    + {$form.SELECT_2} +
    {$form.SCH_EVERY_DAYS}
    {$SCH_WEEK_DAYS} + + + + + +
    {$form.SCH_WEEK_DAYS} {$form.SCH_WEEK_DAYS_2} {$SCH_WEEK_DAYS_2}
    + +
    + {$form.SELECT_3} +
    {$SCH_START_DAY} + + + + + +
    {$form.SCH_START_DAY} {$SCH_START_DAY_OPT_1} {$form.SCH_START_DAY_OPT_1}
    + {$SCH_START_DAY_OPT_2_WEEKS} {$SCH_START_DAY_OPT_2_DAYS_WEEK} + {$form.SCH_START_DAY_OPT_2_WEEKS} {$form.SCH_START_DAY_OPT_2_DAYS_WEEK} +
    +
    {$SCH_MONTHS} + + + + + + +
    {$form.SCH_MONTHS} {$form.SCH_MONTHS_2} {$SCH_MONTHS_2} {$form.SCH_MONTHS_3} {$SCH_MONTHS_3}
    +
    {$form.SCH_REPEAT_TASK_CHK}
    + {$form.SELECT_PLUGIN} +
    +
    {$form.CASE_SH_PLUGIN_UID}
    +
    +
    {$form.UPDATE}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    +
    + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_Edit.xml b/workflow/engine/xmlform/cases/cases_Scheduler_Edit.xml new file mode 100644 index 000000000..ca6163572 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_Edit.xml @@ -0,0 +1,836 @@ + + + + + + + +General Information + + +Please insert a valid processmaker user name and password. + + + + + + + + + + + + + + + + + + + + +User Name + + +Password + + + + Test User + + + Edit User + + + +Properties + + + + +Description + + + +Process + + + +Task + + + + + + + Perform this task + + + +Select the time and day you want this task to start. + + + +Execution time + + + +Select date + + + +Start date + + + + Daily + + + + + + + + Weekly + + + +Every + + + +Select the day(s) of the week below + + + + + + + + + + + + + + + Monthly + + + +Day + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Of the month(s) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Advanced Options + + + +End Date + + + +Repeat Task + + +Every + + + + + + + + + + + + + + +Start a case based on following registered Plugin. + + + + + + + +Update + + +=1 && days<=365)){ + msgBox('Days must be between 1 and 365', 'alert'); // confirm, info + getField('SCH_DAYS_PERFORM_TASK_OPT_3').value = '1'; + } +}); + +leimnud.event.add(getField('SCH_EVERY_DAYS'), 'change', function() { + weeks = getField('SCH_EVERY_DAYS').value; + if(!(weeks>=1 && weeks<=52) ) { + msgBox('Weeks must be between 1 and 52', 'alert'); + getField('SCH_EVERY_DAYS').value = ''; + } +}); + +leimnud.event.add(getField('SCH_START_DAY_OPT_1'), 'change', function() { + days = getField('SCH_START_DAY_OPT_1').value; + if(!(days>=1 && days<=31) ) { + msgBox('The days must be between 1 and 31', 'alert'); + getField('SCH_START_DAY_OPT_1').value = '1'; + } +}); + + + +// for advanced + +leimnud.event.add(getField('SCH_END_DATE_CHK'), 'click', function() { + if(getField('SCH_END_DATE_CHK').checked){ + enable(getField('SCH_END_DATE')); + } + else { + document.getElementById('form[SCH_END_DATE]').value = ''; + document.getElementById('form[SCH_END_DATE][div]').innerHTML = ''; + disable(getField('SCH_END_DATE')); + } + +}); + +leimnud.event.add(getField('SCH_REPEAT_TASK_CHK'), 'click', function() { + if(getField('SCH_REPEAT_TASK_CHK').checked){ + enable(getField('SCH_REPEAT_EVERY')); + enable(getField('SCH_REPEAT_EVERY_OPT')); + // enable(getField('SCH_REPEAT_UNTIL')); + // enable(getField('SCH_REPEAT_STOP_IF_RUNNING')); + } else { + disable(getField('SCH_REPEAT_EVERY')); + disable(getField('SCH_REPEAT_EVERY_OPT')); + // disable(getField('SCH_REPEAT_UNTIL')); + // disable(getField('SCH_REPEAT_STOP_IF_RUNNING')); + } + +}); + + +leimnud.event.add(getField('SCH_START_TIME'), 'change', function() { + hours = getField('SCH_START_TIME').value; + answer = hours; + var parties = answer.split(':'); + + if(parties[0]>23){ + msgBox('The time can not be increased to 23:59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } + if(parties[1]>59){ + msgBox('The mininutos can not be greater than about 59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } +}); + + + +leimnud.event.add(getField('SCH_REPEAT_UNTIL'), 'change', function() { + hours = getField('SCH_REPEAT_UNTIL').value; + answer = hours; + var parties = answer.split(':'); + + if(parties[0]>23){ + msgBox('The time can not be increased to 23:59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } + if(parties[1]>59){ + msgBox('The mininutos can not be greater than about 59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } +}); +/* + * @function case_userSchedulerValidate + * @author gustavo cruz gustavo[at]colsoa[dot]com + * @desc This function makes an Ajax call in order to validate if a user is registered in the system. + * @return void + */ +function case_userSchedulerValidate(username, password) { + //G.alert(username); + //G.alert(password); + var user_uid; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerValidateUser', + async : true, + method: 'POST', + args : "USERNAME="+username+"&PASSWORD="+password + }); + + oRPC.callback = function(rpc){ + //msgBox(rpc.xmlhttp.responseText,"alert"); + getField('SCH_USER_UID').value = rpc.xmlhttp.responseText; + user_uid = rpc.xmlhttp.responseText; + //alert(user_uid); + + var oRPCProcess = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerGetProcesses', + async : true, + method: 'POST', + args : "USR_UID="+user_uid + }); + + oRPCProcess.callback = function(rpc){ + document.getElementById("processListDropdown").innerHTML = rpc.xmlhttp.responseText; + if (getField('PRO_UID')!=null){ + var process_uid = getField('PRO_UID').value; + loadTasksDropdown(process_uid,user_uid); + document.getElementById('form[UPDATE]').disabled=false; + showProperties(); + } else { + msgBox("The User login data seems to be invalid.","alert"); + } + }.extend(this); + + oRPCProcess.make(); + + /* if(rpc.xmlhttp.responseText>=1){ + //getField('SEARCH').disabled = false; + msgBox("User successfully logged","alert"); + getField('SCH_USR_UID').value = rpc.xmlhttp.responseText; + } else { + //getField('SEARCH').disabled = true; + msgBox(rpc.xmlhttp.responseText,"alert"); + } + */ + }.extend(this); + oRPC.make(); + + +} + +function resetForm(){ +document.getElementById('form[UPDATE]').disabled=true; +document.getElementById('form[SCH_USER_NAME]').readOnly=false; +document.getElementById('form[SCH_USER_PASSWORD]').readOnly=false; +document.getElementById('form[SCH_USER_PASSWORD]').value=''; +document.getElementById('form[TEST_CONNECTION]').style.display=''; +document.getElementById('form[EDIT_USER]').style.display='none'; +//hideAll(); +//hideProperties(); +} +/** + * @desc Load Tasks Dropdown + * @author gustavo cruz gustavo[at]colosa[dot]com + * @desc This function loads the Task Dropdown filtered by process. + * @return void + */ +function loadTasksDropdown(process,user_uid){ + //alert(process); + var oRPCTasks = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerGetTasks', + async : true, + method: 'POST', + args : "USR_UID="+user_uid+"&PRO_UID="+process + }); + + oRPCTasks.callback = function(rpc){ + document.getElementById("taskListDropdown").innerHTML = rpc.xmlhttp.responseText; + }.extend(this); + oRPCTasks.make(); +} +/* + * @function collapseAdvancedOption + * @author gustavo cruz gustavo[at]colsoa[dot]com + * @desc This function collapses the Advanced Options Fields. + * @return void + */ + +function collapseAdvancedOptions(){ + var flag = document.getElementById('EditLogAdvancedOptions').innerHTML; + if (flag=='visible'){ + //contractSubtitle('ADVANCED_4'); + document.getElementById('EditLogAdvancedOptions').innerHTML = 'hidden'; + document.getElementById('checkAdvanced').checked = false; + document.getElementById('form[SCH_END_DATE_CHK]').checked = false; + document.getElementById('form[SCH_END_DATE]').value = ''; + document.getElementById('form[SCH_END_DATE][div]').innerHTML = ''; + document.getElementById('form[SCH_REPEAT_TASK_CHK]').checked = false; + + + } else { + //expandSubtitle('ADVANCED_4'); + document.getElementById('checkAdvanced').checked = true; + document.getElementById('EditLogAdvancedOptions').innerHTML = 'visible'; + } +} + +/** + * @function validateSchedulerFields + * @author gustavo cruz gustavo[at]colsoa[dot]com + * @desc This function validates the special cases for the scheduler data fields. + * @return true/false boolean + */ + +function validateSchedulerFields(){ + +var validFields = true; +var requiredFields = ''; +var badFormatFields = ''; +var startDate = document.getElementById('form[SCH_START_DATE]').value; +var endDate = document.getElementById('form[SCH_END_DATE]').value; + +startDate = startDate.split("-"); +endDate = endDate.split("-"); +startDate = new Date(startDate[0],startDate[1],startDate[2]); +endDate = new Date(endDate[0],endDate[1],endDate[2]); + + if (document.getElementById('form[SCH_START_DATE]').value==''){ + requiredFields = requiredFields + 'Start Date,'; + validFields = false; + } else { + if (document.getElementById('form[SCH_END_DATE]').value!='') + if (startDate>endDate){ + badFormatFields = badFormatFields + 'Start Date can\'t be greater than End Date'; + validFields = false; + } + } + + if (document.getElementById('form[SCH_START_TIME]').value==''){ + requiredFields = requiredFields + 'Start Time,'; + validFields = false; + } + // check if the field time is compliant with the regular expression + // for time format hh:mm + var regExpString = "([0-1]\\d|2[0-3]):([0-5]\\d)"; + var timeRegexp = new RegExp(regExpString); + if (!timeRegexp.test(document.getElementById('form[SCH_START_TIME]').value)){ + msgBox('The time format is invalid','alert'); + return false; + } + switch(document.getElementById('form[SCH_OPTION]').value){ + // daily + case '1': + +// if(document.getElementById('form[SCH_DAYS_PERFORM_TASK][1]').checked==true||document.getElementById('form[SCH_DAYS_PERFORM_TASK][2]').checked==true||document.getElementById('form[SCH_DAYS_PERFORM_TASK][3]').checked==true){ + if(document.getElementById('form[SCH_DAYS_PERFORM_TASK]').value!=''){ + validFields = true; + } else { + requiredFields = requiredFields + 'Weekdays,'; + validFields = false; + } + + break; + // weekly + case '2': + if (document.getElementById('form[SCH_EVERY_DAYS]').value==''){ + requiredFields = requiredFields + 'Number of Weeks,'; + validFields = false; + } else { + for (week=1;week<=4;week++){ + weekIdOne = 'form[SCH_WEEK_DAYS]['+week+']'; + if (document.getElementById(weekIdOne).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + if (!validFields){ + for (week=1;week<=3;week++){ + weekIdTwo = 'form[SCH_WEEK_DAYS_2]['+(week+4)+']'; + if (document.getElementById(weekIdTwo).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + } + if (!validFields){ + requiredFields = requiredFields + 'Weeks,'; + validFields = false; + } + } + break; + //monthly + case '3': + if (document.getElementById('form[SCH_START_DAY][1]').checked==true||document.getElementById('form[SCH_START_DAY][2]').checked==true){ + for (month=1;month<=4;month++){ + monthIdOne = 'form[SCH_MONTHS]['+month+']'; + monthIdTwo = 'form[SCH_MONTHS_2]['+(month+4)+']'; + monthIdThree = 'form[SCH_MONTHS_3]['+(month+8)+']'; + + if (document.getElementById(monthIdOne).checked==true||document.getElementById(monthIdTwo).checked==true||document.getElementById(monthIdThree).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + if (!validFields){ + requiredFields = requiredFields + 'Months,'; + validFields = false; + } + } else { + requiredFields = requiredFields + 'Start Day,'; + validFields = false; + } + + + break; + //run once + case '4': + + validFields = true; + + break; + default: + validFields = false; + break; + } + if (requiredFields!='') { + var message = "The fields "+requiredFields+" can\'t be empty"; + msgBox(message, 'alert'); + return false; + } else { + if (badFormatFields!=''){ + var message = badFormatFields; + msgBox(message, 'alert'); + return false; + } else { + return true; + } + } +} + +]]> + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_List.xml b/workflow/engine/xmlform/cases/cases_Scheduler_List.xml new file mode 100755 index 000000000..6d800bd40 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_List.xml @@ -0,0 +1,37 @@ + + + + + + Name + + + + Process + + + + Task + + + + Time next run + + + Last run time + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_Log.xml b/workflow/engine/xmlform/cases/cases_Scheduler_Log.xml new file mode 100644 index 000000000..26ec4a638 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_Log.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + Date + + + + Time + + + + User + + Result + + + + Created Case Status + + + + Routed Case Status + + + + View + + + diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_Log_Detail.xml b/workflow/engine/xmlform/cases/cases_Scheduler_Log_Detail.xml new file mode 100644 index 000000000..0a19c74c8 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_Log_Detail.xml @@ -0,0 +1,42 @@ + + + + + Scheduled Task ID + + + Task ID + + + Process Id + + + + + User + + + + Execution Date + + + + Execution Hour + + + + Execution Status + + + + Created Case Status + + + + Routed Case Status + + + + Back to List + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_New.html b/workflow/engine/xmlform/cases/cases_Scheduler_New.html new file mode 100644 index 000000000..1f87267d5 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_New.html @@ -0,0 +1,236 @@ +
    +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.menuUser}
    {$form.GENERAL_INF}
    {$form.PROPERTIES_INF}
    {$form.SCH_UID}
    {$form.SCH_USER_UID}
    {$form.PHP_CURRENT_DATE}
    * {$SCH_USER_NAME}{$form.SCH_USER_NAME}
    * {$SCH_USER_PASSWORD}{$form.SCH_USER_PASSWORD}
    {$form.TEST_CONNECTION}
    {$form.EDIT_USER}
    + {$form.PERFORM_TASK} +
    {$PRO_UID}
    {$form.PRO_UID}
    * {$TAS_UID}
    {$form.TAS_UID}
    * {$SCH_NAME}{$form.SCH_NAME}
    * {$SCH_OPTION}{$form.SCH_OPTION}
    + {$form.SELECT_TIME_DAY} +
    * {$SCH_START_DATE}{$form.SCH_START_DATE} + + + + + +
    {$SCH_END_DATE} End Date{$form.SCH_END_DATE}
    +
    * {$SCH_START_TIME}{$form.SCH_START_TIME}
    + {$form.SELECT_DATE} +
    + {$form.SELECT_1} +
    + {$form.SELECT_2} +
    {$form.SCH_EVERY_DAYS}
    {$SCH_WEEK_DAYS} + + + + + +
    {$form.SCH_WEEK_DAYS} {$form.SCH_WEEK_DAYS_2} {$SCH_WEEK_DAYS_2}
    + +
    + {$form.SELECT_3} +
    {$SCH_START_DAY} + + + + + +
    {$form.SCH_START_DAY} {$SCH_START_DAY_OPT_1} {$form.SCH_START_DAY_OPT_1}
    + {$SCH_START_DAY_OPT_2_WEEKS} {$SCH_START_DAY_OPT_2_DAYS_WEEK} + {$form.SCH_START_DAY_OPT_2_WEEKS} {$form.SCH_START_DAY_OPT_2_DAYS_WEEK} +
    +
    {$SCH_MONTHS} + + + + + + +
    {$form.SCH_MONTHS} {$form.SCH_MONTHS_2} {$SCH_MONTHS_2} {$form.SCH_MONTHS_3} {$SCH_MONTHS_3}
    +
    {$form.SCH_REPEAT_TASK_CHK}
    + {$form.SELECT_PLUGIN} +
    +
    {$form.PRO_UID}
    +
    {$form.PRO_UID}
    +
    {$form.SAVE}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    +
    + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_New.xml b/workflow/engine/xmlform/cases/cases_Scheduler_New.xml new file mode 100644 index 000000000..1b3589d1b --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_New.xml @@ -0,0 +1,735 @@ + + + + + + + +General Information + + + +Please insert a valid processmaker user name and password, in order to assign the case to their respective owner + + + + + + + + + + + +User Name + + +Password + + + + Test User + + + Edit User + + + +Properties + + + + + + +Task + + + +Description + + + +Perform this task + + + + + + + + + +Select the time and day you want this task to start. + + + +Execution time + + + +Select date + + + +Start date + + + + Daily + + + + + + + Weekly + + + +Every + + +Select the day(s) of the week below + + + + + + + + + + + + + + + + Monthly + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Of the month(s) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Repeat Task + + +Every + + + + + + + + + + + + + + +Start a case based on following registered Plugin. + + + +Save + + +=1 && days<=365)){ + msgBox('Days must be between 1 and 365', 'alert'); // confirm, info + getField('SCH_DAYS_PERFORM_TASK_OPT_3').value = '1'; + } +}); + +leimnud.event.add(getField('SCH_EVERY_DAYS'), 'change', function() { + days = getField('SCH_EVERY_DAYS').value; + if(!(days>=1 && days<=52) ) { + msgBox('Weeks must be between 1 and 52', 'alert'); + getField('SCH_EVERY_DAYS').value = ''; + } +}); + +leimnud.event.add(getField('SCH_START_DAY_OPT_1'), 'change', function() { + days = getField('SCH_START_DAY_OPT_1').value; + if(!(days>=1 && days<=31) ) { + msgBox('The days must be between 1 and 31', 'alert'); + getField('SCH_START_DAY_OPT_1').value = '1'; + } +}); + +leimnud.event.add(getField('SCH_START_TIME'), 'change', function() { + hours = getField('SCH_START_TIME').value; + answer = hours; + var parties = answer.split(':'); + + if(parties[0]>23){ + msgBox('The time can not be increased to 23:59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } + if(parties[1]>59){ + msgBox('The minutes can not be greater than 59', 'alert'); + getField('SCH_REPEAT_UNTIL').value=''; + getField('SCH_REPEAT_UNTIL').focus(); + } +}); + + +/* +leimnud.event.add(getField('SCH_OPTION][1'), 'change', function() { + showSelection('1'); +}); +leimnud.event.add(getField('SCH_OPTION][2'), 'change', function() { + showSelection('2'); +}); +leimnud.event.add(getField('SCH_OPTION][3'), 'change', function() { + showSelection('3'); +}); +leimnud.event.add(getField('SCH_OPTION][4'), 'change', function() { + showSelection('4'); +}); +*/ + +function case_userSchedulerValidate(username, password) { + //G.alert(username); + //G.alert(password); + var user_uid; + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerValidateUser', + async : true, + method: 'POST', + args : "USERNAME="+username+"&PASSWORD="+password + }); + + oRPC.callback = function(rpc){ + //msgBox(rpc.xmlhttp.responseText,"alert"); + getField('SCH_USER_UID').value = rpc.xmlhttp.responseText; + user_uid = rpc.xmlhttp.responseText; + //alert(user_uid); + + var oRPCProcess = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerGetProcesses', + async : true, + method: 'POST', + args : "USR_UID="+user_uid+"&PRO_UID="+$_GET('PRO_UID') + }); + + oRPCProcess.callback = function(rpc){ + document.getElementById("processListDropdown").innerHTML = rpc.xmlhttp.responseText; + if (getField('PRO_UID')!=null){ + var process_uid = getField('PRO_UID').value; + } else { + var process_uid = gup('PRO_UID'); + } + loadTasksDropdown(process_uid,user_uid); + + }.extend(this); + + oRPCProcess.make(); + + + }.extend(this); + oRPC.make(); + + +} +/* + * @function validateSchedulerFields + * @author gustavo cruz gustavo[at]colsoa[dot]com + * @desc This function validates the special cases for the scheduler data fields. + * @return true/false boolean + */ + +function validateSchedulerFields(){ +var validFields = true; +var requiredFields = ''; +var badFormatFields = ''; +var startDate = document.getElementById('form[SCH_START_DATE]').value; +var endDate = document.getElementById('form[SCH_END_DATE]').value; + +startDate = startDate.split("-"); +endDate = endDate.split("-"); +startDate = new Date(startDate[0],startDate[1],startDate[2]); +endDate = new Date(endDate[0],endDate[1],endDate[2]); + + if (document.getElementById('form[SCH_START_DATE]').value==''){ + requiredFields = requiredFields + 'Start Date,'; + validFields = false; + } else { + if (document.getElementById('form[SCH_END_DATE]').value!='') + if (startDate>endDate){ + badFormatFields = badFormatFields + 'Start Date can\'t be greater than End Date'; + validFields = false; + } + } + // check if the field time is compliant with the regular expression + // for time format hh:mm + var regExpString = "([0-1]\\d|2[0-3]):([0-5]\\d)"; + var timeRegexp = new RegExp(regExpString); + if (!timeRegexp.test(document.getElementById('form[SCH_START_TIME]').value)){ + msgBox('The time format is invalid','alert'); + return false; + } + if (document.getElementById('form[SCH_START_TIME]').value==''){ + requiredFields = requiredFields + 'Execution Time,'; + validFields = false; + } + switch(document.getElementById('form[SCH_OPTION]').value){ + // daily + case '1': + //if(document.getElementById('form[SCH_DAYS_PERFORM_TASK][1]').checked==true||document.getElementById('form[SCH_DAYS_PERFORM_TASK][2]').checked==true||document.getElementById('form[SCH_DAYS_PERFORM_TASK][3]').checked==true){ + if(document.getElementById('form[SCH_DAYS_PERFORM_TASK]').value!=''){ + validFields = true; + } else { + requiredFields = requiredFields + 'Weekdays,'; + validFields = false; + } + + break; + // weekly + case '2': + if (document.getElementById('form[SCH_EVERY_DAYS]').value==''){ + requiredFields = requiredFields + 'Number of Weeks,'; + validFields = false; + } else { + for (week=1;week<=4;week++){ + weekIdOne = 'form[SCH_WEEK_DAYS]['+week+']'; + if (document.getElementById(weekIdOne).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + if (!validFields){ + for (week=1;week<=3;week++){ + weekIdTwo = 'form[SCH_WEEK_DAYS_2]['+(week+4)+']'; + if (document.getElementById(weekIdTwo).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + } + if (!validFields){ + requiredFields = requiredFields + 'Weeks,'; + validFields = false; + } + } + break; + //monthly + case '3': + if (document.getElementById('form[SCH_START_DAY][1]').checked==true||document.getElementById('form[SCH_START_DAY][2]').checked==true){ + for (month=1;month<=4;month++){ + monthIdOne = 'form[SCH_MONTHS]['+month+']'; + monthIdTwo = 'form[SCH_MONTHS_2]['+(month+4)+']'; + monthIdThree = 'form[SCH_MONTHS_3]['+(month+8)+']'; + + if (document.getElementById(monthIdOne).checked==true||document.getElementById(monthIdTwo).checked==true||document.getElementById(monthIdThree).checked==true){ + validFields = true; + break; + } else { + validFields = false; + } + } + if (!validFields){ + requiredFields = requiredFields + 'Months,'; + validFields = false; + } + } else { + requiredFields = requiredFields + 'Start Day,'; + validFields = false; + } + + + break; + //run once + case '4': + + validFields = true; + + break; + default: + validFields = false; + break; + } + if (requiredFields!='') { + var message = "The fields "+requiredFields+" can\'t be empty"; + msgBox(message, 'alert'); + return false; + } else { + if (badFormatFields!=''){ + var message = badFormatFields; + msgBox(message, 'alert'); + return false; + } else { + return true; + } + } +} + +function resetForm(){ +document.getElementById('form[SCH_USER_NAME]').readOnly=false; +document.getElementById('form[SCH_USER_PASSWORD]').readOnly=false; +document.getElementById('form[TEST_CONNECTION]').style.display=''; +hideAll(); +hideProperties(); +} + +function loadTasksDropdown(process,user_uid){ + //alert(process); + var oRPCTasks = new leimnud.module.rpc.xmlhttp({ + url : '../cases/cases_SchedulerGetTasks', + async : true, + method: 'POST', + args : "USR_UID="+user_uid+"&PRO_UID="+process + }); + + oRPCTasks.callback = function(rpc){ + document.getElementById("taskListDropdown").innerHTML = rpc.xmlhttp.responseText; + // if the user is assigned to the task the default task value will be diferent than char + if (getField('TAS_UID').value!='char'){ + showProperties(); + } else { + msgBox("The User login data seems to be invalid.","alert"); + } + }.extend(this); + oRPCTasks.make(); +} +leimnud.event.add(getField('SCH_REPEAT_TASK_CHK'), 'click', function() { + if(getField('SCH_REPEAT_TASK_CHK').checked){ + enable(getField('SCH_REPEAT_EVERY')); + enable(getField('SCH_REPEAT_EVERY_OPT')); + // enable(getField('SCH_REPEAT_UNTIL')); + // enable(getField('SCH_REPEAT_STOP_IF_RUNNING')); + } else { + disable(getField('SCH_REPEAT_EVERY')); + disable(getField('SCH_REPEAT_EVERY_OPT')); + // disable(getField('SCH_REPEAT_UNTIL')); + // disable(getField('SCH_REPEAT_STOP_IF_RUNNING')); + } + +}); + + +function collapseAdvancedOptions(){ + var flag = document.getElementById('EditLogAdvancedOptions').innerHTML; + if (flag=='visible'){ + //contractSubtitle('ADVANCED_4'); + document.getElementById('EditLogAdvancedOptions').innerHTML = 'hidden'; + document.getElementById('checkAdvanced').checked = false; + + //document.getElementById('form[SCH_END_DATE]').value = ''; + document.getElementById('form[SCH_END_DATE][div]').innerHTML = ''; + document.getElementById('form[SCH_REPEAT_TASK_CHK]').checked = false; + + + } else { + //expandSubtitle('ADVANCED_4'); + document.getElementById('checkAdvanced').checked = true; + document.getElementById('EditLogAdvancedOptions').innerHTML = 'visible'; + } +} + +function gup( name ) +{ + name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + var regexS = "[\\?&]"+name+"=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( window.location.href ); + if( results == null ) + return ""; + else + return results[1]; +} + +]]> + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_NewOptions.xml b/workflow/engine/xmlform/cases/cases_Scheduler_NewOptions.xml new file mode 100755 index 000000000..e4b34d1d0 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_NewOptions.xml @@ -0,0 +1,6 @@ + + + + Back to list + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_Scheduler_Options.xml b/workflow/engine/xmlform/cases/cases_Scheduler_Options.xml new file mode 100755 index 000000000..d18059f7d --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_Scheduler_Options.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + New + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_TaskDetails.xml b/workflow/engine/xmlform/cases/cases_TaskDetails.xml new file mode 100644 index 000000000..469ba64f3 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_TaskDetails.xml @@ -0,0 +1,28 @@ + + + + + Title + + + + User + + + + Init Date + + + + Due date + + + + Finish date + + + + Duration + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_TaskInformation.xml b/workflow/engine/xmlform/cases/cases_TaskInformation.xml new file mode 100644 index 000000000..948f1184d --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_TaskInformation.xml @@ -0,0 +1,29 @@ + + + + + + Title + + + + Description + + + + Init Date + + + + Due Date + + + + Finish date + + + + Duration + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ToReassignByUserList.xml b/workflow/engine/xmlform/cases/cases_ToReassignByUserList.xml new file mode 100755 index 000000000..216358cd9 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ToReassignByUserList.xml @@ -0,0 +1,46 @@ + + + + + + + + + Case # + + + + Task + + + + Process + + + + Priority + + + + Init. date + + + + Due date + + + + + + Status + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ToReassignByUserList2.xml b/workflow/engine/xmlform/cases/cases_ToReassignByUserList2.xml new file mode 100755 index 000000000..946ea3db3 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ToReassignByUserList2.xml @@ -0,0 +1,39 @@ + + + + + + + Case # + + + + Task + + + + Process + + + + + + Status + + + + + + + Reassign to + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ToReviseInputdocsList.xml b/workflow/engine/xmlform/cases/cases_ToReviseInputdocsList.xml new file mode 100644 index 000000000..3cf1849c9 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ToReviseInputdocsList.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + <en>Title</en> + + + + Version + + + + Creator + + + + Comment + + + + Created Date + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ToReviseInputdocsListOptions.xml b/workflow/engine/xmlform/cases/cases_ToReviseInputdocsListOptions.xml new file mode 100644 index 000000000..860eb5943 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ToReviseInputdocsListOptions.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_TransferHistory.xml b/workflow/engine/xmlform/cases/cases_TransferHistory.xml new file mode 100755 index 000000000..47ae9f385 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_TransferHistory.xml @@ -0,0 +1,46 @@ + + + + Task + + + + Delegated User + + + + Delegated User + + + + Delegated User + + + + Task Transfer Date + + + + Start Date + + + + End Date + + + + Action + + + + Enable Action + + + + Disable Action + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_UnpauseDateInput.html b/workflow/engine/xmlform/cases/cases_UnpauseDateInput.html new file mode 100755 index 000000000..c7fec245a --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_UnpauseDateInput.html @@ -0,0 +1,40 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + +
    {$form.DBS_UID}
    {$form.PRO_UID}
    {$form.TIME_STAMP}
    +
    {$title1}
    {$unpause_date}{$form.unpause_date}
    +
    {$form.pause_exec}
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/cases/cases_UnpauseDateInput.xml b/workflow/engine/xmlform/cases/cases_UnpauseDateInput.xml new file mode 100644 index 000000000..12608ee70 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_UnpauseDateInput.xml @@ -0,0 +1,20 @@ + + + + + + + + + ]]> + + + + Unpause date + + + + Pause + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument.xml b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument.xml new file mode 100644 index 000000000..7cba89ed5 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument.xml @@ -0,0 +1,32 @@ + + + + + + + + + Filename + + + + Created Date + + + + Creator + + + + Origin Task + + + + + + + + File + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument1.xml b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument1.xml new file mode 100644 index 000000000..0200219f3 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument1.xml @@ -0,0 +1,56 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + Origin Task + + + + + + + + + + File + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument2.xml b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument2.xml new file mode 100644 index 000000000..b5be5d0f8 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument2.xml @@ -0,0 +1,52 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + Origin Task + + + + + + Comments + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument3.xml b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument3.xml new file mode 100644 index 000000000..7b3d16347 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewAnyInputDocument3.xml @@ -0,0 +1,60 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + Origin Task + + + + + + Comments + + + + + + + + File + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewAnyOutputDocument.xml b/workflow/engine/xmlform/cases/cases_ViewAnyOutputDocument.xml new file mode 100644 index 000000000..162227faf --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewAnyOutputDocument.xml @@ -0,0 +1,36 @@ + + + + + Output document + + + + + + Create Date + + + + + + + + + + File (.doc) + + + + File (.pdf) + + + + Creator + + + + Origin Task + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewInputDocument1.xml b/workflow/engine/xmlform/cases/cases_ViewInputDocument1.xml new file mode 100644 index 000000000..237a5f4b7 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewInputDocument1.xml @@ -0,0 +1,65 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + + + + + + + File + + + + Back + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewInputDocument2.xml b/workflow/engine/xmlform/cases/cases_ViewInputDocument2.xml new file mode 100644 index 000000000..d6d49502e --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewInputDocument2.xml @@ -0,0 +1,61 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + + + Comments + + + + Back + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewInputDocument3.xml b/workflow/engine/xmlform/cases/cases_ViewInputDocument3.xml new file mode 100644 index 000000000..da6b9e8aa --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewInputDocument3.xml @@ -0,0 +1,69 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + Creator + + + + + + Comments + + + + + + + + File + + + + Back + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewInputDocumentToRevise.xml b/workflow/engine/xmlform/cases/cases_ViewInputDocumentToRevise.xml new file mode 100644 index 000000000..75933f95a --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewInputDocumentToRevise.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + Title + + + + Comment + + + + Type + + + + Format + + + + Created Date + + + + Creator + + + + + + + + + + File + + + + Back + + + + + +var back = function() +{ + javascript:history.go(-1); +}; + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewOutputDocument1.xml b/workflow/engine/xmlform/cases/cases_ViewOutputDocument1.xml new file mode 100644 index 000000000..652053fe2 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewOutputDocument1.xml @@ -0,0 +1,48 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + Output document + + + + Description + + + + Create Date + + + + + + + + + + + + File (.doc) + + + + File (.pdf) + + + + Next step + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewOutputDocument2.xml b/workflow/engine/xmlform/cases/cases_ViewOutputDocument2.xml new file mode 100644 index 000000000..e44dc5225 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewOutputDocument2.xml @@ -0,0 +1,44 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + Output document + + + + Description + + + + Create Date + + + + + + + + + + + + File (.doc) + + + + Next step + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewOutputDocument3.xml b/workflow/engine/xmlform/cases/cases_ViewOutputDocument3.xml new file mode 100644 index 000000000..f3f3071b1 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewOutputDocument3.xml @@ -0,0 +1,44 @@ + + + +<__DYNAFORM_OPTIONS type="xmlmenu" xmlfile="gulliver/dynaforms_Options"> + + + + + Output document + + + + Description + + + + Create Date + + + + + + + + + + + + File (.pdf) + + + + Next step + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_ViewOutputDocumentToRevise.xml b/workflow/engine/xmlform/cases/cases_ViewOutputDocumentToRevise.xml new file mode 100644 index 000000000..74ff7234f --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_ViewOutputDocumentToRevise.xml @@ -0,0 +1,34 @@ + + + + + Output document + + + + Description + + + + Create Date + + + + + + + + + + File (.doc) + + + + File (.pdf) + + + + Back + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_advancedSearch.xml b/workflow/engine/xmlform/cases/cases_advancedSearch.xml new file mode 100644 index 000000000..5aa5e6b89 --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_advancedSearch.xml @@ -0,0 +1,73 @@ + + + + + + + + + # +## + + + Case +CasoCaso + + + Task +TareaTarefa + + + Process +ProcesoProcesso + + + Current User +Usuario Actual + + + Sent by +Enviado porEnviado por + + + Due Date +Fecha de vencimientoData-limite + + + Last Modification + + + + Start Date +Fechas inicial del casoData Inicial + + + Finish Date +Fecha finalData Final + + + + Status +EstadoEstado + + + + + + + + + + + + Apply Filter +Aplicar FiltroAplicar Filtro + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/cases/cases_advancedSearchFilter.html b/workflow/engine/xmlform/cases/cases_advancedSearchFilter.html new file mode 100644 index 000000000..ad6da509f --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_advancedSearchFilter.html @@ -0,0 +1,56 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$PROCESS}{$form.PROCESS}{$TASKS}{$form.TASKS}
    {$CURRENT_USER}{$form.CURRENT_USER}{$SENT_BY}{$form.SENT_BY}
    {$CASE_NUMBER}{$form.CASE_NUMBER}{$APP_STATUS}{$form.APP_STATUS}
    + + + + + +
    {$LAST_MODIFICATION_F}{$form.LAST_MODIFICATION_F}{$LAST_MODIFICATION_T}{$form.LAST_MODIFICATION_T}
    +
    {$form.FILTER}
    +
    +
    +
    +
    +
    diff --git a/workflow/engine/xmlform/cases/cases_advancedSearchFilter.xml b/workflow/engine/xmlform/cases/cases_advancedSearchFilter.xml new file mode 100644 index 000000000..7fb8dbb9b --- /dev/null +++ b/workflow/engine/xmlform/cases/cases_advancedSearchFilter.xml @@ -0,0 +1,51 @@ + + + + + Case Number + + +Process + + +Tasks + + +Current User + + +Sent by + + + + From + + + + To + + + + Status + + + + Filter + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.html b/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.html new file mode 100644 index 000000000..25261b4c8 --- /dev/null +++ b/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.html @@ -0,0 +1,33 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$DASHBOARD}{$form.DASHBOARD}

    {$form.ADD}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    diff --git a/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.xml b/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.xml new file mode 100644 index 000000000..d462fc9f6 --- /dev/null +++ b/workflow/engine/xmlform/dashboard/dashboard_AvailableDashboards.xml @@ -0,0 +1,28 @@ + + + + + <en>Add availables reports or charts</en> + + + +SELECT * FROM AvailableDashboards + Chart or Report + + + + Cancel + + + + Add + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dashboard/dashboard_NoAvailableDashboards.xml b/workflow/engine/xmlform/dashboard/dashboard_NoAvailableDashboards.xml new file mode 100644 index 000000000..808827fed --- /dev/null +++ b/workflow/engine/xmlform/dashboard/dashboard_NoAvailableDashboards.xml @@ -0,0 +1,11 @@ + + + + + <en>No availables reports or charts</en> + + + + Close + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections.xml b/workflow/engine/xmlform/dbConnections/dbConnections.xml new file mode 100644 index 000000000..f077f2db1 --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections.xml @@ -0,0 +1,34 @@ + + + + + + + + + Type + + + + Server + + + + Database Name + + + + Description + + + + Edit + + + + Delete + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections_Edit.html b/workflow/engine/xmlform/dbConnections/dbConnections_Edit.html new file mode 100644 index 000000000..8bd08252f --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections_Edit.html @@ -0,0 +1,77 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$DBS_UID}{$form.DBS_UID}
    {$DBS_TYPE}{$form.DBS_TYPE}
    {$DBS_ENCODE}{$form.DBS_ENCODE}
    * {$DBS_SERVER}{$form.DBS_SERVER}
    * {$DBS_DATABASE_NAME}{$form.DBS_DATABASE_NAME}
    * {$DBS_USERNAME}{$form.DBS_USERNAME}
    {$DBS_PASSWORD}{$form.DBS_PASSWORD}
    * {$DBS_PORT}{$form.DBS_PORT}
    {$DBS_DESCRIPTION}{$form.DBS_DESCRIPTION}

    {$form.TEST}   {$form.CREATE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections_Edit.xml b/workflow/engine/xmlform/dbConnections/dbConnections_Edit.xml new file mode 100644 index 000000000..f3452d507 --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections_Edit.xml @@ -0,0 +1,69 @@ + + + + + + UID + + + + SELECT * FROM BDCONNECTIONS + Engine + + + + Encode + + + + Server + + + + Database Name + + + + Username + + + + Password + + + + Port + + + + Description + + + + Test Connection + + + + Save + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections_New.html b/workflow/engine/xmlform/dbConnections/dbConnections_New.html new file mode 100644 index 000000000..ddb0b7851 --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections_New.html @@ -0,0 +1,75 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.DBS_UID}
    {$form.PRO_UID}
    * {$DBS_TYPE}{$form.DBS_TYPE}
    * {$DBS_ENCODE}{$form.DBS_ENCODE}
    * {$DBS_SERVER}{$form.DBS_SERVER}
    * {$DBS_DATABASE_NAME}{$form.DBS_DATABASE_NAME}
    * {$DBS_USERNAME}{$form.DBS_USERNAME}
    {$DBS_PASSWORD}{$form.DBS_PASSWORD}
    * {$DBS_PORT}{$form.DBS_PORT}
    {$DBS_DESCRIPTION}{$form.DBS_DESCRIPTION}

    {$form.TEST}   {$form.CREATE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections_New.xml b/workflow/engine/xmlform/dbConnections/dbConnections_New.xml new file mode 100644 index 000000000..7a2939afa --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections_New.xml @@ -0,0 +1,66 @@ + + + + + + + + + SELECT * FROM BDCONNECTIONS + Engine + + + + Encode + + + + Server + + + + Database Name + + + + Username + + + + Password + + + + Port + + + + Description + + + + Test Connection + + + + Create + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dbConnections/dbConnections_Options.xml b/workflow/engine/xmlform/dbConnections/dbConnections_Options.xml new file mode 100644 index 000000000..14b678cde --- /dev/null +++ b/workflow/engine/xmlform/dbConnections/dbConnections_Options.xml @@ -0,0 +1,10 @@ + + + + + + + New + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_AddUnAssignedUsers.xml b/workflow/engine/xmlform/departments/departments_AddUnAssignedUsers.xml new file mode 100755 index 000000000..c412a4e6e --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_AddUnAssignedUsers.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + Firstname + + + + Lastname + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_AvailableUsers.xml b/workflow/engine/xmlform/departments/departments_AvailableUsers.xml new file mode 100644 index 000000000..362ba74a6 --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_AvailableUsers.xml @@ -0,0 +1,25 @@ + + + + + + + + + Firstname + + + + Lastname + + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_Edit.html b/workflow/engine/xmlform/departments/departments_Edit.html new file mode 100644 index 000000000..949162984 --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_Edit.html @@ -0,0 +1,54 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    {$form.DEP_UID}
    {$form.DEP_PARENT}
    * {$DEPO_TITLE}{$form.DEPO_TITLE}
    {$DEP_MANAGER }{$form.DEP_MANAGER }
    {$DEP_STATUS}{$form.DEP_STATUS}

    {$form.button}   {$form.BTN_CANCEL}
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    +
    + +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_Edit.xml b/workflow/engine/xmlform/departments/departments_Edit.xml new file mode 100644 index 000000000..6dc4d252a --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_Edit.xml @@ -0,0 +1,88 @@ + + + + <en>Department Information</en> + + + + + + + Name + + + + Status + + + + + + +SELECT USR_UID, USR_USERNAME from USERS where DEP_UID = "@#DEP_UID" + Manager/Supervisor + + + + + + + var sGroupname; + sGroupname = document.forms[0].elements['form[DEPO_TITLE]'].value; + +var verifyDptoname = function() +{ + document.forms[0].elements['form[DEPO_TITLE]'].disabled = true; + document.forms[0].elements['form[button]'].disabled = true; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url :'departments_Ajax', + async : false, + method :'POST', + args :'action=verifyDptoname&sOriginalGroupname=' + sGroupname + '&sGroupname=' + encodeURIComponent(this.value)}); + oRPC.make(); + var sResponse = oRPC.xmlhttp.responseText; + document.forms[0].elements['form[DEPO_TITLE]'].disabled = false; + if (sResponse == '1') + { + new leimnud.module.app.alert().make({ + label: G_STRINGS.ID_MSJ_DEPTO + }); + document.forms[0].elements['form[DEPO_TITLE]'].focus(); + } + else + { + document.forms[0].elements['form[button]'].disabled = false; + } +}; + +var validateLocalFields = function(oForm) +{ oAux1 = oForm.elements['form[DEPO_TITLE]']; + if (oAux1.value == '') + { + new leimnud.module.app.alert().make({ + label:G_STRINGS.DBCONNECTIONS_ALERT + }); + oAux1.focus(); + bContinue = false; + return false; + } + else{ + savedeptomain(oForm); + } + +} + +leimnud.event.add(document.forms[0].elements['form[DEPO_TITLE]'],'change',verifyDptoname); + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_New.html b/workflow/engine/xmlform/departments/departments_New.html new file mode 100644 index 000000000..7fb457db2 --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_New.html @@ -0,0 +1,41 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    {$form.DEP_UID}
    {$form.DEP_PARENT}
    * {$DEP_TITLE}{$form.DEP_TITLE}

    {$form.button}   {$form.BTN_CANCEL}
    +
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_New.xml b/workflow/engine/xmlform/departments/departments_New.xml new file mode 100644 index 000000000..265c7f19a --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_New.xml @@ -0,0 +1,94 @@ + + + + + <en>Department Information</en> + + + + + + + Department Name + + + + Cancel + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_Options.xml b/workflow/engine/xmlform/departments/departments_Options.xml new file mode 100644 index 000000000..ddfb8a50d --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_Options.xml @@ -0,0 +1,12 @@ + + + + + + + + + Assign user + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_SubNew.html b/workflow/engine/xmlform/departments/departments_SubNew.html new file mode 100644 index 000000000..1967567d6 --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_SubNew.html @@ -0,0 +1,47 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    {$form.DEP_UID}
    {$form.DEP_PARENT}
    {$DEP_PARENT_NAME}{$form.DEP_PARENT_NAME}
    * {$DEP_TITLE}{$form.DEP_TITLE}
    {$form.button}   {$form.BTN_CANCEL}
    +
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/departments/departments_SubNew.xml b/workflow/engine/xmlform/departments/departments_SubNew.xml new file mode 100755 index 000000000..c0d7b0c48 --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_SubNew.xml @@ -0,0 +1,81 @@ + + + + <en>Department Information </en> + <es><![CDATA[Información de departamento]]></es> + + + + + select CON_VALUE, CON_VALUE FROM CONTENT WHERE CON_ID= '@#DEP_PARENT' + Parent Department + + + Department Name + + + + Cancel + + + + +getField('DEP_TITLE').value =''; +var sGroupname; +//sGroupname = document.forms[0].elements['form[DEP_TITLE]'].value; + +var verifyDptoname = function() +{ + document.forms[0].elements['form[DEP_TITLE]'].disabled = true; + document.forms[0].elements['form[button]'].disabled = true; + var sDepTitle = getField('DEP_TITLE').value; + var oRPC = new leimnud.module.rpc.xmlhttp({ + url :'departments_Ajax', + async : false, + method :'POST', + args :'action=verifyDptoname&sOriginalGroupname=' + sGroupname + '&sGroupname=' + encodeURIComponent(sDepTitle)}); + oRPC.make(); + var sResponse = oRPC.xmlhttp.responseText; + document.forms[0].elements['form[DEP_TITLE]'].disabled = false; + if (sResponse == '1') + { + new leimnud.module.app.alert().make({ + label: G_STRINGS.ID_MSJ_DEPTO + }); + document.forms[0].elements['form[DEP_TITLE]'].focus(); + } + else + { + document.forms[0].elements['form[button]'].disabled = false; + } +}; + +leimnud.event.add(document.forms[0].elements['form[DEP_TITLE]'],'change',verifyDptoname); +// leimnud.event.add(getField('DEP_TITLE'),'change',verifyDptoname); + +var validateLocalFields = function(oForm){ +//oAux1 = oForm.elements['form[DEP_TITLE]']; + var oAux1 = getField('DEP_TITLE'); + + if (oAux1.value == '') + { + new leimnud.module.app.alert().make({ + label:G_STRINGS.DBCONNECTIONS_ALERT + }); + oAux1.focus(); + bContinue = false; + return false; + } + else{ + savesubdepto( oForm); + } +} +function cancel(){ + currentPopupWindow.remove(); +} + + + diff --git a/workflow/engine/xmlform/departments/departments_UsersList.xml b/workflow/engine/xmlform/departments/departments_UsersList.xml new file mode 100644 index 000000000..3724a756d --- /dev/null +++ b/workflow/engine/xmlform/departments/departments_UsersList.xml @@ -0,0 +1,26 @@ + + + + + + + + Username + + + + User + + + + Manager + + + + Reports To + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/datemask.xml b/workflow/engine/xmlform/dynaforms/datemask.xml new file mode 100755 index 000000000..7ebb53372 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/datemask.xml @@ -0,0 +1,37 @@ + + + + +Options Mask + + + %A — full weekday name +
    %b — abbreviated month name +
    %B — full month name +
    %C — the century number +
    %d — the day of the month (range 01 to 31) +
    %e — the day of the month (range 1 to 31) +
    %H — hour, range 00 to 23 (24h format) +
    %I — hour, range 01 to 12 (12h format) +
    %j — day of the year (range 001 to 366) +
    %k — hour, range 0 to 23 (24h format) +
    %l — hour, range 1 to 12 (12h format) +
    %m — month, range 01 to 12 +
    %o — month, range 1 to 12 +
    %M — minute, range 00 to 59 +
    %n — a newline character +
    %p — PM or AM +
    %P — pm or am +
    %s — UNIX time (number of seconds since 1970-01-01) +
    %S — seconds, range 00 to 59 +
    %t — a tab character +
    %W — week number +
    %u — the day of the week (range 1 to 7, 1 = MON) +
    %w — the day of the week (range 0 to 6, 0 = SUN) +
    %y — year without the century (range 00 to 99) +
    %Y — year with the century +
    %% — a literal '%' character]]>
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaform_Fields.xml b/workflow/engine/xmlform/dynaforms/dynaform_Fields.xml new file mode 100644 index 000000000..15163b237 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaform_Fields.xml @@ -0,0 +1,22 @@ + + + + + Field + + + + Type + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.html b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.html new file mode 100644 index 000000000..76507d9b7 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.html @@ -0,0 +1,49 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$form.DYN_UID}
    {$form.DYN_TITLE}
    {$form.DYN_TYPE}
    {$form.DYN_DESCRIPTION}
    {$form.ADD_TABLE}
    {$form.FIELDS}
    {$form.SAVE_FROM_PMTABLE}   {$form.SAVE_AND_OPEN_FROM_PMTABLE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.xml b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.xml new file mode 100644 index 000000000..594710133 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariables.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + Save + + + + + + + + + +0){ + //alert(invalidFields[0]); + msgBox("@#VALIDATION_MESSAGE","alert"); + } else { + if (value=='save'){ + dynaformSavePMBasedForm( formElement, false ); + } else { + dynaformSave( formElement, true ); + } + } +} + +function assignVariable(){ + var variables; + var i=1; + while( document.getElementById('form[FIELDS]['+i+'][PRO_VARIABLE]')!=undefined){ + if (variables!=''&&variables!=undefined){ + variables = variables + '|' + document.getElementById('form[FIELDS]['+i+'][PRO_VARIABLE]').value; + } else { + variables = document.getElementById('form[FIELDS]['+i+'][PRO_VARIABLE]').value; + } + i++; + } + document.getElementById('form[PROCESS_VARIABLES]').value = variables; + currentPopupWindow.remove(); +} + +var _oVarsPanel_; +var showDynaformsFormVars = function(sFieldName, sAjaxServer, sProcess, sSymbol) { + _oVarsPanel_ = new leimnud.module.panel(); + _oVarsPanel_.options = { + limit : true, + size : {w:400,h:600}, + position : {x:0,y:0,center:true}, + title : '', + theme : 'processmaker', + statusBar: false, + control : {drag:false,resize:true,close:true}, + fx : {opacity:true,rolled:false,modal:true} + }; + _oVarsPanel_.make(); + _oVarsPanel_.events = { + remove:function() { + delete _oVarsPanel_; + }.extend(this) + }; + _oVarsPanel_.loader.show(); + oRPC = new leimnud.module.rpc.xmlhttp({ + url : sAjaxServer, + method: 'POST', + args : 'sFieldName=' + sFieldName + '&sProcess=' + sProcess + '&sSymbol=' + sSymbol + '&sType=2' + }); + oRPC.callback = function(oRPC) { + _oVarsPanel_.loader.hide(); + var scs = oRPC.xmlhttp.responseText.extractScript(); + _oVarsPanel_.addContent(oRPC.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var insertFormVar = function(sFieldName, sValue) { + oAux = document.getElementById(sFieldName); + if (oAux.setSelectionRange) { + var rangeStart = oAux.selectionStart; + var rangeEnd = oAux.selectionEnd; + var tempStr1 = oAux.value.substring(0,rangeStart); + var tempStr2 = oAux.value.substring(rangeEnd); + oAux.value = tempStr1 + sValue + tempStr2; + } + else { + if (document.selection) { + oAux.focus(); + document.selection.createRange().text = sValue; + } + } +_oVarsPanel_.remove(); +}; + +function cancel(){ + oPanel.remove(); +} + +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariablesGrid.xml b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariablesGrid.xml new file mode 100644 index 000000000..60beb36a9 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_AssignVariablesGrid.xml @@ -0,0 +1,13 @@ + + + + + + Primary Key + + + + Variables + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_AvailableSupervisorDynaforms.xml b/workflow/engine/xmlform/dynaforms/dynaforms_AvailableSupervisorDynaforms.xml new file mode 100644 index 000000000..1c1531b7f --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_AvailableSupervisorDynaforms.xml @@ -0,0 +1,27 @@ + + + + + + + + + Title + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.html b/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.html new file mode 100644 index 000000000..7afb4694b --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.html @@ -0,0 +1,39 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    {$form.DYN_UID}
    {$form.PRO_UID}
    {$form.TITLE}
    {$DYN_SOURCE}{$form.DYN_SOURCE}

    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.xml new file mode 100644 index 000000000..1b3e29163 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ChoseType.xml @@ -0,0 +1,52 @@ + + + + + + + + <en>Please select the Dynaform Type</en> + + + + Type + + + + + + + Cancel + + + + Select + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.html b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.html new file mode 100755 index 000000000..8b66102b6 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.html @@ -0,0 +1,149 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.FCD_UID}{$form.FCD_FIELDS}{$form.FCD_EVENTS}{$form.FCD_EVENT_OWNERS}
    {$FCD_FUNCTION}
    {$form.FCD_FUNCTION}
    + + + + + + + + + +
    {$fields} {$fields_selected}
    {$form.fields} + +

    + +
    {$form.fields_selected}
    +
    + {$FCD_CONDITION} +  
    + {$form.FCD_CONDITION}
    + + +
     
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.op1}{$form.op2}{$form.op3}{$form.op4}
    {$form.op5}{$form.op6}{$form.op7}{$form.op8}
    {$form.op9}{$form.op10}{$form.op11}{$form.op12}
    {$form.op13}{$form.op14}{$form.op15}{$form.op16}
    {$form.test_condition} + + + +
    +
    {$form.eventOnload}  {$form.eventOnchange}
    + + + + + + + + + + +
    {$event_owner} {$event_owner_selected}
    {$form.event_owner} + +

    + +
    {$form.event_owner_selected}
    + +
    {$form.FCD_STATUS}
    + {$form.save_condition}   {$form.BTN_CANCEL} +
    +
    +
    +
    +
    + +
    + + + + diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.xml new file mode 100755 index 000000000..db04cbe6f --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHide.xml @@ -0,0 +1,132 @@ + + + + + + + + + Conditions Editor + + + + Function + + + + Applying the function fields + + + + Selected fields + + + + Condition + + + + / + + + ( + + + ) + + + AND + + + + + * + + + + + + ]]> + + + OR + + + + - + + + + + + =]]> + + + NOT + + + + + + + + == + + + != + + + @# + + + + + + On load event + + + + On change event + + + + Field event owner + + + + Selected field event owner + + + + Enabled + + + + Test condition + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideList.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideList.xml new file mode 100755 index 000000000..a46fd6e42 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideList.xml @@ -0,0 +1,36 @@ + + + + + + # + + + Function + + + Fields + + + Condition + + + Events + + + Event Owner + + + + Enabled + + + + Edit + + + + Delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideOptions.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideOptions.xml new file mode 100755 index 000000000..49da30e2a --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideOptions.xml @@ -0,0 +1,12 @@ + + + + New + + + + + oConditional = new Conditional(@@DYN_UID); + //oConditional.showID(); + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.html b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.html new file mode 100755 index 000000000..4afa5f40b --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.html @@ -0,0 +1,26 @@ +
    +
    +
    + + + + +
    + + + + + + +
    {$form.gFields}
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.xml new file mode 100755 index 000000000..ac5e60524 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTest.xml @@ -0,0 +1,17 @@ + + + + Test values for DynaForm fields + + + + + Save values + + + + + oConditional.populateTestConditionSetup(); + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTestGrid.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTestGrid.xml new file mode 100755 index 000000000..89a245de2 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ConditionalShowHideTestGrid.xml @@ -0,0 +1,13 @@ + + + + + + Field name + + + + Value + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Edit.html b/workflow/engine/xmlform/dynaforms/dynaforms_Edit.html new file mode 100644 index 000000000..9101b20fa --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Edit.html @@ -0,0 +1,63 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.DYN_UID}
    {$form.ACTION}
    {$form.PRO_UID}
    {$form.TITLE}
    {$DYN_TITLE}{$form.DYN_TITLE}
    {$DYN_DESCRIPTION}{$form.DYN_DESCRIPTION}
    +
    +
    +
    +
    + + +
    diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Edit.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Edit.xml new file mode 100644 index 000000000..2b9376b36 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Edit.xml @@ -0,0 +1,143 @@ + + + + + + + + + <en>Dynaform Information</en> + + + + SELECT * FROM ADDITIONAL_TABLES + Create from a PM Table + + + + Title + + + + Type + + + + + + + Description + + + + Save + + + + Save + + + + + + + + Cancel + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Editor.html b/workflow/engine/xmlform/dynaforms/dynaforms_Editor.html new file mode 100644 index 000000000..1cec88ee5 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Editor.html @@ -0,0 +1,28 @@ +
    + + +
    + + + + + + + + + + +
    + {$form.title} +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Editor.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Editor.xml new file mode 100644 index 000000000..4b1a2a97e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Editor.xml @@ -0,0 +1,258 @@ + + + + + + + + + <en><![CDATA[<table cellpadding="0" cellspacing="0" width="100%" style="background-color:transparent"> <tr> <td class=\'FormTitle\'>Preview</td> <td align="right"></td> </tr> </table>]]></en> + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.html b/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.html new file mode 100755 index 000000000..06352fb69 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.html @@ -0,0 +1,35 @@ +
    +
    +
    +
    + + + }dEzPReN7__R~XE~+BsM#6xTgzm_LOhP{l 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/fbr.blue.png b/workflow/public_html/images/newSkin/fbr.blue.png new file mode 100755 index 0000000000000000000000000000000000000000..2dcc39d873686539fa55544acfed3fd7e24e0daa GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDVAa<&kznEsNqQI0P;BtJR*x3 z7`Q%wFr(8NlNmrki4xa{lHmNblJdl&R0hYC{G?O`x6Go{^8BLgV*kzZen4{sL24p= zeXNr6bM+EIO7tpn3m9zdD+&^mvr|hHl2X$%^K6wA6cm&cGE;1o!cBb*d<&dYGcrA@ zic*8C{6dnevXd=Slkzt6Dft8V=m8nq_l75IHH0{3mDVb@N*t8p285%&fBPoJvx6ua$1X93& zLmlKNG;u-!mXZt)uY%H|9B{OxBzopr0Kye literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/fbr.png b/workflow/public_html/images/newSkin/fbr.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3256ca010ea00408763140f2bee4b8ad0c5e1b GIT binary patch literal 41152 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/frame.home.bottom.png b/workflow/public_html/images/newSkin/frame.home.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d83a05a7ffc38b124ea9b629bb395a1e3cf1989c GIT binary patch literal 557 zcmV+|0@D47P)>Lcv1_3NGBV7f5o0xU8X0 zoi?U%nyA?&_5XumUIvrJEZ)acxUMT(t(E}*KpM~U3^NQvkE;LxWKlU`20<|6DgXdk zR8CYHjmCSs-R|4A&5Zy6^q?@t^P3QJCe~dgp|?{J6dR%N0vzJ zdf)&6iYIRR(Y}q=zW&tCx5?it)=y5v9}tO;ZWHzX*-V6k9xwoa;)aEx^>nEPhTij& z@BK^`-^Figh@8tHFaV(NL6H^~S>X}CC!>(i8@x!_vnC0G0szVz7+K-*Cnydki}>Jh z!Z>FqEC8TfVR3SoS~z4id6BaQ0F*a44r)CpQYVXyDI-s~004>`5Si!lNFbck%{F001SMH1hQSF98Ms>^8=?^qOH000000NkvXXu0mjflF0E1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/frame.right.bottom.png b/workflow/public_html/images/newSkin/frame.right.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..64b06aa2b852511bc8337b4fcfcd0afc46908475 GIT binary patch literal 43095 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 HZ{Po4tZ$}k literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/frame.right.top.gif b/workflow/public_html/images/newSkin/frame.right.top.gif new file mode 100644 index 0000000000000000000000000000000000000000..00c9fc88a8df92cd8570414f46e0b945d645abcf GIT binary patch literal 197 zcmV;$06PCiNk%w1VMGE60HOu}|NsBr-`~v4%-Y)8_xJbV;o$%P00000A^8LW000I6 zEC2ui07L=_000AuXsR;tFv>}*y*TU5yZ>M)j$~<`XsWJk>q>*L%!WV!c&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-@?f^1g6dcWYXcuX#v&*-$eS6B$v@VI{XE)7O>#IuElTi%$HnB^3+|jK4fx977}|8Q(Js{9^1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z76M_$OLy!300kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!ywE43U_c{OA9FduE9hr1aOgeV# z*o`X&1_vc}h!}vt9LwTo_KF8uqOHYVvrSZDuwvH>cp}_A9cToDr>mdKI;Vst0OX54 AZ~y=R literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/ftlL.png b/workflow/public_html/images/newSkin/ftlL.png new file mode 100755 index 0000000000000000000000000000000000000000..14b43f8c749408a9c048000cf6b4a34d885f3f47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#IuElDyYcUtF5*C;b)GJcAr`0iPT0tM$UwmLzkQ-+ zuQpo(TSNov9%kVUj;~De5}4UGsZNpI(`@hE>#W-Z z*4_KPx%gc}uL48n?XvknyZRrmh;H7VAknrwjEOgTe~DWM4fHw1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z`T)X=PHRkN00kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!6M843U_cY*YN~Og)>{XE)7O>#IuElThZXzmI8_D))^DCJjv*F;jIUWmelY@-fG|bi zKM>$E0Av9(J_SHId52@3&B(4~z&w3}gvAx+!RUWP?CbFg`XKCdPnl z5y%&Wf(zMT7#n05%s^x|NFD_KGXeq3B9JBcf(vF4SSLs`9{dlg2&4uSLU4-+SpwCE z;cA#=AcH{|<`@tSE`SZaoTeeKDs;W8)6KiT}gnm|0JsKD_|92qs7i`s~@W6F|O!Co>?2>fqmdKI;Vst0Lvns AXaE2J literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/input_back.gif b/workflow/public_html/images/newSkin/input_back.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9d4a35491a4383c6a7aa91cf2064308ee254a4f GIT binary patch literal 44 tcmZ?wbhEHbWM*JyXkcLY|NsAo4<8hNvM_*v4u}BBFfcLq@JBLO0{|Yv3V;9r literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/nextPage.gif b/workflow/public_html/images/nextPage.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cd65a407c665a5f3ac9cfa57888852d24bdc864 GIT binary patch literal 277 zcmV+w0qXuoNk%w1VG{rn0K@mze8x(g)LW(3rq1ZM*X%Nn&e!SlKbFzG+wEeh*;1g@i@@T3xZkSK={1qh zo5UA^8LW2LK-cEC2ui022Tb000G&;3tYvc1e;G3}Y)U549Rglw615 zeg>6zJ5QmbXc+{MU2Cw3j2;Qs1K3h@NFC}3K&ZGZg-;-}0{|M~5#;dcI9+D*ROCT? z2#azY@E8dg1UhhWeSQobEQ4q+8)8v#T`n4I3>OnpN)Krd7)p{3BRw3RA{qz`MigX0 b1qekhFb)Z*9t;T%Ii$7+8yhN#Eg=9qP5*W` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/object_permission.gif b/workflow/public_html/images/object_permission.gif new file mode 100644 index 0000000000000000000000000000000000000000..7e00a138eac1df6e73ecdaffdb133500e0c3eb72 GIT binary patch literal 1051 zcmWlY`%fDM0Dy}+LE^F~WD-Lni$5$HHBp~XHt?sgCEL9fR>+PmJBKpWb6*ISSB5*)(TTE4&F`{DcEc=Pom zFMUyCsxjR$?NTfjaZ$&jS%}YpoKBkiXRO1V^Dn>|pj>2OyO7nghMwQ}XOpLr6wd#< zxh+Qio^WFXu4$SPi^ciqJ(4L<%o-kA3Iq{ZNrt$!?&~hgjmhg4H_hcE@&?Vsd#zrI zTZ3lS#@rwrUYYQbzmDMjL!isY{yuu^_R@xR7`frV>@I?it>2ssyL^m0z{1oVMu`B3 z_K)C0<8+tBO-Ax?ScQqGCxDYod~P8#a1*z=D41OeNlS#F6GE0zmI+=9@d+P*D|3nM zoqL#I{A_h~^g8;6{FG?mf{qK>KZ4BYBDU^?=^&dO@`ey02lM(hn|C(3Wpw~% zyAR>BAd?2@MO-vcA&Wui~j3 zwvZ0U3vNd6#S>s6iKWuCAdJOjx5)Vy6bDP<{A@Sk^)E(S;1SEL|1I-3KQe=ztg~t2 zV!ippr+zwS>L^1!ePH|PsdHbEr{85d+VAe{6bgk>`3L@cpscij>6zUVcAqd+Y?+D= z)i!trv9^k;r#}sO?D(ZUsYqL6&u6!qXO7H`RgtHvPkKIK``_!VgU%JTSlb<*aa7jU ze)Ktto~Umw2#t?#aW?3OjcLEntae@5yWhIl*jiOp*Sfw;8W)$JsI5OcZUw&8%J;u` z(DK^c`>TnUTdzXW%`;y#98a`VK3Z{f_3GQ*2cG|cxKMWTQs-lb+N+7t zeOSx+;&*o=XYSwI!@PQap(b+n;PHx`t&T0_1bw;sxl;{2hgxpm_pGgaJ)>9;TPlxx v_B36XZ)vLtzVOIl^qoPtc~Cz3ai+YoV_)5|?@iv!_@)v6^T~%ROt1V8yA97` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ok.png b/workflow/public_html/images/ok.png new file mode 100644 index 0000000000000000000000000000000000000000..5941f106173ae756260d2152b0565426f34cff95 GIT binary patch literal 23144 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 C*aD~xcoPrc!UG6y{MmSun7AldH$E5` z-oQ6A?&e-l+iuf=cv{i|?uj)xrIb<57@u-qX~KDuN+D7qq>>+$oaHK?Nn@-vrm5?? zSqy{_631~Svr?(DDs)i|!+#rhf=*CEMnq$xNu-H8V;)Y$7cB94xE^=?^1^WF?cUwrCuk=) literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/options.png b/workflow/public_html/images/options.png new file mode 100644 index 0000000000000000000000000000000000000000..5d92de3fc9edabb6c1069dfa2a6318148e53bf45 GIT binary patch literal 900 zcmV-~1AF|5P)5i3wUSxX=KCA|lPuVWz`e&;9au(X_6rPx4*;lF#BNR#!h`csK*d9>dVT zpPU>Wj^jvHtBum}arsuO<$M|hp(O;5bKQX1*&O-&vna0Xb9h+9^Zd4Ld!IOt(=j=D zp=*Br`SF>V+((+Geh4xlgg^)$?@{WNE3YLS$Bi3}R%{rFZ}<0$wI~YbhlkG^y}jKi z3Nt%9f9<%gzvX!$K@iYvT4XY5#>PfafX_k9wpte3+xrxYrNZXs&JXo^3xIRyhUn@t zmtEIYec#7+Jak=WXs90mWn?6CJ)6yZ>HEQ@D2hlXjrZo}F3+b@op@dVfTpS0TGQ*a zEQe;JO)6zFJw5vHrt7M`w6t)cT5Wt$Dn0mSaq)$>E?#_!M#DnWG)_TXxnjS*}OB|tJJq* z5u(%j_lf=elcAJco0vFHUtc%2?Gwk6Ac#0RDp7C4d2@esK-|3+`Elqt@<-8;CcE%v z0#MY6iI;xf-93oPL+- zG*gNjH{PY)ZsR!KifJZaPNg~~EXymU`v))Ie5HG4q+DPqIG_)(%>+jx75@2$`i^C} zg_a$m0SKXxNNBe$%emcb+GZ>ir$4^)qWop=tI=E|oiaKA=#(&~xLPF5wXJO(-JqaO zP0bMm0dX87B}k!%17@Aqvp*Hvt=QJP^reAk5-Mj5NT{fhpTHwTN($>6;2q1g#k{6sNNOjrb)^3KzW{)uKrAS%|88<{;=Z5m!Z@fIzg1o3 a?SBC8VR)#mYHyMN0000h58YIStO;l`IAz9_USgzfs*fA~q< z@wh|x|4%;i>B`HWg$KVhp8Wmt>;H{6|9j5%y!Zb9!VCYkSN{L@{rkR0|8Kti-*n*3 z+Ux%>zWsOZ**T-N|4u&r_y7NYk8S_jPydhH^MBvdf7f6AfAjI%#~=TH{P@9u4JiI( zVPt2pV9)_cg8an5w%1`!frpM%|A{36{@$_0y$j7B?E~q1^t--5T$0aHxEzKvSHdU6LU5n9ELexnj zP(o#~xtW=|p)Z>dmxSqh)5VG_eU!Nv*ruxK?@`&}CB~pEAanGXj48h_zwoZ9Oc#Vt z`S9y&E8V!Mq<`6)U*?<|FR!Z1U9U6OZ{4`$%PnH`@zW=HUk)jrpTB-eiHH1WV7B69 HVz34P-4wx; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/panel_title.jpg b/workflow/public_html/images/panel_title.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b194de09c1afbd21d4dcacb5db1fd54c3dd67451 GIT binary patch literal 359 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{$)g$iO7X$SlbC{|JLP0|PT70}5bdX9G&e3NSD+vM?jdh$b?zu!bg0z6g{S z1NjhHl7WF0WS*oTP#D!jVMeCFiT`gg@BoFG1epaH>=`zhOi3*BJ!6k`h{6D}T z$iX1Vz{1QZ$iO7X$SlbC{|JK^$f*p-fP;Y*C@v$wz{JRkBEu-kED{(r@gh)Gl97Rt z67D?3n1LXeSx8ATrhqp*n3|62?^Kw&09W3=xJulq+_=Ept SM4*;!LbYX#+}z#zb&1JVt$lYygxLD50LVZ#DPMkaQ%h!YzUnOm4-yka~y zFgABH8l~+y@gVUCs{*se1&*S|<7`|(T~}rV9X!cmz^rnC!}y>llLfQDg^tMwPBJ+# zi(KH?a=??B%|y$!>Qh7Taz-{A+XA7+(A9zKl`Kv=WQVPmRrJg02zYRCGZQltgEasP CWK&)M literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/pin-dn-on.gif b/workflow/public_html/images/pin-dn-on.gif new file mode 100755 index 0000000000000000000000000000000000000000..c8ec479657bbe49f7a6481dcb00c6b1d9ee6f32c GIT binary patch literal 252 zcmZ?wbhEHb;=~3;#ug?HlNlZx zlbYKFB{O&qOkC{7Cc&vAA?e_Fd?L4#Rz&2c$6l<8!Y6npELePoMNyJX;lf5mM<&)L zHjN908I2RzcuHbsnLKG+?$6BAP^F;Kv^soglB>X^gJEmK9i2)%#1#EA`w%q>hZUNIgU z7@NB#jEyQJ3LB3z$T?R%x#7@wl0hSwEx^I3@ic>8@*$O#o6;DVRM=l^kzByw$?Q-m nrBJybqhXOp_av7CTUG|Ms7TtB?h<@-q>Y1B?v9p$0)sUG@ybmR literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/pin-up-on.gif b/workflow/public_html/images/pin-up-on.gif new file mode 100755 index 0000000000000000000000000000000000000000..e67145bd9b0fd729b87ac2d49c839aaed4a3e550 GIT binary patch literal 241 zcmZ?wbhEHb;=~3;#ug?HlNlZx zlbYKFB{S}vn8@hH#O=h!;c4{5omGQ*MU14w!Q(6j%m?OZepWs`n^8KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C0rW{kK~#9!#MeQDlyMlx@z1=wR?AYBWe;mrV##hgWLp`E zESnBpN|8-%NgXR?y0kiNqOD_6i7ur>icv($3>6(>SVhudmLamM*cH*`KTKm^@67DZ z%Wt z$1{8m&?`H9V91Rd!^x1~#no;>?a!Mc8-yqvFDH z-12PHV53a5{sb2t(j);RWuajFMHp`^}*=i6YkceRrK8vsOb VW`ScROBVnD002ovPDHLkV1ns&N1Xrw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/plus.gif b/workflow/public_html/images/plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..393e24644779a65989935a9305fcd2bd5f531407 GIT binary patch literal 878 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 Z0RZk=HP@Ix9bo_f002ovPDHLkV1iJXAIAUy literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/pmdatetime.png b/workflow/public_html/images/pmdatetime.png new file mode 100644 index 0000000000000000000000000000000000000000..12098b48eebc2fb6b6021a5725b4d5436a7359e7 GIT binary patch literal 2815 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 VGeHy;7Y92^3JE6?4l6t%06WV)Z+`#) literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/printer.png b/workflow/public_html/images/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..6cfdf4f26e26069e405283893befce206f99fd78 GIT binary patch literal 3255 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/processmaker.logo.jpg b/workflow/public_html/images/processmaker.logo.jpg new file mode 100755 index 0000000000000000000000000000000000000000..30cd0041708df78137e0aa31aa10c31cade9b4a0 GIT binary patch literal 15731 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 LfB!e2M>GEy^Lf`I literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/processmap/contract.gif b/workflow/public_html/images/processmap/contract.gif new file mode 100644 index 0000000000000000000000000000000000000000..90cac8a8b73be20eee4aa2c29a6bd9b6da8d2280 GIT binary patch literal 91 zcmZ?wbhEHbv}Rysn8?5|bLPzd|NlRG_KbmnLGdRGBRc~VgAS0*0Fq~5(rMvW+II4N u((DOdONHES{o?X^xWzEFed()H+w!Uoq^Vt-Z+lK=&9fi%%7r|v4AuaYQ6f(O literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/properties.png b/workflow/public_html/images/properties.png new file mode 100755 index 0000000000000000000000000000000000000000..08881ac8c7b3295d731776b7b773c550ad6e2690 GIT binary patch literal 42987 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 ZI`go=1^q?u-#2XOY8l)t(zyTRe*l{~1r`7R literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/reassing.png b/workflow/public_html/images/reassing.png new file mode 100644 index 0000000000000000000000000000000000000000..90fb7ff404ad0dbed977ebac0ad050a3b469a750 GIT binary patch literal 2242 zcmV;z2tD_SP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igT6 z7Bd^!PA*OW00=@!L_t(o!^M|tY+S_^$A4$$-u3P}wm0iXUJi)~q&6)CD2ehCO~Rw8 zTJnL1s6gUb)DJXLD*=_D2(>DFs;cqu*yIsfKcZ$Bqr|JL2_&Cbnj zDwiuLrO-;DwZe5>+?Y$ub#WXg(llCW9LGV4AX=l8pp+tF8ep*qVl4<!5o%|Y$N|dIMvu=g9cD278x6#pj0XmYf5r* zXpDGsEBQi+_=1H1H~_{Ne6JcoK}FCAWKjw&0V07cb##=ddFzxwEQH3({~WhS5J=+R?jr>C*T zL^an@so`5J6#4MjNt|RdAvbT{OlM~oN(IWaQiw?103@(J)EO$4&;^EarAj7~AwPSG zl~=B!CqhO$kC>pfX6fR^7-RV0=re%}Jm1F{gGEr%*r2f38UpyiOTy^#JfEsprBEo6 z%jKwg9*zzvB@KmA4_jzXCh6?xKxrYLpKWl!^L%{YM_EM>v=&hcYbA7n4UcZARy{ng ziZPbCxl0s_MMMP0apr}gg<38^fMhaBdwL-jFvenxkF|9JJWS{_Yb{18G&Ud$;QN7r zzA-2feBWno?h@8o9LKG@rRL*#GLT3lXl-q&M~JoH`v$NP1ANnf%r{i5!J1%$D5;aN zT&_?qmr+X9qh?-e4c%08ep6G7L_C2Ym@sCIwHV)TxS(3~sCrdw6^u0qK|%=>D}(^j za;bzdCV)G_hp6I6;zlV&EEYp4!CD_{1smoHKk9-^HcMAm2ZDr=AdyTLgr>C?5y5qx zFbu;`B+^H52VyZ72tv?U1=a*Epyq~z5o(R$E^z`$`f$UqMe(8>m3 zUvq)d4X7ndIy%PdDwQvs^E^u|rt9w!35-@K(&=;q0VN^nq>=xv z4HONW&T;CD$Ayy1#Q6eSu1j&l)kzk&yCE{&M^+#xtWVYg^9RD>iV) zwcjM+>P8eb3Xl$Jy>>!0G=Dra%MW&!`NS-tebq{?-OxwYN%Q2cbKJSJpNi+=IC|b* z*NL(3^MkDWsI@u2=!OWeEbE}s3)kLYagWT-U6k;x9xAdKZ2>v#R_BAYh!a&{If6_53uC2m@^fRYEFW}p&Q+NMQaOuH#w-+h|xw_U|g z_B_qnTh?Nl41>i%;&X8xyZSKz21|ovs+n*jth#vxCw{-Dh5$rT2}edMn3jc{nDn?I zU1HPf1pvH#x}ki}K#`~R!_m$)y!-Cwq*4jq|Lk3s_AX_hI6x_1sw+P{d$_KAAUnXb zL(g)sZat4cqz_)aUQ&ZLHb3Ho*8jNRtJW&u;VqDDZ@i+U{g1=#e&x27m)*d zxci^pm>r+(V8)-}q0Wc6uj@YAn%e43eV|z6EkUO`7JqN@ z-1#+3Ok%X?7AhZAST@?t@~NvU(zj;)4}s?aUCRkt zYl_ttvXxD=uiMJ9jW^;X;&lXPM$R($+8eBBnq}LzD>&Hy8;YeFLIM#hpthHQo{f0D5{%d*_}?8_V)Mx>9>P}{l|cFKm{lR74GK&;JMV2)Jiw*QY}@dn^m>OSRSSWf5<5wAf^`5{0 zsofm@ho|MHM`-R|112CY*x*heD(IC4(TGx@G$I-zb0Qkw_?-RSx3SjpZw3yra*|jx QPyhe`07*qoM6N<$f@A4CZ2$lO literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/refresh.gif b/workflow/public_html/images/refresh.gif new file mode 100755 index 0000000000000000000000000000000000000000..868b2dc594ed057242f5b642e0c28a764edb9412 GIT binary patch literal 570 zcmZ?wbhEHbVk&zkko3Jv}`=wY9ay#l;mB6<4ob?da$@cI?=#Tem)b z{CMKTiA|d}ZQZ&xKR>^vrDfv8i8pTCsIRY|JbCi6Wy|*N-TV0QV64I4HT6%}2& zbm{*6`w0mN3l=Q6dGlstV`FP;Yfetip+kqxo;`c!%$e)guh-Pn%$zy1s;cV4hYvnJ zKCfQAnloq4jvYIinwoz8{CW8B;Wca4ELyZ^;lhQpX3aW!^k{s1{L-aMr%aiWnVEUy z$dTEzXYb#?zp}Ejy1M%I?b|bE%y{tN!Rpnk=g*&?oSb~+%9Ws?p#T5>GYkY!{K>+| zz!1Tp1F{?xCk*V<8zPz_mX9^mC-VXy`OS3=Nw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/report_tables.gif b/workflow/public_html/images/report_tables.gif new file mode 100644 index 0000000000000000000000000000000000000000..e12861f84ba794eeae6ea024d449892c061171b1 GIT binary patch literal 405 zcmZ?wbhEHblw=TRxXQrbHTl@;%m3?lJ~(sc%%eX~(q^8y_wh&Xkq;-|Kl}Onf7{k? zlMnyC`|kglr~gYJjxf86A)i;q6vfA9a4Jx{*<`_a1j!nLuXo}K*_K7JFXF!M7W$lDz{&#|ar0fXH-e(CkgWuAC2b93gkmUB0_Gb>4! zS625+Ds{RsGs(8)$udoGW#;1Vt6Ids&o$SDSw?eauBOZiXJ!ehB}=3vHaanDD6Gv< z(AcHRtR}XthJj7(FtdR6eg+PKv&z!y>O8k@-;!27E6U0zDl9B0_*9gSRrK%?<_{k~ Oef0nO?Yo~NgEasU9k4V2 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/resizable-e.gif b/workflow/public_html/images/resizable-e.gif new file mode 100755 index 0000000000000000000000000000000000000000..ba26ebfaeb771d9f4577e57c1068970826a744c9 GIT binary patch literal 65 zcmZ?wbhEHbWMkl9IK;-Vd-v`$XU;r)`0(k|r|;gq`~3Oye=yKt00NL224+4FQ=tWC Q4t^7xd+Aw3B@=@+05@qLc>n+a literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/resizable.gif b/workflow/public_html/images/resizable.gif new file mode 100755 index 0000000000000000000000000000000000000000..18d4c3760ffb38f2499ab9ff49b938c39e283943 GIT binary patch literal 330 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 N002ovPDHLkV1jgbSKj~t literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/reviewed.png b/workflow/public_html/images/reviewed.png new file mode 100644 index 0000000000000000000000000000000000000000..5d16e96f67e6fe58394ca0761e4d9dd25dbf2ce5 GIT binary patch literal 1797 zcmV+g2m1JlP)Px#32;bRa{vGh*8l(w*8xH(n|J^K00(qQO+^RU2@n+%5w%{@QUCw|24YJ`L;(K) z{{a7>y{D4^00xCgL_t(|+RasIOjKtSeN6!s(Y8NrP1CfdO{>OKZK_Q)F06G2x4J@u zlGuWhYD(L*u^MeuG*$%J6g9PVDb*rwI1D4hzFJwrBE#-5FvGCU3y8k$g3Q;mv>N>o*AU}(`ID?4kjfK@{apoMEuOAGUYweZRC)%a~G&MnMN0Uy6#@feNbEE>_T&TyPzuT}sUXP6@s!&@~`MiLo(zlYUG;c@& zRhnwtzI_KNss~UcC!?si1c`~ake-=|+}u2<9;DKHB?<})k(-xCzZVPg=9U)J)jY=P zgT)ApX+ZF~Is~7s#g@=AR6Tww;4|v{zHfprri4s^ugSW+o!& zp*I*{Xl+G{UN4~68_?L;fQ7qL;deA2Yxn14{ee6z4pxh?2>~;thtngcBhiqEu(B|l z6d*zJkX)Y=z*gVAmxN^MGF6?1{DMLx-B$=Vva@rLNpmhKF6C!-L5OHI8llWrV$H#o znCo{5t3p&*^7TEq1|?yRZvu4M7I^;TX`Auubi|d#A*wVAv1PH?tJ-Uuv}KZFkOTFN zPiWR!*#+)i?vy)c2vUJoBUA+{NSh>_%sByR{i~R@F%}DV{Dsx~?qJ%oOW1I9EoL5@ zffG4LaU}gPeo-Gn;LSjrv{g9p=^z0OjamYSO$1D~o+0jK^7i%)6qG$AQV9V!e6c?@ z1lz8zgQJf#=59F;w_OT2dwqi0hi8i4en{SnkbA+{n;2x1whQuwgEGJ~KY#uL)M;uF zu(XT}8iksk(}dl(5)+ZERMKb)prW9D@$)9Qo?3w5TmIN{_e<`C&&S2wre``bY_$L)@gJS8`ocu)qoOSYNACc15FLmPqb+uGaF(b@`2BpMfhOXd)S@gjR3_e1l(DJ1BzhV#O=;Z zzU+ku5nG>;ktw#AG9`tAmyPuFbZ9ghuKdjRB8++Y1<20IMp=0oCa#+VuTyj2dv5`@ zCe4Fi>U``{ErMV2d~8UVh0VXup}@I7@{+unY#0HJ95%9hV4E4K^Y)Go;XsGIYpy1< z877kn-2_v&3Hnw&Ciu9({rEJv-gSn%Vj?`0E^t%0!29}COx`dV(p>4s5szX{yh4$T z3_5r+36+(VNT(d|G0R6V*WBD(c7nyqqYxr=hGsaen1HpBAHlnLGU0XjroV%69*+1k zJ08Tbcq9RoeC^Y{ZIsi_b0-(LGMVU_(AC{N@JyATEoKXeXu>P*j`00$CW18YV%!o3 zgxx$n`j3&eNgS(8%tGYg$s*W(u7cFk(*v``f*z_2tJR9$UMrefb)fSNZ~9EYvG~xj zeGPg3O4?>=X=x&8n(AugQ6T?$^hlh16%`dIDk?$_jX|wei{Bp6Z*n-x%ggDcETR9+ z#MN8Z1aV(q-{=MK7UaNjmz`uUR}LI^YPNSwpiXwWO|??+M+KMzUHmE9S=0HgfLwcFoq4_;xRg|=M}&YkN;Rh1Rt;eAwlX&g+>=$9)) z7Q;d1b;jU;eg0;%Stu_lwc*MY;Mz6dMZdKXQ96HRW!;OyBLL`O#> zA|e78FJ6RBrz5ATs3FTJ1iXZcI%o2cN8se-G>!kjj-__E+TliUx5MKZc-rA*$LDq| nvtv17g&iv$930-4{*TwcvL=@soIFMl00000NkvXXu0mjf8BbHT literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/rotate_cw.png b/workflow/public_html/images/rotate_cw.png new file mode 100644 index 0000000000000000000000000000000000000000..8af69cbfc0d361b4fe6b37f52d8edf663573adcd GIT binary patch literal 1817 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/row_down.png b/workflow/public_html/images/row_down.png new file mode 100644 index 0000000000000000000000000000000000000000..992794a38cfdd5034c61088e604b2089f64802d7 GIT binary patch literal 1164 zcmV;71atd|P)P000mO1^@s600001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2iON3 z6)hVo^zuyr00az4L_t(I%Z-#xY*cj=#n1n}H`AHNOgmF4Fam|v7FtPdBY_m6j-rBz zwn<4y42ct?h{1)51{Q2hbmz*bk;IVEgv14YEKFI!1PQ^CLctb+U>%`DTRLew^FIGy z*Tu972_@Xs-Q4_g?z!hOJVL#9tThd=zQ#nRFP+FdMTCUo&5oC*Z+_2tc=Xr@CH1g* zw%8o_wq-qlU8HgJ>wV)I0Ny>iK3*5K_jj!AJ>1jsQf6giDB9@>arN(W>df$o zud3C#!^e-z_)9^|#b)!X>D@i8FMl~RH&O1|6~D0gwTAZ9%iDkG>wSO!){Xu3N&7LT zNkXUqTzUwVk66q$;<3b*$*JOomM!|^pJzh;P{@mWIzJqE?%>mQUBiyQZeOxH*KPZJ z;F*uQno?_-)Eq*E5Yk5|J%qwVz^m{@6@~>CUuJKbo}B1y?pD9vI4`{iu50gSO_5D) z+s5|nJk-X(Fg|e^&8wb-Wm-_App=AEA-D>`rH6n!@Oc$ZFpH{RM%6E4X10W}3xAAM z%Fcic)p#NQKg0q6$yNLE)SA^kpNGLLJig)y2pxhe4@yf&%^_rfP12Vns{3TX1=*8oIjy4BrRgf!vx(HN~qz8H^cVjDbi)YYjybO4ZiI#ex#y zB4#F$u4}>d>z6S+dK%N^TToge60_DtV%A_bCv$~72LFT9+l|>+ybfMC55|lIKHUQm z3!VfBg%9CNjE-Kxm9g{Mb*p2fbiTeRaXa2%f8osqjfTORqITqXHYZ*$KRxgIO4c1!F-8fk32do-9CaT)T?V;foZwe2_F9DCAMR z_lkb}v~ueCH(4KP`k93)lgcEU1BdUmh-llgv>kPVSs2W$d9nbxUkL{@6#|F$@?ignC6uHN^TqPM+=PZQE{HktLNZu1qNbtu!ikT`FCh z`HB1DokAYvrQS(4hgAS(%(Y$m+2pEtk0cHuYZnACB%+PT)NjC=hD}IDRshO`>r~*m zJ`B@f(YV#=%>`5A7wOzmkm3lO;s~@Q0(s)rmB}}jrQ;@J3?RUcrZC4s6fpsz0=WJh zga|Qf`MVRRaJ@7P?$-Gw(xeR<(JWpcE)MIz`>@brj)$& zip+j)pWx~4?f?J)A^8LW2LK)bEC2ui02u%m000GMpeK%GX`X1Ru59a;TeVoPSv84M zmrIgNJ5t9n2?UR-fgzX~I1L&EA|j}^1}XuvM(7eml0tzZf|wyG0)rtD6)qe_Sqw-& j9&JzIfRTG31rl{A5`}pRh-e-FjDuT`kdcy;EFl0p*WO_q literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/run-build-file.png b/workflow/public_html/images/run-build-file.png new file mode 100755 index 0000000000000000000000000000000000000000..a19d5ff4fe5c0632f7f63934d48def8204a12a97 GIT binary patch literal 1649 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/select-icon.png b/workflow/public_html/images/select-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b8ce81f4a2c36230997271f4339c443d4bae90a5 GIT binary patch literal 1350 zcmV-M1-bf(P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igM{ z5C<8;6CG#(00hQKL_t(I%Y~I)h*V`5$A9npo-^m1ncdl)+1Z`_a;r^KTSZg1EGw`= zf(#<8ivl6Ai!y_Vgf1+I=%(l*y9z2Ox+o|k%EF6?Fq29v6hmEW&2`;%Kj&l5%$$$+ z?P6xfkH{W4aCpyoe(#_EdH>H5y*mIvYY;T<4M;<;lT2(*x3z3(ZEsnfaP4jcDh#5+ zLSf-_alZV$U#{-ghGRn3dkr7~1ct$+oG1FO>)zQl(6P!(yGSKKn8vmOV+_@W zfSK{R!q}e|J}S)mZ%N5X#3it5T~~kI7%(xto%zf=L&M8&XnqQFwo8);|r52yqoSj_B;}&3-g=`?9TGyF(mB=y*}(zpE1Xgkgx| zCg|+TWn&XQFn_UpOv33VIF7K|v#Gs98<#)qq->%v=2~TpVIX}Y0CSZoViS??>GCSo zg}aI~)dNy8rBZ9avgAW6)(yUz$){x)ME?mC2x?K4b~nfF;WxRXZwvWkKS3N&istb$ zZrkkCTqgAOerXJuOuqGnj=qe#78Jl>2y~TIxeW}Ym$I~dh;27L$@ZI{0}U-LNxE*x zK4JvJQrY63t|i&qq>>n8t_jvA!j=xVEUG(o2A=gt*~ADf7LG5P;LWVUM~Ql z4*2@7k12-pB$R{J8cW%@X{+0^Ju9n(tj7ij;wq62K?nq3NgG!s33Wgvt}v7vZf^3! z`2&12`YD}W4kcCNj0;pkXe-u{Fb%3Un)Ug+Xmhd{1CHf!V&*7ECJ#{z=4f-Wtj^sE zKsEB&d-P?_6wXo#X6W>K$v7QIsnEt?RVu+uCG^R-9YkTsKzbREuY9(t>i4N1IdFDA zQ@+oGH$Fzz?F8Vnk#{*Vb(9txN@1CDc#49P!*e|<)tXePwfYX-?ypw~MG)8c?%Y@W zUHXfSJ)5y*f_$o<>B@NyjsL=)jju6~Udp6D#-4*uGat-iOOTBi`;kvMDpDKQXH|L) zo=%3_O3tj9^JiIzsvMp;!iDk(clOMGhC_-6C~yS{ytbEOgbTL%HnhbP`=10}G9?+bO7Z|iNtdTCz$ck&h$+>g4Eb(PL-%Ai0wJR1!=?Q&KU2wViA5EQceLKjB@bRy6FW zj#8+MvK{yW0V=(&Il9Wa!naX@LFKYSrRpj$bH(iOf8XBgKNRtTGnOw?6b3T&(KKNFy-8TB&|@ UThUk5g_BG9uk_4F7h$jl078=!f&c&j literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/steps.png b/workflow/public_html/images/steps.png new file mode 100755 index 0000000000000000000000000000000000000000..d1e2d87782e50461ce7c2dc714a3d27490a92ae4 GIT binary patch literal 239 zcmZ?wbhEHblw=TRIKseSo-?C%!<+c2Tem)WQn~BO%rpO;E0#{Z^knPJ|Nc!|&OH4e z(|>5no+lfw{ZE^DrfuPg<+q;%cCFZT`+w`^3vD~z9e?zH;o1K$-@RkN0Th3-FtP)! z(gDeX>||igd7#>tk~uG9)w-P5`(8hpVx+^vRQdefB8~2e{5MvIbWCp*+}Y*8cK*as zPFas|&K9wS6)D@hShhLl8OU^QidHq-)3-T;9z58XJh4H zXJ_Z+|EI`$@KzRlhK~^C}Lq|5@z(jVX zLJ_0Ji3>TDoi-j64Z8S2#W<;`iIYoATtZSxRZU$(Q_IBE%-q7#%Gt%$&E3P(D>x)H zEIcAIDmf)JEj=SMtGJ}Jth}PKs=1}Lt-YhOYtrN?Q>RUzF>}_U#Y>hhTfSoDs!f}> zY~8kf$Ie}c4j(ys?D&b3r!HN-a`oEv8#iw~eDwIq(`V0LynOZX)8{W=zkUDl^B2fp zj10^WZ^3 zTeRQm*I~QIHx#FYFRwpjyQuzxy#IfO11bL*xU}#6X9%}{`TpU529}Tex7WYC|M)*J HvEBp#?OO2; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/styles/red/bsms.jpg b/workflow/public_html/images/styles/red/bsms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e7f7c7bf8b7afc9c1348dc0b2cc919df78787fcb GIT binary patch literal 1186 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 z z8TbhR#2AAt%P^bG$mjE8iXy+7ot^cMjD$Fzw{!r~JDrY2$!4(lda>wo_CH7@67Mxl z!)R#y6p+beKtyP_+gMxs(zn0A_qe;8zj@JSvs)|{s#R+Tny!5g4hNqdw~q>ggM;8W z4x^#*vnm6?$;k<C0+E?Os zgb5~A{s2~x;2-Efx9%ON1Z*9(Bk8Bv*W7rIEv&OTZLkiGi8SZY4FVSZm~?2| zN>;u-tntuy1ZKUuj9eNhSU{9Ch$L$^jj-Dy3~Z359~NZ*fDC-EC_kI3s@14WHvOgD znACS`j=S4(3!Xe%%33Mn_&0g%s~uOxC$G@B3AI9@09768dX6J<$xg^{nhTT3o|AJwHc8yrkC;zGApGJDy3LBRECLN$ ze{(n*1PYVBcw9!9;s|Pr3J0D!(c(r_jtOQob|`I^t{ev_*YlQOUIGoH4*A5!jFf~P zIdvwdX^v(f!$4E!iwpc7=nB0`J-@MYnQl7T6v`Knq4nt(Kz+Ieg%B5n>8dXFbjAKZ z!8~`MSF|0syT{_WkhDoaLY8pNw9A@#E^5#?z^vp4xJh6XHZ3?b{xiQ`*1RluS;9eG zo~J%I%4?Ynb-xz(J*U?hL=Hwj@C)RwxE#7gD}D#Z4~V4BKuv?HIsHD~;)scgJ?CUT jy3rQCJ>flCYp8)FWmiW2e6?>d{#~jp)a=jmuipFxLzztR literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/system-search.png b/workflow/public_html/images/system-search.png new file mode 100755 index 0000000000000000000000000000000000000000..4f0da0097b92a791e299dd535ea55e820a124b2c GIT binary patch literal 2584 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 E05g@O=Kufz literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/toadd.png b/workflow/public_html/images/toadd.png new file mode 100644 index 0000000000000000000000000000000000000000..651c7f1d79b4b14c8fb0ff9a31c7ad72a994a2bc GIT binary patch literal 50814 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 W=T>v#Q{gKB00003R0f<0jNnFXc)3_pm1Pf z21-Z^0xbd|1Yl$mWL7d1`hSao2Ph8Y2r}3+1S}0+;I+(UvX)5t{n{y3kNZugu2|_H zyi&I8NTc^+(P>A`=7q7Is+ARIewgE!w;*$77|Vh~^Ei4=1O??L1nK!1|D04(mSPyT z*lw}n<9}t2TMvls{I}{xsr;OUrozdoFL=LAPP(*s@o%fkner3+9y>1d&af5ZHGI~0 zI(OO?{wq8lEn#16o3&0A=BjUD;TCe+m9VKa^3LMfsq5x6%!=+7%c*Bv@JOoY(W9-~ zuH8B45%8`nTq{QKLtnp+Y=|+hpUh9gh)D}B^R3*%yz-%^LiYI_<)G)AgO_hKGg^1~ zdtz&C6zL+MbMB+L3a-V)r(k zSJkO0^S|Q$91#kokJ;p3GLB3z_F#IA==P z>@#_{g;j++XFg-kvhb5e%vx*0V$?Q$Uvn!YZyKZgk*^9j=EdxKv2s#u=aE*$*jb_J zQdTRMmb^T_?(y1_pZ9v1TMK*&3#r#TG41hWk!3PAI!C=aos+)r+w;dN{)w@>a1$>scV;r0{>pIt&hD|(lD2JBF7h>-~h z+LYp9+4$=8r>lmK@(#uM9=3JcHJ|zP=PsM`dOlHCrY$;AIqlFofm^3s&;8;FEnn(> z|7q>h%7j`#&v>3(aUz4&huuao2y=iYs{^BNC@1RfEaeZSS|SO4!MN2B*%{rgY- zKK1$d?n{f`f7(^+S){3M0%>MP;U|Pv@W{Oy0z`vt}RzpxipPr6dL!h nDg3x>kxh9;nOnBs7>YQX8qL*c{PrP_DVPr5Luh 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 H5%to)yLr|q literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/trash.gif b/workflow/public_html/images/trash.gif new file mode 100644 index 0000000000000000000000000000000000000000..a627b60fbba2fe43fea010ebec4d246d363e9099 GIT binary patch literal 872 zcmW+#y{c4U3>;XwXdzs+S-~QL3jSdscm)y01+PC?T3Y13gSCu}D2Q4JVi!bi?IWZT z5dNJlw(o(U9OJs2URP>mI^00SOSAOabv01}p9!V^kF zA`_KB!3r#RL4_z}p$Y(P)}apwV_I2YZ)rvv-6&%i(^$r??R1BeB7;n_dVte>vhI{K zoaroQlQd1KixNXjvBYL>G5sD?FoGGZV9Q}SLp`ZvBr{pb*2s#DuWw+x=XHbrK`M0c6S$cZX%?VN@^!8 z)O@^Cp$KKDLT!(wnxuDKDpHxMRC{KnX71fwic*%Ugt-?@uifsV_OR`0XU0Xd(ZX#e zhGklowK?s>2;>}?7dHhcNcap*MAQpK1y2mWm#jrIr{8>9jE^s>NId^9`jA$@NKM*oVxp|aN-1ra1S7Dj} literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/tres.gif b/workflow/public_html/images/tres.gif new file mode 100644 index 0000000000000000000000000000000000000000..c170909ad16805fddeeea160a174757200bbc02f GIT binary patch literal 671 zcmZ?wbhEHblw^=(I3~qlY;64U`|o3KzI1kXYwftA+rMzyotK`6Z`E9Rs+*Gk@Xfm| zM~-iO_Tkg-zn*i~Mkgj4dIxB4I30KD{)yZ7wOgkjJ$G)-s&!Ak{k-<^dsgq1|NsA| z?Z4>b<1^>pYh5Qdvpv^+x~6$=JCk$nq1L=@i;tgs@c2pBjps9G&RqB8UF3C<`3R@mFy?>Tl-d-;BY)B>0E zynFAzr=GqafAW6m#m9~ZZY+KHcHPNydQNU<&YVe0OFMJt!L3(sEw`QnI-dSOhXDvc zalyd;uR*G*xuvzOy^U8~!oosZoVTN$X$q5t#EgDMM%_tG7E^mAw3mo8PMoB@uy@HU zt9ebUnbb6uWOe7x)19&?kY)b?%MH_}FV^M@HuOGVJjtqe`cf|DCh7fplV%*7(5kdw zebU7xJDb_|dxlJwTDzjrm7jM3B6K-fPdEv04;G&-lJCDMv3yg_QlV(V97JO=X6sF-TAYpLvF@uPV V2>0ENrUNaF+^m_8mAF_KtO3yKiwFP! literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/trigger.gif b/workflow/public_html/images/trigger.gif new file mode 100644 index 0000000000000000000000000000000000000000..9557cdf2a4c4be732a9d366191d5f8345bd1aca5 GIT binary patch literal 310 zcmZ?wbhEHblw=TRIKsdXl^C;Y*RGi}XWqVjyL)o?h7B8^{(pMm%FVi_y6G#YFFU+_ z>5gS*&Yb!G|9@e5;o)0{moHy_KYsjRzzr0CvM{nUh%xAZ zlz{AHVBNexwJ#-eUdF0*Ij^S)IeM%=A+pGTrzyffhpmy3)1|D3!G$A4Ri(c@MKD%l z(Igh{0Lc(O>-F1@Yq9K_aFXQ_?}HGoBT64V1bEn(Y&SY+1aZW<^YOOw@-Yj>ax@6` zF>|!>HueejXmInD1#?!^7;^G)YcmPBGcqwTb_%3ubJ#QTcx+;wu4N>`$yrp!5>lqk oD9psivXqsHg@Z{rUyGGRDLYe%<-8s@1H)p|d-oscD>7IE0JKqOk^lez literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/triggers/Google_Calendar_normal.png b/workflow/public_html/images/triggers/Google_Calendar_normal.png new file mode 100755 index 0000000000000000000000000000000000000000..427e132d50c135a0ac6ad55d60340981d7fc10fc GIT binary patch literal 884 zcmV-)1B?8LP) zwa~7@%K%rd-P+3`cfkW~)8ygN0%OAiYRw0Q`zV+C27>egPmuv#xYW|c1a;t}wYyV> zux*>dEohMic;!)##^Bw~c&N@*pwKOW&N_y~zth{=*vV9^gU=xkK7!N^UvS#5N^lN&cPCDxd&dV)!5C~ z)yE!i(*tM3O`qV<>Hh##t4Ganvj6}BN=ZaPRCwBq)M;~~KoADtK~Ck^2yz*`h|$F? z#yhMrJOBS*rRPLYxAK0Rda8T6hXVb3`o+?Rlx3-D+He?#oleKLZO>b+Tvt(oKraqR z$eIpsXaLkI(6xL_b=|TgwJSv{Z|KGMF{fBiA3-#JRY@=8)Nj&~oS{li#i&OMpeD6B zZ5F*p`+Iu!(WaH87NvCdDIBGHAqAbMa6A>X&$53RzdW^zdfsk4{yMTmL{RI_}%erXYpHhuw_+`wti#3kt1wLT;Qn$WcaQH<3j#8jAdWUo76uH;|42 z?V02hH)t3pW{fKwIgVq(MI%b{L>A>VB)L=`%s%2Yj#RaqGm04vMLIO|H=qXWDe$d? zP+3$^$|k01IwS?#Xp-mWL`sZ0bw&R5Cy@JGRA`2gUt z3xxncAK(vs;G?^}x3{NV13HaB>r-H86VPh4?Mr}Y60-Bxx?C=g@X`;gqXYs$(- zJG*(o)MpEiUXu%QRf~#;$b^e*Vl`>6HDMXtPKpGMmjNlPN1JtFhls z(orB7MvT1iE-q${ZeXg_PHF?tAiE^$xF#Hjm5O|LN{_nM=+2k>WHM=oS}IkP%hc>1 zZL7gx*xK5fGYS@0+bSw5I_Co)uJ}px*skZF53XW0(}|BZ+>}%Jt|z1-K8B2)J_l~m z>o8#ss`wMXa@#+R^nV-|7sHmgUb-AX4XwW?rZ)=|Ng+ykM_rq$LD5xrAxJH0E0N0U z#1E>+>JJ$d-iz9_hw~|v;Ps2)%bIyg%+a}xkt0=ARk6nx5`!1OFATa(OSQOu<@Mm~ z?Cj4AbKm7q3xCL&HC5#1WhAA>CM6}k+ueHg$LQkH{I#1TgK7AuXhN# zx_Y~qF`f!AsOc{IH(tp*eYYIvsMPj#Xf!_#4E2b6Qd;`K#!7U{Uzku%nH}|=cRYE-z zZijJQT;qw0k%;N4Q9p-vHfonMH&aHzaFB_%BB5~NAjdLZ?oUQAQ6APiLjMVo4xcOx zVx8WEN#YpCVAq{WB^4Mh(mIdqPUBGcr|{;O7@C#E#cxPi?ujJ%Vf?Wxe1h=mm~AK* z3*s4TPl-qn9tqiAjXL0x9a%FOKUK~MN3?`Z*i%6p!a1^uy=m0@!0rvEW{r$YK4bX> zY6E*LU>G7QHzCkV1Z77TE4{XJ(wRgzN1xaU0s~g*cERY5PZf`g!ZJf<_>G$<${=kH zY$Sm}s)$GRwJ(LQ*@99SAt)0o9A#PJ3fWtH+Ur_{P3{C*VsiGdaq!rmo02N}mtiTg zN&uP%AC7#S@3612)#F^wRJ{LLwa{00|rjpGH9PH_op@?$cRh z_(^N92p!!`jjpvQoFS3&$uxQ?u1>{*?e`0m0zNi09V#J!H4NJhKr>te%qv8nZCfq_ zT|+;}guXzTbeH@3@fj8*Nl_*#P$eY#lFYnaZTS>##h4X({scl^w`YE{oW|s&PE^#syxijCtU^3|lC<2~+^oLL{QmsJ%FLw33_hN`fsyOp%h4l$De*Eh9USmYtrGF@&F^o`s}L8g{B0q^6&JYg&5+ zdoy%)pRSc72>{OcsOavZBtC97%A8UoO^7Rh#2n}Vpo+?#ESWIl^FpT4 z0bLA8>ChoZ6{j7l$jM+4qei1fheY*}vI+n>K&!sIigjZGuRrCWT`4va(XzNQhn(pd zwS$kjY+G7|yHSQzsXbLjrK5#B&RWF{DFuy7H&tKbO- zlF(7MdlCZzUYN@So?``?5J$SX+||QK92R{^gU|sd*|PDSVqABi=0u1!?K&|#bt=M+ c{QQlg0V6F0cuEV6v_Oa=3^wRrfq?)3I}$~^Y5)KL literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/workflow/public_html/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png new file mode 100755 index 0000000000000000000000000000000000000000..81ecc362d50ef5abbc0420aacd5345822f1f6098 GIT binary patch literal 3457 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 QVoz;Zd3kvNGZTX~0GEg4!vFvP literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/unknown_icon.gif b/workflow/public_html/images/unknown_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..b139aaa076ba1b095994ca38532a031cdec25eca GIT binary patch literal 808 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/users.png b/workflow/public_html/images/users.png new file mode 100755 index 0000000000000000000000000000000000000000..b70f90da3a194cdd9b92b08acbf28153358feda3 GIT binary patch literal 1145 zcmd7R{WF^f0KoBwDxukSs;hHn-R9iTb?e;KM$3k^#7j%2r}Z{f)a$$@UK`SgkUV*$ z$RkoD5g`a7^4>&9B9TfkuF~kZVCkx*b=_{Sx9z&?f3fdh@cHE%8y6EAmg56>1AhR( z=V9T+H0dz@dIg*yRnHccd^a~;MY$0QPTNQZ+>qe&69zjPbBX-wD}megm0#B; zxoSE?TlsXB*)sVE+n+;~?s2D>M*F`yqmfiw2;#mO(Lzr(uz-*=C9 zto!L189d3uRjZXTrm?O`({H1AddI=uYEN&!ZINC8)yQUzpfK-FcZOvc50Be6KytiDYvkLS!&R16GFQ7{0Z&Fc$uef6Zlk`_T$Y%Gdh zo!n5KV_e*vQ0QuyD!8AE<0f^mI@{%T5?3RJZpoLGqe2n64a2tly|vOM870&woWiwc zch5NJ!W!k;fSwQG22J>aP+IM!DN?qKQTlp+X-=<)Rb}0@CgU_|YPpNkn!+Oa81a)I5Ul zW;6eqWEjE7L?V!d zPz5H2Rgyaqxkttx<9S^zR^B}`B6MV6ce;OGQaGdXhu6fCY)Wo*Ikj z^{O<(p2?8zI7#~_s`wm4^l%T6mqx9R>7qlMKDw&s2v{DYg_--Uu*oh7e!04L<94zjnoBg)l%DAW1t)}yQnXNte83vl5- DgMS8^ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/yellowBackgroundMenu.jpg b/workflow/public_html/images/yellowBackgroundMenu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..465b1e0f3f3448c2d2d3b67f25acbc8a75f6e7ca GIT binary patch literal 349 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{bod$iO7X$SlbC{|JL9(5Vb4fQ20>EGxjk$i$8!&MeHrE*=yzi3*BJ!6k`h{6D}T z$iX1Rz{AWa$iO7X$SlbC{|JLP*r^Q2fQ5|%C?O-jz{J3gEY2Xz#LOxhGU*~vR)Ud{ zfte9SmYIc>4Jacf2=qFN1cQ+9|63qyfwnRWGT1Y`aG4{gTP0+uS>#(2y29hg(wAli dVGEU+W}NPI*2?=>va4gq6{BVE#U1|N1OTE(Hxd8< literal 0 HcmV?d00001 diff --git a/workflow/public_html/index.html b/workflow/public_html/index.html new file mode 100644 index 000000000..7f9a643e6 --- /dev/null +++ b/workflow/public_html/index.html @@ -0,0 +1,8 @@ + + +Redirector + + + + + diff --git a/workflow/public_html/skins/JSForms.js b/workflow/public_html/skins/JSForms.js new file mode 100644 index 000000000..b8c975817 --- /dev/null +++ b/workflow/public_html/skins/JSForms.js @@ -0,0 +1,496 @@ +/*if (window.attachEvent) + window.attachEvent('onload', _OnLoad_); +else + window.addEventListener('load', _OnLoad_, true);*/ + +//function _OnLoad_() { + + +onload=function(){ + + if (self.setNewDates) + self.setNewDates(); + + if (self.setReloadFields) + self.setReloadFields(); + + if (self.enableHtmlEdit) + self.enableHtmlEdit(); + + if (self.dynaformOnloadUsers) + self.dynaformOnloadUsers(); + + if (self.dynaformOnload) + self.dynaformOnload(); + + +} + + + +function refillText( fldName, ajax_server, values ) { + var objetus; + objetus = get_xmlhttp(); + objetus.open ("GET", ajax_server + "?" + values, false); + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + var textfield = document.getElementById( 'form[' + fldName + ']' ); + if ( ! isdefined( textfield )) + var textfield = document.getElementById( fldName ); + textfield.value = ''; + + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { +// alert ( objetus.responseText ); + var xmlDoc = objetus.responseXML; + if ( xmlDoc ) { + var textfield = document.getElementById( 'form[' + fldName + ']' ); + if ( ! isdefined( textfield )) + var textfield = document.getElementById( fldName ); + var dataArray = xmlDoc.getElementsByTagName('value'); + if (dataArray[0].firstChild) + if((dataArray[0].firstChild.xml)!='_vacio'){ + textfield.value = dataArray[0].firstChild.xml; + if(textfield.type != 'hidden') + if ( textfield.onchange ) + textfield.onchange(); + } + } + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function refillCaption( fldName, ajax_server, values ){ + var objetus; + objetus = get_xmlhttp(); + objetus.open ("GET", ajax_server + "?" + values, false); + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + var textfield = document.getElementById( 'FLD_' + fldName ); + textfield.innerHTML = ''; + + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { + var xmlDoc = objetus.responseXML; + if ( xmlDoc ) { + var textfield = document.getElementById( 'FLD_' + fldName ); + var dataArray = xmlDoc.getElementsByTagName('value'); + if (dataArray[0].firstChild) + if((dataArray[0].firstChild.xml)!='_vacio') + //textfield.innerHTML = '' + dataArray[0].firstChild.xml + ''; + textfield.innerHTML = dataArray[0].firstChild.xml; + } + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + + +function refillDropdown( fldName, ajax_server, values , InitValue) +{ + + var objetus; + objetus = get_xmlhttp(); + objetus.open ("GET", ajax_server + "?" + values, false); + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + var dropdown = document.getElementById( 'form[' + fldName + ']' ); + + while ( dropdown.hasChildNodes() ) + dropdown.removeChild(dropdown.childNodes[0]); + + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { + var xmlDoc = objetus.responseXML; + + if ( xmlDoc ) { + var dropdown = document.getElementById( 'form[' + fldName + ']' ); + var dataArray = xmlDoc.getElementsByTagName('item'); + itemsNumber = dataArray.length; + + if(InitValue == true) itemsNumber = dataArray.length-1; + for (var i=0; i'; + } + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + + + +function iframe_get_xmlhttp() { + try { + xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (E) { + xmlhttp = false; + } + } + if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { + xmlhttp = new XMLHttpRequest(); + } + return xmlhttp; +} + +function iframe_ajax_init(ajax_server, div_container, values, callback) { + var objetus; + objetus = iframe_get_xmlhttp(); + objetus.open ('GET', ajax_server + '?' + values, true); + objetus.onreadystatechange = function() { + if ( objetus.readyState == 1 ) { + document.getElementById(div_container).style.display = ''; + document.getElementById(div_container).innerHTML = '...'; + } + else if (objetus.readyState==4) { + if (objetus.status==200) { + document.getElementById(div_container).innerHTML = objetus.responseText; + if (callback != '') + callback(); + } + else { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function iframe_ajax_init_2(ajax_server, div_container, values, callback) { + var objetus; + objetus = iframe_get_xmlhttp(); + objetus.open ('GET', ajax_server + '?' + values, true); + objetus.onreadystatechange = function() { + if ( objetus.readyState == 1 ) { + div_container.style.display = ''; + div_container.innerHTML = '...'; + } + else if (objetus.readyState==4) { + if (objetus.status==200) { + div_container.innerHTML = objetus.responseText; + if (callback != '') + callback(); + } + else { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function myEmptyCallback() { +} + +function disable (obj) { + obj.disabled = true; + return; +} + +function enable (obj) { + obj.disabled = false; + return; +} + +function disableById (id) { + obj = getField(id); + obj.disabled = true; + return; +} + +function enableById (id) { + obj = getField(id); + obj.disabled = false; + return; +} + +function visible (obj) { + obj.style.visibility = 'visible'; + return; +} + +function hidden (obj) { + obj.style.visibility = 'hidden'; + return; +} + +function visibleById (id) { + obj = getField(id); + obj.style.visibility = 'visible'; + return; +} + +function hiddenById (id) { + obj = getField(id); + obj.style.visibility = 'hidden'; + return; +} + +function hiddenRowById (id) { + row = 'DIV_'+ id +'.style.visibility = \'hidden\';'; + hiden = 'DIV_'+ id +'.style.display = \'none\';'; + eval(row); + eval(hiden); + return; +} +function visibleRowById (id) { + row = 'DIV_'+ id +'.style.visibility = \'visible\';'; + block = 'DIV_'+ id +'.style.display = \'block\';'; + eval(row); + eval(block); + return; +} + +function setFocus (obj) { + obj.focus(); + return; +} + +function setFocusById (id) { + obj = getField (id); + setFocus(obj); + return; +} + +function submitForm () { + document.webform.submit(); + return; +} + +function changeValue(id, newValue) { + obj = getField(id); + obj.value = newValue; + return ; +} + +function getValue(obj) { + return obj.value; +} + +function getValueById (id) { + obj = getField(id); + return obj.value; +} + +function removeCurrencySign (snumber) { + var aux = ''; + var num = new String (snumber); + var len = num.length; + var i = 0; + for (i=0; !(i>=len); i++) + if (num.charAt(i) != ',' && num.charAt(i) != '$' && num.charAt(i) != ' ') aux = aux + num.charAt(i); + return aux; + } + + function removePercentageSign (snumber) { + var aux = ''; + var num = new String (snumber); + var len = num.length; + var i = 0; + for (i=0; !(i>=len); i++) + if (num.charAt(i) != ',' && num.charAt(i) != '%' && num.charAt(i) != ' ') aux = aux + num.charAt(i); + return aux; + } + + function toReadOnly(obj) { + if (obj) { + obj.readOnly = 'readOnly'; + obj.style.background = '#CCCCCC'; + } + return; + } + + function toReadOnlyById(id) { + obj = getField(id); + if (obj) { + obj.readOnly = 'readOnly'; + obj.style.background = '#CCCCCC'; + } + return ; + } + +function getField (id) { + obj = document.getElementById('form[' + id + ']'); + if (!obj) + obj = document.getElementById(id); + return obj; + } + +function getGridField(Grid, Row, Field) { + obj = document.getElementById('form[' + Grid + ']' + '[' + Row + ']' + '[' + Field + ']'); + return obj; +} + +function getGridValueById(Grid, Row, Field) { + obj = getGridField(Grid, Row, Field); + if (obj) + return obj.value; + else + return ''; +} + +function Number_Rows_Grid(Grid, Field) { + Number_Rows = 1; + if (getGridField(Grid, Number_Rows, Field)) { + Number_Rows = 0; + while (getGridField(Grid, (Number_Rows + 1), Field)) + Number_Rows++; + return Number_Rows; + } + else + return 0; +} + +function attachFunctionEventOnChange(Obj, TheFunction) { + Obj.oncustomize = TheFunction; +} + +function attachFunctionEventOnChangeById(Id, TheFunction) { + Obj = getField(Id); + Obj.oncustomize = TheFunction; +} + +function attachFunctionEventOnKeypress(Obj, TheFunction) { + Obj.attachEvent('onkeypress', TheFunction); +} + +function attachFunctionEventOnKeypressById(Id, TheFunction) { + Obj = getField(Id); + Obj.attachEvent('onkeypress', TheFunction); +} + +function unselectOptions ( field ) { +var radios = document.getElementById('form[' + field + ']'); + if (radios) { + var inputs = radios.getElementsByTagName ('input'); + if (inputs) { + for(var i = 0; i < inputs.length; ++i) { + inputs[i].checked = false; + } + } + } +} + +function validDate(TheField, Required) { + TheYear = getField(TheField + '][YEAR'); + TheMonth = getField(TheField + '][MONTH'); + TheDay = getField(TheField + '][DAY'); + if (!TheYear || !TheMonth || !TheDay) + return false; + if (Required) + if ((TheYear.value == 0) || (TheMonth.value == 0) || (TheDay.value == 0)) + return false; + if (TheMonth.value == 2) + if (TheDay.value > 29) + return false; + if ((TheMonth.value == 4) || (TheMonth.value == 6) || (TheMonth.value == 9) || (TheMonth.value == 11)) + if (TheDay.value > 30) + return false; + return true; +} \ No newline at end of file diff --git a/workflow/public_html/skins/ajax.js b/workflow/public_html/skins/ajax.js new file mode 100644 index 000000000..76b92e3dc --- /dev/null +++ b/workflow/public_html/skins/ajax.js @@ -0,0 +1,128 @@ +// Popup code +var gPopupMask = null; +var gPopupContainer = null; +var gPopFrame = null; +var gReturnFunc; +var gPopupIsShown = false; + +var gHideSelects = false; + + +var gTabIndexes = new Array(); +// Pre-defined list of tags we want to disable/enable tabbing into +var gTabbableTags = new Array("A","BUTTON","TEXTAREA","INPUT","IFRAME"); + +// If using Mozilla or Firefox, use Tab-key trap. +if (!document.all) { + document.onkeypress = keyDownHandler; +} + +function myEmptyCallback() { +} + +function get_xmlhttp() { + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } + if (!xmlhttp && typeof XMLHttpRequest!='undefined') { + xmlhttp = new XMLHttpRequest(); + } + return xmlhttp; +} + +function isdefined( variable) { + return (typeof(window[variable]) == "undefined")? false: true; +} + +//DAN Nov 24, 2006 +//parameter asyncronuos was added to work in syncronous mode +// usage: ajax_init(_,_,_,_,false); +function ajax_init( ajax_server,div_container, values, callback,asyncronuos) +{ // DAN Nov 24, 2006. variable asyncronuos was added + asyncronuos = (asyncronuos!=false)?true:false; + + var objetus; + objetus = get_xmlhttp(); + + try{ // DAN Nov 24, 2006. variable asyncronuos instead of true + objetus.open("GET", ajax_server + "?" + values, asyncronuos); + + }catch(ss) + { + alert("error"+ss.message); + } + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + document.getElementById(div_container).style.display = ""; + document.getElementById(div_container).innerHTML = "..."; + + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { + document.getElementById(div_container).innerHTML = objetus.responseText; + if ( callback != '' ) + callback(); + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} + +function ajax_init_2( ajax_server, div, values, callback ) +{ + var objetus; + objetus = get_xmlhttp(); + objetus.open ("GET", ajax_server + "?" + values, true); + objetus.onreadystatechange=function() { + if ( objetus.readyState == 1 ) + { + //document.getElementById(div_container).style.display = ""; + //document.getElementById(div_container).innerHTML = "..."; + div.style.display = ""; + div.innerHTML = "..."; + } + else if ( objetus.readyState==4) + { + if( objetus.status==200) + { + //document.getElementById(div_container).innerHTML = objetus.responseText; + div.innerHTML = objetus.responseText; + if ( callback != '' ) + callback(); + } + else + { + window.alert('error-['+ objetus.status +']-' + objetus.responseText ); + } + } + } + objetus.send(null); +} +function iframe_get_xmlhttp() { + try { + xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (E) { + xmlhttp = false; + } + } + if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { + xmlhttp = new XMLHttpRequest(); + } + return xmlhttp; +} \ No newline at end of file diff --git a/workflow/public_html/skins/ext/ext-all-notheme.css b/workflow/public_html/skins/ext/ext-all-notheme.css new file mode 100755 index 000000000..2dc750d1a --- /dev/null +++ b/workflow/public_html/skins/ext/ext-all-notheme.css @@ -0,0 +1,5150 @@ +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}.ext-el-mask { + z-index: 100; + position: absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity=50); + width: 100%; + height: 100%; + zoom: 1; +} + +.ext-el-mask-msg { + z-index: 20001; + position: absolute; + top: 0; + left: 0; + border:1px solid; + background:repeat-x 0 -16px; + padding:2px; +} + +.ext-el-mask-msg div { + padding:5px 10px 5px 10px; + border:1px solid; + cursor:wait; +} + +.ext-shim { + position:absolute; + visibility:hidden; + left:0; + top:0; + overflow:hidden; +} + +.ext-ie .ext-shim { + filter: alpha(opacity=0); +} + +.ext-ie6 .ext-shim { + margin-left: 5px; + margin-top: 3px; +} + +.x-mask-loading div { + padding:5px 10px 5px 25px; + background:no-repeat 5px 5px; + line-height:16px; +} + +/* class for hiding elements without using display:none */ +.x-hidden, .x-hide-offsets { + position:absolute !important; + left:-10000px; + top:-10000px; + visibility:hidden; +} + +.x-hide-display { + display:none !important; +} + +.x-hide-visibility { + visibility:hidden !important; +} + +.x-masked { + overflow: hidden !important; +} +.x-masked-relative { + position: relative !important; +} + +.x-masked select, .x-masked object, .x-masked embed { + visibility: hidden; +} + +.x-layer { + visibility: hidden; +} + +.x-unselectable, .x-unselectable * { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select:ignore; +} + +.x-repaint { + zoom: 1; + background-color: transparent; + -moz-outline: none; + outline: none; +} + +.x-item-disabled { + cursor: default; + opacity: .6; + -moz-opacity: .6; + filter: alpha(opacity=60); +} + +.x-item-disabled * { + cursor: default !important; +} + +.x-form-radio-group .x-item-disabled { + filter: none; +} + +.x-splitbar-proxy { + position: absolute; + visibility: hidden; + z-index: 20001; + zoom: 1; + line-height: 1px; + font-size: 1px; + overflow: hidden; +} + +.x-splitbar-h, .x-splitbar-proxy-h { + cursor: e-resize; + cursor: col-resize; +} + +.x-splitbar-v, .x-splitbar-proxy-v { + cursor: s-resize; + cursor: row-resize; +} + +.x-color-palette { + width: 150px; + height: 92px; + cursor: pointer; +} + +.x-color-palette a { + border: 1px solid; + float: left; + padding: 2px; + text-decoration: none; + -moz-outline: 0 none; + outline: 0 none; + cursor: pointer; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border: 1px solid; +} + +.x-color-palette em { + display: block; + border: 1px solid; +} + +.x-color-palette em span { + cursor: pointer; + display: block; + height: 10px; + line-height: 10px; + width: 10px; +} + +.x-ie-shadow { + display: none; + position: absolute; + overflow: hidden; + left:0; + top:0; + zoom:1; +} + +.x-shadow { + display: none; + position: absolute; + overflow: hidden; + left:0; + top:0; +} + +.x-shadow * { + overflow: hidden; +} + +.x-shadow * { + padding: 0; + border: 0; + margin: 0; + clear: none; + zoom: 1; +} + +/* top bottom */ +.x-shadow .xstc, .x-shadow .xsbc { + height: 6px; + float: left; +} + +/* corners */ +.x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbr { + width: 6px; + height: 6px; + float: left; +} + +/* sides */ +.x-shadow .xsc { + width: 100%; +} + +.x-shadow .xsml, .x-shadow .xsmr { + width: 6px; + float: left; + height: 100%; +} + +.x-shadow .xsmc { + float: left; + height: 100%; + background: transparent; +} + +.x-shadow .xst, .x-shadow .xsb { + height: 6px; + overflow: hidden; + width: 100%; +} + +.x-shadow .xsml { + background: transparent repeat-y 0 0; +} + +.x-shadow .xsmr { + background: transparent repeat-y -6px 0; +} + +.x-shadow .xstl { + background: transparent no-repeat 0 0; +} + +.x-shadow .xstc { + background: transparent repeat-x 0 -30px; +} + +.x-shadow .xstr { + background: transparent repeat-x 0 -18px; +} + +.x-shadow .xsbl { + background: transparent no-repeat 0 -12px; +} + +.x-shadow .xsbc { + background: transparent repeat-x 0 -36px; +} + +.x-shadow .xsbr { + background: transparent repeat-x 0 -6px; +} + +.loading-indicator { + background: no-repeat left; + padding-left: 20px; + line-height: 16px; + margin: 3px; +} + +.x-text-resize { + position: absolute; + left: -1000px; + top: -1000px; + visibility: hidden; + zoom: 1; +} + +.x-drag-overlay { + width: 100%; + height: 100%; + display: none; + position: absolute; + left: 0; + top: 0; + background-image:url(../images/default/s.gif); + z-index: 20000; +} + +.x-clear { + clear:both; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} + +.x-spotlight { + z-index: 8999; + position: absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity=50); + width:0; + height:0; + zoom: 1; +} + +#x-history-frame { + position:absolute; + top:-1px; + left:0; + width:1px; + height:1px; + visibility:hidden; +} + +#x-history-field { + position:absolute; + top:0; + left:-1px; + width:1px; + height:1px; + visibility:hidden; +} +.x-resizable-handle { + position:absolute; + z-index:100; + /* ie needs these */ + font-size:1px; + line-height:6px; + overflow:hidden; + filter:alpha(opacity=0); + opacity:0; + zoom:1; +} + +.x-resizable-handle-east{ + width:6px; + cursor:e-resize; + right:0; + top:0; + height:100%; +} + +.ext-ie .x-resizable-handle-east { + margin-right:-1px; /*IE rounding error*/ +} + +.x-resizable-handle-south{ + width:100%; + cursor:s-resize; + left:0; + bottom:0; + height:6px; +} + +.ext-ie .x-resizable-handle-south { + margin-bottom:-1px; /*IE rounding error*/ +} + +.x-resizable-handle-west{ + width:6px; + cursor:w-resize; + left:0; + top:0; + height:100%; +} + +.x-resizable-handle-north{ + width:100%; + cursor:n-resize; + left:0; + top:0; + height:6px; +} + +.x-resizable-handle-southeast{ + width:6px; + cursor:se-resize; + right:0; + bottom:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-northwest{ + width:6px; + cursor:nw-resize; + left:0; + top:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-northeast{ + width:6px; + cursor:ne-resize; + right:0; + top:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-southwest{ + width:6px; + cursor:sw-resize; + left:0; + bottom:0; + height:6px; + z-index:101; +} + +.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{ + filter:alpha(opacity=100); + opacity:1; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-position: left; +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-position: top; +} + +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-position: top left; +} + +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-position:bottom right; +} + +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-position: bottom left; +} + +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-position: top right; +} + +.x-resizable-proxy{ + border: 1px dashed; + position:absolute; + overflow:hidden; + display:none; + left:0; + top:0; + z-index:50000; +} + +.x-resizable-overlay{ + width:100%; + height:100%; + display:none; + position:absolute; + left:0; + top:0; + z-index:200000; + -moz-opacity: 0; + opacity:0; + filter: alpha(opacity=0); +} +.x-tab-panel { + overflow:hidden; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border: 1px solid; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header { + border: 1px solid; + padding-bottom: 2px; +} + +.x-tab-panel-footer { + border: 1px solid; + padding-top: 2px; +} + +.x-tab-strip-wrap { + width:100%; + overflow:hidden; + position:relative; + zoom:1; +} + +ul.x-tab-strip { + display:block; + width:5000px; + zoom:1; +} + +ul.x-tab-strip-top{ + padding-top: 1px; + background: repeat-x bottom; + border-bottom: 1px solid; +} + +ul.x-tab-strip-bottom{ + padding-bottom: 1px; + background: repeat-x top; + border-top: 1px solid; + border-bottom: 0 none; +} + +.x-tab-panel-header-plain .x-tab-strip-top { + background:transparent !important; + padding-top:0 !important; +} + +.x-tab-panel-header-plain { + background:transparent !important; + border-width:0 !important; + padding-bottom:0 !important; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border:1px solid; + height:2px; + font-size:1px; + line-height:1px; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer { + border-top: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-bottom: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-bottom { + background:transparent !important; + padding-bottom:0 !important; +} + +.x-tab-panel-footer-plain { + background:transparent !important; + border-width:0 !important; + padding-top:0 !important; +} + +.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer, +.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer { + height:3px; +} + +ul.x-tab-strip li { + float:left; + margin-left:2px; +} + +ul.x-tab-strip li.x-tab-edge { + float:left; + margin:0 !important; + padding:0 !important; + border:0 none !important; + font-size:1px !important; + line-height:1px !important; + overflow:hidden; + zoom:1; + background:transparent !important; + width:1px; +} + +.x-tab-strip a, .x-tab-strip span, .x-tab-strip em { + display:block; +} + +.x-tab-strip a { + text-decoration:none !important; + -moz-outline: none; + outline: none; + cursor:pointer; +} + +.x-tab-strip-inner { + overflow:hidden; + text-overflow: ellipsis; +} + +.x-tab-strip span.x-tab-strip-text { + white-space: nowrap; + cursor:pointer; + padding:4px 0; +} + +.x-tab-strip-top .x-tab-with-icon .x-tab-right { + padding-left:6px; +} + +.x-tab-strip .x-tab-with-icon span.x-tab-strip-text { + padding-left:20px; + background-position: 0 3px; + background-repeat: no-repeat; +} + +.x-tab-strip-active, .x-tab-strip-active a.x-tab-right { + cursor:default; +} + +.x-tab-strip-active span.x-tab-strip-text { + cursor:default; +} + +.x-tab-strip-disabled .x-tabs-text { + cursor:default; +} + +.x-tab-panel-body { + overflow:hidden; +} + +.x-tab-panel-bwrap { + overflow:hidden; +} + +.ext-ie .x-tab-strip .x-tab-right { + position:relative; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + margin-bottom:-1px; +} + +/* + * Horrible hack for IE8 in quirks mode + */ +.ext-ie8 ul.x-tab-strip li { + position: relative; +} +.ext-ie8 .x-tab-strip .x-tab-right{ + margin-bottom: 0 !important; + top: 1px; +} +.ext-ie8 ul.x-tab-strip-top { + padding-top: 0; +} +.ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + top:4px; +} +.ext-ie8 .x-tab-strip-bottom .x-tab-right{ + top:0; +} + + +.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text { + padding-bottom:5px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + margin-top:-1px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text { + padding-top:5px; +} + +.x-tab-strip-top .x-tab-right { + background: transparent no-repeat 0 -51px; + padding-left:10px; +} + +.x-tab-strip-top .x-tab-left { + background: transparent no-repeat right -351px; + padding-right:10px; +} + +.x-tab-strip-top .x-tab-strip-inner { + background: transparent repeat-x 0 -201px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-right { + background-position:0 -101px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-left { + background-position:right -401px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner { + background-position:0 -251px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + background-position: 0 0; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-left { + background-position: right -301px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner { + background-position: 0 -151px; +} + +.x-tab-strip-bottom .x-tab-right { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-left { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-left { + margin-right: 3px; + padding:0 10px; +} + +.x-tab-strip-bottom .x-tab-right { + padding:0; +} + +.x-tab-strip .x-tab-strip-close { + display:none; +} + +.x-tab-strip-closable { + position:relative; +} + +.x-tab-strip-closable .x-tab-left { + padding-right:19px; +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + opacity:.6; + -moz-opacity:.6; + background-repeat:no-repeat; + display:block; + width:11px; + height:11px; + position:absolute; + top:3px; + right:3px; + cursor:pointer; + z-index:2; +} + +.x-tab-strip .x-tab-strip-active a.x-tab-strip-close { + opacity:.8; + -moz-opacity:.8; +} +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + opacity:1; + -moz-opacity:1; +} + +.x-tab-panel-body { + border: 1px solid; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background: transparent no-repeat -18px 0; + border-bottom: 1px solid; + width:18px; + position:absolute; + left:0; + top:0; + z-index:10; + cursor:pointer; +} +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background: transparent no-repeat 0 0; + border-bottom: 1px solid; + width:18px; + position:absolute; + right:0; + top:0; + z-index:10; + cursor:pointer; +} + +.x-tab-scroller-right-over { + background-position: -18px 0; +} + +.x-tab-scroller-right-disabled { + background-position: 0 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scrolling-bottom .x-tab-scroller-left, .x-tab-scrolling-bottom .x-tab-scroller-right{ + margin-top: 1px; +} + +.x-tab-scrolling .x-tab-strip-wrap { + margin-left:18px; + margin-right:18px; +} + +.x-tab-scrolling { + position:relative; +} + +.x-tab-panel-bbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +} + +.x-tab-panel-tbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +}/* all fields */ +.x-form-field{ + margin: 0 0 0 0; +} + +.ext-webkit *:focus{ + outline: none !important; +} + +/* ---- text fields ---- */ +.x-form-text, textarea.x-form-field{ + padding:1px 3px; + background:repeat-x 0 0; + border:1px solid; +} + +textarea.x-form-field { + padding:2px 3px; +} + +.x-form-text, .ext-ie .x-form-file { + height:22px; + line-height:18px; + vertical-align:middle; +} + +.ext-ie6 .x-form-text, .ext-ie7 .x-form-text { + margin:-1px 0; /* ie bogus margin bug */ + height:22px; /* ie quirks */ + line-height:18px; +} + +.ext-ie6 textarea.x-form-field, .ext-ie7 textarea.x-form-field { + margin:-1px 0; /* ie bogus margin bug */ +} + +.ext-strict .x-form-text { + height:18px; +} + +.ext-safari.ext-mac textarea.x-form-field { + margin-bottom:-2px; /* another bogus margin bug, safari/mac only */ +} + +.ext-strict .ext-ie8 .x-form-text, .ext-strict .ext-ie8 textarea.x-form-field { + margin-bottom: 1px; +} + +.ext-gecko .x-form-text , .ext-ie8 .x-form-text { + padding-top:2px; /* FF won't center the text vertically */ + padding-bottom:0; +} + +.ext-ie6 .x-form-composite .x-form-text.x-box-item, .ext-ie7 .x-form-composite .x-form-text.x-box-item { + margin: 0 !important; /* clear ie bogus margin bug fix */ +} + +textarea { + resize: none; /* Disable browser resizable textarea */ +} + +/* select boxes */ +.x-form-select-one { + height:20px; + line-height:18px; + vertical-align:middle; + border: 1px solid; +} + +/* multi select boxes */ + +/* --- TODO --- */ + +/* 2.0.2 style */ +.x-form-check-wrap { + line-height:18px; + height: auto; +} + +.ext-ie .x-form-check-wrap input { + width:15px; + height:15px; +} + +.x-form-check-wrap input{ + vertical-align: bottom; +} + +.x-editor .x-form-check-wrap { + padding:3px; +} + +.x-editor .x-form-checkbox { + height:13px; +} + +.x-form-check-group-label { + border-bottom: 1px solid; + margin-bottom: 5px; + padding-left: 3px !important; + float: none !important; +} + +/* wrapped fields and triggers */ +.x-form-field-wrap .x-form-trigger{ + width:17px; + height:21px; + border:0; + background:transparent no-repeat 0 0; + cursor:pointer; + border-bottom: 1px solid; + position:absolute; + top:0; +} + +.x-form-field-wrap .x-form-date-trigger, .x-form-field-wrap .x-form-clear-trigger, .x-form-field-wrap .x-form-search-trigger{ + cursor:pointer; +} + +.x-form-field-wrap .x-form-twin-triggers .x-form-trigger{ + position:static; + top:auto; + vertical-align:top; +} + +.x-form-field-wrap { + position:relative; + left:0;top:0; + text-align: left; + zoom:1; + white-space: nowrap; +} + +.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-trigger { + right: 0; /* IE8 Strict mode trigger bug */ +} + +.x-form-field-wrap .x-form-trigger-over{ + background-position:-17px 0; +} + +.x-form-field-wrap .x-form-trigger-click{ + background-position:-34px 0; +} + +.x-trigger-wrap-focus .x-form-trigger{ + background-position:-51px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-over{ + background-position:-68px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-click{ + background-position:-85px 0; +} + +.x-trigger-wrap-focus .x-form-trigger{ + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-over{ + background-position:0 0 !important; + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-click{ + background-position:0 0 !important; + border-bottom: 1px solid; +} + +.x-trigger-noedit{ + cursor:pointer; +} + +/* field focus style */ +.x-form-focus, textarea.x-form-focus{ + border: 1px solid; +} + +/* invalid fields */ +.x-form-invalid, textarea.x-form-invalid{ + background:repeat-x bottom; + border: 1px solid; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid{ + background:repeat-x bottom; +} + +/* editors */ +.x-editor { + visibility:hidden; + padding:0; + margin:0; +} + +.x-form-grow-sizer { + left: -10000px; + padding: 8px 3px; + position: absolute; + visibility:hidden; + top: -10000px; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + zoom:1; +} + +.x-form-grow-sizer p { + margin:0 !important; + border:0 none !important; + padding:0 !important; +} + +/* Form Items CSS */ + +.x-form-item { + display:block; + margin-bottom:4px; + zoom:1; +} + +.x-form-item label.x-form-item-label { + display:block; + float:left; + width:100px; + padding:3px; + padding-left:0; + clear:left; + z-index:2; + position:relative; +} + +.x-form-element { + padding-left:105px; + position:relative; +} + +.x-form-invalid-msg { + padding:2px; + padding-left:18px; + background: transparent no-repeat 0 2px; + line-height:16px; + width:200px; +} + +.x-form-label-left label.x-form-item-label { + text-align:left; +} + +.x-form-label-right label.x-form-item-label { + text-align:right; +} + +.x-form-label-top .x-form-item label.x-form-item-label { + width:auto; + float:none; + clear:none; + display:inline; + margin-bottom:4px; + position:static; +} + +.x-form-label-top .x-form-element { + padding-left:0; + padding-top:4px; +} + +.x-form-label-top .x-form-item { + padding-bottom:4px; +} + +/* Editor small font for grid, toolbar and tree */ +.x-small-editor .x-form-text { + height:20px; + line-height:16px; + vertical-align:middle; +} + +.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .x-small-editor .x-form-text { + margin-top:-1px !important; /* ie bogus margin bug */ + margin-bottom:-1px !important; + height:20px !important; /* ie quirks */ + line-height:16px !important; +} + +.ext-strict .x-small-editor .x-form-text { + height:16px !important; +} + +.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .x-small-editor .x-form-text { + height:20px; + line-height:16px; +} + +.ext-border-box .x-small-editor .x-form-text { + height:20px; +} + +.x-small-editor .x-form-select-one { + height:20px; + line-height:16px; + vertical-align:middle; +} + +.x-small-editor .x-form-num-field { + text-align:right; +} + +.x-small-editor .x-form-field-wrap .x-form-trigger{ + height:19px; +} + +.ext-webkit .x-small-editor .x-form-text{padding-top:3px;font-size:100%;} + +.x-form-clear { + clear:both; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} +.x-form-clear-left { + clear:left; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} + +.ext-ie6 .x-form-check-wrap input, .ext-border-box .x-form-check-wrap input{ + margin-top: 3px; +} + +.x-form-cb-label { + position: relative; + margin-left:4px; + top: 2px; +} + +.ext-ie .x-form-cb-label{ + top: 1px; +} + +.ext-ie6 .x-form-cb-label, .ext-border-box .x-form-cb-label{ + top: 3px; +} + +.x-form-display-field{ + padding-top: 2px; +} + +.ext-gecko .x-form-display-field, .ext-strict .ext-ie7 .x-form-display-field{ + padding-top: 1px; +} + +.ext-ie .x-form-display-field{ + padding-top: 3px; +} + +.ext-strict .ext-ie8 .x-form-display-field{ + padding-top: 0; +} + +.x-form-column { + float:left; + padding:0; + margin:0; + width:48%; + overflow:hidden; + zoom:1; +} + +/* buttons */ +.x-form .x-form-btns-ct .x-btn{ + float:right; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns td { + border:0; + padding:0; +} + +.x-form .x-form-btns-ct .x-form-btns-right table{ + float:right; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns-left table{ + float:left; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns-center{ + text-align:center; /*ie*/ +} + +.x-form .x-form-btns-ct .x-form-btns-center table{ + margin:0 auto; /*everyone else*/ +} + +.x-form .x-form-btns-ct table td.x-form-btn-td{ + padding:3px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-left{ + background-position:0 -147px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-right{ + background-position:0 -168px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-center{ + background-position:0 -189px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-center{ + background-position:0 -126px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-right{ + background-position:0 -84px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-left{ + background-position:0 -63px; +} + +.x-form-invalid-icon { + width:16px; + height:18px; + visibility:hidden; + position:absolute; + left:0; + top:0; + display:block; + background:transparent no-repeat 0 2px; +} + +/* fieldsets */ +.x-fieldset { + border:1px solid; + padding:10px; + margin-bottom:10px; + display:block; /* preserve margins in IE */ +} + +/* make top of checkbox/tools visible in webkit */ +.ext-webkit .x-fieldset-header { + padding-top: 1px; +} + +.ext-ie .x-fieldset legend { + margin-bottom:10px; +} + +.ext-ie .x-fieldset { + padding-top: 0; + padding-bottom:10px; +} + +.x-fieldset legend .x-tool-toggle { + margin-right:3px; + margin-left:0; + float:left !important; +} + +.x-fieldset legend input { + margin-right:3px; + float:left !important; + height:13px; + width:13px; +} + +fieldset.x-panel-collapsed { + padding-bottom:0 !important; + border-width: 1px 1px 0 1px !important; + border-left-color: transparent; + border-right-color: transparent; +} + +.ext-ie6 fieldset.x-panel-collapsed{ + padding-bottom:0 !important; + border-width: 1px 0 0 0 !important; + margin-left: 1px; + margin-right: 1px; +} + +fieldset.x-panel-collapsed .x-fieldset-bwrap { + visibility:hidden; + position:absolute; + left:-1000px; + top:-1000px; +} + +.ext-ie .x-fieldset-bwrap { + zoom:1; +} + +.x-fieldset-noborder { + border:0px none transparent; +} + +.x-fieldset-noborder legend { + margin-left:-3px; +} + +/* IE legend positioning bug */ +.ext-ie .x-fieldset-noborder legend { + position: relative; + margin-bottom:23px; +} +.ext-ie .x-fieldset-noborder legend span { + position: absolute; + left:16px; +} + +.ext-gecko .x-window-body .x-form-item { + -moz-outline: none; + outline: none; + overflow: auto; +} + +.ext-gecko .x-form-item { + -moz-outline: none; + outline: none; +} + +.x-hide-label label.x-form-item-label { + display:none; +} + +.x-hide-label .x-form-element { + padding-left: 0 !important; +} + +.x-form-label-top .x-hide-label label.x-form-item-label{ + display: none; +} + +.x-fieldset { + overflow:hidden; +} + +.x-fieldset-bwrap { + overflow:hidden; + zoom:1; +} + +.x-fieldset-body { + overflow:hidden; +} +.x-btn{ + cursor:pointer; + white-space: nowrap; +} + +.x-btn button{ + border:0 none; + background:transparent; + padding-left:3px; + padding-right:3px; + cursor:pointer; + margin:0; + overflow:visible; + width:auto; + -moz-outline:0 none; + outline:0 none; +} + +* html .ext-ie .x-btn button { + width:1px; +} + +.ext-gecko .x-btn button, .ext-webkit .x-btn button { + padding-left:0; + padding-right:0; +} + +.ext-gecko .x-btn button::-moz-focus-inner { + padding:0; +} + +.ext-ie .x-btn button { + padding-top:2px; +} + +.x-btn td { + padding:0 !important; +} + +.x-btn-text { + cursor:pointer; + white-space: nowrap; + padding:0; +} + +/* icon placement and sizing styles */ + +/* Only text */ +.x-btn-noicon .x-btn-small .x-btn-text{ + height: 16px; +} + +.x-btn-noicon .x-btn-medium .x-btn-text{ + height: 24px; +} + +.x-btn-noicon .x-btn-large .x-btn-text{ + height: 32px; +} + +/* Only icons */ +.x-btn-icon .x-btn-text{ + background-position: center; + background-repeat: no-repeat; +} + +.x-btn-icon .x-btn-small .x-btn-text{ + height: 16px; + width: 16px; +} + +.x-btn-icon .x-btn-medium .x-btn-text{ + height: 24px; + width: 24px; +} + +.x-btn-icon .x-btn-large .x-btn-text{ + height: 32px; + width: 32px; +} + +/* Icons and text */ +/* left */ +.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:18px; + height:16px; +} + +.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:26px; + height:24px; +} + +.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:34px; + height:32px; +} + +/* top */ +.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:18px; +} + +.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:26px; +} + +.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:34px; +} + +/* right */ +.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:18px; + height:16px; +} + +.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:26px; + height:24px; +} + +.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:34px; + height:32px; +} + +/* bottom */ +.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:18px; +} + +.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:26px; +} + +.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:34px; +} + +/* background positioning */ +.x-btn-tr i, .x-btn-tl i, .x-btn-mr i, .x-btn-ml i, .x-btn-br i, .x-btn-bl i{ + font-size:1px; + line-height:1px; + width:3px; + display:block; + overflow:hidden; +} + +.x-btn-tr i, .x-btn-tl i, .x-btn-br i, .x-btn-bl i{ + height:3px; +} + +.x-btn-tl{ + width:3px; + height:3px; + background:no-repeat 0 0; +} +.x-btn-tr{ + width:3px; + height:3px; + background:no-repeat -3px 0; +} +.x-btn-tc{ + height:3px; + background:repeat-x 0 -6px; +} + +.x-btn-ml{ + width:3px; + background:no-repeat 0 -24px; +} +.x-btn-mr{ + width:3px; + background:no-repeat -3px -24px; +} + +.x-btn-mc{ + background:repeat-x 0 -1096px; + vertical-align: middle; + text-align:center; + padding:0 5px; + cursor:pointer; + white-space:nowrap; +} + +/* Fixes an issue with the button height */ +.ext-strict .ext-ie6 .x-btn-mc, .ext-strict .ext-ie7 .x-btn-mc { + height: 100%; +} + +.x-btn-bl{ + width:3px; + height:3px; + background:no-repeat 0 -3px; +} + +.x-btn-br{ + width:3px; + height:3px; + background:no-repeat -3px -3px; +} + +.x-btn-bc{ + height:3px; + background:repeat-x 0 -15px; +} + +.x-btn-over .x-btn-tl{ + background-position: -6px 0; +} + +.x-btn-over .x-btn-tr{ + background-position: -9px 0; +} + +.x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} + +.x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} + +.x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} + +.x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} + +.x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} + +.x-btn-over .x-btn-br{ + background-position: -9px -3px; +} + +.x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} + +.x-btn-click .x-btn-tl, .x-btn-menu-active .x-btn-tl, .x-btn-pressed .x-btn-tl{ + background-position: -12px 0; +} + +.x-btn-click .x-btn-tr, .x-btn-menu-active .x-btn-tr, .x-btn-pressed .x-btn-tr{ + background-position: -15px 0; +} + +.x-btn-click .x-btn-tc, .x-btn-menu-active .x-btn-tc, .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px; +} + +.x-btn-click .x-btn-ml, .x-btn-menu-active .x-btn-ml, .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px; +} + +.x-btn-click .x-btn-mr, .x-btn-menu-active .x-btn-mr, .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px; +} + +.x-btn-click .x-btn-mc, .x-btn-menu-active .x-btn-mc, .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px; +} + +.x-btn-click .x-btn-bl, .x-btn-menu-active .x-btn-bl, .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px; +} + +.x-btn-click .x-btn-br, .x-btn-menu-active .x-btn-br, .x-btn-pressed .x-btn-br{ + background-position: -15px -3px; +} + +.x-btn-click .x-btn-bc, .x-btn-menu-active .x-btn-bc, .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px; +} + +.x-btn-disabled *{ + cursor:default !important; +} + + +/* With a menu arrow */ +/* right */ +.x-btn-mc em.x-btn-arrow { + display:block; + background:transparent no-repeat right center; + padding-right:10px; +} + +.x-btn-mc em.x-btn-split { + display:block; + background:transparent no-repeat right center; + padding-right:14px; +} + +/* bottom */ +.x-btn-mc em.x-btn-arrow-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} + +.x-btn-mc em.x-btn-split-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} + +/* height adjustment class */ +.x-btn-as-arrow .x-btn-mc em { + display:block; + background:transparent; + padding-bottom:14px; +} + +/* groups */ +.x-btn-group { + padding:1px; +} + +.x-btn-group-header { + padding:2px; + text-align:center; +} + +.x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} + +.x-btn-group-tl { + background: transparent no-repeat 0 0; + padding-left:3px; + zoom:1; +} + +.x-btn-group-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:3px; +} + +.x-btn-group-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-btn-group-bc .x-panel-footer { + zoom:1; +} + +.x-btn-group-bl { + background: transparent no-repeat 0 bottom; + padding-left:3px; + zoom:1; +} + +.x-btn-group-br { + background: transparent no-repeat right bottom; + padding-right:3px; + zoom:1; +} + +.x-btn-group-mc { + border:0 none; + padding:1px 0 0 0; + margin:0; +} + +.x-btn-group-mc .x-btn-group-body { + background:transparent; + border: 0 none; +} + +.x-btn-group-ml { + background: transparent repeat-y 0 0; + padding-left:3px; + zoom:1; +} + +.x-btn-group-mr { + background: transparent repeat-y right 0; + padding-right:3px; + zoom:1; +} + +.x-btn-group-bc .x-btn-group-footer { + padding-bottom:6px; +} + +.x-panel-nofooter .x-btn-group-bc { + height:3px; + font-size:0; + line-height:0; +} + +.x-btn-group-bwrap { + overflow:hidden; + zoom:1; +} + +.x-btn-group-body { + overflow:hidden; + zoom:1; +} + +.x-btn-group-notitle .x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + height:2px; +}.x-toolbar{ + border-style:solid; + border-width:0 0 1px 0; + display: block; + padding:2px; + background:repeat-x top left; + position:relative; + left:0; + top:0; + zoom:1; + overflow:hidden; +} + +.x-toolbar-left { + width: 100%; +} + +.x-toolbar .x-item-disabled .x-btn-icon { + opacity: .35; + -moz-opacity: .35; + filter: alpha(opacity=35); +} + +.x-toolbar td { + vertical-align:middle; +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + white-space: nowrap; +} + +.x-toolbar .x-item-disabled { + cursor:default; + opacity:.6; + -moz-opacity:.6; + filter:alpha(opacity=60); +} + +.x-toolbar .x-item-disabled * { + cursor:default; +} + +.x-toolbar .x-toolbar-cell { + vertical-align:middle; +} + +.x-toolbar .x-btn-tl, .x-toolbar .x-btn-tr, .x-toolbar .x-btn-tc, .x-toolbar .x-btn-ml, .x-toolbar .x-btn-mr, +.x-toolbar .x-btn-mc, .x-toolbar .x-btn-bl, .x-toolbar .x-btn-br, .x-toolbar .x-btn-bc +{ + background-position: 500px 500px; +} + +/* These rules are duplicated from button.css to give priority of x-toolbar rules above */ +.x-toolbar .x-btn-over .x-btn-tl{ + background-position: -6px 0; +} + +.x-toolbar .x-btn-over .x-btn-tr{ + background-position: -9px 0; +} + +.x-toolbar .x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} + +.x-toolbar .x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} + +.x-toolbar .x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} + +.x-toolbar .x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} + +.x-toolbar .x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} + +.x-toolbar .x-btn-over .x-btn-br{ + background-position: -9px -3px; +} + +.x-toolbar .x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} + +.x-toolbar .x-btn-click .x-btn-tl, .x-toolbar .x-btn-menu-active .x-btn-tl, .x-toolbar .x-btn-pressed .x-btn-tl{ + background-position: -12px 0; +} + +.x-toolbar .x-btn-click .x-btn-tr, .x-toolbar .x-btn-menu-active .x-btn-tr, .x-toolbar .x-btn-pressed .x-btn-tr{ + background-position: -15px 0; +} + +.x-toolbar .x-btn-click .x-btn-tc, .x-toolbar .x-btn-menu-active .x-btn-tc, .x-toolbar .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px; +} + +.x-toolbar .x-btn-click .x-btn-ml, .x-toolbar .x-btn-menu-active .x-btn-ml, .x-toolbar .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px; +} + +.x-toolbar .x-btn-click .x-btn-mr, .x-toolbar .x-btn-menu-active .x-btn-mr, .x-toolbar .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px; +} + +.x-toolbar .x-btn-click .x-btn-mc, .x-toolbar .x-btn-menu-active .x-btn-mc, .x-toolbar .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px; +} + +.x-toolbar .x-btn-click .x-btn-bl, .x-toolbar .x-btn-menu-active .x-btn-bl, .x-toolbar .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px; +} + +.x-toolbar .x-btn-click .x-btn-br, .x-toolbar .x-btn-menu-active .x-btn-br, .x-toolbar .x-btn-pressed .x-btn-br{ + background-position: -15px -3px; +} + +.x-toolbar .x-btn-click .x-btn-bc, .x-toolbar .x-btn-menu-active .x-btn-bc, .x-toolbar .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px; +} + +.x-toolbar div.xtb-text{ + padding:2px 2px 0; + line-height:16px; + display:block; +} + +.x-toolbar .xtb-sep { + background-position: center; + background-repeat: no-repeat; + display: block; + font-size: 1px; + height: 16px; + width:4px; + overflow: hidden; + cursor:default; + margin: 0 2px 0; + border:0; +} + +.x-toolbar .xtb-spacer { + width:2px; +} + +/* Paging Toolbar */ +.x-tbar-page-number{ + width:30px; + height:14px; +} + +.ext-ie .x-tbar-page-number{ + margin-top: 2px; +} + +.x-paging-info { + position:absolute; + top:5px; + right: 8px; +} + +/* floating */ +.x-toolbar-ct { + width:100%; +} + +.x-toolbar-right td { + text-align: center; +} + +.x-panel-tbar, .x-panel-bbar, .x-window-tbar, .x-window-bbar, .x-tab-panel-tbar, .x-tab-panel-bbar, .x-plain-tbar, .x-plain-bbar { + overflow:hidden; + zoom:1; +} + +.x-toolbar-more .x-btn-small .x-btn-text{ + height: 16px; + width: 12px; +} + +.x-toolbar-more em.x-btn-arrow { + display:inline; + background:transparent; + padding-right:0; +} + +.x-toolbar-more .x-btn-mc em.x-btn-arrow { + background-image: none; +} + +div.x-toolbar-no-items { + color:gray !important; + padding:5px 10px !important; +} + +/* fix ie toolbar form items */ +.ext-border-box .x-toolbar-cell .x-form-text { + margin-bottom:-1px !important; +} + +.ext-border-box .x-toolbar-cell .x-form-field-wrap .x-form-text { + margin:0 !important; +} + +.ext-ie .x-toolbar-cell .x-form-field-wrap { + height:21px; +} + +.ext-ie .x-toolbar-cell .x-form-text { + position:relative; + top:-1px; +} + +.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-text, .ext-strict .ext-ie .x-toolbar-cell .x-form-text { + top: 0px; +} + +.x-toolbar-right td .x-form-field-trigger-wrap{ + text-align: left; +} + +.x-toolbar-cell .x-form-checkbox, .x-toolbar-cell .x-form-radio{ + margin-top: 5px; +} + +.x-toolbar-cell .x-form-cb-label{ + vertical-align: bottom; + top: 1px; +} + +.ext-ie .x-toolbar-cell .x-form-checkbox, .ext-ie .x-toolbar-cell .x-form-radio{ + margin-top: 4px; +} + +.ext-ie .x-toolbar-cell .x-form-cb-label{ + top: 0; +} +/* Grid3 styles */ +.x-grid3 { + position:relative; + overflow:hidden; +} + +.x-grid-panel .x-panel-body { + overflow:hidden !important; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border:1px solid; +} + +.x-grid3 table { + table-layout:fixed; +} + +.x-grid3-viewport{ + overflow:hidden; +} + +.x-grid3-hd-row td, .x-grid3-row td, .x-grid3-summary-row td{ + -moz-outline: none; + outline: none; + -moz-user-focus: normal; +} + +.x-grid3-row td, .x-grid3-summary-row td { + line-height:13px; + vertical-align: top; + padding-left:1px; + padding-right:1px; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-cell{ + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-hd-row td { + line-height:15px; + vertical-align:middle; + border-left:1px solid; + border-right:1px solid; +} + +.x-grid3-hd-row .x-grid3-marker-hd { + padding:3px; +} + +.x-grid3-row .x-grid3-marker { + padding:3px; +} + +.x-grid3-cell-inner, .x-grid3-hd-inner{ + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + padding:3px 3px 3px 5px; + white-space: nowrap; +} + +.x-grid3-hd-inner { + position:relative; + cursor:inherit; + padding:4px 3px 4px 5px; +} + +.x-grid3-row-body { + white-space:normal; +} + +.x-grid3-body-cell { + -moz-outline:0 none; + outline:0 none; +} + +/* IE Quirks to clip */ +.ext-ie .x-grid3-cell-inner, .ext-ie .x-grid3-hd-inner{ + width:100%; +} + +/* reverse above in strict mode */ +.ext-strict .x-grid3-cell-inner, .ext-strict .x-grid3-hd-inner{ + width:auto; +} + +.x-grid-row-loading { + background: no-repeat center center; +} + +.x-grid-page { + overflow:hidden; +} + +.x-grid3-row { + cursor: default; + border: 1px solid; + width:100%; +} + +.x-grid3-row-over { + border:1px solid; + background: repeat-x left top; +} + +.x-grid3-resize-proxy { + width:1px; + left:0; + cursor: e-resize; + cursor: col-resize; + position:absolute; + top:0; + height:100px; + overflow:hidden; + visibility:hidden; + border:0 none; + z-index:7; +} + +.x-grid3-resize-marker { + width:1px; + left:0; + position:absolute; + top:0; + height:100px; + overflow:hidden; + visibility:hidden; + border:0 none; + z-index:7; +} + +.x-grid3-focus { + position:absolute; + left:0; + top:0; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: text; + -khtml-user-select: text; + -webkit-user-select:ignore; +} + +/* header styles */ +.x-grid3-header{ + background: repeat-x 0 bottom; + cursor:default; + zoom:1; + padding:1px 0 0 0; +} + +.x-grid3-header-pop { + border-left:1px solid; + float:right; + clear:none; +} + +.x-grid3-header-pop-inner { + border-left:1px solid; + width:14px; + height:19px; + background: transparent no-repeat center center; +} + +.ext-ie .x-grid3-header-pop-inner { + width:15px; +} + +.ext-strict .x-grid3-header-pop-inner { + width:14px; +} + +.x-grid3-header-inner { + overflow:hidden; + zoom:1; + float:left; +} + +.x-grid3-header-offset { + padding-left:1px; + text-align: left; +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left:1px solid; + border-right:1px solid; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background: repeat-x left bottom; + +} + +.x-grid3-sort-icon{ + background-repeat: no-repeat; + display: none; + height: 4px; + width: 13px; + margin-left:3px; + vertical-align: middle; +} + +.sort-asc .x-grid3-sort-icon, .sort-desc .x-grid3-sort-icon { + display: inline; +} + +/* Header position fixes for IE strict mode */ +.ext-strict .ext-ie .x-grid3-header-inner, .ext-strict .ext-ie6 .x-grid3-hd { + position:relative; +} + +.ext-strict .ext-ie6 .x-grid3-hd-inner{ + position:static; +} + +/* Body Styles */ +.x-grid3-body { + zoom:1; +} + +.x-grid3-scroller { + overflow:auto; + zoom:1; + position:relative; +} + +.x-grid3-cell-text, .x-grid3-hd-text { + display: block; + padding: 3px 5px 3px 5px; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select:ignore; +} + +.x-grid3-split { + background-position: center; + background-repeat: no-repeat; + cursor: e-resize; + cursor: col-resize; + display: block; + font-size: 1px; + height: 16px; + overflow: hidden; + position: absolute; + top: 2px; + width: 6px; + z-index: 3; +} + +/* Column Reorder DD */ +.x-dd-drag-proxy .x-grid3-hd-inner{ + background: repeat-x left bottom; + width:120px; + padding:3px; + border:1px solid; + overflow:hidden; +} + +.col-move-top, .col-move-bottom{ + width:9px; + height:9px; + position:absolute; + top:0; + line-height:1px; + font-size:1px; + overflow:hidden; + visibility:hidden; + z-index:20000; + background:transparent no-repeat left top; +} + +/* Selection Styles */ +.x-grid3-row-selected { + border:1px dotted; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background: repeat-x 0 bottom !important; + vertical-align:middle !important; + padding:0; + border-top:1px solid; + border-bottom:none !important; + border-right:1px solid !important; + text-align:center; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + padding:0 4px; + text-align:center; +} + +/* dirty cells */ +.x-grid3-dirty-cell { + background: transparent no-repeat 0 0; +} + +/* Grid Toolbars */ +.x-grid3-topbar, .x-grid3-bottombar{ + overflow:hidden; + display:none; + zoom:1; + position:relative; +} + +.x-grid3-topbar .x-toolbar{ + border-right:0 none; +} + +.x-grid3-bottombar .x-toolbar{ + border-right:0 none; + border-bottom:0 none; + border-top:1px solid; +} + +/* Props Grid Styles */ +.x-props-grid .x-grid3-cell{ + padding:1px; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background:transparent repeat-y -16px !important; + padding-left:12px; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + padding:1px; + padding-right:0; + border:0 none; + border-right:1px solid; +} + +/* dd */ +.x-grid3-col-dd { + border:0 none; + padding:0; + background:transparent; +} + +.x-dd-drag-ghost .x-grid3-dd-wrap { + padding:1px 3px 3px 1px; +} + +.x-grid3-hd { + -moz-user-select:none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-hd-btn { + display:none; + position:absolute; + width:14px; + background:no-repeat left center; + right:0; + top:0; + z-index:2; + cursor:pointer; +} + +.x-grid3-hd-over .x-grid3-hd-btn, .x-grid3-hd-menu-open .x-grid3-hd-btn { + display:block; +} + +a.x-grid3-hd-btn:hover { + background-position:-14px center; +} + +/* Expanders */ +.x-grid3-body .x-grid3-td-expander { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner { + padding:0 !important; + height:100%; +} + +.x-grid3-row-expander { + width:100%; + height:18px; + background-position:4px 2px; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-row-collapsed .x-grid3-row-expander { + background-position:4px 2px; +} + +.x-grid3-row-expanded .x-grid3-row-expander { + background-position:-21px 2px; +} + +.x-grid3-row-collapsed .x-grid3-row-body { + display:none !important; +} + +.x-grid3-row-expanded .x-grid3-row-body { + display:block !important; +} + +/* Checkers */ +.x-grid3-body .x-grid3-td-checker { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner, .x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner { + padding:0 !important; + height:100%; +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + width:100%; + height:18px; + background-position:2px 2px; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-row .x-grid3-row-checker { + background-position:2px 2px; +} + +.x-grid3-row-selected .x-grid3-row-checker, .x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker { + background-position:-23px 2px; +} + +.x-grid3-hd-checker { + background-position:2px 1px; +} + +.ext-border-box .x-grid3-hd-checker { + background-position:2px 3px; +} + +.x-grid3-hd-checker-on .x-grid3-hd-checker { + background-position:-23px 1px; +} + +.ext-border-box .x-grid3-hd-checker-on .x-grid3-hd-checker { + background-position:-23px 3px; +} + +/* Numberer */ +.x-grid3-body .x-grid3-td-numberer { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + padding:3px 5px 0 0 !important; + text-align:right; +} + +/* Row Icon */ + +.x-grid3-body .x-grid3-td-row-icon { + background:transparent repeat-y right; + vertical-align:top; + text-align:center; +} + +.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner { + padding:0 !important; + background-position:center center; + background-repeat:no-repeat; + width:16px; + height:16px; + margin-left:2px; + margin-top:3px; +} + +/* All specials */ +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner { + padding: 1px 0 0 0 !important; +} + +.x-grid3-check-col { + width:100%; + height:16px; + background-position:center center; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-check-col-on { + width:100%; + height:16px; + background-position:center center; + background-repeat:no-repeat; + background-color:transparent; +} + +/* Grouping classes */ +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom: 2px solid; + cursor:pointer; + padding-top:6px; +} + +.x-grid-group-hd div.x-grid-group-title { + background:transparent no-repeat 3px 3px; + padding:4px 4px 4px 17px; +} + +.x-grid-group-collapsed .x-grid-group-body { + display:none; +} + +.ext-ie6 .x-grid3 .x-editor .x-form-text, .ext-ie7 .x-grid3 .x-editor .x-form-text { + position:relative; + top:-1px; +} + +.ext-ie .x-props-grid .x-editor .x-form-text { + position:static; + top:0; +} + +.x-grid-empty { + padding:10px; +} + +/* fix floating toolbar issue */ +.ext-ie7 .x-grid-panel .x-panel-bbar { + position:relative; +} + + +/* Reset position to static when Grid Panel has been framed */ +/* to resolve 'snapping' from top to bottom behavior. */ +/* @forumThread 86656 */ +.ext-ie7 .x-grid-panel .x-panel-mc .x-panel-bbar { + position: static; +} + +.ext-ie6 .x-grid3-header { + position: relative; +} + +/* Fix WebKit bug in Grids */ +.ext-webkit .x-grid-panel .x-panel-bwrap{ + -webkit-user-select:none; +} +.ext-webkit .x-tbar-page-number{ + -webkit-user-select:ignore; +} +/* end*/ + +/* column lines */ +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + padding-right:0; + border-right:1px solid; +} +.x-dd-drag-proxy{ + position:absolute; + left:0; + top:0; + visibility:hidden; + z-index:15000; +} + +.x-dd-drag-ghost{ + -moz-opacity: 0.85; + opacity:.85; + filter: alpha(opacity=85); + border: 1px solid; + padding:3px; + padding-left:20px; + white-space:nowrap; +} + +.x-dd-drag-repair .x-dd-drag-ghost{ + -moz-opacity: 0.4; + opacity:.4; + filter: alpha(opacity=40); + border:0 none; + padding:0; + background-color:transparent; +} + +.x-dd-drag-repair .x-dd-drop-icon{ + visibility:hidden; +} + +.x-dd-drop-icon{ + position:absolute; + top:3px; + left:3px; + display:block; + width:16px; + height:16px; + background-color:transparent; + background-position: center; + background-repeat: no-repeat; + z-index:1; +} + +.x-view-selector { + position:absolute; + left:0; + top:0; + width:0; + border:1px dotted; + opacity: .5; + -moz-opacity: .5; + filter:alpha(opacity=50); + zoom:1; +}.ext-strict .ext-ie .x-tree .x-panel-bwrap{ + position:relative; + overflow:hidden; +} + +.x-tree-icon, .x-tree-ec-icon, .x-tree-elbow-line, .x-tree-elbow, .x-tree-elbow-end, .x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{ + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-repeat: no-repeat; +} + +.x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .x-tree-node-icon{ + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-position:center; + background-repeat: no-repeat; +} + +.ext-ie .x-tree-node-indent img, .ext-ie .x-tree-node-icon, .ext-ie .x-tree-ec-icon { + vertical-align: middle !important; +} + +.ext-strict .ext-ie8 .x-tree-node-indent img, .ext-strict .ext-ie8 .x-tree-node-icon, .ext-strict .ext-ie8 .x-tree-ec-icon { + vertical-align: top !important; +} + +/* checkboxes */ + +input.x-tree-node-cb { + margin-left:1px; + height: 19px; + vertical-align: bottom; +} + +.ext-ie input.x-tree-node-cb { + margin-left:0; + margin-top: 1px; + width: 16px; + height: 16px; + vertical-align: middle; +} + +.ext-strict .ext-ie8 input.x-tree-node-cb{ + margin: 1px 1px; + height: 14px; + vertical-align: bottom; +} + +.ext-strict .ext-ie8 input.x-tree-node-cb + a{ + vertical-align: bottom; +} + +.ext-opera input.x-tree-node-cb { + height: 14px; + vertical-align: middle; +} + +.x-tree-noicon .x-tree-node-icon{ + width:0; height:0; +} + +/* No line styles */ +.x-tree-no-lines .x-tree-elbow{ + background:transparent; +} + +.x-tree-no-lines .x-tree-elbow-end{ + background:transparent; +} + +.x-tree-no-lines .x-tree-elbow-line{ + background:transparent; +} + +/* Arrows */ +.x-tree-arrows .x-tree-elbow{ + background:transparent; +} + +.x-tree-arrows .x-tree-elbow-plus{ + background:transparent no-repeat 0 0; +} + +.x-tree-arrows .x-tree-elbow-minus{ + background:transparent no-repeat -16px 0; +} + +.x-tree-arrows .x-tree-elbow-end{ + background:transparent; +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background:transparent no-repeat 0 0; +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background:transparent no-repeat -16px 0; +} + +.x-tree-arrows .x-tree-elbow-line{ + background:transparent; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-plus{ + background-position:-32px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-minus{ + background-position:-48px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-plus{ + background-position:-32px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-minus{ + background-position:-48px 0; +} + +.x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{ + cursor:pointer; +} + +.ext-ie ul.x-tree-node-ct{ + font-size:0; + line-height:0; + zoom:1; +} + +.x-tree-node{ + white-space: nowrap; +} + +.x-tree-node-el { + line-height:18px; + cursor:pointer; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + text-decoration:none; + -khtml-user-select:none; + -moz-user-select:none; + -webkit-user-select:ignore; + -kthml-user-focus:normal; + -moz-user-focus:normal; + -moz-outline: 0 none; + outline:0 none; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + text-decoration:none; + padding:1px 3px 1px 2px; +} + +.x-tree-node .x-tree-node-disabled .x-tree-node-icon{ + -moz-opacity: 0.5; + opacity:.5; + filter: alpha(opacity=50); +} + +.x-tree-node .x-tree-node-inline-icon{ + background:transparent; +} + +.x-tree-node a:hover, .x-dd-drag-ghost a:hover{ + text-decoration:none; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom:1px dotted; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top:1px dotted; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below{ + border-bottom:0 none; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above{ + border-top:0 none; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom:2px solid; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top:2px solid; +} + +.x-tree-node .x-tree-drag-append a span{ + border:1px dotted; +} + +.x-dd-drag-ghost .x-tree-node-indent, .x-dd-drag-ghost .x-tree-ec-icon{ + display:none !important; +} + +/* Fix for ie rootVisible:false issue */ +.x-tree-root-ct { + zoom:1; +} +.x-date-picker { + border: 1px solid; + border-top:0 none; + position:relative; +} + +.x-date-picker a { + -moz-outline:0 none; + outline:0 none; +} + +.x-date-inner, .x-date-inner td, .x-date-inner th{ + border-collapse:separate; +} + +.x-date-middle,.x-date-left,.x-date-right { + background: repeat-x 0 -83px; + overflow:hidden; +} + +.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr, +.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr, +.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{ + background:transparent !important; + vertical-align:middle; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background:transparent no-repeat right 0; +} + +.x-date-right, .x-date-left { + width:18px; +} + +.x-date-right{ + text-align:right; +} + +.x-date-middle { + padding-top:2px; + padding-bottom:2px; + width:130px; /* FF3 */ +} + +.x-date-right a, .x-date-left a{ + display:block; + width:16px; + height:16px; + background-position: center; + background-repeat: no-repeat; + cursor:pointer; + -moz-opacity: 0.6; + opacity:.6; + filter: alpha(opacity=60); +} + +.x-date-right a:hover, .x-date-left a:hover{ + -moz-opacity: 1; + opacity:1; + filter: alpha(opacity=100); +} + +.x-item-disabled .x-date-right a:hover, .x-item-disabled .x-date-left a:hover{ + -moz-opacity: 0.6; + opacity:.6; + filter: alpha(opacity=60); +} + +.x-date-right a { + margin-right:2px; + text-decoration:none !important; +} + +.x-date-left a{ + margin-left:2px; + text-decoration:none !important; +} + +table.x-date-inner { + width: 100%; + table-layout:fixed; +} + +.ext-webkit table.x-date-inner{ + /* Fix for webkit browsers */ + width: 175px; +} + + +.x-date-inner th { + width:25px; +} + +.x-date-inner th { + background: repeat-x left top; + text-align:right !important; + border-bottom: 1px solid; + cursor:default; + padding:0; + border-collapse:separate; +} + +.x-date-inner th span { + display:block; + padding:2px; + padding-right:7px; +} + +.x-date-inner td { + border: 1px solid; + text-align:right; + padding:0; +} + +.x-date-inner a { + padding:2px 5px; + display:block; + text-decoration:none; + text-align:right; + zoom:1; +} + +.x-date-inner .x-date-active{ + cursor:pointer; + color:black; +} + +.x-date-inner .x-date-selected a{ + background: repeat-x left top; + border:1px solid; + padding:1px 4px; +} + +.x-date-inner .x-date-today a{ + border: 1px solid; + padding:1px 4px; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + text-decoration:none !important; +} + +.x-date-bottom { + padding:4px; + border-top: 1px solid; + background: repeat-x left top; +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + text-decoration:none !important; +} + +.x-item-disabled .x-date-inner a:hover{ + background: none; +} + +.x-date-inner .x-date-disabled a { + cursor:default; +} + +.x-date-menu .x-menu-item { + padding:1px 24px 1px 4px; + white-space: nowrap; +} + +.x-date-menu .x-menu-item .x-menu-item-icon { + width:10px; + height:10px; + margin-right:5px; + background-position:center -4px !important; +} + +.x-date-mp { + position:absolute; + left:0; + top:0; + display:none; +} + +.x-date-mp td { + padding:2px; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn { + border: 0 none; + text-align:center; + vertical-align: middle; + width:25%; +} + +.x-date-mp-ok { + margin-right:3px; +} + +.x-date-mp-btns button { + text-decoration:none; + text-align:center; + text-decoration:none !important; + border:1px solid; + padding:1px 3px 1px; + cursor:pointer; +} + +.x-date-mp-btns { + background: repeat-x left top; +} + +.x-date-mp-btns td { + border-top: 1px solid; + text-align:center; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + display:block; + padding:2px 4px; + text-decoration:none; + text-align:center; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + text-decoration:none; + cursor:pointer; +} + +td.x-date-mp-sel a { + padding:1px 3px; + background: repeat-x left top; + border:1px solid; +} + +.x-date-mp-ybtn a { + overflow:hidden; + width:15px; + height:15px; + cursor:pointer; + background:transparent no-repeat; + display:block; + margin:0 auto; +} + +.x-date-mp-ybtn a.x-date-mp-next { + background-position:0 -120px; +} + +.x-date-mp-ybtn a.x-date-mp-next:hover { + background-position:-15px -120px; +} + +.x-date-mp-ybtn a.x-date-mp-prev { + background-position:0 -105px; +} + +.x-date-mp-ybtn a.x-date-mp-prev:hover { + background-position:-15px -105px; +} + +.x-date-mp-ybtn { + text-align:center; +} + +td.x-date-mp-sep { + border-right:1px solid; +}.x-tip{ + position: absolute; + top: 0; + left:0; + visibility: hidden; + z-index: 20002; + border:0 none; +} + +.x-tip .x-tip-close{ + height: 15px; + float:right; + width: 15px; + margin:0 0 2px 2px; + cursor:pointer; + display:none; +} + +.x-tip .x-tip-tc { + background: transparent no-repeat 0 -62px; + padding-top:3px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-tr { + background: transparent no-repeat right 0; + padding-right:6px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-bc { + background: transparent no-repeat 0 -121px; + height:3px; + overflow:hidden; +} + +.x-tip .x-tip-bl { + background: transparent no-repeat 0 -59px; + padding-left:6px; + zoom:1; +} + +.x-tip .x-tip-br { + background: transparent no-repeat right -59px; + padding-right:6px; + zoom:1; +} + +.x-tip .x-tip-mc { + border:0 none; +} + +.x-tip .x-tip-ml { + background: no-repeat 0 -124px; + padding-left:6px; + zoom:1; +} + +.x-tip .x-tip-mr { + background: transparent no-repeat right -124px; + padding-right:6px; + zoom:1; +} + +.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc { + font-size:0; + line-height:0; +} + +.ext-border-box .x-tip .x-tip-header, .ext-border-box .x-tip .x-tip-tc{ + line-height: 1px; +} + +.x-tip .x-tip-header-text { + padding:0; + margin:0 0 2px 0; +} + +.x-tip .x-tip-body { + margin:0 !important; + line-height:14px; + padding:0; +} + +.x-tip .x-tip-body .loading-indicator { + margin:0; +} + +.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text { + cursor:move; +} + +.x-form-invalid-tip .x-tip-tc { + background: repeat-x 0 -12px; + padding-top:6px; +} + +.x-form-invalid-tip .x-tip-bc { + background: repeat-x 0 -18px; + height:6px; +} + +.x-form-invalid-tip .x-tip-bl { + background: no-repeat 0 -6px; +} + +.x-form-invalid-tip .x-tip-br { + background: no-repeat right -6px; +} + +.x-form-invalid-tip .x-tip-body { + padding:2px; +} + +.x-form-invalid-tip .x-tip-body { + padding-left:24px; + background:transparent no-repeat 2px 2px; +} + +.x-tip-anchor { + position: absolute; + width: 9px; + height: 10px; + overflow:hidden; + background: transparent no-repeat 0 0; + zoom:1; +} +.x-tip-anchor-bottom { + background-position: -9px 0; +} +.x-tip-anchor-right { + background-position: -18px 0; + width: 10px; +} +.x-tip-anchor-left { + background-position: -28px 0; + width: 10px; +}.x-menu { + z-index: 15000; + zoom: 1; + background: repeat-y; +} + +.x-menu-floating{ + border: 1px solid; +} + +.x-menu a { + text-decoration: none !important; +} + +.ext-ie .x-menu { + zoom:1; + overflow:hidden; +} + +.x-menu-list{ + padding: 2px; + background:transparent; + border:0 none; + overflow:hidden; + overflow-y: hidden; +} + +.ext-strict .ext-ie .x-menu-list{ + position: relative; +} + +.x-menu li{ + line-height:100%; +} + +.x-menu li.x-menu-sep-li{ + font-size:1px; + line-height:1px; +} + +.x-menu-list-item{ + white-space: nowrap; + display:block; + padding:1px; +} + +.x-menu-item{ + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-menu-item-arrow{ + background:transparent no-repeat right; +} + +.x-menu-sep { + display:block; + font-size:1px; + line-height:1px; + margin: 2px 3px; + border-bottom:1px solid; + overflow:hidden; +} + +.x-menu-focus { + position:absolute; + left:-1px; + top:-1px; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; + overflow:hidden; + display:block; +} + +a.x-menu-item { + cursor: pointer; + display: block; + line-height: 16px; + outline-color: -moz-use-text-color; + outline-style: none; + outline-width: 0; + padding: 3px 21px 3px 27px; + position: relative; + text-decoration: none; + white-space: nowrap; +} + +.x-menu-item-active { + background-repeat: repeat-x; + background-position: left bottom; + border-style:solid; + border-width: 1px 0; + margin:0 1px; + padding: 0; +} + +.x-menu-item-active a.x-menu-item { + border-style:solid; + border-width:0 1px; + margin:0 -1px; +} + +.x-menu-item-icon { + border: 0 none; + height: 16px; + padding: 0; + vertical-align: top; + width: 16px; + position: absolute; + left: 3px; + top: 3px; + margin: 0; + background-position:center; +} + +.ext-ie .x-menu-item-icon { + left: -24px; +} +.ext-strict .x-menu-item-icon { + left: 3px; +} + +.ext-ie6 .x-menu-item-icon { + left: -24px; +} + +.ext-ie .x-menu-item-icon { + vertical-align: middle; +} + +.x-menu-check-item .x-menu-item-icon{ + background: transparent no-repeat center; +} + +.x-menu-group-item .x-menu-item-icon{ + background: transparent; +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background: transparent no-repeat center; +} + +.x-date-menu .x-menu-list{ + padding: 0; +} + +.x-menu-date-item{ + padding:0; +} + +.x-menu .x-color-palette, .x-menu .x-date-picker{ + margin-left: 26px; + margin-right:4px; +} + +.x-menu .x-date-picker{ + border:1px solid; + margin-top:2px; + margin-bottom:2px; +} + +.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{ + margin: 0; + border: 0 none; +} + +.x-date-menu { + padding:0 !important; +} + +/* + * fixes separator visibility problem in IE 6 + */ +.ext-strict .ext-ie6 .x-menu-sep-li { + padding: 3px 4px; +} +.ext-strict .ext-ie6 .x-menu-sep { + margin: 0; + height: 1px; +} + +/* + * Ugly mess to remove the white border under the picker + */ +.ext-ie .x-date-menu{ + height: 199px; +} + +.ext-strict .ext-ie .x-date-menu, .ext-border-box .ext-ie8 .x-date-menu{ + height: 197px; +} + +.ext-strict .ext-ie7 .x-date-menu{ + height: 195px; +} + +.ext-strict .ext-ie8 .x-date-menu{ + height: auto; +} + +.x-cycle-menu .x-menu-item-checked { + border:1px dotted !important; + padding:0; +} + +.x-menu .x-menu-scroller { + width: 100%; + background-repeat:no-repeat; + background-position:center; + height:8px; + line-height: 8px; + cursor:pointer; + margin: 0; + padding: 0; +} + +.x-menu .x-menu-scroller-active{ + height: 6px; + line-height: 6px; +} + +.x-menu-list-item-indent{ + padding-left: 27px; +}/* + Creates rounded, raised boxes like on the Ext website - the markup isn't pretty: +
    +
    +
    +

    YOUR TITLE HERE (optional)

    +
    YOUR CONTENT HERE
    +
    +
    +
    + */ + +.x-box-tl { + background: transparent no-repeat 0 0; + zoom:1; +} + +.x-box-tc { + height: 8px; + background: transparent repeat-x 0 0; + overflow: hidden; +} + +.x-box-tr { + background: transparent no-repeat right -8px; +} + +.x-box-ml { + background: transparent repeat-y 0; + padding-left: 4px; + overflow: hidden; + zoom:1; +} + +.x-box-mc { + background: repeat-x 0 -16px; + padding: 4px 10px; +} + +.x-box-mc h3 { + margin: 0 0 4px 0; + zoom:1; +} + +.x-box-mr { + background: transparent repeat-y right; + padding-right: 4px; + overflow: hidden; +} + +.x-box-bl { + background: transparent no-repeat 0 -16px; + zoom:1; +} + +.x-box-bc { + background: transparent repeat-x 0 -8px; + height: 8px; + overflow: hidden; +} + +.x-box-br { + background: transparent no-repeat right -24px; +} + +.x-box-tl, .x-box-bl { + padding-left: 8px; + overflow: hidden; +} + +.x-box-tr, .x-box-br { + padding-right: 8px; + overflow: hidden; +}.x-combo-list { + border:1px solid; + zoom:1; + overflow:hidden; +} + +.x-combo-list-inner { + overflow:auto; + position:relative; /* for calculating scroll offsets */ + zoom:1; + overflow-x:hidden; +} + +.x-combo-list-hd { + border-bottom:1px solid; + padding:3px; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom:1px solid; +} + +.x-combo-list-item { + padding:2px; + border:1px solid; + white-space: nowrap; + overflow:hidden; + text-overflow: ellipsis; +} + +.x-combo-list .x-combo-selected{ + border:1px dotted !important; + cursor:pointer; +} + +.x-combo-list .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +}.x-panel { + border-style: solid; + border-width:0; +} + +.x-panel-header { + overflow:hidden; + zoom:1; + padding:5px 3px 4px 5px; + border:1px solid; + line-height: 15px; + background: transparent repeat-x 0 -1px; +} + +.x-panel-body { + border:1px solid; + border-top:0 none; + overflow:hidden; + position: relative; /* added for item scroll positioning */ +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top:1px solid; + border-bottom: 0 none; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top:1px solid; +} + +.x-panel-header { + overflow:hidden; + zoom:1; +} + +.x-panel-tl .x-panel-header { + padding:5px 0 4px 0; + border:0 none; + background:transparent; +} + +.x-panel-tl .x-panel-icon, .x-window-tl .x-panel-icon { + padding-left:20px !important; + background-repeat:no-repeat; + background-position:0 4px; + zoom:1; +} + +.x-panel-inline-icon { + width:16px; + height:16px; + background-repeat:no-repeat; + background-position:0 0; + vertical-align:middle; + margin-right:4px; + margin-top:-1px; + margin-bottom:-1px; +} + +.x-panel-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} + +/* fix ie7 strict mode bug */ +.ext-strict .ext-ie7 .x-panel-tc { + overflow: visible; +} + +.x-panel-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + border-bottom:1px solid; +} + +.x-panel-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:6px; +} + +.x-panel-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-panel-bc .x-panel-footer { + zoom:1; +} + +.x-panel-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} + +.x-panel-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} + +.x-panel-mc { + border:0 none; + padding:0; + margin:0; + padding-top:6px; +} + +.x-panel-mc .x-panel-body { + background:transparent; + border: 0 none; +} + +.x-panel-ml { + background: repeat-y 0 0; + padding-left:6px; + zoom:1; +} + +.x-panel-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} + +.x-panel-bc .x-panel-footer { + padding-bottom:6px; +} + +.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc { + height:6px; + font-size:0; + line-height:0; +} + +.x-panel-bwrap { + overflow:hidden; + zoom:1; + left:0; + top:0; +} +.x-panel-body { + overflow:hidden; + zoom:1; +} + +.x-panel-collapsed .x-resizable-handle{ + display:none; +} + +.ext-gecko .x-panel-animated div { + overflow:hidden !important; +} + +/* Plain */ +.x-plain-body { + overflow:hidden; +} + +.x-plain-bbar .x-toolbar { + overflow:hidden; + padding:2px; +} + +.x-plain-tbar .x-toolbar { + overflow:hidden; + padding:2px; +} + +.x-plain-bwrap { + overflow:hidden; + zoom:1; +} + +.x-plain { + overflow:hidden; +} + +/* Tools */ +.x-tool { + overflow:hidden; + width:15px; + height:15px; + float:right; + cursor:pointer; + background:transparent no-repeat; + margin-left:2px; +} + +/* expand / collapse tools */ +.x-tool-toggle { + background-position:0 -60px; +} + +.x-tool-toggle-over { + background-position:-15px -60px; +} + +.x-panel-collapsed .x-tool-toggle { + background-position:0 -75px; +} + +.x-panel-collapsed .x-tool-toggle-over { + background-position:-15px -75px; +} + + +.x-tool-close { + background-position:0 -0; +} + +.x-tool-close-over { + background-position:-15px 0; +} + +.x-tool-minimize { + background-position:0 -15px; +} + +.x-tool-minimize-over { + background-position:-15px -15px; +} + +.x-tool-maximize { + background-position:0 -30px; +} + +.x-tool-maximize-over { + background-position:-15px -30px; +} + +.x-tool-restore { + background-position:0 -45px; +} + +.x-tool-restore-over { + background-position:-15px -45px; +} + +.x-tool-gear { + background-position:0 -90px; +} + +.x-tool-gear-over { + background-position:-15px -90px; +} + +.x-tool-pin { + background-position:0 -135px; +} + +.x-tool-pin-over { + background-position:-15px -135px; +} + +.x-tool-unpin { + background-position:0 -150px; +} + +.x-tool-unpin-over { + background-position:-15px -150px; +} + +.x-tool-right { + background-position:0 -165px; +} + +.x-tool-right-over { + background-position:-15px -165px; +} + +.x-tool-left { + background-position:0 -180px; +} + +.x-tool-left-over { + background-position:-15px -180px; +} + +.x-tool-up { + background-position:0 -210px; +} + +.x-tool-up-over { + background-position:-15px -210px; +} + +.x-tool-down { + background-position:0 -195px; +} + +.x-tool-down-over { + background-position:-15px -195px; +} + +.x-tool-refresh { + background-position:0 -225px; +} + +.x-tool-refresh-over { + background-position:-15px -225px; +} + +.x-tool-minus { + background-position:0 -255px; +} + +.x-tool-minus-over { + background-position:-15px -255px; +} + +.x-tool-plus { + background-position:0 -240px; +} + +.x-tool-plus-over { + background-position:-15px -240px; +} + +.x-tool-search { + background-position:0 -270px; +} + +.x-tool-search-over { + background-position:-15px -270px; +} + +.x-tool-save { + background-position:0 -285px; +} + +.x-tool-save-over { + background-position:-15px -285px; +} + +.x-tool-help { + background-position:0 -300px; +} + +.x-tool-help-over { + background-position:-15px -300px; +} + +.x-tool-print { + background-position:0 -315px; +} + +.x-tool-print-over { + background-position:-15px -315px; +} + +/* Ghosting */ +.x-panel-ghost { + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + opacity:.65; + -moz-opacity:.65; + filter:alpha(opacity=65); +} + +.x-panel-ghost ul { + margin:0; + padding:0; + overflow:hidden; + font-size:0; + line-height:0; + border:1px solid; + border-top:0 none; + display:block; +} + +.x-panel-ghost * { + cursor:move !important; +} + +.x-panel-dd-spacer { + border:2px dashed; +} + +/* Buttons */ +.x-panel-btns { + padding:5px; + overflow:hidden; +} + +.x-panel-btns td.x-toolbar-cell{ + padding:3px; +} + +.x-panel-btns .x-btn-focus .x-btn-left{ + background-position:0 -147px; +} + +.x-panel-btns .x-btn-focus .x-btn-right{ + background-position:0 -168px; +} + +.x-panel-btns .x-btn-focus .x-btn-center{ + background-position:0 -189px; +} + +.x-panel-btns .x-btn-over .x-btn-left{ + background-position:0 -63px; +} + +.x-panel-btns .x-btn-over .x-btn-right{ + background-position:0 -84px; +} + +.x-panel-btns .x-btn-over .x-btn-center{ + background-position:0 -105px; +} + +.x-panel-btns .x-btn-click .x-btn-center{ + background-position:0 -126px; +} + +.x-panel-btns .x-btn-click .x-btn-right{ + background-position:0 -84px; +} + +.x-panel-btns .x-btn-click .x-btn-left{ + background-position:0 -63px; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + white-space: nowrap; +} +/** + * W3C Suggested Default style sheet for HTML 4 + * http://www.w3.org/TR/CSS21/sample.html + * + * Resets for Ext.Panel @cfg normal: true + */ +.x-panel-reset .x-panel-body html, +.x-panel-reset .x-panel-body address, +.x-panel-reset .x-panel-body blockquote, +.x-panel-reset .x-panel-body body, +.x-panel-reset .x-panel-body dd, +.x-panel-reset .x-panel-body div, +.x-panel-reset .x-panel-body dl, +.x-panel-reset .x-panel-body dt, +.x-panel-reset .x-panel-body fieldset, +.x-panel-reset .x-panel-body form, +.x-panel-reset .x-panel-body frame, frameset, +.x-panel-reset .x-panel-body h1, +.x-panel-reset .x-panel-body h2, +.x-panel-reset .x-panel-body h3, +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body h5, +.x-panel-reset .x-panel-body h6, +.x-panel-reset .x-panel-body noframes, +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body p, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body center, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body hr, +.x-panel-reset .x-panel-body menu, +.x-panel-reset .x-panel-body pre { display: block } +.x-panel-reset .x-panel-body li { display: list-item } +.x-panel-reset .x-panel-body head { display: none } +.x-panel-reset .x-panel-body table { display: table } +.x-panel-reset .x-panel-body tr { display: table-row } +.x-panel-reset .x-panel-body thead { display: table-header-group } +.x-panel-reset .x-panel-body tbody { display: table-row-group } +.x-panel-reset .x-panel-body tfoot { display: table-footer-group } +.x-panel-reset .x-panel-body col { display: table-column } +.x-panel-reset .x-panel-body colgroup { display: table-column-group } +.x-panel-reset .x-panel-body td, +.x-panel-reset .x-panel-body th { display: table-cell } +.x-panel-reset .x-panel-body caption { display: table-caption } +.x-panel-reset .x-panel-body th { font-weight: bolder; text-align: center } +.x-panel-reset .x-panel-body caption { text-align: center } +.x-panel-reset .x-panel-body body { margin: 8px } +.x-panel-reset .x-panel-body h1 { font-size: 2em; margin: .67em 0 } +.x-panel-reset .x-panel-body h2 { font-size: 1.5em; margin: .75em 0 } +.x-panel-reset .x-panel-body h3 { font-size: 1.17em; margin: .83em 0 } +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body p, +.x-panel-reset .x-panel-body blockquote, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body fieldset, +.x-panel-reset .x-panel-body form, +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body dl, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body menu { margin: 1.12em 0 } +.x-panel-reset .x-panel-body h5 { font-size: .83em; margin: 1.5em 0 } +.x-panel-reset .x-panel-body h6 { font-size: .75em; margin: 1.67em 0 } +.x-panel-reset .x-panel-body h1, +.x-panel-reset .x-panel-body h2, +.x-panel-reset .x-panel-body h3, +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body h5, +.x-panel-reset .x-panel-body h6, +.x-panel-reset .x-panel-body b, +.x-panel-reset .x-panel-body strong { font-weight: bolder } +.x-panel-reset .x-panel-body blockquote { margin-left: 40px; margin-right: 40px } +.x-panel-reset .x-panel-body i, +.x-panel-reset .x-panel-body cite, +.x-panel-reset .x-panel-body em, +.x-panel-reset .x-panel-body var, +.x-panel-reset .x-panel-body address { font-style: italic } +.x-panel-reset .x-panel-body pre, +.x-panel-reset .x-panel-body tt, +.x-panel-reset .x-panel-body code, +.x-panel-reset .x-panel-body kbd, +.x-panel-reset .x-panel-body samp { font-family: monospace } +.x-panel-reset .x-panel-body pre { white-space: pre } +.x-panel-reset .x-panel-body button, +.x-panel-reset .x-panel-body textarea, +.x-panel-reset .x-panel-body input, +.x-panel-reset .x-panel-body select { display: inline-block } +.x-panel-reset .x-panel-body big { font-size: 1.17em } +.x-panel-reset .x-panel-body small, +.x-panel-reset .x-panel-body sub, +.x-panel-reset .x-panel-body sup { font-size: .83em } +.x-panel-reset .x-panel-body sub { vertical-align: sub } +.x-panel-reset .x-panel-body sup { vertical-align: super } +.x-panel-reset .x-panel-body table { border-spacing: 2px; } +.x-panel-reset .x-panel-body thead, +.x-panel-reset .x-panel-body tbody, +.x-panel-reset .x-panel-body tfoot { vertical-align: middle } +.x-panel-reset .x-panel-body td, +.x-panel-reset .x-panel-body th { vertical-align: inherit } +.x-panel-reset .x-panel-body s, +.x-panel-reset .x-panel-body strike, +.x-panel-reset .x-panel-body del { text-decoration: line-through } +.x-panel-reset .x-panel-body hr { border: 1px inset } +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body menu, +.x-panel-reset .x-panel-body dd { margin-left: 40px } +.x-panel-reset .x-panel-body ul, .x-panel-reset .x-panel-body menu, .x-panel-reset .x-panel-body dir { list-style-type: disc;} +.x-panel-reset .x-panel-body ol { list-style-type: decimal } +.x-panel-reset .x-panel-body ol ul, +.x-panel-reset .x-panel-body ul ol, +.x-panel-reset .x-panel-body ul ul, +.x-panel-reset .x-panel-body ol ol { margin-top: 0; margin-bottom: 0 } +.x-panel-reset .x-panel-body u, +.x-panel-reset .x-panel-body ins { text-decoration: underline } +.x-panel-reset .x-panel-body br:before { content: "\A" } +.x-panel-reset .x-panel-body :before, .x-panel-reset .x-panel-body :after { white-space: pre-line } +.x-panel-reset .x-panel-body center { text-align: center } +.x-panel-reset .x-panel-body :link, .x-panel-reset .x-panel-body :visited { text-decoration: underline } +.x-panel-reset .x-panel-body :focus { outline: invert dotted thin } + +/* Begin bidirectionality settings (do not change) */ +.x-panel-reset .x-panel-body BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override } +.x-panel-reset .x-panel-body BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override } +.x-window { + zoom:1; +} + +.x-window .x-window-handle { + opacity:0; + -moz-opacity:0; + filter:alpha(opacity=0); +} + +.x-window-proxy { + border:1px solid; + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + display:none; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} + +.x-window-header { + overflow:hidden; + zoom:1; +} + +.x-window-bwrap { + z-index:1; + position:relative; + zoom:1; + left:0;top:0; +} + +.x-window-tl .x-window-header { + padding:5px 0 4px 0; +} + +.x-window-header-text { + cursor:pointer; +} + +.x-window-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + zoom:1; +} + +.x-window-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + z-index:1; + position:relative; +} + +.x-window-tr { + background: transparent no-repeat right 0; + padding-right:6px; +} + +.x-window-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-window-bc .x-window-footer { + padding-bottom:6px; + zoom:1; + font-size:0; + line-height:0; +} + +.x-window-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} + +.x-window-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} + +.x-window-mc { + border:1px solid; + padding:0; + margin:0; +} + +.x-window-ml { + background: transparent repeat-y 0 0; + padding-left:6px; + zoom:1; +} + +.x-window-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} + +.x-window-body { + overflow:hidden; +} + +.x-window-bwrap { + overflow:hidden; +} + +.x-window-maximized .x-window-bl, .x-window-maximized .x-window-br, + .x-window-maximized .x-window-ml, .x-window-maximized .x-window-mr, + .x-window-maximized .x-window-tl, .x-window-maximized .x-window-tr { + padding:0; +} + +.x-window-maximized .x-window-footer { + padding-bottom:0; +} + +.x-window-maximized .x-window-tc { + padding-left:3px; + padding-right:3px; +} + +.x-window-maximized .x-window-mc { + border-left:0 none; + border-right:0 none; +} + +.x-window-tbar .x-toolbar, .x-window-bbar .x-toolbar { + border-left:0 none; + border-right: 0 none; +} + +.x-window-bbar .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +} + +.x-window-draggable, .x-window-draggable .x-window-header-text { + cursor:move; +} + +.x-window-maximized .x-window-draggable, .x-window-maximized .x-window-draggable .x-window-header-text { + cursor:default; +} + +.x-window-body { + background:transparent; +} + +.x-panel-ghost .x-window-tl { + border-bottom:1px solid; +} + +.x-panel-collapsed .x-window-tl { + border-bottom:1px solid; +} + +.x-window-maximized-ct { + overflow:hidden; +} + +.x-window-maximized .x-window-handle { + display:none; +} + +.x-window-sizing-ghost ul { + border:0 none !important; +} + +.x-dlg-focus{ + -moz-outline:0 none; + outline:0 none; + width:0; + height:0; + overflow:hidden; + position:absolute; + top:0; + left:0; +} + +.ext-webkit .x-dlg-focus{ + width: 1px; + height: 1px; +} + +.x-dlg-mask{ + z-index:10000; + display:none; + position:absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity:.50; + filter: alpha(opacity=50); +} + +body.ext-ie6.x-body-masked select { + visibility:hidden; +} + +body.ext-ie6.x-body-masked .x-window select { + visibility:visible; +} + +.x-window-plain .x-window-mc { + border: 1px solid; +} + +.x-window-plain .x-window-body { + border: 1px solid; + background:transparent !important; +}.x-html-editor-wrap { + border:1px solid; +} + +.x-html-editor-tb .x-btn-text { + background:transparent no-repeat; +} + +.x-html-editor-tb .x-edit-bold, .x-menu-item img.x-edit-bold { + background-position:0 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-italic, .x-menu-item img.x-edit-italic { + background-position:-16px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-underline, .x-menu-item img.x-edit-underline { + background-position:-32px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-forecolor, .x-menu-item img.x-edit-forecolor { + background-position:-160px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-backcolor, .x-menu-item img.x-edit-backcolor { + background-position:-176px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyleft, .x-menu-item img.x-edit-justifyleft { + background-position:-112px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifycenter, .x-menu-item img.x-edit-justifycenter { + background-position:-128px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyright, .x-menu-item img.x-edit-justifyright { + background-position:-144px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertorderedlist, .x-menu-item img.x-edit-insertorderedlist { + background-position:-80px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertunorderedlist, .x-menu-item img.x-edit-insertunorderedlist { + background-position:-96px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-increasefontsize, .x-menu-item img.x-edit-increasefontsize { + background-position:-48px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-decreasefontsize, .x-menu-item img.x-edit-decreasefontsize { + background-position:-64px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-sourceedit, .x-menu-item img.x-edit-sourceedit { + background-position:-192px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-createlink, .x-menu-item img.x-edit-createlink { + background-position:-208px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tip .x-tip-bd .x-tip-bd-inner { + padding:5px; + padding-bottom:1px; +} + +.x-html-editor-tb .x-toolbar { + position:static !important; +}.x-panel-noborder .x-panel-body-noborder { + border-width:0; +} + +.x-panel-noborder .x-panel-header-noborder { + border-width:0 0 1px; + border-style:solid; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-width:1px 0 0 0; + border-style:solid; +} + +.x-window-noborder .x-window-mc { + border-width:0; +} + +.x-window-plain .x-window-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-header-noborder { + border-width: 0 0 1px 0; +} + +.x-tab-panel-noborder .x-tab-panel-footer-noborder { + border-width: 1px 0 0 0; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-width: 1px 0 0 0; + border-style:solid; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +}.x-border-layout-ct { + position: relative; +} + +.x-border-panel { + position:absolute; + left:0; + top:0; +} + +.x-tool-collapse-south { + background-position:0 -195px; +} + +.x-tool-collapse-south-over { + background-position:-15px -195px; +} + +.x-tool-collapse-north { + background-position:0 -210px; +} + +.x-tool-collapse-north-over { + background-position:-15px -210px; +} + +.x-tool-collapse-west { + background-position:0 -180px; +} + +.x-tool-collapse-west-over { + background-position:-15px -180px; +} + +.x-tool-collapse-east { + background-position:0 -165px; +} + +.x-tool-collapse-east-over { + background-position:-15px -165px; +} + +.x-tool-expand-south { + background-position:0 -210px; +} + +.x-tool-expand-south-over { + background-position:-15px -210px; +} + +.x-tool-expand-north { + background-position:0 -195px; +} +.x-tool-expand-north-over { + background-position:-15px -195px; +} + +.x-tool-expand-west { + background-position:0 -165px; +} + +.x-tool-expand-west-over { + background-position:-15px -165px; +} + +.x-tool-expand-east { + background-position:0 -180px; +} + +.x-tool-expand-east-over { + background-position:-15px -180px; +} + +.x-tool-expand-north, .x-tool-expand-south { + float:right; + margin:3px; +} + +.x-tool-expand-east, .x-tool-expand-west { + float:none; + margin:3px auto; +} + +.x-accordion-hd .x-tool-toggle { + background-position:0 -255px; +} + +.x-accordion-hd .x-tool-toggle-over { + background-position:-15px -255px; +} + +.x-panel-collapsed .x-accordion-hd .x-tool-toggle { + background-position:0 -240px; +} + +.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over { + background-position:-15px -240px; +} + +.x-accordion-hd { + padding-top:4px; + padding-bottom:3px; + border-top:0 none; + background: transparent repeat-x 0 -9px; +} + +.x-layout-collapsed{ + position:absolute; + left:-10000px; + top:-10000px; + visibility:hidden; + width:20px; + height:20px; + overflow:hidden; + border:1px solid; + z-index:20; +} + +.ext-border-box .x-layout-collapsed{ + width:22px; + height:22px; +} + +.x-layout-collapsed-over{ + cursor:pointer; +} + +.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{ + position:absolute; + top:0; + left:0; + width:20px; + height:20px; +} + + +.x-layout-split{ + position:absolute; + height:5px; + width:5px; + line-height:1px; + font-size:1px; + z-index:3; + background-color:transparent; +} + +/* IE6 strict won't drag w/out a color */ +.ext-strict .ext-ie6 .x-layout-split{ + background-color: #fff !important; + filter: alpha(opacity=1); +} + +.x-layout-split-h{ + background-image:url(../images/default/s.gif); + background-position: left; +} + +.x-layout-split-v{ + background-image:url(../images/default/s.gif); + background-position: top; +} + +.x-column-layout-ct { + overflow:hidden; + zoom:1; +} + +.x-column { + float:left; + padding:0; + margin:0; + overflow:hidden; + zoom:1; +} + +.x-column-inner { + overflow:hidden; + zoom:1; +} + +/* mini mode */ +.x-layout-mini { + position:absolute; + top:0; + left:0; + display:block; + width:5px; + height:35px; + cursor:pointer; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} + +.x-layout-mini-over, .x-layout-collapsed-over .x-layout-mini{ + opacity:1; + -moz-opacity:1; + filter:none; +} + +.x-layout-split-west .x-layout-mini { + top:48%; +} + +.x-layout-split-east .x-layout-mini { + top:48%; +} + +.x-layout-split-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-split-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-west .x-layout-mini { + top:48%; +} + +.x-layout-cmini-east .x-layout-mini { + top:48%; +} + +.x-layout-cmini-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-west, .x-layout-cmini-east { + border:0 none; + width:5px !important; + padding:0; + background:transparent; +} + +.x-layout-cmini-north, .x-layout-cmini-south { + border:0 none; + height:5px !important; + padding:0; + background:transparent; +} + +.x-viewport, .x-viewport body { + margin: 0; + padding: 0; + border: 0 none; + overflow: hidden; + height: 100%; +} + +.x-abs-layout-item { + position:absolute; + left:0; + top:0; +} + +.ext-ie input.x-abs-layout-item, .ext-ie textarea.x-abs-layout-item { + margin:0; +} + +.x-box-layout-ct { + overflow:hidden; + zoom:1; +} + +.x-box-inner { + overflow:hidden; + zoom:1; + position:relative; + left:0; + top:0; +} + +.x-box-item { + position:absolute; + left:0; + top:0; +}.x-progress-wrap { + border:1px solid; + overflow:hidden; +} + +.x-progress-inner { + height:18px; + background:repeat-x; + position:relative; +} + +.x-progress-bar { + height:18px; + float:left; + width:0; + background: repeat-x left center; + border-top:1px solid; + border-bottom:1px solid; + border-right:1px solid; +} + +.x-progress-text { + padding:1px 5px; + overflow:hidden; + position:absolute; + left:0; + text-align:center; +} + +.x-progress-text-back { + line-height:16px; +} + +.ext-ie .x-progress-text-back { + line-height:15px; +} + +.ext-strict .ext-ie7 .x-progress-text-back{ + width: 100%; +} +.x-list-header{ + background: repeat-x 0 bottom; + cursor:default; + zoom:1; + height:22px; +} + +.x-list-header-inner div { + display:block; + float:left; + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} + +.x-list-header-inner div em { + display:block; + border-left:1px solid; + padding:4px 4px; + overflow:hidden; + -moz-user-select: none; + -khtml-user-select: none; + line-height:14px; +} + +.x-list-body { + overflow:auto; + overflow-x:hidden; + overflow-y:auto; + zoom:1; + float: left; + width: 100%; +} + +.x-list-body dl { + zoom:1; +} + +.x-list-body dt { + display:block; + float:left; + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + cursor:pointer; + zoom:1; +} + +.x-list-body dt em { + display:block; + padding:3px 4px; + overflow:hidden; + -moz-user-select: none; + -khtml-user-select: none; +} + +.x-list-resizer { + border-left:1px solid; + border-right:1px solid; + position:absolute; + left:0; + top:0; +} + +.x-list-header-inner em.sort-asc { + background: transparent no-repeat center 0; + border-style:solid; + border-width: 0 1px 1px; + padding-bottom:3px; +} + +.x-list-header-inner em.sort-desc { + background: transparent no-repeat center -23px; + border-style:solid; + border-width: 0 1px 1px; + padding-bottom:3px; +} + +/* Shared styles */ +.x-slider { + zoom:1; +} + +.x-slider-inner { + position:relative; + left:0; + top:0; + overflow:visible; + zoom:1; +} + +.x-slider-focus { + position:absolute; + left:0; + top:0; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; + display:block; + overflow:hidden; +} + +/* Horizontal styles */ +.x-slider-horz { + padding-left:7px; + background:transparent no-repeat 0 -22px; +} + +.x-slider-horz .x-slider-end { + padding-right:7px; + zoom:1; + background:transparent no-repeat right -44px; +} + +.x-slider-horz .x-slider-inner { + background:transparent repeat-x 0 0; + height:22px; +} + +.x-slider-horz .x-slider-thumb { + width:14px; + height:15px; + position:absolute; + left:0; + top:3px; + background:transparent no-repeat 0 0; +} + +.x-slider-horz .x-slider-thumb-over { + background-position: -14px -15px; +} + +.x-slider-horz .x-slider-thumb-drag { + background-position: -28px -30px; +} + +/* Vertical styles */ +.x-slider-vert { + padding-top:7px; + background:transparent no-repeat -44px 0; + width:22px; +} + +.x-slider-vert .x-slider-end { + padding-bottom:7px; + zoom:1; + background:transparent no-repeat -22px bottom; +} + +.x-slider-vert .x-slider-inner { + background:transparent repeat-y 0 0; +} + +.x-slider-vert .x-slider-thumb { + width:15px; + height:14px; + position:absolute; + left:3px; + bottom:0; + background:transparent no-repeat 0 0; +} + +.x-slider-vert .x-slider-thumb-over { + background-position: -15px -14px; +} + +.x-slider-vert .x-slider-thumb-drag { + background-position: -30px -28px; +}.x-window-dlg .x-window-body { + border:0 none !important; + padding:5px 10px; + overflow:hidden !important; +} + +.x-window-dlg .x-window-mc { + border:0 none !important; +} + +.x-window-dlg .ext-mb-input { + margin-top:4px; + width:95%; +} + +.x-window-dlg .ext-mb-textarea { + margin-top:4px; +} + +.x-window-dlg .x-progress-wrap { + margin-top:4px; +} + +.ext-ie .x-window-dlg .x-progress-wrap { + margin-top:6px; +} + +.x-window-dlg .x-msg-box-wait { + background:transparent no-repeat left; + display:block; + width:300px; + padding-left:18px; + line-height:18px; +} + +.x-window-dlg .ext-mb-icon { + float:left; + width:47px; + height:32px; +} + +.ext-ie .x-window-dlg .ext-mb-icon { + width:44px; /* 3px IE margin issue */ +} + +.x-window-dlg .x-dlg-icon .ext-mb-content{ + zoom: 1; margin-left: 47px; +} + +.x-window-dlg .ext-mb-info, .x-window-dlg .ext-mb-warning, .x-window-dlg .ext-mb-question, .x-window-dlg .ext-mb-error { + background:transparent no-repeat top left; +} + +.ext-gecko2 .ext-mb-fix-cursor { + overflow:auto; +} \ No newline at end of file diff --git a/workflow/public_html/skins/ext/ext-all.css b/workflow/public_html/skins/ext/ext-all.css new file mode 100755 index 000000000..d299984e1 --- /dev/null +++ b/workflow/public_html/skins/ext/ext-all.css @@ -0,0 +1,6789 @@ +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}.ext-el-mask { + z-index: 100; + position: absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity=50); + width: 100%; + height: 100%; + zoom: 1; +} + +.ext-el-mask-msg { + z-index: 20001; + position: absolute; + top: 0; + left: 0; + border:1px solid; + background:repeat-x 0 -16px; + padding:2px; +} + +.ext-el-mask-msg div { + padding:5px 10px 5px 10px; + border:1px solid; + cursor:wait; +} + +.ext-shim { + position:absolute; + visibility:hidden; + left:0; + top:0; + overflow:hidden; +} + +.ext-ie .ext-shim { + filter: alpha(opacity=0); +} + +.ext-ie6 .ext-shim { + margin-left: 5px; + margin-top: 3px; +} + +.x-mask-loading div { + padding:5px 10px 5px 25px; + background:no-repeat 5px 5px; + line-height:16px; +} + +/* class for hiding elements without using display:none */ +.x-hidden, .x-hide-offsets { + position:absolute !important; + left:-10000px; + top:-10000px; + visibility:hidden; +} + +.x-hide-display { + display:none !important; +} + +.x-hide-visibility { + visibility:hidden !important; +} + +.x-masked { + overflow: hidden !important; +} +.x-masked-relative { + position: relative !important; +} + +.x-masked select, .x-masked object, .x-masked embed { + visibility: hidden; +} + +.x-layer { + visibility: hidden; +} + +.x-unselectable, .x-unselectable * { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select:ignore; +} + +.x-repaint { + zoom: 1; + background-color: transparent; + -moz-outline: none; + outline: none; +} + +.x-item-disabled { + cursor: default; + opacity: .6; + -moz-opacity: .6; + filter: alpha(opacity=60); +} + +.x-item-disabled * { + cursor: default !important; +} + +.x-form-radio-group .x-item-disabled { + filter: none; +} + +.x-splitbar-proxy { + position: absolute; + visibility: hidden; + z-index: 20001; + zoom: 1; + line-height: 1px; + font-size: 1px; + overflow: hidden; +} + +.x-splitbar-h, .x-splitbar-proxy-h { + cursor: e-resize; + cursor: col-resize; +} + +.x-splitbar-v, .x-splitbar-proxy-v { + cursor: s-resize; + cursor: row-resize; +} + +.x-color-palette { + width: 150px; + height: 92px; + cursor: pointer; +} + +.x-color-palette a { + border: 1px solid; + float: left; + padding: 2px; + text-decoration: none; + -moz-outline: 0 none; + outline: 0 none; + cursor: pointer; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border: 1px solid; +} + +.x-color-palette em { + display: block; + border: 1px solid; +} + +.x-color-palette em span { + cursor: pointer; + display: block; + height: 10px; + line-height: 10px; + width: 10px; +} + +.x-ie-shadow { + display: none; + position: absolute; + overflow: hidden; + left:0; + top:0; + zoom:1; +} + +.x-shadow { + display: none; + position: absolute; + overflow: hidden; + left:0; + top:0; +} + +.x-shadow * { + overflow: hidden; +} + +.x-shadow * { + padding: 0; + border: 0; + margin: 0; + clear: none; + zoom: 1; +} + +/* top bottom */ +.x-shadow .xstc, .x-shadow .xsbc { + height: 6px; + float: left; +} + +/* corners */ +.x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbr { + width: 6px; + height: 6px; + float: left; +} + +/* sides */ +.x-shadow .xsc { + width: 100%; +} + +.x-shadow .xsml, .x-shadow .xsmr { + width: 6px; + float: left; + height: 100%; +} + +.x-shadow .xsmc { + float: left; + height: 100%; + background: transparent; +} + +.x-shadow .xst, .x-shadow .xsb { + height: 6px; + overflow: hidden; + width: 100%; +} + +.x-shadow .xsml { + background: transparent repeat-y 0 0; +} + +.x-shadow .xsmr { + background: transparent repeat-y -6px 0; +} + +.x-shadow .xstl { + background: transparent no-repeat 0 0; +} + +.x-shadow .xstc { + background: transparent repeat-x 0 -30px; +} + +.x-shadow .xstr { + background: transparent repeat-x 0 -18px; +} + +.x-shadow .xsbl { + background: transparent no-repeat 0 -12px; +} + +.x-shadow .xsbc { + background: transparent repeat-x 0 -36px; +} + +.x-shadow .xsbr { + background: transparent repeat-x 0 -6px; +} + +.loading-indicator { + background: no-repeat left; + padding-left: 20px; + line-height: 16px; + margin: 3px; +} + +.x-text-resize { + position: absolute; + left: -1000px; + top: -1000px; + visibility: hidden; + zoom: 1; +} + +.x-drag-overlay { + width: 100%; + height: 100%; + display: none; + position: absolute; + left: 0; + top: 0; + background-image:url(images/default/s.gif); + z-index: 20000; +} + +.x-clear { + clear:both; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} + +.x-spotlight { + z-index: 8999; + position: absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity=50); + width:0; + height:0; + zoom: 1; +} + +#x-history-frame { + position:absolute; + top:-1px; + left:0; + width:1px; + height:1px; + visibility:hidden; +} + +#x-history-field { + position:absolute; + top:0; + left:-1px; + width:1px; + height:1px; + visibility:hidden; +} +.x-resizable-handle { + position:absolute; + z-index:100; + /* ie needs these */ + font-size:1px; + line-height:6px; + overflow:hidden; + filter:alpha(opacity=0); + opacity:0; + zoom:1; +} + +.x-resizable-handle-east{ + width:6px; + cursor:e-resize; + right:0; + top:0; + height:100%; +} + +.ext-ie .x-resizable-handle-east { + margin-right:-1px; /*IE rounding error*/ +} + +.x-resizable-handle-south{ + width:100%; + cursor:s-resize; + left:0; + bottom:0; + height:6px; +} + +.ext-ie .x-resizable-handle-south { + margin-bottom:-1px; /*IE rounding error*/ +} + +.x-resizable-handle-west{ + width:6px; + cursor:w-resize; + left:0; + top:0; + height:100%; +} + +.x-resizable-handle-north{ + width:100%; + cursor:n-resize; + left:0; + top:0; + height:6px; +} + +.x-resizable-handle-southeast{ + width:6px; + cursor:se-resize; + right:0; + bottom:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-northwest{ + width:6px; + cursor:nw-resize; + left:0; + top:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-northeast{ + width:6px; + cursor:ne-resize; + right:0; + top:0; + height:6px; + z-index:101; +} + +.x-resizable-handle-southwest{ + width:6px; + cursor:sw-resize; + left:0; + bottom:0; + height:6px; + z-index:101; +} + +.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{ + filter:alpha(opacity=100); + opacity:1; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-position: left; +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-position: top; +} + +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-position: top left; +} + +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-position:bottom right; +} + +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-position: bottom left; +} + +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-position: top right; +} + +.x-resizable-proxy{ + border: 1px dashed; + position:absolute; + overflow:hidden; + display:none; + left:0; + top:0; + z-index:50000; +} + +.x-resizable-overlay{ + width:100%; + height:100%; + display:none; + position:absolute; + left:0; + top:0; + z-index:200000; + -moz-opacity: 0; + opacity:0; + filter: alpha(opacity=0); +} +.x-tab-panel { + overflow:hidden; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border: 1px solid; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header { + border: 1px solid; + padding-bottom: 2px; +} + +.x-tab-panel-footer { + border: 1px solid; + padding-top: 2px; +} + +.x-tab-strip-wrap { + width:100%; + overflow:hidden; + position:relative; + zoom:1; +} + +ul.x-tab-strip { + display:block; + width:5000px; + zoom:1; +} + +ul.x-tab-strip-top{ + padding-top: 1px; + background: repeat-x bottom; + border-bottom: 1px solid; +} + +ul.x-tab-strip-bottom{ + padding-bottom: 1px; + background: repeat-x top; + border-top: 1px solid; + border-bottom: 0 none; +} + +.x-tab-panel-header-plain .x-tab-strip-top { + background:transparent !important; + padding-top:0 !important; +} + +.x-tab-panel-header-plain { + background:transparent !important; + border-width:0 !important; + padding-bottom:0 !important; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border:1px solid; + height:2px; + font-size:1px; + line-height:1px; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer { + border-top: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-bottom: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-bottom { + background:transparent !important; + padding-bottom:0 !important; +} + +.x-tab-panel-footer-plain { + background:transparent !important; + border-width:0 !important; + padding-top:0 !important; +} + +.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer, +.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer { + height:3px; +} + +ul.x-tab-strip li { + float:left; + margin-left:2px; +} + +ul.x-tab-strip li.x-tab-edge { + float:left; + margin:0 !important; + padding:0 !important; + border:0 none !important; + font-size:1px !important; + line-height:1px !important; + overflow:hidden; + zoom:1; + background:transparent !important; + width:1px; +} + +.x-tab-strip a, .x-tab-strip span, .x-tab-strip em { + display:block; +} + +.x-tab-strip a { + text-decoration:none !important; + -moz-outline: none; + outline: none; + cursor:pointer; +} + +.x-tab-strip-inner { + overflow:hidden; + text-overflow: ellipsis; +} + +.x-tab-strip span.x-tab-strip-text { + white-space: nowrap; + cursor:pointer; + padding:4px 0; +} + +.x-tab-strip-top .x-tab-with-icon .x-tab-right { + padding-left:6px; +} + +.x-tab-strip .x-tab-with-icon span.x-tab-strip-text { + padding-left:20px; + background-position: 0 3px; + background-repeat: no-repeat; +} + +.x-tab-strip-active, .x-tab-strip-active a.x-tab-right { + cursor:default; +} + +.x-tab-strip-active span.x-tab-strip-text { + cursor:default; +} + +.x-tab-strip-disabled .x-tabs-text { + cursor:default; +} + +.x-tab-panel-body { + overflow:hidden; +} + +.x-tab-panel-bwrap { + overflow:hidden; +} + +.ext-ie .x-tab-strip .x-tab-right { + position:relative; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + margin-bottom:-1px; +} + +/* + * Horrible hack for IE8 in quirks mode + */ +.ext-ie8 ul.x-tab-strip li { + position: relative; +} +.ext-ie8 .x-tab-strip .x-tab-right{ + margin-bottom: 0 !important; + top: 1px; +} +.ext-ie8 ul.x-tab-strip-top { + padding-top: 0; +} +.ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + top:4px; +} +.ext-ie8 .x-tab-strip-bottom .x-tab-right{ + top:0; +} + + +.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text { + padding-bottom:5px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + margin-top:-1px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text { + padding-top:5px; +} + +.x-tab-strip-top .x-tab-right { + background: transparent no-repeat 0 -51px; + padding-left:10px; +} + +.x-tab-strip-top .x-tab-left { + background: transparent no-repeat right -351px; + padding-right:10px; +} + +.x-tab-strip-top .x-tab-strip-inner { + background: transparent repeat-x 0 -201px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-right { + background-position:0 -101px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-left { + background-position:right -401px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner { + background-position:0 -251px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + background-position: 0 0; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-left { + background-position: right -301px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner { + background-position: 0 -151px; +} + +.x-tab-strip-bottom .x-tab-right { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-left { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-left { + margin-right: 3px; + padding:0 10px; +} + +.x-tab-strip-bottom .x-tab-right { + padding:0; +} + +.x-tab-strip .x-tab-strip-close { + display:none; +} + +.x-tab-strip-closable { + position:relative; +} + +.x-tab-strip-closable .x-tab-left { + padding-right:19px; +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + opacity:.6; + -moz-opacity:.6; + background-repeat:no-repeat; + display:block; + width:11px; + height:11px; + position:absolute; + top:3px; + right:3px; + cursor:pointer; + z-index:2; +} + +.x-tab-strip .x-tab-strip-active a.x-tab-strip-close { + opacity:.8; + -moz-opacity:.8; +} +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + opacity:1; + -moz-opacity:1; +} + +.x-tab-panel-body { + border: 1px solid; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background: transparent no-repeat -18px 0; + border-bottom: 1px solid; + width:18px; + position:absolute; + left:0; + top:0; + z-index:10; + cursor:pointer; +} +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background: transparent no-repeat 0 0; + border-bottom: 1px solid; + width:18px; + position:absolute; + right:0; + top:0; + z-index:10; + cursor:pointer; +} + +.x-tab-scroller-right-over { + background-position: -18px 0; +} + +.x-tab-scroller-right-disabled { + background-position: 0 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scrolling-bottom .x-tab-scroller-left, .x-tab-scrolling-bottom .x-tab-scroller-right{ + margin-top: 1px; +} + +.x-tab-scrolling .x-tab-strip-wrap { + margin-left:18px; + margin-right:18px; +} + +.x-tab-scrolling { + position:relative; +} + +.x-tab-panel-bbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +} + +.x-tab-panel-tbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +}/* all fields */ +.x-form-field{ + margin: 0 0 0 0; +} + +.ext-webkit *:focus{ + outline: none !important; +} + +/* ---- text fields ---- */ +.x-form-text, textarea.x-form-field{ + padding:1px 3px; + background:repeat-x 0 0; + border:1px solid; +} + +textarea.x-form-field { + padding:2px 3px; +} + +.x-form-text, .ext-ie .x-form-file { + height:22px; + line-height:18px; + vertical-align:middle; +} + +.ext-ie6 .x-form-text, .ext-ie7 .x-form-text { + margin:-1px 0; /* ie bogus margin bug */ + height:22px; /* ie quirks */ + line-height:18px; +} + +.ext-ie6 textarea.x-form-field, .ext-ie7 textarea.x-form-field { + margin:-1px 0; /* ie bogus margin bug */ +} + +.ext-strict .x-form-text { + height:18px; +} + +.ext-safari.ext-mac textarea.x-form-field { + margin-bottom:-2px; /* another bogus margin bug, safari/mac only */ +} + +.ext-strict .ext-ie8 .x-form-text, .ext-strict .ext-ie8 textarea.x-form-field { + margin-bottom: 1px; +} + +.ext-gecko .x-form-text , .ext-ie8 .x-form-text { + padding-top:2px; /* FF won't center the text vertically */ + padding-bottom:0; +} + +.ext-ie6 .x-form-composite .x-form-text.x-box-item, .ext-ie7 .x-form-composite .x-form-text.x-box-item { + margin: 0 !important; /* clear ie bogus margin bug fix */ +} + +textarea { + resize: none; /* Disable browser resizable textarea */ +} + +/* select boxes */ +.x-form-select-one { + height:20px; + line-height:18px; + vertical-align:middle; + border: 1px solid; +} + +/* multi select boxes */ + +/* --- TODO --- */ + +/* 2.0.2 style */ +.x-form-check-wrap { + line-height:18px; + height: auto; +} + +.ext-ie .x-form-check-wrap input { + width:15px; + height:15px; +} + +.x-form-check-wrap input{ + vertical-align: bottom; +} + +.x-editor .x-form-check-wrap { + padding:3px; +} + +.x-editor .x-form-checkbox { + height:13px; +} + +.x-form-check-group-label { + border-bottom: 1px solid; + margin-bottom: 5px; + padding-left: 3px !important; + float: none !important; +} + +/* wrapped fields and triggers */ +.x-form-field-wrap .x-form-trigger{ + width:17px; + height:21px; + border:0; + background:transparent no-repeat 0 0; + cursor:pointer; + border-bottom: 1px solid; + position:absolute; + top:0; +} + +.x-form-field-wrap .x-form-date-trigger, .x-form-field-wrap .x-form-clear-trigger, .x-form-field-wrap .x-form-search-trigger{ + cursor:pointer; +} + +.x-form-field-wrap .x-form-twin-triggers .x-form-trigger{ + position:static; + top:auto; + vertical-align:top; +} + +.x-form-field-wrap { + position:relative; + left:0;top:0; + text-align: left; + zoom:1; + white-space: nowrap; +} + +.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-trigger { + right: 0; /* IE8 Strict mode trigger bug */ +} + +.x-form-field-wrap .x-form-trigger-over{ + background-position:-17px 0; +} + +.x-form-field-wrap .x-form-trigger-click{ + background-position:-34px 0; +} + +.x-trigger-wrap-focus .x-form-trigger{ + background-position:-51px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-over{ + background-position:-68px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-click{ + background-position:-85px 0; +} + +.x-trigger-wrap-focus .x-form-trigger{ + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-over{ + background-position:0 0 !important; + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-click{ + background-position:0 0 !important; + border-bottom: 1px solid; +} + +.x-trigger-noedit{ + cursor:pointer; +} + +/* field focus style */ +.x-form-focus, textarea.x-form-focus{ + border: 1px solid; +} + +/* invalid fields */ +.x-form-invalid, textarea.x-form-invalid{ + background:repeat-x bottom; + border: 1px solid; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid{ + background:repeat-x bottom; +} + +/* editors */ +.x-editor { + visibility:hidden; + padding:0; + margin:0; +} + +.x-form-grow-sizer { + left: -10000px; + padding: 8px 3px; + position: absolute; + visibility:hidden; + top: -10000px; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + zoom:1; +} + +.x-form-grow-sizer p { + margin:0 !important; + border:0 none !important; + padding:0 !important; +} + +/* Form Items CSS */ + +.x-form-item { + display:block; + margin-bottom:4px; + zoom:1; +} + +.x-form-item label.x-form-item-label { + display:block; + float:left; + width:100px; + padding:3px; + padding-left:0; + clear:left; + z-index:2; + position:relative; +} + +.x-form-element { + padding-left:105px; + position:relative; +} + +.x-form-invalid-msg { + padding:2px; + padding-left:18px; + background: transparent no-repeat 0 2px; + line-height:16px; + width:200px; +} + +.x-form-label-left label.x-form-item-label { + text-align:left; +} + +.x-form-label-right label.x-form-item-label { + text-align:right; +} + +.x-form-label-top .x-form-item label.x-form-item-label { + width:auto; + float:none; + clear:none; + display:inline; + margin-bottom:4px; + position:static; +} + +.x-form-label-top .x-form-element { + padding-left:0; + padding-top:4px; +} + +.x-form-label-top .x-form-item { + padding-bottom:4px; +} + +/* Editor small font for grid, toolbar and tree */ +.x-small-editor .x-form-text { + height:20px; + line-height:16px; + vertical-align:middle; +} + +.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .x-small-editor .x-form-text { + margin-top:-1px !important; /* ie bogus margin bug */ + margin-bottom:-1px !important; + height:20px !important; /* ie quirks */ + line-height:16px !important; +} + +.ext-strict .x-small-editor .x-form-text { + height:16px !important; +} + +.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .x-small-editor .x-form-text { + height:20px; + line-height:16px; +} + +.ext-border-box .x-small-editor .x-form-text { + height:20px; +} + +.x-small-editor .x-form-select-one { + height:20px; + line-height:16px; + vertical-align:middle; +} + +.x-small-editor .x-form-num-field { + text-align:right; +} + +.x-small-editor .x-form-field-wrap .x-form-trigger{ + height:19px; +} + +.ext-webkit .x-small-editor .x-form-text{padding-top:3px;font-size:100%;} + +.x-form-clear { + clear:both; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} +.x-form-clear-left { + clear:left; + height:0; + overflow:hidden; + line-height:0; + font-size:0; +} + +.ext-ie6 .x-form-check-wrap input, .ext-border-box .x-form-check-wrap input{ + margin-top: 3px; +} + +.x-form-cb-label { + position: relative; + margin-left:4px; + top: 2px; +} + +.ext-ie .x-form-cb-label{ + top: 1px; +} + +.ext-ie6 .x-form-cb-label, .ext-border-box .x-form-cb-label{ + top: 3px; +} + +.x-form-display-field{ + padding-top: 2px; +} + +.ext-gecko .x-form-display-field, .ext-strict .ext-ie7 .x-form-display-field{ + padding-top: 1px; +} + +.ext-ie .x-form-display-field{ + padding-top: 3px; +} + +.ext-strict .ext-ie8 .x-form-display-field{ + padding-top: 0; +} + +.x-form-column { + float:left; + padding:0; + margin:0; + width:48%; + overflow:hidden; + zoom:1; +} + +/* buttons */ +.x-form .x-form-btns-ct .x-btn{ + float:right; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns td { + border:0; + padding:0; +} + +.x-form .x-form-btns-ct .x-form-btns-right table{ + float:right; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns-left table{ + float:left; + clear:none; +} + +.x-form .x-form-btns-ct .x-form-btns-center{ + text-align:center; /*ie*/ +} + +.x-form .x-form-btns-ct .x-form-btns-center table{ + margin:0 auto; /*everyone else*/ +} + +.x-form .x-form-btns-ct table td.x-form-btn-td{ + padding:3px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-left{ + background-position:0 -147px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-right{ + background-position:0 -168px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-center{ + background-position:0 -189px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-center{ + background-position:0 -126px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-right{ + background-position:0 -84px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-left{ + background-position:0 -63px; +} + +.x-form-invalid-icon { + width:16px; + height:18px; + visibility:hidden; + position:absolute; + left:0; + top:0; + display:block; + background:transparent no-repeat 0 2px; +} + +/* fieldsets */ +.x-fieldset { + border:1px solid; + padding:10px; + margin-bottom:10px; + display:block; /* preserve margins in IE */ +} + +/* make top of checkbox/tools visible in webkit */ +.ext-webkit .x-fieldset-header { + padding-top: 1px; +} + +.ext-ie .x-fieldset legend { + margin-bottom:10px; +} + +.ext-ie .x-fieldset { + padding-top: 0; + padding-bottom:10px; +} + +.x-fieldset legend .x-tool-toggle { + margin-right:3px; + margin-left:0; + float:left !important; +} + +.x-fieldset legend input { + margin-right:3px; + float:left !important; + height:13px; + width:13px; +} + +fieldset.x-panel-collapsed { + padding-bottom:0 !important; + border-width: 1px 1px 0 1px !important; + border-left-color: transparent; + border-right-color: transparent; +} + +.ext-ie6 fieldset.x-panel-collapsed{ + padding-bottom:0 !important; + border-width: 1px 0 0 0 !important; + margin-left: 1px; + margin-right: 1px; +} + +fieldset.x-panel-collapsed .x-fieldset-bwrap { + visibility:hidden; + position:absolute; + left:-1000px; + top:-1000px; +} + +.ext-ie .x-fieldset-bwrap { + zoom:1; +} + +.x-fieldset-noborder { + border:0px none transparent; +} + +.x-fieldset-noborder legend { + margin-left:-3px; +} + +/* IE legend positioning bug */ +.ext-ie .x-fieldset-noborder legend { + position: relative; + margin-bottom:23px; +} +.ext-ie .x-fieldset-noborder legend span { + position: absolute; + left:16px; +} + +.ext-gecko .x-window-body .x-form-item { + -moz-outline: none; + outline: none; + overflow: auto; +} + +.ext-gecko .x-form-item { + -moz-outline: none; + outline: none; +} + +.x-hide-label label.x-form-item-label { + display:none; +} + +.x-hide-label .x-form-element { + padding-left: 0 !important; +} + +.x-form-label-top .x-hide-label label.x-form-item-label{ + display: none; +} + +.x-fieldset { + overflow:hidden; +} + +.x-fieldset-bwrap { + overflow:hidden; + zoom:1; +} + +.x-fieldset-body { + overflow:hidden; +} +.x-btn{ + cursor:pointer; + white-space: nowrap; +} + +.x-btn button{ + border:0 none; + background:transparent; + padding-left:3px; + padding-right:3px; + cursor:pointer; + margin:0; + overflow:visible; + width:auto; + -moz-outline:0 none; + outline:0 none; +} + +* html .ext-ie .x-btn button { + width:1px; +} + +.ext-gecko .x-btn button, .ext-webkit .x-btn button { + padding-left:0; + padding-right:0; +} + +.ext-gecko .x-btn button::-moz-focus-inner { + padding:0; +} + +.ext-ie .x-btn button { + padding-top:2px; +} + +.x-btn td { + padding:0 !important; +} + +.x-btn-text { + cursor:pointer; + white-space: nowrap; + padding:0; +} + +/* icon placement and sizing styles */ + +/* Only text */ +.x-btn-noicon .x-btn-small .x-btn-text{ + height: 16px; +} + +.x-btn-noicon .x-btn-medium .x-btn-text{ + height: 24px; +} + +.x-btn-noicon .x-btn-large .x-btn-text{ + height: 32px; +} + +/* Only icons */ +.x-btn-icon .x-btn-text{ + background-position: center; + background-repeat: no-repeat; +} + +.x-btn-icon .x-btn-small .x-btn-text{ + height: 16px; + width: 16px; +} + +.x-btn-icon .x-btn-medium .x-btn-text{ + height: 24px; + width: 24px; +} + +.x-btn-icon .x-btn-large .x-btn-text{ + height: 32px; + width: 32px; +} + +/* Icons and text */ +/* left */ +.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:18px; + height:16px; +} + +.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:26px; + height:24px; +} + +.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:34px; + height:32px; +} + +/* top */ +.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:18px; +} + +.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:26px; +} + +.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:34px; +} + +/* right */ +.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:18px; + height:16px; +} + +.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:26px; + height:24px; +} + +.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:34px; + height:32px; +} + +/* bottom */ +.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:18px; +} + +.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:26px; +} + +.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:34px; +} + +/* background positioning */ +.x-btn-tr i, .x-btn-tl i, .x-btn-mr i, .x-btn-ml i, .x-btn-br i, .x-btn-bl i{ + font-size:1px; + line-height:1px; + width:3px; + display:block; + overflow:hidden; +} + +.x-btn-tr i, .x-btn-tl i, .x-btn-br i, .x-btn-bl i{ + height:3px; +} + +.x-btn-tl{ + width:3px; + height:3px; + background:no-repeat 0 0; +} +.x-btn-tr{ + width:3px; + height:3px; + background:no-repeat -3px 0; +} +.x-btn-tc{ + height:3px; + background:repeat-x 0 -6px; +} + +.x-btn-ml{ + width:3px; + background:no-repeat 0 -24px; +} +.x-btn-mr{ + width:3px; + background:no-repeat -3px -24px; +} + +.x-btn-mc{ + background:repeat-x 0 -1096px; + vertical-align: middle; + text-align:center; + padding:0 5px; + cursor:pointer; + white-space:nowrap; +} + +/* Fixes an issue with the button height */ +.ext-strict .ext-ie6 .x-btn-mc, .ext-strict .ext-ie7 .x-btn-mc { + height: 100%; +} + +.x-btn-bl{ + width:3px; + height:3px; + background:no-repeat 0 -3px; +} + +.x-btn-br{ + width:3px; + height:3px; + background:no-repeat -3px -3px; +} + +.x-btn-bc{ + height:3px; + background:repeat-x 0 -15px; +} + +.x-btn-over .x-btn-tl{ + background-position: -6px 0; +} + +.x-btn-over .x-btn-tr{ + background-position: -9px 0; +} + +.x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} + +.x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} + +.x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} + +.x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} + +.x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} + +.x-btn-over .x-btn-br{ + background-position: -9px -3px; +} + +.x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} + +.x-btn-click .x-btn-tl, .x-btn-menu-active .x-btn-tl, .x-btn-pressed .x-btn-tl{ + background-position: -12px 0; +} + +.x-btn-click .x-btn-tr, .x-btn-menu-active .x-btn-tr, .x-btn-pressed .x-btn-tr{ + background-position: -15px 0; +} + +.x-btn-click .x-btn-tc, .x-btn-menu-active .x-btn-tc, .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px; +} + +.x-btn-click .x-btn-ml, .x-btn-menu-active .x-btn-ml, .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px; +} + +.x-btn-click .x-btn-mr, .x-btn-menu-active .x-btn-mr, .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px; +} + +.x-btn-click .x-btn-mc, .x-btn-menu-active .x-btn-mc, .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px; +} + +.x-btn-click .x-btn-bl, .x-btn-menu-active .x-btn-bl, .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px; +} + +.x-btn-click .x-btn-br, .x-btn-menu-active .x-btn-br, .x-btn-pressed .x-btn-br{ + background-position: -15px -3px; +} + +.x-btn-click .x-btn-bc, .x-btn-menu-active .x-btn-bc, .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px; +} + +.x-btn-disabled *{ + cursor:default !important; +} + + +/* With a menu arrow */ +/* right */ +.x-btn-mc em.x-btn-arrow { + display:block; + background:transparent no-repeat right center; + padding-right:10px; +} + +.x-btn-mc em.x-btn-split { + display:block; + background:transparent no-repeat right center; + padding-right:14px; +} + +/* bottom */ +.x-btn-mc em.x-btn-arrow-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} + +.x-btn-mc em.x-btn-split-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} + +/* height adjustment class */ +.x-btn-as-arrow .x-btn-mc em { + display:block; + background:transparent; + padding-bottom:14px; +} + +/* groups */ +.x-btn-group { + padding:1px; +} + +.x-btn-group-header { + padding:2px; + text-align:center; +} + +.x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} + +.x-btn-group-tl { + background: transparent no-repeat 0 0; + padding-left:3px; + zoom:1; +} + +.x-btn-group-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:3px; +} + +.x-btn-group-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-btn-group-bc .x-panel-footer { + zoom:1; +} + +.x-btn-group-bl { + background: transparent no-repeat 0 bottom; + padding-left:3px; + zoom:1; +} + +.x-btn-group-br { + background: transparent no-repeat right bottom; + padding-right:3px; + zoom:1; +} + +.x-btn-group-mc { + border:0 none; + padding:1px 0 0 0; + margin:0; +} + +.x-btn-group-mc .x-btn-group-body { + background:transparent; + border: 0 none; +} + +.x-btn-group-ml { + background: transparent repeat-y 0 0; + padding-left:3px; + zoom:1; +} + +.x-btn-group-mr { + background: transparent repeat-y right 0; + padding-right:3px; + zoom:1; +} + +.x-btn-group-bc .x-btn-group-footer { + padding-bottom:6px; +} + +.x-panel-nofooter .x-btn-group-bc { + height:3px; + font-size:0; + line-height:0; +} + +.x-btn-group-bwrap { + overflow:hidden; + zoom:1; +} + +.x-btn-group-body { + overflow:hidden; + zoom:1; +} + +.x-btn-group-notitle .x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + height:2px; +}.x-toolbar{ + border-style:solid; + border-width:0 0 1px 0; + display: block; + padding:2px; + background:repeat-x top left; + position:relative; + left:0; + top:0; + zoom:1; + overflow:hidden; +} + +.x-toolbar-left { + width: 100%; +} + +.x-toolbar .x-item-disabled .x-btn-icon { + opacity: .35; + -moz-opacity: .35; + filter: alpha(opacity=35); +} + +.x-toolbar td { + vertical-align:middle; +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + white-space: nowrap; +} + +.x-toolbar .x-item-disabled { + cursor:default; + opacity:.6; + -moz-opacity:.6; + filter:alpha(opacity=60); +} + +.x-toolbar .x-item-disabled * { + cursor:default; +} + +.x-toolbar .x-toolbar-cell { + vertical-align:middle; +} + +.x-toolbar .x-btn-tl, .x-toolbar .x-btn-tr, .x-toolbar .x-btn-tc, .x-toolbar .x-btn-ml, .x-toolbar .x-btn-mr, +.x-toolbar .x-btn-mc, .x-toolbar .x-btn-bl, .x-toolbar .x-btn-br, .x-toolbar .x-btn-bc +{ + background-position: 500px 500px; +} + +/* These rules are duplicated from button.css to give priority of x-toolbar rules above */ +.x-toolbar .x-btn-over .x-btn-tl{ + background-position: -6px 0; +} + +.x-toolbar .x-btn-over .x-btn-tr{ + background-position: -9px 0; +} + +.x-toolbar .x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} + +.x-toolbar .x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} + +.x-toolbar .x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} + +.x-toolbar .x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} + +.x-toolbar .x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} + +.x-toolbar .x-btn-over .x-btn-br{ + background-position: -9px -3px; +} + +.x-toolbar .x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} + +.x-toolbar .x-btn-click .x-btn-tl, .x-toolbar .x-btn-menu-active .x-btn-tl, .x-toolbar .x-btn-pressed .x-btn-tl{ + background-position: -12px 0; +} + +.x-toolbar .x-btn-click .x-btn-tr, .x-toolbar .x-btn-menu-active .x-btn-tr, .x-toolbar .x-btn-pressed .x-btn-tr{ + background-position: -15px 0; +} + +.x-toolbar .x-btn-click .x-btn-tc, .x-toolbar .x-btn-menu-active .x-btn-tc, .x-toolbar .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px; +} + +.x-toolbar .x-btn-click .x-btn-ml, .x-toolbar .x-btn-menu-active .x-btn-ml, .x-toolbar .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px; +} + +.x-toolbar .x-btn-click .x-btn-mr, .x-toolbar .x-btn-menu-active .x-btn-mr, .x-toolbar .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px; +} + +.x-toolbar .x-btn-click .x-btn-mc, .x-toolbar .x-btn-menu-active .x-btn-mc, .x-toolbar .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px; +} + +.x-toolbar .x-btn-click .x-btn-bl, .x-toolbar .x-btn-menu-active .x-btn-bl, .x-toolbar .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px; +} + +.x-toolbar .x-btn-click .x-btn-br, .x-toolbar .x-btn-menu-active .x-btn-br, .x-toolbar .x-btn-pressed .x-btn-br{ + background-position: -15px -3px; +} + +.x-toolbar .x-btn-click .x-btn-bc, .x-toolbar .x-btn-menu-active .x-btn-bc, .x-toolbar .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px; +} + +.x-toolbar div.xtb-text{ + padding:2px 2px 0; + line-height:16px; + display:block; +} + +.x-toolbar .xtb-sep { + background-position: center; + background-repeat: no-repeat; + display: block; + font-size: 1px; + height: 16px; + width:4px; + overflow: hidden; + cursor:default; + margin: 0 2px 0; + border:0; +} + +.x-toolbar .xtb-spacer { + width:2px; +} + +/* Paging Toolbar */ +.x-tbar-page-number{ + width:30px; + height:14px; +} + +.ext-ie .x-tbar-page-number{ + margin-top: 2px; +} + +.x-paging-info { + position:absolute; + top:5px; + right: 8px; +} + +/* floating */ +.x-toolbar-ct { + width:100%; +} + +.x-toolbar-right td { + text-align: center; +} + +.x-panel-tbar, .x-panel-bbar, .x-window-tbar, .x-window-bbar, .x-tab-panel-tbar, .x-tab-panel-bbar, .x-plain-tbar, .x-plain-bbar { + overflow:hidden; + zoom:1; +} + +.x-toolbar-more .x-btn-small .x-btn-text{ + height: 16px; + width: 12px; +} + +.x-toolbar-more em.x-btn-arrow { + display:inline; + background:transparent; + padding-right:0; +} + +.x-toolbar-more .x-btn-mc em.x-btn-arrow { + background-image: none; +} + +div.x-toolbar-no-items { + color:gray !important; + padding:5px 10px !important; +} + +/* fix ie toolbar form items */ +.ext-border-box .x-toolbar-cell .x-form-text { + margin-bottom:-1px !important; +} + +.ext-border-box .x-toolbar-cell .x-form-field-wrap .x-form-text { + margin:0 !important; +} + +.ext-ie .x-toolbar-cell .x-form-field-wrap { + height:21px; +} + +.ext-ie .x-toolbar-cell .x-form-text { + position:relative; + top:-1px; +} + +.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-text, .ext-strict .ext-ie .x-toolbar-cell .x-form-text { + top: 0px; +} + +.x-toolbar-right td .x-form-field-trigger-wrap{ + text-align: left; +} + +.x-toolbar-cell .x-form-checkbox, .x-toolbar-cell .x-form-radio{ + margin-top: 5px; +} + +.x-toolbar-cell .x-form-cb-label{ + vertical-align: bottom; + top: 1px; +} + +.ext-ie .x-toolbar-cell .x-form-checkbox, .ext-ie .x-toolbar-cell .x-form-radio{ + margin-top: 4px; +} + +.ext-ie .x-toolbar-cell .x-form-cb-label{ + top: 0; +} +/* Grid3 styles */ +.x-grid3 { + position:relative; + overflow:hidden; +} + +.x-grid-panel .x-panel-body { + overflow:hidden !important; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border:1px solid; +} + +.x-grid3 table { + table-layout:fixed; +} + +.x-grid3-viewport{ + overflow:hidden; +} + +.x-grid3-hd-row td, .x-grid3-row td, .x-grid3-summary-row td{ + -moz-outline: none; + outline: none; + -moz-user-focus: normal; +} + +.x-grid3-row td, .x-grid3-summary-row td { + line-height:13px; + vertical-align: top; + padding-left:1px; + padding-right:1px; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-cell{ + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-hd-row td { + line-height:15px; + vertical-align:middle; + border-left:1px solid; + border-right:1px solid; +} + +.x-grid3-hd-row .x-grid3-marker-hd { + padding:3px; +} + +.x-grid3-row .x-grid3-marker { + padding:3px; +} + +.x-grid3-cell-inner, .x-grid3-hd-inner{ + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + padding:3px 3px 3px 5px; + white-space: nowrap; +} + +.x-grid3-hd-inner { + position:relative; + cursor:inherit; + padding:4px 3px 4px 5px; +} + +.x-grid3-row-body { + white-space:normal; +} + +.x-grid3-body-cell { + -moz-outline:0 none; + outline:0 none; +} + +/* IE Quirks to clip */ +.ext-ie .x-grid3-cell-inner, .ext-ie .x-grid3-hd-inner{ + width:100%; +} + +/* reverse above in strict mode */ +.ext-strict .x-grid3-cell-inner, .ext-strict .x-grid3-hd-inner{ + width:auto; +} + +.x-grid-row-loading { + background: no-repeat center center; +} + +.x-grid-page { + overflow:hidden; +} + +.x-grid3-row { + cursor: default; + border: 1px solid; + width:100%; +} + +.x-grid3-row-over { + border:1px solid; + background: repeat-x left top; +} + +.x-grid3-resize-proxy { + width:1px; + left:0; + cursor: e-resize; + cursor: col-resize; + position:absolute; + top:0; + height:100px; + overflow:hidden; + visibility:hidden; + border:0 none; + z-index:7; +} + +.x-grid3-resize-marker { + width:1px; + left:0; + position:absolute; + top:0; + height:100px; + overflow:hidden; + visibility:hidden; + border:0 none; + z-index:7; +} + +.x-grid3-focus { + position:absolute; + left:0; + top:0; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: text; + -khtml-user-select: text; + -webkit-user-select:ignore; +} + +/* header styles */ +.x-grid3-header{ + background: repeat-x 0 bottom; + cursor:default; + zoom:1; + padding:1px 0 0 0; +} + +.x-grid3-header-pop { + border-left:1px solid; + float:right; + clear:none; +} + +.x-grid3-header-pop-inner { + border-left:1px solid; + width:14px; + height:19px; + background: transparent no-repeat center center; +} + +.ext-ie .x-grid3-header-pop-inner { + width:15px; +} + +.ext-strict .x-grid3-header-pop-inner { + width:14px; +} + +.x-grid3-header-inner { + overflow:hidden; + zoom:1; + float:left; +} + +.x-grid3-header-offset { + padding-left:1px; + text-align: left; +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left:1px solid; + border-right:1px solid; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background: repeat-x left bottom; + +} + +.x-grid3-sort-icon{ + background-repeat: no-repeat; + display: none; + height: 4px; + width: 13px; + margin-left:3px; + vertical-align: middle; +} + +.sort-asc .x-grid3-sort-icon, .sort-desc .x-grid3-sort-icon { + display: inline; +} + +/* Header position fixes for IE strict mode */ +.ext-strict .ext-ie .x-grid3-header-inner, .ext-strict .ext-ie6 .x-grid3-hd { + position:relative; +} + +.ext-strict .ext-ie6 .x-grid3-hd-inner{ + position:static; +} + +/* Body Styles */ +.x-grid3-body { + zoom:1; +} + +.x-grid3-scroller { + overflow:auto; + zoom:1; + position:relative; +} + +.x-grid3-cell-text, .x-grid3-hd-text { + display: block; + padding: 3px 5px 3px 5px; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select:ignore; +} + +.x-grid3-split { + background-position: center; + background-repeat: no-repeat; + cursor: e-resize; + cursor: col-resize; + display: block; + font-size: 1px; + height: 16px; + overflow: hidden; + position: absolute; + top: 2px; + width: 6px; + z-index: 3; +} + +/* Column Reorder DD */ +.x-dd-drag-proxy .x-grid3-hd-inner{ + background: repeat-x left bottom; + width:120px; + padding:3px; + border:1px solid; + overflow:hidden; +} + +.col-move-top, .col-move-bottom{ + width:9px; + height:9px; + position:absolute; + top:0; + line-height:1px; + font-size:1px; + overflow:hidden; + visibility:hidden; + z-index:20000; + background:transparent no-repeat left top; +} + +/* Selection Styles */ +.x-grid3-row-selected { + border:1px dotted; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background: repeat-x 0 bottom !important; + vertical-align:middle !important; + padding:0; + border-top:1px solid; + border-bottom:none !important; + border-right:1px solid !important; + text-align:center; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + padding:0 4px; + text-align:center; +} + +/* dirty cells */ +.x-grid3-dirty-cell { + background: transparent no-repeat 0 0; +} + +/* Grid Toolbars */ +.x-grid3-topbar, .x-grid3-bottombar{ + overflow:hidden; + display:none; + zoom:1; + position:relative; +} + +.x-grid3-topbar .x-toolbar{ + border-right:0 none; +} + +.x-grid3-bottombar .x-toolbar{ + border-right:0 none; + border-bottom:0 none; + border-top:1px solid; +} + +/* Props Grid Styles */ +.x-props-grid .x-grid3-cell{ + padding:1px; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background:transparent repeat-y -16px !important; + padding-left:12px; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + padding:1px; + padding-right:0; + border:0 none; + border-right:1px solid; +} + +/* dd */ +.x-grid3-col-dd { + border:0 none; + padding:0; + background:transparent; +} + +.x-dd-drag-ghost .x-grid3-dd-wrap { + padding:1px 3px 3px 1px; +} + +.x-grid3-hd { + -moz-user-select:none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-grid3-hd-btn { + display:none; + position:absolute; + width:14px; + background:no-repeat left center; + right:0; + top:0; + z-index:2; + cursor:pointer; +} + +.x-grid3-hd-over .x-grid3-hd-btn, .x-grid3-hd-menu-open .x-grid3-hd-btn { + display:block; +} + +a.x-grid3-hd-btn:hover { + background-position:-14px center; +} + +/* Expanders */ +.x-grid3-body .x-grid3-td-expander { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner { + padding:0 !important; + height:100%; +} + +.x-grid3-row-expander { + width:100%; + height:18px; + background-position:4px 2px; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-row-collapsed .x-grid3-row-expander { + background-position:4px 2px; +} + +.x-grid3-row-expanded .x-grid3-row-expander { + background-position:-21px 2px; +} + +.x-grid3-row-collapsed .x-grid3-row-body { + display:none !important; +} + +.x-grid3-row-expanded .x-grid3-row-body { + display:block !important; +} + +/* Checkers */ +.x-grid3-body .x-grid3-td-checker { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner, .x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner { + padding:0 !important; + height:100%; +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + width:100%; + height:18px; + background-position:2px 2px; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-row .x-grid3-row-checker { + background-position:2px 2px; +} + +.x-grid3-row-selected .x-grid3-row-checker, .x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker { + background-position:-23px 2px; +} + +.x-grid3-hd-checker { + background-position:2px 1px; +} + +.ext-border-box .x-grid3-hd-checker { + background-position:2px 3px; +} + +.x-grid3-hd-checker-on .x-grid3-hd-checker { + background-position:-23px 1px; +} + +.ext-border-box .x-grid3-hd-checker-on .x-grid3-hd-checker { + background-position:-23px 3px; +} + +/* Numberer */ +.x-grid3-body .x-grid3-td-numberer { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + padding:3px 5px 0 0 !important; + text-align:right; +} + +/* Row Icon */ + +.x-grid3-body .x-grid3-td-row-icon { + background:transparent repeat-y right; + vertical-align:top; + text-align:center; +} + +.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner { + padding:0 !important; + background-position:center center; + background-repeat:no-repeat; + width:16px; + height:16px; + margin-left:2px; + margin-top:3px; +} + +/* All specials */ +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background:transparent repeat-y right; +} + +.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner { + padding: 1px 0 0 0 !important; +} + +.x-grid3-check-col { + width:100%; + height:16px; + background-position:center center; + background-repeat:no-repeat; + background-color:transparent; +} + +.x-grid3-check-col-on { + width:100%; + height:16px; + background-position:center center; + background-repeat:no-repeat; + background-color:transparent; +} + +/* Grouping classes */ +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom: 2px solid; + cursor:pointer; + padding-top:6px; +} + +.x-grid-group-hd div.x-grid-group-title { + background:transparent no-repeat 3px 3px; + padding:4px 4px 4px 17px; +} + +.x-grid-group-collapsed .x-grid-group-body { + display:none; +} + +.ext-ie6 .x-grid3 .x-editor .x-form-text, .ext-ie7 .x-grid3 .x-editor .x-form-text { + position:relative; + top:-1px; +} + +.ext-ie .x-props-grid .x-editor .x-form-text { + position:static; + top:0; +} + +.x-grid-empty { + padding:10px; +} + +/* fix floating toolbar issue */ +.ext-ie7 .x-grid-panel .x-panel-bbar { + position:relative; +} + + +/* Reset position to static when Grid Panel has been framed */ +/* to resolve 'snapping' from top to bottom behavior. */ +/* @forumThread 86656 */ +.ext-ie7 .x-grid-panel .x-panel-mc .x-panel-bbar { + position: static; +} + +.ext-ie6 .x-grid3-header { + position: relative; +} + +/* Fix WebKit bug in Grids */ +.ext-webkit .x-grid-panel .x-panel-bwrap{ + -webkit-user-select:none; +} +.ext-webkit .x-tbar-page-number{ + -webkit-user-select:ignore; +} +/* end*/ + +/* column lines */ +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + padding-right:0; + border-right:1px solid; +} +.x-dd-drag-proxy{ + position:absolute; + left:0; + top:0; + visibility:hidden; + z-index:15000; +} + +.x-dd-drag-ghost{ + -moz-opacity: 0.85; + opacity:.85; + filter: alpha(opacity=85); + border: 1px solid; + padding:3px; + padding-left:20px; + white-space:nowrap; +} + +.x-dd-drag-repair .x-dd-drag-ghost{ + -moz-opacity: 0.4; + opacity:.4; + filter: alpha(opacity=40); + border:0 none; + padding:0; + background-color:transparent; +} + +.x-dd-drag-repair .x-dd-drop-icon{ + visibility:hidden; +} + +.x-dd-drop-icon{ + position:absolute; + top:3px; + left:3px; + display:block; + width:16px; + height:16px; + background-color:transparent; + background-position: center; + background-repeat: no-repeat; + z-index:1; +} + +.x-view-selector { + position:absolute; + left:0; + top:0; + width:0; + border:1px dotted; + opacity: .5; + -moz-opacity: .5; + filter:alpha(opacity=50); + zoom:1; +}.ext-strict .ext-ie .x-tree .x-panel-bwrap{ + position:relative; + overflow:hidden; +} + +.x-tree-icon, .x-tree-ec-icon, .x-tree-elbow-line, .x-tree-elbow, .x-tree-elbow-end, .x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{ + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-repeat: no-repeat; +} + +.x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .x-tree-node-icon{ + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-position:center; + background-repeat: no-repeat; +} + +.ext-ie .x-tree-node-indent img, .ext-ie .x-tree-node-icon, .ext-ie .x-tree-ec-icon { + vertical-align: middle !important; +} + +.ext-strict .ext-ie8 .x-tree-node-indent img, .ext-strict .ext-ie8 .x-tree-node-icon, .ext-strict .ext-ie8 .x-tree-ec-icon { + vertical-align: top !important; +} + +/* checkboxes */ + +input.x-tree-node-cb { + margin-left:1px; + height: 19px; + vertical-align: bottom; +} + +.ext-ie input.x-tree-node-cb { + margin-left:0; + margin-top: 1px; + width: 16px; + height: 16px; + vertical-align: middle; +} + +.ext-strict .ext-ie8 input.x-tree-node-cb{ + margin: 1px 1px; + height: 14px; + vertical-align: bottom; +} + +.ext-strict .ext-ie8 input.x-tree-node-cb + a{ + vertical-align: bottom; +} + +.ext-opera input.x-tree-node-cb { + height: 14px; + vertical-align: middle; +} + +.x-tree-noicon .x-tree-node-icon{ + width:0; height:0; +} + +/* No line styles */ +.x-tree-no-lines .x-tree-elbow{ + background:transparent; +} + +.x-tree-no-lines .x-tree-elbow-end{ + background:transparent; +} + +.x-tree-no-lines .x-tree-elbow-line{ + background:transparent; +} + +/* Arrows */ +.x-tree-arrows .x-tree-elbow{ + background:transparent; +} + +.x-tree-arrows .x-tree-elbow-plus{ + background:transparent no-repeat 0 0; +} + +.x-tree-arrows .x-tree-elbow-minus{ + background:transparent no-repeat -16px 0; +} + +.x-tree-arrows .x-tree-elbow-end{ + background:transparent; +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background:transparent no-repeat 0 0; +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background:transparent no-repeat -16px 0; +} + +.x-tree-arrows .x-tree-elbow-line{ + background:transparent; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-plus{ + background-position:-32px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-minus{ + background-position:-48px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-plus{ + background-position:-32px 0; +} + +.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-minus{ + background-position:-48px 0; +} + +.x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{ + cursor:pointer; +} + +.ext-ie ul.x-tree-node-ct{ + font-size:0; + line-height:0; + zoom:1; +} + +.x-tree-node{ + white-space: nowrap; +} + +.x-tree-node-el { + line-height:18px; + cursor:pointer; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + text-decoration:none; + -khtml-user-select:none; + -moz-user-select:none; + -webkit-user-select:ignore; + -kthml-user-focus:normal; + -moz-user-focus:normal; + -moz-outline: 0 none; + outline:0 none; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + text-decoration:none; + padding:1px 3px 1px 2px; +} + +.x-tree-node .x-tree-node-disabled .x-tree-node-icon{ + -moz-opacity: 0.5; + opacity:.5; + filter: alpha(opacity=50); +} + +.x-tree-node .x-tree-node-inline-icon{ + background:transparent; +} + +.x-tree-node a:hover, .x-dd-drag-ghost a:hover{ + text-decoration:none; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom:1px dotted; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top:1px dotted; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below{ + border-bottom:0 none; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above{ + border-top:0 none; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom:2px solid; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top:2px solid; +} + +.x-tree-node .x-tree-drag-append a span{ + border:1px dotted; +} + +.x-dd-drag-ghost .x-tree-node-indent, .x-dd-drag-ghost .x-tree-ec-icon{ + display:none !important; +} + +/* Fix for ie rootVisible:false issue */ +.x-tree-root-ct { + zoom:1; +} +.x-date-picker { + border: 1px solid; + border-top:0 none; + position:relative; +} + +.x-date-picker a { + -moz-outline:0 none; + outline:0 none; +} + +.x-date-inner, .x-date-inner td, .x-date-inner th{ + border-collapse:separate; +} + +.x-date-middle,.x-date-left,.x-date-right { + background: repeat-x 0 -83px; + overflow:hidden; +} + +.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr, +.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr, +.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{ + background:transparent !important; + vertical-align:middle; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background:transparent no-repeat right 0; +} + +.x-date-right, .x-date-left { + width:18px; +} + +.x-date-right{ + text-align:right; +} + +.x-date-middle { + padding-top:2px; + padding-bottom:2px; + width:130px; /* FF3 */ +} + +.x-date-right a, .x-date-left a{ + display:block; + width:16px; + height:16px; + background-position: center; + background-repeat: no-repeat; + cursor:pointer; + -moz-opacity: 0.6; + opacity:.6; + filter: alpha(opacity=60); +} + +.x-date-right a:hover, .x-date-left a:hover{ + -moz-opacity: 1; + opacity:1; + filter: alpha(opacity=100); +} + +.x-item-disabled .x-date-right a:hover, .x-item-disabled .x-date-left a:hover{ + -moz-opacity: 0.6; + opacity:.6; + filter: alpha(opacity=60); +} + +.x-date-right a { + margin-right:2px; + text-decoration:none !important; +} + +.x-date-left a{ + margin-left:2px; + text-decoration:none !important; +} + +table.x-date-inner { + width: 100%; + table-layout:fixed; +} + +.ext-webkit table.x-date-inner{ + /* Fix for webkit browsers */ + width: 175px; +} + + +.x-date-inner th { + width:25px; +} + +.x-date-inner th { + background: repeat-x left top; + text-align:right !important; + border-bottom: 1px solid; + cursor:default; + padding:0; + border-collapse:separate; +} + +.x-date-inner th span { + display:block; + padding:2px; + padding-right:7px; +} + +.x-date-inner td { + border: 1px solid; + text-align:right; + padding:0; +} + +.x-date-inner a { + padding:2px 5px; + display:block; + text-decoration:none; + text-align:right; + zoom:1; +} + +.x-date-inner .x-date-active{ + cursor:pointer; + color:black; +} + +.x-date-inner .x-date-selected a{ + background: repeat-x left top; + border:1px solid; + padding:1px 4px; +} + +.x-date-inner .x-date-today a{ + border: 1px solid; + padding:1px 4px; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + text-decoration:none !important; +} + +.x-date-bottom { + padding:4px; + border-top: 1px solid; + background: repeat-x left top; +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + text-decoration:none !important; +} + +.x-item-disabled .x-date-inner a:hover{ + background: none; +} + +.x-date-inner .x-date-disabled a { + cursor:default; +} + +.x-date-menu .x-menu-item { + padding:1px 24px 1px 4px; + white-space: nowrap; +} + +.x-date-menu .x-menu-item .x-menu-item-icon { + width:10px; + height:10px; + margin-right:5px; + background-position:center -4px !important; +} + +.x-date-mp { + position:absolute; + left:0; + top:0; + display:none; +} + +.x-date-mp td { + padding:2px; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn { + border: 0 none; + text-align:center; + vertical-align: middle; + width:25%; +} + +.x-date-mp-ok { + margin-right:3px; +} + +.x-date-mp-btns button { + text-decoration:none; + text-align:center; + text-decoration:none !important; + border:1px solid; + padding:1px 3px 1px; + cursor:pointer; +} + +.x-date-mp-btns { + background: repeat-x left top; +} + +.x-date-mp-btns td { + border-top: 1px solid; + text-align:center; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + display:block; + padding:2px 4px; + text-decoration:none; + text-align:center; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + text-decoration:none; + cursor:pointer; +} + +td.x-date-mp-sel a { + padding:1px 3px; + background: repeat-x left top; + border:1px solid; +} + +.x-date-mp-ybtn a { + overflow:hidden; + width:15px; + height:15px; + cursor:pointer; + background:transparent no-repeat; + display:block; + margin:0 auto; +} + +.x-date-mp-ybtn a.x-date-mp-next { + background-position:0 -120px; +} + +.x-date-mp-ybtn a.x-date-mp-next:hover { + background-position:-15px -120px; +} + +.x-date-mp-ybtn a.x-date-mp-prev { + background-position:0 -105px; +} + +.x-date-mp-ybtn a.x-date-mp-prev:hover { + background-position:-15px -105px; +} + +.x-date-mp-ybtn { + text-align:center; +} + +td.x-date-mp-sep { + border-right:1px solid; +}.x-tip{ + position: absolute; + top: 0; + left:0; + visibility: hidden; + z-index: 20002; + border:0 none; +} + +.x-tip .x-tip-close{ + height: 15px; + float:right; + width: 15px; + margin:0 0 2px 2px; + cursor:pointer; + display:none; +} + +.x-tip .x-tip-tc { + background: transparent no-repeat 0 -62px; + padding-top:3px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-tr { + background: transparent no-repeat right 0; + padding-right:6px; + overflow:hidden; + zoom:1; +} + +.x-tip .x-tip-bc { + background: transparent no-repeat 0 -121px; + height:3px; + overflow:hidden; +} + +.x-tip .x-tip-bl { + background: transparent no-repeat 0 -59px; + padding-left:6px; + zoom:1; +} + +.x-tip .x-tip-br { + background: transparent no-repeat right -59px; + padding-right:6px; + zoom:1; +} + +.x-tip .x-tip-mc { + border:0 none; +} + +.x-tip .x-tip-ml { + background: no-repeat 0 -124px; + padding-left:6px; + zoom:1; +} + +.x-tip .x-tip-mr { + background: transparent no-repeat right -124px; + padding-right:6px; + zoom:1; +} + +.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc { + font-size:0; + line-height:0; +} + +.ext-border-box .x-tip .x-tip-header, .ext-border-box .x-tip .x-tip-tc{ + line-height: 1px; +} + +.x-tip .x-tip-header-text { + padding:0; + margin:0 0 2px 0; +} + +.x-tip .x-tip-body { + margin:0 !important; + line-height:14px; + padding:0; +} + +.x-tip .x-tip-body .loading-indicator { + margin:0; +} + +.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text { + cursor:move; +} + +.x-form-invalid-tip .x-tip-tc { + background: repeat-x 0 -12px; + padding-top:6px; +} + +.x-form-invalid-tip .x-tip-bc { + background: repeat-x 0 -18px; + height:6px; +} + +.x-form-invalid-tip .x-tip-bl { + background: no-repeat 0 -6px; +} + +.x-form-invalid-tip .x-tip-br { + background: no-repeat right -6px; +} + +.x-form-invalid-tip .x-tip-body { + padding:2px; +} + +.x-form-invalid-tip .x-tip-body { + padding-left:24px; + background:transparent no-repeat 2px 2px; +} + +.x-tip-anchor { + position: absolute; + width: 9px; + height: 10px; + overflow:hidden; + background: transparent no-repeat 0 0; + zoom:1; +} +.x-tip-anchor-bottom { + background-position: -9px 0; +} +.x-tip-anchor-right { + background-position: -18px 0; + width: 10px; +} +.x-tip-anchor-left { + background-position: -28px 0; + width: 10px; +}.x-menu { + z-index: 15000; + zoom: 1; + background: repeat-y; +} + +.x-menu-floating{ + border: 1px solid; +} + +.x-menu a { + text-decoration: none !important; +} + +.ext-ie .x-menu { + zoom:1; + overflow:hidden; +} + +.x-menu-list{ + padding: 2px; + background:transparent; + border:0 none; + overflow:hidden; + overflow-y: hidden; +} + +.ext-strict .ext-ie .x-menu-list{ + position: relative; +} + +.x-menu li{ + line-height:100%; +} + +.x-menu li.x-menu-sep-li{ + font-size:1px; + line-height:1px; +} + +.x-menu-list-item{ + white-space: nowrap; + display:block; + padding:1px; +} + +.x-menu-item{ + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; +} + +.x-menu-item-arrow{ + background:transparent no-repeat right; +} + +.x-menu-sep { + display:block; + font-size:1px; + line-height:1px; + margin: 2px 3px; + border-bottom:1px solid; + overflow:hidden; +} + +.x-menu-focus { + position:absolute; + left:-1px; + top:-1px; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; + overflow:hidden; + display:block; +} + +a.x-menu-item { + cursor: pointer; + display: block; + line-height: 16px; + outline-color: -moz-use-text-color; + outline-style: none; + outline-width: 0; + padding: 3px 21px 3px 27px; + position: relative; + text-decoration: none; + white-space: nowrap; +} + +.x-menu-item-active { + background-repeat: repeat-x; + background-position: left bottom; + border-style:solid; + border-width: 1px 0; + margin:0 1px; + padding: 0; +} + +.x-menu-item-active a.x-menu-item { + border-style:solid; + border-width:0 1px; + margin:0 -1px; +} + +.x-menu-item-icon { + border: 0 none; + height: 16px; + padding: 0; + vertical-align: top; + width: 16px; + position: absolute; + left: 3px; + top: 3px; + margin: 0; + background-position:center; +} + +.ext-ie .x-menu-item-icon { + left: -24px; +} +.ext-strict .x-menu-item-icon { + left: 3px; +} + +.ext-ie6 .x-menu-item-icon { + left: -24px; +} + +.ext-ie .x-menu-item-icon { + vertical-align: middle; +} + +.x-menu-check-item .x-menu-item-icon{ + background: transparent no-repeat center; +} + +.x-menu-group-item .x-menu-item-icon{ + background: transparent; +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background: transparent no-repeat center; +} + +.x-date-menu .x-menu-list{ + padding: 0; +} + +.x-menu-date-item{ + padding:0; +} + +.x-menu .x-color-palette, .x-menu .x-date-picker{ + margin-left: 26px; + margin-right:4px; +} + +.x-menu .x-date-picker{ + border:1px solid; + margin-top:2px; + margin-bottom:2px; +} + +.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{ + margin: 0; + border: 0 none; +} + +.x-date-menu { + padding:0 !important; +} + +/* + * fixes separator visibility problem in IE 6 + */ +.ext-strict .ext-ie6 .x-menu-sep-li { + padding: 3px 4px; +} +.ext-strict .ext-ie6 .x-menu-sep { + margin: 0; + height: 1px; +} + +/* + * Ugly mess to remove the white border under the picker + */ +.ext-ie .x-date-menu{ + height: 199px; +} + +.ext-strict .ext-ie .x-date-menu, .ext-border-box .ext-ie8 .x-date-menu{ + height: 197px; +} + +.ext-strict .ext-ie7 .x-date-menu{ + height: 195px; +} + +.ext-strict .ext-ie8 .x-date-menu{ + height: auto; +} + +.x-cycle-menu .x-menu-item-checked { + border:1px dotted !important; + padding:0; +} + +.x-menu .x-menu-scroller { + width: 100%; + background-repeat:no-repeat; + background-position:center; + height:8px; + line-height: 8px; + cursor:pointer; + margin: 0; + padding: 0; +} + +.x-menu .x-menu-scroller-active{ + height: 6px; + line-height: 6px; +} + +.x-menu-list-item-indent{ + padding-left: 27px; +}/* + Creates rounded, raised boxes like on the Ext website - the markup isn't pretty: +
    +
    +
    +

    YOUR TITLE HERE (optional)

    +
    YOUR CONTENT HERE
    +
    +
    +
    + */ + +.x-box-tl { + background: transparent no-repeat 0 0; + zoom:1; +} + +.x-box-tc { + height: 8px; + background: transparent repeat-x 0 0; + overflow: hidden; +} + +.x-box-tr { + background: transparent no-repeat right -8px; +} + +.x-box-ml { + background: transparent repeat-y 0; + padding-left: 4px; + overflow: hidden; + zoom:1; +} + +.x-box-mc { + background: repeat-x 0 -16px; + padding: 4px 10px; +} + +.x-box-mc h3 { + margin: 0 0 4px 0; + zoom:1; +} + +.x-box-mr { + background: transparent repeat-y right; + padding-right: 4px; + overflow: hidden; +} + +.x-box-bl { + background: transparent no-repeat 0 -16px; + zoom:1; +} + +.x-box-bc { + background: transparent repeat-x 0 -8px; + height: 8px; + overflow: hidden; +} + +.x-box-br { + background: transparent no-repeat right -24px; +} + +.x-box-tl, .x-box-bl { + padding-left: 8px; + overflow: hidden; +} + +.x-box-tr, .x-box-br { + padding-right: 8px; + overflow: hidden; +}.x-combo-list { + border:1px solid; + zoom:1; + overflow:hidden; +} + +.x-combo-list-inner { + overflow:auto; + position:relative; /* for calculating scroll offsets */ + zoom:1; + overflow-x:hidden; +} + +.x-combo-list-hd { + border-bottom:1px solid; + padding:3px; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom:1px solid; +} + +.x-combo-list-item { + padding:2px; + border:1px solid; + white-space: nowrap; + overflow:hidden; + text-overflow: ellipsis; +} + +.x-combo-list .x-combo-selected{ + border:1px dotted !important; + cursor:pointer; +} + +.x-combo-list .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +}.x-panel { + border-style: solid; + border-width:0; +} + +.x-panel-header { + overflow:hidden; + zoom:1; + padding:5px 3px 4px 5px; + border:1px solid; + line-height: 15px; + background: transparent repeat-x 0 -1px; +} + +.x-panel-body { + border:1px solid; + border-top:0 none; + overflow:hidden; + position: relative; /* added for item scroll positioning */ +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top:1px solid; + border-bottom: 0 none; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top:1px solid; +} + +.x-panel-header { + overflow:hidden; + zoom:1; +} + +.x-panel-tl .x-panel-header { + padding:5px 0 4px 0; + border:0 none; + background:transparent; +} + +.x-panel-tl .x-panel-icon, .x-window-tl .x-panel-icon { + padding-left:20px !important; + background-repeat:no-repeat; + background-position:0 4px; + zoom:1; +} + +.x-panel-inline-icon { + width:16px; + height:16px; + background-repeat:no-repeat; + background-position:0 0; + vertical-align:middle; + margin-right:4px; + margin-top:-1px; + margin-bottom:-1px; +} + +.x-panel-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} + +/* fix ie7 strict mode bug */ +.ext-strict .ext-ie7 .x-panel-tc { + overflow: visible; +} + +.x-panel-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + border-bottom:1px solid; +} + +.x-panel-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:6px; +} + +.x-panel-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-panel-bc .x-panel-footer { + zoom:1; +} + +.x-panel-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} + +.x-panel-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} + +.x-panel-mc { + border:0 none; + padding:0; + margin:0; + padding-top:6px; +} + +.x-panel-mc .x-panel-body { + background:transparent; + border: 0 none; +} + +.x-panel-ml { + background: repeat-y 0 0; + padding-left:6px; + zoom:1; +} + +.x-panel-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} + +.x-panel-bc .x-panel-footer { + padding-bottom:6px; +} + +.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc { + height:6px; + font-size:0; + line-height:0; +} + +.x-panel-bwrap { + overflow:hidden; + zoom:1; + left:0; + top:0; +} +.x-panel-body { + overflow:hidden; + zoom:1; +} + +.x-panel-collapsed .x-resizable-handle{ + display:none; +} + +.ext-gecko .x-panel-animated div { + overflow:hidden !important; +} + +/* Plain */ +.x-plain-body { + overflow:hidden; +} + +.x-plain-bbar .x-toolbar { + overflow:hidden; + padding:2px; +} + +.x-plain-tbar .x-toolbar { + overflow:hidden; + padding:2px; +} + +.x-plain-bwrap { + overflow:hidden; + zoom:1; +} + +.x-plain { + overflow:hidden; +} + +/* Tools */ +.x-tool { + overflow:hidden; + width:15px; + height:15px; + float:right; + cursor:pointer; + background:transparent no-repeat; + margin-left:2px; +} + +/* expand / collapse tools */ +.x-tool-toggle { + background-position:0 -60px; +} + +.x-tool-toggle-over { + background-position:-15px -60px; +} + +.x-panel-collapsed .x-tool-toggle { + background-position:0 -75px; +} + +.x-panel-collapsed .x-tool-toggle-over { + background-position:-15px -75px; +} + + +.x-tool-close { + background-position:0 -0; +} + +.x-tool-close-over { + background-position:-15px 0; +} + +.x-tool-minimize { + background-position:0 -15px; +} + +.x-tool-minimize-over { + background-position:-15px -15px; +} + +.x-tool-maximize { + background-position:0 -30px; +} + +.x-tool-maximize-over { + background-position:-15px -30px; +} + +.x-tool-restore { + background-position:0 -45px; +} + +.x-tool-restore-over { + background-position:-15px -45px; +} + +.x-tool-gear { + background-position:0 -90px; +} + +.x-tool-gear-over { + background-position:-15px -90px; +} + +.x-tool-pin { + background-position:0 -135px; +} + +.x-tool-pin-over { + background-position:-15px -135px; +} + +.x-tool-unpin { + background-position:0 -150px; +} + +.x-tool-unpin-over { + background-position:-15px -150px; +} + +.x-tool-right { + background-position:0 -165px; +} + +.x-tool-right-over { + background-position:-15px -165px; +} + +.x-tool-left { + background-position:0 -180px; +} + +.x-tool-left-over { + background-position:-15px -180px; +} + +.x-tool-up { + background-position:0 -210px; +} + +.x-tool-up-over { + background-position:-15px -210px; +} + +.x-tool-down { + background-position:0 -195px; +} + +.x-tool-down-over { + background-position:-15px -195px; +} + +.x-tool-refresh { + background-position:0 -225px; +} + +.x-tool-refresh-over { + background-position:-15px -225px; +} + +.x-tool-minus { + background-position:0 -255px; +} + +.x-tool-minus-over { + background-position:-15px -255px; +} + +.x-tool-plus { + background-position:0 -240px; +} + +.x-tool-plus-over { + background-position:-15px -240px; +} + +.x-tool-search { + background-position:0 -270px; +} + +.x-tool-search-over { + background-position:-15px -270px; +} + +.x-tool-save { + background-position:0 -285px; +} + +.x-tool-save-over { + background-position:-15px -285px; +} + +.x-tool-help { + background-position:0 -300px; +} + +.x-tool-help-over { + background-position:-15px -300px; +} + +.x-tool-print { + background-position:0 -315px; +} + +.x-tool-print-over { + background-position:-15px -315px; +} + +/* Ghosting */ +.x-panel-ghost { + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + opacity:.65; + -moz-opacity:.65; + filter:alpha(opacity=65); +} + +.x-panel-ghost ul { + margin:0; + padding:0; + overflow:hidden; + font-size:0; + line-height:0; + border:1px solid; + border-top:0 none; + display:block; +} + +.x-panel-ghost * { + cursor:move !important; +} + +.x-panel-dd-spacer { + border:2px dashed; +} + +/* Buttons */ +.x-panel-btns { + padding:5px; + overflow:hidden; +} + +.x-panel-btns td.x-toolbar-cell{ + padding:3px; +} + +.x-panel-btns .x-btn-focus .x-btn-left{ + background-position:0 -147px; +} + +.x-panel-btns .x-btn-focus .x-btn-right{ + background-position:0 -168px; +} + +.x-panel-btns .x-btn-focus .x-btn-center{ + background-position:0 -189px; +} + +.x-panel-btns .x-btn-over .x-btn-left{ + background-position:0 -63px; +} + +.x-panel-btns .x-btn-over .x-btn-right{ + background-position:0 -84px; +} + +.x-panel-btns .x-btn-over .x-btn-center{ + background-position:0 -105px; +} + +.x-panel-btns .x-btn-click .x-btn-center{ + background-position:0 -126px; +} + +.x-panel-btns .x-btn-click .x-btn-right{ + background-position:0 -84px; +} + +.x-panel-btns .x-btn-click .x-btn-left{ + background-position:0 -63px; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + white-space: nowrap; +} +/** + * W3C Suggested Default style sheet for HTML 4 + * http://www.w3.org/TR/CSS21/sample.html + * + * Resets for Ext.Panel @cfg normal: true + */ +.x-panel-reset .x-panel-body html, +.x-panel-reset .x-panel-body address, +.x-panel-reset .x-panel-body blockquote, +.x-panel-reset .x-panel-body body, +.x-panel-reset .x-panel-body dd, +.x-panel-reset .x-panel-body div, +.x-panel-reset .x-panel-body dl, +.x-panel-reset .x-panel-body dt, +.x-panel-reset .x-panel-body fieldset, +.x-panel-reset .x-panel-body form, +.x-panel-reset .x-panel-body frame, frameset, +.x-panel-reset .x-panel-body h1, +.x-panel-reset .x-panel-body h2, +.x-panel-reset .x-panel-body h3, +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body h5, +.x-panel-reset .x-panel-body h6, +.x-panel-reset .x-panel-body noframes, +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body p, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body center, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body hr, +.x-panel-reset .x-panel-body menu, +.x-panel-reset .x-panel-body pre { display: block } +.x-panel-reset .x-panel-body li { display: list-item } +.x-panel-reset .x-panel-body head { display: none } +.x-panel-reset .x-panel-body table { display: table } +.x-panel-reset .x-panel-body tr { display: table-row } +.x-panel-reset .x-panel-body thead { display: table-header-group } +.x-panel-reset .x-panel-body tbody { display: table-row-group } +.x-panel-reset .x-panel-body tfoot { display: table-footer-group } +.x-panel-reset .x-panel-body col { display: table-column } +.x-panel-reset .x-panel-body colgroup { display: table-column-group } +.x-panel-reset .x-panel-body td, +.x-panel-reset .x-panel-body th { display: table-cell } +.x-panel-reset .x-panel-body caption { display: table-caption } +.x-panel-reset .x-panel-body th { font-weight: bolder; text-align: center } +.x-panel-reset .x-panel-body caption { text-align: center } +.x-panel-reset .x-panel-body body { margin: 8px } +.x-panel-reset .x-panel-body h1 { font-size: 2em; margin: .67em 0 } +.x-panel-reset .x-panel-body h2 { font-size: 1.5em; margin: .75em 0 } +.x-panel-reset .x-panel-body h3 { font-size: 1.17em; margin: .83em 0 } +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body p, +.x-panel-reset .x-panel-body blockquote, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body fieldset, +.x-panel-reset .x-panel-body form, +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body dl, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body menu { margin: 1.12em 0 } +.x-panel-reset .x-panel-body h5 { font-size: .83em; margin: 1.5em 0 } +.x-panel-reset .x-panel-body h6 { font-size: .75em; margin: 1.67em 0 } +.x-panel-reset .x-panel-body h1, +.x-panel-reset .x-panel-body h2, +.x-panel-reset .x-panel-body h3, +.x-panel-reset .x-panel-body h4, +.x-panel-reset .x-panel-body h5, +.x-panel-reset .x-panel-body h6, +.x-panel-reset .x-panel-body b, +.x-panel-reset .x-panel-body strong { font-weight: bolder } +.x-panel-reset .x-panel-body blockquote { margin-left: 40px; margin-right: 40px } +.x-panel-reset .x-panel-body i, +.x-panel-reset .x-panel-body cite, +.x-panel-reset .x-panel-body em, +.x-panel-reset .x-panel-body var, +.x-panel-reset .x-panel-body address { font-style: italic } +.x-panel-reset .x-panel-body pre, +.x-panel-reset .x-panel-body tt, +.x-panel-reset .x-panel-body code, +.x-panel-reset .x-panel-body kbd, +.x-panel-reset .x-panel-body samp { font-family: monospace } +.x-panel-reset .x-panel-body pre { white-space: pre } +.x-panel-reset .x-panel-body button, +.x-panel-reset .x-panel-body textarea, +.x-panel-reset .x-panel-body input, +.x-panel-reset .x-panel-body select { display: inline-block } +.x-panel-reset .x-panel-body big { font-size: 1.17em } +.x-panel-reset .x-panel-body small, +.x-panel-reset .x-panel-body sub, +.x-panel-reset .x-panel-body sup { font-size: .83em } +.x-panel-reset .x-panel-body sub { vertical-align: sub } +.x-panel-reset .x-panel-body sup { vertical-align: super } +.x-panel-reset .x-panel-body table { border-spacing: 2px; } +.x-panel-reset .x-panel-body thead, +.x-panel-reset .x-panel-body tbody, +.x-panel-reset .x-panel-body tfoot { vertical-align: middle } +.x-panel-reset .x-panel-body td, +.x-panel-reset .x-panel-body th { vertical-align: inherit } +.x-panel-reset .x-panel-body s, +.x-panel-reset .x-panel-body strike, +.x-panel-reset .x-panel-body del { text-decoration: line-through } +.x-panel-reset .x-panel-body hr { border: 1px inset } +.x-panel-reset .x-panel-body ol, +.x-panel-reset .x-panel-body ul, +.x-panel-reset .x-panel-body dir, +.x-panel-reset .x-panel-body menu, +.x-panel-reset .x-panel-body dd { margin-left: 40px } +.x-panel-reset .x-panel-body ul, .x-panel-reset .x-panel-body menu, .x-panel-reset .x-panel-body dir { list-style-type: disc;} +.x-panel-reset .x-panel-body ol { list-style-type: decimal } +.x-panel-reset .x-panel-body ol ul, +.x-panel-reset .x-panel-body ul ol, +.x-panel-reset .x-panel-body ul ul, +.x-panel-reset .x-panel-body ol ol { margin-top: 0; margin-bottom: 0 } +.x-panel-reset .x-panel-body u, +.x-panel-reset .x-panel-body ins { text-decoration: underline } +.x-panel-reset .x-panel-body br:before { content: "\A" } +.x-panel-reset .x-panel-body :before, .x-panel-reset .x-panel-body :after { white-space: pre-line } +.x-panel-reset .x-panel-body center { text-align: center } +.x-panel-reset .x-panel-body :link, .x-panel-reset .x-panel-body :visited { text-decoration: underline } +.x-panel-reset .x-panel-body :focus { outline: invert dotted thin } + +/* Begin bidirectionality settings (do not change) */ +.x-panel-reset .x-panel-body BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override } +.x-panel-reset .x-panel-body BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override } +.x-window { + zoom:1; +} + +.x-window .x-window-handle { + opacity:0; + -moz-opacity:0; + filter:alpha(opacity=0); +} + +.x-window-proxy { + border:1px solid; + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + display:none; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} + +.x-window-header { + overflow:hidden; + zoom:1; +} + +.x-window-bwrap { + z-index:1; + position:relative; + zoom:1; + left:0;top:0; +} + +.x-window-tl .x-window-header { + padding:5px 0 4px 0; +} + +.x-window-header-text { + cursor:pointer; +} + +.x-window-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + zoom:1; +} + +.x-window-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + z-index:1; + position:relative; +} + +.x-window-tr { + background: transparent no-repeat right 0; + padding-right:6px; +} + +.x-window-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} + +.x-window-bc .x-window-footer { + padding-bottom:6px; + zoom:1; + font-size:0; + line-height:0; +} + +.x-window-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} + +.x-window-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} + +.x-window-mc { + border:1px solid; + padding:0; + margin:0; +} + +.x-window-ml { + background: transparent repeat-y 0 0; + padding-left:6px; + zoom:1; +} + +.x-window-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} + +.x-window-body { + overflow:hidden; +} + +.x-window-bwrap { + overflow:hidden; +} + +.x-window-maximized .x-window-bl, .x-window-maximized .x-window-br, + .x-window-maximized .x-window-ml, .x-window-maximized .x-window-mr, + .x-window-maximized .x-window-tl, .x-window-maximized .x-window-tr { + padding:0; +} + +.x-window-maximized .x-window-footer { + padding-bottom:0; +} + +.x-window-maximized .x-window-tc { + padding-left:3px; + padding-right:3px; +} + +.x-window-maximized .x-window-mc { + border-left:0 none; + border-right:0 none; +} + +.x-window-tbar .x-toolbar, .x-window-bbar .x-toolbar { + border-left:0 none; + border-right: 0 none; +} + +.x-window-bbar .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +} + +.x-window-draggable, .x-window-draggable .x-window-header-text { + cursor:move; +} + +.x-window-maximized .x-window-draggable, .x-window-maximized .x-window-draggable .x-window-header-text { + cursor:default; +} + +.x-window-body { + background:transparent; +} + +.x-panel-ghost .x-window-tl { + border-bottom:1px solid; +} + +.x-panel-collapsed .x-window-tl { + border-bottom:1px solid; +} + +.x-window-maximized-ct { + overflow:hidden; +} + +.x-window-maximized .x-window-handle { + display:none; +} + +.x-window-sizing-ghost ul { + border:0 none !important; +} + +.x-dlg-focus{ + -moz-outline:0 none; + outline:0 none; + width:0; + height:0; + overflow:hidden; + position:absolute; + top:0; + left:0; +} + +.ext-webkit .x-dlg-focus{ + width: 1px; + height: 1px; +} + +.x-dlg-mask{ + z-index:10000; + display:none; + position:absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity:.50; + filter: alpha(opacity=50); +} + +body.ext-ie6.x-body-masked select { + visibility:hidden; +} + +body.ext-ie6.x-body-masked .x-window select { + visibility:visible; +} + +.x-window-plain .x-window-mc { + border: 1px solid; +} + +.x-window-plain .x-window-body { + border: 1px solid; + background:transparent !important; +}.x-html-editor-wrap { + border:1px solid; +} + +.x-html-editor-tb .x-btn-text { + background:transparent no-repeat; +} + +.x-html-editor-tb .x-edit-bold, .x-menu-item img.x-edit-bold { + background-position:0 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-italic, .x-menu-item img.x-edit-italic { + background-position:-16px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-underline, .x-menu-item img.x-edit-underline { + background-position:-32px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-forecolor, .x-menu-item img.x-edit-forecolor { + background-position:-160px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-backcolor, .x-menu-item img.x-edit-backcolor { + background-position:-176px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyleft, .x-menu-item img.x-edit-justifyleft { + background-position:-112px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifycenter, .x-menu-item img.x-edit-justifycenter { + background-position:-128px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyright, .x-menu-item img.x-edit-justifyright { + background-position:-144px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertorderedlist, .x-menu-item img.x-edit-insertorderedlist { + background-position:-80px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertunorderedlist, .x-menu-item img.x-edit-insertunorderedlist { + background-position:-96px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-increasefontsize, .x-menu-item img.x-edit-increasefontsize { + background-position:-48px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-decreasefontsize, .x-menu-item img.x-edit-decreasefontsize { + background-position:-64px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-sourceedit, .x-menu-item img.x-edit-sourceedit { + background-position:-192px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-createlink, .x-menu-item img.x-edit-createlink { + background-position:-208px 0; + background-image:url(images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tip .x-tip-bd .x-tip-bd-inner { + padding:5px; + padding-bottom:1px; +} + +.x-html-editor-tb .x-toolbar { + position:static !important; +}.x-panel-noborder .x-panel-body-noborder { + border-width:0; +} + +.x-panel-noborder .x-panel-header-noborder { + border-width:0 0 1px; + border-style:solid; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-width:1px 0 0 0; + border-style:solid; +} + +.x-window-noborder .x-window-mc { + border-width:0; +} + +.x-window-plain .x-window-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-header-noborder { + border-width: 0 0 1px 0; +} + +.x-tab-panel-noborder .x-tab-panel-footer-noborder { + border-width: 1px 0 0 0; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-width: 1px 0 0 0; + border-style:solid; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +}.x-border-layout-ct { + position: relative; +} + +.x-border-panel { + position:absolute; + left:0; + top:0; +} + +.x-tool-collapse-south { + background-position:0 -195px; +} + +.x-tool-collapse-south-over { + background-position:-15px -195px; +} + +.x-tool-collapse-north { + background-position:0 -210px; +} + +.x-tool-collapse-north-over { + background-position:-15px -210px; +} + +.x-tool-collapse-west { + background-position:0 -180px; +} + +.x-tool-collapse-west-over { + background-position:-15px -180px; +} + +.x-tool-collapse-east { + background-position:0 -165px; +} + +.x-tool-collapse-east-over { + background-position:-15px -165px; +} + +.x-tool-expand-south { + background-position:0 -210px; +} + +.x-tool-expand-south-over { + background-position:-15px -210px; +} + +.x-tool-expand-north { + background-position:0 -195px; +} +.x-tool-expand-north-over { + background-position:-15px -195px; +} + +.x-tool-expand-west { + background-position:0 -165px; +} + +.x-tool-expand-west-over { + background-position:-15px -165px; +} + +.x-tool-expand-east { + background-position:0 -180px; +} + +.x-tool-expand-east-over { + background-position:-15px -180px; +} + +.x-tool-expand-north, .x-tool-expand-south { + float:right; + margin:3px; +} + +.x-tool-expand-east, .x-tool-expand-west { + float:none; + margin:3px auto; +} + +.x-accordion-hd .x-tool-toggle { + background-position:0 -255px; +} + +.x-accordion-hd .x-tool-toggle-over { + background-position:-15px -255px; +} + +.x-panel-collapsed .x-accordion-hd .x-tool-toggle { + background-position:0 -240px; +} + +.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over { + background-position:-15px -240px; +} + +.x-accordion-hd { + padding-top:4px; + padding-bottom:3px; + border-top:0 none; + background: transparent repeat-x 0 -9px; +} + +.x-layout-collapsed{ + position:absolute; + left:-10000px; + top:-10000px; + visibility:hidden; + width:20px; + height:20px; + overflow:hidden; + border:1px solid; + z-index:20; +} + +.ext-border-box .x-layout-collapsed{ + width:22px; + height:22px; +} + +.x-layout-collapsed-over{ + cursor:pointer; +} + +.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{ + position:absolute; + top:0; + left:0; + width:20px; + height:20px; +} + + +.x-layout-split{ + position:absolute; + height:5px; + width:5px; + line-height:1px; + font-size:1px; + z-index:3; + background-color:transparent; +} + +/* IE6 strict won't drag w/out a color */ +.ext-strict .ext-ie6 .x-layout-split{ + background-color: #fff !important; + filter: alpha(opacity=1); +} + +.x-layout-split-h{ + background-image:url(images/default/s.gif); + background-position: left; +} + +.x-layout-split-v{ + background-image:url(images/default/s.gif); + background-position: top; +} + +.x-column-layout-ct { + overflow:hidden; + zoom:1; +} + +.x-column { + float:left; + padding:0; + margin:0; + overflow:hidden; + zoom:1; +} + +.x-column-inner { + overflow:hidden; + zoom:1; +} + +/* mini mode */ +.x-layout-mini { + position:absolute; + top:0; + left:0; + display:block; + width:5px; + height:35px; + cursor:pointer; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} + +.x-layout-mini-over, .x-layout-collapsed-over .x-layout-mini{ + opacity:1; + -moz-opacity:1; + filter:none; +} + +.x-layout-split-west .x-layout-mini { + top:48%; +} + +.x-layout-split-east .x-layout-mini { + top:48%; +} + +.x-layout-split-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-split-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-west .x-layout-mini { + top:48%; +} + +.x-layout-cmini-east .x-layout-mini { + top:48%; +} + +.x-layout-cmini-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} + +.x-layout-cmini-west, .x-layout-cmini-east { + border:0 none; + width:5px !important; + padding:0; + background:transparent; +} + +.x-layout-cmini-north, .x-layout-cmini-south { + border:0 none; + height:5px !important; + padding:0; + background:transparent; +} + +.x-viewport, .x-viewport body { + margin: 0; + padding: 0; + border: 0 none; + overflow: hidden; + height: 100%; +} + +.x-abs-layout-item { + position:absolute; + left:0; + top:0; +} + +.ext-ie input.x-abs-layout-item, .ext-ie textarea.x-abs-layout-item { + margin:0; +} + +.x-box-layout-ct { + overflow:hidden; + zoom:1; +} + +.x-box-inner { + overflow:hidden; + zoom:1; + position:relative; + left:0; + top:0; +} + +.x-box-item { + position:absolute; + left:0; + top:0; +}.x-progress-wrap { + border:1px solid; + overflow:hidden; +} + +.x-progress-inner { + height:18px; + background:repeat-x; + position:relative; +} + +.x-progress-bar { + height:18px; + float:left; + width:0; + background: repeat-x left center; + border-top:1px solid; + border-bottom:1px solid; + border-right:1px solid; +} + +.x-progress-text { + padding:1px 5px; + overflow:hidden; + position:absolute; + left:0; + text-align:center; +} + +.x-progress-text-back { + line-height:16px; +} + +.ext-ie .x-progress-text-back { + line-height:15px; +} + +.ext-strict .ext-ie7 .x-progress-text-back{ + width: 100%; +} +.x-list-header{ + background: repeat-x 0 bottom; + cursor:default; + zoom:1; + height:22px; +} + +.x-list-header-inner div { + display:block; + float:left; + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; +} + +.x-list-header-inner div em { + display:block; + border-left:1px solid; + padding:4px 4px; + overflow:hidden; + -moz-user-select: none; + -khtml-user-select: none; + line-height:14px; +} + +.x-list-body { + overflow:auto; + overflow-x:hidden; + overflow-y:auto; + zoom:1; + float: left; + width: 100%; +} + +.x-list-body dl { + zoom:1; +} + +.x-list-body dt { + display:block; + float:left; + overflow:hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + cursor:pointer; + zoom:1; +} + +.x-list-body dt em { + display:block; + padding:3px 4px; + overflow:hidden; + -moz-user-select: none; + -khtml-user-select: none; +} + +.x-list-resizer { + border-left:1px solid; + border-right:1px solid; + position:absolute; + left:0; + top:0; +} + +.x-list-header-inner em.sort-asc { + background: transparent no-repeat center 0; + border-style:solid; + border-width: 0 1px 1px; + padding-bottom:3px; +} + +.x-list-header-inner em.sort-desc { + background: transparent no-repeat center -23px; + border-style:solid; + border-width: 0 1px 1px; + padding-bottom:3px; +} + +/* Shared styles */ +.x-slider { + zoom:1; +} + +.x-slider-inner { + position:relative; + left:0; + top:0; + overflow:visible; + zoom:1; +} + +.x-slider-focus { + position:absolute; + left:0; + top:0; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: none; + -khtml-user-select:none; + -webkit-user-select:ignore; + display:block; + overflow:hidden; +} + +/* Horizontal styles */ +.x-slider-horz { + padding-left:7px; + background:transparent no-repeat 0 -22px; +} + +.x-slider-horz .x-slider-end { + padding-right:7px; + zoom:1; + background:transparent no-repeat right -44px; +} + +.x-slider-horz .x-slider-inner { + background:transparent repeat-x 0 0; + height:22px; +} + +.x-slider-horz .x-slider-thumb { + width:14px; + height:15px; + position:absolute; + left:0; + top:3px; + background:transparent no-repeat 0 0; +} + +.x-slider-horz .x-slider-thumb-over { + background-position: -14px -15px; +} + +.x-slider-horz .x-slider-thumb-drag { + background-position: -28px -30px; +} + +/* Vertical styles */ +.x-slider-vert { + padding-top:7px; + background:transparent no-repeat -44px 0; + width:22px; +} + +.x-slider-vert .x-slider-end { + padding-bottom:7px; + zoom:1; + background:transparent no-repeat -22px bottom; +} + +.x-slider-vert .x-slider-inner { + background:transparent repeat-y 0 0; +} + +.x-slider-vert .x-slider-thumb { + width:15px; + height:14px; + position:absolute; + left:3px; + bottom:0; + background:transparent no-repeat 0 0; +} + +.x-slider-vert .x-slider-thumb-over { + background-position: -15px -14px; +} + +.x-slider-vert .x-slider-thumb-drag { + background-position: -30px -28px; +}.x-window-dlg .x-window-body { + border:0 none !important; + padding:5px 10px; + overflow:hidden !important; +} + +.x-window-dlg .x-window-mc { + border:0 none !important; +} + +.x-window-dlg .ext-mb-input { + margin-top:4px; + width:95%; +} + +.x-window-dlg .ext-mb-textarea { + margin-top:4px; +} + +.x-window-dlg .x-progress-wrap { + margin-top:4px; +} + +.ext-ie .x-window-dlg .x-progress-wrap { + margin-top:6px; +} + +.x-window-dlg .x-msg-box-wait { + background:transparent no-repeat left; + display:block; + width:300px; + padding-left:18px; + line-height:18px; +} + +.x-window-dlg .ext-mb-icon { + float:left; + width:47px; + height:32px; +} + +.ext-ie .x-window-dlg .ext-mb-icon { + width:44px; /* 3px IE margin issue */ +} + +.x-window-dlg .x-dlg-icon .ext-mb-content{ + zoom: 1; margin-left: 47px; +} + +.x-window-dlg .ext-mb-info, .x-window-dlg .ext-mb-warning, .x-window-dlg .ext-mb-question, .x-window-dlg .ext-mb-error { + background:transparent no-repeat top left; +} + +.ext-gecko2 .ext-mb-fix-cursor { + overflow:auto; +}.ext-el-mask { + background-color: #ccc; +} + +.ext-el-mask-msg { + border-color:#6593cf; + background-color:#c3daf9; + background-image:url(images/default/box/tb-blue.gif); +} +.ext-el-mask-msg div { + background-color: #eee; + border-color:#a3bad9; + color:#222; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-mask-loading div { + background-color:#fbfbfb; + background-image:url(images/default/grid/loading.gif); +} + +.x-item-disabled { + color: gray; +} + +.x-item-disabled * { + color: gray !important; +} + +.x-splitbar-proxy { + background-color: #aaa; +} + +.x-color-palette a { + border-color:#fff; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border-color:#8bb8f3; + background-color: #deecfd; +} + +.x-color-palette em:hover, .x-color-palette span:hover{ + background-color: #deecfd; +} + +.x-color-palette em { + border-color:#aca899; +} + +.x-ie-shadow { + background-color:#777; +} + +.x-shadow .xsmc { + background-image: url(images/default/shadow-c.png); +} + +.x-shadow .xsml, .x-shadow .xsmr { + background-image: url(images/default/shadow-lr.png); +} + +.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{ + background-image: url(images/default/shadow.png); +} + +.loading-indicator { + font-size: 11px; + background-image: url(images/default/grid/loading.gif); +} + +.x-spotlight { + background-color: #ccc; +} +.x-tab-panel-header, .x-tab-panel-footer { + background-color: #deecfd; + border-color:#8db2e3; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border-color:#8db2e3; +} + +ul.x-tab-strip-top{ + background-color:#cedff5; + background-image: url(images/default/tabs/tab-strip-bg.gif); + border-bottom-color:#8db2e3; +} + +ul.x-tab-strip-bottom{ + background-color:#cedff5; + background-image: url(images/default/tabs/tab-strip-btm-bg.gif); + border-top-color:#8db2e3; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-color:#8db2e3; + background-color: #deecfd; +} + +.x-tab-strip span.x-tab-strip-text { + font:normal 11px tahoma,arial,helvetica; + color:#416aa3; +} + +.x-tab-strip-over span.x-tab-strip-text { + color:#15428b; +} + +.x-tab-strip-active span.x-tab-strip-text { + color:#15428b; + font-weight:bold; +} + +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} + +.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{ + background-image: url(images/default/tabs/tabs-sprite.gif); +} + +.x-tab-strip-bottom .x-tab-right { + background-image: url(images/default/tabs/tab-btm-inactive-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-left { + background-image: url(images/default/tabs/tab-btm-inactive-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-right { + background-image: url(images/default/tabs/tab-btm-over-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-left { + background-image: url(images/default/tabs/tab-btm-over-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image: url(images/default/tabs/tab-btm-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image: url(images/default/tabs/tab-btm-left-bg.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(images/default/tabs/tab-close.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(images/default/tabs/tab-close.gif); +} + +.x-tab-panel-body { + border-color:#8db2e3; + background-color:#fff; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background-image:url(images/default/tabs/scroll-left.gif); + border-bottom-color:#8db2e3; +} + +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background-image:url(images/default/tabs/scroll-right.gif); + border-bottom-color:#8db2e3; +} + +.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar { + border-color:#99bbe8; +}.x-form-field { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-text, textarea.x-form-field { + background-color:#fff; + background-image:url(images/default/form/text-bg.gif); + border-color:#b5b8c8; +} + +.x-form-select-one { + background-color:#fff; + border-color:#b5b8c8; +} + +.x-form-check-group-label { + border-bottom: 1px solid #99bbe8; + color: #15428b; +} + +.x-editor .x-form-check-wrap { + background-color:#fff; +} + +.x-form-field-wrap .x-form-trigger { + background-image:url(images/default/form/trigger.gif); + border-bottom-color:#b5b8c8; +} + +.x-form-field-wrap .x-form-date-trigger { + background-image: url(images/default/form/date-trigger.gif); +} + +.x-form-field-wrap .x-form-clear-trigger { + background-image: url(images/default/form/clear-trigger.gif); +} + +.x-form-field-wrap .x-form-search-trigger { + background-image: url(images/default/form/search-trigger.gif); +} + +.x-trigger-wrap-focus .x-form-trigger { + border-bottom-color:#7eadd9; +} + +.x-item-disabled .x-form-trigger-over { + border-bottom-color:#b5b8c8; +} + +.x-item-disabled .x-form-trigger-click { + border-bottom-color:#b5b8c8; +} + +.x-form-focus, textarea.x-form-focus { + border-color:#7eadd9; +} + +.x-form-invalid, textarea.x-form-invalid { + background-color:#fff; + background-image:url(images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.x-form-invalid.x-form-composite { + border: none; + background-image: none; +} + +.x-form-invalid.x-form-composite .x-form-invalid { + background-color:#fff; + background-image:url(images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid { + background-color:#fff; + background-image:url(images/default/grid/invalid_line.gif); +} + +.x-form-grow-sizer { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-item { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-invalid-msg { + color:#c0272b; + font:normal 11px tahoma, arial, helvetica, sans-serif; + background-image:url(images/default/shared/warning.gif); +} + +.x-form-empty-field { + color:gray; +} + +.x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-webkit .x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-form-invalid-icon { + background-image:url(images/default/form/exclamation.gif); +} + +.x-fieldset { + border-color:#b5b8c8; +} + +.x-fieldset legend { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#15428b; +} +.x-btn{ + font:normal 11px tahoma, verdana, helvetica; +} + +.x-btn button{ + font:normal 11px arial,tahoma,verdana,helvetica; + color:#333; +} + +.x-btn em { + font-style:normal; + font-weight:normal; +} + +.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{ + background-image:url(images/default/button/btn.gif); +} + +.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{ + color:#000; +} + +.x-btn-disabled *{ + color:gray !important; +} + +.x-btn-mc em.x-btn-arrow { + background-image:url(images/default/button/arrow.gif); +} + +.x-btn-mc em.x-btn-split { + background-image:url(images/default/button/s-arrow.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split { + background-image:url(images/default/button/s-arrow-o.gif); +} + +.x-btn-mc em.x-btn-arrow-bottom { + background-image:url(images/default/button/s-arrow-b-noline.gif); +} + +.x-btn-mc em.x-btn-split-bottom { + background-image:url(images/default/button/s-arrow-b.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom { + background-image:url(images/default/button/s-arrow-bo.gif); +} + +.x-btn-group-header { + color: #3e6aaa; +} + +.x-btn-group-tc { + background-image: url(images/default/button/group-tb.gif); +} + +.x-btn-group-tl { + background-image: url(images/default/button/group-cs.gif); +} + +.x-btn-group-tr { + background-image: url(images/default/button/group-cs.gif); +} + +.x-btn-group-bc { + background-image: url(images/default/button/group-tb.gif); +} + +.x-btn-group-bl { + background-image: url(images/default/button/group-cs.gif); +} + +.x-btn-group-br { + background-image: url(images/default/button/group-cs.gif); +} + +.x-btn-group-ml { + background-image: url(images/default/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(images/default/button/group-lr.gif); +} + +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(images/default/button/group-tb.gif); +}.x-toolbar{ + border-color:#a9bfd3; + background-color:#d0def0; + background-image:url(images/default/toolbar/bg.gif); +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} + +.x-toolbar .x-item-disabled { + color:gray; +} + +.x-toolbar .x-item-disabled * { + color:gray; +} + +.x-toolbar .x-btn-mc em.x-btn-split { + background-image:url(images/default/button/s-arrow-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split +{ + background-image:url(images/default/button/s-arrow-o.gif); +} + +.x-toolbar .x-btn-mc em.x-btn-split-bottom { + background-image:url(images/default/button/s-arrow-b-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom +{ + background-image:url(images/default/button/s-arrow-bo.gif); +} + +.x-toolbar .xtb-sep { + background-image: url(images/default/grid/grid-blue-split.gif); +} + +.x-tbar-page-first{ + background-image: url(images/default/grid/page-first.gif) !important; +} + +.x-tbar-loading{ + background-image: url(images/default/grid/refresh.gif) !important; +} + +.x-tbar-page-last{ + background-image: url(images/default/grid/page-last.gif) !important; +} + +.x-tbar-page-next{ + background-image: url(images/default/grid/page-next.gif) !important; +} + +.x-tbar-page-prev{ + background-image: url(images/default/grid/page-prev.gif) !important; +} + +.x-item-disabled .x-tbar-loading{ + background-image: url(images/default/grid/loading.gif) !important; +} + +.x-item-disabled .x-tbar-page-first{ + background-image: url(images/default/grid/page-first-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-last{ + background-image: url(images/default/grid/page-last-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-next{ + background-image: url(images/default/grid/page-next-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-prev{ + background-image: url(images/default/grid/page-prev-disabled.gif) !important; +} + +.x-paging-info { + color:#444; +} + +.x-toolbar-more-icon { + background-image: url(images/default/toolbar/more.gif) !important; +}.x-resizable-handle { + background-color:#fff; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-image:url(images/default/sizer/e-handle.gif); +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-image:url(images/default/sizer/s-handle.gif); +} + +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{ + background-image:url(images/default/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-image:url(images/default/sizer/se-handle.gif); +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-image:url(images/default/sizer/nw-handle.gif); +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-image:url(images/default/sizer/ne-handle.gif); +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-image:url(images/default/sizer/sw-handle.gif); +} +.x-resizable-proxy{ + border-color:#3b5a82; +} +.x-resizable-overlay{ + background-color:#fff; +} +.x-grid3 { + background-color:#fff; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border-color:#99bbe8; +} + +.x-grid3-row td, .x-grid3-summary-row td{ + font:normal 11px/13px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row td { + font:normal 11px/15px arial, tahoma, helvetica, sans-serif; +} + + +.x-grid3-hd-row td { + border-left-color:#eee; + border-right-color:#d0d0d0; +} + +.x-grid-row-loading { + background-color: #fff; + background-image:url(images/default/shared/loading-balls.gif); +} + +.x-grid3-row { + border-color:#ededed; + border-top-color:#fff; +} + +.x-grid3-row-alt{ + background-color:#fafafa; +} + +.x-grid3-row-over { + border-color:#ddd; + background-color:#efefef; + background-image:url(images/default/grid/row-over.gif); +} + +.x-grid3-resize-proxy { + background-color:#777; +} + +.x-grid3-resize-marker { + background-color:#777; +} + +.x-grid3-header{ + background-color:#f9f9f9; + background-image:url(images/default/grid/grid3-hrow.gif); +} + +.x-grid3-header-pop { + border-left-color:#d0d0d0; +} + +.x-grid3-header-pop-inner { + border-left-color:#eee; + background-image:url(images/default/grid/hd-pop.gif); +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left-color:#aaccf6; + border-right-color:#aaccf6; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background-color:#ebf3fd; + background-image:url(images/default/grid/grid3-hrow-over.gif); + +} + +.sort-asc .x-grid3-sort-icon { + background-image: url(images/default/grid/sort_asc.gif); +} + +.sort-desc .x-grid3-sort-icon { + background-image: url(images/default/grid/sort_desc.gif); +} + +.x-grid3-cell-text, .x-grid3-hd-text { + color:#000; +} + +.x-grid3-split { + background-image: url(images/default/grid/grid-split.gif); +} + +.x-grid3-hd-text { + color:#15428b; +} + +.x-dd-drag-proxy .x-grid3-hd-inner{ + background-color:#ebf3fd; + background-image:url(images/default/grid/grid3-hrow-over.gif); + border-color:#aaccf6; +} + +.col-move-top{ + background-image:url(images/default/grid/col-move-top.gif); +} + +.col-move-bottom{ + background-image:url(images/default/grid/col-move-bottom.gif); +} + +.x-grid3-row-selected { + background-color: #dfe8f6 !important; + background-image: none; + border-color:#a3bae9; +} + +.x-grid3-cell-selected{ + background-color: #b8cfee !important; + color:#000; +} + +.x-grid3-cell-selected span{ + color:#000 !important; +} + +.x-grid3-cell-selected .x-grid3-cell-text{ + color:#000; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background-color:#ebeadb !important; + background-image:url(images/default/grid/grid-hrow.gif) !important; + color:#000; + border-top-color:#fff; + border-right-color:#6fa0df !important; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + color:#15428b !important; +} + +.x-grid3-dirty-cell { + background-image:url(images/default/grid/dirty.gif); +} + +.x-grid3-topbar, .x-grid3-bottombar{ + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-bottombar .x-toolbar{ + border-top-color:#a9bfd3; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background-image:url(images/default/grid/grid3-special-col-bg.gif) !important; + color:#000 !important; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + background-color:#fff !important; + border-right-color:#eee; +} + +.xg-hmenu-sort-asc .x-menu-item-icon{ + background-image: url(images/default/grid/hmenu-asc.gif); +} + +.xg-hmenu-sort-desc .x-menu-item-icon{ + background-image: url(images/default/grid/hmenu-desc.gif); +} + +.xg-hmenu-lock .x-menu-item-icon{ + background-image: url(images/default/grid/hmenu-lock.gif); +} + +.xg-hmenu-unlock .x-menu-item-icon{ + background-image: url(images/default/grid/hmenu-unlock.gif); +} + +.x-grid3-hd-btn { + background-color:#c3daf9; + background-image:url(images/default/grid/grid3-hd-btn.gif); +} + +.x-grid3-body .x-grid3-td-expander { + background-image:url(images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-expander { + background-image:url(images/default/grid/row-expand-sprite.gif); +} + +.x-grid3-body .x-grid3-td-checker { + background-image: url(images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + background-image:url(images/default/grid/row-check-sprite.gif); +} + +.x-grid3-body .x-grid3-td-numberer { + background-image:url(images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + color:#444; +} + +.x-grid3-body .x-grid3-td-row-icon { + background-image:url(images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background-image:url(images/default/grid/grid3-special-col-sel-bg.gif); +} + +.x-grid3-check-col { + background-image:url(images/default/menu/unchecked.gif); +} + +.x-grid3-check-col-on { + background-image:url(images/default/menu/checked.gif); +} + +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom-color:#99bbe8; +} + +.x-grid-group-hd div.x-grid-group-title { + background-image:url(images/default/grid/group-collapse.gif); + color:#3764a0; + font:bold 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title { + background-image:url(images/default/grid/group-expand.gif); +} + +.x-group-by-icon { + background-image:url(images/default/grid/group-by.gif); +} + +.x-cols-icon { + background-image:url(images/default/grid/columns.gif); +} + +.x-show-groups-icon { + background-image:url(images/default/grid/group-by.gif); +} + +.x-grid-empty { + color:gray; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + border-right-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row-selected { + border-top-color:#a3bae9; +}.x-dd-drag-ghost{ + color:#000; + font: normal 11px arial, helvetica, sans-serif; + border-color: #ddd #bbb #bbb #ddd; + background-color:#fff; +} + +.x-dd-drop-nodrop .x-dd-drop-icon{ + background-image: url(images/default/dd/drop-no.gif); +} + +.x-dd-drop-ok .x-dd-drop-icon{ + background-image: url(images/default/dd/drop-yes.gif); +} + +.x-dd-drop-ok-add .x-dd-drop-icon{ + background-image: url(images/default/dd/drop-add.gif); +} + +.x-view-selector { + background-color:#c3daf9; + border-color:#3399bb; +}.x-tree-node-expanded .x-tree-node-icon{ + background-image:url(images/default/tree/folder-open.gif); +} + +.x-tree-node-leaf .x-tree-node-icon{ + background-image:url(images/default/tree/leaf.gif); +} + +.x-tree-node-collapsed .x-tree-node-icon{ + background-image:url(images/default/tree/folder.gif); +} + +.x-tree-node-loading .x-tree-node-icon{ + background-image:url(images/default/tree/loading.gif) !important; +} + +.x-tree-node .x-tree-node-inline-icon { + background-image: none; +} + +.x-tree-node-loading a span{ + font-style: italic; + color:#444444; +} + +.x-tree-lines .x-tree-elbow{ + background-image:url(images/default/tree/elbow.gif); +} + +.x-tree-lines .x-tree-elbow-plus{ + background-image:url(images/default/tree/elbow-plus.gif); +} + +.x-tree-lines .x-tree-elbow-minus{ + background-image:url(images/default/tree/elbow-minus.gif); +} + +.x-tree-lines .x-tree-elbow-end{ + background-image:url(images/default/tree/elbow-end.gif); +} + +.x-tree-lines .x-tree-elbow-end-plus{ + background-image:url(images/default/tree/elbow-end-plus.gif); +} + +.x-tree-lines .x-tree-elbow-end-minus{ + background-image:url(images/default/tree/elbow-end-minus.gif); +} + +.x-tree-lines .x-tree-elbow-line{ + background-image:url(images/default/tree/elbow-line.gif); +} + +.x-tree-no-lines .x-tree-elbow-plus{ + background-image:url(images/default/tree/elbow-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-minus{ + background-image:url(images/default/tree/elbow-minus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-plus{ + background-image:url(images/default/tree/elbow-end-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-minus{ + background-image:url(images/default/tree/elbow-end-minus-nl.gif); +} + +.x-tree-arrows .x-tree-elbow-plus{ + background-image:url(images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-minus{ + background-image:url(images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background-image:url(images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background-image:url(images/default/tree/arrows.gif); +} + +.x-tree-node{ + color:#000; + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + color:#000; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + color:#000; +} + +.x-tree-node .x-tree-node-disabled a span{ + color:gray !important; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom-color:#36c; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top-color:#36c; +} + +.x-tree-node .x-tree-drag-append a span{ + background-color:#ddd; + border-color:gray; +} + +.x-tree-node .x-tree-node-over { + background-color: #eee; +} + +.x-tree-node .x-tree-selected { + background-color: #d9e8fb; +} + +.x-tree-drop-ok-append .x-dd-drop-icon{ + background-image: url(images/default/tree/drop-add.gif); +} + +.x-tree-drop-ok-above .x-dd-drop-icon{ + background-image: url(images/default/tree/drop-over.gif); +} + +.x-tree-drop-ok-below .x-dd-drop-icon{ + background-image: url(images/default/tree/drop-under.gif); +} + +.x-tree-drop-ok-between .x-dd-drop-icon{ + background-image: url(images/default/tree/drop-between.gif); +}.x-date-picker { + border-color: #1b376c; + background-color:#fff; +} + +.x-date-middle,.x-date-left,.x-date-right { + background-image: url(images/default/shared/hd-sprite.gif); + color:#fff; + font:bold 11px "sans serif", tahoma, verdana, helvetica; +} + +.x-date-middle .x-btn .x-btn-text { + color:#fff; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background-image:url(images/default/toolbar/btn-arrow-light.gif); +} + +.x-date-right a { + background-image: url(images/default/shared/right-btn.gif); +} + +.x-date-left a{ + background-image: url(images/default/shared/left-btn.gif); +} + +.x-date-inner th { + background-color:#dfecfb; + background-image:url(images/default/shared/glass-bg.gif); + border-bottom-color:#a3bad9; + font:normal 10px arial, helvetica,tahoma,sans-serif; + color:#233d6d; +} + +.x-date-inner td { + border-color:#fff; +} + +.x-date-inner a { + font:normal 11px arial, helvetica,tahoma,sans-serif; + color:#000; +} + +.x-date-inner .x-date-active{ + color:#000; +} + +.x-date-inner .x-date-selected a{ + background-color:#dfecfb; + background-image:url(images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} + +.x-date-inner .x-date-today a{ + border-color:darkred; +} + +.x-date-inner .x-date-selected span{ + font-weight:bold; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + color:#aaa; +} + +.x-date-bottom { + border-top-color:#a3bad9; + background-color:#dfecfb; + background-image:url(images/default/shared/glass-bg.gif); +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + color:#000; + background-color:#ddecfe; +} + +.x-date-inner .x-date-disabled a { + background-color:#eee; + color:#bbb; +} + +.x-date-mmenu{ + background-color:#eee !important; +} + +.x-date-mmenu .x-menu-item { + font-size:10px; + color:#000; +} + +.x-date-mp { + background-color:#fff; +} + +.x-date-mp td { + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns button { + background-color:#083772; + color:#fff; + border-color: #3366cc #000055 #000055 #3366cc; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns { + background-color: #dfecfb; + background-image: url(images/default/shared/glass-bg.gif); +} + +.x-date-mp-btns td { + border-top-color: #c5d2df; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + color:#15428b; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + color:#15428b; + background-color: #ddecfe; +} + +td.x-date-mp-sel a { + background-color: #dfecfb; + background-image: url(images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} + +.x-date-mp-ybtn a { + background-image:url(images/default/panel/tool-sprites.gif); +} + +td.x-date-mp-sep { + border-right-color:#c5d2df; +}.x-tip .x-tip-close{ + background-image: url(images/default/qtip/close.gif); +} + +.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr { + background-image: url(images/default/qtip/tip-sprite.gif); +} + +.x-tip .x-tip-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; +} +.x-tip .x-tip-ml { + background-color: #fff; +} + +.x-tip .x-tip-header-text { + font: bold 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-tip .x-tip-body { + font: normal 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc, +.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr +{ + background-image: url(images/default/form/error-tip-corners.gif); +} + +.x-form-invalid-tip .x-tip-body { + background-image:url(images/default/form/exclamation.gif); +} + +.x-tip-anchor { + background-image:url(images/default/qtip/tip-anchor-sprite.gif); +}.x-menu { + background-color:#f0f0f0; + background-image:url(images/default/menu/menu.gif); +} + +.x-menu-floating{ + border-color:#718bb7; +} + +.x-menu-nosep { + background-image:none; +} + +.x-menu-list-item{ + font:normal 11px arial,tahoma,sans-serif; +} + +.x-menu-item-arrow{ + background-image:url(images/default/menu/menu-parent.gif); +} + +.x-menu-sep { + background-color:#e0e0e0; + border-bottom-color:#fff; +} + +a.x-menu-item { + color:#222; +} + +.x-menu-item-active { + background-image: url(images/default/menu/item-over.gif); + background-color: #dbecf4; + border-color:#aaccf6; +} + +.x-menu-item-active a.x-menu-item { + border-color:#aaccf6; +} + +.x-menu-check-item .x-menu-item-icon{ + background-image:url(images/default/menu/unchecked.gif); +} + +.x-menu-item-checked .x-menu-item-icon{ + background-image:url(images/default/menu/checked.gif); +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background-image:url(images/default/menu/group-checked.gif); +} + +.x-menu-group-item .x-menu-item-icon{ + background-image:none; +} + +.x-menu-plain { + background-color:#f0f0f0 !important; + background-image: none; +} + +.x-date-menu, .x-color-menu{ + background-color: #fff !important; +} + +.x-menu .x-date-picker{ + border-color:#a3bad9; +} + +.x-cycle-menu .x-menu-item-checked { + border-color:#a3bae9 !important; + background-color:#def8f6; +} + +.x-menu-scroller-top { + background-image:url(images/default/layout/mini-top.gif); +} + +.x-menu-scroller-bottom { + background-image:url(images/default/layout/mini-bottom.gif); +} +.x-box-tl { + background-image: url(images/default/box/corners.gif); +} + +.x-box-tc { + background-image: url(images/default/box/tb.gif); +} + +.x-box-tr { + background-image: url(images/default/box/corners.gif); +} + +.x-box-ml { + background-image: url(images/default/box/l.gif); +} + +.x-box-mc { + background-color: #eee; + background-image: url(images/default/box/tb.gif); + font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif; + color: #393939; + font-size: 12px; +} + +.x-box-mc h3 { + font-size: 14px; + font-weight: bold; +} + +.x-box-mr { + background-image: url(images/default/box/r.gif); +} + +.x-box-bl { + background-image: url(images/default/box/corners.gif); +} + +.x-box-bc { + background-image: url(images/default/box/tb.gif); +} + +.x-box-br { + background-image: url(images/default/box/corners.gif); +} + +.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr { + background-image: url(images/default/box/corners-blue.gif); +} + +.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc { + background-image: url(images/default/box/tb-blue.gif); +} + +.x-box-blue .x-box-mc { + background-color: #c3daf9; +} + +.x-box-blue .x-box-mc h3 { + color: #17385b; +} + +.x-box-blue .x-box-ml { + background-image: url(images/default/box/l-blue.gif); +} + +.x-box-blue .x-box-mr { + background-image: url(images/default/box/r-blue.gif); +}.x-combo-list { + border-color:#98c0f4; + background-color:#ddecfe; + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-combo-list-inner { + background-color:#fff; +} + +.x-combo-list-hd { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#15428b; + background-image: url(images/default/layout/panel-title-light-bg.gif); + border-bottom-color:#98c0f4; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom-color:#98c0f4; +} + +.x-combo-list-item { + border-color:#fff; +} + +.x-combo-list .x-combo-selected{ + border-color:#a3bae9 !important; + background-color:#dfe8f6; +} + +.x-combo-list .x-toolbar { + border-top-color:#98c0f4; +} + +.x-combo-list-small { + font:normal 11px tahoma, arial, helvetica, sans-serif; +}.x-panel { + border-color: #99bbe8; +} + +.x-panel-header { + color:#15428b; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; + border-color:#99bbe8; + background-image: url(images/default/panel/white-top-bottom.gif); +} + +.x-panel-body { + border-color:#99bbe8; + background-color:#fff; +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border-color:#99bbe8; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top-color:#99bbe8; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top-color:#99bbe8; +} + +.x-panel-tl .x-panel-header { + color:#15428b; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-panel-tc { + background-image: url(images/default/panel/top-bottom.gif); +} + +.x-panel-tl, .x-panel-tr, .x-panel-bl, .x-panel-br{ + background-image: url(images/default/panel/corners-sprite.gif); + border-bottom-color:#99bbe8; +} + +.x-panel-bc { + background-image: url(images/default/panel/top-bottom.gif); +} + +.x-panel-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} + +.x-panel-ml { + background-color: #fff; + background-image:url(images/default/panel/left-right.gif); +} + +.x-panel-mr { + background-image: url(images/default/panel/left-right.gif); +} + +.x-tool { + background-image:url(images/default/panel/tool-sprites.gif); +} + +.x-panel-ghost { + background-color:#cbddf3; +} + +.x-panel-ghost ul { + border-color:#99bbe8; +} + +.x-panel-dd-spacer { + border-color:#99bbe8; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} +.x-window-proxy { + background-color:#c7dffc; + border-color:#99bbe8; +} + +.x-window-tl .x-window-header { + color:#15428b; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-window-tc { + background-image: url(images/default/window/top-bottom.png); +} + +.x-window-tl { + background-image: url(images/default/window/left-corners.png); +} + +.x-window-tr { + background-image: url(images/default/window/right-corners.png); +} + +.x-window-bc { + background-image: url(images/default/window/top-bottom.png); +} + +.x-window-bl { + background-image: url(images/default/window/left-corners.png); +} + +.x-window-br { + background-image: url(images/default/window/right-corners.png); +} + +.x-window-mc { + border-color:#99bbe8; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} + +.x-window-ml { + background-image: url(images/default/window/left-right.png); +} + +.x-window-mr { + background-image: url(images/default/window/left-right.png); +} + +.x-window-maximized .x-window-tc { + background-color:#fff; +} + +.x-window-bbar .x-toolbar { + border-top-color:#99bbe8; +} + +.x-panel-ghost .x-window-tl { + border-bottom-color:#99bbe8; +} + +.x-panel-collapsed .x-window-tl { + border-bottom-color:#84a0c4; +} + +.x-dlg-mask{ + background-color:#ccc; +} + +.x-window-plain .x-window-mc { + background-color: #ccd9e8; + border-color: #a3bae9 #dfe8f6 #dfe8f6 #a3bae9; +} + +.x-window-plain .x-window-body { + border-color: #dfe8f6 #a3bae9 #a3bae9 #dfe8f6; +} + +body.x-body-masked .x-window-plain .x-window-mc { + background-color: #ccd9e8; +}.x-html-editor-wrap { + border-color:#a9bfd3; + background-color:#fff; +} +.x-html-editor-tb .x-btn-text { + background-image:url(images/default/editor/tb-sprite.gif); +}.x-panel-noborder .x-panel-header-noborder { + border-bottom-color:#99bbe8; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +}.x-border-layout-ct { + background-color:#dfe8f6; +} + +.x-accordion-hd { + color:#222; + font-weight:normal; + background-image: url(images/default/panel/light-hd.gif); +} + +.x-layout-collapsed{ + background-color:#d2e0f2; + border-color:#98c0f4; +} + +.x-layout-collapsed-over{ + background-color:#d9e8fb; +} + +.x-layout-split-west .x-layout-mini { + background-image:url(images/default/layout/mini-left.gif); +} +.x-layout-split-east .x-layout-mini { + background-image:url(images/default/layout/mini-right.gif); +} +.x-layout-split-north .x-layout-mini { + background-image:url(images/default/layout/mini-top.gif); +} +.x-layout-split-south .x-layout-mini { + background-image:url(images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-west .x-layout-mini { + background-image:url(images/default/layout/mini-right.gif); +} + +.x-layout-cmini-east .x-layout-mini { + background-image:url(images/default/layout/mini-left.gif); +} + +.x-layout-cmini-north .x-layout-mini { + background-image:url(images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-south .x-layout-mini { + background-image:url(images/default/layout/mini-top.gif); +}.x-progress-wrap { + border-color:#6593cf; +} + +.x-progress-inner { + background-color:#e0e8f3; + background-image:url(images/default/qtip/bg.gif); +} + +.x-progress-bar { + background-color:#9cbfee; + background-image:url(images/default/progress/progress-bg.gif); + border-top-color:#d1e4fd; + border-bottom-color:#7fa9e4; + border-right-color:#7fa9e4; +} + +.x-progress-text { + font-size:11px; + font-weight:bold; + color:#fff; +} + +.x-progress-text-back { + color:#396095; +}.x-list-header{ + background-color:#f9f9f9; + background-image:url(images/default/grid/grid3-hrow.gif); +} + +.x-list-header-inner div em { + border-left-color:#ddd; + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-body dt em { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-over { + background-color:#eee; +} + +.x-list-selected { + background-color:#dfe8f6; +} + +.x-list-resizer { + border-left-color:#555; + border-right-color:#555; +} + +.x-list-header-inner em.sort-asc, .x-list-header-inner em.sort-desc { + background-image:url(images/default/grid/sort-hd.gif); + border-color: #99bbe8; +}.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner { + background-image:url(images/default/slider/slider-bg.png); +} + +.x-slider-horz .x-slider-thumb { + background-image:url(images/default/slider/slider-thumb.png); +} + +.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner { + background-image:url(images/default/slider/slider-v-bg.png); +} + +.x-slider-vert .x-slider-thumb { + background-image:url(images/default/slider/slider-v-thumb.png); +}.x-window-dlg .ext-mb-text, +.x-window-dlg .x-window-header-text { + font-size:12px; +} + +.x-window-dlg .ext-mb-textarea { + font:normal 12px tahoma,arial,helvetica,sans-serif; +} + +.x-window-dlg .x-msg-box-wait { + background-image:url(images/default/grid/loading.gif); +} + +.x-window-dlg .ext-mb-info { + background-image:url(images/default/window/icon-info.gif); +} + +.x-window-dlg .ext-mb-warning { + background-image:url(images/default/window/icon-warning.gif); +} + +.x-window-dlg .ext-mb-question { + background-image:url(images/default/window/icon-question.gif); +} + +.x-window-dlg .ext-mb-error { + background-image:url(images/default/window/icon-error.gif); +} \ No newline at end of file diff --git a/workflow/public_html/skins/ext/images/default/box/corners-blue.gif b/workflow/public_html/skins/ext/images/default/box/corners-blue.gif new file mode 100755 index 0000000000000000000000000000000000000000..fa419b50abe5030db04492578d5dfd39c02fb6ab GIT binary patch literal 1010 zcmZ?wbhEHbXlGzpbnMH9^WV;$J9qKo#mkp3U%h(u+O=ypZrr$e^X8p9ckbT3 zd+*-8gExOZc<|ui!-tO^J$n53@slS{o<4p0?Af#D&!4}1`SR7PSFc~ce)Hzd+qZAu zy?gim{reZ6{(SiG;p4}TpFVy1{Q2{jFJHcX{rc_Ox9{J-|M>Ca=g*(NfB*jT=g;52 zfB*ga_y7NYhEYJJ5ODbKKqZq#iZO~mS(q6ZW-;i1JPgVc3>@bfOgUvd3KTeaMcKM` zTmT9+Dym5^6eP5&35jyCL~LwoUdG4CQ1IlzMJEOhS7<|o6TkONJB|cJt&_qGY8j_CFdSfKOOVXz5IAt4 zV}p{G0>c6amIz;I6#<3?kJdQw@UbxnC^#-)=MmtuQ0WM8YMvo$(vtdt@jw$#qNfCh wKq7O5AQyweiU(yaTnsEKITutM85$V*3^XlGzJaNxkCA+uU@@+{rdHrH*em)ef#d+yZ7(kfB5j>g)|NZ;-|Nno6kqR9CJB(DX)7#&QKUtU= zfEhstWHBgDFmRk=;OCU_C{XAUlw(`PkjU7?)Tn7;VYmK z&r@KbvglBQu=1upg@udrDMSY z2FDg@ogF$0Oia(gUJntM;F*w7{y{XRIF%d;*fMw Ru}w*2KC@pnhK+^68UTSX)nNbt literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/box/l-blue.gif b/workflow/public_html/skins/ext/images/default/box/l-blue.gif new file mode 100755 index 0000000000000000000000000000000000000000..5ed7f0043b6b0f956076e02583ca7d18a150e8f6 GIT binary patch literal 810 zcmZ?wbhEHbWMN=rXlGzpbnMHWJ9pl^dGqhzKZa2-8UiCM1QdU=0Db(QK?me-P@Z7m PU}s=uVK7ioV6X-NGaC=| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/box/l.gif b/workflow/public_html/skins/ext/images/default/box/l.gif new file mode 100755 index 0000000000000000000000000000000000000000..0160f97fe75409f17ab6c3c91f7cbdc58afa8f8f GIT binary patch literal 810 zcmZ?wbhEHbWMN=rXlGzJc<|tzJ9pl^dGqhzKZa2-8UiCM1QdU=0Db(QK?me-P@Z7m PU}s=uVK7ioV6X-N<)RPU literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/box/r-blue.gif b/workflow/public_html/skins/ext/images/default/box/r-blue.gif new file mode 100755 index 0000000000000000000000000000000000000000..3ea5cae3b7b571ec41ac2b5d38c8a675a1f66efc GIT binary patch literal 810 zcmZ?wbhEHbWMN=rXlGzpbnMHWJ9pl^dGr7Oe}+*o8UiCM1QdU=0Db(QK?me-P@Z7m PU}s=w;80LdV6X-NJSY$C literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/box/r.gif b/workflow/public_html/skins/ext/images/default/box/r.gif new file mode 100755 index 0000000000000000000000000000000000000000..34237f6292a7da6ac5d1b95d13ce76a7194dd596 GIT binary patch literal 810 zcmZ?wbhEHbWMN=rXlGzJc<|tzJ9pl^dGr7Oe}+*o8UiCM1QdU=0Db(QK?me-P@Z7m PU}s=w;80LdV6X-N?ynEj literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/box/tb-blue.gif b/workflow/public_html/skins/ext/images/default/box/tb-blue.gif new file mode 100755 index 0000000000000000000000000000000000000000..562fecca87176274af7bf13c419daaf93f169249 GIT binary patch literal 851 zcmZ?wbhEHbWMt4{XlGzpbnMHL<6oAa{JQeg*VSjft~>i}!})KUE_~a1@%#46-*;X4 zvFF;4eb;~7zJ2@P&7Vha|2%Q`=a~n;&OiEf>B+Ba&wkx{`TPEx-%p-AdGqGY@@87@w|Nk?Lg3%Bd$|0cmlLhGf{|q`H xPk{0S1BVKOBoBu|W0NBntB_a%g98I2m#~UU!-oTo%xv5uDh>q)92y%KtN|VsNKya* literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/arrow.gif b/workflow/public_html/skins/ext/images/default/button/arrow.gif new file mode 100755 index 0000000000000000000000000000000000000000..3ab4f71ac115188898fa2701b6b11561d0461e4d GIT binary patch literal 828 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/btn2.gif b/workflow/public_html/skins/ext/images/default/button/btn2.gif new file mode 100755 index 0000000000000000000000000000000000000000..bf1f6dd9315ada12fc71cc6e8ec16e6ace8d161b GIT binary patch literal 8783 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/group-cs.gif b/workflow/public_html/skins/ext/images/default/button/group-cs.gif new file mode 100755 index 0000000000000000000000000000000000000000..3d1dca8f05ca550917346830a5a0ae4e16665181 GIT binary patch literal 2459 zcmeH`i9ZvH1HdQ!yk5P2p?H)dxpp{mJU@!;=?=U!!Pkq*zsjUC!6Bk-dSFVOt_!mB{_I3VoryMO9y{@Ma z=-n9DL$B{GJqcGoa`AW@KtUEXYxS9y%>dB{M#Mz_E@4eP*_kWX z^$4C>m(33o-~&JGx7SyMz30WrFL$>$RxxA>k0+M{zIVY>_Ns?Yre=MWTI_qhMP6lu~OPcC3oegZjRc3=(^V7L)w0*({)+2G{4{T;} z!o0jGzAzuE1S`!ys~+~X;Ic~gSFD>2s0i!s44Nr2{v9?`?2ia5C=Ng`%#;QugJvIl zX2534LY2Z0<&i8qVL7rJG?#U&KWwg2Z6tfHDp4JGvpPj7exmxGdU$C3eVxYnn$L!U z`PxTjbD?!bexlEHC5Xm_h{s6L!t<)w{UTi5CucPzxwui(_yinUcAMBO2QMa*XVGKC z=GlNC5?&-)q})%Ygw02%fDp? zVNB8KSM#G-X(81lbZQu7nT3hsnXV^A4@CVZF?NFV-}t){`7%2$Np8AIR-7-nvHOnQ^Yr z29ODG<^*{=utg%~TyB+{CHl7?LfQY-rAyiI?J<{dz1}#QCwUHfpd2o~hf|W=KB6QJ zu45SUAF!!>)JvC{YD)6?1&ZX1^D@s|{)cn`#dBJlpkU5!N_ZIg4~{NC(Uzy6x{{=1 zKe?rfYg@ITrV0~|@8ub{|BR&EQ|Ia^S=qK8j9Iy>vok3>3+xaUQ15r1*4vMH-k~NY zr<-xLf4OeU(HvTdwc$>QVsM?qQfg-Hww|)w(fE}flAPtt)lx0AZ85ZzM!P3YPuBpu zIz4GQX`B=4@`f%`F)25gdrYI#mTiHRMj`BlpN4SV3>xj>^#pw_p3!SNBqur_%-}Fb({3Vq!raSJOb>jsf$Mg_Ll=3M}zGh0*jv{cQuF zqmjT9Ni1sMYJk1%XufpWRdV7?$2CxI+916|kz;5kukQ^K6G~rle?6IYiE>rdD!AJo z!NKDDVl5bDbMZ#j3K=C~N*BvVzNyC%m1wm(h9_K{;$IbDeX@-l!VY^kdI9N8_1=jfHxh8T3_)wKnK|Kp zd#kHb=JVjpZkT2o*vDFxiHooYdyV1V)pyhI?)CaUwehdL_6Z^()SB zh=d#_`1@P3XpBUY8&RN-J+pLr$&4YwYPAf?9 zNv=0?zgF??W86>)p4GbSeVcF@FJrNNcTI26z+a}2%;xSja7^K`kr~TUVtBW8#)oO;GY8+ecXL81wkhso@Q7N{RGV36L4-Fn0@B=bZS$i$`@>*e=Y6L&Ng dUQu}td}@Irs8Us{==-D1xS|KJM_Czg`hV^ynJEAO literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/group-lr.gif b/workflow/public_html/skins/ext/images/default/button/group-lr.gif new file mode 100755 index 0000000000000000000000000000000000000000..7c549f96d6064d4b0cc022671fd823c13df36d8c GIT binary patch literal 861 zcmZ?wbhEHbe8J4f(9Xcn@V{aEiR+JFe`Od2qaiTzLO}5+3p2>qIv@g+Cm1-a7??R2 z95yUC*vuiU6?0<4!o%$X%3gCkHZD5aEn%E>=fuXv$NLqWyJS2!Ejc+^BY0KJ$xTbW LTbP(wSQxAUYf&Xs literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/group-tb.gif b/workflow/public_html/skins/ext/images/default/button/group-tb.gif new file mode 100755 index 0000000000000000000000000000000000000000..adeb0a4cf54bdfb626ab6f3c070f6e2919f374c0 GIT binary patch literal 846 zcmZ?wbhEHbWMt4`Y-eC-_}{So#PvfrK0JQ?m0=W&hQJ650mYvz%pfo8fCx~YVBpYZ yVCE5U*s$PWGl#HNOoc$h;dTLKuQ?tY7ai@EFwVMjV&mfD{R+-`G6D(;4Aua=h#nIF literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow-b-noline.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow-b-noline.gif new file mode 100755 index 0000000000000000000000000000000000000000..a4220ee9066357ea2270a842ed244bbaadb23de4 GIT binary patch literal 898 zcmZ?wbhEHbJi)-n(9Qq?M~)mhbnDyy|Np_fQDQU%Mo=fuXv$NLqWyJS2!Ejc+^BY0KJ z$xTa7Pd7+DHOF)FGT%0aqGx+fZdP}nYuC)RmLp-s#l;?zwPH_gS$TPRz~V9<4hCxg D_B%R6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow-b.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow-b.gif new file mode 100755 index 0000000000000000000000000000000000000000..84b64703006ca6d86d335b89f8d40b9fa3883c48 GIT binary patch literal 937 zcmZ?wbhEHbJi)-n(9Qq?M~)mhbnDyy|Np_fQDQU%Mo)`~r~W##4N0gJundTm{G tbu}Af#?`K^tFNzT+TJAVU8dErDdY00*wfqA-ripD_|#nQ={XJz)&S^DQ3wD4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow-bo.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow-bo.gif new file mode 100755 index 0000000000000000000000000000000000000000..548700bf45a4766e4633a2ad21cdd03a907e191c GIT binary patch literal 139 zcmZ?wbhEHbJi)-nu#f=+R-O3x{>OhHL-8jIBNqcRgAPa(B=5i!GpB#$>9_og=WMyv zz4@M01z+1Ek7>_3m%Tc*Z6(9;Pd?Yb^*;Y~?)yJ}o<}i97JcmS(V9N7;WKBi*YYc? qzIL6>+J0x<_w3ZJ<4-pI?D3myle6{rUd98@zwG+kS1-=MU=08a%|q${ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow-noline.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow-noline.gif new file mode 100755 index 0000000000000000000000000000000000000000..0953eab5c875fcb0f3b40babd89052b064bf9fec GIT binary patch literal 863 zcmZ?wbhEHb*_y R+_d!cbc5tmb0h^AtO41(Cb0kj literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow-o.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow-o.gif new file mode 100755 index 0000000000000000000000000000000000000000..89c70f36fa653684087485ab673043ecbf615cdd GIT binary patch literal 937 zcmZ?wbhEHbO`C@~rWBPawEf3h$$FfcLbfcy-~6AT<} z46G~?3JVq-Y-VLwiqV*$aJZREUaCi9W8%>kKJB0>J3c15x5sMVlHA(yGnuN7&N42);+}s>}e3|KPvE1;j`8SW1{tiuYV6X-NOpiu@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/button/s-arrow.gif b/workflow/public_html/skins/ext/images/default/button/s-arrow.gif new file mode 100755 index 0000000000000000000000000000000000000000..8940774785c25d4467b239aa608a9eee40e273d1 GIT binary patch literal 937 zcmZ?wbhEHbkKJB0>J3c15x5sMVlHA(yGnuN7&N42);+}s>}e3|KPvE1;j`8SW1{tiuYV6X-Nh3iI; literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/dd/drop-add.gif b/workflow/public_html/skins/ext/images/default/dd/drop-add.gif new file mode 100755 index 0000000000000000000000000000000000000000..b22cd1448efa13c47ad6d3b75bdea8b4031c31e9 GIT binary patch literal 1001 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
    H6srOVndaq^Bq(PIE6uVpPZ!L!U z&MxCM^5;P#&N&1Ib6FFd^fC-I;fNECC-wQJQB$Y55=&#-aI=jzR~Z6HCZ3!}-7uFq zQ3xZFc*09C!SE7cXcJnbkwzSaWMfz;p`?<8F&5+_M+yZw(nCb5MA4Bk{aBEYK^95m zHBd$=Wt1{%B#%57)o9~7@tAX2j><#>OiI_V<f4Fm8jp3{iK`JFg0Earxg+)mYCQO1u3wt1= zNVcA`12DI}s#44gFvze2mgAjUOaw5CFb_G;k`zcSD5%iF4d?(9Nwy*b9B{9sc$0+; zGx&k!e>EE74G%D@0na%GhNXltMX=BU9^fEj3D6tz*Ak(p#8QkFT(r~8h8=2x%@07l z^UN|NhP4DDw-}MeIKJ%vk_*u6Y(w0cRl0K}jU9PpPCQ+LgrhFMIMd88Cvj>fs7eyV zq(V+UH09?|X0G|>3w7QQ=${vk(cxEZ+4$opg*m3>mlIl$7gBIw##L4H-n$r4U?57J zBz0iC@l}M70T_OkY0C4^hXRTz?AZRr^fEaKUKU0XJ51*)?MW`SK zGl&5d7??m8#=tu>fIQxXc$Y@BlAdKmu1l0~Q!KKT}XKhBEYm874ph3SgiWsMuYNz+eUi z7;*uvI7JD=LO}>XKmr#Cq!(OBMJhtCdKT$|C_vE1D*zG=SGj^HGGNFkB+?9*34s|r zAOQ(fVH9Wpg9|}%$4e5b3l#)G2v8vkQG6nlVmN>XG|&oKqTw=8xWX7d0D@7NVGIl8 r6!btbJzExzbr{joG#1ymk324NldBw{Y9~5_knSL+J00qz6c7MAhD0lK literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/clear-trigger.gif b/workflow/public_html/skins/ext/images/default/form/clear-trigger.gif new file mode 100755 index 0000000000000000000000000000000000000000..da78d45b3214480842c62514af524f4aebb66124 GIT binary patch literal 1988 zcmdth=~t5n8U^q-VGC;mBm0hsV8ubLEt_Ll8<8_(J7+8+GN29vjM%!ALxG`*vV;KaE8sA!@Y z4L3~1jhLAW4>!Ua947Tqg?%((Kh;b$Ko$&=1w*rGb*ec?N^AxVXqe@UN>0 z891^{u56v7+E|jCmSrZke1FwUW#X##SBxOn2(GSyLZMKlQmNHyjYgx@YWd;~fq0Ft z+7v0*1j;R;!o*jZMDlHsa!;f+iM1w)YEP=(muf+oW=p08<(hqkW|zMX3O7KpZcnTO zrMf+lxo?0HvrSO0Hz^EedrHHu(zqvI1C{Hb+PJIP0JWQ-Y#UT;feI6-)9Lhjy}@8G z8jZTOUH$s*&hGy1-ahdEdx6`Q=5Zi!^uxptKLNl%;1tXUNoYe@!v1h1gG9hjRlyIY zT+i)opRVyJ$m^OWcFfcd!goE+KKq624@2~*{(Gx41$X#rT_Vu?_+4{kc3!~LZ@o|e@KE%NaSqqM2CdnRrfg1wYE_n>MZsu=aYxhs@ zZYg1(SHAI5{)vrY3S>+Sr2G5!}cb)=Lak{l#IcWFsP=h z54sOE<$IwK0i|U>!mQGuh`69u9r$a%T`NxXx|!$| z=ac7y%X=&#XG<+_jk=4wnhTGFb+y-lKaBeiK%tbtM}APdfB|~CqPsh#af)y^(trRQ zEp@1acO7D$So@a(lTLRcQP%+{D$xQ)D?;t7^o`EZs~jG0R~!KcEY9V= zMfruL`9PuG*Qsdx+dj=Ii`&E0II=PwOPulj+Tj@q29JB~T2{m(hfi&|!E zBM$OTv98=N_;e}11gu55UTB%9W)-L))9jWO$gpd{tFfCL@43sLIsT;NS-D3u+AQ2N zWr!%TS6ADl-D$@0q>qlSMI`y2eiHE9u3$58=)j+XZx;IBIT;=;f85a*t?a9*L%6-} zN85P+E0<{PUGyX_R!^ME+)_z>Mape4XM92w`b7;YV!insg9^+qDfzUevNmaJNM0}502MlVmsU>iV}`Lr`6`Bb{t@C#l~>;SXe`ck9;fs%svkL zUAe$-+haTd`enn-;A=LHa#CU?4rl5R1@d8MkEOU&)s-HE(zl)`8NRsxz3AFuDKdp$ U;ezY9-WkTkP-6N%4gg~Q2Qp;nKmY&$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/clear-trigger.psd b/workflow/public_html/skins/ext/images/default/form/clear-trigger.psd new file mode 100755 index 0000000000000000000000000000000000000000..f637fa5d1e12460beabc8b49968ebc0ac883e754 GIT binary patch literal 11804 zcmds6349aP)}JgbA;Ocbf>0GuzzQfJ2%?B00)>YNvUCxIvIz*tj;%n8sK7&Q0D1CQ zltrLGX$urmTA(P<7APcb>E5(W(lkk%eQ6sqbH8&Z({?6l6~E8l?|bhhzmt2G|2b#w z%)MuF?;SDbgAWNF;rR%l=?1ij5D}P%Pn#Gda2|Dsn39*gv69|L?fuB$)^z-xcZ_{4X20k60XxFxV=MG&uck0loQ$W{epAL8` z@TpFnxc9s0xL3xsevqPF5EIuLxGK)@FY{NO49xe089u%ln6UW4E9?>u#0o8GIs42h8( z5j{U9=|;dbx%q`xBUW#1D}JhLx2L=J>D%wcpqGXYdu{lL*GIlP_PufACj?LYaQcjy zvqD0{<}X;dXz?dYmabX5ZvBRhpGSVV?W?c9*}h}v?mc^d*!RyL_y6nYvE#p-IC(1W z^!W=HlP_JCrd;{;x0|R9vZ4sjD>ATAkivwb>ocy7~qej}Ume z1HV4~f!ojH3xxt<8{8ire*=)9qtLI{VE<0
      o7Rp;JAVnkiWNRA}kX#4!D)64-8 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/date-trigger.psd b/workflow/public_html/skins/ext/images/default/form/date-trigger.psd new file mode 100755 index 0000000000000000000000000000000000000000..74883b21c54ba3552492162863caf022d51e43c1 GIT binary patch literal 12377 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 BA5{PV literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/exclamation.gif b/workflow/public_html/skins/ext/images/default/form/exclamation.gif new file mode 100755 index 0000000000000000000000000000000000000000..ea31a3060a36a625cb5cfdf4fdc5cb4fa5c3b239 GIT binary patch literal 996 zcmZ?wbhEHb6krfwXlGz>`0sGY+vu>b$x(l^!y&e3LT!$PJ06d9I~VJ7A=2?olFzvm zzpDxE7n6N1CI(zd3A#}bd9NVyZb9tbn*6)9`43}*9>oVgP7HaP6#6VR?0I_l!meOY(6|dTBUw78N>aBj$UH@iM{ilZ1FAYgw8_pbc0Z{x51oBkf&`s?Q9|Ns9pjDkTQ0*XIbm_d%z0TG})!N75lfssSTW5a@j z7VZsy6h0k$;Gk@@Yl-LKR#u*NrzJaX3aNBVGqZFP(Gfc8+b>uAY)8hyXKfvg1xYiW zY*bF=5>dbAA)s8qF(=rm< znzH#Wl@*DQugyk|h0s(J9u~z4MZR499ryhC^~?K*w-=e{wl~-nv>Egj1cL7gguBx% zT)Zq@NE=-Nt6g4JyGT~9fVo?Mjr%bh_W%^(#8yHO+#|w*$V3wYFrM_Cf1JV+84je7 z9ROpGU-)jyX(BU$6nbeLjSW4@*$~LtaEfn9=b%FPo5J`zLU_AExy0xc;4Ihg&$RuV zvJGs78Rz*%p2AAl3(x<8lzp}-|FX4l%|7EfIvgRBjB8tSQLP1VZWEF#ywdLj z>2hyD&Cz7(vFsX(us-NkLs+sfDkV2EMfeY2cqXqlT3nl0R8N;Z551!ZFX)PvHbvg; zPAF=Ql@G){8oW?FobYU%-aQi8(syOzQ{37bFFif|+O^~xchYiY*TsbylHyFUEVrOS zC@mHh+?B~>#g(;XRrU9uJgcg0tgWkKmA77d(0=`qGNYy=^WpQ%CrV+BN>bPLw6R6f z(sR2_!|q(n>iQ^DjS2e4MK5Qv`<8AFEsF-0Btwh&iZ>0-?TxLUQpLzh z&8rU$BjfVd`o|+*kbdR$!ncucOIodVe0*G|(@jlJ&&BTL3F4!sWQKrZSsrbm`jlswPRiNw~ox#)EssIi3K_U?mR$7V-IC9eE}g* z5#SHoR>a6~NhI<=Q;WTt%?}Qu9NUN;+@wtJJS0y=!z59V(h!KT_cmHu5NujLLCxE9 z_QU0%P-;FGb5tI6*gk|&C@tm`|9+v*B6nv=lO}$S+iOD$Mn~aW%lOvrmnW;VvcjwTy1x_M|Vx7g?UOR%A{vxR1=O9xx`_0#)mAz z#O%%n@__a?l=898*N7xDAiI1b<_~Z{nslUk?g_Dey!Eax#h5@k{{; z%`faJ5{8R)QaC;cQD8x5`VzNXi1Wqp3x`c^8P{6P{gaVWuFtYe7c(1?zIg}q~%W>VJ1sc%Av?5s&yuiMsG8Vvph~HOnJjUP7z}R9x z!{}s!KCBJ0F`$WM&Ver~;K&ocSHW(s6Mh)nO&1ErxjYUP9z|fJI2_q7U~QAux`?+R z3gs}A84lrf=7C(=X6VrsYzT(A2H$czA`b%`i`+&{!uU_X)(G<^EyNUO6=M{u;y53QM-q4Y5!fjNf2B$c3=RvJnhbNor$)h(^K&^hwf=q`1g%>cIxsnNp85qN`tNhU3jbmaN?09D@dd_WcK8kleih literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/search-trigger.gif b/workflow/public_html/skins/ext/images/default/form/search-trigger.gif new file mode 100755 index 0000000000000000000000000000000000000000..db8802beb370d7554d5319c0e0d5c4ecb8da2c5b GIT binary patch literal 2182 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 BV7LGP literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/text-bg.gif b/workflow/public_html/skins/ext/images/default/form/text-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..4179607cc1e9486dd6fcc8467c79b5b41dbf4f76 GIT binary patch literal 819 zcmZ?wbhEHbWMmLxXlG!!_xRa|&!0bk{rdI$_wPS{{`~#>&!4}4|NZ;_|3AYh7!85p p9s-I#S%6;r&!7YHC@4=ba0oCkvIrP7I50A^3uwfgFi>Ey1^^@>A+7)b literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/trigger-square.gif b/workflow/public_html/skins/ext/images/default/form/trigger-square.gif new file mode 100755 index 0000000000000000000000000000000000000000..3004ec589026c038e7d056e2b99e3a877d1ecd50 GIT binary patch literal 1810 zcmeH`=~I#k0Eb@@(r`m7uUt*s$}CGwv#`U(3p3rqV|JbGJ~p>wuw%A$t1UBIwalz( z+{&#$%ZT+L@5&Oi)(njo!2=aJUO-TkLqNb6-<{omV!!O~!}Il-d1iizNhCtlp<{qI zFbe>0K=r2)<>eaTOHke`M`}Tc$K&-w`Z;)h1NmlC>qos_ACXo(VMBP*8NSR=2g;eC zTse!>fe=?>)ai87)6-h5_EoP^AP~Uz`M$nBKA*3fwW+K~cv^AWkZNFHpqV2d92_)R z?LwiDBeg?jq*rY07MUBnWnJRA;o;%P^jikAjW3;mVK^eS*lI_(V=4h;GFfaNL{^bV zWP|59VCLdoYHQ)h*?r>{i-ixF%vSq=!rTU`t#k0} zUggI0TWvzs=P^~+(A0Wn8IQWMaOQ0fTZF_<#RVfdDJ| zU-P$Wo*?VVKr zv>QMX8JhcNpY6P}`bdd8lUmhVPVfpMuo|9opEw=-v~3MQ=RHRG1nv9Oc-)Z|m)zHr z)TI1eNurS+6-EBZuS;&Cc#vt;!iFD%gK}8SH6tyq?@1m&3uTYPa>Im(Gk9&3h6-_B zp3}k4Vn(P0zi~{h{VkGnsuu#lr^Ct719}PhhL} zwJTGMKb;z>Igsvlx}rs~`R#5PcR8;)iRvvM|Jk(+(lJoch!ov6ixFnDlj011>WQkv_op8RKJdoL^uEJJCSo!-%b_pjdzFFrJmJ5u%l|L{a0h$@c| zQG*K7nT$MuxPuq(trliLXcs$F;zO;`Hcjg#WrSFHN-C$kgd zQHVYJk}Y{TLeFA3E+FTQu8@r5a-tocYEMo=ei(-!z!|5@yEuY}*X6J=)3sNTi&Up} Wr&xDc=v65PKOA33bU>qlt$zauvnrPW literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/trigger-square.psd b/workflow/public_html/skins/ext/images/default/form/trigger-square.psd new file mode 100755 index 0000000000000000000000000000000000000000..e922ee65de361157b2c9bada8704be67a50510ea GIT binary patch literal 36542 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 Vn+0%uFaj>+OMzhhbM}qFe*^Pn6NCT& literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/trigger-tpl.gif b/workflow/public_html/skins/ext/images/default/form/trigger-tpl.gif new file mode 100755 index 0000000000000000000000000000000000000000..e3701a383107e090fe25d3fb8d63aaa9290435e9 GIT binary patch literal 1487 zcmeH`{ZrC+0DwPCBIojs3o|_0?P^-#Ox&%!R?e}@xx}{YYR;I~>N*jn-Qn&=-p-KA zeA(%=S((N$6_|l9fQC+Hxi9#N2luQwPBW3%=l!}^GELum-8=KbTwwF%Rj%DgphgD1_aTFbxxSbc_7 z*tiC}T&|Us6}Q{%@p#OB*cyNreCzg?@X|W$2*O^k*XQ%C`Tc=FAQ%j8?6A4LxwQ?$ zFnGh80{=sSgX_p0D-7aZyI(&6LSe8g^uSq3699<4vDu>uKv9OqBv(z-4-J(@5=c^c zCvT(%gPg*qb@7!*M7$td*%d>&myq6H6@|%BvEwc%rj<`}&sV>d68bLbzTg)ez92R{ zL%OWyA+pbMNDmz0eA2_8Du?G1p`W#a zi*2IW=5FT;Nm@-f=nK&Ju|GKH$G>G{YFkTqB2{y*&pLXG@cG}HCp8gjUV5YGKrX;c zKcN|~+$?$NF%5hJAHnq}74oAsZQo5Wi&P-SqG~)}Tn55ltvZdK`IT)rc<_XRg^Z+L zEoNSBGTq*jc(eqdQjVJMM2OG;fu#t{Wg$qSxg0~TkXJ<4QMskK7QwahebOaMWkPZx zRCQcO<&}om1lH;#2Gv?~f?O}Zn-ZB9UH!@7hU*~W__FO@Msfvo|59dNOf4yZWj)Bw z%xm6#wG3~s&!Wh#gS~vA{n3r&QHV_+#^*Lr;_-`|0`e>QZ$*LSBb*;mXnE6}$b132 z(DJsR0TJCw1C%R+wAP Mbv*YluxN1lKj3usvH$=8 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/trigger.gif b/workflow/public_html/skins/ext/images/default/form/trigger.gif new file mode 100755 index 0000000000000000000000000000000000000000..f6cba375ae3a96c87639a5b3034d204953d1db14 GIT binary patch literal 1816 zcmeH`_ft~`0DvC>l)V*M8qq2uh!jyON)b6kq!482iD+?8gcdhyFlbZ|=|RDBw1|nK zYy=g-LKp%@NJ7F0kj2X&VI?8&k(c$_{t^AH-#_r(eRtok-4Q`Qq@Dnl0SotmX1et2 znD}NDyN)jG6Qb30kilRKf(n0Ju2yFdDUimGJpp_36beNxUC5kJ*3g9v!Msd^{)2b{ zt)YWDy+JOQ)A*{nxjFfQrm0UnJ3HGlGWq@9yh#Kd7#LtOnJgA-XlMwAVF=L=4-dbm z3fXKnRiF=ye+a^8A5VqoQJqfL&C@akG8PEYxRXj))60QJM@IwV@*uUQp?9K-gJ^UH z4u_-FYMW@18U{!cz;a0asZU(Z0H>#?IrHd{2&N23`ni(|NYg@>b`8qZYBi$ODPSFh z7`jJhAVkyHJFzMLVGDbb%7s2qg)pKQKO~dc9tw(M&*S2TMv}O{ul| zX(hr_p*$X+#+A0Sq=O=OW@d&4Y7hhgA#_j(ixyB=hq5JVKA%tHNdpt|spDd)a$!U? z)5sF_^Hs10Wr_7%E*AvBz=Vf`lc;0?RY8zKjRwZ&(}g;vQppgb43Ta~iVm}RDwPWO zpZ~tVO2otn0PX`m|Em6d0x&}XXEXQ6TK?^DjDz>V9vskq*Um8{ZzSEb>&{ZYsD`$> zm)(zuOII)3T~F#=j=_{4?5+PUs&M0;zw%rhk5ixe#BCnweRnc8-_pj+BdVzUj`_L_ z?#D?-(@DGs1nWi=zJ{hbxhrf&%I9P;z^0j13zsoCgUyB!LQG$M=6Bn zEAz4?W0%OlXZ*aUKJ;U)pd(AW$gbc;9oStk74bN_sb181!*oCQpv$^Dw9=iqU&fOF zA~XHNGjV!qu8eunzbD^*Rqi>fhV#@l+mqU6##_(wB0iO=C7ZkUxySYgSDd!7KA4`t z06t~PYMpC;jw9vdJDi-&MA7~e!G~Qkj#U=LMSSMXfRx;YLuK16N&BjCr(TdvP5rdc zt{pce*VU*awki_c3{bJ8r)Ojoe=08|_7OJCv7kK{Qgd2!MVLiRi_8Mw-eFrw8P7v;1u9x z-}%LDSypYcB`tYg>w`BBcdlCOdCe)M zfedWoWIDv&Q{*sXo@UiMg$8V^0TPUXMplY3&fDl%31>0(Zc)nn!H}aK4fIu=z6)kv z-+Z?)QwhI?k0h;tqPxe!h}L*+mSyQBc8+_@CEm253L5eZ-+%~}u_Mh*3<*qT_XkyU<3LnMio0A;#iIPH2>?PU+mB(da-cCK;QqFvtUd_gzW zR3d9re%ms)ZMLbqzj@+o@P+O3jjpA7c>MCCZPR2MtU)a-vAv->;ui9GR8TT!P_r-l zp)l_j*PxyKbA^6(s&E5fn9Jqqg!@{l99z5`bkz(Dw>Ii+vxSa)plM$yeY@T53FcuX yYq-rg40qd+b;#6`NHN(^kZr9xY#!i+x4U-1Xsrs12{a3_fn)Cim5HGM5d1gxR!0f| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/form/trigger.psd b/workflow/public_html/skins/ext/images/default/form/trigger.psd new file mode 100755 index 0000000000000000000000000000000000000000..344c7682409411be63023e77ab2e2140403a4fcd GIT binary patch literal 37599 zcmeHw33wCNz3-81ykXWrlABPf`X*`bt-+S$O)i-0mG}k+$2Qr!$kNz2$dW6`Y<-v{ z-M&}I(!SgFyEnbBX`6IOVz?=BaJD9COK`|#OCVqfm_3HFS$LHt&HMe&%t#~2Cg{C1 zFC>z_IdlH&Ip=?Vb7syN&8VQHx|V5}^hw0-dTb3Wg(XO=Wr2c{%Bn*fXi>@@~PkHdvoi$f7V?K8`}~Xxue_e2YqHMIxGT3RyQ-yBSlV>!YNt@U`t~}@>SY#_HDf_h+Psy8E1O%I z1-DtZve{;L6|S70VYWKzg+kkOK*_fp_nM_&PhAe|&4m9StR@vR=m2>Q_f0Udke#!)w#o5&2ZbH%I z*Ie&tbhr?DRb!YWbhuh&=>S)oG)*5wHW=oTuXjP+Rb=lLr zEDEwJ=)6ZMUJ?9{>I|zT*cUCWP8;uXt0haY3C)7t?LvR(!~4T(DQs{!o6YVbb4!b@ z$zrB1&suJ`${pFFv}9gZNcH2cb+C|N<->p!6i34;C@L&<*c?vuwNPZ7mo*k!)oCFy zb-e^fE3inw$(>^;P&-g-jOpUmCYRgcT$L5mKErWi%atjSPMAvYge0X9>nA%9(nK!jF|>gUZycypJ~(=U^8Xr8n77+;K5IRHa6(y6P*h=He-&_@HL|;FE=|k zC%3q~LT}7A6ql8jmFP`nrjoq8Y(q(Txm@wEn#tAv*hVN}Wz#rFAW1Y5h+A0Qv{JC$ zUDkv_%tgJc&qk2Pl&GQ{lHU`uG~}oaRf0%EKAzO#>@O6}0rI4pMM(3Uae~ivC0%y@?e4pKk;@ zD1|;!6Qu>vL`r2DffY)r6eBQ1DQuB)TOcS$p93kSs4Y^7lh5-7l$uaaq+G|8i+sL; z`1wE^QeZMiZ-P%s$<|arwx$BoF%^)G$;5R`dY&h5ChpB-q7qHqr-^EU3xT{$;5HLj z&&mrzATsC%2%Y1h6;Bof+0+mqodReOy}M(k?4_ZKsU)!ONk) zOD2S~zl(dxX}pk_f*TK4JX|qFASUHFy5ixADFQJm$I%rJS4cyftZxz=!%CcrU=BO97k6?Trou;CgnJ~;^B%Z z0x>Da(G?F@Oc97lIgYM)xMGSxOv-U|#lsa-1Y%N-qbnY+m?999avWXpaK#jXn3Ut_ ziiazv2*jiuM^`*tF-0II?)Cy5)kCp5d6EfoB6Vbb{T2C;9A+^D~yzRm>^ik57K7Y;kGbJ=Ntp zJdoyc>#CQOEUGNkWz5OSD#kNvLRMB;U74+lprr=SkkfsspaI$>J_bOP#k&SXG3l80SjPTAX--Z*H}@ zQK;Zg%gwE>y4B%qTJ6B|Nj5y_GcSwuVJ4f8ZSQWPXG!N;==n#7Q?W^%=W@e+qpG+E z9QBg!yewIkmU>y2O>UvN*y%K{3OO|si7LTRsnj?=KDt@t1eLZG<>R>9m~DXaXQvw?8WcPb5dTlzad0O_IXuDp*&2_=XjHHhK9!@9QsD^X zT>T@`I1LN-#;4?vaJAOgN$1%XGtT?pY_c~vzNwr|$2v<_S5;S+Rg-Qh9v{Em+$<== zm+H(J%X#EVPw1CDe@36tQ|Bq?Mhdxd#-u#8>N2e$75Oq^k>GX(S$op;_1ErjzbfEvgx)Y!g`~KVQ?iTbk>t zduF4ECvZ|N!qOPf8A6-#p%{;QEN=5OuHCpE{O5^tm&e6RBHkEZD)!-}d z`CA!p;j+m*<;j8vnRJKYJSQim*E!90SBu$++X}0=BylE}%tkti)iEbCGdpv!7VMo& zK;FVu$v!S{O?VeYo@30ak$mKGdKyx^buvo&1uo@po8+~e6r^W!`X9pSgiD-GsrS5mbSv-TvlnX`?zX1 zk^C)gb;soJausBYO6_hr@D!CPjW$QU*@kh-vW#v>-f3IpB0fH;OUS*9v0xzXupZ3$x~;l3^28evz^jh#a88x0 zQ3&HCnQiVmb7L59vPH1j>V%clwX_Ehvg+T#K*zFEG#X8mPXu)CW z5)@#NEX@WWMRC*X9c}i?mjB>qzkTto z_fHMxFTAU9#See}yUknoeK<6YX|AN|JDv*3j?w{X9C4O_AwR}mQTR0Z1!uU1#a;OU80hXS? z%bdm*u>Q51j{nu0yY;6_$x!Nt@rI5-dVHtmD_JT zwr}W;_PuNFo3Z!nKg~V=^kd&%nzgEZ!%aVa_7}(YW|cgc@aX*e{zp~wcSTk%G#t5W zkN(*W`))Y<%oiVde0$~}j^%aV_k*58L;GIo5!pYSK6sz|Y_j_|(g9EL-;C{=wAgrT2cQf8^(F$8YRd z(EYr~b{l=Wo;~@;|Nha1Uu{0P{=<9B&HV+>pIbikm)9O`{Qb_JKlCgP7~gyT&Nntb z`{F+9z`XXshfeQ%taRPdNwa%i=&oJ<$Ag{)zZlxozhLmt-48$dr>8g1-toV4mvrvm zS^3z3;csOwd$QRwxVhzP_r0{kncscd=zXp2@Y=HN3wobB_LlXoAD5rI_PwTqg8hbR z9lt!_@Z8_?AYWDjnf zy6;C1&D`{QMUioXt19>S= zZ+&ft<>N`(7^Ukwpwk+yemigK~_kYZ?Z#lj5=lY+$a@za- zo*lct`R;EwuYG#c9+6EM-13*TPgg$Qy>I*0x0*Y0f2wc)&NsfXYu638RefjHJ^d^4 z_pF|x#PN4OZ+`f|{fi#YJTc{lJ99hNeCzO;rZd-W`rZ9Un;&z1aQ2xOFRgpzanIl8 ze--W7dGQ;+d_8bMbIs_Ub=SJxJylg}%+D<={or1VbB}Cj+t)Vq+9S?em*0K*4}V<# z@O}ON`EuU;U+%OIY(6KliDy>7el-6=MHvZ?kcYgQ&^ZxX;zt|Ko?DTHF=})UFZ+>joPuF~PLA%J-)Mtzwy6Hzp zH}$uEamN>jUtGKQgGc}L0IbVTtu-zF^Uil_rjMMw>G2g=yY5_5D6;3)p1J=gBLg?B zUbEnVo?{{tyZH$HB|g$Dp%IcsohhuCS($^?;}S&2s@YQH-Pl|_*8+`eK0-ssN?9$V zi*0#y&p?)G=2lg)e?}&SC2OYhe-oe?DAU}4D;`p1tX^|tF#mw&E3ys-ca0u@GQb#J zT{$%do~JX$<3DWT*Fa?Z6t-P#_V*rS4D&mAf7$oNGkQIKVK%)LU#GmGt5JMt=4wN};fjB72IFzyd+M7h zPZB@ne6yp4E(7Rlk=jb1WJ)M}w3j}?EM@rBl_J5O;>Ty2v`?fdr!W$+OQ zI?7y=Op=>i9B=WYFemavKZB(_NCh# z_z|*|i`DH+cP(vdaF@eVQ*f?LO_^eCaxWE}#kNMwo83$C27W$oo>CUhCe^YA7oS2) z7S)2&g1>K&C*u^Fw1y^|{QGHTLR}H$K%TG=GbO0eJwB%mZ{D{mjh$d~xLnG58dO-i z-BD%6Pnmc#lqk_km((t)P=2{ZIu~6ka1R< z`EPlY3f<^dEi^}j;xZAEXS3IjVcm>H6m_tstPtvJsY}A+NHv^@pPdUV3QU=S_@EGG&RV*6Tbs;I5{4vvW zz9SS|lH!)XCPS9e?8;ezy_WNSLoCg#X0yGivZkU2`KiP&wwKZ9h3j=y3Cb!qA8U#$ zY8Bj&3s!-jbjT}y;cI1KR?y<>WK(wA=Sx;)fIF>)ORM@7&V{%%4O;_dC`cJG#`a8* zV->Ejh=7sMJ8UP>RS=+iP$H!XSm4A>na)ic_7<{#0_*=iTz4qX;09VsrG&Hp*=vp?Rd09l#1&m4Sc?WlPWAe zdP`npUL`nn+2qI8YNxu<^?x#3ggZ^E_*$usWlL?qUxLxfX`;=%%E|RtHPP@$(c@UK z*y^d>i3A{$;}@({V;)_im)Vyo2RN78TrITz6qMU6Hu4`9w}zF@7Vs!mksr(q_%%Ao zEK-EDFO!n?HXb1pMM$%QN>)Ya1Jc0fiX)U#!v|6wEerEjhoY3iY7iwCCULZ;tYdmE z4@D(`=ubE*ym3gPa0B#E$E@VoTS+x@ncX^((d`)x?*nA6I4alHwc^?U|FVW#O}d46 zVn>IwZL^?`5KzOe#l6c`#Kw;3IC$ECJ;iDvQbL#x(OZi6H8UY1dVIa|6OEn*QNv&E zUHP{U$Jkig6Jji1^vm^_f$P|;alf-6SAF|BnAq1Ay?K0^eI1@r%}Z^bZItj_ki66< z`dG)My;`5x*0+tdNx4gBFiLRR)2He0@a)w{Ql9agQK*ZW(GJgh3Pl-DuR>iQ*=~iR zjOUa>ohR8&g`$k-xI%H+c7>vh=cq!RBfEDLiZY%ag*vP8c6i=aD9U&aDbyj&V29@g z&B?aD4Xll4JX;j%0LfldD9U)YDpWVgUQ#H^pmf>GK9aqnP?Yg(SE%%^uNNToZKChJ|8aS zN_Ld-3@H?F-03-@P?YfuDioIixsn}aJOc^^jCXntD->ls{R#z)cM_^4JIZ)2g{Z+! z;J>dO2i>lADR(GH0_B~+ZeM%fF4oR7IC5kPDDMQ!WQsCqlS~2Sot|9^MH$Ztg#yaQ zl>z1B%7F55Wx)8jGGO>>kjbc?&2EhNhDLJLs7)hyUl$PF9ld!1nw~BsA9iEtM8b1H z5~vQau1kH|fY{x4ign95k#UMJ-GxMwNf|{1NOyTWiil?v5fI%)n38<(j3NSPy9kPs zh-a=q1UPpQxFsu|QLKRGE;=S85ziy0;3>7-w&AoG{5(z9{MhY}vZBiiH z#O`C?!1pdz#Y$Kn?l4TA$h6nra6K-NC>>>KD(Xxa6)wBL(zTg8PVC5>z*DV1g7$^k z`XZ#!+7ngfvh*1*jflS8WxIXi$V)Sz97#tO9Vw5b!}L*cIQE^!wmVa*csLzx9WIZw z57SR%Bo2rPxe4v4fEkuNygMlq*}26OM;UKP=Bbb7 zgn6uz-Om1%6|h29Bq5ivfSBy}VMgrpi=%4djG73OTwp#?6M(+PkBf>>-lw+ksRWTq zDN2DTHlWvv0i+^ag;OENk&^NB$PdF7fG>4ETwg6w=ha#i79adjyJ=5NQ+!i?JekP# z(4x_iV9qP+)1J3>3>nH}N#1~{M=SsrIX4`%0GP&+CZa5Y5)4H)G9d2(C0T!PTnUHL zh$sR|Nc&|yKq-pHp#(0Vgj9x7IV)ooQBVp{U-_lLB`XAnl0tAODZ~XfDl$KiL|qol zav&)xz7Rh`B}Gvo;8Y{H)iQ{J`JhLRpdeeV9#kQF!~jYhJi)wL`J;6>aNvUj2YU`2 z*%t@SI5G~LY5>Q_fx~kgIMC<78Arx}gORdY0*;*Hz~L4E&Nxy42R$hR$14NJ3*gB5 zGH}L_aNuC(0N@~%f#U^mqIeuQ-~u>EIdC#CpU>mKF)#zpowqRjLfeP+0v}=~?axHe z7g#^~q#yQ@+!sO9dR|~1`evQn|G_-jjV~h$^f-u(|#;Ijx6RE8G4Y?L0M~X3?A=M3?S%H zr2Sk2{TadGy$K$A6DjY_|9|U3F|0;0Z66>q*7gL8<;!O^pQm!MP)Tc#)wnZG{!)?c3iU@DA+V!PD*AVYe-?lQ#dh zjJ7D@(W9qEd?Tlh@$~3XwKi*;d+xk9S8w!reE7e5@A-419q;Vy17omz5RAT^?}%;N zw!JqnGVtCzJPmBiYKzk7IW`EBkq<{;GI*>f%7nFvXDt^{g3*u7cj4?=Z^zqjzdHcJ zi*4ZDx8H`%j*Dc$Nl+7yjsMI*39yK{j17}y!uGJOma|AC|< z!>GjY5kD=-23}0r{1*>s&!0C3UQC7oFC?H(pdtcT#|_uO(yM=K(r#+~z%KvRu?&3O zi9N%)!#zG)*7d)X^zs%@j%Uluep=TJY)FyX0Ox)$7$m)at5hFsRj3*U_NXdHCpHZFLPssG929!J~)8_JaqH4v!8W z{eY)|gIVoS8vO%4`0x+;;lnr3A7#SY`Jh$<9c+A1>!cBi2yA?WYCm{*fXY2d_@Q;b?@H2t36x;tKi{2#xmi98XQQ2TBrY=q&6SyNW$}LfbohdX(-3s5O)Utkb)T?eUVm zWCOB2$nu_Gr@UktlF`s5t?iT62()GTb@lfTVxSq6(|)l#a7x>Ix>rj5r>1pBDd2v3gc9qf@#v9t>oFd!U-t-&M_mJh zJ}~^lelUE417i27Q)j$B?-?l#z;TpDK-50EZavcV>mK!slOioxw|KVr0t#3UpX>Q> z)HOIr1*{Jcb9itNrSuM?SnoM6iXHAfb*ei`!!IU5TO=3av}k=kj;s%?)2^4sqOQO( z?T22@@O~ILHhHA``0-wN=aumG25=iBTm$zp0wY>)fSUxo{*g)17JMjz4{0ds@}EdL zO)kBs{d5l{a9oQLs0!X*Km13C{i9eJfi@OC>1Io$Hin`j!;cIfp)0E{->Jki-bcJ= ze02ZCe>{oT+}rDe*D%qjUn@Q;j?xX9aIMfl)HQlqdv4_1DBZ2`9Z&3q+ul+5QL*{` z7PU+ng1Wq?+26cmIf}Lo^?G3!WO1typN1dlW(>4WjzBYXFDJnAM4i{(cw HPl*2qO$roZ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/gradient-bg.gif b/workflow/public_html/skins/ext/images/default/gradient-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..8134e4994f2a36da074990b94a5f17aefd378600 GIT binary patch literal 1472 zcmeIx`%jZs7{KwDTLnZd*hMh7R3%&{VK|xh5d@TrMjeTpnq?_&b8`}Bh(kowLJ^R= zwLrP_Mz6F*N-1{`N?)K@6i}uD1>V*|OIv8)A|*;9JN<2c#7;i>=A7rpCpmEmrw$)U zc7mcXc@UIVGnG~gOy34*)9Li-becMyuD$~>)ERVj219+9F_Xbm-(}8ZvefrjGxzFd z?gQ+Z2W-&U2kcoQXO_sF&Em{uap$rD-W-Vsija6n4j*~Q*W?J0hYp%tpk9;bpv@I( z@`Tz)B2B(fn=b+vZGl)@(4Z|8YYQ8+MGfzZp1v;z8bNg>jk*$vu2iBclgyVj>B^es z9|O{PvUGvmyzs<9PmwK9WcqTTMPJ^kuV~R%wCXE?Ha*qBP}OFjwi~K|4nuYOVl`;T zVhzx_SPOK48f&|ZG@#o^cQDa=jErs*qsPQ}W@7f3n4r(hETGq1*K1~j_Lq?Dr%LqcFxvPW zut}by5*6B{LZvEO(+Ju$Vv_!sOuZvAc4ePkK}Mg^X|R8{wv3g3jV&Qm0~*o(w;!4zGtP^}q4TE3f=4jcq2s zNTj41IT7{z(FAgK^iIzZ@_2j+Ir8!+!Q#r@%9(ju7k_5|Ghf7eqx2?7%YoH4jP!wx7HA*Q43) zwFOW=pP6ly3pn=?dHpWVl+z~h4aA7q3Dbmfk>A9h*D=1j0=ZkaJtNDl4|Dy58=OQ4 zb=w|rEX#G|6q4dPk_gFV6VcYbmUmazi7x6i6Xb&As-j$U2PJ(S9-JDYvw05^=DZ2M z-q(%65iC7!Sf=Hfs~2MFb#cc_ASYbPO$Z9ewDx-)GFuhcxKI?v{g{Fd`2H?N2mNoG a(II?Zs7)DAnPM9b=8J95L)rdV=-9sjoxm#q literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/arrow-left-white.gif b/workflow/public_html/skins/ext/images/default/grid/arrow-left-white.gif new file mode 100755 index 0000000000000000000000000000000000000000..63088f56e1c33fd23437ab00ef3e10570c4a57fa GIT binary patch literal 825 zcmZ?wbhEHbWMSZBXlGz>`0uc0#Y_e;`2YVugfU8vhQJ630mYvz%pkAofCx~YVBipA cVC0bDXlQU?ViVMIiI|XhxRH&WjfKG)0LI-8@c;k- literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/arrow-right-white.gif b/workflow/public_html/skins/ext/images/default/grid/arrow-right-white.gif new file mode 100755 index 0000000000000000000000000000000000000000..e9e06789044eacb8a695cd1df46449bcb2b9aa07 GIT binary patch literal 825 zcmZ?wbhEHbWMSZBXlGz>`0uc0#Y_e;`2YVugfU8vhQJ630mYvz%pkAofCx~YVBipA cVB}zNNKj~OV&PY_IbpESp@o^1jfKG)0Ls}94FCWD literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/col-move-bottom.gif b/workflow/public_html/skins/ext/images/default/grid/col-move-bottom.gif new file mode 100755 index 0000000000000000000000000000000000000000..cc1e473ecc1a48f6d33d935f226588c495da4e05 GIT binary patch literal 868 zcmZ?wbhEHb( zLO{cVgpLOZ6Fwx&_)sw8LBWC#1q=Q+toSft!~X>b{xgh%(GVD#A)xq^g_(hYn?VQU zd{CZX;BaIR=ZFzVT;Rwl#vu{Yu%W4$ky$xng~3BdrVc>?i4_ctPK=BUEM^-R4mL70 a^J-WG2rw*VW@C5a%Q0YR@NEQ2S_1&+BRBT| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/col-move-top.gif b/workflow/public_html/skins/ext/images/default/grid/col-move-top.gif new file mode 100755 index 0000000000000000000000000000000000000000..58ff32cc8fa2aa1be310b03bb2af77c1b77abe93 GIT binary patch literal 869 zcmZ?wbhEHbG68wVGIhem=U(^LUb4h;c?We$u2%uEc{03e(}^8f$< literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/columns.gif b/workflow/public_html/skins/ext/images/default/grid/columns.gif new file mode 100755 index 0000000000000000000000000000000000000000..2d3a82393e31768c22869778698613b2f5f2174a GIT binary patch literal 962 zcmZ?wbhEHb6krfwXlGyuEL<5_v@*CDh*pJ^t_~?(6IQl1ymDPc)rN@bjZrn5V(PZU z)NOSrd+hMvA+B+IeDltP)?JCMyOZ1ZrgZEJYkQj3eITRnaL%L?Ia5yNO*xf6?R5V1 zGX)b57R)?XH0ylvoQuVCFO|-_Qnuh~<)Ryvi*HsfxmC5~cGa>w)ywZpoH%jn)T#64 z&D*eH!>(Ps_U+r(Fz^e+YaA8aNxk9Lx+wXJ9gs4iBqReojG&n z?%lgL9)0`&|3AYh7!3i+LO}5+3nK#qAA=6a7*L*I;F!-K%OT^jVZp&>mh3YgjfYq| z1(lp?K5S5QW|J^Yxp3pe#^mFCnoeCZo|g`B%4>LkiP*V`#cPUi%)1K8vI{DjqJ>lyj2t2o f3la`CGVn;rtSCr4)W)vpHOFJ)qNAORj11NQ63h`c literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/done.gif b/workflow/public_html/skins/ext/images/default/grid/done.gif new file mode 100755 index 0000000000000000000000000000000000000000..a937cb22c84a2ac6ecfc12ae9681ab72ed83ca78 GIT binary patch literal 133 zcmZ?wbhEHb6krfwXl7towPL}p0*huu%~roJzC1V7qiQ)z(xVq;t8Q*e g@TwP&*%vbDj%DY0^FxMh_Sd^OqF)Bg*^}7&&A#5)LvkG7IyS zOnBJr%r7CL!Q$}XP&==XoWqO@51m;T- zPZpr7|1;=-+z!eU3>@+d`VlJv8V|8>3M$wXTxdAR#L6ikV-V2L(7?dJ#=^p24FK}3 BP__U7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid-blue-hd.gif b/workflow/public_html/skins/ext/images/default/grid/grid-blue-hd.gif new file mode 100755 index 0000000000000000000000000000000000000000..862094e6803f522712e4d193c7becd8e9b857dd3 GIT binary patch literal 829 zcmZ?wbhEHbWMmL!XlGzJa`*r7`~Ocp_<#1%{|it4Uw-=k+VlT6U;e-I>i_*W{~x~l z|K$Du=O6#S`uzXxm;WEW{r~*q|F@t2fByde=kI?YU>F6XAuyCfK=CIF(E0xvbU>Z} m<=_zzU~q6?um%8<;zWG_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid-blue-split.gif b/workflow/public_html/skins/ext/images/default/grid/grid-blue-split.gif new file mode 100755 index 0000000000000000000000000000000000000000..5286f58f6f798184c3eeacba1352cfd39b9ae03e GIT binary patch literal 817 zcmZ?wbhEHbWMbfDXlG!Ub?iS7FpPrH5Ezjmp!kyo=M_wPS^_`om@~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid-loading.gif b/workflow/public_html/skins/ext/images/default/grid/grid-loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..d112c54013e1e4c2f606e848352f08958134c46f GIT binary patch literal 701 zcmZ?wbhEHb6krfw_{6~Q|NsBg$>(oA`P8%SHjuGk&%@0ppYOTwO7TCppKD04vtxj( zk)8oFBLf42;y+oZ(#)I^h4Rdj3>8V47nBGRLn+Q9-(eXZMC@T`q-A zfguTok_rhvuF+B}YGk&S-hZ1Y!QP;7UE)!jv*adK6)hob2AOf}GE&w)<#=MknJHoV zY^}*Md|xE}K6*MO&RAU_^MUKk=Djk=g^pDJi6uprK3M%`#IdVL zUEAw4e{ zmg0{~p6|Ie&p`6H%mYO|r)_gjg|As;$iv1hQk=MZgX#CFjEx2xI6HUG&(-w8Y7Wpj zcm93g6udbnGzoX) literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid-vista-hd.gif b/workflow/public_html/skins/ext/images/default/grid/grid-vista-hd.gif new file mode 100755 index 0000000000000000000000000000000000000000..d0972638e8305d32d4a2419b3dd317f3c8fd3fe2 GIT binary patch literal 829 zcmZ?wbhEHbWMmL!XlGzJe){5xGZ#;uy>#l_<(QpFT5;g3%Bd$|0cmlLhGf{|q`H nPk{0S1BVoYrq2Wc#zV~Pyb=r?3JDC2Ol*7#9t#p29T=29Ey>tSt{5 zHY{*#Vsg}oIT5h%K(m0QN{+|JM3-h^O`|Opf{7fxyq0BWID}eGbgMYd>zNVs*sDWV zoA1qwjZY3uXHRaM;~D(iZJx6IEfY?Wr2(@o4CQoZZdq`CwriwbsHEt#km;etaZ`6L zTz!3gENh*F_qI0?jS`nu#m){}(7wIk@jlUvh3oF_E@dsdaeDjvxJFSXZaJBV1#O2r zgyqE~6rDPbPjEKrQ!sFDJ262wU4TQ;rQ!Sn=9UHq#|Nzf3_+{e1Rfn?ZRD4$;FDGQ z#@r~Pu^>)X$(*&3x9Pl?tj&%CoF~dRyY`d67r$SB{>v~5Mnhoag@EEu7NDp9Gw6W44$2b@93l*? Z95Nmo7Bnz$2y4ZhC{SczU}R*l1^^j55kLR{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid3-hrow.gif b/workflow/public_html/skins/ext/images/default/grid/grid3-hrow.gif new file mode 100755 index 0000000000000000000000000000000000000000..8d459a304e0b224f8c28d6b7b585da7019d28cce GIT binary patch literal 836 zcmZ?wbhEHbWMYtDXlG!!aN)x1H}BrOegF2|hj;HkzW?y)!^h7bKYjW6^C!b77!85p z9s-I#S%6;r&!7YHC@4=ba40eea>#gWNI1yM!7mYUVnf4WCKe8!85Rx=4Ga>@3=9GS G4Auam1ttan literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid3-special-col-bg.gif b/workflow/public_html/skins/ext/images/default/grid/grid3-special-col-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..0b4d6ca3bf28ba44b4ee215fddf936aab7cdd5a0 GIT binary patch literal 837 zcmZ?wbhEHblwe?DXlG!!aN)x1H}BrOegF2|hj;HkzW?y)!^h7bKYjW6^C!b77!85p z9s-I#S%6;r&!7YHC@4=ba40bda>#gmIKarv!7ZX-kkHV;z{nslr{jQv6El~jRSSoL H0)sUGu7M?* literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/grid3-special-col-sel-bg.gif b/workflow/public_html/skins/ext/images/default/grid/grid3-special-col-sel-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..1dfe9a69eae133929f3835ffcfd108959539b9e5 GIT binary patch literal 843 zcmZ?wbhEHblwe?DXlGzpb>`cJ$GN zbN|hshj0HpdiUqa`#(?L|9SS|&x?`0o(b_B3_s=d77u3+H|!r zfbs+bM-c-fhm6OD1qYj1`88rr6eKbU2cZFVdORzJ@!m~?8+%1KMTTg@3K$aq~=^PX>8{)(q7 acp2+dVHKAK1EYrP>l5}X$w&(@SOWm68Djnb literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/group-collapse.gif b/workflow/public_html/skins/ext/images/default/grid/group-collapse.gif new file mode 100755 index 0000000000000000000000000000000000000000..495bb051dcee00b837a948af56f7a59e77b69aa5 GIT binary patch literal 881 zcmZ?wbhEHb}Lc00Z?nwEzGB literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/group-expand-sprite.gif b/workflow/public_html/skins/ext/images/default/grid/group-expand-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..9c1653b48dbd2d4bb00886c379ba3a66813737c4 GIT binary patch literal 955 zcmZ?wbhEHbuiX3i z{QdXWpZ@~^!zdUHf#DSbia%Kx85kHDbU@w$?_tHlbAgvKT&29}T*1_wr_8B7v4Oad0D zH!!O=%UO7AS#fc($7HS8Q(IPEULLU6Yp&PURaaMg26lV0F?{M|skyG2(-{0TB%q{1$Bh!Jw8USBOURwYF literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/group-expand.gif b/workflow/public_html/skins/ext/images/default/grid/group-expand.gif new file mode 100755 index 0000000000000000000000000000000000000000..a33ac30bd2b3758ab2e003f70ce638ab77eaf101 GIT binary patch literal 884 zcmZ?wbhEHbbN~|U;Bpe)@m>5|?LIe~TnPxDF-7pDQklw(o P-YjR~vE{{q1_o;Y#^^iR literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hd-pop.gif b/workflow/public_html/skins/ext/images/default/grid/hd-pop.gif new file mode 100755 index 0000000000000000000000000000000000000000..eb8ba79679eabb7811c3d9d1c86c43bcf67552cc GIT binary patch literal 839 zcmZ?wbhEHb_??HKjfkTCXkweD9 mfT4kbgI~?WW5NQ*7JhN9o*xBDE*)ahRw)@D7aeL~um%9t9ucMh literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hmenu-asc.gif b/workflow/public_html/skins/ext/images/default/grid/hmenu-asc.gif new file mode 100755 index 0000000000000000000000000000000000000000..8917e0eee0cdf7758e83c4cffa7a7239f72b8427 GIT binary patch literal 931 zcmeH`u}i~197Zo~Emb-ML>(No#i13!1{`|2)F4_jl^X=3LnUJzge<}>RZc~zP~kV; zB68w#pu>SnK&adpIt5*dn`7OIQ?33Dj(x+oeanNlwY^!!2PQI6AN?^vMGITlu?Sc$ zU>9uS*}igoaC}8PN`jCCnovooc75v7&|^Bl#h|GI2x(JLP!wWjlNOK|~-m_dM?T+-E!pI0dd^5l}(d@Glq_swQ5Q<6ypk{;!;VaqFyLusAH|W zI_^hNH}3WaBSr@P!$9skWgujrrQZ^Mn?RWcN@fn{AM5KVovc^P{B4D$=SroI5_&zI zNSF`DRwb35%9fAbth<-%@nxq_$~TO}IN9OvPh(dz1*g;6JvytHv(;6&xjkRcOr!mB r{VRFNa;Pe5osHT>5@ibIb~{3g+0C%lYO~3O6<&R=-|w9m23q?84YkzM literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hmenu-desc.gif b/workflow/public_html/skins/ext/images/default/grid/hmenu-desc.gif new file mode 100755 index 0000000000000000000000000000000000000000..f26b7c2fc5836850958f7f2b1fafd3988a988d7a GIT binary patch literal 930 zcmeH`u}cC`9LIl>nH9kiSwcv;h)RPe4nCSX#PT4JtLbR)IJcwe#y6z#3aSf)9!+l$ z;%yxW@kSwnZWM)ZydeVHiWX}!?QdxG!)N_2ANcN;ig{#6Ai)s+7(q%#GE!y5mQ{jO zj5MrhrlNCIcT|&WCe|#b*{*J3-4-SmmeaOT%60^HIHrQgae`8gf*j^igs3uBp{hnT zopO)5V>`?=nQ1YLFxzIBGSTNY=9rB4oG{nnt~U^b3F->w3Rehk(B^L2>$m$u&+|JS zzvF-O{o!cJw7~xri2now00G#VJYn()2%o@AE8lw!UPJ@SiC{BRyCfUg+)-YByjskr zv+Ug{Ji~hAw(%`jAsUlHdvfpXd_GaEWO`qB`!@?~^gbD{hpr>BT&DZEGYhLy?xoZ; n!ca~nNw;=d4=v4s)H*Z{&Ndrqrwj#{39jU-m51Y}8o>51Tocwt literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hmenu-lock.gif b/workflow/public_html/skins/ext/images/default/grid/hmenu-lock.gif new file mode 100755 index 0000000000000000000000000000000000000000..1596126108fd99fc56226b412c6749c55ad5402b GIT binary patch literal 955 zcmZ?wbhEHb6krfwXlG#X4~ou+bjZoeOV2FG$|=q-C@C(jDlf0eD{N@b6W`Inv#*zP ze=o<1{(yu1+=nJ`ADhB`dOG8|nG9#s|^2dGCVn`{Pc*@>k~$=Pg%ddVgCO)!~fR||KBnE z|HJVAKg0iLR{x*dJ-;0I|GC%y_pblnMF0Qq{Qtk(|NlOXjV)~*Jzd>>6DCZaK7IO( z88c?ioVjUP%kt&RSFKvLYv;-0XzkU1m_xG3of4~3u@#FvBAOHXT`19w_f1o=? z!B7qX#h)z93=CNeIv`Jg@&p6N42G*5G9DWiIGRQ-bEs^3`rv@RCy$K9p(kC=rd|^` zST-*?>B_{iQlwx7E2E<(Ghbe(62oy`Y27&t0f`^nn;9J1SUxr?H8M5pwCs2h(8SWt zC8Qv+=HXHgep#c0o(mriDDdjJR6ObU=;Xr2&gPqN_0-kZOwH=MQtsX=WoB-cUnB8y dW3n5EfMAf!nn#R>TRBB^*6i?z@O5CY1_0nG4B-F( literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hmenu-lock.png b/workflow/public_html/skins/ext/images/default/grid/hmenu-lock.png new file mode 100755 index 0000000000000000000000000000000000000000..8b81e7ff284100752e155dff383c18bd00107eee GIT binary patch literal 648 zcmV;30(bq1P)WdKHUATcr^L}hv)GB7YRATlyKF)%tYH6SZ6F)%P+<{wS~000McNliru z(*hb477vONgHQkf010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00H1h zL_t(|+NDy@YZE~f{$`WrhuKPySQAA=4|-5UL@Ysj^nd8hiS;2Kdj#HUllo z8f~>&*KFH9Nwz?Ckui3oR;%3`NI(gPUDtho|G}f2_3e8bT8ASerBbE5)1bTYdcFQ| zZM?C8k+I47`6u~>51*b--wCz*ER>uRr zeV-UkHLH%}72i$a+1i|RAKlWyIlu9^60fuoN4rrzunmYfG3Rj9y^HEzZv5(CEO81y zUYkzkSk-KQ`3%0SF=Q~vI7Aru=z0O7P{Z@#ja`PhX$8v2D-^Gzc;YIGcnR19E(0MI z;kZD@0aiO(XrN-PsAlqHZzKK#l1tJ_)zheV5(%VKYS5UK?$7C;0+>qp-G76P-YrWc z5ZrIlD9FnLDKc3)8S0<dA!cTgY+CR4-a*;u;!NrNF3LWTlP5a1_; iES|Z7@j-3=)A|j?vD&^)Yn&Va00007>1uYXA>3Qh}beSb(Ur!W`$ZoRvwlh8h#GSA{v3P9MZmob1&N}#H|)3 ziyhJ(U{)KHf*@)Iy5?}L)|RKuO{O%cx#h;IvM2X1`q0Jo18y$3o31q0)ZQR~04YGX zfXCOw7l;j1uOz`;`%xPF|1H(H=TQ-Al80O7c-*kEIp@ZM``Ch}Whn7a@ zEo{qiRYg+i%R z4h#&aR4TPvt$O^~PNy46p*I)|Mx)VWGFdDZtJOL&G4XSL3{j3aZnxWK zXJ;3eLR8p^IE^@iXhU=a0)b#Kw7t0&jYea!SUet2Boc@bilUOqB;u|J|M|xX6jAAP z03n=6?Mi(Dm?nrZ^SKu7#oi7Bm%1nSA1H5qaf|0_D`c0ZeXQSbMRJ}Wp^ujFWEojX z(Y1{1lBcW8em3h3o6B)FgQ$TZv?6jQ8yMxx;o>^&qx~ghy5ef_6fHB&ac3`cuq8MD zSbdMbr>J*|b@#!#g0h@qxe*x=qGVcHY literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/hmenu-unlock.png b/workflow/public_html/skins/ext/images/default/grid/hmenu-unlock.png new file mode 100755 index 0000000000000000000000000000000000000000..9dd5df34b70b94b708e862053ef4a634246acc8d GIT binary patch literal 697 zcmV;q0!ICbP)WdKHUATcr^L}hv)GB7YRATlyKF)%tYH6SZ6F)%P+<{wS~000McNliru z(*g|-5GqRX(wr!towOa3bz1}%hRS$Ze*UVXl27U>F*+kf-M;&k-s!`fDVCrZezlf>dy^3`BTW$z=L>EIW zO>?T0B!*En2q>u<@}12dniz6|2?Qm9qx{jpBiX~P{FQ(#@rTzxF``)#1i>x@j&6Pg z`g9}R!YZ+#Bpq}r3e{~P5}$S=h*)1OVUmx@SN9wqKg;4@^1P3fXJWAV73+q9*IOoT f&)vjR{Ezq!d`RXXnklE900000NkvXXu0mjfw|6I- literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/invalid_line.gif b/workflow/public_html/skins/ext/images/default/grid/invalid_line.gif new file mode 100755 index 0000000000000000000000000000000000000000..fb7e0f34d6231868ed2f80b6067be837e70cac44 GIT binary patch literal 815 zcmZ?wbhEHbWMN=tXlGzx_z#4mU^E0qXb33&WMKq(T?a&f@&p4150I4La9D7liGhiU G!5RR1hX@}4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/loading.gif b/workflow/public_html/skins/ext/images/default/grid/loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..e846e1d6c58796558015ffee1fdec546bc207ee8 GIT binary patch literal 771 zcmZ?wbhEHb6krfw*v!MQYQ=(yeQk4RPu{+D?cCXuwr^cCp}%d_ius2R?!0jBXnAQ) zOH<|l|Nj|aK=D7fpKD04vtxj(k)8oFBT!uNCkrbB0}q1^NDatX1{VJbCr|b)oWWMT zS%hVC ~NwO_yO%;SvZ5MdNYf|QNy-I*%yJaj+uTdt+qbZ z4E`Fzb8m}I&!N8OKmWEcCmrLs^Hs&3i)mt@hQVdcqghkaBs*D}tG_lKew4?rTjzIZ z9tSone1TS+TR7tu^CunG)Y7Jg#sw#)sG9C!c0I%LEzP)9;hqRf&)s$D8d5Db{TBs% zgl0~5QQ91luq4Q9tJgt4QLbaxZvAaKeCM9!oy85dg4k>TdBSVqjHub_PG=PO&J-rx z7oYTuF+kH|tG-UK+EkUhDjYx?zW?T|lx>+aOQm zzL$v$zBLo4Cj=G&tw{H}dW?tlTkS)SY4<#NS92z*EY-MMB6Ftp`R=*=*Ev7cS+X%W zMCur^FdlokL}1Y+&aasU2J4#EOuNlnb9CmqgLCGTSY!1BD42pkHY^XidQ5=>YQx%` z*%Pm9D!CkBu&tMWm(%-ejACVWGS2RX5=QOJ$1*tr7F}F+*-OA+Ly&Isg|AEuUYicA z#%IG6kPXkHt{zk2M6zK@Vu^4Q(1zE$?yY6M!^&jQ+2^E?!p7{g*|X6}vuRC3p@jk0 W117c83?+LXEZI4G$p&LV25SKE>nb+@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/mso-hd.gif b/workflow/public_html/skins/ext/images/default/grid/mso-hd.gif new file mode 100755 index 0000000000000000000000000000000000000000..669f3cf089a61580a9d1c7632a5b1309f8d0439a GIT binary patch literal 875 zcmZ?wbhEHbWMYtKXlGzpd-4Cei~rYO`oH1Q|BaXbZ@T<{^OgTwuKwS8_5ZeO|94#b zzw`S4UDyBbzVUz0&HsCE{@-`&|NdM558VEL!C+hQ;zA>HJFm1! z#)%1x%x&D_IuR=Z8kt%-g@N({4h;>A%p3w50S6iynb`#tJSI3aHnDO`7-U>H(Adn* Pui(%j;MmmCz+epk$!Kdz literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/nowait.gif b/workflow/public_html/skins/ext/images/default/grid/nowait.gif new file mode 100755 index 0000000000000000000000000000000000000000..4c5862cd554d78f20683709d0b450b67f81bd24d GIT binary patch literal 884 zcmZ?wbhEHb6k-r!XlGz>`0sG^=;33>fanOrC>RZa5f%c9KUtVTUe*B-pgh6A5y-&E zA>*-O!NDdb7MYkC1`iK4@=0rzWCSQRbnt4Ywd@dF=+rMIANR*%(jvDmG5%#TnwOp& kU}SchrxH17*#QO%<_$5P0_ncfbgjEYUKG8!(7<2~0Pia+WB>pF literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-first-disabled.gif b/workflow/public_html/skins/ext/images/default/grid/page-first-disabled.gif new file mode 100755 index 0000000000000000000000000000000000000000..1e02c419f5e73fc1ba5770df0448d44adf856288 GIT binary patch literal 925 zcmZ?wbhEHb6krfwXlGzZPfyRu$tfx-s;H=_udjFb@6g=b+}hgO*4EbE-rn8a-P_yS z*VotI-#=;6q{)*fPnj}h=FFM1XV0EDZ{Ga*^A|2$xOnm6B}gPhY%v@z$+dw{PFR zd-v{x2M-uV!Dt8!L;Mq+#E6<8x|aFW_O4e+3))3Q*|Q=94?bWMk!6jGP<+(r$fM>Xwqe7gmNr&4?FkK$jz>EMMFb>zJ~*Z~ zvMU=|C?p6pu`gocw@ENKkig96%Ptk5a9{xwcPOV4M}k2k%Q{v@i4+D0okN>5F7xql HFjxZs_zi%( literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-first.gif b/workflow/public_html/skins/ext/images/default/grid/page-first.gif new file mode 100755 index 0000000000000000000000000000000000000000..d84f41a91fca3a0ccc1107a78ffbf7b62c527afb GIT binary patch literal 925 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!N5_)V9X)ov0=f%X7nX_llo;Ppa!i5VLFJ8Q4$&%&Em#6pV(z;0OW5pDfG_ z46F<~Am@Pc1OrC}12>0^$A$$5o7t@;-Y_UNJMxKf6&W}lT+k*Y$eyJjc<@21kdg?` z9)m}X2f37ODg+`IICZeGskVGL@ZdlLlaQT?!H)&bz6?zAIR*(A8e5nhSgkHN9C*OQ m>dC5ipkT8?(+Va*AAy7q4&fY(0%9#)p=)k#W@Tbxum%8@3U^Ha literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-last.gif b/workflow/public_html/skins/ext/images/default/grid/page-last.gif new file mode 100755 index 0000000000000000000000000000000000000000..3df5c2ba50b143fca7d168d5acbcc4404b903ee8 GIT binary patch literal 923 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!N5_$V9X)ov0=f%X7)sh7DeV(M==$yO&0_YC2+|IvM<}Q z@ZbVY8B+}&lf=VK2L;XIwg}8jWa;H%bG(qjsCck}M+|z`(?y z1M&eVPcU$JFtBpScx+g3u$hC^!6V}XBXb*zY)A!1phGj4Fjq*7gQ62lFOR54M?r!E kLmQ{U6cz@-#wJD`MJWvdVWq}d0_-7oPHt8|*uY>70KTb0MF0Q* literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-next.gif b/workflow/public_html/skins/ext/images/default/grid/page-next.gif new file mode 100755 index 0000000000000000000000000000000000000000..960163530132545abe690cb8e49c5fef0f923344 GIT binary patch literal 875 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!NB3cV9X)ov0=f%W)9;69vKr@Ionu*A5?G{Hgn3DYJ|un wK6d5q<#D`_!KiqUp-ntt3Jb$U#ts%8MWY1*!jGC}2?&SWIk{Q=U;~3S0KQg&YXATM literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-prev-disabled.gif b/workflow/public_html/skins/ext/images/default/grid/page-prev-disabled.gif new file mode 100755 index 0000000000000000000000000000000000000000..37154d62406ddc064dba311b95f554e49ad38003 GIT binary patch literal 879 zcmZ?wbhEHb6krfwXlGzZPfyRu$tfx-s;H=_udjFb@6g=b+}hgO*4EbD-QC;U+t=4O zY0{+0lPAxdIdk5;dGqJbU$}7L;>C-XELpN*#fp_HSMJ!cW9QDDr%#{0ef##^yLTBz z!Dt8!oe)s`$->OQz{;Qlaxy4SFmU)VaC69bY*=uxnSOV literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/page-prev.gif b/workflow/public_html/skins/ext/images/default/grid/page-prev.gif new file mode 100755 index 0000000000000000000000000000000000000000..eb70cf8f6a3b7f524bbeb3656d875a823b27fd7c GIT binary patch literal 879 zcmZ?wbhEHb6krfwXlGzh@tC0DJ54uuo^j+di-h&|8QW#kzUrr(*H68ylXk-(>4ag{ zZHv4+cEz{tOYf>=ebOm>XHxXSuI{Hx{sE`lD_*51{Hrf`RNeQhe(3PuA-LgMaLe7$ z)_W1{_x-!R`FH*eYuz6C>RX^ z>V<&fPZnkd21y1TkddG~!NB3eV9X)ov0=f%W)AK)kBA8^Y;DZmPc|?ZI=9Q{X*oQZ zkbJD2lgIqQijPiCj2*mD6%7sx9yN0CvxS^laG;@KrlbJNftid9=jS`{vav8&0{~Hw Bh1385 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/pick-button.gif b/workflow/public_html/skins/ext/images/default/grid/pick-button.gif new file mode 100755 index 0000000000000000000000000000000000000000..6957924a8bf01f24f6930aa0213d794a3f56924d GIT binary patch literal 1036 zcmZ?wbhEHbA}e@6f*BUeEG-{mbu9UVeYtn)@A#A9pQ#+`IB&@5(0= zRzH}y`r(9CPbRH>G-dUZ>1!TLU-xM0+NU$tJ)FJ%!HkVh=4^U8ck{CaTb?f6`F!=h zms^g%-go-h&Rf5C-u=Dz!SB6~|L%M6=kVF*ht9t`fBVhRyMGQn`g7pPpQDfe9DDTl z(5wGPUi>@u`u~ZCzfU~=ed^KQvyc9qee&n@+yCcY{k`z?&xIF%F1`GB>D9kWZ~k3* z`RB^(KUZJ||Ns8~&oBx`LjW}d6o0ZXGcYhR=zxSld4hrCB?B{ujK>Cr zPF^XagaZi+ome=9Dmm#SD}7El7CSA;=KXekY^RG>e-{ zuuVYm(pR@|5zQ!{2@Y3s!WlFkEt+xRKzr=&*z_|U*@qgNWbB##KVWn?)_GXn$>4`} z#Rk5^9iqw$CMLJ{owi8Xkg$-crJaR6?!tz^#b0>Dw8Q57c+l9;Af%gcqV6G6E2r=p gYaW5X0}L(q1$Yc3_9+}>;A5Sv9e-|5r2~UC0H_cnr~m)} literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/refresh.gif b/workflow/public_html/skins/ext/images/default/grid/refresh.gif new file mode 100755 index 0000000000000000000000000000000000000000..110f6844b63f04ee495cb6260aadccc5c91f3245 GIT binary patch literal 977 zcmZ?wbhEHb6krfwXlGy$h}b9*vsWVToJh$rg~Ib{73bBfFRNEyRjIzARe8a@{G?U= zS=*`;&XtFqYK{lh9g^y}Bh~OmX2K7phHF|4mvmY#YBk-m>AI%V{Zwn}AFb*CO}Zah zE&Ol0{J&TG39p`WUhP-C+HU)IUUQmo-)qvfh`zI76Yqx1zV0&XfzSMxLGvGbFMQ~+ z=(Y3m{~l}q`>*>SwD@7vl2_py{zq>5pE~<)_MEHvb8Z#%9?x5TCvVmLlErrtmc7Ye z^(1@q`{eEa%QikQ+y0|u-~Un|+W)`u;QzYA|67+{YhHeP%Er5`D<5=iecZe0VgIfd z6ZSoyyYE@Yq4%wa{&t-D-*@u=lr#UQo%uiG{Quc!{>?l8fByOZOAkC-cNm zdAaJ$n+2EuFS_`D;g$bOF8yC{^Z%AJuQpuyyy5=;?RWm~z4m$Iga5mp{NMZF|DH$x z_dNZ7J^Oa?<^NmHzCC{Z^XcdR&%XSB{pru! zuYbP%{{Q3WpTGb9|NHkJ2pC4ez=eR~PZnkdh6V;5kP|?8f`MZl10$!5$A$$5)il%s zei$5ka6nGTs361eNrP~El!A@oXXa)eCC+CvI2;iHZM67s#E^NJN1wTgOT&i;3Ec;TOAjTi zTyP{|exu5jn1!2~IsF{O7w}9FI^s0Dv3!z%j9{}Lqr9=eiw8w24r1-;JbMZ*Iy$pR TTfCj3pwPfLY5NRjCI)K&rUX|l literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/row-check-sprite.gif b/workflow/public_html/skins/ext/images/default/grid/row-check-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..610116465e7e34fe6ec137d674a5a65eb44f3313 GIT binary patch literal 1083 zcmZ?wbhEHbG-BXmXlGz>j-2EYIms=0ihImdkJxD*ann5GrhCOt_fD7*mN_@JU|~Yh zlH}5*DP>F3%9rQXt#bJ9;Pl_AtZj8)e}DJP-90mRO_;lP-R7O^x9r-qeb1Jidw1;K zKX>_o#p_P2-*JBTzJq)AAKI|<;`aSlckaKi>)_Qrhp!zxeDu(fW5aL2&AYd5-M(@A-tF6WZr{0c>(2e#ckkc1d++>}M|bZ(ymSA_y$28PKYDua;miAv zUOssE@WI2!4<9{x_~`M2N6#KTe)9Oq(zkK@q?aP-hU%!6+_U+q`A3uKn{Q2YOFNRSt)Ivb< zCkrzJgCK(r$l;(o!NBpKL779wW5a@j%^bpFa}I1+c({#=)o#uSgQOPDOrxwjGt!z| zdt@$e$lSc_@o^LJpjAf}JZwJMArZPP=b&Sgps8HqqLPD`kM_zs`Roai*qqK|#L3VT zF?sR}KXId?9~w-oM=!LvF0}h7u%L13YL4V{2NpVaOx6sKXt0%-%sxprU4%n}F=ee| zk7OB3V$o4<2?NtNdOnMp+}aIPI1Cb!oedm&q`N#WDjn;2s@TV#Wb?^^L6Du@WzE4m zBH2;`fg2hOC%gI1Qk$u|ta4(CLnAZyojrZEhG#jire0bj>DOw0Oe9%D!a<-Z<>RHq z%WD>VO!l0r8@nULP;YPhBrdTFH4+!k**uiX3i z{QdXWpZ@~^!zdUHf#DSbia%Kx85kHDbU@w$^aLtQ^>)SRb9SKCQ``Jr`=eVAz{OT z183VTy}$iASS#R nB^X?DXxtttx-R#(S?*zGzsXrO9p?HCdj*-f<$NLv92l$th`d^G literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/row-over.gif b/workflow/public_html/skins/ext/images/default/grid/row-over.gif new file mode 100755 index 0000000000000000000000000000000000000000..b288e38739ad9914b73eb32837303a11a37f354a GIT binary patch literal 823 zcmV-71IYYGNk%w1VF3Ug0EYko000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui0096U000OS0Po$iSC8I2dGX-ATgb4XLx%wY06VC` Bj$r@* literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/row-sel.gif b/workflow/public_html/skins/ext/images/default/grid/row-sel.gif new file mode 100755 index 0000000000000000000000000000000000000000..98209e6e7f1ea8cf1ae6c1d61c49e775a37a246c GIT binary patch literal 823 zcmZ?wbhEHbWMq(KXlG!!`QrEOm%s16{{7(1pGR;1JbC};*@r(bKmL9F`S1V#{~1QX wXb24J5K#Qd0`%X11|5(uL3x6KLxe$C!6IP+Ln9*-6GOy_4GW#y85tR@0bQ{sTL1t6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/grid/sort-hd.gif b/workflow/public_html/skins/ext/images/default/grid/sort-hd.gif new file mode 100755 index 0000000000000000000000000000000000000000..45e545f74423d274d5ba7fd942349e9b6e377787 GIT binary patch literal 1473 zcmeH`Yfn-E06_1O8OuKCZ05?;9y0{yY?;~WgRMsR$~K$2`D~d1@}bQ#*KE^FOzmNr zk4h0m5xA%*2nq5&mj9jr&@R9m?MLJ@ z28+?&*i;q2X{glmbaXwjt9hit_dI1))x{ir6L_uMFRHs`tO}FBO&#lQRo8}|J5?7Y zU`>9C$Th8w3EHL`Ba086h!(PEnZzn=+PIK2*LI5;-9YgM=D}nEMKj(5E_P-Pm7jo~EXPhgm4T&wVplL(D->;y1`B0^KR=R4S}*a1vj)fV>NEY1mB8Uq&zYI6Q%t`{**z!J+Vr;E@5~g9*=aqW{3>u}nt)+%y z;;>ng6u?b5{(;L^(y<6nxNxiv6hU01L$+fA6FPrm&HQ1X9CMc{2sC$3gd=9b3;|~m zeo4%+^eknA7SU=RVi9X;xUJr+UX-mqm<4W0%pznE9#Hd|0*@ZIv{eO*Nb# z12yCIrOhLLJlbn33DTB}t(F_b2bV4~y*j=}%v9m90(t13QX1^b_==P$D+H{5*5Mu? z8gKY>BXXf^7@!+sCzFj+>XgJsqfc(1Ya(r=#J=3 zlZtj9{~(p*xA$9X2mMtN6e0bM#^36uHAhJ9Q&;+@HQ_ThCJ=yPPcaaStzMs1DHP_0 zvw_E92pgO+s83$0SnZp{u*pvQ$A3#Rftg(VD(=52XCTzUftd4T-22$PQrgIR*gHx4 z{43C_yk?5j?(i$Mual4dFf?{<9Wn}qfaB%>iNwkdu&q!m&h2IcZ$2Th!C8}<*_&Pr zyKl`OZw8N)3D^4?RK}UoD=o00gbKYHy=yv32mZ9Dl8aIS8x^Z$2?NwcBLzFmZOtoW zzN62&u*QDIz{Fy}^YAXY&Txmg7ATSAhAr8K5fZbFZ*SFa$_qE2L|VVFHOI{wKE8B_ zGXV2p-56OO`rc4Z7g3zbj)2_3YjK$((`OUqD%*mgvS`YELYsVW1or1)YW%;)D$oE>#r zQ3z|D(W$Eg`c?NY^+fD&+nctrc25@u47U__J8-QW7NqK!$T9C@*SpuaHyFRRpIGae rj_Lao#za}+eaj_<`F9!mRdtBiaY8;H`0o(Vu;KK>|7RZkKlk|m`6vG`Jo$g|>HkYl|6hLg|LXJq z*I)d<@$&!8m;Z0Q`hVy3e}+*o8Un*81QdU=FoV3K10q0qf`LPwfssSTW5a@j%?wOD iArS@)&h5PNMll*66^^tBbH?qtQJ{FJU!IwX!5RR^E;%az literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/expand.gif b/workflow/public_html/skins/ext/images/default/layout/expand.gif new file mode 100755 index 0000000000000000000000000000000000000000..7b6e1c1ef82bc36104018936848c3ebfa6e05e6b GIT binary patch literal 842 zcmZ?wbhEHb`0o(Vu;KK>|7RZkKlk|m`6vG`Jo$g|>HkYl|6hLg|LXJq z*I)d<@$&!8m;Z0Q`hVy3e}+*o8Un*81QdU=FoV3K10q0qf`LPwfssSTW5a@jO^j@6 iCK3sWhnx8sU0hxiEIiaD!s-`t;^Ttj{VdE(4AubXYdZG; literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/gradient-bg.gif b/workflow/public_html/skins/ext/images/default/layout/gradient-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..8134e4994f2a36da074990b94a5f17aefd378600 GIT binary patch literal 1472 zcmeIx`%jZs7{KwDTLnZd*hMh7R3%&{VK|xh5d@TrMjeTpnq?_&b8`}Bh(kowLJ^R= zwLrP_Mz6F*N-1{`N?)K@6i}uD1>V*|OIv8)A|*;9JN<2c#7;i>=A7rpCpmEmrw$)U zc7mcXc@UIVGnG~gOy34*)9Li-becMyuD$~>)ERVj219+9F_Xbm-(}8ZvefrjGxzFd z?gQ+Z2W-&U2kcoQXO_sF&Em{uap$rD-W-Vsija6n4j*~Q*W?J0hYp%tpk9;bpv@I( z@`Tz)B2B(fn=b+vZGl)@(4Z|8YYQ8+MGfzZp1v;z8bNg>jk*$vu2iBclgyVj>B^es z9|O{PvUGvmyzs<9PmwK9WcqTTMPJ^kuV~R%wCXE?Ha*qBP}OFjwi~K|4nuYOVl`;T zVhzx_SPOK48f&|ZG@#o^cQDa=jErs*qsPQ}W@7f3n4r(hETGq1*K1~j_Lq?Dr%LqcFxvPW zut}by5*6B{LZvEO(+Ju$Vv_!sOuZvAc4ePkK}Mg^X|R8{wv3g3jV&Qm0~*o(w;!4zGtP^}q4TE3f=4jcq2s zNTj41IT7{z(FAgK^iIzZ@_2j+Ir8!+!Q#r@%9(ju7k_5|Ghf7eqx2?7%YoH4jP!wx7HA*Q43) zwFOW=pP6ly3pn=?dHpWVl+z~h4aA7q3Dbmfk>A9h*D=1j0=ZkaJtNDl4|Dy58=OQ4 zb=w|rEX#G|6q4dPk_gFV6VcYbmUmazi7x6i6Xb&As-j$U2PJ(S9-JDYvw05^=DZ2M z-q(%65iC7!Sf=Hfs~2MFb#cc_ASYbPO$Z9ewDx-)GFuhcxKI?v{g{Fd`2H?N2mNoG a(II?Zs7)DAnPM9b=8J95L)rdV=-9sjoxm#q literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/mini-bottom.gif b/workflow/public_html/skins/ext/images/default/layout/mini-bottom.gif new file mode 100755 index 0000000000000000000000000000000000000000..c18f9e34ac1f4d06525592c5ec25783921e7ab1c GIT binary patch literal 856 zcmZ?wbhEHbRAyjhXlGz>c6N36?{M+r#W!!>FpPrH5Ex-0p!k!8nSp_kK?me-P@Z7m zFlAunknz~C;9xU5Gl#^14GRyqF(|p!cuZW_z#t(WR-;k)_;9y`aa9RNLW=VQMPsFy Kokpn+4AubBJRUOu literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/mini-left.gif b/workflow/public_html/skins/ext/images/default/layout/mini-left.gif new file mode 100755 index 0000000000000000000000000000000000000000..99f7993f260b374440c5c8baa41a600eca99d74d GIT binary patch literal 871 zcmZ?wbhEHbWMxohXlGz>c6N36?{M+r#W!!>FpPrH5Ex-0p!k!8nSp_kK?me-P@Z7m zaA9EP;893e(9p!fE+S&!pm?~AUD|4jgy5sYono4CYdSV2yD|teHi#$`Jzc6N36?{M+r#W!!>FpPrH5Ex-0p!k!8nSp_kK?me-P@Z7m zaAja+k&tj`IMB$%CgZbW!-Ix)HhHZSi@+q84iWvZBN>K^-5Dep8%#8W7*0-Pa>$EW bxpC?7J_E~BDJKIG4z;p#3-JgDFjxZsq+}v; literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/mini-top.gif b/workflow/public_html/skins/ext/images/default/layout/mini-top.gif new file mode 100755 index 0000000000000000000000000000000000000000..a4ca2bb20aad89264b9022fee88ee29154dfb192 GIT binary patch literal 856 zcmZ?wbhEHbRAyjhXlGz>c6N36?{M+r#W!!>FpPrH5Ex-0p!k!8nSp_kK?me-P@Z7m zFlAuo;89qx;9xU{u$s(?fCCNf0?JM-3L76eGxBgot>IYk*sW87)#{JM#>MWF#5uKM LPHswdV6X-Nu*4oA literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/ns-collapse.gif b/workflow/public_html/skins/ext/images/default/layout/ns-collapse.gif new file mode 100755 index 0000000000000000000000000000000000000000..df2a77e9cc50cdb15e8be856710f506d462a9677 GIT binary patch literal 842 zcmZ?wbhEHb`0o(Vu;KK>|7RZkKlk|m`6vG`Jo$g|>HkYl|6hLg|LXJq z*I)d<@$&!8m;Z0Q`hVy3e}+*o8Un*81QdU=FoV3K10q0qf`LPwfssSTW5WW+W=1|P io&z5e4!5x=GEI;OeCX1}EU(tHE{jAJP4AubO%sO%a literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/ns-expand.gif b/workflow/public_html/skins/ext/images/default/layout/ns-expand.gif new file mode 100755 index 0000000000000000000000000000000000000000..77ab9dad2948270706c9b982c5fcdce78940b4c4 GIT binary patch literal 843 zcmZ?wbhEHb`0o(Vu;KK>|7RZkKlk|m`6vG`Jo$g|>HkYl|6hLg|LXJq z*I)d<@$&!8m;Z0Q`hVy3e}+*o8Un*81QdU=FoV3K10q0qf`LPWfssSTW5a@jjf_kR jAsz;b4DD>fMm823AG&mK%ZJ76*!b{ZzXCfO3xhQP{>?dp literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/panel-close.gif b/workflow/public_html/skins/ext/images/default/layout/panel-close.gif new file mode 100755 index 0000000000000000000000000000000000000000..2bdd6239987b95025826fa39f37a036d73ae1c9a GIT binary patch literal 829 zcmZ?wbhEHbWM^P!XlG!MGRSrK@6dAaKf@>(4S|st0*XIbm>C!t8FWBi2jvL{4k-pk f4i1Na28TvQ9=?!{4GD)^*u|AnEG{HEFjxZs3+oT= literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/panel-title-bg.gif b/workflow/public_html/skins/ext/images/default/layout/panel-title-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..d1daef54c578cced19b7f0c3074dd7a23d071cb1 GIT binary patch literal 838 zcmZ?wbhEHbWMoKTXlGzB%sOhAecUMblu_OpknmbK5V>R(wmyk!^#qaiSiLO}5+3(z&}UbNe&Fw0C0UOPyhe` literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/panel-title-light-bg.gif b/workflow/public_html/skins/ext/images/default/layout/panel-title-light-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..8c2c83d82536f2e1e8c1fa15ccdf6683047b1d34 GIT binary patch literal 835 zcmZ?wbhEHbWMoKUXlGzJdGFVm`@haV{B`m1uPaY~Uw`)d){EbFU;TOT=Fj7|f1bYo z^Wx***Ps8s`}&t*6pV(zunPgjpDaK>{b$et`3#gN7&sIdqzxh#C@?lLvvCPXC@3&A WvZm{QhJfNv7G{tF#eZVXMX8A; zsVNHOnI#ztAsML(?w-B@3=BFTX;5xq;Lv4YLV0FMhC)b2s)D9)qBYY9s=7v2nHV6X-NX@DCv literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/tab-close-on.gif b/workflow/public_html/skins/ext/images/default/layout/tab-close-on.gif new file mode 100755 index 0000000000000000000000000000000000000000..eacea39b623348f656de9a8f0df4ac4b74ceccbd GIT binary patch literal 880 zcmZ?wbhEHb)z|%kKX-x z_TkUV&wm+4!Dt8!#}H8b$pZA&e+C_p=RkRafy0-9okPYWK%u#rLy#**AmKn$J2Q)p zz={Nh21Zf+FqsJojYs=sS(PMy7OF5cvh&sKnGv+0v0q<*pG<%Q!&xR)rDrk@3zqxO MXKm)=;9#%@0E9$42LJ#7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/layout/tab-close.gif b/workflow/public_html/skins/ext/images/default/layout/tab-close.gif new file mode 100755 index 0000000000000000000000000000000000000000..45db61e6000bedd9a4eacdd171d99a9af159389b GIT binary patch literal 859 zcmZ?wbhEHb+a1fq{uZ2jn48o?zgxVBqGE@d#MZ z(99ty#S`H0kb#knn;}DEVv=)*u)3Vdj=;yqxu0#kX9cC0)w0klmAo1XIMn(o} E0NP7EbN~PV literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/menu/checked.gif b/workflow/public_html/skins/ext/images/default/menu/checked.gif new file mode 100755 index 0000000000000000000000000000000000000000..fad5893727ee8a13f428aa777380ae97152adec8 GIT binary patch literal 959 zcmZ?wbhEHb6krfwXlGz>j-2EYIms=0ihImdkJxD*ann5GrhCOt_fD7*mN_@JU|~Yh zlH}5*DP>F3%9rQXt#bJ9P}a7(ufM;0=I)-EyC%%tyKeK&xyuhMUUy>sj`JIKUfjO_ z>dyTab{)LB=kT>-Cr%wbdG^%lGbhhnIDP)=+4C1qp1*tM!nLy(uU)-*?dpv?S8v|E zb?f%+J9qBfy?6e~qdWJX+*RNl{ef##~$B&;sfByLSi(wRuh5*qap!k!8nE{v; zbU->ld4hps4uc|xjK_ur2b)<{HDXQ_Japi6Q1W6iYUvPA5Rzlscwpk<4sO9XmXjI+ zi&_OWe7|@wG&BoL67X4M6R7Omz-DfcwPk^l8<#v6OGU!M%_;%{ss?XfI5Zp-5OGar zYW(QXz|GEX#*rx~s>CVD%q0^Mz{1hH&cW`(j0A>8wr;ZvZ4rjePOb7*MGqXL4LK$% TI;tJY@rY17bXb6iiNP8GS6tA5 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/menu/group-checked.gif b/workflow/public_html/skins/ext/images/default/menu/group-checked.gif new file mode 100755 index 0000000000000000000000000000000000000000..d30b3e5a8f138bfbbfea3d1d6d5631a81268fe26 GIT binary patch literal 891 zcmZ?wbhEHb6krfwXlGzxGAUp-FJv++Vzw-1u&!ctt7CJoDF4C-YI>17M;4q>erj}J#1 znRLYtaeQ=iW)bC#?NNBB=*-HhDWD|4xae>zCoh|V$$>=XHZB1n7Kal~O{`q}VgeQu b3s{-ixj1G-bT~0I2=PqTialkbz+epkbq-F$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/menu/item-over.gif b/workflow/public_html/skins/ext/images/default/menu/item-over.gif new file mode 100755 index 0000000000000000000000000000000000000000..01678393246989162922ff0051d855ea02b4c464 GIT binary patch literal 820 zcmZ?wbhEHbWMU9yXlGzpb>`d67r$SB{>v~5Mnhoag@EEu7NDp9Gw6W44$2b@9D)q2 W95Nmo7Bnz$2y4ZhC`fc*um%9+ToJhd literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/menu/menu-parent.gif b/workflow/public_html/skins/ext/images/default/menu/menu-parent.gif new file mode 100755 index 0000000000000000000000000000000000000000..1e375622ff951a3a3f1ccc668061e81b9c93b411 GIT binary patch literal 854 zcmZ?wbhEHbOQz{a2h@&qVP zFmM<%@JmQ|Y*@g^%E=?8;=tJG)Wo9VlknjJLnFJO0!M|%0mo(rQBEC(fQyeBCb4lX KFcA=7um%9T95sFb literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/menu/menu.gif b/workflow/public_html/skins/ext/images/default/menu/menu.gif new file mode 100755 index 0000000000000000000000000000000000000000..30a2c4b6c0458751f85126e8bbca6ef2ccc2ff00 GIT binary patch literal 834 zcmZ?wbhEHb{Kde?(9Xc{=<(wZA3ps5|DRzLjE2C-3jxKSEI?2HXV3w89h4^+IOG|a lIb=LGEI8Q6z#`0voy-@k72&h=Y%ZQ8zP%g((!cJJT4@8F*OhYlV-dg#cp zW5-XNI(_EM*|Vq5Up;&A+S!ZOuUxr$qNpFDl?^y$-QVDS9;ix)3mg1{>fcnt(^ zUcUi>w{PFRfB*i&hYz1Vefsj{%h#`8zkU10FbYOPfHonZ_>+YhWU>y30Obh=jxGj9 z4jGRP3l283GHb+~D0p~)!9>Yxj)(FAXDKG5ESZ1@4oAD0WI9R=9v*6Ak!N+{dHKMR zl}FY^$AdFLm4!>ptVN@75u5?#BR20ya;KC(goN;9V qqtnW!)kYaNB(j|}n>i$H<|I5^)XKF~L^CSn=7x7MEgZ~D4AuZjXTU80 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/panel/corners-sprite.gif b/workflow/public_html/skins/ext/images/default/panel/corners-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..aa0d0ed8fb4a7af14a00f77c9fb0f456144363d0 GIT binary patch literal 1418 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 F0{~gSY2E+; literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/panel/top-bottom.png b/workflow/public_html/skins/ext/images/default/panel/top-bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..578ffb6092a47d9af33fd86615855ac328958537 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^j6kHr!3Jb81>C#}q}WS5eO=kFvq*AsijL3o~JcpmZ-+$h~ z_Wy_3jh&1fGyeT$7yAGIfBVLN2O~0szQ_GbNqF=$At@m#iKWOT4w?3V`{ps}G&u8y_K7ar7g$G|QJ^XUz(U+@FzFvR&^~SSrx1N9d{QdWj z-+%u9|IaWAMnhnTgn;5t7G{uBbwC6tPcU%&XJBNJ@Yt}xfl*RO%SR(2fsIE%+3C!K zfJH7{j7BjxP82F1;}LV};`zC;>EvWJ`=E%EMNf}&8YCb3qp@(=*;(?+FYc`TtlTo+ zp}tPWVT;DaewImEzP~m$Twd;HFEzuf^wn|Zh|NiVI~J_IzD{1aLst9S;-<|R=j&n) zY}38n&-3V1@9&L`cXyZBTirNa{{A?712gkCNfC{QhXnY zwzDg8A8&6~zAsyC`Qh2A#m@8R-Tqnd^6EzM>veOgi(cJ6SpHx9zpZuUvuBsv!|mtQ z{`~sk_VIfC{dRwUzj*$9`+oWV#ozz3{+M6K{3(1v{q?!!3mQ0?c06e26_QxkD6Dkj zcI%WyT+_vK2mMcNg7q+sp IvM^W!0LCzFhyVZp literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/panel/white-left-right.gif b/workflow/public_html/skins/ext/images/default/panel/white-left-right.gif new file mode 100755 index 0000000000000000000000000000000000000000..d82c33784d106a699921e8186376adfe08ed7159 GIT binary patch literal 815 zcmZ?wbhEHbC) zJaOyO$=jb!-~D{{-ski8KVNw8<p u#Ky(P`xTtKWIQ)5IXPLwHYwudrlqH+8zi5aADi9QnH9n_(1;hQKfi0UeNEKzV_IL!CjML&jsnf`iQ*+*TO}5*nMB cm>F0E91a{{WZ^W*x^rUV;^X}?%uEc{048uWPyhe` literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/qtip/bg.gif b/workflow/public_html/skins/ext/images/default/qtip/bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..43488afdbd4924057e45df94ed68690068fbabac GIT binary patch literal 1091 zcmZ?wbhEHbvJG_ z_wB{IZ!h0}dj&)vzP|>dkKf;X{QmaSk9R=y`N#XuKRjL%gg;OJ?2_%ZN9oX+&1IxF3}_H>l603F*t71i4@GZyiE4sw%lkTl{?!^ z6Bo7I-L2~P;_hzq*8BVGLsu~TDQ|svxII!MZqJR@$6^zdt>?XQDtdZif@HSanM&4& z=Nke$o_R~@-`i0Xygcmmtu?PVY}k3~nAhx8xhrg)|NZ;-|Nno6Q7{?;gDC_Qf3h$$FfcOc zfE)$N6ATu z!(r;m%j_$9KP-wo!oMF4bR^Z#pCLVEt6JIYJY>r`(GBHu8TKMAH hV%craN*NY1aV$`Fvrs8ibZTIkpzPfzqoBZG4FEi-n5_T+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/qtip/tip-anchor-sprite.gif b/workflow/public_html/skins/ext/images/default/qtip/tip-anchor-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..9cf485060802498647ba462c826869140085778c GIT binary patch literal 951 zcmZ?wbhEHbRAb;`_|Cx4x9Z%wLw6p$`1JJa&v#${Ljc1l7!84u5dw-oSr{1@*cfy` z-Ua0e297BVyc{MB2@4t-nK?8-AM7;o6g|H=X=D(-<8}9T;jWog=1UD z4&$fCrm{73`D9*Nda=)=)Tw8u>7xs+o|a)(X9%W5PEyUaQmLAfdV6NU**cdOLJyDZ LX;5ZkVXy`O9&A$y literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/qtip/tip-sprite.gif b/workflow/public_html/skins/ext/images/default/qtip/tip-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..9810acac5b323d99a641627276e8dbb9a3607d2e GIT binary patch literal 4271 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shadow-lr.png b/workflow/public_html/skins/ext/images/default/shadow-lr.png new file mode 100755 index 0000000000000000000000000000000000000000..bb88b6f2be887650f28b16726e470c09459b9c86 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CG!3HG1zpHNqQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiZnf4978H@C8Z=JJZMPDQ+U>TNx_ce55uGN4u2%Q{wE|U g2=cJ=GBC0+@aVFNEX<$33#f^~)78&qol`;+0F-4Xf&c&j literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shadow.png b/workflow/public_html/skins/ext/images/default/shadow.png new file mode 100755 index 0000000000000000000000000000000000000000..75c0eba3e101e3f32cef8bde7bae7383d849e935 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Q+l0V0jwbN>KRk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XZhE>nhE&`-GTD~D$v~hjI>0gT@Uw(Rj}ARr(#+ZY|Nr|R ztz576{))TQsGN9FjsN;R=N;cX_7>}LNxZmoT3OARN%FUXp-|AVh0k3k3m;=qQcOOgc@EIAyfV(r;i((zEeg z`}y44S?ng!NoE&wcK=*_2F$s1%jHel(|yj_4>tF9g$FFYCZ&0@DQ;=K_|9xe0dH@S zX*Z%4Z8@@VyGFIRewDnzd#yOua)FIqa}4Vg?=kT(Xhpeh(=cjy2J|F@r>mdKI;Vst E09T24*8l(j literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/blue-loading.gif b/workflow/public_html/skins/ext/images/default/shared/blue-loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..3bbf639efae54ae59e83067121a5283ca34fc319 GIT binary patch literal 3236 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 JpNE6N8UT=&&-wrW literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/glass-bg.gif b/workflow/public_html/skins/ext/images/default/shared/glass-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..26fbbae3bc6d2510832a5ed709f0cb029c2c1170 GIT binary patch literal 873 zcmZ?wbhEHbWMpt*XlGzJe&g*4AiDYX)q+w@6G_xop)#NygPUI-MM=} z^!_{$-T!dm{)dbAKU@Mb9(=g)@WaK2A1*!oaQVT<%a1-@ehfsPt~~sB_0h*Gk3U^| z^yxZ~`{dJA5c+)e>E~-e^z6&^=U;C;`E>K?=UY!d-+uP_&hsxfUVOdx;_KT_KNv>A zXb8|f1QdU=0PXzGpaZfQlqVQC+!&%a1WaT)$|)>om2)9Mk%@&tK#^^Rgu{V`ZWgW# wlLCgu<17lIIuQpJG%~aEtN6@tSlD!$TihV!!H0*;9Rf;j6Erp|DKJJSK2bm`zya0vPFVPO+Hzo=EoiUW<# zt-R7&85aT+o!hu13_^AkENo)sW?~Im5RiDNg-b{!q(fjK6AOo^oXv^{2OL}3c(n`? z0um24adC-+cuZKp#Ka=XC$l2qfI}-2tCoO5K;nT0E+&=`4uJ(sK-Uz9X;c_IJk-Xo z?6;=E@bR%edFMWzN~5Qzrs*f2TT>bQ{@gtKWw+(i!R!IjKB)<%j$y1Z!Zof6-y9;DGq~5NJ}7gDVJu-S5NBXy HWUvMRItY+| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/large-loading.gif b/workflow/public_html/skins/ext/images/default/shared/large-loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..b36b555b4ff04f841bb2101514d8f95bcf7358f4 GIT binary patch literal 3236 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/left-btn.gif b/workflow/public_html/skins/ext/images/default/shared/left-btn.gif new file mode 100755 index 0000000000000000000000000000000000000000..a0ddd9ee8203b9fc45eb5ee78ae6bcb7e57aed7b GIT binary patch literal 870 zcmZ?wbhEHbSKV^zd-BO3vC604f{{R1d4Yk$n}L-sZYVSj)zmI o(Q}fL|Dq=uMNdw3X~iE>$=vYlK$lteqcf2P3=A_Zn3))?0bn93t^fc4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/loading-balls.gif b/workflow/public_html/skins/ext/images/default/shared/loading-balls.gif new file mode 100755 index 0000000000000000000000000000000000000000..9ce214beb5cd4db00666778d371223c605874519 GIT binary patch literal 2118 zcmbW22~ZPf7=}Y29Kir0FmlXvp;AJNF@T|n3=l~OQNReX(lJsJSV$lTCK1p9Cy_(M zQm|OSsz3m3sz4Eyf*^8<#%d)Dpydoi0>~kDK!ll=ZaA%FI-`5dzq{YQ`#%5s?JSAx z1lbx&?h&&9gFi*>!1pzUs7{@wn9`hLm1fx>(Jl7@kz#sNtqbnGu~ zQe16TTxnMP)H3+<{h@2EL)RY+mC2N450&LIW#wqY$lA~nbxPa!&C zu$mg`OY>TK<}eSK12l%IF?DpG!V-0@d@BkYlXMMpg0lep88I%nH28pK5h2~o?kkh6 z2b2xQChiFj0eW(#g;VTwwMJ5_?EDvp>#4GK+r2+JC89@-_OzrTH4{qP8k0!hnWK}9 zap_c+yqJ92gY!};(l)Zfx*I7zMHm#j&@PQG;7HGJgfynxUXLv`)H1{Pg;t0}hNdo2 zEzCw6`;fZ{f2sO<=B5-4@O@rsqC&BzvE4Uy6nRmKzwG>WQa)|oDe}n~loonAD-5{> z?UL_)*}^8e6BlB4$-lNLQ?wCd`#X$Xp*I-B46&`*HeU)u(UfY42oW;RS(7rB(NZ(l zVXa9y3Fg@)|wdEu-^Mr$bM<2lcshb1_0+qU%7*YY5d4R}04b5q{6gDK#lN_Yz+3 zA)Yn+Y!&vbrDwhDx#Nq+`TkLUbU3j!TN`d7b-gn)W>MmQ_}fG`$z)HJCVV5zccWav z)VK6731;9=Y1sl!Lg@h;g8AmhLs23E}Fg8bsA}jW84be zJj3a&!EX+(#)=!^aPHuvE0%9D^z0oWQl`8qV(5Oxp*_o)rkOg&mhP%-u(0XS@f3?_`nfh@f|7!XJ# zk%OqjKq3JM^2G-d4?(;7)p&sbDCoC_x zFgMyk0aQ)fOAm{tLDLuoh6x2UK0R(bi$jkD1vEB~9?s%M(#YylM@%FuVp#;fssZ~@ e5vO$#&5sswUKi2&Xpx=kB8ZO`!7YivcK-uGv{KRl literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/right-btn.gif b/workflow/public_html/skins/ext/images/default/shared/right-btn.gif new file mode 100755 index 0000000000000000000000000000000000000000..dee63e2113fcca680699455e8a56ee3eecc81c40 GIT binary patch literal 871 zcmZ?wbhEHbSKV^zd-BO3vC604f{{R1d4Yk$hk=zr!efJiBO@aVPsE804;fk*WxQe}6c#pgOBlzkIk8cxsZYUC>4${T q6OT!%mh)U@eo8sjryPH%CUe8H16^j>kIqCIFfh!NVPs)pum%9ETq}wI literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/shared/warning.gif b/workflow/public_html/skins/ext/images/default/shared/warning.gif new file mode 100755 index 0000000000000000000000000000000000000000..806d4bc09385a98ef1ac19d25e30a21310964e7e GIT binary patch literal 960 zcmZ?wbhEHb6krfwXlDR{f&hVn2muENhm@owhyM-@5dsqm1SVuCOej#8P@%A(LSO-q zY!KMcp>SY^z=a6{7Zxa7SYhyB1;c|43=ehyk-&!?1`l=wJUAfm;Do@30|Fm_AFI_r#;p+LTS5IEMaRKbDQDQU%2#0{;PZnkd237_gkWx^dVBna` zz|A4!v0=eMCPx*A6NM8NOc1gSve|KQ1H(iiYYu@O7ZQ#gR8*}I_~Dqq(8*@R^@`(W z@)HIIWfz?e!wVeVa#HbKFBUvx;Axbo`SPIg5jz8ey-mRe1I2~|N`gTPEE1a-8hE@l zIU)=NI+%skoc{dSsL0&PpvCnl!Qs*I)AH$&GFuihv|L@Lt98xe!$KzpaZ%Pw4hauj N9~|!BW@BNn1^{&szCZu~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/e-handle-dark.gif b/workflow/public_html/skins/ext/images/default/sizer/e-handle-dark.gif new file mode 100755 index 0000000000000000000000000000000000000000..b5486c1a95bcc0f39a88c15c10c04ef7c3c561dd GIT binary patch literal 1062 zcmZ?wbhEHb#gW zSa7hJLs%>3#D;~3+Xa-p=6GyebhKN-IP1=djf;=>D>!$_cy3y9a}Xwye0g*kiI*?5Qm)FE0;R>^0YG>#D1(BQ|H< zJ+*c9_4NsdyJWq$t+}~5+bHZ`26bb>Fw+9?{8q{mh;)M z;o;#9VePmxJJK5%IOMqVHRPj^sIT3W`5a^n+Y$P=Sr`RJG*P^>+2hm zPtWt+z3uJo9mTKjo!!0t{rv;Y-12^Vc6@w%VzPGpxjj2SKfkcpd%oY^U0+|{*qnX; T+}_>a-#<9q&HP*pKCAv-hK1$|Ns9CqhK@yMn(uI{$v4q z^gn|R$h)9C!NBpKfm=XAL80MbGZUwri^YZqhZs0z^?H5?BpvP&kx!db5t!`W$7S2b zqB-%Q$7EIBJeSUo%H9(-b?1e=ob=3RreXN4Gm*mSr)OK$9{O`qIOF^RkA5xFQ(IO9 zFA8Y)Qk9(g>dN%6%}IB6ZPp537_~c2R9fuK^(DT0C)w`)@-kv`_TxiyyRYTm+?Dlm z+u82#x%YQh|7ByF6IPITsO+X(*qn%W@yBY|oz3n@jiJwDpWpD!D2@#*RM zbouaqd#t{`KC@K){5zTIFYoRwZ~uS)Uu;d~r?Y35yRVo1RrUSt+WvO_e>SyWKknT> zJ%9fHy1zfqK96ts%NTLLo=K|Xej|%gL_(8*oyNju5wi@%W(mC&iq(=uJ08}`wQ)S^ zU@r4m)TA`+$HFenMHNXcqO(ps>K2aMv8dblS;yl(gIhO}`i(wCBu{X-7xARuS!$-r zBtxy6DwFLl{a7+3@KuG%R2RL@rISOsESFA=YWlf!dTg9#+RVgBGoQ{#TXpj3tc*=F z(`J{P%UnLE;@C>{IW_xUs!yq9`t^KTlbF|wh3RZvD`vN;S*=*yYqTq4ZlxC2%O&OS zey&(Dz3kM>?LPQFywyoHAYVDT0ajVyEf83S5 zYUk}~v)}G~z3g<}j<=J3>+SdwC9S{f)2`L|`~Ez7{eCaQVeNvw_itHmILNZPy5Jy> z_M8uUINa|T91(v1`~4w4?>U7>|FZqra8xea=i@Pz{v4wd67%mAp3VHu<2 zhTV5Ioz;IFV|>wdeI5}aFh%{jYv+pP@iy=AuwcHjMWHRrml`Q7q*+i$mvZu8$Qzn3`O RcKf}i-@V(HGcqz*0{{svxFG-l literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/ne-handle-dark.gif b/workflow/public_html/skins/ext/images/default/sizer/ne-handle-dark.gif new file mode 100755 index 0000000000000000000000000000000000000000..04e5ecf7d3837aec9510f5467282c10f158a5563 GIT binary patch literal 839 zcmZ?wbhEHb+Yh5$94ZWq95Nmo l794Em;N}uwNKib;z{ui|Vj-Z!(9Iz$HK#)0@qq>gYXJ2^5-b1! literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/ne-handle.gif b/workflow/public_html/skins/ext/images/default/sizer/ne-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..09405c7ac7b321b3eb9170b1584167448819a071 GIT binary patch literal 854 zcmZ?wbhEHbc63}qqP#3eHjE2L+1SS?XB|ZfS0S0RTeD^Ni literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/nw-handle-dark.gif b/workflow/public_html/skins/ext/images/default/sizer/nw-handle-dark.gif new file mode 100755 index 0000000000000000000000000000000000000000..6e49d6967c08db2c02a3aeb9c1f3cacb9c8665f6 GIT binary patch literal 839 zcmZ?wbhEHb+Yh5$94ZWq95Nmo l794Em5abeINJw;KWMp#S2{2G%=w_Cco6{kn+|a;a4FKuB5a0j+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/nw-handle.gif b/workflow/public_html/skins/ext/images/default/sizer/nw-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..2fcea8a9285dc74626ba9374055b25ab77e53a08 GIT binary patch literal 853 zcmZ?wbhEHb#gW zSa7hJLs%>3#D;~3+Xa-p=6GyebhKN-IP1=djf;=>D>!$_cy3y9a}Xwye0g*kiI*?5UEB1_q}2ZmnDnS(jHwY|grS zYU}Fj>k|%l$$D>Fb8~aX+fl6@9wVn{Oa!M?d$LFZ(!z@^VzW> zaVFC%HL)EM4v!B{Q1+hZvvbqa(=&{-@15DX`T6+;&fRjpySBW%ydrpY+}T}QUtiyl ze0rYm?rm>x?*pKCAv-hK1$|Ns9CqhK@yMn(uI{$v4q z^gn|R$h)9C!NBpKfty3dW5a@j%^bp7F()=GJlrmz>@~+@*_y+_d!cbc5tmb38XMJ3HH=_|=`0o0p%T&eFss>$PRY#l;?zwPH_g zS$TPRz+$htURzgPT^+GG>+Y$otFNz5INT-cy=~3S%^8FMbi#@YAI?A-kP`~v50 zIp1AdUS3`iygKgeuC1@HZ%95pZ|#k>jf~q0nRm>cz3u(|1I^s>etUL&e0*ZEcKo?L zJ3n7!TI4<7Z||eAWv;!(H3F^$JPCf70^_gXw#@wm_C+l$Bj4s4oFCb)=Y zKAGsDw(`j&AG4QFCI`4_KAjR0micsQMB2)y(_+eAKAoP>rul3}%CyX9Gc%U0d^Rg* z+skLO3yx_%pHp%z^ZDG0XDgr2tNHfw`TPbptrrVg#Ijy2>`+_vVo{ITs~3wWxM{sy zG9@hQ<LuU0IXmi21oie;-_ty;6~)vMJTjxl$oIxtuR03tF% AKmY&$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/se-handle-dark.gif b/workflow/public_html/skins/ext/images/default/sizer/se-handle-dark.gif new file mode 100755 index 0000000000000000000000000000000000000000..c4c1087868afab5b5bfd329f52d9907eb1c0061a GIT binary patch literal 838 zcmZ?wbhEHb+YZ5$9Lfxg96SOJ k3mltSSY>Q9925^Vv52er?AV~l(9La}b>~E3vIB!P0N;ZWjQ{`u literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/se-handle.gif b/workflow/public_html/skins/ext/images/default/sizer/se-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..972055e7b297a702ab9aa2d799d133b94ac92315 GIT binary patch literal 853 zcmZ?wbhEHb{~M&wt%~@%zrJ-wdN* zGz5lq2q^w!0s8MhgAT}-pgh6AVaveCA>$E{(A3N!$mMciL!xsdyOP%wjSCG&yTw_> nZk(97*nvsGxlP1k!4l8OOsp$nb_OLhOgBgro5QJ~z+epkjJq?f literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/sw-handle-dark.gif b/workflow/public_html/skins/ext/images/default/sizer/sw-handle-dark.gif new file mode 100755 index 0000000000000000000000000000000000000000..77224b0c06f1666685286c5322fb02b4cd2204bc GIT binary patch literal 839 zcmZ?wbhEHb+Yh5$94ZWq93m15 l2M#ndammSOI2<_C%q421Gvk7Sb33nm)}0d@l^YrutN|0L6o3E# literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/sizer/sw-handle.gif b/workflow/public_html/skins/ext/images/default/sizer/sw-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..3ca0ed96df2059fe283c1d65fa1032a777e1ff97 GIT binary patch literal 855 zcmZ?wbhEHb_F_q!3-qVNZQx|DV-A6h!W?b)Wnj^{5*w_%-mFl zkc?6VBXb4c#3BVF0|N^M17j-_11m#w1ziJE1B0DgB7cDlD)IDnWxv59C8liseo9Il zP>8d@BeIx*f$tCqGm2_>H2?)!(j9#r85lP9bN@+X1@ct_d_r9R|Np;d_l_fHFK%AH z^6>thcW+(4aQ66_;|EtQS$O!!!80cg?%BPQLC5($P(5QwkY6x^!?PP{K#rTIi(^Q| zt+Nw$@*Xe{IQ-;9=l;Lnc?BNrIk1yMnla18!|Rfx_=~o=7sXGUdm8y8?D5mi^pr2Z pI^U;TAL(EB=a!G%y}ycg#aS#EpKsu3JPkCF!PC{xWt~$(69A`aaP9yA literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/slider/slider-thumb.png b/workflow/public_html/skins/ext/images/default/slider/slider-thumb.png new file mode 100755 index 0000000000000000000000000000000000000000..cd654a4c1680183026145066b4aa1a7802605456 GIT binary patch literal 933 zcmWktYfO^|6#dFz0*jkYAxr02nPDo(Y#3G2We5n&sxU;xD0?`TAk?4`t&?nHc7tSd z3BhbUwh=-{CW2C=R96rO(&5-gscoUWiha@ACv=ooX>pu=`*F^>IX5>s$;rK%mHE!r zP$h3lZ zsu&tSJM$EgWSu@k&1X2N$vNfP1r2#P<>bx>9-HY>X?dzQ`iE=Wlw;RNCAE=}lB(Zo z<6gMZclprm#8~&$>T1JWM}M<~-Ml+E|D-6_*cxWgU-Z?i6ust)nk;MoNq#u7uv;l^ zc%Sp4FTSFge0_U;M2mWF(hez^x65SwD7r47cs}l{u%vZ=dWdj%&y6Bm@aZmsp732n z`nJSRY5d(iFV7q)Zw^u^L<>z!SwVOYYiDTWE^70(u!`A86P*2iZai9?pV48-{yUCV9Ec?o@;sUjk=1>cAm88uY+&dR!6>c{!;b@zv}ZnqTHCISIq3j zrmRZR!4J?JEO}MEgUxOYRO$OSzfMm1HjkLN%MA;yI5!rveWW!)Se@qKRd$^E(bb#N7V}{^w%jXPw*+ z6yhxKh%9Dc;5!7ujG`J|4M0JbbVpxD28NCO+UBR8*c(lVeoYIb6Mw<&;$UDTwkjI literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/slider/slider-v-thumb.png b/workflow/public_html/skins/ext/images/default/slider/slider-v-thumb.png new file mode 100755 index 0000000000000000000000000000000000000000..7b3d7258ada4c81c6fc060bd5eea69524f0ddd65 GIT binary patch literal 883 zcmWkrX-ty`0R50E#}rYbBu=wW5C%9+p|mz^KUyf-HiDg2qsADUdFzy5J(6V!F6ux{ zaM+2OO$`xO3Uq)R3W!vwP+G1+0l{9h^wh2t1P1Ecw;%7wOWvRN3Pjo4mW8hgCkSGh zfX~}W=_U$Ep}`bKs$wE3`9_+#SDKM~L?S(L_6#XL@#7IfeEd9_vW3i&r8Rg-rR1}uO-*=86B3}KEpj8RNJSwCe z<7ROQqPp;lkCMd%5%jZYyEu~r&Z91X zf9j@W8dR9k4|L3<$&YFmJnu7Kt{FYwd>r5Rl|w2Y#50Oj3~YoXAgst?bG&}PJ#5B*LU z{dhi%PAi5yumtc_57k?YzK3lZCO;fAuuj1>3uQ0r2GKeOg9r8x@cfIq0W`lshXs93 zIA`IVN8>P>-au=Idk*gx@Nx_tR`fbB@($(zCT8GUfYt`J8SN(MT~J+7{6rlSB;A?4 zi{Lm$j#55Vz~hQ9js9@RB1tFCELoIyqu@p3lls?9n^{Tg3m@givo8E|x9G0ECUCv$ zW>S2Nc)=b`i+*yoGx z#+_e9u4`NQ<+fT+t3SUpVSIPU;$N@*R&qb?%B_=I<2M+#S1hId9!oIRt6i-(mIr+o zmUzJ$m2>{w#i(h~Zhb8&|6|8ij!3;n-D6VqYdY^0h8ofXcZ&8bNx3$};+3(67|G0C z237+ptgBK!Xd(M@Vq?UoRC)CgD-;F^C*wA|I6wb-VmZG|v7&PSfrH%d3oaQ}7UiZq zmftCgdwjomxq$gFHJCdQ+PZ_EoJLm54s(eZpwB$-?_*CEA{yP4?kaf^!fVZ&ljHjyZH3qg@$%oTSO4z3`gia3-v=)~KYIE3!JEGi-~N64?(ft0f1iK&`{Lu@ zSD*gA`TY0Im%nen{QdCl-?v}?7)HTp2+%PE6o0ZXGcYhQ=z#15;&S4a5oxH0SN zs>{3yhr48VA6(hFIb*xfjjnHNf_V!bACgrtUw2uk;$t4KK*H+yJ${-Taz2a<42PQM zPKxkJ(vROCEp9#6VdthqhN;HZya#U@-alV!X+70p)|aQ38N94n84nr1IKF1C+YDL8 zubH>}>|d1e-fGQTF3`ljJvU-UF#ieLincdQJ1?_cSRCKycQ>=`^>ta}{qLqUet*xy z)BNWDJCWv}pR=~lGk;&w`1|`i_5=0rzcl^*E&k`x_V*!;|Nk?vt!M}q6Ulhc$Px7* zgo(%O#e-%}i_n8DB4HVctbU3M9=6GpbuB|t=_ytT&nMMP z`uTi9#V?DDDUEfNEBackRz9EIx$NhQITN>8zMMPtSf%EI+Fv_07qYUjFjxZs<-Km4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/scroll-right.gif b/workflow/public_html/skins/ext/images/default/tabs/scroll-right.gif new file mode 100755 index 0000000000000000000000000000000000000000..4c5e7e3958dd31d9591fb86b76bcea760d402589 GIT binary patch literal 1300 zcmZ?wbhEHbRAJC&XlG#XDOwU%v(DkaLssvulIcf!H$6UdwB$-?_*CEA{yP4?kaf^!fVZ&ljHjyZH3qg@$%oTSO4z3`gia3-v=)~KYIE3!JEGi-~N64?(ft0f1iK&`{Lu@ zSD*gA`TY0Im%nen{QdCl-?v}?7)HTp2+%PE6o0ZXGB7YP=z#15bKis=idlbh4oJ2jiQWW7vW8%1R%X~mwJayU>VV6oTSu17E0R!3~kx?Aw2 z<@$QPLv^y%A^2nhXpR#NS^OQa!}QC!nD7;IO;8 zMx0HeKEtuD{z(do7CH|P>8bhKX)WCR_&kGEx1E$yOZVv&hST{9O`5VV%#Yn|$HjEy z<(27&ui0@eG=H;qZ?pX04-d`WZ8%~tlY3xKCG+ufGv&WNSh(rqhAS)OQxEL5Zr*!u zxBSPm6AoHE-0~gh?W8#ltoZnb3pn3T+xmtnRW2k2*D$RU8Q9-}2&7w}D*% z12@~1jK{qeQU;5eZN9yD+|MU+!Ku&XmWIj%k8c_&6J6zIs!Z}Wnz?wg|38VPQ_O=R zmrim{nwiQS9d&c*bki)!XH!#V?Npr=w<=O~cEqlqDszHP%~YA|bBpuojLarUwdpBR zFQ3nM{B-l#g8D}{RTia7NvSW+wu(|;lJ7N3eQ9yjE{%mYT3$=$IaFDxF7sq#VXy`O DM15!0 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/scroller-bg.gif b/workflow/public_html/skins/ext/images/default/tabs/scroller-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..099b90d8aca10ad0e0a87552e5eca975a72f985a GIT binary patch literal 1100 zcmZ?wbhEHbRAvxkXlGzB3f<)J-=TNYo33`GCmeE$39%ip(O{=Nqa{`~*` z?|&d*7zLvtFcd;S@h1x-0|O(24#=^fJi);6pMjM_#$&^RgUzhWECL4>ELn-DC~RnIVicC$7cz76!_!<$ z>JQ$${Hzu@UzjE8z|Ms$FE5w2*ptE~x+;X5$?(CI16#El)=4dqV*M?ebAwTWCGCLb z!rW*EhC5yYr?2V8>?~$a3FsDXisvX`{L|_%{qTbW%}d{jE|}`vc)XF(rY@$UsPV+) zrOQ%#E;pnzH`+^U=vaM8Kg*>5z~#U!(>vEVxDMCxM!#ZRY9ajM9&bW<)1iIUzyH}X ztY+Y{kkp7jH^=eevkOau1SA?YzdQ|GUUZ`%w(=VXldOd1+nvQV=ceVVf8Tof`}V7UcV7Lu_vY_|cfTII{rlwo-)A5GzWVg{)n_33 z|K{`GH(&m~{qpzyxBo!EFbYOPU=W9Z;!hT!>;5z7fZPbm6AT=|49qGs6ec`4(8R&7 zWpctG@o+1jveTR&8bSd<0UIDB9_$ireT@Wf$*vuBf>3d;uuMTd5FMl%bJhJ}p` byxeRN0S*aFO-%B91_mD*nV1VVf8Tof`}V7UcV7Lu_vY_|cfTII{rlwo-)A5GzWVg{)n_33 z|K{`GH(&m~{qpzyxBo!EFbYOPU=W9Z;!hT!>;5z7fZPbm6AT>x8PqvsJT@#i*vuiU z6?0<4!o%$X%3gCkHZD5aEoRSf;Kato$NLqWyJS2!B{ngr2Cs@axoPR?Y3lK(=6G&i zc6O>^{;NADH!nXw$F7-6)@zIMg+(5dwPLGER$g8nkZIQIwRKf!fAIROyQe}EudPcs z9QRji+nSq8QqHf6-EFLUdwW6Rq8{(<>tc3SeC{e)y?y=t)|&rZayE(v4-Z%JD#yu$ z8$LdsCF?v-Cd}yR=_uXgdorQM&(C|=Hp|(Dn7q7fhzYodz&w>VTjrBahiCSe0-cybJ4R4j(HVwd#&8~uB^?Te?#&2xA%OzoBzw} z2R5}c2wYkne}3QI-`_txK0V)m|GvM!e|&y@|NQ>_|NlL=Rd~?AB9`%>kwb08gC-uc z7Y~{R+%z7xh=gT4Y!xeeexOaJ?8U=&g*J^x9V*i@9(8IgTk)t%XWNTM-3I$CVwp{@ zWjyY+c(&qkpUt-ykNX|iG@ndx5zBls(L=3Mg^f|?!IQ}WZkkW0goI^2of?t0^69jg zvX@V%C$wokn~{{I(7=?jY~{0AIon=7n_X~B^ZA^TYnjjIRyp5UhSa>TCY|tnU?ix<%(si zUaeZQ?bWN*8;-eiy=G^vNqD_>$Fo(h*X{ZC>h<~qY}#)&91+WYv+;!5>NlHCNgZHd qxZtM!cFUEp?6+HQq^*9t?M~V2x7#1IX}{a?WSX}gvj__dgEat$YLPww literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/tab-btm-left-bg.gif b/workflow/public_html/skins/ext/images/default/tabs/tab-btm-left-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..dde796870137f9f9e091100ec800072498b64f80 GIT binary patch literal 1402 zcmZ?wbhEHb)L}GYXlG#P-SqhEz0a4Q{k!+(?}K;0UVi%X`tzT6U;lpi_V@FTzh8g; z`|4|fnTJWlvlbe=$Pt%A$HOF)Fva?eR z^IzRLxmo@E9J^*NS+5Y~3yVA^Yx!1{th~HDAl0nbYwN13eZlLq?w$%wytXdkaM)k1 zZEJ2WN;$tOw%SQ_jCSclKT^G@bGXMuX5aD#!Z;nSXxHI@h^gZ$rb^*Ecq2-#@o^_xJY?4tM{T_useY z=jRufSI4i9ThRFZ!{gKQ{rB(t`}@b|*Z0rw-w!MY*fbtAu<&VIVB}C+@t}#v?8Sp- z0XL0@Eh1qV4_hVDRy=HzDLb*yfulv^QHRR3j7Oas%T_$<(%JUnQMbV{jmJGE*D{iO znN$}%?z8#!;&HzNo92@VE@GKaCVHr?d@{+$?B$cmeq2iqObH3gd^$BEZROKxF=a2G zPETmld^RIxTIREv8S^wRFy(A}`D}K&3zjwN)<`^_abSv3P=;*2^VR!m?g2osqUGa~YHAgO|$}v}wIsv1D4-tCcI3t$MX; z&9+ysR&O{KuJwA&CMJOf<{i&gy53p&!*>FTG`_0A^YOCLDI%9Tv4Z}7o z?YCR5gk`_odLwQ1+6^oY+y}NlXw!bT^!xwa?EmKT z|J&;S;_(08@Bg5}?dtXa?f3tl!0hz=|JmyP;P3zB^8e-Y|EI_Co4xAq`2W}F{hGY$ zjk4q5?)u;D|MU9)A^8LV00000EC2ui00RIq000F%ARq)HIhN?DnrzyxZVbjHt3>W|e1@Q4~3<(Tm;RsAF1q~rm=nyy|06T&;ZRY?0 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/tab-btm-over-right-bg.gif b/workflow/public_html/skins/ext/images/default/tabs/tab-btm-over-right-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..45346ab145a9f4796dfbebe62d84c2a785e16b21 GIT binary patch literal 638 zcmV-^0)hQUNk%w1VJrbM0K@goS5=hKY(MPoOO23|ls}S{n3*z{nw_2~oS&kfp`)glrKhTo zsjIGrt*^3wv9q>zwYR!&xx2n-y}!a?!NbN{#mCB1$;-}9JI~T<(bLvq4b|7%TNc{f z;8YRc;pI&e(BTJr4xw7TUm@{kM ztU1F10-!^S9!C>oFt6t5zwd>cgW6PdRyEg3#3kK-k&AYen-@tJ?|=UP{`(&Y7)HTp2n_uYQ2fcl%)r3Npab#>C{HkO#4<3m zSU7BWz}U#Fsu82{@Bt$ykATIDjt0lW%z^?U8V?ebn>bh$O%xm^r7&}_$QvXWEO>f~ vokdbbz+rM46PqC~1H*!Z<&1OKC3FlnEYJv?!yK*^TN$w6U=tHF6N5DXg62z6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.gif b/workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..34f13334511d9d8efe3dee18e6f69f3d1277f8e6 GIT binary patch literal 835 zcmZ?wbhEHbWMq(HXlGzJee3<1+wafb{&4orhjVv6oWJ|w!rhM-?|r;<|I_6MpRPRk zboC(+eZKbS^YurcZ#@2d^U0T6PruxL`t{DUuXlmy`PX~TzukZFjbRjwhQJUE0mYvz zKv(}~&;hv}lqVQC6d3d)RyZU!wQvY1*c4o7ILO4xDIjB!uz;bFk%@_cgM+~u0EV(m Avj6}9 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.png b/workflow/public_html/skins/ext/images/default/tabs/tab-strip-bg.png new file mode 100755 index 0000000000000000000000000000000000000000..fa8ab3f462f07ad14c7dbbf76117118a302e35a9 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0y~yU~>SnxjEQ?q`I@C5s=a;ag8W(E=o--$;{7F2+7P% zWe87AQ7|%Ba7j&8FfuSOQ!q5JGBmO>HB!(uFf}kZ+p+j0P#=4Vr>`sfH6CexDft?u z8*)G)&H|6fVg?4eLmeKJnpZ&P`;>Yb*KkvN$ zdGGD72k(9{jDpb+7>*&J_>%?bt^W) literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tabs/tabs-sprite.gif b/workflow/public_html/skins/ext/images/default/tabs/tabs-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..e969fb0b7338c81f8e22e3f69f82fe49fb9b3d2d GIT binary patch literal 2120 zcmeH`|3A}t0LMR@Sv#(pzRU-6RFY!pi@u#ZcG;OPS3Isuz7>Quj<9+o%+>iHqydKXVUq3t_j~CU~d;1O=3^k%I zK@b^`uT%}+t{?xq&)D9te$_uGl4xEH&A%Shb`ERb%I3SIy7w}@coY$jfq&$NZiV54 za=zztL9f!-HxBy8kpUIxp8ygSBAEcv31nyzNTM!e8%TbKsW$>0{H=_AsuJ(WpBfSg6Eg;XE65o%BUvD{bXEk zOXWSPEqo%A=v#Hal?Wf>hPPG~`V-;UmYcp0i`uPV+Gua_+QM z+jV}9XjM%UXVRS6?YV-3@6U&nCSD1PY#jK)GL$I7A7l=yuRmuXLlc& zu@F~vWI*)H{TFEUl1yM1Q1?`aK~Y?SJL;YpH0EedBw1L87_?THz$uRK(*dzsGDIRr zN|-oDu000xBPZXiMrBDev$%^N#95@_X;=$Cd;!|xEBsJq?XSTrf4yxQ8O3r=d><9( z$|fA7Z?+Cv6}4?0d(}aA(YxVj&me;IkXQF!hcK$_x&zIB`dxH%z}@AAET`IkY#?-W z$p}0A^jgNzrjTXz(8BD)vKw(l9~dVr_zGG6(PpcLQ%k!J%WoygcA%1$&nV<~7}(J7 zQY@FzM+-6?Q<$mNZpzVnSG{=+X~duCio)EOmnf#~Nu{EgbFmx6bj+qJOSnb!#x$OQ zx309J8HCcIwJqyPQw7b|^|;5i*7XaX39QN3hPrj%RhD2mP!*TgGF~F`a34c;?haG& zx`J%V`8^&zq=y45Z4xVov0;gS$z^#J7eHm)^lR+#H!Oo9khi&`&-UgmsGutKK zo3JG{IQG`S`*8EoS+V&=lHg5rPQu)WxZ?7;?)XQlxt^mhNSa=H@?lM%-@f~@{?s<0 z&`1vYIN) zra0~MyiReB6<(**9P7x_+-5Gmp-umDajq_{K$xRXs*K1n9B%+@W8xbj8=()LXV1q> zMX*6MN)n85BA`R-8Mu=o%`(^n`+Em-BweC&$n`L*==eqTTw-v8Jr{{O(q~Nu5lXI5 zOmaCba9#xEHSd)AVCWluTNGO4?WKyhhl1J$ll<_EGTqg0SK=TsxEO4=3?n(>GxLWT z+Fs!J71z|k&D@lenZG({BP+%iMQDqn^!^rkIa&w7FRn2+vc5;h@EPdNBxq}`#kPbC z!!{vHsb7oUY(CXAY`Y?h>hbZ|hI1IH9cro1&PAQB85HRX%{3qI^-El@T)1yD;q6N* z*pLx1l<(NiH$fRyS&5sN5QggKUQUKG{0r|y+e1x{I|Dc3>xW_#PS&{kV>SHjg&6$f z11U-@noGbjlFRoKHs`+Mp*9sBYCBRn9lAbP_HeiTu9##_UP~ji_3{WK0b80cM#ok+ zttB1zXuJ7p=bEan)?Gi(v2G2VjIEI9b|-hUZmaplWs}LP1I{(G?igl@OCfy#Q^4Yw aY~k|oDS;V9tOD~>PCR>kAPR$l-2Vk@&nw{o literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/bg.gif b/workflow/public_html/skins/ext/images/default/toolbar/bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..0b085bf24e173f7a2568c347f3245bdaade1579b GIT binary patch literal 904 zcmZ?wbhEHbWMZ&jXlGzJdGqb5TR`;g^zCwCTzUXRA1^)paQWfKD-So0~;Fd71bH3SrYvH+d-pFs!YKv14w;7Da~Z1~~up_!du)~evahJ_E= zc%_Uy&NM7kYU38y$=KqsP`Q;;Sgxby!h)1$R&Ie6E(r^kHZrktoKP`HXkcJuWMa6% p$*}A^6FZ-Z#4LwKrYSs=j0zqwFtu<5D0@r@Sh(uyYDPu|YXAnXewY9N literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/btn-arrow-light.gif b/workflow/public_html/skins/ext/images/default/toolbar/btn-arrow-light.gif new file mode 100755 index 0000000000000000000000000000000000000000..b0e24b55e7ee53b419bdd5d769bb036b19fe9592 GIT binary patch literal 916 zcmZ?wbhEHbQ@i%X_#s+qO5ao&#Bg}b_z?(JW>fAX3`Gd3KV zv*q~0?WdOQKC^1y`Sph`ZaH>k$H{AZ&)(dB?ha5d!zdUHfuS4%ia%Kx85kHDbU>Z} zernn7GpqKUUw`Q0mSb0ToV>R8?9Kh>?)?A%A85cR7!84;8v=?yS(q6Z7#Vax zUI66@296R2W)2yT4GRu7a|mm>STHs?w+nNawPX}9G%#|o>fAZ8aq;nf1?Mgq&rM5C zPSyxs6?1aa(*sN*0#Y579~gX_Ir7AO7EE5yG(%Y4FT%k%!-dUUH;Lzh!*aJqzAC;N dg;0f-Rg6jrr6;$pzP>);aF?w2wgd+TYXG#xTAcs@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/btn-over-bg.gif b/workflow/public_html/skins/ext/images/default/toolbar/btn-over-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..ee2dd9860c799be6dc194b387c36a953c55aac59 GIT binary patch literal 837 zcmZ?wbhEHbWMoKTXlGzJeCy}&J3mj~|8@T1uggzJpf;!hT!Z~imrfcyl?6AT{b$et`3#gN7&v4Zqzw`_ELgzA$|)pg(Xe14 SBQvX#kb;4O15gDcgEauAx-gUg literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/more.gif b/workflow/public_html/skins/ext/images/default/toolbar/more.gif new file mode 100755 index 0000000000000000000000000000000000000000..02c2509fee0fb4555df61072d8e8daac8dc7430e GIT binary patch literal 845 zcmZ?wbhEHb_??HKjfkTUdnM1~7 r!-9j&9Ku>L9YCQ*K7KbIgN+Z4bP31@U9tF}++`ynz+epkzXub1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/tb-bg.gif b/workflow/public_html/skins/ext/images/default/toolbar/tb-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..4969e4efeb37821bba1319dce59cd339cec06f86 GIT binary patch literal 862 zcmZ?wbhEHbWML3xXlG!!aPPx~`#|*Z;=Kx_O l3y+3|gN`0r3Od0)xY0~Iq4Rm?bCJ?B`>oTK&gPd3dz*}CLR%aU_l zD=ze`x;$asm5J-FP1|y7=C<4Oc0KGp@OARxuQQK*oqzJ{(lcLIpZm7u8ukxPurZ-YfblWU`p4o5&%%PX!%{-|5oZ<}b{tn!>Yw4W=u^Uq zQpF50j}MM*?7gx+W?f1zJDKabS=0$Rg*yZqflo?c5Ixr^dQ@Bde4NjsFf-c#W=%hte#Xx8144{oy_EOnT}e!Oo~L)&NLV<%|FT literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/toolbar/tb-xl-btn-sprite.gif b/workflow/public_html/skins/ext/images/default/toolbar/tb-xl-btn-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..1bc0420f0f0e30675a9eef74adbcb55e3efe9d00 GIT binary patch literal 1663 zcmd_p`BPE}00(e9$fKOV%p>iPJj&c%bKS|xcC^ftT+_6&bQ^Q1v0|HYZH>xJ<)Pwz zJ{2=BT=7g3OVbPx;Rzm~c$*61k!dRMUNt+7`}{lhJD>Uf{{7*5&d1C3_zfM5t5zZg z*DM_almg(yCS!GDY@;y)?seu{c7h(Q&j zgny%6K+jMmP;5z0Y-vv%s!SALDvB=?$Crz#U$z654p0@{`RiKu^2 z14&f_^ePFRB}v{QO|F)tR7+E8P=l$c+QGEiq4e6Jw7Q}6I#~v)9yOfNFq~OGocVGj zt6?PT&fvmXJUF)t2KjJ7H_Q;g#SmQ5 z1DA>53Nc*S3$yy*ntr%$0BMjQ>>fpnXzn#itbEfu-`cm(hU#B@JFwI)`Pd=(_)fa~ zZtzp*(8~Lvl_n|DJczUmA#Y?z+c45Gigb=49N8*o_%nB8jW@E^HM-6jM|cwme{6$4 zuIe6F2`1FtlZbFqBbs8TgLuNs?IjW4Js7St1q>d8g*)ROwcN6j>9 zSu?Y&nf(OIS6~Hd6`or~l%J7#)Ecs|_GNMX3+8_r>uji{Y{M4quYv` zK1ZlvHoGPY*j-7ev-=+W3ti~ob1cXsIm=-%B`70^8A;N(lJ71^2VXz?dPh4Tu$GN$JgLf z{3za}WGW%h4420UW0~llVVYVIXr;Kr+JF~!z5KiQkXD$d#isr)hd6Wp9fH_M_ied= zbBRO2H$dKNZxrE1@t!jP7=AW&Qn~^8e!TYHBDTNK?x(Rb1Ec7OaGiY&W#c)!Q|oa) zxR@|!V1K^37G&$K8%{T-20M=%Uw4vYF~9N0M5&-GxF;=F>DrU-MpPWMarYu94|<*m zCmr;5E>{wK?G#LcKY>tb9dwxj<f_U;r4roZGa6lchMQo#=t2JlW z1rrR`MBfun)4u2}<(LGzxnp$QfVUwDi0IAGB@ z(YR^83IK=@3&2sHp2BJ>i_4GC(}I&g&Z3hSEU z&NlR)MYGw$S*eL3K?x;6chQB>jr0!$UUa!Ir<-f7mDQk# zBwX&silB=a;YFDn76zFmv)QzrZEk1V*~{;o^E|)bI{pWJ`S9@Y+&;Y*FLa&mKg-o{ zGXtE#VCd`XtN%z$v&7^lt+S-nPx^l-H-oChVzFASZnt}UeB9&lc)ebq&o>x?i8W;+ z0x#DTPXs0f@Cq;`sILTdDyqJY!dp!Y{CJS@QVn6G|s1BUZM+WbuojB z68@5KNy4B6%MygL5X|E591VxVu~;mTNF6 zT4fpSr~#G*mQx_FYA^?^pdwK*kF0=+VKowA?Or}MJ76DP!CM%*AD^gZu#s95A z(UowVnQP&+Hh#jD&D=5%-X5|Hk63M^_B)Qd&U>!=55^uodhEK?;~v?6`RUM^EeD?u zRaBmERc*B$=XEu%J!RdtiuUaXoK+lWJI3$cRO{Tq^PTU^ZQD8=zLF2tqkLnX?vSIJ z*Yl=;`DA&!eg2!Rd7-JEKVqNJFP{p`eI1PmRwLiEcXNZi?S{R1W!QA>{Vrp4!M?Mx zj_=e@PDiKTTrV5^*>fdcRasKn(y`S4;=E(uxo1t%_l&bzclc_ccC0io_oQne9xONN Gx$b`#5UBhB literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/drop-add.gif b/workflow/public_html/skins/ext/images/default/tree/drop-add.gif new file mode 100755 index 0000000000000000000000000000000000000000..b22cd1448efa13c47ad6d3b75bdea8b4031c31e9 GIT binary patch literal 1001 zcmZ?wbhEHb6krfwXlG!sZ8LT1HFNH_aOtsj?X~gjxA*9E^z3&Ep6U}i%{O4CWB5GR zxH(~o^CD6fgr+PAPg@j`zBoE{b!f)w;OtcqS!<$mRz>A)jmQU~$dc{RCEH^Pc0?BK zj4s|4Q@Ag_Y)yK_x{UHY2^CvX>NjQ8>`JNKlUBPgy>f3}?ar*)o!Rv}a|;e8R~}5M zI+k5?IJ@p(X5I1prmcC+Tl3ns7k2C@@7Z0}wX?EwUq$b}>dE`-8_$%sovdm*S<`y9 zvg=S~|DoE>6ZKu^Yp3pS>N(xmcc!K9QuCyv4O0&^O+Vf`{Y>lRvmG-|x6L@yKI2T+ z?1R&1ADl7ea@VxWol~!LO}o-P{c88ji`{c?Oj>eo%Chs*mR*>(;O5i?H>WMVJ$u!a zxvQ_tS$1N<@{-~Tgx`xUa|S^%B{CoY`?W?%iUF5@2}Z*cg>Eg z>v!B;zx&SmUDr15xw>=vgZ29!ZQJ`~+mSmvj^5pQ^4^hC_l_QYap3f`!)G2GJNw}H zxtAxeygq;Z-KCo^FW&ihj$;hsoH8C8796zp$T+b>@c4oQ4ptl9{CxcUY?nYS7uzPr^nkf~ zF-KnfWK`sLl+9v^jSOlzC8As$;v$iu&bdH0ut_86$zxX@GwwqiGMCbLCdz4)g$X=7 zcxoaWQ~HIKhmx0vy2>O}Xevx#ky5l?_wGr-qtgtHrgJ}!+;FF#5#6#i2*%nh> zyAFx!#AZoGf3_x%!Zyuz9to2P8w(l~c~334oIij5|Ns9CqhK@yhFS=VTXXjp>_!!i-ZjhjBP9&d=d&P1P-@w z2*?REbZj`-z{teJvFE@96*ex`7^N1;;s=LXIk{il(fr(WZkkH%E}e=3)qp;}RJS=1 ZACr#t%8J+VSOzWgoT4>ViN zU%dGJ;lrOVU;h61@&EsShEXsY0)sdN6o0Y+UH6|s2joUjo?zgZ#9+@MbEA=|m5*7N zuP1?_;V=Wcmd2kAjEoFSyb3l63JeWQEzG)l4<-aOJF{^!n#_11;LyO$#4EyJxnXG= zBd1*n!vlvz??xWBngt9APKV|*$upc#SeW74&N(&d!GU0fOO1}n=k{oQNISc~334!T+I5ReJa7x*DTyS#YWmWQ8@*yChwS&o6 zrsT(mM-FYgx*h@@4;QobG08Hm@c7Wg%*HKZQ}Uv~iG_ooBg3QNK|^B;FB^}5K!V!o j#pc~334eSRT}sa)VS__s8w&@Y zgu;q|!z~;Fasmw<8xA%wGBG*Ccx+O2Y*vXZDtTe_=t!5iao(F9ACgZ@)bm{w(wUgh k*e9SZBf7&RvvH|ppWc*{Usi^4=^EOswG7BU)WBd303hyMjsO4v literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/drop-yes.gif b/workflow/public_html/skins/ext/images/default/tree/drop-yes.gif new file mode 100755 index 0000000000000000000000000000000000000000..8aacb307e89d690f46853e01f5c4726bd5d94e31 GIT binary patch literal 1016 zcmZ?wbhEHb6krfwXlGzhFH%vfSJo_7)vQuAsWC9EH&km;*6LR^?KiYxFJMjooS=wa?sdwqwu&r?{0KDI0upwuR+x56{~g zkq<(VSvvztwnvw2k15z6Ua%vwaA$PU&gkM@F@^i$%l9PIZcnS(l~TJWt#)5}{f^9- z1J*HzZPSi=W*zp-IqIEx!mH#^WYOu+{6mTPhZFOT08vuj(d7JNDFp|U3y&lh98WDi zo>p==rRYRP$%%~86B%VEGs{k8RUS;KJD6E_Jiqc}cGa2O`cnnX`*Pb46}28MZ8%lj zaHgpFTzUJ+%FZKY-6tw0oU5O>vwy;#zG=ssCm!gZcDil)nbs*M`lp@kn035;#_6_M zr`l(nX`gwvYwo%3nHRffUg(*1rFZuAiSsW_n15;F+#8b?UYok``qahOr>(v;d-dhn ztL{u+dw=%2>kHRkU$E}Z()D+iZN9m5#o~d_ub#R;qm;f57%vfxPJS?4f`H%+y8jS!N=PUJlT2r&He)i4xD~_ z;M%)OH{V=&_T};0@2@}p{P5-1r$2vx|NZy(|Ns9CqkyasQ2fcl%)rpgpaaqk$`cG6 zR~e)^Wjr=4aC9<_3F%-wzQDoVIAhB~=k&AfoLyW-Re?t*%+d(FBC_aGf`Fq$D3_+D zkjse)Dz(dOBqZEh6jdE-UYxkdEGT3zv4dmE!Dl=ZWi9e%{1g;@!G-s^!P$| z8==@$AR3<{5^GPA?~^>Pma%d|c$9FpHZ#?|? z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$lae%R5x_+pfh=9;jCRWxkA&~=x h2Yp#A(~SZe4mdO}wqloSIC&-M@bZAgN<174)&TX)MQs28 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow-end-minus.gif b/workflow/public_html/skins/ext/images/default/tree/elbow-end-minus.gif new file mode 100755 index 0000000000000000000000000000000000000000..9a8d727d70ff5161ec18c0cd0156ae8d50a23b75 GIT binary patch literal 905 zcmZ?wbhEHb6krfyXlGzB^h$R6?=)rU-Z?Z#?|? z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$``4~=2xoOmJxRJ?YUCe?7 p4c<*mc6tvw4?K5dl1^^H;N?iZ| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow-end-plus-nl.gif b/workflow/public_html/skins/ext/images/default/tree/elbow-end-plus-nl.gif new file mode 100755 index 0000000000000000000000000000000000000000..9f7f69880f48db8d86785639055fcc198764617b GIT binary patch literal 900 zcmZ?wbhEHb6krfyXlGzB^h$R6?=)rU-Z?uiX3i z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$uiX3i z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$y4*XmR1y>vzmpih{E$}o|KC(Juvl9;ogEauy5=OfK literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow-end.gif b/workflow/public_html/skins/ext/images/default/tree/elbow-end.gif new file mode 100755 index 0000000000000000000000000000000000000000..f24ddee799ccebea4dfe60fd65a5703a6a59d44f GIT binary patch literal 844 zcmZ?wbhEHb6krfy_|CxK^xx^&v19*7!DtAK$PiHc$->A01UeuBlqVQCG#MBA01UeuBlqVQCv>6yVWIQ%3 sIM~R@rxjCSpm?~QTh?igM}U%RmzciOnH3WikN0ueH<|n}RA8_M07ViGB>(^b literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow-minus-nl.gif b/workflow/public_html/skins/ext/images/default/tree/elbow-minus-nl.gif new file mode 100755 index 0000000000000000000000000000000000000000..928779e92361aaebfe9446b236d95cb64256e443 GIT binary patch literal 898 zcmZ?wbhEHb6krfyXlGzB^h$R6?=)rU-Z?Z#?|? z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$lae%R5x_+pfh=9;jCRWxkA&~=x h2Yp#A(~SZe4mdO}wqloSIC&-M@bZAgN<174)&TX)MQs28 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow-minus.gif b/workflow/public_html/skins/ext/images/default/tree/elbow-minus.gif new file mode 100755 index 0000000000000000000000000000000000000000..97dcc7110f13c3cfb72a66a9891e8ab3ccef4a98 GIT binary patch literal 908 zcmZ?wbhEHb6krfyXlGzB^h$R6?=)rU-Z?Z#?|? z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$``4~=2xoOmJxRJ?YUCe?7 s4c<*mc6tvw4?K5duiX3i z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$uiX3i z{QdXWpZ@~^!zdUHf#DSbia%MH85kHDbU@w$y4*XmR1y>vzmpih{E$}o|KC;?;W0q*gYXG$^NPhqT literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/elbow.gif b/workflow/public_html/skins/ext/images/default/tree/elbow.gif new file mode 100755 index 0000000000000000000000000000000000000000..b8f42083895bb98276f01a5d0e33debddb3ccf1b GIT binary patch literal 850 zcmZ?wbhEHb6krfy_|CxK^xx^&v19*7!DtAK$PiHc$->A01UeuBlqVQC^cfgAWIQ%3 wIM~R@rxjCSpm?~QTh?igM}U%R7pF1PhKh>{$NPBfn?f{-mK<+pWMr@g0DWQ)HUIzs literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/folder-open.gif b/workflow/public_html/skins/ext/images/default/tree/folder-open.gif new file mode 100755 index 0000000000000000000000000000000000000000..56ba737bcc7734693d7ddb2f50c8f3235fceacee GIT binary patch literal 956 zcmZ?wbhEHb6krfwXlGzB^h$R6?=&-=aaIP?oGg}kIcy8^I2ILfEiU9P24$!>3v-_@?Pw@dZdEXiZDqz?6KotSEHa+=}k8OCR3nw(sqcz%)E z^&Jkk_UAm>?EL6pz~8F{|8JLmcvAKMN&S?id*>|OyM6oiIctwC-Fj{1-dlT*9ou>8 z$^Yvu|6jNKf8Y82L+Ae=lmGvp`Tzf%|NoaBIdbIa(W7V2p1pYS;<0P5Z#?|?{QdXW zpa1{*{pbJx{|uvGGz2IP0mYvz%nS^S3_2i_KzV|JV1OfBquQXEGvI4}0>6q3BdQLvD`XSzZ1sfd8&rn9pxa_cf0 z8;-R|sQDgyVbIvhINu@p(3Fo!OdU)nOn*uow`yILl(G@%_!WGtV|{}AnFkvZ9YR(b rI<1IZ9mc}SXv*Rj;4nR}iJ6T{KqBGLF$ZZACT_Vm-ya@qV6X-NkKMK> literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/folder.gif b/workflow/public_html/skins/ext/images/default/tree/folder.gif new file mode 100755 index 0000000000000000000000000000000000000000..20412f7c1ba83b82dc3421b211db2f2e93f08bf2 GIT binary patch literal 952 zcmZ?wbhEHb6krfwXlGzB^h$R6?=&-=aaIP?oGg}kIcy8^I2IRjFD>R>Udq3sOkj1T z@R}--bv0re>LfNdN^fnF-QFU)=hNov3pP6ZL zdwbCB?S=oZs*|No!)|Nor- z|92fYaNzXm(`U|{xqSKZwQJXoU3-1w;m7CizrX(c9|#ym!DtB3CIl3JvM@6+Ff!^t&H2GZdv-WZP}~tRj*oB|LorIYr@vw({}!uwfFDhO(&LbJ2U^lzeR`sUwH800T8|T z00#d*{P_PLi2nZvyK9sf4FQ^mfZ|UUW(Ec>1|5)1pgh6A(Z?XlA>*-O!NF!$M-7&b z2M@Kd^GWGABrIrf5YP;mqG0Ic!oef1<ENsed*j@4Yk?RR_1qN#Xfm)wA literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/loading.gif b/workflow/public_html/skins/ext/images/default/tree/loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..e846e1d6c58796558015ffee1fdec546bc207ee8 GIT binary patch literal 771 zcmZ?wbhEHb6krfw*v!MQYQ=(yeQk4RPu{+D?cCXuwr^cCp}%d_ius2R?!0jBXnAQ) zOH<|l|Nj|aK=D7fpKD04vtxj(k)8oFBT!uNCkrbB0}q1^NDatX1{VJbCr|b)oWWMT zS%hVC ~NwO_yO%;SvZ5MdNYf|QNy-I*%yJaj+uTdt+qbZ z4E`Fzb8m}I&!N8OKmWEcCmrLs^Hs&3i)mt@hQVdcqghkaBs*D}tG_lKew4?rTjzIZ z9tSone1TS+TR7tu^CunG)Y7Jg#sw#)sG9C!c0I%LEzP)9;hqRf&)s$D8d5Db{TBs% zgl0~5QQ91luq4Q9tJgt4QLbaxZvAaKeCM9!oy85dg4k>TdBSVqjHub_PG=PO&J-rx z7oYTuF+kH|tG-UK+EkUhDjYx?zW?T|lx>+aOQm zzL$v$zBLo4Cj=G&tw{H}dW?tlTkS)SY4<#NS92z*EY-MMB6Ftp`R=*=*Ev7cS+X%W zMCur^FdlokL}1Y+&aasU2J4#EOuNlnb9CmqgLCGTSY!1BD42pkHY^XidQ5=>YQx%` z*%Pm9D!CkBu&tMWm(%-ejACVWGS2RX5=QOJ$1*tr7F}F+*-OA+Ly&Isg|AEuUYicA z#%IG6kPXkHt{zk2M6zK@Vu^4Q(1zE$?yY6M!^&jQ+2^E?!p7{g*|X6}vuRC3p@jk0 W117c83?+LXEZI4G$p&LV25SKE>nb+@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/tree/s.gif b/workflow/public_html/skins/ext/images/default/tree/s.gif new file mode 100755 index 0000000000000000000000000000000000000000..1d11fa9ada9e93505b3d736acb204083f45d5fbf GIT binary patch literal 43 scmZ?wbhEHbWMp7uX!y@?;J^U}1_s5SEQ~;kK?g*DWEhy3To@Uw0n;G|I{*Lx literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/icon-error.gif b/workflow/public_html/skins/ext/images/default/window/icon-error.gif new file mode 100755 index 0000000000000000000000000000000000000000..397b655ab83e5362fdc7eb0d18cf361c6f86bd9d GIT binary patch literal 1669 zcmV;02738NNk%w1VITk?0QUd@0|NsJ0|X2J00{{R5ds1i7Z(~66B`>G9v&Vb001Kp z5h)oOFaQ8I0021w0Y3o&E-fxEFEBACCN(uSJUcx_0Rc|{08I)CQ~&^5003P90ZlnN zZ2HgaR#tRYR&iNbdS75? zU|?otXJ=+;Yin(FU|@V`YIb#ZeSCg?et>}h0EGYmiU0tO0055<5Rm`?kOl^o005Z) z0GmN+?~005%|1f>7~rUeD5005~41+4%8tpx?M0RglK2)Y6SybBAy92~17B(5YS zt0^g|FE6h$GP@!ovpPDDN=%4PP>)+%g=J@gYio~fZHaSpjd*yLX=#~kY?O0znsITT ze0->1U$sL+wn#|6N=l(?ZKHd8zjAWJ0s_Pf3(Ero%L)p|939OP64C(y(FzLN0RhLMcRH8%DjAoeXS{Ujv)EG+gtJ^wQ^{W?3v zNJh*-LCQ@{#8XqnUth>oR?f~+Utj)HQ~z6A@Lyo#VPouQYVB}x>v?Q{t%gd(L*0R{xyxG~vlatYag2Jb&>V$^kk(2*{ zf&Yw*|C5vdnwsaLq~@lni75b z|Ns8}{@~x^A^8LW00930EC2ui03ZM$000R70RIUbNDv$>R;N^%GKK1uH+KXhN+gI) zQmI(8v}vO?E0!usk6NLdNb;LSjN7_}3)gKMEm^BfQ9=}oWJFkzOv$3fZRN_A+GfF& z32BcxoBv$pj74i3x2G;S3XK)B)FeoEmXWL#snn`jv}gsDrLa^fQ>tQ`viiu;6mb&4 zIih50RjgR4R9RKTR}rL1lO$0B9ElMiAmt)9>blUBj4Y5687efWvLQo=T3ms|nUS42 zGT05w#%K~HN|L}(qt>OeA3m=K#Zlp_nV3Y10NJUdgV?}Dj3P~n6lR(~fAPA&<^wy< z3SY;ip*i$tjvF;7)cwO(hY@E;pU(dEJAMvK96x^EuyA(#I4D2W)wt>4TNE8YjvOf} zG)mrhfAgFX#~WKj)1E)1@X?1HY^b3I4=}g`${ckFf(Rmn_^}B+|J5T5Fy|aN${TUW z0S6mQFhRr!;UgPsq@e^7N-V$&6Kb%bq#Sa*Vdfi^>~mm0dsJzqm1!)YL=j6Upi2{A zuE7S7XQmMhKT=kc#-N0zk;D-~AfZ4mcqp-i8dkz#<`P*@Bc(t0{IW!$Ngy$V5I-1@ zizZxdisc(i!~o5u$IbJ_rv6JTkwg(c{D4CNyI4a65=m^j#u6#8*Ipi;`17AUTJ(BE z5kdIy0|yB7l8z8W9HFeL2U?Ou5|`ZbpQ}X_F@z60{NTU@$Nckz5JFhX#WM$9V(qqN zczc{Zzy$F_4?N^RzzK;Blf(}}6cGhE|5-BcwnvOnPkU1IumcV|U{F8}13B@74?zS0 z#dwzlam2`nic7|EPvkH$4mJotfiVMJGlaxG_)rEWKMWD>&Oe?)03;wIQ58SrAhy#rm+eCjRSRuH))@dW!7dZ& zW5o_u2R%03bq^haWeql1000EIv_ld+Sb#9`4TvW`^x8Ju-~j^zOmNFONd2>m2p`;_ zHs5>m&A|f!9AH8(f>-{JI5cc`2#jD0Go}*+k21NqFv0{8KoG$M PBfNl1GVhQS5C8x>^BLCH literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/icon-info.gif b/workflow/public_html/skins/ext/images/default/window/icon-info.gif new file mode 100755 index 0000000000000000000000000000000000000000..58281c3067b309779f5cf949a7196170c8ca97b9 GIT binary patch literal 1586 zcmV-22F>|LNk%w1VITk?0QUd@002Ay07w84PX`%A3LHrS9ajJYWB>?a019mY3w!_= zeheW`4kS_$BTNt{R2C>w87x&AE?6EhTN5*F88u@cHent&Zy_^VB{*RwJ!T<2Ybrfu zEanAeNJ0@02_k<8;bxSjRY)#049Cl8e5Y1_tY3bkWN(XQaEfVlk7;?7 zZF!SzdY5*8mt2auc!8LDgq&lBt7(C!V~et7k-lw{yKsuMageiql(2i8y-tSTQHA4U zhskM;!F86%bDF?tGlSHx~QzWsjj`Ou)c+z$A_QDf}_NMrOt$@%8RPR zi>%9lsM?CJ)Qqyzkfy4!pytE%CW@Nu*TlB$=|re)xF5pzRlaC#O0*M=&Huzs>kT8$>*ZV^`Xr3 zq{{ZD&GV%F^A_)Y{V6-P_#W#@Xx7+U3jK?!?;j!ruDO*W%II z<s1(&F;b=Ka&^{@UjA-Rbn(?f%pA|J?Ea z-}(RG-{a%sWQF}}=T6!l(LfBVqwLzTzdz--gr zA>~JRUspdjz=SD#uW#3T=*1z15PotP*O<}1TXI=rW8fk~GqY79KP}1YrcVGlvzs zDl$nW+ZJ<7GW-rh3M7OOB8UkZSwRrC?KL;(Q+JJH=Ywg3PC literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/icon-question.gif b/workflow/public_html/skins/ext/images/default/window/icon-question.gif new file mode 100755 index 0000000000000000000000000000000000000000..08abd82ae86c9457172c7a4fdbc527641cf28e48 GIT binary patch literal 1607 zcmV-N2Dtf0Nk%w1VITk?0QUd@02fyP7F_@vT>uhh032%o9CQF5e-A8e03mY#BzglW zcL_0l6g7B5MoUafO-xQwNKjc)QdCG)VMGais%VD1YKp&Yk+f=&xOI)E zaEiQim9}=7y?K_jd6&3+oV;3t&|-(kYnQ@tj>UPC!+4gSZh?S#&mcD?Rw3D8!n4hVIpuCNxypy7?lBc|sslAz{ zv!1E8nykH`pQ59qrl_Z?tE#T5tFf-Ly0EXZv$D0gx4OH!y?~j^f}_NSpv#4+%#5bO zjit(rsl|+~%!H%Tg{shuuF;CD-i))_m#xK;uF0IQ!Je+okgwa9u*sgY$DOs#l(p29 zwb+%o+nKY|oV(kBuJ?(u=#RDcm$&DYyyKX=;G(m`qqxkgwZo{l%AmW~pu5Wy1~n_!_~3H*|^2hyUEtQ&D)~F!=r_S`L&GoF&_N~(Sv&!PL&+@j??Yq$Bv(odm+WouL^Ss^uzv2JK z#>vRX%gf5m#L3db&e_e*)63J`)6&(_)!NwC+uGXR!PV)++V9BJ>B`#d#N777-1y4d z^3d1g(%a?H-|XGp;>6+p%jEve=>OE=@803%+~e!f;quVt`_t+E+2!%y==0m`{@(Hb z;NRop*MI`>g(&|>+<34{Oa!Wf0xe!3Pge_@yBbqQDAy z^yqLDY^(Y`Bgb#Yy&t*SHt<)MmubQE= zM_%4K|K!o54GAF7UTBq*Ob!?g0o7_ijR4L$#5Cl7WQu5*Y1Gi(Bmg6D)2&N<*T z_(l=0(9+Fy7{;fLf+vi?iGtvWSYtTY0MiN@9f&f^H7LmFMINyXBrZBDyqCps^d=g7F3EF65lHnZVrI>UYlglJe zU~oq>afkv8HsRE$YQu zh#-bkqRKD4cwz`3RWxA(1Qnd&3}YuvgUT2`;GhH*Q&3SwBCD*Dh!i~7&_D!W@DWW; z1F;hgDs>bA#0Ei30Z1pS2x5T)7=Y0SG)EyV5IfR9lMEkstO3X(t9(I08OcCnvDYWD z6Ol7qAd-p~6!7sjC){4MV~P`tbU^{7d>1~=99ZDpN7scTEv^xRGv0Vk((EBd#a;&l F06QAMRrde@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/icon-warning.gif b/workflow/public_html/skins/ext/images/default/window/icon-warning.gif new file mode 100755 index 0000000000000000000000000000000000000000..27ff98b4f787f776e24227da0227bc781e3b11e8 GIT binary patch literal 1483 zcmXAoYc$k(9LB%H%(yfgGuR9b<4z3ocd29*O43CNd(`UWmQ=H)a>`a4DYpzOx}c(x zSlvdcWJ?+unZaR-H7>b~v1S^TyJ_?Ptx;{_9t|N0Ki69nENoJ2v3`>&g|W8&busa_So7*+dD)$ zvLc<>kt@t%F{f~h9qzG`vt^ZG;7|7JumJBhJ9Y+8Lf4suZE^fH#5_9C`L|tWUS6U8 z{=uOE0fBzowgqiH9`W<?y6`^?T9Sbi>kIro^$r3_Y4hFwk)R(#Q}G+VFY!jG?tX{A@K zA7Ak-yF;xiAyhqNys9yLRL-ovzEyCSA}UpDxeZO_LcSl+NfU}@28A3*bVbNWrHA>fZ4D_larvD z0o4={9|wFI(DV=ZJRp1#nxdfzI{Lyuvvho356v%?4p|^%j&Mta>}F3~{K0|F!GZpTzVLoC6_EgdgTr?dzB>V$ILvD;-4MrIlR(m27G@h~>JlYZ zVAt|_ro3YUVh;qD&xzwC(+MYO@wD@Y_NS8}VxR3300jn*@X<;}{z{$rL zTQ1Ygt3r~JNZK6NqxROCFAF5#=}AsXB5Gp!SiKu3HLoB=^T~;XI#AbK!S$~9M1UFk{5%nyiu}%*CZiIbNf<7_U*)eK2jmJEb7FxOYX=;RObGwm=_w(}-X91Z& zqYL6B`%{}cDrkMSM*JWx2`jXogS!VNpUr25HWVJ_hwMpzlk(}y+|3YZ)%_6gfm?u*PI1fu~NtNN%<%o?1bnQ|HcP z+A{@eE%wEmbNMT^8Mo3bU$&{4r}IL6UfVqFo%2t*Tz4deYD9aVZE~6`7TH{nSG#4; z<6vfan`>!V4h5%@)!a#Ahc&Ef--@I2iU;@wEYEC-zjIsI(0PM(`f?qQqf=C&8Tb?#p4A}3P=ZzHb8 zU%2?008r{GmdfTSw5X-f*JnevxfSlSM{Cc=no(Hy6^Zi{dugQHUH~t06Bw zQt4307HjGF&8-z0AF;fZZq8-%?^|4nr#0y83LDz+toN8`gZZg2p9Yd5@bP-%L)8(V zUmmP8OS8yf(llyk`BV+l3sY@pR^S)K>*+DB$}jc0e)m$1w?{Mi5Ahq5K8vj4mE(=f iL}jwpve+-)v>A%!R(IJo>4b>g=e!-tLq`xb9G_3G{0 zGdEv6d-+ygtj!51%UBZR7tG-B>_!@pqvPq~7*cWT?X^Hr1_hqO2g;KF>0Y)?neb;$ rtH-@3vsBJ|GJLS*We`|3`JPV9O%{pDFOA1RPGj(N^>bP0l+XkKCecH0 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/left-corners.psd b/workflow/public_html/skins/ext/images/default/window/left-corners.psd new file mode 100755 index 0000000000000000000000000000000000000000..3d7f0623e03727a632cf003e22e11593d547de53 GIT binary patch literal 15576 zcmeI1e^3-<7{}lDcK7c172LsrFbH>wVhuI%BO?1j;4ffmCc%<)CPO77wGtJH8DkKN zvKdW7$)+hFN{x{NQZx(GprDKf4pB~$KoLdMl;0e;Z11zs-VFT_IWTkFyze{vx#xZN zeRucy?sLz+w-*-qTpYqkDmZ|ca;b^9+hLK>&$6u8qwtm?BqLSqbA&!FhXCf2IpSP5 zggo9P{i$dM!a|eKidi4x zfe~`or3s2zo7{pj_T(#PN0y$^#Ma;O3tpYP!_MB_V}_^KoVotJaqW$vTu$aD?fhX+mk<5R{ivIbz5BziP4hj!ePN0LL5Kf*=i$Y2sSj0%M#)4G_3kj^dN zMIS6V_F2-)(QEg{@4IBo306n>?Ts$(j9H%a)WLvd8;Y}&k~bPQDERq{1XOVT@R3zT z{sq0-5&?afxSLN~0G&leed!0DtdLcXMC=dm>vSIZV8!-TMdr%mdGYBrLDeG_Isw(M zU$Xp$fF8be-QBm_u~b0%sPx_y^^K+dp4`sqHzT-G@?&Q%XEf&n${+=-9b$U~b&il=5o92>F@0C4S*uP!0LSq>g=xxqCDh z$PgA=B&(A$n&XiVc>?&%BT0UIkqLsO3+BE4M)Jn7t|!L!%p>`obp7|Hj7`|QB{5kW zXgMUY#-2Xnnb>mJr40G!OvcfX_k5-xn2(8<@BpKgDlnM}knfIJ7^amfFv$u)T!~qW zL$p!_CRYI#J#EgyS%rKL&g$XYCHx7N1s9=KCjzJ{TvW z7p!sUfj$bVffdGq83L1nYGA{0VBpP=)#;jnt{J980hatzKONUP^qQ?(0UB4<0%69y3#E2IL6&q!Uq=Rpjs4tz5?Mit0(?ST`<5Jh{POMDn=j@c;kE$^ r3VFIXhE&{2PDn^;Vsc|+GqPadUdIqEbJpV=P?o{d)z4*}Q$iB}hcqa_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/left-right.psd b/workflow/public_html/skins/ext/images/default/window/left-right.psd new file mode 100755 index 0000000000000000000000000000000000000000..59a3960a2353ebe4c9a22bde84cb79979f3150ad GIT binary patch literal 24046 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/right-corners.psd b/workflow/public_html/skins/ext/images/default/window/right-corners.psd new file mode 100755 index 0000000000000000000000000000000000000000..86d5095386123b82d2cf11b8308dd1e40459fd9a GIT binary patch literal 15530 zcmeI12}~SS7{}k6nLRj~?k>Af5XvrxAQ6Ry3L4|4Xi*vsE)@@~F;uIT!~;q#R!!xo z)uypht+Z-PFI~})hN>+#^`KBdlxS&@1r)i;QLJ(;u!-ndFU z?hVIfH3V=ia=v&SEkb_JknvKq0%5@_bRgB*wE)!HJX6XfWTnAA;h5d z5041bN31j$^q8EckSmremCN-yjZUZkw@s+Vhe;4JEH)C7*f7I#V|~G8*jSxwl&GO-;uI*-972|-go~48IL@=@v+CB*p#(7cgwR|^PbyQShVBi zov*yQYwsIx?t80b|ADs;A36H|2bK>@KRW)&r=OiTS@HR)GgZ}RYijGhsc$@gq3OqF zYfEcqS9j0F-oE~UOT#0hW47^$N&6H=>`XX>e~O3Lj~R|*IR(UnnXTlCw8p{jjh16eys&)26}8rZI&jwcEb^b;}T6Rcji#e)*Im)rtEp z!~9ou5p?YDJh-kerY>3sXDoJ73%0vp(2n51!5s*G`*C?A&zl{=B~FHI)K- zxR_4;9~{^{#P@Xt4Gv`NiY_~CerM0v`hxG2=DlqdRS9=)DgAhx*MTg)-r{Jk|6XW8 zP|?}TVu?_pImfNazC93Fwf}4(ewL z>Va$KfdjIWf_mV#dEg+$9I859Gc3v*b78;Pm*UkpzM8BV9JsOCIgTCkf(_=07z1?$ zMq!MCdf=jYz{8WFpdPqw9`K}?Lsh412D)Zg6bCr+PyJF{>(G04Z3k#xx%Tr}s&~in zB}gD&EXPZn1K2i;9#C`WfUbykP(Mj%1JwesN@xOgo`QPdnt3n<*-1e?aN9hXBE=l4 zI)98*b~~;*=KKxYXYnhjISfKq#3fJz68b>(0xnAE21P+VaM3*A;mJ@?58O5ncv8%v ws`Cw`vh%p5!8wWfd0_(Pi5LfU1#B=zK|OHMJaEF3p`aePZ5}vDF^8)D2iAzm(f|Me literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/default/window/top-bottom.png b/workflow/public_html/skins/ext/images/default/window/top-bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..33779e76b8d7407100e44ea79974d9c8300a9573 GIT binary patch literal 180 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 e7??TCIy4q6Xzpf_KfuF~nAS2=D2zh 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 Ku&A#Ku>T(wJsgPu literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/button/group-cs.gif b/workflow/public_html/skins/ext/images/gray/button/group-cs.gif new file mode 100755 index 0000000000000000000000000000000000000000..7059e2b0ce43b8cdcc4fd0ca4491c1f2d2c55e0b GIT binary patch literal 2459 zcmeH`{XY|k1Ayn0bGp8vI4&>A+g`lnp;rRoe&*!-Sb+NU(x*%^Nw+R5?aJbIS&f($V z(b3Vdv9aalWu<@lx4{2R0llpQa)AF~@{j&`0-z`Z$SEs2odTq!DINs}bSomSl%9gAfA0inO#vK?R?q5YKJTw` zN>kGQtr0&^<5~y~796YZ`$i5mcg%@J7$ycV!^Z_I;(O|q_8c{+pOeSEg90Uu9ya+S z=ax`_bK_9PGsB|!1n7uHQ+e%jyKCm8%Eq`D$hZpAMO?L_NofM#@`RCLTp9?OlWPirG+klF& z9xkBSBI946v&8{$L_u*NW^uMOCi}fKc3~@*+gd2F1Ce7c1elDDGP4p#iRRB*Gl< z*96g=yCqr{H|_01PI2UpM6NX+)Fsgv-nXiC&@CYbTpT z*Xrd*GO7)$NYPJ0)D_E0Q@+XVCl>vYR^>lUlGaP@#4A=M4l$1u>m;EZ~ zNAsOGCaKBiw#58o**;enAaBc;Q(a3`u%Fsi#ka0o&{Bo*Cl2t9+rC3l@2T^26s&Ap z4o9!u)!Chro&&xT7SQgupV3oFe*Q{LL`gT}X@7s+ma93q7GuMkUW&%I4@qd5H9LCB zGDqXrdMHYk3r|b6(6-soQWE8nFf&sP>}dC*=cI8@s>|v-Ohx3}5Z-Z(c3X}GR)U1v z3&#fWolH9Y;q`cZExyqkI}|w&!~0QZ-InDbl^~LKg@fOKx@uGykDSjKoJ_9oIxiv> zPZ`5 zl*n@p&17{w!6IVmOWqHs(k@Z2s#=9~+QYe6LT`)(vur-j$XYI=1flSI`N&`DHcTij zJlZE^Vizvg4)QpFWj;A%Z+u!C-xuRT!-;B7*bDEr-5vBv`@*~V?K(l`sVrqy>F*jl zT?GD_T2Fhb5UO|X==Q60OW%zDB!(T<2YYFGH&&nF0bLUD0}mDGH9CeTU7h1z7hrv} zjT{h1eHy%hjK(^j1dux!I8+9w*W1jV^tipDn(-?t|24Z+(l-@heXm)YRw6wM;0?ScaigGT5^3=%xlAaH2Ai^cH6q7owvh2THj z2U(N~9wfwp@V+I3K}|9=ydobjXjAns&Txo?93=(>ShDHN1d|&`(1-3h2BT!w5N@^8 z^ETT5aphj5g)=1Z2A18}V{aOcBa98ZFj@v1mJrx2t3J1hmkClf$8XQ{ z79IR)8pUer+yF-x9v_*tEG6|NiZ0baf?3|27swVf%yh%}Y9EU`!GgrLSG<>COQ~}X zV%QKdq>aI8Nl!FSP=QQtnXzAfi81lOU||)w^Wf8qR6(VxT1D@#t;QAI0D!VG;LP8z CJe}bH literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/button/group-lr.gif b/workflow/public_html/skins/ext/images/gray/button/group-lr.gif new file mode 100755 index 0000000000000000000000000000000000000000..3f41fbd841a22ed3f7522bb853ec09b688021e0e GIT binary patch literal 861 zcmZ?wbhEHbe8J4f@STBS?%cV@jvagX@+H?O7!84u7XpeuSr{3BKnFyC@&p5i6$3K| zgTsae2b(#BwPH?eSa`TyK-p`K$HqlRyCsaX?wr`T_;|m9bC-BiH(bo_bWK($p|PYFjxZsYh*if literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/button/s-arrow-bo.gif b/workflow/public_html/skins/ext/images/gray/button/s-arrow-bo.gif new file mode 100755 index 0000000000000000000000000000000000000000..fa5b2f4e95781276d027b5d24d8e07607d8ab591 GIT binary patch literal 123 zcmV->0EGWXNk%w1VaNap0FeU#_V)I~#KZsq0RR90A^8LW00093EC2ui0LTCd0006^ zjE||y?GK}zwA$-{-n{z{hT=$;=82~2Dh}=o$MQ_q_KoNI&iDQg3<`(DqVb4KDwoWr d^9hYgr_?G`fW=z3+^#U|4U5M#0hwF?06Xm!IU4`~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/button/s-arrow-o.gif b/workflow/public_html/skins/ext/images/gray/button/s-arrow-o.gif new file mode 100755 index 0000000000000000000000000000000000000000..52a514132fefe43e5ce98ab2c9198fd32eef2323 GIT binary patch literal 139 zcmZ?wbhEHbeZ_wM~*Onf#OdVMg|6E1|1L&B+tMU6JxM)_VIjyn7mb4 z$$3V}zkL-=>{N?`WOsDw{+wlKwR-lprQv(;TRnfwSnM=s`48hwO=nsj{M@3sz@*LL onoZjDBWq7{Gbis($(@<)xA^+~;^@C=?RSeSV(qqxFfdpH0P?Ul>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/form/clear-trigger.gif b/workflow/public_html/skins/ext/images/gray/form/clear-trigger.gif new file mode 100755 index 0000000000000000000000000000000000000000..be3ff587cdb41bc01c38b02f378b7097c49e41fd GIT binary patch literal 1425 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/form/search-trigger.gif b/workflow/public_html/skins/ext/images/gray/form/search-trigger.gif new file mode 100755 index 0000000000000000000000000000000000000000..0cc4f596b4afa65392eaa6f63fad54238705eb43 GIT binary patch literal 2220 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 a(II?Zs7)DAnPM9b=8J95L)rdV=-9sjoxm#q literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/col-move-bottom.gif b/workflow/public_html/skins/ext/images/gray/grid/col-move-bottom.gif new file mode 100755 index 0000000000000000000000000000000000000000..c525f7ebd730582b18ee02869d9aedc9fbbf527d GIT binary patch literal 177 zcmZ?wbhEHb(@`2GG*e#iL++S^78UZPEMXP zXHHpJSx-;Tk|j&3s;UYL3qwLe+}zy4!osq$vT|~A{{R2afEy_OWMO1r5M$5*DFNBZ zz^b=EHR@P~l5oms E0PIgRd;kCd literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/col-move-top.gif b/workflow/public_html/skins/ext/images/gray/grid/col-move-top.gif new file mode 100755 index 0000000000000000000000000000000000000000..ccc92b6bc2f7a55aff742a88abc09822e90237ba GIT binary patch literal 178 zcmZ?wbhEHb({T(&(CjcY%DJ?-?C*(Sy|bfIdfL6TGia#TvAff*Vh*k5;AStwEzGAGoS*+ zpDc_F3{ng_AYqW546OPKmPs-g@+{)e34FXnYNNs#M*b_Is!E<0x||NBo%E5L$LPGHH z@agI4>gwv{<>lPm-1zwT-rnBd-{0-+?f3Wh^YioX@9+Ej`{d;0?Ck94=jZbB^6u{L z000000000000000A^8LV00000EC2ui02}}^000I5U_k_AX_DfguBnsze#Gq|1{lW43fj5@t-5GijP6aC2o& zoi=+4_(?NpPogh*3S~(^XHBI`k(M-iQ|i;DOr4ITDzm9p09<`~)fyJ(Sf^!ETHOj& Y=-QoFhn@x6_UPQAb*tV@8aD(0JM!HA literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow-over2.gif b/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow-over2.gif new file mode 100755 index 0000000000000000000000000000000000000000..353d90626ea426cc2fff395d3d89c7bfff4b216b GIT binary patch literal 107 zcmZ?wbhEHbWMU9w*v!Ci>(;Gj&z?Pf`t;GGM|bbuy?y)ky?giW-@m_S&z^@5A3k~V zOG8X^< literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow.gif b/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow.gif new file mode 100755 index 0000000000000000000000000000000000000000..8d459a304e0b224f8c28d6b7b585da7019d28cce GIT binary patch literal 836 zcmZ?wbhEHbWMYtDXlG!!aN)x1H}BrOegF2|hj;HkzW?y)!^h7bKYjW6^C!b77!85p z9s-I#S%6;r&!7YHC@4=ba40eea>#gWNI1yM!7mYUVnf4WCKe8!85Rx=4Ga>@3=9GS G4Auam1ttan literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow2.gif b/workflow/public_html/skins/ext/images/gray/grid/grid3-hrow2.gif new file mode 100755 index 0000000000000000000000000000000000000000..423b507bbca6e8ff21a5c1c92c052f91497ab97b GIT binary patch literal 107 zcmZ?wbhEHbWMU9w*v!E2?AfzVpFVy3`0?GlcQ0SQeD&(p^XJcBzkdDZ&71e{-+%b< z;qBYE$BrF)@!|yo7%2W^0n<7l5@ZGgi-f@m%~b(fOAj88;wb8I^_=69yvE_Rkq--l FH2~F!G;aU^ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-bg.gif b/workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..12d64d7cd45677be881f27077bb4a41a944751e2 GIT binary patch literal 158 zcmZ?wbhEHblwe?DIKsg2>C>ktPoBJe`}WzhXOAC0{`m3ZhYug#ym|BP-Ma@59vnM% z?8S>0uU@@+`SRt%hYue;di47BYX(w);!hT^avcx}vXg;TT0x; TxTf?h>0Gsj`?N_k2ZJ>LIA}d7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-sel-bg.gif b/workflow/public_html/skins/ext/images/gray/grid/grid3-special-col-sel-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..4fa6e10714e6b2b234ba96add832107d50803cb1 GIT binary patch literal 158 zcmZ?wbhEHblwe?DIKsei>(;Gv=gwWbcJ2K6^H;B4y?OKI_3PJf+_dculSFT*Sbm`LBvu7_~zI^)hX$De&;!hT^avcx}vXg;TT0x=fXd(yGK^tEq9>)hd T6PkLKbgo*%ecB|NgTWdA;B7b} literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/group-collapse.gif b/workflow/public_html/skins/ext/images/gray/grid/group-collapse.gif new file mode 100755 index 0000000000000000000000000000000000000000..c9ad30dd91e6a867e8646c431a90025edf9d0977 GIT binary patch literal 136 zcmZ?wbhEHbgxLc|NqsiSKqyR_wC!aix)56vSrJsPoH+}+I8{b#idJ^ z9zJ~d=+UD&_>+Z^fq|Dn2gC!J!N6j=;iTv4tgxLc|NqsiSHFGxcFUG6ix)4xd-v|APoFMcyts7f(p|fD z9X@>c=+UD&_>+Z^fq|Dn2gC!J!N5|u;iTv4t!^)-cttuXbRB1CQ3_Cc&cV~h zq{5hRyGU?KL!&^0(@6#ggND||K*tOwvF$G&IjxOae`8JA>9Jef<+APMSO=R*=CO07Ly*b^rhX literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/group-expand.gif b/workflow/public_html/skins/ext/images/gray/grid/group-expand.gif new file mode 100755 index 0000000000000000000000000000000000000000..663b5c8413e2b56915358f4428ff10eb11dac023 GIT binary patch literal 138 zcmZ?wbhEHbgxLc|NqsiSHFGxcJboHTefVuc=6)hyLUf*`m}4;uBA(t z9zJ~d=+UD&_>+Z^fq|Dn2gC!J!N6j^;iTv4t?n61IU=1Dx=t{(CegNBwy!@vwCvF$G&Ij!|mVz34PFx@!Q literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/page-first.gif b/workflow/public_html/skins/ext/images/gray/grid/page-first.gif new file mode 100755 index 0000000000000000000000000000000000000000..60be4bcd3b851cf6f0d853b503467851014b5d2f GIT binary patch literal 327 zcmZ?wbhEHb6krfwxN5+Vot>SMlCp2#K37-QY15`npFTYyA)%$ErKzc@qoX4%EUd7w zFg7+eD=TZtlqmrL0p;c8US3``H8qKei3blJY;JDevuDrh)vGsd+*nsvw`$d@va+(> zyLY#?woaHZVcxuXeSLim4GpQOsW~}0m6eroadGqK&u?sO?CtF>C@5I7W=(s0dwqR< zet!PMi4!X-D*pff&p--L{K>+|z+k|j1JVTY69Zd{!;AtC9jSizCe9QW30V>KLRG^m zi>rxF42Eh3v5Bq@5fau?#yToHWEhT}VL!KN1=sq9!p9d5N3pW=^0;a0wK%aUGjh4{ kYVgt-9n3$cNot2d}efsn%Q>ILtHm$C%ZqJ@Q6DCY(ZEfAS zapS60tJ>S!!@|N+Q&T%SItmI3%F4W{`~nVDJi|Zy#WCM^XAR_|NlP&Re|D97DfgJRR$f9sUSZwuq7Rs zRN$c_)$iVXk>QdAcW+W+lA)Tw#l%IA4V?t!4+?C0AR)@lgt-9m^gj<^z7{HtgNiMy1MrE_C0&{Oq(_>EG%r}#*M31 zt(q`lLPtkOYinykLBW(MQ`W3mQ&v`%nwt9m|9=KTK=CIFBLjm7gAPa`$W8`U69v`2 zl+1Y=txMEWHmDTuF}NyoF~GV@;l-LmP7WL@5kfA44Amk`J`#xnt-h-^IOLvwJIRT` F8UTl6Iw$}D literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/page-prev.gif b/workflow/public_html/skins/ext/images/gray/grid/page-prev.gif new file mode 100755 index 0000000000000000000000000000000000000000..d07e61c36a89c5c40e752663e60a9500e383dc53 GIT binary patch literal 186 zcmV;r07d^tNk%w1VGsZi0K^^uzP`R>WMqVdgqN3>U|?XZtgL^3e_>%^N=iyzUS52B zd~9rNcXxMIR#u3JhP5f*_)&66N(rk(==>!EPJ;8F+xJ7^b4JOBUy literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/refresh.gif b/workflow/public_html/skins/ext/images/gray/grid/refresh.gif new file mode 100755 index 0000000000000000000000000000000000000000..868b2dc594ed057242f5b642e0c28a764edb9412 GIT binary patch literal 570 zcmZ?wbhEHbVk&zkko3Jv}`=wY9ay#l;mB6<4ob?da$@cI?=#Tem)b z{CMKTiA|d}ZQZ&xKR>^vrDfv8i8pTCsIRY|JbCi6Wy|*N-TV0QV64I4HT6%}2& zbm{*6`w0mN3l=Q6dGlstV`FP;Yfetip+kqxo;`c!%$e)guh-Pn%$zy1s;cV4hYvnJ zKCfQAnloq4jvYIinwoz8{CW8B;Wca4ELyZ^;lhQpX3aW!^k{s1{L-aMr%aiWnVEUy z$dTEzXYb#?zp}Ejy1M%I?b|bE%y{tN!Rpnk=g*&?oSb~+%9Ws?p#T5>GYkY!{K>+| zz!1Tp1F{?xCk*V<8zPz_mX9^mC-VXy`OS3=Nw literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/row-expand-sprite.gif b/workflow/public_html/skins/ext/images/gray/grid/row-expand-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..09c00a66baeddeeed16bc06a428b8a93bf4d944c GIT binary patch literal 196 zcmZ?wbhEHbG-BXm*v!k|>gxLc|NqsiSHFGxcFUG6ix)4xd-v|APoFMcyts7f(p|fD z9X@>c=+UD&_>+Z^fq|Dn2gC!J!N5|u;iTv4y%w*}?*6|Zog-zE$Wf-gr!$+J z6iy#!IAEOn*eF1GyMIntGK=kDhJ=Iw8S9f#pHF&fFh(>8r<_gNKHq5pn}GtymEMRf vw`Q&&hNg#no1d5ZCmMtc{L7T8uC1?><&KNglJDqb=vJIKY4Vgwf(+IG0D4r1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/grid/sort_asc.gif b/workflow/public_html/skins/ext/images/gray/grid/sort_asc.gif new file mode 100755 index 0000000000000000000000000000000000000000..7e562e202dbba8990cc767b17ee85c6f73e18bfb GIT binary patch literal 59 zcmZ?wbhEHbAFQW2399tFN!`=jWG^k>Tm-nVOoKkdTm=m>3@)ucM=5VPTP! zl;q;#QdCsr>gt-AnaMyip!k!8k%2*pK?h_5$WIJxE)Ek5JanY`Pb?|&)L~&*_%wZi zgMrY=Lk}DsSy*l?ZqBmQ;Sg3~cw%Y8Dv**Y*ufyx=JUzv0SAwix2%w~gim`%XO|;` FH2_I2IVAu9 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/menu/item-over-disabled.gif b/workflow/public_html/skins/ext/images/gray/menu/item-over-disabled.gif new file mode 100755 index 0000000000000000000000000000000000000000..97d5ffacb769047b4e0a889446a9df4d1ea5aac4 GIT binary patch literal 49 ycmZ?wbhEHbWMU9yXkcJ?_UzfGPoETjvM_*v4u}BBFfeiS^h+Li%OB6kU=09UoeaJJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/menu/item-over.gif b/workflow/public_html/skins/ext/images/gray/menu/item-over.gif new file mode 100755 index 0000000000000000000000000000000000000000..e0dc5f7c06c1be1b3fd4e7104be5b3dd0b63c9d8 GIT binary patch literal 850 zcmZ?wbhEHbWMU9y_|Cv^{rdGAH*Vazb?f%++js8Vxp(j0g9i^DJ$m%`@#CjYpFV&7 z{KbnGFJHcV{rdHrH*em)ef#d+yAK~e{Qv)-VHAvpz|ao?#h)x-Pw0S1P@Z7m&}UF~ zX<&GGkeQuN$|T`H!a*ihE+G{M2f>4l%xpX&HzFDs8X1{cI5-3t8ax>o85yhruMk2c literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/menu/menu-parent.gif b/workflow/public_html/skins/ext/images/gray/menu/menu-parent.gif new file mode 100755 index 0000000000000000000000000000000000000000..5461a8bfc3ffb5ab25cc99893e322d0ca5c58df4 GIT binary patch literal 165 zcmZ?wbhEHb47cl-k`l?M?apNK gSu&}?Nn$+-O#2ckbM|ckkYV2M-=TeE8_mqsNaQ zKY8-x>C>mro;`d1{P~L)FJ8WU`RdiH*RNl{dGqG&+qduDy?g)u{f7@9K7Rc8>C>mr zpFe;7`t{qlZ{NRv|MBC;uV24@|Ni~||9^&2Fd71bG6WQVvM_=irUN2Cd4hrCKLaC= zgvW*j2N)HFw0t~19ByqFkgt~|J zDlwsjIpJ_qufd1L#?2Y$?KEbay}iZA%XMO|_V$AgY%HH%ojslKps9)VKc9!ff(;K3 zak43K9N1x)%+e)m-DZ=p@yYRt`s@pGej25poo!q#ru%bq+U3RC&2F)?zNB35jocqr zD`l2;Yo+z}V|$~&=iJ|z+y3lt_11!$2Rqf->t_Efcz$BGbhzGLv#-xDFO>uP-(Nl4JpH}hzP~@ezkYmw{r>--zWu)_o>0g9DSScw zRlykx8o8Bz%x&T~l33V$FVsS=fmd!tVw;TLj)m>AQ5yF;o^nb&YE^4mv8Y4U>4Z|- z;l_r8JtpTk4mlWI^LX6L{A7hPo6WBk$rJ2vbtF%8kc(8A=&kird9uHi<&r6;PL`?t z9#N61Q>}|KRi^niNiLlc&b3o@X8Np~srFmmru*Rq`7=<)xAjd zdBtrnpU-Rfq?s|lLvGcJ8O>(1G#2+ylgyko`Pt4DOQr|STDf#Wo>a#21xZq?mMt#Q zdbM)NqO7b{Yu3GbwS3i~@LQ|ate1+?TD#+x)arGcKSgCPJn&CbXW?P1S1Z@=Wb=Nr z>DaxlH=9qH?atmZRV_Ma>xH;#ovpXCUh8bXUuCV^Cp{%QZ>QtD>bzaA7I|NA;^r+8 MNMK6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui0096l000OW0QKq1ch4TZdGX%0V^^-B!-o(fN|YE7 F06QjbkQ4v_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/panel/tool-sprite-tpl.gif b/workflow/public_html/skins/ext/images/gray/panel/tool-sprite-tpl.gif new file mode 100755 index 0000000000000000000000000000000000000000..18277a3d4873a92ed7b481533026dd6e6f91f831 GIT binary patch literal 971 zcmZ?wbhEHblw;s$_|CxK@ZVw1oH;vo?0ER_;p4}TpFMl_;>C+suU>ul@ZrmsFWI% z7A6UgIUW-k53w<_W!yPYc;Ik{sB_dAjY*4+cW?)-irJa)gkhS2zfpk0=4HODdik%W z%v`Yi{Cv(BCRr`v#*2$R1b6tH3Q0S@TyMS|ufW8HtE(e8cbqvDn%1~J;jmbN=C(CH z%o&$gnLa358$FZ#(W$xB2UPFwHWI%x^>&bh+umw^oevfpo*e0xT$)#-@nON^771A^ J5eWeXYXBZ@aLoV! literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/panel/tool-sprites.gif b/workflow/public_html/skins/ext/images/gray/panel/tool-sprites.gif new file mode 100755 index 0000000000000000000000000000000000000000..11845e66c96040e4b4e67a50e9052ce02b58bf0a GIT binary patch literal 4464 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 z
      zk>A&6NIlkj-sVT_OPx%!x9L{cr){prc@2dW^tpj}Pm3ps#$2QLm7(E?1MGy{ z6ZtFOFca$0vaS}V9|7Ko1|uFA-hhz@vcEl$EWoitPr&3JK`x+Ra~%88-zIderr88X zg_LA2mI81a5tcUf;5E@-eG|fipu$b1Jcw2nhKngp4Gzi$Oi@%iEp_$Tv83!QG?#^qi2aEZzy5bNg$xOqmj@Wc)X8?+e#} zx2GKV<{Dy)`=4Fkf%;H;vx5LS{Mwa3j{r%VOGk$2Xv#)?FjOevEmxrluOU7=gUdQl z*gS#mE7&Gm^2u0eS`L@B{XD>_DFmLbgiw(NUhP4@u&~a&>mna)S~O8-e#`#U3%IQ| zN2=3k7_G;by;ep9JH4bG(enlSv^#X^jHU>E=c3D(e^WT2Ot2G%aZBIz+NF&#WGfBj zZDEw;dn$2gb(E6E2LI%s6c2S)mxue8^tJljWbOk;nCiBlGzM>~c{$Z1Af^tgZXzdq zBC4cK!cp#5$_t)cEbR*HsJVn-7^>diuM}jXTs>YKvuAXG_RdY6?-TDfUyXaM)i;bK z<<30{FY|jUa8QjeaJ;l|Sc8QFnH93AFO1cZ?+a!&AZ1o7`Z*B-o+sg0ks7%ci%jrJ zC$+QqdN~03f^yJdCw-b?oo%GDx<_`U+M8*an`qVhj0A#9t-%q+66OxprOG+k z;k#<7J-tcg-Ulc}dv`TPSiHEw?iKz4iSL`JqTi^#zSoG9Lyy_twrF%s8-zqy_w5{e zM0?U#MacpUU)6O6$fPDu-KN4DoSY)&fOzEjuZ1_Cc@}RG0lVmWc&Da=es63GPPFir zjR1j@zf@{qGPdG+I|YZiAdh_9Guscg>=wx@J$tEAug5*j%jz}vRKQGUcQ!4*a?skkU! Z^yiU%(_7GxN+;&t=qS6-??+=?%lih?%jLv;K9R(4<9{x z^!V}Pr%#_gd-m-4^XD&KymC#}q}WS5eO=kFvq*AsijL3o~JcpmZ-+$h~ z_Wy_3jh&1fGyeT$7yAGIfBVLN2O~0szQ_GbNqF=$At@m#iKWO-O#2ckbM|ckkYV2M-=TeE8_mqsNaQ zKY8-x>C>mro;`d1{P~L)FJ8WU`RdiH*RNl{dGqG&+qduDy?g)u{f7@9K7Rc8>C>mr zpFe;7`t{qlZ{NRv|MBC;uV26Z|NqZ03PwXBf@$o)cwxSshn^Zjcn9V&RP8L0FYm`zr zF-J4_@BtqFqE}~TCMvM8J2W#LHMqdkyx5~ZO2Wgj@$zy%O@mgh&{qwdoSU-FS|uj5 zFee;t>NWV#*tj|4yq(5uv$wYxdAUx^)!u&4fsN(UtFxyQ9yB$v{^#>hSg_&YAx<_W zjsrUklUcfCt=nu8Ha#dLpePP@EVyV)&v)|Zs)y^;IFYNgE5 zZmqQ5er#{__niA1bK9T&t=?L2^I)esd)@4x1ujycUf-(#Ro2S3G+xPe9_t%f_uiyXw)3^T@#S`k7KZP%-zbZIm zK_j=)kGW0!MiL8~?}b{(HSo%PI)1&kOz~ zsj(p9ljVy!9nWUInBOh8>c!$7r&k$Erub!LE^JEj(wH%O(#;ji<`+q=T0W^MYSoJ6 zlcH9xT)pVls#Vi>8A)lcS#!?n+1jLMSs82hoVumGb{`w}n+-eOY2|F3DYrU%(-FPf Vnw!pBS!->%{EX|yRz^k!YXB4;a=8Ei literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/panel/white-left-right.gif b/workflow/public_html/skins/ext/images/gray/panel/white-left-right.gif new file mode 100755 index 0000000000000000000000000000000000000000..2c9e142be832aa2b1bfc7e5df32cc70f5c721c6e GIT binary patch literal 815 zcmZ?wbhEHb-j`MZjT$ M!a)WGCME`J0Q>YT`Tzg` literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/panel/white-top-bottom.gif b/workflow/public_html/skins/ext/images/gray/panel/white-top-bottom.gif new file mode 100755 index 0000000000000000000000000000000000000000..025fbd51ab056b068cd7cf2556652263d26bf578 GIT binary patch literal 860 zcmZ?wbhEHbWMt4`{La8|{rdGAH*Vazb?f%++js8Vxp(j0g9i^DJ$m%`@#CjYpFV&7 z{KbnGFJHcV{rdHrH*em)ef#d+yAK~e{Qv)-VHAvpz|ao?9gr75d4Yk$k%85tgW+Lg zGaHYXhDQU#K}Kd)E&&Mz1%`%h3FE9gCpIoV-ml=?CF6N%am!?l;8igvH!VFq-5~kY O9M8?md>9!S8LR<>K~9zc literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/progress/progress-bg.gif b/workflow/public_html/skins/ext/images/gray/progress/progress-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..5585d802fb566804cffd9ca41775d2aa9fc39ed8 GIT binary patch literal 107 zcmZ?wbhEHbWMoKS*v!DNYuBy|7cMMbymj=gw27P8~UN zWb@|DD^{%7zkmO%S+kZbS)%xpg#iR~Km^DP1{Mi}6P~O0?ohjWL8?EQ<4mA{!>V;T LulMD!FjxZsN)9o; literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/qtip/bg.gif b/workflow/public_html/skins/ext/images/gray/qtip/bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..a9055a5ebade2f4ba2f5fd1461d9f8a3478646ac GIT binary patch literal 1024 zcmZ?wbhEHb({T}zkmPv^XKp1zyJRI`~Uwx!zdUH zfuR-xia%L^PX5oJ19CVhPcU%YWiaHBu_$Ob*v!tU5p!b0!$V90%5EkO8qa=t4qF?&UHs9h zx!&8?-Q8V&|5fbiZTaz=8je=Uz7buWxT-_gJoe0&70HVom6`8){#=$i+tB!M%*mfi zo}cG*==yeIqlsJh3T>~Lw;M{GTQ(%ii#Y5qd&{t+`1QTH(hcwLA87v1$H8C?08ARV ACIA2c literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/qtip/close.gif b/workflow/public_html/skins/ext/images/gray/qtip/close.gif new file mode 100755 index 0000000000000000000000000000000000000000..69ab915e4dd194ad3680a039fd665da11201c74f GIT binary patch literal 972 zcmZ?wbhEHbg)|NZ;-|Nno6Q7{?;gDC_Qf3h$$FfcOc zfE)$N6ATu z!(r;m%j_$9KP-wo!oMF4bR^Z#pCLVEt6JIYJY>r`(GBHu8TKMAH hV%craN*NY1aV$`Fvrs8ibZTIkpzPfzqoBZG4FEi-n5_T+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/qtip/tip-anchor-sprite.gif b/workflow/public_html/skins/ext/images/gray/qtip/tip-anchor-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..0671586f3b1af76f979139cc3d9d702e7827da17 GIT binary patch literal 164 zcmZ?wbhEHbRAb;`Sj5Wk<;$04%a-lmzyJC3=N~_QWPkz1pDc_F46F<~AOVnC2IkC& zsEw{H9-N*Tdb_>D1SE`oE(r)QOJtofFY!vKV&ZHFuF9Nl;I&ce#AoI+IaWUFIYcC# z=byX~7W8ukgPX5WPj4FQ60K*OEWHC1)y&W7s0Rjxi#TnK)Sch@bIH~6iad1zGXd$w J4oOZ1YXEz3H%|Zn literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/qtip/tip-sprite.gif b/workflow/public_html/skins/ext/images/gray/qtip/tip-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..4ade664ef27fa2cac59f5f12aa28e5c3e18d3151 GIT binary patch literal 3241 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/s.gif b/workflow/public_html/skins/ext/images/gray/s.gif new file mode 100755 index 0000000000000000000000000000000000000000..1d11fa9ada9e93505b3d736acb204083f45d5fbf GIT binary patch literal 43 scmZ?wbhEHbWMp7uX!y@?;J^U}1_s5SEQ~;kK?g*DWEhy3To@Uw0n;G|I{*Lx literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/shared/hd-sprite.gif b/workflow/public_html/skins/ext/images/gray/shared/hd-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..d943833e1dcd0f1418ee3a9a014837d437f19b28 GIT binary patch literal 305 zcmZ?wbhEHbWM-&lIKse?o}QkOkr5vspPHJQl$4a0mlqcomzI{6m6es8oSdDVos*N3 zkdTm{pP!hRn46oMl9G~{nORU!5E~midGcfj2L}ecK=CIFSY8K2g6w2qU8lehGDXAF z;qsE~KnA@(cKjQ3%+_ff;8W;`HxOcEVRCyCctk{&uR%S*U`E(V1`d`99tC?@m=tWp ztYsM3l=q5pFy#HXoxpH`aq`I(kyac388#Z5np@i1*f}^cxOnz?`}ze0MNAEiil3P> zJ1rwCr)Xhed3mLe$O?5Ktu?%Q>o=J2n{VN^-p=K)i^E0GegA=pf&NEAjvbE@h&|1j YcZn9MhD>7IE08Nu#L;wH) literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/shared/left-btn.gif b/workflow/public_html/skins/ext/images/gray/shared/left-btn.gif new file mode 100755 index 0000000000000000000000000000000000000000..3301054ffa24c326b0f13facdb9382e53a04d9ce GIT binary patch literal 106 zcmZ?wbhEHbcZPNXD=%e)X*S+`s_LuCFGq}OPQnJK>iNP8GgMlO{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/e-handle.gif b/workflow/public_html/skins/ext/images/gray/sizer/e-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..a8ed0edee93975d0d233cffe52d9f2e85e7d0d81 GIT binary patch literal 753 zcmVFMR=<=fla;Nak+qoe=-{{R30A^8LV00000 zEC2ui015!m2LJ>A7(xU7iaog61kuiXaqZj{Zl73^l9{3!wYse{!r)1(vG>Y0zw5b~ zFW3XtenKPeNJJKs(5KW%ZCaVwrIwZDZg1W&cs%TqmE!VOokpLdRWtiNy{_H!Jbn+i zxBGH@b%B6)g@1#FiHLEEjf{SDkCKskhm?ein2wc#la`vGpPrqUqNSmvnWLtvoU5p; zsjalLwz9afy0E;jzL34Zznj9v#K)(>$gal8!_Ljj%eA@6(9^fO&(hc3+~3sN(c#wM z+2!Qh>Eq|>?d;X=@$ll<^Y-=L>-gyJ{POwC-P7lf;6Q-^_ZduB5MjTA3LOG`$Pi+~ zh!`(ww8*jlqDP7#CyJyOlH|yLCR3tZxv(Tli7H#3lo=D|%Zwde(!9Cx<4l`7g906j z(`U`1I*Im7iu7mGqf4Deg_=`pRjNjLUe%ga=u@str-HTGRq0l*V$q&8TlTBkwrSah zUF%jZ*|~7(#;wbDuV1}@^9sgG_^x5Bg%KYftGF@a$8Qruw(B_ZV#}2&PwpF7GUm;H z2Vd6wxisn1oJD6&?HP6G)~rXzUj15j?V|+>1j%inhJoIOa_=qxoWySs9Uuq?!P|Fn z2+3tE7t!3raoe4-s|KB&c6aXEP0t1o`!;#)<-dzJzh1p-_v71#e?LDy{q*(O-$&2i zdw%$~`q?L7fCK_);C~3>r(l2Q`M02h49fRlgA_^_;eHTiSRsZR4tU^%7HSw`hXp2h zp@$}l$l-`AuIM6)Aih{)j4+-!qm3Wpm?DWes#v3sHv-usk2|*bBat))iKLE64r!#4 zPdX{1lt)HcnLb)ZAU<%nKm0oITW|?S`spgn$a_MH6ON#lXoN!t>XPkK2 jS?8B@_L(Q2f1bJKoqGCNXrO7fxu>9t8Vaas2><{)RT`I{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/ne-handle.gif b/workflow/public_html/skins/ext/images/gray/sizer/ne-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..6f7b0c2958b20d3b23c5abda3b43dc1559f9a720 GIT binary patch literal 128 zcmZ?wbhEHba@|Np^*2QOc~eD>_wty{OAK7IQ9`SVAQ9s$MC zfZ{(v=c3falGGH1^30M91$R&100tcfAOIQ2z@i{I*Ph) Snkw8Vqv9&yY7rpFU=096AV2B= literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/nw-handle.gif b/workflow/public_html/skins/ext/images/gray/sizer/nw-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..92ad82cf3642db5fa14321505b5e121c878e9758 GIT binary patch literal 114 zcmZ?wbhEHba@|Np^*2QOc~eD>_wty{OAK7IQ9`SVAQ9x-45 z#h)x-F&z*IGJ}CdUf_i1>b(-&iQg7D3A8Y#b~JNvITwj6s8C>;%Es#G!e9*m=iw+~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/s-handle.gif b/workflow/public_html/skins/ext/images/gray/sizer/s-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..d7eeae278cf8013f3cab45c1b9a069579cd20bdd GIT binary patch literal 494 zcmVFMR=<=fla;Nak+qoe=-{{R30A^8LV00000 zEC2ui0MG{t000C37`oj4Fv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{ za7Zi~Z-S(9$!t2G(5Q4uty-_xtai)odcWYXcuX#v&*-#z&2GEj@VI=gEEJM<{9TZz z`~QG}f`f#GhKGoWii?bmj${Opl9QB`mY0~Bnwy-Ro}ZwhqNAjxrl+W>s;jK6uCK7M zva__cwzs&sy1SBg1_Zvq1;4?(#>dFX%FE2n&d<=%($mz{)~f^A+S}aS-rwNi;^XAy z=I7|?>g(+7?(gvN^7Hid_V@Vt`uqI-{{H|23LLo2fPriV5gr_nkf6hd5F<*QNU@^D zix@L%+{m%BqsMswLW&$ovZTqAC{wCj$+D%(moQ_>oJq5$&6_xL>fFh*r_Y~2g9;r= zw5ZXeNRujE%CxD|r%fOt?uiw9b0}CEZxUk{Fh!ZPb%($`R$B-jSo=my2<;$2eYu?Pcv**vC kLyI0wy0q!js8g$6&APSg*RW&Do=v;9?c2C>gG~ScJ5XvO>Hq)$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/se-handle.gif b/workflow/public_html/skins/ext/images/gray/sizer/se-handle.gif new file mode 100755 index 0000000000000000000000000000000000000000..f011a3bb2e9fe281dbfcf9adff0eb0d370456557 GIT binary patch literal 114 zcmZ?wbhEHba@|Np^*2QOc~eD>_wty{OAK7IQ9`SVAQ9x-45 z#h)x-F&z*IGJ}Cde!>KyLktoEC96(26sk0TNWB^$x!`%@(u5fax%VsL+!?F^5i=~8 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/sizer/square.gif b/workflow/public_html/skins/ext/images/gray/sizer/square.gif new file mode 100755 index 0000000000000000000000000000000000000000..7751d5e15a785f1a50b61bfc8c5c21a0f9421358 GIT binary patch literal 123 zcmZ?wbhEHbU|4d2;*qZ3YaW z_>%=JrUN2DW-zd52%PXt-63)MQ1x^Vjjla@|Np^*2QOc~eD>_wty{OAK7IQ9`SVAQ9x-45 z#h)x-F&z*IGJ}CdQNY8%Nu$L_;f>=h6%OYjk=co%2d}ZN*Oqv^;cmsc_YN!!)&M)r BE5rZ* literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/slider/slider-thumb.png b/workflow/public_html/skins/ext/images/gray/slider/slider-thumb.png new file mode 100755 index 0000000000000000000000000000000000000000..4bf01be8952e0c2fef407b15833da6017d6109f7 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^T0pGJ!3-qdOK@HUQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JidF~sgt$I@_;B;)&HMN7|NZ;-+qZ9@J$p7`!i0|>KYsc0 z<=VAt_wV0-{rdH#OP3x!dNgz9%=72Z-@0|{>({Sm&YU@R?AVDDCypOKe);m{PoF;B zym|A-j~{Q|y!rO++q-w~K7amv@#4joFJFHD{{8mt+fSZ6dH??X)2C1G-o5+y@#AgV zw%xdKFMGaQgQ3em6JtH4gw7iXTCHLoX8mN z*7|^HhsrVC?)U#wX8NrPD0=a2n)kovDWUPEBHNVpY$MHg1a!`mIlt_#PNlDU{wDt* z%eUJ$9e=9wT}x5Lck&TO-bGuk8JYOrb>V&8*S+xP!PU2 zY!7Go_gY@NW47AM9{xTQ@Lp{e-&5zgF%!RhD!RKy zbZ_MTebJ%c{eoAQ?fxinebdyHf}U6Vf8VY2+xL98 kY*b&K&6+bQo{5KH?i&LMUjMf>z?fn1boFyt=akR{0H@W71ONa4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/slider/slider-v-thumb.png b/workflow/public_html/skins/ext/images/gray/slider/slider-v-thumb.png new file mode 100755 index 0000000000000000000000000000000000000000..6b3eeb703f92943763428b44292197c8b4329fb4 GIT binary patch literal 632 zcmeAS@N?(olHy`uVBq!ia0vp^xDSr z1<%~X^wgl##FWaylc_d9MXLjRLR=p{e7Je@=KcHk|Ni~^?c2A{o;{l|VZz6cAHRJ0 za_!o+`}gm^e*OB=rAv<C>lo@7{g<`0=)F z+iu*raplUDLx&DMfByXF(W5_q{`~Oa!}aUeU%Ys6=gysb_wGG-@Zi;}S68oIJ$35T zxpU`$?mZ#-&=*KqmIV0)|0feLSglEQU|?XB^K@|xskn9J%FVn(1_G=Bw^h%2H9L1~ zHj_?aJatR;|Nm6csZL@`&OMph}E`~=f=Tz2O zg+2eNDRO5q$6Bkct3CIvQPIeq^>t^*XN?0d^FLSYo}>IFd$x_!i|Js`Th!K;C{w!?k>cW)*e3s-yXErJ4)uG?^4ZHy zRE4D!>Qy|bHE5X^zb-poBVw<|`sIJ}MW%#ZcG@4?cOgI5!tK8HN#Q#x=XO6#OB7kK zwW^c#`0KO37WiCDWO=FkI`bRr)~wsvQ<=*OraYX+@@3v6y(>&6b0^x>E8WfYoU$+c q)6O_c*Xhmkw=WFi-Tq`f12e;f`vwwc-H(IP6@#a%pUXO@geCwlF?9R@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/scroll-left.gif b/workflow/public_html/skins/ext/images/gray/tabs/scroll-left.gif new file mode 100755 index 0000000000000000000000000000000000000000..bbb3e3d9d35fd19b61bd8d0a0bd5f42dd3e82ccf GIT binary patch literal 1260 zcmZ?wbhEHbRAJC&XlG!^&(E){taSMA(ACv7Wy+Lw>(*VncJ2E0>o;!PxOwyDty{Nl z-@bk4&Yin=@7}w2@BaP!4<0;t`0(MQM~@yqe*EOglc!IgK701;`Sa&5Uc7ku^5v^n zuU@}?{pQV^w{PFRd-v}B`}ZF{eE9hB(?)aQ7{?;gDC_Qf3h$#FfcLb zfE)$N6AT>x8CW@FJT@#i*v!GL5p!b0!o%$Xo*r{NHZD5CBxW3>qp)c4@qPu@2^td? zE;%__!?=g%;HIUgrz^U}&G6j3>@2sk-C{6l>y=^}2HC1i!~*t=M0VE{$9P zi@oMX9bDPII>NT+#;mWag1Hh7cgcDm%xvGBv0dm!*S9s7ISU>il2tHY7tB}jF^^Xu zVRif-KUEGn9iS@@HP6k9*psLqzdu^sy4PXnrbLFR#@1I4+%&v@zSh#Z)nV3`rXetA5}PyR$*!>=zn%O#4ov)L+b4`x5mc->6qPNwhq3GQb~ZY|jP`SiKP)~c^8 zDg&1DY|2hgsMuY$JmhNL$+@pe8h?I%#=gM*|I{_{oBTvi%=h2FuW5Vf=hLOL7VQ83 zpFvGPB8f%lnFtey+KLBF96r--HVasl9%vB>%XrARcCWshkjGny1}Ebdi2H{)@iP2CISUI#YICEc!{DxP$D-rBLG z)A!hqC4F*iCzbjvvm~B&1@DVkI#nfUrfO#NJ&Uy7gtkhxnekCKmrl!-(tI`}weN@8 atb}_f(`IF@i(KAOwMb(5Bvuv{25SK3cQ--+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/scroll-right.gif b/workflow/public_html/skins/ext/images/gray/tabs/scroll-right.gif new file mode 100755 index 0000000000000000000000000000000000000000..feb6a76f0ae36a545fcc77242b53261680199c39 GIT binary patch literal 1269 zcmZ?wbhEHbRAJC&XlG!^&(E){taSMA(ACv7Wy+Lw>(*VncJ2E0>o;!PxOwyDty{Nl z-@bk4&Yin=@7}w2@BaP!4<0;t`0(MQM~@yqe*EOglc!IgK701;`Sa&5Uc7ku^5v^n zuU@}?{pQV^w{PFRd-v}B`}ZF{eE9hB(?)aQ7{?;gDC_Qf3h$#FfcLb zfE)$N6AT>x8CW@FJT@#i*v!GL5p!b0!o%$X+!JPaY+Q7-Q%FB+iH2eG@qPv8va$sA9+SCBOozMC+_uY(~X=Y~m lbWUzm=JUBFY&)M%sr~e0`Q%19%NG+`_f@RuXJlls1_1f>KmPy# literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/scroller-bg.gif b/workflow/public_html/skins/ext/images/gray/tabs/scroller-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..f089c0ad65ccfc9be9663e7e0d65f547e9160ac3 GIT binary patch literal 1090 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 H6%YVBg5#z` literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-inactive-right-bg.gif b/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-inactive-right-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..bf35493685825b861e5adcfe7e9c22d331a6e50f GIT binary patch literal 1383 zcmV-t1(^CrNk%w1VJrbM0EYko000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui04xDA000R80M!W`NU)&6g9sBUT*$DY!-o(fN}Ncs zqQ#3A|GC1*v7^V2AVZ2ANwOh0TqRSgT*)2C2rHjPTPs#T9uuWH@ORbkeyV8dShDz>cIq-4*kUAr?a+qZCG zqKr$ou3Wo#^NMtzV1UR_f)>(?$_!=9Z|HtpLX$<4*hdndZxy@S(a2VA)EmhXxmUtUt4 za^}!M&U+rcI>zbNvwOs@y}L#3-or!xOji%rx%24Lt6$H)z5Dm@;D7`cXyAbeCaBFH-H8z=%9oaYUrVeCaUP7j5g}%qmV`_>7ZqiaYU-(|rmE_ythVavtFHb;L(D(4)@tjmxaO+suDtf@>#x8DE9|hu7HjOW$R>*{ pGUT}8?6c5DEA6z@R%`9G*k-Hkw%m5>?YH2DEAF`BlEY3w06PxN$anw% literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-left-bg.gif b/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-left-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..96d2e5eb8a519e15bf48608df8d4c5b5a92ec7d4 GIT binary patch literal 1402 zcmV-=1%>)YNk%w1VJrbM0EYko000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui04xDA000R80A2l4N3fv5g9sBUT*$DY!-o(fN}Ncs zqQ#3CGh!5|v7^V2AVZ2ANwVZajwVy8T*n4zqDYe}O?q^x)2C2nHjPTPs@0BDuWH@ORbkeyV8d4ZDz>cIqGZpiU3)Vv+qZC6 zx{XV>?#H=y^Xi?5cdy^S3Ht&b{8upH!*&fLUi?-uw(>hI~UOiJa>(?*`!k(?vHSOCWZR6f;R5tJ5ZG8hDE>$@3<8qB7Urtgt z^XCPfLw_zXp7rb4vuoeZy}S4C;KPgmA5Xr#`Sa-0t6#5PpuG3++*pMVAms6hM_YUrVeCaUP7j5g}%qmV`_>7ZqiaYU-(|rmE_ythVavtFXpbD(kGWy28yrxaO+suDtf@>#x8DE9|hu7HjOW$R?}o zvdlKiEIGD1EA6z@R%`9G*k-G(u=?z`~DEAPDY I${P>>J76Hy3jhEB literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-over-left-bg.gif b/workflow/public_html/skins/ext/images/gray/tabs/tab-btm-over-left-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..164d1016945304e0f9bcc09126e78b21cf73dc6b GIT binary patch literal 189 zcmZ?wbhEHbWM(jAIKsfNZQHg_pFTZ*{`}XkUq65T{P5w!A2g?YaiOz=0)+iXNk%w1VJrbM0K@+9|9?da&}>gww6@9+Qr|L5oDySuyP<>l<` z?5wP;-rnBx^Yi25goS5=hKY(MPoOO23|ls}S{n3*z{nw_2~oS&kfp`)glrKhTo zsjIGrt*^3wv9q>zwYR!&xx2n-y}!a?!NbN{#mCB1$;-}9JI~T<(bLvq4%OG&TLaqM z;8X$M;pI&cn_%!zU{Pp+!09QO%P@tf}g9sBUT*$DY!-o(f zN}NcsqQ#3CGiuB@P=LpeAVZ2ANwTELlPFX8s$9vkrOTHvW6GQ<)1HExICJXU$+M@= zpFo2O9ZIyQ(W6L{DqYHSDS!n5qDq}gwW`&tShH%~%C)Q4uVBN99ZR;X*|O~js9npp zt=qS7(BTJr4xw7TUm@f-h zaGC>oFt6t5zwd>cgW6O?BU_pZ0xO3~?&AYen-@tPV(96ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui00RIr000O)0M-3-C6M62f(Q>PG{`Vv!-WnbLY(-p pqC|@n9mX3dZy>#a_6Fh`m~Y^|f&2#g8~Bf#tAXTPkz*GS06TgxpfLad literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tab-close.gif b/workflow/public_html/skins/ext/images/gray/tabs/tab-close.gif new file mode 100755 index 0000000000000000000000000000000000000000..98d5da9528411ee291e0548246d9c86a82455d32 GIT binary patch literal 896 zcmZ?wbhEHbJo2h-f@WP;TO2Q8ZC-n3TfI!6I*vV6fon wDRve~6%L2VX-sT}ybKHr5|%U0VVBS`*swq&a1L|0R%~U!f`d&=%uEc{0N$%ghX4Qo literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tab-strip-bg.gif b/workflow/public_html/skins/ext/images/gray/tabs/tab-strip-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..040b677a52f9a5eff89870aa31d1874765ea5a39 GIT binary patch literal 835 zcmZ?wbhEHbWMq(HXlG!!ef##EJ9qBhy?gK8z5Dm?KX~xq;lqcI9zA;e`0SnxjEQ?q`I@C5s=a;ag8W(E=o--$;{7F2+7P% zWe87AQ7|%Ba7j&8FfuSOQ!q5JGBmO>HB!(uFf}kZ+p+j0P#=4Vr>`sfH6CexDft?u z8*)G)&H|6fVg?4eLm6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LV00930EC2ui0096R000OV0Gl<#*3BEZaO23CLziwHyN3`XLJSB1 EJ2X9wg#Z8m literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tabs/tabs-sprite.gif b/workflow/public_html/skins/ext/images/gray/tabs/tabs-sprite.gif new file mode 100755 index 0000000000000000000000000000000000000000..1901b231b007616143c945403e60d961f41e3b32 GIT binary patch literal 2109 zcmeH`{Xf$Q0LQ;ZOddAN!(v@TbTf3+QC^++C1EKie%(+0&*Z1&L5(D3l^=;-L!*qA^d7#|-O3WXCB6C#mFEEY>75~)-=IXO8sH6@eDrl+T8 zW@ct*XXobTjiz=0BX=zEVRxd9vudJ-BuCA`Ft!XqG;QPKC z_@5cDQR`@byM+3NZ%qJT4e%Ad4{5w?u(lzB_ptP7E)=6<4XwvL18mXp!=3eI7!$ZZ z39*+|-UWsGRfl!4DzH$vS7*uIhROpFxTkcutD%Z-40i`_+Sgd!YXo=OcA~qn=B**z zWzXGxkLdjdaHsf@?njIu1Go)o6ZUa!2snyQ-+AXO^LV4}Xj_t_3N_LkGb`N0NOuY2 zBz^+fe@st_YR&y@PiZ+83pf%>brE{@*-m6 zqo_erlq2Oe_3_Dp%OQ;9>&GM8$Mh{i5j{{_;-^lsW5hvg;0owX8TS4`wl6_nmvw5a zhuuO1ETAOK=0k0*89G`hyI_7Bdqt%WiahMgY5TIWWY!tM<#4`+>7!o8jNcv5`FI84PYNgKdR?m`H9rRz+Tlal)cT}xsn%rrq-O0q{1 zGdJv*l9uHM?&cB9jwVc2P-8=R1bEuiWECyvDlzi`1&OSwtQ`80PQTrqz^Dq>01Srd ztI!0%hq`2VRz+IR5rdY=!u@?h& z$n0x3-=07>t$wD=*uifLY)*kqIz5Z~eCUXnI=T{3cxjFOIKI%=j=V+Fd-Pb#li z^vK3Z4s}byJolNUPx%;U^+aJ%vRXuqt5b_h(r45XTFPg)KS1p1!+!$QOXmUornZ}C z!x!EKXvkn&0U9RpCZo+%ZDcfD&!-S=Wx**#|KQ+Lgtl?#6rrE^@oy{d{R+9YkR1h~ zE?!FI6syh=BZ`+!-_%gl$)z01azg!O%1SIRg0dRj>qGg18;20rRz2O>ntpA;f)3RS zl*}iL_zP5~aBtlke4;2@pthrWudm~0OL>);idY>!i7Emf?**2a40ltL_G%oWr0F4Zah zDE0?F3)7&iM_qo0vv>~M<6;a0{be^{v*GW~fZeR5{AVyd&-YvZ4Jp`f3-ulOxy#-V z45ZM?-|FfR?m)nVlxihePiL;_m}Pfi*0qWjP5=M^ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/toolbar/bg.gif b/workflow/public_html/skins/ext/images/gray/toolbar/bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..9ab78a2ec788d6dfbbcd6212a4d3b1d9917d55e7 GIT binary patch literal 854 zcmZ?wbhEHbWMZ&jXlGz}_Uzg7=g(ifc=7V(%U7>ny?*`r&6_uG-@bkK?%n(M?>~I_ z@c;jRhEXsY0>d-}6o0Y+efFP02jo9co?zfGW)Rn5a1d~4Xl7*5h_P7kkby}+S!_nc jfrg{q>_&192R0@*^>d1J$arpAa&odp@G2Wg0S0RTW*Ik7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/toolbar/btn-arrow-light.gif b/workflow/public_html/skins/ext/images/gray/toolbar/btn-arrow-light.gif new file mode 100755 index 0000000000000000000000000000000000000000..b0e24b55e7ee53b419bdd5d769bb036b19fe9592 GIT binary patch literal 916 zcmZ?wbhEHbQ@i%X_#s+qO5ao&#Bg}b_z?(JW>fAX3`Gd3KV zv*q~0?WdOQKC^1y`Sph`ZaH>k$H{AZ&)(dB?ha5d!zdUHfuS4%ia%Kx85kHDbU>Z} zernn7GpqKUUw`Q0mSb0ToV>R8?9Kh>?)?A%A85cR7!84;8v=?yS(q6Z7#Vax zUI66@296R2W)2yT4GRu7a|mm>STHs?w+nNawPX}9G%#|o>fAZ8aq;nf1?Mgq&rM5C zPSyxs6?1aa(*sN*0#Y579~gX_Ir7AO7EE5yG(%Y4FT%k%!-dUUH;Lzh!*aJqzAC;N dg;0f-Rg6jrr6;$pzP>);aF?w2wgd+TYXG#xTAcs@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/toolbar/btn-over-bg.gif b/workflow/public_html/skins/ext/images/gray/toolbar/btn-over-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..ee2dd9860c799be6dc194b387c36a953c55aac59 GIT binary patch literal 837 zcmZ?wbhEHbWMoKTXlGzJeCy}&J3mj~|8@T1uggzJpf;!hT!Z~imrfcyl?6AT$05BdEW&i*H literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/toolbar/tb-bg.gif b/workflow/public_html/skins/ext/images/gray/toolbar/tb-bg.gif new file mode 100755 index 0000000000000000000000000000000000000000..4969e4efeb37821bba1319dce59cd339cec06f86 GIT binary patch literal 862 zcmZ?wbhEHbWML3xXlG!!aPPx~`#|*Z;=Kx_O l3y+3|gNw^!V}P zr%#_gfByW%ix)3nzI^@q^_w?u-oAbN?%lf&@819W_xJz*zyJRI{}04K5{!XHj)Kt; z7%Cy4_>+Yh5$9Jd%486*rY9BSaXJ>!E&dA8fU=090ubNf> literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tree/arrows.gif b/workflow/public_html/skins/ext/images/gray/tree/arrows.gif new file mode 100755 index 0000000000000000000000000000000000000000..a51a8e477fb2be3d370ba4841944dc6572f1673a GIT binary patch literal 407 zcmZ?wbhEHbbYKu-xN5{uSXij0rnYR^vME!hL`FvL*|X=yjT_gmUoS5&zjyCmXJ=ZH{ZT}`{~oC88c=qT)6PSfdgyTu0473+-@JLVX3d&gw{ERmx$^w^^N$`q z+P{DQ;>C;Ky?b}$$dN^h7Tv#p|LWDN*REaLw{PFMbLVc~zJ2A&l|zRPUAlCswYBx- z%a?cV+&O#pY(+)Ik|j$nU%q_s;K2tE9xxCM6o0ZXGB6l1=zw&9{KUYv#bIWFhmKVL zi6uoRbFAiHSW)7&HfsGv7tZQA7CT(nT3OY&3}$5{PPAbVn7G3Ipa++fz=h2M94gKX z@&*3VKm*E*MEPZXYgp<$)ELB?RD6{gm>JkRjkGj*z56G4>Q52UW64iS7+TGP;u9agxLc|Npmd-#&QoVD;+Nix)5c^y$-Lk+%)6#tp3e=bwtN~-tK1cun literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tree/elbow-end-minus.gif b/workflow/public_html/skins/ext/images/gray/tree/elbow-end-minus.gif new file mode 100755 index 0000000000000000000000000000000000000000..585051376cf71dfb82cf109d88c2857168dbd913 GIT binary patch literal 154 zcmZ?wbhEHb6krfy*v!Y^>gxLc|Npmd-#&QoVD;+NTefWZ^y$;$#fz6NU3&QN;a$6S z9XodH#EBDEu3TXN1I3>#j0_BX3_2hl$P5M+_X{UISI>R@s@C}bRfisqBAJt}EIQd7 z4Y%0zg`-z%^PGxRWNZkyQCy+Mek<>S#t)75>kTIh;`o}_oC9Cjsdp~4VAYy^egOxA FH2|ztLX`jj literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus-nl.gif b/workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus-nl.gif new file mode 100755 index 0000000000000000000000000000000000000000..752b42a3c74c39538bfca4c94afa9bb09de0befe GIT binary patch literal 151 zcmZ?wbhEHb6krfy*v!k|>gxLc|NqsiSHFGxcJboHTefVuc=6)hyLUf*`m}4;uBA(t z9zJ~d=+UDLFrfI8g^_`Qmq7<405XGt#bv`u&((V^UY~s}xL}dMks?mVSxU?Ws~EC( zh|OX;Jn_O*AqIyB@0>U`Ft9r}x+`wrV_;79l<^R5)hXV@QRO>#L&cm<1_o;YyTv@k literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus.gif b/workflow/public_html/skins/ext/images/gray/tree/elbow-end-plus.gif new file mode 100755 index 0000000000000000000000000000000000000000..ff126359d396ef5e5c9a9bcec2bdfba4dc084a52 GIT binary patch literal 156 zcmZ?wbhEHb6krfy*v!Y^>gxLc|NqsiSHFGxcFUG6ix)4xc=6)hyLUf*`gH8rv879w z?%K8M@ZrNpj~-#j0_BX3_2hl$P5M+&kH9#SI>R_+n`@+35kRg#?Ga*TYf<38@R-i3PC&`z~@ed-ye;dtsu% H#9$2o_3uG@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/window/icon-error.gif b/workflow/public_html/skins/ext/images/gray/window/icon-error.gif new file mode 100755 index 0000000000000000000000000000000000000000..397b655ab83e5362fdc7eb0d18cf361c6f86bd9d GIT binary patch literal 1669 zcmV;02738NNk%w1VITk?0QUd@0|NsJ0|X2J00{{R5ds1i7Z(~66B`>G9v&Vb001Kp z5h)oOFaQ8I0021w0Y3o&E-fxEFEBACCN(uSJUcx_0Rc|{08I)CQ~&^5003P90ZlnN zZ2HgaR#tRYR&iNbdS75? zU|?otXJ=+;Yin(FU|@V`YIb#ZeSCg?et>}h0EGYmiU0tO0055<5Rm`?kOl^o005Z) z0GmN+?~005%|1f>7~rUeD5005~41+4%8tpx?M0RglK2)Y6SybBAy92~17B(5YS zt0^g|FE6h$GP@!ovpPDDN=%4PP>)+%g=J@gYio~fZHaSpjd*yLX=#~kY?O0znsITT ze0->1U$sL+wn#|6N=l(?ZKHd8zjAWJ0s_Pf3(Ero%L)p|939OP64C(y(FzLN0RhLMcRH8%DjAoeXS{Ujv)EG+gtJ^wQ^{W?3v zNJh*-LCQ@{#8XqnUth>oR?f~+Utj)HQ~z6A@Lyo#VPouQYVB}x>v?Q{t%gd(L*0R{xyxG~vlatYag2Jb&>V$^kk(2*{ zf&Yw*|C5vdnwsaLq~@lni75b z|Ns8}{@~x^A^8LW00930EC2ui03ZM$000R70RIUbNDv$>R;N^%GKK1uH+KXhN+gI) zQmI(8v}vO?E0!usk6NLdNb;LSjN7_}3)gKMEm^BfQ9=}oWJFkzOv$3fZRN_A+GfF& z32BcxoBv$pj74i3x2G;S3XK)B)FeoEmXWL#snn`jv}gsDrLa^fQ>tQ`viiu;6mb&4 zIih50RjgR4R9RKTR}rL1lO$0B9ElMiAmt)9>blUBj4Y5687efWvLQo=T3ms|nUS42 zGT05w#%K~HN|L}(qt>OeA3m=K#Zlp_nV3Y10NJUdgV?}Dj3P~n6lR(~fAPA&<^wy< z3SY;ip*i$tjvF;7)cwO(hY@E;pU(dEJAMvK96x^EuyA(#I4D2W)wt>4TNE8YjvOf} zG)mrhfAgFX#~WKj)1E)1@X?1HY^b3I4=}g`${ckFf(Rmn_^}B+|J5T5Fy|aN${TUW z0S6mQFhRr!;UgPsq@e^7N-V$&6Kb%bq#Sa*Vdfi^>~mm0dsJzqm1!)YL=j6Upi2{A zuE7S7XQmMhKT=kc#-N0zk;D-~AfZ4mcqp-i8dkz#<`P*@Bc(t0{IW!$Ngy$V5I-1@ zizZxdisc(i!~o5u$IbJ_rv6JTkwg(c{D4CNyI4a65=m^j#u6#8*Ipi;`17AUTJ(BE z5kdIy0|yB7l8z8W9HFeL2U?Ou5|`ZbpQ}X_F@z60{NTU@$Nckz5JFhX#WM$9V(qqN zczc{Zzy$F_4?N^RzzK;Blf(}}6cGhE|5-BcwnvOnPkU1IumcV|U{F8}13B@74?zS0 z#dwzlam2`nic7|EPvkH$4mJotfiVMJGlaxG_)rEWKMWD>&Oe?)03;wIQ58SrAhy#rm+eCjRSRuH))@dW!7dZ& zW5o_u2R%03bq^haWeql1000EIv_ld+Sb#9`4TvW`^x8Ju-~j^zOmNFONd2>m2p`;_ zHs5>m&A|f!9AH8(f>-{JI5cc`2#jD0Go}*+k21NqFv0{8KoG$M PBfNl1GVhQS5C8x>^BLCH literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/window/icon-info.gif b/workflow/public_html/skins/ext/images/gray/window/icon-info.gif new file mode 100755 index 0000000000000000000000000000000000000000..58281c3067b309779f5cf949a7196170c8ca97b9 GIT binary patch literal 1586 zcmV-22F>|LNk%w1VITk?0QUd@002Ay07w84PX`%A3LHrS9ajJYWB>?a019mY3w!_= zeheW`4kS_$BTNt{R2C>w87x&AE?6EhTN5*F88u@cHent&Zy_^VB{*RwJ!T<2Ybrfu zEanAeNJ0@02_k<8;bxSjRY)#049Cl8e5Y1_tY3bkWN(XQaEfVlk7;?7 zZF!SzdY5*8mt2auc!8LDgq&lBt7(C!V~et7k-lw{yKsuMageiql(2i8y-tSTQHA4U zhskM;!F86%bDF?tGlSHx~QzWsjj`Ou)c+z$A_QDf}_NMrOt$@%8RPR zi>%9lsM?CJ)Qqyzkfy4!pytE%CW@Nu*TlB$=|re)xF5pzRlaC#O0*M=&Huzs>kT8$>*ZV^`Xr3 zq{{ZD&GV%F^A_)Y{V6-P_#W#@Xx7+U3jK?!?;j!ruDO*W%II z<s1(&F;b=Ka&^{@UjA-Rbn(?f%pA|J?Ea z-}(RG-{a%sWQF}}=T6!l(LfBVqwLzTzdz--gr zA>~JRUspdjz=SD#uW#3T=*1z15PotP*O<}1TXI=rW8fk~GqY79KP}1YrcVGlvzs zDl$nW+ZJ<7GW-rh3M7OOB8UkZSwRrC?KL;(Q+JJH=Ywg3PC literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/window/icon-question.gif b/workflow/public_html/skins/ext/images/gray/window/icon-question.gif new file mode 100755 index 0000000000000000000000000000000000000000..08abd82ae86c9457172c7a4fdbc527641cf28e48 GIT binary patch literal 1607 zcmV-N2Dtf0Nk%w1VITk?0QUd@02fyP7F_@vT>uhh032%o9CQF5e-A8e03mY#BzglW zcL_0l6g7B5MoUafO-xQwNKjc)QdCG)VMGais%VD1YKp&Yk+f=&xOI)E zaEiQim9}=7y?K_jd6&3+oV;3t&|-(kYnQ@tj>UPC!+4gSZh?S#&mcD?Rw3D8!n4hVIpuCNxypy7?lBc|sslAz{ zv!1E8nykH`pQ59qrl_Z?tE#T5tFf-Ly0EXZv$D0gx4OH!y?~j^f}_NSpv#4+%#5bO zjit(rsl|+~%!H%Tg{shuuF;CD-i))_m#xK;uF0IQ!Je+okgwa9u*sgY$DOs#l(p29 zwb+%o+nKY|oV(kBuJ?(u=#RDcm$&DYyyKX=;G(m`qqxkgwZo{l%AmW~pu5Wy1~n_!_~3H*|^2hyUEtQ&D)~F!=r_S`L&GoF&_N~(Sv&!PL&+@j??Yq$Bv(odm+WouL^Ss^uzv2JK z#>vRX%gf5m#L3db&e_e*)63J`)6&(_)!NwC+uGXR!PV)++V9BJ>B`#d#N777-1y4d z^3d1g(%a?H-|XGp;>6+p%jEve=>OE=@803%+~e!f;quVt`_t+E+2!%y==0m`{@(Hb z;NRop*MI`>g(&|>+<34{Oa!Wf0xe!3Pge_@yBbqQDAy z^yqLDY^(Y`Bgb#Yy&t*SHt<)MmubQE= zM_%4K|K!o54GAF7UTBq*Ob!?g0o7_ijR4L$#5Cl7WQu5*Y1Gi(Bmg6D)2&N<*T z_(l=0(9+Fy7{;fLf+vi?iGtvWSYtTY0MiN@9f&f^H7LmFMINyXBrZBDyqCps^d=g7F3EF65lHnZVrI>UYlglJe zU~oq>afkv8HsRE$YQu zh#-bkqRKD4cwz`3RWxA(1Qnd&3}YuvgUT2`;GhH*Q&3SwBCD*Dh!i~7&_D!W@DWW; z1F;hgDs>bA#0Ei30Z1pS2x5T)7=Y0SG)EyV5IfR9lMEkstO3X(t9(I08OcCnvDYWD z6Ol7qAd-p~6!7sjC){4MV~P`tbU^{7d>1~=99ZDpN7scTEv^xRGv0Vk((EBd#a;&l F06QAMRrde@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/window/icon-warning.gif b/workflow/public_html/skins/ext/images/gray/window/icon-warning.gif new file mode 100755 index 0000000000000000000000000000000000000000..27ff98b4f787f776e24227da0227bc781e3b11e8 GIT binary patch literal 1483 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 VL2+p=XLUfTJzf1=);T3K0RXZceS-i1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/images/gray/window/top-bottom.png b/workflow/public_html/skins/ext/images/gray/window/top-bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..2887f063e81658e8462a74f4a9d3eb421b5531df GIT binary patch literal 2860 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 KMNUMnLSTaXcuOPz literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/ext/pmos-xtheme-gray.css b/workflow/public_html/skins/ext/pmos-xtheme-gray.css new file mode 100644 index 000000000..9bbc01dfb --- /dev/null +++ b/workflow/public_html/skins/ext/pmos-xtheme-gray.css @@ -0,0 +1,215 @@ +/*#x-basicshapes li { + background-image:url('/skins/ext/images/gray/shapes/basic-shapes.png'); + background-repeat:no-repeat; + margin-left:25px; + } + +#x-shapes-text {background-position:1px 0px;height: 30px} +#x-shapes-task1 {background-position:1px -30px;height: 30px} +#x-shapes-loop {background-position:1px -63px;height: 30px} +#x-shapes-flow {background-position:1px -94px;height: 30px} +#x-shapes-group {background-position:1px -124px;height: 30px} +#x-shapes-loopsub {background-position:1px -153px;height: 30px} +#x-shapes-assoc {background-position:1px -184px;height: 30px} +#x-shapes-msgconn {background-position:1px -124px;height: 30px} +#x-shapes-lane {background-position:1px -239px;height: 30px} +#x-shapes-dataObject {background-position:1px -273px;height: 30px} + + +#x-event-shapes li { + background-image:url('/skins/ext/images/gray/shapes/events.png'); + background-repeat:no-repeat; + margin-left:11px; + } + +#x-shapes-event-empty {background-position:1px 0px;height: 35px} +#x-shapes-event-msgstart {background-position:1px -42px;height: 35px} +#x-shapes-event-rule {background-position:1px -80px;height: 35px} +#x-shapes-event-timerstart {background-position:1px -120px;height: 35px} +#x-shapes-event-sigstart {background-position:1px -161px;height: 35px} +#x-shapes-event-mulstart {background-position:1px -202px;height: 35px} +#x-shapes-event-linkstart {background-position:1px -242px;height: 35px} +#x-shapes-event-emptyinter {background-position:1px -283px;height: 35px} +#x-shapes-event-msgconn {background-position:1px -323px;height: 35px} +#x-shapes-event-timerinter {background-position:1px -364px;height: 35px} +#x-shapes-event-errorinter {background-position:1px -405px;height: 35px} +#x-shapes-event-compinter {background-position:1px -445px;height: 35px} +#x-shapes-event-ruleinter {background-position:1px -486px;height: 35px} +#x-shapes-event-caninter {background-position:1px -526px;height: 35px} +#x-shapes-event-intersig {background-position:1px -565px;height: 35px} +#x-shapes-event-mulinter {background-position:1px -607px;height: 35px} +#x-shapes-event-linkinter {background-position:1px -646px;height: 35px} +#x-shapes-event-emptyend {background-position:1px -688px;height: 35px} +#x-shapes-event-messageend {background-position:1px -726px;height: 35px} +#x-shapes-event-errorend {background-position:1px -766px;height: 35px} +#x-shapes-event-compend {background-position:1px -805px;height: 35px} +#x-shapes-event-terminate {background-position:1px -844px;height: 35px} +#x-shapes-event-endsignal {background-position:1px -884px;height: 35px} +#x-shapes-event-multipleend {background-position:1px -922px;height: 35px} +#x-shapes-event-cancelend {background-position:1px -963px;height: 35px} +#x-shapes-event-linkend {background-position:1px -1000px;height: 35px} + + +#x-gateways-shapes li { + background-image:url('/skins/ext/images/gray/shapes/gateways.png'); + background-repeat:no-repeat; + margin-left:9px; + } + +#x-shapes-gateways-exc-data {background-position:1px -1px; height: 55px;} +#x-shapes-gateways-exc-event {background-position:1px -60px; height: 55px} +#x-shapes-gateways-inc-data {background-position:1px -120px; height: 55px} +#x-shapes-gateways-parallel {background-position:1px -180px; height: 55px} +#x-shapes-gateways-complex {background-position:1px -240px; height: 55px} + +#x-shapes li { + background-image:url('/skins/ext/images/gray/shapes/shapes.png'); + background-repeat:no-repeat; + margin-left:9px; + } + +#x-shapes-task {background-position:5px -3px; height: 30px;} +#x-shapes-startEvent {background-position:5px -34px; height: 30px} +#x-shapes-interEvent {background-position:5px -64px; height: 30px} +#x-shapes-endEvent {background-position:5px -95px; height: 30px} +#x-shapes-gateways {background-position:5px -127px; height: 30px} +*/ +#x-shapes p { + type:none; + + margin-left:9px; + } + +#x-shapes-task { + width:36px; + height:26px; + /* background-image:url('/skins/ext/images/gray/shapes/pallete/task.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-startEvent { + width:38px; + height:38px; + /* background-image:url('/skins/ext/images/gray/shapes/pallete/startevent.png');*/ + margin:2 2 2 2; +} + +#x-shapes-interEvent { + width:38px; + height:38px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/interevent.png');*/ + margin:2 2 2 2; +} + +#x-shapes-endEvent { + width:38px; + height:38px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/endevent.png');*/ + margin:2 2 2 2; +} + +#x-shapes-gateway { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-dataobject { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:0 2 2 2; +} + +#x-shapes-group { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:4 2 2 2; +} + +#x-shapes-annotation { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:5 2 2 2; +} + +#x-shapes-pool { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-lane { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-milestone { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-sequence { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-association { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + +#x-shapes-message { + width:36px; + height:36px; + /*background-image:url('/skins/ext/images/gray/shapes/pallete/gateway.png') ;*/ + margin:2 2 2 2; +} + + + +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +/* + * FileUploadField component styles + */ +.x-form-file-wrap { + position: relative; + height: 22px; +} +.x-form-file-wrap .x-form-file { + position: absolute; + right: 0; + -moz-opacity: 0; + filter:alpha(opacity: 0); + opacity: 0; + z-index: 2; + height: 22px; +} +.x-form-file-wrap .x-form-file-btn { + position: absolute; + right: 0; + z-index: 1; +} +.x-form-file-wrap .x-form-file-text { + position: absolute; + left: 0; + z-index: 3; + color: #777; +} \ No newline at end of file diff --git a/workflow/public_html/skins/ext/xtheme-blue.css b/workflow/public_html/skins/ext/xtheme-blue.css new file mode 100755 index 000000000..9d5256403 --- /dev/null +++ b/workflow/public_html/skins/ext/xtheme-blue.css @@ -0,0 +1,1646 @@ +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +.ext-el-mask { + background-color: #ccc; +} + +.ext-el-mask-msg { + border-color:#6593cf; + background-color:#c3daf9; + background-image:url(../images/default/box/tb-blue.gif); +} +.ext-el-mask-msg div { + background-color: #eee; + border-color:#a3bad9; + color:#222; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-mask-loading div { + background-color:#fbfbfb; + background-image:url(../images/default/grid/loading.gif); +} + +.x-item-disabled { + color: gray; +} + +.x-item-disabled * { + color: gray !important; +} + +.x-splitbar-proxy { + background-color: #aaa; +} + +.x-color-palette a { + border-color:#fff; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border-color:#8bb8f3; + background-color: #deecfd; +} + +.x-color-palette em:hover, .x-color-palette span:hover{ + background-color: #deecfd; +} + +.x-color-palette em { + border-color:#aca899; +} + +.x-ie-shadow { + background-color:#777; +} + +.x-shadow .xsmc { + background-image: url(../images/default/shadow-c.png); +} + +.x-shadow .xsml, .x-shadow .xsmr { + background-image: url(../images/default/shadow-lr.png); +} + +.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{ + background-image: url(../images/default/shadow.png); +} + +.loading-indicator { + font-size: 11px; + background-image: url(../images/default/grid/loading.gif); +} + +.x-spotlight { + background-color: #ccc; +} +.x-tab-panel-header, .x-tab-panel-footer { + background-color: #deecfd; + border-color:#8db2e3; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border-color:#8db2e3; +} + +ul.x-tab-strip-top{ + background-color:#cedff5; + background-image: url(../images/default/tabs/tab-strip-bg.gif); + border-bottom-color:#8db2e3; +} + +ul.x-tab-strip-bottom{ + background-color:#cedff5; + background-image: url(../images/default/tabs/tab-strip-btm-bg.gif); + border-top-color:#8db2e3; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-color:#8db2e3; + background-color: #deecfd; +} + +.x-tab-strip span.x-tab-strip-text { + font:normal 11px tahoma,arial,helvetica; + color:#416aa3; +} + +.x-tab-strip-over span.x-tab-strip-text { + color:#15428b; +} + +.x-tab-strip-active span.x-tab-strip-text { + color:#15428b; + font-weight:bold; +} + +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} + +.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{ + background-image: url(../images/default/tabs/tabs-sprite.gif); +} + +.x-tab-strip-bottom .x-tab-right { + background-image: url(../images/default/tabs/tab-btm-inactive-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-left { + background-image: url(../images/default/tabs/tab-btm-inactive-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-right { + background-image: url(../images/default/tabs/tab-btm-over-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-left { + background-image: url(../images/default/tabs/tab-btm-over-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image: url(../images/default/tabs/tab-btm-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image: url(../images/default/tabs/tab-btm-left-bg.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(../images/default/tabs/tab-close.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(../images/default/tabs/tab-close.gif); +} + +.x-tab-panel-body { + border-color:#8db2e3; + background-color:#fff; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background-image:url(../images/default/tabs/scroll-left.gif); + border-bottom-color:#8db2e3; +} + +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background-image:url(../images/default/tabs/scroll-right.gif); + border-bottom-color:#8db2e3; +} + +.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar { + border-color:#99bbe8; +}.x-form-field { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-text, textarea.x-form-field { + background-color:#fff; + background-image:url(../images/default/form/text-bg.gif); + border-color:#b5b8c8; +} + +.x-form-select-one { + background-color:#fff; + border-color:#b5b8c8; +} + +.x-form-check-group-label { + border-bottom: 1px solid #99bbe8; + color: #15428b; +} + +.x-editor .x-form-check-wrap { + background-color:#fff; +} + +.x-form-field-wrap .x-form-trigger { + background-image:url(../images/default/form/trigger.gif); + border-bottom-color:#b5b8c8; +} + +.x-form-field-wrap .x-form-date-trigger { + background-image: url(../images/default/form/date-trigger.gif); +} + +.x-form-field-wrap .x-form-clear-trigger { + background-image: url(../images/default/form/clear-trigger.gif); +} + +.x-form-field-wrap .x-form-search-trigger { + background-image: url(../images/default/form/search-trigger.gif); +} + +.x-trigger-wrap-focus .x-form-trigger { + border-bottom-color:#7eadd9; +} + +.x-item-disabled .x-form-trigger-over { + border-bottom-color:#b5b8c8; +} + +.x-item-disabled .x-form-trigger-click { + border-bottom-color:#b5b8c8; +} + +.x-form-focus, textarea.x-form-focus { + border-color:#7eadd9; +} + +.x-form-invalid, textarea.x-form-invalid { + background-color:#fff; + background-image:url(../images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.x-form-invalid.x-form-composite { + border: none; + background-image: none; +} + +.x-form-invalid.x-form-composite .x-form-invalid { + background-color:#fff; + background-image:url(../images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid { + background-color:#fff; + background-image:url(../images/default/grid/invalid_line.gif); +} + +.x-form-grow-sizer { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-item { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-invalid-msg { + color:#c0272b; + font:normal 11px tahoma, arial, helvetica, sans-serif; + background-image:url(../images/default/shared/warning.gif); +} + +.x-form-empty-field { + color:gray; +} + +.x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-webkit .x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-form-invalid-icon { + background-image:url(../images/default/form/exclamation.gif); +} + +.x-fieldset { + border-color:#b5b8c8; +} + +.x-fieldset legend { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#15428b; +} +.x-btn{ + font:normal 11px tahoma, verdana, helvetica; +} + +.x-btn button{ + font:normal 11px arial,tahoma,verdana,helvetica; + color:#333; +} + +.x-btn em { + font-style:normal; + font-weight:normal; +} + +.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{ + background-image:url(../images/default/button/btn.gif); +} + +.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{ + color:#000; +} + +.x-btn-disabled *{ + color:gray !important; +} + +.x-btn-mc em.x-btn-arrow { + background-image:url(../images/default/button/arrow.gif); +} + +.x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow-o.gif); +} + +.x-btn-mc em.x-btn-arrow-bottom { + background-image:url(../images/default/button/s-arrow-b-noline.gif); +} + +.x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-b.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-bo.gif); +} + +.x-btn-group-header { + color: #3e6aaa; +} + +.x-btn-group-tc { + background-image: url(../images/default/button/group-tb.gif); +} + +.x-btn-group-tl { + background-image: url(../images/default/button/group-cs.gif); +} + +.x-btn-group-tr { + background-image: url(../images/default/button/group-cs.gif); +} + +.x-btn-group-bc { + background-image: url(../images/default/button/group-tb.gif); +} + +.x-btn-group-bl { + background-image: url(../images/default/button/group-cs.gif); +} + +.x-btn-group-br { + background-image: url(../images/default/button/group-cs.gif); +} + +.x-btn-group-ml { + background-image: url(../images/default/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(../images/default/button/group-lr.gif); +} + +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(../images/default/button/group-tb.gif); +}.x-toolbar{ + border-color:#a9bfd3; + background-color:#d0def0; + background-image:url(../images/default/toolbar/bg.gif); +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} + +.x-toolbar .x-item-disabled { + color:gray; +} + +.x-toolbar .x-item-disabled * { + color:gray; +} + +.x-toolbar .x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split +{ + background-image:url(../images/default/button/s-arrow-o.gif); +} + +.x-toolbar .x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-b-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom +{ + background-image:url(../images/default/button/s-arrow-bo.gif); +} + +.x-toolbar .xtb-sep { + background-image: url(../images/default/grid/grid-blue-split.gif); +} + +.x-tbar-page-first{ + background-image: url(../images/default/grid/page-first.gif) !important; +} + +.x-tbar-loading{ + background-image: url(../images/default/grid/refresh.gif) !important; +} + +.x-tbar-page-last{ + background-image: url(../images/default/grid/page-last.gif) !important; +} + +.x-tbar-page-next{ + background-image: url(../images/default/grid/page-next.gif) !important; +} + +.x-tbar-page-prev{ + background-image: url(../images/default/grid/page-prev.gif) !important; +} + +.x-item-disabled .x-tbar-loading{ + background-image: url(../images/default/grid/loading.gif) !important; +} + +.x-item-disabled .x-tbar-page-first{ + background-image: url(../images/default/grid/page-first-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-last{ + background-image: url(../images/default/grid/page-last-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-next{ + background-image: url(../images/default/grid/page-next-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-prev{ + background-image: url(../images/default/grid/page-prev-disabled.gif) !important; +} + +.x-paging-info { + color:#444; +} + +.x-toolbar-more-icon { + background-image: url(../images/default/toolbar/more.gif) !important; +}.x-resizable-handle { + background-color:#fff; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-image:url(../images/default/sizer/e-handle.gif); +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-image:url(../images/default/sizer/s-handle.gif); +} + +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{ + background-image:url(../images/default/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-image:url(../images/default/sizer/se-handle.gif); +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-image:url(../images/default/sizer/nw-handle.gif); +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-image:url(../images/default/sizer/ne-handle.gif); +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-image:url(../images/default/sizer/sw-handle.gif); +} +.x-resizable-proxy{ + border-color:#3b5a82; +} +.x-resizable-overlay{ + background-color:#fff; +} +.x-grid3 { + background-color:#fff; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border-color:#99bbe8; +} + +.x-grid3-row td, .x-grid3-summary-row td{ + font:normal 11px/13px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row td { + font:normal 11px/15px arial, tahoma, helvetica, sans-serif; +} + + +.x-grid3-hd-row td { + border-left-color:#eee; + border-right-color:#d0d0d0; +} + +.x-grid-row-loading { + background-color: #fff; + background-image:url(../images/default/shared/loading-balls.gif); +} + +.x-grid3-row { + border-color:#ededed; + border-top-color:#fff; +} + +.x-grid3-row-alt{ + background-color:#fafafa; +} + +.x-grid3-row-over { + border-color:#ddd; + background-color:#efefef; + background-image:url(../images/default/grid/row-over.gif); +} + +.x-grid3-resize-proxy { + background-color:#777; +} + +.x-grid3-resize-marker { + background-color:#777; +} + +.x-grid3-header{ + background-color:#f9f9f9; + background-image:url(../images/default/grid/grid3-hrow.gif); +} + +.x-grid3-header-pop { + border-left-color:#d0d0d0; +} + +.x-grid3-header-pop-inner { + border-left-color:#eee; + background-image:url(../images/default/grid/hd-pop.gif); +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left-color:#aaccf6; + border-right-color:#aaccf6; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background-color:#ebf3fd; + background-image:url(../images/default/grid/grid3-hrow-over.gif); + +} + +.sort-asc .x-grid3-sort-icon { + background-image: url(../images/default/grid/sort_asc.gif); +} + +.sort-desc .x-grid3-sort-icon { + background-image: url(../images/default/grid/sort_desc.gif); +} + +.x-grid3-cell-text, .x-grid3-hd-text { + color:#000; +} + +.x-grid3-split { + background-image: url(../images/default/grid/grid-split.gif); +} + +.x-grid3-hd-text { + color:#15428b; +} + +.x-dd-drag-proxy .x-grid3-hd-inner{ + background-color:#ebf3fd; + background-image:url(../images/default/grid/grid3-hrow-over.gif); + border-color:#aaccf6; +} + +.col-move-top{ + background-image:url(../images/default/grid/col-move-top.gif); +} + +.col-move-bottom{ + background-image:url(../images/default/grid/col-move-bottom.gif); +} + +.x-grid3-row-selected { + background-color: #dfe8f6 !important; + background-image: none; + border-color:#a3bae9; +} + +.x-grid3-cell-selected{ + background-color: #b8cfee !important; + color:#000; +} + +.x-grid3-cell-selected span{ + color:#000 !important; +} + +.x-grid3-cell-selected .x-grid3-cell-text{ + color:#000; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background-color:#ebeadb !important; + background-image:url(../images/default/grid/grid-hrow.gif) !important; + color:#000; + border-top-color:#fff; + border-right-color:#6fa0df !important; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + color:#15428b !important; +} + +.x-grid3-dirty-cell { + background-image:url(../images/default/grid/dirty.gif); +} + +.x-grid3-topbar, .x-grid3-bottombar{ + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-bottombar .x-toolbar{ + border-top-color:#a9bfd3; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background-image:url(../images/default/grid/grid3-special-col-bg.gif) !important; + color:#000 !important; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + background-color:#fff !important; + border-right-color:#eee; +} + +.xg-hmenu-sort-asc .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-asc.gif); +} + +.xg-hmenu-sort-desc .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-desc.gif); +} + +.xg-hmenu-lock .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-lock.gif); +} + +.xg-hmenu-unlock .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-unlock.gif); +} + +.x-grid3-hd-btn { + background-color:#c3daf9; + background-image:url(../images/default/grid/grid3-hd-btn.gif); +} + +.x-grid3-body .x-grid3-td-expander { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-expander { + background-image:url(../images/default/grid/row-expand-sprite.gif); +} + +.x-grid3-body .x-grid3-td-checker { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + background-image:url(../images/default/grid/row-check-sprite.gif); +} + +.x-grid3-body .x-grid3-td-numberer { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + color:#444; +} + +.x-grid3-body .x-grid3-td-row-icon { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background-image:url(../images/default/grid/grid3-special-col-sel-bg.gif); +} + +.x-grid3-check-col { + background-image:url(../images/default/menu/unchecked.gif); +} + +.x-grid3-check-col-on { + background-image:url(../images/default/menu/checked.gif); +} + +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom-color:#99bbe8; +} + +.x-grid-group-hd div.x-grid-group-title { + background-image:url(../images/default/grid/group-collapse.gif); + color:#3764a0; + font:bold 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title { + background-image:url(../images/default/grid/group-expand.gif); +} + +.x-group-by-icon { + background-image:url(../images/default/grid/group-by.gif); +} + +.x-cols-icon { + background-image:url(../images/default/grid/columns.gif); +} + +.x-show-groups-icon { + background-image:url(../images/default/grid/group-by.gif); +} + +.x-grid-empty { + color:gray; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + border-right-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row-selected { + border-top-color:#a3bae9; +}.x-dd-drag-ghost{ + color:#000; + font: normal 11px arial, helvetica, sans-serif; + border-color: #ddd #bbb #bbb #ddd; + background-color:#fff; +} + +.x-dd-drop-nodrop .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-no.gif); +} + +.x-dd-drop-ok .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-yes.gif); +} + +.x-dd-drop-ok-add .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-add.gif); +} + +.x-view-selector { + background-color:#c3daf9; + border-color:#3399bb; +}.x-tree-node-expanded .x-tree-node-icon{ + background-image:url(../images/default/tree/folder-open.gif); +} + +.x-tree-node-leaf .x-tree-node-icon{ + background-image:url(../images/default/tree/leaf.gif); +} + +.x-tree-node-collapsed .x-tree-node-icon{ + background-image:url(../images/default/tree/folder.gif); +} + +.x-tree-node-loading .x-tree-node-icon{ + background-image:url(../images/default/tree/loading.gif) !important; +} + +.x-tree-node .x-tree-node-inline-icon { + background-image: none; +} + +.x-tree-node-loading a span{ + font-style: italic; + color:#444444; +} + +.x-tree-lines .x-tree-elbow{ + background-image:url(../images/default/tree/elbow.gif); +} + +.x-tree-lines .x-tree-elbow-plus{ + background-image:url(../images/default/tree/elbow-plus.gif); +} + +.x-tree-lines .x-tree-elbow-minus{ + background-image:url(../images/default/tree/elbow-minus.gif); +} + +.x-tree-lines .x-tree-elbow-end{ + background-image:url(../images/default/tree/elbow-end.gif); +} + +.x-tree-lines .x-tree-elbow-end-plus{ + background-image:url(../images/default/tree/elbow-end-plus.gif); +} + +.x-tree-lines .x-tree-elbow-end-minus{ + background-image:url(../images/default/tree/elbow-end-minus.gif); +} + +.x-tree-lines .x-tree-elbow-line{ + background-image:url(../images/default/tree/elbow-line.gif); +} + +.x-tree-no-lines .x-tree-elbow-plus{ + background-image:url(../images/default/tree/elbow-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-minus{ + background-image:url(../images/default/tree/elbow-minus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-plus{ + background-image:url(../images/default/tree/elbow-end-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-minus{ + background-image:url(../images/default/tree/elbow-end-minus-nl.gif); +} + +.x-tree-arrows .x-tree-elbow-plus{ + background-image:url(../images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-minus{ + background-image:url(../images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background-image:url(../images/default/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background-image:url(../images/default/tree/arrows.gif); +} + +.x-tree-node{ + color:#000; + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + color:#000; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + color:#000; +} + +.x-tree-node .x-tree-node-disabled a span{ + color:gray !important; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom-color:#36c; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top-color:#36c; +} + +.x-tree-node .x-tree-drag-append a span{ + background-color:#ddd; + border-color:gray; +} + +.x-tree-node .x-tree-node-over { + background-color: #eee; +} + +.x-tree-node .x-tree-selected { + background-color: #d9e8fb; +} + +.x-tree-drop-ok-append .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-add.gif); +} + +.x-tree-drop-ok-above .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-over.gif); +} + +.x-tree-drop-ok-below .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-under.gif); +} + +.x-tree-drop-ok-between .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-between.gif); +}.x-date-picker { + border-color: #1b376c; + background-color:#fff; +} + +.x-date-middle,.x-date-left,.x-date-right { + background-image: url(../images/default/shared/hd-sprite.gif); + color:#fff; + font:bold 11px "sans serif", tahoma, verdana, helvetica; +} + +.x-date-middle .x-btn .x-btn-text { + color:#fff; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background-image:url(../images/default/toolbar/btn-arrow-light.gif); +} + +.x-date-right a { + background-image: url(../images/default/shared/right-btn.gif); +} + +.x-date-left a{ + background-image: url(../images/default/shared/left-btn.gif); +} + +.x-date-inner th { + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); + border-bottom-color:#a3bad9; + font:normal 10px arial, helvetica,tahoma,sans-serif; + color:#233d6d; +} + +.x-date-inner td { + border-color:#fff; +} + +.x-date-inner a { + font:normal 11px arial, helvetica,tahoma,sans-serif; + color:#000; +} + +.x-date-inner .x-date-active{ + color:#000; +} + +.x-date-inner .x-date-selected a{ + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} + +.x-date-inner .x-date-today a{ + border-color:darkred; +} + +.x-date-inner .x-date-selected span{ + font-weight:bold; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + color:#aaa; +} + +.x-date-bottom { + border-top-color:#a3bad9; + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + color:#000; + background-color:#ddecfe; +} + +.x-date-inner .x-date-disabled a { + background-color:#eee; + color:#bbb; +} + +.x-date-mmenu{ + background-color:#eee !important; +} + +.x-date-mmenu .x-menu-item { + font-size:10px; + color:#000; +} + +.x-date-mp { + background-color:#fff; +} + +.x-date-mp td { + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns button { + background-color:#083772; + color:#fff; + border-color: #3366cc #000055 #000055 #3366cc; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns { + background-color: #dfecfb; + background-image: url(../images/default/shared/glass-bg.gif); +} + +.x-date-mp-btns td { + border-top-color: #c5d2df; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + color:#15428b; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + color:#15428b; + background-color: #ddecfe; +} + +td.x-date-mp-sel a { + background-color: #dfecfb; + background-image: url(../images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} + +.x-date-mp-ybtn a { + background-image:url(../images/default/panel/tool-sprites.gif); +} + +td.x-date-mp-sep { + border-right-color:#c5d2df; +}.x-tip .x-tip-close{ + background-image: url(../images/default/qtip/close.gif); +} + +.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr { + background-image: url(../images/default/qtip/tip-sprite.gif); +} + +.x-tip .x-tip-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; +} +.x-tip .x-tip-ml { + background-color: #fff; +} + +.x-tip .x-tip-header-text { + font: bold 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-tip .x-tip-body { + font: normal 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc, +.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr +{ + background-image: url(../images/default/form/error-tip-corners.gif); +} + +.x-form-invalid-tip .x-tip-body { + background-image:url(../images/default/form/exclamation.gif); +} + +.x-tip-anchor { + background-image:url(../images/default/qtip/tip-anchor-sprite.gif); +}.x-menu { + background-color:#f0f0f0; + background-image:url(../images/default/menu/menu.gif); +} + +.x-menu-floating{ + border-color:#718bb7; +} + +.x-menu-nosep { + background-image:none; +} + +.x-menu-list-item{ + font:normal 11px arial,tahoma,sans-serif; +} + +.x-menu-item-arrow{ + background-image:url(../images/default/menu/menu-parent.gif); +} + +.x-menu-sep { + background-color:#e0e0e0; + border-bottom-color:#fff; +} + +a.x-menu-item { + color:#222; +} + +.x-menu-item-active { + background-image: url(../images/default/menu/item-over.gif); + background-color: #dbecf4; + border-color:#aaccf6; +} + +.x-menu-item-active a.x-menu-item { + border-color:#aaccf6; +} + +.x-menu-check-item .x-menu-item-icon{ + background-image:url(../images/default/menu/unchecked.gif); +} + +.x-menu-item-checked .x-menu-item-icon{ + background-image:url(../images/default/menu/checked.gif); +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background-image:url(../images/default/menu/group-checked.gif); +} + +.x-menu-group-item .x-menu-item-icon{ + background-image:none; +} + +.x-menu-plain { + background-color:#f0f0f0 !important; + background-image: none; +} + +.x-date-menu, .x-color-menu{ + background-color: #fff !important; +} + +.x-menu .x-date-picker{ + border-color:#a3bad9; +} + +.x-cycle-menu .x-menu-item-checked { + border-color:#a3bae9 !important; + background-color:#def8f6; +} + +.x-menu-scroller-top { + background-image:url(../images/default/layout/mini-top.gif); +} + +.x-menu-scroller-bottom { + background-image:url(../images/default/layout/mini-bottom.gif); +} +.x-box-tl { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-tc { + background-image: url(../images/default/box/tb.gif); +} + +.x-box-tr { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-ml { + background-image: url(../images/default/box/l.gif); +} + +.x-box-mc { + background-color: #eee; + background-image: url(../images/default/box/tb.gif); + font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif; + color: #393939; + font-size: 12px; +} + +.x-box-mc h3 { + font-size: 14px; + font-weight: bold; +} + +.x-box-mr { + background-image: url(../images/default/box/r.gif); +} + +.x-box-bl { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-bc { + background-image: url(../images/default/box/tb.gif); +} + +.x-box-br { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr { + background-image: url(../images/default/box/corners-blue.gif); +} + +.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc { + background-image: url(../images/default/box/tb-blue.gif); +} + +.x-box-blue .x-box-mc { + background-color: #c3daf9; +} + +.x-box-blue .x-box-mc h3 { + color: #17385b; +} + +.x-box-blue .x-box-ml { + background-image: url(../images/default/box/l-blue.gif); +} + +.x-box-blue .x-box-mr { + background-image: url(../images/default/box/r-blue.gif); +}.x-combo-list { + border-color:#98c0f4; + background-color:#ddecfe; + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-combo-list-inner { + background-color:#fff; +} + +.x-combo-list-hd { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#15428b; + background-image: url(../images/default/layout/panel-title-light-bg.gif); + border-bottom-color:#98c0f4; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom-color:#98c0f4; +} + +.x-combo-list-item { + border-color:#fff; +} + +.x-combo-list .x-combo-selected{ + border-color:#a3bae9 !important; + background-color:#dfe8f6; +} + +.x-combo-list .x-toolbar { + border-top-color:#98c0f4; +} + +.x-combo-list-small { + font:normal 11px tahoma, arial, helvetica, sans-serif; +}.x-panel { + border-color: #99bbe8; +} + +.x-panel-header { + color:#15428b; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; + border-color:#99bbe8; + background-image: url(../images/default/panel/white-top-bottom.gif); +} + +.x-panel-body { + border-color:#99bbe8; + background-color:#fff; +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border-color:#99bbe8; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top-color:#99bbe8; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top-color:#99bbe8; +} + +.x-panel-tl .x-panel-header { + color:#15428b; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-panel-tc { + background-image: url(../images/default/panel/top-bottom.gif); +} + +.x-panel-tl, .x-panel-tr, .x-panel-bl, .x-panel-br{ + background-image: url(../images/default/panel/corners-sprite.gif); + border-bottom-color:#99bbe8; +} + +.x-panel-bc { + background-image: url(../images/default/panel/top-bottom.gif); +} + +.x-panel-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} + +.x-panel-ml { + background-color: #fff; + background-image:url(../images/default/panel/left-right.gif); +} + +.x-panel-mr { + background-image: url(../images/default/panel/left-right.gif); +} + +.x-tool { + background-image:url(../images/default/panel/tool-sprites.gif); +} + +.x-panel-ghost { + background-color:#cbddf3; +} + +.x-panel-ghost ul { + border-color:#99bbe8; +} + +.x-panel-dd-spacer { + border-color:#99bbe8; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} +.x-window-proxy { + background-color:#c7dffc; + border-color:#99bbe8; +} + +.x-window-tl .x-window-header { + color:#15428b; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-window-tc { + background-image: url(../images/default/window/top-bottom.png); +} + +.x-window-tl { + background-image: url(../images/default/window/left-corners.png); +} + +.x-window-tr { + background-image: url(../images/default/window/right-corners.png); +} + +.x-window-bc { + background-image: url(../images/default/window/top-bottom.png); +} + +.x-window-bl { + background-image: url(../images/default/window/left-corners.png); +} + +.x-window-br { + background-image: url(../images/default/window/right-corners.png); +} + +.x-window-mc { + border-color:#99bbe8; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} + +.x-window-ml { + background-image: url(../images/default/window/left-right.png); +} + +.x-window-mr { + background-image: url(../images/default/window/left-right.png); +} + +.x-window-maximized .x-window-tc { + background-color:#fff; +} + +.x-window-bbar .x-toolbar { + border-top-color:#99bbe8; +} + +.x-panel-ghost .x-window-tl { + border-bottom-color:#99bbe8; +} + +.x-panel-collapsed .x-window-tl { + border-bottom-color:#84a0c4; +} + +.x-dlg-mask{ + background-color:#ccc; +} + +.x-window-plain .x-window-mc { + background-color: #ccd9e8; + border-color: #a3bae9 #dfe8f6 #dfe8f6 #a3bae9; +} + +.x-window-plain .x-window-body { + border-color: #dfe8f6 #a3bae9 #a3bae9 #dfe8f6; +} + +body.x-body-masked .x-window-plain .x-window-mc { + background-color: #ccd9e8; +}.x-html-editor-wrap { + border-color:#a9bfd3; + background-color:#fff; +} +.x-html-editor-tb .x-btn-text { + background-image:url(../images/default/editor/tb-sprite.gif); +}.x-panel-noborder .x-panel-header-noborder { + border-bottom-color:#99bbe8; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +}.x-border-layout-ct { + background-color:#dfe8f6; +} + +.x-accordion-hd { + color:#222; + font-weight:normal; + background-image: url(../images/default/panel/light-hd.gif); +} + +.x-layout-collapsed{ + background-color:#d2e0f2; + border-color:#98c0f4; +} + +.x-layout-collapsed-over{ + background-color:#d9e8fb; +} + +.x-layout-split-west .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} +.x-layout-split-east .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} +.x-layout-split-north .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-layout-split-south .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-west .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} + +.x-layout-cmini-east .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} + +.x-layout-cmini-north .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-south .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +}.x-progress-wrap { + border-color:#6593cf; +} + +.x-progress-inner { + background-color:#e0e8f3; + background-image:url(../images/default/qtip/bg.gif); +} + +.x-progress-bar { + background-color:#9cbfee; + background-image:url(../images/default/progress/progress-bg.gif); + border-top-color:#d1e4fd; + border-bottom-color:#7fa9e4; + border-right-color:#7fa9e4; +} + +.x-progress-text { + font-size:11px; + font-weight:bold; + color:#fff; +} + +.x-progress-text-back { + color:#396095; +}.x-list-header{ + background-color:#f9f9f9; + background-image:url(../images/default/grid/grid3-hrow.gif); +} + +.x-list-header-inner div em { + border-left-color:#ddd; + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-body dt em { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-over { + background-color:#eee; +} + +.x-list-selected { + background-color:#dfe8f6; +} + +.x-list-resizer { + border-left-color:#555; + border-right-color:#555; +} + +.x-list-header-inner em.sort-asc, .x-list-header-inner em.sort-desc { + background-image:url(../images/default/grid/sort-hd.gif); + border-color: #99bbe8; +}.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner { + background-image:url(../images/default/slider/slider-bg.png); +} + +.x-slider-horz .x-slider-thumb { + background-image:url(../images/default/slider/slider-thumb.png); +} + +.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner { + background-image:url(../images/default/slider/slider-v-bg.png); +} + +.x-slider-vert .x-slider-thumb { + background-image:url(../images/default/slider/slider-v-thumb.png); +}.x-window-dlg .ext-mb-text, +.x-window-dlg .x-window-header-text { + font-size:12px; +} + +.x-window-dlg .ext-mb-textarea { + font:normal 12px tahoma,arial,helvetica,sans-serif; +} + +.x-window-dlg .x-msg-box-wait { + background-image:url(../images/default/grid/loading.gif); +} + +.x-window-dlg .ext-mb-info { + background-image:url(../images/default/window/icon-info.gif); +} + +.x-window-dlg .ext-mb-warning { + background-image:url(../images/default/window/icon-warning.gif); +} + +.x-window-dlg .ext-mb-question { + background-image:url(../images/default/window/icon-question.gif); +} + +.x-window-dlg .ext-mb-error { + background-image:url(../images/default/window/icon-error.gif); +} \ No newline at end of file diff --git a/workflow/public_html/skins/ext/xtheme-gray.css b/workflow/public_html/skins/ext/xtheme-gray.css new file mode 100755 index 000000000..b5c13f7f1 --- /dev/null +++ b/workflow/public_html/skins/ext/xtheme-gray.css @@ -0,0 +1,1654 @@ +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +.ext-el-mask { + background-color: #ccc; +} + +.ext-el-mask-msg { + border-color:#999; + background-color:#ddd; + background-image:url(/skins/ext/images/gray/panel/white-top-bottom.gif); + background-position: 0 -1px; +} +.ext-el-mask-msg div { + background-color: #eee; + border-color:#d0d0d0; + color:#222; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-mask-loading div { + background-color:#fbfbfb; + background-image:url(/skins/ext/images/default/grid/loading.gif); +} + +.x-item-disabled { + color: gray; +} + +.x-item-disabled * { + color: gray !important; +} + +.x-splitbar-proxy { + background-color: #aaa; +} + +.x-color-palette a { + border-color:#fff; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border-color:#CFCFCF; + background-color: #eaeaea; +} + +.x-color-palette em:hover, .x-color-palette span:hover{ + background-color: #eaeaea; +} + +.x-color-palette em { + border-color:#aca899; +} + +.x-ie-shadow { + background-color:#777; +} + +.x-shadow .xsmc { + background-image: url(/skins/ext/images/default/shadow-c.png); +} + +.x-shadow .xsml, .x-shadow .xsmr { + background-image: url(/skins/ext/images/default/shadow-lr.png); +} + +.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{ + background-image: url(/skins/ext/images/default/shadow.png); +} + +.loading-indicator { + font-size: 11px; + background-image: url(/skins/ext/images/default/grid/loading.gif); +} + +.x-spotlight { + background-color: #ccc; +}.x-tab-panel-header, .x-tab-panel-footer { + background-color: #eaeaea; + border-color:#d0d0d0; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border-color:#d0d0d0; +} + +ul.x-tab-strip-top{ + background-color:#dbdbdb; + background-image: url(/skins/ext/images/gray/tabs/tab-strip-bg.gif); + border-bottom-color:#d0d0d0; +} + +ul.x-tab-strip-bottom{ + background-color:#dbdbdb; + background-image: url(/skins/ext/images/gray/tabs/tab-strip-btm-bg.gif); + border-top-color:#d0d0d0; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-color:#d0d0d0; + background-color: #eaeaea; +} + +.x-tab-strip span.x-tab-strip-text { + font:normal 11px tahoma,arial,helvetica; + color:#333; +} + +.x-tab-strip-over span.x-tab-strip-text { + color:#111; +} + +.x-tab-strip-active span.x-tab-strip-text { + color:#333; + font-weight:bold; +} + +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} + +.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{ + background-image: url(/skins/ext/images/gray/tabs/tabs-sprite.gif); +} + +.x-tab-strip-bottom .x-tab-right { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-inactive-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-left { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-inactive-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-left { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-over-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-right { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-over-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image: url(/skins/ext/images/gray/tabs/tab-btm-left-bg.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(/skins/ext/images/gray/tabs/tab-close.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(/skins/ext/images/gray/tabs/tab-close.gif); +} + +.x-tab-panel-body { + border-color:#d0d0d0; + background-color:#fff; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background-image:url(/skins/ext/images/gray/tabs/scroll-left.gif); + border-bottom-color:#d0d0d0; +} + +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background-image:url(/skins/ext/images/gray/tabs/scroll-right.gif); + border-bottom-color:#d0d0d0; +} + +.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} +.x-form-field{ + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-text, textarea.x-form-field{ + background-color:#fff; + background-image:url(/skins/ext/images/default/form/text-bg.gif); + border-color:#C1C1C1; +} + +.x-form-select-one { + background-color:#fff; + border-color:#C1C1C1; +} + +.x-form-check-group-label { + border-bottom: 1px solid #d0d0d0; + color: #333; +} + +.x-editor .x-form-check-wrap { + background-color:#fff; +} + +.x-form-field-wrap .x-form-trigger{ + background-image:url(/skins/ext/images/gray/form/trigger.gif); + border-bottom-color:#b5b8c8; +} + +.x-form-field-wrap .x-form-date-trigger{ + background-image: url(/skins/ext/images/gray/form/date-trigger.gif); +} + +.x-form-field-wrap .x-form-clear-trigger{ + background-image: url(/skins/ext/images/gray/form/clear-trigger.gif); +} + +.x-form-field-wrap .x-form-search-trigger{ + background-image: url(/skins/ext/images/gray/form/search-trigger.gif); +} + +.x-trigger-wrap-focus .x-form-trigger{ + border-bottom-color: #777777; +} + +.x-item-disabled .x-form-trigger-over{ + border-bottom-color:#b5b8c8; +} + +.x-item-disabled .x-form-trigger-click{ + border-bottom-color:#b5b8c8; +} + +.x-form-focus, textarea.x-form-focus{ + border-color:#777777; +} + +.x-form-invalid, textarea.x-form-invalid{ + background-color:#fff; + background-image:url(/skins/ext/images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.ext-webkit .x-form-invalid{ + background-color:#fee; + border-color:#ff7870; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid{ + background-color:#fff; + background-image:url(/skins/ext/images/default/grid/invalid_line.gif); +} + +.x-form-grow-sizer { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-item { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-invalid-msg { + color:#c0272b; + font:normal 11px tahoma, arial, helvetica, sans-serif; + background-image:url(/skins/ext/images/default/shared/warning.gif); +} + +.x-form-empty-field { + color:gray; +} + +.x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-webkit .x-small-editor .x-form-field { + font:normal 12px arial, tahoma, helvetica, sans-serif; +} + +.x-form-invalid-icon { + background-image:url(/skins/ext/images/default/form/exclamation.gif); +} + +.x-fieldset { + border-color:#CCCCCC; +} + +.x-fieldset legend { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#777777; +}.x-btn{ + font:normal 11px tahoma, verdana, helvetica; +} + +.x-btn button{ + font:normal 11px arial,tahoma,verdana,helvetica; + color:#333; +} + +.x-btn em { + font-style:normal; + font-weight:normal; +} + +.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{ + background-image:url(/skins/ext/images/gray/button/btn.gif); +} + +.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{ + color:#000; +} + +.x-btn-disabled *{ + color:gray !important; +} + +.x-btn-mc em.x-btn-arrow { + background-image:url(/skins/ext/images/default/button/arrow.gif); +} + +.x-btn-mc em.x-btn-split { + background-image:url(/skins/ext/images/default/button/s-arrow.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split { + background-image:url(/skins/ext/images/gray/button/s-arrow-o.gif); +} + +.x-btn-mc em.x-btn-arrow-bottom { + background-image:url(/skins/ext/images/default/button/s-arrow-b-noline.gif); +} + +.x-btn-mc em.x-btn-split-bottom { + background-image:url(/skins/ext/images/default/button/s-arrow-b.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom { + background-image:url(/skins/ext/images/gray/button/s-arrow-bo.gif); +} + +.x-btn-group-header { + color: #666; +} + +.x-btn-group-tc { + background-image: url(/skins/ext/images/gray/button/group-tb.gif); +} + +.x-btn-group-tl { + background-image: url(/skins/ext/images/gray/button/group-cs.gif); +} + +.x-btn-group-tr { + background-image: url(/skins/ext/images/gray/button/group-cs.gif); +} + +.x-btn-group-bc { + background-image: url(/skins/ext/images/gray/button/group-tb.gif); +} + +.x-btn-group-bl { + background-image: url(/skins/ext/images/gray/button/group-cs.gif); +} + +.x-btn-group-br { + background-image: url(/skins/ext/images/gray/button/group-cs.gif); +} + +.x-btn-group-ml { + background-image: url(/skins/ext/images/gray/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(/skins/ext/images/gray/button/group-lr.gif); +} + +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(/skins/ext/images/gray/button/group-tb.gif); +} +.x-toolbar{ + border-color:#d0d0d0; + background-color:#f0f0f0; + background-image:url(/skins/ext/images/gray/toolbar/bg.gif); +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} + +.x-toolbar .x-item-disabled { + color:gray; +} + +.x-toolbar .x-item-disabled * { + color:gray; +} + +.x-toolbar .x-btn-mc em.x-btn-split { + background-image:url(/skins/ext/images/default/button/s-arrow-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split +{ + background-image:url(/skins/ext/images/gray/button/s-arrow-o.gif); +} + +.x-toolbar .x-btn-mc em.x-btn-split-bottom { + background-image:url(/skins/ext/images/default/button/s-arrow-b-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom +{ + background-image:url(/skins/ext/images/gray/button/s-arrow-bo.gif); +} + +.x-toolbar .xtb-sep { + background-image: url(/skins/ext/images/default/grid/grid-split.gif); +} + +.x-tbar-page-first{ + background-image: url(/skins/ext/images/gray/grid/page-first.gif) !important; +} + +.x-tbar-loading{ + background-image: url(/skins/ext/images/gray/grid/refresh.gif) !important; +} + +.x-tbar-page-last{ + background-image: url(/skins/ext/images/gray/grid/page-last.gif) !important; +} + +.x-tbar-page-next{ + background-image: url(/skins/ext/images/gray/grid/page-next.gif) !important; +} + +.x-tbar-page-prev{ + background-image: url(/skins/ext/images/gray/grid/page-prev.gif) !important; +} + +.x-item-disabled .x-tbar-loading{ + background-image: url(/skins/ext/images/default/grid/loading.gif) !important; +} + +.x-item-disabled .x-tbar-page-first{ + background-image: url(/skins/ext/images/default/grid/page-first-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-last{ + background-image: url(/skins/ext/images/default/grid/page-last-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-next{ + background-image: url(/skins/ext/images/default/grid/page-next-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-prev{ + background-image: url(/skins/ext/images/default/grid/page-prev-disabled.gif) !important; +} + +.x-paging-info { + color:#444; +} + +.x-toolbar-more-icon { + background-image: url(/skins/ext/images/gray/toolbar/more.gif) !important; +} +.x-resizable-handle { + background-color:#fff; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-image:url(/skins/ext/images/gray/sizer/e-handle.gif); +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-image:url(/skins/ext/images/gray/sizer/s-handle.gif); +} + +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{ + background-image:url(/skins/ext/images/gray/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-image:url(/skins/ext/images/gray/sizer/se-handle.gif); +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-image:url(/skins/ext/images/gray/sizer/nw-handle.gif); +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-image:url(/skins/ext/images/gray/sizer/ne-handle.gif); +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-image:url(/skins/ext/images/gray/sizer/sw-handle.gif); +} +.x-resizable-proxy{ + border-color:#565656; +} +.x-resizable-overlay{ + background-color:#fff; +} +.x-grid3 { + background-color:#fff; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border-color:#d0d0d0; +} + +.x-grid3-hd-row td, .x-grid3-row td, .x-grid3-summary-row td{ + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row td { + border-left-color:#eee; + border-right-color:#d0d0d0; +} + +.x-grid-row-loading { + background-color: #fff; + background-image:url(/skins/ext/images/default/shared/loading-balls.gif); +} + +.x-grid3-row { + border-color:#ededed; + border-top-color:#fff; +} + +.x-grid3-row-alt{ + background-color:#fafafa; +} + +.x-grid3-row-over { + border-color:#ddd; + background-color:#efefef; + background-image:url(/skins/ext/images/default/grid/row-over.gif); +} + +.x-grid3-resize-proxy { + background-color:#777; +} + +.x-grid3-resize-marker { + background-color:#777; +} + +.x-grid3-header{ + background-color:#f9f9f9; + background-image:url(/skins/ext/images/gray/grid/grid3-hrow2.gif); +} + +.x-grid3-header-pop { + border-left-color:#d0d0d0; +} + +.x-grid3-header-pop-inner { + border-left-color:#eee; + background-image:url(/skins/ext/images/default/grid/hd-pop.gif); +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left-color:#ACACAC; + border-right-color:#ACACAC; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background-color:#f9f9f9; + background-image:url(/skins/ext/images/gray/grid/grid3-hrow-over2.gif); + +} + +.sort-asc .x-grid3-sort-icon { + background-image: url(/skins/ext/images/gray/grid/sort_asc.gif); +} + +.sort-desc .x-grid3-sort-icon { + background-image: url(/skins/ext/images/gray/grid/sort_desc.gif); +} + +.x-grid3-cell-text, .x-grid3-hd-text { + color:#000; +} + +.x-grid3-split { + background-image: url(/skins/ext/images/default/grid/grid-split.gif); +} + +.x-grid3-hd-text { + color:#333; +} + +.x-dd-drag-proxy .x-grid3-hd-inner{ + background-color:#f9f9f9; + background-image:url(/skins/ext/images/gray/grid/grid3-hrow-over2.gif); + border-color:#ACACAC; +} + +.col-move-top{ + background-image:url(/skins/ext/images/gray/grid/col-move-top.gif); +} + +.col-move-bottom{ + background-image:url(/skins/ext/images/gray/grid/col-move-bottom.gif); +} + +.x-grid3-row-selected { + background-color:#CCCCCC !important; + background-image: none; + border-color:#ACACAC; +} + +.x-grid3-cell-selected{ + background-color: #CBCBCB !important; + color:#000; +} + +.x-grid3-cell-selected span{ + color:#000 !important; +} + +.x-grid3-cell-selected .x-grid3-cell-text{ + color:#000; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background-color:#ebeadb !important; + background-image:url(/skins/ext/images/default/grid/grid-hrow.gif) !important; + color:#000; + border-top-color:#fff; + border-right-color:#6fa0df !important; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + color:#333 !important; +} + +.x-grid3-dirty-cell { + background-image:url(/skins/ext/images/default/grid/dirty.gif); +} + +.x-grid3-topbar, .x-grid3-bottombar{ + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-bottombar .x-toolbar{ + border-top-color:#a9bfd3; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background-image:url(/skins/ext/images/default/grid/grid3-special-col-bg.gif) !important; + color:#000 !important; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + background-color:#fff !important; + border-right-color:#eee; +} + +.xg-hmenu-sort-asc .x-menu-item-icon{ + background-image: url(/skins/ext/images/default/grid/hmenu-asc.gif); +} + +.xg-hmenu-sort-desc .x-menu-item-icon{ + background-image: url(/skins/ext/images/default/grid/hmenu-desc.gif); +} + +.xg-hmenu-lock .x-menu-item-icon{ + background-image: url(/skins/ext/images/default/grid/hmenu-lock.gif); +} + +.xg-hmenu-unlock .x-menu-item-icon{ + background-image: url(/skins/ext/images/default/grid/hmenu-unlock.gif); +} + +.x-grid3-hd-btn { + background-color:#f9f9f9; + background-image:url(/skins/ext/images/gray/grid/grid3-hd-btn.gif); +} + +.x-grid3-body .x-grid3-td-expander { + background-image:url(/skins/ext/images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-expander { + background-image:url(/skins/ext/images/gray/grid/row-expand-sprite.gif); +} + +.x-grid3-body .x-grid3-td-checker { + background-image: url(/skins/ext/images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + background-image:url(/skins/ext/images/default/grid/row-check-sprite.gif); +} + +.x-grid3-body .x-grid3-td-numberer { + background-image:url(/skins/ext/images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + color:#444; +} + +.x-grid3-body .x-grid3-td-row-icon { + background-image:url(/skins/ext/images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background-image:url(/skins/ext/images/gray/grid/grid3-special-col-sel-bg.gif); +} + +.x-grid3-check-col { + background-image:url(/skins/ext/images/default/menu/unchecked.gif); +} + +.x-grid3-check-col-on { + background-image:url(/skins/ext/images/default/menu/checked.gif); +} + +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom-color:#d0d0d0; +} + +.x-grid-group-hd div.x-grid-group-title { + background-image:url(/skins/ext/images/gray/grid/group-collapse.gif); + color:#5F5F5F; + font:bold 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title { + background-image:url(/skins/ext/images/gray/grid/group-expand.gif); +} + +.x-group-by-icon { + background-image:url(/skins/ext/images/default/grid/group-by.gif); +} + +.x-cols-icon { + background-image:url(/skins/ext/images/default/grid/columns.gif); +} + +.x-show-groups-icon { + background-image:url(/skins/ext/images/default/grid/group-by.gif); +} + +.x-grid-empty { + color:gray; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + border-right-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row{ + border-top-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row-selected { + border-top-color:#B9B9B9; +} +.x-dd-drag-ghost{ + color:#000; + font: normal 11px arial, helvetica, sans-serif; + border-color: #ddd #bbb #bbb #ddd; + background-color:#fff; +} + +.x-dd-drop-nodrop .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/dd/drop-no.gif); +} + +.x-dd-drop-ok .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/dd/drop-yes.gif); +} + +.x-dd-drop-ok-add .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/dd/drop-add.gif); +} + +.x-view-selector { + background-color:#D6D6D6; + border-color:#888888; +}.x-tree-node-expanded .x-tree-node-icon{ + background-image:url(/skins/ext/images/default/tree/folder-open.gif); +} + +.x-tree-node-leaf .x-tree-node-icon{ + background-image:url(/skins/ext/images/default/tree/leaf.gif); +} + +.x-tree-node-collapsed .x-tree-node-icon{ + background-image:url(/skins/ext/images/default/tree/folder.gif); +} + +.x-tree-node-loading .x-tree-node-icon{ + background-image:url(/skins/ext/images/default/tree/loading.gif) !important; +} + +.x-tree-node .x-tree-node-inline-icon { + background-image: none; +} + +.x-tree-node-loading a span{ + font-style: italic; + color:#444444; +} + +.ext-ie .x-tree-node-el input { + width:15px; + height:15px; +} + +.x-tree-lines .x-tree-elbow{ + background-image:url(/skins/ext/images/default/tree/elbow.gif); +} + +.x-tree-lines .x-tree-elbow-plus{ + background-image:url(/skins/ext/images/default/tree/elbow-plus.gif); +} + +.x-tree-lines .x-tree-elbow-minus{ + background-image:url(/skins/ext/images/default/tree/elbow-minus.gif); +} + +.x-tree-lines .x-tree-elbow-end{ + background-image:url(/skins/ext/images/default/tree/elbow-end.gif); +} + +.x-tree-lines .x-tree-elbow-end-plus{ + background-image:url(/skins/ext/images/gray/tree/elbow-end-plus.gif); +} + +.x-tree-lines .x-tree-elbow-end-minus{ + background-image:url(/skins/ext/images/gray/tree/elbow-end-minus.gif); +} + +.x-tree-lines .x-tree-elbow-line{ + background-image:url(/skins/ext/images/default/tree/elbow-line.gif); +} + +.x-tree-no-lines .x-tree-elbow-plus{ + background-image:url(/skins/ext/images/default/tree/elbow-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-minus{ + background-image:url(/skins/ext/images/default/tree/elbow-minus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-plus{ + background-image:url(/skins/ext/images/gray/tree/elbow-end-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-minus{ + background-image:url(/skins/ext/images/gray/tree/elbow-end-minus-nl.gif); +} + +.x-tree-arrows .x-tree-elbow-plus{ + background-image:url(/skins/ext/images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-minus{ + background-image:url(/skins/ext/images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background-image:url(/skins/ext/images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background-image:url(/skins/ext/images/gray/tree/arrows.gif); +} + +.x-tree-node{ + color:#000; + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + color:#000; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + color:#000; +} + +.x-tree-node .x-tree-node-disabled a span{ + color:gray !important; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom-color:#36c; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top-color:#36c; +} + +.x-tree-node .x-tree-drag-append a span{ + background-color:#ddd; + border-color:gray; +} + +.x-tree-node .x-tree-node-over { + background-color: #eee; +} + +.x-tree-node .x-tree-selected { + background-color: #ddd; +} + +.x-tree-drop-ok-append .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/tree/drop-add.gif); +} + +.x-tree-drop-ok-above .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/tree/drop-over.gif); +} + +.x-tree-drop-ok-below .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/tree/drop-under.gif); +} + +.x-tree-drop-ok-between .x-dd-drop-icon{ + background-image: url(/skins/ext/images/default/tree/drop-between.gif); +} +.x-date-picker { + border-color:#585858; + background-color:#fff; +} + +.x-date-middle,.x-date-left,.x-date-right { + background-image: url(/skins/ext/images/gray/shared/hd-sprite.gif); + color:#fff; + font:bold 11px "sans serif", tahoma, verdana, helvetica; +} + +.x-date-middle .x-btn .x-btn-text { + color:#fff; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background-image:url(/skins/ext/images/gray/toolbar/btn-arrow-light.gif); +} + +.x-date-right a { + background-image: url(/skins/ext/images/gray/shared/right-btn.gif); +} + +.x-date-left a{ + background-image: url(/skins/ext/images/gray/shared/left-btn.gif); +} + +.x-date-inner th { + background-color:#D8D8D8; + background-image: url(/skins/ext/images/gray/panel/white-top-bottom.gif); + border-bottom-color:#AFAFAF; + font:normal 10px arial, helvetica,tahoma,sans-serif; + color:#595959; +} + +.x-date-inner td { + border-color:#fff; +} + +.x-date-inner a { + font:normal 11px arial, helvetica,tahoma,sans-serif; + color:#000; +} + +.x-date-inner .x-date-active{ + color:#000; +} + +.x-date-inner .x-date-selected a{ + background-image: none; + background-color:#D8D8D8; + border-color:#DCDCDC; +} + +.x-date-inner .x-date-today a{ + border-color:darkred; +} + +.x-date-inner .x-date-selected span{ + font-weight:bold; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + color:#aaa; +} + +.x-date-bottom { + border-top-color:#AFAFAF; + background-color:#D8D8D8; + background:#D8D8D8 url(/skins/ext/images/gray/panel/white-top-bottom.gif) 0 -2px; +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + color:#000; + background-color:#D8D8D8; +} + +.x-date-inner .x-date-disabled a { + background-color:#eee; + color:#bbb; +} + +.x-date-mmenu{ + background-color:#eee !important; +} + +.x-date-mmenu .x-menu-item { + font-size:10px; + color:#000; +} + +.x-date-mp { + background-color:#fff; +} + +.x-date-mp td { + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns button { + background-color:#4E565F; + color:#fff; + border-color:#C0C0C0 #434343 #434343 #C0C0C0; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns { + background-color:#D8D8D8; + background:#D8D8D8 url(/skins/ext/images/gray/panel/white-top-bottom.gif) 0 -2px; +} + +.x-date-mp-btns td { + border-top-color:#AFAFAF; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + color: #333; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + color:#333; + background-color:#FDFDFD; +} + +td.x-date-mp-sel a { + background-color:#D8D8D8; + background:#D8D8D8 url(/skins/ext/images/gray/panel/white-top-bottom.gif) 0 -2px; + border-color:#DCDCDC; +} + +.x-date-mp-ybtn a { + background-image:url(/skins/ext/images/gray/panel/tool-sprites.gif); +} + +td.x-date-mp-sep { + border-right-color:#D7D7D7; +}.x-tip .x-tip-close{ + background-image: url(/skins/ext/images/gray/qtip/close.gif); +} + +.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr { + background-image: url(/skins/ext/images/gray/qtip/tip-sprite.gif); +} + +.x-tip .x-tip-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; +} +.x-tip .x-tip-ml { + background-color: #fff; +} + +.x-tip .x-tip-header-text { + font: bold 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-tip .x-tip-body { + font: normal 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc, +.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr +{ + background-image: url(/skins/ext/images/default/form/error-tip-corners.gif); +} + +.x-form-invalid-tip .x-tip-body { + background-image:url(/skins/ext/images/default/form/exclamation.gif); +} + +.x-tip-anchor { + background-image:url(/skins/ext/images/gray/qtip/tip-anchor-sprite.gif); +}.x-menu { + background-color:#f0f0f0; + background-image:url(/skins/ext/images/default/menu/menu.gif); +} + +.x-menu-floating{ + border-color:#7D7D7D; +} + +.x-menu-nosep { + background-image:none; +} + +.x-menu-list-item{ + font:normal 11px arial,tahoma,sans-serif; +} + +.x-menu-item-arrow{ + background-image:url(/skins/ext/images/gray/menu/menu-parent.gif); +} + +.x-menu-sep { + background-color:#e0e0e0; + border-bottom-color:#fff; +} + +a.x-menu-item { + color:#222; +} + +.x-menu-item-active { + background-image: url(/skins/ext/images/gray/menu/item-over.gif); + background-color: #f1f1f1; + border-color:#ACACAC; +} + +.x-menu-item-active a.x-menu-item { + border-color:#ACACAC; +} + +.x-menu-check-item .x-menu-item-icon{ + background-image:url(/skins/ext/images/default/menu/unchecked.gif); +} + +.x-menu-item-checked .x-menu-item-icon{ + background-image:url(/skins/ext/images/default/menu/checked.gif); +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background-image:url(/skins/ext/images/gray/menu/group-checked.gif); +} + +.x-menu-group-item .x-menu-item-icon{ + background-image:none; +} + +.x-menu-plain { + background-color:#fff !important; +} + +.x-menu .x-date-picker{ + border-color:#AFAFAF; +} + +.x-cycle-menu .x-menu-item-checked { + border-color:#B9B9B9 !important; + background-color:#F1F1F1; +} + +.x-menu-scroller-top { + background-image:url(/skins/ext/images/default/layout/mini-top.gif); +} + +.x-menu-scroller-bottom { + background-image:url(/skins/ext/images/default/layout/mini-bottom.gif); +}.x-box-tl { + background-image: url(/skins/ext/images/default/box/corners.gif); +} + +.x-box-tc { + background-image: url(/skins/ext/images/default/box/tb.gif); +} + +.x-box-tr { + background-image: url(/skins/ext/images/default/box/corners.gif); +} + +.x-box-ml { + background-image: url(/skins/ext/images/default/box/l.gif); +} + +.x-box-mc { + background-color: #eee; + background-image: url(/skins/ext/images/default/box/tb.gif); + font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif; + color: #393939; + font-size: 12px; +} + +.x-box-mc h3 { + font-size: 14px; + font-weight: bold; +} + +.x-box-mr { + background-image: url(/skins/ext/images/default/box/r.gif); +} + +.x-box-bl { + background-image: url(/skins/ext/images/default/box/corners.gif); +} + +.x-box-bc { + background-image: url(/skins/ext/images/default/box/tb.gif); +} + +.x-box-br { + background-image: url(/skins/ext/images/default/box/corners.gif); +} + +.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr { + background-image: url(/skins/ext/images/default/box/corners-blue.gif); +} + +.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc { + background-image: url(/skins/ext/images/default/box/tb-blue.gif); +} + +.x-box-blue .x-box-mc { + background-color: #c3daf9; +} + +.x-box-blue .x-box-mc h3 { + color: #17385b; +} + +.x-box-blue .x-box-ml { + background-image: url(/skins/ext/images/default/box/l-blue.gif); +} + +.x-box-blue .x-box-mr { + background-image: url(/skins/ext/images/default/box/r-blue.gif); +} +.x-combo-list { + border-color:#ccc; + background-color:#ddd; + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-combo-list-inner { + background-color:#fff; +} + +.x-combo-list-hd { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#333; + background-image: url(/skins/ext/images/default/layout/panel-title-light-bg.gif); + border-bottom-color:#BCBCBC; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom-color:#BEBEBE; +} + +.x-combo-list-item { + border-color:#fff; +} + +.x-combo-list .x-combo-selected{ + border-color:#777 !important; + background-color:#f0f0f0; +} + +.x-combo-list .x-toolbar { + border-top-color:#BCBCBC; +} + +.x-combo-list-small { + font:normal 11px tahoma, arial, helvetica, sans-serif; +}.x-panel { + border-color: #d0d0d0; +} + +.x-panel-header { + color:#333; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; + border-color:#d0d0d0; + background-image: url(/skins/ext/images/gray/panel/white-top-bottom.gif); +} + +.x-panel-body { + border-color:#d0d0d0; + background-color:#fff; +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top-color:#d0d0d0; +} + +.x-panel-tl .x-panel-header { + color:#333; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-panel-tc { + background-image: url(/skins/ext/images/gray/panel/top-bottom.gif); +} + +.x-panel-tl, .x-panel-tr, .x-panel-bl, .x-panel-br{ + background-image: url(/skins/ext/images/gray/panel/corners-sprite.gif); + border-bottom-color:#d0d0d0; +} + +.x-panel-bc { + background-image: url(/skins/ext/images/gray/panel/top-bottom.gif); +} + +.x-panel-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#f1f1f1; +} + +.x-panel-ml { + background-color: #fff; + background-image:url(/skins/ext/images/gray/panel/left-right.gif); +} + +.x-panel-mr { + background-image: url(/skins/ext/images/gray/panel/left-right.gif); +} + +.x-tool { + background-image:url(/skins/ext/images/gray/panel/tool-sprites.gif); +} + +.x-panel-ghost { + background-color:#f2f2f2; +} + +.x-panel-ghost ul { + border-color:#d0d0d0; +} + +.x-panel-dd-spacer { + border-color:#d0d0d0; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} +.x-window-proxy { + background-color:#fcfcfc; + border-color:#d0d0d0; +} + +.x-window-tl .x-window-header { + color:#555; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-window-tc { + background-image: url(/skins/ext/images/gray/window/top-bottom.png); +} + +.x-window-tl { + background-image: url(/skins/ext/images/gray/window/left-corners.png); +} + +.x-window-tr { + background-image: url(/skins/ext/images/gray/window/right-corners.png); +} + +.x-window-bc { + background-image: url(/skins/ext/images/gray/window/top-bottom.png); +} + +.x-window-bl { + background-image: url(/skins/ext/images/gray/window/left-corners.png); +} + +.x-window-br { + background-image: url(/skins/ext/images/gray/window/right-corners.png); +} + +.x-window-mc { + border-color:#d0d0d0; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#e8e8e8; +} + +.x-window-ml { + background-image: url(/skins/ext/images/gray/window/left-right.png); +} + +.x-window-mr { + background-image: url(/skins/ext/images/gray/window/left-right.png); +} + +.x-window-maximized .x-window-tc { + background-color:#fff; +} + +.x-window-bbar .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-panel-ghost .x-window-tl { + border-bottom-color:#d0d0d0; +} + +.x-panel-collapsed .x-window-tl { + border-bottom-color:#d0d0d0; +} + +.x-dlg-mask{ + background-color:#ccc; +} + +.x-window-plain .x-window-mc { + background-color: #E8E8E8; + border-color: #D0D0D0 #EEEEEE #EEEEEE #D0D0D0; +} + +.x-window-plain .x-window-body { + border-color: #EEEEEE #D0D0D0 #D0D0D0 #EEEEEE; +} + +body.x-body-masked .x-window-plain .x-window-mc { + background-color: #E4E4E4; +} +.x-html-editor-wrap { + border-color:#BCBCBC; + background-color:#fff; +} +.x-html-editor-tb .x-btn-text { + background-image:url(/skins/ext/images/default/editor/tb-sprite.gif); +} +.x-panel-noborder .x-panel-header-noborder { + border-bottom-color:#d0d0d0; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-bottom-color:#d0d0d0; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-bottom-color:#d0d0d0; +} + +.x-border-layout-ct { + background-color:#f0f0f0; +} +.x-border-layout-ct { + background-color:#f0f0f0; +} + +.x-accordion-hd { + color:#222; + font-weight:normal; + background-image: url(/skins/ext/images/gray/panel/light-hd.gif); +} + +.x-layout-collapsed{ + background-color:#dfdfdf; + border-color:#d0d0d0; +} + +.x-layout-collapsed-over{ + background-color:#e7e7e7; +} + +.x-layout-split-west .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-left.gif); +} +.x-layout-split-east .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-right.gif); +} +.x-layout-split-north .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-top.gif); +} +.x-layout-split-south .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-west .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-right.gif); +} + +.x-layout-cmini-east .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-left.gif); +} + +.x-layout-cmini-north .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-south .x-layout-mini { + background-image:url(/skins/ext/images/default/layout/mini-top.gif); +} +.x-progress-wrap { + border-color:#8E8E8E; +} + +.x-progress-inner { + background-color:#E7E7E7; + background-image:url(/skins/ext/images/gray/qtip/bg.gif); +} + +.x-progress-bar { + background-color:#BCBCBC; + background-image:url(/skins/ext/images/gray/progress/progress-bg.gif); + border-top-color:#E2E2E2; + border-bottom-color:#A4A4A4; + border-right-color:#A4A4A4; +} + +.x-progress-text { + font-size:11px; + font-weight:bold; + color:#fff; +} + +.x-progress-text-back { + color:#5F5F5F; +} +.x-list-header{ + background-color:#f9f9f9; + background-image:url(/skins/ext/images/gray/grid/grid3-hrow2.gif); +} + +.x-list-header-inner div em { + border-left-color:#ddd; + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-body dt em { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-over { + background-color:#eee; +} + +.x-list-selected { + background-color:#f0f0f0; +} + +.x-list-resizer { + border-left-color:#555; + border-right-color:#555; +} + +.x-list-header-inner em.sort-asc, .x-list-header-inner em.sort-desc { + background-image:none; + border-color: #d0d0d0; +} +.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner { + background-image:url(/skins/ext/images/default/slider/slider-bg.png); +} + +.x-slider-horz .x-slider-thumb { + background-image:url(/skins/ext/images/gray/slider/slider-thumb.png); +} + +.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner { + background-image:url(/skins/ext/images/default/slider/slider-v-bg.png); +} + +.x-slider-vert .x-slider-thumb { + background-image:url(/skins/ext/images/gray/slider/slider-v-thumb.png); +} +.x-window-dlg .ext-mb-text, +.x-window-dlg .x-window-header-text { + font-size:12px; +} + +.x-window-dlg .ext-mb-textarea { + font:normal 12px tahoma,arial,helvetica,sans-serif; +} + +.x-window-dlg .x-msg-box-wait { + background-image:url(/skins/ext/images/default/grid/loading.gif); +} + +.x-window-dlg .ext-mb-info { + background-image:url(/skins/ext/images/gray/window/icon-info.gif); +} + +.x-window-dlg .ext-mb-warning { + background-image:url(/skins/ext/images/gray/window/icon-warning.gif); +} + +.x-window-dlg .ext-mb-question { + background-image:url(/skins/ext/images/gray/window/icon-question.gif); +} + +.x-window-dlg .ext-mb-error { + background-image:url(/skins/ext/images/gray/window/icon-error.gif); +} diff --git a/workflow/public_html/skins/green/iepngfix.htc b/workflow/public_html/skins/green/iepngfix.htc new file mode 100644 index 000000000..a8c5d312f --- /dev/null +++ b/workflow/public_html/skins/green/iepngfix.htc @@ -0,0 +1,68 @@ + + + + + \ No newline at end of file diff --git a/workflow/public_html/skins/green/images/bar_bg_bw.gif b/workflow/public_html/skins/green/images/bar_bg_bw.gif new file mode 100755 index 0000000000000000000000000000000000000000..d0e0b054f2152cd9f37f7ee09bd2475a9014a9e2 GIT binary patch literal 809 zcmZ?wbhEHbWMq(M_|Cxa;>C-tTetrC^XJKvCr_U~Wf%pcAuy6cKnLVmP+nl*;A3Fs SU{F}F;9xU{uoe#ogEat7Zxf3E literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/bf.jpg b/workflow/public_html/skins/green/images/bf.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c41bdf1e943c35c38f22de233cb86e599e0da188 GIT binary patch literal 318 zcmex=i3*BJ!6k`h{6D}T z$icwHz{AWa$iO7X$SlbC{|JK^*r^Q2fQ=m}E++t#;6xT?U}9!v6A}vyopK2%FT%)( zA_?SxLi3*BJ!6k`h{6D}T z$iX1Rz{1QZ$iO7X$SlbC{|JL9(5Vb4fQ=m}tRTR^$i&KuEWs+u$jm03Bo-Vx|&a$Ql_KgarTJV&DNPXA)!H=;Uucj#j?8>hBzQ U?ZWp;x_|Ke8)@gd=J@}c0J{A$$^ZZW literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/bsm.jpg b/workflow/public_html/skins/green/images/bsm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee151c40f7ef7a2ee6d7ed21c31460aeb68c7202 GIT binary patch literal 292 zcma)$OA5j;6h&{$*EF?>X{EFs6vy3zf>6*+>Czmy2tNbeNlYCSKNAl;c$^3K-Ea;M z*j>NvK_VULfN;YGf-%OK;9N{aoJ0ws5~FpZwXx=fHM7iSGvj@pd*9S`-LxY^2$52z zCM~TktHKr4c>H$>M>vHFoDzqLBh-;_!eXe3cNmq?7xqg7^QiM5i^00jh!_{HFqFhU P)M15ts}4)D-iON*g`gze literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/bsms.jpg b/workflow/public_html/skins/green/images/bsms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e58d448cad27c0c3e5071cc65818abd57b45304d GIT binary patch literal 323 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{Jcb$iO7X$SlbC{|JK^$f*p-fSHjUC@wDml;A{>VP<4y7Zef?3Y&5fq!Hvr zWPJ<_j7&grNkK-S6(|ynOoGCJ|8FtyFaxConFSf_8E)sk(Yq$Q=jD%>(^9KXc&?o6 LadQP@!~dHAw0|+h literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/dark-pointer.gif b/workflow/public_html/skins/green/images/dark-pointer.gif new file mode 100755 index 0000000000000000000000000000000000000000..ff504f304cdcbf71ed547e735a8ae1b2de6bf252 GIT binary patch literal 49 zcmZ?wbhEHbWM^PuXkcW}(9rn*|G(l-7DfgJMg|=QAOOiQFmbf-H%eylMrtrv0{{nn B32OiV literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/error.gif b/workflow/public_html/skins/green/images/error.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8630575944bb13c948d52e052220c7ef261b3cf GIT binary patch literal 561 zcmZ?wbhEHbWMhzIc*Xz%|NsC0ZfF19#q~!-pu{8_jD z&(>{!PoDaF?do?UqwmH>-;9jD0ZC)y?-mx{EiJwQNjtmm_IBT0Tz< zewCK~EGhX}TKcP|=2vaaPaxUc{HvwqcX#)%uC8C*K-B$v(xhLLCjJ7FlPCY4IrA3~ z%>trXzZWd{y%2~N{$9TP_X?o1*Zo-!botgl+qVARw(ZZJJ%9G@`MY=T-@}Lg9y#*o z@ZrBFPyRi1>d&c@|1Mnkd*S@w3m5)fyY~0mHDG9fLxoO+;!hSv28L(`9guyXIALJ# zYlw=BisFlkhzJi0j|dIn(%V+kJylPlhP)wjU=%)0iy@$WOtIT$?hz(Q?f0B zQhLyfh#-g;dn<@|>9x>+e}#9?TD*F3Hc6ATh@Lv^{Q7wBec!wp_SIVX?zDJK6a-8)fjKjV)jeEpYm591%e=+M15lEbMie8#@TX>RY-$% z5XHixP3jn|I23mXZ3XuaZOG?Sl;Z0|ChvLdkxoYjSth6mHWJNPHIN8MvfzWMxfe~h;o~FUqQ5Z^~2Vt#@ z)UT&jS_3&kF-Xd4!cz1kNY2YzN=v8aZ-EM8;2!dTmI9ih@If>56#sZJy(VQvKAY5T z80-0!K~BEQNSloL285kXNABn{p-rf!(`l$^P}33|kqEXuhQfpw-0X{->f~`?QO9Qv z@j#@D>ST*$Bq>TXY=grgf0)P%2Ig@aVTgRF$_gARbE3(EMvh{{2(1#*&YrstkgMos z#5@BUWgYQx9x+kc~{3{4%-$3O$R2_qxM zjOn=^o#|Zse}>uC&@X?BwtLrNTM)Ogi#--_&(yP?*_P2D)I}`oxTuMt?=?+03jVXc ze%1V0@Mj5!@A9WPUzX+bNg?@D}pe4Rdk*l!>3$EC@h!r JUzRp@{{ShsJqZ8+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/fbc.png b/workflow/public_html/skins/green/images/fbc.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff292f0f2313d582b0c1c35416a732e2d110d9a GIT binary patch literal 40655 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 A>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/fbl.blue.png b/workflow/public_html/skins/green/images/fbl.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd9228cd668f78f5de6356f5afe8720f0d84ce0 GIT binary patch literal 1343 zcmcIkO=uHA7+r0RX=p7~DOM224OWG0Hrb>}vm_~P(%Ptrr3n~&%4B!ahGc)(otkZ_ zh+08w6+I|Y1bYz_#7i&gMT)JU2eCKBv*1zjphcn1CTaSE=&8f({CvFkzHiJ(-BYJS^#o_Oz( z;6B`&#z`fIOHe~px2R+h=*w%Uq-X{G^xVM&(P=R;>G&yLP$VZbAx=Y5sbH6(LZN^# z$fDuA9HIdLG{}n~`bvi45=vVyb+?y znmk#XVU`AE2rh)^NTxoPaXm{D5=0$iVR) zKk1~Ha-+jGG6yv=#}7vPsyWFnM2}#s@+?~_m7FDyQ_+T5cOVd8T^!4C3_&pZn2e#p z$hy5EvZ@nBx}fD%oL6LE>cXrtibFJQCaSgS;hffPRo3lvu{C8v43Z!p z(GbLnmQs{rc++)&NYWEDnHxZBS=aa|3NZ?selTt~!?{zOiznUf8(PP&fHu+NikQ!h z{hi+7tC_ zr#f#4_n-e-yr839mZ9zKGc)1ej#%kVCOr0Ir^LWaCSy#fQ&xt_=E%Aee|g_rH+J*Q zgXQVB;$-@f++g4P>Z7Oh@@J%QGUMITI@1sf`OZIMmRDA~>g;yA@A@rf{>svU=})^Y z7Ry8{tUoq$abdasU3Yr22wp6HXnb90nL6C*pcmS$F2_7{XE)7O>#1}l>|kK)RwGxq_7qC8z3Lo7}wCrIcueEbgtp4X0? zIN{M%rB?ML<;o<%EY8!Hm-}bV_m_~6__5GLd6I;&wpW9;i?HAA%22WQ%mvv4FO#r~!M+*P| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/fbr.blue.png b/workflow/public_html/skins/green/images/fbr.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..2dcc39d873686539fa55544acfed3fd7e24e0daa GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDVAa<&kznEsNqQI0P;BtJR*x3 z7`Q%wFr(8NlNmrki4xa{lHmNblJdl&R0hYC{G?O`x6Go{^8BLgV*kzZen4{sL24p= zeXNr6bM+EIO7tpn3m9zdD+&^mvr|hHl2X$%^K6wA6cm&cGE;1o!cBb*d<&dYGcrA@ zic*8C{6dnevXd=Slkzt6Dft8V=m8nq_l75IHH0{3mDVb@N*t8p285%&fBPoJvx6ua$1X93& zLmlKNG;u-!mXZt)uY%H|9B{OxBzopr0Kye literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/fbr.png b/workflow/public_html/skins/green/images/fbr.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3256ca010ea00408763140f2bee4b8ad0c5e1b GIT binary patch literal 41152 zcmce-1yCJP^XN$+K=6>@?h@SH<>DIL9fG@CkP!T$!JUh{1b26LE^={qhb7M;fphQgVjm=0T zt(?rEtV-p6P-IH_xRq@PSxqXaM`e-!rKmK%hkX{q{<1Es7yAk}mQb=G+2 z%$F;HZ*sj3^FHDI_`9?9FcHGTo8x3&JR`tG)`mitP75~H0HfldwmiZt)u zW~*iSO5>U8G!74ccrFd?e5aUFLpnB-LqK^neG{b?Zr#1f70jtvilG#H>Qb8 zO~(%SFmFM(b=mr{v5;+f?dY*FldFy zes`#@Gv%di;GI`rpW}uKR;aI?THpLI`%L&_Jg0xsFL+t?#C>sFZe^0w=!oO_6}>$} z2#h%E@IHc!x18P%y`&8?#2hh^ zGb?x)RGEdIrpi-4qo^>bu(7c65<~h+;O2S@=0ZL7Yx29i3`kW z`4>srO<~TPpd4gdplVy7aJu$83G%!pyMn)dO)ZQMElmC(FFi9onZQ1lR$ho6oEQ!* z+PJoXmpnp~AM-IE#kfSZoC(VJ8=3zWbYD6=a| zn(0r1m}wt!AB&;pjxhp??6Cta9R>ymO@rkm2hD?RBnNj z2IQ39;5KbWb|VTflrba4>2VH*LtiUa&8V)@!Ns013ri|amy~ zXxrnVMQxfe5)u!eDSxSF5qXReYh7110HNV+hgi)Br!@@PlkI>89=_;@E@_Zaq5IWm z85Gz6>25xn&v%X=^F`pBkq@RLYQz%{aRT3Nu7M~B(%|t8o|jH%V}2m|VC>4rSd92l zB0%s2N-jDD7pm+}rZD;e%C2MuyD;MZujZZ`lvynGLL!Ih_~4u{xpTvhe`=oDVE@AW zP3<8yq2h~j84dq9_(LTh7-zcwXzquP)?+eYx{uRivxwU>I*aoy^MH=8QU@aPN@Ad$ zZ;y4Bs*Igu*v}h5n#O@%pah~I*G?)HE$y~c!zo8hWBp3vckmELn-_C%yxVzUgj4RZ zT&b!;&LLSnPNNcrC8FFx7tWbC_^mJ)ec&THfDIM^$p1i6wuK?BM?#BHNyc7jOdW_D zJqm01csQzBqvB@e@wf6Nbs(J0%B*2ut31hcbic@(ZBNLF*|g_FY(^2t2pnIQ`9Z9~ zG8_)I&V@w-B!z77GtSNuerrXkWi+?S6N)q4C@CS57b8{qS~CUbr~OCV6v#OXVT&GO z5BRskGhv8O^6-V*<=6a7uhG?|7P&tyH5Q@@{MPH8X>@K&Ifyk!Po&~Q;Z%1jkHf)< zDbv!p09IJh)20KhgqQvc&Skc~m3kvoe&YVYbDxIoA>0|?M;mj^9p;(O^q%IUT+n6Y zed#!Ism5|)LFbH7${u9oS>yJZtij`-=M2kI<9rUhBhzU4oxllX`+;H5Jla`XVo+|9 zl~fz0EPlQ$b45&_j~7g1A`N)El82<(GR|c`i#G6eAGz>~Q1@pb531#AMulx9JpP)2 z3vX@Z#qSl}_XAm#QTB-jo}oU5_A-10#sW!S`^y%H^Ul~qGX2Fj+m>5i*L^2$U`^T?kkLT>e) zUb#D-bgvu@;ghwBnAr)^Sju`?uAPK6l@D_&e#XuKBz9##YU5;)+9Pu0Pv^#!Hm__S#~&hNx_zAS9h{F=6=|oxu>w+zQ?o z5E|~o1u9c-NJWd)8sSAUG)#7tem+^Mo@ASB=dZRnghuIBN}T)-06?qChFEnJy6w46 z-IYc3I<$3n@$sCHOw8l(U67nn?L^0k5DcWgp)h-4&=!<}R9!ImegQVaXr>8=S>j-( z;#CA3y=86eFK$1}T+XX)mX(&}e8|twZXw{_VY^)jwrF<$?Y%E&5|iS>W_Kd6^PP`& z{JU3jew6_22oZ4~W{K2=X}3>}Nx)$`!42T>_@l@(8gy?mM%A4a)(vL)Vb3fTBjs{7 zx_&w+OAxAfbm_vwbDo9N+6%3ncuzGvgzD+ct-=rFu$A=Z41v;!e)=p|Xd>a;UlJ_a zICB8mi#Gq{1Z^z5C`r;hJ+ryi7%LB}Z0KzGK)PcT+zLZvgO(~p){VzX)5K}tCak3iKh#h} zLnft)eLfJobw8h*il@v4#27wtc&1s=b(tG=D%|=2gN=NfvC(!3q+Zf+Q|z;Ya`-Yk zP!*74=mhH2D*FbwdhMeHRt@Jixr^fzb+Uqs zBaseu+F>^OS{q$5GS(iG*@g5}$G!V|zkhUOQ|#uJw&vMzq4wUH`K%j5a?fWr$4TRw zfG?I>nq&ei7M3R<(5QSr_32OR;6^YF-E8GIbKI%)kISEZ5Pl9egq>bsc_K4@Ih_$6 zD5?jyHrYyOY&=pRC4X@O0V!n!hc;q~aLzOHozpeRO{a~8wada8)Qjdh1LqIft&$af z9l14ecNx!y-){XCG45izUCgJFu#Wy}9nLWXp%SV7+OW@42O<^>Fec&UTLA9S>V_18 zvBgpb>wHf%lvXwzG0QWOp`JIfvV73m&+0Bn=^6Zb!xi2nf#1lBzDyW&H7{s_z%Trg zU8*0|?kh1fqBkNuwLl3gFH(0*Bjx0iY2OPh7quA&=#nPYuh4{ zJpt?Y+xO+*S7N?4V8^Q`7N{}&>tPTz{k(-PW!Cz_ZRE{jHK(avucGalezGUT%vWEF13;;{rt!F$pFGigtYbGG+xs5 zx9KIjm|tq$IQ|@wsCljfw61*=d$o{f&7OHt4!j=%<1V z@j~p8LUfV3Id+qdvPCAo+tLUN!YDVIK)n*H=2R@`eXWn#F;yDBs17;`r~EV7Swe?Y z8p7_>U`-Hio&0ok)M!lehWmKyBKcv zG5t2m);?L2t&go_A|I3a%UOOz-ZYl(&`pb@u5W)VrQWez>#pQNdj)sl_Sjo<~+^E-?@5O|v=g0v0T4mM7$BPDu#MS+|Qb{K1p{Sgb6@{O1 z8m&eKTyY6Lm%X8@xpJIdm1!OH1)7*L=$=X#v+~Lx|L({X#08tmS01otMFGpcbMLE= z{f1Y6p`du^MgU4;zK#@qx@&$IQU4e%Ox@N{BS2ei@R@D+OH+?$671Lv4m+uyLIiQV zJ>!?z1K!uHMH@9J*2)NaJ~@X2+H@|JKiPE~&1&#%QZPu&-YfqMC{rFe{C($7S&Bm29>EIv?} zX&CZbPd`wU6X0U7(r#1IhpC8N2fd}u_XRD$gKv#E#dXd3P?}L4_uKj={|GegU`a?* zoui*^b5BxF@{qcj^P<)`TLk3Ht<=-GWi33?8Wo{XAayA6WNlJ2i)vNrSfqJ-M05^ z^D?ni>{j@j?2L(bh2*V|gsf3Ty}L2EvPz=5Eld0sm5NEv2|&VMSi&>Svf`j#CE?`& z#gG^hCwc#M`8s%A^ggMK$D?JEhtM69$fz$`GtUC3XVpP<%4A^lOi)|s@%J}?O&mJC zoyuxZGb#pA2WJT!cj^PH?JQXwxrsr`A9d_09M4+Wcf_qg+l&y+nxE%UFE0lg*ky|L zDtfW+1Y@Uu?KtHvFMpE{F0_OV`n|2O;UREY&2G@`lq^O0g6sz&&)Q_k*pyR>FL?px z6_D#`zi?)^C=udXH3hFVc!)q*B51Y)IJr*NsX4kS^uGf(faPfFTa3DGq5ixa~V6Q2zh5#;__sp zGx-2~lz?OcJtr6QXnh2pM{+$(hDyjm9B6NBCNT~qo5|?O%ca=j09*aq_MhhQ8P@G2 ze!WYVp_w86mlF!bh!?9-)$Qczq)|QAyVjHy`ji&a)3_!!w!0F;Q-eWh|3JDnSp07( z&8CN*Z1sAqu0ykws(a%h;(wa|%b@zu45eZ+Kf^_xXjaD{kC)`o)LlT{2#*&fz+akR zjOn$758#jMd@U2*jz*w2K1IjV4B0;>c-a}7qVs$dJa^#%{Kw_1tLtR8f9g}`%nm`@ zKkvuK|D!dX!8<3v8`xz`;p21m|NX8Owxh}Yv-Quf=cZUDi)j6!nY%#HzuW$E=E~*k z;S?g73QAVrAisd0=Rn$`e#DLqnr21C(m8JD!wf+0MQZV(g@v$rU}6Y3IXY8!JV>g5We^DUG?!|ZMyd}ZGUE{>5AEL z%IL7-!Of?#uA&tDfLXvan$1`rp+_^!LQc^w+nyCqGri}3;yXgn)#~XbWzk{eDb4@F zPBnzm%;jgXsFe?Hz|#T>ROry_q+O49;hhs)>j)W+ zA;-#g`sGr`tQl93i`+6BVE)O~l!W((=6i<0&rii?9J)rm+MKqwR-93~5mu1P8ujQf zWS?*ZW~ZX=fzX!-YqRyT#Jr7uR%^_?UMWc5e)5)ZtL)paepJ^E&5Sp7yo0r9 z{wx&)D*QiGkbl9PL{afN-*9;5v2!uOU1zF}pndcyC!Cq)WDZo12fn|^yIs94Z#lJ#p$o#ZFO}m#Keg& zr}32uE_VkSz%xOw*ZVag*}qSX+UM=d`HTDrA0DLCp5`%W3Fv2tIM6pUffN#-4-yxBhlr+4Qunt5c)eaea2am)$w{<7YQL7U$Q zV_W8mJf_f7j(MPG5?v&7u_JrEtia`B66mC+xnw zmbMcA!r)fE*1r zKVVVk9NV*-oN4~obRkP<5e5NX=`iP$nV^aXWjC48$)(Tfi!wd-^g?yY_6;etjNaja-rypLjrbzyOm{y<#EVvJ&7SC5Ji)ulBiv_Gn zuZWZ3fEh3)QPds8%A&gUOrz*YwI13G|N7%;1tw};lcatjbb0A#;zu&ksv$|=X~dxX zv&p|ajJJg{A#h;)C@$0| z%fsgK&m%jb7DByokf~qspR=^&+A;6ZrK4}-R2lcy((O+2PZBNJQ}-=8mU?BmqG@Hp zFG}%{0J<_S(;UklOuUgppz9-hvzf{S=Jue(;3imw;aV|pFt_Yd%cHNg>_zwe6Lr5| z;mPE2B;AijuCMdaF_!zAVWF;PHdki|ycg=-;(haA#beAwz=oDk=#@xE$kWqr<0pus z8L7{?(x^&H{=?}WDP3>F`tJ;s)RbM-w@mL_SL5G@!EhgINs|jcSZk*_m_=fbjsB1x z)VbOQQ@3@D*T!ZYQWk?iF8I);(>;;>&yckYksT-8;m4q|IMx%JVj z&Z+t&@wZdEm$@hex_J(8e%;X4f>eng0VM~&amBG#GeiU!^Z|kBOR-zL$JR`uPnq3% zZ!xills5%JKk8DIa_lE8g+}kPetj~FUveKN7YbL&d}`UR&i{p1nGiX_h?bd9C2QMs zKdK?wuYouE`XHV7+oZ5Eianpauso`_i0@2>)Dxpam+)b$c< z)q^}~rfem=4g{mH9H~l}SQl;vhk5nwi(!Ho-P_Eb752bL{>UevD!7)!M0F6n7Lu;T zV==epg;b)upMqI~e6r$iSs9aiu`S*4-4h-IBxy?^lt&adh*8uFCMsuBVa5VfuFqhQ zFE(4lpPg4BfSz#St8mfzC)X;}i1)pxWHK5H{HmT3O3rUX@pC zjs{b~W|mAl@nzI)T^bu>c&uN_?+%$kHkzO!stTf>0|+&~d3qfg9$Ze4GcJ2P zD_EmNWa+IA1UaSoyIr^lwV*(|bjV8)8E?C-`mQ#d5t&RujKP$U##I=88}E_6G#;Om ztxDfyzY{mKbBY!{s^3)T_$7Px->0uTr=%lNJ)DG3&fNB094N4;$K-iEk3K47N1>t} zr|I0oc*GQ)H!=U6EPx)yIz{`j9a#jWWkYOdw6wMg8mTv!>Z{IC@^ttFPe8zV@FVYb zd=nGR=NWeG1F8#WfXyB1r~cb@LF~Uz9X)ND#)kzANr;zFf!I`zJlwdS&7P%#4l%vx zg%boWYDb+6e8FYcyE&a3X zPCE;H(Hi!@j|qGkn-|18;LLP8g0%y$4;)2FGTm*g8(b>nP4#lPI*!42Dq+ul{TrqS zm~hEx3(9cl8B&fgS8_(rQk3sEn_c?r(@?HGS{K^pg_fl^y_P?3VfV&`K8id?h{FTK zJ8?)PEqwobK2jq5kSe=7g!mFfp1LvNmg+K=v5QnT?fOjYcaq!2VXzev zt-IAm?jB#)w6^+l#H~~NFfTa+#=N6kYU+X7A=C;*zD0w@RQN8Ho7}gqW#Psi#bS2J zZPWdPdW6Vz)r7yfx)#%cCl+DV)kJQOj-CD@G!$xLXbgV*65-PU9)`iKeYu`g(pbxTQL@UOBG`V9U)d?8t>`Sj+X}?@C>~Y|@Ib-LG7c zFV^h(O4Y733Z3IQQ=|&Eb$Gh58kPi?lGrrm`nVj68SKqIw-qDUJR4Vz)qqy#uyW`q zK~~|XY~~C0G4hD;q(F*wn-pD5%}7?GhLUa@;NZTyxMUVKYYZ$aAI7>*c8J}guR>41 zxlJhT;=YW{;|mU_SNQz3b!3#;?mT{vxd(sffQiQsWW}h>;;2>5&$=C4PI}6@J)B)U zEfx21D4l!IofoR;q3n{lYix*A>3=5KGuYYNkS%3WlR^vgt=4TgqDVd_Wdu*!a{cY! zVMRP3|6mpL2eEt0q2vP$9tAO1T{KQRf!q!oWm2g9MAB55pNQnu<+AM;No(jly~8-< z{SPuY3}Zw8uc0D0?KSQH1yQ79#rhxdL|Ti7&3F!O>s`3UFIz4m+dm_a@KnXl+w~@E z50InAC-?tL5Cxgb3)j*XB6HHvqLG9!VHyV1c(P+yeas3UgHnF^9`M5rQFyj7LYV!p ziK!{8C>6OWnK{n74Vs?gj^7{?5FsC(uVRHi3bos7)B#vf z{Qmq|TB!Vvpi#Fr30Jn1>TxQGWiU#wSwsUKS+9Iz5XAyRec#F`L@V~VMnoMW+kYBz zz(z}H!iO9?74Jef_<9hjEHtL1%uslQg>L*26z+hS|J@nthf1TU7{iZjLcD7U7y(5! zwmd-{fizopM?tUKsLoIDAr*=H-zhQUbEE6l*@^Ia26TA^6To>CKTLjJ6aVtK5RDZ? zdCrnvuEUI0D*S(h5F4=g-CTwTLxc0}EzZ;ZHh5Sv2S1q(+Coc(OPj}#ckjVXeTu{X zMcIWdp0pjeAxq8Gi?)qW%YPm>@n<=U#C1ICOi7%|gBe;*>oo;>^@Hx%W-Lp5h9s}K z1hgp!?X;9MtBWsNN7S#)Y7jOxBcs)xv@Abjq)_8Cf;8gOxQ-neIuROdfgpe+XC=LrIy38e)zipiULK zfiEIS#p5G4V5d<=f-A(P*3XDzPyG&Aiw8zC+D3w#=)9>Qy|ue2txd+sge4>`g8DY` zWtL7%1(kA|DYO|0jufgSkj%79i6wgi`#b^FRz3XP&MTuxLqxb8EX#M=8rA&Y4Vw_9Q#%Q4bTHi^P=N2N0L~G?asxKNP1GIux z0f74~q?0zt^8+r*-x{>Fw_-%Go@(4483HjT_+ZQeqQh^WcznN`wu@(nT;N_7Dv7-l z*d;HzZlBtqTcrqvE@}7Oq+!c~9Cf|liJ5D6pTP>obG0Dqbx}n|%Jo=71g2Nx3+!9L z$sE(OAcN%(p?05fT%n^O-0b*;U5myMM9L+?bru7n6T(lIy_v;G?4QKcL{$k15#$&! z3tv)~GZrMkwTxeSZV=(mAaz0fIwr@xL9J;Cd@^v31lE_TMhCdxiVqJk2>Zr2mAT2n zU4A)5LWHmLzbme;e_7FK6$p-Nbyed&`etnjMN7NS2(R!E`NFZ8a;mpQ#5=QSLbVpD z?HPc7dpb7h0y3(4m} zQ(Tt8$@&rTCUP`?G!4xWe*R3z;An#f$6V3&iN?RU^J#Rbay!b7-UY`oV;#6pWm(8z z>VA&kl&&QQ`Y{mg?_mtWkbai6#=@yBGfyE%p%nYkXEOd*GUxeW%OH zHS%kb<+*s(_ud2|p%tHLC{`0*gzH2iFiuHpe6`Zxe0S_6p%Cv+A|cWVP@GXI#@Gn% z5+V6tK}#icfc z1SZ)nDb%QhVeE4w>QOXB$pkHwKg51+Nk){5^vH`tnM`raWr}xOUFk5z{%qt|C@#z{ z16K=Ozc(EVel;A{-`|H;UgI4Sw6I&}RTc`X1u!z@6UEqsRk5bJnYf1Fm+=x%t6f?h z#WN>5iujJWUmN}|Ew-MIS}OOKzMA3KX|<4(llaVaMG+Zamjt8WUZWw1(slFcXNRh~ zZIB9}i6y`32ah^)F!%C|GkyqhRKQRKvO-vm=u3%l68e~QHcD4ANtjK7grOy+;WZgND}~f7W%E!6_JA&=;dQbpWPOG5e^t^+2b2 zhj(<{k~Ki%5uT0sR-ZeA?!&@#l;G4tT+bG=N_LhW55X#@rQ(X%F;8?FA#ZdgZH)H7 zBj`}2XKcGsk}UC!W;<4u%O#SXrK3y*3P)kKmJV!L3dPhSw!aGuiT?<@~FmI|dBogKXn9i3wKFQq_JKu~8Z>3)Ao}xQMSZtK?kwORsACQx{5KZbVy7 zmT_|Hp-CBeq0zI?tnHqzq9NxbC_5g*VZ-n}FK0fl5m|TU3e4Q@RYt2I?v(N*Gi6& z3-Rp7*2bDWg8orfnVb$~-*-2uJu{5*+r;VqUvx4JDpF`i8Z+lr^La-su&5~nB zNz4vN->g{qFrpHc7$)ko!DR-R?NqNX)UT%tHHA{QglZEhKkKElHnJ_SM~w=K`%}b$U--ESe^ix)GvlZC=u>f|VoOfR$4t9mgFOL52-gQ|f(6FnkG-nozA7=}I z09_-=P)gmr@D4=r_)+IJg8t0>MAPsSTEmwA){a}AzH#XoB+o>7nj{Yg-9{5n?dA!K zxI{4JYx`7FjHSV^H;EW#eImsVwRPg+Z#wTfQB2*WX;$R%>xv#JpQIFPce?+f{s2`6 z)qqMTam>hqXM#SiW2Jm|%oak~s2E1DZt2Y)&vUDN>!53c!w7#-cLdwf&>&Nf=_SF? z?)k+aKC+USvu9y`>uL9VEJ4l7mcfr;xfanMrKrn*{2-)rTVn#$0rBIg0X@rH4kfP% z0`;x@8HpO4Fg-==)VzQXUxf_=8l=!rvkPjj!?pKisp<|8+Ct75w4Be~a-4Zjzwwj3 zLPI#buyETy@>uylAa3vdDK=Pr<&YNZ|Kam}v3u|}$z_jjGL=on3>hS~X=OSAlbYbk zpg-U!GbQhkKuXwGYHQ3Z!1*>vmwk~qSjKa4R57#s2o|>tS7-ji?FSpZKu#=sMM>}e z`}_3720-u9O9lrYtl5Ltt^m&U>O{a{u9a?*>c%p*h*i zBoFPJ2?Gd$Kpte@yL0LvRLkq2h~CA1Tg%Ani2O(B!0^$Gd;5w12%=l`>*el#BEK)O zM{|1Ke_Vd>d>l!6SFe3H4xIiGHcCZ{z5i&dcR@}6SetY5Xhud;NAJ6;3WhKIXY1WB z*H_)a|1--=@@z)9v4ll04xKPI%_Qn*-Ilkh>~m^>r`K4pxkujcsZVimYi1lt-Iw;g zoLiil*);>)?ZCsw@bo9)kTu)K?W(Dsn#R#G2zP1)!1;--LzNTUPLw-#MUrnSw{xSE zN^O_a&QxjJq4Y@gK0{n=^!7DpX9h3!$aBp8%t=%{uUZi6#AQ+dvYh5GW}*ako;2N# zwZ;WrF-#Q2YED>h<;-_L*Ipmz4QEGDgb&FN;2Ufdq-2ZfUqG)hXOk#yu}Rl+_!grf(nibK9Wwp0P~BUS{v`DwvHK(i$4r z(2zv zU%j~XlD)JEAxpnHa5PY9iRx)XKe-?{s~1TNUJ%I=-$_!5qY!ky=D}_>F>ZPmyvUMl z+CBr0AKwD_Y&$W1ngvZ>;VN9D<-!CHx$b=l8&FR!C(e1%_Q$!-?T^dQ*cGP>DmTWr zQ?J9ksI)Hi(Xu%OoX8}j4+ilpub{|cVq8L^!V=+_T9zs10qrYjT5lx*>Lg-|N@uEy zy(FP5P@dko$tqv9H_^Y6!lP{XM-m(%O@*Ir+!g;-y$-YFiR|(|VTxnf@}aCA#GzsPHcLrzBk3uGthS+q{a556u{)-H8SKpHH(WS6_4(JPd4AY%+rbeDX_tj}S2m^)8CP z{HE9NCJ-~Z##S!Tq2A`UGkWG$d&;DllnygtVf+GDKVEwFv=E%vfV#+u|?yCi|8lX zy|94u^(X&)Q*(8)CHQnjA*tEa2aj}%+{zJKVFSKwqO--Uz4$jY2ccx63hC>ky0?U< z&=7KdBuM!BUw|*vDS0+Q)E}E_qBAiN&1Xs->SK6}gCX1j&j%;Tt;q8faYGvBuq!9U zz;%4yGuWN*%C8UgOc_EW$|J_V6D`FxG_kiFGjRJ|$J-)~)C>OFsa%?2Xh=H#N8FKz zdsmzomv&k=C2YS*@w>}6WnSSvoQmwXjCt?3p!L4I(i#PzuXTtbZ#nq_{+L~~ST@D~ zHRrj+HT!)z0B`Nki+h4E=@wT}G~knjO=^SA%Z2XmsS$-Aif6IL7ljY51Vy5$FZqAD z#U^|5;#jtV$>uvb9XlC%#cJn%j%?{y#wtdthe727|IVRvJl{1!f_VekX;MAN|fjPVqY)cN+I4rieNO{_QT_p8Qa z912itJ($hE6Zi{SMfjNEK7xM}hXDc3(h*U)CjOQVpC} z3q$ioCtWnn6SN8unRd5aC9rTZhN$NW@XL<}P5|g$f!Ubpza+J?6TtEL6GPTaGJwpP zxq-IYqUb@BJy&V5c132l zfxgvPf8MWxzlO#{XvWRbtsk>~B@MxP0Kk6jAl}pL-tchuF~ft-DA)MtjQTcwnEbqq zxaT1o-2L(*UhR7cs`)JFL1SL5H|=wG6^m)CbJjZ!Hzs#g>^~v!#9J-yDhl&+DRyK! zfTLXgFKd5YfSx4m8>BtWDU%fxn4- zmMe!7qjKy`Q1DFh=R9Z`PkeTZVN}QupzlB*!Nor9A~8Yr2ez>=!(b-bG5wkf8FDrboPSUX-J}(FuMW(Pp|!WY1&5(o8Yh3;Eo2FESa@>3DV~R%Kpi zn2nSp;cY#3j<4co#T!8CChl>Xm_u8>XtL3wj(GQJLM*su=$LN@NGw4+@uGLFIV~2Y zA=7V>46i7&SkR#Bvr9+5O^0Is_MAW5%QCYdi8qZtGcRd8o8ev%%O7q~5$)rsRuTQ& zst%Z^IMF!`uS*=lv`V?>_9$E<)kE-o&E13b_e)RrZ+m>^@pN)k8XBgg^Y<%D_suvb zo3~J~*s+H?V++5AH!SVqPuOoDYjeqxjNtw{hn;fdWokxP**F_0lH9V+>Ib?y3lR!+ z`?!#HOqx^vvCUf6i);|l@ralfu<0wBBGNt~?Two(yMK z76BHd=eFx91IKcYfj%KSZ;A1eO>)I(!e!wFIO0!uvcXc%<-h?Jw;pe~rX&3*Qsc<0 z9xNei)dT(~WAA^%nOMJF&)>ll`AIUo_Pt3)xfLPNC3Ja-Ep0hZhY6#-qH^E>O=ed@ zPdcohzt75tb1E7gQS~7Z?RdiFnXssSaD5KCed~VlPPpKw&YH0zy0N=aHn}=aK)k!2 z$D5ao+Fd^=XZb-uAWWVUFt%Q_X*Z)_7jd|%_YLoEHCfWy6d$Me#nZ6Xd5FUa11M-28@w!UpK&o{03POX??FV%tHtn z3JK{e;^@CYHv@qqvy499IzRvR8+SC0>MZTEwY$)3sH&!V&VBmfnp!6d>Tzw+O*dpY z%w)H-d+0U@k|F+)mIrh9e*+Jb=l_TBu>15p$R#&Q%_GiD<5^Ht%ckM3$>GABi>q;e z!8{%jTY)WDAkCu_HS;_1%j)aiL3vQYh)~R5%k2xkashfjH%DT$VcXZGzL}R}&QFss zoTQ#%Q7evjjw|inkrMF{zR9s*C$#gb69#Pi-Shg0j$6IQ`W4EMIuYuoHUoW~k^G^~&@lzE;jo*(3omuQh}fp1 zW0FLi^f1u3q?t;u-O@F4b7Fi$L){Dr>Y>uJon7Z?-O9=D$PVhu*@pXD*#`5ox~*{n z_Vo1(Vt2@nV>Q*AOZ@v!DaPqiT?V00VJD$XDj&ON7f2Wi)KA8s0o4K%;Pb`-^$#8X zIqpN%-~HReN+RI{)$2_vW#*rC3JEZCsgjUzj)7Fw$6z%@ftI}jR~qj&A>QzOo1yV} zSn|kwWP* z1p2|xRGNm-2}JAu&giGRUy0D084O}f^5M2rZ>|Cgqyr){WzNcWm zr%UQ7j35Rve;zFcPbr3B5exkAfsJpll&R-p_~=B3;iPp7PAj^Z3^5B$$uKib(<$OL zC+QSnM!^`sBx;@fEXl&DYxODab4$&_Ms)|id+Y*ZL8Ax@A`%%s1H@Kv1Q=1`5{r<=uU)M^e`oh#J=P(OSB|N+( zCL9~?i!bU76c-WY)%CWjN4Pst0lIMxE7IRFY#22CN$2wq%1}@rqTZk5`{Vd~Dyd&n zHl%wdkX2itU|XEMu5@!C&YF)V_hN>DmfSUW@4#NVpQA#0?a*pmhoOaJvcw? ztK77%UGfR_Z(BHUSw91tM!R2O`PbwXTeEyoId6Q|(EiS`*H2uzkA^ zV_7y?iqPIpx=P{mU~hK=;tbIduq9w@JMGQ!?o`P0q{ynwRkC(-_lVK% z9vhoFP~gM=F&zIBI?VuA7sWNxjjgxId(LtF|GqH(8qNO`R{n=W-xnq$3b?|JEU7Am zCrwIA5tSc{5htl4Wfz;~eszi@HKbKZxZ=TcnemKQCf*1C*XM@?&Kt!yhNcAMSRPhmp}p^~gBU3buQu4% z*5i~yjbE3cckpkIAqK3M_m%sQ2^NT`e?2nLxgPUQ3o^j5A=u6vDhM@fBEWLIH1t;X zs`%i3hP>|y(f2Q9AX!*$pnnt@cI3XkBC{gWT?6T22t8Rtp2?JY@n zR~gR}ix)9Ip`Mv{uI;^yZHdosp|4k1y06!@MiV`S(ehL;?guM9*bwUj@{EbtM+%{F zy$2ZiJ^TDf-I$lbcKQ{j6Yz3D@?|6Omhy`5FxZci*jb3y_xCt`6A8Xe`|)1-HPWJm zCJFhm8|G4vE{xI0}x@bGF;tj^tvTdW?Rw&xnTQ72w z(QnXq(#_!RO@{BtW6yrnLgx19T1zi(z4pjoxZwbX@wk*WWz*i#Uo7dlBVNcCEGRti zq?y$@4*qjV&F~BbnHhScY104-P24`F)l|1eT=%VD?>(*`z+L}dL1^x4#&LV?Pw1F9 zf+(gBr(CPNrY}77yt*Ch$O`F*_!bB;ytv<)4%7r$HKy5 z=J0uA9$_DKAb4-J^O`|a|LDrvz(Q#BGP_bzC_S&Xl;kaOZNZJ%$7eBm5`WQOU;rf5 zq11o6VzK9Z+_=p&U`f0PypTp2aCuqv!(Q+PUhX~G>4SU&8_u+M@6nn)#WRnRuO^Ng zuQ>L@4&L@Ohx`lPG~CXw3qXp5__QZvPt_*O;{+paS{w0;eMrb}d)k+0K7Jcb29!(_ zu=L~C{tmhUBSTG|<5llHOp`+gd`upp*z=p?&Nt5n2XKu%LT`knN~5cl9BVDQCpvB0 zo<8eK&^SGNH@#8Z8M6~>_gNNDkf)B3;c7W=h|quH!i>C!W3XY(*50`nDp(h{eGi?5 zzp~noeeVUqD;>IrHVDdi9>BhT)>VDoM)KjWpnWs;35@9*-s5WT{O_CEj2xFv~P86{A~IQ@GJNYP2JY#Wu`U{CjMPi zjXz}R($aVA{mINOANd)#hcgY+x(@Ye*t|wBCvNv$5wp4qZC25TAx^ztasz#xtQk#N?K^HtSW|>saWq{Z9-~@$}Bi<1W&>iE43x^eM!w$&2x| z__^gJ<9P;qwvTM8a_S`C{~D!fjpZ3*{tD7{0kBwjJMpHQj)7^6^Isscd2;9f@FL&~ zSZh08mh3Nz)qkWVzR3t|IQEhzbbtUl5}%POw`Gr^%I4F@y~n(lhQMZnXGl+}fJA>F z3+utaN_pjkVb1`U|7|WiVU-F)VULJkxlO<5z<# z(^RKVKx>aJ!j;|iJK&ovS;!d=@&4)ae0Ims-*|sPG~O(`F17>AJwyYYH-m5fN473i zCbq{tVuBFI{I~zDz4wl4;)~b4K~QWIML?tqDk>mN=^-d0Dovy+O{9rPFQFx|VNL@Cz4d8yE;WQnn`MvwbGVA0 zh-iP7;?xWue=^3H3zUk$SAbQqPwT|wfm0c{iM6O-=$`nLd+sRbkEJE=A_QFMbGKqC zb#Gq@cB799W4+dk0bQ63@?(47P^Js_t+zgc&HngP2XqQcKZ|A9qcN~bC%t_m;BdA- zB6*>975_rhvm-bQ*TX_B+g`VZg|BC`GhM1_w!1C0ERPam^c2^vF$5DT^JENo&}%`a z4Ctm+90#L=5y>=r7)Biv&}_j@8bY>lqJcGA2f)HS5N^5n*LVtPAa?XS&TrrOr<$uo zzeWeZ5g5D3e!zMT>k2tBy?2-=GOY)A?sxCxP=)2_0$C*Hj5Lt%!OWo0)>QCoLwv8< zP1jGcN4}$4BiUnXWZQqb{9iHg&&a4+cjDV6(PWq)uMGS6K$n`KiPIDk^>fs;ZE;)( z7i{VPyehfftB#br_OHHeGz#7fZ`?L@>g1%s&<4u(@nbpl;hc?>Jof$NzQ!$DL; zIt3E(co*?H?bu7yJgLgH%{1m!d_s7anC$qd8XnPaUZ*MKyWJD%sjQApCDTu>BXyFO zrNE{x2;-U$u*W(SOtBTYxZp|w_FT1g(mZ^Rpapmarl$+KsGm$8!Li>d6GOR{YQDXQ zv^YI3fhKs@vW?h?9Zr)B3)YlFo9SF~$T0 z&X%=|;BhGzi4I!n%~;q&xk^&BOyIBTsdaT7$ZgF;$$pjY6Oza%h|JaEo4-rNcIPz=}Yi}ci^u4%VJKf(yWSj>aU z62-3x;}0y@I`GViu}0{t=rb)D@}b)b39qpcr03K9`62NR-%-AW&#d!g>=sg)D*gD{ zu#2F8x!oo#)S~{={#r8yAhTrIERUiq`17oDiRS3dJg@W=inrP8dETgWl|seAddFx) z3QnpfcyY{#YF=;!8}t!2IqO&}866+_v@WxN(iwSRhx^vnsMDzIacV6!VO+0|1R>wg zExwJ`NzN0F`W_Nxk4j{mFGyP^F5AVrMQ8wAZ|~A&Cs2noxwr(d{|;bZ-1%=ur5pI* z&jGCDvE2`(9tj7@3VeI4EyOomS$LcZb zlo=f6L<5wusz)x;^5ms5OwRpalx4iiuv|fH(d=Otth%mP(ZgSTe2HDat*1NNQ1X8A zIv=Qa$!ag~UZ{&U2)v2UjhZLQ%=qHMs>=eRrQZlfZp~pAMtZIw7)UUjO^cpY?q#hl zP1EWl9@czP*>zU8UYekBmYs2g@~Ey_%rn>Jycl*Ra_+5cq=29pjbA&LnMz0xAPhR2=Mf}J00w~fKS$T5Taz19kl1f z)IF7MgHNzK`gXzLHHHRl2f;KE+jQ3Yb4)u<93ZQSRW-9`_382}q@P*rS1hR1RAa>; zh<(mcmeWMo!#t|h@Y6HP?<`VIELNUSTu7*P@q~N)z}GX)0u&vcnw3|xrF?72KlwdY z?cuTHPWn;k7%P5GlN7|cPrE_B6dcv9nM63#_qo$Ytd+cq22;$KGvb|E1qY`!h?cHa z&~7Am*a~?rKpZFeMmmMyNC#zP35NP+wLWF6nKuFnE#!j=P!*n)mROIP?qK!x@2+Sg zdMrRL`NY&s{!As*Nd0XSU2R(O7`&4b&;+Wwuc)oOd=lC`lJUiT=3ABn#v|xX^mSYI z+>i)zAn0}cm(N`VvsF`mBpy^j(w*>@bYCv#V0>6hh$%Wdp$3pS#!O8c&4@sxvuy(r#npiTOXFvC7AIb@)% z-cEAJfBnbGairal49Q_#er6vC=s4Fp%7W+cU~*r;lNBA`9mt(HM};*!_uQy(%Bu815U94oEt z(i0aeBX*qQo)IlA)66YmrRhJDABgz zuRB1Zcf+?%$>gCR14qW_D=7?djRGrd;+-{%yhSU|aIDOZcxS#(g)NmetA*a~=L_lW z8F+D$PklP=Ni->$+Hv}$Mh1a;0luvL5PhSR0->~dbo7Q{A?>Zys(ZGQ7id52@j;3A z7Pa$9{aE~kOas1j#pKK-!x>_tU|wQM2^>TV#E0r8$Vh?+jOu|CMbJcU_^(bCZ z`lr$H3AiWTM4~GJj=!~Mou1t;7TL{0V0zgZ%~PcmP+@xMecP1&6{$!KP=>4o@XC>@ z>AJwE9tJd=ZCS4EBqCXongjTbI|GHk;LZTHMcit9>% zS|B@TYWLsida$0sEzUHU37fHx%=gG^%PT1C^@x)EyYn2M9d!cRYd4x?zG%nF$Z%t( zwp^)YNO$z>-evV-&Wd>FuDUmP>p$Jqv8t|EQgxd&)XxGG=IzTxiZ$yqg8T=O(HVTf zvtf8SNR@uCjW4z9M2a-k>22_bR}KC%5|$GTa=(EsG5)nM%sp1#2AsL1STLUvxk`?% zvs(Y66tCox9&}Dh#i5xIu3d9t;Ip^zBvu2u&{{RM#q!cRoEX0w=6`tlhArQ?$w`51 z{Mu1h#)A<57<;IV_mKz}_j&3|rE?3c2Nmdbk)p3X`BegxTxz-E^pjosO>Ka@B2;DC z7NUKo>+%g(OdI)UPfV?b#z8^9q+lm4Tb*ZqbGW0?%{}RX=_w82o})8cAl(E`P?~m)P=NS%wXxBIwl=fm@u?sP{>u?&-N}2}K(Ux|E zI?#I6)gjmAt`#?NX`l>c>Idl?fKyVJ%rGD5wc6I z)Vo9{(9Y$RNjc0Q#nF|cud=YLw5CakBSkd+J{H!&8}YNlWUHzdl?{&5(&Ps0VB?N( zPq?MiK3^AYu7Sk(PdwrJ-1AqjN7WRTjPN;eBPRD9up|a%Aqux%7j5uA1QT6^<~0bQ z17@RMY3yI>dCl)bM#syNf?h@z=BL zSV3qu_X@mi`dE1HQT(Urw`~bf3=!pMGQ+#HE(Q6Nh9seDwn&Xor=yjp?gdcmB}c8L zJg~1^+cU^r*n4g4HT9VvQhGi%N05-?xGo4iwld|V?zSJ>YO>L2Z)|?WOKY~}yJ^0V z4&wOD__4Vf^5Ls-jxg8uLJz_~LFI>~62@(E4j9uhqVt-|vhW^_3o4 zxbQ6Od4r;7wwZJ8UUJvKT{3sTX_t6>5lIhZa`{~;IE{-CPAn`I9njOKiBco)R>}s5 z#vigEsY&3=9)WamS(iw5(<0m%VaQDVGPJDzkz6KfPQx@eQrPHo)qWMR^^-}NlELU> zKA>{;ag~@Zgv)d1cB^WO?sT;vgh}=GxGadl*Xrn*SChN+&*iKvFUNH?*|CwqCF=G5 zL*ussfWf%IY;;VqUqwJ_#TJFBpzFl^h4+0=+eyLc*F53GIZv-*KqP)vbEhibr(01k zkRhkXT}$e6_ZN`_dn2@p2Z)uK$4R!(I8y%Qg2T(=iuF|}qXOYPCTheLzoT*(3A^CL zvRcK$ihbeCZIPcb@~)M@%>X{w*+|KA`K>@aAsp3g`#x;8^O-ZBOavGdlpTO;$+_2S2hjHo78kPj>bS%pB zwFI^^?ALvWChj7zmSfY~rM@ZaX9z$()}3I*YXo&bUkOfUz!k!C!WJQi?22FH`5$=M z6Fx~fS`u7R^986XIE5gqf3AOIt!H2Lv<>im=87@x!6Yu{YoAf!8*56xu|8{z>3=Je ztngH44g!Xo>h(tGQX(W4Yqshq5n~K11V`LUzhUYNL}Iho?dTJcQ!OHVweFlCW;l|B zu$G2&YMvh``0uFs_d)LW`NSe^ za!+*65QCb~1QQ1GR_jaAy*Qse*8(0osFwNiziG&43JW?XX0NFMPcHEPV}!D}J{M_p5uzVnO(R7*M|o5akQr zLO+kRi(*$Qjdk;gmLu;h_4I)}AS9g`nVd>`_XC>BJ)GL$`xpwNKO+_Q$CR7Dct}>z z7B{jHV;8*33sC&zXrDp9+p+qre(j-c%FoYavQ^3oD_CKbR!?%m!}AsJFGAC7u2f+l z)F&NLC(bTsfj*7e$Mk)N1%X`OHE>1dG?>?pF5!oUxI59bq{5%*cwaVmXg2w}HAwvz zBPOf27!z4$G3*MpEF^hi*Assw)Q`lkPOuh3%_h>UHIYHrjDUrXo049vGL0npcEV^8 z=OmzCZ5KdTIKNQHcBZ{~iGR#magtlGZ|@j)o>|UoV>2!F8q^gG8;H|}uuv0;E~aix zE;9!oJu?<|r;R8ynBBUp{@ zX6JCcXaXr`bSwhWn?W7Z9ZohFj(oz|>+hBXA04{+ejZXU%9(mK^50Y3_nI3xll^a{ zoKxI4kNxIVg|<5Xr)xBiz?y6B`nS#x6??3`;oBYhe5$zJNUj{Gn3Z_>;<4X}gZ_jyk*@kHZ^AmXOUvk`VHV=O z;1Bkf4BFH#hJ1Kp?_&qxnF%b{Fw;e28Q?Ld>XAxtTE}|kmq)HsZ@f)k**jy4Gg3N@ zuSiqeZ?!EeIetXiq+O9XUu)CADNdjwbsbn(SXe|nf<}C#q0Qu>r&DF?dZ*G>O_&*W zQteuG$q6nrsKHC0-i(?OWxV9tEF0v{jEZhu((m)=AZQXiQvBET zW($YgfUFX$2A(88Mszgo)WRWFBZJqc=VQdLeSo)q%OQ$fr%S_O&>XYyk3E%Poji>1 z3?+N2tPdp4%O)4OK_xmHeCf0wuH~zd<={M>A8)?j>Wqr(1)zTNsAUrz)71B1UMh9j z_h`G$oC$MUtrnFyJ{y&URm!*G%mZ|*)5q=?>Iti4lp*grpifC#{i0FbmEm`Y=Az@x zpB$}oqzF=aq;5pFJ!SrJSp16Dz#DqatQ7TCY}Z+P&T+35Qnd_pNCJS)r%w6G=T38!myk5^t9yYEo)IW+0@gO zmM$1dTTzdJFs&3Ek{%h~7E@5M2*;TmLtgr*uc9`f22)S!$-q8DURL?CUu!L%OQNqq zD8!Ejmk9}ur@RK%;d0AIR~TbJsX8*(osFrM(xbv&gek8q9fRIOJ!;pluw7HD_1<6c zlckGyYYCjXjxReEoxY|)I~xD$9^7~7pr3+YTgFf;kg1MbKG6zu95@Cw!FAPKkMD6X z9yKe(V_8FtrZ<6KlIC8y{kT{CfuV(`^l0tJ(D3IXS5$`$aZk-8gu%-huc~R~rZ;@* z4M7c5)L$L)k6!6)uD9p^^M&&mg-mQR;^vSZB8_te-}>Jml=a}hjVv4ZfD?oUCVlQ* z+xO6lFK7>6kdRoA(C?Mvx;winKOO|0?7-hKO0{Ino8RiPesSo+e|gFD1WDo>$d-7W z_HqafRbxpDaK?s6qC?(%L}Q5iSxU4Y^8zBy1RrB?3^-kth@wD+mx_f+=wKz~1x7b&hQ zrRB9WX)lYVP~CKP$F(x?XN1}UN5u4_bKETyeE#Vwo}&GkyXZQdk-hmTV}oISr;iFM z#0>JZK?u9HB01me15lmo8SRd5T*4N|=M5zjT@Z%Mm2FPf6ZX8kk4|5Cd0fu7)<*hB zgbg7#B5iPrqKQ&StW;|EC<{hXOicB6J|$>J?QOho)Wis&}B?`4A)x=8wn{|*|W28s6eW1ywzZMX|Gwf=m+Ex=KLC`CbOZp9>6qU zbLYI0!d>FIXH&Uf#a!SqXgYPGBdULQ^m=uyit7k!J`nIed8pa&cM16!Cksk|#&env z`Jq=@4Z4cx4-!EZlb^1yq;BKAHjPlYx8mQh>n*1Au=NfkG!-YT>&bU{Sxwt_w<*_Z z#hjbp$eCSQ7jE-aeKg)O^V!v^r&O8vahffnoeoFVZXY<$Ra5D~z9Q9tM6qJzs-csV;epR}z%@nI5vhJl56eR4 zdr9X>lZ3BXHs=oHECwGI{lS%xH7z@dD@RUj?r{jf;|ttpPfwp@*QlY`;B^LtNo(ksNmTqEteBRp2jpSEKaW zw2A$yUuZlGX&1)gOn&6hTsw=IM|x%J`HPonj;ecz{=vTrW7rZz)Sfc5Ao z7ggCfCNNaQpXbm?rK1dVYAV;-YfI7e+7wF!#nvHaZ2nyVc)OukI-Smh2t*7p=CC3! z4XVGNbPpv8Syqn1K)(!hemXcCXwny5cixF8-GBZzisQPp{FRv%o$CQQ^C+dCodNd4 zAqE36HEYRV`I^)Z$GlDaa`VS$O71dt880Gr2P{q|<QAEfyK*HGjoa?kpQJhOBf#XGOu`A0d zAK!4!`Wz1KdF$MP&e>(1)F=%N?a4WCD5^9LK%@vT3{wBH>7`GR=@lCQWIZuv%9F_NNr?RIz@3Fsme>Q(!h-!KOQ1?T!+4| z;{0vp!DWZgG4F|(!(eFakTCT)-qit^6;1@TO9&<#DDHFvW;K5Rvc|i2Y?;z?KiB%^ zW73)Ud+G#Z-dQ>-w!Qrv)d+K;Y43bm zb%+JhkYVJ!pZ1a^azWmGg7p2&EtJNIeS_lji zFsJ)Hd52=X6d7n$lNz`qmOfC#3$OTc?bo4m9d|mM4EZ>-n!e)@=N1zTfk@E9iEAXC zp~%H+!idr|oVTj4W7r#3pyaw z^z8v5NEkS{V3xT0^^ErF&ey||qN`;`nEZQ$A9AXGcPdzuIC1`2hw_@~4Xz?8t~9~X zcTe5?rR~?29wzFLgR)FcI-rpgxXdt9?x+l*r&TT-CGUZ~Ab>z<5+weM`%TXu`${gfG zt?ns-meGa$+WuQ;KFuY~OFR=*n~yu<3S<{dNfH`Q;xPG1pU#T8|ZT7mXfW}K*15VXs%Wov9w*+=py<+MZCvP9mngxN~WIkrXWy*Q&VHV#Xqa8u)~_p zopBTWf+psxB79sSZ{QD&3Sti4+G1VN`g8A17_~jv?t23YAY2}F6x54ot}ZBcZX?L7 zz8Su4*;pzvEbZI&{L8i49-Bw?Q9C$?RNj*V;_{4$ILIQ`_QEAz1}wC^#GZZE5maV0 zW!}9+J2z|;H4b|OKTdwOCD0zCsP*8I`L(x**CFcfeVY`ad|9oWn})M2)|tFO z$z|1*``H6dD>7GptOV%g5U%Fke#J9EfkArwPwMb*O`!R z>C}n)_YZNUBlhoYq6=2J&QXnUP00s$J{jG*!lCI?UEz5~LJ+eFwA%WCZcqaFtn%50~XDg|jPaYjOJY4E4aQAJ_QJutP-sOWhIJ=)D zFqp4Qh#LBJ1lkq_^Fk~hNsImV9%i~_cKGp!;CBohih$Fv> zA8b#oMTDR2R&cu}GHC9vHrJ%2W${E)NcL{=dC61kEdc*OM4LBGlk8T+?XBQJ^3{=4 zpBRbU!z-i!mwlVPoo#hB#DMihW_bg>U z*|nojF7EOC)oKfSg=wqaw6~s#;PVt1~K4@0S-9*9NK#0 zSBluD`K`q1cKwOBg&pV4vbm>RZ$g}lMLrTFUDmgV?(Muc@D+=PTjF67bNt|aKlxXr zQ$3}$4{f`Av`|@joRKFX%}g88pO97ynml+ra-78pLKEuP0D&6jRNI|__qZJ05P_H= z!5`k5MDD)+qhb1pZ>m$0LfaQPV<2~31>K^&tbi@o_yhaCVa4}@+^$1XZ+t7}LP=q2 z#920l%}NtKvz%_iJH1f8wbu*t-R@Hq#d90_<~&PUxC}zJ#@XiZpL{^%Nj6{0o>O|( z#R=ADvVTNK#6X5e4+UOm5ezHyy&7MQ`lQJ}4p9#_-K}+YK!xNg1AIMZZdC73dVreW z_Rim0NW%FAw>2=|4fKSo-jS)HY_Dv}ca@ESvQ2`rrX5uAlXLq9^ZAdMq{V}>rhG+T zAMVav+a_?Zd*PiGC9MyOMKOj;%krz(^_nZ1l?9nA7?0^3mrvgp&nzFg@m*n}lt<(J z2P@qX*NK1te)yYTveklIH)6u^lfu5~k!04Q_mPa?Z7UsQ%zkQcEU*PZm;1(hx| zBGdOCy5s-RId~;LJ#K1pejYqNRCIUShy7l*`dYR|QW?D8h+cX%DZAvOT(Tzzj#;g} zA`nykF?N4szTut*h#I>+S*KoM?iP*?}W8y@S_Nb%rO$jIV zw5CUzD1}pp6|WBlD!OgmB3I8yGX|s-w>KIF!H4bpv~haWo8WOLi(qUBQ^*ptqvJ^E z4zxb!3-vyoU-xTZ>Absspg_CX3qegR{glL%IZ|P5pt)bz_Zr0WY3OHTlZVJzz&@LI zm=ONd_QN*Ai*r9koZl`_Dp2B*TaaBLmnDx_Up(l&UwADFNIsz`$39%cx-a>zra7fOVI~M1iHEVdWOng_w@Gh2g#9ZQF5|A z9w0gUQ|7AXfkvJ;e9lJ&ds;_X*tkdey6bqzfem)*N9b}g@be6Hla27ZZxH8XBmpq5^?H zPCztH1O$7lsOjkFsHm!|sH-b;6v`oy{-JIW%Kjnpe`fM`K4(2c+=G1rLwy4LWq;@E zc0C|06eK72yP$uTzZ&Nj_)kIpA%6knpj3%)3sg}%p{nvv&YXn$oQ=9h!JclR0l_u_ z0k;hPZ2mvLZzpSHt)c%r<$n_WTk5~*JVHW8 zr|7>VHxKae@rwN4C0Ex~Q~fLXe-QnZTwmoki2nfQ59+_$^k26BpMZI||HCUVEcn(R zyT!v@#q*Y@pQnFl2#1;4e`e<4uIm*L?B^D0;N$1!?Wq#z@2#)$@5cYJet*`QV+)Qg zRsQki-&Ox-SN>mF`Ir0umF)k_bhD5R!QI5QiEBdyHYDD3*CwtF5!jG;(_NdmHbh`U z;!SsL;@S{_4T(41wTWv(1U4kzbk`=X4H4Loc+*{*xHd#!L*h+$ZQ|Mxfenc_-L;8p zLj*P?-gMU{t_=~`ka*Kwo47VaU_;_fcWvU@5P=PeH{G>~YeNJ!B;It_Caw(;*pPVB zU7NTzL|{YWO?PeL+7N*ai8tM~iEBdyHYDD3*CwtF5!jG;(_NdmHbh`U;{VZIJO6#s z!_%Mhcn5^@97m;1EratENbiNSr){+3%5C%n?iva~-L>zGCv``1gB2EePo7L%6>>NC zUGJmF~kbT6~_8?-KXI9AP z4T&o+&HVDd=2N@BDsw3rJXU*n;RW%Y?BH8y$Pz{0^}}*aL4fC#jLf6D^aeP0BSMI4 ze#ZeDt5U*wQ{ucn7j4H>6zgeR8{_H=NsZzZAGg$E1Is;k_$Ji8P8c=rWt9G8)b1^_ x*W|-l$IUD%r3*Y3AQ4EXK1`$b-=gmL-Y@m=y(d%W_cJaRj4jR9X00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru*98Ot9S~=9h+hBz0nbT9 zK~#9!?b|VG+h7=g;ZJG^osunUeT7aP66h&>g3hH-@Ch;+3U%?43mEFfS1=?H$WU^E zSSP5m35!-;9B_pc$1XUI`#kXT3)@=0Nv|a(cXxMHr_%`lfK63ZWeDtqBuNb68O&z0 zNXxRE83h0Uu&J^vXK9}2Q=UEqMG@E6*Mp0Tix0!$@MlC+NklwMKZ%H> z*XzCQcDo;skB{FU9v;3iHUMB1k3u0V{txr{JiEWYpN_}lZ~cD%M?_SM74@)q*wcnR zUHW~~c>n;w3;vH_Xv9^_M{~y>R}NA0{{SCd{9J7Skxn%68QNY*?C008zk zG@f$&XdtX}S3+n20RQ6Q-OgV|0nZ*1tG=r?4Fb^s0Bj>HR$bfxyBiFdgVot1@ALGR4pyIw${5KkA!5Rc=@2?+^CA~LMZye*;<4GkxCb47S; zJQ!WwZe&>Sa82MkBer;gTe~DWM4f33y46 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/frame.home.bottom.png b/workflow/public_html/skins/green/images/frame.home.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d83a05a7ffc38b124ea9b629bb395a1e3cf1989c GIT binary patch literal 557 zcmV+|0@D47P)>Lcv1_3NGBV7f5o0xU8X0 zoi?U%nyA?&_5XumUIvrJEZ)acxUMT(t(E}*KpM~U3^NQvkE;LxWKlU`20<|6DgXdk zR8CYHjmCSs-R|4A&5Zy6^q?@t^P3QJCe~dgp|?{J6dR%N0vzJ zdf)&6iYIRR(Y}q=zW&tCx5?it)=y5v9}tO;ZWHzX*-V6k9xwoa;)aEx^>nEPhTij& z@BK^`-^Figh@8tHFaV(NL6H^~S>X}CC!>(i8@x!_vnC0G0szVz7+K-*Cnydki}>Jh z!Z>FqEC8TfVR3SoS~z4id6BaQ0F*a44r)CpQYVXyDI-s~004>`5Si!lNFbck%{F001SMH1hQSF98Ms>^8=?^qOH000000NkvXXu0mjflF0E1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/frame.right.bottom.png b/workflow/public_html/skins/green/images/frame.right.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..64b06aa2b852511bc8337b4fcfcd0afc46908475 GIT binary patch literal 43095 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 HZ{Po4tZ$}k literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/frame.right.top.gif b/workflow/public_html/skins/green/images/frame.right.top.gif new file mode 100644 index 0000000000000000000000000000000000000000..00c9fc88a8df92cd8570414f46e0b945d645abcf GIT binary patch literal 197 zcmV;$06PCiNk%w1VMGE60HOu}|NsBr-`~v4%-Y)8_xJbV;o$%P00000A^8LW000I6 zEC2ui07L=_000AuXsR;tFv>}*y*TU5yZ>M)j$~<`XsWJk>q>*L%!WV!c&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-@?f^1g6dcWYXcuX#v&*-$eS6B$v@VI{XE)7O>#IuElTi%$HnB^3+|jK4fx977}|8Q(Js{9^1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z76M_$OLy!300kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!ywE43U_c{OA9FduE9hr1aOgeV# z*o`X&1_vc}h!}vt9LwTo_KF8uqOHYVvrSZDuwvH>cp}_A9cToDr>mdKI;Vst0OX54 AZ~y=R literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/ftlL.png b/workflow/public_html/skins/green/images/ftlL.png new file mode 100644 index 0000000000000000000000000000000000000000..14b43f8c749408a9c048000cf6b4a34d885f3f47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#IuElDyYcUtF5*C;b)GJcAr`0iPT0tM$UwmLzkQ-+ zuQpo(TSNov9%kVUj;~De5}4UGsZNpI(`@hE>#W-Z z*4_KPx%gc}uL48n?XvknyZRrmh;H7VAknrwjEOgTe~DWM4fHw1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z`T)X=PHRkN00kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!6M843U_cY*YN~Og)>{XE)7O>#IuElThZXzmI8_D))^DCJjv*F;jIUWmelY@-fG|bi zKM>$E0Av9(J_SHId52@3&B(4~z&w3}gvAx+!RUWP?CbFg`XKCdPnl z5y%&Wf(zMT7#n05%s^x|NFD_KGXeq3B9JBcf(vF4SSLs`9{dlg2&4uSLU4-+SpwCE z;cA#=AcH{|<`@tSE`SZaoTeeKDs;W8)6KiT}gnm|0JsKD_|92qs7i`s~@W6F|O!Co>?2>fqmdKI;Vst0Lvns AXaE2J literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/input_back.gif b/workflow/public_html/skins/green/images/input_back.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9d4a35491a4383c6a7aa91cf2064308ee254a4f GIT binary patch literal 44 tcmZ?wbhEHbWM*JyXkcLY|NsAo4<8hNvM_*v4u}BBFfcLq@JBLO0{|Yv3V;9r literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/message.png b/workflow/public_html/skins/green/images/message.png new file mode 100644 index 0000000000000000000000000000000000000000..d198da7514ae8e2e8ccf255f26cb81ec04b3c117 GIT binary patch literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol@0V0Kb;z1N=fk$L90|U1(2s1Lwnj--eWJ!1Q zb!1@J*jMvAa59jukn9oU%fL{j%D~Xj%)s#TKahUOz))(y!0;-8fx&791A}<}r1+z5 z3=E8Zo-U3d6}OUV{yjTe&&DQ@l#-CZa*4;`*Z+F928N`cUw`vY_$hy=orC$Pq$C4V z$J6ig@ADKK;8@zI1>%W&JhI=UaKrR!BIuPkn1D= r1YQ9Lo&Ep+wQ@Q2Htph3IKXh8Yt9V)eAN(OEHHSw`njxgN@xNAWk{Lg literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/images/warning.png b/workflow/public_html/skins/green/images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..818df84e6fdfc8ae23e755a260b3f134ba7f8386 GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol@0V0Kb;z1N=fk$L90|U1(2s1Lwnj--eWJ!1Q zb!1@J*jMvAa59jukn9oU%fL{j%D~Xj%)s#TKahUOz))(y!0;-8fx&791A}<}r1+z5 z3=E76o-U3d6}OW9{Qv%~p3Q(E=)a_-goL6^14B~ckN?t#k{URjt}wC)a5F!aSNLu3 z!n8`9g@K79$97$TTxBvKV$vWONk(xme>Pzvl;gn>-*h(Nc0L-FyT V6H&!H?Z9wj@O1TaS?83{1OTm{Y#;yt literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/green/printstyle.css b/workflow/public_html/skins/green/printstyle.css new file mode 100644 index 000000000..32227b7c1 --- /dev/null +++ b/workflow/public_html/skins/green/printstyle.css @@ -0,0 +1,500 @@ +body +{ + margin : 0px; + background-color: #FFFFFF !important; + color : #000000; + font : normal 8pt sans-serif,Tahoma,MiscFixed; +} + +@media print { + a:link, a:visited { + text-decoration: none; + color: black; + } +} + +@media print { + @page { margin: 10% } + blockquote, + pre { page-break-inside: avoid } +} + + +.GridLink { + visibility:hidden !important; +} + +.page-break { page-break-before:always; } + + +input[type=submit], input[type=button] { + visibility:hidden !important; +} + +input[type=file]{ + visibility:hidden !important; + display:none !important; + overflow: hidden !important; + +} + + +.FormRequiredTextMessage { + visibility:hidden !important; +} + +.tableOption { + visibility:hidden !important; +} + +.boxTop div.a, .boxTop div.b, .boxTop div.c { + visibility:hidden !important; +} + +form.formDefault .FormButton { + visibility:hidden !important; +} + + +.Record +{ + visibility:hidden !important; + overflow: hidden !important; + display:none !important; +} + + +/**------------------------------------------**/ + + +/* Box Top Model BEGIN */ +.boxTop, .boxTopBlue +{ + height:9px; + padding-left:8px; + padding-right:8px; + position:relative; + overflow:hidden; +} +.boxTop div, .boxTopBlue div +{ + background-color:#FFF; +} +.boxTop div.a, .boxTop div.c, .boxTopBlue div.a, .boxTopBlue div.c +{ + position:absolute; + width:9px; + height:9px; +} +.boxTop div.a, .boxTopBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftl.png); + background-color:transparent; +} +.boxTop div.c, .boxTopBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftr.png); + background-color:transparent; +} +.boxTop div.b, .boxTopBlue div.b +{ + width:100%; + height:9px; + border-top:1px solid #DADADA; + background-color:#FFF; +} +/* Box Top Model END */ + + +/* Box Bottom Model BEGIN */ +.boxBottom, .boxBottomBlue +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottom div.a, .boxBottom div.c, .boxBottomBlue div.a, .boxBottomBlue div.c +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottom div.a, .boxBottomBlue div.a +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottom div.c, .boxBottomBlue div.c +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottom div.b, .boxBottomBlue div.b +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +/* Box Bottom Model END */ +/* Box Bottom Model Blue BEGIN */ +.boxBottomBlue div.c +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottomBlue div.a +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} +.boxBottomBlue div.b +{ + visibility: hidden; + overflow: hidden; + width: 0px; + height: 0px; + +} + +/* Box Bottom Model Blue END */ + +/* BoxPanel Bottom Model BEGIN */ +.boxTopPanel +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxTopPanel div.a, .boxTopPanel div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxTopPanel div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftlL.png); + background-color:transparent; +} +.boxTopPanel div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftrL.png); + background-color:transparent; +} +.boxTopPanel div.b +{ + width:100%; + height:16px; + background: transparent url(/skins/green/images/ftc.png) repeat-x; +} + +/* BoxPanel Bottom Model END */ + + + +/* XmlForm BEGIN */ + /* form BEGIN */ +form{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form table{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form.formDefault select +{ + font:normal 11px sans-serif,MiscFixed; + color:#000; +} +form.formDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; + line-height:180%; +} +form.formDefault td +{ + padding:2px; +} +form.formDefault .content +{ + background-color:#FFF; + border: 1px solid #CCC; + -moz-border-radius:10px; -webkit-border-radius:10px; +} +form.formDefault input.FormField +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; +} +form.formDefault input.FormFieldInvalid +{ + border: 1px solid red; +} +form.formDefault input.FormFieldValid +{ + border: 1px solid green; +} +form.formDefault .FormLabel +{ + color:#808080; + text-align:right; + padding-right:5px; +} +form.formDefault .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + + padding-left:5px; +} +form.formDefault textarea.FormTextArea +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + overflow:auto; +} +form.formDefault textarea.FormTextPM +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 12 Courier New, monospace ; + overflow:auto; +} +form.formDefault .FormTitle +{ + color:#000; + padding-left:5px; + font-weight:bold; + background-color:#E0EFE6; +} +form.formDefault .FormSubTitle +{ + background-color:#D1DEDF !important; + color:black; +} +form.formDefault .FormButton +{ + text-align:center; +} + +form.formDefault a +{ + text-decoration:none; + color:#006699; +} +form.formDefault a:hover +{ + color:orange; +} +form.formDefault td.withoutLabel, form.formDefault td.withoutLabel table td +{ + padding:0px; + height:8px; +} + +/* form END */ + + +/* pagedTable BEGIN */ +.pagedTableDefault +{ + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + padding-left:5px; + padding-right:5px; +} +.pagedTableDefault, .pagedTableDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a +{ + color:#2078A8; + text-decoration:none; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a:hover +{ + color:orange; +} +.pagedTableDefault td +{ + padding:0px; +} +.pagedTableDefault .pagedTable td +{ + padding:5px; +} +.pagedTableDefault .pagedTable +{ + border:1px solid #DFDFDF; + border-collapse:collapse; + color:#27373F; +} +.pagedTable td{ + text-align:left; +} +.pagedTableDefault .pagedTable .Row1 +{ + background-color:#FFF; +} +.pagedTableDefault .pagedTable .Row2 +{ + background-color:#EEE; +} +tr.Selected +{ + background-color:#D8DDFF; +} +.pagedTableDefault .pagedTable .RowPointer +{ + background-color:#E0EAEF; +} +.pagedTableDefault .cellSelected1 +{ +font-weight:bold; +} +.pagedTableDefault .cellSelected2 +{ +font-weight:bold; +} +.pagedTableDefault .pagedTable a +{ + color:#FFF; +} +.pagedTableDefault .pagedTable a:hover +{ + color:orange; +} +.pagedTableDefault .pagedTable .pagedTableHeader +{ + border-bottom:0px solid #DFDFDF; + background-color:#E0E9EF; + background-color:#6F7F75; + color:#5B5B5B; + font-weight:bold; + background-image:url(/js/maborak/core/images/silverBackgroundTableTitle.jpg); + background-repeat:repeat-x; + height:26px; + padding:0px; + overflow:hidden; +} +.pagedTableDefault .pagedTable .pagedTableHeader a +{ + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; +} +.pagedTableDefault .pagedTable .pagedTableHeader a:hover +{ + color:orange; +} + + + /* Grid BEGIN */ +div.pattern .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +div.pattern .FormTitle +{ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} + + +div.grid +{ + font:normal 11px sans-serif,MiscFixed; + padding-left:10px; + padding-right:10px; + margin-top:7px; +} + +div.grid .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + width: 100%; +} + +html>body div.grid .content +{ + width: auto; +} + +div.grid .tableGrid +{ + width:100%; +} + +/* Grid End */ +/* XmlForm END */ + +.tableGrid_view +{ + width: 100%; + border-top: 0px solid #DADADA; + border-bottom: 0px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + +table.tableGrid_view td +{ + border-top: 1px solid #DADADA; + border-bottom: 1px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + diff --git a/workflow/public_html/skins/green/style.css b/workflow/public_html/skins/green/style.css new file mode 100644 index 000000000..5ef179aa5 --- /dev/null +++ b/workflow/public_html/skins/green/style.css @@ -0,0 +1,3018 @@ +body +{ + margin :0px; + background-color:#ECECEC; + color :#808080; + font :normal 8pt sans-serif,Tahoma,MiscFixed; +} + +a, img { + padding: 0; + margin: 0; +} + +img { + border: 0 none; +} + +.Footer +{ + font :normal 8pt sans-serif,Tahoma,MiscFixed; + color :#000; + height :150px; + text-align :center; +} +.Footer .image +{ + /*background-image: url(/skins/green/images/bf.jpg); + background-repeat: repeat-x; + height:10px;*/ + +} +.Footer .content +{ + color :black; + padding :10px; +} +.Footer .content a +{ + color :#006699; + text-decoration :none; +} +.Footer .content a:hover +{ + color :orange; +} +.logout a +{ + font:bold 8pt Tahoma,sans-serif,MiscFixed; + color:#006699; + text-decoration:none; +} +.logout a:hover +{ + color:orange; +} +.temporalMessageERROR +{ + -moz-border-radius:6px; /* Rounded edges in Firefox */ + background-image: url(/skins/green/images/error.gif); + color :#ffffff; + border-style:solid; + border-width:1px; + border-color:#ffffff; + font :normal 8pt Tahoma,sans-serif,MiscFixed; + text-decoration:none; + height:25px; + padding:0 20px; + vertical-align:middle; + font-weight: bold; +} +.temporalMessageWARNING +{ + -moz-border-radius:6px; /* Rounded edges in Firefox */ + background-image: url(/skins/green/images/warning.png); + color :#555555; + border-style:solid; + border-width:1px; + border-color:#ffffff; + font :normal 8pt Tahoma,sans-serif,MiscFixed; + text-decoration:none; + height:25px; + padding:0 20px; + vertical-align:middle; + font-weight: bold; +} +.temporalMessageINFO +{ + -moz-border-radius:6px; /* Rounded edges in Firefox */ + background-image: url(/skins/green/images/message.png); + color :#000000; + border-style:solid; + border-width:1px; + border-color:#ffffff; + font :normal 8pt Tahoma,sans-serif,MiscFixed; + text-decoration:none; + height:25px; + padding:0 20px; + vertical-align:middle; + font-weight: bold; +} + +.userGroupTitle +{ + color :black; + font :bold 8pt Tahoma,sans-serif,MiscFixed; + padding-left:10px; +} +.userGroupLink +{ + padding:0px; + padding-left:10px; + padding-bottom:10px; +} +.userGroupLink a +{ + color :#006699; + text-decoration:none; + font :bold 8pt Tahoma,sans-serif,MiscFixed; +} +.userGroupLink a:hover +{ + color :orange; +} +span.treePlusLink +{ + background-color:#E68B2C; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.treePlusLink:hover +{ + :#EFC395; +} +span.XtreeMinus +{ + background-color:#006699; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.XtreeMinus:hover +{ + background-color:#EFC395; +} + +/* leimnud.app.menuRight CSS begin */ + +/* Processmaker CSS begin */ +.pm_separator___processmaker +{ + +} +.pm_separatorOn___processmaker +{ + +} +.pm_separatorOff___processmaker,.pm_separatorOn___processmaker +{ + height: 7px; + cursor:pointer; + text-align:center; + overflow:hidden; +} +.pm_separatorDOff___processmaker,.pm_separatorDOn___processmaker, .pm_separatorOver___processmaker, .pm_separatorOut___processmaker +{ + height:7px; + width:100%; + background-color:#C1D2EE; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + border-width:1px 0pt; + overflow:hidden; +} +.pm_separatorDOff___processmaker +{ + background:url(/js/maborak/core/images/separator.up.gif); + background-repeat:no-repeat; + background-position:50% 2; + +} +.pm_separatorDOn___processmaker +{ + background:url(/js/maborak/core/images/separator.down.gif); + background-repeat:no-repeat; + background-position:50% 50%; +} +.pm_separatorOver___processmaker +{ + background-color:#C1D2EE; +} +.pm_separatorOut___processmaker +{ + background-color:buttonface; +} + +/* Processmaker CSS end */ +/* processmap Theme.Task begin */ +/*theme firefox begin*/ +.processmap_task___firefox +{ + position : absolute; + height : 30px; + width : 150px; + background-color: #006699; + border : 1px solid #006699; + z-index : 10; + overflow : hidden; + cursor : move; +} +.processmap_task_label___firefox +{ + color:white; + text-align:center; + cursor:text; + padding-top:11; +} +.processmap_text___firefox +{ + position : absolute; + cursor : move; + background-color:red; +} +.processmap_title___firefox +{ + +} + /*theme firefox end*/ + + /*theme processmap begin*/ +.processmap_task___processmaker +{ + position : absolute; + height : 40px; + height : 38px; + width : 171px; + width : 164px; + z-index : 10; + overflow : hidden; + cursor : move; + /*background : url(/js/processmap/core/images/bg_task.gif); + background : url(/images/fondotask.png);*/ + //background-color:#006699; + //background-color:#6F6F6F; + background : url(/images/borderTask.gif); + background-color:#0576C4; + background-color:#006699; + vertical-align:middle; + display:table-cell; +} +.processmap_task_label___processmaker +{ + color:#FFF; + text-align:center; + /*position:absolute;*/ + margin:10; + vertical-align:middle; + cursor:move; +} +.processmap_text___processmaker +{ + position : absolute; + z-index : 10; + cursor : move; + font : bold 8pt Tahoma,MiscFixed; +} +.processmap_title___processmaker +{ + position :absolute; + cursor :move; + font :bold 13pt Tahoma,MiscFixed; +} + /*theme processmap end*/ + +.pm__toolbar{ + align:left; + font-size:1; + line-height:31px; +} + +.processmap_toolbarItem___processmaker +{ + margin:0px; + border:1px solid #CEC6B5; + background:#EFEFEF url(/images/dynamicForm/toolbar.buttonbg.gif) repeat-x scroll 0%; +} +.processmap_toolbarItem___processmaker:hover +{ + margin:0px; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + /*border-width:1px 0pt;*/ + border:1px solid #316AC5; + background:#C1D2EE; + background-color: #C1D2EE; + + +} +/* processmap Theme.Task end */ + +/* processmap Theme.Panels begin */ +/* processmap Theme.Panels end */ + + +/* Theme leimnud.module.grid BEGIN */ + +/* Theme leimnud.module.grid END */ + + +/* Menues */ + +TD.mainMenuBG { + background-image: url(/skins/green/images/bm.jpg); + background-repeat: repeat-x; + height: 25px; + left: 46px; + top: 72px; + direction: ltr; + text-align: left; +} + +TD.mainMenu { + background-image: url(/skins/green/images/bm.jpg); + background-repeat: repeat-x; + height: 25px; + left: 46px; + top: 72px; + direction: ltr; + text-align: center; +} + +A.mainMenu { + font-family: Tahoma; + font-size: 11px; + color: #FFFFFF; + font-weight: bold; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} +A.mainMenu:hover { + color: #D3D3D3; + font-weight: bold; + text-decoration: none; +} + +TD.SelectedMenu{ + background-image: url(/skins/green/images/bsms.jpg); + background-repeat: repeat-x; + top: 72px; + height: 26px; +} +A.SelectedMenu { + vertical-align: middle; + font-size: 11px; + font-weight: bold; + color: #000; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} + +.SelectedMenu:hover { + vertical-align: middle; + font-size: 11px; + font-weight: bold; + color: #005791; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; +} + + +TD.subMenu { + background-image: url('/skins/green/images/bsm.jpg'); + background-repeat: repeat-x; + height: 25px; +} + +A.subMenu { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +A.subMenu:hover { + font-family: Tahoma; + font-size: 10px; + color: #092148; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +TD.selectedSubMenu { + background-image: url('/js/maborak/core/images/silverBackgroundSubMenu.jpg'); + background-repeat: repeat-x; + height: 26px; + left: 46px; + top: 98px; +} + +A.selectedSubMenu { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + +A.selectedSubMenu:hover { + font-family: Tahoma; + font-size: 10px; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; +} + + +/* Menues END */ + +/* Box Top Model BEGIN */ +.boxTop, .boxTopBlue +{ + height:9px; + padding-left:8px; + padding-right:8px; + position:relative; + overflow:hidden; +} +.boxTop div, .boxTopBlue div +{ + background-color:#FFF; +} +.boxTop div.a, .boxTop div.c, .boxTopBlue div.a, .boxTopBlue div.c +{ + position:absolute; + width:9px; + height:9px; +} +.boxTop div.a, .boxTopBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftl.png); + background-color:transparent; +} +.boxTop div.c, .boxTopBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftr.png); + background-color:transparent; +} +.boxTop div.b, .boxTopBlue div.b +{ + width:100%; + height:9px; + border-top:1px solid #DADADA; + background-color:#FFF; +} +/* Box Top Model END */ + +/* Box Top Model Blue BEGIN */ +.boxTopBlue div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); + background-color:transparent; +} +.boxTopBlue div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); + background-color:transparent; +} +.boxTopBlue div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} + +/* Box Top Model Blue END */ + +/* Box Bottom Model BEGIN */ +.boxBottom, .boxBottomBlue +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxBottom div.a, .boxBottom div.c, .boxBottomBlue div.a, .boxBottomBlue div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxBottom div.a, .boxBottomBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/fbl.png); + background-color:transparent; +} +.boxBottom div.c, .boxBottomBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/fbr.png); + background-color:transparent; +} +.boxBottom div.b, .boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.png) repeat-x; +} +/* Box Bottom Model END */ +/* Box Bottom Model Blue BEGIN */ +.boxBottomBlue div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); + background-color:transparent; +} +.boxBottomBlue div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); + background-color:transparent; +} +.boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.blue.png) repeat-x; +} +.boxContentBlue +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + padding-right:5px; + padding-left:5px; + background-color:#D0DEF0; +} +a.linkInBlue +{ + font:normal 8pt Tahoma,MiscFixed; + color:#006699; + text-decoration:none; +} + +a.linkInBlue:hover +{ + color:orange; +} +/* Box Bottom Model Blue END */ + +/* BoxPanel Bottom Model BEGIN */ +.boxTopPanel +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxTopPanel div.a, .boxTopPanel div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxTopPanel div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftlL.png); + background-color:transparent; +} +.boxTopPanel div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftrL.png); + background-color:transparent; +} +.boxTopPanel div.b +{ + width:100%; + height:16px; + background: transparent url(/skins/green/images/ftc.png) repeat-x; +} + +/* BoxPanel Bottom Model END */ + + + +/* XmlForm BEGIN */ + /* form BEGIN */ +form{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form table{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form.formDefault select +{ + font:normal 11px sans-serif,MiscFixed; + color:#000; +} +form.formDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; + line-height:180%; +} +form.formDefault td +{ + padding:2px; +} +form.formDefault .content +{ + background-color:#FFF; + border-left:1px solid #dadada; + border-right:1px solid #dadada; +} +form.formDefault input.FormField +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; +} +form.formDefault input.FormFieldInvalid +{ + border: 1px solid red; +} +form.formDefault input.FormFieldValid +{ + border: 1px solid green; +} +form.formDefault .FormLabel +{ + color:#808080; + text-align:right; + padding-right:5px; + /* width:180; */ +} +form.formDefault .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; +} +form.formDefault textarea.FormTextArea +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + overflow:auto; +} +form.formDefault textarea.FormTextPM +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 12 Courier New, monospace ; + overflow:auto; +} +form.formDefault .FormTitle +{ + color:#000; + padding-left:5px; + font-weight:bold; + background-color:#E0EFE6; +} +form.formDefault .FormSubTitle +{ + background-color:#D1DEDF; + color:black; +} +form.formDefault .FormButton +{ + text-align:center; +} + +form.formDefault a +{ + text-decoration:none; + color:#006699; + cursor:pointer; +} +form.formDefault a:hover +{ + color:orange; + cursor:pointer; +} +form.formDefault td.withoutLabel, form.formDefault td.withoutLabel table td +{ + padding:0px; + height:8px; +} + + /* form END */ + /* formSearch BEGIN */ +form.formSearch input, input +{ + font-size:8pt; +} +form.formSearch a +{ + color:#006699; + text-decoration:none; +} +form.formSearch a:hover +{ + color:orange; +} +form.formSearch +{ + padding-top:5px; + padding-bottom:5px; +/* width:100%;*/ + padding-left:10px; + padding-right:10px; +/* padding-left:10%; + padding-right:10%;*/ +} +form.formSearch .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; + padding:10px; +} +form.formSearch input.FormField +{ + border: 1px solid #99BBE8; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + width:200px; +} +form.formSearch .FormLabel +{ + color:#000; + text-align:center; + padding-right:10px; + width:40%; +} +form.formSearch .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; + width:60%; +} + +form.formSearch .Record +{ + width:80%; +} + /* formSearch END */ + + + /* pagedTable BEGIN */ +.pagedTableDefault +{ + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + padding-left:5px; + padding-right:5px; +} + +.pagedTableDefault .subtitle +{ + font-weight: bold; + color: #000; + font-size: 13px; + padding-left: 10px; +} +.pagedTableDefault, .pagedTableDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a +{ + color:#2078A8; + text-decoration:none; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a:hover +{ + color:orange; +} +.pagedTableDefault td +{ + padding:0px; +} +.pagedTableDefault .pagedTable td +{ + padding:5px; +} +.pagedTableDefault .pagedTable +{ + border:1px solid #DFDFDF; + border-collapse:collapse; + color:#27373F; +} +.pagedTable td{ + text-align:left; +} +.pagedTableDefault .pagedTable .Row1 +{ + background-color:#FFF; +} +.pagedTableDefault .pagedTable .Row2 +{ + background-color:#EEE; +} +tr.Selected +{ + background-color:#D8DDFF; +} +.pagedTableDefault .pagedTable .RowPointer +{ + background-color:#E0EAEF; +} +.pagedTableDefault .cellSelected1 +{ +font-weight:bold; +} +.pagedTableDefault .cellSelected2 +{ +font-weight:bold; +} +.pagedTableDefault .pagedTable a +{ + color:#FFF; +} +.pagedTableDefault .pagedTable a:hover +{ + color:orange; +} +.pagedTableDefault .pagedTable .pagedTableHeader +{ + border-bottom:0px solid #DFDFDF; + background-color:#E0E9EF; + background-color:#6F7F75; + color:#5B5B5B; + font-weight:bold; + background-image:url(/js/maborak/core/images/silverBackgroundTableTitle.jpg); + background-repeat:repeat-x; + height:26px; + padding:0px; + overflow:hidden; +} +.pagedTableDefault .pagedTable .pagedTableHeader a +{ + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; +} +.pagedTableDefault .pagedTable .pagedTableHeader a:hover +{ + color:orange; +} + +/*Adicion Rube*/ + +.pagedTableDefault .pagedTable .masterDetailMain +{ + background-image:url(/images/masterDetailMain.png); + background-repeat: repeat-x; + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; + font-weight: bold; +} + +.pagedTableDefault .pagedTable .masterDetailOther +{ + background-image:url(/images/masterDetailOther.png); + background-repeat: repeat-x; + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; + font-weight: bold; +} + +/*Fin Adicion Rube*/ +.pagedTableDefault .pagedTable .RowLink +{ + background-color:#6F7F75; + text-align :center; +} +A.firstPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noFirstPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.previousPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noPreviousPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.nextPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noNextPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.lastPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} +A.noLastPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} + + /* pagedTable END */ + /* Grid BEGIN */ +div.pattern .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +div.pattern .FormTitle +{ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} + + +div.grid +{ + font:normal 11px sans-serif,MiscFixed; + padding-left:10px; + padding-right:10px; + margin-top:7px; +} + +div.grid .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + width: 100%; +} + +html>body div.grid .content +{ + width: auto; +} + +div.grid .tableGrid +{ + width:100%; +} + +div.grid .tableGrid .vFormTitle +{ +/* color:#006699;*/ +} + /* Grid END */ + /* Tree BEGIN */ + +div.treeBase .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +.treeNode +{ + padding-bottom:10px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:#808080; +} +div.treeBase table td.a +{ + width:16px; + height:10px; +} +div.treeBase table td.b +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; + text-align:left; +} +/* TreeParent BEGIN */ +div.treeParent +{ + +} +div.treeParent table +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; +} + +div.treeParent .treeMinus +{ + width:16px; + height:22px; + display:block; + position:relative; + background-image:url(/images/minus.gif); + background-repeat:no-repeat; + overflow:hidden; +} +div.treeParent .treePlus +{ + width:16px; + height:22px; + background-image:url(/images/plus.gif); + background-repeat:no-repeat; + display:block; +} +div.treeParent .treePointer +{ + width:1px; + height:22px; + display:block; +} +div.treeParent td.c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +div.treeParent td.d +{ + background-image:url(/images/ftv2node.gif); + background-repeat:repeat-y; +} +div.treeParent .treeNode +{ + padding:2px; + padding-bottom:1px; + font-weight:bold; +} + + + +div.treeParent .treeNode a, div.treeBase .treeNode a +{ + color:#006699; + font-weight:normal; + text-decoration:none; +} +div.treeParent .treeNode a:hover, div.treeBase .treeNode a:hover +{ + color:orange; +} +div.treeParent .FormField +{ + background-color:#FFF; + padding-bottom:10px; +} +div.treeParent .FormField a +{ + font-size:8pt !important; + color:red; +} +div.treeParent .FormTitle +{ +/* font:bold 8pt sans-serif,Tahoma,MiscFixed; + font:normal 11px sans-serif,MiscFixed;*/ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} +/* TreeParent END */ + +/* TreeChild BEGIN */ +div.treeChild td.b +{ + padding-right:10px; +} +div.treeChild td.a +{ + width:10px; + height:22px; + background:none; +} +div.treeChild .c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +/* TreeChild END */ + + +div.treeChild +{ + padding-left:1px; +} +div.treeParent .content .treeNode a.selected +{ + color:white; + background-color:#006699; +} + +/*div.treeParent div.treeParent .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); +} +div.treeParent div.treeParent .boxTop div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); +} +div.treeParent div.treeParent .boxBottom div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); +} +div.treeParent div.treeParent .boxBottom div.b +{ + background-image:url(/skins/green/images/fbc.blue.png); +} +div.treeParent div.treeParent .boxBottom div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); +}*/ + + + + +div.treeParent table +{ + +} +div.treeParent .subcontent +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} + /* Tree END */ +/* XmlForm END */ + + +/**************************** Start -> JSCalendar Widget by Erik Amaru Ortiz *********************************/ + +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #6F7F75; + font-size: 11px; + color: #000; + cursor: default; + background: #F0F2F0; + font-family: tahoma,verdana,sans-serif; + z-index:1000; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #6F7F75 url(menuarrow2.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #000; + color: #fff; + padding: 2px; +} + +.calendar thead tr { /* Row
    containing navigation buttons */ + background: #6F7F75; /*e*/ + color: #fff; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #E9F2E9; +} + +.calendar thead .name { /* Cells in footer (only one right now) */ + text-align: center; + background: #206A9B; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell }dEzPReN7__R~XE~+BsM#6xTgzm_LOhP{l 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/fbr.blue.png b/workflow/public_html/skins/iphone/images/fbr.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..2dcc39d873686539fa55544acfed3fd7e24e0daa GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDVAa<&kznEsNqQI0P;BtJR*x3 z7`Q%wFr(8NlNmrki4xa{lHmNblJdl&R0hYC{G?O`x6Go{^8BLgV*kzZen4{sL24p= zeXNr6bM+EIO7tpn3m9zdD+&^mvr|hHl2X$%^K6wA6cm&cGE;1o!cBb*d<&dYGcrA@ zic*8C{6dnevXd=Slkzt6Dft8V=m8nq_l75IHH0{3mDVb@N*t8p285%&fBPoJvx6ua$1X93& zLmlKNG;u-!mXZt)uY%H|9B{OxBzopr0Kye literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/fbr.png b/workflow/public_html/skins/iphone/images/fbr.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3256ca010ea00408763140f2bee4b8ad0c5e1b GIT binary patch literal 41152 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/frame.home.bottom.png b/workflow/public_html/skins/iphone/images/frame.home.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d83a05a7ffc38b124ea9b629bb395a1e3cf1989c GIT binary patch literal 557 zcmV+|0@D47P)>Lcv1_3NGBV7f5o0xU8X0 zoi?U%nyA?&_5XumUIvrJEZ)acxUMT(t(E}*KpM~U3^NQvkE;LxWKlU`20<|6DgXdk zR8CYHjmCSs-R|4A&5Zy6^q?@t^P3QJCe~dgp|?{J6dR%N0vzJ zdf)&6iYIRR(Y}q=zW&tCx5?it)=y5v9}tO;ZWHzX*-V6k9xwoa;)aEx^>nEPhTij& z@BK^`-^Figh@8tHFaV(NL6H^~S>X}CC!>(i8@x!_vnC0G0szVz7+K-*Cnydki}>Jh z!Z>FqEC8TfVR3SoS~z4id6BaQ0F*a44r)CpQYVXyDI-s~004>`5Si!lNFbck%{F001SMH1hQSF98Ms>^8=?^qOH000000NkvXXu0mjflF0E1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/frame.right.bottom.png b/workflow/public_html/skins/iphone/images/frame.right.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..64b06aa2b852511bc8337b4fcfcd0afc46908475 GIT binary patch literal 43095 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 HZ{Po4tZ$}k literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/frame.right.top.gif b/workflow/public_html/skins/iphone/images/frame.right.top.gif new file mode 100644 index 0000000000000000000000000000000000000000..00c9fc88a8df92cd8570414f46e0b945d645abcf GIT binary patch literal 197 zcmV;$06PCiNk%w1VMGE60HOu}|NsBr-`~v4%-Y)8_xJbV;o$%P00000A^8LW000I6 zEC2ui07L=_000AuXsR;tFv>}*y*TU5yZ>M)j$~<`XsWJk>q>*L%!WV!c&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-@?f^1g6dcWYXcuX#v&*-$eS6B$v@VI{XE)7O>#IuElTi%$HnB^3+|jK4fx977}|8Q(Js{9^1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z76M_$OLy!300kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!ywE43U_c{OA9FduE9hr1aOgeV# z*o`X&1_vc}h!}vt9LwTo_KF8uqOHYVvrSZDuwvH>cp}_A9cToDr>mdKI;Vst0OX54 AZ~y=R literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/ftlL.png b/workflow/public_html/skins/iphone/images/ftlL.png new file mode 100644 index 0000000000000000000000000000000000000000..14b43f8c749408a9c048000cf6b4a34d885f3f47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#IuElDyYcUtF5*C;b)GJcAr`0iPT0tM$UwmLzkQ-+ zuQpo(TSNov9%kVUj;~De5}4UGsZNpI(`@hE>#W-Z z*4_KPx%gc}uL48n?XvknyZRrmh;H7VAknrwjEOgTe~DWM4fHw1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z`T)X=PHRkN00kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!6M843U_cY*YN~Og)>{XE)7O>#IuElThZXzmI8_D))^DCJjv*F;jIUWmelY@-fG|bi zKM>$E0Av9(J_SHId52@3&B(4~z&w3}gvAx+!RUWP?CbFg`XKCdPnl z5y%&Wf(zMT7#n05%s^x|NFD_KGXeq3B9JBcf(vF4SSLs`9{dlg2&4uSLU4-+SpwCE z;cA#=AcH{|<`@tSE`SZaoTeeKDs;W8)6KiT}gnm|0JsKD_|92qs7i`s~@W6F|O!Co>?2>fqmdKI;Vst0Lvns AXaE2J literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/iPhoneArrow.png b/workflow/public_html/skins/iphone/images/iPhoneArrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1e58c8a0dccb6399bcccc0b3b26ce9a85d8108 GIT binary patch literal 272 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 + + + + \ No newline at end of file diff --git a/workflow/public_html/skins/rtl/images/bar_bg_bw.gif b/workflow/public_html/skins/rtl/images/bar_bg_bw.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0e0b054f2152cd9f37f7ee09bd2475a9014a9e2 GIT binary patch literal 809 zcmZ?wbhEHbWMq(M_|Cxa;>C-tTetrC^XJKvCr_U~Wf%pcAuy6cKnLVmP+nl*;A3Fs SU{F}F;9xU{uoe#ogEat7Zxf3E literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/bf.jpg b/workflow/public_html/skins/rtl/images/bf.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c41bdf1e943c35c38f22de233cb86e599e0da188 GIT binary patch literal 318 zcmex=i3*BJ!6k`h{6D}T z$icwHz{AWa$iO7X$SlbC{|JK^*r^Q2fQ=m}E++t#;6xT?U}9!v6A}vyopK2%FT%)( zA_?SxLi3*BJ!6k`h{6D}T z$iX1Rz{1QZ$iO7X$SlbC{|JL9(5Vb4fQ=m}tRTR^$i&KuEWs+u$jm03Bo-Vx|&a$Ql_KgarTJV&DNPXA)!H=;Uucj#j?8>hBzQ U?ZWp;x_|Ke8)@gd=J@}c0J{A$$^ZZW literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/bsm.jpg b/workflow/public_html/skins/rtl/images/bsm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee151c40f7ef7a2ee6d7ed21c31460aeb68c7202 GIT binary patch literal 292 zcma)$OA5j;6h&{$*EF?>X{EFs6vy3zf>6*+>Czmy2tNbeNlYCSKNAl;c$^3K-Ea;M z*j>NvK_VULfN;YGf-%OK;9N{aoJ0ws5~FpZwXx=fHM7iSGvj@pd*9S`-LxY^2$52z zCM~TktHKr4c>H$>M>vHFoDzqLBh-;_!eXe3cNmq?7xqg7^QiM5i^00jh!_{HFqFhU P)M15ts}4)D-iON*g`gze literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/bsms.jpg b/workflow/public_html/skins/rtl/images/bsms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e58d448cad27c0c3e5071cc65818abd57b45304d GIT binary patch literal 323 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{Jcb$iO7X$SlbC{|JK^$f*p-fSHjUC@wDml;A{>VP<4y7Zef?3Y&5fq!Hvr zWPJ<_j7&grNkK-S6(|ynOoGCJ|8FtyFaxConFSf_8E)sk(Yq$Q=jD%>(^9KXc&?o6 LadQP@!~dHAw0|+h literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/dark-pointer.gif b/workflow/public_html/skins/rtl/images/dark-pointer.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff504f304cdcbf71ed547e735a8ae1b2de6bf252 GIT binary patch literal 49 zcmZ?wbhEHbWM^PuXkcW}(9rn*|G(l-7DfgJMg|=QAOOiQFmbf-H%eylMrtrv0{{nn B32OiV literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/fbc.blue.png b/workflow/public_html/skins/rtl/images/fbc.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..9a503c9d1cf820e20fc93f62063b1aa55f9019c0 GIT binary patch literal 1242 zcmcIk&ubGw7~O)DbfMH9#8eLs>(%V+kJylPlhP)wjU=%)0iy@$WOtIT$?hz(Q?f0B zQhLyfh#-g;dn<@|>9x>+e}#9?TD*F3Hc6ATh@Lv^{Q7wBec!wp_SIVX?zDJK6a-8)fjKjV)jeEpYm591%e=+M15lEbMie8#@TX>RY-$% z5XHixP3jn|I23mXZ3XuaZOG?Sl;Z0|ChvLdkxoYjSth6mHWJNPHIN8MvfzWMxfe~h;o~FUqQ5Z^~2Vt#@ z)UT&jS_3&kF-Xd4!cz1kNY2YzN=v8aZ-EM8;2!dTmI9ih@If>56#sZJy(VQvKAY5T z80-0!K~BEQNSloL285kXNABn{p-rf!(`l$^P}33|kqEXuhQfpw-0X{->f~`?QO9Qv z@j#@D>ST*$Bq>TXY=grgf0)P%2Ig@aVTgRF$_gARbE3(EMvh{{2(1#*&YrstkgMos z#5@BUWgYQx9x+kc~{3{4%-$3O$R2_qxM zjOn=^o#|Zse}>uC&@X?BwtLrNTM)Ogi#--_&(yP?*_P2D)I}`oxTuMt?=?+03jVXc ze%1V0@Mj5!@A9WPUzX+bNg?@D}pe4Rdk*l!>3$EC@h!r JUzRp@{{ShsJqZ8+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/fbc.png b/workflow/public_html/skins/rtl/images/fbc.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff292f0f2313d582b0c1c35416a732e2d110d9a GIT binary patch literal 40655 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 A>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/fbl.blue.png b/workflow/public_html/skins/rtl/images/fbl.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd9228cd668f78f5de6356f5afe8720f0d84ce0 GIT binary patch literal 1343 zcmcIkO=uHA7+r0RX=p7~DOM224OWG0Hrb>}vm_~P(%Ptrr3n~&%4B!ahGc)(otkZ_ zh+08w6+I|Y1bYz_#7i&gMT)JU2eCKBv*1zjphcn1CTaSE=&8f({CvFkzHiJ(-BYJS^#o_Oz( z;6B`&#z`fIOHe~px2R+h=*w%Uq-X{G^xVM&(P=R;>G&yLP$VZbAx=Y5sbH6(LZN^# z$fDuA9HIdLG{}n~`bvi45=vVyb+?y znmk#XVU`AE2rh)^NTxoPaXm{D5=0$iVR) zKk1~Ha-+jGG6yv=#}7vPsyWFnM2}#s@+?~_m7FDyQ_+T5cOVd8T^!4C3_&pZn2e#p z$hy5EvZ@nBx}fD%oL6LE>cXrtibFJQCaSgS;hffPRo3lvu{C8v43Z!p z(GbLnmQs{rc++)&NYWEDnHxZBS=aa|3NZ?selTt~!?{zOiznUf8(PP&fHu+NikQ!h z{hi+7tC_ zr#f#4_n-e-yr839mZ9zKGc)1ej#%kVCOr0Ir^LWaCSy#fQ&xt_=E%Aee|g_rH+J*Q zgXQVB;$-@f++g4P>Z7Oh@@J%QGUMITI@1sf`OZIMmRDA~>g;yA@A@rf{>svU=})^Y z7Ry8{tUoq$abdasU3Yr22wp6HXnb90nL6C*pcmS$F2_7{XE)7O>#1}l>|kK)RwGxq_7qC8z3Lo7}wCrIcueEbgtp4X0? zIN{M%rB?ML<;o<%EY8!Hm-}bV_m_~6__5GLd6I;&wpW9;i?HAA%22WQ%mvv4FO#r~!M+*P| literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/fbr.blue.png b/workflow/public_html/skins/rtl/images/fbr.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..2dcc39d873686539fa55544acfed3fd7e24e0daa GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDVAa<&kznEsNqQI0P;BtJR*x3 z7`Q%wFr(8NlNmrki4xa{lHmNblJdl&R0hYC{G?O`x6Go{^8BLgV*kzZen4{sL24p= zeXNr6bM+EIO7tpn3m9zdD+&^mvr|hHl2X$%^K6wA6cm&cGE;1o!cBb*d<&dYGcrA@ zic*8C{6dnevXd=Slkzt6Dft8V=m8nq_l75IHH0{3mDVb@N*t8p285%&fBPoJvx6ua$1X93& zLmlKNG;u-!mXZt)uY%H|9B{OxBzopr0Kye literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/fbr.png b/workflow/public_html/skins/rtl/images/fbr.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3256ca010ea00408763140f2bee4b8ad0c5e1b GIT binary patch literal 41152 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/frame.home.bottom.png b/workflow/public_html/skins/rtl/images/frame.home.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d83a05a7ffc38b124ea9b629bb395a1e3cf1989c GIT binary patch literal 557 zcmV+|0@D47P)>Lcv1_3NGBV7f5o0xU8X0 zoi?U%nyA?&_5XumUIvrJEZ)acxUMT(t(E}*KpM~U3^NQvkE;LxWKlU`20<|6DgXdk zR8CYHjmCSs-R|4A&5Zy6^q?@t^P3QJCe~dgp|?{J6dR%N0vzJ zdf)&6iYIRR(Y}q=zW&tCx5?it)=y5v9}tO;ZWHzX*-V6k9xwoa;)aEx^>nEPhTij& z@BK^`-^Figh@8tHFaV(NL6H^~S>X}CC!>(i8@x!_vnC0G0szVz7+K-*Cnydki}>Jh z!Z>FqEC8TfVR3SoS~z4id6BaQ0F*a44r)CpQYVXyDI-s~004>`5Si!lNFbck%{F001SMH1hQSF98Ms>^8=?^qOH000000NkvXXu0mjflF0E1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/frame.right.bottom.png b/workflow/public_html/skins/rtl/images/frame.right.bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..64b06aa2b852511bc8337b4fcfcd0afc46908475 GIT binary patch literal 43095 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 HZ{Po4tZ$}k literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/frame.right.top.gif b/workflow/public_html/skins/rtl/images/frame.right.top.gif new file mode 100644 index 0000000000000000000000000000000000000000..00c9fc88a8df92cd8570414f46e0b945d645abcf GIT binary patch literal 197 zcmV;$06PCiNk%w1VMGE60HOu}|NsBr-`~v4%-Y)8_xJbV;o$%P00000A^8LW000I6 zEC2ui07L=_000AuXsR;tFv>}*y*TU5yZ>M)j$~<`XsWJk>q>*L%!WV!c&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-@?f^1g6dcWYXcuX#v&*-$eS6B$v@VI{XE)7O>#IuElTi%$HnB^3+|jK4fx977}|8Q(Js{9^1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z76M_$OLy!300kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!ywE43U_c{OA9FduE9hr1aOgeV# z*o`X&1_vc}h!}vt9LwTo_KF8uqOHYVvrSZDuwvH>cp}_A9cToDr>mdKI;Vst0OX54 AZ~y=R literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/ftlL.png b/workflow/public_html/skins/rtl/images/ftlL.png new file mode 100644 index 0000000000000000000000000000000000000000..14b43f8c749408a9c048000cf6b4a34d885f3f47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMQ!3HD+(^8%SDYhhUcNd2LAh=-f^2tCE&H|6f zVg?4T4{XE)7O>#IuElDyYcUtF5*C;b)GJcAr`0iPT0tM$UwmLzkQ-+ zuQpo(TSNov9%kVUj;~De5}4UGsZNpI(`@hE>#W-Z z*4_KPx%gc}uL48n?XvknyZRrmh;H7VAknrwjEOgTe~DWM4fHw1|%O$WD@{VEX7WqAsj$Z!;#Vfk}U9uEM{Qf z`T)X=PHRkN00kvVTq8a>QWe}Xi&D$;i?WOTH_Q70)rf)AI2WZR zmSpDVDTHL^rZN~B>KhsA8<=ZI_`U(EF!6M843U_cY*YN~Og)>{XE)7O>#IuElThZXzmI8_D))^DCJjv*F;jIUWmelY@-fG|bi zKM>$E0Av9(J_SHId52@3&B(4~z&w3}gvAx+!RUWP?CbFg`XKCdPnl z5y%&Wf(zMT7#n05%s^x|NFD_KGXeq3B9JBcf(vF4SSLs`9{dlg2&4uSLU4-+SpwCE z;cA#=AcH{|<`@tSE`SZaoTeeKDs;W8)6KiT}gnm|0JsKD_|92qs7i`s~@W6F|O!Co>?2>fqmdKI;Vst0Lvns AXaE2J literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/images/input_back.gif b/workflow/public_html/skins/rtl/images/input_back.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9d4a35491a4383c6a7aa91cf2064308ee254a4f GIT binary patch literal 44 tcmZ?wbhEHbWM*JyXkcLY|NsAo4<8hNvM_*v4u}BBFfcLq@JBLO0{|Yv3V;9r literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/rtl/style.css b/workflow/public_html/skins/rtl/style.css new file mode 100644 index 000000000..ee5c985ef --- /dev/null +++ b/workflow/public_html/skins/rtl/style.css @@ -0,0 +1,2391 @@ +body +{ + margin :0px; + background-color:#ECECEC; + color :#808080; + font-family :normal 8pt Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + direction : rtl; + font-size : small; +} + +body .panel_content___processmaker { + position: relative; + color: black; + font: normal 8pt Tahoma,MiscFixed; + text-align: justify; + border: 1px solid #A3A2BC; + border: 1px solid #FF9900; + border: 1px solid #919B9C; + direction: rtl; + /*border-left:1px solid #1983BD; + border-top:1px solid #1983BD; + border-right:1px solid #59A5D9; + border-bottom:1px solid #59A5D9;*/ + background-color: #E8F2F7; + background-color: #FFFFFF; + background-color: #F9F9F9; + background-color: #FFF; + overflow: auto; + padding:0px; +} + +body .panel_frontend___processmaker{ + /*width: 100%;*/ + height: 100%; + position: absolute; + background-color: #E8F2F7; + background-color: #E0DFE3; + /*background-color:#59A5D9;*/ + direction: ltr; + overflow: hidden; + z-index: 2; + top: 0px; + left: 0px; +} + +.Footer +{ + font-family :normal 8pt Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + color :#000; + height :150px; + text-align :center; +} +.Footer .image +{ + /*background-image: url(/skins/green/images/bf.jpg); + background-repeat: repeat-x; + height:10px;*/ + +} +.Footer .content +{ + color :black; + padding :10px; +} +.Footer .content a +{ + color :#006699; + text-decoration :none; +} +.Footer .content a:hover +{ + color :orange; +} +.logout a +{ + font-family :normal 8pt Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + color:#006699; + text-decoration:none; +} +.logout a:hover +{ + color:orange; +} +.temporalMessage +{ + color :red; + font-family :normal 8pt Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + text-decoration:none; + direction : rtl; +} +.userGroupTitle +{ + color :black; + font-family :normal 8pt Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + padding-left:10px; + direction : rtl; +} +.userGroupLink +{ + padding:0px; + padding-left:10px; + padding-bottom:10px; + direction : rtl; +} +.userGroupLink a +{ + color :#006699; + text-decoration:none; + font :bold 8pt Tahoma,sans-serif,MiscFixed; + direction : rtl; +} +.userGroupLink a:hover +{ + color :orange; +} +span.treePlusLink +{ + background-color:#E68B2C; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.treePlusLink:hover +{ + :#EFC395; +} +span.XtreeMinus +{ + background-color:#006699; + color:white; + font:normal 7pt Tahoma,MiscFixed; + text-decoration:none; + padding-left:1px; + padding-right:1px; + overflow:hidden; + cursor:pointer; +} +span.XtreeMinus:hover +{ + background-color:#EFC395; +} + +/* leimnud.app.menuRight CSS begin */ + +/* Processmaker CSS begin */ +.pm_separator___processmaker +{ + +} +.pm_separatorOn___processmaker +{ + +} +.pm_separatorOff___processmaker,.pm_separatorOn___processmaker +{ + height: 7px; + cursor:pointer; + text-align:center; + overflow:hidden; +} +.pm_separatorDOff___processmaker,.pm_separatorDOn___processmaker, .pm_separatorOver___processmaker, .pm_separatorOut___processmaker +{ + height:7px; + width:100%; + background-color:#C1D2EE; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + border-width:1px 0pt; + overflow:hidden; +} +.pm_separatorDOff___processmaker +{ + background:url(/js/maborak/core/images/separator.up.gif); + background-repeat:no-repeat; + background-position:50% 2; + +} +.pm_separatorDOn___processmaker +{ + background:url(/js/maborak/core/images/separator.down.gif); + background-repeat:no-repeat; + background-position:50% 50%; +} +.pm_separatorOver___processmaker +{ + background-color:#C1D2EE; +} +.pm_separatorOut___processmaker +{ + background-color:buttonface; +} + +/* Processmaker CSS end */ +/* processmap Theme.Task begin */ +/*theme firefox begin*/ +.processmap_task___firefox +{ + position : absolute; + height : 30px; + width : 150px; + background-color: #006699; + border : 1px solid #006699; + z-index : 10; + overflow : hidden; + cursor : move; +} +.processmap_task_label___firefox +{ + color:white; + text-align:center; + cursor:text; + padding-top:11; +} +.processmap_text___firefox +{ + position : absolute; + cursor : move; + background-color:red; +} +.processmap_title___firefox +{ + +} + /*theme firefox end*/ + + /*theme processmap begin*/ +.processmap_task___processmaker +{ + position : absolute; + height : 40px; + height : 38px; + width : 171px; + width : 164px; + z-index : 10; + overflow : hidden; + cursor : move; + /*background : url(/js/processmap/core/images/bg_task.gif); + background : url(/images/fondotask.png);*/ + //background-color:#006699; + //background-color:#6F6F6F; + background : url(/images/borderTask.gif); + background-color:#0576C4; + background-color:#006699; + vertical-align:middle; + display:table-cell; +} +.processmap_task_label___processmaker +{ + color:#FFF; + text-align:center; + /*position:absolute;*/ + margin:10; + vertical-align:middle; + cursor:move; +} +.processmap_text___processmaker +{ + position : absolute; + z-index : 10; + cursor : move; + font : bold 8pt Tahoma,MiscFixed; +} +.processmap_title___processmaker +{ + position :absolute; + cursor :move; + font :bold 13pt Tahoma,MiscFixed; +} + /*theme processmap end*/ + +.pm__toolbar{ + align:right; + font-size:1; + line-height:31px; +} + +.processmap_toolbarItem___processmaker +{ + margin:0px; + border:1px solid #CEC6B5; + background:#EFEFEF url(/images/dynamicForm/toolbar.buttonbg.gif) repeat-x scroll 0%; +} +.processmap_toolbarItem___processmaker:hover +{ + margin:0px; + background-color:buttonface; + border-color:buttonhighlight buttonshadow buttonshadow buttonhighlight; + border-style:solid; + /*border-width:1px 0pt;*/ + border:1px solid #316AC5; + background:#C1D2EE; + background-color: #C1D2EE; + + +} +/* processmap Theme.Task end */ + +/* processmap Theme.Panels begin */ +/* processmap Theme.Panels end */ + + +/* Theme leimnud.module.grid BEGIN */ + +/* Theme leimnud.module.grid END */ + + +/* Menues */ + + +TD.mainMenu { + background-image: url(/skins/green/images/bm.jpg); + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : short; + background-repeat: repeat-x; + height: 25px; + left: 46px; + top: 72px; + direction: rtl; + text-align: right; +} + +A.mainMenu { + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; + color: #FFFFFF; + font-weight: bold; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; + text-align: right; +} +A.mainMenu:hover { + color: #D3D3D3; + font-weight: bold; + text-decoration: none; + direction: rtl; + text-align: right; +} + +TD.SelectedMenu{ + background-image: url(/skins/green/images/bsms.jpg); + background-repeat: repeat-x; + top: 72px; + height: 26px; + direction: rtl; + text-align: right; +} +A.SelectedMenu { + vertical-align: middle; + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : medium; + font-weight: bold; + color: #000; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; + text-align: right; +} + +.SelectedMenu:hover { + vertical-align: middle; + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : medium; + font-weight: bold; + color: #005791; + text-align: center; + padding-top: 6px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; + text-align: right; +} + + +TD.subMenu { + background-image: url('/skins/green/images/bsm.jpg'); + background-repeat: repeat-x; + height: 25px; + direction: rtl; + text-align: right; +} + +A.subMenu { + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; + color: #005791; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; +} + +A.subMenu:hover { + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; + color: #092148; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; +} + +TD.selectedSubMenu { + background-image: url('/js/maborak/core/images/silverBackgroundSubMenu.jpg'); + background-repeat: repeat-x; + height: 26px; + left: 46px; + top: 98px; + direction: rtl; +} + +A.selectedSubMenu { + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; +} + +A.selectedSubMenu:hover { + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; + color: #005791; + font-weight: bold; + padding-top: 5px; + text-transform:uppercase; + text-decoration: none; + direction: rtl; +} + + +/* Menues END */ + +/* Box Top Model BEGIN */ +.boxTop, .boxTopBlue +{ + height:9px; + padding-left:8px; + padding-right:8px; + position:relative; + overflow:hidden; +} +.boxTop div, .boxTopBlue div +{ + background-color:#FFF; +} +.boxTop div.a, .boxTop div.c, .boxTopBlue div.a, .boxTopBlue div.c +{ + position:absolute; + width:9px; + height:9px; +} +.boxTop div.a, .boxTopBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftl.png); + background-color:transparent; +} +.boxTop div.c, .boxTopBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftr.png); + background-color:transparent; +} +.boxTop div.b, .boxTopBlue div.b +{ + width:100%; + height:9px; + border-top:1px solid #DADADA; + background-color:#FFF; +} +/* Box Top Model END */ + +/* Box Top Model Blue BEGIN */ +.boxTopBlue div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); + background-color:transparent; +} +.boxTopBlue div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); + background-color:transparent; +} +.boxTopBlue div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} + +/* Box Top Model Blue END */ + +/* Box Bottom Model BEGIN */ +.boxBottom, .boxBottomBlue +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxBottom div.a, .boxBottom div.c, .boxBottomBlue div.a, .boxBottomBlue div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxBottom div.a, .boxBottomBlue div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/fbl.png); + background-color:transparent; +} +.boxBottom div.c, .boxBottomBlue div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/fbr.png); + background-color:transparent; +} +.boxBottom div.b, .boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.png) repeat-x; +} +/* Box Bottom Model END */ +/* Box Bottom Model Blue BEGIN */ +.boxBottomBlue div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); + background-color:transparent; +} +.boxBottomBlue div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); + background-color:transparent; +} +.boxBottomBlue div.b +{ + width:100%; + height:16px; + border-bottom:1px solid #DADADA; + background: transparent url(/skins/green/images/fbc.blue.png) repeat-x; +} +.boxContentBlue +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + padding-right:5px; + padding-left:5px; + background-color:#D0DEF0; +} +a.linkInBlue +{ + font:normal 8pt Tahoma,MiscFixed; + color:#006699; + text-decoration:none; +} + +a.linkInBlue:hover +{ + color:orange; +} +/* Box Bottom Model Blue END */ + +/* BoxPanel Bottom Model BEGIN */ +.boxTopPanel +{ + height:15px; + padding-left:24px; + padding-right:24px; + position:relative; + overflow:hidden; +} +.boxTopPanel div.a, .boxTopPanel div.c +{ + position:absolute; + width:25px; + height:15px; +} +.boxTopPanel div.a +{ + left:0px; + top:0px; + background-image:url(/skins/green/images/ftlL.png); + background-color:transparent; +} +.boxTopPanel div.c +{ + top:0px; + right:0px; + background-image:url(/skins/green/images/ftrL.png); + background-color:transparent; +} +.boxTopPanel div.b +{ + width:100%; + height:16px; + background: transparent url(/skins/green/images/ftc.png) repeat-x; +} + +/* BoxPanel Bottom Model END */ + + + +/* XmlForm BEGIN */ + /* form BEGIN */ +form{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form table{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +form.formDefault select +{ + font:normal 11px sans-serif,MiscFixed; + color:#000; +} +form.formDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; + line-height:180%; +} +form.formDefault td +{ + padding:2px; +} +form.formDefault .content +{ + background-color:#FFF; + border-left:1px solid #dadada; + border-right:1px solid #dadada; +} +form.formDefault input.FormField +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; +} +form.formDefault input.FormFieldInvalid +{ + border: 1px solid red; +} +form.formDefault input.FormFieldValid +{ + border: 1px solid green; +} +form.formDefault .FormLabel +{ + color:#808080; + text-align:left; +} +form.formDefault .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; + direction: rtl; +} +form.formDefault textarea.FormTextArea +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + overflow:auto; +} +form.formDefault textarea.FormTextPM +{ + border: 1px solid #CCC; + background: #FFFFFF url(/skins/green/images/input_back.gif) repeat-x; + color:#333333; + font:normal 12 Courier New, monospace ; + overflow:auto; +} +form.formDefault .FormTitle +{ + color:#000; + padding-left:5px; + font-weight:bold; + background-color:#E0EFE6; +} +form.formDefault .FormSubTitle +{ + background-color:#D1DEDF; + color:black; + align: right; +} +form.formDefault .FormButton +{ + text-align:center; +} + +form.formDefault a +{ + text-decoration:none; + color:#006699; + font-family : Ezra Sil,Ezra Sil SR,CODE2000,Times New Roman,times,serif; + font-size : small; +} +form.formDefault a:hover +{ + color:orange; +} +form.formDefault td.withoutLabel, form.formDefault td.withoutLabel table td +{ + padding:0px; + height:8px; +} + + /* form END */ + /* formSearch BEGIN */ +form.formSearch input, input +{ + font-size:8pt; +} +form.formSearch a +{ + color:#006699; + text-decoration:none; +} +form.formSearch a:hover +{ + color:orange; +} +form.formSearch +{ + padding-top:5px; + padding-bottom:5px; +/* width:100%;*/ + padding-left:10px; + padding-right:10px; +/* padding-left:10%; + padding-right:10%;*/ +} +form.formSearch .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; + padding:10px; +} +form.formSearch input.FormField +{ + border: 1px solid #99BBE8; + color:#333333; + font:normal 11px Arial,Helvetica,sans-serif; + width:200px; +} +form.formSearch .FormLabel +{ + color:#000; + text-align:center; + padding-right:10px; + width:40%; +} +form.formSearch .FormFieldContent +{ + color:#000; + background-color:#EFEFEF; + padding-left:5px; + width:60%; +} + +form.formSearch .Record +{ + width:80%; +} + /* formSearch END */ + + + /* pagedTable BEGIN */ +.pagedTableDefault +{ + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + padding-left:5px; + padding-right:5px; +} +.pagedTableDefault, .pagedTableDefault table +{ + font:normal 11px sans-serif,MiscFixed; + color:#808080; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a +{ + color:#2078A8; + text-decoration:none; +} +.pagedTableDefault, .pagedTableDefault .headerContent .tableOption a:hover +{ + color:orange; +} +.pagedTableDefault td +{ + padding:0px; +} +.pagedTableDefault .pagedTable td +{ + padding:5px; +} +.pagedTableDefault .pagedTable +{ + border:1px solid #DFDFDF; + border-collapse:collapse; + color:#27373F; +} +.pagedTable td{ + text-align:right; + direction:rtl; +} +.pagedTableDefault .pagedTable .Row1 +{ + background-color:#FFF; +} +.pagedTableDefault .pagedTable .Row2 +{ + background-color:#EEE; +} +tr.Selected +{ + background-color:#D8DDFF; +} +.pagedTableDefault .pagedTable .RowPointer +{ + background-color:#E0EAEF; +} +.pagedTableDefault .cellSelected1 +{ +font-weight:bold; +} +.pagedTableDefault .cellSelected2 +{ +font-weight:bold; +} +.pagedTableDefault .pagedTable a +{ + color:#FFF; + text-decoration:none; + font-size:short; +} +.pagedTableDefault .pagedTable a:hover +{ + color:orange; +} +.pagedTableDefault .pagedTable .pagedTableHeader +{ + border-bottom:0px solid #DFDFDF; + background-color:#E0E9EF; + background-color:#6F7F75; + color:#5B5B5B; + font-weight:bold; + background-image:url(/js/maborak/core/images/silverBackgroundTableTitle.jpg); + background-repeat:repeat-x; + height:26px; + padding:0px; + overflow:hidden; + direction: rtl; + text-align: right; +} +.pagedTableDefault .pagedTable .pagedTableHeader a +{ + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; + direction: rtl; + text-align: right; +} +.pagedTableDefault .pagedTable .pagedTableHeader a:hover +{ + color:orange; + direction: rtl; + text-align: right; +} + +/*Adicion Rube*/ + +.pagedTableDefault .pagedTable .masterDetailMain +{ + background-image:url(/images/masterDetailMain.png); + background-repeat: repeat-x; + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; + font-weight: bold; + direction: rtl; + text-align: right; +} + +.pagedTableDefault .pagedTable .masterDetailOther +{ + background-image:url(/images/masterDetailOther.png); + background-repeat: repeat-x; + text-decoration:none; + color:#5B5B5B; + padding-left:5px; + font:normal 8pt Tahoma, sans-serif,MiscFixed; + font-weight: bold; +} + +/*Fin Adicion Rube*/ +.pagedTableDefault .pagedTable .RowLink +{ + background-color:#6F7F75; + text-align :center; + direction: rtl; + text-align: right; +} +A.firstPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.noFirstPage { + background-image: url('/images/lastPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.previousPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.noPreviousPage { + background-image: url('/images/nextPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.nextPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.noNextPage { + background-image: url('/images/previousPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.lastPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; + direction: rtl; + text-align: right; +} +A.noLastPage { + background-image: url('/images/firstPage.gif'); + background-repeat: no-repeat; + background-position: center bottom; + padding-left:21px; + padding-top:20px; + line-height:40px; + text-decoration:none; +} + + /* pagedTable END */ + /* Grid BEGIN */ +div.pattern .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + direction: rtl; + text-align: right; +} +div.pattern .FormTitle +{ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; + direction: rtl; + text-align: right; +} + + +div.grid +{ + font:normal 11px sans-serif,MiscFixed; + padding-left:10px; + padding-right:10px; + margin-top:7px; + direction: rtl; + text-align: right; +} + +div.grid .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; + direction: rtl; + text-align: right; +} + +div.grid .tableGrid +{ + width:100%; +} +div.grid .tableGrid .vFormTitle +{ +/* color:#006699;*/ +} + /* Grid END */ + /* Tree BEGIN */ + +div.treeBase .content +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #DADADA; + border-right:1px solid #DADADA; + background-color:#FFF; +} +.treeNode +{ + padding-bottom:10px; + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:#808080; +} +div.treeBase table td.a +{ + width:16px; + height:10px; +} +div.treeBase table td.b +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; + text-align:left; +} +/* TreeParent BEGIN */ +div.treeParent +{ + +} +div.treeParent table +{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:black; +} + +div.treeParent .treeMinus +{ + width:16px; + height:22px; + display:block; + position:relative; + background-image:url(/images/minus.gif); + background-repeat:no-repeat; + overflow:hidden; +} +div.treeParent .treePlus +{ + width:16px; + height:22px; + background-image:url(/images/plus.gif); + background-repeat:no-repeat; + display:block; +} +div.treeParent .treePointer +{ + width:1px; + height:22px; + display:block; +} +div.treeParent td.c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +div.treeParent td.d +{ + background-image:url(/images/ftv2node.gif); + background-repeat:repeat-y; +} +div.treeParent .treeNode +{ + padding:2px; + padding-bottom:1px; + font-weight:bold; +} + + + +div.treeParent .treeNode a, div.treeBase .treeNode a +{ + color:#006699; + font-weight:normal; + text-decoration:none; +} +div.treeParent .treeNode a:hover, div.treeBase .treeNode a:hover +{ + color:orange; +} +div.treeParent .FormField +{ + background-color:#FFF; + padding-bottom:10px; +} +div.treeParent .FormField a +{ + font-size:8pt !important; + color:red; +} +div.treeParent .FormTitle +{ +/* font:bold 8pt sans-serif,Tahoma,MiscFixed; + font:normal 11px sans-serif,MiscFixed;*/ + font-weight:bold; + color: black; + background-color:#E0EFE6; + padding:2px; +} +/* TreeParent END */ + +/* TreeChild BEGIN */ +div.treeChild td.b +{ + padding-right:10px; +} +div.treeChild td.a +{ + width:10px; + height:22px; + background:none; +} +div.treeChild .c +{ + background-image:url(/images/ftv2vertline.gif); + background-repeat:repeat-y; +} +/* TreeChild END */ + + +div.treeChild +{ + padding-left:1px; +} +div.treeParent .content .treeNode a.selected +{ + color:white; + background-color:#006699; +} + +/*div.treeParent div.treeParent .content +{ + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.a +{ + background-image:url(/skins/green/images/ftl.blue.gif); +} +div.treeParent div.treeParent .boxTop div.b +{ + border-top:1px solid #99BBE8; + background-color:#D0DEF0; +} +div.treeParent div.treeParent .boxTop div.c +{ + background-image:url(/skins/green/images/ftr.blue.gif); +} +div.treeParent div.treeParent .boxBottom div.a +{ + background-image:url(/skins/green/images/fbl.blue.png); +} +div.treeParent div.treeParent .boxBottom div.b +{ + background-image:url(/skins/green/images/fbc.blue.png); +} +div.treeParent div.treeParent .boxBottom div.c +{ + background-image:url(/skins/green/images/fbr.blue.png); +}*/ + + + + +div.treeParent table +{ + +} +div.treeParent .subcontent +{ + padding-left:5px; + padding-right:5px; + border-left:1px solid #99BBE8; + border-right:1px solid #99BBE8; + background-color:#D0DEF0; +} + /* Tree END */ +/* XmlForm END */ + + +/**************************** Start -> JSCalendar Widget by Erik Amaru Ortiz *********************************/ + +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #6F7F75; + font-size: 11px; + color: #000; + cursor: default; + background: #F0F2F0; + font-family: tahoma,verdana,sans-serif; + z-index:1000; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #6F7F75 url(menuarrow2.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #000; + color: #fff; + padding: 2px; +} + +.calendar thead tr { /* Row containing navigation buttons */ + background: #6F7F75; /*e*/ + color: #fff; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #E9F2E9; +} + +.calendar thead .name { /* Cells in footer (only one right now) */ + text-align: center; + background: #206A9B; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell
    + + + + + + + + + + + + + + + +
    {$HTML}{$form.HTML}
    + {$form.PME_HTML_ENABLETEMPLATE}{$PME_HTML_ENABLETEMPLATE}{$form.PME_REFRESH_VIEW}{$form.PME_RESTORE_HTML} +
    {$HTML2}{$form.HTML2}
    + +
    + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.xml b/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.xml new file mode 100644 index 000000000..32eb498ea --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_HtmlEditor.xml @@ -0,0 +1,80 @@ + + + + + + + + +HTML View + + + + Enable HTML Editing + + + +Restore Original HTML + + + +Refresh View + + + +HTML Code + +0) + { + getField("HTML2").value=window._editorHTML.doc.forms[0].innerHTML; + } + else + { + getField("HTML2").value=getField("HTML").value; + } + } + function html2_html() + { + if (window._editorHTML.doc.forms.length>0) + { + window._editorHTML.doc.forms[0].innerHTML=getField("HTML2").value; + getField("HTML").value=getField("HTML2").value; + } + else + { + window._editorHTML.setHTML(getField("HTML2").value); + getField("HTML").value=getField("HTML2").value; + } + } + var restore_html = function() { + alert('restore_html'); + }; + html_html2(); + +]]> + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_JSEditor.xml b/workflow/engine/xmlform/dynaforms/dynaforms_JSEditor.xml new file mode 100644 index 000000000..8a6acd932 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_JSEditor.xml @@ -0,0 +1,47 @@ + + + + + +There is no javascript code + + + +SELECT XMLNODE_NAME AS UID, XMLNODE_NAME AS NAME FROM dynaForm WHERE TYPE = "javascript" + Section + + + + Code + + + +getField('JS_TITLE').style.font ="9pt tahoma"; +function resizeJSEditor(){ + try{ + getField('JS','dynaforms_JSEditor').style.height= + document.getElementById('dynaformEditor[4]').parentNode.clientHeight-32-32; + }catch(e){ + } +} +resizeJSEditor(); +var JSCodePress=false; +function startJSCodePress() +{ + var code=getField("JS").value; + getField("JS").className="codepress javascript linenumbers-on"; + JSCodePress=new CodePress(getField("JS")); + getField("JS").parentNode.insertBefore(JSCodePress,getField("JS")); + JSCodePress.edit(code,'javascript'); + getField("JS_LIST").onchange=function(){ + dynaformEditor.changeJavascriptCode(); + }; +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_List.xml b/workflow/engine/xmlform/dynaforms/dynaforms_List.xml new file mode 100644 index 000000000..b881bdce4 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_List.xml @@ -0,0 +1,34 @@ + + + + + + + + + Dynaform + + + + Type + + + + Description + + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Options.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Options.xml new file mode 100644 index 000000000..f5e102efc --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Options.xml @@ -0,0 +1,151 @@ + + + + + New + + + + + + + + + + + + + + + + + + + + + diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Properties.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Properties.xml new file mode 100644 index 000000000..f54c61ea7 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Properties.xml @@ -0,0 +1,198 @@ + + + + + Properties + + + + + + + + + Dynaform + + + + Type + + + + + + + Description + + + + Others + + + + Width + + + + Mode + + + + + + + Next Step Link + + + + + + + +Show print dynaform button + + + + + + Apply + + + Revert + + + +" + response,"alert"); + return false; + + } + + + }.extend(this); + isTrue = oRPC.make(); + return isTrue; +}; + +// function setDropdownSelection made a selection in a dropdown element +function setDropdownSelection(id, value){ + document.getElementById(id).value = value; +}; + +// function changeToolbar +// @param type +// @desc this function change by Ajax, the toolbar located in the superior part +// of the dynaform editor +function changeToolbar(type){ + var proUid = document.getElementById("form[PRO_UID]").value; + var dynUid = document.getElementById("form[DYN_UID]").value; + var file = proUid + "/" + dynUid; + var dynTitle = "New Dynaform"; + oRPC = new leimnud.module.rpc.xmlhttp({ + url : "../dynaforms/dynaforms_ToolbarAjax", + method: 'POST', + async : true, + args : 'TOOLBAR=' + type + '&FILE=' + file + '&PRO_UID=' + proUid + '&DYN_UID=' + dynUid + '&DYN_TITLE=' + dynTitle + }); + oRPC.callback = function(oRPC) { + + getElementsByClassNameCrossBrowser("panel_headerBar___processmaker",document,"div")[0].innerHTML = oRPC.xmlhttp.responseText; + document.getElementById("publisherContent[0]").style.display = "inline"; + document.getElementById("publisherContent[0]").style.position = "absolute"; + document.getElementById("publisherContent[0]").style.top = "0"; + document.getElementById("publisherContent[0]").style.left = "0"; + }.extend(this); + oRPC.make(); + +}; + +// end added code + +function orderButtons() { + var propertiesDiv = document.getElementById('dynaformEditor[8]'); + var a=getField('PME_PROP_REVERT','dynaforms_Properties'); + var b=getField('PME_PROP_APPLY','dynaforms_Properties'); + a.parentNode.insertBefore(b,a); + propertiesDiv.style.visibility=''; +} +orderButtons(); +/*getField("ENABLETEMPLATE","dynaforms_Properties").onclick=function() +{ + var oAux; + if (oAux = getField("PME_HTML_ENABLETEMPLATE","dynaforms_HtmlEditor")) { + oAux.checked=this.checked; + } +}*/ +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.html b/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.html new file mode 100644 index 000000000..25b2ba341 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.html @@ -0,0 +1,47 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.DYN_UID}
    {$form.PRO_UID}
    {$form.DYN_TYPE}
    {$form.TITLE}
    {$DYN_TITLENEW}{$form.DYN_TITLENEW}
    {$DYN_DESCRIPTIONNEW}{$form.DYN_DESCRIPTIONNEW}
    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.xml new file mode 100644 index 000000000..51c08ae0e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Saveas.xml @@ -0,0 +1,51 @@ + + + + + + + + + <en>Dynaform Information</en> + + + + Title + + + + Description + + + + Cancel + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_ShortList.xml b/workflow/engine/xmlform/dynaforms/dynaforms_ShortList.xml new file mode 100644 index 000000000..0560bdb1a --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_ShortList.xml @@ -0,0 +1,34 @@ + + + + + + + + Title + + + + Type + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Supervisor.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Supervisor.xml new file mode 100644 index 000000000..9485be375 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Supervisor.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + Title + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_SupervisorOptions.xml b/workflow/engine/xmlform/dynaforms/dynaforms_SupervisorOptions.xml new file mode 100644 index 000000000..7e7e36b35 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_SupervisorOptions.xml @@ -0,0 +1,80 @@ + + + + + + + Assign + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_Toolbar.xml b/workflow/engine/xmlform/dynaforms/dynaforms_Toolbar.xml new file mode 100644 index 000000000..1f746463b --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_Toolbar.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_WebEntry.xml b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntry.xml new file mode 100644 index 000000000..8d6328434 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntry.xml @@ -0,0 +1,226 @@ + + + + + + + Properties + + +Initial Task + + +Initial Dynaform + + + + Method + + + + Input Documents Access + + + + + + + Web Service User + + + Web Service Passsword + + + + Cyclical Assignment + + + + Test Configuration + + + + Generate Web Entry Page + + + +=1){ + getField('SEARCH').disabled = false; + //webEntry_generate(PRO_UID); + } else { + getField('SEARCH').disabled = true; + msgBox(rpc.xmlhttp.responseText,"alert"); + } + }.extend(this); + oRPC.make(); +} + +var webEntry_generate = function(PRO_UID, TASKS, DYNAFORM) { + //alert(PRO_UID+" ** "+getField('TASKS').value+" ** "+getField('DYNAFORM').value);return; + otask = getField('TASKS'); + odynaform = getField('DYNAFORM'); + sw=0; + if(otask.value=='') + { if(odynaform.value=='') + { alert(G_STRINGS.ID_WEBENTRY); + } + } + else + { if(odynaform.value=='') + { alert('This process has any assigned dynaform'); + } + else + { sw=1; + } + } + if(sw==1) + { + if(getField('WE_TYPE').value=='SINGLE') + { oPanel1 = new leimnud.module.panel(); + oPanel1.options = { + size :{w:600,h:400}, + position:{x:0,y:0,center:true}, + title :"Web Entry", + statusBar:true, + control :{resize:false,roll:false}, + fx :{modal:true,opacity:true,blinkToFront:true,fadeIn:false} + }; + oPanel1.events = { + remove: function() { delete(oPanel1); }.extend(this) + }; + oPanel1.make(); + oPanel1.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../processes/processes_Ajax', + async : true, + method: 'POST', + args : "action=webEntry_generate&data="+{PRO_UID:PRO_UID, TASKS:getField('TASKS').value, DYNAFORM:getField('DYNAFORM').value, WE_TYPE:getField('WE_TYPE').value, WS_USER:getField('WS_USER').value, WS_PASS:getField('WS_PASS').value, WS_ROUNDROBIN:getField('WS_ROUNDROBIN').value, WE_USR:getField('WE_USR').value }.toJSONString() + }); + oRPC.callback = function(rpc){ + oPanel1.loader.hide(); + var scs=rpc.xmlhttp.responseText.extractScript(); + oPanel1.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this); + oRPC.make(); + } + else + { + var k = new leimnud.module.rpc.xmlhttp({ + url : '../processes/processes_Ajax', + async : true, + method: 'POST', + args : "action=webEntry_Val_Assig&data="+{ + PRO_UID:PRO_UID, + TASKS:getField('TASKS').value, + DYNAFORM:getField('DYNAFORM').value + }.toJSONString() + }); + + k.callback = function(rpc){ + if(rpc.xmlhttp.responseText!=1){ + msgBox(G_STRINGS.WEBEN_ONLY_BALANCEDJS,"alert"); + } + }.extend(this); + k.make(); + + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : '../processes/processes_Ajax', + async : true, + method: 'POST', + args : "action=webEntry_generate&data="+{PRO_UID:PRO_UID, TASKS:getField('TASKS').value, DYNAFORM:getField('DYNAFORM').value, WE_TYPE:getField('WE_TYPE').value, WS_USER:getField('WS_USER').value, WS_PASS:getField('WS_PASS').value, WS_ROUNDROBIN:getField('WS_ROUNDROBIN').value, WE_USR:getField('WE_USR').value }.toJSONString() + }); + oRPC.make(); + oPanel.remove(); + Pm.tmp.editProcessPanel.clearContent(); + Pm.tmp.editProcessPanel.loader.show(); + var r = new leimnud.module.rpc.xmlhttp({ + url:'../processes/processes_Ajax', + args:"action=webEntry&data="+{ + pro_uid :PRO_UID + }.toJSONString() + }); + r.callback=function(rpc,panel) + { + Pm.tmp.editProcessPanel.loader.hide(); + var scs = rpc.xmlhttp.responseText.extractScript(); + Pm.tmp.editProcessPanel.addContent(rpc.xmlhttp.responseText); + scs.evalScript(); + }.extend(this,panel); + r.make(); + } + } +}; + +hideRowById('WS_ROUNDROBIN'); +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryList.xml b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryList.xml new file mode 100644 index 000000000..667dd5cfd --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryList.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + Delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryOptions.xml b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryOptions.xml new file mode 100644 index 000000000..3b16b5d40 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_WebEntryOptions.xml @@ -0,0 +1,78 @@ + + + + + + + New + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_XmlEditor.xml b/workflow/engine/xmlform/dynaforms/dynaforms_XmlEditor.xml new file mode 100644 index 000000000..440b6243e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_XmlEditor.xml @@ -0,0 +1,24 @@ + + + + + + +XML + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_vars.html b/workflow/engine/xmlform/dynaforms/dynaforms_vars.html new file mode 100755 index 000000000..bea0ac03d --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_vars.html @@ -0,0 +1,27 @@ +
    +
    +
    + + + + +
    + + + + + + + +
    {$vars}{$form.vars}
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/dynaforms/dynaforms_vars.xml b/workflow/engine/xmlform/dynaforms/dynaforms_vars.xml new file mode 100755 index 000000000..08c35460a --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/dynaforms_vars.xml @@ -0,0 +1,10 @@ + + + + + SELECT * FROM DYNAFIELDS + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/_options.xml b/workflow/engine/xmlform/dynaforms/fields/_options.xml new file mode 100644 index 000000000..a682c2973 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/_options.xml @@ -0,0 +1,9 @@ + + + + + Value + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/button.html b/workflow/engine/xmlform/dynaforms/fields/button.html new file mode 100644 index 000000000..82a897bc1 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/button.html @@ -0,0 +1,58 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$PME_ONCLICK}{$form.PME_ONCLICK}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/button.xml b/workflow/engine/xmlform/dynaforms/fields/button.xml new file mode 100644 index 000000000..9f1b35cde --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/button.xml @@ -0,0 +1,47 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + + JavaScript to Execute + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/checkbox.html b/workflow/engine/xmlform/dynaforms/fields/checkbox.html new file mode 100644 index 000000000..1d32a976d --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/checkbox.html @@ -0,0 +1,90 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    * {$PME_VALUE}{$form.PME_VALUE}
    * {$PME_FALSEVALUE}{$form.PME_FALSEVALUE}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_LABELONRIGHT}{$form.PME_LABELONRIGHT}
    {$PME_ENABLEHTML}{$form.PME_ENABLEHTML}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/checkbox.xml b/workflow/engine/xmlform/dynaforms/fields/checkbox.xml new file mode 100644 index 000000000..935e8d2b3 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/checkbox.xml @@ -0,0 +1,74 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Value + + + Value if not checked + + + Default Value + + + Read Only + + + Hint + + + + Appearance + + + + + Label on the right side + + + Enable Html + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/checkgroup.html b/workflow/engine/xmlform/dynaforms/fields/checkgroup.html new file mode 100644 index 000000000..741132c26 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/checkgroup.html @@ -0,0 +1,93 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_OPTIONS}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/checkgroup.xml b/workflow/engine/xmlform/dynaforms/fields/checkgroup.xml new file mode 100644 index 000000000..dfebeb919 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/checkgroup.xml @@ -0,0 +1,82 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Default Value + + + Hint + + + Appearance + + + + + Mode + + + + + + Data + + +Sql Connection + + + + + Sql + + + + + Options + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/currency.html b/workflow/engine/xmlform/dynaforms/fields/currency.html new file mode 100644 index 000000000..6f234ebf7 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/currency.html @@ -0,0 +1,136 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_MAXLENGTH}{$form.PME_MAXLENGTH}
    {$PME_CURRENCY}{$form.PME_CURRENCY}
    {$PME_VALIDATE}{$form.PME_VALIDATE}
    {$PME_MASK}{$form.PME_MASK}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE_OP}
    {$PME_FORMULA}{$form.PME_FORMULA}
    {$PME_FUNCTION}{$form.PME_FUNCTION}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/currency.xml b/workflow/engine/xmlform/dynaforms/fields/currency.xml new file mode 100644 index 000000000..d0f6bd43e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/currency.xml @@ -0,0 +1,134 @@ + + + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Max. Length + + + Currency + + + Validate + + + + Mask + + + Required + + + Read Only + + + Default Value + + + + Hint + + + + Appearance + + + + Size + + + + + Mode + + + + Operations + + + Formula + + + Function + + + + + Data + +Sql Connection + + + Sql + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/date.html b/workflow/engine/xmlform/dynaforms/fields/date.html new file mode 100644 index 000000000..4aefb8242 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/date.html @@ -0,0 +1,149 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$PME_RELATIVEDATE}{$form.PME_RELATIVEDATE}
    {$form.PME_SUBTITLE3}
    {$PME_STARTDATE}{$form.PME_STARTDATE}
    {$PME_ENDDATE}{$form.PME_ENDDATE}
    {$form.PME_SUBTITLE3a}
    + {$form.PMED_AFTERBEFORE_DESC} +
    {$PME_BEFOREDATE}{$form.PME_BEFOREDATE}
    {$PME_AFTERDATE}{$form.PME_AFTERDATE}
    + {$form.PME_SUBTITLE3x}                 {$form.PME_SUBTITLE3xl} +
    {$PME_MASK}{$form.PME_MASK}
    {$form.PME_SUBTITLE3b}
    {$PME_EDITABLE}{$form.PME_EDITABLE}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_SHOWTIME}{$form.PME_SHOWTIME}
    {$PME_DEFAULTVALUE_SEL}{$form.PME_DEFAULTVALUE_SEL}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/date.xml b/workflow/engine/xmlform/dynaforms/fields/date.xml new file mode 100644 index 000000000..06568caa0 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/date.xml @@ -0,0 +1,230 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Type of date range + + + + + + + Start and End Dates + + + + Start Date + + + + End Date + + + + Relative Start and End Dates + + + + Data Codes: A number followed by a letter to indicate the unit of time (d=day m=month y=year).
    Use negative numbers for past dates and positive numbers for future dates
    NOTE. When these relative dates are set have the priority, leave empty to use Start and End dates.]]>
    +
    + + + Start Relative Date + + + + End Relative Date + + + + + Mask: %Y=Year, %y=year (the two last digits at year), %m=Month, %d=Day]]> + + + + + + Mask + + + + Behaviour + + + + Editable + + + Required + + + Read Only + + + Show time + + + + + Default + + + + + + + + Hint + + + + Appearance + + + + Size + + + + + Mode + + + + Cancel + + + + Save + + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/dropdown.html b/workflow/engine/xmlform/dynaforms/fields/dropdown.html new file mode 100644 index 000000000..6666c2bc8 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/dropdown.html @@ -0,0 +1,111 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEPENDENTFIELDS}{$form.PME_DEPENDENTFIELDS}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_SAVELABEL}{$form.PME_SAVELABEL}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_OPTIONS}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/dropdown.xml b/workflow/engine/xmlform/dynaforms/fields/dropdown.xml new file mode 100644 index 000000000..038c4c0af --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/dropdown.xml @@ -0,0 +1,123 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Required + + + Read Only + + @@PME_XMLNODE_NAME AND XMLNODE_NAME <> "" AND ( TYPE="text" or TYPE="textarea" or TYPE="dropdown" or TYPE="listbox" or TYPE="hidden" ) + ]]>Dependent Fields + + + Default Value + + + Save label of selected value in variable + + + + Hint + + + + Appearance + + + + + + Mode + + + + + Data + +Sql Connection + + + + Sql + + + + Options + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/file.html b/workflow/engine/xmlform/dynaforms/fields/file.html new file mode 100644 index 000000000..d56ba2fb7 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/file.html @@ -0,0 +1,71 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_PRO_UID}
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$PME_INPUT}{$form.PME_INPUT}
    {$form.PME_SUBTITLE3b}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/file.xml b/workflow/engine/xmlform/dynaforms/fields/file.xml new file mode 100644 index 000000000..c067da16a --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/file.xml @@ -0,0 +1,66 @@ + + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + +Input + + + + + + + + + Behaviour + + + Required + + + Hint + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/grid.html b/workflow/engine/xmlform/dynaforms/fields/grid.html new file mode 100644 index 000000000..75daa8b4a --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/grid.html @@ -0,0 +1,61 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_PRO_UID}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_XMLGRID}{$form.PME_XMLGRID}

    {$form.PME_ADDROW}

    {$form.PME_DELETEROW}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/grid.xml b/workflow/engine/xmlform/dynaforms/fields/grid.xml new file mode 100644 index 000000000..99be0579e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/grid.xml @@ -0,0 +1,51 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + +Grid + + + + Add new rows + + + + Delete rows + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/hidden.html b/workflow/engine/xmlform/dynaforms/fields/hidden.html new file mode 100644 index 000000000..493921135 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/hidden.html @@ -0,0 +1,71 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    diff --git a/workflow/engine/xmlform/dynaforms/fields/hidden.xml b/workflow/engine/xmlform/dynaforms/fields/hidden.xml new file mode 100644 index 000000000..9c5f2d324 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/hidden.xml @@ -0,0 +1,64 @@ + + + + + + + + Properties + + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Default Value + + + + + + Mode + + + + Data + + +Sql Connection + + + + Sql + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/javascript.html b/workflow/engine/xmlform/dynaforms/fields/javascript.html new file mode 100644 index 000000000..d455fa989 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/javascript.html @@ -0,0 +1,55 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_CODE}{$form.PME_CODE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    + + + + diff --git a/workflow/engine/xmlform/dynaforms/fields/javascript.xml b/workflow/engine/xmlform/dynaforms/fields/javascript.xml new file mode 100644 index 000000000..157bfc2a3 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/javascript.xml @@ -0,0 +1,42 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Code + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/link.html b/workflow/engine/xmlform/dynaforms/fields/link.html new file mode 100755 index 000000000..7abac0591 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/link.html @@ -0,0 +1,78 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_LINK}{$form.PME_LINK}
    {$PME_TARGET_SEL} +
    {$form.PME_TARGET_SEL}{$form.PME_TARGET}
    {$PME_VALUE}{$form.PME_VALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    + + + + diff --git a/workflow/engine/xmlform/dynaforms/fields/link.xml b/workflow/engine/xmlform/dynaforms/fields/link.xml new file mode 100644 index 000000000..4675e3cc8 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/link.xml @@ -0,0 +1,85 @@ + + + + + + Properties + + + Field Name + + + + SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Link + + + + Target + + + + + + + + + + + Value + + + + Hint + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/listbox.html b/workflow/engine/xmlform/dynaforms/fields/listbox.html new file mode 100644 index 000000000..bdb29d37d --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/listbox.html @@ -0,0 +1,100 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_OPTIONS}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    diff --git a/workflow/engine/xmlform/dynaforms/fields/listbox.xml b/workflow/engine/xmlform/dynaforms/fields/listbox.xml new file mode 100644 index 000000000..dca4945f6 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/listbox.xml @@ -0,0 +1,90 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Required + + + Default Value + + + + Hint + + + + Appearance + + + + Size + + + + + Mode + + + + + + Data + + +Sql Connection + + + + Sql + + + + Options + + + + Cancel + + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/password.html b/workflow/engine/xmlform/dynaforms/fields/password.html new file mode 100644 index 000000000..7d5e4a966 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/password.html @@ -0,0 +1,90 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_MAXLENGTH}{$form.PME_MAXLENGTH}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_AUTOCOMPLETE}{$form.PME_AUTOCOMPLETE}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    diff --git a/workflow/engine/xmlform/dynaforms/fields/password.xml b/workflow/engine/xmlform/dynaforms/fields/password.xml new file mode 100644 index 000000000..c64956718 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/password.xml @@ -0,0 +1,77 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Max. Length + + + Required + + + Autocomplete + + + + Read Only + + + + Hint + + + Appearance + + + + + Size + + + + + Mode + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/percentage.html b/workflow/engine/xmlform/dynaforms/fields/percentage.html new file mode 100644 index 000000000..1719ea80c --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/percentage.html @@ -0,0 +1,130 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_MAXLENGTH}{$form.PME_MAXLENGTH}
    {$PME_VALIDATE}{$form.PME_VALIDATE}
    {$PME_MASK}{$form.PME_MASK}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE_OP}
    {$PME_FORMULA}{$form.PME_FORMULA}
    {$PME_FUNCTION}{$form.PME_FUNCTION}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    diff --git a/workflow/engine/xmlform/dynaforms/fields/percentage.xml b/workflow/engine/xmlform/dynaforms/fields/percentage.xml new file mode 100644 index 000000000..2f4275867 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/percentage.xml @@ -0,0 +1,125 @@ + + + + + + + + + Properties + + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + + Max. Length + + + Validate + + + + Mask + + + + Required + + + + Read Only + + + Default Value + + + + Hint + + + + Appearance + + + + + Size + + + + + Mode + + + + + + + Operations + + + Formula + + + Function + + + + Data + + +Sql Connection + + + + Sql + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/radiogroup.html b/workflow/engine/xmlform/dynaforms/fields/radiogroup.html new file mode 100644 index 000000000..2dab49004 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/radiogroup.html @@ -0,0 +1,95 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_OPTIONS}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/radiogroup.xml b/workflow/engine/xmlform/dynaforms/fields/radiogroup.xml new file mode 100644 index 000000000..225df755b --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/radiogroup.xml @@ -0,0 +1,85 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Required + + + Default Value + + + Hint + + + Appearance + + + + + + Mode + + + + + + Data + + +Sql Connection + + + + Sql + + + + Options + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/radiogroupview.xml b/workflow/engine/xmlform/dynaforms/fields/radiogroupview.xml new file mode 100644 index 000000000..cddc03e68 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/radiogroupview.xml @@ -0,0 +1,38 @@ + + +
    + + + Field name + + + + + + Required + + + Default Value + + + + Appearance + + + + + EnableHtml + + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/reset.html b/workflow/engine/xmlform/dynaforms/fields/reset.html new file mode 100644 index 000000000..abb8ce2e4 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/reset.html @@ -0,0 +1,51 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/reset.xml b/workflow/engine/xmlform/dynaforms/fields/reset.xml new file mode 100644 index 000000000..86a5b30e6 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/reset.xml @@ -0,0 +1,43 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/submit.html b/workflow/engine/xmlform/dynaforms/fields/submit.html new file mode 100644 index 000000000..31f0a9069 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/submit.html @@ -0,0 +1,55 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$PME_ONCLICK}{$form.PME_ONCLICK}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/submit.xml b/workflow/engine/xmlform/dynaforms/fields/submit.xml new file mode 100644 index 000000000..a2f4b4639 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/submit.xml @@ -0,0 +1,47 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + + + Javascript to Execute On Click + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/subtitle.html b/workflow/engine/xmlform/dynaforms/fields/subtitle.html new file mode 100644 index 000000000..96ace7cbb --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/subtitle.html @@ -0,0 +1,60 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE}
    {$PME_ENABLEHTML}{$form.PME_ENABLEHTML}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    + diff --git a/workflow/engine/xmlform/dynaforms/fields/subtitle.xml b/workflow/engine/xmlform/dynaforms/fields/subtitle.xml new file mode 100644 index 000000000..a8ae4e0a2 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/subtitle.xml @@ -0,0 +1,52 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Content + + + + Appearance + + + + + + Enable Html + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/suggest.html b/workflow/engine/xmlform/dynaforms/fields/suggest.html new file mode 100755 index 000000000..16197a5be --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/suggest.html @@ -0,0 +1,141 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {$form.PME_TABLE_DATA}{$form.PME_PRIMARY_KEY_DATA}{$form.PME_PRIMARY_KEY_TYPE_DATA}{$form.PME_FIELD} + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_STRTO}{$form.PME_STRTO}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_SAVELABEL}{$form.PME_SAVELABEL}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    * {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    * {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$PME_MAXRESULTS}{$form.PME_MAXRESULTS}
    {$form.PME_SHOWNORESULTS}
    {$form.PME_STORE_NEW_ENTRY}
    * {$PME_TABLE} + {$form.PME_TABLE} + {$PME_PRIMARY_KEY} {$form.PME_PRIMARY_KEY} + {$PME_PRIMARY_KEY_TYPE} {$form.PME_PRIMARY_KEY_TYPE} +
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    + + + diff --git a/workflow/engine/xmlform/dynaforms/fields/suggest.xml b/workflow/engine/xmlform/dynaforms/fields/suggest.xml new file mode 100755 index 000000000..4a594bdcd --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/suggest.xml @@ -0,0 +1,285 @@ + + + + + + + + + Properties + + + Field Name + + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + + + + Required + + + + + + Default Value + + + + Hint + + + + Appearance + + + + Size + + + + + Mode + + + + + + + + Autosuggest behaviour + + + + SELECT * FROM DB_CONNECTIONS + Sql Connection + + + + Sql + + + + Max Results + + + + Show no results message + + + + Save on dynaform + + + + + + + Store new entry + + + + + Table + + + + + Primary Key + + + + + + + Type + + + + + + + + + + Cancel + + + + Save + + + 0){ + p2 = s.indexOf(" WHERE "); + if( p2 < 0 ){ + p2 = s.indexOf(" ORDER "); + if( p2 < 0 ){ + p2 = s.indexOf(" JOIN "); + if( p2 < 0 ) + p2 = s.length + } + } + + + ss = s0.substring(p1, p2); + ss = ss.replace("FROM", "").trim(); + ss = ss.replace("from", "").trim(); + + aTables = ss.split(','); + + otable = getField('PME_TABLE'); + oPK = getField('PME_PRIMARY_KEY'); + oPKT = getField('PME_PRIMARY_KEY_TYPE'); + oPK.length = 0; + oPKT.value = ''; + otable.length = 0; + var newOption = new Option("", "0"); + otable.options[0] = newOption; + + for(i=0; i= 0){ + p2 = s.indexOf(" FROM "); + p2 = (p2 > 0)? p2: s.length; + ss = s0.substring(p1, p2); + ss = ss.replace("SELECT", "").trim(); + ss = ss.replace("FROM", "").trim(); + ss = ss.replace("select", "").trim(); + ss = ss.replace("from", "").trim(); + + aTables = ss.split(','); + + otable = getField('PME_PRIMARY_KEY'); + otable.length = 0; + var newOption = new Option("", "0"); + otable.options[0] = newOption; + + for(i=0; i + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/text.html b/workflow/engine/xmlform/dynaforms/fields/text.html new file mode 100644 index 000000000..cbef7de80 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/text.html @@ -0,0 +1,139 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_MAXLENGTH}{$form.PME_MAXLENGTH}
    {$PME_VALIDATE}{$form.PME_VALIDATE}
    {$PME_MASK}{$form.PME_MASK}
    {$PME_STRTO}{$form.PME_STRTO}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEPENDENTFIELDS}{$form.PME_DEPENDENTFIELDS}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_SIZE}{$form.PME_SIZE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE_OP}
    {$PME_FORMULA}{$form.PME_FORMULA}
    {$PME_FUNCTION}{$form.PME_FUNCTION}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/text.xml b/workflow/engine/xmlform/dynaforms/fields/text.xml new file mode 100644 index 000000000..63e796ff0 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/text.xml @@ -0,0 +1,177 @@ + + + + + + + + + Properties + + + Field Name + + + + + SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Max. Length + + + + Validate + + + + Mask + + + + Text transform to + + + Required + + + Read Only + + @@PME_XMLNODE_NAME AND XMLNODE_NAME <> "" AND ( TYPE="text" or TYPE="textarea" or TYPE="dropdown" or TYPE="listbox" or TYPE="hidden" ) + ]]>Dependent Fields + + + Default Value + + + Hint + + + + Appearance + + + + Size + + + + Mode + + + + Operations + + + Formula + + + Function + + + + Data + + +Sql Connection + + + + Sql + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/textarea.html b/workflow/engine/xmlform/dynaforms/fields/textarea.html new file mode 100644 index 000000000..6fc5e98fd --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/textarea.html @@ -0,0 +1,107 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_PRO_UID}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_REQUIRED}{$form.PME_REQUIRED}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_ROWS}{$form.PME_ROWS}
    {$PME_COLS}{$form.PME_COLS}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_SUBTITLE2}
    {$PME_SQLCONNECTION}{$form.PME_SQLCONNECTION}
    {$PME_XMLNODE_VALUE}{$form.PME_XMLNODE_VALUE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/textarea.xml b/workflow/engine/xmlform/dynaforms/fields/textarea.xml new file mode 100644 index 000000000..d1698cc56 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/textarea.xml @@ -0,0 +1,88 @@ + + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + Required + + + Read Only + + + Default Value + + + Hint + + + + Appearance + + + + Rows + + + Columns + + + + Mode + + + + + Data + + +Sql Connection + + + + Sql + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/title.html b/workflow/engine/xmlform/dynaforms/fields/title.html new file mode 100644 index 000000000..c24e3d36c --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/title.html @@ -0,0 +1,62 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE}
    {$PME_ENABLEHTML}{$form.PME_ENABLEHTML}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/title.xml b/workflow/engine/xmlform/dynaforms/fields/title.xml new file mode 100644 index 000000000..2f9e1fa9b --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/title.xml @@ -0,0 +1,52 @@ + + + + + + + Properties + + + Field Name + + + + SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Appearance + + + + + Enable Html + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/yesno.html b/workflow/engine/xmlform/dynaforms/fields/yesno.html new file mode 100644 index 000000000..8abaa7670 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/yesno.html @@ -0,0 +1,77 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PME_A}
    {$form.PME_TYPE}
    {$form.PME_TITLE}
    * {$PME_XMLNODE_NAME}{$form.PME_XMLNODE_NAME}
    {$form.PME_XMLNODE_NAME_OLD}
    {$form.PME_VALIDATE_NAME}
    {$PME_LABEL}{$form.PME_LABEL}
    {$form.PME_SUBTITLE3}
    {$PME_READONLY}{$form.PME_READONLY}
    {$PME_DEFAULTVALUE}{$form.PME_DEFAULTVALUE}
    {$PME_HINT}{$form.PME_HINT}
    {$form.PME_SUBTITLE}
    {$PME_MODE}{$form.PME_MODE}
    {$form.PME_ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields/yesno.xml b/workflow/engine/xmlform/dynaforms/fields/yesno.xml new file mode 100644 index 000000000..673aff55e --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields/yesno.xml @@ -0,0 +1,67 @@ + + + + + + Properties + + + Field Name + + + +SELECT XMLNODE_NAME, TYPE FROM dynaForm WHERE XMLNODE_NAME = @@PME_XMLNODE_NAME + + + + Label + + + + Behaviour + + + + + Read Only + + + + Default Value + + + Hint + + + Appearance + + + + + + Mode + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_Edit.xml b/workflow/engine/xmlform/dynaforms/fields_Edit.xml new file mode 100644 index 000000000..0f79a154d --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_Edit.xml @@ -0,0 +1,24 @@ + + +
    + + Field name + + + + Type + + + + Default value + + + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_List.xml b/workflow/engine/xmlform/dynaforms/fields_List.xml new file mode 100644 index 000000000..cc6b5fedf --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_List.xml @@ -0,0 +1,29 @@ + + + + Field Name + + + + + Type + + + + + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_Options.xml b/workflow/engine/xmlform/dynaforms/fields_Options.xml new file mode 100644 index 000000000..0e97b4c5f --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_Options.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_ShortList.xml b/workflow/engine/xmlform/dynaforms/fields_ShortList.xml new file mode 100644 index 000000000..2a73cf558 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_ShortList.xml @@ -0,0 +1,21 @@ + + + + Field name + + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_Toolbar.xml b/workflow/engine/xmlform/dynaforms/fields_Toolbar.xml new file mode 100644 index 000000000..07b15dfbc --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_Toolbar.xml @@ -0,0 +1,104 @@ + + + + + + + save + + + + + + save as + + + + + + + + text + + + currency + + + percentage + + + password + + + Suggest + + + + + + <en>title</en> + + + subtitle + + + + + + submit + + + reset + + + + + dropdown + + + yesno + + + listbox + + + + + checkbox + + + checkgroup + + + radiogroup + + + + + date + + + hidden + + + link + + + file + + + + + javascript + + + + + grid + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/dynaforms/fields_ToolbarGrid.xml b/workflow/engine/xmlform/dynaforms/fields_ToolbarGrid.xml new file mode 100644 index 000000000..0b9594709 --- /dev/null +++ b/workflow/engine/xmlform/dynaforms/fields_ToolbarGrid.xml @@ -0,0 +1,56 @@ + + + + + + + save + + + + + save as + + + + + + text + + + currency + + + percentage + + + + + + + dropdown + + + yesno + + + + + + + date + + + hidden + + + link + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/appEventsList.xml b/workflow/engine/xmlform/events/appEventsList.xml new file mode 100644 index 000000000..639ed4f1f --- /dev/null +++ b/workflow/engine/xmlform/events/appEventsList.xml @@ -0,0 +1,30 @@ + + + + + + + Task + + + + Case Title + + + + Action date + + + + Event Description + + + + Event type + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/appEventsListCompleted.xml b/workflow/engine/xmlform/events/appEventsListCompleted.xml new file mode 100644 index 000000000..a2890fd89 --- /dev/null +++ b/workflow/engine/xmlform/events/appEventsListCompleted.xml @@ -0,0 +1,30 @@ + + + + + + + Case Title + + + + Action date + + + + Last Execution + + + + Event Description + + + + Event type + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/dynavarsList.xml b/workflow/engine/xmlform/events/dynavarsList.xml new file mode 100755 index 000000000..4a6a7e319 --- /dev/null +++ b/workflow/engine/xmlform/events/dynavarsList.xml @@ -0,0 +1,11 @@ + + + + + Var. name + + + Dynaform + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsEdit.html b/workflow/engine/xmlform/events/eventsEdit.html new file mode 100644 index 000000000..8ef6c5f32 --- /dev/null +++ b/workflow/engine/xmlform/events/eventsEdit.html @@ -0,0 +1,100 @@ +
    + + + + {$form.PRO_UID} {$form.EVN_UID} +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {$form.TITLE} +
    * {$EVN_DESCRIPTION}{$form.EVN_DESCRIPTION}
    {$EVN_STATUS}{$form.EVN_STATUS}
    + {$form.SUBTITLE1} +
    {$EVN_RELATED_TO}{$form.EVN_RELATED_TO}
    {$TAS_UID}{$form.TAS_UID}
    {$EVN_TAS_UID_FROM}{$form.EVN_TAS_UID_FROM} {$EVN_TAS_UID_TO} {$form.EVN_TAS_UID_TO}
    {$EVN_TAS_ESTIMATED_DURATION}{$form.EVN_TAS_ESTIMATED_DURATION} {$EVN_WHEN}
    * {$EVN_WHEN_OCCURS}{$form.EVN_WHEN} {$EVN_WHEN} {$form.EVN_WHEN_OCCURS}
    {$EVN_ACTION} + {$form.TRI_UID}{$form.EVN_ACTION} +
    {$EVN_CONDITIONS} + {$form.EVN_CONDITIONS} + +
    + {$form.TITLE3} +
    + +
    {$form.CONTINUE}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsEdit.xml b/workflow/engine/xmlform/events/eventsEdit.xml new file mode 100644 index 000000000..b3057199b --- /dev/null +++ b/workflow/engine/xmlform/events/eventsEdit.xml @@ -0,0 +1,176 @@ + + + + + + + + + + <en></en> + + + + + + + + Description + + + + Status + + + + Behaviour + + + + Execution time + + + + Type + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + The time starts with task + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + The time starts from task + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + To + + + + Estimated Task duration + + + + days + + + + Action + + + + Condition + + + + Execute trigger + + + + + + + + SELECT * FROM TMP_TRIGGERS + + + + + + Event scheduled graph + + + + Cancel + + + + Save + + + + + + diff --git a/workflow/engine/xmlform/events/eventsEditAction.html b/workflow/engine/xmlform/events/eventsEditAction.html new file mode 100755 index 000000000..c214db759 --- /dev/null +++ b/workflow/engine/xmlform/events/eventsEditAction.html @@ -0,0 +1,150 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.EVN_UID}
    {$form.PRO_UID}
    {$form.EVN_DESCRIPTION}
    {$form.EVN_RELATED_TO}
    {$form.TAS_UID}
    {$form.EVN_TAS_UID_FROM}
    {$form.EVN_TAS_UID_TO}
    {$form.EVN_TAS_ESTIMATED_DURATION}
    {$form.EVN_WHEN_OCCURS}
    {$form.EVN_STATUS}
    {$form.EVN_WHEN}
    {$form.EVN_ACTION}
    * {$EVN_MESSAGE_SUBJECT}{$form.EVN_MESSAGE_SUBJECT}
    {$form.title1}
    {$EVN_MESSAGE_TO_TO} + + + + + + + + + + + + + + + +
    {$form.EVN_MESSAGE_TO_TO_SIMPLEADD}
    {$form.EVN_MESSAGE_TO_TO}
     
    +
    {$form.title2}
    {$EVN_MESSAGE_TO_CC} + + + + + + + + + + + + + + + +
    {$form.EVN_MESSAGE_TO_CC_SIMPLEADD}
    {$form.EVN_MESSAGE_TO_CC}
     
    +
    {$form.title3}
    {$EVN_MESSAGE_TO_BCC} + + + + + + + + + + + + + + + +
    {$form.EVN_MESSAGE_TO_BCC_SIMPLEADD}
    {$form.EVN_MESSAGE_TO_BCC}
     
    +
    {$EVN_MESSAGE_TEMPLATE}{$form.EVN_MESSAGE_TEMPLATE}
    {$TRI_UID}{$form.TRI_UID}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    + + + diff --git a/workflow/engine/xmlform/events/eventsEditAction.xml b/workflow/engine/xmlform/events/eventsEditAction.xml new file mode 100644 index 000000000..b7441a609 --- /dev/null +++ b/workflow/engine/xmlform/events/eventsEditAction.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Subject + + + + + + + + Send to + + + + + SELECT id,name FROM eventomsgto + TO + + + + Carbon Copy + + + + SELECT id,name FROM eventomsgcc + CC + + + + Blind Carbon Copy + + + + SELECT id,name FROM eventomsgbcc + BCC + + + +SELECT TEMPLATE1, TEMPLATE2 FROM templates + E-Mail Template + + + +SELECT TRI_UID, TRI_TITLE FROM triggers + Trigger + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsNew.html b/workflow/engine/xmlform/events/eventsNew.html new file mode 100644 index 000000000..8ef6c5f32 --- /dev/null +++ b/workflow/engine/xmlform/events/eventsNew.html @@ -0,0 +1,100 @@ +
    + + + + {$form.PRO_UID} {$form.EVN_UID} +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + {$form.TITLE} +
    * {$EVN_DESCRIPTION}{$form.EVN_DESCRIPTION}
    {$EVN_STATUS}{$form.EVN_STATUS}
    + {$form.SUBTITLE1} +
    {$EVN_RELATED_TO}{$form.EVN_RELATED_TO}
    {$TAS_UID}{$form.TAS_UID}
    {$EVN_TAS_UID_FROM}{$form.EVN_TAS_UID_FROM} {$EVN_TAS_UID_TO} {$form.EVN_TAS_UID_TO}
    {$EVN_TAS_ESTIMATED_DURATION}{$form.EVN_TAS_ESTIMATED_DURATION} {$EVN_WHEN}
    * {$EVN_WHEN_OCCURS}{$form.EVN_WHEN} {$EVN_WHEN} {$form.EVN_WHEN_OCCURS}
    {$EVN_ACTION} + {$form.TRI_UID}{$form.EVN_ACTION} +
    {$EVN_CONDITIONS} + {$form.EVN_CONDITIONS} + +
    + {$form.TITLE3} +
    + +
    {$form.CONTINUE}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsNew.xml b/workflow/engine/xmlform/events/eventsNew.xml new file mode 100644 index 000000000..ddc0a53bd --- /dev/null +++ b/workflow/engine/xmlform/events/eventsNew.xml @@ -0,0 +1,178 @@ + + + + + + + + + + <en></en> + + + + + + + + Description + + + + Status + + + + Behaviour + + + + Execution time + + + + Type + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + The time starts with task + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + The time starts from task + + + +SELECT TAS_UID, TAS_TITLE FROM tasks + To + + + + Estimated Task duration + + + + days + + + + Action + + + + + Condition + + + + Execute trigger + + + + + + + + SELECT * FROM TMP_TRIGGERS + + + + + + + Event scheduled graph + + + + Cancel + + + + Continue + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsOptions.xml b/workflow/engine/xmlform/events/eventsOptions.xml new file mode 100644 index 000000000..30e2c41ae --- /dev/null +++ b/workflow/engine/xmlform/events/eventsOptions.xml @@ -0,0 +1,157 @@ + + + + + New + + + + Pending + + + + Completed + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/eventsShortList.xml b/workflow/engine/xmlform/events/eventsShortList.xml new file mode 100644 index 000000000..fe2431992 --- /dev/null +++ b/workflow/engine/xmlform/events/eventsShortList.xml @@ -0,0 +1,28 @@ + + + + + + + Description + + + + When occurs + + + + Type + + + + Status + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/groupmailList.xml b/workflow/engine/xmlform/events/groupmailList.xml new file mode 100755 index 000000000..6668b0ad3 --- /dev/null +++ b/workflow/engine/xmlform/events/groupmailList.xml @@ -0,0 +1,12 @@ + + + + + + + Group name + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/events/usermailList.xml b/workflow/engine/xmlform/events/usermailList.xml new file mode 100755 index 000000000..33fc5ccab --- /dev/null +++ b/workflow/engine/xmlform/events/usermailList.xml @@ -0,0 +1,16 @@ + + + + + + + Fullname + + + + email + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_AddUser.xml b/workflow/engine/xmlform/groups/groups_AddUser.xml new file mode 100644 index 000000000..6fcbb9da0 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_AddUser.xml @@ -0,0 +1,19 @@ + + + + + <en>User</en> + + + + SELECT USR_UID, USR_USERNAME FROM USERS + User + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_AvailableUsers.xml b/workflow/engine/xmlform/groups/groups_AvailableUsers.xml new file mode 100644 index 000000000..9bb69e04c --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_AvailableUsers.xml @@ -0,0 +1,25 @@ + + + + + + + + + Firstname + + + + Lastname + + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_Edit.html b/workflow/engine/xmlform/groups/groups_Edit.html new file mode 100644 index 000000000..fd0fb1d99 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_Edit.html @@ -0,0 +1,46 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.title}
    {$form.GRP_UID}
    * {$GRP_TITLE}{$form.GRP_TITLE}
    {$GRP_STATUS}{$form.GRP_STATUS}
    {$form.button}   {$form.BTN_CANCEL}
    +
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_Edit.xml b/workflow/engine/xmlform/groups/groups_Edit.xml new file mode 100644 index 000000000..5e98fbcc2 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_Edit.xml @@ -0,0 +1,91 @@ + + + + + <en>Group Information</en> + + + + + + + Name + + + + Status + + + + Cancel + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_List.xml b/workflow/engine/xmlform/groups/groups_List.xml new file mode 100644 index 000000000..bfea35078 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_List.xml @@ -0,0 +1,23 @@ + + + + + <en>Group properties</en> + + + + + + + Group + + + + Status + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_Options.xml b/workflow/engine/xmlform/groups/groups_Options.xml new file mode 100644 index 000000000..74dc0e0f6 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_Options.xml @@ -0,0 +1,13 @@ + + + + + + + + + Assign + Asignar + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_Search.xml b/workflow/engine/xmlform/groups/groups_Search.xml new file mode 100644 index 000000000..c8811645a --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_Search.xml @@ -0,0 +1,25 @@ + + + + + User name + + + + User name} + + +var currentPagedTable = @#PAGED_TABLE_ID; + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_SelectUsers.xml b/workflow/engine/xmlform/groups/groups_SelectUsers.xml new file mode 100644 index 000000000..0ccc0e34c --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_SelectUsers.xml @@ -0,0 +1,8 @@ + + + + + Assign + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_UsersList.xml b/workflow/engine/xmlform/groups/groups_UsersList.xml new file mode 100644 index 000000000..bbb4e1b45 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_UsersList.xml @@ -0,0 +1,21 @@ + + + + + + + Username + + + + First Name + + + + Last Name + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_UsersListTitle.xml b/workflow/engine/xmlform/groups/groups_UsersListTitle.xml new file mode 100644 index 000000000..d941ac3b5 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_UsersListTitle.xml @@ -0,0 +1,10 @@ + + + + + + +@#GRP_NAME + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/groups/groups_userSearch.xml b/workflow/engine/xmlform/groups/groups_userSearch.xml new file mode 100644 index 000000000..5c43145c9 --- /dev/null +++ b/workflow/engine/xmlform/groups/groups_userSearch.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/gulliver/dynaforms_Options.xml b/workflow/engine/xmlform/gulliver/dynaforms_Options.xml new file mode 100644 index 000000000..584f49bad --- /dev/null +++ b/workflow/engine/xmlform/gulliver/dynaforms_Options.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + Previous Step + + + + + Next Step + + \ No newline at end of file diff --git a/workflow/engine/xmlform/gulliver/dynaforms_OptionsPrint.xml b/workflow/engine/xmlform/gulliver/dynaforms_OptionsPrint.xml new file mode 100755 index 000000000..5d842105f --- /dev/null +++ b/workflow/engine/xmlform/gulliver/dynaforms_OptionsPrint.xml @@ -0,0 +1,20 @@ + + + + + + + + + Print form + + + + Previous Step + + + + + Next Step + + \ No newline at end of file diff --git a/workflow/engine/xmlform/gulliver/pagedTable_Options.xml b/workflow/engine/xmlform/gulliver/pagedTable_Options.xml new file mode 100644 index 000000000..660e82d05 --- /dev/null +++ b/workflow/engine/xmlform/gulliver/pagedTable_Options.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/gulliver/pagedTable_PopupMenu.xml b/workflow/engine/xmlform/gulliver/pagedTable_PopupMenu.xml new file mode 100644 index 000000000..220a36adc --- /dev/null +++ b/workflow/engine/xmlform/gulliver/pagedTable_PopupMenu.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_AvailableSupervisorInputs.xml b/workflow/engine/xmlform/inputdocs/inputdocs_AvailableSupervisorInputs.xml new file mode 100644 index 000000000..c77852091 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_AvailableSupervisorInputs.xml @@ -0,0 +1,27 @@ + + + + + + + + + Title + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_Edit.html b/workflow/engine/xmlform/inputdocs/inputdocs_Edit.html new file mode 100644 index 000000000..445f33638 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_Edit.html @@ -0,0 +1,68 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$form.INP_DOC_UID}
    {$form.TITLE}
    {$INP_DOC_TITLE}{$form.INP_DOC_TITLE}
    {$INP_DOC_FORM_NEEDED}{$form.INP_DOC_FORM_NEEDED}
    {$INP_DOC_ORIGINAL}{$form.INP_DOC_ORIGINAL}
    {$INP_DOC_DESCRIPTION}{$form.INP_DOC_DESCRIPTION}
    {$INP_DOC_VERSIONING}{$form.INP_DOC_VERSIONING}
    {$INP_DOC_DESTINATION_PATH}{$form.INP_DOC_DESTINATION_PATH}
    {$INP_DOC_TAGS}{$form.INP_DOC_TAGS}

    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_Edit.xml b/workflow/engine/xmlform/inputdocs/inputdocs_Edit.xml new file mode 100644 index 000000000..52c893df0 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_Edit.xml @@ -0,0 +1,122 @@ + + + + + + + + + <en>Input Document Information</en> + + + + Title + + + + Document Type + + + + Format + + + + + + Description + + + + Enable Versioning + + + + Destination Path + + + Tags + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_List.xml b/workflow/engine/xmlform/inputdocs/inputdocs_List.xml new file mode 100644 index 000000000..71505fed8 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_List.xml @@ -0,0 +1,36 @@ + + + + + + Input document + + + Type + + + + Original + + + + Access type + + + Description + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_Options.xml b/workflow/engine/xmlform/inputdocs/inputdocs_Options.xml new file mode 100644 index 000000000..c9b9029d0 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_Options.xml @@ -0,0 +1,55 @@ + + + + + New + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_ShortList.xml b/workflow/engine/xmlform/inputdocs/inputdocs_ShortList.xml new file mode 100644 index 000000000..70f3e7718 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_ShortList.xml @@ -0,0 +1,29 @@ + + + + + + + Title + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter(form) { + @#PAGED_TABLE_ID.doFilter(form); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_Supervisor.xml b/workflow/engine/xmlform/inputdocs/inputdocs_Supervisor.xml new file mode 100644 index 000000000..7b8f0cfea --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_Supervisor.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + Title + + + + + + + Apply Filter + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/inputdocs/inputdocs_SupervisorOptions.xml b/workflow/engine/xmlform/inputdocs/inputdocs_SupervisorOptions.xml new file mode 100644 index 000000000..9c0e08ba2 --- /dev/null +++ b/workflow/engine/xmlform/inputdocs/inputdocs_SupervisorOptions.xml @@ -0,0 +1,76 @@ + + + + + + + Assign + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/changePassword.xml b/workflow/engine/xmlform/login/changePassword.xml new file mode 100644 index 000000000..8ab49df6f --- /dev/null +++ b/workflow/engine/xmlform/login/changePassword.xml @@ -0,0 +1,75 @@ + + + + Change password + + + + @#DESCRIPTION + + + Password + + + Re-Type Password + + + Save + + + + + + + parseInt(oAux.value)) { + alert('@G::LoadTranslation(ID_PPP_MAXIMUN_LENGTH)' + ': ' + oAux.value); + return; + } + } + var oAux = getField('PPP_NUMERICAL_CHARACTER_REQUIRED'); + if (oAux.value != '') { + var sER = /[0-9]/; + if (!sER.test(oPassword1.value)) { + alert('@G::LoadTranslation(ID_PPP_NUMERICAL_CHARACTER_REQUIRED)'); + return; + } + } + var oAux = getField('PPP_UPPERCASE_CHARACTER_REQUIRED'); + if (oAux.value != '') { + var sER = /[A-Z]/; + if (!sER.test(oPassword1.value)) { + alert('@G::LoadTranslation(ID_PPP_UPPERCASE_CHARACTER_REQUIRED)'); + return; + } + } + var oAux = getField('PPP_SPECIAL_CHARACTER_REQUIRED'); + if (oAux.value != '') { + var sER = /[ºª\\!|"@·#$~%€&¬\/()=\'?¡¿*+\-_.:,;]/; + if (!sER.test(oPassword1.value)) { + alert('@G::LoadTranslation(ID_PPP_SPECIAL_CHARACTER_REQUIRED)'); + return; + } + } + oPassword1.form.submit(); +}; + +]]> + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/dbInfo.xml b/workflow/engine/xmlform/login/dbInfo.xml new file mode 100644 index 000000000..981fb4748 --- /dev/null +++ b/workflow/engine/xmlform/login/dbInfo.xml @@ -0,0 +1,43 @@ + + + + System Information + + + ProcessMaker +ProcessMaker + + Operating System +Sistema operativo + + + Web Server +Servidor Web + + Server Name +Nombre del servidor + + Server IP Address +IP del servidor + + PHP version + + + Database +Base de Datos + + Database Server IP Address + + + Database Name +Nombre de la Base de Datos + + Available Databases +Bases de datos disponibles + + +Navegador del usuario + + +IP del usuario + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/login.xml b/workflow/engine/xmlform/login/login.xml new file mode 100644 index 000000000..3ada13a8d --- /dev/null +++ b/workflow/engine/xmlform/login/login.xml @@ -0,0 +1,127 @@ + + + + <en>Login</en> + + + User + + + Password + + + SELECT LANG_ID, LANG_NAME FROM langOptions + Language + + + + + Login + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/newSite.xml b/workflow/engine/xmlform/login/newSite.xml new file mode 100644 index 000000000..d7cde7557 --- /dev/null +++ b/workflow/engine/xmlform/login/newSite.xml @@ -0,0 +1,167 @@ + + + + New Workspace + + + Name + + + Database Options + + + Workflow Database: + + + Rbac Database: + + + Report Database: + + + Drop database if exists + + + Workspace Administrator + + + + Username: + + + Password (admin): + + + Re-type Password: + + + + Test + +"+ G_STRINGS.NEW_SITE_SUCCESS_CONFIRM+"
    "+ G_STRINGS.NEW_SITE_SUCCESS_CONFIRMNOTE, + action: function(){ + + parent.parent.window.location="/sys"+data.name.value+"/en/green/login/login"; + + /* if (typeof(window.parent.admToolsContent) != 'undefined'){ + + parent.parent.window.location="/sys"+data.name.value+"/en/green/login/login"; + } else { + setTimeout('redirectLogin()', 1000); + }*/ + }.extend(this), + cancel: function(){ + + //window.location="../install/newSite?type=blank"; + }, + width:380, + height:140 + }); + + data.goto.enable(); + data.submit.disable(); + data.reset.disable(); + } + }; + data.name.focus(); + leimnud.event.add(data.name,'keyup',function(){ + var v = data.name.value; + data.ao_db_wf.value='wf_'+v; + data.ao_db_rb.value='rb_'+v; + data.ao_db_rp.value='rp_'+v; + }); + data.submit.onmouseup=function() + { + ed('disable'); + }; + //data.name.passed(); + + function redirectLogin(){ + location.href="/sys"+data.name.value+"/en/green/login/login"; + } +]]>
    +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/login/noViewPage.xml b/workflow/engine/xmlform/login/noViewPage.xml new file mode 100644 index 000000000..5dd6f963a --- /dev/null +++ b/workflow/engine/xmlform/login/noViewPage.xml @@ -0,0 +1,16 @@ + +Login to system + + + <en><![CDATA[You don\'t have permission]]></en> + + + + The account you are logged in under does not have enough security privileges to view this page + + + + Please press back button to continue working with this system. + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/nologin.xml b/workflow/engine/xmlform/login/nologin.xml new file mode 100644 index 000000000..ac55138e0 --- /dev/null +++ b/workflow/engine/xmlform/login/nologin.xml @@ -0,0 +1,22 @@ + +Login to system + + + [CDATA] +
    Your session has expired.
    + [/CDATA]
    +
    + + + + + + + + + + + + Login + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/login/showInfo.xml b/workflow/engine/xmlform/login/showInfo.xml new file mode 100755 index 000000000..94dc685c0 --- /dev/null +++ b/workflow/engine/xmlform/login/showInfo.xml @@ -0,0 +1,9 @@ + + + + <en>Information</en> + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/showInfoUpdate.xml b/workflow/engine/xmlform/login/showInfoUpdate.xml new file mode 100644 index 000000000..4a3e81dcf --- /dev/null +++ b/workflow/engine/xmlform/login/showInfoUpdate.xml @@ -0,0 +1,29 @@ + + + + + Information + + + + + Affected Files + + + + + Errors + + + + + Environments Updated + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/showMessage.xml b/workflow/engine/xmlform/login/showMessage.xml new file mode 100644 index 000000000..bd9ce51f1 --- /dev/null +++ b/workflow/engine/xmlform/login/showMessage.xml @@ -0,0 +1,9 @@ + + + + <en>Error</en> + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/sysLogin.xml b/workflow/engine/xmlform/login/sysLogin.xml new file mode 100644 index 000000000..e339b222d --- /dev/null +++ b/workflow/engine/xmlform/login/sysLogin.xml @@ -0,0 +1,53 @@ + + + + <en>Login</en> + + + + User + + + + Password + + + +SELECT ENV_ID, ENV_NAME FROM availableWorkspace +Workspace + + + +SELECT LANG_ID, LANG_NAME FROM langOptions +Language + + + + Login + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/login/sysLoginNoWS.xml b/workflow/engine/xmlform/login/sysLoginNoWS.xml new file mode 100644 index 000000000..dde3fe4ce --- /dev/null +++ b/workflow/engine/xmlform/login/sysLoginNoWS.xml @@ -0,0 +1,52 @@ + + + + <en>Login</en> + + + + User + + + + Password + + + +Workspace + + + +SELECT LANG_ID, LANG_NAME FROM langOptions +Language + + + + Login + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/messages/messages_Edit.xml b/workflow/engine/xmlform/messages/messages_Edit.xml new file mode 100644 index 000000000..ce6b0da66 --- /dev/null +++ b/workflow/engine/xmlform/messages/messages_Edit.xml @@ -0,0 +1,19 @@ + + + + + + Message Title + + + Send as + + + + Content + + + + Save + + \ No newline at end of file diff --git a/workflow/engine/xmlform/messages/messages_List.xml b/workflow/engine/xmlform/messages/messages_List.xml new file mode 100644 index 000000000..a9fcc3d7a --- /dev/null +++ b/workflow/engine/xmlform/messages/messages_List.xml @@ -0,0 +1,28 @@ + + + + + Output document + + + + Type + + + Content + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/messages/messages_Options.xml b/workflow/engine/xmlform/messages/messages_Options.xml new file mode 100644 index 000000000..e06ce585e --- /dev/null +++ b/workflow/engine/xmlform/messages/messages_Options.xml @@ -0,0 +1,34 @@ + + + + + New + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/messages/messages_ShortList.xml b/workflow/engine/xmlform/messages/messages_ShortList.xml new file mode 100644 index 000000000..654ae3ed2 --- /dev/null +++ b/workflow/engine/xmlform/messages/messages_ShortList.xml @@ -0,0 +1,21 @@ + + + + + Output document + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocsDynaformList.xml b/workflow/engine/xmlform/outputdocs/outputdocsDynaformList.xml new file mode 100755 index 000000000..d96e94e2a --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocsDynaformList.xml @@ -0,0 +1,23 @@ + + + + + + +Dynaform + + + + Template + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocsUploadFile.xml b/workflow/engine/xmlform/outputdocs/outputdocsUploadFile.xml new file mode 100644 index 000000000..8cb9fc477 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocsUploadFile.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + Download + + + + Click in the link to download current file + + + + Upload + + + + Upload a modified file + + + + upload + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_Edit.html b/workflow/engine/xmlform/outputdocs/outputdocs_Edit.html new file mode 100644 index 000000000..ba4b888da --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_Edit.html @@ -0,0 +1,39 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    {$form.INSERT_VARIABLE}
    {$form.PRO_UID}
    {$form.OUT_DOC_UID}
    {$form.OUT_DOC_TEMPLATE}

    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_Edit.xml b/workflow/engine/xmlform/outputdocs/outputdocs_Edit.xml new file mode 100644 index 000000000..c7cfe06e1 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_Edit.xml @@ -0,0 +1,135 @@ + + + + + @# + + + + + + + + + + Save + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_List.xml b/workflow/engine/xmlform/outputdocs/outputdocs_List.xml new file mode 100644 index 000000000..0cd923a13 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_List.xml @@ -0,0 +1,27 @@ + + + + + Output document + + + Filename + + + Description + + + + + + + + Apply Filter + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_New.xml b/workflow/engine/xmlform/outputdocs/outputdocs_New.xml new file mode 100755 index 000000000..4fe549ad5 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_New.xml @@ -0,0 +1,109 @@ + + + + + + + + + <en>Output Document Information</en> + + + + Type of Output Document + + +Dynaform + + + + Title + + + + Filename generated + + + + Description + + + + + + + + + + Template + + + + Save + + + Save submit + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_Options.xml b/workflow/engine/xmlform/outputdocs/outputdocs_Options.xml new file mode 100644 index 000000000..45b1b6031 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_Options.xml @@ -0,0 +1,103 @@ + + + + + New + + + + +]]> + + + + + + + + diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_Properties.html b/workflow/engine/xmlform/outputdocs/outputdocs_Properties.html new file mode 100644 index 000000000..cb0660865 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_Properties.html @@ -0,0 +1,106 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$form.OUT_DOC_UID}
    {$form.TITLE}
    * {$OUT_DOC_TITLE}{$form.OUT_DOC_TITLE}
    * {$OUT_DOC_FILENAME}{$form.OUT_DOC_FILENAME}
    {$OUT_DOC_DESCRIPTION}{$form.OUT_DOC_DESCRIPTION}
    {$OUT_DOC_LANDSCAPE}{$form.OUT_DOC_LANDSCAPE}
    {$OUT_DOC_MEDIA}{$form.OUT_DOC_MEDIA}
    {$OUT_DOC_LEFT_MARGIN}{$form.OUT_DOC_LEFT_MARGIN}
    {$OUT_DOC_RIGHT_MARGIN}{$form.OUT_DOC_RIGHT_MARGIN}
    {$OUT_DOC_TOP_MARGIN}{$form.OUT_DOC_TOP_MARGIN}
    {$OUT_DOC_BOTTOM_MARGIN}{$form.OUT_DOC_BOTTOM_MARGIN}
    {$OUT_DOC_GENERATE}{$form.OUT_DOC_GENERATE}
    {$OUT_DOC_VERSIONING}{$form.OUT_DOC_VERSIONING}
    {$OUT_DOC_DESTINATION_PATH}{$form.OUT_DOC_DESTINATION_PATH}
    {$OUT_DOC_TAGS}{$form.OUT_DOC_TAGS}

    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    + +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_Properties.xml b/workflow/engine/xmlform/outputdocs/outputdocs_Properties.xml new file mode 100644 index 000000000..792d69498 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_Properties.xml @@ -0,0 +1,176 @@ + + + + + + + + + <en>Output Document Information</en> + + + + Title + + + + Filename generated + + + + Description + + + + Orientation + + + + Output Document to Generate + + + + Enable Versioning + + + + Media + + + + + + + + + + + + + + + + + + + + + + + + + Left Margin + + + Right Margin + + + Top Margin + + + Bottom Margin + + + Destination Path + + + Tags + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/outputdocs/outputdocs_ShortList.xml b/workflow/engine/xmlform/outputdocs/outputdocs_ShortList.xml new file mode 100644 index 000000000..8fce0f034 --- /dev/null +++ b/workflow/engine/xmlform/outputdocs/outputdocs_ShortList.xml @@ -0,0 +1,35 @@ + + + + + + + Title + + + + Type + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter(form) { + @#PAGED_TABLE_ID.doFilter(form); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Current.html b/workflow/engine/xmlform/patterns/patterns_Current.html new file mode 100644 index 000000000..2e3265f46 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Current.html @@ -0,0 +1,62 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$ROU_TYPE}{$form.ROU_TYPE}
    {$ROU_NEXT_TASK}{$form.ROU_NEXT_TASK}
    {$ROU_TO_LAST_USER}{$form.ROU_TO_LAST_USER}
    {$form.GRID_SELECT_TYPE}
    {$form.GRID_EVALUATE_TYPE}
    {$form.GRID_PARALLEL_TYPE}
    {$form.GRID_PARALLEL_EVALUATION_TYPE}
    {$form.SAVE}
    +
    +
    +
    +
    + diff --git a/workflow/engine/xmlform/patterns/patterns_Current.xml b/workflow/engine/xmlform/patterns/patterns_Current.xml new file mode 100644 index 000000000..b808ed4b4 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Current.xml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + <en>Workflow Pattern</en> + + + + Type + + +Next Task + + + + Selection of executant + + + + + + + + + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Evaluate.html b/workflow/engine/xmlform/patterns/patterns_Evaluate.html new file mode 100644 index 000000000..b25486921 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Evaluate.html @@ -0,0 +1,49 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$form.ROU_TYPE}
    {$form.GRID_EVALUATE_TYPE}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Evaluate.xml b/workflow/engine/xmlform/patterns/patterns_Evaluate.xml new file mode 100644 index 000000000..40ac11ba3 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Evaluate.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + <en>Evaluation</en> + + + + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_GridEvaluateType.xml b/workflow/engine/xmlform/patterns/patterns_GridEvaluateType.xml new file mode 100644 index 000000000..2b4784f70 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_GridEvaluateType.xml @@ -0,0 +1,14 @@ + + + +Next Task + + + + Condition + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_GridParallelByEvaluationType.xml b/workflow/engine/xmlform/patterns/patterns_GridParallelByEvaluationType.xml new file mode 100644 index 000000000..70cbfb0a0 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_GridParallelByEvaluationType.xml @@ -0,0 +1,13 @@ + + + +Next Task + + + + Condition + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_GridParallelType.xml b/workflow/engine/xmlform/patterns/patterns_GridParallelType.xml new file mode 100644 index 000000000..538eb3445 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_GridParallelType.xml @@ -0,0 +1,9 @@ + + + +Next Task + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_GridSelectType.xml b/workflow/engine/xmlform/patterns/patterns_GridSelectType.xml new file mode 100644 index 000000000..293091053 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_GridSelectType.xml @@ -0,0 +1,14 @@ + + + +Next Task + + + + Description + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Parallel.html b/workflow/engine/xmlform/patterns/patterns_Parallel.html new file mode 100644 index 000000000..76cf6a767 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Parallel.html @@ -0,0 +1,49 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$form.ROU_TYPE}
    {$form.GRID_PARALLEL_TYPE}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Parallel.xml b/workflow/engine/xmlform/patterns/patterns_Parallel.xml new file mode 100644 index 000000000..2513b5a19 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Parallel.xml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + <en>Parallel</en> + + + + + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.html b/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.html new file mode 100644 index 000000000..89dbc8d09 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.html @@ -0,0 +1,50 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$form.ROU_TYPE}
    {$form.GRID_PARALLEL_EVALUATION_TYPE}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.xml b/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.xml new file mode 100644 index 000000000..b01e8cc88 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_ParallelByEvaluation.xml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + <en>Parallel By Evaluation</en> + + + + + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_ParallelJoin.xml b/workflow/engine/xmlform/patterns/patterns_ParallelJoin.xml new file mode 100644 index 000000000..93112ce19 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_ParallelJoin.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + <en>Parallel Join</en> + + + + +Next Task + + + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Select.html b/workflow/engine/xmlform/patterns/patterns_Select.html new file mode 100644 index 000000000..20d57f517 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Select.html @@ -0,0 +1,51 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$form.ROU_TYPE}
    {$form.GRID_SELECT_TYPE}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Select.xml b/workflow/engine/xmlform/patterns/patterns_Select.xml new file mode 100644 index 000000000..935b0711c --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Select.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + <en>Selection</en> + + + + + + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Sequential.html b/workflow/engine/xmlform/patterns/patterns_Sequential.html new file mode 100644 index 000000000..549abd57f --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Sequential.html @@ -0,0 +1,50 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.action}
    {$form.ROU_UID}
    {$form.PROCESS}
    {$form.TASK}
    {$form.ROU_TYPE_OLD}
    {$form.TITLE}
    {$form.ROU_TYPE}
    {$ROU_NEXT_TASK}{$form.ROU_NEXT_TASK}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/patterns/patterns_Sequential.xml b/workflow/engine/xmlform/patterns/patterns_Sequential.xml new file mode 100644 index 000000000..a9b086b83 --- /dev/null +++ b/workflow/engine/xmlform/patterns/patterns_Sequential.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + <en>Sequential</en> + + + + +Next Task + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategory.xml b/workflow/engine/xmlform/processCategory/processCategory.xml new file mode 100755 index 000000000..f1b5aa397 --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategory.xml @@ -0,0 +1,33 @@ + + + + + ProcessCategory form + + + + Gory Uid + + + + + Gory Parent + + + + + Gory Name + + + + + Gory Icon + + + + + + save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategoryDelete.html b/workflow/engine/xmlform/processCategory/processCategoryDelete.html new file mode 100644 index 000000000..e467c5b7a --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryDelete.html @@ -0,0 +1,39 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    {$form.title1}
    {$form.CATEGORY_NAME }
    {$LABEL_CATEGORY_NAME}{$form.LABEL_CATEGORY_NAME }

    {$form.BTN_SUBMIT}   {$form.BTN_CANCEL }
    +
    +
    + +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategoryDelete.xml b/workflow/engine/xmlform/processCategory/processCategoryDelete.xml new file mode 100755 index 000000000..1706be154 --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryDelete.xml @@ -0,0 +1,31 @@ + + + + + Delete Process Category + + + + + + Category Name + + + + + + + delete + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategoryEdit.html b/workflow/engine/xmlform/processCategory/processCategoryEdit.html new file mode 100644 index 000000000..0264a965d --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryEdit.html @@ -0,0 +1,48 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title1}
    {$form.CATEGORY_UID }
    {$form.CATEGORY_PARENT}
    * {$CATEGORY_NAME }{$form.CATEGORY_NAME }
    {$form.CATEGORY_ICON}

    {$form.BTN_SUBMIT}   {$form.BTN_CANCEL }
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    +
    + +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategoryEdit.xml b/workflow/engine/xmlform/processCategory/processCategoryEdit.xml new file mode 100755 index 000000000..b7d6967ac --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryEdit.xml @@ -0,0 +1,56 @@ + + + + Process Category form + + + + category Uid + + + Gory Parent + + + Category Name + + + + + Category Icon + + + + save + + + + Cancel + + + + diff --git a/workflow/engine/xmlform/processCategory/processCategoryList.xml b/workflow/engine/xmlform/processCategory/processCategoryList.xml new file mode 100755 index 000000000..f4c6839d7 --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryList.xml @@ -0,0 +1,25 @@ + + + + + Gory Parent + + + + Category Name + + + + Category Icon + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processCategory/processCategoryOptions.xml b/workflow/engine/xmlform/processCategory/processCategoryOptions.xml new file mode 100755 index 000000000..6ad9d02b7 --- /dev/null +++ b/workflow/engine/xmlform/processCategory/processCategoryOptions.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/objectpmView.xml b/workflow/engine/xmlform/processes/objectpmView.xml new file mode 100644 index 000000000..4d50a8a94 --- /dev/null +++ b/workflow/engine/xmlform/processes/objectpmView.xml @@ -0,0 +1,136 @@ + + + + + Process Properties + + + + + + <en>Title</en> + + + + Version + + + + P.M. rev. required + + + + Category + + + + + + Rating + + + + Downloads + + + + Subscriptions + + + + Author + + + + Privacy + + + + + + + + + Create Date + + + + Update Date + + + + Description + + + + Install Steps + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Assignuser.xml b/workflow/engine/xmlform/processes/processes_Assignuser.xml new file mode 100644 index 000000000..1c2d7a354 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Assignuser.xml @@ -0,0 +1,74 @@ + + + + + + + Assign + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_DeleteCases.xml b/workflow/engine/xmlform/processes/processes_DeleteCases.xml new file mode 100644 index 000000000..3be148962 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_DeleteCases.xml @@ -0,0 +1,32 @@ + + + + + + + + + Are you sure that you want to delete this process? + + + + + + + + To Do + + + + Completed + + + + Draft + + + + Cancelled + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_DirectoriesList.xml b/workflow/engine/xmlform/processes/processes_DirectoriesList.xml new file mode 100644 index 000000000..355744e73 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_DirectoriesList.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_DirectoriesOptions.xml b/workflow/engine/xmlform/processes/processes_DirectoriesOptions.xml new file mode 100644 index 000000000..02763d136 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_DirectoriesOptions.xml @@ -0,0 +1,86 @@ + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Edit.html b/workflow/engine/xmlform/processes/processes_Edit.html new file mode 100644 index 000000000..eb964112a --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Edit.html @@ -0,0 +1,58 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.PRO_UID}
    {$form.THETYPE}
    * {$PRO_TITLE}{$form.PRO_TITLE}
    {$PRO_DESCRIPTION}{$form.PRO_DESCRIPTION}
    {$PRO_CALENDAR}{$form.PRO_CALENDAR}
    {$PRO_CATEGORY}{$form.PRO_CATEGORY}
    {$PRO_DEBUG}{$form.PRO_DEBUG}

    {$form.SUBMIT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Edit.xml b/workflow/engine/xmlform/processes/processes_Edit.xml new file mode 100644 index 000000000..ffab4f1cc --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Edit.xml @@ -0,0 +1,70 @@ + + + + + Process Information + + + + + + + + Title + + + + + Description + + +SELECT CALENDAR_UID, CALENDAR_NAME FROM availableCalendars +Calendar + + + +SELECT CATEGORY_UID, CATEGORY_NAME FROM PROCESS_CATEGORY +Process Category + + + + Debug + + + + Cancel + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_EditObjectPermission.xml b/workflow/engine/xmlform/processes/processes_EditObjectPermission.xml new file mode 100644 index 000000000..df5d73b17 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_EditObjectPermission.xml @@ -0,0 +1,130 @@ + + + + <en>Edit Specific Permission</en> +<es><![CDATA[Nuevo permiso específico]]></es><pt><![CDATA[Permissão Específica Nova]]></pt> + + + + + + Status Case + + + + + + Estado del Caso + + + + +Target Task +Tarea destinoTarefa Alvo + + +SELECT * FROM usersGroups + Group or User +Grupo o usuario + +Origin Task +Tarea origenTarefa Origem + + + Participation required? + + + + Type +TipoTipo + +SELECT * FROM allObjects + Object +ObjetoObjeto + +SELECT * FROM allDynaforms + DynaForm +DynaForm + +SELECT * FROM allInputs + Input Document +Input Document Documento de Entrada + +SELECT * FROM allOutputs + Output Document +Output Document + + Permission +Permiso + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Export.xml b/workflow/engine/xmlform/processes/processes_Export.xml new file mode 100644 index 000000000..520a15d8d --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Export.xml @@ -0,0 +1,35 @@ + + + + + <en>processes Info</en> + + + + Process Title + + + + Description + + + + Size in bytes + + + + + + + File + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_FileEdit.html b/workflow/engine/xmlform/processes/processes_FileEdit.html new file mode 100755 index 000000000..7d8405e24 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FileEdit.html @@ -0,0 +1,40 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    {$form.pro_uid}
    {$form.filename}
    {$form.TITLE}
    {$form.fcontent}
    {$form.ACCEPT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/processes/processes_FileEdit.xml b/workflow/engine/xmlform/processes/processes_FileEdit.xml new file mode 100755 index 000000000..925dca590 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FileEdit.xml @@ -0,0 +1,31 @@ + + + + + + + + <en><![CDATA[<div align="center">Edit @#filename email template</div>]]></en> + + + + + + + + Save + + + Cancel + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.html b/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.html new file mode 100755 index 000000000..d75699fba --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.html @@ -0,0 +1,29 @@ +
    +
    +
    + + + + +
    + + + + + + + + + +
    {$emptyfilename}{$form.emptyfilename}{$form.ACCEPT}
    +
    +
    +
    +
    +
    + + + + diff --git a/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.xml b/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.xml new file mode 100755 index 000000000..20d88723c --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FileEditCreateEmpty.xml @@ -0,0 +1,9 @@ + + + + Filename + + + Create + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_FilesList.xml b/workflow/engine/xmlform/processes/processes_FilesList.xml new file mode 100644 index 000000000..4c5aeec2f --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FilesList.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_FilesOptions.xml b/workflow/engine/xmlform/processes/processes_FilesOptions.xml new file mode 100644 index 000000000..5d7e74a3a --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_FilesOptions.xml @@ -0,0 +1,150 @@ + + + + + New + + + + Upload + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Import.html b/workflow/engine/xmlform/processes/processes_Import.html new file mode 100644 index 000000000..949a85f0b --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Import.html @@ -0,0 +1,36 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$PROCESS_FILENAME}{$form.PROCESS_FILENAME}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Import.xml b/workflow/engine/xmlform/processes/processes_Import.xml new file mode 100644 index 000000000..b6b3f4d30 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Import.xml @@ -0,0 +1,38 @@ + + + + + Import Process + + + + + File + + + + Import + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ImportExisting.html b/workflow/engine/xmlform/processes/processes_ImportExisting.html new file mode 100644 index 000000000..ec8411229 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ImportExisting.html @@ -0,0 +1,43 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    {$form.TITLE1}
    {$form.IMPORT_OPTION }
    {$form.PRO_FILENAME}
    {$form.OBJ_UID }

    {$form.SUBMIT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ImportExisting.xml b/workflow/engine/xmlform/processes/processes_ImportExisting.xml new file mode 100644 index 000000000..fd0941fc6 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ImportExisting.xml @@ -0,0 +1,44 @@ + + + + + + <en><![CDATA[<div align="center">Importing Existing Process</div>]]></en> + + + + The process you are trying to import already exists. Please select one of the following options to continue: + + + + + + + + + + + + + + + + + + + Save + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ImportSucessful.xml b/workflow/engine/xmlform/processes/processes_ImportSucessful.xml new file mode 100644 index 000000000..3e4238777 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ImportSucessful.xml @@ -0,0 +1,37 @@ + + + + + + <en>Process sucessfully imported</en> + + + + Process Title + + + Version + + + + Category + + + + Process Uid + + + + Please follow these instructions to complete installation + + + + + + + + + Continue + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_List.xml b/workflow/engine/xmlform/processes/processes_List.xml new file mode 100644 index 000000000..d6468722d --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_List.xml @@ -0,0 +1,23 @@ + + + + + Category + + + Title + + + Description + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ListPublic.xml b/workflow/engine/xmlform/processes/processes_ListPublic.xml new file mode 100644 index 000000000..256cc4583 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ListPublic.xml @@ -0,0 +1,43 @@ + + + + + <en>Title</en> + + + + Category + + + + Version + + + + Downloads + + + + Rating + + + + Subscriptions + + + + + Author + + + + Update Date + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_New.xml b/workflow/engine/xmlform/processes/processes_New.xml new file mode 100644 index 000000000..ee453c22a --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_New.xml @@ -0,0 +1,51 @@ + + + + + + + + + Process Information + + + + Title + + + + Description + + + + SELECT * from ProcessesNew + Template + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_NewObjectPermission.html b/workflow/engine/xmlform/processes/processes_NewObjectPermission.html new file mode 100644 index 000000000..62a8e991e --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_NewObjectPermission.html @@ -0,0 +1,85 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.PRO_UID}
    {$OP_CASE_STATUS}{$form.OP_CASE_STATUS}
    {$TAS_UID}{$form.TAS_UID}
    {$GROUP_USER}{$form.GROUP_USER}
    {$OP_TASK_SOURCE}{$form.OP_TASK_SOURCE}
    {$OP_PARTICIPATE}{$form.OP_PARTICIPATE}
    {$OP_OBJ_TYPE}{$form.OP_OBJ_TYPE}
    {$ALL}{$form.ALL}
    {$DYNAFORMS}{$form.DYNAFORMS}
    {$INPUTS}{$form.INPUTS}
    {$OUTPUTS}{$form.OUTPUTS}
    {$OP_ACTION}{$form.OP_ACTION}

    {$form.CREATE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_NewObjectPermission.xml b/workflow/engine/xmlform/processes/processes_NewObjectPermission.xml new file mode 100644 index 000000000..03aa118bf --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_NewObjectPermission.xml @@ -0,0 +1,245 @@ + + + + <en>New Specific Permission</en> + + + + + + Status Case + + + + + + + + + + Target Task + + + + + SELECT * FROM usersGroups + Group or User + + + + Origin Task + + + + Participation required? + + + Type + + + + + + + + SELECT * FROM allObjects + Object + + + + + SELECT * FROM allDynaforms + DynaForm + + + SELECT * FROM allInputs + Input Document + + + SELECT * FROM allOutputs + Output Document + + + Permission + + + + Cancel + + + + Create +CreateCriar + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_NewOptions.xml b/workflow/engine/xmlform/processes/processes_NewOptions.xml new file mode 100644 index 000000000..a1071eda4 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_NewOptions.xml @@ -0,0 +1,6 @@ + + + + Back to list + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_NewSimple.html b/workflow/engine/xmlform/processes/processes_NewSimple.html new file mode 100644 index 000000000..879e8cabf --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_NewSimple.html @@ -0,0 +1,46 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE1}
    {$PRO_TITLE}{$form.PRO_TITLE}
    {$PRO_DESCRIPTION}{$form.PRO_DESCRIPTION}
    {$PRO_CATEGORY}{$form.PRO_CATEGORY}
    {$form.SUBMIT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_NewSimple.xml b/workflow/engine/xmlform/processes/processes_NewSimple.xml new file mode 100644 index 000000000..58e465f1e --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_NewSimple.xml @@ -0,0 +1,79 @@ + + + + + + + + + Process Information + + + + Title + + + + Description + + + +SELECT CATEGORY_UID, CATEGORY_NAME FROM PROCESS_CATEGORY +Process Category + + + + Save + + + + Cancel + + + + + + +document.onkeypress=function(e){ +var esIE=(document.all); +var esNS=(document.layers); +tecla=(esIE) ? event.keyCode : e.which; +if(tecla==13){ + return false; + } +} + + +var verifyProcessInformation = function(oForm){ + var nameProcess = getField('PRO_TITLE').value; + reqName=ajax_function('processes_Save','lookForNameProcess','NAMEPROCESS='+encodeURIComponent(nameProcess),'POST') ; + + var oAux; + var bContinue = true; + oAux = oForm.elements['form[PRO_TITLE]']; + if (oAux.value == '') + { + alert("@#MESSAGE1"); + oAux.focus(); + bContinue = false; + } else { + if(reqName){ + //the process name exists then we can't save it + alert(G_STRINGS.ID_EXIST_PROCESS);return false; + } else { + if (bContinue) + { + oForm.submit(); + } + } + } + //return false; +}; + +function cancel(){ + history.back(); +} + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ObjectsPermissionsList.xml b/workflow/engine/xmlform/processes/processes_ObjectsPermissionsList.xml new file mode 100644 index 000000000..d64507651 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ObjectsPermissionsList.xml @@ -0,0 +1,37 @@ + + + + + Target Task +Tarea ObjetivoTarefa Alvo + + Group or User +Grupo o Usuario + + Origin Task +Tarea de OrigenTarefa Origem + + Participation + + + Type +TipoTipo + + Object +ObjetoObjeto + + Permission +Permiso + + Status +Estado + + + Edit +Editar + + + + Delete +BorrarEliminar + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ObjectsPermissionsOptions.xml b/workflow/engine/xmlform/processes/processes_ObjectsPermissionsOptions.xml new file mode 100644 index 000000000..940b8cabd --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ObjectsPermissionsOptions.xml @@ -0,0 +1,125 @@ + + + + + + + New +Nuevo + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Options.xml b/workflow/engine/xmlform/processes/processes_Options.xml new file mode 100644 index 000000000..380e3af38 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Options.xml @@ -0,0 +1,57 @@ + + + + + New + + + + Import + + + + Browse Library + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Properties.xml b/workflow/engine/xmlform/processes/processes_Properties.xml new file mode 100644 index 000000000..b610e3190 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Properties.xml @@ -0,0 +1,46 @@ + + + + + + + + + Process Information + + + + Title + + + + Description + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_Search.xml b/workflow/engine/xmlform/processes/processes_Search.xml new file mode 100644 index 000000000..36ce5fdab --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_Search.xml @@ -0,0 +1,20 @@ + + + + + UID + + + + Title + + + + Description + + + + Apply Filter + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_UploadFilesForm.xml b/workflow/engine/xmlform/processes/processes_UploadFilesForm.xml new file mode 100644 index 000000000..2f3f8115e --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_UploadFilesForm.xml @@ -0,0 +1,67 @@ + + + + + Upload Files + + + + + + + + + + File 1 + + + + File 2 + + + + File 3 + + + + File 4 + + + + File 5 + + + + Upload + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_User.xml b/workflow/engine/xmlform/processes/processes_User.xml new file mode 100644 index 000000000..bd3eb482b --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_User.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + First name + + + + Last name + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ValidatingGroups.xml b/workflow/engine/xmlform/processes/processes_ValidatingGroups.xml new file mode 100644 index 000000000..4fc1cfead --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ValidatingGroups.xml @@ -0,0 +1,39 @@ + + + + + + <en><![CDATA[<div align="center">Importing Groups</div>]]></en> + + + + Some of the groups that are you trying to import, already exists. Please select one of the following options to continue: + + + + + + + + + + + + + + + + + + + + + + + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_View.xml b/workflow/engine/xmlform/processes/processes_View.xml new file mode 100644 index 000000000..84006a367 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_View.xml @@ -0,0 +1,20 @@ + + + + + + + + + Process Information + + + + Title + + + + Description + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_ViewOptions.xml b/workflow/engine/xmlform/processes/processes_ViewOptions.xml new file mode 100644 index 000000000..add7b07d4 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_ViewOptions.xml @@ -0,0 +1,6 @@ + + + + Back to list + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_availableProcessesUser.xml b/workflow/engine/xmlform/processes/processes_availableProcessesUser.xml new file mode 100644 index 000000000..8d87fa4e2 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_availableProcessesUser.xml @@ -0,0 +1,17 @@ + + + + + + + + First name + + + + Last name + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_subProcess.html b/workflow/engine/xmlform/processes/processes_subProcess.html new file mode 100644 index 000000000..7f6e6399d --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_subProcess.html @@ -0,0 +1,76 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.SP_UID}
    {$form.PRO_PARENT}
    {$form.TAS_PARENT}
    {$form.INDEX}
    {$SPROCESS_NAME}{$form.SPROCESS_NAME}
    {$TASKS}{$form.TASKS}
    {$PROCESSES}{$form.PROCESSES}
    {$SP_SYNCHRONOUS}{$form.SP_SYNCHRONOUS}
    + {$form.SUBTITLE1} +
    {$form.grid1}
    + {$form.SUBTITLE2} +
    {$form.grid2}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_subProcess.xml b/workflow/engine/xmlform/processes/processes_subProcess.xml new file mode 100644 index 000000000..833d6f3bd --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_subProcess.xml @@ -0,0 +1,173 @@ + + + + + Sub-Process + + + + + + + + + + + +SubProcess name + + + + SELECT * FROM NewCase + Process + + + + SELECT * FROM TheProcesses + + + + + Type + + + + Variables Out + + + + + Variables In + + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_subProcess_In.xml b/workflow/engine/xmlform/processes/processes_subProcess_In.xml new file mode 100644 index 000000000..30850b5af --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_subProcess_In.xml @@ -0,0 +1,12 @@ + + + + +Origin + + + +Target + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_subProcess_Out.xml b/workflow/engine/xmlform/processes/processes_subProcess_Out.xml new file mode 100644 index 000000000..9e4cf4c56 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_subProcess_Out.xml @@ -0,0 +1,12 @@ + + + + +Origin + + + +Target + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/processes_viewreassignCase.xml b/workflow/engine/xmlform/processes/processes_viewreassignCase.xml new file mode 100644 index 000000000..e63ac48a0 --- /dev/null +++ b/workflow/engine/xmlform/processes/processes_viewreassignCase.xml @@ -0,0 +1,25 @@ + + + + + + + First Name + + + + Last Name + + + + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/processes/registerPML.html b/workflow/engine/xmlform/processes/registerPML.html new file mode 100644 index 000000000..f50bc68c3 --- /dev/null +++ b/workflow/engine/xmlform/processes/registerPML.html @@ -0,0 +1,35 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    {$form.pro_uid}
    {$form.TITLE}
    * {$PML_USER}{$form.PML_USER}
    * {$PML_PASSWORD}{$form.PML_PASSWORD}
    {$form.PML_LOGIN}
    {$form.link2}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    +
    diff --git a/workflow/engine/xmlform/processes/registerPML.xml b/workflow/engine/xmlform/processes/registerPML.xml new file mode 100644 index 000000000..47f0794ad --- /dev/null +++ b/workflow/engine/xmlform/processes/registerPML.xml @@ -0,0 +1,28 @@ + + + + + + + <en>Login into ProcessMaker Library</en> + + + + Username (or Live Workspace) + + + + Password + + + + Login + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reportTables/reportTables_Edit.html b/workflow/engine/xmlform/reportTables/reportTables_Edit.html new file mode 100644 index 000000000..6c73cd267 --- /dev/null +++ b/workflow/engine/xmlform/reportTables/reportTables_Edit.html @@ -0,0 +1,59 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$form.REP_TAB_UID}
    {$form.TITLE}
    * {$REP_TAB_TITLE}{$form.REP_TAB_TITLE}
    * {$REP_TAB_NAME}{$form.REP_TAB_NAME}
    * {$REP_TAB_TYPE}{$form.REP_TAB_TYPE}
    * {$REP_TAB_GRID}{$form.REP_TAB_GRID}
    * {$FIELDS}{$form.FIELDS}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/reportTables/reportTables_Edit.xml b/workflow/engine/xmlform/reportTables/reportTables_Edit.xml new file mode 100644 index 000000000..90bc7195b --- /dev/null +++ b/workflow/engine/xmlform/reportTables/reportTables_Edit.xml @@ -0,0 +1,94 @@ + + + + + + + + + + <en>Report Table Information</en> + + + + Title + + + + Table Name + + + + Type + + + +SELECT * FROM processGridFields + Grid Fields + + + +SELECT * FROM processFields + Fields + + + + Cancel + + + + Save + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reportTables/reportTables_Options.xml b/workflow/engine/xmlform/reportTables/reportTables_Options.xml new file mode 100644 index 000000000..f4f879c52 --- /dev/null +++ b/workflow/engine/xmlform/reportTables/reportTables_Options.xml @@ -0,0 +1,101 @@ + + + + + New + + + + + + + + + + + + + 80)) { + bContinue = false; + } + } + else { + if (getField('REP_TAB_GRID').value == '') { + bContinue = false; + } + } + if (bContinue) { + ajax_post(form.action, form, 'POST'); + currentPopupWindow.remove(); + @#PAGED_TABLE_ID.refresh(); + } + else { + if (getField('REP_TAB_TYPE').value == 'NORMAL') { + if (j == 0) { + new leimnud.module.app.alert().make({ + label:'@G::LoadTranslation(ID_PLEASE_ENTER_REQUIRED_FIELDS)' + }); + } + else { + new leimnud.module.app.alert().make({ + label:'@G::LoadTranslation(ID_PLEASE_SELECT_MAX_X_FIELDS)' + }); + } + } + else { + new leimnud.module.app.alert().make({ + label:'@G::LoadTranslation(ID_PLEASE_ENTER_REQUIRED_FIELDS)' + }); + } + } +} + +function reportTablesDelete(sUID) +{ + new leimnud.module.app.confirm().make({ + label:'@G::LoadTranslation(ID_MSG_CONFIRM_DELETE_REPORT_TABLE)', + action:function() + { + ajax_function('@G::encryptlink(@#reportTablesDelete)', '', 'REP_TAB_UID=' + sUID, 'POST'); + @#PAGED_TABLE_ID.refresh(); + }.extend(this) + }); +} + +]]> + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reportTables/reportTables_ShortList.xml b/workflow/engine/xmlform/reportTables/reportTables_ShortList.xml new file mode 100644 index 000000000..039d3e373 --- /dev/null +++ b/workflow/engine/xmlform/reportTables/reportTables_ShortList.xml @@ -0,0 +1,27 @@ + + + + + + + Title + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter(form) { + @#PAGED_TABLE_ID.doFilter(form); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report1.xml b/workflow/engine/xmlform/reports/report1.xml new file mode 100644 index 000000000..db57bff30 --- /dev/null +++ b/workflow/engine/xmlform/reports/report1.xml @@ -0,0 +1,33 @@ + + + + + + Processes + + + + Cases + + + + Best Completion Time + + + + Slowest Completion Time + + + + Total Duration (Hours) + + + + Average (Hours) + + + + Detaills + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report1_back.xml b/workflow/engine/xmlform/reports/report1_back.xml new file mode 100644 index 000000000..f3dd2c774 --- /dev/null +++ b/workflow/engine/xmlform/reports/report1_back.xml @@ -0,0 +1,8 @@ + + + + + Back + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report1_dashboard.xml b/workflow/engine/xmlform/reports/report1_dashboard.xml new file mode 100644 index 000000000..2f0f8df2a --- /dev/null +++ b/workflow/engine/xmlform/reports/report1_dashboard.xml @@ -0,0 +1,26 @@ + + + + + Processes + + + + Total Cases + + + + + + Slowest Time + + + + Total Duration + + + + Average + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report1_search.html b/workflow/engine/xmlform/reports/report1_search.html new file mode 100644 index 000000000..48ac08054 --- /dev/null +++ b/workflow/engine/xmlform/reports/report1_search.html @@ -0,0 +1,27 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + +
    {$FROM}{$form.FROM}{$TO}{$form.TO}
    {$STARTEDBY}{$form.STARTEDBY}
    {$form.FILTER}
    +
    +
    +
    +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report1_search.xml b/workflow/engine/xmlform/reports/report1_search.xml new file mode 100644 index 000000000..96ff3c383 --- /dev/null +++ b/workflow/engine/xmlform/reports/report1_search.xml @@ -0,0 +1,21 @@ + + + + + FROM + + + + TO + + +STARTED BY + + + + Filter + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report2.xml b/workflow/engine/xmlform/reports/report2.xml new file mode 100644 index 000000000..e74d1d58a --- /dev/null +++ b/workflow/engine/xmlform/reports/report2.xml @@ -0,0 +1,28 @@ + + + + + Processes + + + + Total Cases + + + + Best Completion Time + + + + Slowest Completion Time + + + + Cases last month + + + + Cases last day + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report2_dashboard.xml b/workflow/engine/xmlform/reports/report2_dashboard.xml new file mode 100644 index 000000000..7928dbaf0 --- /dev/null +++ b/workflow/engine/xmlform/reports/report2_dashboard.xml @@ -0,0 +1,26 @@ + + + + + Processes + + + + Total Cases + + + + + + Slowest Time + + + + Last month + + + + Last day + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report3.xml b/workflow/engine/xmlform/reports/report3.xml new file mode 100644 index 000000000..116d10a16 --- /dev/null +++ b/workflow/engine/xmlform/reports/report3.xml @@ -0,0 +1,28 @@ + + + + + Date + + + + Total Cases + + + + Best Completion Time + + + + Slowest Completion Time + + + + Total Duration (Hours) + + + + Average (Hours) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report3_dashboard.xml b/workflow/engine/xmlform/reports/report3_dashboard.xml new file mode 100644 index 000000000..a9d30034f --- /dev/null +++ b/workflow/engine/xmlform/reports/report3_dashboard.xml @@ -0,0 +1,26 @@ + + + + + Date + + + + Total Cases + + + + + + Slowest Time + + + + Total Duration + + + + Average + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report4.xml b/workflow/engine/xmlform/reports/report4.xml new file mode 100644 index 000000000..db0d0cfbc --- /dev/null +++ b/workflow/engine/xmlform/reports/report4.xml @@ -0,0 +1,28 @@ + + + + + User + + + + Total Cases + + + + Best Completion Time + + + + Slowest Completion Time + + + + Total Duration (Hours) + + + + Average (Hours) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report4_dashboard.xml b/workflow/engine/xmlform/reports/report4_dashboard.xml new file mode 100644 index 000000000..eea16ef29 --- /dev/null +++ b/workflow/engine/xmlform/reports/report4_dashboard.xml @@ -0,0 +1,26 @@ + + + + + User + + + + Total Cases + + + + + + Slowest Time + + + + Total Duration + + + + Average + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report5.xml b/workflow/engine/xmlform/reports/report5.xml new file mode 100644 index 000000000..db0d0cfbc --- /dev/null +++ b/workflow/engine/xmlform/reports/report5.xml @@ -0,0 +1,28 @@ + + + + + User + + + + Total Cases + + + + Best Completion Time + + + + Slowest Completion Time + + + + Total Duration (Hours) + + + + Average (Hours) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report5_dashboard.xml b/workflow/engine/xmlform/reports/report5_dashboard.xml new file mode 100644 index 000000000..eea16ef29 --- /dev/null +++ b/workflow/engine/xmlform/reports/report5_dashboard.xml @@ -0,0 +1,26 @@ + + + + + User + + + + Total Cases + + + + + + Slowest Time + + + + Total Duration + + + + Average + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/report_filter.xml b/workflow/engine/xmlform/reports/report_filter.xml new file mode 100644 index 000000000..0b6e82fc0 --- /dev/null +++ b/workflow/engine/xmlform/reports/report_filter.xml @@ -0,0 +1,50 @@ + + + +Process +ProcesoProcesso + +Tasks +TareasTarefas + + + Filter +FiltroFiltro + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/reportsList.xml b/workflow/engine/xmlform/reports/reportsList.xml new file mode 100644 index 000000000..e7846542b --- /dev/null +++ b/workflow/engine/xmlform/reports/reportsList.xml @@ -0,0 +1,18 @@ + + + + + # + + + + Reports + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/reports_Description.xml b/workflow/engine/xmlform/reports/reports_Description.xml new file mode 100644 index 000000000..4b1bcbdd5 --- /dev/null +++ b/workflow/engine/xmlform/reports/reports_Description.xml @@ -0,0 +1,24 @@ + + + + + Task + + + + Best Completion Time + + + + Slowest Completion Time + + + + Total Duration (Hours) + + + + Average (Hours) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/reports_Description_search.xml b/workflow/engine/xmlform/reports/reports_Description_search.xml new file mode 100644 index 000000000..cda5056fa --- /dev/null +++ b/workflow/engine/xmlform/reports/reports_Description_search.xml @@ -0,0 +1,26 @@ + + + + + + FROM + + + + TO + + + + SELECT USR_UID, USR_USERNAME FROM USERS + STARTED BY + + + + Filter + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/reports/rpt_filters.xml b/workflow/engine/xmlform/reports/rpt_filters.xml new file mode 100644 index 000000000..3bd734fb9 --- /dev/null +++ b/workflow/engine/xmlform/reports/rpt_filters.xml @@ -0,0 +1,16 @@ + + + + + Initial date + + + + End date + + + + Filter + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_Edit.html b/workflow/engine/xmlform/roles/roles_Edit.html new file mode 100644 index 000000000..d4524b6cc --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_Edit.html @@ -0,0 +1,46 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    {$form.ROL_UID}
    * {$ROL_CODE}{$form.ROL_CODE}
    * {$ROL_NAME}{$form.ROL_NAME}
    {$ROL_STATUS}{$form.ROL_STATUS}

    {$form.CREATE}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_Edit.xml b/workflow/engine/xmlform/roles/roles_Edit.xml new file mode 100644 index 000000000..0db95b3e6 --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_Edit.xml @@ -0,0 +1,38 @@ + + + + + <en>Edit role</en> + + + + + + + Role Code + + + + Role Name + + + + Status + + + + Cancel + + + + Update + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_List.xml b/workflow/engine/xmlform/roles/roles_List.xml new file mode 100644 index 000000000..8fe241492 --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_List.xml @@ -0,0 +1,36 @@ + + + + + Code + + + + Name + + + + Create date + + + + Update date + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_New.html b/workflow/engine/xmlform/roles/roles_New.html new file mode 100644 index 000000000..bc64944c1 --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_New.html @@ -0,0 +1,43 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title}
    * {$ROL_CODE}{$form.ROL_CODE}
    * {$ROL_NAME}{$form.ROL_NAME}
    {$ROL_STATUS}{$form.ROL_STATUS}

    {$form.CREATE}   {$form.BTN_CANCEL}
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_New.xml b/workflow/engine/xmlform/roles/roles_New.xml new file mode 100644 index 000000000..0dfd0f8f0 --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_New.xml @@ -0,0 +1,36 @@ + + + + + <en>Create a new Role</en> + + + + Role Code + + + + Role Name + + + + Status + + + + Cancel + + + + Create + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/roles/roles_Options.xml b/workflow/engine/xmlform/roles/roles_Options.xml new file mode 100644 index 000000000..bf4ea7c12 --- /dev/null +++ b/workflow/engine/xmlform/roles/roles_Options.xml @@ -0,0 +1,345 @@ + + + + + New +NuevoNovo + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarEdit.html b/workflow/engine/xmlform/setup/calendarEdit.html new file mode 100644 index 000000000..39cec6ca8 --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarEdit.html @@ -0,0 +1,67 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.CALENDAR_UID}
    {$form.DEFINITION_TITLE}
    * {$CALENDAR_NAME}{$form.CALENDAR_NAME}
    {$CALENDAR_DESCRIPTION}{$form.CALENDAR_DESCRIPTION}

    {$form.CALENDAR_STATUS}
    {$form.WorkDays}
    {$CALENDAR_WORK_DAYS}{$form.CALENDAR_WORK_DAYS}
    {$form.BUSINESS_DAY_STATUS} {$form.BUSINESS_DAY_TITLE}
    {$form.BUSINESS_DAY}
    {$form.HOLIDAY_STATUS} {$form.HOLIDAY_LABEL}
    {$form.SUBMIT2}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarEdit.xml b/workflow/engine/xmlform/setup/calendarEdit.xml new file mode 100644 index 000000000..69d5edbd9 --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarEdit.xml @@ -0,0 +1,371 @@ + + + + Ndar Uid + + + + + +Calendar Definition + + +Name + + +Description + + +Active + + + +Work Days + + + + + + + + + + + + +Work Hours + + + +Holidays + + + +Save + + +Save + + + Cancel + + + + + + + + +1) { + getObject('BUSINESS_DAY').deleteGridRownomsg('['+i+']'); + i--; + } + return false; +} + +leimnud.event.add(getField("BUSINESS_DAY_STATUS"), 'click', function() { + if(getField("BUSINESS_DAY_STATUS").checked){ + document.getElementById('gridbusiness').style.display=""; + getField("CALENDAR_WORK_DAYS][0").disabled=true; + getField("CALENDAR_WORK_DAYS][1").disabled=true; + getField("CALENDAR_WORK_DAYS][2").disabled=true; + getField("CALENDAR_WORK_DAYS][3").disabled=true; + getField("CALENDAR_WORK_DAYS][4").disabled=true; + getField("CALENDAR_WORK_DAYS][5").disabled=true; + getField("CALENDAR_WORK_DAYS][6").disabled=true; + } else { + document.getElementById('gridbusiness').style.display="none"; + cleargrid(); + getField("CALENDAR_WORK_DAYS][0").disabled=false; + getField("CALENDAR_WORK_DAYS][1").disabled=false; + getField("CALENDAR_WORK_DAYS][2").disabled=false; + getField("CALENDAR_WORK_DAYS][3").disabled=false; + getField("CALENDAR_WORK_DAYS][4").disabled=false; + getField("CALENDAR_WORK_DAYS][5").disabled=false; + getField("CALENDAR_WORK_DAYS][6").disabled=false; + } +}); + +leimnud.event.add(getField("HOLIDAY_STATUS"), 'click', function() { + if(getField("HOLIDAY_STATUS").checked){ + document.getElementById('gridholi').style.display=""; + document.getElementById('hiddenb').style.display=""; + document.getElementById('showb').style.display="none"; + } else { + document.getElementById('gridholi').style.display="none"; + document.getElementById('hiddenb').style.display="none"; + document.getElementById('showb').style.display=""; + } +}); + +function hiddenholidays() { + getField('HOLIDAY_STATUS').checked=false; + document.getElementById('gridholi').style.display="none"; + document.getElementById('down').style.display="none"; + document.getElementById('up').style.display=""; + document.getElementById('hiddenb').style.display="none"; + document.getElementById('showb').style.display=""; +} + +function showholidays() { + getField('HOLIDAY_STATUS').checked=true; + document.getElementById('gridholi').style.display=""; + document.getElementById('down').style.display=""; + document.getElementById('up').style.display="none"; + document.getElementById('hiddenb').style.display=""; + document.getElementById('showb').style.display="none"; +} + +function cleardrop() { + while(getField('BUSINESS_DAY][1][CALENDAR_BUSINESS_DAY').options.length > 0) { + getField('BUSINESS_DAY][1][CALENDAR_BUSINESS_DAY').options[getField('BUSINESS_DAY][1][CALENDAR_BUSINESS_DAY').length-1] = null; + } +} + +function AddItem(Text,Value) { + var opt = document.createElement("option"); + getField('BUSINESS_DAY][1][CALENDAR_BUSINESS_DAY').options.add(opt); + opt.text = Text; + opt.value = Value; +} + +function check() { + cleardrop(); + Text='- ALL -'; + Value=7; + AddItem(Text,Value); + + if(getField("CALENDAR_WORK_DAYS][0").checked){ + Text='SUN'; + Value=0; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][1").checked){ + Text='MON'; + Value=1; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][2").checked){ + Text='TUE'; + Value=2; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][3").checked){ + Text='WED'; + Value=3; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][4").checked){ + Text='THU'; + Value=4; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][5").checked){ + Text='FRI'; + Value=5; + AddItem(Text,Value); + } + + if(getField("CALENDAR_WORK_DAYS][6").checked){ + Text='SAT'; + Value=6; + AddItem(Text,Value); + } +} + +leimnud.event.add(getField("CALENDAR_WORK_DAYS][0"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][1"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][2"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][3"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][4"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][5"), 'click', function() {check();}); +leimnud.event.add(getField("CALENDAR_WORK_DAYS][6"), 'click', function() {check();}); + + +var dynaformOnload = function() { + + rowsCount=Number_Rows_Grid("BUSINESS_DAY", "CALENDAR_BUSINESS_DAY"); + for(i=1;i<=rowsCount;i++){ + timeValidatorWrap(i); + } + grid_BUSINESS_DAY.onaddrow = function (iRow) { + timeValidatorWrap(iRow); + } + getField("BUSINESS_DAY_STATUS").checked=true; + if(getField("BUSINESS_DAY_STATUS").checked){ + document.getElementById('gridbusiness').style.display=""; + getField("CALENDAR_WORK_DAYS][0").disabled=true; + getField("CALENDAR_WORK_DAYS][1").disabled=true; + getField("CALENDAR_WORK_DAYS][2").disabled=true; + getField("CALENDAR_WORK_DAYS][3").disabled=true; + getField("CALENDAR_WORK_DAYS][4").disabled=true; + getField("CALENDAR_WORK_DAYS][5").disabled=true; + getField("CALENDAR_WORK_DAYS][6").disabled=true; + } else{ + document.getElementById('gridbusiness').style.display="none"; + cleargrid(); + getField("CALENDAR_WORK_DAYS][0").disabled=false; + getField("CALENDAR_WORK_DAYS][1").disabled=false; + getField("CALENDAR_WORK_DAYS][2").disabled=false; + getField("CALENDAR_WORK_DAYS][3").disabled=false; + getField("CALENDAR_WORK_DAYS][4").disabled=false; + getField("CALENDAR_WORK_DAYS][5").disabled=false; + getField("CALENDAR_WORK_DAYS][6").disabled=false; + } + if((getField("CALENDAR_UID").value=="00000000000000000000000000000001")||(getField("CALENDAR_UID").value=="00000000000000000000000000000002")){ + getField("CALENDAR_STATUS").disabled=true; + getField("CALENDAR_NAME").disabled=true; + getField("CALENDAR_NAME").style.background="none"; + getField("CALENDAR_NAME").style.border="0"; + } +} + +function timeValidatorWrap(iRow){ + getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_START").onchange=function startValidation(){ + validateTime(getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_START")); + } + + getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_START").onblur=function startValidation(){ + validateTime(getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_START")); + } + + getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_END").onchange=function startValidation(){ + validateTime(getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_END")); + } + getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_END").onblur=function startValidation(){ + validateTime(getGridField("BUSINESS_DAY", iRow, "CALENDAR_BUSINESS_END")); + } + + + +} +function validateForm(form){ + rowsCount=Number_Rows_Grid("BUSINESS_DAY", "CALENDAR_BUSINESS_DAY"); + msg=""; + + for(i=1;i<=rowsCount;i++){ + msgStart=""; + msgStart=validateTime(getGridField("BUSINESS_DAY", i, "CALENDAR_BUSINESS_START")); + + if(msgStart!=""){ + msg+="- "+msgStart+"\n"; + } + msgEnd=""; + msgEnd=validateTime(getGridField("BUSINESS_DAY", i, "CALENDAR_BUSINESS_END")); + if(msgEnd!=""){ + msg+="- "+msgEnd+"\n"; + } + + } + getField('CALENDAR_NAME').value=getField('CALENDAR_NAME').value.replace(/^\s+/, ""); + + if(getField('CALENDAR_NAME').value==""){ + msg+="- Invalid Name \n"; + } + var flag=true; + var rowsHoliday=Number_Rows_Grid("HOLIDAY", "CALENDAR_HOLIDAY_START"); + //alert(rowsHoliday);return false; + var j=0; + for(var j =1; j<= rowsHoliday;j++){ + msgHolidays = getGridField("HOLIDAY", j, "CALENDAR_HOLIDAY_START"); + if(msgHolidays.value==''){ + flag=false; + } + } + if(!flag){ + msgBox(G_STRINGS.ID_REQUIRED_FIELDS + ": \n Start Date ","alert"); return false; + } + if(msg!=""){ + alert(msg); + return false; + } + + return true; + +} + +function validateTime(object){ + timeToValidate=object.value; + msgError=""; + if(!isValidTime(timeToValidate)){ + G.highLight(object); + msgError="Invalid: "+object.value; + }else{ + object.style.background=""; + msgError=""; + } + return msgError; +} + +function isValidTime(value) { + var hasMeridian = false; + var re = /^\d{1,2}[:]\d{2}([:]\d{2})?( [aApP][mM]?)?$/; + if (!re.test(value)) { return false; } + if (value.toLowerCase().indexOf("p") != -1) { hasMeridian = true; } + if (value.toLowerCase().indexOf("a") != -1) { hasMeridian = true; } + var values = value.split(":"); + if ( (parseFloat(values[0]) < 0) || (parseFloat(values[0]) > 23) ) { return false; } + if (hasMeridian) { + if ( (parseFloat(values[0]) < 1) || (parseFloat(values[0]) > 12) ) { return false; } + } + if ( (parseFloat(values[1]) < 0) || (parseFloat(values[1]) > 59) ) { return false; } + if (values.length > 2) { + if ( (parseFloat(values[2]) < 0) || (parseFloat(values[2]) > 59) ) { return false; } + } + return true; +} + +function cancel(){ + + window.location = 'calendarList'; +} + + +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarEdit_BusinessHours.xml b/workflow/engine/xmlform/setup/calendarEdit_BusinessHours.xml new file mode 100644 index 000000000..6fe84c943 --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarEdit_BusinessHours.xml @@ -0,0 +1,15 @@ + + + + Day + + + Start (hh:mm) + + + + + End (hh:mm) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarEdit_Holidays.xml b/workflow/engine/xmlform/setup/calendarEdit_Holidays.xml new file mode 100644 index 000000000..bca356aef --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarEdit_Holidays.xml @@ -0,0 +1,12 @@ + + + +Name + + +Start Date (Recurrent "Y-m-d") + + +End Date (Recurrent "Y-m-d") + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarList.xml b/workflow/engine/xmlform/setup/calendarList.xml new file mode 100644 index 000000000..afc11b52a --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarList.xml @@ -0,0 +1,29 @@ + + + + + Name + + + + Description + + + + Status + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/calendarList_Options.xml b/workflow/engine/xmlform/setup/calendarList_Options.xml new file mode 100644 index 000000000..1d92e12c9 --- /dev/null +++ b/workflow/engine/xmlform/setup/calendarList_Options.xml @@ -0,0 +1,8 @@ + + + + + + New + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/emailSetupTest.xml b/workflow/engine/xmlform/setup/emailSetupTest.xml new file mode 100644 index 000000000..f33b5fb9b --- /dev/null +++ b/workflow/engine/xmlform/setup/emailSetupTest.xml @@ -0,0 +1,36 @@ + + + + + Mail System Test Page + + + + Domain + + + + To: + + + + From Name: + + + + From Email: + + + + Subject: + + + + File + + + + Send Email + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/emails.html b/workflow/engine/xmlform/setup/emails.html new file mode 100644 index 000000000..6dabf4c0c --- /dev/null +++ b/workflow/engine/xmlform/setup/emails.html @@ -0,0 +1,92 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.THETITLE}
    {$form.MESS_ENABLED}
    {$MESS_ENGINE }{$form.MESS_ENGINE }
    * {$MESS_SERVER }{$form.MESS_SERVER}
    {$MESS_PORT }{$form.MESS_PORT }
    {$form.MESS_RAUTH }
    * {$MESS_ACCOUNT }{$form.MESS_ACCOUNT}
    * {$MESS_PASSWORD}{$form.MESS_PASSWORD}
    {$form.MESS_TEST_MAIL }
    * {$MESS_TEST_MAIL_TO}{$form.MESS_TEST_MAIL_TO}
    {$form.MESS_BACKGROUND }
    * {$MESS_EXECUTE_EVERY}{$form.MESS_EXECUTE_EVERY }
    * {$MESS_SEND_MAX }{$form.MESS_SEND_MAX }
    {$form.MESS_TRY_SEND_INMEDIATLY }

    {$form.TEST}   {$form.SAVE_CHANGES }

    {$form.SAVE_CHANGES2}
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    +
    + +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/emails.xml b/workflow/engine/xmlform/setup/emails.xml new file mode 100644 index 000000000..d1f6328c5 --- /dev/null +++ b/workflow/engine/xmlform/setup/emails.xml @@ -0,0 +1,639 @@ + + + + + Configuration + + + + Enable Email Notifications + + + + select * from mails + Email Engine + + + + Server + + + + Port + + + + Require authentification + + + + Account From + + + + Password + + + + Send a test mail + + + + Mail to + + + + Run in the background + + + + Execute every (in minutes) + + + + Maximun number of mails sended by attempt + + + + Try send mails inmediatly + + + + Test + + + + Save Changes + + + Save Changes + + +Server response: '+msg+'
    '; + } + $('status_'+step).innerHTML += 'The test has Successful'; + } + else { + if( result == 'FAILED' ) { + $('status_'+step).innerHTML = 'The server response was '+msg+'
    '; + $('status_'+step).innerHTML += 'The test has Failed!'; + resultset = false; + } else { + setTimeout(response); + } + } + step += 1; + testSMTPHost(step); + } catch (e) { + if(resultset){ + $('form[SAVE_CHANGES]').disabled = false; + } + else { + $('form[SAVE_CHANGES]').disabled = true; + } + $('bnt_ok').style.display = 'block'; + return; + }; + } else { + var html = "

    "+G_STRINGS.DBCONNECTIONS_MSG3+"....
    "; // + $('status_'+step).innerHTML = html; + } + } + ajax.send(uri); +} + +function cancelTestConnection() +{ + oPanel.remove(); + /**if(resultset) { + new leimnud.module.app.confirm().make({ + label:'Do you send a test mail with this configuration?', + action:function(){ + testEmailConfiguration(); + }.extend(this) + }); + }**/ + resultset = true; +} + +///************* Adds routines *************/// +String.prototype.trim = function() { + return this.replace(/^\s+|\s+get/g,""); +} +function $(id) { + return document.getElementById(id); +} +function AJAX() +{ + try { + xmlhttp = new XMLHttpRequest(); + } + catch(generic_error) { + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (microsoft_old_error) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (microsoft_error) { + xmlhttp = false; + } + } + } + return xmlhttp; +} + + +function initSet(){ + //$('form[MESS_RAUTH]').checked = true; + hideRowById('MESS_TEST_MAIL_TO'); + if(!($('form[MESS_ENABLED]').checked)) { + hideRowById('MESS_ENGINE'); + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + hideRowById('MESS_BACKGROUND'); + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); + hideRowById('MESS_RAUTH'); + hideRowById('MESS_TEST_MAIL'); + hideRowById('MESS_TEST_MAIL_TO'); + hideRowById('TEST'); + hideRowById('SAVE_CHANGES'); + $('form[SAVE_CHANGES]').disabled = false; + } else { + hideRowById('SAVE_CHANGES2'); + if(getField('MESS_ENGINE').value == 'MAIL'){ + hideRowById('MESS_RAUTH'); + hideRowById('MESS_TEST_MAIL_TO'); + showRowById('TEST'); + showRowById('SAVE_CHANGES'); + } + } +} + +leimnud.event.add(getField('MESS_RAUTH'), 'click', function() { + if (this.checked) { + showRowById('MESS_PASSWORD'); + } else { + hideRowById('MESS_PASSWORD'); + } +}.extend(getField('MESS_RAUTH'))); + +leimnud.event.add(getField('MESS_TEST_MAIL'), 'click', function() { + if (this.checked) { + showRowById('MESS_TEST_MAIL_TO'); + + } else { + hideRowById('MESS_TEST_MAIL_TO'); + } +}.extend(getField('MESS_TEST_MAIL'))); + + +/** end test Connection Events **/ + + +leimnud.event.add(getField('MESS_ENABLED'), 'click', function() { + if (this.checked) { + showRowById('MESS_ENGINE'); + switch (getField('MESS_ENGINE').value) { + case 'MAIL': + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + hideRowById('SAVE_CHANGES2'); + showRowById('TEST'); + showRowById('MESS_TEST_MAIL'); + if ($('form[MESS_TEST_MAIL]').checked) { + showRowById('MESS_TEST_MAIL_TO'); + } else { + hideRowById('MESS_TEST_MAIL_TO'); + } + $('form[SAVE_CHANGES]').disabled = true; + + break; + case 'PHPMAILER': + hideRowById('SAVE_CHANGES2'); + case 'OPENMAIL': + showRowById('MESS_SERVER'); + showRowById('MESS_PORT'); + showRowById('MESS_ACCOUNT'); + showRowById('MESS_PASSWORD'); + showRowById('TEST'); + showRowById('MESS_RAUTH'); + showRowById('MESS_TEST_MAIL'); + if ($('form[MESS_TEST_MAIL]').checked) { + showRowById('MESS_TEST_MAIL_TO'); + } else { + hideRowById('MESS_TEST_MAIL_TO'); + } + $('form[SAVE_CHANGES]').disabled = true; + break; + } + //showRowById('MESS_BACKGROUND');////enable this line in the next release + if (getField('MESS_BACKGROUND').checked) { + showRowById('MESS_EXECUTE_EVERY'); + showRowById('MESS_SEND_MAX'); + showRowById('MESS_TRY_SEND_INMEDIATLY'); + } + else { + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); + } + } + else { + hideRowById('MESS_ENGINE'); + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + hideRowById('MESS_BACKGROUND'); + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); + hideRowById('TEST'); + hideRowById('MESS_RAUTH'); + hideRowById('MESS_TEST_MAIL'); + hideRowById('MESS_TEST_MAIL_TO'); + showRowById('SAVE_CHANGES2'); + $('form[SAVE_CHANGES]').disabled = false; + } +}.extend(getField('MESS_ENABLED'))); + +leimnud.event.add(getField('MESS_ENGINE'), 'change', function() { + switch (this.value) { + case 'MAIL': + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + hideRowById('MESS_RAUTH'); + showRowById('MESS_TEST_MAIL'); + if ($('form[MESS_TEST_MAIL]').checked) { + showRowById('MESS_TEST_MAIL_TO'); + } else { + hideRowById('MESS_TEST_MAIL_TO'); + } + $('form[SAVE_CHANGES]').disabled = true + break; + case 'PHPMAILER': + hideRowById('SAVE_CHANGES2'); + case 'OPENMAIL': + showRowById('MESS_SERVER'); + showRowById('MESS_PORT'); + showRowById('MESS_ACCOUNT'); + showRowById('MESS_PASSWORD'); + showRowById('TEST'); + showRowById('MESS_RAUTH'); + showRowById('MESS_TEST_MAIL'); + if ($('form[MESS_TEST_MAIL]').checked) { + showRowById('MESS_TEST_MAIL_TO'); + } else { + hideRowById('MESS_TEST_MAIL_TO'); + } + $('form[SAVE_CHANGES]').disabled = true; + break; + } +}.extend(getField('MESS_ENGINE'))); + +leimnud.event.add(getField('MESS_BACKGROUND'), 'click', function() { + if (this.checked) { + showRowById('MESS_EXECUTE_EVERY'); + showRowById('MESS_SEND_MAX'); + showRowById('MESS_TRY_SEND_INMEDIATLY'); + } + else { + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); + } +}.extend(getField('MESS_BACKGROUND'))); + +if (!getField('MESS_ENABLED').checked) { + hideRowById('MESS_ENGINE'); + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + hideRowById('MESS_BACKGROUND'); + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); + //hideRowById('TEST'); +} + +switch (getField('MESS_ENGINE').value) { + case 'MAIL': + hideRowById('MESS_SERVER'); + hideRowById('MESS_PORT'); + hideRowById('MESS_ACCOUNT'); + hideRowById('MESS_PASSWORD'); + break; + case 'PHPMAILER': + case 'OPENMAIL': + showRowById('MESS_SERVER'); + showRowById('MESS_PORT'); + showRowById('MESS_ACCOUNT'); + showRowById('MESS_PASSWORD'); + break; +} + +hideRowById('MESS_BACKGROUND');//delete this line in the next release +if (!getField('MESS_BACKGROUND').checked) { + hideRowById('MESS_EXECUTE_EVERY'); + hideRowById('MESS_SEND_MAX'); + hideRowById('MESS_TRY_SEND_INMEDIATLY'); +} + +var verifyData = function(oForm) { + if (getField('MESS_ENABLED').checked) { + switch (getField('MESS_ENGINE').value) { + case 'PHPMAILER': + case 'OPENMAIL': + oAux = getField('MESS_SERVER'); + if (oAux.value == '') { + alert(G_STRINGS.ID_MESS_SERVER_REQUIRED); + oAux.focus(); + return; + } + break; + } + if (getField('MESS_BACKGROUND').checked) { + oAux = getField('MESS_EXECUTE_EVERY'); + if (oAux.value == '') { + alert(G_STRINGS.ID_MESS_EXECUTE_EVERY_REQUIRED); + oAux.focus(); + return; + } + oAux = getField('MESS_SEND_MAX'); + if (oAux.value == '') { + alert(G_STRINGS.ID_MESS_SEND_MAX_REQUIRED); + oAux.focus(); + return; + } + } + } + oForm.submit(); +}; + +var oPanel; + +var testEmailConfiguration = function() { + if (getField('MESS_ENGINE').value != 'MAIL') { + oAux = getField('MESS_SERVER'); + if (oAux.value == '') { + alert(G_STRINGS.ID_MESS_SERVER_REQUIRED); + oAux.focus(); + return; + } + } + oPanel = new leimnud.module.panel(); + oPanel.options = { + size :{w:400,h:200}, + position:{x:0,y:0,center:true}, + title :"", + theme :"processmaker", + statusBar:false, + control :{resize:false,roll:false,drag:false}, + fx :{modal:true,opacity:true,blinkToFront:false,fadeIn:false,drag:false} + }; + oPanel.events = { + remove: function() { delete(oPanel); }.extend(this) + }; + oPanel.make(); + oPanel.loader.show(); + var oRPC = new leimnud.module.rpc.xmlhttp({ + url : 'emails_Ajax', + args: 'action=testEmailConfiguration&usermail='+account + }); + oRPC.callback = function(rpc){ + oPanel.loader.hide(); + oPanel.addContent(rpc.xmlhttp.responseText); + var scs = rpc.xmlhttp.responseText.extractScript(); + scs.evalScript(); + }.extend(this); + oRPC.make(); +}; + +var closeTestPanel = function() { + oPanel.remove(); +}; + +initSet(); + +]]>
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/emails_Sended.xml b/workflow/engine/xmlform/setup/emails_Sended.xml new file mode 100644 index 000000000..0edf7f02a --- /dev/null +++ b/workflow/engine/xmlform/setup/emails_Sended.xml @@ -0,0 +1,14 @@ + + + + + + + @#MESSAGE_VALUE + + + + Close + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/emails_TestForm.xml b/workflow/engine/xmlform/setup/emails_TestForm.xml new file mode 100644 index 000000000..bfd03dc6f --- /dev/null +++ b/workflow/engine/xmlform/setup/emails_TestForm.xml @@ -0,0 +1,68 @@ + + + + + Mail Configuration Test Page + + + + From Name: + + + + From Email: + + + + To: + + + + Send Email + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/holiday.xml b/workflow/engine/xmlform/setup/holiday.xml new file mode 100644 index 000000000..fb3f85b9e --- /dev/null +++ b/workflow/engine/xmlform/setup/holiday.xml @@ -0,0 +1,19 @@ + + + + + Holiday + + + + Date + + + + Description + + + + Accept + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/holidayList.xml b/workflow/engine/xmlform/setup/holidayList.xml new file mode 100644 index 000000000..2d3d4f990 --- /dev/null +++ b/workflow/engine/xmlform/setup/holidayList.xml @@ -0,0 +1,20 @@ + + + + + UID + + + + Date + + + + Description + + + + Delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/holidayListMenu.xml b/workflow/engine/xmlform/setup/holidayListMenu.xml new file mode 100644 index 000000000..70d0f8624 --- /dev/null +++ b/workflow/engine/xmlform/setup/holidayListMenu.xml @@ -0,0 +1,6 @@ + + + + New + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/language.xml b/workflow/engine/xmlform/setup/language.xml new file mode 100644 index 000000000..c65475914 --- /dev/null +++ b/workflow/engine/xmlform/setup/language.xml @@ -0,0 +1,16 @@ + + + + <en>Language</en> + + +Language + + + + Add + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/language_table.xml b/workflow/engine/xmlform/setup/language_table.xml new file mode 100644 index 000000000..bb7b7ef13 --- /dev/null +++ b/workflow/engine/xmlform/setup/language_table.xml @@ -0,0 +1,16 @@ + + + + <en>Language</en> + + + +SELECT LAN_ID,LAN_NAME FROM LANGUAGE ORDER BY LAN_NAME + Language + + + + Add + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/languages.xml b/workflow/engine/xmlform/setup/languages.xml new file mode 100644 index 000000000..bb68b2425 --- /dev/null +++ b/workflow/engine/xmlform/setup/languages.xml @@ -0,0 +1,12 @@ + + + + Code + + + Language + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/languages_ImportForm.html b/workflow/engine/xmlform/setup/languages_ImportForm.html new file mode 100644 index 000000000..eab653857 --- /dev/null +++ b/workflow/engine/xmlform/setup/languages_ImportForm.html @@ -0,0 +1,34 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$LANGUAGE_FILENAME}{$form.LANGUAGE_FILENAME}
    {$form.IMPORT}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/languages_ImportForm.xml b/workflow/engine/xmlform/setup/languages_ImportForm.xml new file mode 100644 index 000000000..0b2a20e86 --- /dev/null +++ b/workflow/engine/xmlform/setup/languages_ImportForm.xml @@ -0,0 +1,34 @@ + + + + + Import or Update Language + + + + File + + + + Import + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/languages_Options.xml b/workflow/engine/xmlform/setup/languages_Options.xml new file mode 100644 index 000000000..922861701 --- /dev/null +++ b/workflow/engine/xmlform/setup/languages_Options.xml @@ -0,0 +1,42 @@ + + + + Import / Update + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/location.html b/workflow/engine/xmlform/setup/location.html new file mode 100644 index 000000000..905828cd8 --- /dev/null +++ b/workflow/engine/xmlform/setup/location.html @@ -0,0 +1,52 @@ + + +
    + + + + +
    {TITLE}
    + + + + + + + + + + + +
    {USR_COUNTRY} + {form[USR_COUNTRY]} +
    {USR_CITY} + {form[USR_CITY]} + + {form[ADD_CITY]} +
    + {form[USR_SUBMIT]} +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/location.xml b/workflow/engine/xmlform/setup/location.xml new file mode 100644 index 000000000..407ee5f39 --- /dev/null +++ b/workflow/engine/xmlform/setup/location.xml @@ -0,0 +1,34 @@ + + + + + Region + منطقه + + + + Add + اضاÙÙ‡ کردن + + + <es><![CDATA[Región]]></es> + <en>Region</en> + + + COUNTRIES + + + +select uid, caption from TERRITORY where RELATION = @@USR_COUNTRY + CITY + + + + Add city + + + + ACCEPT + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/logo_Option.xml b/workflow/engine/xmlform/setup/logo_Option.xml new file mode 100755 index 000000000..db610391b --- /dev/null +++ b/workflow/engine/xmlform/setup/logo_Option.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + +function deleteLogo(nameLogo) { + +new leimnud.module.app.confirm().make({ +label:'@G::LoadTranslation(ID_MSG_CONFIRM_DELETE_CASES)', +action:function(){ +ajax_function('logo_Delete','','NAMELOGO='+nameLogo,'GET') ; +window.location = 'uplogo'; + +}}); + +return false; + +} + +function changeLogo(nameLogo) +{ + ajax_function('replacementLogo','','NAMELOGO='+nameLogo,'GET') ; + window.location = 'uplogo'; +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/mail.xml b/workflow/engine/xmlform/setup/mail.xml new file mode 100644 index 000000000..65da81e90 --- /dev/null +++ b/workflow/engine/xmlform/setup/mail.xml @@ -0,0 +1,41 @@ + + + + Email Settings + + + + Method + + + + Server + + + + Port + + + Timeout + + + + Requires Authentication + + + + Email Account + + + + Password + + + + Save + + + + Test + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/mailTest.xml b/workflow/engine/xmlform/setup/mailTest.xml new file mode 100644 index 000000000..0d501db99 --- /dev/null +++ b/workflow/engine/xmlform/setup/mailTest.xml @@ -0,0 +1,14 @@ + + + + Test Email + + + + Send to : + + + + Test + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/noProcesses.xml b/workflow/engine/xmlform/setup/noProcesses.xml new file mode 100644 index 000000000..6f4b888a4 --- /dev/null +++ b/workflow/engine/xmlform/setup/noProcesses.xml @@ -0,0 +1,8 @@ + + + + + No processes available for this environment + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/pluginImport.html b/workflow/engine/xmlform/setup/pluginImport.html new file mode 100644 index 000000000..11cd4c79f --- /dev/null +++ b/workflow/engine/xmlform/setup/pluginImport.html @@ -0,0 +1,37 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$MAX_FILE_SIZE}{$form.MAX_FILE_SIZE}
    {$PLUGIN_FILENAME}{$form.PLUGIN_FILENAME}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/pluginImport.xml b/workflow/engine/xmlform/setup/pluginImport.xml new file mode 100644 index 000000000..d5c898366 --- /dev/null +++ b/workflow/engine/xmlform/setup/pluginImport.xml @@ -0,0 +1,41 @@ + + + + + Import Plugin + + + + Max upload file size in bytes + + + + File + + + + Import + + + + Cancel + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/pluginList.xml b/workflow/engine/xmlform/setup/pluginList.xml new file mode 100644 index 000000000..f6ffef07f --- /dev/null +++ b/workflow/engine/xmlform/setup/pluginList.xml @@ -0,0 +1,38 @@ + + + + + # + + + + <en>Name (File)</en> + + + + Description + + + + Version + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/plugin_ListOptions.xml b/workflow/engine/xmlform/setup/plugin_ListOptions.xml new file mode 100644 index 000000000..df5f620ef --- /dev/null +++ b/workflow/engine/xmlform/setup/plugin_ListOptions.xml @@ -0,0 +1,6 @@ + + + + Import + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/processHeartBeatConfig.html b/workflow/engine/xmlform/setup/processHeartBeatConfig.html new file mode 100755 index 000000000..f774fe6df --- /dev/null +++ b/workflow/engine/xmlform/setup/processHeartBeatConfig.html @@ -0,0 +1,44 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    {$form.HB_TITLE} {$form.HB_LINKINFO}
    +
    {$HB_OPTION}{$form.HB_OPTION}
    {$form.HB_SAVE}
    {$HB_LINKINFO}
    +
    +
    +
    +
    + +
    + + + + diff --git a/workflow/engine/xmlform/setup/processHeartBeatConfig.xml b/workflow/engine/xmlform/setup/processHeartBeatConfig.xml new file mode 100755 index 000000000..a82a777d9 --- /dev/null +++ b/workflow/engine/xmlform/setup/processHeartBeatConfig.xml @@ -0,0 +1,30 @@ + + + + + Processmaker Heartbeat + + + + Enable Heartbeat + + + + + + + save + + + + + + var sendValues=function(form){ + var hbOption = getField('HB_OPTION').value; + ajax_function('processHeartBeatSave','','HB_OPTION='+hbOption,'POST') ; + window.location = 'processHeartBeatConfig'; + }; + + + diff --git a/workflow/engine/xmlform/setup/showMessage.xml b/workflow/engine/xmlform/setup/showMessage.xml new file mode 100755 index 000000000..8d310b279 --- /dev/null +++ b/workflow/engine/xmlform/setup/showMessage.xml @@ -0,0 +1,9 @@ + + + + <en>Error</en> +<es>Error</es> + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/skinsList.xml b/workflow/engine/xmlform/setup/skinsList.xml new file mode 100755 index 000000000..9eeb6f653 --- /dev/null +++ b/workflow/engine/xmlform/setup/skinsList.xml @@ -0,0 +1,24 @@ + + + + + # + + + + Name (File) + + + + Description + + + + Version + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/skinsListOptions.xml b/workflow/engine/xmlform/setup/skinsListOptions.xml new file mode 100755 index 000000000..7d2a0b098 --- /dev/null +++ b/workflow/engine/xmlform/setup/skinsListOptions.xml @@ -0,0 +1,8 @@ + + + + + New + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/skinsNew.html b/workflow/engine/xmlform/setup/skinsNew.html new file mode 100644 index 000000000..944e1153d --- /dev/null +++ b/workflow/engine/xmlform/setup/skinsNew.html @@ -0,0 +1,43 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    * {$NAME}{$form.NAME}
    {$DESCRIPTION}{$form.DESCRIPTION}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php} +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/skinsNew.xml b/workflow/engine/xmlform/setup/skinsNew.xml new file mode 100644 index 000000000..283da2991 --- /dev/null +++ b/workflow/engine/xmlform/setup/skinsNew.xml @@ -0,0 +1,45 @@ + + + + + New Skin + + + + + Skin Name + + + + Description + + + + Continue + + + + Cancel + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/upgrade.xml b/workflow/engine/xmlform/setup/upgrade.xml new file mode 100644 index 000000000..70b8d5683 --- /dev/null +++ b/workflow/engine/xmlform/setup/upgrade.xml @@ -0,0 +1,47 @@ + + + + + Upgrade System + + + + + Current Version + + + + Max upload file size in bytes + + + + File + + + + + + Upgrade + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/uplogo.xml b/workflow/engine/xmlform/setup/uplogo.xml new file mode 100755 index 000000000..74fe0ffca --- /dev/null +++ b/workflow/engine/xmlform/setup/uplogo.xml @@ -0,0 +1,36 @@ + + + + + Upload your logo + + + + Max upload file size in bytes + + + + File + + + + + + Upload + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/uplogoList.xml b/workflow/engine/xmlform/setup/uplogoList.xml new file mode 100755 index 000000000..96313a971 --- /dev/null +++ b/workflow/engine/xmlform/setup/uplogoList.xml @@ -0,0 +1,27 @@ + + + + + No. + + + imagen + + + name + + + size + + + + Description + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/webServicesDetails.xml b/workflow/engine/xmlform/setup/webServicesDetails.xml new file mode 100755 index 000000000..32fb7863e --- /dev/null +++ b/workflow/engine/xmlform/setup/webServicesDetails.xml @@ -0,0 +1,28 @@ + + + + + WSDL Server Details + + + + Server + + + + Port + + + + WSDL URI + + + + Workspace + Espacio de Trabajo + + + + Session ID + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/webServicesSetup.html b/workflow/engine/xmlform/setup/webServicesSetup.html new file mode 100644 index 000000000..0c8ef1b16 --- /dev/null +++ b/workflow/engine/xmlform/setup/webServicesSetup.html @@ -0,0 +1,48 @@ +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.title2}
    {$WS_PROTOCOL}{$form.WS_PROTOCOL}
    {$WS_HOST}{$form.WS_HOST}
    {$WS_WORKSPACE}{$form.WS_WORKSPACE}
    {$WS_PORT}{$form.WS_PORT}
    {$form.button}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/webServicesSetup.xml b/workflow/engine/xmlform/setup/webServicesSetup.xml new file mode 100644 index 000000000..a575ca866 --- /dev/null +++ b/workflow/engine/xmlform/setup/webServicesSetup.xml @@ -0,0 +1,42 @@ + + + + + Client Setup + + + + select * from protocol + Protocol +Protocolo + + + Server Host +Host Servidor + + + Workspace +Espacio de Trabajo + + + Port +Puerto + + + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/weekend.xml b/workflow/engine/xmlform/setup/weekend.xml new file mode 100644 index 000000000..55a369d52 --- /dev/null +++ b/workflow/engine/xmlform/setup/weekend.xml @@ -0,0 +1,31 @@ + + + + Weekend days + + + Monday + + + Tuesday + + + Wednesday + + + Thursday + + + Friday + + + Saturday + + + Sunday + + + Accept + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/workPeriod.xml b/workflow/engine/xmlform/setup/workPeriod.xml new file mode 100644 index 000000000..dce11c6d2 --- /dev/null +++ b/workflow/engine/xmlform/setup/workPeriod.xml @@ -0,0 +1,59 @@ + + + + Weekend days + + + Sunday + + + Monday + + + Tuesday + + + Wednesday + + + Thursday + + + Friday + + + Saturday + + + + First Period + + + + Start time + + + + + End time + + + + + Second period + + + + Start time + + + + + End time + + + + Accept + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsAssignUserToGroup.xml b/workflow/engine/xmlform/setup/wsAssignUserToGroup.xml new file mode 100644 index 000000000..65cc7ee8c --- /dev/null +++ b/workflow/engine/xmlform/setup/wsAssignUserToGroup.xml @@ -0,0 +1,26 @@ + + + + + Session Id + + + + SELECT * from user + User ID +ID User + + + SELECT * from group + Group ID +ID Group + + + + + + AssignUserToGroup + Usuario Asignado para un Grupo + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsCaseList.xml b/workflow/engine/xmlform/setup/wsCaseList.xml new file mode 100644 index 000000000..c8a3e2290 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsCaseList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + CaseList +Lista de casos + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsCreateUser.xml b/workflow/engine/xmlform/setup/wsCreateUser.xml new file mode 100644 index 000000000..7e78c280d --- /dev/null +++ b/workflow/engine/xmlform/setup/wsCreateUser.xml @@ -0,0 +1,42 @@ + + + + + Session Id + + + + User ID +ID de Usuario + + + Password + + + + First Name +Nombres + + + Last Name +Apellidos + + + Email + + + + SELECT * from role + Role +Rol + + + + + + + CreateUser + Craer Usuario + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsDerivateCase.xml b/workflow/engine/xmlform/setup/wsDerivateCase.xml new file mode 100644 index 000000000..fb7d2091d --- /dev/null +++ b/workflow/engine/xmlform/setup/wsDerivateCase.xml @@ -0,0 +1,25 @@ + + + + + Session Id + + + + SELECT * from case + Case ID + + + + SELECT * from taskCases + Task Case(delindex) + + + + + + + DerivateCase + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsGroupList.xml b/workflow/engine/xmlform/setup/wsGroupList.xml new file mode 100644 index 000000000..3cd2f348a --- /dev/null +++ b/workflow/engine/xmlform/setup/wsGroupList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + GroupList +Lista de Grupo + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsInputDocumentList.xml b/workflow/engine/xmlform/setup/wsInputDocumentList.xml new file mode 100644 index 000000000..da0645631 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsInputDocumentList.xml @@ -0,0 +1,20 @@ + + + + + Session Id + + + + SELECT * from case + Case ID + + + + + + + InputDocumentList + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsInputDocumentProcessList.xml b/workflow/engine/xmlform/setup/wsInputDocumentProcessList.xml new file mode 100755 index 000000000..8b0647c42 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsInputDocumentProcessList.xml @@ -0,0 +1,20 @@ + + + + + Session Id + + + + SELECT * from process + Process ID + + + + + + + InputDocumentProcessList + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsLogin.xml b/workflow/engine/xmlform/setup/wsLogin.xml new file mode 100644 index 000000000..3398ddb0b --- /dev/null +++ b/workflow/engine/xmlform/setup/wsLogin.xml @@ -0,0 +1,43 @@ + + + + + <en>Login to WSDL Server</en> + + + + User ID + + + + Password + + + + + + + Login + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsMessage.xml b/workflow/engine/xmlform/setup/wsMessage.xml new file mode 100644 index 000000000..cac96d591 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsMessage.xml @@ -0,0 +1,8 @@ + + + + + You do not have enabled the SOAP extension + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsNewCase.xml b/workflow/engine/xmlform/setup/wsNewCase.xml new file mode 100644 index 000000000..5d498b108 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsNewCase.xml @@ -0,0 +1,27 @@ + + + + + Session Id + + + + SELECT * from process + Process ID +ID de Proceso + + + SELECT * from task + Task ID +ID de Tarea + + + + + + + + NewCase +Caso Nuevo + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsNewCaseImpersonate.xml b/workflow/engine/xmlform/setup/wsNewCaseImpersonate.xml new file mode 100644 index 000000000..038464853 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsNewCaseImpersonate.xml @@ -0,0 +1,27 @@ + + + + + Session Id + + + + SELECT * from process + Process ID +ID Proceso + + + SELECT * from user + User ID +ID Usuario + + + + + + + + NewCaseImpersonate +Nuevo caso + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsOutputDocumentList.xml b/workflow/engine/xmlform/setup/wsOutputDocumentList.xml new file mode 100644 index 000000000..d872443c3 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsOutputDocumentList.xml @@ -0,0 +1,21 @@ + + + + + Session Id + + + + SELECT * from case + Case ID + + + + + + + + OutputDocumentList + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsProcessList.xml b/workflow/engine/xmlform/setup/wsProcessList.xml new file mode 100644 index 000000000..39b8c3350 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsProcessList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + ProcessList +Lista de Proceso + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsReassignCase.xml b/workflow/engine/xmlform/setup/wsReassignCase.xml new file mode 100644 index 000000000..34c55123c --- /dev/null +++ b/workflow/engine/xmlform/setup/wsReassignCase.xml @@ -0,0 +1,35 @@ + + + + + Session Id + + + + SELECT * from case + Case ID + + + + SELECT * from taskCases + Delindex + + + + SELECT * from user + User Source + + + + SELECT * from user + User Target + + + + + + + ReassignCase + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsRemoveDocument.xml b/workflow/engine/xmlform/setup/wsRemoveDocument.xml new file mode 100755 index 000000000..5e7d842a4 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsRemoveDocument.xml @@ -0,0 +1,20 @@ + + + + + Session Id + + + + SELECT * from documents + Document ID + + + + + + + RemoveDocument + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsRoleList.xml b/workflow/engine/xmlform/setup/wsRoleList.xml new file mode 100644 index 000000000..c0f23b55c --- /dev/null +++ b/workflow/engine/xmlform/setup/wsRoleList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + RoleList +Lista de Roles + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsSendFiles.xml b/workflow/engine/xmlform/setup/wsSendFiles.xml new file mode 100644 index 000000000..5d14a28f1 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsSendFiles.xml @@ -0,0 +1,52 @@ + + + + + Session Id + + + + + + + + Send your file to the server + + + + Upload Option + + + + SELECT * from documents + Input Document + + + + File to Send + + + + + + + Sending + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsSendMessage.xml b/workflow/engine/xmlform/setup/wsSendMessage.xml new file mode 100644 index 000000000..f535a7943 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsSendMessage.xml @@ -0,0 +1,44 @@ + + + + + Session Id + + + + SELECT * from case + Case ID + + + + From + + + + TO + + + + CC + + + + BCC + + + + Subject + + + + Message + + + + + + + SendMessage +Enviar Mensaje + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsSendVariables.xml b/workflow/engine/xmlform/setup/wsSendVariables.xml new file mode 100644 index 000000000..a052f4ca3 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsSendVariables.xml @@ -0,0 +1,36 @@ + + + + + Session Id + + + + SELECT * from case + Case ID +ID de Caso + + + Name 1 +Nombre 1 + + + Value 1 +Valor 1 + + + Name 2 +Nombre 2 + + + Value 2 +Valor 2 + + + + + + SendVariables +Variables Enviadas + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsShowResult.xml b/workflow/engine/xmlform/setup/wsShowResult.xml new file mode 100644 index 000000000..4beed2f1a --- /dev/null +++ b/workflow/engine/xmlform/setup/wsShowResult.xml @@ -0,0 +1,15 @@ + + + + + Status Code + + + + Message +Mensaje + + + Time Stamp +Time Stamp + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsTaskCase.xml b/workflow/engine/xmlform/setup/wsTaskCase.xml new file mode 100644 index 000000000..5b1a8520e --- /dev/null +++ b/workflow/engine/xmlform/setup/wsTaskCase.xml @@ -0,0 +1,20 @@ + + + + + Session Id + + + + SELECT * from case + Case ID +ID de Caso + + + + + + TaskCase +Caso de Tareas + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsTaskList.xml b/workflow/engine/xmlform/setup/wsTaskList.xml new file mode 100644 index 000000000..e8c95e6c8 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsTaskList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + TaskList +Lista de Tarea + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsTriggerList.xml b/workflow/engine/xmlform/setup/wsTriggerList.xml new file mode 100644 index 000000000..6fb4d469a --- /dev/null +++ b/workflow/engine/xmlform/setup/wsTriggerList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + TriggerList + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsUserList.xml b/workflow/engine/xmlform/setup/wsUserList.xml new file mode 100644 index 000000000..7899fc905 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsUserList.xml @@ -0,0 +1,15 @@ + + + + + Session Id + + + + + + + UserList +Lista de Usuario + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsVariablesGrid.xml b/workflow/engine/xmlform/setup/wsVariablesGrid.xml new file mode 100644 index 000000000..f23a7796c --- /dev/null +++ b/workflow/engine/xmlform/setup/wsVariablesGrid.xml @@ -0,0 +1,9 @@ + + + + Name +Nombre + + Value +Valor + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrCaseList.xml b/workflow/engine/xmlform/setup/wsrCaseList.xml new file mode 100644 index 000000000..507cb1292 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrCaseList.xml @@ -0,0 +1,20 @@ + + + + + GUID + + + + Case Title + + + + Status + + + + Del Index + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrGroupList.xml b/workflow/engine/xmlform/setup/wsrGroupList.xml new file mode 100644 index 000000000..28be59065 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrGroupList.xml @@ -0,0 +1,12 @@ + + + + + GUID + + + + Group Title + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrInputDocumentList.xml b/workflow/engine/xmlform/setup/wsrInputDocumentList.xml new file mode 100644 index 000000000..61d35a04d --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrInputDocumentList.xml @@ -0,0 +1,30 @@ + + + + + + + Filename + + + + Document GUID + + + + version + + + + create Date + + + + created by + + + + type + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrInputDocumentProcessList.xml b/workflow/engine/xmlform/setup/wsrInputDocumentProcessList.xml new file mode 100755 index 000000000..d91e051c7 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrInputDocumentProcessList.xml @@ -0,0 +1,18 @@ + + + + + + InputDocument GUID + + + + Name + + + + description + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrOutputDocumentList.xml b/workflow/engine/xmlform/setup/wsrOutputDocumentList.xml new file mode 100644 index 000000000..4a5b1b3d7 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrOutputDocumentList.xml @@ -0,0 +1,30 @@ + + + + + + + Filename + + + + Document GUID + + + + version + + + + create Date + + + + created by + + + + type + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrProcessList.xml b/workflow/engine/xmlform/setup/wsrProcessList.xml new file mode 100644 index 000000000..6e63e047d --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrProcessList.xml @@ -0,0 +1,13 @@ + + + + + GUID +GUID + + + Process Title + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrRoleList.xml b/workflow/engine/xmlform/setup/wsrRoleList.xml new file mode 100644 index 000000000..eb9a46e3b --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrRoleList.xml @@ -0,0 +1,12 @@ + + + + + GUID +GUID + + + Role Title + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrTaskCase.xml b/workflow/engine/xmlform/setup/wsrTaskCase.xml new file mode 100644 index 000000000..2de1dd9ee --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrTaskCase.xml @@ -0,0 +1,12 @@ + + + + + Del Index +Del Index + + + Task Title + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrTaskList.xml b/workflow/engine/xmlform/setup/wsrTaskList.xml new file mode 100644 index 000000000..9c07832c5 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrTaskList.xml @@ -0,0 +1,12 @@ + + + + + GUID +GUID + + + Task Title + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrTriggerList.xml b/workflow/engine/xmlform/setup/wsrTriggerList.xml new file mode 100644 index 000000000..67a916115 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrTriggerList.xml @@ -0,0 +1,16 @@ + + + + + GUID + + + + Task Title + + + + Process GUID/Title + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/setup/wsrUserList.xml b/workflow/engine/xmlform/setup/wsrUserList.xml new file mode 100644 index 000000000..4c166ac50 --- /dev/null +++ b/workflow/engine/xmlform/setup/wsrUserList.xml @@ -0,0 +1,12 @@ + + + + + GUID +GUID + + + User +Usuario + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/conditions_Edit.xml b/workflow/engine/xmlform/steps/conditions_Edit.xml new file mode 100644 index 000000000..c0f3325b6 --- /dev/null +++ b/workflow/engine/xmlform/steps/conditions_Edit.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Condition + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/conditions_List.xml b/workflow/engine/xmlform/steps/conditions_List.xml new file mode 100644 index 000000000..6b294a873 --- /dev/null +++ b/workflow/engine/xmlform/steps/conditions_List.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + Title + + + + Condition + + + + + + + Apply Filter + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/conditions_Options.xml b/workflow/engine/xmlform/steps/conditions_Options.xml new file mode 100644 index 000000000..2575789a8 --- /dev/null +++ b/workflow/engine/xmlform/steps/conditions_Options.xml @@ -0,0 +1,23 @@ + + + + + + + + + +function editCondition(uid, sStepTitle) +{ + popupWindow('@G::LoadTranslation(ID_EDIT_CONDITIONS_OF_STEP)' + ': ' + sStepTitle, '@G::encryptLink(@#URL_CONDITIONS_EDIT)?UID='+ uid , 500, 216); +} + +function saveCondition(oForm) +{ + ajax_post(oForm.action, oForm, 'POST'); + currentPopupWindow.remove(); + @#PAGED_TABLE_ID.refresh(); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/steps_List.xml b/workflow/engine/xmlform/steps/steps_List.xml new file mode 100644 index 000000000..bb083a10f --- /dev/null +++ b/workflow/engine/xmlform/steps/steps_List.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + Title + + + + Type + + + + + + + + + + + + + Apply Filter + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/steps_Options.xml b/workflow/engine/xmlform/steps/steps_Options.xml new file mode 100644 index 000000000..af4d64498 --- /dev/null +++ b/workflow/engine/xmlform/steps/steps_Options.xml @@ -0,0 +1,75 @@ + + + + + New + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/steps_availableBB.xml b/workflow/engine/xmlform/steps/steps_availableBB.xml new file mode 100644 index 000000000..3528850a3 --- /dev/null +++ b/workflow/engine/xmlform/steps/steps_availableBB.xml @@ -0,0 +1,24 @@ + + + + + + + Title + + + Type + + + + Mode + + + + + +function pagedTableFilter( form ) { + @#PAGED_TABLE_ID.doFilter( form ); +} + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggersAfter_List.xml b/workflow/engine/xmlform/steps/triggersAfter_List.xml new file mode 100644 index 000000000..1f7b3aa98 --- /dev/null +++ b/workflow/engine/xmlform/steps/triggersAfter_List.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + Title + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggersAfter_Options.xml b/workflow/engine/xmlform/steps/triggersAfter_Options.xml new file mode 100644 index 000000000..555270d2e --- /dev/null +++ b/workflow/engine/xmlform/steps/triggersAfter_Options.xml @@ -0,0 +1,13 @@ + + + + + + + Add + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggersBefore_List.xml b/workflow/engine/xmlform/steps/triggersBefore_List.xml new file mode 100644 index 000000000..0af177241 --- /dev/null +++ b/workflow/engine/xmlform/steps/triggersBefore_List.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + Title + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggersBefore_Options.xml b/workflow/engine/xmlform/steps/triggersBefore_Options.xml new file mode 100644 index 000000000..43c1b4a73 --- /dev/null +++ b/workflow/engine/xmlform/steps/triggersBefore_Options.xml @@ -0,0 +1,13 @@ + + + + + + + Add + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggersCondition_Edit.xml b/workflow/engine/xmlform/steps/triggersCondition_Edit.xml new file mode 100644 index 000000000..3957225ea --- /dev/null +++ b/workflow/engine/xmlform/steps/triggersCondition_Edit.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + +Condition + + + + + +Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggers_Assign.xml b/workflow/engine/xmlform/steps/triggers_Assign.xml new file mode 100644 index 000000000..1dc657bc8 --- /dev/null +++ b/workflow/engine/xmlform/steps/triggers_Assign.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + <en>Available Triggers</en> + + +Triggers + + + + + +Condition + + + +Assign + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/steps/triggers_NoAssign.xml b/workflow/engine/xmlform/steps/triggers_NoAssign.xml new file mode 100644 index 000000000..689894357 --- /dev/null +++ b/workflow/engine/xmlform/steps/triggers_NoAssign.xml @@ -0,0 +1,12 @@ + + + + +All the triggers available were assigned! + + + +Close + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_AssignmentRules.xml b/workflow/engine/xmlform/tasks/tasks_AssignmentRules.xml new file mode 100644 index 000000000..85507a740 --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_AssignmentRules.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + Case to be assigned by + + + + Variable for Value Based Assignment + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_Definition.xml b/workflow/engine/xmlform/tasks/tasks_Definition.xml new file mode 100644 index 000000000..84f6aa7a2 --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_Definition.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + Title + + + + Description + + + + Variable for Case priority + + + + Starting task + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_Labels.xml b/workflow/engine/xmlform/tasks/tasks_Labels.xml new file mode 100644 index 000000000..a98d472ed --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_Labels.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + Case Title + + + + Case Description + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_Notifications.xml b/workflow/engine/xmlform/tasks/tasks_Notifications.xml new file mode 100644 index 000000000..90f8f5b51 --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_Notifications.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + After routing notify the next assigned user(s). + + + + Message + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_Owner.xml b/workflow/engine/xmlform/tasks/tasks_Owner.xml new file mode 100644 index 000000000..3df914dbe --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_Owner.xml @@ -0,0 +1,12 @@ + + + + + + + + + Set task performer as + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_Permissions.xml b/workflow/engine/xmlform/tasks/tasks_Permissions.xml new file mode 100644 index 000000000..b50115c68 --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_Permissions.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + Exceptions Handling + + + + + + + + Allow arbitrary transfer (Ad hoc) + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tasks/tasks_TimingControl.xml b/workflow/engine/xmlform/tasks/tasks_TimingControl.xml new file mode 100644 index 000000000..91247eee9 --- /dev/null +++ b/workflow/engine/xmlform/tasks/tasks_TimingControl.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + Task duration + + + + Time unit + + + + Count days by + + +SELECT CALENDAR_UID, CALENDAR_NAME FROM availableCalendars +Calendar + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tools/translationAdd.xml b/workflow/engine/xmlform/tools/translationAdd.xml new file mode 100644 index 000000000..47a83bf55 --- /dev/null +++ b/workflow/engine/xmlform/tools/translationAdd.xml @@ -0,0 +1,25 @@ + + + + + + Insert Translation + + + + category + + + + Id + + + + value + + + + save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tools/translationsList.xml b/workflow/engine/xmlform/tools/translationsList.xml new file mode 100644 index 000000000..f6addf5af --- /dev/null +++ b/workflow/engine/xmlform/tools/translationsList.xml @@ -0,0 +1,33 @@ + + + + + Category + + + + Id + + + + Value + + + + Edit + + + + Delete + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tools/updateTranslation.xml b/workflow/engine/xmlform/tools/updateTranslation.xml new file mode 100644 index 000000000..4ce62dc8b --- /dev/null +++ b/workflow/engine/xmlform/tools/updateTranslation.xml @@ -0,0 +1,29 @@ + + + + + + UpdateTranslation + + + + file + + + + rows + + + + JavaScript Update Translation + + + + file + + + + rows + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/login.xml b/workflow/engine/xmlform/tracker/login.xml new file mode 100644 index 000000000..d54543388 --- /dev/null +++ b/workflow/engine/xmlform/tracker/login.xml @@ -0,0 +1,18 @@ + + + + <en>CASE TRACKER</en> + + + + Case Code + + + + Pin + + + + Enter + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_AvailableCaseTrackerObjects.xml b/workflow/engine/xmlform/tracker/tracker_AvailableCaseTrackerObjects.xml new file mode 100644 index 000000000..4c18be443 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_AvailableCaseTrackerObjects.xml @@ -0,0 +1,18 @@ + + + + + + + + + Title + + + + Type + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_AvailableStageTasks.xml b/workflow/engine/xmlform/tracker/tracker_AvailableStageTasks.xml new file mode 100644 index 000000000..9fb7baa1d --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_AvailableStageTasks.xml @@ -0,0 +1,14 @@ + + + + + + + + + Title + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ConditionsEdit.xml b/workflow/engine/xmlform/tracker/tracker_ConditionsEdit.xml new file mode 100644 index 000000000..4329a0771 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ConditionsEdit.xml @@ -0,0 +1,74 @@ + + + + + + + + + Condition + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_Configuration.html b/workflow/engine/xmlform/tracker/tracker_Configuration.html new file mode 100644 index 000000000..4e48907e5 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_Configuration.html @@ -0,0 +1,38 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$CT_MAP_TYPE}{$form.CT_MAP_TYPE}  
    {$form.CT_DERIVATION_HISTORY}
    {$form.CT_MESSAGE_HISTORY}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    diff --git a/workflow/engine/xmlform/tracker/tracker_Configuration.xml b/workflow/engine/xmlform/tracker/tracker_Configuration.xml new file mode 100644 index 000000000..bbf05b516 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_Configuration.xml @@ -0,0 +1,96 @@ + + + + + + + Map type + + + + Edit + + + + Derivation History + + + + Messages History + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_DynaDocs.xml b/workflow/engine/xmlform/tracker/tracker_DynaDocs.xml new file mode 100644 index 000000000..87ae11a15 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_DynaDocs.xml @@ -0,0 +1,18 @@ + + + + + + + Title + + + + Type + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_Inputdocs.xml b/workflow/engine/xmlform/tracker/tracker_Inputdocs.xml new file mode 100644 index 000000000..8233c8606 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_Inputdocs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + <en>Filename/Comments</en> + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_Messages.xml b/workflow/engine/xmlform/tracker/tracker_Messages.xml new file mode 100644 index 000000000..10eb9660b --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_Messages.xml @@ -0,0 +1,27 @@ + + + + + + + + DATE + + + + SUBJECT + + + + FROM + + + + TO + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_MessagesView.xml b/workflow/engine/xmlform/tracker/tracker_MessagesView.xml new file mode 100644 index 000000000..63673c632 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_MessagesView.xml @@ -0,0 +1,32 @@ + + + + + + + + + <en>MESSAGE</en> + + + + SUBJECT + + + + FROM + + + + TO + + + + DATE + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_No.xml b/workflow/engine/xmlform/tracker/tracker_No.xml new file mode 100644 index 000000000..6a4d416d0 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_No.xml @@ -0,0 +1,10 @@ + + + + + + It is not possible to see information related to this case. Please contact the System Administrator. + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_Outputdocs.xml b/workflow/engine/xmlform/tracker/tracker_Outputdocs.xml new file mode 100644 index 000000000..c13241f20 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_Outputdocs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + <en>Title</en> + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_StageEdit.xml b/workflow/engine/xmlform/tracker/tracker_StageEdit.xml new file mode 100644 index 000000000..2463165d3 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_StageEdit.xml @@ -0,0 +1,32 @@ + + + + + Stage Information + + + + + + + + + + + + Title + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_StageTasks.xml b/workflow/engine/xmlform/tracker/tracker_StageTasks.xml new file mode 100644 index 000000000..2348d5725 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_StageTasks.xml @@ -0,0 +1,12 @@ + + + + + + + Title + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_TasksOptions.xml b/workflow/engine/xmlform/tracker/tracker_TasksOptions.xml new file mode 100644 index 000000000..3f9ac90ea --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_TasksOptions.xml @@ -0,0 +1,75 @@ + + + + + + + + + Assign + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_TransferHistory.xml b/workflow/engine/xmlform/tracker/tracker_TransferHistory.xml new file mode 100644 index 000000000..136258d2c --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_TransferHistory.xml @@ -0,0 +1,35 @@ + + + + Task + + + + Delegated User + + + + Delegated User + + + + Delegated User + + + + Task Transfer Date + + + + Start Date + + + + End Date + + + + Action + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument.xml b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument.xml new file mode 100644 index 000000000..9b8e7fe66 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument.xml @@ -0,0 +1,24 @@ + + + + + + + + + Filename + + + + Created Date + + + + + + + + File + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument1.xml b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument1.xml new file mode 100644 index 000000000..b0a004406 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument1.xml @@ -0,0 +1,47 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + + + + + + File + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument2.xml b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument2.xml new file mode 100644 index 000000000..107a24eae --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument2.xml @@ -0,0 +1,44 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + + + Comments + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument3.xml b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument3.xml new file mode 100644 index 000000000..c937fc35e --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ViewAnyInputDocument3.xml @@ -0,0 +1,52 @@ + + + + + + + + + Title + + + + Description + + + + Document Type + + + + Format + + + + Created Date + + + + + + Comments + + + + + + + + File + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_ViewAnyOutputDocument.xml b/workflow/engine/xmlform/tracker/tracker_ViewAnyOutputDocument.xml new file mode 100644 index 000000000..58084712f --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_ViewAnyOutputDocument.xml @@ -0,0 +1,28 @@ + + + + + Output document + + + + + + Create Date + + + + + + + + + + File (.doc) + + + + File (.pdf) + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_back.xml b/workflow/engine/xmlform/tracker/tracker_back.xml new file mode 100644 index 000000000..267cae6d5 --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_back.xml @@ -0,0 +1,9 @@ + + + + + + Back + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_objectsList.xml b/workflow/engine/xmlform/tracker/tracker_objectsList.xml new file mode 100644 index 000000000..4ae810e7c --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_objectsList.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + Title + + + + Type + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/tracker/tracker_objectsOptions.xml b/workflow/engine/xmlform/tracker/tracker_objectsOptions.xml new file mode 100644 index 000000000..af85b2e9f --- /dev/null +++ b/workflow/engine/xmlform/tracker/tracker_objectsOptions.xml @@ -0,0 +1,104 @@ + + + + + + + Assign + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/dynavars.xml b/workflow/engine/xmlform/triggers/dynavars.xml new file mode 100755 index 000000000..f749f157f --- /dev/null +++ b/workflow/engine/xmlform/triggers/dynavars.xml @@ -0,0 +1,22 @@ + + + + + + + Variable + + + + Variable + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggersCustom.html b/workflow/engine/xmlform/triggers/triggersCustom.html new file mode 100644 index 000000000..2fa8c4dc9 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersCustom.html @@ -0,0 +1,60 @@ +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.PRO_UID}
    {$form.TITLE}
    {$form.TRI_UID}
    {$TRI_TITLE}{$form.TRI_TITLE}
    {$form.TRI_PARAM}
    {$form.TRI_TYPE}
    {$TRI_DESCRIPTION}{$form.TRI_DESCRIPTION}
    {$TRI_WEBBOT}{$form.TRI_WEBBOT}
    {$form.SAVE}{$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    + + + + diff --git a/workflow/engine/xmlform/triggers/triggersCustom.xml b/workflow/engine/xmlform/triggers/triggersCustom.xml new file mode 100644 index 000000000..749ee1bdb --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersCustom.xml @@ -0,0 +1,90 @@ + + + + + + + <en>Trigger Information</en> + + + + + Title + + + + + + Description + + + + + + Save + + + Cancel + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggersNarrowEdit.html b/workflow/engine/xmlform/triggers/triggersNarrowEdit.html new file mode 100644 index 000000000..f215e86f5 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersNarrowEdit.html @@ -0,0 +1,45 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.TRI_UID}
    {$form.TRI_TITLE}
    {$form.TRI_TYPE}
    {$form.TRI_DESCRIPTION}
    {$TRI_WEBBOT}{$form.TRI_WEBBOT}
    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    diff --git a/workflow/engine/xmlform/triggers/triggersNarrowEdit.xml b/workflow/engine/xmlform/triggers/triggersNarrowEdit.xml new file mode 100644 index 000000000..b71f83e23 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersNarrowEdit.xml @@ -0,0 +1,87 @@ + + + + + + + <en>Trigger Script</en> + + + + + + + + + + + + + + + Cancel + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggersProperties.html b/workflow/engine/xmlform/triggers/triggersProperties.html new file mode 100644 index 000000000..7ba8ac54b --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersProperties.html @@ -0,0 +1,47 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TRI_UID}{$form.PRO_UID}
    {$form.TITLE}
    {$form.TRI_UID}
    {$TRI_TITLE}{$form.TRI_TITLE}
    {$form.TRI_TYPE}
    {$TRI_DESCRIPTION}{$form.TRI_DESCRIPTION}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggersProperties.xml b/workflow/engine/xmlform/triggers/triggersProperties.xml new file mode 100644 index 000000000..44dc51492 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggersProperties.xml @@ -0,0 +1,87 @@ + + + + + + + <en>Trigger Information</en> + + + + + Title + + + + + + Description + + + + Cancel + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggers_Edit.html b/workflow/engine/xmlform/triggers/triggers_Edit.html new file mode 100644 index 000000000..d892c1436 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggers_Edit.html @@ -0,0 +1,42 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.__DYNAFORM_OPTIONS}
    {$form.PRO_UID}
    {$form.TRI_UID}
    {$form.TRI_TYPE}
    {$TRI_WEBBOT}{$form.TRI_WEBBOT}

    {$form.SAVE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggers_Edit.xml b/workflow/engine/xmlform/triggers/triggers_Edit.xml new file mode 100644 index 000000000..b7bb2eb30 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggers_Edit.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + Cancel + + + + Save + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggers_Options.xml b/workflow/engine/xmlform/triggers/triggers_Options.xml new file mode 100644 index 000000000..b8cd977f1 --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggers_Options.xml @@ -0,0 +1,148 @@ + + + + + New + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "+ response.xmlhttp.responseText); + } + }.extend(this); + oRPC.make(); + } + function triggerNewWizard(nameFunction, library) {//alert('@G::encryptlink(@#triggerNewWizard)?PRO_UID=@%PRO_UID&NAME_FUN='+nameFunction+'&PARAMETERS_FUN='+parametersFunct+'&PAGED_TABLE_ID='+@#PAGED_TABLE_ID);return; + popupWindow('@G::LoadTranslation(ID_NEW_TRIGGERS)', '@G::encryptlink(@#triggerNewWizard)?PRO_UID=@%PRO_UID&NAME_FUN='+nameFunction+'&LIBRARY='+library+'&PAGED_TABLE_ID='+@#PAGED_TABLE_ID , 600, 600); + } + +]]> + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/triggers_ShortList.xml b/workflow/engine/xmlform/triggers/triggers_ShortList.xml new file mode 100644 index 000000000..c7d406fbf --- /dev/null +++ b/workflow/engine/xmlform/triggers/triggers_ShortList.xml @@ -0,0 +1,31 @@ + + + + + + + Title + + + + + + + + + + + + + Apply Filter + + + + + +function pagedTableFilter(form) { + @#PAGED_TABLE_ID.doFilter(form); +} + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/triggers/wizardOptions.xml b/workflow/engine/xmlform/triggers/wizardOptions.xml new file mode 100755 index 000000000..359ea0e75 --- /dev/null +++ b/workflow/engine/xmlform/triggers/wizardOptions.xml @@ -0,0 +1,10 @@ + + + + + Param Name + + + Param Value + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfo.html b/workflow/engine/xmlform/users/myInfo.html new file mode 100644 index 000000000..4257035e2 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfo.html @@ -0,0 +1,119 @@ +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE9689}
    {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    {$USR_LASTNAME}{$form.USR_LASTNAME}
    {$USR_USERNAME}{$form.USR_USERNAME}
    {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$USR_GRACE_DAYS_1}{$form.USR_GRACE_DAYS_1}
    {$USR_GRACE_DAYS_2}{$form.USR_GRACE_DAYS_2}
    {$form.TITLECHP}
    {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.TITLEADD}
    {$USR_RESUME}{$form.USR_RESUME}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$form.TITLEPREF}
    {$PREF_DEFAULT_MENUSELECTED}{$form.PREF_DEFAULT_MENUSELECTED}
    {$form.SUBMIT3}
    +
    +
    + {$form.VERIFY} + +
    diff --git a/workflow/engine/xmlform/users/myInfo.xml b/workflow/engine/xmlform/users/myInfo.xml new file mode 100644 index 000000000..4cc175c1a --- /dev/null +++ b/workflow/engine/xmlform/users/myInfo.xml @@ -0,0 +1,246 @@ + + + + + + Profile + + + + Photo + + + + Resume + + + + Personal Information + + + + First Name + + + + Last Name + + + User ID + + + + Email + + + + Address + + + + Zip Code + + + + SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + + + + State or Region + + + + Location + + + Phone + + + Position + + + + Expiration Date + + + Status + + + + Role + + + + Reports to + + + + Department + + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Preferences + + + + + + SELECT * FROM menutab + Default Main Menu Option + + + + SELECT * FROM CASES_MENU + Default Cases Menu Option + + + + Save + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } + }; + ]]> + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfo2.html b/workflow/engine/xmlform/users/myInfo2.html new file mode 100644 index 000000000..26e141139 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfo2.html @@ -0,0 +1,111 @@ +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE9689}
    {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    {$USR_LASTNAME}{$form.USR_LASTNAME}
    {$USR_USERNAME}{$form.USR_USERNAME}
    {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$USR_GRACE_DAYS_1}{$form.USR_GRACE_DAYS_1}
    {$USR_GRACE_DAYS_2}{$form.USR_GRACE_DAYS_2}
    {$form.TITLECHP}
    {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.TITLEADD}
    {$USR_RESUME}{$form.USR_RESUME}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$form.SUBMIT3}
    +
    +
    + {$form.VERIFY} + +
    diff --git a/workflow/engine/xmlform/users/myInfo2.xml b/workflow/engine/xmlform/users/myInfo2.xml new file mode 100644 index 000000000..f01bbffc9 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfo2.xml @@ -0,0 +1,220 @@ + + + + + + + + + + Profile + + + + + + Photo + + + + Resume + + + + Personal Information + + + + First Name +NombresNome + + Last Name +ApellidosSobrenome + + User ID +ID Usuario + + + Email +Email + + + Address + + + + Zip Code +CEP + + +SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + +State or Region + +Location +LocalidadCidade + + Phone +Telefone + + Position + + + + Expiration Date + + + Status +EstadoEstado +Role +RolePapel + + + Reports to + + + + Department + + + + Change Password +Alterar Senha + + + New Password +Nova Senha + + + Confirm Password +Confirmar Senha + + + Preferences + + +Default languaje + + + + SELECT * FROM menutab + Default menu option + + + + Save +GuardarSalvar + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } +}; +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfoOptions.xml b/workflow/engine/xmlform/users/myInfoOptions.xml new file mode 100644 index 000000000..eaf78f068 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoOptions.xml @@ -0,0 +1,14 @@ + + + + Edit + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfoOptionsView.xml b/workflow/engine/xmlform/users/myInfoOptionsView.xml new file mode 100644 index 000000000..f4579a3a1 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoOptionsView.xml @@ -0,0 +1,14 @@ + + + + Cancel + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfoView.html b/workflow/engine/xmlform/users/myInfoView.html new file mode 100644 index 000000000..16f6e0a5f --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoView.html @@ -0,0 +1,108 @@ +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE9689}
    {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    {$USR_LASTNAME}{$form.USR_LASTNAME}
    {$USR_USERNAME}{$form.USR_USERNAME}
    {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$USR_GRACE_DAYS_1}{$form.USR_GRACE_DAYS_1}
    {$USR_GRACE_DAYS_2}{$form.USR_GRACE_DAYS_2}
    {$form.TITLECHP}
    {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.TITLEADD}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$USR_RESUME}{$form.USR_RESUME}
    {$form.SUBMIT3}
    +
    +
    + {$form.VERIFY} +
    diff --git a/workflow/engine/xmlform/users/myInfoView.xml b/workflow/engine/xmlform/users/myInfoView.xml new file mode 100644 index 000000000..28445ee26 --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoView.xml @@ -0,0 +1,153 @@ + + + + + + + + + Profile + + + + + + Photo + + + + Resume + + + + Personal Information + + + + First Name + + + + Last Name + + + + User ID + + + + SELECT USR_UID, USR_USERNAME FROM USERS WHERE USR_USERNAME = @@USR_USERNAME + Exists + + + + Email + + + + Address + + + + Zip Code + + + + SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + + State or Region + + + Location + + + + Phone + + + + Position + + + + Expiration Date + + + + Status + + + Role + + + + Reports to + + + + Department + + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Preferences + + + + + + SELECT * FROM menutab + Default Main Menu Option + + + + SELECT * FROM CASES_MENU + Default Cases Menu Option + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/myInfoView2.html b/workflow/engine/xmlform/users/myInfoView2.html new file mode 100755 index 000000000..16f6e0a5f --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoView2.html @@ -0,0 +1,108 @@ +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE9689}
    {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    {$USR_LASTNAME}{$form.USR_LASTNAME}
    {$USR_USERNAME}{$form.USR_USERNAME}
    {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$USR_GRACE_DAYS_1}{$form.USR_GRACE_DAYS_1}
    {$USR_GRACE_DAYS_2}{$form.USR_GRACE_DAYS_2}
    {$form.TITLECHP}
    {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.TITLEADD}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$USR_RESUME}{$form.USR_RESUME}
    {$form.SUBMIT3}
    +
    +
    + {$form.VERIFY} +
    diff --git a/workflow/engine/xmlform/users/myInfoView2.xml b/workflow/engine/xmlform/users/myInfoView2.xml new file mode 100755 index 000000000..c85c02dcd --- /dev/null +++ b/workflow/engine/xmlform/users/myInfoView2.xml @@ -0,0 +1,148 @@ + + + + + Profile + + + + + + Photo + + + + Resume + + + + Personal Information + + + + First Name + + + + Last Name + + + + User ID + + + + SELECT USR_UID, USR_USERNAME FROM USERS WHERE USR_USERNAME = @@USR_USERNAME + Exists + + + + Email + + + + Address + + + + Zip Code + + + + SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + + State or Region + + + Location + + + + Phone + + + + Position + + + + Expiration Date + + + + Status + + + Role + + + + Reports to + + + + Department + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Preferences + + + Default languaje + + + + SELECT * FROM menutab + Default menu option + + + + SELECT * FROM CASES_MENU + Default Cases menu option + + + + Save + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_AuthSource.html b/workflow/engine/xmlform/users/users_AuthSource.html new file mode 100644 index 000000000..cc2a92dbe --- /dev/null +++ b/workflow/engine/xmlform/users/users_AuthSource.html @@ -0,0 +1,42 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE}
    {$form.USR_UID}
    {$UID_AUTH_SOURCE}{$form.UID_AUTH_SOURCE}
    {$USR_AUTH_USER_DN}{$form.USR_AUTH_USER_DN}
    {$form.btnSave}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_AuthSource.xml b/workflow/engine/xmlform/users/users_AuthSource.xml new file mode 100644 index 000000000..7cf9a73ba --- /dev/null +++ b/workflow/engine/xmlform/users/users_AuthSource.xml @@ -0,0 +1,49 @@ + + + + + <en>Authentication Source Assignment</en> + + + + + +SELECT AUTH_SOURCE_UID, AUTH_SOURCE_NAME FROM AUTHENTICATION_SOURCE + Authentication Source + + + + DN + + + + Cancel + + + + Save + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_AvailableUsers.xml b/workflow/engine/xmlform/users/users_AvailableUsers.xml new file mode 100644 index 000000000..8eb04fc3a --- /dev/null +++ b/workflow/engine/xmlform/users/users_AvailableUsers.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_DeleteAssign.xml b/workflow/engine/xmlform/users/users_DeleteAssign.xml new file mode 100644 index 000000000..c18a9d72f --- /dev/null +++ b/workflow/engine/xmlform/users/users_DeleteAssign.xml @@ -0,0 +1,25 @@ + + + + + User cases summary]]> + + + + + + + + To Do + + + Draft + + + Completed + + + Cancelled + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_Edit.xml b/workflow/engine/xmlform/users/users_Edit.xml new file mode 100644 index 000000000..4b73e7df0 --- /dev/null +++ b/workflow/engine/xmlform/users/users_Edit.xml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + Profile + + + + Photo + + + Resume + + + + + Personal Information + + + + + + First Name + + + + Last Name + + + + User ID (*) + + + + Email + + + + Address + + + + Zip Code + + + +SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + +State or Region + + +Location + + + + Phone + + + + Position + + +Reports to + + +Replaced by + + + + Expiration Date + + + +SELECT CALENDAR_UID, CALENDAR_NAME FROM availableCalendars +Calendar + + + + Status + + +Role + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Save + + + + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } +}; +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_EditAdmin.xml b/workflow/engine/xmlform/users/users_EditAdmin.xml new file mode 100644 index 000000000..ba78cb835 --- /dev/null +++ b/workflow/engine/xmlform/users/users_EditAdmin.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + Personal Information + + + + + + First Name +NombreNome + + + Last Name +ApellidoSobrenome + + + User ID (*) +ID de usuario (*) + + + Email + + + + Address + + + + Zip Code +CEP + + +SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + +State or Region + + +Location +Cidade + + + Phone +Telefone + + + + Position + + +Reports to + + +Replaced by + + + + Expiration Date +Fecha de vencimiento + + + Status +EstadoEstado + +Role +RolPapel + + + Change Password +Alterar Senha + + + New Password +Nova Senha + + + Confirm Password +Confirmar Senha + + + Additional Information + + + + Photo +Fotografia + + Resume +Hoja de vidaRetomar + + + Save +GuardarSalvar + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } +}; +]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_EditOptions.xml b/workflow/engine/xmlform/users/users_EditOptions.xml new file mode 100644 index 000000000..3661c4f8d --- /dev/null +++ b/workflow/engine/xmlform/users/users_EditOptions.xml @@ -0,0 +1,16 @@ + + + + Back to list + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_EditRT.html b/workflow/engine/xmlform/users/users_EditRT.html new file mode 100644 index 000000000..91bf51fdd --- /dev/null +++ b/workflow/engine/xmlform/users/users_EditRT.html @@ -0,0 +1,153 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE3}
    {$USR_PHOTO_SHOW}{$form.USR_PHOTO_SHOW}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$USR_RESUME}{$form.USR_RESUME}
    {$form.TITLE1}
    * {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    * {$USR_LASTNAME}{$form.USR_LASTNAME}
    * {$USR_USERNAME}{$form.USR_USERNAME}
    * {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_REPORTS_TO}{$form.USR_REPORTS_TO}
    {$USR_DEPARTMENT}{$form.USR_DEPARTMENT}
    {$USR_REPLACED_BY}{$form.USR_REPLACED_BY}
    * {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    * {$USR_CALENDAR}{$form.USR_CALENDAR}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$form.TITLE2}
    * {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    * {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.SUBMIT}   {$form.BTN_CANCEL}
    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    + diff --git a/workflow/engine/xmlform/users/users_EditRT.xml b/workflow/engine/xmlform/users/users_EditRT.xml new file mode 100755 index 000000000..b8adc1ebb --- /dev/null +++ b/workflow/engine/xmlform/users/users_EditRT.xml @@ -0,0 +1,282 @@ + + + + + + + + + + + Profile + + + + + + + + + + Photo + + + + Resume + + + + + Personal Information + + + + + + First Name + + + + Last Name + + + + User ID (*) + + + + Email + + + + Address + + + + Zip Code + + + + SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + + State or Region + + + Location + + + + Phone + + + + Position + + + + Reports to + + + + Department + + + + SELECT * FROM aUserInfo + Replaced by + + + + Expiration Date + + + + SELECT CALENDAR_UID, CALENDAR_NAME FROM availableCalendars + Calendar + + + + + + Status + + + + + + + Role + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Save + + + + Cancel + + + + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } + }; + + function cancel(){ + window.location = 'users_List'; + } + + ]]> + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_List.xml b/workflow/engine/xmlform/users/users_List.xml new file mode 100644 index 000000000..a2f845d29 --- /dev/null +++ b/workflow/engine/xmlform/users/users_List.xml @@ -0,0 +1,39 @@ + + + + + Full Name + + + Username + + + E-Mail + + + Role + + + Due Date + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_New.html b/workflow/engine/xmlform/users/users_New.html new file mode 100644 index 000000000..7f9a012fd --- /dev/null +++ b/workflow/engine/xmlform/users/users_New.html @@ -0,0 +1,146 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$form.menuUser}
    {$form.TITLE3}
    {$USR_PHOTO}{$form.USR_PHOTO}
    {$USR_RESUME}{$form.USR_RESUME}
    {$form.TITLE1}
    * {$USR_FIRSTNAME}{$form.USR_FIRSTNAME}
    * {$USR_LASTNAME}{$form.USR_LASTNAME}
    * {$USR_USERNAME}{$form.USR_USERNAME}
    * {$USR_EMAIL}{$form.USR_EMAIL}
    {$USR_ADDRESS}{$form.USR_ADDRESS}
    {$USR_ZIP_CODE}{$form.USR_ZIP_CODE}
    {$USR_COUNTRY}{$form.USR_COUNTRY}
    {$USR_CITY}{$form.USR_CITY}
    {$USR_LOCATION}{$form.USR_LOCATION}
    {$USR_PHONE}{$form.USR_PHONE}
    {$USR_POSITION}{$form.USR_POSITION}
    {$USR_REPORTS_TO}{$form.USR_REPORTS_TO}
    {$USR_REPLACED_BY}{$form.USR_REPLACED_BY}
    * {$USR_DUE_DATE}{$form.USR_DUE_DATE}
    {$USR_CALENDAR}{$form.USR_CALENDAR}
    {$USR_STATUS}{$form.USR_STATUS}
    {$USR_ROLE}{$form.USR_ROLE}
    {$form.TITLE2}
    * {$USR_NEW_PASS}{$form.USR_NEW_PASS}
    * {$USR_CNF_PASS}{$form.USR_CNF_PASS}
    {$form.SUBMIT}   {$form.BTN_CANCEL}

    +
    +
    * {php}echo (G::LoadTranslation('ID_REQUIRED_FIELD'));{/php}
    +
    +
    + + +
    + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_New.xml b/workflow/engine/xmlform/users/users_New.xml new file mode 100644 index 000000000..cb32867d5 --- /dev/null +++ b/workflow/engine/xmlform/users/users_New.xml @@ -0,0 +1,337 @@ + + + + + + + + + + + + + Profile + + + + Photo + + + Resume + + + + + Personal Information + + + + + + First Name + + + + Last Name + + + + User ID (*) + + + + Email + + + + Address + + + + Zip Code + + + +SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + + +SELECT IS_UID, IS_NAME FROM ISO_SUBDIVISION WHERE IC_UID = "@#USR_COUNTRY" ORDER BY IS_NAME + State or Region + + + +SELECT IL_UID, IL_NAME FROM ISO_LOCATION WHERE IC_UID = "@#USR_COUNTRY" AND IS_UID = "@#USR_CITY" AND IS_UID NOT IN ("") ORDER BY IL_NAME + Location + + + + Phone + + + + Position + + + + SELECT * FROM aUserInfo + Reports to + + + + SELECT * FROM aUserInfo + Replaced by + + + + + Expiration Date + + + +SELECT CALENDAR_UID, CALENDAR_NAME FROM availableCalendars +Calendar + + + + + + Status + + + + + + + +SELECT ROL_CODE AS USR_ROLE, ROL_CODE AS CODE FROM ROLES WHERE ROL_SYSTEM = '00000000000000000000000000000002' ORDER BY FIELD(ROL_CODE,'@#DEFAULT_ROLE') DESC + Role + + + + Change Password + + + + New Password + + + + Confirm Password + + + + Save + + + + Cancel + + + + + + + + + + + + + + 0) { + showRow(this); + } + else { + hideRow(this); + } +}; + + +/* + * function validateLocalEmail + * @author gustavo cruz gustavo-at-colosa-dot-com + * @param sEmail email form field. + * @return true / false + * @desc function using regular expressions ir order to validate + * an email adress. + */ + +var validateLocalEmail = function(sEmail){ + var sFilter = /^[a-zA-Z]+([_\.-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([\.-]?[a-zA-Z0-9]+)*(\.[a-zA-Z]{2,4})+$/; + if (!sFilter.test(sEmail.value)) { + return false; + } else { + return true; + } +} + +/* + * function validatePasswordFields + * @author gustavo cruz gustavo-at-colosa-dot-com + * @param sPassword email form field. + * @param sPasswordCnf email form field. + * @return true/false + * @desc function that compares the values of two password fields + */ + +var validatePasswordsFields = function(sPassword,sPasswordCnf){ + if (sPassword.value==sPasswordCnf.value){ + return true; + } else { + return false; + } +} + +/* + * function validateLocalData + * @author gustavo cruz gustavo-at-colosa-dot-com + * @param oForm form that is validated. + * @return void. + * @desc function that validates local data for email and passwords. + */ + +var validateLocalFields = function(oForm) +{ + var sEmail = document.getElementById('form[USR_EMAIL]'); + var sPassword = document.getElementById('form[USR_NEW_PASS]'); + var sPasswordRep = document.getElementById('form[USR_CNF_PASS]'); + var sAlert = ""; + var bContinue = true; + bContinue = validateForm("[{\"name\":\"USR_FIRSTNAME\",\"type\":\"text\",\"label\":\"First Name\"},{\"name\":\"USR_LASTNAME\",\"type\":\"text\",\"label\":\"Last Name\"},{\"name\":\"USR_USERNAME\",\"type\":\"text\",\"label\":\"User ID (*)\"},{\"name\":\"USR_DUE_DATE\",\"type\":\"date\",\"label\":\"Expiration Date\"},{\"name\":\"USR_NEW_PASS\",\"type\":\"password\",\"label\":\"New Password\"},{\"name\":\"USR_CNF_PASS\",\"type\":\"password\",\"label\":\"Confirm Password\"}]".parseJSON()); + if (bContinue){ + if (!validateLocalEmail(sEmail)){ + sAlert = sAlert+"Please provide a valid email address.
    "; + bContinue = false; + } + if (!validatePasswordsFields(sPassword,sPasswordRep)){ + sAlert = sAlert+"The password fields don't match.
    "; + bContinue = false; + } + if (!bContinue){ + msgBox(sAlert, "alert"); + } else { + oForm.submit(); + } + } +}; + +function cancel() { + window.location = 'users_List'; +} + +]]> +
    + +
    diff --git a/workflow/engine/xmlform/users/users_NewOptions.xml b/workflow/engine/xmlform/users/users_NewOptions.xml new file mode 100644 index 000000000..5e86f0437 --- /dev/null +++ b/workflow/engine/xmlform/users/users_NewOptions.xml @@ -0,0 +1,6 @@ + + + + Back to list + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_Options.xml b/workflow/engine/xmlform/users/users_Options.xml new file mode 100644 index 000000000..637e39121 --- /dev/null +++ b/workflow/engine/xmlform/users/users_Options.xml @@ -0,0 +1,208 @@ + + + + + New + + + + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignCases.xml b/workflow/engine/xmlform/users/users_ReassignCases.xml new file mode 100644 index 000000000..433a86a2e --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignCases.xml @@ -0,0 +1,18 @@ + + + + + + + Process + + + + No. of cases + + + + Reassign to + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignSelectSubType.html b/workflow/engine/xmlform/users/users_ReassignSelectSubType.html new file mode 100644 index 000000000..683ebc64f --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignSelectSubType.html @@ -0,0 +1,41 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.USR_UID}
    {$TYPE}{$form.TYPE}
    {$SUB_TYPE}{$form.SUB_TYPE}

    {$form.CONTINUE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignSelectSubType.xml b/workflow/engine/xmlform/users/users_ReassignSelectSubType.xml new file mode 100644 index 000000000..c50783075 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignSelectSubType.xml @@ -0,0 +1,51 @@ + + + + + Select the type grouping of the cases + + + + + + Reassign Type + + + + Group Cases By + + + + Cancel + + + + Continue + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignSelectType.html b/workflow/engine/xmlform/users/users_ReassignSelectType.html new file mode 100644 index 000000000..4ed3c55f0 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignSelectType.html @@ -0,0 +1,35 @@ +
    +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + +
    {$form.TITLE1}
    {$form.USR_UID}
    {$TYPE}{$form.TYPE}

    {$form.CONTINUE}   {$form.BTN_CANCEL}
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignSelectType.xml b/workflow/engine/xmlform/users/users_ReassignSelectType.xml new file mode 100644 index 000000000..29b682960 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignSelectType.xml @@ -0,0 +1,46 @@ + + + + + Select the reassign type + + + + + + Type + + + + Cancel + + + + Continue + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ReassignShowInfo.xml b/workflow/engine/xmlform/users/users_ReassignShowInfo.xml new file mode 100644 index 000000000..03d6a6c1a --- /dev/null +++ b/workflow/engine/xmlform/users/users_ReassignShowInfo.xml @@ -0,0 +1,50 @@ + + + + <en>Information</en> + + + + + + + + + + + + + + + + Delete + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_Search.xml b/workflow/engine/xmlform/users/users_Search.xml new file mode 100644 index 000000000..f9461ca6a --- /dev/null +++ b/workflow/engine/xmlform/users/users_Search.xml @@ -0,0 +1,12 @@ + + + + + Full name + + + + Apply Filter + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_Searchx.xml b/workflow/engine/xmlform/users/users_Searchx.xml new file mode 100644 index 000000000..5c43145c9 --- /dev/null +++ b/workflow/engine/xmlform/users/users_Searchx.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortList.xml b/workflow/engine/xmlform/users/users_ShortList.xml new file mode 100644 index 000000000..04dedc3f5 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortList.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortList2.xml b/workflow/engine/xmlform/users/users_ShortList2.xml new file mode 100644 index 000000000..56fffd948 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortList2.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortListAdhoc.xml b/workflow/engine/xmlform/users/users_ShortListAdhoc.xml new file mode 100644 index 000000000..6002fc727 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortListAdhoc.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortOptions.xml b/workflow/engine/xmlform/users/users_ShortOptions.xml new file mode 100644 index 000000000..f44768436 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortOptions.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + Assign + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortOptions2.xml b/workflow/engine/xmlform/users/users_ShortOptions2.xml new file mode 100644 index 000000000..44cac0953 --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortOptions2.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + Assign + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ShortOptionsAdhoc.xml b/workflow/engine/xmlform/users/users_ShortOptionsAdhoc.xml new file mode 100644 index 000000000..648b0cb8c --- /dev/null +++ b/workflow/engine/xmlform/users/users_ShortOptionsAdhoc.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Assign + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_View.xml b/workflow/engine/xmlform/users/users_View.xml new file mode 100644 index 000000000..386880caf --- /dev/null +++ b/workflow/engine/xmlform/users/users_View.xml @@ -0,0 +1,130 @@ + + + + + + + + + Profile + + + + + + Photo + + + + Resume + + + + Personal Information + + + + First Name + + + + Last Name + + + + User ID + + + + SELECT USR_UID, USR_USERNAME FROM USERS WHERE USR_USERNAME = @@USR_USERNAME + Exists + + + + Email + + + + Address + + + + Zip Code + + + +SELECT IC_UID, IC_NAME FROM ISO_COUNTRY ORDER BY IC_NAME + Country + + +State or Region + + +Location + + + + Phone + + + + Position + + +Reports to + + +Replaced by + + + + Expiration Date + + + + Status + + +Role + + + + Change Password + + + + New Password + + + + Confirm Password + + + + + + + + \ No newline at end of file diff --git a/workflow/engine/xmlform/users/users_ViewOptions.xml b/workflow/engine/xmlform/users/users_ViewOptions.xml new file mode 100644 index 000000000..1db10099b --- /dev/null +++ b/workflow/engine/xmlform/users/users_ViewOptions.xml @@ -0,0 +1,17 @@ + + + + Back to list + + + Edit + + + \ No newline at end of file diff --git a/workflow/public_html/images/1.png b/workflow/public_html/images/1.png new file mode 100755 index 0000000000000000000000000000000000000000..e1d531cdec7796de52573213c24475bc194f4b0c GIT binary patch literal 1266 zcmcIkKX21O6h9h-(ug8;K?n(PayLYLw&TXl$w}2FEe&eY(pa=0A@yosQY-Nv>}%sz zh=C0z76v9JkXTsw2z&q*HWv5*e1`Izq)FQWrk?Ek^Zfh0_wIMk_j`@DkrOXO=3){uyUPXM;~m#8OBiDbyG~i!o^L3Pu*&z{wd07lj+>T!+_g)N zv{=cR2?esp1;dHg^JAKnrGZZh^VCcvJb;L9SsLcE)7Zq-AmUh;)x50~bgUO;&Cp6l z@jh-bfgds-YX;U71v-ru40s@!L6a&u7|qCO)2-U-C?>4R(!LNOC8Xc)%l(2JL>;1* zN+qIbMAPzs$j3*%U`gJO=Y~#B{nU7DM{X$Gz{jaywig_TvLvN}#%;7Y7LEh?@kl(7 zkt8f6s;rQ)XCRtjq}7Ns5kyuH^ePvQ16NxGGi9CwO`=Ztyv78tq(M^&HaYmSd>gk>?*#9S(V~_O;52D`S zSR9-19{0E}V$e)IubE@hb`W_?R9ugBI0^lZNhZdB<~Ph5$^y!gjO+3=_3=?&%4DMZ zrMMqDz04qzmw5{p$j$U}7!+;#J6NvAk+MKkl_*B>P4pZPH|n(|EBoHwMN^Nj6%o3F UuB-39ZNnE-Uuo99EbqSh3$DjG^#A|> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/2.png b/workflow/public_html/images/2.png new file mode 100755 index 0000000000000000000000000000000000000000..644bc7bf66aac6dab69437baaff173b2e24b4a6a GIT binary patch literal 1256 zcmcIkzi-n(6gDkGh^Pb%6+%LsT#1SJY{#t|%TClLEe&eYsIf#~;%Z+~E3wacck-hKCcFB|pyGuc~NNs?x& zYn4qtUKa1vH1EHE*!|6i>14U;W-^%{zczmI<<-WzyK-=FaD04xbaZrhc<8+Q`kdRZ z#A}ZdNmAy-dnx@`+U3TZY^BATq|N$>Vrj`ITNtbc6!!`3CL5pc)OoDy0@JFkTOJ7& zBp^x}#*$r1W8`%)16#NgM2-vqkU`)(^27O>T8qngJ6PMNxVc|YbF=B+eg!GE%jsujNd0Q~gfF@BVd|W{c7lj@V!I$yCfuS2bg-Y@5l4^z4z|B=XJrnXky z6600*UYQpCw~u?j#4w#M*SuUV_xeawim6wnp{t05zO%DU;sm-`J7>$b#f*VmCxBMnQ4 zmPLu;EM^JzyM%)l>4dSX0svGH2Cn*euCCXU3fT$Q4j5@3G(7*H>z4v`v7C1@B*+or z7-Uf|PEqEn1D{CDr5UPV0O4I%9plZc3I?yPUN>DeUX%+;c zknYDEXN5SO9Xk2zr%FkF#3L}_P=26-!UpNj>X%-#HJO`RYo$yH&b5fRi6!e9HVR(jxEDO!qPtWj&pbPXm z4Z`;RdAjWxbEsHCmNBBA0gdPmltP>lW}v#<(*^tg1PlDJUdb-&4UQ%7A?cBb#5@(6 z8Rs<%eAK2a!n_?Y-ao{L?bof`HRbx=)T`eMuqM7K NwUtKo^YXJ7e*oSTLF@nk literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/4.png b/workflow/public_html/images/4.png new file mode 100755 index 0000000000000000000000000000000000000000..3db4bc02d36c09c470016169df1a53ec1ae898a8 GIT binary patch literal 1256 zcmcIkzi-n(6gHG0L{tI^A%uiD+?Duj$E}-_ovKY*8q}m!V~N7V)xM-wVxKu*8@D3^ z5=;y%h=GX}RpNg@>dpiU3>{I&j^!>%lePm)J=yo;`TO2`_uccoS!+C=%-_o^iZWSS zuC9ymntZQLi2nPhoj+ojNEd2eE|>fHd-a!C-dJ1l77q^(PfkvbkB^Uzj@*ymUJLv6 zWcgXDDB6^KuVkO+c7*XRU)eK1EUQa4yD_q`Vq`BAd{JoA}3e>rB-pP<4 zM}%XLMcp_>nXC4FA~Ba{sDeI(cU*Ol&qjR>R460B(u{(y7cF4TXr^tJ?3qWPi8*+J zV_@3A)OFFBsA!8vB-3wdIWI{zj%{wb5~Vmpivuc4kx2PaXJ)F$Oto>Ktt2v z$g?0i!iXx2U{0AwX}5ggI6$RYbR_c}XdHFSCsoWzS?W>HXA6em85XiEG;KdW!ykYy z(Cah^Tf67!wr5PEVhLHskbVXT*vP?Ee!i@JD(j+pOC^mcWOkOCl2U zRA^?L*DUZ+i?Rswav0$@fl1tU;Mn-j{03QzvJhnnM|F9c`sgSxWir|sLG literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/50px-Edit.png b/workflow/public_html/images/50px-Edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c6cf695756d9c687fc4d8b473cdd9749cf3c656c GIT binary patch literal 6443 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�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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/activity.gif b/workflow/public_html/images/activity.gif new file mode 100644 index 0000000000000000000000000000000000000000..94d46c129f6bba02f2f0b230d9f4d2c7a48e1412 GIT binary patch literal 6610 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 AkpKVy literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/activityanimation.gif b/workflow/public_html/images/activityanimation.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9d538409eb551a0febd86391480af8899198ed8 GIT binary patch literal 1952 zcmZ?wbhEHb^kZOWc*ekB7dzE9W?D?ea{t`NDFaKYD{Qu|g|I3g5fB5?U*Ps6%zy1IH_y682|My(_|K`*G zzyJQ%gCdbQ)mQpevPj{LYY`PZABx7LMx ze>nT~*{<(5+P|Dk`*wff$31@EZ})zGyz1%--|u%O{Qh+6aG$}qQz<{5EI!@bea)@yo!!0t(lo9zK5h{N?u7pWc0V^Et=eIKe)ssN`nhVlDymoC42|z$BJ-PVFFt zkP{aaT{=1Qb#s0gJaXw3wN6@c;^U&(rs1;`B9qk4ip#p?EU>J6eVCg|A;Lo7paSz* zGqb{1PhJ-Lo}F!3{_T&XiDuw3k9IxQ4=P+D@{vbANIY7?BWTWWD@P$w(W!%-*C*iv zLzqtF<_x8)n|Q6ay}7w1`}Vcg?(%ify9+<>lJwcJ;o;#9VePmxI|>yL!N$nI$RNSM z3JkX5hTNtmNC@O1hfH%W)VnBw&@5!Asw^X{t(gb$vSqBbd8k8^yuOHn4xbW_WL|c- zuZMS9X1tY~Sw^n3ikP4xKd+jETpojeV1Qj@l8v)ps!Jon9ejht9nyou9U6ng9j1fO z9jMv1zaNrlk#cBW)&y9h1?NXd;>^pL086w;X)`aoAD(EDl4c$QQldplr^xX#knTWE PrvvE@`N-L{< literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/add-user-32x32.png b/workflow/public_html/images/add-user-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..7fecf5d95f82d2a17629cdac1ef8158350a43019 GIT binary patch literal 2356 zcmV-43Cs40P)1hd8OQ%~u6Mn**Xtv`z-t-ekl&7}o)t4!%>X8XR zmQ~nCMcq&Py2szRcK-hYAlJ{WVmWrNs%k#PG-0}(U_=2*G>)O}0Yrx-ByAXV`BQ)N z*Z)rehPTb~I7FeH06a!fK7^_nV4M|nM+5XY5V(ZE$p*AtY)3pU+YnE`-Sdqh?g9vH zomnUFe63Jc46$Z4z?K6_D-feyi2|kyq=|@rx*K19aTUp=5+;bUh3^HvkuUB5=y_v? zPY}3v!R>-)@k+os3y>Os$TUIJ_5o`+Rxf%#@aBjC{J)>J zis#r(o~p4(|Mtsdh87Ckmw{d7eCwW-EZME;Jl$L|<83ztDA}PuHmhXu!7%{-H)nl?)mI(`K0;bHF2)NT}cc%h794Qz} z5vw9PJJERf9GaWEtzJ;O;&1VHM+{(XfB$J&9jQ<|x;!6c6UP9#xj1WM!n!us4{FUG&ugf&e(X7CN z6UiqcOJEA3p(J9#Bvq~fRnt2ZO?!TzC~<_s7`Gtq0;u_`uW?+DUN!f!MnlgbKQ9Ai zWw{WXA`Ghko~|I8F7;AHDmYf{LZC7e`MD2Z-nd1m%Bn#QUyLhKBREFHrAQ+_@$W`U z%XP%MB`8VV0$C9%P1X^Beiy)#JIm@w8M)=%N2^aMj*^T~jFX%fQN2Me*LVl()*ew?dYi)2R|Ria59*nq^FI5pLU-jWPV9X}Oo z#{Uk7%q{5G{1lV|OG!I;Op-B7=aEDL*<2xsF5t`7Gmu*qXo?Y0OubzBgZ{7X^;rF= zc7|bmr4MFdCL#vH>Pm>OBQ% zSX#9LPvtGfrt53aL2{}z@hB8nCi%%kNDh-XhFC10vl8wMCz{m5;Hg283GMqs$8xZJ z;SM{gpIve^nz z#qeq9^ihpu*9gMOUZJDhr@>(g*tl>rb_X{>6nI1i6X@DHJl_H=ee{Pm(1wP! zq~K|Eh}WUge?w;pCJwnd2`NfSC`PpnP`M@Fba;5op7=dX@J_|nD;w<^F-+5z)*5>Y z#DdT}Ot`b1cyaD}>a-1M1pK5#TVp3MLU?EI90hWF|!(;p9ZTO)5J&2qWgRvmO%@KqH5txQq z!<7HlO8`uRV>FLvs-MN#!Q&WKLX@pW((5*arG))Ks?k`JgpAQ{ES$CkUko0iYbMfp zH)iK9#6W)pOTV?;2I!0SVo(YosVA|keJ29R0a8OiPoxh+Ukzd?6t+aFVSKN8o*?%( z2zfllkAE1vNaJk8?W`>TO93l5Jp+*@q-!U7A-H%{Pnm>)WDhJfD{Dnp;PMw^^Y{Nm z;Wb!<1~uETxb8c?Sz&j045_UgTtC zAWaa#u{4Sd2}wtex}xRwvqxJI>QBHo-Dd;wbY0O^NScJqP(C)y`;F~`Q#~iJ>)MCN zcI3e0@RE|$MI*iFX!heqXMj4Xd>-47GGXB>?!5#tpLcR#O9bTPXCOZ-6Io6dTr>;X zfhagFR?yxOK+`Ed^2+j1;44C=m`RYFt$?h{D0Ypqy%J7FAh06Rg$!HG{%Ak^U4C?3 z=t3kOp^7kS3E*8DAn#>YDT#cZzVD%#5L_l@o6jTNn}!UU|8GH94_iHu$QAr&6SKBPnwu7J$FokIsvo7>W$hT1K(6zhf@Q{)Ll<0{iH+ z%D%zCo{UUd4sbL)5E%QKRULZRfI|`C&B{SRc_E5QM!}org-b}cU2mDzQY4Zb#*Iin zdi}lVZtFp4I7Dj)IZQpGh5#IZ0egegtPkR-; zL@;JmYH4U%6O*4F@rxqg=McrGoepQFE6wtYi+sY{)g#Fg1&vV)maMEvIlY12vBtgQ zYga`7?Z&QTvP52dfxNRy;Ds#C9s-&_RIB&j4qR^;?q2VY7~qcW$CzN%_P<@R%oh2& aSN;hyj-*#Lqi?JL0000~HzhjfHD;-hTM{?S$iv*FU>ApE-EvS72iGnKNfv z_S*dYFy;H7|1RFqrK_($ee>!6_iMIpq3?hE56kU6_29?Eqi##Lo~hhuxT;iSGrqTA=`^RIFxq^ukiFf?}?qf zqVr}*&Qh2wDlIx)SYAqCp%=fvl%>msr8rjec{44ZE4*B4E1SX&uU#9bbDT(HQ`{*$ vWySteEN8q#L|GJAZr#4c#jsQ4At$G#Bp;umB16CL+js9jeEjsmk--`Oa44K( literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/addc.png b/workflow/public_html/images/addc.png new file mode 100644 index 0000000000000000000000000000000000000000..1241b8655fc57bebe90d7fc3527e2cf8d36b8c69 GIT binary patch literal 716 zcmV;-0yF)IP)Px$fKW_SMVQQo)%L2d-=?40lzq8tMU6Rhw_JC;V35CejKOfl>77WAJkj%}r`3gX zx?F{~ZJ5l8s??pA)r+;?tk>?+hRJ+^wQNt7L0z6rmdJUt-KkNQLbTbXW1vyB-jSBn zi>A+(rqGr~k2;skg=MQ%aKU5L>(7h3bH3uXx7w=U^4yBgeTK<;SDrIANerZ?##p+NP`2oV4Al#puAx z=EKhE$#K44-0|2#jW&3+WRbvlWujDi#%pSmx8SdNy>2^(GJm;k$?czVxm$zH zcZt4uXsc6Xqf>szZ;8l%lEr|R$AzWan^2iSio$u1!hLnFVSKt|wcL@l-IB@fppCwJ zezIt6s#?3;uZ+uqwcDtb)QYRtihjXqTAWL>*`<@sh=jOohPiINL;#2d9Y_EG010qN zS#tmY3ljhU3ljkVnw%H_000McNliru+5;C53p2GHo3a1^0L4i}K~xCWW2mpMXH4?o z*DK8C0Wult>$x~goz$F-0^*B7TrTx=t)ggVCdXJ$xq1dh4oz3)d}H~na$lCPGKRz` z5oXJXy1HQfaADml296S@3{k(jI&XG9vq%XBF%2P|Ixwis5#(k_mC_D|ax3jC7zzYR zy;N0zoZ2Ae6ln&NPzM7Sb|ANg&CZ&WfyalXnw_uK)|M?VO(~h7-a^(rlff#1LB`OZ y7vxAeo0vF7g%CGZUa*_%%_VcWS;aX6flL5Cp*SA-|6f}G0000#jX`8sEOQW!driMMny!Y+HBus$alT^7IhXQPaTAYBS$i(Ef5*#r?-+0Z#h)yU>{aizWogD*Qjr0td8G$+#|4BI)r6!i7rYMwW zmSiX-W+hhSNI#p{aB=u^kJ9BqzM)+D@@g7D>_ZH z6>Nk>K2^#dec$hd&5{fSg)a9?JsDb3M<1+M;h^GLd*HyqYe$(ldZsj_W{3#!96X@l zAjsu&py5MupnEfu)0U^(0!(Kp*sL-QO$pql{X%Kq;`Av7E5z0lI$B?E`RzKdsAZ)9=nHHN!5+~JF4SY+VADb}iE(C2i8t1nx?>)BhL zPS>_TA<--6ZN7=uLx=rfr*28JR#UU9l!(BR!@3s} qR&*pBVEQRw*vTQWVY)*bLIMx~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/alert.gif b/workflow/public_html/images/alert.gif new file mode 100644 index 0000000000000000000000000000000000000000..6ea558abe3538e366ce1cf3a8e589fd230e15420 GIT binary patch literal 1277 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/app-edit-32x32.png b/workflow/public_html/images/app-edit-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..cfccd4033c8cc1cf81e68a017be1fa1895d23a29 GIT binary patch literal 1430 zcmV;H1!?+;P)%NO zWcV7>5Cu*J6K^vx zXP^(m0$NqshQLV_S2Unwj|Z@l;j1a&=}ZFdCLT`Ibx?1l7Q?&fR$>8$=If~H??H9B z2ZQ{2yeKi#-lcA?XhHa|dAQIj+>5n`SVRH)QUwg8fSHMgs>oCe;Z!)z(`8I3H86Xi z7n8~i_~_nDWI`;tvk7|B5)&P}l`Fbrde_|WH!i2v(}YtLpMRn3bWNrJS0=Y1(~2i) zfL}u;-OlLm#qa_i#1urB2{WaF+7C;i{IU+X)RA=mCCPHR#IIlzn2g*s$exV7mv^T_Ir&qF@>In&me9MU?H&rj}Ok%67B zGKb3?fkH}@5sF$c91_MAyD*!iQ*U=8=vHAf6X95Tx2a2M{|efn8sJQ0+`X;kAvR)B zb!^n)E$IaGr{%*@m)9sQ%)_+424*qMcLtqM6$w#hB4%ZALz-de4RqhKkx9SMJq;sY zM0D)(kGVVV8UaPix0A$LH)llfvDc;zMzKeYcU(x+Hiw&8ZCMY;(N(}72bl`GH~Ju4 z)d1UB6yo-1;^(UbJh)~b%Dmd77b=1~`v&u&vKg%$KT1;MeB8a%x`~+x#ob58y@A;9 z1<8>2h-a@7(9(7~-n3!U+Us)a6~zHRa{WxJ$5+E~Yiqd`iXOP-91HW!3dlZq0Yhji@ks7*!Se#Bk9#h}! z_qh8MHMdl->duFMpju^yY@qTy>%OE zUz&^ZQB&w#?KPIX^@dBIl1_lw+^B1g*?kK0v&z8s`tR`fr7l!gSM?fWSr+dU>kCCz zmU#^Qa9ROeQ~CPal0rWWJ@=7JE>TEvZO39}J%4IcMcyW^b7la&2~bJe=y5s66bJHh zzY~OGL2OzL^J?E{iTnC?#`NnSycC-XELpN*#fp_HSMJ!cW9QDDr%#{0ef##^yLbPi z0>yuV&PAz-C8;S2<(VZJ3hti10St;iSr{1@V3)|EVve|k`G7} SPi0ujc3EY@!xZl}25SJhtW-Gw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/arrow-up.gif b/workflow/public_html/images/arrow-up.gif new file mode 100644 index 0000000000000000000000000000000000000000..2572db3b50c58d7f897c31071c064efbde6c4652 GIT binary patch literal 155 zcmZ?wbhEHbC-XELpN*#fp_HSMJ!cW9QDDr%#{0ef##^yLbPi x0>z&!j0_C&3_1)z0J4*TRpNnq-GL0I$jZ1G%Oe)kVP%V(G$-yZV|%r<<6N;dzs@IGl6tx&L#{|DM|w z@b5ox$&Q^O*etgE$9$z+$uE44UW?`z^4x^q;9Ui`Y1+(Yh7>% zGQJQmp&suk8GnyrubxX8T?yYSW)M~TS*L2OHjA45|FfRk!>(?sI9J243L*=x`LP$q zs#~nHvXhD89z$;zGwqyIhR64Ac-b1#iWYuKrS9Wsq^#&V zjYm5w4*RIj;x&Dgz0kF;tZyVGn!g@Dm>(7M&ETTOGO)3oD|7mN{}H2_58qOMr5zh62jxD5 zkFq?zENZBOOQ}tUqbSNcdUE+pZl)M*N^a7+Ieg~T~ B{~Z7T literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/arrow_order_desc.gif b/workflow/public_html/images/arrow_order_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..30d8ef7fa97d482d47781640b8fed8ffbffad98b GIT binary patch literal 835 zcmW-gUuaWT9LGO53FgigEs~~+pm!iF52dE7tySyH)|f7JiR(7o>MmFr*HTFnX^*-= z;a($?EDq|MjP;?&V6cI&S`^zU{@Pd1&*JHe_7S?eF36`~A-Oet&;Y zPdwIn;))+X74Ug{g?|dQYOS#PE_E$cSS?sLxpW#{*9bb3KIdl~n1Lk|uL2$6J%eo) zEf7XKZY{L%`KMeAOY;z|d9;5ydW6*s-#78f!sc<3i%1H8R-SKW8huNg^&(~P0eb@Q z8RR2L7U3hp-$?%oir>ALGQXkUtK<=`{xoV7%gtg(|Nm+KL^jZi%X3wSGKdEdSiV1B zEC*w@4~RbbR#u57!4SXTHsh>5r~_7aTL}pGKRs>v!XsKzjUFG5g%u zJ~d|7rHL3}OV+DF%wS}UR2suzT=;d3?iiU7(y2$n2pZ!z(z+tLX~_^zb5_tUV?s9^ zhfb52N>7zbHt``^AEGB^$*e5h^{)jGw?J9wZ>;={kR{l>%sHFS93eYoIn9yA?5z73 zi$Z6^=6@SP4#Ps7q5NWJEEXSAI;a%q5w`5({V$^niEVmqiv^YsP^|3ux6C^^bsyD) zH^m yCZb1Zc2VwMKn>xoSGDO^+)>m(gBFf_kyUngb%lmB<#t`2E<$}+lbYi5aq0u5@c<40 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/back-24x24.png b/workflow/public_html/images/back-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..94df756d9a2abc31ef4f2f753c8b719feae7359b GIT binary patch literal 1609 zcmV-P2DbT$P)R$Fo`h|gD$)hj2a_MBb!7B##bbOA}ZhuR7?zD z!ZVQ#MU4^o!>FJb5{V#h9Ejt!cHLOpyT0GOkK?%|8ykqkFS%_`dhYl8e!ufO-#G~X z5pJ)?u1NA+mSvmtdVMVd76Bok5LL|Oau;MpKE&wQ@2gzn!gtDn|DM=wR~2=YO(tj#AyCOb@ajE8%RYfwsNqrqrs2eQn%>ai2TcLliOzB;|YEVRo8 z;@oh2H?&{)5mIsv%z7U5tS&!CQe;RJ;Yu#Pbiwlc>+S$3ETX|$Floyns*}xNE=p-#O0FKKyXn^Q6T!C)XohpFOGi29rEMPhYRyWZ=&o5>Gl89DEll3r7Rb>A^sg8|g#q zhXT$7tM6M5y@@caJF%Iv0?4We8I>}jPezj9TBrwh&s+`nns1O<>Xi(&Qwq0K^qU zF`Fi0JPaMpdobn?eNr>NW(D^7eReZ%>RR*XcH!GA2e97eAQoDkktJwgsVp21FWvJR zx`c6r>XZj?$9?eD@2f%3r%|G6Whp?K0>ot?9Z^3tkDY~Yj9(Cqrs6K_>$|?dY`3;Q zxbG1tH9DY>a_92^TICj4RKE;d1ywgK9P`2Ysf1p53fD2n2)zq40bww!qd%B+=`kadJ-8L%1b_-ySf#A&UBfyzB`KfZTtEg5A} zfJHrBK?Y@2A~{u}>mg%WRw;WKyzwr4Y4S$ml#AOj5{aDn&bz0uu@q@ zz{0wvSZa3WEja+t8SX+=jcUfpv!NjLA0|ImiHh6L?;#Vcop3cGVs+7CGG|27DU5`} z?)I)-<+0RWC@~jOLl%-bW7k5Nr97W>D8Rt?pvQ-dwcjg`yhFyBPgAEw&}M#|%qyAK ztub(a?fJYS7~c!prqVM!%&2@5N-cHpe}e)*mE}y{%0<@4;j!ZR9*jn#Cw}(rYwYmv zfYFu_7)o^$7IpCSq+M8Io;Zxb<%kCjOlpvUqGnK169Z#x`|C?mY4K4bgs`FXIWo;U z^Av_c!Cl?bmDb(oUxf+_2hmJ#em1YS!~EK9Fj|;ASfPhHXv^6Tz{z_dE%~W)Liz1H zGzyHP;A%Vv3+q1xd$yzv1A)K-i_O&b_HXmRuGbbZH(0fSwUXw#9pEfz99#o;tdD&B z$08`@F6CRut?LBHK~Qqx`wx6YL|=a^_V^>Ej@pk5qpg87 z*XsRkF*mv})REKka=UUo+ zuK{xleN8Tn$)#wP?A4MRV#92zYONeA$rIIUpp+TklgXtToTDnjgYDWM@J%leY(I5` z4s(ayn;@0DOeI!tl?!8%LO4tg+Xo6^z{pkM!((11wZgQV7!qf@Dk^Wb>wyRaeDejt z*5*xi7!G^3fj@DYS}~@vxh=H1NghN1hh+*pG-e5u8EUe@kl0#L?z;WJ83Hn$=gsZN zDbDlaFXV!F03w+#%*qiWQ{QWOb&L@VtPO0u3+swzk=l_>Af-r8A{lEbcaFL9kvS0B zn$YrAQFkq7ITV6vH-hf00000NkvXX Hu0mjfsp|IX literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/bg_ctaTooltip.png b/workflow/public_html/images/bg_ctaTooltip.png new file mode 100755 index 0000000000000000000000000000000000000000..81faf5c71264074e18f805391cf71b5f88d93939 GIT binary patch literal 3617 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 Q6^{>Gi%r%jl>dJd06I8FmjD0& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/borderTask.gif b/workflow/public_html/images/borderTask.gif new file mode 100644 index 0000000000000000000000000000000000000000..9f251c9d4259663192628975909d5a7e496c14a6 GIT binary patch literal 156 zcmZ?wbhEHbT*9EnFp+`bKMXK1Fev_HVPt1uV$cDy89?$3Ot~$(D^I`WUp!~at?r{Y z6@K%#J<=$A(z#5la?LyL%l-ZRelzjm;W|CA zAO5rcX=SDU>iIn;5+WrsfHN_ZFe#HUdAwsG5mF%&^7xdML`juQ$zvrOiIEzakz?(o zPUZm-kV2@y6ZS~J%)+e9#_W*~dl6P)6ZS}tYf)BZQ}(C^ufInRs*yHR@sxL%|t52T{Q&Y{LO+ zpa@<=BA|i^-~j{D;t~aFsvg6F84zP{rXI6{H*n+HTs=mK?2$C0MV5#SAt4pS0N?Nm zb8rLED1%I>i~JEZpaLfJ0MBuc0}PKXL1b_UR_q<|#b%;=XbYNv)DbgsMV4qD(n3Or z1T}DvUcw?gh58^fv=(x}4?-XU5~X;KOYBe#fd3O_te#T7QmKrMja94F>FMc(g@szJ z)@U@AmX?~$W~ZrkJWiOg!pQ$l;h1Q9_zM3CN?#=3kUREz z=J0r@yL9@-?)=9)J)7U|8F;gCfM+j_zFeLk|FD1d-RRWXt}{EP)-PV@`?}bCf2(_O z^6p@*Z(^b}_<7&=y~`&aULD?Y<#GG`$=luc|6acKEB|G3-J_k?dpDJiyg0S>+_v5x GI`j`JO|k|6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/btnGreen.gif b/workflow/public_html/images/btnGreen.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c62c8085ae58b563758fd45c1a92440dfa6bb80 GIT binary patch literal 875 zcmW+#F>6&}3_TXXsz^cTRwU|D&_z*HTu!mrItWE@k5YGMrvnZmxai;%?)2^3sC7$KxkjTNu}10GNy0vV_P5|&`X6G}uP z6O};03M_a*g(zg93IJ`^p$`aST3KLkX+|2|C}SAYSjMjHbcd57gG{n|fYW@k?vyi} z=`3fHG)<|C5<^U}#Aa?W{T@^>f*Gt}%V9Y~J*i|QGg-;j$cl~RMHQo%#VTUd?Q!yv zM=_*TP^)G(*lv<3Olc|;hRrPGvrZ#7NY7L2Yd%}LORjLGtGq{ccNcbUBBYc`Y9}nz ze7sYk2xX{3ZI7jzq<38^Qkkk$duF9(?%iC9QkJTOxfe~Z-R`3Hu)yQ)*EJk0C*)k$CvZBEo zr$=^o7j`Zee-9(xOIq}0Szxg|`s{xl=l>k<`RcLF?ajTP zA77k4v+{lC^@Z)1>z9sJ_MSfe@@nJ6vwyo+_V2t|zkhV``q}-hx0?@7?ccikZtKCd OC+9wYJ^0mf-2M+Jr)1jz literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/btnRed.gif b/workflow/public_html/images/btnRed.gif new file mode 100644 index 0000000000000000000000000000000000000000..edbe05a9fa21433c74a521d03a39286488a0efe2 GIT binary patch literal 875 zcmW+#J!_R=3_X5;Rgr?wtw_|Rpo^lYxSV3Kbr6c+o=V-FoensN;G%iCIY-S;!bsD)rdY)Qe^V!l}a)m2h9xBmkR<78X_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/btnYellow.gif b/workflow/public_html/images/btnYellow.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8c146116849e84932fd358fd7104827f2090f4f GIT binary patch literal 879 zcmW+#J&%oH5ItnEBAZRriXjqfLyc%oal>wis6{bU;uk0n5?_giN;d^s8-Kv4gi@`T zE%e)o*yNhoN$&gHcQP|)&NpUBaLp9F^p*}W7l@N!%2}rCRsheX+BwZ${Egd zma|Ekrqo4=A*NVjGq;$24=NbJ3|6q^u$-ZuR5Fs8tYm9s#YXa?ic!pB6*21eIQht< z7}6@JRWloGH^~&HG?fX%W)|{Ur;!_^=c)BIpDo=bSGdwu-Xpua3p+OvQc5MY6BcSd z-lB9ZcTs!TcC|C(qS|d5h7!n_{z>g+iHXWIk~_3^ZvKTXK%bZwYB--`;&|3@7&$q`Mr2?ZtczI PcW-xZJ>#*XE4ca}5_e~G literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/bulletButton.gif b/workflow/public_html/images/bulletButton.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a0fde40cb3ef4653fc40c4a75bd7a0de5eb846e GIT binary patch literal 112 zcmZ?wbhEHbWMklD*v!Ci#+c#F{$;m|eSZJ{^kin`jWpX&H;;aOcJ*FE^s}WM=N+Z!o#8)&4g(N?%wS-V-7vwCU7(ajSs>LhP=`Grr-NCD Qb5V{`r75p!svv_k0C^@X)Bpeg literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/bulletButtonDown.gif b/workflow/public_html/images/bulletButtonDown.gif new file mode 100644 index 0000000000000000000000000000000000000000..886a20a975c2bef856e58a871df3d81ee0178600 GIT binary patch literal 121 zcmZ?wbhEHbT164)7v-C+4Daw1{XW-MkhTc25SK3p)5xL literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/bulletButtonLeft.gif b/workflow/public_html/images/bulletButtonLeft.gif new file mode 100644 index 0000000000000000000000000000000000000000..3cf1154b46ae59f46363880ec040f7c15a9c2a4a GIT binary patch literal 129 zcmZ?wbhEHbWMklDc+Agm#+c#F{$;m|eSZJ{^kin`jWpX&H;;aOcJ*FE^s}WM=N^R0OJn;%rgM&zoy%BO#A=xOUA^sIZa%Ew3Wn>_CX>@2HRA^-&M@dak04x9i000R91^@sA mAaKaz)RA~0wD3TMkrWLk6ahgFgkS`yA*evW089WB5db@B8aJZ= literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/bulletSubMenu.jpg b/workflow/public_html/images/bulletSubMenu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d9f87e76444f0977d38eaa192bf450638701adc GIT binary patch literal 286 zcma)%O$viB5Jtag;>5Sq+@Ar zWNd8Qn7&>L=ndzRAirP+K_z1spwB1(Z}vPX1RBR#;1OBOz@VoL!i*J5?aP3I5+$w? zCBgY=CFO}lsSJ)O`AMk?Zka`?<@rU~#r~V+{eWu3Kx&+eQWHxu^Yau!GILWI3@r2w z4fPGo&AN(!MzaWlR7CjtSS9D@>Lr2<(W}TUV6d^TC`e4sPAySLN=?tqvsF@1P*76H zOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbW>1sjvcS&P^>zRH(?!$t$+1uvG$^ zX$541g!Ppaz)DK8ZIvJ{j_?goaLzAERWQ*r)J--pHc>D!(=#$RvNSi-Q3y^fQSeI4 zQ!p}DFfuRz5=K_W=0F5=3>YZcaRF(YqLehNAQv~Noj{(gQbtKhft9{~d3m{Bxv^e; zQM$gNrKP35fswwEkuFe$ZgFK^Nn(X=Ua>O75STeGsl~}fnFZkR0-2kblwVq6tE2?7 z2o9j0ODup}lvfN5JYX>DS0onb8|oS8!%YTiv;hiQfny@SC?r2W#||yR6r6*NZ9qCv z6d`Oy=udS?EJ?Kkg@>+zg|4Ath@pvPxA{0Fl;*#eOr>m6V)YRGgOaJiYVZHSqkt=4s!V_SIMC9+P;i z(X-TaVM5226IVUz1X7m#tBN_YKKeo0GxqHoVsi>z=iPPEvwmGM-RsupY*v={UbgEw z9>%PAK27nB@Ygw3Ewu~otzu1lzta42HOIBSs$&HpY*?hB9#;vxh+zF;% zXDN8U3UyGsqTTpqCHu~M^Yy-dQjmRR%8)%ZVu|g?nlr08E`JYJVP4xNq#W{7{-5Bt b_&Ubhml{7Y$9}yG^bdoltDnm{r-UW|dl^}_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/cal.gif b/workflow/public_html/images/calendar/cal.gif new file mode 100644 index 0000000000000000000000000000000000000000..8526cf5d19a915aa8073cf344873c4505491970d GIT binary patch literal 127 zcmZ?wbhEHb6krfwSj51v)Yr?)cd3`J*V1K6uU)?O9}E~67!-f9FfuT(G3WrDe9t*l6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui00#gE000OY0P}?TM=*>)f&UB+REV%(!-NMHB4jww HVL$*o2z-wX literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar-dropdown-down.gif b/workflow/public_html/images/calendar/calendar-dropdown-down.gif new file mode 100644 index 0000000000000000000000000000000000000000..416debd30d731be6cc9466a207c43530fa3661ad GIT binary patch literal 820 zcmV-41IzqJNk%w1VFv&N0Ox1`000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= y{r&#_{{R2~A^8LW00930EC2ui00#gB000OP0Q2PeM^NBDg9ZyGBzTZvKma=)r;A7c literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar-dropdown-up.gif b/workflow/public_html/images/calendar/calendar-dropdown-up.gif new file mode 100644 index 0000000000000000000000000000000000000000..481455ae9d605c5411c825ccea5f1a6b9ca75ed1 GIT binary patch literal 820 zcmV-41IzqJNk%w1VFv&N0O!{L000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= y{r&#_{{R2~A^8LW00930EC2ui00#gB000OP0RIWhBd}neg9ZsAL^v={Kma>y7>Ygs literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar-next-month.gif b/workflow/public_html/images/calendar/calendar-next-month.gif new file mode 100755 index 0000000000000000000000000000000000000000..07e16a7cbe326babe47e6ad3046f22f4d1a2646a GIT binary patch literal 823 zcmV-71IYYGNk%w1VFUmN0Owo)000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui00aOB000OS0Q3ACm`5N%gZ~O96sR!az<&V&06UmY Bj647U literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar-next-year.gif b/workflow/public_html/images/calendar/calendar-next-year.gif new file mode 100755 index 0000000000000000000000000000000000000000..a733f5fe743518717e1030b7b381d6e512d3e0f0 GIT binary patch literal 829 zcmV-D1H$}ANk%w1VF&;R0O#WX000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui00;mF000OY0Q3ACD3D;mJO%$DG&oS6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui00aOB000OQ0RIWhGmu~&g9Hl-{C99+o`3*5<~fVF literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar-previous-year.gif b/workflow/public_html/images/calendar/calendar-previous-year.gif new file mode 100755 index 0000000000000000000000000000000000000000..48729c6203c88f89f75e48238e4d9b40664120ba GIT binary patch literal 830 zcmV-E1Ht@9Nk%w1VF&;R0OyAQ000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui00;mF000OZ0RIWhBk&(Vg9q~vR5);9!h;AK7GxN4 I;KYCcI|`1EEC2ui literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/calendar_heading.png b/workflow/public_html/images/calendar/calendar_heading.png new file mode 100755 index 0000000000000000000000000000000000000000..4f40b8224ae0f7f2dd32e69106456ea70f831b02 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ek!3HFAQtjD+6k~CayA#8@b22Z19JVBHcNd2L zAh=-f^2tCE&H|6fVg?3oVGw3ym^DWND9B#o>FdgVlZ#PMLsYF-x)ms7?djqe!g0N} z*O7}sf#u)|6|Jyt9FKXxA(`vRQw{IVV3Ma$P-;BoIA69jon7U5KzesjX{QM`5 amUmfm{DhQZU-&t;ucLK6Tzsx{F7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/next.gif b/workflow/public_html/images/calendar/next.gif new file mode 100644 index 0000000000000000000000000000000000000000..bf0215277434ed78f8099712c46eb55cc5f606fa GIT binary patch literal 214 zcmZ?wbhEHb6krfw*v!DN>dvp0Q(yhMc2(_uJnPDj&YkyiR$Y#mcBFXYt;9Jec0T-7 zci?5y(f4VK&vl>w>DIJG@h1xd2L8IRSE53)* zgd}9n8tC{Ouwt94tLDg5c$!s${mKCoNioUZu!NfvWdyoe51FQh$zNwYcyK|TeDBc) zN3&{yg$zuNZ1Y4Ujw=;f7&Wn0NHRvLu~~{XB?oiJ@H4gR>S<>6#xa>jW-)WHvBwFs ObFwYroi8iMU=09xqE7k% literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/next_year.gif b/workflow/public_html/images/calendar/next_year.gif new file mode 100644 index 0000000000000000000000000000000000000000..ac12ea1307e4d35ee401f358372b5c69c06fae88 GIT binary patch literal 256 zcmV+b0ssC-Nk%w1VGsZi0J8u9s@(d7%Joi)x_Z0gn$-A-x!!E5(^!_obFtcCoXEN1 z`hLLag2nG}Y@>00$NYAYi~z;6?@{0Wh#Q zaHc>43>Y-XxU*ryjvzl4H7fAH#{mRT@?=^dKewZczmuz#XON+u0n@#=42nNl7#SFt7<7PY Nfa*bPrVvI3YXHjL5YGSr literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/prev.gif b/workflow/public_html/images/calendar/prev.gif new file mode 100644 index 0000000000000000000000000000000000000000..211e1faba1e22b37a9b329a020be9ce08999dfc9 GIT binary patch literal 212 zcmZ?wbhEHb6krfw*v!B%{nC#O_kOpW{NmreyJXX?s$GvFrXEROe6I2Eo7`2G+jrib zdHi|LgGb?3`e=hQK1V3g*muHe+`u+^?Ek78$?Im^N=k&Ty~ Mlhb+{zaWD(0895#mjD0& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/calendar/prev_year.gif b/workflow/public_html/images/calendar/prev_year.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8145d598f2651f4066f94885eec0c5525f7250a GIT binary patch literal 259 zcmV+e0sQ_)Nk%w1VGsZi0J8u9s@(d7%Joi)x_Z0gn$-A-x!!E5(^!_obFtcCoXEN1 z`hLLag2nG`N79SYcD3HMd2MhufIH2&sfs_FRa%6zOq5uZ~5;S1I zfIvwE4Fxa&Pyiyyh7Nl=7?AM*(xe%gIwQm$17-yrFkpA^f&~K_n00udfq}~j JoDK{K06QEwT@wHR literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-admin.png b/workflow/public_html/images/cases-admin.png new file mode 100755 index 0000000000000000000000000000000000000000..8dc4d0cca4ac0424d39309abc1451b84457b49a8 GIT binary patch literal 675 zcmV;U0$lxxP)p00001b5ch_0Itp) z=>Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RV2LTfxAjM}l-v9stHAzH4R4C6? zl09e>VHn4s_q}Vp*yNJ*BR1)mEr=E?x(Z@NbaQiaaS+7Cf~&ZQpo^=UhzjB$tqy_~ z6fI(WB9a6Q0Dy>yNT6?b+D~qtuN7Bo-*Z}VwY;(N=-NzaZP^zcLJ?pr za09^n-HW4>BZ`s)U?>UEc1yWW#f|OR`|stR2xlAsDYo+K&%(fxy&*wNYX*pK1S ziF7(HTtM(-DXH(+0~8?^>Uls5;hnp3eQfkl`oMAAo5f^?rw(F#XuTd|io_{g64DGf z^eCU*WBGEY?Iv8_ziIi8=SpWU-;z-x5CIkzBtp|NUcISky0=+39zOWkFr2StdN#L= z=m-i6hHe1%a-q5}o37NE;i%;X*0v|s^VaBPortkuABn^W6W_ngMBQ~ z%hb5|U8~q_$Lm<}I7_Kw`tZchQWbXF2}CSxROaX3X*-tQ>X;TTF0LDr`~eH_P1`#d$Uy)A002ov JPDHLkV1fnpG5!Dm literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-cancelled.png b/workflow/public_html/images/cases-cancelled.png new file mode 100755 index 0000000000000000000000000000000000000000..8b7a29ad8c280cf38df9873abff945b2bc5a08e4 GIT binary patch literal 785 zcmV+s1Md8ZP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igY# z5FIVkc)f)H00NOoL_t(2&qa>AZd_FqK-b=9pT|tb_6R!!?6^P_B#{s}g-MzSIwU0i zAq@qQpdx>fK5Z0HM2N3ILPD++MI~|Jv1C zB2q*IRYgQl5fN2X1oi9&4-8MmvZ~gmsMRigWx?eMN*2y5C|dQ&12p$XE>*{ zUCU^HpR==5d`QJ|&N5tE#e0W$hBL$LQg%*I3SHN5F`aWfKBaD2R@dGur6Bh0H(&GM z`|o%&?eNY}ce$>jKw&zaG8&Dj&d(85M1`xv71`U{!$OKOemCdWy$Q(#r-CX_GNtP% zrNdhvrvt1A(E^`rt}__C#FmRCF4x@o$S_qzpyW)~WmFvI0?sJ_!Hk#^gV5154Ypj? zoKF}0HExN);Z$$}DH#3aG4F7iNx>naOcxDTlB4Td44@Z`>+6o-6{n8q9lhl7X5_9R z24S@yL6mA%Q@R=u%&8K5pv_A(E9w;Uo)`m38=@`Yjlc20i&g8I)_NY40;4OVt{DJ5e91XDg3dZHQL8~vU~OUK!p3G+c8 zttuu@p1^X+=A%dWx+b^nWx2_)f6~wo1+$J`%nXvFnz#5De_)RvQ=Fq6jrjNBL$;ni zEwkBN?C9vopC0|grY|^A91hnxV&j?2CM?%CSiOIrbmK)MC+?tbyr*7o*l41t5c55_+~`{lQjv-3Uq_~van zK0NS?S=BE&_Y0*@;R=*qfk-Jb91gd3c6L6ks;YYR`t|RN`TY6XaQ*FnMFPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igY# z5FQA#Q91zt00MnUL_t(2&rOg&h@4dv#eetB`(|f$cHNMLfJnqcc8Xm< zMZ{pCm0gHo8np?j6>PLhBM25^vtVIsp@J?Fgup7hnPjuG-}mnObFamYAqOs}Ilp`0 z2rKRXFb9wj0>ERy%fPO?|7qrXCnqOIB_|(-!AD~L(z{7ZftJOE^KdIG_%)2 z2(P;Pi$DaS)JjTEC4 zAas$_#R1FvhiFz*Gny3DEHR~wq64rvdE1HVn zvKl9$Ny%9qkT_na*7}QC`7YMhZh32WLzAm1AH5J;U}WMD(3C|}@|+cS6Z6nlEps=& z_48l9-WGt*-hMjF&Y!hUVRN7rHk#XS1udmM0eXkN;N9AJ;11&%gPt|3CZr;fHYjI^4Yc=EDaYEC2NU v-N)zeJa_5Zf*Bm1-ADs* zlDyqr7&=&GJ%Aj}0*}aI1_o|n5N2eUHAey{$X?><>&kwMol!tWu5|O;OF$vX64!_l z=ltB<)VvY~=c3falGGH1^30M91$R&1fbd2>aiAi9PZ!4!j_Xs8TM9KO2(TP@7;uDH zkl*FW|NB?8n(i8H-psadT~OY?89`RbrF;0fIU6Q)c`z=OUL@*sTJlEU<^tj88-C6F j!CU#gTe~DWM4fvnh6g literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-draft.png b/workflow/public_html/images/cases-draft.png new file mode 100755 index 0000000000000000000000000000000000000000..a9e3a6e9378eca13ffd04593fdd95eaef9382d5c GIT binary patch literal 844 zcmV-S1GD^zP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igY# z5E39NQQh|d00PWOL_t(2&pnY(Yg|=Sp+dlAK7)(k%B6Z*Fe3#>U3%{{FsMTU&c!Vq)T2p66$sbGF@X|K4miKU-a0{cCu5 zxELQFFQ=!cNs6L)6Zn2m6a6~OPXd7V~oZSBPK>=u)oUt?_HtYe)efu zme*XX)jDpqTJMaEjNCpxImrR6iAdSQT5GH|w0lrQk4+7=T8(>m?_7NH^r^D|d7eKk zisGl+%_d)ebDbbiN~Bi`-6Am1=g1t?`Vy+uK7vRlBE|w_S(eo6bz7-a_;KqdyE_j! zJ6tEP4NxEI$63ojX6c1Unr5hKrmEHfbh}+ssZ@NU(ICw-*4Nj`Dph7K%uw`tM3eBO z>o{YTG)qxcud1hJRYgQxp66V?e1#AK8=r4*@b>}Ur&PRUxC(inCG{yH;$n=}0*Hta zkpy6N_IZ|}x=sEf-226sg zIv}wC)><{j7!l#9bHt;^k8$2}>D>=GDGa~f{h2@iDcLy)B&R+HoPLfm5@U2pl2EJV z3=9qt%0LkeFTZ{X;|Iy;a{gRD1N{{M|9^Ij(G*4D?%)4|ufF_(lapgY2$W?>r_(`1 z_~p)Tc<mduOeE%Q^RkbFLR-)EJ|Ph^lG~AxMl-jWMdKMpbu#jeh~3 WXkr+gqMacC0000p00001b5ch_0Itp) z=>Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RV2LTf;H}e|IRR912M@d9MR4C5{ z!8>adQ5Xi`_dA!F+0AW7H*q&=!eWAv6u}!35X4I%Scsy(KtZt-3qi54690f;VQZze zh}x(qh@B<~UJ!!8HJa>Yc6R2R^L;)Kys*eXLSV<<7o3Zi!S}x_8Fw5PA-Ld&BE2BY zEaZhX9D9P&B|6`RtB;=D8OnNdZ2scWtFzT*<0gz2s8V1k2rD=dOGKA$p8qlZraD=v z)lnbwQ&F-se(q%Jc7htT7l9%GAORTs`rYg9Po;cMsdf^@b~OH;y)C#60fHgYN&tW$ z1V9>Y;A;K6bMYY4FA4)`tknVscIHA@_wt? z9&de}%-eGK<;(4PZI9oP&en(5mKRR#+NCcXIrR9(<(X(ewQ`WkZYrloe$UL`ymD)W znsbBHB(V;a#{0fXb)h;aS8ef04|6iRD|KBNnb03v{b7my bB?9~h$YMJ7ycJjn00000NkvXXu0mjf3<@(f literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-inbox.png b/workflow/public_html/images/cases-inbox.png new file mode 100755 index 0000000000000000000000000000000000000000..fe5da96797d464dc220c1f646750dc0337274c55 GIT binary patch literal 580 zcmV-K0=xZ*P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01sgR01sgSs6VG^00007bV*G`2igY# z5Dzm^gYY!~00G2FL_t(2&y|tCYg1tqhM)7@@8%};CI(EU2Gpr83Q`4aJNs8SIEnPX za8+<}69*?3M<+paEJdLbJ1AI-3Za(7l6Xz-ukX9ZAz-S4;JY0T&v|*@1OL#@F!^oX z+8gs&5YPsJ&n(cOP7~B zZw!DlLA%om)t5qO;dpG((sL{fIMuFk=0t;)g`CHq9X2qkfo%gAfXXXcIce3EEX~RD zk}v{QN97&QKMr_15Nayic=ApTlPLgZy!(tqn$yffRt2=;kSKsS5^AB6mX6hK6I&M? z%Er}2;^xWxp!aZ=dHDY6SZ&<$s*D@wQK^B*JhUp)tl<9EC+=KHsq*~~-3!;xS%As@ zt5y(qsMYJ39~oI^4N-rjRw17BxOedjmeac(k)^W+=GhL|8gMQJQ{Y19Nz zQ~|Z*{UIWXuLSSXIZP03n&#PcSClwkk$&w{sm`1Y1Q<-Xgf#)y;&i;X3Gfri9Mo~< SX81(_0000AxPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01sgR01sgSs6VG^00007bV*G`2igY# z5EMFrX@d&@00F>BL_t(2&%KeoYm-qNg`a!huY9}-ZE0!h2X;vZbtw|if@8r^7ykmm z!O6wlO~FMSUHcz&QFIZZ;Ght7kw`%?#c0ze^=;m-d+*O7U<2-+@xa63oCE(u4_@vr zJbCk}G3zOS+fTRG*V|{`Yi)5({R8@1^YBAKdv%E$jS;WAz0IwAH(&Vxt1I(!*Dqg` zZwINWMT%<0XLOho*FxrFkNYor{LF-OsM$QdOlK{zTYv@-YjLhr%}7YooIEcHA`meY zrQy!T876toLM&WeiJ2G!fF6H&&i6znnN?)YqZtQ89>kF%420YmLSJ*YGlz2?^}sSn z!hFzuHtjt8ygjyFz3D_4S1%wc1U1uLgfuI7^lp#1zRa!G$6n{swKX3g*?Zgc;zhzr z1)XGMi&s!$XJ%E@lP-_Xf2CrM7#$w80ek>04k?c*%!Gy-A^m-X+0})b8jw0m>MRb& zU${t*P$owyp%hIi1x3^XnZBtdBQn3x8mtwJIX;2&-$S$?pgj*!LUrjB)ldO~2p~Rr ze;=g;>lD_cCoo>LqZ{WoOi^O2BmL3GiA<9L&P O0000+&Q3 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-paused.png b/workflow/public_html/images/cases-paused.png new file mode 100755 index 0000000000000000000000000000000000000000..52db74f19cd5a5ca71d443f7f78d7ba2c79fe42c GIT binary patch literal 731 zcmV<10wn#3P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igY# z5En5$mI*)r00LV{L_t(2&&89?YgA_x#((GixHDHx?ns7M8ifX>qG?RK>Ov?|a9Q*Z za4T+I+MOHQr3e-`?i9Oiw=F1$xM@q;G-<188X+}KoXN+`oy^SrdXI}JxNz@*XZ3J6 zJRb+%*T_V(8DF{b^{Fa^V8jwM>=A$hr~(jFaTWwYG3MKEt}V#a)YQz0wRJjX77v!@=8#J{jq2Em1m_$gf`*EtAC6H}fqLWt!ELwO<)is|UUqj$l5r**3BNC|QVmjOr;jjm z{9}r;!25{9A2a~P`3Mm(C(fLmTUcEuml~s@;_zgXb~@sDn)B*x1~r!m`rZWcB}beB>zdoIK00#=J>DoU#7%Zhx1m zs))TKIS}*Fp(an()-~PkiE$AV6HW3w+cVButhI=UxK`^$Z~V}Uu>-X_Wj^G`2ah>- z`cr;eZpe3cz7MzW-n+5!@83W727?+1s*1JN3vLz$UT!uL-B+)RH3lna zduK=fT3Y;L@!|c8+iU;*0+_d&seqay8(n?2^yf1Xk^ON@T(2`MO4(?&if+4e`}HC~ zcnb<(veI|O_|I0KF5l{>{f<^4OLw{tdt2Re3qSpE6X2`!7vA|8uK+Ur7X5SL6c7La N002ovPDHLkV1kk-Ox^$h literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-reassing.png b/workflow/public_html/images/cases-reassing.png new file mode 100755 index 0000000000000000000000000000000000000000..211c68e277d499033d05a78b1ba8d1cefde62bdb GIT binary patch literal 809 zcmV+^1J?YBP)Px#32;bRa{vGXb^rhab^(3Wg3JH_00(qQO+^RV2LTf&8Py{x5C8xIyGcYrR4C6y zlDlr4RTM_o-sk+68PCOz0mqgT!2}VLh6pKu1tK6CBqW3cuK*3m9TjhoHm?9B4G~om zB#0GIQpCoI9V{^88xCeX&fNdooI_ztDOU3pt62Kv%cZXuUzmCRl8AT_K~)hER76A- z6+xaM&N&$j2JYbC-^cR$TkrL7uTO1v= z2*TJ~=bTK|YZz+?ti_(9s;GkC8IN=N{Sk+UEwZejT0i6Qi2eAZ4_W%^3k1O$iyB2# z5HF0Kqu1}z{JTk~+dUB)rBQ5;E9t1+rTDCN-|7v-Xj74ET0^QZEnzyjDHK)goS)pI=BS2q7T=1%Kp_9k|CbKwflHKxes6K?O`#tPt^aCa-GHhZ4; zUxtx0OwU&N_TB_*+rKbgT<4RQKI3A2fhdn@x@~@{{D|tw6KHh`ZtWRTr#x=K4}ZYs zk&-5!6}LiL+VowY8^<@e*}LhJ(hz&_j)_QaPxmJKM};>yM;( z@Y_zl+3tRDxHxxd_ML2;vA??iedGRXcWu8vy#DlQM~sQlxJ!|ypO1hbPmnzE?as09 n4f-%d2H8N=DZb~Orq=%thSou7=D=~u00000NkvXXu0mjfB4&J< literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases-search.png b/workflow/public_html/images/cases-search.png new file mode 100755 index 0000000000000000000000000000000000000000..cb0e2b418e37d30c08ef0c593cb76ce0b86c7270 GIT binary patch literal 754 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igY# z6Ad;Inb=_f00MGJL_t(2&$W?1XcJ)=#@{br?$Y!cioKX?lC~sV4cZu5DP1~gC|c;y z(nTmJW^)&^IJHwY7YA{uh(pCeCaqma#JVRv^I?d|Qw8DkTsX&&wD>>O@vY{WQ@o8@`FxU#bH zacymFu(-Ggx~>EIwRL%U`HtJ|&h-2J8A|E9P$=|V)3k>?&)?>G{wpEmexXo!e|C@0 zAdyHsn46p1;y5m$C<^8{Zd#V*ySlE+rfEVX5*Z7J!`E!v?$&Cx{qt}r6k1wXSlE^% zX)+iLGELKt-YU&9PwTwh*JZ#kKHWo$ksmn2?ThS3V8}Wk+`tU_-AYg+-O6jX= zwJNr3M@)zVwsb=VKW@XpaT)axci9cVM#tO~BykA%S^DGdGb{Mh^0zeHsMXV{eIGd8BEY(d~BgPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igY# z5EdSfTm@JF00R<9L_t(2&t;KYNK*kE#=mpUcDCil=G<&EH<>JFQ_C)t8LQ~#C8&Jr zrrn^2>cO%=BD%gu7YeD2GNm3u=phgz124rw)JmpW99kmfe0&AAk71 z?++hwt*si@w%-8&l-yp$UzxLdqf{oVafa+B+sriKoAI*|Z>%NC%->{2L!*{f2L}KJ zm0A$^$>r8lQmsOFMJAEgm?t|D!&BdUAy1g4Xi6xO(~78Xo@4Ei)67J$Y4C+L3Shx} zwz*1R)D>J8(W2VMw#OFNsQZDv)Az*H=XV1@{=v+hnVXcCDVj7f6TvEGD*U{^X)=k* zrd_!4?ribP;d-v@?wTRPk)_4IzFB=zhd-do?iV(f+$nT!sL5F-(TYH>GOQs*65;t_ z*I<0w;&?jr%=uwstpO{KYSH&-8~{*oBnto%EoVNR5K8%hWIS1++m=p{Y|KmgqH{Y( z*a3Ea4($LCW8?VJFtu3O|7;QkRayXGJmY}|Q5wA=RhL4LGXX1{A-jMOA__{zot05s)N3ILuIy~V}4 zYUsk94

    i6r*Rj|Bv{N4@#G^H8gc{cVw8jh}jB#})BAP&U?d>)TS(3G%{CI#Jn zuZ9LaBLVz1yy>bDAFdB#y30MAmLq=SbNGiCh7nN$GD|=UNXE_9x4-Rt=;~p^_y;OQ zNyD%=1J*7#Y#%*=srK1kN|`WA8k+?G{caWhZ3h749nvgn~`LI3~&07*qoM6N<$f*-A%wg3PC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cases_torevise.png b/workflow/public_html/images/cases_torevise.png new file mode 100755 index 0000000000000000000000000000000000000000..a4c4785a64fe23905de5cdec0027fb6270f722af GIT binary patch literal 746 zcmVPx#32;bRa{vGXb^rhab^(3Wg3JH_00(qQO+^RV2LTf%HfQN22mk;Ad`Uz>R4C7d zlD%(JR~W{B@44rG#2?o(mQ53dB+h^mi5LknHBM)%OihWDiHQnT>d>`PCM47_voo+z z`WGOiU_x7|RfmdDmC9701{)FtabxH6+?#Vd*s-$Zk>249KfUksJVyX#W-8e)=D(bq zt$y}-v$Zij6u6CUcl*)TH@^B~bad1a5uq=o6s=Zk!x*z8-!I?RuAlyH>mYmc*MAJf z(GrI{UB)vpi&rX4pPxj#ZjVe7hEgfU$Hwk7o6T=^6dhfD+mV|ub^{i_sS)PWSQGK{ zlfStC@K3G}c}$iku-1YIiM0R`fYMrDTm3s~UssIM zwZ?HAl;be4AVOu|PyLq)eKLW=urCySMHqS%&J7czFvj#?r5Kn8)ZX6S^YTbmTu+nL zLS92&3xTW2r4*$zX#zh$L{LfraGaltO!VVi*-agG4mc9UkalpjMyw@o_ZTaMq%#>r zgcG6n;N|68_4Q|ue#?FQm&1>3ws#NcZncrtYYOo;f~C{#Vyzu)9>9P+c<{rE+4E;9 z?S8}OUN-ar}=wubg7a3!S zqDb=j{La;dg&ULQa;8)&-4&(Ou?L6K6)!C0Ryh-@A4^$c>n+a07*qoM6N<$g0pm52LJ#7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/charts.swf b/workflow/public_html/images/charts.swf new file mode 100755 index 0000000000000000000000000000000000000000..e8c1e53318b43d3368ae09a33f2445c61e3b568e GIT binary patch literal 81768 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 C5s1P7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/checked.gif b/workflow/public_html/images/checked.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cb4c523e9b2abd16bc39bb993964c4230c43b8d GIT binary patch literal 908 zcmZ?wbhEHblw=TR_|Cw@_*`|J-Pep!?hQ$uiU)3_P{AN!;EY1zrXza{p`g{yZ7&3wBzvf9VcJD zd&e*eMp6jqfIJJz3k)2E3|l#5JT@#i*vuiU6?0<4!o%&{(tl=nY)ooyvro&obK)cW zF-a?@E|HfL6OT<)4E}Q=u;}5*iCW>?LVg%MbrI09|L3t#S?$~$wR9hwg2_+Z1w`uG l=FI$%(k0?Gz0SpQlBQFq=;pYV6I)kbU!QQeiXkNo z9=>(!)!Y85)4Ojx_bn{f4UTe|vLxr+L#-WG=G=RI;`V))h?xBsu2|UGY0uyG{^y^_ z6L%XgKDhVg$J-AdFTDR2n_skP)28AJkMyl}xsidv F8UVq$j$;4- literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/closereg.gif b/workflow/public_html/images/closereg.gif new file mode 100644 index 0000000000000000000000000000000000000000..30bc5ecaba251c5d2d0e55b8a1b8cd4167a8665d GIT binary patch literal 200 zcmZ?wbhEHb==|Gats=gwWQVZ(y;>;F%hGz%!$*EeJN z^8cNk|J&RDx3&FmZk{n`&j0%Q>9c45ude=IRrSBJvVZdA{)rR+=jQ$cqU`K{Sy}%x zGXABf|4&W*my+@?Dd~Sq%>T&9{~;m&{rvuWdHuJy|8HmaUr+C!w)P=&^FyYl|CE*g zDJcAtk-4IwaYbGIpQPk&P0fE|V*iAN{|O47my+5Il;z_3$HDQRo&7&6>v;iz{|pTO z7#SG`B~bjy!pIJEnGVQxpg3V*?`>dcYHn$5Vbk~N>Xv10({k?ac93b+be}ZINv>JX z*Vjl~w@XFb)W=1msaueN+tHGhL7{tfmo`72lqj!&@m7XOZW0WPs@{{f`FL81F|jDx zdmZRj;^0-2=i)TD(j~;e<7&swpnO2a!^ceBq{~p<+{aeDS=wc0x3x&CoXt-QH3_Bz OO7U%t9Ner-4AuZ7p1J`5 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/cuatro.gif b/workflow/public_html/images/cuatro.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b33cd8739e68414089b88a21069564895e761e6 GIT binary patch literal 681 zcmZ?wbhEHblw^=(IL5=EYiRWH`|o3KzLeM2Y3;aDbLFXSX_MoD8ygNCyZiaaoO`cz z+ou2j|6eC4N_+mcr%#`rIddlN)cxv17ZO)&E3U4dIdkTx-+!mwdHLkq&ubsQuYK~a zWcR7sg)1T>BhB|*k34a=d&;!#8_zS&J}|Pj)$L!n`^CriKmTZNIOTcx*1a!3F1-Kt zx>K}_n>hi?Oq-qD${#@N_cue5pZ zv+t>=@5i6KKXt~8(u~SIYUB1k#mFEl*O|onB-V=HcZpn zyjMbv<)>Pv&frUWL*j*@9}nF?Ka?C!mZ-9==FfD>C6Grv}jkXGVihYoIuC$CIJ HI2fz}@3E&Q literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/date.gif b/workflow/public_html/images/date.gif new file mode 100644 index 0000000000000000000000000000000000000000..af14779cadd0edd9e17d56bd79dbaf355c800978 GIT binary patch literal 94 zcmZ?wbhEHb6krfwn8?h)pi}h!|9{6dkAbA(PZmZ724)5w1|R^*Gcf7T>9;)amVfaa w-jJFfdpH05{Vl^#A|> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/deactivate.png b/workflow/public_html/images/deactivate.png new file mode 100644 index 0000000000000000000000000000000000000000..0cfd585963d255190b8855a7689e8da1c4d7cf6b GIT binary patch literal 700 zcmV;t0z>_YP)*?Fk0YVb%?UEFajs1S?+YtYiPrjx0+ z+4YbyJXwz!SX#yqTlhtNQ%Ku9=RNm$j)&+(}lZ!UGGp|@|O z09YA#-dR#rIaGe;MBLe!ht*}!c?U}6YT!dfHDO%~>xtx&Klk-^WB==sC_vP4ddg4L z#GN10u$+QGf$!(i3&8VpF6O6+ef~&gQ#>AVqCJH_utvKMAuOeG%3%mn<<%9)yb~#4 zHc70e5sYyQ03$?zFUko7D1Bg1=6jXvg#bUm1b(pVKuC*}koEKGdj<=zdM#RWsl+kfRf;OU^G_BQh+Fc$z&F_AHuQYu(b)aq=H_Fx idDl8IBmWBc*Z2i=4uSP&;Q8VJ0000p3=IQIcfBJa06QY6YgzyR literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/delete-icon.jpg b/workflow/public_html/images/delete-icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..540b07a6a67d13260fe79a9cbcd56f1b3086dd18 GIT binary patch literal 2316 zcmbV~cU03$7RP@fzmP%=O;7}+OOYOm@DO>FpopLX1`z>~5|t`MIwB}V5R{IhA}G4Z zlNJGA0tktS?IA@1C`F`i5(!B_NH)B;XZM`_Yj?kQ=AJn-_ujdmGsFMPp9Cab9I=i7 z1OfmMfdPCTu;1Rp!S1-5hm}h3S^cnxpkS3)qkV=d+Lxk3F9xe%U7S>0jygE0#A1y1 z>ZwFt@;@IMb6Lek#nJ@D9|P0979aJ!&!XQ*2I1B~~Bj88`0**i+QDP!Ulqd>; z5RniO6%!Yi5J!qgq9w)Ag0=W|5r`mhI|~Hi;z$Hiu=_uX-wB`*fFWQAg{T5TXb2Py z;r9T_0!SF-PXYgw;3g0z3>WkyA_!=a1cV?^s1OJh^a~22lLY4gh=xh+F|reucK3&? zM#>nc72HRt9emy;>+uIe-6SCD3KAu^LtbI0hNhPGUL8|2jJbuSmHn>{j!w>4mt)6I zczSuC#08!WIu{%g8WtUMDK?I9IX?YrM&`BaS=oiRZWk4ol$Mo0sD4;e`{;4qlg6gz zmR916w)XB%KPwp9Y79M?R0zrlx1U&3>PoUsz=RSY@rTIo$P)Z7v7^{R>Or z{{s6DF0_D42n3-Ze47g*6epNaGzi;cBrIj;4)>3gRy9sT$Q&%V|GW#SX5zt+4T$;! zC8usWrNP`r`;+Xy1H1Bnk^Kwo-&{066bcbM9uy7O0$ZC6@?0{LKJ}r?M(VxWj>TiA zmfElNS97DWsS{!G6~XeE==UZRwociMW#>LFhneoiRsLy)|HY!cnKv{PSCf}svv*I6 z?s}HDiu@cnTcLQ>NliU~1Zf;r<9eF8DH3QKW4$TOn!n@OWNAW)JL==Sk?eSD@tb7t zLeoxx`d)YESG0>lA0+ZmPl}{*C5V z2RVd(Exy~lH~)%~@^DN&_j001T=colXwKnx#%+qbs}-p3mHG0_xSSRP^t>ETbHq&S zh^y7cr6XW+!=T5f z1lPd}W1G6)l7|z)t-53x-bbF&T{qZb;Yn`hJ80PH-9wW0k8z@@-nGs#eb9KhQ#Zwt zy-B0Tk?ex{RfiOH?7Deuab2Jf_E5Vp-M)tC|_3xFbXgqOOF#xgM7e++(f0g z>duTT=S(SQ#h(quWA0xJ99%AHV()*Q*Ec;^DGb(G-wv`_Vx50vdNO0bD=vhWIP(m} z2RwBtB!#x4buFBn<*%n(lX0x@Y5JH!Z{(MhE_)tGP+}jA2^S9`k_=zA24GxO>3MSg zybq(Z)bL84vgRl^r#qh5dqdifTNB1pVHA-X&Gh5kLfH<4RLh=wmDVB4jisMg!nJi1 zAC5GpbRE#6TU+u07@F%lgK;_}me3iOteh8kBW=1oIC5=_Kt65cr^CJQ(kPS}*Tt!l zWM!Fs1#yed$HUqQT0uSj-Ug-BTLEgfZ&C;;2BDMXn{=xpzm+?__3CRwF)bs38@tjY zN<$gGmR**oZx=mS(Oj?n_Fw}`JWFr)%^y>iA$U#sQI)Tf2@>*LEbrZu`M36Z z9$NkC!BANB8R?kAnBM^7%E)QImK%JadrV^V*m1Y(5e|EP+_AO+LH!XLTQXBIMx@|H z)op{LQ4p5IuEY!6I0he>k}H_r!k@~vl~`2O7$8yZ22SYC2y0U{PB;h7!|Q-=n;s16 zE8A>7&=j=5%owT}xmw%w)3=rgKEaKs?X{K?U47lDFmdOh;^bDbW<>pw$c(n~5uU_+ zitVh-(qv?57&pWHXzo}2iuO1!_l2akdi+M!ho%L3LQrIsm-dbq4T7J*RZq#$mSawrP z7@2R_l)`tJm-{WZF-@jr$Hh>D>Yhj%%|u%%2IEeo!=J2|m}m{{Vltx;{Yxc2J}ldd zOaob$29ZNmaT@)6AkB$&cw>f5;v&tdA4Y$f!G6q*AaD-0?IdQ*#iDjj$z&4s;`JW8 ztahHsCEzyCFv4?9`=54@QG_oPS9s5`bj!2*{z>R;@1TPxii+AmNjrFf-+)cxt)KSE zloVu2h!1&X!gE&@g0QZJRL*KXP-lHlRA=1LadZ#>w8R0xLecBf_t9S?*>z%?WNF41 zu^GQ*op5N5>&IK|cmj#6HQO}*_hi5R$tw6F<~M6vSs_g_vGmLNzn!VPd5_gMmmS-| zls>?)?S9ChEv+7U;Nx;G{Yb(Cf2=q*={%W5uF=2$L^r$b|SZA#_$l;8aw_LX9g8&M%^S>?v4f7+-1<=&}r7;^20 z52K+l6Px#aHjKJF#O=@YHS-|k#k9D*=dfDnocJmPH?X@(k`LhXX;IWEPHO#by|-6< z-P{Y1#83J}fFq6m4E<3X^)5rPoL53p*tB8LyYo|%Ww_B(hoZyp&0EFee8MT~&a<=2QwEuL6^IOWsdGZx@v?p4HBhDVKU#5)OM{cp43wen p;1WG*6ErkkVV7;L^(G$kxz0oxooe=HJgesPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXZ1 z4+b$c;|h@g00dJ>L_t(I%UzVoZir2axhWda&TbkcPO>4ksT$1^fr0 z#&%O08spS&LrhE+=(rJ_?w(MS0vdRDO$ZI#YL(J_hJ4k*f|^7e5%BTLsGGNC z*Y@`_JUY#6p+@(xr@H4Ly=61$Z4Z)IvjW|T_}`Oc>OMZ=v_S0I zgB$_Sdm9Q=T#pqaQuWR#*1YgMD-Z4`xiUq=#6`T3VS-x|P{^ZcI?1+XS_~b(T%+g( zD+9!q2M|B}f~p&xjZs>sT-7ic(z)X)mc92jT>b_1&F5It8H~1WMBS%+eG)$~30gYP z;z?F_wNmyLnRCO<5?%w|5w{-dV)l4O={@V%{KWyx%oXy7K4el~&hooAlAOHC_}C(1 z{XI10=c!LlQEzNUDS=(IxLk3lNmU79lm1f7P&2a*Yj!+Jx>Zs7>NBpC5=3|IrRRxf zSr{3o)^#Vn?;jw(ZavP#ICgf4nimj7UrT6J#qjGPZ|OGNVP>P0EEjZlMC2fo?Vs zFDzhM6=>_i86Ckoa~490+0#ScuAQ`R>L;FvqASHxAPJQOIH4_D*F@2+Q&_4XB8@~> zt-`x>p2b54vCj=MbLdlscfCmN;t==&gEmUpNnItW-ModGa9!QFoL!oL>EZ1-y_unF31-{-(7y=kdf&fCG zuH?qR@t&zKmG|UIR?2KJ5xPbYN_@{J@IzD>`U-Uv_(&iw?L~&Se>Q-I1`Hqp7ywPd xS|PM21!603mr}|AvI=z!I0BsChjRHJ{{WRTOtC3fYw!R7002ovPDHLkV1j6sC$j(m literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/delete-user-32x32.png b/workflow/public_html/images/delete-user-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b603cf97d508bb9c22f9af2805c973472a2d1c GIT binary patch literal 2455 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 VZe8Pbk5B*r002ovPDHLkV1krcdNTk3 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/delete.png b/workflow/public_html/images/delete.png new file mode 100755 index 0000000000000000000000000000000000000000..586d543f787a0c3ca485ee408016834fea6f8ddb GIT binary patch literal 248 zcmVAZ3WGsG!hnf1hwMS)6$vB?g+x#mWE6>nBEx=l yHVO)XKv8TuE)NwK1_UAm1{W0%Ee;I^799p81PE`GkZV~Rraynv1l zho+{+$=z;;*0#>eH)(VdJvJ$SgTLx#BcZ)I0#~#}9xL#_6XSlt!}5if?LPygo&S9eo!@$U8OckI}amzM{0A=sr@2*sZ)j0_Cs3_2h=ke?XX zIu6V(@X(R!Ke43fWR6w1OH0#438$IYXD0<(aBPlHTpVC<=YX%q!vuu|^DkVzt(kK4 z#bL*_Zjw;=N$@+Vs!8&C s%IPYJED{o3X3nRqF6F5uBeKDq|G*q`US37biW4VKoj!B+tRsUp01OC+)Bpeg literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/der.png b/workflow/public_html/images/der.png new file mode 100755 index 0000000000000000000000000000000000000000..c18ef6689676d14db4707f69c3e8168ad61bb399 GIT binary patch literal 1275 zcmcIkzfaph6gGk(L}DnaXw?oqnX!$}b_^z#69fsAR3so`3EB>D*q2}>_POVyF^uih zPF-7d?bt5;2UyrxIx!Tf?Z(8;MDLQ207E-*^8I@HzW3gJ_k8bGt53($57Lq(jg^;5 zYkVFNePo!AFMqwQ@M$=nFFUDJ>gS)8-+cRUb=g@sI5;>vJ3Bc!IX*r_HqNf1f)Y!V^2i5b|&4L{7w000^IUS3|Gs;HHyhxPe2VZ@C=1OH-WCIe9*0|$v>VZt+mo(FDBpR_}Tr=&uW}a)+2@Mb{_yKBQ7=;ZR4vhcIubVY53tpD6UzeAu z_pkC+76aXH#eLW5Z3dBp;Sc-)nGladr)b6R;P?TS)ETI0P&KFD(^njEw_KWYQXgIQ h9!ia)opH1^F(i%74Q+n;pp9WZz{RzCfQS7jw={Mk|eOhS5t%R z@o-N*KX&Wcvj?YodVaGnne00BX)16(hzDVZ5(qq1zU`j6@aEf)+-}T50n4(S;L2*6 zbFTqcagbd6GGi|sGSWT0&t~8UyI}ki8~79WL-2I;woMOJ?brb(bFizzCfnD7kwvD2 z;w5|W0;7jt9L{C3P3NHH#~;_gA0QNxD zkrW@EXarwf9lm9?fV5ynSOz2e|5}(G9NF_E>_7KW2A%??N|s((@r|Y}MK#N@|DglV zPmVFx(n6}Mr%yMn!v#2=flCHxeuyY=qZ_s>#YK0PY`EDST)Q3+jtR*n7(H}IOC^SP zHo=i44Qv7)fnU|$x9vNnYd^mLpFG>n@M~`jXEgnX$6)_+P~bY+31Ta3FLTQ;mEX5r z@|0CM25?Nk&|mgXPtT-p{ucByFPW?KINVXTX2sJLo3{v~pkwMfqbJ`a(cJd$xMAM) z7__|y221F>uqxrv@Q{5KZega88Lu-sve@-=NbwHs8w+d&q7_ucMb$oZ0{Wf|}8 z%U*)tx3aWapLn9a!iG!n?wB<&j<^Dyhf9`Dvage&3-RYudHr|Ukpz07z|7z<#cS6{ z3VdO~z%5XtM2llu)^H4Dr$?BbRo{36CYCJwV~^FB)x}zjcaB#Z7cM(sY2JWKhT%jP z@y`AOZ^J_w*q@z9qN#bbd>(gM7z;Ko>;VN82Jtf;7=l$Bt$70` zge_S@pWi%%d=3o;uRA5TZmlma4KypACu4MtAkS|$(+;_;g!9RMy58+QbOrtoC;*H> zK36a%F0~!4N~a1arEV-)l$yFF90MAN^h}EUbQgZVA6+;G1lQ>MLaf%t63u0U#N7QU zBq0!PH@IAwJ~thc19Z0c9O{6t{}WW^Wq_pv9?L`mkc5-p_@D(UOsfTz)bM38fUioy zgxEDhW_6JwHLuEy#-yW3^eg2yO=rXDR)LN(Hx~x;FT7*JUjvn^R0LkhE0u}7fdojh zKr^jW9xTVeB=kltkR^d+T6hE)g2qw{rhrGGKIoU5H-tU0(!Ob=Ip@x5r{;9Im-iC6 z!#2FB6;!U#di!$wWDh9~84$8SHR(M+pNDpcSI%l<6{YTSF;PIC)$xVgTeeMUkzyzd z*zk=JZ>%hy#SM7CS!G4y%?gF~c=qtS7ENuSavjOA)9(`K7D#~IfAS7??mZVko5>hQ zrGN_o7`B0EiQ5~3p9YKM=3C0Wv5*aSIpF!Y0Vg4)H2irMkY#}cM6w3qD&^r@D!j4c{wxwWApfA0v-X;1bZqgz58x7EXkbJ5rA0kr|)v^tu{D(-SfaC^aN7+ zs^|?x>jRS-uK7vj^xlS_u&Z;lEB(?Li?5wu0=^S!*9d;QW<}ADZqrQJ7*Wvx?5dqk z>Dffq*m(+umOPSefKaVV9KCC8@r{wr85G092YBrSCxb5DjpzDHs+T`sRbPKx7ot}f zMxi(wjYyWYekyVKUTy5+z3a`ir)nTeHe-+jv`U2&E@5^ja^E}x&wS*ebQ8qNJ<=<8 zH3UCf*PX_bH5?N@Ng&xRNLEKsmo08!p|1o$o{b`;J8z3BpN4y?s_o`aonl(X1)Ox*yBnhu9qYA;eWznM+ z=;)iwjE}1?tMKbf&^7|*f9>J45?mEczCYN{iy hs&A!XI?4Zu{sW}21QM3dqm=*v002ovPDHLkV1g={D=+{6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dialog-ok-apply.png b/workflow/public_html/images/dialog-ok-apply.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3153c4b8c3bad6ca9be9a9e3443a340f7b5942 GIT binary patch literal 1218 zcmV;z1U>tSP)U^|__PTIO^ojCBpP2VE}0@`(-6h!L|#k?Lfj-_#>{LYlWbE!TIdS& z;YuIx?3EYd!%COAnHWCFHb19U6BgK;n)?k(M`bef$;QL5NuDo2k2(nuG8p7s~r^# zo24N+4%=In7cI?5gRR9@!LQ{9>I=3g&1MsXNC2U*kdm+%gvT|5&cRNEJfU{!UFkI} z<4+$WU9*l?nN^n_DBPqic9cLQ34|8~^#6QDa!t6K+;6(y!(Xt!WG^$D&BHb8H>xKY3D8>PW&8jtz9d?VUXwJsy1~?OUKWsK2ktE7Rul`4A$0L}CIc6~X<^GGe#c zj^^yo*@I3EG1 zf$&oCuza()08u63zT#rSui-ka&sujO3HLO&p3`z?tBML$T9!sA?w7AkDwJBsDrkJx z*Mmuqt1EImvJcC+<_OeJsGB*?cz8?6-9)3)gHj?X0-^v21yGR~hDOH4S?|^7SsnYv z=CVSyj?*F@mmsFv4v29ePwl|T-aee48vk7A7Iq*Fe+wk^9=e4$84uN#7ZZxfmJKW! zkxe9}SQK&kn@NK!s-eLk^6goJv^U>4uHNLxY;Z&eIuoWxtkBNwRlsRZ; zxmP#Wt|bYYf;;_A}~m5Na}3F6Cz@<7!uJaqR}{_J^`bH3mBhs4f;>`>yQE0 zjAYu~+C#T#`PO^tOz>sTgUUkENKy(4k%WLnQGh7#_ymxMOE5%P%nmX5Y1TF3`@&a= z3`v^_br0*_$usaz71aatS`QSerEw67fB=x!$}`u8^_c#W!H+KY4-35urMM1O45iwK zv>y~0Esx*TNHA}_3PoxZ1RzVBP8ZT+s*A?CU#2hm`g}#WPBKcxOg;0d(`bF<-Y1pt zavr%0DGY)ES31-+tK*YOV literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/doc.gif b/workflow/public_html/images/doc.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a2a2c890ed5faea7867a49fc149fabd01889147 GIT binary patch literal 653 zcmZ?wbh9u|6k-r!c*ekBV^^|d(V8olu9TG3?Af)Yr?2PDt3OK?T`4JAbLZZdo~}Jd zj-6Sv?o3S7l$yFVSFXL;v+K&2Z(nNadgjcU5si|7? z&>2hSN{C_6B5)iXWo^bt~n)T zOO70SvSrhioV+D}e*I}_0-C(W#}6pGWzDK5Po8~oajIFeY{`{NcWSCy_Uzl!(>LYK zyFW{oU3v28OHbdCGpDYsS$8ER3Fy2nSFU~8v+K^6Z-3^@1G=qd%cd=JW^LKB4d^hS zUZ80}1wh7>FQ0(6Y`Jsm%btCAO3K!>G);N(><_~L0UeONptxXQ|J0zauCMOzA*ILB z$>Ag-*3zWk;^5mfO_;$fP)Fv zIXAa#RY>X&U}3WS!XC%ly*jClLLZL k3eH_^YR)nar2<mn-n2wFPn8hU~X8Qvdx5Z?Ma|tnO%36yl4mW@NVNApgf-&q5foir+u}ejnkuax=Z1K5y@;&F~zV~^~bI!>*uV}6LEMYMXBC;5$Q275q z0|Q#?fsZv%5qDkp<#O2t0YR8qBbP*VW;^c3O_H!I3){BW1G5^SB0gR$ViQgY2V?(bo@b&@D4V++N`~tpPj#4sBi<(?L%~xE_ z(rbP|(^cO9;;Ff$DUhC*?%z5xaBT4ApS{>CBI_N;=`NMa(U0GI>lylv{)v{BW|mx) zX5OMSnK{kaxjc{}aD9Bo;Xh}_IDPW`B>P#t;U}zE`%4fbA!?dtWh-vbTE83{*w?kK zeED26ed=`IfjjO!+2Kq~bdQ{UlkVqskdlxaw_Zox{1j-9st}t}A;Z!AJzN+YXX8)1 z$S=B{=`aibxQ{+2aszryk_<}pkM<$8QFe9|>O z-`;*b@4k7S{hhb7?v`J3_1EvD8muUy&|%%CRal4ZwS9kUW7}<8sGV~W0tXfFDKWv7 zt+o7U!DbFU|2QRQoNG7TQ)L@!Ey`1q#pi3^Y@Pb5Ksa4kSExY=!NmeW(Lrn*yRHE< zmjhMiqsU~+Y`XbNJlWMneSSI1uH8IK0zl}8fQGO%Z7&kTyZ9l+{^PhKgNWxLK}bBW znL4tISCd=PiWni&QImliHm&Blt{wbl&qh+|Y|;Q|lpmrEK$sHO@z9;K|E4%eLXB%0 zjFz&D6bu4aGdJtgl$$`E{5z%hPf)jF1F6Oa&?**Ky1a?Y`x^P{o}aV*?xzw44ABq< z0V)Vl;S^Pc0b}oV;}qUTGD825&Ay%ndPi5{E%-ia={9;kY-R7O^EldHi|bsV@UH`u z&zvE2{g|p;;>H_R(D%>7cy2M7fYJ&T2A~BrU`iA~sqhYg8pX&7J+Igl!e#ubV;{Nt z<{1kr@Jjso!REM3FKx*LP+G#kLxq!69$I^Z zszeYBV`Pb#O2fj%pG$~Ws-4bq*Y6JUT-PbCJ%q)5J#TOdnTMIC27osJLSaT=Yh?tj=N!3#~rzyDx?3{Ja3$NF8rVMSN z1CU{)LIVt$WTl!K%d|=7YVqAOOd*lR+$&Zw_Wm0f89`|ibPBCBN-3DEElXDh@J4xt zfx90*y$6xUet$o*b0_PI#nO>bDGa7gLqpJ7BY+r2Wuyu5I0Z9>nVEyKe0;x5P%Ptl zE@IV?Ui3Y6?BM=KfnKIz#9r!*X@d*}R&4AfzG|Ituj!-;%9GMuRP=Z`T z3;9LY5M&neNc#hix9@)Hu1P&r{X!BiEFx;95Ywo3zQ+cN;}@bk!iZPLnjhXr7zPXt z4bjp5z%w05@dyU9KmfEttAH@@XNx@+A3Jvv%M{!|lWABoB|c2&?p-f*bnLx7Azsx$ zB%mV$LJ-Y;wKpiYRKOW8VB3P@o8((oMk9Y@_pXDx+IDZzRUS5|2CXryY!s_RT@?{@ zRFw+w%0)uIM15_VKv^ie9!WLu@UDlR{zF^m)}(m#JE4x_M-VFwV#KKkI{K(EMC&l> zTb7_~3(rguicQ19RpEne4|V;qYwwPPcy$Bus;_d})ri($09pV=)V0!xl_Rtpo%YU0 x+n?C`Gl8s002ovPDHLkV1k1tFf#xE literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/document-review.png b/workflow/public_html/images/document-review.png new file mode 100644 index 0000000000000000000000000000000000000000..2cc1fde59bafb7d61832153929d26e63350e98a1 GIT binary patch literal 2000 zcmV;>2QT=EP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igP{ z7cB|D9BkA800&S>L_t(o!@XBqY!v4e{?0$Mb6Je<_Sy!+E?a}|m$VLcOB!KlnusV+ z5=0|asKQlWnx{Td)E8Qk^rb3MBEbV96;h#U$whJ1a#4gMDo7B40I7qwyDZ@11z*;? z-t}H)=Kudb_!3`s4M=H^bhI<0U-NzEJ7>;0OHxYYv#Zyx*F>Y^&!iiobS_@$9p+j%|vc03@hc1`ux_vt=I4hFl55vScf77xo3B4LC!97Ll1XUDsh6#sUI!DJUr^ z=^q|R*uOt{N2#eUN86@mbavNcL>v{#t~tg>e1m9mJ9m?COz7CK4zt zD#{5yp9bZtfrAHMKVDr^Q~HNL4QEQq%dlnV_u*Mnj;e|kC@@uw$8D4pxL_)T6bP%! zTT$vM#wX{lB5*g3bh;lqcI;TH!Xl#_sxSaBO>_6njRK|Gr#f_+5QwGEBLRKL} zED7ig!;ZkPEuiWyknTcb>sqvQZot_uIc(cTWH2A%<* zB{N4VR|jN&sRjrvSR6~WK5Oh_6DkKDBFrb7H{g*qp?5?kx8zuROk%Q7@#nMMiLqU z1|#SSL1P5Nr9f2`m<0x^OEq9N=QAW2V_@^{^QprA*7wngcs#~xDht!X5egAORT)&q zpeYPGBj^g724@6KA-EKRsxUBxz#WcK(?&^g@q!w7Tw~E_G%O{Y&7HN}nn)FKApr?6 z0#pLDnTT~|2AmO;neR*rK+R?Wp23C<>z7EM%a;(4Qi`FWp?`kIFFiF@#*>}0VA}#h zPJhcPBy?pu9WF*-Ab2EcI5?norKM8W}LNec~>LBZsIkeEus=kp;L3?iLQ=LA}gz=CN= zMDp0Xe?)yl1EyRaB+UZE6b0@T8i)}z&auLAP?{RU{m?B00s*wNwqTv#4}~$@4u#Ox z)`rs3(!70uF_wE8&JwtH?;bw*@I$OwvldlVRVXYhMkH>-#T*psz{torLcxEdy}cEk zot-#y<_xY}xq_X$cA>he3OBy^0u2of@OV7Ai|$bbGTAI_+eRoDL@*e{=-4`A^?IM2Kz4?}{C++^ zhq>DA(W6Ik>Cz<-5q|vYt7vQQKq4N4ZQH1?uV1jRD33+JaTWkG#`1#CUY|H|0v9h{ zL@XA=k9O|F#_n#cFbsr3A+)x(PM>883|)IP0mpIXfR~GY@o!&WANu?I5s5^wW$RXK z-m(>IR@LCbg$rnGY(&NpNnh=%f}9)CqH=xYM9Zbdwr$&>X&UB(~g252V%1Uwi^l5O;F)=ZLm$vVa zEiKJ-_4ChfojP^ug~Nvr-EqD0;VgCg&-Eekcc3d?80000xqyejSG2WHNksk8ZP`K2dMzWsDOa3k`>-SS>A_lF#~YHx3U^XARKqj#1*e5*fm{nlq6^lJMI zLZS`3W;=FF)7o(*<@Ei%&%W1Oc^Y@>zWJW(pFVvmz4&Gx2!yHK&Y8>(hQj`6Rsr8@RfJ-(w&fT;<0a{ zrS#t!r3T6;C-s{Aai}=a%H1yDt8w7U2}foZc{_`mA4OWqjAC5^tksX)C$LGxSy&uw W%24FxHg8JENI0}M)}@hw!5RSJfSsHG literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynaforms.gif b/workflow/public_html/images/dynaforms.gif new file mode 100644 index 0000000000000000000000000000000000000000..4cf8786799d33834c486c7da65d63f2edd4231ad GIT binary patch literal 402 zcmZ?wbhEHblw=TRxXQrbHTl@;%m3?lJ~(sc%%eX~(q^8y_wh&Xkq;-|Kl}Onf7{k? zlMnyC`|kglr~gYJjxf86A)i;q6vfA9a4Jx{*<`_a1j!nLuXo}K*_K7JFXF!M7W$lDz{&#|ar0mG4UqlTgh%Iw^ndCleAb?(eck|{m% zl1lAv%uKQ^d9q9sU75M~D=U*3__=1eFw1C8%hi-w>dY)5HNS^JN@AT8vxdT|90iRX zy3A@~o2%H=4l)a9?`7Z+IHfGDuFiA)#&v1sQ=+VVqQb(0f{#S`SVa#WVt)JX{X73p LpTGDyGFSrui-WE0 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/.directory b/workflow/public_html/images/dynamicForm/.directory new file mode 100644 index 000000000..62dc33166 --- /dev/null +++ b/workflow/public_html/images/dynamicForm/.directory @@ -0,0 +1,5 @@ +[Dolphin] +AdditionalInfo=3 +SortOrder=1 +Timestamp=2010,3,1,15,44,37 +ViewMode=1 diff --git a/workflow/public_html/images/dynamicForm/button.gif b/workflow/public_html/images/dynamicForm/button.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd3d1e4670bbdf03ef53a893318492cafecabfe1 GIT binary patch literal 395 zcmZ?wbhEHblw=TRxXQrb?%s9u=&k9~_ok$5`TzfadDE0npS~~OexbT$b4~5_2M^w? z-Fsv1+(SXZvrEg)mXs{tw(U|`&F0$9IXykw)~!3^<1_L7_wN-A8zwE-cIx!q#fy*R z<{gNRUcPVN^~(CK-@kv~fAJjyErH@s7Djdk1qL0EB_KaBu&r>IP~f2>)qi41(a9XE z`CcpuUTggXPjNRKcw4ozfx9U1=d7J`Pd%#85H^|BleS1uLgB@!#A<-OmZJ-nn~E=(-m-`;({7p4_QKSu^@0Ims&EC2ui literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/button.jpg b/workflow/public_html/images/dynamicForm/button.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9a3a5f25e7af259ca9fdc9b8f18f959e3120c5cb GIT binary patch literal 575 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLgyEVrF4wV+YD<2rw|RFtRW)GP6SE8G&+w z46H)JhHQ$CBBDx0fk~4u0aZ#eGBPj&F%kf(WMlwXLx^o)|rD9j6lfBw)JUM+LSB*8CK6a6Un3W(CAUfqEA1*zm@j* zsch=(_jKFToA*|OrC;`ByyvkpLS@O+T(x)GrQY9B8 zMbgxxM(aaA+?TnUvRADn==J+;5v7UOC+5y#wQst7?_#B1Wa;ON3BRRyD$Z<|)4TTA zpvB~H7FXOAlZKY%g`u-Jf1X=&=KN&8WpBHGhkwfdb^iCc&!Rs9Rga}NPPltFeuMVr Z+UmcbR$8a6aGT1P;>pI4z{dFhCIGAxt-SyM literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/button_on.jpg b/workflow/public_html/images/dynamicForm/button_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fe71a19d10fe71a0519dd18f9360f389fc1fa330 GIT binary patch literal 937 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(W?*DuVPyx(=?O3}vM{hPv#~Kl6&%Cr-K~Dy9@1a?vQL5M&l3BLfpNvSBO?tc=WTOh7p^pq&iNEbOeT zoN%)km<3r_g%m|Z4IKl64hknuTzHX9DXDRzm{D-yq(z4xKKg%)fd^RduJDx4GdO7^u;4_F^nyEc_>W~@n179T&GO>y zoxQuP3giTKTFCcYUueI^H`RLX9v@#>3x19RS9mwwIl?w!ih3Kb3WMJHHmlc7#Xgg~ zh5U5?Gfe2}u41j(bc$6!{OQcNXysY6&O{2{keST4)JtE-bXVIY>(}SmCKq^bnRnsw z_hmk7IizK$H$LRP)U%aYf0x|^j#=BRXXaR5p7dQPS!Y+Ud{;o9vS;9e$(IW)Qty{} zzIoXqqxU+9(eCwzm!jKVXRDkF>1n*b$C)>KvZ%X1Tdn6mu3LYZ_owP_yIfj+Y1h1q zZLe0wbp8sz#J(na#?K?q?c}1fStf322)(v_)vj+}j;&@|wdHD{!)E(l{)m)gIxCJ_ ztq*3ech3BCmC5JE(&J0qd3G&$y<*#yiJ8Ad=IwTU+_xpJ>|}7H>R!P#OG&-Zr1FkE zQ`MpsRMJ~&mA=%Poe7if6;a)BMv>RxR@3yYybBbS3q$7}`Tnp>KSRxPdh2B2kV)BI z(^UH+svnfiUYoX0>+;jX&slzG{fYh}Uncr(>3;t2^)oK6xIFvx@18Z+40}H33fH^d z5WSl9pP?|jILf+orqPT-yR*9m-94^nO}+Urc1zqcoy{xLHl334&K21>D=ZQkFD^Jk>-`&C%I3YyCDc1eV2%J<2SySY^-rs#>@j5_%2oL*M)|C;~^Qd1xR literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/check_group.gif b/workflow/public_html/images/dynamicForm/check_group.gif new file mode 100644 index 0000000000000000000000000000000000000000..d628c9959bf362b0fe8a9ec4d130e0e206c45b05 GIT binary patch literal 377 zcmZ?wbhEHblw=TRxXQr5mCm*Q@FDlve$(ggzI@}lSFKmynhCp4KK=Upt46AB{F3-} zTQ?-6C*A#j_sHWTav=)6%lo$F)cAYe*V<< ztJ|Odf4*b?u36jXTzh}*|BwH{>x1Vk*&mx8ua|Fr;N0N_YY%_;{~>sG$ix*B|NsBL zbj#Ai=Z^jV|NX#~m!|cmyY}pxxBSrli|-hS1ByRc7}*(&7<53&L4IOjo8~aHz(Yr> z|3u2Bq6|3$Jx8a^mW}JAn7Uj{%luXqybydT#ytCs`^Turmi`?vc`*t>4Na$no2~yf z@bSBe%V=pUD6lCN6c@XR@baqj$_Oy0xd`zn&s7#yo4F{>$1fmgaacrD%;NY&t>o0j z8Cf}by?uqH<(1X7M*NKp&91HOo!vWkO_(%g+Kk1s=gnWZ`1*~Tw{9CbGFSruardNn literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/check_group.jpg b/workflow/public_html/images/dynamicForm/check_group.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f25c17b9a7f71784b34442047af654524906d3d GIT binary patch literal 699 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUW&*mE9Vn+Kz`(@F!pO|X!VQ&YVrFDu z5fow-R#XyUa||kE7d138Ni3Q;dE;fEdI?4bW=2M2qZoi1Sb#F>KpUADSXkH*vW!fE z%!-DALc)m?S&ST$3L6)0{C|sq2WSCMLXg3p;azXRiil&T8crekwMP$Ic{9ZH_?%4G zr}ZXRHK#@4$t%l^GORB@pW7#AzT|c_Gt1O#&$-PeymOL_OLv_3z9+5l-OA#rU-Ua4 z&QV%_=JVR=%WJzUA68cMJd{6C|J?sfe~=8%0dK1=wq)rZF}p&)3mvm!u1q~0n){kZ zXTD+f9{rV1_RF5$k~UfR^tWKH9h*;z)VpzU_vueBzsfRCXU5i>A1osI7F!E@NgM1v zJ6Y92w@|R}tJth>uf4tA?!5gdRov_6q@_jM-lxuA5?Xt6%hB}`+t#$-obOi26YNhnrIJQ;|0z#v)P@3z$V1k{ay)-vj_} C3ghMg literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/check_group_on.jpg b/workflow/public_html/images/dynamicForm/check_group_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..37533d1a86c8e7f418627aaf345cbf84e34f73ac GIT binary patch literal 946 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXoM}Wn*AsW?=`)8455kF)}kTv9qy5;3ERG}i8CuDA0H`*_gkz(==@Iulk;31B#>epo7T z5%;=1mPe0n<(Pa*%sa+I!DWj`((S0%Ed9Kit0!^S>~FoZ@uPkICYeu?AFVtWt&ZOk z<#2Rs{q<#{5qg&=Gi-nBR6E0Es@U#5_g-Y==BgB4yiq8vch!1Un9xMI?-Qn3(#Xg+ZtXOt=&T0F{EBJZJCC%K4r=|7Xs&==rra!#U+it&lqh?SiACA9Qyz1Dkq*XZP==N~w}vPUlKvRvSnK56RW zpjJ1@L!!2eY)oby44caBTASE?Rh{|3ZvDHttFGJ4*87m3njISYNFqylZnknJOSI}^ z_ke>_t5bd6Jjk=XUASD-Wa*R#5C6vAOv|0OF4pP9r90hirlOY^iUN;{@lU+9;FoMj zrnmkPTiKg_=Yy3m>c=W%#IYo{39Nhg{CxO@z_QhCd}|)R<_LQeWt0$Y@MYRIi6GTJ zrHv~BJaQiJ)ZEhb<#v6iXRLCb@04_Ih2ZX@{YOLpGkD3n{od-&xbWG_n|}BHdDVo* ze_8k?e|PKy6Pvr%dbjVN?eHq?*HZ6FUaP-Dl9Hd+4%3OgS zGmY2oz0o;s^}RR$wJP6j-n#9<{|8}Er|1b#uwohe{;$m5-GuMTQ zlaEiNU255Kxec6aoSAgh)HX$NY46kB<;0}0PhOMj>^aeW3dc;Cg!J{L*>ByxbzSH( zle(A~8=Ls!7cbNw$V9yhmwCYY`ODXDmw9-FfB*UWhc|YDfq=t?1qYiLXKTcq*zji3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|O%qGXpYUWM*MyVq*tNY6}1*8JU@wIT@h}m>HQ^ z1Q}R`ghdS56a$UT9Gyy9rfk0a5vW*-k%5Vs5vCBVo(W_W8&FPFkb#kznTZX_B1R@b zW+6isMOJ0U#KI3ofgAtdV&Gv0njy$6$Y9U#Zc<8@NzqB`Z7e#4T(3fxZPg8%bbV9W zWlc`gAKo{D#osLb&!98gV@JfUf3wxf9n2?gw)nZjN0{}tVA(srFrz;oMT3%8CK+D4 z%bjy%n#7^0^Hjc;Tg$(psW#&^Yws40!Ul7c*a5%0n@UDp1TIlFhN{r#BF zw|cW*hD0yle(_Do9KC7FxV28J~Z+6?ypZvp^~hP}uD literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/checkbox_on.jpg b/workflow/public_html/images/dynamicForm/checkbox_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eba561a751b738443df683c42d09803f05f23507 GIT binary patch literal 952 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(VPIrpW@QJ;8455kF*30*v$C;6Z z*fYEf=nMCsa%|mFZ!RzMn8S?9%M7k6Ul1ycnmMQDj3#H$t`x@LIo`R;4kt`7OJ(M{ z-`-y;eE#Lt_{*JETNlsT`|a1D`|s!7E=OM7D!8|vXQ8FH?#gLFfj(yMY_h-J6b-m)`SprV zuCcJ+hg&B?Ht;20_KYzteWl=>`{@Pi2H*7tf!a$HetR+Z9m>8dWfe5t#8cry-isbL z`8b2Pk_WF=oM5tTu=;aO{7LgI&rtazcAQ;rSIu6>cYbCs+f$iu?pCqUHCGM8o~~bB zShjap-1Vc8-?kK=Dx13NW%!3xhdRt>aGo`J*PhBRXldyEYDLTr*+AjNnH&F}la1XY zx^;c`pCf5cr}cHc{8e?hXR}#d%C0+yR_fjK7Fwz*2spysjl@( zSh3bkyQ4$J>l@SkZVt<&O`p6r*Hy!P%>x!12B za&Ha&H>qyY?~QW~9gp69$~Zor>P zPWJNc7j_)IdF;~jmcDtiF-e>DUz<5|=BH1e+S=NVUVZQ5 z>+j;~9uO3Mn@p(E9QVoA`7EWL?mJy@=V*mj6=G#zJ0g5sjX|GNxST=$ z2Y9q&jW6!j7)Z$qX-jaJ7>e+ls!0BnH13Y@)l>D#xuBrjz{$rWr1fSy cUt3dq+?<$B*2Ryech;;*xN~A+vH*iM0DGCQ>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/currency.jpg b/workflow/public_html/images/dynamicForm/currency.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c174d609e95f05dce71af11ad2bfd6fecdf48ba9 GIT binary patch literal 791 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 Uml)rNkDop~_WkzV+mXQ<0HE!M_5c6? literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/dropdown.jpg b/workflow/public_html/images/dynamicForm/dropdown.jpg new file mode 100644 index 0000000000000000000000000000000000000000..79243bc7d6ba057ecb2a677fedf159212aeae64f GIT binary patch literal 637 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|OHiGa~~MU2zOx!SOCPro! z23A2OHX&hAMMK9x5oHx4r=XC+#>p3f>LozlW<)WJg^`IFD5DOvl98E-g&iRYlwc7A zno+oLqmW2oV&lYvAO7EB-~qaYNsw8P!Jgr}`BJxJnR3Uq@5^f@6!+^~U2?SM((SJ~ z{|^4UASpd{&qVv@3T4+v|=?d-#NF!tR&|C)_Hi zGVRsAs(os6mSv2ce|4(3jqSX-Ca=7XTCO-X>4D!w!{gF{1;I1#+~%#F5|3%XX_=NqK7g`Zk}W*1>jVtEs^;ZD;;e zm#x&kweqx{=3mhZdsq5d^eh#9bJO+P3&VF}4xMZv9WQP~UzwH25_L_Y;OHI(vkp61 l;ZrNNFYI@jq`Gs*)qJ)4pOdTJ95|Z66TqgyEW-Z(CII5Jzsvvt literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/dropdown_on.jpg b/workflow/public_html/images/dynamicForm/dropdown_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2179ab4a51660f35449cd474817b4a11a39b446 GIT binary patch literal 923 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXoM}W@ThyU}6W#=?MVk7?@c&*cqYnj7-cd z46K4|Lc&TSqKbx&frS&rl%0Zt7hXyRnZ?M!$O=;m*1^ia$jrjV1e7xn1TvYJ*x6ZN zmN7B_4HFbnWED1aOibFyCL$VGxbUKKa^u0KMGybqV&Gv0st{xrWUyy=7x2}_ulXK`cwzef{rh7@ixw@tY-6ye;qj)QX*E+emC^b^--RAi6x8_-^*;f_wEw23A*mo(UeC34CyH~oteDW*z3)kE|(=~P|W`~}a zQ+c@2L@VO@jEU!y%wchiM^r4t=gh1)cJ2k~+j}J2JVj%6-R=5ga{9C@ zLumJ0yW}-hDuoUEWSdV5d%c*;(tG6MmpcqQKHU&a-}~#>Y>T^xp4};%V)IQ;c1!$c z_HTvasY(ZZ9-gZ*HJeiUL~g#uhPS#m54OhNTzRQF&t1Is;rPAnkKbJ`?0V36vf|#0PyhdayLsdPq|5Cwok#ft*R*YWmDzG|%drR1 z)!UlRm$@vrdj8jb! z+r0KXSW>$1!nZ$v@4Wby+I=Lt?MUb98~d*PKYZcY@{1FF=h)WFxzKhv@yp)_{l_ZL zJ^Gm0u_L8!&-WkSpMUsw^~ImX$3N&zQrdL-ZN`*iojczwzS+F~@crwLKV{B7Z=SPt z!PRaCqse~jT#DwLt2$X!J?({H1Ix^9j~+ex?>NWk$)lhD|NjqO<1zb6)wbi04_$g) zwd~f@CqFwc*3CTGH04mmv`sg+-uMyNddRtYZ%*GCgY<2u?(d1}J%9iG-|Q*pPCxq9 zxxaA1v7S#q|6RQMN-S!F={&8+FF(Hg@?*{EkN5BWOl#hECBby zEoW-_*WX!t=*g_B4PECNqBjP3F1M*aSGx23%f>4u$#bqv+Wh3j!~f5|{}-&~DW7s` z#`>#A?yOa97TI-sO+woVuQ^U7ojV<7o6SDcy#3mLgUo&VFTP_K1+WlM{K>+|z_5%# z2P6Q>6AT;`48EK)9vc=MY~~P_nsYc{;o)`x_Ia~B0+o(-3L1;;skkU|yo=p`rljYm zDejY0eGPLo0#v+=)nXT!>@4a#+An86>&lA2bf38#smnyHCOz}&)K8pOlQ|{TZ;oB% kHx?<=luI+hL*;U3PF-i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUVP#`vW(Uft3IOFmfRPm{&&bTg!oVsh zB&^70=onmBvhXrcnIt0vGtj%pMli83GqM7uR0J6qnVFec5weUxtC@uqSqvw#Iwlrw z6n^;s76T76SX7X~p5fi(*_}B-A}KRmd-T$~6g(!_e$+p4`aqD-^iOa1`}ND8m4Dis z@cH;x)#t~xjW(8g@fE$E`ZH|ilpCLBOgp`%QdYTj@p;a5Ur*&5`zQN`uD{-%tHaKQEqb@f->fI~hVLKu#VPGUxKEV-I?F3=CR@ADK+PL{Ono_UMM^{ zXk8T%nsYw0m9Hy1Y_fYmekt3ton^^Is-IroI&6LXxSs6?yU(Xy-Ll&HI_}sb>ou`1 z)3$LOSv%{-vXz^k-3-{AoR}Y_9k%4s&4Tu3OYaF5Uka=8+SZC&>`7?(l6ljTEivxX V(;$m;3uO{o3Y!Fvam4?>2>_TD+jIZ` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/grid_on.jpg b/workflow/public_html/images/dynamicForm/grid_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a59279b0b6b5d9dc461dfe31246e8b662e61a99c GIT binary patch literal 945 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL50|PVAtqcgj#LUXT#txLy7hqswVq|7y;b4c#GBPo< zurde=39~6G8H$Jn1{Y3TcuCnYC?vV$GRQ2TIY7e@MlrB3Ffy|;0j10Y89!Y@M^t*GG%plzCJ*BX5;+ADQ>wHnwBY!=iUAJ{E>ISVEpMh@N(v z9})1@jq~G;(;qLM@G$B&UZc2}SKRT3L4D_^OX<(2>O4Kf*swB#L8h?Bc*pChx~fsz zvQEdnGkpGK(%O?z^&Ecov7D#fy-sfx*>&msN5ee}xdV2`O)9?6f7VBB%Nj;G2J3(7 zE)SY-d4|fbsF}>SHMsQP?kh*$UAkblQ9N_$tS`?u2enLny5p~fx3l$b&BT4jb4%73 z7WzpEf4p-#L!k0rfqYVJQi{mqZqDWv#ygseWo4)CSXTD%)R8&Ym)$OZWAn9a%k1@g zYdH_idcc)3Wm!vNM4F-Ex@%!MQ@PEI%s#G;+N$ZZc8hS+o7;`s3oitx@4D=xAz|mg!2`R#S5pg;M1& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/hidden.gif b/workflow/public_html/images/dynamicForm/hidden.gif new file mode 100644 index 0000000000000000000000000000000000000000..04c60957b0b44be132cf165dd992dcab2dbb702c GIT binary patch literal 188 zcmZ?wbhEHblw=TR*v!CC-ZbU^|NqOkU)Z>D)x&VFTP^{1I3>#jO+}&3_2hl$P5OS%nc_!SMRlWeRlW%1P#%Y%z3PBB95>3 zi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|OHiGa~~MU}j`uVPoe2N@@x)FflSSGqJG4q#2o* z8CV2ag%pJi*_0gv*+oQ^f|E7^l}a%(Ff*W<12h)sXP}(2AOp}8W>zFyfaVAa8L}t_ zvI!eGCNBJci-8BInMsgYkinkei(Gcbb)E}M3wO2U-Zk<&+;&3w7pt<0d%~ItJ7<0~ zH+j->JL=}C>6h<(m2=%G=+yKmLR^;PwtTi$-;+z0VM~SC(iSeb{Z}vY%Z_{5duP9$ z6uo+>o9%}}H8)q+Pgb*2_VDz^On-B~-Rg(eJguu+c|A=}$UjM#I`v6rdh6r5nk5_u z>}G| zExYp%t#Rkwps29RP?Ezoo2yx=>1ahWXRTJ_dBNNK$v^f7x~>ox>xn-;Z{9+qJj>jb tc}BJ8r+VMcXVzI4GdZ8@V7?6Jq>UP`>ia~JXBDNsU|7J^z{T+YCIESLqeB1y literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/hidden_on.jpg b/workflow/public_html/images/dynamicForm/hidden_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3ca743ef32f158c7e6cb0b7cab274696e01fffbe GIT binary patch literal 913 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(Wnf}vVP^x%84EBlF)=bRaQdwK<5#M$`%ZO#D0fA8ir`_{BZ5kcJ|{eM zV79c2x|+c`%fmCt^V;K|T+6pF2tUlDvF&8sl;1hmbU5W)rYg2txops55u8&S7Ajxy zLg29UJ+GBkpVAmlxrrQ1VmRLLlS^|)j_AMcX|?OjXWeI)O__FeshjN&i<+KZ&o>wE zHmUw+SW>p=z<~|dRrIya{hhR2YkThDBHvH!FATg+eKOg6=;QwUT@F3WkB@AdwCVU7 zzg;V34t!f{e#9_xqVSuO*LJtdrLB*eb5_(n$-AWDuyOh1N2Q4iBm@nZ9&Fz6vNU<^ zW6@_#{co@49%U&C->PEsAktv9;9-fYo~#!;P6R$)^XFDjMM_D)Qs;f;ACqb-ueKCu zYpDHcKear@_Wo3hzUWr% zp83Y_wx0c-@oBm9*O1=1eks?jcZWu8I?VKUN^6Ml{hJg2X1jj4`%FD~w%73$qTx&S z{gC6b-?f=vGw(2$%f=&Nrd*u7a~S)NE?aV8!)`J2d%l0H1FqeA5Zfm5Z)^OQg+I*C zuE>+Hjk~*gclD>G*H-_VV$b$->)XTZt8Z_u&aVrxFSw(&*I-&`Xu=)~pT?fakNoGY W(V6DjSQ@VVe(BR0JNI1we-i*cs!sy| literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/hover.gif b/workflow/public_html/images/dynamicForm/hover.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f76294710e7b01eae2150a70161726412e56e0e GIT binary patch literal 560 zcmex=i3*BJ!6k`h{6D}T z$iX1aAj!-q$iO7X$SlbC{|JK=10w??D+3Z>XJKGuVrB!%83-^iGBYu9F>}JCnHZT_ z7+Bc^g+xTflnk8$6BR=)IR=LoPMWfC(Pofoj0{Z7jEpelAexnlnS~K#nj+9vMivxl zpgn@ZfkGlmj)jU7|KDQZVFv0KWENzwXQ6X-ujOZoPJ~Lz#^}jQ!s=%QWo`Ui?>1$A*AM?o z)mLl0^};6K>r*UH+RM@7+}x!buy7++@Tn^uXS?;i^2*sZ)jO+|N3_2hV$P5M+uL&nTSMRlWeRlW%1dTFgQ3a&{4+kchg{N2;j0HY+ zop^alhQUF>+;Inw!c4}K4{}+$pA}3@kYLa__s+DCQDlLTtBuy|^Dnl{5@KYq1_0S2 BFw_75 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/javascript.jpg b/workflow/public_html/images/dynamicForm/javascript.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d8bdec303fbf0b6c25d101589f61dcf4206ee8ed GIT binary patch literal 573 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JKw10w@7BLgyEVP$6n%BTr2Ffy|+F)^~jq?v$x239sf zAz^k!LlH40WyeO435*yfFfy?)17&1^_ArAG0x&W$3n~T*8GiVGi-8AdFOwj%AcH-_ z{i@fAGfFS;?P9#{;Q4xm!ZDk0JJrovpY|S0Ea>E_wEL-)8z5bkC^pfqRyBKPR{LGa ztcoX@5zBnP%lNP6j=5b^l)HSfr9qTq<@VzfUG4VZh zCnxPMnk@Eu@{_&myxCpD?yRf3$CT8-;*j!b^)8Vwdjf59t8Nxejy&XU^(xcurui`o z+4~Z8AD*o1n20T literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/javascript_on.jpg b/workflow/public_html/images/dynamicForm/javascript_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..40ca43264265dfae3cf5a6f46bbfed1b287774ad GIT binary patch literal 970 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL50|OH?BLfm(W@TVvX8}qX3otM-GBYu;a1^#2wE572Q;g3N*p_6&Dl ztkjs*$8^Ch;@FZ&-E$s$ec%3G^=ZRahrlZz*Y<2^YMgM#WO11le_HpG_+^{RC*P0S zIcxjo#SKq`H(sbViC6k-YJKwk+L*I`=lYnZD%=q~EStnJF|cYw!2-rP^WA1|V?I?l zDa6xa>lYEFzl_?abyoJOR_W?!AG&)b@ZpQ^ug{gu{o#9g5ucy-or}NI>V55+Z*7X} z(GMwGd-+o9sr8+i3F|VSCKx%nn?}pUy)}Njo$JOXFGsCH0s9SoTeOZi_fOub{x__D z+x9i#x8kl$JM~IJQh6Gu)-(mxzQiMICHp*W4CnmZy!7niwyP0^tTPoJ&gpop5NMqg zE6l2VJaW~&Wx}D_4DJPdb)T2}x5)jRw#xoQ?PMpjRRue2?bTX$t*M^%bjz&ixnW21 zcb=Qr7;KOiIRBjBWi_+oGk^HMZNA5SaGGG<)_s$e1+iX0Aq$ zvUoS~)uOWt&KIs&y7Qgy;cK>D9?Lg~|M6oj5R{yHD=6hqpF2a*$^Du4lpY>yVw!N; zQ1JJcyYoIu7OS_0ZF`lgJxOHi`-kgeUT0=GY~xUTJ2$o~O2COOUV02Z!V! z)zZvE6H=4sFrNOiJlAISf{v-0#@Y%@6?qTCB2A)>F0kTkJl|`%@95R5i~ci6*x$S? zf2cQMTfpb}Dc5*ctSqQ1U37S7c4Dhi#3OB~R+hGN498zxWH-~+4h)>BR`N1r+1CWO z$k0El)_)E7BmM5W-^1jy-(JRi`}!l~)2jVfoj>I74&D**xpr5`+t(kKe&=qvdYLmd hG>rRj%L$2-b}GM0oGx9|QRgc6xmF&hZIu20CIFYPZczXL literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/link.gif b/workflow/public_html/images/dynamicForm/link.gif new file mode 100644 index 0000000000000000000000000000000000000000..54ce9c508ba98c70bb75129cb30d04d4b941e3a2 GIT binary patch literal 650 zcmZ?wbhEHblw=TRc*els9}u~8{o!eI*FIm&apcmoySo-twaxpnN94hS`|H-OdAuSb zGr#6UvB9Pd8}}bNv2Xw0mbk@y5Ap_tx&ccW2k4>Yh0#i_F^MD19Jv2k6B#`czu3F3TBT&D_{SUAP`sx;3oRACHQ8nKy;iNP8G0we)1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/link.jpg b/workflow/public_html/images/dynamicForm/link.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed5ed1b2a1084996a0d2b89a9659bb4acdc7d78a GIT binary patch literal 558 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|PSyGa~~MU}0lqVrB=*sR%GIF|shSFfqeqff5WX zf{H?{N`^+lfy$1FKvj~Aj0^}BV3j~+EUZ8&c|oAzj4a5;GcpMR>0ivpP(UiQk`pYYUc-r-)lF=JkG5Zd3&U6pC#)lvv7+iYkFQCwz~K^V5Tll z+L9G%4PoEzF7M`YH$5+KZ}}vV)SP^tb#B|;I(>S}|~$*=%r^WD9KOF|zoT_;us6)kP~4r*{{9 z>ai3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|O%qGXoM}1q!e+F|z|D4FnjN7@3(FnYme^3K*G~ z8CV2ag%kso42{@?MZ}aHg9|4vyc86YJn14(hZG|N6Eh z;TCt+N|q+hv#|a8H2T$pU-Mp;4y}H);0w-Dg%;?zU#1 z#Q2n@;CMxoN=UpJp9q8T1XlqxcXKf(;JJOqkg9^t?MiJt6qBiw3foMy~j>6Z9lrk>4$`MSEqPpSeWyj z69*o)?|$wrF-3pL#)314Hy%#9$sh0AlIK*qvgNwh0l^#0^JgyS^YHyKWu5(rTB+uw zwWk#x{+p6^?sDl8-D{@yS$;=Wybo6VxckbYFQ4k7D_E{qMSBZ!ZZG4w^;qLzo1{!h z;^m295Bp3m#a++5(5m*D*F-Vo(U#p^uWq|t%2jP$I8nBHp}?&}d?{+qNBTA1@Xpg0 zF7`7mc6e1h>s+F=T@6P{Ze87%=-BSFcNhIqN8uTNN1uify| zyP8K+=(u3S6%7@$0yg_lfyu0`@AS-fn%{l1GB^9cwpluVv-bZ8_$&QsofR9u`0bn3 z=kMQ{zBc?n1DE{bx=@IiU){ea_5oMa_Ra9tTD2i|hfibA3P!3%y_w14uN@;z$pf5-kW`gQO3Uwj9&oN}P}lZBC; zL4!dDWE99x3~UD-rWAPSNcEpsQgqVAa^8g%%nnPHc*VQQPOBzpa5X*DI8k(7xTQ=< zp<1Au)kea3=g=~x&6`UEBrjZ8 z>ck{=^eA%{2lHhOCe`cv6l6tY749<0zk2;fUh)0=yKF-2U%!3-E|l!f#`Nz$1LM1F MrwtD#DKJi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUVP#`tW(Ud{2rw`*Gc&R=alsTYF*36- zunG#X35zHiI*J-8nV1CzhlCYPyfkUrMxYK!Mh0e}&yh`IVrF3lS)>HCl!=jri5Vfw z$RxgEFqDhMr5s%DBO=NuD|*gz zefRs-FF(4MZ~l;e<>|chu20e~9;@)tvk2U|yKTp^;}YT}YFm7?mMfjFs=T`Eh2g!c UwHNMbA3Q9=kkr5v!2bUx0F;y0tpET3 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/list_box_on.jpg b/workflow/public_html/images/dynamicForm/list_box_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cd78c2184d1064fd93ef3af17665187536c46934 GIT binary patch literal 890 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL50|OH?BLfm(Wn*AsVFyYX2rw|RFfy{Tv9Lp>8JU<_ z1Q}S_goG6xMZ^q)CteaY3Jg**a|#VhoCee(#mK#!@CPf zM+-Z8mnq3sUOV_Rux4_~q*W(eN`=lVH11CFzxMkwlVJz%&28JBZhz4J?aD9XcZagB z&RxD@TAcp&lM{5;&%XOsvsn7Vk(Z3Q3k5C-iR{x<$op{V<1R-#S;MX)Jdg%nbbUv&o<>^+@X1W4}cn+|#s~oDy4+8Y?_aO~tR`gmd}3 zO<@afepJgT605FQCMy^9V`7D_cwA=dJM%>8SG+}j-@R>%r(gVP85Uw}e7E!O-7t%P zGUc^>XMcGgj<~J;XRrESWy$F2^EZDr$`4-h_Akq9v#H)8b1nVU3sZj__1L}m@Z_Xl z*8;nrE%usP%FguLwr-lhy!xvTN>pYR{k=T9TJak1hJQRWOb)!sJE_U@apk^@4fAJ; zJ}REGOrdFAlI~3D-@BIhJQavux!>FG+x$Oe_KWTAtUp&!d(Z!%{)u_-Q>62j<)*CA z-M`@F$+$(Q&#dLOdc@`7P^z^%I4=LX#Ij2zJ4;TTeeg#>YvFvp=9vBKG=kTj&C{Ew zzQEk#NXn_4K+dxL5+WW?R=;k&FymH|{E}tn`RtoS<6?RCEo0lIbnepG)F~#@ZfWK! zDoj|tK>OVx&xMIbMb&rj{f!Yjw&mv9%}M*KmjCqmrG0mvWgGwL(@ppG)t)L}RX^qY zqP;ig9AS1@SO<{8?YJXS3zryY>HX F0s!=lO@06X literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/password.gif b/workflow/public_html/images/dynamicForm/password.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b8b24820fb5ecc82254de4ae275c86accb37129 GIT binary patch literal 192 zcmZ?wbhEHblw=TR*v!CSY;64h|NqWutN$A_Bqb%5H%&1&w^+OPhL5k$^6eL5qGMcL zTth-a_FsI*00xRbSs2+Fco}p+Jdha-EV&y_damAU@%rrU{|Oq5DVg&a$`~A9@6#`c z>14dWZsLV+7x?xy=v!R4C}y7&@FMz+4(E~cTSc}BocC%i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUV`67v%$)g3HTCk*Cc89!)n={Vc&O@?UfYVImK8lGc`eR;V)_>6nS12^ z-6;P?iAi2_WhaXpPfILomo2)nbbri@t;hQLCQJVG+4X9UkW6uoTkcygFNrIq3?@sy z?rpqfxcw}rf7YY3;Y+O2O&|UYd}_13|M{NU_?G)m@0@Pg&t6+?`+VO0=R7BAp@2UliS5yH00UO#4%--!7J%N8U;DZdjt} zQKFNvGcO8Ks}-+1D$jej=wcHFMk-t*D*tzA%Xw@O#m6W_rL%E literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/password_on.jpg b/workflow/public_html/images/dynamicForm/password_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bd7d9267cbb826f8c564caa79b4088c3ec56d0e7 GIT binary patch literal 1034 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/radio_group.jpg b/workflow/public_html/images/dynamicForm/radio_group.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03837f6aaff8b29959e26719885c775d7581f6ba GIT binary patch literal 618 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL5(5Vc}j0_0C%D}|T!VZ*D6JTIsWM*b&VTMUEGBGo- z2(k((vMCt~E2}h$1Qr6-Nq`JMHi3bGk%@&FC?g}tzzj4ESq^9fi=dEU;Qw0;JU|I1 zL1sY)dxr1UvsdUYH1_)~kdS^-gq zd-0bSdP;NScd3WR_owVxd4B5lFnJfLw>QpTsamq&Znj_bZ%3INu@IGIo(%7L7bQ-8 z7k86SqQb(|Tx;p+kJJ0^1TB44)AI7JG*494%{z9YESW;T%dLZSe-~XB6gX~dt|-pT zP@q-%Q72$gjl1vOuJaS0tP@_}?z`V3^FoZP)&3H{b^GN`RtC@4&Rb*GVS0Px>=kd7 Sxi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXoM}W@TVuWMT)(84EBlF*30*v#@hQ+t@3Q3-{@FK`SMg}HkMn)t9nOK=w*cd>T83Qe5 zU}k0J2HF7uj6l913(!DA5ywC_VbP$(q{4{{4_-9dc*!ZbsOjPVTMRtRKobR-1sUua z-f4dGHH+kR4GCm@x@?(-#Iyu61}0DSE9S?FN|#;u*6xz_t1r|h>5}&})h34vc}*9$ z`9}0yaF)DqE5)sQ+N*m$eXCB@J{E}56!ydbA=!o-T853_ZY?bJ$5mPf~&c(`xE4#tJ=j+7LhUCOm=s@1jG z7k^tEOt>|3nPJq%I~MhdJeoVIHJ7jKD!IB&JUo7PfZnV8M-#O98`-(lissJrdT80V z`S+P6LU$KPUB6Ig5c4Y0G-v}$Im7*Xg`1wVyem3&{5${6MBi6C()js{#a0)2YJXb6 z;v*L7>sjPr^(f;;Z1w586K=LQZagHCsC3)3W7W=r%yqfDB-Z+DS+=^R>*W;v(>r*T zPlxp_eY3ISlIoXIt03K~yvs+NrBB^%iRNb9aPXGy7cEuhRz}Hb>{jv@4!28KHk?hX zoO0wy2CLCWHl52KbXi0N&#W)&Y;L@Kk@w2|qX}X1%r#-N^X9w?dEsiebKhr<&kfO5 z&GD&!k|p27?Aj84oBg-N&+xIuAXRZD_#a`{##=FeQ ydtZK(-M&9X|BNx`>SaQwR;>~Do%A5;$*+^24|A(dOwkj)w6*JVy11#~|C<1f&uBvc literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/reset.gif b/workflow/public_html/images/dynamicForm/reset.gif new file mode 100644 index 0000000000000000000000000000000000000000..c22ecc48d757623fd8fe279d87220ad681153736 GIT binary patch literal 383 zcmZ?wbhEHblw=TRxXQrb?%s9$_?<}$wxy(O`TzfadDE2Ymd$tXzFfQaMosPY<=ZcO z`t&_0cy?*o*^-jwbLSo^tJz%9uwmP_OFcc?ow^chEID`U!&e}Pb>ygL5EVaqa=6lVwPQ{&lx@cy&hE+(_S1LTsLpsz8-Mz{)2}BjttfS D-2aG4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/reset.jpg b/workflow/public_html/images/dynamicForm/reset.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a16da9be285a1a48921ee52ef21a75d55b79da4a GIT binary patch literal 544 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUW@2MxVF$`-3NSD-19=SWFlk06WjvoNv(rR0IOF)^|r+rh{r$jl-vVko5O z`2Q9I4>KdsJwSu)8Qx!xI&;v35eQk6dy1R4O@Dvm=1uA8Z-wG^YDG9Xd*)bp%spQc zcBd-3YjW+EV4Zz0Yt)O+?6GZCEU#L5-6_^7DE!u>7KxULmf?+o5s|aamLKi(wdwIFRownpP}^b oqkSU2yVFV}dCweq!g1%^&F`U}w@sZ)R;0R22w-IhkpF)Z066`OeEi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(Wng4tW?=`)=?O3}F)}l-v$4Yz0A(0h z1X3Jxipc+nYT79#@_Gb2nb$Ve8TVQkDyKsjTeogi~LSYU>M z%o1b~Qe+i11RCWSlsIwW!QiCAi(*ENlNKF*_~`#F1|DXhiGs|64E7A~zJ*QmO=rwd z)=3WXbUjxXS(9g%I`cr;hU8n77bhHOWovGDvwHX3_S>#6;-B*FS@wSW%yoNXE%~)# z&mDfd=!^cRWuIp6yO*{++|T(`LpDpn@rovukhn848Vu>`OS8AJoK;cTsPgRXFRs9T zhxN;5g>mmKuQtB3R;TyOwTbLIZxuASY}B5#*YB5KnNMC+X3D8eUMCi06_>P@ez?>v zv5Y}!?Wq;&FB7t3eqCJrNL%%K&fHy{f}!(I?bbZ$aqim_&10u;PMnbw8nN2yPUE`p z#JApsHy&*&RC*wH?_#Ll&aB_{OAko*dCs5t=XtqQ;;uzMGJl6P-}Aj^x8?ff&Uxl6 z6E`{N9+%GTv;GmT!?bG4sznD={%x`QlF}0y*tb2t*v&?c`>d=;QNPN>W%ta54ET&M zd|tzH^Wm{Qoj*74-J|EXKQ45EgPdsap+if4NzQUh2J@}U8;Pq{Vma@xxHI19`UQ0 zc|zjR+n>vJOAB6JGbvgx{o(N@jc@BJR_wA_eeCqRY#*!B)jXO)#|0yU*=2=4ddS2azf&y&B@n31~Xh6i`H}BYoC_%?AiYRHvxVGOXC0l literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/save.gif b/workflow/public_html/images/dynamicForm/save.gif new file mode 100644 index 0000000000000000000000000000000000000000..84f7ae368c5deb7b0f4d5805b4aa9e74d0978c42 GIT binary patch literal 998 zcmb_b&r8&C5FJ5DiNLV%vO?PrLfN1kgd_+-Dl?OyRTR2JG~j}C=@1@jMaWa=rCX-g8JIRvGLicVf6x_C%D#PsI#H#D$(cXnppy!Yn27cQPZ-FZDnIohF! za{83hql~N^QLR=TzdLz);E8Vt{PzEXiG)arEH)uyCKh5PHe!#WFo}>TiII5pDw7JS zk{YSUs49mD!j*)*=&OQ5IwIV1c3vtFjua z2PyQLuqm6dIXGgJUD%b~*s&F?0S3}w30kOOF|Yv*EDU=HiX5RLCgPzFYmupnny80d zut3pN%)}h(K?=R%DsJMC2R}d))35{jK>`ZF8ekv|mS_bJECx29f#u;`l#wG$)x${W z!&+o!Y7So^7c5XzH+A?3r(pnip&dp;Ev$qepowYN0ZtGMg`?8_*sn zif)vVBODilk=$Sl2N;cL2g6w?XA=5&?lO-6_7$-5X$cEk~q!az!-<0gqm04Hd? z4!9D`gC?xX@7C54ty3Z1>iADk{R%BM-Z{1LWTyCGaI5pp{CsJ7aHMwR_TIV5;g0NE`=j2C z%D~o0;ECCl{@mqv QueZJ|TwOfd(nx3i0o2E}UjP6A literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/save.jpg b/workflow/public_html/images/dynamicForm/save.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e39ec054e3a62a2aa21706ccd6a13bf882d33df GIT binary patch literal 849 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<ECr+Na zbot8FYu9hwy!G(W<0ns_J%91?)yGetzkL1n{m0K=Ab&A3Fhjfr_ZgbM1cClyVqsxs zVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bamA37; z-p@b1VQ2ljBgem(&Y5Sq@q$ik?-ApZR(txS%=%f3H}m8bRLPXQ;w@icE`2oSpz4*~ zVoNhk|4h?V=3a5V_{hgioBFJp*jM~{b+=%j%+=tCAB`*Hb<*suZcLDuZjcLl@L=K< znc{o9SCuB7c>AQqwU}Y&)>&+-VIe6hrIHfslI|b;E_Un2)$4)VC%qL}hR zr$NNdocaI%%$YMlX|OJ^e!PU@PZmZ724MyrkSdU!46KJ9sPv^|&dXS}F6Z^Ci!Eoi zs9170?kRro-|pzb2Tl$u4i7#A)F@2e$Jlt|mh6Ikhnpf@V>WUgT43?>U&hwxyz*Oy ze5d8YJWO@fc$nXI@ahC+a4~cE)drQSvIw)VF*CWPc}B&kS#hv%u^LZwNK96@n!(8* zR?E&jMKzzjgoAZ8t1~MrbI^R9@=9Z?C@z-et|m>)8&_=Y(CX^xV-+x3u~Bc@jE#Z< j%UNe$n$ESDUs%w4v)<~G&Agjm>c4*T_T76OMFwjC0X%Wq literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/save_on.jpg b/workflow/public_html/images/dynamicForm/save_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..255d44f50e814dc7d9f4b43172d717b144a06d75 GIT binary patch literal 1009 zcmex=Hq-)3-T;9z58XJh4H zXJ_Z+|EI`$@KzRlhK~^C}Lq|5@z(jVX zLJ_0Ji3>TDoi-j64Z8S2#W<;`iIYoATtZSxRZU$(Q_IBE%-q7#%Gt%$&E3P(D>x)H zEIcAIDmf)JEj=SMtGJ}Jth}PKs=1}Lt-YhOYtrN?Q>RUzF>}_U#Y>hhTfSoDs!f}> zY~8kf$Ie}c4j(ys?D&b3r!HN-a`oEv8#iw~eDwIq(`V0LynOZX)8{W=zkUDl^B2fp zj10^WZ^3+bw#c%img_}Diq*5x9~ zKJjpI#s_C>gJaLx7asRpaD8^uf{$Ir&#KI}q+L~6c{4I6EBfxsaPvV~QuoTyHIPxn`&MD*Uvx`}3$t%*h4Jr($G;teX3( zue-0>k$ryA8;2bU)_mH3dOr63a{Hdw{Oipye3A)aDm4L5ylC%c3b{4yxraZ^Ev;M z`eQp^1|CiPx!5gJ?e@Pdx>uH)?3~#DFrUS|?d#01;#dA%No`%E`K@-wX|{9a@_zHa zE?%|bcZ7;uxc$nN{~5NuvwuFve&T-ysl}Dms%KWcTfujyaDMRnScxdprCr~yE-lZ0 Qy>M>S#BVhl-T&VN0L(>@GXMYp literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/separator.jpg b/workflow/public_html/images/dynamicForm/separator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cd13d95ec27bff22330440809913941d4963dc4b GIT binary patch literal 8763 zcmeHMc~nzZ8ow_uI}r_wTYEHu5Niz~iEODz5fJD!E{IE=(_-@S5+X?+CNF}tW2&{% z<;>~0x1P3EtEJ01bB^6yI&&PCirV8;v{t27i&X1U6{_F@<;{0r7QoumX6AJM%H_O! z@3-FX{@z`}`?!|Fy56YMsdVW^eYP-Uq~PU84?acgpeQwLV-vkmWoJ)0fb6YI4Vvj%AanIPg<}dnu8yk_55-{0Kw$>+z1;#s<~U`8V49p9cJ#sNrDGxi*XAl@Eg zEt;9h(&xe<{CWiH-VnHEq#*e*l_(Eg^SoKL_u$rDQ+7VpIZ`5RKA*ktz#G)+31{y- zV(1ygq1|!gXZ-b0BX{KLjb%4~{PK1^hlCY}^S|g)zccZ~rMupS4<4|0l{CA4>Q41v zE^qa0>-Y%7w#qu>@EViLhFMF_tiIhu*wh(!)~oQOtNq(M61 z?&yf==qaAkF&gJPB{z}1Q&zfpJVdc>3$rs*~ylh?frPM6b*KCEnDg>DK|ZCVHhWN zC=IduDa$GuPhGy#VGkiSFfjR&5F0EdR@!FvIa%n+7SbN}KI*eV?EdO87JC8XWITPq zRR;V|Dh><41WjSw7;72JR8RG>UOKceuuSfRh4c%q!oskypnk!Rfmd94uR6aUmDm{~ zg69+dSrS;dBrjE9Qt%2?7_87<83!syfbT^^;ZBTR^3hBFLg)YUk`LSmqwv~u<>DXalgup!`fuH&O7+gzSNhQlx z8?{=uH_eQHkf%|MOIvHM*6PyIwP-?KZMB)IqFI%NhEq0Ief_gtYL&y9tDc=^ zIo)1kZLXR(FhU=*wQ3cw!dB&~=a{CcSUB3M9IQ&8mYt^87!2c7Hjmjw*D#(cl`btq z4K6)ao3X5La?l}Ax$5A=YHDiIY7A+N$F9}o zV@}wtA0Cc5JRC5PT*VJn2-ER6s#yo)R+-_#WOLO%pTlZ2TWxwWab@5dsk@M^{%Au80tbNIAN?qHsloKt#&X)fI&+A_O8*j;^jK zToEA1FTS*T&DwRZzP5hzmUkN7eeeB`Klyaq_8mL-eZIf(z`;Xb z9sl~o$y3eWpTF?K#Y>lOc68pledjJrA17*sq(~?fip3%qgsg-_tw<+EN%8s9C3

    QALESenn22SOz~`6b~tO>o3bsLQ(61MtM6_@@721y!-SvwsmF7VOQGvGhGet*@yh+ zj&E zwd?FB+fMs;a_I2oHviW8PXCF{s+(6^{*rg@SdZz+0Uc_<4ZTwx<|elqoDr$^9u#nrk#F$ z%fFlV-u|ZNkt3!le{0-wc*9jqYscA}{`&Q2uPokR-!Sc&sUvnYacJVP_pfx%Y^>mp zHb4AnUenaJasIpWI8^Nac0+5zSx3*Ryk&l(N7va=!L;-|e5og;vtq$_O_z@|o{q-) z@)PZg7r!Am-<@%>kV7e5%&m%-zvNKn#ADYdUhmoLmv(Web7a-ElWmJDe(d=BbyRn( K`=5U9)PDfKUN&j~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/submit.gif b/workflow/public_html/images/dynamicForm/submit.gif new file mode 100644 index 0000000000000000000000000000000000000000..75429c7a9704a63de3bfa18415356ab3b38cda38 GIT binary patch literal 388 zcmZ?wbhEHblw=TRxXQrb?%s9k^xcUQcUClP`2YWZNy+k0pT4i%d!wfIdP>Tc<=ZdZ zx%0B8XIoJ4?9#HcwViYJ?73RrG^MO&^PD*c-hcmIS-;iCXJT&Nf#~SvlNM~NZrQwg z_33TfE+|&Y;Yo12P-rCkD2K2PPJH z=t%XSSWjv z`(>i;isjOri=4T{ z88>d)yiq|xe616^C?C(h{Rj5(iI%#uOA2wEI(_DpkmS*0lKg^KuU+TA;Kk0)b?^Rz PI{}ZMJbmWx$Y2csiHMCI literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/submit.jpg b/workflow/public_html/images/dynamicForm/submit.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4906437a07d2246267e10fb264afc27ba187d04c GIT binary patch literal 552 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUVPa=yWdq7-2{14+GqEzUvcjYpnV1C` zSXhOG6%E+}*+oQ^3LTx2CSL-om0)CGW@Ln^1Jg{*EUZ8oIiPJoE084_nFN_xgoH&{ z760F2;9+J2ItOU3J;VNGTW2<9FwA05Yta6;`eQNQ0mJ1Rnv=dBJ-cfbpGGQ&W}#-} z={+aBeiugJ`(k-f6j>!7O2YE5Iq8ONe%mh8y7WkE9@B+l)p&(Yk(C$TX?EMUXW48wR=+Q;sq%s0xxw3zz9<)? z?3KGyY_&h-f1Uqs_Kx{o%4KI>7)j6Uyui3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|O%~BO?O>ure?*F|)C-110qZ7?^+@77lip0uWD- zfmM-BNZ3$BOvy2@aMC4q(V*avi5HzgrZF-wF$2AhFpULh95Wje$TVZ1wTw(m>}<@O zPV&Gv08Y##u$Y9U#y-LeV zZE?dE!D)soRTka*c3i*r_?gWXeAjrY&r2Ce2rM{}CwsNrdBLBIz1)8e-1f?sE;e1C z?#Db;uif#-#VYZiom-ZD+-@Aac{$^$hFq3{;}K0NA#oCB0StT3w^_YqH1_1w@wB@8 zpJBpMi7#9~Q>UgCpYM?@bB!?SYqt4na)@8T;NG8MK|Etw#`f^AD_wEuKxg{pa0ob7_*+m;5GnrJM^E_=dgVea@~@pP^= zp`L#tZ^)i;`*q&qv6N+Qk&#SAsP?vKyZbK#*xH_)zgP2qxsBP)z?v<8wH@B7eU#gB z^>XJtbC!v_9CXj!ew$bI=~x77XlAHu)5$*>wHYTRHZ7KUw{Kam`_#)ppPane>m1j&-7`JkZNFk;@ZK$R z+o1y+v*N>kzK*U`Z`D8g;_57?C+|P4_%roS@)!9s{@<7G>wmAGC7rmud-->#%~8p| zCWXRvN8hpT++F!_UE7hG(n;P~ukGIcp6I?by{r4-t98HiSFW2;Hf@_kkZPaO#uWh` z**CarBX*kT=pF5S=lgr_s_Rk@qIFi)X087n@Nf3rerY!T)yucW=hth+LWMdvB>dV{ v9rE`5Q|He-hq7L_Y+ALN_3ow^?wEO>Y6=c>wnT`BmdAau*(`2u`u`>XFUdzb literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/subtitle.gif b/workflow/public_html/images/dynamicForm/subtitle.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d78329e3b9b056953aaf9ac7c8e15650f92615a GIT binary patch literal 257 zcmZ?wbhEHblw=TRIKseSY;2rc(qLm}KWF9su&BhQo;gc5pN>n(wYITayZ3r!(*zIi zfUapPlCw%C&)>ZD*u%A3&-n&~7F4vP=T%x+IqkprjsY)F{K>+|&LGO515yRDlYzA^ zLA5U>b6&=(bvduY`WI{XeClIkdSm@@52x(<^2r}0m{|`MD8Er!96woH(;#2;*ayo4 zQrjC|zdksFgHia>nhRV)+7s?NHB<@YEIRQ{A&5aNRwG`R%g>renUTp_oj<`pkhzdS hK%JT0nL{W@l-q_^o0&ODg@0i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JKw0|PT7BLgyEV`pUo%BTx4Ffy|+urV_*LuDD6fP7Xq zK_Ov9B|}GcWh0TmMxa7*MxYVM1~4!H6#^yXfc7u}wIfL~G6^yZDGECViu}LDzyp*4 z@&y^}8TP%~IGM+%d~CJ zZWI?T*{tZ*Stq~2^Y7}I-2JEY__^LnDddN4$}ahuW??IJQ`~ar+G%=j$E?4f*tKWM zTA$;od2O?!b_8t?nYd(mo&Uls*HnA2{xY*%y*}-$!m}{{l+aHHtuCnUWdFH#TFDuE}+AW1& zZpyv-&#-t-i1WdFyQTBz%iqqgk Y(_UStWp_(ux$i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(WngAuV`l=&nFug2GBdF-v$AkQg$+f-lpF(tf+t>5HZl%LE^M5%aN|XgiHr=)49v(zvaqr-FfoH{GXdJn z$i&3T$2KkG338KWf8T!Q zqRd?j{;3RScsJcS!Zu-w`ZV524B|V#94%{@xuj*9%G}()ho&T7(0)2Cl-<&GZp4Yn zFGa4doOx+c+pM?)+RK&**EV;u%CA$hiqkNen9j25)b*cp{+L~EZp}2f7CbXB;#kls z$CIX7w)U1!zTKE~q*YI~q;`SI-_q#d{7b%h;P#=OrP(rGQ;z0+q%qe=Z@y* z{;s$+$@!gRSj3zBU;E8&ZI_(mxbWEe%?_7Uf6ZR$b>%Y8$^*B=)+*+$$eHq=!MV7@ zBYEP7=YrX878CT`9?q+uw*0+Pr={)MoAp+q%bPDvTEOvvasRWz^fxVcmWlR%l3#Rb zuGX$ieD8NI&yLIty|d=4uF;&9wBx+rrsb|xXsqoISh%TunObb6Ottqa=`c4l+h;TR z_Au&auUKW0$9m;ysDjs-pYvRcbWNicA1T~xzLD)z)SdFwOsQ=<&v)3S9IF4=a`JCl>8HSR$4t;3uqI(kQY-}!#83Ku=LL+rHH`@O+` zFWa-$+_=0T;m4l6+V|@IPT76c{;u(d@UuNHB<%F{z0LuJ>=p)86(77FG-ZXl@5BP# bqMDOm5A&!ACd7u`tiJH+Ow66@|8D{S9}$K( literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/suggest.gif b/workflow/public_html/images/dynamicForm/suggest.gif new file mode 100644 index 0000000000000000000000000000000000000000..149228c62e084512883ee72085750014da8fc665 GIT binary patch literal 1144 zcmeH`|5MX-9LL{-IaiFaWTpdzF@=cph+y5JP0yK<$e{UfoNPL97{_}cDsGS!7RA^PNx&w z&2BeIkpAW6WlRp)Jq$^b9*^fC6<#N2yp+#NvDiDaLi;J&N7FP=(+tC`Fd^saI<*>c ztU;6|F#8Asb2vZ*gMmOWv=$6N$Po?&!;xq>f+4yFID|2d0$_*{TNwJE|5_k3#N|AR z0PRFE{`~~vV+2p69UAT%*YT5ckKGzpTMAPPDlQ)yA*_PbKev8D7!G$eOJAzfESXix zEt;_Xtv^QJpW3TACQ`@-RQjwUZT8rh->L6BY>-MSWIREC{+H=Z>eg>xH)Zqk21}LJ zmS;*vbJc`JSDSF$aechmaR1NEv)*K^n)c5!ytP zYD>#ksc&$rd`IdU>F3|GDROeg^#kd*?!r8lABe3SvB2% z^tGJ%@l9EBb;^|yi+eKd;9}EfIc3CM*`Bla?rGyc6lLtHUd!yuXiyx9Q%ZljQ@g!Q p?tY|8+C5#HAQc=?@-q&cxLcP}&MNuhq8&v2j`j+}J`M-H_zxq+tiAvM literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/suggest.jpg b/workflow/public_html/images/dynamicForm/suggest.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6465cebf1e15cb677d19863ce5e9acc782d4e934 GIT binary patch literal 473 zcmex=fb=5CFfs`WDKZO-C^`PW#lQnJl}V6U zkinke(#KD7b4_OyzS#BYkl@ybIRearDXK^L?9l>#@Gx=@G#8 zRaHgGCiCM;Ek)1e8L4uKT!t}g>iZ9OPN>};@cU)u+rS+PVw3lpIjFt9%E#Y#Z_XC= bq95CQS7lvUv{Yx3?(awM@kE^}hVV z7!E-OE{4M_PPezqo=e=PHP8pHp^mssh`s>kHmk k@ZbBeV@|Dr#Je9gaR$3(1R5HfnrfBW+B-VCLi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JKw0|PT7BLgyEW@G07%4iBOFaZH0GZQ;ho{@=}g;kJ2 zNRdt0kUdaDR7u4tv2Y?#sU#!F5EN6GSr}QFfKn4J z5eb~Q@&7Fb9%e?Mlb8h=>=|Czep*!UfMxIemG?T<%?#W8O(#eM8^AN9ku!JQ}gQ8DMs^7)vV@k;#ZaOt6Fcj!$x(_?DMzIKUQAax9FSJ z#kTN_ur%JRGx;)AJs!V{7q44>nXN?bxzUF^`{3$`V~V;oBsSiF5v*4DeT!Qwd5rq5H(EKS{h&%Rg!RZWFeM zX_B@ptylWJmf&4KFWK!zSAT~nItlRTq!+(bMIfoYRVX$Dx`M~gi{r^n>XnWzJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/text_on.jpg b/workflow/public_html/images/dynamicForm/text_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0475cdc38d81491e830569ed04b1ec5912bd0d1c GIT binary patch literal 1001 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JLL0|O%qGXoM}V`gDxXJBLkN*V|-FflPQGqSLALKQGF zF|!CVunH-%u?riDhy?~0PQ0Y7;^-6ksXbYq8avOKo<4W}SWbGw_W+BJR*Mx5Bqkh4u~7ZX)&6$TzwUn-`GWo5ch8La zUY230m~H!@yg1@UWRBybunk%#CAxJ_Tj(s{Td}w3@XZgWf0U&zdBCB!Ft_ITx(s%o z)4T>ICoS$z+I6e{Kxo7*g~JUDGLx?_n{gvh?uXw#PsJz6Zv;M{WqdSC#eCg`Wv6du zn!C-JZ8up|c300dt&45pAB4hqv(DtpRP=Z}*m>}{;FVr>{j>u!isw9gT&L=1BlmEE zcEx19wu^7<7xb9jT{Z3b_Ru>k-fdgDv`pen*z_LlQ<@=GW>O4?wQ4%f?J@J&VY2hn zyH$@8kA$t-dB4o+;`g67Z!Ns><9GFGm7__|VpR7S9%5A~ko9`KppkQtSRYKOMW8 zcU;s{$NAe<^^MU-XEB>-ip&$4b7i@ygS1>#(Cdf;#SibS*!Q0yR6Bg~vKQA*v$yTq z!_GVHWlrgeMeg1?H(wp=f28ERT_wTZV#yPx9S5Jssh!^{@-J}Zuh!!i>gWFq@Ys@h zk}==9KX=J{x#ih^?D^>h`d`70;>h%Jj14e)6XWTw7zWKC{ zw(s6=UP(sk*;OwW929;R+M66DJRyjM-Qv7Y-wqu+cP|}&73c4+h0k4l7e327%X!6i z>24lPq2q!PS2R@23fSz!ws$5StnTj3@~tQd$$5QXnS|coto`p6{xrY3s)C3A^y5X} z_wP@gw>3}hmHgz|sClgH;WZ_}Kq2`ZdBSlsytP(sh_mo%?3w&y^4rUto^A(nuRV=g M_~@v#7XSbN literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/textarea.gif b/workflow/public_html/images/dynamicForm/textarea.gif new file mode 100644 index 0000000000000000000000000000000000000000..ae03823c77edbe28d4e7c33406ef77cba141d7ac GIT binary patch literal 1197 zcmbW0`A?e#7{_0MZ4D4bnTpW`H%T1V(1j^vN?-?U5gl_zXRJmi2CFIom?pjirUYrEmL|-uFRiIr{dXFjhx^Wmru72Yh~be)~L6zE3_+*~!v^ zLUbCC2CMNW7F53uRdJ~FGqrrrNB}c35WclV2toC%+Cf9?_<&M zBjFGvezTv+G2#w29-&#gdu4ki^8Ch6mp5zV|O`BMm;=wHjrjiNdUVJYR%VE=)^oMjRiAEs?kvU}1tA!_BHm$=l zZPZTbr@>JkS0)vYi+SR)A%hm0R>{=LN#&G80X|vqIcMFL8K=o*H`vUYTQ~k_ZMvCv zAm>1CHUy5>ThG&YmkYJ@EYm07Pe=^&$4VbH|J%5`e6m(Y#Oy9T+8$0FV+uU|02 zh2)aOIrqHRIXCO@dFjnG6~u#*+v{ z0{#IWtBKtUoCIYPGj^SLbdW#9R>;QX6OUvPk#v02Vt~zhl|iF`6;f|3ufyoH>Q*Cu zhk4p=QrnEMUJbT3-NN^@ceb@aa_Oww=5bl|8l_gP(7;n6WR8Gsr;xDd3+FT{&}}z{ z{N6Fa$S8l9NvA}@fq;L$y6Oj`MiKPSdEK^1aN$UC5whT8GwEF&Z9@ax<)zRAJPwpi zayfkuNyMbY#Q(Hf7YT(gU%re06`G7S`EXnN~MAzNGui$ zg+hTqz~k{~G#Zsk?ds}^+54}>|Fi8~Pk03YLO{+ozx@*cY6}qJKPVfn6kpwu+QBbf zA&V~u1-}vs^v+M4cZ&;$4;_7N;A}U@NGj&hm7U255i-|xXIw_UQso!sYO?Fj6}d5m ze1BXT`N-|6lBU{Ic+)Tmm|J*}5{9C^% z?cMGYQch+?KMs7pKmL2Fs;!XLKX|GTJ=K^QuUuANg5Nt-FF-Y*@#gv^WoPYobj62n ztI_-&7FHSV%Y%*2cH$4@lYgwwRTh_KW}PWIp0ozY?j*mToWG)@#P8bkSw1RV=iBvq zdT|ye`(QumctG`#Ue&gF!+oRwFAIPL!7qpv1pV1T#> VKV7*PhtD|ExcAQPiIQUA@IRk##gqU5 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/textarea.jpg b/workflow/public_html/images/dynamicForm/textarea.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a787d8935db0ca8306f9cc88d95fce22e938ce65 GIT binary patch literal 619 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL50|OH?BLgyEVPaF0E zS=od{6qSqug9|Szn>sp&6gN$tvUt-apbiN}24+T>Vu+DU%q$>l6oFPUvM>Sl!vWAR zK_Nq7MV3G%qr(5U7Y=5LveU)OGLnSWO0-}XHHK^wCt(dan9C@cd7kQ zGMs!#Vx4J8solv!DfWZ0|IU98cr-E2B{BEk#dz0r(SOsI#=H_fXv2G`CHIkNTG%U2 z{=IUi_V+t|dV5py&#HF@d%}F`U1n8o$>vi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JL510w?yGXoL;I+THl9VlfYz`(@B$i&3T!3~vWWMXC! zWME|z5*ATZx+E%Q=olCrGEv#cIjFF>dCKA?7lFE@K;|(rA{ofU!pO|Z#sHKv7Gz*# zW@2LFU}c5MGXVuy1cek?4FeMkCkl&*IwoyAcu`5&DQIC)p;`h%#m`D%JD8WXR3GFHI$w|ZR&Ym;h5`($$!J%KbpzV+mLs5c1}>u{OAYv z>uRieM1On#tY5Lu@7R;}N4<|z9`0S`d+IM+hEhtH$3utz3?7x?OnyD`?%REWgRY;d zD75&f{$B^w6#>ei6 zRVr1-p1xmScT4|stW>D`qoZLvJq%8~HvP^2^ybxx*^X*UgZI2Tv>~uzf>QE_Z&|&Z zYI^fap561%X1ihUtj%`C)op3!;&Mm%3OA$blf4On9LFOKg*V6CKYOjE@4Z05m*A?} z?gx4G>iyBRY5F@VH$`*5sq@gYe%)n%H? zThAMd{k^Fl@=UQ%T>Zg|l~U!)w|gfE$5pO8taA0X;^H#N6om&*{nPW>ow?0@b8bF2 z{}dSF_eT8W2QD``)!jUrLdOLou4t&36|mWT>+|L2oILs7yYKJ51(_~8o3knU=hgbV z&Y$wdnl~hTth1f+_4A$0=T`rFB|o`h>$`)^M}K^ad;NT;{Ej@~xEbDBt2V^Ns5u<- a{5tvVwN_Py0~YR~@1{>nH{ZSf|4jgT4?7Y7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/title.gif b/workflow/public_html/images/dynamicForm/title.gif new file mode 100644 index 0000000000000000000000000000000000000000..294f222e7fe3a17ad489b10be2145fd62dc9b48d GIT binary patch literal 97 zcmZ?wbhEHblw=TRn8?6jY;3%8$3+kCfc+QWDgI<(WM^Pz&|v@qkURsE(VYI3r{D4~ zp2L5mTJv62dREN?#Xe`tMGGXh98}?&#t_}%aQ(nsZ`FG@WgC_)`q<$k#l>I^0Nn&4 AegFUf literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/title.jpg b/workflow/public_html/images/dynamicForm/title.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fe4da1cd1aeb02f26cfd0a756416bf58466e609a GIT binary patch literal 579 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUWn^b!VFSwP3NSDL9nQqU4wGhNVrF4r z6%=9<77;aMR}@oLaWpbE2`ij(38-8GDY8SEMM&9QLY#br^jFwjw`t6OJ5qlc4-RD-rP=3{y$9Rgbt^6k)6PNCh6 z*Ij!i%T2FYE^y+xi|V-?waZ)UGwaV4)<^qD>DwDj9g eKV`4oKJR|V?A!52ukDg`(d=Pla1fCHe-i*s5}_IZ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/title_on.jpg b/workflow/public_html/images/dynamicForm/title_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9645584414f11b3a0ff033ead184b73b7ee31c3 GIT binary patch literal 945 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXoM}WoKq#U}6KxnF=s4GO;o-aQHfctXk&MVjvN5qRFfy|PC5;7v zW->E#u`;tFn<>aDq$q4?n~3PbjY`U@LCHmn4*tKzzymamNsw8P!JeUV zOINVS7GGb*wwsv^uix(yn6gyU^~%v3JX>e3y#DExSIAl;29~#H#cria8hA)9 zh>!Vc@;9&d@5=ZP?@!Wl|1L^j`W^U|ednC^r?dWX{%25{zS8#B)hkE)^?I9^FkIo? zbmtMXhnMg+-boDNJ3qC(W_)UKQcGp_t)Co%b`4V>wh3llRJC zrP(8ch+Q55JM09XZ~nH-t1u<(Q%u;IhXIu{tIsqPi}ZK6U);jiG2`j9-41m#!kwo~ zbiTBy`aDxRS88Wi;(^U?LyyK8+%jvHiXK z@UHhY5vgtO-F&xOZ%p`h=)yDB@NE&3vu_;oIo)UIvpCzeI3$Q~duf#x+eE)DAF497 z82UG`=N~!zyhZMm*NT4+fB3L$4K6)+`maHnU$CZI=(Ah?mxR}9TAkTZarINep560v zZCZ*$-ud~=*C@43JYOs-nR2?AcXeV%O6u;J`!_u7cq}eALwlmj+Pkb_TmMC^Ji5(d z;q3L(vzKW4&0R2U&LvykOLPA-SiIC~{>s0zP5Q_8n$T$$AK(0N^}INJXRDrq^0FPT z4xGGq+|%W2$LqDZXBXOUZszDiMzYFuC{uy)m8g=dP}{$I8!qu35gmzNE>ZaF@{&AESHQ|#rZr&cP|6AI&3mN z5AP7>vRG^ZSCWBxZ5s`VYF-+d)@>?mCZUl22_*z;UVmmbH5w*3I3*iN1tT+)lqGcp zEiDBLNqZ5W5h0=ijvO2X9Gxl=2naE+7^Dj)Cj|pZE~~CF7`+0h7a0W}Nft99A|kyv zH@^cb2OSVeC&w5L*bXee9yvMENj5VAi3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLgyEVqs-tX9mh?2rw`)F)=bTu`xsC8JU<_ zSOpn`gcS_~MU<3{91{y07XnpEFfuT~)IgOoGcvINWfXyS0nK1Rl4WEPWL9Kh6>=;T z32gj-i-Ct3s9TU(kinkeo^Ev0+VYKwhg{|t*EcZOO!9AFUvF|QOY7bwW8ROET{|`I zF5;D$IM-_D`O2z~BQ}2t{Z+*6s+v4TAZ|N+cVn~H7^# z-Kg-|7Wd;l+rL>Ke^4~hSMFnx%cH1_&EjhwCan69zsgZ*=dA;NEp>aGdr$A$7Pn~c TRq=Bc3+4eM&w`i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OH?BO?O>u&^>QvoWv(<%|Rvm>8LvnAll4q0&Ge z3#%Z5kgy_~h?tULV4|pU@We}wK_SV7jguB$1nQAyWMBdsh%kz*e+nI5tXg8 z-PF%>Y1fU-ZI`ze@U%}<$dj06DNy*kd4b)ovVY&}7j2Tuax7qp1VudONGVjwc^Z?mRke@#@o6uCg8-iMRL4bw8Keto#w3H z7I-P_x?iYc-Xn3dIah*@MHb$3IxM*7fw#@(Cq|_&Om+qAGjKTF&%er3RpLlq&w>|s z@8&j`En8LNWx+0a*~eAnvfJA;JU!=kzUh_|?d8uqAd;6)awyJBr5>~8r)9&a{@wQ-=ul7;7uwn1f zW8c+&+X+NRebAleRl92a56_?8udd5FvsYh!n7@2~)4QwTe^mY~{hDpn#`k^sp>y;8 ran>Gs@aj3+Hp8BlvPY84lIm~O&--XPGcpE+|Tcvo=GmY+F!d3Uaz+;sS!P2=C5DLoS}PyGM?e^AA}`h))_%vkP_dNDM8 zR$F`LmMvR0o&Hr)T9LZpb;jY0mIW6N9Xb@3knrox^ZJIy!lL3IKYp}t{4}MfCuq{I zHG8j{$DK>+Iy!OU#9J9oOShaoeqeK1!^8y(7W{nvaM#JF_dnh5p0;ArvIp~T&fmLZ z<=VaXmM&dtpL(UXt|2Wgt*2+ol%6Tm5BvvG6-WQKx3|Ym|F!?(J8<|>L@54bVPt2> zWY7Vb0*Vs`_Wuo;P0cN>ZS5VMUEMvIRt_E$C$ZWvTgT6^)@e6RRPtP~&@;+HGdx__ z-p{yA$Rmz>IO$~Og2zsR%|eGXwkR%{C(6rb60uT(ExCtV!C+58M84}3(Jy*O4sbkSYU5yh zQ_ExdiAkU*;a~2-B>qJ%UE+NSHpc!74yb7Hn4LVt&~Dt@dgSb^na$UBsySuxEiIKq?0Q2iFi~s-t literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/yes_no.jpg b/workflow/public_html/images/dynamicForm/yes_no.jpg new file mode 100644 index 0000000000000000000000000000000000000000..983f0cf8cfae86954dc0dc107a3c6d688d8b181f GIT binary patch literal 668 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|OHiGXpYUVPs}vWe3V>2>|67nSnf3s5~PRvmgtD zkT9#FlA)uhk#S&RP)O3`i$Jv!j10_-jL60?Ftac+0cF&HwlOiVGP59TVPq0yRt!x1 zAZ+N!qEy(p@!-e*w-|Vs8G+7X7G$tzcvop@@HqM8MC&(giaYQ8W?c1DRWyI2%92Uj zZyem!$0apc$>LU{#v9Sr?ssclvi&B?i@e;wyZyKL-)jwrcI|2ll8lJj@Q%ZZ;oA92 zJbxY2Yo_OT3+)rGRGiAdabWVJMQawkiRxc_OSQ3R_i5jskKfFTFxTF*<^DYOWXlVC z_6Tb&={djUGjqPwk-8}tnQvN0Y^XK4F0B=`u*0f9s$rw&LhGjHy+tZNS-I{{xcXE1 z`u&(M6ZbmSL{u0qYWrTOwCuh2Ep1;h)hkNpD)Z&*U?(dO> zi_Jdm`uQj0`=jlb&-3b+#y*{%dvA5le+Iw1tIrzF;(W4QRZ@1_+eZOY*!*lm8aqF} z|1P!grdGx-{x+sNKP)G4#V%A$Ssa&gFZu3#|LxCXuI&6{wPRwNYK(_i{wn1_)!Ejo X_t)3`N?7#jT0>X^*9FEXhW|GKipSY6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynamicForm/yes_no_on.jpg b/workflow/public_html/images/dynamicForm/yes_no_on.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f322a9e1fce2a890a4412bc68bb1299d6d314f3 GIT binary patch literal 955 zcmex=i3*BJ!6k`h{6D}T z$iX1PAj8Zk$iO7X$SlbC{|JK=0|O%~BLfm(Wng4tW?=`)=?O3}F#$QO9L!J^K#m{_ zgAl8*BAbYkVUU=yV_ zG>m~okX1-A(9kh4sgO-rL^LRP;l_(%N=C^OA2v;1bnwxKkNagmaY|MvP%og4aG{T{y#>uOfnbPH9ETwPWTUP+f(dFL12Rxj&) zAv7t+O-v_htKeG2pGUct>~Me7H(lza!QJPZ>-N~6iJJQJ{p??h^^A8vWU_emxM#&V z3rArWiK5q;o2tHCopq=*J2U*GicU`jN2JXJG0jC2UiNJA?bn%n=0?{_l^O0w+A^+a z8K~~j(mKWHy5i^EpJ$h6s2b~a$;gDyY+G|elx5ZT-41zgm&re?_^7b+rlF^{!|$Ll z{Vko2tcxQ0cg<6%QtcMwpVl||X_RD!^6bE67v~lk-aKuyGIT}vgU5Tqn2xISyyN2g zGSB~kM%bTe>vzi4%L=}oWxcf4eTnmG{tO46UvcjRHlJ)%-lX;I#;(_^&DGS79M-e+ z3cXs%%=OmnoeuBC-^Xqi7(ZzfJ0?`LdslJO3Go@Wf>kR28ES0~?C-j=Ty^p#ne`Rx zjro_{^~f|mQJH;n^RLo5TJ!SqbS~YVEWKEEccqtD!^z{TCKuYt?KfPutzeQfCm&1v zv8}G9bIbi!Fup5U&2_o|o?f$fd()kN(lZs7-VzF$l6}ng+1{Iq z98cXh+sE%=dL(d~zsz&*cSXx-IqzQA*1wzasgjd-XZb_D6@3yx%v(73%zC*?ImUMB z**1~R92B0^FxxV~nz>x6|ZS{yYwHf|!zxiwsgE&jLG{AXCo|8Re<^NNUjAHMW{ z`TC~yZCL%K_7C^BZ3YYVynKC=`A56JY^y|_RjUq`U5XG*`Q!QXWy_L95x!SmtW7A7 K(>68ye-i*Z$X;Ur literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/dynavars.png b/workflow/public_html/images/dynavars.png new file mode 100644 index 0000000000000000000000000000000000000000..6f9e2e5cec6e6c27d53a25322d7f871ba0d07390 GIT binary patch literal 6289 zcmV;C7;fi@P)Px#24YJ`L;#Qgq5!Zt*rx3O000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igM{ z5HkYvTqkn?02mQTL_t(&-pzVxa9r1w-gn=7{a)`Ix*OYT5alx0&ADTxHQ zf}{w5B+zI8{dz&~d%yd(n;!rnYP62acI8&#Pvi9Mv!C;wa|wP;XPz+$`I?+9)}(f; zNdQ0;MRa%hs3?b1BZN@=e|X5R@+HQYl*-rSwL?Nr`<=gh?H&E?eCwr#j~>j?Eq1IoUABlK7KT>vrw>DFiEW)rWya~9=# zgTgB*|M5#-!at#*02J~u2KZ+w;Q0K!L|1BZtzM3IhkVaoon4TxzIPqV%PXi=%TmDS zl>tZ=V{4Za0x-~OwXOt1U36sgD24_Hl;xGo#Nc3`^5njU>2NgivCMsh0^$Ik*EBu8 zqGSoB6fIT5)r5kUN)tBV;4@D>4glXq0(2)8m zUO+TmBPk_=L~tn`-D%5w@b6L(ZBf7 zPviQEerP$F9AC}l?V6^+?RG(q4QgAqj-~FsXJ;al%l=?^co3nkh^QMT{T)#(Jn{Ix z@TP(OZ<`k4hG9l@!^GWpZbPF{$MlssOirFdI-Rj+bE~^!L$Mb#h1ErGJoepWGCB2W zN&s6kA7g8OpGvbP5CPbSLSFbdm!G=6usf3}9m=J%@#U4}XuH{xIF3i8C!+1xxjpsh z7avF%7XO3IBQZL*by#vqwr7fswp=V%iB2^n$~7sSE6E(ki)enTvk?Yrijzjl`Z~j7^f?Qq>SXO8BJ<*LEioONURqequbakg%(2 z2X==8L$N`+XV31bV9@`<*yso?)?1RQ(gWFiDON65qMD{lhG~K^2Ad#&5Du1UYVD4y z7^X=H0eGI59Co`bg(Y#v&h6j`aPHkxc>9eL5>;E{-}vTN4;AX=@7x}zzcmH0b;~D{ z%ZHC2e|>yme!;F$4K9}pJMY{f7E1DpB}bUK=xD-;RObCM+S@|*wos(9)b z$EE!0YJ6mDY-}NwLR^+pziCgnT><3MY$Ce4nmhF78>hw>7Z&Xr)nK>Vv1M#Cee!Gj zrniia{`FEiFQv2jKP#3i}&*MpW{hpN5&evT= zM|u2#dno`c0SiK%E|jV*NvzgMY@lBrkb4i*DwX)D*ItdzT|O6$#fP7-HPuA1**yB2 z4u=f|Ja_Dv^fy2GSzKAp#BW@`VOLcZf*@ei;3oR;!@oN{Ix_saX&O&eD%JkVy467l zoK6RVelNm)7c5J|LZTQ^srKzoz?C?6K0h(GZF8LynRxcKGyRJzX-U&Ga2!WOQAGbh zm)aBZOfrK{IJ};*t#|Eues=m?{NmYj!xzWLWv|;K2@sAj#wG!1zcB?c#-zVL@$UHB zOJ@%y78B8Cs|7*`g25mi-@R*k+t$smcQozMn+vHsi{+}_Fidb92T`;^;0Z2GU%~v1 zn<$q{psFSUEGCL#e{a7W^LpF~UoiN0`BG_rrBduyRh0mM)9GT7NFY%uY6oYhb|)VF zQXRQF?nsnMMY&QcNLOd(?7?to{LZoAL%OAXC+zhmehuzZwU%snYs!4`nLJ&9zf`Du` zhfC)#Ad}9Z*=)izO*kA5xZF;yR;w3Hi$#C(>T!9`p7F8CGv~sKiG-xF41AS7h*@9_W z9}z-Vg~O1pn~jUrCj6Mb2h(cGEDxaU4RSp!WM;euRz; z4(y*xr20$cnq(LT2uHvekXlLM%)6(NNoQaf1_&W=d%fD0En8EMKD>9aR4Tl}3(~VE zPMnOr`s&Z+Y&L^-s|Cgw2;t!MxV7F$I6V|w!vv>Jozn7Uq%~3yeJ+3Z&O3fEvUxNytZ$Mi?XWXvrf`005}Kxg=WP&dB5ZaM zqSH|*Rm!jSv$pr_!phc%_dmrAEv&@PUznB(t2qz?gu_ATx*@IROJ23px_081C&tva zDw(EZrp$0JzqQ`3UWqCp^%z~Mmw13rU%* zxvLfqdJDOHIoxiwBk{rLHwa_la=Cn~WN);5Yu2rzTq=KTTWFdl>a`jwYu}d`V=}Rb zB+SgsNX<$^)-_#XjDhEQ`29W%4)ltpdb3}p8rV9rYqwfBf9?Wu+1!Tkgb)M*0ql9; ze%S0z@yhkZSfyGAr5bAWCaTp6EYk!SgVt`KZs-Vfh2VC(#9Y1@FP17Gguv;vL+Y>2GsI&!N8 zXu7dZBW}>>x07Exm=xZS) ziUK9Diq%Rj!~n_bajDcWQ{7&V+GsQxIDtI&*dw5-3Qf~7pIF4XsdFFzdb=Zd>WN3; zcG%Z=Weh7y2LEN^e_%z)tkZi=|tb0ydrpZxgV*yo`3ceVh9Mk|d$GUq-Q10YG3`Yr+eH0GG=Jr^^jTTLl5Y z@is8V5Q_9d6vg#>2zZ`@B-snO?CQ(QOUq9ZK`pECxSMWIP z;gph<&YV7tPNxG=6v6R40)YVS?+Gb3o(E%)0V0Vu+XkOJ&(r?i9wi*~Q2>c;TSpS# z`44|cxkj^zPN%)WIAaVN)zIlsSQguum~>PXm2&9=)@SPo)8%$TH%wTT1;zlL=izkN z(e89$vGu_SA>eocZm%Ch!y~Xe92)>h6h%b)yTg9JXMeld2m=<~6qS{5cMs)w4h%qt zYKlOFiICr`cwBbYX}4jTCK!NbyMuQw&L}fCk_Q1CBm^nKVS{-FhHA5=+(@Pl>bm|7 zLddfKQiKpDKm#niUoQ>AM7>sruIms*8#s;w;W*T44d_(cus&l9rfEQwL^$kraOrJ3nKM&RJDrWYIgW$F>qo!b2T>F^J{N5qwF{&;y|5hWsH(&mmsm_JPTY0p z_JXSEY~2%STh|l-^q)c`(=<`8HSqR@IT!%$+7kOv8Z-?9)3Xbho?8Gf2$IE_^7oG) zR|JS6ILp{bRHkX5Ua!G4ja#k*r^61aX)rD80~Z>!jYv-q>~{M`v%&K`+%6|Hs$w~r zgsQ#|?Ri0fud54ohhxnv*4cp#_`_+12s%WVUj5`ryUi#f={92MiTG-H{Dz60*jq-{;1e$@3_c${z?VLEzEb*AG#Y zHs}RGfXC$uCvGP8=X2RmBod|%KQyk4jEtaMt;@+uRRRFJWRuQbx*}WpsHExohdiKG ztx1eoaZ^)~SX?HxS`C_}-^Q;c)vL9*VVbZ^ODPwNmkOnFT^Jr7LA%|+e5(n=Fkl)6 zn$;3?UE3&gZnqQB{vO!v5(rsqGBmXVff?}oJP?F6Ohq^XQL>@aZsYRw<@GYP9*33% zSSI@AKG^NjMuN303#<86>C*J2enGI&9e3`W5=HybV9*W1%mX(xO=gy*sqGH_&yW80 znd5%1{OA|<5>0y_8{OXI@H~g(Kl?|RrituoVIx{Poi?t|&5>ra3Cpq~?M`RErE8~z zUAyi>A)kS=yo^q}4Q3hWbZV$os|ZE9*E79H2M2l!fuKKJ$QL9-*FZZhFy26;(ST{1 z5Cj1n;h<{<-o0`jxmV$)TMTqcW!g#=2a3XSyiOj!my z!gu>7%jIUQRBg$IX-R~T#T#?;FSR@BGi5;h#hdSd>L&P)2no})P;0aR01l@EW^=7y z5k(1ugM(OCoWy{B2163|jBnQx33vM4lWz}KD;0?`pxtU=;pRO0Fh)x9Eul;#W?M>pivFU`8nKm&pikPe5f^=DkGQ@I59D}Y4AnMFyhrh z2Axg|*Djt$xm<$Ni2z1MIXmo7K>2V+7f^72eA3X@e?jKL{g+t9&TXs9`TC6{k8tM)uTJg@r)>t%_ z%4FipOH1fxdWB%nk9`mAhC{MJH+1Fn zBwsC8T-gNID=`LbS9BZeExG|_;9blpc{IsT&W*4EhKn}SA{NH3IG!T;OPe+q%%q( zF+3b06&D;1@7HHVzCh|_PKK&UGyWrhdkX3NAYKl))}@7_O3)k%qlyL%32(wT9U zY7#F9@cDfpHV0}QDiPX=N4kS@Utj1CeLi1!$M$V7bsfc01*XMdcR0}3+a2D%b>u0N zA*HnpQZTBAmQ%T1rD}tCJ)S8^6p!dWesYKqb$v7RiN~}o_Ccihfq^eIEiLh%{`i}- z>jmhx%@85XnM^9Z{XIt?d+ZBRxlkCd6*E$`m_cIpGJgIuI~ap~^XRa=ckkZBLk|t9 z$z*bJmM2GDF4v3IdLyn<4FrIa&PId5z=UYG(Mq);8ip=+1$-DC9$4(C24?0K86?UJ%&r!hc{WIy5w- zCK;RTt2U4P-s8V_*s}ET$v0nG*0cFU{Y$j=8H> zB!4g%fBcCj&@cDWNH{b_h;W4Y_+P8=pJ^{JM2MP9CMWGXHXrHo|G{Bm8RL_0zaiDi z1x&%7=PPohRws-BZnpyg zzfb9?+Jq?Blx(iV-ad2IPIc{N%d+AZ&YqQTT%Cq#Xb6XbT3>f4b@#TB1Yy=uUhkP4 z8X~`O;XiUSG&D4%GR7wTZu^mc|0n62 zKXErm){@SoAV^34-Jd*tI5sje{?;!~NJ}?oP_LG7<-$2BoyiQ(T)i5lR2vTW^wE|| z;Scx;zup$>nojch0;`nDs1^(2dzY`ugyTeJF^%Vi)P48eM<3dIuR=9UjE+VZdt^D^ zs@KD-$^0(r_kD%qqzT5@;)hn|gir>iI9;wtuq!BfeLnC!PZ?thF&Qm4n-Vh^njIBx zj|ai7AiO>wL{XFh9PkRk#AjNM-%o)L$0GHd%@DUy*e2UwsjIl|(AROs(-*d?0^~DEc@o24D z73+-#sVp1sRs|Q`q{Q-x64nS(17nV#W)A@$+zpf|K z|JLpE&3b^BEXz>9TeN0Wl><*dp??4P@sv^0pM^;zkIxMc-0veoP%3n}Q@2-v&-6rw zF=kf^h3NHUKBnsWvzgqg+-$apMm1O#gVW_eB-F*iT><6d^m{LyJAX+Dg+i>Sy9e>% z0c^kP4q7)_%0oj#6ktfVJ2Eq@11ssGtSDKj({4vqO_z9q$6&MU>Li?&+uL`!51M)6*aJE4>k7jFFQkmn7RXy$T^8TM5WV z3G-WdCB_&dw+}{c`^T;EIs2^l+!~79&c^$XDG2**l)?W8v`SnCM|d%W00000NkvXX Hu0mjfInMEJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/e-loader.gif b/workflow/public_html/images/e-loader.gif new file mode 100755 index 0000000000000000000000000000000000000000..901ad3f9ddcc8b576a0a73a498c9b22c7338d382 GIT binary patch literal 7322 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 xgK`h3Q%Ho5=+002ovPDHLkV1oYlE`0z1 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/e_Edit.png b/workflow/public_html/images/e_Edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c82d931527420129ab20acbf829d76ff09b4e6 GIT binary patch literal 3070 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 X;@o2Z_N|m>00000NkvXXu0mjf)*}BK literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/edit.gif b/workflow/public_html/images/edit.gif new file mode 100644 index 0000000000000000000000000000000000000000..8958354d487739a0533847c30aa057dc9bfeebe3 GIT binary patch literal 681 zcmZ?wbhEHblw=TRc*elMtQx)U_VeY3FS@U~EEd1`{L@$Kj$T;0VVhskoLl$q@4EM# z-?6ZB-Jy%uuJv7eW!kjn(dX}_n@^RjJ-q$WokI^_Zaj0H%ej5c-eamY+oGFRFTVPy z{pf8@gZTSz-d}zE{NwlUXU?2id-I7*K=Zb{&&;MB+W+KT`}T8vXYcBk&)vCq?}@W# zqb96fwr!tL^}?f1KO8uE^zxgJr>@_*`|J-Pep!?hQ$uiU)3_P{AN!;EY1zrXza{p`g{yZ7&3wBzvf9VcJD zd&fXup!k!8k)0umK?h_lC{7sI|2IT6HMg|3wRd!OvT1kqHK}n+_II%=1y634m7UVe z#cgiiB&)YnM8wC3H9*#(!!_8_E6Qo>Ry|c48%96nPBRZ%=}^C;$Bz4Vad@yW8tj%b zaZ^{9^68WH4fd87*t&DizCL-rU~>s8r=>d>1N!{+WSJSnRQz}C66tf$+v6`G6X0UJ z$Z^i1{M{Nh9zlmWd&~L~4oq+ie8euV`|D+}iI z<8|ZE*6wgl<-m{?8!jn0E>!msY2i4)tm2{0zHUjy!bQs!`Gr|h5(`|MSd^sacvu{` lqPa*xl*eOdK_UmYSj3W$j*FSccpUTCYRhI-YX~q{0|3iG7$X1x literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/edit.png b/workflow/public_html/images/edit.png new file mode 100755 index 0000000000000000000000000000000000000000..dc93dda279921e8f00621482ace209abb893873e GIT binary patch literal 1975 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/event_multiple.png b/workflow/public_html/images/event_multiple.png new file mode 100644 index 0000000000000000000000000000000000000000..298b8eacb60f25c94c4673a27ce99d2e484e947e GIT binary patch literal 1574 zcmV+>2HE+EP)P000^Y1^@s6LVfqm00001b5ch_0Itp) z=>Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01m_e01m_fl`9S#00007bV*G`2igQ0 z4kR2}A`~$I00pK=L_t(Y$6Z!QXcSEtebvh>ju~RcAd}Hc2F5_pNI)b35jEg)m4xWY z=p}fSfS`zoAf80#q#%kQLM|>CL{WkglnA0iyeb|dj))<%^-^8+{=-=HC)TCAtE#{E zt?&Cp7>00N7mnjV2mt_)Qo{Fr2qBOp38a*890w%fc^*h2j$>@tumM_Y2qB=9g5x-F zUDxi#ag2024KGO&q*5shU@iba6h-iTAK7dcN-4Om3$uLRN0KCPT^C7`KnMZXbrFW4 zRnRQY^E?26Qpz3}t9;*w<2YDYSiqY%Z&CN@00<88b68IDY)N zkWzMp{*K+L2WifgQcy}E2m+7UnG1wjC2#WB&YU4hL{S7O zC0eZ(q9_7M^!E1h>C>kmiAJN*0WmMNS`FK`ZzoBsf%#D>g`GQhvahd?aU5gMo;^Hr zzdoQZxaA#XJ<*$x|}3Rr4m1V`h+A&Iv^`6E6`eFWMqWjzJ0SnCW%Xz zE)f7!h4()+9pyQp58#h|IasVKo&!eZO$7YJrpj<9vVPOHj@7o{D zGDLdo)-CMayB9(TL{S8-HGJPkcXzi{+*w^+MWIkYsZ@fL5&$~E0x&T#foIR2SzuF? zK@eEVpP!${=;$Z_KnMXL1m3@YzmBodYPCQT)6>(udGn_26(-=r!^8af^C#C5s0rxn z*RNSFmuV8foNwEC?jZeS~2M&+{-aFo2^+k79g$ zoL|3w#imW0kjv$eBnf6`XE8oL4j}|utroJ`EavCuStt}RJUonMvx!_T2T`xr(bd%j z062X3Fo%YQaP8VPVJ_5aHO$S;Q7MIHvuXXTltNEW4~`u>Cc3)1EXDWq^zg}(Ct`GT z6hROmm&v6t z0ZA+_F2Zpf-nenY#vup-wA*bo8V$5sElY@oJX@_64jeeZLx&Do29{Ey*=+s~V(7p; zzkKKYskc_3PL9{rh*c+imps_oGlK;OyD6Ht0$zc%Fwa43WuXY%BMDAGY%uR~SE= z9`SFWjjPt)Hx`(8Q#XeGg~@ND$=dPAaU9#P&5RX>p&jZx&$9wEnanzcJkNua60Ymw YKY2GJ%$I|4TL1t607*qoM6N<$g4HR?;{X5v literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/events.gif b/workflow/public_html/images/events.gif new file mode 100644 index 0000000000000000000000000000000000000000..1a0cd8fe974ed0469e242597d06020ba012e59d3 GIT binary patch literal 1167 zcmZ?wbhEHblw^=#c+LO<|NsAg_wL=>w{M?4d-n9{(C>lAojP^$ge{MfN$hYug#zkmPUy?giU*|THEj;&j_ZrQSB^XAQ)Hf`Fl zVZ-|M>({MYw|4E?RjXF5Sg~T+vSo`FEn2v6;erJV=Fgu$Z{EDwvuDqoIkT^?ucxP{ zySux+y}hlit+lnarKP30xw)ySsj;!Kp`oF^zP`4$wx*`0y1Kfms;aE4tfZu*xVX5e zsHm{8FfT7JJ3BioD=RZIGb1A-At50?K0YokE;cqcCMG62Iyx#UDk35xG&D3MBqT5} z(BI$R&(F`>+uPIA)5F8V&CSil#l_j#+0oI_-rnBM&d%D}+RDnx($dn*%*@Eh$k5PG zUteEOPftrrOI=-ERaI44Sy@R*Nl{TzUS3{KPEJ-Do=x_LOXtOegchmHS0x4; z+}IB?D1Xop*yw)jh!o$`@E zVKci%h)p=>T#tlBGWypH416B;w#vpZ_-|x5kR2z@;C5u8VgRcWyXO%Jx6hB68ibhy zw?s~Iyuh=~@l~$C45zjS9oEb#EStInJe2sg{}gCgJn3Z+s5`Plp+nJ4%2Lc?0XrXi zP)WdKBJATc-~MrC3kGB7YRATcvKF)}(eI3O!9F)%RlwXN9z000McNliru z(+UO=0||Jrp?m-U010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00KZs zL_t(|+O?A3Yf@nt$G^wp(c_OcC0lHw6w|pa)|^&@Mbh%7!bYqg7eUZP7v1*{c$MrX zBFLMrON&j449pF(sK_zXh&J68aa!t_Tg~a&Nq6*gybuZ<8${o$hxdJ+&-csozQ8|< z*zV%uJ5y&%wS8ilUg)1r%sJcrpoXc|TS+3IZXK>47GI@$vD; zCX?x0KA)#QrxviBEnt2xgFdqYWs<|A(-A?Tl#}s9d}7)?{le{bpZ^OW2*RkvVj&ZW z1iqx^aFV@_^7joqfAtnV#|+dOH6fEqp;RjAY&JX6kYG#H($W&C*X!Z&co3V3;X^Er zA*}F9WPzdRC8Zwy- zrBX?J9X?r~BkM&t9KNqmDDtAiu+?gnQk1wpn#S1JSS=kS5=jmAOEkIZ_xrCk0BVXx zqwlNL>g{AQIUpu684Ly@5{c9j37JeLD7GB)`FwA7{0B9;T&_W<(-{x}JV}zHfj}UJ a|DoTZ!|(x+(@-%00000R0w$0N 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/file-archiver.png b/workflow/public_html/images/file-archiver.png new file mode 100644 index 0000000000000000000000000000000000000000..81700b8e2787301e08ea61d844807d28b514f479 GIT binary patch literal 1718 zcmV;n21)seP)}NZ6oMkeZMbmb=7b>WP5G@A~n}AB? z!i5S15(lIrgg^o=95?_1j=+Hff&-g4(DuXyE`Xq{LPa2z&MqzN4W zcX7e@Kwyuq>o-Eh%EZlf4~#LGrVdlrKxHn;!6-u%h36w0{UY;k0DO1<(;ppMBH*`A zp4*wp*-vC_`<_h3-l1uli7SX+KSU5xKm+nwD| zFc3<>xmrMca}ryMO^l6Z5mAQIbpv6$5|bsa6mm99!(OuP%JLNXaMgxAf_!lTy-pp~ z%3SKZ6i8&r2q-kKRza2Agl;c@L3B*mZETnt!Npn&$Io0+#EP7%^;UVB+$l|?y#7`Y z%fZD{f1z>VB-qdrDF>zsj5&H}o;&tCHs5>)!s=nUwsy>ftx&2F3Y*4q@HaU0A3emAzp@#PbGF z9?4>Y^btfBg8UAgJ@PH4Ckv|T^2VJ2G0~hqhUSSs(oMHwlPUpRs^Od?V-gf?ihqy( zj!n~(h@yVtLINTZ>n(%8@aJ&Twskl&-@=w1cgMd+tuiC4KAZ0N6_+gIiw$c>Q9bh)yyk_Jy~^rUFU`vW1P5aR zaR`YuB^{X!JF#u+4fy$|9}sjdNoQm=GzJz?FfKrsTCVbCcf%x4xY7dn;w~rDm5xrk zh3QS>s4moC#6L*Ah=d>l8Z%b3e3(4l8v}AJCBO%Z1Yii&_3fa6cB=ue+eA*IgX77d zMonYjTwJN;id==-2NDN3l5-OYXrO_I*_k8Bt#xdisRkv<`(m$X2-6NMU-e4lX$O2? zfYGE%1;@~kA(~7BHAf@_zq~I%Bj9|+j#r|F$%h?Cs^>%N-0xik$*u(pLa=On1j+@C z0X#`!0fmtltO<`MOM zq6BaW%4wV_2Xu>o`W(f41}uo@go3IlP^-7mZC97O_?NuT8@KdqsjQ5`3V}-o-MzN54q0-={Tb#sXrjZbmAs9w1pb4*2 zR}Kt6xb%al9R}Ky^Rw1h9~?d$UD5x7*QFbywLPZKs_zyG*?pEy3}Q-BZCHefYO{r2 zyS|iM2!xcezRy3cE%?vA_x15mD56ya3=6^OdoA1XJ}eiqk6V^S^mrKz38KT40v760 zfY(&lDCJyq`{67C_7J|9JD0Zmss*HlbWhyklwISq(SrN1ow12&8ZZn4mud}!emA+L z`+n5vh5VW7Z1!NG zh3tLY{PL@OOPx5Hlz7B4eOW4M`41hIo1e7#Qm$ zB&f9J_V!($tK;oCIQ#o}?d>T0`)!t_;nc5ru)FHewutjcNcHtl$p8S!x>NI3P38aq zUUJmBrF!#PT9l#P?(ReFLPFR80Hd$vS8UWRNWPJu-?qQ(>C<7Js_4pNny+2sd`ao z&-3wbA^8LV00000EC2ui01yBR000J%z!hgm5*Uv(+Gfc)IVprF;qeFrJf2N+F-kom zzZm0UvDiGK=BS~IR4S7k*=Ep)NEEgt(hHze19UAGB0dy45+)22C@wcF1}zF9B0LL; z1uz{hI0!P52@V)93nm2x7aa(z5DEzi1{gadr!@mC85s}|uL&&}C2SuB3}XWzAP$kg RI|t4OGtmIk7}eE506T1-p$-55 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ae.gif b/workflow/public_html/images/flags/ae.gif new file mode 100755 index 0000000000000000000000000000000000000000..78d15b67dcba8937b13dd3a4514037af411e38b0 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h{#{)FXaLsM)&N)l07n4){QUF)02US&L_|bQwM{!a zJ1#CRQnykxG&K7~MF4vM{#jZ7dwc$OclrPT?f?J)bO8HGNevAR^78Wg`}@(+(fm(O z`aM1TR8;{7Oq@ zz-9buYW-7FAt514OG{zCU`Vq_{&I8u008sz^ZNSw`1ttw`T6(v_w@Ai_4W1k_V)h( z00000A^8LV00000EC2ui01yBR000JtK%dZ8dps(YfO5bj_#zRHBt&hsWTg=!;f$OB z5N%?XN|`>NnbQOA6bhMJ4yWt!dV-n+(jmd+bap#Dc{DE@EOB#nJUccj8Z|T<77l=n zju<-{6E2k;i-I;77&aiC4jdc}3nDNu2L~4y3qJ-YCo3H&F$f3>3Jt8a2E`Nn2%x z*e)ma?d|GgUfMJ*;#5wpU2^H5pXC4me0OEedwMwl0Kvb2w=Fw?004up-P^%bgn)75 znVGe-Ym9$Uj(dB5Z#G7R%u$crhciH4k<0CYeBZx4Wny4moZreMBhqK1`Xu~6I^ zV1mz)AV^<}%Vie>(<}uCucDHiBm%+1HK+W={*92I(D{i^@+;so| zRIAVK01}EvipKwjichuW0048F%I#yL(PX{m{gRegoX&i(*{xWCU7*mff}Com)BpfG zGK0ndBboN*r#gkiP?gI^k;y)Z$NId%)XLm&snlkm&w;bs?}3Qrlb!#?%J_(o@AUcq zt+48#s{g94G=IbS+~ro4$6B7xk(<4+kg5PKqAh^LT86lYsLr0T(npcU-;|;E;+Dy5 ziPBVUA^8LV00000EC2ui01yBR000J#K*Hg0xf~k4PKUvSI1#bMNU%^vEEYpaqme*< zFN$NlLYXR>EJmUrkVX_r%T=2NScL*>rZ^OIJSh?A6Z8;wq83-~oAR!(A z2_69oHYXAoGZls*A`_+$AR8SPprQjIq#_RwHv_5`p`#5VA21vo2qCHlT3w&HAg?LB(9j#x(?I|`wXLLC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/al.gif b/workflow/public_html/images/flags/al.gif new file mode 100755 index 0000000000000000000000000000000000000000..c44fe0a0aec913b8667d8d4f97acb82bb5b33db5 GIT binary patch literal 370 zcmZ?wbhEHb6kyz3*}0WNQQnvVdvF@dpO9#693UzcW`aWZ|>R$Cbv9v>Zj zRafpT1H&yhiwBXux0xBPnW*0JvAA zyIK1a6Z5xF`pJP4pI&E-JAhTIwFxZ(2F);`!Bq4Wte13okgB~V^5PN-pf{h*p zAteG86(=ezEhsMpAT$_0Jer-Kp`)c3rxy$`FghC>92^n5A|eY59}El+!~wgvzV&T?|aJ3FiQL`3`h z`_}*fy1U{404(+O_3Z!vAt9Xr0Cq%0u~byK{7g*uFfjHiD)l5J`9D8TPqy~<_WMUi z;o;%v=jYws-QVBe<>lq$Dk%YNlCM|w%ym)?La`QHa4b+iq7-%^Y{1n`1ttC%gg%u`ttJf`T6<&{{Hdt z@&Et-A^8LV00000EC2ui01yBR000J!K%Y=}dKe#_4k*O=_#~nZLK!| literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ao.gif b/workflow/public_html/images/flags/ao.gif new file mode 100755 index 0000000000000000000000000000000000000000..8c854fa1084eb333de9df427f96983a28cf4e35c GIT binary patch literal 244 zcmZ?wbhEHb6ky+^Ctb=TzxAm zD>E~*kIgX~pw=%k)gc|Ao`~`SG%K%Jl$* z-r4N-Dzo>~)6@R`{sEio;qv?T_VyE}@Al(K)#>w#)Ax+l{F&PMqu%_G)%W`P`sMci z^YioH@%e+!^Z<D}-6A+PhVGu49(E0Y`USYuTe9rimz0Ujl`@h=fpTgCg+xq(Jb)Mb)3#0Az_4WMx z{PgtnA^8LV00000EC2ui01yBR000Jyz?WfY2pItY1_Py%s0^uSYCy%5cDc)H^#~0> z;6T7)IUHiNMCH+PZQi31q|-T(77G&2&ge>OT369R@m9Ep65 z8VE8n2!|XTKMgl9a&&fh6sf5-3_E6M39$sTGcySa3?*4x85I>Q9v%h53II$JJP*nu MA|D?L&>uknJCLTx^#A|> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/as.gif b/workflow/public_html/images/flags/as.gif new file mode 100755 index 0000000000000000000000000000000000000000..d776ec2711bcd6ff8f0451188b0d3c739c309e70 GIT binary patch literal 365 zcmV-z0h0blNk%w1VGsZd0M!5hRaEwDEp<;cvh zmg&=GczFE-1N~@c`kMd%Y#p=i+=i}ivibS>_Vx7WjD6^Ue7Tf#+fG92l$7$Pp!)If z0RZgw%*BU?{gY2F>dj8UqI{sBo&W%!m2%IZQ?T#W%Cmn}&{}ieU|-a1ec)YD`Q+Tb z004VpPuE2}qKtt60O91|;+lr(@aV!rLGuFu0DJ%fyH|#HRm|hs(;*@M@Z_)f@#z2n z`4JKSA^8LV00000EC2ui01yBR000Jxz};{7Yxs`H(XG|`1)fiX)Ii8&G#!|e!F4z! zs)6NTQe0eH21#YHXnGUH=@Sw;32hB)!k1s@2oM==8+?2b6bUi{bsRGi76TO>6cZFY z5eXqWB0dHV0691*D-|Xb3m_m7ody7}H8l_gFBlaG2{fG^9$j9qB`7Nc2c1V8$jC9v LF(WoN4?zGsMO>ji literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/at.gif b/workflow/public_html/images/flags/at.gif new file mode 100755 index 0000000000000000000000000000000000000000..87e1217365c869c8bf2fa6a35cd597108dbe47c5 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h`uh6#`1tGq0P_F<`ZYEEqN4V4a`#J1_V)JrL`3v6 zGxFNCd z0RI30A^8LV00000EC2ui01yBR000Jtz@PBvEBa2zfl?s&HJ+0Rj=?aEP&Ce=+0bZe zF&it9SP&GXEujEwK_IJ7NOm)nGM`5;mGba-F8}}m0T&lN4j_AefP#bwhKP!cfr9}E z4i_7UGdTqj5pi>McNiElDkmmoW+XZ;6%``07O7V>9a<6+6ch>y78W~715Cyb$SNv3 H%s~J<(#ocW literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/au.gif b/workflow/public_html/images/flags/au.gif new file mode 100755 index 0000000000000000000000000000000000000000..5269c6a0e0a2c5ff0554266d9fdb854c5e8c2807 GIT binary patch literal 378 zcmV-=0fqiYNk%w1VGsZd0M!5hthUorYNpAFmH;h|$9IETa;%q+vf+)8=jrf|D@Z|H zod5tb002@WL5j)H;s5{=<7sHLz0`J#yGmoCo2knH0%eb#!f1W6HBp!Grld`4sybGg zi*}uDfwPsQ#=67WMPHtAg}5+Hlu2TrK3SXAW@_hgZ|Ka?-NVdvJ!zq$!lkm%e~Gu{ z-R7UU+uf|Qvx1nUkgSJ)r?+v3=()aYMRnfc>)>y2ws2+)GW3#LM5@q^ivc z3EsHAA^8LV00000EC2ui01yBR000J;K!R+LNDNZ5ijpy6EEc<5>(xW)0Fuy!=U5dM zz5@;dG2Kc9&Ex{W1QrQe28YWWU;)a6gaLFGEGH@g0xmx>6dxZL77-B(H3kPCM3J(k+1vUs2B&Z?{ARY}Qx>_DQ Yq5-4|5jGYZx(rTFPY>D;4ckEgI~~rLTmS$7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/aw.gif b/workflow/public_html/images/flags/aw.gif new file mode 100755 index 0000000000000000000000000000000000000000..27fdb4d13906897b572573cf0364bb72d800054b GIT binary patch literal 365 zcmV-z0h0blNk%w1VGsZd0M!5hVy@I}wAfRm&H!$=eY@L?#Ns-Z#*@h7^4~=A+$(ao z+WhWz06LcW*Z@PD$p9&oS*g-$v)5g!(faFb`{`8xSE~8uOZMVC0DQavW3K>8n)&Ht z4Ti$^=34gSQsQoIPNB?(!QOVd+upGNg1_EXrq4;9%K%uj0CTkyip2m(sT+~W^x{gM z#NB4F)enlq06n7UiHUr_;Bd9rXs^>~vDg3~h5PDU27$ly-!xdL&>@k>Tc^(eGL-k@ zLtd-XA^8LV00000EC2ui01yBR000Jxz+GyU;&5;n3<@>KWGb0gD|V&_xBzzL_Kr{{KP*w!!KXxD{01P+XD|HEL{k zjt)FM4GT9E6c!df7Z*7Rs0bqiB$aC=m<|TB0ydo!6B`>H9UdMmEC|A@87C(dDk?BA L3_TCe&p`k?K;@jA literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ax.gif b/workflow/public_html/images/flags/ax.gif new file mode 100755 index 0000000000000000000000000000000000000000..0ceb6849f49d128216572e9fa7d9b6318090c31b GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5h?7K+=N~&j+%0+m&{TK{}s@VA2hVsK$H*K~jXt|NH z*!$9ZbezokXJve&((W`Y_FGi|B$ogHY}Rc6>$pGw08Ri6i#&3*p1k7uuoGU5$|z#4 z05+msio*PRbWwx8{gjVZg~j`IZy#d4OMbrm+m-ZEN$tT}^TuWQ#Bcb`Z1>`#>&s@^ z003f-#r)x&X_C?H(Rm(Qt;<;e^k`r3(rfm*VENB=?Mg!PNkdP8!|Aa!@k2cHz9{g% zPS1@1A^8LV00000EC2ui01yBR000J+z{F_SBV+;r4kr?^I1`xY3RF@Q3JwQDAdrkO zSA%E4fC)4q9Z4gBhDEontMefZI+EVYU|2L#DkujBJ^&Oa69gb0A`J}?5GFZ150yAA z86^uhDiAh8Z0J0uLubnGBOtx99ax8G$$0b#*@te literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/az.gif b/workflow/public_html/images/flags/az.gif new file mode 100755 index 0000000000000000000000000000000000000000..d771618498ded597d5d95979e455fa797e77c0cc GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5hG_KcFw{-xD#p8>NNwwNmx!VAJ0NiwR0Biu&Vqwip zOaM;+E~Zu5Yiu^ETmW~t(_38SmzV%D07tWGlK=qTdwV^wV#`ED^V-|$xVX?#Q2=DD zSH9tA!QLC9M*vu;a>n9b!Q*<$8VuqG3ax&5B2k|~b7DarE_DPRAqW#ad>9cw5)Cyk1OyBqhCC;V zAsIZ4kpK)Ih8>tVHVYdRF#s~32o@U=A*2fn9u=so3#}U!23?pSJP-}DtrkyEPzcHn J2M)?X06XGIopAsF literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bb.gif b/workflow/public_html/images/flags/bb.gif new file mode 100755 index 0000000000000000000000000000000000000000..b7d08e57e3686b1fcec0bf4668fd99ffa8bcedb2 GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5h001id$12hmiRI literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bd.gif b/workflow/public_html/images/flags/bd.gif new file mode 100755 index 0000000000000000000000000000000000000000..0fd27ecabe8d3014611684d8d81a1c6a8529fce3 GIT binary patch literal 361 zcmZ?wbhEHb6kyB6foGBf_Bm?D%#Qiu>wVkbDPVFy-ika1 zX9gfp{K*2M7<51c$WIJxZ4UD_jU#(5bnG@?xbvhkx3Yz_p}ajOznr?2L~$dpks%9PyRABpNuLt0 zm@x~7tUWs;4}+)%_iQmeRSsc=MIsFHY(l1Ubk+(BGcAg*v01u>ErV&V7pu>y)2AI7 FtO3oAcfkMv literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/be.gif b/workflow/public_html/images/flags/be.gif new file mode 100755 index 0000000000000000000000000000000000000000..ae09bfbe149911d7877616273c87935511426dbc GIT binary patch literal 359 zcmV-t0hsb-^(-t(N=ow_9P#e}`}=eD?6 z@&Eu-R8;%>M_5@|_xCUM_9{9$I{f@h_4Oo0MMeGT0QvJh-_Zc{?K$}JHsRv{)!_j4 zH#bjDPyPK-`S$?N+W`0XF!|^JKtDhG_F(+{W%TVI(cb{u-2kNk0Q2)e_Vz;Y@ih1G zFaQ7mA^8LV00000EC2ui01yBR000Jrz@JcfFqvks8E44}{2ovS0s(>8YJ;r6`Jhlf zn%Bs4Ikf_g7Fa+1{qEacm)!07%~Zffld)F1tmLtAR!3` z1{E!iku(k%l_WQr6#xo96D2evJ)sQ^6&o9-sB9V%5u0s6) z0RI30A^8LV00000EC2ui01yBR000Jqz@PBvD;5z*WFqlfI2VIKr2>KQL;wnNVXfZ4HdccqdBJh?EiD(F7ySJE-0a-*78Xf) z6z22hJghuTxlQu&@=LW#?(XjD_UiguTl{2X9HSg9sxA8Z`uF$uYLh+rQd8>c>iRuB za+*i>_V(W1-s}JXC88zuJ3I3L0ObGxVT&^JG&JM!<3O`O@eK`9xKaRw0015UE2S&o z002g_Mp(L7AfF)M?cXq`Ft^jU(dW_l0000&0QfXCJFq(7@8IA^8LV00000EC2ui01yBR000JsK%Y?PC_;`JO=CpZEXdlVD~0yZ`T z92^)JBqRf$3ZWz`H4^|EAvXmDIywmnC@2Ljr4kYu834K=AtfcNJR-s$#Ka@VEiF9D GK>#~f5SPFJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bh.gif b/workflow/public_html/images/flags/bh.gif new file mode 100755 index 0000000000000000000000000000000000000000..56aa72b2b645a4054500f28e6c2336aafc8ab784 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h_bn~@K|%RaQv3V+@-8m@0Ri?ZD)>7){p#xK>gx0$ zAoV3B@eK|4MMd{ZOY;B#@(>XHYH9U8KIQ-b_%=4`0092|{rpQy`$tFa0092b(EV<1 z_b@R0W@YprAM+U*_%t;7008+{SK?}vx}hKAh$0Q&m+{QUg#^78)v z{{R2~A^8LV00000EC2ui01yBR000Jzz@D&ID;Nu*&|{g&^nOqaA_v<$0=*^74@Y0EW_r?D_Tl*4*fbh-<`Z*OQ9fXJ`8Q z`T%4A_w4fHc6QubTh#;u$Lq@T#l>^Sa^>jUSiV?Nx>Lyj00372o7Cpiup3;{PE7apk*31SHeBncV- Utrs{bA<@wS)YLLEFgig1JGeZe&;S4c literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bj.gif b/workflow/public_html/images/flags/bj.gif new file mode 100755 index 0000000000000000000000000000000000000000..e676116f8ea589be623ced9474ae95d26b409ae1 GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5hRJK(0^&~s1I(o@^_e41WQ~>+?0A9UbvXB=jF2-~a&g z85!s20Q>t#_b)H?^*>0kM)vkZSh`kXzhXnJKwQ0Ca>jG^Ha7P=F#P;XPO?isuRq-Y z004;qA^8LV00000EC2ui01yBR000J!z@PBvC>oBLj7IbMI0n!Y^zleoArQvqH#po( z-rY+S8j(uc=htJRjmzi2%;h+lJSh)=Y%T=?F?2Y16)8Lf1UeED78V2u4GJk09ThS; zFeoZ3EfYDA3Y0w^Hkq596ALU2H61+yubP|_ARrhl5j6)K0K60w7Z(c)7#Kbc5fKH; O1qjXvEG$0LK>$1EJ(0`+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bm.gif b/workflow/public_html/images/flags/bm.gif new file mode 100755 index 0000000000000000000000000000000000000000..9feb87bc9e846584ff47884f0b08b21637a36896 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h%NG}sahT%O-_0y6<%NaQJ3M;2WAotO+PA@tO>&t4 z0P)({gu!msuDRZ0W6m)#=zMvq0081^YK{N^wg3RwN=fmkrF9`q+gn@JN=nc*HQsD& z*i}_+#O2mSMaB*e$6;;MKtQ>Jn$tx^&pJBGAt5v-P1Hg{-@(h7i;IzlvBP|hgBLyM z&(`L)*me*ge$*`cb~Pfy=?di3Y#kD$!}09k(( zJ%<1QA^8LV00000EC2ui01yBR000JzKv3Z3WA!c|ijop(Mocb21BYnAHVy}d!^tTC zGQvy((QQ1Zg61*EC@wAwfnce{(!2a&q@bZxA|gBu0cr;w9Sb27FDnTkAPF`zYYQeR z3nUX1GdUF=A!=+42BjLC5}%=K10^M-9}hni4xnlStt9{eAF;DqTR9mcX(VfGvrZ8T N%oENNKhZxy06PV_l#2iW literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bn.gif b/workflow/public_html/images/flags/bn.gif new file mode 100755 index 0000000000000000000000000000000000000000..b7b6b0f9199a96b4ef57eb4cac7413fe8a71793a GIT binary patch literal 373 zcmV-*0gC=dNk%w1VGsZd0M!5h*@ScBy8zjGWz@n?Mn*{IW$=0|4^4?A^E-v-e0KTa|+?tW#iFo|`==t;W?$|Hn z-uU+CRPy)t@7qi8-B9t*0QKfQiHC=(s;czoc(aE9QBhI&?M?OB0QK_MVPRqZ{{8>} z0RR90A^8LV00000EC2ui01yBR000J(K%Hr5su*RLOJf-b{C*G!V><10G8u!x`RjRA z48!Aq!7LVt3C-K%xD}|w;mjgUd>@`j!C9pMEiV!~F(eLnI5-3V03Zc_5)vU21tvBF z1epL76ape3A(I6a3@$kb11ACk6c(-oH43B%2N5$G9v%s5gG|6 TzDf;E0Ta;<4ih8SH$eb9y}PV* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bo.gif b/workflow/public_html/images/flags/bo.gif new file mode 100755 index 0000000000000000000000000000000000000000..4844f856924ae58edfb7fba44e7f5c448a2409cf GIT binary patch literal 359 zcmV-t0hs4vV(D)Xgb0J8x6j)oh?9PI!A>Dfc;*-7r+SMA+W=+{2y)j90jO;OfS+aCb+ zZ2+~@I#HDX`@xU-Yhm@MWcaUe{SE+6*-y~rdg<6v>DpD3#Q^l7S@h_CxYj>a*j4D* zPX84HA^8LV00000EC2ui01yBR000Jrz@P9(D-Mpwk#h8VI3JN{C=>`BuFOZ(dMJ2f zF@>TqYQZ?1nMNb~=yZbkhc)S3E)GY9H53#K02vt#up%M=2&W4R8yh_+f5#0kd62+7Jp F06Q~Io@M|5 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/br.gif b/workflow/public_html/images/flags/br.gif new file mode 100755 index 0000000000000000000000000000000000000000..8c8661626bae57026266d56824709a9283d8c7ff GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h*yZ@7)EQ*1WcKzcVzE>JD*$C`>Gbp+sM%CSoJIWn zQhU35Q=?NucKT?rY5e?309XJTgBo9}UjRe^CWu`v2kCd}8kT1>3rugqR`S3bi zgXwK^s&kt8u;D^CmlU4TF*&3(uH8eG%5(PeNv*7*{qs>jm_YUIMD*z&EnxTj{8|8G z00000A^8LV00000EC2ui01yBR000JzK%YxI2Q|##o}-XBqc_nX~imf zicKPi(J(H}D*|_FGz=@5CIvz-2nvM?01#zd0|OKZ7Z5dh4=oKZ93dtH2L~iS5FP{% z8z>nK6&yE_F&%{?3?MWt20T0lI{^_97(WvuAPEUG12#Gb6t58)vRzpWG%#ai8o)?P NOBc>R(9u6Z06T&Vj4=QJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bs.gif b/workflow/public_html/images/flags/bs.gif new file mode 100755 index 0000000000000000000000000000000000000000..c0a741e5ca69ebadee7774120d87675df8f6671f GIT binary patch literal 351 zcmV-l0igazNk%w1VGsZd0M!5hMwYHDg_-ri8!;Q+I)&W*gF7+nE;!qRZKOZCw|d!C*;+}}yn+fUcmx}HB1#?JuD%K#f2#Hvf&yg>cgPCviDJJ8U&oE3tS1(vB1E9iJ}{c4-fTIVo~<2!MAGgDgFLhzJ)0iw_wz xkbjbsiy1pHWd{cv8#N#x2P!{4BvmsX9v(bA6ciyL1UCgs1p&Uk1i`{V06Udwm5Ej<$3qzlIq*j_PPM<>g?U%;q-DH zHz@pY7YC=NAd&!=j7w<4FL0hGvELK*3i%RX*Bbn0QcQj_}5dq zmwf!+Nalz{@sUyQ6#(zM0PNRa-@8`meof^k6VUOkydMcq-6}VrsEW3M&=`)TtD{ zkw~S{$joSq1J_#!yF{6IX16(Ty6p%d*8_Z7HV|nXKMG+4A`cH5A0#9j8v`5|h6FA( z4;L2(5HAQJk{AL67Ca~h3=07oI1(WyCkX-y5DY0AHwzmGpCJw>KLR=w!~rk|0|O=| X4h}vlBO@^-B_JRi*e54G+(7_4r_HFM literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bv.gif b/workflow/public_html/images/flags/bv.gif new file mode 100755 index 0000000000000000000000000000000000000000..6202d1f3a2df4184878f5ed8bc23aa630d43c061 GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5h01vKZmEH98^zCF}`uh6sZENy;dei^_23FAb_xIv4 zFM6fq>gwv0xa;FBE9*^5?Ot5H007+=6wLqt>r_(O008MkL-O+Sq$r8H8S8KAKx4qwEzI+G%}a&g)Y3x25QbD!hlDJJ;%`1$$yu>b)6{{G_A^8LV00000EC2ui01yBR000J+K%cOO_*IUTgL1<384SHfuU06)29OoSwQzVEFmNnFct&>I;*X(EH(-}2Ut4`IvFn*G%YA0 W3NpY46Bhss8xhtKBqTiBK>$0|z?fYC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/bw.gif b/workflow/public_html/images/flags/bw.gif new file mode 100755 index 0000000000000000000000000000000000000000..986ab63c2764732ffd789269068ea5b033c3ace0 GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h0Ega4$@D@(LOaCqa&mL>^72YbN;5Mv0JHX7()euE z_k-U2W7PVV<^THn`u6tr0G;YpRaJ`N{r&y@`1tr`()K$$I{>coe&7CS*7_2|{`B

    v=j^b6%_x}F=0IBa4#s7NR`F`B`Pft%J z$^T%_^Z>W_Z`k~L-2TnY%?ZH$?d|PR&GwVz{*U7Ra@Y5B*!XkW{dU{^)z#IA-~0i+ z{Qv*}A^8LV00000EC2ui01yBR000Jwz*cIgnazBo(F<|8pir7d!)CkPB)!FAr6S=V zQ4A)w)4?(sMj~NSKnkb$WbUX_9{30EM~FmN1_A;W2L~J>Ap$>qe}RLAhanvniv)mz zgocP69S1)&6LofZ8wI8XGA|2hYbG@TumiFp00>)MISL9D6)qkgBD60}C?FsZ5FZ~U KB>>I$03T&+g{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/by.gif b/workflow/public_html/images/flags/by.gif new file mode 100755 index 0000000000000000000000000000000000000000..43ffcd4c7168eed43697af80901f59eb800c8d2e GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h^B5TYTU+S>093qGEvhXRp%(m0OZPA^^#B0Ij1oIEdc!h z0RI30A^8LV00000EC2ui01yBR000Jtz)u48^BIkZWKtmbxf~9RbTUaK0<@V#a5Iep z0SL*!xnx3z#r7u*kIUz@Vke-0Mi3R*j9w@d8Uj8aG?sYQ0`8CB=w=;M2%_}ui@050@}uG%YO>r938jh^H}W7}|?_-K3K zM1A#akM4Aj*@T_#<5Dho0|wkLR+Wj%A4LZh+xDUfJE%({`-8pwZ9f z{Ndf=;q&d~$@RWoci%R5=|6Golc2NI>C&_C&Srt-fT#OlgzToYz=W6VaHPjheDCQ1 z0Qmp_A^8LV00000EC2ui01yBR000J!z@KnP@c9VHqA^5jek3~#rqn@gHZc$d2LOlw zESpVnnI#fE!PYA}v>K7g;gPVUDH4&W!gwtlDlj}277uE90W2*A4kiT?2o@tVY8n9n zd<{A@5ezFM5R@U77Xb$~5iSb{2@nto0;3lk92W`(1`0B+uL1%c9Va;fHy$1_4;jiS OAV$tU1JTmcK>#~z$E7#` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ca.gif b/workflow/public_html/images/flags/ca.gif new file mode 100755 index 0000000000000000000000000000000000000000..457d9662d54d976cdd5b4f4d8e480831995d9af1 GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5h_3Z8L?(Xu0iRy=l@p^jcX>8{c8~XbC@H|54tgHR~ z{p{o9^^lbH_4V@d^4S0Y+eAs^MMu~qDBL$X>Rw;?qo?RyWA1ZyrT_rA008Uj>+XGl z$p8S=85!+vbKXr;=1x@WC@jm%%f!UQ?PX@=VP@_yIonlP;%sf|SXl8(Q|!II=^rQF zYHQTg)b-HQ_nxBe&dtBSzw`C=^ox+{QeE3CFX-Ld^p=?QnV#ZRTln|*=)l3>GB@Ep zK=kzVA^8LV00000EC2ui01yBR000J+KotTJ`WcN5N8rKam?{;VVhR8p4!gp|!$DLS zo9SV&nKc>_P{CQD5frZ&iNaese34Sd1QT2iS{?-@5Dq;)78xNq0v=;27Bvwq0X7pl z87w#(BnJQ}ARs3T0TMkQ83qg&6gv$72??Yc9X1~r4>TSr4L=Syv$PTrxB?pmy-ESg W8WRx2Ob;9`BGn_;G8ozzK>$0p52i2x literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/catalonia.gif b/workflow/public_html/images/flags/catalonia.gif new file mode 100755 index 0000000000000000000000000000000000000000..73df9a0498e644d740d4b977b750e7c2f81c6777 GIT binary patch literal 238 zcmV>2R(OZZtg{&-mI@-yij3G>G+^+_kur3&)* zRQT&N?ejb0wj1j3Dd+AZ_{=f;YDez$MDjlu?7$`U=P22&66m}k?^h%Ay9L;CJOA^8LV00000EC2ui01yBR000GRASa4Yd7M;wH4xyw+omXjATbR_ z?0n>Vg8^n>fW%@nfksm(I2?ssXFBx&2Z-zhVK{ug;Ll=Fsbn%03&zS0Vzt}ua>-~u oAAx)zv9`Li2or*W1{5_m40TQqczFpa6e|sr7L^tWmZ&#vi!oWTyicM>= zhmfsIOrUA~?N;j4Rj|#BG>=sgeLO*$Wh{(RN}X%~76AYBesQ#oRG(};m|-=NS^!f3 z07L*pms~xQRYsj?Ih9>zu7hB!eoUQS=FC1!n^Iq*gHNGvceRn>%}V3YQ{vNQ?9xyE z-B^6BU(voNRhBx+#7NJ{QUF~SLYHNzx=l@-V*pPXW1vrLt#M?oaMHv-+Q~uM%1;1Y z0{{R3A^8LV00000EC2ui01yBR000J%K%Y>!DRPd2jX+TGJuCy%<)To8M1@u1)Et-! z4FCZ1kz_!)38gZ#7z|;GLzP)TCJEQ?_GmS92P!fdH9QLmFg-~ZIRFP3EF&Ey2nhiJ z1V0-WClm}eDKQ>+moFMW9109&9UUY)mH`nF5U3#^XBr-Nmk}@#6R090Vx1o}X9PQG RKTAs$&=o(^Kho1d06YCiiGu(D literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cd.gif b/workflow/public_html/images/flags/cd.gif new file mode 100755 index 0000000000000000000000000000000000000000..1df717ae5cdacf3d7ea543831aaf2fdb0f94262a GIT binary patch literal 243 zcmV}Nk%w1VGsZd0K@0RL4d|2GYA-u}p90A|GB{{Rq6xZ3|^8TV$2-0BSTOZ tJ`>D_6ZdB5brBvA8-;Rze|2hu4{{fe7ZH+^gBA%3n3x5d9-W;b06Q}=W@i8Z literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cf.gif b/workflow/public_html/images/flags/cf.gif new file mode 100755 index 0000000000000000000000000000000000000000..35787ca489da892f75fb431d52e85ad726b85b3d GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h`b9-Fr!*Lr7?RSH`T1A%_4V}hIiuO501eXV>6HEb z{f4IZ3O(rdDk{6;F$7`+i^_{+i1YaP_?Wc%`8YY$)BsDmOGURuCY&a1$Zh20=d#-z z1~B0LYiod^_`|~h^71dM)(v`{_TJtA03+Vc&H(ZN001BW*#H3h`~AS?Tbi4q&y8{3Je{YcVx#GE#tooSGnC6XK%v(QD>^g>goG3n0|O9?HV+RO78VydITQ^T z7y_CBCy$bp0S%X$n#~#3Y`-G literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cg.gif b/workflow/public_html/images/flags/cg.gif new file mode 100755 index 0000000000000000000000000000000000000000..e0a62a51cafbd00551b5258b17284e542272d4d3 GIT binary patch literal 359 zcmV-t0hsg*-+&G0P{37UEWHq-x`d#!NAM+U*-~a$r+f?z%0s8ts^UDeL zvnuz?OHkNM%JOCP%@Oy}7yJ8Qtm|UG@JH=Q0Qas=P1OMRQ%3E-0QS8pX5D6<=tSKB z006@PA^8LV00000EC2ui01yBR000Jrz@Kn9C^BR*mWpEg1)d7UWio-yN|?%x-i_`v_xJf&S^aWy{$F4GWo7tRSoJ+U`$V)sTy`awef zdwTg;So~^g^&=zw{Qdb`TlOj{_b)I0d3pQ$`~G@*?EnDy`1tzz`uzO-`T6<%{r&v_ z0RI30A^8LV00000EC2ui01E&M000JQz@PBvEBY7&!0&LV-EJ8Ts8aZ~C=NldmkO8` zznY`7-33@Eg|DWK?QA-ptl_)$cJFv@g!4^yCvZGD5e5(pFBl?vG&3Fp1SKCNgApMx e4+#J&94-$1Sv6Q#~ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ci.gif b/workflow/public_html/images/flags/ci.gif new file mode 100755 index 0000000000000000000000000000000000000000..844120a52b2ace1595d581a03c564d71d3f14f0c GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5h`m8gwt)$}Rwl0QB_q($doZhX69oGW>l24Z{ucWdQrJMgIQ&Ce0=`%{KnKS^c`}_R-{Py=9HV>Qy5;rs^761T%qz?}T6ci0NGb$-49Dtb*84?W*9y1jc3JND8 O%n%R`H#Z&*K>$0Fexktu literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ck.gif b/workflow/public_html/images/flags/ck.gif new file mode 100755 index 0000000000000000000000000000000000000000..2edb73994c90da240f120ea7a3143da4fd1b0723 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5hixQZ�Ba-d*wp60o~!^6Yf z)83@4%IKArdyBAef1%iKb3RdjrBiL=Y-?zGr1<#wL{@{-8yPn@f!UCkyJvfopvUIJ z$^ZZWA^8LV00000EC2ui01yBR000JuKpslu@tis|!iT^lC=@zhtI;TsTrt6jVUws7 zxfdW%3j}1K2jyUJWPY9%1^~e9OqatA;@}v50|f~c6+I0lI1zjt3lu*c2@)0-4-6qQ zZHx#9EFUl_8EOZLeG3Q(5kH=xYY`fK2B#Ynssf^}rKb}c8me1eDy#>i5U)Q?PftI~ I%*;UmJAFx!?*IS* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cl.gif b/workflow/public_html/images/flags/cl.gif new file mode 100755 index 0000000000000000000000000000000000000000..cbc370e6ca757d338d851e78a257338c5088edff GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5hRHfwoZEXNt#rj)Y{A6Tir``HdQS$Qg>gwwG^78T% z6WQwbRFu-}008$yMC1Sf^*cNC008nXF7)l~g}mnO@9*&q4f_B9d$#5KMMd~DH1{tr z_9`m%Bqa17ANe{u`btXkGBWcS8Q%Z^=jZ48KR+|dD`anSRHa6wc(|D`gRGQiV zKd)P$+t=y#k;CU(nAH9K{@?BRcd_F4@bLKf`1SSm-2edm{QUOz_Wk|+`uh6&`}_I% z`S#~9+pog_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cm.gif b/workflow/public_html/images/flags/cm.gif new file mode 100755 index 0000000000000000000000000000000000000000..1fb102b295c86d04176b567ac795d92913dd23c8 GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h_AD&?YG?LHIOgU6^Ya||J2?0EN$l+aXu@dsc60gp zR{(|p_4OoEyHoo_MMZ!}X15^;I|>4pih*93Mh&*jH7OM41RiNO4Iv>JI2af>8Vm%10~a?T4;>i= z6EOf9j}$tQ2$eiJ1pojrA_No^Cn*;Q9Uve%rZA`!B_$jw8(ceVG$bT&JtrI-J{KD+ P%ry|t&nYQB)Ik6{8V!;B literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cn.gif b/workflow/public_html/images/flags/cn.gif new file mode 100755 index 0000000000000000000000000000000000000000..b052530978823707ba275dd861a188e55cc0f181 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hs{jD)lSsJ$0Ony~-8MD*C@0eNB6BFS@ zMa=*J+b=KPKtS3nE7mS9;ZRW6B_-onSmsz(_Rmq*ARy5V4c|&i>2Ge`MMc&hANt&Q z;Z9E4Iy&AuI^aS=)fpMW008J}YW2)Z`zbm)I8f18ZBYhGiKN`WYtZ3-}cTd005pyci#QlQT^Lg`Poy8aNCjBL@cn87O~(gocQU000aq zE(MW?BZ-TZB`6LOEgvrf12zf@7$PD(0|ui3v>+g*rl_g14!yk)z`zE>!$AN$75JQN literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cr.gif b/workflow/public_html/images/flags/cr.gif new file mode 100755 index 0000000000000000000000000000000000000000..0728dd6a498c4c3e2a69652e0476a60aafe60171 GIT binary patch literal 359 zcmV-t0hs42Jdg_UT4O>Pkug0516X`S5ac002{7e7D^g z7-xgL<~uv>q@;wL%<=N_f0xSk`T3Km)a_MO?yRf(%F5v-CF3hA004OLuC0xu(fP&1 z`~Cg)zP|Rny8r-X{Qmy+xwyFi0C$nbbdJMriNM|f0Q0uB^|!X)X=nMNq3cgi<>~3? zKtSE!-{2n~@rQ+ppw81lKlj4H>!6?d$jI})zWmhGdz8rG008;?{Q3X?^Rlt?^z`$z zv-|%3A^8LV00000EC2ui01yBR000Jrz<^MQDHcD-4+0U8I3*fQ%;A9GMx+vA2kQPf z9G%V(i3rXt)vZ#iZ8oz`#}hjFY^mH~GFcG@Eerqv7ZxuqA|`u&fP#dE3Ji${jDduO zFA53(A}}>{C_X$H6ci1oG!!xh90sliX97JBw6rc5R909eB?}7)zzGFNOT`EU$jQh- F06PNatDgV> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cs.gif b/workflow/public_html/images/flags/cs.gif new file mode 100755 index 0000000000000000000000000000000000000000..101db64939d70025b6a4712466a58640ff4023b7 GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5hb92T1{{HrJb6{Y-^A;8W0Eb*$yLx)b`uh6#`1tnr z_U6mWOiZzCY{7nh$ogAb`htS}=;-`pWJN`<002mXgUk6+Q}k?X`aM1Sii%THw(I}^ z_(VjCiqAAOru92J^8f$<0C@5)F7xyA@?~Y^00000Wb-sM@eK{&008^@`}Zy`kC4)& zq}umOOIcXC_%t;5008wNAvrm%^>}#re0(e{q4_B(Wo5wQ$H(;b_57fq_4W1L008{_ z{PgtnA^8LV00000EC2ui01yBR000Jwz=CjC2pL1BWU_E*9sqzw12-_dGz92g%kD>pJS1OzB3BBl}#4;B_K92_4XCnq8zJs`##$jBwj KDJebAK>#~H;F-+; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cu.gif b/workflow/public_html/images/flags/cu.gif new file mode 100755 index 0000000000000000000000000000000000000000..291255ca3f7621e4af8eec0a3239a7f75d22a6a9 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h`T6<%$jA9;XxiJ|_Jq?EnA(CY< z^Mktn01D^oEiL{1{bi~BYNytGv)%LPT>u#CPn-Fj#LM*b^z!oZ@kmH@vHX0t{$Zv0 z_xJYzDDRrW$MaHBY^?fdsrf&V_C}QTL6Gu?z5f6J;cKn_Pnz}XMn-6>{zR1b-T(kg zm-P30drFx2Zm<52y217DZ~XhZ06QEjsZsy{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cx.gif b/workflow/public_html/images/flags/cx.gif new file mode 100755 index 0000000000000000000000000000000000000000..a5b43089b01283eabb0e53b270e414575d24679b GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5hXV+)rR004|-W!KN{ zNC0jCCsdO~%|(se94IKpt*z%-a!RsRc0B{%_xkE$J z01Qw}%}f)z6QJZj005*@(oRo|A{h)Y9}6Tm7Z(8=IXf#Aehv;jf&nNIC>uCB zHYx*-9uf;62?P)j1qCfG4-7mWou8o_r4OFew3<>lq3*RJB@;{4ib^W~d`$By{bNBYx1_V)Ar{rvs$#re}e`qx+D<%^c7!WanIvNN(RvjoW z5F08akT^R6JXkUrFcA$A5j#3KI649bIW<}XAut}QI6^ox0AgcgkS(k;NlOj^1P28L L2m%5#&_Mt@EbY{X literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/cz.gif b/workflow/public_html/images/flags/cz.gif new file mode 100755 index 0000000000000000000000000000000000000000..0a605e581dee0f0d8500f0f0d67d7feb3f1d6f03 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5h$^Za_s@~NB0d}k9<{23PM6~kq^6u{Lz0&OJ>gwd> z<@B4I-QC^sl$7NY6Yq-RdeT z=_DlWG&JlxI_New+5iCPA0Kg@*yu7c>@P2RquY_Z>Wi=7@Q;t}OH0n(^6pSjm$>Bp z{r>ANF4x!BW1ZgbnVD^*;lkDL$Ay{x{{H*>`}p|y{QUg+`T6$t_Wk|+`uh6A008&* z_x1JlA^8LV00000EC2ui01yBR000JuK+EYzG#C%aL_)!|m{hfBYlp+xc)6R8VSx;0 zwH@`E_35_VzyLAEYIQ#ymle>+5ac)U_o}coB^fX@3kwYmC=U-Y0u>X1A{QPVBpVzd z1P&hn6(<>yla-g54kG{sC!ifJmY5D07!*AP0W=a4D=85X9v&Yf6tV?9ARq$A0szX& IJ-Tnb?>;`x008evN%!~n^<7=$LMcM0086-4e2E%>pnj6VPWhsG4xqk z?Kd~;D=YMBYV&4h@?Blw008hoLg*hK=NTFK`T6wp^yo4&{{H^%PEN=G0QL3t`{(EL zR8;Nl?dUZ%@mN^t&(G>PIqy3=`}_OyPfzgx0Ql_A^8LV00000EC2ui01yBR000J)K$~wk`LQOGN+ra6JbZ!Z0HqsvJ{b@UkZM2? zh|Mq8a)@ReO~=rf1j4PKqIOPqE{nosuxZtJ3Uz81BNzogC_g+rG&m(Y2L~%A5i1El zii{ACk&_V-CJ7ZD1`Y%zHyn2(BoY!QDit55GdnjL6s!^!77RTVSz9{-DGL}fFDDGX UOCb*pE-?)S)G8`HJt{!}JEF&=EC2ui literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/de.gif b/workflow/public_html/images/flags/de.gif new file mode 100755 index 0000000000000000000000000000000000000000..75728ddf21520698e46ede37ffb6ffe6797b2eda GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5h@Z4^tKQH`sb@}U;sC_TBwX3LxFY`x7nTvh(rdIZ{ zX_SeDRmk~Z$xI*esy^4v)C;Ck|#M6-%7SXfx=i6{ABV78<$X*oGRKRWhOQtvY}y1KFV zSy{b7F`I-h{MDq&xUcenaD!W0=FJ`I9v)^%Jm`WQ@8E5%t)rE4a)5z>`|+ZjoRH|x zB0oPbA^8LV00000EC2ui01yBR000Juz>Q<*Nd1n;q=UsQ6mn1oqt{z3e#_l%GHG~8 zq|GLU_}O9-iB9+V%pPzQs_d!=1Q?2`r8*oeD-bdPb$EJwet-~ygcW&veSd)vHG>2& z3JM9EA|f3fB_%fs0Vg~e85$ZOARZnZ96mHSFDC=H0};9*ya2uc7bC(W1Ox`hF9a9L I7Z*VQJGrf#Gynhq literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/dj.gif b/workflow/public_html/images/flags/dj.gif new file mode 100755 index 0000000000000000000000000000000000000000..212406d973881f3be2b8c1f4cc4bbed17bf29119 GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5hvFoud%q>TR{s5@}G|e*rmH>^h`X9+3l(+oH+5S}6 zRQ>$@iLLoMdHZFo#G1PLro;XGn3y@xIeet{jH&k|YV@ne{w>ih07~f+#S(<1_x$qm zMAJn1`uTmH^&`zAak9z{!wnf?@PVoKO4dn)tN5V5{29p^`uh9#_xJPn|6QiQzvI@8 z-;I^$mj1!P6J75BNr5eK_jKNL6v`Co_vw_h`PStA>hb+slm7rY=iT(({{H>|hXDKg z`~Uy{A^8LV00000EC2ui01yBR000J#z(h_!BsPw+N<{<{{Zt8y)B=H+Opgb`hWY(? zHxpuPFfdA^iJ{AD<1A$}dZNZG7O%|$m9SAL8X6uR6gqej5eq&jEFd5bkSicDiV+(= z9RMU37at!dG!g|qiat9t1OWjb2PYXB1U(&lngkcCtr;O90X-=-E(*dV92^o71gX6( P1I^6^(9k{8(?I|`axbfZ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/dk.gif b/workflow/public_html/images/flags/dk.gif new file mode 100755 index 0000000000000000000000000000000000000000..03e75bd297377de3d398b7c36a613ae283ca64e2 GIT binary patch literal 374 zcmV-+0g3)cNk%w1VGsZd0M!5h@KjXydV2Tk>-Tnb?>;`x008evN%!~n^<7=$LMcM0086-4e2E%>pnj6VPWhsG4xqk z?Kd~;D=YMBYV&4h@?Blw008hoLg*hK=NTFK`T6wp^yo4&{{H^%PEN=G0QL3t`{(EL zR8;Nl?dUZ%@mN^t&(G>PIqy3=`}_OyPfzgx0Ql_A^8LV00000EC2ui01yBR000J)K$~wk`LQOGN+ra6JbZ!Z0HqsvJ{b@UkZM2? zh|Mq8a)@ReO~=rf1j4PKqIOPqE{nosuxZtJ3Uz81BNzogC_g+rG&m(Y2L~%A5i1El zii{ACk&_V-CJ7ZD1`Y%zHyn2(BoY!QDit55GdnjL6s!^!77RTVSz9{-DGL}fFDDGX UOCb*pE-?)S)G8`HJt{!}JEF&=EC2ui literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/dm.gif b/workflow/public_html/images/flags/dm.gif new file mode 100755 index 0000000000000000000000000000000000000000..2f87f3ca6a52c118cdfe6bc0a6dbc623025db1a8 GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5h0BZng!fANOcuk|@^oCLV{QPvaE&x*iRLC-1x?DV} zJY&COmA5ucv`vA{f&J}j^z`(2cXIaSTlV2N04@MOtv~a0HZ`d=OG-l;8rvDgkm9|A-a-SpKT&M)l)gBIsMxJ{ow$M z%uC&3AK>~-_2NPAW-IDzF!Xak@og&eZ!urKUH){MK+`4=x$Z$a8m$@ z00000A^8LV00000EC2ui01yBR000J!K%Y>k(X4(2fD&*x_#9A&KyZr`0t;IL=X3_N0|+uPBp@IdNClP! zB@7l52nHh%pc@(jI1LRs9t<=FE+{4$3KSXvre`5FBqOdFuoM7T3keA#5*QF?3MwkT ON=;3M8x+#hK>#~#;)-ej literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/do.gif b/workflow/public_html/images/flags/do.gif new file mode 100755 index 0000000000000000000000000000000000000000..f7d0bad39e027d93dfedfed5b001b2f32ff31205 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5hQ*62Y{r&1hL|}Np=Q=v}`22Z}&g@-X00372A)xo| z>*6FN=QcIe005Mv*vtR`=RQ8}^Y)FN)mwADIaaUaEG+u=_4M`i`SkPYQc~+ySNi(; z`1ttt_V(KV0C9)Q=SoWLVPU-h0K@q<#=ip))CxkzKSY=X$< zL_~g)(AnST003d>)zR>8Z~XW7^YioV^ZoB?YU)o_;9x^v5Wds;H z04ggcClfFpHk1%@3K5!|6g&tXC6x>nr9G$=00<3N8X7ksr2`WaJOH&zOd}&PFEGjo I%m_gMJNYW5asU7T literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/dz.gif b/workflow/public_html/images/flags/dz.gif new file mode 100755 index 0000000000000000000000000000000000000000..ed580a7cec832efa9c9aa4900ddfef45d938e132 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5h+S=Oe?CkdT_Kmuu<#K4(d2Vc{iBy$ylfS9*)z#Zr zP|?xR;o{=wj)z;Dd-Cn=`TF_*Tqpob5aC-;jhKPlQ%7Q zXrzXIvX}y9HFT?xhPIz!o`89-ly9hv^Yin@$;i&m&eqn}A$d)7dtl~!bnUsgMUH7q zk#6YE%<9?K^~=la^zu%kfVpj8RGfPC@bGl1kIrskW}19HgERA^8LV00000EC2ui01yBR000J$K$LEn@kBffjgr9t05XW^U;qL^u2=y;hv3lSh3Ar3bR z2QDf#BxXJ)5gnBWDGC(?Fc?0KK06X34hJnPIVmfujXgiEHiV-zF(f2DK0iMt5*NxF Q%o`;O3nn`|B_%-sJGCdIJOBUy literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ec.gif b/workflow/public_html/images/flags/ec.gif new file mode 100755 index 0000000000000000000000000000000000000000..9e41e0ec8c22fba363719ef9ba536c7c168e0ac7 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5h=)C~--(>ULTIq6f$N&KQ>yZEeTiZH1)+#FZ<5&06 z4<}}}?#2N0SW`xQ!*rUrS%aqSH!=C;b=Lp@_v3o@;cYr}zHF1RT#e23;dA=uW9R?? z`{;r7-%R=Def;Tb{p)l1=Y@Ks*JF*X;Y&;N&I9sFMEdEB@IpHPDWd%Cmr;etFm1b4 ziONiY#{J(5e4o4#Q;DSj0N+DH{_J>xqrTK1ALCL|{_v0TP)qgVVnTYs_hVg`w94VK z0QuJ$A^8LV00000EC2ui01yBR000Juz@Jd4P?V00Bw+bdIaP(i=@bfiD3lDK$>DfB z5=o^J2nYljANLy`m(PNV?}ej*K%b9BljwIkIsh>}H83y_4;L3BBM^=k1}P#K7%eL< z4m%bWEG!ESk&~8~nw*{sI|c*;HzXu82eAmVHZ}(`8$7xV4LK$zC@2xb5fd8|$jJoD I%*;UmJDaVaZU6uP literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ee.gif b/workflow/public_html/images/flags/ee.gif new file mode 100755 index 0000000000000000000000000000000000000000..9397a2d084aa397846d125405e06e31f81ca3eeb GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h04K9&qux6^JMr=HUY_3K;^K64b=un6(b3TWH@g4; znaaw_QkB_ElGrLMD;O9UA|fIH7OP51N&pF@S)1KGh}1?#Mm9D!KtMoLR8%*F(lLS1 zDtpcN`1tnr_Vo1hd$8pD`}@DYzxDO?071XS#l=rgPyGD+LyOc$kJnU~+b}RN!NI}9 z!^3#4gpdSZ}D|-{0T)`T6tn^ZNSw_xJbm^6~&f zzW@LLA^8LV00000EC2ui01yBR000JwK%dY@N*DpiNMtfm_&^|+OLn^j0tDKO(QtwY z1d58ALRB;yPE0{^g~yHZIn6;Seg<2{B(Y!w7b^}B5EwsrdwqX_gAfk_hcA47fP#b% z4;Mc*Cm|s_IUPJ6BOf|FJvuD~Cp(~`q^3Os13fGSpE;pCqot>)A~**JFfa(m3kxMB KEi57;K>$0OoS+N< literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/eg.gif b/workflow/public_html/images/flags/eg.gif new file mode 100755 index 0000000000000000000000000000000000000000..6857c7dd57a75a6232f2ce346c8183f63a0686fb GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5h@ZEI!`uZ&`E%IYy^Wl9wJUsGTToDoxf`WqTG&Ji; zN$_%V?nOoOYisp-df&`s?Q3gWTU+Jj<>deX?p0Owii(PgiuQJPQc_df008#(_Ve@e zL_|dLQ&VeeZ0P_1G&D4OdwXJHW7PlvOG``det`CnkoJy_`}_OyyLRnZ0j?@dkV*@n*m0QjV&>^wd7_4WMx{Pgtn>i_`#{rzTU zW&i*HA^8LV00000EC2ui01yBR000JvK%S8I`Am+-j50IgIi8oxqR|)(3=|5j=`eUZ z9U6myOC($h+v;XIRVuPl%CT5LAgWPs-_z*=Ed(zb8aX>T5`2CrEGz&3g*zLFdy4@C zH8lW+8yhKMfJ|ZDMKRz4<1t0FMbfn-)8(JO2LuNwG=Z?A-bJ z`E+!2M@L5hY5-$nWBSR-;~Eq4$V;^5%--{3K$FCm^G`jL_HFE9K2`{FDt`eI@-rZV17Px0~b_w(}-mJa;< z`~Uy|A^8LV00000EC2ui01yBR000Jrz@KnPEQ)@BBw)b|g&YovL`OkFrJW9AdpfN& z6xa?#1`*CG6>Jp&a}IEy??J05c7AP^QL9~22K zE*l#uDFU7X2@sS64Hz#k1}qsFGcyGRJp(nQ7!wm07YGQbsW~z?qzwVX!zRWf$jBl= F06Y6ZlW+h4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/en.gif b/workflow/public_html/images/flags/en.gif new file mode 100755 index 0000000000000000000000000000000000000000..8f198f73a777a6af8d3c8e0b9b2ce48168a216dd GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5hV`H}Z`ug_v_3`oX{6FMd)+t~b6RQz~i+ha=mD=V72{QPBRx?@WGIy&a&mbT%E8IW!TtSPICuH}{{8#^`tkAa18?Ei{{8*o z++%0NA^8LV00000EC2ui01yBR000Jzz@PA!N&$|l2Vx0<{BkH=DIlQ+0->w`_Cs+v zo`Ju(0i zIDb4K9W8?qA0G<`A^`#$8+MVC77acxDm7+kX%V0WxGEYA0Wn&rsXHq)79ulC2u)2S N7!(u-2O82r06XTKt3Ch# literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/england.gif b/workflow/public_html/images/flags/england.gif new file mode 100755 index 0000000000000000000000000000000000000000..933a4f0b3dbe2f328d15f73895ba576aa78295ed GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5hm;eCXgM;eo>f(xu{r&yob#>cSRqLap(9h55o}SDo zDA{sy`}Oto^z`}j^Sl56&oMFg@$uMAP0=E`CvM@Qe^-`(Ba z<>lq!;o;-s_-l#}!9?AJ#~)l5v{hKBF&@$K#H{P_6M zRaMcyzvk!aN=?0fyu0Xnen4Z^|l!7&RRaciTXx zJp#iZacpmv+sp?hh$SZn*V3@eTC~F)cv28j}X6%!B&kQV?jG$JK3 zGAWG|6e9}@0RSrmHCa3njvx&-J3BTA0t7l*I1!H~tU^0E0;XFLC?qDUAFVk{O&S|9 N001rs&^gjU06PoNyxsr+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/er.gif b/workflow/public_html/images/flags/er.gif new file mode 100755 index 0000000000000000000000000000000000000000..3d4d612c774fd0e2af39995926d21a3c0b8c33fb GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5hX~bz*eB|_YI{*XE_{357d0X_DP6BTLW{B!MZRY?0 zy6Y(^N3}eC<0QHb`Po6pE007-CF#rGn!wCTDNk;Q#VfK7| z`MFH@&O-o*0Pb8vDyb?uvO2XpU-2?D_Q6E+9UbjoW3d1LRIf<(p;ccs0961%*ok^> za3QR6snbeIineuFWX#1pUi7&-%4kxThfdREezBl<`psB=irs;JII2%5xM4o^M@sas zMlq~0A^8LV00000EC2ui01yBR000JtK#c0(DH;#RgG5=`Y*;rKU^<0Z8Iq=^z@^nt zj8NzY!d50Y90AAaWq3LYsGN-$QiMDwIS9VK0l}>&D+&Y0$O_8K H3PAun=2?lT literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/es.gif b/workflow/public_html/images/flags/es.gif new file mode 100755 index 0000000000000000000000000000000000000000..c27d65e5f1218537ae3dc51733ae628cca95ecc6 GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h{9Ii6Q&aWzCHD3!^erv?V`Jv#0RD1w{{D9J78d>e z0Q~$+>;M4s008~{ZSwLH{{C9~`$hLlOZr4a^fNR0JU#I8LG<-I{cCIgdV2RnMC@o) z^*cM|008(lHt`J&_VzII^BMU70QB@9`1m&9008;n?pN$nQT$9y^1ZOY&ZyvwQRJse>&Z*q008{} z0RI30A^8LV00000EC2ui01yBR000Jsz@PBvEBZvphLXYfWuBSC0fQ+N0D*v{nE`mS zx5=d9p%AtT1O!r3$s!RG2{aJM3~2~0wOLu@bOIw6cnByb8!b37b9EyjgbEG|E;=?Z zDuIs=k&`(*J1`cGArB8AGa?0JWCR2(EC~r89|R?;Us@U(92^v81U*U(OvN3?B_%z} GK>$1Bgrgn+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/et.gif b/workflow/public_html/images/flags/et.gif new file mode 100755 index 0000000000000000000000000000000000000000..f77995d0ab47d81355552a534b769575ffe05d15 GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5hcf00^#no`Bb77rgPLfgiR8&xyi)FFm_4Oy}0000< z5dHmB^z}RVMn?1V9Q^!CnaZ(wy2}7F0RH}S^jJA*ql7PcT3(xf<>df*t&~QKYx`kh zQQBLHOpS(ke6LM7b* z00000A^8LV00000EC2ui01yBR000JwK$v1klo*YvWJ>XRWip*kWqP^rIJ2K3W4&?= z22Ctxv1oofnP4pdxJ`sOVUTJ~7We?b1u;bs2o4Mwb_)*=0elcDCV_&46NiWZiw6-7 zn1d@gA0IUoHU|eZJvSvK6f7$n4IUyVIUylBARs6xB&r)51-%WwBCjVTBt9d@BMHjO KEX_X8K>#~YC5%M? literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/europeanunion.gif b/workflow/public_html/images/flags/europeanunion.gif new file mode 100755 index 0000000000000000000000000000000000000000..28a762a59cae1c775b52f2c26b21ad658632073b GIT binary patch literal 171 zcmZ?wbhEHb6ky8jO69TOFm!wUDVT;A)?!_C{yfy2gaWmCOrR*q$^bR9R{scg(%O@TO|giqzYsR{U*?U8O5D U#0n;zPAS`BTG1CL&&Xg60F0$Rp#T5? literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/fam.gif b/workflow/public_html/images/flags/fam.gif new file mode 100755 index 0000000000000000000000000000000000000000..7d528852dc3f4efe6cec2d7f25e4674816af4c7c GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5hRNVW-^HgZw`+DR4UETfrREzpag!n;y)AxGU`GuG5 z0Q_s4$@N_T#q;(ub86K9{dc4FD{i6i0O$Y!`2ZM9+WP>!{6yRPS>gWu04n!Og8-@Q zX3_w2;{EtOd&%=?%JpD#+5iBn@?_xt`9y#Kvi8pRX@KVc!SYYc_GI@scgXT(_%w6B z@k@E={?GMu_c?g^J9qp~h{yC7X~pN zixD#c0XPp9k`)&RESV9UC?5|y0u?$m9uW=^5k4p=Eh`))0s?pi8o?w7A0I0{4<#ZZ Q8ygeP&<_tB95+D#J95gS9{>OV literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/fi.gif b/workflow/public_html/images/flags/fi.gif new file mode 100755 index 0000000000000000000000000000000000000000..8d3a1918280816780d79856b678e2ebb5bb76d66 GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5h{r>*P&)WbiyhL-+$q-dTj%J8aF`-s|}I z_)&e-x4+G6k=`<8%JTB_Re;vK!qWHn`hcS2hNk7+;_YFI*-d)X!O7PE0Etd|&|iq! z005lz_4Q+m-1heNN_f-z`}Xr?J8L`~36s^SQy#NO#iq_xR=O^YZfY{QUg-`ug|x z_y7O@A^8LV00000EC2ui01yBR000J%K%G!05U@^_N+NMGkubX74?uZM06bo(7gP9F zQ2?M}m}$A*k1s$F%gUQnOp^O_3LOlK(r9=#2Q3gHAOk1}5E%j!27d<-3l}&82rdo_ ziW4({gOY{_4h|X_2{m(rAU=0C4g9xlX|nrTtN5Iz&ug^#l$OE(bNB!&-(s`+ z(LFiN`_)KB*mQZ%Q&iJjT~wa<0Dk;Y zc*Ul#)rlEBT(J49dzFJDNq-YNXBkUnu=&@Bj*x$;ak%+jh0f%+zRwvM=aiM^)7oiO zk9eKgA^8LV00000EC2ui01yBR000J$z(?UQdmU(uPA1c6hC&BKFOksoERcZ7B*5V$ zJKh992A~F;4XhHmNMt(DWCF6qJg|>Sk$NnA2sb1o7zsBX6(0(Vem5357#J--E-Miw z4kr#J3oHRR7Zf!EYz7P`92^W9o}r_q1S1X{4kH>F0ivW41_ZtV91sS#TV0^KA|kxQ QO&w1X&EkWpbP#0IBkZG(I zI|I#NsOdxu#!OOa0CKWjOjd$nAd$g9!fBicDjy#mKOiFk5j-s+BMm7kHWn5b9v}e@ zc>*B;6BIoe6&NBAmk1038!Vg@9-*U`4gvxi8V@g>D59he4hRSv8xIc-6AD>dprRuq Sq?g4^4GIm@(-YR$K>$0bS(5+& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/fm.gif b/workflow/public_html/images/flags/fm.gif new file mode 100755 index 0000000000000000000000000000000000000000..7f8723b7da96997e52b64aa9a90b112828d0c3e1 GIT binary patch literal 377 zcmV-<0fzoZNk%w1VGsZd0M!5hah%8;X0MsK*@LOh2Uethrp>9v;gPl2JAA&LzTSzh z)RVN={QUfetkP|n#`gC1kFwRR$m6EL+`iN1mbcgdG>o~=soV?qm!{D{dLOaapBMH1q}A?D&`J_Xutgouc569)lqu+uPC6(d+B$=jZ3+&CSjG`}^|p^7i)j`uh6!_xJPj z^Z)<S_%x44Qgjl}c&lY3ENVi*#SF`jw zQJXCyqG-9^-Pb2pO=OL2x3{D1Ihy?y-rnB$m5kKX z)Yt$3w8iJV%jsr^%<5`g?(XiPwcY0C=H%q$?sjUj!{w&A-t&HP_xJazz2WW&0CJMj zs?RiQbXoVKJ@hTySuv= zN2U1q__xUC>|Rjp>+3{pyW-;FpP!#^kI|;N;Ipu>uD|3gSFo+9_7 z>~odVA^8LV00000EC2ui01yBR000Jyz@PB9K_CFBujQ zjbnlXC>J5^c-oz zY4-LpRD8_-{&QQrTlMuMUAjEtsVQ89)Jk>C0BQhQfWTjb&-wW~PP9V+MgUT`Qv3Tx`uafl z_%{9h0C&iDRDRK5zF=0lR${+dLvP7|&3P=PEM>u5ZIH=rkkx{r-tzJkag*0|me@V5 zF#v-AA^8LV00000EC2ui01yBR000Jrz@JcfDPBlOi_-G*IA0);Vj6SERFYJ)YQ<(U z8Vtsk{nc(W2xPNCX*9l22$ga*3^ZuCMA~Rr!T{VS~Ynna}=XVtbp!|Lf{JQmlm=H*ti=+u`)AVSnMi-(+*O z!o=O#-R=JV|NsC0A^8LV00000EC2ui01yBR000GnV5Ce?*=1Q51Qm2lOygk;;}L`x zMcji75JjW$iF_oI&!s{5FcJ_(MDzF@0Y^%qa!GVN)-V7Y{&)%*0&>hYxZMEDxBPL3 z5%_H+P@p93bqfgr0u>A&4+I-^1_%`h1P&1b10D|?7Z)C52rC>24jU5(0STrB78V5p KtO)}NApkqQ-f7za literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gd.gif b/workflow/public_html/images/flags/gd.gif new file mode 100755 index 0000000000000000000000000000000000000000..25ea3123187325ea334cd556a8725f10d6d6f1ab GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h`PfMK+EtFuT8_Lk@?HSvIRN(7DqzG={^NFipiU;F zCK;R=^~gEr002p|M#j@PRk>7Pxj^&N8T;Qyd%9}#%_{qI0R7}u^8f(%%UDdOHb$H> zrNlTjrYKjZMEl)f_-;nm-dg?PYZsyy`QAL&008*hHif@+iNkvM(=_#7H|f_=ugXT( z#UD1X3&(aoaIP6(j4a=YRrX{&i@Q&=#15ajd-KmV;m$br(m?svJpG9PimYPY008{} z0RI30A^8LV00000EC2ui01yBR000Jwz@PB9v-m7Vf(65D_-u%1R3!RX1DS*qB?w)< zlQ7Bjh$0qz?3ck literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ge.gif b/workflow/public_html/images/flags/ge.gif new file mode 100755 index 0000000000000000000000000000000000000000..faa7f126a7eeb2cdd66c8e7d7bae6c19288d00a7 GIT binary patch literal 379 zcmV->0fhcXNk%w1VGsZd0M!5h^J`|q!^7$}FY#Me`uh6v*x2;+^!)7X+S=Ow{{HKU zgyQ1j?^;yL%ggeamFZ|=>XMD}^78baoA-%^($doUzr5z==J?*-?}dT$VqNpPw(o#@ z@TQ^D0RZh(PwfE!<4#BNkd42;zv=1e-{0TY*Vp%_r1Pz)_oJZqq@mf@+3(57?L|NN zuB_s9ZTZg1Edqm6FfT(fIiI{QUg={r&g% z_v`EHA^8LV00000EC2ui01yBR000J&4c69K@%@B50D}3d^dxy0jRWQH6{`n86gfi4j~dT9~*=NI5-0gECQAS zEFA+jC@B(&10EO(qZ<$%7Fil-I}9EMun-Xj0Si1QE*y6rAO;Z%ATSZN1Q!k$cK{Et Z1u!cSB1{M>B@`4L9Ss570U{zn06Tokyea?y literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gf.gif b/workflow/public_html/images/flags/gf.gif new file mode 100755 index 0000000000000000000000000000000000000000..43d0b80172e97a08147c64f811ea5c7775ad46fb GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hs;a7*ui5eO@$F<*#M13od&TML>hy?y-rnB$m5kKX z)Yt$3w8iJV%jsr^%<5`g?(XiPwcY0C=H%q$?sjUj!{w&A-t&HP_xJazz2WW&0CJMj zs?RiQbXoVKJ@hTySuv= zN2U1q__xUC>|Rjp>+3{pyW-;FpP!#^kI|;N;Ipu>uD|3gSFo+9_7 z>~odVA^8LV00000EC2ui01yBR000Jyz@PB9K_CFBujQ zjbnlXC>|i_4OqFa&sJ> z9G#v)0Biu0l{WVFGxY!f<>dhXdU{*CTlOj{Xu@dxVPWe408+M7M@KpJ^*#4YO#N$X z04V@3r7r+j002h-3zZ81H~=)MG$f)V{7g(UrZOs{DioO%`8+-NH#hzL001BW{8d%` zQBnN-PxkgJ_c1a2{7PtMHDF#Z_C!QLuR!eYHu>~A^6x4Tmk;vt6k)z%_)}Bx^G5vu z0RI30A^8LV00000EC2ui01yBR000Jqz@PBvD;6I}q{Z@!I3tO~W>cvESUe3gV!gIV z1_LSun`oN=FIY^TOlTHWArNrIdW(k5@j?tT5OQ@f2MZV&4SfTDfdzI42RAY^IDP{< z4iF3!0s=JzA{{0p3JNDVB^;ZcprWLvIUpS?3_B7M7Z;tMpe3TT9>E{OA;lcWE6G6s EI~OyF2LJ#7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gi.gif b/workflow/public_html/images/flags/gi.gif new file mode 100755 index 0000000000000000000000000000000000000000..7b1984bc692fea25c149976f81b83eefe4115c6e GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5h`FL*WsY>!XF8KKP@?25#^YhgJ0QX)~`D|k9&&~Mc z+9?L`uh9(`||Pe>FMdMX=VCmTk~2$@8aR!Ju%|O>|Rv)6$R*3O1V8X@@io8 z_4VOMJp7c6@l;63$H)7GeDvSm>F4L}<>dDE_T2yg_4W1r{r&g%_w@Ai{QUgy@9+Np z{{R2~A^8LV00000EC2ui01yBR000J$z@D(T*>FIh#e%^wH5$F&&qvMWcs!40Fwi-o zRNvzyQ*667Z!ervAP9#U8fSxSs*eOJq)O;)I6F8H96nb(02me*7!rX6Erf?22`(!o z36CE;5Hvg;9U2lO0W&o_1s@*;F)1$qum}eMBN+r4Fcd5|5eOn82eSbb7K;}G0=y9s Q6U`F_710$p)Hgu@JB@m~0ssI2 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gl.gif b/workflow/public_html/images/flags/gl.gif new file mode 100755 index 0000000000000000000000000000000000000000..ef445be003587758a9c100f3b8f4ba28d7ecf95e GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5h{JgyUWo7(cUi_n@_4W1b?d|w;bMrJb{QUg;Mn>xD z>gML=`kb8N;^N-k-uIJ}?-CN$*4Ffki~Hf>>;M4d008wnJM;hm`@zBTE-w9UZt)Eb z`v3s^R8{_ylk^`S{7XyU008qD8TlIRt_c0RS`uhztxb4-XQLFAy9W8Y)^` zJuWpLA`k}^93>!Tm@p=s5S}3%0SPt$Fa#4Ms2dv@Ar}GyCLJXtHYgSr2L~A$Hy6qj O%*++fAt5)@K>$0)Ft+3X literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gm.gif b/workflow/public_html/images/flags/gm.gif new file mode 100755 index 0000000000000000000000000000000000000000..6847c5a8c0232d984f7c8569a6f7b89b96736963 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5h5tR{Cw^Y_hNB}DU(KIvwPXGl@{oP|@Y?=D{_Vz8K zEdU7Rgsc8MtUN<^^<_5J($?(pt{=R9%q&BwrH{BE81UXb>EsQut;Yv1MHQik(Ziu729_51ku@bd5>o*}!zyZH3;^!M~Kr7~iV z`@;YLA^8LV00000EC2ui01yBR000JuK+|tHq!^E+B~N4wt|z8sdlh&I zV1nSJx|lDwTVlQ2h2E@Ig~5nrKB5=m@qk%g3kD1bE*(A|9w{Io4h}0effX4UA|ePK zeHJw|AP);O7aF2GJR7Ds7^yfqB^(e94JZltZIsglm3;X*=`$a|mSy>dB6#V>6C88zu^&&H-GWYjO`|w8m z@k>OnMEp-r_xCUT>j3rjJ^cJ-ADQ4|UZN~l|!gvlF*DuHr^e2w<21@AEEG#Yme6E6cS92*@l3n(-Of<6(3BsGdK z01J;M1r?G5BoYpb04Wa!CN?Ub7onn0QOco{QUg+`T6xtH1=3N z{{H^@`uYLs0P{sE{&r#j%>aM*bo5g+`)pYGXinn*0Nnrpnf#Fa)@c0_0R8%J@IfCP z?Ev#+Nc3n-{_Tht`2*d*sr$8G{Nri;wS@lZaLKWk0Pz5I_G$i;g8a&V@kS)|Y*74$ zcktZGA^8LV00000EC2ui01yBR000Jpz?Nlb@fbag24abz#86OyR3aG+L?TDd^W%6q zm@uZ3$pFqWmF@uoMM#8Fps=}&dL~uP_J~B{0T2at1}`QFFe@o=a)KKp1_myNJ2W$Z zf`kS<5GM&fjB|Aw1|J_R1t&jaWM*do46(5{I9Co@6BQK)yb8V)N=p>OA;k;F$Uy)* Dz3QR) literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gq.gif b/workflow/public_html/images/flags/gq.gif new file mode 100755 index 0000000000000000000000000000000000000000..8b4e0cc41ecc29ca33c6780e4d3334123a4aae24 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5hgTMYUq%n5LcID;e`TO}0hyB~y+1XT70BGp}efw#` zX^g`9);c;~yk7VB_f51-;%sd5^Yi)k_Ls{20EPenNC2q-07R`s0CxcL_3{8@0P^nc zQ?^t0`S-j40N!F^-AYQ*EG+r(xBUG4)2@!#O!e!cz8 zA0Cg&>FM|To~6)`!;9ZrTfW1<-{s$-(EY{8$%?;)^!M`gF*dl3;n zehU*4oDwT5Dk>YJ8wQIqARr_RtRW#fEiDW`2rv-0A0ILYyd@%R1*_B3)xyo}qO|0?#_IX``tI=dzRBve!R7Gq z^7i)l@$&REUCfQ5+v)A~;pFX!pW6#P!~iM0f|}g`0GExV;q>(NO>)(NgUjvj_M5HX zdz9KOSIL#A-T)c2xy9!I0E*`6^7#4u_xSts_4?!H@B%f$;^N}`{QS4X=g-&gSa!$? zG@;Vg-SYJJy~yXt%GLlFq1oT@=<4&Tu*dA~^78Ze2O+8G=k5S}K;&nLhPNH9Mi1~aOXNQ>;tg^K!o zy} OO#v0p&mq#%K>#}%6u74V literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gs.gif b/workflow/public_html/images/flags/gs.gif new file mode 100755 index 0000000000000000000000000000000000000000..ccc96ec0093b08b01c9324d90d77d962f297755d GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5h#>Uv%tF_jJjVUR4c6Frd>+Sq$P!khzY;2-MM2%x( zpgTK-N=lKOAUxya>SqWx001uP%+g(5obhdC000!HeVPCOQ{{YoFff0MVvA5vlr}Yi ziH5ZE^YlhWeEpe$=UG|P&Z7Bwao*qN_(R_cf=VV}aquXVN$HH7Mwx{F#FkLGXerQFcmx-4h0Af06z@`JsBAuD>oY$ z9Vjg)1wRl78Vm_&mjfdqDlCnkqNErD0|X=m00^E6qiU}M2fe)*w_9DUX_v2_O%y-N J%+1R|06RkFo6i6M literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gt.gif b/workflow/public_html/images/flags/gt.gif new file mode 100755 index 0000000000000000000000000000000000000000..7e94d1dda0ab4a00cf6ce142d317cb66ee3eb114 GIT binary patch literal 374 zcmV-+0g3)cNk%w1VGsZd0M!5h@$~p=rThS0|Aw~zRF?YyHudc9^y=#B07&=%1Lj$o z_fwVj03`2ClKOhD{q^ z-S_wRA^8LV00000EC2ui01yBR000J)K$~D_sU42ASwW>@s04#3NTSi`bd%92gNr~Z zfy~8v>H$h6nZi2=h&C5pc?a;wK8u6^B+A?_b2%6v9~F5PAQ>A36FoaQKNuAiF)t_< z4jUv56OTVU1~DNVEGP&LBm|t0JP!sO933X66sjcvpAW7byeTLJU?VsaKe+}bCMhXC U2ulnRD=rWaFfAx3KG{J4J1s%9mH+?% literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gu.gif b/workflow/public_html/images/flags/gu.gif new file mode 100755 index 0000000000000000000000000000000000000000..eafef683d5f0280f58de5bda5d17a9f6766e1b72 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5hLu2wfUGmw{){dk8VSf70S6`E-|AU(R`T+pn0086w z0B(u;VSV*ndHHFC_fc>2?EnC4hWt!y^>T~)W`g^3js1zA{aktVewF-slKS)j09khQ zcaZ*7bM|(R`EZK;R(1DQbMsMf_ET{3dXxU2xQXOyYh`5VW`Ossfq&m)W}v!{w85sr zd7y5H_s4sm-DX2_jQOBSd(Kv6bdLSnyh6udh2m{-jf1Iwb*Wi)_(x~-_W%I#007$n z0R0I7A^8LV00000EC2ui01yBR000J$z@JcvDDrq3O|J)m{0z{+z+yQZFd5Ip|${z=jq{PzuC=Q~5-0B`hi(b~_At1AP$`Hv$4G4-z{77YPU! z3yTCQCpZO?00A2bJO`Q$GdVRflK}xCKBW|AIvoWt0HLlUJ{njaF$)e33=9_=AtMjH QOHB|8&mca zFyyoV_4Onfof$`~LHzt6FQ_jw zrZOL(AN*Na_Vz^e^*<4h0FKKgkj*RpcXwN^Q2P2@{7+C2mk;%Jc8zj#{Az0UZ*Tno z0RI30A^8LV00000EC2ui01yBR000Jqz@PBv%NQj{k7vRBMV_^UX8L&C3I$5Q$>F>{ ztJSDPGM!Lb?kfZym(L7Xz^4Nsa38lB#bCtdI{*L&1_l)s3N$ko78No+J$45U5FIQ7 zDJ~5v9RfZ)2L~7vmYA9iu_0t6dgAvPBml$9+5v;@M!AjQT4$jCte EJ2d&0^8f$< literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/gy.gif b/workflow/public_html/images/flags/gy.gif new file mode 100755 index 0000000000000000000000000000000000000000..1cb4cd71d6fd05fa1d42a8afbfc3d25d4512a43d GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h0B!)EnQ->^IW?y=)#$(Z`^x}K0QyKs$J@E-_10Ck zRFQ`}hRlg$zhl}@PxkqF{&#ow_ALHaR{$~q_V%iD!*>Rh2K;Jj6P6VE`dV^nM7Byu z^YyC4*j*zfYV=(tySwr6@#Ev;)z#I-#l^k7z2V{E$H&KTkNS$B`(=yv z-{0Tv?)r0>_jQ{1{rvrQj`wtw`-Y$OgPHn>pZZ~l^#@1kYm52m>Gq1J`T!;000706 ztNQZt^z`-h>FN0U`}_F#_}kmt`T6FNFb z{r>*`A^8LV00000EC2ui01yBR000Jyz@AX3SS%(N&TQ78Ku(Nk)L>Al0tW)&!|MIM zKc9~mtI=dOoDJapig}vSIlaR@6mAehL=tRNI6FE!7QR4sr<|QTZR8-|O zG|T`1^?G{x(b3!h0Pq<)OKR)9c8u3q0?Lk55MMdyoVe2?J@L5^%W@he1Mf7)f?Kn8^N=f7&AM$Ey`@g^S z;opdmE|u59$9OzQ z34=fevWx;4&bCXs%n}pUtb;~`7QYiX(O~6jE&wA4Di#z!8VMgf1QRj@H98n79ubEd zA1Njv1PuT&lO7TZJqIhA9UnFT0xc+_G^7V5CLJRq1_1~Our~!64pwb193eOs5ef)>y2ws2+)GW3#LM5@q^ivc z3EsHAA^8LV00000EC2ui01yBR000J;K!R+LNDNZ5ijpy6EEc<5>(xW)0Fuy!=U5dM zz5@;dG2Kc9&Ex{W1QrQe28YWWU;)a6gaLFGEGH@g0xmx>6dxZL77-B(H3kPCM3J(k+1vUs2B&Z?{ARY}Qx>_DQ Yq5-4|5jGYZx(rTFPY>D;4ckEgI~~rLTmS$7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/hn.gif b/workflow/public_html/images/flags/hn.gif new file mode 100755 index 0000000000000000000000000000000000000000..6c4ffe8e84324c2ea40f2a50e6e0ab391b0f77a4 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h{{H^N#KdHN(O7iOJzc|ei`VMx^A9$%dy?7!08#)1 znqGO(CP}>X_4TB);s6q%=H}*wmCI^_)BpgALu1Ik$m;m`_^!I)y2a@L0CTm$sZ_G1Q!otn%E>FI>#O60vzkrt9J5igp zzvo3;r5ixGm#E+K^YhQw@k(dLNN346Sj6My@y5{a`T6<${QQBH*1*c^!OHB#&+fCn z;s5}9A^8LV00000EC2ui01yBR000Jzz=u$%C{B*YpYpM4BA$hUL?T!W1{nonVI7n_ zGzy_+LeWAI*{yft?JAg53k15PTo8bs1moav78?c)gaLT~IUEKY4h|MJF%6N1h&d!1 zfEFD(1~DHE0cj_1DJdEnJ{K1wBR(t>0%Bw+3=A(X2e~K-6I5JY9y1~$1OzH72|p7` N8Oi__SwdDR?U1Oct<>lpbsoy$<%>4ZP`*n40r`}bR()Ttt z`anPc9HdB%(f@9$KW)_t+!_C!SY zNl5@y!TbCB`~3U-OH21xR{#*5_*`5{daY=p+i9fUY^2*!lhgI}_5A<<`OM7p^z{Ax z{r>;}A^8LV00000EC2ui01yBR000Jwz@PB9D;5n%Bn0vcIG-3yqv3GSWXym>Qd(3B zw*qIQNVKxt#Ud8s@W=@h3*!5He3wJ}EjZ|UIuvzyd2Smd0)L5ucrY(IZzKsRJpuwf z6fO}NHUuIyWi=inBNithnw=sKDmf^l7O@&23@a-G6&W}-6RQsz8acEK0L1_u9Wyfs K2q4ZNK>$19yrlgA literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ht.gif b/workflow/public_html/images/flags/ht.gif new file mode 100755 index 0000000000000000000000000000000000000000..059604ab20eb6f3a5063c0321ae2e8b1badc4a67 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h_eVDX5y0py7K@tXbA{g4008b+M)GJ`1187oMl)`K z-2el)YjMhyqv%|5)@6Cx>Od~!002^H)9y?={9H`*b7Wm(#C?w9`%*&y9K`lHCw+s| zWoyXG004!R;`1vPdW+rw0Iq6%+Dl^4TkZPe^MD(g2S=`tUA zis1bK0C;`T3l*p0EmYUr3G9Lf{dG&c}c8K5aU{L*g zZ^ZxrA^8LV00000EC2ui01yBR000JtK!i}3$piw6WM~;eG@dltVBqmwKsy01**8HYX?(2@onPECK=~2^|p?qNJv%sw5;3Kd%S7JvIiTq@}o?5e3G_9myR( H%s~J<4X=$u literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/hu.gif b/workflow/public_html/images/flags/hu.gif new file mode 100755 index 0000000000000000000000000000000000000000..6142d86817c12d74b84a4b19d7f60045bc0dfbd8 GIT binary patch literal 357 zcmV-r0h<0tNk%w1VGsZd0M!5hqT^01W^xjxG*;4(N1r^YimXo<#s90K5PIJ(xW@mOAQtd$j-n05|~QOiVA4FDi~I zB#R{0Dk>j`9~6NU-aAHk%VprRSYEHkW3d1LYzG;FX-Onn zhgF6J3W;1D7W4HDkIUyyCpYMsOugL>bxM^~Bsx4g3U+yWeSd*G5IBW-G<<%5f)Efq z3IsJV5ik`68XFuQBOeYoKLi1tpP{3r4h{{e0RaZLGo2KlHx08Gz!Jg?#6QNzKS2OH D+N+ap literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/id.gif b/workflow/public_html/images/flags/id.gif new file mode 100755 index 0000000000000000000000000000000000000000..865161b0307cfd1609732950cba4d9a6c7999aa3 GIT binary patch literal 362 zcmV-w0hRtoNk%w1VGsZd0M!5h@$vERqMhVoS?qdq@s5YO008Rh>gML=>64A?o|*Eh zrs7RQ+%+oWP)6leP3C4^%m4uEY-Gd$0Mh^f-T(mF008J=SL0Jj?SOgeXkX=AQ{hNG z;Nal={QUj>{p@pV112#cW>!lRp)AA@TZ~kuBz>JZt9nj?3$I| zJu=`!IOdLs@QQ=*jD^)03-0dj`1ttt_V(S~-QNQM`}_O#_4WGt`tfFwS*DGCZG0RagtD+mZL2{IlY9UVA2 zJTyKvIXgW+J0LigmzkTLpFceuJRLfinw*|L002K6KBcCovp+vJIXwU~#0CZj2Ou0A IHqAi*JCOOXTL1t6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ie.gif b/workflow/public_html/images/flags/ie.gif new file mode 100755 index 0000000000000000000000000000000000000000..506ad285906c72324b51a6d2e9e067177444dbb0 GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5h?e*;dhXCjR0OsfB^nWvY$$IE^k-~a$hv`X}aJLBWy`k7kwdM5alQDVPh_<}cg z$alWJu+Y%Z_Ixbx`0)4d=;7bnSiD&Ei9hrp06?xk0FeOr`1sub0Qvd(_V)Jr`uhC* z{P*|wA^8LV00000EC2ui01yBR000J%KwMxL7#Ihqnay^&U;>3`%h&1nd_5FOr4m3_ z3Qf#v=xtaOSj1Zhhho0+ZbSH_)`1o+Gy=$TG9L~JHC_*VB>+7;IX^OkASMD03nL{S z0E|C83<)406eN_FHxrFK6$~H;2Lz%k9ybsZn-!@C85trZ5?~q#w6zQb1R^3j4H6O@ R94;>}78WifBs$hX06RAOp?v@V literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/il.gif b/workflow/public_html/images/flags/il.gif new file mode 100755 index 0000000000000000000000000000000000000000..c8483ae52f057c8131c67501b466bd5bdd3e46fd GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h&d$z)rTd+o`NG1&dY<`ek@k(P{eGhQTZQw1l=tW7 z=jG+)m$UxY*Vn(lzst+Z)6>(tySwr6@#Ev;)z#I-#l^k7z2V{E$H&KTkNS$B`(=yv z-{0Tv?)r0>_jQ{1{rvrQj`wtw`-Y$OgPHn>pZZ~l^#@1kYm52m>Gq1J`T!;000706 ztNQZt^z`-h>FN0U`}_F#_}kmt`T6FNFb z{r>*`A^8LV00000EC2ui01yBR000Jyz@AX3SS%(N&TQ78Ku(Nk)L>Al0tW)&!|MIM zKc9~mtI=dOoDJapig}vSIlaR@6mAehL=tRNI6FE!7y?`uh6v^7Hz%001}u^YiprrdUp*P5>YP`}_P! zpGo!Je*W#Gp|je6zJUGUZGV!-`~3Uou>kk60Pv&$_RcK)-)V!4z4y>D`P4o9*i7{F z_5Z&BA^8LV00000EC2ui01yBR000Jvz@JbEDVj_+h2nO5{65f+!y(IMG6aDD_4?|E8002HHJ`#B&EQtsfIthX(C54AHEF=^& zGZsFBkrE6O1_lEI5h(#GEe#DFDIlMsq^78<9UTEH3^5uS8ylgc5v2jQ3?arM$S2Am J%qz}806T|Gt@i)` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/international.png b/workflow/public_html/images/flags/international.png new file mode 100755 index 0000000000000000000000000000000000000000..77ea8079e0f2a9b7d9cb202a61c292db787d7de2 GIT binary patch literal 816 zcmV-01JC@4P)U0=YpJ z6o>*O-h+lWprAs$LOM_iIuZ(m0!S!A5r`m!gBOA0BAeKW*N)`%cxLC$ow+PeK;cjN ziX)v<9^sthJV?%o*!uYH+TM74PX^K7z7BuaVXzy8VY}0AwBx`}l=RkPa_iflAB-PPx1HDgRL#Z=6@|3uhu-vxbDYiB`gwpZP z(zBOH--#i zhbKKA9U1b{QkMo0FUTN_yM7QNMa`ophnPI$=ACWsj!$^$N}r7@7y0D#Uq}nkzT!9+ zXr&QCER-us$F0utN<>-Y*xKO*4MwXS&P0QIe>~x>j~+5e)_8xUnYs?&{q!eNMd&bM zZt8|=#$of|XomJ9LM8Zqr{LY!nrvO`a6AeabR(YUg4FMGmr=2+o~w* zSYdFLhjAX(mVEu=4!@0C3@>z<&K2*y^EzMM{vq3aa6iRS;r9X;_Cs_pP=maD+IFN@_tw~um%5oQ zUH}I&%uGl6=jQ+bZe3-z{imduwur24O~l6HsI1iay1I#n!|l>Z002&Gn@c|@i`(4n z^4;S5oS8~etev6F)Ya=)V6#I@sovo3?bO?TsAAjG&gr(ks>Ph* z!_4l?IpEIRTSuAQ$wl4Gdcnoo*L{uP;PFveu(G9OaGPHBprQ3&U-$C&tbwT4*z2iH zbD59BA^8LV00000EC2ui01yBR000J(KpG&RP!KhNfWxs^I$)d~V#R5E3ZO!S6`4_V z6-cK8$?*h&N9lkYV0?&1C5Jd!D3kT!5c&K_Dg*>6Efx~ T6b2F>xK2wL)Ya4r*g*h0BUh+0 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/iq.gif b/workflow/public_html/images/flags/iq.gif new file mode 100755 index 0000000000000000000000000000000000000000..c34fe3c44ac029c96bbc44f4fd1a814b8235902e GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h>hlr5TwF#*M)d#ytK6*S_2zwh zeZJzt{9|KdV`Mx$JnH}e6ciNp`uTy#gZE5K{cCIcMMeL6diyvyTU%SS;kN#Ec2ZJP z{fdhD{rvodg~H~=oYJ26adPhV@ia6vz2m)XX>5&)jg`-q_vX5cu>1kC^SPodc962ANhPDA|fCG0R(s%EC>rXEG#VxED|S$cs&RS z2`(fg0G*SC0x~8hIynjoHZ?CLB@GHcKMe*B4kH4$5V^Smunia(8yg10v?I2>u*u5H Hut5Mj5z(S@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ir.gif b/workflow/public_html/images/flags/ir.gif new file mode 100755 index 0000000000000000000000000000000000000000..156040fc578e6a7a1bc2399c40523cfa7f41e945 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h>Hq-wmX^8Wx%8{60E7U`<;$nnr{(44*Y4L!v`WnA z%<_bU{AFhI#l`X!754V_V!mSfy1D>&0Q566089W}yj=SA_It{E0Av9A)YSS!MEYA> zQn*oT!fQOPJaWZz`L(wAP*C$NE%!u3^(7_sJ3I0K0Q&m+^Yioe%+28d0Qdj^`J$q; z-?XpZu|K0fcgT10rKMB0Q&+lI_wn*Es4)09H~Bm~{N?5Q`}_6v_1ypf{QUd?i2(HU z^!@$)A^8LV00000EC2ui01yBR000Jyz@AV@AV`i9j8aLsTwt)zr_+HzDl=Jv(z{%- z98MzP@ziQtfdV05BU%cV!cd^Ue)u1cX90m|4-Yy%ItO`sIRPvY0fIg#g?NZ3CkqQS zgD5CI2Mah68K5931EdWx4Fd}+3>q3YHWMNwBo4L?6FaOM8zH_UBPAshvLZVs$R+^G M%PP()JJCS^JK%<H%{6AP`uh4~io)bW zLI40qah1w#lgUwhyjX(1-Y6#{SfxyOxh`R>^78WUd3Y&Zs6KA9003rQhr$2=S>ro8 zL2b=SW9KbF%;ngZTLPLvXX(003%_#`gC1`}_Mq zZ?Urg0OwX!>R49iO-$wGMR}ioeJSROX0EIFs6(2AHF(e8b8#)k^3NAl< z1uP_igM|PT05Svy84m~wCp8x$2NM$(B?|-|4>LR)J*%x277-{5CRr*xFFg-AI1)4^ TC@l+20RuM!8r2Ke*g*h0+u4{_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/it.gif b/workflow/public_html/images/flags/it.gif new file mode 100755 index 0000000000000000000000000000000000000000..d79e90e99e9cd5e9603313cd6a840bdf23abd8f2 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h_e@Lxg#hB>;@;lg<^TZl6BGGWRrK`q^*uf8008nX zE?Bx*09OF<4GsSO{#?CW^8f%tuR>I|RRDbed&+wNWdKyURP`k#^BEaWwod?d0P`|3 z-~a#si2%aF!uK&TNwi7yA0PHBD|yIybjEb$<>dfx005By^foqFyjac6&GsxT$jHb` zvrG6lH#(|1Xu@dvTwL=tHTFbAV83D8+uQZ^_1ypf{r&y>`}_R-{Py(tySwr6@#Ev;)z#I-#l^k7z2V{E$H&KTkNS$B`(=yv z-{0Tv?)r0>_jQ{1{rvrQj`wtw`-Y$OgPHn>pZZ~l^#@1kYm52m>Gq1J`T!;000706 ztNQZt^z`-h>FN0U`}_F#_}kmt`T6FNFb z{r>*`A^8LV00000EC2ui01yBR000Jyz@AX3SS%(N&TQ78Ku(Nk)L>Al0tW)&!|MIM zKc9~mtI=dOoDJapig}vSIlaR@6mAehL=tRNI6FE!7dN zd@J3P04Wauo4O>(*?IKSABDqIg2{K~!vN>OBme4q?$1tHSy<-VS(SxFl8t()nOR+_ z82|tPA^8LV00000EC2ui01yBR000JxKu0YFC>9gQ*XA2tx8hJl#0*Mp>0Sg0!8Ut&I4@2FfukLorfVND;ysdus$jd6&pV<1`G%tV`Ly8Bp4YsKNA-K63NLT L%*+xME({S;F)=14CLS9-epOaZVqkDu>-d|2;g6S>^(yPXxw#C% z48dE2V|K+PCnx*(_+)2iU%PfqW03}fJ3~oHiL0w?aB%Q%7Z<77(tm)Ur-#9U;cr+N zgEqsbPoFMcy!f+k;)|T5KXd2*NlS|e4?lnYyy;5Qf3s%Y4fa}6U9C7@@t2F|p9vH8 z#KcUQ9m|lwur<@(V3|SEzNA0?{$IX+wODSE5FK4vS^4?%=N~_QeETpBlj-E-sawYi(g7&(0-fEUvB4T4f<;-Nn_YF|o2; zPR>G=U0K|KnT=D;P)JBiLV{D4T~W`7mzRf!dD(JPQ(0DSeSPjD!ot!gWKYRDGFSru D;P{a* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/jp.gif b/workflow/public_html/images/flags/jp.gif new file mode 100755 index 0000000000000000000000000000000000000000..444c1d05c59ed6a43e63fc7cc7b809f47422ccca GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h`8zxI_V)Pr`0wxU)6>)K?d|L9>-R4&_%=4><>lAc z*XQTw_9`mr>FM3w-PP6A+uPgwMn>P?-}p5(_A4v+G&KBGRoU6u`8+(~%`awbW*4FfWef0J9{i>?b(b4r)RrXt3`~3U#lau|syY;)f{r&#= zmX-Riul(uh`+0f%et-M>`}Fkm@$vD`&(Hb!`TF|$_xJbw{QUj>{qpki^Yiom{{Hp# z_5c6>A^8LV00000EC2ui01yBR000JyK%Y>^ zZ-qQvx?SNNBcTYxnl_dwY83H$CD#LiO|W?MqSQ008AJGra%+Sy)(L zKtS_hW#AVdH?TYMU14m)ZE#IZ=jh_q*T3uM=grE>+tbJ_q%`yK@!;9cQBhGDp&(aW zTmS$7A^8LV00000EC2ui01yBR000Jsz@KnPEDA};in72gNLW1HQS$WNE|=TG!hQU1 zqmx*N_}3(3k0 GK>$0)Ly?03 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/kg.gif b/workflow/public_html/images/flags/kg.gif new file mode 100755 index 0000000000000000000000000000000000000000..72a4d412c805708b5f27c5a38622a46e86a14cad GIT binary patch literal 373 zcmV-*0gC=dNk%w1VGsZd0M!5h_@ztrYismlWAm3S>^nQ`D=X?MALtqy`N~7;BO~Mh z0Q7}9_QNy!)z^Sy}N#MfiJr@?Bl&Ha7HBRP8Y_^G{Frd3otEG4X{f_I*qA zRZ;RtLgy?j^jT5wKsN4QBk(~w_MSWUl1B1aSopv?^tUSXQ&aVKO6@otQ-kt?Kxm(j!%+|jWD|880;3=hGc0v?6DBMW3lJ+U92_?)1pojJg)9p* zFDNT9Iw}edk_CkpGc_D22{8%@3J9SS4-8^tW;PMGBO^TlAXYzF9ykXF1UWe*BmqiH NOc~A@0nyPx06Qe4k+A>( literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ki.gif b/workflow/public_html/images/flags/ki.gif new file mode 100755 index 0000000000000000000000000000000000000000..4a0751a221904a25343137a7a4a5aef71e112f5e GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5h@rQbxtlas-yX9F&_U_%w)9PDz%0^j|=-Axod}+hX z=jr9+wZiA)NjCP*$?R@k%m4sugwX&3cIsqPe3aPF*X>qgj_Sf#^yO0uE0F15PK%z~ z-Z&)b-BpmK;Bbl4VSUc>-FyH5SHA!N*4*%_xZmPJFEmV*2Fo_ z*3sn7((l~9Q)#JVahYm_&5fD6=@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/km.gif b/workflow/public_html/images/flags/km.gif new file mode 100755 index 0000000000000000000000000000000000000000..5859595e809b6e8a98704cc408a7267920ad3e80 GIT binary patch literal 358 zcmV-s0h#_sNk%w1VGsZd0M!5h01oTx)d2YTQ~LV)mxr|gYXJ84_5A#D>GSE^G#2{$ zYS`=8Xr1@rNGhkd+*cC>-6gY0NwH0 z003D4A^8LV00000EC2ui01yBR000Jqz+1paEE)sIKtVU7P!3SVWh$sDAC{b~gnq9G%<3I~Ib&TxZo_Wz4GoNldUwcoQc+PVr+09H^hX}@W4 z$7M{kOuDfv^id$~I{@0++TY*cX=h@foQj5lTxDTNZ)#U`Z$igy0G*nShJt3@0001q z00000A^8LV00000EC2ui01yBR000J$K#gzcix?9~4dBO&K%OUyg~VzZYz-9Z=Ys^k zsf(+i7|j@BxE&= zfD;Y}2OkwG5e67L6dfQd5*3^uo+`r_g2Jw5vA>G4cV05t6HJ39bN@c<6qBz6D!#KiMNMeIXE04C?|QdIlO%H{9> z07CBU008xJbKL0q_H}mli;Lpz{`=nD`qR_j>ip&>-Kkf?qp>#egEhb6n~@L!P)=#kB|46ne}gQ`^d<%&G+_& zgz!;PA^8LV00000EC2ui01yBR000Jyz#3&pF&GI*f<(fR;5N{WXj&?LJ_tlX2FuMr zJ5OM&P-K258UXfsX&j7@#S%%e28qiW#EbECBM)_V2?7lO9Udbj9wZI{c6b7Yh&vTN z6(I}{gp)QdhzAE6438<20yZcuh#(3-4<{E55iTtQCMJ44S6EsF1uDV|#5YPz91su~ M%quGs&?`XzJM&4QW&i*H literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/kr.gif b/workflow/public_html/images/flags/kr.gif new file mode 100755 index 0000000000000000000000000000000000000000..1cddbe75b3087d8abe0be4845b8339b490d1f713 GIT binary patch literal 385 zcmV-{0e=2RNk%w1VGsZd0M!5hbeiF&rli!=)A@*pe0+RUYQ_6SMf>yfXlG~P=jHkN z`NYJ;-sIx-_4V1=+U@f4{Mgv(>FJ7!ipSLL%F4>_4Co$*W>Bw*WcaQ;os%!>*ww5^7Q%Z@$l2x+34={uCTDs*VScizN*CV-{0TH zd6Uc0&-1ah(9q5D_4W1i^R=DBqpaE5+}zL8(a+V>{{H^`{r&Xx^z!oZ_xJbw{QU9v z_5c6>A^8LV00000EC2ui01yBR000J_K%Y?9={z1K%}De~FnqtCW1-9CdcEC-qToG$ z5ecD|gFqAx1i`@z`EU*i>M$@E20IjD(Ez=15iu`z6%_*-4mu4O9XMA#GlePzEj&6I z4IU3y5i%#DGxmY1OX%fq5vlW92*%oB|R(z2m(A46FV>*2oyUO8a)aN fC=on74Gj?iC_BeXO$-bnAQ&bdDK-`sEMJYmMn>ov z8Bb47;^E>l>J20u+s5T1;X@Z*S%*UzWbssOwF!_RG6&GQb!{>9vG+m7@|Vx4Va?&x;h|s8^>EksaoG6! z)kD0~h_BI+aM9+z*OX+^^?1j!Y1aFT%dCRUyWhV6pVFt_$~foGMu({bf!E<)&gZJh zcmu!xA^8LV00000EC2ui01yBR000J)z~48ZQ0cPx# literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/la.gif b/workflow/public_html/images/flags/la.gif new file mode 100755 index 0000000000000000000000000000000000000000..d14cf4d82c62f716ee124e1b2afbf8bd79a41c0f GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h@;N!BW|MW1+gp6p`T6;WLw!AE%7&og%+>Dva&z|p z05o36ggkg`i`%h(sQO}J`dwX}Ta4QP0A+*K004**002pC%;o9xEm*|-Yio;0fSXi= zWQ5rMdV2LlMC||ou5z0I7PwV;)8qgE_fk^#O-=Y#SMe_|03*I%f!Fu<_ic#Qe>8A$ zjoVOl&P#I9?eO<~n&4@O+E8@RvUs17PJ)$HiA-?KpJS82kg@FV_MTsmO#nY_15fb) z0Q~>}A^8LV00000EC2ui01yBR000Jyz@KoaC>DLl&*#@^b`pt9=J9}-NTp9NN27s2 zfxs>j*=%Zo3hK~m$R+{=Vr8it29&j%!+{Y97c&NfA`~G9G8_W}e*`KM3kC}=hA|u| z0|Ppa7ZwW(7&n!eA}<_r1D_Ze78E=VIAb<78U+luEG#t@3RNaoB_19C#3#lQNIps* MBh4cc(9uBvJEn@1%m4rY literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/lb.gif b/workflow/public_html/images/flags/lb.gif new file mode 100755 index 0000000000000000000000000000000000000000..003d83af5e0ac0bb96a30dfa4932a43915e3fba6 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hD%NwCGBEU>P{CMGEg1KS zeDQ2t^78WW^z_5R!lKNh@M2NS003L0TlxC>(*OYVfpqR(PCb)7+W-Kx0092|{q0*y z=0r06{r$uM0O>_Cz5oD2mPARKO855m_4W1hdTsvx{`2?sg}Q{x-^=AcF8%xb?N~@C}y*Yt0X(b7Px_hsW==K zScqkVAP_zl5J1Dut#+tdU@{^ZNDhF>)amse5+XJyb$5AuelQX`AtEVucLe}_JvR~( zAr~Pu4F(Jbl9e|TCjl214*@(3p9K^p8!TlnA1VR@3Arsk6jxbevSu$FDk{865gr~O M%o)xZKG8t{JI9i#CjbBd literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/lc.gif b/workflow/public_html/images/flags/lc.gif new file mode 100755 index 0000000000000000000000000000000000000000..f5fe5bffd2017b1a599d94b4fd5745098fb0e845 GIT binary patch literal 259 zcmV+e0sQ_)Nk%w1VGsZd0K@-TAu z@%Gn5Hf!~fxAkFQm2{o+Dq`bplkGn{JYR_JahUI(!uQRgGWYE*V~z4EUfn8R;k)Ab zD`W7m!s?EOgeqX$A^8LV00000EC2ui01yBR000GmAO?&;VKN1yG8_X0a8NbdhBOVL zLocom1j1wRpil(7Kn@{Dcsz*+MWH~xbchE*A|YTR3d}%LsOSWU0Jk&1U?vZ;S@1|W zEEY#%!l%dubPWa<7X||W695z$1q}iN3LOWN2OR~85g80V2n(K{3K61=DjXaTs2Uj` J8Lg`!06T6AWa9t; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/li.gif b/workflow/public_html/images/flags/li.gif new file mode 100755 index 0000000000000000000000000000000000000000..713c58e1df193b0256be462a3437c95af926e600 GIT binary patch literal 359 zcmV-t0hssmzVQaqZh z!vGnld1aW&008t@L+xl)DF~@ zSCHT;5Aa4W>|sowk+<${TPX`+X;O^vO*e2`laHREMR3Hv!KX%Z$msw8@N{DP;A8aM zX8-^TA^8LV00000EC2ui01yBR000Jrz=d$QAQ+E?OlA>Ms8Tt_X2aohIv2n)#4`Cr zE5OHtlNd0c?Wre<+{WcI#k160vSM8vL!sa@Gcf~$0}O^XEi@n?3_m*-BO?wDH8n3K zB?1BvH4O(AFbD|=0R;sUnh-7l6$d1uq^78wE+_@9JTfv5FrlykrMCye4aLR{70Jp$ F06Pnflbiqm literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/lk.gif b/workflow/public_html/images/flags/lk.gif new file mode 100755 index 0000000000000000000000000000000000000000..1b3ee7f572ddb8199166f65e8803233cdaebca1b GIT binary patch literal 377 zcmV-<0fzoZNk%w1VGsZd0M!5h{+C$v(@WyB7rACo`;AEGyd>$jN1;4ZaHnYW)E}!% zW?Y+G^2j5eHA(i>Q0~Vy_uOQ;Wiqo`Z25*h^Up)ccqB}aNb$@)o-{hmhC;)6bf-mJ z#BUqfm@L|xL{*nm?Y}d(V|1=kX0cgR>%uPi*;JV=LjIy<_SHC}K|J~2a`o9;{gO~b zj6~k2Kv9%W%7Rquz-MNmW!9KB$9p@^f)K4vPsoC6u24#^QeDi1F3^N5-J&1%*HqJz zNBP-TA^8LV00000EC2ui01yBR000J-z@P9}>Ny;N0EKe7JRUy;;&f8QG@+10A{zKQ zKiL8RfM{-9MQ$?~?ZV@-L}7q=JQ>`fQW67L5OW47AT~1*dp!#uECeee3Md&M1qnJ0 z6%Gq81Oz<_8$Jx93>YRH0Us6w6Al{(12i2GJf^5GEfW&~BLfY;CKwSZ9274Wx&baD X2f!vN5j9Ls4Oz$U literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/lr.gif b/workflow/public_html/images/flags/lr.gif new file mode 100755 index 0000000000000000000000000000000000000000..435af9e506f70a8cc09022ae3029373facb3ee0c GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h;Ami@006B30N!R@(LFP>wA0{cU&H_a-eX$bURAaL z0L}mag@?Gl00885ZR2ri;caExT2b3qO`HG#003CoRZC`RrPfSB{{H^`{r&Xx^zZNW z_xJk9006lF0M}Vh++0%OY-8tyeW0Po+gVT3L^<{6<@f99*ic8`Z)VtERnRakXhcp5e|E(;u`37noK1Oy)wCUthEk~66;OHB$20>uHx6B9o_ GK>$0mai$so literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ls.gif b/workflow/public_html/images/flags/ls.gif new file mode 100755 index 0000000000000000000000000000000000000000..427ae957e508a6c90df90c68f2320b119bf372e7 GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h<>loTn-%~u03Dnr01s_coyhC#>_wKu-`(3QhPvwU z^F*&lB9T_py_GPCz4`h1JF7bYL;y65zx(<2`1bNAe4D>{miq3 z-_Wu>lENi^wBggYHmEi;rZV;K<^25nD1x_as?K<^(Hx*0%H8JxF@pd>jnU!i)xevM zzS{Bh_0hVG_wwpkqRl_4Nx00`OQv)D`};(Zy>FefA)7Sq=GVrmdHehO>FMeG{QT|h z?fUxqA^8LV00000EC2ui01yBR000J#K%dZOFz|SQBw{&J`93faXQa{edb{7FRUr5% zuMMY))hZ4N8^O@PSTMEn1Jy~8Yyw1swb43i7#0Q1BE`QJsoDir+URq$bA z_uD)C=X3hyYxl|k{nP;W-&O5BJ%l;7{1gcNpq%=3ZTkB9`1tq$YVH6;-d(c!gv9#*g7BZ7tSf@AJVX6BGjjJwH7-dJBDjfrEu6Jso$1Tgt5T@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/lv.gif b/workflow/public_html/images/flags/lv.gif new file mode 100755 index 0000000000000000000000000000000000000000..17e71b7eb6bb2dc4f4e63837cd70be048d08f1a1 GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5hu0lhpG&H(YRP5Q=oE#jaGBUzzYjgkrX8-{F{QR*- zMp^&>@!{dhdwRxlbG1=Xtv)`;o}RKwN~JC?>B`FV_4P>r0O{7&zFb^^008>>`uOXBfMEz^Yiom{{EO06y@dR=+o2W&(EqnJnGli#(8&0BdeM3Si~wcH zWdK_MOTJ4`!BBF|a&F9S0A&DS#$i#vQ6;V=O}|YrvoJcgI$_CS08#)|!&QRRg8)SU z089W*z)n}gS2eUXe$#$x%4$KkK_IIjJ+wVHwKqAlIWMsNmIg8Xv}C?!dXPQLsh_4fYX3GxH~nqHaE66Nxn%-yh~lg zT>zN?A^8LV00000EC2ui01yBR000Juz@Jb!7$g#cB9w9}<=Yc$F ziVG}|X;27;)=uKZg;V4P1KlcBD2pHH0x!=EIXV?6G7AF;eR61lgA)Z912JSBb1oJi zjUyr)2@W%q1ePBsDib3BB%BW&JfWAQrT_pY8vP*D9* zQS~Jy`a(kaR8;@^dKPd4Gs57O6~vv^*%l3008@8Ve~pW`bI|jL`3=k0QLX? z@&Ew-Sy}1;0RMY?^dBGd85#F5F#Kw2{AOnQU0vb;0Q^f!`$|dqJU#O=GW}Fk-v9vl zIy(M&dHO#;`B+%Ga_{m6nG9Rd>Ax1Hw1McAs2WLHYgY` z6f`t43y=joCK@A_FD-PPAq530EE*&kr2`0$sSyzdEE`%}2@)6r6c;-x1~NTMO->#j N6%{5XEIrae06XmGiQoVL literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mc.gif b/workflow/public_html/images/flags/mc.gif new file mode 100755 index 0000000000000000000000000000000000000000..02a7c8e1bdcd38bf6ce52dc5662d1d75026b67d1 GIT binary patch literal 359 zcmV-t0hs(J z@$vEgU0w3>^YuSJ>gwwBW@i0#bo***^dKP5&(G)Q=lpMP`cF^&aB=!vT=-K{`Bzu= zL`3{$W&C$|$H&LX%gOm?XZ!p6`1tts_4UQY#rF30`T6<%008sz^ZNSw_xJbo^z`!b z^8Ww;A^8LV00000EC2ui01yBR000Jrz@PA!E9NE>gVJy~{5DXBD0LdS3M$qL<=k{S zh{`3QSTr7xNTLfClg;P|r6tKZ!sGHeO(A{i3=A(KRWbzt00RRFArc$`kTW|tG(0yo zJvu%;8Xy5Pl9ZO1nm#%iCILH>m6w@592`D27@?x0nI1l~7`*}l78V2qB^ogqHZV3p F06Uswuu=d3 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/md.gif b/workflow/public_html/images/flags/md.gif new file mode 100755 index 0000000000000000000000000000000000000000..e4b8a7e3f67097d65193a435018d68d1a0798af8 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h-B3dS0I{c(RP^B~OJ~w#ecS!+UE*X}+e$s_#sL2E zdxMwa_T@3wGbO120GfwGY=qpl008>wOY_(!ev{(-?r8k%RQufk<-GvrZe-g=IChNQ z;8;xg=tTDAJ=7~4{L%o!0032S)?azq+CVawgFOHMpV&Jsp#T6{b=dgkK=$QK zj7na3)ioRq>SWf5>VEgl*qCmap|6ni3lGcpehgbe_P8#y9A z5-l$}B@8DGl9ZPO9V!o<1E3!WC;<>Y1TQKK6B9hCAFHij1uix=H7g!8Xlbn`$R-I1 N7|j?CDA6cE06R$cn05dF literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/me.gif b/workflow/public_html/images/flags/me.gif new file mode 100755 index 0000000000000000000000000000000000000000..a260453c2f73f32c07a75de3dcc5d990fceff33a GIT binary patch literal 238 zcmVjVnU0|@E6KJ?8$=pz#6vOEuFvF)}# z;jSy>oHOJA2LItkA^8LV00000EC2ui01yBS000GR;3tkw=|CuST?pX5upkRc``kCB zQ&LacI7(;X=?w-y04{*ZbTFMGvZmApHX4mndfx o1nz;Q5ovVj2NQP^Qb%-vf-^D)jE#*G36YTzlo14%m;@mJJHTpU4*&oF literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mg.gif b/workflow/public_html/images/flags/mg.gif new file mode 100755 index 0000000000000000000000000000000000000000..a91b577d138eeaa5d0f9bc8a00cee9ddb3305062 GIT binary patch literal 372 zcmV-)0gL`eNk%w1VGsZd0M!5hO0r5Eo*epARO$c#>gwt}tUXz}TK#Kl05$;iBqaAt zOy=h1HL5k@;^Nxc+S5HKFQqT^007W49sB?Q3zZ81D*ymT0R3iW`$tFmK|=XFJoq;@ z_c1Z{D=Q?TB>YTFGo~^sq$(7d6#4o2?d|Q~-`_T{HrGcp{9s`hq!%KpBKAZ?+fqQA z008=2T<2$9^*=xTaB&cq57$mREw3&6{QLd<{Vbv^{)L76`}_U<{rdX){QUgy@9+Np z{{R2~A^8LV00000EC2ui01yBR000J&z@D&2ni!3dWMnYt{eC_lE_OIvP%eQ$(S$}1 zf)6I6*>F1CUeu?%h{@(oVl^N|bvD$vd`=`_0|ab5JTELWCnpaN5)v~l1Ufu5IR*s` zG&CwIDJdov1Uxx8I|d98Aszt%A~GNd3p_hJBLJwXtTGf36$_*zBL)Bf1(ysU5H}SK S4J8gG7SR?6)D_kUK>$0+p_E1d literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mh.gif b/workflow/public_html/images/flags/mh.gif new file mode 100755 index 0000000000000000000000000000000000000000..92f5f485c3bb6e33dbf40656bda07e3742c071a3 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5hxy0R=s?qhQZg-KxskYMq0BsmTlZ|k9L}{`3+q?h( zR7+~BwRBrkbh12StM=p2001wAo5ymG!dYjT_kl4(W29SsxmkI%WrDf@02nq~q5l5< zG+3T%hPy{i_^kXs|~^Yw2A8*Wm7JgR#$@g7wX=EKr+wc$#u) zga8S9A^8LV00000EC2ui01yBR000J$z@Jc9C>9k+r0W*}m?8s-MAX4pF1;1)7uak9 zmqsJxaa3M2*zHH~2F9V9!xy6n9;ZTt0KkM6H4_YWC?6#`1p{Fr2sH;XcON(r7Z3#! zV+eu*2`K;_JR=$z1tNb3oFoArAO^0Z1sFX#I{*?IAi1t192p8MEd&yO3mz2}4jLT2 QHYx>35Yf^Z)YL%$J4-p13IG5A literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mk.gif b/workflow/public_html/images/flags/mk.gif new file mode 100755 index 0000000000000000000000000000000000000000..7aeb8311b2b6a4e18b278d1774459e57335c1b76 GIT binary patch literal 382 zcmV-^0fGKUNk%w1VGsZd0M!5h{8?7{*f{@h0RED8_Bl8G+;I4bGyD4h^Z)?$ye#Pe z0Qq@4_{>KBb#?o_NBKub`-VsR###JvPyA(N_xCySnG)&h0Qash_NpfT`gijf82*1* z_ADp->r?wvO!Pn?_H8-zM>O_oC+#-?`<6rdZCLqcNA`9q-v9vgEga~^0QF4({Wk#o z;{ftO6#bV`_Bbo@S`*#f0Q2S={CH;j@M8XmS@vBk`Mx>y*dOuA4)WtH`maL$zf}6u zUHXiT c9uEu*1koW0J17S$NebF3Dhepy-!ee}J1K9L&j0`b literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ml.gif b/workflow/public_html/images/flags/ml.gif new file mode 100755 index 0000000000000000000000000000000000000000..53d6f490c1777de4f9d44195d5e188cf2a35db0e GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5h?Da!Rv`Xjz0BXW&`22I|=m7luY4kBM_en|lS6BS} z0QD>^^Bf!ihyeE3D0<0y>GL=BBqUL`QS9|j^wb<&y<7l#0CL82I;uJVXaM*3MDi08 z`T0Bg`a$^kHT69`Sh`sNR{-%14e|g0MX^Qu`$zZpFZT8-{QOMy^(0idRNw#r{ryqn zqX6&tQ}py6!4O&4|n0B#;M4t{?E78eo$BmjCQCk_k@ z8#yZ$1CTlp9+W8*m>UP110*^a5TY*>8zLg78C)PL6EPYZH9ci!KNcAoAt5&f$OSDc JD?iRb06S!MmRbM+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mm.gif b/workflow/public_html/images/flags/mm.gif new file mode 100755 index 0000000000000000000000000000000000000000..9e0a2756d2ebf850087f556cf77289009985f3a1 GIT binary patch literal 365 zcmV-z0h0blNk%w1VGsZd0M!5h`9nkXB_-Y6`1CwI`dwZ000610?d1Rf_%=58OH1ki z0Qx>Y@=a6#0LOiO zmFiJU*Kly;czNVTM%}@|@=HtGMLW(_Sl(S&*Yq|v`$$OfLrQFA+Hq~)c5>d`008X( z0002PA^8LV00000EC2ui01yBR000Jxz{c+1@_u`KpBFCl2H5} z6@dU{a^V0ggeKDchQ~7wS}h4+4h`5NWvInMX&QAM0|z8LHaaI9AvAOW9Up~0Dhv!c zIRh+$kRK2?2OAz|3nh<{5D+3G8z2Cs2oZyx7Z(#F1z8qb2^ataH#Z^^6Fo~!J_-s4 L%p)T`&_Mt@&VP;h literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mn.gif b/workflow/public_html/images/flags/mn.gif new file mode 100755 index 0000000000000000000000000000000000000000..dff8ea5a63f0a3ec96dfd0dcb95a0a7abed8083c GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5hK|%Ta+GzgCTz7N&^f58_NlE{EdHYpV^(-tZD)v!P z{qr0g`)FH4IPLW$B>d4${Aft?00000>He%%?EnB(N%8z!Tl!r+X=(iC008n66ZJhk zFfaB$J@rRN`ZYE9@eK_C0Q>*|);l}-OicXw001N;_22*iT~hJ;*hC&4^z}A2WnlLn z8SehbdH=P0{@ro=abhYY@cxH(Jvj0tAMZ;`_b@B*`m#j+-ds&V?)h6){ex89008{} z0RI30A^8LV00000EC2ui01yBR000J!z@PBvlZ1{TNn}Z({0uLHVKBg0S(d}0;4}yr z7LX O63r4KCnr7AK>#~`43F&q literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mo.gif b/workflow/public_html/images/flags/mo.gif new file mode 100755 index 0000000000000000000000000000000000000000..66cf5b4f05dc02126365be46762113446f171a8b GIT binary patch literal 378 zcmV-=0fqiYNk%w1VGsZd0M!5htJ5t>eK)_ z0QC0sQngY=u|?YK+Iq=)am8`~g8*H=UAEn}m(P~~SpZMAPXI{(M6N^tbO3P0Y)Y|8 zF{LnGyi7l?KRT*93zZ81EC3pu8d|!738K-oN;DY5a``m@aiMCmJs`=!Yv%|;$A$NP0yis$eeV4+6o4SOY!gi9p zM{BlIcBwmInnGuu001C@l!%F>i0sgicaElSjJR!vwDiBKYoDF;_+o*uV2ZQ2#p3<#r26otkD|Afrn#QA zrT{I0A^8LV00000EC2ui01yBR000J!z@Jc9DGrW@Wby}S0t_sN1J>IRN~QzTvf;G^ zw9^DZx#}tgQ1uJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mq.gif b/workflow/public_html/images/flags/mq.gif new file mode 100755 index 0000000000000000000000000000000000000000..570bc5dd18a8cd881e03c9a56c3ebcc514191fa0 GIT binary patch literal 379 zcmV->0fhcXNk%w1VGsZd0M!5hTXLl}RGv_4tisCRo~+NNwAAM6@??9o{QUgT*5k_3 z<+j1v03U?2z1I2p`2YfQ=H})A05XA<#O&_!U3RgBn8lT)&AGzb003F^_4Q9`sk+79 z)!F8Zoy5)5<#~_6003wJ07b~q;?UUXLSCYGjK03e-o3`%_xJh$02lxgeZ$M$SaGn5 zoykaLr%7h0`uh5Eh`rk0=-}n>)!poAfw|q{?_YSayv5t;>FMF-?bh4q`}_O$_V)e# z{rC6xA^8LV00000EC2ui01yBR000J)s+bJnQ06YHGuI>N; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mr.gif b/workflow/public_html/images/flags/mr.gif new file mode 100755 index 0000000000000000000000000000000000000000..f52fcf0933bdd5a8e30a1d2f7d76b97f728c9ed0 GIT binary patch literal 377 zcmV-<0fzoZNk%w1VGsZd0M!5hfXF0h!e{`M05z#K0E7ThwNXT_L_@GK0BHc&>@Y2) zEdV_LGo>>Cc>sFJdH_lQaKv#rmpNj-VqLyn`ujyqt4;6rEkm+HBcUUs*-C4>Yd)?% z09ybVn;9mPCQ7wRAB!JPwogj4N;;}KSh-nLxKwt?b`+Wv04D%Dt~*`4T`rj}g2^NRIXC!;d4wT zq*5W1F>D3{g^24V?FtnNg*G@SFop-gq>J@F1{Wy|3@{!T8w&&wB^5F}G!YRm2{||& zBZ?3qA2SIyEiE+(ARQ+I3k?Au7aI{Q78U@dCpQc~s;wylD;^%SH#Z7D2v=bRA_it7 X0}KiZC=E*-91qqD3qRT@3qb%oq~mv! literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ms.gif b/workflow/public_html/images/flags/ms.gif new file mode 100755 index 0000000000000000000000000000000000000000..5e5a67aa882715433cef156d6586341b5f50c8a4 GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5hX)9;rcXyqRRA+R#002$RY&qox!(I;tiatq!836tfEpCMGHrtpi#hprWH0 R%*0Gi1Ps#B9@W)B06X1&k5K>s literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mt.gif b/workflow/public_html/images/flags/mt.gif new file mode 100755 index 0000000000000000000000000000000000000000..45c709f2bc68af31bf62940c2765474f1798639a GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h{9|M0=H}JY)8gXd+}zyq6BG0D^7T48^Z)?t008nX zF844n^(7_xQ&aH`4fjn=^*%o4008+yLjL^y_A4v&A0PNPHuW|(^BEc9008;`0Qo#U z^D;8u008*-`1kks_4W1d@9*vH?fF+%y|}p4$;rvc$olW^`dnQ3OH1=LHSgWs@$c{U z>gxP*a`^4->+9?M^78um`S?ag`~3U+@bLHR?EUri-2edj`T6_%`}+F&@$vEg{{H;@ z{Qdp?A^8LV00000EC2ui01yBR000J#Kpu-nB(5|Xgc6ZRfMkMSulKvT007je@kkg1 zq!RTPYe+Vh1tsO2n8vwT33!M%Q3az80A1@CO2Pzy23OFzU0RsaB P1SJs>85tco)Ik6{yXCVQ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mu.gif b/workflow/public_html/images/flags/mu.gif new file mode 100755 index 0000000000000000000000000000000000000000..081ab4533607939fa2bb70838fc34e35024272aa GIT binary patch literal 358 zcmV-s0h#_sNk%w1VGsZd0M!5hXLpgiSZP$WRO4r7SZaqkShP8&IRH}tsWeF@M5grg z9I{ASQfj;R_bo=PMwrei`}|AYQ&U4-vj8yw`};!q`8v1&07+!I$^ZcJ@)M-iJ^lS{ z02xc0(JTNK0F%ocb%UJr^fY*j%c=kX=5TR}#tlqfeL7RE=z4lqal!oj0001oFQ6~@ z_%-$QB#@o3T5!GL;Q+~dh!2YZVYvWbx?nF&tVsX>hX4Qo07T(lUZ~kbx!`7w$P=H_ zG{XP@A^8LV00000EC2ui01yBR000JqK+JDAv>1=0ttvyIpt@ zV8r6K62V{$#zi7IootDOBv($Q)aydQ2AAhJFCc;dgan2JCMEzLDjN_G6ciOL4Gk^| z3K=0WjgXR*mY5luF*H0o8X7(w4-X$7JtZX%GY2&_0=W*m2E8o59tXn16UD|J$R0re EJA^uk@&Et; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mv.gif b/workflow/public_html/images/flags/mv.gif new file mode 100755 index 0000000000000000000000000000000000000000..46b63875b1fb72f602ec068d935042455e4ed795 GIT binary patch literal 372 zcmV-)0gL`eNk%w1VGsZd0M!5huG&JNjG2bX7 zUf*8qWL@xAR&wZd>Hq*(-dlR?e&j4S;mhrjc|>04A$;8)`S z0OtSzA^8LV00000EC2ui01yBR000J&KoICh^cj7XWaYvHNuH9y;BY_?2%g5`;v{rB z7+xY_k&Q@zMWCA#i9Uv10T*cjAc5Ziqk1!D0yZ}hCL0QQ10E z4K5!A3<5L;Aw4e-84i~V69ok&Ius@_FEym52oPo@8ZjFiD-RDoF%A`09$5$1RfRXqB literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mw.gif b/workflow/public_html/images/flags/mw.gif new file mode 100755 index 0000000000000000000000000000000000000000..ad045a09c124c010eeb1ce5adf28a3b5f28fba4c GIT binary patch literal 364 zcmZ?wbhEHb6ky*$`1tskt};Cv73Hj{sjsj9l!1YTh2fi-*-vZhJO+lp3=FYLT>tp{JFRo-FgKeO z8=H10ZDC~Ol9G~$h4%Iv?WGsUM7y{oF853{H?QBG)m2&PGtDq@UsAD?lfhC0<;BVj z#tcB9_>%=hG3bB@ke?XXIuFb*@UWWOb|OASveA--DS+GID~IwG@e>Cgz7aB;c;eS# z$*AZytAk!GPFv(pDNbC$H~Z|;EgM3##FdN7*m-%?YU)H;8jH)@I%?}#SX7mz%uO{7 zB_u34I2ac(TB@+>@f!)t3kcX68#8aR;bOHC5s{SS=hqfqZDS*_m6cWMxa>(;yE9x| Ic8(0z0Cd)M=l}o! literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mx.gif b/workflow/public_html/images/flags/mx.gif new file mode 100755 index 0000000000000000000000000000000000000000..ddc75d04d8f2b05b315d7960abebe0604fd9e1fa GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h=W1?MqI7z=lG`;q09yu2oow7kOSk|4gMO=WUGP6008&*_j9z3-aSIuFE!ygI_=U{QTe5#NOoIjeTn0 zPgCSzWb*Frqq3jR&(FZHllS@f`1JJRN>BCo_B@ne!esC^{avh*CKMIRzCIsgCw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/my.gif b/workflow/public_html/images/flags/my.gif new file mode 100755 index 0000000000000000000000000000000000000000..fc7d5236148edbed734df8a666731eabfe88968e GIT binary patch literal 375 zcmV--0f_!bNk%w1VGsZd0M!5h^ycRK@$vKMn%&Wc>gwrCP4ndB-bGE;007*krQl6hwg3PR2bl8W;?|v= z+c`t-!oudp#sC1t-m0qLEG(0d(AyjwOiSF{&w|6PC5LxQv8}`L$Hm>dyYA)gZEfLq zb;9-U_3P8q_ut>$)TQIvp5Md6@#pS4JK6i^<@fFF57%;0^5q7T=u^K8V V9UTu35D+*ZAQl!qJsTTA06XF)t_T1C literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/mz.gif b/workflow/public_html/images/flags/mz.gif new file mode 100755 index 0000000000000000000000000000000000000000..7d635082a690908e3fb17ac14c490b6e39eab441 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hzn{ItTgr0 zDoM0SRJv4k$#wbKH`<7D=i|-KQCR?l0Qb{IX~JncI6L;oUi8m7`$Jo91@Pl4&nF6HJ%NMG!|np7M&mJFnd`S z;Dk7V)%HGxlDY(F!(afG;L$pKA~KIBQ>mCt9zFsFHx?imJbfl7Cn_oxf;$!uh#4y@ zBqTa1DJwod8WO{DxC$Yl79744z!$n; MATw7ID zxc~r<05kw8qA8o7*lKFS`8zusoEwLP!}w-x>*4D>t32W0@A!#{^3v7p>GAk@cW`jU z004T%z`N>543qa92rdRbTTX? z0zpAR?ol+JQ4KNphQ}Za=9GS^I)opnFrH;D5NQ`CF)Iu|8ww8=E(w7cu10t>=AFvDtISC1?JS!^|BqSmt R4Zlq`It0=T)Ya5M06TOHp8)^> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/nc.gif b/workflow/public_html/images/flags/nc.gif new file mode 100755 index 0000000000000000000000000000000000000000..b1e91b9a80f4e4d69a3225e1dce5faaf099e0499 GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h`1UqumfigBbxln;GlW^1nnM5xtQvMkiKydqb4~mE zOZ6p91xLs897bA=+xIhAq;jj9Wutth<3o&Q{rp)beNdsHPy72s04BQtEdXStf&etz302BcAJz(Vk0GY1JkF)9aD^ih>H220taUFf^?pvR{s9m6a^}#yc z;&5DEKu~{b{JDF^sD}N%gIJMx)7Mb*^IoXOQ@7N4B>**Zp5W5ZnnsanRD^C$gw_B{ z%K!iXA^8LV00000EC2ui01yBR000JwK%daZU~G<dD>FPV6FU$1Tl#-7C literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ne.gif b/workflow/public_html/images/flags/ne.gif new file mode 100755 index 0000000000000000000000000000000000000000..ff4eaf074e9ffd097b3820ad9c56fdda7e336fd1 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hRJT99`H4pOc{Bh|001ul0BivKq-omi z-5Z!3)z#HJsyzPw{?X;pCZ8tq^78(xbS|PU_V)Jd1_1LS0R5U>_T}39IRHtqN&A&l z`OdXry<+|C;`!;_)#%mw`uh2@hWqQ`L#{(Jr8EBT<^QjG{fh{R2`<`I?)V<&E-~N_a_1VeylTP*H)-|X#p~s>8{QUIv z^!4@iA^8LV00000EC2ui01yBR000Jyz<_WV$QUh1OT`j6IVI49ltyc9a+Sc~a=C3# zC<0-%DijD6oXlkMct-Hg2ZPaJUO$Jv*Q<#J9268kK0gc*dp#*GWg>$<5r&9-DIpvK zF*Ae_5k3qs0yd&H3Z*O{AP)~9JO~{m4Gkp|5D*IsD!CH}t{nis8XB+-JF~k8$Os0@ M1_#Xt(9l5uJ4gkx9{>OV literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/nf.gif b/workflow/public_html/images/flags/nf.gif new file mode 100755 index 0000000000000000000000000000000000000000..c83424c2c3c02352efee0e63f4011be0129e2fc5 GIT binary patch literal 375 zcmV--0f_!bNk%w1VGsZd0M!5he5-s+lT5?Q!}a#{VxD6FD*%M8gf@OQw9T}|+Qs_% z`tkAcHlUu^q!s_no*yY$Qd@Ws`T^ev2YNBd%taZ)b&HerT01^PY(z-K&Gc9#3 z6Kxa8-N{OgN<@uBSejT3X$?GtJVJ&-Q zlAGcJh$&rKcY$4i6R$4Gs_pAt4c_1a2L504oCv VJZi&CO)EV$Is!d94Ngu$06RnPl%)Uw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ng.gif b/workflow/public_html/images/flags/ng.gif new file mode 100755 index 0000000000000000000000000000000000000000..bdde7cb3bf708d1ee0bbea86c0b0d407d708b691 GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5hddYe=r#ABU@?5=K?(Xhw#BBh20CL82GN&^2`t<-e z004ymFQhN^_4V)c@9gsI09gP~wovNu>HuT_Pqj~3yIBpE4FF0204xAXvq}<|5&&!f z{r&wVp(RDJMO3y_RJl|+syRQcKP;pyAD$l>n;8_E6ab3=`}_Mzv`N<1*4f$FT)A9C zuSCbw$K2-J=kDiNxmX~dAa}@jV83Blyjbh&>*(+3y~n*~z-IXP`276*`T6{#XcoB}a*Jd(-OcsFXEWzRIb^=!HL%Ey) zv_XZsL-`yb#3*xtia&y~kLOT#TJ2d4L=l*IIu9cqG9n5K2Otp{0&_Y)4;>^WAqoZs z5h)%5fImGFlO_R{1)3rbk39`HB_0>NbZe0G=U#X^llC=&nx18Q8b z*~KC;8kJau1Zed*od$yt1k#~x9JS8t$N%+uDLOef3=BLzJO+J#I3g%8B!)g7iF}M4 zA}T5*haMh21`-c&avcH!cQqOsHZcbgWF;*H5)~B)2s1MU83b5b3m9YyB`#>ZOHCgj M%mL0B(9l5uJD$t2%m4rY literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/nl.gif b/workflow/public_html/images/flags/nl.gif new file mode 100755 index 0000000000000000000000000000000000000000..c1c8f46d0c328cc5ceae99f0ccd7c5047ae93d83 GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h00DIV{{A#>vH&5E`eJhySf}*>0P^zk`uh6#`1tnr z_WpW_T8hK{U28>qx;k>TDrThkJd0frAGJ zJ|Y7!3?LsJ4jT^wArKH68x{Z(4k@EDry2zX92_AYs|=l=p{@d?5V!!t7{$dF$R5fb GK>$0vUY#BQ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/no.gif b/workflow/public_html/images/flags/no.gif new file mode 100755 index 0000000000000000000000000000000000000000..6202d1f3a2df4184878f5ed8bc23aa630d43c061 GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5h01vKZmEH98^zCF}`uh6sZENy;dei^_23FAb_xIv4 zFM6fq>gwv0xa;FBE9*^5?Ot5H007+=6wLqt>r_(O008MkL-O+Sq$r8H8S8KAKx4qwEzI+G%}a&g)Y3x25QbD!hlDJJ;%`1$$yu>b)6{{G_A^8LV00000EC2ui01yBR000J+K%cOO_*IUTgL1<384SHfuU06)29OoSwQzVEFmNnFct&>I;*X(EH(-}2Ut4`IvFn*G%YA0 W3NpY46Bhss8xhtKBqTiBK>$0|z?fYC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/np.gif b/workflow/public_html/images/flags/np.gif new file mode 100755 index 0000000000000000000000000000000000000000..1096893a70f475c9407efff0afe534deec81af54 GIT binary patch literal 302 zcmV+}0nz?PNk%w1VF>^W0M$PL2MRYH7*)Xl0KxzO+yDR~9Bd&n)-ENh5gT<88gd8> zINksN8Wle0ZEZ6t#ugrb`|Il{H_R+VwCn%?>V17GBAM6#0QS?<`sU^xC!PigHt+xd zCm)0Ch=}A}T_iHP>VksM008;i+zJmq3lK*N5Jdd&@D>s_`QYFZ9C)t)039us#{dBO z!001*8$=^#$@~*BhC%Fp|N&D*RKe$V2vVE zgga)E<;rVZf~hZEjT=pYS$?HpgsSP$e0P?%02^IScAi~k7044wcNL72H z0022XXp~BFoJMb%ex18}nYmYeqi&C}YKyLAhpKdxwBY9LVuYq;h^v#U#7=ji-oaQ@ zdZdr2zb99Pc9gTbfdKK{n%}h@`}_Og!(2;rp6JhZNN}2do3^;e)?K91Plxa2sJDOF&HKr zE*oYG26Qh94+}pUBPui}0%>%h4*&+EBoQY%3kj96S*)B^MPQa-6ojOH2jJ KKh4g~K>$0!fQ&2v literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/nu.gif b/workflow/public_html/images/flags/nu.gif new file mode 100755 index 0000000000000000000000000000000000000000..618210a755d0faa72b11a29fb07ab7c0c66d155d GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h+S2WMhw1sIrumhX?dC~rblC3cP2|Wt?9@x}*;M`1 z)ryDQ^6gRe@>%BGJ^1xp-@!HY@K#%S?&{$}^-DrUv-L;mT4>Cr~&;6Cf*M)U7i=ifm6#>L0A-h+C{{`!3V%V7S%zWsM^{ephu zSXt%a_3Y$C{qs^*R?64m{PyBoZe+BAlET4@;6XMqvHP^M=Hf~8>sa&d zQ~cj?A^8LV00000EC2ui01yBR000J#z`|+~z!VA;U1FBWBrXVvOyNQSO1Hr1@n}RC z2#ew)s0@ArOK-&37#JYRc#vY5Tbs6l(D6uB05B#yHU&Hedm;oLF#-!U7y&0OG>8Nu zI2s2T99>>M43?NVFPj_al}cTuV|24eRGOEZ#pJ@uA~}%ps;HHCopL&7HAET>aRJP@1%w*VbZ zFoFSP7(X&DldJGJkX{u6q0)13Hkd(Sz)3JBEFB#ZI~E%=5qkkH2{kf4EiEMt78pMP z6cjuf2_GpS4;&d97zG8H000=B9-$(nrl=RHoe&(arKc1C3JMnm2?$vWU7;Bp8W94f P!3a*z2MN;C(m?<_p3#U7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/om.gif b/workflow/public_html/images/flags/om.gif new file mode 100755 index 0000000000000000000000000000000000000000..2b8c77501d4fcb4eebfadfd58e5fceaff2e50afe GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h+*(=yPyqV+`uOgo=i4(8_OGpsVE0083R;zYDW-rnBYR8;o%_AaR|(JCs|MMXTaJpTIn z{{H^hN=ni@JJvuz)jK;Xt11+s6fdnWB&Z}Gr5_oi8PPU2(?37XD=Ppk0NPJa{P*`X zuQW@zOVl+r@9*%@FfcihdMqNJv%4i~Eo0CzVo6B8OTEf5zMDiOxU0m%x> KKg}vCK>$0WIGL^h literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pa.gif b/workflow/public_html/images/flags/pa.gif new file mode 100755 index 0000000000000000000000000000000000000000..d518b2f9780dcab0072328d4007ce28bd7f3f064 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h^IBT&h=}R{0Ar=~hr0RfM@IlS=<;%M{QUg!czAZM z_3I=gfVTM3($e)~WA1BfZL0Qrv-s`p?a$86_V)JiOiW3Y@$B^e^3>G&`uYG^^3?zU z07&itDB=Jb-d>{h-v9tqob>K7G3_fW@jN{5H#S+H^-r1e^YioXK|$}w$MMU{*Vor) zsQ8`8`Wt`s@9*&B@cr{qQt*C$08jDgGBJ3u_qf;l_4W1r{r&#_{>#hD^78WZ^z`xZ z@&Et-A^8LV00000EC2ui01yBR000JzK%Y29|%qH<0z*6k@`pQ(=)3n?2fE?^81HVQKd2L}%iGaDKVEdw7W zAtw|RI6WvlJq?qVm=+eCJplncC=)ahmzk!WD+M(wJUbkT5D){Fs2CVLxf}+^9UUGX NEDa446FbsD06SJcu!#Tw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pe.gif b/workflow/public_html/images/flags/pe.gif new file mode 100755 index 0000000000000000000000000000000000000000..3bc7639057b36907b31b465d608bbabe017e9409 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h^*ufEE-v|0Rq+iC{{H^*5D@!CMe+au{#jY>0094c zd;WKK_5c9-U0wAhCFTGC^BEcX008O$0O9}u`bkOiGBV!)0QB_q{7+B)R8;pdG4?Af z@)Q*MKR@&zAO3lH{N&{RTwMKNVfRi>_`}_O+{QUOz_WJtz`T6;rJ6A>nr9g8|N7Z4l;6&9Wb9V>vN7Z;}k0Tv7*TLOTX7cLb60X0ia2{Ohc$P*Sd H%s~J<+RLIo literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pf.gif b/workflow/public_html/images/flags/pf.gif new file mode 100755 index 0000000000000000000000000000000000000000..849297a57045d279a8edf2657314cfc5e9496ac5 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h>*-{-007)PJmXVS~=I5Zl$?gej>%Xy+eIWCjc!MB6xayJ1RFUH8(khJb4FhJ0u`7 z4h}XWKRg{jdX*#+5+xH8C7m4|JSh(@WMvQ#At43^Gcy(x4^~()3>6gu0vj6^yGct+ M3C+zE&=f%cJBfF#l>h($ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pg.gif b/workflow/public_html/images/flags/pg.gif new file mode 100755 index 0000000000000000000000000000000000000000..2d20b078561ed92f92a9034f24d382e33db894df GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h^8x~$QBin!c>Z;D^(rXy7Z#Wu9A#x?Ha0fs004Ph zT=`X1C@3gIL`2jvG5BRRQ4kPjH8u1yGF)9HO zv9Yn<008_?gxH1m2HZvX)Hyes-+Tp<$^*n4~Y zb7k{F8o|NAG%qjt$~^l^NBc)d^tK;HOG}WDkoKx8jeC3eyf@NOQT28u^@Jt;00930 z00000A^8LV00000EC2ui01yBR000JsKuE&p>lu%LWHRx?u?EnA#nKX~7K;i~FbQB6 z9@(apdl0lg?nI&U%r-HT=|;$GCm_ltka;{vDLW(>TQ3?H95oRR5(GRnE`(`%4FU}a z2nGZNCj}Br2Nw+u6bLX33=ks)o*h324ICk+s2?9I1^^PS2NO02hohLLi>^P%$jQkl GK>#}|p@q}{ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ph.gif b/workflow/public_html/images/flags/ph.gif new file mode 100755 index 0000000000000000000000000000000000000000..12b380acd38aba726f63d337660206bafba34339 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h?EnD%{dn;U3-t8p0002=^z{G$ZTCh-Wg>ZUa>f1q zSo9nmG&HJ0L9qE$RQ>(_X=%a$080J+A(&zsEx%BMH{QSvA zMzSCvpZcn;`DJGM(aU*x$@=p0`}~dn|2OaN8v6Qct*w`)jh10xzMr4kva;e>SGjk0 z#@zq_A^8LV00000EC2ui01yBR000JtK%8etG#HPOWNo#R`4S0;R5$8{D3QVA!5f9H ztwx8zn6x4VOGc7PP{QM~8J!6PI0c`WJejyUSt<$&EFw2K7Z(VN2p0qe8UZvMGZiEy zCMOFE8yF~Q8WJ%umzkRzohVu&F9)TXoErilC^jn<4!H-rA0HSPARs>#0L8||D9I>4 H%s~JUbKv57`IX+(7_4In0sJ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pl.gif b/workflow/public_html/images/flags/pl.gif new file mode 100755 index 0000000000000000000000000000000000000000..bf10646366e6e2de00d04ca75e60c5cbc662e5d6 GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h{qFAkZf^BEJN8OS^Z)?o*4FYaF8Ekk`~U#>U|{hL z4gLK6@(>XEMMd{DHTN$s_9`mw008wQB<27B;s5~jA0PQTI_dxb`$|dkGc)rU8Q%Z^ z_4W1oKR^BP@$wWD`dwZ3Pfz$$RQyj*_vz{TWo7T-;q^m9{d9En=H~tH@&1mE>Dk%q z-QD@?>-+8P`)FwVYHID@-|^$)`}_O&`1sub0Qvd(_V)Jr`uhC*{P*|w{r&y_@$vrt z{{R2~A^8LV00000EC2ui01yBR000Jsz@D(@Q2_ui7b%sRnPk1+&qw9)bUIq@R@=3r zRG&4w?c#Qg~;C6SYrmzfL-1{(x~hKLO(0s$0JO|I|& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pm.gif b/workflow/public_html/images/flags/pm.gif new file mode 100755 index 0000000000000000000000000000000000000000..99bf6fdb60bb4e92ef55622efaddf8f322b76e48 GIT binary patch literal 374 zcmV-+0g3)cNk%w1VGsZd0M!5h?t^XN;o`WXG33)!zpqdL042z~a)Y9Q@o8aKS-8iy zR!d8tYGZTO$7JFF03%=p(9_j;c(7Mkr+;*4Kti<4xJ3W}MK(9A003k|M4)nLSdxl; zXl0UNTWQn z(|4Hw08db)Oii@bWpU9>T+&u#e}KN)p=apm=EA8Rl9AwEI2nzYq!I&Itw5<1trek03<;E_85kuJ zje$hLSrAGv%L6nzWCw$di0olVERfYFghFxTA_O`l3U`I>`Zo5O=hzI051K~ z(R_<>S8lfe08IC$s7zz1X_}18YJZxl>x+b1RQb4~o>;?C9eRBNk8W`r_Lc|lsEEJ&qabh%J)=l-If*U#vAcDdW0t59c{qL|M? zT9{XUUdpxCcdTA|sdZm*-y1o{004QLj>=kgbga1}^|Q9!qO@64x&Q9&duhKhOrw8Y zt2YSqof5S0td1JtF5IyBnu)pA`1x=TU`vH2oDw`$OXSl NPt6Sp(9sD&06UU^mbL%@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pr.gif b/workflow/public_html/images/flags/pr.gif new file mode 100755 index 0000000000000000000000000000000000000000..6d5d5896709989000cb51a3d13f77593ba68938d GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h+}!(XWcK5CcKP}F&Nw-JdHlEl0Hy!|%vx>p^74iN z0QvRx*i%&8Y;0Ux{?kK4@$K#Q_V$_p06{_eFCVq(Yu0Mu1g#KQf}GBQg``_)WL z_44un0Q<-&DE#^O`uqI!^z_+XUZh^7#2p=wj{eU)Jl9!S007rWM*H^l^=@hX`1ki- zVE%t==D}z#U02f4{@KaN_4oMMzrScv;No#|s%WaWd$?3l z`~U#|A^8LV00000EC2ui01yBR000J#K-9rPG#HPDgYxhz^kg!@Zr6ZSDxwQR(rme2 zpD=4dj;J`4=E~6mfIx!*i)D^bIwf1lq2VDI3>yy*CMOad7$5*XDHAgU86F-aBqjikL05|~sR#yLddH^c` z{ZCN+Z*TJQ^7)RD(9qEN`T6wq^*EA)g`sSy@VtOm+tkj;Px--7*}^>iaB*p(T-NCNQ;|jW zJT~WeT<}3KL6J1>-QDecPGFy5^ED~-XH4SISMItt`%_2oxIILUMEXKP>S-$G(A3=k z002z@A^8LV00000EC2ui01yBR000J#z@Ko)DRMMOjm7f&d`6>2>T;P(6xay!GgBQl zCjo8;3K<64-zZ?S5o!WK`Ru?zevQCJR_YOQEp!DBcMTLKGBGPIH!lMY1%nU^2owhZ zE+h;LkC7Q6lL!(l04NCwJdgz$83rPhIu#W#12n1`9UTL&GXVh<6cHF04|u})Ik6{x-5+a literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/pw.gif b/workflow/public_html/images/flags/pw.gif new file mode 100755 index 0000000000000000000000000000000000000000..5854510fa9ee2e9b218f8a783b331e7200512ea3 GIT binary patch literal 374 zcmV-+0g3)cNk%w1VGsZd0M!5h^!Fw-sr3MY{Vk;Q_V_gbF5UoT@rBE{09@{2zWe?A z6ic)BJF4{nIpTWB|5CR2L9O^bt@&)j{Y|y{amD@sd;0)z_FcaI{`?&O`~-Kxq5wnZ z3zhL$y8c+Y`2bGqII8$1q4gi0^hL4z6q)ifrt=w`^LNPpXTbb>#4U`KTifeJ-R)Blm+~v5?p?h4JgnuO)sBnL$6UMmr`nlDu=d2_VNb0k217Wg2cg`?cj|ZmKYK8v+zND;a@583Z(jCJYUV z6BB@fFESz~BmoT-5(^_W3KB;M4z`ua|7-SPAJ^YioT?DFsO`}f(|_b)H>_4?=C-GiCy>VSFs z`}^nV@a^yU_SDh&($MzI$oTW~>UneN>hN%Z%JcO4_xJq#OicCl_5A$&{Qv;;^z;A# zr~d!|A^8LV00000EC2ui01yBR000Jvz@PBPD;5_>Bnb4&I5UUC<|OCLdiK6o5=c`StaMQcHnNM|M6p zWG5hOF)4pdM*IBxg;GuM?(A0$1?lJKmTG14@bHdbTJ`hu_4V_2K|7&%bewZ-a5ph} zML&HFMX?<>TYwrht5fRZny~H2eGe{r&y=`uh3#`S{{H{} z{{R30A^8LV00000EC2ui01yBR000JwK+JB45oZ=7$k?u1o-Ww zQyM@4(hv@tLCrhu@o#}@Z;vhj literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/re.gif b/workflow/public_html/images/flags/re.gif new file mode 100755 index 0000000000000000000000000000000000000000..43d0b80172e97a08147c64f811ea5c7775ad46fb GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hs;a7*ui5eO@$F<*#M13od&TML>hy?y-rnB$m5kKX z)Yt$3w8iJV%jsr^%<5`g?(XiPwcY0C=H%q$?sjUj!{w&A-t&HP_xJazz2WW&0CJMj zs?RiQbXoVKJ@hTySuv= zN2U1q__xUC>|Rjp>+3{pyW-;FpP!#^kI|;N;Ipu>uD|3gSFo+9_7 z>~odVA^8LV00000EC2ui01yBR000Jyz@PB9K_CFBujQ zjbnlXC>KmW0Po!Z_V!r){ZaeyVEp`L^%SwzVzog`06(D@Hu4#=r=dt008Ib=jvcp(q3Wp^>_62^zga4?W3f@001?Bw(;@t z09Bas^77^7<@NRTA^8LV00000EC2ui01yBR000GRU?hr0X)Y)lAuKz+Qz8REwn9)a z3{2qvH3I_2s8o7CU+tiIJTMH#r9drkID!MydHHk*)hkxpd<-a*fmJ;IxIYX6fnl+9 oHXFsqV|f#H1b27}3LPGLZyy^Sj2(oG9t{qY5)vMln3*8}JCP7%O#lD@ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ru.gif b/workflow/public_html/images/flags/ru.gif new file mode 100755 index 0000000000000000000000000000000000000000..b525c4623312f57d837c23d28d18fdb97e730de0 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5hjg9#7^8NHJEf^T{&pl|Ioc{d${KqF&^A;8`F!xne z{o~~C`deH4WMnEU_Jf1>A|mzr`ug|x_xMmy`aL~#bpGDn>h|{bm6iO`M{w)_0QW>h z^*cNB002r#{lgqh;ebFwadRwpd3${j11fPZgLry;eggw3CNVS_ z83Y73HwOnFA0#9003CJ#W_foV%^7cdX_ehGj%=Gw9;mAnu^D_W7 z=LduTA^8LV00000EC2ui01yBR000Jtz@P9pnGBADj&jBP5uOB&)MP5yJRaD{S?GRB zB?Jr8;PDz;f)^~lU}}|$ZZsi$z6db}lgY?r7d{683JNV8000iJBqS#%E)EM3G&BOc61@h$D8VWb55>g`$jB!TWms0>s z00000A^8LV00000EC2ui01yBR000J$K%Y>EKqQWnf)CD0m(r zJv}=CC>sq86eKMmKM5HN0VyXIG8hmB79;=-r5XV=5-tr23^5`E000U<6IWRmn=~jA QAiKj#Oh3}o)IUK0JE%R1wg3PC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sb.gif b/workflow/public_html/images/flags/sb.gif new file mode 100755 index 0000000000000000000000000000000000000000..8f5ff837fe4c9c0280ee8d3e4601725c86099fa2 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h=F3Yvg*&9A>&CB&R#+8hXWlG(Eab^=%ELz-avT5v zyNiqG`1t&CbK*mbL#DGuKtJ0_O5Mem009BWB6cEdY~WH-+ftKLkAI^^Mb;E;6k1!{ zM@QcdX$~}jG$nT>dwb=-sE7aw0OQhQkyik>oq}+jK-IWxrkAL$qP5}FUE|~U005uT z()GW-L*&F?zQt&@weYW*0H3Wt=*&N!p6W|W*j0}*l49~5{KF%~rz9CJDkgb4`&KMEBV z5ji0M2se=l8XlDu5k4n9ke?bIq6#US2qp#w6q2hQ20sJ?BQO^iI1Ua00UjQ+KN2zo MB0tX0(9S^sJJi99umAu6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sc.gif b/workflow/public_html/images/flags/sc.gif new file mode 100755 index 0000000000000000000000000000000000000000..31b47677e0d51f2958f3c833b36345c5267a064d GIT binary patch literal 357 zcmV-r0h<0tNk%w1VGsZd0M!5h2apH&la}uR0MF>s_*7N=`bz*a003M7rPrqb0EaoI zIrb?j`8z!JwYB?;NBfyY^z`)o{Zjn*Y1r9l^YQX}ddm4=V2_TNgi;OnPEP#%0OaK4 zbacsIU%dVOaWA7U`anSVHa1>f!S^sQ1pzMr0D1hDWy#3^`hA7#=imFXXM@Otsi~>p z;A$(CCHOizmzk*S_48)CX7}dp=g-ge!ov2}*Y-q2?(pvRb#?ejNwe9raB#%d+kE-$ z079-pA^8LV00000EC2ui01yBR000Jpz=TkE(inY$q%u)yvOG|U$zmZ8G6JTk(~3k2 z4iFhbdcSh@gVtvZd#003=tu-+(Vym_VDgS_JY{{BRK z#{dC{7+JJus@d}L@_Du4_4V}tNweYM;Z2p&#oX?Y!Q=J%`%;3+HgmrK6qrSn%`J4o zTAtQNjn7k_)YH_|01A&Cbio{b#432i057Wh`}<*!&`WE;M}o<3uiYPj#+}LNC4<8N zRi#s**d+4_rI1Ud8VwT%$LkG9 zm4tY8nRFDDE~G&S9B8pp0*6unx)cKn6nJnh2qh&xJ6#P1AvOyE1uh;Z9fVyYFDfDf zizyQd1(H1w5FQL6m=Q226ofb%8vqavGYlIG84o^$6$T?A3_1?K8U!AL79M3a8Uq*u Y0KWo4EDInq86Y4F3j_o$A0I&gJ6ofk%>V!Z literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sd.gif b/workflow/public_html/images/flags/sd.gif new file mode 100755 index 0000000000000000000000000000000000000000..53ae214fa16b78b4c491add45bb56f70f4339a6a GIT binary patch literal 355 zcmV-p0i6CvNk%w1VGsZd0M!5h1#HJ(<>gwuk#BF=edi-N!6ciNu?(O$XO#N$X`a(kedwNQ>O6&jt z{qFAb^Yh~3;yXJ#`}_O$=H}qw;50NePq$C|R#shMU3kfO_)}B;QBl3Uy^z0(K}10S zJpkv&$8M}|T*6#$l*FC5{(%MR9h?+zy#V#mJ^0c!5^0?raiBAOsQ@Hw?3(~Ng{wV@t_^9H00~z5)<8pxux6sb zC3&I%07L!TQTx|M_RcGNu*&}3S@+N{SedzCpS}Pvbp6~^001HU*-HQ!WBl4rd9KO! z&oceN000wR_ts18p#W2swf zr~pHOA^8LV00000EC2ui01yBR000Jzz@PBvYBWry$wc+SU^>50h!qI%7K=?uN0Kq1 zp^`#$@-P4zOT}jZbaE^OuAH)^*9MNJ;|h>HDIXaF4RtgN26(1d0tj zD?NgQhLi+5EeR$IXOV0i5eErYSWN=oisUF9Ss@MUJ~LPFcm&)v_@;nUOTF){LZc=^lA?&Rb7yuAGG?)~!e@L^%` z=jZDQ3G?ac_3P{FK|$z6Md(;q?O0g*`}_F#`1SSm_V)JY008;<`SbJh`uh6!_xJSl z^z!oZA^8LV00000EC2ui01yBR000Jwz(~#|gcu=>WTV2&ohS?dgCG!qSRUGhBgs)x ziPXgez=SfElBUyL6)uU>2@^xBKQak~p(0!+baoma9}XK400{|KSz8@43Jx$1Vk+U%X literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sh.gif b/workflow/public_html/images/flags/sh.gif new file mode 100755 index 0000000000000000000000000000000000000000..dcc7f3bcffadfaf36ba17812e55f66c0fd10b466 GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5h_N1uI(B(o`u8Et=MqRQrOsen)40MCV002uoQmg%E zX3wuVOJTLTqDpFg!TAVRxPV;gJFGlwVI~X=wWJAX}C5{ufeNT&#^$$v_ar?f;Ug7psm@myx(P! zWdHy(A^8LV00000EC2ui01yBR000J%K-8gNz!YRF(PnvRUIc(ZBoY|$9F7SolL;XV z5RXD3rdbFAK|*3dU;q#@egr`|)&KyA^78WT?(X_qTl{2XO;pbGvA6pA`b1CB_xJbtQd3)F)A~I< z_V)JmJ3I6M0H-Hi^E5P~9aZrS4Xrh3_V@fiOw9lQw=O)%;Q#>0Z|2P=x>$^&uhg?)LaJG~nR$FF?&d0028l&mS(t0};cjWSy2-qo!Y)jgsTt008y% z_5c6>A^8LV00000EC2ui01yBR000JuK%YoL4$SBGv IJgwv0xa;FBE9*^5?Ot5H007+=6wLqt>r_(O008MkL-O+Sq$r8H8S8KAKx4qwEzI+G%}a&g)Y3x25QbD!hlDJJ;%`1$$yu>b)6{{G_A^8LV00000EC2ui01yBR000J+K%cOO_*IUTgL1<384SHfuU06)29OoSwQzVEFmNnFct&>I;*X(EH(-}2Ut4`IvFn*G%YA0 W3NpY46Bhss8xhtKBqTiBK>$0|z?fYC literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sk.gif b/workflow/public_html/images/flags/sk.gif new file mode 100755 index 0000000000000000000000000000000000000000..1b3f22baf9e1af04495b4044dc6b7082552f9f04 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h`uh6xD=YPOdZqvX{D+0t!`l4v^Zot(_3Z9SW7g^b z0Q5IE_(n!VT+#pmrFx3pcYD)3Sk(MvVrF*P?c?P085#OpTj6_*S##Zknd|h6koi(m zRc+XWli>j%%lG&9@&EwPLR!iyM)3^|P-oZu-rnH=0Ew95{q5}bo}$h+P+f4<@N0AS zkd^rF@P>86_y7RMBR}x1v*+F4{msnghLqs5!}93rthes`;^B~*;cITr_*h!q008~< z_5c6>A^8LV00000EC2ui01yBR000JtK%Y=(D7st-#O+3*_GVcXs8?y!r_n-4Gk-Fc4=#Te}NH$bp|bk^45 zii+iD;b=58%TiL+K0eR@0GIRg^8ma6dU@StW!5@6&j0|30G$A!pz2=UUR>K;EiKXe z`}++Iz&EA^8LV00000EC2ui01yBR000Jvz@Jcf8yPJ~3t{;~I1vDVMq@A>4l4($+36fq z*;*vB3j}JYfb4S7K_IqV^zksnEP{c)*J~*h3kwW9K0F(F1AKmff`lT5d5V95gFYf6 zJ~S*T92^uBFC-ZmI5QeZm$h@{>+^E9`isQ<0BQGNtM+BD z`T6tyd%OBwsPt;F_y8o|RipCt_4NQOzN}z?zWa{2fmx~eYOK=n z`TtdoNKc~mezW1D%+i#`_hp^acDelkQ}0NV)r7$OjkmFi!1VU^_V@Sq{r&y%_y7L> z{{R2~A^8LV00000EC2ui01yBR000Jzz*cWaDj7}4g0j=;{eHeEkN2o<7K>dID&=uD z*Q{f8YI^(6iMbM-wv`};>!xl~57L0G(5cgT0(005WKJoorCRkl0k*Z}1EMqs~T@AfLO-Z1$1G@jH!!{k8x@@4$=Y5V$M{rzqD_cn3Gae~M%jLtP!xmeu* z004miA^8LV00000EC2ui01yBR000Jwz@Jd4Dyjg0fO0VSIi4hs2WP9@5?Dmj@sf-L z0u2cBU>y`%r#BQHKXPY?mO&bYE*jU&v}!3J4IcvxI(GyhG$(Ed?D5n;Qou76u|287HNu3mdkp7F|7T6}=P`W@kPY5ycT4$SElk KB_%%3K>$0(ftB|F literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/so.gif b/workflow/public_html/images/flags/so.gif new file mode 100755 index 0000000000000000000000000000000000000000..f1961694ab98384142d534dd682287dda3b37892 GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5hl*#@8Nai7+^!WgD_KCv# z;_diGo%D9P{RM&j*y;L4obv!~_CcBQdA$Bvrt<)H`AVPkb+`F!wEI@1@_D)WeZ2Zl zqV*7m{vnb7aJ2UTUhjIi_I$hgX|VTGqViFs_KU>*akTis-TJ=T_p;Uaki_}8+WS?f z`4fr%A^8LV00000EC2ui01yBR000J+z}Ii+YJ3(8lSU+w#9|GA6oA3pHWtQgg@Ofs zfJlVoQ7BTBgh2p#1YBXVqB5EI){qu05S34QARs#zHZ3O!1Roe>DJeM_89ERMCm{!k zH)m-)92^@Rl_LTK3ma$^1``Z27a<`d4kZI778Df+26-nPuMQ3>10oD8TsRLj2?qiK WB`P%o8ci_;1p(Fs*aO-GK>$0Av#T!v literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sr.gif b/workflow/public_html/images/flags/sr.gif new file mode 100755 index 0000000000000000000000000000000000000000..0f7499ad954a455a4742c4b53c3c8c2e3f558275 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h{bgnVP5}D-`e(st?DFjO`Str%RRD(o^B5TW%|-w+ z0Q^cy0Ac`p%6sVV>GJmT{aIT3Mn(X20A0Oa^)fU4cX#$nOZ6fm`SUsZtWrp_N%*!h z`N%jstUdKBEA>4+GNv>A008Cy0AapkRJc|5`}p-kKHmTUHK;eq*~>w$LQb_%{7+Bv zE->^rIR0*M_(4MUMo9KZL+$zT`hr0CQBe6^UiQK&`q)4Bd@xY9P*}QJaK&(S$aT}@ z)&7c%A^8LV00000EC2ui01yBR000Jtz=LpjkQgP5Wb)8xHhMhXU@)5ONV>pGz~z>{ zg~DU}@P&S_Gyssv7;2Un%q9v|AO_YVfx~eq9v2rMbuW1f5i}SWIe`}lgds0_5ilGZ z8#jUo2rhLMHh48~GA1q*Eglvp1Yltg1hEdYvndi(RwOGL8Y&$fC?FsTNJ#<5#|p~J H3PAunnPZt? literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/st.gif b/workflow/public_html/images/flags/st.gif new file mode 100755 index 0000000000000000000000000000000000000000..4f1e6e092b35de465031930db0bd661ab5e1665e GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5h>+(1NYXDigRr~u!tf@8tDgf~S0D8)J08#+;^(Ksp zB|57#OS4D$XG}AuF87sH=sZ2EN%iwBqCt&9G(Z63I zC5FqgSU4ElO6-wZMcx3wWCBs~eiaGrF&MB2Fc=Ug2_hGG5)BOlA}2Tm2?{tFhCd$? zIurvi8iWZb87&xx9}N@{adQwI9UL4QJ3lusV`dIBBO^T|Bo00XHCI_-wYClgAxa3# N%RbIN1qD7q06RBYi{tlp#qV34i@{^(4g`4a4_Vxe(w>w%R&?NpnbSvS+W;xo_4W1q{QUIv z^!@$)A^8LV00000EC2ui01yBR000Jvz@2cXP<%eE(}~0673_xJ^z5$PLO3 JD9tEA06WZouv!2B literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sy.gif b/workflow/public_html/images/flags/sy.gif new file mode 100755 index 0000000000000000000000000000000000000000..dc8bd50948773d5698d49ad4a214a9847fb09d5b GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5hWMpLfMMeL6dRtpt^Z54G*4F-Zc2ZJP^Z)?t00918 zUPMGh78VvQEiIkZpY;3oG&D3mK0f*Y06IE44Gj(V_xJnz`}+F&^78WW@$u2o(WTp` z>GSJcx?cTJQTkk5jLwen`S9-U?)+n8{cCGWOH1}FEaC9s&(F{IF){czH~3Ri`Bzu@ zOicY$RQ_36At538JU#tzar^xH`1tts_4WMx{Q3F${Qv;=_V)Ah^Yrxe{r&y^{{H^} z00000A^8LV00000EC2ui01yBR000JtK%dZuE8-*)gc6ZR_ykacK}I5t6d%^AIv6{aadLEag`pTaC_exT5fcy%4KOea3=|X%Kdu7<2L~k!u(Gqfy~)bU Hy+Hsw(&wg* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/sz.gif b/workflow/public_html/images/flags/sz.gif new file mode 100755 index 0000000000000000000000000000000000000000..f37aaf801198a2afc9700c33f0c71a126358ab67 GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5hP)SKIa=JS-G|P)m+04jKi^iE37kQ1f3|ghfuCK+v zy!pv|^0!#~)RX`(j+wmEt2H#&Qvmh7WXN`P^N|9w&fx$>ou$Ot>ZUoCxzDmpOx&n- z^y}vvWU!60$?dE|gssJ`%HF0bDZg7<^}%lLu}-6#n1TQRIDEP7vQx7|K$AK;o2bX* z;NF9Bke|TT+?ruTgT&>+xd1(Px`0BOMMh>}V!~KdkBf<+owlM;QM^-3UXKTY(pY#G zq_9N7D3ciXq~*0T001yqc9~yusj-_rQfPT=jJ;2Ft~+I=VT8GruG0Vj6f#_( zdw8NeVyW?`rYlf>GFOCig^kv&x08maHejIu0AXf`y3(>idm}~m>CH-UuJFrVP;aPR zfVDtqs@>Gy^A^8LV00000EC2ui01yBR000Jyzy!yDLKy;yl5)Xh8V)Z}?$F4XOqf=oV1d{G z0L4$C=&@XpP$;5;1P-1Wz{5ZgI=t0`Mu12fItUCIA|n?rFewi+E^asl95DnKBP0$d z0s=c78YLALDg-VUBpU-eGCmU_Z7Ng}vMDgWn^XPTyO-%p+miX?J_wA48NJ?dc&%gix@ZxCd zMo8@7TkYa*6+^k?Eic>2A?eLf=srK{&{XT*SMTVa!K(nxmjLERNb%Wh04=j+gw*um zi08WiA^8LV00000EC2ui01yBR000J!Kp14mlPQjh-($IiB%X)c>4ZZ009e4oIgo%p z6bgy7E44BK0asE1lL(H*nU>}yygkp`F#~&-k$9M literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tf.gif b/workflow/public_html/images/flags/tf.gif new file mode 100755 index 0000000000000000000000000000000000000000..51a43250963e5862d4cbf19d34a4cbb53cfb3b7b GIT binary patch literal 365 zcmV-z0h0blNk%w1VGsZd0M!5h001pZU8DVNZ2$pje2KbYajtcNv-vqX000$MWuyQA zSN#0^Phg}#QkuNN)^2>YiIv1WPMJ1Il|E3Ic7(Y4K|ufjMvR!oMOdHvM@Lv_sQdr` zI!%}SOiW#EtT9BAMOK~SF!)>sd0a|`}_NDe6vbhpg~idEkTe^V4~jO=Tc*&YI(B&33vYf z{{8*^A^8LV00000EC2ui01yBR000Jxz@E_e`)!T`h0?<8T`s<;U^+XESST65Ns0bS zoeU#@c||l^$c*?4SID=BWCs{P9>2vRQ#oL691>-#1P%=opahkdnGGB!Ar3kQ2nrN4H9V6kE(tj+Aru_B3QSA@ L%m4__&_Mt@20fAt literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tg.gif b/workflow/public_html/images/flags/tg.gif new file mode 100755 index 0000000000000000000000000000000000000000..ca6b4e7744dd89a6bc12c61900830fd7054c6554 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5h0Dk~jxmMc47642D^2ro9r#5J^H0#z#ZN_We$SKvh z1^_Vt{aagHt0hmR8T(UH`bkOte0=iOL;iJk+L8d~%`E_80QS)<{@mQ|(KO@FI{Ml@ z``SeQwYL9-g-WnS9hn^fasXnzU@@aE_0A*s)iq(TFFUb2>)d9meE|F2N#~saMXo|n zv`+re&_Ap@`{PF{pez2HoBPE8{N!r=R=!E6)`2{7IR*wd4GlR1J|18X5D+H?BQZQ6AO#C~ zZj2B*CWQ{41_LuRDjXXdb9E#HtT+@3CgjLrD? z`1bbp?EnCCbHrO*xc`EI{B(5u{QUZAYCAitgoVla`ug@&Rbpehnw!=D0DAxcF696K z_gGjgETMOJ#PUT&N=mXpMX`H)#`N^`Mn3S?zx3nKxuvndD=H4<1_92Nz?A0IqRO~o6>FfcsJ GK>#~&ADH3* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tj.gif b/workflow/public_html/images/flags/tj.gif new file mode 100755 index 0000000000000000000000000000000000000000..2fe38d4ab9213a814453896b2edaa13d69751c4a GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZd0M!5h_u-uK^77qdV?>HXQj=5ENlDQ(G~a7$J7MMc=y z*!ktE^wo6Ybaedu{MuGlEqW~$Y!=;ITmTvX_St@!008;<`7(VnK88ND007xiQltO? z4Q37a-i@sQ0K5PI_xJbu`ufw;)Arw&*G*0K(P18O9$lJU`10Lkpk(>!wmO44SeIDz z)_6;fOZCrPBXuLrEG+ligEfFPE_^QZ_4U&{J^TCn_V)Jk^Yi`v{q*$o{{H^I008y% z^#A|>A^8LV00000EC2ui01yBR000Jtz@D)8DQ1oy&t_TaA)bxs;UEx59vV^;A?adC ziG6m&a23ORXuHz5Eca|}BhgiIU*A&0~jkaG!QT*5fL05G(W2+ECd8D1Ff$Y5D>Z(Kgr6= H%RvA;T1}p6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tk.gif b/workflow/public_html/images/flags/tk.gif new file mode 100755 index 0000000000000000000000000000000000000000..3d3a727fde64fe5afc971a13eb412b6adfd2de77 GIT binary patch literal 372 zcmV-)0gL`eNk%w1VGsZd0M!5hN`-D*b=Cj?i+Ymfv9e^Ks+7aKP_MM8m!g|0N64?R zUCYB)=IQr2RLcMWrT_qYR&LfzWz>w7qG^1}WO~}ArDQl%(d*n!it#^at|=Q zZiC(|ShZE6J+iZYf{ukkUC;mkv==zTQfkCSU%jWNdN54M-O^Zli@vzFe|m$Bf05cC zKgQqLd|RYYmX>1A$Y06EdDhKt*wAI;+=h{!fsvezOXSZ9d5~1|~QjkCxAr=?}AQdfnA{-Di2t6bg7A1rRBMkzH z5h^z*7#1fTFFY`n510}=F*ybm9RMBx8z-d{AtWXXHUtV4t{brr4io_p69qIE7djXK S4JQe}OH2X})YH_|K>$0GgO)@9 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tl.gif b/workflow/public_html/images/flags/tl.gif new file mode 100755 index 0000000000000000000000000000000000000000..df22d5823900f670fcccfd571052d18619ac8441 GIT binary patch literal 360 zcmZ?wbhEHb6kyP#$Sy@>RA3l7_!0_GMJ0c?LPjd1n28O@c+234TJ_!r|1d5xP{p_&*rmg)+Pw%_F z{*R!bpJ8E3mMs3r%Ue}d<>lq|)5i7z(7Ml|KR4UVotE^o%=&L|@UQzpKYuy=d}{sO z%3#)_`2U;?{~D`4UAO<47Fk&6`p3uTUu)Fn)iu9jVtjmp{>1q7PmBEd)8_B4n!7;T z89+esCkvR?0g)g-F|f5d96If;6W2FcrTOFLj|puWtx6N`*vN7iKMA@Tq#3o);1Gk! zt$2+^+MGp?KS>5w{;})xP+D+G#6U)hgPFUGuU&~<+gh@*xuvYa!kAGsNW&kJvCUQg1b!{qiMqQS3Jb+e7ief^9TsnVMQIBd(jAkHiJ^(TR z(sE@CVl9uho*Qa9Vwrf(YFx==Uu2qj%x!0^001v`OLnM=#amRnCmGavY_-n5b*G3S zZa=@&$l{@y!Pd!uu9CN4UekYdMu%TVh+)lTQ_*Qug|L;uV_;{VecYOo-imP5g?<1z z00000A^8LV00000EC2ui01yBR000JzK%XyF3Tz&o$6@(v{(J@k;l+wEU>?vUfyq1# z5grMLF;p6p3&K?SsvI25s^)5p5DN+Iw>gn=A{h(-03H?#5G@vbEF3Z+H5L>jhlw8- zKMx8b11ORR1&A#l0tlH5Ap Nvp)evPSMdp06X`pgsA`k literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tn.gif b/workflow/public_html/images/flags/tn.gif new file mode 100755 index 0000000000000000000000000000000000000000..917d4288c9424fb3a01546189e8765091127b7c9 GIT binary patch literal 375 zcmV--0f_!bNk%w1VGsZd0M!5h^fNQ{JUsPWT=Xq1{dRWt>+9?Q0Q3L=|9X1*Qc~pr z0R6SK_S@U{OH1`5Bl@wi^BNlVw6yxGtNvYG_C!SbJw5tFMDi08`GbS`R8{_Qa{X>@ z`fhIV4GsHYVfp|7{#jZ4YHIvuX8K)S`$|dR008_?Px|TU^sB4=R8;miH~8o0^Ho*( zy}kXx!S`rq{Iat5WMuTAq4(C-{omjDSXlOaeEFQ5_>`0RcX#~n@BLF#`FMEU008{} z0RI30A^8LV00000EC2ui01yBR000J*z@PBvEBZd4gYsZ7{18wAL9+>oJfm8s;Y3U( zAQw%id+=0%0rv@BEC>ls3-=m0C<-3|lzQJz7#IvO4h{i%8apO12`4!e5d{Jc5Qjb+ zCL|9WH!C+b3<3}rDheMVBo-19F#!S*C@dEj03{zH78Ml_GX(`Q0v8<}10@GoS_usl V6ai>y13gPk)C$%mB|X|f06P+8o0b3o literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/to.gif b/workflow/public_html/images/flags/to.gif new file mode 100755 index 0000000000000000000000000000000000000000..d7ed4d11641ae1c1c9001dddc7653973045b6c66 GIT binary patch literal 367 zcmZ?wbhEHb6ky>fLOY4)K-jAT5ud1p)Lqh-N z<$Y05_{huq&Bf)rm)AQ6hOc&Z&lnhfCnkQevifdd@YBlbmy62}GqYa|4Br?SJ~1%7 z0?N9%eUX>{VPf)GQu0q$)}OSrU$L=|fZ|@BKW%J38yVeaVED_x@XOx*|NsAg{`~n1 zM1TMOtEu_@`}h0zAK$-!|L@|(pAiv2vCpQaKdo)Pn3?@cNciLJ^B1TvIQZYce|H%e zK7RbD_>+YJ1av?I$WIJxJqP9oNK9U8B-xv`xzV9c`%w3V)w)iLPIk0$6fCf0Sn%{x zDVLg0>W3fS(so96m->bCaJE0W{(5JbjsdHARt1lskS4bcV_I`7r<{UFCpV*Ny4ZwC zOcpAViZist;M4#va<950ObGx_e)FmLqqyT zM*dx0{(5@(JU#Lg6ZbJO{&sf!etz;UF7zNE`B72*o}T$sRr+CJ{&8~sZf@}n4f;Sp z^(7_x00913S@`7S`8zuLadGn*8T@K${AOnQU0w7aANV&n^D;8v008zZEd1o;_x1Jn zx3~T2>G@b#`=X-vjEwX)Hu%`s^z&1=FloSdBO001^NHuL}h<^cioeSP;!OZ6ioDk>^tV`KjF^ZP_ZT3TBBo16KQlm2vd zQ&Us+EG+!)?)5!A_ck^}L`3*fQWzN-`Bql);^Oy3Mf+i4`Tzj@SXlgKX5Ih*`dwX2 zOicSqN&HVw{OjxS-rnQE!T%*C_Li3YQ&ax6wf=c|{pIEQ?d|mA;@i8s^@fK100930 z00000A^8LV00000EC2ui01yBR000J-K-lQ_8{twt6zaizG#WDtV}M{-Yys7YMG{FG zKARG4D<~>zYaIqU7$YMsF$OCSTPa-< XCNu;KlNBY$Oi$Jj5HdtWJ3#FMOnWx-8hvD?$HWv97lqg?>qvO8n2**KTU!;U!T=C}U-{`~y>{r&xE00960 z{{R30A^8LV00000EC2ui01yBR000Jtz@D%N0$Glhi}FHC^hQvP20;Y?WUfab;q&Rf zJl;-1o)8F=miIuiK_H&WhBLrK7z&=lQ8K_Q3v?Ja1t@t83_Cjq3xRbZA9o!B0uCt# zfPym-A}|9T5-B+`a)OW|5e1(TV`XP&4Y9E&7gi4sCMGN@0W~-jz&}d~#2FbYFBU(` H%RvA;*H)jd literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tw.gif b/workflow/public_html/images/flags/tw.gif new file mode 100755 index 0000000000000000000000000000000000000000..cacfd9b7aacab39f8975b3567d65ab0ac0e62813 GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5hT!hm2HZ}K4OZjVVgrwg97pwU^Jz|N}_C!RuxaX3R z+42(;bClWlEiLvcD)KHa_)=2!B_;a+0Qpu|03onbeb4kDAby|S@eK`4c+2`gK<)ql z^*%o4008@8Ve~pW_b@Q~MMd@i0P+9;>Hq-Z008;<{h68F^dBGd85#U$X8K)S`8qmR zfzkU)N%Jx?-v9u8o!jg|OYt^3?MF~|nc4IrvLjctHMir)KbL%AFn40IVgYk3wN9R)E505}yH88dhhC@CKu z5(7LgAsQ@&lqm}~Ndugopp^>?FEA1+ou3VPsu&m#Fd|zMT>=OQ93M9?4-Y;}PERBx N9UUblFh0^j06S#9jNSkM literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/tz.gif b/workflow/public_html/images/flags/tz.gif new file mode 100755 index 0000000000000000000000000000000000000000..82b52ca29807dcb6dfcc632cb22c853b52f41fd5 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hH>mW~=twm*GgMGB0EGY-n(~~{hJ}v++UjFly<5V? zGv((-l#VL^EZzV~%ve}h(#}Hwc>n-7;(Ez?&fNe~wNi4%b5yxgZpTgG-b62?@`{K< z4wmr%MCfkBZd6o4RI$8w$akH|0C{vt=I~w5=1NXZPUY=4K&|$_y#TwnJ(Sm4U%>#R z-b=3FN5SD+laE&K?OZ=UJoWQQ)zW5VWMWgT08zM1*yTZKziEAYJTs!-;OJm(ZLC>U;-H(TEIYv2%*H~(po?UXafo*1`Y%kZg3lCbT|PZ01^=%eGngK zf+q$A1(7}oGmB>oI4>Za8~_azG?xN`0R}s$92yNjH4hIkJS06RC;$K&#J5Zb6gCbW M9TLtB&=NraJ0=2<1^@s6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ua.gif b/workflow/public_html/images/flags/ua.gif new file mode 100755 index 0000000000000000000000000000000000000000..5d6cd83f597ea6681e2afe62af7745ce3f6ca463 GIT binary patch literal 360 zcmV-u0hj(qNk%w1VGsZd0M!5h{QPM7`C0160QB@60C@aYxYzmlJl?hdD5Lg9vioVm z{QLY%`};)m^E6Sn{NlX;a>o7uX!Y{)6MD)207L0ZveWnXMD_JMYr)=3v-k4yE?vI< z^3?!hz1%{t`SI}$`rZKc+5kMR`2d3cOSb$stN8f%H23!}_Vz0E^(0if{aL*JF{$?e zSMNTn&v3-x`1npkuF)W$^Z;G)E~obZk;jVA=Rd9W{ow#%zWV@AnRm$kTDtn~&j47v z{s4vlA^8LV00000EC2ui01yBR000Jsz@P9p8WE0!h;r6yjV90?1fr#}mt*h$* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ug.gif b/workflow/public_html/images/flags/ug.gif new file mode 100755 index 0000000000000000000000000000000000000000..58b731ad5c6cad47c4f3fdea21763c6537010a5a GIT binary patch literal 359 zcmV-t0hsTZ9Ldc$_uEAD^(*~SQiX+mt4&QrL`0l3 zGwJ{U^I|pg^BMNoHu(4V#K~8fCvvH7Y_<0hzdd<35^L84=NJ^lmZDq z05Tq%0|OAB8lf5xE;BI!8yhJFtPQRsBLycJ9UT-DI5;7@480~MJ{iIb#Kk?wKFK~o F06WatnQZ_7 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/um.gif b/workflow/public_html/images/flags/um.gif new file mode 100755 index 0000000000000000000000000000000000000000..3b4c84839342c61a9e9b079291cb4b021824019f GIT binary patch literal 371 zcmV-(0gV1fNk%w1VGsZd0M!5hkhb2ayyfgnOtAm})YR1Z`T5EK0NdKzxytP7LqnAS z0PXGV={h=h008FZ=2U#n*E%}(_V)1b@a|n*^!4@I0RgAGged` z<}EGM003Em)7m2=;wUJ5wB7vt{G+(wrMcqs^YdVp+5Z0ie}8|_(9rL1Z}Oj?(HgwPoCbr1xqqpGZDk@KR$ya{R?(XjL^78EL z>|2A?A^8LV00000EC2ui01yBR000J%z@PBv**zY*3#h{Ebbcp9RCFu2A`wcjCqexX ztyU~xA&n*zL4qMLd_}Q>B{BkVc|Ofz=0OC=W&j~-3>h2=13MxC1tb&z5*T z4=-gnf*2+Y7aSlT5DF;;StSw@lN$~W2L~`0D=KMghB-DLEG!TWGO2e9c^fnb1Sv2~ R6;2%n&;tVs3Juml06QBhscHZK literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/us.gif b/workflow/public_html/images/flags/us.gif new file mode 100755 index 0000000000000000000000000000000000000000..8f198f73a777a6af8d3c8e0b9b2ce48168a216dd GIT binary patch literal 367 zcmV-#0g(PjNk%w1VGsZd0M!5hV`H}Z`ug_v_3`oX{6FMd)+t~b6RQz~i+ha=mD=V72{QPBRx?@WGIy&a&mbT%E8IW!TtSPICuH}{{8#^`tkAa18?Ei{{8*o z++%0NA^8LV00000EC2ui01yBR000Jzz@PA!N&$|l2Vx0<{BkH=DIlQ+0->w`_Cs+v zo`Ju(0i zIDb4K9W8?qA0G<`A^`#$8+MVC77acxDm7+kX%V0WxGEYA0Wn&rsXHq)79ulC2u)2S N7!(u-2O82r06XTKt3Ch# literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/uy.gif b/workflow/public_html/images/flags/uy.gif new file mode 100755 index 0000000000000000000000000000000000000000..12848c74131363a1a78d279e0df008422b1707fe GIT binary patch literal 373 zcmV-*0gC=dNk%w1VGsZd0M!5h@%H;fi__%fSEy~E0ryX58U@tnfv?(_I+q}t_4Qnix#T&7(5uVr_4MOio7(N|?EpEfD0jtmtKZ}4@0!2k z>gwrJmf57n=+oBR&ePWO^Pb4g)56Hk?(TV^#OU(!mFe&FgRg5)ut8It(x{3=C)|Cn^R8 zDg-qzb9Hxk1y?s44;Ky<6@`X~i5M6GED8Wh1F_g*4pwM4d#!!qcQlV_X0LQl(QglQgWX)=o~N zs#9y#)#_SWs;*me^YineLtc1zyPZ5(07n2WkS>`vQk5}H003XTz0sdUUgF~Kjw3G;uVrPhOQB1;a)vsXI@#Fj+1c!~v)2uO4Y|45_4W1q{QUIv z^Z)<=A^8LV00000EC2ui01yBR000JwK$NBv)N2g z55eGigLPuDf_n42)IJ{$$6^VMOeY0P^?M!uJv}ZA3=IGPJU%=XEr5cAhKN2OivkCM zgN28QARs;|ZgnGfc`Pghs3$)p5)=?N86^n`2(>yoC94t<5f~UW6t1wbxg-n63jxXj KKh4fRK>$0~?46DP literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/va.gif b/workflow/public_html/images/flags/va.gif new file mode 100755 index 0000000000000000000000000000000000000000..2bd74468d6b328a625c2c3a44f46dee979ec4b97 GIT binary patch literal 369 zcmV-%0gnDhNk%w1VGsZd0M!5h`uh6&>2vnuTm0>e`|5i3<6-H{0{iTR`si-*^77r?-Sy;d*4Eb3)6(nbtn}eki6e!)2#sX_4N1m_xa~( z`}*d=)eem$>`1bABvjFSO z2hY#XA^8LV00000EC2ui01yBR000J#K$XGgGkA`!O2uM9IDMt)U~m|q09e3Bt~bosFgUFR4!2l23cLIxVa!9Aw3uv PA|fvk5D^hS)Ik6{@a)B^ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/vc.gif b/workflow/public_html/images/flags/vc.gif new file mode 100755 index 0000000000000000000000000000000000000000..48213816af17a104ca3d031312588ff1ec97afc9 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5h<+T9!_k92)04bs=7nv8M*+f@Y(Rq2~>hd=H{8IAs zTTHS{089Y!^dz?4HpJ#eOR_ES@J;{#v|wP=X1y~pr7`sM9q#fd=I$2!{A2t3MU~Gd z_V`Ed??(I909LnE-|so}_C)>tZ~fZiZsGOyJ7i?uJ*qu|g5K=G0Qvbm4wMe~ z_%#3k#{dA4_Rs+I@l$)qMrLQ$x7{S@@E=65LZjC@?Db3Z^kDb*E{4l1{QOLw(vPW{0^y9Kt#=06`#+-d6>;| zi3CrhSs^L|8+SHQByb!KqJuGP8#FZp1Qh}jB?crND=iQZ4Hg&#ETR%8B&RJpJsTFTEU}{}Y;GJOAtokgXrmG@ QFDlL|0MP&f)B-^OJ8QU=H2?qr literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ve.gif b/workflow/public_html/images/flags/ve.gif new file mode 100755 index 0000000000000000000000000000000000000000..19ce6c1466f493ff8702f776364295095e8f6f2a GIT binary patch literal 364 zcmV-y0h9hmNk%w1VGsZd0M!5h=;-$J0s{U0cl`WmJUr7F7|H$S0Q4v*`BYTv008{_ zTlhvs`};-f!2lv6%=Y#wa&qIDndM4K+Vd6`{NDhECxQ3(PE}Ri`(a{T2v_<&J?Ogt znn#xPJ3I2$0Q502j53Gv^7#M&jY5_H_S*or)BybaO!@ge`1m&f0KWbGRHdcr_xCa3 z008~{QMuY_eHnPH(uwZR0O8{CgM{9$YN{kh863OF{$woXuOh6r26)05&!b4g?~2dwnYeHxV<01%`Nh0E;(* zjs*obA{jLt96386AQcrbs4yTt0T>G!9UmVD2NSjv0Us@`7zn-#z#Xx&2R{MF3CYSW K%q>69K>$0TIGSMq literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/vg.gif b/workflow/public_html/images/flags/vg.gif new file mode 100755 index 0000000000000000000000000000000000000000..1fc0f96eed0e8e31729bd61b0dafaafd9e2c76ea GIT binary patch literal 368 zcmV-$0gwJiNk%w1VGsZd0M!5hv2~Z&tGEgRk^lftJ3OnlUwTx6Q{u$XEiI(VevkkF zGOEL%N=ve1W4!Y{Hb9*F{CK-*|gnUAlM>PJ3Ra zQc|_7tXl7(omPZrGc~4?bEzUCpn;xH001DLzMfcEx#f|R*P5w3Jg?<~fnSSWex`4n zmS&=zZ-88%gAql>zg<5+t~ffW%@r4ygT39(-^jveQ&YZDNvvFvN#bZ{VO6h+dcDrEeN++Tb~mIuCKQa OP0b3=3MA6fK>#~4#*32x literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/vi.gif b/workflow/public_html/images/flags/vi.gif new file mode 100755 index 0000000000000000000000000000000000000000..66f9e746b6aedf561e504119ba5827873e95414b GIT binary patch literal 376 zcmV-;0f+uaNk%w1VGsZd0M!5hy}ix*`QYQ*DC_I%kJ8lA zu=VVWcW~0y*4KiTN%-~CE2lM>r2|&>G$uO z{QUH*s^DBk+3d~G_xJhG&(HAaYxnl?>(w6k^1$rhM)K@)=;-H*f8e~%ro6nm?(Xi+ z&MV&AUhe2I=jYAIzf$h**5u`u*46Ut<)i%ezGP6{lCw>moZY{_ZT0I`%gf91^78!r z{PFSeA^8LV00000EC2ui01yBR000J+z@JdaDzXMB6k!?pQ33(m!nfJ@D5b|^QE-Yb z3kv6y;RHk&h)c)vEi9H@YBFIIUM&c$!2l^P7#R#V9v%<^E;Sth3^Wx!J|ZIr9|sT$ zIU0)z5)vQ|7zUIFCKU+;i){u55I8e2I0ywK8a+KB13s%PDku;n2stZ4Jv=C@s~{jF WG7=RPw#7#~Vbius< literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/vn.gif b/workflow/public_html/images/flags/vn.gif new file mode 100755 index 0000000000000000000000000000000000000000..f1e20c9412cd1d7b33b1daf3b2c178896dc8b1e3 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZd0M!5h^*lW6008s=0RMV=Z$Q(|r8}|tomt>1Gt7B0Re2K6Fw*Y-)IWQI#0Cy89EhP>g9}zJa7Aqu$J`^n` z8yPPVGc}PU4JQN~A($C15i~qIk_`Xkh5lViL;|4Z{t5e0n`vI=`<^?c9IDRa7k-0NcGH0H6RuK|iOTd$6W&mU?-! zOiSd=P_uOaRjpM3Jpk3mb|N4h&A)S7bXb)D0LPU8)vEyM(@)TMcNoVRGchg`#uNPj z00000A^8LV00000EC2ui01yBR000JxKojm~^BIpmfKvHWkytv8v_M5zHGp5J;<=O% z8VF=S#$dIb%H+}#lLr_KBrBUR46a8i<>2usGbukmG#xn)1_A;Kj2jy#0xv%+BXnFaf>|z!4DyxIZ^PF(}Fj L%n1w6&p`k?=S6^; literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/wales.gif b/workflow/public_html/images/flags/wales.gif new file mode 100755 index 0000000000000000000000000000000000000000..901d17507dfa6428fee33367dfa321144dcfcece GIT binary patch literal 372 zcmV-)0gL`eNk%w1VGsZd0M!5h>W+{~y+8f^{g1|Rx0K-U-R{uKzCkbU z_V)7G*vVT_dvPE6`1pF2JmiFbAX}WbY>sxB#C-6A(&>Vx9`KL0eoJ z0!9a7i!BnMtsrrUg&Yiss6i5?1vSA;vYJ64A1xyQ9w0j^4<`&49UXBU4+I%1DLw-V z5(Eqp5e^O;B^o9-7?uhd2N66I8xtllBPa!>mjO94HykV^8Yns_9JB*93knJ^2RJev SIUK$0m_LeLF literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/wf.gif b/workflow/public_html/images/flags/wf.gif new file mode 100755 index 0000000000000000000000000000000000000000..eaa954b13694ab9e3aa3f77ed03e372f47abd722 GIT binary patch literal 377 zcmV-<0fzoZNk%w1VGsZd0M!5h&PhqoR8+<_HQRP}!7eW1m6hRjw5!6hZfK0Vrvjcot`l>h*P004CW0M%h( zi~s=2L`1g_56L<@oB#mVW@gMmL3{uJ+HY^zYHHJ6UC~ZX!!|aLcO;jB`)Sd~r&_Kx8K1!xK#3pNWCBR3HR1_nAiHUcgS6c#Nx zBM>Aw00#^o0t74)76dOS8W1I&p8_>05(_OaGbD|`4_aIa038Sw X5-2MK!%I#a)EOBg8rc^Y8bJU%oBE4P literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/ws.gif b/workflow/public_html/images/flags/ws.gif new file mode 100755 index 0000000000000000000000000000000000000000..a51f939ede562216b0b37b393dcb489ed82968bb GIT binary patch literal 365 zcmV-z0h0blNk%w1VGsZd0M!5h_e)FtZEa>|qxn2NNlBFUL`1#4*76e*_bn}YdarbA zqV_5(@-8m;Qd0FLCHnvX`Bqo-ARzG#4FCW$`anSL008wqKIQ-b`(a^OS)BAbI`=Rz z`$a`eL5KDL08vMZ@&Eue^dBGiHa7S)H1io5{AOnQU0vb;0QovPoSnn_ zN=X0!Cr3Mj^D;8u008thHm$JGc6PAP(c*D&sd;gy{7+AtqssF&H9|rNfACB_)6>)b zz`*{@%=M?I_^+?*JS?uRuJrZw_IPddab@*&Y4P##wY9alxVZO(dHnqR^z`)g_4V%n z00000A^8LV00000EC2ui01yBR000JoK%dZ;DH=6M&EeqlcyuF)gl4ND5GjL$>A7Z6 zphjcGV8pf}SF3fwU`VABOrdy{Ouf&Cv)hFR0|W#GJv==V6nlMtfrEtEGj2CI139h2?+qF8yg7~KM(>I76BC%549b)tgR3cyaK+k0kXM2#Kp$PK>#~Y Covxz* literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/yt.gif b/workflow/public_html/images/flags/yt.gif new file mode 100755 index 0000000000000000000000000000000000000000..a2267c0546ff372e5c0717dc7c79518a2e6c7cce GIT binary patch literal 382 zcmV-^0fGKUNk%w1VGsZd0M!5hN=dQI%E{&B<^JgC);3%v*F7z?w%N6`wAR(t?(XjVva@bK{F;^OD$=jrF?_44w&xw`uM`}+3w z^6&5S^Yi|{zx4F<;o{-`_xIb`>SAQR@9*%~*VpLl>iGEh`uX_%`1j_muE@v7-B3cn zy}HE5;qK(*Vp_BO`S`A^t?KFN>FDP9@9**P@!CQ!^Y8Kg{{Hgv^7i)j-QC^K&(HPs z_5c6>A^8LV00000EC2ui01yBR000J?K%WqU!EqFd*XuH~2tdByZxHc#3fMxVc9QU- zxkV_HifvGv+HU9d<#Gsw#?`2QOoGoY;Z6hsHX{Io3N0BcJ|!JF2OJV4Fd`xVGc*<% z9}hMQJrfc(ECdV$GbRoW9S55l6FLekHw+9FATkiCBnvw$I|?cWz!ftNGdevG8X6WB c5*={}Iy^iS#tKbOJS7hY2LU|?J>fwBJ6lxJZ~y=R literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/za.gif b/workflow/public_html/images/flags/za.gif new file mode 100755 index 0000000000000000000000000000000000000000..ede52589199b0360eb5d92c3aa174dd9b4eda473 GIT binary patch literal 363 zcmV-x0hInnNk%w1VGsZd0M!5hF)_^b006PF<;vvPpxUzcF*1+H0QR@I0052rWoA>f zX{nC@YQJ{?X8`#~NcpCw=<04pMbkU0T}ZKL6cofkuVd!hTKQL3laW?hxOaNUkaBW! z=I!PinK(0|O8_|l0EH1asaij)VRO4@DWOa=rdQd~%iPpd$-#c2o?ddgU1ML%_`SbN zzjys_a44KW>GFq!yIRD9Dg=(mWWb=&5I7H)D?zi00;(L8Us2Jz!9{=2n`J#0yj4Z J%+1b006TO7llA}r literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/zh-cn.gif b/workflow/public_html/images/flags/zh-cn.gif new file mode 100755 index 0000000000000000000000000000000000000000..b052530978823707ba275dd861a188e55cc0f181 GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZd0M!5hs{jD)lSsJ$0Ony~-8MD*C@0eNB6BFS@ zMa=*J+b=KPKtS3nE7mS9;ZRW6B_-onSmsz(_Rmq*ARy5V4c|&i>2Ge`MMc&hANt&Q z;Z9E4Iy&AuI^aS=)fpMW008J}YW2)ZY@=a6#0LOiO zmFiJU*Kly;czNVTM%}@|@=HtGMLW(_Sl(S&*Yq|v`$$OfLrQFA+Hq~)c5>d`008X( z0002PA^8LV00000EC2ui01yBR000Jxz{c+1@_u`KpBFCl2H5} z6@dU{a^V0ggeKDchQ~7wS}h4+4h`5NWvInMX&QAM0|z8LHaaI9AvAOW9Up~0Dhv!c zIRh+$kRK2?2OAz|3nh<{5D+3G8z2Cs2oZyx7Z(#F1z8qb2^ataH#Z^^6Fo~!J_-s4 L%p)T`&_Mt@&VP;h literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/flags/zm.gif b/workflow/public_html/images/flags/zm.gif new file mode 100755 index 0000000000000000000000000000000000000000..b2851d2b405c7ffe20eadff1b0bccbb7fe8b62e3 GIT binary patch literal 358 zcmV-s0h#_sNk%w1VGsZd0M!5h12q8d85sa)0AZ|Qe7$@CSO9UhacQw>07n3Xz=QyN z09mM6ZnbVK7Z+x*X59b)mC2R!C@AMFC6309Ri;(#I5h2qJzc9^6%-K4004-?hyZf{ z?0+_7u4Cl@0C~K6QlwILxpq#XPLarw=%i(BvTfa;TRAi_=t4Y6pGlmsb?BK_fWLrh zvuo)zF7Aj!c&=#iibv>(IcTqFdAWIBu3d}7i{vC6S+r(QqEP3IKjWfbC?X(Ns8<7l z0{{R3A^8LV00000EC2ui01yBR000JqK%da3C~h`_WMPT$L7t<@#HLB8NITOC;A9a# zAp@i3z}0jzSQGLMj~$)Mf|8p76eF;h9Ir%pJTV>$6K-S!axQ;7FCH5G^(%_TIQaKBkgjm`_4Vd*NT%Co08;=cC@9!j zI{p1s{QLW%S4PJ=83BXlXiPMy_R-c=~E;drwE0IS|{@$n7s@9&mlPWSgoJ3Ku1){pJQz1QK_^1WV( z003VA0P?x1qSjyW@A1!4Hs9R<+)N^;rAxq3MCs`O@AB}RTvqYy=#=S< z9u8+f4xDa0TB@-xB)W-I0RP{6BNP%#KZtT7E1^c L%M#Ad5N#))(?;hJ7b| z0D$3aCbdY%qqGeT4$yw=epR8vfIX8fdcEEcpXWc(CATnFOgEcNUt`NNYj=A(`D;CL z?G3fZ6L-^;J3pBHOz>Q}etYB5_P1v9#j~xq^xKe`xnKjpj=QbTc`$W_8b?Wb zi4=@7sY@0H(~42Ta8|W&-LR_m{L`^K0E2!Pvy__?WkX{n7s5K431U-@Daln#UXy#tB(obxw>#od8IdEIh-W#}^-PH|Y7~aD-i)F*o zB$7}yse+NIS7NAV{AYgctm(C&*AjK_81e1`2=-1>wJc|AH}y{pHISJ@v53 zCvUFGHD`g@{Ob=y^IxD_e*XCnSBy-<*dW*a1~~=h0ucM`mD^aI4dR0^CnqO^q@*On zt5>f;Ubt{?eUS}G(Wno>#A+qW*AYQLZl(!&BX$x7Ik;qO170ssEM z@$bKXf%rGW?|(r27bf-TSv zD}TdX0CM*JhkLO)8|Y^+n~Q^sK~hqR;q|N647YFGy>NTZJsWr!5CaSfwJm@a><8NX v2&h?|L&^Vsef#(CAJ7D_NmvNQpDc_F4B`wr zAUTko46LmWRQpmg=Vh!~m-BkxYvt1)eneQjyV4i>$G$t+Aq(lQQ5ODR6CR)ZBjg*=U4pG>e=aMI%G1~bb|Y=;>SzW=N&QmV?wFKExx(b*a4 x&c|ubJ8{w^!KP+DR-sw5=LiW*Q*oX-ckX;G;T0=atukG^ZvBRhn+y~gtN}|6cWD3s literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/folderV2.gif b/workflow/public_html/images/folderV2.gif new file mode 100644 index 0000000000000000000000000000000000000000..aeb69ac6c35a15d8b8cbb02b80d8ca9318bfd7fc GIT binary patch literal 243 zcmZ?wbhEHb6krfwXpv(GE%Xa73J5O_h$sn+EDee*3yLZaj;#)huZu`%h)8aZPHB!! zZH-N9kIU*w%I*cCSUdIhd~zw-+tV`G7b2pdBaW8%piJ$5GNM6b1BydBMDr=KcGbZw}xNwbi8 nu_fy53hF5C?WHZA(twYF)>&l>9aAn*EdLfE%5*V literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/fondo.png b/workflow/public_html/images/fondo.png new file mode 100755 index 0000000000000000000000000000000000000000..9e2dfa6c33a7f49094960f7be8756868088c1d3f GIT binary patch literal 1249 zcmcIkzi-n(6n1HmLPQ4^KwUVwEAiQmTQ?^sRU5Z7s7b5F5^2T2)xM-wVxKu*iQAD4 zCRRp}Kw@D*Vgd>AZ?J&GUx1Jp%UzNtZ3mco^8I@HzW3gJ_k7Q`8~0}Ob9qHkW@{Vn zj+lYyQ&*be+ARJ6q>k{L9$k{7eXf;QT5*GDnMuB;w#o*)SO{l3;OYLs=LQ7V<7ZbH*62t*-0 ziaE{-aXLSAa_Yw=sn5cMhcpJ#FW#qzysWA+(725bhm&!jI30;6WP}+`prPq->{$>U zVMJ9%FsIC;v{$)s9iZAQI+A$~G>JOl6Blz*k$M#LrGjC2hJ`E(E!cZ!_(RYIdYuMg z`{+E~_KXEoEFsGn(a(TJbO%Zy&ImJ5U7qQJ{eOZ5{#dW%ko5-F68MnxNJL_u3eAl3 zngu>;Qx;)f2_xJgFo`=3oEZO^-!N-Y7NRWSxGqmqA7ACAEGD{Niu<9{%M7AM(=WsW za#KDIgQAtcgBM0b(U+iMK;2$^&K?WI^_silFYF5cRSf9>7>3vc{geC_AlYk#L-{lD_!o4Hqh zPPzEI=ltKZo{!l(-=}SR8@}dw(8{O2%N~0!ei*Ru zrv2QzuCuRO&ARO{{j%kh%jT0V8ce>fIpvzsgp2CEmzBCMD72lCXg(|4c$%-~I9Jti z*7BnVuVjb-ed1CQR|DNig)WpGT%PfAsA%PdMQ&o9a@_TMb;$H2fM2vQT_>tmIipR1P$ zQleLpTfksrUr~^loSj;tkd&I9nP;n{prD|nkeOnu6mIHk;9KCFnvv;IRg@ZBer{{GxPyLrY6beFGzXBO_g)3fiCt!HVtT56L0-Cz zK0*+$`yj3cCJSJ))Q6`_nA71=NfQPl+-YJw#86sV!f@hK6|evi0~HS7L<`CeA(^?U z3oqmqjwY_I;JNM&Q=Gp3 zy?;{ZgHFt;((--kKf=$2ZhO8~P~p9}5@Y7#%^p*@COz>{TKQ+L%VI;%7uq}5sYLeP znm+jtw~w8b|Dsh}CaQ#7IcukwT0K!HMgCI${^tvhZOoq^wBkb!<7?ptR zYI^MF{fEOg%!=$FVdQ&MBb@08gffzW@LL literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/form.gif b/workflow/public_html/images/form.gif new file mode 100644 index 0000000000000000000000000000000000000000..3503f66a12a7697eb179ec961e59a729a8080333 GIT binary patch literal 990 zcmZ?wbh9u|6k!lz_|Cv!V^^|d(V8olu9TG3?Af)Yr?2PDt3OK?T`4JAbLZZdo~}Jd zj-6Sv?o3S7l$yFVSFXL;v+K&2Z(nNadgjcU5si|7? z&>2hSN{C_6B5)iXWo^bt~n)T zOO70SvSrhioV+D}e*I}_0-C(W#}6pGWzDK5Po8~oajIFeY{`{NcWSCy_Uzl!(>LYK zyFW{oU3v28OHbdCGpDYsS$8ER3Fy2nSFU~8v+K^6Z-3^@1G=qd%cd=JW^LKB4d^hS zUZ80}1wh7>FQ0(6Y`Jsm%btCAO3K!>G);N(><_~z7?B~M_>%?fZygW`$`cG6yBYjB zWIQ%Ja8OYfkc!a=NIWF$KOv)_u|bJRQA{r=f@2BiVPVH9IwFk+Ji1kN{bD2pQ@pq) zDo;2eQ|QFN)TUq6q0$lHB0AaCPlxl?A%_za&BdiEPX;!7PSJ|=yQo>qJFB>mD9aJinYPDLc)w;X8>-Bo0(dg~%?eFiOnwpxJm>3-$Z8n>6uZYRXEm`&- z@pJ3L-rm;B^+zg_L`=j1S5cLuVk)i@`A(ChB$mXJM1HC!$;3?DByy#?Bo}jWmtY-Y zAs!_nkV&ZEiAE++)ud{wt{Rz-eM)LcJ!xcmu9K;mx@lxJyiTs>>aLM1Q>cY{Xk?)X zM=8=WKb(+&3Ji6;Ep2eXu#`Mof|89{a!ZjNqQE@4r^s$mW05>CR64_RDXKJzZ5&X8 zBD|J~K!pkLz(87FQebWtIV{XT%--E1XNNbqx%RNgQIb7L6D?U18zGSjG2k1on8OXC zDMKdeGJggwQGqFYz;o_7U_@>Sk>LbdmH%*@Qq%`Ge}tgNhTZf>?(t?ljYot>TC z-QE5D{lmk$=z-xZEU2FtJVKOxm=i4%>nSF0oU+noc` zvt4pYYSBD;eDL($!;^YzaB=Bt$Kvs!&ZE0$doD}Y_`VWAhyyGV~8|v8t2+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2lastnode.gif b/workflow/public_html/images/ftv2lastnode.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7b3e55cd044af047e571b8e46d99dd4b801ee60 GIT binary patch literal 142 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ727U&`e=?ytsfj5H?w)Q6!MTY= zCBcbhsYME5Ky0LEz@P&%5oCu0i}Z(+o~!p-ygs}8e}YEQf$*yI>683lZcElVAIHLA F4FFl;B{Tp4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2mlastnode.gif b/workflow/public_html/images/ftv2mlastnode.gif new file mode 100644 index 0000000000000000000000000000000000000000..11ae43a5ae00b76b81e0bf2aa8d2b33efbbb5e53 GIT binary patch literal 125 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ721W)QkPeU;3@lm(Cp=eAeekN* p_`j$^Uvhd>T*aykg+2Kb&IWtk{95(e)U)Zpf&vd6DN{iPYXB-WAG`nn literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2mnode.gif b/workflow/public_html/images/ftv2mnode.gif new file mode 100644 index 0000000000000000000000000000000000000000..fcc2d37333116b6a7fdafb7eb099b0fbf16f5f63 GIT binary patch literal 97 zcmZ?wbhEHb6krfzn8?h~(9rPz|9=Js1|X^UlZBCiftf)E$YlV@GcXy=>0inAdcV{h y&KuRqH*8MaDwJnxxm_{k(5@=y&r{V-%~+?@{-rzd%6SH^X6Fa%Bnm|s7_0$apd^X_ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2node.gif b/workflow/public_html/images/ftv2node.gif new file mode 100644 index 0000000000000000000000000000000000000000..40167db1a5b31ebead9581ca798aa406aee3aa48 GIT binary patch literal 147 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ727U&`e=?ytsfj5H?w)Q6!MTY= zCBcbhsYME5Ky0LEz@P&%5oCu0i^7MKo~!p-ygs}8e}YEQf$*yI>683lZo9tgq}1G- K5^~9c4AuZD0w@gt literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2nodeSimple.gif b/workflow/public_html/images/ftv2nodeSimple.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ac5e6f9fc1e50298fb149380e94b788e187c61f GIT binary patch literal 93 zcmZ?wbhEHb6krfzXkcV$XlVHV|G(ltnb4fn#1sX0PdA0&+{B`i;KZ`jB84y@HqtX- sQ2fcl$iTqJpu+$JAe{_MB0c>pPrv0~Jg20oz+Z^fq{`h2jpc?o?zhc zW?<%!@z}7yv5|pKE2hFg@o+mUqsJVJjSF3y`ItE*W=u>t*2|&GC1GjgaA>j&dy`3J gV6s<_u5Hi~j*V#^vn?W@ZMj*fes~@;GZTX~0L!c;O8@`> literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/ftv2vertline.gif b/workflow/public_html/images/ftv2vertline.gif new file mode 100644 index 0000000000000000000000000000000000000000..63ee93a0f3886253fc434c0bbd4732c2593ed254 GIT binary patch literal 140 zcmZ?wbhEHb6krfz*v!Dt(9rPz|9=MJ08pjkPZmZ727U&`e=?ytsfj5H?w)Q6!MTY= zCBcbhsYME5Ky0LEz@P&%5oCu0i{yuso~!p-ygs}8e}YEQf$*yI>66mBcWK4AGFSru D3pykE literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/gear.png b/workflow/public_html/images/gear.png new file mode 100755 index 0000000000000000000000000000000000000000..5488da9ec6824b0e541bae53f3f815d347f13dc6 GIT binary patch literal 20152 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 XCz!Escr{8=00000NkvXXu0mjfgJiz4 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/go-lt-off.gif b/workflow/public_html/images/go-lt-off.gif new file mode 100755 index 0000000000000000000000000000000000000000..c68cc4f620b6a19236a9bb0981b1a4e00bfc13d4 GIT binary patch literal 246 zcmZ?wbhEHb z-~as&1PtT?#h)yk3=9GcIv@i;b~11jGblO;IBZzp$jHQQ6mepMB6ACqj8}}ugo91p z62^KJ5`m5Gtc-STAqOTpHce(^S`adGfeI6gX8f_5$RdYRjAqOajzmskXq;l#_)8~p uL5A02#;$252d+3YEc54`V&kxN)m3Iy@tCc<1Rot~<6xDO(Kb+Eum%7r0tRw{;!hS%1_l8J9gqPaI~h1i7!(}@95yU)WMpFJi#W02Awvrjo52i^jY`e! zg5nu>P82d8W8`wu;!v2hq^X}Xh>c^xq|~N<4uLg2md4MHGir-J%kd~+U}Vy+XZ!ne vW5dO%?#vQ@GZw6DWbj)k^`m0Js;jHn?eq>*T~&5zPY~p?@d!(BV6X-N{X|ez literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/go-rt-off.gif b/workflow/public_html/images/go-rt-off.gif new file mode 100755 index 0000000000000000000000000000000000000000..738a3508bbd05e155015105f668c8dc35e02cfcf GIT binary patch literal 246 zcmZ?wbhEHb z-~as&1PtT?#h)yk3=9GcIv@i;b~11jGblO;IBZzp$jHQQ6mepMB6ACqj8}}ugo91p z62^KJ5`m3P4085uAqOTpHnA`=&GD%;a`a>|2tLNcu=z>DZ04YQS0X1hoS$OP{6i;l ufy1dq?%mT&5)>FNFZ1V}V&kxN)m3Iy@tCc<1Rot~<6xDO(Kb+Eum%7z22W@J literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/go-rt-on.gif b/workflow/public_html/images/go-rt-on.gif new file mode 100755 index 0000000000000000000000000000000000000000..99ff1da235389239f1c2a317a2b29b2a27b93352 GIT binary patch literal 246 zcmZ?wbhEHb0tRw{;!hS%1_l8J9gqPaI~h2N85A7^95yU)WMpFJi#W02Awvrjo52i^jY`e! zg5nu>P82d8W8@NH;n1A4q^X}%h=pT9QR*ocdBGDgmc|Wd`gz0kuKb+XaDJ*i^N&9f u3l5xGPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igM* z4J8~K`gg+s00}8cL_t(o!_AnxuVu+q#(%3;)qb3F&po%>{TTW&Ee2T#Sr(QhL^41C zi9^c?WH>P?84`g5qDlD^utY!rLIem0h`}Pj4B(LsW^80L%-Ckeec$(ZRzZ-y{o?Z>RaDh>xjGa^Eg7`9N3U2hwR`PEQ13S%#YrHEf|=Cv%xr{ zR0jhb+@{^{3K&$I?@ONV=bM{FpC!Y+QtSNQJpY#Bmx%iS1h53aW~$I#@vV2>^lyCg z>!1bqii8R^fljDKR^20h=k+h~%E1#^#ucH$=#>-|3_^ff9aXu;k37SOIRts0C3QeX zz=)u@fjCUXX*=ON@4w}L`n5l1ajWIlt;bB`hH8hjy3a6809>BE#fQiL%O8IEPdw0z zgh(q66eL`)o*^_~h6Dwl(4af2DnS%Ma2zwES_=U*L?RxsYG{Ne3S&NgT(*<|N8?Za=-c1_ckbSKfaI2S8__(_v&6?t$d%36mi2ng z{_PcC|Hr@Mq@4SP%^TYSr`zGRO`f>OTQ2gJ^XZb~tMjj%PXnjZ@Y>n9Wxhtv#x2L2 ztFN3-6D5F4CaBEEZtfUczW?4g{jc8q8~*42{)GVNy@U+|yrzsZxwk9qCWzd;@+`o$8j5z|O&7Yup8>qrU- z8StKBkCECF(-zMIlL@K;3r|T2yk@$vk54OdQJUp~ zN2`|YRf{uWTDU6b$PlQTO25~!TEtoJMNpL+yO7}IoSCMPe7WIY-~I=F_lti(zju!q zt5L^}X?;P%9#M_T1w+oHHV^~UY(!r%G9c2h^$O_>k3y*lsv$bi)jdiadGE*Xadh<* z>4p3E9`JDekYzd`PaL4?}}_jq*w3G4O_b?Y?AFpLla7>GH+ou+As z%!`&2{~Kiako? z_VP9l?>=VHtr*9NYDT9WK_cwF#ROGF1XL3tgqyjZ0|u~&YhJngD)$Z^5<`RK3D?t?3n9=gBV88>!71Ya;*>J5*^4aLUoiA;WNm1ZNxvEC?C`A~QoN zL>B!%>-8;`ixq8i7j5RmZ3YsA5Uw>@5NYw9j+)e9rBWGa;~s5XATr@5fIP1;ZIrW% zQ%=rK*>1N?(|`#C5i~Ws`pI_z?-VmGx0mExIn{H@L1ndCv)Vf#q2!#gQc;bhHj!(+ zi9#1AL_xHnS@g8yf_ybS&)D^Gl7!8$VVVjO0;%t2O^G2jlT!P!3RE1-oUx32c=`cb z+fu0PFV{3(i+B&!sI}6z4TfXx1QgscMoi@WG#^Q2LCK4-#Jy`pRi+cMJk3vPD@ zXp?A~juaA@%(ee6y?mmUt1xRsc1MFi^f3EVnp2s{ z+>o5*Q_k`k=bK~Nrf0F(W6|x=(2^Q~7SgIgPUPd_pF_AK#cr-JnVSZ;i5MeY*HLWN zTlE0!^d&o2azjhR#gJflaG*k%s|i&lmx)5=;^GoLOGJI5~;@-dl_ zu5CGQBBhRC5D8$CDJ7G9LEkT^2;(*bk-l9b5pvFGc)6~H&>*ND8xE+}VHdORs2QXZ0w#1!)3B>hboR)Q z7>0q9lQX{fx!>ph{zI8lU3C!n(ZzrJH@^LsJbn5hXJ;n_g{E!i0s#Etd!OI>?3Z}B|7pQNJUd>YwwdT@SLpkV9b8wcwN^Bwmy1fvyAJ&M nxiOhLcFE|FAcFk7{&Dv+RAu-i8?q7!00000NkvXXu0mjfmTR#D literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/group_add.png b/workflow/public_html/images/group_add.png new file mode 100644 index 0000000000000000000000000000000000000000..268bc23ebbe9fd4f51bb8e5bb65f8036f6a0add0 GIT binary patch literal 936 zcmV;Z16TZsP)^h-ACKC-fga|OE1`pmqx{@@1pdaiB9VP%2vyf$Gz>5r`6AF@|pyo+VaYy z5AvK|bfkd@fV35$p=$lGO{ir9n)7~2N-J@C zp26~;V0p#0`o91dvX4zAC;BZ>R*j@OkzCu6Q!xhrDj(U%+~MHGw)*ZypSRa2S}sMF ziZ#xqKQ4?{6+7*}mZTIHiYPL@kmOr+*?#u5p!WNF;~BBh!n5IB?R)Bd{RQ2)<0{t! z4P+cuWDDzL^Ld&MHZrjk=gW(yPs$nV<4TPC_` zk!PKe)G(=qET@B>o=w0{>E<8X=7%~&FeD_Kgrt-suf(`vuRs%m)wwjO`P*c38P@V? z@}^8_jry;|zQ0>5+OEcm9sd#b#h8y!^)x%&8VB~aa+iA-7q9jaofzcxSmC?`Acenr z{>Z-Yn}Jt8Ecx6B@oA!-_h;&uY&yolha+TGR*l{MMhwZI(ens~D9{oNaeXb-CZ8Je zbRGy+p6GgEuQrqu%sB2LQ5GPf?Iymc5b(RWcI^YHB^c(=y)OX}s(pgx%nb&I2NZdr zYjNzM=AG*Iw{|j@EyGA!7)dbF7P&P+eBNaB=DWB(3Ip*z!gWV@r@xzYF2Tg)R9{30000< KMNUMnLSTZ!)4HJm literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/heartBeat.jpg b/workflow/public_html/images/heartBeat.jpg new file mode 100755 index 0000000000000000000000000000000000000000..e6e767cb121a890150ecd5d1b0c7f9a7755a61e8 GIT binary patch literal 1338 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(E(Ug>gt`C&BMTEFGYb zP)JxrQPfb$@dHqy1S11n2}C6mJ0k}tP)0=%CB-!$Rys$*-6g(D z@nU%7sp*QV)@K}An;kW8dx=lt-@}#JN9MVv{(3BWKG&?4=SAVhDk+&s1-&uamxGvC zq`h`a+DQs65O120yf5&C;`I%!HH`~uGhTi-d-%^+_PX`)*u>DvB~?9^+VWKk`AVm_ z9Q&}_IQ7Qb+_Ps4oEOZGPjhd3X1z4*jO{b^>6}aaGnVwGTd*fe{b%qFk6pU2UFqWO zu(PXnHay7+%MCp(8aHdA$eZBOO8o=Zb{%Osu=}qW=b0*rnK#aFeOhsT)e}n@oAXjd zeLb{8uPEKZqr;e7Ojo~#w7J60AepH-HAD!NwtDo4luj6Q$+{j#oQGw)jmSH68^ zW5+lDkg>=1Qwcun*Ili67Fcy!$Vn?a_V%4Kxh0dX964bxm-*pobhulYjZ%QyB(Ysq zUo-zWJep{Ful4Z9x6NEOHXEb0PMwo8+EnOuqTcdNO~vV8N40G`H#5sFO1bINrgYNE zrZqeKu(X{)>F?(&7cbnobZytONvn@dirdcGps2cOx74xqA18IRu3m4zlthjT z^Izgs)2UR{sbrLVJi|q>A#`@-Sju#DfB*XZtLERAKYCkl`rnY; zD!TAv=pw#}QzIRtW5k2nT&JvgH|s=S&!oj$PwVQQHa;C?&gF6a($mbi&Rus6b3)fw zOD|fU>zK5<;GN{siAF4$CYG+R@AwFqCKMVP+8tB=^Ih1f?n2qtjr$({i8^!oTc+Sw zlOqpxW<>r=-L+WdO1!F|Z#93wOqLnk{tuju-@hz>yYdjP;<2^r9np_O5;mVM(poWX zyJYDWi}yRG8$9~DW8S0cdAF2y-fP=<;-J!Mmy4T!d|9wnP^x48dinR-f4}a!E3Cb2 zrmxj1me7?iMJMcNj0#~gP+*o{(f`}{x6;f>nv-VEU)nx>S6%zsPyVSJFXzPHzMSv8 kX7SF232)3qX0MByw13KB6A=~`7Ze4MDI5U`36m3f5*MQr3LG6X z9ibcv78Dt-2?+vJ9jyr+69fUewi6Tp2m-me#=Ev1aUK*00>;P42^s(}5DXpC+X8nk QFU~mumk0w3*CHVRJ5q~&mjD0& literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/help5.gif b/workflow/public_html/images/help5.gif new file mode 100644 index 0000000000000000000000000000000000000000..154d29fad12fa5f52262c5fa29952a90ac52df80 GIT binary patch literal 13259 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

    -w- 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

    *(aZ9gu4y($YEcnH^xC6HA|}3N;a7>v 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 Bb~*q6 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-calendar.png b/workflow/public_html/images/icon-calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..83a9899603fa55710746bd06cb28e3b6a5aaf024 GIT binary patch literal 1218 zcmV;z1U>tSP)VCM6{$0000000000 z0000006hQzJOBVb018G506PExJOIMN!o|hK$;rvd$;r*l&5n+a>FVhKU;qGu004sk z0E7Slg#ZAC004&o0Ehqpi2wkK004^s0E_?uRRIBv00E5v0(1cajR6By0t1Z$1C9X$ zjsgUR0|bi%1dRj)jsgXa1O<-*1&;#;asvjB0|$u(2ap8_kOc^l1PNpZ36TT}k_8Kr z1q+h~4wMHEl?W1+2^E+N6`2ben++O#4H}yb8=MXuoev(K5FmvTAfFK-pb;XS8zP_* zB%u=}q7x>g6ept;D5MoBHz+ALDJeNADWw)FG$|^j7ArR?D>^DGrWY(ZD=nuOE~pqU zqb4w^88M_SF{v6dsv0w=Co`%VGpidks~a}095<~UIHN2%t{ytCA3LufJgq7{u^>LN zAwRMqK(iu3v?D~ZE=8$0MXxtSwk1fnCP=s@Nw_CUutH0@C{4FDPq;o$yed$Qg z(O`qge1z9#h1X_{+iZ@Gj*gIyj?jUS-EWeTl9|(#o70$_)0&~xo~7EFrrDmR*`KEX z0I1rZsQ>_~*{8F!v$Nf>v)`)z#hI-QU0e z-~a&P008dp?)3EZ_4W1k=H~YH_V?!I_xJbs`1twx`TF|$`}_O+{QUj>{r>*`R8K{Y z0000QbW%=J00Gk&b`TdL5NwEL`0kcU&K~y-)jgq}? zQ$Y}gzuled*w=O(MHUnRkp}SuNc8Xw2!VuXcnmsT0`eY6G^r@45LC305E2n05dYk3 zdv|9jh%MW(EsnnO=**ef6@U}qB`b1o;nfd7x(;^?^wtc=;Ch&e+({t<&-=|nLhzC- z=a?=coV<>DCR~Q<95{W@ZnpLc@tWeao_x9o`JyvI9M*epp}3`4lQ^8EoHQStnx=z^ zIl;_*YlKFbqj+!GtH#&~ch7FbU&Y7}%wj4mg~|(-y)%tReaZc!pl_lfpjtJYOKwaf zNAFBix2<~E(TS-csMASZx&+#c5}f7qv;O}1e)aXsA2kG1mxsY&mUA7%Ysw#EP9O4Q znAMQkJ7c@tBVm^e1hbuq7|{Xje@j+j zl@8Xv>h`bX@0*-2lj)3UFD0n1ve;tY;V`b!f^wxpYfO8Ia!gs%+J2}Fr!KG2LIE?u z6qwLlkdTC|C2UeP4gN(fpg;p%;8Bl4b-R8%&>acI=-D75w)HLi)4>#ku(!qVWH19{ g`VhDIKh841U%O8Wm29!W0000007*qoM6N<$g5Ed;f&c&j literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-cases-inbox.png b/workflow/public_html/images/icon-cases-inbox.png new file mode 100755 index 0000000000000000000000000000000000000000..00a804394b2bfedf4a61fc291d6c11080f3ceec9 GIT binary patch literal 3449 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-cases-outbox.png b/workflow/public_html/images/icon-cases-outbox.png new file mode 100755 index 0000000000000000000000000000000000000000..701e85fd96d3fad9350dd5a3148eff5238ef5be5 GIT binary patch literal 3364 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 ZfDp?~Lw{vQ1}NVQz@XioY8`@-{{ax^Di#0$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-departments.png b/workflow/public_html/images/icon-departments.png new file mode 100644 index 0000000000000000000000000000000000000000..ffbfdbe88b42c28cc00033b44937aa554be80213 GIT binary patch literal 50463 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-language.png b/workflow/public_html/images/icon-language.png new file mode 100755 index 0000000000000000000000000000000000000000..f26f3a1c71a1d760f6378f8fa48425374e8017f5 GIT binary patch literal 1574 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-plugins.png b/workflow/public_html/images/icon-plugins.png new file mode 100755 index 0000000000000000000000000000000000000000..5c8af7d2138370a2307a60f4199898113cb5a1ac GIT binary patch literal 1763 zcmV<91|0c`P)`BL#FihHw?kvI2JYsJuK z2aoT@zX<#Pz&C%pv>TT7{gVq`o4&AZIg&gLp#}1OZthU=+T8CheY|SZx67Ua@Z=|J zkLM;;0AmcB_IJO#w)6SvE86cxA#joNbMU1PPkG=xjib8d6Jm1ox#!Ev52t$+?K0+y%5qJ+myB$~?IxC^_o$VR`a}Lst)?d-_rX z_myu11S-Ixs|S$bO69Nkp8#N#`o9V=RzLn__tRjQtpFbiz6Qj`FS^^b#?p?|3}jQS z7?%ZOzpo+}Zfu@~G3PYW9qPk%`<9$~WM6lW1_UA{S}7df|JW}-*p1*D_AYs@#I2oM z7Hx+GMgY(Jcfw9%#2do$87tugj@bhN!M%zAbKUK2-MDMkYU}vW&kH~6AO?E z$xM8zaln(MXtG+EY0c!dklMETT~KRt4$G2|3MLvmz*+m0coW7+K=6;is82*9!hSkD zf?7!P6mnt|`O*jzDs&*)`PRK3EqVZ)%~-O1?h(Y;vP`lWo+{QsgIa(YuNwok@H8WE z!m^nYjKUQ;4F+-nQ3*o$s$C1;SlqdE+f7sF;OqETMLWS0bDQU5$nQ6kifEMtthF_O z8K?BF!(lNH2YE3B$9KUj4Q>+(D5IkiFp3rLcWrE*mf7~w9j{9ob90Q{1?U<8y?bN1-^ z1?w;rT!l+Dy1DgMC=@a1Uo&t@7D5CFjEWF}3RJQZ^|&aAJjRuaYUmg(@A74Vk@Mqw z`u6p|*S0465O0ZfDWOLSr<@M}2pfQ7#((_@lb%#W>Ip^SZ39<*5VnrA3zAN5dgoS&RrXG7B{70nxd>g{{_IzIg3tf zR~&ZL$CP*sqq7pL0G#W1eg1qa$){a;`M1LWB(aPD<-79CK(4TO4o{P_p#n2!#Y#=0BeSbF9%;b))y?t9xKN0Q$;r0~v^t8p-r|I?8 zlCs%A-oqcmCEVHBQpai>hF2Gv6vLX^=C^RzYl^sp>8TFvcH9ju&&=+mQui1E{ktyz zD1E*4=t}*TWm{7MNA$8JYh!3ic+zR)Z=E>fUHuRX&&J+j2WnWe480 zt2@&f{PfDFBl`yq*=_Mwucwgjc&BSGWYauPGqrvZ#7J!r}$;)2A=Xp|vd%sZ`BDjt=jUm_W2vk|%98erL0pNBt zV1)YNyFrvxUm!TD0_w`3>oq_(7}b$e6#&(62T*Xe|ntpQWkooo7QFxD`}{1X6FBLRUp zICO;aJ^(G07A7w=rJx+7EdH&4>a)QG@H-_(7?Up|_!DBT&WD%zq;~)S002ovPDHLk FV1f>+LjC{% literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmappcacheview-rebuild.png b/workflow/public_html/images/icon-pmappcacheview-rebuild.png new file mode 100644 index 0000000000000000000000000000000000000000..a57ecb4c379147f9aa5202cf18e8ec3e1e078879 GIT binary patch literal 703 zcmV;w0zmzVP)Px#24YJ`L;$e>s{pG&%~Co5000SaNLh0L00!&;00!&<9(6c100007bV*G`2igb} z4jUv7(Hx-w00KWrL_t(I%Z-!GOItw{#eXw-NsLKa6G2=B+l}}i)I}+@cI`rO+fpbL zgo>*o(v5{;aa#+aAGqwoLbctPlACZvt#@Z-4eYPfDed0LJ+Ec&u0~-utgW zHk%zhI5-f~G-ZE(-*H`6Y}*#sb%S!bEQg1OmStH|EEZ?aa}9u0Di!rS58wB(Z9BZS zwuXqHwN~kLnxUbgSglsWvaHy70o9rm3WY{8nT(sJ$+dy&l#fil6etBjKvygV5Ezc*6r0WFEvXxOZJTg7 zERjf5we0#qfNpc(`#xH0fItI`j*fn+*Xs`|mCCbRE;n#;a`N4E-B!|PFH^PhlgKit#_7}mp`=Znx;u_Z!hiZjy_qd ld=aLm9@8-ri9|>H{s18fB$b!$&o2M~002ovPDHLkV1iIqIqLub literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmcalendar.png b/workflow/public_html/images/icon-pmcalendar.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f1c659ba77a89905874b71df89fcd4d644658c GIT binary patch literal 945 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hzm?8pvLR`0Q z-3k}6moVPxuMWDaFw z?qz1~V`T1QVrgS$>1JW+Wnt-KV(nvL?Pp@`XJ#v6X6t8W?__14z{&wc6InP@*f}S% za7|+62BOJqd{fx@r*a5Q;}o62Ejp81ayGA24X@N}Ugbb78a9wZix=qz%yPC%iHP0RDUK^aecWU@lVGwJ?@B6!ZG9IU2&;L0@6;Ir5_B+K5JQU zI=t|7c+ugsnv3x@7ZaLK*0fwtYrUS({T}zkmPv^XKp1zyJRIW1J8IOeqYEB|(0{3=Yq3q=7g|-tI089jvk*Kn`bt zM`SSr19KS&GuB>hIs+7BFY)wsWxvHC%x@$nAKKso6gukZ;us=vIrPkaZpK8J;~&q@ zf1ok@&mA4HlnowgX%meMJdBjheol1MS)#+{#`b-0jLqHR^Ud|A?*>+UmD^X_rr&Uu zP5#`|u2ostn<8?rpI*62EjhsHXwbTw(r4ZFrY#lWcjig5`y>{2PZv}6mrW7EA%r#p;_dh*MTO8I==w%>B%v7Iay z>V9QxnQe)@$M}!29FQ>FbZO?fbL!>=e+$1Hs{8enG0y4qMAPx#24YJ`L;$e>s{pG&%~Co5000SaNLh0L00!&;00!&<9(6c100007bV*G`2igb} z4Id_l^#;%Y00KElL_t(I%axN&NK|1IhM)7@tE4CuVFqQEEfk_Z%Y~z08wUw74AhEp z5e8=E!k`o?T0~e-B-p~JaACiz(hwxb60}IdO*&Ng2g=Mymd>d6ruWXYa2$V&d^d-W zbIyCtdCzx*S*!zg@*i;SS8MKUan@Phu|8sAilw5WBFHLmrJ$Ra5Bo`OwVCpI+jW3T zm6hQDr4&jjL6{Sur-ICF#NrRs{4^_iXGu*Sv1k< zJ)7gYYTo~|gMB$UOpmtV8+gX~+a?j>r=~o>RQy$v6A}Q>0h9C zVR@c%@t&V?-vqVid|2`2OsU<>DX$g^7j9oEY|~A^Q%}|1KE8bY!HrX6#BMEM#LmRw za1gNVc>-B5w-O;}`3QRIx%Hr%cc0u;9UEhNii2J=7pK#?XiT+qbp&UyhwFIsqKoIv zgOuj_aik^D_3J2kd54$jq~ zrb$#()ZYnSHNM6@Fi2_XWi}?Jp=mmHNNvL~mL&r$I;IRqI_(`FR&!fO$Zh~q7rd9k f0@{J!OC5gzDCopT_TXoD00000NkvXXu0mjfXNxi^ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmcaselist-setup.png b/workflow/public_html/images/icon-pmcaselist-setup.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8ce6249284ec41d6624c51c7fc24f6bb207331 GIT binary patch literal 760 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 Ze*rDChhBqn-M#<-002ovPDHLkV1g?Q!$<%C literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmlogo-15x15.png b/workflow/public_html/images/icon-pmlogo-15x15.png new file mode 100644 index 0000000000000000000000000000000000000000..10ebba29e81af12bc48240c7bb7d171c25c58e3c GIT binary patch literal 957 zcmV;u148_XP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2igb| z4?7;fOtU`#00TWqL_t(2&sEY}OjCCN$MN6)^z>rs!4`T&kWwsCAZ)C}D9(o^vT3GS zG@JUMiI;eZM%^3P784%K6619f6T>uSs4)y@e2{IBxL`~aj3HF&r6^LMrBDxr_Oz$% z={e``lV|8&&rTAEhVMu;RVTl`eB%^Ut84Rt|__`$``u(h9cTc&E-t-mt@;V3;@tE zo?V@H%YDl&%T`t|Cr{%V`p)dfz#ECl=EG!WKC?3znm}2VHD1+E%^+m)Bc7iKAKAWT z3+;Kqla~_-7?lFi7~Gg9GE#4|L|{vybLSu@L?iPer=g2!-R6jQM{xze%zY5}J^I()29!wAv)>B5XQO3X!F_#0Ml5y>F z4;J4H!0Yi~)Y6P$jgJ<>E^2b>nLB~taWXVE{l(a1vO|Er_UP3CMzJPYSOh~RijG)a6t&+j_pZU;WmuBpC!!;tz#q^xRl^=W(+<$9|>-?oRf{ol$V5}EL zgAOm9U(s2IpQKC%YSqj5bzQ~Gcb_^d2_Xv0Ib3-FsB5UncOCi(N583{OQl&NtnkoY zz8bT|KD1imh|6XYjEZ2nI++ln{BO_bOf0i|y%ECn2%J?_$Y^bZk2~qtZiehx>%DEU zdG2;S2-cP8HTOOk762|>JkOqNZ)?tE#ceJ}*-Z*`?%TPQ=Wq3WyP~-C(S}dz4}1WZ f0H~@8hGFm?pFVA)iHO}P00000NkvXXu0mjfX6e2v literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmlogo.png b/workflow/public_html/images/icon-pmlogo.png new file mode 100755 index 0000000000000000000000000000000000000000..3576c24cd8ba9eb2c15867812feac091d369a07a GIT binary patch literal 2809 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 LNkvXXu0mjfX{}sn literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmlogs.png b/workflow/public_html/images/icon-pmlogs.png new file mode 100755 index 0000000000000000000000000000000000000000..1fb706b94a4ac0733948d00de6f5b471b4b02c51 GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&V!3-qtMdT|0DaPU;cPEB*=VV?2IYj|JA+A6g z4u1UjF=4`lS+iy>T)1%2qD8A$uimg>!ucJAD{XV0Dk2M!!NcI@QIQ)fWn-1+n8 zFI>2E<;t}iH*VblfqVDwKe&JY;lqcIA3b{VH=O_FEi6;@k=)k9bc3g)BW?977~7Cnp?WO1Z!g;NcX*#C1gVNF#%WN*7y$lT!wR v#u5t4`^!(9-CL75&?4z`*cfo@Dw{%aFf7Ll`_={an^LB{Ts5V6lqx literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmmail-conf.png b/workflow/public_html/images/icon-pmmail-conf.png new file mode 100644 index 0000000000000000000000000000000000000000..8b64e2e2b7e6acb00d5f0e946291eff32ce00dc3 GIT binary patch literal 658 zcmV;D0&V??P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igb| z4>c*~ayz~N00I(8L_t(2&!v)2OH^SL#((d9-}`55?l{h*289_W1*usO4MepQre&@K zqi@i+2#UT#%eEFl10pS2wGdiZq=eawC^`Ng=T6R@x$kM==)zUl1BU|#9(Z`p5B@`{ zGx`kP#2BrIijRsD)=KiPF2_;2^r19M7-pvA3<|@{l(AOYUsevdnDfYBAVs>f~HW7XW-wcn(1 zn6O=I(TEe`KMk(*`TTY*crLyFS@`Ae%MxK{{R3007*qoM6N<$f4u*Y00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igb| z4FWl6Mqhvc00V$YL_t(I%XN@lOj~sT#n0`%ZEs6IXvc zgT?sJWSW^7F-GTuj7;N;I&~&fh>M9a^J$tbCSXV$IAFkrvdN%hr4GB6b?w?xIQ$&o?#Rku5{Tue1RarH(H~Bp>uYvA+V6O=zSpd>*rUnllG$L^PYh4oTUm|IJ^OOU z*)I-#rMWvFDm+Xii|>$_y8|} zLZMcvk<72-3HN(3fT z1tf_=6bU4WqC^NJLLo^2Arc^C0LWzA%+#g6)bem;I{N$B%58gAdBuI@=;$9ml2T5h ulmVsxmMEnFC?tu3(*Iy6gFxW+&3^#%S($^UC^cmO00004u*Y00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igb| z4FCWIb+rlr00R9cUU& z;UUn&i8G6XqM>@oC2;oW@$asjygGkq@KNMeqGvNK{`nC$(wpbscMk)61nZ+mFd^{cJ}u>(qxE5g09;_z16rR=D&XS zK2KMf@$u>;L_`2F7!K>|Hg#Nzj%}jrQ>^rsp}7M^T~6&?Xv$a{aQyxG-*N2y1H&(! zSa|IE%8ySEl*(wE4M-;;Ll4U3P(FtYIdsUOkdtP~ihATk0ZW>UjiPw!?Ss|1XI}i^ z)a2yD9)idM;g;zOhYtZRxLHFjSa04P29Sq5rlfpecNETY^_?xeQ9`sS_65hr5P4G7c9IR5vZro$t{`?d3Mj>tN| z`o0+t?8JhI_f_c0feM}|0zcOrPQHlD9c4G0=C^Kzmb%)EOixXm>=}u|1}a>Db^*n< zX%|q~fWk98dkPE=1X|rtKlBB;oXKoCTZ^t7s^^73$2f3bN(ei9#M@o=ecH~G3ydJ5 zp*_l`H2ib3UI)k#Kwtp8L$H1GgHiPlV!#F3v$S-uln9S01WtC>{x1j|7Qf`MVRRaJ@7P?$-Gw(xeR<(JWpcE)MIz`>@brj)$& zip+j)pWx~4?f?J)A^8LW2LK)bEC2ui02u%m000GMpeK%GX`X1Ru59a;TeVoPSv84M zmrIgNJ5t9n2?UR-fgzX~I1L&EA|j}^1}XuvM(7eml0tzZf|wyG0)rtD6)qe_Sqw-& j9&JzIfRTG31rl{A5`}pRh-e-FjDuT`kdcy;EFl0p*WO_q literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmskins.png b/workflow/public_html/images/icon-pmskins.png new file mode 100644 index 0000000000000000000000000000000000000000..cacf521c6787267011651cd3541a60fb75f281f7 GIT binary patch literal 851 zcmV-Z1FZasP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igb| z4>uZXlsGB?00PrVL_t(2&xMk2Xw-Ea$6ue{_uTDw+q${w&5bR_>bhFLnt6roNf8Et zJEF*93K^qjS|BDA1VI>55KPEWCN5$vNQlTMN<$V4O5>X24nE z_w9)n_Q?11*ZcG4^M2#^`!}1WdC@S8*Qjet7=mH$CYNp7Uj>7~M=Z-aR4SDslarHC zgw1H0fM0@)-v_!k$@!Tjrv3*TUaxo0@bIvX$KyRyUr&vho3?eK)lo3^xvifqsJ-LB zhaC()n&AuC!?^nmJ_kT;85oF%BauWZoqi4xzpBJL%dIc|t;HR43}?10k>~_*8R#Fb zpkDy}q=774%c^oB~k}a&UsZ zzbk&lVAmfT*H-$kT9u969;JG7h3cSdX>K`@NJi`M= zsW%UeUbD^0H?u#@KGEFV9Cy3jBlGj~(|0~8!ilX_^s5@q8h{5)D@8g_e0%a*BpNx; z*4Flyh;)`prH=!FK;ND48oJ9t?gu)IZV!=79*(v&Far>cM$h|vzJs+|EpOZQfKuw1 zWm%1NILCuOx=A0&Fz}sBXaY*}x)x@ZHPas$(AU?eY}?)^B4g{;HK?Tf~RbB>g zV5`88hH0a!=_teYGW53#0 zhvsb@{@knhubO;5Zv!8_@=~aMFp$}K<#PDT=wL zSB>6|ZqxudUEKZ9O0q|iu@1Qz+dwL|!B|;dFY5~#xwjIhyPR@*xakU~FFbv2;cDo@ zQtH{dv5b6Th5ku3_7*ZtQp}pFkn_0gY@@4I6xCeKse5$MY1O4#t7F%is`=ve!mYDs dlIa*w{TCK2D&e6Uya)gQ002ovPDHLkV1o7alcoRw literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmtables.png b/workflow/public_html/images/icon-pmtables.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e29b6a0f3d62dc22d0de89a1e52dc4e6c9505e GIT binary patch literal 723 zcmV;^0xbQBP)4u*Y00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igb| z3_1}@t|7Jn00L7S;;Cm_0%fCwWwKoD@bS>Y34xc!=$?ki6G(%Kx+g@abm{9(?unH{bdThp)wv&p-a?{QVE^>+P-_M#tTyOF5IbVM9$-MxO8sXhVMMS21A_yYW+7T60^qDat zxI=1mx@qyNaS{=Q4 z?c*nZQmtduIooVxnK87t_| zG!2~01Fu9VwX)~}iwHv&g32?^!odⓈI*eP*wUK7Oy5$m8NOgtrK^;7I(W`^qRujrO{5fQ4x@@_Xl$uaCA z0bsRSJ^kt7!=DjxRnP-sqgz) z&Nt|Bt3>R@Jl2w@jv?9a~5Hp}I5ytud+{sUJ<{C`iRIsyOy002ovPDHLk FV1lyCO!)u+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-pmupgrade.png b/workflow/public_html/images/icon-pmupgrade.png new file mode 100644 index 0000000000000000000000000000000000000000..ff3cb80e19b49bf43abf95f880a82c8df51e3a40 GIT binary patch literal 1076 zcmV-41k3x0P)4u*Y00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00VXa00VXbebs`@00007bV*G`2igb| z4FM1V*_1B;00Xp1L_t(I%XO1&NLzOl#?SxWzYqNUm#!$;P_Cah} zWo2b_jCHIl4BQxHjE*6~I+##LQOi0V73My;K_#%#*anvC-0H+ujkF4O8e?p3qtR$` z)m)S7O>X}CusWn;zi;R8JP(|6H~`NuFmRJ-ZvL2lS`uSplkH<;lkEUN004Z{{0Z&8 z;UV^W#uLB8e_+{>_E6{v_x{;)X6K=j(qK4*gW(XayLfMkHX8%0-dc(`(Gk$JMvr!VD{E#D)P^ifVnxG*kXCV^ih1ux6 z8l%%BFnP6Ky=%MJtN;M$>guU>xt=@I-+$v5nx-?`sU-OD&61G#7ZiX2XF*00aTQcb z3Umq@7nYiIRr!bKl2UT%aVAg!0RIH3RP+Z$Mfsl^jrFZoiy6Lu*o9d~gtklgVVBBuQ{D zIEpj{25DJZn-Wo4croj^?C<180M_Bck7t8x8sedGr%J6SOgKyAfW(0MyKhw~*4N`F zI4;^@HWx!UyoM=IBeQJY4&tS|Nf~!@zAVbK zYlJvPb2AHbk?`u*PnI9wC8wt+R(E#7^9)n}hTZNcRUi`Alpmpvsq2d?vt^5H{I|KK z8Bz4M+LY-rTAzp#$$vCv=NU!y5;F^@%emV1OU+5dihFCP5ozrz!T-=<)GKo zSY<$nqzO(EcURSfR@SL?mfhWqbCVaaAc$yjaS`--Q_k-n?QCmn`J4m*C@!{dr&1|l za&q*NR;wy?I-O;-LIo;B8PrORjUp*WE{lzFR)!qTp^1t6BP{FvFqKNhgTXoX?CkXN z-X2jyLz5N&U~uqPHWZ3rkLOOz@1Men1dkI59#2g@z=MO{7{^7i*E_@l05mo>Y4?A} zeo#lpx7U2WVUA&#gI2566$k{RKp-Gltu`0KFb9W+|KP4({qEZT1^i2GZ9P?8%^02v uDYx6*>vp?)0e}Jk#4wDZuI?E1tnY77j;z*w8qy^I00004u*Y00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igb| z4=eybzzWI$00VAGL_t(I%Z-!kYg=_3#-HE0Buy6EB&OFiS(-Xq+77c0wRsn8cIb07--1qy>HC{7UPtXAjdhP|<_?Lyt9wfDrP%}LT+mziNETc%CocFToB@zVZbbzq!P>v^WoUch`4pZ9S+fR!KIxo}LSj-uWtY zuq*TJr!Q#u7s#HT_wno00FIyfj2BJD)BZN+8K=i?`1$%A;%ONSMPOhEJU$O13mfOB z$M3(hID2NR(Lac_-_C6t(NgRhT7zfJfq-kMp=sAk?Ojc@p~j5G^(;zNAlT!Dw3$XC zmB;?RwytbO?oTCJE^e-UP}rG>0sx=i^=?OJ{Q=G@=uVFv6;;Q*XbvTY!RX{N?rjt> zc|VTv@H#|?rLl8g;OoCvqd3bO9^PbpGm$Iny^rrE>5>X?9QvQz3-KWa!_XCB40^Sl-BjVHwP?N_bFK5SKNm zgn*(6jI0r%UO%aIIiRto_E+EgXno*V?E(NWb+u;WN?O(vt7&q3K8{GT07fuiE-Axi zF@d&Lz#3SnG(oN1ji%;0$Vyc|{`#T4mxt#s0WbgnMN?SOt2(jP@cK8uETKSXEMyee z99ASW8oJpCO5{PzCQOWuz(OQgiA2omrvBZJ*VMmu#2EF$O^z1a!k^lez07*qoM6N<$g7d`EwEzGB literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-rebuild-clean.png b/workflow/public_html/images/icon-rebuild-clean.png new file mode 100755 index 0000000000000000000000000000000000000000..c073f26c0b18ca2c9d2b3be5acb26a1039cda7ff GIT binary patch literal 2489 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-skins.png b/workflow/public_html/images/icon-skins.png new file mode 100755 index 0000000000000000000000000000000000000000..05c34b9a4b9cfe2d23f50de00081ad58f2ddc9c9 GIT binary patch literal 1703 zcmV;Y23YxtP)$eLt_i-|xK=ilT^6C}i2$*;NukdcfQCzUhL<<#M*azyGC~GiMI7 zSgbAx41+hPO+YLbw>mjFJ@)hS)B5`QK6iC>?ccIx%W!UPZsfEGSXo(hI668Ga=F~0 zgoFg@*s){Uwzf7ZDJkhULI``@!I4)N5Pti+B%*yI3BBaZT#F!$@d8p`DIj$fp`^yz zXaR)J1^2SDvL3Xywo={Q-Bdfq9o1w0}&bmP7%R14FK)Ov2~)?1Vj~!a1Dco zV4^fPN`U?)kw~O!wVLYe>>Lq^L=?(FLFxvjHWWfjfbQNi=D6 zGg^SAprBw^OiT>L%srcN}@J56c~rujvbYAgM%M0k;_N8 zzP?&o!h_5Gn;zA`z`zT*ILp`$N9aMIVN!_Rm{fq&)p@ZtZ@wUwNJb)s!Xdg0v;>F4 z>57Vq(&DMvY^*>LsgsWvQ0&RJyFrp(n6J$l?~`6*lhL>adC0a9UL5l|KrJr z%d6%AZ!p#i`tW$5(eW8r#E>|sR4TQ2U)_)IgxcU_6~u zQd0iF-4B4V$#8RX>xaZMFE6jN^w=38Ae~HLwSj=l@B)ws%g)Xo!YKCZ`@zM<=fX0CRMwG$>3_#?r{&78L4(Dz#&uKV2J$BCo0%<^FfS49A0VfOu zju_bwvEV7*6TJ}7E=}c+eyNJ0YPY98A%x5@5J;FnAV*(|Lk5 zdS(sP)+D07Ivh`>Cxve_5SR;&GQy7lhZhIX%?HFFXsVsOEJt>r3116|iK6({PdFWW>8-4_J^ijfQIYIsj|0Y zYdN!Ro=hrma!|hX_&~m*sdts4_GXo0_vP)1t>^aSuT$49uQ>E^Vd389;+*ZDm!wyn zU6EA&O=)7`#g!R~FUs=s)a4a9hs!r+9w^_DvAeuhwzd3dT26EPv|7A&K^smXKv0VwvMO~u2#kbzdOu02b zE&X;xN@jOhLSA=>u%IU(rlcnzs5K_0%za|?18N=&{B6@Gv@b)e*qV$zSuu2B98z7002ovPDHLkV1iIJ8(#nb literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-system-upgrade.png b/workflow/public_html/images/icon-system-upgrade.png new file mode 100755 index 0000000000000000000000000000000000000000..00bb4480c66cc2dc47760ce852f5e299efcb6876 GIT binary patch literal 2588 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon-webservices.png b/workflow/public_html/images/icon-webservices.png new file mode 100755 index 0000000000000000000000000000000000000000..ec888b8dd31e9778c9bc54650c22127fc6119b24 GIT binary patch literal 2445 zcmV;833B#{P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iXT6 z4Jje}^amXP00|9AL_t(|+Pzl`a8%V9{?2{w-o5)wHX$KT@-QJ_NRZeF0@H$n52P;@ zbvn+pzT2^*Gj_&yXv=7|E!qw<>I~Fsr?n!Y^;Oy#q=Hrii$KIA!jcdYLdYh&+0AbD z?%v&d@9E!FXVgNW&mOD${+7qRQJt`yBlz9V1l0ld`|ZqQ$>jb=k@VJ!{sqw{|XWLIDgt?~Sqy zB_9}>MqZR~K}Ri8i40^#Vh-o1ZkUBjR?Khp1^o9O=?m@U)*lBy+;89c5?D@)pG8I8 zPri5iZOfnY1>8Iu%docg8VHJlv{Asoa2zI+;P$xD(ov6@0*8^DK_-)f1p$d@0v(H+ zd3|HWclzHiKRuKD%>mH9z=`uAa01@&JxhM@{ja^`@v1zY%&|Ea%z_^9AY)qa_&o^E z@?l2iF28I(L|K9{lR=g|0YN}X(1Tdgz}Q$4l@(s}_Kso4_QPy`TLnu^A()Ks{@XbS zT&*uzy67cEQ@F*!F7B#BOKT-2(s@{%L6ihAMMl-^5V*hqNyP5`BXGbW5t-4688}P; zJw`a}M>>^-?sdZ#_E8b~qDUn0TW%dPaRvw=)HZis=hhXZGI`eA6h@W{Naq{?j0kX& z*oG_$C@s-pS`N1FK1zydWI`Zm+K|Wxl1lC|9n;P^XW|Xn*U8e5IfrERkBS_AH-NJgOp(sDF#&*$!s#hC2nv^ zdN?vh1`A--#We_(XrKjDwNxAhg+@t&1rD!IMj6ew)_P#&O;%o}cj6=b>CI_;5)ufi zDuv>yEJ-P0fBytrWGauQ;E9*tML3|MvAzsFk<-P>I0H12yR1}4!gMI72&Z5bOW~G< zU;bz{Hod{IW3T|u9SAH4)_r}Tec6rt(VJ)YUD_mM31TT?`=TpVrGut6j44}7Aknq5^alEr>Aq*Rzf=dK$ zTHo7-&p?_^zGdeNH*#5)SdRMYC!@(E{jCq~z+E?71Tc=ssU%Ki9Q04*FhxBM`4kuy z07WVi05RsALncpTQ{xz-b!j7yPr~a_aQNtnGkd_cogq~bIS8DtI}e`1!j>>LZ0ji= z!+lW$`-YRSBmt^U24mufeW!pd77ZvWG?EAMGf~81Q;2^YlksB2CZ}N09O1t`kWLw| zOH8;~P^Awmp^Yr6EN62({7Nr6n##}}_9E=pFf^6LNYa2=aHx6#5E%f50|33N&{{1%f{IY}P1{V=ef|^_8U_^b95Nt?n9RiNrr5aa_?}g>E|kuUk}u zJC`+~y{-fbnbH;|N-V+x!?Fu!!AM1^^2BF@6i6bUiJj>r{5ggOe>^n1dgYxn7BrhN zmS+s2TLC9&%ZW@&Z3(*SLm+>`0wB?gAc7Cl`3EuH-Ko$#AL>TD9Pw~YZuBZ8=<;9&~-0`kCJ(y{U=;* zxD*8{soEPE#ap{~A`v^iIrhQdH;VWSrs8j>`VPMFm{*?LbzxmeLtA4hZ>#aMtJ=Z{ zYAPVAuxtzQOpXqm6jXuZB%g(2`}Y8j#br-9b3`|6K}CTp$l3yCvJO&I{ZulGTzY~> zPxPL$q6fdKl+A~TGvLyz7TE8+_Qcbvc9}lf#+?D^_`l=;OI1L zBhOD9kFoK-lL#smhx!h^;-A}ji4-a+V}8F6exDAVBv)0XsFEPqeE-g87@zBIF2t2Qm_Gnx4K!-!+iY8Ongiled00000 LNkvXXu0mjf%)M}$ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icon.trigger.png b/workflow/public_html/images/icon.trigger.png new file mode 100644 index 0000000000000000000000000000000000000000..d563efd5467d5aea3f99385669987bb47faba443 GIT binary patch literal 2339 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 JPDHLkV1mTpcMSjl literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/iconoenlace.png b/workflow/public_html/images/iconoenlace.png new file mode 100644 index 0000000000000000000000000000000000000000..2974ba75724bb9b3afaf92281e84643a4c761e1d GIT binary patch literal 2148 zcmcIkYfuwc6ke-!kPhwWjFI|WLtE*TWRrj(F$n?@MR^Sm1yLuP%@SfB8#kL0us(ty zAVO85h(J*ULJ$pnc?H8mYCComi>)#it@W+bTGE>YLH*JG;+yQ<&B^)B`R;d5 zHY*}*m5cLSX9$8^f>#S8!Tlp}&2pLw*18oGAKa#D0)nHRoSd%T3Lk=?DbFH8qE}k& zcna357Slz8sieNN*a)qKK)?~qYf$zxU0~7F@`}c~nr84*>4gDPTW=YJSEs0YEW?=8*k=KgOlHMVqjoV}1z9IrX5Xuo9cZTPOUyc(1$ zKT!=DovX;LsyJPFprod$DZe$btlsc@;g*7$eM7~uWhYEP%y5=?XJtr_9yRsnJ#I>R z(Xin`UHn7Smdd7#Ll>~SCMKwpeMU6;YVGLDCD&f={`oC+c zoNK)ajsD0zKOECKXn5Y6YrO_pdj<7Fn_l%St{n_})$3%nK%?db-Ilc4zVuVwIY+Jv zimnKaoqLX%RWHs#r5)PCmxJ!t2Hia^&FNtmw26TLLpO8e3y=>+S#Jxx@LHHo$%))L14c(4hyu6i+0rp4CF7pS};#n_xTP} z_>Jr+i(#I!mS)+{7|3xmXUF}d55bLd%hL?)I}#F(yLIWA%0iEesqVeo=IqSSUrCzZ zqjlT1BU$t{ebWJ2m(qRRzJ*wN0F}HoK9f%D{9;|k{J7nWy^1aI+r6Y3Rk|!uE|-TS zFHlIutF#Ng+KjdRv-lX82O||376r|8fNqDUP#6;vlaK^ZP*6}ch88<47R%rS9*n~= zLX*6n+tgzLl4qz_$7vvl>1Mm8=*s=R1VLA7Wh@m%Bv45xi9`MpLX5*fG7?WBNVz7w zZc!KnO`B=Ui46_mVuX^3+ESQ0r5fV->C`AD$0=BhOJyoP9fn~#ER*o*>z9VILe+tI zqHJ{viASY`MPn&)%vVD96FBp9TtHUh6bkE<3YCVd4n47< z5pWx-~B2#3P}84OLbib8b^mB!6cZQykU&pb=#iaiT|Hr5^UTrwU$)ak41tZxB^$=DoO)9 zW54a01mh+Uq!OhBG9@a-5w%LnLnea%sn4Mrj0G4=WPC1POCLYVNqLy?eNxIhicV$| zsOxbGc!AJtF9-Y3+WrpFG9?bNmLY65!t(LnOKt@j4}*pN(XNLukw{c)W{YukH5?JGR(5`&2Uyp>n9 zeEVm9hQ4DlL$j~d3#W9>My8hzMoOEe?^$1&+U&9Q=EoYEftJ3c{*nIW z`K(J(b4=>0J891nQ#~Z%*~Rkr%3K2e^8fHxTG!rUx#gk-8(DrPFI#_n@l8KdbzmHq z54*RtZQSo~;#IV!Jero(k(p)*esbH@)up8{KkP6bp+JfnL*^tx8Ke8moE1-Qx6nq& lT^u0JXMqZx3|l90YrZf>(wKPX&ll{{`z3T;Koz literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icons_silk/calendar_x_button.png b/workflow/public_html/images/icons_silk/calendar_x_button.png new file mode 100644 index 0000000000000000000000000000000000000000..3caa59e0232cd67ad0f3abd21ac110e3fc138585 GIT binary patch literal 48177 zcmcfIb97|Q`zZQoVoZ{W?POv*nb@{%+s?$cjfrjBwrx8d-pu=bkJef1{&9Zi-o0w0 zdw11-s=90U>i(=JR90F94jL002nYyHOjJ<*YybUg{Q(L7wGGtoaQWJSIq-`qLVhit zkcJ^&kD+Wu)f|9;ps)X~!2IP*DPK>bI|`{fD%co1y6D*(0r45y=o{e+o7o$=*w|Y* z$kgFU0|9};+uAFuxMp0W+gQx~!XAougx+MtE3@q{CQUAAXvn>Yi6Y<^TK{#UmZWK6 zdKXNbzwt=u$%O|%y06Lc-v(Vl*1Iz31ZJg`SaULhmJq12f3orsacF6q^73&x35a=P zd-o&^EC!vjs-7LD8-;8D4iAj9Jon|sD|kc_~oPG-5sdKv!? zX>-B5*7)@5yb-&kkwecQqJ6y6?@wg2J#_eoLPNSbKW#xaQb_kfXf+_A$ZA--S4ut?&a8jvt2oS_OxWW<+L zc(k7QH&OjENJBrKo5a?M>{N30bkr#~RNE-RPPFRd6!WSEQL|#CYR%>?NQQ_yDT4?vPES||z_bAf|zZH`Y5(5ooN_=TzSJ!Zi$5Pp$?~-?L?CtgX6EB!!&}+&4GwY#vUq zwA*>iUz>!j++CUOZKS+bxA3}aZ}JZ$UjrDqTAhH%Zca>A&zxnPs9s2G1bD5QP3Jnp!k=iAjfE%IFLNT2EniJPeZ)Lo)E{dU%Y-9q zvmf_#Zq_sJM+)$~+IFL{AKu;UnxbjA`B%&qUnqd4&+#zdFkL8wqvEKV_4e-n{vB=x zZ<#frJGaDRuA{r5nr^x$gvfx)!|(S93xuZArY-0JyG2vMJLrFmUbc`8nfdKOWbjW2 z_y)bO21veE_YriAY0nm|?;@w)0xL)vWFM7d^#;AGIm@2F+R^S@HS+T@lqVHq=(KAO zk1+#3DUl%~KMRqe3`B>HYH0wl=e2P4Zi0;g9a|xa5S=F>9k##oJIwtBjAeGQNm7Y? zy(NBRk?$$0|rtQjku%vfTcU&LOlE>p}{Ej9I+qy}afd%ep>F2^q^xfZSw z>xN?Rzq5>JCgKc}5o&9J-eKSGL7v2c3^`$A=;Iv6(7vBU#3nDu$x$Dkp(5(Tk{K%W zhbEYR`!#W@yev27Jk4W?BM0#wQ(`Ra(Bj^xncs@Z{i?2ek7?P{fRx!F6G#<0jEZ+F9z@{b{s> z&Y+@e9C@+cSm#+B2$L2y_A9T1BFZp&_!D!wohq=v=BPTuTbF$%dl<@a*a}4SRxBx+ zsFxM89g&#TS;8M7gzA-~C)isr1dl8robWnsA_Yr2h68QTg^&xG3mw>cF$vBV&z6}C zc~FuCb0sCwE@q*?lp__s)&%uxFW2Kd1s2C31%cBbE*(=~fbkv75sSdlliYhfGfq1gnhv=1|`!4^a{*;rM=2=un;`q&iTZd!FvRl?Ps=oWzCBw zcJ?^%{AI%*BSPW1e`v$g5(y!62DaIw9v)$(t|g--Oh>KDYMLv13>YocsQA^DU4J0fo%sgv~0D z%?m7g-#s#PhYHui-FXCGDg`VvcLoFVpA9z|)0#L6Qa=5_0@=vJ%ZrFk?eMT(Ahz(Z zT1YJdg?mRTa>wQpBDf!ts-^#kUJ7>5h*64W(1_B@2M#Q&S+h}yX1;6@rEQmUy}^xH zp4NfgKv*+;5aS5rat>v{Td$V%1skMGV~;HJGT^8t=)PZ+#W^@Z*PRSW>MEonZaH^J z)J!76S2WGNH};^}Y%o^IS$KA!9mCG0aQPtk=W*=D_dG|T_&b}dQW5<{j>N`1^bSD= zGb4A@r?Y%XB=^z;F>^`iZ2;TOp^xfiipQiM)d*8%ZhDX|L6lu}C#r7dZj7I=DI@IE zOjEDp8rRh*wMK^T%s5vH6-7NPe=h!lFf=!^Dkl3ZMspGu6>!qZ_Hr;`rWW+FD8QUK z%F|L)p2LnNh*lq6e-JX98+^aGwU=_N5wVh?Cka%3+|USi!j&e#99ouJVYDhzC@KW* zDFYH&FUClQwjdj~?=7fjnv#mZD{!MW(7wY^T-@G%VcnEkjSes#e#xK6+Ry+s!w-qy zuzz-F$~%Itc)Q6Q=jjHGbokS!dWb;t>UP@cNF5tC`cIEd{7f-jbqKv?6uO_W#fXpEbhA zVvK6F<=$H`hWfP!#DfCVNg8cT7(^-tQ3xFAxq?+fr)nz03JCWBrd}aTrU_HKu<)8{^WEES{_9~y^w28Of{=T_uk=DODyEQ6}26H6(Q6;M~N-`~_g-eBc5 z_3ORC7jtgbFX52$?p**w36|HS?|wJVc8)c5Cw_fB}=jpR8p~8 z7GZf&#*vIdKa#)<_AAIGp$5kb&s{k}q7v+Wjlrk^_{vxE3dsG%LG>{D`rr(d{V*jc)?Y?tQTkcb!Q0ZjFFH z-DkUXQ2OXxxCUgz$tjbz9OZO2af0{`p0NH==Q*mP|Hj$Z9dJUOl$JuVLe>p zpk_5gFj6Utl`f2NaKF3n>rn*HwBozxvPF4xK?&$obSupLGg)}z$+&pks_emtdBlM# zDnAMoVi77JdBFN;xpyRYsc(HP$J-J_;E%+1JP3ZPFzp`5J)D_fdj0|*#J-Uhq#HO1 zES5h|vLs0-M$xz}B41z`Bl*oGE3qF!6{{XhVi)>dX1((v&=zS#GEUj@PkAghg@BLG z>Pe%GHD|0Uu7&q=fgdF#Q-JRX!jZ}LD&v7VK_GnJw4U(s^@hu%m<#7S%f;-~9g8J6 z)ufr-_r~3C^*t~O9|i>1XUl&^k76#lX29!dvL3M<7j%7d9Il}+FASqAeQd$95!|0M z;^BD*1dFrHEaMR^k)qjptZZ!4JD=Sm;))?zc4Q=_*Z8Hqehmh+4Sau6IVKG0RT4Gq zOo7W=J)#=oIUqi*72FWdGa?=}TeBc+F9V_#%RBX&v_Dsn&O?=$r~4U;ig?1xUjWL# zPpBL_MaV&ruo=I=DX}3hZO9QWDZ^wcz$D5gKsJcd^LtNYQobp{B5p*Afs*8Bo}diB zc5{wjE%A^|;M>IUM5(;z7=OoB>Atd{bvhK!5FKHbe29Z%^#zrI2K&eg6?DZmMT4wDty>pVi+k~ieYxuap;O16r~{T{d$FD z>;q{Z;z)6B_CL&EZc;Uq7g|*ZAF#Q z<800^(bB}eR4cAv<-~hRT82>2ve4UTNZs_N0ZwM$Khc@>3(_mooj(omSjbpe4u}}_ zv~Pc3LZALhekxH98l3razvp}UZRZdAG_%s05B)tnC#R*$m5d^uMBzA`7+P|7lo zr-Wt2H!O?G{<+Bg!PaJ4OxZEGj-`+7J)QOm@l`6~@FVYB{Kq$|_ z^6mQKea!ou7KeYl}Dj?5o$JP0bJQyUswh4!k)V8@?zD?+i zl+b*ec8-`6F+8j?({C;p7~TAHrYvwNCucM7RClsC=T7uTn7V%7_~)xMUiq z5y-zZ!DJj&s&Ve0hIAdJGp`I!HU7+28*|8Nd+dj}#|^?7K~{;=nltz3mL}p{>)&Fk z#bPJ2Ff54Cs$e;b6EbAY+O9$ZyI;g~1FiMg_!_(bvRq70qyy(?_spj|MLwZyW6!+^ z1RO?7>!5}BP&EA#S0C{Q|M~Y@zXmT1vzd44*F)zneo*}S>(uy zv(mi)_DW~&jVm~7>ot$p=OdDm;m*Uk0xQL619!#c*u|{IC+(ia&$113r&aYi*yjai zg;!u6k7{tH1pw0|F(H)0rwqR##$NC+N<4B(%RI;kYJTrkM#R=WBdD_=Dc$Dc!EV#Lx~!X*^{yfjwRM~I{6EQ5*cSQHg6B!l%#^dlspWZfekCG|J; z8V74<=bz4%%PsmxVVNq!lUvZvxZN!QBNgquLi3nit2w*p?HN|e8CrJE11l&dRWWs} z{LwEkS_mHU1JiC8t;+O{1Jfu1DzF{kK~ZiCC;~^uruq8EVY!q+mFVujVLK?$U(jaD zbha_O_|LWN9JQkwDWfXcT6d4b@|U)ShS*y5kJn+Xlwh^~(-7_WG_)Ac@+jwCR<(nY zn@Wwtz$6N1*$R8yB*QXbM{#ol&AIaD)xRMt)!tOy!4Js zZ!7;3h&F@(Z~183Ywxtuf!4p#iU)cBNpyMoonJQE7MA}vBzGL``@YilHd`2M2epQ&}sE;SLfMZa!jKyjWip~|q!OhMERsbEP~S-z-j=%vsT z-y?VTvt{q~Hs3d&XL-0=Z!t@C8p(uu71eZFnm;(qe2p>JYKEwPi}cYwWc5hAwc7mR z6``V&a3h|mH@LuKjsIykg4!d03-Y3G74ljgS1_}NWQ2ADEs+wf^yl6vvQ`n9xwy(7 zu9?@%P|Uc?ilFQ!LY{9yQ4J2jL4!|uI{e7L_ z)fT}%KZ}`H>EX zV7O+L{UA_9kE^$|&yB!@vXs0WW>3?o+f6fMPavd?V^c|2{RoN{VV=f0}qqLndZKgd{?A60-b!|KdW5S zv?Dr{X^Tk3oI8UFnrN#QWa?ZFDn88XWh+?4;MV=M8NfduVH)hooV&_Bwm?x;a*s&9 z&wmg|Keya4P)7wGAO|H>AWMLpCSIUSWt zlXHOG=ab1~hSOS&xk7wH8T1a`F9K}hMYDkwyJNL{i9C9qif)@7#Se0rDZb5q9{he3 zMi}4Z@3Q5u4N*m)@>Gg8Yj-86lfr##QxGYAsFa^Cg4qSe_`ZCRfU47jAzU&Z>)i1y zS6XI;sKcvG9E?ReI4a;5aRF(4yA7E5^#8|CF|C+jg=lO>OgCk}a>O=06=p-v~@PS}`JY8PHrIuhDidfR* zqg-1K`t{v?4nz*leGqHY(FV7t+69)jWWH0;-nIH0UE;l8z3s_Szvm~z6o7bop)kuy ziD$Un8g=e+V%Z|kMevM9!VTXbY*uSWW?M8!%*kSeitw~O9X+ z$jYE8leB)eA_1z=y;@BHS<=y)k}M&JNWQ`Dkip`c8Ph0=vE)1 zc#_zCha@eXZn}(JFwWqMpNw0!{`-P1o?dd~4U1BsE(s{ZnRK<29~IlK^^9qa6o<_$ zK<>y2Gu?jpjL%Vy1K!diPDxPgIk3G6b-jy(IDivDzlyRD1puv{Qctv1i2E+1+PZ4g z+w}tNWC3A`T`9u+wsmDN`3mrot^Au z!*mmKXs})7WJo>GLxHf}ObAnVvFHe~4SL0nyM5&+s*6?vj5c|6y9BOivTox(Yj1~( zXqrmlX=Qxl(%aaIHcHq^Gw%}oHmnZ0d@KH>Y7j|OwDa+fX|U5(!F6^5XylexJKi_v zM+sH0d+Pcdkucj?9}9~cn*{fjX3QrLV0vX*B3g{W`7UkSO7$kPaPt5q5_(;s#~6ya$7X{4(Qw)k#D2vQMIF^&t|o{ zzGVcoO)j}~D&PWys190S%u-jCYP{2^4myYK;NwwtdmL!tO9t@py1DucFPt6*OWM-R znlCZETEz7~Bn1RG^fx61B4olR!D5bhKh%yeNwbIKCzvy`{gkKDWb16NJ)4m^cwd~1 z2A3#FKP(t-ZjJX7Q>mSJQ(T=lPqLH4%iOlcc6O_By^{A|qxqu!Q$=r_jO=lFBDZY4 zN08kX3zeOXYc6L&wOSO9b+6 z8;W8};}dDV=Xg7oB9K=7Z3rR$<;JCVJzULrWk|grS#<$>mXK|4>IO)V?cxIdi$^>* z!Zmc>Bst%tzJ9?Lqlv#@jlOq8X6=7}S^kKK_DX6k+~UF6=yeOOfYCg6F{NkgY-ZkB zyWU+)aelE{E!;Y?3T|f`8gO*oY;8G!;RU%1xYjhq+jiF8T<^T>;eqpVCr|3@p|#~{ z4&OmsAGrSGWvB5p)L2CX)OR;&FU_>Ud$qCd92M*e$#32^pZ=4mcRsN2~i@ED5aQg?d5X`=^&X0`noUKGS5z<|rr$Hte{;nvu9 zs}=OcnT=~O9veOtY*kR^Ph8hrTv%Pv5svvTfWEdL_#R zPDTvDnHf#XGUu-&ks&a>t3P8f>kmG|IT0nE-35AROnfvbgzvu!zo}~a_GC*8fb+@{ zR6=D-u8tMouEqv627U!fo5JE09Ue|#iKe3b-BSMW62>n=Ux#dY|w1X z-}pXqZsyO`M~f1BXq^|lx{h`vH+y%5FQrNA;Ph~J?PeCurJkMax})pe&dJ+70v}lp zg;JijRJuBPey?QXy^zi1p>5{RKD)c1aH>Lls)TZ>6t1ftTKz)(6@u$E4c2j-#j(=Cu{X8eis1uXLOC9M?qq)=T^1J_FL;j^(^h#_6C7*36MV){^me_}X|4?;80m z++3I-lP~pMyuL4Lq4Qf=$W zzvF>ZZLX4#T3qm#Rfrj^n&a^y7gy{V{IEPjS8khI)XjFrlqIvG&umiH(rzyp*bHR@ zUJFppKCW9J2vo;m0IT?dJfO$gcC&D5QHx;{JosnAAx|D{>JtcVkv=s|7(zoX&p?n1s9R_l)99VG!iOQ%?>Ghx zFUYxdIUmF5C^I>ngQgO?^)S!ZbB9%?u-978^U{Mqd+A_sEL~u;(k7m#A6uT8&cS%x zLGZ>T37NF3qf;YdMj%%rVkRJ0=J>AAl1_o(3RwM7iaoIcdMGN${dbW42!v5TXI*JV zxVY;i6Z4Ef&6vI=91c?g6)x$Lo4t>AGo=H%*HLvZr8JuN{d`qRfmhOsh?J$4AF89u8hWL4H_Dj zO4^q_Ry&-f5_1ONQ^HJ7P0O%nBS8#1qvIP8pCr-Z&teeKmgVQEk1tUZ_M=M=7lj~G zEI|9FEmTzJCtc)tjgIO5?`{`(bNK(xcHxwrT%)Yo;;Z#&q#Pf^LQf#HefJ3=Vu3nO zVPy$g2E&?usmzTIYm>K`NHnG#G@zkHMQm~0xS#!q9sHs%&hTR=5J|}Ip&7q|)=7Pd zvkd`kgq{K2SbX*dO~lW>!?ij{p2uiG&vp#WzC3xUEA`Bh&OjfNDn4mJ)hJt~r@sO^Ez1LQsv- zdXaWD%TyR?av`z|PqD>B>2N!Rva)f=)MJXdN(S}j5z3Km49NK2=m2>YVXQe`D&M`m zX$`xEt;2m$%n1E>Ibt;GpuA4q*jG5;13-9nS&`uUk-UMTW=Nn90g=o>iVe;T|7|W{U__lm8jC<0 zuO!FL>;Hu72ChAw@7;Ao(80uYYoJJj_3Y6}llAN|NL5Z=UHC@<-d7>^E+P(rjrJCic(65_e+b3I#LDuo(&B zc;zA!yDpwl;@o2K)PlhRpsZ+Q>yO}rsFow_;W)`X%vLi<)LnFlGYjBF3V4jbXdjr~ zJ4(5Go~btbF;p^LCPoBO325p7S#r^aSpF%nB;hDW@JbQ{311@?w#QsilVlJU`A+pn zB0Q|*1nG?MopAIZyb?^y;4p1kGyM^&DI=m&W_y9K)bfa2j42~oDd18QaX>@OFk;P4 z7P6lIDMLA&pGAP*114-anePLpeR~w%OHZ&M#F5laFn-VcS$N71N-p*R_7th55J>8Mo}f zyjp_6{@#|m*vEuXk)ZjMOCcsOa51;|bX7&(7Lar*88+e&J7G+KQSGsRovatQ<22el zRVUGOP*uS`e(y;r0HN+Qtgx9|^|K0KAU0xmJG*jJzFg&t5TiIRywcx8#qe3kACwgf z@H1|F`z15ho-=HFi9cjduTi;GFE|duh{wH`+Gg!3qr@hlCs7)Hf+|Dx!&Yh$YJrjnH`7^6tOeUEJ(Za=VJEu-CczAl$`N8QUf@HH?Ju#BFofJ2w zY2lWzZGlfF<3^`O(zv+8A-1iY*cI6m3NqiM5L-H9!*6??(%!xc^o50(jCom^i%;P_ zs>I|^zn_lDIz+Z6fc3L%9cI8{)PYq`?I^z~dQw^vaAY9p!-@d89ruvYk`IofFFfCU#w* z12;2{3jOFwe=;yFLa!(v_q6Xp{FoMi-~YeO zb9Vv-G!BxyTEY;{w`95`u<3V^!m?RETjnHAJN@7vpUu#jc3bsvGD-^S6U3J-i6PoN z3m0Ug@x;G%W~G5BedJ^eh6c3+q9IQi)V21)E#k0@HR!LtFhykW%9GzkX_q{?Sr3k@ z{(q};-@M7=L>8*D2Vh!hn7n5mf6%|?P34bz)Y}NcjCff}M{<|Z*c2CF7p6B)pgvd1@CwPke z(E`*LnIWb*(*8_aTE2{j#Qb*CidjyPouGpFYY3<6v~#k>a-inB4X zvYuIU#o3>P6<>Ge_=y9v?b>2&t61&>QwjFeNHya|kUVA#}dLkRkZ#Mnt@<1zx7m}{;giAj7L~GZTlycsK`uNHB%cdfh6~AriYv`C=kxF~WVH z%$GMF>6Q&Jwv+*AJ=I+`Z$xkx(s`D7p1)rv-QxlxmtQyP)@}lEQQRoTBTuz1Yo2l? zMBq);S5j_cN{Qw+eLBTNcIAqQ)t4SRRxv5M=j&4_QV-yQLe zo2PaVm3Kp^-J?i4Jvgj<0MN0{4Fdr+nwSL9XDL(zCiFO*Mdqy*H{HiDwPQUEuqWhM zABo3v;ujcmXX+*mM?&Npi~eQv%41J0QZgjZT5J!)czdaoHpCC8I+&DtPNH5Uudp>d zj1EC237Uhf_ep{ThQub$3C!M>?Wa-hLKu>hzA* zL5)AZr0So)vQ>ts)9YX>Qc*;X4o%zs3e`U@^cx#zpY27lO4Dr`u(DF}A1b4C))t7$ zN2nb<(~~Jh=b#l>`k$NGf)4ttXu+;GAByZbH7>_usg(~ zyj}m2R_0&Q%B1{4JvSWos9+^G7ajE0()O}{J2^7#lk~Ud%HNv*1k?dv^`fWrC2K){ zW$izsF@Vtu=aKtn!1bL+AQ6MZ{mhG-idCO;rZ7mm19dA0@d7=Zmk>}33#Q~7}jD}VqVZ=!oR2k`9%t`H6bi8!5B+Mgo#N{My{p)_;I z%!QPSS;t;af^cF_%6(HBh}j?lL#r)70(%}aw10TFe1ekHn*PHQmFO=Y`_Ng!o~4nD z>@RA0Pgmb>-%5MORM#6*Qy$PPDJSPiJ4i}^JD~J2fBjHf3Dn^>G}jD%)eQ&f$Lzo0 z8SorlVo)e{2<%Xf`Xh!--}O0qF}7AbTVLXttsaS6`cM=BZcQ>-ui80^sO>BBh}RLw z@wQs+<3>%DR%M@5l&aMEb3#DLOaf!WL-_qEZkfc6gH^NSn<^lXxNcaZ`#dZK%nERI{m#*k(Qvj! zpdWoa%K6M{w`fyuH(5SUG?BRfj#57p`*?Gxy7I6*%8fOOCVH?^L(>8dG_nvX6e!t6p{)Cw7 z+n&|bd)odD08z!JTsH!9((KY}kol!iwmMM-ytn`HC|%nB;Zbrzs}H*(C6$feZc}19 z_uKv_kYXb~%gW2Y-BNf-oV}!Y{kaxaHa=HsGD>+cLyi%-9VX^A+FIu+Vo9mNrendX zD`Qysbgi<8PvkJwthwLn|D08~Ji74xrsJTEX|a3J>`gtQunPjU9eU4TC)DCIrUNj` zvH^lB{D>1mJ`1ra%n9u$wRtEW0I@fw?Uf&S0~y|GG0UL32BhF z;(aJ)dcbbZtS%>+HQ;E(_}JQwGjlm6|A>8H9`CXvmvAP(SVJL%`G?G!kWmZ(j=7g1 z%5g)^+*TY0i3i%7P0s4)`Wc%F@e?n=vj3L+58PhEQ0h-Nlz0GmIUlF3Kw3REYDyrL z?gl67a#%|CKOE+L=jJ{QIt}mMm%es)iQ5@;14mml!!c*)O6{E@{^(ymKRXqgT5gne zC#E}=otjG5Hy)^9L|Qs7n3(#90oi9{JTOcn{`?JcGU^VMi~x@p z4bhw~*iOWd#d!xin+{paT(be{%{)%z0EyG1y58&u!Q>=-q~1Z9ubb$j9Z%6+L9H0| z3%>AJOKrX+_*U^xqRjmr=L4l$6um$ruZvao(7Hqx0-54N!3Ws$A1ZL4mU zY_?f=5lR2yR~`UKSr2C~4c1=dHfQ~L%A|JDEKO)5AXz};w?50|R0AkmA6ghDt!bbm z8P|}#ryckGK!pd{?@wYFoUYeyX`NWI?b+ko6%Hn8M1Qj>X~9XTpz$5{Q=s4VFKp-MObAC43&uX&EBgiTztcms~U# z_Z%SX@DiMTmR@`g)PNXEv&p%@&T0Gc2dexlB2W!Qu|8PKSpZf66x-^445=={lNj3I ze)w`fIM0K(4RzYJ)pFO(WW0UCow^PmOnlrM&BL)z@9Y8%@*ai`!BmA1a&19s1(e1r zE#_p1PZt=qX&As}7^s16$UF{bu*HsO7t}BUGmf3u2j z!IkHLpABZCKwCBYrp>=~h8OMQMD;MXpOI}3B8{X+!@2kLxRxp+@l>uo18&%gJW@yp@YkE<7SU+E;5x49g0z3C_nh8?$LmYl?WzgJHARcJHgyJp3C>uWrv%)d-YC>5n!}N>T zOCG;8uz3^6#ZgV3C(azgHdPqC_t*imS5i!K4AYzf@`ws-kz&Umh=BMvDxu zOiaE?j%q5$?hTU!G>J+`2>?_K==i_kct|`#k zl8mB&J0HSiW~K7y+@F+1gbzvg~uwzfaQ%nTeWpjzV}wiMnHr$bv% z4zzkEm`*uJ)5s*Vrw{=AiC`MyIq(+>Bi8Sf%bF+gcNFI-BRM z40k+t<8Z76M28b_L)aoUD}{B8^`(HFg}3WpOA8Km3!2zm4QDa#7eisel(>^4eP>xd zv`hRO5V%PdGug?%u~1-=O?J#|TwER2R?oE8Uv^DacWgM`B{@4{io0^lkJe049gdk_ z8MW`!PLsS}9UWnga2jcBYqoL+wx4$w18w^L$w_K5OZLug!nxhWMw{DlJ3CCGeS@_A zX7j@TO2>`c-rnN15#WXSaxY629H6u9X^YlJ^rc^Nue*(x(N;P`8hBYQNe+1@A8uEN zjSgJ>8p~&ob~9(QnfK0mF3ydI){Xs$07)nB{mUGpcSR-bQwV#C9i=8e%3i5kj?O^K8rA}`(w%a4#1(Ss{vUh=Qq94#Q`Jcm_rXBKS^8&tE>*dp@6^vQ1c z$9losRT+g?SOL*W1D$3br-hzjwBV<=Y~JT=b+&M`af>YfFYwh;`wx71&Ihn)o#(vA znf>_eYZ5rOxKMG;oddSpI?+vL0(^p&e#ER1^j<@KW#e^zCFp%6(`iYM!TZyFKcCpT zMg|JlMjY)6s=)k%*zQ*Yr6QG34jTYVdo`_#BKRMO!4 z5Px`B{#gvkGW+VA25=GEI2%JO@NyHpM?>01Bc2gs zX!d2KDXn;w$zeXsAGMm1kD8L{#xEMKW*3%I`T5B20g4WI^pB!YuX3T5{i1mO%f&*$ zGt-}rc;}C0@Ov@j3ZZ=J*WZeZbky)Kz*N67b{oEWqWCiTm1^jt()wS@GyJ#mSBha~ zWb7IntgwP8rWgSQab!Wvk2qm@QR|p=m%B?C(Gj&OoHbX*tcBCy0!XAhpqLkc1A36& ze=n|Loj#u*Yga?jc%L|JWJ*yU$vZ26>zzKEt}30bkJ6{rPLp>P_EOlsSHJeD-N);s zkCwK^s0AA`pGpxGI1e80x8=nJ@sG<-OP`nflcg=2tfEk?MV1b!5vO==e1;%c*bLK?*>$6sM$h#v`ip zl+x|?tQI%q+)A((`VeuTW7Tg4`zi0V`{7WJr!}FPVTD($WAaL&rnX6e@M3kSwd6*X zTw89nitipoKXRJ(?^wDDp$~1vi&QTaf8N>9Ua8$~yx?k{TC}n}RJsO^9bcG3OdXnt zW?m;fcD5xw-DSQ_E#E|Y2DxQDId%5abR@og27TP2YJS|;=}q+&MM;sqyPT}`q3v6o z5M@rqyb$wFY5_o{j%*4dG^5{#JE_)aFSb?-lW&{wcIDQ7jc$3f;5qP8c!f?7>rS%rP#&q_tTy*yt@)gIk)y8pB1_jQ|bGVR#z zwBn8O^3aNyrtu#3ns(NC`V{9pb3L*dHxYk4yI0eS+pIhD`PFy=N^@RDk-B4J=Od8x z))mj|wZ-#m=v6hldvYt~mW=uhXn$_xle|MEmUrs$CB3$$J^X%P4ejV<^91}pbPcL? zpcUQuV=$p>>TF*oV>I<%{v%@v(D&hdt|7sz!RJ-TOa1QhcyZ7$Z#A~wJBdMN3>S%izL^wCEL`?ts%Xq>0Naq)DSXmUULVit#{v3^J|~oS?HMXj^E}~3G-&;*OlRaCT=V_(|LL> zM@?fb`*05xi+0HlUapxOIh;4`(GHp7Eyv!7!3{aSuY02{dBolxy;y4(d-*k9sUJQg zw7Lmqoh9E*oj2VvABUWL9;uG_6n?5WU*8uN%iv&9ToAt27|=~(k2$Mt$1e}Sz&`y1$n!NY1)$|=3X>psZ{yIZDJ#xZH>l%c%xHIYS@TPMD-o(!PiBl#! zzFx(=(WZH!(Xr>|xw!&@-gorSAIX+EKeh3kZ349a+BG&>Bk8fv`_H)0!5*ROY+EpP zb{_@t)W_{TgJff^tq-C-yYFL`jXZ7O+%vNSrE3K4-&6s|C6@BUg8#_vqeSuatBf6_Saw-y~bQpeAY8^F={VCtYI~_ z^jch(8(IPke0oTm%q1w(GY)Kg2#s!ExM=o9vvkvYPPNGy-N$dI9*>=%vwMmx*C<)q zUbdX;FVneFgOErmej?mX2=I0?V#oVns%`&Z26- z)0X<(9b*uiwVk*287O>sIaRC%?H`yk-*9a94Ic68vOmP!&v{=uQ=(&KE}z_8pCUY3 zNSB8QUVj_4xYK-;ytTb&zRjV{4-n2&&0G}t+{3kO(7*jyyxZ@&5iwc%yzro$jRtLs z^I5{Re0AXhe&_ZQ+2}Z56(0N(qy0jG_mJt=cSxi-E@2 zRp)Wut%K^VlIthI>rcOEfcjeeHMJdW67N>s4R_Zm7vk8scVk3)Fwy(g%3;Ol%3&K% zz_VRE) z9c^&kwzCZRa02#*%I+QBo{m4(|NGaK$F}QOM5^Y1&t}-h>!~e{>ro>w-BNfv8qp_n z*4Fm3`{B?`bZUS>msU|-ZLTZ4_RFbd@NIieBEs|#Ir5S*pyrdq8!x+PY;GlA8`v_( z3}L|fh#8Z;s;&erOJ!)vyGfJt#~QEmhjmo)Mcd<19E;Joec{&3d)J+kzJj+ip!g$S zyX8p0aRt%3C>A6*1W9m6kU$`~ zGdLtT32q^{ySqbh4-kf6fdq%(?#|$YI~jcN0fw1*oOAEFr{1f&RrkmJ@w#^Hy{o#b zcdzbVR=w7@o8AJ3-IKCmdchz*kjtPtGHbbD>`5AYLW-im!Inwp6_D?c%d^Fpwb4zd z7s~NMwvQx*tS$YX+OZs?x(oESVl980aCbg5MFTIo1K{TaR3D-ir z`dYlT;&z>sf9c~Jhkx=F#*yBAeAZ$%rV^N$oa#MA#kjG?3rSi~>kuMwz_lu{ddD}M z2YnE{FA&YXq64UyCMmR)1jmV9g6g!Ob=3ydV8vFEtm6<;Vs*fNu(+7yM~Q6c>L#-A z-H9jKMcY7{pSsKj&G4a3J5mmrglD`BS4ZsVkEtAGdvLHFnyR2|jDvR|d_j3ar$O@# z-Obxjj#m0LXA_Nfxcdg3Da{0|!9FH9nz{KbfWh@&>&`u&s86U+2JHgRG&gO5|2ywf zF*qk;7*%{#uNJVOmrajIhJQ3@tucgEjU6=>eR3kFoso zd1^S9I*kI7ayIGO+|SqLuGOjyz;3^Sw-1ckX#vd#+rRe7HH@hkyz~0(Zn?;AQk;kX1!e*@Zn`mqW{}mlW;a?7-kHDB!Ka(|`6iz) zEBCNWUUiz5j#t~9b_7Vd+CwV*k53r(9X7pM|GEUw=Mwup`-80Uv${!w7XU(#uz-Vi zvxvKkU0A1YbXz$OzPwl`{UN_R63BWP+tEs8Rbi@31-|h+`f10)qoG81?f;kv`hyzY z{12Nu`0TkD+(XT3=8{D%1H^Aoz#<9bgSQiC0atPJhBv2ke#Jo(jEp@b6<+0EiTn*x zkSbB48u@+r`Rwi|{!0BA9r!cDADedt7eQd;!vsa;V~DQxBI+{X$94)=L8H|J?;tEp9pcIDCuH)0J!l<~d?a+{wvKq+#nJ%qpBBnGl%4xMX-72zy&VQzsy^<&oD{BR z+T}mdFw+W}E0B&W!`D}kWFRbZdR{y?cd z$kHt=;HwVuXqlp5(d~P3-|wmFgO(j9C{x8yQ-#gjsXvztI>!FZk4E=@m1Oo8CCN?8 zINiN29s?SWRdx3l9+7wuol*b?N>{3CHvKAkisOO)8N@dwD)0xU!C~cW*bqg#4ZU5+ z_3jVjK|i}SQ;UB(4|A6;+jDOvNsIA&8v3r7uEvl9r=KY^8|Dm3F&hEy)|WO&)EIp( zIb82Yw#VXFr!MWX^ZoqI+XCHXhBN(pmi-r!s0qc9HAKiCOi)EyNH(WY;j4-*#p~cf zzh}x7#;V!D|2g0(joFyu1Y6>3LEw60chXDX?Pr{_+ir>@m#tSBJ~e@#tf{KuYrS&? z86lhni-#Ny%~Rqpss5f!D5CFEHvAPA^Cg5IFO3evb~t!qH9k$@`_&)oJf#1}==nCL ztT4wobglT=e5x}bsWwVBIZ2YxkH~7%|HYfn2fAYKe}sE6I(*mR`lCYbu}X)8&@ZJ5 zhC0(5{Hx}IVMD&^`vee#JlkQY?Dkn?U4OXAfxqOh)&ggQ-KkfeYgu`N8Ss)#aLQ|j zn%iz`Y%G*(9>#%?muGgJ`LJ&RXW7>iGQaqNhu0rMu0*1TZ5u9qF2^h(lGnaWB#S_ z(4UE;hop`H8l55X%9G9fW-OD5*?XQlu~XE+7>M5zB0gFnW+N*)qMe^Oat#es(hJVa zJ_Gx_tl+CS7QeLimyj7wPTl-wb8=#K7y@x5y?-bhr}CRdB!Om;z`>n{OUau2hDe>9 zg&R6Qen}uB4Jy;P3`4 zk3-%XSZYrq7le{boJtK+FPPkKrw*Hnx(A}ae3aVv+Sl`|vaB4dtge~0^r!tV=6QRt zW(?31=}{_98wWEmpo4ZW4BFxJ6ANPDh*^+4g-yk+MVF04JpRNjA7_0_=-KiD0>yT$ z*GN$()CqKRUMdIx;bT7&5a^9!W*n&eBq;yV_zmo@B z#ISq@6kl*w9|Qevp#dFQ_kCQ+T&DSMigY~sgK%$=HtxmWHssr2{-D#5mK_WY&HIp( zWP)JlH@mhvI2%d=L}idWb~AXChjXA_&}SP~UsH?Y>vS%~Q$$qL@I6Is|4da2(PhPT zBj@fne2LyM6bok%&#sP-i0qWMtr=(xx;GQp&d<+8?3CqhEUY7%;B>Uf9xynQ@0y>} zi{<5H(U_s&Dl=O6&D|oHk0axS#Tz@ z2DJG#1cn+p+XXxfYv>+!NZz*?E}LCV4Wa1Z#Vp<4R*!(~1Mk);bu+yoRDMGe#h;sQ z_YDKp(Bl;s@g$P_+JY(G2Ag_OS6$OgrN&^X93!)*_ATlf&7WX&FAFI6|4SEkg!DiT zR-jrfY0X_myY$d5@KO(+w^fLS@e2o25wyjO=tg)bnUI_Qel0!Y0XK^h1-gx6Pcu6 zpvu+do%djc)nnYMG2*-X$hUj}^u~f=2FawnivYc&mWOrTSvVXkUtDs%dH>RvcIBAd z6)x@~E%lI>G4lNo`?K+U5`vRnt}Y#0@+~xHv?B0(x6=7XI*k^&v3*QEllv?R-y~k{ zh8$?)PhwFsg@Wn2-#dhz2wjBRFcSSHWNeqidzKwizWZ}5H3)RlZKSl1b#YJUQ~smi zY`6`BZuNRM;N4Dy%XKI1+9x_oaHiQf5IO~p7(?Fi?a$MR+kIv&@OisAS`?aosxM zW3r4A{-29{*Z%XE+61)bK)-zYA;Bx9i_@x1)ue(9I<*)MMR$=gO@`E-iAySJ7d8NX zpdEUj)YMTfic7#Kul>TC8C@uoU#p+-(m?*kN{VfkYM$xtQlJC93W_EE4l_!yRy=ke z@vBt$k<0yVq2{5w7sx86bsy%ilWau3pW0@ua!JYqUP+pdj##j z3RLZgy4l&fd4G#)=Y2%}hlzR?<%nqhW)<3eU45TqBNkN+Zo6pumJj@*2ZnL+k8A7# zDmqiqO|rY58H>U-!|uRm!IMU{#SR)MT)5u7-HDO~Meq>EE-u}`I|(3>&#w+{L^8kI zL{KL2E--}6`;XVT&uiVfv`Xh!=`-Hjm+bZK^=*BqmTJKyDBthS*iYhmE%9S0hXgZ_ z$_yyus!Bwb2WP!E-}e4M0krUwA)75;^vDMgq9Q))D|YEibKdq$BI_hjx`}wzqG15k zSxpgBcCY)e<+n3LfzxjBB*dgwvywj1`%H?+;?QPZx>fg|p-kY#RFcVud^p#R$+B}+ zLb^d#x3Jb&U{%GXHiEr*>9Bu%djn4wxoI_aYxtSA@HkRn9nJtX53ww&vf{(pNJDTs zUl`ni{)ODh-ek8WV-$RLi>&_i7y?FNwj+r)GY%#4`k{9rRYt5J$;S|DRFY9(Gzvz1 z1M{f$KhuP8yi_{aKUnVl6BJ+wj+)}HXvlFE9<)bNxx)3Xx~F`s_dRc+EehQ}p!-du z;ZCr41T3l!^~DkJUsChGl-zX&pP(tw#|_;qS;FgdF7wzFY)cGHgZi;L>5U!;_m z%kTb8J7c%F6P2sLAQUbXZI&1=3>^LB?Ik*?1UtR>eNxkH(bvUtyL>3s%muP{Ij_3( z3AkB^exN6bS)^I7k5PqV-Ah(D=^Y$hj_`SzmE0y)qC}Qzvi1)P>|KC>_7$3XhmehN z`G>pB&AP(d5T}l41i}YrUh2A^=!B*EXVCA}aZ2z_vw~RViNnBORfAGN4**cKlU-cEUAdQ+cEAV~BztqmvhM(gv<7Jc%T0&GA#RMBPxZzp zHca-fD#wtI8sc4iY|>pPyVAj)N;FfCVr>t11F$RlBNC*F99gB&fBO-;Rg z23-gZAN*5w(!Re5sMNn;)`KA*kvh5x=ARxk@rF>Qp8Z){_w|_tUayO-WJ|61eS2E< z!VBWq*Y-unKAn_L2#|jN?cx>*{a(0XaS63dWhldA` z;Bl`qdY#30I$a@texgfH)=o{;H3|-g^L+HG^am89?BJj+RF0ICRPYL#2f9;nHD`i% zuUFJU>K(;Yr$MgQgh<2RhXyb8m$QHpJx!@G-j5z7-}LNsQIN+}gqfGhxdHf5C=TS%PHp7&~Tne%vZO0(I%eg*&oSO<_S&>2|Zgw)%Gv+Pec}f!#mUiFgoD z_2XUbiT)|;@aHj27(e3k220KLW;vY=s`~sR1Htwwd7q5VlB^OmaCi7f4-8KT%LwF8$KO{9S z!>q5g79$@014b?+<}4=;g$^xqobSaCYF5TjrS)1}m|0HnfB=}_>1#v}9LsLzm+!w9 zC>x2P*O$zbrd@9&j~;9ObESZvvR5FJo=_{E`^Ai7#_U@2AezZ8hX>faS>vr=BcM`r zK6lh{(m!z)739RyeWkSdsN%p>nRk8Vz&@)`s65uvA`E z;Q@4cPO>dbQO!&+CX#@cUK5RDe|3H>U%gsxMv=?>m_ekXl&qwbf{=hg)XR`tWQzCB zkIt7#cl@YPeez)Y&W9h_0T_4wpUbXgnl(&8mt(avQsl4(fJeSx@>pPX(|O3I5=VjN zF9{yrMc!b(tQjCUxX&jR9GNE zt#sno!D(LaZZ0^2BD!P8C7N{Zc-w8LoAwZ55c46|ov)C;f&uw={4n<9%!m+&3nnKv zr!nC22&$N`;EH=B*l3X>NNIDb?Q8OkzQUSn4Frr>hWF;W_GKMqn$JhHmcWG}moviD zAQ(i^@8PXqe=(uH;X%UW@-*Pb zYK~K%(q4b~|6B|+ZnTgts0KuIywL~N-KGI^F#&tf4twPO8U~$EBe-DmonDmV^%ADT z?+HS>VmzVs7MVc}=H6A4aLLAy1>tUF;+a{~ae%JqalyWSeh_?Uxx3AD4l(Z01vNu~ zA%4Lt0PqPa$ZFO93=CauLOe{sAl-=Wng@C?tO6!oz2F1?p|DUu2X^>hLwkVz2T=C^ zS-F!2Jio7O(O!9LjfVD?>c6LV{s~DN4gLSDlmC6I|A6}CY&l_HyiHT)B8wYfPE~$Q z`SR(>lB)lj>}6bHLPA0!S5Al){Kpv(cz8dLnvXT~IF!-}0OQqiL)*DO|APbx0nt_( zQr``M6~Dw3_hY!43_f!}+l&hCzxqnI751D2z3Dm4H1Kt=&wBcDU1aaYWT406g`5jo zX5P9C=Yku5Qqg7#`Wrwa;87W{H?J!eK2Q#`&uopzo%# zj=UU?a->(8v&6)l^A4-*XNrF6%px~gmYQ-CW}=iMvr-z^?^zuy1X_|mIB_D+j-69{ z&Q_JElHCVu?-Fyi&?U6~M7ZG*&%D6ntjVsAQce#dcqpvywJL0;3vo+stqu+jH{#$f z7PN?n6XIHYXc_G34R;~}(qVaN{Jevfi@F-$%^@UsXoz_L9goc|>H}hAz;v~~yl1W) zO%#k2w*x=k(Js*Qx%RLT$9So@eZlDZJ89OuweqirVS%S52QKs|KqnE57KQ(pURe0k z5lz_ew)*;ltQL5C@$~ArtUSX@Z3`BVoCFsfdBZLHOMUbkKDC1wHJ(GBdQXQ_nCKGm zBLw4ZnOB(3U?5+4^zs|=87OI3UIkr?iQ=|7IE@2@|3_Qljk2D_do>%(A*uE|4jxZC z+jQ&iHw$<(E&9HoqOz-?6Dk#$Ine|Z^fPg0?bPQ^55|uzIM&mK$k>Ag!sOA zMV5e%T0!73m`Hr|>?>^6waLr<68M2jVy`7LXiM>mNXy=2+U1Rrruhs4Jyr-otxsmq zJt?tG^#?#wZs1~z7ODuOdVDV=yd74>AoNl3B3sGmJnET`H%Bf=7{EolC+(B;JQ3Sj zZEN_~I=R!tvoQxLz|Fy^>WV#-xPd}4be(wRjZcJOtewB&XJ70vlIzIVq+vAYQ<8h^0_Lqw;lLWPz{ zuHXBw{nuk+Rs4f}h+GE-G}N!=Ss^}zK2f~HiOL>dlY9OdWA@!HRNmo&qVLEDS*U|j z=<5sRzg{cv%}C8m6Y)LP>52L{_Sot{mRw902Q-dsz$H2uElA=N#}2~5@~EO#B-y3Y zVy9R6P<00TrN5pRIaL0%ToD2U&f_n~ z-M(b#52fGZJ$Qo}Zx5)KxqWYxofF`RF75>%yFx*Nl^4BRDCI3$uitSON5?VQ$@tb= zWt0S`V6gcKb!K#&ks;MfF)4{*HR+GVqE{FQjLMzYb8aRS=!IxOlFCt(1P)l!NdBQQ z>bBjQ`@{M+&u*=B$&he#EwTu_k2nYsMzCJexpU zHE}8NPx(D*6@aRlogk6bXPsMEjwM(&05{yEX6`w7CtGJ;52KzyIA@kO#NHt|+$zID zslD5sa(wunVR~17iJOK@@_Jn5@7mch?x6I#-uiHz8W|@1{eEZ)<}Up7V6Wr-lri?o zrEf^eRkb(BZByN_2w#c?Yltu+GGR+rAsa8Jlp`~|jn!{SCdhLiAPYajH#l)(@6-F> zx*axJcNuzt-xAo#m(6*A*fQp8zGXb!;7D;?6KP)bbfkVp+beCzE!!Dd45h}(w7Q6j zPmIw1w0Rvi6yYRg`TaxKA<_|feaWUyXdZ1jP^84)`X({DgQbE4aL@sI{S4iMfp!xQ z(@ap3y#CaHc34)M<(&hwo08_cX)7`$GsL>87q@Tw&EoHOpmctE;iKuji4l=`HPM`x zVW4j>zj4u29_*RDbrx3+?|m3jpp+e|i>6z&aO@7gn>wq55RT^?MI`Zfm>1Zze4wCG zz~$TL^2eOzU7_*}qY+DUP#v0sO!Z4DJ$o!s^?Gx?uQX{Ed z-4M`}Y&FB0b4*Jave8SfUW!>)&wR1Kl4a(c6Qcwzam94S=Q50eysR_t`6c$u8KAdlAfAH5@qWJ00v>iT-gXcw|94d8&y87ki znp?ked-Hj@xZQq)Bv}rbR3@ ze=!rvFW(#qw54mAIDW>zR45f1$;bFovyJ4z4Fwj)p#UW{;3F1@9=X&#y6oE(b0lRO zzde4zFFy@y$doI)yv4Fh(n;e$*FH>1mR23y#Gb8=j7P=MVKfhyIenGjBUe;T*LJI| zr|oZ5?4;k{y@Tn~w%H}_CDq?(I8`diAl6BmuV;hAn%=(Z8YlN67_fe}Bt|DaR-vt& z!;N{l4EnT5;p!xy9oza7mODuTwcYuZcaJx#M22sTqeFi6D9;;ZqV;&oUj|X z6E0g?4L=8sDq@dO5$@;U%|6VOqO#lvmz1+e7{+_ePlktA3lB=AsE0_zh4LIJ5hqj~m(GlW@1)xU#{zw|=G~>ca;h%(&zB9QvDdFqQ}c_- zY@w;pgq$e$Ap9*Cy!ulylY`2#RiQFPTSuR|=nm`P#U(p_avAo(`!a75Yu-Uj z^3p{@b(PTAT-Bb*idQS#1;=y8fLZrtlYTeZPd`mrTqrM*+>W7du>3K0cEaKbYX)Ej zv%A4|v3nU2n$>8rZY1=_UaZ3GkTTCwCo*^nUn{6*w*Gmpj41=Q+kk7~ONM*BW8nGxPfJE#G`+Zd z)@I>E@AQ1@je#Mw+Bmde#eBZBWLGdnqsrdBoOpcZ;`f~wv*_-k?2^B0#6;zyw_|CQ zqa=O=NisdfXp6zg!LVNe#afr3Cnh55*DNVM*hwKG%pb`4_=gUvMpM@nFIBGE?Jz7E z@9s_@kcfGIa#Z&Cg2x6yoU72|PKN9W){Lh9Ctm0VdO`p`#=1`z4yGzN=@bIwBdG zazC<$I-o0TrxeIn39L?L`9ee$L}gy!K&q|2gZjyq9sEIusn6k34?Q$YH6hOsd?WuI zOI;8Q!H})si{jm(KXRl8nUzwVaPQ-n0c^+HkBr$Z=AWbQP^(|^UlS0wW(O(^SV=5^> z^J3nH5b}Pza!?1WAU=l!xMG(f?h%q_Ye~`iK|*q}Bzi)t?Pw{An^fh-XZ%@C0Rl`W zqNwfmD)8Dz0q4UPOXPwd=R6{P!q-fnGGq&2w&ld(iPs7Kx8dzg#hVBbROS|~=5dBe zwtqg=`BfWl6OC`_PB0bPW8+5=7K^SoVW2MZ>ShbY0L!avn)OXgy0%UiI#{f<&*1ww zEf39_-Bz+(Gm43@DMkP;zn?7MKuSPh7wVZ{Ls?5q(72RufE&Accm3*2xOpMqS!mKU zQY-z9ppT+`+5a>l0qGBeFEyRWb*#)*>Q--|nL= z%^KG*D)eFZA?}q*TdsC2Y;fSbh+?2`1rY7+OkmQs_TY9dJRiMVaK$HZ7jc*hkI1svDg<*Ul~Du>iJ zz0}`Gn-+3}SEPVwpIr+DW8zzu|CTtu;xGO5$h?$)qhvy zyfQrQ@!eQmInSQc43UDg-wO6TskHGEyERsO7AymLKC!mfhPdqJRhIvxH>KG8p95cD zM}k#JDr*`lS23uLW14<<3K^!%^oRt0p&1fdXU5o1&`0OpGz%s6f5t{ac&7O7H>`ao z84jp@&^N`n#Fr5R@ZuKXh%Zgp@~BV)b!FLZa0ni~HJr&9UV^X`KV61*j1t^n50xC% zLMJw~0wf)5g>!nS)b?w7eDt;MT_26Tp_A!T8a${b?!nuYi`M7YiR%2#lgcXE=TBg5 zDp|~VZgj+#8T4_cdTUq>wqYH-KA!jVyFc-5rExIIDrfl5t;iUJkm`Y1X;e+UzvDlM z`<*3U0T?hvJdLm;j1HMn@gGVXUvn``RjXDtTV*jPKlA^!|K`I+w9Jvi+5{D;_MRgX zzt@Av)=HQk`Q|Zz+zhBUc-YAiA@fyk_U7rs6_Bn-K6tkc5y>2DNElA z34{Q@U-Fs|^B;F(c%~qXUJrjJPRi8|4?}PN`&m6p-$* z#Mur1J9I=n*2IAd3O_7XPE%gu?p$p!$alMSns9DVTPfgWUS^q9ynFXEC*l|WO0C6j z+PsDXNT}&ucd6<%*>|@(-eA&W61kL3xpY*<9Z)V^v@i+RMm>>q?+Sr}ze>MR9>Efk zrF5`8f>eC$O=2-DdH3Z(H_W9hM{V4kQPiE9l+ zkZ5^Np#19BMkKrZLrql86HU&KA0`;ppu3M|>}dC49YinBU;RjP6a-I&)oAyt+w3vKVa4dRc=_tmQMF8hjX6}_xR&T;!HNhVc1l=YJHHi*0QGPh( z6=zNvrN28f@Rb39Ro-R$-Gn#=+J-RX5?Im_7BQQggTScO<5paqR&H~L3Y)KAefR__ z6MrGTNA%dgYh~0T`ZLjoreT@&ZV_v-S4{oe3p`7uvh49vwPj@K#r_?v@B^OioswjO z-dzY2y1UR}p3jUj|5Y7zJ0*P9mHC1Wyc$nMfZkddUd&=6^wzgjl;ONO66z43oKh{J zmr{Oni21w@taUL6 z{qauAM1p**VseFPn`s}|3O`o_(Yr~L1o2xJYTvz~YyY0;LNV~vSyJ&dwtJ2I&E*A> zm~&h`@Wf!!;4vpj2w_i??T*Pi!%N{HaQ9%xra$`f(K^CdY|W~AqXWjc7Tl^Sn!7*C zd%BsJ-0=LCA(~Y)p(%*S8WcO3{C7 zII@<$!pbqaIbDlOtiQ~N%WLwP)*Ln*Bb(FiL|0k#5Tk8xGUw zC+N!$6JM)6#L%tV*m$NN!+VJ6b~_rRnUE%LS|ir{S-_G5A4@!jzwl>==rLOPOC)N3 zP`V_ROAoJxzb}_Q5I7x%cjIF&Y|z66TQCG|8Z&)S7D=a{yOplj;5sj_S!%TBY2@UF z0G^h2j7@NjFA2u;*7gE?%{NtDTI03mLL4=HRGvUn4xc(YD~&@l zHRoDjFhe?iWuNcijR9PAA4g!HUJ-%#)9E7D6HJARR&T}5NutI#BKrGH+q^s~LAh?S zts-xG6Ax@dm3$KzY7LN2)Hw-aM5qOy27F?$=@E54NY&QQqLT|Uy03_*DzL@TnDUg% z%jRX#<3GT8n+q2c?_@Qjj!}BCx*GnM^@nm`-1_uZ?}1>rYHA!xLSQrkdTIRi*)RCh zOhuDs%L7cT)dF;d-iCkLlZeS%UbV_ee9!fhsbYyx=I{7YR|n)aYOnA%L8S$^z^UYi zQ-1HzW@5j4e17NC8HrqaRY~q+2VdNCTn1Rk;x%n2o!VJBpon0}oqXD#+Mlvst&@-&v?Xtbq#4T6 zP1_CxX8G1PD_=Lh) zG3l7wX+>XzcT<&>bu;=Q$oq^fS3^cpHWW^u5V0Qax(Ag@|H$&Zqnw0b5eQ5!L%C)C z6RacDp6NfMY70FM^U-BJjp87f{~fXHEbZz7O@!2&tWN~+S9&*z;Xe>j4?i?UZ}c0a z9!y%lHP?gAn#HiPJ^$$N-nlfcs7AiU_aGS_f}df`qny4rF)B~6?S(nzMr@d6ypo{A zxu4mnj~{YkSo&GYpN&-bUMnWdjWjQ^HL0t0G~pD3MP)~u`;td4y&Xq)am{8}3p`R; zzJIuT#bAuTLvr$^r5Rwkwo1k8*O0OArM4usauSknGMET>#~$jjUk+#G^L z?QP;zn3{j%*`PsU9ztjdQ`_r4iYC!H2KRRKK=pHxwTd4g!x!903(ODH%WxrrJfLia5o-f4DA-5PTmy zRtyKz3^`qPPifajJ-#_uJ<(Nw?W}K@a<-DTb3N8%T!IxTmfY6|-)Hl2wPAk_g_L?5 ze#7WeD-*S%7A^UNjVG2WEPs4Tr5TkpZdb%8vwqw0{xFpebF~<4jYvZiGv#4eklj7f za5IP8S1XmokWvb_G+61Uj1|55yPMs6l)b_AnsD}Pm$UeTGhnWjS+lvucQ%MJraAK! zB?%qRmipc;HQI)r*!nltzuDlf=w&fqW`d)t(wPVn@#q0<$cxjYj8-awuxg9Fyr`L+ zo4SiN3dAFVO2N@dsjtjjG8v!B7Wa~}uUuBi?4MUu1K7aX@T8(j(ZGZ8TIaBlnZjR< zhIL$Qd|k=81s&vd%6%iRANML^R8Zgf1#NC`;Vnj<_(o9Ee8n4m4M1lwAM5@4675+F zj-tE0eGw^j5nYr>Y#zR!%-GN#)!RBf5QTzc;{h|j^XqA#YRm(PI&n|m38fRQKvqEuegR=8tw2WEawy|O@zTti6^2;}~ z6EyK@1G9h)l)#rptjbECd@#LPz_M^5EiG9q3G?;(`wD|o?2BsYbnBq+rA?zK$e^Zz zeT~z|inkb4YlNOIwi^pNyWy_hRb%8cah>nK_4c;zn;Pn}VjVVy7B z*q9AaF`Id%nLoqE#pq$k?(&&1F!iWE-T2*`ql1hzxNT(GiC;wT-Qd-jF`k7A4;9{c znSs*NpIcIp(TQX;{;U?v1aF7gxi)7))=S^7+?3@35!cFX0 z-wGx{^&(5Uw5v;}dH#(C*rwS=T}&|lvbpPjMJnlo`~AtI`3Yahj{O!1c$hmxO*Ex? zk*U+!2CUgo5nnw3Jl*~PW1UX9_KUoVj9>(CcW6}HwZ5NL zL-~$%ik{Nov@43Ay|gMvNi?-GzycgLu~<3$q!0eBix(GF9nyMloIiv*hcRbQ;i8{@ zZKP}E!0MEU0C!EUUBp)N6^W4SYP$ew#vjT=U97W5Oj`nl}BtybtCx=K(zCjRJh_0 zF&0||)k<)_5xTa9W&9J?k&;*TCdBykp2GeS^#!goRWs4`HSSEb;K2_Oo5LUL@Hnsap59t5a{#ka5LjFEZWd0fN_XhI!coWLoR~k!1;u(c65kB2-JkEx!S&6c8sI3+?(8JwVa{0f&_b3w z-^c9f20~?jK}Z*|(Vyq_X1_tb%?C7pwLE|HI>mXbkIR`&TzvT%<9jgkxD!mM_7#`V z1C0{=LQ}!FJ$iU4Mtr9SW}(+hmGIWt7~}gQAP1EU?)Hul)4;u{2)T+vZLhn=2f896Qgki&_LITEy{Vt*u1Tijb*R=30KPBPG+_MI*#Fa5V5Stjt@ zZ$Oz^BUNG#_&zW<84^NE&VOAxL4rGBgu0c*6AQ8AO=UJ*)_BdS;tR8zNRxzmeBb}r zf()Iv`4u}t@GN-K&PdyzEtl_0Xd_7F6EEmY0zgDZyIAMtL>O_pS@C>^HzPcm4z9K(?f?{Xom>p5XCT_4O*C7)-}bOyN^!XZ=vsTLux6jNqQ|r%C(D+l5e{oo&{k<(%g>AjT))^d8)_Q%Odk; zmPeNN0TzV4BR%JD8olK88!N4h*=M~eiZk7OfPFWI(9HyP&$4@*RHYm*g zoI4 zpQ8YYECV5N1$RS` z`JQh&6+gzY(TOD+p%XVVM$~?SuzH*-nbM7(8u?14mhvK^Wb*qnn7zz|g)nxPA;a@M z6DfRwPMfc{&j%2Dr$QUJ{~&~H9wKfGH2xQ#KO1Fe=Nb77piOdo zh|dob@Ny0{cnS5<8CCqASUiX(*p|P^u@LAU`mu5~ zz5doRGEv1JsW#$+fN_# zb%@eanR#Ud73o9V1+c+n0gu~j$1;1_hmQ6IJ}sZmr?#`!J%uFbpgiimKN%B^;Uza$ z722hq!*HVS=79u5cI6Y3QgNTTbM;)FvITq-GC?&R1|9!K0wB%JXii)>AL|2bY=TC; zgE@{&h^c1&c`yNd?hau3d2wO?4!+YXWh>T}Ix-0-MeF=n43u-;rnH7OM2T@rJGs57 z?mdXfsC%+*=CrY?yZ|`dS;=BG2j;TJ9gA%f6T}KEO0*F+Y<~I`^7|;Sm`{3bdpX13 zJtNMBQ?^u7%<$Dh+b zkl!B0i=Qudt^+pEk1DMBZD4UO7&Ax^ohgZrnCWo`Gg{_)Kr8hhOO^%-Y9>&$=T^{f zF6SXXJw+97+~mGU{R}dJtcXAfc%m#P*3X0LK9N{E$>ew9e{mc1@dRldC3$=ukFJt@ zGPCw!bj}SXCydWuZgGBEo$KHVSO7jDjZSCm=%N+E+c_m92$v>sOR9TZ80iakHXsM{ zF;?oX_of;sBxT3)eUgSZzMFOvV==jpGP)u^d_8Pa(gl$${`e)>Ax#^E=_9uZI<3#} z>if0((xK2^;X8RCJkAaDJ8Av}R=A2T7YKg~^!ABSk-iSwYe8BmzP&oFhve8lc+^%O zH!uhKw!~Ono0@DaVsxR2wTQz7=J2(&t7gms1~dy5G*%f~|Fs}4Crs>qhHUn|<1X6^{*e8)f?8Bh(01nKjl*73k! z^-SR{;%#KTA~|NfYc_`-8;SQras@G{?mb3)sUuz4xZr@C>4 zUhwEG&nJ%gn4{fmFm~kDDie_LkFLUzUFaXad>^^=TDqrbziHt;nk*TGH{*_gV5pFN zPP6+ly{^m5n!x}6zfy#vaMp8Q=J;^@f}x>dIRAHu=nmcgKJfGZyyhuHbgA{@Ypoa9 zTX+z3JU7@)O=0}$-N&O99&vkOW5Dv zU)tE1x-y#zoC>zGdZVbM6yMw1+ZIq7{`kqn#ANW~#Idrv`k&x?e*W}QFWx5t%gV|I zArPCVL1`g>bMx?c{Bv+{sQdf(#qsg6-P!KlorokiGQ#xtd(>wd8X8_DGcz%&7ho{h3-$Z*7I$L5%uBRbKzXq?+%aWM-TVT#i*hR!J>Y)**| z0{&r4D-ZVPb zt|dqM(nfOc2L1mqOeKf!@f+kHcHhq4D&q05P^-?s7}C>l6KxlhW;&k|vv%ib1(C!$ zNmCKUAo*0G)u9yj)i($ct63?`j!&1QJ5wl&b!mx<$|}jwnM#UG3bQat6-=-=*T7CO zB*NNl4mZv!g`<6OZtR~%g~%wv6e)$t{sj?3dM1)WyC@`1EESm~vN$9zL5#^Ug*+h^ z$s!qKIq5(!If6+f+#iO^ZbZ1u1^5b0>e!mxolwnn_N~WW2GI4zb~0juVa)#p?{(AYix6* zb9^C(drTmw5@kszDiur6@y=W!!A;^RE{bGmmyV`ws=)SBtuD$#yNcXMN|uc9S5AQ@ zR-LG)G$cc*Fo{$ml1fF=M4eQD%VfAjnmegJ06kWoPMfU-#gCU`5?m6G%doNXNzhn1 zf%-*E5;JPuzo*CM|4W$JH15l}&Se{YEoKu+*(f{ZVBDND=~QQC6J9{O>?EVI+Q~u+ zbvg>H;zV1jBSeT|fqa zV3;nb3&;Qv4ATX50T}>-VY;9$AOk=!Oc&GzWB>?;>4Lg|3;@9}T~HU00U#Kr3+e(g z00hHyL0v!wfMA#|s0+vd5De1=bpaUwf?>L#E+7LyFiaQJ1!MpShUtR3fD8b^FkMg= zkO3eVrVHuD`=$=S*QL%}m9iISc-XvUKsU_;{+VbIjfA{#hW*kK9Bu)7Vh-s)bg_jTQ@zqY+qF6neL=jdHmQj`A07At&aIdcdPxRk-N@% zPyJcem1wE*b|u~`Q5t_Mon;X32${jhc7}Z1l^MIhTAQn@(f9N#F4?v>o7MFl8+cbz z2m1RzQ|~RKa&$5CtIoc{>vrwzA4vPE^~bpMTlWV|vsRq$-L~g?bBiT1?-EOF-_odF v9^G)Yk(f4o;U(T;Pjl46_l^xMemI@jPxOA!_Se_`b3eBGz9f literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icons_silk/checked.png b/workflow/public_html/images/icons_silk/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..fea71f33d9354fdc65ce5800b70ae515ce4d8dc2 GIT binary patch literal 618 zcmV-w0+s!VP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igi8 z5F924QXanm00HVrL_t(I%dJ$ssv1EUJv(>3uCNQTqAuH78BCMHLJ3?%6#HOd6)X%l zr1lwngNv=Gg^&kWJAV)&ViOR=2T+93V!`;c&ZLRUx_33VxF1Y0^L^*cIrGg7@J=B( zCx&4>19%4T@eSDD0ABL>{0m$pUwgeCr7b4F2_jo)GRaL2%Xev)M$y--oKIsMTr+27@4kd@u|nAUf(E2q8C# zCX)%e-7a)pN3~i7W9%XT03Jm*z_Kh)qE@Q~Ns>^hR3OVTEX#u5@3-@>h%P%hV>B9J zyWJw2%|h4pS2d<-3d9ZKoP%?YMx%jFrvuJ8#^W(0NkT4{v-6zuE8I;*yWI}M;Sih6 z2D8}=>2w;3qIfF4OH?ctv0N@OolXG&$z<{-$<;k_Ta#rO<#HL4Btg?O#A2~4TlcIT z8Do!5Rnce^sZgD2j3r9gCy&di@lML_jIEftgIkvzy^?7?e_2mi4Pp zDEzUB_WON(KA%4^#-M2$2qCsAFD0wh3X8=8hr^-ne*L7~Zhuh}<(tpv`z#28@6O9V zACJeLX`1y?sq_=TS@1Y~5x|4jH{g5p0{{R3 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/icons_silk/search_x_button.png b/workflow/public_html/images/icons_silk/search_x_button.png new file mode 100644 index 0000000000000000000000000000000000000000..60336e75fcb90fab5128e6398cb1333ea24f7ef7 GIT binary patch literal 620 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%0Dp_XFuKZp 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

    e~42*&;(s%U@k#iMZxjudN*xTqo3 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

    L#%sbez#Wk%rVx z3}AiU}0kHVbCtkMx~ ze?6q4--Q8a?(RKeL6ZZ;xZbCN8850Bq;zs|v*Zt2v%==+MgI?K?m;Vo#R2y+*+tMJ z!~Ny~|LUQ54yS=&vxM{pN^0(BC`8+l2Fd3P+nB<6Uqbep#l5I+)9>L750$NC{ zCAFReDDd(>HpgJlXPxn^4`XKP|2P0IbsNj{$4{VUo7|v4$jFR|8eGw0$r#Xli`9&b z14)-qO^oPjD}l7-@DmC|QLN*!8hfYOms$+M4>7$s5&sx4dI+L2 zEvNviY1{P*x>`=bNXIH@gIV{g=cTz#_xjhJ4OUddC*%*RvPHFd5})Hp0ai=jdop1+ zGwkLk9^p&Tk899=y|i1KCu(ZCr$x{ zEYqxU0UeO+L83|y3At$3hfw^N2NLVyH_qg+@=_Id^1U`=z|$oa-PUzDly?8=&wjRs z1KST7!-f&gj18huo}53jAi0m5JTvpNga~ZELnPk{L&@f|cl$kFD;|V%MSh6(PGkKL zic9A@kp&Kl&!II6I+~n+F(1ilHU%P-3~hD!VCr-3A9m<#ZK4t#y!#mgA7%qfF&a!2 zJ2f&KszvV~3MEN!;M}A=35!JEKUYK{2)J!Q61$A{!}3_d`yhokv}+3WL<`6tmg7WXm-32LfQUkCy$^> z!+($Jpckn(pX?+1-HI(Wa0UPdrFrvPyiGYUpkkST-XkBPYi0aJXu-mtrrUS$<(M!# z3GcI=wyVsnj5G7e?~48}>y+3`oYgWK1SX{o=99+b)KZqjv+_%un4N0CnXr;UUW1Y- zP3z3ZF$_Mt4#IY9P#Pn!RP$XQrOEa~15ZhinK&zKhjWe07d}=$%F7ufr@WoevC++g zO?F*TucGZQD7&H+?Od^QXAa2O3n#T7vboDCwwn3i{WmOFZtwhc`|562f?raC1mouQ z!*eiAMx8Nf>UKvxu)$@qcyqZ!i6@j1X40yZtFh$6I%o!R@<#4X-79EhkZPngy|CUS zYVac5m|`v|XtY8I0ct7ROl;^ECYU?q{18h0m`1)2gkBZZ;_V%1>saYO{NB?YE#G9E zbxx9-(JEhr{Dwp#+eQ!n@Lu!jg$sx7?I;_2ZmWMjf96rRe<6$zct_Yce-GeBHWi#?`%#Rf&slD@EmlN-F+{uP5GLplIaz#hCohkS?J1PNOkL*{8M^6r>7!zKV3_IU#e1JO}?86Kdb-LR=DR-OHN5nO}A6 z$F6e!#;qTxn-syiDgYlfuONSeFCeIp_M_(r+>ZI3RI$(3dBPEwpxdKh)1Bdjhg~(T2;Gka-l}%A-!6zwlk!lV0&oyX zX{#>JscdxPdFZjKh1Zx<^i1L%FOaEYQ_`8Yf{-OBxx}GCXVAS49oUvp0tnPrF>EF_ zdlv1&4$!AXJ0&Q!a8_(X?FTh|>w>(tmk+m0iIY2Zb2X^`FcVOF#tngjKV>M2ktZ{n z(RF&7Es&zrDuk_6-K?mSRnThA^AFxXJyz7$&#?3HJt_fZ(?li#RCzp2Vtaf0bWu@} z!EUZZF9qzNmjh+H>|0O5#kQnpX;F6StiEf7xl|n76Tm(<0N0r_fF9c}`rei9Z)4-) z%sncKGA}aZdwr$*3$xRPMn>S~*lcVTRS~SpzB6!L!Fp7cTpoLBbmrxeXlQD(?XAAO zz3n&#jf&i>3`7&;y2<3piI#fvAj`-gtMC_!@(kYH-T8Md@uGK`8?99Zzxo_M2ygV* zh>Aab|Mo44tsZbVa%|{MjEo$f?~A#)aYAv{tKx5j#sT;snmP!&Z;f=K0Rh4(6}Nzn zhba_$^24lt_t6Ik_n_kgU8ra4Sy{-BqOsysrOB#fPtpK5(=k|P%}b0)!{&>+KvIZ` zK$ZixRQ89SXhRD`%+b>_} zflAsQxs`!rVN>SwFC!pL$d(H`5f4gdP$qh|t_SJ_c0Cn+yXQyta4Hhe?A~nHUGgJf z{BQQra+KT>c^}b#g3)Y>T*)|iLv<6sF)>KPrn`yx`G`n@Xu~;|CgSHh&s^u(*4BPB z$aV2G`2LsC3Y*z#ZD7JH=W-uXCf%#LSI2yF9$P-F053M_i&VCZ(~VZZzt0GSK+<*{ z4jk<~gLYgn$iu(xw_YcVGD$99pKu$F~3Irz}{rNZQKW z#jZj?BSfszVKTbv+6M#(hWBd`P2SP#Z2RGQj;*JSr#-C&lw7F-EYCXL(6weZD7xwX zlPSx|=x=&HD}aykY|-5CZav}y&nZf6kDbS9;|=2{(BJ}XEDg(=f{(@Yw)=`Idx{U( ze*dd?S>peLM z8GbUX3Wlr0awXV@LdeT@d$c}SGZK(lo>|%)b=cf~knJ2!$g_}|uEYlduD|D41vht< z1BZ6_YNDbA^FM!9=R?kd+m0$&FKhYr0E>*gsp(!t&h$hYpmzFm@`vf*LxFJ>3Idwr zp}Dkl+ne;*cxvKGjd0MiBC>k0MD}bkAIXXTXe~*{G``SzOQ~B%PAoD~ zfP`+8Rnpr}58pEZo}H{YN-^>;5}cYK-NI$6dGt2N=1hXRh8j^21)`o&oGs6- zx3&a6)xR2119g2}Xoge*ilH+X=%ScW!7pUyax9emT!(DDpJ*?HPz8co3p zO;Y65@c&p~h5ono?|vwyiVG9zSo&_F8whsC9Af6nr;x%tf$>2Y*|_uJ8mKN6Y9IK6 z)u}}1sR(r!s@srhqjZn?HPELa(XqF%8`Y>9cxer9R!I5oLXy%b{iiD##x9hUAHNbk zMvWZGG9kx0_Cj$c7*mK#E;!6Taa<4;-ZZ9<`?AR5bP zxlQ4&BJk}s=!#A)6&l_O+C9d)qw1C4r0L4xZ)yg#=T$T>h#P{LoD<`TkQd$`d2PTj zcsN~$2=AS~*3D^@wdYDTn&Mf{Ea3oBK=5bNP$;AAx;)@tGHY5wuZsYKBM@eCtFFQz z5E*Ci+_yF3mlJdgA={l@Pzn4zi#GiUPjYznD$il(GwQ@@287p<7DC@@r+wj|5Xy8M zOejZZ9?>gSW34h6Of(NE#Jz<>unvAmTX5gx7LTIV3kyPh{hk%Iur4!TDzq6#P{&J3 z8G2%cJV>W#?(i`!7gA(w>?h#mU4q!yf;C+0dbXGRFF&!>5Ep%> zHp>XQ&4%|o9_1Fy-!E@?vQ^!t6QIohnIBnM{Sy#MN z0S{?jjkqfOb4xgU%5$3PiIsNX5|5L{=SVAop~B!ztZ&E7TmUpf*jLe zzlepAk&1{4k+bvFGvJy0y9tO8q~9qlwkvP*8|clC37!HZUv_&YOao7LPlmZxCcYED zc>k`T`kYk%kQ%Z#MK@6tkov~wr^=uuT2%pEA-@18%#xtH-oyA*PQxxmIN+iCwtm<2 z-v0)!oUr4CtWhwSYb3Wu*bA+R(!YK=93^ewv_nsWWePFgamLzI3To}4^^jqi!NZO^ zGM>E7$ggL&k)3E=MvkgN5glGo;l~lZ&;D4!%6W3set~I>Cgi{$sQkaydY5v_26617xB4#z zRDF%}i=n?B5%XfS<2;A74eSBDPVv8@bAgx;jeV#(zu3U`Ht(MFTP9DlbOX<;CigJJ zF3uQEW4}WFjNPHZufslL+0#N_hJ|fWf2OS1U6zIME9b}Nh!2<$jQIXFlhe<7VY*gC zhp9dv`IiRM8R9a;vl%fh^m$Omv{VL7rAbAfaz?E}iOS2T7*hcqE3UR}-8rFqBj!QM-jG0S-V&YU$cP>KaIO`QpUF_bi4RXR2WycfFBKHeBWRgOyW;ak$!My zj;TQ#O`6RjFr~!%g+_-M22P;cm95?uT&9-YDt)EF7**)U8jGg7ocy3ZNRy^Sjl?f| zl698Az#Y{>!Q1QZOqUNWKRXmNiv&m?Q(EI)cC5sZ0Z0vyRAg@5gmz9^D zST^Y|s1~DpA%?{YHaeHS(m>N1!Vm8E@1lbbjq9bjZPe8m7G>iuhg@|ChSvy7Jav-> z7xnzE#|jZ9dpL)VD7qoVu-S{R0^1yC8$7l!s4v}kw#n&R0SnQGyVAXx%R8-D&RT-o zMAT2<&A4C@@~-BPN)r52mh)vAWz5?S@?{mKnEBpi+nwX;Cu`T`vz! zEJ8Cst+DrpJMq`Lcf?x{$tP8%)UFAuT5WN4v ztAw9DsU^DVcOvA0zQ@y}C1T{8ytI8AzTaEai}oz&TeV(pM=@O2RcBw*^lpu=bxt>V zCLf%2yC-xh^<}B6?zFnakUg3KP2|y$az*lsp{wpq{h~3#J!tWad>ByyccZ4!KrpsE z@7-b0>;F_%RRF#30Tu(o>%hK*{2p26V8;d>C{z~z+) z8ru|5ZZG{cKD`F7F)SJ{-}d&qfyZ_T5BlC#)y^_Xy%*T@bDoHAEimoF-OG}j*@db znbTP0SUjEv_K>1H$jUm6gaD;UQ5`aYIvs7r%xJuHHSE6D^R?w1^(O2t7*Bn3U!_UH z0vJTQIK{YU+C-Ni#>Hww4n`Bd-zQ&R)x)SmOb2=6Aj?GwQ5}yAdpzy}DNSC+0tHR{ zW(#3@Tv4V@9!TTxdVAgI-Y7(cg@xClX5Bg6UXk<>#nU|iegWHgICCXnhlvDm22JaL z2uhz&Jl$_bLCY4&tTQdlq7y5uc6}ROB7Hz5Q5~CDL5X)Mc=;NoKgK?a*4mVNvy8!? z7jpJ1gU0{G*IP!#(M9XJ!GpV7fMCJhEjU4f1b26Wd*h8mV7<&CWQVaBAKBU#{7Y8D*JDjb(;v;s7*IVjYqJmjyu&;|MVtVpQL z*(!D2$ugT6t4OhB>P;4H{Dy(d(VOpae&7u68v!Tza_beVYG@3Uz07dW5RuBXtJ%lf z2O#AkAQ>7PLvwI&NI`%3@`Wbs{4vAp{o@HS>Apw!DA5atHC?k-myDRk^<;q>r#~RG z{GsLKTJg%*3&4n1ZD#ZvKK$xq_Y={lLoRYwXJwu?j}Ys@2c}DrPe%KumPs{tsz_jV zWLSIjNKBkQH%bPdpUzTJ@RMq-5<&wXEn(Iq#ru1B3W<-859JRQR!~YTJ(}lnkV-n| zoIu5?zD=X`Jz`LBS(k!3@2_`a89f-P*db-{jQ{I2`szf;&bW$ysGkc6Z_7ECLM_0v zHL5$pOBS5qd;v8l+!H`N&>VBS*$Wv-YFZ(W$L2Uy*M)g~{U?^?*r|-7V0lc*mav6K z4a&h}RQPWK6y?QOx#+(ul21|nkRbu#zsyUaKrhh=b92PMdFTaRhgM%9=>*fNK1{>; zg(lzYl*VI3HX7SR{uxF=p*);xV@XBdZh|RhoGAJJ^U+O9hQ6rlC(s3^?1fxt5qhZD zb?MYiu!7qN&@utluh}4WAtfOHwO*MwnzhXOjpE5Rf&S;f+V(C~5YNkBfMxk~2UHb# zTXMAqMc8S#;=OpB>+3YC-qoiX#Pct=fCn%ABq5^^7*j)Vrhn`3aVZqYBA64iQ+K{g zcDlL9Z@v(+9X!&Qf>e%5Jgs!>bGQ++GjJR$0OIKyj1^LsenauO#EnDx9EvGn!VUyw z+?oS)V6907Xkn{LQF?Xgzzg!62Vc9Yk+Uro4caZ*HB1Tj*bXi+(48-GSl21VuTr|l zY(v<@*2R_wjRDOr)3nJQ;kS!_ zg)gWo2%YL)C=haen~Vq9q@UVGASMyFMtf$?5w|JE=f7u+ri72%j)58>%#%1;G%$8; z^rlk!;AxUtl4A0RFlm_uG^iMLKAr-Ow9m1}|CHlzq+r|MCq6c6VDc`m*pzq^^FfCEv9ox%8^R zVsp$5i!%#5MG&?u;gqmQU^{G6uLt^(J%_d4pP+K@w-t!$x^cOz;YjY)zwkQL%lA{G<{G3k+||4eI~jf~cI{kL*z| zLOCY9JAOJ)E^E@ zPBN#z!%2RCL*`KyVu&#Y1oQB}R)N zm0YSa>Z$S=tS6o`uAO;Iv)!gZAaIJ^DCaIfOi#wnC>YfY1}Iu0FIo8}_MtaPt7!F3 zQQCw|LwqM}yH>HOaq(4u9+@-mij9){+oZ=@tq!ItTh_c|iBbnqcb|)KL0d%z%DMf} zTqKsG@41Nf9npYf?JVc%4q}+U3*ZKWKlL5G#rKntN~T8wz9%$gypPyNt0F1>q(h(q z87DtsLAouLIBv^FEMi6yJ;?)=J%IKdWjG}ipOWY}cE(3ch&^&_on?yx z207;4S9IA~S>#bsQ672PlzsRT5x0YbGUg<~Se+FW_Ous^9z{#ow2D4PCMGj~cX#0x z6vh;R=2b+KIo!A{WXe7&pm!AU`A3h^^Yusrg#p$~WwNGCd$0Z>^{om^PQ1SL;W>1! z3~~h`IRV(-Q}Z>n|Ut40kZjmHp_<{#3~AFvJ8<)R}Z! zx<380pBn-^=uv^jY{GgUPEGvJ5th7orReyD;7-Pbc+VczY#RfGkp@^c&{4z@Hr}mR zl(IU+QjWPj+Ff<>z&va*(K+S;yM|Fx^p#_m<}Ws`!@CwQ|Giaz-)_>d&*IW^ubkVgnMLS;pB@CV5VxhTzvg_@pp zXeN)Y79=ZyJrvFQz8R`L`)CreEL2^Tbk^sW<0NYu$E0wAu}2|S zUUNC>U8V@d1L0}CV2|GAtE@D!%d>TrK6M<&Bv~HieZEjnP=oo;tTmX*OOtbE4eGPI zO`|8${RgfMiwDbb(WkNT4@c1D_3(+p_1%AN4RudYXwFWC+#3xsSNxNZ*wO>=hRu>l z*jWP8SIvrfxweXXTuVi%i(_Nn)kOp9MEn8fidO~-y7^Ie`b9&tZD5SHm z)=F{w77?1BV;v57B{1?p0FG1^2Dp+yL_W-D>j!mUu>ec zEz+oWYS{iD=Mee5Z)v&%XQ85nGxvPwH2>``^FIo1zMe)`}QUJLXN+%ak{iEd2P{ zhSyBm?}I;>8j(+?L3p>}K;P=N*9({XR_^%{_(P zL^*$cYaVll-qG(Tg-6<`R2FqrbmQS!jBWT0Aw=3*T%y%68pl-&Y#u`nKiunIf}L}O zcC8h++bzGq?8X{w@y*{$4`^{AGj>#__&)1wllRh|?*aCBS>Qq&vRXg)G4BoqlhJ-> zl14aUravt{mEAWDhExUov3%@faNWMT4#?ap*6+1{bOFP8hXdYm)bq=M)lBhE$CA-g z#1m^{3%)_6cE1SnA>+39 za9OI&bXjWd3*+{E{d1Tj=y8lT13Lvx{Z$g3a}`OaZY5H?PADS#ulg)Iq<$4yTaA=G zofldQ4o}DybY0xpo`-yV8B|oxdd}?Ak13M|h@p#%{oe19V8UjuBHeAFPDY3X=hqy0 zEKI|RXJL&OX2nP=`yoSpDs4sYtQiYyqkI2W3q2{Lg_L#uX~l02ifVleRPoVkZY|_E zGP-KS0QGEI?>pTJ%FzBpRk(2IlafHVL?4qbl#t!gXP*NF64Yey=M|MOiSa(giHxf7 z$}OlcoRfA$r54izTvo4$$wlmbU)|c*u{I-5EUoRDtGs~M`qE1c`j~s> zx@xm!CTffOx>}n;R$w2kH*Wa7@f%3o2VHjE^+1p1%aF9kfdt!?*6N}{ZxfBN+UW9r zbZ%iH5xfuE9UGu)^)?Bm1LV34+kxn4g*IYsA!38MuaIOh(tS5tz8vIap1BMA$9j9) zN>8nG=+(@VeWz1VX$jh4Zv7q7V$W@p?YS;)mjU-&jyBS<*Vwo^wln|-y5wQ;{3m)o zn#H!Pf_}-Pfd*s(uAbPR84*#7PFZPvCSDp8~vexqvt;D z85<>=rEQmJ5JOheGSPIk9P?6k=Ey@R0I&A)oQgJoLD2s|lo}J8eN08mWVZrfV#Fc|BhK#>I{lYXY_+xASK*(Zr zp+S0yE%M@IHz-oo5B!O)yww#3c-6-e)~ll&V$C?_$)Sms*^(Az)FcOT9zbBznb=Z#TXE7> z<#^%^@ z^+@|2h2Z4I#c~n&Pch;%<0!*ND!^%q01;Bx+jj; z9}Z?+Pc*C`zI~k56jCB&89l=Q0+6z;tu5UaM4r{CGLzx z;N|7Lg5CN1xBhLmL^WGFxV5QC*V)D8I2*xbabe-w5%qJ#g#e}G5MY!3(>N(PnWNHT zJUu5=PGkeAm-?b1TwJ~<5)y0-w9ooy<|)Lc<Qoa*KnJ9tMZI9MF@Od8wz zp2wvRSERe7W+3d7B@Nc9zrPmhnE?AxX0hLHGNA4#BLBR4$L~g<$4#!<%4hqHs&1gH z&@58SY?(hpjseuUOA9hi``SySRO6^5Tv|vK`R!^4XXM`PT64DsQD$AiPT6)i3nGPCR}F!z#;>69A-8s86- zcP+#t>>w4ZsF>EG$t8kV@MjZP`q&&xSFy4Sd_k>#Nwl(5PHgq)EWwclV{$(QR1wEy zxmv9>mgE|_fybvbmlO8V+LH%C2=Vp6=(+lM&Six`0t?i(Aj-9KdbfFH~L=tl1nPvSPh9!S1_M68J(P-otqsI%hPU@f)V` z)K^+8JIuODLcNYz#MyT!FrPk+9#JE1!YK`fj16|2r#DYgK9aSuryAk7B|jV|oxe+c zZH$A=M{RYFo*Ic#hm^dq7<7;{5LOxO>!r(hzCYP$BnAWlH#yDCgg1X5dzhM+@ni1v zN?Vb%+X5u0ujK$!KL2IjZ}-6ur$9SdacO%X0*}f?@%7WD=!D$s-0~mGn4=pF!h$t` zo7I?Rzcrq*EMMq%zCT5^(&9-vLF_A5SpZyTi-ln6+l8!Fok8PopcB|*4F|x|jPNwq z4nZ+BQcX>n#*QDEXU|W2gQ0|EAKV>k6X;IK@Vltc0XSfB?n|4nGxmSVuUDzc9N?%0 z-164aDV&Kb&htTOqPuJKTv;ap`;+A^)5lDZv|rx*q|JfQv47x_wObsrJQye3j^=-d zfVV)#Nn`o1f@LK()dVM(QvzGUf%ktpv8%_W5~^FS%Wb*%8(GDV4@5(xl~?ui>r?CM zuj*E}_ZQm@y`k+2=*@XWf2XSb_~n%h4lEvh0YBL=@5e!)so9ivab~7A-hLH*Jlt#f zP6`$Y4egWy|K^OBEMSUVLEMgANZr$-hKQcy0ZqQ?B<7z<&SWa@SK)>6W*ei?TJKHM*G^qFbPnWPEARtIlI-Dt+H>|9#5@sWy zld-A+DHS~_ek2b7l*Z3K{BByJlGOA1cVAL-m}2BqLMuH1DL$X$7Ay?V$UG<`NA2Y3 zN=i65zLp7<`%&qtClq~MMw)}PIwyt38(|{;j=&J75w#nz?RkY5@3|dv)y7j%I&~ALp>3GAB;Et zm{WOu#Y*akXs+PIz%+iOVe`Kbvo}w0849a-NiRCUF+_;+fF=U;W_5xQk%uBd+lZFw z1ebLirr%xv4Fj->Ls(8ll$4s6tc@)Heju}`2e$1@3tFlYFIKAQqJE1mcFCge<`7?- z)C+p@)V3^()z|IcfupG5l&$<(te)bPrzcI)&1fl;G!QReO7L)il}h2D zCb=bBFZ} z0~Zz-+4{1{KBAuGV=1#f{;M#l!ok5sCoyQehA@e%geN8@5|q$cii^Vl872a2Hg0b7 zPeC9JUENXL{{>&j>bZ0)G>N(x8yg3b3b=^^yo8F1icw0^$IO)|@ldoEk=r#G=3h28 zX%|q=6%?ItYMA7YcYu+q$c%om$Bry)!k#b!y^23mz)g{D4F)$8D^CRF2?#2bz z^`#NS;LYK$+TVT(46HkWQ=BukTGRK++UJ*S5U>_rU!F?g*mr<7$L2pmurAbe?*Vxl zG*fl%kL^myRAFEKABFt+1ZdF^R)pF&R7Z)W!xP#D|BbG`g=mGIo%9?U_LCavk*x$?Y1Gx?- z(u?m+WEnL1KHYl3!G+M!Fahn&amMUH?Ue-+`vUx-<1Yq|4<1r#R-P-xEqi$S0oyrd z-;wBpR_h0N-3nl(nMH#8LY`O=>A=4iDfiQdLU)G*NiN%*TM-~n(Ze;5h1_9O!?ZPC z{Sr;!Bxi$e8-$JKjJR>U{*ttJ1NHu^avOt`T|Q`rtfZ5fy&0wZ>1$WJt{wWfIAH<0 z8Zd$A?=mlm;0kz1uH@*sDtfqyama08Y3tY0fUu8Bwgn8eDgD&qDf71G8wchO1mlYzWm2Y`L zYw3CUFZHXRcGrGnD>#qzM0r~n;2khMYt~!9{t&wga%v)Zdk;rluW8{{N(S@|od zlWKAsb6P5J9T&|8{WK%TLg8=}j$DKhT$q|se#^fPW0_YS{?3<^IKwMkgwlLx^R;Kq zffM^{owz<Ng6~VpJy{Fl-jf7fq=k@=?Shr8km66n_mNbRsWp6>2!*HMliT@YKvLXBHOMMj*i- zOJ<6qX#Dxl<)I%!`BW3aw)3&?OybH6*<>)~7t+1Ko!J)xm2Lr99L!?I7KiE2c0QGFG_F@>>+1I~LOzS#1nibKcexM1L?3abKN>W!f>HEu3M@Np zjZmyQywQ!_o&zg7jvHIhby;LyF0f7g)z5`s(jWghEv zU5WuEOw zf(?YMt}~S7Ddt6RXLkkDE-?e!RW6%FV8DvrskT;<+zc7;Sg+FerKS4TrreM@is5o& z<~{NpM(S16M{f2u=CgM%VdWb12hr{p}SA?W+ zSlph^j;8Y=YcKI*?3ZkER0Va`Jg@8|Czcxs!B-fmEO8G;$o`a(uly48=FFkWP>+UnhfBigb+Ib^G5#W z@M`49oD6d~14c0t)#s7hAXA5KoDBVr1bV-m?OoO4gI~CZlzo^6FPhF{HFiKMKzGE;r!*2<7678%|-BxT+Ae z7wof0$+2@q1YvpdjFuoWbN}OiHgfvuGht1m=ipwfNE!u27=;ai_-A=AW87p$FWASE zAf7RSJ71Y% zV<+I~>8*|iA)xP`thU}&o9=!anBl zpXSEtu~vBngUGHqGls?0*aI=71>cS7;lK94%6rI5xk6X7I9tJk16%0>kl}n=o0~U> zlNhqevk95y+>W-lgMjtk5vuL-@{;p!5H5qdsXO$^QhlV3jM#(aK~iA{-DKM3Z2!Q3 za~F=3ysB^=$_@~D>#A`|$^vB7n?<|NouVJ=(0h}93M?EXqS3da*qYWvU(^ir(a9l= zj#0$z<`<-=li=?NdS32Wi00?k)^gyJGEay$@SA_`=R;oBtEmcUUpLPhRR{+_zm8Dr zoa+sqSLXk4!`;D%6aJRaG3w<&c};vcGk|0wpiKwOt!39R)R~)Gz|`sDxKyKZH$oO_ z1GrcH4uC;mwO?tn5Y=h4{|migVrx2Pk=+AjKgT##X)KIJmwW$@I<89_E{-&ld=f7}R#=b{_HULm4U{vB;l(3SL!QrLB z+2fx=-rTXfWC!y_@+pBpq0AWgptJ!>bob}ir!&$Zc+|s0;3dby%DtERY>Q?5)QY{_ zFEo;ES{o1#ap89^dJJ42 z5S|l1eE4HJdS<-Z6~7{k1%6(yrVwW#6YoulKEJxz??k2FPVD_@h>*NY+pSdo#+`p; z^)$XBZ1q}dnfsKEjcON-%9`h91oxnDE{NCzJ^W4q}yL+p=#MpnmDT`39 z@BE}&|1*LqZ4N0*IGxXgi20||8AoI6VGD&|&P*s`j4IB@X5Wt}^hSekJbAVc*e2CI zb_DWF^7^)k?SIU8U05mxh(ZmjJr+Mt5vpA5d_2A-LDss9g9r=b5J8o0U|XP?tyBLr zdq6bBbqniA##&+9W+t#V&$UT5pWD|FI~evZpn7@%aWZvMn5vr44(ERKiNpK=YZzbkmIOHQ}91Fv&7o#^#h=LAy#C?kRvNvsRG%n(n{Leme=Lb_zUqM)e(VG{U;hey0 zlRTjKmt#l_raN1?F2x;(uhh*<5vu3tHv8N$+d*|9_%Ns@S6RqSPgT5)8bUGDm0vT1 zg!d>p>~i~@nhJ-E_r1doI`0UU{bN0JiIV87v?cT90~goq&Q1)?2cThEApqDMw%kzo{2HPVZ3IG6QlD^BuMEgA9fPH96zb%qO z4**JZ^wG~t>5ejhfu3GDuxmv>03dH|?C%c>DeN;B<%b6Z1dwoibtokNU;(`vIcjWm zfE%X5i`8s(zhj)QB~0rrq{8=Z%M!4yi7_s@cj350l7Llm5$NV67fD$eP%^(`>t@gL zW}WOMvHIfjC5~~msYUvGK?ocr6&2eG9ll5^dv*^x>$40LKD;>R7YQjwS=jk#<1CS4 zO8Vqo#V1V^j*&jr5nY+Z;DFV9U9%bID9hjoKCkQjwSZ!+60?0HnJ5`Sg(#WL&%H;- z4-+p6vnzHkFVDZ3t8x;fIm|~lx&vtxQhRZY?$0+3gQd&D#Dd@hqRV8N7Zs_%hkPI3N68-6yu^wfUsFD;613M z0|)p`1||WQJ<=NAEzLRy?ZCOL4l!&24c@O8!<_vRE+nBhyD>rbsRSN8LKvQEC|*%zgvBY%l%L!j%p5yx0$iu z_5K+M!`wFn0udip#rMGh_3U5r9}<)%YdnywVWE^G&l@T|)yd1~eBLP%$RM|dr-{50 zD3F7~cHyv}-YvBp%KARv5-;tIpTJ8j)kTrV7NQG_ZnvK0dY&$<1@LpTNIz9}=K7AO zkMrkfK#M7$dK45`8Z#}PXT4>6&e5qMLR(XPn5(lh0SDpZ-$_K)u-CEL+ndv{2AmUU zN~_@zbw1)Ka7ev}H=g+6bVzPzvzKQ#?&4Am$1;@la`_Ab*jafMjP~0T`Nqq=7o&v&=C%15#Hr2IY18ft5Q^7J3ra8)Z)b) zyXw#L9M`N6PBo8`n7Q7}4LC=iBl}L5DPS2ERy3J(!*H+tziJ{V(Om*Tufd5mpo=Zp*3AGt(q)VU_1b zG6jVAaf45JXDCp1$_sX37bS|w;>oPuEvt9^PBm#&UQSR z;=o+++)n(C9+gwX9{J*K-8+U* zb?AOSUW`JuA%!hc?>g)?8~xczaP^}M+!7+7xb6d68HS}8xjj$50dajtGoc%HaHSzO zLqPyD--0nYpCJm+xO+C(W-gYy)|&%ZP$T@FeCgm7HDlJnO8u2RG>(_cU1BSDI89ea zXFcaLgCVN{Em0Q8gC7bm;JvfvmhU*-d)Exk>Ted3u~Q^wWaa0OA71f?m>Bs!qC9kV zLu$Cu7VN0{B%>TSGb5*LeHggK4?P8tV+fL;reqnxD~7DKjVLW+#%%eTnA^T=`5%pS zoq#*7UkXJzn)T-NudJpMRTh>vtV`tN$O#Bkr~)KkFh{4?qpTYvJ^dm4hbGE_kiz#~ zkB!m!$Ub8kqyjwppbA!SqC`~ZF~Y;UL3G(K#&&jgJZ>PdWv#eLPNC-1p`HOgze?TT zeUbP8TeRzh#qDsG-owM=``+~0*SoXzBCF?Xi*m;+nnnwCKuwyZqM;#ux`)68z?~wO zhKGMmj*iNAV2AlcUc=eBN}i%Dokj@f*`);q1vT4M4u&f1O`ci+0LXMOQ0L+BN=!@N z+{x?&xCE9?MUM{;(KHxOQJ|0OK;H%n#5(9z3{4$g%5h{2pWhEPjrQK{*i6j|JT??`|Q$-D(Q#Ty13{JBOIL?oR1 z6BRk)LnV;aZB}Rj^ueAivxMKieKT0^^b={$gi{jF;&t4@FKnQC_%ryW2mRZJN>nQ` zGRDiDswVd%|3~tfu33 zI-5_k?@b1mg*j%2XX-=FRA=zT%?CW+1DKw}wvx61VXk(z9a#kGfTJ3YV{?kl^U)ki z*ERS?;=A$hz54X;yG@yOO%rhX8^G~LtB-9jfZ;I!DW;+d7k z?T*1bTj0ma!>G`rjBt-U+ZWPK@yQn3YU#yzS74w0JhBX#XCaZ)4@MgIXuVwrUyFDn zxd(FN0FB7`{tEgp4HUJxwyotOicuXOI#3U6ZNg@2OIylEVuYv=l3<=BvqDF&buMF3 zvLrJD=gf4h>?&|Q$u93Pll14!5Ofre!s^MM8YVqukX3tLj+3{aw3A8AxOKnm3z}xP z^6Ojbaj%1;_}QzqYnXMqA@Rx$nt8U86D2Dx$M|GsXP4=-&CEKC;C$CbZ^41j#$2q!G-XFLP8=k5KoX)C?Iw8fEPIm$A&kx6!*K zwvWDgkJi3oag+)7!(QD@y6WAE*57Fhs}i4Af;_F^k6vms=gi(JE)7^A^H09>wYiBx zddV+KUla{zDN0zBkCmZz~12Aik{-#ABQCe>63G847#gm9!Yz5UnbI;5bnbzurTac%HK zcM31+N>fkNWN_a1<`S5*<$(`pt?zoGL@+Zb%6rs*?=Mj6eW8vqn)<<0a zoX4Stuf--Bo@>SZ;rnv=YVO~?J!|l1T?8Lq>3^w>DU=ybx9C|(iv*2i=N_hp+>eVXx$H|{?KvpCp~}F zA>Vn}``u!wFj#MpY9Tmr!%a*nyUsiM_(Bb)a^VvVt_<$G#B^OXxYkK5v>lYEdV#-! zUmfoyufj(M#(buW$?#{0F%uX4^Sd)8w?7HAWFykY25d=v==>qe1yNm!x(*!+qqhxm zP=RUFT<0e>2$g~VR9w@%>tLqv__N;54HxniT4Dt*@M_7CEf3Bjf!L8h2a|UD@H4b{cneF?s=7CKL(@5qst#RFbmkvlUK#-W76Y^ z>uX&F0i=c6b)OGEP-Xit>5X-Nq7v3!GE7nRKh;o}q@!RmTru=U5S)#HUE&SMNqP6i zLRlPpn}R9cC{eU-Kjbef>T~~is)!te;NDH#g%P0FYA(^>iKi|deN#8zzYQZ$a!c9{ zABC`iIJnjF5yJ>XC=fhnRKHQO<&U$~%86laH`{-SOH5}Z5~mr+!f#5@i0Ogu?WK)0 z7nhPY_`Lfqi41d_@Ae7pB;4VD4w@DOk?&e_i1C*BQ)_!xgkMdNBtJh{n1mQc6dpD z6zt;UCIyte8O!Z9oLh7Kxbv68u~*g*c8+M3+B)I@Xx&`6g?PM9rtUpXpWLz`08w$Y zw{%soE8{|v#~cEG^t02|B_SdvR@T*x0&;cZR{DB+V|M&gOkaEqxbs_!@b{EyX<7J! ztws(BNytduuq03C3FnJOvU5fGrCEv zZETu1B7%cq0VQ`%Sy|Mwg9#w-!3dY)r^G{)gbLp%L`Cr*o8rzaA`(` z`+4WfrCBWZ3ncRPMeAy2I^|KD{B}9{C2u!P!7m}~Lgeq)8|ILjd8%W+i}y$arR4z3;}?e)S#fTYE@<>!Hd;VqiRrK>v9341uXaV+`%5|Z;~vY=biuf!^wcR$IdMN)UW_P`-X3DTum$d0pa|5w|F)`IkJG$ z`Z#qOi3GiMeA-x{mXFVjQ^!f=Crx85)Z5UdBzqV(Id3ynL)t2_j_vu4f`=g%qOJ*r zj@suW$6d8T@M~-~KAco|X)(A)q%fMUO&BAiNawGR?@j$)U2KoMfPJ7LseRD8``aao zj71?E0D%*CF5~8uvJ~|VBN8Sdk4EojC3H)G@o+HYU3;NM5n-C@a=${~JX-v9Z~O@5 z!)@025j*u?nDC%sHfSZ+u&`GZ9(lWH%1#{Gmegw@qeUzo060X@Fm-ZUDX8JnqJ}yrDPm+-soT!r%Q>C!(Jiea& zEo-AKDe)e~^BTg2b*tbpo-73WsTG73OY!ofkGv$w}v<%iN?AEsLA2>z?J)4PbtMH&8veI zXU7(~toh4}2_EUcX54Q%fQs9`8y@aKDo~fJW+tZCZqVce&${wcu|8>49QmZ1h%3ht zOs{MP1Ld?IFSaCz3oJ`?-oM?5^9?X}MlxaYkbmVy*VLk#!9LcQFyVFI73S>&(R|0T z=!+JC@I&3dX#QliHp^4)Eli|81II6sX$V9E>^9m^4?Nijl6}8H$lErzLCX-i3Qw7~ zT-agI58|e!+;#4qiv;G3#fkU{rqH7PnB|5?P^~uE>X6Pg-Hy@=a2F$XTJ!J{NYnW`+6&ixba^Lr7VnE1ztrIiIwO zhb%``9_t;5*(XiWB!)odlmZ23il6>nnamK~)7zV}8&zJSl|Z|pq3v&KI=*7FK%oKq z?ISZDBSYgZUvpz~Xk>H-M!_Xy@rFUW(4$vhK=;?5CmjpP%9`jSwIb9sUMBlux@YQ~ zr5uCBZ*e-V6-dZ#`=C-x&g$0Hev%k&vVX!5yJqbQVZ?mFTDOfKDg0<(&2 zLsBoLtc>$(a9lW_Ig=(u)0gMxtBFd*6n3-y=Z7m~fd8OhnVmh^n{NhS-BskxtM2Nr z34NvaCY#?FqIgxPiHMJ{G+yaNRXOv_evpib{JFXMRev=06X#pGR&u|D9PeZRT@)8H z5nEqfwn?fa6h5nRt)-ReN&Me(d3y~Oow$koXj!&|HEC$7B!?}Fj4chnd1h<{bilAj>omR z?(Dk)ukd_L{c#4eJweR(Aocj0_2oQv{;I{dnp4TOV?gZ*P9J-F&of%-=LugS zcGXD&%lOT^M-wGhZTPl^8oMr=taFjHGhX{w-2ungUH)kL)Dyuuhq;TX9FA3~KT0BO z#vFH(9#1b5z|}1J;xd!J@F%_9aVBiK&B%w&%X1O$vi&jEw8+dWQSXtbA%DsHH4oy{ z+(hc9e|ueAfC(ZQAR*8l)o1Ac^~`+t>}gVu(9WiQb{9AW9~6TKACKPqy?OlyO2U)b zEz6gIG2=?zv)A+aW`m1~hmE3xm8Z>!PM_DK$MwHbCvWu@QiWmyEJlzONtDFat{p-6 z;dB!$|8*I+`)!T*6OhthM$qc+NVsVjLn#sNYSXvNMYN@A2hdYUC@Qm5keEJSz}t8L)#nX9%u8cr1FG zDYfVJrSz@=5&*!svn(?JJ$m*2oXm9fLLSiu<+8EN*8|8+|Hb(W9L>sFs6j=W$V}4bW16 z79rkIx*k3TZt7h%zvMfq^LiU7icUH_c>DaUoHY#GQt#T3OER5b=`RI$jEgRi6}`sn zu{K6_sri+3D1fnwylo;cK*7;Km_`4cwsOyIF#J=e#>)3pH;vXa$pD#l)v*D-rv0q%|+lXTu`%T@5NEyvUi>uvPx;=)?V zLO*Dagac`PpJVNhYAm#Tr-a>(XRG)Sh zfpH5q4_c1@-)a{hQ1E^m92p^J<>V~e$@Q&6pDV9QORFDrwf>bl_j>?X^!5a76!|k4 zAQTC2SL4aZ_{^N%!b{TPZ(m>ZSB1V2Y8|ZR`tIunpzr}j<-Vu8v&zDS)V~6FjZA>8 z$DL2zL|_PVmD|aZD0H4Ppc@M7s{uo{5vM`AVHx25T$|kgOE@= z4KSDKWp*BW4ZCZ))JU>H2DhE|^3{~^^t%H0_FB%7t5 z=esXp!ok3(T}SuD5ItGq>Dg1d=UGzjrgj(ak3ve$^=Hu=j@=a-_d4m5rXlwybavm{ zBOs{Sn~%v*`^I6c`^NPvgZJb+a4VVr6&maNZ70&)s)%lER=!Q(T+6>S9DbXEPLK4(wS zH6u$>nLcOXmMfS`6Q5ne)!8o1PPMtM?pu7gP%SL!Q&&M>uu3hm~MjDWZ z%ls6RD6nq6Nfwi%;~SC5mT~>V|3@_Oa_W4Uf}M6pO}67y{KAZi7un3Wyfa1hX1)+_ z&S-)?O(E0S2Sw{Okh<0W97mrxcNUKBVwtdh;}VFG7c@1ubSTRqr&VBHBWG7hBv_Mk zIG=MCp;lccES%xC?{35(JY(8uBp4)Fu{r*>1{zxdUK@ z@@CKf^_M6}h}*{IVM_Q44Q&copM1F${{kLEm?0F61mm{&L?={8;t@FiJ(8SI9UI~k z$mIS{aXLAQ!bIIS54&SOqxIR6oCX0{AO#Zq4rKl%eJB0}p6o75orfV(Phs5YsW-sWeG=DBqsJE}KXLA{H7eIcv2wS) zD;ZW(SOY$9vIDKh-5;VT&I}$L?aj0&EVKR(TVE9xSFm&&+#$GIAV7kF$~CuCA_HYZbvmIVmxOgbOEv^3zW# zoEyC31PAwBDhuH4FcrH3D*4itV>2m4SNf7c_efmPsZ%N$NLlMWXu9WzuXl-toG(0^u6(Jd^b7Yv`S;!Lk{c*( zePXB<^>f=zcB2XbkI@Mu?J&66u{)|!dJ|C0^8DtxW@Z@`jO=H{afHy zybv(C4wmgksW(4=^~gQQ;-4QAC{YZGf3av8iuHMQ*pDtu_fAg8yox4Ljdj85vf?Cb! z`zP0z0FE(1Dfh2%f$u(5A2}Gk1h{&w^qTcEFx1QZaV}5yi>rSGQs&FE>PET}EzT3W z+Cb&*-k+b6fl_c(s04Tqp92dGb2KhQ^+2UUyjQk@fA3{U!@EQfS@ZFKY)%PiW8?lGYP7qYQDKcwZ5jp4w# z-csiX=7$Bt)RL#9Z+U4+kn*RA63mO^NXn%}Q)c_{qzj#&AAANkXWCY8UKnwD-bq?V z8a{Rg(t9L3l+(c`pXy0|wS3o#-BvZ}6p)!W*Otk@f{gN;cUNH_w}(N?cws*Z8YY9S#*S7Ib%fT8lib7c;^1T)H3Y0ct zG{TC%rVqi_ zb|*~51+sZ>FYZ~Xp>>f~bOCHZ)`$7Tg7TRC?w>I`b^0>Jy&I*bXA$M0SX*bZE#j!n zP^68N$vA56Xf0b9z|}sksU9QCP0{$ql2@LMi2d8t#F5O<5XLvIb|SAf@;~d3#woDN z-9^XA@y$>lU~MgV^>Gk;-Ca@&$$C>sgi{bwjaoa4wusAW)obr91e{8dAKJ*pW}67u z(0i+zH3KP$eM(!PY>_l|eGVsVZ+Bt;&>Ybfl9B1ND%uyQkL#_xXp^7aC(cM8RMWo) z;!B-{RFd-+T5qsB!fstc%yqeQW@z!>lcMm8U90f*+8nhHd1?60w0hKfPL<5yqM_hn zWO-1q%{(sq9Jw}y{Rq7S)zkOcJ@DW9=BnQ0F*>I;`4wJMr`EyfbXdeKd~5XB>TBj> zM4PVE4O<+TLQtA_Vf=D)rE4Rs9UNlC%fh1@cqf;8Yn9}3Giax(;@jbp9B4c=Th4eL z3SY!`91)p7t6b}VWF-|vDByV5tHyZ)ZNtLo&sF*>x^LjtaW<}btT4?b`_}fy+8rjn zoNjqO<3}IG&D;vU!HgpnP8XVwexz*fXZP&IaxqQg5YKQ*Qff+L28P|Z+z&$$N;TnVI7K=|QZ=86 zBG6I(?a3(TdfK(sNp-fDU=Q!t@`v)rjP#ND)Ub5q!1tyEQbzxOT@~A420sZYUVaB z&tEtCGZIQYmhTT5RQ7pggV@)^Jp?)VvdR^qull3w7}WosqzdE0nsO zvJ+kemK*B51b5(#P9k9w)5VD zU3DC)&3kU;%T_#dWVb!Q@d~w`D~Bw@R)anPca+%;l;m3JRNc-*J);!Q=xFtuus@^VN@9w zi|{5Hjauo&)%OoO^(346^}_faWU32JJbJjZ-ze^4?L9&CUveC^CdpG=3U9XbPJ zvM{$$s-1tR<^4G__YURIs>cddy5aNYaeY^)m^wMmZscv1|0n#s0(GCmS)wT~3KgM1 z$c?NJWz?4jP!!v@hmp2P;qEvps+Mi(SV95@oK1S2jPMu~fu4Xv(~$c3=?`zVz>`qY z0JES-$s@vJLWGvja_B?(j$u*6(k&09D=&SJvV24SW0u@)Im*yGs|431ZZj*js!QWk z?-{hc^J1t2&gyisI)Ub>8iM^2_v~{Q8tx%O>>Gmqgik!VH%XXqG7!R5<;=n*<>c0m zMBU^++Y1-9UbOHQvxOFF0+ERokr1LaSB^pg^Uq{m{CSA3&xAY&=>gbtDC?Qdb$`|B-ZKn(iPbiu#JTC*vO+T6 zUe2@DB!oGzSO%|s0M2RkNUGu~b&Yk)+>eX%@4F?wmJZEYh~$t%XEk+=t)(v&Kc@4KchxCRO@t)BcobP3ZfZL-OqS?W zk1^pnGwDvjSX7_?KqgGq+-rQF+gR}hwg(+rKTmQQp z8y{@1@^{sTG6YxI=l}Z2YSv1IHz6e2377BcVH}kw3?daIyc%fd5~b4&Y^EML_!X9vCy2y)rj! zhEkt~Eo( z4vTrPZ@jzH^KQFYUp*Zl1L!9Nh?FnBbDpZqU|#Z@_{Fl^S|(x>I*e8&UNTr<*M78w zEbcA{;lt?zQ69Gche^_VVS3XGYQGc;lzHv7xWP@J!;itSTkpt)=Nyj8* zGY~A>M8;YrNq_>fKMxHi_KFl5!~?=GMeMkfR_dG4HE1Tyr!MY}OAW1(I<9@+1qbyw z_k(s?wqVdW3fKtW?b;N(Y@x$Mt6Dx7DX})n`eaI!3N#jn>qVHV|V3!}xOu2RE2*4=3SH!2y z2N(*>0nGnFtbkM?WRP zN709D-0WgBf_Y}85sEeq9iUOn(Ck0GbGdD6SwzozVd_kH^;pEfl8N^K<7bDVD*C~8 z{4q#je;awk%E~D&=1VzAJ|nW$lkp%w2F5wON#DHzzY4|)#>9bC1(&H7`y-!h|87SO zx99mZvu&#pIvoi+fWDXW7L+RyKj;3{3qz^4N%)%i$AVl)oJq4K|BLjgY+dYR++hlr zFG;h0OT2LpuTl0Bg?BuUt(); z=Cqxe-Nd%Xg_@52giw2XJCFCRgF@_U`^_ya4M)pOPLkvkLf45;wSTkd0^H0wJrs~8gAK!AJlwbdPS(NjwK%UoZv>aX?V zW3)c_w+pJ`*Wd0gOqr^&0_aLfwpp7y0rmkbt=hqes=Wtl2yyN#! z2V%pP0qZ9HIoe?lLYDGt&+z8waY_+;iR_U(cxQCTAgu^3ftnGlKOcFnO{F7Ugi6Q= zq4R3LE~8mlLIAiDD19Zd{)r3sJ5NNWO5CZ+yf0wXC_xTr8iQ#sxu&(=$c|vXM?WMJ}w9MTRD)V7Dr9z7!&Qf*wo?<-PDZ8&X~9-Ub)ALXQuW@P|=xCz(-tD=Q_9byC9)b(2rj6hAq0}B&l9E z7%xw&H1!Iig+^x&sT~z|HEr_UKL_l!om=NT#pc~tgFcaToUCH0abz%ejQNkH*>Ddv z#CQzxK4oQ-%4W7PVS2RVb+)ALmwiFp)*NYE4E=&;>_S!5eL+8ni3q|S^j(jx$03fr zf^^*DQpM%(X-yZ2+;fV80q(t?vs$7>`_T|SlbTv=R*{aNi5gEmYUy-j%5<+QXkmqV4C^Zuf{Jt{S}4=<;FDi<4JAx29e*zqcF-h*TY(UGo@ zqBMSdNpf!hohVE6R-|`4m+tAwEm1K&wCrXzXr60Z5ORoHYnHn`r+>cQPk!#u1xww2 zi4Mf*Pg`Gv$P`k$pq7dG@!X_iB&K!jMQuXmy>3<*CMiyi8+iTG<-1-kvj?G=*D&$% z8yIP5XpVMA(hZO1X=ZzY&E4^yhNit+GxeWT+Ja;m_ApnnQpS{ai&tQ7v_RN|XE zkt;W#Iz8gvY`G4{Q}7|STzuwp`YFn<^a6BL)e=7`b^nc?E*~PXv?uoW=6&*)NoEyXw}RG721yp@$oz? zCA1nEa~9Il{i%TU{5nzOd#g3^nlo(z0{vd}>ScSplV&BvlRfWsMJmh0Cl`(E;$wvJ zkrdLN^2c0HmOr@bYwPRlE7;rH>jAJD1hJ7}J~|C^SQ(b5Z zGqcO*bWb(~wVK%?ZVrxZm7ULRKpF7#ex{0Fr$u&vh>k^`qHc~lp#Lx$85v1h_V^x{ zqiohHtb3P9i^JLS_lI+pFHtj}1~z-Y^8?G{@ABWLK7ZeYTlbT2a$+uCt1i9qOW5Ic z;bqdGLM3K8rLAImM;!-5M{)sTy_oF%V$l{@8&)Rig z!T|PgL9&k(Yy}^1s~#KiDb+1QZ3a?q*UjJ1oblSxyu?AkYlp>OL)ip2>)K7jhpQF8gMlmq2%&#H&r%b>~dweDX-F`yFVh z#EsgePBR-#^^Lv@x`2v#{IC1p@-I8}x*DW?nP2>eV{A8v#ighQrB&8T#HCkeeBX_U z7fRhhnh#j!9r++1Z8+cZVOUz^Xpo;Y){T7$vqPW_LCg$`s><})3t`*4umx)#R^PnT zp*F|$b!&H_g}MgsqwOQk5l&ykn~(osDKJS~8KTn}u>RO^a26uH;7Hr&R>6n!ozik< z!)}cAxaNdvv4MY2V0(NqRggY@@56tv52!eWQT%tpGH z^g`W%L;H1d$_Im)jo1?V$&zlr>mgNknU^1I+Ag=5i>3Rh+d$aEs(p$?S*jFW_%rd@ z;wKy7-v!>6#!i!SH|ba%cJ@&(SZEC$HWeM$l14sP_@8>9t>o^TE6RIdYz*M1``>VO zT6i4=EP}@_d!XMjjwd3ig}gCs|07Q8td=3>GXHDS_F0Gg;XPkTWq`&34B1oxqduB# z$Uza}vxGoS^B(iKwoO!MV{uUnFBa#Vub6R{RH7~>b`i}5dmX!iwv%h#dl$kqBiejQ zUqLe6$0E0!-JZ%d%gC1l->qZjMPfUjfcv7cbZaUhX{Rir(!UW!D8!KmL&7=lt?|iV z9~<0q`Wl%Pv`@8RMncL0Yc=V6^RLed)ud4+KJB`4&@xIGU%^83(0he^-c&zB=}nQs zgSr5IQc)|ko-Kg}xeIrHK9@U7$*9jzola<10{IoXno|N4Cv|`ZDU#ldOI_{r)H4|K zeVLH4$GFm;j?0@b=!38- zqnEe-GeacPu;`-ir#5AkI-U!DB{x==oJnVOw~R&JpLO+{A6zmn^j26fvPf9B^I1)~ z=AI457Rkm*ed-iSM0g&JQeiy%$Q-2M8fj@Cl2%X;uJipXPpe$L=J(^{CKvmck#WZ{ z*lRbO^Rqq@6P|Ybc)J%p@5O329Y>NidZyTnu|JU9Vgu%b$=P+$ah`&dw(@BtHHZ7| z(~DLij`po*U+<*D2S!50)Baxz9p)KEm#c1>e;ZqGR!GC#qHAN?u(R#16+cDZEuBXc z+7tH^w?AdR-U|S@xo|Qiv;HEi>Cz7+wml;G@=P~}@K7KE>1I?Xq7Q+eQ5uct1?ec5 z0cr+H%h!ZT452s!$&AS2iVK%N|DZN+x%td8;fWvYd8<)@liN&R`VEcP3j!DWSrc6S zW)*u=dpP0*&s3uR*IPE_camR}jwAf;2e^!8j>^E*ockH87@<$#bZB>F@gg)q6P2)i z($Ms(Q4SuuO(2p)ey z{Q_0P0Dko*_36j%>Iu?S2h*474UG3aEKLY# zb(_?S2c+YmHe^PPRdgF+f%T^o3OK&X4iD+;5U4+~V4`S{)shxR) zZ)KKXBuFK^rd6g-@9d4QFQB^lzpc8vcPjm6NYhQikd)|zj&qQvW7_-}??C!Pe%u?K z&H?sa-5Vt{n6GYmQ ztid`uxN6f@Lo~k`iEZ^(papwxq$(6O)0@ndRYxrVjUP3&an%I5szesu81ex-qZHw2 z9wf&27F1)Zwi$jw>M7%EyZ*zxe0OEH`F$M>ll%i3Z9tn1gYh~nPi-i&6HH`E9qA4f zk-S2xron)v^L*$#zXPEj41#h9s!XNJg&#-S5<}&0(Jb9o(P+!x_$*(b9y$DBU2+1S zqHPuaII5o$$!f?$SoUT$fHP{`;87VM+0BovsHo{1X8lAmgbqeQ2lVna7&XuC zb)-MN$SHl@DJn2n>J>?<9Z8!E|LIoInsx*PO9RcdixGok+e(&ghv%5+pNwSNE5 z$iau3{ET^jw)mz)@Eqpog)$NDnUlf;oDB1>J`@cRCF4%cqVFE6v-ko2>oqs=+d5{0 zKWGsnx4#4)qJxAC9OGqCu&*fRQXc2=$M4v=PjVDQ76U8#f6j|R51C#xQ-B&$>fFxU zi|n>HzA<88Si3js_ja$yks%LyfEkZP^!5|TRfI9c4f5fjeAp;5M&0(m#_9Sf^tmy zPHaH&p!k=Wwhx9I}8E-I-+ZTd@314Eyv4U zI=yxg&_$e^Fs977EW98C{&(Gm^X66>7i$#jFOJ1RA0zpQwNK75iQV{?Y0TBr_8*um z&R2H!y@@V%;}aQkpZBU#+e*%gj4;=B;-3(QyZ+?P+uQe@1xo#w1sY!VE=??S+m~4t9 zZaxn7#5apFJBAK$)o2DoX@wOocjzt6d$xr#qbU`n4Qw6s9r|)#R@7cP2Se#nfIhma znED)EM>fwMnz}H~4O!__2v=C{3NbU4Q&C{#iWI;FBnq|Ns<>QUhka3)JJsO&=Jy@h zx%zkUwI}aXFw;jviVaJQEeQWwSz-;M-O_NdUN)BgjB3+ZPxwIt{rG|-{P^T-X8?!> z;cH%rR$BlrA*Z*c`@6E$KL==Kt3^}yE^v!>-?+{_jr8`fXCdf{T&eojRBzRV4J6@9 zxvM;3O1W9eo5r-hA?=M`_NIe-!nF6S#8_vfi7iDbekw7WUBeeLYPNmzLxJ@~-t}dS zgF!O-+<$&f7vaCMurfFk+AeSfvIkD%tIPhE z;It3MNF;4=xCBj_T^jmrqyVULp@YOf9^m2!v*1_fLjG^A{v`;wexZzryP5(BhIX6% z8vzrI&`163uzwgOeYwzK9@FR|Mi@-Ct!za77c?y0s~&T33)F9!FR53{0^8(OD?I)B z0>qBjZh5A{*nObHVTJ7@b06029}6#@)asDhRRT80k-vOTqrQ;Gb1ZXVCs!fJ#{{K} zjF=c6j|=yJurTc971E6ZtNtE%CMM~Pb%TY$_6By=2~TMXncyYn@8Y`B!C8Vn1-(m4 zxPQkUC>V}Diirok#li|-Umt4pyna{ll{bt^8r9Gs2a-tvx|ZjQ&olqCHbztsk)AI2 z3(0b0+hjy9c4Igd8xd6i0p%0b-a*MT9pavp;-owd-mtXQ0Ub3>jD*;u12wIZ#Af+^ z;{hArVdHfY<8D%+0zUIy=W-XKw)O)obZ)gM+_j5!N|{Mb)PNDq<-%XKoYUwibRS#a zBblcrCn1&wj?mE1&-Nk@ahZb1*Vn&N+}Y2?%=%(2%GL&<_76*aZ4KY#?$_cE3<%@}|GD3x>C?^L*>-*cdT<-#w3mNCkI}U>O}s z>aZyr%5}YJs=SHFAuok`Vr4yQ-Jy?nTTXsujL(DX6@0-Tj=K=tfrJSD1Z+52TrB|**D z7>$64EbuqPw`3XJ>!JJX!Z9E+6591hlZqt#>AqB_jGg0W4DL#@koS_jii&4SVBj>g zdZ&OoHJR7gl8x_>+TiYqE{%^8v*OeT1~w$RZu#RfE7xkw1S&SRLo%Qk$o=_m+fwr3 z@xda_3+8T)%)k~O=%+e*oe0?p`o#HP0eUm5C-O$`hv-uLEaIw>K+$tWuNatjHqCdY3sx7@t-fOCsW z)(HO^zYLw2tl_v|at|vjCznQykMGt|RrU7g&!6FKnZZSSJQAy|(Zq2L4qH;FHBJ|e zBMJP>gTuo%xw--=@LydC>;Mg;MiS0M&+JIieKpx2<9-_hTOXWMt)}I|pP3@C z0PHHLtIJ3c8Ts^Gc4VCXv{n=ejp+_<27Ioe3Sv81MAR_<^2t!9NFs088}-s`V@EP; zj#10!xszMw>!nTcv__%n8>rN^F9oC zUN&1fCfWXNF|zZg8C_84oM+80(4}JxlE^T5BTak(MfS?IpIH$_&OiJSg3mdMkA$h% zCsEeE$3`n`QTjuW&MKogu!lV*_KgZ-%Wdu;==4(tpsVm{v0$`WA9XBF+Jwp}Nxl$CZ7bE<+?~?d{ zphD%r;bFh((6~^YE=S`Ncjm8uM))Njb>DXYDYAdo=@OJ4W!8OB&<<$AiE4h zssh?htFDFwzs^G3Q9nQgOzcs44d>>d-3$pz&){C~jn-tJ3B;e#w*GVR?4TC!<2|6T z=*3^|(H*}~!ZfW{0?-r7l;42>TZ?(c{51jtw>)kvWsuiG2&KWQ*Cwk8`6XzRb-VZO zv<^8fOhEXru z*>A@bINBJ=HHePF6F8g$eA;ATxU09;T!PqiY2W4pHja0is|~s$X#=KDA|u@`ho+l% zX~2QvxzxfKLUz{TIpb-`B1pK0%(OD=LZ86?8I6+Wa>KX|v83gvDs?`9(0l%ABg2S7 zzb#qR)j697=t(V}^GG}l`MVl6ZZ`dT;oAN{&VS}+C?nW{HJPQ_(?A)Ez@i7ykF987 z>A9y{@9HfDsGv-%f6e2#XT3hcawo`8q`y&cwhAFn! zAMD=uMD&5WfMsEOLF0N7hdT<&JL)>Ch0u3NFT6fByP{MdV#F32EYu~~)$$7fbO8(l z?^;$|4R5uc)-0#S%f4%!;530>p9VLnQ1=NDHF^Rz$RX}v|lG(=8Wiw`Ry4qqmBWS6gMpW947iY(` z`jcz=Ui(ptsH264O>k(2WVkS2`$^+fZ2JAqkWg+5^!ezeL${6GknBRX`lr_*ZKAu? z^H-&j4fYS?zb{@nR2oeOe0`ctb4aY!NaN$<>q6|TtRXEew2+e(`V>n1j~<2_G`JN^ zWP+YOwh~hOUZj&;U6@uE!}2HW2RqKAfTA2MJN46GXONYQiLRLBH3c5i*I+=|)_*UA zAYhgGYa__ACL0EjLCH1ttTZllcto8q3J&u`abZS+?Xfi8vkB(u#*^AGw+a(Xu0 zbdG$vpLlsUSA;FPA2s{SwCgNXl0-sHdgXE)nRS~JOEJ>mOuKYy&7yG<2#wu)Gzj&{j8`b#c$*1GCk^-Eb@t$^~be5ilP`WF?x-&dH6q(SDcc+U47*$ zd#ojB>k;ewi1l%_fyM9CBTDPET9YFD@VdWpLEponpYc{m2DMG8&U#I`)3em+IMS6> z*)6)8ulwy0A5p}IrB+s(;)L}hRB2|x+rHT#&^KJ6+@5QofrUjR%?_ zgQGg+usSV7DMq)>Q}%K==4!U{A#(GBbd=abH^ZX@r1bB+Jljd(BZa?hi6~oGbG>rG;Qg}pZTTO5| zq?!I-`X@q zf1G&+l>~g&UVfuEn ze0BAW{E9EK@m!yI0={H)CMm0M6v}s6m6to17&~swA%Ju756!sr!6I}0&mUmU7^Jg0s2q}1j z$$(;Q&;AimUJf*@#lSILVVtBLpPZZwl@Kcdr{((mcy|wot-s3h3y{So04eL`Hm~HY zy6cmZ6Z((<`P@uJVj?1-US?=tpOhJvdTvb(7NGP);^5;W2zY#Zvh*oeT9~WN4jW>u znKJm}y*oQQ8IqsW2LN|TG<_BD^EZJ4W}0oDE}bP`N>{O93nWVtXzHXH1IB&J>hKu@ zlvNhMNL&4}e}5jD8R*T#FF7%mn^k`RSvTs_Xx4tIrS+O40OEC@KP5ir_6*=(aR&viS3v%~as*`x=kjLzT+F z(8$Us;JJR|OrWNLN8P4EDwqAID~u$5g1i8|@FyB1)BsPc#C$3&4y3H0R#W>o;&#Jv zD^TvoK%d*`H;p^5qhzAjWv|Rh#JQk|M}AfPjK5g$n6h4Gnrv zvw)s&HA#c3OyXL0}84zlarGvEQVrAM26*^rn1}Y zCK`_UO?}KAk678h_aB7rwy_^?I$m~$iSt&o*fG%2N#0s^%>{xLR8>skgYDzP+RJWQmUfh&0S$ zC^wi4VA(7;#!VRjB9Y6jRJdVK)2u@HBcUe$$4Zkh5|^`)i9ow!i>~43VG2u}I>09e zv^VvjqQ{?j++8r#Np;_~qw$*Ty&W}E!&q3d6hFC&>yy8fZA!TAZ+-T&7r&5R_xrTv-rAmmC^T*+a^H|*Y1Mp1&=vQ@C^|qWLg(@J%)_}bB zZeUIKuKiab5K#iylS?AgyRWGOyKcY=ua3$ zMYId}EXCf81u3f#&N#GXB;{kavE*cNGnNipv>)g~fiD#)qRbk-Kz76zWC`j~j$V_9 z*3qsd(`994cG{q%qx0_GT1>?Aw<~Vj)6=uFQk5dG!1}-tdqa)$U4deI-DK9!EsW>I zK!Iq){ylV#1+0|oN*zU9a`In}+%PDZ1FgDR^D!#`B=SuG=xNW>LX_f)AP=FSx|&t1 zRggZtn(D^C)#)!f{%9xAtVkh6fbx6Q@2uY&{38sAC;R)&k!O%RMvB??MP&>M2p5)M z#ZcwMk>DpA&<2?F`VMkpz}Z=4&a6%Ofaq`2tAU}(TL7W%!KlZ<%g3kCFdlVT0agYz zMaBj!d}+|;Mcwk?GVg;wYPXK;x};XMM3b??#aC7vgM%xP6kr1K5SNnl^5Um8;g0(m z57g$sBqwL4N0vcL^>rSnUx?u_dPfz74sGsgrXVjLWuxCaupV?4J>DPtsfm(5HL&14 zIfHFgKUE% zIV_YV1|{qz*azG=fxU0o2%H8Z`OJt17`~GBEp52Ey5dGz(a-m8MA^B_Kg3~a6SEj3 z2@09BMGkn=9A*tZ{>t`YLjI#8FGYr2q;eM9Ztg|T%l(m&s`MSFVC|-vm}}x#w3yD9 zH90t-^1(5R$>csbthre0jyHDDT6u0h@;5peZ9N*J`&lCvE7Cr%-Q0!C{?`D5D|*=Y zEM4Wf>E*ublfEQZwOK(~R-Ls+ll=JRKD_1D%+G%vchCc(k5p*YNG5|ZKC4d!_Rlaj zYODrdEUF8XS@i`C?kZMU8?y4s(UN~~E@dx~cquZ{`KYJ?;>RGWniW8&N40Yfj31BF z)r2Nq)A{XetC4fZD(jY4q*#O)TcWLe+ZYFXp$8f9NS=Wue_VyaMNX(4X;g-S7_ z2}g3y6;3-jK1t<26R%Dr^$nQ#nn60EAs6wc%{cYCznufB<{$SK?L-EO_etL3ephVQ zpP1IdnGEC@_PdhEvY3g)Cesu2-<9q$m6|AItdF)`?#-Z)hlw}ko8#3ob|v6RA#vH~suPFLf9ZXs(8d=>#WihcoJpa*)F6K! zl#)LLORbI;7kNy6d^7^VH(?O-_#Yu$FJtVm+Q#sC?AkbizwCV*QvO@Rn_S|>%2RWq zvXg*PaPuKeW%snNBarZ!)LTvpH?6tF-o=x8d`J!;K1>hPfJT zsw6IAqE?0D1>6k_J6wMZiVy%ZIyXujX zhr%aSOTehNA8~Duq^o3nk&?pqAXk`2j1f zjGL_$F?^V;+6GJu$wx*f#1f1A9OYv>Zs>u;M&v8!;r3Qh7BbUja^8So#sZe~VI7_-Dw7VYP)_@tB z1_Q4hrrPDM>TagYDRlcXzC=ifdCdp8F4lVKq!jB>P@wc z44W8Iust*uSUuhO{~S*|`#Ugx7dM&3ZX2MbPl&}KsMJe22gmDXnWlH-AyY$aX%|hx zw4Ix)aUl~fh%t~|m9KFTJN}W+Y}5fS63j)NDX$0<>0h`B%9X^+n7;&VLn!qzJ?g-j zqJ6mJGG#y$<3&Hfl}exZWT`F+FMnb7W`$AvA+Cj@A|uBS|L53U@FAO=XYQDCXW>g< z6DE#7>T|(E%D~Lsj0>thysjSlp!)cqp)fKvz<;W*aIE}}u8ZSG7B6flT?t>NnXh3f z_Owkp>WRG&T99y)4em?f{8wwFTHT217G&`vfRgvW z;R|k3zToKpZffey-Wn{^IPPxywvUnriKauZ8hodC$Lsv-AArZdy zK2%^Jt|`To6GL&v!oupgGBnZh5Z>R5h_3SgBk%pkr$Z@Dg-^28nrJ+capABWBy zuR}ifUeKMJX7Fof3A2%ThRxChb|%5L=LzyVNLm^&o&aZEpk_BGr#JEEnnJ19$pH%k zi)TM4)3nZH5=_M@*slNA9Rr;oYbh}*if-JgIL zA^{|Bzph9UQGhZV`XY3Yzr=6K)aag_;2adX1CYoq5-;6?Lah_E~wu`nKcf|L=PJvp`m_ z$K1df7O(+~f(sIz@IgPNDC*jJ7gD52Kwz$drx~MRRmcWYPLVituESU_Q2@_+)(WuK zhJ`PkLP(Sy4UfN94so3`ix~Mv|8ESbXtEF$4dQsR4Wlt}EX4BSePl5YUtseTH0MOf zL%(xiv!@fqhl&uukfjw!^-|klqE@g_89iC?YLw>#z=rX;Kg-Lz7b0OL{&0lI;1R=V zMRH=u&Xy%5anYyYnVU?6z?S6ZegJk-u~KTt9SsF;#4P3YQ0TTf@$Q)TWa)p$Q8N`v z{ZLejCOaDe7#LVFYpdo!IC3R< z0W-15wjU0RuW!$D2xnBCngY7;gG9|d9r*LBX)>E5RWy_Qv>CfQsWqZFd4_1>8WnZy$jM^anu96AbZcr@`BYR^p%4NrBfV{mD7zaf7?A zfYV~YYO7y3-pm)(q}q<;|L*g%UUr2Da1fdJUu=;NfHx!Wab$qeeoP^MnV-Q`$Obx{ zjCeGoZHcoNpIrN|Q34CQDMV9%eEY>OZuoL|Wqf>|p8LhI-smHSpTgqtlf`3*VW-uV zigY+eC4lf?MY^)(j@$$aa&R`{Nw)sA@eDUNjR?K(CP2;W&a2W9JR+_7K#n2%#+#C& z9b5CrT}B8|!9q^!7lgT=2gy?O4fSJj56~U5946DiE4Chv^eDn`e|^0Q5)v?P{8s~# zf+XmDd$x`b&(6)Q!NtZFIX5wJcN^l5ii)Z?H#>{2qN<9r(&6_KcC}Eh(-1{PMde{= zXxIwW?cmf0A|9_~9qf?6YU!G;cAp2bYFeukphim`feh7gUcYS?0a<9*BLM_ExWs4`Bs$2fY62@I~GpbzrZ zqF0WFq3F&HRyj?Y60i|KT6W-z#p2gdWB(L0nlISLz`zjI0#%Jcyk}Gs4U~UcF8MKO zh4W+D!3-_ci~5Snxgs~$5WzZQCsU*h%LDdG08!s!i)}Fx2nIz;i{UY5Dv1V%p_2|C zT4B44SDrC%!^F7^p)!AMc8>TSXR?w%F+HsowvZ(7kt}r*=Y9dH2ep)st>kv9R1LLe z(PHV-;`onxoQC;ympFRo_QFCl0v|=)0%Y>cb6@v){)RSL_Yyh)684?lPnvLm^bT;SR&e?9@baR}Fer@vokg!%EtEUe z^#mpyY&5!x4ST63!YJBeQ``w(TSYCctTHt2i~iy^-QxrFcQ1&Vws(hx?knIdX+{0r z%rMbwZu7Uv{|OtY@R!e(n$=Z`4%mOnAK&lZDXjof3sVN{j-CZ}pVzU6QL4JXs1sR~ z!x$c&mu&xIW0yx=n~U4>T~nJHY6hJ8d<&r+`0{fDfPvDh5C{Es#Bt=M&tEZ!=rKhN z2M?Y- zUg3}h)G3S?89`z&etF>^=IR9deTR&tGyVo%l~?3~AMYY>cWSnt(-vofb-KLd zY{DDb*Ykpff?%v*)>8=5|HSh3n2ge!=)&knbFTEe5g2#<2dTr>!o#%ncw~4tyn|>% z90WBIaaNA6V~(5Pqr=gGP{&mE>=2xK_+(tS0+__OfOhzwkupH@2d9pEt+!9@|C)%m7^^O5v)sQ&3y z3jP<6=SIG3bOM0dW$MuESfBH@CRV88+Cs7Z!kuq$gi+URX#x-7WAkuzA)}qX8p@n4 z1iL`dtk|A6)CdqoQXHV=@IU-TS{H4Wd61?L~q?*d8fSNG*65#tkN0% zg21wiSW&kBtYf`U+9K+|n@tnH!=7`D{t2rHu9#!(H$* ze~`z;%d5kPdiEd`thU5^>Lj;AUx@Gsq-MF&f4{;Jnwy(@LaozT?fyRW%MKV^vrrS5 zX_n6(8yk~r_}7(EL{ZUQ*su&(Qwl;tLQI^abywP4E_O{PHW-yJ;gNllih`!56wY-m z%+0r6<~u$u$F%@c<-p`PQHH=La1a69#Y8;T_F5<&UNH-+NJS#{v3!P*@`4pBR$Ja@ zwX{%5{BZf4&c^h58&4DCbX{X&?{Bbw)#^F2O$I*5&divt)I!TDDVeP_qsg8u=J83x z$}YoBCA36CT!>nPqNvIE-iivyj$Q74V6zgM4MH;0Y(g&3O*I?&{vk!`)QLTH#wGW* z6ZXEh1M(~LPCUv~y$MpPYK72j7*?^gs>ug*WwVv%9+sfi5Yvoi%|n(eqqVAE+w@n~}) zlJYlu)~SVuViyv3Kc(w1A*=z{s>hBwKIiBTGblt*3(&=0#JDz?MTb>J zeu!MJw}-T$yNA31mi@hiNcaQ)V*vJ%m47OmHBn!^;7KL#hv!c7I@VItNsFpxHw^{dGUp$911nuKUg(3)(QuJCS@eZL-b>Ai7nf zl~re&8iV5x$C`)&{z!LoxET^TKlan_MoMNkQ7haE@;A-2yGo#blqZAoeHuU?jImV4 zlh+lQi~(H4ef)qEs3a6(!Ck!rS-k~DVP){xn0{nHmVg|8Xa&h1f6+$d#98Be7Bkcm z%Bg<85!QPB52PUCZUJFQ4&>y%K{`!?EbMCD4Wqf~O|#d`IaF~5X+ zw+pC2ocJhSc+|KNw{wCrpnB`|?)s&0F;#NalCwPw$}UAVlQmFuaP*I=jIXdutw^^H z2RncN@Y`OjUU>M`WO7yL-)h!N*$D5HHhllJqRZ!{WZIvINc1$&>)X||D3cO2@Q9%J zG{}hQeLK$TtNCvY=Ph&7w5cE1T`nf=FoXXZo8_K#5 zJbW%U1wTK$n_KKyOsg-qOV6?d)5qoI#h4T~Xgs{6lp`02&z}!s(ochxi=6L1j*PU9 z$RQi3T99x*qJ!4bO{tz)9Hx?ZHRQ?Y&&ffE?j)20Sc-}hYo0)$ryGs@NYz0&x9ksfyljUgb-7rF&gHLLUPKV5P-+OgLs8HcLs>*2% zaK19q`75d>PLfCa@|$R8?t~HHyMJu5Zt0n}<7`zY5m(pIJ_r*Ocrj2>Q)V@Qoy`w} z(00X-(HtCbVlJ<_K z8a{A;ssnEnv0isWP{*r~YRa`b@0fvT@&J}U{ZC!;HIjb@7#C9s*eoao=cSKV#?p9` z0imnTfAOwVE}4KPigA2@AeTc|SO*?T;`LfQ0LCf+*_qB0hC>w zcP*Zv{Oz0VQS4|i1Kkt*$H!U*I(KEBAk5_?x*6WbtAEN&fGCfKt2FGv?A(kbENA@? z&a^8xX*bo;Ok_de)&I+4AeSY7dsuR5hZEbLh^%JbiJBD%*ilX3k90~it{y9EoBjj; zDs?*`PEf3LGjs<*aS*zE6cH%3fyNLTnj(;|2s6kbnTA=i{{tc#n<9 znccB^-hs_)){F3XzxSDaged=As@LQm??KG-_v_>w%*)J$#})TD1d?7^S6K8M%+GuF zqO4{5SyfqwWR=egqG|NyPxj->1sJV9v?e5HAShK~f*4}Fp*Z7>Yi{i3$;@E^Z1f?n zE-YLd-a=I)5*X$%-}(#W4G5SXLlQzQ`pO*vAYJd4Ygmshacc9UhfRo3ym#Jqw-tV@ z>fHaYvFKq|(%?A@sQT*0z_P6!!s2I={>-#p40k7{M-&52)(?4cqJEj@&&kH@Sm35L z-H0Cyn;b!-5q#tW#YRHP%sG!P-1heNL5zRLCMNEHkMNtZp&^c>%uFwOI=XQd3W|Of zPR?Z@MPesW^}*$QEoJP(IW{JyqqOS4B#z*8$cr`_Vmcdgv&Zw@+3=+Q*mn{hda_=B zgFd}0!Q>OPbautStaBnc`eY)J-E`tTk3tX_j=u9V zik>6Tb^h8@B)+1eq7+V$OkXWNEBIXz)w5JvAQxULZ6LNqvV8CONlSI7RQJbIAoZD^ z;fM_fM?y3*BH|~u2~Z_>%8H{@U0qJqBl^3+<90*h0|I4I{fif_IEx+f9>o6CO;lN{t9o>0RQ{r zB-1HQJQo*Nv%ys0OF0&~BUq2dU0yW5nSMb)YVv-N{Sz$-2}!(MAqO2-N&t#PYAp7g zU5UTi|#5Nws278vubwH{_&U^LZ879AJ12w8r-;Jk^Fy+vR6Tm^nK?K z(CG4!Kvqu)(M`;byjH$a^xRFDoH#3T^#JKSY&-^xeXWRI8g@J<9r1-I`^zn@LAlx` zu&r7iJr$GV+`SFxgn+a>rg7pkQTAA811fo=pr7e3Xupn956#*`2VQiFn>#=nnX57G zLNI7a9qXb7Lw*S?#WKpm;>w8lS8RDDu24T%P;xH&(AN;J0K&p7skS0|(G#W!ysXP& z9;FVUThz531FsN3yD~|jVy-H!-WJI&u?3}uv*)CmC!R2(pj<17f{bCan1#jufb+FE z{hn*erWBeXu!dn{Puf2kyRZPp-sj|r4?n_V&g#)~g89TTXGxDQ33mH}!`Md_Hkpbm zC+1oxRKy&dc*BWZA&RK0e?epQK z?$n~5;MvvL4LJU!p2Uj*9eMzu$!TSfgltY~ch*%&Scmk!0dAq;-e-yXRpgolV}x38 zoi#_E-pN0Ri_P-5VAp~%zc*vU=sV2GzhgO`aX911zW8%OBENf$Vq^N?(gc9cewMK0ebcU=jGaV9ca~)h!lYO+1)6Lx;Eg2|b3MIgh^FWr6Xb|K@y2&m`15)ClCqJ=saV07KjNZ}o)&r={s!l~`=cz^ zx*#Jt>tesNKo6U+02=gyy@a_Y8W8}Sj1p(~KUqJKXLF8&?7=p#$9C`LIW?Q`)6t2x zYAm|w$f=k*I6F3FyYBw#JiX4-rCu^5mNgUJC~lt4!~9eEGKvHM3?EvwKY2T+AToJ0 zTcmGojjX1oHuAAIviP$DqLq#WU}%?D>@pTwJUhS#KLuB0RQ{Tby+!9@I)4Wmo4z|atjX+FDs+DP_9ANZv^9^C;eX~{WH29 z`iZNiH#}+{Y-^d59&SkLFLzrrv*K<9h-o@OL;)FGTwJp?8E)zxv6 zGNZ0<-QaF(Sr|d0qe8&K!uHP0TqR2gBpfD&iK&9jg-x<6Dy(?PYF(Z48mGkI0d;my z_foHqLpA|W>Q2#&tT!a#fw}tpP5_9T+406Zfp8kY%K5Xst+f5;597+fKw%6Q)jZ1V zZh-o)aRCFop~aibzcWguEMLADP9PT!w~<0IT^$!PdxRzI?(d^_pj#Z@v=yD4oY)vd zNDQAJLI|YEwr?zhwilJkQznZN!oq-e0h%ly*M& z_xZv9q%rIoKQ=JXHZqZXZen)E=&L;aWr8C!8)os{jj4p`!VYSn*!2`0;m?_*l6F~n z9X#u#>4zlrFtC-wx0|+i{}kpdlufram)3>Hxy?Q84x=++^tkZSnq@A=<5#TKs!$ka z;eBP8n6`c@6dIlQ6K8GOz?}xmH9Cs{eC79;rojp{I5HDi&@&y?oZkS!j<$ z%fD?X2PbYEDGJcbG~bqXGa{?@hb?j7SvP6xol_UgE4>jn4NVywDnE`8HM!Lu5Pz>u z7>^VU_Mf4ohMs#jJ#6o+>l>eI)2`j1xdxaa@6;*3?ISiEzIcpP))|jl+SnUD>#3F% z%ka8F6G!O0iDn7tRVnCnjPVuz>~LYTxuL&k_Kw!PJECrxby-Z8F!yx$Q(q-Ms?{pP zXig^vp{}S6lHTQJ7mzm3{ljV*lo?da< z7Hv97kSXNmw`Z>4LKCJp|F-Y3@QpvW{x|ZWpaV1EJ{mXY#aBzV3i)iWIVkLVHJF zgI-VtF67^DS`3e8jyV3{4UTFvBV}%S{^a?&MtqcG7>t?P^%~u&T&zp{E-rYQpol_` z{Q8;H`wcUl@IkgOFo%CYRGvWB;^qRPis*gYb6#t9;P;h3d*|7z^ULYF6;pf=J5^1* zr}y(dLEFQuw7)l8NETOV@8vi|R_5ED^lI@iSsLAjn=A(vq1S!Zrh4c7)1=9}+upaQ z)yGkk1bb{5(WT#tK-FWo9^S@=Ol)8_1H8>7;o=i4W~)(C$qsoAm-gb zxa8YnrOq`9Jp72!f)@z1*a*zjf8GMnE2c~8)@-2E&M$~YBv6t$XlRi{=6s=rerBx^ zLHVrK9$bbPZa_M7Bdbv+obgR}po5T=MFQi%Qs!V|F}pe8ZWJ3v#88_}o&F3fWM2F; z(yaNCq_EQpxv%uu+R8|zo%uq-T4?>t>F#iRfoEi;^pQd8US7D_T{I<{85SW#HP`M{ z^epQ9>};J2$pUjh0!M04=1tiPg{z890z&GS)PR9z%Y_cC;%-b4L zpGRn57Ub8ScLN19xpY8faJy6{q^2K-2$<1I%gRCVrMl|BhJh+)qXF#MJ@W3wg`Sk5 z+LLJNZT{0%6*YnZ;Kn$@}~J9Z)rLY+1L_?y2qhT7F+LHDh&4^b}(?E`n21G(uxz zr;GV6*cbRa9b8=a&-eFL$92tZoR0fh3k0tlD1i1F6GV}A9Yq2{!cCJ8z2y}Z@72}S z4@rFu|D7@4WX!KDnas^j<4-UB?P+GB;Dgl)#Xg6t{#)E!f&8U8{ZJdMAFT4v@x4g!$T zrz8d<$IAvx1s<-C7WCZ|Ez?Z`gMQ38#346 zP5=28ZE7u@fyicpiTR(0Q{bqy0Oo=~?`aN%_n-e#?{i6L%l!ld_R>8;!nz#JfE`|T zYa)ZYCHK}``bXB7X8Az|^x$tEvsNm@E@gt7_PFd*T>pkP8BWvY%*;$%Eu~?wqJ}?& z`lBhpYsY3*ja@RcCtRiL0b8N_eWpQ*O^;h>qWf%zIW{{)mF>CV|ZM(C2tzY)%(QhV5%0w8Z@>uP)fQP%-Q3VD{};nl;UqS z?*5FlP-DXn)^Aw&7P0AG>NJPXz8AO}eKEz#5{Jyyold~@cr}fU;6vGLCAqmw?JKPm4LCif;c*C%ifD@yFvAJWl z)l$)N$bzN|(_E)f0mN+7dU#U%To3MD@S@mgJ>9Szs{3MLTh;{(wM_?-Ty+`)=H3kQ zof+1ffWbTFs-TiVyrx01`J~e_wgYjf=#QF38O7MjSqGiQG@1CJ{6tji=n==r%#+#- z_FtQPt*5535_D7>(wD84|F=84gd&g&9d~auhZtNztQgY zj%}_Wa~=J$?@Nkm8Ni9lfXY>5_qg~nlf5)H76Cd@KIN*w+LFh?$Hirx^1#;_86Flq z%uY`1pBh%t)|~InqMut_tSZDVXw_EjaD)yAhJT&FGpb8TjW_|rU^1+L)lLtQxjnSuA9&{XhE9PlKaQ{Eqq*fBolW%rKM+izDC9f zR699_rJ7|B_xNlRY9tIls?9X=phvjQtac;T@;a;yjouVIip{8BehMcO zV^|c63o7KeZ>(yxgYYfsh7-s4W7=CS^}!mO6Zur^bHCix)z<{p8A zlBDZ?SSJCEq8d+(iyS_RP}A+0b`DE^iPnA?@V2OB<;Q%qIZkXLJs(;cAb(YiRzecv zM^A1MLd`LLD!%|0bejm}?F11w!c;uGSj94{U4E*VvJu4RcMyG<{_8YY;Jr4-@FUi! z@*yjCqxNB#Maq!M7+ajqk|9zraAvjalEVaAiWFx@agM8=ofloM19A5ojDcFxp!JY} z@*ECsHoZ8`S993EhXd#;I562QC9!$<2GICn@cA2qH5grLXX5y$%X@JW*gQ8S8Lmmf@Zg_}!Sc~5k9O=4Mp^%@h4eeV~9 zx7qO$EV}W?L^wa3S{$+*>49SkPD^obF^}CAjl#)zf6d_O;&-J0kH&g96ENEloaybl z`fmO{xrZ_(WiSK%_(FWgVBh}d)aLqX;zbE}r$g*LkaX}`?wy(ZemA-cp^kzgb_d-g z0k^=r#*FyKer1a%bwKQuMT~+y!BYg~IZ&)ek;&wFWR@@r^$MK zA&IqVa#Y&vSnVF?to_UFF#^U)=P37TqnH49b5 zyq5jb90z-Kasorj%z8MgTE4dLk%0J6oXF4dH@+oL9RX|=wa{ZOB=*V#Ja*_5vgm1` z_7r9H({JDFu#AAlVK=8$$TU2(Iu!ZGLDrqWHep{!I?){qX6IH-+DhCK`}5WMk@a@d z+@;RpU-ih7Q#1Xhsue6_^X9k<5_+*Hq+y4HH_e`i< zJ^zB;sdK@uSv=gdW6Lu^F=yxG$h5B;?e2g=(~mu?4re@sB*tWmRJBdN;y~MpkzImR zYz{*Uc`m#{3nPSQA3scYSN6@!>Ow$^JNlN6XeFh-ae9-GktZV>YlWQzuxAl;A`NCM znPrRxN4fB^@;KNXiXhJ=6F80z2rgP$GQ(kL74{1r>4^s>4Y9%bn{EQqVP#prwC3@5Oo#w)S5 z@Z~*utxC87bpFESqy&cdwf8iCo8S26bgr1ZickWWcfY)vX-ns;j*80^Fx4LO#>^jf zZ)jCdhJ8PbjUK-0?9rJa+pQF>_!<(B?uMUGer~Y1#dFHm<o}-98}BQMDMXlHjkVyOOC@JO zpd-jC^csvJ;vGL_d$RNkoj{*(cDu(j`6FiUA4@dHiCy7qBO+wCjh6LKeG+d>>lQ#X za}#V_QC?EAwJmzQth16voi+61d_+7tAWtL6c!fAKLkU77J zNZ~2CZ(BZ?8M9em`90=r1soSKP(>?arUdi)H;^IYn&gkf$OupsX(*B+!os$%1ZM=$N3uJwxlb`pgVY;D^z>WL)0-1J{cYt4a&yc{b-vj^zY#HTY9Q? zj@6+(6_P>44)cWPY?!i$+_p^%D!KHBqUB}FUF@~qls_sDqPyD!WG~@=3(~bEY4?0M zDw4(CWNO39YGw{iCeu_Wi%`Eg(XEL(exyorn*F1x^!W#9mFt}{dpy|Y_T!9!k(|IH zuE3>(J#PVG5{6XUCkQLn@bgcOLo~3z5UE*jLn-ym*S}tce?GfoFNzKPkPUUNQCw^# zX6}SRq*^T~XU=PZcPG%S*Q-M=!ImQGbn{{5Al1zw+EBA2T?f9AP&OdJn1C(0-=M(` zF_EPZlYI7@|6~V2;Vw)oo1iQeYh<3ZN2qNLl4uG^O?Bx1gwxpj38h#A*6b(ydr zc+w!rwY|}FNelq`eB-jAoO2&4D7fbG$=5ey^L8qLPv&*8D`t4W)M&=2dU01xPqd%^ zty^-2rivuK1`_ZtlJi2j7r;(syuZM{oqm?4jOMoF+qwY#48rD-K8P*h9lHga!~Yz3y9?9kUi887e>GryF9bmc6B$p zg%_c^>NbOq@J3r+F*2PMj#rP*WE1jz=z%4*8uIMk-0-Ev3)`G+8TDD}C)DwkC{|a&#McF)heFY`Ttf$xL-jfKi>T_0QdE(}x`%&7*f`94 z@XpFXJan4({ydDVu|odIodNq&hmtaM5`dL}nUS%1IO`Pa8&Gl!)6MMuuN~xyad%n4 zg}`>LXYVeSEd!RtMHUcyuZ$|>ukiuyxfRPyvlh<)ru?D*=X+~~A8@CLzJ&R>adPuB zsFLHRb?eW|f3T+i<>Q;U;*)7UvC}(G+No&_OL7p#8aoYK7XCBPq!M)`W|%!Hn^Z^3Y(I<-ul9V) zNu|)@Zb&;VUHi=7%!cj1@d zkB%VOBTAux%WpaEG|M|33yFthQCqXqjMyLX_{TUkt_ z`L_r5X1Akj7iC`I2DD&E`;7SL)hqon3Ve+c=l}(5B9ev{y1z%$*J%Z<6>ktT{T-#f z5N7ijmazsAfY6t&lXo$x9BQdYb1Fyyd?iS~pij4DfzkA?-s1Pv#Bdgrqu^~^2j3K$ z+T6(yJ`_C1g;wBsL#b53=L@m`gQ0>>c8HH*(R4pdU5^mB9j){lU|PvY7!AAVB; zeZ8N1$-m_?(`l?MNCd*r01txbN5Wv2eKo8{~8?j;6FQjk;Nlq>aT7>fWf|K+HX;zP|ocTUl5X z=t8uP{`$2(m~B4xKMQW|?)Cw4w4Fe`g7{P_{!>JiBCz~tP`-{{ljSm`{>Gw)$*u`Ja9OJ?L~K1`BJ?_V1^F4sYD@ zpN9INm=Ca<3asq&;e#LBoEC$yWcHldrc6yNz_L0WhuE+?FhGw0) zkV8Kh5hh8`sgIy6>c6?3$XP9c?K37K2a7uhV8C~6BK^q;nZw* z@Ci=xrNboIV;z%Wlc;Qn;fl6QiT|&i&)R(EWbXBoy@PvjttkVn z;l6|xHN8cK`bUT1&DYM&maRni(p@^M7iPrXYSJHxHX?4Wv29h;*Di&o`3i%bd(Qsw zWM*u$0**M~g@Udoql42;6N8}l&6^#c-@^NaC%#JeBQFw+%^Rcm)-^p5qi|~RqrqFd zRPUK_6<$OR>}H^yJY%773cs=$5wKLRQzBU)?l5`C2e?l2y|@mQNKMBy%Ju(vb(LAe zjHoH|W4jFpQw;~{7fe{ms1pZxrk=k>2NQHL;qIuy3LeFj{d;Fgd=kEk2Ma5WFln)% zv8Wh66EmF?*n;XAPWAd85O152>W~Kvdbcp6EGVrJPJsIi);TO0<$FxZ zj4WBD`okdBoPuqOa5GFg+`>|`Lee|zi--6I~yw4TeJ?>Fl_OMv5_x9|s8*R$k>U3J^O;-!o#;icBvrUz+g5)tC zZO&EH2}$1Sc4O${u{mav;o{P3vU5Oqp(YMdDPNUGX06^aP$4Ea;_J84cL0x94fq;s73|t<7Tb9&uN2{j6) zJlB}R`5R$anv%?5Z#UEY0b$qJ0R$cY0vD^v3ICFg7kKc;;Jw z8ydxKq!#mc6V0b3ZjHPM-Xi8-Yu@u5W{6AJ7p(#V|?uZ4rc z#ZZTYb4Xsu?DrCgNfV8)09<3ol7U~{@?5XD+~Z5pxBjnZBXVgEi=vR6PIbq!_fuDgJKYr3DDBaCIAP!S zykU`(uA6oE7I8&&(LRNk=WJuiS(p*;$m~M7YIlvE-I(vELGV@?jj6P(eZlPee7JR@ zdJvu_w@K~0+CZ9|H6FAvtWr!QAK>c(&xRjpFeArr9Ls9pq;IyJ29<{3Vheyk?l=bo z&xd3Q99se(pXtAkxkvYR=$;Zyd|8;E@1LHYj(pqD$I9zI&JDc-&D)0m1AtHyME31k zZQwQz>1(5Wc(bmSg9sgeS^rK)OUuEiii1&ferK~*OpK^eW^2iWFc4A@h0EG|d~(om z*a#|L{yS=AM0|8|(niSTcsSqTaqq=weO(etw%GiYe(fOma~kjED(fhBmkg6z1t=za z{rf#p=UnaZ?tl@@HYE*B8XX12?Gf>{6%{ibzE_3`(dDdB9=iu-S=0LWMWP$ay$hJO zAM>TB0M^0#cl|@_B0RP+yE?FHeM;aN47Xj1*U1ues?FUe(h=)w;r-=exOuT9>*}t_ z`Y02+n?eN=!M1K>z5VuwXt&0l;;d?HciH?^0pJk~f0;DFMhx*}GTSLC%;tm@sAGnH z(^v9FYn7-nOAdrPF0h8>Lbmfp1%H|qxuMkfPi>Ed|rc< zJ^mkJ=e?8!SMA|L5nm!!+yWP|iof!8`9l1%rHUUSi0U`I(_CEhH7PXy=E+TiZay23 z4lB!Xs2IS4MuAI#6GAW0-M-ZBZkG9_Tc?m~xFZa^P?oz$R!13@NTuG{&xqeF;5Za= z0P~(n=}w8Aq;Hpz8tXoVs-OlEXG0oPY1T^EnsDDVayie<)cyn+t-{Pc3fV zb0B%f{jED_NzG}}6UR#~Zh3tI?}*er{EcH*aqJdH(WprWe@w2x;9-H@%|bm%T)_ZK zErN1kj&e)u8S_~AYB28mpOlcT86D=Mh;^)p-w#rS(-_$y?bUpNKD$xm0*hZWAu_yR zSjD#RFSgI%VN}R##S&&DdO5Ls8`Iqv>cofjXfDI){qW1kKH{dNX7>*QGJTs+-Qnnu?a(!j=?s z)!(c%hk0gAhJ^l7hU{qrY}|TPX4u^Nc<(W6(UH9FkNV~HZrXJg62^5)pGF@BrPkAG zfC&#^uhG-ig{9N_<Dm&7Ptw z&CxpdFuySgou^)F`VTE(aVd^F<9zwIKBYh%WTA#&7kVOZ(XvLNMmGW#?MZG5x&HF| zMy%aWl$mrF@Vq%y+^KQQ_ckQE!Nxxev5_H-+QAan-{9CaDBBxm(y=b7*NLNNek#Uo z`@>2W+3|0YpAWiabKHGAA0QA9>4w}A7)Gu|{EZWcCa!?$h3l4MGK9o7kU`>U1bdu) zSV-pQXz~d*H#Y|RQ6GD#&Dw9xB50^3H@sY0bEw@G?vdTnR?;xcHe21|^IG)1dv5Tq98|pV;Jke5A$|CzQsZpHLXLRW`ytds5Ff}7L%TxdgVW#4`f(iU#{~D zaVP{V!>>g;yXE$~&1`>A^1R=EYZw=Jg2aTj_>-`Wx+Rb!7OseUG*u#cj3-K-rS!Xl z2Bd&i6F2{ho(Ibd3)xZDhW@HI+D(g4cx-YW ztT}8vdy02Xp3Zf(K)FfKQOHYY42y(*16SplT@ILg60X031$5p&d&Ih_v^ZNc}?rLqZn&TQ; zM&1j4XNS1=@-TRc`vrxE=jQx+FA~x@mBTnqM|G67g;9W`%t`7)3$}si$B%(TQgBn8 z5|TFMP3ribajn0K5M+UNIV4F*$+c!XD4@C`+!)AVPgj|{q#OwDSaGC!u(&8H=fsxK z)JzQxmJH;Q&o}t-V?-kH@mmnn=c8|ZcsZ;}uwI%TXgQ4*w5a3I(45(I2m_P@h#z!< zWhmBn(SIlrDq!b`w#MM2IX(OcQCJ~F5D6D@sJVM%w(RPPg~+DKEFlM_3u0|q!7Jfr z|BlIwev*3_fqRFn|7L^4c2Yh76N#l>))--D=ec%8!bVeWoT#8IImH_^!hsOfcHLee zi4*7BwBqb4LH7u47Jv7JXJpP_vK1Loi8VVdA12aO^pt%i)X8PoC7KAVc}+6%NnWvM z)RWdX(M-{`#G2BQ^ByPL>3CE>y%hSFy7`dkde8dhi3m9f&ga0h6;RE^hIK&6870F< z-XJEL7kOsOqpHr-yHPzK)iPSQOoVxL4Qi3~?hZIf%X!UcEOcpsj((Ug)?kK@NHfn> zB)xBlBkj>W!sfi?6Y|f{W-Tv}w6Q7S&`J)B_XD)2Q_CTAnkUt#Poyvb?sqqd8q&Jb zr4n_V(jn&@`eX5zBu-||$8|OGk@Q8tY<*v8+Gw@JPd+Gt{(%7)`TWG#r&v>J_U>I0 zeHlfbM2tdmcI?B;tzH>qRb4%)s6@mMSXx?I9MWUrY+%lj#Dvc~NO!$D&RAPT_XCjA zhm~Xwf)K?D7e&r$-sB7cS^=MJz`a{sIa}AZT}|j*up5uiA&n-jq(AS^*T=4|0I}KZ z{MAyuIYyms2K`rder}{FbpEZs>&BOg+R?wCSN~Af5okVd{Map9#Ato>nHwa1C41+{ z@wl`pU3uPYoacSnAc6RS#<=T^B^>qf@f#v%IzlJj)uUA8$)fn4ALM0!%%mx4U!NFo zUBP)b1sseqPcOD_fE%EMAP+p)Z0HyVqWE$wruS&BL^)4@`gfJVkbaEbcuX$|WDq8> zT@+z_JP;GtZk5T<`id4F;guTGu5-gJ$AxXgG+1vg#noi!7Dd%4vw@#WDwtql!zA2u zvJTnYX+RFsefU@*D%QkNVmO8d6@@FhO`rX;x4_2LbO;ORSBOr&AS@7;3e@e5{8RRD zce?n(w0o5nUajR#lP5gUenr>Wb;)WwS|6`>IT=Gkj>GbAA0(veRD%EQ7MZYIvVnnt zZe&=PCK?{zXEY)rYeIbdR8#^2Z4fT*5)LZr)WN}l+R4sN{GYu&Gu!*rT69i;XV2~T`n~X5tluo%L77dc%!Rcu^2TX`{XThrO5x!Gve9{1J z4m;8ye|FYU^wdRAFVHrIV(24b_jK55&|1n~oBc_?R%D`6h#c^BrR zkxE`gUOYr&Q_}^AyAd0|HGOVaz}cG5(r{EiW9h?l1by@FZEs4*H%;yvveIm<7?h&l zt}83B5+{0mZx5Q^{|I?|zx&RO5vT{62#@ok-4httjdH=W(~{*JqDK$re2VwyAvV1J zt09p&CZH*XO)FeWvV-cMrW&hYC+p+lN@_zgIk?QjgU#pl;z~mC6)ESaz&3h3SdTml zSg^9ThTYoSj5r;*abu1i1MUXMP=eT0JYU&dhQcW}1O z0lOZ4v1^^ks?04C>OS;yb&v8AXa5OUtLA0lM8fhUyi@3b?BM*7T*TH8mE$mHB&X0b z?mU8{lM@yd9nsd|@-9-YL>MYiL=;tl%~p{KQi*Fm&Nav2E7L?z`(M}v-ouAE_&o7WcJ>?}1)uDizi5s^tXiGqsil8Z@ z$XC>6%Q)$|4pzGDs#o z%4Az9Ju*=_{u;z4aV!;B@47N0ObMyML~t2ZyB#j1@m-x7G<7GI+I?IjjJdoFuD_iL zl4$y+m~$fq+OAe8%m;N)i%)BBc6oa{R>GB3WvfVeNA8DNGvwjSG{IZ#IeOsn&Ln-X zT6YvCcvbwdx(=NGBxwWuWTuv!IWA@#R#+8kj*b*~pj*)5iI<`ca8$j-(I}OGZ%CiY zZW=^9_|~Ju$$rmB6|Q2N6JOumnH&ezLcPjVwYlH^7#d0tJtZe&mIxla#Dkmq$*NtMfNR*ht zldE2F2EKs#<+!jV8|jzd6s7&)6j1-1csb0=4-h@^$M)rd&xKNUq?Q1%)2d$pFWYZd z5SP~rhlr>sUW`91%F`zfK>dTOL8 z_Fr+!!8x`FP?5=2p!@?FTjtK3t#mlOXV3m;Iiw~LYlU6lXY}_{5iWDPOu}!_DpcPk zAcWuU5b@kB(TLVt0#F^kV$xisw;rq6oe{F?xDyhDqjWdE{P*f-@hr_fvrX;{68u~^`0?;Be-pwEzB&_Q&Cad9&YEu^~>yFq#e zdD;1(*EpJ)6X8R3{H{K+aLM9391^Y@QSV5i&-#iZ+540Ym`7#7*uE2SGex3{8&k{9 zPlOa~Tx9PAA$+=0mX0Pjr^|H_9x77mDsq`T!?^A$hXIUV9{_V_&x3J6pV%U8=c4A#cBVNvk^HZivwMCm)pRZxNYEWY_(RF9<{gh56H! zTG1qq>B0I<1BuS{?=pQcKij&KL%@&D{!D1X zS7$JWq(Lw9){H^%zmbA`!0#@&%v1|MRoX52BfpmZJc%(rDm2_S7T?%h8%#pR+bLtU zZa+l~XA$N(iJ90(Hydu{rqp%b&zp^DcTZ&}oY_#fTytFxqy)uc?sumlA6e0{04qTH z-(FVF>{}I5ZpfpwK(G(=jncEO`Q*d#Z(twsw7VDp>m03EfbF)ZFTx!M!jlNW{7sa~ zPTeR!Z#e^JSzyElMxFU?t13T~Xz*XHyWP`zBvshotoowPM?!VumyxxTn|giDW(5u- zmF1^1vapY2ek#+%d+Efozd6D-t7c+N zgvY==v4xnPLGX|=dMD7H_Q3JCHgL--Z|qsySup$;rr; zXFuEjNxz{alBOrRL79|8?_}BYe3V!{T3de?R{Cn*`|HONMXbkYH5(3hU}U1`}~uh9$X^fMLVRw-h6O zERSWA_3Ix?;}x-O+;lN1K1=3+aow^0OQIb!n-@G)N8C0}I*!X4Y$~y?On^s3ipa~l z!fLs#{bfzj#w#9Q_7}X~wGqDOz*^M@a6Lr3&$Z-ZV8r3 zP4f8Rh#K!BX`t1VZ?IG~?r@m6vY#gHgYIl~cm{`a7VWX|InFm73h4)2uvHy1!V^9Q zt$X6tSq%AWGDRuAXg-h4O6eKNxJQtF*&_-c_N6GR$u}lAmuR~&SvR+yrZG_6c7#t3 z7@X9hM$?+&t5U$qW$?pRBiNVR-V{8?uqt-@5D|I;#*L0xaRr=2(Vle$0g+Ur?jzYzcwhjPD`o(1min!KUL}NwFE{8zD5QN(!Pw zp#-qw6^cXS6y`?VqKhM*L8o*SY|OCxo|x@!`Z=)Jq0SnU{>Y_tK09VwU7vfHEp|x? zdUv+MATRaH`@G=b(EWzgv)un25#w?2+fY~6yB{(ZJ-iJ#Kfe-u53dMtkSFkN%lbD6 z84p1Hr(`9rYJfeG<`u6pjrw*&--K9n&5w0Nt{1g>%ue^S7DsP6h?qvFzWsYN>w$xE zj5HV+N#=#CHyv}hZ6Cbr4)|R|)POtpd{*p8=bE556BOQ4M6Hof>iKnBuWQ52TD=j4 z4&R+7d6isy+*~Ws%gm*FaR86&!0oal6PoMrNJJm7cdrjN0QS%J@Ko6jO%9|a?m2}1 z@R?G2QsBN*ZdUeOU2zfYK9th4@@MxZ;JbS+!LoPWN`L9bcB_TIxOkxbYlcqf`9{Tl zQ@BJqKY6HowiQ|UtcakfPU2P|ZUm19yK&(Pqx0FfG&b&<90GriVb;|^&6j2V@6N1* zpVi_Mya7EB%@+3>wE6~Czfg2G0YcNd8gjy9EGwlUjF}m$yC${ zz)!F&UOWjU##$5pd-B$Z-VS3n=Sf`8DJ&d7dGrgnp~{b?8%Q4A7Afk(M=H+fWSs&| zx#s&bws$bzv|a5G%Fwrl+Qi;vXrHCj*dP)>Q*C1D<==!Mm2w4Vsg`K?VgXo>ty2Ii z<)UbDFEMQjCjrVADM^E{xMx2}iUeN|RTi|Ax_rk7at<53sfZo|nj0Z&lsLpRl`vCZ z&6AY$%3~SH)30=WR5H=%Jh@oI<(3@qpRJ7e-cKzoSTJgBCdfiy^Fzo2ER&wt5&fhm z7Vx~UOzmn)QQZ0Cbr4X$YcJ{X)R|kghcIOKh?1h+7R3_Q_)iRrsrlN%GD8P-luQp$ zZzp(u{)Bq4pe#%3QR979tSZ0}82Urc#iA*X{RWWs;q0rcyVzS63*AQt+SPwtg6g)D ziRZ!O?(f61MFyxqYVDpA>pqb9NQgeE520{Hf~H@@=j+YArrDnW zF1Hw)yT{`{UJF^}+`peM*K^0&qztP)H?s~&B2Cvs{{07d4@(Bj!Trl)dlvY`T7g#9 zXY8GJ4p*;T>^PT@u!YhC1^h+rG_16rzc5G4 zBU8em7qIa5q2?bnMD9DBm@NEj(vr(tN)wN za?&^m-Ku$U(;$MPn*_&KaW+%sJ@|dN6EZ2~^bZI#>Vh?1_<*Nzz5^}ciiUA=h)CTx zf~pA@ybBO%#BWCxB>~J<69@3%oCHl9@$ztjz(ofF+!5R}rWInrQzDu2P8~Yj51QD- zyQfXUlRL3acb{L+N5LcD<=+~LMhm@oyR;0s0~FK5sZm=JKjWK;?*w_KzwI@FNYyXD zFfF#evZ&kIo_?7Ac>~@nN|4=<$|BBOVy4zKwzT-xl)&I2_zj5rG_qqq^VH z>;~uA9}kb_PqW&jpZHX&re-u>PE4s^>%KY(kXJ389_W&t1htjnKyv z%6{?`LQ&y^`$Lzl2abLEr36c&tP^w~4%@epDkV?s7gK@1iSm*Q;^6ZPOPG>X-e*Gn za}EyUJxdA?!X~DW#etDmxF7lRsCZ#Dh_E*lyZ=l&_a21BRRhhyL+s{soq2>p(svDt zC{kv`yV5z~r)X098Z?5Hq;SKJi&Z}E=fTosNCksLQG{uRfs@f6`UvKF|MnA+HQ4fJ zs+k=SCIeV&@tFwhzEr!-Ou}-96UA671Pfv?8Z9&?(yJs!tVZ&fCezcFe}ZFrtOk!q zNqm)qQ=cNZ9aEX&4*LiFT=-4*4yF;VYpMLicDt&Rw)#eiAQPa59#O1Da~*JA4GZIZY?C z`~odDL=!nplg_34vR{$BAMaAb0aTICzcy>{>X*f;9H?M2s}gZd{$H!412pc`7=SnT z?%X%-fgcqp>MJ~5L?9?oK96(foOpuZXx~CWn0t4)oqH;cO=R9VWKSnUu%;-JA(U0V zo@~KcdN}_K1r>Wg1|Z$&EmUz3DVhHnEFZZ)HX_>gC}au^kGs@YHEqI;M@4PZS;7^? z9=O$4wXDJXy@cAPx3uF?5w1ZbW9a$LPphHli0ad{bI3_ZB`%3|Z)bA5#nQ%;My#(8 zepyTWH@fO2jezCitT67M98I`o|1hnovqTWXzpb19& zD=jAst6zcyOjwjK8R$Qg+1B{fy=xDw6nO)WXJ#+$mv!;_sXJdt+_kW#_W2# z*<@KH7f_+a$3H<}wC0=q5|K1%TcLHw-pf%fcVP4-{}%3N$r~oEh_*M=t?mX<%0?Fd z@6@y8bS=!vp=R`KK2`6zJHjAW#$fU5*_)BAoge0xa z34%~Miw>&2H5^b@I_bo(6I2!4DygmTQX~w|Rc_RvF+-bFM zI{39oIzL0o^A0wpU5Y6UDzlU+2fz~q>5aByzp84EA|;O*0zJzY+dQtnOc3n0&5DG4 zoggsS;VP&}gTFq(XXF*bf+dru*l9L-f!?Z2bHXqjdwWYeT)SgJ3yyoo1W1PibL~`px70NI7BcI@lju?Xa=Fqt{@2BLYgMq#~tYVJeTy zuEh2v;5In-<$fpZu4Di+f^iV*OeLCRnVCwYNfQv*E-_MTJ)ksJbs#Rt?$O`=0?LTZ zlDNS%NxF%Hz%hfmsN>n^-;u6(h6R5#h|EG*N1hrsceF=^jC40)*)sF}~#yb6h^ET=d`b$C(I;8AT;L_Dqg!UWL=g`<$ z29C!qo(LYU*!sNJ=U)C0xiP=FH3j~qW_2gpoC_gIlN)hjx5)TL+Y8$DuFeH-n~Iuz zeHuB2L9;5{GR$b5TDQgUonS#m*SozrY(T3U3VSu1iZi>pZzlXCwAk(}DDoTU-yU5Y zL!O}_;v9-;P7D>%;*^_6QJAr-8&F6h)1k>&{4KvO3lns;#8*P1#2FLLdMa(Z#7!N8 zD}G`xlb7<&OzRdvU7qTHOVenN0syX6Vc7Wd#zV^N=^Igh+X@53@C|08_Lb7|aUB6a z4Kep_AQluE>(Q&nqDj2YD)W63Oz|`{{ZjIz!xmTg*K(KYBVJp{v*9I$?58SmFd~UD zpo#kO@|=*y+G?-W1qrpX?K=ah7O!E2_~&;7gt&akuSL_V-IVg|mZp^*M`~B(;SJ+J zhU_{veDq@@W)i`wE2X|J>(rru`kHuzlf8T-K4w`=Tbdf3y<%I{h~tevIMeNFJ@qCU zql9#Dp#Pm6iQEOB|BzLXQFt{_I??`p!FaF$pBRTZE`Tb23Zi!qUj;)8QRhLvBU@1b z4@2x>Hnx@<)bxW}Na9DQAexO600W%5PXpFfTni=aB!X=XZ)1?cxSdqYQ66j782nbf zfdIcyjOej%tmnwf&_!tcduP^JlPX*Ca_s5h2OrA8om6hUoce2l{LY6OC%nacQNAQT-f+! z-Kq38YV@jB=ddAqTz*9WH-`G(dHUw(I%G;FA{Fj?Z`=Q1G1Q>8Z4~ymYDRWo%q%~@ z+wc{4I)(0`wuTnVPvkt(G37HA#=qa7>CJ|na$;T@C0iLwtN`F87T^ z_!Xww-hF>Jkv3>hWKm^;XpWi0+L^T0bg(Q`iCavlk9*FIUn;tlRB+{37;BxE|`HeL%ZUCADW6C|Y~5 zc)O=z#?@~fSL)>mlw`s*@2X)?QTmf=6E(hckUS1vdYpOMTb zbgSG#3zh*R0+meI$-4vT^d;x2uA*o-4^U}+^VfM|Ed7JD01>7mte4O^I|A~$VhUg0 z^}5ynxg_DLZ6ni#5`LQpSz8{7FLWWke;<-R53(1k6nIsPaS%tb-)QbF6V*`DBH>RU z5@D#!>B}|VUU0yQ8HJ#`8ImO=Yn%Gdj|5|seGzdJ*_C&)&({~{f1i+?NF;RyHTYQD zm8R)pyh`7OyDw4CP>7hfua>v_Va@+4)UYu7k&bt#L!lVKi2CYIdaFY&=8#Tf`aXKn z6Imd9+$to)PIW10FqujjE$6@hn63ggl6NHXxOWzZ(pj${lN=r8Ye=G0{(O(HLCV;w zbxKYo^(5EtnqDQiS~KL$yid|(^%D+t#wDDjaJ#41bhZ93b+-EVuA-`f&F28AYk^(DHs< z!pcvNzXEhdyUM(JXo6~o%}k#q+fnGg95WdYiLry$Yoo*d<_oNH#`Uu$GJ=VNcS`I( zv0EZ-<`s%5ZQKvYX>y!nc&xA@_5c2TcuLcJY@VM8Mn6LP99@N)>9QFd$>1K^_LVpw zcAPzF=ufVU&O!5R$x*&qFG>uBZHCI-?l@%I6QHOhe?j)ncS;;gjuVg4N0%=%ig+8$ z=3z3lGom~x;eYr!{4;F=RR6HKg^v)6>EUt!@&VgN_T3B3O-7+QydQ>#st|^@ORwzk zdzhL7+qSRXL@|TW+UKZf=w^uM@JF$5NKGHnG4CGG`rSOxhh03;+WT3CB43SjrvrM( zh;3cE#l29Fmf@$2Y_Q$NG3&%|neAMObUA_G@X7JlBm&|xP6_Qyf^7=rJf3X~QZ*&& zaV>l^&gnz8IgsoF8jm1q%mk!>(eDDC@R-#0ySQH>=b~n#O8O7Nj^(G#{Ce!vbFax{ zK;XHzW7R0DiUY^2rVY!@J*RkqC_ZxJImARDrx8l%?5y0)d9xdpCt}7SsLt0V>&(B5 zw}4Y6bg0-GWX%HTht*e`K}r{y(k{Yqd(^CwALkTbYeohuxp9e~MX*c}*5aI9l65iH zO8yQ}Stib*6wB@CuK2E2kUn&kB>gi5siw^crxJO{+ncN$*BKRpI-(e|JowJ_38fyp z?lEyyAM`ntXt~6B%24l<{9*GkK5|{~3yM}Tr+jos%fP#MSP;wP!>@O1l3o$qp-9ld z!-b%iU_mZQ2sxXidpz*Ub&!eFiYl^9pX6qqG>7}1##3lyxI6>*6M0p-^CY=ow#E&R zr+=9Gq+1|)?U???w>C;e+u=86@nP%XU*W(kdD$Cx!n{seY=eIK0`N6h`a)c`0>E{F z?)sY}-R4lYDiTx9Y+csknDQ#=CnWD#F_s0jiFldIRrRImBDVU zAin(LS$-Yc5t64o+pu~aQfm*qK}g}BxTXLX&D?3z_qmwDw~ZsRk`Bq~sKd!=C?D}j z&;ZJ^;q$VRX^{~91mU<$Ey(K-25@pec%2kD4Xn&5`iJ2eSpnhuEyNpYnqo*tT{M~L zPHdplS~LJTtr=C;N%&;yerFg;A(XIy{@*$Ie>K|_00O0b(Ail%*l9I}4jFg9wsT(h zl_X*P3#n%?Q1r$77w~_(`+v0y#KWF_jvy|3`pR2!Y6YOf5qv1>sojT1md3%p z<4!Osw<;CZm2$VL)RMl8SnEmiwyc<}t^sw%4W=JP>Y0y|Vl0<|6ijLu2!2s)?_16U zm7S58wq8iZyurg3ZvxD5RZ3DLyp2NoAufma<(=S6L{?H8$rxwPA1wXQyg_siiy^ud zyYNq|{?z65|Jpe);-X4%oHU66DOz1SyYR2XH9{6*Ow(>j!niUc&6t0h>TvrR7N~6( zykWOkoQaB4KL5Egiuf{>%qYeb{oJmAQ*$3yd;*bU76X{BD5EU?LqM~eM1$%WkpTj+?E-VxSsOV3A;&eY`3*-8d&D7}!gh*G(D!ua%q96@i2 zZ`9~zw*T9R+H+V=Tpc1ULWqvYgnM zLuf0;O!&d-1BNwtSqiwq1!5(uruboUw!}$0Vbn7)fG=U7c9K z1c07o2T}C@6>s0NU5Azr4NxZ6!drsTpC`<)(dPiYG5pj$KPUoS7GA?#hHNKVhb}ci z6_w0RJ{sYS+zCg3iEOMT)s(1M=(eilLG6=H=CjTc=rq#tp4<^>3HI6N)@`>UfK%KD z^VOTnbl-P6wv2Oj;enOmzhGbSaoBW+JjjoI9W}H4t#D0e0Mxh@k55LIH{ZfD}O^TC;SdzG|k4~nQI8V2z;>@bLN{6N2F_Q{Ts1aN4;PUqzw{TIvlE% zDIUXE*DsoVVi#Wgz@gOQMb#1|9sjL8BmO+FH&|0w1eYci*gA`8a--iao@^{~>UORy<5~yZV)6 z((uY&C^~mtZ8k)KR_|IpIYPXn;_{bJ7s+9dxCQ=JK`#bQ=_!6%!d))6J9h5o+F|)j zuedwGw5I5(LcGt#38y%(@;*Hbc9w`%LHqZQlHogK)X7|<$e*obB9E;@CsxQvI*)%) z)ujVxjoOV6m-MOJ0_#%krysnto-U6@7=Xho%Hns4BZUa;La5me2&MlJ)t~={+2FW7 z-i}QKl&tP++-ihyiDv}x(UdEjRh<V%V~TNhj2xpJ{9ot5bg5q60yVZ3C$5&@{mf z3>}je#8iI5m^)5iM|uX8hq+Oh@viT+Gxp@0u<;tpt@nR6y&tfzXm^fKfspJxFn6HD zMsM=iM&$;Z-}L|6w0B1!{Fz$ZuK+(@kYRP^)2bMq5r*6g$gtiZ{CeKmaoXh0@(rR( zMI&+7ZY9h~$NvUF*LdwqE&eyHpihzjD@r23-qZbtH1EYEHXpUonz(jh_M|Gg1H7^+ zPb!7Ejc)K8WYoShc(a&v5dIDFMm3!?9a0G;m{7PM&SoVZw^0m@!#H}2X1O2*O*g^FI>D(fc+BQL;(0D=Ve~CZcRAQ zkV+^ioI+w9_iHMr_-+r4E_SpK3V?bCmiv3_xHSapS7{_E~nvm^hF}EWYr5ISptaw$hgIA%+jkz{0<76Dn63Q^BJ98QA4ul_4?iu)EPV4q%DKBS zoXuDaqUW`mJz@m7&16(dmkKm~E_{Y^R<+w^69w!W3#j^+?6j(SXdq@P#X%gsk!cpj z$n}=`8Tfs5e%Km(E|bvKG#`RRmJ zNjNN6mDehNiPU0HK3S$jy0O&zN6;B1hIzUm5Orv+6b0|KLdbNEKe6$=ZY@eW!JVya zOtc=|b-AE}^>*qCOvRgq1{SG#4=C*@$JFIC2rhah?7TgwG~u6!k6r)wO?9`0s-&eD@9pw%7M9-;A?4#KNL>SRJj6&xPsf6Q>11=11L61Ajh8v zQq*wuI$M_GXp)}(1Z}MKnkJUiyUa2t?B4qJ%vbV-@O z=z;iLzs@bMoc+*ejBc1~S{P5zm|`Ajrc3Mj>_z!B)~O(MBOMIB^f7&yriVrQW`6jCe<$-^wA<+I71w@ceyha;vtT&h5L9W$ zJ}y-=-)w}@d3=@7JwLDI;_jYbS&5xXa#p~Isp3`~6zzja$5sk3*9~z-BB(;KHmS&6 znD&wvzVUS&(o7~lk6|4DiSo%FXN%Gcgui9#Tg_N!;nKNd4 z13Lq%nU-2-G*lCRk9c9QH8)V~$hLYp}b`CbEE|qRP?uK+a9TG%iWK^vGK4^y8Az^t3eju;10y)pY=d+=g)l zWCBDwm22IzM4NO&(wUzLH1HxO88=As8Of8Ia!s$xqN@ITmf2tt|n!Yhd)X& zQSCgC4l#%lZU|KO5aj!vDI1Ph+%>NY9Y09jSq4?EPG!Ao?qwA_LRdTJcavE*SpPBh zx(&TRH0A1_byqudfZ$CBCg5a6q2bo!=Dh|^UT~mW-P#dBSDdMl`g{p+XyAes;Nqvn zlQ3|cvBQ%Qw)X<0-qVbTe~35rqv$cA6N7kh6U><_#EG}DW_ z%fK_?mTlWPL-5b4Mw5z;&n$>%@GY3miS2EVfocBoRVv$1hswF9Wcn_wWpu z@AY>q;}>d=JgtI716SpV{xrBqh2dLme+1e9%b+NRvmOts&4vpr$2M^FNcLV{Y1X^= zmdp018$UM&4_$P))+qm>C}1Q*zZ31*Z~99sijQO;#8ne&p+)@25Sc$6+e|3jy^>B2 z(pgvYL;;qgA7w7CXCbIx5`L0dJlwp|sBK*p2mrg4-`oKUY1!}Rh0G+#Mxh3(v~^P7Gxh{s4}B_YtB+`aM9{>59ddKRfUc4dGtS zk#zzht91I|vbjK^jP?Lb!JL>ULPtNa94}rZSLD-nX{8ql@qi8?p#0*uVu+KA%>XOe z4aa@S^3f$v!$YHa<*xFODmv3sw%lceOT;%x6Yh)1U~ozp!lm&FKgG}E=X4F!lvGq= zMDZF&A;tYv@ISb4`X|$OU;D@g22-0)cOqH7R@Nu`h2GS(3!LjWjK_Cg4MG^s9f;l8 zy_Q1!UH9bw^I*S{OvxuCxugLsB*43u2InMQ)*)CSi- zfB1jBtZoAHQO2zbD6BH?2Ma*Rr-X8g_c1KWBO)hIGxyqTuy9;bl;pXVA4qab!9jm zFsDC)S{9Awf8f|`&Rv3D+tuo!&?Z&ET{~w-CGPhJ_3Gby=_nRrxW7w^P#zT(I$8|P zkPiPyxSCCm)z+W;^_fxYYm7kQPZ&fDn`y9{=Gh98&VrqojZlT`A8Xjt5LfE>>`U$* zDx62E>|2ld5(FY9-Zi!i50apHLAZGXFam#y?;0Y)DwM~ge0!4_T1*z7??807i~PP) z^G;35USwpDEy|l*6=P={GB}5qbE1w843noJfHW}mQ(Z(AWi4j(0o4%~?7DJi$dB)o-p-@;RywI~?)gDb^ zhVaCR)~QK@7$NhIU%b~-g+S-3;nK#;KGq+@Z8Rke8+ot3%l+x=dj zOv2YAaGZl$@IAj8RCO0+%lBCM~b+?_Vc{>yci@;}9yt`lSFtOobd?MZbv zH`wLc)w2DG|J8LUOBZ`KL_SYsCY{lU*K*WFx@Ot>)nzCP!?kXIB)4(|&vonA*sS?m zl`!d&6lhB)%oLei!sgBZqdKpfxjFb}-{?>+FoK+0wJNT&KOJjHoho#ml?kJIXHwl8 z|8xX&__sYqK8V0rCu{q2SXr%pSPR{-1@-O%3sxTO6PEnv2LBghA%`7^>m}0Ab*oGy z9;(}t+>I8cgwU`~^_J(2`|K4TmJZI2Kl#SW(7zcO*B;87Bnn9dC|lBDg;Zw|7tE`CaS@C^!~-C5Gkk zy?-Oe?S?G4#8$j!RrwJ3&|*vuvq*Guu(Y;v!tu)8ek7 zb!BPof8$BJvgMpKh?czQHI^3M+!#4ODKoJ@x4V*YD5uv|@K&MpB+6*@9-q}1WXx^u zB52pV3fFicd10#n*M14&%d~5on03){kk%QZxZ%|e()1>eXLd$eOIT1X=BSCD|2lcf z1G7Ub{Uk&CJIs-YW}c!TY-GEn?h=fznl21B&^Wf=7ge9JY(pZ5PdhB-H+7m(cL~Qo zW7r3~uhbq3;}i)Xi@*|JHe;n0DjV{TeLS?mlyIOe&X-BS-3|??u+IVdL*HR4<^sta}xEnpd_Tx9P7o-_-5ecky(uyax;ia2`5>VPrq)Blh? zRUd>Lx@*?|(8wkH*UVXu^Yyx2jMj?<+j%LmoH(21+5+G5?ANmX-9%(%Kn1Z8^)-ED zy_=E``;*sn$YGTT z3>49jUMce}m=S5&ZZeB4YF~gPY57#@th(_by||bmv%YdJf>DR-u$*7QD-`2Pat-6O zUeAW&=h_{BOUj=BP2YfDrwiT8LTFlBlm&7VJ9dSk6f|Kin+kuhfsy0zs#TFg%?Y5x zVFqfaTGfWz&oC2(RU7=Amd*bU(kwV;m-xBwxm&_6`}>M-UF&Ifsgl9fqjGlnJ5L8!9 zs>8CpU>%>FsH&+2hKHjZ{u$}LSvSKcB;-2C%g;}>VQui{7X^ieh3&xDOu=I#fya9y zi!Em8O4*{A1_lOTIXTX37`YspX0GRsEZPl9}0n1-M9P1>k!`jzH&bO*UU)7~*;||Mg%zGkS93CS#Qo z7YY1)b9qTp(6G-vKJJ#bBi2Z~cjbRSq+0vD^xNy7d1$ zRyawxxM+wgsza(UO8r4DnBM9op9;DeKr-e(yM=zkNxODVVi`T&fWEJ)?{=#f}Rz+{JqxoRA}U-Q+W`WPcUHmox#IsCDnr_3k)IN z9)ojhfDmx+{+xACW2E>Vs>7kVNJLR_UGm)uqomjlZL5K##%a~MJmb?QdI;Q9x zqso}TUxIMLu>D~88+`X%raxGihI5C1EonDxT?!iVz)UkCFog-5o}Ugm2Cklwd-$zP zL+rkmG@VOLito$sHAaY1=JgIGOMVC5qT&~t!n@+Q$U6|q%u7f#F$IpzJ1unduWY7Bx zddgTX+l025A@UbR{dv^w$*hGPUp^WfD%!js)&xw5H*Ygx;1KAtG8^ce9V$9VV~L6D zXydUtfjPmBXiV=2pujLDUCB=ytl|!*)cv{AdD%sZ39{8)rANi`)5=?bsJZj2rPZsVg4ci4hmTJuKIwxRjJVinr zKaNT)OGFIDtTC7*&YHkz)`#Z$*-6&u5m=^M&+L9Q{X2z_^$SE4Fj=f#G!jc8MCkhP zZ|kOhYUL8NX-GEzWI4H8pbU5KJ4EQ2DmdagZD@hHn1{N=qGbo@?T8>@u zc=`_b#w)ecSJk^g#Il+wE&SPu^`b-Q5>`4w-2LFe z1;i8Kg-?(bXK#lw(BU=a!|>$aVD!4xyTdoXQVg~hlN6j-M=G5ue}+3z{yg70Ogi6u zK6CIp@jWSTwB7iz6BD6#2a5@M`mfs^MBAPsnaI%pvgfQAd7afapa#H5K$G9r+&69$ z84`u3co7Ty{WtegjMxePpFI8+2A~RC9gr?>2e~Y4t$U4z@vW!1rZ|MQUAV=yA{!VI zUxhChI=WMQpyq?20B0&dhQvgJV;s7|rJo@c&LFQpiARan0A`ug>9w7V9MY zf0+Na{@%ySl7h@@N8%@j=IRx4x<9MHM-8`UXChSnz!; zeYq(HR{SvA#NL$97PstFmuz+Up>;MS!b<|>mU^V;ag8{#=QuBp@T$tq;*b>b+f45m z_}iL6bU$k|x}{}SO%EtE~eb9Glbh?s=WPa0fPS2u5~5taTnW}Ag_ zmX$x)j6+_CHJ9X28WO307{ zd9`GJ$iY}+bFNT{uiSrM8Hm-E2(Ozt+~#?3Ulo;IMNqDXp`;s-w-m{MoTLwuG&@R? z^d|0S3j}P*{<^M+#yKQUu$<$f2}{eI6%W^J9Hv^;zVc>ib|eOnH;K#>TPVkTVwiJD zMwwvVXrG+HJ1>@-)yqiFsr_eH!Mu?_ZIi*6f|&?=V$E-f7~09oXHcyQFKZeCb3Un| zu?JtZ4CXT4q z)oTsjYWeBShNJ^p1gJE7g?U?w_G`u@&6USEYp1-d=dFDN>J(qr8tF}kTywQKS3nrD zL8VRS#i>PCMY*YH9PQlfAj;_Gfb=7I0Sb<>nXELc`(UI&Gw==#MXYrE`@yEk$X+|; zF`{Y7m~1fW*uFLX1h#%Noxg(`6g>JYzr zA(>iI7Oc>LbNC;`D2{u#ER}n=e*A4xW2=U}c+z-an2EdKrrW_f^nP~s{ke^tYFb0U zMe#xUQ%9*SidYXxb5UWRxoq4;G6&W_-rG~wYv-pQUe;*QT6NdFw`HDJtpoo}qE)@c z{+X(+kJxy@%^Bj6YXh&aX#3*du|p*X9QoCV49v{*>gjb^LXgqc8wek{%qEHwyJh}Otvqy7=k}4 zt*BU*ou#g(X5IdMt0!h}G^G{c;zn2vhP?&}3Arq|>2aYRT*F4EzgcMn zELtvh8yznk_+UfBED?6lv~aDl?$@j4#H{@P zRr^oD-F-s^U2RicT?g4;H^ZU;UjYoTD8LtxQUNUTkIIRLBEjJef_DV*ehSL~hwZM2 z?FMV{b;4>*10L_NfvV6)edE7Wt75wsVoa8)n#-c7p$V}-^>}QywbTi(*o=LL@;A2k zWAg5AjGnXzF6YYzmT7{4&oIx^I|g?7&5m5Qg1MXAvL_U0A~p+ut%{XE^bcG(t>t|g zdTl1wX^i{=aRyvMc3EZ6OOhW|7psvLs{;7yW6Ug}xsZvc_gK2fn22 z0?NN(qe_eHxAJdzpWL1JL1zxzX_xoeE01+VDyrPD`^@A#WX=x-KobC*vbs$b`XJ(?a{@%<0k(oCdl!N%vOb7Wa2 zX}hLJS+0#KhKB|Bbqc>Szcs@6?$SnlV(J7Cxd=n7ju?lr;RGE6@FqevXGYs$tL%Z| z`7x#wBNn~R`b7%^0n_ODESl=6;{lqU^7=SjR9+Vt7GP=6ez$zGa}WJkI?s6)%qQgu zD8ES+8$&M6cJIizv*UZ8r|kM5q$azAFcr$@bxu>5AeZUCiV1%l1|6p!-{V>;VV zr|l2F6}{`F0e806on~AOimiXYd6403F-cR@c#J+_7cD6|NGm;k!yTW@yN2L}P!gMR%^34?PZ3&cO*HqN*I@?GX}PmJldsk3l#=B-2x+fehUo5fn> z$1l!s;Va*=Z*WXw;`#_U=XMbz#%7C#>Cyp8(Z0A@KL7T~uoqPeJ-YJYyLhPnF?ebU zH%~Qw7_#*6G!#Sr)W(H9hpRg&2z~z^`U8LRufqP!2G{9mfw)ivd`nQcK3a1#PIv{f zN%$|k@74eAM74`O7(Km10;BDgjH0|wA10l0rZb+8&y9_Z7^#*0Pb1~x)82_C2;p7P zV)tGx_fnO~q-Nhdh`%Mtt4@#Xx`6S{&OgE7euUPmk#6e4C*cxs6(IcsNY6Tb2UXk} z_8nE^i+_vRZNyI#9_GNBrm?$0KK~%j0RO>IAu>fspl+o#v3{<|p=)d=1kRJD_7^-; zw9nt;Q^a;#tZ;K=8#RtB0`kAk=e>HQV;N&I#Z0n~sG%$aMVJ@av+BvPQC_Rs|^lfv~M;?P~0ueDKPpMa!|zCS+in)6~W{q96n z@y*+s-#`q9L-nb0vt9Uw206(L!9Sd@gyZ@#e{yt50mm=;nam+8t#RjWe146T47rim zjzqt*r7`4_>8A~h=20igf@dk*B^;y;Yxf~@{m}4r=rD;>d!+n2VQcfEi5RjTNh)R# z*rSh68c_TZ?kgr7O2swIGMG+9eu(0L0w8+g=9l7?rtSa|DwmMs>QbSsaDDrNFZA64 zoUrFx3Jzzm9f>xE6h_FAIHd=dECP01LF@$cO_^>;?lUkH zlbcx~O4+rUlbNP`T|A<*;s`|H;)|%$NKLR+JYT^KhdBMtha0q{EfxEKrhQ_>Sx;`@ zjN8<&41fiT?nkj=r%=;lIdB0vjGva3QX5E}Gfu|7$Jd1GjAi1OK(5WP0Q+$fS*H00 z#Y`E)pEZO_^uIIg!8iOE>y-;bx6KzeO4RE%jMpb|s-F%>sOM9tUca^|yQem3#IZ?g zbnBe7x_{QfD5m{SgjD*-L}heWz0*%6lJ~KrIJ^Z|zPfi6U3>(=Y~0wr(Yrt_5=70g z)y5Fb2x{}Hr8fuf(V`okH@`95Q`Rp)y)=xZ<38YqXn!Jp!m*?y)v};a`OH%p*)&XY z)jgHHVOrWIAuyNp$1=`e%88XOQq4?QWmBPUD!S-k=a#_&d|k_3bU)mlJp69y9MRSd zhxaoUn4UjHHZh|QGO=&zPMEGAcGCpCjfMM-%@S{_gg?0E{~}7QK?$x!um;DYJ%ial zL+*FCb_GpG&it4i^Xdh07(e3=_WDOL;uIp90ujp1#2rx}7eS`V*TW<=a*u4vS5ZNV z@vMCCaP9$$3^_dHLBnyOf>dYbw<61e5PJq*AgJb|Gqo#X20_g({7X>cPK0Q?hviS- zsKk;Epc%EijbF?h=ec0PX!3=kbAi~Q)z3HdBGq$_4DaF2d!W&SR?dHd`F*m>{_2y! zKRorgyha}uv<+{4%DaH0S>hUX#o&RRpiv`eL)0?+WnIk$31#T(>>bz z``Qr6Ep*$3YySAn6YQjs781Zkl*vq-cTBQ(mfW8vh05W!iqaR_kC z$H?#z#b-+q4Azv1+@^6V5QfKoi9+znka_}*{~aP-6WJ$w%APbd!ucfZzKhF@48WzD z3w&KVoPrud9QbloPSu<+fq`hW_!n6!{9NHnI~h6*474Z~{h2Jd&9fy$5|}C3o#C0= z)iHVh_kYNU4ejYB)BEbF>QC6C2tWeBf?$|!Kg&~LA4I8#BEzy6P`B?m`3tFUjYi5t z(Agxk&2RqPtTXxLyn_Y$KI6~BFP!fF`lCfTpLN8! z<4N;m_Ls3f+nc4I#jR~s6D0o@Eub_F#}VOKh&;@Zkh*4}ZkDGOR}J1l5epH+$@&GL zXdqxB5XcV-&B@I|FTNhvPcM=_qGxskjm+r(hH6reKHv3W95ok?*3O~_)q!#OhslPb z|19Q8X)81IUvFVZuYRqivB$y+9&QBmcA1-m-VjhKGP=<+yHdx$Q^Uy9Mb0D*yiT)^ z9gNvdf-lN_!IfttMGolYHtywDKq`Cf5_F8u)CT7aCS`ECMv1j2DwsNuEeIrWrH^fq9 zr>C%$Kh~u4zrIMSYnX7D(6De5HDapL*_wf|DiZLyvScP^8=K~46SP`)E+%Grc;>L{zry6uEE2SF-HX$;3<+ zhefChnM6iLzwGoPBH2!^%vP5U*91oU#_umwU6T*Hq+E7N+c&b_=}P@v#z@5Sq-SE5 z{()sB9;Y7Gu1`cVn_}7NL_~6X*q0@wzLAcusN{CYm!(?RbKHF zMfL|!;bCWV=%3U>J5*WaWTuiAL)oTF8$9lU+S(o) z(eW_79oM&DDLVk&5gOnz7e^57Jg-uS1fku`*gZI}Xbw5PBk>a*9F%U+jJC8?3U$rw z_>f%_sdb#hhYfIO>m9s4Zds=_ocH?~x{GnNTh=6Wce(A0_J7!V>!7yUE^Zf!ySoOr z;!xb(rMO#>LMiUW-QC^Y-3qk0ySux)oZaW0`OX~qXD2fudrvYUx$m`p>$+w!-}uST zxXp1Vv(y#I^dY67_waP67C@Pq1@f$X-FU~0YND#6(H2oJsbHDnih+!pXY3kD7FBU# z(oLVtRe~H{+A;tUYoFx=kMI7YxL8sSIgoy(Lz)^G7Ivw};7K2iB`)UV7JcSAv$>!H z>Vtz!Q&~&m@EBc^cGtmD_0PukL5NOh=VuIY5{j*yr8x36R@O=wm(VJR z1`>G}zUv7LB>d^92No!;3&2;G;)>`TOPejZ@_`wJMR$bjnqc3CBe%|f!PA0+(%&9G z+{Ftlyv=57(d-+#2VE?syADuDP~FTETmkVUZjMOxQzzj#DpHjAJC|Gp!?T;uTF7xr zxR;t8jz@4Ir+AoNJdLvQ=GDxije218L8Alo(qZMim|`iik)Na?5JO^{lwfY}!8;|J zzPkPJRW~f@uD-l_tjZY}mgRO-4$F@7pzJG)W)#u-QMp`vUQMYNk0{7C`z zUnG}_xuAIiw934SaxDDt_;xqxbvXmJfp~P@nEnN&Z55bGTE<`J`&X38`d6A7+)MuW z+YYlfgx)F~YmU;!=TnM)RPfi$`PKF|=ewP_RL8tl$ez2_VEjdT`>vI>?x zBL~hg%_OSdU$k7*Ebyud^k>OgQP4$~-wc@LSw>0rl+_j8?LF+$c^cy_iy|pX6s*mV z%ZtmtVJn%EJ#5H3Jr}VE?yWZrT5}-0!YJmmb#Hp~2g7aMv_S4$YLZAPKVJIFlohgR zwV3T@`QcA=k?4HXpx1XlF3a5I89{jY^qA^;J{Ob%op*o#{&++4>H(o%>O&-Vf=Eu0 zK~;2-U@Y+KUoiL7f#}X&l(*GzPi^&u$f4@(Q|Y1%Ru4z8-4Aps9B@AMsQ7n*lU57? z&c!aIjdD`JOzc$GGTtP~|h_C3X^CI|YTL5v;8`gN1rHJ6q zy_29zlK}89N@i9fOINLv5q3{)EE3Ra=fO%_Ef{mr(Xlw<7|=_1C2}_sS}8os4s(+k zbkXZ%UeFdh)FK8B2Pg0DBF)jM+xP0FIovPM@DRv(gCVl+T z4{)l({(4kU>O*F|NdtI=jwQ`e;M=Lyv}<)Ewiq$xkh_p=_AVHD_WVK5$JAix77ZUy zm>3v0W%2PdlGxbT8-am=POh%5J~9>-7QwZ(R}Vm`fn@4?%crNOr?pW)cP1kPpO=@X zq^}<}J*~3OwpNs#o{nH^dy%f|tE;D1{@uzd1;^Oaldq$r12;F@GH*jmTf6Bel)a;) zn6fh3^vnzz0l~|wn!GPM28M7L!nMh2u#Xgx&tK!*rY7v6p&>cty83!FLc&p>Niu+y zhpWq>je~;&9m1nlQc@zMuTPBOlHjNG1sc=hYZTSA1wTK3N(Ru?W5$xF&w3Wk0mB@e znZW=Ajh}Tnme0p|>_usYx_EDPEvhW^pdcZC_dlaa8W?Px1NP&OeZT;4zCvv_2*(d&U%)k1d;vM;1!*WAx8KvcQwkav;<1L{Q?V z!rB!_dd^gvKVH!zEvB8&DE?}f4;UmO&pj?qd`qt#%)1AY0!TaIApdwmLy`g*HWDYX z8N;3l-0K^N?006$AO&*bC~U0q!Up$jflURD;t&d#poL^q)IK^7OS zdE6ANB%Y9-p8lWt8jimkAQptG2|_?XNW{Ns6++H@EoV9V#qn#N!MC%MADNhMaM$@_ zy)z~zCTHBAimC|)g_zlWTX9(YQ9BaMa(0vYOvU2+cawoAq6kT*W6h)My%EhCLm>0T zsU6FReGEG#$WB{3WjvlONV0>jlR8EPSzaX)I`{3X8g_0~5n-Yk6wT;}kh26jy!{Lw zQu3$JurOo5x}6fUsJZqTvDS@eH6Zv*O(J7dp=bS&+4|O{Z)!aV{Q3RmqSRGh$~r+t z0$s3v^-MG;%mLw-{*`p&-wjZ zNXN<#0J7!)0Y~74TiDu43JZgW1g1`~#dLRjBXCHzx3_0QOnsCp?WCHM_C_FOW@gGE zmz9?*YiSKl{*;u2IXyjfg}J`JuevxpGaJ2cYT^vKESWU5u|di@h~(qTVpk!x!d1;F zD4>wA$P++y1Ln-!w+C~DZlNYuS0hqVQV#s#sHmtm-PS{PVc*`~MppvnQHXq{WMxf! zLINW<#DXbS^?%nRbI&dWBrSU;>{I75^AbO$))s6d;E`VccnM)5ij#L79FOy`7>XAY zoyV%-DTm@I@Uen&Sn_K<{fKHkRjJ1c;lBp=3p5b_;~O1Ib4B~%uvAzi8|!AWb*LGf z{LNUdLi9%lX6?o2bz>s?9SUv2tbex!o1eY6F9}b6)?qeYm@EaT&Op0{ISqcE(hR16 zF>B!3)x3iVaiRfO2(+Tk8g7QYn!z2crmCwTIsB6toS@TEXVLFfgjA7EgOMO!1d7Qt zFBiFrK8AY#4CPv6YLmgH(~+Hio{EO$FwgoxFFqDi@!eWG6QU&CN)eY(0^1W1J$W=4 zlc9A*pK;%uMd)+Vm&(sKSCkPrCpC+%pS5=sZmJq1aZZ?Jw#*f>j-xw0Ep2xG@*u{f z-H~s+op;mB=lU$Z>!@{~Kf}&ato;>I+?!PsbZ$hZBa89{t{aY#*>=1TP!gL#K$u*EpX!5X2BTnC#`MIYh`(cr>s ztA9Ip82|$}sx!8z(+nQ6s^4jKPQ~28!g-2v;?hU|!-E;K?A^{^9(`&}?fSRBkF0NEWe^g1mPP1%XCmID*I49`~fI;0{~uyEI@*1@9ouDT1THY0Fx zn)nauP}y0ai7B_YiFE_l-^k98&qorDc3(uU+hbIg5LQC0E;;)5|38TXFwe-^Cq8FF zx&LqE!2Z>2o^Y@Ah41$BM=wRqE3k2-FHX@;flflgTYj{!dmTfqW?HuNw(NhWeUOj# zNLQf7&9tCLnhdP&?awlpo3df_tQUOj`Juk~M)aw8uUj0yjocB@UPP^hdR8W?Qi(iI zSnQ-x{jftsPy;Cwo2MTuWK}ns883%{aM11(5P3aJ-*v^2>VOdo1&0^8TlGDMb0Yf- zYe5J3+#dR*1*~MiiGxEY=XPAcEOQmkg=7kF?dW!s8+}nNQQv|l=Sh{Mq7*!QgzSWL zOA=3XOr`GTK)YOgWAYAY;9sHR?y{pq#04Q&C%~yC!Q^kTea|<1xKv1TRfN>ojV1)* z!dD8qvQXI~FlRDnV+W;j;MU0ymCB%%P8IEi>{Zd=W=$dP&5zOpe9FMTOMdFS#I}@= z6>5AyPQV)%3H@u2sZ%8pdqjqr${YzG7d zpKxqFto9kTs~VghKo&XzJ>%pDcG@C%EBDy}WwC6WXM7YAeY~Xso z9cZ1A#1iecRozJkua?~9GV87 z?T}I_jNlk}#}CG5$(z)+JW4RzX#qb$e`*&5S0y1f7u^DwryK>IZf~HoZco>O6Y zM!X~GRvi(6qksf>^-c_q4fdvV8ThKoEiTvqg^dM_>~Ferf$^ovK9NL0lcHW(CcDD8 z_yPf%kZ+r6B~JzcaTj=l?nJ>I6I!_9belDMDst`Avjd4T$f>_zip6Xe|9<~XcQ3$T z{1t8y3RhxyCt?lymEp$fgjz+!_U9QVFH$$|a>>n54AAQom7U$dL-%UHg+{C6GO9<; zmPRo1q`2!1lF^?*3`|ao(uUiq=M@=(+`Xf9Ib|vcOndh_!0KS4ygepKNQa)AGa&w| zhH<8$adWP!8hPGjr`P@TCsgr7OiZ9`h1_`7^G#c0ZHhe6t=@b?K9gnVEYvq4F&arb z<=#F{s#u;(uYUq&>|nfqo`?sxzlpj?O&61E3e93c2?ksx4YkBThYeY}_K!UxbVtY= zK6*s%q!1$1W6Vb@%WCgbd8t=_r$&pI z4)A$Vd1Gl_3{7@!1A+|o^xGQi4Fwv6DkPe_g3W& z+n~^$e#xiY0#`1v>NzSWztxl0mxnS;+%w9_H$^9!b~Zxs0ttA@PMRIaM<6fhd>5J( zbRsK@fFC5IGgJ)4rD={vxwR1fVqTK1RKbX5qoSeReHaq~Pa`Wtk*&QV7M_kfm@+%1 zv{B!9k|xLaYYKFM$`RAC6E@CPom-Vb1X<$oiB#`;R*GmUqbArvnNbvsBAYHx+NmcjxWU3Pw!0p4+?}H#^F-Hw{l0WM0}zi;9!o8W_;#Vrk(nRh2Qx{XEX1!slJ&V%+H`KphLMh(ys1=e=ra zfFZ_uyDY;G2y=ivURmUFPY(84qCRiU^#_|u@A%GjSw-y5c&n>NfDmlk{&OQ)zJ5*Q z*f=_ZsERw0mF$PX=-_!fXNirG(Z^@%^Orht>85mP{?m8|-+=F9G`R;>u#-RFV9wi- zQDnIDTQeio2Fy|kB;olrW=4CR?RbBxMb_&AF5*p0x>rS1kb3imGMS{(z8xx*@PH=A zn6-76F+^3Fov;?=^9v8lyT%7yYjlUver#lXP)4DxQq=ajLPJC`=2cD3RIJcpvr%usGNU3-L|~U`R%#i z27lm0%kj=T%!?ov%36zb`oFwuUH#(xi=ZH|H(IeLRI*|kHB!URFV=*t@N<%KYr(~{ z3Ws4!+;8R$`Nh~fvngz|sii`#emJTNtA6fYfLAG@UqT7pw(@+Pd9ZiQ=PG3W{TV+2 zF3?)M?47lM_cVKZ6P!)+G7q*x4d`|VCWP_XcB>PVyVvsTu>~d;udm0GuWY2c2CiY# zX&dZx4YW;KO?0>VB|y=2uE&)euWB5~FKh4wEe8Hkp)-qus2n;}Sdj2vNxCKrHesWN zDvNG&>8_rScMMG{7O9{d7XqpTxa{WMXYG>)94w+Z4iLEe-Gk<_3drdOnP zfsTN1`A6Z9(_qnNUxsg#E@Hz<9{m$04;fP)n*`z+hXL<&udBN`xmABo z6}zj+0y{4IO5|7lVCWW79q>`k`}B=gegk{G4ML5jK(@CBptI(dmyfu<<^0PSBbq&> zBQ64o#gzfIrXLsSYxxx3(cr@>S%3AL-MM#)qj(?-ejTr_t_n?<(M=o|2m#yR9p0|Y z|0gFFh%lCUueCWXwmMLg-?H&bcIOM-F5CHbky`>Nt^boTnN3Bw!z5>99B;|U%|7CO zCh82*=VhF{J(@Alsx|(5Dxc1on91W*_5wH#t;xIqvK9sOyYa%J%HM zZ(&7q@fM;F%oeQ_LLYYU5xOE*O2*>`kDsO+JPFUx)%<#w&kxFT`7z3Jew^ct;ly-# zklB~;3puMTq|8koH%)DZKW4s}pk=6p z?p|jpm*+M{5al=-uPbMTc2np>t!GJ4nAOxAO{Y2%2qA zgt&eZyz9)cj)r0GZ0k7CKuIJs2^<7DzTl7KivE9H^d1mHsY#&$jgKAcw~PGDJZ?@b_1CQK?hmmW(zJ&M%B7>Ev%+4jc|*N zREBeDdBy!1Ay88+B)QEerSUoQ=b+Oh`BQ?vm`)CNF=7D>B6duEF|~D3OmhJ-{W8vJ z071qng4g;4hd7BJn&KYo5lUo&8+U!<5T9AwkO()l=3zyF(RRj&N(p^^UyR7TqLgv_>IC(Z~6hsKD|G|u;t_LGwmrmlp1Tnh#70_aq=e8?_ z?usSV?AgQ-!1X2>CxECM>ewV|NSF|ZiXL8Tu{e3gxuOSO&Fc*R9883EjM7hbyuZJ9 z_4EiwU>@hlDk>@llhi!jN^qt}0>1iwaZM8watMjeY&<+XB>yXDU}Dj>fLu#nUOwOc zp(3RNT$#igv!b{-7(8ELJ;;F*-hwR1Q7K!E|8=C#klnoRFChdwnrOeoQ#2hkRKEUp z5PyFpRGJTH$Hf0?8zVn!k_Oic%)}Q~6#2d}zkL_f7Ur0JQ98t;6@gyfsQ56O@|jZP zy?G-5z5R~nL4X-~64JxUy{$dvvjm~asu7-onF4P=IB-7Ro5P|#wus)l@C-vRS)%3{ zvT0CccI$DBycUjfx;y$^sbnZ2$R4$E=w)(VH&X5`8-U9S?3Ib$Gmiu)pou5^@D#lK zibR1(yQq32DYZ=&USz4anrGwT;hi*g#($KC^F^Sg?)$onr|%#Mj)0N(gP~SjBs-nx zc^>PdfXdnKrP!5WWv}H{dGP$Wr;Q3&ZKYsm1yk1yr|!$5Vg3ppVo@d}U9xeBE0T8K z=PAPP!H@`7Jvx#}=UKXE?Hzv^=48;kz|jvMFrimWK0_mL=8$_3u|v%FGP@F3K_D4c zd;YvuHq|)t;%5l0Kjd}+tDtV5-0{Y*1Yr-_V+1Qq;^RJ7iN_b?``s$21Bns+FzQKi zH*7r(DH4QQv4HibD0T!E^|ES~q*QKW|5^_1%yZJOAG^El$oz>>`F^`Ol+%dfS!qAx zFaV5`npZg2dH`DQ*{n2aFNE|*mP|IPm+KN+o$ApP)m8Nwt1!NO!FXWYUx9m^WB-GGtv=*N@t*Ve~mSvZ9{Y%}PA zEalNGuc{K}K`x)0Z?B{>Ju;^Oz9hIhz;4yqLhQ$H=>u*h2L%y5`tV(vw#;&5S{q!x z+2y}M9=dppOWFNU&Elv|uV^cX&B9~+4h)lGJQTF}^~BR;4Y)<1LaC-jN{oE;5V zqzTWV{+W*+0M)C<}wuw1$Y->1%1=<6s z@=IJlnnmQV^qWZ?S9IJ?Y1^;*B{gBQv!ex7REe6&6AhPV5triwUs~~;v%loYg*=Rd zC|Io)j2f3`or&Nx5)p8(|H5p)jpG!8&%|0k?sxxM!@P^{=Hw{a5YJmTST2TCI{jF1 z3HN$;ujG7Zusjl`xmof3n%^z8%ia0JXe)l@Zk{uEP@Q4?;his#+EG_tiol@in3$5! zdP{npAt2VYXAp!w`_9KjtJKkx{>47aTFBvC6tN*7hS4ObDgt2QZ%}93C}Vg)z){_7 z(ciUUY6Oiszg7u+T=Cp;JmvB}(DA6==diiKw2h3$nhyIAZn_mwt=zBV7GbvCiuyYe znS64EXk;;lP4uSsuTD)<=|-{``YLH2h(zZXg$}U{J0=|$^3^r??+oUfEx}Ouq_|!k zqjs35#M#JsiNcPpfwMt8{ZQ_9z)RiRc*kv;&_DZ==@3<&d_PZK<*~9W!l-EaZZr}@LY&*2=RxbHUENk`{7>q*Gci>Ay+i14?|w%8yFwDaNTY%G%19XSZ|}2x zvqKA_$Faji(0M}~Rlnq-(n7RdztUS?-^FOJa~zu9^>H_WSAB&=O{9iHaz!^l$=-EO zn0MO#{q{KYFw1vYA_4<$uV|6MEGf=GB$gbJ>8Ti*tIAbI?g%8bUx%Gf)uZ|g5ViK5 z39Z!;H2FUtT9u1_cRi@<|n<<*??j`YIlBw`X3=klcjSj=%9U{hUZUNEJ{Cu`SSGTux z#8oW^GZ$S%u%x=^%Osrzv2G}!-OJv@8{E89v`r;6fH|QjyVMYX`ceup$ybApa?cdp z--AV%s0Jr0F zSkabixz{C`=zYzLoh~Chd{g8lQ;DD7xfhMVY+za~<*AAflDQwWzLsIvfjCjz4Vmb= zGG`A*zSUsyr@YwTxitp67BoNk6a44QMcf573me@iMD2@MlfB4uptXi&-6dHm`bW)z zX>(irZ~PEhR3`9^eUO9gCeO+L;tj>P#)4oxRwlI%{8!Pxm}2pg*ZS0$MG^Q7#nW5R z82j9p7uU!%CObu$N=1B0UQ;a$y++3{#nL9Doq%Uqibjq5;TIQV4IMJOuwh^-B`1*V z3AB%}hff>;@hl-q@H}TU%R1S-DnQU;iCagPs@Ej7+Dn=Zd}%(5_B7 z*^CgB+1hJZ@{;+D_boon-rkT6##EAwnQYjSM%_X=b{pKtuJ&-d zhRM|)yGfT2c9^-R+jK*N%4|-H_4-r8nwaSYkDBpSAtG;<@V=guw^^fg)=i+K*=eh} z%J{1*#TJtwiK2R9UG?v@74Fmx>#*IiySY~c%ixLB~>zAYCx8S=Fq z@;+h-H@wA_2p;M5gNoGg8#rE?vow23q4MxgTH#CuZj3z1$MyHl3SAi{Sod@|w_c5O zxAD@#-$N8qm;cR5t$wbIVLGrUTwi*YszwS>pM*M{NehL-5p)MANa?@_ z`X|u-S-&vdEQe@%Im3;n4;n_x$OO&GiJYJt)=Cl022x1nfayM}ch|=9KR9R5Q z>UgphTyKSQTcXQKO8R$lIsBAk*ZhI_Xhj}aFgMcT+e9wsLx#ypTsn6|9 zSAU{bJtHPmpJsm3knCX8l5Ys~QyWYE5a{oY!5+qV#Qo?jYHt@5$TH)q%wImoNYMVp za(Q^1yuX6&Ib=Yjw|2|4#R|L;R;Pl!QY>AMSU{w2Uvgui(k?q(`(ws1_WtWh6C?+6 zHrdK$IcJv-qH}k?a`Jg}6fOi}fle;{JlLFN7p!WEYCq0omAuEq?y~-lq~p!`jGAr2nKjEOeQB?0?}BNQ3@~zZMj|fU2sA3AU|0Q zV9TnnvLFXNv)3>pjy)3x=h*7ksuhI$MS)cMqyRP6RI$36;~&uKs|r0D1R2A`G8yb9?AE2O$d#*^&_BWbqC6Tr#9@E1K)V*|2CPQ=%<5%>v z)Ph!*xtz~4ShXme?El6d?eZ+fV}%V8scF-AG_}rg8KNcH{vHWu;Y}NOp=sA$7>8gX zsSi;$Q0Pl!jY(6a5evr(L?dbuIU-eRso)w94 z33>3UGZInI<}3B7up%IbEZ7hUy2n@V>hEQ8YpTnf3-BGc-%UT2I6R9+GigA}l_^)M zXbu&m*Lfdhxcz&S%Onf~2l@Mbl)Xe+>e|-qLjMYs5IrswbNo%SB&)agEJ*DWJ&>gA zrYD-7(?=g#r_Rmu@;c@zSSoBBgy#=SBExwM&Q57V#xrWblXq*vJ!F(93WjAjQMjrW zoewA@>vN)ZPw$x0DG!}TCkb#n?~}hkc#RY-S~{0>0AGt^ik6zop4!+BV@EIw5!9Uj zeZy7I6bnBra-LH?gX#9s;P=C?!+Ry`#*d4e&GUXIxmBi+hzuPHhM8De0s5KdiBdOru_fD@jrmn z^TENtG+8N2!43o-V(sZoY4Ag|-HQcgxKRqSqWf8yrmUhVeIrqwq#CM$3%a5EX)BCueGHZ$8h zVB>HPLILtBa0UhjK(@?>UUYeBDHi@7Vh!}|+qa;tRD3V5H|I9`;l;(2(Ba>6!vd#s zFnH;h-sA**bRSZVR9zt898s1iSfTbHXp#Z@pI8-rGL& z0_(VO!E*u`7BioVf$6^JaxZA$2Bq8!UoaLuZ7dPwg8wTtlIO#(W*$Z}@BK?h&2sVo zZ znXs>!?veR?g&5GFti7V-fwo~K`Y*?t*FzoW_5iEfAA$9tE8|CO{K{S1qW)!Lpoq0a z-ySkHBNu6+Nf&oIPBvrXjkAE;g~3u#SN|oCA==0kal`ZsYRwY<=9mrZU?Dnm3y`t& zbL-(^^?gyZrHw%Ga_TkM-D&O<7xYR$m=myzt`>;iBB-t>lpY=_YFd_5J0jj5b0!mV zTk~1k<6s09rNB!7pdc%)r~MQ#kjs`^Jzi>5Rk;xj6tfVvBK-SQ=cTJg4#m6_HiC*vM#0X!ro$7zb4G+Z{qx>b0lBmfGa%^`i`aUU zg)y#+ZsH?0K5UeDsr@fZL?KGtMB9Trb<sOZ1 zA!?NmkuJr<)8Nah^c!gfUCzg1Np)cOvwc*B))&N~gnn=;>4v=5pgJC&Xf#+^?$r!E z430zQ4Yg*1^YB{UT%Wt6hYI_f?wN<9Vq`+ zl7nQ`sD7uE)C2TuUO&c#M1VeGG{9(eii1!SQbvnOgetiB^o2rd>TEKnz~`1y_Scfg zY*q1tS$WYnymY@<1K-fC8H1ucQbn+HeyA2V|6Pfouf7P&w9eKzzM$ujHEHpUq)+Fo&_AR z?T{1^B|m$*EaE!DZ_P$zRB#wH`!u@g7du~UTXmWRM)kY1R2`0Sr;{0-WHSXnMrd7j zM-%DA2jg4mD5U&g1B3!Bx~x-6qHpZ*zbfNBv*45)nEMmS@TdKCSn#^wU#{@0w}6Tqhp zAq^&IzUCc-<+5baw*a8Ds_5VG2k<`-@j9O8O5OgQ&VT+j^sbyw1Cgx&FtB_S10IkE zHB+N%M^}M%8usWptc;m8te82q-Q+3IS?2sZmLjRq6GLpwYS!|0kU+w0y^`k4Unx61 z6#H_IP5h0oCzvawth7=}&dnj--^^XK$O(=LD}RQR_@#LWB338 zP;1sw`uk`oa71L_Uf493z+QuzzJbVXUoWl1QkJGwVtwxG;mL8%WlF}}h|QfyG#uVv-(Ik|81X?TbhcNc9_H zjJ%kQGI%LMcn<4oja(l`IObQ5yWhN}_(obzhG;o875KXBVL?$YjI1L%b|Yl17Kkx+ zLfqvwMHsC2c&J|#`zhnO>{Ssx|w?~K*~#9M8%5KYpEa!ozc$a65p-+#bsZ%{PR_KQIk|WxFWA2 zjPvjXb2CnvaQsAa>$DFxV+z@1x4<1$VIAdn=*zp3vy_Ov9r-=&WAtZy+G;r=dk$lJ z0?-e_2SOhS-tX4tTP0~EK@$e0V^aqfEU zwuMP=vkF*5grmw`d$~JMxA5jPUHUpD9@|zPInR|FQDa5vgx99HonS{QeB-=6jaxnM z+(3Vz3sHaAPCCdb(r28S34Z zMQ%i3S`5FO-I$kZ@oGFyE5C(jImjzaCThnva6Huhxn5U2-n}O>Q$z`TgTo~6Z(-R9 zQhTc4YnB6*JnBDuI!$b0GouVZ+Btn25S_V!?&WIWj zf{q)-Yk1Yo-A{3v2iv`%F_|L4F}JQU8~jS%)>l|aJhn>lNTe%0z{}d?tCjedxRJJ; z3j;Lny{0|f71U$}16W9@h4zGx!k&8;r0{GC4s}y?=iEXMR3{>cOX(jzW#50*c8GG? zir0shd2i!y{HCR3l78NOhUPvrMaiuzB>8nDA5%NNDa9|7-ck3N{N$5gowm}1iRAe=X;6jj6F@z-is5|LrRVGHh`SPf@235&b2Yk@1vPen(3!W3RSESMaYHrjIdj~k+O)=dFGkL5}MWzrrV;H9WHT8;=ElbNz?Q z9D)$lZ_t_)eV8TW$bRatHXe+R-oHh>C|#=hSR&wKqo^$vm0LF z)IqyOier;9K#DH`v6&??FA-v8)5-VZzlvW{kjjp1L2`6dn3gXw8Xg~u5ho};oB z_S;=9k|rHwWMnFF03Us==hO8U0DV$?h#!@dHI#z2Q+BM~QeG0-@#>cwOW)u8U!)?) z@d2qPlh-BXZi$YrY_ZKL0}HTw{p{Cc5r_jNUVLY5@1<2j36H!Z=m(&Bo!^KUrA|KB z0X>dX(APPRfw^);jfjmlatNa>4ig|3S*;&wLRP-gUx7=qWQox^`}6q`oNsn2puK!1 zfWANTv;z9yL(=4y5(hG?rVn+Cy1N2>%J4n9DWrq zi0LyX(!L{jW0G^Rm{-4h(!YTnzE2?&?rRtOr}s3GV}p*^e-rwm6@#l1POtY02&$$i~$0dw4uH=^AVLww_@+%gai-U%_6|M>ZMTu|QNfMqVcTvn~^- zN~_mzOoqY_`vZTE!}-dCy&%PKk1S~|Y;4Sgf(lD&z=Ddgw__LaUHP~WJ5^=vJmzj& z416$ge!za!WyiFvLD8=p;od9!JK=Dh_f;)H_{WW$1&JPF>E29Gh&8U>)C0DSD_K3W zjHIl8pK)zUIt2yA&zpTfhA6{Il$3RHejXI`>?Kw8EZ~7SI9O0swLUjB)w3!FUZM(j zZ0)CX>Oczr3)rUFQrUb82yb6rSxHT&QC0a>^b1r%5@|##LkoN`i4h#RZyzf#h+k07 z8kg}qG)x9^YyvoFQX(P{t!->lH@kOXQXHaM)w!-7!S1!K$CgU!Wt>A#JBTKHVWk>V z9`K}s_4>>%Ft~Eb!_w05W%7U8+xwN5(?^<*a&5=Jb-`7Ni4RIh3C%jA{K9h&L29Rl~S#5>q1#(K<*NwbM2hUZ^VjS0F} zhcHAHhK7lwK~GI}05b*{H`ZXSz8y_?m&>3RJ!gM44oG|(rvZj}1HXWbyM9?AKKZYf z6Iz*hJ3T07xJ?V1Dx`vd`swi#)1@wml+*Y4p|BswgQP=BaOot8=Qo9l9N-+lbJ6P}JIB>wIy%nV$h-j*3|YI8i2M zw*6fQ9&I#>jVBB4{gh3W8k|B3`cdF{;@b7!#&GF%T-U4y19Z*pofOZBfybfR4{8;& z`NwjF2BJv@tc;bTmy$c(v6_h2rxkn^GWj`}e-L>|qBmxgLdieq-!w9Ln5GGMJ=4$H z7h$tE790`(pRChscNf#kL%gXTK1k7q^LVocrPhRiK^gien!{?%9|oE^rjmU&cgC{yIZ&|h@44tbhX8? zVh_?bA>B{e)I?baifgh(_yN7uZt%4AJ0&j_1nvd8RlAaa0D0~z%>~v`l?{{U4IXD- zViq~j@|jzq+A<$92aNXYb(aU=WwPb%;H;E z?xDKB!aS*)HrD9JfxN8J`fT`Qg>ylY^H!EBH~#WVtpo@o&mGFuwseC@h%8NfbS4Lk zUDrf%f|M~WnfW997%Q*AH!>5&9xX+f!FENZ<|SB3WuhOvlJC_k>w-zBH>`E?zSQHL zeLM|wC*>C!@-e267DSZw!JZB8`*)}iPP)W_xflmf z^g^wl8~(O>VT-kXghRhLm!;+)=1zou3jRjw4p z4g0zQiQj_;)E3DI#N|4fU=i+ZKaTisB%rS{_~9JXfav%~?Ja+_>+~(`q*g~O)f*ry zKmA<2il_wRY;+yvS zc(+Y~3aHW%@Lg7ed&g7RYh#$UW$*&UEktv*>;m?xqmH|JKqt6d@tz_WltB}xfyzCB zBg#|p-}R7tNdOz5pVvS16*C1;B(68;8J%^k(d>=_P3SPW3#itseU5Yq^5jviM?I)G z*a~>cU=ip?IVrs9k6AUhTK_GG-40+`vc6fF>hF)otbVg98hR!A&@2U{aMU*}?-%J8 z+nrd@s`YjMbZ=~>(N`a}srdTSJoRcG>Uf{O@0}EpXL-CgPB;z3p^>h@4sLD@c=VtQ zETD7?svrdQ5af=G2}2Eo6eG0baC4zZzvr%DPzGr?p+gKwe6L#CX4K$XeuWRVhPiQw zA7AM&&cfB8%WG8>ap9v?e-X{;*UR@(mW%na(&0{GB3ir`&*busqZ`_S>Db#@gB0exUSe~W zgfRXA06fCw-pT^#!d*sDod@X%?Jgz6-d$Kg5N{eh0%*n zfwJXX)9*X--+a^PhO<9H4V6j{yf1rtcK$IdrXtm)sfZ<|Z(qQ)9f!L*Q^6_)Km)p5 zsgvKW(zH;!xb&lNNwKewgF}9{45ES?N24@s)tQK!IM6Rk2R6r_Pxiwe5$}G?vrLCe z6ot1$oRN{Ck3TdUIE3cy6?OlSmlFI={a}G`_&=;N5!)^YJ-x0Qr>cXT4f(u5_n-ZA zP_<^t_5Q!Q1F`bf)W3D_?$W=bF6f@p^*U!H5|pgRH%*^X`X3Aa!w}Ijui%p)@DYFJ z2sr;hoQ6TUoQR>4DKp{IpwP_-{IBd#aFP`5cJuGKZr8d!2%;W(LbwB)Iz#DP-G@^kiKevZP-~I1DajkVoKuA|HaZ(2DH^Q-L^<^ zcMtAv#R=}N#f!TYmjb~pI24!S?oM$i?heJ>-M{pCzhBwCcXtCxcJ9oXvuCVrMZ`Rr zA?2W74$}@IXT%HxQ7{rUyWeJ0GJ>>R+a4Ng?-{*QDx7at0?_87p}GmmDB3A4{OJCJ zj}E|HEhwIAH4x=~du4SEi@S-{IIaF$DH*UMZ69&)^XQk`&jgF^habHmL4t9}D$Ow{ zU$yn0;GWu4pB=W~&K|B2q~voiQj7eKKp$1sS;>;WY?N0C9?kqF&d?tQFW@_+@)&^XH7QY65HPhih>K?E=eQb}`&MXGO9vFcV)O{JxdgKBLTv z&*|kwwU4b(mWugRt0FC>cPv*Tq#xZ)2d7V2gKaepBl9Ioc||Nuf|{A6RjThI2tgCP zMr)ol@n3Yh@~Xo%JoY#KpBvd41xXS}}b%tvRg~ z^g%f#Eo+FLjh60rG1xi7ZShL)+a7MjhYiJxEb7St` zG;h4-oa;TGjWsIWw^}w!e4o<{vOQ#KO_Q)8EpV++RXWlw$x^OY6;$*}lSOg>urw0x zMcB>`7k3z?p^Q{JHxH__UC}lp(I9QJDe)D!WyxRci1JD^i_hB>d>6i8{NXRlGzvA6 zyA%J}vq-Kg+X%*(~;6qdmg*7KzUj#?2?)t0uoFVVO%>}~Oa z{o1rgJ9fJ?wG|J)h`OyEd+p>SHE`51iNM zV7(h2Sm!^3mbS4qo51vb*=@gO=5ijlszzb%!_QQvRz!|gq9{EGra&O!Ex&*!7^f@H z>5DfhnHz=Fe(5y(at{g`n(!w1F2_%~siG`IIhH4_;^QR0M7V$iG(JfBD3gvix>C8Q zAVTf1=5jBDk=8cY?3P_lL-MryTc|Wl8c^TCQFGjgxM#0bnb{J4-a0bowTU{nnPlbjCGXzdbj3Z zjlIEPF3yBR;hfyuJp%*gCSct#HUiR9>90*6ElKT3-CS)eW<|u}ca~x3_8AOE&aYf;bCUDcOhlhv8 zL`t*_3`$5lCnp&)YkJCL2tdNzswx)gxXs<&;F}v)*f6h$_=JRXyo2`|capyh0|8umaeIG|W27 zDl0<*1AA_OcXxL!oSblisY2v8aXFfk;-rXA#gpfyrKOfRF^9qB6%{U49%x>y4T0u^ z3kxaexwnguzkILl&mUP`g=~W`bsrZiz)X-;_cXm1B>DRd9y?bn(r*x;5jB#+qQqiq zX_+cVDs4b$7vAh~xpf0XB@tkqo}M-V8cu85a#j;YV@N@zOp;O8|6yigLRK9afXHv} z8j7ltcb_4~yQ14<#^7D6h~veQ>j@L*>bAluKL=I}X^^x2;AHvXhOq-9_$u!NwZ-@$ zdj;yE)9*WV01vtYA;{I8Y!ElB;SXcOO0MR15SW z_?n`j(_>W%%R+O5Z3PhRkSEHzf)i$8d9#RvSZHZ66GELT%$L3;BX7;W z(0c#y@lO}ck}}1TG-zd4yg5TFD0A`L*!Kh~l^Cy|!c)Xygw~bk1uq^KJ>*H+k<6TM z#@6=7dFK6JiV4wb>c8KKFWP}Z4j(i_zp$=flOTb3(AeSyokVPQV>RP!u_)$Vt=4_* zUz1J6u$4Hkq`5PUU96cHQL3nx97C@A1r89`eh1w;Y_6B0dw@^qSQsBvXhl5XN_I*; z5)9qjUc8J?z8&USzW*pFC^!RwpbKT9dYIT2+vw0w}CLN?D{cyeCsa1+daRr#No0<`jxV(kM=zx^=XUMQ(S z54xe`G8{(?KSR89I;YWmiGZ6GvB1WrPrb{Eh>Yw7DckChCL9og&hmXsUc)A@QqgJ^ zEWMKtgb32&8qjV<4rFfT1mb89AQ$!^7pTYu!-32U43RRkPC3t(lQQ$bo!gl&YZ?>= z(lj=Jt0O1!-wuVlqIEzY05x=BP>|SpZz$@kfw7^gi1bH*Av_S4+IzEf_|l1wL{;AI zv^nw*#v6Renbn}Z03{1BtFL>%m@kau?VwCVarB4M9Py`s>U$ElUAPJO6_F@xFW!LhXZM zsAWDe#H_~UNjHpT*u&FPU-v>nu*Nfm9S^{a+gD9eULJ`83%sJRuCpe84X_I}T_%&c z%Cob_&m27!DMgz>j4R)9yA#09lN&D3KxRD!Pw)U*i-hg`>zkS^K&3205n7Q34}&A_ zS9Kwy)h{TiA#+>CJ{%`oKaDY0K)*A%3vXi)mKGQLG~^6g)~G$vH9kws7@#2_BafY) zoB@^&pK7@3uLkFpmr-QW(X5`o71w&{+=jbs%#z|rtZZTy>vhQ;r70^bqs_eWs*q&i z>&t6e@)wM_oPuv-gQnc}1WNC+z*Wm$%B^+_AJv)H^j_o-F1H6;>N_qU?*>y=$gJdy z^j(R5qGXCBP5KQaZ89!FkGE?Gw{jI^J;{d|Z1wa2%^l%8s;;iD(`s{p4aRYn%T8!X z3{8UAKie>{v;FS#(L4)N&Bf@&B`n)?9UU*~+@zO5(!r&t8B>jBJiLetBQBi=fVHPJ zYxNhG^;jJj7Z>mOH|cXndf-=J$p^d90{2I8vBIV>%P;#QyBo89Em%w&%o6?YK5yTQ z6KI};L*%U?)-0UcRCQ8;({vqj04S_=S>L70ZI_n`$E-o_yc2B!{ zfSRPF`9O$#K17b@N2BQUhh2#2l{YeK9fcvLcRgL^((CX_Y7ChU8P%$Jz5GRecyDKC z$1pZFW^8IIUZ?MJf2RLN;iavsE0pKXCBf3+wex2h{afrK&h*@zLJmx2Rn>$5bxceQ zFQh^N^9GQT5dJ2ik!U78Ubo(6f%z>MLUG0ecs(9Q#;@AA9^k(NAx~5IdgQNaY6(^x zc{&iX3)4GLt5Q#fY=Z2%v`}*j?r9{MY1{DNUh4;Dy@9IjtyAz7n?PPJyNG5Fzm^q@IF=#%oV7;$o*SKexlWyn{fw zcFm_qT$TX{*W{uf*YNLltgty_4$b>*m4CnC+Z8VLE6u$PA{-sr&O{cNx$p|i!3Tlq zgbEwc)BC$3|E7as6^~Aq0iNhrpaFBYQ*b-na4Rvyc4_H9{m|!!*tGGLCl;=aAn`#^1)IF4;PQsLuda2M>Euy1xvUU1*owA3JWMNT<} zQsxFRh(5K)6aT%9s@v_ew7~Te;wjje-!J%m$8+fu@C^g*(AxL2isI*IhMt($@ADwn zE-!R!A(}~py>Rog1dTds(}rM5-N+2qX{{KH>|R>%;)F1usnQVSbKiky>l@V_^7)|H zBkVOid>Q$p*(XOHSP3nZN*ek5uctNVKFn{gPn|^4!zDu!5D#Hi{f1ONf$uM0Z z40iAAkteU3VYd$Nl2=p*x{q7$850)^#IENF9*jPqP-Gs_s=pxQ5^P{A`FA}yNXqqm zM{@UwGc*(xcf+uuoJ?pz$fS$JizDA{ft%5b7q)X7kZP0p0y54y<8F2C68C>&M^Z1z zoA*VQ^d^lzY0j56W6rBjF&*>RM~N$HYf5#bHDmTd)WQT?0W@q>q^gg$u7JT+%H?m! z5O%pjdUrf?JhtHtwu89TRmuT_E~@>QZ-Ety_5Fh0+0fnIG5#46MR4mUVt7LgFa%~g zlAbe|y%hHj#ukqK%L43+^-yzP`;4=>!UejyBD<4eutLYTGFSR2U5bq!a3`k!u{=0+%Y1IeB zSnyL40;e^F{ zL(d%t%-;|hJmC*t?R*;U_^WEjDbFEeIoOqM8x}k;;^$-yB3wcsjRjc)Qo2z(uk*c( zjVsC>gSyy(Cj54uMwN4xZww9Zymv2<0kosTp7)Reqov7$TDJ}Jq?%WyJGegwGPP!8l6T24|7hQyh^Bx`^YA!A=1|eag!-OnZ2#2m5#wW3!zo)oAhH8yL z*r?>iMjt-5bX*h$ZK^GACQg28JCM{4S?HlGM(}#Wp1fi%@ilD&;kJ|51gNXWKI~_bX0jGl6~)B3B0x`{fzxREB#%KrOf2EyMSP8)s5<8JG@!wr zeHOPnTIA~pf4wv}B4KJSh(+Y=hZR9jYR(9!P$uChi%deJ+0D|45o_}0B8)y%&V!B! zC~HKh4L$M$Sb)RLVRG|8$ekvPFm*MwU(aDUy`unqP$cJpe{DsmJ?iuG5l4VOr11BS zwO)hts|qb^7wJ*~k`Rx^I`8oVqQG zZs_7h7gR7GA6V6$P+&dqN!P8D@)3M8Lk^zxw_oCP_ODlT@)ud_fYcWAY<^`WT&Unk zy#jM9ge0nvk7IruE-KOZfcp{R?Y{iNR2}R7w7@8y<|fU?WK6qabE!1c))=A|6T0eh zPvj30s9+M<^%%m&-Pn%>moG#1hV!qR+3VUALm&T)s`O+Heo9i4_o?GqxPKd~D-vvQ zj}_Fny%CxGSKjCDrHZhj(#=>fNjNfX`LTrc-0vBWpOm{?NbDb-A4|7-;i8^=_=C`7(X&Z}^}a8?h<#=Z|3SN6p+MRu?33gKDlV`Ed~y zjUtPAr61XO)#4G4hl+|}fKM7tx9;$@S4+t}omYU^hcx!&5uZCSZ0P%*iScR7Yj z(dQ?}s0K(b(F;#fj*Ahfa0c8YM)W0Y)0+rMsmHXPYkfIs{%Tf~HYsMZq;Imc<20zc znU_8RlleegGrFldn?{8Tl;{$E-g#K&@FOQw^d!OJJF1m>_}fd&f2VD~RJZwd^tF%O z*d*gpNUHn{~JC=-~7QEiLqbz@!K{>rSngafk31mrUip*)hth^jO|A zgmtT0oq$CAn3hupfs^Jk*X(G=e#N>mjjy*0T6VL#8Xc0~b-2*!bjgLgp4tenefJC> zy{_sc8SAK$PbqW)!>-TDp&D1N-O>=TZMhben^kPSUlKIz_A_AN;9>*>KC&BX_aO;F=o6A9Fn!&1)G^|AP%)tw4e-#_~mUK0JWY&bE$<)dni=giJ{SBgN#he}P z&-pr|#0XWxD6;4n^lqLx=Vvpg^#H!Qpx)hV`Fo_-iVGl44EvMX#IhrU8WdC9FK>VKr6gMjGIYy$_!@^;GbSUW z0TXq4;E^dm$i0^ak$6GItWzKdFNPQ)7p)WXi8DvecOfzS%bntoY3?`O;n9@i%Fm*6 zRG&x8pt9i`+)&!V)S$bO&x$yFrD=UWE!t0zLIxJwE0J$3a9s7b9EYB{9Sg5T)zaIC zCKwwT*WC@F_^AwUVMUW!Woppff~Dy1^3vn>wUg>PE57}9wUg*cin%Zy7OsL?9#vPQ1o;WbR5IKsm|;GcWrplK09HQwv&F*qP4~IYE17F&?8Mj*oqKs z!7%%w;*rLxVqCZ4G1Cj?75JKDRUyG!)H1!F`ptI;DyA(5EXznv?yg$-SM$mYF0Fij zBXsp!Q)W#dH9dJYWpuQp&BHxF$%DiM!7KX}<%G6!BcZ!sc>Cdm5rh)P1dg)Jn8A|P_qLv7(~_83niN&#P8kOYI9l((yKU}<&LV^BsMY88RPapJZ z>V3`cpnt!dU9r1{f*c_Q^n9^3;qK6KJD|iUHuaN^=g+wl-=SrJ1&gVP2&kCccFIV9 z(%QUswEkG7cC^=W)*bGFLCJ?=v)I^tURjrj1B>*@;c#Qakuy8#Z0;wWtZNmb#P5Ig zN3vKp!!f$9IV6SK{P!`=b=~ATc_t1l0Dt5LsU?KHmqL;Jt98&`PlRK^gR7`p#m|0W z&1c_q>nz1)*F#roM$8Etzrq`rJxao*RqiWDFO#{mUCl;W<-J-;0;h2Vf4Z&M_bQse z*xh0_E=EEOQ@ zY9mDaDUF)^`|`1cJLP#HWX@(rf8~oBFZKiB<^) zqhWqerGDaBgUCApA+pNH8S!9#<}YsNe2y6R-)}Z|wqzDgzXigmIT6IAy(!#(Y4M1% zITXMHEHVC!|CH_j_DE>6P^nMG$f!rh%)CxRMb%Gbb#SrSOCz%^{dSi7eBgeA=T-g# z60*F#z|-A|6YWFwIgT6N6rrp3>{HI{GVXbvK-#mfv=pwhhkuo>0kM1}rXZB%vqvkT z9Y9-0)TF^krtnzkszU>!_o%y3Q(E=!P@i9oZv-3Lue+5>Pja@_tu9E-`d0KonU@PI zEBVa3u6=9DTXd|-yVqwQ_Ejd0^wA`j<5`!#g4pc220q)cE^9<}{}HJVmB}66M=N5w z8sJg;s&e{n=xc^j(p%w#M_39di3r0ovL!>z_obtxit`P|Bej=MDit~+;%?-T`txoV zuWXq6_}aZZxbxd93OPA$f{!{LdmuEGQ)pR6+=XrW6%WrwO6~{N(P}KTBF549WI5sC zDAj&qoMC0(gES%LW)uReRY8)EmINqJ#<|zXm*5X_ijqNl2gT;yose$_Z2JO*7kz20# zoymzf%IsRp$pP)K8)e?_P87Do=u+(L^LP6Lk^!D^lO;1PM+#oG3@o)W&X)yCa3~sT`;%&CDdEXmLA6Td| zakB+&(&PNid130~BOG8@N#nKtM9el?D_~ z^!VE_Cj*ck)tGaI806L6^(@S&ule6kzS9K6sG=Lu_l=a5ZJ@XDwa`vA%846P&aE9l zv}DFHh-V=tZMZ31OZX4S=L|tDyM!Qa_|4BOCj$_)tYGiVK~l9(m=v?`&a-uQzMf>F z*w!yzZ(SQxUws7mPYKbD0*k}FJlz-|ThibvJpKZ@mOTuBy@dq2O zUEa>{wkB6!gbsH%2{+_GLo71cJ2(AU7UTTSggYiK#m)KS;LYhQO9lX6&cdy zhd|R$&o{W<&0?0v_(no4y%czaq!!b^C*cVAp7F{KHthS@%Zl5FK}cg|rTJZo62)9M zfA=vPK)Slqiyz~C2YS5UN)kMGvUS+RVJx|i!pO#88;r7>R|aMTnws9AcEMJHz!JH$4p;A0 zS(+_02Efo=9~x{}ILy$HSktq<1D?n$smuSRoTyEX~4#K6i%Uv?Z;RSLMOrbMK)!U$vH-MbL>iv9Ru@it zA08#AD?@eNBkfg=gn2?}%AxUwYMs`^L{%W@kchC1!jZh)e(Vvb00b{D7*_NlA)Sn^ zg`Gt;9LVc-o0d>r!l6HE#zYU*Hb$-CS##6iz~%GXaI~r}%wDnd9AqAT)8!$BD=@=@e0=N_zB`$W{^K#4rBK`bQU+8xO6$48D8pI@VFV za4~~Tv@TET+2@0xFjKCOb4jrSl*Bf_bw%+vZo;??Ew2fvK^Nwsq^X~`Vsgw5A6weT z#CPt64-Z+~pH0$!1pEiR`O8VOEChi$zVy|LMHE*Yr_~TU^8s6VPqw;FGZ02sD`|1y0WVne`F>@fZ-nnGfB2y(~8(I}=UHT0>1 zYAEjOxZ%IaNE?^txErTnHT3v7-B1V~Xk8)34cg%!c#sES_2J>7U8TrK;}4pR>W20U zCxQ1*ySy9cjXw&53T%iWgk3;`|kps3HZLe|4+^QkTBHM$bBR4M(k9sAZjvzm& z*xbQs7i#!1bFa^WQjS%K+}+eoh>y_ z!7L6mXLeiT)&e^tE9HY?o$Z%vC||^8a*Zl_vrikvBCiKNZd>ykk43OFTB*NW7HWON zU1KRwZ@p=>*d9WOM)*2!(nEl4vAarm)L5F#vRtWB*(H;EQai1_X9!CGgJTD2j6d;hjy#U>wF;$xX*pkA z^}c_7r>~k$E$TlMY$4Xp4vLY%qdEV^tBT z_~lL?<3fe;^2N%1L4G_Z)o)Fx4|f2Ceh_S(sn*4Y+VvGq?O}9;PBfms=XP6>xo+gc zX-S$rW;rawqF=J>O?4}uFSLH6E2pMGir_bBeQwuwKnrL^#nIhz0Is$DfY#d$d-?iI zJ|ZXG=6l|0FkCCg)Rg%3Y$Cer$k=>?*@3<8?}!*LEgXC$Y|*As4>7~6z4%|{_Mswk z?)SK`BPbn2kjtjqA~oYzs5;@=+3yQ!bQA{!RSwMa`r|@7C+g^~-_$$HCg$|+kPY2i zO8Zvh_9+g$!XTBKclMgDAN};8(OqE@UzVQ1sOl4Be;$XL3m)Pwbe_RZHJh|>LWAOy zOgF-&tTv?6;@{uv;99?Ac}tNjt+V}I2~}@#L0`)HY!H@1Xy)$YF>#jJU+!(qY>-G0 zQM;ab;S9YdzY^`JVn8#}T0}izwlaT6eo#o@Z!h8Xq`~ZPllqsD>SasU#k(c=NI>BZsZ!a<{`ff84 z>{>rT6}roNf5D&8sPnL8nf=+H^xgU_#jvi-?3(2C|6%`i6h^6Mq)RLlw&kLOj&v8l z5jD%IC8=*KNb7_v#rG*SNz493-d6QW;}8S#Vy@}_1~DMI{&=SeisI`Tw-n<4z<$eY z!;U;GM>n^(j{N-mD+s?r%+A(!nu&>NX84$Yc5zW#$Ivi)&4-ePrU>HMp=4ZKI2IHZ zk_!rEK4y5VySlpa-k)z6{+8RhhY*U)u(0Fe;>i4i1iWtmzVkhb2|s`8;&+eS+@pTE z)P=BwAccvH?ClLiYp*^UPgIc#cwE>pF;$?Rt+i<>q4o5cXecW;b623zp*mP2H-NO+ zhRpy64-ux3@Yb?;yMh(q;9v(i{m;t?-f zv*4^Lt88uH6*#{bNeFH{p`-X>CHzWiMR|w1k8>3r{a`&wq^7@TSTJv{CJ*map2lCjhf3$=0a3;S{}N-hU5DoiJLzzn`L zvk{8x$&z}h?7MDE<%3J3u)a$v!k*=K#n%YxFnu9T_9!QbV(ee}2 zDeg0;a|y!6_YVTTvZ&--!@Fo)&AtWb{pupyALp0XtgU)S(W&hcO&+ZR)4dY>!>?3D zhTeUFUMuIm+{el%ooF{nLi^d^kKHMYV|+UjLo>R-lf3Lpa?0Z=p?0_y%_qbEx&>(q zRBp#+kceSx?!9|C(%+)CPV?wox%nZ~@Do5mUY=fi#)%q;VNAf*6>GGUFPi(MkP?41 z0$fjh=#XPB4b4k=8&_|y39?TslO2?-)Hr}OxHrOD{ zjVT|@csNF~!w-O+^oWQEvS1~Zbn^dD2?zp4s`^(9!AJTI#HeW)_|WSw`7mGzcpBP> zqkKep2bDJn2d>&ANIuIOu%zPxzDc}=>ia;_^aV@CT+5-jfc(2R+_ncuXrgmU88lnR zQkgGYE**~EXSF$uYwFb<%Kbmbn z(B6FSpPFxPiD0Sw1-oa=qz z((LEG;JK0x79UV!*z3!4tkl9g{(XNZaOc%dx^Xo^^1R~HyNZZ(!25&44QW-IgAuvb zi|M<{@@2~q_RB+TJ7B^vhw4fo+IOj-SV*#2|v!n!AM!c*-MhBFmlJ1@(^N{k(~sKdsg0SZ=7H{Rd-Roiq=QSnZor-!T!ee$N0@W+w&S zGKXG;q`>phu&wA2#9fR({JeUZOudG?)gdXCa~HLX5G=*CQ^vOVcz!%$-YL7Z7jH>_ zK|_<8fEm>tJ}u_ij3XN~r}CnW9^A>Jf^HSYRLZtkjunpV-czk9>!(Yho%t=)XyH-rMbX{-Kz7 zB}hm*c;Ob`X(ZREQH~0zWjP(_>O#6@l4>o;1e!bCOlZFk!`&HN2z-I zIkx6oztn@*u8_~|tAS684{E1&BVjhnT5yS^rE_0@ztiQG1i0(-fzR#sVC+m6MIoPk z={ck>jD#xrYkWce#OrH6(x5NkZ=ez8ziht{T#J+_w$_+<+LRCtSCjE!iwgvGFMdF9 z%lGv_kN<8Q+Ro&yT9G8uY0%+Qk51igXg0$38BLv-c_ZU*slC-7;zHL*mB5pwZ}gV#y;9;saqe*fzmia29d`k+N zbIPP_JCX8X@(Y)=L3`j!;3r7WN)|{W=!FG}*-rEHL_3wK>a%HgIKiGEVS|3)~BhyRdO57SySp%;(MRJG)egi@g6 zOz#hPOZb4>i|;E~>a)mLZd%OU>}Yi2WU!H{r0HH^p&ObeXL5X8E}j=IZMx*>DmjM6 zYu8&~!UOtw2T0^bCC|%2beoEvO5SW}?y))CssbOq<>W^OJjj(XcZya( z$?w8fM=e7Dx|TfLc}Q;GQI4E(;WuXRZG{kz<|t#~zTstSvU_-1tG97Qp3C~;Y3R~7 z2+`uGK8lF<5M^O9aW7oH=-4qqXYz>lmg@aY1-w0h*Zt7m>L4rM-FQd#jZu2WLpBdm zZ09R#04fdH&O1DSW>I~S7Y;c#k1Y#0gU()CfQv5CF=T@WP4!7B_Ye+W^9IYFF2i88 zapbQcn!!Ir6=sDc3e1ka54haHQxxRudzAqRV3K`WP{$^6UJTYjSLHhq=<|scc?;)d z+}?3ozl8&ll=t&RW4}CtDH*C`y5P5Ibq+uVAl)2j`{%5_+7-mdYk*Q)xN+>RW`Pgc+0UM%9riJ0MQrmW>g9Cp$C5xX*9SJIY<%{uA&^O&>p{{7--iJzB!X zm%RO6{Mjo;Vx$pUl3}Zy=Vi%>GNhx$#8g$q0hbA--R;3cNlr5K zrzF3$C@DLv#FvD;FHq1gmCEsD%J3yDCAW)*);_H3s8zFIIfa+vkC)>UO;GCOY8E6U z%8JL+!ww(|)P|t0-k@*Nx%TqybLrIG@Vfzad*fOv@=JEEs4)Y;Q6VZ&v7?(%SL^O~ zL!RveM`sgEk(Wsg`yP^JEbY~ShS@0W?04OeBl^0r^hP+#2viFQ#a{D& zmwQ!rni56ybZu*u!H*o>{J_Nt{rPbXFK$zN9rSpY3=~@d2gkbWHas52;%&*W@)lD8K=qQ}0@3)_}KR zauSS)J~eQW1EYJr^N|j|K5^qikt(bbh6&ow8RYv^FAtiA-$Hq3C6l|jAaVTMGkbn@ zP1^jVWbAzcJ|s$Imy~9<-FUc&){pNyUc4d6JyaP`Z8;cN9KbDMgv>WlOOM6R6%_+` zB+f>CUMmWdUb4{0RQKQnZz4Lg-Jzj-pkE0-yNi8JIR`1m1Y+i+XmQ6Jd{R=Y_$ZR7 zj+Sv8{b$2DG1_=s38Pg5Q>+6DHYZg2+Vi|oAkpsk65i)Pv=-cuu*o55UV1`1G)+6` zxL`Uvd{7Ha+*m(W?+f94dD z>3@d;s4>Qp?=2dpf$PxQ-ha48M!sOOYx^QPSNgx3K(9q!=YG#n0!rFGzCz%*j^K^G zSTJY(31=P3BZcWjR#Q<_&T-pm7o<~|FQ7W%_XwG@<^Yu1;eUg-qU}T%>hU+N-DY_C zEGho)fda{(-AmoE^xe$0)J6IOscG62A`S^X4O4}I)F4tZ?||uo)XpVtizUojAvx?8~=v0q>Cvb$mEVX53{K7x^3LU~r&`!QpLi|xB>=_=}Z&U=k;*Vu!Wtq=+!Ks}Fs@Z@p%CL9c zyWEC%sAx4qfSwDX9v28e;Q~}1!9lyiJrR@TuQ1-56}*~c_|XMcg4Z`xl(Bnb!0mgpjB_tc<3kxcr((5fYS%4WHtoLB1}@e(mM`#9 zl_$HWVrN{>a1hw7SF)pvRn#FnTa82OvqMkpe80z=%ywp%^mATK+R|?;iJoh^rGPSZY)?4R`VjNOvFlzlzs&^ zPIU_EJyBP?h5u4(g!@uaLevgbwG0+49jY6b_;n(T$|x5|2RYPaKkQ+&8O|xJ25n6mT>mh>bUzD%{YfFMg!Smh zSKZuxS9Ck87r%(ILip9#%k#AiL&E(g9!qj;l(jil;I+-o*y!2q1`+~WY)iUU=mbFm z<{LY-t<220>wQ*R+o*s{{;96-3|>4AlJ~9O5A+%kh)0rhwIpB!%d`_msvq!?4v&Q! zOnPBmD-5E?u^A>iP2qKM8AT@6+71j_Bbp{BhZFGH{YiZ>Fb?!uFo@++^6aL_>qpZ= z8=*c=Qn@4RBPL(r5D1Xx3ApNGQ4|0<%-cx5q1dEyT6f?Ch44?h0P!*nS=9IFIM3=; zO0?sCqaD3aV zQv~Lb$s%f;&&T;+e#7Y-gS4n!2t#kX47fYMYbM#7>I|+H!MPOUPGbRa4f^keF@)vwLn`v|B&-kp% zEAy75FoWEMGW{n1rp`5e>v)_x2y^mG{zXkn%-LL$ceklPP98-6P3EeL0M_1*n>%Q- zy(TLoY*@!xT_if1u~dO2NA;caC=+|q{~K(sN~D9X_sr|0WQ8Z4+}vJ@vXx^9TzKC4 z8{bovAGhzkq(axlrle*3m6Lcv)tQ_Q-{)~C74`HCskU7@SHl4(^hb1+M{$#bGn(iQp@pfZz7Gn1 zUIiJmQwKij+RmTW;kIW(yVMdF zkVHc%CU4<8lqB&2YssJ|v8?Z1@2mnwWaZd5sUg3?L--{-=6_EE2qmYSo4~W1sfZ-y z_1bZm9~W1k&S{(p6Jz`ktxhRe!3PE>`+g@Ho#6jiJIkOrqVCNnArKq}cQS(oCU|fQ z?ry<@ySoQ>_uwAf-4Z0Y6Wrb1bvt?g_10GH?ziPb*9<*wJ6UfqJ-3MG}J_4%wt6`{-)6{-z~>J6cvC?GIffv)P)g z+?Fc5O{qwx4S-TTePt2%a*ev;;K0QF%L*G#+X1Vk0l!p5cU4$)x`g30XXCr1VpLF? z9d=;K?vKKAo?G<*T}n=p#?y>0XfvYUKjnsk|4`gY_$}Fsfyi`#g;#DMxobN@inBeE z-KMr?09e{=c{fiP&jrL}H?#1y4iN^hMlq1srO^wB9Nxoxspw?D1cz;@LX;nwE46{q z1q#Ait^D3-D```JYw-xw0}GgjY1@c z_n5edwOh;_K2W2JVd^mI7pEvP*0M;_4yoHh+e%tWEE&QHEn$dvg>7Dc616pLFjvaj{CtO}yCo7*8p?AgOMu3>|~(`4Mg;w+cV zV(cb?>i=>xYa>boN4V%cq|ijEFRZhMeYq`>MRo8&UoB)lZ4U}0oL*R17fD!z6U(#N zPPpBw#Zj2_`9KN$zn1X*-7;GLa0(%Q*D&YekmS%4+I-*4be+TX@UgmLIJ%B*g@YFc zmMuj1nq2ZmXCM~7dGdxq%^Yz)u)BsC%c*4{&5$DR1@)gl>(Lx%*qbF? zN^@fI-stzdg^cU7X(|kq?v?24YlGS-A;>u%%qdB^O{)R2&<!c;^|iTLk)B zvhaoh1Le;5XWe{8$G{81ZNGDX;lR0QPd-|*D1gW3Gf}CV88DCce|pydWX6!_ zyBi#c@S`Gd`(*|(U5~B2LHumZ}z%7^4&=}0Cu4cMzZoF=8Y!o}iP)m%9n-o(m%%R%a-iB~-rK+KY zdf{MW`*f}S92qGeUtIKXlZf^6+&?&wS64@b1ecb6G%zrD&%;A(YHBJqFgj{1bai!A zSV+!MnP3zUD);*PZhuixk(i8(kpdz$v)R$p!%bnKfq+2g7isBXW?*-S()$=JZfOTY z8k)S)Qf|*Jb{ZP9(&pxSSZHi)Yz6|5HDxq69xq*Kb~Ja(UR_r>LQ)V!pFx)>Snn6$88yr2A!CAm|Xqz@?s)iauT<`rR9N1RJ2#bjI)hN z$wa{4OF?q)8E{~-W^g%MZ8w)CBqaD(RoRm96g4&`i%&_|MKSs+C@4f2k7gLE4o?61 zqg9Zdy_TDoHzk3jEF)ue2$b;uk}FREl_&b;)MK@~nMK@3^i7ZG~KcG|9K((L+06+lKH*q@1&Dnted@>I?c)5eJVQyX32Pr zBQR$;%bOlS4;kN6c3mcK|Au_b;Aqrg1*mn}XyB}FMGJKo%3zL`3`Bn=T8sY_^e z|2xGlSNVW5K7|x-gn00r$qeU@Wlwp=F_BZofW>?w7V zl59o7m!1dc=Aarp<$T0I0l7qXfW;u;dYU59*jXta%BzT@UbPQYVM`Hc zxM*zXRbagUMn~XsLE@@^8$7DU$;%%}NHZc$x6+0Ik4Sgfl#hXEOqGA=4>%|fHbRpy zEx(;U_wn07{mdS^I$ZxBMI!xZr~X)Z=0!Y;IQ0QWaujn-xVdju5M@93FLraBFo%nI zXdy#N1S(hT*y{1EymnHe)&186W51@G27Vh5jYeujPJN@ujov%O-6Gv!J!@6F zRf2y)%<(d)^C4&nA7$h1TFwjyy6z#%3X4p+)Tvk4(qR+Xk>}dXrqxx94T!kqkXE>c z!LHA3#d&kUW9SBk<`~j^8sAmrU>DLbdN(@vAAf?V81+M3Gz(w6`$zHyy{7f0KW9IOiF*ZO;#2<7e*$?tG#Vzo4mkA!*8hAhl896C9K-Db zjrz%R%jOw^*KL1V6?RSI9vkQZ+21dQU!qGWF+Hm6jX=G`q|3;0WuK%cjjJ67RLRZ4 z{)pg%2T|OCw6WnH)xj!%EUOdO$!Q7)A*#j-&J7PJUlz5Vyu(6b`KmVh&xTS~=J_in zF~)mV6+-Wh$ffsKB@sEeFr&(56ed4ux{z`5qW`SN1BFhxX|pcuN8C&BC=4T9e>21T z>0lSqf%L1%j%kNKuzT0v3koV_OA0SG=s2n8ResoVQ!_FDLLo}h5qomRiR=zy`G5eZ|`1VxEk0_1_wRHw-g+z(c_IT>5dtWUT z^R63}`hu0uo}1Yt3cavy6!kh~(5gF$+5vYhCCPQzPd#ZuAw9;ep5HJYnvl!{omE+> zw1gxPsUL4^Ol0DPBqt1~f{qW!AvuqRliQN=kqTlLRZ2~*K# zDnH`6bUTwM+vz$p6S(&(^M;NDxEruawPJE&mkQ+8rsYD3{g~H?(qK6@-Y;kL!D?0T z(CMa}h79`!3K~pPvpB=mKtk!POXh@?=Xqp;s*EwN`#FcwdTP`&Lajh*HjoZ4g+EUL zEjQmi(sP_&EV{i4vh1R*kHC?X>Z7+N!f} z*@kn380bgY?P@KewuU5_L1!N%WNX0E)!Bj4_Xk%pEt#cCXv)9UhyS>F;Br?9h|o$Q z+(4$XaLbT5GE35-Sc${Ofe9B$KDMP`2eLZwo?CrvMcmE8aYXaBH+FS9lN_?bH{Dv^ z$sa{Hd5F}i;+i%b?@VXHhFfj*8Z}Ilo@MgW(dwb;PUvCNVJ@%KWK(27gfY7j#f0(G z&@x5!l17mb`h$8CMCzsMmH=kdLc$qn#m32I`fsirx@Mhk@h#->Z?LjSv){E|DttqCbFa0Pj7dBKzp@EwJ%nnhEK#U!L7RzaChcJB~U^g*8 z_?DZyVF2b-4@W#~-5;OMRzv+ZZcK4+a9bAWz}RArpf49i-*Rr=78^%iKD85gjtoDD0E zmNTvSNy4XAoPaLXaJAT#5{u|Ods7p>hxFsXAk_E!_j!Ztu`#)AvoSx)(im3hAY@Rp zUJR^S2~pqN=Gu2lUVAASE70+B8<*N&=FldSYE`@0T|j#?dhV_yT}B_6{I*-UHlMk{xzi68HI%NmdtDTHdFtOieT(gpmFr>}G(1 z^QwQqae6cjSY_xqI6C%UV12vwCy#A2@E7eSqvn7a8KG6kzpiJK{fS3jbgJWp^lTB)e z_&c~*yjH6z%=MHpwd(0NcL%~RW!f_-6?-83Ki}j5|3_YOWdg`cG@%!a4;;W6)2?F5 z?Rk4@sJ1O9*YjT-mq2FlJpiH?={*pBjlg$H5-wA^mKlA#(~xJ>UykQ(Dl(Iz+5a2)*6C+f0$KoR8Ps!x0 zw)BtIXSyL@@priVB&@%Q;;_XF=XNljau7hCUMB4Unpo^dF1wS!E4~uduVsZhZ)H@+ zj^b{q(VX^=S5@VAUnUMm>DJF$hs-O|XZM{UPYlU||Ja=Dl)|TAS_eh8rs8c-W_LVd zHL~=MDY_sLwP?w;*=7)fiED)+1d~>e@9i)a_j7kgIwJHoq;u8JjS+!>k(lLX9_MX; zWCTjLuZAm}9}Cr(@JA@~9J^d;O`5X~IYnN~x+&J%WdWIJ-hBnsoQ`w6`I;^HuMlL| zIs2zl^Er|mwl_S=AL_Zk^=Z6(_Pt{z=a~&{|Bdl%Hdl>cC z?*p#jVOzl4hE2zA1fk-yn*eIK!IxBHE`x6!^h}yES^pOlkC5+lP76R#N$ne~_=-73{PEJN0us z*Q#Hersm6`vWIqU>p-ABlc_nej*_JkiyA7 z-cA#4MM{x-fC13eOm@8VFyy$(^YlpZ73!~Kd=;#)JKaTe2= zmUv?|qV}^Uv2FBFAD-|LGxhR0RC(TdBX8-3Aws^>R21xy#ZY**lxp9ep)5PhouIQ3 z|0LpJ<1RxCy3?Ef0an}dez_*R9USH$MR@GXM4~{dSsYKJ^=%DK{}4X!_jsz+hc@T) zm{lfrv*5>-xHc-rKufVuJ>4N6Lm8zVNd#whlADlhJ~W;Rib|jD7kR(T@g+~)vr$ll^rg~Lm;7m#%nOdD zcB`(>s(9q3$@myh)>K%J>OU9ipoBZ{}m^vVVJHp0~=9@$e>hJX@$z zm6Y05xay;1yT_cI9*KSHUrScIGFEl*!j^w9AOnm`wrn$s@tMlrP60bf3j>{yBi#)B-X=!jM5$;30 zw6vCDl9Kwv-&tN*^3eeDTLOQ^IVB7X%$SKSHa50YFoS>}i2#h1y!<%(k|;eYk5O+V zvAQBJ4H7QhA_Ww>kdTrT#B4lL8v{el`dL!|y_?C~dZpd-vM+|rM=6|yD}M~gOhq81 z@(1MP=vTR37zqgpF^rO+6khL+la*?<)H~lCF99Cn&Do-stOlzkGoVFv4?Hyu4U+)y zH{0S&AGf=5FjGM~2Y7Peu{i-5+0@1BcF2Mc%)3TTPEH$JTipyhW@hGSHaPnPz_yqf z6eP;E<_36@xxxyt?jJ8kSKb%UqvPO|W8vbSkWJf)6L5Omo{Gn^#&)>x^4=5k1d==; zQ9zqw3B6-q@t>w{);DhK?66&USazPgP(Dugjf}`pm7bGzwC;02aWI_Txw^Vu@p;_Z z+}pnRuXIpA_C6u%TU*m#{20UK2UxN2uCI47q3oaLN!p_NXji$@DXh1*wkRfk_&E@g zl6p_?h>`8bJQQXwuWi;Xd7Uitn4UjA%?!S&h=Cc6P5MlWvLd!}2J`_BN0-*p(i(cm z{0*cNSShi_*a4@&6`Rh;fH}GAS$4u*g z)Lp(a5fk){4;B}At4S*;C^-6dw*v4^FyV}mW>HPZ(g^5iY_1Vg5UF#Ce;Da440z_` zu@U&%>3e)^CDPd1O2o^{+i1HX@*0$K&o5n98Juq@ROYJvO`TDma+ApzJ!X)(#e=PU z;mX`xKiP%&vKv6&QH~!f@B<3wXvwyu9eYJuy62Mf!HE!52l$*k?a3B8}Aci{e4+iJJ-FTG}U z<0P@`sz4{dOx+e|{5^-x)T@F$XUF}|#@lha;K$u7SPdp8{?KR74Y0AQBfWlyMSBSI zJp@DoSgi9TvA%OnzNvx_Uy~Q^FyYk{BlmAhhDPK3=9K@YsPsgqN2#Cwh&(Y zEzCa%jZ5Zw`VON-tu%vcVmxV68H$*+?Tg2GH&Rp%ZfeR6*%ErbRgCj0f~s3eV1(Ou zZV8W=vB4#iX~t~xJB9+k_sfW}!>{kyET^ZZD=RC%0ldG-S2A430JJd$6=uHJ<6xS0 z{#4*$&IpxIfNO*DK6+Q3023)u4riPs3~nh->(KR&W-E2O1Y;wRl+u>hwzs#XWJ%jfl0K^WqVe8-ePRab^}xEJJ6-_(r6cJX%I-X8 zS`L?|V&xLLqm_=#J%^k(wTrwjkM^wq&=^;zQba-F9OI~=&}fqIY$%0!=!p?fy&AuZ z?O=KSi2p~ zWh>K*mKjRU5|bybKq{V3o*%O*J^>dy@*JHfPLq>4isblh;dP_+8?uR+%gd8B-mF|K z6DgQbp4U$+Fks_MN}37nx5=67c zOZ(J*?V4RkWvs!Cos3RE>}DqKi4kr5?s7V2Ui(hbrvN#NDIPIE1}7(TsyK;u;(OfN zBeo1gdtWhDo^Ms4pZ7@jPs>FCKVB_q*PB2d=C(g~Zx!~M4F4KbwOmIWmsNE8iIyqI zr&&iH>wwQ##<4w0O4hgoOSo{pu(RGRGR z3E*Q~pMUaU$56`4oc>@+NC?8Wb8wg1~C%y)hk{$VVjQ4`D#bY#-SPxs=3R zB8y$GA?MGvNoiPSWLKAazko}-)KX%oJal(HdWwc7Cp-J>Is68-N%2Lbbykf_k28Oh-R*i0LqdP~Y=oQ8`cVh}G-aJ@2LLH}{U1K)XlyioVrVeuJ!8#Jhsv=E z!v74TIE)=VY}5uM+mYv9NLmtF0mH$S+gvNW_&{Dv#Vqe6$WFy`ZW45kJDc<`5$_+( zL}#AtI!DLI!50x7i#nJ&JlJ003B=So$w`(E>#c{wZr+3%fJ^5@4HVncdRQfXQC$ex zEZsH)Y87gugI+1o4%*kOe%^Yy%Q}?`4^bN)!-E+`|KNjO?ZB%<`&3=D>%T?5;e7u1 zB&uFn>#>UmKOZOcP+F8+k;#|-!2aw&nd8ZXcug}|1$dbUzj|*O2Lt1tM1clZ;AIFM?=(tYB4>!0#Ou) zIf*iCr@{GTAhUcJsy@#*Zm*4a4x))3djZ>WLyQh7CN3`NEn0@-?Ta&E1#-7dIZU8k zDPyuOoK-Ox4#RPbv?Q|qN6Ri!TjcR)Q-?drtb_58z230!ga??7uDFR?ygMRyE7H4` zF3Xoo0hm3b%`9+ulmm}+t`;8Q-ut49psAj`Ge)|3Vq-k#sZ5K%aFjrGZicDN;9nwy z$kVC58YO5}b(C;431d38Fl0;pCUxn$jdDOs4^Z*XuW?;y5K1ATsNh91NNBj2&KyO! zLr-pxN1!~f7MP8ZQ%*#vG!t|Dv-g%3#4a7Q2L(|HjGM4N8@Xji{)FxhRtc*Xb2kH- zXQ({EQA`eBu%>~K8&Z^R9y5ltTc#BK)cr1b^STn_e5$AdYT&}tIEfdsXTH+rClE*I z@?#s`9=vedG+zO(*#)Q1wCKC>{Tf)oVQoAsSO4is!O@UIe(Pga&#s{89r0iUS8NP|6TTbwOv%S>VW^?)%CoJMB zL~^Ju9%L>%5f~_XGm0Q!26#W)#Slsj@F(?he!qT_nQ~>1 zTuRifJ_D)t@4toq6WJ7^Grd3kP@Y1p>t-hOXZq_v1_6M;-SkE;Rn<)ni7q^`*6Tp* zlJegyDKw%KC~vwXc`0F#szWd${znXjiuECuu!wP=sT$4s_N80v{X0Gn(ln!T`md~? z-1UM2=vsz^#M)K<4j9AbHT*(@tZ3=07WC%F)5q*-MI-JD8f1&C>6j|N8ye)+zYmaz zVG&z_6F@LaS92eW;d8|f)GWcYj01*1H9Nv@Dbx(ep3u`$3_LD?EzMF{uSZlY>y)!< z#i8Jo?9f+cq^nyA&-tp>+KMRHbcdq^ZSN`9OUt<)jxS+|$1fMiUq6{u4KGv=0E=w3 z+-nXSuAE-IDv=l>cJ;!BLp$>Z`Z+#2@ve~H29$Naf4@mTeq=tHAY{2Hj$98nynJ*( z8zbO2RaJOVUGvBI&9V6-0=9lqM)mI z%u}(vlVPj%aBs0aP|ozU4YA9h;RI$=t^E5F4Kk)iV2^rHW-B7hQt+Ik?_bg|BF%3P zQ9GGM6U1<9(Cb@_e_8~*r4t58dq8h_q?&e|1eL(#(Bvulyux9sK9EG z*ZAvdj7Iw8+0E?bRkYin}--=IBWIi=(89hTyJZ{BQm(WL(vs4ltRQk3dyGH5SJh5O@K*lBuGqUSpQ zJbMMxp7rU5)*x?r+yIfsXGS6}ECH|wRs3D1;!026z#CbGL6vP_cR|8XTH~=Bx{{V% zr6%iXik!V6UXdYGs@SkFIZRgj;Pi(PhW)zUUT@<;T7)(IJ@bny7H>**qSik;Sphtw zw-lKV$62a9Z{sxsjC~JjcGZ~mzIuI+lT9jO)lTt@L3S>|*{J{KA(M@e`fK4$Prjza zw!eh3p{kaOMrj<*91JdAu*2TyoNKO7|coRtnvg(%hz=;hb84 zvy!|+YUq+NP3n)~L8TGeCvL<%Gk7^VMa2$rb!ksLf}A0YXtF?X8e`(Lihkb8m=;={ z4GJ|HY!sX}s8HapsC@_!OU?0x@mI=`5DQYB6` z>Iidk3eM+m@s<`M4<$YMP%_HYz55mB_dBz3#WfhKbiU%;3P`W1rE-1OewZ4Xs?1X$ zEy6sl(z$`Eh4Q+V4VPV?7SrdnQM&Nj!tBd&5}UAEMx`VE3}#H=(-$ci4&6i^%;(a< zse-yz+qbrL<3E)(nd}Jp#tFy-w?uV*#aHrA6ZMYay|2My{9@#{rjAydU!48ZkbXi6 zr-@tV2ib;SH^_4MeZp74+Jcg7-hHO*RWLbWMYoLxWj29pySe~_w&@$J#aH`jj0)v} zSY3ByqyA#qP7x^6==)pxjU%{AYTeF5l&BwE+xH)x7#_x?Zj~$p&IDX9MN0)Q;{NQ? zjfqw-x0V|V1hg+S|Aq^e)1d}IU#XM*q-~6Pj=wPRYK0-oZ~okb8o1t&Luqa!&S5%`}1V0;cUKwlQfT3O=sFyc{zQh>BfYpMn1%i$zR>BU0QpZmX zU?@GM3H5PY$`zj)eLEG+Ky12$TMh8ebhA^a0eag)% z%526_=nFQ&4eyKmhf&L}v0E{+rgiM@?|6FB=wqAWh*Jm~e+o>b7bQNb1qJq&$Zxb0 z5v?1uzLm%()5bpA&wRd(9dgvhRUxs3fw__wDn;IXuXi=_xr`XZBqAA(UbX2yOm zZ4_KfwJfOhjY#1t091HyJH!mOD{L1(Rzk3gOHdYuey#Oug?F0>QMSUXU=q>ab+fx- z&1F_bDr2PSV_k@1uahm-Q|4{QD!E)cp`0nDO?qZodgO8hl>XDbCDEN!dg*7oBY#9x z3vfcyWWd^h^$(ImSaLq@&Yjt$lnZOGc-i47<8?ahVjf6h=1WI*_lr}VMBBDF^HkPH z=%^w95$-v$uggYdHBeK6Ke?D^o9G)-! zE-^2)IC*$5ThDU9Ieo(^SoNc=4Jp zx7txD|8UMzs%Oy$Dd9fddO*^1;b1W@^8`(hqN1hHnIx}{tx0ccI2yC{|SJV{{k z3@Y-5f+dvK0S6%URuo4^&dGYg#CN5EEjQdI_nrZj+>R1`XX5@u`@;OxG%uwT{E4d#;>PZc>~UKWkH0FsFtnsV2xCZwS)#_?WVzKMGy3~UxQi4XVk|o z9>_OY=|W%p042YREI~Dtd^NEq8N_g^f$Rg)qeQJj7~*Hs*oqJGAQ+7s$uGZG~7W;zbCdxEG9BAwGhx(b`2?{2I+ zH=l*$v2a)K`mkw?J2IPznK-Ag8?5`8Z6Ti$==63*`VS0G7OP++RE6=Y4(yo76fqQp zuU~zd`h%DKi@?}osoGXy6EQpD0KMp3?W*>`P*FgeqyGKw1nikDO`eA;PAZ$_cdRD8 zjle7YAk@Q3zr5G6jZzc&nbeC*^Wuv~H<;(D+EHv@DDWBDqS~Z+c+1Oz7N*D9*yoqo zg0GiJ6*bVLHL+MOKmY20!}x9Z1f_r}xV~>Nr>wn1MvkIXMj^|0drQqiCRR?sFR+EK zHvk9HoDKQ~TD3iUh2>EKw)(!~(u*%MYIR zkV-(m&je3c;)!AEjd|soQT(7m*fEt|ksJ79k{QXmUbaqAM!Bx?#|Gs zr8b=~vU7ghVqwI*i9IL$9W5y|DV{>1%!?iNf%r2Xb>T?6E_@NC49>iW|9ps??Ie3# z==UG1?C1NL>c4|QgX=UIiE3P+`BJ8UF`POfD~%I$#LSRzo|^E`aXZNhPct=$I4w`t zY}TiMF{6aHR?sFLL_%*YU4Me#8EOgg%%Pv$%%i6Oti(~ef4=}>JVvARlHZ3P-rv&; zP2z=@InE|Amn51jqfH5v$dMRXw)xp;G^z1z<&-VIHOuFm1j++NGJ)Kuc z;_gpPvrmHiqy#+^gYt0!D*e4S<_k^Hk;GkHdOs6e+n<|C@Jfp@QCicGoqI(G z6Y-Pw&v)AE#swtmgzQ&X9FZo46Ld8N%Wr=@>yxKUr+mo_!SnfY3oo?yvX*;EN194S zGQlNoa&~7UBYE>x){xLSe3J8(%;2j5Z?UqrE~y;V;v_D_bIquTh$v@IS^^~o@!b|A zT?Hg^fiBz(6muOL*7%2y;{J9!ahGL6eUs!Pc_Y>`?}RZt8i{Eo07?+- z>xnHCO%(U^FZ7%v4X5Mi;FbI5ob~tciEd|f%`)eYMI@EUL zHN-~SIOy2e`HqV>UqA{AR55C7_A_(l;b=`3>F9JT4gSf=csSzRx+j7Yj)EO??yp;} ziMw@{pQx$^0;=+&xVkgZIK0Q5k-<>H`L+GMu8+Ux#wYo>NYBgoJh`8HJG{7M%;s)Y zxNns&z_9TKvi*T0zcOX|EpOtQCcK8(x0br)6d;u-J5LMfqxgEV{dWXue3mR5;aVsb z0mpMb7Tj*p*`2NTLgiZEe>HUuHUKu@8hsA5!G__f0Z}vmT-_ zZF9#)Qm9>L>#81%YzQOS|B$r<=_(1hP2|-dk}&0WY#YJS#Bn{QPkrfP9Aj1XHxLH4ss5{DOX^$L5XpR@D>+1VpsnLG_aoK0yj$j>Y=y4P|ayf+=J zXjB(WW!T+Z(6+7eMs=zZk;|bNPvV%h?AQGR%j|{8XSvB|0NB{DD0R;MBPPT33v;@? z7<1WSw2|A~n!Bl?yOLrJ+hTZm_dg68lS4kE*Vq1b4%&djeQ@*&LwK34Y?H4fEtjg>g8y<$|YKN zwV5y%VfPOvN^QhR7Ge3xP#P(YOS*ljQ$0+=ZunhWV&IsLx&`+k3KbnJAS=Va!5(L~ z-^*U4+(k6m=Qh@4l6Uxd0QG<0yb+swY8?3KFw=3;PP;pQDC_Xflh zUzZd-&)T=jvb2@vdK*Z96`cB>ewmXQ_O?oQhQh7JO@?vC4wKzXcw^01#P*mT9;cBT zeD)Wc0|hyxiT^#tNY@g%K?3*RHn*EMTT;uf{py#b z%%}|CDLB3VyYY{fRfLKYd+M`i#dCHmn)q1=3~if-pyUnx7Eif~9bGQW6mJuliG5)0 zr}%WFDs_Z&8}*k#ocPqSfSRIb9iAMg!~7aMSBUrL@MP>`gP=l8+Chm99%BZCg*0wm z@Z2oua`A=wFU{vsbovbJdKcCHux!kxmzMPMWwSJ3szzu14z!`mwbGsUYuVzl_kb#2 zbg{mTi==*S#-;XZ)X%L&#Rah3ypST`r{b{NyS!udKP;W%&p+BT3RS*NWoRj!9;(?F#xlK$-#NbIx7&$y9 zj#j}UK(v56RY_)`lr;#vK%(>-l3V%RQ|DS~jabjI9zxa--_dT7P_xpGx6FTTFV?tq zuG7Wax^~h?#frOjka{6KU)dBi+M>!~f2PX``)+(9xIKND^GQ81 z1T7`~(dL@hK)#^2<~BOuxi>~ZuCD`4?TdUw&Noc@?w}!56(MK7q)cGJ-xoEJ0^!}H ztc@40Aw9D1Vl$n;jpmSneDS16b|%cz0ymW`jgI1xo?j0ikZ~iJt{%Z^pMhZ#RKjIL z(e9YQlOLVGs+@s!C=GVolsDuFB+-kmi6KfjU`^B4oyT5bV_X;LcIL+}!H=r?x@^3J zZm{cui0~ZD;HX`zO`-`7cCTp%zL8|2Z{oo`N^Oo+{AU`aRHh~KH*fJJvtPb=8wp^5 zEBacgTolYu;tV)M4&!4OHq&H2&uhP3H*&X`Km0_p^J!E{404(JG@m3ICz-RBT==Fe zSu#BN$DR|U8aFm^2VHf!w?2`0uuTsdczOOdIbXB4%|IyY z^$e57@IFIL7-K4j{xiiXq7aFNuV*-Ei~9At`3rl??Yw)mmkV;Qbi-QmGmgli#43X3 z1+VDGg}3)SquK-zB~c8HTdj|Y?zj)Nto#EK$hHBxa!7H#u(FK7sU+Lh+~l4~<5(IB zX!si9Vq>%TMv!Pvm$NzNPiL3lOg@)_?#UnnDETRHCrJy9Z8*Vy-n+~vjBa#5k&T7g zoF5tnr?vNyQjBW0UW-x?+w&;%m|M(Mp_TKS&Q@Q%vMN3hlyNroD2P95G@+KT!t0)$|G7OJw4SXKj%6aa zL9(NMc`NB?>_PISVr5~ zP5CV0!?Y>+oqNdLf(rAwLc6l1ySJxnf+E4{qBY{Mhet;#9MMU1S~=!s9lt^&t(IT2 zdp~n4)SRdM8Lg|U10^MMkA%;2J2g40IJCN5(GWi)@^b-;*N)Qm!xAe2DT~a^#U$FT z+GjNj()M|9=I`q}k{#m2_3)z{T)hVi7MG~osI$M#$|^cfxugK6AdSF?8FpY1d_Pe0 zplWz#;WhpHtZC*D(}MXH7s&mgKt~0Ly(f;(ZwMAdXI((9nsCM^ zd|n<8Xd9pEM;q4v@nos-jxNGdlRU>=xk|cg0;SO=!g+c0b9zrpb!+Ox05jNMGgrU= zN5an{(Wnw6I-m9HdjWzHzHV53{2<<*G{62PzNQij;d*NH9m26m2uDZ^ov6bWG@Evh zE|drrB6m*)YKK?D_z;zi>Ws{~*z+}xqS@|PFG~c0V%xms7GmJl2)d^^*3a61)5ubd z_k%mYXTq;fPIGzCj61JZ6=%IQFPhK+hlhfSQLY|oF;st-o;TQ_r^kl(9E3Sps2sSolOG zmMfj`EC#uJ0;NDxg~a@p=in*wLs8`+x_Hr$_e>43Z2xpdYir(~wMk?_KJyQ|J3n$O zgz%SK&rL#?{7R)r1^RiH<1M6h9(1MGDUn%YgKCnwqm}P>ssAaAHZg;%a>zlhKqHen zb>|Q)5Rh0T5-YX(eoyMK@wmXP?~VjxhI{+OZA9D*Z!W$5 zD=A7utBCrvX_9^3Z{}bKMNiWfhD`s6{G@U;`uZg*+dV=yErdW;{^?-7|mg0SM z%jRWParrO!lpSQf+_7o#Gw_V{a%f~ZuM|G1U1!i@?tZ8}u3?5cd2TogAscYR6u+US zp^lIR_WDLv;Rooi8&l|-7$94dW}0pY-rwIxnwuR&$N)Fi@JI~sQJ5?TvgMqs!DDSB z`G}-eCv2=r7y()ZI?yjIzFF!f=42$oYN5UG%9sSW=<$oPJ)Jx!Y*&*rOq`y$)fD79 zeI~&0Ri1A#Pe<21wS6hwogLSPkr{xoS$K>&Y9eSy^k!L2jr2*u?u+V(${wLIk>Y#Z z(c)cm8UM17`Z&(mK@@qew?x;M7Wx#syCoMnE z&?q>yNyeH|{3=^;9}2g4^+v?;c^Ld3o#68v#R>UFcWF2 zV8|om18ZOOki;&h3mG@>Ym~Yav51>*g~wL@_v$s7vSe#o0SnjJ3?8vaEHj^oHPw}Un@oncby2f4H0p87BAyI!tit{x6wAlc zzc^LYhh$n$X3eB^fR zI}?dNN8sM;5pw?wGo2}+MWKK@%J|e6gXWk#ln-ok-cg?Oc#Y-v&y<4IyPRC! zqPGk^tZyIozmT04VCL1(w`fTrTj~{#Q%X$qE1GaQVw6#NiSF|BL!PTnwG&xFVHHbr1hy!TTShwFGDhE+)sysPxE{C+D=EK82@8W$?c~wU)tqIQ+P~+2UJAVU@ zMOMDy)TeyNnn0j0+*=t6`9MX}MY90^oS$(@YulTvhwFmF(OI_&F27Cd#c6Zg;@&g) zeuqxE$9W1p`=&63LS(-bCV0&SmLyWaw-$#tO()S87HxvZPdmf?C0^mzc)hvJ%o)nd z9T6sj`}yvwZQZ$JD=c!ZuB&k^cWCUadXRQ~5A{s6w{-qBgy{|S43ymzdL15VOgr-R ztj_iJ`dsz)zSCHl`=QDdZCJ)!P1A-C1)&i0OHu7xNo!jF;5lt>G5LVTCtDB7=NQ=0 zrcds}H~bUQSVs8G3^Fsm{QEqREVy(7L$T)2^+{&Z0&jxWdghnL&qXtKOioq>@#zjJ2Gst&yUBKa4aV&94CJjL)PV-r(>?CKrT zg!<+t&I|=c=AAtN=*=~;4&`R4XD^T_Z$0^7nHaTDe+K}ZP_PRH#CZFDx;`Om)(i!f z3Zu%HQ*CtRMkUIK_w9I!A}l%F8eKB|YIqZCc6M$=`sdB~19ft2^youm@2A+WgiHNt zF8Mlot#Lgv0i5h$91zZz8 zPoa#-7#5>~(gJMQIKOBc4>Vs>Bq1)^e(Wj>qG%M4ZPjAjv<$NqphZ;lJ-V|pW<0{e z<2C(OZH^-TN6uz*wceA%YCd5t&=SFb_QLko3a{Yp!i5}H77<#_Pn_Dz>zwSC^gNkQ z4vsk)k4wudVX4!wv*a6LMZd0zrmksz|6;1dly0My3!6u}03a%2O#;un-?rO17wgM^ z-t6!&5YIBauJbDnfgjFOEqfzQd?Pot^DXD~yYmLrIaOH4AjHz9)qbwAO}+jxe=;-M z=&2FEaBUX4{ltw}C+fVqP#bwJm{dB~^#w(`+dIGW%uj6Ov|BN}DOOfK7Cp;no#U+F`AL8lhxqEWro!H#cGCnsKvb}92Qd(67qNJpp3>^;vN$&Y* z(%}NK$ssD~woRkM{e1yRNhGpQ3=FUC^>J`;F!dCX(DhuZ zNuKe$5v@?!_eS_B&UXLZexTGPgo&L}H|F1WVXC5PS==pY;!$Ad_P?ll>!3KE?tMGB zyE}`!yNAVtLvVL@_u#=T5Zv9}-5nNpO>hYA@Y~N*Z@pFDe|C3fdV6N7c6&~rzRz{j z$G($utwB-2tSO-xQHsZ1y#K&WZV6Oj$Hh;Vi4NpD!dVNbNue4$)<~9iR3B3+GIK=h zz%ifC&Hh-RUvqvJ^3k(fQ+1hXN;y|f0bWt!wWMTmUfeEIcthH+ur?GQE{ca_xo~A| z#+M)!?Bf1y%m?p@U17=JT1VcD;#kb3HThHAMaQpgRo0I23(nK1t_KyWc(^QCBpUSR zR=Hgoo*R=^Iq;TYU0B~Re8VhXAdIL?vnOn3cht(g3FxWE^@4aa=cGiigh#FHc_ffQ zrlY`${dt+YUH_CTN|#Eq8Ji#XU`;=6?=XN)UzkSs>^AxIDrhUyf%m@B+UNsPwE&Kn z>Yf^Y7)h!|UXulu(&d4p_|LNdGgXeZjK}%ff(NX(u}F9)$ziq%54iUYkEytXK^$Ty zv}mKl3}jeTGRfY}SZ(wqNO^4>%0qgxgx)Z)K(Gp)UsVtC^4jzmYx`&Zu~rP28bUj# zh2a)S%1kC;#wsZ2Ymxs|UpQuL(&Vm2$Va0Z*qcP?DlQ`f4+b6lzA4OgaBx^aqWAy! z<7_h?`SzWnfpm*;Sp@6m@iDMJzG$AX1lwk<>;4MGmgf-FusbxzJ(E2p^~c@-1@g)g zB{}&QXJ=>Dr$jE_o}M07#Cv;;xGVkM_AcM0m&C6>7mhWTydZ4A^B8&P=p%m_LdM{2 zR95)=nvKPkMwhLpx#HVn-0j%JlE1Q{Mb6w{9d*w9JP73Cvh34i7=202sKV*!yzTUL zFD10d_-h&d`^MlP)XB+7BPCUL#PKxvx2jF?`ALhZ3T9I+HW*gxco;R%)@Z-A5uR5p z^&;`Z>r22^-)qSnSC#CQo)-yWD4(EHL#Q6aXX~%(eEIn ztA~a2xmih*Ku(;+hCqyz%~I``aol$JS2&1iFZ4O+l`@SYYB^XSCQ}1YS`?w6dlK zkGdJ0xz-}7*aN_75X8t`;_n2f+nB)r)8Dre3Sa7W~N1$$v+=OmPrl*r%v{?vdGSt%dI^Fh%v(L%t(!y^{RLtE*#c z#Js;hTS@=4-W>u9=MT!OE|QHVx(9X8=_elAsNa%yWeSz&;S*diQzo?*eYYQrmr zfzw*l|E(>5;)-uC-nNr`pM#4ZLggE7>gR38@y=3w2)&!x?YYbWdCt=J_;z*J;}=f@ ztxm|knseek3NfH(EsIr|>;W+oDHX5v4}>?_-R|Ql>1xpwHl2~I+b&R}|YKMfPU83SYOr_;IYy%R)DGa~R`* zg?!t_W-BNKWdUD!nLysJ2^Iha?so3?*-&|?n_XhrH`RL@lYU~sR1t}px9Q<|Wx-47xUkSR-2 zq9>NW5`T{plh+^tH(F}GbBB2y@a3&?8FA&)r?bJAFt8T|MQxB5V53IlnT#MViyY=4 zg}27~M>$P1p>TxD&bdv9+i7%zJ?X&6xjEdmB~hWwmNC4rkF$_rq8jL?-6kb0*SYpQ z9z7HrNnPGFe{h}8aF?hf2h&V9;VL4+W2rb^PSd_Xx&P!-OJ1>S5HFzj`vEck-?gdk zn<5y@8ig{)z^KUZ89>&(1MF7dKs7=SJy|8-MU4HJHkL*(U>O55p zvGSJbyx4;3{~oe{b%V5)L0O z?)et+xk?XV)F+Fr#sU@7R|`$HRVu5oLeh4HyibRgB)=@N@uO@*X^4`6G z)o|S@N_Mi|_;Z8W8TkU!mu*q~c9FtF`{?A|=z(lAI0v0~JCsT9EG4O6H$O~+1#W>fkMFUl z^@Q8gre2#Iu$N)b#72}nSWSc;JB$HSVb-z{DuG4F4<#`uQHkQhlAwNdF}}oe z%C+$eVsq&+g>o-TUqo>anpl)e0PQ7}h8-=13Bf_6BMH|3kVmWlQ#%n|yrY()jh!== zsp)ECQ&TuW!3?|IV=FjYTTThduxlE#tPM~1;pdGpgqyh)O@J)Ui%-Se!gt!hv%P*O z{iMsno}K^;GLGBv(;wR+&I1H0$S$mjvs=e!t5MKb)n%2nA;rxwQ_L~*^YbE&Xz4g@ zCB4n}slQ1u*l`x2`R=n!f z#Y-!ioazoCE30aJsdF|nfxRWS7sKkQU(nG1?KL(lO7$2&}D5gV}2$VmE2_3!sQpBD}EWBzXtjT!=c#bclV=6 z>G2kwlb1IaG@PknRgkv#CyK56`B*HDtjg!&&%9f5r~xSu=$mjtXSGfsABXY!)o!Fg zS71p7*pak5#5vq@o~p=gmxy})xAmNcKR<<^Yxz{(oOcP>=~j^_jDUck76&To%Bi!{ z$v+weQPI#S3d$v0B>$4UlkjOS$r#|f4$hK09;7El@hJy84NOU}_Q@Ohip)=T*fD(b z&i5E$fDxUcJL?#CZ5?Y0_49sJ2HR+i06(fmfGr-V1FY?_7-yF!gN08eYq1e_He{hm z-%w1oHCgeZSeD-6BNlHfBf9*TQp(#(GJCHR(uaj(B=0`Ae*kVg@4*g#7P#)5<`Rv| zvm_LOt>A7E{lGlaKuEx&?XQ4_3yq>~Su4gVgy=5JjYNaxTSx$o-q|kZcJM%j$k^Ia zL5cP5u;A-%NX78uyRLv;!MZWl8f;~x#&3){0wHT}sjEm4qk>2$$M(S3%i5THNpl(g}u7d#NxA7 zorfs7F*@+`kn`2YI#s|PA@fHn+DgLhEhCAy>Ju@_|D0oR&c%Z-zc7d=dbn@9kWbW& zVB~2|XsizV{gryioslMO9<}&}=p|m4{I#y5w5$UyyBp}Wd#z4Y+l6O|aJ&i3z`$Rb zh-_+lR8ksKa0$BsE&mcmZ2Fe-_Cj5$ziS*cEmjl%w zcclNu$WLYfxFoL^Y*w~3F)?A1`el4yL-l zxQJuDyT8Z=X19of2zj%Y1dW$cM9kFH)w#`GMzGMdeqIIb_5YgNXbhDdkzO9qaAC#V zvuuO5zS_i zUue2W7%JeiLFv|MvH;)JbP61^pHFic`hD&D+gpypO%A3VxUx$?NkU+9VgjFCCxMG- zk%B?$v&6*BOJMpzUgYqKnu;nETxP;}lII0JJkJ1yQ^=VEo}Q-rSNV;BVgHu}xbx$i zT=R?)mLW%f{;q<8434i-WVSK<1Q#DNX^OFsK?66ny|vlc|^y-k%WN@w$Kqkq|k&1o5iq7 z)|B~}MN-w*V)R_EMDo8t$ftHYa765k;Vf-Sjdk}BZqjz(vm#6NZhSA2n1>?t_;_irG(1^4Z*wZgT!O`i75J|R?GiUEz{4h#!xR=szuy*9Rz_e-X z^|+BADj^xJcJ?cr>{5~=IoKu8-EY1gq)$|C*()&^8$aiAyHbW8h_WXb$c@|e9INZM zFt2g!NCQE%W0kk&-E|#nQM%-~nR`27*Q+jpsWXJ)>#{A-vG<*sqEE8EjM?<9U8CY45F2GT>(aTwrfm9<~ ze-^@M%JQc*9KRA-5?>B?(--SC8mJ;m;7FFVC~WYE z=*H>hWg?QJj2U;>Ku47-LEg@naSbTHomr_G6qMur6%2;!9y_A=8h(2U_sMT7(gKg_ z$4|YAqaBbgj{N_Z5Fujbn2knA>6pj($UdhVKcmM=bz*0~KN(@i;0%<`=LolXpU1C` z{UPKSqcKc5d&!j6jJEcjC@Rhm=Kmrh8kpidhecQ4VHh2YN<|<^ym{G26vP9c>78uj z@=O2W+7Lg8%RMC@R1sId_^HxZ^9G>vBRJfvxE<|Ch5hlkTRCcUeLqEdQ^EGhHlxMe zoZ!T-;{U;7qTT+?bI0Yn`kWx?JVOWH6_!QrzgSEx5%`C_$#SxAz=HKfmvJou_OY!O zYd+)w-iY2FW# z$Kk&esTO_svWb~$uYJusk>`E^Hq^0F)zsBlBl)Ve&?lPWxP@zuSHX?;>?KEamr zRmVg3C!9`n78^)2E-A?L*ly~;&?>JIu{d7IsP3K}mWVX3a36tB#gm;wXl!&J0otfp zR$z#N6?wUWT*H+;e4{(Tyc6N#kIH#ihmD%@|A9grDu{14Wr-aMMDJEUe%g{K0c?Eg zbEyPmAzUjD=L~%gtr;lS?B=B1V*tc80p|V52@37;$|SE}fC?5d-0$Y2GRwH^xlmb1 z_*QqoA`mah|A-KY3F*s%>~k7F@=;aYtpMhW`_Fnlp^4jmi`0UEn}?$uPD~CBS7Xhp zk>Gy(=I4-khFjRel)tD_+wV4PH#2D=7_A~?$Z4N;Y;Pm9oBz(pMiJ3+0brCiFquW3vB;|El(1)arX~{2R z!Ru^Jy{$1{;4s>+^qCk0fRJIe8@$k~g4}s~r5u(P!dhGC1OGc0$bs^<^6WAo%>Pld zpLUJF20_z#>w?K)<6E$xP>=%e5x5sJE`y(rwQo2PZY##MmvU9T@6>jbF?neP;Ts|x z%5L2;+?qXm`jgw0ox~c(K2Az?Vc)8#lfIc45$B=OPZlQBiG;dZz}4*!q;=V@2`;AH zbiI9}5;@YJ#8uTAO6h;G-Qm#IqJHN#?Qd{3WP{wv{=klw5XD$*fC+tjd`?_RY5Mg0 zyWgDOm{tQQ&4VtT(H}W!RDF9+1lvl=3H`hs*U?~7M7o99qc|3L0)PT>8|Th*wGQLZ}{NJxLkH6?OwN}58|i4cVcsjes4fW}_-90)WL_5G~QCIlUq)iAd9 zC}6OLH8W*CPf13|jaeTMD2?F#{LDumfT1X2JjdhNf7$)Ic5j}W)CD=)hoAMU9U&2` z6a$+$2FtQ|?;P(3l8fi{Mey+XOT+)K?a-*%Kvq&>Js0pIj?yV1UmMxk@s9^z>&+68 zoQD0X&du}y^%5LfG&vs?G^0k%$Z0dtzb%ltR=dqFa+k261Xr*p&|7JZ+Tf#{!9um# z;EJ39C-^NY!7bA|n{XLy?F8QPX+q0%x6#5#nilvUuajR_{BJU?UO@$7=C`Q%C(w{N zxb%~T_(eB>)L?dM=+n$Hzr7Po*8iJe_^RfBiZR|7H6YH%!<`>-e&Aa@NSTG$m6I6f zJ}im{GOn7uz2K2|N!yeLn1tagizb?{6D!%LWh_@X z#p3*}W;E5Px@E)3H=TqW<`# zBQG)~q8|WxSOW;qud*MYRx5e^};Ylf(X^Ju)J#j5U-5)SjL3`t)ij=ow)5=t11zNQuMfuaYEkxh{}2QD0)NzZDwTQmE_e? zA~;2e0#PG<7Ie>5~cdp$~CVVP>B$h=WDK2g2rO( zqNRS@eI5j_@Tpg3Ilq}oaW&ausAMT|jkTyl(8B=@ELCwH(!})VeRWH)G zceYG{_$dQ>DHP58yZq;%9Dx#pb(+}---%RxHyz6Wi^^V+GP?t>eU8lC1 zc?8KH;+H~|b+1I5@|a*3n2d=I5_4(93AO!=Yq0}xnYBrUUvo6ybAy`q`of<|{UJv8 znA*WKNW$XHlc4Y?2%l~8?{xnfJ~<6M zqy;Mq-IZ~uezp)_rTea-&_7ryip2k@Fg$n3BIBb*D!P6>En7`Q~A+l`)$2+=cSMCde$L1`|n0L4g*-xOJh8nF+zpRZC#hym5pB7?pj0?lBYui+1lUwCN^S_&+f;f z|4A5X3chp*dbN_BQJT-M#CH;e@mBY)%` z)=ql+`?J__#w9_-;(1-mpEEJj$1F7R_+8K!)DB(JuUu5MT6$!?RX)M~zK&{W0UVz~BeNmkXtpYW%GRWAKQVz#rUSrzaHOeNaxL{*K-*#1b%%jzJgtp(1-494t=yD z^J(a9g)&FOLq}YT2E9(sXI%CB3LSdoWt6Fv-54r0@kIn^oK3mJ5ak9M)=XKV2uy?+ zu$bsw?&^+eO$U3)KnNn*jeTyn+pROWagu}KQ8e>ZC<6J<@m3_UIfb=wXrx^F9d0LN zrFH=s;iE%Cp#(_z1a4s4=JZ)Ex`+{qc~>r~@SKf$(+C!6a>DDPva(3pwKaK}IWWU1 zJ(5&SO---UBi37KcK(WP6^tw7(`}ZLl9I2&fGJ>ZHlM_$0Y%Vg7eEMbjbjRf{oKXC zuC~OSdB_V?$u2G~$mp>_>ut`IJof9M-M)_;;yVkj;D_cQ_A!{%Vo$u5xY(aiR77== zB`;!_QM@)Wfe6N^2Z3d!w>de!V8JMxb*Q51lwaKWQ|8W_#rXMJV?5Tqt)!%+Hkilm z4+4SSZI`Q5w7b0Oxt=$H;7e?A*wShCxj%h|498|WWK9IXp=ay=^hKC;5^R9a`z<7g^*)QN^*5jg^w|j@|fX# zLE~A1-sVr*!~G!_9@U>b@tmDT2d79ESV)f3``oQcwwkP}(K>qyrxTn#xDWZ}buK7k z9tpyjQ;K(OxtXqJBM+w5QJ+p3g?CQYb@Y&nEe~BO?_TCd5i8>NsC7WMN3mV=+x{fR zT4)r~h4_JhLYea=q(O%ZWjjr@k*~3Aet{#=o~fHEMU;$s4& z728VxvLgkrnA$I;v}%(yVcp&uoMXNabHs;LtYGQYMUQ%x>Url*8dRfGHR^5GURBs4 zE_QL|?I)u0XKML<6LWaAycJ0kPPyC5M2K$*Ymu6kG(0aglJ*Z?@0(4;bwY*euI}<( zgSsZOLBpmus-uQ|SI9rE?1b|uhU!p7&A%PT*#@I)CEuG(>zEPz?|YEHL_fW4g+(3H zFH1IG=^mhZq!aicIu6>s1$HUKYowc`Wh%EO27P@=Q(XY zT^0_bCQr;A_sYQI^JO{OBbcbHkdn!MIV$zAi$ z4gwDUtNy4`TU-=%5^aG^x<*KQRm1#ekepjH*R`cIjsLS!ifokgfot^(f;-AAv3%!4s%Oyo|SiU9|>syDX@Kd-LCIE%@I zBbw%%Foo3!rvk9zR#Bo3vI0%bJXf>G$5tIOG634eik3PQM_>2OQO8yCaG+g zLDI1d$B?$uzhFPQgZXOKQ(%By6;f9GNW!xf>MN=}y|gTeJNu{Jj$Sl)tww$6dtPz3 zc3%P{+Q!bm+Nyyo&WK?t-`T|}uZ_Q{K!>M4RdEcwp_zWmoCuM@ z>h5*dMLA(9>kf+^ck&G++9co0WH=!^*YK3OHTM%if;7oN$M(73HmBPNaZM^au8V4X zgDn`g_^o)I*XWS-rqWK@N0 zFOOP{2_ei9k(KgKcE4&WVyGZ1J2MiAgxPy(%|*S`B$nmI{k5d~wrnYuaXW-=-i(;p z`#LD1I8SIQW?X#nZ_H+3u*;%}YlZSr799~7D(ei+;XDzS>w)SgIruvAO~qz2w4JtfvVEg+c1af;-Y$dO|jp zIpoaSNFpPh2}H(%_79uvc{KaIgfKxh%?myRfP{QRqI^Ij5|E}+?`o7f-8cvfUhX@snfJ_=3cKFhH^bcJA4rlD<9Bjyj+TVQa=)vn{cmg^Ec3n0Wv5d;f3^3w^)AQu{LW zb?F!JQGD5~XvG>8IjCujnj9RwEcglLWH=0xJe#Y{)Ge5}Kr`GYO0_I0nx$i)7czU9 z)WOuaeB%$#i5H>chr|)(iJP)GgA__q;{S>*OqH}KW3JIzzT%&gn#8svYz0u5xJ+2cq&_k~bp#llDNA`F!EHu*G$u8*v@ zE(DDx|Lb!s@uRM@GroOnkkh^j|IYo*+h=Bo%Or~U;MIPI^2VwHku=Z%$OwObZ?85A zyj-_`c>Gn#QeJ5by+4N$fgpC*NXSoyofTd3SMe*X{*TsoB;zq#i+)%g)cX50g~ASp zb!xGG4qRS)tN_eTJ}+2v7fTuD($(;hl9IhkQXW28e_Ptc?EUsxb4IP9mIWkG6rm9@ z4RUFUeO=^6WF=Z$A8k24%7vX3AGLGtWRC@bpnQaSGUAz0ZW9bC!RT&616kU8>HrTL zlDoaI{B_%mxmxUc#~S=}S&+dZ;VRW-_}3}iNFQb}S)1WhM|-X;3QmH@Zoxlw{paWA<_vJWL?@ zAiHDb)OUZCAh2JF&mWY60$$ipc`8t3f?Jlp(ElCHUS46>(pUV_IqwpHmQn0cpm4=- zs~<8aaEZL;e9L!xfEs;<46l~LxiL@G0TWx=%9eYER&_X&&?J5`&k%^ttlBw8Rga=j z%9FqMB(O-PJL{*}>WbhQZr9zG`|RAAxF3m2%UiIwsv{NsH+o>olRGmId}Yj_PAP`Y zYMAO)Ga3IX>G%94t5m_b{1TtPou}@%;EPLM)u@>^Y<6J*_asygfg-(}7x0O=c%c)u zZXd1Oc;dT=&Rn4x7+rzms?vT(1OY@`RY7NG(Neo@cm~XdWe=nW9q_#$v&H$IXL<+7 zIEw<>j`;hiH(*~$T5r*~CL#y6;YMzNi2N6$X}%wT0nN(y$s6Fq!=w1RE;8s*V)O<` zTE7(mgLkCi=lgNC@@ygPT$;>x>4hFq^|+hxv7Mi0G8&fFGo4O*zqFto?7r4ZlS zBU>(csrQml%nvIcJMUN)A3$P%S5f|>x+o@x5%E|k5W>!KrQCkZ80I;1kS7)Y!8c|v z!3bGe%4l^5O_+zrik(d?t%gPC`*#)DJ{vR=$;MyImPAQkwn&!eA%%p0G;o;YEJ2`= z=BX*7-s7?4MRzUd2uJJT;G~f7#b~I=&hQ*2yoK!`=cKWdb>zcSQUAD8-`y5=vtJ7i zuhyLpIE0Tvka^C5vJwSE)l{6GH0J&x5pwbrGawzCh1);qUvJ0CjzBBa)+fPvMa@4* zfqq#RY_k-7y>JX@Y?~dxe0RaapN1_e>Z2fUenl%hSf#&9)(tvxUz5Mh)D32K#vQb< zu%dPc$#UhB`&CbpB5BWYi}BKrFi` z~+}53alVTv|1OFD0D7mg>f&cPxrS0eCK_k6K)-0K7B(ZS& z-Yl7!QbM!l@tN`Z@`rcP>(@eQ!f~rsYAiW&lr^qvYE!uJ)}yz2JQ1eB9>MK)KTyVN zONHmIvAe6w-+b1Sf2@Y#_0I?nf_J*y;YRh&XHz!O9PGi4Zu=qJS&&FNmXp5d?z6A% zOutqPZi{1N_CV6#iFAg3xCr0;TA%=jH>xaaOBJu4aLJCpJZDCK(Z0P#4OTb@fO?fbb6 z2Pj0{3%{HW(s-}y*^kwvd>b{gB8+6r7~nbB6FX~({MX>ojc3=Vk0egssdgtdWqQkt-0 zJK*sl&M!0n&L~z8g_=L0%X7dP{}P5T?Sk;aemHPuC&DP+l3}tPT!^wbOj#)m+>T>givQ_nkK&&t(VD;}EWmOlR^LI)k1RVV_+W?4Tjng?p2PzaEy|}Y0H5vRM zKcQa%dJ4y*A^Q+!+$i!UW8tW{3<3sUI&!$Yc3s|#KA(So1hlV0j1AoZ1v<#)m!RI* zi~Qbpan^qSfEXY9fcQBU5E=T|f4lZ&w0_K*;6`t%?>i)$8$*@jKM5+?rOaMkz)#A4|3PRYtI|N$mY0V5{s@#1TK_k8 zs`>p!VTkU*4bn$cM=Ek#vWEH_2&8XU_2k48Qi=;fK>(Ns${kK_w}ak!eP}WfKX~wh zzJ+c3XK#9j3Ry1AQGtl)QjCMFOyl>hPS2}PjK>i70r~FkEWU9NC~jNg_`GQ zQg#<#-NB-mn>>}EAQ1rpfsB%pr3aq8oSaFh%{V7|uCKWgio|U-n6aH-SBL)m{5%Ew z)9rIqCEYD#dghF4! zuBR{fTSWWAaD8ngj5Lt*(I+C6DFSq1%K22%qG|<&=`igmkd z0v-QtdF~MS-A?nu<_3PW_k*)1C?YS%lp$!MZ^~-B=CgBgRMqSf7l4d!>Of#femuci zA~SRK?_MMJR3`mz26!CZ0a6}R7hAX^nD7t$KMUbn*m1{VM!<}tGnLE^*jR!}a(6Gl z$;mk9#yF#Z0PJ!}$JnfVM0W^f%CBFeT~axoH#$vL^UfXgH@kB(eq>vWzB5_;%4%vv zPzN2!E8t|(wpN#yGj4N)6xz!mm~e9N*!w9AHL<{VShMxok}JfIdBZOxBm^tPdGc`` zA7~~ok~0F34D}?_YqsHj$-R9z&M&Nt|MWh1q+?;(yENw=%Ffg$X<|0INb03zps_|S zqL@SyWy*?<7x79{cjEM9?VPh8e%Fb2H1fI5t!wlYM~iM!_7p6rUKYO|+xWMX5wdLe z{nEf=eM@aWOwsiWRQ=b(pw|hr1C~ZvQ!`|v+B}k5Ka!%AdJIhkYc=uHKZj?lEBnRf zuAk3TDbqtfBR&1W<1}MtY@tLl&$p(tt(}sNFZ4R<$z*K)D}M)VcjpSwETvHy)FA}(o7cCY$rs2_SM)Ok5E^Doec)P+F#pZ5zr2&QEvxkhlFhL z+9W2(U0z6QDv{|3YFSyCv+pQ;aq;jFF|xGOv^OzPm1SH@4O$&Zl17idd@$OG61zh*#@k5o*i2P z?hF5%PRM>#>=-|-InLAEqnujy#*f5*;uYumM=|5Q)&Fy05ISh!+ek<|2&E$pRv$a0QFuA%sr3dAAjS1+p1-s^E{6_YrTI z|7&3XP3xf3A35^OFMpX_^vAoo^74Uds zd8p>-WaRX_kgMr#|8Saiv-^B2!+Py75e??mFN=HjN4h40S*&ZGRU(@3ktJWiEq$DU z(vb+5j?B!R`O%mqNjj7HXJ5sQS<%X@|49*J(e4)Dc0nJfuXvzHDVQP^gbkk%6M%{> zf9n)#t%NwIx!QRs!jeTLS{8u zfdV~Vf98)ji(iAkh0c`jmdPX1%VDBoF{8@T><39;qDIof+sQxxKP52LeCqJx4Z4EUkhoA?BZ}cN7Bj9wb|aHU3XImA(uu^=lsfoerG9P zB74tVuOhB(j5eAukdYU1l3*jym+oN~#_DdTl~~F^a-FN2h1!PUDl3q8?+BB)7_0E5IitaaT-0C1;R_|l zIL)Y7`GgA{xmES?FMP3Sk0*Z#nv3wnc;K@%EmXwz$dvdx@Es);5T#6A&BqK(65!y1 zSM7`S@|Jn_-5bl+BfhEXQ#@lMc3BQ9to8%QEhB=>E=HL9S429h>Tzz9tZnIi+=wVguSwwS4hbwoJ{t-<;NB&M>z$hl zSL${qVJcf;QS-WIOr5E_u{&AsUlorMIF00wEPEtwwFuZ+N*;Niwjxea4eRU_+~&>&31?JNP}<1*UeC)RbwAjEo>3 zH@U9KBX(lT!2Sg}Wj!U52t}%(ru|2iwo4sVNDjRiCJoe{gT zSItL^CSkhhxY_pg3g`IjjI$MTmJxLnil3jqe|wu$PEO9r!y`N*VsuJ_7=&~JOlU#& zr&FCHmU0Do{Z(YJJ6!P)A8*Cn|0^jx2__%MQOJdG%7d>WZ}izYF` zCg|}872QA#rQHKM%J9B=Zyl3-c|+7v_ECpmU!YiKuHkL>MwPQUZE5Ck8Wea95h3sdX$jl-*lXYY6zuz znCIGeLSrkm`OLI_HiSErMCzYIa5dc<6}n9ILFchjyN0oDRz{SmaW{;MUba>YkVZ3@ zX`tDAW) z6)(`2ccwyXq_Hq3U(zYUMNI)Ii)y-_qCDl)^3X5hT%MzAg3ZdFwZpJCS4W$th zZGj%s=s6l_#_|JR4cMfREw zeTkvl1-<-knH(g`;CCPU^iwSNVzz_fLN(%|2)~_s5Pi8~$l;#YYR7?`JOp_R3o=QH zDt%K|7CLfEH1v;V0WIXasZt9~b@cfS%U=qDcblqq4pm+?S*0Cv-0XNWr4E25okU}$ z&gz1JkU@v+JZ=_3HgeOUxS5i++ALeG*dYs91}(0T_d?RuZ1^u8k2{Z4?#2kYOf5Ql zv;3!aF86y*aovjOn!*bbVnRYvhtI$2MwezezYu@ru##f7h*30|_ej9|$`1iocQBqc zguEn%@U1f$G4VgDW%7<$%_g2Sr;|K=6b9V$G0VQdhPf(?e}QMK~gDkmudrs##lxUb?ZsBZaJBEGixPt@B!apHrp@~RP8}SSlVlhr;e$`O3(<7NOfIl`PGx}v8Mys`@XmYsNKOB-D4o}8K#=~Z@gqp@ z5bw|x5+s0_bZ>+LNUfDlxZ|^Pr>-YHMXCW;| z1BiV!J$5F8PRJvP*}vu|pC&q#X6p)f)@IRnrcEP)B&gVpe)N_5LGA_Lwlas)z}L4l zvVV&lyw#VRn)SZ$3Sb)|p{YUc2s8MTBa_D8 z9ti&DiS;Oa&hutuJFUI7XG<%7`YbHB?y29e-34B2Y73uo{YfN0?ii_9_A?k9RN_x` zOR+zU+Wq>@IAOfAgODq{ER9F2o!-dbowj0v;KwpE)hY74XrVG|U`%QvM;{0v68F2> zUu?+Dn6c``9{?;T!gZM#%1-J9%O>g4eC0Sl$s~l0uW%&ccv=6!B&DPjWh7_D|KWIK ze;gw5^Ij!rmt6Yy59NoZlX$JGn0Uk5pq9OU?eEqSXjyrA^sI zVCBQ_Yu)cy5ym97zl{g`{35kN$H_PlpKtMH{QTY&5XB=@qNAhJ?U3(&#l@+9dC3V- zikLcHJ(T=jX#B@_2)_~4akYTtu9cnqMv2hPFBO$LEj5+ngrv*@J2Dt_LMjj=GrDv9 zHV-aT#+q4|*v;~#N!>zh6R2N!c_Eyy=N35JTwk9+zQo1Gj$zg*Q8NL%>$ExTi3e9z zou3U@4E1m!61*wS2W}Tlc(}T9=E?FMqjO~&7V6C5%wk6>E@LR{o12;azI5qhgP!~j z64m6L;Dbc+6S(F#_P*T_n>6>(ht=BJnqWTPYF)>z%|KC+ z#Xv{L$AaYX<^D{{t?mBp`Suzt)Tr&n{*@pn>;_I*tOSNJrCS0TSVqr_oJ+>9tB?x| z39Mn^>{ZqPA)Z1Xi)9>2s_U-K5Qf01f9e6dL}zDk-NW`g&p# zEJqo+Cf{KQ^BF~g)HdVK7<^HmK(A{rdsO*%21}uWTNx><9sRM_tqURFl%V>4h>O6zmV`83(&2tJ?nHvgaHk2bQjToM zS);o*>gH@PAoEFd^tR7%l9a1DI5tnmnjHSTO8l?`r^L%8(ZUg?VPnyO$pNh*Q2`k5 zKfkUaqwdeqJ~{a~TneZ(Ho%b-XU&m~3uRnctddquMOv99&lfopT~TeHzD#vr(x)>z zYQhT04pTmJg1XCFXl8nq9wnH<>7^=S8P2x2ni7w?Rpus;!vP}bt3vAv4B#5uOU;2o|0D4TbPruIafPqTqm89@f3I|P+e zEWhAt=iB#={~>DB7U-FiL_+forFZB;M~HtwrmZJx=~)Qb)cvUtiA~_*OTTUrm%Qp15Bd7oOklrDquRV)HM|m$Kg4 zI2cAA>fT1<-haQ=Mlml?PCBwZzL69x--?smkCL&uF ztXXZo$|Y$_>+9=m%*+*{P)Gf*wX-bWdq?-MouL|tOPBc=U8*1z7fzqzNQHQ@{yD5F z|9z_}j|4`__A}$%-JOYKrJynA1G%7!1?4|;)1BD&l6KsnPPwyKOf8lu<-R^YD8l~p z5v9(?9p*&`34ZQ25U}A|KorVsA3CZHz6U9+ZE3A|oq>>KyzhS(tEWmNd&NoLe zH|lQ&Td^-q(H7dFg=;PY^tkQJROvqe4197&Qxv4fF^tUZD!s&WcxfVIK zevJQ&nRVscnR7L`to`TYFSEJ`MjqtTSH3)ESh22#k8GCg`6~yEI5?1%_ zU%W>XEm0eh?ziei9KTtSWoxg_0iEKWI>ysF#}b;iB&}TM?2-X069$$U&IixEnoIWgJ4g*1146&(}KVo zZwzpyAfI6BNiMF%zApzRE?=qhx>#}EK8aB*e1nSIH3b`Wp+#7UU2gO;D3Q15WDEmq zH$2gdC)&||sa|wnjOe~u>>RarQ4YSrdU8U_d~Qcrbg;YxP3;b)H&L{o+b-q2W-ZXotNuqRmkGE?wF#oEE*HnhQ6493ObDr0efb@{E+>`20;viQ=*! z{CU!+djSP2;Oh`5TfTBjHIrv&0K5l%_xfbeLm?GC9o#uHnfNC>B}lhWzA*9Q;bVED zKMow~Kf(|Z;5Xguu#zmlDny-!6^F|K4W=2aw zb=SPiK59p(fjW_$I@8%gqeWgiKh-WB!Zc`@7hJ8_D^uPh|90!-C8)oeKk;^3Y3?Ow zz(gC#ZqlBQ7Ki=kQ|6EY^{;f{9Dl;GO@cWm#I_c8P55nI@gSbx8@I1J?W@L_u8&ap z=r@kL+Y;_Y>Eat+e7r=jK88gb2Kw6(fFeEo-D#Z9Yl?j4AB0t6j7VrP4yE)!8_U7u z4ZeKrif73h&76hwr5MP@1Wsgv5;IeXVE>WbS*1HMm=gjXlCBQuoXyPn!DK+lX=kW; zB*!^5VYh$;e(co>>=)#(9A)6Wh=?j@Cd-I_BWnjn&fM1Ql)FE#R4n?M z^~q?|TUlFoy@1Qo(g^R*RtJf}5b#Yva9 z43CPsftNCQvhW%EZfMd-MVup8!~V>Rbx0Qc^N=HA%mX^VMcSfh1|*e!9(XXB8`W`) z?Ls6>Pes*BjHzex1qKd}a$@(}3*NVJj&bCiI>poosiefjU9@mk?P5ppE>B(!m>UKe zE+Hl55H0+m_@{sjJ;i*mm6VC}F%w)Xgj;Ga&W$0Y2dfCf%rJGNV6H|FhTvi#op15* zYAWKbh3TC$X7jhn=Z8QI@C~fX``asPtH7{(9t+68k||+?>;P#9;ug{Zf#}b=17Iv6 zVqOxQ8Le5+q$1Vk@f)(d7$nwDaBbcXZt`IPSbO3^%q}Mr5SJUv#sHv&V^8jEe9Mv~ zff#r#j6NI#&=~QBh6GSrI0|cHnEw)mWyS&)v$74Eq@IF04Yv6UA@MiV$2#L7+;U>X zwP(>{(y+Y&@N{Sj*uw*^`Jb7G{6#JTe>#HfPzf8)oBlI3{J96QaLhjkVRxfIKmH;M z#{m@v!J!EF>d$t*1+N<1=#K_{(Rk);k?NU0eBX;wYj&bDjc>FF)kr?dXJK&(UI+vt zN8Ie-{Z4SUj*G~bKH_HNJx@8vAVlFk2cC7}l<+%z$}=8RUjFeqs8r+a1+_U=Ld6=9 zPAXMy8zvjsY(vcWu?hjwN$2S2j(V<}Xowz8bB^Vww(m zzS*IK8uLnp($zZA@{fID<*Q>1IB&1TjX}`Ydh zGOj(EosG~l&AI}DZkvs~JSDO><@WxP$WBlJOvQvlPZ0*=rKxA1`LjKd0KL2PGwbM7 z^N$}AvhJytjl>d2(0?C{;o}52c?V;f*94f$lhLzCw9k`ihQB&fD%}T}pmrxyZ#hv? zDDJ61J8+OSV{V~Jsyai`^AHhX%-sMlW4<6(ukyQ6mWX_adO%(oGfd=a(7?HuzA0~ov z78yHvB#lUD_R<(Zp=UzHaeyU^YXEE%J+HQATj&{*A*V zT*mQ!Pti#eOFd7mYfW4q8?ECC;>jETq$B%lkKH8_qo?6XP`3=vq3sW{TFzO(NZq;; z>skbHh)}L(b=EYsl4!jdUU}I3bn2D!pstl`BsXST;}yYrW6P|m9VPjr{_hDlm@YSP6lHSx$P8Y%u7qB{h?AF%^ibtEtRYok5+8O<;}=-Znu{+#k?63-@KFdlh>lUUQ=lqX4VG zZxFf89&C)e0PGd`KTl^cAnO#L>ZorOQRkiLg|{mfGlK2WdmF3M?&X|0h_gkU&cn6uGWt_~o=)l*@!A!!L(iddbw9H^gSzE63FREqJ9CEHO zW+mx*(!NGy&atuTGn<*qP2pU?vh36_rj&_Yx$nG%arV8jXRB$Y?1CFUXDd7huaFjn zk1+xat)IjXE};HLeK=QjJou7UMv@G^N|OP~V@yiYoI;%t8{H-%Up`(=@vgC=;$I`j8NhZkYq#bTvi&@93Nm$*5N6hGJA;vS@4u6bubfJ8=0 ziU!KMb#UynL9+uCGBWa*muIZ6tRK*C6zeF8t<&B0?$7*9lkMtP2s?0rg@t9DcE;`R zrI8Wk$?&tn{~r3h*$vjm?;N=kemC3DTV}gH&wLi1RR2Tn(L^IQ>J0wNJ*jY-D10(Y zzOR+}!XC#29(-iG{-k@qFT%B&mSWv1$~J2%t>3yG*{;@M=7II6{95Hp(;*>B#~^9A zMZA__yWoY3rbaf%9skCYvV_Y1rx$R8vR4JVo=5S0XtM>T1@ubQ)@S;8^ff}B}xocaF~VU7W`^F^>}I?RM;&4-!~k8lF6|NR_>Lgru9lu`zBeFjaZ>O zj|u!P@-e56MBc`p7VLvAy@u&MGZHFmwEu035O2)SF+Du0n$$5>N^k0Gj%J8meIV&c{JH5Z?g9DbPi1!9WIuyVcM4nd;l0btP+ z1YJ8JL=Ih;f5tXvcoyD0fldG$?l{=Yjd`N7uxJ85<84|3KK}dlx6!4vF$(WMA)PQ; zLH0oBcO4}vY31eDu6oFC1H}+)_~FJ3<8V+BHPf5(4@>*(D%yn;=0k+>LGp&(1N*uK zHaO8<2B_+Mj9VXE!#nXD@dbQ za4o0ox3CO`IjODVFyNyG>GjmyaA=F0%ri9wRleveAJaRd1sr^jz&t9M)^+t~5twpn zWlg%z5^QQ{D!gtE>kQ;*XR{w%u_-dTtx8~MxbLmdwo9o_SZg9`mnR0uYUy)iBGnEta8mY z+J2+Z|WQXQAarcdV0oCl}ooR9MV0LI|gFf?zEpiza$K~uqma%iA z@nPyXv8c_VOU#R4g<_24x&6Xzn1$kTt9D$s#;@``^>2UXU1EF-xA_S(M18H~%rk+> zh}EPIr#y$d4NN2Y_g=2i2QFUh3VP3LN-afu7r8)}k0dw@0ho~P$9s4@-eT>x zvzrdZW35pHc5AwjCI*nsSJkRNKcYT;OiAFvtb zq4j+0fj>xSP-}L&83n?A;1ce&MN*EQOF2g#Z?L%=50Ny*Sd4du0=`pvMk)sCF$7Pv zpU~H@a%9?78;L5S5}r7dxt40=1R)0LIiivZMAFwRqvJO{>j?`CV8sg#p>%$U#DV#q zM(@d_n44vBKjz6*#x&yY9L+_k8&B*&nieonq97Wc%?YR%Ru`{%)#qMJx;`iHI<7zv z991^-`hc~#DcgScHQ2g}*vZ9ftv|)2f>zW#mu;HFXP6eWpozj(gV7fF%jcPNv);*J z-(X3bu8Rn9aYGRETQ%#`)x1Xzk__NI#${DH*hx)@s>6cnL4#>s{|6S?(LzFXVVXTn zG+8q6-IuVw;}ZnXv5;l1L|a(w-u7XUT@m;%nnVU>^$v0gz zm5lE68c*YT%KljzZA*_>f8}utjuxWA#yu#*J6$H#{N(B0_)q5D;os_0>nECt3h(!z z*vs%LnGz2T)ws03Xq(qVL3+^v4Pzz|qPsFZCI1ezfKftgi3JK`U;AN2e@t9R8+I0F z)Exxahs}3<;8ih)1SQl()K9ggR6jsKELhue<;15cB zSYghLmK2}OH_Y_wb@nN}=!&pGCH3s_u9U2O$|c;RZj`=! zsanDU7g(^ihix#b_gVPGz5VbSa#-_kb0hI`&(@Xu;wGilO!-8l*UcyzLr@9VM?nMc zW%A;(dg$lEwTx*=>$Qn)7o~pD!=EBj5 z97a!|M8OFdyo0|n3ysx~v0HyoXUx-S67Tm7vPrMMq~n#|;zj9>A$Q#iFunW{(=^f$ zjlyGxm{fktyWm4z4bDdZQ^tzE9f``zeL~F(m{vc6RG5o;9E0Jcl^|habGN?N4d)tY z$LWdBboX{Gn@x}q_5udp%;|e1G6Ans$(_LE%Y#7Qp#hAl@$||0(^cy`!p3y(@H?3c z!$5l%LeKODTs#sAOc4>ga?#9Yw+pNJBC3QHpYU+Cf7u;c7t>PxMQ;7<(#@Cx-FA(w zX-3!M`5p6^FU94GTQ%`-AEC4_oiZ6~^n|2Qb>#N|J<8y0Xz2WFmeu{CpRz5SralY6 zBrytnjg{P=?qZrD8JB(DJhiC206nkQOTBG;-p-6jKwXC-+WmrH0hcwBrbkA+Rn500 zNsSbDjva=< zLQ04O;GCD=S6WV^SatGzE$Lhu)Y9&_%08t4EZgz04^AA;4rmTCi+`L~Cne48tCxR$ z4WI(bd<>SDzg#Hf;Sq!voPyBnB#e53d3aoURbo*skB!hntToc`m^G5vOa>=N6Bp)A z*IIBA4)Ngs&7oZp;4G}lhT`VtAi$lAKXnShbRh1<%W_&7G#{58mIWE1f*{6$=LK{KTU zDj+VbSY_KW>Dq6WCLd0ratrXM{4`@`TO+otfZ0E=J0;h!4?_$x?|t9bVUbR4UZEu>5|@U4Wj!|U@JJJ5Lc zd_F7US1lhJ2dz<^UxB^s2Y&PBqTT7mD8;RPwwt-Bmg^MXAQuO^@!+0)u0E~6e<1_7=gG7q+*+_^=UT`$>s>Oz>O=bCq=q1Q`z< zi3C;HiB23BnFK}ib&4Fn8PsVWrfXfov4kywnGQIVHCT)baG6bJtI`K$Vj=^jUFP6| za-(zu>NAajL>cKSNIgZ42~P_X+%y@fpek`>DHP9u-Q8#+Qu8h{>9)bs6DiyZ;IsV- zZ8cA3!ZPwfjfhkobpCQ>Y1B8uj88)><9l|T<*l8CT@7`mT}5>@T{Rt@T}2&jUFBix zn{zAkirnQi>3Cntu>eincww;Lon?Vt9roAY`!h^>&5)gRR{~JhcB?u`k_~pKToxME z_)5e#8Il0RmLi7bfrrILo`;jR{(_oP$B{wo>1h9fFTT|AeqU%ZrTnp%?#@JB`6_l( z|HmYwRF4Gu)qy7GDSFyuCAk&#^1;(T2cf!tXHBGvIxe2^)* z#wOWzm)4s4Cq8w#DV{B4aJl8_scJPUj1Pq{h`Cq5%@MS2fNT_ZQ9Wvf??PrOkH)P~ zr-HhEkGNHtv%Xu%ucIXG#~mvErb7-7AOEX6%blits$-QUQx+}Ds8C2o*hkrO5V zpi{YH0S*)j#z!u-p%e)BFeG9t`hMcv|j>GF8_RQ~YfQKVpd^yw^p zim+je(I-D-!kGfPR?;~X64ueoQ^sl4^(hvYf9W91xHE5>{ZpTLIYi>hQ~+|Z}3}LU-`=yb#yG#4;%mX z^}TN+V-u49()z02@9*N~#1`wzo4$(*>oa z8(7)cP^F{;D$Aqphd|uCy!nldAJq#}3+GdBw{cVJsn4IEJ}NBi9ZhrD-ro~Yy#HQU zkXdYTKElM3*v%56ke{UHq=W1{e%|5YlAz+dJ;c!tgnPeSU3@AmWEbx=EiErdY_}J4 zMXrS82U#w%svVzjJq}vd5Fvp)E$Gizmq^kI<)==U4U&e3^EOwBv&<)Q^)v}s5HRvB zpTE!j(g|BB`m79$Tmdl(&CcRPAS282FT@PCUHGQUzI7}Pz}renS}ZqV#OO5T`;HUM zv1$j)K+h=@M&t5b_eD^tHYP2TzyBR6_|-XLm5@k${v$ZP5&3hX`Nn z^~V5GKKo5g-n5<`6C_-?F3)o8`8mVu{cF^S4TG1Pcrg90nZBKr=T_QtD{7~VqW}-| zgaa#>biZHkga8T_-m{-uZS)BezK!f#(y>8&((T&~-?A6Y6bHfHzeclT0q+@HM-cb; z;uzS;?JEb?Zo}O?+aNe$LQFdP8Se3F0{o?~86}3`9f}hDhE6Klp4-z6VtV~mLmhVe z|L`huWGJ1EZ2E>%p)%nc&`1#l}euZBh6I|mHaJ<=zsBz&ssm-tf z8TMx`@1z8}2m^Ir%dJ|W&p)p8LWG=Le2DYOuo*-#Q*4-=O?tF-ZZRlCSZxZQKsa_cf>aDRTQVZC5Yy#2kf#1_)G{@ zj~bygF56@h-Fi2}+SEn^a6FJzwts_BaRN1ulrzxW1ytU;?*JHN0kr0nB-d1vHMa+ke(!wZXqCgvd(mpW0)gmaimK2jG zZ7sEm{)nANN5FzObeqg_PKS!4lJ+wQqlZEd=J2II?bG@hi2mUXsf1>uyAoEqf=8c2 zWa>C1b*)`T6>TgU`F; zxGaxHW;E>UAGS07;U%umgRDi_r|%TLW0>fQeC*YocywT|0y zhy1^Xn5TPp_WTfxtCOUpBqlB{Hwh*tJ69+w8rmxpR$);QM_cCe<0B-A9s-MLV?fmN z+uz;o6#~xS8L35WZ5d)>{(XMNP^D;1dk#XtSn25K&=D39SzTLSUv0(@Ay;S3BJ&ius6Jx>W>#Gg0h zco42@X~0o`y{JsX<>jTJ`1x8(uYVjbGM+BCl0Oj)$n-&xJPV{Nstg6*8>jZq;FdGza@6}+v9*vBe}%+btIlWGcPf~vQK0E ze^FcAs6__=9Yrs3KxEE;ZiMC+W;!wvJ971~eH|EMYonry1e`Q`^ois%Tw8r(9X3C= zsKoZeZUsJMG?%}4Eo%f~Q0-1{AUy(r(EnRD6f%Vow0(oskb| z>8sNz#bX$0#+}UeD!w2E{llE^YM2JegnUHG)<1s&l^joWqCYT)Zm9$~i#^nH5SnAnO zvVQWPTQg+83+9Tv-{wYdS+u&p{F;anx)>+*?Elk(T>qfPM$$ix380apkti*PAuUf1a1}~6lbF^|DvbDk2kKyr zgz|wkz% zd>zlSssH|vUt}$nF60$&u!=;p`6)bI*rYPy{+U!GmsAj`A~svJPy-E{P+Y}>+&I!} zT8KUPc15BDLCtu*0pwOCzUqp-gi9av!AuQbm~`*Zd|q(!YJ>>I2J2Me$QKr#kbdIX#?10knH?%(j;q#R6S;H;FHlF&Tti> zBrSt6(77;v%he(&mX?;ryuM{X ziku*YCnZi?a!CGc1!Zwama2dK`a?MflW^geK^){K;y9G?dw)F4d55K@q2ZDG>3M{Y z+kLVD43_P8#>M#coGRqTdZQzlaTDkFvP(w+0R(2?&?%T=Ne)^@NmVcTSezdLapFVo z^=a#rq)qrfoe1^(IUBURk$Snwc`u|$lj2td<}`wcu$vSDn&%ZM2SA)uw{5cra=OT6rp9&or)$%1p1uUXQ0}%-kFL}Gu&(Vmfa39&8iV`ghes1o_71?q zXejwmY@Yz5<>=H4lKC4OM#SF_WaWP`V%|h;0ZJ2nHWTe-<0gY#rvJ`tn$YjshvYY0 zF&ZoQgcP~P{nvcR0*L->mh+5$ZQZps8!CJWHRuj{Xn5}>2P!nM3MFMiltDocU85Xi zGtOrxFC3-|wk*`2y?Fp+oHmEny+ohiNq+MI({)w5gVxD8D`~^SUhqlp@9%RZ^+@sGl>z$Q?KK8|}kcOBR!d z(y$X(zZL`*rl-?XAb@vw=h&Y!rqlV-sa)ph&H%isiJC1)^2)m&uc?e3H1bZ;^xA^3 zGqH-gG?pS+mTA6^_bH9JLW8S-+d#e#GC2xB;7RmdEhC#CTsX%BC*No1B0Mi;d?(C` z3ViMr(rZ_J5|48-Av7=Zxcr6iEYY-$*r>;Mt@NwBIvm#5w&Iw3q%M|89}>>?-*9yHNM%`nbBe!{yl(FqS71R^=;IKDVEE;nPF7lAgaq@&#t`3yY-v zSpP5Pm7hmVb$#J|*p}2YvZmof>|!6jN)a7}pyh{6xu|20kJMTy$HNF9=zoaCDXq}G zW=XHglqhc{5oD>#y&3p)Yr)bZo{PPt(eeT70|I3Q{1uhOd~5K%bw)R3<&t>~!RuEl zP6C;yk{xbw*zOFFUtI#K;P|gx9W%gF4$SSkR?x;)mLVOfj6o4it4i0POZsions6Lz zTlo>sUq{%jbM5MahoEFC)UQ33GEY{vQ^{{s#br1j=Ys=p)0mCLJzpCG?r!;=9n~is z*A&-6h>fg`(j0Nf`Nwt;)#OfsKbos0Zh-X+_p>B1pso~_kZQX3mkyp`c%Qv7&gzNX zN6+DM59Ni|$~>^vn|%Mu;Xu!%GNE=1p)FmJh!5Q%7uuZv=AlMeWfRMUofFS!UX=(a z)zqe|=U2l)t_}HcdMEgS;iSz0Wwa z!;7!7z~yTLa0^pF*Y3HRo`W+PF&lLC5tb)YkwvbOQ9zzN3Mbn5f)5$|>P}Q0XUC+Y zb7(D!CA{^n7X34VdH+lVKDO%?U2!|Ioy3h=v%wALZW`Hn zIsMnn!oQaE?Ov@??~VUCme(ZGVRAe!bAhwMIZ5+~KjaHZS=TYX?ZeEg#smE9%I90A zB-@|8qS(YvEEb~Sh!s95z;d}B<)8}45Jn&tfI#*2AFi$h@G4y4uNuuUsb6T8Z0=zp z6~m02Vq=gSRN&#^X`$uk=#c{?4Zc7V!4c!72Sp!H?v^O$t`PPugD5VK@V~5ZGcI1J ziT5->YeeWeG7KiK?t|$h8`5F9i4s1F)Y{2%?*y6U{c>AV(z92?(`NRTf@*i>nzamXwgm@WQ1Q z5J=;Q|2an=V{vPEVs3)39Akmv>f*wFCnIshsg%xRHzM?W#iJ}mlr<0p5mUuj0dcmb z7nL!Q1(A-VW6mpcV)F6;2ZIGf)241MEiGRJJFf<*W5NwMo+s{G+}(F%-G60_7eW=? z^YSE@dPy+-h?Shu7yv_X10R1Xd>|50@OfLDA3@pZpn2-oG3Lt0`p3Hc$56%&MFq8n zjq?5+IH-+TQ-^3do~Kz!4r{w`JXd4bLU92^4w<7rJb%Tph3-Lc9r&TTEDwZ-Yocsc zeK7$0WrIEb6p_4Gce5e;xQ?@S(4P)6ZIY)?V*jd6AouM>F4KM(RqE_Fc%u`)sG$OK zsvc0RUnuhxr_4ffa^gX)ysx`@4n*gO{e&>sayodTU%4FxuykxbxZe%|P+|D>IkK+W zzm~^%bC^ax?#nqZZ@1}(^(SmQ?nFCe4PFql0+kK+bbKf5uyY11?(~?^W>y1je79UR1{%7|_fc%>9bV30)Lz7}` z9d+=6kFP%+acu`cg+>aqiz`)PL{z}M6fe4%?kT8!iGiT}P1)-5D}?F zY`Qv}uZwkV06b{_h8o8l`~s?C>jk)7b@q2U2E9t>l3#=Wh0wJm^|D-{Jlb=4|$U87pKtZ@n8m^&jRe z2Z${|{X2GrIYN9{dusnIzp1$^yj5V45VCHk$1TM%clpKw#bnPlQ@KFdzX%0W!HQbj z=AJWJg_tC65Jc;V>_$0m%t9$L{*5=~%+V}XwfHr3!99z{^;&1Mi?te}Z)8XMhGo#a@pUtpzwugKH40&NKxXnlR+QC}>De zpP3CF-fPu;i(!(DA*mR5+z(_FJjY@bh=)cgz$PG&`lk~=OIp~5Yzzi#xgT7l!{tf9{Z}4 zGDhLE{h-b9IudvyeI18X>rJ^I>Z?x86ba7n^#kcv@T*3tFpO* z0#57$9aSpqd+^xNUnGJI5XO!LzgqIW{%^wdOXs48|d=bo!d(s$@2HBE%) zLYB)Re)zDY*XGkE+{OT{5~}sEk8w;umH#J}8leSaXuC}0!dg$Li4@1_@6YiE&BPPP zD2CX7QQ6RF8`O*k)w(5TF zyev2oVPR)0E9=Hqw^W}sr=hc`I0H&Im}Q86*1hiy7hYOZ42zU!ZZW{lv%wi`FB1~Q zcfu$=64=0&ibf&07PA7*cnzt^!F#T52COV}0VOO%kcTUKn$SERYmw{SI>U5UHv)+~ zlC>a@DWr>o&CvE*dpMWAuiN+gdd=0xIJ!dY>keCEtwY;)|f6kF;$^z zS+#$hw)>-`GEb{;2}dIA;O{6KM~?qn4ohyWW=1@sCmm3Qy1eCvqtEw!CpDbAzM+9o z>?;TqPKbah$bv)@FHc{yr1d))@VvBM^2-~Z1`iD+mt_V?^f*#JP?vlXW{h&K`Lhaf zJN^6g#tKbx848K^LGK$=1^iDW4D?TZ4UT3*&X9a!zMd;!dB=p*Qz{y9#*v(AI0(?T16~T;0bAc$~Ouo_nf+OwBsiDBDEXtDQ z1K`oh>@g3K8Hk|{ivkXsx*!JzZdRBCpsmY6eOH`>#05R1Re(>B@Rc6!f5u--SaK5$ zg0TzL;s5XO3#Wx6=}=sCugJV@qwvkKKJ|ROD3Ne$*rTx+)Hz=4n_mU?RxuD~N%am6 zH+LeP?SFwU>hPm@@qlDq3GjKJ8J65=i6jqI9n@&yWD64=G#Qb?sBs*{DJ?x?An|Gg zuM&5@z{py2k*d~3na;njzCn_eB7!07!XM^)FXSL~Epz~GZBEcr=vmN}wt^wO#PcZ4 zabcJ&m-G#!=vd>JP2~hIE5-5V?hARS1HP`BWvTrTRVCC#A+IJp-%hh7AxyoN$fWY` zMpT(M*FNWpe%(jZb8#t@wFv8gcmt99V?3EE^vw+KbF#_PZn#x1_o!2*8;*n zIz(Fqx>~?2lpo&dJC*ux?`rF|=|EXNW7B)7ZTZAg|1%GKu>O}n`C0=txak;Wjy)}? zlwYNrceF#@;%FTZ@>z_r#nU$`0~e&{2F+D3Y@3r~PTWQTR(GgQ3PpdPJL%8G>!n?M ztSEMsKAi-Xo<79(dsMYQ;nph9fNPlsgjRpIz)XKsZqtBsR6$k2HyKxC{jNos_1ogE zsUdGIz#@u10U3{%A=i~-JM?9>%zt$=ie{@4FW{d;?QX(Q7i7@|t{kONFLz!BZC$Kr z{{CNli%_*T<(HJBV3?$`Yw3HHcd4@+Nl-G243WfWqiDz1SkFEv&00eB4ytS?-%!adc1H^?_2)<%vx~B zz<0Jd1aWLEDuW9gn+9{}w585fh6AfTpe|4!&wJ?G@F#ItDBl|y3G7)=g8c#SOj=Gd z@W*JAPezaUnh6)XE9+Q4<|vsxM)La{2E=QFX+*Gfwuxo~NA1*edH16Ir79S=NY)`5 zX|(O)*}l+BFOKyX``p)1X;^=P^WZf*ET`F`_Ck4jY3jTLHVWflY^Fx^>#F@eSZ0Kx zr8_#xcW8yf_Fi44Tw!Sd#yw{$OolC!@L zBHP(qWv36)365#t7v$eR=Due--gJ3!qmQx`ZlA^UG#UH}^)}bQ-QE`$g3>~aJq)YY z3;EG3Fa7X2Abd5+63dFPIP@r5f*z=XGsWAEwOWsC4(~G7JQUAKO~V(p<;mO@-zzo+ zxyqVQnnnpR$HRD{u|AE7z4_lC;eP!jl+;UEl5GSU`E2!2ei`7-=_hWjeodBBPanFm zOB4#2T>6Nk+7jr9_z3+Z!+O`iW;T0a3n(Tx10kJI?o{1a2ssIE2)!k``TSUlwYNvl z@wib9)n(2?#X>O_szUM=_OC;z=q2Ype(NjldXK=S@evpkK189w{Mf4g zwHo&fB_-E<+6k3JAXWkk>GpM>&FA#$rjCs)$iSO}ztADbf>NGUHz1q*N8bB$(UCzj zfzOQ}tXB^uYC=A`%~EvZuP(cE?E(#bOY#+G%pj?i;eK302hofMc@xvySpwL+%UtA+v37o@qHhc2=6 zr)&#H86udB#sGQ$CETr10a#Nqcu>5c+l9nDzCpglLPhy(qwe9Vz3lDza#&BVBtb&b zz?7(pdE3z8tZ`v~pR$-ARHT8It;phYNiw_bUHPwk%l=QdHY1cFB-q zT~`lAHvvr5q_<0*&cH zh}ir=*Cz!=se%NPC2AYd5;g3TF~1Tj(Dx_%E!d&q!3cF@Jq{{G@5pT})OR(en~G5U z{(=qq80;sEaXSa~x=x@lJ*Y$}FlYrOSk7_ef!TYezV}Rv`ggcs(@KP)m73yhfWW{hMN48ec{-}KNS^wZeaco}{ql9yF}iWMS9J`NJr z{tq0|qc?pHW+d<(=tj*2$i4HHM{Y}jJ=8+ibXiASS`ymV{M9Fwj^f4S?3EHsse!08 zRxuVo9{k(yp?&lS5UE*srbhiyh56$|3(Wk_unbS!DM+0ZVGVj5s$oN+rP%kFqI;eP zQ<2FWR)Ydog{JJg2wxXYrp-Ikr;8UMh0$y?~WO#={Ss4BMs=xc!F zV^3rUY%+$>b!8`2Y?ca)82>NOlze!sZ>0PW=(Cxa9vPNsB(KEPIYZe^{-pLC{kiy^ z^w4&gBoIGF1DC1)IGJuEHqmfyc@6yeQwAg|O0K~XOXwmW+XZnrM_Sl#rAoLJ%|U$G z)QXV6o6*qx47tNtu8;(kKKk|KpG?l9gqtVt2f5bglN&ulzlgS;f7ftb1fdm5Pf!t( zIqVGP1>ZXYR31ZKxJ*ONtKW+!~2M&$i=;s7T1FYzYu>#1m6`*DDuD`>nnFLu=s zMfGj*rqft1al=&;#J_#I{h*%EFG`*YmT)_?4&quF;yJ&RMeZRsU@0JUf&1qjuNQm4 z_-h)R%acpTb`TMQxn4@Fnb--Z&ae;=(y5CNoY_YR=by+)eH}ZxFccu!jsdioiRo0_ zi5;z6X`G`Df4;B#m1OQ{4ysz7w0lDr@Y;ZYho39HnPdzjEE(SNem&|C;CN2^ZLie) zJf7yU>^!G`oVPp)$=g(ag=j(zCYlu|zNXIu>vB4LY!^-q1YT`w4ZIvG?>@bSYAgOF zd%3*q5E&f|IHjZr8YCx!7NdBlrf7R;wI^OVZ?}YjT9%NA-PnvXqm2^sfTyGo!v;&F zDLG<-ji5PQ{#+@;2M>u2`X1reqNsTXx$P)-e_wl8MYhk8Z+>eIj3J{G&5bF}k#FF|;GA5dq$^4u@A`Wzgx>J>*~Ykna%HL+6D z*5Wn0u*()mLOBz&ML_|88lui>C_x+=r4kXt9(Oy>o$rUsYO*gFANZ&~Fi@h>8BwKv z(k7Hru_i)BkA_~zCF=X-+{&JUFXeJpb?eOsRj)IeQBH0yG9pi14Of0Jj>_jy0oTI1 z;OGUeo=sDihwP|rn+abv)D@8~-cMG#KOFdxG$s!QL8;A0h^WyPh!8*HdIJ8H7ofs{ zRPWbRQgwC$7e+fFrZ4=CuR;z5WaN{}xqNf;eRpoJCLbqp#=m8Xr-+-o3Yk2_;40g@%Ld1ZO{k{}@F0Y*`@G(_SBZ!W?7$(?*ZM3kA6Av3nfM1ah^?t>Uw$ z0sl~?&B=Ow`p*zX zIJ;TGq1J%o>&ey)>$@BUq96M%d;Qr+N1fTWLFE7K`Ih?bZJO~*LGd!;v;3opj4p8v zP>susH@Xr#=dK^8p~!z66K_5QYy+EQ0RaK*rXwzW;(vmJEBO2gfoZv@s3?)IFE|2C zKtNwh-R*uRNL)-T*z!W1$_VnYrzcS8z3Aqnd9;hjqa{4 zL8&e~B&1l6EX_!2=5pTQ_KlM8$OOjNubmp%IXM$l-i<9S=d9e^j`uX*rElWLM@E*h z3VN>HhBv9XK`=$DvnFaEEG;dmdw3xJAzrElAd>j%_n zcJ7e7he4gPwLRNSf!eI6kU0&Xj8lw58V$OiPkwy1;HG<@_JjqAXmLu}f16y@B9 z#T}c@3c`lDVV>yao->5c07l4rFe6f3b^9cq1+Z|ud4c{mFhRLWQT7E>HVKZuVoT5G&wfe3K(^dFH}4 z)Q(|WdZq2|@ZCq&p=>`b??UxQMa9W^)QxeBu;XdOjGv{UK6TgL?kJ}b@wij%wi_Y* z4Mlv<_o>NXeJUMAr?fqN#~|`Q(swg)4}%nu?>i3j9T)fk&b9q+X^tyQ(n5k`f2kQe zn=ftJ-{$fVd`SqI&!<$L>xJa~RbTc009os9t)IOdM>Fb{3LmdYi3$Uwpw9x|l~w!5 zUZW2j)c+dEUoRU(mW_81E4|+g#61}{^r8{AD-jW?p?po-C7H{lTmMoemaxBjim?fT4SvxO=ULTJ>MFD{MbsO zl!m0me?8M6JOZdl4RkZVJ~H%dw%PpMiuEO_G3e^B1^6R9Myj8tg4{!?TfB%mSV}p<)8jOiN%!r+*{)Rl+*gD@t+xr9uMMcy=A%_1fGOniKshm z!$Rkjy6OM|^ckU7a2kSXh0BdNxwVj0=?eUhhd%@g&$;{MEVCi?`nIT1Cd7xT^KkZ9Yk1H}lvHF!>M0NTrJS5_@`_YrS@;I*$}ceiUy zQUcQXD+uW zA9O{{Q#!{)f0sLSD}R}pf>fh_O48yCDwk-mg@eERfJg|7a7jM$z7-;lTZHsQw5Bo> zx@lVABS%La2@WHa#F@|lKt}IwLW|yem8m?H=1VH)e8ne(O&}-@dFc)v8Il$0MBd56 zng2^3`@$3VAspu~sG)*v_9G?c=efv|7>KgN$jKCufN5_jw@wc)Lw;NIXmfvfnpFv0 ztPhab@**aAP#@FLSa7;G$q9GwQ{axds$sk9^(ix~yz(vvDED4>JnJ|)eMLEPS= zguDa{f4E_ zksMH&{?;aP&zUBY80hq~8o&^QOHJw;=F#9Jd5?0YK&R8jnWMyyzht{b5o^p$(RORo zM*YI+^9$@nnsn{iM`tSQi54!d5dxLakFUEDz4Ft1q||+URe#_H`NMfGv_H^w`bFvD zZiQKsCJ^pz)fsb5@o7*rR*^9k!jSjm3rP0JOh`%hGdio0Q7#N>1i)p(+h)jC8fa{y z#YQTN)XZi>-@eMa$`b65w?*v!aTX&maXkj>FUE`wkv6%b1xY^PcOi^t!K(b``hXK@ z1-6}1ZuuS__bw%o8^w_Hfnro555t;buIIK1W-+gM(82q2jz$-nOAUAg?cap~wAJr| z$ks$IXz4(7Rl9#eg(LAkKI>FGX!7;KDe<3~Q2EGVhm>^+N&Fi7-)qg+XJkFfAwb#7 zU}*0YkAIK`a3q9dN)IedsZ3s8^9)r69%^$yBv^!odBCKVrBB}VxBerzzsTY-FdRGI zl(CW-p1dqaE;!`hJ0@Fxyqbt$Nt`dTBhy`1Abb|f2JJ75)IofXc+u**jRJc@J%mG)7><=QN(8T{q3HjI}h5Jct|nmFxc9VVQ)fjc{FL7iM9aG4z( zaa>v-3vRPTK_%2=ad(;ThD|1QM{lU0!tUE%k65e4g?5fbJZ1l68RI_EfjO+efRQnd zy9|aT0$MCe&iK+0Wgti~No{sZVOU0j2;AXQan#-Daxuwiqa45;yQ`O;e6ADS@BNjdzXVC}!?AGEmtHl-@O0^grAOvi> zg+#hz(cYvr7eoAD%3nsN#sZ&Bs0(*8QYk3U@k;}tPU~wsd&!;kU&midWFq6U#T8$= zqm4)QU&XAj_~Wz0DWU>b2l&PFG`yn{{H13f1|iF|zgKe??r&KSm^Z`!8x04(LtZOA zbIvl->H|415u<3{fJ!`+_%n&iO@k@%1ON}&yRAkAI%YG)@6bz{kwEWhxnncrq)OZX zpY3{tW~<{Ej2H3geone!;B$t@0;m?bk`5FB$G<5_OIP+@w#oStqDAsgzBmMK=k29! zbA^@^BJ?`0L&(GJ>+oYY8~XKJ5!)7X_er>*8rELt9$e8=n#UZW5O^H>b?wVx^|hpa zDyjAg8jCh*q#X?c*EDiwGETzc|6o+zr78SxM%9sqRld~!!>CFsdQA2A*cIKljv=9t zQW`^&>o=&zDq}na<&ky^It@qT$`&NLTjY6^{ zqj{(zic9jxxtMv4frsf7l*RylQSC;|Y+1QX6t+F+W{f@!vU&=R)#iq<$Z_(~LYIgw zT!2pdfAD6mf{k_MVJSI#$P!cxqns9C;ME^djkym%3f81zHGzV}9%r!|m(}k^;rfrC zwEk;a{Hh@|L_A|2mEB~df~FK61xZ@N;YNEuX0-#Br_K9MOKdjfG$1?OkEz6G<6uqi znZU`xzaE^xDc%7ua&c{Cw42aJ__4YU9`cl=H8b*9)MSi}e{C8Ij!|ThV*jkI`y0dF zj@5iW=IDoAH``~019Rc)zfhBUN$G|`vlBR<-SwTe2crMTW-@sFZIEXF{9jP;jv?OK$2(DY8<>3QsB#0tqIN>?7R`H*5>6U;0e!_uL%E4e zH(-ANR2G2!A?Cly1w4!&Zin98{#hwb6eh*K3kTJVzdh}5vK+*f48>X6ycOQ^9d?|0 z)8NSe2fXzT2u3U@83xdsjSmWJ3%Ok*6wq9WzohG9(#EmGmp(sQjHFtjaY!M#8m3R$ zmr*ZW&^w+qv`@|pAh7LqGx>I8W-T`%V?W9lQ|LkJ{pY|Uv^=63g+mZd8YVweYWhMY zYksby{{HV^ZN*Dj0`xs%2KfdaHp0_B3oJ$xW?c%T>*LUe&bqHCe_NzveR!MLZ&;{- zzo)`%71Z{nl=#RDc##9YB3p0UzSjxp!!zm(t7LmXbB;!; zw4ZIXAKESd-%@00C;TPw8}j+Zxk|skHSsyW8vR#_Y~-i^Ges736OHGHEGuH*s9;dJ zp-LOS!6)x#VJGETk4g`jPA)i@=1J55@*doNdN5aX8;R977kOHwb33Rmo)6?@E9Si9 z(8W{k*SwNJ_l7kw0m)DJ&~mLVb`kgGtWOe1YWdqm9#@s8nC zmXfGXn=eT*f1O6sGdVzN&z(Y^hAK1*w3Vu^c70?b^ z1$T|y>qYD?cd~y`SH}%N)O7=`Mk!lC>`;Pn8Cx_rPriv_yxk}HzLfe z5O4zr#F5RjLcQ%Ib=^epB!W=XuHhYDNlAzBKpfRDs~waF4wbfO&VVRo4BX}Kufo|d z9Gl7DhOAKFXcOAkXPLp~I_MSQhmIc2fEZKYO~JH2GXOla)0o#39Ngvd{AQs8wiCI$ zXJ)sRmi2y!&M-Hfd{XoRE}Dq=?7Gvq`0{0rbU^$9U7*{w2_G0VF1|0V(n&7 zE?oFHwRsKxG#K^X)JaZ)n7Yiu>+%v*Hm3LI{LczIP&aghfCc_Tzv$lSB>&yt*eF@# z{4_o|x+B+RdKV<$X#&yXoKI77`9!!_Sf;NbfNVy9U~WwqOZDFFYUYxSlyH>tu!b=Y zC+%_=+%UFke4fQ7}`{j~7Rjh7P&?Nj;aT@HxkM}mT-Dl7$v-7Jz z{{ACN21riE7bYTxyMXhUD+}wKeDDY}M64eGV4hrbb<6Wt#;yFA&m_2_df|E-GLC)g+xX;br_1> zeDJPq0)pZ~T6m(<3+#u)F=S6j`r%6xF8n9X9 z_cfS#-s=*jzcsy1q9_LUsOd?o`gU4KJ&9a8ONJ6@YQFRve#U1sUaar{OEnK#H*I#s zs8QV8*Ypav=XerbUy-nzt%Dpw6Pe_GI8yX#A=aSs!TYH78VcWv5OOap zIIErIk(=lNw_u{{O*`>1-93?6Rye$G`C10iJIV9+#5PV+T=!<2=z8ht9G%QZE(ZOd5-Wzq)R>7}q;PmFRgej~ zEWrzt!@ON?cHpa_R+{y9Ti5vV@^b!8ZrC(TGZc+b-{qAlM#@?FPNK~TiMx3xX8h7W2s>f zrH33YQ*AqZEGnqWxLPWMp&+-ivN9?uD#CPz9vB-V#Krx}!p=_fmPvPg9eXH5`3veJ z6;;9a@A1)Cg;V;-3l!7{NwWx1QE}2%UY}fU@>o$fn?#z_va_>Q4GffyOQBUuXf=>1 zDJjvFqYxrTM;Xm1H~~`*qj<0tiE27K1sjAhhBG`$tfZ3_M@UF9I5!u~-Q-*WNrF;? zR>j(y4nRI-7KMckk@HXyI>@#Rrx^A$@!Q3?b8LZgs#Oez$VfFm>@tj zG;jc6`8Z2lLj${9DR(UYBM4w!>+~#kbMl4s~nGSE+Zn z8y=y1LkWIou>2(aHGINEeiyLg(IlR^`Y62)b&wv|bvr$YBvAe0e{gO;Op8IX*nNsH zPGQIY(bSdV=&@$89`_5)*J-8@rXQCL-$T8BYcSU?X{|qy$|c9rqlBCg;}iV)5d~rH zVBL-)a^8wmFzmo}nA5}225jE4>T)AeYlt?F-BPqDqcgJ3`p>Os#na-!V(X9aQ8EfpAcNHNHSyLKn9;zgfdTJ)H}Qm&vd=Zf@KDYE@ zvb90q&zgl(#@Q2R`ZL-^*ji}i(>B9asB}k9(^fSiShEBZl|2F2mhWb@sJaRM_55`M z_i!7?zaH_%>$k*s_s7%3pHj!`eqx0!{O1uck+mc<33eim z)7ajYi@v|O7NBT5-VA^-5*>DNDGd6FsiyW`=$tzCWk~1){rPDko>4gog>Q~U|#|@2L%&0x>L`m^wRma71MwU{c zP5v1TP>604_u0ZIc_5QsEAEQAU4ul~!%Ex7jp&E<8GALEv+UXZ-PwJp0>gU4HZl@} zj9FLcz+)g*lOhy2e*U+M1!< z62D0I@vW^BG$18L9Zc3Vp;o;vPt+pbV;%n?)r2XQmIQNOOPjd}siR$Ar$;Li46dIn z2C8&xyo(~NQP3Ce=zq8w4sSb8g(y66aB~M?{h^?yMt%Qzc{EJrxG}m}dYp%r9b`hw zD?Iq|w?;*WxyS}JhV;}COEnU+q3V_pHJ#cKhQlX#)-GA~yKWz%HaDPbSe@G#GIRFee%O#?+3|QW$@Ke|&s=qtnX1KC#tg7=c95 zC+Mf3L6gGHPG97xfHFX9l{ZY@Mdn-F*qAa~(9w~lBbS?+8kUfd5Zwyh$|@r)9C&+o zm;78AWsU7J%_@dw!*wkHd$hAN{$aLx89Qo&N#l_9&&D>N_{|mwDm626bl%+0PvDSI z9PP`OFB?DX#=@Fbo}ZtS^7E(X(e(2beW0Ku@>v9agKvkMXq!l_ab{x5vs6X={a?lM z2!aLd4QaCE*1P@rfiF(y(8=Gz#BUuP}L<^g@W_C`xMQ)6y3x8^7 zlYb0g-hBX1nhaXS12|WMw~v6c3GfY*IZdODBFSH;k|pDPMHajix_<%xs4E#9<&?pG zHhBWxkUB>StC16?3OY7d8L9;QOJJJ7pBq2l4toJ-;<|n@M&JZG8c&vzj&aAPm2N&ADuk{~g5$_&kgFMjZFcx06rvhPP0TNkX1Y zNknemfKAfx28DLU@S09JN$5%l_g|^i(>_fCj15YEp1sJp+4Z2YHM2Jg|M`If4dcG$j8ND5c!=DfQsV~3(W3)Da*3V>X6WbBhDZgg| z|JKeIbUJF`lKhn0346ddI|u-VGVf8zFW%0{9$P^DkQbn{-gCgn*|^^NWYO;M#wblb z#bw5mOs2OFxGY~Uu{xWdy-j6I#3P=Ul{3lM2K{t4N?yRk_9IdFRGo-d|E!!SnYYV9 z?=RpSyAk|i%~!vJ$Xz$|{~r|630~?y!zU!OFClaGK56mFv=ZNh?@sBDQ}!wOp@#gk zmWN%GJOUT0=M_xIOF<=mzk9K}#vY)n5ik@DdYlRXB!$fS5A%!QvN zthLrlPAz{-Sx&3JGN!zqVh!pnK<|zdG(ytJp-l$d-8Jhp0)#4ny#$M_^C6HOq~YZ# z=WoF)?KXs*NmRi7_4OOmu9JMn(7~4n3mN?b_aElMJ6xzoM|E+nr(mV03Tz=`L!rc3w7YRLacz$6*5n)p}eIQE#vTo^zS$&jN{e3YaA;Wq@}SyndaKlSed4W{94FyM;KFteYKm!p+-7FNpU$l z&(1AiF5H+O&vWqw9sx1WXFtM1xEkSIwTIrTP%Hf1^J!1Wm1x*fc>D%KJfjCMkO6(1 zbn?~psH@i3>aNk`qLenKF=GXB0P~`@-}>@^B9H$x@` z`F%NjSdyBxr%3qU{hfzZ&m*MFM{u69RLa8lc7XZ9FABg{m| zu1qi1=>P6<1RT1+@(`I}O6bd%((djza+L5~`e%a5kgxx>-tTI#nxmLt(oX83E!%4N ze?y1fBaH=68x0#G@h9`=cyIjbd}>Ed?5?V;ylN>M>g~;B#RYus_=W!9h+Q3B-SYyY zC13){UNQdLsdrh3wHXN`?t+SzmdEninji2C;j)M5XlrAYWR;?xP*mI0KnJd`zrsXx zyV{oASe(xh4$NC=3%~P{vnv+am2J4a-W%ufJSPS|LW{nhAAy@Fln_OY3@$6%SL+}{ zVtw}dqAt#45(IDnG8c>gN(47GHEAUY6HqS_0v{oLd=P!R#?hk|W5^TW6lv?o`+%Bq z4^<-hXs9mEkfQ}bH$~oTRtbj1_i%FBa->71+d#KI2blyh0j32$Ifamkz0E&x64CTmMOwe3s1%%y7jEvkqs#;Y1EWU* z&G!+NBHwm&*gL|>o~h>T}}#7rKHkUxc=ne4==L#c_>6k(hoTiW_zeswG284X(qO-_{( zUr=txBN_ie-<2-1G>}ojzuNe=4l%hb9N16vi6}Y*!iZ7-1p<)=2Bk>4jH-fPm9bY3 zqK^R%Iwx%g=?HI!B{Wqo$|eV{omgiEk{M%u@0P(wH$jF1?^fcz)%IUdyb^a?tPocq zax`_FI(R||K2tS#`$R;mHM-C&TY?1ZT?I5VqQ!8a+hL4|bf2Qbf|IXg`R;Y>Hk zc%VkCI-W&3l8ha0V=Oli7K9HM_W{9nALxVxsXpF&D%gP4*_ZqJLI`p}0kG^wB8p~w zRw4?5=y)VwS{+Ky`MxrKfrZF@jYX?5*m29@pikBM0Z%zIbt;z;bHjJgBAmkgC z4qvLmRY0@v$rHfPT}D{`j0K8 z+DPkMe;w!8<$B_9kG3((Gj0+6TX$I1tN)`_!JXAI2kn67{_@LfpBYJcmH zCt^4I> z%ju&s2qxU4N|+dlb^T=igxnFPE1j8iJqPTRwI6b5bIEHeL2vzUWkL#HJ7q-0I0yFl zxTyWH>G8X@r@qsR@JjBF)udvN19{)o|L3dTud5py>4eo>W`Cz9eoGU6U{T#?<;Q9Q zP>PB?zz`f~33=J2%Zj3*yaa&3EYrJYRoK|)yr z=rNB!Yb;{d_uQ%q0r!7jMNgD`@qd-&djN_aZ~ZH|^KN-A0~{l%L$tqR+rT~U?7bZ6 zf+Y93Ru?NJ`9Yh3`S7yAet@c5ZC^8g+L&MHTEa>08G66Pid4O{PtO;anzq!&UB~pR zR+|N(tTQa|3f#EUVwAGH)xbn8p$qCqA%W0k$;MXS(p!p}0PB6R5e^KdeV^--F+K+*m93$|w-&@huXOP~fgYK84$r3;8cEge{MFdH z93f~dmad?4jDzJTf+oT70_Ro$*%#wHN9%hW(+Y1oNiAut8uYW=e?b2*v}F^12EaH} zwBhayol!_7oLDv_90~2|T~UJsg_>xeB#=nn9jpY;BO)%~#gmJ+Qk_x5P#VZf(xZzz zl%2Kt`=w`oLk}yUoygqT-LNc9T!8xE9nsOvA^X@+&wCX_Td=@IaMmSc7WeF)!kf_2 z?a_0H=FqE|*242wI~Y;doDizi)=B2SyF%LP>M94BKk4+w&rJ3t z3JMAy?`yLSFLEj$-G;jk8?nn=jSE?Uk zzGAUs2B{o(U#vDWBowEUqz&h7k-NGmwv*0}C-@0P@g9?_FL8i_9ui%Fb#dvrf~dPk z%5RK+KiPZ53tkf+m?!2#7B_yLU+US@49`BtiA(o)@378SWzNQxTx$KA2}vaUIB?UH zI9`#i7$ZjcMatiQxXy=qYA6ewGuURGPZw-e%>za(Rbpd|`E>&UMQF)>T%}HvIkl>C zpIZLp;|y#2vWB6YcX#N#qcj*+q!Ji7|EnxX*ljMHhJ2NNCss^6G9!4h(_F(5plu9&FLoJ_3NMSts8y+Xd8COQ6I>usGzI0 zzHev7(!sC8?w|!e^eZoY)9>W+f4trU;>~6G$cl?rdfs0zt~xhgYZOFUQ_uh(q)bO% zyox<3O@V5Mxlb3<(cfZ0!<$~2i_bS@JMWsi;VAEkDRz%DWY;j2&C<2^99Y*dQ5h_mY5$;KL8Xcrx-4E<|7TKFhloTn#>2J4-b$ zA9RWis2QXcSyukA2p!~MwCcWVSN@06;`-T}mG;Bgt6Ni|hr#%P`V2CX(+;IvX@W6| zf}l#!tcmu6Dq|G^E(`T15&rslH_E`&#NnlWE8s)9M1>!a$uOwFEIAR0w3Y0Gmw`el z=lp8O#Rp+hG&+YG97~UOW1_gzC&o?q5ol8IiWj^eK5{DFHylNuCF_q4n5-2K;zJbl zM;70#9M_mDXj4jq0YHgnjb1xucFP4>b>u98`*+n3tx4ATyqmTCu85gyl85+0>seNB zFEC*8I2p@%Yr!09NqloD3#IH4BF7)Sr+l}^)wN2CHh=oUkATxh^ai}eYGVo=* z1^ju1h7o(;E75FA8OIj zdoqZ`Bf%WdEhlLmKRj(wxw$5*`V{&nQ=;1wbTA^?6X;fQY>MjY5+mJd_Fc8Z-Ak!?M?8E8nUR?^#BJz{&DXGU!(%BD$I7nx zc)9XF*5-36g@)(xV>nSuL}?7@wcJ%dGY@VGJXyOStYhG^G=eSa3LbS17bV=*h1XA_ z925uG*Oit&TE$-Zk#%%a` z?2IH(?#;=SisU@a)1oV;v6`qSXuCG#(5AOcxcSE*P8zarRPS1W=k`f9)2)Wkj;Uwd z1OOQ-GQ2x#yflfK$!Iizi!=Dh?&+Zezjlz;QCq<27HZeBuklJ zHYaw|&RTV>7E^qz^9xN+Rao3(zMt!HG>`bgoD4@n@;xg7Pkj6+>MQJ3jkJI*)BF|1 zjFr`6hUe?r$2~a`W}oGG$?~bIj6%*SrL3=f)ZWYLR=sI_Lu5@%Wpmq-#|3tLHdbBO z?r}nzJi4|oD#M5ULCJsODt9t`7V*)|=hKT4W+Ne#(I#dO*4&hFIzZ%~$yeFd^62N6 zx5ssfILRwuGASODb5WrKVnG`w=SN`0RmOAP&)0i+stzLqM2mn)Yx{rjDRyJ_973yV$;mo8@3WH3DK8lpi3z6aho-SlDj zNEwnh1Zd7O8Ep+Gl3O05)0eE71Kq>N5@T)!f%1TQcFXl@n&o+S_(A&+YD!;XsAfd^ zz<`&EQCi^8*ZNgR;vp7C(DF;uYnd+{79o|zS8hb;+WCOR^<5!zLYG0DFzmhfMlBf0 zEYea1EA;rlk^=;IHU?Pqyrskg(C1&namhurn{Eufj7ui8d^mr?dZTvaIYgx%Kg`L& zq9^@^BNUZ_+KvnLrN+CDlYFyN!^TB9&~WmC_5LkJ{EGzSu0~9ScTd?}M>hNTssOzr z2w6rpGdXv4qP2K?_EgzcRMsv;EXGSfu14$>P0oNhv)Z$T{#USy{M3JIAsv?Qyq@`_ z;6}-}n>iIx@G+?^A53iACn81`k4Ksxe(SGl$EIgL!5(E+cd4e9DlPXXy#TKku~9=X zqx@K0SQctH7d3b$lJ7HmUl>_#fZIco$C@IK0B0nIv3Ri=Bdw%<1T3f?N~=@kP&^$L zTM0=bhQgCk8`XorqE3e0X!-J6I(!YR!B3%^+=siDC5u~6z0hs6&U3{1sE%H2X-Zv! zFa!o!)i^-YJekFCQ~E0dYLbyQpmoy1j#CGzFN|D4Ms__ak4B+FCd295qa`u6a^jV9 z6FXwe0k-tGr^<_lbCUqvplfXL9wGL$EivO#ftSIK6^!VW@O}NrQIWrc(7k-LtHEn0Pi>J@YwzB9a#`7S}=E!20( zDqI^FB&TQOSz*ebc6kmabWw1jL-$4$1Vu#!-BL@ILsJ<4 zl@TdoFGO#uhhajiGJqrAA?PNdlS7#0LRK)d`Qe*3casGSXwje{7=XC%{E4{c!D*@w z`6(xyaQ%5s#tmCKF5YQ{q0!!y*JLF7yrv>bQ|ya4{P8c;0+1z{4dxWZlnpyYoR;E2 z6v#gM1|VuKLr{c7oOV?ts7oae`sB<84(O!%|6O$-5ad;yN01ON;~{hnQfqXBDr>MhQw z+TF{~7{{!+t1Y&H6IId18j)36y@F1x`D?$9iP!h^xp`|nPlMi%;zVw!agJ9D`b*oU zO%y-HoyTZNORw;+nfJsyyuJT4-|J`#D-ixbvwmfPnl)gfRdx?fj~v|cmr+LJPo>@v zk=G|QIX?@JA9p?Xm-+qtXLr}%>XU!eP)KZrOd#~;ml!Zh+@2rt+^qrX4}A`muct9X zYe?|(x#9aRpCwkmheXt49qfRYa`VZ5eI`)+h-y?C4N|d$E&SrbKXy5Q)kp%*nfpE% zv;&r60^Eeu334V|5ud#0%TEK;)x$-(S*KB1#OvNBZlDqX)LDa=$Ce}qjt<-0eEB(L z)ufq$4uNzp{f|VEc)CG|;}q(<-xpEK-rpMBI5Z!M>cf^R21>tl#eQ7{g1LVLTaKCP zKfzF#q{AF3SPCv>4N<&L06*8CbAMi|6HHUkH2S3t)%oE_H~J|h`b-t`lZwA}726#V z$vck(z#h#XUErCMb#Rd#llp?pI7uU!q+F-KY)bOvXFOzTOP1mj9(+^lSYfUibi4X3 zM$K1=+9oWwt_k?p89M@PJuN@i;ay?3JTedz{C1rMCCDOk7mX68gjdU~{4V!`km;08 zMMar}(tK)g(sBWhoRLlf$CBqi+A!-QbCP!fhAt8BD*AiWSSz`Hp`VZoyF0R%!gx;Mj6!_uL8FDx#<(RANd%WlY9hq5^HC|{glIy z2s?h!O&9{%J3Nxl>0plLZCA+RLNK_q6VBZi3PlH1DB3$M3z|#^A$y+;xl8E%me;7G zc78{#OI|{UbE7k`sTGUbr(eS)s1Ge}KUJZ@yuj0wR-Evw!(61eopZ@iV+oG(p$(JW zYrEL%KnUZ)u`L$z#_F5IU0jWMWfG`RBDUf9!mttG?wm2(_lc&GwbQF<$W&%SVUmnr z-E=<>!M(9_W|7lqu~s-x6mRveaHca;X5)l)n4{^|8NghGm&&IH41EPLuTMubH4q$r zCA+0#dz#1hA9)UG!I-i&6f;p{bBz;vQ4DN!-jVWeL8hw>#6yg+yyD}+Rco->jm*wi zxS5=o$XK{N^7XNs2ARVuC@Iy%Fp49R{rU-m!U!vKZ$Yp1O?OoU-X)jHY&@1xkzk?;(w+0AAjfn;=LifU>AL zy10cUv(jX(UX+xiTH4s?+76&!KQS^oU+>E1@VZ8LD<{rg96BC4u0Y0<@Oz9jn2(p$ z8ukdOi-{GTFV~x*lyD&+AVh;Zl7G||4j+2na^JSTGn8=699s^|1e8pw6w@F>&o@62 zbp8b$wV>YiespPv^Fr(}{mU+{ZrgGqUS)+Zs;8I31SaH@Qh?G>;Y;*o zmh=6N)^0KwJazgp?R;e{4R1ZyV+o=)=OpHy!e}6s5547mSTz%g@whWY`yE4EwJZ%ngW$xML6&{27S~wASwANrL?~(rW zsfC8TB6>;EJqHz$Y)Y~>lo#!K-I8R~HJg`l*xbkej)bc#KV-g?u;@4q-=;`8H0> zskfoThw&Nk_sIQZX{*Wv3RN>`#C$|hzw?~U-QA_mKoG}1K?>Gi*&s_XDmrqJ(h6nX z=+%m@3e?T8uVXA`>v^HKCs+{;F!TW(;1A}k?;GIC=!j4HO&V=Q%}=<;n280{Cj388cyLZLt8HhoLQ$AfGxpP+T7 zUS#SC*z*`w{uFy#nU-Rq zA$RefRZ9;VdalD{IuLB^ZIh;B_ev}YW% zJ3v*(RuP{%;%jm##YmA$UL}TyX&s_MSQHW_PigXOpHWg+xZTXx{t|6PzbN6`2w^R4 zIr=QPYx7u0Jxgf4gh#$;wfqne+~BDE$~Ei`QDveCF9JIgkf=d$EkxK{xj53@ic%lZ z@8L49FC(6v;qD8ObPB0U)DJOG$hU$`Fjb9VdU<0}!)IHy-bOaEx1i9NpRjGDGm!m~ zMOyrRQzUx-HZV@vlfeGArxv%NoPXU09tI0Uytv|Dzjei{)GZI1#l_k%h5}ts{~Chp zyaUuJ_MvCfku!EO zxH7%$&tSLXR^zqlgTo`XP`2>wpDYmj87@f5SjduK=atoLYa`G#k9C6#crxRe`d8&E zbPs{v&_gFOfrpEiWW_+nqNrt@r=^U+5KkiLouAwde?2*6I+O{)mXMn>+X=Dn+k2?CEzEA+U0+xBP8=D;6J#!ZxUW@TjJQg%TrLS)1D1B_zuHt_}yY2&18;wb(4A54Q{#3RzWMEe^yjJVUt~n!a=e zbu9IMaM$MqZdER_vZF3Faj&NP*Ep|So|rlzLqw+V-2ZqRi2mfy5+fR+eRS$Ds)UV z!cu@}nXhrnQ~6l-DeL?FEl-)sH~4T0NubsC#Pj!G7X(Ie9z$VSSZ2t?L^#~snzRWC zkL^s~PASW&8U_;gx&8aPcJqA%QsNthIs(CDNo?hK&;=ShqaF@?; zy+ak?D!&nVcz9qTYGIKLCL~l~+N?~W=>SSA$)u9-MV#gqSvGK=^Qv~6GB@Da%N#>e zwEUdRR^kvw3d1QZDhg3AS4z6i0)G|i`+(!Pp8d7!er9Z2P$K59*hKwl_(_tW>)w~> zN>O{eZ<%2tSxge#@p`QeBniYx6q*fK6#~B5mvYxJc5jT1L1ncfcVUu_!KrD}TVpu3 zIlRU21esXNE%pq+{F{_WIOyZYH?8L85a}^)1Pb5tRrZx%56Y>`y78wNjhj`}%z>CL zE^N@d_{C#aJJR?pto2Y5a`kybd5!y4cd6znNM%f-k2&TeZ_Z<1O!HF(yDyh#`;pMd zzG~Cbc{}|n6fd&IR#CmerlOMYHGJDVs7{~O3ppjDj{N(ZJQ`b^YCy7C#=IWNO}W$k zotA2WOR%JFstUGdzv0HOL&Ks3b<%L6R?>KbKGw!ZnCHR*r*n& zj5{D37Zis@c&)-`4W9`0p zC^2wx4ej(lXtO`RrNrsfd*3*#1^P1&-KO$M1e?gb`iK;CM18rcCK$fD#Zb&!a%^;4~s4(tGX_+;#&g@hDc%^CNv)M#|eBV?qSLv4)4P1wn z7% zF5K5Uk<@j~pEFfAryfz}<6AUuI;1_BrJ(%&3|&MHX)&J9#Hr2WT7Uimg~YMXB5Y71 z$ZR}z~6Y>kGKD{H&229;Fx0bk%36Z`mGx zHpB^;KkXzrI9TQKeroqCF-(Gc?d_OA9UR4m5M$TxLqSkZdMz&7KBUB!3z! z&zKNWH()W@L6bWA{@dZeI7-e0W;5iV|LILSd^cK{cc1H;j)w1=B*s65i4pq>wAmdc zk96u%w?K#HhZr61=L*TAa-j0GGEW{P!|r;B{XPcVE?X7@6G|tO+W@z2<##z{xw;i0BELuq^~a%y zH=Z^jcABku#8`#PXlaYf_}jOuSH3N1L;Y^U4ZPi+Mq(j9ulUr|)TFjHuMq&jUJVTc zQ_bbDhTk_m?a1M}KfwtFDI+5j2O!!jKoC`3Zbz6k`kjk^Xn23l%%IaK!|3Q}T>POgqFf`#;J`qgCBABK zX*CUvwo6Q~W`i*}Zp|P>jRhDElYyuz0KT~mw9IkzZgiOg0}>XLz8$3kFh{8oRm}mf zKA#MJ-~-LV8N%(~CBw)WF0oqlE;b-Pz}TQNiC@e3U!L)ii(niFFym$Nm5GqcPFs0F z=;czp7>E(TVt$`=k({q+n!DG?P2dcybN^pdy>oCZ{TKBc+qP}nPEKqaCr(am+qRt( z+qP|-*tYLHzxTaW_x?3qU0vVl>6z-@v-et`b)gOg1qE>4gGc+ETJi8lZ#zO;pP8Yf zqld)DBRR2DFHxxC(?Ek4&`hT@g9?7Xn%qq8D#4xYOFfEts&Uw?`O9T-FsHn4(Q4ET zb$L9btEKyXzgcWFcyW%&XC<9Wy(1S1>K#SbfQl>RvRh-2g4=Q$_`aD@LVYkSz(;@o zx|%Bxy&FUnWPUOzcKPM;pB;WE+QTchrbSwhA>Bga_k_I0=3C z%$|~sKK+0$f8RLwvltEaJd`95kIiATdLS&M83bM)rx=43h#A177<*I}P9NrRKc$z6 zeQNosZl!s8A~ciO?45{d2U4FmIoweaGur}31BW3Qw?Y0xXe*|6OT09!2S)pbvp|sB zN7`+Bw_GyLkD1Oet&kGKQy=Z`p3kw3OUqHS{)hD5XVmGGa!Ve%>!BKsz+|d9H*V)47FB9?{Haxr77U2E-x{ zaQFn-;h*|he!~fbhW{qlvJpZ;;B9EVj%7qhH68`u;j1e?|waYLs{W)|4|-|CChMh4~S~ z$L$~e96rCTU+17ydu@>J34b`VUWA0b5!-t_>K9_+oGoK6HGMy8h&YtGUf?4nkAq-6 z!iR+4Ifwn4#gFf1EJ~1IZ!J06RaF~ym6UaGW@N$nw;h|OjpRYl)o=GERJvLG-<~wF ze+c!&tZc&Ov3jhQZ3Q25>mC|caSMpKsGmam5sEu=C9hRTlLfiOfnt%yEOL1H3Y1^fU`%M|s*eLN>lkUGkN&~7x9p(Y8DOK^ z_%ycOhyP{jz9VEN!AGM~l;FOKQ>x-?zlz1dR%ws)>)-~ZYAPC9%G$+~FLJO;3F$E4 zkQXxn;7!|4$E1pY7S3K2FaPFiN~M?TYM+09og9HabF)!IJCE4c&^JsuOjz*-N2Xwb zQb(2WpU^iI=#2W**m2n9EUL$ps;Zv})npxPl6B)Id89GiEp`Jz2A|y*k zj2AbBbCC9SOEx?bGGDT(iwU9p3%3v&n<#K zt8FWwLyp^2Z4q||E7#&&_k$W{dP2f1$`DGWG*ay*;fYd$BXz2Yt7)@+KC8j{M62Ku z$d;+f@hzf)-q?WKjJxs@<9i~DF`WXb>)z#SGzhf+0Ta8#?#ozy4 z3<$13WFESd&@8-w3pR|QR5xH4E66X&iHThQO8$HPCPyod@$W);`<`rlX>OvFR~uFm zcK7w=nLJ}-dM@E;PqXG4J}A07J#O|l$B9R#XY|*jrvk2IP&@yh4qZ_OA{F1x0u0 zh=4ml`zzkz&XxjTW(QUr9UaL!$Qt~Tk%>=B8}(OG?3jAUV6~`u6aw@Fk%?N$i-4KF zUS^WcEVOxrPaWU6>FA;pBFi<)YHE54V8ij)VgXT7^4H0s>YmDFrf5}7P07$FDk>`2 zS@THWOBE{WdP0bV0&qow6VuaXsu#({sKpPg>^v!w&AC9YS)qsI|<^DSmer3aK^(2ZN2QIpc)@b*oJSR7jEf>hB89M|STD zsw|!$)sOtu&TIpln^{Ux8{x6KfVwZ;4H)3N(D83t;&~UXJkVoC|-KrRHv$8{hz;{TvGm->Y-&QJ!QP!o%jq>s%5 zDg~dLm?-jriLY8t>B_v*>-TdCtR*BaZq^N`T&KsAC(1Fwns z-p~6*5K3>XtPcH?4Da9m{QNwGQjzj=xND4q7DGLgd<%ur7hwc zTD*%-#L@ZN$fzE`JgZN3&LjT{l(IJX@tCKMyG7L~tXCZ=alWh90e>j5JDlb^jqlQ) z;1d@X?$=gVSI__9gCa$hbFm$i_)eNhfsEESK7t-Cf<$MmkfOp`yXGw@Yt~YB>yD0= z{b7iW?Ma|0LFn)ax;%ThiYmFB?(k!zq_*iLx+P`+z-u5QObw#--!sEX(Z0b2#JOB&?$dG zn++lLnGFfvlgp>F0ec8_rT!MNQu#=UjbBA7l&7kXgG?w)C{Gd+A|Runz(JNyL+T|8 z-_jC+Dtqbu$FF3DUV$w}LnvZe3oV75P@D^dPm~yp684LOp5B(V{qGWzzTh$?68CzH zl(IZj9?mPdhaA~CKT(eoZAEK@%sm)cWMF)jsDR^r?-jU+e74j#eN0y=3iNq|5p6`J zMmUL$ZuYA}zpu ztPlVt1>f!=K-s&w1{(~;lKp9okx-lo)RaIdjx>mYGT1OCttM9K03ssjg_K2aXr0!= z+j`9DApk?=`B<0vn$RrPAoWKC0Kbat!a&MWO1VpU}#)Ru<4$wzG|KH8Ej>x)P7&N5-g>Hc!L4n^OBCzO z#=}vs6`wCO`z{UvL?Oo2W-?p&jx&IUL(40Kf)*SiXJ$=s9JQ$257EjBPrRfJb zPhk!PP?5g0Yws7IpdenQR#cpA1VAz#>A?ECyHyLHpj`F$wavU8~Qs8cq)lX6D@TPCQ7*H z2F_)eU_>o9mm;P__9zSCrRr94B(Z-qe6lY zKAFlGl;u|;f|0qRVr2Zm2*+b8(lHG??+9mnkWQPkv3Z zZ*`y$%#_^P<$w{3krxI$6rv^8A8C}_;>`)^^g5F3iEYm`YIOVSO-7%ee#euUcF3sZ z_cO&jogJ0B7B0lk!H`uMqtKmh3EHl+Rs1`hFX|r>|Fl3PT0rWhm=;L?4nL08ZF2~) zOlJ!&vkj%tSF}iJA$^y@Tb2bG@KsaTpZ<}>b7b5I{he1>yEN9suEK74C`V306cC1h zkK_JJ>t2DRm>TSQyR$Vi_{7ColJy=EeKd{`k<0t_Rv6^o?TJ;##I4#g2A#z!b{%~I zuf4jG+1ZwzR$4G8#r!#c!Y{S24`?1&qG{xc*(PE~c~ku~I2DDGEk$3{q#oYGC%klO zvivSXQ3oInH5wkgS))W~lBmX?$7$TIuRf*Froo#_r-e{|S6-r&ld#=aX47~tVzGlf zcdD98H;=scGT=((@>_zv94uYEh$%;t8$Owj=YXwBW-k7g_m?Q*Fek~R4OB#70v7L2 zQp|OT#N!kz7~~yCKVp2jwDIk3>?!$#!BMtg0ot~d|`X{Kz!618!Le2VZ=%wsBqEoN|J1ICG2__s#|t0Asbj-ae7Q9!beb4RnC z=zRVqp~jAGAnx+0xl~3~MEpTwk|rOY`8r=7jT2MoZ$t&d9TbSkBh|wXV|JH@M7|4O zzVdMrKcZ``Iy@!1d|~^W#v`(_E>8)SGcuu=B~j{OpYu?Fq%u{E^yr$RxNTO z&RM1U_|8ot#&V=wenax|7I$M4M+vzeu_QpSfbBO|B?2$JH(%6*vpduVf*Fe1zwzfhxDlLw!i5L3a8fI* z(1!vTK_?O%>jL7>-lX?*Z+OfhCkJ{@U^btR25B55{$_WApB z!xh8CQ8c@VheyT*_p2aOaY#Z&|Gb-pLD9Q4HIz6fcCE<)IcuB71F-JWCM~J=qIU!Pbz=)*&q?1QtIqh(8Zj zR8@VbD6?);w41fbb0zp%Y;CeP{nDq8_#3?&oY}NpK8r-G1}Mlu%VSW5%udl%!Q_NI z=J4))X+3(8OJ>!JZtqYI+h#@1r+0h=hD zikj zJ%5G(#fVkh;1q9RZO41t9x{I62)v9(JCQT07f?t*9R-Nt?9KxY#|lNMZKt}`3@7_Q zwgc6F&X!!no7Arnb$R7U7R(ba))v-Z%^z}NiM);z-y0kbZ^gslCQ@7pq9#VK&mN|DK{5lI+T9>Vf7;385y?v`FpG15u+aR*+oi?Nhxzw0!)e@dW; z(D1ELaLW$&ZUqlt!k@rF3TJERXyQFMm-;vz9-R-}%?)3AtEAKYdI(sZmFnbo{SoT* zDEU+<|JZE2`R6Fa2H=TUO}!s!2>nQ zDFGIac)E@HE9#((-*Ps*>Ht^lTh>Ow(}>KNq~$*2zck3(fdDMl?Q%Y!4Qjg>?tP7E z5H&Uh@jA4$=SY@PN-#sL_Uc@XdQ$1rzPIw`BXI{04E=NqRU4r5o4ukk-xh>%>{R+==hEEOHoPj@;V6$a#xG z8*=;ui`0ss1pJRepHZ|>5%m6ks@%DuDFd`@*ezBdPbj}A9$r9DSmouRlB#sIyTd+4GPtxf=0w*N4Jn({9v&vpya#jx6<9iq^Y0FryCU zJA_7CnSCLB81`N_0VEtn3b3yso^~Ql8m8^9< z>R_L-%T;W5nF$8>;RrGk*%5Cn9=uER_fywwfO#ynLXkrDAZJ-$3>UfG`I);#nNP8W4JWj*^SoU~d& zVwa9g3!Nk#p#kqG+&B<2G~l|=J)Wy+(C=(PDjL9Le4bfQrE{W}=x7kxzdDp+*lPt` zYN1jqf{(&sJG?P0^!(to5B=AemwuLoDCWYaYJ!=>v+_2DDQ? z;jsY|edR~Mq-GWr1jNeQ$H)5e@-i2Ieh&WwF9H3o z^OG0;4TB?hTeyhr%n=yt__w0MQJxgwx%pcl`kX`Lyp$8$wy1%Ni#roBy}8*LS}AHl zd^+wd6C_VJrvcz|%mh?bSLdlf^EeS!$T$=D&j30DQVum6fE@2xgHG4#0G#yLpT%}$ zn9_=h^#=24oEa=-0O(^G5sW6rP?Wak(CRGl3^uD4rzhaf>wlHr|XmL zUqHQDJePDTs6ym%4`lBoS<9c)EC9ZMkf0oChprq1~e|Kmecq-?~sm{~~;)xSeD_Rr|2CoDM12achOO?+P z&?_!0OLGJGkYrR;7BLo-bmVh*)TF|aNb zL}U2sj=c0I^k6qI5+>?5OYW)FJunQ2q8MH5NQ3W!9rV~Pry-sx?05yM4Ln;iN8gwa z_ETaKGIlO=#ylR0dZLQ%!d3)NCmEL;{2I0G1@Ufq_T3#?Nke>N>cW}nKdSRp23fYo zZaXswR?v6>T}ngrNRx76t;=332WyG@Q(%~f(4)2bpZs%A_I{N~`@ zMVy}*cXQYWH$D^gX`>@VzKa(J*8}bLeGT_ED*LdeZBOOW6h-aSp{{mrsH5vSUD`G@ zQ(3vTKv&u)(HwG{1yI{5a4TDY^$9SiN)w-7cp`wWrA1k?E|{lgYT44WuuNUc zo+-8G2Jf&!0i^98#AE1%P{#wBJ_fYfJa@l@E)Id?ks&$c6_ldej<<@l2kLGBp1rgS zw1y014dNh8&?Y7H7z<=oc=&+bwAC!SawqE8ZBbJ-WrcJXT%La~0RkZu3zY2+n(qk3 zr64qO32fSm6j2@TqT0pjhnb0!Omr%sw8w_)59+_5FC>q|B`j1779L44#?{tZjHwvV zqt2Y$4kWSA4SWdgKc)U}3_{2ozRnNZuqdv{hd0t|cHwvBQr`zfzUM!DXdWOkDF3lP zhO;DwlW>I{2+H7`PwMn9Q{%5IkO=xPpd7Lkm9`QOR^k!qY~fg1<&3tuRza z8t_n3n4hQTFegd)4HUHq=0|rYezzAp#jbkf6~aVeme^7Rkjqu-honH_HxBr!gyZz1 zul+7E4R|0n8)v*9r{_%zIa)cJ>75Xh$MPl1elT59@{}f&WtHY|3IAKEZ<>2f^i@ve z8K7S{=x|qO-&+e-JL!4`0J9r#M+D;HkGUpncO@(!5gS5VMnW3q0VyL%xj3&QnORybcKx1LB z*Wl*of~`5(OXup(h6YwiS=9E_VB7}@dkq(S`V_mQs+9!^b2MGKYl?w zubzXjX<$l*544nDYsI7AWH^rQKQZ2P^YU@z%2nI8Sy6jlq+WEsgOYIEPwCcn(HVZy z<8hlo9qQa~b~!g~LF$(CVYQ~F)$Pez?IUDGuOHnBQQ>HtFPau6(VD6XAE%z^9GYOs zLI+C1Ic;h*Nucjn+Id>Ma7iNe5UECaS`b5ahkGB}$TU-Kyn`H2dNV_0cjaMt2I7Sy z-#*XnNN!_;-+$NFoS8vI(pZR$vSK1gln}#e5OLbHKI<6&T$3yxu02VdRT;cUX!~}u zt3GE}_BJl(*6wM9DJa=es-mp{y*|2;Pi^Mmuhcimu#-%}GOOz^Tk)ST{9luN8 z@~gcSoTHr6?taXa!(6N%XM)FdS!7aSc?VAj^q4WP5p#Zgcapv;Htzm|vO+__b{8Ha zX~Spy5rwizOzVZmDcE;;*sSpjD5~Trv5lfdZlcoY()B)*oP9l(*7(AUvNjL5ouozh z>To!A?R{h1`n!I&O{X%gH3>70*aPm3(^RU+N!y)>3qycbV5FOV(9!j;6v--FMbF3F zq*QxI^|sr+r;CkM=T#+hCcqz(q(*2~w>duPv@H0i4Ipp&Z(ZWNs&A^eZFzmS)t{vq zwbi|=!>7{d_Uz}`9Qk#LG=r41juF*mD!!>Wz49a~ZmK%)l`{*5?wWE6LvmVK32e^?=f$VeoL>v)y}a4c z@0V-cpJnO==q0QQqnE1PX@qs7ELVGoVI<&~S>|She`tp|CNC@Z_L(8RKYWF}&bW7h>Gf8YZXo?UHlZ4`dV17z>p;)h$ag*7Os3@(!DDD_)wB%sL_F z((Tz*ZC z3|K^#M|wal9T%~Tpc99Ji0cWJ`VLQ_J~nW&WPGfw>KGtk6Jyi%Ec5-97UE?$+sg>n zI8W86lrdhOOa1@~`GznY?kHfVg{pr}^tqvZ|H@rW(y%Nkl}m|r{Q5IEIj&Gsy`e+k zRnr}V4yOL@nB1EvQCP%fY!f`GpJ98^?J(ZjNh0uRd2>;%Qeu*4%ON{jr)N~Qa2=zo zf&4ePB@}6?3|~leMqr67TfCIrPbql5^2~;OuQ&c3`X?k==i+H`pYyDwWGq{`P2>OP zxY;;DXCDuBvT$1B;%E2WNVpZNsfa-j50!OfJBBKXluGsVAg3L75U`jTS|;rcAN9%= ze>6co41p;Wa3Y*2njsqY_Hay`|5U3&l%nJ zG{Fg@Xl4sZFQQ&TE6|?Yqhsz``DJ;|R>NESFR=ig2XdtK^}NRVj#(S|UjdgH+U{=e zt+!Mz;(8dO$C{DZCh-ThyFH=u<9U~-OI$Zn0}f)1w-k06dAw`(E{%&1!;p=|{uaM5 zS6GI~jv1^v?oV_CNkTR}A%Rmi4pU= z1Q-hCb3PGf-h|N2IP-508IfsGI7|ZRei}v4k6QW>tYySZ$VcKAz(_DhgTlen5}-qP zG{UU<)fYR!atlJ11I8rrwwlVgy2HzskJvu_2W=(eJ1}Kr*Ce4o&6eaD)(AO2G$_`Z zN!|=^g?bdu?$sf21hNFOrgq4F!g~+kF@g7OF)xNOIIEoyz0Fzhn?ASr=@r-0%gIwU zkAMV-a~;IRhYh*8+a0j6Ge(Le;}(kh4P*PEq{#GA|2>{9?g223EXk> zXc!nRCsMg+J{e<;? zzNQ-3*kA$(xd$LgBw?VSoUe=p{Jy@tk9O;ff=*~%;5E6vzoukWv~p}4+KN| znvBM>A3yo&zkQ(b@^+>a_Y~7+J7_LSZ%-jm5d-2FJUl97r)SI9V=BM_jwO1!DIp~# ziV7_N^B~`_{nB5Ch4t*dUU(`oq-g=&_;jIyO)mWyf6?Z5CWq`|7&R7mSpj0c*!>_9 z#J}w%%TP8syHcY0c_k|9@he;^Ufv8qjKnx|DbS;7=8~*JX~sU=PdWwL=gnoEU+smC{>867u>KdlJw2vvqy zhdMtsf_JuGieiGbn~Z^WSohm8cojS{ZZRL`A2+PefIl*)$@$~7f$UG4JpgQeKcR5g zc0L3F11A5IwO@UMGyLIgw-{UEg$U>F#@aq<7>rd2YTWm|#=4(hA?$Z$@VY?ULf-su zF?1f4DLaNNyx9YoaL%+ZHwNr$R<}p)y-CY)AHF~Ky{J9eOov5TFjP@0`0fL(f}v9i zJwcIN=v};fxR#_VE7k+8jG=H|uGp6p-iV>+l~XRgya z2!$XjkZ3BN9L9}62f_7tK=D&UNErHDJZ#6DX*_+wyd$wBP?kXSul861eQkp#75mFx_ zc%00djpD9+Y(+`ae}Q13l(+&bJd#&bLWI^8_4H+^w(A2vsM`@5L3~gevYb zelm9)EfG~eFEwhU?X$m_b8nkxaC0gk|Gwm(Vi<;t!V?KnK(1CTiZ<49$IFR?W{r2G z_AxhA3OkAUZAYX`#~`HkJV_?3ag>yo{R97C{E;~yOQ{gI(r0%<>7=P5+**M>P1X~c zgT7en7{r)I;`D+~h%#C$BaGDJAzrI_%eK`kIK7&A$aIGrHyP_?64iHh>XV-2RKO>g z(+Q)moY-P5KI4C8W$!j8hA@`m(HQ!!7<4-p2W-b$SV0(%l{6If&C5;;!L`fWVY#!i z|Ia6~8%<1TurS!@bC8jNV^CmFK#=@#g z9e(^@Byj}~-t-dOP`p5=FR&ylJ1BE;z$0`p9!}UbE4x6JfZfUT(k<5gPYQ9~>yCJD zl43TKsZYNT92Yb@lBfV|Tg1KlQvhYbyUAGS0#I^eMlejXK(Kz2q7QSiK|JrKba}M3 zj-%{o3Tr5xY}>3W3eCZU1etjEKHbE#r#I}Kewmk?NQq`mkcI=Eg_7%^Tl$tH#j}>p zIo*^|kK}1Pl=JpIZL$$DM@%z=`0Nc6l=ITV8!qQPju#~kdz8r0cs~!q1n{k_gT@<+RY`u#f&qslA=BM^EgS*N=~R&3B|2 za7?9yZz#s?l=x)5nPDzdFWx;;(q!_^Lgp6`5EqMr_AT@T*S|=F&*=}2V|_#hrtdUG z6+^&PY|LQiQ-E9tJ4x(Zs9uKPpm$%qXweZglDBVURg@1l)A1q!vzM$)8d+5~VOM`_ zS$I_lf-qTM58U+t%z0JQaVeF&j<|A;Bo8w)Jn+A_0$psFBtkw5L%u#^7NsDDDJ4Y} z1DG-7LlWc++vj>sOC!WLNAP?q1Q!d8xL_Bvbg&B!W|N3}cwM`bLz z;_~KiG%-eRG_mGy*#uA7qp^IhpMDW_c>+EYHmQ76uHJZPab-I_ZG_p-etv%Dq-Uo? zbZgulbM!gYT;`HA;Ch>Rb`5fFIQh8XbKM1J1W+9v9dj!y-4C?7K!eL%#aZ^jrz~#)pvomOXe0(@8BVKN9W-p<+ZLCv@ z#hgaA6^$Aug^xM>eMEeoU|>?44qWe(QfOyEC>ROO%~D?Gx$f1Hl9F1K{95kFy0g%0 zv~U^8hPI=QwtiT2!~= z%%zU)7dH%HP~g=v>zqSar#EWp;Iyv7CICMD{Pwlwrs>vidF!-Js`h#g@I6V~OT|c9 z`2~!phy?GfN~|1^GBI&reICk)AG#!mOvEG6qMhYJA{DSp_+N~tSP-~UK_dzON+GS> zUsA;QLvR+WbHT3=y)~#7D4!cg0u6E#&-BQL6IGK>^UkNqZ6(#Btv;+4I5P?P4j5;G z(q2&E{5kBK-~&>RBqC8gS^dM-zMzN~2KF*Y1rskK*8rtiku@LRgZLy3CT43DGyQ7q8EQmBCA>_;j{6d8JB3l8@mv0l}OB*+%6(|tsl7}WDAL$qdhh={mqcPYIyS3 zXME~v=v+wITK>P8H<9diJCFjo;f->IonVK?kmeTSURcCPeUTV*>*38>1_V~^^dmBM zb4+`(`&y}X#N3YpI(aOuJ=}QY4g|}7>jacGl=0bDu4~FO>+p&Wm z!`9b-NN8zj<6Ye#U~=t5_piXqWn8g!Aq4bK)z^6Fz62zzJ@eE}TdiD?Dw2;h4=D2PdbXk`i+HTt4ZSYcs$bbK13w?9R1$ z01EgB8!f}jwR%y2wSvRv>-{MMfZcQ%jm5VnYL*6c>w}k44t?PHC3=f`3wpl@jmJcT ziTR;LLs3KFD5tRGHJP*PjJb@49R?!zg3$+|X?Y%D#jqB_9=~q`XpDw2zd(>fO?}-- zFU4y_6Ai1Y2TNg7UOu@xi6k3FWiLr@VHPou! zM^epQQ@nR|b=Rc~V8czdYyzM}S%jW_&8E?tr>8jwM0D_TF`L|W)K0g9i+G`pq##Z! z?WrGbS`AbYuH{9rSO8Dhwq`eG()ms|bWhH`)BkthaFU1wiTpK<%?(*F@gU&CWO*EO zrmb?YJN?lx@}eYWLy`YY_K5;qS!r+Q`%-hyVDaJs*lYaj_hEagwYrn9mZ;NBrwsCm zTOz_ZOt>ld&5qid^wLRAv1r4GSVNOr7&j03{@Coby?-NPSaLP%MxMz=n&>;Go5YW= z-R_mUJgXI$3kV25n4sWU*==?`29ey@m5F9ap)Ongf?`0#J8}~`t?6@8~%2A zYQ^|;q>TH%4XkXrc_C~3#FxE|_!b0{LOTaoE$R5jQ&+r%02#SLF!5eJCe6-ChYi_* zCstXuLi`L)^brrNAie`0OHq1A;yFd~3L7zZ9+)5alhjo8F!rhwRSlpt3koy?lg%3X z)(e*4VHt(yp$2!Ms;UyjPB>4FqC?n-BFVrjQrl97YeXwGtegUq<>R4coe3!0yVMe6NAG$E7FM&v?h|Cn&a>mi4kgd$B3I~#mVL9jf_ zWb&?fNpv=TM*NX$cwMf7I}%q!t;VD_1ckoau=Z$ zU%4P@4}#3Se^P6AT^Ai)%dzq5iYGmhC&S^-NG-N`A!=r|7Ao3s-alUoEk}FsKM;Q; z1qaS;_=J{vUX!TG=Y{}l+2>xWREQx_f7pob@~ExtDp1BTaw6+lXXtk{ME&VBJ4kIg*-+3RKof9{Fb6b<1e zT>H3NQp%1|NAHC;pj@8{Vk&H_3?GE|N9MQ~HEm#*0wwW6c^e9AXEG?=7YYI|3~j|n z`nwrry4v=)rLCln4zISftzALhX1=()O_)_*U)%s5izoO6B{|nkGD36K8P`dAWaDaL zf!I0r2U&LgufV#}UBE%%*uewQ&d5(X+{Nai!_1%)tBd)jc`)Lgrek^$L31AVa8fqB z%Rz=`T7iih+Gwh2N!k&Cl`@A(FGo+!iXAv{Y7N&|@oOy=0;A}&GHA=GLW}meRU&4F z_@0SfyAk^xd{hQ2SMVCvGHhUWoU|CkT`_(gd>$_{!)O}6eL z4q}NnH#e13R0dUBPtK-9?H{>05D^i{N)kBCp0fo)IR+ON?*IB?FOV_?XuYN~1payu zXJKWXUsxFE^7Qav&cFd!<=B{q%M3yv@9vC>Ep2VZot#*cq6duY6#*#)YG*-zLPJAA znaGp^0-Yht$?1gp|5jEi0&=dW zO1(j-bNj{2=dB*~#N?!swsvG)R$pr&!suYR+=j@DX!sHn**$Yc-p9bb}Yv5B<@ zqi)>KaiS4T$L66EV{_w7H`{Te6YjB7n#R)L1(rpP)#ODWZ9gL~=5I=FasnYnQ#5xj)5Z3#tfFj&c(01PVzli_ z`!XrQNWDS5XSVLWo$$wJXwi%~Qd@e;U6#~To!u_{rUN%6V8v~oGQf(R22T<)Lq6SN z^jE{gquy03vNsL$o{ibjgRQW_y&oe61q zy$3F_Kb0bc^<}hBbKte3hu{y<2O z7f>#!ft8bKX=&*hK4R&m3Q|%1He{-V;g9&{{rUv-AED0q6h|Wo%KDrefdEdA@BVVM z97?2kib5HAQBhE6bM1dw9}*4G(QqSP4^K~5xY05T6)-L}R8rDDxR0cp1;QkXdD)!1 zfPYua*5XKh{`^?=z)_yqkE2WNG-QdV-F9K(cn;(QOyS8Q%J&4B+xoJ2nRHOKL9O>&3FV5W_0%l1_fav&WUz`#-A@R|T~M|WQhN`91*zmhvBs*y^?DGo|aO-*lo zGv>S>vSWD9n+z~v@)^yi%JuIwPSpJtEtw30gDGxA8uj@Gl%`r} z!9xT$FIeme#sa`^DgW^s{tsrOlE5y$8O^5=x2gt+L37+`Hs0c9``9MtE&%J^f5&rX z1&c78c-NY9?HaCK)tqbxuq7Xw%qj5rZ5{2#a=7d8e_3nxyX?VN$@E0f--jUFN+b z?#b0)AU3AQPDAmlfw}btCR@I&T{n6s(Zml2TkAE1T{L|4RBITeOb2PoNjh_)yM(nzmR+<5q>XZn9q&+Qf(^X?N5zU(>PU#Oc|z z$2IKgnQTq(Pa)_he+iDp52v(4g?GRB!f9#i0ihylowiH&=Q+&gdyf@H>SB3~^^JV+ zUFKQ#B?GwzIv$Bq9CihM^HZ>Y^j}lX-Cww@j^YexLRajQiFkpRk92?4p0x66PrNFSq zOXNfV^wnD7)|IvVQ(q}>M&oUlhkyH2#jZfgfL-4G!%CD{IIoCov5@!;%Or{md&Pihfwb z-y8pRi~^3fNUzXKVAoc-6og@_j?}1@RN*NzRznW(@;3G01zzyqRn~ZXq74h@ijHAh zCpbF)odG}#)?+r780ZP+h2Bdjnu^ZZr%Vc7Ix!B&q2uEUEl$+bl?n)Qgs{uB=$9dF zhK;5Tm5r=1C39q(9>V{7sc#4nj9KZT(=8=A4qnoyhj_w(@JF>-j9nYH(lrl^O{sJ>uOc5%#y;I7Nc9Z3=|z`$RuYrj;8<1Nx8%@!^AA$?z{QIYDhuS zYm7k7d~%+<{IQ8w;@B%THz93W(<~a^!I&<^?Cb*&@lf~Yt7?NVba0!v^d%?RI|&T8 z#Mg_HIP}=WqVzbKOhnl}-r-0lt`S_f38s(D%ezfwyvO>**3qV<2&c_Q%6mP*x1 z%_u4IBmA4#Zwqby8(=ixigGkcd8_X~<-)CNM!&Pc14PuQb(BFSW5@3xOJ({%w2N5q z>&I}0l>hw@G_hlNNT6va(crn&y8&O(*hnQ8NNH>+U89}hp;JBO3*0&=-DV)z1W&o_ z0`?ZyAubd9QkiuD#Wb88{7rv+j9NW_;ZCeOZ8G*F68bqf!7&|XAg%KzNz2UVXn^R+|EwTSvG1XROV8edVE^bmZ!% z09NW*M(8@{A6%ErU*q%1C7DtPN{xRW#@wH%6aR2^0?X!y-9I~k5CJjMizFTH6~e0SOmrV&N7ZIE@fKhF+a>8-X?KDHOAzHV z1Vd81pjx8Ny5;8BongafFX*=J6hha(G{Y}E21Ym`Nwg7(3io1ttnAi`&SRqpEZ1B| z&>`8k^6hRQomveqxypYqq^9q{8P+~T7FQs(40p^;R)-IN^4k)T!G=wK@TRF;KJl!pRjw-}jKAzpwNJZ5NpB!|p`VeUkC7%XAWF zj5jN@^QjYl-k>eBfObdGi#(}#Dz~(`0e|G{K~o;tX~T$zH_M_-Z&y@m$4t+55z0Eb z5Ltsn>l4h_!rMg-7eM>rDT0A)BJ4Xgf?(4_t+OeTS7ppMN&7VXU_-X34I8|-#89p2 z4eoLwGNu1?99qIe2~{Af@*osB$tD)x$zypMx}TPD?Dj8aNQ8LiBDim1BsM`0KERlD zT$>_H9P#D){VxWzLmz3yH<}-lz&P$5G`r^!>#tkovwqJ%|7%gKPVs?9UowWoRJ&6g zh%erPIaip_l^CLO14RGI9Ko4Q0n+EYerXd#8YTPul1>*?aD{b~8vr>3_foknAg5uq z{-6!M1-~cIRylRe`xb>GD#Q2y*raNsAV8Wm1pduE zp|};7KykO??oh0_6e7FkHL;`+IvxqnJ9`|Lb?_h zTRTf51$aE~NhSwxrQPrM?$$qWJJT@@2NST zCshL6|Bd*}Uvb~O*(_dugevj2%6v*qW>4d zXU|LqzaUi@Pg6&zqLDdIl0ZNbeJCW0B*bC(n6Vd6bSI|2^Szu&jO&9mT%Ia!VR|FGsv6=Yxj<8b+(GU`1H;F8zn0KJBZ zRrZnO_Wy_S`8bosENJmhl_B6{3X3T`_EY=^iGYU+_V}kFsK-Lk%z&85EULBJ{~zX) z^ZjNpJCd2KlL;28^LZ)yRW^BWaxr*Xq|b3Z9=`&Px8`-xBwB6TmV#qs)sh?5!!WIT z|2s}q*Y7Zc8a7yA)X{DH$)b5k?SB=2utk@&A^#m+M<@|I5AuAF;Z zg_|LCzyb}ZGM@jV%D`O%#3(?i@#+yOQgIw@+>93Pj1wI55}zr~z12%5#E6yz!jxjH z6S?J+v5LX@n+_`9Fi^#%4oYU0(TuO@VBHd#q-dV?&L(aRD|Z^ox3mn8atRaA-Tm{y z6;bQY?#~f5$-0?3=BfdZg5)o?lqw|cSvB0c(ZHlHFctXXQYGWn+g9Z2qdlBIOH^>BN)E2v!&Yc-(1)N!JE5MR>c5p3D{Z_`7}HgYho74uSf6bY zpd{0M#pH3}NufBVk+*ZE;N`shDgPl#XXoknOnbm(GFG1PR?oe@``NWGK>CyRy`XRB z(2X=jioVE#8(>xH8H=jnj*5WJz2DQe=;{d{OV`JlP zJJxlIWE46rrJdBGCN}ru7#Af% zZmc#pmwIP@AcpLEfvYg2>@7Zi(is5y%pX)X?Hz~_aNWaRS%d@3$Yb7KN8O(U{|D;R zfj}puEtDP}YupX52+o*0}}e?a_#hxKN!=PMe99mz#a9VnLkn?*oh z?8vA7k^h)9;JP@JKZf{_mtu!POQZ@-TP+ z;M&mD*}nnADHL^f3w8U4bJY`xP-uy;`_TvZQY8rq37Wzx@Tu({=L5wv#`CdJ=5k0< zrs$vM+fm?x-bjA+wl(^RR6L1YrDQ23a@c4*t6BQ!8|=>;M*UO7CX%EmdJv|-pV$RM#v^>#PE0aIHP!=gPc0;I$m6h&ZwyE{GzgUF;>Zc$ySjULZ{l_iZ^Y3{i`-`(-0P=M`W*x$j z0IbkOE}=SpxUAHCEkBSijP5Ydv>~m?QYFLNdu2}R3P%=h|3Q`7xGwI%DO1+%N}K|` za)_)-LHPFLG+DU5`n*hIckKM`MLE5`&mZKD-54om!Y!(L>O)gdEhr$-H(5SjL093V(0c*RzhqD%(;|Eg!J+D`So< zoQJ3APefEyf#|tm{1*`oZ0HDPvYij|smlF{Y@d?1Ob_6m~X>6)>lnw!utxqpbJ7a07qP{{! zN*SR{8b!tzTf?b5*0>r#*Xhn<-ZkSt^~4fq;Z=;Vz^8MInDdUs!y4yP{S%UlmSEbj zdni0dVK`fuZ8R28OzcWx_Cccx{kK`EoT)>Xy`ppKePor1op*NBQoZjir70eSOsD?K z5;F*Wg$-@5utlGEhnI@b2|_X+@)nkMNyZYy zmUPbickg9KJfbVQ1wprFYJ&sentE?ZdVPK%?ocNY{3Lt7ZR%*-FSg#XLA$Jbj+L2u z+q)JBdL2dU*a}HWRZw0cz#y^ufs2Fl6Btt00HU-aB@_T#1#q+cCkbeMPf`mD!FUZv zYh6^p_j0V|Pbdaijn}met6o!dQ=_SWEDtc=0&ov7HzzAmfJ543H2Lj^=2%Y)79Eq} z1Ukj298S|WcqB0-+&e0De*kq{T>KAs?&N`qi8x>Y$K~sAFkMP4<|iT@M;QaqtG0nB zJzO8A3B$+i?oQ-PT=|f4#!?6q(n?2n*L>j9tztotV{jxE4H zEKZC|&H?s&I+uB3=h`ya5LQ=-fe-D2f+RgxNvofT0K%zlK^KGMODo@lHy612^>Sp5 zd*p;wgv$9Zpr1lw0~{neFGf)St;Ao3H?P{+*?A7&maRmP4be;|yhk1n`CTCf;`ea2 z?UHU&A+&DLTY!BZFO;SE68qDU*DEt15f^)B!31tY1@a{Pv6FP)-{vTQ*p&uF?AH)= z0*4q4b%Im^4ux{4SbSgCCAkEh-lJx`Y|q-y#EzGkAZ)oO!8(HYkepS&aIlS?P@R}s z7&kTW;w)e4gDbdvYAK5GfN=0r;#I^aZ&(~Cql8T+ERI~2n?8ky3EqnXbshee(d$FX zs|=Mdc=V8?{i2yxKuw)i*k@QCce9LA$aOEfq{NEuoc1_^>YiZGIOLlqKz@+m?tf}S z{CYEePZKK*9)tjo3Qvx;1<1;1f2VxAB)8fb3BW*@-C%Ezmj+?%7aR6jHayMMccWT_ zZ^+?syi45gX41f&T6A{Ua?eGrF1rs-WZ-i3-OTxdL#d6I1&!S(0fYFi=NmH1H^n#9 z2ddt#usA9=EC;QBj@qdF?gF_*X_{1zYhkypLM zmHQPVOY*wQA6?3cD=|1PG@H<@wP&~dBL~W3BQs!y@V|DFMo0sdLPFa?91L9PyII}s zbdYdi?Fo$Dwdka$M|+V+3Q(hi8BpD23k0l6hfoS+F^a2KL^X2Hx(FpN01cgm?5Y5` z`l%}s@K2R~JCJ9|)69!yqm>#OOM<4c>~kGZz~;hOmkhuM5@2J`oeT;=P=z3bxY#xJ&@(&^6wc<`$>3@u3T!-WN0&b}oI1pQ@|hUc>DU1ejz)&D zFjoxw8nd?z*DXW{5`rAgqBfW$o3H%uSBm?{7ZQ88t}`Lb>NDcHD3IJOsKYYBKt_fT zDBhTA;~&sqQRt`-5c(c}oOZHM`<@Y15j#(ps3A7c;z5mshU`I3jHt3Qh5}ZhN7Vcy zZ{$KSUYzt#k$Y3^|~G33oL+6@P?EB^WW10U4k~i5A+ysk`yOv>{Py2IEX1gpRMcRfMo>g3`T!TO^p@-{`L>; zhuYu>Y*7(1E$ky}+Qc);(tgqP6IzJs_B#^$6T%#3vgYXka+hk*VG4-pw{SE>9JMX* zDI>shYFxys>^PS|82C7ZFCm&_z~^%~kdU`hGMgH}dSn(7Skg3z#aO9YogBalrk0}s zZmStWI+_ZB$U|MFddur@>SfnO2>g4F9l%129bsz?=vv*Lh5#ov;HaEil>-xVE!S9(=QWs0=CKJ~^MCafzZIl~yHG%q zq}+%E?VqjxaFM3?#=6W2rt=w@@z+dLva~@EBA$#LgtlK$u}4Nm?p5$)o%coHDZ+u2 zC=0ErUFq10`WmbKEGY#fbZ&+3e*aQ>0<=`PybbdDR=f8H%~)Y_nFl$ za=r=qPwNJ78WXt0UicD+hM=3&?~gZd`3xcvRr_Vx@iS-PB|RNA@+~2n8`_S7( zc6B0II=|QWe1sDm)UQE2ILw*RzsU1ppo&y(9UER@slGiQc~!kXe3w#rs785<`G*b_ z1%>XPqT8uA6eFU~Umk3zun~lahHLpN9VmmL>3VX@>xZr9EaP-adydLv%?>MzvLdYm zTIJfjYzA!&@hze;eb?5RB43dDm--ccoHuu6{y zyfTrnAn6!d;PylT=(;motfz|ll~OrCu`R()eJD|fc(P;kU4tnAPALXJX4+-G^LF0^ zMrUL|5xNGHIC}%Y+4TGQAeFz}(}WT4>Igx5kLi%u=WSG_+h$fl#?WPxL{9MmCNaZ> z?*dhNcjFY24wDKw)Ydt87Egu5MTX`A+gFsB_^)XpDBi4GxZoqyHZUoV{}{rJprk#2Fg#sfj#N7J4JzrJ9+V|Q;V@#QXWyGM}0QkYj`VWb21FmbV0b&FYn z!(z(g%`w@Z+NbweWfc4lnRZ5#;UmMt3knJfmXi}pO59bbR)toRx3+UtjSMHsa~r6A zKmSsR`rIKmK^RoBw;0Nza}TYswVJBb6e#I8Q}ybkKz_t(=3YqO&!*NAV#l&Snwgn3 zQ3^V5u{>l~<%v58kCEbx;^Vm{=R`E`seY}RG=2qmozZtda@*Yk9B@%(Pj}1qZ!UC+ zm+~P|G(t{uJ;y_2$M#csbi)2dd>5XU)V@a8>&tD|0{fV_W*!UrdDo_^c|v)QEUyyl z#Td;(>eAJ-WsYz1{V+pLO;;C=mRSU|fe_w=Umq~C(u!a%lOlML>simK(ou<|V!*#~ z8*CFbI`;yKA8Yf8?PVPGCd8Zc6S}mK@&0&uk4RcAeR-~1!|}$o{ET-&+}M}P`=Qz2 zlOC`XSUl3VT;0gvx~q4z)k_c5^;-?!nR<0mOY8_5k>J883lW$=gT z*ZZ1Oo;dYzLLWpgSjXp=q}rmpyek1gs&t{f7Lo6+hSDrC{6-0r=wg{*hD`6d7^H7U zGL0r}5jL38DrI=-t2x~J_dA5K+k zDs&ZpsZK4My)BbGoaVZ7qfC@|vG`;z##bidRsh3Iw{id2;hfRHb=0^VRjVlaod|6_ zSsq)AP7(HNjSQWrkTXTjW_t$B1!xfjg&G@1ZbM9z^gky=Tn@9G9uK8 zvD@j7);{$a;{qt>2)h{)2lh*IyiaUh)e z$u$pUV<(!LQtx#VJI>xVY;Zs&Q$?-KnJoq^+{Hktw*yq!hcY63e_o`?_MBti4MmnD z$W_UwXd3xHH!@z&KOlf~wpsEcS=G#K`L(27J?(&9Z3pY+y4v5j|Brk$*zE4(a3zOD z?%HwvP$Yx$K?v|4?TIm!{=ikm#5+|de#aD8Wr?!KI)^g23@7&^6OJTIpS)>wpp>lj zLwP#Bw2%CaG1%_zd0hXqidfjF(%H{FP0t+CT3n2VbzMkHh-+2(!6HOaH{2TD2$>X&0hxIwBNq zd^{VJ1v_LIoQ1(0cVzxSl$tXwaItn>QEVH)%3{dl4~Sie5PpWEXc&Jm)m-ur+mFc??R+{wvoI5VEDJE5R0tvPlsyf;Y zi0m42jIA^hth!4yX|^6XJ;k86N<9Ce#&7AWYW~A-@ze`^bVTTe6$?U{kyzoS+ReOt zr5Vs}Pg4kg#gbIT>R@qi=s&e_c;*G#>rB@^AGCqsio7p$(zh8e zGPXR~`9{tSt)QFj5C*+EqrU|zSj78p%71eIqS(!5G>+Nt-?=9Ig6+cEV-ie$)XWkv zmSu8OH{N@Nmi8Qc+|j7?TCppair_8ry9g%C0sm8=A?6g;u9d|>I(QlU|yxp01DL)_ffpw7)e z)D4q3>Pn2#MJ>I%HTeXS-p8j(S9`lF_h%EfF*Nkka#eLY!E$8t$M4xy0fPXI0A`@ zw|P{L0Ocm9^OmdyH14+5$Tz%ZDfn+ropN$CrJeLWFJ`L3ro3@h#14;@OPvk}PKAKy41 zqw4q_mOU%hl2=f!3~|+{7u!huGiuCtzlmO{*^Vr&ctq|Kh2PXF=ZX`dLWG%)Eu()d zPf?C_V!QIc8CkhPi3R?K`evNtiiYA_1)R)8pwQsZ6!#W>UY=9@6#&W3&W3lvVEF2+ z?C0kP1cTfd-(`sEOx^RKwSKE<#z7n!9rgB)ST*nJ1RBpsXY&4EgNrfH<~jGh@r-jI zD;{TFmN`c)fHkrIy1($0POVFEi(bo-?>

    9UhR0FN5q-Nrtv<`AU6n=n4BnWainwEcYx@=rJZH$(y~Bd|!6AYB zpracZ=8k=*u!{&8Hns7O2o>5@UB|AKxzI!lbpPG8PZ9MT1Oeg{rz9!_isV7SyP}oo!kopP0smvCWrwsM(a;2X?w1A%!XCRYi=?MWOr}m;8(? zb76%^Linxi^mlW|7<_{>y^SYOU6mQ_wz*^q;Ak$ z+5J}G{WfCp$kuASQQ9~CU1SHs*~8>+Mr+&hw#Pkd!n-@Q15V7=xqF)WstdtFy>pU& zqpe4W?r%hIKe~oZ2lPh~A`02Y*)X^K^x(Y(MjPTD!5d3HYdFwT&!b+J;4M4gpGy>kJ+sP#&{GU_SDYE1X1*NTF-FbR1rO)W;4lUNQc>z1i46CBKmcDcm>V z0nxd(mX4J)uz82?RWB?9ki&<^(zsXlm5lqsapsVp4L6a)WhJOS6-t()W5a#|e~0(D zaszsVdV+8?31?Fzq%;v9Z#VT%$tP4GPOG5wK{#Ud)6 z#UA!({S0N+le#{~r=(CZv#{9u9?f&g^(aLG4Zd0Lo1^m`(mmj?K_C-Hc^v77T*)|z zLR1AomXx2=B?E{zl*4TyI4$2~<>hS%C@Ky;7k_&Jet`PDbKv_`x$%+L21{IA+~OtN zc`AWUp=WnIOPB*2?de1Hwzm%{b`uXgBi=l+$4iB4Ss_{h0#wY>7J@VDHiQC3=; z)$`Q-;5WLi%npaB+ab2~STer6k|L4*2Z7-@!ElSYNk{DF85rj*y7T7ghW(pxh9rvX zEmN490w)cb$*{t28MY?WiYdaMS`QkYp!F%&DAjCzk$w_~Zvb zA9cZ$`nO~ZEZtx30!tEZV)AxJowRCnyAS}KeRF6#9VnHQ2_Mh6l)4j%>uq=Jm&t~# z$e*}HKSC**ju|lr2=v^b+OviPNG~GWx4bL-Un7p2oNJ6W_N8 zr{!8~v>9%zSy+!?7Zx^)U|BUzWhOVmcnQ_{1@xsVm$Y2TsK47H>GA648FpnGv1FmV zStvqF$Nf)MLE}PG+Y6TZXjcSTmr5#YOwr%EG@vdQ7Jji6lCfW~sA=9mRM!m?yR$O+ zJo5h1S;2EfmVE~5o43WMTSOyk_`nd?J3SStN+8x3kFu zyX4I@mrhHaA6k{5!H1b%JQI~x^bna^cz41rfAP+b4o|*0vUU{g@s|y3t;1OQS4y)^ z9tn1@_8}K4$2N|enY+ewk{wq0Ab3>0ES>=;=gdnjaa1!Q61E775I{n_W}Ru<(aVUmgzmx!v25IlKU-@H z2@T!wwZY1rot+ieN{?Mdv*HMNwS}D8+dZuNGFQW&10Hw)qhbjUcm>c9ZPjEAm*F^{ zuN^OHH?l!g2x}p2QN)x32GW{8HHf{bzCzFO_XM(cVnO{^bL)N;C?^c5frOGdk{mbj zJ-BIWEv7>;Biw&UJP1|*Isa&?#}UIx03kWmtnt|uwQF`H7qyUKezX)qNgxZgbI=ZE z?>Wc+NDFpeh8|W)DNoWhhL%m8k7P9M{wHh-9wK-j2nIA<7OSzrs+}>#?w41+xbUe!Jx5%t+7;G~hGFN<~Z# z%BI}GbY_U!_||z1=~n$vhyG@_3`a- zZ@@>H`<)N}z28QO;`t_J3C%1C-G618YGsm+0GXznMcBB$6s_>gKJIUn2t0m&aHNcR zucJ!fOIbnATR2~}IX+Lv&Ys6+fK^dZU^NsE&vFU#fhowda(IG7a);p!&F=Z9EwOKq z|L&hO<;xeLcw;eyU%vl1bxhc4vHd&D#XTUY{mnZ4smXrV%hLAz)CcvF{{7H-^I_#@Fj6bLka<$H#;hE)SuP;Km&R-i4hact`AyLVPI-wQa_d~lpkiXynvD+WVV@#A?0-mqL+-{1B1&&o$ts7XOD!v!*6{0_WempKV< z_>Li;(5*gxok%$MAa|XwWhZ|z!-Yp717BzoR|c=%cqNLEVy^G5 zX(SmC|2MIp+p4u4dnWwh+K zF`9x~Z?H4JAa)|YZa}_o{0V0iiJK2n1#czO(AQ&{uLuaG5sL}bqP#?SJ68V<_H&SI zolu27hEgzDYGnJR6u1oC#upy8FpPH7I?*g|4xnexGk(y-|4V`cAE#p%{)@egVP-P> zm93V5uq)5_f#NvoCf2TGmR|`QNA0s_KFn2E)@`)}oVw~$XgL!yoe*0YFI+nPam=2*q)61ApRyd%cRv1X~K;59DfRErF1wwYjn$PQ(EW5P}bR1;ob7e~*2 zdJ{sL4yWGaBmN>a(LzD$wWXY|_H~8S_j51W;TD!LF(>>REI8xM`B;UNz)PF%(kTo9 z)=S(31|DiZ6Cnh4A9SaJI6;qwhG?W+tMd^mjSzCa42Nce>IXyWA61{Zl5VgEJnvrqQb!lCLk_of!&mWpxPIM_=m#D(tQmVv8{kXFA8>?gex0ve`8)S9 z;OnmCYyDhYoEOyxrfbjFJde23nk8d-tv~*is2y{=By!36sdH@*b3!s`F%qGI*9p7o zMalrIj(FPmW?xBB*ossxQ65}YxQoEw2DGS|-KKFd{(Al)9QJtLgt(h+>oDe@dyS+w ztIM#fzHWX&BeYK38dapz>cN6~XQP8$~Ddp?pde z>s?F-=2EHJ(k`RYD}#(qDDkz?QdLE8$f2md=lAeS_U+o;MLz6;rU^mr;~ag19XAV> zm&O|!F*S3BkfY`R;zr-5jcI?(vi10z^J+TMOGxx0*WuN)f4hzjwe<6x;#a2Eznr7~ zEq5!kM&~`-?Vm#i(=JLFMt(S3p2i zx%V)U#*Drzp!nCPd0RQgnjBKsX#?^T(3-w>W<>W8T+4mDBe*%;)4!3ivP#lfnU_4L zXx$L z!h6f!$58T$@#FmtgL!VG{hpws56frrbe&eb2YQQYdPZ@h?l+9|0lYCWEr-|WflOK) zEd(+1Iv&Oa?FG$v>)y|vlJ9jXud?#h#%!eDo06r6RMV1|S%D2bQmsw=C zkw<2Zsm?Q zVQaJ&|B&sSypNB*njhqFij{`g5TJ&uIoqbM?^8ubU)bO`;>uJ~wh-x{m}jU;A*Qd_ z^~`1(LgpHzj-F35e@5-$?+Gy!Boa5}layG~Cbd_CA>X&2bqCEnJCJ*QFIPC?*Y=mu zhO~F*UBl2MDheHu1m494WV_(faI>f>9BJvTMO$4M9%|E6=;v%Uo+75^EKeJk`8Z-O zHMzbwI2uzj5C^w61gw=iS}k?;S=Sp6r6GtP%VW0(Wz+WPAZkb2eyV8Esa%`&z0a%} zN#fSCJ=Hs*d#(5y9YQt~-WAHhZr(!d5O`mz;)(>_fRBP?e&n2NoF9jo$iir$!Ey0)eoN2 z%;+9!SC92*Dq95@S^-E5gCFADJ@klJ{i-k8#!wVU5dDYkGaVvM8TF(Wp#-pfp%by6 z9Thy`Zqd`cCh~Pe&E{*Fj#YI0z`qD2AC5ldVC^^B$iC4*mz!Bp;TtDJ zDF`+$ZV;faqNS#WaaCzU!lHyo0_`RAS|EhiRr?{$;q&|E){EQQ)5VLCo*tkQDjT~6 zGMB=mq9hd+(Y;{*{Av;koSd2xpZ*CT%+j9g7{dVx9wW>%5V{f50(48};niRs1bKN0 z0B@)wW?^fqAT5fLPXWx8H!6hx2O1XEDT);A-mDRRfSG0qNT;o)xvJx}GYEP#`cdC~Zl8 z9zO{vi!0;65K4T8|8pyM4U@kdXe`tH%JsLbJE;Ds^aVyVuL6{vuvdWxgiR$dN0-HL6^y&r&|`4SzpU|+S&}C=?HNcWW7xf(OJ8y0gL#?<6plYGVeVUB#Bw@p zy<4wwjR_(weANjOk7avOWJ!Do5&!Dm3G*wHS}!8y0kw_5=E#XT$68x-$vV1>98JGE z(H{F9K9NPBENUhN(JSFzwlkg~w0whAp^IE%+W6-=M>y%ItjsDoK0Z%;NiBK`9}H=| zu4;x5!pJ5pgEbt_fxW)Mw3P((E$3g57q95oBy6n$gl2O>JSgGhVEU(8jewGPj2R{{ zKE)-|_{)p*whOK85Azyw`F;aLY~Bx2F)HDt3Tbz&j6*nThLA-K0byZbj;?pNk7hLe zg9reAte#1gf2QJQ2%8ri0o!$idJz=VNuMz7O0%aIUhsCAHKa~`j;p-SrN>W6X^ zJ^w{czYyz%a_xAJ52v11nQB-4)}Qs$uzz!lUi#_#hhB#wX+?{9cmSjoaPo27(gt8( ziC60Xj0F+Ny-tqIC@LAD4_}WEJadAx($f5oEN9m|iw2lV?10@Bb7HjT_*q`BT7<>E z@rn(T|C*JH%SV$VRs*Vm5a1@3kE@bjwoajkQC-5^@-=BQ-JgkP`9gO$>r&+!>1;SA zw{Fm(n)!?)9~Cq3d&^S;vJ@(@CqCrSQ1r{&kVX#_*Ha?MqUd4m^i1?Bx?CZL6Ix~W zicS)>O#^NKfm94zsAgx@V`-4aIO@WoZsp?1y@0nc(&O7nZ>~aL$bMpZALhwA0f)c( zwAY{dzx*9Yh&gz?JQ1YqwG$3NYd4aYKadjj+}I zP@Z+A&73ctp!Wgs>STAbXXQyHf|QMjiXf)oHvRF6pirU2fW{jX)psE1BSxjgQwn-?uU~6CZvHPFU;nt1G+N##;hv8?)+Z z#l8fz^Bgwq7)#CUYVy})(D01xjO!@8TJZbnyO5IF23luVMR{d$b!TP@mQOxI{kxkC zcub=7FkcQEzA^pQn;Dvcf^1}Q;oUjGu=nY*>Od^}iaXq--}Xq74<6n(N>MPZuC&c7 z@S~QRy0Z1l*P-!YBv|X2+1Z`(FfjELimYB3SR4Ty9?(!;QZhX}I_h#FiHl7IHwl5X z5hnx);6guc)V4aI)&&M^;XqyNmPH#S!!ZBw9wFU;P>_GNOcrCwLHLdVZOgmT|8UqZ ze1=}3SR@UPbKI~QU97qF`7dOm*1rUv&~8Nw!y-SpH7q|BdF<3J(I9r!0ES$jhHa$r z-MYt1P;2(+$tbY=66N(TRr~_9zbML1H_+rHlCqM6CAVAmZtkW2?z2eBv)BmKjlZdh zPViXz!1t}xLY4T{wj2#$-FoS*MMBGA%4gmIsb<8D5bLz_;4=b>z(a$tsyM}ytN)Ef z>vR+L5$I%~?h2w3IPESjeGoVPP9<~CVht9Gq_9vdR3Y>=i*`ecZMWXfwfpA>{Dc>E@M42q{$oq=~ zaKU|n0A-l#tRBj=8EAh*Sw#4eJE(H@r;ZB~d9ZJ%JJ_k0x>b52wm>FMI{AI1NR<;%|BzTO9E5CHw%vNfCkH?$o;jC1hV zSs%;gSCqV>%PwNaqMf`j@1;@OA8K;w%TT(whs2f7Hf0=Ye-IX6Es$q(zW8;gk+KiE z{QCa@+yVA2e54YU^m%s4(A2k;7XKT?f~=tlef%5Bqmy_&(Ljboyz>U)!|s!RwQU`OOmY{CrnVlO1PuL zTeL9X9LowY&LfS4WtLyY%{IBvdSDDegGa*5h|IBss4i9*y)(8;ZrqA`7qva;n4^7Qg}dhANY2Peh9-j~XWhlLJjm4ESckH+D2fzN7Khp$nj_&wvtyB$)i zkwiiDA5GOV>ORQr9Vb&1SB$EEsln-WOcy_S8j4gTB{y8HhQ>CdHT0Phw+8D?g2hXffkb6v;|xL( zg}r?x!0E~n!|DS(G~(&f!mxUx*wF9azTwd-X=uR57kx(y*KSLru`Vo(o!Wbpk4fY3 z*@@oQ^79KsSCxd1g5mXmY2+LX`TCyt8W}362Q|(pT@&HS^x`;}y_+S|u47~@GlN-$ z!zme}z$PesLxp7hhe>B1j;?jg^)q@JoRsqWz3a7F)1^0k{S0o=0!;;J$bDXXM1uSS zplMf;11e?4a<`oJdLq@f!|AZfPa1!SMG%iccuq;nFh-q`N2KlTr|0;h(pyD)k`C`h z@qR1Yw2p2S8bUa4z7@z*Dv4LJBc=zb$5{(_9Ka}N3$1i|oOa$gZPJV1{{G;smxG)< zC>27Ycy%fAuEV3jSHXItIpsS;1;3DxcvQQ;@A=T(k)XyPD|P7eZidhcTEs6rt?X>7 zHDiCXptOfo6sn8oIH0T5sl|zV*EVj}tMi-a4wsoFboMmkI*VS1TD`tgyJ23WVa4Kh zu7>`4GB)qG?kk-#+q1`GXz7|`XGQvUDElWBn5*GoAu=lp)XJDO@lW@2^J0giHnD-O z$$qg6$-B_o4^-^c*?lN4r;au=DgsSj_+TOodv}5Qi25WoJ1IYw&y4cYZZ&il9qcp@ zvCLdl`*}3naLt%;Rk5w^iS>g-V>e3ZWu9($bn9%!?^kH9`7S$YHVCW8GjYdphOo#o zMJem=N_yY!FIb^>MTWL`E1JI-`l;l{SH$|x=k~`8U(OBM#ma-;>z(x9f%tVe(eTmI zUW)BsEtTyNrB~0FAs^9=F42vuYm)9Qz7jmnY;@{+>;|*XF5^7gn_}Z$d}xVB%8Z1M z4T0Nu>4sI=7<&W5j;niTZ@?j{XXCLox}DsSGnv}Z>u^|>_2Bqr0kzx;B2-8b_PhvM zpTUfOJf3&?K_Oh-xPD{`=UGg_(sW=lDGmR}5K=u6^ZD($0KAJZR(Jwc6dp<+WrO5= zQh-3CX_x^SpI(#ccO1u`^GMq&?)hRrd=5bt3VAXp24}S(f*VG1fSEQx0jg2S}XxlRq7_DhggY zPecpp#%H@k#Tw%?dta0jzB~>Q?M~SEahsHf&3t~EbC#)eucB%kX#6tGoU#)?`nlFm z&&25BF&Rn4T&2V}$9H##$Oq6A1LmcdMv{x@C^BWY3Vl#vZN50f>ETNiiTc;paWSZBJtHN?s9C>7<{Dn5I|%BjYQ7a0(B* z(uD^NN}lDr(xMEtP_LPOfrv6RHdb~}XjQo5&o$6i*HJ7G91k(t%Gk(}P0Fu61zt2_ zUm;x`o{zqaVO^Fl#!JFXDlEmTFNgN!^YsxlfP_vlpxG`60tw;r-{cBq>8Vk^+K1Co zt9`-WQ`-B!aaP9G-`J>D`Dk~? zfIjCBSCA#PUXqFGZtKmZGjt>OwB!@ND80iiNI7~_MsoRjSsS$>bVqjbH5)qum*@q} z#HF))p>mUA2*vsVIF=*Hz59!(EEM+l?iyP^ z1}^rXu)$AYPVLymZ}dfmiqLK@Md$Zf_i>+lrWYbP&8My*JmVBJ;`Et9hc%|=o39z; zStmq{YsR>Sf<`@@yC&hHa3Kb(sz>fi?slDUM?9?JAsL91?9r#M>)kw27(Zhpd*)ra zpud?xFU28uO!wdBo=>_*g5w-j+^7=9_>r#A5}hyS=T_-AG%SzXN<}TgWL6V>4X-tB zMeQ?bu3BDhE3rl_KG*YlS+Deo5{=)!c9v_p7O#$jSLj`%??6 zfkg#A$FW!y44vORD(xA0B&M|bHzRgSA7ba#mX@%NxOliL?}1DqZKd6CiW!I2V1rPL z%ze_#1d)n?Kg5NR1xO}2nFBva(&bX-^0xxvEKQ*o7R}vklH3C(WFd5{0#w0fDS7uF zJSen}+DBH13)}keT_=9GJ2~!;OqS6=;*%U;FZ#`A|sLWEu zceHJsaYnEGzM8_Hk?cQfu}Xg&Me&U!5X4uNM7h(?e2=2T(Ds`d0ai3#t-a0To9y_& zHLs7~#?ocGH567@Z8O>_Gg^<2@R8zFO|Km6EDji)G>z2}7B z6IGMJywoLVO}K}!>Em*vC|Cyvz^Ej;>m!#Qx`1xRAE4zi{#N^qqGm>-;JHJ|8-h zPByLq7y1T`H=8qhVS_Iv+c8D()RtLg7I1j=m(*}%jb(kN)GPL18W;RLK@s_ljJ`+t z6D?aLdrzmJWL~?k$PFto=Fc>v_59_N2?01E+A~whD^s$>Frj?Lc}kqQ?f8?b*f~l< zfv)pi`dHn`51tRBox0ARhg5hs;5q!f{cs|G&MCD&;cWD5fKq= z*|LQ>fmXWWDYXxkl71%k!RpnkF<_)kY%qpg{vcwHOrlof+O=yzD?ORKmd~F*|HZCd zyC(8{$Um^;KNy!=dutf#T!*9X_Ha~RABGIqaRuCgJQ|--?>P+hp2OeN2L#MzII5g~ zL6-aYY>t8IpZ>xC)Hx4-BN3^!q*h%Yj=W35IbRaA)@~SHyBuWv$kG=}QEopR6*qoC zsnf40zA_v>=8K1N1aw#W*P6;i-wuYfMdj;NsEpW$>a^SNJvV~IF+*Myo7^WuT65}0 z$~s;D*Sb?1W3AtiJ>ZNBOkM8@g*zlAR;Ic?S&hnMvpFxFd#YpNTV zO5Z;%x`R!cW3k6j&h5nYE8nsOIdS90hpt)o^o7mm;YFK0o>ZE`KH&^3B4l9v;s|v8 z4#Fx@4qjE}*rq!jJ9W-D9=~SOJ5~R_MV}0*{$wxo{0}l!+xGzT`J9I!PT$=E*<0%%Ww)GowVMXc zhm^A8$K~)71YjSLVmHp--vI^JE#!440ow-s04eM@TQo33O4+W!ZsQr`1aY=?hyE1o z(496gLtghW9wTHZ882wCqJ6vGEMnNH*s3!Ho3*Brx}bgYg)L>)4-I(?`A3$h>!X89 z&J97i+J`7R`ymQX4MFIY5m8)$MBg0aU4Hc+sI(Zu)C!{^C{y_mx#vDcgyZNCj)BT= z{R>qVZ%!_w5~&SAsrnG)$qYgCfsZ(6$dVI8jT<5iL*{$ULgxRq_Z?tWU0K_HlT0%6 zO(rvm5)%`Xn2e4YlcL39T62lMT!bir3gq9qzOnb(yR0$0#XFLbdjQ< zSU`~?3h%eqQLOjEz4(3qpO|}|XFca!xaYlV?X%B&*4k(7z4p9=di8g4<=`Jtq4W;U z+06KxP(T4npWl0tA)7O%;P&~IXsz%?+<`CJg=R?SO=EK3IMP0~OZtP8TmDrOy?@+m z40%rLdswcYaOL>+r9=A%QC|F!`|cUBJpK33RiBAm!-FwxATH=nf=do=d={( zopV3q3u3T+?H_8Kmw8m1{0X>r4k&X3Qr82q3(y<(GkOEZpf_Fyz2z<_HTnSdinF5} zl_X#HZv9keJGI)q59FvbIluuR;uj!z9D4n}M)#S|(Bb+qdLyQzC-_IyTYUldUDN#p zGUQ|SAVkm@PI~=EvCm)Np~r9r@)6n`|AN~#@1x!M?*lXBZJYOin0a{Q{Usir8G$Z$ z3ADR>giiNQ(C#{n)27D!!+{yH+4|3@F=b#u-|>|SqxVsw|CfOoGE-;T4}ogG)D;?x z?ByB#4W$PEjmu1m^*==Z(a(BARexwp)}H#4m?3|yQMNgYuqn#cpa0?DqwEt5fTHXJ zoO}qiSs!7`&wmpw%04jp@4eA>S{y@W*eP*Q_NFNkqDR?I>%VGw&XCWe>{}(V@K*e` zO?ZY}^L_3cN7?@Kmj8FcoP}xeJ14)!kjZM3;Xi9}iubIQ{ofuo^EQ8!HebfIdATe) zD=Sc}x){-#(wxxogWMc6E|W!u31kClG$g#suK5Op<_9+6&8_=^s4%oYG;3&Iy z12fIZ2E7cRm$cB>jb63w=+)SR9;Oj#b6a8gzzq4A0o__53mn(yE7xR~p;BhqzzmtB zu<{4r`5WrWmn-zv$Sz0CQaN0akwfK@n$7+duQ8;vwj8E!w@8)R=hOe~F;g}0mYAHwoTHIgYMug}fJ;!YOzxFZbrsBz+P(!a3@PTmyv8&ZzDs3rWUD5mjbgCg zE)%P)(xBvgVPJ+_bs`P+@#WBBfCs(upk{Xt^NvPfuX`?(U9({vQi4TBaRW2tN~=^z z>PN#kw1ktRK}A?#9M5S+ff-WC!0pHX>~N}|!y0skb_k|xo#kZ8!9Ywu z7}z^;i(T8cBTiz5e0#RW#zrkBc_i1aUCV1|XvnLptINB3^=jUgD_8QWs;ctJ%gggh zOH1=gN=ovIii+|I3JUTrUc8u>ot>@vBGBXR?rxAgeE9I0bai!c(%IR`Nk>NqC++R+ zc<|r>C+E+ff1YbY6{%>m%6kmc^cHBkghRu@7g|Au+~24i7OfSb9&;PJLK?Bzrxx;V zRopr0>FLkM0jM5SAJ92x1H|abz;W9IXf7QC%bYF_h%_Qi+S=N1@7_JMw6t*N^wo*t zHmXR~2NWG1iMDJvbQO3a$@w7r+anH$%;+nj)+e;RRA7oqS#gt*vb%BAB_Hw8XK+3v z4CeO1&^p(~0rhD?#muOD7*+nFEj~W}IS>`oqD?#KGOQ9?up<>%>GKfleF62*Ya9@j zRpX~oOiavkASzu&n|(|clmo6|djg=C2y6)Hg#Ot=4yaEHDjn7*+$5%`sOLasWo56; z1fzx}EvTFt0ZcBfYji5c)z@bHHXe@$s$oZE#Api(3wsX4 zdTJ?^1?wvbMy0^002dXzqrzJW2?<=IQo9fceTOt55GJK!ZV+!`hJ4!@(%#n$`yDoL z^RhRZNWnMBNpyw`NIK1TUbd>mCeavji}@nH^RlO@d?^}33N1m&_iMiMvZtzy z>=o%Y61h&z0AO#!ylgQ;iW%}(&yY#xsz_P$4L40Me)(|J_?e2%kQKhiQLHijrCEo0 zD&rArq%0akrmX#j@2tbPgIN70(M7oWr3PaBJ(T~Kl z4#j-*tKy@~XbZeJ>o7CKM07s7RppCUXB}o)FBgrEnyUhF=kig!I_t35Ls@t}sw(v1 zJL`~lMj5f8KEm-)Q&j}tS%>v!1i2p7|)gjj$Vcks1Y zhm{TsP;T+d*Fwd#{nUlH`C?s&0XKfL4$}<&bG_Jf^7kU$#D}Gy@Hf(kK$sLV`FOCVyyNEPrvIiO zf6&#{&C=J`zrEY3_?U4-Q^CoETkRGxH?QwX-i@b+q*7c}IBT1ojgK!qW?Bsv4+0=N{$_ovn3ww7{OLAJSN38rjq)%*B~; zuvqZouKRr&@~q=-fVIU>Z*)s+a;gotjc>*xqw+m(1SD-#p>Gp+6LOZ7-fslNE~&Ih zL=*OU)i=)3x;*%~GwhOntQ~m$u~uLMSYyh)#jc^4A;k>&t7J&3m%Z11^?e$LTw^r* z{z9#($3$kxohRh<_^%H+!cruL++Z@VQ{;Nt{1|dj^|JXfr?-Mzy7l+#w>^_+kbS+n)B%sLq0AXixj=^-Fqnt!`GoYWhXjv=ipxA zpKvdJh@)`Yq+ zxY^FHg7j_d@{yLoKQ*%aN6J9?T8Y5DFkGD{DkrTAE%$LPF=&nktkO<)JV?3niCw zQC(FA2M32XD=Vu#rlzL-YnGatsz+}k`atq>Gmw{)hKo6=D9F2joa_tS8{+8b=+>~X zFgIUcU;d@8;^X6ab+t7pW*X$>rgI=U7m|^cnT+)GR5Ua+JWJD~TPY|gsF-`lW zkFO z#{_I*V$#DrJdeYN55Mkf*9Hw+l$q%D%nZ_?4}gRo1SEZ6QRQL7%cLEoc@c)6&k=$ST!g@xQ_`XPD?zjNnK557R` zc{PIZv!1J~D~~;*c&t%9%*@QZ3=9lvj~qEttEs6Ox^LgUxIKIJv@)mOW81cEzx-Ya zj(Hrjnfv18>FHVP;^I=vo@q|3y=IF95*Qdbo83>8)x&j8da^QS49wBWV~yTFSY%}6 zh>(yFJ$BW2-rnAK34|WclyGt3!UZmSBPl5ftS3A53&bAFdinYJ+;g68%uAOpG5;u& z%NnC4uxQ2s^&8fcdsrv*VEu>xWoJGTud1pFl=kr=0MiugN8s=84`wo#iWV9gN(*!G z?})5Xc{E{y+Ja1=6G)3b5Z3VU@bCchr8s|b{rdI%Zw=<>=n(+51%XjAAZbIIG0%is zDvSbT(vm>s<>mQnWM^kL!qU=GkNG=Dcb?o{=sx=Ky@;V`4Ihe@u%Wnnb|`KIe+*mg zDLt!Jt@4nQllx_$$I`p(nI_kszYyIwPT*mKE*`abfYEU~qvLHt_aXK~k!p<}Ue#Hx zhK>?Bv==Q#WAwM8$8qdwQrB6li-*_rIBjU(ReuE6qeck_b|?0eKQQ$zo<0cCnzx(- zxmTzlJcs}eZ@81Q6m`MFS{Vfo7a4#(0N<-WJ52j##yngN92PWaP1vu?Gw$xX;y+Yg z?BxCKd7Eg37?YCbD9?6KyiL?gWJk^daa4A8Hpf#!@iqq znKNfN@+V;S-GO&`VWSwN_bKxpw>Z?V+1CZHimFc5Ul`yuH`G z(Om6Jqg~&Ar^|Ko9nKAQYwhdJ<*jS&WKC<#ml$2Ko2ywNcnS5LZr49Om2jt-?I+mB z-D%!%vVMYDM02y8SJbo7&BeL1dXL4dUZ*5dmR4u#roQO3=24M_9dF;4<|2~&i zP0lH?CiC3-2V>srh>VO3Jw{$U=K9^GQ7w8O(wDDJLQX2NDqM)mrVx+%rHFV(zH zBbwn$dlu~U*x1;3SXfx_zx!Ex@F+L^RRH=M1$q=wlF%{v-i&TM1P*M{7yA<4Uj^xl zEc@bHLqo$>K~E7qdSXz}M}u=j{`5GaV`?vo0*KG)|MY0m)z#&%5qlJkV2>g_#?3r- zWq7PnJy?5q+1lFHGUlvh0br=Hv2h$@&sH5B9gjnY4hd$+B}{; z`ZNTCC;*8s09>ZAHU<#gdT#jRmiXbfpGH#uWRcX!eu3JOhWFl29FF@5!z;TR?LpF2 zt%ZEifWt9%b0UO9x0E4o}PH=tQh2Q~4a zXdNEb8laP>h|bGf&{?vP8C-uLrix>;0e%;M1IaK-%HDds%@E+*GL??>7d}ck)CgbHr5kd}9v6Naif4v3)Fi?l;%f)iqaF zSH~6?7ppPzm0Nqk&$UnQ80f4cGW+mKHh`cuP;uI7V1Ou^#jiq5$ z`b9D?uc#6>!919UG@zuSk$X2wKoq(!UAk1TY3#C6KjDBV!ln^qa*3(o$s`&PC2#h~ zkt4LWzu?AZ@%%{UFUHYOE5-Yso}OHcPoX*OsTu?OKcuCl6X(yLFZlAaFRpZRb1P)d zW*7mHhf6~k)R$;nggK*_GiOfN#*G_GWMpJ?`GPP{b|sUCG(fO_|NfCw6N1V)EL^yd z%eSGT6O;usZQ8Vvlqp5^A;ygx_c|DjGLZe$HdKYd+}xaAcyrYl)YQ~)@ZdqNhynp_ z*|LSpQ5rdNB=`+yaE(h>rEhG6mL#Gf4KFV*3S>B7D=RC`L>4~av(NaXooj1rbM+o5 zt%?$wD3OUw89#nJ#*Q6}QKLrT^Upu$5_u@Cs87TUDP~A9L;i{x^0=EG)a=*c>71Ij zMOr@|5t$)R1zCXqoSIkWiwwk&>y76@s5vzQF{IFQY6fD+=_+4As5vzQG356PMnb%{ zkC-9F4EY;l$S8e9B&_<9CYvB`{=3)X=f9&RGDBwBX`@hmDqfvab58PI6_FS+aQmX@7=)TrGY~`WpFR><+eYKXIW-AOsL_9)Yx{^9@@-+rz?gV6 zPLN%Px|M2&AUenSkoH*?DjCV@<@GI_wHi^)wU5i04M z7YYOLE)#D$F`>=}dCljLTzei-mFE#wmW1FkUnnPUc(mi(+L)~|3Lgjp`6H9eGvyYz z(VmaWJC{*%rvRZ>3lUvYiZhol!}C%B0xxC4CdULDLRS>636%XCKOi5EG85F?Petkd z3*fczPqm%%D62cf(q*jzY-6<&*DUIm%Xq`ST?6;UnG2yTr= z?42~kHe7~lc?C|ER6->>A1aX-V01AW&R6Y`-xLZN7pcdK9OlZt2y`~O<`nX7MZ>Qp z907N8kkecQ%R(NGU#!56sC+0fUtnLUGY-@kU|;nicwMrAceW`cPt1sa5vacSb|lW! zyTG#9jcIck7n(0&Z+szkgy-R4&P6CyX+Wl82V}|=v7uxSbQ2CBy~+nOO{X-z2-IHP znhe8oeW+Av!ufg%{I2FKiPuOgDl&*0yO#@~1b#5!0+XqhddYCNEpWdyxT{#fsG9twV!ARkx@Ip0bwK6L>L zEaIWy5(7ndeORYx!!=o-fKr|TZHbbXVjb*JNpm#R6P2+qX)jb_lCjP!2kU~aVzvJj zEVWI;>Hs&^_*zhMSc}wZUjpf6@^ZSqg8$NR%Tx_SmN`K$RU5kLiP#m81?BKED4s3F zMi=(^>}KqATmz>xeH;!@dRd#kZMo;7zp@TibSzd47jA^Wqc|1%k>{Zkl?$!VJZSmF z<7A#55-UA$$bSccR5JOL@BOyGe$HQ62aB0yKJ}5?c^9~)N5VBN32qt52rmwUbE+-@ zJSI(;44kz&)#zur$$CG<{zqrxHFiS#Q)y(9#AN+%cpOs9kYa}XO)%tY3p1$LKUrgZ z?XkHq4%j6+L$0yoKMpx*->7<#7;=NjLP6t@-6Aoh(BqH;G2}D>YmD<<+owN<-0!wk z^l?Z*3^{4vH?^d}Z+IM1%#dP+{7o>Vo~kM$<)5rE9=_~DB-km4&X9(Ov{0Zv?WJ+Z z+&w=+W8-I)A~9sp(l7XqLq;t4W3xyMN#+PO4ml7*Ml2f+q1X25k0H<5DD90^^8z>79e50Zt{ z3Fc&#dkV*pyS*kOtiSLmmz2L#}iA4grkdeX=d#nPraC=S>;dE;yzeV295_ ze5>J9_b zji2Iw7i6I<)P4ScFgqwUBQZ>T>+s!m!V`GE9cmHW=X*gtL z4%MUP;FXngf1{Ve^qsjI=kOng+-$QN2Q&|$prizARJ0(yL{?LV-;oi9VG=rSrbGT?xeebO*zo)ou`38gSlkt9kQkeojk+CDotAOiz~PQDDe zMRz4sRCjYgn^g8=uH-yONl8IYPL2~go+~*Qi`Oq|CmC-v&YCrA!f!l_oOMDqS6A0k7Z;aD zPEJmb1_k2g=BCB~+9|V+5_cRN90r$`&p=B1mMf$L9XmU_!2z8*b?OmmL&-U;ho{ru zXa)kU8f$KDF1(q{l*e>`(IP=7PMk<%{U?J~W}pe*CMG7r0i8T~av?LNm)6ptsUDQy zMu|;yyHL+IHa70R&hhcH4YsC!m4(cdM}6xb(Vo`S=qrS0WMtIN?lr+VHf8~JwyyC_ zI2F?fi-2-&Z82JO!pzL9mrP+=JTf#iEY;W77Yt%TAhC@|ENsEKg1fK?smEcLVp<-g z^VqRt-wM?p#(s6SP7EZ00r;ifgjdoHL}uTHzV}sZFe}ax3dGRos_m($Mx4vP3!jvm zaEQ7NH)dW))-7ne*FesYH}I6aqYT78vJr843?%s`>?5zkg=uy+vl&{aYapv%5-gN9 z+U{2nn|FsZ#WwsJoLM6WXEa0IwFWXrg#@8Z)v=1T#T~fBu`9*Q3t}J#7|0@>qEL}; z0Y#gNJZjLO^k(>{He;VtH5MEe5#$;9oA7w7K_RVEg!$To1Q9c&m?8hK7!pCsw(UMj zZ^n=aP_#v?J`i;T_x)4{$B^(N5M7`k0Lb?Tg4J->d6Q@i37;*th&jSQ7(j|OkaQf# z_5i%Mpxb0}j*uXmm=k#z$nyn~t$;`d7-tNyND`;l0Q%nz%#iR}XNyQ}2I9lCummF5 zaf~65;RLv@29Ayvj@;n30=Vc6Br;RNG=XS626Bpl$OAgx3eS)@xd^zx+9H-|5p@(u zcLbam_~B8a@e*uigECV_F_6!HPYn4R-SmQ*!B36^ z+<>NcBh)8{TOI4L#`+4DAFse7<8sW@E5#(uV!Q+td#UXOxsS+#dkDMOir}0U z_-EaPSNa{CPQ3-Egl5>s-oOd=Xg3SHhHv-gzYY|T)dJtl7Mw}Hi_(5@qis$L^g3CdVvkx ze!u5c)ZgyHS?0lYcK4v;VGmSJU%@9!Q=bFvWsRA5`97yrK-L{jE7F2aAT#J#$+;S} z&0V(JW%7|JeJaF2anZ(D(y zo1M)3yQsL{fg22PqkRR2PLF*Kw8E+i51C112Ay<|0ql0Wf))n4(Y})VEN4-Q>KmPq zGAu?;)qQj_)9P<^;p0g!6yBCJDus1))3d8VW^6uLg|#*nSYcTP88aRh8kay)zZf%h zFJa2zLQK*wz)DLVKK?1{IS_R!lhA9>4`P?szmB^a`#fu);#Q5FPF2|ESjm~O&ZZ0s zC(1a06&6qAB_QflpDX5I#O7>vIkPZ)MLKsiBo-t=Vom~v&5Xy;DY2XxbmFTb<_7U5 zX2`dlA^lSWvEOksmk+twd=XY2J0?0qZm_cBn-4i=#b(hMa=n0j$e)$J6pbN;%7+w& zA%EG$KOgcXjfB|-RqL=Hu(z$&p_n1X4Ed{M$YLKGq^uu{M9DuQdG%K?Q&kt8Ax#eG zp-5x;%k#2T#$)ZYU7|5$pv+f%^C7+Fju4F@1?58~u)mAMkbd*{=R^8Qide8~P_+&P zZEtC~V(w)lS(yUmYHD?KABm{~Yu^IZ9_p`_pWnQExf@NV(2gHRsffyCR*mA!5}R3c<^! zy#TV5fjnLxDi2XW{=q;-PciAkm6H1C1CD9Eds%wQyJL4mpJ#{wJ}?%NncP)v?llDYiwg zgF=uT1DS^D<_GbMv99P;YY-KKISz9%+g=ieq4{q{wfnsgG!^)6EXea*dnCtA zVQjXG{Mc;gRYxv3D->LCRA@@KS*AFkCIpi2z3y0HecN|TRx(j#vWJNblW#I?mL1Em zS<#eiwnVUI`Mw)N^L;iJuoK2IQD&meM1zSslYLCqG5I>pO12=$Y)NQ88g0In=dtDp z`|@%oT2Da^JOv@Gb}^ZkbWHk4vYE^+fk1_RTYGX`6-b-iFKE$c8fmCRS|#W&9Gh$| z+auUCpDjHXoK}r}dIACLeG0ns>EE_9QHax>KQ`&u62U+@?(1${a9l~IEqn^F>nVsL zlWj~kGnpBCc>a;NqYDI^mgOYR`pGJ4?5~-~KLsEywmb!qW%5P5{-VwpZArneqBCse zCTE^p)s%KZmM;HSOy-a&Oja?OP9Pb!tGbJWRFQmOHo{b=uMr5AYOz!?{lv1SWOJE< zM59GV;*Uy=jn$byHuliGBWV`PdrG6U(U9kanoLV18p7H2K1+5ACOHh?!f*U+9+${4!Wr7}pw$JGC-}N_zeNH&yKCBpL?bzrMeCq6`Y1ANIp_Z8z=th_ZZuXsrLUf)hflT$CfY!toL7z zH=^22XXW9`bHj?$(ijxgZi`rhjX^7+5vzjJMJKU4cpK&&pMjZ%lOYn-k}2-Rj&Lrt z#j*1`u+BBb@hn5;U`>EXR7Ea&tEG;| zsw(K-wiTT#lc&NLO|WI#XlO5fg$3LEdQdaKY^n--^bN{4^nu q=8wMky*Q))TMT(;unZ~C8T}vc!&QDPF@fL!0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igi8 z5EnQesrnZH00C4#ehCG-y0e6K`N(VRrucW_DPnwZp4t0#Ov9-|qv!(?OezvDgpJ2uAL3VgQ6(L2W^f z41(bLl$dkQAlCav9YnXw)W!1i@ShaueSq|N8Z7-kpwJyLK&HxNzpD+{`Q1Q>RT`wQ800 zQvQGc{)HaZ4cy^%_wL;nFJA23yZ6bHC!02H$~fV(_|ELc=YHqTox5@4M$IG7s)rsG z_gp`H`t_FP{1>we)0u;9-kTzure3F*)*bNBkM?5h(<09~{7h~Fe;zn6Hc4bX&}m?FI?^e@94|A2$?2dFqfcB&VOK&z2Wx1;1_4G! y7dB>pQ63gWhBgiXT{n>i>BS8P1@)sgL@=3q9<^tU(C7$!xWPfBh?k9p!5RQgN~<0K literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/inf.png b/workflow/public_html/images/inf.png new file mode 100755 index 0000000000000000000000000000000000000000..ac06accaa1d80382746acd035f9c9cb38c93cce0 GIT binary patch literal 1275 zcmcIkzfaph6gGk(jf&Jts6y?~lUX`6KHD)dIoXLIfs%>@L@brI3x|CPR^lJnM`IY< zshzs^59rzs{RbFICw5ddQrnG@r2`YaOF{w+?ZnBxAJ5^e!Rw|YH@q6_bTRvD@u@(;w4o*)`yWQ^b@$uQ&+0oI_ z`T6iW#Tr;s&h;4cfsG5$2s>i-09JBAp;= z#j9T))>!Df9J5hfL3ZFtm_ww*3k9Q?gxGEo3bsho^-U1~AOhDh#b>isxf+(pw!6F^ zk@|kkviDnd-Vuw1w2>f2_6Wrw@!Ecj5>xE?L~PE@Py{^)ZJA;}pN;AoCQC4RUOQzSvLYj?62#z{RtlmfRPy;elvSvz8HUKjdp^ZU#*b(EPA>eENo+@MNZr5(+%Mh=cBv_fJkYQW zHiyGuAU__6$7F;F4xu8+aOjy44Q528h+rB-RuHrc*Ny{}>RE#`uYg8TM|@JoloYrg z8F?6-n2 zf;sk3uW&bN_m0J}A!!qj_%vpkDOWXfY}5!M57UC{;UF2Nea%dhT7c!w^%I^1PM$ kV9Va-qxHs}DJR?+6DG~EKi|JqrrCF)vREsBTG)L37fL2gasU7T literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/inputdocument.gif b/workflow/public_html/images/inputdocument.gif new file mode 100644 index 0000000000000000000000000000000000000000..32f2d1db0bcddd004372c17685828777549500a0 GIT binary patch literal 417 zcmV;S0bc$`Nk%w1VHp4y0M!5h5qA+Sr1ZJn|9a97t6PD?g6Z(|RJ#8mhas)k|Bu7u zUdLX--~W@$^3>`1al!O~$@}T`|4N)n-tYgV()}x`|IOviq|^QO_xHZy|Jm*Tg23#x z*8kD%{!+F7GOhmq|NqJ5{#m^LNw@!p%l|W(Ga-y2zUBVc>i_KV_VM`t#oopE`1k+- z00000A^8LW2LL?)EC2ui02u%m000KQz@BhOEE1#c4DE7Nf>&yM4e2 z%*;Y!z(8W?m@9+}Ei;8eh8C-2&N6~J^hrt_92^oAV>=Ko7#b=lFi9s14habb2@)ok z9tQ_30ZI`I1Cj{~B&9n#Iw>?u790)(0}DB`Ii(`2NfrqXybcAICNjb#xJYrwlpV^; zIS)+_6Tp`O)DzB34>B6t+}kqOOAj5=CMf0|;7ZWl-PTPC6gBem^B_$K8w~pU`WqKi L00Rni5(EG{-PFx` literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/izp.png b/workflow/public_html/images/izp.png new file mode 100755 index 0000000000000000000000000000000000000000..52dd86d0f31e018556dbc8604c10c8e1a5ee84c7 GIT binary patch literal 1275 zcmcIkzfaph6gGk(jml7|s;YMA$xKy=&vpzZmJd zYNxK1x^`@r{sSy*jFlLQ)OKUaR#i;&oP-1z=)}psAJ53I4@4i>?{_+#jW59AJ(>9JIp7it}>UrzPfz8Oopw;my3<%V(pq3W|hbU?^I~ zRkH>#rWM`PbLR9Us38uXp%CaM&{b7*x|KD>Ba-PhxsVp4&Ahs`R$A=G6sx?v%{jFo zY`5D=JF5`ZfLbn>gQ^a7JtGjAXgB02&VD ze{+Zq0)le`fEpOmuwlcY@!I@)S&Om|WeEp$ zd7k>_nh8j5IGqAATE%5$>q>3+T?d|`~XYp4AeBJn$z#uD}lIMF3mZq jk1n08QwP)Uo79k`+kZ#?_>ZHG_%4+fs->^z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ={7FPXRCwC0mVaoJbsWcE&;4+>ABU$)bFR}1b7_e! z4Oh#G3^U!9vrTim zZQkvEJa^Cc8@K0S-~Di#*Y<%o&zHMDUa#-x{T!Q3N{JOxo;N!^Y`RrObx`v5zcsA; z$3qH}WZL*Yvo+vhOII0>q_wbV+D@Lyg0-F!?D|=X{Mn>1sSA{Lm*8`rXN`L&MOhxE z+5sTP3GdE%h&wm^IE~;LS{^d zgaDnPu>*4+uKH z;yKs^w~gT&P`8g6aHI`>+6CJlhrN4d^Md0m_RTIBSHRE(MB}DJEDl+2aJdGm$fpVa ztWxr8Ps8;n)&>;(+$}hE0Nz*$AC`mn1~>(*>~OOza*|K(EgDlG5f@3Ym4qpio(VH% zg6}?9`Y`$T2k|eiz<1maZ4m(Yy%Ubsz=~&K-v*d}6?EIsJlgAKQS1bJ@7XxIfZkt$ zlF+R)8hEBc)PP_NkKT>%)iOAK2o9VC@9R*u5%L-#;21p%!mu=2$?mBi+_{3d73?z!V7) z8{BkS0OuHSK*$aNP6NO@LLeM9R-9?LS=-&&H)0bOTx}t4fK!?hb_q5hWP?t}@R*-# zK$-xT0Gr^B6+Bi?PtkA2>beV^hp)AV2EPX;JfyaOo=6HPiF5&89paj`4GV0yzH?bg zOUlYI{~8)=npl18QgB~GtE$85zCTynBLqSTm?8#Cn1E#=$WDMmLZ&d`X$n4a1Eb95 zX10Fc9DV21U*UlbbO)k*(G(6=T#Qy-oay)jr?e!jB+nTJ3 zJB%&+8}(pqb2Pa9qF%M*hA93rP9>Vu2j543sr^s*O@#BU2EX=$p&c-I>F)-v$Re&}1ko72 z1qD?7n`s6bX-`SO8XYhgJf%0!Q5SoVv*~}*rwx`E*?&MlHSN4lIol`(bR{s6sqXEd zRXoX$u1oZ4=18U0fGWQRS+o(P8$S5KwOf z*=tnso+##XQ3-Td;4W3cWX+yn7v-VV9C94yml{TVv{0dt7~ UE}f}hiU0rr07*qoM6N<$f<|I_m;e9( literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/language-selected.png b/workflow/public_html/images/language-selected.png new file mode 100755 index 0000000000000000000000000000000000000000..ee54586594cae5f4099a6cadd3fd492f7b2ec2d0 GIT binary patch literal 829 zcmV-D1H$}?P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ige+ z4>lp0BW_Xv00O;9L_t(I%YBngXjMlP$A2?(ulI$-_+Cvki_{o{vtQzHk;a@7*nynN1`S-H@ROk z)5Xn8ErMq=aG3djoihTUYjBcst;^?_PYm;kAu)!9)bOfu08E;)sjdou-tD#jyAZ^N z`PlF*)Wiw+k!E6Qj-T%b0En)^$!2TqFOC$2h7~Wf3&4?p5V%s1a|Ffl$L#&!O>zF_ zKR6~$w{5DcD!j-X#D>aca_M}rKQuPQ5F<^f6eSYfzZ z9Af0JL(GKF5b1Ibw0+Bk8;yMSPF)6oPM3MET(qE(SimBL;rfGa#{FTeXK<|{NCUne z?c%qdz$&GL1KsbvpE7v+9G7knSSQ;i!$O={P*R|c z0BgB+{~JQ}-zG|1!PPG(nVKtc^w%C-y&Bniu#d;Z=|`R`@m$G7QS;Q-1TpyGEd3ot z_P>3ag13erKc8eeD6#YG2K*qR;Q z<7fu(WNL;VM(>iZsvuvTBVXyUqSB+ash!JX{dD*3q%>E;4f+rvY>_~9%$xtwDkpP;$1W$o)L*F5|e+8avOLR_`&00000NkvXX Hu0mjf#XNY? literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/lastPage.gif b/workflow/public_html/images/lastPage.gif new file mode 100644 index 0000000000000000000000000000000000000000..fae0cca3612fed5ca7072a9cc6a2d087ee72da30 GIT binary patch literal 284 zcmV+%0ptEhNk%w1VG{rn0K@?A}#W0S{-tX<5%iwFT z*S+25K$p)If5%^_)r!E~JpGn` n@tlx`fU9RSKR>P&Q|ntA**5>w#+lIvr`TM4-uv8xk--`O%`G66 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/loader-gears.gif b/workflow/public_html/images/loader-gears.gif new file mode 100755 index 0000000000000000000000000000000000000000..914a0f2b0453ec8e35133b0c82547dc64b547aad GIT binary patch literal 22004 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 V5HY@mgKzgLO_YMBYGYrFI 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/mail-message-new.png b/workflow/public_html/images/mail-message-new.png new file mode 100755 index 0000000000000000000000000000000000000000..13b2c8f48fb32d1d834d58800c1ca404da32b59e GIT binary patch literal 1258 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igM) z6csPfC*QmP00e4DL_t(o!|jz_Y?D2_p z@EeENFlPl^E|)$O3h4nep!`GbvI7SWyt04){+ERi52+rHU$zT465-s9PW%eoY! zP7=A^$A^!d0N}NAFX32R&7>w67>jWH*H2-T6CC12bvm#T3We-a%4>J95JmWIOSgN` z;zbxs^u)3~ScM=qdZj3gk6p!<&oi2ns0Nklni>YK^zY*ctwjJ}`Q2>C-tYE;9qd*+ zH*+Bt8lY4sm`L>%H521~NL5cdD~W4hFRNg{+Am4+x;m?xlD`K(d-g1ijg9{b;2rXU z9WF*MaIFI#G6?JjL4S81o-JrP&xeVQM~I~%n$44_0!k4WX;g2wqyXV?7)4PC27^c` zS-W;EU0q#BDRH~q1Ofp}c@q&W0tS$Nh`%i{*RQAjhjvQ!rHtjrQ0k!aeL=YaDh&_~L(e+}sugbu?9~uY zLm~?$bugs?IuZiV9Xxn&Uu|veN6pR6C3kuVo4#$rr}u#Y944r-K+OUe?1J{^3jj}j zDR9<9I0d~a2v0yZjU7>VkRFDt3X~(!F~)A*L~ug@jZ#Wq zq4fp{27kwDwPLs10T>@2$K&zf_xn*4g@%R(IyySgG!3KCNG6jZ7K?H5{6&tfI7V+( zFWdxDKzf?e09b&B;nCy@t~`CY1;J4yQ2}g}QvPx;Ug9%foS`k&hPT$s)rD8V2;=|_ zmPMEHWKR>@9Xr_m+_ql_Ka-kFrrycPN&Xl17q)Z@ UK#7y>u>b%707*qoM6N<$f@nr9F8}}l literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/mail-queue.png b/workflow/public_html/images/mail-queue.png new file mode 100755 index 0000000000000000000000000000000000000000..884ad82a6023dc22c9ab0118946ebbdc4c8cf4ae GIT binary patch literal 1740 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/mail.gif b/workflow/public_html/images/mail.gif new file mode 100644 index 0000000000000000000000000000000000000000..036a9489514b739cc390b7331590519bc2d1e294 GIT binary patch literal 277 zcmV+w0qXuoNk%w1VHp4y0K@X$A^8LW2LK-cEC2ui02u%m000G&;3tk`X`X1Ru59bRaQu1Ows=V* z?fFuBsmUZmEE~awDZVxH%8E`@xZG zQUo~x{^%$2ZUiY65fKxG6a|WfhY=Mi1{M$&l$Dl~1}P5^1D&3qoe&Qx00E|_sHgxb b4i5$f7Y+^r0@nfk&@naED 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 literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/minus.gif b/workflow/public_html/images/minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..b8537df69b69f4d9dfad86b674b417b7e6f09432 GIT binary patch literal 868 zcmZ?wbhEHb6krfz_|Cx4(9rPz|9=Js1_%jcjDpb+7&#%J_>+Z^fq{`h2jpc?o?zf` zWMJly@z}87U^9oXR?LYF3JvW7igGLl8y7itiR)VNC@e@m&LHBi3*BJ!6k`h{6D}T z$icwHz{AWa$iO7X$SlbC{|JK^*r^Q2fQ=m}E++t#;6xT?U}9!v6A}vyopK2%FT%)( zA_?SxLi3*BJ!6k`h{6D}T z$iX1Rz{1QZ$iO7X$SlbC{|JL9(5Vb4fQ=m}tRTR^$i&KuEWs+u$jm03Bo-Vx|&a$Ql_KgarTJV&DNPXA)!H=;Uucj#j?8>hBzQ U?ZWp;x_|Ke8)@gd=J@}c0J{A$$^ZZW literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/bsm.jpg b/workflow/public_html/images/newSkin/bsm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee151c40f7ef7a2ee6d7ed21c31460aeb68c7202 GIT binary patch literal 292 zcma)$OA5j;6h&{$*EF?>X{EFs6vy3zf>6*+>Czmy2tNbeNlYCSKNAl;c$^3K-Ea;M z*j>NvK_VULfN;YGf-%OK;9N{aoJ0ws5~FpZwXx=fHM7iSGvj@pd*9S`-LxY^2$52z zCM~TktHKr4c>H$>M>vHFoDzqLBh-;_!eXe3cNmq?7xqg7^QiM5i^00jh!_{HFqFhU P)M15ts}4)D-iON*g`gze literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/bsms.jpg b/workflow/public_html/images/newSkin/bsms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e58d448cad27c0c3e5071cc65818abd57b45304d GIT binary patch literal 323 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{Jcb$iO7X$SlbC{|JK^$f*p-fSHjUC@wDml;A{>VP<4y7Zef?3Y&5fq!Hvr zWPJ<_j7&grNkK-S6(|ynOoGCJ|8FtyFaxConFSf_8E)sk(Yq$Q=jD%>(^9KXc&?o6 LadQP@!~dHAw0|+h literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/fbc.blue.png b/workflow/public_html/images/newSkin/fbc.blue.png new file mode 100755 index 0000000000000000000000000000000000000000..9a503c9d1cf820e20fc93f62063b1aa55f9019c0 GIT binary patch literal 1242 zcmcIk&ubGw7~O)DbfMH9#8eLs>(%V+kJylPlhP)wjU=%)0iy@$WOtIT$?hz(Q?f0B zQhLyfh#-g;dn<@|>9x>+e}#9?TD*F3Hc6ATh@Lv^{Q7wBec!wp_SIVX?zDJK6a-8)fjKjV)jeEpYm591%e=+M15lEbMie8#@TX>RY-$% z5XHixP3jn|I23mXZ3XuaZOG?Sl;Z0|ChvLdkxoYjSth6mHWJNPHIN8MvfzWMxfe~h;o~FUqQ5Z^~2Vt#@ z)UT&jS_3&kF-Xd4!cz1kNY2YzN=v8aZ-EM8;2!dTmI9ih@If>56#sZJy(VQvKAY5T z80-0!K~BEQNSloL285kXNABn{p-rf!(`l$^P}33|kqEXuhQfpw-0X{->f~`?QO9Qv z@j#@D>ST*$Bq>TXY=grgf0)P%2Ig@aVTgRF$_gARbE3(EMvh{{2(1#*&YrstkgMos z#5@BUWgYQx9x+kc~{3{4%-$3O$R2_qxM zjOn=^o#|Zse}>uC&@X?BwtLrNTM)Ogi#--_&(yP?*_P2D)I}`oxTuMt?=?+03jVXc ze%1V0@Mj5!@A9WPUzX+bNg?@D}pe4Rdk*l!>3$EC@h!r JUzRp@{{ShsJqZ8+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/fbc.png b/workflow/public_html/images/newSkin/fbc.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff292f0f2313d582b0c1c35416a732e2d110d9a GIT binary patch literal 40655 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 A>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/images/newSkin/fbl.blue.png b/workflow/public_html/images/newSkin/fbl.blue.png new file mode 100755 index 0000000000000000000000000000000000000000..6dd9228cd668f78f5de6356f5afe8720f0d84ce0 GIT binary patch literal 1343 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

    containing the day names */ + border-bottom: 1px solid #B5CFBF; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #B5CFBF; /*e*/ + color: #000; + border: 1px solid #000; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #6F7F75; /*e*/ + border: 1px solid #FFF; + color: #FFF; + padding: 2px 0px 0px 2px; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #456; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #A4BBAD; /*here*/ +} + +.calendar tbody .rowhilite td { /* the rowwwwwww*/ + background: #C9E5D4; +} + +.calendar tbody .rowhilite td.wn { + background: #F1F8FC; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #E9F2E9; + padding: 1px 3px 1px 1px; + border: 1px solid #6F7F75; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #6F7F75; + color: #FFF; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fff; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { /* Cell showing selected date */ + font-weight: bold; + color: #D50000; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The
    */ + background: #000; + color: #fff; + border-top: 1px solid #206A9B; + padding: 1px; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #B8DAF0; + border: 1px solid #178AEB; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #006AA9; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #def; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #34ABFA; + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + font-weight: bold; +} + +.calendar .combo .active { + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + background: #F1F8FC; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #E9F2E9; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #E9F2E9; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { /*e*/ + border-color: #000; + background-color: #6F7F75; + color: #fff; +} + +.calendar td.time span.active { + border-color: red; + background-color: #000; + color: #A5FF00; +} + +/**************************** End -> JSCalendar Widget by Erik Amaru Ortiz *********************************/ + +/**************************** Start -> Suggest Widget by Erik Amaru Ortiz *********************************/ +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +input.module_app_suggest{ + color:#333333; + font:8pt sans-serif; + padding:1px 1px 1px 3px; +} + + + +div.autosuggest +{ + position: absolute; + background-position: top; + background-repeat: no-repeat; + padding: 8px 2px 0 3px; + z-index:1000; +} + + +div.autosuggest div.as_header, +div.autosuggest div.as_footer +{ + position: relative; + height: 0px; + padding: 0 6px; + + background-position: top right; + background-repeat: no-repeat; + overflow: hidden; +} +div.autosuggest div.as_footer +{ + +} + +div.autosuggest div.as_header div.as_corner, +div.autosuggest div.as_footer div.as_corner +{ + position: absolute; + top: 0; + left: 0; + height: 6px; + width: 6px; + + background-position: top left; + background-repeat: no-repeat; +} +div.autosuggest div.as_footer div.as_corner +{ + +} +div.autosuggest div.as_header div.as_bar, +div.autosuggest div.as_footer div.as_bar +{ + height: 6px; + overflow: hidden; + background-color: #333; +} + + +div.autosuggest ul +{ + list-style: none; + margin: 0 0 -4px 0; + padding: 0; + overflow: hidden; + background-color: #fff; + border: 1px #C3C3C3 solid; + color: #000; +} + +div.autosuggest ul li +{ + color: #ccc; + padding: 0; + margin: 0 4px 4px; + text-align: left; +} + +div.autosuggest ul li a +{ + color: #000; + display: block; + text-decoration: none; + background-color: transparent; + /*text-shadow: #000 0px 0px 5px;*/ + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + background-color: #444; +} +div.autosuggest ul li.as_highlight a:hover +{ + background-color: #D1DEDF; /*erik -- back sel color*/ +} + +div.autosuggest ul li a span +{ + display: block; + padding: 1px 0px; + font-weight: normal; +} + +div.autosuggest ul li a span small +{ + font-weight: normal; + color: #999; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: red; +} + +div.autosuggest ul li.as_highlight a +{ + color: #000; + background-color: #D1DEDF; /* erik -- hover*/ + + background-position: bottom right; + background-repeat: no-repeat; +} + +div.autosuggest ul li.as_highlight a span +{ + + background-position: bottom left; + background-repeat: no-repeat; +} + +div.autosuggest ul li a .tl, +div.autosuggest ul li a .tr +{ + background-image: transparent; + background-repeat: no-repeat; + width: 6px; + height: 6px; + position: absolute; + top: 0; + padding: 0; + margin: 0; +} +div.autosuggest ul li a .tr +{ + right: 0; +} + +div.autosuggest ul li.as_highlight a .tl +{ + left: 0; + background-position: bottom left; +} + +div.autosuggest ul li.as_highlight a .tr +{ + right: 0; + + background-position: bottom right; +} + + + +div.autosuggest ul li.as_warning +{ + font-weight: normal; + text-align: center; + color: #A0A0A0; +} + +div.autosuggest ul em +{ + font-style: normal; + color: #000; + font-weight: bold; +} + +.textBlue{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:#006699; + text-decoration:none; +} + +.textBlack{ + font:normal 8pt Tahoma,sans-serif,MiscFixed; + color:#808080; + text-decoration:none; +} + +/**************************** End -> Suggest Widget by Erik Amaru Ortiz *********************************/ + +.tableGrid_view +{ + width: 100%; + border-top: 0px solid #DADADA; + border-bottom: 0px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + +table.tableGrid_view td +{ + border-top: 1px solid #DADADA; + border-bottom: 1px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + +.ui-widget-header { + -moz-background-clip:border; + -moz-background-inline-policy:continuous; + -moz-background-origin:padding; + background:#5C9CCC url(/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) repeat-x scroll 50% 50%; + border:1px solid #4297D7; + color:#FFFFFF; + font-weight:bold; + font-size: 11px; +} + + +/**************************** new calendar **********************************************/ + +.DHTMLSuite_calendar{ /* Main div for the calendar */ + border:1px solid #8F8F8F; + background-color:#FFF; + width:220px; + position:relative; + overflow:hidden; + font-size: 11px; + +} +.DHTMLSuite_calendarContent{ /* Sub div inside DHTMLSuite_calendar - this is the div where content is added */ + position:relative; /* IMPORTANT - This must always be like this in order to make it possible to position sub elements correctly, especially the iframe */ + z-index:10; /* IMPORTANT - This must always be like this in order to make it possible to position sub elements correctly, especially the iframe */ + background-color:#FFF; + font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + + +/******************* + + START CSS FOR THE HEADER ROW - WHERE YOU SEE MONTH AND YEAR + +********************/ +.DHTMLSuite_calendar .DHTMLSuite_calendarHeading{ /* Heading of calendar, where you see the month and year */ + background-image:url(/images/calendar/calendar_heading.png); + background-repeat:repeat-x; + height:21px; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} +.DHTMLSuite_calendarHeadingTxt{ /* Inner div in the heading */ + padding:1px; + text-align:center; + font-size: 11px; +} + +.DHTMLSuite_calendarCloseButton{ /* Close button at the top right corner of the calendar */ + background-image:url(/images/calendar/calendar-close.gif); + background-repeat:no-repeat; + width:13px; + height:13px; + position:absolute; + right:3px; + top:3px; + padding:1px; + background-position:center center; + cursor:pointer; + font-size: 11px; +} + +.DHTMLSuite_calendarHeaderMonthAndYear{ /* Div elements for year and month in the heading */ + padding:1px; + padding-right:2px; + padding-left:2px; + cursor:pointer; + line-height:17px; + font-size: 11px; + font-weight: bold; + font-size: 11px; +} +.DHTMLSuite_calendarHeaderMonthAndYearOver{ /* Mouse over effect - month and year in the heading */ + background-color:#FFF; + border:1px solid #8F8F8F; + padding:0px; + padding-left:1px; + padding-right:1px; + font-size: 11px; +} + + +/******************* + + START CSS FOR THE TIME BAR - THE DIV WHERE YOU SEE "Time: " and the hour and minute + +********************/ + +.DHTMLSuite_calendar_timeBar{ /* Time bar - where users can select hour and minutes */ + background-color:#D3D3D3; + height:21px; + border-top:1px solid #8F8F8F; + text-align:center; + position:relative; + font-size: 11px; +} +.DHTMLSuite_calendar_timeBarHourAndMinute{ /* General rules for the displayed hours and minutes - the ones you can click on the bring out the drop down boxes */ + padding:1px; + padding-left:2px; + padding-right:2px; + margin-right:2px; + cursor:pointer; + font-size: 11px; +} +.DHTMLSuite_calendarTimeBarHourAndMinuteOver{ /* Mouse over effect for the hour and minute displayed in the time bar */ + background-color:#FFF; + border:1px solid #8F8F8F; + padding:0px; + padding-left:1px; + padding-right:1px; + font-size: 11px; +} +.DHTMLSuite_calendarTimeBarTimeString{ /* String "Time:" */ + position:absolute; + left:2px; + top:2px; + font-size: 11px; +} + +/******************* + + START CSS FOR THE NAVIGATION BAR - THE DIV WITH THE LEFT AND RIGHT ARROWS + +********************/ + +.DHTMLSuite_calendar_navigationBar{ /* Navigation bar below the heading */ + background-color:#D3D3D3; + height:17px; + border-bottom:1px solid #8F8F8F; + position:relative; + font-size: 11px; +} +.DHTMLSuite_calendar_navigationBarToday{ /* Div for the string "Today" in the navigation bar */ + text-align:center; + font-size: 11px; +} +.DHTMLSuite_calendar_navigationBarToday span{ /* The "Today" string inside the navigation bar */ + cursor:pointer; + font-size: 11px; +} +.DHTMLSuite_calendar_btnNextYear,.DHTMLSuite_calendar_btnPreviousYear,.DHTMLSuite_calendar_btnNextMonth,.DHTMLSuite_calendar_btnPreviousMonth{ /* Buttons - previous/next month and year */ + position:absolute; + background-repeat:no-repeat; + background-position:center center; + width:13px; + height:13px; + padding:1px; + top:1px; + font-size: 11px; +} + +.DHTMLSuite_calendar_btnNextYear{ /* Next year button */ + background-image:url(/images/calendar/calendar-next-year.gif); + right:2px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnPreviousYear{ /* Previous year button */ + background-image:url(/images/calendar/calendar-previous-year.gif); + left:2px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnNextMonth{ /* Next month button */ + background-image:url(/images/calendar/calendar-next-month.gif); + right:18px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnPreviousMonth{ /* Previous month button */ + background-image:url(/images/calendar/calendar-previous-month.gif); + left:18px; + font-size: 11px; +} + +/******************* + + START CSS FOR THE MAIN DIV CONTAINING ALL THE DAYS WITHIN A MONTH AND HEADINGS (weeks, days(Mon-Sun) etc.) + +********************/ + + +.DHTMLSuite_calendar_monthView{ /* Main div element for the days in a month */ + + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView_headerCell{ /* Main div element for the days in a month */ + background-color:#FFF; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView_firstColumn{ /* First column - the week column */ + background-color:#D3D3D3; + border-right:1px solid #8F8F8F; + text-align:left; + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView td{ /* Default css for all the cells inside the calendar, i.e. week heading, label for the days, and the days */ + text-align:center; + cursor:default; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_headerSunday{ /* Sunday in the header */ + color:red; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_daysInOtherMonths{ /* Days in previous or next month, i.e. before start of current displayed month or after days in the currently displayed month */ + color:#999; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_daysInThisMonth{ /* Layout - ordinary days(mon-sat) in this month */ + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_sundayInThisMonth{ /* Layout - sundays in current displayed month */ + color:red; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_initialDate{ /* Inital set date, example: the date in an input field which you are populating with the calendar */ + background-color:#8F8F8F; + color:white; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_invalidDate{ /* Inital set date, example: the date in an input field which you are populating with the calendar */ + color:#AAA; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_currentDate{ /* Date of today */ + background-color:#dfe9fa; + font-size: 11px; + font-weight: bold; +} +/*************************************************** +* +* START CSS - DROP DOWN BOXES +* +* +***************************************************/ + +/*** MINUTES ***/ +.DHTMLSuite_calendar_minuteDropDown{ /* Drop down box for minutes */ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:23px; + padding:1px; + text-align:center; + /* You shouldn't change these 3 options */ + position:absolute; + z-index:152000; + cursor:pointer; + font-size: 11px; + +} +.DHTMLSuite_calendar_minuteDropDownCurrentMinute{ /* Minute in drop down when it's equal to current minute of the display, i.e. the minute you see where you click on the drop down */ + color:red; + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAMinuteOver{ + background-color:#dfe9fa; + font-size: 11px; +} + +/*** HOURS ***/ +.DHTMLSuite_calendar_hourDropDown{ /* Drop down box for hours */ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:23px; + position:absolute; + z-index:152000; + padding:1px; + cursor:pointer; + font-size:11px; + text-align:center; +} +.DHTMLSuite_calendar_dropdownAnHourOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_hourDropDownCurrentHour{ + color:red; + font-size: 11px; +} + +/*** MONTHS ***/ +.DHTMLSuite_calendar_monthDropDown{ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:70px; + position:absolute; + z-index:152000; + cursor:pointer; + padding:1px; + font-size: 11px; +} +.DHTMLSuite_calendar_dropDownAMonth{ + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAMonthOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_yearDropDownCurrentMonth{ + color:red; + font-size: 11px; +} + +/***** YEAR ****/ +.DHTMLSuite_calendar_yearDropDown{ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:30px; + position:absolute; + z-index:152000; + cursor:pointer; + padding:1px; + font-size:12px; + text-align:center; + font-size: 11px; +} +.DHTMLSuite_calendar_dropDownAYear{ + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAYearOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_yearDropDownCurrentYear{ /* Current year */ + color:red; + font-size: 11px; +} + + + +/* UP AND DOWN ARROWS INSIDE DROP DOWNS **/ +.DHTMLSuite_calendar_dropDown_arrowUp{ /* Drop down - moving to previous year */ + background-image:url(/images/calendar/calendar-dropdown-up.gif); + background-repeat:no-repeat; + background-position:center center; + height:8px; + font-size: 11px; +} + +.DHTMLSuite_calendar_dropDown_arrowDown{ /* Drop down - moving to previous year */ + background-image:url(/images/calendar/calendar-dropdown-down.gif); + background-repeat:no-repeat; + background-position:center center; + height:8px; + font-size: 11px; +} +.DHTMLSuite_calendarDropDown_dropDownArrowOver{ + background-color:#dfe9fa; + font-size: 11px; +} + + + + +/* IT'S IMPORTANT TO HAVE THIS CSS RULE AT THE BOTTOM IN ORDER TO MAKE THE PADDING OVERRIDE PADDING OF OTHER ELEMENTS */ +.DHTMLSuite_calendarButtonOver{ /* Mouse over effect for the close button */ + background-color:#FFF; /* White background color */ + border:1px solid #8F8F8F; /* Blue border */ + padding:0px; /* The sum border+padding of this element should be the same as border+padding of .DHTMLSuite_calendarCloseButton */ + font-size: 11px; +} +.DHTMLSuite_calendarDayOver{ /* Mouse over effect - days in the calendar, i.e. days in current displayed month */ + background-color:#D3D3D3; + font-size: 11px; +} + +/* YOU SHOULD NEVER MODIFY THIS ONE */ +.DHTMLSuite_calendar_iframe{ /* Iframe used to cover select boxes below in older IE browsers(version 6 and prior) */ + position:absolute; + top:1px; + left:1px; + z-index:1; + font-size: 11px; +} + +.calendar_picker_min{ + cursor:pointer; + background-image:url(/images/btncal_min.png); + float:left; width:96px; height:23px; + /*font-weight: bold;*/ + color:#000; + font-size: 11px; +} +.calendar_picker{ + cursor:pointer; + background-image:url(/images/btncal.png); + float:left; width:121px; height:23px; + /*font-weight: bold;*/ + color:#000; + font-size: 11px; +} + +/*@start: PM tooltip -> neyek */ +#pmtooltip{ + background-color:#EEE; + border:1px solid #000; + position:absolute; + display:none; + z-index:20000; + padding:2px; + font-size:0.9em; + -moz-border-radius:6px; /* Rounded edges in Firefox */ + font-family: "Trebuchet MS", "Lucida Sans Unicode", Arial, sans-serif; + +} +#pmtooltipShadow{ + position:absolute; + background-color:#555; + display:none; + z-index:10000; + opacity:0.7; + filter:alpha(opacity=70); + -khtml-opacity: 0.7; + -moz-opacity: 0.7; + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} +/*@end: PM tooltip */ + +/** + * (init) Dynaform Handler styles */ + +#sortable {list-style-type: none;margin: 2; padding: 0; width: 700px;} +#sortable li {margin: 1px 1px 1px 1px;padding: 1px;padding-left: 1px;font-size: 13px;height: 28px;} +/*#sortable li:hover {background: orange;}*/ +#sortable li span {position: absolute;margin-left: -1.3em;} +.dtext{padding-top: 0px;font-size: 13px;color:blue;} +.dynalist td{font-size: 10px;color: #000;} +#jq-siteContain {width: 910px;margin: 0 auto;} +#jq-content {background: #181c21 url(images/bg_home_content.gif) top repeat-x;padding: 4em 40px;border-bottom: 1px solid #000;} +#jq-intro {padding-top: 1em;width: 515px;margin-bottom: 3.5em;} +#jq-intro li {float: left;font-size: 1.4em;} +#jq-intro li a { color: #5DB0E6; font-weight: bold; text-decoration: underline; float: left; background: url(images/icon_check_whiteOnDarkBlue.gif) left no-repeat; padding: 0 30px 0 23px;} +#jq-intro li p {font-size: .9em;} +body.jq-enhanced #jq-intro li {position: relative;} +html.js div.jq-checkpointSubhead {display: none;} +body.jq-enhanced #jq-intro li div.jq-checkpointSubhead { position: absolute; width: 253px; height: 54px; background: url(/images/bg_ctaTooltip.png) 0 0 no-repeat; top: -1.5em; left: -35%; z-index: 100;} +body.jq-enhanced #jq-intro li div.jq-checkpointSubhead p{font-size: 1em; padding: 10px 5px 0 50px; color: #AE0001; font-weight: bold; line-height: 1.3em; margin: 0; cursor: pointer;} +.toggler { font-size:10px;height: 200px; position: relative;} +#effect { width:180px;font-size:10px;height: 135px; padding: 0.4em; position: relative; background: #fff; } +#effect h3 { font-size:10px;margin: 0; padding: 0.4em; text-align: center; } + +.current_selected_item{ + border:2px solid orange; + background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; + font-weight: bold; + color: #2e6e9e; + outline: none; + +} + +/* + * (end) Dybaform Handler styles **/ + +/*extendend fields styles*/ +#fieldshandler_items_table{ + direction: ltr; +} + +.htmleditor{ + -x-system-font:none; + background:#FFFFFF url(../images/input_back.gif) repeat-x scroll 0 0; + border:1px solid #AAAAAA; + color:#333333; + font-family:sans-serif; + font-size:8pt; + font-size-adjust:none; + font-stretch:normal; + font-style:normal; + font-variant:normal; + font-weight:normal; + line-height:normal; + padding:1px 1px 1px 3px; + direction:ltr; +} + +.FormTextPM{ + direction: ltr; +} + +.directionSide1{ + direction: ltr; + align: left; +} + +.directionSide2{ + direction: rtl; + align: right; +} + +.pm__dynavars{ + direction:ltr; + font-weight:bold; +} + +.tag_cloud { padding: 3px; text-decoration: none; } +.tag_cloud:link { color: #006699; } +.tag_cloud:visited { color: #006699; } +.tag_cloud:hover { color: #ffffff; background: #006699; } +.tag_cloud:active { color: #ffffff; background: #ACFC65; } + +input.notValidateThisFields { + position: absolute; + left: -9999px; +} + +input#DynaformRequiredFields { + position: absolute; + left: -9999px; +} + + +/* +* COMMON LAYOUT PANE FORMATTING -----------------resizer panel ------------------------------------------- +*/ +.pane , /* outer pane class */ +.ui-layout-pane { /* inner pane class */ + background-color: #fff; + border: 0px solid #777; + padding: 3px;/* alignment & padding is on the inner-divs */ + overflow: none; /* will be auto-set to 'hidden' for any pane with a 'scrolling content div' */ + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} + + +/* +* OUTER-LAYOUT PANE FORMATTING +*/ +.pane-north , +.pane-south , +.pane-west , +.pane-east { + overflow: auto; /*neyek1*/ +} +.pane-north { + border-bottom: none; +} +.pane-north .content , +.pane-south .content { + text-align: center; +} + +.pane-center { + /* show off the inner-layout inside the outer-center-pane*/ + background-color: #F6F6F6; + padding: 0px; /* for outer layout */ +} + + +.ui-layout-center .footer { border-top: 1px solid #BBB; } + +/* +* INNER-LAYOUT PANE FORMATTING +*/ + +.ui-layout-center .ui-layout-pane { + padding: 10px; +} +.ui-layout-center .ui-layout-north , +.ui-layout-center .ui-layout-south { + text-align: center; +} +.ui-layout-center .ui-layout-center { + padding: 0 !important; /* inner divs have padding */ +} +.ui-layout-center .ui-layout-content { + padding: 0px; +} +.ui-layout-center .ui-layout-center h3 { + font-size: 1em; + padding: 5px; + margin: 0; +} + + +/* +* OUTER LAYOUT RESIZERS & TOGGLERS --resizable panel +* By. Erik +*/ + +/* north-pane is not resizable +.resizer-north-dragging , +.resizer-north:hover { background: url(../img/resizable-n.gif) repeat-x center; }*/ +.resizer-south-dragging , +.resizer-south:hover { background: #DCDCDC } + +.resizer-west-dragging , +.resizer-west-open:hover { background: #DCDCDC } +.resizer-east-dragging , +.resizer-east-open:hover { background: #DCDCDC } + +.resizer-west-open , +.resizer-east-open { + background-color: #999; + opacity: 0.1; + filter: alpha(opacity=10); +} +.resizer-west-open:hover , +.resizer-east-open:hover { + opacity: 1; + filter: alpha(opacity=100); +} +.resizer-dragging { + /* see draggable.opacity option + opacity: 0.5; + filter: alpha(opacity=50); + */ +} +.resizer-dragging-limit { background: #FF3300 !important; } + +/* IE6 * HACK - always show resizer graphics because IE6 cannot understand elem:hover */ +/** html .resizer-north { background: url(../img/resizable-n.gif) repeat-x center !important; } */ +* html .resizer-south { background: #DCDCDC } +* html .resizer-west-open { background: #DCDCDC } +* html .resizer-east-open { background: #DCDCDC } +/** html .resizer-north , */ +* html .resizer-south , +* html .resizer-west-open , +* html .resizer-east-open { + opacity: 0.1 !important; + filter: alpha(opacity=10) !important; +} + +/* +* SIMPLE TOGGLER BUTTONS (used on Outer Layout North/South only) +*/ + +.toggler-north-open , +.toggler-south-closed { background: #DCDCDC } +.toggler-north-closed , +.toggler-south-open { background: #DCDCDC } +/* +.toggler-east-closed , +.toggler-west-open { background: url(../img/toggle-lt.gif) no-repeat center right; } +.toggler-west-closed , +.toggler-east-open { background: url(../img/toggle-rt.gif) no-repeat center left; } +*/ + +/* +* extJS-STYLE RESIZER/SLIDER-BAR (CLOSED) +*/ +.resizer-west-closed , +.resizer-east-closed { + background: #B4B4B4 url(/images/separator-v.gif) center no-repeat ; + border-top: 1px solid #777; + border-bottom: 1px solid #777; +} +.resizer-west-closed:hover , +.resizer-east-closed:hover { + background: #D1E6FC; +} + +span.button-pin , +span.button-close { + position: absolute; + top: 0; + width: 20px; + height: 20px; + z-index: 2; + display: block; + cursor: pointer; +} +span.button-close-west { left: 0; } +span.button-close-east { right: 0; } +span.button-pin-west { right: 1px; } +span.button-pin-east { left: 1px; } + +/* CUSTOM pin-buttons */ +span.button-pin-up { background: url(/images/pin-up-off.gif) no-repeat center; } +span.button-pin-up:hover { background: url(/images/pin-up-on.gif) no-repeat center; } +span.button-pin-down { background: url(/images/pin-dn-off.gif) no-repeat center; } +span.button-pin-down:hover { background: url(/images/pin-dn-on.gif) no-repeat center; } + +/* CUSTOM close-buttons */ +span.button-close-west { background: url(/images/go-lt-off.gif) no-repeat center; } +span.button-close-west:hover { background: url(/images/go-lt-on.gif) no-repeat center; } +span.button-close-east { background: url(/images/go-rt-off.gif) no-repeat center; } +span.button-close-east:hover { background: url(/images/go-rt-on.gif) no-repeat center; } + +/* STANDARD toggler-buttons - when the east/west panes are 'closed' */ +.toggler-west-closed { background: url(/images/go-rt-off.gif) no-repeat center; } +.toggler-west-closed:hover { background: url(/images/go-rt-on.gif) no-repeat center; } +.toggler-east-closed { background: url(/images/go-lt-off.gif) no-repeat center; } +.toggler-east-closed:hover { background: url(/images/go-lt-on.gif) no-repeat center; } + + +/* +* INNER LAYOUT RESIZERS & TOGGLERS +* +* These styles target 'children of center pane', so only affect the Inner Layout +* This layout has applyDefaultCSS=true, so use !important to override defaults +*/ + +.ui-layout-center .ui-layout-resizer-closed:hover { background: #FFEDCA !important; } +.ui-layout-center .ui-layout-resizer-open:hover , +.ui-layout-center .ui-layout-resizer-dragging { background: #C4E1A4 !important; } +.ui-layout-center .ui-layout-resizer-dragging-limit { background: #FF3300 !important; } + +.ui-layout-center .ui-layout-resizer-north , +.ui-layout-center .ui-layout-resizer-south { border-left: 1px solid #BBB !important; + border-right: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-north-closed{ border-top: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-south-closed{ border-bottom:1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-west-closed { border-left: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-east-closed { border-right: 1px solid #BBB !important; } + +.ui-layout-center .ui-layout-resizer:hover .ui-layout-toggler { + opacity: 0.4; + filter: alpha(opacity=40); +} +.ui-layout-center .ui-layout-resizer:hover .ui-layout-toggler:hover { + opacity: 1; + filter: alpha(opacity=100); + background: #FD9 !important; + border-color: #CB7 !important; +} + +.ui-layout-center .ui-layout-resizer-sliding { + opacity: 0.3; + filter: alpha(opacity=30); +} +.ui-layout-center .ui-layout-resizer-sliding:hover { + opacity: 1; + filter: alpha(opacity=100); +} +.ui-layout-center .ui-layout-resizer-sliding .ui-layout-toggler { + display: none !important; +} +.ui-layout-center .ui-layout-resizer-sliding:hover .ui-layout-toggler { + display: block !important; +} + + +/** cpanel settings **/ + +#cpanel div.icon { + text-align: center; + margin-right: 2px; + float: left; + margin-bottom: 2px; + background-color: #fff; + -moz-border-radius:6px; /* Rounded edges in Firefox */ + +} +#cpanel div.iconbox { + text-align: center; + margin-right: 5px; + float: left; + margin-bottom: 5px; + background-color: #fff; + -moz-border-radius:6px; /* Rounded edges in Firefox */ + +} + +#cpanel div.icon a { + display: block; + float: left; + border: 1px solid #CACACA; + height: 32px; + width: 200px; + color: #666; + vertical-align: middle; + text-decoration: none; + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} + +#cpanel div.icon a:hover { + border-left: 1px solid #808080; + border-top: 1px solid #808080; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + background: #EFEFEF; + color: #0B55C4; +} + +#cpanel div.iconbox div { + display: block; + float: left; + border: 1px solid #CACACA; + height: 32px; + width: 200px; + color: #666; + vertical-align: middle; + text-decoration: none; + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} + +#cpanel div.iconbox div:hover { + border-left: 1px solid #808080; + border-top: 1px solid #808080; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + background: #EFEFEF; + color: #0B55C4; +} + +#cpanel img { padding: 2px 0; margin: 0 auto; } +#cpanel span { display: block; text-align: center; } + + + +a.iconmenu { + color:#005791; + font-family:Tahoma; + font-size:10px; + font-weight:bold; + text-decoration:none; +} + + +div.grid { + font:11px sans-serif,MiscFixed; + margin-top:2px; + padding-left:4px; + padding-right:0; +} + +/* js-calendar styles*/ +/*jscal2.css*/ +/* CSS */ + +.DynarchCalendar { + border: 1px solid #aaa; + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; + background: #e8e8e8; + font: 11px "lucida grande",tahoma,verdana,sans-serif; + line-height: 14px; + position: relative; + cursor: default; +} + +.DynarchCalendar table { + border-collapse: collapse; + font: 11px "lucida grande",tahoma,verdana,sans-serif; + line-height: 14px; +} + +.DynarchCalendar-topBar { + border-bottom: 1px solid #aaa; + background: #ddd; + padding: 5px 0 0 0; +} + +table.DynarchCalendar-titleCont { + font-size: 130%; font-weight: bold; + color: #444; + text-align: center; + z-index: 9; + position: relative; + margin-top: -6px; +} + +.DynarchCalendar-title div { + padding: 5px 17px; + text-shadow: 1px 1px 1px #777; +} +.DynarchCalendar-hover-title div { + background-color: #fff; + border: 1px solid #000; + padding: 4px 16px; + background-image: url("/js/widgets/js-calendar/css/img/drop-down.gif"); + background-repeat: no-repeat; + background-position: 100% 50%; +} +.DynarchCalendar-pressed-title div { + border: 1px solid #000; + padding: 4px 16px; + background-color: #777; + color: #fff; + background-image: url("/js/widgets/js-calendar/css/img/drop-up.gif"); + background-repeat: no-repeat; + background-position: 100% 50%; +} + + + + + + +.DynarchCalendar-bottomBar { + border-top: 1px solid #aaa; + background: #ddd; + padding: 2px; + position: relative; + text-align: center; +} + +.DynarchCalendar-bottomBar-today { + padding: 2px 15px; +} + +.DynarchCalendar-hover-bottomBar-today { + border: 1px solid #000; + background-color: #fff; + padding: 1px 14px; +} +.DynarchCalendar-pressed-bottomBar-today { + border: 1px solid #000; + background-color: #777; + color: #fff; + padding: 1px 14px; +} + + + + + + +.DynarchCalendar-body { + position: relative; + overflow: hidden; + padding-top: 5px; + padding-bottom: 5px; +} + +.DynarchCalendar-first-col { padding-left: 5px; } +.DynarchCalendar-last-col { padding-right: 5px; } + +.DynarchCalendar-animBody-backYear { + position: absolute; + top: -100%; + left: 0; +} +.DynarchCalendar-animBody-back { + position: absolute; + top: 5px; + left: -100%; +} +.DynarchCalendar-animBody-fwd { + position: absolute; + top: 5px; + left: 100%; +} +.DynarchCalendar-animBody-now { + position: absolute; + top: 5px; + left: 0; +} +.DynarchCalendar-animBody-fwdYear { + position: absolute; + top: 100%; + left: 0; +} + +.DynarchCalendar-dayNames { + padding-left: 5px; + padding-right: 5px; +} + +.DynarchCalendar-dayNames div { font-weight: bold; color: #444; text-shadow: 1px 1px 1px #777; } + +.DynarchCalendar-navBtn { + position: absolute; + top: 5px; + z-index: 10; +} + +.DynarchCalendar-navBtn div { + background-repeat: no-repeat; + background-position: 50% 50%; + height: 15px; + width: 16px; + padding: 1px; +} +.DynarchCalendar-hover-navBtn div { + border: 1px solid #000; + padding: 0; + background-color: #fff; +} +.DynarchCalendar-navDisabled { + opacity: 0.3; + filter: alpha(opacity=30); +} +.DynarchCalendar-pressed-navBtn div { + border: 1px solid #000; + padding: 0; + background-color: #777; + color: #fff; +} + +.DynarchCalendar-prevMonth { + left: 25px; +} + +.DynarchCalendar-nextMonth { + left: 100%; + margin-left: -43px; +} + +.DynarchCalendar-prevYear { + left: 5px; +} + +.DynarchCalendar-nextYear { + left: 100%; + margin-left: -23px; +} + +.DynarchCalendar-prevMonth div { + background-image: url("/js/widgets/js-calendar/css/img/nav-left.gif"); +} + +.DynarchCalendar-nextMonth div { + background-image: url("/js/widgets/js-calendar/css/img/nav-right.gif"); +} + +.DynarchCalendar-prevYear div { + background-image: url("/js/widgets/js-calendar/css/img/nav-left-x2.gif"); +} + +.DynarchCalendar-nextYear div { + background-image: url("/js/widgets/js-calendar/css/img/nav-right-x2.gif"); +} + +.DynarchCalendar-menu { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: #ddd; + overflow: hidden; + opacity: 0.85; + filter: alpha(opacity=85); +} + +.DynarchCalendar-menu table td div { + text-align: center; + font-weight: bold; + padding: 3px 5px; +} +.DynarchCalendar-menu table td div.DynarchCalendar-menu-month { + width: 4em; + text-align: center; +} +.DynarchCalendar-menu table td div.DynarchCalendar-hover-navBtn { + border: 1px solid #000; + padding: 2px 4px; + background-color: #fff; + color: #000; +} +.DynarchCalendar-menu table td div.DynarchCalendar-pressed-navBtn { + border: 1px solid #000; + padding: 2px 4px; + background-color: #777; + color: #fff !important; +} + +.DynarchCalendar-menu-year { + text-align: center; + font: 16px "lucida grande",tahoma,verdana,sans-serif; + font-weight: bold; +} + +.DynarchCalendar-menu-sep { + height: 1px; font-size: 1px; line-height: 1px; + overflow: hidden; + border-top: 1px solid #888; + background: #fff; + margin-top: 4px; margin-bottom: 3px; +} + +.DynarchCalendar-time td { font-weight: bold; font-size: 120%; } +.DynarchCalendar-time-hour, .DynarchCalendar-time-minute { padding: 1px 3px; } +.DynarchCalendar-time-down { background: url("/js/widgets/js-calendar/css/img/time-down.png") no-repeat 50% 50%; width: 11px; height: 8px; opacity: 0.5; } +.DynarchCalendar-time-up { background: url("/js/widgets/js-calendar/css/img/time-up.png") no-repeat 50% 50%; width: 11px; height: 8px; opacity: 0.5; } +.DynarchCalendar-time-sep { padding: 0 2px; } +.DynarchCalendar-hover-time { background-color: #444; color: #fff; opacity: 1; } +.DynarchCalendar-pressed-time { background-color: #000; color: #fff; opacity: 1; } +.DynarchCalendar-time-am { padding: 1px; width: 2.5em; text-align: center; } + +/* body */ + +.DynarchCalendar-hover-week { background-color: #ddd; } + +.DynarchCalendar-dayNames div, .DynarchCalendar-day, .DynarchCalendar-weekNumber { + width: 1.7em; + padding: 3px 4px; + text-align: center; +} +.DynarchCalendar-weekNumber { + border-right: 1px solid #aaa; + margin-right: 4px; + width: 2em !important; + padding-right: 8px !important; +} + +.DynarchCalendar-day { + text-align: right; color: #222; +} +.DynarchCalendar-day-othermonth { color: #888; } +.DynarchCalendar-weekend { color: #c22; } +.DynarchCalendar-day-today { color: #00f; font-weight: bold; } + +.DynarchCalendar-day-disabled { + opacity: 0.5; + text-shadow: 2px 1px 1px #fff; +} + +.DynarchCalendar-hover-date { + padding: 2px 3px; + background-color: #eef; + border: 1px solid #88c; + margin: 0 !important; + color: #000; +} + +.DynarchCalendar-day-othermonth.DynarchCalendar-hover-date { border-color: #aaa; color: #888; } + +.DynarchCalendar-dayNames .DynarchCalendar-weekend { color: #c22; } +.DynarchCalendar-day-othermonth.DynarchCalendar-weekend { color: #d88; } + +.DynarchCalendar-day-selected { + padding: 2px 3px; + margin: 1px; + background-color: #aaa; + color: #000 !important; +} +.DynarchCalendar-day-today.DynarchCalendar-day-selected { background-color: #999; } + +/* focus */ + +.DynarchCalendar-focusLink { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); +} + +.DynarchCalendar-focused { + border-color: #000; +} + +.DynarchCalendar-focused .DynarchCalendar-topBar, .DynarchCalendar-focused .DynarchCalendar-bottomBar { + background-color: #ccc; + border-color: #336; +} + +.DynarchCalendar-focused .DynarchCalendar-hover-week { + background-color: #ccc; +} + +.DynarchCalendar-tooltip { + position: absolute; + top: 100%; + width: 100%; +} + +.DynarchCalendar-tooltipCont { + margin: 0 5px 0 5px; + border: 1px solid #aaa; + border-top: 0; + padding: 3px 6px; + background: #ddd; +} + +.DynarchCalendar-focused .DynarchCalendar-tooltipCont { + background: #ccc; + border-color: #000; +} + +@media print { + .DynarchCalendar-day-selected { + padding: 2px 3px; + border: 1px solid #000; + margin: 0 !important; + } +} +/*border-radius.css*/ +/* This is for Gecko-based browsers */ + +.DynarchCalendar { + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.DynarchCalendar-title, .DynarchCalendar-title div { + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.DynarchCalendar-topBar { + -moz-border-radius: 4px 4px 0 0; + -webkit-border-radius: 4px; + border-radius: 4px 4px 0 0; +} + +.DynarchCalendar-bottomBar { + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.DynarchCalendar-bottomBar-today { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.DynarchCalendar-navBtn, .DynarchCalendar-navBtn div { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.DynarchCalendar-menu { + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.DynarchCalendar-menu table td div { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.DynarchCalendar-weekNumber { + -moz-border-radius: 4px 0 0 4px; + -webkit-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.DynarchCalendar-day { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; +} + +.DynarchCalendar-day-disabled { + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; +} + +.DynarchCalendar-tooltipCont { + -moz-border-radius: 0 0 5px 5px; + -webkit-border-radius: 5px; +} + +.DynarchCalendar-time-hour, .DynarchCalendar-time-minute { + -moz-border-radius: 3px 0 0 3px; + -webkit-border-radius: 3px; +} + +.DynarchCalendar-time-am { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} +/*steal.css*/ +.DynarchCalendar-focused { + background-color: #fff; +} + +.DynarchCalendar-topBar { + background: url("/js/widgets/js-calendar/css/steel/brushed-steel.jpg") no-repeat 50% 0; +} + +.DynarchCalendar-bottomBar { + background: url("/js/widgets/js-calendar/css/steel/brushed-steel.jpg") no-repeat 50% 50%; +} + +.DynarchCalendar-hover-title, +.DynarchCalendar-hover-navBtn, +.DynarchCalendar-hover-bottomBar-today, +.DynarchCalendar-menu table td div.DynarchCalendar-hover-navBtn { + background: #dde url("/js/widgets/js-calendar/css/steel/coolbg.png") repeat-x 0 50%; +} +.DynarchCalendar-hover-title div, +.DynarchCalendar-hover-navBtn div { background-color: transparent; } + +.DynarchCalendar-pressed-title, +.DynarchCalendar-pressed-navBtn, +.DynarchCalendar-pressed-bottomBar-today, +.DynarchCalendar-menu table td div.DynarchCalendar-pressed-navBtn { + background: #445 url("coolbg.png") repeat-x 0 50%; +} +.DynarchCalendar-pressed-title div, +.DynarchCalendar-pressed-navBtn div { background-color: transparent; } + +.DynarchCalendar-hover-week, +.DynarchCalendar-focused .DynarchCalendar-hover-week { + background: #ddd url("coolbg.png") repeat-x 0 50%; +} + +.DynarchCalendar { + background: url("/js/widgets/js-calendar/css/steel/steel.jpg") no-repeat 50% 30px; +} + +.DynarchCalendar-day-selected { + background-color: #1864fc; + color: #fff !important; + background-image: url("coolbg.png"); + background-position: 0 50%; + background-repeat: repeat-x; +} + +.DynarchCalendar-day-today.DynarchCalendar-day-selected { + background-color: #1864fc; + color: #fff !important; +} + +.DynarchCalendar-focused .DynarchCalendar-body { + background: url("../shadow-b.png") repeat-x 0 0; +} + diff --git a/workflow/public_html/skins/iphone/images/bf.jpg b/workflow/public_html/skins/iphone/images/bf.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c41bdf1e943c35c38f22de233cb86e599e0da188 GIT binary patch literal 318 zcmex=i3*BJ!6k`h{6D}T z$icwHz{AWa$iO7X$SlbC{|JK^*r^Q2fQ=m}E++t#;6xT?U}9!v6A}vyopK2%FT%)( zA_?SxLi3*BJ!6k`h{6D}T z$iX1Rz{1QZ$iO7X$SlbC{|JL9(5Vb4fQ=m}tRTR^$i&KuEWs+u$jm03Bo-Vx|&a$Ql_KgarTJV&DNPXA)!H=;Uucj#j?8>hBzQ U?ZWp;x_|Ke8)@gd=J@}c0J{A$$^ZZW literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/bsm.jpg b/workflow/public_html/skins/iphone/images/bsm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee151c40f7ef7a2ee6d7ed21c31460aeb68c7202 GIT binary patch literal 292 zcma)$OA5j;6h&{$*EF?>X{EFs6vy3zf>6*+>Czmy2tNbeNlYCSKNAl;c$^3K-Ea;M z*j>NvK_VULfN;YGf-%OK;9N{aoJ0ws5~FpZwXx=fHM7iSGvj@pd*9S`-LxY^2$52z zCM~TktHKr4c>H$>M>vHFoDzqLBh-;_!eXe3cNmq?7xqg7^QiM5i^00jh!_{HFqFhU P)M15ts}4)D-iON*g`gze literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/bsms.jpg b/workflow/public_html/skins/iphone/images/bsms.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e58d448cad27c0c3e5071cc65818abd57b45304d GIT binary patch literal 323 zcmex=i3*BJ!6k`h{6D}T z$iX1Rz{Jcb$iO7X$SlbC{|JK^$f*p-fSHjUC@wDml;A{>VP<4y7Zef?3Y&5fq!Hvr zWPJ<_j7&grNkK-S6(|ynOoGCJ|8FtyFaxConFSf_8E)sk(Yq$Q=jD%>(^9KXc&?o6 LadQP@!~dHAw0|+h literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/fbc.blue.png b/workflow/public_html/skins/iphone/images/fbc.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..9a503c9d1cf820e20fc93f62063b1aa55f9019c0 GIT binary patch literal 1242 zcmcIk&ubGw7~O)DbfMH9#8eLs>(%V+kJylPlhP)wjU=%)0iy@$WOtIT$?hz(Q?f0B zQhLyfh#-g;dn<@|>9x>+e}#9?TD*F3Hc6ATh@Lv^{Q7wBec!wp_SIVX?zDJK6a-8)fjKjV)jeEpYm591%e=+M15lEbMie8#@TX>RY-$% z5XHixP3jn|I23mXZ3XuaZOG?Sl;Z0|ChvLdkxoYjSth6mHWJNPHIN8MvfzWMxfe~h;o~FUqQ5Z^~2Vt#@ z)UT&jS_3&kF-Xd4!cz1kNY2YzN=v8aZ-EM8;2!dTmI9ih@If>56#sZJy(VQvKAY5T z80-0!K~BEQNSloL285kXNABn{p-rf!(`l$^P}33|kqEXuhQfpw-0X{->f~`?QO9Qv z@j#@D>ST*$Bq>TXY=grgf0)P%2Ig@aVTgRF$_gARbE3(EMvh{{2(1#*&YrstkgMos z#5@BUWgYQx9x+kc~{3{4%-$3O$R2_qxM zjOn=^o#|Zse}>uC&@X?BwtLrNTM)Ogi#--_&(yP?*_P2D)I}`oxTuMt?=?+03jVXc ze%1V0@Mj5!@A9WPUzX+bNg?@D}pe4Rdk*l!>3$EC@h!r JUzRp@{{ShsJqZ8+ literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/fbc.png b/workflow/public_html/skins/iphone/images/fbc.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff292f0f2313d582b0c1c35416a732e2d110d9a GIT binary patch literal 40655 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 A>i_@% literal 0 HcmV?d00001 diff --git a/workflow/public_html/skins/iphone/images/fbl.blue.png b/workflow/public_html/skins/iphone/images/fbl.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd9228cd668f78f5de6356f5afe8720f0d84ce0 GIT binary patch literal 1343 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
    containing the day names */ + border-bottom: 1px solid #B5CFBF; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #B5CFBF; /*e*/ + color: #000; + border: 1px solid #000; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #6F7F75; /*e*/ + border: 1px solid #FFF; + color: #FFF; + padding: 2px 0px 0px 2px; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #456; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #A4BBAD; /*here*/ +} + +.calendar tbody .rowhilite td { /* the rowwwwwww*/ + background: #C9E5D4; +} + +.calendar tbody .rowhilite td.wn { + background: #F1F8FC; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #E9F2E9; + padding: 1px 3px 1px 1px; + border: 1px solid #6F7F75; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #6F7F75; + color: #FFF; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fff; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { /* Cell showing selected date */ + font-weight: bold; + color: #D50000; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The
    */ + background: #000; + color: #fff; + border-top: 1px solid #206A9B; + padding: 1px; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #B8DAF0; + border: 1px solid #178AEB; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #006AA9; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #def; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #34ABFA; + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + font-weight: bold; +} + +.calendar .combo .active { + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + background: #F1F8FC; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #E9F2E9; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #E9F2E9; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { /*e*/ + border-color: #000; + background-color: #6F7F75; + color: #fff; +} + +.calendar td.time span.active { + border-color: red; + background-color: #000; + color: #A5FF00; +} + +/**************************** End -> JSCalendar Widget by Erik Amaru Ortiz *********************************/ + +/**************************** Start -> Suggest Widget by Erik Amaru Ortiz *********************************/ +/* +================================================ +autosuggest, inquisitor style +================================================ +*/ + +body +{ + position: relative; +} + + +div.autosuggest +{ + position: absolute; + /*background-image: url(/skins/green/img_inquisitor/as_pointer.gif);*/ + background-position: top; + background-repeat: no-repeat; + padding: 10px 0 0 0; + z-index:1000; + + border-bottom: 1px #708090 solid; + /*border-left : 1px #708090 solid;*/ + border-right : 1px #708090 solid; + /*border-top : 1px #708090 solid;*/ +} + +/*div.autosuggest div.as_header, +div.autosuggest div.as_footer +{ + position: relative; + height: 6px; + padding: 0 6px; + /*background-image: url(/skins/green/img_inquisitor/ul_corner_tr.gif);*/ + /*background-position: top right;*/ + background-repeat: no-repeat; + overflow: hidden; +}*/ +div.autosuggest div.as_footer +{ + /*background-image: url(/skins/green/img_inquisitor/ul_corner_br.gif);*/ +} + +div.autosuggest div.as_header div.as_corner, +div.autosuggest div.as_footer div.as_corner +{ + position: absolute; + top: 0; + left: 0; + height: 6px; + width: 6px; + /*background-image: url(/skins/green/img_inquisitor/ul_corner_tl.gif);*/ + /*background-position: top left;*/ + background-repeat: no-repeat; +} +div.autosuggest div.as_footer div.as_corner +{ + /*background-image: url(/skins/green/img_inquisitor/ul_corner_bl.gif);*/ +} +div.autosuggest div.as_header div.as_bar, + +div.autosuggest div.as_footer div.as_bar +{ + height: 6px; + overflow: hidden; + /*background-color: #000*/ + background-color: #E0DFE3; +} + + +div.autosuggest ul +{ + list-style: none; + margin: 0 0 -4px 0; + padding: 0; + overflow: hidden; + /*background-color: #000;*/ + background-color: #E0DFE3; +} + +div.autosuggest ul li +{ + color: #ccc; + padding: 0; + margin: 0 4px 4px; + text-align: left; +} + +/*celda*/ +div.autosuggest ul li a +{ + + /*color: #ccc;*/ + color: #000; + + + display: block; + text-decoration: none; + background-color: transparent; + text-shadow: #000 0px 0px 5px; + position: relative; + padding: 0; + width: 100%; +} +div.autosuggest ul li a:hover +{ + background-color: #444; +} + +/*al pasar por encima*/ +div.autosuggest ul li.as_highlight a:hover +{ + + /*background-color: #1B5CCD;*/ + background-color: #EFEFEF; +} + +div.autosuggest ul li a span +{ + display: block; + padding: 3px 6px; + font-weight: bold; +} + +div.autosuggest ul li a span small +{ + font-weight: normal; + color: #999; +} + +div.autosuggest ul li.as_highlight a span small +{ + color: #ccc; +} + +/*al cambiar entre celdas*/ +div.autosuggest ul li.as_highlight a +{ + /*color: #fff;*/ + color: #000; + /*background-color: #1B5CCD;*/ + background-color: #EFEFEF; + + /*background-image: url(/skins/green/img_inquisitor/hl_corner_br.gif);*/ + background-position: bottom right; + background-repeat: no-repeat; +} + +div.autosuggest ul li.as_highlight a span +{ + /*background-image: url(/skins/green/img_inquisitor/hl_corner_bl.gif);*/ + background-position: bottom left; + background-repeat: no-repeat; +} + +div.autosuggest ul li a .tl, +div.autosuggest ul li a .tr +{ + background-image: transparent; + background-repeat: no-repeat; + width: 6px; + height: 6px; + position: absolute; + top: 0; + padding: 0; + margin: 0; +} +div.autosuggest ul li a .tr +{ + right: 0; +} + +div.autosuggest ul li.as_highlight a .tl +{ + left: 0; + /*background-image: url(/skins/green/img_inquisitor/hl_corner_tl.gif);*/ + background-position: bottom left; +} + +div.autosuggest ul li.as_highlight a .tr +{ + right: 0; + /*background-image: url(/skins/green/img_inquisitor/hl_corner_tr.gif);*/ + background-position: bottom right; +} + + + +div.autosuggest ul li.as_warning +{ + font-weight: bold; + text-align: center; +} + +div.autosuggest ul em +{ + font-style: normal; + color: red; +} + +/**************************** End -> Suggest Widget by Erik Amaru Ortiz *********************************/ + +.tableGrid_view +{ + width: 100%; + border-top: 0px solid #DADADA; + border-bottom: 0px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + +table.tableGrid_view td +{ + border-top: 1px solid #DADADA; + border-bottom: 1px solid #DADADA; + border-left: 0px solid #DADADA; + border-right: 0px solid #DADADA; + padding: 0px; + +} + +.ui-widget-header { + -moz-background-clip:border; + -moz-background-inline-policy:continuous; + -moz-background-origin:padding; + background:#5C9CCC url(/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) repeat-x scroll 50% 50%; + border:1px solid #4297D7; + color:#FFFFFF; + font-weight:bold; + font-size: 11px; +} + + +/**************************** new calendar **********************************************/ + +.DHTMLSuite_calendar{ /* Main div for the calendar */ + border:1px solid #8F8F8F; + background-color:#FFF; + width:220px; + position:relative; + overflow:hidden; + font-size: 11px; + +} +.DHTMLSuite_calendarContent{ /* Sub div inside DHTMLSuite_calendar - this is the div where content is added */ + position:relative; /* IMPORTANT - This must always be like this in order to make it possible to position sub elements correctly, especially the iframe */ + z-index:10; /* IMPORTANT - This must always be like this in order to make it possible to position sub elements correctly, especially the iframe */ + background-color:#FFF; + font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + + +/******************* + + START CSS FOR THE HEADER ROW - WHERE YOU SEE MONTH AND YEAR + +********************/ +.DHTMLSuite_calendar .DHTMLSuite_calendarHeading{ /* Heading of calendar, where you see the month and year */ + background-image:url(/images/calendar/calendar_heading.png); + background-repeat:repeat-x; + height:21px; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} +.DHTMLSuite_calendarHeadingTxt{ /* Inner div in the heading */ + padding:1px; + text-align:center; + font-size: 11px; +} + +.DHTMLSuite_calendarCloseButton{ /* Close button at the top right corner of the calendar */ + background-image:url(/images/calendar/calendar-close.gif); + background-repeat:no-repeat; + width:13px; + height:13px; + position:absolute; + right:3px; + top:3px; + padding:1px; + background-position:center center; + cursor:pointer; + font-size: 11px; +} + +.DHTMLSuite_calendarHeaderMonthAndYear{ /* Div elements for year and month in the heading */ + padding:1px; + padding-right:2px; + padding-left:2px; + cursor:pointer; + line-height:17px; + font-size: 11px; + font-weight: bold; + font-size: 11px; +} +.DHTMLSuite_calendarHeaderMonthAndYearOver{ /* Mouse over effect - month and year in the heading */ + background-color:#FFF; + border:1px solid #8F8F8F; + padding:0px; + padding-left:1px; + padding-right:1px; + font-size: 11px; +} + + +/******************* + + START CSS FOR THE TIME BAR - THE DIV WHERE YOU SEE "Time: " and the hour and minute + +********************/ + +.DHTMLSuite_calendar_timeBar{ /* Time bar - where users can select hour and minutes */ + background-color:#D3D3D3; + height:21px; + border-top:1px solid #8F8F8F; + text-align:center; + position:relative; + font-size: 11px; +} +.DHTMLSuite_calendar_timeBarHourAndMinute{ /* General rules for the displayed hours and minutes - the ones you can click on the bring out the drop down boxes */ + padding:1px; + padding-left:2px; + padding-right:2px; + margin-right:2px; + cursor:pointer; + font-size: 11px; +} +.DHTMLSuite_calendarTimeBarHourAndMinuteOver{ /* Mouse over effect for the hour and minute displayed in the time bar */ + background-color:#FFF; + border:1px solid #8F8F8F; + padding:0px; + padding-left:1px; + padding-right:1px; + font-size: 11px; +} +.DHTMLSuite_calendarTimeBarTimeString{ /* String "Time:" */ + position:absolute; + left:2px; + top:2px; + font-size: 11px; +} + +/******************* + + START CSS FOR THE NAVIGATION BAR - THE DIV WITH THE LEFT AND RIGHT ARROWS + +********************/ + +.DHTMLSuite_calendar_navigationBar{ /* Navigation bar below the heading */ + background-color:#D3D3D3; + height:17px; + border-bottom:1px solid #8F8F8F; + position:relative; + font-size: 11px; +} +.DHTMLSuite_calendar_navigationBarToday{ /* Div for the string "Today" in the navigation bar */ + text-align:center; + font-size: 11px; +} +.DHTMLSuite_calendar_navigationBarToday span{ /* The "Today" string inside the navigation bar */ + cursor:pointer; + font-size: 11px; +} +.DHTMLSuite_calendar_btnNextYear,.DHTMLSuite_calendar_btnPreviousYear,.DHTMLSuite_calendar_btnNextMonth,.DHTMLSuite_calendar_btnPreviousMonth{ /* Buttons - previous/next month and year */ + position:absolute; + background-repeat:no-repeat; + background-position:center center; + width:13px; + height:13px; + padding:1px; + top:1px; + font-size: 11px; +} + +.DHTMLSuite_calendar_btnNextYear{ /* Next year button */ + background-image:url(/images/calendar/calendar-next-year.gif); + right:2px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnPreviousYear{ /* Previous year button */ + background-image:url(/images/calendar/calendar-previous-year.gif); + left:2px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnNextMonth{ /* Next month button */ + background-image:url(/images/calendar/calendar-next-month.gif); + right:18px; + font-size: 11px; +} +.DHTMLSuite_calendar_btnPreviousMonth{ /* Previous month button */ + background-image:url(/images/calendar/calendar-previous-month.gif); + left:18px; + font-size: 11px; +} + +/******************* + + START CSS FOR THE MAIN DIV CONTAINING ALL THE DAYS WITHIN A MONTH AND HEADINGS (weeks, days(Mon-Sun) etc.) + +********************/ + + +.DHTMLSuite_calendar_monthView{ /* Main div element for the days in a month */ + + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView_headerCell{ /* Main div element for the days in a month */ + background-color:#FFF; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView_firstColumn{ /* First column - the week column */ + background-color:#D3D3D3; + border-right:1px solid #8F8F8F; + text-align:left; + font-size: 11px; +} + +.DHTMLSuite_calendar_monthView td{ /* Default css for all the cells inside the calendar, i.e. week heading, label for the days, and the days */ + text-align:center; + cursor:default; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_headerSunday{ /* Sunday in the header */ + color:red; + border-bottom:1px solid #8F8F8F; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_daysInOtherMonths{ /* Days in previous or next month, i.e. before start of current displayed month or after days in the currently displayed month */ + color:#999; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_daysInThisMonth{ /* Layout - ordinary days(mon-sat) in this month */ + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_sundayInThisMonth{ /* Layout - sundays in current displayed month */ + color:red; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_initialDate{ /* Inital set date, example: the date in an input field which you are populating with the calendar */ + background-color:#8F8F8F; + color:white; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_invalidDate{ /* Inital set date, example: the date in an input field which you are populating with the calendar */ + color:#AAA; + font-size: 11px; +} +.DHTMLSuite_calendar_monthView_currentDate{ /* Date of today */ + background-color:#dfe9fa; + font-size: 11px; + font-weight: bold; +} +/*************************************************** +* +* START CSS - DROP DOWN BOXES +* +* +***************************************************/ + +/*** MINUTES ***/ +.DHTMLSuite_calendar_minuteDropDown{ /* Drop down box for minutes */ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:23px; + padding:1px; + text-align:center; + /* You shouldn't change these 3 options */ + position:absolute; + z-index:152000; + cursor:pointer; + font-size: 11px; + +} +.DHTMLSuite_calendar_minuteDropDownCurrentMinute{ /* Minute in drop down when it's equal to current minute of the display, i.e. the minute you see where you click on the drop down */ + color:red; + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAMinuteOver{ + background-color:#dfe9fa; + font-size: 11px; +} + +/*** HOURS ***/ +.DHTMLSuite_calendar_hourDropDown{ /* Drop down box for hours */ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:23px; + position:absolute; + z-index:152000; + padding:1px; + cursor:pointer; + font-size:11px; + text-align:center; +} +.DHTMLSuite_calendar_dropdownAnHourOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_hourDropDownCurrentHour{ + color:red; + font-size: 11px; +} + +/*** MONTHS ***/ +.DHTMLSuite_calendar_monthDropDown{ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:70px; + position:absolute; + z-index:152000; + cursor:pointer; + padding:1px; + font-size: 11px; +} +.DHTMLSuite_calendar_dropDownAMonth{ + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAMonthOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_yearDropDownCurrentMonth{ + color:red; + font-size: 11px; +} + +/***** YEAR ****/ +.DHTMLSuite_calendar_yearDropDown{ + background-color:#D3D3D3; + border:1px solid #8F8F8F; + width:30px; + position:absolute; + z-index:152000; + cursor:pointer; + padding:1px; + font-size:12px; + text-align:center; + font-size: 11px; +} +.DHTMLSuite_calendar_dropDownAYear{ + font-size: 11px; +} +.DHTMLSuite_calendar_dropdownAYearOver{ + background-color:#dfe9fa; + font-size: 11px; +} +.DHTMLSuite_calendar_yearDropDownCurrentYear{ /* Current year */ + color:red; + font-size: 11px; +} + + + +/* UP AND DOWN ARROWS INSIDE DROP DOWNS **/ +.DHTMLSuite_calendar_dropDown_arrowUp{ /* Drop down - moving to previous year */ + background-image:url(/images/calendar/calendar-dropdown-up.gif); + background-repeat:no-repeat; + background-position:center center; + height:8px; + font-size: 11px; +} + +.DHTMLSuite_calendar_dropDown_arrowDown{ /* Drop down - moving to previous year */ + background-image:url(/images/calendar/calendar-dropdown-down.gif); + background-repeat:no-repeat; + background-position:center center; + height:8px; + font-size: 11px; +} +.DHTMLSuite_calendarDropDown_dropDownArrowOver{ + background-color:#dfe9fa; + font-size: 11px; +} + + + + +/* IT'S IMPORTANT TO HAVE THIS CSS RULE AT THE BOTTOM IN ORDER TO MAKE THE PADDING OVERRIDE PADDING OF OTHER ELEMENTS */ +.DHTMLSuite_calendarButtonOver{ /* Mouse over effect for the close button */ + background-color:#FFF; /* White background color */ + border:1px solid #8F8F8F; /* Blue border */ + padding:0px; /* The sum border+padding of this element should be the same as border+padding of .DHTMLSuite_calendarCloseButton */ + font-size: 11px; +} +.DHTMLSuite_calendarDayOver{ /* Mouse over effect - days in the calendar, i.e. days in current displayed month */ + background-color:#D3D3D3; + font-size: 11px; +} + +/* YOU SHOULD NEVER MODIFY THIS ONE */ +.DHTMLSuite_calendar_iframe{ /* Iframe used to cover select boxes below in older IE browsers(version 6 and prior) */ + position:absolute; + top:1px; + left:1px; + z-index:1; + font-size: 11px; +} + +.calendar_picker_min{ + cursor:pointer; + background-image:url(/images/btncal_min.png); + float:left; width:96px; height:23px; + /*font-weight: bold;*/ + color:#fff; + font-size: 11px; +} +.calendar_picker{ + cursor:pointer; + background-image:url(/images/btncal.png); + float:left; width:121px; height:23px; + /*font-weight: bold;*/ + color:#fff; + font-size: 11px; +} + +/*@start: PM tooltip -> neyek */ +#pmtooltip{ + background-color:#EEE; + border:1px solid #000; + position:absolute; + display:none; + z-index:20000; + padding:2px; + font-size:0.9em; + -moz-border-radius:6px; /* Rounded edges in Firefox */ + font-family: "Trebuchet MS", "Lucida Sans Unicode", Arial, sans-serif; + +} +#pmtooltipShadow{ + position:absolute; + background-color:#555; + display:none; + z-index:10000; + opacity:0.7; + filter:alpha(opacity=70); + -khtml-opacity: 0.7; + -moz-opacity: 0.7; + -moz-border-radius:6px; /* Rounded edges in Firefox */ +} +/*@end: PM tooltip */ + +/** + * (init) Dynaform Handler styles */ + +#sortable {list-style-type: none;margin: 2; padding: 0; width: 700px;} +#sortable li {margin: 1px 1px 1px 1px;padding: 1px;padding-left: 1px;font-size: 13px;height: 28px;} +/*#sortable li:hover {background: orange;}*/ +#sortable li span {position: absolute;margin-left: -1.3em;} +.dtext{padding-top: 0px;font-size: 13px;color:blue;} +.dynalist td{font-size: 10px;color: #000;} +#jq-siteContain {width: 910px;margin: 0 auto;} +#jq-content {background: #181c21 url(images/bg_home_content.gif) top repeat-x;padding: 4em 40px;border-bottom: 1px solid #000;} +#jq-intro {padding-top: 1em;width: 515px;margin-bottom: 3.5em;} +#jq-intro li {float: left;font-size: 1.4em;} +#jq-intro li a { color: #5DB0E6; font-weight: bold; text-decoration: underline; float: left; background: url(images/icon_check_whiteOnDarkBlue.gif) left no-repeat; padding: 0 30px 0 23px;} +#jq-intro li p {font-size: .9em;} +body.jq-enhanced #jq-intro li {position: relative;} +html.js div.jq-checkpointSubhead {display: none;} +body.jq-enhanced #jq-intro li div.jq-checkpointSubhead { position: absolute; width: 253px; height: 54px; background: url(/images/bg_ctaTooltip.png) 0 0 no-repeat; top: -1.5em; left: -35%; z-index: 100;} +body.jq-enhanced #jq-intro li div.jq-checkpointSubhead p{font-size: 1em; padding: 10px 5px 0 50px; color: #AE0001; font-weight: bold; line-height: 1.3em; margin: 0; cursor: pointer;} +.toggler { font-size:10px;height: 200px; position: relative;} +#effect { width:180px;font-size:10px;height: 135px; padding: 0.4em; position: relative; background: #fff; } +#effect h3 { font-size:10px;margin: 0; padding: 0.4em; text-align: center; } + +.current_selected_item{ + border:2px solid orange; + background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; + font-weight: bold; + color: #2e6e9e; + outline: none; + +} + +/* + * (end) Dybaform Handler styles **/ + +/*extendend fields styles*/ +#fieldshandler_items_table{ + direction: rtl; +} + +.fieldshandler_item{ + direction: ltr; +} + +.htmleditor{ + -x-system-font:none; + background:#FFFFFF url(../images/input_back.gif) repeat-x scroll 0 0; + border:1px solid #AAAAAA; + color:#333333; + font-family:sans-serif; + font-size:8pt; + font-size-adjust:none; + font-stretch:normal; + font-style:normal; + font-variant:normal; + font-weight:normal; + line-height:normal; + padding:1px 1px 1px 3px; + direction:ltr; +} + +.FormTextPM{ + direction: ltr; +} + +.directionSide1{ + direction: rtl; + align: right; +} + +.directionSide2{ + direction: ltr; + align: left; +} + +.pm__dynavars{ + direction:ltr; + font-weight:bold; +} + +/* +* OUTER LAYOUT RESIZERS & TOGGLERS --resizable panel +* By. Erik +*/ + +/* north-pane is not resizable +.resizer-north-dragging , +.resizer-north:hover { background: url(../img/resizable-n.gif) repeat-x center; }*/ +.resizer-south-dragging , +.resizer-south:hover { background: url(../img/resizable-s.gif) repeat-x center; } + +.resizer-west-dragging , +.resizer-west-open:hover { background: url(../img/resizable-w.gif) repeat-y center; } +.resizer-east-dragging , +.resizer-east-open:hover { background: url(../img/resizable-e.gif) repeat-y center; } + +.resizer-west-open , +.resizer-east-open { + background-color: #999; + opacity: 0.1; + filter: alpha(opacity=10); +} +.resizer-west-open:hover , +.resizer-east-open:hover { + opacity: 1; + filter: alpha(opacity=100); +} +.resizer-dragging { + /* see draggable.opacity option + opacity: 0.5; + filter: alpha(opacity=50); + */ +} +.resizer-dragging-limit { background: #FF3300 !important; } + +/* IE6 * HACK - always show resizer graphics because IE6 cannot understand elem:hover */ +/** html .resizer-north { background: url(../img/resizable-n.gif) repeat-x center !important; } */ +* html .resizer-south { background: url(../img/resizable-s.gif) repeat-x center !important; } +* html .resizer-west-open { background: url(../img/resizable-w.gif) repeat-y center !important; } +* html .resizer-east-open { background: url(../img/resizable-e.gif) repeat-y center !important; } +/** html .resizer-north , */ +* html .resizer-south , +* html .resizer-west-open , +* html .resizer-east-open { + opacity: 0.1 !important; + filter: alpha(opacity=10) !important; +} + +/* +* SIMPLE TOGGLER BUTTONS (used on Outer Layout North/South only) +*/ + +.toggler-north-open , +.toggler-south-closed { background: url(../img/toggle-up.gif) no-repeat center bottom; } +.toggler-north-closed , +.toggler-south-open { background: url(../img/toggle-dn.gif) no-repeat center top; } +/* +.toggler-east-closed , +.toggler-west-open { background: url(../img/toggle-lt.gif) no-repeat center right; } +.toggler-west-closed , +.toggler-east-open { background: url(../img/toggle-rt.gif) no-repeat center left; } +*/ + +/* +* extJS-STYLE RESIZER/SLIDER-BAR (CLOSED) +*/ +.resizer-west-closed , +.resizer-east-closed { + background: #B4B4B4 url(/images/separator-v.gif) center no-repeat ; + border-top: 1px solid #777; + border-bottom: 1px solid #777; +} +.resizer-west-closed:hover , +.resizer-east-closed:hover { + background: #D1E6FC; +} + +span.button-pin , +span.button-close { + position: absolute; + top: 0; + width: 20px; + height: 20px; + z-index: 2; + display: block; + cursor: pointer; +} +span.button-close-west { left: 0; } +span.button-close-east { right: 0; } +span.button-pin-west { right: 1px; } +span.button-pin-east { left: 1px; } + +/* CUSTOM pin-buttons */ +span.button-pin-up { background: url(/images/pin-up-off.gif) no-repeat center; } +span.button-pin-up:hover { background: url(/images/pin-up-on.gif) no-repeat center; } +span.button-pin-down { background: url(/images/pin-dn-off.gif) no-repeat center; } +span.button-pin-down:hover { background: url(/images/pin-dn-on.gif) no-repeat center; } + +/* CUSTOM close-buttons */ +span.button-close-west { background: url(/images/go-lt-off.gif) no-repeat center; } +span.button-close-west:hover { background: url(/images/go-lt-on.gif) no-repeat center; } +span.button-close-east { background: url(/images/go-rt-off.gif) no-repeat center; } +span.button-close-east:hover { background: url(/images/go-rt-on.gif) no-repeat center; } + +/* STANDARD toggler-buttons - when the east/west panes are 'closed' */ + .toggler-west-closed { background: url(/images/go-rt-off.gif) no-repeat center; } +.toggler-west-closed:hover { background: url(/images/go-rt-on.gif) no-repeat center; } +.toggler-east-closed { background: url(/images/go-lt-off.gif) no-repeat center; } +.toggler-east-closed:hover { background: url(/images/go-lt-on.gif) no-repeat center; } + + +/* +* INNER LAYOUT RESIZERS & TOGGLERS +* +* These styles target 'children of center pane', so only affect the Inner Layout +* This layout has applyDefaultCSS=true, so use !important to override defaults +*/ + +.ui-layout-center .ui-layout-resizer-closed:hover { background: #FFEDCA !important; } +.ui-layout-center .ui-layout-resizer-open:hover , +.ui-layout-center .ui-layout-resizer-dragging { background: #C4E1A4 !important; } +.ui-layout-center .ui-layout-resizer-dragging-limit { background: #FF3300 !important; } + +.ui-layout-center .ui-layout-resizer-north , +.ui-layout-center .ui-layout-resizer-south { border-left: 1px solid #BBB !important; + border-right: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-north-closed{ border-top: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-south-closed{ border-bottom:1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-west-closed { border-left: 1px solid #BBB !important; } +.ui-layout-center .ui-layout-resizer-east-closed { border-right: 1px solid #BBB !important; } + +.ui-layout-center .ui-layout-resizer:hover .ui-layout-toggler { + opacity: 0.4; + filter: alpha(opacity=40); +} +.ui-layout-center .ui-layout-resizer:hover .ui-layout-toggler:hover { + opacity: 1; + filter: alpha(opacity=100); + background: #FD9 !important; + border-color: #CB7 !important; +} + +.ui-layout-center .ui-layout-resizer-sliding { + opacity: 0.3; + filter: alpha(opacity=30); +} +.ui-layout-center .ui-layout-resizer-sliding:hover { + opacity: 1; + filter: alpha(opacity=100); +} +.ui-layout-center .ui-layout-resizer-sliding .ui-layout-toggler { + display: none !important; +} +.ui-layout-center .ui-layout-resizer-sliding:hover .ui-layout-toggler { + display: block !important; +} \ No newline at end of file diff --git a/workflow/public_html/skins/valida.js b/workflow/public_html/skins/valida.js new file mode 100644 index 000000000..04b69022f --- /dev/null +++ b/workflow/public_html/skins/valida.js @@ -0,0 +1,1108 @@ + +var Labels = new Array(6); +Labels['ID_THE_CHARACTER'] = new Array(2) +Labels['ID_THE_CHARACTER']['es'] = 'El caracter'; +Labels['ID_THE_CHARACTER']['en'] = 'The character'; +Labels['ID_NOT_VALID'] = new Array(2) +Labels['ID_NOT_VALID']['es'] = 'no es válido para este campo'; +Labels['ID_NOT_VALID']['en'] = 'is not valid for this field'; +Labels['ID_ERROR_CALLING_CONTROL'] = new Array(2) +Labels['ID_ERROR_CALLING_CONTROL']['es'] = 'Error al llamado de control: no hay control especificado'; +Labels['ID_ERROR_CALLING_CONTROL']['en'] = 'Error calling the control: no target control specified'; +Labels['ID_ERROR_CALLING_CALENDAR'] = new Array(2) +Labels['ID_ERROR_CALLING_CALENDAR']['es'] = 'Error al llamado del calendario: el parametro especificado no es un control válido'; +Labels['ID_ERROR_CALLING_CALENDAR']['en'] = 'Error calling the calendar: parameter specified is not valid target control'; +Labels['ID_NO_ROOM_FIELDS'] = new Array(2) +Labels['ID_NO_ROOM_FIELDS']['es'] = 'No hay sitio para más campos'; +Labels['ID_NO_ROOM_FIELDS']['en'] = 'There is no room for more fields'; +Labels['ID_NO_ROOM_FORMS'] = new Array(2) +Labels['ID_NO_ROOM_FORMS']['es'] = 'No hay sitio para más formularios'; +Labels['ID_NO_ROOM_FORMS']['en'] = 'There is no room for more forms'; +Labels['ID_PARAMETERS_NOT_EXISTS'] = new Array(2) +Labels['ID_PARAMETERS_NOT_EXISTS']['es'] = 'No existen parámetros'; +Labels['ID_PARAMETERS_NOT_EXISTS']['en'] = 'Parameters do not exists'; +Labels['ID_PARAMETER_NOT_FOUND'] = new Array(2) +Labels['ID_PARAMETER_NOT_FOUND']['es'] = 'Parámetro requerido no encontrado'; +Labels['ID_PARAMETER_NOT_FOUND']['en'] = 'Required parameter not found'; +Labels['ID_FIELD_NOT_EXISTS'] = new Array(2) +Labels['ID_FIELD_NOT_EXISTS']['es'] = 'No existe el campo'; +Labels['ID_FIELD_NOT_EXISTS']['en'] = 'Not exists the field'; +Labels['ID_INVALID_EMAIL']= new Array(2) +Labels['ID_INVALID_EMAIL']['es']="Email invalido"; +Labels['ID_INVALID_EMAIL']['en']="Invalid Email"; + +var keyAlfa = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZáéíóúñÁÉÍÓÚÑ "; +var keyAlfaUS = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +var keyAlfaUS2 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +var keyDigit = "01234567890"; +var keyReal = keyDigit+"-."; +var keyAlfa9 = keyAlfa+keyDigit + ".,@"; +var keyAlfa8 = keyAlfaUS2+keyDigit ; +var keyAlfa10 = keyAlfaUS+keyDigit+keyReal+"@"; +var keyAny = keyAlfa9+"!#$%&/()=¿?¡+*{}[]-_.:,;'|\"\\@"; +var keyField = keyAlfaUS + keyDigit; +var ALFA = 1, INTEGER = 2, REAL=3, ANY = 4, ALFANUM = 5; FIELD=6; ALFANUMAOUTSPAC = 7; EMAIL=10; LOGIN=11; + +function Upcase(t) +{ + aux = t.value; t.value = aux.toUpperCase(); + +} + +function isIn ( cadena, car ) { + var i = 0; sw = 0==1; + while ( i < cadena.length && !sw ) { + sw= (cadena.charAt(i) == car); + i ++; + } + return sw; +} + + +function IsValueOk(objRecieved) +{ + if(!echeck(objRecieved.value)) + { + alert(Labels['ID_INVALID_EMAIL'][GetCurrentLanguage()]); + objRecieved.value=''; + return false; + } + return true; +} + +function echeck(str) { + + var at="@" + var dot="." + var lat=str.indexOf(at) + var lstr=str.length + var ldot=str.indexOf(dot) + if (str.indexOf(at)==-1){ + + return false; + } + + if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){ + + return false; + } + + if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){ + + return false; + } + + if (str.indexOf(at,(lat+1))!=-1){ + + return false; + } + + if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){ + + return false; + } + + if (str.indexOf(dot,(lat+2))==-1){ + + return false; + } + + if (str.indexOf(" ")!=-1){ + + return false; + } + + return true; + } + +function IsKeyValid(mode,event) { + var msj; + evvent=(window.event)?window.event:event; + if(evvent.keyCode==9) + { + return; + } + if ( evvent.keyCode == 13 ) { + if (top.document.webform) { + frm = top.document.webform; + if ( frm.onsubmit ) + frm.onsubmit(); + } + return ; + } + //alert(evvent.keyCode); + car = String.fromCharCode( (evvent.keyCode)?evvent.keyCode:evvent.which ); + //alert(car); + bOk=false; + if (mode==ALFA ) bOk = isIn ( keyAlfa, car ); + if (mode==INTEGER) bOk = isIn ( keyDigit,car ); + if (mode==REAL ) bOk = isIn ( keyReal, car ); + if (mode==ANY ) bOk = isIn ( keyAny, car ); + if (mode==ALFANUM) bOk = isIn ( keyAlfa9,car ); + if (mode==FIELD) bOk = isIn ( keyField,car ); + if (mode==ALFANUMAOUTSPAC) bOk = isIn ( keyAlfa8,car ); + if (mode==LOGIN) bOk = isIn ( keyAlfa10,car ); + + //evvent.returnValue = true; + + + if (bOk==false) { + + //alert("asdasd"); + if(browser.isIE) + { + alert(Labels['ID_THE_CHARACTER'][GetCurrentLanguage()] + ' ' + String (car) + ' ' + Labels['ID_NOT_VALID'][GetCurrentLanguage()]); + //evvent.returnValue = false; + return false; + } + else + { + return false; + } + return true; + } +} + +function IsAlfa (f) { + return 1; +} + +function IsInteger (f) { + return 1; +} + +function IsReal (f) { + return 1; +} + +function IsAny (f) { + return 1; +} + +function IsAlfaNum (f) { +} + + +/* modal function*/ + function getValue ( nameField ) { + val = top.document.webform.elements ["form[" + nameField + "]"].value; + return val; + } + + function setModalValue ( nameField, display, value ) { + var cacheobj=document.webform.elements ["form[" + nameField + "]"]; + largo = cacheobj.options.length; + for (m = largo - 1;m>=0;m--) cacheobj.options[m]=null; + cacheobj.options[0]= new Option( display, value); + cacheobj.options[0].selected=true; + return ; + } + +var controls ; + +function control1 (nameField) { + // assing methods + //this.popup = cal_popup1; + + // validate input parameters + if (!nameField) + return cal_error(Labels['ID_ERROR_CALLING_CONTROL'][GetCurrentLanguage()]); + if (nameField == null) + return cal_error(Labels['ID_ERROR_CALLING_CALENDAR'][GetCurrentLanguage()]); + + this.field = document.webform.elements ["form[" + nameField + "]"]; + // register in global collections + //this.id = controls.length; + controls = this; +} + + + function show_dialog ( nameField, page, width, height ) { + //var field = document.webform.elements ["form[" + nameField + "]"]; + + if (crtl) crtl = null; + var crtl = new control1(nameField); + + var url = '../controls/' + page; + + var left=300, top=60; + if( window.screen && window.screen.availHeight ) + {left = (window.screen.availWidth - width) /2; + top = (window.screen.availHeight - height)/2 -20;} + + var options = 'top=' + top + ', left=' + left + ', width=' + width + ',height='+ height + + ',status=no,resizable=no,dependent=yes,alwaysRaised=yes'; + + var obj_dialog = window.open( url, 'Controls', options ); + + obj_dialog.opener = window; + obj_dialog.focus(); + + return ; + } + + function open_dialog ( nameField, page, width, height ) { + //if (crtl) crtl = null; + //var crtl = new control1(nameField); + var url = page + "?" + nameField; + + var left=300, top=60; + if( window.screen && window.screen.availHeight ) + {left = (window.screen.availWidth - width) /2; + top = (window.screen.availHeight - height)/2 -20;} + + var options = 'top=' + top + ', left=' + left + ', width=' + width + ',height='+ height + + ',status=no,resizable=yes,dependent=yes,alwaysRaised=yes,scrollbars=yes'; + var obj_dialog = window.open( url, 'Controls', options ); + + //window.changeValue ( nameField, "" ); + obj_dialog.mainWindow = window; + obj_dialog.focus(); + return ; + } + + function showModal ( url, width, height ) { + options = "dialogHeight:" + height +"px; dialogWidth:" + width+"px; center:yes; resizable:no; status:no; "; + res = window.showModalDialog( url, 0, options); + return res; + } + + function show_onDemandField ( nameField, times, maxl ) { + var i = 1; + var sw = 1; + while ( i<= times && sw ) { + eval (" this.fieldDiv = document.all.div_" + nameField + "_" + i +"; "); + if ( this.fieldDiv.style.display == 'none' ) { + sw = 0; + this.fieldDiv.style.display = ''; + } + i =i+1; + } ; + + if ( sw ) + alert(Labels['ID_NO_ROOM_FIELDS'][GetCurrentLanguage()]); + else + if (parent.frames['frameXmlContainer']) + if (parent.resizeFrame) + parent.resizeFrame(parent.document.getElementById('frameXmlContainer')); + return ; + } + + function showOnDemandTab ( fieldName ) { + eval (" this.fieldDiv = document.all.div_" + fieldName +"; "); + eval (" this.fieldArD = document.all.arrowD" + fieldName +"; "); + eval (" this.fieldArR = document.all.arrowR" + fieldName +"; "); + this.fieldDiv.style.display = 'none'; + this.fieldArR.style.display = 'none'; + this.fieldArD.style.display = ''; + if (parent.frames['frameXmlContainer']) + if (parent.resizeFrame) + parent.resizeFrame(parent.document.getElementById('frameXmlContainer')); + } + + function hideOnDemandTab ( fieldName ) { + eval (" this.fieldDiv = document.all.div_" + fieldName +"; "); + eval (" this.fieldArD = document.all.arrowD" + fieldName +"; "); + eval (" this.fieldArR = document.all.arrowR" + fieldName +"; "); + this.fieldDiv.style.display = ''; + this.fieldArD.style.display = 'none'; + this.fieldArR.style.display = ''; + if (parent.frames['frameXmlContainer']) + if (parent.resizeFrame) + parent.resizeFrame(parent.document.getElementById('frameXmlContainer')); + } + + function show_onDemandForm ( nameField, times ) { + var i = 1; + var sw = 1; + hideOnDemandTab ( nameField ); + while ( i<= times && sw ) { + eval (" this.fieldDiv = document.all.div_" + nameField + "_" + i +"; "); + if ( this.fieldDiv.style.display == 'none' ) { + sw = 0; + this.fieldDiv.style.display = ''; + } + i =i+1; + }; + if ( sw ) + alert(Labels['ID_NO_ROOM_FORMS'][GetCurrentLanguage()]); + else + if (parent.frames['frameXmlContainer']) + if (parent.resizeFrame) + parent.resizeFrame(parent.document.getElementById('frameXmlContainer')); + return ; + } + + function hide_and_clear_onDemandForm ( formName , index) { + var i = 1; + var sw = 1; + eval (" this.fieldDiv = document.all.div_" + formName + '_' + index +"; "); + this.fieldDiv.style.display = 'none'; + + baseName = "form[" + formName + "][" + index + "]"; + for ( i = 0; i < document.webform.elements.length; i++ ) { + qfield = document.webform.elements( i ); + qname = qfield.name; + + if ( qfield.name.slice(0, baseName.length) == baseName ) + qfield.value = ''; + } + if (parent.frames['frameXmlContainer']) + if (parent.resizeFrame) + parent.resizeFrame(parent.document.getElementById('frameXmlContainer')); + return ; + } + + + function clear_field ( nameField, index ) { + field = document.webform.elements ["form[" + nameField + "][" + index + "]" ]; + field.value = ''; + return; + } + +// Title: Tigra Calendar +// URL: http://www.softcomplex.com/products/tigra_calendar/ +// Version: 3.2 (European date format) +// Date: 10/14/2002 (mm/dd/yyyy) +// Feedback: feedback@softcomplex.com (specify product title in the subject) +// Note: Permission given to use this script in ANY kind of applications if +// header lines are left unchanged. +// Note: Script consists of two files: calendar?.js and calendar.html +// About us: Our company provides offshore IT consulting services. +// Contact us at sales@softcomplex.com if you have any programming task you +// want to be handled by professionals. Our typical hourly rate is $20. + +// if two digit year input dates after this year considered 20 century. +var NUM_CENTYEAR = 30; +// is time input control required by default +var BUL_TIMECOMPONENT = false; +// are year scrolling buttons required by default +var BUL_YEARSCROLL = true; + +var calendars = []; +var RE_NUM = /^\-?\d+$/; + +function calendar1(obj_date1, obj_date2, obj_date3) { + + // assing methods + this.gen_date = cal_gen_date1; + this.gen_time = cal_gen_time1; + this.gen_tsmp = cal_gen_tsmp1; + this.prs_date = cal_prs_date1; + this.prs_time = cal_prs_time1; + this.prs_tsmp = cal_prs_tsmp1; + this.popup = cal_popup1; + this.fecha = "0"; + + // validate input parameters + if (!obj_date1) + return cal_error("Error calling the calendar: no target control specified"); + if (obj_date1 == null) + return cal_error("Error calling the calendar: parameter specified is not valid tardet control"); + this.date1 = obj_date1; + this.date2 = obj_date2; + this.date3 = obj_date3; + this.time_comp = BUL_TIMECOMPONENT; + this.year_scroll = BUL_YEARSCROLL; + + // register in global collections + this.id = calendars.length; + calendars[this.id] = this; +} + +function cal_popup1 (str_datetime, pre_path) { + this.dt_current = this.prs_tsmp(str_datetime ); + + if (!this.dt_current) return; + + var left=300, top=60; + if( window.screen && window.screen.availHeight ) + {left = (window.screen.availWidth - 200) /2; + top = (window.screen.availHeight - 215)/2 -20;} + + var Direction = new String(window.location); + Direction = Direction.replace('http://', ''); + Direction = Direction.replace('https://', ''); + Direction = Direction.split('/'); + if (Direction[1].substr(0, 3) != 'sys') { + var Key = new String('c0l0s40pt1mu59r1m3'); + var Controls = ''; + var Calendar = ''; + for (i=0; i<('controls'.length); i++) { + TheChar = 'controls'.charAt(i); + AuxPos = (i % Key.length) - 1; + if (AuxPos < 0) + AuxPos = Key.length - (AuxPos * (-1)); + KeyChar = Key.substr(AuxPos, 1); + TheChar = String.fromCharCode(TheChar.charCodeAt(0) + KeyChar.charCodeAt(0)); + Controls += TheChar; + } + Controls = encode64(Controls); + Controls = Controls.replace('º', '/'); + Controls = Controls.replace('=', ''); + for (i=0; i<('calendar.php'.length); i++) { + TheChar = 'calendar.php'.charAt(i); + AuxPos = (i % Key.length) - 1; + if (AuxPos < 0) + AuxPos = Key.length - (AuxPos * (-1)); + KeyChar = Key.substr(AuxPos, 1); + TheChar = String.fromCharCode(TheChar.charCodeAt(0) + KeyChar.charCodeAt(0)); + Calendar += TheChar; + } + Calendar = encode64(Calendar); + Calendar = Calendar.replace('º', '/'); + Calendar = Calendar.replace('=', ''); + } + else { + if (Direction.length > 6) + Controls = '../controls'; + else + Controls = 'controls'; + Calendar = 'calendar.php'; + } + + var obj_calwindow = window.open( + '../' + Controls + '/' + Calendar + '?datetime=' + this.dt_current.valueOf()+ '&id=' + this.id, + 'Calendar', 'width=200,height='+(this.time_comp ? 215 : 190)+ + ',status=no,resizable=no,top=' + top + ',left=' + left + ',dependent=yes,alwaysRaised=yes' + ); + + obj_calwindow.opener = window; + obj_calwindow.focus(); + + + +} + +// timestamp generating function +function cal_gen_tsmp1 (dt_datetime) { + return(this.gen_date(dt_datetime) + ' ' + this.gen_time(dt_datetime)); +} + +// date generating function +function cal_gen_date1 (dt_datetime) { + return ( + (dt_datetime.getDate() < 10 ? '0' : '') + dt_datetime.getDate() + "-" + + (dt_datetime.getMonth() < 9 ? '0' : '') + (dt_datetime.getMonth() + 1) + "-" + + dt_datetime.getFullYear() + ); +} +// time generating function +function cal_gen_time1 (dt_datetime) { + return ( + (dt_datetime.getHours() < 10 ? '0' : '') + dt_datetime.getHours() + ":" + + (dt_datetime.getMinutes() < 10 ? '0' : '') + (dt_datetime.getMinutes()) + ":" + + (dt_datetime.getSeconds() < 10 ? '0' : '') + (dt_datetime.getSeconds()) + ); +} + +// timestamp parsing function +function cal_prs_tsmp1 (str_datetime) { + // if no parameter specified return current timestamp + if (!str_datetime) + return (new Date()); + + // if positive integer treat as milliseconds from epoch + if (RE_NUM.exec(str_datetime)) + return new Date(str_datetime); + + // else treat as date in string format + var arr_datetime = str_datetime.split(' '); + return this.prs_time(arr_datetime[1], this.prs_date(arr_datetime[0])); +} + +// date parsing function +function cal_prs_date1 (str_date) { + + var arr_date = str_date.split('-'); + + if (arr_date.length != 3) return cal_error ("Invalid date format: '" + str_date + "'.\nFormat accepted is dd-mm-yyyy."); + if (!arr_date[0]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo day of month value can be found."); + if (!RE_NUM.exec(arr_date[0])) return cal_error ("Invalid day of month value: '" + arr_date[0] + "'.\nAllowed values are unsigned integers."); + if (!arr_date[1]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo month value can be found."); + if (!RE_NUM.exec(arr_date[1])) return cal_error ("Invalid month value: '" + arr_date[1] + "'.\nAllowed values are unsigned integers."); + if (!arr_date[2]) return cal_error ("Invalid date format: '" + str_date + "'.\nNo year value can be found."); + if (!RE_NUM.exec(arr_date[2])) return cal_error ("Invalid year value: '" + arr_date[2] + "'.\nAllowed values are unsigned integers."); + + var dt_date = new Date(); + dt_date.setDate(1); + + if (arr_date[1] < 1 || arr_date[1] > 12) return cal_error ("Invalid month value: '" + arr_date[1] + "'.\nAllowed range is 01-12."); + dt_date.setMonth(arr_date[1]-1); + + if (arr_date[2] < 100) arr_date[2] = Number(arr_date[2]) + (arr_date[2] < NUM_CENTYEAR ? 2000 : 1900); + dt_date.setFullYear(arr_date[2]); + + var dt_numdays = new Date(arr_date[2], arr_date[1], 0); + dt_date.setDate(arr_date[0]); + if (dt_date.getMonth() != (arr_date[1]-1)) return cal_error ("Invalid day of month value: '" + arr_date[0] + "'.\nAllowed range is 01-"+dt_numdays.getDate()+"."); + + return (dt_date) +} + +// time parsing function +function cal_prs_time1 (str_time, dt_date) { + + if (!dt_date) return null; + var arr_time = String(str_time ? str_time : '').split(':'); + + if (!arr_time[0]) dt_date.setHours(0); + else if (RE_NUM.exec(arr_time[0])) + if (arr_time[0] < 24) dt_date.setHours(arr_time[0]); + else return cal_error ("Invalid hours value: '" + arr_time[0] + "'.\nAllowed range is 00-23."); + else return cal_error ("Invalid hours value: '" + arr_time[0] + "'.\nAllowed values are unsigned integers."); + + if (!arr_time[1]) dt_date.setMinutes(0); + else if (RE_NUM.exec(arr_time[1])) + if (arr_time[1] < 60) dt_date.setMinutes(arr_time[1]); + else return cal_error ("Invalid minutes value: '" + arr_time[1] + "'.\nAllowed range is 00-59."); + else return cal_error ("Invalid minutes value: '" + arr_time[1] + "'.\nAllowed values are unsigned integers."); + + if (!arr_time[2]) dt_date.setSeconds(0); + else if (RE_NUM.exec(arr_time[2])) + if (arr_time[2] < 60) dt_date.setSeconds(arr_time[2]); + else return cal_error ("Invalid seconds value: '" + arr_time[2] + "'.\nAllowed range is 00-59."); + else return cal_error ("Invalid seconds value: '" + arr_time[2] + "'.\nAllowed values are unsigned integers."); + + dt_date.setMilliseconds(0); + return dt_date; +} + +function cal_error (str_message) { + alert (str_message); + return null; +} + + //to call picker date.... added byOnti + function picker_date(nameField, NotOutOfForm) { + if (!NotOutOfForm) { + if (document.webform) { + var date1=document.webform.elements ["form[" + nameField + "][DAY]"]; + var date2=document.webform.elements ["form[" + nameField + "][MONTH]"]; + var date3=document.webform.elements ["form[" + nameField + "][YEAR]"]; + } + else { + var date1=document.all["form[" + nameField + "][DAY]"]; + var date2=document.all["form[" + nameField + "][MONTH]"]; + var date3=document.all["form[" + nameField + "][YEAR]"]; + } + } + else { + if (document.webform) { + var date1=document.webform.elements [nameField + "[DAY]"]; + var date2=document.webform.elements [nameField + "[MONTH]"]; + var date3=document.webform.elements [nameField + "[YEAR]"]; + } + else { + var date1=document.all[nameField + "[DAY]"]; + var date2=document.all[nameField + "[MONTH]"]; + var date3=document.all[nameField + "[YEAR]"]; + } + } + var cal1 = new calendar1(date1, date2, date3); + cal1.popup(); + } + + + + + // Original JavaScript code by Duncan Crombie: dcrombie@chirp.com.au + // Please acknowledge use of this code by including this header. + + // CONSTANTS + var separator = ","; // use comma as 000's separator + var decpoint = "."; // use period as decimal point + var percent = "%"; + var currency = "$"; // use dollar sign for currency + + function formatNumber(number, format, print) { // use: formatNumber(number, "format") + if (print) document.write("formatNumber(" + number + ", \"" + format + "\")
    "); + + if (number - 0 != number) return null; // if number is NaN return null + if (number == 'Infinity') return null; // if number is Infinite return null + if (number == '-Infinity') return null; // if number is Infinite return null + var useSeparator = format.indexOf(separator) != -1; // use separators in number + var usePercent = format.indexOf(percent) != -1; // convert output to percentage + var useCurrency = format.indexOf(currency) != -1; // use currency format + var isNegative = (number < 0); + number = Math.abs (number); + if (usePercent) number *= 100; + format = strip(format, separator + percent + currency); // remove key characters + number = "" + number; // convert number input to string + + // split input value into LHS and RHS using decpoint as divider + var dec = number.indexOf(decpoint) != -1; + var nleftEnd = (dec) ? number.substring(0, number.indexOf(".")) : number; + var nrightEnd = (dec) ? number.substring(number.indexOf(".") + 1) : ""; + + // split format string into LHS and RHS using decpoint as divider + dec = format.indexOf(decpoint) != -1; + var sleftEnd = (dec) ? format.substring(0, format.indexOf(".")) : format; + var srightEnd = (dec) ? format.substring(format.indexOf(".") + 1) : ""; + + // adjust decimal places by cropping or adding zeros to LHS of number + if (srightEnd.length < nrightEnd.length) { + var nextChar = nrightEnd.charAt(srightEnd.length) - 0; + nrightEnd = nrightEnd.substring(0, srightEnd.length); + if (nextChar >= 5) nrightEnd = "" + ((nrightEnd - 0) + 1); // round up + + // patch provided by Patti Marcoux 1999/08/06 + while (srightEnd.length > nrightEnd.length) { + nrightEnd = "0" + nrightEnd; + } + + if (srightEnd.length < nrightEnd.length) { + nrightEnd = nrightEnd.substring(1); + nleftEnd = (nleftEnd - 0) + 1; + } + } else { + for (var i=nrightEnd.length; srightEnd.length > nrightEnd.length; i++) { + if (srightEnd.charAt(i) == "0") nrightEnd += "0"; // append zero to RHS of number + else break; + } + } + + // adjust leading zeros + sleftEnd = strip(sleftEnd, "#"); // remove hashes from LHS of format + while (sleftEnd.length > nleftEnd.length) { + nleftEnd = "0" + nleftEnd; // prepend zero to LHS of number + } + + if (useSeparator) nleftEnd = separate(nleftEnd, separator); // add separator + var output = nleftEnd + ((nrightEnd != "") ? "." + nrightEnd : ""); // combine parts + output = ((useCurrency) ? currency : "") + output + ((usePercent) ? percent : ""); + if (isNegative) { + // patch suggested by Tom Denn 25/4/2001 + output = (useCurrency) ? "(" + output + ")" : "-" + output; + } + return output; + } + + + + function strip(input, chars) { // strip all characters in 'chars' from input + var output = ""; // initialise output string + for (var i=0; i < input.length; i++) + if (chars.indexOf(input.charAt(i)) == -1) + output += input.charAt(i); + return output; + } + + function separate(input, separator) { // format input using 'separator' to mark 000's + input = "" + input; + var output = ""; // initialise output string + for (var i=0; i < input.length; i++) { + if (i != 0 && (input.length - i) % 3 == 0) output += separator; + output += input.charAt(i); + } + return output; + } + + function format_number_1000 (pnumber, decimals) { + if (isNaN(pnumber)) { return 0}; + if (pnumber=='') { return 0}; + + var snum = new String(pnumber); + var sec = snum.split('.'); + var num = new String ( sec[0] ); + aux = ''; + if (sec[1] != null){ + var num2 = new String ( sec[1] ); + } + else{ + var num2 = ''; + sec[1] = ''; + } + var aux = ""; + var aux2 = ""; + var len = num.length; + var len2 = num2.length; + + var i = 0; + var c = 0; + for (i = len -1; i >= 0; i-- ) { + aux = num.charAt ( i) + aux; + c ++; + if (c % 3 == 0 && i > 0 && num.charAt (i-1) != '-') aux = "," + aux; + } + decimals2 = decimals - len2; + + if(decimals2 > 0){ + sec[2]=''; + for (i = 0; i < decimals2; i++ ) { + sec[2] = sec[2] + 0; + } + sec[1] = sec[1]+sec[2]; + }else if(decimals == 0) sec[1] = ""; + else if((sec.length == 1) && (decimals == '')) sec[1] = "00"; + else if(decimals2 < 0){ + for (j = 0; j < decimals; j++ ) { + aux2 = aux2 + num2.charAt ( j); + } + sec[1] = aux2; + } + + if (sec[1] && sec[1].length > 0) + aux = aux + "." + sec[1]; + + //if(sec.length == 1) sec[1] = "00"; + //aux = aux + "." + sec[1]; + + return aux ; + } + + + function quita_comas ( snumber ) { + var aux = ""; + var num = new String (snumber); + var len = num.length; + var i = 0; + for (i = 0; i < len; i++ ) { + if (num.charAt ( i) != ',' && num.charAt (i) != '$' && num.charAt (i) != ' ' ) aux = aux + num.charAt ( i); + } + return aux; + } + + +/** + * Sets/unsets the pointer in browse mode + * + * @param object the table row + * @param object the color to use for this row + * + * @return boolean whether pointer is set or not + * the setPoninterForm is the generic an specific for forms... + */ +function setPointerForm(theRow, thePointerColor) +{ + if (thePointerColor == '' || typeof(theRow.style) == 'undefined') { + return false; + } + if (typeof(document.getElementsByTagName) != 'undefined') { + var theCells = theRow.getElementsByTagName('td'); + } + else if (typeof(theRow.cells) != 'undefined') { + var theCells = theRow.cells; + } + else { + return false; + } + + var rowCellsCnt = theCells.length; + for (var c = 0; c < rowCellsCnt; c++) { + theCells[c].style.backgroundColor = thePointerColor; + } + + return true; +} // end of the 'setPointer()' function + +function SumarValoresColumna(Columna, NombreBase) { + NombreBase = new String(NombreBase); + Aux = NombreBase.split(']['); + Total = 0; + i = 1; + if ((Aux[1] > 0) && (Aux[1] < 10)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(.)\]\[/g, "\]\[" + i + "\]\[")); + if ((Aux[1] > 9) && (Aux[1] < 100)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(..)\]\[/g, "\]\[" + i + "\]\[")); + if ((Aux[1] > 99) && (Aux[1] < 1000)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(...)\]\[/g, "\]\[" + i + "\]\[")); + while (Objeto) { + Total += Number(removePercentageSign(removeCurrencySign(Objeto.value))); + i++; + if ((Aux[1] > 0) && (Aux[1] < 10)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(.)\]\[/g, "\]\[" + i + "\]\[")); + if ((Aux[1] > 9) && (Aux[1] < 100)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(..)\]\[/g, "\]\[" + i + "\]\[")); + if ((Aux[1] > 99) && (Aux[1] < 1000)) + Objeto = window.document.getElementById(NombreBase.replace( /\]\[(...)\]\[/g, "\]\[" + i + "\]\[")); + } + Total = format_number_1000(Total, 2); + NombreGrid = NombreBase.substring(NombreBase.indexOf('[') + 1, NombreBase.indexOf(']')); + Objeto = window.document.getElementById('form[SYS_GRID_AGGREGATE_' + NombreGrid + '_' + Columna + ']'); + Objeto.value = Total; + Objeto = window.document.getElementById('SYS_GRID_AGGREGATE_' + NombreGrid + '_' + Columna); + Objeto.innerHTML = '= ' + Total; +} + +function GetCurrentLanguage() { + var Key = new String('c0l0s40pt1mu59r1m3'); + var Direction = new String(window.location); + var TheLanguage = ''; + Direction = Direction.replace('http://', ''); + Direction = Direction.replace('https://', ''); + Direction = Direction.split('/'); + if (Direction[1].substr(0, 3) == 'sys') + TheLanguage = Direction[2]; + else { + Direction[2] = Direction[2].replace('º', '/'); + Direction[2] = decode64(Direction[2]); + for (i=0; i<(Direction[2].length-1); i++) { + TheChar = Direction[2].charAt(i); + if (TheChar != '') { + AuxPos = (i % Key.length) - 1; + if (AuxPos < 0) + AuxPos = Key.length - (AuxPos * (-1)); + KeyChar = Key.substr(AuxPos, 1); + TheChar = String.fromCharCode(TheChar.charCodeAt(0) - KeyChar.charCodeAt(0)); + TheLanguage = TheLanguage + TheChar; + } + } + } + return TheLanguage; +} + +function decode64(input) { + var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + var output = ''; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + } while (i < input.length); + + return output; +} + +function encode64(input) { + var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } while (i < input.length); + + return output; +} + +function onChangeForAll(obj) { + if (obj.onvalidation) eval(obj.onvalidation); + if (obj.onstrto) eval(obj.onstrto); + if (obj.ondependentfields) eval(obj.ondependentfields); + if (obj.ontotalize) eval(obj.ontotalize); + if (obj.oncustomize) obj.oncustomize(); +} + +function ValidateOnChange(ObjectName, Mode) { + //agregar el código para validar el contenido de un control +} + +function RefreshWithExternalValue(TheWindow, ExternalField) { + Parameters = TheWindow.location.search.substring(1).split('&'); + if (Parameters) { + for (i=0; i= len); i++) +if ((fld.value.charAt(i) != '0') && (fld.value.charAt(i) != decSep)) break; +aux = ''; +for(; !(i >= len); i++) +{ + //alert(fld.value.charAt(i)+" -> "+strCheck.indexOf(fld.value.charAt(i))); +if (strCheck.indexOf(fld.value.charAt(i))!=-1) +{ + aux += fld.value.charAt(i); + //alert(aux); +} +} + +aux += key; +zero_found=false; +aux_temp=aux; +aux=''; +for(i=0;i 2) { +aux2 = ''; +for (j = 0, i = len - 3; i >= 0; i--) { +if (j == 3) { +aux2 += milSep; +j = 0; +} +aux2 += aux.charAt(i); +j++; +} +result_value = '$ '; +len2 = aux2.length; +for (i = len2 - 1; i >= 0; i--) +result_value += aux2.charAt(i); +result_value += decSep + aux.substr(len - 2, len); +} +//alert(result_value); +fld.value=result_value; +return false; +} \ No newline at end of file diff --git a/workflow/public_html/skins/workPeriod.js b/workflow/public_html/skins/workPeriod.js new file mode 100644 index 000000000..e0f6f0711 --- /dev/null +++ b/workflow/public_html/skins/workPeriod.js @@ -0,0 +1,20 @@ + +function abc( panel, txt ) { +/* commonDialog ( '', 'saved' , 'saved', {}, '' ) ; + setTimeout ( leimnud.closure({instance:myDialog,method:function(panel){ + + myDialog.remove(); + panel.tabLastSelected=false; + panel.tabSelected=1; + panel.makeTab(); + },args:panel}) , 1000 ); +*/ + var img = document.getElementById( 'workPeriodGraph' ); + img.src = 'workPeriodGraph?b=' + Math.random() ; + +// panel.clearContent(); +// panel.addContent ( txt ); + return false; +} + + \ No newline at end of file diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php new file mode 100644 index 000000000..240597f35 --- /dev/null +++ b/workflow/public_html/sysGeneric.php @@ -0,0 +1,530 @@ + $vValue) { + if (is_array($vValue)) { + strip_slashes($vVar[$sKey]); + } + else { + $vVar[$sKey] = stripslashes($vVar[$sKey]); + } + } + } + else { + $vVar = stripslashes($vVar); + } + } + + if (ini_get('magic_quotes_gpc') == '1') { + strip_slashes($_POST); + } + +//******** function to calculate the time used to render this page ***** + function logTimeByPage() { + $serverAddr = $_SERVER['SERVER_ADDR']; + global $startingTime; + $endTime = array_sum(explode(' ',microtime())); + $time = $endTime - $startingTime; + $fpt= fopen ( PATH_DATA . 'log/time.log', 'a' ); + fwrite( $fpt, sprintf ( "%s.%03d %15s %s %5.3f %s\n", date('H:i:s'), $time, getenv('REMOTE_ADDR'), substr($serverAddr,-4), $time, $_SERVER['REQUEST_URI'] )); + fclose( $fpt); + } + +//******** defining the PATH_SEP constant, he we are defining if the the path separator symbol will be '\\' or '/' ************************** + if ( PHP_OS == 'WINNT' && !strpos ( $_SERVER['DOCUMENT_ROOT'], '/' ) ) + define('PATH_SEP','\\'); + else + define('PATH_SEP', '/'); + +//***************** Defining the Home Directory ********************************* + $docuroot = explode ( PATH_SEP , $_SERVER['DOCUMENT_ROOT'] ); + array_pop($docuroot); + $pathhome = implode( PATH_SEP, $docuroot ) . PATH_SEP; + + + //try to find automatically the trunk directory where are placed the RBAC and Gulliver directories + //in a normal installation you don't need to change it. + array_pop($docuroot); + $pathTrunk = implode( PATH_SEP, $docuroot ) . PATH_SEP ; + + array_pop($docuroot); + $pathOutTrunk = implode( PATH_SEP, $docuroot ) . PATH_SEP ; + // to do: check previous algorith for Windows $pathTrunk = "c:/home/"; + + define('PATH_HOME', $pathhome ); + define('PATH_TRUNK', $pathTrunk ); + define('PATH_OUTTRUNK', $pathOutTrunk ); + + +//************* Including these files we get the PM paths and definitions (that should be just one file *********** + require_once ( $pathhome . PATH_SEP . 'engine' . PATH_SEP . 'config' . PATH_SEP . 'paths.php' ); +//******************* Error handler and log error ******************* + //to do: make different environments. sys + //G::setErrorHandler ( ); + //G::setFatalErrorHandler ( ); + define ('ERROR_SHOW_SOURCE_CODE', true); // enable ERROR_SHOW_SOURCE_CODE to display the source code for any WARNING OR NOTICE + //define ( 'ERROR_LOG_NOTICE_ERROR', true ); //enable ERROR_LOG_NOTICE_ERROR to log Notices messages in default apache log + +// ***** create headPublisher singleton ***************** + G::LoadSystem('headPublisher'); + $oHeadPublisher =& headPublisher::getSingleton(); + +// ***** defining the maborak js file, this file is the concat of many js files and here we are including all of them **** + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/maborak.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/core/common.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/core/effects.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/core/webResource.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'dveditor/core/dveditor.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'common/tree/tree.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'json/core/json.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'form/core/form.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'form/core/pagedTable.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'grid/core/grid.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.panel.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.validator.js', true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.app.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.rpc.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.fx.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.drag.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.drop.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.dom.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.abbr.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'maborak/core/module.dashboard.js', true ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'widgets/js-calendar/js-calendar.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'widgets/suggest/bsn.AutoSuggest_2.1.3.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'widgets/tooltip/pmtooltip.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'thirdparty/krumo/krumo.js' ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . 'widgets/calendar/pmcalendar.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_CORE . 'js' . PATH_SEP . 'cases/core/cases.js' , true ); + $oHeadPublisher->addMaborakFile( PATH_CORE . 'js' . PATH_SEP . 'cases/core/cases_Step.js', true ); + $oHeadPublisher->addMaborakFile( PATH_CORE . 'js' . PATH_SEP . 'processmap/core/processmap.js', true ); + $oHeadPublisher->addMaborakFile( PATH_CORE . 'js' . PATH_SEP . 'appFolder/core/appFolderList.js', true ); + $oHeadPublisher->addMaborakFile( PATH_THIRDPARTY . 'htmlarea/editor.js', true ); + +//************ defining Virtual URLs ****************/ + $virtualURITable = array(); + $virtualURITable['/plugin/(*)'] = 'plugin'; + $virtualURITable['/(sys*)/(*.js)'] = 'jsMethod'; + $virtualURITable['/js/(*)'] = PATH_GULLIVER_HOME . 'js/'; + $virtualURITable['/jscore/(*)'] = PATH_CORE . 'js/'; + if ( defined('PATH_C') ) { + $virtualURITable['/jsform/(*.js)'] = PATH_C . 'xmlform/'; + $virtualURITable['/extjs/(*)'] = PATH_C . 'ExtJs/'; + } + $virtualURITable['/htmlarea/(*)'] = PATH_THIRDPARTY . 'htmlarea/'; + $virtualURITable['/sys[a-zA-Z][a-zA-Z0-9]{0,}()/'] = 'sysNamed'; + $virtualURITable['/(sys*)'] = FALSE; + $virtualURITable['/errors/(*)'] = PATH_GULLIVER_HOME . 'methods/errors/'; + $virtualURITable['/gulliver/(*)'] = PATH_GULLIVER_HOME . 'methods/'; + $virtualURITable['/controls/(*)'] = PATH_GULLIVER_HOME . 'methods/controls/'; + $virtualURITable['/html2ps_pdf/(*)'] = PATH_THIRDPARTY . 'html2ps_pdf/'; + $virtualURITable['/Krumo/(*)'] = PATH_THIRDPARTY . 'krumo/'; + $virtualURITable['/codepress/(*)'] = PATH_THIRDPARTY . 'codepress/'; + $virtualURITable['/images/'] = 'errorFile'; + $virtualURITable['/skins/'] = 'errorFile'; + $virtualURITable['/files/'] = 'errorFile'; + + $virtualURITable['/[a-zA-Z][a-zA-Z0-9]{0,}()'] = 'sysUnnamed'; + $virtualURITable['/(*)'] = PATH_HTML; + +//****** verify if we need to redirect or stream the file, if G:VirtualURI returns true means we are going to redirect the page ***** + if ( G::virtualURI($_SERVER['REQUEST_URI'], $virtualURITable , $realPath )) { + // review if the file requested belongs to public_html plugin + if ( substr ( $realPath, 0,6) == 'plugin' ) { + /* + * By JHL Jul 14, 08 + * Another way to get the path of Plugin public_html and stream the correspondent file + * TODO: $pathsQuery will be used? + */ + $pathsQuery=""; + //Get the query side + /* + * Did we use this variable $pathsQuery for something?? + */ + $forQuery=explode("?",$realPath); + if(isset($forQuery[1])) { + $pathsQuery=$forQuery[1]; + } + + //Get that path in array + $paths = explode ( PATH_SEP, $forQuery[0] ); + //remove the "plugin" word from + $paths[0] = substr ( $paths[0],6); + //Get the Plugin Folder, always the first element + $pluginFolder=array_shift($paths); + //The other parts are the realpath into public_html (no matter how many elements) + $filePath=implode(PATH_SEP,$paths); + $pluginFilename = PATH_PLUGINS . $pluginFolder . PATH_SEP . 'public_html'. PATH_SEP . $filePath; + if ( file_exists ( $pluginFilename ) ) { + G::streamFile ( $pluginFilename ); + } + die; + } + switch ( $realPath ) { + case 'sysUnnamed' : + require_once('sysUnnamed.php'); die; + break; + case 'sysNamed' : + header('location : ' . $_SERVER['REQUEST_URI'] . 'en/green/login/login' ); + die; + break; + case 'jsMethod' : + G::parseURI ( getenv( "REQUEST_URI" ) ); + $filename = PATH_METHODS . SYS_COLLECTION . '/' . SYS_TARGET . '.js'; + G::streamFile ( $filename ); + die; + break; + case 'errorFile': + header ("location: /errors/error404.php"); + if ( DEBUG_TIME_LOG ) logTimeByPage(); //log this page + die; + break; + default : + $realPath = explode('?', $realPath); + $realPath[0] .= strpos($realPath[0], '.') === false ? '.php' : ''; + G::streamFile ( $realPath[0] ); + die; + } + } + +//************** the request correspond to valid php page, now parse the URI ************** + + G::parseURI ( getenv( "REQUEST_URI" ) ); + $oHeadPublisher->addMaborakFile( PATH_GULLIVER_HOME . 'js' . PATH_SEP . "widgets/jscalendar/lang/calendar-" . SYS_LANG . ".js"); + define( 'SYS_URI' , '/sys' . SYS_TEMP . '/' . SYS_LANG . '/' . SYS_SKIN . '/' ); + +//************** defining the serverConf singleton ************** + if(defined('PATH_DATA') && file_exists(PATH_DATA)){ + //Instance Server Configuration Singleton + G::LoadClass('serverConfiguration'); + $oServerConf =& serverConf::getSingleton(); + } +//***************** Call Gulliver Classes ************************** + + G::LoadThirdParty('pear/json','class.json'); + G::LoadThirdParty('smarty/libs','Smarty.class'); + G::LoadSystem('error'); + G::LoadSystem('dbconnection'); + G::LoadSystem('dbsession'); + G::LoadSystem('dbrecordset'); + G::LoadSystem('dbtable'); + G::LoadSystem('rbac' ); + G::LoadSystem('publisher'); + G::LoadSystem('templatePower'); + G::LoadSystem('xmlDocument'); + G::LoadSystem('xmlform'); + G::LoadSystem('xmlformExtension'); + G::LoadSystem('form'); + G::LoadSystem('menu'); + G::LoadSystem("xmlMenu"); + G::LoadSystem('dvEditor'); + G::LoadSystem('table'); + //G::LoadSystem('pagedTable'); + +//************** Installer, redirect to install if we don't have a valid shared data folder ***************/ + if ( !defined('PATH_DATA') || !file_exists(PATH_DATA)) { + if ( (SYS_TARGET==='installServer')) { + $phpFile = G::ExpandPath('methods') ."install/installServer.php"; + require_once($phpFile); + die(); + } + else { + $phpFile = G::ExpandPath('methods') ."install/install.php"; + require_once($phpFile); + die(); + } + } + +// ************* Load Language Translation ***************** + G::LoadTranslationObject(defined('SYS_LANG')?SYS_LANG:"en"); + +//******** look for a disabled workspace **** + if($oServerConf->isWSDisabled(SYS_TEMP)){ + $aMessage['MESSAGE'] = G::LoadTranslation('ID_DISB_WORKSPACE'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; + } + +//********** database and workspace definition ************************ + //if SYS_TEMP exists, the URL has a workspace, now we need to verify if exists their db.php file + if ( defined('SYS_TEMP') && SYS_TEMP != '') { + //this is the default, the workspace db.php file is in /shared/workflow/sites/SYS_SYS + if ( file_exists( PATH_DB . SYS_TEMP . '/db.php' ) ) { + require_once( PATH_DB . SYS_TEMP . '/db.php' ); + define ( 'SYS_SYS' , SYS_TEMP ); + } + else { + $aMessage['MESSAGE'] = G::LoadTranslation ('ID_NOT_WORKSPACE'); + $G_PUBLISH = new Publisher; + $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showMessage', '', $aMessage ); + G::RenderPage( 'publish' ); + die; + } + } + else { //when we are in global pages, outside any valid workspace + if ((SYS_TARGET==='sysLoginVerify') || (SYS_TARGET==='sysLogin') || (SYS_TARGET==='newSite')) { + $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . "/" . SYS_TARGET.'.php'; + require_once($phpFile); + die(); + } + else { + if(SYS_TARGET=="dbInfo"){ //Show dbInfo when no SYS_SYS + require_once( PATH_METHODS . "login/dbInfo.php" ) ; + } + else{ + require_once( PATH_METHODS . "login/sysLogin.php" ) ; + } + if ( DEBUG_TIME_LOG ) logTimeByPage(); //log this page + die(); + } + } + +//***************** PM Paths DATA ************************** + define( 'PATH_DATA_SITE', PATH_DATA . 'sites/' . SYS_SYS . '/'); + define( 'PATH_DOCUMENT', PATH_DATA_SITE . 'files/' ); + define( 'PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE . 'mailTemplates/' ); + define( 'PATH_DATA_PUBLIC', PATH_DATA_SITE . 'public/' ); + define( 'PATH_DATA_REPORTS', PATH_DATA_SITE . 'reports/' ); + define( 'PATH_DYNAFORM', PATH_DATA_SITE . 'xmlForms/' ); + define( 'PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE . 'usersFiles'.PATH_SEP); + define( 'PATH_IMAGES_ENVIRONMENT_USERS', PATH_DATA_SITE . 'usersPhotographies'.PATH_SEP); + define( 'SERVER_NAME', $_SERVER ['SERVER_NAME']); + define( 'SERVER_PORT', $_SERVER ['SERVER_PORT']); + +//***************** Plugins ************************** + G::LoadClass('plugin'); + //here we are loading all plugins registered + //the singleton has a list of enabled plugins + + $sSerializedFile = PATH_DATA_SITE . 'plugin.singleton'; + $oPluginRegistry =& PMPluginRegistry::getSingleton(); + if ( file_exists ($sSerializedFile) ) + $oPluginRegistry->unSerializeInstance( file_get_contents ( $sSerializedFile ) ); + + +//***************** create $G_ENVIRONMENTS dependent of SYS_SYS ************************** + define ( 'G_ENVIRONMENT', G_DEV_ENV ); + $G_ENVIRONMENTS = array ( + G_PRO_ENV => array ( + 'dbfile' => PATH_DB . 'production' . PATH_SEP . 'db.php' , + 'cache' => 1, + 'debug' => 0, + ) , + G_DEV_ENV => array ( + 'dbfile' => PATH_DB . SYS_SYS . PATH_SEP . 'db.php', + 'datasource' => 'workflow', + 'cache' => 0, + 'debug' => DEBUG_SQL_LOG, //<--- change the value of this Constant to to 1, to have a detailed sql log in PATH_DATA . 'log' . PATH_SEP . 'workflow.log' + ) , + G_TEST_ENV => array ( + 'dbfile' => PATH_DB . 'test' . PATH_SEP . 'db.php' , + 'cache' => 0, + 'debug' => 0, + ) + ); + +//******* setup propel definitions and logging **** + require_once ( "propel/Propel.php" ); + require_once ( "creole/Creole.php" ); + + if ( $G_ENVIRONMENTS[ G_ENVIRONMENT ]['debug'] ) { + require_once ( "Log.php" ); + + // register debug connection decorator driver + Creole::registerDriver('*', 'creole.contrib.DebugConnection'); + + // itialize Propel with converted config file + Propel::init( PATH_CORE . "config/databases.php" ); + + //log file for workflow database + $logFile = PATH_DATA . 'log' . PATH_SEP . 'workflow.log'; + $logger = Log::singleton('file', $logFile, 'wf ' . SYS_SYS, null, PEAR_LOG_INFO); + Propel::setLogger($logger); + $con = Propel::getConnection('workflow'); + if ($con instanceof DebugConnection) $con->setLogger($logger); + + //log file for rbac database + $logFile = PATH_DATA . 'log' . PATH_SEP . 'rbac.log'; + $logger = Log::singleton('file', $logFile, 'rbac ' . SYS_SYS, null, PEAR_LOG_INFO); + Propel::setLogger($logger); + $con = Propel::getConnection('rbac'); + if ($con instanceof DebugConnection) $con->setLogger($logger); + + //log file for report database + $logFile = PATH_DATA . 'log' . PATH_SEP . 'report.log'; + $logger = Log::singleton('file', $logFile, 'rp ' . SYS_SYS, null, PEAR_LOG_INFO); + Propel::setLogger($logger); + $con = Propel::getConnection('rp'); + if ($con instanceof DebugConnection) $con->setLogger($logger); + } + else + Propel::init( PATH_CORE . "config/databases.php" ); + + Creole::registerDriver('dbarray', 'creole.contrib.DBArrayConnection'); + +//***************** Session Initializations **************************/ + ini_set( 'session.auto_start', '1' ); + ini_set( 'register_globals', 'Off' ); + session_start(); + ob_start(); + +//********* Setup plugins ************* + $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + $avoidChangedWorkspaceValidation = false; + + //Load custom Classes and Model from Plugins. + G::LoadAllPluginModelClasses(); + +//*********jump to php file in methods directory ************* + $collectionPlugin = ''; + if ( $oPluginRegistry->isRegisteredFolder( SYS_COLLECTION ) ) { + $phpFile = PATH_PLUGINS . SYS_COLLECTION . PATH_SEP . SYS_TARGET.'.php'; + $targetPlugin = explode( '/', SYS_TARGET ); + $collectionPlugin = $targetPlugin[0]; + $avoidChangedWorkspaceValidation = true; + } + else + $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . PATH_SEP . SYS_TARGET.'.php'; + + //services is a special folder, + if ( SYS_COLLECTION == 'services' ) { + $avoidChangedWorkspaceValidation = true; + $targetPlugin = explode( '/', SYS_TARGET ); + if ( $targetPlugin[0] == 'webdav' ) { + $phpFile = G::ExpandPath('methods') . SYS_COLLECTION . PATH_SEP . 'webdav.php'; + } + } + if(SYS_COLLECTION=='login' && SYS_TARGET=='login'){ + $avoidChangedWorkspaceValidation = true; + } + + //the index.php file, this new feature will allow automatically redirects to valid php file inside any methods folder + if ( SYS_TARGET == '' ) { + $phpFile = str_replace ( '.php', 'index.php', $phpFile ); + $phpFile = include ( $phpFile ); + } + $bWE = false; + if ( substr(SYS_COLLECTION , 0,8) === 'gulliver' ) { + $phpFile = PATH_GULLIVER_HOME . 'methods/' . substr( SYS_COLLECTION , 8) . SYS_TARGET.'.php'; + } + else { + //when the file is part of the public directory of any PROCESS, this a ProcessMaker feature + if (preg_match('/^[0-9][[:alnum:]]+$/', SYS_COLLECTION) == 1) + { //the pattern is /sysSYS/LANG/SKIN/PRO_UID/file + $auxPart = explode ( '/' , $_SERVER['REQUEST_URI']); + $aAux = explode('?', $auxPart[ count($auxPart)-1]); + //$extPart = explode ( '.' , $auxPart[ count($auxPart)-1] ); + $extPart = explode ( '.' , $aAux[0] ); + $queryPart = isset($aAux[1])?$aAux[1]:""; + $extension = $extPart[ count($extPart)-1 ]; + $phpFile = PATH_DATA_SITE . 'public' . PATH_SEP . SYS_COLLECTION . PATH_SEP . urldecode ($auxPart[ count($auxPart)-1]); + $aAux = explode('?', $phpFile); + $phpFile = $aAux[0]; + if ( $extension != 'php' ) { + G::streamFile ( $phpFile ); + die; + } + //$avoidChangedWorkspaceValidation=true; + $bWE = true; + //$phpFile = PATH_DATA_SITE . 'public' . PATH_SEP . SYS_COLLECTION . PATH_SEP . $auxPart[ count($auxPart)-1]; + } + if ( ! file_exists( $phpFile ) ) { + $_SESSION['phpFileNotFound'] = $phpFile; + print $phpFile; + header ("location: /errors/error404.php"); + die; + } + } +//G::pr($_SESSION); +//G::dump($avoidChangedWorkspaceValidation);die; +//redirect to login, if user changed the workspace in the URL + if( ! $avoidChangedWorkspaceValidation && isset( $_SESSION['WORKSPACE'] ) && $_SESSION['WORKSPACE'] != SYS_SYS) { + $_SESSION['WORKSPACE'] = SYS_SYS; + G::SendTemporalMessage ('ID_USER_HAVENT_RIGHTS_SYSTEM', "error"); + header ( 'Location: /sys' . SYS_SYS . '/' . SYS_LANG . '/' . SYS_SKIN . '/login/login' ); + die; + } + +//***************** enable rbac ************************** + $RBAC =& RBAC::getSingleton( PATH_DATA, session_id() ); + $RBAC->sSystem = 'PROCESSMAKER'; + +//****** define and send Headers for all pages ******************* + if ( ! defined('EXECUTE_BY_CRON') ) { + header("Expires: " . gmdate("D, d M Y H:i:s", mktime( 0,0,0,date('m'),date('d'),date('Y') + 1) ) . " GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + + //get the language direction from ServerConf + define('SYS_LANG_DIRECTION', $oServerConf->getLanDirection() ); + + if((isset( $_SESSION['USER_LOGGED'] ))&&(!(isset($_GET['sid'])))) { + $RBAC->initRBAC(); + $RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] , PATH_DATA, session_id()); + } + else { + //This sentence is used when you lost the Session + if ( SYS_TARGET != 'authentication' and SYS_TARGET != 'login' and SYS_TARGET != 'login_Ajax' + and SYS_TARGET != 'dbInfo' and SYS_TARGET != 'sysLoginVerify' and SYS_TARGET != 'processes_Ajax' + and SYS_TARGET != 'updateTranslation' + and SYS_TARGET != 'autoinstallProcesses' + and SYS_TARGET != 'autoinstallPlugins' + and SYS_TARGET != 'heartbeatStatus' + and SYS_COLLECTION != 'services' and SYS_COLLECTION != 'tracker' and $collectionPlugin != 'services' + and $bWE != true and SYS_TARGET != 'defaultAjaxDynaform' and SYS_TARGET != 'cases_ShowDocument') { + $bRedirect = true; + if (isset($_GET['sid'])) { + G::LoadClass('sessions'); + $oSessions = new Sessions(); + if ($aSession = $oSessions->verifySession($_GET['sid'])) { + require_once 'classes/model/Users.php'; + $oUser = new Users(); + $aUser = $oUser->load($aSession['USR_UID']); + $_SESSION['USER_LOGGED'] = $aUser['USR_UID']; + $_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME']; + $bRedirect = false; + $RBAC->initRBAC(); + $RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] ); + } + } + if ($bRedirect) { + if (empty($_POST)) { + header('location: ' . SYS_URI . 'login/login?u=' . urlencode($_SERVER['REQUEST_URI'])); + } + else { + header('location: ' . SYS_URI . 'login/login'); + } + die(); + } + } + } + require_once( $phpFile ); + if ( defined('SKIP_HEADERS') ) { + header("Expires: " . gmdate("D, d M Y H:i:s", mktime( 0,0,0,date('m'),date('d'),date('Y') + 1) ) . " GMT"); + header('Cache-Control: public'); + header('Pragma: '); + } + ob_end_flush(); + if ( DEBUG_TIME_LOG ) logTimeByPage(); //log this page + } diff --git a/workflow/public_html/sysUnnamed.php b/workflow/public_html/sysUnnamed.php new file mode 100644 index 000000000..6f0f2098f --- /dev/null +++ b/workflow/public_html/sysUnnamed.php @@ -0,0 +1,33 @@ + + + +Redirector + + + + + + + \ No newline at end of file